pax_global_header00006660000000000000000000000064114732520660014520gustar00rootroot0000000000000052 comment=0ffd308877aaecf9455e8f9700926e9f6df4631a ants-1.9.2+svn680.dfsg/000077500000000000000000000000001147325206600144605ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/ANTSCopyright.txt000066400000000000000000000030001147325206600176500ustar00rootroot00000000000000ConsortiumOfANTS® - http://www.picsl.upenn.edu/ANTS/ Copyright (c) 2009-2010 (updated to current year ad infinitum) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the consortium nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ants-1.9.2+svn680.dfsg/COPYING.txt000066400000000000000000000027111147325206600163320ustar00rootroot00000000000000Copyright (c) 2009, 2010 ConsortiumOfANTS All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the consortium nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ants-1.9.2+svn680.dfsg/Examples/000077500000000000000000000000001147325206600162365ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Examples/ANTS.cxx000066400000000000000000000240411147325206600175300ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ANTS.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:05 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkPICSLAdvancedNormalizationToolKit.h" #include "itkANTSImageTransformation.h" #include "itkANTSImageRegistrationOptimizer.h" #include template int ANTSex(int argc, char *argv[]) { typedef itk::PICSLAdvancedNormalizationToolKit RegistrationType; typename RegistrationType::Pointer registration = RegistrationType::New(); registration->ParseCommandLine( argc, argv ); std::cout << " Run Reg " << std::endl; try { registration->RunRegistration(); } catch(...) { std::cerr << "Exception thrown: ANTS" << std::endl; return EXIT_FAILURE; } registration->GetTransformationModel()->SetWriteComponentImages(true); registration->GetTransformationModel()->Write(); return EXIT_SUCCESS; } int main(int argc, char *argv[] ) { int dim = 2; // while(argc--) printf("%s\n", *argv++); if ( argc < 2 || ((argc == 2) && strcmp(argv[1], "--help") == 0)) { std::cout << " \n " << std::endl; std::cout << "Example usage: \n " << std::endl; std::cout << argv[0] << " ImageDimension -m MI[fixedimage.nii.gz,movingimage.nii.gz,1,32] -o Outputfname.nii.gz -i 30x20x0 -r Gauss[3,1] -t Elast[3] \n \n " << std::endl; std::cout << " Compulsory arguments:\n " << std::endl; std::cout << " ImageDimension: 2 or 3 (for 2 or 3 Dimensional registration)\n " << std::endl; std::cout << " -m: Type of similarity model used for registration. \n " << std::endl; std::cout << " For intramodal image registration, use: " << std::endl; std::cout << " CC = cross-correlation " << std::endl; std::cout << " MI = mutual information " << std::endl; std::cout << " PR = probability mapping " << std::endl; std::cout << " MSQ = mean square difference " << std::endl; std::cout << " \n " << std::endl; std::cout << " For intermodal image registration, use: " << std::endl; std::cout << " MI = mutual information " << std::endl; std::cout << " PR = probability mapping " << std::endl; std::cout << " \n " << std::endl; std::cout << " -o Outputfname.nii.gz: the name of the resulting image.\n " << std::endl; std::cout << " -i Max-iterations in format: JxKxL, where: " << std::endl; std::cout << " J = max iterations at coarsest resolution (here, reduce by power of 2^2) " << std::endl; std::cout << " K = middle resolution iterations (here,reduce by power of 2) " << std::endl; std::cout << " L = fine resolution iterations (here, full resolution). This level takes much more time per iteration!\n " << std::endl; std::cout << " Adding an extra value before JxKxL (i.e. resulting in IxJxKxL) would add another iteration level.\n " << std::endl; std::cout << " -r Regularization \n" << std::endl; std::cout << " -t Type of transformation model used for registration \n" << std::endl; std::cout << " For elastic image registration, use: " << std::endl; std::cout << " Elast = elastic transformation model (less deformation possible)\n " << std::endl; std::cout << " For diffeomorphic image registration, use: " << std::endl; std::cout << " Syn[GradStep,TimePoints,IntegrationStep] --geodesic 2 = SyN with time with arbitrary number of time points in time discretization " << std::endl; std::cout << " SyN[GradStep,2,IntegrationStep] = SyN with time optimized specifically for 2 time points in the time discretization " << std::endl; std::cout << " SyN[GradStep] = Greedy SyN, typicall GradStep=0.25 " << std::endl; std::cout << " Exp[GradStep,TimePoints] = Exponential " << std::endl; std::cout << " GreedyExp = Diffeomorphic Demons style exponential mapping " << std::endl; std::cout << " \n " << std::endl; std::cout << " Please use the `ANTS -h ` call or refer to the ANTS.pdf manual or antsIntroduction.sh script for additional information and typical values for transformation models\n " << std::endl; return 1; } else dim = atoi( argv[1] ); if ( dim <= 1 || dim > 3 ) { std::cout <<" You passed ImageDimension: " << dim << " . Please use only 2 or 3 (for 2 or 3 Dimensional registration) " << std::endl; argv[1]=(char*)("--help"); ANTSex<2>( argc,argv ); exit(1); } /** * Try the simple case of the call "ANTS fixedImage movingImage" */ if( argc == 3 && ( atoi( argv[1] ) != 2 || atoi( argv[1] ) != 3 ) ) { itk::ImageIOBase::Pointer fixedImageIO = itk::ImageIOFactory::CreateImageIO( argv[1], itk::ImageIOFactory::ReadMode ); if( fixedImageIO.IsNull() ) { std::cerr << "Invalid fixed image: " << argv[1] << std::endl; return EXIT_FAILURE; } itk::ImageIOBase::Pointer movingImageIO = itk::ImageIOFactory::CreateImageIO( argv[2], itk::ImageIOFactory::ReadMode ); if( movingImageIO.IsNull() ) { std::cerr << "Invalid moving image: " << argv[2] << std::endl; return EXIT_FAILURE; } fixedImageIO->SetFileName( argv[1] ); fixedImageIO->ReadImageInformation(); movingImageIO->SetFileName( argv[2] ); movingImageIO->ReadImageInformation(); unsigned int fdim = fixedImageIO->GetNumberOfDimensions(); unsigned int mdim = movingImageIO->GetNumberOfDimensions(); if( fdim != mdim ) { std::cerr << "Fixed image dimension does not equal " << "the moving image dimension (" << fdim << " != " << mdim << ")" << std::endl; return EXIT_FAILURE; } if( fdim != 2 && fdim != 3 ) { std::cerr << "Unsupported image dimension" << std::endl; return EXIT_FAILURE; } /** * After the checking, we can add the default parameters; */ std::string arguments; std::string transformation( " -t SyN[1.0] "); std::string regularization( " -r Gauss[3,0.5] "); std::string metric = std::string( " -m PR[" ) + std::string( argv[1] ) + std::string( "," ) + std::string( argv[2] ) + std::string( ",1,3] " ); std::string outputNaming( " -o ANTS.nii.gz " ); long maxSize = vnl_math_min( fixedImageIO->GetDimensions( 0 ), movingImageIO->GetDimensions( 0 ) ); for( unsigned int d = 1; d < fdim; d++ ) { long tmpMax = vnl_math_max( fixedImageIO->GetDimensions( d ), movingImageIO->GetDimensions( d ) ); if( maxSize < tmpMax ) { maxSize = tmpMax; } } unsigned int numberOfLevels = static_cast( vcl_log( (double)maxSize / 32 ) / vcl_log( (double) 2 ) ) + 1; std::string iterations( " -i " ); for( int n = numberOfLevels; n > 0; n-- ) { itk::OStringStream buf; unsigned long numberOfIterations = ( 5 << (n-1) ); buf << numberOfIterations << "x"; iterations += buf.str(); } iterations = iterations.substr( 0, iterations.length()-1 ); itk::OStringStream dimBuf; dimBuf << fdim; arguments.clear(); arguments = std::string( " ANTS " ) + dimBuf.str() + iterations + transformation + regularization + metric + outputNaming; dim = fdim; std::cout << arguments << std::endl; unsigned int my_argc = 0; std::string::size_type delimPos = 0; std::string::size_type tokenPos = 0; std::string::size_type pos = 0; while( true ) { delimPos = arguments.find_first_of( " ", pos ); tokenPos = arguments.find_first_not_of( " ", pos ); if( std::string::npos != delimPos && std::string::npos != tokenPos && tokenPos < delimPos ) { my_argc++; } else if( std::string::npos == delimPos ) { if( std::string::npos != tokenPos ) { my_argc++; } else { break; } } pos = delimPos + 1; } unsigned int arg_count = 0; char **my_argv = new char*[my_argc]; delimPos = 0; tokenPos = 0; pos = 0; while( true ) { delimPos = arguments.find_first_of( " ", pos ); tokenPos = arguments.find_first_not_of( " ", pos ); if( std::string::npos != delimPos && std::string::npos != tokenPos && tokenPos < delimPos ) { std::string arg = arguments.substr( pos, delimPos-pos ); my_argv[arg_count] = new char[arg.size() + 1]; strcpy( my_argv[arg_count], arg.c_str() ); arg_count++; } else if( std::string::npos == delimPos ) { if( std::string::npos != tokenPos ) { std::string arg = arguments.substr( pos ); my_argv[arg_count] = new char[arg.size() + 1]; strcpy( my_argv[arg_count], arg.c_str() ); arg_count++; } else { break; } } pos = delimPos + 1; } switch ( dim ) { case 3: ANTSex<3>( my_argc, my_argv ); break; default: ANTSex<2>( my_argc, my_argv ); } } else { switch ( dim ) { case 3: ANTSex<3>( argc, argv ); break; default: ANTSex<2>( argc, argv ); } } return EXIT_SUCCESS; } ants-1.9.2+svn680.dfsg/Examples/ANTSConformalMapping.cxx000066400000000000000000000402101147325206600227010ustar00rootroot00000000000000#include "antsCommandLineParser.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkFEM.h" #include "itkFEMLinearSystemWrapperItpack.h" #include "itkFEMElement3DC0LinearTriangularLaplaceBeltrami.h" #include "itkFEMElement3DC0LinearTriangularMembrane.h" #include "itkFEMDiscConformalMap.h" #include "vtkCallbackCommand.h" #include "vtkPolyDataWriter.h" #include "vtkPolyDataReader.h" #include #include #include #include #include template class CommandIterationUpdate : public itk::Command { public: typedef CommandIterationUpdate Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; itkNewMacro( Self ); protected: CommandIterationUpdate() {}; public: void Execute(itk::Object *caller, const itk::EventObject & event) { Execute( (const itk::Object *) caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { const TFilter * filter = dynamic_cast< const TFilter * >( object ); if( typeid( event ) != typeid( itk::IterationEvent ) ) { return; } std::cout << "Iteration " << filter->GetElapsedIterations() << " (of " << filter->GetMaximumNumberOfIterations() << "): "; std::cout << filter->GetCurrentConvergenceMeasurement() << " (threshold = " << filter->GetConvergenceThreshold() << ")" << std::endl; } }; void InitializeCommandLineOptions( itk::ants::CommandLineParser *parser ) { typedef itk::ants::CommandLineParser::OptionType OptionType; { std::string description = std::string( "Two mesh images are specified as input - 1. defines the label mesh. must have a scalar attached to vertices named 'Label'. 2. defines the feature mesh. scalar name is 'Feature'. we put the 2nd mesh's values into the flat space." ) ; OptionType::Pointer option = OptionType::New(); option->SetLongName( "input-mesh" ); option->SetShortName( 'i' ); option->SetUsageOption( 0, "[InputMesh1.vtk,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Display the mesh." ) ; OptionType::Pointer option = OptionType::New(); option->SetLongName( "display-mesh" ); option->SetShortName( 'd' ); option->SetUsageOption( 0, "[InputMesh1.vtk]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Inflation --- two params : \n 1. BandPass (smaller increases smoothing) -- e.g. 0.001. \n " ) + std::string( "2. number of iterations --- higher increases smoothing. " ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "inflate" ); option->SetShortName( 'f' ); option->SetUsageOption( 0, "[,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "SegmentationCost --- 3 params : \n 1. Float-Max-Cost : controls the size of the output region. \n " ) + std::string( "2. Float-Weight for distance cost = edge_length*W_d \n " ) + std::string( "3. Float-Weight for label cost = H(fabs( desiredLabel - localLabel ))*W_l*MaxCost \n where H is the heaviside function." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "segmentation-cost" ); option->SetShortName( 's' ); option->SetUsageOption( 0, "e.g. [40,1,0]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The output consists of one (or more) meshes ... 1. the flattened mesh with features mapped. 2. the extracted extrinisic mesh. 3. inflated mesh. "); OptionType::Pointer option = OptionType::New(); option->SetLongName( "output" ); option->SetShortName( 'o' ); option->SetUsageOption( 0, "[MyFlatMesh.vtk,,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Map to a canonical domain : pass square or circle "); OptionType::Pointer option = OptionType::New(); option->SetLongName( "canonical-domain" ); option->SetShortName( 'c' ); option->SetUsageOption( 0, "[domain]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu (short version)." ); OptionType::Pointer option = OptionType::New(); option->SetShortName( 'h' ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "help" ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "Parameterize the boundary while searching for the boundary (a bit slow and not guaranteed to be doable). " ) + std::string( "If false, we try to parameterize after the searching is done. " ) + std::string( "This option is meaningless if you pass the boundary in as an option. " ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "param-while-searching" ); option->SetShortName( 'p' ); option->SetUsageOption( 0, "0 / 1 " ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Which label (unsigned integer) to flatten. " ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "label-to-flatten" ); option->SetShortName( 'l' ); option->SetUsageOption( 0, "1" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The name of a boundary parameterization file (not implemented)." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "boundary-param" ); option->SetShortName( 'b' ); option->SetUsageOption( 0, "[filename.vtk]" ); option->SetDescription( description ); parser->AddOption( option ); } } template int ANTSConformalMapping( itk::ants::CommandLineParser *parser ) { typedef float PixelType; typedef float RealType; typedef itk::Image ImageType; // we define the options in the InitializeCommandLineOptions function // and then use them here ... typedef vtkPolyData MeshType; vtkSmartPointer labelmesh=NULL; vtkSmartPointer featuremesh=NULL; vtkSmartPointer inflatedmesh=NULL; typedef itk::FEMDiscConformalMap ParamType; typename ParamType::Pointer flattener=ParamType::New(); flattener->SetDebug(false); flattener->SetSigma(1); // flattener->SetSurfaceMesh(vtkmesh); // first find out if the user wants to inflate the mesh ... unsigned int inflate_iterations=0; float inflate_param=0; typename itk::ants::CommandLineParser::OptionType::Pointer infOption = parser->GetOption( "inflate" ); if( infOption && infOption->GetNumberOfValues() > 0 ) { if( infOption->GetNumberOfParameters() == 2 ) { inflate_param = parser->Convert(infOption->GetParameter( 0 ) ); inflate_iterations = parser->Convert(infOption->GetParameter( 1 ) ); std::cout << " you will inflate before flattening with params " << inflate_param << " applied over " << inflate_iterations << " iterations. " << std::endl; } else { std::cerr << " wrong params for inflation. ignoring. " << std::endl; std::cerr << " " << infOption->GetDescription() << std::endl; return EXIT_FAILURE; } } float maxCost=40,distCostW=1,labelCostW=0; typename itk::ants::CommandLineParser::OptionType::Pointer costOption = parser->GetOption( "segmentation-cost" ); if( costOption && costOption->GetNumberOfValues() > 0 ) { if( costOption->GetNumberOfParameters() == 3 ) { maxCost = parser->Convert(costOption->GetParameter( 0 ) ); distCostW = parser->Convert(costOption->GetParameter( 1 ) ); labelCostW = parser->Convert(costOption->GetParameter( 2 ) ); } else { std::cerr << " wrong params for cost weights. " << std::endl; std::cerr << " " << costOption->GetDescription() << std::endl; return EXIT_FAILURE; } } typename itk::ants::CommandLineParser::OptionType::Pointer displayOption = parser->GetOption( "display-mesh" ); if( displayOption && displayOption->GetNumberOfValues() > 0 ) { if( displayOption->GetNumberOfParameters() > 0 ) { std::string dispm=displayOption->GetParameter( 0 ); std::cout << " render " << dispm << std::endl; // read the vtk file ... vtkPolyDataReader *fltReader = vtkPolyDataReader::New(); fltReader->SetFileName(dispm.c_str()); fltReader->Update(); vtkSmartPointer normalGenerator = vtkSmartPointer::New(); normalGenerator->SetInput(fltReader->GetOutput()); normalGenerator->Update(); vtkRenderer* ren1 = vtkRenderer::New(); vtkRenderWindow* renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren1); vtkRenderWindowInteractor* inter = vtkRenderWindowInteractor::New(); inter->SetRenderWindow(renWin); vtkCallbackCommand *cbc = vtkCallbackCommand::New(); ren1 -> AddObserver(vtkCommand::KeyPressEvent, cbc); vtkDataSetMapper* mapper = vtkDataSetMapper::New(); mapper->SetInput( normalGenerator->GetOutput() ); mapper->SetScalarRange(0,255); vtkActor* actor = vtkActor::New(); actor->SetMapper(mapper); ren1->SetViewport(0.0, 0.0, 1.0, 1.0); ren1->AddActor(actor); renWin->Render(); inter->Start(); mapper->Delete(); actor->Delete(); ren1->Delete(); renWin->Delete(); inter->Delete(); fltReader->Delete(); return 0; } } /** * Initialization */ typename itk::ants::CommandLineParser::OptionType::Pointer inOption = parser->GetOption( "input-mesh" ); if( inOption && inOption->GetNumberOfParameters() == 2 ) { std::string innm=inOption->GetParameter( 0 ); vtkSmartPointer labReader = vtkSmartPointer::New(); labReader->SetFileName(innm.c_str()); labReader->Update(); labelmesh=vtkSmartPointer ( labReader->GetOutput() ) ; vtkDataArray* labels=labelmesh->GetPointData()->GetArray("Label"); if ( !labels ) { std::cout << " Cannot find vtk Array named 'Label' in " << innm << std::endl; std::cout <<" exiting " << std::endl; exit(1); } innm=inOption->GetParameter( 1 ); vtkSmartPointer fltReader = vtkSmartPointer::New(); fltReader->SetFileName(innm.c_str()); fltReader->Update(); featuremesh=vtkSmartPointer ( fltReader->GetOutput() ) ; vtkDataArray* feats=featuremesh->GetPointData()->GetArray("Feature"); if ( !feats ) { std::cout << " Cannot find vtk Array named 'Feature' in " << innm << std::endl; std::cout <<" continuing " << std::endl; } /** inflation */ if ( inflate_iterations > 0 ) { vtkSmartPointer smoother = vtkSmartPointer::New(); smoother->SetInput(labelmesh); smoother->SetNumberOfIterations( (int) inflate_iterations ); smoother->BoundarySmoothingOn(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(180.0); smoother->SetEdgeAngle(180.0); smoother->SetPassBand( inflate_param ); // smaller values increase smoothing smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOff(); smoother->Update(); inflatedmesh=vtkSmartPointer (smoother->GetOutput()); std::cout << " done smoothing "<< std::endl; flattener->SetSurfaceMesh(inflatedmesh); } else flattener->SetSurfaceMesh(labelmesh); flattener->SetSurfaceFeatureMesh(featuremesh); } bool paramws = parser->template Convert( parser->GetOption( "param-while-searching" )->GetValue() ); flattener->SetParamWhileSearching(paramws); unsigned int labeltoflatten = parser->template Convert( parser->GetOption( "label-to-flatten" )->GetValue() ); flattener->SetLabelToFlatten(labeltoflatten); std::string canonicaldomain=parser->GetOption( "canonical-domain" )->GetValue(); // canonicaldomain=ConvertToLowerCase( canonicaldomain ); std::cout << " you will map label " << labeltoflatten << " to a " << canonicaldomain << std::endl; if (canonicaldomain == std::string("circle") ) flattener->SetMapToCircle(); else if (canonicaldomain == std::string("square") ) flattener->SetMapToSquare(); else { std::cout <<" that domain is not an option -- exiting. " << std::endl; return 1; } std::string boundaryparam=parser->GetOption( "boundary-param" )->GetValue(); // do stuff -- but not implemented yet // flattener->SetDiscBoundaryList(NULL); std::cout << " you will flatten " << labeltoflatten << ". param while searching? " << paramws << std::endl; flattener->SetSigma(1); flattener->SetMaxCost(maxCost); flattener->SetDistanceCostWeight(distCostW); flattener->SetLabelCostWeight(labelCostW); std::cout << " MC " << maxCost << " DW " << distCostW << " LW " << labelCostW << std::endl; flattener->ExtractSurfaceDisc(); std::cout << " begin conformal mapping "; flattener->ConformalMap(); /** * output */ typename itk::ants::CommandLineParser::OptionType::Pointer outputOption = parser->GetOption( "output" ); if( outputOption && outputOption->GetNumberOfValues() > 0 ) { if( outputOption->GetNumberOfParameters() > 0 ) { for ( unsigned int p = 0 ; p < outputOption->GetNumberOfParameters() ; p++ ) { if ( p == 0 ) { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(flattener->m_DiskSurfaceMesh); std::string outnm=outputOption->GetParameter( p ); std::cout << " writing " << outnm << std::endl; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); if ( flattener->m_DiskSurfaceMesh ) writer->Update(); } if ( p == 1 ) { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(flattener->m_ExtractedSurfaceMesh); std::string outnm=outputOption->GetParameter( 1 ); std::cout << " writing " << outnm << std::endl; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); if ( flattener->m_ExtractedSurfaceMesh ) writer->Update(); } if ( p == 2 && inflatedmesh ) { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(inflatedmesh); std::string outnm=outputOption->GetParameter( 2 ); std::cout << " writing " << outnm << std::endl; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); writer->Update(); } } } } return EXIT_SUCCESS; } int main( int argc, char *argv[] ) { if ( argc < 2 ) { std::cout << "Usage: " << argv[0] << " args" << std::endl; std::cout << " try " << argv[0] << " --help or -h " << std::endl; exit( 1 ); } itk::ants::CommandLineParser::Pointer parser = itk::ants::CommandLineParser::New(); parser->SetCommand( argv[0] ); std::string commandDescription = std::string( "A tool for conformal mapping to various canonical coordinate systems: disc, square " ) + std::string( " operates on 3D vtk triangulated meshes.") + std::string(" Open problems include computation of, consistent orientation of and parameterization of the boundary-condition defining loop. Should we use curve matching ? Knot points? Min distortion? " ); parser->SetCommandDescription( commandDescription ); InitializeCommandLineOptions( parser ); parser->Parse( argc, argv ); if( argc < 2 || parser->Convert( parser->GetOption( "help" )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, false ); exit( EXIT_FAILURE ); } else if( parser->Convert( parser->GetOption( 'h' )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, true ); exit( EXIT_FAILURE ); } ANTSConformalMapping<3>( parser ); } ants-1.9.2+svn680.dfsg/Examples/ANTSIntegrateVectorField.cxx000066400000000000000000000374771147325206600235430ustar00rootroot00000000000000 #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "vnl/algo/vnl_determinant.h" #include "itkWarpImageFilter.h" #include "itkImageFileWriter.h" // #include "itkScalarImageToHistogramGenerator.h" // #include "itkImageToHistogramGenerator.h" #include "itkRescaleIntensityImageFilter.h" #include "vnl/algo/vnl_determinant.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkBinaryThresholdImageFilter.h" #include "itkDanielssonDistanceMapImageFilter.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkLaplacianRecursiveGaussianImageFilter.h" #include "ReadWriteImage.h" #include "itkGradientRecursiveGaussianImageFilter.h" template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType low, typename TImage::PixelType high, typename TImage::PixelType replaceval, typename TImage::Pointer input) { //std::cout << " Binary Thresh " << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } template typename TImage::Pointer GetVectorComponent(typename TField::Pointer field, unsigned int index) { // Initialize the Moving to the displacement field typedef TField FieldType; typedef TImage ImageType; typename ImageType::Pointer sfield=ImageType::New(); sfield->SetSpacing( field->GetSpacing() ); sfield->SetOrigin( field->GetOrigin() ); sfield->SetDirection( field->GetDirection() ); sfield->SetLargestPossibleRegion(field->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(field->GetRequestedRegion() ); sfield->SetBufferedRegion( field->GetBufferedRegion() ); sfield->Allocate(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( field, field->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TField::PixelType v1=vfIter.Get(); sfield->SetPixel(vfIter.GetIndex(),v1[index]); } return sfield; } template typename TImage::Pointer SmoothImage(typename TImage::Pointer image, float sig) { // find min value typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter(image,image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TImage::PixelType v1=vfIter.Get(); if (vnl_math_isnan(v1)) vfIter.Set(0); } typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); typename TImage::Pointer out= filter->GetOutput(); return out; } template void SmoothDeformation(typename TImage::Pointer vectorimage, float sig) { typedef itk::Vector VectorType; typedef itk::Image ImageType; typename ImageType::Pointer subimgx=GetVectorComponent(vectorimage,0); subimgx=SmoothImage(subimgx,sig); typename ImageType::Pointer subimgy=GetVectorComponent(vectorimage,1); subimgy=SmoothImage(subimgy,sig); typename ImageType::Pointer subimgz=GetVectorComponent(vectorimage,2); subimgz=SmoothImage(subimgz,sig); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( vectorimage, vectorimage->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { VectorType vec; vec[0]=subimgx->GetPixel(Iterator.GetIndex()); vec[1]=subimgy->GetPixel(Iterator.GetIndex()); vec[2]=subimgz->GetPixel(Iterator.GetIndex()); Iterator.Set(vec); ++Iterator; } return; } template float IntegrateLength( typename TImage::Pointer gmsurf, typename TImage::Pointer thickimage, typename TImage::IndexType velind, typename TField::Pointer lapgrad, float itime, float starttime, float finishtime, bool timedone, float deltaTime, typename TInterp::Pointer vinterp , typename TImage::SpacingType spacing, float vecsign, float timesign, float gradsign ) { typedef TField TimeVaryingVelocityFieldType; typedef typename TField::PixelType VectorType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename TField::IndexType DIndexType; typedef typename TField::PointType DPointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; VectorType zero; zero.Fill(0); VectorType disp; disp.Fill(0); unsigned int ct=0; DPointType pointIn1; DPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType vcontind; DPointType pointIn3; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::IndexType IndexType; unsigned int m_NumberOfTimePoints=2; IndexType index; for (unsigned int jj=0; jjGetSpacing()[jj]; } itime=starttime; timedone=false; float totalmag=0; while ( !timedone ) { float scale = 1;//*m_DT[timeind]/m_DS[timeind]; // std::cout << " scale " << scale << std::endl; double itimetn1 = itime - timesign*deltaTime*scale; double itimetn1h = itime - timesign*deltaTime*0.5*scale; if (itimetn1h < 0 ) itimetn1h=0; if (itimetn1h > m_NumberOfTimePoints-1 ) itimetn1h=m_NumberOfTimePoints-1; if (itimetn1 < 0 ) itimetn1=0; if (itimetn1 > m_NumberOfTimePoints-1 ) itimetn1=m_NumberOfTimePoints-1; // first get current position of particle IndexType index; for (unsigned int jj=0; jjGetSpacing()[jj]; } // std::cout << " ind " << index << std::endl; // now index the time varying field at that position. typename DefaultInterpolatorType::OutputType f1; f1.Fill(0); typename DefaultInterpolatorType::OutputType f2; f2.Fill(0); typename DefaultInterpolatorType::OutputType f3; f3.Fill(0); typename DefaultInterpolatorType::OutputType f4; f4.Fill(0); typename DefaultInterpolatorType::ContinuousIndexType Y1; typename DefaultInterpolatorType::ContinuousIndexType Y2; typename DefaultInterpolatorType::ContinuousIndexType Y3; typename DefaultInterpolatorType::ContinuousIndexType Y4; for (unsigned int jj=0; jjGetSpacing()[jj]; Y1[jj]=vcontind[jj]; Y2[jj]=vcontind[jj]; Y3[jj]=vcontind[jj]; Y4[jj]=vcontind[jj]; } //Y1[ImageDimension]=itimetn1; //Y2[ImageDimension]=itimetn1h; //Y3[ImageDimension]=itimetn1h; // Y4[ImageDimension]=itime; f1 = vinterp->EvaluateAtContinuousIndex( Y1 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f2 = vinterp->EvaluateAtContinuousIndex( Y2 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f3 = vinterp->EvaluateAtContinuousIndex( Y3 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f4 = vinterp->EvaluateAtContinuousIndex( Y4 ); for (unsigned int jj=0; jjGetPixel(myind) < 1 ) { timedone=true; } if ( ct > 1000 ) { std::cout << " stopping b/c exceed 1000 points " << voxmag << std::endl; timedone=true;} if ( voxmag < 0.1 ) { timedone=true;} } return totalmag; } template int IntegrateVectorField(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; double dT=0.001; float gradstep= 1./dT;//atof(argv[3])*(-1.0); std::string vectorfn = std::string(argv[1]); std::string roifn = std::string(argv[2]); int argct=3; std::string outname=std::string(argv[argct]); argct++; std::string lenoutname=std::string(""); if (argc > argct) lenoutname=std::string(argv[argct]); argct++; if (argc > argct) gradstep*=atof(argv[argct]); argct++; typename ImageType::Pointer ROIimage; ReadImage(ROIimage,roifn.c_str()); typename ImageType::Pointer thickimage; ReadImage(thickimage,roifn.c_str()); thickimage->FillBuffer(0); typename DeformationFieldType::Pointer VECimage; ReadImage(VECimage,vectorfn.c_str()); SpacingType spacing=ROIimage->GetSpacing(); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( ROIimage, ROIimage->GetLargestPossibleRegion().GetSize() ); double timezero=0; //1 typename ImageType::SizeType s= ROIimage->GetLargestPossibleRegion().GetSize(); double timeone=1;//(s[ImageDimension]-1-timezero); float starttime=timezero;//timezero; float finishtime=timeone;//s[ImageDimension]-1;//timeone; typename DeformationFieldType::IndexType velind; float timesign=1.0; if (starttime > finishtime ) timesign= -1.0; typedef DeformationFieldType TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType2; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction ScalarInterpolatorType; VectorType zero; zero.Fill(0); DPointType pointIn1; DPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType vcontind; DPointType pointIn3; typedef itk::ImageRegionIteratorWithIndex VIteratorType; VIteratorType VIterator( VECimage, VECimage->GetLargestPossibleRegion().GetSize() ); VIterator.GoToBegin(); while( !VIterator.IsAtEnd() ) { VectorType vec=VIterator.Get(); float mag=0; for (unsigned int qq=0; qq 0) vec=vec/mag; VIterator.Set(vec*gradstep); ++VIterator; } Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { velind=Iterator.GetIndex(); float itime = starttime; bool timedone = false; VectorType disp; disp.Fill(0.0); double deltaTime=dT,vecsign=1.0; float gradsign=1.0; if ( ROIimage->GetPixel(velind) == 2 ) { vinterp->SetInputImage(VECimage); gradsign=-1.0; vecsign=-1.0; float len1=IntegrateLength (ROIimage, thickimage, velind, VECimage, itime, starttime, finishtime, timedone, deltaTime, vinterp, spacing,vecsign, gradsign, timesign); gradsign=1.0; vecsign=1; float len2=IntegrateLength (ROIimage, thickimage, velind, VECimage, itime, starttime, finishtime, timedone, deltaTime, vinterp, spacing,vecsign, gradsign, timesign ); float totalength=len1+len2; thickimage->SetPixel(velind,totalength); if ( (totalength)> 0 ) std::cout << " len1 " << len1 << " len2 " << len2 << " ind " << velind << std::endl; } ++Iterator; } WriteImage(thickimage,lenoutname.c_str()); return 0; } int main(int argc, char *argv[]) { if ( argc < 4) { std::cout << "Usage: " << argv[0] << " VecImageIN.nii.gz ROIMaskIN.nii.gz FibersOUT.vtk LengthImageOUT.nii.gz " << std::endl; std::cout << " The vector field should have vectors as voxels , the ROI is an integer image, fibers out will be vtk text files .... " << std::endl; std::cout << " ROI-Mask controls where the integration is performed and the start point region ... " << std::endl; std::cout << " e.g. the brain will have value 1 , the ROI has value 2 , then all starting seed points " << std::endl; std::cout << " for the integration will start in the region labeled 2 and be constrained to the region labeled 1. " << std::endl; return 1; } std::string ifn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(ifn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(ifn.c_str()); imageIO->ReadImageInformation(); unsigned int dim = imageIO->GetNumberOfDimensions(); switch ( dim ) { case 2: IntegrateVectorField<2>(argc,argv); break; case 3: IntegrateVectorField<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return EXIT_SUCCESS; return 1; } ants-1.9.2+svn680.dfsg/Examples/ANTSJacobian.cxx000066400000000000000000000354701147325206600211670ustar00rootroot00000000000000 //#include "DoSomethingToImage.cxx" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "vnl/algo/vnl_determinant.h" #include "ReadWriteImage.h" #include "vnl/algo/vnl_determinant.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h" #include "itkVectorImageFileReader.h" #include "itkMatrixOffsetTransformBase.h" #include "itkWarpImageMultiTransformFilter.h" template typename TImage::Pointer VectorAniDiff(typename TImage::Pointer img, unsigned int iters) { double timeStep = 0.065; typedef TImage VectorImageType; typedef itk::VectorCurvatureAnisotropicDiffusionImageFilter< VectorImageType, VectorImageType > FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( img ); filter->SetNumberOfIterations( iters ); filter->SetTimeStep( timeStep ); filter->SetConductanceParameter(1.0); filter->Update(); // Software Guide : EndCodeSnippet return filter->GetOutput(); } template typename TImage::Pointer GenerateGridImage(TImage* img, unsigned int gridsize) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; itk::ImageRegionIteratorWithIndex wimIter( img, img->GetLargestPossibleRegion() ); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) wimIter.Set(2); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) { typename ImageType::IndexType ind=wimIter.GetIndex(); for (int i=0; i<2; i++) { if (ind[i] % gridsize == 0) wimIter.Set(0); // if (ind[i] % (gridsize+1) == 0) wimIter.Set(0);// tartan } } wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) { typename ImageType::IndexType ind=wimIter.GetIndex(); typename ImageType::IndexType ind2=wimIter.GetIndex(); for (int i=0; i<2; i++) { ind2[i]=ind[i]-1; if (ind2[i] < 0) ind2[i]=0; } for (int i=0; i<2; i++) { //this creates a 3-d effect //if (ind[i] % gridsize == 0) img->SetPixel(ind2,2); //this gives double thickness if (ind[i] % gridsize == 0) img->SetPixel(ind2,0); } } return img; } template typename ImageType::Pointer ReadAnImage(char* fn) { // Read the image files begin typedef itk::ImageFileReader< ImageType > FileSourceType; typename FileSourceType::Pointer reffilter = FileSourceType::New(); reffilter->SetFileName( fn ); try { reffilter->Update(); } catch( ... ) { return NULL; } return reffilter->GetOutput(); } template typename TDeformationField::PixelType TransformVector(TDeformationField* field, typename TImage::IndexType index ) { enum { ImageDimension = TImage::ImageDimension }; typename TDeformationField::PixelType vec=field->GetPixel(index); typename TDeformationField::PixelType newvec; newvec.Fill(0); for (unsigned int row=0; rowGetDirection()[row][col]; return newvec; } template void ComputeJacobian(TDeformationField* field,char* fnm, char* maskfn, bool uselog=false, bool norm=false, bool use2ndorder=false) { typedef TImage ImageType; typedef TDeformationField FieldType; enum { ImageDimension = TImage::ImageDimension }; typedef itk::Image FloatImageType; typename FloatImageType::RegionType m_JacobianRegion; typename FloatImageType::Pointer mask=NULL; mask=ReadAnImage(maskfn); if (!field) { return; } typename TImage::SizeType s= field->GetLargestPossibleRegion().GetSize(); typename TImage::SpacingType sp= field->GetSpacing(); typename FloatImageType::Pointer m_FloatImage=NULL; m_FloatImage = FloatImageType::New(); m_FloatImage->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); m_FloatImage->SetBufferedRegion( field->GetLargestPossibleRegion().GetSize() ); m_FloatImage->SetSpacing(field->GetSpacing()); m_FloatImage->SetDirection( field->GetDirection() ); m_FloatImage->SetOrigin(field->GetOrigin()); m_FloatImage->Allocate(); m_FloatImage->FillBuffer(0); typename ImageType::Pointer grid = GenerateGridImage(m_FloatImage,7); if (grid) { typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > TransformType; typedef itk::WarpImageMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(grid); warper->SetEdgePaddingValue( 0); warper->SetSmoothScale(1); warper->PushBackDeformationFieldTransform(field); warper->SetOutputOrigin(field->GetOrigin()); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(field->GetSpacing()); warper->SetOutputDirection(field->GetDirection()); warper->Update(); grid=warper->GetOutput(); typedef itk::ImageFileWriter writertype; typename writertype::Pointer writer = writertype::New(); std::string fng=std::string(fnm)+"grid.nii"; writer->SetFileName(fng.c_str()); writer->SetInput(grid); writer->Write(); std::cout << " Grid done "; } typename FloatImageType::SizeType m_FieldSize = field->GetLargestPossibleRegion().GetSize(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator wimIter( m_FloatImage, m_FloatImage->GetLargestPossibleRegion() ); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) wimIter.Set(1.0); typedef vnl_matrix MatrixType; MatrixType jMatrix,idMatrix,avgMatrix; jMatrix.set_size(ImageDimension,ImageDimension); avgMatrix.set_size(ImageDimension,ImageDimension); avgMatrix.fill(0); itk::ImageRegionIteratorWithIndex m_FieldIter( field, field->GetLargestPossibleRegion() ); typename TImage::IndexType rindex; typename TImage::IndexType ddrindex; typename TImage::IndexType ddlindex; typename TImage::IndexType difIndex[ImageDimension][2]; double det=0.0; unsigned int posoff=1; float difspace=1.0; float space=1.0; if (posoff == 0) difspace=1.0; typedef itk::Vector VectorType; typename FieldType::PixelType dPix; typename FieldType::PixelType lpix; typename FieldType::PixelType llpix; typename FieldType::PixelType rpix; typename FieldType::PixelType rrpix; typename FieldType::PixelType cpix; float volumeelt=1.0; for (int j=0;j(field,rindex); for(unsigned int row=0; row< ImageDimension;row++) { difIndex[row][0]=rindex; difIndex[row][1]=rindex; ddrindex=rindex; ddlindex=rindex; if ((unsigned int) rindex[row] < (unsigned int) m_FieldSize[row]-2) { difIndex[row][0][row]=rindex[row]+posoff; ddrindex[row]=rindex[row]+posoff*2; } if (rindex[row] > 1 ) { difIndex[row][1][row]=rindex[row]-1; ddlindex[row]=rindex[row]-2; } float h=1; space=1.0; // should use image spacing here? rpix = TransformVector(field,difIndex[row][1]); rpix = rpix*h+cpix*(1.-h); lpix = TransformVector(field,difIndex[row][0]); lpix = lpix*h+cpix*(1.-h); // dPix = ( rpix - lpix)*(1.0)/(2.0); rrpix = TransformVector(field,ddrindex); rrpix = rrpix*h+rpix*(1.-h); llpix = TransformVector(field,ddlindex); llpix = llpix*h+lpix*(1.-h); dPix=( lpix*(-8.0) + rpix*8.0 - rrpix + llpix )*(-1.0)*space/(12.0); //4th order centered difference if ( use2ndorder) dPix=( lpix - rpix )*(1.0)*space/(2.0*h); //4th order centered difference for(unsigned int col=0; col< ImageDimension;col++){ float val; if (row == col) val=dPix[col]/sp[col]+1.0; else val = dPix[col]/sp[col]; // std::cout << " row " << row << " col " << col << " val " << val << std::endl; jMatrix.put(col,row,val); avgMatrix.put(col,row,avgMatrix.get(col,row)+val); } } //the determinant of the jacobian matrix // std::cout << " get det " << std::endl; det = vnl_determinant(jMatrix); // float prodval = m_FloatImage->GetPixel(rindex); if (det < 0.0) det = 0; m_FloatImage->SetPixel(rindex, det ); //totaljac+=det; }//oktosample if } std::cout <<" avg Mat " << avgMatrix / (float)ct << std::endl; if (norm && mask) { std::cout <<" using mask && normalizing " << std::endl; /* typedef itk::DiscreteGaussianImageFilter dgf; float sig=2.0; typename FloatImageType::Pointer temp; { typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOff(); filter->SetMaximumError(.01f); filter->SetInput(m_FloatImage); filter->Update(); // m_FloatImage=filter->GetOutput(); temp=filter->GetOutput(); } { typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOff(); filter->SetMaximumError(.01f); filter->SetInput(temp); filter->Update(); // m_FloatImage=filter->GetOutput(); temp=filter->GetOutput(); } */ double total = 0.0; unsigned long ct = 0; for( m_FieldIter.GoToBegin() ; !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { rindex=m_FieldIter.GetIndex(); if (mask->GetPixel(rindex) > 0 ) { total+=m_FloatImage->GetPixel(rindex); ct++; } else m_FloatImage->SetPixel(rindex,0); } total /= (double) ct; for( m_FieldIter.GoToBegin() ; !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { rindex=m_FieldIter.GetIndex(); double val = m_FloatImage->GetPixel(rindex)/total; if (mask->GetPixel(rindex) > 0 ) m_FloatImage->SetPixel(rindex,val); else m_FloatImage->SetPixel(rindex,0); } } for( m_FieldIter.GoToBegin() ; !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { rindex=m_FieldIter.GetIndex(); double val = m_FloatImage->GetPixel(rindex); if (uselog && val > 0) val=log(val); else if (uselog && val < 0) val = log(0.01); if (uselog ) m_FloatImage->SetPixel(rindex,val); } typedef itk::ImageFileWriter writertype; typename writertype::Pointer writer = writertype::New(); std::string fn=std::string(fnm)+"jacobian.nii"; if (uselog) fn=std::string(fnm)+"logjacobian.nii"; writer->SetFileName(fn.c_str()); writer->SetInput(m_FloatImage); writer->Write(); return; } template int Jacobian(int argc, char *argv[]) { // std::cout << " enter " << ImageDimension << std::endl; if ( argc < 3 ) { std::cout << "Usage: Jacobian gWarp outfile uselog maskfn normbytotalbool " << std::endl; return 1; } typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::VectorImageFileReader ReaderType; //std::cout << "read warp " << std::string(argv[1]) << std::endl; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[1] ); reader->SetUseAvantsNamingConvention( true ); reader->Update(); typename FieldType::Pointer gWarp=reader->GetOutput(); // //std::cout << "read warp 2 " << std::endl; // typename FieldType::Pointer gWarp = ReadWarpFromFile(argv[1],"vec.nii"); // here hWarp is changed in place to be fWarp // Jacobian(gWarp,argv[2]); // std::cout << " vecanidiff " << std::endl; // gWarp = VectorAniDiff(gWarp , atoi(argv[3]) ); // std::cout << " vecanidiffdone " << std::endl; bool uselog=false; if (argc > 3) uselog=(bool)atoi(argv[3]); bool norm=false; if (argc > 5) norm=(bool)atoi(argv[5]); bool use2ndorder=true; if (argc > 6) use2ndorder=(bool)atoi(argv[6]); // std::cout << " name "<< argv[2] << " mask " << argv[4] << " norm " << norm << " Log " << uselog << std::endl; ComputeJacobian(gWarp,argv[2],argv[4],uselog,norm,use2ndorder); // DiffeomorphicJacobian(gWarp,1,argv[2]); // if (argc > 3) DiffeomorphicMetric(gWarp,argv[2]); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " ImageDim gWarp outfile uselog maskfn normbytotalbool use-2nd-order-central-difference-boolean " << std::endl; std::cout <<" for example " << std::endl << " ANTSJacobian 3 myWarp.nii Output 1 templatebrainmask.nii 1 " << std::endl; std::cout << " the last 1 normalizes the jacobian by the total in the mask. use this to adjust for head size. " << std::endl; return 1; } switch( atoi( argv[1] ) ) { case 2: Jacobian<2>(argc-1,argv+1); break; case 3: Jacobian<3>(argc-1,argv+1); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return EXIT_SUCCESS; return 1; } ants-1.9.2+svn680.dfsg/Examples/ANTSUseDeformationFieldToGetAffineTransform.cxx000066400000000000000000000361201147325206600273120ustar00rootroot00000000000000/** ANTS Landmarks used to initialize an affine transform ... */ #include #include #include #include "itkLandmarkBasedTransformInitializer.h" #include "itkImage.h" #include "itkImageIOBase.h" #include "itkImageIOFactory.h" #include #include #include "ReadWriteImage.h" #include "itkTransformFileWriter.h" #include "itkVectorImageFileReader.h" // #include "ANTS_affine_registration2.h" #include // #include #include "vnl/algo/vnl_qr.h" template void DumpTransformForANTS3D(const TransformAPointer &transform, StringType &ANTS_prefix); template void GetAffineTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &transform); template void GetRigidTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &transform); template void FetchLandmarkMappingFromDeformationField(const StringType &deformation_field_file_name, float load_ratio, PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, itk::Image::Pointer maskimg); // // The test specifies a bunch of fixed and moving landmarks and test if the // fixed landmarks after transform by the computed transform coincides // with the moving landmarks.... int DeformationFieldBasedTransformInitializer3D(int argc, char * argv[]) { const unsigned int Dim = 3; typedef itk::Point PointType; typedef itk::Image ImageType; typedef std::vector PointContainerType; const char *deformation_field_file_name = argv[1]; float load_ratio = atof(argv[2]); bool bRigid = (strcmp(argv[3], "rigid")==0); std::string ANTS_prefix(argv[4]); std::string maskfn=std::string(""); if (argc > 5 ) maskfn=std::string(argv[5]); std::cout << " mask " << maskfn << std::endl; // input PointContainerType fixedLandmarks, movingLandmarks; // output typedef itk::MatrixOffsetTransformBase< double, 3, 3> AffineTransformType; AffineTransformType::Pointer aff = AffineTransformType::New(); ImageType::Pointer maskimg=NULL; if ( maskfn.length() > 4 ) ReadImage(maskimg,maskfn.c_str()); FetchLandmarkMappingFromDeformationField(deformation_field_file_name, load_ratio, fixedLandmarks, movingLandmarks, maskimg); if (bRigid) GetRigidTransformFromTwoPointSets3D(fixedLandmarks, movingLandmarks, aff); else GetAffineTransformFromTwoPointSets3D(fixedLandmarks, movingLandmarks, aff); std::cout << "affine:" << aff; DumpTransformForANTS3D(aff, ANTS_prefix); return EXIT_SUCCESS; // initializer->SetFixedLandmarks(fixedLandmarks); // initializer->SetMovingLandmarks(movingLandmarks); // initializer->SetTransform( transform ); // initializer->InitializeTransform(); // // transform->Print(std::cout); // // // transform the transform to ANTS format // std::string ANTS_prefix(argv[4]); // // // typedef itk::MatrixOffsetTransformBase< double, 3, 3> AffineTransformType; // AffineTransformType::Pointer aff = AffineTransformType::New(); // GetAffineTransformFromTwoPointSets3D(fixedLandmarks, movingLandmarks, aff); // std::cout << "affine:" << aff; // // // if (bRigid) // DumpTransformForANTS3D(transform, ANTS_prefix); // else // DumpTransformForANTS3D(aff, ANTS_prefix); // // // return EXIT_SUCCESS; } template void GetRigidTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &aff){ // Set the transform type.. typedef itk::VersorRigid3DTransform< double > TransformType; TransformType::Pointer transform = TransformType::New(); typedef float PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > FixedImageType; typedef itk::Image< PixelType, Dimension > MovingImageType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::LandmarkBasedTransformInitializer< TransformType, FixedImageType, MovingImageType > TransformInitializerType; TransformInitializerType::Pointer initializer = TransformInitializerType::New(); initializer->SetFixedLandmarks(fixedLandmarks); initializer->SetMovingLandmarks(movingLandmarks); initializer->SetTransform( transform ); initializer->InitializeTransform(); std::cout << "rigid: " << transform << std::endl; // ANTS transform file type // typedef itk::MatrixOffsetTransformBase< double, Dimension, Dimension > AffineTransformType; // typename AffineTransformType::Pointer aff = AffineTransformType::New(); PostConversionInAffine(transform, aff); } ////////// // x: fixedLandmarks // y: movingLandmarks // (A,t,c) : affine transform, A:3*3, t: 3*1 c: 3*1 (c is the center of all points in x) // y-c = A*(x-c) + t; // steps: // 1. c = average of points of x // 2. let y1 = y-c; x1 = x - c; x11 = [x1; 1 ... 1] // extend x11 // 3. minimize (y1-A1*x11)^2, A1 is a 3*4 matrix // 4. A = A1(1:3, 1:3), t = A1(1:3, 4); // step 3: // A11 = (y1*x11')*(x11*x11')^(-1) // type info: // assume PointContainerType is std::vector // assume TrnasformPointerType is MatrixOffsetTransformBase template void GetAffineTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &transform){ const int Dim=3; int n = fixedLandmarks.size(); vnl_matrix y(Dim, n), x(Dim, n); for(int i=0; i c(Dim); for(int j=0; j y1(Dim, n), x11(Dim+1, n); for(int i=0; i x_tmp(Dim), x1_tmp(Dim+1); x_tmp = x.get_column(i)-c; for(int j=0; j A11(Dim, Dim+1); vnl_matrix x11t = x11.transpose(); //vnl_matrix_inverse tmp(x11 * x11t); // BA -- removed this -- not used? vnl_svd qr( x11t ); // can use vnl_qr A11 = qr.inverse() * (y1.transpose()); A11 = A11.transpose(); vnl_matrix A(Dim,Dim); A = A11.extract(Dim, Dim, 0, 0); // std::cout << "y=" << y << std::endl; // std::cout << "x=" << x << std::endl; // // std::cout << "y1=" << y1 << std::endl; // std::cout << "x11=" << x11 << std::endl; std::cout << "A11=" << A11 << std::endl; vnl_vector t = A11.get_column(Dim); typedef typename TransformPointerType::ObjectType TransformType; typedef typename TransformType::InputPointType PointType; typedef typename TransformType::OutputVectorType VectorType; typedef typename TransformType::MatrixType MatrixType; PointType center; for(int i=0;iSetCenter(center); transform->SetTranslation(translation); transform->SetMatrix(matrix); return; } //////////////////////////////////////////////////////////////////////// //Stripped from ANTS_affine_registration2.h template void WriteAffineTransformFile(TransformPointerType &transform, StringType filename){ itk::TransformFileWriter::Pointer transform_writer; transform_writer = itk::TransformFileWriter::New(); transform_writer->SetFileName(filename); transform_writer->SetInput(transform); try{ transform_writer->Update(); } catch( itk::ExceptionObject &err){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl <<"Exception in writing tranform file: " << std::endl << filename << std::endl; return; } return; } //////////////////////////////////////////////////////////////////////// //Stripped from ANTS_affine_registration2.h template inline void PostConversionInAffine(RunningAffineTransformPointerType& transform_running, AffineTransformPointerType &transform){ typedef typename RunningAffineTransformPointerType::ObjectType RunningAffineTransformType; typedef typename AffineTransformPointerType::ObjectType AffineTransformType; transform->SetCenter(*(reinterpret_cast (const_cast (&(transform_running->GetCenter()))))); transform->SetTranslation(*(reinterpret_cast (const_cast (&(transform_running->GetTranslation()))))); transform->SetMatrix(*(reinterpret_cast (const_cast (&(transform_running->GetMatrix()))))); // std::cout << "transform_running" << transform_running << std::endl; // std::cout << "transform" << transform << std::endl; } template void DumpTransformForANTS3D(const TransformAPointer &transform, StringType &ANTS_prefix){ const int ImageDimension = 3; // ANTS transform file type typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; AffineTransformType::Pointer transform_ANTS = AffineTransformType::New(); // typedef TransformAPointer::ObjectType TransformA; // std::cout << " writing " << ANTS_prefix << " affine " << std::endl; // std::string ANTS_affine_filename = ANTS_prefix + std::string( "Affine.txt" ); std::string ANTS_affine_filename = ANTS_prefix; std::cout << " writing ANTS affine file:" << ANTS_affine_filename << std::endl; PostConversionInAffine(transform, transform_ANTS); WriteAffineTransformFile(transform_ANTS, ANTS_affine_filename); } int DeformationFieldBasedTransformInitializer2D(int, char * []) { std::cout << " not implemented " << std::endl; return 1; /* typedef float PixelType; const unsigned int Dimension = 2; typedef itk::Image< PixelType, Dimension > FixedImageType; typedef itk::Image< PixelType, Dimension > MovingImageType; typedef itk::Image< PixelType, Dimension > ImageType; typename FixedImageType::Pointer fixedimage; typename MovingImageType::Pointer movingimage; ReadImage(fixedimage,argv[1]); ReadImage(movingimage,argv[2]); // Set the transform type.. typedef itk::Rigid2DTransform< double > TransformType; */ return EXIT_SUCCESS; } template void FetchLandmarkMappingFromDeformationField(const StringType &deformation_field_file_name, float load_ratio, PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks,itk::Image::Pointer maskimg){ const unsigned int ImageDimension = 3; typedef typename PointContainerType::value_type PointType; typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::VectorImageFileReader FieldReaderType; typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName( deformation_field_file_name ); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); fixedLandmarks.clear(); movingLandmarks.clear(); unsigned int nb_voxels = 1; itk::Size field_size = field->GetLargestPossibleRegion().GetSize(); for(unsigned int i=0; i FieldIteratorType; FieldIteratorType it(field, field->GetLargestPossibleRegion()); srand ( time(NULL) ); it.GoToBegin(); unsigned int cnt = 0; for(; (!it.IsAtEnd()) & (cnt < nb_try_to_load); ++it){ bool getpoint=true; if (maskimg) if ( maskimg->GetPixel( it.GetIndex() ) < 0.5 ) getpoint=false; if (getpoint) { if (rand() % 32767 > load_ratio * 32767) continue; PointType point1, point2; // get the output image index typename DeformationFieldType::IndexType index = it.GetIndex(); field->TransformIndexToPhysicalPoint(index, point1 ); VectorType displacement = field->GetPixel(index); for(unsigned int j = 0; jSetFileName(fn.c_str()); // imageIO->ReadImageInformation(); int dim = 3; // switch ( imageIO->GetNumberOfDimensions() ) switch ( dim ) { case 2: DeformationFieldBasedTransformInitializer2D(argc,argv); break; case 3: DeformationFieldBasedTransformInitializer3D(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ANTSUseLandmarkImagesToGetAffineTransform.cxx000066400000000000000000000353461147325206600267670ustar00rootroot00000000000000/** ANTS Landmarks used to initialize an affine transform ... */ #include "itkLandmarkBasedTransformInitializer.h" #include "itkImage.h" #include "itkImageIOBase.h" #include "itkImageIOFactory.h" #include #include #include "ReadWriteImage.h" #include "itkTransformFileWriter.h" // #include "ANTS_affine_registration2.h" #include // #include #include "vnl/algo/vnl_qr.h" template void DumpTransformForANTS3D(const TransformAPointer &transform, StringType &ANTS_prefix); template void GetAffineTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &transform); // // The test specifies a bunch of fixed and moving landmarks and test if the // fixed landmarks after transform by the computed transform coincides // with the moving landmarks.... int LandmarkBasedTransformInitializer3D(int, char * argv[]) { typedef float PixelType; const unsigned int Dimension = 3; typedef itk::Image< PixelType, Dimension > FixedImageType; typedef itk::Image< PixelType, Dimension > MovingImageType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::ImageRegionIteratorWithIndex Iterator; ImageType::Pointer fixedimage; ImageType::Pointer movingimage; ReadImage(fixedimage,argv[1]); ReadImage(movingimage,argv[2]); bool bRigid = (strcmp(argv[3], "rigid")==0); /** get all of the relevant labels in the fixed image and moving image */ typedef std::vector LabelSetType; LabelSetType myFixLabelSet; LabelSetType myMovLabelSet; /** count the labels in the image */ Iterator It ( fixedimage,fixedimage->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( fabs(label) > 0 ) { if( find( myFixLabelSet.begin(), myFixLabelSet.end(), label ) == myFixLabelSet.end() ) { // std::cout <<" f-label " << label << std::endl; myFixLabelSet.push_back( label ); } } } Iterator ItM ( movingimage,movingimage->GetLargestPossibleRegion() ); for( ItM.GoToBegin(); !ItM.IsAtEnd(); ++ItM ) { PixelType label = ItM.Get(); if( fabs(label) > 0 ) { if( find( myMovLabelSet.begin(), myMovLabelSet.end(), label ) == myMovLabelSet.end() ) { // std::cout <<" m-label " << label << std::endl; myMovLabelSet.push_back( label ); } } } std::sort(myFixLabelSet.begin(),myFixLabelSet.end()); std::sort(myMovLabelSet.begin(),myMovLabelSet.end()); LabelSetType::const_iterator fit; LabelSetType::const_iterator mit=myMovLabelSet.begin(); for( fit = myFixLabelSet.begin(); fit != myFixLabelSet.end(); ++fit ) { float fixlabel= *fit ; float movlabel= *mit ; std::cout << " fix-label " << fixlabel << " movlabel " << movlabel << std::endl; if ( movlabel != fixlabel ) { std::cout <<" labels do not match -- exiting " << std::endl; exit(1); } ++mit; } // Set the transform type.. typedef itk::VersorRigid3DTransform< double > TransformType; TransformType::Pointer transform = TransformType::New(); typedef itk::LandmarkBasedTransformInitializer< TransformType, FixedImageType, MovingImageType > TransformInitializerType; TransformInitializerType::Pointer initializer = TransformInitializerType::New(); // Set fixed and moving landmarks TransformInitializerType::LandmarkPointContainer fixedLandmarks; TransformInitializerType::LandmarkPointContainer movingLandmarks; TransformInitializerType::LandmarkPointType point; TransformInitializerType::LandmarkPointType tmp; // compute the CoM's of all the landmarks ImageType::SpacingType spacing=fixedimage->GetSpacing(); for( fit = myFixLabelSet.begin(); fit != myFixLabelSet.end(); ++fit ) { float currentlabel= *fit ; float totalct=0; TransformInitializerType::LandmarkPointType myCenterOfMass; myCenterOfMass.Fill(0); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( label == currentlabel ) { totalct++; // compute center of mass ImageType::PointType point; fixedimage->TransformIndexToPhysicalPoint(It.GetIndex(), point); for (unsigned int i=0; iGetSpacing(); for( mit = myMovLabelSet.begin(); mit != myMovLabelSet.end(); ++mit ) { float currentlabel= *mit ; float totalct=0; TransformInitializerType::LandmarkPointType myCenterOfMass; myCenterOfMass.Fill(0); for( ItM.GoToBegin(); !ItM.IsAtEnd(); ++ItM ) { PixelType label = ItM.Get(); if( label == currentlabel ) { totalct++; // compute center of mass ImageType::PointType point; movingimage->TransformIndexToPhysicalPoint(ItM.GetIndex(), point); for (unsigned int i=0; iSetFixedLandmarks(fixedLandmarks); initializer->SetMovingLandmarks(movingLandmarks); // initializer->SetFixedImage( fixedimage ); // initializer->SetMovingImage( movingimage ); initializer->SetTransform( transform ); initializer->InitializeTransform(); transform->Print(std::cout); // to transform a point // transform->TransformPoint( *fitr ) << std::endl; // transform the transform to ANTS format std::string ANTS_prefix(argv[4]); typedef itk::MatrixOffsetTransformBase< double, 3, 3> AffineTransformType; AffineTransformType::Pointer aff = AffineTransformType::New(); GetAffineTransformFromTwoPointSets3D(fixedLandmarks, movingLandmarks, aff); std::cout << "affine:" << aff; if (bRigid) DumpTransformForANTS3D(transform, ANTS_prefix); else DumpTransformForANTS3D(aff, ANTS_prefix); return EXIT_SUCCESS; } ////////// // x: fixedLandmarks // y: movingLandmarks // (A,t,c) : affine transform, A:3*3, t: 3*1 c: 3*1 (c is the center of all points in x) // y-c = A*(x-c) + t; // steps: // 1. c = average of points of x // 2. let y1 = y-c; x1 = x - c; x11 = [x1; 1 ... 1] // extend x11 // 3. minimize (y1-A1*x11)^2, A1 is a 3*4 matrix // 4. A = A1(1:3, 1:3), t = A1(1:3, 4); // step 3: // A11 = (y1*x11')*(x11*x11')^(-1) // type info: // assume PointContainerType is std::vector // assume TrnasformPointerType is MatrixOffsetTransformBase template void GetAffineTransformFromTwoPointSets3D(PointContainerType &fixedLandmarks, PointContainerType &movingLandmarks, TransformPointerType &transform){ const int Dim=3; int n = fixedLandmarks.size(); vnl_matrix y(Dim, n), x(Dim, n); for(int i=0; i c(Dim); for(int j=0; j y1(Dim, n), x11(Dim+1, n); for(int i=0; i x_tmp(Dim), x1_tmp(Dim+1); x_tmp = x.get_column(i)-c; for(int j=0; j A11(Dim, Dim+1); vnl_matrix x11t = x11.transpose(); //vnl_matrix_inverse tmp(x11 * x11t); // BA -- removed this -- not used? vnl_svd qr( x11t ); // can use vnl_qr A11 = qr.inverse() * (y1.transpose()); A11 = A11.transpose(); vnl_matrix A(Dim,Dim); A = A11.extract(Dim, Dim, 0, 0); std::cout << "y=" << y << std::endl; std::cout << "x=" << x << std::endl; std::cout << "y1=" << y1 << std::endl; std::cout << "x11=" << x11 << std::endl; std::cout << "A11=" << A11 << std::endl; vnl_vector t = A11.get_column(Dim); typedef typename TransformPointerType::ObjectType TransformType; typedef typename TransformType::InputPointType PointType; typedef typename TransformType::OutputVectorType VectorType; typedef typename TransformType::MatrixType MatrixType; PointType center; for(int i=0;iSetCenter(center); transform->SetTranslation(translation); transform->SetMatrix(matrix); return; } //////////////////////////////////////////////////////////////////////// //Stripped from ANTS_affine_registration2.h template void WriteAffineTransformFile(TransformPointerType &transform, StringType filename){ itk::TransformFileWriter::Pointer transform_writer; transform_writer = itk::TransformFileWriter::New(); transform_writer->SetFileName(filename); transform_writer->SetInput(transform); try{ transform_writer->Update(); } catch( itk::ExceptionObject &err){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl <<"Exception in writing tranform file: " << std::endl << filename << std::endl; return; } return; } //////////////////////////////////////////////////////////////////////// //Stripped from ANTS_affine_registration2.h template inline void PostConversionInAffine(RunningAffineTransformPointerType& transform_running, AffineTransformPointerType &transform){ typedef typename RunningAffineTransformPointerType::ObjectType RunningAffineTransformType; typedef typename AffineTransformPointerType::ObjectType AffineTransformType; transform->SetCenter(*(reinterpret_cast (const_cast (&(transform_running->GetCenter()))))); transform->SetTranslation(*(reinterpret_cast (const_cast (&(transform_running->GetTranslation()))))); transform->SetMatrix(*(reinterpret_cast (const_cast (&(transform_running->GetMatrix()))))); // std::cout << "transform_running" << transform_running << std::endl; // std::cout << "transform" << transform << std::endl; } template void DumpTransformForANTS3D(const TransformAPointer &transform, StringType &ANTS_prefix){ const int ImageDimension = 3; // ANTS transform file type typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; AffineTransformType::Pointer transform_ANTS = AffineTransformType::New(); // typedef TransformAPointer::ObjectType TransformA; // std::cout << " writing " << ANTS_prefix << " affine " << std::endl; // std::string ANTS_affine_filename = ANTS_prefix + std::string( "Affine.txt" ); std::string ANTS_affine_filename = ANTS_prefix; std::cout << " writing ANTS affine file:" << ANTS_affine_filename << std::endl; PostConversionInAffine(transform, transform_ANTS); WriteAffineTransformFile(transform_ANTS, ANTS_affine_filename); } int LandmarkBasedTransformInitializer2D(int, char * []) { std::cout << " not implemented " << std::endl; return 1; /* typedef float PixelType; const unsigned int Dimension = 2; typedef itk::Image< PixelType, Dimension > FixedImageType; typedef itk::Image< PixelType, Dimension > MovingImageType; typedef itk::Image< PixelType, Dimension > ImageType; typename FixedImageType::Pointer fixedimage; typename MovingImageType::Pointer movingimage; ReadImage(fixedimage,argv[1]); ReadImage(movingimage,argv[2]); // Set the transform type.. typedef itk::Rigid2DTransform< double > TransformType; */ return EXIT_SUCCESS; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " FixedImageWithLabeledLandmarks.nii.gz MovingImageWithLabeledLandmarks.nii.gz [rigid | affine] OutAffine.txt " << std::endl; std::cout << " we expect the input images to be (1) N-ary (2) in the same physical space as the images you want to " << std::endl; std::cout << " register and (3 ) to have the same landmark points defined within them ... " << std::endl; std::cout << " landmarks will be defined from the center of mass of the labels in the input images . " << std::endl; std::cout << " You can use ITK-snap to generate the label images. " << std::endl; return 1; } // Get the image dimension std::string fn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); switch ( imageIO->GetNumberOfDimensions() ) { case 2: LandmarkBasedTransformInitializer2D(argc,argv); break; case 3: LandmarkBasedTransformInitializer3D(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/Atropos.cxx000066400000000000000000001374411147325206600204230ustar00rootroot00000000000000#include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkMaskImageFilter.h" #include "itkNumericSeriesFileNames.h" #include "itkVectorImage.h" #include "itkVectorIndexSelectionCastImageFilter.h" #include "antsAtroposSegmentationImageFilter.h" #include "antsBoxPlotQuantileListSampleFilter.h" #include "antsCommandLineOption.h" #include "antsCommandLineParser.h" #include "antsGaussianListSampleFunction.h" #include "antsLogEuclideanGaussianListSampleFunction.h" #include "antsGrubbsRosnerListSampleFilter.h" #include "antsHistogramParzenWindowsListSampleFunction.h" #include "antsListSampleToListSampleFilter.h" #include "antsManifoldParzenWindowsListSampleFunction.h" #include "antsPassThroughListSampleFilter.h" #include #include #include template class CommandIterationUpdate : public itk::Command { public: typedef CommandIterationUpdate Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; itkNewMacro( Self ); protected: CommandIterationUpdate() {}; public: void Execute(itk::Object *caller, const itk::EventObject & event) { Execute( (const itk::Object *) caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { const TFilter * filter = dynamic_cast< const TFilter * >( object ); if( typeid( event ) != typeid( itk::IterationEvent ) ) { return; } std::cout << " Iteration " << filter->GetElapsedIterations() << " (of " << filter->GetMaximumNumberOfIterations() << "): "; std::cout << filter->GetCurrentConvergenceMeasurement() << " (threshold = " << filter->GetConvergenceThreshold() << ")" << std::endl; } }; void ConvertToLowerCase( std::string& str ) { std::transform( str.begin(), str.end(), str.begin(), tolower ); // You may need to cast the above line to (int(*)(int)) // tolower - this works as is on VC 7.1 but may not work on // other compilers } template int AtroposSegmentation( itk::ants::CommandLineParser *parser ) { typedef float PixelType; typedef float RealType; typedef itk::Image InputImageType; typedef unsigned char LabelType; typedef itk::Image LabelImageType; typedef itk::ants::AtroposSegmentationImageFilter SegmentationFilterType; typename SegmentationFilterType::Pointer segmenter = SegmentationFilterType::New(); typedef CommandIterationUpdate CommandType; typename CommandType::Pointer observer = CommandType::New(); segmenter->AddObserver( itk::IterationEvent(), observer ); //segmenter->DebugOn(); /** * memory-usage -- need to set before setting the prior probability images. */ typename itk::ants::CommandLineParser::OptionType::Pointer memoryOption = parser->GetOption( "minimize-memory-usage" ); if( memoryOption && memoryOption->GetNumberOfValues() > 0 ) { segmenter->SetMinimizeMemoryUsage( parser->Convert( memoryOption->GetValue() ) ); } /** * Initialization */ typename itk::ants::CommandLineParser::OptionType::Pointer initializationOption = parser->GetOption( "initialization" ); if( initializationOption && initializationOption->GetNumberOfParameters() < 1 ) { std::cerr << "Incorrect initialization option specification." << std::endl; std::cerr << " " << initializationOption->GetDescription() << std::endl; return EXIT_FAILURE; } else { segmenter->SetNumberOfClasses( parser->Convert( initializationOption->GetParameter( 0 ) ) ); std::string initializationStrategy = initializationOption->GetValue(); ConvertToLowerCase( initializationStrategy ); if( !initializationStrategy.compare( std::string( "random" ) ) ) { segmenter->SetInitializationStrategy( SegmentationFilterType::Random ); } else if( !initializationStrategy.compare( std::string( "otsu" ) ) ) { segmenter->SetInitializationStrategy( SegmentationFilterType::Otsu ); } else if( !initializationStrategy.compare( std::string( "kmeans" ) ) ) { segmenter->SetInitializationStrategy( SegmentationFilterType::KMeans ); if( initializationOption->GetNumberOfParameters() > 1 ) { std::vector clusterCenters = parser->ConvertVector( initializationOption->GetParameter( 1 ) ); if( clusterCenters.size() != segmenter->GetNumberOfClasses() ) { std::cerr << "The cluster center vector size does not equal the " << "specified number of classes." << std::endl; return EXIT_FAILURE; } else { typename SegmentationFilterType::ParametersType parameters; parameters.SetSize( segmenter->GetNumberOfClasses() ); for( unsigned int n = 0; n < parameters.GetSize(); n++ ) { parameters[n] = clusterCenters[n]; } segmenter->SetInitialKMeansParameters( parameters ); } } } else if( !initializationStrategy.compare( std::string( "priorprobabilityimages" ) ) ) { segmenter->SetInitializationStrategy( SegmentationFilterType::PriorProbabilityImages ); if( initializationOption->GetNumberOfParameters() < 3 ) { std::cerr << "Incorrect initialization option specification." << std::endl; std::cerr << " " << initializationOption->GetDescription() << std::endl; return EXIT_FAILURE; } segmenter->SetPriorProbabilityWeight( parser->Convert( initializationOption->GetParameter( 2 ) ) ); if( initializationOption->GetNumberOfParameters() > 3 ) { segmenter->SetProbabilityThreshold( parser->Convert( initializationOption->GetParameter( 3 ) ) ); } std::string filename = initializationOption->GetParameter( 1 ); if( filename.find( std::string( "%" ) ) != std::string::npos ) { itk::NumericSeriesFileNames::Pointer fileNamesCreator = itk::NumericSeriesFileNames::New(); fileNamesCreator->SetStartIndex( 1 ); fileNamesCreator->SetEndIndex( segmenter->GetNumberOfClasses() ); fileNamesCreator->SetSeriesFormat( filename.c_str() ); const std::vector & imageNames = fileNamesCreator->GetFileNames(); for ( unsigned int k = 0; k < imageNames.size(); k++ ) { typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( imageNames[k].c_str() ); reader->Update(); segmenter->SetPriorProbabilityImage( k + 1, reader->GetOutput() ); } } else { typedef itk::VectorImage VectorImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( filename.c_str() ); reader->Update(); if( reader->GetOutput()->GetNumberOfComponentsPerPixel() != segmenter->GetNumberOfClasses() ) { std::cerr << "The number of components does not match the number of " << "classes." << std::endl; return EXIT_FAILURE; } typedef itk::VectorIndexSelectionCastImageFilter CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput( reader->GetOutput() ); for( unsigned int k = 0; k < segmenter->GetNumberOfClasses(); k++ ) { caster->SetIndex( k ); caster->Update(); segmenter->SetPriorProbabilityImage( k + 1, caster->GetOutput() ); } } if( initializationOption->GetNumberOfParameters() > 3 ) { segmenter->SetProbabilityThreshold( parser->Convert( initializationOption->GetParameter( 3 ) ) ); } } else if( !initializationStrategy.compare( std::string( "priorlabelimage" ) ) ) { segmenter->SetInitializationStrategy( SegmentationFilterType::PriorLabelImage ); if( initializationOption->GetNumberOfParameters() < 3 ) { std::cerr << "Incorrect initialization option specification." << std::endl; std::cerr << " " << initializationOption->GetDescription() << std::endl; return EXIT_FAILURE; } segmenter->SetPriorProbabilityWeight( parser->Convert( initializationOption->GetParameter( 2 ) ) ); std::string filename = initializationOption->GetParameter( 1 ); typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( filename.c_str() ); reader->Update(); segmenter->SetPriorLabelImage( reader->GetOutput() ); } else { std::cerr << "Unrecognized initialization strategy request." << std::endl; return EXIT_FAILURE; } } /** * Posterior probability formulation */ typename itk::ants::CommandLineParser::OptionType::Pointer posteriorOption = parser->GetOption( "posterior-formulation" ); if( posteriorOption ) { if( posteriorOption->GetNumberOfParameters() > 0 ) { segmenter->SetUseMixtureModelProportions( parser->Convert( posteriorOption->GetParameter( 0 ) ) ); } std::string posteriorStrategy = posteriorOption->GetValue(); ConvertToLowerCase( posteriorStrategy ); if( !posteriorStrategy.compare( std::string( "socrates" ) ) ) { segmenter->SetPosteriorProbabilityFormulation( SegmentationFilterType::Socrates ); } else if( !posteriorStrategy.compare( std::string( "plato" ) ) ) { segmenter->SetPosteriorProbabilityFormulation( SegmentationFilterType::Plato ); } else if( !posteriorStrategy.compare( std::string( "aristotle" ) ) ) { segmenter->SetPosteriorProbabilityFormulation( SegmentationFilterType::Aristotle ); } } /** * convergence options */ typename itk::ants::CommandLineParser::OptionType::Pointer convergenceOption = parser->GetOption( "convergence" ); if( convergenceOption ) { if( convergenceOption->GetNumberOfParameters() > 0 ) { segmenter->SetMaximumNumberOfIterations( parser->Convert( convergenceOption->GetParameter( 0 ) ) ); } if( convergenceOption->GetNumberOfParameters() > 1 ) { segmenter->SetConvergenceThreshold( parser->Convert( convergenceOption->GetParameter( 1 ) ) ); } } /** * mask image */ typename itk::ants::CommandLineParser::OptionType::Pointer maskOption = parser->GetOption( "mask-image" ); if( maskOption && maskOption->GetNumberOfValues() > 0 ) { try { typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( ( maskOption->GetValue() ).c_str() ); reader->Update(); segmenter->SetMaskImage( reader->GetOutput() ); } catch(...) {} } else { std::cerr << "An image mask is required. Specify a mask image" << " with the -x option." << std::endl; return EXIT_FAILURE; } /** * BSpline options */ typename itk::ants::CommandLineParser::OptionType::Pointer bsplineOption = parser->GetOption( "bspline" ); if( bsplineOption && bsplineOption->GetNumberOfValues() ) { if( bsplineOption->GetNumberOfParameters() > 0 ) { std::vector numLevels = parser->ConvertVector( bsplineOption->GetParameter( 0 ) ); typename SegmentationFilterType::ArrayType numberOfFittingLevels; if( numLevels.size() == 1 ) { numberOfFittingLevels.Fill( numLevels[0] ); } else if( numLevels.size() == ImageDimension ) { for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfFittingLevels[d] = numLevels[d]; } } else { std::cerr << "Incorrect number of levels" << std::endl; return EXIT_FAILURE; } segmenter->SetNumberOfLevels( numberOfFittingLevels ); } if( bsplineOption->GetNumberOfParameters() > 2 ) { segmenter->SetSplineOrder( parser->Convert( bsplineOption->GetParameter( 2 ) ) ); } if( bsplineOption->GetNumberOfParameters() > 1 ) { std::vector array = parser->ConvertVector( bsplineOption->GetParameter( 1 ) ); typename SegmentationFilterType::ArrayType numberOfControlPoints; if( array.size() == 1 ) { numberOfControlPoints.Fill( array[0] + segmenter->GetSplineOrder() ); } else if( array.size() == ImageDimension ) { for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfControlPoints[d] = array[d] + segmenter->GetSplineOrder(); } } else { std::cerr << "Incorrect mesh resolution" << std::endl; return EXIT_FAILURE; } segmenter->SetNumberOfControlPoints( numberOfControlPoints ); } } /** * labels */ typename itk::ants::CommandLineParser::OptionType::Pointer labelOption = parser->GetOption( "label-propagation" ); if( labelOption && labelOption->GetNumberOfValues() > 0 ) { if( labelOption->GetNumberOfValues() == 1 && ( labelOption->GetValue( 0 ) ).empty() ) { typename SegmentationFilterType::LabelParameterMapType labelMap; float labelLambda = parser->Convert( labelOption->GetParameter( 0, 0 ) ); float labelBoundaryProbability = 1.0; if( labelOption->GetNumberOfParameters( 0 ) > 1 ) { labelBoundaryProbability = parser->Convert( labelOption->GetParameter( 0, 1 ) ); if( labelBoundaryProbability < 0.0 ) { labelBoundaryProbability = 0.0; } if( labelBoundaryProbability > 1.0 ) { labelBoundaryProbability = 1.0; } } for( unsigned int n = 1; n <= segmenter->GetNumberOfClasses(); n++ ) { typename SegmentationFilterType::LabelParametersType labelPair; labelPair.first = labelLambda; labelPair.second = labelBoundaryProbability; labelMap[n] = labelPair; } segmenter->SetPriorLabelParameterMap( labelMap ); } else { typename SegmentationFilterType::LabelParameterMapType labelMap; for( unsigned int n = 0; n < labelOption->GetNumberOfValues(); n++ ) { typename SegmentationFilterType::LabelParametersType labelPair; float labelLambda = parser->Convert( labelOption->GetParameter( n, 0 ) ); float labelBoundaryProbability = 1.0; if( labelOption->GetNumberOfParameters( n ) > 1 ) { labelBoundaryProbability = parser->Convert( labelOption->GetParameter( n, 1 ) ); if( labelBoundaryProbability < 0.0 ) { labelBoundaryProbability = 0.0; } if( labelBoundaryProbability > 1.0 ) { labelBoundaryProbability = 1.0; } } labelPair.first = labelLambda; labelPair.second = labelBoundaryProbability; unsigned int whichClass = parser->Convert( labelOption->GetValue( n ) ); labelMap[whichClass] = labelPair; } segmenter->SetPriorLabelParameterMap( labelMap ); } } /** * intensity images */ typename itk::ants::CommandLineParser::OptionType::Pointer imageOption = parser->GetOption( "intensity-image" ); if( imageOption && imageOption->GetNumberOfValues() > 0 ) { unsigned int count = 0; for( int n = imageOption->GetNumberOfValues() - 1; n >= 0; n-- ) { typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); if( imageOption->GetNumberOfParameters( n ) > 0 ) { reader->SetFileName( imageOption->GetParameter( n, 0 ) ); } else { reader->SetFileName( imageOption->GetValue( n ) ); } reader->Update(); segmenter->SetIntensityImage( count, reader->GetOutput() ); if( imageOption->GetNumberOfParameters( count ) > 1 ) { segmenter->SetAdaptiveSmoothingWeight( count, parser->Convert( imageOption->GetParameter( count, 1 ) ) ); } else { segmenter->SetAdaptiveSmoothingWeight( count, 0.0 ); } count++; } } else { std::cerr << "No input images were specified. Specify an input image" << " with the -a option." << std::endl; return EXIT_FAILURE; } /** * MRF options */ typename itk::ants::CommandLineParser::OptionType::Pointer mrfOption = parser->GetOption( "mrf" ); if( mrfOption && mrfOption->GetNumberOfValues() > 0 ) { if( mrfOption->GetNumberOfParameters() > 0 ) { segmenter->SetMRFSmoothingFactor( parser->Convert( mrfOption->GetParameter( 0 ) ) ); } if( mrfOption->GetNumberOfParameters() > 1 ) { std::vector array = parser->ConvertVector( mrfOption->GetParameter( 1 ) ); typename SegmentationFilterType::ArrayType radius; if( array.size() == 1 ) { radius.Fill( array[0] ); } else if( array.size() == ImageDimension ) { for( unsigned int d = 0; d < ImageDimension; d++ ) { radius[d] = array[d]; } } else { std::cerr << "MRF radius size needs to be equal to the image dimension." << std::endl; return EXIT_FAILURE; } segmenter->SetMRFRadius( radius ); } } /** * euclidean distance */ typename itk::ants::CommandLineParser::OptionType::Pointer distanceOption = parser->GetOption( "use-euclidean-distance" ); if( distanceOption && distanceOption->GetNumberOfValues() > 0 ) { segmenter->SetUseEuclideanDistanceForPriorLabels( parser->Convert( distanceOption->GetValue() ) ); } /** * likelihood */ typename itk::ants::CommandLineParser::OptionType::Pointer likelihoodOption = parser->GetOption( "likelihood-model" ); if( likelihoodOption && likelihoodOption->GetNumberOfValues() > 0 ) { std::string likelihoodModel = likelihoodOption->GetValue(); ConvertToLowerCase( likelihoodModel ); if( !likelihoodModel.compare( std::string( "gaussian" ) ) ) { typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::GaussianListSampleFunction LikelihoodType; for( unsigned int n = 0; n < segmenter->GetNumberOfClasses(); n++ ) { typename LikelihoodType::Pointer gaussianLikelihood = LikelihoodType::New(); segmenter->SetLikelihoodFunction( n, gaussianLikelihood ); } } else if( !likelihoodModel.compare( std::string( "manifoldparzenwindows" ) ) ) { typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::ManifoldParzenWindowsListSampleFunction LikelihoodType; float regularizationSigma = 1.0; if( likelihoodOption->GetNumberOfParameters() > 0 ) { regularizationSigma = parser->Convert( likelihoodOption->GetParameter( 0 ) ); } unsigned int evalNeighborhood = 50; if( likelihoodOption->GetNumberOfParameters() > 1 ) { evalNeighborhood = parser->Convert( likelihoodOption->GetParameter( 1 ) ); } unsigned int covNeighborhood = 0; if( likelihoodOption->GetNumberOfParameters() > 2 ) { covNeighborhood = parser->Convert( likelihoodOption->GetParameter( 2 ) ); } float covSigma = 1.0; if( likelihoodOption->GetNumberOfParameters() > 3 ) { covSigma = parser->Convert( likelihoodOption->GetParameter( 3 ) ); } for( unsigned int n = 0; n < segmenter->GetNumberOfClasses(); n++ ) { typename LikelihoodType::Pointer mpwLikelihood = LikelihoodType::New(); mpwLikelihood->SetRegularizationSigma( regularizationSigma ); mpwLikelihood->SetEvaluationKNeighborhood( evalNeighborhood ); mpwLikelihood->SetCovarianceKNeighborhood( covNeighborhood ); mpwLikelihood->SetKernelSigma( covSigma ); segmenter->SetLikelihoodFunction( n, mpwLikelihood ); } } else if( !likelihoodModel.compare( std::string( "histogramparzenwindows" ) ) ) { typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::HistogramParzenWindowsListSampleFunction LikelihoodType; float sigma = 1.0; if( likelihoodOption->GetNumberOfParameters() > 0 ) { sigma = parser->Convert( likelihoodOption->GetParameter( 0 ) ); } unsigned int numberOfBins = 32; if( likelihoodOption->GetNumberOfParameters() > 1 ) { numberOfBins = parser->Convert( likelihoodOption->GetParameter( 1 ) ); } for( unsigned int n = 0; n < segmenter->GetNumberOfClasses(); n++ ) { typename LikelihoodType::Pointer hpwLikelihood = LikelihoodType::New(); hpwLikelihood->SetSigma( sigma ); hpwLikelihood->SetNumberOfHistogramBins( numberOfBins ); segmenter->SetLikelihoodFunction( n, hpwLikelihood ); } } else if( !likelihoodModel.compare( std::string( "logeuclideangaussian" ) ) ) { if( segmenter->GetNumberOfIntensityImages() != static_cast( ImageDimension * ( ImageDimension + 1 ) / 2 ) ) { std::cerr << "Incorrect number of intensity images specified." << std::endl; return EXIT_FAILURE; } typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::LogEuclideanGaussianListSampleFunction LikelihoodType; for( unsigned int n = 0; n < segmenter->GetNumberOfClasses(); n++ ) { typename LikelihoodType::Pointer gaussianLikelihood = LikelihoodType::New(); segmenter->SetLikelihoodFunction( n, gaussianLikelihood ); } } else { std::cerr << "Unrecognized likelihood model request." << std::endl; return EXIT_FAILURE; } } /** * outliers? */ typename itk::ants::CommandLineParser::OptionType::Pointer outlierOption = parser->GetOption( "winsorize-outliers" ); if( outlierOption && outlierOption->GetNumberOfValues() > 0 ) { std::string outlierStrategy = outlierOption->GetValue(); ConvertToLowerCase( outlierStrategy ); if( !outlierStrategy.compare( std::string( "boxplot" ) ) ) { typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::BoxPlotQuantileListSampleFilter SampleFilterType; typename SampleFilterType::Pointer boxplotFilter = SampleFilterType::New(); if( outlierOption->GetNumberOfParameters( 0 ) > 0 ) { boxplotFilter->SetLowerPercentile( parser->Convert( outlierOption->GetParameter( 0 ) ) ); } if( outlierOption->GetNumberOfParameters( 0 ) > 1 ) { boxplotFilter->SetUpperPercentile( parser->Convert( outlierOption->GetParameter( 1 ) ) ); } if( outlierOption->GetNumberOfParameters( 0 ) > 2 ) { boxplotFilter->SetWhiskerScalingFactor( parser->Convert( outlierOption->GetParameter( 2 ) ) ); } segmenter->SetOutlierHandlingFilter( boxplotFilter ); } else if( !outlierStrategy.compare( std::string( "grubbsrosner" ) ) ) { typedef typename SegmentationFilterType::SampleType SampleType; typedef itk::ants::Statistics::GrubbsRosnerListSampleFilter SampleFilterType; typename SampleFilterType::Pointer grubbsFilter = SampleFilterType::New(); if( outlierOption->GetNumberOfParameters( 0 ) > 0 ) { grubbsFilter->SetSignificanceLevel( parser->Convert( outlierOption->GetParameter( 0 ) ) ); } if( outlierOption->GetNumberOfParameters( 0 ) > 1 ) { grubbsFilter->SetWinsorizingLevel( parser->Convert( outlierOption->GetParameter( 1 ) ) ); } segmenter->SetOutlierHandlingFilter( grubbsFilter ); } else { std::cerr << "Unrecognized outlier handling strategy request." << std::endl; return EXIT_FAILURE; } } try { std::cout << std::endl << "Progress: " << std::endl; segmenter->Update(); } catch( itk::ExceptionObject exp ) { std::cerr << exp << std::endl; return EXIT_FAILURE; } /** * output */ std::cout << std::endl << "Writing output:" << std::endl; typename itk::ants::CommandLineParser::OptionType::Pointer outputOption = parser->GetOption( "output" ); if( outputOption && outputOption->GetNumberOfValues() > 0 ) { if( outputOption->GetNumberOfParameters() == 0 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( segmenter->GetOutput() ); writer->SetFileName( ( outputOption->GetValue() ).c_str() ); writer->Update(); } if( outputOption->GetNumberOfParameters() > 0 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( segmenter->GetOutput() ); writer->SetFileName( ( outputOption->GetParameter( 0 ) ).c_str() ); writer->Update(); } if( outputOption->GetNumberOfParameters() > 1 ) { std::string filename = outputOption->GetParameter( 1 ); itk::NumericSeriesFileNames::Pointer fileNamesCreator = itk::NumericSeriesFileNames::New(); fileNamesCreator->SetStartIndex( 1 ); fileNamesCreator->SetEndIndex( segmenter->GetNumberOfClasses() ); fileNamesCreator->SetSeriesFormat( filename.c_str() ); const std::vector & imageNames = fileNamesCreator->GetFileNames(); for( unsigned int i = 0; i < imageNames.size(); i++ ) { std::cout << " Writing posterior image (class " << i + 1 << ")" << std::endl; typename InputImageType::Pointer probabilityImage = segmenter->GetPosteriorProbabilityImage( i + 1 ); if( segmenter->GetMaskImage() ) { typedef itk::MaskImageFilter MaskerType; typename MaskerType::Pointer masker = MaskerType::New(); masker->SetInput1( probabilityImage ); masker->SetInput2( segmenter->GetMaskImage() ); masker->SetOutsideValue( 0 ); masker->Update(); probabilityImage = masker->GetOutput(); } typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( probabilityImage ); writer->SetFileName( imageNames[i].c_str() ); writer->Update(); } } if( outputOption->GetNumberOfParameters() > 2 ) { std::string filename = outputOption->GetParameter( 2 ); itk::NumericSeriesFileNames::Pointer fileNamesCreator = itk::NumericSeriesFileNames::New(); fileNamesCreator->SetStartIndex( 1 ); fileNamesCreator->SetEndIndex( segmenter->GetNumberOfClasses() ); fileNamesCreator->SetSeriesFormat( filename.c_str() ); const std::vector & imageNames = fileNamesCreator->GetFileNames(); for( unsigned int i = 0; i < segmenter->GetNumberOfClasses(); i++ ) { std::cout << " Writing likelihood image (class " << i + 1 << ")" << std::endl; typename InputImageType::Pointer likelihoodImage = segmenter-> GetLikelihoodImage( i + 1 ); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( likelihoodImage ); writer->SetFileName( imageNames[i].c_str() ); writer->Update(); } } if( outputOption->GetNumberOfParameters() > 3 ) { std::string filename = outputOption->GetParameter( 3 ); itk::NumericSeriesFileNames::Pointer fileNamesCreator = itk::NumericSeriesFileNames::New(); fileNamesCreator->SetStartIndex( 1 ); fileNamesCreator->SetEndIndex( segmenter->GetNumberOfClasses() ); fileNamesCreator->SetSeriesFormat( filename.c_str() ); const std::vector & imageNames = fileNamesCreator->GetFileNames(); for( unsigned int i = 0; i < segmenter->GetNumberOfClasses(); i++ ) { if( segmenter->GetPriorProbabilityImage( i + 1 ) || segmenter->GetPriorLabelImage() ) { std::cout << " Writing distance image (class " << i + 1 << ")" << std::endl; typename InputImageType::Pointer distanceImage = segmenter-> GetDistancePriorProbabilityImage( i + 1 ); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( distanceImage ); writer->SetFileName( imageNames[i].c_str() ); writer->Update(); } } } if( outputOption->GetNumberOfParameters() > 4 ) { std::string filename = outputOption->GetParameter( 4 ); itk::NumericSeriesFileNames::Pointer fileNamesCreator = itk::NumericSeriesFileNames::New(); fileNamesCreator->SetStartIndex( 1 ); fileNamesCreator->SetEndIndex( segmenter->GetNumberOfClasses() ); fileNamesCreator->SetSeriesFormat( filename.c_str() ); const std::vector & imageNames = fileNamesCreator->GetFileNames(); if( segmenter->GetAdaptiveSmoothingWeight( 0 ) > 0.0 ) { for( unsigned int i = 0; i < segmenter->GetNumberOfClasses(); i++ ) { if( segmenter->GetPriorProbabilityImage( i + 1 ) || segmenter->GetPriorLabelImage() ) { std::cout << " Writing B-spline image (class " << i + 1 << ")" << std::endl; typename InputImageType::Pointer bsplineImage = segmenter-> GetSmoothIntensityImageFromPriorImage( 0, i + 1 ); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( bsplineImage ); writer->SetFileName( imageNames[i].c_str() ); writer->Update(); } } } } } std::cout << std::endl; segmenter->Print( std::cout, 2 ); return EXIT_SUCCESS; } void InitializeCommandLineOptions( itk::ants::CommandLineParser *parser ) { typedef itk::ants::CommandLineParser::OptionType OptionType; { std::string description = std::string( "This option forces the image to be treated as a specified-" ) + std::string( "dimensional image. If not specified, Atropos tries to " ) + std::string( "infer the dimensionality from the first input image." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "image-dimensionality" ); option->SetShortName( 'd' ); option->SetUsageOption( 0, "2/3/4" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "One or more scalar images is specified for segmentation " ) + std::string( "using the -a/--intensity-image option. For segmentation " ) + std::string( "scenarios with no prior information, the first scalar " ) + std::string( "image encountered on the command line is used to order " ) + std::string( "labelings such that the class with the smallest intensity " ) + std::string( "signature is class \'1\' through class \'N\' which represents " ) + std::string( "the voxels with the largest intensity values. The " ) + std::string( "optional adaptive smoothing weight parameter is applicable " ) + std::string( "only when using prior label or probability images. This " ) + std::string( "scalar parameter is to be specified between [0,1] which " ) + std::string( "smooths each labeled region separately and modulates the " ) + std::string( "intensity measurement at each voxel in each intensity image " ) + std::string( "between the original intensity and its smoothed " ) + std::string( "counterpart. The smoothness parameters are governed by the " ) + std::string( "-b/--bspline option." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "intensity-image" ); option->SetShortName( 'a' ); option->SetUsageOption( 0, "[intensityImage,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "If the adaptive smoothing weights are > 0, the intensity " ) + std::string( "images are smoothed in calculating the likelihood values. " ) + std::string( "This is to account for subtle intensity differences " ) + std::string( "across the same tissue regions." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "bspline" ); option->SetShortName( 'b' ); option->SetUsageOption( 0, "[,,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "To initialize the FMM parameters, one of the following " ) + std::string( "options must be specified. If one does not have " ) + std::string( "prior label or probability images we recommend " ) + std::string( "using kmeans as it is typically faster than otsu and can " ) + std::string( "be used with multivariate initialization. However, since a " ) + std::string( "Euclidean distance on the inter cluster distances is used, one " ) + std::string( "might have to appropriately scale the additional input images. " ) + std::string( "Random initialization is meant purely for intellectual " ) + std::string( "curiosity. The prior weighting (specified in the range " ) + std::string( "[0,1]) is used to modulate the calculation of the " ) + std::string( "posterior probabilities between the likelihood*mrfprior " ) + std::string( "and the likelihood*mrfprior*prior. For specifying many " ) + std::string( "prior probability images for a multi-label segmentation, " ) + std::string( "we offer a minimize usage option (see -m). With that option " ) + std::string( "one can specify a prior probability threshold in which only " ) + std::string( "those pixels exceeding that threshold are stored in memory. "); OptionType::Pointer option = OptionType::New(); option->SetLongName( "initialization" ); option->SetShortName( 'i' ); option->SetUsageOption( 0, "Random[numberOfClasses]" ); option->SetUsageOption( 1, "Otsu[numberOfClasses]" ); option->SetUsageOption( 2, "KMeans[numberOfClasses,]" ); option->SetUsageOption( 3, "PriorProbabilityImages[numberOfClasses,fileSeriesFormat(index=1 to numberOfClasses) or vectorImage,priorWeighting,]" ); option->SetUsageOption( 4, "PriorLabelImage[numberOfClasses,labelImage,priorWeighting]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Different posterior probability formulations are possible ") + std::string( "which include the following: " ) + std::string( " Socrates: posteriorProbability = (spatialPrior)^priorWeight" ) + std::string( "*(likelihood*mrfPrior)^(1-priorWeight), " ) + std::string( " Plato: posteriorProbability = 1.0, " ) + std::string( " Aristotle: posteriorProbability = 1.0, " )/* + std::string( " Zeno: posteriorProbability = 1.0\n" ) + std::string( " Diogenes: posteriorProbability = 1.0\n" ) + std::string( " Thales: posteriorProbability = 1.0\n" ) + std::string( " Democritus: posteriorProbability = 1.0.\n" ) */; OptionType::Pointer option = OptionType::New(); option->SetLongName( "posterior-formulation" ); option->SetShortName( 'p' ); option->SetUsageOption( 0, "Socrates[]" ); option->SetUsageOption( 1, "Plato[]" ); option->SetUsageOption( 2, "Aristotle[]" ); // option->SetUsageOption( 3, "Zeno[]" ); // option->SetUsageOption( 4, "Diogenes[]" ); // option->SetUsageOption( 5, "Thales[]" ); // option->SetUsageOption( 6, "Democritus" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The image mask (which is required) defines the region which " ) + std::string( "is to be labeled by the Atropos algorithm." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "mask-image" ); option->SetShortName( 'x' ); option->SetUsageOption( 0, "maskImageFilename" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Convergence is determined by calculating the mean maximum " ) + std::string( "posterior probability over the region of interest at " ) + std::string( "each iteration. When this value decreases or increases " ) + std::string( "less than the specified threshold from the previous " ) + std::string( "iteration or the maximum number of iterations is exceeded " ) + std::string( "the program terminates."); OptionType::Pointer option = OptionType::New(); option->SetLongName( "convergence" ); option->SetShortName( 'c' ); option->SetUsageOption( 0, "[,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Both parametric and non-parametric options exist in Atropos. " ) + std::string( "The Gaussian parametric option is commonly used " ) + std::string( "(e.g. SPM & FAST) where the mean and standard deviation " ) + std::string( "for the Gaussian of each class is calculated at each " ) + std::string( "iteration. Other groups use non-parametric approaches " ) + std::string( "exemplified by option 2. We recommend using options 1 " ) + std::string( "or 2 as they are fairly standard and the " ) + std::string( "default parameters work adequately." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "likelihood-model" ); option->SetShortName( 'k' ); option->SetUsageOption( 0, "Gaussian" ); option->SetUsageOption( 1, "HistogramParzenWindows[,]" ); option->SetUsageOption( 2, "ManifoldParzenWindows[,,,]" ); option->SetUsageOption( 3, "LogEuclideanGaussian" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Markov random field (MRF) theory provides a general " ) + std::string( "framework for enforcing spatially contextual constraints " ) + std::string( "on the segmentation solution. The default smoothing " ) + std::string( "factor of 0.3 provides a moderate amount of smoothing. " ) + std::string( "Increasing this number causes more smoothing whereas " ) + std::string( "decreasing the number lessens the smoothing. The radius " ) + std::string( "parameter specifies the mrf neighborhood." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "mrf" ); option->SetShortName( 'm' ); option->SetUsageOption( 0, "[,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The output consists of a labeled image where each voxel " ) + std::string( "in the masked region is assigned a label from 1, 2, " ) + std::string( "..., N. Optionally, one can also output the posterior " ) + std::string( "probability images specified in the same format as the " ) + std::string( "prior probability images, e.g. posterior%02d.nii.gz " ) + std::string( "(C-style file name formatting)." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "output" ); option->SetShortName( 'o' ); option->SetUsageOption( 0, "[classifiedImage,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "By default, memory usage is not minimized, however, if " ) + std::string( "this is needed, the various probability and distance " ) + std::string( "images are calculated on the fly instead of being " ) + std::string( "stored in memory at each iteration. Also, if prior " ) + std::string( "probability images are used, only the non-negligible " ) + std::string( "pixel values are stored in memory. " ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "minimize-memory-usage" ); option->SetShortName( 'u' ); option->SetUsageOption( 0, "(0)/1" ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "To remove the effects of outliers in calculating the " ) + std::string( "weighted mean and weighted covariance, the user can " ) + std::string( "opt to remove the outliers through the options " ) + std::string( "specified below." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "winsorize-outliers" ); option->SetShortName( 'w' ); option->SetUsageOption( 0, "BoxPlot[,,]" ); option->SetUsageOption( 1, "GrubbsRosner[,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Given prior label or probability images, the labels are " ) + std::string( "propagated throughout the masked region so that every " ) + std::string( "voxel in the mask is labeled. Propagation is done " ) + std::string( "by using a signed distance transform of the label. " ) + std::string( "Alternatively, propagation of the labels with the " ) + std::string( "fast marching filter respects the distance along the " ) + std::string( "shape of the mask (e.g. the sinuous sulci and gyri " ) + std::string( "of the cortex." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-euclidean-distance" ); option->SetShortName( 'e' ); option->SetUsageOption( 0, "(0)/1" ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "The propagation of each prior label can be controlled " ) + std::string( "by the lambda and boundary probability parameters. The " ) + std::string( "latter parameter is the probability (in the range " ) + std::string( "[0,1]) of the label on the boundary which increases linearly " ) + std::string( "to a maximum value of 1.0 in the interior of the labeled " ) + std::string( "region. The former parameter dictates the exponential " ) + std::string( "decay of probability propagation outside the labeled " ) + std::string( "region from the boundary probability, i.e. " ) + std::string( "boundaryProbability*exp( -lambda * distance )." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "label-propagation" ); option->SetShortName( 'l' ); option->SetUsageOption( 0, "whichLabel[lambda=0.0,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu (short version)." ); OptionType::Pointer option = OptionType::New(); option->SetShortName( 'h' ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "help" ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } } int main( int argc, char *argv[] ) { itk::ants::CommandLineParser::Pointer parser = itk::ants::CommandLineParser::New(); parser->SetCommand( argv[0] ); std::string commandDescription = std::string( "A finite mixture modeling (FMM) segmentation approach " ) + std::string( "with possibilities for specifying prior constraints. " ) + std::string( "These prior constraints include the specification " ) + std::string( "of a prior label image, prior probability images " ) + std::string( "(one for each class), and/or an MRF prior to " ) + std::string( "enforce spatial smoothing of the labels. Similar algorithms " ) + std::string( "include FAST and SPM. " ); parser->SetCommandDescription( commandDescription ); InitializeCommandLineOptions( parser ); parser->Parse( argc, argv ); if( argc < 2 || parser->Convert( parser->GetOption( "help" )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, false ); exit( EXIT_FAILURE ); } else if( parser->GetOption( 'h' ) && parser->Convert( parser->GetOption( 'h' )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, true ); exit( EXIT_FAILURE ); } // Get dimensionality unsigned int dimension = 3; itk::ants::CommandLineParser::OptionType::Pointer dimOption = parser->GetOption( "image-dimensionality" ); if( dimOption && dimOption->GetNumberOfValues() > 0 ) { dimension = parser->Convert( dimOption->GetValue() ); } else { // Read in the first intensity image to get the image dimension. std::string filename; itk::ants::CommandLineParser::OptionType::Pointer imageOption = parser->GetOption( "intensity-image" ); if( imageOption && imageOption->GetNumberOfValues() > 0 ) { if( imageOption->GetNumberOfParameters( 0 ) > 0 ) { filename = imageOption->GetParameter( 0, 0 ); } else { filename = imageOption->GetValue( 0 ); } } else { std::cerr << "No input images were specified. Specify an input image" << " with the -a option" << std::endl; return( EXIT_FAILURE ); } itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( filename.c_str(), itk::ImageIOFactory::ReadMode ); dimension = imageIO->GetNumberOfDimensions(); } std::cout << std::endl << "Running Atropos for " << dimension << "-dimensional images." << std::endl; switch( dimension ) { case 2: AtroposSegmentation<2>( parser ); break; case 3: AtroposSegmentation<3>( parser ); break; case 4: AtroposSegmentation<4>( parser ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/AverageImages.cxx000066400000000000000000000134451147325206600214710ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: AverageImages.cxx,v $ Language: C++ Date: $Date: 2009/01/27 23:25:24 $ Version: $Revision: 1.21 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. //Note: could easily add variance computation //http://people.revoledu.com/kardi/tutorial/RecursiveStatistic/Time-Variance.htm #include "ReadWriteImage.h" #include "itkOptimalSharpeningImageFilter.h" template int AverageImages(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; bool normalizei=atoi(argv[3]); float numberofimages=(float)argc - 4.; std::cout <<" Averaging " << numberofimages << " images " << std::endl; typename ImageType::Pointer averageimage = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::SizeType size; double meanval=1; size.Fill(0); unsigned int bigimage=0; for (unsigned int j=4; j< argc; j++) { // Get the image dimension std::string fn = std::string(argv[j]); std::cout <<" fn " << fn << std::endl; typename itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); for (unsigned int i=0; iGetNumberOfDimensions(); i++) { if ( imageIO->GetDimensions(i) > size[i] ) { size[i]=imageIO->GetDimensions(i); bigimage=j; std::cout << " bigimage " << j << " size " << size << std::endl; } } } std:: cout << " largest image " << size << std::endl; ReadImage(averageimage,argv[bigimage]); averageimage->FillBuffer(0); for (unsigned int j=4; j< argc; j++) { // Get the image dimension std::string fn = std::string(argv[j]); // std::cout <<" fn " << fn << std::endl; ReadImage(image2,fn.c_str()); unsigned long ct = 0; if (normalizei) { meanval = 0.0; Iterator vfIter2( image2, image2->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { meanval+=vfIter2.Get(); ct++; } if (ct > 0) meanval /= (float)ct; if (meanval <= 0) meanval=1.0; } ct = 0; Iterator vfIter( image2, image2->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { double val = vfIter.Get()/meanval *1.0/numberofimages; averageimage->SetPixel(vfIter.GetIndex() , val + averageimage->GetPixel(vfIter.GetIndex())); } } typedef itk::OptimalSharpeningImageFilter< ImageType, ImageType > sharpeningFilter; typename sharpeningFilter::Pointer shFilter = sharpeningFilter::New(); if (normalizei && argc > 3 ) { shFilter->SetInput( averageimage ); shFilter->SetSValue(0.5); averageimage = shFilter->GetOutput(); } std::cout << " writing output "; { typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput( averageimage ); writer->Update(); } return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "\n" << std::endl; std::cout << "Usage: \n" << std::endl; std::cout << argv[0] << " ImageDimension Outputfname.nii.gz Normalize \n" << std::endl; std::cout << " Compulsory arguments: \n" << std::endl; std::cout << " ImageDimension: 2 or 3 (for 2 or 3 dimensional input).\n " << std::endl; std::cout << " Outputfname.nii.gz: the name of the resulting image.\n" << std::endl; std::cout << " Normalize: 0 (false) or 1 (true); if true, the 2nd image is divided by its mean. This will select the largest image to average into.\n" << std::endl; std::cout << " Example Usage:\n" << std::endl; std::cout << argv[0] << " 3 average.nii.gz 1 *.nii.gz \n" << std::endl; std::cout << " \n" << std::endl; return 1; } int dim = atoi( argv[1] ); // Get the image dimension switch( atoi(argv[1])) { case 2: AverageImages<2>(argc,argv); break; case 3: AverageImages<3>(argc,argv); break; default: std::cerr <<" You passed ImageDimension: " << dim << " . Please use only 2 or 3 (for 2 or 3 Dimensional registration) " << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/AverageTensorImages.cxx000066400000000000000000000067141147325206600226650ustar00rootroot00000000000000#include "stdio.h" #include "itkImage.h" #include "itkImageRegionIteratorWithIndex.h" #include "ReadWriteImage.h" #include "TensorFunctions.h" template int AverageTensorImages(unsigned int argc, char *argv[]) { // typedef itk::Vector TensorType; typedef itk::SymmetricSecondRankTensor< float, 3 > TensorType; typedef itk::Image ImageType; typedef itk::ImageRegionIteratorWithIndex IteratorType; char * outputName = argv[2]; int mathtype = atoi(argv[3]); float numberofimages = (float)argc - 4.0; std::cout << "Averaging " << numberofimages << " images " << std::endl; typename ImageType::Pointer averageimage = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::SizeType size; size.Fill(0); unsigned int bigimage=0; for (unsigned int j=4; j< argc; j++) { // Get the image dimension std::string fn = std::string(argv[j]); std::cout <<" fn " << fn << std::endl; typename itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); for (unsigned int i=0; iGetNumberOfDimensions(); i++) { if ( imageIO->GetDimensions(i) > size[i] ) { size[i]=imageIO->GetDimensions(i); bigimage=j; std::cout << " bigimage " << j << " size " << size << std::endl; } } } std:: cout << " largest image " << size << std::endl; bool logeuc = true; if (mathtype == 1) logeuc = false; TensorType nullTensor; nullTensor[0] = nullTensor[1] = nullTensor[2] = nullTensor[3] = nullTensor[4] = nullTensor[5] = 0; ReadTensorImage(averageimage,argv[bigimage],logeuc); averageimage->FillBuffer(nullTensor); for (unsigned int j=4; j< argc; j++) { std::string fn = std::string(argv[j]); ReadTensorImage(image2,fn.c_str(),logeuc); IteratorType vfIter( image2, image2->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { TensorType val = vfIter.Get() / numberofimages; averageimage->SetPixel(vfIter.GetIndex(), val + averageimage->GetPixel(vfIter.GetIndex())); } } WriteTensorImage(averageimage,outputName,logeuc); return EXIT_SUCCESS; } // Main Program int main( int argc, char *argv[] ) { try { int dim = atoi(argv[1]); //char * outputName = argv[2]; //int mathtype = atoi(argv[3]); int numberofimages = argc - 4; if (numberofimages < 1) { std::cout << "Basic useage ex: " << std::endl; std::cout << argv[0] << " ImageDimension average.nii mathtype list-of-files-via-wildcard " << std::endl; std::cout << " e.g. \n AverageTensorImages 3 average.nii 1 *registered.nii " << std::endl; std::cout << " mathtype=[0=log-euclidean, 1=euclidean] " << std::endl; exit( EXIT_FAILURE ); } // Get the image dimension switch(dim) { case 2: AverageTensorImages<2>(argc,argv); break; case 3: AverageTensorImages<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0;; } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; return EXIT_FAILURE; } } ants-1.9.2+svn680.dfsg/Examples/CMakeLists.txt000066400000000000000000001077701147325206600210120ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.4) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) #Change PROJECT_NAME to the name of your project PROJECT(ANTS) OPTION(USE_ITK "Use ITK Libraries" ON) OPTION(USE_VTK "Use VTK Libraries" OFF) set (CMAKE_INCLUDE_DIRECTORIES_BEFORE ON) FIND_PATH(VTK_DIR UseVTK.cmake $ENV{VTK_DIR} ) # Set up ITK IF(USE_ITK) FIND_PACKAGE(ITK) IF(ITK_FOUND) INCLUDE(${ITK_USE_FILE}) ELSE(ITK_FOUND) MESSAGE(FATAL_ERROR "Cannot build without ITK. Please set ITK_DIR.") ENDIF(ITK_FOUND) ENDIF(USE_ITK) # Set up VTK IF(USE_VTK) FIND_PACKAGE(VTK) IF(VTK_FOUND) INCLUDE(${VTK_USE_FILE}) ELSE(VTK_FOUND) MESSAGE("Cannot build some programs without VTK. Please set VTK_DIR if you need these programs.") ENDIF(VTK_FOUND) ENDIF(USE_VTK) #The following lines are required to use Dart INCLUDE(CTest) ENABLE_TESTING() INCLUDE (${CMAKE_ROOT}/Modules/FindITK.cmake) IF (USE_ITK_FILE) INCLUDE(${USE_ITK_FILE}) ENDIF(USE_ITK_FILE) SET(DART_TESTING_TIMEOUT 1500) SET(PICSL_INCLUDE_DIRS ../Utilities ../ImageRegistration ../ImageSegmentation ../GraphTheory ../Tensor ../Temporary ) INCLUDE_DIRECTORIES(${PICSL_INCLUDE_DIRS}) LINK_DIRECTORIES( ${ITK_LIBRARY_PATH} ) # non-templated class -- this should be stored in a library and linked in... SET(UI_SOURCES "../Utilities/antsCommandLineParser" "../Utilities/antsCommandLineOption" ) ADD_EXECUTABLE(ANTS ANTS.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ANTS ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ANTSJacobian ANTSJacobian.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ANTSJacobian ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(PrintHeader PrintHeader.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(PrintHeader ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ResetDirection ResetDirection.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ResetDirection ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(ResetDirection2 ResetDirection2.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(ResetDirection2 ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(BoykovGraphCutFilter BoykovGraphCutFilter.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(BoykovGraphCutFilter ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(GeneralLinearModel GeneralLinearModel.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(GeneralLinearModel ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ANTSUseLandmarkImagesToGetAffineTransform ANTSUseLandmarkImagesToGetAffineTransform.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ANTSUseLandmarkImagesToGetAffineTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ANTSUseDeformationFieldToGetAffineTransform ANTSUseDeformationFieldToGetAffineTransform ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ANTSUseDeformationFieldToGetAffineTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(FDR FDR.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(FDR ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ImageMath ImageMath.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ImageMath ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SurfaceCurvature SurfaceCurvature.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SurfaceCurvature ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SurfaceBasedSmoothing SurfaceBasedSmoothing.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SurfaceBasedSmoothing ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) # ADD_EXECUTABLE(test test.cxx) #TARGET_LINK_LIBRARIES(test) #ADD_EXECUTABLE(WarpImage WarpImage.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(WarpImage ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(LaplacianThickness LaplacianThickness.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(LaplacianThickness ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SetOrigin SetOrigin.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SetOrigin ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SetSpacing SetSpacing.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SetSpacing ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SetDirectionByMatrix SetDirectionByMatrix.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SetDirectionByMatrix ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(WarpFunctionalImage WarpFunctionalImage.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(WarpFunctionalImage ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ConvertScalarImageToRGB ConvertScalarImageToRGB.cxx) TARGET_LINK_LIBRARIES(ConvertScalarImageToRGB ITKIO) ADD_EXECUTABLE(CreateWarpedGridImage CreateWarpedGridImage.cxx) TARGET_LINK_LIBRARIES(CreateWarpedGridImage ITKCommon ITKBasicFilters ITKIO) # ADD_EXECUTABLE(CreateJacobianDeterminantImage CreateJacobianDeterminantImage.cxx) # TARGET_LINK_LIBRARIES(CreateJacobianDeterminantImage ITKCommon ITKBasicFilters ITKIO) ADD_EXECUTABLE(MeasureImageSimilarity MeasureImageSimilarity.cxx) TARGET_LINK_LIBRARIES(MeasureImageSimilarity ITKCommon ITKBasicFilters ITKIO) ADD_EXECUTABLE(ConvertToJpg ConvertToJpg.cxx) TARGET_LINK_LIBRARIES(ConvertToJpg ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ConvertImagePixelType ConvertImagePixelType.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ConvertImagePixelType ITKCommon ITKBasicFilters ITKIO ) ADD_EXECUTABLE(AverageImages AverageImages.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(AverageImages ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(AverageTensorImages AverageTensorImages.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(AverageTensorImages ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ImageSetStatistics ImageSetStatistics.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ImageSetStatistics ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ThresholdImage ThresholdImage.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ThresholdImage ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(MultiplyImages MultiplyImages.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(MultiplyImages ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(SmoothImage SmoothImage.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(SmoothImage ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ClusterImageStatistics ClusterImageStatistics.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ClusterImageStatistics ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(LabelClustersUniquely LabelClustersUniquely.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(LabelClustersUniquely ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(StudentsTestOnImages StudentsTestOnImages.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(StudentsTestOnImages ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(LabelOverlapMeasures LabelOverlapMeasures.cxx ) TARGET_LINK_LIBRARIES(LabelOverlapMeasures ITKIO) ADD_EXECUTABLE(MeasureMinMaxMean MeasureMinMaxMean.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(MeasureMinMaxMean ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(WarpImageMultiTransform WarpImageMultiTransform ${UI_SOURCES}) TARGET_LINK_LIBRARIES(WarpImageMultiTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ComposeMultiTransform ComposeMultiTransform ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ComposeMultiTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(StackSlices StackSlices.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(StackSlices ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(MemoryTest MemoryTest.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(MemoryTest ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) #ADD_EXECUTABLE(ANTSOrientImage ANTSOrientImage.cxx ${UI_SOURCES}) #TARGET_LINK_LIBRARIES(ANTSOrientImage ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(PermuteFlipImageOrientationAxes PermuteFlipImageOrientationAxes.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(PermuteFlipImageOrientationAxes ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics ITKFEM ) ADD_EXECUTABLE(ImageCompare ImageCompare.cxx) TARGET_LINK_LIBRARIES(ImageCompare ITKIO) ADD_EXECUTABLE(ResampleImageBySpacing ResampleImageBySpacing.cxx) TARGET_LINK_LIBRARIES(ResampleImageBySpacing ITKIO) #ADD_EXECUTABLE(ResampleImageByOtherImage ResampleImageByOtherImage.cxx) #TARGET_LINK_LIBRARIES(ResampleImageByOtherImage ITKIO) ADD_EXECUTABLE(CopyImageHeaderInformation CopyImageHeaderInformation.cxx) TARGET_LINK_LIBRARIES(CopyImageHeaderInformation ITKIO) ADD_EXECUTABLE(WarpTimeSeriesImageMultiTransform WarpTimeSeriesImageMultiTransform.cxx) TARGET_LINK_LIBRARIES(WarpTimeSeriesImageMultiTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics) ADD_EXECUTABLE(ResampleImage ResampleImage.cxx ) TARGET_LINK_LIBRARIES(ResampleImage ITKNumerics ITKIO ITKCommon) ADD_EXECUTABLE(ExtractSliceFromImage ExtractSliceFromImage.cxx ) TARGET_LINK_LIBRARIES(ExtractSliceFromImage ITKNumerics ITKIO ITKCommon) ADD_EXECUTABLE(TileImages TileImages.cxx ) TARGET_LINK_LIBRARIES(TileImages ITKNumerics ITKIO ITKCommon) ADD_EXECUTABLE(WarpTensorImageMultiTransform WarpTensorImageMultiTransform.cxx) TARGET_LINK_LIBRARIES(WarpTensorImageMultiTransform ITKCommon ITKBasicFilters ITKIO ITKNumerics ITKStatistics) ADD_EXECUTABLE(ReorientTensorImage ReorientTensorImage.cxx) TARGET_LINK_LIBRARIES(ReorientTensorImage ITKCommon ITKBasicFilters ITKIO) ADD_EXECUTABLE(N3BiasFieldCorrection N3BiasFieldCorrection.cxx) TARGET_LINK_LIBRARIES(N3BiasFieldCorrection ITKIO ITKStatistics ITKNumerics) ADD_EXECUTABLE(N4BiasFieldCorrection N4BiasFieldCorrection.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(N4BiasFieldCorrection ITKIO ITKStatistics) ADD_EXECUTABLE(KellySlater KellySlater.cxx) TARGET_LINK_LIBRARIES(KellySlater ITKIO ITKStatistics) IF (USE_VTK) INCLUDE (${CMAKE_ROOT}/Modules/FindVTK.cmake) IF (USE_VTK_FILE) INCLUDE(${USE_VTK_FILE}) ADD_EXECUTABLE(ConvertVectorFieldToVTK ConvertVectorFieldToVTK.cxx ) TARGET_LINK_LIBRARIES(ConvertVectorFieldToVTK ITKNumerics ITKIO ITKCommon vtkIO) ADD_EXECUTABLE(GetMeshAndTopology GetMeshAndTopology.cxx) TARGET_LINK_LIBRARIES(GetMeshAndTopology ITKCommon ITKNumerics ITKFEM ITKIO ITKMetaIO vtkRendering vtksys vtkIO) ADD_EXECUTABLE(CheckTopology CheckTopology.cxx) TARGET_LINK_LIBRARIES(CheckTopology ITKCommon ITKNumerics ITKFEM ITKIO ITKMetaIO vtkRendering vtksys vtkIO) ADD_EXECUTABLE(WarpVTKPolyDataMultiTransform WarpVTKPolyDataMultiTransform) TARGET_LINK_LIBRARIES(WarpVTKPolyDataMultiTransform ITKIO vtksys vtkIO ) SET(FLAT_SRC ../Temporary/itkFEMElement3DC0LinearTriangular.cxx ../Temporary/itkFEMElement3DC0LinearTriangularLaplaceBeltrami.cxx ../Temporary/itkFEMElement3DC0LinearTriangularMembrane.cxx ) # Build the library ADD_LIBRARY(FLATFEM ${FLAT_SRC}) TARGET_LINK_LIBRARIES(FLATFEM ITKBasicFilters ITKIO) ADD_EXECUTABLE(ConformalMapping ConformalMapping.cxx) TARGET_LINK_LIBRARIES(ConformalMapping ITKCommon ITKNumerics ITKFEM FLATFEM ITKIO ITKMetaIO vtkRendering vtkIO) ADD_EXECUTABLE(ANTSConformalMapping ANTSConformalMapping.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(ANTSConformalMapping ITKCommon ITKNumerics ITKFEM FLATFEM ITKIO ITKMetaIO vtkRendering vtkIO) ENDIF (USE_VTK_FILE) ENDIF(USE_VTK) ADD_EXECUTABLE(ANTSIntegrateVectorField ANTSIntegrateVectorField.cxx) TARGET_LINK_LIBRARIES(ANTSIntegrateVectorField ITKIO ITKStatistics) IF( ITK_USE_REVIEW_STATISTICS ) ADD_EXECUTABLE(Atropos Atropos.cxx ${UI_SOURCES}) TARGET_LINK_LIBRARIES(Atropos ITKCommon ITKBasicFilters ITKIO ITKStatistics ) ENDIF( ITK_USE_REVIEW_STATISTICS ) #Set any libraries that your project depends on. #examples: ITKCommon, VTKRendering, etc SET(Libraries ITKIO ) #SET(CurrentExe "GlamorousGlue") #ADD_EXECUTABLE(${CurrentExe} GlamorousGlue.cxx) #TARGET_LINK_LIBRARIES(${CurrentExe} ${Libraries}) ## # Copy all the shell scripts in the Scripts/ directory to the bin directory ## OPTION( COPY_SCRIPT_FILES_TO_BIN_DIR "Copy the script files to the ANTS bin directory." ON ) IF( COPY_SCRIPT_FILES_TO_BIN_DIR ) FILE( GLOB SCRIPT_FILES "${CMAKE_SOURCE_DIR}/../Scripts/*.sh" ) FILE( GLOB PSCRIPT_FILES "${CMAKE_SOURCE_DIR}/../Scripts/*.pl" ) FOREACH( SCRIPT_FILE ${SCRIPT_FILES} ) ADD_CUSTOM_COMMAND( TARGET ANTS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SCRIPT_FILE} ${CMAKE_BINARY_DIR} ) ENDFOREACH( SCRIPT_FILE ) FOREACH( SCRIPT_FILE ${PSCRIPT_FILES} ) ADD_CUSTOM_COMMAND( TARGET ANTS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SCRIPT_FILE} ${CMAKE_BINARY_DIR} ) ENDFOREACH( SCRIPT_FILE ) ENDIF( COPY_SCRIPT_FILES_TO_BIN_DIR ) ### # Perform testing ### SET(DATA_DIR ${CMAKE_SOURCE_DIR}/Data) SET(R16_IMAGE ${DATA_DIR}/r16slice.nii) SET(R64_IMAGE ${DATA_DIR}/r64slice.nii) SET(OUTPUT_PREFIX ${CMAKE_BINARY_DIR}/TEST) SET(WARP ${OUTPUT_PREFIX}Warp.nii.gz ${OUTPUT_PREFIX}Affine.txt ) SET(INVERSEWARP -i ${OUTPUT_PREFIX}Affine.txt ${OUTPUT_PREFIX}InverseWarp.nii.gz ) SET(WARP_IMAGE ${CMAKE_BINARY_DIR}/warped.nii.gz) SET(INVERSEWARP_IMAGE ${CMAKE_BINARY_DIR}/inversewarped.nii.gz) SET(DEVIL_IMAGE ${DATA_DIR}/Frown.nii) SET(ANGEL_IMAGE ${DATA_DIR}/Smile.nii) SET(SEG_IMAGE ${DATA_DIR}/nslice.nii.gz) ### # ANTS metric testing ### ADD_TEST(ANTS_CC_1 ANTS 2 -m PR[ ${R16_IMAGE}, ${R64_IMAGE}, 1 ,2 ] -r Gauss[ 3 , 0 ] -t SyN[ 0.5 ] -i 50x50x30 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_CC_1_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_1_JPG ConvertToJpg ${WARP_IMAGE} ANTSCC1.jpg) ADD_TEST(ANTS_CC_1_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.9992 0.05) ADD_TEST(ANTS_CC_1_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.61 0.05) ADD_TEST(ANTS_CC_1_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.00038593 0.05) ADD_TEST(ANTS_CC_1_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_1_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.1606 0.05) ADD_TEST(ANTS_CC_1_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.61 0.05) ADD_TEST(ANTS_CC_1_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000380545 0.05) ADD_TEST(ANTS_CC_2 ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,4] -r Gauss[3,0] -t SyN[0.5] -i 50x50x30 -o ${OUTPUT_PREFIX}.nii.gz --go-faster true ) ADD_TEST(ANTS_CC_2_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_2_JPG ConvertToJpg ${WARP_IMAGE} ANTSCC2.jpg) ADD_TEST(ANTS_CC_2_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.7083 0.05) ADD_TEST(ANTS_CC_2_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.62 0.05) ADD_TEST(ANTS_CC_2_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000461792 0.05) ADD_TEST(ANTS_CC_2_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_2_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.8012 0.05) ADD_TEST(ANTS_CC_2_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.62 0.05) ADD_TEST(ANTS_CC_2_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000442839 0.05) #ADD_TEST(ANTS_CC_2_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -5 0.05) ADD_TEST(ANTS_CC_3 ANTS 2 -m CC[${R16_IMAGE},${R64_IMAGE},1,4] -r Gauss[3,0] -t SyN[0.5] -i 50x50x30 -o ${OUTPUT_PREFIX}.nii.gz --go-faster true ) ADD_TEST(ANTS_CC_3_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_3_JPG ConvertToJpg ${WARP_IMAGE} ANTSCC2.jpg) ADD_TEST(ANTS_CC_3_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.7083 0.05) ADD_TEST(ANTS_CC_3_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.62 0.05) ADD_TEST(ANTS_CC_3_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000461792 0.05) ADD_TEST(ANTS_CC_3_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_CC_3_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.8012 0.05) ADD_TEST(ANTS_CC_3_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.62 0.05) ADD_TEST(ANTS_CC_3_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000442839 0.05) #ADD_TEST(ANTS_CC_3_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -5 0.05) ADD_TEST(ANTS_MSQ ANTS 2 -m MSQ[${R16_IMAGE},${R64_IMAGE},1,0] -r Gauss[2,0] -t SyN[0.5] -i 50x50x30 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_MSQ_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MSQ_JPG ConvertToJpg ${WARP_IMAGE} ANTSMSQ.jpg) ADD_TEST(ANTS_MSQ_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.7416 0.05) ADD_TEST(ANTS_MSQ_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_MSQ_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000543902 0.05) ADD_TEST(ANTS_MSQ_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MSQ_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.7845 0.05) ADD_TEST(ANTS_MSQ_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_MSQ_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000501458 0.05) ADD_TEST(ANTS_MI_1 ANTS 2 -m MI[${R16_IMAGE},${R64_IMAGE},1,32] -r Gauss[3,0] -t SyN[0.25] -i 50x50x30 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_MI_1_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MI_1_JPG ConvertToJpg ${WARP_IMAGE} ANTSMI1.jpg) ADD_TEST(ANTS_MI_1_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.4 0.05) ADD_TEST(ANTS_MI_1_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.45 0.05) ADD_TEST(ANTS_MI_1_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000370686 0.05) ADD_TEST(ANTS_MI_1_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MI_1_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.6 0.05) ADD_TEST(ANTS_MI_1_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.45 0.05) ADD_TEST(ANTS_MI_1_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000366879 0.05) ADD_TEST(ANTS_MI_2 ANTS 2 -m SMI[${R16_IMAGE},${R64_IMAGE},1,32] -r Gauss[3,0] -t SyN[0.25] -i 50x0x0 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_MI_2_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MI_2_JPG ConvertToJpg ${WARP_IMAGE} ANTSMI2.jpg) ADD_TEST(ANTS_MI_2_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.4 0.05) ADD_TEST(ANTS_MI_2_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.45 0.05) ADD_TEST(ANTS_MI_2_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000370686 0.05) ADD_TEST(ANTS_MI_2_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_MI_2_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.6 0.05) ADD_TEST(ANTS_MI_2_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.45 0.05) ADD_TEST(ANTS_MI_2_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000366879 0.05) ### # ANTS transform testing ### ADD_TEST(ANTS_ELASTIC ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,2] -t Elast[1] -i 50x50x50 -r Gauss[0,1] -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_ELASTIC_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_ELASTIC_JPG ConvertToJpg ${WARP_IMAGE} ANTSELASTIC.jpg) ADD_TEST(ANTS_ELASTIC_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.5 0.05) ADD_TEST(ANTS_ELASTIC_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.4 0.05) ADD_TEST(ANTS_ELASTIC_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000459869 0.05) ADD_TEST(ANTS_GSYN ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,2] -t SyN[0.25] -i 50x50x50 -r Gauss[3,0.0,32] -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_GSYN_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_GSYN_JPG ConvertToJpg ${WARP_IMAGE} ANTSGSYN.jpg) ADD_TEST(ANTS_GSYN_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 11.7734 0.05) ADD_TEST(ANTS_GSYN_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_GSYN_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000478672 0.05) ADD_TEST(ANTS_GSYN_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_GSYN_JPGINV ConvertToJpg ${INVERSEWARP_IMAGE} ANTSGSYNINV.jpg) ADD_TEST(ANTS_GSYN_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.0541 0.05) ADD_TEST(ANTS_GSYN_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_GSYN_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000475175 0.05) ADD_TEST(ANTS_EXP ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,4] -t Exp[0.5,2,0.5] -i 50x50x50 -r Gauss[0.5,0.25] -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_EXP_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_EXP_JPG ConvertToJpg ${WARP_IMAGE} ANTSEXP.jpg) ADD_TEST(ANTS_EXP_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12 0.05) ADD_TEST(ANTS_EXP_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.5 0.05) ADD_TEST(ANTS_EXP_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000423693 0.05) ADD_TEST(ANTS_EXP_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_EXP_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.349 0.05) ADD_TEST(ANTS_EXP_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.5 0.05) ADD_TEST(ANTS_EXP_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000339606 0.05) #ADD_TEST(ANTS_GSYN ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,2] -t SyN[0.75] -i 50x50x50 -r Gauss[3,0.0,32] -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_SYN ANTS 2 -m PR[${R16_IMAGE},${R64_IMAGE},1,2] -t SyN[0.5,2,0.05] -i 50x50x50 -r Gauss[3,0.0,32] -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_SYN_WARP WarpImageMultiTransform 2 ${R64_IMAGE} ${WARP_IMAGE} ${WARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_SYN_JPG ConvertToJpg ${WARP_IMAGE} ANTSSYN.jpg) ADD_TEST(ANTS_SYN_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.0239 0.05) ADD_TEST(ANTS_SYN_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_SYN_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${R16_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000461922 0.05) ADD_TEST(ANTS_SYN_INVERSEWARP WarpImageMultiTransform 2 ${R16_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${R16_IMAGE} ) ADD_TEST(ANTS_SYN_JPGINV ConvertToJpg ${INVERSEWARP_IMAGE} ANTSSYNINV.jpg) ADD_TEST(ANTS_SYN_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 12.5104 0.05) ADD_TEST(ANTS_SYN_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.6 0.05) ADD_TEST(ANTS_SYN_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${R64_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000444279 0.05) ### # PSE sub-tests: Check to see if .txt files and .vtk files also run correctly ### SET(ANGEL_IMAGE_TXT ${DATA_DIR}/Smile.txt) SET(DEVIL_IMAGE_TXT ${DATA_DIR}/Frown.txt) SET(ANGEL_IMAGE_VTK ${DATA_DIR}/Smile.vtk) SET(DEVIL_IMAGE_VTK ${DATA_DIR}/Frown.vtk) ADD_TEST(ANTS_PSE_MSQ_TXT ANTS 2 -i 91x70x55x40x30 -r Gauss[3,0.,32] -t SyN[0.25] -m MSQ[${DEVIL_IMAGE},${ANGEL_IMAGE},1,0] -m PSE[${DEVIL_IMAGE},${ANGEL_IMAGE},${DEVIL_IMAGE_TXT},${ANGEL_IMAGE_TXT},1,0.33,11,1,25] --continue-affine 0 --number-of-affine-iterations 0 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_PSE_MSQ_VTK ANTS 2 -i 91x70x55x40x30 -r Gauss[3,0.,32] -t SyN[0.25] -m MSQ[${DEVIL_IMAGE},${ANGEL_IMAGE},1,0] -m PSE[${DEVIL_IMAGE},${ANGEL_IMAGE},${DEVIL_IMAGE_VTK},${ANGEL_IMAGE_VTK},1,0.33,11,1,25] --continue-affine 0 --number-of-affine-iterations 0 -o ${OUTPUT_PREFIX}.nii.gz) ### # ANTS labeled data testing ### OPTION(RUN_LONG_TESTS "Run the time consuming tests." OFF ) IF(RUN_LONG_TESTS) ADD_TEST(ANTS_PSE_MSQ_IMG ANTS 2 -i 191x170x90x90x10 -r Gauss[6,0.25] -t SyN[1,2,0.1] -m PSE[${DEVIL_IMAGE},${ANGEL_IMAGE},${DEVIL_IMAGE},${ANGEL_IMAGE},0.25,0.1,100,0,10] -m MSQ[${DEVIL_IMAGE},${ANGEL_IMAGE},1,0.1] --continue-affine 0 --number-of-affine-iterations 0 --geodesic 2 -o ${OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_PSE_MSQ_IMG_WARP WarpImageMultiTransform 2 ${ANGEL_IMAGE} ${WARP_IMAGE} ${WARP} -R ${DEVIL_IMAGE} ) ADD_TEST(ANTS_PSE_JPG ConvertToJpg ${WARP_IMAGE} ANTSPSE.jpg) ADD_TEST(ANTS_PSE_MSQ_IMG_WARP_METRIC_0 MeasureImageSimilarity 2 0 ${DEVIL_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 0.0116083 0.05) ADD_TEST(ANTS_PSE_MSQ_IMG_WARP_METRIC_1 MeasureImageSimilarity 2 1 ${DEVIL_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.884041 0.05) ADD_TEST(ANTS_PSE_MSQ_IMG_WARP_METRIC_2 MeasureImageSimilarity 2 2 ${DEVIL_IMAGE} ${WARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000710551 0.05) ADD_TEST(ANTS_PSE_MSQ_IMG_INVERSEWARP WarpImageMultiTransform 2 ${DEVIL_IMAGE} ${INVERSEWARP_IMAGE} ${INVERSEWARP} -R ${ANGEL_IMAGE} ) ADD_TEST(ANTS_PSE_JPGINV ConvertToJpg ${INVERSEWARP_IMAGE} ANTSPSEINV.jpg) ADD_TEST(ANTS_PSE_MSQ_IMG_INVERSEWARP_METRIC_0 MeasureImageSimilarity 2 0 ${ANGEL_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 0.0109054 0.05) ADD_TEST(ANTS_PSE_MSQ_IMG_INVERSEWARP_METRIC_1 MeasureImageSimilarity 2 1 ${ANGEL_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.901632 0.05) ADD_TEST(ANTS_PSE_MSQ_IMG_INVERSEWARP_METRIC_2 MeasureImageSimilarity 2 2 ${ANGEL_IMAGE} ${INVERSEWARP_IMAGE} ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz -0.000704717 0.05) ### # ANTS images with non-trival rotation header test ### #SET(ROT_REF_IMAGE ${DATA_DIR}/ref2.nii.gz) #SET(ROT_MOV_IMAGE ${DATA_DIR}/mov2.nii.gz) SET(ROT_REF_IMAGE ${DATA_DIR}/r16roth.nii.gz) SET(ROT_MOV_IMAGE ${DATA_DIR}/r64roth.nii.gz) SET(ROT_OUTPUT_PREFIX ${CMAKE_BINARY_DIR}/RotTEST) SET(ROT_WARP ${ROT_OUTPUT_PREFIX}Warp.nii.gz ${ROT_OUTPUT_PREFIX}Affine.txt ) SET(ROT_INVERSEWARP -i ${ROT_OUTPUT_PREFIX}Affine.txt ${ROT_OUTPUT_PREFIX}InverseWarp.nii.gz ) SET(ROT_WARP_IMAGE ${CMAKE_BINARY_DIR}/rotwarped.nii.gz) SET(ROT_INVERSEWARP_IMAGE ${CMAKE_BINARY_DIR}/rotinversewarped.nii.gz) SET(ROT_WARP_FILES ${ROT_OUTPUT_PREFIX}Warp*vec.nii.gz ${ROT_OUTPUT_PREFIX}InverseWarp*vec.nii.gz ${ROT_OUTPUT_PREFIX}Affine.txt ) #ADD_TEST(ANTS_ROT_SYN ANTS 3 -m MSQ[${ROT_REF_IMAGE},${ROT_MOV_IMAGE},1,0] -t SyN[0.5,2,0.05] -i 50x5x0 -r Gauss[3,0.] -o ${ROT_OUTPUT_PREFIX}.nii.gz) #ADD_TEST(ANTS_ROT_SYN_WARP WarpImageMultiTransform 3 ${ROT_MOV_IMAGE} ${ROT_WARP_IMAGE} -R ${ROT_REF_IMAGE} ${ROT_WARP} ) #ADD_TEST(ANTS_ROT_SYN_WARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_REF_IMAGE} ${ROT_WARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${ROT_OUTPUT_PREFIX}metric.nii.gz 35.4473 0.5) #ADD_TEST(ANTS_ROT_SYN_INVERSEWARP WarpImageMultiTransform 3 ${ROT_REF_IMAGE} ${ROT_INVERSEWARP_IMAGE} -R ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP}) #ADD_TEST(ANTS_ROT_SYN_INVERSEWARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 34.8184 0.5) #ADD_TEST(ANTS_ROT_SYN_CLEAN rm ${ROT_WARP_FILES}) ADD_TEST(ANTS_ROT_GSYN ANTS 3 -m MSQ[${ROT_REF_IMAGE},${ROT_MOV_IMAGE},1,0] -t SyN[0.25] -i 50x5x0 -r Gauss[3,0.0,32] -o ${ROT_OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_ROT_GSYN_WARP WarpImageMultiTransform 3 ${ROT_MOV_IMAGE} ${ROT_WARP_IMAGE} -R ${ROT_REF_IMAGE} ${ROT_WARP} ) ADD_TEST(ANTS_ROT_GSYN_WARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_REF_IMAGE} ${ROT_WARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${ROT_OUTPUT_PREFIX}metric.nii.gz 35.4473 0.5) ADD_TEST(ANTS_ROT_GSYN_INVERSEWARP WarpImageMultiTransform 3 ${ROT_REF_IMAGE} ${ROT_INVERSEWARP_IMAGE} -R ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP}) ADD_TEST(ANTS_ROT_GSYN_INVERSEWARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 34.8184 0.5) #ADD_TEST(ANTS_ROT_GSYN_CLEAN rm ${ROT_WARP_FILES}) ADD_TEST(ANTS_ROT_EXP ANTS 3 -m MSQ[${ROT_REF_IMAGE},${ROT_MOV_IMAGE},1,0] -t Exp[3,2] -i 50x5x1 -r Gauss[3,0.0,32] -o ${ROT_OUTPUT_PREFIX}.nii.gz) ADD_TEST(ANTS_ROT_EXP_WARP WarpImageMultiTransform 3 ${ROT_MOV_IMAGE} ${ROT_WARP_IMAGE} -R ${ROT_REF_IMAGE} ${ROT_WARP} ) ADD_TEST(ANTS_ROT_EXP_WARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_REF_IMAGE} ${ROT_WARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${ROT_OUTPUT_PREFIX}metric.nii.gz 35.4473 0.5) ADD_TEST(ANTS_ROT_EXP_WARP2 WarpImageMultiTransform 3 ${ROT_MOV_IMAGE} ${ROT_WARP_IMAGE} -R ${ROT_REF_IMAGE} --ANTS-prefix ${ROT_OUTPUT_PREFIX} ) ADD_TEST(ANTS_ROT_EXP_WARP2_METRIC_0_2 MeasureImageSimilarity 3 0 ${ROT_REF_IMAGE} ${ROT_WARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${ROT_OUTPUT_PREFIX}metric.nii.gz 35.4473 0.5) ADD_TEST(ANTS_ROT_EXP_INVERSEWARP WarpImageMultiTransform 3 ${ROT_REF_IMAGE} ${ROT_INVERSEWARP_IMAGE} -R ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP}) ADD_TEST(ANTS_ROT_EXP_INVERSEWARP_METRIC_0 MeasureImageSimilarity 3 0 ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 34.8184 0.5) ADD_TEST(ANTS_ROT_EXP_INVERSEWARP2 WarpImageMultiTransform 3 ${ROT_REF_IMAGE} ${ROT_INVERSEWARP_IMAGE} -R ${ROT_MOV_IMAGE} --ANTS-prefix-invert ${ROT_OUTPUT_PREFIX}) ADD_TEST(ANTS_ROT_EXP_INVERSEWARP2_METRIC_0_2 MeasureImageSimilarity 3 0 ${ROT_MOV_IMAGE} ${ROT_INVERSEWARP_IMAGE} ${ROT_OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 34.8184 0.5) #ADD_TEST(ANTS_ROT_EXP_CLEAN rm ${ROT_WARP_FILES}) ### # Test SyN with time ### SET(CHALF_IMAGE ${DATA_DIR}/chalf.nii.gz) SET(C_IMAGE ${DATA_DIR}/c.nii.gz) ADD_TEST(ANTS_SYN_WITH_TIME ANTS 2 -m MSQ[${CHALF_IMAGE},${C_IMAGE},1,0.] -t SyN[1,10,0.05] -i 150x100x2x2 -r Gauss[0.5,0.1] -o ${OUTPUT_PREFIX} --geodesic 1 --number-of-affine-iterations 0) ADD_TEST(ANTS_SYN_WITH_TIME_WARP WarpImageMultiTransform 2 ${C_IMAGE} ${OUTPUT_PREFIX}.nii.gz ${OUTPUT_PREFIX}Warp.nii.gz -R ${CHALF_IMAGE} ) ADD_TEST(ANTS_SYN_WITH_TIME_METRIC MeasureImageSimilarity 2 0 ${CHALF_IMAGE} ${OUTPUT_PREFIX}.nii.gz ${OUTPUT_PREFIX}log.txt ${OUTPUT_PREFIX}metric.nii.gz 0.0943736 0.1) ## # Apocrita tests ## SET(R16_MASK ${DATA_DIR}/r16mask.nii.gz) SET(R16_PRIORS ${DATA_DIR}/r16priors.nii.gz) #ADD_TEST(APOC_OTSU_INIT Apocrita 2 -i otsu[${R16_IMAGE},3] -x ${R16_MASK} -n 10 -m [0.3,1x1,0.2,0.1] -o ${OUTPUT_PREFIX}.nii.gz ) #ADD_TEST(APOC_OTSU_INIT_RADIUS_2x2 Apocrita 2 -i otsu[${R16_IMAGE},3] -x ${R16_MASK} -n 10 -m [0.3,2,0.2,0.1] -o ${OUTPUT_PREFIX}.nii.gz ) #ADD_TEST(APOC_KMEANS_INIT Apocrita 2 -i kmeans[${R16_IMAGE},3] -x ${R16_MASK} -n 10 -m [0.3,1x1,0.2,0.1] -o [${OUTPUT_PREFIX}.nii.gz,${OUTPUT_PREFIX}_posteriors%d.nii.gz]) #ADD_TEST(APOC_PRIORLABELIMAGE_INIT Apocrita 2 -i priorlabelimage[${R16_IMAGE},5,${R16_PRIORS},0.5] -x ${R16_MASK} -n 10 -m [0.3,1x1,0.2,0.1] -o [${OUTPUT_PREFIX}.nii.gz,${OUTPUT_PREFIX}_posteriors%d.nii.gz] -l 1[1,0.75] -l 2[1,1.0] -l 3[0.5,0.5] -l 4[1,1]) ENDIF(RUN_LONG_TESTS) ants-1.9.2+svn680.dfsg/Examples/CTestConfig.cmake000066400000000000000000000010261147325206600214070ustar00rootroot00000000000000## This file should be placed in the root directory of your project. ## Then modify the CMakeLists.txt file in the root directory of your ## project to incorporate the testing dashboard. ## # The following are required to uses Dart and the Cdash dashboard ## ENABLE_TESTING() ## INCLUDE(CTest) set(CTEST_PROJECT_NAME "ANTS") set(CTEST_NIGHTLY_START_TIME "00:00:00 EST") set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "picsl.upenn.edu") set(CTEST_DROP_LOCATION "/cdash/submit.php?project=ANTS") set(CTEST_DROP_SITE_CDASH TRUE) ants-1.9.2+svn680.dfsg/Examples/CheckTopology.cxx000066400000000000000000000343611147325206600215430ustar00rootroot00000000000000 /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: CheckTopology.cxx,v $ Language: C++ $Date: 2008/12/07 03:06:27 $ $Revision: 1.8 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "itkDiscreteGaussianImageFilter.h" #include "itkImage.h" #include "itkExceptionObject.h" #include "ReadWriteImage.h" #include "itkVector.h" #include "itkBinaryThresholdImageFilter.h" #include "itkRandomImageSource.h" #include "itkImageRandomConstIteratorWithIndex.h" #include "itkImageLinearIteratorWithIndex.h" #include "itkShapedNeighborhoodIterator.h" #include "BinaryImageToMeshFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "vtkCallbackCommand.h" #include "vtkPointPicker.h" #include "vtkCellPicker.h" #include "vtkPolyDataWriter.h" #include "vtkPolyDataReader.h" #include "vtkExtractEdges.h" #include "itkMinimumMaximumImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkRelabelComponentImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkLabelStatisticsImageFilter.h" float random_range(float lowest_number, float highest_number) { float range = highest_number - lowest_number; return lowest_number + (float)(range * (float)rand()/(float)(RAND_MAX)); } float ComputeGenus(vtkPolyData* pd1) { vtkExtractEdges* edgeex=vtkExtractEdges::New(); edgeex->SetInput(pd1); edgeex->Update(); vtkPolyData* edg1=edgeex->GetOutput(); vtkIdType nedg=edg1->GetNumberOfCells(); vtkIdType vers = pd1->GetNumberOfPoints(); int nfac = pd1->GetNumberOfPolys(); float g = 0.5 * (2.0 - vers + nedg - nfac); std::cout << " Genus " << g << std::endl; std::cout << " face " << nfac << " edg " << nedg << " vert " << vers << std::endl; //edg1->Delete(); //caused malloc err edgeex->Delete(); // should be deleted b/c of New() above !! return g; } float vtkComputeTopology(vtkPolyData* pd) { vtkPolyDataConnectivityFilter* con = vtkPolyDataConnectivityFilter::New(); con->SetExtractionModeToLargestRegion(); con->SetInput(pd); float g = ComputeGenus(con->GetOutput()); con->Delete(); // should be deleted b/c of New() above !! return g; } template float GetImageTopology(typename TImage::Pointer image) { typedef TImage ImageType; typedef vtkPolyData MeshType; double aaParm = 0.024; typedef BinaryImageToMeshFilter FilterType; typename FilterType::Pointer fltMesh = FilterType::New(); fltMesh->SetInput(image); fltMesh->SetAntiAliasMaxRMSError(aaParm); fltMesh->SetAntiAliasMaxRMSError( -1000.0 ); // to do nothing fltMesh->SetSmoothingIterations(0); fltMesh->Update(); vtkPolyData* vtkmesh =fltMesh->GetMesh(); std::cout << " start topo " << std::endl; float genus = vtkComputeTopology(vtkmesh); std::cout << " Genus " << genus << std::endl; // vtkmesh->Delete(); return genus; } template void NormalizeImage(typename TImage::Pointer image) { typedef itk::ImageRegionIteratorWithIndex Iterator; float max=0; Iterator vfIter2( image, image->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) if (vfIter2.Get() > max) max=vfIter2.Get(); if (max == 0) max=1; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) vfIter2.Set( vfIter2.Get()/max); } template typename TImage::Pointer SmoothImage( typename TImage::Pointer image, float sig ) { typedef float PixelType; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOff(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); return filter->GetOutput(); } template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType low, typename TImage::PixelType high, typename TImage::PixelType replaceval, typename TImage::Pointer input) { typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } template //std::vector typename TImage::Pointer GetLargestComponent(typename TImage::Pointer image) { enum { ImageDimension = TImage::ImageDimension }; typedef int InternalPixelType; typedef itk::Image InternalImageType; typedef TImage OutputImageType; typedef itk::BinaryThresholdImageFilter< TImage, InternalImageType > ThresholdFilterType; typedef itk::ConnectedComponentImageFilter< InternalImageType, InternalImageType > FilterType; typedef itk::RelabelComponentImageFilter< InternalImageType, InternalImageType > RelabelType; typename ThresholdFilterType::Pointer threshold = ThresholdFilterType::New(); typename FilterType::Pointer filter = FilterType::New(); typename RelabelType::Pointer relabel = RelabelType::New(); threshold->SetInput (image); threshold->SetInsideValue(itk::NumericTraits::One); threshold->SetOutsideValue(itk::NumericTraits::Zero); threshold->SetLowerThreshold(0.499); threshold->SetUpperThreshold(1.001); threshold->Update(); filter->SetInput (threshold->GetOutput()); // if (argc > 5) { int fullyConnected = 1;//atoi( argv[5] ); filter->SetFullyConnected( fullyConnected ); } relabel->SetInput( filter->GetOutput() ); unsigned int minSize=50; std::cout << " min Size " << minSize << std::endl; relabel->SetMinimumObjectSize( minSize ); // relabel->SetUseHistograms(true); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } typename TImage::Pointer Clusters=TImage::New(); //typename TImage::Pointer Clusters=relabel->GetOutput(); Clusters->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); Clusters->SetBufferedRegion( image->GetLargestPossibleRegion().GetSize() ); Clusters->SetSpacing(image->GetSpacing()); Clusters->SetDirection( image->GetDirection() ); Clusters->SetOrigin(image->GetOrigin()); Clusters->Allocate(); Clusters->FillBuffer(0); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); float maximum=relabel->GetNumberOfObjects(); float maxtstat=0; std::vector histogram((int)maximum+1); std::vector clustersum((int)maximum+1); for (int i=0; i<=maximum; i++) { histogram[i]=0; clustersum[i]=0; } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { float vox=image->GetPixel(vfIter.GetIndex()); histogram[(unsigned int)vfIter.Get()]=histogram[(unsigned int)vfIter.Get()]+1; clustersum[(unsigned int)vfIter.Get()]+=vox; if (vox > maxtstat) maxtstat=vox; } } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { Clusters->SetPixel( vfIter.GetIndex(), histogram[(unsigned int)vfIter.Get()] ); // if ( Clusters->GetPixel( vfIter.GetIndex() ) > maximgval ) // maximgval=Clusters->GetPixel( vfIter.GetIndex()); } else Clusters->SetPixel(vfIter.GetIndex(),0); } float maximgval=0; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) > maximgval ) maximgval=Clusters->GetPixel( vfIter.GetIndex()); std::cout << " max size " << maximgval << std::endl; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) >= maximgval ) Clusters->SetPixel( vfIter.GetIndex(), 1); else Clusters->SetPixel( vfIter.GetIndex(), 0); // for (int i=0; i<=maximum; i++) // std::cout << " label " << i << " ct is: " << histogram[i] << std::endl; return Clusters; } template typename TImage::Pointer Morphological( typename TImage::Pointer input,float rad, bool option) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::PixelType PixelType; if (!option) std::cout << " eroding the image " << std::endl; else std::cout << " dilating the image " << std::endl; typedef itk::BinaryBallStructuringElement< PixelType, ImageDimension > StructuringElementType; // Software Guide : BeginCodeSnippet typedef itk::BinaryErodeImageFilter< TImage, TImage, StructuringElementType > ErodeFilterType; typedef itk::BinaryDilateImageFilter< TImage, TImage, StructuringElementType > DilateFilterType; typename ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius((unsigned long) rad ); // 3x3x3 structuring element structuringElement.CreateStructuringElement(); binaryErode->SetKernel( structuringElement ); binaryDilate->SetKernel( structuringElement ); // It is necessary to define what could be considered objects on the binary // images. This is specified with the methods \code{SetErodeValue()} and // \code{SetDilateValue()}. The value passed to these methods will be // considered the value over which the dilation and erosion rules will apply binaryErode->SetErodeValue( 1 ); binaryDilate->SetDilateValue( 1 ); typename TImage::Pointer temp; if (option) { binaryDilate->SetInput( input ); binaryDilate->Update(); temp = binaryDilate->GetOutput(); } else { binaryErode->SetInput( input );//binaryDilate->GetOutput() ); binaryErode->Update(); temp = binaryErode->GetOutput(); typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; ImageIteratorType o_iter( temp, temp->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { if (o_iter.Get() > 0.5 && input->GetPixel(o_iter.GetIndex()) > 0.5) o_iter.Set(1); else o_iter.Set(0); ++o_iter; } } return temp; } int main(int argc, char *argv[]) { if ( argc < 2 ) { std::cout << "Parameter missing" << std::endl; std::cout << std::endl; std::cout << "Usage:" << argv[0] << " image.nii {g0image.nii} {threshold}" << std::endl; std::cout << " If you put an arg for g0image then image will be smoothed and thresholded \n until it has genus zero or the smoothing kernel gets too large " << std::endl; return 1; } float thresh=-1;//0.0001; if (argc > 3) thresh=atof(argv[3]); typedef float PixelType; const unsigned int ImageDimension=3;//AvantsImageDimension; typedef itk::Image ImageType; typedef float FieldValueType; ImageType::Pointer image; ReadImage(image,argv[1]); image=BinaryThreshold(0.5,1.e9,1,image); float initG = GetImageTopology(image); if (initG < 0 && argc > 2) { std::cout << "smoothing into a Genus Zero image with thresh " << thresh << std::endl; float G=1; float smooth=1; ImageType::Pointer simage; while ( G != 0 && smooth < 20 ) { simage=SmoothImage(image,smooth); NormalizeImage(simage); simage=BinaryThreshold(thresh,1.e9,1,simage); ImageType::Pointer bigimage = GetLargestComponent(simage); G = GetImageTopology(bigimage); smooth=smooth+1; simage=bigimage; std::cout << " G " << G << " at smoothing " << smooth << std::endl; } std::cout << " Final G " << G << " at smoothing " << smooth << std::endl; float G2=0; unsigned int mct=0; float err=1.e9,lasterr=1.e10,derr=1.e9; derr=lasterr-err; while ( G2 == 0 && derr > 0 ) { lasterr=err; err=0; ImageType::Pointer out = Morphological(simage,3,0); ImageType::Pointer bigimage = GetLargestComponent(out); G2 = GetImageTopology(bigimage); typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; ImageIteratorType iter( bigimage, bigimage->GetLargestPossibleRegion() ); iter.GoToBegin() ; while ( !iter.IsAtEnd() ) { err+=fabs(iter.Get() - image->GetPixel(iter.GetIndex())); ++iter; } mct++; derr=lasterr-err; std::cout << " G2 " << G2 << " at morph " << mct << " err " << err << std::endl; if (G2==0 && derr > 0) { simage=GetLargestComponent(out); } } WriteImage(simage ,argv[2]); } else if (argc > 2 ) { WriteImage(image ,argv[2]); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ClusterImageStatistics.cxx000066400000000000000000000262141147325206600234260ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ClusterImageStatistics.cxx,v $ Language: C++ Date: $Date: 2008/12/15 16:35:13 $ Version: $Revision: 1.20 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkDiscreteGaussianImageFilter.h" // RecursiveAverageImages img1 img2 weightonimg2 outputname // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. #include #include #include #include "vnl/vnl_vector.h" #include "itkMinimumMaximumImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkRelabelComponentImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkLabelStatisticsImageFilter.h" #include "ReadWriteImage.h" template int ClusterStatistics(unsigned int argc, char *argv[]) { typedef float PixelType; // const unsigned int ImageDimension = AvantsImageDimension; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; // typedef itk::ImageRegionIteratorWithIndex Iterator; typedef float InternalPixelType; typedef unsigned long ULPixelType; typedef itk::Image labelimagetype; typedef ImageType InternalImageType; typedef ImageType OutputImageType; typedef itk::ConnectedComponentImageFilter< ImageType, labelimagetype > FilterType; typedef itk::RelabelComponentImageFilter< labelimagetype, labelimagetype > RelabelType; // want the average value in each cluster as defined by the mask and the value thresh and the clust thresh std::string roimaskfn = std::string(argv[2]); std::string labelimagefn = std::string(argv[3]); std::string outname = std::string(argv[4]); float clusterthresh = atof(argv[5]); float minSize=clusterthresh; float valuethresh = atof(argv[6]); // std::cout << " Cth " << clusterthresh << " Vth " << valuethresh << std::endl; typename ImageType::Pointer valimage = NULL; typename ImageType::Pointer roiimage = NULL; typename ImageType::Pointer labelimage= NULL; ReadImage(roiimage,roimaskfn.c_str()); ReadImage(labelimage,labelimagefn.c_str()); typedef itk::MinimumMaximumImageFilter MinMaxFilterType; typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New(); minMaxFilter->SetInput( labelimage ); minMaxFilter->Update(); double min = minMaxFilter->GetMinimum(); double max = minMaxFilter->GetMaximum(); double range=max-min; for (unsigned int filecount=7; filecount < argc; filecount++) { // std::cout <<" doing " << std::string(argv[filecount]) << std::endl; ReadImage(valimage,argv[filecount]); // first, threshold the value image then get the clusters of min size typedef itk::BinaryThresholdImageFilter< ImageType,ImageType > ThresholdFilterType; typename ThresholdFilterType::Pointer threshold = ThresholdFilterType::New(); threshold->SetInput (valimage); threshold->SetInsideValue(1); threshold->SetOutsideValue(0); threshold->SetLowerThreshold(valuethresh); threshold->SetUpperThreshold(1.e9); threshold->Update(); typename ImageType::Pointer thresh=threshold->GetOutput(); typedef itk::ImageRegionIteratorWithIndex fIterator; typedef itk::ImageRegionIteratorWithIndex Iterator; fIterator tIter( thresh, thresh->GetLargestPossibleRegion() ); for( tIter.GoToBegin(); !tIter.IsAtEnd(); ++tIter ) if (roiimage->GetPixel(tIter.GetIndex()) < 0.5) tIter.Set(0); // typename typename FilterType::Pointer filter = FilterType::New(); //typename typename RelabelType::Pointer relabel = RelabelType::New(); filter->SetInput( thresh ); int fullyConnected = 0;//atoi( argv[5] ); filter->SetFullyConnected( fullyConnected ); relabel->SetInput( filter->GetOutput() ); relabel->SetMinimumObjectSize( (unsigned int) minSize ); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } typename ImageType::Pointer Clusters=MakeNewImage(valimage,0); typename ImageType::Pointer Values=MakeNewImage(valimage,0); typename ImageType::Pointer Labels=MakeNewImage(valimage,0); Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); float maximum=relabel->GetNumberOfObjects(); // std::cout << " #object " << maximum << std::endl; // float maxtstat=0; std::vector histogram((int)maximum+1); std::vector maxlabel((int)maximum+1); std::vector suminlabel((unsigned long) range+1); std::vector countinlabel((unsigned long) range+1); std::vector sumofvalues((int)maximum+1); std::vector maxvalue((int)maximum+1); for (int i=0; i<=maximum; i++) { histogram[i]=0; sumofvalues[i]=0; maxvalue[i]=0; maxlabel[i]=0; } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { float vox=valimage->GetPixel(vfIter.GetIndex()); if (vox >= valuethresh) { histogram[(unsigned long)vfIter.Get()]=histogram[(unsigned long)vfIter.Get()]+1; sumofvalues[(unsigned long)vfIter.Get()]=sumofvalues[(unsigned long)vfIter.Get()]+vox; if ( maxvalue[(unsigned long)vfIter.Get()] < vox ) { maxvalue[(unsigned long)vfIter.Get()]=vox; maxlabel[(unsigned long)vfIter.Get()]=(long int)labelimage->GetPixel(vfIter.GetIndex()); } suminlabel[(unsigned long)(labelimage->GetPixel(vfIter.GetIndex()) - min)]+=vox; countinlabel[(unsigned long)(labelimage->GetPixel(vfIter.GetIndex()) - min)]+=1; } } } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { Clusters->SetPixel( vfIter.GetIndex(), histogram[(unsigned long)vfIter.Get()] ); Values->SetPixel( vfIter.GetIndex(), sumofvalues[(unsigned long)vfIter.Get()]/(float)histogram[(unsigned int)vfIter.Get()] ); Labels->SetPixel( vfIter.GetIndex(),labelimage->GetPixel(vfIter.GetIndex())); } else { Clusters->SetPixel(vfIter.GetIndex(),0); Labels->SetPixel(vfIter.GetIndex(),0); Values->SetPixel(vfIter.GetIndex(),0); } } // WriteImage(Values,std::string("temp.nii.gz").c_str()); // WriteImage(Clusters,std::string("temp2.nii.gz").c_str()); float maximgval=0; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) > maximgval ) maximgval=Clusters->GetPixel( vfIter.GetIndex()); // std::cout << " max size " << maximgval << std::endl; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) < minSize ) { Clusters->SetPixel( vfIter.GetIndex(), 0); Values->SetPixel( vfIter.GetIndex(), 0); Labels->SetPixel( vfIter.GetIndex(), 0); } // WriteImage(Values,(outname+"values.nii.gz").c_str()); // WriteImage(Labels,(outname+"labels.nii.gz").c_str()); WriteImage(Clusters,(outname+"sizes.nii.gz").c_str()); // now begin output // std::cout << " Writing Text File " << outname << std::endl; std::string outname2=outname+std::string(".csv"); std::ofstream outf ((outname2).c_str(), std::ofstream::app); if (outf.good()) { // outf << std::string(argv[filecount]) << std::endl; for (int i=0; i < maximum+1; i++) { if ( histogram[i] >= minSize) { // outf << " Cluster " << i << " size " << histogram[i] << " average " << sumofvalues[i]/(float)histogram[i] << " max " << maxvalue[i] << " label " << maxlabel[i] << std::endl; std::cout << " Cluster " << i << " size " << histogram[i] << " average " << sumofvalues[i]/(float)histogram[i] << " max " << maxvalue[i] << " label " << maxlabel[i] << std::endl; } } for (unsigned int i=0; i <= range; i++) { // if ( countinlabel[i] > 0) { if (countinlabel[i] == 0) countinlabel[i]=1; // outf << " Label " << i+min << " average " << suminlabel[i]/(float)countinlabel[i] << std::endl; std::cout << " Label " << i+min << " average " << suminlabel[i]/(float)countinlabel[i] << std::endl; if ( i >= 0 && i < range ) { outf << suminlabel[i]/(float)countinlabel[i] << ","; } else { outf << suminlabel[i]/(float)countinlabel[i] << std::endl; } } } } else std::cout <<" File No Good! " << outname << std::endl; outf.close(); } return 0; } int main(int argc, char *argv[]) { if ( argc < 4 ) { std::cout << " Given an ROI and Label Image, find the max and average value \n in a value image where the value > some user-defined threshold \n and the cluster size is larger than some min size. \n " << std::endl; std::cout << "Usage: \n "<< std::endl; std::cout << argv[0] << " ImageDimension ROIMask.ext LabelImage.ext OutPrefix MinimumClusterSize ValueImageThreshold Image1WithValuesOfInterest.ext ... ImageNWithValuesOfInterest.ext \n \n " << std::endl; std::cout << " ROIMask.ext -- overall region of interest \n \n LabelImage.ext -- labels for the sub-regions, e.g. Brodmann or just unique labels (see LabelClustersUniquely ) \n \n OutputPrefix -- all output has this prefix \n \n MinimumClusterSize -- the minimum size of clusters of interest \n \n ValueImageThreshold -- minimum value of interest \n \n Image*WithValuesOfInterest.ext --- image(s) that define the values you want to measure \n "; return 1; } switch ( atoi(argv[1]) ) { case 2: ClusterStatistics<2>(argc,argv); break; case 3: ClusterStatistics<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ComposeMultiTransform.cxx000066400000000000000000000400311147325206600232740ustar00rootroot00000000000000#include #include #include "itkImageFileReader.h" #include "itkVector.h" #include "itkVectorImageFileReader.h" #include "itkVectorImageFileWriter.h" #include "itkImageFileWriter.h" #include "itkMatrixOffsetTransformBase.h" #include "itkTransformFactory.h" //#include "itkWarpImageMultiTransformFilter.h" #include "itkDeformationFieldFromMultiTransformFilter.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" typedef enum { INVALID_FILE = 1, AFFINE_FILE, DEFORMATION_FILE } TRAN_FILE_TYPE; typedef struct { char * filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; TRAN_FILE_TYPE CheckFileType(char *str) { std::string filename = str; std::string::size_type pos = filename.rfind("."); std::string filepre = std::string(filename, 0, pos); if (pos != std::string::npos) { std::string extension = std::string(filename, pos, filename.length() - 1); if (extension == std::string(".gz")) { pos = filepre.rfind("."); extension = std::string(filepre, pos, filepre.length() - 1); } if (extension == ".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else { return INVALID_FILE; } return AFFINE_FILE; } bool ParseInput(int argc, char **argv, char *&output_image_filename, char *&reference_image_filename, TRAN_OPT_QUEUE &opt_queue) { opt_queue.clear(); opt_queue.reserve(argc - 2); output_image_filename = argv[0]; reference_image_filename = NULL; int ind = 1; while (ind < argc) { if (strcmp(argv[ind], "-R") == 0) { ind++; if (ind >= argc) return false; reference_image_filename = argv[ind]; } else if (strcmp(argv[ind], "-i") == 0) { ind++; if (ind >= argc) return false; TRAN_OPT opt; opt.filename = argv[ind]; if (CheckFileType(opt.filename) != AFFINE_FILE) { std::cout << "file: " << opt.filename << " is not an affine .txt file. Invalid to use '-i' " << std::endl; return false; } opt.file_type = AFFINE_FILE; opt.do_affine_inv = true; opt_queue.push_back(opt); } else { TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename); opt.do_affine_inv = false; opt_queue.push_back(opt); } ind++; } // if (reference_image_filename == NULL) { // std::cout << "the reference image file (-R) must be given!!!" // << std::endl; // return false; // } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue) { const int kQueueSize = opt_queue.size(); for (int i = 0; i < kQueueSize; i++) { std::cout << "[" << i << "/" << kQueueSize << "]: "; switch (opt_queue[i].file_type) { case AFFINE_FILE: std::cout << "AFFINE"; if (opt_queue[i].do_affine_inv) std::cout << "-INV"; break; case DEFORMATION_FILE: std::cout << "FIELD"; break; default: std::cout << "Invalid Format!!!"; break; } std::cout << ": " << opt_queue[i].filename << std::endl; } } template void ComposeMultiTransform(char *output_image_filename, char *reference_image_filename, TRAN_OPT_QUEUE &opt_queue) { typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase AffineTransformType; // typedef itk::WarpImageMultiTransformFilter WarperType; typedef itk::DeformationFieldFromMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); typename ImageType::Pointer img_ref = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (reference_image_filename) { reader_img_ref->SetFileName(reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } else { std::cout << "the reference image file (-R) must be given!!!" << std::endl; return; } typename WarperType::Pointer warper = WarperType::New(); // warper->SetInput(img_mov); // warper->SetEdgePaddingValue( 0); VectorType pad; pad.Fill(0); // warper->SetEdgePaddingValue(pad); typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; const int kOptQueueSize = opt_queue.size(); for (int i = 0; i < kOptQueueSize; i++) { const TRAN_OPT &opt = opt_queue[i]; switch (opt_queue[i].file_type) { case AFFINE_FILE: { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast ((tran_reader->GetTransformList())->front().GetPointer()); if (opt_queue[i].do_affine_inv) { aff->GetInverse(aff); } // std::cout << aff << std::endl; warper->PushBackAffineTransform(aff); break; } case DEFORMATION_FILE: { typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName(opt.filename); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); // std::cout << field << std::endl; warper->PushBackDeformationFieldTransform(field); break; } default: std::cout << "Unknown file type!" << std::endl; } } warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); std::cout << "output size: " << warper->GetOutputSize() << std::endl; std::cout << "output spacing: " << warper->GetOutputSpacing() << std::endl; // warper->PrintTransformList(); warper->DetermineFirstDeformNoInterp(); warper->Update(); typename DeformationFieldType::Pointer field_output = DeformationFieldType::New(); field_output = warper->GetOutput(); std::string filePrefix = output_image_filename; std::string::size_type pos = filePrefix.rfind("."); std::string extension = std::string(filePrefix, pos, filePrefix.length() - 1); filePrefix = std::string(filePrefix, 0, pos); std::cout << "output extension is: " << extension << std::endl; if (extension != std::string(".mha")) { typedef itk::VectorImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(output_image_filename); writer->SetUseAvantsNamingConvention(true); writer->SetInput(field_output); writer->Update(); } else { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(output_image_filename); writer->SetInput(field_output); writer->Update(); } } template void ComposeMultiAffine(char *output_affine_txt, char *reference_affine_txt, TRAN_OPT_QUEUE &opt_queue) { typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; // typedef itk::DeformationFieldFromMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); // typedef itk::ImageFileReader ImageFileReaderType; // typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); // typename ImageType::Pointer img_ref = ImageType::New(); // typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); typename WarperType::Pointer warper = WarperType::New(); // warper->SetInput(img_mov); // warper->SetEdgePaddingValue( 0); VectorType pad; pad.Fill(0); // warper->SetEdgePaddingValue(pad); typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; int cnt_affine = 0; const int kOptQueueSize = opt_queue.size(); for (int i = 0; i < kOptQueueSize; i++) { const TRAN_OPT &opt = opt_queue[i]; switch (opt_queue[i].file_type) { case AFFINE_FILE: { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast ((tran_reader->GetTransformList())->front().GetPointer()); if (opt_queue[i].do_affine_inv) { aff->GetInverse(aff); } // std::cout << aff << std::endl; warper->PushBackAffineTransform(aff); cnt_affine++; break; } case DEFORMATION_FILE: { std::cout << "Compose affine only files: ignore " << opt.filename << std::endl; break; } default: std::cout << "Unknown file type!" << std::endl; } } typedef typename AffineTransformType::CenterType PointType; PointType aff_center; typename AffineTransformType::Pointer aff_ref_tmp; if (reference_affine_txt) { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(reference_affine_txt); tran_reader->Update(); aff_ref_tmp = dynamic_cast ((tran_reader->GetTransformList())->front().GetPointer()); } else { if (cnt_affine > 0) { std::cout << "the reference affine file for center is selected as the first affine!" << std::endl; aff_ref_tmp = ((warper->GetTransformList()).begin())->second.aex.aff; } else { std::cout << "No affine input is given. nothing to do ......" << std::endl; return; } } aff_center = aff_ref_tmp->GetCenter(); std::cout << "new center is : " << aff_center << std::endl; // warper->PrintTransformList(); // typename AffineTransformType::Pointer aff_output = warper->ComposeAffineOnlySequence(aff_center); typename AffineTransformType::Pointer aff_output = AffineTransformType::New(); warper->ComposeAffineOnlySequence(aff_center, aff_output); typedef itk::TransformFileWriter TranWriterType; typename TranWriterType::Pointer tran_writer = TranWriterType::New(); tran_writer->SetFileName(output_affine_txt); tran_writer->SetInput(aff_output); tran_writer->Update(); std::cout << "wrote file to : " << output_affine_txt << std::endl; } int main(int argc, char **argv) { if (argc <= 3) { std::cout << "ComposeMultiTransform ImageDimension output_field [-R reference_image] " << "{[deformation_field | [-i] affine_transform_txt ]}" << std::endl; std::cout <<" Usage has the same form as WarpImageMultiTransform " << std::endl; std::cout <<" For Example: " << std::endl; std::cout << std::endl; std::cout << argv[0] << " Dimension outwarp.nii -R template.nii ExistingWarp.nii ExistingAffine.nii " << std::endl; std::cout << " or for an inverse mapping : " << std::endl; std::cout << argv[0] << " Dimension outwarp.nii -R template.nii -i ExistingAffine.nii ExistingInverseWarp.nii " << std::endl; std::cout <<" recalling that the -i option takes the inverse of the affine mapping " << std::endl; std::cout << std::endl; std::cout << "Or: to compose multiple affine text file into one: " << std::endl; std::cout << "ComposeMultiTransform ImageDimension output_affine_txt [-R reference_affine_txt] " << "{[-i] affine_transform_txt}" << std::endl << "This will be evoked if a text file is given as the second parameter. In this case " << "reference_affine_txt is used to define the center of the output affine. " << "The default reference is the first given affine text file. " << "This ignores all non-txt files among the following parameters." << std::endl; exit(0); } TRAN_OPT_QUEUE opt_queue; // char *moving_image_filename = NULL; char *output_image_filename = NULL; char *reference_image_filename = NULL; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc - 2, argv + 2, output_image_filename, reference_image_filename, opt_queue); if (is_parsing_ok) { switch (CheckFileType(output_image_filename)) { case DEFORMATION_FILE: { if (reference_image_filename == NULL) { std::cout << "the reference image file (-R) must be given!!!" << std::endl; return false; } std::cout << "output_image_filename: " << output_image_filename << std::endl; std::cout << "reference_image_filename: "; if (reference_image_filename) std::cout << reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim) { case 2: { ComposeMultiTransform<2> (output_image_filename, reference_image_filename, opt_queue); break; } case 3: { ComposeMultiTransform<3> (output_image_filename, reference_image_filename, opt_queue); break; } } break; } case AFFINE_FILE: { std::cout << "output_affine_txt: " << output_image_filename << std::endl; std::cout << "reference_affine_txt: "; if (reference_image_filename) std::cout << reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim) { case 2: { ComposeMultiAffine<2> (output_image_filename, reference_image_filename, opt_queue); break; } case 3: { ComposeMultiAffine<3> (output_image_filename, reference_image_filename, opt_queue); break; } } break; } default: std::cout << "Unknow output file format: " << output_image_filename << std::endl; break; } } else { std::cout << "Input error!" << std::endl; } exit(0); } ants-1.9.2+svn680.dfsg/Examples/ComputeSimilarityMetric.cxx000066400000000000000000000175701147325206600236230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ComputeSimilarityMetric.cxx,v $ Language: C++ Date: $Date: 2008/09/10 19:53:13 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "ReadWriteImage.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkAvantsMutualInformationRegistrationFunction.h" #include "itkProbabilisticRegistrationFunction.h" #include "itkCrossCorrelationRegistrationFunction.h" // #include "itkLandmarkCrossCorrelationRegistrationFunction.h" template int ComputeSimilarityMetric(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::Image JointHistType; typedef itk::ImageFileWriter jhwritertype; // get command line params unsigned int argct=2; unsigned int whichmetric = atoi(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = std::string(argv[argct]); argct++; std::string logfilename=""; if (argc > argct) logfilename = std::string(argv[argct]); argct++; std::string imgfilename=""; if (argc > argct) imgfilename = std::string(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typename ImageType::Pointer image2 = NULL; ReadImage(image2, fn2.c_str()); /* typedef itk::ImageRegionIteratorWithIndex VIterator; typename FieldType::Pointer field=FieldType::New(); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->SetBufferedRegion( image1->GetLargestPossibleRegion() ); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->Allocate(); field->SetSpacing(image1->GetSpacing()); field->SetOrigin(image1->GetOrigin()); VectorType zero; zero.Fill(0); VIterator vfIter2( field, field->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType index=vfIter2.GetIndex(); vfIter2.Set(zero); } */ typename ImageType::Pointer metricimg=ImageType::New(); metricimg->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); metricimg->SetBufferedRegion( image1->GetLargestPossibleRegion() ); metricimg->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); metricimg->Allocate(); metricimg->SetSpacing(image1->GetSpacing()); metricimg->SetOrigin(image1->GetOrigin()); Iterator iter( metricimg, metricimg->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) iter.Set(0); typedef ImageType FixedImageType; typedef ImageType MovingImageType; typedef FieldType DeformationFieldType; // Choose the similarity metric typedef itk::AvantsMutualInformationRegistrationFunction MIMetricType; typedef itk::CrossCorrelationRegistrationFunction CCMetricType; //typedef itk::LandmarkCrossCorrelationRegistrationFunction MetricType; //typename typename MIMetricType::Pointer mimet=MIMetricType::New(); typename CCMetricType::Pointer ccmet=CCMetricType::New(); int nbins=32; typename CCMetricType::RadiusType hradius; typename CCMetricType::RadiusType ccradius; ccradius.Fill(4); typename MIMetricType::RadiusType miradius; miradius.Fill(0); // mimet->SetDeformationField(field); mimet->SetFixedImage(image1); mimet->SetMovingImage(image2); mimet->SetRadius(miradius); mimet->SetGradientStep(1.e2); mimet->SetNormalizeGradient(false); // ccmet->SetDeformationField(field); ccmet->SetFixedImage(image1); ccmet->SetMovingImage(image2); ccmet->SetRadius(ccradius); ccmet->SetGradientStep(1.e2); ccmet->SetNormalizeGradient(false); double metricvalue=0; std::string metricname=""; if (whichmetric == 0) { hradius=miradius; unsigned long ct = 0; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { IndexType index=iter.GetIndex(); double fval=image1->GetPixel(index); double mval=image2->GetPixel(index); metricvalue+=fabs(fval-mval); ct++; } metricvalue/=(float)ct; metricname="MSQ "; } else if (whichmetric == 1 ) // imagedifference { hradius=ccradius; ccmet->InitializeIteration(); metricvalue=ccmet->ComputeCrossCorrelation(); metricname="CC "; } else { hradius=miradius; mimet->InitializeIteration(); metricvalue=mimet->ComputeMutualInformation(); metricname="MI "; } std::cout << fn1 << " : " << fn2 << " => " << metricname << metricvalue << std::endl; if (logfilename.length() > 3 ){ std::ofstream logfile; logfile.open(logfilename.c_str(), std::ofstream::app); if (logfile.good()) { logfile << fn1 << " : " << fn2 << " => " << metricname << metricvalue << std::endl; } else std::cout << " cant open file "; logfile.close(); } if (imgfilename.length() > 3 ){ /* typename MetricType::NeighborhoodType asamIt( hradius, field,field->GetLargestPossibleRegion()); unsigned long ct = 0; double totval = 0; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType index=vfIter2.GetIndex(); double val=0; asamIt.SetLocation(index); // met->ComputeUpdate( asamIt, gd); met->ComputeMetricAtPairB(index, zero); metricimg->SetPixel(index, val); //if (ct % 10000 == 0) // std::cout << val << " index " << index << std::endl; // asamIt.SetLocation(index); // totval+=met->localProbabilistic; ct++; } std::cout << " AvantsMI : " << totval/(double)ct << " E " << met->GetEnergy() << std::endl; std::cout << " write begin " << std::endl; typedef itk::ImageFileWriter writertype; writertype::Pointer w= writertype::New(); w->SetInput(metricimg); w->SetFileName(outname.c_str()); w->Write(); // met->WriteImages(); std::cout << " write end " << std::endl; */ } return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Basic useage ex: " << std::endl; std::cout << argv[0] << " ImageDimension whichmetric image1.ext image2.ext {logfile} {outimage.ext} " << std::endl; std::cout << " outimage and logfile are optional " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: ComputeSimilarityMetric<2>(argc,argv); break; case 3: ComputeSimilarityMetric<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ConformalMapping.cxx000066400000000000000000001047161147325206600222270ustar00rootroot00000000000000 /*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: ConformalMapping.cxx,v $ Language: C++ Date: $Date: 2008/03/12 03:23:04 $ Version: $Revision: 1.15 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkBinaryThresholdImageFilter.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkMesh.h" #include "itkSphereMeshSource.h" #include "itkBinaryMask3DMeshSource.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkFEMConformalMap.h" #include "itkFEMDiscConformalMap.h" #include "BinaryImageToMeshFilter.h" #include "vtkCallbackCommand.h" #include "vtkPointPicker.h" #include "vtkCellPicker.h" #include "vtkPolyDataWriter.h" #include "vtkPolyDataReader.h" #include "ReadWriteImage.h" #include "itkRescaleIntensityImageFilter.h" #include "itkSurfaceImageCurvature.h" //#include "../BSpline/itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkPointSet.h" #include #include /* OPEN QUESTIONS: LOCAL FROM GLOBAL FOR TRIANGLE IN 3D (MARCELO) USEFUL FOR INTERPOLATING STEREOGRAPHIC COORDS INTO IMAGE. CURRENTLY JUST DENSELY INTERPOLATE ACROSS EACH TRIANGLE. -- Not necessary for triangle TRIANGLE AREA IN 3D (D0NE : USING CROSS PRODUCT ) - need to insure we use the hypotneuse as the AB edge : so theta is <= 1.0; - try to apply bcs to even out the map - what is the effect of material param E? */ template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType bkg, typename TImage::PixelType foreground, typename TImage::PixelType replaceval, typename TImage::Pointer input) { typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); float low=bkg; float high=foreground; if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } void Display(vtkUnstructuredGrid* vtkgrid, bool secondwin=false, bool delinter=true) { // Create the renderer and window stuff std::cout <<" second win " << secondwin << std::endl; vtkRenderer* ren1 = vtkRenderer::New(); vtkRenderer* ren2 = vtkRenderer::New(); vtkRenderWindow* renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren1); if (secondwin) renWin->AddRenderer(ren2); vtkRenderWindowInteractor* inter = vtkRenderWindowInteractor::New(); inter->SetRenderWindow(renWin); // vtkCellPicker* cpicker = vtkCellPicker::New(); vtkCallbackCommand *cbc = vtkCallbackCommand::New(); /*------------------------------------------------------------------------- void vtkCompositeManagerExitInteractor(vtkObject *vtkNotUsed(o), unsigned long vtkNotUsed(event), void *clientData, void *) { vtkCompositeManager *self = (vtkCompositeManager *)clientData; self->ExitInteractor(); }*/ // cbc=vectraEventHandler; //-> SetCallback(vectraEventHandler); ren1 -> AddObserver(vtkCommand::KeyPressEvent, cbc); vtkDataSetMapper* mapper = vtkDataSetMapper::New(); mapper->SetInput(vtkgrid); mapper->SetScalarRange(0,255); vtkActor* actor = vtkActor::New(); actor->SetMapper(mapper); vtkDataSetMapper* mapper2 = vtkDataSetMapper::New(); if (secondwin) mapper2->SetInput(vtkgrid); if (secondwin) mapper2->SetScalarRange(0,255); vtkActor* actor2 = vtkActor::New(); if (secondwin) actor2->SetMapper(mapper2); if (secondwin) { ren1->SetViewport(0.0, 0.0, 0.5, 1.0); ren2->SetViewport(0.5, 0.0, 1.0, 1.0); }else ren1->SetViewport(0.0, 0.0, 1.0, 1.0); if (secondwin) ren2->AddActor(actor2); // add the actor and start the render loop ren1->AddActor(actor); // this->InteractionPicker->Pick(x, y, 0.0, this->CurrentRenderer); // this->InteractionPicker->GetPickPosition(this->DownPt); renWin->Render(); inter->Start(); /* int X, Y; char keypressed = *(inter -> GetKeySym()); inter -> GetMousePosition(&X, &Y); std::cout <<" X Y " << X << " " << Y << std::endl; renWin->Render(); inter->Start();*/ /* vtkPointPicker* picker=vtkPointPicker::New(); // vtkPoints *GetPickedPositions() {return this->PickedPositions;}; float x = inter->GetEventPosition()[0]; float y = inter->GetEventPosition()[1]; float z = 0.0; picker->Pick(x,y,z,ren1); std::cout <<" picked " << (*picker->GetPickedPositions()) << std::endl;*/ mapper->Delete(); actor->Delete(); ren1->Delete(); mapper2->Delete(); actor2->Delete(); ren2->Delete(); renWin->Delete(); if (delinter) inter->Delete(); } template void MapToSphere(typename TImage::Pointer image,int fixdir, float e) { typedef TImage ImageType; typedef unsigned char PixelType; typedef itk::Mesh MeshType; typedef itk::BinaryMask3DMeshSource MeshSourceType; PixelType backgroundValue = 0; PixelType internalValue = 1; typename MeshSourceType::Pointer meshSource = MeshSourceType::New(); meshSource->SetBinaryImage( image ); meshSource->SetObjectValue( internalValue ); try { meshSource->Update(); } catch( itk::ExceptionObject & exp ) { std::cerr << "Exception thrown during Update() " << std::endl; std::cerr << exp << std::endl; return; } meshSource->GetOutput(); std::cout << meshSource->GetNumberOfNodes() << std::endl; std::cout << meshSource->GetNumberOfCells() << std::endl; typedef itk::FEMConformalMap ParamType; typename ParamType::Pointer Parameterizer=ParamType::New(); Parameterizer->SetDebug(false); // Parameterizer->SetDebug(true); Parameterizer->SetReadFromFile(false); Parameterizer->SetParameterFileName(""); Parameterizer->SetImage(image); std::cout << " fixdir " << fixdir << " e " << e << " best e ~ 3.e-3 "<SetNorthPole(fixdir); Parameterizer->SetSigma(e); Parameterizer->SetSurfaceMesh(meshSource->GetOutput()); // Parameterizer->GenerateSystemFromSurfaceMesh(); std::cout << std::endl; Parameterizer->ConformalMap(); Parameterizer->ComputeStereographicCoordinates(); int irad=50; if (Parameterizer->GetImage()) { std::cout << " writing param images " << std::endl; { Parameterizer->MapCheckerboardToImage(0.05); typename itk::ImageFileWriter::Pointer writer; writer = itk::ImageFileWriter::New(); std::string fn="checker.nii"; writer->SetFileName(fn.c_str()); writer->SetInput(Parameterizer->GetImage()); writer->Write(); } } } template typename TImage::Pointer SmoothImage( typename TImage::Pointer input,double var) { typedef TImage ImageType; typedef typename ImageType::PixelType PixelType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::Image realImageType; typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(var); filter->SetMaximumError(.01f); filter->SetUseImageSpacingOn(); filter->SetInput(input); filter->Update(); typedef itk::CastImageFilter CasterType1; typename CasterType1::Pointer caster1 = CasterType1::New(); caster1->SetInput(filter->GetOutput()); caster1->Update(); return caster1->GetOutput(); } float ComputeGenus(vtkPolyData* pd1) { vtkExtractEdges* edgeex=vtkExtractEdges::New(); edgeex->SetInput(pd1); edgeex->Update(); vtkPolyData* edg1=edgeex->GetOutput(); vtkIdType nedg=edg1->GetNumberOfCells(); vtkIdType vers = pd1->GetNumberOfPoints(); int nfac = pd1->GetNumberOfPolys(); float g = 0.5 * (2.0 - vers + nedg - nfac); std::cout << " Genus " << g << std::endl; std::cout << " face " << nfac << " edg " << nedg << " vert " << vers << std::endl; return g; } float vtkComputeTopology(vtkPolyData* pd) { // Marching cubes // std::cout << " Marching Cubes "; // vtkMarchingCubes *marchingCubes = vtkMarchingCubes::New(); // vtkContourFilter *marchingCubes = vtkContourFilter::New(); // vtkKitwareContourFilter *marchingCubes = vtkKitwareContourFilter::New(); // marchingCubes->SetInput((vtkDataSet*) vds); // marchingCubes->SetValue(0, hithresh); // int nc; // std::cout << " Input # conts "; std::cin >> nc; // marchingCubes->SetNumberOfContours(2); // marchingCubes->SetComputeScalars(false); // marchingCubes->SetComputeGradients(false); // marchingCubes->SetComputeNormals(false); vtkPolyDataConnectivityFilter* con = vtkPolyDataConnectivityFilter::New(); con->SetExtractionModeToLargestRegion(); // con->SetInput(marchingCubes->GetOutput()); con->SetInput(pd); // vtkUnstructuredGridToPolyDataFilter* gp = vtkUnstructuredGridToPolyDataFilter::New(); // gp->SetInput(con->GetOutput()); float g = ComputeGenus(con->GetOutput()); // marchingCubes->Delete(); return g; } template void GetMeshAndCurvature(typename TImage::Pointer image,float e, const char* filename) { typedef TImage ImageType; typedef vtkPolyData MeshType; double aaParm = 0.024; typedef BinaryImageToMeshFilter FilterType; typename FilterType::Pointer fltMesh = FilterType::New(); fltMesh->SetInput(image); fltMesh->SetAntiAliasMaxRMSError(aaParm); fltMesh->SetAntiAliasMaxRMSError( -1000.0 ); // to do nothing fltMesh->Update(); vtkPolyData* vtkmesh =fltMesh->GetMesh(); // assign scalars to the original surface mesh // Display((vtkUnstructuredGrid*)vtkmesh); std::cout << " Genus " << vtkComputeTopology(vtkmesh) << std::endl; typedef itk::SurfaceImageCurvature surfktype; typename surfktype::Pointer surfk=surfktype::New(); // kappa=; typedef itk::Image FloatImageType; surfk->SetInput(image); //SmoothImage(image,1.0)); surfk->SetNeighborhoodRadius( 1.5 ); surfk->SetSigma(1.); surfk->SetUseLabel(false); surfk->SetUseGeodesicNeighborhood(false); surfk->SetkSign(1.0); surfk->ComputeFrameOverDomain( 3 ); typename FloatImageType::Pointer kappa=surfk->GetFunctionImage(); typedef itk::Image itype; typedef itk::RescaleIntensityImageFilter< FloatImageType, itype > CastFilterType; typename CastFilterType::Pointer caster=CastFilterType::New(); caster->SetInput( image ); caster->SetOutputMinimum( 0 ); caster->SetOutputMaximum( 255 ); std::string fn=std::string(filename); fn=fn.substr(0,fn.length()-4)+"kappa.nii"; typedef itk::ImageFileWriter writertype; typename writertype::Pointer w= writertype::New(); typename itype::Pointer kimg=caster->GetOutput(); w->SetInput(kimg); w->SetFileName(fn.c_str()); w->Write(); typename itype::SpacingType spacing=image->GetSpacing(); vtkPoints* vtkpoints =vtkmesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); float mx=0,mn=9.e9,meank=0; for(int i =0; i < numPoints; i++) { typename ImageType::IndexType index; for (int j=0;j<3;j++) index[j]=(int)(vtkpoints->GetPoint(i)[j]/spacing[j]+0.5); float temp=kimg->GetPixel(index); // float temp=image->GetPixel(index); if (fabs(temp)>mx) mx=fabs(temp); if (fabs(temp) 0) mn=fabs(temp); meank+=fabs(temp); } std::cout <<" max kap " << mx <<" mn k " << mn << std::endl; meank/=numPoints; // mx=1.3; // mx=2.0; vtkFloatArray* param; // bool done=false; //while (!done) { param= vtkFloatArray::New(); param->SetName("angle"); float dif=(mx-mn)*0.25; float mx2=meank+dif; float mn2=meank-dif; dif=mx2-mn2; for(int i =0; i < numPoints; i++) { typename ImageType::IndexType index; for (int j=0;j<3;j++) index[j]=(int)(vtkpoints->GetPoint(i)[j]/spacing[j]+0.5); float temp=kimg->GetPixel(index); // float temp=surfk->CurvatureAtIndex(index); if (i % 1000 == 0) std::cout << " kappa " << temp << std::endl; //=fabs(manifoldIntegrator->GetGraphNode(i)->GetTotalCost()); temp=fabs(temp); param->InsertNextValue((temp-mn2)*255./dif); } vtkmesh->GetPointData()->SetScalars(param); // Display((vtkUnstructuredGrid*)vtkmesh); // std::cout<<"DOne? "; std::cin >> done; } std::cout <<" done with curvature map "; vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(vtkmesh); std::string outnm=std::string(filename); outnm=outnm.substr(0,outnm.length()-4)+".vtk"; std::cout << " writing " << outnm << std::endl; // outnm="C:\\temp\\mesh.vtk"; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); writer->Update(); std::cout << " done writing "; return; } template float GetImageTopology(typename TImage::Pointer image,float e, const char* filename) { typedef TImage ImageType; typedef vtkPolyData MeshType; double aaParm = 0.024; typedef BinaryImageToMeshFilter FilterType; typename FilterType::Pointer fltMesh = FilterType::New(); fltMesh->SetInput(image); fltMesh->SetAntiAliasMaxRMSError(aaParm); fltMesh->SetAntiAliasMaxRMSError( -1000.0 ); // to do nothing fltMesh->Update(); vtkPolyData* vtkmesh =fltMesh->GetMesh(); // assign scalars to the original surface mesh // Display((vtkUnstructuredGrid*)vtkmesh); float genus = vtkComputeTopology(vtkmesh); std::cout << " Genus " << genus << std::endl; return genus; } template void MapToDisc(vtkPolyData* vtkmesh, float e, std::string outfn) { typedef TImage ImageType; typedef vtkPolyData MeshType; typedef itk::FEMDiscConformalMap ParamType; typename ParamType::Pointer Parameterizer=ParamType::New(); Parameterizer->SetDebug(false); // Parameterizer->SetDebug(true); Parameterizer->SetReadFromFile(false); Parameterizer->SetParameterFileName(""); Parameterizer->SetSigma(e); Parameterizer->SetSurfaceMesh(vtkmesh); ComputeGenus((vtkPolyData*)Parameterizer->GetSurfaceMesh()); Parameterizer->ExtractSurfaceDisc(); ComputeGenus((vtkPolyData*)Parameterizer->GetSurfaceMesh()); // Display((vtkUnstructuredGrid*)Parameterizer->GetSurfaceMesh()); std::cout << " begin conformal mapping "; Parameterizer->ConformalMap(); std::cout << " display patch "; // ComputeGenus((vtkPolyData*)Parameterizer->m_ExtractedSurfaceMesh); //Display((vtkUnstructuredGrid*)Parameterizer->m_ExtractedSurfaceMesh); // std::cout << " display flattened patch "; int segct = 0; // float step = 0.1; // float maxt=0.0; // for (float tt = 0.0; tt<=maxt; tt=tt+step) { // std::cout <<" Building at : " << tt << std::endl; /// Parameterizer->BuildOutputMeshes(tt); // if (tt == 0.) { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(Parameterizer->m_ExtractedSurfaceMesh); std::string outnm;//=std::string(filename); //outnm=outnm.substr(0,outnm.length()-4)+".vtk"; outnm=outfn+"mapspace.vtk"; std::cout << " writing " << outnm << std::endl; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); writer->Update(); } { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(Parameterizer->m_DiskSurfaceMesh); std::string outnm; std::ostringstream buf; buf<<( segct+10 ); // outnm=outfn+std::string(buf.str().c_str())+"mapflat.vtk"; outnm=outfn+"mapflat.vtk"; std::cout << " writing " << outnm << std::endl; writer->SetFileName(outnm.c_str()); writer->SetFileTypeToBinary(); writer->Update(); segct++; } } /* for (float sig=0.4; sig<=1.0; sig=sig+0.1) { Parameterizer->SetSmooth(sig); Parameterizer->ConjugateHarmonic(); // ComputeGenus((vtkPolyData*)Parameterizer->m_DiskSurfaceMesh); Display((vtkUnstructuredGrid*)Parameterizer->m_DiskSurfaceMesh); } */ typedef typename ParamType::FlatImageType imtype; typename itk::ImageFileWriter::Pointer writer; writer = itk::ImageFileWriter::New(); std::string fn=outfn+"flat.nii"; writer->SetFileName(fn.c_str()); writer->SetInput(Parameterizer->m_FlatImage); if (Parameterizer->m_FlatImage ) writer->Write(); std::cout << " done writing "; } /* template void MeshToImage(vtkPolyData* vtkmesh, int imagesize, std::string outfn) { const unsigned int Dimension = 2; const int splineOrder = 3; const int component = 0; const char* dataname = "scalars"; typedef TImage ImageType; typedef vtkPolyData MeshType; typedef typename ImageType::PixelType PixelType; typedef typename itk::Vector FunctionalDataType; typedef typename itk::Image FunctionalImageType; int numVertices = vtkmesh->GetNumberOfPoints(); vtkmesh->GetPointData()->SetActiveScalars( dataname ); std::cout << "# of vertices " << numVertices << " Fitting variable " << vtkmesh->GetPointData()->GetScalars()->GetName( ) << std::endl; typedef itk::PointSet FunctionalMapType; typedef itk::BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typename FunctionalMapType::Pointer funcdataPoints = FunctionalMapType::New(); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); FunctionalDataType data, data1; typename FunctionalMapType::PointType point; double bounds[6]; vtkPoints *meshpoints = vtkmesh->GetPoints(); meshpoints->ComputeBounds(); meshpoints->GetBounds( bounds ); for (int ID=0; ID < numVertices; ++ID) { data[0] = vtkmesh->GetPointData()->GetScalars()->GetComponent(ID, component); for (int dir=0; dir < Dimension; ++dir) point[dir] = meshpoints->GetPoint(ID)[dir]; //Debug //data[0] = 1*point[0] + 0*point[1]; funcdataPoints->SetPointData( ID, data); funcdataPoints->SetPoint( ID, point); //std::cout << ID << " " << point[0] << " " << point[1] << " " << data[0] << std::endl; } std::cout << "Read all mesh data" << std::endl; typename FunctionalImageType::PointType origin; typename FunctionalImageType::SpacingType spacing; typename FunctionalImageType::SizeType size; float maxX, minX, maxY, minY; maxX = static_cast(bounds[1]); minX = static_cast(bounds[0]); maxY = static_cast(bounds[3]); minY = static_cast(bounds[2]); std::cout << "minX " << minX << " maxX " << maxX << " minY " << minY << " maxY " << maxY << std::endl; size[0] = imagesize; size[1] = imagesize; origin[0] = (minX + maxX)/2; origin[1] = (minY + maxY)/2; origin[0] = minX - (maxX-minX)*0.1; origin[1] = minY - (maxY-minY)*0.1; origin[0] = minX; origin[1] = minY; spacing[0] = 1.1*((((maxX-minX)>(maxY-minY))?(maxX-minX):(maxY-minY)))/imagesize; spacing[1] = spacing[0]; std::cout << "size " << size << " origin " << origin << " spacing " << spacing << std::endl; typename BSplineFilterType::ArrayType ncps; ncps.Fill( splineOrder + 1 ); //const int numLevels = round((1/static_cast(Dimension))*log(static_cast(numVertices))/log(2.0)); const int numLevels = 13; typename BSplineFilterType::ArrayType close; close.Fill( false ); std::cout << "No. of levels " << numLevels << " splineOrder " << splineOrder << " # control points " << ncps << std::endl; bspliner->SetOrigin( origin ); bspliner->SetSpacing( spacing ); bspliner->SetSize( size ); bspliner->SetGenerateOutputImage( true ); bspliner->SetNumberOfLevels( numLevels ); bspliner->SetSplineOrder( splineOrder ); bspliner->SetNumberOfControlPoints( ncps ); bspliner->SetCloseDimension( close ); bspliner->SetInput( funcdataPoints ); bspliner->DebugOn(); std::cout << "Entering BSpline" << std::endl; bspliner->Update(); std::cout << "BSpline fitting done" << std::endl; typename ImageType::Pointer outimage = ImageType::New(); outimage->SetSpacing( bspliner->GetOutput()->GetSpacing() ); outimage->SetOrigin( bspliner->GetOutput()->GetOrigin() ); outimage->SetRegions( bspliner->GetOutput()->GetLargestPossibleRegion() ); outimage->Allocate(); typename itk::ImageRegionIterator ItO( outimage, outimage->GetRequestedRegion() ); typename itk::ImageRegionConstIterator ItB( bspliner->GetOutput(), bspliner->GetOutput()->GetRequestedRegion() ); for ( ItB.GoToBegin(), ItO.GoToBegin(); !ItB.IsAtEnd(); ++ItB, ++ItO ) { ItO.Set( static_cast( ItB.Get()[0] ) ); } typename itk::ImageFileWriter::Pointer writer; writer = itk::ImageFileWriter::New(); std::string fn=outfn+"flat.nii"; writer->SetFileName(fn.c_str()); writer->SetInput( outimage ); writer->Write(); */ /*** Evaluate quality of fit ***/ /* typedef typename itk::LinearInterpolateImageFunction< ImageType, float > InterpolatorType; typename InterpolatorType::PointType testpoint; typename InterpolatorType::Pointer interp = InterpolatorType::New(); interp->SetInputImage( outimage ); for (int ID=0; ID < numVertices; ++ID) { data[0] = vtkmesh->GetPointData()->GetScalars()->GetComponent(ID, component); for (int dir=0; dir < Dimension; ++dir) { point[dir] = meshpoints->GetPoint(ID)[dir]; testpoint[dir] = point[dir] - origin[dir]; } vtkmesh->GetPointData()->GetScalars()->SetComponent(ID, component, static_cast(data[0]) - static_cast(interp->Evaluate( testpoint ))); //vtkmesh->GetPointData()->GetScalars()->SetComponent(ID, component, interp->Evaluate( testpoint )); data1[0] = vtkmesh->GetPointData()->GetScalars()->GetComponent(ID, component); cout << "error " << data1[0] << " original " << data[0] << " at " << point << " interpolated " << interp->Evaluate( testpoint ) << " at " << testpoint << endl; } vtkPolyDataWriter *vtkwriter = vtkPolyDataWriter::New(); vtkwriter->SetInput( vtkmesh ); vtkwriter->SetFileName( "newmesh3.vtk" ); vtkwriter->Write(); */ //} template typename TImage::Pointer RemoveNaNs(typename TImage::Pointer image, float replaceval ) { typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter(image,image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TImage::PixelType v1=vfIter.Get(); if (vnl_math_isnan(v1)) vfIter.Set(replaceval); } return image; } /* template void ImageToMesh(vtkPolyData* vtkmesh, typename TImage::Pointer image, std::string outfn) { const unsigned int Dimension = 2; const int splineOrder = 3; const int imagesize = 512; const int component = 0; const char* dataname = "points"; typedef TImage ImageType; typedef vtkPolyData MeshType; typedef typename ImageType::PixelType PixelType; typedef typename itk::Vector FunctionalDataType; typedef typename itk::Image FunctionalImageType; float replaceval = 5; image = RemoveNaNs(image, replaceval); int numVertices = vtkmesh->GetNumberOfPoints(); vtkmesh->GetPointData()->SetActiveScalars( dataname ); std::cout << "# of vertices " << numVertices << " Fitting variable " << vtkmesh->GetPointData()->GetScalars()->GetName( ) << std::endl; typedef itk::PointSet FunctionalMapType; typedef itk::BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typename FunctionalMapType::Pointer funcdataPoints = FunctionalMapType::New(); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); FunctionalDataType data; typename FunctionalMapType::PointType point; double bounds[6]; vtkPoints *meshpoints = vtkmesh->GetPoints(); meshpoints->ComputeBounds(); meshpoints->GetBounds( bounds ); for (int ID=0; ID < numVertices; ++ID) { data[0] = vtkmesh->GetPointData()->GetScalars()->GetComponent(ID, component); for (int dir=0; dir < Dimension; ++dir) point[dir] = meshpoints->GetPoint(ID)[dir]; //Debug //data[0] = 1*point[0] + 0*point[1]; funcdataPoints->SetPointData( ID, data); funcdataPoints->SetPoint( ID, point); //std::cout << ID << " " << point[0] << " " << point[1] << " " << data[0] << std::endl; } std::cout << "Read all mesh data" << std::endl; // Create new data array vtkFloatArray *newdata; newdata = vtkFloatArray::New(); newdata->SetName("atlas"); typename FunctionalImageType::PointType origin; typename FunctionalImageType::SpacingType spacing; typename FunctionalImageType::SizeType size; float maxX, minX, maxY, minY; maxX = static_cast(bounds[1]); minX = static_cast(bounds[0]); maxY = static_cast(bounds[3]); minY = static_cast(bounds[2]); std::cout << "minX " << minX << " maxX " << maxX << " minY " << minY << " maxY " << maxY << std::endl; size[0] = imagesize; size[1] = imagesize; origin[0] = (minX + maxX)/2; origin[1] = (minY + maxY)/2; origin[0] = minX - (maxX-minX)*0.1; origin[1] = minY - (maxY-minY)*0.1; origin[0] = minX; origin[1] = minY; spacing[0] = 1.1*((((maxX-minX)>(maxY-minY))?(maxX-minX):(maxY-minY)))/imagesize; spacing[1] = spacing[0]; std::cout << "size " << size << " origin " << origin << " spacing " << spacing << std::endl; */ /* bspline code -- not doing b-spline now typename BSplineFilterType::ArrayType ncps; ncps.Fill( splineOrder + 1 ); //const int numLevels = round((1/static_cast(Dimension))*log(static_cast(numVertices))/log(2.0)); const int numLevels = 13; typename BSplineFilterType::ArrayType close; close.Fill( false ); std::cout << "No. of levels " << numLevels << " splineOrder " << splineOrder << " # control points " << ncps << std::endl; bspliner->SetOrigin( origin ); bspliner->SetSpacing( spacing ); bspliner->SetSize( size ); bspliner->SetGenerateOutputImage( true ); bspliner->SetNumberOfLevels( numLevels ); bspliner->SetSplineOrder( splineOrder ); bspliner->SetNumberOfControlPoints( ncps ); bspliner->SetCloseDimension( close ); bspliner->SetInput( funcdataPoints ); bspliner->DebugOn(); std::cout << "Entering BSpline" << std::endl; bspliner->Update(); std::cout << "BSpline fitting done" << std::endl; typename ImageType::Pointer outimage = ImageType::New(); outimage->SetSpacing( bspliner->GetOutput()->GetSpacing() ); outimage->SetOrigin( bspliner->GetOutput()->GetOrigin() ); outimage->SetRegions( bspliner->GetOutput()->GetLargestPossibleRegion() ); outimage->Allocate(); */ /* typename itk::ImageRegionIterator ItO( image, image->GetRequestedRegion() ); // Evaluate quality of fit //typedef typename itk::LinearInterpolateImageFunction< ImageType, float > InterpolatorType; typedef typename itk::NearestNeighborInterpolateImageFunction< ImageType, float > InterpolatorType; typename InterpolatorType::PointType testpoint; typedef typename itk::ContinuousIndex< float, Dimension > ContinuousIndexType; typename InterpolatorType::Pointer interp = InterpolatorType::New(); interp->SetInputImage( image ); ContinuousIndexType contind; for (int ID=0; ID < numVertices; ++ID) { for (int dir=0; dir < Dimension; ++dir) testpoint[dir] = meshpoints->GetPoint(ID)[dir] - origin[dir]; newdata->InsertNextValue( interp->Evaluate( testpoint ) ); //vtkmesh->GetPointData()->GetScalars()->SetComponent(ID, component, (interp->Evaluate( testpoint ))); //vtkmesh->GetPointData()->GetScalars()->SetComponent(ID, component, interp->Evaluate( testpoint )); // cout << vtkmesh->GetPointData()->GetScalars()->GetComponent(ID, component) << " " << data[0] << " " << interp->Evaluate( testpoint ) << endl; } vtkmesh->GetPointData()->AddArray( newdata ); vtkPolyDataWriter *vtkwriter = vtkPolyDataWriter::New(); vtkwriter->SetInput( vtkmesh ); std::string fn=outfn+".vtk"; vtkwriter->SetFileName(fn.c_str()); vtkwriter->Write(); } */ int main(int argc, char *argv[]) { // Define the dimension of the images const unsigned int Dimension = 3; typedef float PixelType; // Declare the types of the output images typedef itk::Image ImageType; typedef itk::Image Image2DType; // Declare the type of the index,size and region to initialize images typedef itk::Index IndexType; typedef itk::Size SizeType; typedef itk::ImageRegion RegionType; typedef itk::ImageRegionIterator IteratorType; // Declare the type of the Mesh char* filename; char* refmeshname; PixelType loth=1; PixelType hith=256; int fixdir=1; float param=2.e-4; std::string outfn; std::cout << "to get mesh: ConformalMapping image.nii 1 255 1.e-3 0 outname " << std::endl; std::cout << "to flatten mesh: ConformalMapping mesh.vtk 1 2 3 4 outname " << std::endl; std::cout << "to view mesh: ConformalMapping mesh.vtk 1 2 3 1 outname " << std::endl; std::cout << "to get image topology: ConformalMapping image.nii 1 255 1.e-3 5 outname " << std::endl; std::cout << "to convert flattened mesh to image : ConformalMapping mesh.vtk 1 2 3 6 outname " << std::endl; std::cout << "to interpolate data in flattened image domain to original mesh: ConformalMapping image.nii 1 2 3 7 outname originalflatmesh.vtk" << std::endl; std::cout << " to smooth a mesh --- ConformalMapping mesh.vtk 1 2 NumSmoothIts 8 outname " <=2) { filename=argv[1]; loth=atof(argv[2]); hith=atof(argv[3]); param=atof(argv[4]); fixdir=atoi(argv[5]); outfn=std::string(argv[6]); } else { filename= (char *)"image.nii"; return 0; } if (fixdir == 0) { typedef itk::ImageFileReader< ImageType > FileSourceType; typedef ImageType::PixelType PixType; FileSourceType::Pointer readfilter = FileSourceType::New(); readfilter->SetFileName( filename ); try { readfilter->Update(); } catch( itk::ExceptionObject & e ) { std::cerr << "Exception caught during reference file reading " << std::endl; std::cerr << e << std::endl; return -1; } ImageType::Pointer image = readfilter->GetOutput(); // PixelType backgroundValue = 0; // PixelType internalValue = 255; ImageType::Pointer thresh=BinaryThreshold(loth,hith,hith,image ); // Save the mesh GetMeshAndCurvature(thresh,param,filename); // MapToSphere(thresh,fixdir,e); } else if (fixdir == 5 ) { typedef itk::ImageFileReader< ImageType > FileSourceType; typedef ImageType::PixelType PixType; FileSourceType::Pointer readfilter = FileSourceType::New(); readfilter->SetFileName( filename ); try { readfilter->Update(); } catch( itk::ExceptionObject & e ) { std::cerr << "Exception caught during reference file reading " << std::endl; std::cerr << e << std::endl; return -1; } ImageType::Pointer image = readfilter->GetOutput(); // PixelType backgroundValue = 0; // PixelType internalValue = 255; ImageType::Pointer thresh=BinaryThreshold(loth,hith,hith,image ); // Save the mesh GetImageTopology(thresh,param,filename); // MapToSphere(thresh,fixdir,e); } /*************** flat mesh to image ****************/ else if (fixdir == 6) { vtkPolyDataReader *fltReader = vtkPolyDataReader::New(); fltReader->SetFileName(filename); fltReader->Update(); //MeshToImage(fltReader->GetOutput(), 512, outfn); } /*************** flat mesh to image ****************/ else if (fixdir == 7) /*************** flat map to mesh *****************/ { refmeshname = argv[7]; vtkPolyDataReader *fltReader = vtkPolyDataReader::New(); fltReader->SetFileName(refmeshname); fltReader->Update(); typedef itk::ImageFileReader< Image2DType > FileSourceType; FileSourceType::Pointer readfilter = FileSourceType::New(); readfilter->SetFileName( filename ); readfilter->Update(); Image2DType::Pointer image = readfilter->GetOutput(); //ImageToMesh(fltReader->GetOutput(), image, outfn); } else if (fixdir == 8) /*************** flat map to mesh *****************/ { std::cout << " read " << std::string(filename) << " write " << outfn << std::endl; vtkPolyDataReader *fltReader = vtkPolyDataReader::New(); fltReader->SetFileName(filename); fltReader->Update(); vtkSmartPointer smoother = vtkSmartPointer::New(); smoother->SetInput(fltReader->GetOutput()); smoother->SetNumberOfIterations( (int) param ); smoother->BoundarySmoothingOn(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(180.0); smoother->SetEdgeAngle(180.0); smoother->SetPassBand(1.e-3); // smaller values increase smoothing smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOff(); smoother->Update(); vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput( smoother->GetOutput() ); writer->SetFileName(outfn.c_str()); writer->SetFileTypeToBinary(); writer->Update(); std::cout << " done writing "; } /*************** flat map to mesh ****************/ else { vtkPolyDataReader *fltReader = vtkPolyDataReader::New(); fltReader->SetFileName(filename); fltReader->Update(); vtkPolyData* polydata = fltReader->GetOutput(); vtkSmartPointer normalGenerator = vtkSmartPointer::New(); normalGenerator->SetInput(polydata); normalGenerator->Update(); polydata = normalGenerator->GetOutput(); if ( fixdir == 1 ) Display((vtkUnstructuredGrid*)polydata); // if ( fixdir == 1 ) Display((vtkUnstructuredGrid*)fltReader->GetOutput()); std::cout << " m_Smooth " << param << std::endl; MapToDisc(fltReader->GetOutput(),param,outfn); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ConvertImagePixelType.cxx000066400000000000000000000152711147325206600232170ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ConvertToJpg.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" template int ConvertType(int argc, char *argv[] , double MINVAL, double MAXVAL) { typedef TPIXELTYPE outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); std::cout << " Updated reader " << std::endl; typedef itk::CastImageFilter castertype; typename castertype::Pointer caster=castertype::New(); caster->SetInput(reader->GetOutput()); caster->Update(); // Rescale the image intensities so that they fall between 0 and 255 typedef itk::RescaleIntensityImageFilter FilterType; typename FilterType::Pointer fixedrescalefilter = FilterType::New(); fixedrescalefilter->SetInput(caster->GetOutput()); const double desiredMinimum = MINVAL; double desiredMaximum = MAXVAL; fixedrescalefilter->SetOutputMinimum( desiredMinimum ); fixedrescalefilter->SetOutputMaximum( desiredMaximum ); fixedrescalefilter->UpdateLargestPossibleRegion(); typedef itk::CastImageFilter castertype2; typename castertype2::Pointer caster2=castertype2::New(); caster2->SetInput(fixedrescalefilter->GetOutput()); caster2->Update(); typename OutImageType::Pointer outim = caster2->GetOutput(); typename OutImageType::SpacingType spc = outim->GetSpacing(); outim->SetSpacing(spc); std::cout << " Dire in " << reader->GetOutput()->GetDirection() << std::endl; std::cout << " Dire out " << outim->GetDirection() << std::endl; typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput(outim); writer->Update(); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " infile.nii out.ext TYPE-OPTION " << std::endl; std::cout <<" ext is the extension you want, e.g. tif. " << std::endl; std::cout << " TYPE-OPTION : TYPE " << std::endl; std::cout << " 0 : char " << std::endl; std::cout << " 1 : unsigned char " << std::endl; std::cout << " 2 : short " << std::endl; std::cout << " 3 : unsigned short " << std::endl; std::cout << " 4 : int " << std::endl; std::cout << " 5 : unsigned int " << std::endl; std::cout << " Note that some pixel types are not supported by some image formats. e.g. int is not supported by jpg. " << std::endl; std::cout << " You can easily extend this for other pixel types with a few lines of code and adding usage info. " << std::endl; std::cout <<" The image intensity will be scaled to the dynamic range of the pixel type. E.g. uchar => 0 (min), 255 (max). " << std::endl; return 1; } unsigned int typeoption=0; if ( argc > 3 ) { typeoption=atoi(argv[3]); } // Get the image dimension std::string fn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); if ( typeoption == 0 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2,char>(argc,argv, SCHAR_MIN, SCHAR_MAX ); break; case 3: ConvertType<3,char>(argc,argv, SCHAR_MIN, SCHAR_MAX ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } else if ( typeoption == 1 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2,unsigned char>(argc,argv, 0, UCHAR_MAX ); break; case 3: ConvertType<3,unsigned char>(argc,argv, 0, UCHAR_MAX ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } else if ( typeoption == 2 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2, short>(argc,argv, SHRT_MIN, SHRT_MAX); break; case 3: ConvertType<3, short>(argc,argv, SHRT_MIN, SHRT_MAX); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } else if ( typeoption == 3 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2,unsigned short>(argc,argv, 0, USHRT_MAX ); break; case 3: ConvertType<3,unsigned short>(argc,argv, 0, USHRT_MAX ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } else if ( typeoption == 4 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2,int>(argc,argv, INT_MIN, INT_MAX); break; case 3: ConvertType<3,int>(argc,argv, INT_MIN, INT_MAX); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } else if ( typeoption == 5 ) { switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2,unsigned int>(argc,argv, 0, UINT_MAX ); break; case 3: ConvertType<3,unsigned int>(argc,argv, 0, UINT_MAX ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } return 0; } ants-1.9.2+svn680.dfsg/Examples/ConvertScalarImageToRGB.cxx000066400000000000000000000221371147325206600233360ustar00rootroot00000000000000 #include #include #include #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkRGBPixel.h" #include "itkRGBAPixel.h" #include "itkRedColormapFunctor.h" #include "itkGreenColormapFunctor.h" #include "itkBlueColormapFunctor.h" #include "itkGreyColormapFunctor.h" #include "itkHotColormapFunctor.h" #include "itkCoolColormapFunctor.h" #include "itkSpringColormapFunctor.h" #include "itkSummerColormapFunctor.h" #include "itkAutumnColormapFunctor.h" #include "itkWinterColormapFunctor.h" #include "itkCopperColormapFunctor.h" #include "itkHSVColormapFunctor.h" #include "itkJetColormapFunctor.h" #include "itkCustomColormapFunctor.h" #include "itkOverUnderColormapFunctor.h" #include "itkScalarToRGBColormapImageFilter.h" template int ConvertScalarImageToRGB( int argc, char *argv[] ) { typedef unsigned int PixelType; typedef itk::RGBPixel RGBPixelType; // typedef itk::RGBAPixel RGBPixelType; typedef float RealType; typedef itk::Image ImageType; typedef itk::Image RealImageType; typedef itk::Image RGBImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->Update(); typedef itk::Image MaskImageType; typename MaskImageType::Pointer maskImage = MaskImageType::New(); typedef itk::ImageFileReader MaskReaderType; typename MaskReaderType::Pointer maskreader = MaskReaderType::New(); maskreader->SetFileName( argv[4] ); try { maskreader->Update(); maskImage = maskreader->GetOutput(); } catch(...) { maskImage = NULL; }; std::string colormapString( argv[5] ); typedef itk::ScalarToRGBColormapImageFilter RGBFilterType; typename RGBFilterType::Pointer rgbfilter = RGBFilterType::New(); rgbfilter->SetInput( reader->GetOutput() ); if ( colormapString == "red" ) { rgbfilter->SetColormap( RGBFilterType::Red ); } else if ( colormapString == "green" ) { rgbfilter->SetColormap( RGBFilterType::Green ); } else if ( colormapString == "blue" ) { rgbfilter->SetColormap( RGBFilterType::Blue ); } else if ( colormapString == "grey" ) { rgbfilter->SetColormap( RGBFilterType::Grey ); } else if ( colormapString == "cool" ) { rgbfilter->SetColormap( RGBFilterType::Cool ); } else if ( colormapString == "hot" ) { rgbfilter->SetColormap( RGBFilterType::Hot ); } else if ( colormapString == "spring" ) { rgbfilter->SetColormap( RGBFilterType::Spring ); } else if ( colormapString == "autumn" ) { rgbfilter->SetColormap( RGBFilterType::Autumn ); } else if ( colormapString == "winter" ) { rgbfilter->SetColormap( RGBFilterType::Winter ); } else if ( colormapString == "copper" ) { rgbfilter->SetColormap( RGBFilterType::Copper ); } else if ( colormapString == "summer" ) { rgbfilter->SetColormap( RGBFilterType::Summer ); } else if ( colormapString == "jet" ) { // rgbfilter->SetColormap( RGBFilterType::Jet ); typedef itk::Functor::JetColormapFunctor ColormapType; typename ColormapType::Pointer colormap = ColormapType::New(); rgbfilter->SetColormap( colormap ); } else if ( colormapString == "hsv" ) { // rgbfilter->SetColormap( RGBFilterType::HSV ); typedef itk::Functor::HSVColormapFunctor ColormapType; typename ColormapType::Pointer colormap = ColormapType::New(); rgbfilter->SetColormap( colormap ); } else if ( colormapString == "overunder" ) { rgbfilter->SetColormap( RGBFilterType::OverUnder ); } else if ( colormapString == "custom" ) { typedef itk::Functor::CustomColormapFunctor ColormapType; typename ColormapType::Pointer colormap = ColormapType::New(); std::ifstream str( argv[6] ); std::string line; // Get red values { std::getline( str, line ); std::istringstream iss( line ); float value; typename ColormapType::ChannelType channel; while ( iss >> value ) { channel.push_back( value ); } colormap->SetRedChannel( channel ); } // Get green values { std::getline( str, line ); std::istringstream iss( line ); float value; typename ColormapType::ChannelType channel; while ( iss >> value ) { channel.push_back( value ); } colormap->SetGreenChannel( channel ); } // Get blue values { std::getline( str, line ); std::istringstream iss( line ); float value; typename ColormapType::ChannelType channel; while ( iss >> value ) { channel.push_back( value ); } colormap->SetBlueChannel( channel ); } rgbfilter->SetColormap( colormap ); } if( maskImage ) { RealType maskMinimumValue = itk::NumericTraits::max(); RealType maskMaximumValue = itk::NumericTraits::NonpositiveMin(); itk::ImageRegionIterator ItM( maskImage, maskImage->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItS( reader->GetOutput(), reader->GetOutput()->GetLargestPossibleRegion() ); for( ItM.GoToBegin(), ItS.GoToBegin(); !ItM.IsAtEnd(); ++ItM, ++ItS ) { if( ItM.Get() != 0 ) { if( maskMinimumValue >= ItS.Get() ) { maskMinimumValue = ItS.Get(); } if( maskMaximumValue <= ItS.Get() ) { maskMaximumValue = ItS.Get(); } } } rgbfilter->SetUseInputImageExtremaForScaling( false ); rgbfilter->GetColormap()->SetMinimumInputValue( maskMinimumValue ); rgbfilter->GetColormap()->SetMaximumInputValue( maskMaximumValue ); } rgbfilter->GetColormap()->SetMinimumRGBComponentValue( ( argc > 9 ) ? static_cast< typename RGBPixelType::ComponentType>( atof( argv[9] ) ) : 0 ); rgbfilter->GetColormap()->SetMaximumRGBComponentValue( ( argc > 10 ) ? static_cast< typename RGBPixelType::ComponentType>( atof( argv[10] ) ) : 255 ); if( argc > 8 ) { rgbfilter->SetUseInputImageExtremaForScaling( false ); rgbfilter->GetColormap()->SetMinimumInputValue( static_cast( atof( argv[7] ) ) ); rgbfilter->GetColormap()->SetMaximumInputValue( static_cast( atof( argv[8] ) ) ); } try { rgbfilter->Update(); } catch (...) { return EXIT_FAILURE; } if( maskImage ) { itk::ImageRegionIterator ItM( maskImage, maskImage->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItC( rgbfilter->GetOutput(), rgbfilter->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItS( reader->GetOutput(), reader->GetOutput()->GetLargestPossibleRegion() ); ItM.GoToBegin(); ItC.GoToBegin(); ItS.GoToBegin(); while( !ItM.IsAtEnd() ) { if( ItM.Get() == 0 ) { RGBPixelType rgbpixel; // RealType minimumValue = rgbfilter->GetColormap()->GetMinimumInputValue(); // RealType maximumValue = rgbfilter->GetColormap()->GetMaximumInputValue(); // // RealType minimumRGBValue // = rgbfilter->GetColormap()->GetMinimumRGBComponentValue(); // RealType maximumRGBValue // = rgbfilter->GetColormap()->GetMaximumRGBComponentValue(); // // RealType ratio = ( ItS.Get() - minimumValue ) / ( maximumValue - minimumValue ); // // rgbpixel.Fill( ratio * ( maximumRGBValue - minimumRGBValue ) // + minimumRGBValue ); rgbpixel.Fill( itk::NumericTraits::Zero ); ItC.Set( rgbpixel ); } ++ItM; ++ItC; ++ItS; } } typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( rgbfilter->GetOutput() ); writer->SetFileName( argv[3] ); writer->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc < 6 ) { std::cout << "Usage: " << argv[0] << " imageDimension inputImage outputImage " << "mask colormap [customColormapFile] [minimumInput] [maximumInput] " << "[minimumRGBOutput] [maximumRGBOutput]" << std::endl; std::cout << " Possible colormaps: grey, red, green, blue, copper, jet, hsv, "; std::cout << "spring, summer, autumn, winter, hot, cool, overunder, custom" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: ConvertScalarImageToRGB<2>( argc, argv ); break; case 3: ConvertScalarImageToRGB<3>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/ConvertToJpg.cxx000066400000000000000000000075111147325206600213520ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ConvertToJpg.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" template int ConvertType(int argc, char *argv[]) { typedef unsigned char outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); std::cout << " Updated reader " << std::endl; typedef itk::CastImageFilter castertype; typename castertype::Pointer caster=castertype::New(); caster->SetInput(reader->GetOutput()); caster->Update(); // Rescale the image intensities so that they fall between 0 and 255 typedef itk::RescaleIntensityImageFilter FilterType; typename FilterType::Pointer fixedrescalefilter = FilterType::New(); fixedrescalefilter->SetInput(caster->GetOutput()); const double desiredMinimum = 0.0; const double desiredMaximum = 255.0; fixedrescalefilter->SetOutputMinimum( desiredMinimum ); fixedrescalefilter->SetOutputMaximum( desiredMaximum ); fixedrescalefilter->UpdateLargestPossibleRegion(); typedef itk::CastImageFilter castertype2; typename castertype2::Pointer caster2=castertype2::New(); caster2->SetInput(fixedrescalefilter->GetOutput()); caster2->Update(); typename OutImageType::Pointer outim = caster2->GetOutput(); typename OutImageType::SpacingType spc = outim->GetSpacing(); outim->SetSpacing(spc); std::cout << " Dire in " << reader->GetOutput()->GetDirection() << std::endl; std::cout << " Dire out " << outim->GetDirection() << std::endl; typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput(outim); writer->Update(); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: ConvertToJpg infile.nii out.jpg " << std::endl; return 1; } // Get the image dimension std::string fn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); switch ( imageIO->GetNumberOfDimensions() ) { case 2: ConvertType<2>(argc,argv); break; case 3: ConvertType<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ConvertVectorFieldToVTK.cxx000066400000000000000000000104551147325206600234260ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ConvertVectorFieldToVTK.cxx,v $ Language: C++ Date: $Date: 2009/01/27 23:25:24 $ Version: $Revision: 1.00 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkImageFileReader.h" #include "itkVectorImageFileReader.h" #include "itkVector.h" #include "itkImageRegionIteratorWithIndex.h" #include "vtkUnstructuredGrid.h" #include "vtkUnstructuredGridWriter.h" #include "vtkFloatArray.h" #include "vtkPoints.h" #include "vtkPointData.h" int main( int argc, char *argv[] ) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " inputDeformationField outputVTKFile maskImage(optional) slice(optional) whichAxis(optional)" << std::endl; exit( 1 ); } typedef float PixelType; const unsigned int ImageDimension = 3; typedef itk::Image ImageType; typedef itk::Image MaskImageType; typedef double RealType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::VectorImageFileReader ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[1] ); reader->SetUseAvantsNamingConvention( true ); reader->Update(); MaskImageType::Pointer mask = MaskImageType::New(); if ( argc >= 4 ) { typedef itk::ImageFileReader MaskReaderType; MaskReaderType::Pointer maskreader = MaskReaderType::New(); maskreader->SetFileName( argv[3] ); maskreader->Update(); mask = maskreader->GetOutput(); } else { mask->SetOrigin( reader->GetOutput()->GetOrigin() ); mask->SetSpacing( reader->GetOutput()->GetSpacing() ); mask->SetRegions( reader->GetOutput()->GetLargestPossibleRegion() ); mask->Allocate(); mask->FillBuffer( 1 ); } double origin[ImageDimension]; double spacing[ImageDimension]; int size[ImageDimension]; int totalsize = 1; for ( unsigned int i = 0; i < ImageDimension; i++ ) { origin[i] = reader->GetOutput()->GetOrigin()[i]; spacing[i] = reader->GetOutput()->GetSpacing()[i]; size[i] = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i]; if ( argc > 4 && atoi( argv[5] ) == (int) i ) { size[i] = 1; } totalsize *= size[i]; } int totalPoints = totalsize; vtkUnstructuredGrid *field = vtkUnstructuredGrid::New(); vtkPoints *points = vtkPoints::New(); points->Allocate( totalPoints ); vtkFloatArray *vectors = vtkFloatArray::New(); vectors->SetNumberOfComponents( 3 ); vectors->SetNumberOfTuples( totalPoints ); float x[3], v[3]; int offset = 0; itk::ImageRegionIteratorWithIndex It ( mask, mask->GetLargestPossibleRegion() ); for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { DeformationFieldType::IndexType idx = It.GetIndex(); if ( ( argc > 4 && idx[atoi( argv[5] )] != atoi( argv[4] ) ) || It.Get() == 0 ) { continue; } DeformationFieldType::PointType point; reader->GetOutput()->TransformIndexToPhysicalPoint( idx, point ); VectorType V = reader->GetOutput()->GetPixel( idx ); for ( unsigned int i = 0; i < ImageDimension; i++ ) { x[i] = point[i]; v[i] = V[i]; } // offset = idx[0] + idx[1]*(size[1]+1) + idx[2]*(size[1]+1)*(size[3]+1); points->InsertPoint( offset, x ); vectors->InsertTuple( offset++, v ); } field->SetPoints( points ); field->GetPointData()->SetVectors( vectors ); points->Delete(); vectors->Delete(); vtkUnstructuredGridWriter *writer = vtkUnstructuredGridWriter::New(); writer->SetInput( field ); // writer->SetFileTypeToBinary(); writer->SetFileName( argv[2] ); writer->Write(); return 0; } ants-1.9.2+svn680.dfsg/Examples/CopyImageHeaderInformation.cxx000066400000000000000000000107651147325206600241670ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: CopyImageHeaderInformation.cxx,v $ Language: C++ Date: $Date: 2009/04/30 18:32:36 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "ReadWriteImage.h" #include "TensorFunctions.h" template int CopyImageHeaderInformation(int argc, char *argv[]) { typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); // std::cout << " Spacing " << reader->GetOutput()->GetSpacing() << std::endl; //std::cout << " Origin " << reader->GetOutput()->GetOrigin() << std::endl; //std::cout << " Direction " << std::endl << reader->GetOutput()->GetDirection() << std::endl; //std::cout << " Size " << std::endl << reader->GetOutput()->GetLargestPossibleRegion().GetSize() << std::endl; bool istensor=false; if (argc >7) if (atoi(argv[7])) istensor=true; if (istensor) { typedef itk::Vector TensorType; typedef itk::Image TensorFieldType; typename TensorFieldType::Pointer timage; ReadTensorImage(timage,argv[2],false); // std::cout<< " tim dir " << timage->GetDirection() << std::endl; if (argc >6) if (atoi(argv[6])) timage->SetSpacing( reader->GetOutput()->GetSpacing() ); if (argc > 5) if (atoi(argv[5])) timage->SetOrigin( reader->GetOutput()->GetOrigin() ); if (argc > 4) if (atoi(argv[4])) timage->SetDirection( reader->GetOutput()->GetDirection() ); // std::cout<< " tim dir " << timage->GetDirection() << std::endl; WriteTensorImage( timage ,argv[3],false); return 0; } typename readertype::Pointer reader2 = readertype::New(); reader2->SetFileName(argv[2]); reader2->Update(); //MakeNewImage(typename TImage::Pointer image1, typename TImage::PixelType initval) typename ImageType::Pointer newimage = MakeNewImage(reader2->GetOutput(), -1); if (argc >6) if (atoi(argv[6])) newimage->SetSpacing( reader->GetOutput()->GetSpacing() ); if (argc > 5) if (atoi(argv[5])) newimage->SetOrigin( reader->GetOutput()->GetOrigin() ); if (argc > 4) if (atoi(argv[4])) newimage->SetDirection( reader->GetOutput()->GetDirection() ); WriteImage(newimage,argv[3]); return 1; } int main(int argc, char *argv[]) { if ( argc < 4 ) { std::cout << "Usage: " << argv[0] << " refimage.ext imagetocopyrefimageinfoto.ext imageout.ext boolcopydirection boolcopyorigin boolcopyspacing {bool-Image2-IsTensor}" << std::endl; return 1; } // Get the image dimension std::string fn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); unsigned int dim=imageIO->GetNumberOfDimensions(); switch ( dim ) { case 2: CopyImageHeaderInformation<2>(argc,argv); break; case 3: CopyImageHeaderInformation<3>(argc,argv); break; default: std::cerr << "Unsupported dimension : " << dim<< std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/CreateJacobianDeterminantImage.cxx000066400000000000000000000134551147325206600247620ustar00rootroot00000000000000#include "itkConstNeighborhoodIterator.h" #include "itkDecomposeTensorFunction.h" #include "itkImageRegionIteratorWithIndex.h" //#include "itkVectorFieldGradientImageFunction.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkNeighborhoodAlgorithm.h" #include "itkTimeProbe.h" #include "itkVariableSizeMatrix.h" #include "itkVectorImageFileReader.h" #include "itkVector.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkANTSImageRegistrationOptimizer.h" template typename TDeformationField::PixelType TransformVector(TDeformationField* field, typename TImage::IndexType index ) { enum { ImageDimension = TImage::ImageDimension }; typename TDeformationField::PixelType vec=field->GetPixel(index); typename TDeformationField::PixelType newvec; newvec.Fill(0); for (unsigned int row=0; rowGetDirection()[row][col]; return newvec; } template int CreateJacobianDeterminantImage( int argc, char *argv[] ) { typedef float RealType; typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image VectorImageType; /** * Read in vector field */ typedef itk::VectorImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->SetUseAvantsNamingConvention( true ); reader->Update(); typename VectorImageType::Pointer vecimg=reader->GetOutput(); /** smooth before finite differencing */ typedef itk::ANTSImageRegistrationOptimizer RegistrationOptimizerType; typedef typename RegistrationOptimizerType::Pointer RegistrationOptimizerPointer; RegistrationOptimizerPointer reg=RegistrationOptimizerType::New(); reg->SmoothDeformationFieldGauss(vecimg,3); typename VectorImageType::SpacingType spacing = vecimg->GetSpacing(); typename ImageType::Pointer jacobian = ImageType::New(); jacobian->SetOrigin( vecimg->GetOrigin() ); jacobian->SetSpacing( vecimg->GetSpacing() ); jacobian->SetRegions( vecimg->GetLargestPossibleRegion() ); jacobian->SetDirection( vecimg->GetDirection()); jacobian->Allocate(); itk::TimeProbe timer; timer.Start(); bool calculateLogJacobian = false; if ( argc > 4 ) { calculateLogJacobian = static_cast( atoi( argv[4] ) ); } typedef itk::ConstNeighborhoodIterator ConstNeighborhoodIteratorType; typename ConstNeighborhoodIteratorType::RadiusType radius; radius.Fill( 2 ); itk::ZeroFluxNeumannBoundaryCondition nbc; ConstNeighborhoodIteratorType bit; itk::ImageRegionIterator It; // Find the data-set boundary "faces" typename itk::NeighborhoodAlgorithm ::ImageBoundaryFacesCalculator::FaceListType faceList; typename itk::NeighborhoodAlgorithm ::ImageBoundaryFacesCalculator bC; faceList = bC( vecimg, vecimg->GetLargestPossibleRegion(), radius ); typedef itk::VariableSizeMatrix MatrixType; typedef itk::DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator ::FaceListType::iterator fit; for ( fit = faceList.begin(); fit != faceList.end(); ++fit ) { bit = ConstNeighborhoodIteratorType( radius, vecimg, *fit ); bit.OverrideBoundaryCondition( &nbc ); bit.GoToBegin(); It = itk::ImageRegionIterator( jacobian, *fit ); It.GoToBegin(); while ( !bit.IsAtEnd() ) { MatrixType J; J.SetSize( ImageDimension, ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { for( unsigned int j = 0; j < ImageDimension; j++ ) { RealType x = bit.GetCenterPixel()[j]; RealType xp1 = bit.GetNext( i )[j]; RealType xp2 = bit.GetNext( i, 2 )[j]; RealType xm1 = bit.GetPrevious( i )[j]; RealType xm2 = bit.GetPrevious( i, 2 )[j]; RealType h = 0.5; xp1 = xp1*h + x*(1.0-h); xm1 = xm1*h + x*(1.0-h); xp2 = xp2*h + xp1*(1.0-h); xp2 = xm2*h + xm1*(1.0-h); J[i][j] = ( -xp2 + 8.0*xp1 - 8.0*xm1 + xm2 ) / ( 12.0*spacing[i] ); } J[i][i] += 1.0; } try { RealType jacDet = decomposer->EvaluateDeterminant( J ); if (jacDet < 1.e-4 && calculateLogJacobian ) jacDet=1.e-4; if (vnl_math_isnan(jacDet)) jacDet=1; It.Set( ( calculateLogJacobian ? vcl_log( jacDet ) : jacDet ) ); } catch(...) { It.Set( itk::NumericTraits::max() ); } ++bit; ++It; } } timer.Stop(); // std::cout << "Elapsed time: " << timer.GetMeanTime() << std::endl; typedef itk::ImageFileWriter RealImageWriterType; typename RealImageWriterType::Pointer realwriter = RealImageWriterType::New(); realwriter->SetFileName( argv[3] ); realwriter->SetInput( jacobian ); realwriter->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " ImageDimension deformationField outputImage log-jac?(default-false)" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: CreateJacobianDeterminantImage<2>( argc, argv ); break; case 3: CreateJacobianDeterminantImage<3>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/CreateWarpedGridImage.cxx000066400000000000000000000137771147325206600231200ustar00rootroot00000000000000#include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkVectorImageFileReader.h" #include "itkVector.h" #include "itkMatrixOffsetTransformBase.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkGridImageSource.h" template TValue Convert( std::string optionString ) { TValue value; std::istringstream iss( optionString ); iss >> value; return value; } template std::vector ConvertVector( std::string optionString ) { std::vector values; std::string::size_type crosspos = optionString.find( 'x', 0 ); if ( crosspos == std::string::npos ) { values.push_back( Convert( optionString ) ); } else { std::string element = optionString.substr( 0, crosspos ) ; TValue value; std::istringstream iss( element ); iss >> value; values.push_back( value ); while ( crosspos != std::string::npos ) { std::string::size_type crossposfrom = crosspos; crosspos = optionString.find( 'x', crossposfrom + 1 ); if ( crosspos == std::string::npos ) { element = optionString.substr( crossposfrom + 1, optionString.length() ); } else { element = optionString.substr( crossposfrom + 1, crosspos ) ; } std::istringstream iss( element ); iss >> value; values.push_back( value ); } } return values; } template int CreateWarpedGridImage( int argc, char *argv[] ) { typedef float RealType; typedef itk::Image RealImageType; typedef itk::Vector VectorType; typedef itk::Image VectorImageType; /** * Read in vector field */ typedef itk::VectorImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->Update(); typedef itk::GridImageSource GridSourceType; typename GridSourceType::Pointer gridder = GridSourceType::New(); gridder->SetSpacing( reader->GetOutput()->GetSpacing() ); gridder->SetOrigin( reader->GetOutput()->GetOrigin() ); gridder->SetSize( reader->GetOutput()->GetLargestPossibleRegion().GetSize() ); typename GridSourceType::ArrayType gridSpacing; typename GridSourceType::ArrayType gridSigma; typename GridSourceType::BoolArrayType which; which.Fill( false ); for( unsigned int i = 0; i < 2; i++ ) { which[i] = true; } if( argc > 4 ) { std::vector directions = ConvertVector( std::string( argv[4] ) ); if( directions.size() != ImageDimension ) { std::cerr << "Incorrect direction size." << std::endl; return EXIT_FAILURE; } else { for ( unsigned int i = 0; i < ImageDimension; i++ ) { which[i] = static_cast( directions[i] ); } } } for ( unsigned int i = 0; i < ImageDimension; i++ ) { gridSpacing[i] = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i] *reader->GetOutput()->GetSpacing()[i]/25.0; gridSigma[i] = gridSpacing[i]/10.0; } if( argc > 5 ) { std::vector spacing = ConvertVector( std::string( argv[5] ) ); if( spacing.size() != ImageDimension ) { std::cerr << "Incorrect spacing size." << std::endl; return EXIT_FAILURE; } else { for ( unsigned int i = 0; i < ImageDimension; i++ ) { gridSpacing[i] = spacing[i]; gridSigma[i] = gridSpacing[i]/10.0; } } } if( argc > 6 ) { std::vector sigma = ConvertVector( std::string( argv[6] ) ); if( sigma.size() != ImageDimension ) { std::cerr << "Incorrect sigma size." << std::endl; return EXIT_FAILURE; } else { for ( unsigned int i = 0; i < ImageDimension; i++ ) { gridSigma[i] = sigma[i]/10.0; } } } gridder->SetGridSpacing( gridSpacing ); gridder->SetSigma( gridSigma ); gridder->SetWhichDimensions( which ); gridder->Update(); typename RealImageType::Pointer grid=gridder->GetOutput(); grid->SetDirection(reader->GetOutput()->GetDirection()); grid->SetOrigin(reader->GetOutput()->GetOrigin()); grid->SetSpacing(reader->GetOutput()->GetSpacing()); typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > TransformType; typedef itk::WarpImageMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(grid); warper->SetEdgePaddingValue( 0); warper->SetSmoothScale(1); warper->PushBackDeformationFieldTransform(reader->GetOutput()); warper->SetOutputOrigin(reader->GetOutput()->GetOrigin()); warper->SetOutputSize(reader->GetOutput()->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(reader->GetOutput()->GetSpacing()); warper->SetOutputDirection(reader->GetOutput()->GetDirection()); warper->Update(); std::string file = std::string( argv[3] ); typedef itk::ImageFileWriter ImageWriterType; typename ImageWriterType::Pointer gridWriter = ImageWriterType::New(); gridWriter->SetFileName( file.c_str() ); gridWriter->SetInput( warper->GetOutput() ); gridWriter->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc < 4 ) { std::cout << "Usage: " << argv[0] << " ImageDimension deformationField " << "outputImage [directions,e.g. 1x0x0] [gridSpacing] [gridSigma]" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: CreateWarpedGridImage<2>( argc, argv ); break; case 3: CreateWarpedGridImage<3>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/000077500000000000000000000000001147325206600213705ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/bone.txt000066400000000000000000000033061147325206600230560ustar00rootroot000000000000000.000000 0.013889 0.027778 0.041667 0.055556 0.069444 0.083333 0.097222 0.111111 0.125000 0.138889 0.152778 0.166667 0.180556 0.194444 0.208333 0.222222 0.236111 0.250000 0.263889 0.277778 0.291667 0.305556 0.319444 0.333333 0.347222 0.361111 0.375000 0.388889 0.402778 0.416667 0.430556 0.444444 0.458333 0.472222 0.486111 0.500000 0.513889 0.527778 0.541667 0.555556 0.569444 0.583333 0.597222 0.611111 0.625000 0.638889 0.652778 0.674479 0.696181 0.717882 0.739583 0.761285 0.782986 0.804688 0.826389 0.848090 0.869792 0.891493 0.913194 0.934896 0.956597 0.978299 1.000000 0.000000 0.013889 0.027778 0.041667 0.055556 0.069444 0.083333 0.097222 0.111111 0.125000 0.138889 0.152778 0.166667 0.180556 0.194444 0.208333 0.222222 0.236111 0.250000 0.263889 0.277778 0.291667 0.305556 0.319444 0.338542 0.357639 0.376736 0.395833 0.414931 0.434028 0.453125 0.472222 0.491319 0.510417 0.529514 0.548611 0.567708 0.586806 0.605903 0.625000 0.644097 0.663194 0.682292 0.701389 0.720486 0.739583 0.758681 0.777778 0.791667 0.805556 0.819444 0.833333 0.847222 0.861111 0.875000 0.888889 0.902778 0.916667 0.930556 0.944444 0.958333 0.972222 0.986111 1.000000 0.005208 0.024306 0.043403 0.062500 0.081597 0.100694 0.119792 0.138889 0.157986 0.177083 0.196181 0.215278 0.234375 0.253472 0.272569 0.291667 0.310764 0.329861 0.348958 0.368056 0.387153 0.406250 0.425347 0.444444 0.458333 0.472222 0.486111 0.500000 0.513889 0.527778 0.541667 0.555556 0.569444 0.583333 0.597222 0.611111 0.625000 0.638889 0.652778 0.666667 0.680556 0.694444 0.708333 0.722222 0.736111 0.750000 0.763889 0.777778 0.791667 0.805556 0.819444 0.833333 0.847222 0.861111 0.875000 0.888889 0.902778 0.916667 0.930556 0.944444 0.958333 0.972222 0.986111 1.000000 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/colorcube.txt000066400000000000000000000033061147325206600241100ustar00rootroot000000000000000.333333 0.333333 0.333333 0.666667 0.666667 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.333333 0.333333 0.333333 0.333333 0.666667 0.666667 0.666667 0.666667 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.333333 0.333333 0.333333 0.333333 0.666667 0.666667 0.666667 0.666667 1.000000 1.000000 1.000000 0.166667 0.333333 0.500000 0.666667 0.833333 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.142857 0.285714 0.428571 0.571429 0.714286 0.857143 1.000000 0.333333 0.666667 1.000000 0.333333 0.666667 1.000000 0.333333 0.666667 1.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 1.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 1.000000 0.000000 0.333333 0.666667 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.166667 0.333333 0.500000 0.666667 0.833333 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.142857 0.285714 0.428571 0.571429 0.714286 0.857143 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.166667 0.333333 0.500000 0.666667 0.833333 1.000000 0.000000 0.142857 0.285714 0.428571 0.571429 0.714286 0.857143 1.000000 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/cool.txt000066400000000000000000000000121147325206600230560ustar00rootroot000000000000000 1 1 0 1ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/flag.txt000066400000000000000000000006001147325206600230360ustar00rootroot000000000000001 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/lines.txt000066400000000000000000000033061147325206600232450ustar00rootroot000000000000000.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 1.000000 0.000000 0.750000 0.750000 0.250000 0.000000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 0.500000 0.000000 0.750000 0.000000 0.750000 0.250000 0.000000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 0.000000 0.000000 0.750000 0.750000 0.000000 0.250000 1.000000 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/pink.txt000066400000000000000000000033061147325206600230740ustar00rootroot000000000000000.117851 0.195857 0.250661 0.295468 0.334324 0.369112 0.400892 0.430331 0.457882 0.483867 0.508525 0.532042 0.554563 0.576204 0.597061 0.617213 0.636729 0.655663 0.674066 0.691980 0.709441 0.726483 0.743134 0.759421 0.766356 0.773229 0.780042 0.786796 0.793492 0.800132 0.806718 0.813250 0.819730 0.826160 0.832539 0.838870 0.845154 0.851392 0.857584 0.863731 0.869835 0.875897 0.881917 0.887896 0.893835 0.899735 0.905597 0.911421 0.917208 0.922958 0.928673 0.934353 0.939999 0.945611 0.951190 0.956736 0.962250 0.967733 0.973185 0.978607 0.983999 0.989361 0.994695 1.000000 0.000000 0.102869 0.145479 0.178174 0.205738 0.230022 0.251976 0.272166 0.290957 0.308607 0.325300 0.341178 0.356348 0.370899 0.384900 0.398410 0.411476 0.424139 0.436436 0.448395 0.460044 0.471405 0.482498 0.493342 0.517549 0.540674 0.562849 0.584183 0.604765 0.624669 0.643958 0.662687 0.680900 0.698638 0.715937 0.732828 0.749338 0.765493 0.781313 0.796819 0.812029 0.826960 0.841625 0.856040 0.870216 0.884164 0.897896 0.911421 0.917208 0.922958 0.928673 0.934353 0.939999 0.945611 0.951190 0.956736 0.962250 0.967733 0.973185 0.978607 0.983999 0.989361 0.994695 1.000000 0.000000 0.102869 0.145479 0.178174 0.205738 0.230022 0.251976 0.272166 0.290957 0.308607 0.325300 0.341178 0.356348 0.370899 0.384900 0.398410 0.411476 0.424139 0.436436 0.448395 0.460044 0.471405 0.482498 0.493342 0.503953 0.514344 0.524531 0.534522 0.544331 0.553966 0.563436 0.572750 0.581914 0.590937 0.599824 0.608581 0.617213 0.625727 0.634126 0.642416 0.650600 0.658682 0.666667 0.674556 0.682355 0.690066 0.697691 0.705234 0.727166 0.748455 0.769156 0.789314 0.808969 0.828159 0.846913 0.865261 0.883229 0.900837 0.918109 0.935061 0.951711 0.968075 0.984167 1.000000 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/prism.txt000066400000000000000000000033061147325206600232650ustar00rootroot000000000000001.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.666667 1.000000 1.000000 1.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.500000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 0.000000 ants-1.9.2+svn680.dfsg/Examples/CustomColormaps/vga.txt000066400000000000000000000002071147325206600227050ustar00rootroot000000000000001 0.75 1 1 0 0 0 1 0 0.5 0.5 0.5 0 0 0 0.5 1 0.75 0 1 1 1 0 0 0 0.5 0 0.5 0.5 0.5 0 0 1 0.75 0 0 0 1 1 1 0 0.5 0 0 0 0.5 0.5 0.5 ants-1.9.2+svn680.dfsg/Examples/Data/000077500000000000000000000000001147325206600171075ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Examples/Data/B1.tiff000066400000000000000000001420241147325206600202260ustar00rootroot00000000000000MM*~                                                                                                                       & "'$$          %&-7=>KSOSYUV]_XMHHI?90)#        *.7AHMVblgdkrpuzusqmaMEVokjgbYL=3"    #/ATbrztYFK_maZ^glv~yyjH4MwfnvwtoopOD4'      -?Q`o~t|j;-Sntd\XQRQFQR^`F4WvbX]fhaWOGA3* !)"'-&%+)!! 5;2.* #/20P\VaQ_mgX5)        "6Ys~{_ML=",4(/FB/''.% !*.'&6;+*" &('#>AMXq}v^N1&        4Uk}|i]=&'(&9$+,;L:#'%(0*'(#3=3"!">:872&'*;X`gkphV5            )$!"$ &-Up~aF!             .Puqa=&?"'$ *"%#  ,A5!" 1*1 %+=_e|mP/            9coD7&'2.)20( !%$)) */2$$&! ($2B%"/3iojN'               DrxL)"#'*,--,)  ,"  &'*+(! )?C5#7RkK["      !Jyc7! !$),-)%! "5=.'54357;?C<1)'(:?2#5*=6_UL        "6O`l[34540) %.599659<&&5CFA8.$*%%,694/=@BA?@DG9/0;7%&$!$7JTOOSWTNPVXSNKGA93,35*/C@/9%%+ZeS-            9bcD# 1CN@8.'(2>G`WI@<;72CEHHDABE93,)'$"%)7N_fVUW[\ZY[^WMHHJJIJ@2$0;E942ar\,             !M{}a#,>C;23.()3G]jyvfJ43AN\[\]ZTSUTRKA8/"08>BOallokgfgjlnaWH??FPWVJ9.)$"/3@R.+Fro9         &L{^% 2KXN7&'(,5CUfqtwlQ:PZ^hs}ugZSV`hYTSUW[gvmorqj^RJTTPijb|y|y|vppqrojfbXNAINMIGC>*,3,+L_= /WkR      Yvm8 =ZH1" =IW_afqzte]^dhi_YSRSYhxysmkkg^UZXUmplzx{{plnqph`[VQGIKMRWSKN/*6)$;Q0,OR:!     "JsgG!KZL3"""$4O\c^]huz}oa_hnkef_XTU]ozooutgY_YWlpq~tqt}}qhekkd^]^^SOKO[ebYTHC:&:VA -IGC%        !Gmb5+SgX-"$-HQ[\SWlz{|pdemrmehd`]_j{xz~wdRdZ[jnr{vsmjs~{sjkib_bee^YSS^ihbKX_L.%&L^;!DU?#      !EbnK-HWN3()*)&'/8X]YTa{xoloqnjegiimx~zyxn]OaV^hmvxttjchywrhabfe```\Y]eji]S]bD$"+6]U3KQA       /\cL.QXF1#.FWN>;AE^_^_o|rkijklgouwz~ysojbXPLDW_drpoiaY]pvoe`gpoh]bb^^elpla`\I7+!5WH%8RW6         =eT% .LRG3,5Dd~ybVX_X[aiusjhkorv~ysoj`SI83NTXice]ZW\oxslhnwyv_egddioqntq[KPH,+$.WN '?UQ3        HfG(RS.*Fls~r`UOVbowzopv{}}zyteN<40PTUe]_[]_fx~truvteijhhmomuovu`RX_9,+$1MO&E]K       6B-\G(96[iw~|}}kUIVfnmuurv|r~~qZ=L=DDLajhie\Xd{tqsshkgbgv|xqjhlia_eN;.2-,[D' 8D.       3=70/?K@-#BHlv~~{ynaNWchgm}vywukaVCQBIGNesw|k`Yau{y{|mprsw{xrsokha[Z^hX@3.$%7\>$.?1    WN0$GJ.-+%K[z{ofbV[adbh|rgWRREIFPPUgstwe]Xav~vrzztf\Z^`jdI100'!LO>OP       'R9&74+'E\<)Q\,      2,*eO4!/;dz~ueckmkjhehuuibZ[a[ZNIPSE+/FSXgnifeir}zvwhkbOHTdkoxq[D,%/'N^H=JS      7?j,17Hiz~i^bisrplfeqh_XOQZ^_MLTWR7?U][emlldn|~|up__YPMXgqw|vfN- .1PQ%*_/     81#4ZI(C 'DSj{jcbaprsqjiung`VYejkSV][]ELdjchnljitzx}~vka_^`bfnwztf^XA)$:')D1%EA"     $K/Rn+ST,6T_owsmcjottop~upi^aopqYaf^aIB_liotok{{sw~xjd`cnqnpxw]VbX3-N2:R:(L)      .OM`6!b.8/O}vibdiptrs}}wf\ovhdbdfe^WFcskl}vxuursn`kedmux~sad]^dE'34<'ZP!/O#     *-15n32.53:4Rwn\ptz{wvmj{|ke_`ef`YVhtpkmlfhzuqtqdcigekprx}wmcVa__hYM)J\1-50         (D*$\s&3'57:Uiyvy|dz~~~owwi^TT\_ZSYcmnha_ajqykgki_`iihuytxu`bYji`c_d(3fH4#:        /K#6tF('B67B\cseeo}{sql^POX\WOLYcb`cgip_dpupcafiqsiw{xqsztfd\rte_\hQ(#]YD+11         "<Pq#! /!UCGRhhqmknzu{tyk^\cf_VJ_eXWhqknZZcg}odelqy|r|vspkgfWSoxokfol2 & JiPC;          -*ea.32U[bdqqq}qomsul|wulmrqh^Yor\Wjsibbhjgq}hgosms~{ym]VYWUqysunrn@:yXW7!      1EuL=5DZlvjovovunmknyzggyxt{wux|xmccsxlgryuYdebbeolinojswfZUShh|xnuqqf]( &&veeE,1(         =_{84 1Egq}ghummpwuqpvuelztlsxy{siakuxx|otg`otuzicfl{q_^_Ztuvhtvwaw@*asmn&A.         7]si@"3Ysussuuspourstpqvxrs{vqg_goyqugddgwvljpw}tiqiewy~vrx~wg])+29}xjJ.)"       %Djz]8 $>evtrpprw|ysnfh~}~q{}lops~}wtogh}ols}oejc^nyxudfE$$".o|sQ2%      +TxK(+Eizxskgmz|rjdi{xyuw{{v}{j`ddhw{tv~p^eW2$X|}[;"$        0`|A"8Qjt}phn~{vrw~vxtx~wiado~tpu{{wkYYQ1 ?tcI%!      ";ltA"7Titr{rwuzq]X^gmooswzwttvu{{uni_VN:+',auhY1        "/P{h9#+Om{|u|{zvX[`FO^lpmkmq|wx|xldgg_^SH=!KflfD        #>fY-%apB'Gcsz|{xtpkoxlluykz~qoma\almhi_G'Unwl_A)(        #&Hfh9+Fav|}y}}{xuvz}vtw}~|vy~wjjfV-Gg{l`S.$&        "&3Xp\.0CYp|{yiflvweeg]/4V{k^d63/        ""&>g|P'1CVjur{jbq|{qbbe\1.IyqckG<0#        *HrD'1Lfuvnxɽ{q~srrystqihfY6$5Dvylj[A-1,    :Uzu6,2\uyú¸vgfiqijlfeaT:$6AkumacA&4+         %Sec)28g·xw{}ut{xyjZ]dbZ\]VWZTE4FdkladI)0        #,fpW6=k¸~olorkmxup^NT`WQSSJNY\V7SiiqljY61        &;4rrJ+*7lwx|ºȿŷkdpaiiwvykd__cn^P\^RYbVC/?hewb]gD '9           #+4Lny@.+=ctjl{rwzz{¿ÿpdkhczvokqzkidhg`_[bF.:         '%dlw6/*@VcXWutpxooyps{vpwyĺ{\mž»uyw~|hiw_{sjoyempigicZhC)6fm}n_bA"P,        #%&pqp1+%EO^ZVv~upomsehzwywqk{wĽq6n}rm{it}{wrogwjgWn_524Zclwdaf[5"*        +/GcjT3 :vokwz{mhx¨J#.3%4RkľsYIG9&3R~|njfir|tomqbiZn^-+-VdjxlU\c8/       .3 PZvx~J0Iytm}ukqv}mӾ|<381:?=byp]PF7+(8Wq}wliXiyyuyj[sj|Y"#Rfk{uNRf N5              ."Jo{pA$_qqx{xmjumtɱd`R3'2@CUssmZA=8,0G^xngypbqwxq}~vfkrjT&+9afwh_[8x         )!8cpxG%Kgjs}~|~|tytos~lvbA-)6H\q{ztkc^XMB38=Qux}zyveh}rsixjivwturcM')7^bitddVCe%        12Kss{{wD#>ektwrmqz}zrvzhnkri~h>/676DatxhVTM=:C7Navxtveryrvnqgbkk}yvnYC*!!1ZmZq_jNRH1      +C%Okvtsm8*A\enngdkt~mdussvfJB5,3Ljn\UF38KStyiyupyrvv|tijdrzpmdPL;'Itbp]mH[/"<      #2#C;N^yuug29DEOZ_agqznfwo~tcNABABYwkSF@BN\ssewou}d}uotshkgu}vlh\GZG$&-dbq_kIZ&/?         $J/7HT_z{}|b1?<5LqjE3=Schytqry~{gfmwkclluz}zxpiZDP=&,S`ndeST.?6       &GM2M\e~wM)A5ACGPbu{x~}{}mlwzR?2.GjjH7=Pfvyi|y^enqrhomrzptupoidZID1'&I\jh`dNAL%'        *2h7Nah|j5B4?@CPkxy}waH84CVl^OE=Bbz]jy\itsqsnt~ka_YZYPL6-?Rek]pJPT/       5>UWZ`pvq\19FAOZ\cpxwrlryxsq}wwO?@GRoiF>IUw}zqm_ay|miq|x{zuuy~~nf\Z]_^ZXH>(%UdrofY^.8A$       =KZXY\q{oV,?Nbkqpopqp{rmqvx|u~T@=COpiC;Nc}tpeewnl~{{][peefggfcbfZM0"I`txo^_5>@$       @IelH3Cc}zxoxs~}mege`cu~kkspI.$(?Xopl^^90(      7abiMW|v@"=]svq~vqkjnv|´qJADGMpsN8B\~u\\^eqjjlr}{omjcH90)>_caP^51)     7d:hWR{d. >_rsr~{slvnffq~~DZeBALPU}S=DWw|ho›TTqsozx|}xi\E=28\`^RpL2-$      =dDAgcypQ" F]Zzyoiervr}X@[}eEFLpqswihmlfWF90$4aodXZX'3.    %*WX/Ztv~{S2O^a|qnigm{ykj|¿vQJQBDhnJ?=Xs}y}|txc]aaa\RG<- "Twj]Z^2O1     #:Ag9\vtx;7TZU`XXWZgv{wyr}}x{Ź~WJRLV|cJAQizsiprluttuw|laccfe_WL;,=lg`_Z3i3%       W0lQdpsn%,8/1AMWbnv^v~tq{ʽ[AHSjwRELcwxsk|{|zvqpruwqt}yrssspjdZH8-\iefX5p,1         c.]fklwU"..6Yipqqnxo~ƶgGJ[z]ORjool~xv~|xuwyvpmosx}~unkcP=#*RyqndHe13        `IAnnl~1'&@N>]}jm~q}}÷}`Z[yƞoeh½úu\_dssqnnuzsgflmlutmmgQ; .;sje\MJ3      3_m*mmnq1#Mo_pvp}öĻufTlg`d|zorqmfemqeTZfkiu~pkmgO6*vg\V`5_1    K/d|pJ!8R]gn{|uu|~ȯwn{bgo}xyjra]ekdB]kohryh~lzXbO'#^qZ_H%t,   b{"cxr.%8Weeadsxz{}~|vuttl]c`fptvuj~flO\J0 *@nh[V&-=   ^)FBanwnMovtgfy|~{lnxt}xfTeoglwzvo|\ZFR?:/(dgbm46Y     5UPed}J\v{tp}~óqbq{vyj_btomq}rlgnRSN[F4&0UehoIaMb&      ,i Sqay(6pw}~wt~py{g||qb{}g_dnu{tg_X[NYep\63!>&8ro_cOwR=     C7d4Lm> Fdrzvuy~{rdp|~loyyqgq̟\Q>?Wddhwwtnkh\OXNB2 Nib[+PlI]9       _mFMdjG 4Q_gkZGLYbiny|wmtpBJpe}wukhiS@KJTah;fO`D     /Ux=Aht: 2XdeztYNVi|t|qdpú|WS_ux~K;kuzvroibacKGQG+H[]@l_VI#    6K{VDx3 1cnzob_nwy{nivfa}pLT}}ttxzzfNGtpe]_degka^[M,.6<\[KurLJ$      7DulBzu$;u|xvlogajmt|yrpfi}{sppkdamz}tk_Pmhuzj^bkpsvxslaE(+ldGbtMI$        8\qoNxb"@j}|{|{~wvwVUy|vurv|gSVlvwvwpinnY\r|usw~yslhN )de[`yRH<          9apfRvaAiywttwtqyma_i|rfeytois{xnkpq{~j^ar~yjWSM1&Y^W[xcVH     Nv|df`Jn}xyidfciy{wxxg_]o~xzqa]hv{xphlv}}oYPN;#J\VPhiWM     OoqIerT&Rtxlf]\\bzozupˣmkx`]\ix{~lXewss~~}}~shV2BebKTgJH"      Pdk7jk?(Ts~qZgjdu}jrskW[zykcc^_hljs{qUHTqrm_`v~zupvxzx`- 8gjMKpIJ%        3bg{<~t6-Ytvdxy~yjlq{w]bqdktncple]Qcķr]_Y\mw}|wtrlaXcfiof< #WcKF~UT)        Ah]6ze8/]sye|gou}najr\juiYjvgk{o]S\]akidgZWWZ]YMDYiicdT, K^LCVW,         Qr]3uW9 *Zm{uk}dbjdCVdUCXtjkeha]decjea_ac_UK[}}b_bF" OeTDKQ,       KiT}4u[#6gpowyrdn\ULA>RWJ=($ aq-|9]&    PqR9wP,B.Urxrzz̿ǿͻt~kkC( b7q?_$    I]9gWrHKcG^lokqyqidrvhWlŸĽȻֶx_srþ}|{y}yy}n|kK'RwIn9k      MlHqLuJSr`t{{vx~slcXQ`H?\ƽŷoputkjqsmŽyrpnkovu}hI ^`S]Bi    KrNw;}RUul{y|`VXVOJ[?KûjS[bT_pde|ʼzvslea^]`etxykL"qDkNG]     @iIv0VRnn~{\==JQQQS]ҽø¾ù[I_ifd]ail˼~ytnjie_\ZZ\_^]g^jXH, |,~GGN    2bJx0zO SksŻfF2=NQNPQ~ĿìżŽZ[wr`c_ZQgzuojffedaaceeeUN@4x$BOF   &dSu6kK!"Xjr\E?R]TNS~¾q]|di]gm]\VPDYó{vsoljgkmlnqqndUTKZLJ>&) $q;yF^D   fUb6b_1#^orzwvw|\JJ_g_ex}pdvUR]dýŭzcf]IBFDWw|wqmlmmmhotuwzxrbWafzh^O;18hapNg<   dNK1`y5!f{~rqmkortw{]KK^hjjh{~n_ms_rtleB.>FY}plfdeikmhqxyz}yqt```vig^?+=]xeOg0     `a;@r}6 !e{z|uqnkkjhilvv~jd^V]»|zpXfxkp¿ǷvZU0=GV|re\_eiovty}kQSjvu\YenQ-I;sMKb*  NWFETe=\z{{vt{t{txyz|}|{|vziUWrĽ{TZwy~ŵdQ:CGLhpbentvwuqfI+3UjrzjdipR1D:fCOb,   Bcf]FW@Hhktrps}rolfgqv|xYF]|PSw~}ÿŹtR?DBAW|tokhiXZZH18R`]epuogglL.?GgHc],  3\PG0?C6`jsxx~{scOcmt||{SWtQSrsncA?88OywhfjOVcbX\gf_]cnofcgL*;\pPmQ&   !N7>QcH-bw}|xwpXi|uxYQdkkxSD32Jumijifnumhbfruka_N%5dmM_@  XOPp{E% ![{~~xh_{fPVl}¹t\C=PuxolkiqsfbagqujYM9*Y^NW0   PhKTW@.Iqx{}x|u`s~wvz|~t\Rk|jel~uyzvyxrtqd_abdf`O>!'FIU_'  8}\`pA9?jtyzykyzk}~|t{p}mVf~nr}~|{qquniibYXYM< 0-76Uc$   ,gQj\/6jmy|~y~qw}uZpp}x~xtYh¶mp{yrnv|yvyz~x{thdWkP8! Sq0TN     !__FQm&@jxtt{}tr{~xUpnz{}ycs¹}~mnjo}{xzvmbiQ2 .`b,UD      8dI>h!% +celkq}yrutu{dWtows~}|xj|vnp]ZT`w}xzxy~ojbS( ;s`;eE     !t`?a32]Vimt}ztu{Rhzrup|ywwlf{rij_YQ[qukku~}zoqdZ& Az\Ni4     usDpw(*Jlmz{pn|l[[l~|}tsuozwzyeavyshitrjlmqv{tzk]( )\mBU[    WtH<5 +Tm}~{mflobNBi]`{u|ytv~o|nvgew·xyqjplhir|yyjICpZ1aQ     -qW=! !Yu}{vtmcahnik|x~}uvzvntmo}rjqob`nyy~}|ta+"6PI@j=    si*G-Bc}|ujfxu~{~symrvwzowwmss`]nxrv~ys_ 9>Wc     G.+gd$"1:[z}o_l{|zt~{wxwqomnzqtnİtw\Sovqvl/IR5)[P      8a:Ut7!!3Og~}nWf|zuusssxxrolmwzou}~j[lnneu!gjKBo4     tIBg! ):Wu{tuw_[nvtz{ztwurv|{wqou}`k}|z~scikrwjP-DpSALn      C~]2Y]01+ #Mp`Pd_gmlpxwz~xqtw}vuxVWtr~{z|wjkjqio`!Oip"4XR       cs6*CW %7a]MVkpml~~lepz{wt~wtgVwiln|zxrqw}}zrollsgt1NtRs-      2oX$*e|9Ba`Slns}w|w^Yn}xmx}Xh}yqohglnlpxzzqrttrpnkhS"iYro       RpSDka?+%H\W_o|{}uf\e}z}awztrkjomeemnx|xw{zrggnqjff`F *%47q?      8j`'  7I-Zl:   Q`^'!1rh+ -DR_}||fhzmkq~}ywoOFK3$=BI4/qT    2ajK:VN+":^q~ru|wZYqrskgkqngly{wtVC5,K(4U>2Q[-     MfmWS~N()Doyw{~~}vx~xlOLabgkinw{}~xtpZ: -%((2OX,   $SvbAPsmQ9+%V}noz{ywuy}}zstwniRM`j{|xsnkcD$"#93!=gB   IzjK-;ar}oC &Ctk`hrsoqt}{z{|}soswqs^Udu~zvqlhd`]\*!QM("b`    3dO9).Muz_3)Pssiiccqopzwwyuomnuwz}~wq[Zqx{{xzzwtgjf\VXWS@ #.156KW,   9\rV3#FZQ:F/ W|{xy}uuuqlkjlouys[\uzzs}vvuusokhjli_YXUP3):?+K\D   :~s]5*)@YL$@mq}y{{xwx|smpx~|xqSVtwuz}vtzuxzwrlihbdb[VRLE)+@F9.^_(      "JbzkC*?RQPK':Y]vvx||pqv}{~|sQTx{vtqpuzw|vzuqpp[[ZUOG>6)10# -CV=     +Yqk\D&4OFCmuB*+Mukr{zv}zX]~xv{zvz|zzxrmd^WOE8,%8K7 KW<      >XjeM+A3'QzlM)>Lpzmvz]cx|wwqrv~thhYG9.$*2NW38VU'   #Efo<0$#0JoQ1%#+[|s~vtt]^{}uvfadjuulXB)%/0&)+5GB/          ^[4!*CpH6ps~ytqt_[nw~rpka`ait{{wspG- " #;c_<)(/IV;          3Vsu[A,;q`1Diyprowznax{vrodZ_lq|~xs[B5(2Mts> 6JZF          %?e[+^pyB'0Ihinlwzx{|{{h\nxx~ukfgd_aio{y{}aYG4"6e4CQ@/        KywJ" Up:$%>epvlutz{tzs{{u_RIVuq}wu{qqohdf{{x}qzl]K5!GuaC!6jF            (Bd; *&StF%6@=Rjx~|swzrv~uYTMU{}|{|qjjx}|zjr|woUS. WJ!"GW9!          2Fi1'(2Dx] "Mpxrxtquv|ylQUOQvzq{wysk||y|wrjZGD5!Ak~1) 'G`=!       $Wl>%+snPC+$2Mgntxblyu|yz{yvTMeVB[np{}q}kTczmemP>  7fT-$Zc3        #dzL!VuhF $*.4Q{}yyxtxqrx||zumqxypL[gXDBiyzznvedt}lXW]N91cC/-@RR7         CK+8Wn|y<-*,*3Vitj^duyrihox~ziaisvfJmtwmLxyw}~qa`_c`YL2<4&dh-:NA*         BptN;# /gjt=#(' !$/4,/Pxz|{xx||xg^bffQRnq{P`sv}sv|p_H=EQ@&1(' C06SN2          5B\[4NSdmJ)!11$ !%1cuqd_YQOxsn\A2=I\mqmlp{bOA-!#27/6 .@PaWKJ  6^`4         :dkP/-*24\f@27>:-,3+)Ik|ue\QFLhJ85 '2977BO[cO."",?<,'XphT+-FLA     BnoS)).7S{sd281"&:A96TeryxkVIFB;9GR7"-/&C<3+ 05% ')3/P_iqZI."&2EWc[E+  !5IW`deF,)+>K[m{}|swsyty}r]UJ?3%$/G^YO>*      *?R]y^ID7   &'09BRdieaowvyzlzwl[I:,!'% *G^\J=-"    %RarthTB8  !$*44+" %+18HWQ8$    2HN[osfN@.$!  %)6BQ^SG;1  +FZ_ejfYH910/,'   $*-FKS\_YMD2)    )4ET\__^[\\XQIC@8>CB<:>CDFJPW_eibZNA5)     !/798JOVZZVSP[ae`XWaklg_VMGCA$     !)-...9<=9229A61)                                                                                                                                  vSants-1.9.2+svn680.dfsg/Examples/Data/B2.tiff000066400000000000000000001420241147325206600202270ustar00rootroot00000000000000MM*~                                                                                                                                                                                                                                       *&(07;?C>MD1044760(#           $7GTTWefda`chjj\dW@@QYW`[VVZUA-            #:HUle9&RXQB@JJ>YUE15QaZQ[djpurlUJ9&            '/CZapeTUb\LFT`]NQdgYH;0&*EUK3JZVOUeqnR5            *9PYQK;!36:J[P7-!/3-)'2%-?KFBIRUdv|gO)         +9]_\MAHF2\YG6-"#2$ #$1FVO=W^[Vh|zZ2              5?Q]`]KaiqE+E2*/(3$194,(&#'A:.H.(%%" .>B>H\MDcoaav_*%           'Ai`LHK^pgBGB'3'"-=GOVULD>87CRTaN>VCOZF=4/-*% -0;Xa]eAo^|k;             "AS`[ULXQ=G3#K:(7CEDJQUI5*--,=UY[E4D/DW[SNOLDBGE,$*+/=P\tadX3             +ZdQSNaG5>#$JS7BG@419CB97=<32;3732@#5DTOT__X]le]UA "'~@=LOlmV@$          0AJdaU_KG)0:V8+'C\rasn]covjTGG?C>?Xtsb?"X]Rnl`I0            *=R`^UZ$-3KTRX8'5LN^[grtkcfmaehaO:*$!8GVHWGZRE7/5ESMaW<47KjN?ID 2*2`cc_WF(              "4K^ln`O"!(KctQ/+)D>NP]MTQEDOSL;@R_P.09C6C*" /7.:ZN/11=NZ6&&TTYdphD                BWnvZkF3OfiB %?:7750/1:92&+0* ''    #3ES[LF?>EG;,,2^qtiP/             ^i~ew7,Gyq;0A7 &" ##      +AOfdYG>CPY+IegUI1           4ipwd#'1guT9DQ7     '0=MZWMGGHI1 #;TlkeT1           ?Papl3JK?><;2  !   0@JJ?2?@=:;<70&  .0! # 9B:/N|^+GgeG              #>nc0.:C_g6+#CU\XZelia\XQD::@@=GSWG)%@QLAHYqvwtv~qdSJIJIF?:, >MDNdh  !\wdB'              Am}f?lQhjb;2 )?FJRZ[TRYVLKBH45GSglqxylG+8LHBQpwyyx{~zpWHMZ[T\LE?+ 3]H=quA#+PuK            ?dleZ5?~R7GYG+1AHNV^^\_^PL]VUDUkmyvRH^)C[a\au~~s^MJNPPILL=3,!#N]@XcV0(CQj^A&        7[aVCDjyT*y:1 +;GS^gihjphOOirl\r{}m_jTezyquiPDEJEBFF=;7*+ +PJAbmN-'*(D``>       .H_Z&8xrXl1+b+:DP^jnprqtoZQ_p}~zbbu}wtz}rdYQJEC;831=C:4&XQLWhZ2$VjN/          >^gj`Otr[jaUDL-8?GMXekknvsryr`V}~{bYmv~ww~zrlkjaSGC736=P^ZQ= $]PThiM/#Ke\Q>        1cwdQ: FXKkUV5*H?@GTdorro|{{|ix}|\Pcuv~umqyyiXO;08M]mws_P15SZFH^Y=6GVh\.         Dmf8QpucKJJE5$6CH;:F\mqsvr~}w[Rb{{ssu|o_YA5Dfx}}xtp\$ 9F*%Ib]<.$;I;@?Meohekox~~}hOJ[wzwqx}vh_UDRwzuokTR'!*)&Jqm@(TaRJ          $Eu{=CwbOKI=-# HPOZDWC[shs~dfn|yxt\IKWz~~xxxkkbW_osw~zshWA) 3C9Gg];'?ZXK(       " =Zpb;&BpnZD7."$5Vmq}~qU`{|}}mfhnxu^LF]|~|~tvg\bqw~|wrmdQ8% *,,EH?QaU4'1Jc5       &HN2mSG7(FPfqg~xsedelzzcRD_{xypcgt}xsqssfO< 3C.;H@BenN*;d=,      7S9,d}f?;2&2LRspuvwjihkzv_RFYy|{xmmxsrsxzteY8?3%,CA[iaM5.:3-    0:~wD1ffL>:/!+4?9N{kzvnjw¼z_JFFTv}}tu|qtx{{xspS + 2AKS`iT+"&$    S\x?LzA77- 9P[P@[p|rgsĺ~^L;7FYv~|y}tx||zyyzdC =CFVnhB$ &+)     %rtA5u|R1$*6]u{mfiwn}ľtSXJ9Kfv}}|vz{|~~|ywpQ=$#/;?JgtbN316<4      7N_#(qE,8(&Mugx~|ŸmXseESovss~yuy{~rzxqyJOJ)%$/5=_ztfH=>IE*       3rX+1[rnihY9*;A&          !Xx^6)`oU1.4!Fkzrz~ů}~nqtbM\b}sl{y~yz{p{iafj]G) .3NujkrpU48P>       8{p5'D{sz)F'J-Xx»|yt{sPcn~~zuy}vqy{xqqy}wgA/@tovck_7-UZ*  V{P$=k{qp.F(J+%7]vz}`dr|~{tv~osx}so|zutY+ '3]n{\[[?$AZC         Awi1.\y|xc B+&31.>_tw~£¸z_{xy­pp{|so|tmwlH )8gvzceY,"=H#       'd\4JpwN:04Fbv|ĬһJ{ʵtrztswxo|wY'!#j}mlj>&>.       :X\FF^s}t1,$8@OcuѻzCttxŴ|xyu}uZ2! hzmjiQ1'//        81 *Nanb>,HOV_o~̻õ÷fjstίvyoSF.* [ukrmd_L0!*      =U,'7@c|\' 7[glmz}żwb}îyxRCC! 3mk^hsfYG(        Ys=2Pc{P" Rm¾Xh^xqv~v^ZH0'slcnxmbQ5      wiDHfnt~:-3dvquƷvc~w}wx~~snzZW ndaktmdVA*#    'QGUkovu-+)Qs~xd[rwĸuyzz}¾þ{xo{vu7XZ_inlf[M;.*     @XY`j}t( 9nsUit¾ȼq~~żù}uo~[-;[hppqmd^E360      &cvWnvp{b Qz{nxɸv`õ}y{xI$[puqspiiD/FE}W( T˘jRu­zos}wrqv}z}|znd*"2lp{eys^bT/6:      G8Cy}z|B"Rx{~»~ػ[@5_utynkhhox{vnx>"'NwwozpebVGO?     #S0B~-+Kj|v|Q>eΨqLEC=Qy|~ktkbcgp|yhx;#5~p|{roXGU\9      E4Fx~Y$ $:DUn||wwt|r_evjFGEV֚jIWGE7Rò~~~wuxorv{|kWw{w{blA]U7       "E4NyI :KZipo]cgqkco}ԽcJRJBSgνt`\NS?FH[rwyo@%kzskmA`P5       %@2]}4$E`putsionrvmuмdFIOMLEKvɴfDERKF1:Dtmun{sul\C($B~}qtkh?aB&        $:0m{&+QtyzjxXJQRMD?F\|špWPPIGDECKTwfqzlx|w\CDM }}uhkeBf7      ';2tl .Vyl`̥pdM@GIKMLStYEIOGEETcvǺ~~yesysrnbSKF"x}wymthHk:!       /G?vwwS8`yreij}g]DNOE:Dby~W^DPP;@SfoktvkO7#gj|uxfIlC6          7[Ts|t4Fm}r̹ZLLMKDDWmN__LJUN7_|¸~ofr{ww|jC-Le}oqePrQJ        ;ifwwKtx˵_OLTJ>SyaD@B?FU­|[[~c{lkw}yvC05feji^bX      2laFyz~&AT{{ɫ_BEPGDnoJBNHMm;deww{{~ypuxywqN& #zh{brhfY       $YV9||~$Cc~βdJNLA]~jKBJHY÷r}}ysntut{uQ*&|}rniLgR       LY7||$Jtz~qrnl͹KIQAQsdMDFLkǺźy}tvtptytiS-#lxn~q^.pS           TsNj!>pw}{iUStuvƻTKQANq`MGIV{·xn{}ulhc^P1 Rxjqp]"sJ*     /.ZgH,`{vwniz|ti[giSM?Qw^KHNb}z}|xuqh^N9 ;zuprd(h4)      0:Loj|.+!8`_i|miw|{ûwUKFX^GFNhķtj~w{lWM@1hxqmb8_-3       *JAWk~|!I("FiNGbgwƽ~QLQZ]C@Gf²qvx`MJB0RqueSE^9E      )_HSwzn\+:jOGjy{|ͼONVS]@;?bȼvny~zz|ycUPF?2B|rcEH[AK          ^YGr{[# "e6M{y{ƲNNSUe;KGVȿūŷ}~xxxkqw~zdNO]VI/ +|seZD8k@       .'QRO}|N/ &gDRt¶÷TVVXtELLXÿŭ~~xzy|mwgegkljknWJ4'/b}hl^[2n3      /`fok|\M]UXXqotºĻĢ_MSOV_GOPq{z~{mX,-%qtyW[-h#        DkH\w}@(\S_ldmůocȾÎQLSZlrNPL`žɻ~xzj@&Qxw`VMhA         -p7Hj{}z\"3&A]Nq~w|y|ơڻ÷nDHNgUKBMs̷ouv{yjQ%"1rxlV\FQ        LWrsF)%*QXQpegvۦѪR?FGoaJ>Baдu\e}tZT9"&g|s_Vc            6DT{uJOZUWvnu|ǮƧIEKFuqQDF_Ӵ|eZgzxytILB##(]voU         G-XHDpO4,"6chSJzȸɻθ^BV\sѺoKSsϻ|uw}x|y~O5PD !Axaq=;.       >vdc\|M("MsmYNĺȮvdmgлɚubrkuwu|hueVZD"8uzhn?hF1        .1@actx:-Wtj]OwƺҸtʹъpɾpfr~~vRabSE:)+\}rkF@b3      B,T^wX# )4RjjeTmľvnȻ~·nyɶttxf_WC294E~|hT'D       N2(_e>%.;Umuu^f|svŹvȷww~s}zngS;@:4xgd&S,      UFRfj}2>aw~|b_dvõuÿ~t|||}x`?<=)%fio4KG*      Z]prdra&FiyvcbW`ļzb_tǺȭyxz|}u_C#q[' :E@fw{d_oqft¿üŴzv~xzxikg[FJ8Cq{p^LbJ-   (B'~q8 555_u}~qTJ\c\iĽswyu}}sfldvkfD:; 5i~r^.c=1    &Ho8xn  =4=`rwr`G?R][g}¹õǻ~fdw~vokhYdhstUD; ,d~mZ!e66     5WOsorC2DU`dWI>CYlu{ʿŷ½űhg}~pfejoos{xzgN9" !Zzie8wDK   @F]g`suX $@*GHOYF>>FYo»ɴyuoqx~~xnI7& IvkbK|KU   $M563ju{|D"-@)OHQbMCEEK\t½̼~tz{sD6*" USUsCWNf{|bo¿ijzgn²úŗ{zv~yM7$ GmayuG;0     N?/_\]~> AR=ZHtʱ|v~ž{WY[pǸ{aD?"<`Rhx;2F   HAHyp::G5[I_p|p}dLRXmŹ~¾{{}XtsilDB" 2^rFdy?7C   D8Hzo4"2G6URek~mmƿ_MQWg½±|{`tjjKQGD"%YyJlIEJ    _AEsu}.%.UFS^tzqĽlbXT]vſźxxmODNC%R{Egr<@A    l@Dpy}x+/YYac}zķýowx]OSc®ijĿqNZB%L}Fms=FB  d5Kx|p'  :M_uda|Ůvc~zXOX\tɳþ¾giCKK~MWK  !n:Vb! &OFZxhf~tlgeyž¸w\umR^ulr¾ƿ¿ķuGO{G~DRD   #t5Gmu}|V4bIUopqlnk`RJLQrĿ|Q^aPpzǿзĹ}K RT~@RH   Jw2Wi}X!CcYUftbPIHN\j~÷ȻeUNPITikhƶû̿v\M5P]L 7spsu¾|ĪԾms|n|͸ſźpQ C%p(F1   AqNg~o)Vyÿ˰eZn{vtŸνɷ_Psfkɾ|rlwbJ D!o4[:  DwXoh~r(/i·ԟziQOemaZ_wҿƟx^^S>Dr[Lb²ztfX_\N H-KmC @x[dG|s'9tֺыNVX^icURH_w̴ƹ^ME<5?czsbFWƾĽ|{|p_Zc]P2Md:    LpFL;t%AsmGh^teigYVIpȾɼǺTEHOUVSRTZu]ǿtrrpptogu2]C}Gm3 EyC[zHy$8k{~h]oZe\lxtI~ 9Jo}t~ʼ.HFPȽĽ{bhq_lu8G@MǾrnp{~{tuxlN*1fmO=%  :_rULbh 7Ldsvo7Uwǽݳ^or^}ǶrM?=ƿkRMsSVdxtm^GB)7;Q5P%UjQt|RL/Ndpz}tvyŻjùx]mqpu|iF·xcIO:RrzmP=%;cF5Yn  >}oJQSE\$'Rgrw{q}Ƽ̽ƽyicu{tʿ~ſaKEe~c9>EMxT &dnEMqma~&E]osvzƱоɻzUhĿ|bg}{m1&VxHb3  P|TL4.&@]hek{ͺ\@jɿ·sv~|i'BӈqGc{   =i?rXa%Me`cutpƴJaʿżʱ}}e%]`Knl    ]uI<ܩB' DigerzxzoYUlij{q¾ɿ{T!ouPSz[    2zh2kTq4=lmfnqyvY:Kŵxw¾ιɫx9 %}ҭNTs@    '^{o]      E{xC8ً40"# !ctyy{{dz~hajxmYboyz}|ux}x? 3ѧm/;rJ      -fX7kѩH.&^myw~Ƶ{}okx|umxussûqoZfe*++ףrBLl/  HzcKb>.La{xwŶxcwyµ}xE\8!^-}MIZd  3mxVB`S<.Wy}}~ƹ{|}`uƾŽWTmCÁZJrg"   "[[0GevENquǾqpbvyƿ}C QdhRZ    FzbEILG Hd]gzqVTdmq¸s_zatlt·|}0/~b9S:   WlR*B- "ZYMGAEJMbʾ~VakϾ( lHBGjx|údM\wrpfnv{qoa}½~k~wyd{dBHq[    Z{cSnU6siM8N~~~nUY\f|~}{vzzrP=]q{~zjghp|0*իwZCV|M      KzoLLoО)Ju[-Hv|vb\[rodq|~r}fNvpf]arO !Z,s`8Fux<    +exS>Z])$qtAB]u`BNcogevxnZ`tƽwhcm[ &z_q])Rc'     NiCV}JHQu`AHevļű|SVlpvuW^z|jcjtxeX*L^ƈZ1e|F        BvCJnuB"Wh=?]Umɸòdf}bdqXv˼ÿĽmWRY^K {)ߘ<3qk2       ,jU=_ݦh#"<+AKH9RnŻ»p}qjxyu{ĿjXSF( >dFŽp*\ra      SjB?L崠Q/8,5JFKeÿwg[iy~ǿ¾\C9-'/ 5zo]6g}I     @z|M'+ȁ5D%#CIký¼ø{y|mWQhʾ_4'4"+Tz`ºuw?Grx)        2c{Z(AŞk ./Izɾcor_RY{ǰ¼|y~vR&6`UaŮ[U,]{U          Fui8K\#$DtĹȺZatsdiɳuryxe7)G`oN99v|(        4t~R>9O<.$!?sƳ˷»[gyvé»pjlwa" A=T`A5X{f      "fkB1Csd%5uĹ_x|pĽpmlqzsB!4DkX2     L{vW3\} 4%nȶa~|qNyz{~K3%`w\l;2+Sl.      $[tHNtrܝZ)7 LhzVdx|W)  4Wlm]C/;Nr\       GaL^eȇ/O v\}iV»p- HxxL39Pjd0       )]S>JbηQF!NuqOm}ciǼ~qzD  !Djh7/TpqA        /fzY-/MxK2  Zp~źuvMobuunyD Bs|cL4=iK       (G^J0;Wma G|ponM|piǹ}tmu~qO ftL27YiQ         +R{s81^{k!Ikj{wy}vum]PKHE@ebOSuqtrq{k`dR) .]s~5;TlW      8ngD+:DɡU  &&TsewpfdIHlwKN{{{yvx~w_]N0!Rzu@#Dmf6    ?sz`5(ʖjnI'&)`wrlm{wrsVBqOI~{}w{~tl_2:\|jf;8Jhg?   R|R#0VY%(/[t{x|xzzVKxYO}s~pq|}dA$8`kJA*AcqV&      "TwZN4X{^>/Tx{xIZu~_Vtn_m}E"#!4fs}I+-6Ztd8     $Wzc.0Je|>!#$-EiwA\queMwyukzhfszK&:uzd6&+An~Q   %L}U3%AT}~H%%(Gr=Z|uIURw^~ygm}xK#Fm^1.CIjoX'   XwwT01,LM,**d||yui?`XZLhoi[D$EtX.B*Mlp}?&!2Sq{xtq|oYXux~omutrwxzKC.'+jyo:$Ozp>         %JfnkF!&?vkO-" .KdbYl{ojhqxj\]_zr`rqwvzmlPa?+,JiwlWcA00IeiD        =ekH(%;O|g3+&% 7IMgzdZg{snrb`iovxp~psquxW?%/(()5dhbT8,&1Ryt:         A^zV<,[Wkq3&3* .MonfyhC6P\cfyxmd^}{dpw]6$&$8v`HE7!.[xsO            &Prqg3*1^Oq>& .=FD[N*,BO__[KEOVOHI>6(!&)!.NqZCE$+Cak`Q&      ?q|fX0BXM>N+!!! *        -OoUB-+=OOEkG%")&!AeyziM9* 4NHEiyoqg7CN0(106+""%#! ,Ux=.8F\mkR+      Ns}ygG.*8E9Ko`;*&$!0@Zl_kvb__a]F2267=ASNHV\UY[&)  ,$ #, $Wd0 2(SjmhO-     9ZtqJ.).%*8Qovd>'!!783DF52-*.#&$0'/)"/AFWufE."/>ig@     2ZpnX9"%)#(PvjI.  '$$)!./%-,;)  -4>WsuT49.0TsjN/        <]k\F1# %1Wm^A0( #*72&+  )'45/@=KP\imls|pgO-5((C $.#!17-6/'/Pt}sT9#           %B`qlVC61*$!"&)(,$.+!-(DH%+A2&&   !#+')%;B8HQ^lshJ/        -H^kp_`R:.12-*" !("71!&()-&276D^mmvwnU7     #6CYntc[a]M1J;##0 !,0*.:'/<9BGAHJKT`TT`\_e]gpook\D0%     !)9ILdhlf_eYP]QIYZT_ad`VUamrmch]TWNRTH;0"         5AE\cenaU]YNTJMD42AKJF5:.!'""          /5#,)$**$%                                                                                                                                                                                                                  vSants-1.9.2+svn680.dfsg/Examples/Data/B3.tiff000066400000000000000000001420241147325206600202300ustar00rootroot00000000000000MM*~                                                                                                                                                                                                                                                                                                                                                                           $##!.DI:3:A<4/*%                      &!+:GNXizqixpgv|~{lb\J@=-              ";WjxwwaGOlrihP-+BCK[r{}|}lWSD5!             +?Tfvs\TU> -T0,2<7/;S>?BLZforeedo~rZ:!                  *9DUm|}thaI3), +/4:=;644.+& "+2@>8KME27;70-17'%";-MgtWJ0                2VzgP:8(&,23,BaadTIMUFZLKW:K^0B=34<=4-*#.18Qh}F'*                   ,God:82&0%;AGXXMFM[^M6';&9)"3*/GLRE`iUDFE<5&*,-Bu[-            "!BnhB32,71@DYZjd]EHKbskukxpjvX\MMnybWdfWZQN9./$&.Dls;              !;YvQ.%6HXdRX[dUce\@DOcxXsxfVEP7$(OO$              /XzqQ-6>?DQakxh>4.;28 (&-[q\}h92 "#&0;Paj}tcGNYW@%!:Yt>                 !4\|Q&;CJMOPLGSA'(*'%   %KQxqa[:!+*$$*,.62KVKJ9Ye[NL?3;Oh2#               !+8:\n5'BN]eXB4122& + +<3(  $ '.. 24@K?FicA83>es6"                 (QgwH1@>ThZS:)$%(4&)/ % +$ !($ &#+RFUR(5NQpP(           4ce^EW>mcQ?4'19:>A5=F45#(  !!9E;GNHA9' &4*,Rkd.<@4[o_&         $3Uxf^I6a82"   0>CCFKC@EFZfX_GD"('AWigmng_T@,,*)**#  %BE?3)# (#'QcG=JOuR&         0`pCEHmV%# $DTjrrodSHNZddqyz`XI9 #=[m!         4l{30/tn@31 (-^Rb|}~QHMixxtstqf[T;?Ut{w~i\cx{vgVLFBG:*/BIIR\nY#[zb#           7XV=*jeL=:(?PYkyl\Vcu|ogkohZPIDNfwz~xlpu~ohi`QSQ?4>HLSXys?*YO&       (QcM'4xdK!// )AX_S{plwrfinfVLMAASivpkz}}}mmyufXYK<82-2T_kqS#clL     KWBIdZ<3 04^lVy~}uuzrttfWPG=>Rk{ml~ngrtj_ZMD:#EFMekA$5aoM    RpV+'PSc&,Tj__exlrtz~{iXSJ@:#5\w^EHjjmu~kj|}z{dWOBMB>Ymnrot{t[Uk|{xx~ybQ@+&)#,-/?rZ))CH            6ttU@leLR8*&Ahd`Y]q|}vqz~saZSEJEMk~{vrqqzu_YlzzjWJ8'%"?EQqQ :-         [y6NWF=dP9@Ufaounmz{w|s~qe_TLKJVo~}xtplrsdbu~wn^P?3#'?J-&b3""H$     @X!*a2NfJ0(Xn}|ypjsqq}pm}oh`OK@"           Po;awR(P=8Z]Ziw~zyykhiymbZ\jznjl`B-#$6,awhkJ41         .ug!8xy8%8: A7          5JIejy\%#"/RvĶris|qwwuw|~tj@TzuxyfZ(M6       E<4_{}Y&0Cfr90RvŸxmĻƮǾȺ~H6 L}{|ocR.?5        !3#Tv{?"CtɜyƵǻȿô`8;{{tl^#99I*      6&W{x:!Q͞Ċź¹o?" &i~z}}xkLSIhO'      $G'+Uzj.$]ľĭkb24#UuzsbHP`_4      '2L0Ig[(6qúϾҬǴñ¶gY#$*U~vm8^ToH      1BA7\L#E޹Dzг~y¶vl;'?v{zvFfZ~e-        >[;CjD!H·ĸԥͬѫ|º|{Z$wu~p\DNab?       MwBUzG$IƻӾЭus\+Tu}{sw$ED[Q      \`YUkz{yn4!>vߪjgʮ»{J ?~}tsLZVY\-          %kwo]w|]$DxӿϾҨg=?oqG  6~WH`Xa<      Fh]XHlGIz«ƺ{ʺҲxKC:lѳ³{lI" "j|p^-VDPC       GD'?Ro7Duİų|~{DZl{ԠoOEKFtЩ¼ƿwkM&Txy|sq9YNNY*       LO&Hrwf.8h˹}wϿyf̩kG@@BR}ȬĿvlQ'I}tlN^rX_8        9eISx|ng(/\ʽĴռȣjECHLW̷xa3=}p[Z]hVI#         FXe`~{~sg&4Y}ÿ³Űػj;6N]kžпsH$,ls|}jkW{YY/          OHvbd~d'#>]u˻ľٿʣqOHARr}Ĩ|{S+"\}r~{}wi;esQd8         Kpduhj}T"$:eÿƵÿwe`ƦrN?=XkĽvvwx{xN)^wk]>:XHe@         Kv{hzop@5cŻg>WchSDEMqĿnó}zrr{W++!Gyy|pjO;D/`L    (P\gxkg@% 3e̻ǷˬQ<:WjCD?Nmuzknv[-3,6k}q}zqvfJC:RU+     Xû{rrXJN5)/9+Sy|nfbA5^NjM       CokCrbdZ+9#,cƿɷ]EJbTF?g}xcXT7-0 =xux}qcfE0gWmZ      %N~oYjoL^S0,)TpŽýâoKCg\UDyDZǼynW5%*%2lxzwubrY=ybmf#      3_}qmknNmzB)%*I_vȻ{ür_OxSMADz°}{qR3#)63`qv]taA~ors2    Gicx?ukr`hV1$8Wcֹyw|GEuhBQ˾{vy»{iG)!(152Dzc`e[vrcu8      PhSl6qcaYq^6++%L[nȤwxŶƽOFyhG^տqnzpY<()#Ay|{d_gcxayF      /]h|NfKFp^S*07[]yҳ|ټĹRB}eGeҹxp~h\M "#]ip0       Eyb5{JTh%#WjY}tw~ͮ¾]IY`bz÷bI[O=H           "y@^{1|wRx{0)>"5pTVWo|͹˽ÿ˸xs׬nXqƷvz|{snYC14?Wz|hldN@?O      %RNg}m&"(SiKS]|ᵦɺ̳~ӻv~̾y]"%'-}yzvniVNy>wd8       (V>vnN #3p]T\fӣwƼԿ{¸ŹDzcB$=Ux{toXdVCc|A       &jQM;q`MY[d\]xټȾƾĸySV:*3z~v{vrZk;\I~;     )\iZE{nz 4^5Q\Zbӽ|ںſ˴ĵ~MOD(pwx|xhe49m>#         #LW+lED_6PE\wǻڿºǸöҹfGAO406R~wuc:?dW1         2P,hp(U^Ke9[¬|n¸¿ĪǷϱƶm=B=[M' -pntiBgNhr2        jFH\{|^" :eWsdlcrϹ~жŸλDZz~lZNI38[@c!")OphzmhpN[      L{TCi 6S=rt|isʵɻƼƵzeWPK?6>HhB( 31u~~qj>Nb%       (kG*p BFN{qbéüϾȼü~}nie__I.GSG >kv{vjQ?rs?     l-vV%B%TkyɽȞ~fjt~|q`M-8BN1 +Vys|rqE=o{Q    !t!) RpTƜoa{Ⱦƿ÷ѣyfrymYF7P_O#36wxj2Nqq[     9s"0~ $sZcxľ½ȹʴDž~~c^FkjV.`nHgk`      Ug@tMxj 4fednȾÚyt{nTa[xl[ =tsw:Zrf  g[o]nxI>]ŵstwž³ƿŷyz|xybqtqVJ))vrd)z?Uzk$       4b(0w0 Y似ÿmxǾ¼˾ͨ{_^ͦ|xGP # qyr"\Yyg<       L[.(|u~! #j¼gĿɹ϶_cedl eywv3^U~i?       gSK)ry\6t¾p˴ʺºĺĶl7WwyB~`L~oC      *vHu?wE;vǽİoW%EyUzV{O     =9^6=zпųx~ɽǵ»ļɤb'2m{{P[xW'       T+ps)8vǻjuռĿ·Ÿľ­d*)&cqvG`s|S#       gz*Kyz2jilýwnŻþżt~¸}i0*\Drb~xP      po/5xp~0bzwrfflsijҷǍsϾ»ĽŸln`xýn1  V}&y]5EpX(      *sS9%suc(>crwvmehwƷòdϸz}ƻzd+ LrGdW&>mwd!    6bE.tsVDl|~wulflopommqzĴùhO\°õ~`= N|}=}g[czg%        LqR7rvNNx|}||κrSLCk̾ʶ~{}g[I/$Qx@f[h{j)    OcGAo~R blf}̻ã]Z\OYZվz̺vzr~wT[B$PGJPp{l+   [eOZoV-zqhºoy]ZjXdz³ʲ|r{vi`6 K~zJ_Xixk,      hs^}rVBɿwKQx{¼Űٯǹ~d0+!E}~V`\iwk-       coOr[IþewnGLaoɺʧ³^.2(EygLXoyl.     lvHocDĺ]iIUT:x[{ͿϻĽϸtV+,!HqlU^m|m/  ,lus]\vY Jĸüûv^XOPOFZZ[Ⱥü͸ȹe<E~oE^tze$      rxyVqx]6:TrƎzzѷy̲{uppuykQ" _gbWwlzA      3ft}Yml? Jsqcd~Т]YrͱiVW`w{\Wmͭxsplhaacktz}~|`)-nzdZYxxt7     .`q~YksqOTmYWk{ȶnCi̱bBMKp|gTPhʷvqllry~okjms{o86q~bzyKJjxv6       \qnUfum\Y{jx³Zi|pwҌYwy|wj[Eotxwxlhsz2)rkQWbmn)         Ztt`qƅol+Yssu^{ߵzYGY׻oe{p<8sI\p8a{yV         Rtyivb{BQւX|xgaݪ}MG@}lrgE FrFVU^ovD        Gsxjny^SJǺׂKx_͚xzidDF<ҵlig@ Hwv^dqbhuI     ?swgaÏr^D~ׄZz}|cryo_FFHNǿvjsk-Hk_sNk|qW      9wziXtzi+,iۊD]wsͰ_UX\Y=HIdyn{cReVTBnvX      3x|mW`tb{>Kqw݌8    ,ekp^c{\ J|mxhwr΁DIH@U<ְ}V#PseV_>c|v-    )bopZ˸Ym*Bcs༊¼YDLHDWάxFOc~`hvxl    #[vqajȽBL,Dk}˧μjpo}IFG=oҸjhkyh4MMj9nwY       Q~sd[Ro7wzyͶefVtԪhIR\DZ}wd^_nvN!%[{F_>r}%     Eu`Smt 5_cuynboļɭywd̔qõxqou|{c54w`dWLv|l       8~xj^zξven#)A8-@vbd˰rzzԱŻywxS#B}Qz6HtP     ,yzwlk̇LTyE5D5&_{piuܾҸ|}yǿyrtF!Ji]u;bx}.     &v|skPɥ\Ac0(+!b`tĻáҵ̻~up>%NX{Y5jhv|    Exp5VrMyw)]kʩ|ѹyk%,._.̸GLmrR#     8x{E5k="' Fvϼs³˾i#'#\TЭI^w}<      $m~}]-Q&)/! 'л˲yqιǿüR#'-Qilp  ,o9M^W _v^W_ϱsVScĴhӾma|Z"3$,?X?WzuH     V{a=sܕR0 Txkd^_Ъx`IOpʴ{hw9', +Y.Llws'        0vuu1Mō%8 !CjyZQdwΦv^Mcõx_ 2"*)"5Y SxP      dyg5qF%"SVzmafzPT~~Ǻļ¨3!"n56krv$     M}_Y^˭?8Twou`Rl}]Ƿhd$0& ;r4OkvZ     ,w~lk9X<J¬gWX`}qcý¬}cH?&#c> _T/iy]<         (jN2fϰn!(7()[wnw\}dqʿŝ{ɭ5=3/,q<0P_3            IkA;* .=/}zzXtTa}ȹ±Ƕҡʧrw~N6+)s_35\xW!        WqI0j}Z*#CE1+E`bKa̱нػĪuwx7"2!40BwqB5ID           4nU0CY;EA(A|uiùq\bŞ|ȻɿQiZ? $?A@_|X0Ec{b(         9xwS5J–oEA9Kp|ľ{tfƶyŨû˴eB!";J+LkB,[}l:         Br~G2jxQ@,&/Xmüohjÿǻεðzk}N #1Tnyt^69kX         /_c?ByZ. 9D"1\ujaȷǶxO]p1 %(uf@6NsG         )eb1Aêe-&&"7{||iƾ»˷pAD]h3  &@Ii5-Nlxt8          E/*4&#)+IP`y\Q>D/91SE7=iTC/9=81"19+%JyN:&-]~d;          EjvV-9A`m6:; #/ #%4>?ISQS=60(  8htc3.-@;,1%(!LI$8XoP'          YyF9#&+XxD) :=$.'/:95. 53.;$)!!&28k·y]USIDJ2.-"-(.hsB CbznA           ^}jJ-%RbpdB# 2;2%.0 187@>4$#+%#4&E2137;:3-!&24 &P}wmW7$5Rj{Z1          JzxL4)*[Y !04?'1.+Q&O7KO67(-=*0B=<8E^QHnYLPW[esw[7#"%"#(%0Xw{\;(>bz~uS&           /f];"+"PuB= 1%#8,+#GM=DCMS7.HJO8C{de\@/7ADN_b1)-*&Hiso>("Ad~v_<           MxgR6RQ,,$$(7, &/*6DTX?0OK}Hl8J3*7>61874210-&!&Hkr]H@&$9d|}J0             Eg?2Qpf7+$.085&'35*@WLqA+ &/4+*;`jG<2 1>E_}x^             DqpB *2cuHG/&."3&  & #." )04861)$+De~z92@53Ldp{xV-               6Rkg= 4UZMM$)*!#$$--1;'#!!#&#,(1Ow|jA+77):`nxy\-             4Tizd7'*OppQGEB( ,+')/50&(,)*/.()6FOW_dhtrK'4BThvsi^S?#            5X~gM='!!"/MUppqqqweqoP^bVIHEU^DBk|y|lS?:=?>!/OpyiT.%          DlZJ;-',;DEQago`½nR8_wx_<"            6QuymI;!! )-3:16alqV2;/)4-%2$54%!)@=@JPQTYYoqG            3UuxsgB6*$)+4?@;("2>R:52;;;T\@4,'# ;4Jbnstrny[7       .Ak{qkaPXWMKQMA9'/&*)(=7M\<;."&7]pyiTOTXO=$            6TzyrttrrssrO:'0?5Kcfqyk]Q>23C[lwn^E(                 FOachbcjjcfqukP250)Rgw}yywkap{xmkosQ*                    '-*-46227au|kZ_o{rQ9+" 7Soxp`N@                 Aduz{ulL9$)?GA2               2GW\QA                                                                                                                                                                                                                                                                                                               vSants-1.9.2+svn680.dfsg/Examples/Data/B4.tiff000066400000000000000000001420241147325206600202310ustar00rootroot00000000000000MM*~                                                                                                                                                                                                                 #)08=@><:83-)8BHB:51+"            "/2E@JWV^tbi~mgmL=Rn~vmrslfXG<6."                   2BHUbadiv||tlhnWLL2*>Xklo{~xks{}wmc^;6)              6FUo}|}vct|{f]r|kXJE4+*!-J^p}{oflmdXWdr~vfJ,            +@[svz~viieRhsTRRB $(,8# 2DIJUaebclu>I_qo^OJ             9Vm}z|zjaT>MIA&,''4936:$($# ZpufTpbPB1       -ISj~zgI2&$+')7AE@KN=@;+0$.6H\b\XYVJ;1,'!+('I[ZbdeaXD'         !@WqjyhNN)*+)06C889553)   +3WZRXdXI5           ,^qev@-')5BH<* 3;55>(" /GZis^Q>,!" 9@9) ,FdtdH2                    I@/ ))'0EAK]^I62REM81:-9?.':j{mY=#              K^Yta6%0PW) )FECYp}xvvjZJewxcPlWKtv|wyywkkY<1:<31*" -PJ'0Ps^B5#             CXbcT*0RL(U^MTtuuamyy~i]Qlhe~y{tf`J46JRK775, %<@*-`ypW:#               ;esn+7`U/LtbG[~uvzvur\[Q^kv{x{xnaXF;HaicSVTH:+:;&#/g}Q9             (QpsB7)2PJ.0Rl[9             IyS-@V."T{y_gt{v~wq41ZU^hhnz}}xspmcWX`nlr}|fj`J@A5":YK5AYgQ.              :db(8R::w|~cis~vt^-(YT]hhmxyxsrlb[Zdpzyon`IAE?2 FYN9(WZB"         ?AqcD=H?$Esx~mnq{ylX??^Yajgkuw|sstl`V^vxpo`JBHIC1 E^H/S\:               !Rd^>%VQ(/Zx}~zupwúrd_b`^gmeenqxwuwrcW\yzgg]OLTWSD/OX8ChT!                )WB.1M@ ?zuxĽð}prn`aose^ehow}ysh_`zx``\Y`ig^ZF) +MS4/Ra8               .w9"iA &Z{{trf_dtyf[`blo~{tmhh|yt`_^dr{rbmQ76T[ 2bS<-              0lJ-Tf& Dz{ĺnZY_imeZY_]\nqplXlv~g_bmx{uqrudF# 7L[!1w_)            $Ik4Qq3 S{qTQZ`]TPT[ejr|{yt`uuxtkemw||zyxnX@ IT1*Lg_.            E{36om 6c||YGU\VSYad`qunzzta~|nffmy~~rmdB-EV@&Us/           *Zk&_h;'Qr{xwq~U&9EGN[]UQhuq{~wseo^Zt~yx|zb;0g]!4`D%!         $F|6RE :e|~{|xT*              #U)O}C F\uǽsxZB=I=uyrgtpqqloz~tux|vkmuo`6 -d_(%hT0          -fQ)]" 6gtŚsYpkT_l`6||zy|vvtoiosrwqrtuN'JqA!EeV!            RfzB!Q{͚wkuy~Q{s{~vnwysuyXF%P`;I}9#       1y}Q/h'2XƵƶdr}ur}ssf /mZ)Y]2      !NZ*V? =e˽prwrz|oyc# Xr<5zQ        /r7?l $%Fsĸ~qz~ss~{wrneEM(ka*-gY"      '1K_,x9)JXqƥqu|xw}|}yurpmlZNq:FlN92DF      -Fi@ebYmwwuwohmrvz˷}kRp~xyohbgrzzvoxsuO Dpc4%FV-        ,3IAC8 >`\]ibjmvpmfdpz|nhxvnv{szx}yb{c2:svc.2n?        #Ldk?gwix}zvtwvwxkp~|ÿ~f|K`~x~yyvqpu{}~zy}y{}s@volV-Rb0#        )=T]AL[ J}sw{z|½dy]nlywxxxy~plQ&WzzeA>]F)          /Tk_)h<*r{{{ĿYrzj~}tuw{znmW+ 2zpW.Sc:          *XV8y#F}|yzɵT}|Ĵzxy~{owqK fwqe6BiK+          !"%6c8RbU|uyͳ}i~~~´~|xpsc@"MsxqS1RTA            2Vw(jU ^~~{skyʿy}{fLB:'?y|q3>YX/             &ClYAKiynyz}|ûux~gJGL?:{~M7ZeB             06t|~νɹsZɽ¹{wuXGMP$8vuzk4TcJ#            *BWc}CqyA![R~Ÿɮvlxʾþ˸hrvRA]0`X9a;3+           ':SfZ?vm2 )hc̻pol}˶Ƿ}zeSS("Q|}j=JGJ8        )=\x?Mh'3z}ȶɵuxĿ¶uwkO;47A\|sifcgpo`NE4 [}rll|>r^G5          U_ys:|v% @tz{}ys{ĶlOE>E]n̜v[DA@<1/Ea¼}nhigbdlrtwviZ. ^z~8-boxo{tx}}ü˼úsdPFJL^ƟeQ;EB@>;G\sĻxtxzlG bt|kowK`YJ           (Jrwpv~x<!/aq}տ˼t]II8A\x>I>SJ:GG2H?RmyY]wvvvmFuFNC          5MpYzs:<[WrwxfƹqIAP;?a{.L>D-;Fd¿}}T'L|t|gqqYPSB            -DsY}t9)Yypv[ʾȷļb9DB@IkM >5/Kgż~zm@'=|krlSIRD        @@{mIc Il{˿ѿgB9BDhIA@+K.BPwýgycL? 9{rvrmgr-L:           9G}eDJ'k½;}P@C@^E@;-F4Ibizz¼zgOJ aovtoir;S9          7T`En*J|T@DC]AB50<9Kk}y|zfUPW BsprnhoP]5          #AceTQ*g½O:BE\@B342:HkĹuq~vcNBKV+ $v~ntplljl9        :Pqoi{7BvļS9>@S|?=6701BDBoż}}xK!@x|{AlGM7         \T}^7wo+,SĽǾwODKCQyK8>:C5R}Ľ~t}Y2"optPZEa8        \ikO}]+Yxݏ»qJCFQB             T>f[dV =q{zpuƸǬwjuzoƸm}E6:f~ž~ulv}uiqyuo*^x`7/B>$           QRmUg}K 7kmy{dk˴}}ȴɼ¸qlnhlÖq_34Jv}bo~m{x|qvzwtD 0gyl77$0&        GU[Fgt;7kd{xePQҽx|Ȭǿ³śl[^mɿ}uRjx}w}{bkGO?>)    /X`WWb':j_t{]ohȾy}Ũ˻tȺoQDd{p$NrvTaeV-    :`n^nL?c[znyȼxz¬Ϳl}Ǹhnd]jrnA"]pljtnJ         GTiy>!QcguĤhlyļûu{»tepvuY$dxPytT*       YMr|/3ikx{low»ǼļyvȾsm]^ Th1skH$       e=q`~\ 9tp~~zy»ɿ·Ⱦ|´\]yxs:|iGuy_1         eAN`~E Nuůt{z{}ǻi[x\o|}||nxk owSkxq9       eRH]B'`z}ŵ|Ƶ~t{`3X}wx{{ztg]|c>hjA          ]oNho)6f}ʺzϼðXRy|{m C}t4tnM&          RyStL 8ZoĵƼ˿¶xžijkdu) *v|PjL)        6MyTv7 >Vk÷Ύxƾó}w{w~sf7!kgYH.         PRbzr+ "Pcvyûº¾{zwǺwhgw{OD>^|v\[=        dWyoT+`is~v{~Ǽ÷ſ¾{{xµ{inmfdor9-KQ|lozL        lX]j|B 2gcd}{Ͽ|~~x÷yspnz^9*[!Gw]wP       +NXa8 1QIO|tWĕp{½}oydzojqgi_kX~kiXF4_,( ,vQO'         )LSh0?SAEmjRuq~¼{stýĺ°vq{kVOQX=RZDX\QBc:* cPH-       %VyWyo$ KM13Mj~`F\^cysŶwnlzÿĹƱ|u{jcfmQVQ=WhSMbJ+TSxD;         ;)qxb^3ZT79ALh{izjZvʑzdzÿtbc}üϿbMay`m{fhm_,NUmAE        (g1meK 0US>C@7BZ|tx齈~˺u`[rÿïkGCn~u1 FWfDJ         H{6Za9 8Y^SYWG?bqzϰ}yz˺~yjX[þUJg|9;|boVQ!        [oDNg|y04johccgzȽpYgƽɾus\Rw÷ɽp[l}J -xl|{hT,      !daZPsw0"Nxonsһýa\lƿ½zltc[lmżζ|~Yi\ olr|mN-     B^]9oZ(1`~qdbpĽvcuɽŲltlvUk|ûȱyqklJu_$csRr`F9      mVv-gR&;elRGVyIJju˿bpybx\]Yoÿn`k^^asCgX?>         88m= ;`r\XhzwruϻҿsRcbVq_QIXĭzl|{] XLt^=P          -0V~+?anzqszʼ{Ͼξ`FR_SamSCK_;®xsVEcmAc&          >7f}'Hf`rxxx|ŸſŷŻuUEG]SW\L7JaȽvznhM:dqHk+        B=nsgx) @VOfqûƼcOKHMLR\Zay˺ÿÿ{zv{zkXQ[iqwsi+<|llYb&       Dy#y[mb#Le»¼Ƚ¾ŵŵqOBMWTQECM/]zȽ׿ʽʾ{tsyzz}{|0 +yhQT%        YsrIS(cƽʿiVRQNIMB57@PesɿŹxuu~C .v^kl/          a}"8V",nýϿ]MXVFON>16@L^xvg\_xʿE .cwWge"         i'.Y@zýǭpJ@Z[?JMEBGD?D~pq`FBa~}H5^[d_          l&=}VM}¼ӶuotC8MN7@FEFMHDL̳whiLJn~g]{ƿ¸y{yJ >a``W        k*reoT" Ny»žȾ}ajgXZXOYYQNW`sкibOV|zUAV}žľ|ozF CTVaQ        f8d_X*Fyùƪ{][p{}Ÿνz[NTrwWAVVQDnN         VwQRKo1 7»wG=?Tlmj]^tֹίhICYoqgVN^Ŀ}@WhYBd@       buT@(i. +þ^9QSZlh`Qh¿ĤvaU^mj]QHe}}};#B@Gs<         U{c;@|( *xįɰX=Y^dupfnĿȩ{x~lYPN?Qʼ>!89LVm4        Gv5}Zw# $cȴƜVFcin{xuvuzu^NUBB{þ½>#J7Oef3      8|1qzT. Rx˽RHaglyxxaxפmsvpwoZZO?b¿û7GJaDlb:        (w9l4EIvxǾɬiFAVakxzdkwTyssskVUAH˼žĽƲ.7hC@r\7        yVg9S;m{ĘR?@Vfr{||gi۩o^[m~~xvRTG?jͽʹr%-}=PxN%     |oMh[ '[F?FYjojc_cβm9Go~ulPIKGXýĺ`0pGgt9       ~vu+y›d$Oǻ=>FWc_L=Uq۟^GWgcXL;HNNQ#6gPsk'         jz;iG)A}{ǹս~L;;LNBJac\\ttȧySEGMAND@Jq3)dDXU      Z|By*8 /yz~zuppruwtx~̰mD98CKWv̿}bRIqͿqJ;}NBL@"_z}vz{|yvrpptsxʥ^       /{cLvF Vxvʼnsĵ̽tDDEKyhhqsj_cu9Zk$        wc7~JQ,QuǾʻʹ^LTŰƯLCBOĿn]^a^_eH,(\cTPfU      pu1m^R :sùɽɮmH`ñdJFXþp^DVt'S%IZ~/     anK_A2g־{f¿õX>[eYosE )og[1c`"       Hwh?] (W¾׷Ųzuvľſl?gþǽƽ^lX![B|y=      .l/fj'Fszqu~ûԴǺutn}—ÿĶxV˽Ķý[v;!_?6zw&   ocF\qH 0`njsƾȾüɮʴ|ozǡɿ|̾¯¼k}n}&2]j       On`Rht Gcoľǽh{ìϿ}zzI 7I,JoJ           -o;QL0Vvĸµlro̸}r|j& SiDIt}(        a{6K{:"MwĶnV]in|s^ǰs|Z vSLbV     `mýÿ¿ƸzŸľsehjbikW2 tK-GwG      KlFfÐ[00Sh¼·ýyuk[_bP" 9H2Rx}*       rsY2UvF5V½Ļqdmjgelrt{qƼƶsiV8 V:?d\     Fk7Fʝ] !Cj¿xi}`TarSc{~sziv̽;wN" >qs(Ss9      zdC2aԨr?4OdkļwXe|jyw}u`JXĺįsB #VP,dw       P|wFAåZ%3Tl­m`cSwêf. +hm1Dms_         bgQt˯v4Jr¾İzjxĻxxQ4WR)Zsp-        K|nPQНR&Bqbml{zxrp6!RXG1avq         fuQQ~0P½ɹv{ºzx{oCAyۭrM )^~w{sZtm{U%"Suz>4^r`*         !_zrR>lўs5 %Oyx~~}­tZslTľxtX. @m^]K:Kq{l         9tmGQѠf,!R~øyawL2qylr}u1#4b}U3>coN%         U`G\ڻT& *e}|Ĵ~jsxdyr9/jvkt||pF >^5"Gwu=          3vvIh|/9CrhI             #?rlB2Kk|1 iqGXmh\ZWCPzjacmw{cA4?mr{="%>f~T#        =d_1>nm' .m¾i`ti\_wz`_~vb[bl|ym-Vze<'+EbqT-        !NyU -Zkh#R¸|rl~mcYnvz~upouu_h|- >FctQ          /d^I%ev#Hyxcrz`ddz/Icrn6#%OzyN%        2nLFXmH).3$Dut}vhgehj/aro7,KffJ%        I^/:_|{<0B(Klhmpk}Z$ iuC#-Pi\:             )\?*yzeO%,:}~nelvtgv}O$ +@o\2OlnA              '^z?/][! *?iw{ggqx{fosI 0etQf]/%[iaE             &^qG1hrk-'7hu|ukorphd{~K'$ EtjaG4Nse=               $W}U1'?]wmF"!,TqxusurmbTcwvsryh0%FeRN'(4vrC            -Y~W InveA+"' 1lh81G[YC'          NZ& /YQ#+/$ .CLKVaclfrt{~gZ`^F)+.--@g}kT<+"")'%4JD %Yhb>           9e]2#FM"'+.(*&.=S^aWPI5()'!)9,;A2&7^}zvuk`ZPD8.)(3-'%+DrsB4Dq\9         'Vyk@#!:wV5('45&  '%!  KJME535-6,&+/--02)*FunP/+Eaq[1              CvsU+" AqM-'.4>K1(* 1#'/41)0-,162# ($%*,.4Mc|O/Kjra*                ?^sZ1El.!<1>?J5@IMJHJMJ@6:73/)#!"4!6H^tS/  CeolJ             AtoG!%1m{D@ $')#..$!!#  ;otYB+"/9_rW:$                  *]t|`5 B/%5Zx^pc<]LEU^NKRK\v}qzq\vVdVSixEfc8*);avqH'             CoqJ+9;EPP=#=Uw٫~tg^e7NVIE("- *DW`jB            9asZL>635=GNCA69@8?FDR]WV][WccTKPWW^^PL97VYV<+)*'%'0Ebuuk`9       -RvxaM<0-0%.A9$+:<>997-$""''% %(1636QR+$.',&5NejdXD1       .CnvwYG89?5+ +::%*2N03FBPObmiO0     3Sn}rWNAAB76,%&)20.2).:BLIAQGeW^njuuUJ4         '/=Jiy~~nwfU[SRZPENSNRajgbb\lhkvrsr{me`RKF           &01%BZcwmr|wwvfnqnr{~wqobnTR_SLGG?5*"          $'.74:?DS`\PQLFB?;50,%                                                                                                                                                                                                                                              vSants-1.9.2+svn680.dfsg/Examples/Data/B5.tiff000066400000000000000000001420241147325206600202320ustar00rootroot00000000000000MM*~                                                                                                                                                                                                                                                                                                                                                                                                                                                       "!!                    !$%,AF?HG?DEE?,                       "+8HKLdk`ilPgi[K/&;,;=, !                        23<5/KSYPDTUEJKBVO;0"/+S]<,<@/!                    #0HwjI)/`e.* 16,79AA-$1*PaB6R^MCFA2'!              '1=:8Bc~Z6@D%*>D@PSOC-+KC?P<5JUKUUMB><-!                "(6AMUJ>A_X1;- "$5AOJ>JLQH8#(NI5>3-594??;3/<2,##8B.269BNUV_U=*6JA'<<*30(454("4MJ58>'               &,:IK@77746::('CF/7J[]Y\fn|q_RQRG9#>C#9*,0<-!'9D>3*FF:B8            3CA@B@92)"!'/56++GVIcs|qjjj{wvyyurrBHD,$$D21GRC.$              %>c^FHD( $''(,2612=K`xyanh^VUQC4RX`flqsshmeEO@=7G:9FG5#$2,3YhSB"                !8F_W;==!'+)&*7@AOOauvodUp]G?GNC4AJIAFRO?Rfhvqv[QVN=* "'*:0!BG9<>%            0DN)6QA0. 0/'"2N^]pjplN9?JMA1',561281%.@:"/.SKjZ[mqaA17:4+"&A7'2HI@/                   7PbR&P>%*,:>?Gd|eD15?HC2:60-1895 .)% ?BHWflc_aVD%("+?8-;;TQD=#              #.5/29>A- .81$ !& 0BSfqk]FL9)//.=1>-5\I             !'TpWR:ZW>K;)=Ols]KGL6#$#     %/FcwmbJ;)A@3'/AE;               &'/WuT/8'& ,,)MoxzdMB>5*#-     #7A0&,Ye_N@82""%))'-CX;#                   #,K`nKReK 6ICLw_A-$#     !# 89.MsfSRM>* ,+#1JGD5           #Gj\:+65-BlIWd2(       .CKH?EF9%.2""4<^qSR4",4)?VbC             "[sc#".<%C_SzL+6$#%  (-0+ '8SjpmKOROE:2/ "#5gqzgWC60)4JbU'          *V~j7*9=4%JcvR+D?  '7>I^gifU7<>CPfy}xc_ZXXVQMC1 , ;qdwwU2'.4"'AS@#               CkoT;'>06@e~7'8+ &-9Rcq{{{o[D61LMOWhx}yymgfd^XLVM.#$Jj}lN><<)EI<+                &<;GUlpi~|rrqfVKQRSYhy~vrrohaZFBPN2) &;WkoaD*5#!-7AE=                   -,FP?4?LMDuv}vM-@" $APh~xYRjw{{z~teUPTLR\dhlsz~sohmih\MEEHKM7. &Ja]UVB&." BLQC,           5E[dYJJTTiQ>*"'  (3Tj|phuz{||shUFAGTcifemwxvnmdyp\ICN\d[WK5 8O\bR96&(@>@ME5            '(6FO[[K?J^nsH% !8MYlww{{usp_K@AUild`jv{{tulmRIZowqlfX< ,FQ[UL3,0+8PIF7         +F=LieL(9^swc? "5CGYr|xu}xx}tuuhVLBWkmedluvmvwyt\Wjwvodbh_C+#"/PhgI3" :N9>OA!         2KDZb3/[x}Y5" 4NUQXh{{~xwseWQN^lmijmosds~{~sactwlibhwv\D:8`j\J/'4E9ASM8           .;68Qi9:izl\(6Wbgomcvx{ttoaWUWeppnolexrpciwvifkwrYGC9 &DO^`M?/-D_d[T=           *JZFHmx2#1`pH-   1Rnwscnwuqto`SOQdsuttlbn{niqzvmajsul\MFQ?&*/KXY_D#7Ylg^N8             ?P\]x45_vsY4/7OXkSgov}vxq\G=D]tyyxpdqxqmqz}wp^`cipo_MKWM*7@Rue0+V^NN['         +nJF5#3i{hP& 4DKRJc|cJ]}þz}z{hA?N]civxqpivtjjy||h^nq`m|inab\5#.+(5RkZ2-SI;Of3            6]P>hP/og5!%Jf~uMjw}XZt~oNOZghgoqmpoljjmwvnftvdktatlqqW7 +6'9fW(:NSWXR-          0TdW8C-dzJ $^be_p}wYYfqneffgnthfry||qkwzjlqbvty{q`: 14&%4qm[:+?TQK^J         %JZDl=*WyP-)!!Oytrvzþı]UhurfcacnuzidvpltwlnrjtxzspqR 09.7]k/ :FCPT=       K]LG7X}g]2# 'Fu~~y{¼ŴcRgwyokggpwyxg`q{||~}utvu{ulra:/857o}J#)6-?{j=)' ?v}s¾mZouklvk{poztmdRC# *,!;goI"4Z\P]G            DvR>z^@y_D !(+j}°hZrsgengwpuvtng_T_P/#/+$/3daL86lSE_.         .c_>+.1W`A"+Nàǿ~ZPS`pyywxzx~m`kwr}nC('P=4,$4z|Z8X~bJD+        "TSJH/6)[tsE" 1 CrƬ}rQMks}}{}yo^Ufxvsu]?=>1/$4ecu;3bnRDK        >e@Lg=FX~G& =mžǾzbeotxwvx|ri^[m|qypU" (67=;#Ka[x@8h]K]5           $ZlL[b@NQ%04]³ſɷxv||xqpop~}yp^7&3AH3bibcM)%H^YTE*         8sriY4Acq4,3E1[{Ӿtyuz}scE #3?4bib_ZK/&CVIJ=!         UmZiS0`x[7*)03 ,[ƻ£y|gL& *8<Zpfn]S=9DMM6        1kYLYHR~~A-*1B!$SŻȾĤ|ydV8$3I QzlwbJA6 $CX[K(         PpVfZ5^|N,&@U%iʿÿȿ̸ǭp~~rk]bO&J&DzjunHB\A&EeeY=        )z]\I4Jpj(^7 Gqſ˺ÿʺĿwgsreh{|rzhf_TU\@ !2C SyeoxjKBMD+JaTX4          Vq__I>]}}ta**/&#\q{~½ľƼùrVjy|rv|woZTOHKWJ&#B*@rhoyqXJLE68U>bN        -{_]VDNrxp}X138erx¿ľhr~xwxsqiOOX`acU9 F@.qqnxyjYQLG=NMl]4      LxY]@?byvxZ!?$LxxvŽ~{xttvo^`p}yp`J>EjmpuzwiZSRG=chUb      #jdpd3DuwwgC+2m|rsľǸlzĿuvuyzsuov|wsnb&7]evsvyq_ROA(GcRa;       8w_h@Ryw~|r9#K|g`n~οϼx}zzxyzrrnu~~yj1 /YqzsrvrcRKF5%hd>a.         $]ni[X\l~o"* jeQ`w{ƿ~|ź{zztomvfR $)$Nvssvvm`XQQ9Yr9bN        6}^seHi]Z|e1 )uqiƽžʴzǷǷƱ~}~yupowia 5zqsvy{yrkMWb:nTQk)        zc^P:N]xH$7 EŸ{tpƽ¯ɽîv~vmoy|vcD 4emsltIDSH;Y]0b       ,vOeO@Rivz=*Uýȹblfʽ»ĸxdat~l_S$RswnzzqtfDGN1skK_<      !ZnM~`TVdx{<%$kɼ¾Ƚ}ϬĽûzd]m~pY_;xwx|xoeSQ[7Rq[CY       +wfr9Zes|tk0(3}ǼϸĖңӸĽ}|njknu}`h' 6pz~xqWbZQX$dR0U(          Q\gh8V_us~>! >ͼ˴̳޴̼ϸĿ®~s{{tyscg{kjB!6`uxrb^T2e@HgFwp|x{/=GUZDK}E4B0       dr,a-wE2)iovshoż¾M@BNʾԤG-?RzȻ}}}}y>"$3>s}}vwDH@MQ|,]>I8      0yR`Yhl||/"#gmkìlJE)Wʴ|Q48Ko¾{}H$7Omszs~Q96_;^8|r?I>   H{5Q4zeq+#$%]l|q§hY>&nحzX=Cc{ƽ~v{xojnx}S*MXkyw{atl5&_+#Q[p-CG,     !^r's/\`rk9"%3ag~˿lEL{ϴ`Wdv¼xqjt}n^ad[VY_gs~{a=@mqyxzj{]7WE-`4z,AK;     1mj#rnTjnz`@%7q{|ʭ|fӿʳkjv}~scq|qekllfZVg|zwk9;^|~z}p|rLJ\Dl)BGG?     H]BT#|^d|{=H-Kyoy~zѯeѾĎqjƸx{o^dpbU7"4Uzzjoqsxy@KSjcEZD      ScAb2pW{a{yLE 3rv{|Ūrx̤vmu~gVUv~zi`I 1Fewupuu}TB\N[RH\HP<       _hAv`reva|XD%Nkͭkjƺqh|ǿzlSYs}zzrh7+;Uwmut}l<^fNh(ZIL;       -dZ3xUriiu?7 ^}k޾Pf^NvƱ|j`}v{z|S!8Ptfq|{v~DP{D_!b@PA      :gVM!gWvbC= ekxn}ijƴoQkm;?6r=XF     ?`Jh|kSOD:*5op^fbZqɸí]Q^Dt͹uit~umt{xkF$0I\aqjru6@1TuFZL     NX,XvHrw`nA7'#U|o`M;VwǭôtRfwVNǴp~ss}vtYE#6HXuwt:pR?XRHEM&    ]b-``d_xlly~X?/ 2iunK8tyɹªKLmNK͹~}x{}~zrt^_;/=Mvvz}?_`OG#<&G-        Jb1ayQ\ssF;'&*htaZDMpvÝԱZRu\A_ɼp}zqxm]Xh9 -?;{uGZ^PGl3I$      2]K=0x\{^{]>9 /fogwvanxھZV|pMaǾ{yzwmcZa2 %84o}~bSv^M2u;D/        ;zDLJ=Y-    WLF2lc_l/#5+n͵rʟ׻c;]U6Vƿ{^eup}ou}X=%!'&kwqylqYU$A1K+      #VOJ5vk{O~Y&.,BzåïưдP:ja5=nŻonxq~}yUF3 %7$Wt}bf]`+E&86         F`6$yNeol>tM.H-Hwɰ·jlȯͨSSxJ9Qqȸ}qpklKD3!69{|tsia[d4N0DH"     DK?5Fgqgdwh=D=! Q̴zUK}XDE~ƹĽyqk{v~~rxxeL?LI$%,4hY~oi}hmZ*+:W,     B8)GLqgtor~F(74 +`}ӶiDD]?MzŽ{szuvotrgcld;.Pukp{]\X3E:E*     -[@"bFyay}yrp,#._zDZŠԿvOOwF\tȻ~}v~xus{{[- %'xfrwVMX;_-;1     'Z=`"gT}}]1 0\¿xp̰ff̠Znx{pq~pG#! fnrzaQ`Do"=B"    ;eL1~4xnz@BV;    !MK;;0nexpt.! )bϱû˿·v]brpu{oeacinbSSWTZ]Q""&zxzzugOWI $_wưͳrt}yu|~p]SQj~xWFV" HnifaOGvEXWW   -QZA4jJ[ab|; $]zvxɴüѶ~gmwtnf]VSR]r~zg`f:  =klmk_\s+8Vf    4Ya5.lAidk}}5(Z¯νżŶzYJNVVQk|~tsoQ /|t{opl`[;9Qa    @]\TnTxa}},-Yz}ηƻȽľ{xVJU\_ctvqfP w~|usvo\MVPQT    $NaS:`AV\iv"*Y|º˸ȾͲws~]][P\yzyrdJ  t~uqw~y^@]FFNV+    +XeM0F2KZs"Xĵv½ƻüɸƸ¿ĿͿyZIZ`RWp~|yZ$ t}tuyztU)Y8)@V3     )WcJ6K*O]d~ V{Űw½ƺfJi\9=OZG    7c^:-MN6g}_ "k{y}xx[YƨʼneV_r{ʛǭ̧yurs~xneWZqC 6~tvdHjFDPWL   =b[<4KkCky{] ,rpzϺ¿ĻlXU`ncY}˥۬ʿwmxtus~}|vnZfE 5w~kyui\[>@OXV    A]W@&Bfdsqz_9}гžqbdYauoTbͧ׮ƻibppiv}yx~|lvB7tnyqcap8*6N[a    %F]WF)43asvydA˷ŽdhlVldMw˽еټųyrfcXnvzu|v{~= 8sxnWWc(#6Q^f  #F`YGHG\jyd 7˿úŽĻǽlrzr{iiٿƿĽ|wk_]grv|~ztI *w{oc\T00[ee% $Jc[NMe}}d +³¼û¿wu©{f_UQ\o}tF )wyycP`HIfg\  'PcZP=V|e nɻź˾ƽӿºĽsid_cvzD 2zweEmXLSkqh&  *TbUKA]|ng U¿ƽƿϽIJ洪þ½x9 @xhEtWRZcX    +VdUHAvgyo H½˿̽½¿Ƴ|l$P{~jPUMP]K  (Wk\JDxXz 4w{ľżŬ~ʸȾd eyi\h9GRfN   %VrcLNv?{ (ln˶­оz;ľ_xwea`1MUb@  #UueJ(f;v 6ob˻ƭ{Ŀȭоθ˼˿µļȷX }~{xbaa2V^gC   SsUF%SJ||6ɿ{ƻϻɹѼɼ¹οɿ³}uC yr}ZWnMJdTp#   LoYO4Zho}( &~ʾçȭ~zpɾȹnd6/|zcOycCHa_j   Fm`XPLmiQ5 '~ø´puϸȳy}tx~пpmtapŵɰn_1DsjhlHLWfc%     =jcWF:`?{A 6ظɵWklp˾Ϸ]j~x|stӷ~d`tigÿ}f3Sl|]idJX[sY(    3ggWC8V+{N =дܻʴwLft_iyiNd{u~utzΨrjwn_jrdıh- btyoFkY=?ah}F   ,grdbA2`Ox^ <˿IJnHahfv`Mx{gcklzvxodͨdMn|fXh^Y»o]jf'  }zgXp2C`fo/   [uplR0lpo :ɿȾoTkjp}WF}ҵǟydXQXfqoko{Ͳn@bw_dh\î[>Lmg$ ww[o{CW_`^"  Hlmga5[rPy 8ϿƸϿʿʽxivu}]dȷƪ{fLMZ[KF]DZϾB^}q|}ubJK\ff !!oVy\Gaci`"    7uqbP@7\..7sƺǾ˿Ū{hgz}sϼrZKSUZ@Pʡ\>^_sý|tujS=CTk~~; >}}K6>idk6    %bk\`N4aqb? -oĹŦrhk|ľȾ§zbFS]VA^мz@=PlkmNiȾwR::^yy|q/ [{~YIq4Qhmp3    XunbO>No,W#iĶvĻžZaq~gCK_NErԟV1+GHN@fþľvP@\x{z{v|M r|t@\\6`bvm*    Fssb^W     Inbc[COq3E 7uĿģ}e_o¯þeZgϺêaO>R¦}zqjY@%N^ Qg?NvEv# AzsľŻ~x¦ǹsX33ysryu{rn\g}t~|Ľ¾}A  *]kS[sf?DZYb}>   ~lXIYvKc<  ,FyjnĴ]]}w»~{n_*KqUO|uL-J_^lv*     PqcO=yidV+ (LxsrtrĿĹgH3"  !5d_Krj>5Hkbx`      %~{t\2-ekC   !%Cvǟx¿įȿ`-"*  4XoGZmO2B?qbI      awb@#=hV% 2k~ȱuĶ|½ɼüs;5#0]\?=P//LVVg{     =}olf:3XsHaD 5#E]PhvJ    [|xzWD5gzI\P* 5eyqx½~~z4"!-0WX@:I*31%/2QeeqY    ;qge:.oeUD*% ( >gyzzcxw|U%-;,;M@Q2Eq>-;RPcd      XxppQ+FjF7<   -q}~lkyw`uþüi,! 009K8.IvgrN/&0Eedm|A      cofP5Ht_4?" @rvq{s·|p0!!)(:J,%ILptd[FXNAWor=        )Y|nG"0[icADJH! Lahpp~v¿¹Ŀqh7 &@T:067ReBA !5[VZouuJ       'V~uf<#;YyAHT'( +7# ;EOrx~yw|bs¿̗|h. 26hc<09TvbM8)FPJsztA        _s]<$Dz5=30=$;Xm~~||Yi²pVhľ¸U/% Jwl[wcn{`.*HNYnvd=         YgK5U7heC069:)1Wu~{}r_{·yff|ͶȨ{L2("",TJ%"~vN)$=Xo}i1       Ewmm;(>[jHP-'3@) )68F`}~ypvcol½~D   'fL4\S8"!8N`oyf9        'dn.;PDFSOLB" 5xe{cuv~n9&  0>Y{e?):Vgu{C         -V|ND-<&7)mW/ &Nnv`¸w_9 %/)1TgXhK$ /;KYlsnU            @l~wWJ6$\1 +0$R{uy]~{D*" )>C7?_cj9"#;Bgesh@           9swnj`H%AZzLOci7 $Eum~xz]q}k9  5TMJIHZW6IMb^wn]D#         6grPG.#cq{sfe5"( 5"Qwrzo`t|sw['!+;2C:[rP3&;NK~wjp6         .Qnt>.%>qe]dS1,  @qvwkkxpRYƿwQ5& '+BlXRPIT]? &3CVdnrh\6            )\~u\A'*GktmYMM< !$E}|dgp``imgm\>)&&3NU\itr`C"              "jwQ* :[x{gOL^8&.%(3W}ulqv|xlx~xvY4 6(,0_N]l_aojJ3)%(Gb]fpr_<               !C{jZO9!Eax{gMQnbPV0 5*+-;]WIUBAfqXQhuqyycH1! !9;I`4 7-(""34E*nfS>:@WP?D/88I7 @ZUCHivl`mis\SJ?:/FtzWWVbrqsksUwL5%Do]]A2,3825MS\lluziYA           7[rvvshTHC( ;W\XVQIZijaSsxqxYsydf&_OVBED')@MH(?GRBYgn~wkW>(               6Qhssj^O538*01,)3EM@-F5$*d>LUPCj`E_tnp_{xZXg;U+=5V/-.<(%+A4+-4J^[iSn{oo[@!               (GiukWZaSY?((:'">E884I+;3,IKH5\K3R\=.J);5B6*9 "-494GXXYbl}f}|ZE*            +?_~|~ol\F:<0 ,=(<97?2%,182RD+;B(2&*("%*6<>G9GJbgk}ztf_F               !;ik|fSTVOHH$$)..#"":BSSIR[gvglj|onzlb=%                      !`|w{roqog_G`_:H3$3-B2'))) .1)2F/@G8L:<                     &/20:<)5G>FF<04DH>7/#                                                                                                                                                                                                                                                                                                                                                                                                                           ћ                          ̍ ׉؇؁ ̃̏ƉمߔώΉ܍؇ vSants-1.9.2+svn680.dfsg/Examples/Data/Frown.nii000066400000000000000000017651401147325206600207210ustar00rootroot00000000000000\rhh ???C????n+1?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ants-1.9.2+svn680.dfsg/Examples/Data/Frown.txt000066400000000000000000001321211147325206600207430ustar00rootroot000000000000000 0 0 0 164.5 0 0 1 195 0 0 1 156 -1 0 1 157 -1 0 1 158 -1 0 1 159 -1 0 1 160 -1 0 1 161 -1 0 1 162 -1 0 1 163 -1 0 1 164 -1 0 1 195 -1 0 1 196 -1 0 1 197 -1 0 1 198 -1 0 1 199 -1 0 1 200 -1 0 1 201 -1 0 1 202 -1 0 1 203 -1 0 1 149 -2 0 1 150 -2 0 1 151 -2 0 1 152 -2 0 1 153 -2 0 1 154 -2 0 1 155 -2 0 1 156 -2 0 1 203 -2 0 1 204 -2 0 1 205 -2 0 1 206 -2 0 1 207 -2 0 1 208 -2 0 1 209 -2 0 1 210 -2 0 1 143 -3 0 1 144 -3 0 1 145 -3 0 1 146 -3 0 1 147 -3 0 1 148 -3 0 1 149 -3 0 1 210 -3 0 1 211 -3 0 1 212 -3 0 1 213 -3 0 1 214 -3 0 1 215 -3 0 1 139 -4 0 1 140 -4 0 1 141 -4 0 1 142 -4 0 1 143 -4 0 1 215 -4 0 1 216 -4 0 1 217 -4 0 1 218 -4 0 1 219 -4 0 1 220 -4 0 1 135 -5 0 1 136 -5 0 1 137 -5 0 1 138 -5 0 1 139 -5 0 1 220 -5 0 1 221 -5 0 1 222 -5 0 1 223 -5 0 1 224 -5 0 1 131 -6 0 1 132 -6 0 1 133 -6 0 1 134 -6 0 1 135 -6 0 1 224 -6 0 1 225 -6 0 1 226 -6 0 1 227 -6 0 1 228 -6 0 1 128 -7 0 1 129 -7 0 1 130 -7 0 1 131 -7 0 1 228 -7 0 1 229 -7 0 1 230 -7 0 1 231 -7 0 1 125 -8 0 1 126 -8 0 1 127 -8 0 1 128 -8 0 1 231 -8 0 1 232 -8 0 1 233 -8 0 1 234 -8 0 1 122 -9 0 1 123 -9 0 1 124 -9 0 1 125 -9 0 1 234 -9 0 1 235 -9 0 1 236 -9 0 1 237 -9 0 1 119 -10 0 1 120 -10 0 1 121 -10 0 1 122 -10 0 1 237 -10 0 1 238 -10 0 1 239 -10 0 1 240 -10 0 1 116 -11 0 1 117 -11 0 1 118 -11 0 1 119 -11 0 1 240 -11 0 1 241 -11 0 1 242 -11 0 1 243 -11 0 1 113 -12 0 1 114 -12 0 1 115 -12 0 1 116 -12 0 1 172 -12 0 1 173 -12 0 1 174 -12 0 1 175 -12 0 1 176 -12 0 1 177 -12 0 1 178 -12 0 1 179 -12 0 1 180 -12 0 1 181 -12 0 1 182 -12 0 1 183 -12 0 1 184 -12 0 1 185 -12 0 1 186 -12 0 1 187 -12 0 1 243 -12 0 1 244 -12 0 1 245 -12 0 1 246 -12 0 1 111 -13 0 1 112 -13 0 1 113 -13 0 1 159 -13 0 1 160 -13 0 1 161 -13 0 1 162 -13 0 1 163 -13 0 1 164 -13 0 1 165 -13 0 1 166 -13 0 1 167 -13 0 1 168 -13 0 1 169 -13 0 1 170 -13 0 1 171 -13 0 1 172 -13 0 1 187 -13 0 1 188 -13 0 1 189 -13 0 1 190 -13 0 1 191 -13 0 1 192 -13 0 1 193 -13 0 1 194 -13 0 1 195 -13 0 1 196 -13 0 1 197 -13 0 1 198 -13 0 1 199 -13 0 1 200 -13 0 1 246 -13 0 1 247 -13 0 1 248 -13 0 1 109 -14 0 1 110 -14 0 1 111 -14 0 1 152 -14 0 1 153 -14 0 1 154 -14 0 1 155 -14 0 1 156 -14 0 1 157 -14 0 1 158 -14 0 1 159 -14 0 1 200 -14 0 1 201 -14 0 1 202 -14 0 1 203 -14 0 1 204 -14 0 1 205 -14 0 1 206 -14 0 1 207 -14 0 1 248 -14 0 1 249 -14 0 1 250 -14 0 1 106 -15 0 1 107 -15 0 1 108 -15 0 1 109 -15 0 1 147 -15 0 1 148 -15 0 1 149 -15 0 1 150 -15 0 1 151 -15 0 1 152 -15 0 1 207 -15 0 1 208 -15 0 1 209 -15 0 1 210 -15 0 1 211 -15 0 1 212 -15 0 1 250 -15 0 1 251 -15 0 1 252 -15 0 1 253 -15 0 1 36 -16 0 1 37 -16 0 1 38 -16 0 1 39 -16 0 1 40 -16 0 1 41 -16 0 1 42 -16 0 1 43 -16 0 1 44 -16 0 1 45 -16 0 1 46 -16 0 1 104 -16 0 1 105 -16 0 1 106 -16 0 1 142 -16 0 1 143 -16 0 1 144 -16 0 1 145 -16 0 1 146 -16 0 1 147 -16 0 1 212 -16 0 1 213 -16 0 1 214 -16 0 1 215 -16 0 1 216 -16 0 1 217 -16 0 1 253 -16 0 1 254 -16 0 1 255 -16 0 1 34 -17 0 1 35 -17 0 1 36 -17 0 1 46 -17 0 1 47 -17 0 1 48 -17 0 1 102 -17 0 1 103 -17 0 1 104 -17 0 1 138 -17 0 1 139 -17 0 1 140 -17 0 1 141 -17 0 1 142 -17 0 1 217 -17 0 1 218 -17 0 1 219 -17 0 1 220 -17 0 1 221 -17 0 1 255 -17 0 1 256 -17 0 1 257 -17 0 1 33 -18 0 1 34 -18 0 1 48 -18 0 1 49 -18 0 1 100 -18 0 1 101 -18 0 1 102 -18 0 1 134 -18 0 1 135 -18 0 1 136 -18 0 1 137 -18 0 1 138 -18 0 1 221 -18 0 1 222 -18 0 1 223 -18 0 1 224 -18 0 1 225 -18 0 1 257 -18 0 1 258 -18 0 1 259 -18 0 1 32 -19 0 1 33 -19 0 1 34 -19 0 1 35 -19 0 1 49 -19 0 1 50 -19 0 1 98 -19 0 1 99 -19 0 1 100 -19 0 1 131 -19 0 1 132 -19 0 1 133 -19 0 1 134 -19 0 1 225 -19 0 1 226 -19 0 1 227 -19 0 1 228 -19 0 1 259 -19 0 1 260 -19 0 1 261 -19 0 1 35 -20 0 1 36 -20 0 1 50 -20 0 1 51 -20 0 1 96 -20 0 1 97 -20 0 1 98 -20 0 1 127 -20 0 1 128 -20 0 1 129 -20 0 1 130 -20 0 1 131 -20 0 1 228 -20 0 1 229 -20 0 1 230 -20 0 1 231 -20 0 1 232 -20 0 1 261 -20 0 1 262 -20 0 1 263 -20 0 1 36 -21 0 1 51 -21 0 1 52 -21 0 1 94 -21 0 1 95 -21 0 1 96 -21 0 1 124 -21 0 1 125 -21 0 1 126 -21 0 1 127 -21 0 1 232 -21 0 1 233 -21 0 1 234 -21 0 1 235 -21 0 1 263 -21 0 1 264 -21 0 1 265 -21 0 1 36 -22 0 1 37 -22 0 1 52 -22 0 1 53 -22 0 1 54 -22 0 1 92 -22 0 1 93 -22 0 1 94 -22 0 1 122 -22 0 1 123 -22 0 1 124 -22 0 1 235 -22 0 1 236 -22 0 1 237 -22 0 1 265 -22 0 1 266 -22 0 1 37 -23 0 1 54 -23 0 1 55 -23 0 1 56 -23 0 1 57 -23 0 1 58 -23 0 1 59 -23 0 1 91 -23 0 1 92 -23 0 1 119 -23 0 1 120 -23 0 1 121 -23 0 1 122 -23 0 1 237 -23 0 1 238 -23 0 1 239 -23 0 1 240 -23 0 1 266 -23 0 1 267 -23 0 1 268 -23 0 1 37 -24 0 1 59 -24 0 1 60 -24 0 1 61 -24 0 1 62 -24 0 1 89 -24 0 1 90 -24 0 1 91 -24 0 1 116 -24 0 1 117 -24 0 1 118 -24 0 1 119 -24 0 1 240 -24 0 1 241 -24 0 1 242 -24 0 1 243 -24 0 1 268 -24 0 1 269 -24 0 1 270 -24 0 1 37 -25 0 1 38 -25 0 1 39 -25 0 1 62 -25 0 1 63 -25 0 1 64 -25 0 1 87 -25 0 1 88 -25 0 1 89 -25 0 1 114 -25 0 1 115 -25 0 1 116 -25 0 1 243 -25 0 1 244 -25 0 1 245 -25 0 1 270 -25 0 1 271 -25 0 1 272 -25 0 1 39 -26 0 1 64 -26 0 1 65 -26 0 1 86 -26 0 1 87 -26 0 1 112 -26 0 1 113 -26 0 1 114 -26 0 1 245 -26 0 1 246 -26 0 1 247 -26 0 1 272 -26 0 1 273 -26 0 1 39 -27 0 1 65 -27 0 1 66 -27 0 1 67 -27 0 1 84 -27 0 1 85 -27 0 1 86 -27 0 1 110 -27 0 1 111 -27 0 1 112 -27 0 1 247 -27 0 1 248 -27 0 1 249 -27 0 1 273 -27 0 1 274 -27 0 1 275 -27 0 1 323 -27 0 1 324 -27 0 1 325 -27 0 1 326 -27 0 1 327 -27 0 1 328 -27 0 1 329 -27 0 1 330 -27 0 1 331 -27 0 1 332 -27 0 1 39 -28 0 1 67 -28 0 1 68 -28 0 1 82 -28 0 1 83 -28 0 1 84 -28 0 1 107 -28 0 1 108 -28 0 1 109 -28 0 1 110 -28 0 1 249 -28 0 1 250 -28 0 1 251 -28 0 1 252 -28 0 1 275 -28 0 1 276 -28 0 1 314 -28 0 1 315 -28 0 1 316 -28 0 1 317 -28 0 1 318 -28 0 1 319 -28 0 1 320 -28 0 1 321 -28 0 1 322 -28 0 1 323 -28 0 1 330 -28 0 1 331 -28 0 1 39 -29 0 1 40 -29 0 1 68 -29 0 1 69 -29 0 1 81 -29 0 1 82 -29 0 1 105 -29 0 1 106 -29 0 1 107 -29 0 1 252 -29 0 1 253 -29 0 1 254 -29 0 1 276 -29 0 1 277 -29 0 1 278 -29 0 1 310 -29 0 1 311 -29 0 1 312 -29 0 1 313 -29 0 1 314 -29 0 1 330 -29 0 1 40 -30 0 1 41 -30 0 1 69 -30 0 1 70 -30 0 1 80 -30 0 1 81 -30 0 1 103 -30 0 1 104 -30 0 1 105 -30 0 1 254 -30 0 1 255 -30 0 1 256 -30 0 1 278 -30 0 1 279 -30 0 1 310 -30 0 1 329 -30 0 1 330 -30 0 1 41 -31 0 1 42 -31 0 1 43 -31 0 1 70 -31 0 1 71 -31 0 1 78 -31 0 1 79 -31 0 1 80 -31 0 1 102 -31 0 1 103 -31 0 1 256 -31 0 1 257 -31 0 1 279 -31 0 1 280 -31 0 1 281 -31 0 1 308 -31 0 1 309 -31 0 1 310 -31 0 1 329 -31 0 1 43 -32 0 1 44 -32 0 1 71 -32 0 1 72 -32 0 1 76 -32 0 1 77 -32 0 1 78 -32 0 1 100 -32 0 1 101 -32 0 1 102 -32 0 1 257 -32 0 1 258 -32 0 1 259 -32 0 1 281 -32 0 1 282 -32 0 1 283 -32 0 1 301 -32 0 1 302 -32 0 1 303 -32 0 1 304 -32 0 1 305 -32 0 1 306 -32 0 1 307 -32 0 1 308 -32 0 1 328 -32 0 1 329 -32 0 1 44 -33 0 1 72 -33 0 1 75 -33 0 1 76 -33 0 1 98 -33 0 1 99 -33 0 1 100 -33 0 1 259 -33 0 1 260 -33 0 1 261 -33 0 1 283 -33 0 1 284 -33 0 1 301 -33 0 1 328 -33 0 1 44 -34 0 1 72 -34 0 1 73 -34 0 1 74 -34 0 1 75 -34 0 1 96 -34 0 1 97 -34 0 1 98 -34 0 1 261 -34 0 1 262 -34 0 1 263 -34 0 1 284 -34 0 1 285 -34 0 1 300 -34 0 1 301 -34 0 1 328 -34 0 1 44 -35 0 1 94 -35 0 1 95 -35 0 1 96 -35 0 1 263 -35 0 1 264 -35 0 1 265 -35 0 1 285 -35 0 1 286 -35 0 1 287 -35 0 1 299 -35 0 1 300 -35 0 1 328 -35 0 1 44 -36 0 1 45 -36 0 1 46 -36 0 1 47 -36 0 1 93 -36 0 1 94 -36 0 1 265 -36 0 1 266 -36 0 1 287 -36 0 1 288 -36 0 1 298 -36 0 1 299 -36 0 1 328 -36 0 1 47 -37 0 1 91 -37 0 1 92 -37 0 1 93 -37 0 1 266 -37 0 1 267 -37 0 1 268 -37 0 1 288 -37 0 1 289 -37 0 1 297 -37 0 1 298 -37 0 1 328 -37 0 1 47 -38 0 1 89 -38 0 1 90 -38 0 1 91 -38 0 1 268 -38 0 1 269 -38 0 1 270 -38 0 1 289 -38 0 1 290 -38 0 1 291 -38 0 1 297 -38 0 1 327 -38 0 1 328 -38 0 1 47 -39 0 1 48 -39 0 1 88 -39 0 1 89 -39 0 1 270 -39 0 1 271 -39 0 1 291 -39 0 1 292 -39 0 1 296 -39 0 1 297 -39 0 1 327 -39 0 1 48 -40 0 1 86 -40 0 1 87 -40 0 1 88 -40 0 1 271 -40 0 1 272 -40 0 1 273 -40 0 1 292 -40 0 1 293 -40 0 1 296 -40 0 1 326 -40 0 1 327 -40 0 1 48 -41 0 1 85 -41 0 1 86 -41 0 1 273 -41 0 1 274 -41 0 1 293 -41 0 1 294 -41 0 1 295 -41 0 1 296 -41 0 1 326 -41 0 1 48 -42 0 1 49 -42 0 1 50 -42 0 1 83 -42 0 1 84 -42 0 1 85 -42 0 1 274 -42 0 1 275 -42 0 1 276 -42 0 1 324 -42 0 1 325 -42 0 1 326 -42 0 1 50 -43 0 1 82 -43 0 1 83 -43 0 1 276 -43 0 1 277 -43 0 1 324 -43 0 1 50 -44 0 1 81 -44 0 1 82 -44 0 1 277 -44 0 1 278 -44 0 1 324 -44 0 1 50 -45 0 1 79 -45 0 1 80 -45 0 1 81 -45 0 1 278 -45 0 1 279 -45 0 1 280 -45 0 1 324 -45 0 1 50 -46 0 1 78 -46 0 1 79 -46 0 1 280 -46 0 1 281 -46 0 1 324 -46 0 1 50 -47 0 1 77 -47 0 1 78 -47 0 1 281 -47 0 1 282 -47 0 1 324 -47 0 1 50 -48 0 1 75 -48 0 1 76 -48 0 1 77 -48 0 1 282 -48 0 1 283 -48 0 1 284 -48 0 1 324 -48 0 1 50 -49 0 1 74 -49 0 1 75 -49 0 1 284 -49 0 1 285 -49 0 1 324 -49 0 1 50 -50 0 1 51 -50 0 1 73 -50 0 1 74 -50 0 1 285 -50 0 1 286 -50 0 1 323 -50 0 1 324 -50 0 1 51 -51 0 1 52 -51 0 1 53 -51 0 1 72 -51 0 1 73 -51 0 1 286 -51 0 1 287 -51 0 1 322 -51 0 1 323 -51 0 1 53 -52 0 1 71 -52 0 1 72 -52 0 1 287 -52 0 1 288 -52 0 1 321 -52 0 1 322 -52 0 1 52 -53 0 1 53 -53 0 1 70 -53 0 1 71 -53 0 1 288 -53 0 1 289 -53 0 1 320 -53 0 1 321 -53 0 1 51 -54 0 1 52 -54 0 1 68 -54 0 1 69 -54 0 1 70 -54 0 1 289 -54 0 1 290 -54 0 1 320 -54 0 1 50 -55 0 1 51 -55 0 1 67 -55 0 1 68 -55 0 1 290 -55 0 1 320 -55 0 1 49 -56 0 1 50 -56 0 1 66 -56 0 1 67 -56 0 1 290 -56 0 1 291 -56 0 1 292 -56 0 1 320 -56 0 1 48 -57 0 1 49 -57 0 1 65 -57 0 1 66 -57 0 1 292 -57 0 1 319 -57 0 1 320 -57 0 1 47 -58 0 1 48 -58 0 1 64 -58 0 1 65 -58 0 1 292 -58 0 1 293 -58 0 1 319 -58 0 1 46 -59 0 1 47 -59 0 1 63 -59 0 1 64 -59 0 1 293 -59 0 1 294 -59 0 1 295 -59 0 1 296 -59 0 1 297 -59 0 1 318 -59 0 1 319 -59 0 1 45 -60 0 1 46 -60 0 1 62 -60 0 1 63 -60 0 1 297 -60 0 1 317 -60 0 1 318 -60 0 1 45 -61 0 1 61 -61 0 1 62 -61 0 1 297 -61 0 1 317 -61 0 1 43 -62 0 1 44 -62 0 1 45 -62 0 1 60 -62 0 1 61 -62 0 1 297 -62 0 1 317 -62 0 1 43 -63 0 1 59 -63 0 1 60 -63 0 1 297 -63 0 1 317 -63 0 1 43 -64 0 1 58 -64 0 1 59 -64 0 1 297 -64 0 1 298 -64 0 1 299 -64 0 1 300 -64 0 1 317 -64 0 1 40 -65 0 1 41 -65 0 1 42 -65 0 1 43 -65 0 1 57 -65 0 1 58 -65 0 1 300 -65 0 1 317 -65 0 1 318 -65 0 1 38 -66 0 1 39 -66 0 1 40 -66 0 1 56 -66 0 1 57 -66 0 1 300 -66 0 1 301 -66 0 1 302 -66 0 1 303 -66 0 1 318 -66 0 1 319 -66 0 1 38 -67 0 1 55 -67 0 1 56 -67 0 1 303 -67 0 1 319 -67 0 1 320 -67 0 1 38 -68 0 1 54 -68 0 1 55 -68 0 1 303 -68 0 1 304 -68 0 1 305 -68 0 1 320 -68 0 1 321 -68 0 1 36 -69 0 1 37 -69 0 1 38 -69 0 1 54 -69 0 1 305 -69 0 1 321 -69 0 1 36 -70 0 1 52 -70 0 1 53 -70 0 1 54 -70 0 1 305 -70 0 1 306 -70 0 1 307 -70 0 1 321 -70 0 1 322 -70 0 1 36 -71 0 1 52 -71 0 1 307 -71 0 1 322 -71 0 1 323 -71 0 1 35 -72 0 1 36 -72 0 1 51 -72 0 1 52 -72 0 1 307 -72 0 1 308 -72 0 1 323 -72 0 1 324 -72 0 1 35 -73 0 1 50 -73 0 1 51 -73 0 1 308 -73 0 1 309 -73 0 1 324 -73 0 1 34 -74 0 1 35 -74 0 1 49 -74 0 1 50 -74 0 1 309 -74 0 1 310 -74 0 1 324 -74 0 1 325 -74 0 1 33 -75 0 1 34 -75 0 1 48 -75 0 1 49 -75 0 1 310 -75 0 1 311 -75 0 1 325 -75 0 1 326 -75 0 1 32 -76 0 1 33 -76 0 1 48 -76 0 1 311 -76 0 1 326 -76 0 1 327 -76 0 1 32 -77 0 1 47 -77 0 1 48 -77 0 1 311 -77 0 1 312 -77 0 1 327 -77 0 1 31 -78 0 1 32 -78 0 1 46 -78 0 1 47 -78 0 1 312 -78 0 1 313 -78 0 1 327 -78 0 1 328 -78 0 1 31 -79 0 1 45 -79 0 1 46 -79 0 1 313 -79 0 1 314 -79 0 1 328 -79 0 1 30 -80 0 1 31 -80 0 1 45 -80 0 1 314 -80 0 1 328 -80 0 1 329 -80 0 1 29 -81 0 1 30 -81 0 1 44 -81 0 1 45 -81 0 1 314 -81 0 1 315 -81 0 1 329 -81 0 1 330 -81 0 1 29 -82 0 1 43 -82 0 1 44 -82 0 1 315 -82 0 1 316 -82 0 1 330 -82 0 1 28 -83 0 1 29 -83 0 1 42 -83 0 1 43 -83 0 1 316 -83 0 1 317 -83 0 1 330 -83 0 1 331 -83 0 1 27 -84 0 1 28 -84 0 1 42 -84 0 1 317 -84 0 1 331 -84 0 1 332 -84 0 1 27 -85 0 1 41 -85 0 1 42 -85 0 1 317 -85 0 1 318 -85 0 1 332 -85 0 1 26 -86 0 1 27 -86 0 1 40 -86 0 1 41 -86 0 1 318 -86 0 1 319 -86 0 1 332 -86 0 1 333 -86 0 1 25 -87 0 1 26 -87 0 1 40 -87 0 1 319 -87 0 1 333 -87 0 1 334 -87 0 1 25 -88 0 1 39 -88 0 1 40 -88 0 1 319 -88 0 1 320 -88 0 1 334 -88 0 1 24 -89 0 1 25 -89 0 1 38 -89 0 1 39 -89 0 1 320 -89 0 1 321 -89 0 1 334 -89 0 1 335 -89 0 1 24 -90 0 1 38 -90 0 1 321 -90 0 1 335 -90 0 1 23 -91 0 1 24 -91 0 1 37 -91 0 1 38 -91 0 1 321 -91 0 1 322 -91 0 1 335 -91 0 1 336 -91 0 1 22 -92 0 1 23 -92 0 1 37 -92 0 1 322 -92 0 1 336 -92 0 1 337 -92 0 1 22 -93 0 1 36 -93 0 1 37 -93 0 1 322 -93 0 1 323 -93 0 1 337 -93 0 1 21 -94 0 1 22 -94 0 1 35 -94 0 1 36 -94 0 1 323 -94 0 1 324 -94 0 1 337 -94 0 1 338 -94 0 1 21 -95 0 1 35 -95 0 1 324 -95 0 1 338 -95 0 1 20 -96 0 1 21 -96 0 1 34 -96 0 1 35 -96 0 1 213 -96 0 2 214 -96 0 2 215 -96 0 2 216 -96 0 2 217 -96 0 2 218 -96 0 2 219 -96 0 2 220 -96 0 2 221 -96 0 2 222 -96 0 2 223 -96 0 2 224 -96 0 2 225 -96 0 2 226 -96 0 2 227 -96 0 2 228 -96 0 2 229 -96 0 2 230 -96 0 2 324 -96 0 1 325 -96 0 1 338 -96 0 1 339 -96 0 1 20 -97 0 1 34 -97 0 1 210 -97 0 2 211 -97 0 2 212 -97 0 2 213 -97 0 2 230 -97 0 2 231 -97 0 2 232 -97 0 2 233 -97 0 2 325 -97 0 1 339 -97 0 1 19 -98 0 1 20 -98 0 1 33 -98 0 1 34 -98 0 1 209 -98 0 2 210 -98 0 2 233 -98 0 2 234 -98 0 2 325 -98 0 1 326 -98 0 1 339 -98 0 1 340 -98 0 1 19 -99 0 1 32 -99 0 1 33 -99 0 1 207 -99 0 2 208 -99 0 2 209 -99 0 2 234 -99 0 2 235 -99 0 2 236 -99 0 2 326 -99 0 1 327 -99 0 1 340 -99 0 1 18 -100 0 1 19 -100 0 1 32 -100 0 1 206 -100 0 2 207 -100 0 2 236 -100 0 2 237 -100 0 2 327 -100 0 1 340 -100 0 1 341 -100 0 1 18 -101 0 1 31 -101 0 1 32 -101 0 1 106 -101 0 2 107 -101 0 2 108 -101 0 2 109 -101 0 2 110 -101 0 2 111 -101 0 2 112 -101 0 2 113 -101 0 2 114 -101 0 2 115 -101 0 2 116 -101 0 2 204 -101 0 2 205 -101 0 2 206 -101 0 2 237 -101 0 2 238 -101 0 2 327 -101 0 1 328 -101 0 1 341 -101 0 1 17 -102 0 1 18 -102 0 1 31 -102 0 1 103 -102 0 2 104 -102 0 2 105 -102 0 2 106 -102 0 2 116 -102 0 2 117 -102 0 2 118 -102 0 2 119 -102 0 2 203 -102 0 2 204 -102 0 2 238 -102 0 2 239 -102 0 2 328 -102 0 1 341 -102 0 1 342 -102 0 1 17 -103 0 1 30 -103 0 1 31 -103 0 1 100 -103 0 2 101 -103 0 2 102 -103 0 2 103 -103 0 2 119 -103 0 2 120 -103 0 2 202 -103 0 2 203 -103 0 2 239 -103 0 2 328 -103 0 1 329 -103 0 1 342 -103 0 1 16 -104 0 1 17 -104 0 1 30 -104 0 1 99 -104 0 2 100 -104 0 2 120 -104 0 2 121 -104 0 2 122 -104 0 2 201 -104 0 2 202 -104 0 2 239 -104 0 2 240 -104 0 2 329 -104 0 1 342 -104 0 1 343 -104 0 1 16 -105 0 1 29 -105 0 1 30 -105 0 1 97 -105 0 2 98 -105 0 2 99 -105 0 2 122 -105 0 2 123 -105 0 2 200 -105 0 2 201 -105 0 2 240 -105 0 2 241 -105 0 2 329 -105 0 1 330 -105 0 1 343 -105 0 1 15 -106 0 1 16 -106 0 1 29 -106 0 1 96 -106 0 2 97 -106 0 2 123 -106 0 2 124 -106 0 2 200 -106 0 2 241 -106 0 2 330 -106 0 1 343 -106 0 1 344 -106 0 1 15 -107 0 1 28 -107 0 1 29 -107 0 1 95 -107 0 2 96 -107 0 2 124 -107 0 2 125 -107 0 2 199 -107 0 2 200 -107 0 2 241 -107 0 2 330 -107 0 1 331 -107 0 1 344 -107 0 1 15 -108 0 1 28 -108 0 1 94 -108 0 2 95 -108 0 2 125 -108 0 2 198 -108 0 2 199 -108 0 2 241 -108 0 2 242 -108 0 2 331 -108 0 1 344 -108 0 1 14 -109 0 1 15 -109 0 1 28 -109 0 1 94 -109 0 2 125 -109 0 2 126 -109 0 2 198 -109 0 2 242 -109 0 2 331 -109 0 1 344 -109 0 1 345 -109 0 1 14 -110 0 1 27 -110 0 1 28 -110 0 1 93 -110 0 2 94 -110 0 2 126 -110 0 2 127 -110 0 2 198 -110 0 2 242 -110 0 2 331 -110 0 1 332 -110 0 1 345 -110 0 1 13 -111 0 1 14 -111 0 1 27 -111 0 1 92 -111 0 2 93 -111 0 2 127 -111 0 2 197 -111 0 2 198 -111 0 2 242 -111 0 2 332 -111 0 1 345 -111 0 1 346 -111 0 1 13 -112 0 1 26 -112 0 1 27 -112 0 1 92 -112 0 2 127 -112 0 2 197 -112 0 2 242 -112 0 2 332 -112 0 1 333 -112 0 1 346 -112 0 1 12 -113 0 1 13 -113 0 1 26 -113 0 1 91 -113 0 2 92 -113 0 2 127 -113 0 2 128 -113 0 2 197 -113 0 2 242 -113 0 2 333 -113 0 1 346 -113 0 1 347 -113 0 1 12 -114 0 1 25 -114 0 1 26 -114 0 1 91 -114 0 2 128 -114 0 2 196 -114 0 2 197 -114 0 2 242 -114 0 2 333 -114 0 1 334 -114 0 1 347 -114 0 1 12 -115 0 1 25 -115 0 1 90 -115 0 2 91 -115 0 2 128 -115 0 2 195 -115 0 2 196 -115 0 2 242 -115 0 2 334 -115 0 1 347 -115 0 1 11 -116 0 1 12 -116 0 1 24 -116 0 1 25 -116 0 1 90 -116 0 2 128 -116 0 2 195 -116 0 2 242 -116 0 2 334 -116 0 1 347 -116 0 1 348 -116 0 1 11 -117 0 1 24 -117 0 1 89 -117 0 2 90 -117 0 2 128 -117 0 2 194 -117 0 2 195 -117 0 2 242 -117 0 2 334 -117 0 1 335 -117 0 1 348 -117 0 1 11 -118 0 1 24 -118 0 1 89 -118 0 2 128 -118 0 2 193 -118 0 2 194 -118 0 2 241 -118 0 2 242 -118 0 2 335 -118 0 1 348 -118 0 1 10 -119 0 1 11 -119 0 1 23 -119 0 1 24 -119 0 1 88 -119 0 2 89 -119 0 2 128 -119 0 2 193 -119 0 2 241 -119 0 2 335 -119 0 1 336 -119 0 1 348 -119 0 1 349 -119 0 1 10 -120 0 1 23 -120 0 1 87 -120 0 2 88 -120 0 2 128 -120 0 2 193 -120 0 2 241 -120 0 2 336 -120 0 1 349 -120 0 1 10 -121 0 1 23 -121 0 1 87 -121 0 2 128 -121 0 2 192 -121 0 2 193 -121 0 2 240 -121 0 2 241 -121 0 2 336 -121 0 1 349 -121 0 1 9 -122 0 1 10 -122 0 1 22 -122 0 1 23 -122 0 1 87 -122 0 2 128 -122 0 2 192 -122 0 2 239 -122 0 2 240 -122 0 2 336 -122 0 1 337 -122 0 1 349 -122 0 1 350 -122 0 1 9 -123 0 1 22 -123 0 1 86 -123 0 2 87 -123 0 2 127 -123 0 2 128 -123 0 2 192 -123 0 2 239 -123 0 2 337 -123 0 1 350 -123 0 1 9 -124 0 1 21 -124 0 1 22 -124 0 1 86 -124 0 2 127 -124 0 2 192 -124 0 2 238 -124 0 2 239 -124 0 2 337 -124 0 1 338 -124 0 1 350 -124 0 1 8 -125 0 1 9 -125 0 1 21 -125 0 1 86 -125 0 2 127 -125 0 2 192 -125 0 2 237 -125 0 2 238 -125 0 2 338 -125 0 1 350 -125 0 1 351 -125 0 1 8 -126 0 1 21 -126 0 1 86 -126 0 2 126 -126 0 2 127 -126 0 2 192 -126 0 2 236 -126 0 2 237 -126 0 2 338 -126 0 1 351 -126 0 1 8 -127 0 1 20 -127 0 1 21 -127 0 1 86 -127 0 2 125 -127 0 2 126 -127 0 2 192 -127 0 2 234 -127 0 2 235 -127 0 2 236 -127 0 2 338 -127 0 1 339 -127 0 1 351 -127 0 1 7 -128 0 1 8 -128 0 1 20 -128 0 1 86 -128 0 2 125 -128 0 2 192 -128 0 2 233 -128 0 2 234 -128 0 2 339 -128 0 1 351 -128 0 1 352 -128 0 1 7 -129 0 1 20 -129 0 1 86 -129 0 2 124 -129 0 2 125 -129 0 2 192 -129 0 2 230 -129 0 2 231 -129 0 2 232 -129 0 2 233 -129 0 2 339 -129 0 1 352 -129 0 1 7 -130 0 1 20 -130 0 1 86 -130 0 2 123 -130 0 2 124 -130 0 2 192 -130 0 2 229 -130 0 2 230 -130 0 2 339 -130 0 1 352 -130 0 1 6 -131 0 1 7 -131 0 1 19 -131 0 1 20 -131 0 1 86 -131 0 2 122 -131 0 2 123 -131 0 2 192 -131 0 2 229 -131 0 2 339 -131 0 1 340 -131 0 1 352 -131 0 1 353 -131 0 1 6 -132 0 1 19 -132 0 1 86 -132 0 2 122 -132 0 2 192 -132 0 2 229 -132 0 2 340 -132 0 1 353 -132 0 1 6 -133 0 1 19 -133 0 1 86 -133 0 2 121 -133 0 2 122 -133 0 2 192 -133 0 2 228 -133 0 2 229 -133 0 2 340 -133 0 1 353 -133 0 1 6 -134 0 1 18 -134 0 1 19 -134 0 1 86 -134 0 2 120 -134 0 2 121 -134 0 2 192 -134 0 2 228 -134 0 2 340 -134 0 1 341 -134 0 1 353 -134 0 1 5 -135 0 1 6 -135 0 1 18 -135 0 1 86 -135 0 2 120 -135 0 2 192 -135 0 2 228 -135 0 2 341 -135 0 1 353 -135 0 1 354 -135 0 1 5 -136 0 1 18 -136 0 1 86 -136 0 2 120 -136 0 2 192 -136 0 2 228 -136 0 2 341 -136 0 1 354 -136 0 1 5 -137 0 1 18 -137 0 1 86 -137 0 2 120 -137 0 2 192 -137 0 2 227 -137 0 2 228 -137 0 2 341 -137 0 1 354 -137 0 1 5 -138 0 1 17 -138 0 1 18 -138 0 1 86 -138 0 2 120 -138 0 2 192 -138 0 2 227 -138 0 2 341 -138 0 1 342 -138 0 1 354 -138 0 1 4 -139 0 1 5 -139 0 1 17 -139 0 1 86 -139 0 2 120 -139 0 2 192 -139 0 2 227 -139 0 2 342 -139 0 1 354 -139 0 1 355 -139 0 1 4 -140 0 1 17 -140 0 1 86 -140 0 2 120 -140 0 2 192 -140 0 2 227 -140 0 2 342 -140 0 1 355 -140 0 1 4 -141 0 1 17 -141 0 1 86 -141 0 2 120 -141 0 2 121 -141 0 2 192 -141 0 2 227 -141 0 2 342 -141 0 1 355 -141 0 1 4 -142 0 1 16 -142 0 1 17 -142 0 1 86 -142 0 2 121 -142 0 2 192 -142 0 2 227 -142 0 2 342 -142 0 1 343 -142 0 1 355 -142 0 1 4 -143 0 1 16 -143 0 1 86 -143 0 2 121 -143 0 2 192 -143 0 2 227 -143 0 2 228 -143 0 2 343 -143 0 1 355 -143 0 1 356 -143 0 1 3 -144 0 1 4 -144 0 1 16 -144 0 1 86 -144 0 2 121 -144 0 2 122 -144 0 2 192 -144 0 2 228 -144 0 2 343 -144 0 1 356 -144 0 1 3 -145 0 1 16 -145 0 1 86 -145 0 2 122 -145 0 2 192 -145 0 2 228 -145 0 2 343 -145 0 1 356 -145 0 1 3 -146 0 1 16 -146 0 1 86 -146 0 2 122 -146 0 2 123 -146 0 2 192 -146 0 2 228 -146 0 2 229 -146 0 2 343 -146 0 1 356 -146 0 1 3 -147 0 1 15 -147 0 1 16 -147 0 1 86 -147 0 2 123 -147 0 2 192 -147 0 2 193 -147 0 2 229 -147 0 2 343 -147 0 1 344 -147 0 1 356 -147 0 1 3 -148 0 1 15 -148 0 1 86 -148 0 2 123 -148 0 2 193 -148 0 2 229 -148 0 2 344 -148 0 1 356 -148 0 1 2 -149 0 1 3 -149 0 1 15 -149 0 1 86 -149 0 2 123 -149 0 2 124 -149 0 2 193 -149 0 2 229 -149 0 2 230 -149 0 2 344 -149 0 1 356 -149 0 1 357 -149 0 1 2 -150 0 1 15 -150 0 1 86 -150 0 2 124 -150 0 2 193 -150 0 2 230 -150 0 2 344 -150 0 1 357 -150 0 1 2 -151 0 1 15 -151 0 1 86 -151 0 2 87 -151 0 2 124 -151 0 2 193 -151 0 2 230 -151 0 2 344 -151 0 1 357 -151 0 1 2 -152 0 1 14 -152 0 1 15 -152 0 1 87 -152 0 2 124 -152 0 2 193 -152 0 2 230 -152 0 2 344 -152 0 1 345 -152 0 1 357 -152 0 1 2 -153 0 1 14 -153 0 1 87 -153 0 2 124 -153 0 2 193 -153 0 2 194 -153 0 2 230 -153 0 2 345 -153 0 1 357 -153 0 1 2 -154 0 1 14 -154 0 1 87 -154 0 2 88 -154 0 2 124 -154 0 2 194 -154 0 2 230 -154 0 2 345 -154 0 1 357 -154 0 1 2 -155 0 1 14 -155 0 1 88 -155 0 2 124 -155 0 2 194 -155 0 2 230 -155 0 2 345 -155 0 1 357 -155 0 1 1 -156 0 1 2 -156 0 1 14 -156 0 1 88 -156 0 2 124 -156 0 2 194 -156 0 2 230 -156 0 2 345 -156 0 1 357 -156 0 1 358 -156 0 1 1 -157 0 1 14 -157 0 1 88 -157 0 2 89 -157 0 2 124 -157 0 2 194 -157 0 2 230 -157 0 2 345 -157 0 1 358 -157 0 1 1 -158 0 1 14 -158 0 1 89 -158 0 2 124 -158 0 2 194 -158 0 2 195 -158 0 2 230 -158 0 2 345 -158 0 1 358 -158 0 1 1 -159 0 1 13 -159 0 1 14 -159 0 1 89 -159 0 2 124 -159 0 2 195 -159 0 2 229 -159 0 2 230 -159 0 2 345 -159 0 1 346 -159 0 1 358 -159 0 1 1 -160 0 1 13 -160 0 1 89 -160 0 2 90 -160 0 2 124 -160 0 2 195 -160 0 2 229 -160 0 2 346 -160 0 1 358 -160 0 1 1 -161 0 1 13 -161 0 1 90 -161 0 2 123 -161 0 2 124 -161 0 2 195 -161 0 2 196 -161 0 2 229 -161 0 2 346 -161 0 1 358 -161 0 1 1 -162 0 1 13 -162 0 1 90 -162 0 2 91 -162 0 2 123 -162 0 2 196 -162 0 2 197 -162 0 2 228 -162 0 2 229 -162 0 2 346 -162 0 1 358 -162 0 1 1 -163 0 1 13 -163 0 1 91 -163 0 2 123 -163 0 2 197 -163 0 2 227 -163 0 2 228 -163 0 2 346 -163 0 1 358 -163 0 1 1 -164 0 1 13 -164 0 1 91 -164 0 2 92 -164 0 2 122 -164 0 2 123 -164 0 2 197 -164 0 2 198 -164 0 2 227 -164 0 2 346 -164 0 1 358 -164 0 1 0 -165 0 1 1 -165 0 1 13 -165 0 1 92 -165 0 2 93 -165 0 2 121 -165 0 2 122 -165 0 2 198 -165 0 2 199 -165 0 2 226 -165 0 2 227 -165 0 2 346 -165 0 1 358 -165 0 1 359 -165 0 1 13 -166 0 1 93 -166 0 2 121 -166 0 2 199 -166 0 2 200 -166 0 2 225 -166 0 2 226 -166 0 2 346 -166 0 1 13 -167 0 1 93 -167 0 2 94 -167 0 2 120 -167 0 2 121 -167 0 2 200 -167 0 2 201 -167 0 2 224 -167 0 2 225 -167 0 2 346 -167 0 1 13 -168 0 1 94 -168 0 2 95 -168 0 2 119 -168 0 2 120 -168 0 2 201 -168 0 2 202 -168 0 2 203 -168 0 2 222 -168 0 2 223 -168 0 2 224 -168 0 2 346 -168 0 1 13 -169 0 1 95 -169 0 2 96 -169 0 2 118 -169 0 2 119 -169 0 2 203 -169 0 2 204 -169 0 2 221 -169 0 2 222 -169 0 2 346 -169 0 1 13 -170 0 1 96 -170 0 2 97 -170 0 2 98 -170 0 2 116 -170 0 2 117 -170 0 2 118 -170 0 2 204 -170 0 2 205 -170 0 2 206 -170 0 2 207 -170 0 2 218 -170 0 2 219 -170 0 2 220 -170 0 2 221 -170 0 2 346 -170 0 1 13 -171 0 1 98 -171 0 2 99 -171 0 2 115 -171 0 2 116 -171 0 2 207 -171 0 2 208 -171 0 2 209 -171 0 2 210 -171 0 2 211 -171 0 2 212 -171 0 2 213 -171 0 2 214 -171 0 2 215 -171 0 2 216 -171 0 2 217 -171 0 2 218 -171 0 2 346 -171 0 1 12 -172 0 1 13 -172 0 1 99 -172 0 2 100 -172 0 2 101 -172 0 2 102 -172 0 2 112 -172 0 2 113 -172 0 2 114 -172 0 2 115 -172 0 2 346 -172 0 1 347 -172 0 1 12 -173 0 1 102 -173 0 2 103 -173 0 2 104 -173 0 2 105 -173 0 2 106 -173 0 2 107 -173 0 2 108 -173 0 2 109 -173 0 2 110 -173 0 2 111 -173 0 2 112 -173 0 2 347 -173 0 1 12 -174 0 1 347 -174 0 1 12 -175 0 1 347 -175 0 1 12 -176 0 1 347 -176 0 1 12 -177 0 1 347 -177 0 1 12 -178 0 1 347 -178 0 1 12 -179 0 1 347 -179 0 1 12 -180 0 1 347 -180 0 1 12 -181 0 1 347 -181 0 1 12 -182 0 1 347 -182 0 1 12 -183 0 1 347 -183 0 1 12 -184 0 1 347 -184 0 1 12 -185 0 1 347 -185 0 1 12 -186 0 1 347 -186 0 1 12 -187 0 1 13 -187 0 1 346 -187 0 1 347 -187 0 1 13 -188 0 1 346 -188 0 1 13 -189 0 1 346 -189 0 1 13 -190 0 1 346 -190 0 1 13 -191 0 1 346 -191 0 1 13 -192 0 1 346 -192 0 1 13 -193 0 1 346 -193 0 1 0 -194 0 1 1 -194 0 1 13 -194 0 1 346 -194 0 1 358 -194 0 1 359 -194 0 1 1 -195 0 1 13 -195 0 1 346 -195 0 1 358 -195 0 1 1 -196 0 1 13 -196 0 1 346 -196 0 1 358 -196 0 1 1 -197 0 1 13 -197 0 1 346 -197 0 1 358 -197 0 1 1 -198 0 1 13 -198 0 1 346 -198 0 1 358 -198 0 1 1 -199 0 1 13 -199 0 1 346 -199 0 1 358 -199 0 1 1 -200 0 1 13 -200 0 1 14 -200 0 1 345 -200 0 1 346 -200 0 1 358 -200 0 1 1 -201 0 1 14 -201 0 1 345 -201 0 1 358 -201 0 1 1 -202 0 1 14 -202 0 1 345 -202 0 1 358 -202 0 1 1 -203 0 1 2 -203 0 1 14 -203 0 1 345 -203 0 1 357 -203 0 1 358 -203 0 1 2 -204 0 1 14 -204 0 1 345 -204 0 1 357 -204 0 1 2 -205 0 1 14 -205 0 1 154 -205 0 4 155 -205 0 4 156 -205 0 4 157 -205 0 4 158 -205 0 4 159 -205 0 4 160 -205 0 4 161 -205 0 4 162 -205 0 4 163 -205 0 4 164 -205 0 4 165 -205 0 4 166 -205 0 4 167 -205 0 4 168 -205 0 4 169 -205 0 4 170 -205 0 4 171 -205 0 4 172 -205 0 4 173 -205 0 4 174 -205 0 4 175 -205 0 4 345 -205 0 1 357 -205 0 1 2 -206 0 1 14 -206 0 1 151 -206 0 4 152 -206 0 4 153 -206 0 4 154 -206 0 4 175 -206 0 4 176 -206 0 4 177 -206 0 4 178 -206 0 4 179 -206 0 4 180 -206 0 4 181 -206 0 4 345 -206 0 1 357 -206 0 1 2 -207 0 1 14 -207 0 1 15 -207 0 1 148 -207 0 4 149 -207 0 4 150 -207 0 4 151 -207 0 4 181 -207 0 4 182 -207 0 4 183 -207 0 4 344 -207 0 1 345 -207 0 1 357 -207 0 1 2 -208 0 1 15 -208 0 1 147 -208 0 4 148 -208 0 4 183 -208 0 4 184 -208 0 4 185 -208 0 4 344 -208 0 1 357 -208 0 1 2 -209 0 1 15 -209 0 1 146 -209 0 4 147 -209 0 4 185 -209 0 4 186 -209 0 4 344 -209 0 1 357 -209 0 1 2 -210 0 1 3 -210 0 1 15 -210 0 1 145 -210 0 4 146 -210 0 4 186 -210 0 4 187 -210 0 4 344 -210 0 1 356 -210 0 1 357 -210 0 1 3 -211 0 1 15 -211 0 1 144 -211 0 4 145 -211 0 4 187 -211 0 4 188 -211 0 4 189 -211 0 4 344 -211 0 1 356 -211 0 1 3 -212 0 1 15 -212 0 1 16 -212 0 1 143 -212 0 4 144 -212 0 4 189 -212 0 4 190 -212 0 4 191 -212 0 4 192 -212 0 4 193 -212 0 4 194 -212 0 4 195 -212 0 4 343 -212 0 1 344 -212 0 1 356 -212 0 1 3 -213 0 1 16 -213 0 1 141 -213 0 4 142 -213 0 4 143 -213 0 4 195 -213 0 4 196 -213 0 4 197 -213 0 4 198 -213 0 4 343 -213 0 1 356 -213 0 1 3 -214 0 1 16 -214 0 1 133 -214 0 4 134 -214 0 4 135 -214 0 4 136 -214 0 4 137 -214 0 4 138 -214 0 4 139 -214 0 4 140 -214 0 4 141 -214 0 4 198 -214 0 4 199 -214 0 4 200 -214 0 4 201 -214 0 4 343 -214 0 1 356 -214 0 1 3 -215 0 1 16 -215 0 1 131 -215 0 4 132 -215 0 4 133 -215 0 4 201 -215 0 4 202 -215 0 4 203 -215 0 4 343 -215 0 1 355 -215 0 1 356 -215 0 1 3 -216 0 1 4 -216 0 1 16 -216 0 1 121 -216 0 4 122 -216 0 4 123 -216 0 4 124 -216 0 4 125 -216 0 4 126 -216 0 4 127 -216 0 4 128 -216 0 4 129 -216 0 4 130 -216 0 4 131 -216 0 4 203 -216 0 4 204 -216 0 4 205 -216 0 4 206 -216 0 4 207 -216 0 4 208 -216 0 4 343 -216 0 1 355 -216 0 1 4 -217 0 1 16 -217 0 1 17 -217 0 1 120 -217 0 4 121 -217 0 4 208 -217 0 4 209 -217 0 4 210 -217 0 4 211 -217 0 4 212 -217 0 4 213 -217 0 4 342 -217 0 1 343 -217 0 1 355 -217 0 1 4 -218 0 1 17 -218 0 1 118 -218 0 4 119 -218 0 4 120 -218 0 4 213 -218 0 4 214 -218 0 4 215 -218 0 4 245 -218 0 4 342 -218 0 1 355 -218 0 1 4 -219 0 1 17 -219 0 1 116 -219 0 4 117 -219 0 4 118 -219 0 4 215 -219 0 4 216 -219 0 4 217 -219 0 4 218 -219 0 4 219 -219 0 4 220 -219 0 4 221 -219 0 4 222 -219 0 4 244 -219 0 4 245 -219 0 4 246 -219 0 4 342 -219 0 1 355 -219 0 1 4 -220 0 1 5 -220 0 1 17 -220 0 1 114 -220 0 4 115 -220 0 4 116 -220 0 4 222 -220 0 4 223 -220 0 4 224 -220 0 4 225 -220 0 4 242 -220 0 4 243 -220 0 4 244 -220 0 4 246 -220 0 4 247 -220 0 4 342 -220 0 1 354 -220 0 1 355 -220 0 1 5 -221 0 1 17 -221 0 1 18 -221 0 1 111 -221 0 4 112 -221 0 4 113 -221 0 4 114 -221 0 4 225 -221 0 4 226 -221 0 4 227 -221 0 4 228 -221 0 4 229 -221 0 4 230 -221 0 4 231 -221 0 4 232 -221 0 4 233 -221 0 4 234 -221 0 4 235 -221 0 4 236 -221 0 4 237 -221 0 4 238 -221 0 4 239 -221 0 4 240 -221 0 4 241 -221 0 4 242 -221 0 4 247 -221 0 4 341 -221 0 1 342 -221 0 1 354 -221 0 1 5 -222 0 1 18 -222 0 1 111 -222 0 4 247 -222 0 4 248 -222 0 4 341 -222 0 1 354 -222 0 1 5 -223 0 1 18 -223 0 1 110 -223 0 4 111 -223 0 4 248 -223 0 4 341 -223 0 1 354 -223 0 1 5 -224 0 1 6 -224 0 1 18 -224 0 1 109 -224 0 4 110 -224 0 4 248 -224 0 4 341 -224 0 1 353 -224 0 1 354 -224 0 1 6 -225 0 1 18 -225 0 1 19 -225 0 1 108 -225 0 4 109 -225 0 4 248 -225 0 4 340 -225 0 1 341 -225 0 1 353 -225 0 1 6 -226 0 1 19 -226 0 1 107 -226 0 4 108 -226 0 4 248 -226 0 4 340 -226 0 1 353 -226 0 1 6 -227 0 1 19 -227 0 1 107 -227 0 4 143 -227 0 4 144 -227 0 4 145 -227 0 4 146 -227 0 4 147 -227 0 4 148 -227 0 4 149 -227 0 4 150 -227 0 4 151 -227 0 4 152 -227 0 4 153 -227 0 4 154 -227 0 4 155 -227 0 4 156 -227 0 4 157 -227 0 4 158 -227 0 4 159 -227 0 4 160 -227 0 4 248 -227 0 4 340 -227 0 1 353 -227 0 1 6 -228 0 1 7 -228 0 1 19 -228 0 1 20 -228 0 1 106 -228 0 4 107 -228 0 4 140 -228 0 4 141 -228 0 4 142 -228 0 4 143 -228 0 4 160 -228 0 4 161 -228 0 4 162 -228 0 4 163 -228 0 4 164 -228 0 4 248 -228 0 4 339 -228 0 1 340 -228 0 1 352 -228 0 1 353 -228 0 1 7 -229 0 1 20 -229 0 1 106 -229 0 4 136 -229 0 4 137 -229 0 4 138 -229 0 4 139 -229 0 4 140 -229 0 4 164 -229 0 4 165 -229 0 4 166 -229 0 4 248 -229 0 4 339 -229 0 1 352 -229 0 1 7 -230 0 1 20 -230 0 1 105 -230 0 4 106 -230 0 4 135 -230 0 4 136 -230 0 4 166 -230 0 4 167 -230 0 4 168 -230 0 4 169 -230 0 4 170 -230 0 4 171 -230 0 4 172 -230 0 4 173 -230 0 4 174 -230 0 4 175 -230 0 4 176 -230 0 4 177 -230 0 4 178 -230 0 4 179 -230 0 4 180 -230 0 4 181 -230 0 4 182 -230 0 4 183 -230 0 4 184 -230 0 4 248 -230 0 4 339 -230 0 1 352 -230 0 1 7 -231 0 1 8 -231 0 1 20 -231 0 1 104 -231 0 4 105 -231 0 4 134 -231 0 4 135 -231 0 4 184 -231 0 4 185 -231 0 4 186 -231 0 4 187 -231 0 4 188 -231 0 4 189 -231 0 4 190 -231 0 4 191 -231 0 4 192 -231 0 4 193 -231 0 4 248 -231 0 4 339 -231 0 1 351 -231 0 1 352 -231 0 1 8 -232 0 1 20 -232 0 1 21 -232 0 1 103 -232 0 4 104 -232 0 4 133 -232 0 4 134 -232 0 4 193 -232 0 4 194 -232 0 4 195 -232 0 4 196 -232 0 4 197 -232 0 4 198 -232 0 4 247 -232 0 4 248 -232 0 4 338 -232 0 1 339 -232 0 1 351 -232 0 1 8 -233 0 1 21 -233 0 1 102 -233 0 4 103 -233 0 4 132 -233 0 4 133 -233 0 4 198 -233 0 4 199 -233 0 4 200 -233 0 4 247 -233 0 4 338 -233 0 1 351 -233 0 1 8 -234 0 1 9 -234 0 1 21 -234 0 1 22 -234 0 1 101 -234 0 4 102 -234 0 4 130 -234 0 4 131 -234 0 4 132 -234 0 4 200 -234 0 4 201 -234 0 4 202 -234 0 4 203 -234 0 4 204 -234 0 4 205 -234 0 4 206 -234 0 4 207 -234 0 4 208 -234 0 4 209 -234 0 4 210 -234 0 4 211 -234 0 4 212 -234 0 4 213 -234 0 4 246 -234 0 4 247 -234 0 4 338 -234 0 1 350 -234 0 1 351 -234 0 1 9 -235 0 1 22 -235 0 1 101 -235 0 4 128 -235 0 4 129 -235 0 4 130 -235 0 4 213 -235 0 4 214 -235 0 4 215 -235 0 4 245 -235 0 4 246 -235 0 4 337 -235 0 1 338 -235 0 1 350 -235 0 1 9 -236 0 1 22 -236 0 1 100 -236 0 4 101 -236 0 4 127 -236 0 4 128 -236 0 4 215 -236 0 4 216 -236 0 4 244 -236 0 4 245 -236 0 4 337 -236 0 1 350 -236 0 1 9 -237 0 1 10 -237 0 1 22 -237 0 1 23 -237 0 1 100 -237 0 4 126 -237 0 4 127 -237 0 4 216 -237 0 4 217 -237 0 4 218 -237 0 4 243 -237 0 4 244 -237 0 4 336 -237 0 1 337 -237 0 1 349 -237 0 1 350 -237 0 1 10 -238 0 1 23 -238 0 1 99 -238 0 4 100 -238 0 4 124 -238 0 4 125 -238 0 4 126 -238 0 4 218 -238 0 4 219 -238 0 4 220 -238 0 4 221 -238 0 4 222 -238 0 4 223 -238 0 4 224 -238 0 4 242 -238 0 4 243 -238 0 4 336 -238 0 1 349 -238 0 1 10 -239 0 1 23 -239 0 1 99 -239 0 4 122 -239 0 4 123 -239 0 4 124 -239 0 4 224 -239 0 4 225 -239 0 4 241 -239 0 4 242 -239 0 4 336 -239 0 1 349 -239 0 1 10 -240 0 1 11 -240 0 1 23 -240 0 1 24 -240 0 1 98 -240 0 4 99 -240 0 4 121 -240 0 4 122 -240 0 4 225 -240 0 4 226 -240 0 4 227 -240 0 4 239 -240 0 4 240 -240 0 4 241 -240 0 4 335 -240 0 1 336 -240 0 1 348 -240 0 1 349 -240 0 1 11 -241 0 1 24 -241 0 1 97 -241 0 4 98 -241 0 4 120 -241 0 4 121 -241 0 4 227 -241 0 4 228 -241 0 4 229 -241 0 4 230 -241 0 4 231 -241 0 4 232 -241 0 4 233 -241 0 4 234 -241 0 4 235 -241 0 4 236 -241 0 4 237 -241 0 4 238 -241 0 4 239 -241 0 4 335 -241 0 1 348 -241 0 1 11 -242 0 1 24 -242 0 1 25 -242 0 1 96 -242 0 4 97 -242 0 4 119 -242 0 4 120 -242 0 4 335 -242 0 1 348 -242 0 1 11 -243 0 1 12 -243 0 1 25 -243 0 1 95 -243 0 4 96 -243 0 4 117 -243 0 4 118 -243 0 4 119 -243 0 4 334 -243 0 1 335 -243 0 1 347 -243 0 1 348 -243 0 1 12 -244 0 1 25 -244 0 1 94 -244 0 4 95 -244 0 4 117 -244 0 4 334 -244 0 1 347 -244 0 1 12 -245 0 1 13 -245 0 1 25 -245 0 1 26 -245 0 1 94 -245 0 4 116 -245 0 4 117 -245 0 4 333 -245 0 1 334 -245 0 1 347 -245 0 1 13 -246 0 1 26 -246 0 1 93 -246 0 4 94 -246 0 4 115 -246 0 4 116 -246 0 4 333 -246 0 1 346 -246 0 1 347 -246 0 1 13 -247 0 1 26 -247 0 1 27 -247 0 1 92 -247 0 4 93 -247 0 4 114 -247 0 4 115 -247 0 4 332 -247 0 1 333 -247 0 1 346 -247 0 1 13 -248 0 1 14 -248 0 1 27 -248 0 1 91 -248 0 4 92 -248 0 4 113 -248 0 4 114 -248 0 4 332 -248 0 1 345 -248 0 1 346 -248 0 1 14 -249 0 1 27 -249 0 1 28 -249 0 1 90 -249 0 4 91 -249 0 4 112 -249 0 4 113 -249 0 4 331 -249 0 1 332 -249 0 1 345 -249 0 1 14 -250 0 1 15 -250 0 1 28 -250 0 1 89 -250 0 4 90 -250 0 4 111 -250 0 4 112 -250 0 4 331 -250 0 1 344 -250 0 1 345 -250 0 1 15 -251 0 1 28 -251 0 1 88 -251 0 4 89 -251 0 4 109 -251 0 4 110 -251 0 4 111 -251 0 4 331 -251 0 1 344 -251 0 1 15 -252 0 1 28 -252 0 1 29 -252 0 1 87 -252 0 4 88 -252 0 4 107 -252 0 4 108 -252 0 4 109 -252 0 4 330 -252 0 1 331 -252 0 1 344 -252 0 1 15 -253 0 1 16 -253 0 1 29 -253 0 1 88 -253 0 4 89 -253 0 4 105 -253 0 4 106 -253 0 4 107 -253 0 4 330 -253 0 1 343 -253 0 1 344 -253 0 1 16 -254 0 1 29 -254 0 1 30 -254 0 1 89 -254 0 4 90 -254 0 4 104 -254 0 4 105 -254 0 4 329 -254 0 1 330 -254 0 1 343 -254 0 1 16 -255 0 1 17 -255 0 1 30 -255 0 1 90 -255 0 4 91 -255 0 4 92 -255 0 4 102 -255 0 4 103 -255 0 4 104 -255 0 4 329 -255 0 1 342 -255 0 1 343 -255 0 1 17 -256 0 1 30 -256 0 1 31 -256 0 1 92 -256 0 4 93 -256 0 4 94 -256 0 4 95 -256 0 4 96 -256 0 4 97 -256 0 4 98 -256 0 4 99 -256 0 4 100 -256 0 4 101 -256 0 4 102 -256 0 4 328 -256 0 1 329 -256 0 1 342 -256 0 1 17 -257 0 1 18 -257 0 1 31 -257 0 1 328 -257 0 1 341 -257 0 1 342 -257 0 1 18 -258 0 1 31 -258 0 1 32 -258 0 1 327 -258 0 1 328 -258 0 1 341 -258 0 1 18 -259 0 1 19 -259 0 1 32 -259 0 1 327 -259 0 1 340 -259 0 1 341 -259 0 1 19 -260 0 1 32 -260 0 1 33 -260 0 1 326 -260 0 1 327 -260 0 1 340 -260 0 1 19 -261 0 1 20 -261 0 1 33 -261 0 1 34 -261 0 1 325 -261 0 1 326 -261 0 1 339 -261 0 1 340 -261 0 1 20 -262 0 1 34 -262 0 1 325 -262 0 1 339 -262 0 1 20 -263 0 1 21 -263 0 1 34 -263 0 1 35 -263 0 1 324 -263 0 1 325 -263 0 1 338 -263 0 1 339 -263 0 1 21 -264 0 1 35 -264 0 1 324 -264 0 1 338 -264 0 1 21 -265 0 1 22 -265 0 1 35 -265 0 1 36 -265 0 1 323 -265 0 1 324 -265 0 1 337 -265 0 1 338 -265 0 1 22 -266 0 1 36 -266 0 1 37 -266 0 1 322 -266 0 1 323 -266 0 1 337 -266 0 1 22 -267 0 1 23 -267 0 1 37 -267 0 1 322 -267 0 1 336 -267 0 1 337 -267 0 1 23 -268 0 1 24 -268 0 1 37 -268 0 1 38 -268 0 1 321 -268 0 1 322 -268 0 1 335 -268 0 1 336 -268 0 1 24 -269 0 1 38 -269 0 1 321 -269 0 1 335 -269 0 1 24 -270 0 1 25 -270 0 1 38 -270 0 1 39 -270 0 1 320 -270 0 1 321 -270 0 1 334 -270 0 1 335 -270 0 1 25 -271 0 1 39 -271 0 1 40 -271 0 1 319 -271 0 1 320 -271 0 1 334 -271 0 1 25 -272 0 1 26 -272 0 1 40 -272 0 1 319 -272 0 1 333 -272 0 1 334 -272 0 1 26 -273 0 1 27 -273 0 1 40 -273 0 1 41 -273 0 1 318 -273 0 1 319 -273 0 1 332 -273 0 1 333 -273 0 1 27 -274 0 1 41 -274 0 1 42 -274 0 1 317 -274 0 1 318 -274 0 1 332 -274 0 1 27 -275 0 1 28 -275 0 1 42 -275 0 1 317 -275 0 1 331 -275 0 1 332 -275 0 1 28 -276 0 1 29 -276 0 1 42 -276 0 1 43 -276 0 1 316 -276 0 1 317 -276 0 1 330 -276 0 1 331 -276 0 1 29 -277 0 1 43 -277 0 1 44 -277 0 1 315 -277 0 1 316 -277 0 1 330 -277 0 1 29 -278 0 1 30 -278 0 1 44 -278 0 1 45 -278 0 1 314 -278 0 1 315 -278 0 1 329 -278 0 1 330 -278 0 1 30 -279 0 1 31 -279 0 1 45 -279 0 1 314 -279 0 1 328 -279 0 1 329 -279 0 1 31 -280 0 1 45 -280 0 1 46 -280 0 1 313 -280 0 1 314 -280 0 1 328 -280 0 1 31 -281 0 1 32 -281 0 1 46 -281 0 1 47 -281 0 1 312 -281 0 1 313 -281 0 1 327 -281 0 1 328 -281 0 1 32 -282 0 1 47 -282 0 1 48 -282 0 1 311 -282 0 1 312 -282 0 1 327 -282 0 1 32 -283 0 1 33 -283 0 1 48 -283 0 1 311 -283 0 1 326 -283 0 1 327 -283 0 1 33 -284 0 1 34 -284 0 1 48 -284 0 1 49 -284 0 1 310 -284 0 1 311 -284 0 1 325 -284 0 1 326 -284 0 1 34 -285 0 1 35 -285 0 1 49 -285 0 1 50 -285 0 1 309 -285 0 1 310 -285 0 1 324 -285 0 1 325 -285 0 1 35 -286 0 1 50 -286 0 1 51 -286 0 1 308 -286 0 1 309 -286 0 1 324 -286 0 1 35 -287 0 1 36 -287 0 1 51 -287 0 1 52 -287 0 1 307 -287 0 1 308 -287 0 1 323 -287 0 1 324 -287 0 1 36 -288 0 1 37 -288 0 1 52 -288 0 1 307 -288 0 1 322 -288 0 1 323 -288 0 1 37 -289 0 1 38 -289 0 1 52 -289 0 1 53 -289 0 1 54 -289 0 1 305 -289 0 1 306 -289 0 1 307 -289 0 1 321 -289 0 1 322 -289 0 1 38 -290 0 1 54 -290 0 1 305 -290 0 1 321 -290 0 1 38 -291 0 1 39 -291 0 1 54 -291 0 1 55 -291 0 1 304 -291 0 1 305 -291 0 1 320 -291 0 1 321 -291 0 1 39 -292 0 1 40 -292 0 1 55 -292 0 1 56 -292 0 1 303 -292 0 1 304 -292 0 1 319 -292 0 1 320 -292 0 1 40 -293 0 1 41 -293 0 1 56 -293 0 1 57 -293 0 1 302 -293 0 1 303 -293 0 1 318 -293 0 1 319 -293 0 1 41 -294 0 1 42 -294 0 1 57 -294 0 1 58 -294 0 1 301 -294 0 1 302 -294 0 1 317 -294 0 1 318 -294 0 1 42 -295 0 1 58 -295 0 1 59 -295 0 1 300 -295 0 1 301 -295 0 1 317 -295 0 1 42 -296 0 1 43 -296 0 1 59 -296 0 1 60 -296 0 1 299 -296 0 1 300 -296 0 1 316 -296 0 1 317 -296 0 1 43 -297 0 1 44 -297 0 1 60 -297 0 1 61 -297 0 1 298 -297 0 1 299 -297 0 1 315 -297 0 1 316 -297 0 1 44 -298 0 1 45 -298 0 1 61 -298 0 1 62 -298 0 1 297 -298 0 1 298 -298 0 1 314 -298 0 1 315 -298 0 1 45 -299 0 1 46 -299 0 1 62 -299 0 1 63 -299 0 1 296 -299 0 1 297 -299 0 1 313 -299 0 1 314 -299 0 1 46 -300 0 1 47 -300 0 1 63 -300 0 1 64 -300 0 1 295 -300 0 1 296 -300 0 1 312 -300 0 1 313 -300 0 1 47 -301 0 1 48 -301 0 1 64 -301 0 1 65 -301 0 1 294 -301 0 1 295 -301 0 1 311 -301 0 1 312 -301 0 1 48 -302 0 1 49 -302 0 1 65 -302 0 1 66 -302 0 1 293 -302 0 1 294 -302 0 1 310 -302 0 1 311 -302 0 1 49 -303 0 1 50 -303 0 1 66 -303 0 1 67 -303 0 1 292 -303 0 1 293 -303 0 1 309 -303 0 1 310 -303 0 1 50 -304 0 1 51 -304 0 1 67 -304 0 1 68 -304 0 1 291 -304 0 1 292 -304 0 1 308 -304 0 1 309 -304 0 1 51 -305 0 1 52 -305 0 1 68 -305 0 1 69 -305 0 1 70 -305 0 1 289 -305 0 1 290 -305 0 1 291 -305 0 1 307 -305 0 1 308 -305 0 1 52 -306 0 1 53 -306 0 1 70 -306 0 1 71 -306 0 1 288 -306 0 1 289 -306 0 1 306 -306 0 1 307 -306 0 1 53 -307 0 1 54 -307 0 1 71 -307 0 1 72 -307 0 1 287 -307 0 1 288 -307 0 1 305 -307 0 1 306 -307 0 1 54 -308 0 1 55 -308 0 1 72 -308 0 1 73 -308 0 1 286 -308 0 1 287 -308 0 1 304 -308 0 1 305 -308 0 1 55 -309 0 1 56 -309 0 1 73 -309 0 1 74 -309 0 1 285 -309 0 1 286 -309 0 1 303 -309 0 1 304 -309 0 1 56 -310 0 1 57 -310 0 1 74 -310 0 1 75 -310 0 1 284 -310 0 1 285 -310 0 1 302 -310 0 1 303 -310 0 1 57 -311 0 1 58 -311 0 1 75 -311 0 1 76 -311 0 1 77 -311 0 1 282 -311 0 1 283 -311 0 1 284 -311 0 1 301 -311 0 1 302 -311 0 1 58 -312 0 1 59 -312 0 1 77 -312 0 1 78 -312 0 1 281 -312 0 1 282 -312 0 1 300 -312 0 1 301 -312 0 1 59 -313 0 1 60 -313 0 1 78 -313 0 1 79 -313 0 1 280 -313 0 1 281 -313 0 1 299 -313 0 1 300 -313 0 1 60 -314 0 1 61 -314 0 1 79 -314 0 1 80 -314 0 1 81 -314 0 1 278 -314 0 1 279 -314 0 1 280 -314 0 1 298 -314 0 1 299 -314 0 1 61 -315 0 1 62 -315 0 1 81 -315 0 1 82 -315 0 1 277 -315 0 1 278 -315 0 1 297 -315 0 1 298 -315 0 1 62 -316 0 1 63 -316 0 1 82 -316 0 1 83 -316 0 1 276 -316 0 1 277 -316 0 1 296 -316 0 1 297 -316 0 1 63 -317 0 1 64 -317 0 1 65 -317 0 1 83 -317 0 1 84 -317 0 1 85 -317 0 1 274 -317 0 1 275 -317 0 1 276 -317 0 1 294 -317 0 1 295 -317 0 1 296 -317 0 1 65 -318 0 1 66 -318 0 1 85 -318 0 1 86 -318 0 1 273 -318 0 1 274 -318 0 1 293 -318 0 1 294 -318 0 1 66 -319 0 1 67 -319 0 1 86 -319 0 1 87 -319 0 1 88 -319 0 1 271 -319 0 1 272 -319 0 1 273 -319 0 1 292 -319 0 1 293 -319 0 1 67 -320 0 1 68 -320 0 1 88 -320 0 1 89 -320 0 1 270 -320 0 1 271 -320 0 1 291 -320 0 1 292 -320 0 1 68 -321 0 1 69 -321 0 1 70 -321 0 1 89 -321 0 1 90 -321 0 1 91 -321 0 1 268 -321 0 1 269 -321 0 1 270 -321 0 1 289 -321 0 1 290 -321 0 1 291 -321 0 1 70 -322 0 1 71 -322 0 1 91 -322 0 1 92 -322 0 1 93 -322 0 1 266 -322 0 1 267 -322 0 1 268 -322 0 1 288 -322 0 1 289 -322 0 1 71 -323 0 1 72 -323 0 1 93 -323 0 1 94 -323 0 1 265 -323 0 1 266 -323 0 1 287 -323 0 1 288 -323 0 1 72 -324 0 1 73 -324 0 1 74 -324 0 1 94 -324 0 1 95 -324 0 1 96 -324 0 1 263 -324 0 1 264 -324 0 1 265 -324 0 1 285 -324 0 1 286 -324 0 1 287 -324 0 1 74 -325 0 1 75 -325 0 1 96 -325 0 1 97 -325 0 1 98 -325 0 1 261 -325 0 1 262 -325 0 1 263 -325 0 1 284 -325 0 1 285 -325 0 1 75 -326 0 1 76 -326 0 1 98 -326 0 1 99 -326 0 1 100 -326 0 1 259 -326 0 1 260 -326 0 1 261 -326 0 1 283 -326 0 1 284 -326 0 1 76 -327 0 1 77 -327 0 1 78 -327 0 1 100 -327 0 1 101 -327 0 1 257 -327 0 1 258 -327 0 1 259 -327 0 1 281 -327 0 1 282 -327 0 1 283 -327 0 1 78 -328 0 1 79 -328 0 1 80 -328 0 1 101 -328 0 1 102 -328 0 1 103 -328 0 1 256 -328 0 1 257 -328 0 1 279 -328 0 1 280 -328 0 1 281 -328 0 1 80 -329 0 1 81 -329 0 1 103 -329 0 1 104 -329 0 1 105 -329 0 1 254 -329 0 1 255 -329 0 1 256 -329 0 1 278 -329 0 1 279 -329 0 1 81 -330 0 1 82 -330 0 1 83 -330 0 1 105 -330 0 1 106 -330 0 1 107 -330 0 1 252 -330 0 1 253 -330 0 1 254 -330 0 1 277 -330 0 1 278 -330 0 1 83 -331 0 1 84 -331 0 1 107 -331 0 1 108 -331 0 1 109 -331 0 1 110 -331 0 1 249 -331 0 1 250 -331 0 1 251 -331 0 1 252 -331 0 1 275 -331 0 1 276 -331 0 1 277 -331 0 1 84 -332 0 1 85 -332 0 1 86 -332 0 1 110 -332 0 1 111 -332 0 1 112 -332 0 1 247 -332 0 1 248 -332 0 1 249 -332 0 1 273 -332 0 1 274 -332 0 1 275 -332 0 1 86 -333 0 1 87 -333 0 1 112 -333 0 1 113 -333 0 1 114 -333 0 1 245 -333 0 1 246 -333 0 1 247 -333 0 1 272 -333 0 1 273 -333 0 1 87 -334 0 1 88 -334 0 1 89 -334 0 1 114 -334 0 1 115 -334 0 1 116 -334 0 1 243 -334 0 1 244 -334 0 1 245 -334 0 1 270 -334 0 1 271 -334 0 1 272 -334 0 1 89 -335 0 1 90 -335 0 1 91 -335 0 1 116 -335 0 1 117 -335 0 1 118 -335 0 1 119 -335 0 1 240 -335 0 1 241 -335 0 1 242 -335 0 1 243 -335 0 1 268 -335 0 1 269 -335 0 1 270 -335 0 1 91 -336 0 1 92 -336 0 1 93 -336 0 1 119 -336 0 1 120 -336 0 1 121 -336 0 1 122 -336 0 1 237 -336 0 1 238 -336 0 1 239 -336 0 1 240 -336 0 1 267 -336 0 1 268 -336 0 1 93 -337 0 1 94 -337 0 1 122 -337 0 1 123 -337 0 1 124 -337 0 1 235 -337 0 1 236 -337 0 1 237 -337 0 1 265 -337 0 1 266 -337 0 1 267 -337 0 1 94 -338 0 1 95 -338 0 1 96 -338 0 1 124 -338 0 1 125 -338 0 1 126 -338 0 1 127 -338 0 1 232 -338 0 1 233 -338 0 1 234 -338 0 1 235 -338 0 1 263 -338 0 1 264 -338 0 1 265 -338 0 1 96 -339 0 1 97 -339 0 1 98 -339 0 1 127 -339 0 1 128 -339 0 1 129 -339 0 1 130 -339 0 1 131 -339 0 1 228 -339 0 1 229 -339 0 1 230 -339 0 1 231 -339 0 1 232 -339 0 1 261 -339 0 1 262 -339 0 1 263 -339 0 1 98 -340 0 1 99 -340 0 1 100 -340 0 1 131 -340 0 1 132 -340 0 1 133 -340 0 1 134 -340 0 1 225 -340 0 1 226 -340 0 1 227 -340 0 1 228 -340 0 1 259 -340 0 1 260 -340 0 1 261 -340 0 1 100 -341 0 1 101 -341 0 1 102 -341 0 1 134 -341 0 1 135 -341 0 1 136 -341 0 1 137 -341 0 1 138 -341 0 1 221 -341 0 1 222 -341 0 1 223 -341 0 1 224 -341 0 1 225 -341 0 1 257 -341 0 1 258 -341 0 1 259 -341 0 1 102 -342 0 1 103 -342 0 1 104 -342 0 1 138 -342 0 1 139 -342 0 1 140 -342 0 1 141 -342 0 1 142 -342 0 1 217 -342 0 1 218 -342 0 1 219 -342 0 1 220 -342 0 1 221 -342 0 1 255 -342 0 1 256 -342 0 1 257 -342 0 1 104 -343 0 1 105 -343 0 1 106 -343 0 1 142 -343 0 1 143 -343 0 1 144 -343 0 1 145 -343 0 1 146 -343 0 1 147 -343 0 1 212 -343 0 1 213 -343 0 1 214 -343 0 1 215 -343 0 1 216 -343 0 1 217 -343 0 1 253 -343 0 1 254 -343 0 1 255 -343 0 1 106 -344 0 1 107 -344 0 1 108 -344 0 1 109 -344 0 1 147 -344 0 1 148 -344 0 1 149 -344 0 1 150 -344 0 1 151 -344 0 1 152 -344 0 1 207 -344 0 1 208 -344 0 1 209 -344 0 1 210 -344 0 1 211 -344 0 1 212 -344 0 1 250 -344 0 1 251 -344 0 1 252 -344 0 1 253 -344 0 1 109 -345 0 1 110 -345 0 1 111 -345 0 1 152 -345 0 1 153 -345 0 1 154 -345 0 1 155 -345 0 1 156 -345 0 1 157 -345 0 1 158 -345 0 1 159 -345 0 1 200 -345 0 1 201 -345 0 1 202 -345 0 1 203 -345 0 1 204 -345 0 1 205 -345 0 1 206 -345 0 1 207 -345 0 1 248 -345 0 1 249 -345 0 1 250 -345 0 1 111 -346 0 1 112 -346 0 1 113 -346 0 1 159 -346 0 1 160 -346 0 1 161 -346 0 1 162 -346 0 1 163 -346 0 1 164 -346 0 1 165 -346 0 1 166 -346 0 1 167 -346 0 1 168 -346 0 1 169 -346 0 1 170 -346 0 1 171 -346 0 1 187 -346 0 1 188 -346 0 1 189 -346 0 1 190 -346 0 1 191 -346 0 1 192 -346 0 1 193 -346 0 1 194 -346 0 1 195 -346 0 1 196 -346 0 1 197 -346 0 1 198 -346 0 1 199 -346 0 1 200 -346 0 1 246 -346 0 1 247 -346 0 1 248 -346 0 1 113 -347 0 1 114 -347 0 1 115 -347 0 1 116 -347 0 1 171 -347 0 1 172 -347 0 1 173 -347 0 1 174 -347 0 1 175 -347 0 1 176 -347 0 1 177 -347 0 1 178 -347 0 1 179 -347 0 1 180 -347 0 1 181 -347 0 1 182 -347 0 1 183 -347 0 1 184 -347 0 1 185 -347 0 1 186 -347 0 1 187 -347 0 1 243 -347 0 1 244 -347 0 1 245 -347 0 1 246 -347 0 1 116 -348 0 1 117 -348 0 1 118 -348 0 1 119 -348 0 1 240 -348 0 1 241 -348 0 1 242 -348 0 1 243 -348 0 1 119 -349 0 1 120 -349 0 1 121 -349 0 1 122 -349 0 1 237 -349 0 1 238 -349 0 1 239 -349 0 1 240 -349 0 1 122 -350 0 1 123 -350 0 1 124 -350 0 1 125 -350 0 1 234 -350 0 1 235 -350 0 1 236 -350 0 1 237 -350 0 1 125 -351 0 1 126 -351 0 1 127 -351 0 1 128 -351 0 1 231 -351 0 1 232 -351 0 1 233 -351 0 1 234 -351 0 1 128 -352 0 1 129 -352 0 1 130 -352 0 1 131 -352 0 1 228 -352 0 1 229 -352 0 1 230 -352 0 1 231 -352 0 1 131 -353 0 1 132 -353 0 1 133 -353 0 1 134 -353 0 1 135 -353 0 1 224 -353 0 1 225 -353 0 1 226 -353 0 1 227 -353 0 1 228 -353 0 1 135 -354 0 1 136 -354 0 1 137 -354 0 1 138 -354 0 1 139 -354 0 1 220 -354 0 1 221 -354 0 1 222 -354 0 1 223 -354 0 1 224 -354 0 1 139 -355 0 1 140 -355 0 1 141 -355 0 1 142 -355 0 1 143 -355 0 1 144 -355 0 1 216 -355 0 1 217 -355 0 1 218 -355 0 1 219 -355 0 1 220 -355 0 1 144 -356 0 1 145 -356 0 1 146 -356 0 1 147 -356 0 1 148 -356 0 1 149 -356 0 1 210 -356 0 1 211 -356 0 1 212 -356 0 1 213 -356 0 1 214 -356 0 1 215 -356 0 1 216 -356 0 1 149 -357 0 1 150 -357 0 1 151 -357 0 1 152 -357 0 1 153 -357 0 1 154 -357 0 1 155 -357 0 1 156 -357 0 1 203 -357 0 1 204 -357 0 1 205 -357 0 1 206 -357 0 1 207 -357 0 1 208 -357 0 1 209 -357 0 1 210 -357 0 1 156 -358 0 1 157 -358 0 1 158 -358 0 1 159 -358 0 1 160 -358 0 1 161 -358 0 1 162 -358 0 1 163 -358 0 1 164 -358 0 1 165 -358 0 1 195 -358 0 1 196 -358 0 1 197 -358 0 1 198 -358 0 1 199 -358 0 1 200 -358 0 1 201 -358 0 1 202 -358 0 1 203 -358 0 1 165 -359 0 1 195 -359 0 1 0 0 0 0 ants-1.9.2+svn680.dfsg/Examples/Data/Frown.vtk000066400000000000000000001416211147325206600207350ustar00rootroot00000000000000# vtk DataFile Version 2.0 File written by itkLabeledPointSetFileWriter ASCII DATASET POLYDATA POINTS 3743 float 164 0 0 195 0 0 156 -1 0 157 -1 0 158 -1 0 159 -1 0 160 -1 0 161 -1 0 162 -1 0 163 -1 0 164 -1 0 195 -1 0 196 -1 0 197 -1 0 198 -1 0 199 -1 0 200 -1 0 201 -1 0 202 -1 0 203 -1 0 149 -2 0 150 -2 0 151 -2 0 152 -2 0 153 -2 0 154 -2 0 155 -2 0 156 -2 0 203 -2 0 204 -2 0 205 -2 0 206 -2 0 207 -2 0 208 -2 0 209 -2 0 210 -2 0 143 -3 0 144 -3 0 145 -3 0 146 -3 0 147 -3 0 148 -3 0 149 -3 0 210 -3 0 211 -3 0 212 -3 0 213 -3 0 214 -3 0 215 -3 0 139 -4 0 140 -4 0 141 -4 0 142 -4 0 143 -4 0 215 -4 0 216 -4 0 217 -4 0 218 -4 0 219 -4 0 220 -4 0 135 -5 0 136 -5 0 137 -5 0 138 -5 0 139 -5 0 220 -5 0 221 -5 0 222 -5 0 223 -5 0 224 -5 0 131 -6 0 132 -6 0 133 -6 0 134 -6 0 135 -6 0 224 -6 0 225 -6 0 226 -6 0 227 -6 0 228 -6 0 128 -7 0 129 -7 0 130 -7 0 131 -7 0 228 -7 0 229 -7 0 230 -7 0 231 -7 0 125 -8 0 126 -8 0 127 -8 0 128 -8 0 231 -8 0 232 -8 0 233 -8 0 234 -8 0 122 -9 0 123 -9 0 124 -9 0 125 -9 0 234 -9 0 235 -9 0 236 -9 0 237 -9 0 119 -10 0 120 -10 0 121 -10 0 122 -10 0 237 -10 0 238 -10 0 239 -10 0 240 -10 0 116 -11 0 117 -11 0 118 -11 0 119 -11 0 240 -11 0 241 -11 0 242 -11 0 243 -11 0 113 -12 0 114 -12 0 115 -12 0 116 -12 0 172 -12 0 173 -12 0 174 -12 0 175 -12 0 176 -12 0 177 -12 0 178 -12 0 179 -12 0 180 -12 0 181 -12 0 182 -12 0 183 -12 0 184 -12 0 185 -12 0 186 -12 0 187 -12 0 243 -12 0 244 -12 0 245 -12 0 246 -12 0 111 -13 0 112 -13 0 113 -13 0 159 -13 0 160 -13 0 161 -13 0 162 -13 0 163 -13 0 164 -13 0 165 -13 0 166 -13 0 167 -13 0 168 -13 0 169 -13 0 170 -13 0 171 -13 0 172 -13 0 187 -13 0 188 -13 0 189 -13 0 190 -13 0 191 -13 0 192 -13 0 193 -13 0 194 -13 0 195 -13 0 196 -13 0 197 -13 0 198 -13 0 199 -13 0 200 -13 0 246 -13 0 247 -13 0 248 -13 0 109 -14 0 110 -14 0 111 -14 0 152 -14 0 153 -14 0 154 -14 0 155 -14 0 156 -14 0 157 -14 0 158 -14 0 159 -14 0 200 -14 0 201 -14 0 202 -14 0 203 -14 0 204 -14 0 205 -14 0 206 -14 0 207 -14 0 248 -14 0 249 -14 0 250 -14 0 106 -15 0 107 -15 0 108 -15 0 109 -15 0 147 -15 0 148 -15 0 149 -15 0 150 -15 0 151 -15 0 152 -15 0 207 -15 0 208 -15 0 209 -15 0 210 -15 0 211 -15 0 212 -15 0 250 -15 0 251 -15 0 252 -15 0 253 -15 0 36 -16 0 37 -16 0 38 -16 0 39 -16 0 40 -16 0 41 -16 0 42 -16 0 43 -16 0 44 -16 0 45 -16 0 46 -16 0 104 -16 0 105 -16 0 106 -16 0 142 -16 0 143 -16 0 144 -16 0 145 -16 0 146 -16 0 147 -16 0 212 -16 0 213 -16 0 214 -16 0 215 -16 0 216 -16 0 217 -16 0 253 -16 0 254 -16 0 255 -16 0 34 -17 0 35 -17 0 36 -17 0 46 -17 0 47 -17 0 48 -17 0 102 -17 0 103 -17 0 104 -17 0 138 -17 0 139 -17 0 140 -17 0 141 -17 0 142 -17 0 217 -17 0 218 -17 0 219 -17 0 220 -17 0 221 -17 0 255 -17 0 256 -17 0 257 -17 0 33 -18 0 34 -18 0 48 -18 0 49 -18 0 100 -18 0 101 -18 0 102 -18 0 134 -18 0 135 -18 0 136 -18 0 137 -18 0 138 -18 0 221 -18 0 222 -18 0 223 -18 0 224 -18 0 225 -18 0 257 -18 0 258 -18 0 259 -18 0 32 -19 0 33 -19 0 34 -19 0 35 -19 0 49 -19 0 50 -19 0 98 -19 0 99 -19 0 100 -19 0 131 -19 0 132 -19 0 133 -19 0 134 -19 0 225 -19 0 226 -19 0 227 -19 0 228 -19 0 259 -19 0 260 -19 0 261 -19 0 35 -20 0 36 -20 0 50 -20 0 51 -20 0 96 -20 0 97 -20 0 98 -20 0 127 -20 0 128 -20 0 129 -20 0 130 -20 0 131 -20 0 228 -20 0 229 -20 0 230 -20 0 231 -20 0 232 -20 0 261 -20 0 262 -20 0 263 -20 0 36 -21 0 51 -21 0 52 -21 0 94 -21 0 95 -21 0 96 -21 0 124 -21 0 125 -21 0 126 -21 0 127 -21 0 232 -21 0 233 -21 0 234 -21 0 235 -21 0 263 -21 0 264 -21 0 265 -21 0 36 -22 0 37 -22 0 52 -22 0 53 -22 0 54 -22 0 92 -22 0 93 -22 0 94 -22 0 122 -22 0 123 -22 0 124 -22 0 235 -22 0 236 -22 0 237 -22 0 265 -22 0 266 -22 0 37 -23 0 54 -23 0 55 -23 0 56 -23 0 57 -23 0 58 -23 0 59 -23 0 91 -23 0 92 -23 0 119 -23 0 120 -23 0 121 -23 0 122 -23 0 237 -23 0 238 -23 0 239 -23 0 240 -23 0 266 -23 0 267 -23 0 268 -23 0 37 -24 0 59 -24 0 60 -24 0 61 -24 0 62 -24 0 89 -24 0 90 -24 0 91 -24 0 116 -24 0 117 -24 0 118 -24 0 119 -24 0 240 -24 0 241 -24 0 242 -24 0 243 -24 0 268 -24 0 269 -24 0 270 -24 0 37 -25 0 38 -25 0 39 -25 0 62 -25 0 63 -25 0 64 -25 0 87 -25 0 88 -25 0 89 -25 0 114 -25 0 115 -25 0 116 -25 0 243 -25 0 244 -25 0 245 -25 0 270 -25 0 271 -25 0 272 -25 0 39 -26 0 64 -26 0 65 -26 0 86 -26 0 87 -26 0 112 -26 0 113 -26 0 114 -26 0 245 -26 0 246 -26 0 247 -26 0 272 -26 0 273 -26 0 39 -27 0 65 -27 0 66 -27 0 67 -27 0 84 -27 0 85 -27 0 86 -27 0 110 -27 0 111 -27 0 112 -27 0 247 -27 0 248 -27 0 249 -27 0 273 -27 0 274 -27 0 275 -27 0 323 -27 0 324 -27 0 325 -27 0 326 -27 0 327 -27 0 328 -27 0 329 -27 0 330 -27 0 331 -27 0 332 -27 0 39 -28 0 67 -28 0 68 -28 0 82 -28 0 83 -28 0 84 -28 0 107 -28 0 108 -28 0 109 -28 0 110 -28 0 249 -28 0 250 -28 0 251 -28 0 252 -28 0 275 -28 0 276 -28 0 314 -28 0 315 -28 0 316 -28 0 317 -28 0 318 -28 0 319 -28 0 320 -28 0 321 -28 0 322 -28 0 323 -28 0 330 -28 0 331 -28 0 39 -29 0 40 -29 0 68 -29 0 69 -29 0 81 -29 0 82 -29 0 105 -29 0 106 -29 0 107 -29 0 252 -29 0 253 -29 0 254 -29 0 276 -29 0 277 -29 0 278 -29 0 310 -29 0 311 -29 0 312 -29 0 313 -29 0 314 -29 0 330 -29 0 40 -30 0 41 -30 0 69 -30 0 70 -30 0 80 -30 0 81 -30 0 103 -30 0 104 -30 0 105 -30 0 254 -30 0 255 -30 0 256 -30 0 278 -30 0 279 -30 0 310 -30 0 329 -30 0 330 -30 0 41 -31 0 42 -31 0 43 -31 0 70 -31 0 71 -31 0 78 -31 0 79 -31 0 80 -31 0 102 -31 0 103 -31 0 256 -31 0 257 -31 0 279 -31 0 280 -31 0 281 -31 0 308 -31 0 309 -31 0 310 -31 0 329 -31 0 43 -32 0 44 -32 0 71 -32 0 72 -32 0 76 -32 0 77 -32 0 78 -32 0 100 -32 0 101 -32 0 102 -32 0 257 -32 0 258 -32 0 259 -32 0 281 -32 0 282 -32 0 283 -32 0 301 -32 0 302 -32 0 303 -32 0 304 -32 0 305 -32 0 306 -32 0 307 -32 0 308 -32 0 328 -32 0 329 -32 0 44 -33 0 72 -33 0 75 -33 0 76 -33 0 98 -33 0 99 -33 0 100 -33 0 259 -33 0 260 -33 0 261 -33 0 283 -33 0 284 -33 0 301 -33 0 328 -33 0 44 -34 0 72 -34 0 73 -34 0 74 -34 0 75 -34 0 96 -34 0 97 -34 0 98 -34 0 261 -34 0 262 -34 0 263 -34 0 284 -34 0 285 -34 0 300 -34 0 301 -34 0 328 -34 0 44 -35 0 94 -35 0 95 -35 0 96 -35 0 263 -35 0 264 -35 0 265 -35 0 285 -35 0 286 -35 0 287 -35 0 299 -35 0 300 -35 0 328 -35 0 44 -36 0 45 -36 0 46 -36 0 47 -36 0 93 -36 0 94 -36 0 265 -36 0 266 -36 0 287 -36 0 288 -36 0 298 -36 0 299 -36 0 328 -36 0 47 -37 0 91 -37 0 92 -37 0 93 -37 0 266 -37 0 267 -37 0 268 -37 0 288 -37 0 289 -37 0 297 -37 0 298 -37 0 328 -37 0 47 -38 0 89 -38 0 90 -38 0 91 -38 0 268 -38 0 269 -38 0 270 -38 0 289 -38 0 290 -38 0 291 -38 0 297 -38 0 327 -38 0 328 -38 0 47 -39 0 48 -39 0 88 -39 0 89 -39 0 270 -39 0 271 -39 0 291 -39 0 292 -39 0 296 -39 0 297 -39 0 327 -39 0 48 -40 0 86 -40 0 87 -40 0 88 -40 0 271 -40 0 272 -40 0 273 -40 0 292 -40 0 293 -40 0 296 -40 0 326 -40 0 327 -40 0 48 -41 0 85 -41 0 86 -41 0 273 -41 0 274 -41 0 293 -41 0 294 -41 0 295 -41 0 296 -41 0 326 -41 0 48 -42 0 49 -42 0 50 -42 0 83 -42 0 84 -42 0 85 -42 0 274 -42 0 275 -42 0 276 -42 0 324 -42 0 325 -42 0 326 -42 0 50 -43 0 82 -43 0 83 -43 0 276 -43 0 277 -43 0 324 -43 0 50 -44 0 81 -44 0 82 -44 0 277 -44 0 278 -44 0 324 -44 0 50 -45 0 79 -45 0 80 -45 0 81 -45 0 278 -45 0 279 -45 0 280 -45 0 324 -45 0 50 -46 0 78 -46 0 79 -46 0 280 -46 0 281 -46 0 324 -46 0 50 -47 0 77 -47 0 78 -47 0 281 -47 0 282 -47 0 324 -47 0 50 -48 0 75 -48 0 76 -48 0 77 -48 0 282 -48 0 283 -48 0 284 -48 0 324 -48 0 50 -49 0 74 -49 0 75 -49 0 284 -49 0 285 -49 0 324 -49 0 50 -50 0 51 -50 0 73 -50 0 74 -50 0 285 -50 0 286 -50 0 323 -50 0 324 -50 0 51 -51 0 52 -51 0 53 -51 0 72 -51 0 73 -51 0 286 -51 0 287 -51 0 322 -51 0 323 -51 0 53 -52 0 71 -52 0 72 -52 0 287 -52 0 288 -52 0 321 -52 0 322 -52 0 52 -53 0 53 -53 0 70 -53 0 71 -53 0 288 -53 0 289 -53 0 320 -53 0 321 -53 0 51 -54 0 52 -54 0 68 -54 0 69 -54 0 70 -54 0 289 -54 0 290 -54 0 320 -54 0 50 -55 0 51 -55 0 67 -55 0 68 -55 0 290 -55 0 320 -55 0 49 -56 0 50 -56 0 66 -56 0 67 -56 0 290 -56 0 291 -56 0 292 -56 0 320 -56 0 48 -57 0 49 -57 0 65 -57 0 66 -57 0 292 -57 0 319 -57 0 320 -57 0 47 -58 0 48 -58 0 64 -58 0 65 -58 0 292 -58 0 293 -58 0 319 -58 0 46 -59 0 47 -59 0 63 -59 0 64 -59 0 293 -59 0 294 -59 0 295 -59 0 296 -59 0 297 -59 0 318 -59 0 319 -59 0 45 -60 0 46 -60 0 62 -60 0 63 -60 0 297 -60 0 317 -60 0 318 -60 0 45 -61 0 61 -61 0 62 -61 0 297 -61 0 317 -61 0 43 -62 0 44 -62 0 45 -62 0 60 -62 0 61 -62 0 297 -62 0 317 -62 0 43 -63 0 59 -63 0 60 -63 0 297 -63 0 317 -63 0 43 -64 0 58 -64 0 59 -64 0 297 -64 0 298 -64 0 299 -64 0 300 -64 0 317 -64 0 40 -65 0 41 -65 0 42 -65 0 43 -65 0 57 -65 0 58 -65 0 300 -65 0 317 -65 0 318 -65 0 38 -66 0 39 -66 0 40 -66 0 56 -66 0 57 -66 0 300 -66 0 301 -66 0 302 -66 0 303 -66 0 318 -66 0 319 -66 0 38 -67 0 55 -67 0 56 -67 0 303 -67 0 319 -67 0 320 -67 0 38 -68 0 54 -68 0 55 -68 0 303 -68 0 304 -68 0 305 -68 0 320 -68 0 321 -68 0 36 -69 0 37 -69 0 38 -69 0 54 -69 0 305 -69 0 321 -69 0 36 -70 0 52 -70 0 53 -70 0 54 -70 0 305 -70 0 306 -70 0 307 -70 0 321 -70 0 322 -70 0 36 -71 0 52 -71 0 307 -71 0 322 -71 0 323 -71 0 35 -72 0 36 -72 0 51 -72 0 52 -72 0 307 -72 0 308 -72 0 323 -72 0 324 -72 0 35 -73 0 50 -73 0 51 -73 0 308 -73 0 309 -73 0 324 -73 0 34 -74 0 35 -74 0 49 -74 0 50 -74 0 309 -74 0 310 -74 0 324 -74 0 325 -74 0 33 -75 0 34 -75 0 48 -75 0 49 -75 0 310 -75 0 311 -75 0 325 -75 0 326 -75 0 32 -76 0 33 -76 0 48 -76 0 311 -76 0 326 -76 0 327 -76 0 32 -77 0 47 -77 0 48 -77 0 311 -77 0 312 -77 0 327 -77 0 31 -78 0 32 -78 0 46 -78 0 47 -78 0 312 -78 0 313 -78 0 327 -78 0 328 -78 0 31 -79 0 45 -79 0 46 -79 0 313 -79 0 314 -79 0 328 -79 0 30 -80 0 31 -80 0 45 -80 0 314 -80 0 328 -80 0 329 -80 0 29 -81 0 30 -81 0 44 -81 0 45 -81 0 314 -81 0 315 -81 0 329 -81 0 330 -81 0 29 -82 0 43 -82 0 44 -82 0 315 -82 0 316 -82 0 330 -82 0 28 -83 0 29 -83 0 42 -83 0 43 -83 0 316 -83 0 317 -83 0 330 -83 0 331 -83 0 27 -84 0 28 -84 0 42 -84 0 317 -84 0 331 -84 0 332 -84 0 27 -85 0 41 -85 0 42 -85 0 317 -85 0 318 -85 0 332 -85 0 26 -86 0 27 -86 0 40 -86 0 41 -86 0 318 -86 0 319 -86 0 332 -86 0 333 -86 0 25 -87 0 26 -87 0 40 -87 0 319 -87 0 333 -87 0 334 -87 0 25 -88 0 39 -88 0 40 -88 0 319 -88 0 320 -88 0 334 -88 0 24 -89 0 25 -89 0 38 -89 0 39 -89 0 320 -89 0 321 -89 0 334 -89 0 335 -89 0 24 -90 0 38 -90 0 321 -90 0 335 -90 0 23 -91 0 24 -91 0 37 -91 0 38 -91 0 321 -91 0 322 -91 0 335 -91 0 336 -91 0 22 -92 0 23 -92 0 37 -92 0 322 -92 0 336 -92 0 337 -92 0 22 -93 0 36 -93 0 37 -93 0 322 -93 0 323 -93 0 337 -93 0 21 -94 0 22 -94 0 35 -94 0 36 -94 0 323 -94 0 324 -94 0 337 -94 0 338 -94 0 21 -95 0 35 -95 0 324 -95 0 338 -95 0 20 -96 0 21 -96 0 34 -96 0 35 -96 0 213 -96 0 214 -96 0 215 -96 0 216 -96 0 217 -96 0 218 -96 0 219 -96 0 220 -96 0 221 -96 0 222 -96 0 223 -96 0 224 -96 0 225 -96 0 226 -96 0 227 -96 0 228 -96 0 229 -96 0 230 -96 0 324 -96 0 325 -96 0 338 -96 0 339 -96 0 20 -97 0 34 -97 0 210 -97 0 211 -97 0 212 -97 0 213 -97 0 230 -97 0 231 -97 0 232 -97 0 233 -97 0 325 -97 0 339 -97 0 19 -98 0 20 -98 0 33 -98 0 34 -98 0 209 -98 0 210 -98 0 233 -98 0 234 -98 0 325 -98 0 326 -98 0 339 -98 0 340 -98 0 19 -99 0 32 -99 0 33 -99 0 207 -99 0 208 -99 0 209 -99 0 234 -99 0 235 -99 0 236 -99 0 326 -99 0 327 -99 0 340 -99 0 18 -100 0 19 -100 0 32 -100 0 206 -100 0 207 -100 0 236 -100 0 237 -100 0 327 -100 0 340 -100 0 341 -100 0 18 -101 0 31 -101 0 32 -101 0 106 -101 0 107 -101 0 108 -101 0 109 -101 0 110 -101 0 111 -101 0 112 -101 0 113 -101 0 114 -101 0 115 -101 0 116 -101 0 204 -101 0 205 -101 0 206 -101 0 237 -101 0 238 -101 0 327 -101 0 328 -101 0 341 -101 0 17 -102 0 18 -102 0 31 -102 0 103 -102 0 104 -102 0 105 -102 0 106 -102 0 116 -102 0 117 -102 0 118 -102 0 119 -102 0 203 -102 0 204 -102 0 238 -102 0 239 -102 0 328 -102 0 341 -102 0 342 -102 0 17 -103 0 30 -103 0 31 -103 0 100 -103 0 101 -103 0 102 -103 0 103 -103 0 119 -103 0 120 -103 0 202 -103 0 203 -103 0 239 -103 0 328 -103 0 329 -103 0 342 -103 0 16 -104 0 17 -104 0 30 -104 0 99 -104 0 100 -104 0 120 -104 0 121 -104 0 122 -104 0 201 -104 0 202 -104 0 239 -104 0 240 -104 0 329 -104 0 342 -104 0 343 -104 0 16 -105 0 29 -105 0 30 -105 0 97 -105 0 98 -105 0 99 -105 0 122 -105 0 123 -105 0 200 -105 0 201 -105 0 240 -105 0 241 -105 0 329 -105 0 330 -105 0 343 -105 0 15 -106 0 16 -106 0 29 -106 0 96 -106 0 97 -106 0 123 -106 0 124 -106 0 200 -106 0 241 -106 0 330 -106 0 343 -106 0 344 -106 0 15 -107 0 28 -107 0 29 -107 0 95 -107 0 96 -107 0 124 -107 0 125 -107 0 199 -107 0 200 -107 0 241 -107 0 330 -107 0 331 -107 0 344 -107 0 15 -108 0 28 -108 0 94 -108 0 95 -108 0 125 -108 0 198 -108 0 199 -108 0 241 -108 0 242 -108 0 331 -108 0 344 -108 0 14 -109 0 15 -109 0 28 -109 0 94 -109 0 125 -109 0 126 -109 0 198 -109 0 242 -109 0 331 -109 0 344 -109 0 345 -109 0 14 -110 0 27 -110 0 28 -110 0 93 -110 0 94 -110 0 126 -110 0 127 -110 0 198 -110 0 242 -110 0 331 -110 0 332 -110 0 345 -110 0 13 -111 0 14 -111 0 27 -111 0 92 -111 0 93 -111 0 127 -111 0 197 -111 0 198 -111 0 242 -111 0 332 -111 0 345 -111 0 346 -111 0 13 -112 0 26 -112 0 27 -112 0 92 -112 0 127 -112 0 197 -112 0 242 -112 0 332 -112 0 333 -112 0 346 -112 0 12 -113 0 13 -113 0 26 -113 0 91 -113 0 92 -113 0 127 -113 0 128 -113 0 197 -113 0 242 -113 0 333 -113 0 346 -113 0 347 -113 0 12 -114 0 25 -114 0 26 -114 0 91 -114 0 128 -114 0 196 -114 0 197 -114 0 242 -114 0 333 -114 0 334 -114 0 347 -114 0 12 -115 0 25 -115 0 90 -115 0 91 -115 0 128 -115 0 195 -115 0 196 -115 0 242 -115 0 334 -115 0 347 -115 0 11 -116 0 12 -116 0 24 -116 0 25 -116 0 90 -116 0 128 -116 0 195 -116 0 242 -116 0 334 -116 0 347 -116 0 348 -116 0 11 -117 0 24 -117 0 89 -117 0 90 -117 0 128 -117 0 194 -117 0 195 -117 0 242 -117 0 334 -117 0 335 -117 0 348 -117 0 11 -118 0 24 -118 0 89 -118 0 128 -118 0 193 -118 0 194 -118 0 241 -118 0 242 -118 0 335 -118 0 348 -118 0 10 -119 0 11 -119 0 23 -119 0 24 -119 0 88 -119 0 89 -119 0 128 -119 0 193 -119 0 241 -119 0 335 -119 0 336 -119 0 348 -119 0 349 -119 0 10 -120 0 23 -120 0 87 -120 0 88 -120 0 128 -120 0 193 -120 0 241 -120 0 336 -120 0 349 -120 0 10 -121 0 23 -121 0 87 -121 0 128 -121 0 192 -121 0 193 -121 0 240 -121 0 241 -121 0 336 -121 0 349 -121 0 9 -122 0 10 -122 0 22 -122 0 23 -122 0 87 -122 0 128 -122 0 192 -122 0 239 -122 0 240 -122 0 336 -122 0 337 -122 0 349 -122 0 350 -122 0 9 -123 0 22 -123 0 86 -123 0 87 -123 0 127 -123 0 128 -123 0 192 -123 0 239 -123 0 337 -123 0 350 -123 0 9 -124 0 21 -124 0 22 -124 0 86 -124 0 127 -124 0 192 -124 0 238 -124 0 239 -124 0 337 -124 0 338 -124 0 350 -124 0 8 -125 0 9 -125 0 21 -125 0 86 -125 0 127 -125 0 192 -125 0 237 -125 0 238 -125 0 338 -125 0 350 -125 0 351 -125 0 8 -126 0 21 -126 0 86 -126 0 126 -126 0 127 -126 0 192 -126 0 236 -126 0 237 -126 0 338 -126 0 351 -126 0 8 -127 0 20 -127 0 21 -127 0 86 -127 0 125 -127 0 126 -127 0 192 -127 0 234 -127 0 235 -127 0 236 -127 0 338 -127 0 339 -127 0 351 -127 0 7 -128 0 8 -128 0 20 -128 0 86 -128 0 125 -128 0 192 -128 0 233 -128 0 234 -128 0 339 -128 0 351 -128 0 352 -128 0 7 -129 0 20 -129 0 86 -129 0 124 -129 0 125 -129 0 192 -129 0 230 -129 0 231 -129 0 232 -129 0 233 -129 0 339 -129 0 352 -129 0 7 -130 0 20 -130 0 86 -130 0 123 -130 0 124 -130 0 192 -130 0 229 -130 0 230 -130 0 339 -130 0 352 -130 0 6 -131 0 7 -131 0 19 -131 0 20 -131 0 86 -131 0 122 -131 0 123 -131 0 192 -131 0 229 -131 0 339 -131 0 340 -131 0 352 -131 0 353 -131 0 6 -132 0 19 -132 0 86 -132 0 122 -132 0 192 -132 0 229 -132 0 340 -132 0 353 -132 0 6 -133 0 19 -133 0 86 -133 0 121 -133 0 122 -133 0 192 -133 0 228 -133 0 229 -133 0 340 -133 0 353 -133 0 6 -134 0 18 -134 0 19 -134 0 86 -134 0 120 -134 0 121 -134 0 192 -134 0 228 -134 0 340 -134 0 341 -134 0 353 -134 0 5 -135 0 6 -135 0 18 -135 0 86 -135 0 120 -135 0 192 -135 0 228 -135 0 341 -135 0 353 -135 0 354 -135 0 5 -136 0 18 -136 0 86 -136 0 120 -136 0 192 -136 0 228 -136 0 341 -136 0 354 -136 0 5 -137 0 18 -137 0 86 -137 0 120 -137 0 192 -137 0 227 -137 0 228 -137 0 341 -137 0 354 -137 0 5 -138 0 17 -138 0 18 -138 0 86 -138 0 120 -138 0 192 -138 0 227 -138 0 341 -138 0 342 -138 0 354 -138 0 4 -139 0 5 -139 0 17 -139 0 86 -139 0 120 -139 0 192 -139 0 227 -139 0 342 -139 0 354 -139 0 355 -139 0 4 -140 0 17 -140 0 86 -140 0 120 -140 0 192 -140 0 227 -140 0 342 -140 0 355 -140 0 4 -141 0 17 -141 0 86 -141 0 120 -141 0 121 -141 0 192 -141 0 227 -141 0 342 -141 0 355 -141 0 4 -142 0 16 -142 0 17 -142 0 86 -142 0 121 -142 0 192 -142 0 227 -142 0 342 -142 0 343 -142 0 355 -142 0 4 -143 0 16 -143 0 86 -143 0 121 -143 0 192 -143 0 227 -143 0 228 -143 0 343 -143 0 355 -143 0 356 -143 0 3 -144 0 4 -144 0 16 -144 0 86 -144 0 121 -144 0 122 -144 0 192 -144 0 228 -144 0 343 -144 0 356 -144 0 3 -145 0 16 -145 0 86 -145 0 122 -145 0 192 -145 0 228 -145 0 343 -145 0 356 -145 0 3 -146 0 16 -146 0 86 -146 0 122 -146 0 123 -146 0 192 -146 0 228 -146 0 229 -146 0 343 -146 0 356 -146 0 3 -147 0 15 -147 0 16 -147 0 86 -147 0 123 -147 0 192 -147 0 193 -147 0 229 -147 0 343 -147 0 344 -147 0 356 -147 0 3 -148 0 15 -148 0 86 -148 0 123 -148 0 193 -148 0 229 -148 0 344 -148 0 356 -148 0 2 -149 0 3 -149 0 15 -149 0 86 -149 0 123 -149 0 124 -149 0 193 -149 0 229 -149 0 230 -149 0 344 -149 0 356 -149 0 357 -149 0 2 -150 0 15 -150 0 86 -150 0 124 -150 0 193 -150 0 230 -150 0 344 -150 0 357 -150 0 2 -151 0 15 -151 0 86 -151 0 87 -151 0 124 -151 0 193 -151 0 230 -151 0 344 -151 0 357 -151 0 2 -152 0 14 -152 0 15 -152 0 87 -152 0 124 -152 0 193 -152 0 230 -152 0 344 -152 0 345 -152 0 357 -152 0 2 -153 0 14 -153 0 87 -153 0 124 -153 0 193 -153 0 194 -153 0 230 -153 0 345 -153 0 357 -153 0 2 -154 0 14 -154 0 87 -154 0 88 -154 0 124 -154 0 194 -154 0 230 -154 0 345 -154 0 357 -154 0 2 -155 0 14 -155 0 88 -155 0 124 -155 0 194 -155 0 230 -155 0 345 -155 0 357 -155 0 1 -156 0 2 -156 0 14 -156 0 88 -156 0 124 -156 0 194 -156 0 230 -156 0 345 -156 0 357 -156 0 358 -156 0 1 -157 0 14 -157 0 88 -157 0 89 -157 0 124 -157 0 194 -157 0 230 -157 0 345 -157 0 358 -157 0 1 -158 0 14 -158 0 89 -158 0 124 -158 0 194 -158 0 195 -158 0 230 -158 0 345 -158 0 358 -158 0 1 -159 0 13 -159 0 14 -159 0 89 -159 0 124 -159 0 195 -159 0 229 -159 0 230 -159 0 345 -159 0 346 -159 0 358 -159 0 1 -160 0 13 -160 0 89 -160 0 90 -160 0 124 -160 0 195 -160 0 229 -160 0 346 -160 0 358 -160 0 1 -161 0 13 -161 0 90 -161 0 123 -161 0 124 -161 0 195 -161 0 196 -161 0 229 -161 0 346 -161 0 358 -161 0 1 -162 0 13 -162 0 90 -162 0 91 -162 0 123 -162 0 196 -162 0 197 -162 0 228 -162 0 229 -162 0 346 -162 0 358 -162 0 1 -163 0 13 -163 0 91 -163 0 123 -163 0 197 -163 0 227 -163 0 228 -163 0 346 -163 0 358 -163 0 1 -164 0 13 -164 0 91 -164 0 92 -164 0 122 -164 0 123 -164 0 197 -164 0 198 -164 0 227 -164 0 346 -164 0 358 -164 0 0 -165 0 1 -165 0 13 -165 0 92 -165 0 93 -165 0 121 -165 0 122 -165 0 198 -165 0 199 -165 0 226 -165 0 227 -165 0 346 -165 0 358 -165 0 359 -165 0 13 -166 0 93 -166 0 121 -166 0 199 -166 0 200 -166 0 225 -166 0 226 -166 0 346 -166 0 13 -167 0 93 -167 0 94 -167 0 120 -167 0 121 -167 0 200 -167 0 201 -167 0 224 -167 0 225 -167 0 346 -167 0 13 -168 0 94 -168 0 95 -168 0 119 -168 0 120 -168 0 201 -168 0 202 -168 0 203 -168 0 222 -168 0 223 -168 0 224 -168 0 346 -168 0 13 -169 0 95 -169 0 96 -169 0 118 -169 0 119 -169 0 203 -169 0 204 -169 0 221 -169 0 222 -169 0 346 -169 0 13 -170 0 96 -170 0 97 -170 0 98 -170 0 116 -170 0 117 -170 0 118 -170 0 204 -170 0 205 -170 0 206 -170 0 207 -170 0 218 -170 0 219 -170 0 220 -170 0 221 -170 0 346 -170 0 13 -171 0 98 -171 0 99 -171 0 115 -171 0 116 -171 0 207 -171 0 208 -171 0 209 -171 0 210 -171 0 211 -171 0 212 -171 0 213 -171 0 214 -171 0 215 -171 0 216 -171 0 217 -171 0 218 -171 0 346 -171 0 12 -172 0 13 -172 0 99 -172 0 100 -172 0 101 -172 0 102 -172 0 112 -172 0 113 -172 0 114 -172 0 115 -172 0 346 -172 0 347 -172 0 12 -173 0 102 -173 0 103 -173 0 104 -173 0 105 -173 0 106 -173 0 107 -173 0 108 -173 0 109 -173 0 110 -173 0 111 -173 0 112 -173 0 347 -173 0 12 -174 0 347 -174 0 12 -175 0 347 -175 0 12 -176 0 347 -176 0 12 -177 0 347 -177 0 12 -178 0 347 -178 0 12 -179 0 347 -179 0 12 -180 0 347 -180 0 12 -181 0 347 -181 0 12 -182 0 347 -182 0 12 -183 0 347 -183 0 12 -184 0 347 -184 0 12 -185 0 347 -185 0 12 -186 0 347 -186 0 12 -187 0 13 -187 0 346 -187 0 347 -187 0 13 -188 0 346 -188 0 13 -189 0 346 -189 0 13 -190 0 346 -190 0 13 -191 0 346 -191 0 13 -192 0 346 -192 0 13 -193 0 346 -193 0 0 -194 0 1 -194 0 13 -194 0 346 -194 0 358 -194 0 359 -194 0 1 -195 0 13 -195 0 346 -195 0 358 -195 0 1 -196 0 13 -196 0 346 -196 0 358 -196 0 1 -197 0 13 -197 0 346 -197 0 358 -197 0 1 -198 0 13 -198 0 346 -198 0 358 -198 0 1 -199 0 13 -199 0 346 -199 0 358 -199 0 1 -200 0 13 -200 0 14 -200 0 345 -200 0 346 -200 0 358 -200 0 1 -201 0 14 -201 0 345 -201 0 358 -201 0 1 -202 0 14 -202 0 345 -202 0 358 -202 0 1 -203 0 2 -203 0 14 -203 0 345 -203 0 357 -203 0 358 -203 0 2 -204 0 14 -204 0 345 -204 0 357 -204 0 2 -205 0 14 -205 0 154 -205 0 155 -205 0 156 -205 0 157 -205 0 158 -205 0 159 -205 0 160 -205 0 161 -205 0 162 -205 0 163 -205 0 164 -205 0 165 -205 0 166 -205 0 167 -205 0 168 -205 0 169 -205 0 170 -205 0 171 -205 0 172 -205 0 173 -205 0 174 -205 0 175 -205 0 345 -205 0 357 -205 0 2 -206 0 14 -206 0 151 -206 0 152 -206 0 153 -206 0 154 -206 0 175 -206 0 176 -206 0 177 -206 0 178 -206 0 179 -206 0 180 -206 0 181 -206 0 345 -206 0 357 -206 0 2 -207 0 14 -207 0 15 -207 0 148 -207 0 149 -207 0 150 -207 0 151 -207 0 181 -207 0 182 -207 0 183 -207 0 344 -207 0 345 -207 0 357 -207 0 2 -208 0 15 -208 0 147 -208 0 148 -208 0 183 -208 0 184 -208 0 185 -208 0 344 -208 0 357 -208 0 2 -209 0 15 -209 0 146 -209 0 147 -209 0 185 -209 0 186 -209 0 344 -209 0 357 -209 0 2 -210 0 3 -210 0 15 -210 0 145 -210 0 146 -210 0 186 -210 0 187 -210 0 344 -210 0 356 -210 0 357 -210 0 3 -211 0 15 -211 0 144 -211 0 145 -211 0 187 -211 0 188 -211 0 189 -211 0 344 -211 0 356 -211 0 3 -212 0 15 -212 0 16 -212 0 143 -212 0 144 -212 0 189 -212 0 190 -212 0 191 -212 0 192 -212 0 193 -212 0 194 -212 0 195 -212 0 343 -212 0 344 -212 0 356 -212 0 3 -213 0 16 -213 0 141 -213 0 142 -213 0 143 -213 0 195 -213 0 196 -213 0 197 -213 0 198 -213 0 343 -213 0 356 -213 0 3 -214 0 16 -214 0 133 -214 0 134 -214 0 135 -214 0 136 -214 0 137 -214 0 138 -214 0 139 -214 0 140 -214 0 141 -214 0 198 -214 0 199 -214 0 200 -214 0 201 -214 0 343 -214 0 356 -214 0 3 -215 0 16 -215 0 131 -215 0 132 -215 0 133 -215 0 201 -215 0 202 -215 0 203 -215 0 343 -215 0 355 -215 0 356 -215 0 3 -216 0 4 -216 0 16 -216 0 121 -216 0 122 -216 0 123 -216 0 124 -216 0 125 -216 0 126 -216 0 127 -216 0 128 -216 0 129 -216 0 130 -216 0 131 -216 0 203 -216 0 204 -216 0 205 -216 0 206 -216 0 207 -216 0 208 -216 0 343 -216 0 355 -216 0 4 -217 0 16 -217 0 17 -217 0 120 -217 0 121 -217 0 208 -217 0 209 -217 0 210 -217 0 211 -217 0 212 -217 0 213 -217 0 342 -217 0 343 -217 0 355 -217 0 4 -218 0 17 -218 0 118 -218 0 119 -218 0 120 -218 0 213 -218 0 214 -218 0 215 -218 0 245 -218 0 342 -218 0 355 -218 0 4 -219 0 17 -219 0 116 -219 0 117 -219 0 118 -219 0 215 -219 0 216 -219 0 217 -219 0 218 -219 0 219 -219 0 220 -219 0 221 -219 0 222 -219 0 244 -219 0 245 -219 0 246 -219 0 342 -219 0 355 -219 0 4 -220 0 5 -220 0 17 -220 0 114 -220 0 115 -220 0 116 -220 0 222 -220 0 223 -220 0 224 -220 0 225 -220 0 242 -220 0 243 -220 0 244 -220 0 246 -220 0 247 -220 0 342 -220 0 354 -220 0 355 -220 0 5 -221 0 17 -221 0 18 -221 0 111 -221 0 112 -221 0 113 -221 0 114 -221 0 225 -221 0 226 -221 0 227 -221 0 228 -221 0 229 -221 0 230 -221 0 231 -221 0 232 -221 0 233 -221 0 234 -221 0 235 -221 0 236 -221 0 237 -221 0 238 -221 0 239 -221 0 240 -221 0 241 -221 0 242 -221 0 247 -221 0 341 -221 0 342 -221 0 354 -221 0 5 -222 0 18 -222 0 111 -222 0 247 -222 0 248 -222 0 341 -222 0 354 -222 0 5 -223 0 18 -223 0 110 -223 0 111 -223 0 248 -223 0 341 -223 0 354 -223 0 5 -224 0 6 -224 0 18 -224 0 109 -224 0 110 -224 0 248 -224 0 341 -224 0 353 -224 0 354 -224 0 6 -225 0 18 -225 0 19 -225 0 108 -225 0 109 -225 0 248 -225 0 340 -225 0 341 -225 0 353 -225 0 6 -226 0 19 -226 0 107 -226 0 108 -226 0 248 -226 0 340 -226 0 353 -226 0 6 -227 0 19 -227 0 107 -227 0 143 -227 0 144 -227 0 145 -227 0 146 -227 0 147 -227 0 148 -227 0 149 -227 0 150 -227 0 151 -227 0 152 -227 0 153 -227 0 154 -227 0 155 -227 0 156 -227 0 157 -227 0 158 -227 0 159 -227 0 160 -227 0 248 -227 0 340 -227 0 353 -227 0 6 -228 0 7 -228 0 19 -228 0 20 -228 0 106 -228 0 107 -228 0 140 -228 0 141 -228 0 142 -228 0 143 -228 0 160 -228 0 161 -228 0 162 -228 0 163 -228 0 164 -228 0 248 -228 0 339 -228 0 340 -228 0 352 -228 0 353 -228 0 7 -229 0 20 -229 0 106 -229 0 136 -229 0 137 -229 0 138 -229 0 139 -229 0 140 -229 0 164 -229 0 165 -229 0 166 -229 0 248 -229 0 339 -229 0 352 -229 0 7 -230 0 20 -230 0 105 -230 0 106 -230 0 135 -230 0 136 -230 0 166 -230 0 167 -230 0 168 -230 0 169 -230 0 170 -230 0 171 -230 0 172 -230 0 173 -230 0 174 -230 0 175 -230 0 176 -230 0 177 -230 0 178 -230 0 179 -230 0 180 -230 0 181 -230 0 182 -230 0 183 -230 0 184 -230 0 248 -230 0 339 -230 0 352 -230 0 7 -231 0 8 -231 0 20 -231 0 104 -231 0 105 -231 0 134 -231 0 135 -231 0 184 -231 0 185 -231 0 186 -231 0 187 -231 0 188 -231 0 189 -231 0 190 -231 0 191 -231 0 192 -231 0 193 -231 0 248 -231 0 339 -231 0 351 -231 0 352 -231 0 8 -232 0 20 -232 0 21 -232 0 103 -232 0 104 -232 0 133 -232 0 134 -232 0 193 -232 0 194 -232 0 195 -232 0 196 -232 0 197 -232 0 198 -232 0 247 -232 0 248 -232 0 338 -232 0 339 -232 0 351 -232 0 8 -233 0 21 -233 0 102 -233 0 103 -233 0 132 -233 0 133 -233 0 198 -233 0 199 -233 0 200 -233 0 247 -233 0 338 -233 0 351 -233 0 8 -234 0 9 -234 0 21 -234 0 22 -234 0 101 -234 0 102 -234 0 130 -234 0 131 -234 0 132 -234 0 200 -234 0 201 -234 0 202 -234 0 203 -234 0 204 -234 0 205 -234 0 206 -234 0 207 -234 0 208 -234 0 209 -234 0 210 -234 0 211 -234 0 212 -234 0 213 -234 0 246 -234 0 247 -234 0 338 -234 0 350 -234 0 351 -234 0 9 -235 0 22 -235 0 101 -235 0 128 -235 0 129 -235 0 130 -235 0 213 -235 0 214 -235 0 215 -235 0 245 -235 0 246 -235 0 337 -235 0 338 -235 0 350 -235 0 9 -236 0 22 -236 0 100 -236 0 101 -236 0 127 -236 0 128 -236 0 215 -236 0 216 -236 0 244 -236 0 245 -236 0 337 -236 0 350 -236 0 9 -237 0 10 -237 0 22 -237 0 23 -237 0 100 -237 0 126 -237 0 127 -237 0 216 -237 0 217 -237 0 218 -237 0 243 -237 0 244 -237 0 336 -237 0 337 -237 0 349 -237 0 350 -237 0 10 -238 0 23 -238 0 99 -238 0 100 -238 0 124 -238 0 125 -238 0 126 -238 0 218 -238 0 219 -238 0 220 -238 0 221 -238 0 222 -238 0 223 -238 0 224 -238 0 242 -238 0 243 -238 0 336 -238 0 349 -238 0 10 -239 0 23 -239 0 99 -239 0 122 -239 0 123 -239 0 124 -239 0 224 -239 0 225 -239 0 241 -239 0 242 -239 0 336 -239 0 349 -239 0 10 -240 0 11 -240 0 23 -240 0 24 -240 0 98 -240 0 99 -240 0 121 -240 0 122 -240 0 225 -240 0 226 -240 0 227 -240 0 239 -240 0 240 -240 0 241 -240 0 335 -240 0 336 -240 0 348 -240 0 349 -240 0 11 -241 0 24 -241 0 97 -241 0 98 -241 0 120 -241 0 121 -241 0 227 -241 0 228 -241 0 229 -241 0 230 -241 0 231 -241 0 232 -241 0 233 -241 0 234 -241 0 235 -241 0 236 -241 0 237 -241 0 238 -241 0 239 -241 0 335 -241 0 348 -241 0 11 -242 0 24 -242 0 25 -242 0 96 -242 0 97 -242 0 119 -242 0 120 -242 0 335 -242 0 348 -242 0 11 -243 0 12 -243 0 25 -243 0 95 -243 0 96 -243 0 117 -243 0 118 -243 0 119 -243 0 334 -243 0 335 -243 0 347 -243 0 348 -243 0 12 -244 0 25 -244 0 94 -244 0 95 -244 0 117 -244 0 334 -244 0 347 -244 0 12 -245 0 13 -245 0 25 -245 0 26 -245 0 94 -245 0 116 -245 0 117 -245 0 333 -245 0 334 -245 0 347 -245 0 13 -246 0 26 -246 0 93 -246 0 94 -246 0 115 -246 0 116 -246 0 333 -246 0 346 -246 0 347 -246 0 13 -247 0 26 -247 0 27 -247 0 92 -247 0 93 -247 0 114 -247 0 115 -247 0 332 -247 0 333 -247 0 346 -247 0 13 -248 0 14 -248 0 27 -248 0 91 -248 0 92 -248 0 113 -248 0 114 -248 0 332 -248 0 345 -248 0 346 -248 0 14 -249 0 27 -249 0 28 -249 0 90 -249 0 91 -249 0 112 -249 0 113 -249 0 331 -249 0 332 -249 0 345 -249 0 14 -250 0 15 -250 0 28 -250 0 89 -250 0 90 -250 0 111 -250 0 112 -250 0 331 -250 0 344 -250 0 345 -250 0 15 -251 0 28 -251 0 88 -251 0 89 -251 0 109 -251 0 110 -251 0 111 -251 0 331 -251 0 344 -251 0 15 -252 0 28 -252 0 29 -252 0 87 -252 0 88 -252 0 107 -252 0 108 -252 0 109 -252 0 330 -252 0 331 -252 0 344 -252 0 15 -253 0 16 -253 0 29 -253 0 88 -253 0 89 -253 0 105 -253 0 106 -253 0 107 -253 0 330 -253 0 343 -253 0 344 -253 0 16 -254 0 29 -254 0 30 -254 0 89 -254 0 90 -254 0 104 -254 0 105 -254 0 329 -254 0 330 -254 0 343 -254 0 16 -255 0 17 -255 0 30 -255 0 90 -255 0 91 -255 0 92 -255 0 102 -255 0 103 -255 0 104 -255 0 329 -255 0 342 -255 0 343 -255 0 17 -256 0 30 -256 0 31 -256 0 92 -256 0 93 -256 0 94 -256 0 95 -256 0 96 -256 0 97 -256 0 98 -256 0 99 -256 0 100 -256 0 101 -256 0 102 -256 0 328 -256 0 329 -256 0 342 -256 0 17 -257 0 18 -257 0 31 -257 0 328 -257 0 341 -257 0 342 -257 0 18 -258 0 31 -258 0 32 -258 0 327 -258 0 328 -258 0 341 -258 0 18 -259 0 19 -259 0 32 -259 0 327 -259 0 340 -259 0 341 -259 0 19 -260 0 32 -260 0 33 -260 0 326 -260 0 327 -260 0 340 -260 0 19 -261 0 20 -261 0 33 -261 0 34 -261 0 325 -261 0 326 -261 0 339 -261 0 340 -261 0 20 -262 0 34 -262 0 325 -262 0 339 -262 0 20 -263 0 21 -263 0 34 -263 0 35 -263 0 324 -263 0 325 -263 0 338 -263 0 339 -263 0 21 -264 0 35 -264 0 324 -264 0 338 -264 0 21 -265 0 22 -265 0 35 -265 0 36 -265 0 323 -265 0 324 -265 0 337 -265 0 338 -265 0 22 -266 0 36 -266 0 37 -266 0 322 -266 0 323 -266 0 337 -266 0 22 -267 0 23 -267 0 37 -267 0 322 -267 0 336 -267 0 337 -267 0 23 -268 0 24 -268 0 37 -268 0 38 -268 0 321 -268 0 322 -268 0 335 -268 0 336 -268 0 24 -269 0 38 -269 0 321 -269 0 335 -269 0 24 -270 0 25 -270 0 38 -270 0 39 -270 0 320 -270 0 321 -270 0 334 -270 0 335 -270 0 25 -271 0 39 -271 0 40 -271 0 319 -271 0 320 -271 0 334 -271 0 25 -272 0 26 -272 0 40 -272 0 319 -272 0 333 -272 0 334 -272 0 26 -273 0 27 -273 0 40 -273 0 41 -273 0 318 -273 0 319 -273 0 332 -273 0 333 -273 0 27 -274 0 41 -274 0 42 -274 0 317 -274 0 318 -274 0 332 -274 0 27 -275 0 28 -275 0 42 -275 0 317 -275 0 331 -275 0 332 -275 0 28 -276 0 29 -276 0 42 -276 0 43 -276 0 316 -276 0 317 -276 0 330 -276 0 331 -276 0 29 -277 0 43 -277 0 44 -277 0 315 -277 0 316 -277 0 330 -277 0 29 -278 0 30 -278 0 44 -278 0 45 -278 0 314 -278 0 315 -278 0 329 -278 0 330 -278 0 30 -279 0 31 -279 0 45 -279 0 314 -279 0 328 -279 0 329 -279 0 31 -280 0 45 -280 0 46 -280 0 313 -280 0 314 -280 0 328 -280 0 31 -281 0 32 -281 0 46 -281 0 47 -281 0 312 -281 0 313 -281 0 327 -281 0 328 -281 0 32 -282 0 47 -282 0 48 -282 0 311 -282 0 312 -282 0 327 -282 0 32 -283 0 33 -283 0 48 -283 0 311 -283 0 326 -283 0 327 -283 0 33 -284 0 34 -284 0 48 -284 0 49 -284 0 310 -284 0 311 -284 0 325 -284 0 326 -284 0 34 -285 0 35 -285 0 49 -285 0 50 -285 0 309 -285 0 310 -285 0 324 -285 0 325 -285 0 35 -286 0 50 -286 0 51 -286 0 308 -286 0 309 -286 0 324 -286 0 35 -287 0 36 -287 0 51 -287 0 52 -287 0 307 -287 0 308 -287 0 323 -287 0 324 -287 0 36 -288 0 37 -288 0 52 -288 0 307 -288 0 322 -288 0 323 -288 0 37 -289 0 38 -289 0 52 -289 0 53 -289 0 54 -289 0 305 -289 0 306 -289 0 307 -289 0 321 -289 0 322 -289 0 38 -290 0 54 -290 0 305 -290 0 321 -290 0 38 -291 0 39 -291 0 54 -291 0 55 -291 0 304 -291 0 305 -291 0 320 -291 0 321 -291 0 39 -292 0 40 -292 0 55 -292 0 56 -292 0 303 -292 0 304 -292 0 319 -292 0 320 -292 0 40 -293 0 41 -293 0 56 -293 0 57 -293 0 302 -293 0 303 -293 0 318 -293 0 319 -293 0 41 -294 0 42 -294 0 57 -294 0 58 -294 0 301 -294 0 302 -294 0 317 -294 0 318 -294 0 42 -295 0 58 -295 0 59 -295 0 300 -295 0 301 -295 0 317 -295 0 42 -296 0 43 -296 0 59 -296 0 60 -296 0 299 -296 0 300 -296 0 316 -296 0 317 -296 0 43 -297 0 44 -297 0 60 -297 0 61 -297 0 298 -297 0 299 -297 0 315 -297 0 316 -297 0 44 -298 0 45 -298 0 61 -298 0 62 -298 0 297 -298 0 298 -298 0 314 -298 0 315 -298 0 45 -299 0 46 -299 0 62 -299 0 63 -299 0 296 -299 0 297 -299 0 313 -299 0 314 -299 0 46 -300 0 47 -300 0 63 -300 0 64 -300 0 295 -300 0 296 -300 0 312 -300 0 313 -300 0 47 -301 0 48 -301 0 64 -301 0 65 -301 0 294 -301 0 295 -301 0 311 -301 0 312 -301 0 48 -302 0 49 -302 0 65 -302 0 66 -302 0 293 -302 0 294 -302 0 310 -302 0 311 -302 0 49 -303 0 50 -303 0 66 -303 0 67 -303 0 292 -303 0 293 -303 0 309 -303 0 310 -303 0 50 -304 0 51 -304 0 67 -304 0 68 -304 0 291 -304 0 292 -304 0 308 -304 0 309 -304 0 51 -305 0 52 -305 0 68 -305 0 69 -305 0 70 -305 0 289 -305 0 290 -305 0 291 -305 0 307 -305 0 308 -305 0 52 -306 0 53 -306 0 70 -306 0 71 -306 0 288 -306 0 289 -306 0 306 -306 0 307 -306 0 53 -307 0 54 -307 0 71 -307 0 72 -307 0 287 -307 0 288 -307 0 305 -307 0 306 -307 0 54 -308 0 55 -308 0 72 -308 0 73 -308 0 286 -308 0 287 -308 0 304 -308 0 305 -308 0 55 -309 0 56 -309 0 73 -309 0 74 -309 0 285 -309 0 286 -309 0 303 -309 0 304 -309 0 56 -310 0 57 -310 0 74 -310 0 75 -310 0 284 -310 0 285 -310 0 302 -310 0 303 -310 0 57 -311 0 58 -311 0 75 -311 0 76 -311 0 77 -311 0 282 -311 0 283 -311 0 284 -311 0 301 -311 0 302 -311 0 58 -312 0 59 -312 0 77 -312 0 78 -312 0 281 -312 0 282 -312 0 300 -312 0 301 -312 0 59 -313 0 60 -313 0 78 -313 0 79 -313 0 280 -313 0 281 -313 0 299 -313 0 300 -313 0 60 -314 0 61 -314 0 79 -314 0 80 -314 0 81 -314 0 278 -314 0 279 -314 0 280 -314 0 298 -314 0 299 -314 0 61 -315 0 62 -315 0 81 -315 0 82 -315 0 277 -315 0 278 -315 0 297 -315 0 298 -315 0 62 -316 0 63 -316 0 82 -316 0 83 -316 0 276 -316 0 277 -316 0 296 -316 0 297 -316 0 63 -317 0 64 -317 0 65 -317 0 83 -317 0 84 -317 0 85 -317 0 274 -317 0 275 -317 0 276 -317 0 294 -317 0 295 -317 0 296 -317 0 65 -318 0 66 -318 0 85 -318 0 86 -318 0 273 -318 0 274 -318 0 293 -318 0 294 -318 0 66 -319 0 67 -319 0 86 -319 0 87 -319 0 88 -319 0 271 -319 0 272 -319 0 273 -319 0 292 -319 0 293 -319 0 67 -320 0 68 -320 0 88 -320 0 89 -320 0 270 -320 0 271 -320 0 291 -320 0 292 -320 0 68 -321 0 69 -321 0 70 -321 0 89 -321 0 90 -321 0 91 -321 0 268 -321 0 269 -321 0 270 -321 0 289 -321 0 290 -321 0 291 -321 0 70 -322 0 71 -322 0 91 -322 0 92 -322 0 93 -322 0 266 -322 0 267 -322 0 268 -322 0 288 -322 0 289 -322 0 71 -323 0 72 -323 0 93 -323 0 94 -323 0 265 -323 0 266 -323 0 287 -323 0 288 -323 0 72 -324 0 73 -324 0 74 -324 0 94 -324 0 95 -324 0 96 -324 0 263 -324 0 264 -324 0 265 -324 0 285 -324 0 286 -324 0 287 -324 0 74 -325 0 75 -325 0 96 -325 0 97 -325 0 98 -325 0 261 -325 0 262 -325 0 263 -325 0 284 -325 0 285 -325 0 75 -326 0 76 -326 0 98 -326 0 99 -326 0 100 -326 0 259 -326 0 260 -326 0 261 -326 0 283 -326 0 284 -326 0 76 -327 0 77 -327 0 78 -327 0 100 -327 0 101 -327 0 257 -327 0 258 -327 0 259 -327 0 281 -327 0 282 -327 0 283 -327 0 78 -328 0 79 -328 0 80 -328 0 101 -328 0 102 -328 0 103 -328 0 256 -328 0 257 -328 0 279 -328 0 280 -328 0 281 -328 0 80 -329 0 81 -329 0 103 -329 0 104 -329 0 105 -329 0 254 -329 0 255 -329 0 256 -329 0 278 -329 0 279 -329 0 81 -330 0 82 -330 0 83 -330 0 105 -330 0 106 -330 0 107 -330 0 252 -330 0 253 -330 0 254 -330 0 277 -330 0 278 -330 0 83 -331 0 84 -331 0 107 -331 0 108 -331 0 109 -331 0 110 -331 0 249 -331 0 250 -331 0 251 -331 0 252 -331 0 275 -331 0 276 -331 0 277 -331 0 84 -332 0 85 -332 0 86 -332 0 110 -332 0 111 -332 0 112 -332 0 247 -332 0 248 -332 0 249 -332 0 273 -332 0 274 -332 0 275 -332 0 86 -333 0 87 -333 0 112 -333 0 113 -333 0 114 -333 0 245 -333 0 246 -333 0 247 -333 0 272 -333 0 273 -333 0 87 -334 0 88 -334 0 89 -334 0 114 -334 0 115 -334 0 116 -334 0 243 -334 0 244 -334 0 245 -334 0 270 -334 0 271 -334 0 272 -334 0 89 -335 0 90 -335 0 91 -335 0 116 -335 0 117 -335 0 118 -335 0 119 -335 0 240 -335 0 241 -335 0 242 -335 0 243 -335 0 268 -335 0 269 -335 0 270 -335 0 91 -336 0 92 -336 0 93 -336 0 119 -336 0 120 -336 0 121 -336 0 122 -336 0 237 -336 0 238 -336 0 239 -336 0 240 -336 0 267 -336 0 268 -336 0 93 -337 0 94 -337 0 122 -337 0 123 -337 0 124 -337 0 235 -337 0 236 -337 0 237 -337 0 265 -337 0 266 -337 0 267 -337 0 94 -338 0 95 -338 0 96 -338 0 124 -338 0 125 -338 0 126 -338 0 127 -338 0 232 -338 0 233 -338 0 234 -338 0 235 -338 0 263 -338 0 264 -338 0 265 -338 0 96 -339 0 97 -339 0 98 -339 0 127 -339 0 128 -339 0 129 -339 0 130 -339 0 131 -339 0 228 -339 0 229 -339 0 230 -339 0 231 -339 0 232 -339 0 261 -339 0 262 -339 0 263 -339 0 98 -340 0 99 -340 0 100 -340 0 131 -340 0 132 -340 0 133 -340 0 134 -340 0 225 -340 0 226 -340 0 227 -340 0 228 -340 0 259 -340 0 260 -340 0 261 -340 0 100 -341 0 101 -341 0 102 -341 0 134 -341 0 135 -341 0 136 -341 0 137 -341 0 138 -341 0 221 -341 0 222 -341 0 223 -341 0 224 -341 0 225 -341 0 257 -341 0 258 -341 0 259 -341 0 102 -342 0 103 -342 0 104 -342 0 138 -342 0 139 -342 0 140 -342 0 141 -342 0 142 -342 0 217 -342 0 218 -342 0 219 -342 0 220 -342 0 221 -342 0 255 -342 0 256 -342 0 257 -342 0 104 -343 0 105 -343 0 106 -343 0 142 -343 0 143 -343 0 144 -343 0 145 -343 0 146 -343 0 147 -343 0 212 -343 0 213 -343 0 214 -343 0 215 -343 0 216 -343 0 217 -343 0 253 -343 0 254 -343 0 255 -343 0 106 -344 0 107 -344 0 108 -344 0 109 -344 0 147 -344 0 148 -344 0 149 -344 0 150 -344 0 151 -344 0 152 -344 0 207 -344 0 208 -344 0 209 -344 0 210 -344 0 211 -344 0 212 -344 0 250 -344 0 251 -344 0 252 -344 0 253 -344 0 109 -345 0 110 -345 0 111 -345 0 152 -345 0 153 -345 0 154 -345 0 155 -345 0 156 -345 0 157 -345 0 158 -345 0 159 -345 0 200 -345 0 201 -345 0 202 -345 0 203 -345 0 204 -345 0 205 -345 0 206 -345 0 207 -345 0 248 -345 0 249 -345 0 250 -345 0 111 -346 0 112 -346 0 113 -346 0 159 -346 0 160 -346 0 161 -346 0 162 -346 0 163 -346 0 164 -346 0 165 -346 0 166 -346 0 167 -346 0 168 -346 0 169 -346 0 170 -346 0 171 -346 0 187 -346 0 188 -346 0 189 -346 0 190 -346 0 191 -346 0 192 -346 0 193 -346 0 194 -346 0 195 -346 0 196 -346 0 197 -346 0 198 -346 0 199 -346 0 200 -346 0 246 -346 0 247 -346 0 248 -346 0 113 -347 0 114 -347 0 115 -347 0 116 -347 0 171 -347 0 172 -347 0 173 -347 0 174 -347 0 175 -347 0 176 -347 0 177 -347 0 178 -347 0 179 -347 0 180 -347 0 181 -347 0 182 -347 0 183 -347 0 184 -347 0 185 -347 0 186 -347 0 187 -347 0 243 -347 0 244 -347 0 245 -347 0 246 -347 0 116 -348 0 117 -348 0 118 -348 0 119 -348 0 240 -348 0 241 -348 0 242 -348 0 243 -348 0 119 -349 0 120 -349 0 121 -349 0 122 -349 0 237 -349 0 238 -349 0 239 -349 0 240 -349 0 122 -350 0 123 -350 0 124 -350 0 125 -350 0 234 -350 0 235 -350 0 236 -350 0 237 -350 0 125 -351 0 126 -351 0 127 -351 0 128 -351 0 231 -351 0 232 -351 0 233 -351 0 234 -351 0 128 -352 0 129 -352 0 130 -352 0 131 -352 0 228 -352 0 229 -352 0 230 -352 0 231 -352 0 131 -353 0 132 -353 0 133 -353 0 134 -353 0 135 -353 0 224 -353 0 225 -353 0 226 -353 0 227 -353 0 228 -353 0 135 -354 0 136 -354 0 137 -354 0 138 -354 0 139 -354 0 220 -354 0 221 -354 0 222 -354 0 223 -354 0 224 -354 0 139 -355 0 140 -355 0 141 -355 0 142 -355 0 143 -355 0 144 -355 0 216 -355 0 217 -355 0 218 -355 0 219 -355 0 220 -355 0 144 -356 0 145 -356 0 146 -356 0 147 -356 0 148 -356 0 149 -356 0 210 -356 0 211 -356 0 212 -356 0 213 -356 0 214 -356 0 215 -356 0 216 -356 0 149 -357 0 150 -357 0 151 -357 0 152 -357 0 153 -357 0 154 -357 0 155 -357 0 156 -357 0 203 -357 0 204 -357 0 205 -357 0 206 -357 0 207 -357 0 208 -357 0 209 -357 0 210 -357 0 156 -358 0 157 -358 0 158 -358 0 159 -358 0 160 -358 0 161 -358 0 162 -358 0 163 -358 0 164 -358 0 165 -358 0 195 -358 0 196 -358 0 197 -358 0 198 -358 0 199 -358 0 200 -358 0 201 -358 0 202 -358 0 203 -358 0 165 -359 0 195 -359 0 POINT_DATA 3743 SCALARS pointLabels long 1 LOOKUP_TABLE default 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 2 2 2 2 2 2 2 2 1 1 1 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 1 1 1 1 4 4 4 1 1 1 1 1 4 4 4 1 1 1 1 1 1 4 4 4 1 1 1 1 1 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 1 4 4 4 1 1 1 1 1 1 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ants-1.9.2+svn680.dfsg/Examples/Data/Smile.nii000066400000000000000000017651401147325206600206770ustar00rootroot00000000000000\rhh ???C????n+1????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@??????????????????????????????????????@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@???????????????????????????????????????@@@@??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ants-1.9.2+svn680.dfsg/Examples/Data/Smile.txt000066400000000000000000001371371147325206600207350ustar00rootroot000000000000000 0 0 0 164 0 0 1 195 0 0 1 156 -1 0 1 157 -1 0 1 158 -1 0 1 159 -1 0 1 160 -1 0 1 161 -1 0 1 162 -1 0 1 163 -1 0 1 164 -1 0 1 195 -1 0 1 196 -1 0 1 197 -1 0 1 198 -1 0 1 199 -1 0 1 200 -1 0 1 201 -1 0 1 202 -1 0 1 203 -1 0 1 149 -2 0 1 150 -2 0 1 151 -2 0 1 152 -2 0 1 153 -2 0 1 154 -2 0 1 155 -2 0 1 156 -2 0 1 203 -2 0 1 204 -2 0 1 205 -2 0 1 206 -2 0 1 207 -2 0 1 208 -2 0 1 209 -2 0 1 210 -2 0 1 143 -3 0 1 144 -3 0 1 145 -3 0 1 146 -3 0 1 147 -3 0 1 148 -3 0 1 149 -3 0 1 210 -3 0 1 211 -3 0 1 212 -3 0 1 213 -3 0 1 214 -3 0 1 215 -3 0 1 139 -4 0 1 140 -4 0 1 141 -4 0 1 142 -4 0 1 143 -4 0 1 215 -4 0 1 216 -4 0 1 217 -4 0 1 218 -4 0 1 219 -4 0 1 220 -4 0 1 135 -5 0 1 136 -5 0 1 137 -5 0 1 138 -5 0 1 139 -5 0 1 220 -5 0 1 221 -5 0 1 222 -5 0 1 223 -5 0 1 224 -5 0 1 131 -6 0 1 132 -6 0 1 133 -6 0 1 134 -6 0 1 135 -6 0 1 224 -6 0 1 225 -6 0 1 226 -6 0 1 227 -6 0 1 228 -6 0 1 128 -7 0 1 129 -7 0 1 130 -7 0 1 131 -7 0 1 228 -7 0 1 229 -7 0 1 230 -7 0 1 231 -7 0 1 125 -8 0 1 126 -8 0 1 127 -8 0 1 128 -8 0 1 231 -8 0 1 232 -8 0 1 233 -8 0 1 234 -8 0 1 122 -9 0 1 123 -9 0 1 124 -9 0 1 125 -9 0 1 234 -9 0 1 235 -9 0 1 236 -9 0 1 237 -9 0 1 119 -10 0 1 120 -10 0 1 121 -10 0 1 122 -10 0 1 237 -10 0 1 238 -10 0 1 239 -10 0 1 240 -10 0 1 116 -11 0 1 117 -11 0 1 118 -11 0 1 119 -11 0 1 240 -11 0 1 241 -11 0 1 242 -11 0 1 243 -11 0 1 113 -12 0 1 114 -12 0 1 115 -12 0 1 116 -12 0 1 172 -12 0 1 173 -12 0 1 174 -12 0 1 175 -12 0 1 176 -12 0 1 177 -12 0 1 178 -12 0 1 179 -12 0 1 180 -12 0 1 181 -12 0 1 182 -12 0 1 183 -12 0 1 184 -12 0 1 185 -12 0 1 186 -12 0 1 187 -12 0 1 243 -12 0 1 244 -12 0 1 245 -12 0 1 246 -12 0 1 111 -13 0 1 112 -13 0 1 113 -13 0 1 159 -13 0 1 160 -13 0 1 161 -13 0 1 162 -13 0 1 163 -13 0 1 164 -13 0 1 165 -13 0 1 166 -13 0 1 167 -13 0 1 168 -13 0 1 169 -13 0 1 170 -13 0 1 171 -13 0 1 172 -13 0 1 187 -13 0 1 188 -13 0 1 189 -13 0 1 190 -13 0 1 191 -13 0 1 192 -13 0 1 193 -13 0 1 194 -13 0 1 195 -13 0 1 196 -13 0 1 197 -13 0 1 198 -13 0 1 199 -13 0 1 200 -13 0 1 246 -13 0 1 247 -13 0 1 248 -13 0 1 109 -14 0 1 110 -14 0 1 111 -14 0 1 152 -14 0 1 153 -14 0 1 154 -14 0 1 155 -14 0 1 156 -14 0 1 157 -14 0 1 158 -14 0 1 159 -14 0 1 200 -14 0 1 201 -14 0 1 202 -14 0 1 203 -14 0 1 204 -14 0 1 205 -14 0 1 206 -14 0 1 207 -14 0 1 248 -14 0 1 249 -14 0 1 250 -14 0 1 106 -15 0 1 107 -15 0 1 108 -15 0 1 109 -15 0 1 147 -15 0 1 148 -15 0 1 149 -15 0 1 150 -15 0 1 151 -15 0 1 152 -15 0 1 207 -15 0 1 208 -15 0 1 209 -15 0 1 210 -15 0 1 211 -15 0 1 212 -15 0 1 250 -15 0 1 251 -15 0 1 252 -15 0 1 253 -15 0 1 104 -16 0 1 105 -16 0 1 106 -16 0 1 142 -16 0 1 143 -16 0 1 144 -16 0 1 145 -16 0 1 146 -16 0 1 147 -16 0 1 212 -16 0 1 213 -16 0 1 214 -16 0 1 215 -16 0 1 216 -16 0 1 217 -16 0 1 253 -16 0 1 254 -16 0 1 255 -16 0 1 102 -17 0 1 103 -17 0 1 104 -17 0 1 138 -17 0 1 139 -17 0 1 140 -17 0 1 141 -17 0 1 142 -17 0 1 217 -17 0 1 218 -17 0 1 219 -17 0 1 220 -17 0 1 221 -17 0 1 255 -17 0 1 256 -17 0 1 257 -17 0 1 100 -18 0 1 101 -18 0 1 102 -18 0 1 134 -18 0 1 135 -18 0 1 136 -18 0 1 137 -18 0 1 138 -18 0 1 221 -18 0 1 222 -18 0 1 223 -18 0 1 224 -18 0 1 225 -18 0 1 257 -18 0 1 258 -18 0 1 259 -18 0 1 98 -19 0 1 99 -19 0 1 100 -19 0 1 131 -19 0 1 132 -19 0 1 133 -19 0 1 134 -19 0 1 225 -19 0 1 226 -19 0 1 227 -19 0 1 228 -19 0 1 259 -19 0 1 260 -19 0 1 261 -19 0 1 96 -20 0 1 97 -20 0 1 98 -20 0 1 127 -20 0 1 128 -20 0 1 129 -20 0 1 130 -20 0 1 131 -20 0 1 228 -20 0 1 229 -20 0 1 230 -20 0 1 231 -20 0 1 232 -20 0 1 261 -20 0 1 262 -20 0 1 263 -20 0 1 94 -21 0 1 95 -21 0 1 96 -21 0 1 124 -21 0 1 125 -21 0 1 126 -21 0 1 127 -21 0 1 232 -21 0 1 233 -21 0 1 234 -21 0 1 235 -21 0 1 263 -21 0 1 264 -21 0 1 265 -21 0 1 92 -22 0 1 93 -22 0 1 94 -22 0 1 122 -22 0 1 123 -22 0 1 124 -22 0 1 235 -22 0 1 236 -22 0 1 237 -22 0 1 265 -22 0 1 266 -22 0 1 91 -23 0 1 92 -23 0 1 119 -23 0 1 120 -23 0 1 121 -23 0 1 122 -23 0 1 237 -23 0 1 238 -23 0 1 239 -23 0 1 240 -23 0 1 266 -23 0 1 267 -23 0 1 268 -23 0 1 89 -24 0 1 90 -24 0 1 91 -24 0 1 116 -24 0 1 117 -24 0 1 118 -24 0 1 119 -24 0 1 240 -24 0 1 241 -24 0 1 242 -24 0 1 243 -24 0 1 268 -24 0 1 269 -24 0 1 270 -24 0 1 87 -25 0 1 88 -25 0 1 89 -25 0 1 114 -25 0 1 115 -25 0 1 116 -25 0 1 243 -25 0 1 244 -25 0 1 245 -25 0 1 270 -25 0 1 271 -25 0 1 272 -25 0 1 86 -26 0 1 87 -26 0 1 112 -26 0 1 113 -26 0 1 114 -26 0 1 245 -26 0 1 246 -26 0 1 247 -26 0 1 272 -26 0 1 273 -26 0 1 84 -27 0 1 85 -27 0 1 86 -27 0 1 110 -27 0 1 111 -27 0 1 112 -27 0 1 247 -27 0 1 248 -27 0 1 249 -27 0 1 273 -27 0 1 274 -27 0 1 275 -27 0 1 82 -28 0 1 83 -28 0 1 84 -28 0 1 107 -28 0 1 108 -28 0 1 109 -28 0 1 110 -28 0 1 249 -28 0 1 250 -28 0 1 251 -28 0 1 252 -28 0 1 275 -28 0 1 276 -28 0 1 81 -29 0 1 82 -29 0 1 105 -29 0 1 106 -29 0 1 107 -29 0 1 252 -29 0 1 253 -29 0 1 254 -29 0 1 276 -29 0 1 277 -29 0 1 278 -29 0 1 80 -30 0 1 81 -30 0 1 103 -30 0 1 104 -30 0 1 105 -30 0 1 254 -30 0 1 255 -30 0 1 256 -30 0 1 278 -30 0 1 279 -30 0 1 78 -31 0 1 79 -31 0 1 80 -31 0 1 102 -31 0 1 103 -31 0 1 256 -31 0 1 257 -31 0 1 279 -31 0 1 280 -31 0 1 281 -31 0 1 76 -32 0 1 77 -32 0 1 78 -32 0 1 100 -32 0 1 101 -32 0 1 102 -32 0 1 257 -32 0 1 258 -32 0 1 259 -32 0 1 281 -32 0 1 282 -32 0 1 283 -32 0 1 75 -33 0 1 76 -33 0 1 98 -33 0 1 99 -33 0 1 100 -33 0 1 259 -33 0 1 260 -33 0 1 261 -33 0 1 283 -33 0 1 284 -33 0 1 74 -34 0 1 75 -34 0 1 96 -34 0 1 97 -34 0 1 98 -34 0 1 261 -34 0 1 262 -34 0 1 263 -34 0 1 284 -34 0 1 285 -34 0 1 72 -35 0 1 73 -35 0 1 74 -35 0 1 94 -35 0 1 95 -35 0 1 96 -35 0 1 263 -35 0 1 264 -35 0 1 265 -35 0 1 285 -35 0 1 286 -35 0 1 287 -35 0 1 71 -36 0 1 72 -36 0 1 93 -36 0 1 94 -36 0 1 265 -36 0 1 266 -36 0 1 287 -36 0 1 288 -36 0 1 70 -37 0 1 71 -37 0 1 91 -37 0 1 92 -37 0 1 93 -37 0 1 266 -37 0 1 267 -37 0 1 268 -37 0 1 288 -37 0 1 289 -37 0 1 68 -38 0 1 69 -38 0 1 70 -38 0 1 89 -38 0 1 90 -38 0 1 91 -38 0 1 268 -38 0 1 269 -38 0 1 270 -38 0 1 289 -38 0 1 290 -38 0 1 291 -38 0 1 67 -39 0 1 68 -39 0 1 88 -39 0 1 89 -39 0 1 270 -39 0 1 271 -39 0 1 291 -39 0 1 292 -39 0 1 66 -40 0 1 67 -40 0 1 86 -40 0 1 87 -40 0 1 88 -40 0 1 271 -40 0 1 272 -40 0 1 273 -40 0 1 292 -40 0 1 293 -40 0 1 65 -41 0 1 66 -41 0 1 85 -41 0 1 86 -41 0 1 273 -41 0 1 274 -41 0 1 293 -41 0 1 294 -41 0 1 63 -42 0 1 64 -42 0 1 65 -42 0 1 83 -42 0 1 84 -42 0 1 85 -42 0 1 274 -42 0 1 275 -42 0 1 276 -42 0 1 294 -42 0 1 295 -42 0 1 296 -42 0 1 62 -43 0 1 63 -43 0 1 82 -43 0 1 83 -43 0 1 276 -43 0 1 277 -43 0 1 296 -43 0 1 297 -43 0 1 61 -44 0 1 62 -44 0 1 81 -44 0 1 82 -44 0 1 277 -44 0 1 278 -44 0 1 297 -44 0 1 298 -44 0 1 60 -45 0 1 61 -45 0 1 79 -45 0 1 80 -45 0 1 81 -45 0 1 278 -45 0 1 279 -45 0 1 280 -45 0 1 298 -45 0 1 299 -45 0 1 59 -46 0 1 60 -46 0 1 78 -46 0 1 79 -46 0 1 280 -46 0 1 281 -46 0 1 299 -46 0 1 300 -46 0 1 58 -47 0 1 59 -47 0 1 77 -47 0 1 78 -47 0 1 281 -47 0 1 282 -47 0 1 300 -47 0 1 301 -47 0 1 57 -48 0 1 58 -48 0 1 75 -48 0 1 76 -48 0 1 77 -48 0 1 282 -48 0 1 283 -48 0 1 284 -48 0 1 301 -48 0 1 302 -48 0 1 56 -49 0 1 57 -49 0 1 74 -49 0 1 75 -49 0 1 284 -49 0 1 285 -49 0 1 302 -49 0 1 303 -49 0 1 55 -50 0 1 56 -50 0 1 73 -50 0 1 74 -50 0 1 285 -50 0 1 286 -50 0 1 303 -50 0 1 304 -50 0 1 54 -51 0 1 55 -51 0 1 72 -51 0 1 73 -51 0 1 286 -51 0 1 287 -51 0 1 304 -51 0 1 305 -51 0 1 53 -52 0 1 54 -52 0 1 71 -52 0 1 72 -52 0 1 287 -52 0 1 288 -52 0 1 305 -52 0 1 306 -52 0 1 52 -53 0 1 53 -53 0 1 70 -53 0 1 71 -53 0 1 288 -53 0 1 289 -53 0 1 306 -53 0 1 307 -53 0 1 51 -54 0 1 52 -54 0 1 68 -54 0 1 69 -54 0 1 70 -54 0 1 289 -54 0 1 290 -54 0 1 291 -54 0 1 307 -54 0 1 308 -54 0 1 50 -55 0 1 51 -55 0 1 67 -55 0 1 68 -55 0 1 291 -55 0 1 292 -55 0 1 308 -55 0 1 309 -55 0 1 49 -56 0 1 50 -56 0 1 66 -56 0 1 67 -56 0 1 292 -56 0 1 293 -56 0 1 309 -56 0 1 310 -56 0 1 48 -57 0 1 49 -57 0 1 65 -57 0 1 66 -57 0 1 293 -57 0 1 294 -57 0 1 310 -57 0 1 311 -57 0 1 47 -58 0 1 48 -58 0 1 64 -58 0 1 65 -58 0 1 294 -58 0 1 295 -58 0 1 311 -58 0 1 312 -58 0 1 46 -59 0 1 47 -59 0 1 63 -59 0 1 64 -59 0 1 295 -59 0 1 296 -59 0 1 312 -59 0 1 313 -59 0 1 45 -60 0 1 46 -60 0 1 62 -60 0 1 63 -60 0 1 296 -60 0 1 297 -60 0 1 313 -60 0 1 314 -60 0 1 44 -61 0 1 45 -61 0 1 61 -61 0 1 62 -61 0 1 297 -61 0 1 298 -61 0 1 314 -61 0 1 315 -61 0 1 43 -62 0 1 44 -62 0 1 60 -62 0 1 61 -62 0 1 298 -62 0 1 299 -62 0 1 315 -62 0 1 316 -62 0 1 42 -63 0 1 43 -63 0 1 59 -63 0 1 60 -63 0 1 299 -63 0 1 300 -63 0 1 316 -63 0 1 317 -63 0 1 42 -64 0 1 58 -64 0 1 59 -64 0 1 300 -64 0 1 301 -64 0 1 317 -64 0 1 41 -65 0 1 42 -65 0 1 57 -65 0 1 58 -65 0 1 301 -65 0 1 302 -65 0 1 317 -65 0 1 318 -65 0 1 40 -66 0 1 41 -66 0 1 56 -66 0 1 57 -66 0 1 302 -66 0 1 303 -66 0 1 318 -66 0 1 319 -66 0 1 39 -67 0 1 40 -67 0 1 55 -67 0 1 56 -67 0 1 303 -67 0 1 304 -67 0 1 319 -67 0 1 320 -67 0 1 38 -68 0 1 39 -68 0 1 54 -68 0 1 55 -68 0 1 304 -68 0 1 305 -68 0 1 320 -68 0 1 321 -68 0 1 38 -69 0 1 54 -69 0 1 305 -69 0 1 321 -69 0 1 37 -70 0 1 38 -70 0 1 52 -70 0 1 53 -70 0 1 54 -70 0 1 305 -70 0 1 306 -70 0 1 307 -70 0 1 321 -70 0 1 322 -70 0 1 36 -71 0 1 37 -71 0 1 52 -71 0 1 307 -71 0 1 322 -71 0 1 323 -71 0 1 35 -72 0 1 36 -72 0 1 51 -72 0 1 52 -72 0 1 307 -72 0 1 308 -72 0 1 323 -72 0 1 324 -72 0 1 35 -73 0 1 50 -73 0 1 51 -73 0 1 308 -73 0 1 309 -73 0 1 324 -73 0 1 34 -74 0 1 35 -74 0 1 49 -74 0 1 50 -74 0 1 309 -74 0 1 310 -74 0 1 324 -74 0 1 325 -74 0 1 33 -75 0 1 34 -75 0 1 48 -75 0 1 49 -75 0 1 310 -75 0 1 311 -75 0 1 325 -75 0 1 326 -75 0 1 32 -76 0 1 33 -76 0 1 48 -76 0 1 311 -76 0 1 326 -76 0 1 327 -76 0 1 32 -77 0 1 47 -77 0 1 48 -77 0 1 311 -77 0 1 312 -77 0 1 327 -77 0 1 31 -78 0 1 32 -78 0 1 46 -78 0 1 47 -78 0 1 312 -78 0 1 313 -78 0 1 327 -78 0 1 328 -78 0 1 31 -79 0 1 45 -79 0 1 46 -79 0 1 313 -79 0 1 314 -79 0 1 328 -79 0 1 30 -80 0 1 31 -80 0 1 45 -80 0 1 314 -80 0 1 328 -80 0 1 329 -80 0 1 29 -81 0 1 30 -81 0 1 44 -81 0 1 45 -81 0 1 314 -81 0 1 315 -81 0 1 329 -81 0 1 330 -81 0 1 29 -82 0 1 43 -82 0 1 44 -82 0 1 315 -82 0 1 316 -82 0 1 330 -82 0 1 28 -83 0 1 29 -83 0 1 42 -83 0 1 43 -83 0 1 316 -83 0 1 317 -83 0 1 330 -83 0 1 331 -83 0 1 27 -84 0 1 28 -84 0 1 42 -84 0 1 317 -84 0 1 331 -84 0 1 332 -84 0 1 27 -85 0 1 41 -85 0 1 42 -85 0 1 317 -85 0 1 318 -85 0 1 332 -85 0 1 26 -86 0 1 27 -86 0 1 40 -86 0 1 41 -86 0 1 318 -86 0 1 319 -86 0 1 332 -86 0 1 333 -86 0 1 25 -87 0 1 26 -87 0 1 40 -87 0 1 319 -87 0 1 333 -87 0 1 334 -87 0 1 25 -88 0 1 39 -88 0 1 40 -88 0 1 319 -88 0 1 320 -88 0 1 334 -88 0 1 24 -89 0 1 25 -89 0 1 38 -89 0 1 39 -89 0 1 320 -89 0 1 321 -89 0 1 334 -89 0 1 335 -89 0 1 24 -90 0 1 38 -90 0 1 321 -90 0 1 335 -90 0 1 23 -91 0 1 24 -91 0 1 37 -91 0 1 38 -91 0 1 321 -91 0 1 322 -91 0 1 335 -91 0 1 336 -91 0 1 22 -92 0 1 23 -92 0 1 37 -92 0 1 322 -92 0 1 336 -92 0 1 337 -92 0 1 22 -93 0 1 36 -93 0 1 37 -93 0 1 322 -93 0 1 323 -93 0 1 337 -93 0 1 21 -94 0 1 22 -94 0 1 35 -94 0 1 36 -94 0 1 323 -94 0 1 324 -94 0 1 337 -94 0 1 338 -94 0 1 21 -95 0 1 35 -95 0 1 324 -95 0 1 338 -95 0 1 20 -96 0 1 21 -96 0 1 34 -96 0 1 35 -96 0 1 324 -96 0 1 325 -96 0 1 338 -96 0 1 339 -96 0 1 20 -97 0 1 34 -97 0 1 325 -97 0 1 339 -97 0 1 19 -98 0 1 20 -98 0 1 33 -98 0 1 34 -98 0 1 325 -98 0 1 326 -98 0 1 339 -98 0 1 340 -98 0 1 19 -99 0 1 32 -99 0 1 33 -99 0 1 326 -99 0 1 327 -99 0 1 340 -99 0 1 18 -100 0 1 19 -100 0 1 32 -100 0 1 327 -100 0 1 340 -100 0 1 341 -100 0 1 18 -101 0 1 31 -101 0 1 32 -101 0 1 327 -101 0 1 328 -101 0 1 341 -101 0 1 17 -102 0 1 18 -102 0 1 31 -102 0 1 328 -102 0 1 341 -102 0 1 342 -102 0 1 17 -103 0 1 30 -103 0 1 31 -103 0 1 328 -103 0 1 329 -103 0 1 342 -103 0 1 16 -104 0 1 17 -104 0 1 30 -104 0 1 329 -104 0 1 342 -104 0 1 343 -104 0 1 16 -105 0 1 29 -105 0 1 30 -105 0 1 329 -105 0 1 330 -105 0 1 343 -105 0 1 15 -106 0 1 16 -106 0 1 29 -106 0 1 330 -106 0 1 343 -106 0 1 344 -106 0 1 15 -107 0 1 28 -107 0 1 29 -107 0 1 330 -107 0 1 331 -107 0 1 344 -107 0 1 15 -108 0 1 28 -108 0 1 331 -108 0 1 344 -108 0 1 14 -109 0 1 15 -109 0 1 28 -109 0 1 122 -109 0 2 123 -109 0 2 124 -109 0 2 125 -109 0 2 126 -109 0 2 127 -109 0 2 128 -109 0 2 129 -109 0 2 130 -109 0 2 131 -109 0 2 132 -109 0 2 133 -109 0 2 233 -109 0 2 234 -109 0 2 235 -109 0 2 236 -109 0 2 237 -109 0 2 238 -109 0 2 239 -109 0 2 240 -109 0 2 241 -109 0 2 242 -109 0 2 243 -109 0 2 244 -109 0 2 245 -109 0 2 331 -109 0 1 344 -109 0 1 345 -109 0 1 14 -110 0 1 27 -110 0 1 28 -110 0 1 118 -110 0 2 119 -110 0 2 120 -110 0 2 121 -110 0 2 122 -110 0 2 133 -110 0 2 134 -110 0 2 135 -110 0 2 136 -110 0 2 137 -110 0 2 230 -110 0 2 231 -110 0 2 232 -110 0 2 233 -110 0 2 245 -110 0 2 246 -110 0 2 247 -110 0 2 248 -110 0 2 331 -110 0 1 332 -110 0 1 345 -110 0 1 13 -111 0 1 14 -111 0 1 27 -111 0 1 115 -111 0 2 116 -111 0 2 117 -111 0 2 118 -111 0 2 137 -111 0 2 138 -111 0 2 139 -111 0 2 227 -111 0 2 228 -111 0 2 229 -111 0 2 230 -111 0 2 248 -111 0 2 249 -111 0 2 250 -111 0 2 251 -111 0 2 332 -111 0 1 345 -111 0 1 346 -111 0 1 13 -112 0 1 26 -112 0 1 27 -112 0 1 113 -112 0 2 114 -112 0 2 115 -112 0 2 139 -112 0 2 140 -112 0 2 141 -112 0 2 225 -112 0 2 226 -112 0 2 227 -112 0 2 251 -112 0 2 252 -112 0 2 253 -112 0 2 332 -112 0 1 333 -112 0 1 346 -112 0 1 12 -113 0 1 13 -113 0 1 26 -113 0 1 112 -113 0 2 113 -113 0 2 141 -113 0 2 142 -113 0 2 143 -113 0 2 223 -113 0 2 224 -113 0 2 225 -113 0 2 253 -113 0 2 254 -113 0 2 255 -113 0 2 333 -113 0 1 346 -113 0 1 347 -113 0 1 12 -114 0 1 25 -114 0 1 26 -114 0 1 110 -114 0 2 111 -114 0 2 112 -114 0 2 143 -114 0 2 144 -114 0 2 222 -114 0 2 223 -114 0 2 255 -114 0 2 256 -114 0 2 333 -114 0 1 334 -114 0 1 347 -114 0 1 12 -115 0 1 25 -115 0 1 109 -115 0 2 110 -115 0 2 144 -115 0 2 145 -115 0 2 221 -115 0 2 222 -115 0 2 256 -115 0 2 257 -115 0 2 334 -115 0 1 347 -115 0 1 11 -116 0 1 12 -116 0 1 24 -116 0 1 25 -116 0 1 108 -116 0 2 109 -116 0 2 145 -116 0 2 146 -116 0 2 147 -116 0 2 219 -116 0 2 220 -116 0 2 221 -116 0 2 257 -116 0 2 258 -116 0 2 334 -116 0 1 347 -116 0 1 348 -116 0 1 11 -117 0 1 24 -117 0 1 107 -117 0 2 108 -117 0 2 147 -117 0 2 148 -117 0 2 219 -117 0 2 258 -117 0 2 259 -117 0 2 260 -117 0 2 334 -117 0 1 335 -117 0 1 348 -117 0 1 11 -118 0 1 24 -118 0 1 106 -118 0 2 107 -118 0 2 148 -118 0 2 149 -118 0 2 218 -118 0 2 219 -118 0 2 260 -118 0 2 261 -118 0 2 335 -118 0 1 348 -118 0 1 10 -119 0 1 11 -119 0 1 23 -119 0 1 24 -119 0 1 105 -119 0 2 106 -119 0 2 149 -119 0 2 150 -119 0 2 217 -119 0 2 218 -119 0 2 261 -119 0 2 335 -119 0 1 336 -119 0 1 348 -119 0 1 349 -119 0 1 10 -120 0 1 23 -120 0 1 104 -120 0 2 105 -120 0 2 150 -120 0 2 216 -120 0 2 217 -120 0 2 261 -120 0 2 262 -120 0 2 336 -120 0 1 349 -120 0 1 10 -121 0 1 23 -121 0 1 103 -121 0 2 104 -121 0 2 150 -121 0 2 151 -121 0 2 215 -121 0 2 216 -121 0 2 262 -121 0 2 263 -121 0 2 336 -121 0 1 349 -121 0 1 9 -122 0 1 10 -122 0 1 22 -122 0 1 23 -122 0 1 103 -122 0 2 151 -122 0 2 152 -122 0 2 214 -122 0 2 215 -122 0 2 263 -122 0 2 336 -122 0 1 337 -122 0 1 349 -122 0 1 350 -122 0 1 9 -123 0 1 22 -123 0 1 102 -123 0 2 103 -123 0 2 152 -123 0 2 214 -123 0 2 263 -123 0 2 264 -123 0 2 337 -123 0 1 350 -123 0 1 9 -124 0 1 21 -124 0 1 22 -124 0 1 102 -124 0 2 152 -124 0 2 153 -124 0 2 213 -124 0 2 214 -124 0 2 264 -124 0 2 265 -124 0 2 337 -124 0 1 338 -124 0 1 350 -124 0 1 8 -125 0 1 9 -125 0 1 21 -125 0 1 101 -125 0 2 102 -125 0 2 153 -125 0 2 213 -125 0 2 265 -125 0 2 338 -125 0 1 350 -125 0 1 351 -125 0 1 8 -126 0 1 21 -126 0 1 101 -126 0 2 153 -126 0 2 154 -126 0 2 212 -126 0 2 213 -126 0 2 265 -126 0 2 266 -126 0 2 338 -126 0 1 351 -126 0 1 8 -127 0 1 20 -127 0 1 21 -127 0 1 100 -127 0 2 101 -127 0 2 154 -127 0 2 212 -127 0 2 266 -127 0 2 338 -127 0 1 339 -127 0 1 351 -127 0 1 7 -128 0 1 8 -128 0 1 20 -128 0 1 100 -128 0 2 154 -128 0 2 155 -128 0 2 212 -128 0 2 266 -128 0 2 339 -128 0 1 351 -128 0 1 352 -128 0 1 7 -129 0 1 20 -129 0 1 99 -129 0 2 100 -129 0 2 155 -129 0 2 211 -129 0 2 212 -129 0 2 266 -129 0 2 267 -129 0 2 339 -129 0 1 352 -129 0 1 7 -130 0 1 20 -130 0 1 99 -130 0 2 155 -130 0 2 211 -130 0 2 267 -130 0 2 339 -130 0 1 352 -130 0 1 6 -131 0 1 7 -131 0 1 19 -131 0 1 20 -131 0 1 99 -131 0 2 155 -131 0 2 156 -131 0 2 211 -131 0 2 267 -131 0 2 339 -131 0 1 340 -131 0 1 352 -131 0 1 353 -131 0 1 6 -132 0 1 19 -132 0 1 99 -132 0 2 156 -132 0 2 210 -132 0 2 211 -132 0 2 267 -132 0 2 268 -132 0 2 340 -132 0 1 353 -132 0 1 6 -133 0 1 19 -133 0 1 98 -133 0 2 99 -133 0 2 156 -133 0 2 210 -133 0 2 268 -133 0 2 340 -133 0 1 353 -133 0 1 6 -134 0 1 18 -134 0 1 19 -134 0 1 98 -134 0 2 156 -134 0 2 210 -134 0 2 268 -134 0 2 340 -134 0 1 341 -134 0 1 353 -134 0 1 5 -135 0 1 6 -135 0 1 18 -135 0 1 98 -135 0 2 156 -135 0 2 210 -135 0 2 268 -135 0 2 341 -135 0 1 353 -135 0 1 354 -135 0 1 5 -136 0 1 18 -136 0 1 98 -136 0 2 156 -136 0 2 210 -136 0 2 268 -136 0 2 341 -136 0 1 354 -136 0 1 5 -137 0 1 18 -137 0 1 98 -137 0 2 156 -137 0 2 210 -137 0 2 268 -137 0 2 341 -137 0 1 354 -137 0 1 5 -138 0 1 17 -138 0 1 18 -138 0 1 98 -138 0 2 156 -138 0 2 210 -138 0 2 268 -138 0 2 341 -138 0 1 342 -138 0 1 354 -138 0 1 4 -139 0 1 5 -139 0 1 17 -139 0 1 98 -139 0 2 156 -139 0 2 210 -139 0 2 268 -139 0 2 342 -139 0 1 354 -139 0 1 355 -139 0 1 4 -140 0 1 17 -140 0 1 98 -140 0 2 156 -140 0 2 210 -140 0 2 268 -140 0 2 342 -140 0 1 355 -140 0 1 4 -141 0 1 17 -141 0 1 98 -141 0 2 156 -141 0 2 210 -141 0 2 268 -141 0 2 342 -141 0 1 355 -141 0 1 4 -142 0 1 16 -142 0 1 17 -142 0 1 98 -142 0 2 156 -142 0 2 210 -142 0 2 268 -142 0 2 342 -142 0 1 343 -142 0 1 355 -142 0 1 4 -143 0 1 16 -143 0 1 98 -143 0 2 99 -143 0 2 156 -143 0 2 210 -143 0 2 268 -143 0 2 343 -143 0 1 355 -143 0 1 356 -143 0 1 3 -144 0 1 4 -144 0 1 16 -144 0 1 99 -144 0 2 156 -144 0 2 210 -144 0 2 211 -144 0 2 267 -144 0 2 268 -144 0 2 343 -144 0 1 356 -144 0 1 3 -145 0 1 16 -145 0 1 99 -145 0 2 155 -145 0 2 156 -145 0 2 211 -145 0 2 267 -145 0 2 343 -145 0 1 356 -145 0 1 3 -146 0 1 16 -146 0 1 99 -146 0 2 155 -146 0 2 211 -146 0 2 267 -146 0 2 343 -146 0 1 356 -146 0 1 3 -147 0 1 15 -147 0 1 16 -147 0 1 99 -147 0 2 100 -147 0 2 155 -147 0 2 211 -147 0 2 212 -147 0 2 266 -147 0 2 267 -147 0 2 343 -147 0 1 344 -147 0 1 356 -147 0 1 3 -148 0 1 15 -148 0 1 100 -148 0 2 154 -148 0 2 155 -148 0 2 212 -148 0 2 266 -148 0 2 344 -148 0 1 356 -148 0 1 2 -149 0 1 3 -149 0 1 15 -149 0 1 100 -149 0 2 154 -149 0 2 212 -149 0 2 266 -149 0 2 344 -149 0 1 356 -149 0 1 357 -149 0 1 2 -150 0 1 15 -150 0 1 100 -150 0 2 101 -150 0 2 154 -150 0 2 212 -150 0 2 213 -150 0 2 265 -150 0 2 266 -150 0 2 344 -150 0 1 357 -150 0 1 2 -151 0 1 15 -151 0 1 101 -151 0 2 102 -151 0 2 153 -151 0 2 154 -151 0 2 213 -151 0 2 265 -151 0 2 344 -151 0 1 357 -151 0 1 2 -152 0 1 14 -152 0 1 15 -152 0 1 102 -152 0 2 152 -152 0 2 153 -152 0 2 213 -152 0 2 214 -152 0 2 264 -152 0 2 265 -152 0 2 344 -152 0 1 345 -152 0 1 357 -152 0 1 2 -153 0 1 14 -153 0 1 102 -153 0 2 103 -153 0 2 152 -153 0 2 214 -153 0 2 264 -153 0 2 345 -153 0 1 357 -153 0 1 2 -154 0 1 14 -154 0 1 103 -154 0 2 151 -154 0 2 152 -154 0 2 214 -154 0 2 215 -154 0 2 263 -154 0 2 264 -154 0 2 345 -154 0 1 357 -154 0 1 2 -155 0 1 14 -155 0 1 103 -155 0 2 104 -155 0 2 150 -155 0 2 151 -155 0 2 215 -155 0 2 216 -155 0 2 262 -155 0 2 263 -155 0 2 345 -155 0 1 357 -155 0 1 1 -156 0 1 2 -156 0 1 14 -156 0 1 104 -156 0 2 105 -156 0 2 150 -156 0 2 216 -156 0 2 217 -156 0 2 261 -156 0 2 262 -156 0 2 345 -156 0 1 357 -156 0 1 358 -156 0 1 1 -157 0 1 14 -157 0 1 105 -157 0 2 106 -157 0 2 149 -157 0 2 150 -157 0 2 217 -157 0 2 260 -157 0 2 261 -157 0 2 345 -157 0 1 358 -157 0 1 1 -158 0 1 14 -158 0 1 106 -158 0 2 107 -158 0 2 148 -158 0 2 149 -158 0 2 217 -158 0 2 218 -158 0 2 259 -158 0 2 260 -158 0 2 345 -158 0 1 358 -158 0 1 1 -159 0 1 13 -159 0 1 14 -159 0 1 107 -159 0 2 108 -159 0 2 147 -159 0 2 148 -159 0 2 218 -159 0 2 219 -159 0 2 259 -159 0 2 345 -159 0 1 346 -159 0 1 358 -159 0 1 1 -160 0 1 13 -160 0 1 108 -160 0 2 109 -160 0 2 146 -160 0 2 147 -160 0 2 219 -160 0 2 220 -160 0 2 221 -160 0 2 257 -160 0 2 258 -160 0 2 259 -160 0 2 346 -160 0 1 358 -160 0 1 1 -161 0 1 13 -161 0 1 109 -161 0 2 110 -161 0 2 144 -161 0 2 145 -161 0 2 146 -161 0 2 221 -161 0 2 222 -161 0 2 256 -161 0 2 257 -161 0 2 346 -161 0 1 358 -161 0 1 1 -162 0 1 13 -162 0 1 110 -162 0 2 111 -162 0 2 112 -162 0 2 143 -162 0 2 144 -162 0 2 222 -162 0 2 223 -162 0 2 255 -162 0 2 256 -162 0 2 346 -162 0 1 358 -162 0 1 1 -163 0 1 13 -163 0 1 112 -163 0 2 113 -163 0 2 141 -163 0 2 142 -163 0 2 143 -163 0 2 223 -163 0 2 224 -163 0 2 225 -163 0 2 253 -163 0 2 254 -163 0 2 255 -163 0 2 346 -163 0 1 358 -163 0 1 1 -164 0 1 13 -164 0 1 113 -164 0 2 114 -164 0 2 115 -164 0 2 139 -164 0 2 140 -164 0 2 141 -164 0 2 225 -164 0 2 226 -164 0 2 227 -164 0 2 251 -164 0 2 252 -164 0 2 253 -164 0 2 346 -164 0 1 358 -164 0 1 0 -165 0 1 1 -165 0 1 13 -165 0 1 115 -165 0 2 116 -165 0 2 117 -165 0 2 118 -165 0 2 137 -165 0 2 138 -165 0 2 139 -165 0 2 227 -165 0 2 228 -165 0 2 229 -165 0 2 230 -165 0 2 249 -165 0 2 250 -165 0 2 251 -165 0 2 346 -165 0 1 358 -165 0 1 359 -165 0 1 13 -166 0 1 118 -166 0 2 119 -166 0 2 120 -166 0 2 121 -166 0 2 133 -166 0 2 134 -166 0 2 135 -166 0 2 136 -166 0 2 137 -166 0 2 230 -166 0 2 231 -166 0 2 232 -166 0 2 233 -166 0 2 245 -166 0 2 246 -166 0 2 247 -166 0 2 248 -166 0 2 249 -166 0 2 346 -166 0 1 13 -167 0 1 121 -167 0 2 122 -167 0 2 123 -167 0 2 124 -167 0 2 125 -167 0 2 126 -167 0 2 127 -167 0 2 128 -167 0 2 129 -167 0 2 130 -167 0 2 131 -167 0 2 132 -167 0 2 133 -167 0 2 233 -167 0 2 234 -167 0 2 235 -167 0 2 236 -167 0 2 237 -167 0 2 238 -167 0 2 239 -167 0 2 240 -167 0 2 241 -167 0 2 242 -167 0 2 243 -167 0 2 244 -167 0 2 245 -167 0 2 346 -167 0 1 13 -168 0 1 346 -168 0 1 13 -169 0 1 346 -169 0 1 13 -170 0 1 346 -170 0 1 13 -171 0 1 346 -171 0 1 12 -172 0 1 13 -172 0 1 346 -172 0 1 347 -172 0 1 12 -173 0 1 347 -173 0 1 12 -174 0 1 347 -174 0 1 12 -175 0 1 347 -175 0 1 12 -176 0 1 347 -176 0 1 12 -177 0 1 347 -177 0 1 12 -178 0 1 347 -178 0 1 12 -179 0 1 347 -179 0 1 12 -180 0 1 347 -180 0 1 12 -181 0 1 347 -181 0 1 12 -182 0 1 347 -182 0 1 12 -183 0 1 347 -183 0 1 12 -184 0 1 347 -184 0 1 12 -185 0 1 347 -185 0 1 12 -186 0 1 347 -186 0 1 12 -187 0 1 13 -187 0 1 346 -187 0 1 347 -187 0 1 13 -188 0 1 346 -188 0 1 13 -189 0 1 346 -189 0 1 13 -190 0 1 346 -190 0 1 13 -191 0 1 346 -191 0 1 13 -192 0 1 346 -192 0 1 13 -193 0 1 346 -193 0 1 0 -194 0 1 1 -194 0 1 13 -194 0 1 346 -194 0 1 358 -194 0 1 359 -194 0 1 1 -195 0 1 13 -195 0 1 346 -195 0 1 358 -195 0 1 1 -196 0 1 13 -196 0 1 346 -196 0 1 358 -196 0 1 1 -197 0 1 13 -197 0 1 346 -197 0 1 358 -197 0 1 1 -198 0 1 13 -198 0 1 346 -198 0 1 358 -198 0 1 1 -199 0 1 13 -199 0 1 346 -199 0 1 358 -199 0 1 1 -200 0 1 13 -200 0 1 14 -200 0 1 345 -200 0 1 346 -200 0 1 358 -200 0 1 1 -201 0 1 14 -201 0 1 345 -201 0 1 358 -201 0 1 1 -202 0 1 14 -202 0 1 76 -202 0 4 77 -202 0 4 78 -202 0 4 79 -202 0 4 80 -202 0 4 81 -202 0 4 82 -202 0 4 83 -202 0 4 84 -202 0 4 85 -202 0 4 86 -202 0 4 87 -202 0 4 88 -202 0 4 89 -202 0 4 270 -202 0 4 271 -202 0 4 272 -202 0 4 273 -202 0 4 274 -202 0 4 275 -202 0 4 276 -202 0 4 277 -202 0 4 278 -202 0 4 279 -202 0 4 280 -202 0 4 281 -202 0 4 282 -202 0 4 283 -202 0 4 345 -202 0 1 358 -202 0 1 1 -203 0 1 2 -203 0 1 14 -203 0 1 76 -203 0 4 89 -203 0 4 270 -203 0 4 283 -203 0 4 345 -203 0 1 357 -203 0 1 358 -203 0 1 2 -204 0 1 14 -204 0 1 76 -204 0 4 89 -204 0 4 270 -204 0 4 283 -204 0 4 345 -204 0 1 357 -204 0 1 2 -205 0 1 14 -205 0 1 76 -205 0 4 77 -205 0 4 89 -205 0 4 270 -205 0 4 283 -205 0 4 345 -205 0 1 357 -205 0 1 2 -206 0 1 14 -206 0 1 77 -206 0 4 89 -206 0 4 270 -206 0 4 282 -206 0 4 283 -206 0 4 345 -206 0 1 357 -206 0 1 2 -207 0 1 14 -207 0 1 15 -207 0 1 77 -207 0 4 89 -207 0 4 270 -207 0 4 282 -207 0 4 344 -207 0 1 345 -207 0 1 357 -207 0 1 2 -208 0 1 15 -208 0 1 77 -208 0 4 89 -208 0 4 270 -208 0 4 282 -208 0 4 344 -208 0 1 357 -208 0 1 2 -209 0 1 15 -209 0 1 77 -209 0 4 89 -209 0 4 270 -209 0 4 282 -209 0 4 344 -209 0 1 357 -209 0 1 2 -210 0 1 3 -210 0 1 15 -210 0 1 77 -210 0 4 89 -210 0 4 270 -210 0 4 282 -210 0 4 344 -210 0 1 356 -210 0 1 357 -210 0 1 3 -211 0 1 15 -211 0 1 77 -211 0 4 89 -211 0 4 270 -211 0 4 282 -211 0 4 344 -211 0 1 356 -211 0 1 3 -212 0 1 15 -212 0 1 16 -212 0 1 77 -212 0 4 89 -212 0 4 90 -212 0 4 269 -212 0 4 270 -212 0 4 282 -212 0 4 343 -212 0 1 344 -212 0 1 356 -212 0 1 3 -213 0 1 16 -213 0 1 77 -213 0 4 90 -213 0 4 269 -213 0 4 282 -213 0 4 343 -213 0 1 356 -213 0 1 3 -214 0 1 16 -214 0 1 77 -214 0 4 90 -214 0 4 269 -214 0 4 282 -214 0 4 343 -214 0 1 356 -214 0 1 3 -215 0 1 16 -215 0 1 77 -215 0 4 90 -215 0 4 269 -215 0 4 282 -215 0 4 343 -215 0 1 355 -215 0 1 356 -215 0 1 3 -216 0 1 4 -216 0 1 16 -216 0 1 77 -216 0 4 78 -216 0 4 90 -216 0 4 269 -216 0 4 281 -216 0 4 282 -216 0 4 343 -216 0 1 355 -216 0 1 4 -217 0 1 16 -217 0 1 17 -217 0 1 78 -217 0 4 90 -217 0 4 269 -217 0 4 281 -217 0 4 342 -217 0 1 343 -217 0 1 355 -217 0 1 4 -218 0 1 17 -218 0 1 78 -218 0 4 90 -218 0 4 269 -218 0 4 281 -218 0 4 342 -218 0 1 355 -218 0 1 4 -219 0 1 17 -219 0 1 78 -219 0 4 90 -219 0 4 91 -219 0 4 268 -219 0 4 269 -219 0 4 281 -219 0 4 342 -219 0 1 355 -219 0 1 4 -220 0 1 5 -220 0 1 17 -220 0 1 78 -220 0 4 91 -220 0 4 268 -220 0 4 281 -220 0 4 342 -220 0 1 354 -220 0 1 355 -220 0 1 5 -221 0 1 17 -221 0 1 18 -221 0 1 78 -221 0 4 91 -221 0 4 268 -221 0 4 281 -221 0 4 341 -221 0 1 342 -221 0 1 354 -221 0 1 5 -222 0 1 18 -222 0 1 78 -222 0 4 79 -222 0 4 91 -222 0 4 268 -222 0 4 280 -222 0 4 281 -222 0 4 341 -222 0 1 354 -222 0 1 5 -223 0 1 18 -223 0 1 79 -223 0 4 91 -223 0 4 268 -223 0 4 280 -223 0 4 341 -223 0 1 354 -223 0 1 5 -224 0 1 6 -224 0 1 18 -224 0 1 79 -224 0 4 91 -224 0 4 92 -224 0 4 267 -224 0 4 268 -224 0 4 280 -224 0 4 341 -224 0 1 353 -224 0 1 354 -224 0 1 6 -225 0 1 18 -225 0 1 19 -225 0 1 79 -225 0 4 92 -225 0 4 267 -225 0 4 280 -225 0 4 340 -225 0 1 341 -225 0 1 353 -225 0 1 6 -226 0 1 19 -226 0 1 79 -226 0 4 80 -226 0 4 92 -226 0 4 267 -226 0 4 279 -226 0 4 280 -226 0 4 340 -226 0 1 353 -226 0 1 6 -227 0 1 19 -227 0 1 80 -227 0 4 92 -227 0 4 93 -227 0 4 266 -227 0 4 267 -227 0 4 279 -227 0 4 340 -227 0 1 353 -227 0 1 6 -228 0 1 7 -228 0 1 19 -228 0 1 20 -228 0 1 80 -228 0 4 93 -228 0 4 266 -228 0 4 279 -228 0 4 339 -228 0 1 340 -228 0 1 352 -228 0 1 353 -228 0 1 7 -229 0 1 20 -229 0 1 80 -229 0 4 93 -229 0 4 266 -229 0 4 279 -229 0 4 339 -229 0 1 352 -229 0 1 7 -230 0 1 20 -230 0 1 80 -230 0 4 81 -230 0 4 93 -230 0 4 94 -230 0 4 265 -230 0 4 266 -230 0 4 278 -230 0 4 279 -230 0 4 339 -230 0 1 352 -230 0 1 7 -231 0 1 8 -231 0 1 20 -231 0 1 81 -231 0 4 94 -231 0 4 265 -231 0 4 278 -231 0 4 339 -231 0 1 351 -231 0 1 352 -231 0 1 8 -232 0 1 20 -232 0 1 21 -232 0 1 81 -232 0 4 94 -232 0 4 265 -232 0 4 278 -232 0 4 338 -232 0 1 339 -232 0 1 351 -232 0 1 8 -233 0 1 21 -233 0 1 81 -233 0 4 82 -233 0 4 94 -233 0 4 95 -233 0 4 264 -233 0 4 265 -233 0 4 277 -233 0 4 278 -233 0 4 338 -233 0 1 351 -233 0 1 8 -234 0 1 9 -234 0 1 21 -234 0 1 22 -234 0 1 82 -234 0 4 95 -234 0 4 264 -234 0 4 277 -234 0 4 338 -234 0 1 350 -234 0 1 351 -234 0 1 9 -235 0 1 22 -235 0 1 82 -235 0 4 95 -235 0 4 264 -235 0 4 277 -235 0 4 337 -235 0 1 338 -235 0 1 350 -235 0 1 9 -236 0 1 22 -236 0 1 82 -236 0 4 83 -236 0 4 95 -236 0 4 96 -236 0 4 263 -236 0 4 264 -236 0 4 276 -236 0 4 277 -236 0 4 337 -236 0 1 350 -236 0 1 9 -237 0 1 10 -237 0 1 22 -237 0 1 23 -237 0 1 83 -237 0 4 96 -237 0 4 263 -237 0 4 276 -237 0 4 336 -237 0 1 337 -237 0 1 349 -237 0 1 350 -237 0 1 10 -238 0 1 23 -238 0 1 83 -238 0 4 96 -238 0 4 97 -238 0 4 262 -238 0 4 263 -238 0 4 276 -238 0 4 336 -238 0 1 349 -238 0 1 10 -239 0 1 23 -239 0 1 83 -239 0 4 84 -239 0 4 97 -239 0 4 262 -239 0 4 275 -239 0 4 276 -239 0 4 336 -239 0 1 349 -239 0 1 10 -240 0 1 11 -240 0 1 23 -240 0 1 24 -240 0 1 84 -240 0 4 97 -240 0 4 98 -240 0 4 261 -240 0 4 262 -240 0 4 275 -240 0 4 335 -240 0 1 336 -240 0 1 348 -240 0 1 349 -240 0 1 11 -241 0 1 24 -241 0 1 84 -241 0 4 85 -241 0 4 98 -241 0 4 261 -241 0 4 274 -241 0 4 275 -241 0 4 335 -241 0 1 348 -241 0 1 11 -242 0 1 24 -242 0 1 25 -242 0 1 85 -242 0 4 98 -242 0 4 99 -242 0 4 260 -242 0 4 261 -242 0 4 274 -242 0 4 335 -242 0 1 348 -242 0 1 11 -243 0 1 12 -243 0 1 25 -243 0 1 85 -243 0 4 99 -243 0 4 260 -243 0 4 274 -243 0 4 334 -243 0 1 335 -243 0 1 347 -243 0 1 348 -243 0 1 12 -244 0 1 25 -244 0 1 85 -244 0 4 86 -244 0 4 99 -244 0 4 100 -244 0 4 259 -244 0 4 260 -244 0 4 273 -244 0 4 274 -244 0 4 334 -244 0 1 347 -244 0 1 12 -245 0 1 13 -245 0 1 25 -245 0 1 26 -245 0 1 86 -245 0 4 100 -245 0 4 259 -245 0 4 273 -245 0 4 333 -245 0 1 334 -245 0 1 347 -245 0 1 13 -246 0 1 26 -246 0 1 86 -246 0 4 87 -246 0 4 100 -246 0 4 101 -246 0 4 258 -246 0 4 259 -246 0 4 272 -246 0 4 273 -246 0 4 333 -246 0 1 346 -246 0 1 347 -246 0 1 13 -247 0 1 26 -247 0 1 27 -247 0 1 87 -247 0 4 101 -247 0 4 258 -247 0 4 272 -247 0 4 332 -247 0 1 333 -247 0 1 346 -247 0 1 13 -248 0 1 14 -248 0 1 27 -248 0 1 87 -248 0 4 88 -248 0 4 101 -248 0 4 102 -248 0 4 257 -248 0 4 258 -248 0 4 271 -248 0 4 272 -248 0 4 332 -248 0 1 345 -248 0 1 346 -248 0 1 14 -249 0 1 27 -249 0 1 28 -249 0 1 88 -249 0 4 102 -249 0 4 103 -249 0 4 256 -249 0 4 257 -249 0 4 271 -249 0 4 331 -249 0 1 332 -249 0 1 345 -249 0 1 14 -250 0 1 15 -250 0 1 28 -250 0 1 88 -250 0 4 89 -250 0 4 103 -250 0 4 256 -250 0 4 270 -250 0 4 271 -250 0 4 331 -250 0 1 344 -250 0 1 345 -250 0 1 15 -251 0 1 28 -251 0 1 89 -251 0 4 103 -251 0 4 104 -251 0 4 255 -251 0 4 256 -251 0 4 269 -251 0 4 270 -251 0 4 331 -251 0 1 344 -251 0 1 15 -252 0 1 28 -252 0 1 29 -252 0 1 89 -252 0 4 90 -252 0 4 104 -252 0 4 255 -252 0 4 269 -252 0 4 330 -252 0 1 331 -252 0 1 344 -252 0 1 15 -253 0 1 16 -253 0 1 29 -253 0 1 90 -253 0 4 91 -253 0 4 104 -253 0 4 105 -253 0 4 254 -253 0 4 255 -253 0 4 268 -253 0 4 269 -253 0 4 330 -253 0 1 343 -253 0 1 344 -253 0 1 16 -254 0 1 29 -254 0 1 30 -254 0 1 91 -254 0 4 105 -254 0 4 106 -254 0 4 253 -254 0 4 254 -254 0 4 268 -254 0 4 329 -254 0 1 330 -254 0 1 343 -254 0 1 16 -255 0 1 17 -255 0 1 30 -255 0 1 91 -255 0 4 92 -255 0 4 106 -255 0 4 107 -255 0 4 252 -255 0 4 253 -255 0 4 267 -255 0 4 268 -255 0 4 329 -255 0 1 342 -255 0 1 343 -255 0 1 17 -256 0 1 30 -256 0 1 31 -256 0 1 92 -256 0 4 93 -256 0 4 107 -256 0 4 252 -256 0 4 266 -256 0 4 267 -256 0 4 328 -256 0 1 329 -256 0 1 342 -256 0 1 17 -257 0 1 18 -257 0 1 31 -257 0 1 93 -257 0 4 107 -257 0 4 108 -257 0 4 251 -257 0 4 252 -257 0 4 266 -257 0 4 328 -257 0 1 341 -257 0 1 342 -257 0 1 18 -258 0 1 31 -258 0 1 32 -258 0 1 93 -258 0 4 94 -258 0 4 108 -258 0 4 109 -258 0 4 250 -258 0 4 251 -258 0 4 265 -258 0 4 266 -258 0 4 327 -258 0 1 328 -258 0 1 341 -258 0 1 18 -259 0 1 19 -259 0 1 32 -259 0 1 94 -259 0 4 95 -259 0 4 109 -259 0 4 110 -259 0 4 249 -259 0 4 250 -259 0 4 265 -259 0 4 327 -259 0 1 340 -259 0 1 341 -259 0 1 19 -260 0 1 32 -260 0 1 33 -260 0 1 95 -260 0 4 110 -260 0 4 111 -260 0 4 248 -260 0 4 249 -260 0 4 264 -260 0 4 265 -260 0 4 326 -260 0 1 327 -260 0 1 340 -260 0 1 19 -261 0 1 20 -261 0 1 33 -261 0 1 34 -261 0 1 95 -261 0 4 96 -261 0 4 111 -261 0 4 112 -261 0 4 247 -261 0 4 248 -261 0 4 263 -261 0 4 264 -261 0 4 325 -261 0 1 326 -261 0 1 339 -261 0 1 340 -261 0 1 20 -262 0 1 34 -262 0 1 96 -262 0 4 97 -262 0 4 112 -262 0 4 247 -262 0 4 262 -262 0 4 263 -262 0 4 325 -262 0 1 339 -262 0 1 20 -263 0 1 21 -263 0 1 34 -263 0 1 35 -263 0 1 97 -263 0 4 112 -263 0 4 113 -263 0 4 246 -263 0 4 247 -263 0 4 262 -263 0 4 324 -263 0 1 325 -263 0 1 338 -263 0 1 339 -263 0 1 21 -264 0 1 35 -264 0 1 97 -264 0 4 98 -264 0 4 113 -264 0 4 114 -264 0 4 245 -264 0 4 246 -264 0 4 261 -264 0 4 262 -264 0 4 324 -264 0 1 338 -264 0 1 21 -265 0 1 22 -265 0 1 35 -265 0 1 36 -265 0 1 98 -265 0 4 99 -265 0 4 114 -265 0 4 115 -265 0 4 244 -265 0 4 245 -265 0 4 260 -265 0 4 261 -265 0 4 323 -265 0 1 324 -265 0 1 337 -265 0 1 338 -265 0 1 22 -266 0 1 36 -266 0 1 37 -266 0 1 99 -266 0 4 100 -266 0 4 115 -266 0 4 116 -266 0 4 243 -266 0 4 244 -266 0 4 259 -266 0 4 260 -266 0 4 322 -266 0 1 323 -266 0 1 337 -266 0 1 22 -267 0 1 23 -267 0 1 37 -267 0 1 100 -267 0 4 101 -267 0 4 116 -267 0 4 117 -267 0 4 242 -267 0 4 243 -267 0 4 258 -267 0 4 259 -267 0 4 322 -267 0 1 336 -267 0 1 337 -267 0 1 23 -268 0 1 24 -268 0 1 37 -268 0 1 38 -268 0 1 101 -268 0 4 102 -268 0 4 117 -268 0 4 118 -268 0 4 241 -268 0 4 242 -268 0 4 257 -268 0 4 258 -268 0 4 321 -268 0 1 322 -268 0 1 335 -268 0 1 336 -268 0 1 24 -269 0 1 38 -269 0 1 102 -269 0 4 118 -269 0 4 119 -269 0 4 120 -269 0 4 239 -269 0 4 240 -269 0 4 241 -269 0 4 257 -269 0 4 321 -269 0 1 335 -269 0 1 24 -270 0 1 25 -270 0 1 38 -270 0 1 39 -270 0 1 102 -270 0 4 103 -270 0 4 120 -270 0 4 121 -270 0 4 238 -270 0 4 239 -270 0 4 256 -270 0 4 257 -270 0 4 320 -270 0 1 321 -270 0 1 334 -270 0 1 335 -270 0 1 25 -271 0 1 39 -271 0 1 40 -271 0 1 103 -271 0 4 104 -271 0 4 121 -271 0 4 122 -271 0 4 237 -271 0 4 238 -271 0 4 255 -271 0 4 256 -271 0 4 319 -271 0 1 320 -271 0 1 334 -271 0 1 25 -272 0 1 26 -272 0 1 40 -272 0 1 104 -272 0 4 105 -272 0 4 122 -272 0 4 123 -272 0 4 236 -272 0 4 237 -272 0 4 254 -272 0 4 255 -272 0 4 319 -272 0 1 333 -272 0 1 334 -272 0 1 26 -273 0 1 27 -273 0 1 40 -273 0 1 41 -273 0 1 105 -273 0 4 106 -273 0 4 123 -273 0 4 124 -273 0 4 235 -273 0 4 236 -273 0 4 253 -273 0 4 254 -273 0 4 318 -273 0 1 319 -273 0 1 332 -273 0 1 333 -273 0 1 27 -274 0 1 41 -274 0 1 42 -274 0 1 106 -274 0 4 107 -274 0 4 124 -274 0 4 125 -274 0 4 126 -274 0 4 233 -274 0 4 234 -274 0 4 235 -274 0 4 252 -274 0 4 253 -274 0 4 317 -274 0 1 318 -274 0 1 332 -274 0 1 27 -275 0 1 28 -275 0 1 42 -275 0 1 107 -275 0 4 108 -275 0 4 126 -275 0 4 127 -275 0 4 232 -275 0 4 233 -275 0 4 251 -275 0 4 252 -275 0 4 317 -275 0 1 331 -275 0 1 332 -275 0 1 28 -276 0 1 29 -276 0 1 42 -276 0 1 43 -276 0 1 108 -276 0 4 109 -276 0 4 127 -276 0 4 128 -276 0 4 231 -276 0 4 232 -276 0 4 250 -276 0 4 251 -276 0 4 316 -276 0 1 317 -276 0 1 330 -276 0 1 331 -276 0 1 29 -277 0 1 43 -277 0 1 44 -277 0 1 109 -277 0 4 110 -277 0 4 128 -277 0 4 129 -277 0 4 130 -277 0 4 229 -277 0 4 230 -277 0 4 231 -277 0 4 249 -277 0 4 250 -277 0 4 315 -277 0 1 316 -277 0 1 330 -277 0 1 29 -278 0 1 30 -278 0 1 44 -278 0 1 45 -278 0 1 110 -278 0 4 111 -278 0 4 130 -278 0 4 131 -278 0 4 132 -278 0 4 227 -278 0 4 228 -278 0 4 229 -278 0 4 248 -278 0 4 249 -278 0 4 314 -278 0 1 315 -278 0 1 329 -278 0 1 330 -278 0 1 30 -279 0 1 31 -279 0 1 45 -279 0 1 111 -279 0 4 112 -279 0 4 132 -279 0 4 133 -279 0 4 226 -279 0 4 227 -279 0 4 247 -279 0 4 248 -279 0 4 314 -279 0 1 328 -279 0 1 329 -279 0 1 31 -280 0 1 45 -280 0 1 46 -280 0 1 112 -280 0 4 113 -280 0 4 133 -280 0 4 134 -280 0 4 135 -280 0 4 224 -280 0 4 225 -280 0 4 226 -280 0 4 246 -280 0 4 247 -280 0 4 313 -280 0 1 314 -280 0 1 328 -280 0 1 31 -281 0 1 32 -281 0 1 46 -281 0 1 47 -281 0 1 113 -281 0 4 114 -281 0 4 115 -281 0 4 135 -281 0 4 136 -281 0 4 137 -281 0 4 222 -281 0 4 223 -281 0 4 224 -281 0 4 244 -281 0 4 245 -281 0 4 246 -281 0 4 312 -281 0 1 313 -281 0 1 327 -281 0 1 328 -281 0 1 32 -282 0 1 47 -282 0 1 48 -282 0 1 115 -282 0 4 116 -282 0 4 137 -282 0 4 138 -282 0 4 139 -282 0 4 220 -282 0 4 221 -282 0 4 222 -282 0 4 243 -282 0 4 244 -282 0 4 311 -282 0 1 312 -282 0 1 327 -282 0 1 32 -283 0 1 33 -283 0 1 48 -283 0 1 116 -283 0 4 117 -283 0 4 139 -283 0 4 140 -283 0 4 141 -283 0 4 218 -283 0 4 219 -283 0 4 220 -283 0 4 242 -283 0 4 243 -283 0 4 311 -283 0 1 326 -283 0 1 327 -283 0 1 33 -284 0 1 34 -284 0 1 48 -284 0 1 49 -284 0 1 117 -284 0 4 118 -284 0 4 119 -284 0 4 141 -284 0 4 142 -284 0 4 143 -284 0 4 216 -284 0 4 217 -284 0 4 218 -284 0 4 240 -284 0 4 241 -284 0 4 242 -284 0 4 310 -284 0 1 311 -284 0 1 325 -284 0 1 326 -284 0 1 34 -285 0 1 35 -285 0 1 49 -285 0 1 50 -285 0 1 119 -285 0 4 120 -285 0 4 143 -285 0 4 144 -285 0 4 145 -285 0 4 214 -285 0 4 215 -285 0 4 216 -285 0 4 239 -285 0 4 240 -285 0 4 309 -285 0 1 310 -285 0 1 324 -285 0 1 325 -285 0 1 35 -286 0 1 50 -286 0 1 51 -286 0 1 120 -286 0 4 121 -286 0 4 145 -286 0 4 146 -286 0 4 147 -286 0 4 148 -286 0 4 211 -286 0 4 212 -286 0 4 213 -286 0 4 214 -286 0 4 238 -286 0 4 239 -286 0 4 308 -286 0 1 309 -286 0 1 324 -286 0 1 35 -287 0 1 36 -287 0 1 51 -287 0 1 52 -287 0 1 121 -287 0 4 122 -287 0 4 123 -287 0 4 148 -287 0 4 149 -287 0 4 150 -287 0 4 151 -287 0 4 208 -287 0 4 209 -287 0 4 210 -287 0 4 211 -287 0 4 236 -287 0 4 237 -287 0 4 238 -287 0 4 307 -287 0 1 308 -287 0 1 323 -287 0 1 324 -287 0 1 36 -288 0 1 37 -288 0 1 52 -288 0 1 123 -288 0 4 124 -288 0 4 151 -288 0 4 152 -288 0 4 153 -288 0 4 154 -288 0 4 205 -288 0 4 206 -288 0 4 207 -288 0 4 208 -288 0 4 234 -288 0 4 235 -288 0 4 236 -288 0 4 307 -288 0 1 322 -288 0 1 323 -288 0 1 37 -289 0 1 38 -289 0 1 52 -289 0 1 53 -289 0 1 54 -289 0 1 124 -289 0 4 125 -289 0 4 126 -289 0 4 154 -289 0 4 155 -289 0 4 156 -289 0 4 157 -289 0 4 158 -289 0 4 201 -289 0 4 202 -289 0 4 203 -289 0 4 204 -289 0 4 205 -289 0 4 233 -289 0 4 234 -289 0 4 305 -289 0 1 306 -289 0 1 307 -289 0 1 321 -289 0 1 322 -289 0 1 38 -290 0 1 54 -290 0 1 126 -290 0 4 127 -290 0 4 128 -290 0 4 158 -290 0 4 159 -290 0 4 160 -290 0 4 161 -290 0 4 162 -290 0 4 197 -290 0 4 198 -290 0 4 199 -290 0 4 200 -290 0 4 201 -290 0 4 231 -290 0 4 232 -290 0 4 233 -290 0 4 305 -290 0 1 321 -290 0 1 38 -291 0 1 39 -291 0 1 54 -291 0 1 55 -291 0 1 128 -291 0 4 129 -291 0 4 130 -291 0 4 162 -291 0 4 163 -291 0 4 164 -291 0 4 165 -291 0 4 166 -291 0 4 167 -291 0 4 168 -291 0 4 169 -291 0 4 170 -291 0 4 189 -291 0 4 190 -291 0 4 191 -291 0 4 192 -291 0 4 193 -291 0 4 194 -291 0 4 195 -291 0 4 196 -291 0 4 197 -291 0 4 229 -291 0 4 230 -291 0 4 231 -291 0 4 304 -291 0 1 305 -291 0 1 320 -291 0 1 321 -291 0 1 39 -292 0 1 40 -292 0 1 55 -292 0 1 56 -292 0 1 130 -292 0 4 131 -292 0 4 132 -292 0 4 170 -292 0 4 171 -292 0 4 172 -292 0 4 173 -292 0 4 174 -292 0 4 175 -292 0 4 176 -292 0 4 177 -292 0 4 178 -292 0 4 179 -292 0 4 180 -292 0 4 181 -292 0 4 182 -292 0 4 183 -292 0 4 184 -292 0 4 185 -292 0 4 186 -292 0 4 187 -292 0 4 188 -292 0 4 189 -292 0 4 228 -292 0 4 229 -292 0 4 303 -292 0 1 304 -292 0 1 319 -292 0 1 320 -292 0 1 40 -293 0 1 41 -293 0 1 56 -293 0 1 57 -293 0 1 132 -293 0 4 133 -293 0 4 226 -293 0 4 227 -293 0 4 228 -293 0 4 302 -293 0 1 303 -293 0 1 318 -293 0 1 319 -293 0 1 41 -294 0 1 42 -294 0 1 57 -294 0 1 58 -294 0 1 133 -294 0 4 134 -294 0 4 135 -294 0 4 136 -294 0 4 223 -294 0 4 224 -294 0 4 225 -294 0 4 226 -294 0 4 301 -294 0 1 302 -294 0 1 317 -294 0 1 318 -294 0 1 42 -295 0 1 58 -295 0 1 59 -295 0 1 136 -295 0 4 137 -295 0 4 138 -295 0 4 221 -295 0 4 222 -295 0 4 223 -295 0 4 300 -295 0 1 301 -295 0 1 317 -295 0 1 42 -296 0 1 43 -296 0 1 59 -296 0 1 60 -296 0 1 138 -296 0 4 139 -296 0 4 140 -296 0 4 219 -296 0 4 220 -296 0 4 221 -296 0 4 299 -296 0 1 300 -296 0 1 316 -296 0 1 317 -296 0 1 43 -297 0 1 44 -297 0 1 60 -297 0 1 61 -297 0 1 140 -297 0 4 141 -297 0 4 142 -297 0 4 217 -297 0 4 218 -297 0 4 219 -297 0 4 298 -297 0 1 299 -297 0 1 315 -297 0 1 316 -297 0 1 44 -298 0 1 45 -298 0 1 61 -298 0 1 62 -298 0 1 142 -298 0 4 143 -298 0 4 144 -298 0 4 145 -298 0 4 214 -298 0 4 215 -298 0 4 216 -298 0 4 217 -298 0 4 297 -298 0 1 298 -298 0 1 314 -298 0 1 315 -298 0 1 45 -299 0 1 46 -299 0 1 62 -299 0 1 63 -299 0 1 145 -299 0 4 146 -299 0 4 147 -299 0 4 148 -299 0 4 211 -299 0 4 212 -299 0 4 213 -299 0 4 214 -299 0 4 296 -299 0 1 297 -299 0 1 313 -299 0 1 314 -299 0 1 46 -300 0 1 47 -300 0 1 63 -300 0 1 64 -300 0 1 148 -300 0 4 149 -300 0 4 150 -300 0 4 151 -300 0 4 152 -300 0 4 207 -300 0 4 208 -300 0 4 209 -300 0 4 210 -300 0 4 211 -300 0 4 295 -300 0 1 296 -300 0 1 312 -300 0 1 313 -300 0 1 47 -301 0 1 48 -301 0 1 64 -301 0 1 65 -301 0 1 152 -301 0 4 153 -301 0 4 154 -301 0 4 155 -301 0 4 204 -301 0 4 205 -301 0 4 206 -301 0 4 207 -301 0 4 294 -301 0 1 295 -301 0 1 311 -301 0 1 312 -301 0 1 48 -302 0 1 49 -302 0 1 65 -302 0 1 66 -302 0 1 155 -302 0 4 156 -302 0 4 157 -302 0 4 158 -302 0 4 159 -302 0 4 160 -302 0 4 199 -302 0 4 200 -302 0 4 201 -302 0 4 202 -302 0 4 203 -302 0 4 204 -302 0 4 293 -302 0 1 294 -302 0 1 310 -302 0 1 311 -302 0 1 49 -303 0 1 50 -303 0 1 66 -303 0 1 67 -303 0 1 160 -303 0 4 161 -303 0 4 162 -303 0 4 163 -303 0 4 164 -303 0 4 165 -303 0 4 194 -303 0 4 195 -303 0 4 196 -303 0 4 197 -303 0 4 198 -303 0 4 199 -303 0 4 292 -303 0 1 293 -303 0 1 309 -303 0 1 310 -303 0 1 50 -304 0 1 51 -304 0 1 67 -304 0 1 68 -304 0 1 165 -304 0 4 166 -304 0 4 167 -304 0 4 168 -304 0 4 169 -304 0 4 170 -304 0 4 171 -304 0 4 172 -304 0 4 173 -304 0 4 174 -304 0 4 175 -304 0 4 176 -304 0 4 177 -304 0 4 178 -304 0 4 181 -304 0 4 182 -304 0 4 183 -304 0 4 184 -304 0 4 185 -304 0 4 186 -304 0 4 187 -304 0 4 188 -304 0 4 189 -304 0 4 190 -304 0 4 191 -304 0 4 192 -304 0 4 193 -304 0 4 194 -304 0 4 291 -304 0 1 292 -304 0 1 308 -304 0 1 309 -304 0 1 51 -305 0 1 52 -305 0 1 68 -305 0 1 69 -305 0 1 70 -305 0 1 178 -305 0 4 179 -305 0 4 180 -305 0 4 181 -305 0 4 289 -305 0 1 290 -305 0 1 291 -305 0 1 307 -305 0 1 308 -305 0 1 52 -306 0 1 53 -306 0 1 70 -306 0 1 71 -306 0 1 288 -306 0 1 289 -306 0 1 306 -306 0 1 307 -306 0 1 53 -307 0 1 54 -307 0 1 71 -307 0 1 72 -307 0 1 287 -307 0 1 288 -307 0 1 305 -307 0 1 306 -307 0 1 54 -308 0 1 55 -308 0 1 72 -308 0 1 73 -308 0 1 286 -308 0 1 287 -308 0 1 304 -308 0 1 305 -308 0 1 55 -309 0 1 56 -309 0 1 73 -309 0 1 74 -309 0 1 285 -309 0 1 286 -309 0 1 303 -309 0 1 304 -309 0 1 56 -310 0 1 57 -310 0 1 74 -310 0 1 75 -310 0 1 284 -310 0 1 285 -310 0 1 302 -310 0 1 303 -310 0 1 57 -311 0 1 58 -311 0 1 75 -311 0 1 76 -311 0 1 77 -311 0 1 282 -311 0 1 283 -311 0 1 284 -311 0 1 301 -311 0 1 302 -311 0 1 58 -312 0 1 59 -312 0 1 77 -312 0 1 78 -312 0 1 281 -312 0 1 282 -312 0 1 300 -312 0 1 301 -312 0 1 59 -313 0 1 60 -313 0 1 78 -313 0 1 79 -313 0 1 280 -313 0 1 281 -313 0 1 299 -313 0 1 300 -313 0 1 60 -314 0 1 61 -314 0 1 79 -314 0 1 80 -314 0 1 81 -314 0 1 278 -314 0 1 279 -314 0 1 280 -314 0 1 298 -314 0 1 299 -314 0 1 61 -315 0 1 62 -315 0 1 81 -315 0 1 82 -315 0 1 277 -315 0 1 278 -315 0 1 297 -315 0 1 298 -315 0 1 62 -316 0 1 63 -316 0 1 82 -316 0 1 83 -316 0 1 276 -316 0 1 277 -316 0 1 296 -316 0 1 297 -316 0 1 63 -317 0 1 64 -317 0 1 65 -317 0 1 83 -317 0 1 84 -317 0 1 85 -317 0 1 274 -317 0 1 275 -317 0 1 276 -317 0 1 294 -317 0 1 295 -317 0 1 296 -317 0 1 65 -318 0 1 66 -318 0 1 85 -318 0 1 86 -318 0 1 273 -318 0 1 274 -318 0 1 293 -318 0 1 294 -318 0 1 66 -319 0 1 67 -319 0 1 86 -319 0 1 87 -319 0 1 88 -319 0 1 271 -319 0 1 272 -319 0 1 273 -319 0 1 292 -319 0 1 293 -319 0 1 67 -320 0 1 68 -320 0 1 88 -320 0 1 89 -320 0 1 270 -320 0 1 271 -320 0 1 291 -320 0 1 292 -320 0 1 68 -321 0 1 69 -321 0 1 70 -321 0 1 89 -321 0 1 90 -321 0 1 91 -321 0 1 268 -321 0 1 269 -321 0 1 270 -321 0 1 289 -321 0 1 290 -321 0 1 291 -321 0 1 70 -322 0 1 71 -322 0 1 91 -322 0 1 92 -322 0 1 93 -322 0 1 266 -322 0 1 267 -322 0 1 268 -322 0 1 288 -322 0 1 289 -322 0 1 71 -323 0 1 72 -323 0 1 93 -323 0 1 94 -323 0 1 265 -323 0 1 266 -323 0 1 287 -323 0 1 288 -323 0 1 72 -324 0 1 73 -324 0 1 74 -324 0 1 94 -324 0 1 95 -324 0 1 96 -324 0 1 263 -324 0 1 264 -324 0 1 265 -324 0 1 285 -324 0 1 286 -324 0 1 287 -324 0 1 74 -325 0 1 75 -325 0 1 96 -325 0 1 97 -325 0 1 98 -325 0 1 261 -325 0 1 262 -325 0 1 263 -325 0 1 284 -325 0 1 285 -325 0 1 75 -326 0 1 76 -326 0 1 98 -326 0 1 99 -326 0 1 100 -326 0 1 259 -326 0 1 260 -326 0 1 261 -326 0 1 283 -326 0 1 284 -326 0 1 76 -327 0 1 77 -327 0 1 78 -327 0 1 100 -327 0 1 101 -327 0 1 257 -327 0 1 258 -327 0 1 259 -327 0 1 281 -327 0 1 282 -327 0 1 283 -327 0 1 78 -328 0 1 79 -328 0 1 80 -328 0 1 101 -328 0 1 102 -328 0 1 103 -328 0 1 256 -328 0 1 257 -328 0 1 279 -328 0 1 280 -328 0 1 281 -328 0 1 80 -329 0 1 81 -329 0 1 103 -329 0 1 104 -329 0 1 105 -329 0 1 254 -329 0 1 255 -329 0 1 256 -329 0 1 278 -329 0 1 279 -329 0 1 81 -330 0 1 82 -330 0 1 83 -330 0 1 105 -330 0 1 106 -330 0 1 107 -330 0 1 252 -330 0 1 253 -330 0 1 254 -330 0 1 277 -330 0 1 278 -330 0 1 83 -331 0 1 84 -331 0 1 107 -331 0 1 108 -331 0 1 109 -331 0 1 110 -331 0 1 249 -331 0 1 250 -331 0 1 251 -331 0 1 252 -331 0 1 275 -331 0 1 276 -331 0 1 277 -331 0 1 84 -332 0 1 85 -332 0 1 86 -332 0 1 110 -332 0 1 111 -332 0 1 112 -332 0 1 247 -332 0 1 248 -332 0 1 249 -332 0 1 273 -332 0 1 274 -332 0 1 275 -332 0 1 86 -333 0 1 87 -333 0 1 112 -333 0 1 113 -333 0 1 114 -333 0 1 245 -333 0 1 246 -333 0 1 247 -333 0 1 272 -333 0 1 273 -333 0 1 87 -334 0 1 88 -334 0 1 89 -334 0 1 114 -334 0 1 115 -334 0 1 116 -334 0 1 243 -334 0 1 244 -334 0 1 245 -334 0 1 270 -334 0 1 271 -334 0 1 272 -334 0 1 89 -335 0 1 90 -335 0 1 91 -335 0 1 116 -335 0 1 117 -335 0 1 118 -335 0 1 119 -335 0 1 240 -335 0 1 241 -335 0 1 242 -335 0 1 243 -335 0 1 268 -335 0 1 269 -335 0 1 270 -335 0 1 91 -336 0 1 92 -336 0 1 93 -336 0 1 119 -336 0 1 120 -336 0 1 121 -336 0 1 122 -336 0 1 237 -336 0 1 238 -336 0 1 239 -336 0 1 240 -336 0 1 267 -336 0 1 268 -336 0 1 93 -337 0 1 94 -337 0 1 122 -337 0 1 123 -337 0 1 124 -337 0 1 235 -337 0 1 236 -337 0 1 237 -337 0 1 265 -337 0 1 266 -337 0 1 267 -337 0 1 94 -338 0 1 95 -338 0 1 96 -338 0 1 124 -338 0 1 125 -338 0 1 126 -338 0 1 127 -338 0 1 232 -338 0 1 233 -338 0 1 234 -338 0 1 235 -338 0 1 263 -338 0 1 264 -338 0 1 265 -338 0 1 96 -339 0 1 97 -339 0 1 98 -339 0 1 127 -339 0 1 128 -339 0 1 129 -339 0 1 130 -339 0 1 131 -339 0 1 228 -339 0 1 229 -339 0 1 230 -339 0 1 231 -339 0 1 232 -339 0 1 261 -339 0 1 262 -339 0 1 263 -339 0 1 98 -340 0 1 99 -340 0 1 100 -340 0 1 131 -340 0 1 132 -340 0 1 133 -340 0 1 134 -340 0 1 225 -340 0 1 226 -340 0 1 227 -340 0 1 228 -340 0 1 259 -340 0 1 260 -340 0 1 261 -340 0 1 100 -341 0 1 101 -341 0 1 102 -341 0 1 134 -341 0 1 135 -341 0 1 136 -341 0 1 137 -341 0 1 138 -341 0 1 221 -341 0 1 222 -341 0 1 223 -341 0 1 224 -341 0 1 225 -341 0 1 257 -341 0 1 258 -341 0 1 259 -341 0 1 102 -342 0 1 103 -342 0 1 104 -342 0 1 138 -342 0 1 139 -342 0 1 140 -342 0 1 141 -342 0 1 142 -342 0 1 217 -342 0 1 218 -342 0 1 219 -342 0 1 220 -342 0 1 221 -342 0 1 255 -342 0 1 256 -342 0 1 257 -342 0 1 104 -343 0 1 105 -343 0 1 106 -343 0 1 142 -343 0 1 143 -343 0 1 144 -343 0 1 145 -343 0 1 146 -343 0 1 147 -343 0 1 212 -343 0 1 213 -343 0 1 214 -343 0 1 215 -343 0 1 216 -343 0 1 217 -343 0 1 253 -343 0 1 254 -343 0 1 255 -343 0 1 106 -344 0 1 107 -344 0 1 108 -344 0 1 109 -344 0 1 147 -344 0 1 148 -344 0 1 149 -344 0 1 150 -344 0 1 151 -344 0 1 152 -344 0 1 207 -344 0 1 208 -344 0 1 209 -344 0 1 210 -344 0 1 211 -344 0 1 212 -344 0 1 250 -344 0 1 251 -344 0 1 252 -344 0 1 253 -344 0 1 109 -345 0 1 110 -345 0 1 111 -345 0 1 152 -345 0 1 153 -345 0 1 154 -345 0 1 155 -345 0 1 156 -345 0 1 157 -345 0 1 158 -345 0 1 159 -345 0 1 200 -345 0 1 201 -345 0 1 202 -345 0 1 203 -345 0 1 204 -345 0 1 205 -345 0 1 206 -345 0 1 207 -345 0 1 248 -345 0 1 249 -345 0 1 250 -345 0 1 111 -346 0 1 112 -346 0 1 113 -346 0 1 159 -346 0 1 160 -346 0 1 161 -346 0 1 162 -346 0 1 163 -346 0 1 164 -346 0 1 165 -346 0 1 166 -346 0 1 167 -346 0 1 168 -346 0 1 169 -346 0 1 170 -346 0 1 171 -346 0 1 187 -346 0 1 188 -346 0 1 189 -346 0 1 190 -346 0 1 191 -346 0 1 192 -346 0 1 193 -346 0 1 194 -346 0 1 195 -346 0 1 196 -346 0 1 197 -346 0 1 198 -346 0 1 199 -346 0 1 200 -346 0 1 246 -346 0 1 247 -346 0 1 248 -346 0 1 113 -347 0 1 114 -347 0 1 115 -347 0 1 116 -347 0 1 171 -347 0 1 172 -347 0 1 173 -347 0 1 174 -347 0 1 175 -347 0 1 176 -347 0 1 177 -347 0 1 178 -347 0 1 179 -347 0 1 180 -347 0 1 181 -347 0 1 182 -347 0 1 183 -347 0 1 184 -347 0 1 185 -347 0 1 186 -347 0 1 187 -347 0 1 243 -347 0 1 244 -347 0 1 245 -347 0 1 246 -347 0 1 116 -348 0 1 117 -348 0 1 118 -348 0 1 119 -348 0 1 240 -348 0 1 241 -348 0 1 242 -348 0 1 243 -348 0 1 119 -349 0 1 120 -349 0 1 121 -349 0 1 122 -349 0 1 237 -349 0 1 238 -349 0 1 239 -349 0 1 240 -349 0 1 122 -350 0 1 123 -350 0 1 124 -350 0 1 125 -350 0 1 234 -350 0 1 235 -350 0 1 236 -350 0 1 237 -350 0 1 125 -351 0 1 126 -351 0 1 127 -351 0 1 128 -351 0 1 231 -351 0 1 232 -351 0 1 233 -351 0 1 234 -351 0 1 128 -352 0 1 129 -352 0 1 130 -352 0 1 131 -352 0 1 228 -352 0 1 229 -352 0 1 230 -352 0 1 231 -352 0 1 131 -353 0 1 132 -353 0 1 133 -353 0 1 134 -353 0 1 135 -353 0 1 224 -353 0 1 225 -353 0 1 226 -353 0 1 227 -353 0 1 228 -353 0 1 135 -354 0 1 136 -354 0 1 137 -354 0 1 138 -354 0 1 139 -354 0 1 220 -354 0 1 221 -354 0 1 222 -354 0 1 223 -354 0 1 224 -354 0 1 139 -355 0 1 140 -355 0 1 141 -355 0 1 142 -355 0 1 143 -355 0 1 144 -355 0 1 216 -355 0 1 217 -355 0 1 218 -355 0 1 219 -355 0 1 220 -355 0 1 144 -356 0 1 145 -356 0 1 146 -356 0 1 147 -356 0 1 148 -356 0 1 149 -356 0 1 210 -356 0 1 211 -356 0 1 212 -356 0 1 213 -356 0 1 214 -356 0 1 215 -356 0 1 216 -356 0 1 149 -357 0 1 150 -357 0 1 151 -357 0 1 152 -357 0 1 153 -357 0 1 154 -357 0 1 155 -357 0 1 156 -357 0 1 203 -357 0 1 204 -357 0 1 205 -357 0 1 206 -357 0 1 207 -357 0 1 208 -357 0 1 209 -357 0 1 210 -357 0 1 156 -358 0 1 157 -358 0 1 158 -358 0 1 159 -358 0 1 160 -358 0 1 161 -358 0 1 162 -358 0 1 163 -358 0 1 164 -358 0 1 165 -358 0 1 195 -358 0 1 196 -358 0 1 197 -358 0 1 198 -358 0 1 199 -358 0 1 200 -358 0 1 201 -358 0 1 202 -358 0 1 203 -358 0 1 165 -359 0 1 195 -359 0 1 0 0 0 0 ants-1.9.2+svn680.dfsg/Examples/Data/Smile.vtk000066400000000000000000001471301147325206600207140ustar00rootroot00000000000000# vtk DataFile Version 2.0 File written by itkLabeledPointSetFileWriter ASCII DATASET POLYDATA POINTS 3925 float 164 0 0 195 0 0 156 -1 0 157 -1 0 158 -1 0 159 -1 0 160 -1 0 161 -1 0 162 -1 0 163 -1 0 164 -1 0 195 -1 0 196 -1 0 197 -1 0 198 -1 0 199 -1 0 200 -1 0 201 -1 0 202 -1 0 203 -1 0 149 -2 0 150 -2 0 151 -2 0 152 -2 0 153 -2 0 154 -2 0 155 -2 0 156 -2 0 203 -2 0 204 -2 0 205 -2 0 206 -2 0 207 -2 0 208 -2 0 209 -2 0 210 -2 0 143 -3 0 144 -3 0 145 -3 0 146 -3 0 147 -3 0 148 -3 0 149 -3 0 210 -3 0 211 -3 0 212 -3 0 213 -3 0 214 -3 0 215 -3 0 139 -4 0 140 -4 0 141 -4 0 142 -4 0 143 -4 0 215 -4 0 216 -4 0 217 -4 0 218 -4 0 219 -4 0 220 -4 0 135 -5 0 136 -5 0 137 -5 0 138 -5 0 139 -5 0 220 -5 0 221 -5 0 222 -5 0 223 -5 0 224 -5 0 131 -6 0 132 -6 0 133 -6 0 134 -6 0 135 -6 0 224 -6 0 225 -6 0 226 -6 0 227 -6 0 228 -6 0 128 -7 0 129 -7 0 130 -7 0 131 -7 0 228 -7 0 229 -7 0 230 -7 0 231 -7 0 125 -8 0 126 -8 0 127 -8 0 128 -8 0 231 -8 0 232 -8 0 233 -8 0 234 -8 0 122 -9 0 123 -9 0 124 -9 0 125 -9 0 234 -9 0 235 -9 0 236 -9 0 237 -9 0 119 -10 0 120 -10 0 121 -10 0 122 -10 0 237 -10 0 238 -10 0 239 -10 0 240 -10 0 116 -11 0 117 -11 0 118 -11 0 119 -11 0 240 -11 0 241 -11 0 242 -11 0 243 -11 0 113 -12 0 114 -12 0 115 -12 0 116 -12 0 172 -12 0 173 -12 0 174 -12 0 175 -12 0 176 -12 0 177 -12 0 178 -12 0 179 -12 0 180 -12 0 181 -12 0 182 -12 0 183 -12 0 184 -12 0 185 -12 0 186 -12 0 187 -12 0 243 -12 0 244 -12 0 245 -12 0 246 -12 0 111 -13 0 112 -13 0 113 -13 0 159 -13 0 160 -13 0 161 -13 0 162 -13 0 163 -13 0 164 -13 0 165 -13 0 166 -13 0 167 -13 0 168 -13 0 169 -13 0 170 -13 0 171 -13 0 172 -13 0 187 -13 0 188 -13 0 189 -13 0 190 -13 0 191 -13 0 192 -13 0 193 -13 0 194 -13 0 195 -13 0 196 -13 0 197 -13 0 198 -13 0 199 -13 0 200 -13 0 246 -13 0 247 -13 0 248 -13 0 109 -14 0 110 -14 0 111 -14 0 152 -14 0 153 -14 0 154 -14 0 155 -14 0 156 -14 0 157 -14 0 158 -14 0 159 -14 0 200 -14 0 201 -14 0 202 -14 0 203 -14 0 204 -14 0 205 -14 0 206 -14 0 207 -14 0 248 -14 0 249 -14 0 250 -14 0 106 -15 0 107 -15 0 108 -15 0 109 -15 0 147 -15 0 148 -15 0 149 -15 0 150 -15 0 151 -15 0 152 -15 0 207 -15 0 208 -15 0 209 -15 0 210 -15 0 211 -15 0 212 -15 0 250 -15 0 251 -15 0 252 -15 0 253 -15 0 104 -16 0 105 -16 0 106 -16 0 142 -16 0 143 -16 0 144 -16 0 145 -16 0 146 -16 0 147 -16 0 212 -16 0 213 -16 0 214 -16 0 215 -16 0 216 -16 0 217 -16 0 253 -16 0 254 -16 0 255 -16 0 102 -17 0 103 -17 0 104 -17 0 138 -17 0 139 -17 0 140 -17 0 141 -17 0 142 -17 0 217 -17 0 218 -17 0 219 -17 0 220 -17 0 221 -17 0 255 -17 0 256 -17 0 257 -17 0 100 -18 0 101 -18 0 102 -18 0 134 -18 0 135 -18 0 136 -18 0 137 -18 0 138 -18 0 221 -18 0 222 -18 0 223 -18 0 224 -18 0 225 -18 0 257 -18 0 258 -18 0 259 -18 0 98 -19 0 99 -19 0 100 -19 0 131 -19 0 132 -19 0 133 -19 0 134 -19 0 225 -19 0 226 -19 0 227 -19 0 228 -19 0 259 -19 0 260 -19 0 261 -19 0 96 -20 0 97 -20 0 98 -20 0 127 -20 0 128 -20 0 129 -20 0 130 -20 0 131 -20 0 228 -20 0 229 -20 0 230 -20 0 231 -20 0 232 -20 0 261 -20 0 262 -20 0 263 -20 0 94 -21 0 95 -21 0 96 -21 0 124 -21 0 125 -21 0 126 -21 0 127 -21 0 232 -21 0 233 -21 0 234 -21 0 235 -21 0 263 -21 0 264 -21 0 265 -21 0 92 -22 0 93 -22 0 94 -22 0 122 -22 0 123 -22 0 124 -22 0 235 -22 0 236 -22 0 237 -22 0 265 -22 0 266 -22 0 91 -23 0 92 -23 0 119 -23 0 120 -23 0 121 -23 0 122 -23 0 237 -23 0 238 -23 0 239 -23 0 240 -23 0 266 -23 0 267 -23 0 268 -23 0 89 -24 0 90 -24 0 91 -24 0 116 -24 0 117 -24 0 118 -24 0 119 -24 0 240 -24 0 241 -24 0 242 -24 0 243 -24 0 268 -24 0 269 -24 0 270 -24 0 87 -25 0 88 -25 0 89 -25 0 114 -25 0 115 -25 0 116 -25 0 243 -25 0 244 -25 0 245 -25 0 270 -25 0 271 -25 0 272 -25 0 86 -26 0 87 -26 0 112 -26 0 113 -26 0 114 -26 0 245 -26 0 246 -26 0 247 -26 0 272 -26 0 273 -26 0 84 -27 0 85 -27 0 86 -27 0 110 -27 0 111 -27 0 112 -27 0 247 -27 0 248 -27 0 249 -27 0 273 -27 0 274 -27 0 275 -27 0 82 -28 0 83 -28 0 84 -28 0 107 -28 0 108 -28 0 109 -28 0 110 -28 0 249 -28 0 250 -28 0 251 -28 0 252 -28 0 275 -28 0 276 -28 0 81 -29 0 82 -29 0 105 -29 0 106 -29 0 107 -29 0 252 -29 0 253 -29 0 254 -29 0 276 -29 0 277 -29 0 278 -29 0 80 -30 0 81 -30 0 103 -30 0 104 -30 0 105 -30 0 254 -30 0 255 -30 0 256 -30 0 278 -30 0 279 -30 0 78 -31 0 79 -31 0 80 -31 0 102 -31 0 103 -31 0 256 -31 0 257 -31 0 279 -31 0 280 -31 0 281 -31 0 76 -32 0 77 -32 0 78 -32 0 100 -32 0 101 -32 0 102 -32 0 257 -32 0 258 -32 0 259 -32 0 281 -32 0 282 -32 0 283 -32 0 75 -33 0 76 -33 0 98 -33 0 99 -33 0 100 -33 0 259 -33 0 260 -33 0 261 -33 0 283 -33 0 284 -33 0 74 -34 0 75 -34 0 96 -34 0 97 -34 0 98 -34 0 261 -34 0 262 -34 0 263 -34 0 284 -34 0 285 -34 0 72 -35 0 73 -35 0 74 -35 0 94 -35 0 95 -35 0 96 -35 0 263 -35 0 264 -35 0 265 -35 0 285 -35 0 286 -35 0 287 -35 0 71 -36 0 72 -36 0 93 -36 0 94 -36 0 265 -36 0 266 -36 0 287 -36 0 288 -36 0 70 -37 0 71 -37 0 91 -37 0 92 -37 0 93 -37 0 266 -37 0 267 -37 0 268 -37 0 288 -37 0 289 -37 0 68 -38 0 69 -38 0 70 -38 0 89 -38 0 90 -38 0 91 -38 0 268 -38 0 269 -38 0 270 -38 0 289 -38 0 290 -38 0 291 -38 0 67 -39 0 68 -39 0 88 -39 0 89 -39 0 270 -39 0 271 -39 0 291 -39 0 292 -39 0 66 -40 0 67 -40 0 86 -40 0 87 -40 0 88 -40 0 271 -40 0 272 -40 0 273 -40 0 292 -40 0 293 -40 0 65 -41 0 66 -41 0 85 -41 0 86 -41 0 273 -41 0 274 -41 0 293 -41 0 294 -41 0 63 -42 0 64 -42 0 65 -42 0 83 -42 0 84 -42 0 85 -42 0 274 -42 0 275 -42 0 276 -42 0 294 -42 0 295 -42 0 296 -42 0 62 -43 0 63 -43 0 82 -43 0 83 -43 0 276 -43 0 277 -43 0 296 -43 0 297 -43 0 61 -44 0 62 -44 0 81 -44 0 82 -44 0 277 -44 0 278 -44 0 297 -44 0 298 -44 0 60 -45 0 61 -45 0 79 -45 0 80 -45 0 81 -45 0 278 -45 0 279 -45 0 280 -45 0 298 -45 0 299 -45 0 59 -46 0 60 -46 0 78 -46 0 79 -46 0 280 -46 0 281 -46 0 299 -46 0 300 -46 0 58 -47 0 59 -47 0 77 -47 0 78 -47 0 281 -47 0 282 -47 0 300 -47 0 301 -47 0 57 -48 0 58 -48 0 75 -48 0 76 -48 0 77 -48 0 282 -48 0 283 -48 0 284 -48 0 301 -48 0 302 -48 0 56 -49 0 57 -49 0 74 -49 0 75 -49 0 284 -49 0 285 -49 0 302 -49 0 303 -49 0 55 -50 0 56 -50 0 73 -50 0 74 -50 0 285 -50 0 286 -50 0 303 -50 0 304 -50 0 54 -51 0 55 -51 0 72 -51 0 73 -51 0 286 -51 0 287 -51 0 304 -51 0 305 -51 0 53 -52 0 54 -52 0 71 -52 0 72 -52 0 287 -52 0 288 -52 0 305 -52 0 306 -52 0 52 -53 0 53 -53 0 70 -53 0 71 -53 0 288 -53 0 289 -53 0 306 -53 0 307 -53 0 51 -54 0 52 -54 0 68 -54 0 69 -54 0 70 -54 0 289 -54 0 290 -54 0 291 -54 0 307 -54 0 308 -54 0 50 -55 0 51 -55 0 67 -55 0 68 -55 0 291 -55 0 292 -55 0 308 -55 0 309 -55 0 49 -56 0 50 -56 0 66 -56 0 67 -56 0 292 -56 0 293 -56 0 309 -56 0 310 -56 0 48 -57 0 49 -57 0 65 -57 0 66 -57 0 293 -57 0 294 -57 0 310 -57 0 311 -57 0 47 -58 0 48 -58 0 64 -58 0 65 -58 0 294 -58 0 295 -58 0 311 -58 0 312 -58 0 46 -59 0 47 -59 0 63 -59 0 64 -59 0 295 -59 0 296 -59 0 312 -59 0 313 -59 0 45 -60 0 46 -60 0 62 -60 0 63 -60 0 296 -60 0 297 -60 0 313 -60 0 314 -60 0 44 -61 0 45 -61 0 61 -61 0 62 -61 0 297 -61 0 298 -61 0 314 -61 0 315 -61 0 43 -62 0 44 -62 0 60 -62 0 61 -62 0 298 -62 0 299 -62 0 315 -62 0 316 -62 0 42 -63 0 43 -63 0 59 -63 0 60 -63 0 299 -63 0 300 -63 0 316 -63 0 317 -63 0 42 -64 0 58 -64 0 59 -64 0 300 -64 0 301 -64 0 317 -64 0 41 -65 0 42 -65 0 57 -65 0 58 -65 0 301 -65 0 302 -65 0 317 -65 0 318 -65 0 40 -66 0 41 -66 0 56 -66 0 57 -66 0 302 -66 0 303 -66 0 318 -66 0 319 -66 0 39 -67 0 40 -67 0 55 -67 0 56 -67 0 303 -67 0 304 -67 0 319 -67 0 320 -67 0 38 -68 0 39 -68 0 54 -68 0 55 -68 0 304 -68 0 305 -68 0 320 -68 0 321 -68 0 38 -69 0 54 -69 0 305 -69 0 321 -69 0 37 -70 0 38 -70 0 52 -70 0 53 -70 0 54 -70 0 305 -70 0 306 -70 0 307 -70 0 321 -70 0 322 -70 0 36 -71 0 37 -71 0 52 -71 0 307 -71 0 322 -71 0 323 -71 0 35 -72 0 36 -72 0 51 -72 0 52 -72 0 307 -72 0 308 -72 0 323 -72 0 324 -72 0 35 -73 0 50 -73 0 51 -73 0 308 -73 0 309 -73 0 324 -73 0 34 -74 0 35 -74 0 49 -74 0 50 -74 0 309 -74 0 310 -74 0 324 -74 0 325 -74 0 33 -75 0 34 -75 0 48 -75 0 49 -75 0 310 -75 0 311 -75 0 325 -75 0 326 -75 0 32 -76 0 33 -76 0 48 -76 0 311 -76 0 326 -76 0 327 -76 0 32 -77 0 47 -77 0 48 -77 0 311 -77 0 312 -77 0 327 -77 0 31 -78 0 32 -78 0 46 -78 0 47 -78 0 312 -78 0 313 -78 0 327 -78 0 328 -78 0 31 -79 0 45 -79 0 46 -79 0 313 -79 0 314 -79 0 328 -79 0 30 -80 0 31 -80 0 45 -80 0 314 -80 0 328 -80 0 329 -80 0 29 -81 0 30 -81 0 44 -81 0 45 -81 0 314 -81 0 315 -81 0 329 -81 0 330 -81 0 29 -82 0 43 -82 0 44 -82 0 315 -82 0 316 -82 0 330 -82 0 28 -83 0 29 -83 0 42 -83 0 43 -83 0 316 -83 0 317 -83 0 330 -83 0 331 -83 0 27 -84 0 28 -84 0 42 -84 0 317 -84 0 331 -84 0 332 -84 0 27 -85 0 41 -85 0 42 -85 0 317 -85 0 318 -85 0 332 -85 0 26 -86 0 27 -86 0 40 -86 0 41 -86 0 318 -86 0 319 -86 0 332 -86 0 333 -86 0 25 -87 0 26 -87 0 40 -87 0 319 -87 0 333 -87 0 334 -87 0 25 -88 0 39 -88 0 40 -88 0 319 -88 0 320 -88 0 334 -88 0 24 -89 0 25 -89 0 38 -89 0 39 -89 0 320 -89 0 321 -89 0 334 -89 0 335 -89 0 24 -90 0 38 -90 0 321 -90 0 335 -90 0 23 -91 0 24 -91 0 37 -91 0 38 -91 0 321 -91 0 322 -91 0 335 -91 0 336 -91 0 22 -92 0 23 -92 0 37 -92 0 322 -92 0 336 -92 0 337 -92 0 22 -93 0 36 -93 0 37 -93 0 322 -93 0 323 -93 0 337 -93 0 21 -94 0 22 -94 0 35 -94 0 36 -94 0 323 -94 0 324 -94 0 337 -94 0 338 -94 0 21 -95 0 35 -95 0 324 -95 0 338 -95 0 20 -96 0 21 -96 0 34 -96 0 35 -96 0 324 -96 0 325 -96 0 338 -96 0 339 -96 0 20 -97 0 34 -97 0 325 -97 0 339 -97 0 19 -98 0 20 -98 0 33 -98 0 34 -98 0 325 -98 0 326 -98 0 339 -98 0 340 -98 0 19 -99 0 32 -99 0 33 -99 0 326 -99 0 327 -99 0 340 -99 0 18 -100 0 19 -100 0 32 -100 0 327 -100 0 340 -100 0 341 -100 0 18 -101 0 31 -101 0 32 -101 0 327 -101 0 328 -101 0 341 -101 0 17 -102 0 18 -102 0 31 -102 0 328 -102 0 341 -102 0 342 -102 0 17 -103 0 30 -103 0 31 -103 0 328 -103 0 329 -103 0 342 -103 0 16 -104 0 17 -104 0 30 -104 0 329 -104 0 342 -104 0 343 -104 0 16 -105 0 29 -105 0 30 -105 0 329 -105 0 330 -105 0 343 -105 0 15 -106 0 16 -106 0 29 -106 0 330 -106 0 343 -106 0 344 -106 0 15 -107 0 28 -107 0 29 -107 0 330 -107 0 331 -107 0 344 -107 0 15 -108 0 28 -108 0 331 -108 0 344 -108 0 14 -109 0 15 -109 0 28 -109 0 122 -109 0 123 -109 0 124 -109 0 125 -109 0 126 -109 0 127 -109 0 128 -109 0 129 -109 0 130 -109 0 131 -109 0 132 -109 0 133 -109 0 233 -109 0 234 -109 0 235 -109 0 236 -109 0 237 -109 0 238 -109 0 239 -109 0 240 -109 0 241 -109 0 242 -109 0 243 -109 0 244 -109 0 245 -109 0 331 -109 0 344 -109 0 345 -109 0 14 -110 0 27 -110 0 28 -110 0 118 -110 0 119 -110 0 120 -110 0 121 -110 0 122 -110 0 133 -110 0 134 -110 0 135 -110 0 136 -110 0 137 -110 0 230 -110 0 231 -110 0 232 -110 0 233 -110 0 245 -110 0 246 -110 0 247 -110 0 248 -110 0 331 -110 0 332 -110 0 345 -110 0 13 -111 0 14 -111 0 27 -111 0 115 -111 0 116 -111 0 117 -111 0 118 -111 0 137 -111 0 138 -111 0 139 -111 0 227 -111 0 228 -111 0 229 -111 0 230 -111 0 248 -111 0 249 -111 0 250 -111 0 251 -111 0 332 -111 0 345 -111 0 346 -111 0 13 -112 0 26 -112 0 27 -112 0 113 -112 0 114 -112 0 115 -112 0 139 -112 0 140 -112 0 141 -112 0 225 -112 0 226 -112 0 227 -112 0 251 -112 0 252 -112 0 253 -112 0 332 -112 0 333 -112 0 346 -112 0 12 -113 0 13 -113 0 26 -113 0 112 -113 0 113 -113 0 141 -113 0 142 -113 0 143 -113 0 223 -113 0 224 -113 0 225 -113 0 253 -113 0 254 -113 0 255 -113 0 333 -113 0 346 -113 0 347 -113 0 12 -114 0 25 -114 0 26 -114 0 110 -114 0 111 -114 0 112 -114 0 143 -114 0 144 -114 0 222 -114 0 223 -114 0 255 -114 0 256 -114 0 333 -114 0 334 -114 0 347 -114 0 12 -115 0 25 -115 0 109 -115 0 110 -115 0 144 -115 0 145 -115 0 221 -115 0 222 -115 0 256 -115 0 257 -115 0 334 -115 0 347 -115 0 11 -116 0 12 -116 0 24 -116 0 25 -116 0 108 -116 0 109 -116 0 145 -116 0 146 -116 0 147 -116 0 219 -116 0 220 -116 0 221 -116 0 257 -116 0 258 -116 0 334 -116 0 347 -116 0 348 -116 0 11 -117 0 24 -117 0 107 -117 0 108 -117 0 147 -117 0 148 -117 0 219 -117 0 258 -117 0 259 -117 0 260 -117 0 334 -117 0 335 -117 0 348 -117 0 11 -118 0 24 -118 0 106 -118 0 107 -118 0 148 -118 0 149 -118 0 218 -118 0 219 -118 0 260 -118 0 261 -118 0 335 -118 0 348 -118 0 10 -119 0 11 -119 0 23 -119 0 24 -119 0 105 -119 0 106 -119 0 149 -119 0 150 -119 0 217 -119 0 218 -119 0 261 -119 0 335 -119 0 336 -119 0 348 -119 0 349 -119 0 10 -120 0 23 -120 0 104 -120 0 105 -120 0 150 -120 0 216 -120 0 217 -120 0 261 -120 0 262 -120 0 336 -120 0 349 -120 0 10 -121 0 23 -121 0 103 -121 0 104 -121 0 150 -121 0 151 -121 0 215 -121 0 216 -121 0 262 -121 0 263 -121 0 336 -121 0 349 -121 0 9 -122 0 10 -122 0 22 -122 0 23 -122 0 103 -122 0 151 -122 0 152 -122 0 214 -122 0 215 -122 0 263 -122 0 336 -122 0 337 -122 0 349 -122 0 350 -122 0 9 -123 0 22 -123 0 102 -123 0 103 -123 0 152 -123 0 214 -123 0 263 -123 0 264 -123 0 337 -123 0 350 -123 0 9 -124 0 21 -124 0 22 -124 0 102 -124 0 152 -124 0 153 -124 0 213 -124 0 214 -124 0 264 -124 0 265 -124 0 337 -124 0 338 -124 0 350 -124 0 8 -125 0 9 -125 0 21 -125 0 101 -125 0 102 -125 0 153 -125 0 213 -125 0 265 -125 0 338 -125 0 350 -125 0 351 -125 0 8 -126 0 21 -126 0 101 -126 0 153 -126 0 154 -126 0 212 -126 0 213 -126 0 265 -126 0 266 -126 0 338 -126 0 351 -126 0 8 -127 0 20 -127 0 21 -127 0 100 -127 0 101 -127 0 154 -127 0 212 -127 0 266 -127 0 338 -127 0 339 -127 0 351 -127 0 7 -128 0 8 -128 0 20 -128 0 100 -128 0 154 -128 0 155 -128 0 212 -128 0 266 -128 0 339 -128 0 351 -128 0 352 -128 0 7 -129 0 20 -129 0 99 -129 0 100 -129 0 155 -129 0 211 -129 0 212 -129 0 266 -129 0 267 -129 0 339 -129 0 352 -129 0 7 -130 0 20 -130 0 99 -130 0 155 -130 0 211 -130 0 267 -130 0 339 -130 0 352 -130 0 6 -131 0 7 -131 0 19 -131 0 20 -131 0 99 -131 0 155 -131 0 156 -131 0 211 -131 0 267 -131 0 339 -131 0 340 -131 0 352 -131 0 353 -131 0 6 -132 0 19 -132 0 99 -132 0 156 -132 0 210 -132 0 211 -132 0 267 -132 0 268 -132 0 340 -132 0 353 -132 0 6 -133 0 19 -133 0 98 -133 0 99 -133 0 156 -133 0 210 -133 0 268 -133 0 340 -133 0 353 -133 0 6 -134 0 18 -134 0 19 -134 0 98 -134 0 156 -134 0 210 -134 0 268 -134 0 340 -134 0 341 -134 0 353 -134 0 5 -135 0 6 -135 0 18 -135 0 98 -135 0 156 -135 0 210 -135 0 268 -135 0 341 -135 0 353 -135 0 354 -135 0 5 -136 0 18 -136 0 98 -136 0 156 -136 0 210 -136 0 268 -136 0 341 -136 0 354 -136 0 5 -137 0 18 -137 0 98 -137 0 156 -137 0 210 -137 0 268 -137 0 341 -137 0 354 -137 0 5 -138 0 17 -138 0 18 -138 0 98 -138 0 156 -138 0 210 -138 0 268 -138 0 341 -138 0 342 -138 0 354 -138 0 4 -139 0 5 -139 0 17 -139 0 98 -139 0 156 -139 0 210 -139 0 268 -139 0 342 -139 0 354 -139 0 355 -139 0 4 -140 0 17 -140 0 98 -140 0 156 -140 0 210 -140 0 268 -140 0 342 -140 0 355 -140 0 4 -141 0 17 -141 0 98 -141 0 156 -141 0 210 -141 0 268 -141 0 342 -141 0 355 -141 0 4 -142 0 16 -142 0 17 -142 0 98 -142 0 156 -142 0 210 -142 0 268 -142 0 342 -142 0 343 -142 0 355 -142 0 4 -143 0 16 -143 0 98 -143 0 99 -143 0 156 -143 0 210 -143 0 268 -143 0 343 -143 0 355 -143 0 356 -143 0 3 -144 0 4 -144 0 16 -144 0 99 -144 0 156 -144 0 210 -144 0 211 -144 0 267 -144 0 268 -144 0 343 -144 0 356 -144 0 3 -145 0 16 -145 0 99 -145 0 155 -145 0 156 -145 0 211 -145 0 267 -145 0 343 -145 0 356 -145 0 3 -146 0 16 -146 0 99 -146 0 155 -146 0 211 -146 0 267 -146 0 343 -146 0 356 -146 0 3 -147 0 15 -147 0 16 -147 0 99 -147 0 100 -147 0 155 -147 0 211 -147 0 212 -147 0 266 -147 0 267 -147 0 343 -147 0 344 -147 0 356 -147 0 3 -148 0 15 -148 0 100 -148 0 154 -148 0 155 -148 0 212 -148 0 266 -148 0 344 -148 0 356 -148 0 2 -149 0 3 -149 0 15 -149 0 100 -149 0 154 -149 0 212 -149 0 266 -149 0 344 -149 0 356 -149 0 357 -149 0 2 -150 0 15 -150 0 100 -150 0 101 -150 0 154 -150 0 212 -150 0 213 -150 0 265 -150 0 266 -150 0 344 -150 0 357 -150 0 2 -151 0 15 -151 0 101 -151 0 102 -151 0 153 -151 0 154 -151 0 213 -151 0 265 -151 0 344 -151 0 357 -151 0 2 -152 0 14 -152 0 15 -152 0 102 -152 0 152 -152 0 153 -152 0 213 -152 0 214 -152 0 264 -152 0 265 -152 0 344 -152 0 345 -152 0 357 -152 0 2 -153 0 14 -153 0 102 -153 0 103 -153 0 152 -153 0 214 -153 0 264 -153 0 345 -153 0 357 -153 0 2 -154 0 14 -154 0 103 -154 0 151 -154 0 152 -154 0 214 -154 0 215 -154 0 263 -154 0 264 -154 0 345 -154 0 357 -154 0 2 -155 0 14 -155 0 103 -155 0 104 -155 0 150 -155 0 151 -155 0 215 -155 0 216 -155 0 262 -155 0 263 -155 0 345 -155 0 357 -155 0 1 -156 0 2 -156 0 14 -156 0 104 -156 0 105 -156 0 150 -156 0 216 -156 0 217 -156 0 261 -156 0 262 -156 0 345 -156 0 357 -156 0 358 -156 0 1 -157 0 14 -157 0 105 -157 0 106 -157 0 149 -157 0 150 -157 0 217 -157 0 260 -157 0 261 -157 0 345 -157 0 358 -157 0 1 -158 0 14 -158 0 106 -158 0 107 -158 0 148 -158 0 149 -158 0 217 -158 0 218 -158 0 259 -158 0 260 -158 0 345 -158 0 358 -158 0 1 -159 0 13 -159 0 14 -159 0 107 -159 0 108 -159 0 147 -159 0 148 -159 0 218 -159 0 219 -159 0 259 -159 0 345 -159 0 346 -159 0 358 -159 0 1 -160 0 13 -160 0 108 -160 0 109 -160 0 146 -160 0 147 -160 0 219 -160 0 220 -160 0 221 -160 0 257 -160 0 258 -160 0 259 -160 0 346 -160 0 358 -160 0 1 -161 0 13 -161 0 109 -161 0 110 -161 0 144 -161 0 145 -161 0 146 -161 0 221 -161 0 222 -161 0 256 -161 0 257 -161 0 346 -161 0 358 -161 0 1 -162 0 13 -162 0 110 -162 0 111 -162 0 112 -162 0 143 -162 0 144 -162 0 222 -162 0 223 -162 0 255 -162 0 256 -162 0 346 -162 0 358 -162 0 1 -163 0 13 -163 0 112 -163 0 113 -163 0 141 -163 0 142 -163 0 143 -163 0 223 -163 0 224 -163 0 225 -163 0 253 -163 0 254 -163 0 255 -163 0 346 -163 0 358 -163 0 1 -164 0 13 -164 0 113 -164 0 114 -164 0 115 -164 0 139 -164 0 140 -164 0 141 -164 0 225 -164 0 226 -164 0 227 -164 0 251 -164 0 252 -164 0 253 -164 0 346 -164 0 358 -164 0 0 -165 0 1 -165 0 13 -165 0 115 -165 0 116 -165 0 117 -165 0 118 -165 0 137 -165 0 138 -165 0 139 -165 0 227 -165 0 228 -165 0 229 -165 0 230 -165 0 249 -165 0 250 -165 0 251 -165 0 346 -165 0 358 -165 0 359 -165 0 13 -166 0 118 -166 0 119 -166 0 120 -166 0 121 -166 0 133 -166 0 134 -166 0 135 -166 0 136 -166 0 137 -166 0 230 -166 0 231 -166 0 232 -166 0 233 -166 0 245 -166 0 246 -166 0 247 -166 0 248 -166 0 249 -166 0 346 -166 0 13 -167 0 121 -167 0 122 -167 0 123 -167 0 124 -167 0 125 -167 0 126 -167 0 127 -167 0 128 -167 0 129 -167 0 130 -167 0 131 -167 0 132 -167 0 133 -167 0 233 -167 0 234 -167 0 235 -167 0 236 -167 0 237 -167 0 238 -167 0 239 -167 0 240 -167 0 241 -167 0 242 -167 0 243 -167 0 244 -167 0 245 -167 0 346 -167 0 13 -168 0 346 -168 0 13 -169 0 346 -169 0 13 -170 0 346 -170 0 13 -171 0 346 -171 0 12 -172 0 13 -172 0 346 -172 0 347 -172 0 12 -173 0 347 -173 0 12 -174 0 347 -174 0 12 -175 0 347 -175 0 12 -176 0 347 -176 0 12 -177 0 347 -177 0 12 -178 0 347 -178 0 12 -179 0 347 -179 0 12 -180 0 347 -180 0 12 -181 0 347 -181 0 12 -182 0 347 -182 0 12 -183 0 347 -183 0 12 -184 0 347 -184 0 12 -185 0 347 -185 0 12 -186 0 347 -186 0 12 -187 0 13 -187 0 346 -187 0 347 -187 0 13 -188 0 346 -188 0 13 -189 0 346 -189 0 13 -190 0 346 -190 0 13 -191 0 346 -191 0 13 -192 0 346 -192 0 13 -193 0 346 -193 0 0 -194 0 1 -194 0 13 -194 0 346 -194 0 358 -194 0 359 -194 0 1 -195 0 13 -195 0 346 -195 0 358 -195 0 1 -196 0 13 -196 0 346 -196 0 358 -196 0 1 -197 0 13 -197 0 346 -197 0 358 -197 0 1 -198 0 13 -198 0 346 -198 0 358 -198 0 1 -199 0 13 -199 0 346 -199 0 358 -199 0 1 -200 0 13 -200 0 14 -200 0 345 -200 0 346 -200 0 358 -200 0 1 -201 0 14 -201 0 345 -201 0 358 -201 0 1 -202 0 14 -202 0 76 -202 0 77 -202 0 78 -202 0 79 -202 0 80 -202 0 81 -202 0 82 -202 0 83 -202 0 84 -202 0 85 -202 0 86 -202 0 87 -202 0 88 -202 0 89 -202 0 270 -202 0 271 -202 0 272 -202 0 273 -202 0 274 -202 0 275 -202 0 276 -202 0 277 -202 0 278 -202 0 279 -202 0 280 -202 0 281 -202 0 282 -202 0 283 -202 0 345 -202 0 358 -202 0 1 -203 0 2 -203 0 14 -203 0 76 -203 0 89 -203 0 270 -203 0 283 -203 0 345 -203 0 357 -203 0 358 -203 0 2 -204 0 14 -204 0 76 -204 0 89 -204 0 270 -204 0 283 -204 0 345 -204 0 357 -204 0 2 -205 0 14 -205 0 76 -205 0 77 -205 0 89 -205 0 270 -205 0 283 -205 0 345 -205 0 357 -205 0 2 -206 0 14 -206 0 77 -206 0 89 -206 0 270 -206 0 282 -206 0 283 -206 0 345 -206 0 357 -206 0 2 -207 0 14 -207 0 15 -207 0 77 -207 0 89 -207 0 270 -207 0 282 -207 0 344 -207 0 345 -207 0 357 -207 0 2 -208 0 15 -208 0 77 -208 0 89 -208 0 270 -208 0 282 -208 0 344 -208 0 357 -208 0 2 -209 0 15 -209 0 77 -209 0 89 -209 0 270 -209 0 282 -209 0 344 -209 0 357 -209 0 2 -210 0 3 -210 0 15 -210 0 77 -210 0 89 -210 0 270 -210 0 282 -210 0 344 -210 0 356 -210 0 357 -210 0 3 -211 0 15 -211 0 77 -211 0 89 -211 0 270 -211 0 282 -211 0 344 -211 0 356 -211 0 3 -212 0 15 -212 0 16 -212 0 77 -212 0 89 -212 0 90 -212 0 269 -212 0 270 -212 0 282 -212 0 343 -212 0 344 -212 0 356 -212 0 3 -213 0 16 -213 0 77 -213 0 90 -213 0 269 -213 0 282 -213 0 343 -213 0 356 -213 0 3 -214 0 16 -214 0 77 -214 0 90 -214 0 269 -214 0 282 -214 0 343 -214 0 356 -214 0 3 -215 0 16 -215 0 77 -215 0 90 -215 0 269 -215 0 282 -215 0 343 -215 0 355 -215 0 356 -215 0 3 -216 0 4 -216 0 16 -216 0 77 -216 0 78 -216 0 90 -216 0 269 -216 0 281 -216 0 282 -216 0 343 -216 0 355 -216 0 4 -217 0 16 -217 0 17 -217 0 78 -217 0 90 -217 0 269 -217 0 281 -217 0 342 -217 0 343 -217 0 355 -217 0 4 -218 0 17 -218 0 78 -218 0 90 -218 0 269 -218 0 281 -218 0 342 -218 0 355 -218 0 4 -219 0 17 -219 0 78 -219 0 90 -219 0 91 -219 0 268 -219 0 269 -219 0 281 -219 0 342 -219 0 355 -219 0 4 -220 0 5 -220 0 17 -220 0 78 -220 0 91 -220 0 268 -220 0 281 -220 0 342 -220 0 354 -220 0 355 -220 0 5 -221 0 17 -221 0 18 -221 0 78 -221 0 91 -221 0 268 -221 0 281 -221 0 341 -221 0 342 -221 0 354 -221 0 5 -222 0 18 -222 0 78 -222 0 79 -222 0 91 -222 0 268 -222 0 280 -222 0 281 -222 0 341 -222 0 354 -222 0 5 -223 0 18 -223 0 79 -223 0 91 -223 0 268 -223 0 280 -223 0 341 -223 0 354 -223 0 5 -224 0 6 -224 0 18 -224 0 79 -224 0 91 -224 0 92 -224 0 267 -224 0 268 -224 0 280 -224 0 341 -224 0 353 -224 0 354 -224 0 6 -225 0 18 -225 0 19 -225 0 79 -225 0 92 -225 0 267 -225 0 280 -225 0 340 -225 0 341 -225 0 353 -225 0 6 -226 0 19 -226 0 79 -226 0 80 -226 0 92 -226 0 267 -226 0 279 -226 0 280 -226 0 340 -226 0 353 -226 0 6 -227 0 19 -227 0 80 -227 0 92 -227 0 93 -227 0 266 -227 0 267 -227 0 279 -227 0 340 -227 0 353 -227 0 6 -228 0 7 -228 0 19 -228 0 20 -228 0 80 -228 0 93 -228 0 266 -228 0 279 -228 0 339 -228 0 340 -228 0 352 -228 0 353 -228 0 7 -229 0 20 -229 0 80 -229 0 93 -229 0 266 -229 0 279 -229 0 339 -229 0 352 -229 0 7 -230 0 20 -230 0 80 -230 0 81 -230 0 93 -230 0 94 -230 0 265 -230 0 266 -230 0 278 -230 0 279 -230 0 339 -230 0 352 -230 0 7 -231 0 8 -231 0 20 -231 0 81 -231 0 94 -231 0 265 -231 0 278 -231 0 339 -231 0 351 -231 0 352 -231 0 8 -232 0 20 -232 0 21 -232 0 81 -232 0 94 -232 0 265 -232 0 278 -232 0 338 -232 0 339 -232 0 351 -232 0 8 -233 0 21 -233 0 81 -233 0 82 -233 0 94 -233 0 95 -233 0 264 -233 0 265 -233 0 277 -233 0 278 -233 0 338 -233 0 351 -233 0 8 -234 0 9 -234 0 21 -234 0 22 -234 0 82 -234 0 95 -234 0 264 -234 0 277 -234 0 338 -234 0 350 -234 0 351 -234 0 9 -235 0 22 -235 0 82 -235 0 95 -235 0 264 -235 0 277 -235 0 337 -235 0 338 -235 0 350 -235 0 9 -236 0 22 -236 0 82 -236 0 83 -236 0 95 -236 0 96 -236 0 263 -236 0 264 -236 0 276 -236 0 277 -236 0 337 -236 0 350 -236 0 9 -237 0 10 -237 0 22 -237 0 23 -237 0 83 -237 0 96 -237 0 263 -237 0 276 -237 0 336 -237 0 337 -237 0 349 -237 0 350 -237 0 10 -238 0 23 -238 0 83 -238 0 96 -238 0 97 -238 0 262 -238 0 263 -238 0 276 -238 0 336 -238 0 349 -238 0 10 -239 0 23 -239 0 83 -239 0 84 -239 0 97 -239 0 262 -239 0 275 -239 0 276 -239 0 336 -239 0 349 -239 0 10 -240 0 11 -240 0 23 -240 0 24 -240 0 84 -240 0 97 -240 0 98 -240 0 261 -240 0 262 -240 0 275 -240 0 335 -240 0 336 -240 0 348 -240 0 349 -240 0 11 -241 0 24 -241 0 84 -241 0 85 -241 0 98 -241 0 261 -241 0 274 -241 0 275 -241 0 335 -241 0 348 -241 0 11 -242 0 24 -242 0 25 -242 0 85 -242 0 98 -242 0 99 -242 0 260 -242 0 261 -242 0 274 -242 0 335 -242 0 348 -242 0 11 -243 0 12 -243 0 25 -243 0 85 -243 0 99 -243 0 260 -243 0 274 -243 0 334 -243 0 335 -243 0 347 -243 0 348 -243 0 12 -244 0 25 -244 0 85 -244 0 86 -244 0 99 -244 0 100 -244 0 259 -244 0 260 -244 0 273 -244 0 274 -244 0 334 -244 0 347 -244 0 12 -245 0 13 -245 0 25 -245 0 26 -245 0 86 -245 0 100 -245 0 259 -245 0 273 -245 0 333 -245 0 334 -245 0 347 -245 0 13 -246 0 26 -246 0 86 -246 0 87 -246 0 100 -246 0 101 -246 0 258 -246 0 259 -246 0 272 -246 0 273 -246 0 333 -246 0 346 -246 0 347 -246 0 13 -247 0 26 -247 0 27 -247 0 87 -247 0 101 -247 0 258 -247 0 272 -247 0 332 -247 0 333 -247 0 346 -247 0 13 -248 0 14 -248 0 27 -248 0 87 -248 0 88 -248 0 101 -248 0 102 -248 0 257 -248 0 258 -248 0 271 -248 0 272 -248 0 332 -248 0 345 -248 0 346 -248 0 14 -249 0 27 -249 0 28 -249 0 88 -249 0 102 -249 0 103 -249 0 256 -249 0 257 -249 0 271 -249 0 331 -249 0 332 -249 0 345 -249 0 14 -250 0 15 -250 0 28 -250 0 88 -250 0 89 -250 0 103 -250 0 256 -250 0 270 -250 0 271 -250 0 331 -250 0 344 -250 0 345 -250 0 15 -251 0 28 -251 0 89 -251 0 103 -251 0 104 -251 0 255 -251 0 256 -251 0 269 -251 0 270 -251 0 331 -251 0 344 -251 0 15 -252 0 28 -252 0 29 -252 0 89 -252 0 90 -252 0 104 -252 0 255 -252 0 269 -252 0 330 -252 0 331 -252 0 344 -252 0 15 -253 0 16 -253 0 29 -253 0 90 -253 0 91 -253 0 104 -253 0 105 -253 0 254 -253 0 255 -253 0 268 -253 0 269 -253 0 330 -253 0 343 -253 0 344 -253 0 16 -254 0 29 -254 0 30 -254 0 91 -254 0 105 -254 0 106 -254 0 253 -254 0 254 -254 0 268 -254 0 329 -254 0 330 -254 0 343 -254 0 16 -255 0 17 -255 0 30 -255 0 91 -255 0 92 -255 0 106 -255 0 107 -255 0 252 -255 0 253 -255 0 267 -255 0 268 -255 0 329 -255 0 342 -255 0 343 -255 0 17 -256 0 30 -256 0 31 -256 0 92 -256 0 93 -256 0 107 -256 0 252 -256 0 266 -256 0 267 -256 0 328 -256 0 329 -256 0 342 -256 0 17 -257 0 18 -257 0 31 -257 0 93 -257 0 107 -257 0 108 -257 0 251 -257 0 252 -257 0 266 -257 0 328 -257 0 341 -257 0 342 -257 0 18 -258 0 31 -258 0 32 -258 0 93 -258 0 94 -258 0 108 -258 0 109 -258 0 250 -258 0 251 -258 0 265 -258 0 266 -258 0 327 -258 0 328 -258 0 341 -258 0 18 -259 0 19 -259 0 32 -259 0 94 -259 0 95 -259 0 109 -259 0 110 -259 0 249 -259 0 250 -259 0 265 -259 0 327 -259 0 340 -259 0 341 -259 0 19 -260 0 32 -260 0 33 -260 0 95 -260 0 110 -260 0 111 -260 0 248 -260 0 249 -260 0 264 -260 0 265 -260 0 326 -260 0 327 -260 0 340 -260 0 19 -261 0 20 -261 0 33 -261 0 34 -261 0 95 -261 0 96 -261 0 111 -261 0 112 -261 0 247 -261 0 248 -261 0 263 -261 0 264 -261 0 325 -261 0 326 -261 0 339 -261 0 340 -261 0 20 -262 0 34 -262 0 96 -262 0 97 -262 0 112 -262 0 247 -262 0 262 -262 0 263 -262 0 325 -262 0 339 -262 0 20 -263 0 21 -263 0 34 -263 0 35 -263 0 97 -263 0 112 -263 0 113 -263 0 246 -263 0 247 -263 0 262 -263 0 324 -263 0 325 -263 0 338 -263 0 339 -263 0 21 -264 0 35 -264 0 97 -264 0 98 -264 0 113 -264 0 114 -264 0 245 -264 0 246 -264 0 261 -264 0 262 -264 0 324 -264 0 338 -264 0 21 -265 0 22 -265 0 35 -265 0 36 -265 0 98 -265 0 99 -265 0 114 -265 0 115 -265 0 244 -265 0 245 -265 0 260 -265 0 261 -265 0 323 -265 0 324 -265 0 337 -265 0 338 -265 0 22 -266 0 36 -266 0 37 -266 0 99 -266 0 100 -266 0 115 -266 0 116 -266 0 243 -266 0 244 -266 0 259 -266 0 260 -266 0 322 -266 0 323 -266 0 337 -266 0 22 -267 0 23 -267 0 37 -267 0 100 -267 0 101 -267 0 116 -267 0 117 -267 0 242 -267 0 243 -267 0 258 -267 0 259 -267 0 322 -267 0 336 -267 0 337 -267 0 23 -268 0 24 -268 0 37 -268 0 38 -268 0 101 -268 0 102 -268 0 117 -268 0 118 -268 0 241 -268 0 242 -268 0 257 -268 0 258 -268 0 321 -268 0 322 -268 0 335 -268 0 336 -268 0 24 -269 0 38 -269 0 102 -269 0 118 -269 0 119 -269 0 120 -269 0 239 -269 0 240 -269 0 241 -269 0 257 -269 0 321 -269 0 335 -269 0 24 -270 0 25 -270 0 38 -270 0 39 -270 0 102 -270 0 103 -270 0 120 -270 0 121 -270 0 238 -270 0 239 -270 0 256 -270 0 257 -270 0 320 -270 0 321 -270 0 334 -270 0 335 -270 0 25 -271 0 39 -271 0 40 -271 0 103 -271 0 104 -271 0 121 -271 0 122 -271 0 237 -271 0 238 -271 0 255 -271 0 256 -271 0 319 -271 0 320 -271 0 334 -271 0 25 -272 0 26 -272 0 40 -272 0 104 -272 0 105 -272 0 122 -272 0 123 -272 0 236 -272 0 237 -272 0 254 -272 0 255 -272 0 319 -272 0 333 -272 0 334 -272 0 26 -273 0 27 -273 0 40 -273 0 41 -273 0 105 -273 0 106 -273 0 123 -273 0 124 -273 0 235 -273 0 236 -273 0 253 -273 0 254 -273 0 318 -273 0 319 -273 0 332 -273 0 333 -273 0 27 -274 0 41 -274 0 42 -274 0 106 -274 0 107 -274 0 124 -274 0 125 -274 0 126 -274 0 233 -274 0 234 -274 0 235 -274 0 252 -274 0 253 -274 0 317 -274 0 318 -274 0 332 -274 0 27 -275 0 28 -275 0 42 -275 0 107 -275 0 108 -275 0 126 -275 0 127 -275 0 232 -275 0 233 -275 0 251 -275 0 252 -275 0 317 -275 0 331 -275 0 332 -275 0 28 -276 0 29 -276 0 42 -276 0 43 -276 0 108 -276 0 109 -276 0 127 -276 0 128 -276 0 231 -276 0 232 -276 0 250 -276 0 251 -276 0 316 -276 0 317 -276 0 330 -276 0 331 -276 0 29 -277 0 43 -277 0 44 -277 0 109 -277 0 110 -277 0 128 -277 0 129 -277 0 130 -277 0 229 -277 0 230 -277 0 231 -277 0 249 -277 0 250 -277 0 315 -277 0 316 -277 0 330 -277 0 29 -278 0 30 -278 0 44 -278 0 45 -278 0 110 -278 0 111 -278 0 130 -278 0 131 -278 0 132 -278 0 227 -278 0 228 -278 0 229 -278 0 248 -278 0 249 -278 0 314 -278 0 315 -278 0 329 -278 0 330 -278 0 30 -279 0 31 -279 0 45 -279 0 111 -279 0 112 -279 0 132 -279 0 133 -279 0 226 -279 0 227 -279 0 247 -279 0 248 -279 0 314 -279 0 328 -279 0 329 -279 0 31 -280 0 45 -280 0 46 -280 0 112 -280 0 113 -280 0 133 -280 0 134 -280 0 135 -280 0 224 -280 0 225 -280 0 226 -280 0 246 -280 0 247 -280 0 313 -280 0 314 -280 0 328 -280 0 31 -281 0 32 -281 0 46 -281 0 47 -281 0 113 -281 0 114 -281 0 115 -281 0 135 -281 0 136 -281 0 137 -281 0 222 -281 0 223 -281 0 224 -281 0 244 -281 0 245 -281 0 246 -281 0 312 -281 0 313 -281 0 327 -281 0 328 -281 0 32 -282 0 47 -282 0 48 -282 0 115 -282 0 116 -282 0 137 -282 0 138 -282 0 139 -282 0 220 -282 0 221 -282 0 222 -282 0 243 -282 0 244 -282 0 311 -282 0 312 -282 0 327 -282 0 32 -283 0 33 -283 0 48 -283 0 116 -283 0 117 -283 0 139 -283 0 140 -283 0 141 -283 0 218 -283 0 219 -283 0 220 -283 0 242 -283 0 243 -283 0 311 -283 0 326 -283 0 327 -283 0 33 -284 0 34 -284 0 48 -284 0 49 -284 0 117 -284 0 118 -284 0 119 -284 0 141 -284 0 142 -284 0 143 -284 0 216 -284 0 217 -284 0 218 -284 0 240 -284 0 241 -284 0 242 -284 0 310 -284 0 311 -284 0 325 -284 0 326 -284 0 34 -285 0 35 -285 0 49 -285 0 50 -285 0 119 -285 0 120 -285 0 143 -285 0 144 -285 0 145 -285 0 214 -285 0 215 -285 0 216 -285 0 239 -285 0 240 -285 0 309 -285 0 310 -285 0 324 -285 0 325 -285 0 35 -286 0 50 -286 0 51 -286 0 120 -286 0 121 -286 0 145 -286 0 146 -286 0 147 -286 0 148 -286 0 211 -286 0 212 -286 0 213 -286 0 214 -286 0 238 -286 0 239 -286 0 308 -286 0 309 -286 0 324 -286 0 35 -287 0 36 -287 0 51 -287 0 52 -287 0 121 -287 0 122 -287 0 123 -287 0 148 -287 0 149 -287 0 150 -287 0 151 -287 0 208 -287 0 209 -287 0 210 -287 0 211 -287 0 236 -287 0 237 -287 0 238 -287 0 307 -287 0 308 -287 0 323 -287 0 324 -287 0 36 -288 0 37 -288 0 52 -288 0 123 -288 0 124 -288 0 151 -288 0 152 -288 0 153 -288 0 154 -288 0 205 -288 0 206 -288 0 207 -288 0 208 -288 0 234 -288 0 235 -288 0 236 -288 0 307 -288 0 322 -288 0 323 -288 0 37 -289 0 38 -289 0 52 -289 0 53 -289 0 54 -289 0 124 -289 0 125 -289 0 126 -289 0 154 -289 0 155 -289 0 156 -289 0 157 -289 0 158 -289 0 201 -289 0 202 -289 0 203 -289 0 204 -289 0 205 -289 0 233 -289 0 234 -289 0 305 -289 0 306 -289 0 307 -289 0 321 -289 0 322 -289 0 38 -290 0 54 -290 0 126 -290 0 127 -290 0 128 -290 0 158 -290 0 159 -290 0 160 -290 0 161 -290 0 162 -290 0 197 -290 0 198 -290 0 199 -290 0 200 -290 0 201 -290 0 231 -290 0 232 -290 0 233 -290 0 305 -290 0 321 -290 0 38 -291 0 39 -291 0 54 -291 0 55 -291 0 128 -291 0 129 -291 0 130 -291 0 162 -291 0 163 -291 0 164 -291 0 165 -291 0 166 -291 0 167 -291 0 168 -291 0 169 -291 0 170 -291 0 189 -291 0 190 -291 0 191 -291 0 192 -291 0 193 -291 0 194 -291 0 195 -291 0 196 -291 0 197 -291 0 229 -291 0 230 -291 0 231 -291 0 304 -291 0 305 -291 0 320 -291 0 321 -291 0 39 -292 0 40 -292 0 55 -292 0 56 -292 0 130 -292 0 131 -292 0 132 -292 0 170 -292 0 171 -292 0 172 -292 0 173 -292 0 174 -292 0 175 -292 0 176 -292 0 177 -292 0 178 -292 0 179 -292 0 180 -292 0 181 -292 0 182 -292 0 183 -292 0 184 -292 0 185 -292 0 186 -292 0 187 -292 0 188 -292 0 189 -292 0 228 -292 0 229 -292 0 303 -292 0 304 -292 0 319 -292 0 320 -292 0 40 -293 0 41 -293 0 56 -293 0 57 -293 0 132 -293 0 133 -293 0 226 -293 0 227 -293 0 228 -293 0 302 -293 0 303 -293 0 318 -293 0 319 -293 0 41 -294 0 42 -294 0 57 -294 0 58 -294 0 133 -294 0 134 -294 0 135 -294 0 136 -294 0 223 -294 0 224 -294 0 225 -294 0 226 -294 0 301 -294 0 302 -294 0 317 -294 0 318 -294 0 42 -295 0 58 -295 0 59 -295 0 136 -295 0 137 -295 0 138 -295 0 221 -295 0 222 -295 0 223 -295 0 300 -295 0 301 -295 0 317 -295 0 42 -296 0 43 -296 0 59 -296 0 60 -296 0 138 -296 0 139 -296 0 140 -296 0 219 -296 0 220 -296 0 221 -296 0 299 -296 0 300 -296 0 316 -296 0 317 -296 0 43 -297 0 44 -297 0 60 -297 0 61 -297 0 140 -297 0 141 -297 0 142 -297 0 217 -297 0 218 -297 0 219 -297 0 298 -297 0 299 -297 0 315 -297 0 316 -297 0 44 -298 0 45 -298 0 61 -298 0 62 -298 0 142 -298 0 143 -298 0 144 -298 0 145 -298 0 214 -298 0 215 -298 0 216 -298 0 217 -298 0 297 -298 0 298 -298 0 314 -298 0 315 -298 0 45 -299 0 46 -299 0 62 -299 0 63 -299 0 145 -299 0 146 -299 0 147 -299 0 148 -299 0 211 -299 0 212 -299 0 213 -299 0 214 -299 0 296 -299 0 297 -299 0 313 -299 0 314 -299 0 46 -300 0 47 -300 0 63 -300 0 64 -300 0 148 -300 0 149 -300 0 150 -300 0 151 -300 0 152 -300 0 207 -300 0 208 -300 0 209 -300 0 210 -300 0 211 -300 0 295 -300 0 296 -300 0 312 -300 0 313 -300 0 47 -301 0 48 -301 0 64 -301 0 65 -301 0 152 -301 0 153 -301 0 154 -301 0 155 -301 0 204 -301 0 205 -301 0 206 -301 0 207 -301 0 294 -301 0 295 -301 0 311 -301 0 312 -301 0 48 -302 0 49 -302 0 65 -302 0 66 -302 0 155 -302 0 156 -302 0 157 -302 0 158 -302 0 159 -302 0 160 -302 0 199 -302 0 200 -302 0 201 -302 0 202 -302 0 203 -302 0 204 -302 0 293 -302 0 294 -302 0 310 -302 0 311 -302 0 49 -303 0 50 -303 0 66 -303 0 67 -303 0 160 -303 0 161 -303 0 162 -303 0 163 -303 0 164 -303 0 165 -303 0 194 -303 0 195 -303 0 196 -303 0 197 -303 0 198 -303 0 199 -303 0 292 -303 0 293 -303 0 309 -303 0 310 -303 0 50 -304 0 51 -304 0 67 -304 0 68 -304 0 165 -304 0 166 -304 0 167 -304 0 168 -304 0 169 -304 0 170 -304 0 171 -304 0 172 -304 0 173 -304 0 174 -304 0 175 -304 0 176 -304 0 177 -304 0 178 -304 0 181 -304 0 182 -304 0 183 -304 0 184 -304 0 185 -304 0 186 -304 0 187 -304 0 188 -304 0 189 -304 0 190 -304 0 191 -304 0 192 -304 0 193 -304 0 194 -304 0 291 -304 0 292 -304 0 308 -304 0 309 -304 0 51 -305 0 52 -305 0 68 -305 0 69 -305 0 70 -305 0 178 -305 0 179 -305 0 180 -305 0 181 -305 0 289 -305 0 290 -305 0 291 -305 0 307 -305 0 308 -305 0 52 -306 0 53 -306 0 70 -306 0 71 -306 0 288 -306 0 289 -306 0 306 -306 0 307 -306 0 53 -307 0 54 -307 0 71 -307 0 72 -307 0 287 -307 0 288 -307 0 305 -307 0 306 -307 0 54 -308 0 55 -308 0 72 -308 0 73 -308 0 286 -308 0 287 -308 0 304 -308 0 305 -308 0 55 -309 0 56 -309 0 73 -309 0 74 -309 0 285 -309 0 286 -309 0 303 -309 0 304 -309 0 56 -310 0 57 -310 0 74 -310 0 75 -310 0 284 -310 0 285 -310 0 302 -310 0 303 -310 0 57 -311 0 58 -311 0 75 -311 0 76 -311 0 77 -311 0 282 -311 0 283 -311 0 284 -311 0 301 -311 0 302 -311 0 58 -312 0 59 -312 0 77 -312 0 78 -312 0 281 -312 0 282 -312 0 300 -312 0 301 -312 0 59 -313 0 60 -313 0 78 -313 0 79 -313 0 280 -313 0 281 -313 0 299 -313 0 300 -313 0 60 -314 0 61 -314 0 79 -314 0 80 -314 0 81 -314 0 278 -314 0 279 -314 0 280 -314 0 298 -314 0 299 -314 0 61 -315 0 62 -315 0 81 -315 0 82 -315 0 277 -315 0 278 -315 0 297 -315 0 298 -315 0 62 -316 0 63 -316 0 82 -316 0 83 -316 0 276 -316 0 277 -316 0 296 -316 0 297 -316 0 63 -317 0 64 -317 0 65 -317 0 83 -317 0 84 -317 0 85 -317 0 274 -317 0 275 -317 0 276 -317 0 294 -317 0 295 -317 0 296 -317 0 65 -318 0 66 -318 0 85 -318 0 86 -318 0 273 -318 0 274 -318 0 293 -318 0 294 -318 0 66 -319 0 67 -319 0 86 -319 0 87 -319 0 88 -319 0 271 -319 0 272 -319 0 273 -319 0 292 -319 0 293 -319 0 67 -320 0 68 -320 0 88 -320 0 89 -320 0 270 -320 0 271 -320 0 291 -320 0 292 -320 0 68 -321 0 69 -321 0 70 -321 0 89 -321 0 90 -321 0 91 -321 0 268 -321 0 269 -321 0 270 -321 0 289 -321 0 290 -321 0 291 -321 0 70 -322 0 71 -322 0 91 -322 0 92 -322 0 93 -322 0 266 -322 0 267 -322 0 268 -322 0 288 -322 0 289 -322 0 71 -323 0 72 -323 0 93 -323 0 94 -323 0 265 -323 0 266 -323 0 287 -323 0 288 -323 0 72 -324 0 73 -324 0 74 -324 0 94 -324 0 95 -324 0 96 -324 0 263 -324 0 264 -324 0 265 -324 0 285 -324 0 286 -324 0 287 -324 0 74 -325 0 75 -325 0 96 -325 0 97 -325 0 98 -325 0 261 -325 0 262 -325 0 263 -325 0 284 -325 0 285 -325 0 75 -326 0 76 -326 0 98 -326 0 99 -326 0 100 -326 0 259 -326 0 260 -326 0 261 -326 0 283 -326 0 284 -326 0 76 -327 0 77 -327 0 78 -327 0 100 -327 0 101 -327 0 257 -327 0 258 -327 0 259 -327 0 281 -327 0 282 -327 0 283 -327 0 78 -328 0 79 -328 0 80 -328 0 101 -328 0 102 -328 0 103 -328 0 256 -328 0 257 -328 0 279 -328 0 280 -328 0 281 -328 0 80 -329 0 81 -329 0 103 -329 0 104 -329 0 105 -329 0 254 -329 0 255 -329 0 256 -329 0 278 -329 0 279 -329 0 81 -330 0 82 -330 0 83 -330 0 105 -330 0 106 -330 0 107 -330 0 252 -330 0 253 -330 0 254 -330 0 277 -330 0 278 -330 0 83 -331 0 84 -331 0 107 -331 0 108 -331 0 109 -331 0 110 -331 0 249 -331 0 250 -331 0 251 -331 0 252 -331 0 275 -331 0 276 -331 0 277 -331 0 84 -332 0 85 -332 0 86 -332 0 110 -332 0 111 -332 0 112 -332 0 247 -332 0 248 -332 0 249 -332 0 273 -332 0 274 -332 0 275 -332 0 86 -333 0 87 -333 0 112 -333 0 113 -333 0 114 -333 0 245 -333 0 246 -333 0 247 -333 0 272 -333 0 273 -333 0 87 -334 0 88 -334 0 89 -334 0 114 -334 0 115 -334 0 116 -334 0 243 -334 0 244 -334 0 245 -334 0 270 -334 0 271 -334 0 272 -334 0 89 -335 0 90 -335 0 91 -335 0 116 -335 0 117 -335 0 118 -335 0 119 -335 0 240 -335 0 241 -335 0 242 -335 0 243 -335 0 268 -335 0 269 -335 0 270 -335 0 91 -336 0 92 -336 0 93 -336 0 119 -336 0 120 -336 0 121 -336 0 122 -336 0 237 -336 0 238 -336 0 239 -336 0 240 -336 0 267 -336 0 268 -336 0 93 -337 0 94 -337 0 122 -337 0 123 -337 0 124 -337 0 235 -337 0 236 -337 0 237 -337 0 265 -337 0 266 -337 0 267 -337 0 94 -338 0 95 -338 0 96 -338 0 124 -338 0 125 -338 0 126 -338 0 127 -338 0 232 -338 0 233 -338 0 234 -338 0 235 -338 0 263 -338 0 264 -338 0 265 -338 0 96 -339 0 97 -339 0 98 -339 0 127 -339 0 128 -339 0 129 -339 0 130 -339 0 131 -339 0 228 -339 0 229 -339 0 230 -339 0 231 -339 0 232 -339 0 261 -339 0 262 -339 0 263 -339 0 98 -340 0 99 -340 0 100 -340 0 131 -340 0 132 -340 0 133 -340 0 134 -340 0 225 -340 0 226 -340 0 227 -340 0 228 -340 0 259 -340 0 260 -340 0 261 -340 0 100 -341 0 101 -341 0 102 -341 0 134 -341 0 135 -341 0 136 -341 0 137 -341 0 138 -341 0 221 -341 0 222 -341 0 223 -341 0 224 -341 0 225 -341 0 257 -341 0 258 -341 0 259 -341 0 102 -342 0 103 -342 0 104 -342 0 138 -342 0 139 -342 0 140 -342 0 141 -342 0 142 -342 0 217 -342 0 218 -342 0 219 -342 0 220 -342 0 221 -342 0 255 -342 0 256 -342 0 257 -342 0 104 -343 0 105 -343 0 106 -343 0 142 -343 0 143 -343 0 144 -343 0 145 -343 0 146 -343 0 147 -343 0 212 -343 0 213 -343 0 214 -343 0 215 -343 0 216 -343 0 217 -343 0 253 -343 0 254 -343 0 255 -343 0 106 -344 0 107 -344 0 108 -344 0 109 -344 0 147 -344 0 148 -344 0 149 -344 0 150 -344 0 151 -344 0 152 -344 0 207 -344 0 208 -344 0 209 -344 0 210 -344 0 211 -344 0 212 -344 0 250 -344 0 251 -344 0 252 -344 0 253 -344 0 109 -345 0 110 -345 0 111 -345 0 152 -345 0 153 -345 0 154 -345 0 155 -345 0 156 -345 0 157 -345 0 158 -345 0 159 -345 0 200 -345 0 201 -345 0 202 -345 0 203 -345 0 204 -345 0 205 -345 0 206 -345 0 207 -345 0 248 -345 0 249 -345 0 250 -345 0 111 -346 0 112 -346 0 113 -346 0 159 -346 0 160 -346 0 161 -346 0 162 -346 0 163 -346 0 164 -346 0 165 -346 0 166 -346 0 167 -346 0 168 -346 0 169 -346 0 170 -346 0 171 -346 0 187 -346 0 188 -346 0 189 -346 0 190 -346 0 191 -346 0 192 -346 0 193 -346 0 194 -346 0 195 -346 0 196 -346 0 197 -346 0 198 -346 0 199 -346 0 200 -346 0 246 -346 0 247 -346 0 248 -346 0 113 -347 0 114 -347 0 115 -347 0 116 -347 0 171 -347 0 172 -347 0 173 -347 0 174 -347 0 175 -347 0 176 -347 0 177 -347 0 178 -347 0 179 -347 0 180 -347 0 181 -347 0 182 -347 0 183 -347 0 184 -347 0 185 -347 0 186 -347 0 187 -347 0 243 -347 0 244 -347 0 245 -347 0 246 -347 0 116 -348 0 117 -348 0 118 -348 0 119 -348 0 240 -348 0 241 -348 0 242 -348 0 243 -348 0 119 -349 0 120 -349 0 121 -349 0 122 -349 0 237 -349 0 238 -349 0 239 -349 0 240 -349 0 122 -350 0 123 -350 0 124 -350 0 125 -350 0 234 -350 0 235 -350 0 236 -350 0 237 -350 0 125 -351 0 126 -351 0 127 -351 0 128 -351 0 231 -351 0 232 -351 0 233 -351 0 234 -351 0 128 -352 0 129 -352 0 130 -352 0 131 -352 0 228 -352 0 229 -352 0 230 -352 0 231 -352 0 131 -353 0 132 -353 0 133 -353 0 134 -353 0 135 -353 0 224 -353 0 225 -353 0 226 -353 0 227 -353 0 228 -353 0 135 -354 0 136 -354 0 137 -354 0 138 -354 0 139 -354 0 220 -354 0 221 -354 0 222 -354 0 223 -354 0 224 -354 0 139 -355 0 140 -355 0 141 -355 0 142 -355 0 143 -355 0 144 -355 0 216 -355 0 217 -355 0 218 -355 0 219 -355 0 220 -355 0 144 -356 0 145 -356 0 146 -356 0 147 -356 0 148 -356 0 149 -356 0 210 -356 0 211 -356 0 212 -356 0 213 -356 0 214 -356 0 215 -356 0 216 -356 0 149 -357 0 150 -357 0 151 -357 0 152 -357 0 153 -357 0 154 -357 0 155 -357 0 156 -357 0 203 -357 0 204 -357 0 205 -357 0 206 -357 0 207 -357 0 208 -357 0 209 -357 0 210 -357 0 156 -358 0 157 -358 0 158 -358 0 159 -358 0 160 -358 0 161 -358 0 162 -358 0 163 -358 0 164 -358 0 165 -358 0 195 -358 0 196 -358 0 197 -358 0 198 -358 0 199 -358 0 200 -358 0 201 -358 0 202 -358 0 203 -358 0 165 -359 0 195 -359 0 POINT_DATA 3925 SCALARS pointLabels float 1 LOOKUP_TABLE default 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 1 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 4 1 1 1 1 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 1 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ants-1.9.2+svn680.dfsg/Examples/Data/beetlerot.jpg000066400000000000000000000203141147325206600215760ustar00rootroot00000000000000JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( )U.{PёXNWytAMb9tEh?7e(q^a? 6s۟Pŝ,uV?@4껇\њcBc/F?CV#Yw{m-4黩k|c\6 ,F-ACQo'*jt7 IEQEQEQEQEQEQEQEQEQEQEQEQEQEPN)2(h&_Ϊ:a-v p\;UMg#0ʩ+֌>ʑ(U <}h43_6=j?cL}: {Y=j/o.אNOL걥ۭ#A@- X.Jv`TwWvM<k+ *k`H^!rI1 Fǯ$JT*^5_1>?M.3tOExx$G$+jU.’:( j51JBum"NginLqȪ޼MuNͥMdSC]3Vx5m>_S[G"ȁU9+kc_aۨ5e \.{K@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@!`'#PX2j.sfK8d?}+/OQhйPϪԒN}\@:a1$%{P\Ak7ɗ^LOX?ҧ9QR/&Oi3Q~Df-FAS,gh^RP+w? jFdF$@TGWAifvXC '[~S[zX(?#~%ukx2H[i7K*/6[,G'KiF R."I U8>4]WFP#̄`oƻ(|[zXy&]ᢎ[j\ӡ A]?'ZҭFG&8o::ƛm[̻0{r*jr!1K'YQZvj6+`vqPCF}COw3YZxO32MvW3xm.7RmxḦ{; t~ͩ;4ׇKۿ."d?с|ۿPr3c8hm,jRиUwd kZS>$o̓h-qw )P}IHATA@`+:Y?/foZ}E{M-zIƺgeܦheH!jdқz5䎦?ƊiwJ TQEQEQEQEQEQEQEQETRNsRי.k,qhg;}H2ă]YCd8i-._ʰunGxn{ekljv̪@hj L e =+]=a5̬4\zψ|Qxfa~HA{S@f-:#CMsYyelV' Xg9#ߥLDwPq\h,~2\  2gW{fAt^|ȯAj/.Ky{wdeIɪ$6hTי|?uuxak-.dz(G@*H#=*5fQ K{$G,;?[,T0`)D}ԻZf(jvUD%YGF?B)d~UqCU\#R=,. Vuÿ \%a$#!rkFS6=.k kzզo#y`}w n7٪WJDVҏSҀ<᧊;GfG'6NǕn3GOz_Nx{zW@+شH#5΀L IE΍Yed@wW]evQ+zX# `AXy]mrМ.@Zgw4QEQEQEQEQEQEQE'?|3:IbeY''X=1\<8݀G6? x剈f2áWE&n( c8Sn|G$Mϕ r#@%Lzon qr&IYNMOvP @1R8$?R([ºcq50~Hя>kՎ [xrc_*kXт8SP&u{-̶hT#$km-aC%˅l_axk8iXbB<lQ3״mEuga t|AwCiycm1i&cm7'=/Lšfr4,Cwl̒ᐎƾ𖺺k| W,~ zw‹%Sq07q儑wYwp>NѲBkb/bkMy=u?J^(CБ4-ɈoL(ր*f[,ҝ.qTf^YϷۃ2 m6߯(qVx"ƕҀ fx1p:mVesO rwTRoD ߻3?lPcEGF; ( ( ( ( ( ( FPF -Cp"n> kz"Wcf3_^,"QVZ%)8&-q@KZ߆k5Iܟc/5P|BCA$2r2>^M*e)\r;^;F"o]fg[_@Yzs+V&Ix\WR[8)3N̿ti:4r:@Q@Q@Q@Q@Q@Q@r:y2H}fGNu l{㵏3J<u/-҉1؛5?iQiNC}__PKem:X#q>.ԯd-q%į6?:ۀ' IMׄt[, VM?OZ"P?>DoDo`ƽCǦĢ/%N7JIv-8& Y~;_ jJyiG>ȵ{|σڴvay ;Кv{͕s?;$5OiCjG@j?oX &:w*m~2k0Orcbl6Fq/@6OF'1uO^[x=Z].Փ=ȫj˶Elz0 g.\_> ǶV" "(CM?Tkz:ŗZ@[yW)/kbx xKĶx)9?5ϭҎ˂?a<q~iS#1[-kA& %[K>T?Vn XWZޓK)T8c}:X\L38#u]Š&MR,$u{NWtw?fF]Y~~qrol[]gBhݞO4CF>]m9A˟x?A]m,|I Ḽʜ`W,oV{lF[>FX?/ I a1 P~Ů7WEJƘ9y495 M-dh±ܿQ^=wge7oynZ, ddg5x[P|Z߄ %g c?3LS! CƾOM'"ɜ|FF{dּ½;Ţ܀Nq/x[uKɤ|2H1`H1g ?dW r&+l|@:R Z(((((((((((0QLha(UCVuDŽtC['>ջEpן 4[\ ɟ%+h7y& ᾿fI@=ziP-xGp5$^'Fܨ$‡Үi>|Aj@Mі7z]m? ^%$v@|d!xqo[x놹Ei+ᧈ-s倠dg̴&'jX¯jTfIDs>ў~Rq^Htri83P\ĶCk3OFG`?|W6;z(-sXd U>#`x'y"J:H9*7ޛOn/-fAnyhůصi'j\ˁ ;qmirsMIot0yLu!N?vLX衚3Gq~3׮rZ_}gF~uQ`&* G7ν#6:}:YR7* $j=EgGjq{eskne%Sqֻ/H-4wӧ_@+vվ $tcZw:yig4Vk>}4Ī)8O+|9GICL4o]x&-c(}El((((((((((((((((((*P)hdQT.|; Kk+V/ͪ}rڇ"- vzVvWֹۏ>3$r_VR`zPěn${s|)iu`Dy>ٯZF[Nn'@N6Euw5/MOʥPr2(PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPants-1.9.2+svn680.dfsg/Examples/Data/c.nii.gz000066400000000000000000000111371147325206600204540ustar00rootroot00000000000000Jc.nii \UM򅘻)RcP*ZjjJaf.*55ԴL'fPV3(=u:t`ogl?^fΜ{b .n. J+fO$Ҳ"y7[zv$nkc ]ʻ ?(aaaaaaaaaaaaaaaaaaai,k5w#0Ҹ%0p)BOfvE9of*O_o8|ÀlÒ+QS?NB;hoUm]Ф V/A3u_K[ E"ivCO íRJ7.Bʹ砙LesWB;hx3QFTSʘGNƅa/ƍ`\,uv/Q.LYzAmK1*7кtob'[dǽ)6:Q0NwrLR4@N(r&o/Blzt4Qv4rsJ?Ɓ`\ƉbܿJaOr2EX%sL>#DU&{Ƌq7ҊVf25T1 k;>#NNO_/n뮪ƚLuZ!n[ҎfNwx1驁uDX@k!)[j麑0z먊.][VGfD-eRb5Yn~7Vetޞقœ>@~ź6:)}5E]|)[[ JD[,x>.hZr6:)GȔ ~idY:kcU =8؞>Lϒ>T_揊:Ac | XFCrz߫0kW԰S}@P1->rU ,?q/op|o*}iio2::^Cc?ҳ:8m3Y9{p/c6ver^L9cha zF;=EA/J#?ko`s&lnO_-"w0!n3YLqy;W6T?L\(k=18hmi5G:5ME)u}U ?L˽|0W ~C,)∇<^gC7csx ^2fmmЧ->[<{Z<M%ӗ1M KG+~X`탽~VO,^m4}W{9-t '#Nʷ:pgBcX[UB{Э;'kNJY>ˤLux#s*>/P" I#?g+:Y)I])߻bwwhҦ'gN{&mm'0Ro25.ֺ8݋Y*Ă#n1F:7Na7{k-}Ϭ"jP0͛#R%.^) ׎ {Uzs');P׀ ?5\>`yE%63ɸTZ;LtNow˘C>a#-#Yhڕ4l"4r0G=-2>;!O`Ff>g)B_+i='}hH*~b<ѷ8B>P~}^s} V`k"v5e69NA_Sƺ)Ͽ!N~RGp(q|}ROL U8rXdjEy1X-a8N\k'7SMx\.znF r9L  : Gޗ̔r >/qژv) xeJ_B~Eǹa񜞟jzKܒ'~~JgG>G?r;N2FV =κ 3}9PT)ҧ}qOG>?ZqJ4!^E 9':gb}7\fȓ{ s r!r Ƚ(smUkw5#֎XCb-5%֖<n]>܏hXb=x"bexpB&wmr=}s`&pu[J?S̖H:!\c{ v3iלw1^b}Xy+daWLyq?8=x.d0yc,sJm:W;=W6⸾ڋ w4!f狤 8ڋ ԟAm#BM6Y{< *u6ѱ/*~ g4yZАCDX2u8oЎAs=2ҳdbϻd.Zu2Bqo2_ugMBspkqq̝vwZ:Z$^4EK##tȓrZIDץg;5҆Lw*9W%yjz)̧6n7<~cD*u::{H7?ܕ9Os5^yմlu\%ecR'u\vH1?'Qޣ\N8~C{H--6C3G1m\WYgLEnQ\XwZ5o'd z s"r1"LQHxv笵ܵh,Rn^'E-uǹEX33oU+ʚlq[}pTi(*&X# nkWp5VsB5%E"VҭVG'9x_8j.a݉@ ~K1k5r8^6TZ=jj}!*hؗ)D}VG>}B/yoHoY݄>7ƀ`L83.޹I@Brh@[>!}Ks7ag {Q}[&u}ocf ˞Pqa:W9Z%{w\T.|X|*'wþdw?E[hm>7ƀ`L?4g3 )Oz2bg'}l 1=<<7Ʊm.eu{7 ʛg^^66@_}c  Ƅa%d nS[CIO^sk j/U~p4Bh}/1kXqUȻƿ 6*ojRZӠ-Bc5qv9x=!_*ojܕRZ-n=hB@ň=^Up]8QWF[hʓ75]{0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ,֡}l`ants-1.9.2+svn680.dfsg/Examples/Data/ch2brainmask.nii.gz000066400000000000000000003644321147325206600226070ustar00rootroot00000000000000͑eWVa`sFXX&1axjQTUf޿ϷB}޾-~o_?\??O'loLi]{6im#M3==뚝hiiZ@Le2ikZޞu.4$k:{gMӕ敦uMGfM3HLe&3陉 P-`'z7;yg]ٳ=k4$k:4T4k:4T5k:4hi4Zf"=3HLe۟;w;g]G{5=۳՞uM7fuMfM3i]ӁFLe2iiTZf=3׃|ְս=kiY٦M7ijZtQٴBL㻚i44M뚴Mk4M3FLi1hDZf*=3+z5g]G{5=۴蕞uM7=N*5T7k44+5ifUM뚔MM3FLg3iDzf*=3{`_5ivtoϚf4k{gm+=뚎4$=.*{5hZפiV5kRV6mhZ\ILi4hi44zf=3fE&mwLcN>kVHtk|m%ޞJӼ⑞5Mw{dWz/M󈊞W7iQ4ͽ{^ќy+3W[3g34tni4hi44fM3FLgUtQݫgYBtJzkyu{z5xg]3g]SEӺWTճ办*{5߹%MszZѳM陫\ժuG+;؛=ۣХW ~H\4繵}}&Jy&No=ҵϞ ѹixFLi4\ݴY-մY%կYw2iVLi*{L7,izg=3FLgσ}lY䑞uMwkyc]EeǺ-Yܣ+z5ߩH$UwteϚVi>rWzt- jz>My-9ݠH_ {ܻ}A=s{Hwgụn5ng:sW:|;giiftӺZgmS-ݱXӬ[4虉*z4i:{g MG3虉D5vvqe}gz6ڲ餪g]TݱIYݲy+]ٳKojO5O^)ճ{]GMit> et˶5=G} jz4=Ojtw+#+ģtmx-Oc{3ܻC-[ {|goenN̽-Za]BaMS-ݰWTKiV+hiDfg;4=ڧŽmӦHLgN~{Vg'm:ze]Ie&iU˺ێ]ѲnWgsN}yR=뺏=,5utS׍MjzOwNu9ݡanPKo>^zқp\+ZO9ZO8#'ģtmz+Nc{Nwgukt{|}_3?KwH.nUCʶw^5 f5MTf߻Li4imT65NRLg&4险 U;ޖMwm:lYۤY$\ѴvWgsKgs)%{d~;~&anu6ݤytOϦ=jhzO魿? Wz瓎kw>Fz瓎vcƧ7>X/izO;O:###/t=vLtkzZ7=B;=B?=S-ݠV~ >ӥ[jn&3h4T4ivrOzfg_g&4陉4Dz8;=]TmYۤlZ\튞u]>M/t4SKs9̈́ wLN4it>t3cπmGM5ηN?^xc'k=X':mO=Io{NzSu۞zc뤷=X+Z}O^zG֫ݳm1=V.ݙγ[2+4ig=ݢyԭMӪ^ _] 4ut*=Ӗ>StPݘHLi3虉 ;=k^iYtSٳ`ejWMٜh =h~fʆ;~&'cnljmgqL73{;lP{a3jz}om~&M'ϡ齤=X#]O>7=^zӏzMO?7=ӥ )K0KzK.`қ~KozQ/]O>HzNzSt\')қO>r0ݘRW|3=8kJӓsBW{\ݫemV ;.+4+;3+jMLWinz3T6g:4|OLg&3hzy`'ߵsvlڦM+7){vNl =wLN6ad?SM2sdLs8մ= wN4ut?]j:g}Ϩ뽤o4vN?^zӏzMO?7ufIo4]-tN[:MWKo4])tN:MWKo4]-tN+tiz.]<=O?7=X#5;t\' қO>OK=PˬnRˬnUˬWǬjwL7Ui.*3]Tg4JLg3i ߾?ŭ^Xg񪞵7vʦ;7qͯlZ}L8ݳnYY7Nw댩uN}_ ݮ3~-KKoݾ~M_/wCIot]-u~N9MWJo4]-unNӕқ9MWKo4]-u^Nӕ[9MWKo4]-tVN[9=WK4Bz3j͜7s^!tnNһ9MZz?:Mc'J=Io?!t;J'ݔY!ݗY!ݛY!ݟY!ݢY!ݤYaEsZ&meo&嫆*z3 _Sٜ 4jVhw4hiiWw1i 3L c#_밃>{ū-{-{]7Nm;o}eޗv;Ѵuim2etϺΛse]gM9ݰsnWKoz{z]oJw{~oE [^Et}Nӕ:]WJot])tfNқ9MWKot])tVN[9MWJ4]-tNN9=WK4]-tNN;9MWK4]- 齜r^!tfN+wsiZz7;:=_%Iu[pdwzrnbcOn3]j *  +1i{4 ݛgtm^9=Vݙ颪/=3~LwFLe~Lg3i=Lg&T:f*=p:yeɊ=ǎ;_tw涝r{uO6O6^nY=L9ݱ&nX9wN3ۮ9>^z{6~ez=ڸhZ-W~6]_+tNו9MWJt]-t^N[9MWKo4]-tNN9MWKo4])t>N8MWK4]-t>N9MWKo4]- 靜wr^!tVN{9MiznN+szBzS뤷>H>K70%n^ҽtI7g4+4miҽiij*+ZݰecMsˊiݚ i.D4gh&3藉4Zf"-@ ))&{fO{FL;Df*3񃎞iYtTݲi+znm+Zv<Ѵɦλ{u?nY۽L=ݰ{Ho^{=tu}+6OsjJ]omguFzϕU-Wv~>M_/u~N9]WJ4])u^Nו;9MWKt]-t>N8MWKt])t.Nһ8]WKo\-t.Nһ8=WJ4]-t.Nһ8=izFN+wry^N+7sz^!* WKzq''Gt9H'T'ݔJTKwiVIgVJgVIgVH7gVHgVH7gVxDZ~MC5=3ѣi #&t.SLgaM9l4<:w>ȫ{gö{lr;iMWnͯ4wՄ+zܔ]5Sv4MP|4eC]ݷ]?i3\ձITZf*2]{UI-뛤-{vO4}gmu;u?nX׽?!wgu^z瓚z}Wl~n]w=i]Kjj:#ϨUC=7tiRz;J͜7sZz'J}qRzj]wqRzj=piZzjM7qiZz8=WK4Bz#;9MyfN+wsz^% -]37>^zG;CǞt:fHw%S'ݔJӬnKӬKӬLϬMϬnOϬPˬnRӬRˬpOCe76ivLOzgڰb&3蘉YXF5d}CߕLg_;?S{3ϯ}Iݺ{猟yٝwu{U=w|MU皸=wzw0mDӝޟ?L3td6L739ل=wlN5at?Yϩv-sφnz^;g}C=jGku;3e=3ѭv̎t MZlO4@imu׮ [v?7~~mϭ^қW4~fMu} WYmOmZk7]YurtFzK9 7tiRz7j͜+rRz#j}qiZzj]+piZzj-+wpZz j-WH4]ٱ\ˎ9ơ?"Տ}:k];#t݇'ԝ=O{{~BݏĦ=M?J)uobO{~Jݥ^5F;Ώzprد I[N@c 6KwwPզwNu_A&ީ7mϩ{>uAާSzRݣCIubדĦս]O;T%v=IzZݑiu/b^Į'}MOV!6=CzR݃iubĦ=MO{V 6 iub.ĞPw"iu?bO{~BݕĞR'6C}{xVﻅUN{8)pz;=-1]4OeLeLe<ޘMzg6ʹzg3Owg<ޟ=3mSodPoӦyJQ{5ӊ4O*56s=o†&򻎿mNľ>kζ'7gL'?70=>~~tD>6{ݿGwc_|-ѻXy-n.=[vwp{7cmxWoxMŭxwqkw]ͷٍ}ջ=F7zos_ o~w7&ww?zN>r;w#?zoN&6M7ovgʩ3rboٟ5݄gndȦ?q6نLoٮϦmĦ}MOT 6=AlzZ݃bMO/6iubĦM?AlzZ݃.Ğ}=?E u?bĞRw&67=?Rܭ|z]7rB8Om6{ePo˦Vo˦yB/fZ/ l';g[iP͞yB;{fZ={fZ? 홧{cPӦyBQ N{6ͯ|g]~/?6#Llo5aNav:O:}+nĜWlyrS߳vMUlӟϏMUo٦?wzqwtm[q~{orn;zorۻ.7{W߫ޯM֫.t{i~{+jӭWtWXoצ_:{nޥzqw{]_7g8zorMoTy]n.N͞Ħ>N͞;tb:gnd;cc&PڲmaOٮu#Oٶ}ܳ͟;3z_n~]Vw-|?^g;`穻~w Ϫ}wN^].Ŧ]]O;T'v=NlzRݛ3iu_bדĮ]OV"v=ClzZ݇iubĦ=]O/6=bۋM?bMO/6=ĦP W₩y;ig7wǦ_M]M?#=om6D󼺣7uO6&7{*{m-n;e-wnxcFf[7T7m~u[w7n[G{nō޵7&aqw{w&yoɍޭz[rw:cg|~؋=wÞ;aƞyG?۩M={ c?=ظ'lںWٮ}'޴ݟ-3[7?-v[oQNyuQa^黇yuf}]O{Vw(v=NzZݛ/iuWbӓĮmO{Vw"v=BlzZ݅iubĮ'V_lzZ}iŦ'w~B}{iŦP^lzZ}{iŮշ~B}iubO{~B݉'=?J)uobO{~JݣSN9F=-vwqjح Ħ']}g=T==g]yulϳ>6t[ۦg}l~MϪ{mϨ{){nϪ):_;;*c nWTYˆܮ-wUUem[p6ugunMt[Խ߼}Mnx[s7]w;wWoy]Nν[zӽ{g|mt{.bw_NMs;[47e?6ϼz?ݲ] MٶϦ<~۶Mm{{NMj';l,n k}Cxw Ϩ{}0ìOpKIubĶ'՝]OT$v=HlzRݏIu'bNĶ'=MO{Tw 6=@lzZ݁bMOo/v=bꛋMOo.v=bOo.6=bO.<=?A ub^ĖPw$6'ԝ=?Nl)ubO;}w .N;ջ8%pz7=-mwwe<ޗ=3ޘM3ޘM3ޘM3ޘ]3ޗMzc6ʹzc6ʹzcS3OWmϩzŞ[3Lw1O|}K^]ڶMN}S}wVo-oubӓĮMO;xudϨ_w\͞l~MϪ;oV{S6=aKmzNÆ^7󼺏6=~{;;oϨ);}߲7{g nUTvYז;ܨ-wMUc}nq;&ugenMv߽xx鯿ƛݻ7&_79b_=.NϞ]7{ɞ=1?3x>a^-{]{eGOöæ-&G_|gqzإMUkxwQN9u՝J]MOTw(v=Nl{Rݗ#iuGb~Į'սMO{T!6=CzR݃IubĦ'V_lzZ}IŦwV]zZ}siŮ'շVZ ŦշVZ ŦP]lzZ}w'~B݁ 'Խ-?Hl)uWbO;{~BݝSŞTwu!to {89Uopz+Ùl g-ܣ҆pzW̴z[6ʹz[6ʹz[6ʹz[6ʹz[vm4m3}m۴ߡ؆=gwiv|Ŧ\1_dG7ٶ|z?N𗺇QwN7Ħ]Oo/6bӓo~Mϩo<~wks6[զg=l~MϪ{kf{Uw6=~{;;_^>pشM?-wQQc][p66uWemMov}߹7;+;u-nSwWX[ܢnCotX{mS 6T[}79=Χw?m.z'{=s;{fǁxՖ~ۏ~{횏zŞlWjSOٶ+=}WgS䴰Wn []SxVﻆyu]]O{Tw(=MzRݗ+IuGb~Ħ'݈]O{T!6=ClzR݅IubMO/6=bӓ껋MO.6=bӓ{]Oo-6=b;M?bO-<껋M?ĦP v
6ԛ}M=8S{s۪?|WomܳmM':'lk'-6vQ𗺇Q?~ygŦշV]lzZ}wiŦwy{S~K;mzN}-9t[զmV{Sw6=`KmzN^7-o6u߿g ߨ 7QMe=[p ]ߴ7{k-nRwTwXߦ[ܤmEUc}nq7&u_zu-nP{ugz{-NVw4u_[;o'_}m8M:'-ÿ]1{.bʞ-s3YW^{|6QWwl|ӻڲ] j[Oٶ+] ܫ) NN {۸!P:uWwu]MO{T'v=MzZݙ+IuGbĮ'݈]O{Tw"v=ClzR݅iubדMO/6=bӓ껋]Oo.6=b{]Oo-6=bM?bOo-6b{=?ۋM?'}?G uObO;{~Bݝ=<]zn ԛ89Uopz'{Uogk8[m6;;QoiKG-.{[RiC~vTiC~wvQG6ٶhGٶ|_=|-៶Pw.규wV^zZ}wIŦ7V[lzZ}oiŦ{V|KyN}M7ZզgwkV{Q~S{mzN}-9uzm36Zۦ=l~{ioRw6&u[enPu/[zk-nPw6u?:o=nQd;nq7uWqnQw;uWzw-NVw4uO[;}-NTnq=wtSm-r;onq[AG˦ϧgndʞyv ?WlGGa^M5?m=g~Ox/vS׶Q夰_>&nWw5-<üSpGIubĦ'ս]OVw%v=HzRݍiu/bד>Ħ}MOV v=@lzR}iŮ'wV]lzR}sIŦV[zZ}kiŮ'7VXzZ}_iŦPYl ŦP[lzZ}o'w~B}{'V_ ubO{~JݕĞR'w Qo z7]=qbدIVN79pz;l ww-жpzG m˿o™YWfN ;|z+]Q}MoubדĶշT\lzR}oIŦշVZzZ}giŦշ{V߻;m>{Q|SmzF}mo7ZצgԷk^Q~[mzF}Mo7uZl~=Ϩ{g npM]߲c=nqM=ߴ'amnqM=߶cmnq ]ߵ7;em[pM]߸7{e[p]߻';cݛnq߿c}-w8U;ltOnq[Cs{z1>^~̞=l?ʫWۚ~Ǔxz_{m~zզmnU?3ܳSPoİWC;1FݾsWw*Rw)6=QzRݟ;IugbӓĮ]]O;Tw#6=FzR݉IubĦ=]O/6=b껋MO.6=b[MOo-6=b]O+6=;MO,6b[M?bOo/6=?C)uGbO{~JݛŞTn5!^͡U[أ az}Ppz+yl79pz7Ùl7sB8OS>&n;;5|WYs>s׺[ߩ;V_zR}wiŦ'TZlzR}giŦ'7VXlzZ}c'ԷVZyZ}-97[Ϧg7kVzjW|c{mo~=_}mo6=^wg 7A.rlM8QotS]lM8UtS}l-w8]ɦ.opԽl 7AͶ.rl-w8Mtl-w8Qot=m-w8Q;lũ6wz;C?t|z9{3c3ߩ~>=݆횯zrS_٭]UOo={ro=\o[vSضPopz'}M^1<üw>Ů'=]OVw'v=LzZݗ+IuGbדnĮ'՝MO;V!6=BzZ݃bMO/v=bӓ{MO-6=bMOo,6=bM?bOo-6=bO-<껋M?ĖRw"v#}=?NIuR/^uWw.o[CMazmqbدI NN 稷rR8GSY꽜Rpz+=-Zu>zӺwS% <@zR}{iŮ'շTYlzZ}gIŦ'7TWlzZ}_i}Ş7VXyZ}gi7\ǦgԷm>{{jS{c[mo~MO}o6}ݷZצNw^ o-w8U}=߲;c=nq=߳{cMnq]߳g=np}ߴ;e}[p]߹{c[p]߻c[p=߾'{_}m8I;ltOnq-ÿ=Oq/{>~~ΞϥgnfgR? |S{ݯ-6>W;Փ{e7|SžWo崰W՝Sx^gkxN;yuR/.ubӓŮ']OTw&v=KlzRݕ#Iu7bדNĦ՝]OV 6=AzR}iŦշT]zZ}sIŦTYlzR}ciŮVWlzZ}_'7VX ŦշVZl Ŧ{V\l ŞRw 6'Խ-?I)ugbO{~Rݧ S;Kx՝:u7vpzةazmvqbحljaz'}MpSޱu_i=/,ܤꛋ]O-v=bӓMO+=M?g̞TĆ>k}t϶Gwoo~;otwaq[;e=NR}klio-w8Y.orSl-w8Ur]l-w8I)]߹8[u'tY;orSݜa] wxꞶWa=NS?fw_q>-MG?g9yŭw}?'_3{՝Lm#NOn3;y}z7O>W.n wSwNyuUu՝{U)v=QzZݡ;IugbĮ'=MO;Tw#v=DzR݅ iubӓĦMO/v=bדꛋMOo.v=b;MOo,vbM?[M?b{MO-6=ꛋ=O.bO;{~B݅SNĦ՝=?F)uObO{~RݟS.5<]CxCЪ1 pKءmWoЪ1|wXkܲ|uv.䵹]}_i}ŦVVlzZ}[imŦշVVyR}[I]Ŧ'7VTyZ}Wi]Ŧw{VVyZ}_i}Ş7VXlzZ}}opS7g 78Q}}pSwg 78Q}]rwe-w8Q}=orS7c nq[;c=NS}cwliom8M}߲o;du{g-NTw6Du'X[r]cn])=߻{9u7tX{lWsB cSo;ܟ{Aw{18~̞Ϧss l+jrRحǩaz 7F;ש~w Ϫ}wN=̪T(v=PzRݝ3iu_bדĦ']OTw"6=CzR݃iubӓĮV_lzZ}iŦ'wT[lzZ}oIŮ'7~B}giŦPZl ŦP\l ŦwV\lzZ}siŞ7{~B}{MO;Vw iubO~J݋S~ĦR$63u|M;]uu^՝:u7VUc7{=|wX.L;;~<-nm{J>7o*6=6=ŞPUlzR}SiMŦ'{VTlzR}Os6=Ş7VTlzZ}Si]Ŧw{VVlzZ}[imtYknPvs[D}vYuNTws74XyNTyk747wX=NRzk4Wƛx7_-q[;e=NS~cliom8M}ߴ;86uzٯY=NŦkjWwÏ7}l#~qu/[;m\Iwx~N魾ֻlUtBgr>=CwMΧsl9{>n>ǞϠq/nei~gG] y^&hw۲zOnٶϷaܨm߫ȉaz7^k=Sx^;ݾkxN;yuf}]O{Vw(v=NzRݙ+IuGbӓ~Į'սMO{T!v=AlzR݁iubĦMO;V_lzZ}IŦ'7TZlzZ}kiŦշ~B}o'V[lzZ}o'7~B}siŮ{V\l Ŧw~B}{iŦP_lzZ}iŦV_l ubO~ҏnTw%3'Խ[>_Ww.!V!|̿o}KW{~|wR"3q ٓ7]A}Cٕ[w=E}Gٓ[w=I}KّԷE}Gٓ[wI}KّԷE}GّԷI}KّԷI}KّԷ>)}nSSyZ}S'wVUlzZ}Wi]ŦwcM8Q}ۭtam8I}߭ov7_79I}xSw_79I}߱&オ;6$ͷWƛovԷa=q{g-NSckeϟWwß7]lw~69uQ=NIGmN>{7鏫{{Y?fCgmM=:_|Mo&k|&|{s3ndȖz lWfer'O7]6gƫl窷QlԮTo԰O[BZuWwnyuSwu՝{U)v=QzRݟ7iugbדĮ'MOT"6=DzZ݇IubĦ'{Vw 6=@ ubĮT^zR}siŦ'շVZlzZ}k'V[l Ŧ7V[ Ŧ~B}oiŦV[l Ŧ7V\lzZ}sIŦTZzZ}giŞշVZlzZ}kiŞ'@fnXwUduz yf_nP r~/'rv3'r~/'r~+7o(r+7o({r'7o(r+7o({r'({r'({r#7o);r6=m{J>)}nTTyZ}m]orշcM8Q}ۍ=tշcM8Q}߭]opwiOWzc;m{[o~=_}oo6=ݷv[٦^wl~=_Ör]~զ?W69uuwoϩ{ٺv͏սܢ+w} {Wwuw3oy]:[z1w9n~͖Ϥ_slsivlz[;>;plg-lM׀ҏi4l4'incӼVv͍lNG{7˶od7o*6=껊=Oo+6bOo,6=[M?껋=?󴺃]߮~;ܪ~ܬĦm u/~M?啽oשyEllڞ==w.ޣo=OdmyWv4{^ ~ͶyMG;;ɟ5Oo-hrw_t畻U|̆N3k+>mϦ3;z+n՛MMȯ1Wg6 >Ҧ9gmj?{`g+џ0+aT>ԿmGgJݟs{Hbg}4}X3Y7"Eˑ_ciwG |j_9w9]7s;>?̧?}TWR~Nޡ春KѪͿ%>~o7Ƹ~o78~S xK7MTd'o&>~+i;ɮOG6}R67MV-dӧo!>~i;ȦO@6}R}ie7ԷmV\v}Z}oIeקwMTX6}Z}cI}e'w=VVv}Z}Wi]eӧwMVUv}C}Wi]eק7MVT}/of{M}O^SS} j^Ӽ6omUMs۪fQ}3n^F4iv[w6omVN3۪U}7mfF4m{i~mSKۦfQ}3nfV4in[wܶ惡mTL۪U}7l~v4i^Ӽ^PPzA}C5WwԌ^SS}奄7MPU6}Z}W meϧMPX6}C}g e77=V]|C(޵|_&~M>7ןͦ?~Oslsw;ןɞ?~Owy7gVNOO6}Cm{{n nOIѸ>tvw=w [=ظi;lOcla+&o~ǯʦWelQ¦ޯMsO?;?_M}3_ׯlw<t_Оn6F?٩=?:mKwӟm_m,6]}b;O}.~')>mSv|&^9-_ϫ3w~o{8~S xKwMRd'o&>~/I;ɦOHv}R6귑MTMdӧo">~i[ȦOA6}RˮOo/>lֲ;˦Oo,>lʦO*>l{jF/o^SS}/oTk{jF/o+;jN9 j^̶惡mUMsۨM}/o^&-;iO[wҞ=mRJ;ڨfU}7nfF4m{i~ԷҎ6omRJ;ڤvI}+hV&M[i~mSKۦM}/nfF4in[w6oymWOڮ]}? 57Ԝ^QQszI}K%-ʦo*l˦o,{l޲˖o@|Zxow?MN&6mӧo򉷮?=^6߼6y|3t~iɦOH6}S^=V~o%>[՛?yz? &{M*۳aNh+kMzi^m3ջiNwkӜV֦ޮ]s3St_3Wsmn~k~pکmd̋l3?ԧ'~k}l}6bo~nC}l]3;x-ZW7oMqWoqV-e'o(>~;IɮOK6}Z^wMTld'#>~iȦOE6}Z.]Vldӧ]V^}Z}oIeק7MTW6}Z}_Imeӧշ]TT6}Z}Sf+;jN/o9k{jF9f jVӼ6omVN3۬Q}3nf6-;iO[wҞ6o]mPHڠvA}#jF iW[wҮ6omSKۦI}+hV-;iGԷҎ6omQI{ڢE}'iNM[iGԷҎmSKۦM}/nnV4inշ6oymWOzA}C 5WwԜ^RR3zI}K5=e7wMPV6}Z}[ }eϧ7=PZ6}C}o e7-V=dϧo">~ ȞOF6}C>MVldϷo'~?i~{Q]~[|FU1CbL _nfPΞޟMsCA{zi]~홟ɜVoզޫMsZW{憟n'۳gl-~OmNd?knw7MsO6|44|?+swLlNw;k kWs*UŦg8O6tbO~SoϷSS{Mҧ?]ҿ S1SWbzE~7)]=ΫT}R7]Tldӧ&>~/I[ɦOI6}ZN7MV}dӧ#>~iȮOD6}J7mT]}R}kie'7]VW6}R}[ime'w]VT6}R}O%-5WwԜ^QQzA}C 57Ԭ^PPzA}Ck~f4ivmSK;ڤA}#jFt}h_շ&oMUE{v6Y}l6dmhgշΦ}mPHڢE}'iN iW7Ү6o]mPHA}#iN-;iO[wҞmRJ;ڦM}/ofF4in[w6omVNڮ jN9f{Q}S meӧշMPW|C}gie7=P]|Z}{ ȞOA|C=Pl]d7o#>~iȦOG6 ɞoN6}C~=9[}->~oϪ 1OC [z[6 47[gnwgRoЦ9ޠ=sCE{z .m37{gnwkӜV֞'۲g6ɮNnզ|tA֟홒=bp=Ol>홉l&篷g`pVnS՟iS==}w)==[=M]lm3;x-Zݿ!>~o7Ƹ~os귔]Tl e''>~;iɦOL6}R^MTld'o$>~#iɦOHv}R6w]T d'wmTZv}R}cie'շMVV6}R}Wi]e'Ԍ^RR3zE}G5i^6omVN3۬Q}3n^&M[iO[wҞ6o}MWG5]}l6dmhgշΦMUE{6U}m6dmhgշ&oMVF;v6Y}l>t}h_շ&o}MWG5]}k>t}hW[wҞ=mQI{ڤvI}+hVF4iv7춪蓮mVN3۬]}? 57Ԝ^RR3zM}Oʦo+>β{˦O-{7=V=dӧ!{~iȦoF6}Z6귑=Bfw=Vl=Ϋ}13whbPƘȦأʦإˆاثدДxK'zs l3enhÜVӞީMsCU[z vm37;inl[e=34=3S~w6G{[4߃s[gaӟnO~?n{m;϶Mʟ͛MM7ջcz3bzcz/E~WQ7oMq_wq^-e'(>~GIɦON6}ZvwMTldקo%>~+I;ɦOIv}ZF]T=dקo >lβ˦O+>ʦOoԌ^QQszE}Gj~v4in[w6omSKۦvI}+hV i_Ѿ}MWG;v6Y}l6dmhoSwަMUE{6U}m.T]hoSwަMUE{v6Y}l6dmhgշ&oMVF;5]}k>t}h_7Ү6o=mRJ;ڤvI}+h^64iv[wܶ蓮mVN3۬+;jF/o^TT6}C}Wime7MPX|Z}g eϧ=V\|C}{ie7 {>~ {ȦOC6}C&7=PlmdӟPd˧'{>~C xO]9[->~oFg1>}3 wwR|ݼ 1O1O1WMGɱWizK6-l[27ԻgngPіަ=sZO{z ^3iN7l`ϼwhL'{g=3SmtT'hӼʞzǿW{5O|s߿{tbK?۾ݮ>{|zWuޗ]sR:RiJSofSVc{Rhj4w)m9ΫTS~Gi;ʦOP6}Z]Tldӧo&>~/i{ɮOI6}ZN7]VlMdק >S;˦Oo,>lʮO*>^RRszE}G 5i^շܶ惡mTLۦM}/hV& iW7Ҿ}MWG;v6Y}l6dmhgSwަMUE{6U}m.DMhw7&oMTDv7Q}n&T]hoSwަMUE{v6Y}l6dmhgշѾ}mPHڠvE}'iNM[i~mTLs۪U}7l~v4WwԌ^SS}/o*>lʦO+lƲ;˞o-{>˞O@6}Cw=Pl=d7o">~ ȞoJ|Kn-Teӧ(~o{)=U/;ʦoR6}C=U/M~sS7F~Uk1C1_-K[izG6l7P͖ޟ=sZA{z6 [m3;gnjPo֞ޮMsڟlvm䟣YDE{f?ݢM33SmW3`_t˟>S:mѯl?۶˧65!Wo̶9Uo4%PhZUogzVc{Rx5>~oϪ[3w~o;w8~O xKwMVl e''>~;iɦOMv}R^]Tdק#>~I{ȮOAv}R})e'wMVYv}J}[imeӧշ]TT6}Z}S j^̶惡mUMsۨM}/hV& iW7Ҿ}MWG;v6Y}m.T]hgSwަMUE{6U}m.DMi{h7&oMTD7M}oDMhw7&oMUE{v7Q}n&DMhoSwަMVF;5]}kF-;iOԷҎ6omSKۨU}7mnf47Ԝ^QQszI}Klʞo+lƲ˞O,{˞Oo/l7=Pl-d7!>~ ȞoJ|Kn귓-Vl e''>~?i=7sʦOP6}Z7MVl e7(>~G [^{Tq_U7D~Wo֘ȶءɖإKU~[b~Qo37gPΦޟ=sKE{z-Fm3왉tk64'vfLsr$'7hL'i^e߃sL-OLwW>oק]b[eޖ]sR)zGbz?cz/[bzcz/EyC|VS7]~cU7y~{UY{^[귔MTdӧ'>~;IɦOKv}ZVw]V}d'">~I;ȮOo/>lβˮOo+>ʦO j^̶惡mUMۦM}/hV i_ѾMVF;6U}m.T]hoSwަMUE{6U}m&4=i{hMTD7M}o4=hw7&oMTDv7Q}n&DMhoSwަMVF;v6]}kF-;iOԷmSK۪U}7mvf47Ԭ^QQ3zM}OiMe7wMPV6}Z}[ eӧ7MVX|Z}g eϧ7=V]|Z}{ eӧMPl d7 ~ i{ȞoE|SV7-Vld'&>~7 ɦOM|C~MTd7o(>~CiɦoP6}Z7=P~o7渧~oϩ7=_^bz czcz[bz+۰W)zO=[2{inwipb_$'eLqzk$fLrr{6͋~7IɮOJ6}ZV7]Vlmdۧo">~ IȮOo/>ֲˮOo+>ꛪ%-5ԷԜ^PPzA}CkvV4i~mQIڠ5]}k>dmhgշަMUE{v7Q}n&T]hoSw&oMSC7M}o4=FԷMSC7M}o4=hw7&oMTDv7Q}n&DMhoSw&oMVF;5]}jNM[iv76omUM3۬f]}? 5WwԌ^RR3zM}O ]eӧw=PW6}C}cieӧ7MVX|Z}gie77=V]6}Z}wie7ԷMV^6}C}iȦoA6}C7=Rd7o&>~3I{ɦOK|CnwMVldӧ&{>~;iɦON6}Zv]Vldӧ'{~G {~{W7=~kS7}[|FUѨhZPƖاحϴxC)zK=[~[Nʆlڭ2Ӝڜ-3͉2/c`~߉>ɖ? N7ۚb[o~.*~oϩ3w~o{ָ~oTw(>~?IɦON6}RnMTld'o$>~IȮOCv}R7]T^6}R}wIe'7]TVv}Z}WIM{I}K%-57Ԭ^PPڬU}7mf6M[iG[wҮ6o}MWGv6Y}l6dmho7&oMTDv7Q}n&DMhw7MSC7Q}o4=i{h&oMTDv7Q}n&DMhw7&oMTD6U}m.dmh_Ѿ6o=mQI;ڦU}7mnf4i^/oYfK[jF){ʦoo,>lƲ;˦O,{>޲˦O.>l˦o/>l d7o!~iȖoG|ZFwMPldӧo%>~+ ɦOL6}R^wMVldӧ&>~7 ɮOM6}CvMP-U/={~{Q=~kU}S|N֯G~QѩŘ+1O1_S_i_)zW6-[nvޜ-33Ӝ؝-3՟Ζy~Ύm^wNm&}ƞOlkwnW66{x[/zSS &Nn.^Nl>6,^_Ϫ)}1[]9ΪSv}JMTld'o&>~/I;ɦOIv}R>]T=d' >~Ie'w]T[v}R}gImeקwMTT}/o j^շ6omUMۦM}/hNh_շ&oMUE{6U}n&DMhw7&oMTDv7Q}n&DMi{hMSC7M}oDMhw7&oMTDv7Q}n&DMhw7&oMTD{6U}m6t}hW[wmUM3۬f]}? 57Ԭ^QQ3zI}K%-ʞOo+lʞOo,lβ[˞O->˦O.l7MPl-dӧo!~iȞoF|Z>7MVldӧo$~'i;ɞOJ6}ZV=Vd7o&>~3 ɦOM|C~MP-U/={~{W~kS7}K|NWѩhRQoᕘ昭ǶءةدФxO)zk'ԛe*'7gLsjwD?{Ev O~t?qk'S۞b[I+滹״{|jgbeքxGi[SGm1[1S1GWooz|VUoMq_wqGozQ6}R]Tldӧo&>~+I;ɦOIv}R>w]Td'o >l˦Oo.>ʦOoԷԌ^RRszA}C 5in[wܶmSK;ڤA}#jFdmhgշަMUE{6U}n&DMi{h&oMTD7M}o4=i{hMSCv7Q}n&DMhw7&oMTDv7Q}n4=hw7&oMUE{6Y}l6t}-;iG6omVN3{A}C5ԷԌ^RR3zI}K5=eϧ7MPU|Z}[i}e77MVX6}Z}cieϧw=P[6}Z}oie77MV\6}Z}s eϧշ=Pd7o!~ {ȞOD6}Z&w=V]d7o#>~iȦOE|Z6귑=Vd7o%~+i[ɦoK|Cn귓MP e7({>~K {~{W7~kUg-9[C|^/G~Woक़+1K1W1_-SzG6-l[0tnm~g{C[f?ٟ=*;E y~g2/{yWMNÍ-؄{|b˿)%)\6'ջow45vw3=v%75fw=fJPhj|^UoMq_wqOwqVwMRd'&>~3I[ɦOJ6}RN7MT]d'!>~IȦO/>{˶O,>{%-5ԷԜ^PPzA}CkvV4m{i~Ҏ]mPH5Y}l6T]hw7&oMTD7M}o4=i{h7MSC7M}o4=hw7&oMTDv7Q}n.T]hw7&oMTD7M}oDMhoSwަMUE{5]}jN64inӼ^PPzE}G%-5ԷԌ^RR3zM}OiMeӧ7=PV|Z}_i}eӧ=PY6}Z}gie7MV[6}Z}o eӧ7MP]|Z}{ie7 >~ [ȦOBv}C귐=VMdӧo">~iȦOD6}Z&7MT]dӧ"{>~ ɦoI6}ZN귒=Pd7o'{~CiʦOP|C=U/M~sQ=~[|NS7ort1z^9-ԛ{覆eP͆ۨj|-?١=3͖y|ߗ ^{#~n|ԖOol=n|r?ٔ{U]bz[uӴحة͆ءɶ昧 1GWooz|VUgmq_oqGozQ6}R귓MTld'%>~+I;ɦOIv}R>귑]Td'o >l˦Oo.>βʦO*>^RRszE}G 5ifշܶmSK;ڤA}#jFt}hgշ&oMTDv7Q}n&4=i{hMSC7M}o4=i{h&oMTDv7Q}n&DMhwSwަMTD{6U}m.DMhw7MUE{v6Y}l>t} iO[wҎmTLsۮK[jF/ofk{5=eϧ7=VU6}Z}W }eӧMVW|C}gieӧwMPZ|Z}o e7wMP^|Z}iȖOB6}Z귐MV-dӧo!{>~i{ȦOC6}Z귐MVl-dӧo!{>~ i[ȞOC6}C&귑MPd7${~/ ɦOM|C~MPe7ozM9)>~oϩ79:ۿz/^mllLw[]nf];enkdϼwwgϼʎd;/WLG?M>٤O0-&|[}l]Mw[{ۙ{ss[x)fwZ5Ugmq_wqOoqVwMTd'&>~/I[ɦOJ6}RN7MT]d'!>~IȮOo/>{ˮOo->lʮO奄ԷԜ^QQszA}CkvV4m{i~Ҏ6o=mPHڠ5Y}l6dmhw7&oMSC7M}o4=i{hMRBo4M}o4=i{h&oMTDv7Q}n&DMhw7MTD{6U}m.DMhoշ&o}MWG;5]}kF-;iO[w6omUM3ۮ+;jN9fK[jF/o7MVT|Z}Wi]eϧշMPW6}Z}_ eӧwMPZ6}Z}k eϷԷ=Pdϧo!{>~i[ȦoC6}Z귐MTldӧ {>~ i[ȦOB6}RwMVldӧ {>~ ȦOD|C6MPd7o&~7iɦoO6}Z~wMV-U/M~sQ7=~cW7o Y{C|^/G~bzL.l>>f&;-/7an62W7Qoמޱ=s=ٙ-K~Y^1>>7|bkw]>_ل;{.mlS=M Mll}lyMs[x)fwZ5>~oϪ[3w~o{8~o]Tl eק'>~;){ɦOK6}RVw]Vl}dקo#>~I[ȦOAv}R}ie'wMT\v}R}kie']TUv}Z}SI=5WwԜ^QQڮY};mnF4m{iG[wҮ6o]mPHv6Y}m.DMhw7MSChzI[&o7hzi{hMSC7M}oDMhw7&oMTDv7Q}m.T]hgշ&oMVF5]}k>t} iW7Ү=mQI{ڤM}/nnf47Ԭ^QQszE}G5WwԜ^QQszI}K%-ʞO*>˦Oo,>ֲ{˦oo.{~i;ȖOC6}ZMVl=d7!>~IȦO@6}Z7MVl dӧo >l7MPldϧo!{~iȞoF|Z>w=Pld7o'~?iɞOP6}ZTqGwqWoM9[C|^G~WWoक़֘ȆاxC:Uo~ޝsïެ=sK_{zm B{8y1+d%~ ^gﻟfԎnk?O.K{[]Mw[{ۙ{s{x%fwZ5Uo-;[U=~sWY{ʮOQ6}R]Rld'o%>~+IɦOG6}Z>w]V-d' >˦O->ƲʦO*>l+;jNYmWOڬQ}3nf6-;iW7Ү6o}MVF;6U}m&DMhԷMRB4E}$-FԷMRBo4I} $-FԷMSC7M}o4=i{hMSC7Q}n&T]hoSw&oMVF5]}k>t} iW7Ү=mQI{ڤvI}+h^64inշ̶Yf jV9K[jF/oTߋʞO*Ʋ˦o,>޲[˖oA|C7MVlMdӧo">~I[ȦOA6}R7MVl˦O/>l˦O/>dӧ {>~ ȦOD|C6=Pd7o&{~;iɞoP6}Z7=P~o;wָ~o)>~oF ^yMllL7;Ml[0t^_MԻgn7ld|l}lq gLʾKܿ#77;K-tsKSox7ԛ;ջ;;3ջs[x)fwZ5Ugmq_wqOoqVw]Tld'o&>~/I[ɮOH6}ZF]Vl]dקo">~ IȮOo/>޲[ˮO,>ʦOoԷԌ^QQzA}Cj~f4iv7mQIڠvA}#k6dmho7&oMSCiz);蝦whzI[&o7hzi{hMSC7M}o4=i{hMSC6U}l6dmh_Ѿ}MWGvE}'iNM[iGmTLs۪Y};lvv47Ԭ^PPzA}C 5WwԜ^QQszI}K%-{Q}S me7=VX6}C}g eӧշ-R^|K귐=PlMdק!~iȦOB6}RS˦O/>l˦Oo/>l˦o/>l7MP=dӧ!{>~ ȞOG|CN귒=Pdӧo'{~CiʞOQ|Z~o~oϨ[Qѫ7RSobcWodCTfZQoweP~'wjެ=sK_{zMwi-~''f}gUS?~I`OlOv6P6.';-ML}llmlyMs[x)z^V/o 9[K|FomqWoqGg)>~GIɮOM6}RfMTdӧo$>~iȦOEv}Z&귐]TˮO->βʦOo+>{I}K 57ԬymVN3۪fQ}3oV iW7Ҿ&oMVF{6Q}n&4=I[蝦wiz);&o7hzI[&o7h4=i{hMSC7M}o4=i{hw7MVF;v6Y}l6t}h_Ѿ6o]mPHڢE}'iV64iv76omVNڮ jV/oYf+;jN/of{Q}S me7MVW|C}g e7=P]v|C귐MPl=dӧ!>~ i[ȦOA|RS˦O/>l˞O/>l˦O/l7MPldϧo!~iȞoF|CF귒=Vld7o'>~;iɞoQ6}ZT7oqOwm;S|VޯGK1O1[ OzG=l}.7۳en[gnwkRo؞6m-lO yKY~ߥ ;#v?A,Im_U~ň3g1ӿrg[~د6-qK}[ mr%obUإWb^VF~o+w;Z|~_om5QǬ='(w=~?I]OLnzR^rדwV'#w=~I]OCnzRrד7To/w=]zRzkIrד}']OwT奄[jO/7Ԯ^Po]]W}]Vo]To]To]Ro;]Q[]Po[]Po{mVomVomUmTomTomSmRowڢAEiz&zM-F[6mRo7ڤBoIhzozozozozozozoznznznznznzmzlzlzlzlzkzz#z#z'z'z+z+z/z3z3z;z;z;z? jWwԞ^Q=R{zEvzOT r}妧=Yn r_B7Br_BnzZr귐V'o <~)rӓ垧MO{V/7=_nzZzir宧M_nzZ 䦿P-䦧o!7=䞧o"m䞿P귒B^r7Bnr7Vw{V xS7V~_S/Db&.^m\{ohC)r|=W;t|f3_o=3%_7^[d7:Ol[\q_{g~#د6=qK}[ mr%ojS G} /EUѨ{B%Fο~_om5S/Ǭ='(7=~CI]OLnzZfrד귒T'o#w=~I]OCnzRrד7To/w=]zRzkIrד}'ջ]O7TQ{zAu]uYvvYvvUvwMwMntEnuAnuA]YUQnQMIhz z-N[6mRo7ڤBoIhz &zM-F[6mRomSmSmSmSmSmSmTomTomTomTomVomVomVomVomW{mW[]Q;]Q;]Ro]Ro]Ro]S]To]To]Vo]Vo]Vo]Vo}PzAvzC+W;jO/TߋM妿P*M;wRx1:ۿ_W/ߪoK7w^ƿߩW;r̪SzRrӓ7T䦧o&w=~+i[]OHnzR>rדwT=' w=_nzRzwIr'MOVo+w=TnzRvzGu~evevEfEf5^%VFFv>v>V.V.F&666zM-F[6mRo7ڤBoIhz &zM-F[6mRo7ڤBۦCۦCۦCۦCۦCۦCۦCۨDۨDۨD۪E7۬F7۬F7۬F7ۮGڮGHHwJ7J7J7JLLM;N;N;N;OzAvzC W;jO/Ԏ^To*.=l7w!Rߓ[+}gPߙ[+ݹcRߢ{k}eW7y..}7^ۅV'}oėwOnp'wدMm7w=oZVاb^;x-Z_W7[{J)Fο߫;r̪SzJrӓV'%7=~/I;]OHzR6rӓwT䮧o 7=_zRzsIr'MOTo*7=S;zIzCu~u~evevUnEf5^%VNFFv>f6V.V.F&666666666666666F&V.V.V.V.V.F&F&f6f6f6f6f6f6v>v>v>FNN%V5^EfEfUnevevevu~u~u~u~+[Er]妧ջ=OB垿Po-w=YnzZzcir'MO7Vo,7=XyZzgir妧;MOw{Vo-7=Z r妧՛MO7Vo.<]nzZzwir_{Br7{Br_D =OG ;-~3/'<~C/(<~K/S xSߨW[Z)Vޯ.=\껸q)oekWЖxK}On/ԷB}g/R}nwڗ~y;e]e 6~ Ħor] nM7wⷀ7[;7w=oRWث˱K}_N/߫{B%Nֿ~_om9f)w=~GI]ONzRfrV'#w=~I]OCzRrwT/w=^nzRzoirۓ}']O7TR{zAu]u]u]uYvvYvvUvwQvwQwIntItAnuAnuAYnUUnQnQnQnMMMMMMMMMIhz &zm=tMtmtmtmt]t]t]tmtmtmtmtmtmtmtmt}t}t t+t+tKꭴʹʹݴjW/7Ԟ^Q慨{5r_wV*7=U r_7Bzgir'MO7{To,7zgir妧;MOwV,7=YnzZzgir垧{M\nzZzsir垧ջMOwB7Br귐{B&r_F =OI =~?iM~Gi[M~O=U_7Fߪo+ѨإS}cF.lo2_=3_=2˻slo *w l{X` Ol߆;On=7p_}gn)]mwԷ1og{R˕دW}c&^=[x%z _W7=V޿~_ok1QǬ='(w=~?I]OLzRVrwT}'"7=~I{]OBnzRrד宧MOwT-w=YzRz[IrMzK ݴʹʹKtKt+t t t}tmtmt]tMtMtMtm=tm=tm=tm=tm=tm=tm=tm=tM-F[6mSmUmVomW{mW{mVomVomUmUmVomVomVomVomVomVomVomW{mW[]Q;]Q;]Q;]Ro]To]U尿]Vo]Vo]Vo]Vo]Vo]W}]W}PzAvzCK-zOS}{BzW/=Xn r妧;MO7{To,7=XnzZzcir_wV,w=XnzZzcir垧[MO{V-7=[n r妧՛MO7{V.7z{/o 7䞧o!M䞿P7[B^r_MyZvr_QnzZrw{B/={7o]5Fο~WkK}c..~\[{wշ)Qߒ; mePߙ{ gTߟ{K=gf/rf 6}Ԧp] nMিnxoom3 6]l[{7r1orS G} _N/߫[{J-WŷFT'&w=~/i[]OInzRFrד귑V]'!w=~ I;]O@nzRzwIr']OV*7=T}/Ԏ^Ro=PzAvu]u]vvYvvYvQvwQwMwItEtEtA]]YnYnUnQnQQnQnQnQMMMMIhz 6F&V.v>v>f6f6f6V.V.f6f6f6f6f6v>v>v>v>NN%V5^EfUnevu~evevevevu~ jOwԞ^QQ{zEzKS}Tk=垧՛MV+r妧;=OwTo,7=XnzZzcir}妧MOBzcir妧;=OVo-7=ZyZ妧՛MO7{B垧o 7䞿PM䞿P7[Jfr_NyZ~r7V귔V xO/]r|~_S/D~c^}꛸{շq-nJSָMxS}W/wJ}s_ޝ{c3ˋ1ppզ NߕmMிxoom3:RӶqO}3WbF.^m\}x!oءעUѩhz!Nֿ~_o]=f)w=~GI]OMzR^r귒T'o#w=~i]OCzZrӓwVzIr'[MOwT+w=VzRzSR{zAvzCevevevEfEf5^%VNNNFv>v>f6f6F&V.V.F&F&F&F&66zM-F[~{~{~[ջf^^^fff[ջnfff^^^^^^NW;NW;N[i{iwWջioWջigigioWջioWջioigigi_/7Ԯ^Po=Q{zAvzC+W;jO/Tk=zO/Ի=Wn+rӓ妧=O7Vo,7=XnzZz_ir}妧MXnzZzcir垧[MOVo-7zoir妧՛=^ MO@ [=~/o#䞿P{Bnr귓[BrwV-妧oV/ߩQѪأb^m\;7w1ohS:Tߕ;+gPߜ{+gw)ōc3˫0ppͿW࿵)ǿd۟;Oo=򎫿UߚfJ}[uMq_}Cf. \{շq9oأWWѪor!Nֿ~_o]=f)w=~GI]OMzR^r귒T'o#w=~i]OCzZrӓwVz{irד'{]OTo,w=VnzRzSR;zEvzCu~evevEfEf5^5^NNNNFFv>f6V.V.f6f6V.F&F&6zM-F[667676ѽ.7ҭ.7ҭ.7ҽ66666Ͷѽѽѽѽѽѽѽѭwҝwҝwҍw....ޮw..ήӾ^Po]P{zEzC W;jOwԞ^QS}{Vo*7zW]O{Vo,7=WnzRz[ir_V+7=WnzZz_/MO7Vo,v>v>f6f6f6V.F&F&F&V.V.f6f6v>FFFv>v>v>Fv>v>FFNNNNNFNN%V5^EfEfUnu~u~u~u~u~ jOwԞ^QR}TߋM妧՛MO7Vo*7zWir]妧ջMOwV*7z[ir}妿Po,7=XyZzg/{MOV-<\n r妧=~i=~ /o"7=~/"䞿Rw{V7{V-妧oSw;[B4w9_=[x!ojVǥq[}?-4_o=2_=/o=]g+wFn|8}c7}ǖn?=-O7X&p_} oojKmqW};f.-\;q5vzR G} /ES7;[R|~_o1~OI;]OOzRnrwT䮧o$w=~IMOEzRr귐T ']OwTo.w=[nzRzgIrדm妧]O7TR;zEvzCu~u~evevUnEf%V%V%V%V%VNFv>v>v>v>f6f6V.V.V.V.V.f6v>v>FFFv>FFFFNNN%VNNNNFNN5^5^EfEfUnevevu~ j_/7Ծ..ήw...ӾӾӮ^Po=R}TߋM妧՛MO7Vo{5{M^To*7=TyZzWir_{V+7zcir垿P-7=[yZzsir_w{Vo/7z/ <~ i{M~/"<~o$䞿P䞿P垧oSǼM=UߩQѩ7BSث[}f6mlTr|3{s|A+fwjݺc6q[/o^"Ԗ3׷_𞿾-m6;wշ9oBQʵحW}c&^=[x)vor!NֿߪWz̪SzRrӓ7V'%w=~'i]OGzR.rwT-' w=~Ir'՛]OTo-7=ZzRz[irדM'{jG/Ԏ^Q]PzAu]u]vv]u]uYvvUvMwMwMwMntIntItAn]]]nYnYnYUUUUUYn]]nuAnuAnuAtEtEnuAnuAnuEtEtEtIntItEtEtEtEtEntEtEntIntIwMwQvUvvYvv]zC+j_igigWջigigigi_i_iW/7Ԟ^Ro՛MO7Vo{5{M^S奄{5{QzSir]妿Po+v>v>f6f6f6f6f6f6f6f6v>FFFNNN%VNNN%V%V5^%VNNNNN%V%V%VEfEfUnevu~ j_i_igWջigigigi_i_iW/7Ԟ^Ro{Er_wV*w=S}Tk=zOS}Tk=zSir]垿P+7=W r垧[=\nzZzs/M_n =~ i[=OC =OFnzZ6r귑{BFr_Jn {=~7i=~Ci;=OR~_o}1FίG~b^}꛸{շq1oRQʅq_}C-=eRߗKgRߝ[+g2}W]Mܪ{K2V&2LM]_zs[.wԷ涙TߗfR}Wu-Ml;[7r5vzR+C}E~Wo w^ƿߩc^T'&w=~3I{]OJn{R>rӓ귑V=䮧o!7=~i]OVo/w=\zZzkirד妧]OT*w=TnzRvzK%+W;jWwԞ^Q=]W}]Vo]U尿]To]To]S]S]Ro]Q[]Po[]Po[]Po[]Po{mW{mW{mWmVomVomVomVomVomVomVomW[]Po[]Po[]Po;]Q;]Ro]Ro]Ro;]Q;]Q;]Q;]Q;]Ro]Ro]Ro;]Q;]Q;]Po;]Q;]Q]Ro]Ro]Ro]Ro]To]To]U尿]U劣PO;OON;N;N;NOOzAzKS}/7BzWirӓ=zOS}Tk=zOS r]垿P+7=W r妧[=\ r妿P/7 䦿P{V]䞧o#7=~i=OGn+;M~+/%䦧o' 垧(<~KM9Q7;[_=[;wq5vZPɥ qS}7[ mTr|7Ws|A_)VS̤ooy{;\]q ߳-7W 񖿺"~K}onik&宙TUojKWжK_}#c6.=;wZ5~_om9o1~OI;]OOnzZ~rדwV'#7=~I]OCzZrӓwVz{irד宧{MOTo-w=XnzZz[irדM妧՛5{MvzK%+jWi_WջioWջio՛iw՛i{i{F[FW;VVVV^^^^ffffffVVVVN[F[F[F[F[NW;NW;NW;NW;N[F[F[FW;NW;NW;NW;F[F[F[F[F[i՛iw՛ioWջioWջioigigigigigi_i_iW/7Ԟ^QSyZ^To*7=Tn rM妧՛MO7T奄{5{MzS/ԻMOw{Bz_/;=[yZ垿P/7 䦧o -䦿PM䞧"7=~/#7=~iMOHn ;=~//o&䞿P 喧o)7=~KM9Q7{;wBSث[}N-\ohK:Wߘ{+gRߞ{+7d&-3;\nػ\IcͶC4jU^d6-`C BL;ɯq)'~?ޯwrws7bE|O9zkil}5'ջ嘆4)vw!71檷9fwBPhj4w=~~}1q^_]V e''>~7iɮOJv}ZN]VMd'!>~iȮOo/>ˮO->βˮOo+>ꛪ5={M}O^RR3zE}GjvV4in76omSKۦvI}+hN-;iO[wҞ=mQIڠvA}#jF iW7Ү6o]mPHڠvA}#jF-;iGԷҎ6omSKۦI}+iN-;iO[wҞ=mQI{ڢE}'iF-;iO[wҎ6omRJ;ڤvI}+h^F4iv76omVN3۬f]}?k~v4i^Ӭ^PPszE}G%-5Tk{EMe7w]VT6}Z}SiMeӧ7=TT6}Z}SiMeӧ7MPU|Z}[ }eӧ=PY|C}o e7Է=Pldϧo!~i{ȞOD|C6=Vldӧo$~'i[ɦoL6}Cn귓=PeϧozoqG_ZF_F ^yMlml}ll}LL7;oweȚޜ=sK?{斓c&9_8s]&2,T{m9O~#S՟wrUoϮ9ޜmsR3z_viS=MLl}l]lY=z/F~JW}w8~Oi[ʮOP6}Z귓]Vd'$>~iȮOD6}R귐]TˮOo.>޲{ˮO,>ʮO*>lʦOoTK[jF/oYmVN3۬fY};mnF4m{i~Ҏ6omRJ;ڤE}'iN-;iO[wҮ6o]mPHڠvA}#jF iW7Ү6o]mQI{ڢE}'iV64m{i~6omRJ{ڠvA}#jF iW7Ү6o]mPHڠvA}#jN-;iGԷҎ6omRJ;ڦfQ}3nfF4ifӼymWOzA}C 57Ԝ^QQszA}C5ԷԌ^SS}奄WwMVU6}C}[ime'wMVU6}R}SiMeӧ7MVT|C}[ }e7wMPZ|C}s e7=Pld7!>~iȞOE|C>7MVldӧo$~' {ɦoL|Cv=PleϧozoqG_ZFίG~bz/L.l>|FV6>f&n~&Mw۲gnfRoΞޟ-sө]2֍2ԍ~2͉2,~=[}nNn[[6?oŞTή9ޛ]sR3z[v)~&V6|FL.,^^S[{%~~]~5q^-eק(>~CiɮOMv}Zf귒]Tmd'o">~i[ȮO@6}ZˮO.>޲{˦O->lƲʦOo+>lʦO*>^QQsڮ]}?kvV4in7mRJ;ڤvI}+iN-;iO[wҞ=mQI{ڢvE}'iN-;iO[wҞ=mQI{ڢE}'iN&M[i~mSKۤvI}+hN iW7Ү6o]mPHڠvA}#jF-;iO[wҎ6omRJ;ڤvM}/o^F4iv[w̶yf jV/oYf jNK[jF奄7MPU6}C}[imeӧշMTU6}Z}WIMeӧ7=PV6}C}_ eϧwMPZ|K}w eӧ=Pld7!>~iȞoG|ZFwMVldӧo%~/i{ɦoL|Cv=P-U/M~9qG_ZN/G~bz /<&l>6|F6V6>f&~;-MgnfRoϞޢ-s˩m2=wY.Ӝڟ-w*?='w ?_]wϷ6'՛kNwfӜRˮ9Ԕدا̦֘Kѫ7bt9~~o~߯~9qVwMVdקo'>~3I[ɮOHv}R67MT-d'o >~IeקwMV]v}Z}sIeӧ]VZ6}R}gI}eӧ]TU6}C}[i]e'7UK[jF/oYmWOڮ]}?lnV4ivҎ6omRJ;ڤE}'iN-;iO[wҞ=mRJ;ڤE}'iN-;iO[wҞ=mQI{ڢE}'iV&M[i~mRJ;ڢE}'iN iW7Ү6o]mPHڠvA}#jF-;iOԷҎ6omRJ;ڦM}/nfV4i^/oY+;jN9+;jF9f+;jF奄7MPU6}C}[imeӧշMTU6}Z}WIMe7wMVU|C}_ e7ԷMP[|C}wie7o ~i[ȞoD6}Z&w-Pdӧ$>~' [ɦOJ6}C^=Pldϧ'[~Ki[^7rQWmQW75Z3;x!79檷17)!vw3574)R祈gnwgVЖޤ=s]2ؖR=;U 0ߩ&صOv煷_߯?3|í-- >+|K;zgvISMM Ml=lmlY=z/F~7BF_jSW]g)>~KI;ʮOPv}Rv7]Vdקo#>~iȮOBv}R7]T^6}Z}{ieӧw]T[6}Z}oie'w]VX6}R}_imeӧշ]TT6}R}Ov4i^̶惡mUMۨfQ}3oV&M[iO[wҞ=mQI{ڢI}+hV&M[iO[wҞ=mQI{ڢE}'iN-;iO[wҞ=mQI{ڤvE}'hV&4M[iGԷҞ=mQI{ڢvA}#jF iW7Ү6o=mQI{ڢI}+o^64iv76omVN3ۮfK[jF/ofK[jFf+;jF9k{EMe7wMPV6}Z}[I]eӧwMVU6}Z}W meϧMPX|C}k eӧ7=P^|Z} ;ȦoB|Zw-Vdϧo%>~+ {ɦOK6}Z^7MVld7'{>~C [^{zQWmoWѪ֘ǶȦإثxCIzOu|C3{37{en81{f[۲ejeTnΎy-{'ɎOnNnן֞t{m>}ŞmS}5ԛow4-v3571f9fR _߫ ;-qW_{rW=eקo)>~CIɮOMv}R^w]Tlmd'o">~ i[ȮO@6}R}ieקwMV]v}R}oieקշMTYv}Z}cie'շMTU6}R}Sf jVӼ慄mVN3۬fU}7nfF4m{i~mRJ;ڤvI}+hV&M[iGԷҎ6omRJ;ڤvI}+hV&M[iGԷҞ6o]mPHڢE}'iNM[i~ԷҎ6omRJ;ڤvI}+iN iW7Ү6o]mPH{ڢE}'hV64m{i~6omTL۪Y}; 5WwԌ^RR3zI}K%-5ԷԌ^QQszE}G%-5WwԜ^PPszE}G5ԷԌ^SS}/o*lʦO*>lʦoo+{lβ[˞O-˞oA|Z7=P}d7o%>~+ {ɦOK6}Z^7MVld7o'{~CiʞoRS]oUѨx)樷=fw5f-2931v31PhJޔ= _hPҖ}2[*7wg+ g[OɆt׾8r{m{>]ޯxK*V˦9Uo4%745vw)75fwBPor^_ߩKq__jSMozoRv}Z]Tdקo%>~#IȮODv}R귐]TlˮO.>l{˦O->lβʦO+>l{I}K5WwԬ^PPڮfY};lvV4iv7mSKۦvI}+hV&M[iGԷҎ6omRJ;ڤvI}+hV&M[iGԷҎ6omRJ{ڠvA}#jF iW7ҞmRJ;ڤM}/hV&-;iO[wҮ6o]mPHڠvA}#iNM[iGmSKۨfQ}3nnv47Ԭ^PPszE}G5WwԜ^QQszE}G%-5WwԜ^QQszA}C5WwԌ^RR3zM}O^TT6}Z}S ]eӧwMVU6}Z}W meӧշ=PX6}Z}c eϧ=P]|Z}{ie7 {~ ȞoG|CN귒MVdӧo&>~3 ɦOM6}Cv=Ple78~/=~1K;[!~~ףS1CWbz /L.6NNn&~~&[=z[mBK{zi77fTnn͞ܚR;[gm-Ow3IvO;Snm_^`rmw۝ ~&^vNL.^9-_߫ ;[)kqW_{rWMU/={ʮOQv}R~귓]Td'$>~)ȦOCv}Z7MVˮOo.>޲{ˮO,>ʮO*>^RR3zE}G57ԬymWO3۬fY};mnV4i~mRJ;ڤvI}+hV&M[iGԷҎ6omRJ;ڤvI}+hV&M[iG[wҞ]mPHڠvA}#jF-;iGԷҎ6omSKۦvI}+hV iW7Ү6o=mQI{ڢvI}+hV64m{i~76omTL۪]}?5WwԜ^QQszE}G5WwԜ^QQ3zE}G5WwԌ^QQszE}G%-ꛪ5=ʦOo*>lʦoo+>Ʋ;˦oo-{>˞O/[~ {ȞoE|C>7=Pldϧo&>~3 ɦOM6}Cv=Vle7zqO_7ZW~=:ۿz/,\6|F6>fMw[oTǛ]47۲gnf]17;an9{tksLI~gLw6|s>#;M OvX}[;ۛw՞v~ފv7<~&;-Ml=lmlY=_FooŸ~/~=ΪSS-e'o(>~;iɮOK6}RVS]TlMd'o!>~iȮOo/>lˮO->β;ˮO+>ʦOf jV/oYmWO3۬fY};lvV4iv7충mSK;ڤM}/ofF4ivҎ6omRJ;ڤvI}+hV&M[iGԷҞ6o]mPHڠvA}#jF-;iO[wҎ6omSKۦM}/hV&-;iW[wҞmRJ;ڤM}/o^F4iv[wܶ惡mVN3۬f+;jN9K[jF/o+;jN/o9fK[EMeӧ7Uk{5=ʦOo*{lʦO+{lֲ{˞Oo.{7=PMd7o#~ ;ɞOJ6}C^7MPdӧo'~?iʦoQ|ZMwո~߯})~~/D~WUk1Cbz[cz'[bz/ [=M{Mlm37gn+wiPo֖ޯ=sڭ3g*77g 9 &'>iԉءԍ-U&]}~Ώ{-O[:QoiZVgrSofSWodsRᥘkѪͿSwո~ׯy~=ΫTRe''>~7I{ɦOJv}RFS귑]T-dӧo!>~iȮOo/>ˮO->lƲʦO+>ꛪ%-5WwԜ^QQzA}Cj~f4ifշ6omUMs۪fQ}3nfF4in[wܶ惡mUMۦM}/hV&M[iGԷҎ6omRJ;ڤA}#jF iW7Ү6o=mQI{ڢvI}+hV64i~Ҏ6omSK;ڤvI}+hV&4m{i~6omTL۪U}7mvv47Ԭ^PPzE}G5ԷԌ^RR3zI}K5WwԜ^PPzA}C5ԷTk{EMeӧ7MVT}奄7MVT|C}[imeӧշ=PX6}Z}c e7=V\6}Z}s eӧ=P-d7o"{~ ɦoI|ZV7MVld7'>~?iʦoQ|ZMo帧~/})~~oz4w5z^9-{ow4!RiBޔ=sC-{z_6 ,ԻgnkPo؞9l3[{akTuvTӻO֖=;+ة_\N'}~حӔدا̦֘+1CעUѨoŸ~߯=~9ΫTS~OI;ʮOOv}ZvS7]Tldקo#>~I[ȦOBv}R7]V_6}R}{ie'7]V[v}R}gie'MVWv}R}WIMeӧ7UK[jF9f jV/oymWOڮY};lvV4inշ6omVN3۬fY};lnV4m{iGԷҎ6omRJ;ڤvI}+hV-;iO7Ү6o]mPHڠvA}#iNM[iGԷmTLۦM}/h^F4m{i~6omTLۨQ}3nnV4ifշ̶yf+;jN9K[jF/oK[%-{Q}SiMeӧ7MVT6}C}WiMeϧwMPV|Z}_i}e77=PZ6}Z}k eӧ7=P^|Z} ;ȞOB6}C7=Pd7o%>~+ ɦOL|Cv7MVleϧo)>~K xS_{bW7wJN_FF~bz,N6^v&{M3ջgneP̦9ޙ=sK9z e/~ 37황nlϞܜpӿ 7 ڴ ԩ-؞č- v{wo[N'}~حՄxCW-1_1SWbz /E~WQ[{%~~/}5qG_7Uo)>~KIʦOOv}Jf]Rmd'o">~I[ȦOBv}R7]T^6}Z}{ie']VZv}R}cI}eӧ]TU6}R}SiM+;jNYf jV/oymWOڮ]}?lvf4i^ӼymWOڮY};mn6M[iGԷҎ6omRJ;ڤvI}+iN iW7Ү6o]mPH{ڢE}'iN&M[i~mTL۪fU}7mnV4in76omTLs۪U}7mnf47Ԭ^PPzE}G5WwԜ^QQszE}G5ԷԌ^RR3zI}KʞOo*ʦOo*lʦoo+{>lƲ;˦oo-{>l˦Oo/{~ [ȞOC6}C&w=Vd7o%{>~/ ɞoN|Z~7=Pl-eӧozoqO_{bWwB^/G~Woक़ 1WGzGuޖ=sC1{zg l-7ԛgn+k]m+-37lnlϖܚ-+W_ &;Ů}^tǧwts֎&|/ӯW6廁] S﷎w[{{[s{x)z^FooŸ~߯=~9US~OI;ʦOOv}JfS귒]Tmd'">~I[ȦOBv}Z7MVˮO->Ʋ˦O+>lꛪ%-5ԷԌ^QQzA}C 57Ԭ^PPڮ]}?k~v4i^/oYf jVӼ慄mUMs۪fM}/hV&M[iGԷҎ6o=mQI{ڢE}'iF-;iO[wҞ=mQI{ڢvI}+o^64in[w6omUMs۬U}7mnF4in[wܶ惡mUM3ۮ jV/oYf jV9k{5=eϧ7=TT|R}Si]eӧwMVUv}Z}SiMe7wMVU6}Z}W }eӧ=PY6}Z}g eӧ=P]6}C}{ ȦoA|Z7MVmdϧ#{>~# [ɞoL|Zn=Vle7zST]oŸ~/o_NF~bz,6|F>f&[=2enfPoΞ9ޝrKI[zim3m-3SlNoΖ6Oo;kS;>9 ]vO6W~W[.Ֆ[nxCI[ Gm1[1KWohj4w=~~/o~߯=~9q^-e'(>~;)ɮOJ6}RN]VMdӧo">~ i[ȮO@6}ZˮO.>ֲ;˦Oo,>ʦO*>^RR3zI}K 57Ԭ^PPzA}Ck~v4i^Ӽyf jV/oYmWOڬU}7mf6M[iGԷҎ6omRJ;ڤE}'iN-;iG[wҞ=mQI{ڢE}'hV&4m{iv7춪惡mUMs۬U}7mvV4iv7ܶ惡mUMs۪Y};k~ jV/oYf jV/oYfk{5=ʞO*{>lʦO*>ʦO*{l˦o,{l޲˦oo/{~ ;ȞoC6}Z7=Plmd˧o${~+i{ɞoM|Zv7MP-e78~ӯ~9q__ߩ+[{_V ^Y=lyMlLLԛen7fR͖ޞrZG[z m?޳Ms-?٠-3Չ2pӿU?WΆm;>k ]7vO67n_ܴ)n`zgwԛԛ3ջx!fwZ5UwRF_jSMU/-[ʦOQ6}J~S7MTd'#>~IȮOD6}R귐MT dӧo >l[ˮO,>ʦOo+>{M}Of jV/oYfv4i^ӼymWOzA}Cj~v4i^շܶ惡mUMۦM}/hV&M[iGԷҎ6o=mQI{ڢE}'hNM[iGԷmSKۨfQ}3mnV4inշܶ惡mUMۨfQ}3nfV4in[w6oymWOڮ jV/oYf+;jN9fʞo+{>ʮO*>lʦO*{l˦o,{>l޲˦o.{l d7o!~iȦoE|Z6-Pd7&{>~; ɖOQ6}CT7o~/~5k;%~~ףQѪ+1Kbzczcz/czCuޕ=sK1[zs m}37;gnOl`ϼnюOvhLtsw 0˿ `?mW?ܤ{bewSأ^ RjBWohjTfKPdkT⅘Kѫ7Zt9~~/ooŸ~/y^{]Rld'o&>~/I;ɦOIv}R>w]Vl=dקo!>~ IȦO@6}R}ie'mVY6}R}cie'շMVVv}R}SI={I}K%-57Ԭ^PPzA}C 57ԼymWOڮ]}?k~v4i^Ӽ6omUMs۪fQ}3nf64m{i~6omRJ;ڤvI}+hV&M[iGԷҎ6omSKۨfQ}3mnV4in[w춪惡mUMs۪U}7mnV4in[w6omVNڮ]}? 57Ԭ^PPzA}C 5WwԜ^QQszI}K5=eϧ7=RW|Z}cie'7MTWv}Z}[imeӧշMPW6}Z}_i}e7wMVY|C}oie7wMV]|K귐MPl=dϧo"{~iȞOH|CV=Pd7o({>~G {^7zW]wUѨob s[x!f=fw1vw%731Qow۲cnfPІަ=sCQz i7lWmNnі^0/3_urdw??t{uw+xGiwzuة͖ءƘ+1CעUѨͿSo帣~W xKS7]Tld'%>~'i;ɮOG6}R6w]Tl=dקo!>~iȦO@v}R}{ie'շ]TX6}Z}cImeӧշMTUv}Z}SI=K[jN/oYf jV/oymWOڮ]}?k~v4i^6omUMs۪U}7nfF4m{i~mRJ;ڤvI}+hV&M[iGԷҎ6omSKۨU}7mnf4ifշܶ惡mUMs۪U}7mnV4in[wܶ惡mVN3۬ jV/oYf jN9K[jF/o7=PV|C}c e'wMVY6}R}cImeӧշ=PX6}Z}c eӧw=P[6}Z}oie7w=P_6}C귐=P]d7o#{>~iɞoJ|Z^w=V eӧo({>~G-~=ΫqO_bWB^/G~Woक़ 1K1S1[MKɱ[IzSv [17{eniRԦު=K[t6DwhLnLW6|zs_;}!tkww_nnU WozObz;cz/bzcz ^^S{!~~/}1qG_]Rld'&>~3I{ɮOIv}R>귑]V=dӧ!>~ I;ȦOAv}ZˮO.>lƲ˦O+>lʮO奄TK[jFYf jV/oY]}?k~v4i^Ӽ6omUMs۪U}7mnF4iv7mSKۦI}+hV&M[iGԷҎ6omRJۨU}7mnf4ifշ6omUMs۪U}7mnV4in[w6omVN3۬f]}? 57Ԭ^PPzA}C5WwԜ^QQ3zM}O^SS}奄7=PV|C}c eϧշMVZ6}R}gie'7MVX6}C}gieϧշMP[|Z}s e7=V-d7!{~iȞoG|ZF귒=Vd7&{>~; ʞoR6}ZMwո~/}-~~ozt1z^^bz cz[czbz'cz; &ě]-7ԻenwhPіާMsCQ{z/[gnE{g+_`';>_YԎds_\9ZnU#v;)3=v%vw1fwBQox1:ۿWwJF_{rW~KIʦOPv}Rv7MTdקo$>~IȦOEv}R]Vldӧ >l{ˮO,>lʦOo+>l{%-5ԷԌ^RRszA}C 57Ԭ^PPڮ]}?k~v4i^̶惡mUMs۪U}7mnF4i~mSKۦI}+hV&M[iG6omTLs۪U}7lvf4ifշ6omUMs۪fY};lvv47Ԭ^PPzA}C 5WwԜ^QQ3zI}K5WwԌ^SS}奄Tk{ʞOoTk{5=e7w=RX6}C}g eӧMTZ6}R}gieӧշMVZ6}Z}k eϧ7=R_|C귐=Vl=d7o"{~ ȞOH|ZN=Vldϧo'~?iʞoRT]wŸ~߯o_FFK1Cbz cz[czbz#bz3 [=-7{engRОޤ=sCM{zMf_E{v-Ss/e?aw_';>_yoŖoӾ{U;o?SSwbSofCQoe[VcsRx1:ۿ_߫ ;[)qG_]T e'o'>~7I{ɮOJ6}RN]Tl]dקo">~i[ȦOAv}ZˮOo/>lֲ˦O+>ʦO*>^SS}/of+;jN9v4i^ӼymWOڮfY};k~f4in[wܶ惡mUMۨfQ}3nf64m{i~6omTL۪U}7lvV4ifշ6omVN3ۮ]}?k~ jN9K[jN/o9fK[jF/o^SS}){>lʦOo*>lʦo*β[˞oo.>{˦Oo->[˞o@|C=V]dӧ"~iȦoH|ZN=Vdӧo'~?iʦoQ|C_7zQW}oWѩ+1Gbz[czbz#bz/cz?xS+zw 3ԛgniT՞ޯ=s3%?Wy= IvFѥikZLCOZy#"ρ-:__3\'V|nj_YMj˟X;GU=j[M3pz;y͜7rj-z 7Eѩx^ooX~7:۾9ozwRv=~Cdӓw]OLv=~+d7]OF6=~Md7]OB6=~ dדˮշ]Oo.TZ=lzZ}ci}eדʦwMOo*VT}奄TM[jnQQtڧ[w>ݢt_:]}?iNWOu~گ~tW7oA}CiNVNvnڻ7ޝDʹw;Q}3ݩiNUMvnڷSwӞd_:]}?iNWOu~گ^ݠG7oݦ6=wQ}SݦnSSiȦ#^~#d+%{VydMPlzZw=OR6Bo5w}sS;)SQѩ)QoOc_6N9%Qo8S]l~v{N3gVhϬRҞYީ=R[{fgJOMeo*gvݿY?LOwwV|{Mo+;]Vo38ߓ{ӶvLŎwٴmߣqz7'9ꭜqzMѫ7pct귿9WoX~7ǼM]OQv=~Cdד7]OJ6=~+dӓ]OFv=~Mdד귐MOBv=~ dדˮ'7]O-TYv=lzR}_i}eדʦwMOo*VT}奄ݤ&-G}E}G-;jNWOu~گ~t_:]}? jnPPtګ7~do尿;Q}3݉iNTL{wnڷSwӾdg'o:Y};iNWOu~گ^ݠ W7o}E}GM[jnRR}7o*VT6B}W ]eʦW*TT6=yZ}Wimeӓʦw=Oo+VU6=lzimeʦW+^y޲˞W/{T_6=lz d+o!VyZ귑=OG6=~}d7MOH6=~#d+%{VydMPlzZ귔MOR6Bo5w}cW;!WѨ-PGb?&N}81Wo8KLnv-QoiO)[fz_  3+՛gV7jϬTo֞YeSeo*7e~o~$jbgߵqnjS_X]j˟W;GU=>)w}7sBɩz7>-z7F~y!SboWܥ~K eד귓MOMv=~3dӓw]OHv=~mdד7MODv=~ d7]Oo/V]v=zZ}kβie˦'MOo+VVv=lzZ}WM}Oݦ&-G7o=E}G-;jnQQ{u~گ~tW7oA}C jnQQtڧ[w^dg'o};U}7۩iNVN{vvڳ~t_:]}?iNWOu~گ^ݠ O}E}GM[jnSS-z7F~9[)֫Noy=f)TzZIɦ'&VzRVIɮ#TzR&i{Ȧ'o!VlzRIe˦w]O-V[v=lzR}gβI}eʮ'wMO*VT6=lzZ}Sݤ&-G7o=E}G-;jnQQ{uګ7^ݠO7oA}C-;jnQQtګ7^dg'o};U}7iNVN{v~گ~ݠ W7o:]}? jnPPtګ7^ݢ&-G7oTm{ʞ7=PV6B}_ʦMPX6=lzR}_ieӓʦMO+VW6=lzZ}_ e˦7MPYB}o*e+MPyZi;ȞWC<~mdMPlzdӓ7MOHBVi[ɞ%{^~7d+(Vy=U/>{^7}{̫Vog}st귿5Zz7^=7qzƩz#'9ꭜ7sͮqz?Tǝ]3+cV7gǬRОYޤ=ZSfz*+whSnf̞Q?owUwW7V}gU~ݢO}E}GM[jnRR{tM}OݨyZ}WˮMPX6=lzβie;˦w=O,VY6=lzZ}cƲie˦W,VY6B}kֲ{˦W.{^lz dw=OB6=~ Ȗ#{VlzdwMPlzZVi[ɞWL<~7d=Py=U/>{^7}sScϩ Ѩh[Mz ~MqjIqz+'ę窷cNqzG=-7eˬP˖Yޛ=B;;fzjFU1ؤkbnmV ?oQϟz{͟|wWX]4.wZ}Om#8W|vs=R_c_6N{%znNdz~K<~Z5ozSRzRIɮ'&VzR^i[ɮ$TlzR6iȮo!TzZ}ieד˦w]Oo.T[v=lzR}gƲI}eʦշ]O*TT6=lzZ}SM}OݦnSS}=I}KM[jnRR{tM}OݦnSS}=I}KM[jnPP{uګӞdg:]}? jnQQ{tI}KݦnRR}奄ԷݦnSS}){VT6=yZ}W }e˦7MPY6=lzֲie+MOo-VZ6=lzZ}gƲie˦W,VY6B}k e{˦=R^Ji;Ȟo!VlyZ&iȞWH6=~# ;ɦ$^~+d+%{Vyd7=OQBpMkX~7z%UѨhc-ROc_6N9)Qo8S]l~v)QoiK'[fz[ 3+ԻgVg<ާ-JWfevm1;Mndv>ķ|fǓwm_W7V}{g6V}G7VNqw;y7k qz+'ꍜ{wqCmѪh~{<~z1֩1~S Ki[ʮ'o(TzRniɮ%TlzZNiɮ'o#TlzRI;Ȯ'MO/V_v=lzZ}wIe[˦'w]Oo,TV6=lzZ}[I]eʦwMOo*VT}奄Tm{6=G7oTߍʦ7MOo*VT}7o*TS{tڧ7^ݠt_A}C-;jnQQtڣ=Oo*VTm&_~?xz{+;ķmWU~gU{GU=&竷[qz3Ꝝ{qj z7F~Y{%Qb}kWܥ~KeדMOOv=~;d]OJv=~'dד귑]ODv=~ d7MO/V_v=lzZ}wIe[ˮ'7MOo,VW6=lzZ}[I]eʦwMO*VU6=zZ}SiMeʦ7MPU6=zZ}SiMeӓ{jnRR{tڧ7^ݠ W}E}GM[FMeʦ7=O*TT6=lzR}Oʦw=Oo+VVB}cβie+ԷMOo-^lzZ}o޲ieϓ{˦MOo-VZ6=lz޲ie+7MOo.^lzZ}w e˞WA6=~ {Ȟo"[VlyZFwMPlzd+o&Vlzd귓=PyZ|{̫ͱNou}[<~7s~K<~ۣQѫ7p[ zǾmgwrR)qz3;ǹ7SܣRwweLeˬPo͞Yޜ=J?{fzJ>m1+إ-S>K[ݥ-s#{n'~WG|fS73nk۶Lo곻]V3۪z[֊orz gws qz+žm{pS ogX~7:۾5֨1~O-eӓw]OOv=~;dw]OLv=~+dדMOEv=~dw]O@6=zZ}{Ie˦']Oo-VY6=lzR}cƲI}eʦMOo+VU6=lzZ}Wi]eʦ7MPU6=lzZ}WiMeʦ'Tm{&-O7oA}C jnQQtQ}Si]eʦwMOo*VT4+[cVܡ-,csSsӿM7=Oߵq>WlI|ۮn#]z'z˶v1Uog8OVN!Qoos<~73w~[Uc}kWܧ~Oe7]ON6=~;d귓MON6=~;dSmOD6=~-dӓw]O@6=lzZ}ie˦շMO.V]6=zZ}oֲieӓ˦7]O+VW6=lzZ}_i}eʮշMO*VU6=lzZ}Wi]eʦw=PWNs[9!Sof8_.O)[fz_ 33;gV7iϬPoӖYީ-BYfzJSeN*{{0wܓ7m|G5|ϾM5z[ٲ]wS[V~϶-ww[ώqz;;ǙgwrjMѪh~{<~3w~[Wb}7U)TlzZiʦo(VlzZIɦ'TzR^)Ȯ'"TzZI;Ȯo VzR}{ie˦շMO.V]6=zZ}oֲie;˦wMO,TXv=lzƲieӓʦMO+VWv=lzZ}WʞMO+VWg+WlĞ>߳Z?6w[ܡnqz?ƹgrJ鱗zE~[QϨm^ou}sQcVI;ʮo(VlzZiʦo(VlzR~Iɮo%۞Rl{Ri{Ȧ!TzZiȦ'MO/V_v=lzZ}{Ieד{˦MOo-^lzZ}kֲie[˦շMO,VYv=lzR}_i}eʦMO+VW6B}cβie;˞շMOo-VZ6=zZ}g e{˦=P]6=lzZ}wie˦Wo/V^6=yZ} dw=OB6=~ -d+o"VlzZ&귑MPyd+%^~3d7MOL6=~3dwMPy e7MPlz-U/>{=֨VogxV޷G~[Wo)QoGb/nԛ89Uo8CSN{=UogǸ?ߴޖ=3ޗ=B3[fZ7{fzw l-3ԻgViP֖YްS[io.enf̖8- ~=-#ۓn֞WVq'UCܧqzO;]=wwcqz3}{wp[1:ϫ ϨmVo5w}s̫TSzZI;ʦ(TzZ~Iɮ'o&RzZFIȦo#VzRi[Ȧo!TlzZiȦo T^6=lzZ}{ieˮwMO.^lzZ}{ieӓ˦7MOo.V\6=lzR}oֲie[˦շMOo-VZiȮ'"VzRi[Ȧo!TlzZiȦo V_6=lzie˦MO/V^6=yZ}ieˮwMP^6=lzZ}wIe˦7MOo.V\6=yZ}w˞MO/V_Bi;ȦWB6=~ -d귐MOB6=~ {Ȟo"Vymd+#{Vlzd귒MOJ<~/d7=OM6=~7d+'^~C e+o({Vlz-U/N9֩Vo}cU;)Q[yo^bn=ջ85Uo8KiɦWI<~+*ɞ&VyZviɦ'{Vy-e귔MPܧ~O Sou}cUcϨMϨ-Ϫ oFFMz~M{qJˮqz?Kܣ.q߽k5fzo̴zw miM4M3+۴gV7jӬPԆYޮSeo-cndʎ?op_w|g={4?.{ޞӛ!UoˮRiCl~vs[9-SoK[bn^Uѩh~{<~7z1֨1~S KIʦo(TzZnIɦo&VlzRVi;ɦ$TlzZ>IȦo#VlzR&iȮ!VzRi;Ȯo VlzdwMOA6=~ [Ȧ' ^~ -d귐MPlzZi{Ȯ' TlzR}Ie˦W@<~dwMOA6=~ [Ȟ!^~ Ȧ'o"V;\h0zi5_gKrU`H3C$ziZ6jۘocCFj;dziC^.ۙ;ohZj;oi^/黾K|I~H}H}I~Jۘ!1K\6nH2qh!єK)ݕ;[3]LtCG=S-ݤnSTKg:3ҭjnuL6)le0i*}劶?z+gz}'Woo~Tg]o~v=tHk{2vHw4q'-ctyMl{2Hi̐`K7qduoy W/>۾{>oˣO/^8z藾K_g8+}FF[GVF^m#/n`K7i6fHwe̒1S[|F4vI3mi LtzCCM%ݣnRTKg:4ҝ^Lt٨Q-YVe3-- #xіϾ*C|ĉz6:׉u?Nm:sts+M.&<1WL.n0fIȇnaӘ!ƑqVޯ^8o򨗾 %}Kt-Mו74]WK4]-}?uLw3MWKt])}/sLӕ2MWK4])}+tLw2]WJt]-}tmLҷ1]WKt])}t=L71MWK4]-}tMLw1MWK4])}t]L71MWK4]-}tML71MWJ\-}t=L0=WK\-}r}L72MWK4!}'vL]w2MWK4]-}'sLӕw2=WJ4!}+sL2MWK4]-}/uL2MWK%};tL74=wH4]-}KKO.`=_=w}qJ/}F_g8#}W9[2J{I~Jۘ#†1K ct [6Y=l{}̒1Sl>4vI4anJtHg:4ҽ.4MtzCEM!ݣnSTK7g:[4ҽ[-& UV%L-?{mo{t]߉{6ΖutuemTsR5]7MM;;8fCl>ns۸}̒a˘#–1GMctFVGF;4o蓾GzZ]ҷ4]WKt]-}CtL3]WK4])}7sLҷ3=WJ4]-};tL2]WJt]-}#tL1MWJt]-}t]Lw1MwH4]-}tmLҷ1MWK4]-}tmLҷ1]WK4]-}t]Lҷ1MWK4])}t]Lҷ1=WKǴ\-}'rLҷ2MWK4%}3uLw3MWKt])}/tL73MWJ\-}3tL73MwH4]-}7tLҷ3]WK4%}?sMҷt髣O~4IqN֯sҷ~e _g}֑n`ۘ#†1K<&n󤛸y̔1S[\6ns۸q̖c[ictKN4Mt[zC1M!ݙnNtIg;4-..Ltz6gLLSѢo:8o]Ϥx|ϼ~ga_[:_G{uwѲ7MhY=mMz;ҍ 馦Mv&;;q̕n1S<&6Y=ls[2fHwi82w>H/}F}_}ҷ}yK쓾Rj;ohiR~johziZJogڮZVj;+odiZ>jciZ>jciZ>jciZ>jodiR>j;dZZfj雙ofiCnۙ;ogiZvJ黙fziZnj黙fiCvjۙogC.雾>o葾닣W/3w~e _g8/}ͷ77Y=>fJwq)ŭctm8fKqۘ/mct;;8nh%ӄO+ݖnLtHi:{4].5MtzCIMӥ/-3Eeczfƪz2LRݢ٪g&|`׭~mǯ:㣿ўg_{u7ճNk~nd˺~ۉR=:J7J}MM{2񧻥[6f M3}f~&]ojvI4]-}KtMw4=WK4]-}KtMw4=WJt]-}CvL73]WJt]-}'tLw2MWK4]-}'tLw2MWK4]-}'tLӕ72MWK4]-}#sLw2MWK4]-}'tLw2=WK\-}/rLҷ3MWKt]-}7tL]74]WK4]-}?tL3MWK4])};tL3MWK4]-}?tL74MWK4!}Gt-]N雾fJwq+ƭct7}6K7rۘ/MNnH2ini%ӄO)=!ݖnLtHi:{3]i4MtzSgg&/=ї/7*LQݡE=3[5'\UڦҟZY+}}]Q'Z:ѳ9ɞuS%ZN4Yon(ݱߓKTK}N&>{tO\[Ict]o葾ˣG/z雾>o葾ˣG/黾K|H}J!1G-ct<&n󤛸}̕n1[|FnwHwrӸC[=ҭ0qt/.&}M4Mt_zZ1M!ݙnNtHwi4-iξLRW[:&mjP32IeZfZ߿?򯃓]意>{>߼GjDϺdG'N4te]dϺ~W9mS-ݚLTK7i~+wKigon*=fKq-ǍctyMl{2Hi8{>z蕾k_o8'}yoo9oYos[0I7q)ct}8fKq/mct#7;;e#wI74i/ФG)ctOS+M!ݖnLtHwg[4ҽijLt{zCAMsBK=ӡ9MٙIjLLSјtpBEw:f^nO?mS_y +}y^'::ѳljN6k:ݳT&ݝnNTIi*;47L7ignKI[ҝ6fKq)ct6ly677a+_o8'}Y{0JqN֯sҷ~e _7~mJQ/}G=-]>{Z}tiRjۙogiZvjۙ+fiZnj黙fziZj[oiiZ{;iI쓾 '}OKSz雾>oˣG/黾۾:z藾K_o}摑֑n`Ә#†1K|Fnm!-.^nwIr˸Kn~4vHw4ih%ӄK)ݕnKtIwi:[3ҽijLtwZ;=S-ݞ9)ݦnTtHwg:t5g>Gz3降fe3=σ[gm7 isREgӴTRg*;:Ѵ7 jYDϚtMtsR7MS)ݚ3ݚ5ݗt/;;q̖1O<&6Y=ls[4fHwm6 looo}q^yooooy _g蕾O/z雾>o^.`-Mҷ4]WKt]-}Ct M74MWJ4]-}?tLҷ3=WK!}GKO.`=-]>{Z}4]wH쓾Cz雾>z葾ˣG/>۾:o蕾_/3w~iK/};4HqFί~a摓֑Ƒn`ۘ!1K=ҭ2nqt3}LwJw3y+qt? M;;2H4ai%Szn*=Jg;4]ҽ.LtCAM%ݢRtHg:;3ҽnLv?g&h{zf#=Jg}PGϿnԴֹW:'|ꞵMٴvtgMNi:J뷥4ҽij4G}tG|ƴ͟[m̖1WL.n{2fIa̒a˘#¦1Cm#/n`JI~H}I~JJJH}8/};4o蕾O>۾Ts>ۡJMfkZOM|i3YUg͟T6ݱGWG'4?tYoJ7i5{[4ۦ;5qt+ҍ8Jq)ctyMl0fIȇna˘#¦1Cm#/n`Ә!1CMct[ ݷ~akW/^8o蓾O/黾{Z}tˣG/黾ҴιW8Um*}tvtcMCgK5MWKɞutsR7]Yutg3 MwIrӘ/ȍct7}:Jq)ct7yMl0fIȃna˘#–1G ct6Y=l3;4 l9ooo8#};6z蓾O>۾۾:o蕾W/^8z蓾O^8z藾k_o8'}yooyouom}̓n1O<&n󤛸}̓n1SL.nq)qt;L;;2H4eni%ӄK'ݔJTKwg3ҍij)LtzCE=S-ݣnStH7i:;4ҭj^5M?Sդg&zI:f"Y61 ~nZloMܶƹşzH0mlY;5t˚TϚ~WgKɞu=k-tWtWI7a̐`JH}8/}9[2IqFί^8z蕾W/^8z蕾k_Ư~8z蕾k_Ư~6o藾k_g8#};4IqN֯~aq^GN[GVF^[\6ns۸u̕n1W[\6ns۸u̖1[ƽLwK3m/ФG ctO.ctSS+=S-ݖnKTKg4ҍjδ)LtzCI=S-g3nfLtZ[]%ݮoi*4ST>g5$Y=3g,[it Lg]s5 ҪZ6RWWjYuR=kM'ZJ6hIt;Si]niڸWNn&a% .^nwHwrۘ/ȍct7}:fJwq+ƍct7}6fKq)ctY=l3;4:rҷSLlg'?Zupo]k矛?}~u;-um~s] iSNuti]dGM 4MTK4spdG&6gWNn&;a% VnHrӘ/mct#7;;i̗n1_\6n3}̒a˘!1Cm#/֑摑q^/~aq^GF[GVGNGFyoo8+}Y{ooyoqdudq88~wt7m:fKqۘ/mctҍLI73}'qt3]ҽ0qt/7{a%qt?鎦=-M{0vI3mijLt_zC3MS-ݙnMTKi{2{+]jjvLtzZcMEli3iVif)Hli63 6t}?uSߵٟl3~e'ukKGG4MlZHvi%[:ݳߐlItIjZoHi3ݙi3]Yi1MYut_LJ3u+qt7}LwIr˸Cҝ6fKq-ǭct,6Y=l{2fHwi̐`JJJJӘ!1K<&9-ly779-l{0fIe򻛤q̖1_ҝ4qt+{[6nhڸ_in~&8gW^v{ۙ8g!єK ctSzZ+MS-ݕKTKg3ҭijLtsZ9=S-ݝf9%ݫVtH7i:;3-Nf3=HlVt3>Ff#M߅I~I+Ϫlimuk>!MM7hZH YIuti]'ёhtӺ~=k-4MtkC5MS-ݚLTJ7i盦JMK74m-qt37{[e!mct7mI7ȃnaӘ!1Ol>nm̗n1_l>n{2Hi̐`K7ȋnaØ%Æ1O<&nwHwrӸG[=ҭ0nfSn~&4H4eni#ҔG)ctKS&M{[2H4eni'TzJTKi3ҍijLtkZZ9=S-ݝnQTKg3ҝNnLtzKe=Elg4降6_iUL_=3/i4fzo?g~]GR >ugUwմʎ:{4 U.CWC=kmN4wTϺ~T?[;Jw{4j4MtoZ5MS%ݘ[&=-MK74q)qt37{[i!MNnwHwr˸C[=ҭ2nqt+7{a# >f{>fK]ҽ2n1S<&n󤛸y̔1S\6nwHwrӸG[=ҭ0nfO^v&4H4ai%ӄK ctOO) S-ݘLTKwi;3ҭitMtoZZ;M!ݞOtH7g;3=j&5MtzZM=)ݪWt2[iVzf=HlVt3S>Vf#=߿?Dk3Ig]*[Y|UuGMϨg]Q iN롻Φuv{4NvsgMD3'[5 Z4MtwZ9MS-ݜnLtS&6gWNn&;nfO[ҝ8K7r-mct#;;i#-VnI73y)qt;L;;2vI;4]jtLtgzZ5MS-ݚnMTKg{4]iNLtCE=S-ݣQTK7g3}.VLtzC]=)ݲg63[i6zftinF->۩^=3g/[i[|PG??SgMϺBeG=뚯hHӤt4Tٳ{5?t5k~8MgϚmMNusg]ÉnNi:[:ݲ!ٝOTKk4Uҽi*tMtWK ctGLJ3q+qt;LwK3m-qtC鎦M;;2H4eh!ѴqtCǽLJ3y)qt;ǽLI7søO>fh +4 zlx黟 [:zle25՛tꦡJdfٳ:djբ3۳Yŧu͌iFwc]!-kHQ-Emh)g]sVTO=뚣"4]2Y׼TeϚWVS=kY]uk:4Ѻ4Ѻ5{4[4Q44Ѻ4Ѻ5Ѻ4Ѻ3Ѻ4Ѻ4Ѻ4Ѻ4Ѻ45Ѻ4Ѻ4>=Uuww&Zwwz&Zw{&Zw{&Zw{&Rww&Jwo&Jwg&Zwgz&CwoZ&Cw{Z&Kw&Zwz&ZvkZEkRekB 4F8h(=k=GiDӬ;{=GLd8NfkZ[Fsz[VwzeM3w-kfqeM3+-kQEk)g]sUTW=34Y׼UEϚUf[U=kW4k~diiTiT6i2U4M;?|tMtMtM4M4MLtM4M4Mݞbwwgzjh jhjhjH jh hjh( jh -h=jh}ٍjiJUi*խ}FDe~j(M_MD+{wFj~ eg&5=)3-y>w1~Z~]0=}XhÚfW6#۳VDϺ殨"{4ge4ݴٓXFϚfKfcY=-f%iJf5f%U kxiT\1MeUZ߭i]U~X[wUM{s>#\=gg|#~ {2z34SӺfl=k=k85͖Y{4hDUٳyA=KMK=M-)5=)5M%4MٹwVqҾbs0RG{հNθQuP!9M*=#z>-XoϺff;5kYLӺfCT_4U;ۺ^d9{8޵f5ّk5M;MզLY#*z3*zRYWT9sVQM<ؓs5d_oߥYk~U\Ѵڋi򩗬L|fFLkj.eMshY1rϺ{4g05Q}4RgpEDOG3:zɔ=&S9@d>jh4Q6]5\1Jw-Dl{>-o˚f%6+5y״VקuMZ4Y\ٴLϑ,Y=o]_{l3w4\ݖVѕti*G{4hZ׌$̦uGlOd9M#iVݝݝў՞4DѺ&Zd{WѺ&=khwz۲5uMΦ!Su0̊4͊jL4M4Mo6V+33|߂Uh6kVڴYߞ55i2dtcMMpѝ4h"5#hOӌi]);]3("4ݢ3232giVSٳўYYwӺftWz4343+32+3P{`EG Ozf=kٽifeM35lz449Ҵv;M34H5U"3jOϬJϬHٚxjc%Š̊̊ =;~:~]0;M=kihBnH&7(ants-1.9.2+svn680.dfsg/Examples/Data/chalf.nii.gz000066400000000000000000000060141147325206600213050ustar00rootroot00000000000000Jchalf.nii T%SW# u 5F,*bE Ȣ(8֊XTH5V1MI$D\Z65t:0C3:wfqn5yXcOgi[r^aUI{LG~﵇+Gs$%!B!B!B!B!B!B!B!B!B!B7ֶ?]aYZr/8՟T}C@FA95xojS}ɳԨu1.fjCS7ԥ_ks گꉵ/jIu=P.8SOWysD$-A<&vDTY}?:ǦJHXdEϸcyQҺv@ 'ܐ˵Xۨek;-Q vAeI`q;FvE$SeyML13Ti=6ѐrA> y!7rr<3nxa"N %/uIcSW=J0>< AN Cvk:<;Ћ5`k4a_r7R6v[s~kbܽx0ّ1\m*b /0i_@C ꚝk^ ҴIl_ܗ'm19:5\[ө1Z#'ɢFUvڝ_HWwzG(ӭ[ev69<:l׶Ѳ%<)t v s"->0=.:0:R6D[.8:~=@,>BlsI1b^qu"fa黺5dA6e1Tq2cݍb XGwNe< HZ>ڠ-qv5X<xt6TF4 /tUWMyԫJb`k%A)k si7wZ>h*Wڠ-qvzUt&EV,~>2}d`<X ^og_$7yh䣑ݨsI+F.甫kxmX'~Yσ%Ɇ#e A/U%#D<kKe$񉡛bȚ͠~u4 L.ooͳ~Lyrux 1FElES뺸3Y[ӻ&O=ZS_Ug?. uޒZQz?uC_5yn긬A:vmqu DcaL{bxm/L#I@{d#osma|r෈5>#>Ze?j b.}yn݋c @}2Q}qFc`,!dySږxI'{>k|2ϩPCz7&9g+:Y)IqԻ^ڪPdjMGHvODcaL  d[ka5KbuD|6픃{_Z>kX~ 4~ ̎;G(ϊ4RK_S!6T{18[yTgS`Y6iʽuQaYsqar_δ3uʹ`]+}}؃2YZ?8 U~ϵ}zSjhuryPYg})s ' g^[e=!օb_U:ۚi7^N9Āpi3lGzKݒ>ǿt =C{D s4vl_{]F:F|/|ZW:K5S^rxgyܐEPPd^F; rx[__o 7Vq"׆<.V?Amt^ un*n^\fL_-?D;AM[k6w :Z=>B/S諫?qys[t)e:'4^E 9';"f3es[d^aY@8g gqq}'̃}ǫi:_ZHâd2+5U 9|Ss oB;M9IV4e=g/~cdi(}d&ۦs$X}z'*/HlS]nnsVlv$$INƓ9YgR:?ЭevE}g_:\*ĂF :9=g:\:pb[w!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!B!BT {`ants-1.9.2+svn680.dfsg/Examples/Data/ford.jpg000066400000000000000000000157731147325206600205600ustar00rootroot00000000000000JFIFC    $.' ",#(7),01444'9=82<.342 , }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz?(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((({x$$?8]}5P/m yԭ ԭs]H5,m?JvJ$n29QEQEQEQEQEQEQEQEQEQE! ;~>崂IWAujugbIncޝMeɫ]HKAA jer3⫵)G\-][mUYnSW 0 -/nT؟iV"/px3>)-RRmkX|FчM$|<:;5kv `Qf7XxS_\u lq^] FC}HUf,QQ؃} ]|l'F#pe`\'MUЊZ@wsAƻFU!ɸ?5EQEQEQEQEQEQEQEfk:[y c+2"-OC!=U; nQՈQHע(Q }-YSÖqo{#^=0kH+-\}kX$w+5$W[7u@u2`ys]_Fڋ7mdzuһ/|n]'ft֝v+YB-w} 6A:/8 jCܺl{?ZkH7Lb}) {SvR4?ނ&y-VG4du&LojR?sjcHzms ^"]BrPk5CU#b\Jdyd`c|YnC6 |r?Ji& x BO~yt0 D l|_϶i{?; LE2;c q2IJC$#*M]|OPSҽ4%fidر9QEQEQEQQM2Ĥ=zJ5oHQ2ָ=O `go%$5\c:ay{"~,“|So4lt2/#*Zc8'R𨦙*as74g~u6e)f3yM'OP7[,wrMh+L8ڤJEOdbӆM5Dm,Q֪%ó 7cfZv#tq?WHF;ps2Ӗ1%1]H=lS&;Xy[$J5NKi9c``?}aoEm/(~(((ܭ3xK~%3mgLho><,L͎ jQ"FR3TIuE.+|CqHm8ҳP?ƧXa@X}ʡ[J< D:c] DJF}Q+q끚x)7?&1e9!{Ni<\ <]i{C\mrY)CqܑԟnX}g4--4}Nُk~[f}SL5R$'BGz;dL$$싱xCcU -cBRAVRZ^Ϧ\C?J,׊ >T\U.#$'MPh`]j^0la{o,nQEQEQE5:=Yk$WsX_jper4yĜI9o VnGSƳ, 'WG*Zv)/mƩ:W)= n:tK=%&- 嶒Fx;WZ̭0[GQ?Wtٴ,nYk[+>n$t>{UƑĠ zUA9vTxJ/8?A\33$LݐH<.bqkX>յGAOpbsIiq!}Ѳ_KƁyZY du5".:ZZ6ڄz4.gYpz&p{C{{nR$[}6#5*|5%ZSfF#K;q=:XXIKֺKvڟq-3]YRvPeO0?/]EQEQEQEG,1N&$OVE׃3{s*V=Y'k*_\=W4ohhdewn'W^-Uvqދ؀ v,v2RoՌ0xd;=XyWnYkVw-K[}qؐz?㸓Au̐"Z4Nɺ *Y?dizr+H{}ȗ9W/4 &HGVu#iP4^}.( 3{V'eKǞ#omy<(6cVANpkI}Ol (:0?Ce~~//ҏ?Թ:Abs.њ_Z$Ǽ/-kxJw-[~T򧏊P~,~Y_ʛ k@^$ ҹ-crQyeHM3qӵS}de)*!#8kTy-t%^F3p1ƒַX!5o #-N>#Ͼ2׳Cg#0~FO(j[j?q*9(((FPdU) [!2xGEZS֍9.ģ涘}$Vt|pr*< NEƮKVrϩq|_v;VW'פw_S' 'H?Z ֣K cXM?ãjw+a/֥u/֦1 ?ԃῇ? ET"~lUO>IH:3?k~2 c}Ո1rCZ. *QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEants-1.9.2+svn680.dfsg/Examples/Data/functional.nii000066400000000000000000026251501147325206600217650ustar00rootroot00000000000000\rE25 ?@@@@@@C??@@@@@@@@@@@@@@@@n+1doֿ{# zI[`B[*(ÿˆI jP:9)G6S!Լ>:?az?t>n\c U%?ܞ=,M>&?7\,>UW¾nY9et>}R<> m?'?DƅuTsӾ`0+>/?j(=ƾYȧQ>Οk??Ne?Kv>=NLD?1k?vU? m?6W!&?։?yw3bS30 WZC?GZr\h)8ܽU >nu?6?,?|fN* ,t>K? ?'>ǺJtN? ?@.nӔij.x?5?ŠP=^Zt!hqf M??ļ?3??'/+ @4N@' @9@V?_'???6g!?2zAe>e? ']eb0 >>k\?v?I @C芿ƒH:(/Dv:FK聻=2?@Q>h3km ܿĿXNjS!|p\ sF=*; ;7&Oacؾ/MD87⿯gҿX!y@C>;?~??8t>o.,^*/4'nſ ɿVI!l>@ @?Q0?Z+@wW^xM--?9?Y¿àvsohAa>?@p?X3aCv{*w^$\xa?&=?I?0_?rzBq"k??4/?]^3ivm9MU6ݦJh>%yU>݁ =&>?1?Ga?cj?K=1:xS࿬+V$D;?@?!?@Pukt:襐)$1>.?oG??m?}V? ?V#x쿿O6??6”> @H5?YMܿ-PWzi<.F?i?z#=j*,?JY36[=?BQ?n>i"%"w6~|?O>TN4??|?_?ك>?Y B;`>h_=0??g@(?~=͕?󗌿f?0@f !@mjF>?ư %:D>ʿn'@>ƽx~:i n5$|%N=@H>7r)],يJ]ƿ)G eO뾨??^7?|<ΝU PS%}IR?3>ݾZ=6 ?f?@Aտ?冿Wsҿ.B<X愽5?s>>|=>'> 1sd?@F@7?; 4qݿ'L7@N[>?l?w?̃$U翊> c@T'@\+?Z˿-ѿC 9[ 'Ϳ!1"w$/32?wʽ =Xvu͓pj-0@\@Tտ"X>X># ta9" <-w8bn`H7yJ&#-4@Z?>mV7UiտZ *jG'. ;} 0ێ@*Ln-?Ƽlu鿄S ,2M?&2.2ӿ̲L<¿?|x>E#=@1K!Y5"I<쿯׿0⿫@F@!X̿_ÿ_R={>5̂?B>BүA׿W W!Yy}ӿ9V3bF@.-s·?^xl( ^:޿]ᅿL Կ$Nit>v??!e?=bÖ>SXBO,1o>{|̿S'ſD˿av,;`6迒lL>S3??)?g/>=>۴ $߿ˏgC|'6=TD]Aafg.؄7HV+?Q?X.> ?a>_?X? j>6??D*>aQMnѿ ny>4l<)M܊]n&Yuf 4󍿎Z>K? D?&<Ҝ>eY? Oa?=p` z ْ3 * pxh?{x@?gy?6=/;ҿ `Ӹ&&?v]?^|N.??Jm޿/sv4oľ?iYPYt??N͸?l? >RGTUx?׶?ZM=>+?_U >ύ??u;@á@&???!^;@?]5?I¿[пE@?j!?b?P? G?ʍ>ؤ?YY?ͩ @ӎj@Z@4(@(@?LK? U??>j?Hǿ)6~,N]*$L3UHc*݂+>)ɿSqVˆ"zD3Y誡.?t?V ѿؽq]K|#[}8Ǖ﴿8`=td?O`?+[l<σ.N2>ys 7@zAcڤM8Կ'$p.>=C%̾=?i@k??7>)@#@7?G=JlIK`D0F>r{=YL >!c7.Q?R)@?NM?RS@))@&vd?==;?߿\Nd˭* g7eƾ"EҾ ҾU7N^%Y9 %FI?88??4|?k@9??,0eK@V@?f7]<KE&}<"j!E?p?e>Ǿx?U?j9??;@Nt@:?Cf}#TGv3.P }SDK4OWUd<ް?jR?!{꿚|ʉ`?? Ou?a?? ]x3լ["Կz )Dٿ:Yצ*!D^ { uzљ zN?j>Ɣ>'HUտg<ҿ:󿰒#EEϴ5ᄎ¿h~DeXnv䐿q w//!)P/efϰ>c9?\>If=Ze>ISd޿(c&߾cߤ'ArݝmK>"s*R?\ =VU˾oqVؾD7Gп\Rrz>*;??d> ,?S\1FQ&ȿW@w-?⺮A1οV¿J鏿_Ծ~N_w48T)-(c}> ? ?E|??q{?-u?#J!}7Ӷ*? P>IϿzٹϭ QR3d^"M<4G?AŽ?g?HJZ>.> E?A#?7?1>lsrW"3%HMg2['t$"ٿ64r,%I8> AB8h=?]|M"?\ZU魟?0?#~0`w!'?f0?x5>>y,q??]?X닿h d\WT &hEd=]x&r3?2n?0s&+Hہ>L5?C= /?C?sS?:I?c?G?!q??8h?`+?L?vBTx⿱|xΊTtw->iK??W>X ?6/w???Q??= QM)]-?@w@}憿A-?$?J?'?\.?p??7???#-?V?s?9@wh@s>ɗfĿ$cǿ߆?\H?+j53?Z?l>^?0@I./@?^??@6@!@?cD?f%?C=Mr>>&?P@;@v`@-b@a@ @@??f?d?D-T2#N\fA,y0|)Wi'eZ{\PM̏K; uB }?yv4V6SxLDq3N9d-)4DLĿo=N?X?#>g(c`'/&4Yn\ >e?=VHL^v ʖ¿٤{Q[ɿU|뽥uI ?ֲ*?f?z>=ɍ>]Ԟ><7>`??ln >YFžP=VE(Y$Çf}^+n]8?p*?2rS5?vq$?Fz//ݿE?vts>⤑?|@5@<)@? >">дEK\迁KDN4zQ心A<3nG3rUݿcD@1+p?z/U??u[@@<r@ :@?RJ?ԧ ? ?״S2EK*_(2?Oo(>_1'ø}! .*+%v~-Bp> D?:?@и@T?Ӯ?d?;%8@k-Ӽ*uȿw:+N@d!J<ǿUſЖ 9#?l@?M? t;,T???8@?:?n>Rֿ61+t "ὸN>y~=$_ǿ*οX[u< >:T?u?mЛ??Srļi6ᑟ1?ś?q?|?M.翱  T."B6ʡrпm̿ H˿& >m><>ⁿCm2rqhѿ_?G)놿WU R6"ѿL]/=˿3=2L$[a "Ŀ [> >+\SD2ȿ[ppZ=Ϭ8?sѽsΓq"ϿsοtuV)W+W|Tʿ `߿|ѿҰѿM2Un XGZ(=5w=>׿S 8e@⨾Q!>h XZ iك >rn~ÿǿHѿ K_vF_=x|)?VE>?~:>5-⾸Xs<Ҷ>>B9?>ݍ>._1&￵" wԪg{:>^PJI^O鿜bU `o9W&'(ƿ#>뾆.>N0=z۝Q=>N(>Kw>|3>+Q?>%Yc X[¾A8[ǿ0<ıLՊeH"п%UL6X" ѿw#nK>Ľ۴ ԌIkNm=`cFIY?25?,=\Zx<߿t> g.S9ҿ ޿+[N`($? B?!#<6?x8?mXr$s0ժ$&/Xx>MaQ#fnk ߿1ʨAfccȨ̿c~l=GS>;$?G/>??@%@L ?"???R">x'-ޠ^ÿBp4$WiCY?F~>󽖬IN;xrUʺ#:=py?3??@95@C. @? X?QVj?'?>КEOjO7|߾NÌb=T\?3>Q?? ?@ ,ʷc??.a??G?`@V@j:<3>c~?K?3$@#?;[Uoqn'ݿ, uȿЧ9c|-ʾX?F=!y?Q>=R+`zz>r?3?@(?)C@TW@@a?, 5.T*?ہ?ڥ?J ? ??E? ‰$h??P>_Pc#SǾV%??.Z?I?H?BԿՙο@ѿe*!>d?Y@MP?KF>ޕ? ??+ޡ>^%$d?`ҳ?5&?id?m?b+]0*?ξnU1$<)Iہ8>'s>Y?9??]kG98< b-$ ;?;$>Ŷ?@@A@@iX()@j?aFϾ?c?tQq^Hwྐ?c?sA`ɜ|8ཿKiME3?@8@\"@@x0)YRW3$jaJ|? 4?o??<,@~+?gNTR#+lV'Qm臿0sIWb!翪m0!ZٿBRݿw̪K;S.?zS>}b[0>xǀ???=+@?@ۊݿ¿Q.>wU>Cr>],_bbN &=,T$ Tտ昿FV3>ÿ&/v>4?z@>>?I??my? '>2>YE>M?>fR暿ΏN>F2:?o#b> b&A )PS=&?]>>U?r>M?80@?)ѿyüӭ1>N,\>4 Dq !ҵk>c?2\ɨ? Q?$ L~CTk>m8?>t|3JڿG?:@?0_ӿ2S}uo>n?A9ቿlz,{Wt˿5\x?Ju>>gv<zO俰]IV޾>A>i <Hfgþ>*?6?-G?{qw? %>tG?>??{߶9]*'/L 򌾥H:%13 ~钿e4>o6?Y.8H 9MG׽Sr? >cÖ6f<Y:>+??g|?y8!%G!C:YIg+߿u ƿL׆ق>d|>-p="Rɿc;(?{ڎ?1Jľ" m?8?&=Їr 1iC+B^>cP>&.沾&"ݿv;X duc޽:Y<T{J1ٿΗa> W?5(3ܟo2Ubia ꂉ<1пt7d6>p l3nb WĿ Ui:foBh!ib=>e=/ΐ`;g%{Y|,v".6=Xy=:՛?y 90n&@ؿb^VxvLX'*%>А>#>I!wPb߿YEv88ƿͿ ҿNi"C?;נ?q=yi#?*޿ErbR 5CV Nx>xt>'r ?T?"?;? '?'>i)e7Z-tl>Ub,*,]ӿM RN$?Zp>i `#,1d}3`JVX=-g?>?@?!!?1>? ?c??{?-7?w>R<nt +~ڿ?4S>}>??kf>L*4ؿ7"bu!"Ͽr?=?Kph??I@  ?Y(>_@?4??n?d˿UP -M߿(~,G)Wʝ>3>Y~>m&?2? 0BL5I ̨Q<_?P> e>y=QbEf~????>[>۳x06-⧿ZΛ>3,ǿOǗh]4rĿ٣P>v>ԭ?rE**?5>= 7jb??U-?=??q?> >?YRP^}_6>T\?宂?LZM"o???kU?>=/@>&?Ҫ@[h<?%??p9?dTgl 쿢?HX??x?cп[<ϔ?C5@ @H???C2>?;?4:wɿIET=Jʿ)#⏑?1@+!z?M?j?X)}gn]>N =?A]:пA݁>?7%r(&#Z5D Dп}߰͟m3Kԫ>Y ܾ?JH??9M::Nr)k?wIHXp%Wuj Wvl7yc>,?ɘ>P&ҾYd>Xc?`>U|FGdӼ>]#â7o}ӾX9>>?Pi?ֿ> ?bsU?i>j6F^sS,(.t5(󾯈PP`c .U>=?3?U?? *?fDe5_VsGBϿN>e׾"3H>eGh)?'?u]A.J3?hhzsſA9)=;˾ k鿾+TK9ӿe)F ?Px?}? @V @YɆ[ƿ}:Q?PD8>*?&>z|?(ͽ࿍"<ʊ"qq lw`C# ֻj"J>_&? @E @?)67o;ƁZij?8 ?" ྙi?P?8?N5X˧+ $yM#"9].x|&Կj6\>?74?ZD?>?V5?庿?3N⿛l/I?@"0n?~pS*>1 >3'PLN0xDe,\K??P> iWɾM?r?j?9?j?Q?Y>.ͣJ!Kmg>?(eyuhF[y=7>ٓڧ>:>njYM?W?l?ڎ%?w@?7谿l莿P!? ;<_<Uʿ !/[Xu?|:>+pGl>>õ;_=S>Mdp ?=B뿐T:?qi!?M?r?;[%I4?Y8@T @P=0㾾^>Qg >=ׅB*lm:o'u>ivh<ľ?m>#⏾࡜hſCKV*H ߻\@Q?j>䎿]>?c@ ??]\ſZpwZ??K6J.Bzl,a'?{? *KN m!̿]>oS=tE>@?;&Nt#zlxLjX +e?q?M!"&u=@f? a8qֿĢ"sn?|X ?>v5l?x91=ȾIQFkn߿* z.ށ{}??п(>6򿅥<Yտ ݾo=M@1^=~h> 44}0t?]?[?F|RxGĿQk` lG1U] ?Zh>ϾUn =ڿd=P?pSϿ*6Z-?>U? "ľ/Q=.Ŀ pQ@ڞThkӽדN? /YO鿾&Fؿ->SRM߾-F 4?]F?~ٿ =>>n!?(k'\*;-qfZz#3eT`o,Uz?6BǾ$j"\\(?tYTclm :U"I'yr'wEd{(Ed\G| Ȉ>UM?>\7L*:bM.=L?x>L&=:7>8ӉM\ʿ=ﹿk1\o濃vy nͿpan|LAr&)]$+:*!ݾ31>)-~|>|?˔?>>,y>?LV>}<>gqGBk$>0<'!d _ݿhbO<@ x3˿-˾ݿ㬿SvAEZĿOb>P?u[>]?}>kN=<5 濨~F߆Is$>0X<MϿ^̂_y-O9 )Ӿ7OX 2}҂ v*n^5?!?A0>0:?ګ?N z?Ϊ?j)?K@72 ?3eԄ ԎF6Z,WV'*U0&1ҿ^Q =^;"N5xu5? ?v^?T?6OQ`a GR'D>>p?ބ],̼Po^=?I?g?Hѣ@ǿD׵l>BL[*/-2wx);} +C%IP/b(2 U?h?@aS?i7.sdQտ`*HL3Pxٿ^2 +*k;憿̾y g)GQz>nxwn>j_?=c?O>GI3䥦a < r=M=:'8>I ?:E?K?q>O%q߿LU4>E??Ѫ?տjh OGYO=s)??)N>qN?d>L?~sZ?*?>hлe=?Ai?MUa:>"&4>w?N;J3>*ߧqAz??->$ÿœٽ[7yV>Z+b?1?Q?@5? ?@je|?_<߾ 쿙{av$ƽ~P?K?XՈ?l?8>F3 5qP=E?h?R@Z?m?at?r>{~D?TQ=,(_t >D8?CڿIE">?!?"?غ=.K^"sD~s@ÿr ׿l]뾊t >g >$^>?yͿָF???hK?,;?E?4?f -Ч;>5;棿w?r>mL+?e>m> ??>?|ؿM$eӿVe5LȽqEC0??⾒t gdPY\P>? æjM>lJʹ$???gMg?ݿ #ƽy -r 94AԿfv%;ȵ>4F?nktI%`> V?>eJ5 OV3?:?c???b=9$vkƿ!L(mzOMs@ ?t>@ھ6N>Cty̿+ӿӲ&l"@3r߿ӗQ)?a!?V?ܶ?F?O- 7 ?7=LMѤQ;ɋ>\" ؛Ӕ>?=@_=TQ?Z?>(ɾVtζA7-PNW| 0;Q~{p^?V?C???7>?7Ȥ˿t**<<>?-?x@?ƍؾ1UdHlȿ`c\2=˽8Ͽy0> #=5vd?{,?<.>y?fC4:5/HqOljU&:|>?y8><QLyȾ`??z?ކ?,?p?,"?x.Ol<.)T]h4Wh }#7[iR>>&Ҧ`>?S9+-{i?o>ebꌾRͿ٥<O꾛DŽf1?7?7s>~>D ? R? >¨?@.@"@@P1?᱾򗼾>i>5*eAo=`8q?4?x@>B&l>=>cb@֕~#}>?}?,)? %;rڿP>?4(><(>J8? ?Tau?z?Y?[==>@>?o@A?#?CQ^ːv>=?.@8{V1+?W??*!>ǾU#nN9?%%]w#%",m ?= >kп8r'½-?ʽ1b3+۾kjF˴V#bA? ?Gة=-s?e@=~?ێ)W=md?.?HE>hC?x ?Vc;YyI^?rC?rH[SG-1qr=Pܿ:"rJ>rz!-W>&RW?,?'ptǿ)]0&(`ҹWG)Y;>EۿN ; K43Dʿuqd迕߿kd"Dh87~=ٳeп֝#3Ucr?*"?>8rhomܲI(MmX&x&t>4JDAqǿzƾ KDU2AZF~@!‚ 7Ͼɐ>?Cj*@ָ?codjr"ÿtԽf@o*?Ҏm'OqI!վגjƿ8EC9W.thξ%ㆿȿDFOՃ80Ŀ=ҿ6c.I=1??o5"INM9JW!\\ѿ1#I->s*> ێgc ` s^\ƿƫlT>'Aǿpپb]ϼ߇,>mw2*wzn"<#`)ǿzJÜȿ@xxC+ϿaȿrܿQտ<"S̿t*Pb&AfD+O̩vQн=C/?L hn>]??UL/Cټ̹̾GB?U j9wϿDž$]ȏiRԿ@(¿xQ=Ϳ+ů,>M{?`>H!Q=??UaG=}ȿ8"g>f ]Q˸@$ k}ѿ ' Zڿ?=vīZ3#͵ÿL˿l]M|ⴿL鴲؏>ujh>t?lf?[?T?%@u3?LϿVI0T>r(6롿:U濸*09Qiݾ=8E ?ξk8I HaZN?ˣ>!?"G?x=7Iʿ(4 WaO~'7J=kj m/@??1@?ݽѩ} TIXO2*l-aWB@\ 4UY8l2$P}PH!?B??%? ߙXȶbҡ?gD &3<-Il[@C[Qz!;8>\=q %ֿ+,8L_x|E8>/\!z̿Ohj;N*|r2f?}C?h?8=볠[>r?a=K(sb??>vl>_;6?Rʑ>0"G>#z w=G?+nt?2>@ u KiL@L>[?( oe<py_C˿y.9d4ƾ. ??><˙Y?W?Б?:>KKf> z?6?<?k}@Wf?? ?O?g? cC8%?>ڕP[ۿ'K>i??Ȱ&3 >V]֗k'vۿdm>)i?Tɯ\?G >>1?=e>΄>j>E?'u?oU=8~>L-k˿tWH_m-pR ?=ɀ?X?5k?ډMo0lWQ\n8ʾ?>]h= ÿWhgʾ 0䔿P UslDý:t>2Ҿ‡<%2wݾPԾ,뾟?Ô?>CY5+[Sžᾴ%K???NQ>??$?⟔>^?d>,>?^ɼn>?i@L?|?t>FW\e>%*?}O?t)?b\ɾX>I:??g??c=D:K>p3\,gо샿Q>? 1?ye??'Bh?zǦ?kȇ>u>ڇ@ >@^?餿YjM}ʿXZO<_x*{+?2.d>S?՘ 0 ;k{/S-|0,灿UzbW)/?p*XU֐@Cw}>y?s?/c=y">6P?@>y^IWſ, ]؂Lҗ&ǣfgͼ4*=3YA??g >c)?c!G|W?>:6>ܩu>ٿ?H!?|ոvC { 8T9Qpc򙿝Y&>G>L pso^# G?t)%bc%ݣ>4j?a'?R?C?b> QZP>+?z?>̄ 0QفҽhF:>l&uC0={>4yj??Ne ?4?K ;eS8忿KM> 'mD M0=H`¿ 7̍>:?'{?q???r)? &JfAm?`*?Q.?;H¤RwFcQ;\A[OAnCWH#AJ/㯿=%AU肅B\?+u?>i>̚i?u?:2?SPqGϿ}gL.ꂽ#?Jj]?u??2.?R;#>O&ۿ.6tZUpԿ՚ Tsǿ}%C=MAt?]C?݉7˾?:-?lv5ʿݗ=ڛ?/???+h?kؿqUE ҿIĿC|CbdȾJۼ>z\a?;L>0s=H?v>,q"Ah dp7t?`?2?9?(A?Cl}@j|xM)CS=G 2$>[m? ?Ih>@KQ>=ۍj˳m? ?vS~zVDy=f>+N=z*0#yU 1ψL ]|kD%?e@??A?3??Oy?PےkBW/?KCe,}.w\??nL>ٿ岙 ˾(=w(?|? 㘓Q>9X~` P̦F>?4s>k/>&@ @W?*?x>47?;|?Sf?⃾[W,3z,C" &:Y`>ʶ?m^?\>ry?dC?D=K$?:?>{k_?>d? ?a^ JS :6S,5=5?-FLbw\?-6@???w?}?;>D+?=qsӾB<8S>e#2$߿O魿K ^??Wj?uI > +I}Lt&LD=x5>?5F?z?`3>c]I0C^+ԗ>ؾL c 弐?^.=fXe? v@}?߇?c@ @?E"пO\;X>??>_1p/=6>H|Ch?Ej?T>Ph==bC'ZIXM=?SX?Xd1ȑ*!AJh'/F=]?;.=gvR^>>%>' ???>tϿpֿN.2Y=U>9?g@?X?L>>A,9k;=RLH>Ct&mmEglĔX˿ ۿiT\6^6R}*`ގ>@bӢ>!JV?c>__dٿp|$G+G m5⿾Ͽ湿ﺿ3q[ OnC/q&G%PYț>o> rXy FfF8bIi#$qjh?MCH㣿Oc?I!Cݭ>Ԗ=N)I¿ŅjNt,{lM62ܿgޑ?wF?C>$xRQP>LFuۋV=>FM-uybRoBᕌ=*$HTo!ÿ7Jcj>yD_ד5">6 LDAۿ>??Mk<3UA\Ͳ T+z<΋?V L?`O%ִ p u4~q ¿؍ ӾhL˂x<>*1cakbI$WAެ<\< S? х=޿H\F ȿfڝ@O:>@?>=GⒾP+3YDVY SoDZD> v#?=fl ySY Ⱦ߾!$#:j!B- .=QφtgK'y(3Tf=i>tfMW>%}]O="#cп y^ߧTI/?™п--??F??l?=cH &Ӕ侉BӾ[[ҿuog5Kg}4LXSտW ﺜݒȽÐjY{}kgN5?63???N>\e'>.$]̿)2#Dq x!=t=kh8Ŀ IO俼̘:?t|6 n>ス(0+{e}ֿ|_1!þFU>32`9Xÿ[{> ?Ͽ?? =3ҿ$ >1 oB$?)>4<"ղ(H2$XǿH%Y.2i?>wܿr+Q3w?S?U?ā*?s} =9{C_|??N݈?c}>V)n?}?Z?z`>o>׺(>ͺ?Y>_￧bIÿb HY;?Z a\ ARv}qE>ƽ*= y> ?e@j?8#?9=0?C ?M+>X*?{???J??4'>QyFq?V,7@?PiB?C?hU?yv? n>AP)uC7Bgr>| AܲG޿ttJٿ,پ|@7G7KeRPt?7@D@N?O ?Tm?tֶ?a?T??^?*}??$@@lc?|?R@P@b>wž.9?:t?S5>迒 ſ%>>m?9??g$?򚹿Y~/V.jb lku'0_鮿o?& @u @~h?؞&}?t?4?]??[?3>@ ?֋OBe>=<2?y >Τ,?9v?p?p?>_퟾-EpE-!<;C= 2 *ԿG \?ND>c$Oо7.E6>ŝ>Op>=ٽZu?>d֫=&\`KQh]e4?>dL?ա?6a>6ڿkqHH祿w;t>>O˿D׿*[>7!%?)?0?U1QԾ]`H匿Z٨W??>Nh? ?D_4>Gѿg8#GmʁF?L?>F&_XL=w5J>d?G?a>?9S>ruU7EӽZdB?C~K?c?Qqk>N1E}޻?'~?B?VL?1?Mٿ`TM?(>, ???$V?P>MkF?@@k??t?6޿GN@}c>F??Ŋ??_?5Q?V/?V@?>?c @7?u%V2M7{)?E @f`\@G@G@N?M?Kt8=z?:/hy=.=Wi76!?V>ﴼ3>qf? 4uӾ+ 6U QSv;sL)Կ,/n.>_\??XU$[7ۿz>pXꝾ<>>d@=&?K>F Kҿou3hҜ>?@/ @s?$4˿ !]> ?{p>+,>/>>s>xk?? Yè謹c¿z/؏տ+^} ?c?C? q?>Xkj˾Nf.:[ 7_=㤄%mO8S_hx7A[!BTLުW~ v-οýH?]?F~oIԥgԱYu<ƶ'嗿=2M ԎGĿWܿ)M xɾ+#ο-QG 3G ڰɿ4ǫwcGL*QS*UȾO1H_ݿ Rz_S|jxj$ƿcT"ͽDei4m*Ѫ^߾:Y>ֿP| J [ok'6S?R>c*v ct8ωpFc>胿нC;?I̭s线@пI=>&?vw3i`nW=YZ?%QNֿw'ſ߿")rI.?oYFD>,AH=RԔ'>YjkQ=u?;#?s|>K)> K5\67<[La+ɿpK6& x=ֿcپQ߾Ii>?ξI?+V?qY3dݾqzƌ^|* #>^$ƇO?1?7ޑ?Nu>FҸ>2ʿ*7 =0&= 6Mt??|lo=o=Ń^͛'HXrὙ)>3?~cr9H? ?P?Uu>o4/?'<>??L>#Є\\@>m??$|"ߤ`I8{>~ϥ>+)aJd?ʇ?땿Q罡u?Z5?-Fr?67+J*?^ ?yN?(lY^,=VL?N@@刾YD?}H?Ƶ> ]hǾ=54&|V μ;q-ꜿEp/|U=oU>5=yC}&R=ee_~(K,P9< }B??{?lO:$Q*yR2So4T7l?d">oZ=4'>,e?z?w?ч?k?@Oľ=&.B^3h\?{O #>c; Gλ_? *?ƹ?*??؂?T> ?PA? 6\TZ?(<(s<۴|!":l.п8x[??V-?! J=#?0?? ~}>*6;>S׿04'Dki?DgI#ǿ>l#{}Y?Ռ?`??e#@8@\?+=>U=h}/pP>*>ڐ>^n {VR=J?>wF=Nղ?C>؄eF6D >n@??ej򾹻%=ĿH %Lm#]8¿j}),1?(>oG>?Q(@?:I?lˑϿ4Kf56I#N3A̾6~ үž<6>VSP?9;@tД?DdR?5_V>lj?&?=??cL>؉ҹ>??0BJ@WIJOPBWer59;?@ݫ?s=T?9>b,(Mտ [пށ!]o>I>j"8}=Ӄ??>N ??R?(X>C 3OOjjXYٽ9>d.9P-`>֜?@T;?n~S~jYĎھR^̟ɔʿ}ծhc DAGxo4X[_v>:?(?%? ݱ=s8}57-?ݠ?gv꾆RICATzvW_#֥m~E?%K>#4U?i]?_?>w\/*^k>uxVfE e0@k#E ھ\>!&?w?&[̾Lξ#jNx _t>~ +! f]t[0bb}rn???F>g>g(> i䰾>_ ]t~KOg-@{3 d׿p 0+>m%? [?Ӏ?KѾȨ\0}IȿwAۃ>ʆ@&F=xݝ?k䅾տ(6ZW$\kZ>n?q?u?w?E]BNW%I#ylk={a^xGB{8ç&?E>?h?3?e?*/Q?スgfվ>>p>>w0=o_q)OL9=%h=M"iN;]I?|v3ڿNƿ.G5?v)?vb,񔀿Gu m@?j㕽6( ?|@&@?g=H??b?%ח=T,'>=PLjpܿLvn14?mJgܿy-z dKA?_>B?>-羱~F(Yd߽ݽ'/Ŭ?!/ @[J?8;=i:Si}ZI\C??`?ĿS/ҿ ѿVEk*྿L&AEJ9տ8nk>>\?qڬY'e>^eVsz|G w??؇>NcȿO?f>: z>x^[#A62yR<j4H?6 ?б>>mjvX:n7j?e?S@?K?Jy?*ܒ?@K?}@aߋ:,g.>!?g?{?X^m?AI=.h ).`޿.Z"wG+??k゚=gpH??ߘ?a>?j>JŻ?-?\?p?ᡠ??m-?t.?PvЗ5?n>F??Nj ? X>CN،>ƒ?ylr?GN"@ͺ}<7>u}VX^rmS6nؿ13x0h<ϑ???Kh?=?A?&?^=?2}]?C?? ?}X.? ??@ӹ?X?#b-?ߴmn>wc?B@R@=Tx!>tY? ?]6t?/?Bn91͐ЯOuɿ b]ZE>?2>꽾wI??l@)@$`?U@@?q8?n>J)>?B> ???"֋?+?i2?_>b>d'E? ??=B @>Dӛ?8klʌ^ I6V?oCV!?fO?(@TO@L?"?.?{T==3d=ǩ=Y">H_a`G?L|?}C?(?̭L :Zwp=l" JV v0?{>KT?&2?%?">tоӽ>2J}}=-M=?o=Rg& w0+8<ܿ?M̿0+1 ?4ĥ?V+?%r+ԯ&r> Lw?. ?[>ȼž ٿ8+b>fe?_?4?>Z?ץ>bW+_gFIǿ9 ף>~ #?x̫?w?#>`ȿr2F;>Ay=O?Ѿ?"Ė?-S?ֿsc Ktf{=0z?j??c?⾐pè4>9=d??`ϋ? ?]>)@mO)@ v?y@7@׶?`o/>] *;=?&Y??v?=>o ?MJ?;h?I??+6@?|7?$N?%'?D\?3?g?J_?P?S?K?/2"0.<->V?Fa8@?;?\@P @ ?o?PD??@@Ɂ˿.KYϿXË>?D?"?@?#>5?Dh̿ROĿ?I?1?s=z)?N8?>!P>j(=oQy/.a>G^?mycPF:ҥ7LtE?D??e9p"7\οK^ۿ,j"j > ѿk῝OA xT=8^T<=#f?&?O@@>EJ,#п()D?>6)ݤyڿ?ԿFǿKs\ -ٿ6=sz\@" ?w??@?.ĿQa:?u >yu"58\P"2>Ӄâcտ#A)쿜9>vI>w sQ?˰?R$?s>ޡ3Dr^ -"No<0k씿M.mNmB?ώ.ϿƑJFxֿ(yy=jT>'?fAOp&<E= #꽛нÄ F!npvݿʿ˿Ϳ]Cǿ\|[>B4̩6܃rcڿc:לk=U>`> ?Oa?~^=곿ѿHymu[ΔkqR^+dZሿW=_ϔ¿_ÿϿ9*`\"ϖ槿͍̀ fTR; LB>t+?~??e)?&k ſP``ٱ&׾k"jQF2 \1km ؿ84 $ſ{|ο5ی0qĤp8>)ÿ #>>>60>J>S >ĩýоjtF޿1-1ZLҿjM1_ѽ$0ۿSzP T: Y#68gѿMоl>'T> >hee>@m>sE[?ϲǾ˪?c>𛿥Tÿ즿Zվ9}ݾVr>j7Yм m=ž ֚VAr$!57B@?  ~r gR-꥽??׽Ͽow?8>6AT6Q>װ֔e?g@ @ю?8XM9?~s?aU?`N&о \ޕƿʿR˾@o=( A4cG]>>];>K=|_ >Z0fO/6?cbn?3*>,cX7'~JǏ?Lݽ?&?"#@??Fsn,>Gɾ.=: Ҽ)'+g<nѿ&VҾj?>n>}l?!>Z>.0Q{zB:Jp:ʿ"tھ^TFb^WB>y>|)k>z@(d@ƪ?jt>QwG$4 @Q^j??75?ũ?>7>B">l- ٿ->;¿eݾ|ڿܿ? ,᏿Ӵ rD??EH?FC?@ҫ? z>77'̿f>Z>}?`68> ΁>t>-? >T?&r"?S ,Q˿n@;D>46]?>] ?/&?m!?4Q?~vDۘ2ۿ+:?+dpK[4/s<>J,??d.@qZ??v?7?s+?Dz>@,$0ԿX%i !Q>?d?Aҿ? ?n=&<<>q>#(ƚa>[ԟN*ikzZ::` =}׾#ֿ=¾|οCu3>)?3rm=?/??@5?{?Xǁe__@?>?>!k_:NU19Wm Efe)?u??W?6yq?G QXh}rAh4m $Շ?䭿-[4 A=v?Xt>} V?Ae?G>ʄFOþ6Ώ]NƘ޿߿W:yFi?dֳ NR??'>#Ѵ??QX>x>R2?_ ?B??^+ :1wg$7Hyٳ!>2#ӽK=D0?F?~כ=ިʳ^֏"ު(<_)ÿMs˽3=ÿfM9Y=T߿QNMo ;ں$1 }\#?1]*wI-TnO*B߃fsT?E?Ƿ >|>G?b?P ?} C<{禾5[?盽 pQ5MHCȿ.@Ig. ?] G>A־ rd#>(k>*?e?RfȾ 0 \ 5Iq>y?ꩽz/dr5fډba޶ԧ3/6?r>?=??w> È?z?8=.']Ͽ  J ߇/`=̂v>A?7?>tC#"}g4??#函n5Ͽ\7?@,0?in.{i{kW+>*\R?5ӣ?:Rn?fr?eM||V_kh'o>)f?p8 rQ=:GU=`6;X^WolxmW??:'렿#ӿޘkʾ~>MxX=lPS=B?@X @w?x"%=!>?]`6?~??U?7ڲ ,ikƜRɔ Lе'V ܓL\@ee> =d뾈>Ϳ@l>{??> ?1>(]h{{g̾J*Կ25??}?s?ʬwdOvɿ$˿UoÿSU *b`t" ݾ{s0G+T?e,"ݿ tx4I{aQ*4]\dje|{v=ى%?ޤ>O'L5l˯7Scֿeڻx?пѿn/_Ϳ-;v>/>Uͽ iX.]t]4??w+|G4"/;?c?fοi_4>)8?oD>K=G1Q+>?\g8￑ AsZIE -$,{=(' @ ,ˎBgV(F>0e>T܌tʿп>X?w>D2fvƾ\њ=T?L@p=?=&ֿ(y;Z= <¿1y[%??.?xk3?"TVwc!?"@)?$+WOP"0(ޙd_>'C>6A((;9:ʿ^ϬPo>*H>\:=,Lտz>)9.>О? ?w3c?#$@h5@PO7/}wd OIW=پ}6W0<\щ=>>&Vq0 [-?xw> ? @A=4679>?B??/ί?&? ?>"?T>7p>˾\}?gwBo<@XG\@H%@0?` _qH>>+))7w妾g? 5?3%Q#?~sN 2>?/m@{@????T4?N,<(JcZ}?S@?j *?>:EN@ҿ8&8'?%?BG ެn3??9?F?~<??@?5U8 (¿ ? l@+* Y? ׾=c_>p??~U%}r*>K?ƛ?x8? yM̽wh>)?bH?Z?b??iS?I>&k+>6N>?ݡ>H 6iWrq?T#@N?d&?}9>A]앾}?a?O?Ad?( @%?iz?:&??ʳ??2GRZpwaXv?Y(@@Q ?>ds1(徜1>8>-=C ?@>??>«?>#??eN31Шf?e?^?B>P%?/?,?h>,>{Bc?g???]?%?[>h ?z-?@UMxL%ӿd pڗ>^?{?N>=*?eb?\??S?D?57@(j?ƴ@g?q?ez9-?[>|A1W:ݿ%ZU&$/g?X>?E?6?Z?$W@KWQ@\2@^&@ @?%W?pP+?laPɿ''(係X=< +䄂>}Q(׆?'@[C@̶5@d??1]?_Hy#Aa>â>T>h zU???R?\?!J>2|y*?0?K>j?=GmDڿ1{#p@(ofZ.j70=bD,iȿ𙿶K~=bSf`?- ?`>GͰIɭiXd,tYސn12j[,ۿNk -&6࿄ƽdLfd M???qC9?Vic %0>e>p5`"Ri9uc¿ؿ:/jc=*uJx8>~U9hOp >ؒ>=u>9?:?V?8@ѐ?0 uv"}SYÄ]⿲}rMڀc8/ӎ o}am:>> ]q>*w<_+лa?Q?׾N ~箲z[>:h/<&O);6ԧj1YU\^?$<p4ŏIU-z=>q5>ɗgt"&_<>B4yx >@">wT>`OA<2iWx]ҿc>׺=P3ȿѿ {r"T>+ o??%>j\)=̯/gƷsv>`>Ƞҽ=K??Y챿JwS쿪k$ؾl޾2sDPſG dsvu`zFAz޾ -<7Jܿ(F6b}>>oD#=~>'8\0=Ӂ>:>˓9>y?-?Z~gTVaeKiȾbQ+P;r5応v(eo>F([bp=g>s翱8!??꽺uLJ1nt =*[>+=s==,/>T?e?u]SA[Q=%>*c\yɿ^|v_ ʚ*8Q#ɿ-XͿ'yŽ.ht>L ? %aWXX9D9e>&+>ِ= M*|/}ܿѸaUn9@>vGF?F?2F>n>qSrпScDؿw?9QwbV罘.=[>?>W1PwӿZhK兿r>+hY"ݾ ?;Q?I??Sjj̿ 1HfS7?"޹? C>y2'Tn%N=YD`=),6o>,z?t 4?>AS>cYu\'??tb?ck7?dC⨿:;>g?9?<?/ ަI>>}`D¿Wj8>7?|u?_?e>;}䍿葿^t$.LHþ=kx+?>?aI?S?o??.p~2v4?.>ҿR!9>)U?0?S? >a?w?楧eb\ր2+=}y?͏??;?Llq?r)-݉ʿ~/Hg? ~,6QݘĀi81l,=L??L'u)_N$6lY0⎽>?i>m?/~?O?zI,)8ɻ 2=>sѱa#x~ ߷U1g2|俢&+(>Sb\:ӎ>w??>VaI CӀ9KFZ>-> <)=??HO?T C(ꩿHſڈؿȇX_ru˿2vpIE5H^[b[Ϳ @F3Bҟ>-a?????[?HǿHN3Lw"Q5>iWCaO ?@(X?5FG t_Ƽ> =/X>f鑿1V1AIо0`[Kg Uo>s 6ĿoUi>K8OA>w?!=m ?b?S?-?@@?wB"ܿaڿ^RѾą0 ?7@'@f?užgF>mܾ߱ʿ;0>\8VL']*q2zgM5 1#ĵ8(@鿓Etj>ij?{Feu?(?ɻ?)? ?pe=#R_JC/^r\3CnF}$^ ޽??`?>|P8#8aWZdHd~ n# J0GIYx5 P󈾦։,yg L ievP1?#(=g4y>l?e??cQſտ5LCRF. RMZ?~K7鿐=2s(>vʜHvBv =rd˾^&*y?Sbb?>v˾^9?¡H>  ` Q>> ;:(3迡0~"o Fܿ}NÈEԜI%&> >]K >y"<X>>佣[=K _ Th]c^Ծ|ホ=Ef?ZGuV=??!?>M?i?R6? 5ɾʼnnM3?^/?FϾl& ӿ駣XN ŔW6DT>.-?7@i@?*"?牾?x?HE={=Gxn @UM@5>7 ??Ody[ς?5?@?JwG);-=?j?ں>*P(4 xw7#Pk3=A:?b?ª+?Vy:>zzLP#QͿMQӆ5/}ΈU>? WmSW׿ %1o?h Xfu.8ͤ>fC>B␾4ɿ'1  _B3#CN!>? ?A C >&;ֿ0鈿%A>6Z&?z?0>DͿ;Uv_=PϪjBNy׶U3  ?x?_?>siIBqsSp=3#h*?x5+:4?>L٦CrT0>>b >U ?5?ŷ?R>kh_&|Xƿ qIٿ?N*S(!??k?(S+i]=l2_ 7j ɏ0ɸ>'Ӿfͅ\k>>vJ.=RҾ8S6?9y?"?yz]JIdJ[ V@>s3?9B39^>Q=>7s$ݻw?}m}]3UǾV jӿfnxοI'?˳K?(*DSzKa>hF?=;R8Mǧr$ڝ>1?4?pX?i?P [4񿦶rJ>z3?ޔ?u=geJXKM/˿& /J>>V@ir'Q}9 >W;W]f@ٻ>ܣ>`!]>s6>YuK=H) \Gd> ?8} i[??<25:oMP? @c@@WT@P?Ldk;n l?b?%E5DM= 9J򿢜 ?V3NG<_RrӢ]m>v>>M7@.?2> ¾}>f> >6??>ɾ>@ U@v ?g?@2h>7>eE>=uվ 5? ? @*ʽq濹6'G[?u>A>K?8?T@2@?Q?D@?4?8@?z???@`@nK6Ϗ1Q͚uNv)l-UA~X꛿.,^?O$ ?(l>I`?tžX+M>%?Ч>/ 0?+dz?}{@j@??Mʿ???>P.i!MT+Y?SD@3@\'/rUQ|]~CE=Fު ?ҿeFuH?o p6?u5?l@'A=b>.ȝ? B`翯>?_>'+adV>?rW_&>cw1>O?dvb,>teL?9?,?R?_T>ebx?Ƥ?lB?5\?r@w@?#5s?2m/[H 7>QR->h0§ @????L?n˷? ?L?i?z?@@ @!?Nx>k=YBʿ:oZ? .k'>?aD?F?{qp?A?I??1?m_;>{??t#@j?@ > ?m?ƥ>q =\M\>? ߿@Ὧ>os2ɛ? @?y?`3>[>B??(|m?3?6?4?S@@@'@=%@+*@8@k}>>?elͿdC6MQ<ԿTf;pePս}?'?zL>a+|=?9\@^@X@[@PD@*@VS@?=JϏD :KK&os21c&Z>K? ])?JG>X@u@ux@(@#@@?𾣈~(-l>C ?&? @JH!@@el?[?ŗ?:9>Xż=^?U?3>PgM>9B>>Mc?,i־?ǿ˿n3ֿ^%yvy;>+,)^>n%>=A_A[?"׿~ֿ7$u*p>q_?3 ?9?>{Kx?=> ?H)UĿ."ſAþsR= ?"J?H:?N>'y>zh@>$ݽ,$dͿԷ쿊 cP?2y?!?nȿ3ھ{鼿Px Ti7*(֒B>/l?'?##?B4>hW,߳RhIpr]V6_0f/ s?SA?NS߾^ۿ/Ϳ .K!A u̿NXf=]>W?Ԣ>@Aؘ܇0eW=^Zٿ^Ͽ4&MKmڿ(d?>^ٿ L-q('s]?¿Aʿuƿɐ6 k?^>tC!\`.>>&aFX4?V ?Ofȿg 18CA_Lҿfھ*ڿeحne['QG'3Jpw;J?e!>!¿ܣ%ڿ9Jw^>? >%1b_^־0>t>?`>ay=Lo ( ׿W$[Fk~C! =dKFJ`[5K-P*[?`7t9ȿw?"yVH}SM{>' gXֽn5?*? ?Ƿ>&?[8?0|E?G?E?5?9пYU,1a.(O4=˼UߪR#`$Z鮿 ˿Mwf(؜e E˸ Mx>% )'=>) ?G>Be)>st?%L=?K?x?E*?]>ӝ㬿ӌUfZWCa6[{,('=׿[.9K">g+&^U?òkO;64<ﭾs4W&Ni9 ~ Jp?҆?u:>Um ߴLټd}?'?i=>???si~[BM_g8ſEn:*qrܼO>t)>־ G'E ^v9^i?A?vH?U"?Er>8 ?i?9?e>>?40?#?ۓPX~-h!ocLIʊ??W=3{>[>8d/!1`:?}??p ?3Sڿ L (?u?aŘ?c(h>?Fe?e>14!?X>>F&?K>;~k>JoP>}ĿaMƿZ? ]9ɺ37|= ؾ`S}wOڽ;QڿUN:>!?6?Vz?<5;1Ϫ߿\?B?c?±>g7FOZ$߾ϕQ|.zH??^?Fۿ򰿑!&R,ʪC5࠿Q l l ԎgcӯK?!?n?ȼ uٿIWտXĿ6b羍?|?LZ??.>/<Ϥ)SGGH+J&j9#1LgľI#=&W¿$ٿCkM 뿃vsʿKf#Ѿjsu a>|.A[p _>?II<Љ:JCο\,l?' Kҿ,ˬճo!e>8>(y:9J{hF=i3PοS>v??y|B?=>>T>R7?$$/3\4߾w/%e{GBZ>} z,q#ürL0DlU6Pw9nݿ"Vm؁] Qh򗿣跥ؑ9VU]JU1-4?>Vt>>[8?`<;3h)* 㸿pچTWԾOgp>?@MH?.-*x:)jĿcRj}=2#~$5hUپ(=?o}?iC?=j aR0g|NSDfTsFrŻG;?>]vA< c /r/Ë?E^burD ǻ S>ɢo?f?VýpݿINv\{^Je"+6r߫ w+>w>̹>?0>WVTZǐ }B{I~bȿ@ֿ(?G?)L?s>F)ɫ &:qqW1M!0~U+ݿRp>>?>. {X䥿;hF8xd2yV¿+9>=>"`?Ԟ>C;, .*>/?7Vj;T"% ?Y@m?3)X?]>P *⾕־yݾ }>o[VBYڍ>FӁ?}>K x> ?r˼̿׽n?h>6#>Т>g5^ch8TBjbAm) 9fp.~?M%@^?P>J%cHnH62bFb?9@_?>wjA<=1" ԿEfYR4Eh<s.&\:?7?;W>08#@x?pa=2u0zs̥ĿH[uH=ki"}B^>>EJT? >8Ŀ(-ÿ-22>w=~w"uA@&eVW\MW6+%;\>ݛ?= ׿qֿ#%<6'z6ۿp\A0t>覾vsL0u=m:g.ۿ`=G8xAoHf>b?/?"R?q?+&)A& tg!wtpDsV7?2>]<}>#?=٬7;>r=e'.Rj>>F뿓iP{\9#+BB4hJf_ 3lL&*<>>=3>(?"Sп^JI ؟4#O9X=ా2;"MӞ=T¾Ј>?>G>}=l=xG*>D7l$= վCw"_Fm%,2>k1{ HreOHk+vߢ)PsS[>j,D_@K2B Z;QUbY$6ܿdm˛?A= >{'=>J)?wZ+̐=gwi ̄ھ`'?cj>g-аU)W~NKC) lcOT&v&vn0)߾+9X^6ܿsww;`Iw>ܢ>o9\aڿlm?ZB6UIs<]?1>B'j|=>s/쿵Eְ??o?]F?tp=(UֿgP;o}(]Gnf.MWoGnϿǿqҿ7 U-Aֿi+opľlLTϽ?j=p6Y <^>J#霿VxMǾab?y3?g>_[bcK??0?i >T??h=U: >n?ş:u94^r8*Z;s'6>ۘm PV)JH\na )3FdYS?W>>я=`//=>MGjt  ^$2~O=;>. 9m.X=.G?<>hl?J?V?'e ?&0.?aY>Q=]p俼'Ǿj?C>~ϿV9ԿmI7nr̿3>y?|>CdM 4D>p?Oa?>aT8?0N? 1>B>oT?z?4@n?=y?'?j˾_yUڡ>;?f?UX=L=\_mb݋1?Th?@t~U18Ջ[`=ɱ|Q>7=?7d?rM?b/>iL&?vi:?Y4?i'>&ȿ׿, @N? =cfYI׾J|?b׿VykGY??6?OvK?;5= >*?=x=NɆ?\\?@?s? RS> y?.???2??}??Xz\<<"&>b\gca?GX~_8_?7?/i:2;?=$?@P=@H@Z$???M?7?=0??F?=>bLE%sS}SKw>@t@t @!? m+(<M>|*??$?mx?)c=nXlzñxFK쿆n?i?VoK?+) (־?f0F?A9h>y?j?]t@$!@@b7?+eQɿde&G{w\54?6X>}>cɠ=ɝ??Q+?st?Ň?U?۫?&#@+1@9@Vx6@r|0:bYݪ}P?U=r>?>>0Zq>6ĿK @~b@uE@h @?@n=@`@29`xU:|xU=%%?+?c? i?]Ͻ0uk??%@M%@@?ɕ?У?@?ʬ>">?Q?>A?b1?=S?aԫ?6?i?h~tȷOP4? ?J?ָ>]>ν%cz>#?L-7=F>f>?3B&VǿXyEWf?eKIgbۿUwٿ?0d,}??k?_>)?L₿</fx8޿{ο=k?d??o?M>u f)ο{ܲ⿖=k2xg>C?3?.>[?9]>Ͽ2"_7Zih(`?7l?'>3߾=Y4տu̿$=2>:¾O>&?L?{4??XΔ.ߣeƿq/пR16ap@ڿC7>}z=Y*>s&?֩?Ogh?%ʿ-ٿe%˴>`W񆐿4>| ,AzE>j~ bx/?8A N6cm\N'>I&g\:>EZ>-۽nע/ܿʾ>ܾj>0ҿ|LUEfK ( )`bɿ K!eC-XzqOÿM彾=h>/~j{v <=hԞ'b Mž ?/>8?aX?>qj ι>S뿈;!%νpgICYlC+}hH@^ſ"Lѿ(FZ yM >,m; n3ݏ яT>Ю!H6;<>]XC<&^,OSjLBjQ&䯿qgB\⿘KO̽<'e!g#zпS&ֿmd rWgRԂ̿-ʿňzY7pWPJk%DWd B;ŵ+F=է=Kk)pIR>_=L .CB:6n=_WutN?ſ)3svP"οA ^޿|*Tp6J?_d凿z(,='B'K0 X/Q=QxE`>-T>D>H>OF=n{>=USpIMǍlο+te¥ 0~o3Gf[3 GOy>x>z+., 3U7Q=Y?#??C>:>iXSSĔz&&-<79 c6">~?F.>UC5Ci?K?ltN546 u$B =v8YRLþd>nMZ& a퓄 j?j?ټ'#⼾P@w~qϭ)p2{=>ݸLP$=uFP????ڗI?{s?>ٿJYkuBQҩ!?x>%>Zc=D=xZTDǿBkÿ֐霿;??0d"Z`!vXҿG"V O忾޿k*}ӫu>3>VCf6*І˸=1>H~?<f?Ggiľ~0^H zY;.Z5mWX=<dn5h2┿;m9g1Eؗ\*?'~?̽@8`ȾbϿFIႾÇ׿3z2 P wϊ?x8K > թ>R}zwL O\?E&R4׽0?~>~u׿ƿ{FATl-T_>ꋿk L3 YY}~nKX!׶RGտs耿GKɑ/G꿌*5 B k"5<?>? 2)?>lpI Ύ#&ٿ~ܿ OZ?d5><ۿdK?3>+u@gؿ _(뼗@сXμK=6Pt>fC8 S߾ÿ˿fWi(BཿPI>/G?R!<7b4!s0M=]Gi=L>s奔ɿ`K˽/>pv ?g>T"̾C֦u:* s1=7`= =I'?&?0jg??>ۖ?v&~Xq[>@.ȿbPk'OW4ةթ.uM9$@Mn*[r>k.. >oD0uM<lfV?,ć=*xHZhL"l>>H?->w>ջ>?p>>3V>ToofAt@ȭ >K>Ej?O?a)4(_zBo=ؼG=䌿3cO/:a_dTh^D#6 C5۾Nr8,??AiֿR]><>mK2mK[>"??A5v?~Jヘ50iC sQ*޿οC V??d߾>Nq'#6- y UW}hŽ>E?#٤?S?Г?` v?^˾h;">L0??b?`$ *ǺOA'DBR=̿ӭ`w `< !>8{<@1('(2yؿ9n@W؏Qc6Lw˿8}5iZ>?/Xw?-?l [=y}Ek ,7u]GE#&XgIjVLD,\>[=c><=?,?k?KA>6Ŀʲ@vڿ Ϳz6(UʖowD ?tp>:2jſ9FTHʿ04Tk`A|^~yl>>h%= \ԛl˛|; ?M?%?v4H L ܈ۿ#; )o"(ׇhLA.?=Kr%;q>᯶>pꁈ'82쿫>ۋS .#se&D'𽿦 fǵ RB36sC #!#nXK­L]{ Q^gྍJ^ ITQAEhп㴿FD "KY(䯿t9묾⳾q#\ ˾Rd;k×C*KWCAhNG,qA(gM1nxe  ky}T lə5؇wiV/A=ʬ}e?  4]h^jRDc r靛K/UؿPMDX??њKHľ>nW=|(۾ԊW&Häi/u?B?f??RFDۿPGþ?sΏ82cz>f5>)2ȱ]'%Agֵ6˙4tj{LD Q՞^0wT{! o$V=,L #ʿpǎÓ=B,AD9k}ȿ [0?݀6lɿJ>.y>T&?T>ĚУ}?BC?s0>c>=TU 8ϳ=mþ.EiMpֿ &VvW3%zik:\A9 H!b Em=c?pɿ)=>%>)fǿM <>O>&>nc %T>%3?:ِ?Zu??e??EA?RK!cbGBǿ[{x<8Uô#^c{keKp#R< 4 .ܿ+w ;W7R+c>Bk?9>!ھTFQ(>Axܨ0*,4?a??c?;?"&?-> a[JißGUB:|ڣ(s:}tw'E#%D̩!Y}_*?1?fI6H}ȿ1' ſ=/??{???Ar?{&^>"|?t?m?,^?Ceʇ i?eʭ 1$vv^:*gIQ`>j?K>>^>&?r;?Q}?/?S3@?wV?B"?[|?g?:?k=j>UQ?xX ?[þRVt >R3?ƒq{ՂQ1jY>t?D]?W"Py>??vH@{@ ?/?rX??U?OP ?X??ZO=-ʾhνɽ^貾BēN6C޾5]K?5??)ۿ~Ͼ%?ԭ?=x?I?h?h>?H??TR?v>? J>??Fc>b>Z[?F4# zGЎ,>? ?~?ǝÿjVp,?%H?ݻ簪>N??9?m(?+?>-?T"?R?y$@$ >@$?Q>|y!uwI׾JP&n:ݿNb砾ƒľxY&>_E>҄¾pξ꾫hl?;r@+?c9b?/u>>A??=@'s@i@Q5 ˾|lq̂A8E"C ?YA ?;>DB>.QJj~Ç,?C?^Ǡ??0y?"-?aZ?ԇ@)@1@6=p?P?<žۿ]m=\?Q><֟A??>U>_=Z]=BYοޔnK@X\@ P@q???a??E?q0KZ8-ľL\>>A?C!?k?:?&jd?2@澭׊?@D?-eZ? %L?T?q@|?M?=?>%??T}2???tɦ?g?^=ba7C>u%>l?q>G>N'ˆ?@e>[>)?cR#>.?>_`kG I?; ?jc=o![2=?jRǃcѐu'0@T>a>>iɸI܊5Lp&;g?` z潿mtn8 yƿcPtF??Z?^J?>1EϾ🩿uۿ$Ţ3-.z>3>G??mzȿ5߿/$!k'>_L>4)>ŐI?SZ?m >(ž:ᅡ[bS,Hl&m?9ӌ?I<=__#N *ſ,  ѿMtr㾀.᯿أm=HXT?5Ԓ?A?u? οd>v18i({I˾0eྴB߿~AVg$U͠>>DĿ\lο3b⼫ctcxpÿ<gdܿ|{$?h?S?퐾( #ƼWn 6Afi6olCk?&j> ȿpӿg'џ>1NP;B< W&T߿/K<οⴿ ef&>c$wY=A>3d;ѿG'e%@dN=,gV~,.QL9 >ԭ>0?>y4nWD @'?Aƿߝ۾侩k3ؿ >'^s'p -i;/>>s;hkzkwrs5ҙsUuS>80yR.<ΐ?[:?Wqv+#΀"VZ¾0ʿ)~ZW?{E?ʿ[SmFW??vg<ߙɿ0vZV缿*n>.OqY?vz=Pg@gw\ ?N< Xau1:ѭbh ?n?e8俾Vҿ-njskۘ|$PR>R ż1N6vcSG޿mAE>6j0R 2O^cÿ>gz~BPWIV@(,- ?><;??LkH'!>݋5>!he=GMCL̿mMv+=[2޿_ j*?짾[vIyFO 7:EF[=ݕ(*X(77:{dL{L*} @uÿ=>>]8[My>PBI>Y?mZID8f'п)+пʧ%o^,~^?|颾joK;T43⿥俗>$ wMJ@ A.4ܿcjDNdg(Կ&/嚿ܿpcj?8Y?>aE >%VB h'Sw;S)ڿu嶅,?ǿ'H"$K³zEbÿm)鏽>?n>(*7A fx14 1V=39m'Q/ӂZʿ۰{R5>;]?Ҿԇz.zq)W>"YC!BT ћqՇ>G?f )?K="8m=~zV˿:3\bh1<\s >!?ŭ?H⑾rِtozRο޿ (=>ξhHDEvfb= Eα2(TQ4Q+ !f`yF}诋&6.(:\>|V?yK?u:"=(t`M,_RTڤ2yp:̿q E7?@=pӾ} 'Ar>M?r?zɾ=-S97= w]RAo=H?3> >G>>w ʽiߝzÒMisOm$KKӊ`w8%d~{ǿ^d63WSc-.<>@e?CmNHKyR-=8ͻұ5>=R޾ $iUަY( b>OĤ}6F_k ?җ?w?_J?4r֬qIkD֒>{,zǿ@ǿΑ7ݾΊ Ͽ&!+%ݮ>xGJ!:OI>a3?+?>?&am6z>d} J5A=,MHWZJ??>ڿJNGEcZ4w e\ ?i=po$;. f_aEDJ9k^}ڒ_=,B5??( @.?'&>]뱿ٿVfT>4@澦%i) V<=/eT}mV=X~>Gnݥ掾uD?_?=1->ɹB>z+J~le ˂ |"M>e>{V=;<>-L?U],>x>?DB2g˵M?? ?@Ͽ=ɿKO‰Ch<?@?OG?$ ? q ??D> |摾2+?>-v-G>$;?Y?;>w,5*$ze:!ܿο|霾8?'I?C1,a'{TĿ?r>䬦>;1Jؽ1a>$F;C;پ?D??J@e?5$?|ü>ho?,>;>># Z늾v?7S?1RA?㫿[?O|tVT 4eB Z^ CdEC/??tʿԾG+t3> C ,d[VxɿȝX/r= R,?y?oK?x?= >0̾:y?"C? 龾[>jj"?,Lo?ufMB&`HXƎ;Z[eXjbDW.N'>,wϋ_tǿx bR4?I?MN\2Prپr`ں0(<[A=k.>^??dX?aa4пȿ\_>>$/&7Hgm>?g޾9Dc, ]o$5Y?@ͧ>쟾x Ǿݿ{о<]?_x?جVnn^U){Bž[㾴'6~:Xv6[>qf~ %z%Ll?h??\U ܊[CX&f~-Aa~Fƾ[`̋2.,VRؠHjɘ猿#{GY\<ϿkꚿP=16u!G* ? b?Q^_ IB!R~?!R@ !"@B?޷?v~?p>}I< V꿨۾ E$Seѿ'I@AQ\~ رNF'I6mG :: >R1?5+?dE(Qkod=S3 g Utu슿Jo0ӿC܅dGn@̿'>7;~{h7 +:۾9=PQҿ]+LHO+?|>䪁X^e0"@:I[ 切X:S-gup@=i?aoҠO ۍZKܝ=u0>.>T.N˜wź+H$D=?*B?,>B ſGǿmIzQl?D2?ӾR*Ep8־ u".W_r;)˪/e['?*S>Rqh'vXݔu*K>?6r˾W=z r;% 6qǿ Eo@=۾GV^h `??33>tB>E6*-M>/?=???}>yܿ$W'71:k*!s6Jz&FhZҐ w^d=@1?U&O^]f῎uվ?)Sˤxn=kBLJ MN˾8w??U@x @ >Z(N>?C)?m9¾R%Cоz/=;]gӞ=eV>>W>q>Qg;2'-$tۿDۍJ؈h6=.?[ҎC;>ykо 7$c ;ޝƿjB=>AY,>p!>( lc?6rTԿc|?K&>W?&zqK?Pɀ?1">mgm6fy[?:~d? Cu?ƻ?ej??2?_?H?=ܓ>??L$=jO$q UBO^-UÑ=ab @]&˼ Χ2Rb뿚n%nHi޿'A>%p[=&?Pz?hn??@??05\־c >7>`>Õ>1 {.'6?QQ?XÿIg*R96g^&ѧc5pP`0>SEU??v?d/>1˾'Y&ˤ?r@%?i@G;"@&U&?N??fA?̏??%?ziq?/]C@4`?`y3-񭿩P? Yׄs ݾ!;?p6? =e4^u4j?>T?? ?Ъ ȶϻ`>7[>#x??s7???b9?J? ??[?#w? ?}bme,9׾y-ھr 7>}ܽ@ѿ(s=&H#lT>P=??4n?¢(RU햭>u?U=?J?,?5?B\c?l?1@>@ z@g@qV??r5?qg?\>8<>P K{fj=ц8+Tnf?V? GiԾc+(> L!?'h??[?J??jy? @?~t@w%@c @HK @ @F*?+?+S?kN?U qc(cWʀi>?.¿W娡r?Ȩ??cT>t>v>q??0??ů@I @ @E@@-)?|ξq`@fs8 p,4g>ʾ.QPEu=$i?z>bɾ]@%="w?f(??o^?4v?r?r1?*es@8@eT@H @#rݭXz\L0ڿ}VO2>=9 ?A.?٣?f>?:=ƙ=叫>jV| ?$?ս?I? ;??0羖.?n @g5@A@v?]>>$?ʼs߿Cѥw ſá~)*>)?u?FӽF>U]5 A`=v?F@??\?-O??Ox?a?P8j#4?o>)$h8ʿ#3EТ??딟?6C?QR=S->߰?-wZ?p>NպED{?ٰ?M?B?½}ë?>@\??@?A?9]s=?ŵ?"V?O>z?ޡY־>Pl?x?jK?.>?=uG嗤?u'?'0)/?@%?d@TЃ=7n)ɄǾbh?>h)B)\:2wz!n01ie~+ÿܝʿHiLɿtR:d);h >C?5Y}?"?u۽=Q͢-]ǿQܿqa׾ dOq_#LǮ߿6Y z&K-G)=i+#9>A?Q`?=kjyUu ݿ 3׿{ܿ;{Go¿P㿛 fֿ}2+1JN`R7=`XE+b-*/>6D>S}96VTrXx0?쿝< 1ӿԿ.&߿2c7)dʶޚIzY 4}޾zֶ~y>>t@>"Y˿x W{Af(#hy ՜S8пϿhEH袿 WɁ߳0xC#/_Ǿv4;"(m(|t'>mȽto(gZFv=s>Sھ8_0@o̟F@ʿl? ?ĿBEٿ( 1Vs? Ͽ-! 1IϿ?2=70=zd;h7>R^>j5-e],ܼwP= Խ^4п ԿҾZO ſԾ1\@4k?>`3?B?:?< =}?.>q>f@ ſ"MAξWpӾUpzjif?fey,?a??s>A?dƦw, >C?z>Px??k?q>J1 &tnN8#ٿipxNl~&M>Z>t6??7s|?|a{?.vvpb?@>?Up?7>eXPㄞ>C=S OϿ[9ҾG?d?<4>De,ְCl޿+޿&Jӿ֕j` YǿR&B>4&SYC =^|H`"ln񮾴@qj???f?>ؾծ>vS?} 3?_L?Ϳ׿pi^XL-f⠿&6\{z p0GQҿ ʾ+)J 5AR>->D RYc6@׿ۿ2~'ǿL Jp?A><>cX>Q˾i᡿> ?*Ŀ-l?>tZvX XstnD? ;0h1Ǡfxޙ#},Cb^0p`0_\V1\=Όe7XȿqoΙFپ:ҿr*oSv>ߨ~3 v>7½)ii> bߤ3DqiIEj+c{ˋFQ owuпz -($#E>-ؾT "A>'>5A>>?Cgeǿ!1@=pT>&?~>Xin=OaǾb12p%î9"+$4(@d{g>Jlm-???N?GCʿgx6rG?H?QվxKJ.??,f1?>x)KmſzӾd5^><gĿ㲾>?C:=%|!IƿI0Vվp>XH>+i/JiXdS9GTN1c?涾2fX/3>u?s=8Wc >N\>H>]NԽ)+O??P½7<_J$) IF9L>Տ>l>@Q=;'?cҼgE3/W7q񾴆 Fѿ͒Ep @RA=6^ ?w?Y`ž kW]22>?laBU]#k#FKbcX< N ;ꊏ.q,?* B?t#\ܿ$LW>y?&?S?w N0eZ7PL~(ȇϭcfkB房i}ʿ=J$?y˾!jp,=Lzྜ\=b:y>3w.=%>>'1fľo> >e|hn4{I wpP8d*('CuB\z?7?7m?"#DZoˀ6@q:I=)0J֎ de>@s?;^? O?ѽv??\ ?4|?¿݋¿N;˕(I=l=0N:?׌?QOĿ8ο7ǿG S>%??>|ڿe^q>%V?9@(7;,cAAsnGt<ֳ=D=>S?O?D???AՎd.PO>ˢ>f Ҵ &0 ⫾.>y?W?8Kݿ邽?Eq?U?XW$?h?ϰ@6w2maKC 6VFCB!=$1ʲc($=A?>Ƽ=e?&{=Ld.׿*&%,`ց_޾Ŵ⾈/h׭ 9ٽ1V?9?@֠>aI>>f^Q?H??v?dž1:Z1L/?)?߷?,v7"^Qsܿ=X^Q2h/=U,3(>F$:2Ͻb%|lه{2&rIN%=4li޿WܿG'JZC@!0.??{_{Fо>??X???>KȺ#2!>^">#',qckXp1҅t=W?*O>VVP5J=-???K_#7 "|>ƽ~ܭ Iɿ9䡿]?<Ώ.7)>Ð@G??;u?c9@H?Eo1LUG"&wp=bȾ}|)3[8?F=lik.Fl ?ɚ?d> X?NY?><PiaH[ sϾ#J⾪þUMf;=Gd{~%s6D"?_?(r? ?j;ӛ޼&4>gڹ*ȿgwٕk4?R?hؾ(4ݫ#`C? (?{k>?fnj=`uoHտ#n(:D "<8?dmQ%̪B? Y=ݿ00C?$W? u>5*?Ӝ>{Qo:fgIpg-㕾5 쿭IX ;cɾYҁX%ZO2D- (zov'j׸""h`>UMѿoC>U?n%='Q87+?`;ۿ\:MN (=$A2ɿ-Gf1>M=j>x>H>o+?c?[?π죿Lп,b=`->L(w\rb >=u@{S?[CZ243\ή>d QjY|?Y?ල>.հ?J!mW`O@|>XN3zr>x?ll?NRI5ꔿ ܿMJ&J>g/??N@zy.?dϐ4iABBQN?T{׿:U]?<=1Y?_=SnF>wÂ=i<C> ?Hƿ"r &((Bl)He >>?:>J>(>u$>8kE>MX?e?z-?gd?V⑾}$/er\={}&ٌ̗̔UQJZ-m];?p[?G)?ttU?t-ֽA>'R=}Ŀwٿ8, ;]x< B?O4?RF_>lBi?J> ߴg>7^? fo?^?2R\2l.R ǿf!HE3)ʋtsj0Pc0 Ioxv+ >? p>-mƿң?n;?G΅L}i?ͿPä>:>0B?V^??:龷¿Qn>ڎ4?Rſ[T=">Hv?k]>M+pV)4ؿx@7;.d>w;׿ENsktΒJ ܀LHhB}5 ǩ9R;ٿ02Qн5~856e&@?l?bH#q0!??} =?ӫ>1?q??;3h2ؿE)lͿsÿ6f BAdꝿ?Y&.5qIrԩbNrwz\;Bi>M2fK"m,;9?}7?g?ʴ?`;??`1?+?)-@4.@\*N첿KPB<7Ѿڧ>f? ?eݽ<=y*pݾBpḳM*<dJ^_ń%P>=J?ܢ>fZ>?h,@bM@7@ ? ?q??]H@+.߿zI>2?^?>) o[`U\I??^>4Q|;k]PM DIh>ؒ??eG?@}K@@S?1w?)x8?H(>6? g>H?\??}@?? N?>?C)?!Q?I9?y= [>\>l-O>>4>DZ?ltm7z?7??D? ]?_|?Ì?~گ?A?? "@N@$@˰?6??a?>в=]qWAƾ"P9dAjR?}4>F?v?[?@@ ?ܰ?u??@p@U@#@>G?ϰ-@@c?S3#?>?ܒ+a=u2B+Ğ>ʿhe#JѾĆp?@@캶??N??ُ1?4M??Ō[@3@_ @Nu@d8@@g\?'N|{I.%oȷ^ļ ¾8)v:PKUsB$ >$?C?_-?>}fI?5%? ?w-F?.?u?k?_@:V<@4 @$z?:7ϿDd! tF-=&VJi3>`q>ע><E??bl5q˿ ;z֪gR:j¼>UM?l(?D?-?z??>J_??r? ?Ě>u&? 1?-?Fո>Kl??8钾)A>t=T>X?>m>k>>?f>o????,1?:?є?1й>z?-<>Aµ?(?s?0S?e?F?Q @s$?~>5?|,y#G.(Ͻ8G. ῕*&gs; > }ﶽjK;̐>>sH>"WZ*տƿk¿7MdҌFN ÿY%Pdp!-jI?(??=>=^$r9TG4 !Jӟ`>$~?q>;-2 Կ$ETLҿ5|8VܾĽ >>oS|ÿR◿(I,ӿ`9äCM¬n@R{ Tо?tձ>!>G ][f B|>_D?@?OS *1`zH\TzWοWD5%m}-?2s+ 8ǿdڿĦVs:ȾnsʕĿ 쿀kֽψ"2L俖FL}=;??T@2hqDay"#+lfK0zaVܾ`)@2iٿ [9wh[ڿ\& =]'Z%0lX %Ҕ~yпaqs靿k*3w?=B<ݻؾyT 4[;}JL, !>;BbB4?\S? N T >F><VֿuAYǿ@\AH*" LbdHI%мʼn>=ޤ3>~?>I??RcO?8EzMߕ=F)`˿䔿 &/{G U8@ξ?$?)e~]?֙>Q>~k{m;Cz!TQ]>q?B*sUO >Z ?-? @:%?>žI? ??x:?l?{z"ꎿB >o=pKPl<{}?s?xw[ο09jap?"ǁz! &_΅dDKV+jfTֿV|5c??2v?f಼>̄و`w\ȿ=SI,;KɼY>&R癿h_SR*n׉Q>ߵ>#DC><=?{2ӿw{ٿI1q>B?Ӿ0폿۰u">N0ѿ|\DzuIpA1Fƽͳ>Zʿ'c zٿ?b߿odPE|+U=z$C@o?@Lqzؽ?:?4C??$*CDÿ857% J=t<??L-"iڿW#> !?0?~?ǹ?kQ? 7Fп8sH F濝¿昿Gp8>Gp>p*??̼h5w%瞿 "%A?=*8?PTWUM F{:Ɉbd7 8> ?G?9?䊔?q>gr𿃗(/俟vtK߾D=?}]=D^>Kg?w>,n:J;[Zvz \:*18Jſ]翳v#l m?-AbWԿ Dpd^>%}ZI{ _?5{R`>r$?@9 @y?>q?7o0=u?F>Ł >>{AG;G?Z?5_?}?W?=w=l0>>H ۳DEN:> ϿEۯe-CUo [y5ֿ2@JkGSKv'Lv̆=rA???"QY>6?)@o?uξ.Qƻk>ډ?ǹ?>mίV>c)T?X#??'>O?:p?Q>x_>Jнϧ| Ċa2Ŀηÿ|߿׿'ʾ?_Q-4ϸP6MbAl]?>}P?-?^>jΐ) g=>'?/t>Uorb}? 0^?8Dc?3ܬ[x.Ї󲹾!o?C?ǡf?@o? ?}>zR=ꎿGQ(|O=Z<*׿+(n*>k?2d կG@=.(%

->?<4=7Gs߽MT>p;i> cXѿ7'ݿ,˵(p_L9ȿd!;q^y8^C?#?S.>}So˵ϾI ?J??t/j]Ήǿ_DѾr,?J{eeF͝'>o=5?뽅G=B= >_>ek?[UT?~=&T'=bۿkݿ/uwkjI۾5Y$gwο-ʾ,@y>X8<Œÿ9,J)忧\H??JZږȿo򷱿w0ھ(;SWٿ ?}>P)B? ?Ui r> ??K?U=1?ٓ>M=xVx!/1ſ@j¶7h俀88=a0?$T?>y¿cfF?Fi?f<8NL6ZΊVW| PMğ2UzWAQNF ??,J\`߾]teVnm?ٸ?= 9n6=K~X?b9ϠϢ_~gē ̿? $?M>A0>j=F>-1هBq?@?5Q?E̿ZZ4i?N1?8}i HOy~N֛GwXԿ"? kV?"I>o]>OzGL̿lA%OV%Hf޾ߺ6ĿL6>bbRC碿=?? ?+>28ۿAx^=!⯾>4N¿Fc;>8,?Ť}?S/@t{,[yb?E?l< C<|q[,?] c.Xi?\?3 .Epӡ SRͽz???P К߽E٥@8fZUO:?t?o??X`W'qChhá1={ԿwBP{;}> d?ze>oj}_\;?F0?rߋ[ɿ˄ƿH8=ŐMPWQelI,:>:~>v<"u?^y>w¿*nug 'Zو?nX?lM?|CLv2.NK7.Z׽֜P̿ u>f?<ܗޤ^~|oO>@D,?X?jH?_ \}|%l8BܿGb!a϶Q>o\5j΃ʟL?Z>ؔ5 (ʊ>k>`{\O ю?9?@> .nw!,Z0IfD'Ks&f>{>ЫR70ѿ$a}1է/\b!}27mO{1W мR4E 'K:/%O>"?%>dw>J}>b2=L?+\1?3Ӿg\ۿ 0Ų"|5_\}@]?b=>Z5?[IN**6>95WZ(1ѾE ?ns>96yRz%V3Կ'Iʷk7>ss] Wq@EXfQ$Iq…4 jL.u.nC7}i1?JL5|G!?Vrk)({$ Pʷk6>Β{ ?K?w =,H>z?/69V]F >pZ19K Q-}&S@U56Ndܰ=ѿ;km#8;@ +8\ֿxW>J> ?=?' ?>4:׿3ڿ¹ÿ'??E\?"k97>?`8޽4=Y>>];+>W0V,F(U~|WdiR=oԿmĿˠ~ jqtzE >տ_Mlz >?hU?m?oE?}^׿L/˿?Bcw<̂y=w?'7?i)=R>.>˱aͿ :=r?%@_5%@s?L]=@<-*$ ߿ r>;v?p?C>W>׈?R>B?>"np?C?Uξdr%=w?x?)@3\?@Y@j>^%I 7wdeZh >H^=;j=þ%h'z%}>zR(6#˿]hS뽡½@>>ل>T]?Iv>,b?ߦ??h:@6@j?go*?ϧb?ʗ?ˑ?d? Y'գ3? ?N?p1Eap=?g?e?R~?>C>@>l>D?L[?U?3+`>4>e?k?yc @(@rg@rկ?7g?>L? yo?̛4J%2/^?L??; Zp-hir?҆?,Ù??s?8܏?v?@8.@R/#@R? ,>Ć>kd?*?!N?;> @Y"IH?I?1t?x)#BlN.{>7?qP?y???t1@oL@B?g?o??I?>-┾C<zE"ق=6z>("J>ʙ?N?M?d?|j?w+{?D?qC@0@? ?"@6@0?k&?l>#Lxd?|Y%hе>=:<}}>1>Ƒ>??8i?y?-@'@?@v9@U!@лu?05t6K2q_?%?|5yu ?vj3>́>?u?j??]?H??ي?2?&;?Eی??G3@@ŗ ?l'%u,[r <HxBo>a??C??aX?O?d?@ǖ?<>TNR>}=>>4&??%@X%@J?F|8xEr*dL=?x9J%N:};>D? ?1?D>e?R?p?7?9?Rg>l? ?L|?~??B?x"d ?8}?,>t>6>m@>?Ly??s>vJ?.?L??VѴ? +?vï?L>#(?z?J?:>Ӯ??T?ȑ?rZ>MDSt?b?9N#?uw9B1q#¿Uzʿ6) b??>ƞBemdp*ھdѾ ֿ^VkɿN ,;$Y-ҿxϿ 'VFQM6>D>E_k??A@?[7`>(;?Tuݿt:xb|E5[?R?r4an)_ǿF]s3BaL0 {?>_ҽ>?v>@U??ř?}>'Z (9`>K ?ϗPI??sjd<̿ЀZԿ@<~>(/Hyԣ[&n>Jh|sW2?#?ڵ=Q׃aU>?=e%cG+?h˿ӿȿllpܿK ƿ:q󟿁 \ȫyO  s(h qtξ|q9dk".ooHѿp> >Jھ}[w ?^r>b&Ub4ɾIZZ2 >>m1&(ſ = b6)>>v?PC?J??ƭ?Q= x]m]~??W<_I>/?lI?>?h>r>z>>>;<?ډ?0P# ? ?>LԾ.9¿{?y81@t=m>E?]??]?A@{?4??>QھpN4JV?G >>j`? ?vA>%ZL3?ڌ?2?4>̪5V{ þn???>bjmÿ/5ֿdпȣbƿ4Ā-(䜿 ˌNAP?Z?;m?__E?0!.k=;տbcQ?;QSq]?(?q???` u-ȿWP>o?K ? >šh;X`_*i.ҔtiY=գT8Y8iZg#jȽu=it>Qo?g??f> ݿU=[&?iFGmǧByd ??H:g>l-qq> {e5>cAO7!A 0伿Yʿ%c>[A?; @@ I?@oXNX K?gq?>h~ >.>s+a}N>a>M,=bVUO=>䘿Zҿ+j;S ϗUׁ>"ʾgN/e۾=7ˊ?u2?qG#WU:? "@K<@@MZ=8bIv\s}–}]='?×I?<=?T?>U>&iy@M ZeK p-sNKb={c?O>?~*?|NdM?=p忋;9 }"=S = 鍿8a#?@?~+(>17OV}|vB*>L?x?Z?Z= ƾQ>D=a'>)zA=??Ǿ?%]pcҾ_NuŖ?=<5k˿LiO־T˿"o󆿽ݿt!꿂ؿKÿs6,o=^?E @~?s)kN'$y:WqsPB/־>z?i?3/?.H+&m<<5>L>?"H?ؔ=dY=#>mH>E0?sʻh"0k!?ٿ#w[ɢ p5?Xځt:BK [jZf߹M%>a?Ϋ?mT]>>h!.ĐNO#+ VLe޾"؅kFEӾ$Q;r=0Ka? &d>c?m >2qA徆My?PMfS@>*e?\ ?>{`ྙ^W&>?x5?*w>YQU5_R,Gz5|Զ2>'?Y ѿc簿ɾ;ϴyoEHPIU>2.?>q>쵾+ѮѿH]P>?O?v?8C߿,# ? ?b;V(RC>f ?)>˃-=bdn?O;?J?Ӓ?7>C *tʿ>, ӿ=W.>1f4:l!AŊ*ɚgdA??%S?㿭@1V>1>"j/:修' ?=.޾(cYD=ơD ?ӳ?m?wg?V??D"?Ù?pd'e.81O >࿰>>5gGοm3aw<MD`Ŀ2!ǿsʈ=?fĿXzx=9r>/h>1X>-?>?3oӿ2Ϳj}dc߭! =2>?Fa? |ӑX6&v]gy\J4>i=Z1_1=2Pr?ܿ~\?X@Ή?&>.vt&I=uʽ_U(fL! NcрT>E?^͉? ?v? t={6*%>zWӿ3"->x~? ?!`?ac?A`>x&迥qCsqgο`پI&o>>>4W#;xxM[ٵ0{>/E?l?C?0>;d(?} қٵ0f"hԀҿAd濼ٿ椿Pz*?üQ2gi|E?/m?$/>)mT,0nn }vP 9?b?` \)3T;XČB# z=r, $ŗ>>=1xfR,I$z>@>-GP-&-*y¿J Կn亦K:A>f(*(UV m)鿳J-~_a?W>26aXw}D8|3oJrZ9{Lj>=/+־NFyKֿ;a9v53"2⿜Ѿu?g4B?NilIШ]Z|Q 䟿< Y3= >`U?I?>e>CE?ݲ3=Nǂ ֶ?; @?נ?=FPܫ^i CD)?ĿUN)cr0^5?'?Z>pX.6>,S4忖޿"wlԿ3>;6$`ٿi>>LU+>q^?W? S=~>ؿB3?'"<_K|…?  9.ꙟZa#t#VĿ Cp0 Z| 0پ=}>i?u?=f:넟?ZU??P-f] ]?jCk1nڃ}VS̿mͿtֆ[;7v-ʰP"ɿ||A`2w 4:(iMM`S>ASplrX?a?Ak?>C-u=i񿀄H>Q1ݾvv)yD WꞿIROyk5$,fK>(=͋L?Q>.q$k|;@ J<Ŧ> +i(z7)K|-d. 7Ael‹a'?D۴rпͿ@iS}ʿ𹿆I|mԤTlD ߿I%ۿ(׬*첂A>?4MYg<>ݯoPN[Cz_9tgѿ Ua6t(sm @J%?Tf?DpRͿh1&{8/I"-t =8?=N>>}R??V>%o;?@?8k?x?|8>=NeX/ڿ7HNO|z?ZE>?y.?CO?BR?;I?+_.|%ʵ02`9ug?*^?C??U>c-䕶>1d?(h?d#=M-_˿9Sc{99x<ߠ\1d A>ٿH#)3=>??Դ作Ĉ?Xo? ? J?2?+N?, ?怊>&_Ya@ Y=~)?Q? +?6,>8>$>QlItC >%z_1|>|?*G4>.pc $"*>???>LLs>/}?).?w.?1>l(Eݎ>&?X?kՁZ>k8??6.@S@}]@at@,@?|??2?(?-??HU>6Β>f ?@>>?}@q?Rƿ%]V,?6?YT=!u>-?6l?l?^:@g@!<@" @?Ă@?JO\?H2?? ?3f>{Y>Ғ?ʫ?ǩLӯa"=@?z (?^i?sL?H? @1@@l@1@ ;@ ^? ?f?9!Hs>wePtzB=;XDuԖ%?/ҼsKQ9h?Ѳ @Z?4?u?9G@u@?f>Oοl??^H.=W_>nsvQG#g_'=nU#?*?$?S@-?e?/@Ku@J09@?){c cUL>)B??rI?`1?X>4=[>(ܜ???}?,??d@9v@D@{ V@ݲ!?[B?8¿__?CÓ?b^? ??8?xդW?Ό?ZK?E?nw???-+ Y>80b?C=vs<}D>&=*Q%?@&?-????z?EM?٪>iNx3$l˾$}(D@=QJ?a?\MY>>T''?,?y#Lv&>>-T?c?Gc>hJO(˾OwH^\!34,j=tx<.=8޿-L??ϟG{>)=7>x=tp㾧?>*m[xr1`Fr"{!ӿQ:~?n?u?%?d?2?*>V>2q>(d|<55>E>>[>9>a+K|ŌK(aT/C28?޿]mk$<&) ?wW?o??(?X??x@#?}X??+yf?, >ﭾ"̼iT>SJ=K'!w^ڛ<??J4hUiĂ"(Ϳ[???_? E?H`?@_?G>ugvK>G%s?ԃq? ̿˿6ՍGtkNqsVnzտw:=U?f3c?{ڿc*j-iVoy$+6ҿE/y\t6>??_???͎?n$4% 1 >k>d+?- GͿa~z?{W(dRNۿfظ*ofw-,ֿ ݿt?f>{*=U>^%.?Ҫ.,=O?7¿23rJ?(?d!=\YU!IT# վEH FU%[a-i 1>?E5>%>T8ئ?? ^>V*=(u>*~?#>R??[ >$䎿*^z&?="?!u f>he yy>65UҿHCxռ{3?O?>:=EM^utOaT+=Ճ>j?fE?2Ľ.#X?Xw@r|@zO>n.Oÿ R?գy= >=t;ږ۾o>c?<[/%ѽIo???p7$??\,?5>SdcſKݿ_'OۿO 3?z .?e<Ծ̊?w?(?%l{"rQ>g;d/?nR=g>YBKPOe&Ͻw(D>b=$ ,"<ٿB>=>֚??,??*h ?M3z#T>!>$ &?zA[?:?krY>"<ԿoDUx>j?0jAa׿X.fF`s&.N > V6+}̾'Y>o>)}oֿaԑ=\zR%Ͽ}7ԿT9ѿ;׾?ah??P?^?T>6Ox?ha@`?dRXgCA-?;>6AK˾&l?]?RG>v">n?1-6˿2UֿL7~V?|>RG὾r>V>s=?T @~?k>~Dn ]HI8뿁c+r?7??"gFм'*ȿ-H<юgh xn82u&ս>[?땇?PKQ+N?'R&P5qtUb w>N>u鄿0߿7οll _Tr"%I֨b?%t?"E??|?|?q>I?pWxa ξ@_[*1gھ4͆) + [[=3??.X?)`>I4?x񿟗1=xgbë~:E n齺Ͼ_ɿտI\O= 9m ۾UaX ??g>6(>`7?ogZ?t/>l>?㞼VCj> Ax+=Sx,>1RԚǿ}2itɋ=υ?io?'?u=*8+yAcqƤyK6#g̾3%C ]RyrI/vZG+<"% ch ,h:B~ ??-?=b# N<uƔ t6/{=#>>(?M;0T'op־=??>ÿJ.;+G'39E̍=NSoNv勿FMFT"`>?"+`Ӿ,G >J)>W>yJ >|* 2ɿd s=©? ??V&>ڦǔ?l[? >pWUlP>jl?QɆ? >>??4??PVOX1:e88%}-uпcRu"n󯯾|ؿ4I/??-?Ln,0T.9[̒?n@S?K>tĞ'Pb?U #?&sZ=`\F?2zMoa??O >#?? [?Yš>>j9˿Bi/˨hm捿ӹAKC1Xv\?Nο:¾+?@?0?—Sm(.!+Lj:!?M>Ӏ5濬Ef(dg[W(Mf.Ĉ> ?ϊ>t>V>Vvufb>!g>[:꿟FMe{ ŕG=">@_0t+>Ʌ[¾ b標AdF>>On?.?'P?,Mbg>|ȿ"煒mU!*P"D:@̿mJoчQgcsPÿa:~?? @90T?'?Y>R^>c>ÿ9r|ֿ5|E%ۦ-?0?WξWf31>Ԯښ¿C!>i?%E?+g?:d?i?i?`Ug TĤ~m!:RENi??N?R>J>`>ƯT3^i>?!?>hdT?&о>1YMwk.CԷ^[>>4W waE/z=-,YENgҝ@>U>Ŀtd0?lJ?k咼IjXCgsC= P0տ{wJ&?(?.>MEտ̇f?>܈*y(4EwR'; xf2OU +h=?M"a ab̻B9:)L←jnpAg2>cI%Q&?nr? ? v><n#?d'/JS(YſuM??{>eDO WpA}>)e'6/0Sy|CFb> ?-5KV=oG_.[-j3-xq;*{b0=Ҕr=^ݾؿ%f g bm??!k?T???R?(>X=&>TM^A[۾LW4"՜ǖ=\>92=8 /<$?\Wzd9JorCR8JA|$R1}ky*>?sW=y* >>fV r0aH>/BY @=@?? >05=럿9C?>$[v8KP;O2U οEY+ e␿E.JeorRn)_=>?#?_DyZsNGqSڿukwT MPaտ#ǟ$㡿ѤοMÿdg@ {@?tb`9f-5#jYV(7O=z8??;m )i8[doEz2qx'nqeX!0gx?g??>D`$ r:j=QݾV==W>4?n?????w FοٿTֿ{ѿ,d' \].뾡ǼGK??9b1??־nⱽ<%?>jT"Կhs??Go?-?-.?aA?)>,=ZI( ϋIm8;%3N?z/p3H%HO0? ?D?1"G??B78辕¢>F??>C?*-P[F?>?-R?? ?Q>>19/I>Wk/A>eőXʟqBeQ6пJ?@?}?}gx ?J?J1?b9>9?<5?{?&?,{?A7??\?S??'?཯5RBDl=}?)?sC?5?zQ߾i.>`L$>@??")Ϳ~y?b?}'?ud== t?Y?b?;Qe?A?yU??oO@Zl@dH@@?NV?> B-%:Cz>WžJ:>7|?p?{>loF ?d^?LM?e[ >h>lHtGa?1(@i@7@%@m(Z@C@^5@d@a?X??Ĥ?l?> >Q>4>p.? 5?D~? i5ξ={>F:$?{Kc*}@O@7_@Gc@T@f<@>@@na?0??~??۔V'o0 ???bԽc>X|>{ ?|@R@>@7@v9@!5@P@@v@ܩ?1F?]?0#vMM~K=(qkkzFþo>>p()? @>@?q%?+?<Ī?y?M? ;>̒=?E?}1?|Lzfeɾ;>~$>^n$#?]T?$:@+@\=?i?"?q@O@Fm?>&ܿ 8nNs?c$M?`>'cA??f$@8@~@?@@]?@.L@+@?c' rݿx eD> ?|??F>. ]ʓ?&9?U??b?@?@N?~ܾsiz>+ >aļ>pR}A*,b< ?ت?a @m?^S?[??n?_? l?>RN˾hYQ=0>x??w?_?/? _?MSn?>3?h?*?!&?ި?ز?7.2Ȟh?dM?r-?3(Aÿ[ ` {D̿ߵi=;gv_ ⢿j=ˎ:Mf"t8?m=[=:Oc`JͿDz)*$>۠>>+}8!6w#+8N";\?l?M?{?pӁ?1>%:?}?j?2?<>:>JK=6>b?T?i:?x=ΰ=bC{ %ݿ#9 $jwZ~ӲFI?g6?"r?'?̨?ܗ?!F?ƵF>>A=̵?-@X?~t?c4>'t%Ѵ?֡?o???C>!>{>+>x???@iM4\z\1 mRd)oSy;{q'XWc<?뿚W2$?0?qQ $1?1Q Iڿ{EU[&?B?[w>@.&s? 9?j`?FMa:ٿxѿſ0~nn(վ%>:BrнMV?,>c0Կ%%E "u}tj>0??0?|N9>7u!?F:n,Fo-6>VQf?9?>U⋿Gx0bxe cxҾ(1Yp[Ӆ>+?Xt^p׾2ۿ.,~GyJ?E>pg/?K?)5ڞ?@ @諸>, s>T 4¿b,gnFQTw 3>E ?D?'a˿ிQ 4>(KC+ ᱓ >9+?$>u=f ÿF}@etvzI9H?Hn? 0?0>68+1=?6@7@28?ZEI-ſ2㔿=o_*VϾ:(Ձ6nt&d=.Tݡ휂)&G<?E86mG)Jv쿞盿7=ԿkR3pcUHԾc'4<\,>f?!V@>q).Vƿr"rw- (I)ܿܿ$Vp=PW> {l,w-2ϻ.H5> BӿN +ʂveS098z3-:]!տ3˿(#G5Vȗd?7@\@~%>#ÿ[>sV>}վLſn͏ҿOο^{2'=fqQ$߾近 'l8'ed{] }1Nֿ Wgo!ZFu̿ʋG 㶿c?dVE"??ɸ?96>,΋>6W?AydNaO( ľ86%K.fԅK>99? ]>&>UrƼF.>!=+O#Ժ{ +=пB7m:'ؽ,G'OHп?-trпdʿkee6?Y~1?~&`($QZ瞿rtnn Ŀ1̾1U\3Vrqg?Lvx!נ5 ZG>wQ.=ܾ=ڍw8'T'=>R$>p?/4>K@튿EF':;(m?(ʀQ}?>[>^]?~ϿM뿔+_ͿԼԿэn>Dk51 y~=<<=$?:><8Mjֆm]>[2ؿ} S??k?^? Xv2n9cԗ>=.r&eUP`uQ!f\t*EOŪ ?cDݙRU"*!>KO-?>?l>)=d̿ S?gX?GM>4bV=?B‰?欸>/4U=%!enr1yۿ)Q-HB?U?c}?е>Lm >>m8NFz=am޾,8 PQ[CBT霿ǵ>?_??Rm?ߑ?pW?"6Q(u;=Wy0F{Ae=/bch4c% Pwɾ2 A ῇ Ù F>5L?> ?:?jg??z)Y^qӿ迿[LL:Ϫ;E7;ϳ>)#2+?K=?R<(&acSOUg>=݆̽/3:j9k 1R]-:пD$gs#C&>4?+?E?ݬ?x%?I\8`Oޡ5|T|oo0H6?1 ?8??p&? ;ļ 4twܿ'&9>p{C?=.>1CsӠ>D>pR^>^yfL7տ}ſ;VϣÄ.>6.H?B>NG&sDޠ,᾿G> >?o?3V=սKF?{9Gticau`7 >\μr>y:>ɔN0Կw3ξ5Qľf>,Ue]ٓFKP)e>r>5 jm뭿 q^>qv=hҾ>fwQ<).#߿]bB Y: ¿KϿ5J~fX ]ݿb"ÿ 7>6?+?`?e$'ſ *<Ҧj=|G#?$O4нr8?? k?Pj>lS콹R>ῇ7HK 9,A>?ur!ɿ9눾z>,hEyqͿyH Hb$-?@Oc?䳽+};*#͘E横EEu&ϙ>5??O>9q?G?V&?5 FDk)(X>I!KQ=!?+? ="0|+ʘeYV»p<]>?8>ϣY&@ĭp˾>̾p6 6햿ֿǡ>??1>Iz<'@>52liy1?a0'Ѿ1=ѿ0ܿ憎<:>?-O~i*3*ӬB="C*?^>Ph@vM,d[޾pHwbD>eȪ *ʿU>VR>jV-%΍οĿD>Z4@?@c?:`E& >̲>:Df#oDL' ΈUIZieu3? /Gܿ^3tmE Ã?BQg洡nPPqV[2ʡ8o#>ы04 Sv=Є?WQsĮeGO j.?D@jk?E=У;,SMKREkTK/^{36cr͕vl2SE)w P~?\"ؑڲ^eNIǿvzsi?0??K>vS=ڲ(>۷G;;?0>>}9 (8 1U|F&?6/??1>WBc *rrr5gnHxO.AqR鿳r؄&xl4V901B>>G=j;&ZcqYmVCYi?#=?qñNjF"ܾ`#(Aտ 4)-9)ѿƵx.Hno>\͜=UQiÄ}>bԡ~6*ׂMC$O?7\ek7=8Y[{_Kƃ'P8Zy?Ⱦu:oR== =ݬ{8~qk$=y? @o>؛kAE?\Ⱦ5*FWd;p>pxَ.1`<>&Opwɽ,yξ!#kL?>?: Q׿]<˿ +afuEM VTg-â?2?xf?}=[]0t>҅ SLi@s?˿F8֔FOKQT؉P?лkOGqV1ڱ=68?>$JqtZZu>q;A=>j8?8c ]#edﰿc*!xſt* @ ͿZNr:iTuUE}u?O??@I?1 ?C=>'?Ƙ?p >>$:?s>E>Pl0?ʿʿbҍͿYſq+O¿nOhſrKc5aX!d̿ر˿u)?7?$?+4?)?R<=k>Ke???~??75>g? kd[5D?o4ܾoĿb!y-C b7x Y@=w;=<>X5p,|(?g? 9?oZ?S=? >S?a??! @w?VD????)B]6?}?E>XE+Eb7@bPb%J[؄\̽>)?.D.?} ??k ??M>gI>???\]??bS?1?}?B>-@/,@+G?)f?1}?M?I:\=ľ>> ?G?E? })3R o xdHҾ/=8Z >k?z?E?-Sk>.'?3@ ?Vr?",~>?@FJ?e?z@@S?lG @@q1@ZN@@>=;>-=>kp>?Q?Vv?}>>hF^ o?I?U@n?|)>ZȽ?W?@ID@ @jF@¿@s@F@L @a?3?1?ۊ?-!?> @?/O?>CZ ;?/?k?#?E;@o[>̽ Ѿԁ/?*@@@-+@όW@,E@$@@T @yB?>g;˿ ݿEgU<?-xl?6)?)F3g>|=UX<?@k@m]@O?Y>꜃?L@="@E?v>ܷ=rst=ru>r H>ȗN?%>w? t? ?L-@(@w?G> @W+@+@?+G?ߡS>sMx;{AFLl>ל|{>fL?V?|?!?ѭ?@F@?{{?+i:?P)m !>;l>Qd z˾A9&ZTxE>.\?>cǃ=9?x?-?:7?ɔ?횜??Y>ޑ>-*4=?*{N;Gr!쟈?`#??Z>߼?l?B?+ ?Vg?'?`">R{ýN>t᣽+Ⱥ5]o>I>7?e?ʆ??8@>=?y?c2>=<>>=>>~0?{ؙ??Il>?9D# U=P??u@eW?[?A?w?>#>S38'Gz ^!(9'|=9E>;>#>DAs3)ٳ8&5ؿ2!G63]cǿ.ζ> 98\=e"%y=J?èzکb 贿ZT߿vݿ//OYG0/q?;>ɥ>1>C> YUn7?+?V?B]d P޿uF3>"˽%F?e????5z>d5'5hOQ7-=h\r>Ć?^?-?F?=}=򼛚bmJL󾠼a>|= ;Pw$Ͻ563Zy퀿rt=j־Zj=xX>/k1ʿ{&hϹ=*Y >??5<WhTm\ +꿫p*,l#9x' ?&" esVTtԎì1GK5mԿPbc_㾑zeh0:vtJEHbO6־Ԅ>Gҿ ޾E=S=tu^#̿Xʿe(#˿#;lF⪾/₿rпIo<(K:S5X(srѿ/'H%;zB^x,?ٿ/a"y?Y;GGC9 /U8qGOJ ?E>1 >| kQp?*%,F(=%Ϳ_\cc^ҽQF}io=>><3?.uPǾEC>d˘?'I꺽C>,#]j= > >? ?;2eFÿq&=NaVK9wL߾㸾vYXݿ|ʿ}G&ٍ>2=?\ 1;L9O x?0>$^+w?hI?&?z@w?Pt>0F?>=7:sN!7:{񚸿Wõn.(ӻ ]ſ}LJKWq?sMK8f俖ֿL ޗ=+? >qm1 fݿоOc>9>j@%{Կ= =D?6???=xCW# oUn';~iH@~^C'!OѾ,`Dv$8ֿ4(cC0$G$k&=MN#)4 >?1}YaSQFGʶ3ۿ^ؿ5K#P\>Q?[?>$t^k徏༽uPhʿп+ؾo[j1 >ȿ8Ŀ-nĤWd87L.e" gIwGwy^'>N\`C$ƿHA?K[?>'R^Ɛӿ&+̿\Ŀ`V翼7 \[1 ]=$޼h16}>m ?~F?kE>! KVg"9\ark +II h yj*6X?q=r3gfDm_NWٿ c{?1=c?|!=Tؾg̏Xу0ƿaٿ#⿘}ɿQƥIgau5X6?O> Ͼ,Q˾S>$>X>t?!Lt߄`:!_6-d,1+s?>B<)-b灿kF8?$.pJ sNf4$#8='{f|$E=ѿM$)Eɾ!ۥy />Ik\Hu8>?>ŗ5W ?ynI?g?꡾P۷fV+R<);RƑ3?I?8>zX=TD>L5Y>>rѾ+>'0%@R>sM4 ,?_2uw>q=$׃>ƍW ؁ g4ÿ><ʿ0hV¾j5w1>[??Rf>AE?s?uT?ξvR]=t4v|&kÿ޿ zӂč>zm?k>n˾ %Q sv?̈3?~˿cdLª<>p=c ULlߑ?B\>!Cs>>S"R|Yf 0U5ӿҿ􆯿r:!En?y?`S>GzipH??K$ӐR%*'*?>UIUZ>i? >q>>1()Ǒ 係V"\5˻Tv/-ەXFu >95 ǿp;]E!SyiYCsbɿ(e轿&rOX3>>\u)X>#y >vӾ&t:K׾gv_뾊z>gM=Q>ܨ<Aq6m 0_u塿'rlwZ'4fISZ);p̯)dT|Ŀ Zp[)^cv?_>hoǾ"N==ѰR-ԾgD􋾕ԧgUI >>.)K6,i>Ղ6u{jX|wҾ͓\Z9kqk^Igp=CQb=ӌ>Yt-f f 'پ y LSl!8D4>3>T>}R>?B쾷~R#tk)rd>ryl=>ўckT:Z?ʤ)!i6Pᶯ p>ˠizJSZ{hpڿgYtK>d6p: >'(IF8 ?Ahk?JPCъLqI׿jn3uE*!^9񚚿ۂ_+?^Q ?'$]}%ڠڿEwzÿxɩ?z4=Կc̾C$1Pch?7>Pʿ1` pv3^7M?٦?p?>?\徝U7"Y[2ο|j=  ړ_hݿƿ~eZ$X4 Ɋ>?b?? < ;VBYsЯE'>[\ɿ2?*r1ꇿe:;??ʾEQ. ?PT?{G?F??t?#{yeI7M3ۿ_F1oxyK2 ?!6#,1Ͼ=>ہ>ES?s{D 3xvԿ̿#.H@ %`1¿4羸&3%kaA?& >&d> @-=Sf?? ?6=F@>\ULڿn;:.(6F9scy-Y/k<b輿G7<0>#?SM>yx%)9K*P῁ nNc´M}{ !=|%οA7{ˌuzKiD=??>qC]=/Ղ?? ?eoy?F>۸B>:/PTH6Nп5ǿExK yٸTك-u>ʿ{s>)S̈[ӽ3'>=vs1K[ѡoddÿl1{qbRiIpq>9l>T?ؑs?ݲӿXgf> ?!t?h??u'@?j>>q4?wRlֿҔEqBZJP>GN dw{*G>1>LxT"X?H׾guDkF,V, M ɿ"E&VV(ݿ E}?VK?_Q?27=piH?^*?۫ T&g??)W(?x?L?\&]п=jr3{X۪7-K"sggrK,E0-F14{H1K@UP>͇R3=$Nl N>iwiWˀeim>p??7D?%'=xr%߿c]:οaGJu1}!/B&\V?VP8?>7TdZ1?=?TM=%/>捾)\!5ʿ:.$u E'U6dDٿqcݿ5ſ+ÿP?&}??F ,2??gg>8">>cb?A?:t?G>m\(K^#NE4LkR&"MݿI Tn{Yy+? tX>???6>=JOF>6=B* *=nB?"?;|?7?L%? JGL;1,62콙'οie&ƿu;0.="ҽg3ſ7j ?2?4?5>>n>fi>*>>?Ⱦ>ޔ`?pǂ?S!?iZ ?=k6_>(|?sk?J=?+Ӏ5>:O::8|/=>>ULp>>>S>kM>M>4>B[Y?IԦ?5 ?}>#>V?&7?G??b??w@c????Y?]=,;mV\5o=z;5?A=C^=N ?V>8> ]?FXt?c/?|?=?f?#j5?W =?-?s??;?@Fn? @K5@1@@c?)N>]<c>T<>).?D:e?v}>nU=!8>?z ?|?Y?=?@hC>gN2>*??t?o?j??@Z@)?7??{ d? >pw?*n>ý=>ǽ1*p$=*>}>>Z? S?Uo?ܩ?9?B>r? ?G?b???O?]?e??*?c]?w>p>ϧAS>lD񩿭:xc>,?#@Ho@@ǹ?<&h@>^Q?9V?|?3??:@6?pj2?_?M?^?w?Ag"?U8XR{D>u?޴?$?V?s?a?=?]>?G??@ʇ?C>>?l?)b?6?ۯ&}=> C@? }>D)aNd𡫿sʾrA?e?Pt2?k?=?Jt @]??9>)#@@?Q9?->%T?T>G>t?54L>Ѡ&饿%n>L>7??Ƹ@H@.@k?+@N_9@1?cھ\]?\?#<?M$?>K>ĻzӍA3??SG?W>?; @q)@=Q@?坿)h|>?VR?F???R8?6>CξQI?3[??>m.>QEȾk7 >=nC?D"? ?|t!?#?Gk @\?Ⱦx/e >+#9?)+??Ǜ? ]>x>eB?/?ɇ?ў>m ?g?)?䝨=^?)R?!O>lZ>cX?K9IQu?i?z> )?7 Q AD6?!>WWD%!ѿ+Cv:>ga*H2⾻E>`e?:? 2@9yZfDj_.9!G??#a?;͇a6>h>n??٠>:C޻$O.긾S~`2 ɿuH"G??|???(Q?RP>OʾO>ykHgܽ οY(տV Dk?}?4??w??.IG?y?'ҿH~J5ٿȬ޿1ib΄ hȒGoͿIO>u?E?>z<?:ɾտr#ɬOjHQqؾ8dx>=>"? d&;ÙZ5{қ(A^_)YA#ݑ悿ȃCY˚eX߿#~d $S=Y?1Ϥ?H?˟ 3fVLDU vͿ>=*O<\7uH>?9ihVᆴ\ꙿ1L8L}1nF+ؾ+=~0|l C>_t>cY?D??V>?v:P +nӜ p?>Eil{`WKĿt{>sZ=cë3 _>(?4j?$=~hw_кl/&P? ~&?I\I$u^NȿbkluJ0ܛ/"Dt&?r??kŭ?r>z>8{?m?Z?8vBƇ>a?>n?=d|?^ǔ4Hl8Vp??C>weͿƳ۾~9??cW?kZ Hǿ%wyjG{l 0~^F>2?p?V"?g>`'=ak/> g=%Vc}>=] HN)?8lϾ5+^ȿ$3О"U4Ⱦg3|CrVqZ|#nәh=qyl=wC%ݽ)C???3f?>a, i8RGqm?ӵ??屓M)V)+M`@6#|'"=1P:Q۾ >E;_ S9 迡_>ѿ0P>+0`eW0?C?;=o˿~&WRX>.?r@]? > /f)?ݚ?^%^gE[ÿrf/ؿ>ӿ7+ pҿR'tM`>3?>|>W8Խ=_򒿆4_m X~E" @'>L+g&&Sd!n[=;i=X¸>n!?z>>@by+˸Rq Zk9hϛ]{˿k8v.>fq?v?9D?V${պc)؇U N-,\QeEM-ޖ| /e5m? ־͚ CϽY̾-5>)ldUC޿{пſe >v_ Ǿ¿L¿ȿR:S"AZ?\?#>,P>?To?C.y=e/?o?Tl?9+?f&?k$\Ywoٿ'mg 9׾>}$E?^?X??T摒 Ȍ%>a޼ZWeh8b?W\4?2q 8߾ƱYT ޿̿Hzdr%(>0=׾Иܢ<=/ZU>@??m}¿"KNݔ:Ŀl>?!>#ƿֶA$BK͙ۿU*οCUZhl>/>SN׿c5$޼lƿӴ_RL`. 鿴]3A?>p>Q=>hB?iKŘ?ݯ?&?y>>$v?|?<>}-8cԴ?_? ? V?D> )?ĿM4 :5ֿe;);L99 = 7TEq?78=z7p+2ǿYÿA$pOI>!?2xd?t? ?>_??~ϼ4k’?x@>?\>sFQ>P?>i?*Ķ?=h'r(-ݚKXS[cmȨ*(1ֹ( zA>?3U@ѿYЬ r#:A6?䨾%^/r@Ϳ}]??>/?t̼-R辗 o>Se? 8P\gVLd$4[5?C'2?^?6ȿ`R6;T῔Nڿbp3ο(ȿO.>Vb-Dտ OY{'ǼKٰXJv_\rB'\Ul>@iZeȿ7L !7>n}?t3?1fU.iͿ''&f}ɿwKhPI>Y/?t?ۧ??N,?d#^\ [s Lp^]*3>; k u/\ yE0 -%r/F\2%( 0"Zf$ȔNbCRdl 3*οʔ# x? ?~a*!8gͿ^?Eފ>]g0?Q%= >.e>vc8>₾xnh,ɿp@VOcZ1}K8䭿c.忦&{)hm80>;e:ʰq {8'0Ln] > ?-)vp;+,2 !"x>}T/ MÿrAn??Kvx;?ٿ?~>w7VPUA>ᄍ2tBf#+< >K[?п묙K03>;$7!Cct~?@ń?>6%gL߆rSEBտ w4XBпR¿U 0zOpvV$ϿC6r>>> E?ZH?,⺿S_B?x>T=@ѾG6=p-ֿ/ÿh;Jt>;67Ί=sDXqmYMԦGO>)??s?`L}ABVyI߿4I#B,(ہ,sIƿ ſHn>[? >$?D?ѾmؿsjEqDl2F{lY1jzv:LSD&Y¿֔FRMzrF˾&?r>,!=1?Pn?}]Q.36jc -U忢GaLo݈U@TmkBw!`>Ca??1?+Q?)́F A/ο=ϾO=gu=r t=TO*5c& eq俿h4H$%:#U? ?L?4>pv?+%N?$P1?>/?pW?HD ?.@Aۿ<ɵQD,vvQ 0ab>?G־?b? >ܼ XP=?M?}>?:%~P5}R]eѥK˿[TfiPqfOv#R)+p=2> Ae8?Kw?4@|?h?5z?aB?0UE?㚓? #?)-? o?cp;grlXt9C7cGkÇQ`P&{\>>G>b!?d@뗾9RAq>4COwԾ̲FaLMdѿ驿ݢ)??9Z|?~:E@`@+??J>/Qa?(>ս4$[xZ [ [Z(=G UiC5=!WíR:zS¿(1;EjJ. 6+Kw뿩 -Sw>tXa?!0m$.|[9p7?zfr??3Ս>o>q%;F~Zj $ǀ>45?4>D{S>w>@ >?!I>p<ſ}ƿW"^ȿkb5u)Pjݿ䐿X#T3@¿cvG?@ 0>q7p>g 9/G#= _9%6>?̹?W?2q>^7G`1 } Rx眿'`,}=njdh?p?Q*> >Hp? ؍?0?*2?^>?Ӧ*?g> ƒ= I I) !c@S^f'/ҿ!ξuc?G??2;RM׾A,[? A}?M?=;?=|:Qk/?>9ʶ}lvۙI!Yrض2.h H= O߿bѿħϾڔ>7=¾4.;2",%>> *>MM?>b?[?p?uľOk"?~?S ?1Yc(o/t(>>F>ɿ>Ͼ[8U Z7D08 MW|=d|n0ȱn `r>WJ?`S?K??v)?[??`"??`>d?n,@0#(@3?.E<5()*> >w?=|>H1o>i|𾞂پp>ŀ>>m>(8uz3>?Y?%?@@%?>H=1?5C@]/@?n>(۾=>77?"C >ƾB>?s?>U?>>?B?#?ԟ?g ?W? ?ǝ>RmUHR&`? @[J%@mV? )?1>b 8=mL㾶> >'?V?@?n?i??C? >/E=?= @N` @Y?޳?",6?]$N28>3?4>{}%?И?{&?Ҩ?B??Z>??L?_??Z?x>\Q>U?3?s$@d}-@S8@X@$?Ɉ?ZzؑPv뽵 >s?>^N?@@0?6%׿`>$?A?#?_?)> 5>*Y?i#?5(@??͢?&9@Pp1,"k???Sto?A ?:?g<P?C)? >] >?\%??ޡ?N?o;"@ -@J?>,=Pߛ>>>%U?FU>]0Y?3@@O @?]%@"@M?{? 9?+?H >>}R>e *>ڱ5??r?X?:?,@GR>6گ_TY?ˎ?E?mMo?? ?Vȉ?b ?1:>wGT??;?Yʿ[?[?ޯȾEc9l=ѫ>} =?Xy?gC?pȁ?@'>?5??#?>--?=ۯ>??o?>1 ?_tk)"_'Va?S:a>Z7Mž˲8y;fw>jF>p~-$ؼUi̾jYx\Fο!A+䆿q?u?H?14?f_ܱ>R'qu>eSr<o4[c /B+v$̿տnſު0}0#]xU!?<(?ė?:?iv?i?G)>쁾4 t)/?>=ulz>}>ѥbֿ%}7KC[Cu`)տpzD?S>M7m_C?=@>"%??rt?Y?Y ?'>+O< @??>nA >>,>a4>4ÿ4;8;׿Z^ ?M?>3_M;$tv??*>jI[>(?z!?O?~k>ǖo?>O>ȿx-տ!EC%%)OܿȮR\ }^OO?xq>9T>!?Է"_%1}n)ACqޠſ ÿx?oy)]}g 1꿶,,9-OgI=rio3':9'?Fn?Ϙ?@?h2@d @b? @6i?>WS>1??hy zx5f`p >t?iH ޿#jG^>O5><ɿnD I׿{-aܙ>b$ykGLJݰٿ.k׽=)#׿>vq?q?n?BU?J?|7??S=S=>$o?e>(?\>K>;e?)+?367Dc2Ϡ伆΂ e?o?WcG>.BI>yLf ^rg(9=.~(?U?P??H>5>NR?>O-]>? I>9Ѿe[X<uտ3wI]tꁿ^ +)ЎvF 7!Zտ5ٿɾ /lkȿrʾF>մA?P^?N?_?!>3> @ pVx=v+??>!X¿1ۧ}ȿ:¿?q4"  ( RտxjUgwSt>?߃> ?3Ο>%`ʿj 忷Zõ?v?l?QVJ?g? ?.?>oY:#N>3;?.F?&%bƿ߿7M* W%-?H_`>9?{?@{gkXŊl¿Gֿֈb_־(񿞦࿥>?߳?< l?X>?j?m0!yQä>Bǂ@JJ NҿxŤz?Z?F0L=JQO?V??'?,> x7:{݉]NÿG[ U6 +쑿wpޞ϶GwͿ5aO?E9?!>.Cμ_|?[pm?^,ۿuN\؝ s!K;Za\RC{z>""?6@,?=ʙ?ak?+?- @8} @?N/?$o }&i+俈-Pz¾5m=8<=N/P?Y_e?֓?0e?+(>L¹qU =[-ne,jT̾iݿ`ҽ>>A?>rJ>˒><6]?/? @?6? ?f?X@@?  ?9y9>OhﵿRj7>C'A?m?ou?k?s?"7>3fӿ *VN0?;>U&Ӿ=&@`=mJ=6ȿOP6̾窿 Ղ>U)?-}?b?'j??G?m=? @|?f?9=>u6???m1K>=擾pG̿AA̿{Ϡ$j"ryϿʉM_ ' ýdq?iߘ ! '5IJÿ,-???X?h??@ @U@jc@el@'@<@t@L?B?Ǹ> mI& ))b2?lp>v@x{K+'U7(׽lcñD> B:Ͼ,"V2;uX?;_>9QsԾL>%?Fn2?.fT?̂?@f@'En@9@` @U???A@#X?6?B(Q>s还c2ib>j?b+ľH@Ln93x_'A%%Ew*?-mw?51w>)ǿlXX\v>7o?l`?`?,? >>/?F?'?rq<?Y?@0b@wJ?\ H?eL??-?c1~:Q>ܽf:??y?/>>|~:&οjvZ끿430Wmr͵Z^c?վF>> ϽY) 6HT =>>غ>kEX(?G?S?3B?Z?v?[>B>BѾ̾࿓ѿZpr?C?q??l?΋d?q>՚ǾϿtF῱0,nп2YSj3{5-ӿ5h8䄫r~?BQ@/b0xlIs 66??3>Nk,?/1? 3?O??Z(U?5\r>D8W>l?x>>G?Q?>[>DQ> ;&*\wZx6̜{@= %8g'zz LڿAc ??>Y .ǿAп`9dۿհ+Fk d?v?g 7 Z>>ki9-&?]iX?G>[WU!5?6r?G.?>ի?x??Q=?O>T>1?j%? &~Ϳ<0ѿ+Vkҿs'hЏ^ ]9=y?kkN'4,P>si&&*-D8pw"?A?Q پg!9?hdV>DXSہ=P?˯> >?=?s>j=bx>j ?D2?R?4>@h%W(†C0.4̿:ۿ!Br+[;! Y􉿖#P`C=?.[xGzz>>?> ik _˺Wf#F(L[&?+d=?tt = q>P ?g~?T~?E z=@Oj=8>L;?Ң?Ӑ??ZU?8#5>TqK,l_R,Ѿ᏿Z? ے>뗿NB=+=U=m_`1Y>ـjr;KȽnAzӫ 砾L>O>/W]????z®=; m>)푾5u2ſ[?ٞ????ʖ">61I[lq6oǡ;"@j<3o>h8?]?e=3@N\^셿 ^>?a,?3>5о*>f>\ji??(??®>(S} +F{/?jr?H?01?X52z H<*?G;?[Mh4To# AlO8)P'>|͋?5غ??4Ń??lxv>VF?L? F>ʾ DnBJ%?Hƛ>)?=>C=?/o?76?0~>)=K9hHDȽm=%DAux@ \ؾqLtTӿ 'Htx> >.)IӾ쵿X<;ھX~3>>?e>e=랱=;!??ا>. Ed?]?2E?S?^>Зz>W???}^><>(=; k]iT#Z<:-'쀿fn mc_ћO+>WU>J7m^@ J>/>>0?0Vļ>&=L&=QK3=:?[???Ա?<>d8>>?T-?zM5&iꤢc wƃYf>qS>|f=_c=v>~>VO>j颿->>~S?c¼⚿_k+I,V]eh =ؾ>"?\?A>wȾW?6?>#??<:&^;4ҿ߄xӿicCտi3>@ཫPE꾋\V4>’>fO?H?{M?AL?4 =?@>it9??"m?'Û>#90ڍ,ۧ;ؿ) "dɿ8ݿNԿD2ݿsz?? >E=҉ 5!??:ؖ?[>=gw꣋ Yyr!ڿ0:@~3kgܿw*Fݿ{1?? =1-;VP9\=p\>?g????]???V%>>2kJ"??>= 2վu=ĉ=؃.aW)L?>-{DJS݄ko$>?C?\?ϐ?$Z?4>0 셾Σut?y@?. @?¼Ld: ?FoL?TQ>b<_{+c=>:8}2ʴi+=Z >l?@ @џ??2?5cQ NFg (>U@@<ã?gnBsٽO?[> ̌>7?S?W({?~>Pe>=v?!@"@_?@j@q?y4> .ϴ$c!>ï?1??O1?zN>d2Y,6z[Y?>?@}?@j;@@ͨ?2=}w P3=????æ> ejƗl-?[??T? ???䑚?W?`?"??>@9}?Af?U? ?E+A7Y>gO?8;@ @? SU?2z[n>}m>0DZ>?o&F?no?:r?%l>q>>Y,>M?C@B@v@vl:=Dh0>p a=k?։?T^>2%?\@???W#?}4?p?'?@2}@<3@XC@x?=??0? ~7F g>i??=Y??흾?Z@?0Ʀ?7r?˾??/?>ro?f@jф?㲾^UH?/n???Z? ޼?nA?sZ@ @! >3:?"??>v?Qlb?pT?O?z@o??(Ӏ?Bga c>O?s Z???%?D g?IT?I@-?51?>x?ʎ?(?V. @o\?զ]j?]?]@3\?`?8???9?s?>Eʌ?j**>(?tlx?rcW ヌd$?=U/TXsW?sm?~>ॾ|f@ZI[Fa?V??r?6D>\<φվrΘ>+?mM9ݾ~WZ<3=P sbiȿY¿Ų@ p<~5?hg?币#?s?1#?K%?r?qu?1? E?Is>,f=U? ~>(~QW:3>>A; ȨwEÿ+= t?^?c3?&>r[@6?OX?[?{? ?IJ?J5)?C>X_??"|?ۉ2= ?o>P >3~Ϯ>?vhPпWEp1yο 6&z<v k?t?,?H>>Z%+:H+@@@~@6??EP?-p??/?x?ލc6ϡ>3K>>Hf>0ľ>飿¿g5<˧(g\^&$' AпD:vcҧ1Q䉿t ??- @1@&?S>?m @c&@Z,??d!?:>9}vZ-IӾJ~kϿ0dBEܿ}^ &g YnHW2)/ǿ]S5韾;KVO>n{?"? ??m?r?ں@t]@}Ɠ?B?_l?? Ҿ.W2j7ʞ9۽S?u bz|H̿pƿ0%3Nֿ=ƿm8sn>![M~k)0Pr0?:_?%=Iy(>q<[?G?I?#Ֆ?7j=RNI5brq}御HmUU@&MIe~.rʿe|> ~߾>a?``b? ?7>bC?V$?F>=xЙ濤ɿtm+޿~οV雿+No ^ ῙL ]Nщv9Nq>ov>>W<о{s4^}>>>r->>Ĕ?ז?+@?K?Tk>ZSq$vе!@ǿ0YO)S%¿HU?r?V!N?{̹>c?*>4D? ?ƛ?"CV=ή= ݽ)85¿D(q޿ܠQMm(m =5<2S^2SW¿ok;ι?~W?$k>}?G;l7pޟ5)@>?Ǘ<T*a`)H:7>L?>3hMH?Zu>Q>^H kNoBCn{B9Bc?(??P?0? >0??.?uN>6ed!⿬*ݴ= <+o ?ϡ?IM?G???C>ɠt' >V>V? U>((֛+">b.nq \ЂBLG^"$=7┡mrKŽj??m?Bz,%?{?(F?c*ܿ5~|ni!k#Rˡ?)@'@S?LL;? ?7O|oѿKS0Ӿ=j> 澾nΝ>Ph/Plڏ )>Ԣ-?Pw޾L=3*;r4eϿ4u'>W?-??3>pП>n?a?>6?SC?rQ?ZJ=~}GG?n?k?@0z??r?G?b0 ?Bb`X}uJ>n ԉObL,?d?:8AReľȿ :п/} >>){>??@?u)?oS~>\>Z=(?Ͷ?Ō?^?9?=@(e@̫0@#N@^b@r+@P?y??Y?P?쾋]ÿ9,+A3&Yl1u;;cl:" ""/0~>?;?=TKXsMהal >:? Vӵ'=p>:i?jEy˛$@?S? `@? @5@B@G@ ]@ʂk@*@S?e?]?s?.{?b¾}˿|Q^]t zCA#{]X$>8?(p?8>V$,#w[84bI:>= ?!77>6L=^̈>@ >@2>?>>*??W@+2@HX@AA@3@!'4@h#@?ɤ?С?P?C??Z;kcwľ jҿ#ǿ3!mFeq"==_<Z5@bunɴ,ͿyH訾ն>'X?,D9sO.?o@ @9C?(O?C(?7u? ??I??U@??uB?M> >`T>Ά񆷿!6?t?OY?99'${-aԾ1t {ۼPp)KMWJ[4P'_ifUVJ:?=Q+8?h5?X>@PݱS松?/??'? ?$??[*;J3џ1>=-?? m!_=>}m?$t:/ճ@Q5o8[ ܿ 5RO#=>:>x>OZ>();+JE>>t?1[w?T??+u???Zr?iӫ?+!?u1]~y?=P)?>%:M۠N.Oᵿ?K>??73>xVgq@P:k^G޾hp(~ABb O ^ dhx?>RA"5gdc>>>?P?:Z?`?B?x>h_i?B?OZ?>qʹe? 麭*zE&B+00ӽG?V>>}ٞum[g\H封xEտI"D)XQXV?:I' >ձ>'뚿 ߾<?}?0~?c?D??Tg<'>??&?G>>f줾C`5e}ʗ3?"D̻{?8D??K?p6>:Kq.*&r]뻐?"8ÿ'߿R0t[I u]bUEڿDf@MQ0?K>雱>z~潺ɾG@>8?7 i?3ty?N>>ن>C~>V?"K?oh>RL>Tي>b?=oJ)ž'fD>?B=?SV/?eh?Ƈ?H-1?1^]Ŀ/}˾2zNX*kݿM7<7M&b`ʷ> =Y<^?!??;X?Xw?>/>R=n>6b)?>>?+=7jlES>3;>6A6*A}۾P[Ef(-T>*}??>$?E?@5>ӭ1=̾)~ݿ9<⓿,UPKK>>i?E >]& +w1F]=%H+5?\?ft<ݾR?S??:8?O? ??%.lEE}D=z>`_>>?"?ݘ?p?F@kS @?V">$Ik(N=155?ga?wP?>W Q7訿5( 3k>>ޭ>m>$?>8?S>Ӿ#ξem>Ț?g?Xb??ao@|x?W_>"Adh'@>@Ԫ?O?)>=U z>v? >:#ſ]sVۿrZK??5 ?S/?f!)?&]"?x??y9?̼?[Y(D??Me? P?7`<sj-9>=u?S?>+>R*= 6V$?C@!@D=@q @Ay?EvͺnyHZpJ??i?:? ->/" Q0%xutUYn+?p1>>A>g?k@d?,>i{׽^??@>ѫAÆ9lAG"+輬A;t"W@:5@(q?^?|?w>r=!/u?>oLJ-H!ڰH~񫽸+s(S@$_/&K=_?7?׺?Ug?w ?*?"+? 'J͉I,Ql..TC30 ¿W 6 CտR-J$-?%4?+ 8־Ah)YFE?v?4?[)?MQ?SC?r?ܪ?>?>4T,> =g[ XXɿoB0ʿ-А[I%" Z > d=쌾_'߲ڏм8???X?t @}?i=.>JY>?Ӧ?՛>Np7c=Ś?￾꒿G &ͧ`b=l>Rh>\?7!?+??&?o?S?B;?I???ąG>`}> =&1>>=#ȿ_>su:qr,H_?l?`?T\>BY#>n8?>>}Q? s??gk?y??zE=M$#yFԝ?Uƌ?q>S 5KMF4# >-tz ѐu L><2??o?Y#'=I}??M@=z$@ @b?a?ý:24~N @?B?>0$&h b?].L$̖=\1>9?k?a>LUCپM?a @>@dT9@!"@e@?&4IYſ4:̅=R?OBd=6>>1?kٵ;E?Bem>Dz?P4@?j?^J?%?ws(>R׿ƿ 6? ?H?&Y ?S?ȸ?h?9?&?sq?Ct?5?7g>%=b?`?QZ!(?'?ھ拿V- 6??{m?:B|=J?lE:2?>>?ہ?uo>3 %(^>I?k=I:>2x?}?T=>4?u?V?^|>!>W??L?n@n?`?? >5d$>N>ڐ6S$Za?Ǧ?҈?S?M?&mo'ʍw)?]?:g? ?+JV=b=$?="?Խ?S?a"?\?C2W?,qƾ]="F??Ǒ=8Fq<8t>a?Y?S??Ո?Mӱla?'H?B??D?r"WV>`M>sm?脸?E?k?h?ј?)C?,?`>j[?+?t1+p>Ⅶ?A?>>{Q? ?5?l?Gv?U%??a>??>Hut<̽3??_?<=w,辏"zR>>8O½Q;価+ >/"?8?.?g޽ڈ??) ]?N?_"?$Q4B' 'R?^0@uG@S@}V?=h1W=,?mV?Q ?M/6?$H?L ?H?=2ݿݿ2@WrMýJ>樽Ͻ#=SWп*׿[Qտ;y$&d?0>?rh?>8@)@ @s@@7 @;6?8?H ?=??M?yʾ>AܼlH(ӿo¿ckJ.+-|JW𴟿cѾ}Ltz"lN3xIN>c?#?F>ua F@)3n@2@8?V?l@#@?U !n4>m?>T ` {r23nv9 Ͽi(|VfпnKVh*쿮]˾?W>N^;y4 ⌿cQ$>?@!E@[?e)(2@t"@i?~0h0<=>%K5^M"@:u׿3 n6߾ɣ??fģݔ˿j 7"-r`@؇>#>?-?_?1O,>=L>+>?w@!j?3?h׽]?[?U> a6#k^Ul\35 ;"hPèVҸR Ŏ??JV?`\=D<_vQNٽk_.uũׄX??tP?|?Zſ" >kx?:'??0@m?>8A< >D ?:T`ѵ*(v4lAY>_$ǿvls&XnIUξuۉ> m!b졿˾1E>W0?S4 YŶK>W'={>foB\Xꈾ>F?KW?h>@U?/d>gB8>>w=E/4пQO9 m'Xq/K|ȿrVUQ(樿HM"U?SL? | ?axϾwbv]*0jv7!>۫=;>Rg?@Z'?hV? ? /?LM=IL >9W޿dտ:sX= ??<}zDK I5#/'߾M\5޿gls;|?,??A>:@>]T>|E=ž >Ymv&@=>!# 0?@@ ?>?ʆ>(n?gZ??/h>h?t>` #MLN$əV%agY4j? ?'?iW?gɬ?G?X ?<??p[?%>ƾM. ?3v @(?^aAEw`g54ː??bv>>Ģ>&lYv]=NAA?">`w8, ׿b'ֿEgE`RlcsZ鶼$S>G?!@@[?`>ƾ$@=@i@(k?3#>ItH Jگrj߿)6>Yd}1;\cO*E>PV>+>S>1E}>:E>y޾m ?!=O v" <<>I?E??n?U>KG$r?e;-@dxU@6Y?,2A>?T@?E"ܿ1g3EQ9пGG{=žI!16:lTm㉿-پnw`>?c?Z?=?ז?3?G@@"?l*,}ȷF=C'gV?.?6?b?`>>> 3-9k?@?'=7=U=y>3&jn"1?>`ܡ?@d@|@iS@@@?\?Ͻk=W?nM?{?ް=b vsW4'.9A_ݿט[ſ=gY<ԝ?|?8?Y??m`?Æؾu޿ᲿsFţއ?I?F?= 1>匽q>f???s@]@3@= @,@^5@?mNP:vn?t? ?\W F5)Kq:dmL5 ՆB ,鿞C2>g@f?M#&?$l.Kږ&c%R<\ǿ=G>"f?3> =g? ??>W?v?m???h@? E?c?{?>ηsr[J k,>6>5{a> OþpgNÿ鞿)1Ja?ܭ*_{kʿi뿵׼'<>x ?1a>pePN-MCC6>28V5-nȤ8Y/T.ѾV>r?o@+@O? ?D?黁?5?q?>?Č???< >4߅>nD??$>p:=1E¿e?F .ԝ4j˭ zE5˗3:E˿0 3=A>>5.>U5?$?Sg?9h?ף?u?+?Jp?=[ނnLG=q?{d> H?]ɘ??jg?+?1׾/ վHBGCeE70 c>y? h?G ӄƾ12֣;տpon !{b{hNj(Q뿫$l"fN=Y[ ?FuC?~o??y??hV?D> G!!ľ5?Nz?H?eo?q ?/@?z=W# aʿ'2g'n cPFI< uI@dEȽ?sfu8Q˴5̑}5,5+K+2D Uk?v0?>͐eLJ3?o?hkt?z??!Mt(?E?|tU?=dX?,^?(3?%?>Kibؿο οiA,nPq6cm>K>݉>E~dX ?+=p|&*$W͌˿?AqZw.#?)e?l<;~ pn ?ok?]K>.>9?d7a+>{?HK>R1|2P=?#6>7?Qq?">r>Ӣ&>Mbaoh` O<nt2%,zgR>?>j%?r?*?Gy^!¿̅xwY~@&z|ӝ>k?}?D?O䔬j:->>4X&!A‹K>ԗECK 7LN>e%s5 I:>SUH_- } Cth??q??{?`=5`dK %c[d)Ͷ<ٔ>;?>k>|?ޮ?㍠??u?>ǤK8O:M=_?s( h,s쿛[o>8P?1=/?r?.*Vl+_*o~ ?MC?X'?ò5ȿI-q/n?]:@@? @L?;X[>"i>90E;>??Ί-@?c?QR? [?dsE?3i=;=&ͰC(>IeSٝY\9PO=يL?c `?Z=Jh$?q=5`=?(>?Q^?(kr?h0=UǾ{6>LÚ/c?c?^@gR?Th?}G ?CJ?R@C>`Q棾 =?Π wVǾI1>h>&| ʿtU>܉Q>Wk?@!?4>??E>??i?8=pbm AD&`?|ŷ??J>FdS@)%^b?=O#@T>@:C@"0@w?)9?\^=p>$4?_~?NEr^E7'^?,?6Z>7c'g>laan?f5@=iF@@zt?7>|eM???糪 +ϳP>F??Ҥ>iZU/lLc ~@P@m$@ؐ?v?9>oy?I?S% K¾?/?cπ?*?x4?A;>? ?1=0B0r!oUY+ =z?O,VJCFVL=4*s> ?- ?Cm?Ȇ??ș?q? ?>?H??c&?(}?+?->/M>>X߾=TD>3l'mJvgS^(˅Vj>>x;??,?y 1>o?N????f?SZ>=b>m-?>K hV>>&i&*ܿ;P?La??v>|!J?>.*׽Ŭqn9?1P??d-=?O>#>Jj?nj?'?'?B{?]#?RD{=Н0E>Oo?t>) knSտ1`O;>F&?-׳}ÿe5Q5x?Bh=>+ ]?:?I?l?,D?vV>AqR9ྂwG?W?,?'putqkW׾B>o@ MO);<>U淽(5? 9?>-b>7}???ػ@ v?7 @?um>ye]7.F>c*?W>Q.:B/>U=徜@ν]1>i<>ya/=<>3?dm? >1(?@i@ @S@@Ȝ?Bq?9׈hԿzy?U3I>z>>e=dP=q>%kd:y3>z???:?^q?V﮾?>6?j?a>!%E|V? ?>j9pk̿?N?9a?E!>N>???zE?ZF?{Z=f?@m?#??Z(h1Ż$sg=⓽9;T}ll ?h?޷u?"!<Όy?_]?/:M?F͉?3>7>1>{F?=e>H웿qή5cF,(Ψ>%>{S#?rn?T>Q;Qlt>q?j?;?@@?q?BT=OY٧ɏ-&>YJ=$ =sc?sx=R?9?~.?lJ?p#pQ??48CXrhkb.6RC>i??#? ?=v?r>3>?<:n?d&@[2?38G،dN;>?i}@@o@!?<(`@=ю???ɞ?>>u?Q@8@%@@(~ r%}s00=&>?ߔ?A?U)?k ?;?<@7?{a?&>`5??? UM?U>)F?n:?\??C?1d?#?ĕ?Ī?~??v?30>~

??/)<߁ϼn>ux?`=o:!ܿՎU>zx??ƨ,˾ü7A>Yj>3D?4?Ü>{ž\==cdwn9쾄@ؿit|t? ?o6^޿A@>-?Dk?> o>0؄?i,?ajkھ/6ֲͿ3&HNu ]??`?/@)@@,?PV>oоv?`m>`WaJd>9ù>Qy> 񾑇Saך}@@?`&¿?#`>S2-k$>լ??+?p??-l?p\Z>ϾZ6w>`?>G-ԿA{ijHk?2>r>CَxM>,m?B7dW>?m@#}?@Җ#@V?YZ?O],?;ObN=%I `ھ#Cy9ʿrS:gt!=Ŀt=>ָ|?Q?޼1}jU&?0?k?”>N`?V+ @ԪK@?W>p,>ibƞ9J޿Z2迴Y˿ >>伿Gʿ{vV>x8?H"ݽ}f>{f[4¨?1%@Q>Y\:2=ǽ')Ǥˮca?U?`~?4?>G..{5\7>D >hO#>~>CG>뾑o ; {>?t>>4>O8>C{>WL?_?YM=+Ur㿾}1MԽs>@?6?qK>XID\{& ?u۽KNb,\Q`,( q4S?M?iZ#jQKH=Is_*?C>]Ծ*!?r2g=43>`v??t?gjh?=!>O[>ǽȾ)} V>xտny8/9˿dȞ᷿~ n>:+LpҾ߻t|ޢ=>]&:E ྿5Je>(nTu?tk?%??8@N=?};{?q>/qG?GS?n=Xf[w֋R4lT{~c>l7>̾ʔf>y=> >4XAQۿ餾#`>T?LW>?K)>=HD|>ݿ>*?u?c9>b+?"?>>P??17?cE?bG ^s(\><*3??.ͿK˿_ArXқTV<ӻ0@ >6 ?n =+KgF[2L>l>%wI=e&ɿQU?8-?O?h>ZÔ>?r> FQ Aꚾ.!1L)6>?>tl?u鿚ɿ' H<(YG]q)fڿغͽtd?@??B?vT{`;=>u3?ll?P?@# 5_]]?3D@?=>9?~>$Y{Xe)Ar)˃ d "sb%8ο=dٜ%jj>7R "=pIV-6>Pr(ԿBԟi9=2@?=8޾L>nV?l?dk?@Kǧ?=T ??4~!@+X?wjƿl2Oa>< C?3b>6lr+&> ?)،?Q?r>(w}ݾ6?Q$ЁG{OA͗~MA t5ZͮKU.>iW?Qb?f?x @>8?W?@N@ģ5@,6@?+[`ʠ5?h>!>Lg>|vє= =8KƦپc z̃~?????s ?'x( ?:? >?AD'?a'ՒGfl;,A>fL??j?&g?\?e?ߩ?? ?[??4?hO@.@E}?>pup2>5>>> >Q7#Կ} t?VkuY(sؾJw= ?Փ>N'+~v6=e>VþQ˾@?:?͈@?پ;P?BM@@a>߿X?-cSKyp\<=Ͼǿz-t/.CGʧTe?P?4?2鿍O'[ب2`߃3Yn>>d> ; 9$=V=WƆIz #"FhB>>/>)ؾ4;?@e?m?N'"`Z|^6^S?u?9TR. (:%W* ԿVô<>?K%?Hr:=&޿4#ʍ?>>U /!k9?o?ko?Y_?w>QJ/Qs͡{=G>>H{>~?w@'@??G>5l+?.7(H4.:0E~6e09a>Jyܿ*9οs,?{ >(Aj}'>1f>Y)>PO=DB:?b?}?ފ?cG,l>S?u?>J.Mjib ?b??z?>1`@ 2qrDn)eguѾ?ܿ w<6tp,U߲(kȿ fa˾ QNPq߿Vγz0̍j ܼ)?p.]ֿEֿm>x?Ӎq? ??(r>=_>>սZܾC7 y2شϿ %n柿4cDj<=1[Hŗý޾[/=4!%<>$?q?$O=%>?4ᆱ]1Zᴌ>>H>BLCx{򿠪#Gj`>/:ZR?5?f?U>!Ŀ6&;+b!a ь/6V;QLwo>>w??*?.?v>U?c?o9a>(?>& >K7?帷>(@g6)?c?j)>e<-׾J+>>s$>OwCyx@Ϳ=4 =KJćpeEq@trɿr].S:;Lݿ;4 &(DN~xXQ6I}bľ3=Af?.Q?[K????Û=ӛ>M(?j=Pj$?yT>&{>|v׏"a>Ϯ?td? =}緾0=9Tk!^ĿQu2= *w}58Dƿ>>Dǽ_54+^%,t<gJ aQ+zx.?j?ƭ?>=vZ¼>4b?6?/Ж?Yw??r>W=U?0? ?;??;=d>5NŰ?[鿷KAB^ $B^ S}¡}\>g? @5??.?Bg}b@ӿ5O p r`=~>?@=@P?n?? ? :><;>::Y?z?@V @8k?-O6?w?ry??'"'\>hm>:F l$E_gl$ 4z~Ӿ6mھ\>R?5?FS @tM?`a?&? @@ ?Kv[{?y>ǿ$G6ܾˈJQ??.?;??~@P?џc26v>Reiz <{T[B f]+<&fϑY8?! @'E?'>>ˁ>U>b?z?{_?ƾkGƟ>?CZ?d=v3>9xkQ4w|?>>ON? ??>ZMg+/?u?~IV[8QK>LR?xa|W3ovﰌs.?O@5@A?̤?3F\?e=3?׹?=? ʿ' #""LS?O%?2?侦ݾ4jy@nN_{0ڙ> 6?.?x$þ ?k>,i>Sd?N=7>ה?ij?Ҳ??>qge87+???ڿ]}j3I/Ԭ3a*mnDՍ lJ?&?D?@d?/$?LOBULϽ2i=D*?vq>'$N\N+>O )}?u1?S jA2 ,*~{Ŀ}<6pÿ30+}>?2?{?b ?ֵ>C ?1q??]>S=<>9? _?M>z?sc;&}ѿ4l;_"ٗ??~?(8Uľ4^z[p y?T%?>?B>>*=G>B?#??R?|?ܜ?#=y1q5m?&? , rz` >*K?pkiJn2>r޳= >?l?d? >kS ??c?4?9B? ?E?t?K%?׿68{?-?`d?A>jt?q?@6?F?S=?*@q?F^=u Z"d #?f?E? T?W>~>~;>=>SD"#> >>!VB鬾%ɾ½=2?g]?0u?J??#ڢ?@%?p?@?l?g@=ū?!O@rRJ@ ?ۙ8?I&>]J> /> u>En>z 8 =7>ǿV(R?j?>?>B>BX?*@Kj?OV X?NX>l{?D>|pՠcn$==}$ھ%ɾar>rE?0mFf<>ٳC??q?Jc?I>}Y?(k?sR?:@@+C? =e8>Iχvqq"oԐ>kjfJ~!C>qC?T?g?4)?,7?z˾;8=? f?%??Eop?~[8'>)K>~? @&W?!>u|=A}??'?߰&>]dzW>ko?{g?y?M/ܺj>)?F?)`?iLT>? ?>ᶾ!쿯=?@˄#@*?eS ? [ ?0qA?K@?@r@jv"? 5Q>0_"@zE@Zg@慿#¿RĞ"?P^־iV>A2?kt~?('?M4?{R?b=?_@sH@@{?\;D^>'N:?؏??]f?i?|s???@I @`;?6d??69>)Ƚl[q?'???/?_~;m=;y4BپPSz/ `o [Ŀ Ӝ>O`ſ{-׾7XdG1[L;~L "$N ?¿k?,?,&pҿ=g+ҾBk?RD?O|2zfɿP2D$¿k@% M6烿? ?A??\?@?ae~>+:}dŗf{*> NL"AdrmK@sپ{Qk3a[=b?{>|琿tf@J@?? ?u?Z?I4>z"Wp1{k=<mĿbݿӿLi_=,>/>`/?_·?H!@p?z}ʾr?#??U@5)@_?">Zl?w?;?RaނNj2":ѿT8؛"tS E9Ծx 2 vv*9_>?T>? >G+>a?";b?v??d?>w9 ?|?ѿ %/*Fwl??oV? ~#>pe?ڦ>*d+z=X?!?b? %?Z@?l U=)((!щφPƾ7=Lȿk&Mg߽b? @?D&f3eG>~Š>os ?>I# ཁ=Ґ쾥>:>6t=x?g!$?~"E>ۨ?m@@H?$ @+I?i=l>f>A }|? <{;O%fn{<#K[ξD3?i=_ޑF/\N@ z*?쎏?&i?Pq?Q>-5?@)x @Q?{X@ @y?|O鄿¿p2Y(ALJӿk㏾U0|q1#䬿ҿ>>?>ב ߿$ӿ?;~7J߅>?cȀ? />Fu}?ċ? ??, @?@@yy@-?;26! ??EܽP&ԭ$Cv G bvT b/IS,̱ſӼ C7$EȾ???گ?_3>>%#ɮ<2%>?lR?zW?N9@I@c ???fܛkɿ (cl<>:"?|`M@:O ؿ4j!sXS࿐ZrYzQ?>cʈ?@9@ ?r=̾n)=BF@u䩞A…|)M>ػ ߿Ye,n忶oӨֿJ ϊ⿭ ӿ勿~<̿}ĿT7@%?k?@?K?K?z ?'?5'{WdS~kMF TLi>Q\d?qW??.G?D (QfG邿Jұ3v>% me?S?kwn9&ڿ߮f#cRq?sO@&@@O?Z?L?f??ook-Pqyi?f>Au \><㰾FQp= &>Mq?b>੔:=(=>GU7]>ć? ?%# Al'lA ew[:_N +,"s??t?+@L@@ @wO@$@@V?t?X7꿭N8JkC?LƊ?܇?Hc?̟>ھG`ο@ֲxah?w]>3Ծ?a? Q?o>\?9?>??]x=0Y\=fgI=D`_!U 7$o>@ +@)@Ǥ!@4@d @*???p?l?a?n?dCY}TJD?i?B??ޙ>3T|Ͽ^쑿\9dC |̿\jDh<';*en = t?A>G*VA:>T_dމMgg#N>??d?}?g?s @~?Xh?MF?? @$0@Zn?'ڿ_qqQi}_W{)>>a,>=7>pr?I5 B??.=˿gpv)s=տ6˿147dk+˿ܿl< -h>&>€>O?u??Y?,A>ܙ?!@#@(6?-Ri4 ?$_u58<;FfP>e)\?{?{U>UM? ?;YĊI>)?z0?-?(m>4+=勡Ю<{d<{? ?>|Vоn??@@v [6> Ǎ?7??H>;K!ma~Z'M>]>BT>ncܿiq=j???*?QĴϿTe63cb5??U?;ܣcd_Ǿ]T=[Wi?l?[pļ >Ms=ή>-ԶJĹǾ?ש?]ҿ?F?OV(oCEj8_? /><($¿ּڿ%pk˿MJY=򥬿~^=9'9?Dv?v?Nj?Ut.?h>bݿ39f6CVb3>w>v}˿ (^2!睿)>/|={ҿ ĝMQ>Bÿ:ȾV>@-ݾʖZ!|=P&١T4/Sп6Zde~-?n^`? ??0E?U"?.7xÿi/rǿ`(oQגI UqؖN`\ŠS(/>}FACxA>?eҫgG!z?e?`<9Qؾ\<rڃt߿]ǿjyCn,½玭>$XϾc>ry??O>U9w̵ln4gipE>Mi>ev<,wFBlܺY/ܿNj=p>o?V?y<>ܔ?to?>xu>X?m?i?@?@Zk-@>uziOs\??+?Hp:֮B`!g/s翛`lQe۾i޿F]W@?kH ?=.A.9ʿ(W?>_>?t<>q B.=k>oI??"?bI?P?H?idtN> >K%>2?ʲ>R>>8-?}Y?2VIuþ5N VDM[b,seĿrW)+`?W? `?eŽ7w] g>Qd[Go䕿 ^=b>@>:?y??yL?3>?|?? C?&?y?YQ>Bs>,?,??4?I?OA>UV?gBѿՍigCiiHii'PgX-$>{/?k?k@ @>G7z󠋿VRۿYW3oI6Z=m? ?l\0?޽5?s?V?Q?w??c澮ζ.ᅭWEnm ô%/Keg ,9cxxE??ˏ?v??߹-? U>l?ƨ~xR8(MeK>IK">;??Z}???#c?"?X>Kr]{ i$딞8>{?y6>ofa$Q;e@>A'>{S?^>vP{iՁ9>W??r?C?i>οW.`mtukeVn "?$@6僿Pe5U|kJ3Ѿ>>ZBE-hs??9?߽پ2O;\<`se>\k?2?[??Y0澮AKF꿱#5L6=>n\"J@p> d=#0>^>Y>MlˡGM? >( >>=?> `=N@>A>8,`W?2@ab?"^GAY]ῷp.A> %A{^*>T>7B>[E?]NоECFedl>R?? ?aD=A>OQ? Z>;<{=>Q>ƥ>|vÙ;K\hX򿋃lDl41ԿK (g4G?m?d?/.?ho%>0?H6?xh?2?EQ? ?t,?L?aс>x>`=x ?-T?Z?~M?%N?M?I*t?*v?.>B}A7$^ODO>m@?’m( U 4\ؾdo{7?>?M??V*?28>? ?d"?6V?B>_?4(?'>uR@+'>mm?zP?<>K1H=Û=yb?r? V@@Ԟ?>z?S-?O>ܞeԿ>պ? @R@>R@0?'.n* Y? ?>b'` ]=%X?p?> kr>ղ?\?m%?پ H/>r>h;&!s5=~C?<@^!@?fX?&>!9x.Be&>-?xp=f3/rK?P|j-`?W<;?->ڭ>m??b=?ZG(]-vX6ݾ>?el?G>Fֿ?>P>(?{{伿>5׹_ͱ 2?J?6??U)?, tpaE/K*k?-?r>H>D?%?G}???J>Qۥr=C=g=e?C>t⾝=&lK?R;? ?5>?-@?h)#F `?v{?(?=4#ҹ *)п1m>$ވ>>渻Y Ͼ=?o?Rp?-?"V??C&=Q??r>/><5SିX*aJ>[=C3b7>-6U c }fR?g`@?.2|>>)?{?\M?!>]ݿsX ???׊>MUN ?>־ k{I?k'P?ʆ+??X?/?L>%>>֎?@K @8E>? *Y>+5 ƿ>>W&?Z>N.>ӈ>!?w?_@-@?@a@`ྜྷź6F?4z?=>D8?ƿE3׾l~ܺ>ԚHቿ{eZH%]aϿu ,[ΔB<ql7!@ ?-N̿ο.ӿH!#˿>0?6`䓐BأV&Ҳz@>ۿ?t 隿!h!?@ @U?ڬिuOwl??^(?Ͽ"|ѿ2@ν.*.9迢m=3־t= V->? ? ?|1??[?ap@s?r7Yr7nI-ׅo;kR<˄>"T>*QMQ=Q>b5=>1/`D?А?ɐ\=`xzӾc,8?W?ׇ???W{?@ @ > x,=W=?#s5&ؾ n=>P)= >Bg-;b#ܾ>>7= ?~?g۳>$lվiv=>Z|>f?J??؛?'|???6?3L_n׿teco˜>>0x>?7xvgd-#|=>g?yLky ( fA? E-?"5?Rq?@2@ @e @Έe?0(U+f=J>m?o?E>VH?=a?w>0{^!>O?,);)Ap}$?>>* ?%r???~?,? 8@?L]@.E5@@x~?iE>X`>1)1͗例 z:ſIݿ qe )ЂǿS22JR|Jt0*FgE>̥#8̾ e??KI??݄?@>U?q?N'%@%@?_?dD@}&@ ?v:??!C2>#ֿZC D͈0n/b-e% /aF}>g?‰E;M?X ¾p*n翻%a?K@?㩦?> ڿ>?1 @*@{?^ߔ? ?$??>=#%ž龃B>_>.꥿E{lǾS!?m??Z&@3H .ӿҥ=X󇿩5&bȸsis!^}myt,dۿu>貙?dy?JS>ܓ?ѷ?]?b }Vj/>ꈕ?]??P #>: ?T=ޣ짔οsՋ߈l d5ĉnel ?Ni?W4Ko易{I`(zu>c۲8H"Гп [޿bϒ;?E#@`?~?> >BG?;_>]??1?>!Dk?o?j (㦿c׉Z:[Jv1>v9 ۯZ,1Uj1"/R꾜þَ?<>ȿ%cK"9 ,t=h?\S@h@y@? ?Ͼ>`23\rS9.ZTk=#>'??Yh|>s?* >??j_?>!>x=5'>6?x?]?EkJ̝5nο+LJ>8?0?d_2^ҿç%վޡ?(@&E)@@r@8?5?H?,>'i"scA֘帿hf?>\>?J@?թ> ?Cƽ׿dx]w?#ݶ?;?%?ꆍUG sf>d?CM?\4?@s'sk?BK7/>?U>0+VD[/? 3@*R@V<@q?Ɓ?"@tp?|&q忋 8c] ktu?M?n?h&!Dl5;)׿M[F?l>öC >T\0uS9Z'~<PP4>Y߿4&WHrO׾U8~dǿ%|=>7?&?.=C;1?(tƘy"+?_&?⤾I;`:؊2S:>˾FI@EF\>"I&&|%??h~n:?ۺ)[3F{(ɵ9p?5?5\ȧeW>?Y}?1\??%?|?#X_V[%Q8G;8ʾ1pǧ,6!?c ȎHSLjC>Ĩ; ȿzйO־>X> ? ?+?t?&?1輱~྾_K6qȿ )R]a?Z}? `=\3m?I迵ؿDkg/A^>&߾s=E^? >1߆6J3eٿ8?0ID@/@.֡?=&"eEV>B߿yտ,׿m 6LH?h>jt 6 >Z0:{=e>>?rΤg ~k-@p޾\,)@EF_r&ȇ>+>q==>~7[Ͼl<>*>EWF??>@ 8|֊>kR>B'>H>B>h?Ԍp???A't6>?66տ_kG/>Q?d%??{վĬ;ྉ>7Mfq.m?|ǾF? ?w>aMq3n?c=4W{fzXqz~ٯ>FnwiSݾQub> |=E>Y;?Ǩ@'?f?Ү?P?+=mt ѾxN<Ŧbٿ_ӿX???a?g$>>x>AmxJ?Jþ-p [t!>JV?a?ھOjZ>%)\*?>U?G>6qs~.Ѿژ$ h'9>P?{HmAÜ"1)8>u3 ?*R?u4Ͽ f!ϿaH=5$Eܿ3i??) @V?8s7ؽ#e??lW?W=_ῲۄ>Q;Q`fS䂿 |!2VpiGjD?-?u? *(fR>m!?ֳ>F; PQr5 㗾Ź=RFSgc#IEM}S\i0/)D\ܾxg> P>ipR B=>2">4|>p>݆>t?bL@@*?=ҩ==5?k->q ?S??69>6?Tp5lbƌ->F kڦ)~L ?8Gy*>Ԅ?x?o?>:0̢t;hۨ? >u=>;"=%00?>5?j@5@0 @m?&?w">R+>,#6?>?? f>-vʚ ֿi!(W8' ~4f˿P  :GT+.xD!>{=+?+>1l>.>Q5I>b>2VbNN MiQ}+Q%޺!/[>v??#(?|L*3b^ۗ Ǿi?T? =r {^ >DK'\ӫ=?>F J!֩r?a1?m>Vu??qĠu56ڿݿŮ |ǽ𫚿a.bRć0̿,0m>ujؾpg՞CfFm?lw?֯ =Uf C?\e?.? V c okog?N?D?6?p,Oj#t>} M71vu>dLG8=eԚ.tG<>>CSW>U/H>`RPmɿ/,N\?L>H:1wHkiR$w>[$x'؊>-Q>e ;U.u$y>^?e?&?V??)l/?0>%>D32UO?>p?5i2+;CҿTSGT?? Xֽg ?/?M?k-?{P?=mP=:6=|=㾮]4?,?i X/_#\?zo?9?*>V x:ߛ?>?_?wv7&,:ÀQNA;9ѾQ>Me>??9?H7>?H*? Z?cͽmCjCaпVͽh>Is? _>*>2Yؽ39??5?>4z<=z=T? }1?SFTeKm4>rz?3=|?e?c?i2?\l?q? k?FqrIq?ŧ?Ὶ?q:U5ާ;Os?x?CHbӽ >s???x>娿Y=]!>-*>͐?:?c??,?,`b׾=p?(?@C>X Ͼ{>.?K;?C'Bh>_?ھu->Ry?=>>_n;>x`?j?X?=?*?mx?R?oF?k-<?6??$!W#12پ)j,R ?ު?Q @Pxy?2 t}88+PcO`ü @a!6@?_J?>z2E>\w(ef'辫>x$??*@ ?o?o 1ν3k>?j@;W@zb@@ 9?Qm?s ģe2H@UN=ur>̮|Y? $?>{>-i>þ=2??@'8*@2(?I)ڲ?>3nʥs݋Wu K@ 'GN>)? gF^oľ>?@`y?c?((7@a!@?? ??-tC"aS>zԸ>b{>T~}?!}K@C@?:?S@οxӿ?N? S ? N!?>%n> wOOp>O?'$T?ؓ?x?Q>O.3>Q??.??Ś6 i#>W????K?e?O?<>|>I?L?E?@s?6?z>y>d$>ɻlNr6ɾ.?</8g= &?!Y?@a?ܙ>nP=ւ}!h>.2C?%?L@ :@9}$(K? ?>4]?Ah=>=>N]1dǽt.>ٿ?g4=cRR1ΘҙŠ82տпGC]&^~?[=j.{m,Ⱦ.t"Fn3uM>k-k傡dBsx22? ??a+>H9iu>rԾ?]\>hudIͿ,:@yyV;%Yy?S֕?^>H?ߪ?*̺?+?k?`X{꿂v/???0??h`>PoD ox$оwR1fLU"5?HJ?댻+y ;?8?6%@z?u??@ >pCѿOhd?n ?g?j:? ?SP@w@r?O(Ε{ݞ,-;=A?0̳>"t)o#"?;>Y-CM>=h?x@V @?=N?B$K#L1?D?ۚ?Б*@0@T?a>s͑pѬ 8RVKR uſ ϿKIÿB pB>+g[a=R?{?{ l?@mIX1?ɖ?֐?/?A 9g?9@$@T?X>sò>/]>I9ؾ(\5/׿f {KtbMi1访I>m}ľg]?!Ӊ?W>JL>NJ?ˡ? ҭ??3>S>!N?%(>=;\ͽK2zm1)n>{?k ?b=ݗ龅o>'p;U0)j ?h?=r??W>">?u? ?Ѿ|>/?š?o ?Ks??p?Q?Ղ?|>Mf=>&>Qkؾ;c|OhDY.Z 0>I=y҂pv >%@5þ,TB?v? ??L???EM?[;]>#F?ȗ????vn??,r?< {_EW3?ʔ? ?){Cek5տ/0w`ҿ8JnqQ=c N>;WI jֿR|12>Pu |Z\*\|u?=d??/E??iLl>T$?,+:?v˼U=Vz=">'9>u>xeؾDB 4.k>=by8mh<تz>y!9>MB=j>^/w?Z?Fҕ-, ο\CXSǾ@m'Xnl> j?މI;(#>_?p5XLn]d@Dž)2WywW?1 @K?$ah$ E@ wSS)s$+=˰x>k&4?ޣ>f/= ?a?PB>=eS1UڿZ>H«Ig`ž-=_ ?YCNx迁Xk¿~݀`? ?jTsI8#r;>C^nOսt&?e?,>=m>@5t@BYνm\sI>։<ݾ>DI{>JN?̂u?淥lK3Tyee?#?j>a^=\s?cU4E>cþ+g;?m?`>h mܵͿ5k]_T$K91(h~>ۤ?œ??r??t=exK>4}P? "?`?b?_蝿ӿqʾi>]>¸R&Ͽ@XOq7EO?a?ZU>c ?>?@Wu?g>2?@??^?=? !/[sS*&g.x0=2Ash"Q}cuU.r %L}𾭘78VЖ9>yi?D?S=9:"s<$>? \?fF?imUN2L6 W˾l35K;p>v$?x>Ⱦνq>Cƿ=ʒ>s违v|(?A;?iu??D M-K>\zom@r?]E5?9==9>it3].>bh???7? ?qc/>?K?`> >N >LaM4n2?T?x=yԿͱܿ聘??4E?@\> ࢿ /c?vib>g=>.B="\RJٿ5WCfd '濟տ(32]ɽ>~?YΌ>̨=j4lh ?9?Dg?z>:ǽarKvNETUT?P9?`=ԻտyNqք>@A?F?{4׿f=o􂿾Zi'>C2+_SRʹᄅg?l;Ի?&t>AK?s?`?)ǵ>tDX>2&>>>4>̓>*zך~[ڿFп3饿@> ?W?% ?Kû> >!2$Jor=s𽿲joI*>K4f/Mfjw"t +ǾvT*<Ⱦu{%m">(x?w@?+>ViB½ ? ??@R?)?r?1?2=p!5<@gPؿ{LfRL]}-'Ͽx???t@?Ⴀ?ٽ>աN3]ֿ1s:> 9>E)ھFwYڿCo>ݴm?Xɾ)=_adҽϡ>Db?+?ܘ?ݥz _ƾvp1?V??{u>Ah>iGn>e>v?*Z5ʿsvAewKB40)A߿?k/{3RA@ @q!?~/?3q ?ɯ V=?:QTOӿ4Cen?O?|>'! { llO??N?:?cF'>4>PI>{?> ԼQ?D>@ ķv2ղኣW4R9(Ѕf2±&vs˽uޱ;Z)u?=Y񨿄> 5?L$? xwx^B;>f焾k0ӿ7*0? [?=鷀`ſc\>c?@˜?UK-F ξz?`rnFc+HCu|,:ƿq*s]БVZލh!w=l/?p?1?D tqj6i?ZcPM??9?7$GPb0 ?%@ @R ߉yÃ>~?C>3dþX8]о2¿H<Èb~rA07-Iף;"W`)qM>&Y>AG(?>f??!HSg0#S?2<@0r@5d?9>) 0?$@L9@?>6>KO*wXMWY@p=JG?I +HCwQ Ͽ 8!ԾuH={>7L|"*?]?j>֕;t>zBfRhYg7N9俋 #@ҿn U4=f[0}eÿ>tOkxH!x^r9FT=*"=Ⱦp<?n;ّm$?A?;0?Pp>7> eԥ5̿ەM +bn;UYj 翦lft .a[o|6g˯J?1?\?=bK,Cz>R>FZXnL⾪G>Ru3վ킿zD=>?DJɿ$ Y0>龜xtVܥ=$砾@< ]U -3Lr>?y/(\;Y3ݱmuqn>;qf̾3>A#?!?Z?= 㙿iH@=kz?a?G@?Ð?뇺&ApAɿ ׿qk? Ws?Yl?v>fʾ>T>D<|ChՐ徴>>9 > T6 \.O}u?c@C3K@(%5@. @{d9?H;GAKx9vT? =?O-_e.6?ؽ?2X>>a>?PE?JCvV>,>Le??E? -> p?S?/>LU>.׾V*?>@Կ=>u?l?}E>0 %Z᜾?>A>=?+X?o>uξQ"=zrL?e?ۮ=;S<3???읔?6?bT+Hr Sw9?@h?%q?@ؽw>BV??x>?>0>g?;j^??yv'>n7*d2>&??&?0??{'{m.1?@@{g MET ?7?U?MU&Q5e]g8)C?2?X???xT?N?>yA?ኺ?~<0?g? @u&@.>>>?\??҃?XTf0ي>?l?ѳ>ЁW ?]q? s>LԳ>@ 0@?">?Li>Q '8)?>Ï>/>V?y?J?>^2?R??Eg??2%@2@/ԥ?[,?N$6JըAbYս͓>t >0K>>>qq?"?k ?ylayv E=2~>^q=:S N0q->8?)? @[y"@1? Z?3N[!~5ּ_z=X?a?9?m=O Fof=?@@ @_??l?ˏ\Zܿ J=QԱ ?@@U?hH?B<??S .@x@ֿ)&Df!j崐>QX??!>X >v?("=Ơc?R{?(?3˾BX?z^#bL> 5>c'+a>g=>4G[k>A>)? ?}U ?^p??_K?/?Q>ܡ%=j!]]>: >_Ca*灿u־S>4G>C!Ҿ F9+>?|>U\&ھ`Ⱦþ'uۀV:闿8b¿_B붿 ??ؕ??c?C?h>v>ú>O??=?=z>2(MKH$`4¿>W+P`~!??Ok*k' REDM> 1c??@劝?>0;_CE=d<2F3?Y?Ʊ>J<8i>󝪾>'?|\?[=O0ݓyz,3sSL !r>r?}p??{?&AB<p硾;#>/?"?i?G>= F&WpU>7=61NǾ (ٿU hCݿ[;$~ Ȟ?̜d{Sz 4; =F?dw>N𾷚> ;?5d?8I>Ҿ8w ӖU?C@@6w?oB?+뿼"+7?]>d ^M_cE# I؆~Aܕ밿Ҷ7yϾ? xS*&V4g|? P?^߾,(y̒[??wj?ŅTҿ{B]09>3?>ck@&w$?)/?Fq1|?q@F?oO>! >9>w> V>o岁mʸ(9r̈́҅Ѻg?o>ㇾC7+ c >;>1?Sh?>"?1@A8@tId>8v @#C@?n̾T>A?"=S5W9d ;x3#vYLp4h[꘾{f6g^=k@?)>P|ÈKvI>㙓?R>=y>Z @I??K>ꤿ-ߖU+eIGvվb>3?>)ZJ>K-??0)]%p$y &P8Ui胧<(>|;9e,@建G>!??Xx?Hgڿݿ>N>*˾9oYE!=i>i=nV=ɒ?2>^>5_+.?n n? iƿ;RXZUW\ٿ珿Y̖@󿑿YO=q>\[+db= =ױ'>d>#,? \?bϷ?Tl?oO?Jb>Pk}>O>n/m_-~*U=7??H >l?=3F9k&?K3RZΫjI"lS6K ( YR>g 'q?s??O_>X?x??gqRɜ>F8Eο`j$ ,/ë?$`??.? E?,ҾNcApf8?W^ ?~RTe"㒾T(>v3)#>ѝ>"ǽL:WڒʿM >2>8?T?u#)GIx3)4Ӿ吏4b=Aoa/ؿؤl[¿#>>]^|wȿ|? ?tײ?;e@p ?O>>[⪾h&?CJ>qM?hF)>U}_Q>wbL\ͽۑLL-<&GM~ 1;DwV>@?Fv>퓼ƾy6 Z=ڋ>6? > j%J|>5q{ߊ>>>n??om?*C>}>EI>VC-˿< ?r?F%?8-;~PMݽO?`^=~3  $Y.ˍZĿw??e>p.8p3ɿb>&#?3f=mv/؈Aÿj;^yTd9HVĿ$?Eۜ?1?Q?? Z?;?qju{0~RMw?>Ⱦ&?5>h>`3?X??\?ߴ>sIlƿ aGUA\̾).0Yþ>?8>%17sRBտ:r2==?$1Z C~Nn~晿q翾YiQh>2>?x׷׹#>J?X>dݾd> 3?&X?G?#??\5@;?:@Po >h}Q~AGxt怿j #?*?8?sߴI@"8*?Ɏ 8ɿ(ÞBq5K`1k#ÿ*54qOѾ&F=0c?{?߼??>:Vns=4 ->U)[? ?Ta:UEwĿv^S{ 6—>%4?I?`¾jΎA5%=O?MՌ0#㶿|u>lx>贻 EVPlJ1F߿@HB:9` j Ţaah>U ?>oٿ3+c0cFM^[Nӓ;E>suH=C=>ja>>,\?=:-K"쾒>?I>2/$O/0⏕ߍ>0:? ?ɐ>YP&" i赿N,J>O;/bǿP;ľK֘h10߿/G'"'ÿw|>t?a/&?>Q=FLXBL6 l <i>|=?>&`1wi#!@ۿ꼿N&s)%YKڼL?5}?=?byFfʩy>_??#?<>: 7vW٧mBO'o+V??ޑ?9 C?HdEС\RWv6!N+ C?! IN 퉿H>BIPNhG(ƿ!r,?62#H6п%tn?g#?X>)WcV?C>r Ͽv9N#z6??Z?2.nk޿c8|־ζbkk,UזE(Q=s9?tF?st>jccҿuF'9j#J`Ŀp?=?0Cd/>X&>G{=|< MLg̋?W_:%>Q?,?=QпL ҿ*j2\6?>C#>2>~ǿAX,cHąվ .n-&#t〿6ͽNF/=3*۾bYNJAѿJ2SbP;>V+`m?@p?>b?}??ss?K>+РPT4z0>8=Yn2+= qXܞ @վcgTDӿ~ƿ*3Կ1ȿ_¿8㏿@>N>?K?˽J>mܿho#^L!eEZ/lSy]Gӿ.1S_!Gi#%YWt8ᆬʾ@eײ p! iʜ]vfkȿ4~2ɦ[N3ѾYpڞy?@ :#@+?Ds>񿑈-6fD^4ѿc!1(fοf}UrK V'"qt5cο!꒿[ 4ؿA 2 "پx߾&r^n+DRMLPݸL>.L>QW}93x&ĺ\? p")#* sȿD]?(>Z,>pZ>ھxgzv m(,bOjz{敿7:H@a꾝dikU¾(}^~Yퟭ#4`뾢M<0q1=UQJM¿Ǿ->O>?Z!@D?n܃?g|?CW0yaRl߿FO?o ^?l?|)0?~? =[4e&/?fN?Ӕb?в?3?Nj/?5l >˵$,ҰU4T>w?0 @??n?x ?+#?2$謿c\)/8kݿz=-eϿ^{$.vMPiDcFr~ =6?#=?cqξ c=,ҽOZ22\?Ʒ=ׅg?.b?5)<%b>0?k k1"*톿j}??,Jy9\^5b??߶:>fjʿ g]ǾD<r<NBvHO?>%e?!=X`>>>P> >H>F?"">Rz?3?3.QkDz ?q?~n?U濕2,juSz?ʠ|>ľ-b%>+;>>t??jJ?E}?S? '~ ?h<"x??J?5>T&?~7> H`?+?G?<ýX?NiC?8= p|g$\(6C3=Z? ?g_??d?8> ?#@%?Fl?6? }?W?q?op>(ZX6黼+x?&$?Z?J>Ȁ>jC>Mg>>4?E?|?w?a?7@g@?r>FcHY7"??AD@h{@'?ج^ 'G@;?,?|I?Mf?%Y?}?^?'?9? >`q¾6xz?jv-謹->DƾB(?K|?{r>s(THHe#%?t>~_ʼYhއT^'>?@S?$џ?^>>,&ֿ1>S䣿ݿ(>zV=>4b>yؾ#> ?>W=K .NK46U?y?@n?um>$ > l2@C Xq]܈7>rj?/>*z݋Q?W?E>wxɿ@轗!?@2@ֹ?q{?8X m y+_?BEc\/bY^d98?VT?PS?}Ϳzo >M@#@Е?ŗʿu 1ؿV ¿}c9_x7m> ?s;>Q?b+?b>=|>[.?R?R??Œk>į%^7F? T?z2>K~jQZ; J??L @j >u ֌=?4 !?c#Cw> ?6f=>>F¾L62(?D/>O<('F? ;ѾI_8$ >B b 1=>nq??-y<}xI=qO=?nNA0 ѿ{iо7 Q0oG>V?Y?r3?H>¾gS9>:>{@q cC {ٿʿ8?N?y ?OH?R??=xU=>}C=A!%HRb;]\>>?=u?M(?\> R46YB^o2m`n-??E@:?&a?I?>YL#/>TW9>7޾UR1VT(]V=>2G>NG8?U#R?1IOG, >#?.sbDbX3+~e=56J[?C?o'!Mn=?ѿ>՟??d%ǿI>5*v?>*=_=? G!?c))~B_ >X&kv> ޾Ղ;#춾(w$v/?TS?6r#IjHUx>n?EſQm.ں\?{?(WM@E)V= ҿ ДK4B>h>fsAݿ" d?-?E0?`1Ͽ˛ұ=V>N_=W/{Lnо,?I?}ŏ??> T*ۀY42H>c\rȾH>#;%?yQ )m? ??"CV|s~؇ǿsǿ*g??[x=ec?M|C6>?i?ӠMb s3hgT>YT?U?>|>PCCA ?14?9@2t@,߿c!پoY ?")?Bh|ؾJZ> ,aSņ=X Nc"1տ׀~_ @E>SUG?IbK# >A}?\=4TB@m_:k&(>N?`6J0?%8@8@/@R򲾵*ܒ#PH?zwZb|:=[?X1ѿ ;= (`˿x҈cʖľ>Dꢽf> qf7>:?6h??,W?\?̷{C~ȿ` 5N^8?g@?TH???B?=é'K> ~GKվhrq |" t1钾վЃp]}پ4p>xnm?'w?w; ])ih"???M?b? ??HtWqVɿM6ѿpǿ6ݿҶLu"?A?g>:>J>xt㿾Sc([+}p?0L?]>8&>ʾ0>B薾7= 3fϾF_ܮN '?,=/_ EP5???ev?>!7eA>HL^J8??@e?Gྴ9!aT_ij^?#1?ަ.+`?bl>,f>A&?d?Uu?TiQa'ʽ*[L#ْ?:?۾Ⱦα?J?iWHSY>?F>??8+1yjdZ?8p?¾|58>dE)C,l??@?6kJnC20> ?ʚ?X@Ʈ? =u??q[?2upݬƈ)Ѿg݁49ᄿ2PϿ鑙>;?z V>x>۾7h:u]>?52a z\?"?O}ξֿ:ӿtԇ-I?7?=DuhjK/Ob?B?!?\ @j?ez4??~T?~xVuSOݟL?G\?>9/4>H?y)?к=>>5s=.qJ2j |>?5g]Iv?>\ӿÿ= [^tc) F ߿|߿(h?_?:?@???t_?SƋ??O>aF=BtG>%@phx۶= a?O>w>>GX;?c$m <󘿨5P濿n!'r?"?6?H}XOI $Ìٿ0-ˑ J*ƿs6M)y]ؿcpn=eq=PͽE??5?Z_?H.?mi>fI=>>ڱ/ꈿ+/e??V:?u>i?@{/d?yM`> ?؞>]? ?\Ƚ?]?~?4?1?_Tw?)U?I[j,̿QY4}<3ŴC'Z.,F¿,ƿٿp>?;b]?O;?>&>6B? ?UMFa&9>3?(>f' 1{?u?Ӄ3ЦѵbY'?~? ?=teԾh#<*?sѤ??l?3?>UwlCg t@u];y[ Ͼ 9Ji/8ݿ`ؔO'>?2 a>xmg.(9ee}>YYE𰬿7, ڼ -\ٿ>Lϳb*zԺ> >ͣ>0?7?]t/?he0@a>"ZR?|h?=spɾ)w C!E:$S"?"?m,U#NDV9 P|]XkU5ƽZ rkKľ.>U:D脾NѾfWs\$ e=>R>ܻ(=<-?S>wBl6B迶'׿Pb??(*???a>.e(%^򻾔}%O>M1>k>n?Ct>ܶ}m|\=/>db? 7>6 ?q=ٚ->1?}׎?켽};3>B75뿤,rcU F!7I' %?/]?V-FտxW^n0st+^f-;;6?dL$ʿ7%;x ĽE4酇?9?ѽ|c0߾W0= !>a=zAR)??Ǻ{Q`I?h ?eF]V*7(N HKf\5=x~n_Ű.3{¿-i翂?CۿE7'a4ྪk'?u?4tdWȽNbq?ɜ? ? s\? >y?5>r'?h?(Fۿ#ӿ8i>6տ@O~ǬԾ>R>vڽ{->>W2鿃A>J5ܾ>G?ֿ󌿸sÿs}@]>>TaXÿV?lc>u?v9?>$;tMTrIȾ4v>j<>Z4Oݶ].53+Ը Ƚqy/Rn왿#(K2Wy>L?{*A(QtCFHD$fe>K>H߶ ѿH# q⩿0OU ڿn3`-Ѿwۿѿ1&ٿ}"R*AN~ KRnXK=辷NM)g}N?K4?yF?&_?=ھ_Bۖ^>uz>1qǾקQѿ'{. Ϳ㮿N1?[w]₩|տ$[ӿoKľ⚿r]88f-P)& c.e|s7l;2qQ ? =GX>6B`7?x>r$??HuHvb4; vҿ5_zh4??>`ݡ?x̾H=,*=K ? 3>vVSDЍ 3\Jn1=k'B[9)YcpEj5i@ ts xͼTB O '[=?e?@S=>Vy>kF_$ [/տҿ ־@=%BNž腿;>Z?KB@1@+? i D &~OBj\>ҿ\$̶L˺\dK?mY4EHcN-_$8Ʀ>x?~?mrr=/ܠ?Y;=MYT%x?,>K??~?Ӑ>w*||m2JCj'>%>*>b?齖%W%`-ĦD/_@,> >`L4>#?ק?2=J'iĿqr8]Ⱦx?{t?*Z?_e=D}Pz<N6Q_H>?&?Tm=G:]zCU>GC=  {+GF) ~$ѾA0ȱC֝A>?0_?\ ?Y cKB>GV>g?ʾ>TI?&Yl>G/pL0*f!2*? ?bj?>?wC>G_?oʾ~3rwO?Y>?V>j8沾'Pբw1?_>Ȥ( >)99v㗹wvs>F>?\1@>qh߾(L ?ĺn?!? ?4 ½ýh [žϙ>8?O?w?2q?\>N}MQ> =K;?]? ??J??٦?@2)@S?>O>[,>ߑ@G]@,@F&@#$?z8q,]G=jF??>a?@+?^>z ?@?d ?!?s? ?t@7ؿI ߽?辽+[G)>{??w&?c??x>mKR!}?zgZLF.¿GbJ??l~?,?Q 5-ݿ-"I&þD?n:z>6$?Jv>?6i?H?A/?B>>SEҿ~m-o=/>E>PF?^\?yR?>p{{ Eɿe{z> Q?@p?l?p?uC?* @js?`=O$>[T_s?8?@n>Uɿp ,Ҿ/፽U ;>I:?/*?wG;IU?N?N?m ?ޭ>r| d;?{?!?M?jG2Bzt`U.lR^ֿ`1n=`՝p8>C??`ݛ???A??\[?p??ھm=?#HO=T??f@v@> ^qD>*ݾh2%?0;?>*lw>F?7Lfjw?[?3F!@kd48-Ͽ=>Kf>Ⱦ3j9gV?8?2ϳ5;jY^1=z¿/ ۿs (yg z?ZJ?Oa)?=M??7?-֬ڿ3b%.)̾q>3 a?<;?>{&!U?=Zb=Yv?X>? @s@?]?3?dB>д|dz,Q׽?,>¾=h:Il6>?Nh? }04v[<=]>? x );=T>z?7@@>#9cV~nH}>a?~2=N_B쾼">?h?ܯ4^>g -?Q ?A2?yk^? ?=g?h?ch#| c?@t?y<_kϿz꿣tS2a}jQʿ >?z2JCƿtkޅ>,y¾W,?ؘ?;-?&g?>o#??F}c=]?;??q??u?~M7@-en㞿 B M>5=& /8WU?f?(? t?MQ?; ?  f-x޾lMƽH"?We??9??Q @?@ΘY>9?a$ʿMv޿gf?>G*~(ҿnt<:H?d?,?\L?Y4?jY?ݞ ?}:@+|@3Ҧd*o/z=sɿ)T־f?V?|>Q>Dγ? `> x~c%{3N_Kg?bi)BsDkVEHuHQU>>~ц>r\+GǿE?_M@xqR@V5@}O%uֿz>U~!>,O>I?[?>d¿]vy?;>ɃV>'=X'[ل>CG?7?HY{+ݾ 6"펾.+ܵR[ۯ=f@V`@^o/@U?zŪ??|Xɯ$yվ>%F>1[>{mH>_>+8ؾ/);?^?\|idX=r-?)?wKVIhLq\4[}JH>!7>k>x1?="Ot> JtTA$>/V?^@fM@? ? t?u?"=Pq?ȇ?S>+t8þb#(BC>>?_C=2?$?>~=]o<WE0?n@?ge?,X?9>~p국/)D?[?V??>{Sp?n?H?>p??H@.x@?Ar?i?|?Ы>7+"7h>8?R>t sȶ>Qbx ދxƽv?ߥ?^>@>X?mW?2쾬a46?>?ׂ?=@mk?󗿾q`Nj>xS?I?S?l>'=h?A@?8?[?? @oU?V?=k vM<-?Y?E?2e?]?B5=?T?h?)_ –õmヿd,'R3?w?Fm ??j?o3Qm >'0۽l?à>{ؚB58?@`fL@>r?>>+?>vཿD>,>yܤ?D?*~?m=?V?>v>9l7<$??1i>P%ھ/LP*6~Y ,eE?$>F?-}?>ya4Fc(ȱA>elOxRWF?l@{@ͽ\ýv?.ܾQqOsD(ֻb;Bb9>o>=c?혋?&?y+U/Okk AjS~ӿ#@`{0>g5s?@d*@<>ǥp.:U=adDg/YZC?">->>v?E?*?N?=NL>ZA?s?\>?K*`:[CRji0_Sz<8? @?N@@`?i=%HҾ:.ck1ſxÿf!"̈́= &+;?7?Ŵ^ +r?i?@z?s?1?.>5&?;i?*?FT?;(?D>`>ϝ )j\Ba=aZlwV6ҪѮa$=$*=-1<.7>qcǿQ¿7 F?2?w??q7?%=$Q&=پ4'e@¬AwŨ $Kݾ=>ȎF:?‚?m?+E?M?>z#>>sfֶN6D=())lֱMg=ptxB23+-QƿI :*m_] wJѣMc`?>`v>?j>ļ' "5a>Y!?">\??a?Y ??-?_B>&~eþ.R>g"ײ⏿$+Jw-AE>\5?\>G辶j#('>"K\¿`q(T?1>m>sTw>AҿvTB=~ֿ^i6 w;2SFf?Nu:˙xd>E lr>Ռ?{U?dq)(w/xqDKվa>smϗfD O=Rǿ˿-a~ᣪa_sW.Oܿ憿-3̂U9|&SNZ1fY!x5mg㿝 F[Ծ|Q&xIfD+-=?[?X??/?}\)@ƿ>ÿVvDDbÿg鿤쌾D6?H>k^ BwN>% KӿU!¿rdNҾU',v TlM'"K?M?GR8?-?'~?C?@I?cW> (=4'8z qžݦsMl}XAq!<x>r?RAҿ.jf?[&?Xeɿ:i8 QwlO"ّLR蒣o̞ſ¤=Ҿ>T %C$O8ĪD,<<"T?"?GG?$D>#>9my]m< ž\8T +rJ=*?>ro "?_uēpk|cC;E亿3S=v>Ѭ?@?,aտ,Ϳ4p"T>VqoMъavxS1]T;SXC/Կs*hG|quE6JC>PM̿!v>R~Kn.jܽ ?#-?=M?87r!'^D \ۿtıEdݿȹY&j1?T?^xƳ<p*M<{FT@|uXfwecɗyOt̿LG2C0dnʿmKX Q*kNA3s]'χ>>z>(ڨ]@ƿʿËٿx EH >? 1>"4?(>k@>Ԗ>s%ÿ:5 Xj}7?**??>a(; si+I=*'~bY~Qe#Hd&'~;gl f;I2S-jO w?^i OPs&;;S?O?`0i¿2<Ơ>ľ?.?V<֊m?c>v>=K? @ ?W.!x;& s`Ɯ$ 1yhᅳۿ"Կ{ %3L.e44~u%Kgq3-{;->OW={ܿD?&C? >ʋ Zlÿ8Ͼ/>T?L?DH?|4?B̆% H:>xevHhd&b>:?J><^u]K76P2wP:AH=K?E?0ۓ?0'Kb/&@?{g=CKnϬ2d>#?}?B?DFտ$"6ؾG?u @wϥ?ݍ=`C@@bރYrѸO?m??Mߌ>K0Y/ۿhI!?? ť?s?v?{?L1??M@L?ڜ?`>TF,T?4"@8HF&?z+>Bm? ?|Q?ZBQ5ʾC|Z+T?@MZ@@v@3@X9@K?߲?ľ?>???0 @@y?W?=cu??X?u?D?L{??@HY@X? ><&>o}=u>4? @ @:?t? "iZr? u?\?MB?a>tt>妸?!?+-?Ơ?ˢ̗1co1=\̖?'@ !@oپq>'=P>7>;?X>N6&>K>2 >D?Q>> yy???G5`|  窿s)>?@I~`@yS=\>*r>ZE>:a>uZ=ܓj?eY?6U^o,=ȕ>ae政:?`@m?}~?DrS??zs?"?9 @@.)=7=Cz?>R? ?7 ???pD? R||jAٿ҉6P?' @y@p؞?@qžRo/>Pb??>z=g&0>5>#? ==ƨ=i:?t=?*?og=(D2heuG>-%;A >pn?+D?)?b?. ?+?V!?_?f? ?4+>!i9+-6 ?V?\??L?ɾ>Zyo>? @j @(?(`3O?ޑ>?hE?r=S Z濿F??vn>>eˡ?c?>pK?`x??? #*tR>if?1?Q>'꾿)!(*]S?]?>>XJ=!Nۿp{FJ!H"x:q-i?+B>l>=i;ÿABZػ [L gnoU]^O># ?GŨ;g!E<ss@I@ @Q+?2氭׃Uhgc=s>>Zr?e?-1?ꎴ ޿.q ̿m<<=E{?ڙ?{*@$!@ `?tƿ\SG(0;5>%??f?1??ξ?AϢ'?)@6@@h?j\Vƿ[<]'>7>?^ѽ>u?_?Vh?O??]?Zy??Di?>靾ed>,<_:>j%?@p?\g?%=o-QJHÁ>.>uzl]q)i_M ÿEϺs.? B?і)?6>?6L??.H0@葕?>nr>,zCo=ӾF4"?2?W?Mi>2Lȫ+ÿ_oߞ?x ?ZοA}dFUb&j?;?p@͢?(Ѷ> eGP>ނu<5 =>50>X?!@:GfAռ=i=89|Kms<>'=X?ǖc>w=pW⿷es͋}󿁇ſP޾=V=K?7w 8ӿ%?Q?W?u?< ?-ƾ6[*=Lw)gJ>Po??Qj (Q<F ȷ`={:a5L>·=Q쉿er`b6JF?y?P⿏Kpr9 @E@?>v͔=a6w>{P?S?(?4=ʘ, > >?l#@_k ?տ ߿~;HGH=}?ھN \@ ~6%׽RuH@Xb>?>79F>c??\? @ +@???+=䣿'?Y=vAa,KN 8{?H,?M? Fҿ޿A8u^ծ>wy?9?vg>tZjMjdSB>o?0@xC? ??g?C@?~@T.?F??r?>U>|?K!倿7 ʿ։|cIد%?yt?HZ?jՊ>E?>z?>~qZMÿ`ᢱ=)W?|?ɋ=B}x>^нp¾Oge:?nv?@7@UV@-@@J+?V?џ??$@ @NDŽ??1~?,>܀>f ??>㺾|]~`Pd6*?L"?h{q?Xl? Ф?@l?‚?yz?t?>W >$ȃ? K?4>*?8>f@| @~?6o?*?z?v:9 q*!&?0?+r[5F9ט+Y_'"Ѿĵ}.J>=(r`;@F 9=W??= @_ٴ??>O0>՚>?=L?H?!g4l^ M@@7@z1@@' @g?Ĥ?ޢ? ٽfȿtֿ;IF=Y 3!Ѯʬd\Vϓ>x>>݀>8?ğt`ܽ=AgiFO/?>ź?x{?2ǨE?Ѣ?{>2t;TbV AS ??@ #@t@p? ?&+1$'榿!gzbvc#>BؾoU?΂[J|XҜXݽD䬿qT2 <>y>ɿ}'X&CI)Ú=&?G?Z @4:2@s@:?˭(ؿ @Urk1l>yf?0= ;( O)|;R<0?U?}b;> }aĿ߿'L`٭4j׿MptpF/"S'J'?=ϋ?7@g @?A?>>NqA]G5To)??Lۄ?r>Kfqؿǽ7ͦ-?>L~dm$ @1KpտE!&?n?iL?OD> o5˿K` GndnTʿ ƾ%>}->5OFs`뫿b418᾿eh=$Z?g-Ŀ"ǿ6}[Pi4~=Z?>v6)=ś!%$O!'Tr+;\>h6>!?,ڼ&@< W>rWJ4t.Cc >yn>>;=pE@ɖ> mB2,P(?`?-?1{?+{>?>㉿ʝޞ>"V>w'Ԡa/'ߒWN~(=Ͻ#L8Ͻta߿9FmnH)S%@7 :$)j>>C>͢>! t3MC濼3%@l̀>YYI=,-i<#0s?d?I?#R>}?fF?Y? Y%Km˽b1OTο@x>9ʿbV>w q}j:ο4п.ߟ톿.l `pֿ˫xNl>{3>,i)ӿ嚿[쿩N=˦b&v Uݾr4otپt>:r>fr^M>j>ޖ=㿱0 D뿪zܶ!-5 XBAܐ> >I? >~͋4_Xƺ̿t̴8譿Q@l:L2#"ǿ?6X=wϿg I8¿$Ǿŭ>f Gw>͚½C?U٣=@G_?">??-?&??v?z b>C mѿH}M̿Yl&jiNRS L׍ rNK=q>D?QP?;^𾫝} ԿW!ǭ*!N8f՟|5Es'/Y?t?>n@;>힘ww{VϜſJkƿd͋-=R |5Ȯy>Sn?Y=K=>2Æ2E4`>5U9ӷvxDsڍ8N! 1A>j0ѿh؟Lؿ4iPJ6c#?X??0?3{ćV@\U"I:ֿ88͸ɵDڿqÿL.;w:ҥĿBaASC¿M &aBl/ 8ybV 1JڢM2Ovӕ/'<9ƿ;Gȿ0:K\.C1>_ ?f7<r@?9!v?d9͘ŹIsEǿsf r<_(Ntf4.S7S: {+@R+:&KQZ~O!տ?N>>>\ɿ #~:rv ?OǓ?F???m`?YӾAɾ+ѿWYڋ<=>>:?n="ޅ_ʿ%&R_5x{y}W#QZGm bb:aĶc4 IJ w_59Ŀa$hȿEҿ2f>ڌ+JwA=J~>@??!=2m7տ((EV8)Z= ׾ZYc^MlL^bnsv>GDaѿL]>>TA؜4u| ޝ)ʌ)9 ~ɇؕ*#ʿk/xX4뾗QͿ=9ln]?>rcN-Z侌?rQ?^E!˨mlE7:< U`:F]o>=<@5(6[qPth3&~_gjD׿?hھ#?b?s>#>/[t?n >qP?x??6@z0>84>bۿ2,$>ݾesʘ>9?Vn>ĿO+{>J?]*9lֶE&eK-N<y?]< FEeSھm =Q???xs过kV??w?~??wy_\-Tȉp6?Zs?C?&Jg'?nLҾ~Cc&*oq=/X?HbH;j򻾅?w?9? q\=9K$>]? +>1F=N>?@g @p?W?X&@x2$cR7ھM1> z?8?=m'@׍/@@?>پ.H>idd?=?$t>??? @z@Y?7yϿ><ͿWIa7C>.%?*??n?(?j??!&?( >P?#I?ZS?ڸY9w?B@@=?*?Ʃ?H>q)e1R" B>;İ?DFٿ žT>&%?Ҿ?%0?=Vc_56>?8 ?P???(@@X?{? @-:?Ȑ?>>|鿄:- 0j(sϿϥ:>71?@G ? =֭þ'+=!hf%}<"= 銾Bz=?#.@J@㧿:62zd> @5q?\l?~>?̲>mj?h?~? k寿w̩>o?2@T}?/?e#>PG)J>y:&>>a>^?B >?+^Z_?>].>qE N3=D9?>?r x?꬗>5?ƾn{:҆n1,? ?`>???Iz<Yr"=Z\<U oPu 6>fo?'w>+>?y>_j? 5䳿><ŴW?X??цbɓyHhS>e>!??v>Kf4Yҿ3d! J^3?X?xT>&0Կ ĺ| ?ڽV.]>B>p?B?ž<? ?J-;~Ժ]Цtb?+?? t?cFGS\LӿQ쿍P 76| TyzhU?\P?1@?CH?`?ՇlVV <~Bv:H>c?̿?:??a;qļ?\ @?wJ?`/?ak>Z=﨓?;·? >!Gǿѿ }ѵ6tO>ջWwϿF<?o@s @ @)?/?Һ?{l? ->=j࠿-ؾ- LS, nǾ I>o>?Ϫ? >x ?ה? ?^K?\A?@ؙ,p0_?@@4@B,?*?Q??7?>mm"z>kb>k?е?v?O?X??mN?tbG>i? ??|39?θ8(Ê>D> MK9Ҟ?@]?i=5#w>,Σo0\p> ?%?p¼2>6D>b=>W7?*?J?%{?J?=޾gi>==? ???j>?}=6οZ]m$>*Tڌ>Xnl|$ ۠? @Xf2@ hHs E>>=@?>$!=>1Tճ9$G+d=>>y%vɻv>Ň>mod;_43=R?t?{t>#o=5=^=UؿM%?K@s@g@x rqU# G4ݾ>+ѽElj)5A?n`7G[sb= =#{n F>M?v~rW*akE|ڽ=X m&q>?"N(4? B@H@I@>S?V> 'Yuۃ=^=l7-?Xzi) _[>[ICj`?ťT^?k;Nf=p>z>Tܧ'ţI>O?90>q?o+?˔@@q?t??>P?1\_=7|&Pm.N>??Ј>=s5Ts-)i3-p?6!7Q?hA? 44oV #>K? ?Pu>t??f?s?݉?J@M@?j@ @G?'?0h?vʫ񿇾W&緿@[l48L\?W۾.?t?Zܢ??J`?m?>}Tfp=.pmB =>%>?8ľ: ɿ/"2=Z@W @ҹ?1`?{T46O;Y7>>*>V ?& ?"Kya\?ϡ?o `M˾^6?k??c??@@?*?/J>>P@|?RT?y?I/?z?nkX?Xt??<5? Dgg>гS:H?%??&{ʱ=2?l>fb>D3L>Iw?̧>.=x?o?7?o 3D ?J?jEz?2>{>hE>L?0==ҿY߿~@ @?c\??Mj?ׇ?(?@տ?? ]a>o޽7$ḧ*>5y=XItQƿB˿+8䐿PBK>Ek?HT߿/$x?~ >-YWQK2=|PIG'w?'?ǿY@r@@q?A>#?<0?U?Ч'? @?-([5QjJ( '@<)$C?SE>D7bտeͿ>4ſ ۿP%^o0XԽC宾wȾy־~W>x>\ (Ĉo $??c>ʇW^;ǿ1 >+?>Ǐc>p=X?y?9?6?>S?? (i@}[߻y>]=B Ы񿸇ľE"ܿvTZꢿ;ğ̜苿>\>7>[3N?|Լ?2>ڿ :#kD pH8Ep"ޭ*wK ={/?W?`>>v>Qǽ"u넿l-1vF}9g|7 ڎݫ>S?(Y?aNJ_F!#>4?E?UOGwʿM>$H9@)B@@@x??ѾⰡ}\Fv(x=?s(<>>x=}uFi\`ZΆAzӿ Ϙz31 $R>w??0?/L0K_Q?^>>:->Z>^>OS>ǾP͓=п b"??'?n??\>B>|,Lp 8 ,[&=?B&=~kVP8 $F=C=~Ѭɝ>AĿaE@=<6l=;1d>lW=!W=ɽz;ۿf_޿.H[_&q}zOs6ޟ>Xt?U.,?;?a?@@I6?x6==?cؽP:ϿА) U;EG(??T:>뾆tg> t> g4??P|?؈пC >rzUϾ< ?>ɾPihl3ڿ-l܀1]6g=ƽBv? /?6?=z_v_~pU52uÿJ¿NlVkc?">>C>XX g–?zF>X|RK>!?@O"@_FV?D1"s,4ަH;P%R5F27nl"?;˿iy?:?%>l4=%Ru+Df<7?U?C>ҵA?O^?G8}>n4?)?>-] ?;?2??g?S?M?=n?l.>fVYD&(6Abs==D.>*hT(Z!wan8G> _>/A _оg^=u<3ټ <r?>p+>b| K8xcE1MϿJ)3?)Պ>sqBl+56qeʽ{2@dQww>᡿b, v&"]?R<پΗII6=ܚ;.gyQ 8Dtёi 3ĒQ_ >w#h?X?3?Δ2.Կܥ(>ӿSr?GYm %cjtϿ! vϿ97fS.-W,!Q`5SI'?1Y _(M?>;}t[:huiOQ'~O;inKiiSԿ ?j}?k>8>=>o?L?*>srx( Z00ڿ? ?B@?c${>*?$=3qC>N??U,3Ia2VE\濘G駽: ƒx1%j0,M@u(~QZ=kI\ֿ{־Yb#s-?߽l(^\= sI (J0P̿Y|?,??rǿ߾нm >QW: l$?F/?!J?W oqi1\CAпj7>ǰ?^?^2k#BN^[ﳻn/ʿ Taݠ[?n?_>%/tP\>, =uq>->3>D=4=U>H헾xIk.MH쎠GmL#iiB3QۿXH?.?ㄝ噈joo,c_{kX=יĖ? @OT]*~a%|? e?NJ?c> >x1?[ >Prz>>/18)B(龾ٽ Z(׾ 8d>2X!_ۿƚ;R}3?nlJ%Tw ڲxh>B;(?=.($>nH?!޾I\q?hI?f/?)οss>%>m̠?O7?s?Y{?+೅¿Ľm@ uջr=L1?T?9>I'ľͶ?58`'Z>7@&):]'6??ϻ4QKlN?@??g?v?Ʋ*?x?+A*:x??L?{?M?7S?pQ9,\5 :Jє]$m?I @.4@~@F?V>q+鳘> +?+?&?X?m?j?X?hl?;:ο_WĿ߆ g^Aa+n~y?8'?S8?M?ş!@?? >-?m?8h!?w?l?:?ɿ@@z+? c?0z2"s?u6vk=hB?ݼ?ý>ߦxh.S?" ?? 6u??Y? ?x;@Y@c?(@H@,?R>c=]3}쿈 ,p>@X>Ό],:B\#󽇄>N,)>{l`u/P՗>=?v0@F@d?$V>'8q; ȿdVɿ#?@\?Y¿;ɿ΄7z=|f>rR?E?>~𿄴s>=??w?R?{B^Ⱦ/>>2X旿Tɾ% m>?K?l84=c[3>P-!W:$A?ؓ?^?o?S#1>2"?0O>,o9fEdڼ#{= oo??;@Z?<ؾ'⻾޾n(Z>(gΎ?;Z>[Nl̿ѿc]%=T>ީ?K?m?ەU?\9U t>8Y"F.߾.=Yj>6Յ=s|4C=??-??Fd]nV*c>?B?ZB>g>IL6{׼1U$? ?o/= >1?!?.'@SBn#ޮ?!jb?ulm =>A?Z>?@@6M?#>d??֏mƮ cBKF0=w>v>m? ?e'S`)> @H#@LT3@Y)@@D?|׾4?CsVA 1o#ݾ>:ґܟ<4?x?O?:a>3ɐ?B?h>WIz?f?b?}1?#1=w3=\?7@0t >=_ټInz&x>G?kc?P?Ɲ?0pپԔ?h?ǜ?&>6M?P?X@a?>:}?? ?rĹNž ?"].? =%`W>V⼰[Wbܿ=<?ھPJ"=%0Q?R?x??*Q?9?>r3R>~h?Y@?vP?r?~?n@"i?1@lUhҾȳ>濿4Ar ?>ڿ5^A٭7P>R?/>B?3??I㼿t2S?>4fP?Ȍ>୾R>LrŹ>9>~>TN;wv¿Qz7qIz="ҿ0͘ >,~>4D@Og@c\`@S@]e>M,G1i S}Nǧ~F>6 bd8>AJើ)0S=x?'&?.ݽ\8ԿX!MV C_a.IkbbjO╿>^??@2@#@0?V|?o}s@ҿz벿Q܌nPۡV[>Y>lH< =&J񾋅򎜾DHHDh8G]c "d/ <~=>iS+g%+?fV?F?-?u@@1@@S?;I. =wg1B-`)?MI@ ?is?њ[$*=?[>X޼Cb=m>pQA?fu? 5?8@ @.@^@[?.?{??>k.BſnVA>  :ZY- ؿ״>o>P?%@?~?@K?!:A?6?cs %l~Mƿ6G `?d? S?DžžjY릿ah~Wտ "=?6?? ɿr,mҞ>|?8lqɾ?΅=St=ZA_}>N?>4h??5:=н]X28s唿P?$?>m=! '>vR?b?a?wD?^حzEX\ze`,|ϿB J=6gC=QϿz2?'8Ͽ#߾D>s`>$l,?>?qgu H_s1F?~?n&?’ܡ=,??Jy>:ǿZJ@@ ??x>+#?U?1 ??.Tɿ > Ѿv>ߗa>ma|^࿹Կ[9i>Yy#<0 ._Z'һrXT!:6?N @-@.?<7ҩT;?}?L8?c?tAvJ +gw?!N?F?T`?!P?L?:W>2?9?0:pY7=(lg?2\?A!=-Ѿ޲?} @MZ@@Շ?O> ??0?znP>xh|_\2'+VM>q8?ׅ@%>B>`?)?)cAy 6~H\>=dU^A w2'|?n,?K7?!%m)޿[os6>@}? ? ޭž$;? @=ur@~6"@ӻ?a?۽rIL2bIPЊ:A!>/џ=Y>>d?̦>%SUk?Z}?pcſӦJ~뾮`𿞫^,+G.qS~c">ՓI!`C?ߚm>=xoD 5Zk?`澑¯@0?Rc>r՜>wu? ?.Y47p{*Z7>?mo?ʵ?eL?o><>h?Xd>Z*yx"Ծ<qK-qS)sbcǿbc"'ipM;>,mӌ?k?htuJnEyR%Q@-@a]@͐? W?=?ݸ?IXh?>17%kȿv˿:,Ӿ-=чg<===޻쿺Q+gFGɿ L E{wѾmxNvD$.c33(?h? Ks??>Cz;H|]i?K?68>=1)Y?%?~.>? %>y?I/=^ui?#>FZ=e?6ھ| ÿ =?j3?dX*?=m?(e ¾*zړޘkgn??AM?>Zr>˽G'޾`>V ?>i//>?Z>~=Xv$>"^UPw]oߧz>v"?U?ų>ܰ={.'4%B6:jI!6@@> <>vPȴ=!ாCU y,m|=%MUZCze ^K>I>jڜ 9p4:@}fW>~>v=2=2A&莿GɿV?W0?=$T?7LMU2Yb?e"?l4P; es潪=TN@l_'`o-bw|H.]ھz>侹ۀd3 ҿ2/dٿrܴ_ Gbx=7ކ$w,/v s2%Ͽ_5q>4& @||8Ed ( N?m[O־ ?+?HJKp!ZٿUGM&do(kʿ49Cǿom[jsr]? hFxt&$?&ܿFSr^>gf[uG3j*K'jBwݓ޺R7#)w΃ ?e?N'?ՌQ?sk%?!"+H, fÿqn>U??SEϰ>{?aMt?>__z\?M?T3.iyOAςC5e"^4iBXIy%TM|~Rk<`n{(޿S?>X>Ў+=aՔ 'D>3,?e>3hҵ=kS,u>=g=?fM?|/et6rt!߾?3%?>@Z]+4s| j!ȧ;-ſٓ 4q?@x08$b4?%?b9>ؾl]>؅??6??+?7,y@x& Ғ>c¿ gӿ&I62߿b)4?nx~Mשr;GɧH5=>F?/? ?*?S.?o\ݿKhZ=YʾSؿ:5>"@m @???2>/??3ƙ]?|s髿Ē='/cE?}????v?L=S=?;c?[;@_@?@L)?x?tb?W ?犗>0ľ8=n?Y?ޮ?ʑ6?Uo?Ͽ!o=Zw@=Q7?A>> T?c@gS@+~??;@˴@?z?-??'/ @t@)?8Co` )>'׿%Lύnd=o?>D\ꭴC?Pd@C&@K @bJ@6B@dG@v4@@ @"@{?3j|/Pg60Z&?5?!/D+qe+5= ?~_x ^-ɿZ1?>p?>:?&E?=?"@#[??R5?F>Lǎ=X>>O ?p.@?u0ſ:L\b>1?V?>b?>!g 8>? ?%kq?l ?`Ou]>N#4>2!? =??ZO=>C>kw6?P ?^L6?#3?Xm>O?R ?h/><: 澌Tȿ)f?XL??.>.#?ē?|Q?5?x1?r>jh>G?ߎ?S4?߾2V&>|j9?='y7畁>M?}?b?*?hJ>P>b>4(>z>1>R?>ӏ<!k?.N>{>n?;??i>?ѿNd:>`c?ǿ/?h>b3?\`? R<uBpqTB!Q`?Ő??\??4f?RE?%-%?}4?(M}@_or3^ܷAĿ&~59sr>?MI?>n???Sd>{A>- Y|?˾^ 4(2fyHtŎz7 x],?`0?fD>!JA>??&?ݘ,?8G?L?Ik\=$1??>=G$$K7lp#ϼImn_οBbݓ9%_=>V>??Tr?F9? ??@Z@D ?[?>=`?u?$u>BnyL4)~:FH/0Y f3QF?)?K>TK>료=M>?Y>?l?X?E??-Ut j$=¾ w>Qmd$=4 ]be*;=#>_?q? YK?em9?ɋ<Ǿae??| LϿ|о}?ܩ???:F2¿Dſ&4;a տ-ƿh_yyɿO޿MB`ÿ5ɿ'Y 1fq>ЅY?/h>V?3@P+(?F?e>jMԾ~Oۇ׿*W߾pݺ=d3G< +p=A*iV,f9wp%O}@ E¾ a?::@[eY@>d@}?gl??xGj*+ Ʒp?c>sj&+׿n_>+a@a5￁V;'=" 1T?=5?}O@V@I?@G@>1?s^?Aq?" ?=1}ߺS̔-?G?>d=NB~IJt>"(?eU۠]f5YmܿGoɸ\=Վ=Ŀ8DȾŃ!?q?A?E?X?|?W?7@\>->;A>i9a>du??Fx^>[fS͑6XB= ?ja'/ÿj[D"L £O! '= =W/0%|޾NdCѾ*ƾ*&?H`?x>V?MZ?a?f?0?E??6@=?k?N?>V ?e?Y?$>;hJ俔Fֿb.qU^f}=\=ʟa?M>[43\+'CH-CQϿٿٿf6' )R[r>?=EZ?n>RD?c @4@@R@c?sHW0"C?t @j>g$;ɿ•W8sMj彎?s?c?F>Xױ2F;??ij-6hU<")?f"@l @_B???O @Gw?cP>4cÿɿ\XI 1˿{>%@@i?m>cp>UXk??;@Sb !~?n>]l>$DInܾb`05x?Pߥ?an:5Hο&=}?OB@u'@ў>#D j>8?w??,O?0 @1$)?~f?T?R>PO=zM>>e.>!?)Dc>ۻ>왗ݨ0g^l2-fmTڽҧgĿu$̿ި?ґg@Ͷq@Ue?1;0x=>?8?b²>=r@G?>֑` CzBAu>I(>m v{m&-O6=~v=&?A? b>QQc@Έ>Nþoc8d"Ҿ`ޢTt>P*6؀?#&<@Ҍ@p@h@ڙ??4okl-ExA>?5>cy .2$j㋾鱴#96"?R?s?U .Ͽ< }hъ?)I?"wPɱ>*"_|kվ~?:_?`E@@׃@(?Y?@k=R4Ὼh;Gb#?AE=HVT\Rҿ}Eb>cw\ M|FTF>69JR!!Y2r ȾXzodտc$"Kh{^fh`:-A?P?N?{e$?2}??7Ύ?4?RF?R!^KĭL >I 񆿵{"[N=)F] 8ſ\!\|G,|X.v=l_(oix0;>v+K* ,ht,\? ??m??]W?L?DT??V>LrsU^WѨϿHa԰`G؈k\2Hs07T#>Qo(Ca3zQua>*>"36Vmmj?>?>CKF-EICn2+sa]b?}?' ീ??,>5KN,uL92_.WDRr=+Qƾ%W=jĀїH|KpЧfKYgȭikj>~BE(r?/?avǿ"Di2e|oQIpzg74?y>!>!?1>ڣþ»驿Zv- g'%cSrZ?G>}^Oܓ/?i?1>&͹?(@l~?0?ָ6>߿9wɋ P|pp@B?me Ϳؿ,ο3=C,տnӾԺ +Yp?O8>䓿 P="=3Na#H>Ò?4K?U7no̕?/7?Kbnǿ¶ھ}>=/23' YE#ƕ!/=R>J〿@.E?^룿uȿԿؿۿ3h>'?~?c?$s?'#?#?3? - 쿔ɛgf??R=%>?'UEemUf(=o=_.&DMR`JUk{Uo#.yڇT#x:H%P??oݷU'$Mʚ>yS?no6?yuq> ?%-?DϿ|?n#rѧn2c[xؾ՜>->.z!{IExy칾] =eѿЕTq=I%)%? `>2ܽgr>̈́?Ki?GRB;>&?ʌ?n?:i}>9>iW=X>>?U? iK)͘B޿bfmzpȾQ?m{O{?_2[u^?z=5ܾ Ϳ3ҿAiPF?@>=2??rIp@?x5%?^<~@-tߑw??Ou??C?ܔ/¿anؿR["=z<"@þ?-_>K??G,߿{$˿¿6Vcp8o"c"]9Hmп^Gd^|(xz??m9NuHƢ'??-Ě?9>W9Gm˽>s׾7\>؏|?_?aR0-ѿ*Ӗ=ެ?+?iA>-:*bDNotI[K#;ֽ <u>L?JF@18@ፆ?Ҿͻa??aɮ?JI-mzZe=Bc>.5n8"*?U?@ B?X)n,?_~p?Dt7ÿv`3.?ɔ?3۴?ݠkۋ??Jk?Sˍ ps@Th?9?9hf?%߿UH.4?@I?@O @Q\?s?U??l\I?a&ݾk?,?t5)D~r甁= `:o |?Nd>>Hr?t??xH@ u@?@@J@ k @ֱ?,??,E@[P(@X@h Xp%bE/* n8{q?K)t֝v?K?>>?)4@""@4??V?AT@1@N-@2@L@/ʿ󢰿]VȾ0Jֿ'cPm0a?cUZ=;Ic>??@?V?"q?)>5?o?P@!@9?W7?>?q @n$U<C=Dz?JblJſ=㱿8? ?ʔ>2?E>=<>a?[?Pڴ?(Yܿm%?2?e>>T%3ce?Qk?>8>Z=-ȽJD?Ac? >Ἐ?=?1]?S?'?)j&=??>?SUi?Y??xnh ֿ4̿q??2?f???k@#?"?LpR>N[>Yc?҄R4="??>)i?7?> Ͽch>:ƿ'8H.>[K0?(6> '=u5;h?@^"@?(?A**޿4d>EmyQuFq-zYUxe w5?[3??Y?9֢i/I ]Hƿс151zp@j<^'>@'z'@>6n=<tɿ䞿%;N";?y?vyAEc3>9>:>}&>? ?/}??B??7$#?%?"?=>>D?x?f׾hJĿldᅪ䡿c SFC#f.$?ԇ?D\?[>^@rN"UT]5;&m`b瀿Be&%?f)@S@#?(>{>O?n?5-??Y?w>}߾}2Nfp? nWレҬc󭳾UbPeAv,?NFa?ŀ?*=߇da><@Vc@V@ yK@UE@C@??硈zd2{??/? '>3sv(8z^ T)eža`ȿ,V??n?=4C?{?>rJҢ 8?b?l?Zl??l?4@>q? O @ @"?G=h 2? B2v=Ѥ??>62sʾ5 =D[ 6dd v9󿅈)흿dgϾ<^ꊾC>>{?J?V@?:p?U?@uʰ?3m?>u>>>}V!oſ(Nnt羞ɾk%bJ"9cljzhHv} Uſ"f㴿5¾o0t??@ @@w?z?5E@v@m@>;j?|l>c@#ľ9>B>s9i:4|E(&ĿBt?>z0Rz"׾m#`?@o @XM?䈿#6r٨B3ھ"C?_kc?3 Lq&E,ѐڃ? B@vk*@>@é#@67@4@v#@٤?0?QK?0e #{?E=ȟz ex>?;2?H?6?=%vW&N@V@'T@.>-6;IμE?L?Ǒ=?G.k>[P|y@J@.B@6*@?]@S???';RN2f?$ʆ$?)N.`B =>8S @®>?,?oQ>k>NNY? 7>O $L>W >?#*C傿랿駿8ܿ?s&A?+?Hҽ̿"<8?8@vN@B@;?=o>'~쐿cNNAHr?|>C-bq#̧vC a=Z?V]^G ?4ʅ?Z???n??d9ǿ 5J:vUa^b>;>+(ēB W'>?է>)>@XU@1hT@[I@`*@cs?˿˿/K[׿ >^cfHؿS迏e!occؿ׾V?BM?W|?ڧ>=B? %٦*rH1>m-^ H ??Q=f^߿w幗?~??Zg!Y>@i@Յ@P@@6F>xo 3鿜C0ſ('ٿY/\پ(*?TF?J*aHپgu>>. 澼̿ؿ[B>txlJ(Lg5ɼӿ|i>V=??k?n?@@ @/?l @?Y-"E=J|+4"> Py調z먿] rT??C@?ʧYmPڤHYӕܿlb5#4Sܾ|$aٿrO.*?wF譿*|鉿[-)HBɢǰ?)h??c?>??Rh?8ѾAf/4%> I4eN@y>T=f>B*g?[?>ˑb K˿ DQg߿q<6C$ sſɏg@-7̾O?e?!׿#6U̿g꿠Bx=U?7? R=< ?k>V*?q>Hͨ3ڇ vܽ@@?Av?g>+D+>j >ݼ>=T xcJ5N'%?#Gʜʿv)=>֠?z>@MN,Dz#L?xc?w!*4@]}8??Oaaz>?hDz?h#r%H9ש?@?)??]?T [?Wrտ  zڿж(WLHڿA >FJ迩6֛??UဿΨ3<d ?l!\cdľD=#ҺPݿ.nU%wGY?Z)j>i>>pO>1]' Ŀ0-ȿĿU-;-[ZS =; ?ï?=IL!ܾՌRJx.HmS??Æ>V̾>>RfE9g|6陿Ījq-zo^4 ">򿅾ׁIu ?/>}G*vZE&>?Ե-??>yA>2S>=?P߼>}"5~Й?C?]?M>J?˜?ۿmZ"\@ f~RO f?4o?䀵݈\ C>'&`=޿/"0?$H?3e>7ov?u?3??܅>m䕾q=v(p??)9yK`HO>_?%>9S=|Byj?>.S>}>>8#>Z R7>=H>b(>䲐r􏅽Ɖ>[>2?H(?+>Q>o뾬> ?tY}KyO" %?.?PK|>wϾlaU6?zC@G?|*?*?p>{>62?Y?M?>~#?i>ږ>=?n?>Yώ/2?4ZcB@>i\y= >!?aW?>V>K >ƿ}tG1i?[?I>̥ ?[>;?c@.@>׿1[0!#?]b?.FHH^=X~<<¿cҩ=ko>)'?=w?7?R7?9)8>wn>@L>?č>o?h?-T*8=@A?Sם>wfrOg0GX2岿ք)?yF@34"~|2[??,?7??r;?|o?{\?DK?f#'6=*1Mjŗ>ͽ @8-L@ވ!@y ?U7ũ7et1]~ٿ,4o\m8>6[x,6)!<@q>Tu??$ ?rt>???>F(Կdl]?X?N ?I1<+Ә~NbT?>Y%FŨT" @? $3?M`\?g@2  *ݭ# V>>!W/׿<3?Y*??D¾fU؏)>^p?ͧ?]?9%:F> W?`?4ի>s { >E;?; ?+q>P?3?% ?4~Qy?`?8&f{B?k#@D;@F@M? s>Ɯf<{!?7?/L?m >Ņ>֤>ԻMEн >܂??A@!%@~?^?G??拶?.5z??w@'?L>55>e[?s>|?+?h>->?jڍ?R?B? ?{?8 @!@@@*5rq?̀?!#PCTny׿9XTZ$2T7=>&%?=> z??U)@lZ@VI?DO X;оٿɆGք=W?uZ'~=%??sDҾl8>?@3&@{=^K-?r?hV>Ԅ?EʿǙhnP!^?@J?8??f@!y>.0>\ ѿg=m?ےw?ѥ3@gϾ40)Z '@U/?\ÏԿAd>R]SUڽU>mS ?G?5@Z@$@tH|Qҿ:xވJ H_;>!/>Ml>`K?A@D@@Ǎ !:仿[lDXSp/=>b<0?>\@"!??nV?O @a @@@Fb?1?=׿m>< ? Zj9 8ъ=꘥þn?(??? @t(@@~=@N=$E?|?G#@/@?%B?K콇Z(.'8vdG3 "% 6s??;'>h>a@=|?L?Rx? @?ƾ?>6@ۡ.@-.@@z?e=]N>>QY3=a; i  )ؿ6b'=YY?z? k> ᏿6HWCH]??L@*w5o*?7@3@#@u?•=U ƚ'i=$ׂ ᖾ.>Z< $gkF@I.Tߎ?/?^˾DR},|R?dD"@M4@tC@ɤ? >=>C? ?o?a?x>>?;@>hߑ5:=R}FV$->"le*???@?o>tսU=? @ @)5?# @b@@,@ w?B:>"k?wP?*;vW?U՝??>Y*ڴ%]l"8T?'q>7>*b>?Z>쑟>SU>'?A`@A5@.@ 6,@n@z@?3@?_?W?=N>PU>{׳龅F%Ç>=j‚>sj?p?!مʽ<9=?Wb>f\ pM>k%ܽeƕ>|[L6]>J@:]@@FF@U?Y@M@;. ?ξ?>\=4Ey=,>*??ŽA>>QuB aZ8>*ž_}S?#?G@ݙ(@E@.@[@CI@"@7 >+0@,?Wy |2/>g???v?DmX̦]ÿyA'9^mN%ֿοY?w?Jy;>X=<x?Q?ᾋBdH?Ǔ@C(@F:@|Y@].@'P?`j?}> ?$??"?@qF3>xyۿѿ; ʰ@־?γ?B?:ޛ?`[?<[ #k>rL>/=?t@"@|4&@#@s9?>qNٿ`s嫿6? >Jο"¿F+??n?ct?|?D%@*&@G?m_;?]>P>~?Jϲk((Lfw[۾0)"-^t>Am?\=/P?e[@i @s?6@(@k0@40u@v@?(O׿ P@=1>*V E=:u ?>!?K?#Y?pvޔ?(d}?J9g;G| p8v[`LWNJpOY>M@6 @!?iK+>?8@3-@<@@ܮo?3XپBXP04@?V˜RG꠾ 1za>$R>ʺG6Uf>Lh>ſ8붿[d.=}b^foel&^̿zV?r{?oH?ʸv?Jˏ?B?s? '? P?5)ri3 6PN?45@?|\sm¨Оy>S־$X.wǣLS| %l1O'޿yS_w 1/1#s=b e}Jy? >[ξ Ҿ!+>Ʀiӿ)ƃ$ k??s#*0ƾe(w>*ƾmKdӿey*3<jͿϿjܿ"ic򬚿'kο(޾ϗ2'Vοo>ǐ6۽>)?Y?C?+F?cI>r4?}SۀVe$neO@O]?Yo>Bh?@Z?0?R?>Sw@>@I!1;u-)u#KglQG 70}&ս=`k>LF=庁? ?+6/3"?N>Z>򪿂#U>?6@Av֙Y W&߿35M@ @><*C<>`IvSy w忐ҿ[hqǑBf>A >pB>VT>eJ>g{>c?<>1?n>etbDycQ.ʢma&?^N ]+˿rNĿztpŋ?D?KobN>^?hp$.ܿm,xp A̿U_ttB[P؎>l{ @p @7@ ?N7+Nd5짿gC͢&jtʔR\>?#q=U=;O??\$?C515 ¿ޛٿ<=d?"oU?DLG6*D7KF1*6tP>??^f?w?\>4;i-rM>q~wjg[>n*=z<?j?G|U-c˿¿LYy>y?_͖> & ]fS ozO>|鐾Vj˿ſ\FjY#K=q.">Jiu&߽kbOɍӿv.W?.ֽ?{ &?>gB?ui>y?M@h?j ?|cο=F@e0?Ze(?6d?,?n>Xbf*)Z??`Ցd>A?'}?ʺ2?Kl ˾1 Vɯξ>?ht?i?̻?ÿAa@>v?Hs=ѕ`l<꾰ʑ> ?m?"` @]?McS=dς&>>`w??P?"?>??2? @@ ?M?,A?>G|? ?'?e>>+>Y[+s|=~@\ˀÿϿG<=-?*?$39ؿdW;3nGO_ԿD7K>L6?"@'@??M=?zJ-g>?@?@(x?_D6Zy[ e=.>m022 ȑοϿX izh@n>!䋊Jv?@nN*@=ݴ>@VN@? dc p`R*|¿@ѽD?aV? %G=XdB>%Jl<Sh>čL>ǭ?^{ᨿ#%o$o>??~ɵ>ͦiH$~6Z>0?]>>0M&U>仾{˾{Ƌ}DX俕=.k?,?9?{ 7?>(?6{=in?l _оN?`H>Hڃ1_??F(6 HJ۽\ɗ<90>?ls>IQ?y=69(?Iӷ8'5>l?g@@Ʉ?Z?k?.>?C> w?s?8F?=?h|po-lgտ9Td]?K(?!?>J??D@b1>@_l@D>>/=0\+q8k-h@ᠿg鬿X)1j (O ~4krl=??"@ ֤>~޾ၿh/ο3ſ mu=zM}آ*+-qD*??Y?>6@`q2Q;C-gW}==?T??B@? ? J=?>piö.Iːտpᦾ?+@us(?N???yI-w1Gq>6?hֹ,a:($WپW??>~NM)"oЋ,YmE4p>c?M?7?1>_~o@)8P2lݒ^k,>TGs?>vR?M?ڠ ?X ?-]?d+?Yӹ??wK>O=P-=.[+b [ԣ?v?G=ޮ ?4E?ѼJ>A?QG@:k@?e?B@N=@G@bd@vw?i>6Cʽ=.=%?l?>\wW=??,}u4>*?*?@)@O?8????R(?D??>Fw=DiGxp R?5=1o[=*?~ܮ'1浀/.x <ē>h?v4/@rχ?.$?@ l??37H>??-?lqž,~?͏@\*F|#T)RB#?u?9j8kn3߾B??cW?Ā??ā?a1???+?En=Y?޷?? 9^.3j?{ާ&&>Dz>(H?z@?>>9$n9.9V@'M@5a @X? /@p~@^?ѳ?`x>‹>?ݹ^?V >Ž-f?B?w?6=ᄾyP=u}i. >Ri:?we?8?ws? ?:>qa>!iA? ,@Mr@=@/.@xe@@7@U? p?V̽DD%h{ʾJ'7?? W PyW;5 ?C?\?+<t|۾?^[~$L5>y??^hZ?l@@#@l*@9T@@K@8@֤?#>%?x?!ⁿYH)<K?j?WD?*?2A!>9?C.1u?u?>5?S^XɾUY4?tVm; '>x?@???G@2OY@J@Ѱ?S?޽?>07>K$]m=ZcV?6M?`"?Z @3?~" Y0)>I(?X ?5ZH#'Я>%? gw(>[,?-?vͥ???c?o2>{C޽oC'+o+?X?P+> ǽŕgL1BC?2Y> ?9c'pο?R#/ſVƿI@??{Ӹ?.=.jL/t1?R5?ȗ@cB.@N@g E@:?ꗽ4tuGi#? T?l-??$? ?Ԏ?x>Y???1Oq[?/>Nx +( d  ?#pB,A S@B@.@m/A@O@@@[6@@˓?<?^ɾljB @$!& њ Q?L??^?%?s>b?0=G?!T?Hk_xuR@ۿcZ͐}F2}ǘv6gb>?c?R.?Ջ?e?e??@F@?m&>{t?J@L$d>,}P苾>O~> ʦ>~>5KؽSD8o ?@,>οھ=?c=174__(/ ERWBǝ`EmۿSSr<5;>>6+?>ŵoN y =%5?K?*?b!ـ8@F?b+?%?T=aϿe\hþGX>j>߾i+Ŀn[Gn^;Tb ?߾X췿kٿYֿ=|6z:^8??R}'쿍K2Ƽ?)>$+?%M&F=y`?*@,#(@7 @=?w?fDʾ^h>? J?`?'>T\eٝX-?l??w0=&8ͿxEEF73޿f詿mp;>_??g @xX?$>"]=p>?Q?*K@vІ?@? @F@7@x>ꃿ/W7T Z[ >4h?_??ֽMPҾ[@&6 b>S?,Ec#=~XZ4>>3=\9xG>RտX;i;y)?љhZvaξ] =<4?ˈ5?-=qɿ邿u<>hE3zz?G? ?пqxN+jzh}%>Qcǿy?$@2@~>*B۷SCv? .=7? 5?Z'_ /\L^7 :FaV-@r[5@t.?A ?ә=!N4> 8\}mFt>6bQٿ?@^W?>ɍ7>D??s?GZ?BT:^<F.H0D2E܅2ÿ"]A>ϧhӋ>MN? ?^ ?cl?{=WW7=O?ɒ?/0o=-8;k(Lje> >*$,?=?ie?|7?>>8m=>ٶ?N??rL=3s&fXϜPf_9'y៿+g1> ]:=Yo]PAɺ7Y=>0y?^?IK=w}vEozҿ"v I>0[yny߿1ʿV[׌>=mjal2տJ$^i=͊ӏ??%?N?1?`P?fbc4ibo-Π-N1?D?"O} c{??=?*{|?'??0<. |6￸^ r?0V"=&f֏=3??d?@ů?>T"%?;,GY%5*yAŶW?#;?\ε?Q?T@U@(r?o?3 I?jp?n@G$?FoIIJؿϏDžHÃM?H8? ==ŖZT?TPE:k!XO*VK:2@JU@,?-h? ?=@-&@ I˾wWn쟿f{ֽ'=R?W3>$־\ wᇿ{5FJu?d+P#?&?3>X& >?Q+@,?v\ CQ9>>y>4SW?? ?vxsMǿOEIbr=[e?ĿC z?\Q2˾0R!<P ?r> u>>B>=N>!=%r)ֿ2 D=e>>!>M?\?(?~?h ?|U=]?E?~J%?K|I<[><0cDNbm> >+R<nv?,?q)^?"?$?2-@z@&?e?;G>L?^*?ukO=9=E?4=?$@< @G?5??4@g@tX=>c(yJ>x.??*?1?K@4@l6N98,m֧ͮ~Asp>)$v]>J??\K?kQp/#\\4 Nw)?j?B?w?AO>RpB." :%?X|UYmdrþ VWf@e1Կ3)>J ? 㫿`Ϳ 9M +M>1pe''>>Skżx~鿲G/ȿb)GV5#?цpHQE??==9a9=y={@.@@Zb9??K2x?3%NnӤ=Ig^>3UdY/hM.P>ޜ>A">?/v=|/>+?D@@.@N䬽0?|0@Q@?"yGſ϶l:?3 >6Wtt>u>Te>ZÚ:1/>??˝? ?3"?t?s9?7箿1.п13>,eX?bԾ_vDyDev=eX?a>jIF־pϾ_?y??o?1?`#@ع&@ f>Fl¿̄VC>X?0р־ a;u&ٿn/$ V <& Fķ>P>کb @3{@ @`R?@JL?0@rsȿ& >~(?u@S ޷<r%؁ϷEKQٿWfysվ/=wh??.?3փ;>7@5m@Si@ڜT@%g@@4YM\ךSrI9=~¿tC0\㔽_L:lv1*)??Pft뾌MAGl =Ɔ?f>%uɏf? ?B?K8?*v=۽*Iտ˝,[>Ȩ'?߁?k&>G  >2̓}2jf?!@l@+?F?Y@=z?Ա82?hؿ~N0??ӣ??i@?D0?a?'? ?,s౿'1>0?5>$SE_-=Ӿ+1|=$ê> ?b?J>A1>6?a/b?X\M?b?l?^?-dNο&e=??Ŕ?'J?#[?!?u„׿6ȍsr=?)e>nLѭ!޹]l$P3f?{@)$F@#(@b?T>!wagg^??<=@I@1@ ?9YʢeGLGL?h?J]/?~k-;M %!>[ 7.ٿW?myWƿi;r"~g?@KT@-?@`#@ڼ?ц?-%=N > T?+?'@.@93@c?UFlP ?7?.6X>ɒ@H*!!GSv_J¿Lfnzݿژst>cfX>m:lb;3>?R @0?>\T;I tgp=?#2?=@w@?0?@,?)aaE}D{)幘s{ƦV tN=~Yo᜿ɿv>أwwȿT`k?7@dR*@t@3?4??`#?pN>8 /ӿafj<;>Q~Z<;=l >tJ}mR-俅7- >-B=?ܯ?;!>?]?"9JjMO\Jȳ?x:Y^U{q 9\ĽčO?V?i?I2?g,\徫^u`,j2nnj_%'?yo@?^Y?t>n0>B?6?n3u zeo6 }?i???1?9?> 2Cdn$OWF۵=C;qM->Z==W@?=i?ueA?wʢ@C 1 ?#??}[>!⯡PSF3Vvf~c "A޾+L0?:/?s9*n!>=/?*,??t~lr쾉f)Xst3 )l5z>~2?N?A$?<=(N޿a>WS??? "Yѽ޾ݾy$׿(k}V a>(?6Ygc5Q 堿}g?a5zP3"ӿie 4޿9࿵۷L10iF_?*>ē&?">"gʿ)E*>CٿW&f>-,H&=G>2?g?q:X%ݿ~ݾ/P+% lGn!a tx*!ͤ,,겠H7ƿ uҾޗ] ?8\?7>ҿ5$D<ĉaנ?#, ޭjظ>Ymྸ4B6=p>(惿߿_X9࿼ h⾿#U, ]] }=cġYg/?fƋ"z˿0W1puy؉ tXXҿǬ|p?ء=?@ԽX?hm/މ? .>{WJh?d? e>]k?\?yE=d^zCTFIHxl#6N(?s>;" RּZ+!n74s>[b?$b'ASӬ?? M6"Q'_n>B?vp?cCG??{?,@A? [?S=?G,U#%Ғ &Ɨ??>G7Vk?j?3ӿr qؾ\?1=]U]L?{0?'?X?(>Q"޽">" ?yWya?η?"l!12scEhuf ;C@m=@?M ?=DEE\j{)?lnB,>?4?ɽq>l)=ѠJF;w*?5^U=&?e {?Z(?$?C3?~??P?t?6?ݴ>>Ҋ>>>ɂ>^N4?w@y@ @&?D?Y?>@n-@?X?$=?wG&ޕ`CVSDܭn>L{B?ܹ??J?f*?4 Sk>$>ϾnjtFg=`;:7An2>@?D>>o=evWqc hӿ*EU=]E0Ͽ}ؿ<:vFӾ:?F?B4A*ÿ}?C=2FSჽ5`?ء?vb)mʾ@wѾkf Y.rO =’?q?нR`Ϳ31o>p8Zg0([އy?b?yf=-׾վp;v>x?ۖ?@ @Ȩ?|??K ?52E3?eCfӑ ^> =ܤ2_ھM?5>nYJAE=D@Rs@..@3?i3@vR?уcп|ֶ-< VIcEؿ3ܿĿҿ8,<LI>KM?@(?hؾIg>?tO@m@w@O?@y3@,'@>gBJd_ܿXC׿gY=߾~迁h{>E0?l??????x?'@b@g@@9g@?(B@\?8v?+[?+|qÿx yQi`dW~p3>ڊ=@ciB5ؾf_?@^?퇇?i_?$@5?P=?P-@d@7+@?ޤ>4]I-W>[?u>JOR>]&>7j7>h?rfc3Ϳc߾p>5>?Y?h???>>Ӊy?ʼn?|u>?:@?>.O j̿kEYV>wH?>*_eHV ϯ ƥ߃tnt(s$W[Կ~dῩZ\ZAs8?UQ??;7@"@? .bdaT@(E9@25@j@`?.8֘u$ѿM ?i>Uƾ!IֿXz"̝#оT οt2JC?d@v@ =@ @dM?v>˖C@G@1?HȎU4}uo˿Ί蘹>m" җ%o+T >j&@cF@w @UK>o_(.G¾r?HD?>/SWӟe.}|@`X̿b濿ٿBV>7J:Z栿ݍ ڲ2LeQ?5kؿ2ê>΁?D%?kƝ"reS6@@O?6>U>Mdv?3>E=+ ſg,[?`?ArJjٿ ͌VB}ɿM,7X%?'J'.Jx< W>?(>v}n"uhbn挫|YU~d$!H?U>+>G=W<#i??=8?-1Έr\Cl> >D~7+ٿ֕emؐ?d>].!HRN?ſֿ|6QԾ xb? sPnŻx$!> ?deP*P>E ?C??U۽q YP\DX>B?{@h_?~>ItZ1?Y?/ȏDɾ &A?Q ?$>IJ?$?x>TϿcJt="޿̿d`35<7K?w?^Y??D@,Y>m ?>5OzN{4GD,>)?`/Yҭ-ExJ?F?rJ>Ϭ??+b?p?,=O9`T`i{?=!B=>:9aL-S=H/>@?'Hi>l(u?R?= >PN6|.Ձ쉿JԿ%?>jnCaݺ½,??G?,j??C?v ?-_=`>l@b?4=k?9)=y{\>8*xfZt>DuEþRN0fmXyC#/EgF``8R',?bt?.>8>m??ɟ?H-7Q P䉿Hki=,u?ˁe?~?)~kٿ4Ji4plvL~V7տMWmT>-4>@??6??>뫾6.4`пCÿqfeݾ{PLQࢽ~>!}?2>l%:ذvzMs>4w2?:?IY]>?>L=&??j>pN??/H>)D~Y5lY^꿭J$n:?23?ldphj,>)E?q,m]>+@?.>.K?9?=l?u?R?p?؞>}Yտu6_yM4y 2??0"?0>gK??*> =_<>jHF?Me?A爽 hh?j? ,?(v)#*?>c?w0>{>YP ?xn@@@?2?oM??i>f춽?@'kYN&>2<2H?b???(?#?>>>6?A d{ʗF?;@;V\7Xqѝ/k?5HVԃ>P= j8,i:^n}>`B ޭ܇W8۾*i=>>=#?+??Q?F?<>=9 Wѿen| T㩿fൿA#S;=???KAg?T>??(??т?&F?[>5P?2ˆd†H8tZ[>PHɾ _-Aɾֈ??Jh>Y/"?Jv>}>U??~??/!?@?4(?MixZ(gɿ˺;տCέULpA̼俸B<>@?8>!s = ?4?kg?#@5@{?>uzۅ‡d,Lտ}ݿ%h>Z*=t}l8N[R'>>>Ps?3???jo?qa?Sz@wC@OZ@?G]>kW>]K p?/R?>? J>>b7=½v >\6͋>_V??]-@շ?J?uZ?i@ ?^Pz@g@I@N{@Q45iNJC bbx4=ȭi ?!?d>8>6?.#>b*S`=N?!?|?D?܋??70?F[@}@yK.@p`x?Z8ѿʿ;H>f n[Um' oߩ|5ٿhտ~Lׄ???/@E(?+>{e@fm}@;@zK?==@=*8@^@5u?fԥ=Cؾ `@1Y>J?M>Ɂ??x? ]I Ͽv/:kտҜ¿F(>+=%Z&o?=.uh7Z?N?o>׾ƒ Kʜvvg⯿t8>H> =Kſ#a>޽ vDL%?w?S?'T>8Ƚ/˭?At?U>Ⱦ '^d3-EXxQ>Q8=?u(J3oþΉ>6D?gF?n8??b?_?}J?K?nnx?*?F??侾?Z=#=㽅\=jPs? &V?=[ ?[=LNA?|?f?7?2?6Pp?ǜL?q>ANNf>#K?zӽ։k?j>ʱ>N>O/β1q>2??>mDQ!a> >{J>x>{(?z>i?$6??4?ԟ 2:n԰ejݙn @*?ºI?G ?n?ޜ?:>0Y>6>'?V@d?ˣ??ξwIR6 lm8o.,m>a}+h9E:ҿv@:#???>{?^??TkX??W?H ?c6dUS?dC?v=WiB#Y*[J8A5qi?%pY)혶yd U?Ck>%g{? ?|?h?{=?Q>q`\VJ=9>>19&Q¿_bI?y?G>jоpFoV>??Cҿ>5?*`?F?T?*?P_p?4=>9>8p?!v?>C~>?9,?Ǣ??f@_?6>L??[>8?M>RZ<4@V??Qt?ˤM?˖:>k;QY2PJhʼ ?"@@C?&Vl?@@)L?nL>?Z @P-@>&>S>*r?#o=Ni>w DS=W? ,MؿŠ?;r>40IڽT~=07?c?4=kn^%OWN |Ha%>E?Rb ?uHp?R?IH?e]?1^1 H ؒw{}=;?|@ڴ@?3m?V ???̭?+?$4 ߾2ePN?)?riz,A??5?8@[V@quD@@?@F??f?@?r5?*?W$?\0q>? >9n-M1?7 @X@W@*@@$?Ӯ?u?ڂ?P?o>\=\SBZrb慿U >2>PIը{KV?>k7N?u?I@@8/@(@?P@:?jơſ ¿ML̿&XֿYpѿN kNGPx %7_q ܾW ?*ǚ?S?z@ʎ@+?ki?L@??U?پ{fÈ9BE{uZP-='w_6>w<+cG>?=娂?!?x?@Q?l>F@/@6?hZ)?_?.K?%/>w%>>>G>JDs˘ 쵙%=& g"vѪP[>o,?4 ?>gK? ȿ.ܾyF[ @>f]~cbٿ)KN'p>`?2>Yk??b?Ǽ@ܿ6ֿ]o60+0F;>|>W?^̚) 0!dC06=BO ~>K>NFc (+>-ЍR'O>X?ݫ>;ȿA),(1=8T=ͿÃH%(!%h)8LHS, /RZ_mg_S >R;:m=>N8Z[¿࿃ $cVzbnڢL ,ﮛԗ¿c|la:^#>d>ݣL>2?ou?v??':s\߿ >H tZN4&65 4>N=zmT_>x?#g?>uy>s1?08>A ? @ڿ꯿ydͿHj޿iƾ\y1M >&?O}?Ј-?h'>E=*v,=0?s(j?cB?S?WOl^g>}saH'-Rw4タ4 i>)&>KϏ$T>>ȸ>U??{n>8?A]i=o?l@4@??t=,9x ?0?*4vÿ߇ >???+?e?ȣ>'=H}y?3&?&=*N6=p2?Q(?Ҕ?>S?g?T?pGF?Fl6>a>O?|?>>g9*.EW9?̬?& @^&@8.%Zh?ss@p>oÖ>W&?{b?(%>>L>w?ڐSϊ=!M= S&;\!#?ԟ?֍?t<.??%?Y ?gu?T?n?I?W=kk:>+?[5>> ?=U)=D?#?Tِ??M>e->v+? Z=%Z>0B>,P<D?vqD=q* ?{?$=>'>֨:?h?8ɾe<{Ӿ3:&?X>>܈R>s>@g?J$GchtOر r&zoIӿw%.3L> >~>سq? S65tǸ;Vz?ʼn?r?|>:?K??@{C?5E?:??.?Y>^?=,>>A۽R_? ?~($?~n`xC>?b?@Ŭ?\@/@ ?ɞ?4Cv=ǥU9B[.+> +w?:?X??t@$b~?l4>ʑ>'t??@@,?}5J?@hnny?\@'?Tg???^?u?G@ѱ?z9xN>>q?HANRWBUWzщ|FL[JR^g@n?H:saWտ翉J2N:սcm=`>VUu olM۰D0K5vP)$v?翎، y` q>\?> C)VUv_4Q{B:пu#TD ҿ7/B+F>Ė>/}¿s*z7J?V_D\FIڿܿAQľgu!n&$D3ƿ'¾E16'>"?x_?`?vX?v=n "'UGoKp2KrWP ?I"??[8?S2>^>C>B?>WbduR/I Z>g?BU*?x=>gu?#?*??IN!6Ӿ"U>6??}A>^Qi&bȿQ>!6+O?Hk?GUE?<[B#ȽHv?v? BiY=7w ] 0? u??3?7v??P?J\f>f?G==G?aQ?`0?£@y?ZF>d׌z>l%?h?{?w??˦?g???V-??ۅ?Xk ž O3?XS?u@l>?R?XP?|>ڽ4?a ???V˚?&?!??@ ? @(?>T?Ht??s8M?J>8Kd>ݩ?2&?Ʈ<?Ș?ɴ?/ @e?t?;>n>>ԁB(EE?DS?j ?|,??3j?P{Q?/)w?#>]CwiЖ??1RLj mK(?6F^,_wj1N>,uzW¿+m@%FYB2=|"{` =}kus#4D?>:d>ue \4>[at6bjQ8$$E >?|~?ר2^aӿ0ߩ>PWbXOLmz2FAaЈ8FkA¿Ey^{?;7=5tѿH<ĕxc*u@pqM5%KXUgsc&AꇿrFH ƿF<>+U>nS >(k p 1 > >?$?2T5& 9߿e¿㚨/{W3յ9/^Ծ{]'?V:*}.84>[#?Q5K!!da= E_nG:zd?&?> >R±>n8? Mi?P>ich6fZ ŏ?D??,@?[?]]@? .">z?0?K?*@@??=A(?ؿ;%$>?@,@1@?~@Vl???GU?/?`?r?0j? ?S/x?+>[>?m?IA???\@P[@|@ ?*a?d>N8?ޡ?Y|>o?9z@?9\?(?ʆ??Wr?.o@3+>?`n? ~??l?@E?? &W?S??ܻR??@ 0P3So'*d>'rϵ \8-l$N߿ mccpſ⿰տL> P@(ȿY4s"}xc}/R}威-aJڗWõ>@n?x@OG=a9M> ?G[?=|n~\C ?@X?u@(?qȮ40?H? D?ӑ?`H@>?A@5@4 @JG?=?{??S{P?L ?$>l0?u?݊a?ʕ?ݐ?&?-?n=1Cͬ5ϾA _9_23kо{]ps<JM>ants-1.9.2+svn680.dfsg/Examples/Data/mov2.nii.gz000066400000000000000000024340151147325206600211230ustar00rootroot00000000000000 ]e6ީ*sS 2@ :6eJ(e-)n{.cV1@J*HTJHDHTFYޜ[q>Y s.tY{[:tvl俤K?vw/_>wzu?{_'-o?k9}k;eEmoNh#jVεOQ [ (F7Fws߄[ȿS+H\P+OGx|ů}خH~m߲}gsnSG`|Єk9$\;W8s8o15ý0 vm A/JƠյ}{Ƕ8;qiNW3y/^=E=y]طߩ15^ϐyMCg c\_>˶=>/X;+2S]/3n n}%yá̯1y|^y$us/jF߃}|1s]kq?>_[ J:F@n^y;p>ӸWcS>wNa)W}C&q>Abʁ,tlفgQ2w o vJEsG -4bgja.?Ǻ#v9S{RH좞1;Fӎf{|~2\m.bM7fz:xkςV@߃?m31lí;AUw`c{hy hu~r ~!sKaV]sa.F8mǦ^Qƽ'*ek8ǃ7؋Ex8{(dO3z K_hh$qIbF+Ҧ%@#M'E=c9έZCAMDiIg4f2̠zv\x4=tyL|У'a1F? Dp,oMb_s] Ki|'t.ua fBv\m-Ym@[FH7߅O!&4_8?fF|LV{nR?3>uSM_V&%/1ցw^umE; |;v"t& xqÜq(v`Ώ>{Sn%~mo%q|s Gqa|>qEAnu|<`oqf. zƜw`@}ĝ$`롇s?9^9~^A'/?Ɓ5kdoipN/EF1Q+Yn*p4pE7[A_c,t]5g#}ۧ1]~<~<5v&~߅q; WǿL3I`ig04Yx ;$h1="-)A;P05pw̖[k Ndd]ӈﷄ/N/qo`1< n 1wC(cO /a&ˢq̩o57a涇Q/ނoˋr`Ca yqiNۀ^7 77 |׺w7{ !dͥO{U5GS6);-^) $yo(s =G5VRu7я'fc+A Ov?gۂ{N;1{/_&9Yݸn_IL.>}{A{? 86k@۩3ςU}+HtĤ߭o? CwIw'xZ| a#1Ӑٮ %#8مrMkiGo2$hFkgj>:#bmSvT5^@}F|%i''rN; .{cޝFe8今ow=Zi̸8Vd\Ci-8Rsq$J樑sZ\lOq!y\w_\/܍>XfsGxx#8!:b9c !Nd8 Qd)m|>|6 ǺJ{(PY T'&Oٿ~[Cq`\ W$lua~ 8χa'A+Sx8n g3Aw>{1hn<_ z :5P]kw cI{0' </ZO8 IGmhwtҸB`LPq^'.^$̟7(5q>,.7|5.jvEt4}~ân!b_ƑS`&1?_F$|s=We6l|"|Or>O6𠬕ż-vb,wsr0~ϧaΤܱh72|`F=kiS'x`I ; :A-iGB9Z\sG 9ts2n)/|)1D6(hay\`'4 C޾I}ׇb{k]~-pv=le5/]]m]+b/yls.8`o|iNZNF4/k62c [;5Áh:G YK9rEz+3|`CsS10c- wKҹ0ǘtG݊Я_aHKGg܉%H3FPr&!gUq p?~p+> Zls.1πIG]q4/zW@>ܹd}>38F{4m] X漕+,O>/9a9XI<%ώ>n.prnI%eR sTD%*63CuЭ3 Wo\؋=X0a~Eyzbge/J8׻wc i.7z_8x @8pRl]aS4&m)W}X̞yܛظd.&rLHtr~ 6my57Q9 ~&złm;4l¿ZcqosV1fiq'fW3ҤCs0>⾢H'Uho܌_u6U%鼟s0ssV^k1el|_7?0AMרũzʋĘ24ɻ/GIō<pybwhK,s1N`؅`*tbNÜ]Ւ%\̜-X>H.g`t 7_ý$q1+ s=뽌sdOB:I6֟(оZ%vm-oS0hDp%c -4#! +# u2%wp8ǧI ￀gjD~wٟ}yކ6aKrioOE ͗vPo؀)q;2Ip!A&ĵVˌMcD$f?~&嗡抬oh'py~bnvAJ1/CmZ_䍞?o-~agu߭%#18<(eNCŭQK'簦_cfe:Z=˘L%CLIA|'+#wzBYߎB7fopMSu4DVγ- 1qԘCp!,}UX5rg0Ϲ:|7 q^ '"g|7>Z5؉˘ c?p/c+;+-gb.N> GF응؆!Cy 0YJdnH|p?Dx8ٌq3}p70<C79~ ~m1Ka eQŎ]^{t0m6b0ꘛ-&,q7e>7eScj߆MYcy}1k, 7G~n$6$oNcld ,N1B{v`6A엀U~O?z`ce j߁p7cn`l] j\ p<>_ka܌2G;ǣ ?>_b}0Y[]f\hZBo}oe1ʹJ.LqWc;7yQx|v0A_K/q쭌%L[_d3/ '1g[<snx=/;}m28d\A}> lݐ':[]8/Ƕ]*|>q#9. Ҿ#mb4hR}&]\[Y=8R7-d+64'u/%IAllx -|7ؿ7JnbNSxViu1}l|[fw.b t;;}$zԛ62db|::|D`y]{}P'/FX3#cu}^yA[hoWu>sPkn|(T죹Zi+f.(ͼnK7$xw9^568'$yisA?}\k qװ4+2ϥm"C`o"g8,5ssClco7m;3>g+vdM/E.X~,ꎶ&Oo-{ϱ5Fd4ּzrSyq|Y)f|Zk5q v Af1K4B*RX w\C84*ٻ13X߄ 4!mCc߻B#EUh݌y l5y.hֺ-w*0.u{oS as9oYkEr', 2C03ϩ&IH(vX>gbH>ՇH_{8J P-uPrqb\磘粮/b\@=/~Հu1EE^\\s70 qzi3tn9`-~9?gI\m 33V뙕ueK&hѶ3pU_}ŭ-;PV:> ѕs=|yދ>sh ၍-1j*Yt0A}rԂc>(:^6fK}dl0:[#oϛ}nj~͸^L}|M6~^bfXg3A@ ?`lEpx;q3A cq^]}̀>"Z8)AGYYleƑ YoS +g9}cVƽI.1P|iw".~?1<gc%]'O--?>SᴰHz;0;CYb =$]bSgU1J?tdq6s{ [Jy .w9}OsuטsHoxڒ&xv-l]w;(SO~;؟GSY ~}ƳZ7T;Pk+侌y αF` kĠH2W; /ZYo`%chۏ)C>Z/R/MKLJⷚ`Ց,w 0h6dv/cLkm,fYCWs >vHE#!2)Yւ_[bԾe55 A?}Nҋ%Mse'ee?c^gGvM(.U>/! )CI1m.yQ?!qGj-I#x!%C? *h*".5l>O@?q`zRds:8DGіg,jh%Ah/ɋȺ9r}ٵ_7Ua,4<1zwbLZň>rs?8#ClQR-MUۨm=9K3c|??ϰzmSqq!ׯZM=y$Nja;sW1>s'1'όG(e_RE9b;pboMKХ$Op8ϼ"1`y keۍOb[q}k)S.>;P]9R#㻞}cI'A'k RگONq'T|[ qZ}\g`\o9U{mBs*I{'^'p_dK-᠉_^5#L-B&8䷲? Rl[ ۉhkk'=`ے#'\qS#d>ɺ2eoh5<k{줬0pz_$sMuO;+V^ @[={YSu3.(T [m_'4I9`I Ж]ir/A?H?> }?恵}[= * n/k]f$;}sۡgJn%>%X/zX,t֚3C1IPT|Al{h=ZS :[gl{0ܰ͡bC,HMŊ@ps͖:~YM郳c;p?Je/ż~6q͐]4J"~!v-A 6ګi:W5Yt dFS#똧 |2Ǹ~&oY>BFGA7o״sijsrۺ@e~5E_u޵De/}\%LKAΕx*ӒNƊ &Ad>6&Ii8ט c0'+h̓y2$5Fh;)ǽ?<c%wmsl㌕Ծ(zmv[Ok^Ʌ?fƒATj.H(G$ys YwX{䚫=t4Xd }KVZ8 뺈EgEkvcP6_t kzI vCwW-İhj=B_>5}?wk [o3Ncn.qwXm>)Ĝ.$Z|D͖51?;PB{uC O}:q(h_R2=d/Uf@u BӨ5sDdnvW/`mb|<ƽ'TO=m99]z܇u.:/fzewv։Y A?f5o(a5 p`,& ZO,mJs%Tn>q]|u~J2u@w }Xߐ1bzX$o`Ln tRCٍs}Am9tV'|sg=fjmHpv}Eh1҆N@Y)~똌8֯=df<\`N컣W2wfJ7~S[Ǩ9Qm9q-sM>JJJ;*tЗ!oRkjV{+.:5Nj\cD؆z@3 T{|qfmvx xhk?<6{D5i#uIjՁ3;'qV'O{\y})ޤiʌ=A܃)ͼnkWW{koc)bK$aυ:r_f^RC;IVF{ >vM{@!㭕}VvY4]m`*TRNTJj Enfൔ5.F{;s4GXwHK(OYp%-|u4WVkeQK=/c cԝƒ:ckvL֔#;iw:8 ;2+ϝQ{voN;MYxRu+=hNrFcOծT!n&97֚,k} EVY^|.8mkĤn;sN>b2Q]՞ qNS/}ׂ)*D'C>˛ݷ@<ЖYkdLPYbsR?aaHf/7\Np]WDg˰RZ0BMI[J '5p2rn^GV>F{TrFl*R&ζ }A-.$i`V_8jxMP˥v$Ϸkpީ/o,JqmŞgR,k,7IS.%Ss.i?Jgu6告s&~CgumK8Fbpvr??w O. 4/MXsSk$\Mٺv! /$ߢ6_=Շhen 2/ǥ)d郬\^iz(gȽτ+|Byl'KzROx6{7?Be9|njkj7a6>DCV9m骱:ga:xmyD5qԮ/^t8f0o<-jѼ k=܃e־hΰEv4\m,xS1a?Iuىך>ϚMj4^Zuu+mUOxbŏH\ мj_DibW7A_aŵ-(m6gYYyZK-w>`kb(ӷ%kؕMb~p 7HZ=mэg' ֿY7c7i4:q!7״UN|唣~S؇@tPgng}l7W>5 ##j9TX|;Q)⒮j[p.n ^ehwME⛨:ԑc[n1ڂZ>biwmӷEoZ0LO*?mL+944h x'ߧMz*c#.Ƃ({p|i:몜w>,!6۾HV皮vLI޻'XcHg U"koL6[aW^dn7z".}UIlr4HFD|1D٭.'>&5d~!CX뷇Mg6 _1~,»AM.j6~h2>@c>Zؐ7}v456XzEr-Pk5y{鵵#{I1 T百!ʖ]K05H4Q|>eʪO̻쐤߿:[y% 16xy8G_G j'\녡8X1]F A'bFuy })7HLTE ZnɠWp.Wᔾ1 A-oh4#av؞̎[l #T]#c4f>]=hz霨 F-Ĺ"ye4I_Dxfꝅ SD? tf7SR콻pq+6z`!JQ'45Oe)a[kwdf,7Nq8Ov?o]aYo~uAf*(OwcOTV3,4:33Yb^ݜ_ fV1CXɵ,A.35T9j7%Wi2TUt͚fz&˸%!7Esc!pvR|={qV8y\"mUC$D`&7\#mhpڧ\ږ>Ieou|0Q]!iME'r:N&*r ,)_.v1ֵɾ y8˻;~ q19dl 7O4Ǹ:^g2IjՔg-^<礇Mlj*ˉ/FZ~{Tt˽W T:-4}*\C: 7z8^*C`rJͩͱΰ<#X,c.*m /*^''h;BF:j\uN޲擾KMŧQsV8 !λIW%-q-[F3ks8s#Yjv +Dw 87oϫ;5&fb?i WY6SH'oךMNc[]\z>#GtV&̦datșhRg8:`tު=C=6,C`r 6ט??՛WƂ@~LRsg8{ҭ|kl!x Iך sr=HS07#Ƣ@Z)}b@uBԛ~WZ2`rv]QmƂ؏ =Aˡ2C{UGҵUeڕ4h1&몶H^bK&l=т?\2TLO=SN̛c8UkOЗC:6R^n+%CӼNޥAFJbL"fZΖ̤wŲWlU,p]$ 4vZg[VWLQ5|'  >e)ޜ%}Oֵ>OOUZw?I{@M<~Q{9 g{1\Z^7eTw"L <[_uwZGAgg{ Ɠ˸Ʃ 82L *[f4z~lk,qMKH~I9 zh??%x{8%Ea4ӱ_wTތsP;LI楩L?8~k3RoXֲfPmq+G?VbNGPAl 0n} Ӂ;boZ2uغ?:*eMK,I^̑s~S qσJY݃1^Q. .7V}?MM[jĸ6i&x!q=uvH%Fqd'iħenwqLpq`PG?l|ۙ65br^z7%+&ǵO=4؂g 91Jl= +jrg<58.|ƽ83 ^N} GsX9gXgX1D[|+5sMdzGYj];e?ӴIKU_Ei~b=mMPG8G[U<_/u{ʆ7AחG1؊g~/ hջݾ@'AGIdm:I|+22m+Q{Hjz7wp-މ|~V[yCssy+-Xmj0;nڌξ{vk-۱1V *'5|CeEאet/wd ~:OO|^87Ee֢ΰouƽ cI]~1L_KOJO4h]û㬷&X=yY;?ͣci]G0z/Zba̦le&z}['tX߬tެ2<56Ex;!xݠZl!x~o<8]z;d_!%;D{េnWe6|K^#6m.mՒ`OfSs*5wR#t+wBx!=@ҳO0{Cci~ ˣ"{o]{ׂ9\,W,A*9A\+?)7G,Y]1Su j9K7+P=dϸ}_.]ށg {ylQ]Kϣ@k0>>&)v3A7(=H>wsk\')sG9+rhg-qڽSOVl/9  7й:{\u?p [{p \x܏𷬟?µg/d雓]-N+?olI)+mNK Eii`;y/oƴSVq9o kq>kYݍg> e/J*K516@{-ho/P?.S/bݎٍ+Udƨo8s)W_-L}ےisg@}e_ o>Q;uLdV\w'xèkVl1z‡Yg\z9Wj'.Tkki+_~S)W:]hrDң$G.z{^Rv|2;m9ALt*ƾZL_MՄ&\rgZ U+0e6[uSW[7 U*MP`ς."}8^>/O~! CYפ'WzC?_񃸏ٿT2kcn '@&`)=%]ŔafWF}Xc;w ~XVf'nUq|ߪ=>h Xw%.Iiu( } R7?:~k 'PnUɰUa㘲&.%='rG]HOmŋ}|}1[q"V 񘗵8/ܐy'S[-a-M_'Q6-]b^4[|B8Hiy:"wqm m '{ h;*X`T[t//݄sPܳ<ހ%#c>Jy~x=짛{,C\&uhȚ^?M^,۷-,Q9T^ɘveYar\>nOFyi ?[=.^JVBL" t~ h}r /:KNϝ f\l{]g+'i\QQjN jZ`ϸvo|]z  HཧQ*:~,ˊ^\&pTt}rH%hbOoFB B0CYKf\:T%{yf?[Noݔٟ}A$k`wO#Gh0kg 8#3[-ivպҸ{I,F苛m-}UP2PJo8AQi)]{G<#V<ލgx h{8l..8}4Ys2lJ_{<=Lz aslls?Z:p{qȈ?JzuSf.zַZ="du9)}˸߅ko»N3,)eSq*c a= vQ~Mq}ztaݚC#ݱnܫI?qbmIʙJ,#} KAvVgzD(m Gցf|ת޿E8.8wCSXu729<1LPO{!'`YwS;C驳7r+OI&3h=eK5yqo + &N׀_O|79I2u4BZ t~}'tt$z#6 m9.gN™ۂy*'%izh|5VwwA?cS_,:_=sHFl}ýM}'apXr p7ӸF^:[/3NR*#jW7W_{y4{ڽ G"F :=w%_pq=L~@c?^0Y>e]"֖V"[6^,N)4y!o\]˺VBϸP'~N$9{mUɘ"?Mú4&PJ8uh m;c{])g*_3=}__ҏ]{7?xτv?Dku؋\飍^ #d\PISbxfqQ\j}gdHOzuoAQ-bS(eߑ$_ľ`d"YL_bPjeJE 52Q7O;o>ǾKm^<`}t+wC>lHpHmwW޶ۡjrmy]ǼCͫkbFZPgP59SI:/vu ycj}]ߊ'}GcϲJEګ3s]gYcBj@l7t1tRRb0rjuhh'rʻ#ۂuʐ[1poPHbǟ_ wBNi!NQ9O0$ ȶG1O\,-NWf>zƱWB߮?Srx{yjqg"H,h,\W>E[ ] >;Ĺf`mI~B|SM/ Oc|ߌuhUWfEgoGG>b+&W8ɚum\r[ٯı8PcCзeG"sepxݢꞴ >!vYv`,_ j=r⸨8$-'&]ՃO.q9 +$xxaK"{눳+ = )T'k4':1ŞтޅgGm?csc=>ѕ}}/-o:VLv2V 2x_{aNH_~'^Am0ymi9ig]C4߄uz􁞟\gĊOG%ߝ!<5x#%?*$ؗx8j\w 1G1k>x} jFCZ<{e)>4ݡriOý? iywMs!qxww,sLBfnh w V^F?I>nQE%{R0(ma"7ۃcό$g6x+=5qhkwq}(<=Afa/txr;x.Z,`?OG[ Bw Ģ>sy]ah`1sIO0?2D_ F|Z'>o`@zҷ{!h%*Ħ9鿁~NoJ: }N|BX O}__aM'6\;ǷE#g[=b~u×g:qd5Vıfj7?2mӁQz dHG[|s_Xk3chA,a}X%vɤo{S֕>͔e闺b_<;NJ/ӎqizZGIߺx4zUx 8Ƿ1(MASN )%طI Ďzpen ?Id9X09>W{0nnſ xbWn.@:w'ysAF4<dj8;aPW 5žn(rZpOQ$\5fK"GӤe2G huOxOnD/U;iw܃Ql"3`:;?~ ͞P#Jϯ>sͼ\ǽ~uNJ! C=B)Cߛ>رi\m}ǚ!{1;qm?Am⯙a=~ǂN&݈<+㸞KwD{wX&!h.;Gs#ɝ>ϩXU:0(v89On&ϥ^D bD s&$ι, OJ xo uIYqzaԚ٠ǫ zӋOd/^ NP6ʾ t"qe'[6 8(1%$2'u"AeȳKAi*[@&?ؒ_o!ђ-FBlJbp=";5%~@t:1EȄiȄ' kFx~怏Yq#kMAj.!RMks ڼc;%9ʩ2W(|`?2ƴHb=OCDZ.!:#V|v8' 9,>*-{cN [C{#֬ΣP=EF!YcU˘ >D̢os1)ƬiO6Wr g1u39 p%~&N Mk}HrrU D^%,r_eC ڼ'\{&OMs#on3qZPxl +t)+ y]$6Duz{)_؀#Ykf)SrnzӬwk5\W{C_5Dbm4RB׃sPۺ`B*gcw+_38Ŝ=-*A,MƓ #EuF$>JnW^-җ0\3ӷ3v~mG1$[`}MQPbw$!uT :;݉w.5!wŇiJ)5q Nk^#5o.p8j/&[hS؟1b'"\1L_..9Wu?ڞ Q !1'/wYkfš)nN>(og;%??s sr.lI[d8.zY+TrHz2Gg盝U'MҖG0@s }Lg1GJansٷYa|G\3Zj;? 2|c:謶7X- ٭ضp4es[^>PƲeHԱːyJBh;J;m>/ 0~s+xh4:Gmhr0V KeQÉkm8V'+ɸA1>ZKe;Gw4c08sFҾBHt]f@wΞvU=i8-2l/ŵc_g!}_ܑ/O;u^7ft韲Ϸ8~q .hOՌgl_\iވ`Ϝ=c>v[5Q+}2/\,lws*&{%1 4><6;5@G9ƫ(?`9ʩidMB78vͿzvk\Iׯ}q`k Cic~1q-iG16ᖂgό $+&OۭnjsVU1q bo/3RHN&*R=Ab?Kx$d>s1VS uiyR~-stO; :KVB8ַI=kƚ?3# 9fmOE|)yxOX́> ش ua,КBĂ]RԿAy-O jy5򲠫f/{>`2V8y=2-}ex^z?ϘQQ-\bx,:c#}ۻX亮Ʈm71sD}0p?t;x8m>K3kT~q;ܘuFƋhʂGh&(g]JQ!qmg61qoWcɜ]zétK<h}~Oh:ĥx候xiz-QR7@^(EvIȺIпOb嗁atkhiHx~&hY7)MNo9KIw5-ˉiw;w)F~>2c5~) ŧ Ntf4 V̓9S[|u"A3) 2M ZGŹ.8ыF\oq?bW|KIw9㰆=H;48 ˌ3y7#!S?joRDu1Pkqm]̵]azZGP6:| c>\Z+^ϗGbS_lYas(ukr 2\1yĚem+3=}1ki#&yRWγ5?=ή:6g\HA -Tf ,jV+ @ȈHTfDdFdAՠVC K $9gY=g~ϙ9}~zYl{^XT)n`g~K8$"VGbvZr=(FֳyB"X"G͟owŸT*G̟~$n΋/|XC\aq.S> s%-jX91̇mK-G iۅ+zr\8c%GBv>dx`"آ%^:kɌʱ{~~6`˜tA;H/?J\QNRIl7WM[}sZL=b~}FNr)8G^XqoSpR*鄮ʋ{hg֝6I'? /z 70pwG%~Cj#6e1ܮЄcO2'δI(f]ި0gb\sbMq^)00Zrriq}30iV,U~YOM a/ %ز(6#q,ך{W/qc:nN<1_*8kExwscIאxUl|cX> \Y?ljnT mڎ c~}צL-WLe5s,ղt|: |isX|Kڬ 8fI5(Evk.asK׾O8:swo?~K^,YM=߻{Yg=39M:>mJzYaO'=;|/&%C:p=^dm f;XPn̰?F}]Iê'ᚔ{n5V^B2g<~$'Hl/l/W>T|n|&@| BI|8 #zR~ǞR_|VR}SXh!<ϵo_qlɨ=nrx7C, BHl8?6nq=Qya@k=͸bs.sʻ~Hzbb/` ux:x[zBw=E鈼ǨGkOfSbh/\eZ+g/~]7< ytǂ| \}m5AVXsa'{8ޚa3lkWxxT!yvwɿ>7QS 1#ψEg-zڄ Փaj6!u }gިr~3]{Soo!6# ޡtJ^\o?]Xa}gyVTKؤ,9B\M}^3g'9;%rz5ݯ7͈ނTqJ {UP%.eLkƴΖ'۔w89svZpJ A;Gl>YPM&NޗEIY#w\_22+2墎\jGKF9kZZ,_{6't\փQA$5EgkЩqS/cI՞di^)GK(~V(7)2p\'ꑸY7g_?[ޓZL]qiWyr>&{ɬJ.Tb Q_'ֳ[B֩W>M[֪x6n/n}z h 9^}PجđI晋{p,}] 2 ƾ?9?浮S6xi|QٰE;_qlJ7=w<M,ZUNaH}88u*<_#$œflO]&Ϯ)_uOX! q U)G~ ĭ~M 9߹j!;Gx-意Ra ?˲7A]+zLQTq?|pňv~eXuU$|:NQ[ 5ӍF1i9NXܠO9PW~b5`M2^̳VWcGUe/v(OSxr%Oz#<mm6Rb2KSr%#R?S9+f+^-Yy2z# sX+U5a'5&gE%>>WC!cfg*3erd tJL'WLN1KWh3wfe7VW \9w.}(?׶\q[#rbֳ*,ӰoeܧK/(t)>[Xt_qufqo{1fv$7͢Q߾}G e@~ f}}88)q[⥜KkDaVC`4L-o$9*o֗Kc.ۮ:;eƔ- >(|iO~M¾g`YԳMЙga|Ver1b#^l2Cv<&~}c^? ظ>w6É{6.?գQF1 'A$gAwz"9<`ǞSaϔOMX'Za>U/=S{C3ys̞LOrRz~[9b=p hwW VY.ޚq"[ď3{,E{ŕ3aB}~!%>0G8~E7Ͳw{UoŹF5zaN}]ĸLNMVp~w~+g^VԱy?E~rx/JW%ȟFNI=^=BU-J# Źmq>Z;}{՗stA2]9 0[hg7jՎMcqb#"&o5N},Dazs87b_g/k{C~9YGlAWcV6$NqnCfufpc0%[7 ׸X-'x]OwZ+/EM u.q"6 eS(VK?8"s׫FT;"!gCT?G>ޯGg>gw`O9g@/<^םhpl/jHq\I*z{朇thjCM~8rKz;sE0E7 _x.#,zQ#^{9;ޥh'L~]܆UqgsFrU)mx&]`?%g=Ny+{ ײ7[;/lFggj3;+Wxġo{siE 7yͷUΜ[f;}NޓX㏺2&=JEqwry "# nQk.Ջa،B|>!|2 fXǚ%+?~g?Wxr :{n1Y ڬ0~mfPnaxhhEs5zT5;Szlv1a<k=.oIzdt13G_*sJ us8x8o̖x i0Bn468̢nΒ «hϔvřm޿ vF7s͜C&EɡlkE}L}XYߨ +r56zQ>qj[d3[Ze^M|C>hgp9}bqw[[Q Ew&ώ˔9mY>_}?GÉÖ'uՙ>-΃{3Ja2F~rfs}lͳX[Ksf}ۂd_NqqY_VKd3=Rgrmw6^C[8Ԇ9ud.xC9] (f}4gM%N,C/gJ_dd#bb3Vgs'~eR2Ypna;u;}׬}҅cM~CV3YOC9YALa_B_r$۹gmr엱÷5tG]87HWQ|#}M} ^f qKpW:_H&7ަYOmΌϘ_~ަu=$ʹ!f} +?ޡ5l~V}tѴh26 5 ǶMLeR:,ȷ}4~ol3fc+~Ij^v+Ln;?PAUs=a]NEcҼ zy_`Oۃ'ɜ[NsbkK[T39^35-gA \6ߔlLoiy>Y -=L,٘>xJvl{=mY^ۮs~qfIOKSLa3rO#?2~Ǡ,\֑4"{)~ՅBNr6=~ε?xrc=6[ZMF.քmVbYmW?^ Vt2J9ݿ!_mb(\W/ W6/m&]AFι\.Oz>qO~.;> <'1 W>y~}!j:=ݜi:wر(\YC8xNaO|ۣaYvQ;4k&.%u?0cZ'cwHPo,?rHG{6ה2%1}>%wgr6uk'c}8 lzCkl9eg="ٯ*~x*vW7 0ma>'Yvr[ԬiuX,]9֧]Ѻ-|YXS?ۜ!E/f%/l jv'MC9} xB2yd}aoµdηoRE[qD Xylzo]ߓC *m./e!ףV-.Oڜ˅|$~8/{NgvcHk ޫV~hΕPߧ+pYxvֽK\t|/ ܞǁKyZQU|b½mqh EQEIMykkwlSQ>}lڵ֖'"/I Nmfl6Q|@:jʋzKҰq9׽uUj6&w2yfq,(Cr^wFcr;5_ ɬzČM7\!c^м\Ţ0 j-mpJviܶ' Y?X搔|=NdsVdKmPS%/SD6esCsHCc{۲'q̪^w9UOZq#׭][uVo1;:,'jXpEk|opo8<7mq^m?LyM!v7lkIǥ#ҧ9a,M˒b#_?GϲuƯѨόj= v' ؖFg1?{r%ݛ%oxfn]y!;}klƺSw=Đ13yu-ݧ5Z6V+Egswݲ){^~mN{ae1]aX'ݯ&]^ W1Ңy{]5esw3Z׶Jf; :8gꑵ^87gƁ/*qsYKn}zZ8@pu"Gɹ^PAf0ɇLe7M9sʣ~О٤5dGðASyqsZIu|4?"̭I:[s=a8q8>NUG9')i]+uiy 5fG]G/ϼ^hzGd' ? 3>U &j﹦?Otћ睲{/NI?+`AoC̯7gxx↊ۚY}6yz'ᆽˇЧk6nay:_k+6Lt_jCʝ/}EL-;SvƅflwE\6%]/r]n] W̜zFdk(W![/bs7dxjܿ-=OLN6'J&#_Dy^שݺ&1;igf:۪jVp¼jzo爃8rdnkĦ6C7ȯ;h|Ś%_UϷ21ܐ1?dKK2Ƴ%Mydl&oȰUW.~FU~8pLz"ۖw9x8f>*fK<Kl{sѡo1|wx^Ű5RⳲI{.=m2ZN^/jCm(ԴY"/"~}{Iuk7[ĘhÚч[v0@-yV0r?`#?}ơ~ydlؗ8 :drCݳ1'Yu]x^.rfe?Yj!\.*/J6#/qW]oY|{\RWJ+qf [RʚIWzZt2Ӎ?5^3Ca}#Zl/V Ϡ;u,3wݽI֑[2Zpٷ=Z1O_n_]sc~i]Q_ew6qV}la&C7!d9.{}q I]␧Yuh.,=q7{4/աد2k6.){Ff~wcHdlZ4sV9G\CSX|rc~U\Fu -x}oV:z11i_:Midcj ۴~o&g-;9SlqE/(p;ج7#I|ë8ߥM3 ]XLf<QX ;/k3A}^z[g37n9I{ 4GWn,zpZS1C'?=xxOxsP1E׃:Ŀv$nR7b1~-_,ﳠZt.lu< ӷ3 ~<[|sz7>/1,+ gG?#,Ϝ ^q!Ņ# | P\/yG>Jl ΆΝP}3ύ\^?Mscl'&?-{M5fm;iwȫN116c¡=1,VdWldLtޑf|(hUWxgX-o\*֧c-\P~zdyĢ22Lv|Fִ7nC3/q)INqŧ(p<{~gsgh?GФ8~ԏrdN[y +$STUe嶪vU~1#G:t hǺbN|* hG[d5'tyj?Y7{}Gp{' s^:A=_G9a:Ry>Հ2(^cJ׸q.]-- 1psi#6'2|ɊU; ]SNQa\x.엟 c0_/F]aVd> >,c1՛'q5O3L/gOލ 鑒ryqw}d}G cY|}̧)z^Lԗ[İcO'ݪ6߱KN A wC CLM|_\ǟ08*kW/XN{mw`MZz kK\ivfac+Oxi!2>ǹXb>}ϐ6|i\I8~x^*eΕÃ:{U%i߫㞛݄  ;u9n~9&gNvkor-׆_2/BP|0}kAnk=U !\;sX:~Q3`ʷ |DfSG!|-|t>9m+3+u/ Sv`0HZ֦ƿ7!Qjp6=ks4[b)!ڢ灞]GKd8G][0-vFgVk^0.<X.lui)lN8p= ۰УҭI#ٮຎM7ئjNQ|.k\/ya&y9.:69 w6ai^y6|'wvnY􍤨໤?r ԷRQZN f2gF} ^N)nɽaVM76LElB.5˃Mǁ=Ԑ3-gLn -Oelb]uƒx~4'\J4׼q[rgi]z's#q8 Lj4ay4?{6{3) vZVӕ߫kz@9o6G+[zYMqɐ_\8MY(n֊\>77sldoR|P93ZS[5a>1@|N3[r^BF =51îfpv*;[t1%ڄ}cR_=!LSk=69@۠}w֜=^OKUc6g!g'nynu be~k/S{54> ?Q^&s 'dN<{Ljϟ修gGuPE|Qn17kD>z䐳qa [0-%zAy87J)Z/-QD~xgl= Xy;\aBJhUg*q ԒX9t86>eZgP͌fE}=LN iJnx-ܫ+ew;!ZW~ Uzq[#3N^}/0=\}u}䱞P<z\gʗm>EX+~%Woj gӟ&]m!V{9˞uzAؿ{!Sdu7E,g+wϣ%Z翇/}X;[\tkג-8.^G9K.kGu2uy6՝n#w6CK|8p1_|bgܜ?VFs\Y耕*ߒsOxW95 X47C~wɛ;#7/Ή(˨#hVT "֙msF-xѻ9i뉊IF͈*hOE ]7'o-m]:+46Z^>2޷FkhTzxnynug\N{1C8p vk0O%'G=>=5Ga|#y9omfY_8g+.x"xx 4Ӝ1K뱾gg15 gukl!bWr⯽(ϖc-v{'tpxs;Fy.lׄ+1}8&'e+v䷟hu4~`+UɏmܺL1uVy9sJoi>297&E9kxw_/U @hn"i08dx]kEq4-?U`vi.,~c1:߳vZ aٰ6 9}UzN]|_1-soԕؘ礌]u-{϶0L]Krj*\I49"\db}۠_}-Ywi9۩Uy#P/MGnwb/'u܅o7pN==/V.fcs"v/ضJJ́8kr(Y/M9!ѱqҜ͟k6/}<|*l?f0wlgf,Bab:~UrLN'p%ӼjV-`mUa["y~J%ŭ8*߈ҿ!qt9"㼘ǧט<_ǜA_fA95׿M X!cu%OM-fq n99I$V$68zR/|DSNIwpwkaQx ژ[_tHov2~XbpSYޔ=B\m,l0ywqJQw"Η\:|E"yz^ӰWeo'6dr;۝x,9T[䯕swBK˲ZQ&{+Ϯ\Hy)_ȜAlX74ŽX}ߌՊcYܐ\'CX% 3i:]yҵY yInurگis\Syǿ5a\WG c_M8 qяɄ%^x>s0.ZZ潐 6/.~xNEc:SsgqBn;]Җ-B!/x0?If?dn}?Lq}Ri6zk;-ASYJwymN8= Ƶk~ WYQ峰t&_*F`}kp:|yë&iĺ=yx3F A[۵_9C3VN^T0X/mô?zqNS9y2uk`G8q>AV+o\B'k5\ވǵ8 - L5 ?:uW\k0ǔiQ׿o_2n zKw\kqM`M>vfhUsMs&2! D$31;mYY︎㳏m?&44sͻWiLd(;ޙT3CiCu^0\b9\S'xi=|g|.^ח'm#G~u{ mKY*/P>a?3ϲ4΋}:;5nǵɗڡ\NFciF9Yui{|9p\{s9K1vl(6wB?>9.2 AYx-)3+k9's^k|>^ }rg9,cD~ċq~^k4լiE!#c,ӽpIW?\:OA :B x{}vݗs=\ZGEع[8V%YٞN5c}~cVy˼*,| ;47KCf%>Y?5PoQpO3)b\g3gCbXgVˎH !)QM5̽II,zSe=tO5ݩ8i&[n. 3ۄ/iIY:#~ClwIx+wz=73_2԰yDu‘Z-102O1o# D3Y(` ||\鎀nU¼\5;'{R|uwYT npOueEal{仼K؟:.M9I]ȝ"΁9߂+U }vIwF=yYYgN֜)r<\* PbaXӥi]V)_u;O(j8¼r7aWG·d}X6Gޤ]ع/U]gA5_i|ꔳIr"qqu3)= q>EŌ?C'Vg\ ߹3a/҂zcR;cʷ)80ЬM8IN5 _Zvp80I F9Hyټ,ۗXW8o>O|u>Zyh5dͫmµBw2 qpmkNifg¶CAGhr7`'Dvݑd^oC.<>HXhY,NGo,h7kkRaTQN|bxwC2x{ ޅ=1#l!D-ҊQxSפgr1ÿ}9n3`.H3I=}PI\S='an)15-NN;%2/׾]v?d!|DJCz8UwgnsKmx", U3xʰDR d}<£c {]r㰹?9S\<g sR ^U<=RıOe5ηKݚ-\fUe+|Ps~`J;6˗{W{6a9#F wⷯ~{k6go)= w8iM/,¼qՎg |p"3@8z.'| T幔5_F™n=䧷][YڬU+ W //SIQyKF#.1GJ./aU#lIk_UHӫGw(yj9ĥCteeSνF, bQ^8KՃd#{vtuCq\9φS_<뛯q {ϰ X#y?){22DZs lx]8vpoT͘o߱2HB #wBos7) CeOr@pi'{߽n+ Ă^[ui= ƤfT3,KOd?k*s,NǢߕ>er/)dg=]µ1խ*{/]8k!UAJ=qiU_!g`Ucy"a2pAFg}|X,\׮\SxӮLi48% ^]#Wִg:Jh+fcKWW|D>0,.~*wi;$߯'S؇&7?SFYT}GJDw-ڽ]~K^yY=˞7杈]By]Td<^\?~dC6t92~f$i{>{2tby ߕމ=ǦN尝 g=*| 9Ak:x tQ7u!<@&Qn“d6a"ui/_+(WFF|ٸ/'qjXE<_9u^>s+ƣJ1ҍy ~<ְ B? 8E9ʍ}}nsXmkE~e;x갶z❎mgd|)5j=ܡQcz;=`n<2-Xo ےcm땓g 1lҮ\OGn2^>>^rQ`}sYlR} 16'B/܀$VenK|3{)מɾRť9Ͳ ٛy@pi3/r)7|g=1\I|P'Ղs77fg +iTI1(}p/3$HObg9NJ9W6y椈_oW\2.+1qW>UL;|srj87u} mFnW4֒yv[ba,CB?JEqSU+#k6dRW.á03u@ԟE.,}6jLu<2z(1P>~n1zZX)ZW糫/=5S 1.{RzciaVx{{tH+tBJni/[\>/qJ5rF})Yc>Fȡ c{ ;P#20s(3˶Ļ 2/Ń8~gC~ o? QX&㡄ɋRd\PUlrb|b"[pNow;|994|+H:M JlUW+ߜ 9]uyNdsWD6Zڳy0cS>71 kj+w]q~⋜z}5Tў-}(E-OYdK吏(flvl XL̺rRROԀ<'ɓT/e$8S5fQҮU]HsꭺUؒr +UPBsjYU񇽯귐fe2 11c=a8jQ-Ts]8ƬrPJ7&=L?w=47U3wwa,⻻(b=]5ps\]s|aˑ/|^Sn[2WaF>lXuB+ͧc c^y(eVNp1ߦu1 gK؃\Nl\uݝC">J*gI]6 g T=CㅣR9mUʊ-ϱ aC=˼뙗~0\#U!߂ɏ$ܸS£9zMC߷t^7u' 5`J&D<1Tȩ^^ؙ|2aNㅡ3"r]/I[TP=q~ǢO" Ms9 ߿w(d:x;FQk[fb;«H"C$'xv1`k ǽyS-Γ6yP6#:O> st 9?k{~b |^fCE!n8ucŭ^#p嚿ENw=NtCJC;!}J1XJ32)c*yZIg+VDy9>;uoA-B\EX.nvqii#)`*y!!ƽb1<7z|L$֗"4^:FgS^.ԋ W|d :QW| ِVf~O|HaPJI}ÿю#ˠZWc糓9bCĬ={T[wPe\Ͽ{)V;>C JAk]*'sXR䝞KFOwjB,}~e!^6l8 .kǃ> >yuvl]o\Z[{&\7]2Kq>~S!(zN]׿k*?eЌ_/['?5[ڨqlQ.=ji6tBfv팭'XbP/KUޏs~Ej/%Ѱ=xB>4+)sTCe۔_Х>O7Z&'uly 8wdspXȎJM(#Ncm`~yjO~3ί1j~'s tuʟJש7qTdy[!qo,˚s6>>m<ݭa&GЇ@|Bz] z7upo(󟤏3C"yѧר S1dMӧq^KFxf 1j0CV^)իժÿk|ߋ.Ou5Ean8nvL+ɔ8Rcgm^;yjaLސk 5imNZm%l_WCl֡ڣC 2xI.~`U^*g M|Eͧ['3GpLL[ o=ղ0ـ. _ۈϾ (=2t劻ɣx)}Kȇ3fnmęàfqχπf\l% z6y<*,08@Oώ.u_&s]=Ģ;k7kԽ(n5 ~ӁV߈<kst7ZTE7a]_% ,"q!+9kx*=+2}g\ oW̼fC]^dºW_kz+2󿬵Zk|N.kS;$_tb1zH^I6 02SMnnp g$;q)03{].6l>{nùrH=kGL_uNfd߾|Ĭ[v])AF3}k//3}|bdn|qp?ϱE?8QQns A\185Y&-aGUs_:m8~"6,D|rćU\x ߭*nZgjl];6=}0a 99NC$$KIŒVT[ ~+#d8/qyI ##.e <_iVLaNU5^H@l11+7nΡO}VmzdZa,s?%Sˠ.%-ҋ$v󗅳;Uu^ Qa KQgΧ(N4WqJlvA s /N7(>k('pf)!`^LWe|O~yT [e$0/{ qa<v| l81&;'ZalϫqO̟hĞO؇}]Uש(. 6:n.lz5L#GSsz5gq|W|{%ney/}i9+o^۝.@<3w'7ʭ<8Ģ]/h>ܷ|`k y=rw8lO^xo~ ]o|;}|7͹wAƯV2xKMm^2q_>,S.e.%q<] ks)4 ?vjM5b!|tm> ف~O0,9niͶX(Cf=&w{ } 7n[u=;5."v:]0a ۇbbRT9UC j!e^X9u2/%֒~/s?&%,[&Xۭ4:q NnG)\\Ǖ엏U{-}&#q˙͝iڏגL~f9G:d?XKgzK4'|'ΚYO|<\2`oE/µZ(ihժIV[QVP)vrF݂kEom~%l3jx_Ӳn8"lǜ3yن%BL:Cxv |N~?e$\Zֿ:~Ȃzv [6Xː˫<ۥZs'ύ}VT_q:ހV -{ ޺6C^_S=8dSРf@ȅQ<߈%8E<<^ׂWI׾Gvs~v0>k}8,tNM,uCIpEocwGosƩk}cY3-[97{Hچپ!5A?NO/]#BY6w }G{9/g\now~'8;H^ˎsN`Y6amƽnv@x69bV[_52K(,qgm8ߕ>+y,nPs=}&6NsgyέWVd bO-g9aՓko|0kL7$mdU,ϢHWɸ w57yaCF6ʣV=|{,n 5cn'2cFXk~o8KOtHCYOӅyMQݫ{lp[AuD?S%3޽ :8"%- S8ۮ:ǹ๱ Q_T\'98p_9~\M]h -?{١IڈYan>ǭj96q}0򂯵ʸ~c!iϻOҡqupV5?Ǟ[!bA='蔴M)'y"{tuGbsF ֤4kqBxasΨ^UlT{K1\ k_묿[!sMV) Q^!!ÆήYي˳yOg{}8`^KOr'| no!区ǨsԷn(\q۟Qq;<)(zlwƹ: ǬWѩ\մ|R7ux G3]ǐlap;߼(lk.' DjGPI6Gߍ;}k<<?xxjdI5ӏ&. ?O,8sj\qz>ZζK~ظM:2tvz#;"d,(\Z]2wkXh;n&6o>{< bcanw;u7ƜiJvRO`&^qXYAea 뇈򳸆B_F` yH_tǹj7U~݆9k`+MvXs{u 󮷜 vlE(@CrDhi3LJ}-׵bQI}l~yn~N?X~;@U38k*!ת'l]<#i5 uw,zluݬVto=ʝV?ZaP5mN!n`K,so6y}q%_:rlbE~'^Ϊi<ٓ34d7x6ɶF]~'!s:4e}}YEKߦ[;=~V-B_TiV'&q֌s'}g:jlN9alss&}U=:_(=9 A' uߐ;tOSglg|ɥ[njOf{*vlHNgpJY_֐?=3 }lr{ x"|o+><9z鸝E?|e_[-iw0gyc_HucANYYf >`IwKgq`L6߷Y_ 1f6߸tאyV5߱Q6Ѭ[L+6SM+1}ń}ڃ9pQkꊓ'}1Ǵbgo+< ~Ko}LOϫkA-ڥ8>%;٭zڐ_툍ylF8,74X_->~~55V{kUxcYWP<-~i=/_q4 b> <}fxvMqpZC86߲]uFs޳(?.4-9.]wWosƭ>]:Jn[ML{pca˖b?ߢ^YsSplqR/؞sjWr`X'O]yV<5 Ԛ[UטѯzC a{yMaAq~k&P%sp9&zִ Q8Jnjy[ݮd[]=vs0 w99\BMx&#՞n&;ɜZ&deW+"vİlQcdW'y6]wiɷ:qŲr_CAuSָatQ05Zuwnz\~0y z]{: B:y6oJ]5]Ի?U{|{ vZvJ6,>blp ZА~9ǥKyofxqJ'*l0_=s^tj׫׽Ii׹ w[[g6L>b{<&^JUgI^}e=nGF%Ҁ-f}[=k 3MΜQ[32ྃyw?Cym߶8/[19Yyҽ|odLʾn~F| HٝϞvKͳb{"^!?G,Fv>QqЗeojާS>sV\Qlismxvt.![uF}.!|wO;PkNvKڴwtp][msc>Nݸs;f*ܳ[-{Uvu~&{Q Ʋ{ KluUس7}qk9g?$z1Z݆V1/LsMjO:eCKkufe_Jqv5ua$Us.ƺr~٪k\mM;9xD7ë5o(nFƖ7!em#e[C,\Gw&8lݮr|9gkݶ{LɂbrC7o ^𱤜ҨZډ`/VI/}>ew*hZy.6{>s| cksy39Ҍgk}l,t[r@`[.=3']ilNtj/Xr]akP#8pfMlA-_jeLSǏ92w+IgEjGbu<ך1ג%{#_%e=“+ᦟfopb.G;7-OxaOs<.kłuqΫ>yߌjb}OLV+/j5jsOlzܗi(VƜ!s=ѐvhO/jtH^P֖߹Nk;>5"~)FYm=B.$|FF_[91裵y>o5==Iz&ݖJUox㼆sBSjL~\% #Î.-Xi仲Ʋ6CQΠZiOH16䙷89w3-@z\o湒zk);e#9G}3m:kPK-zR{^Ӿ,Ǒ7UUS={[=vruo`âr7c18q~?ޭǶ8`9tkshxz= 1sI~ ׄ0sr(x>1frn7aXY^0Cy׭QjnK7[6wR=$Cz!uFvׄ3(S̽Ou-̇q.1,s;B͟<$jNu}uyk)%;!Xm)w˽{X=rtjX;.bgq]ƸS:yCc);洧~uU=/b\EAo}cJ{[<#~v?n2,ϴgmL,o9@p_9utݱ\cfYk^ޝ Ls&j˙ݞ ,}ꡘU \&1OގkKrPxNhud<#fTy25Pbv쌞,k5&|Cu{Fr2!탺/sCqGf}aJf3cڬEн6%ى=5~=uYc[=# ˕hbA_i:No\jھm+tZ!C/p]Fco#Zпp'.P?jx,ʿZg^M<4:[vM6.~zqM$l~?Ӯ._~Wd>E?"a?FUG+6zk;7o֨dF8Vd,~P c>ջgnmjNaNgÊG<\y&P-|J\XSa.1S&#ʩu𞽢6uUF rb'wzzW\\R]q *Sq s2&F\v[cz[i]||zՄG=$MP}|5<8#׵pNNu^u9i;gd|A1fpXq?~b޸lFj#>r⽕#qya8]bydo #c}PWfuIK/֡,߿l 6=škӲ 9Vzi/m-F6gɏݧ| =VÙs,Xy/ylxZ㱦[=:50>~?vaЌ)kO[3?6gyEf%]naqihW[uHݒɰKxC]dK# s]OַSrkfH_iO쌴CQZޛsn眰$/MJ~<,'p}g9>ߐ(EóV ǒϚ%o˕Z ly}jTv_X\}0W|a g$na+y0^#B|mA١-ʵ8$_̎'_Z-߮YzrVKi=7s)HlUzмNdWЗt1{#; yQlQզ=2zjG>2=Iֻc.6hm-}+tzՀ89{ .Ss?sqVC>B?LK۳rfsۣJ?!jUM{iVdIȜ #c4_ٓ*kr?x);9q~POlKSսsuXnmYy~6mT~Ij˳V΄O~t0|mnct4;ܞX=!ܱլP،O},Kۣk{>-dG r1!b we Xx9].W}ºU#%O{#dM~O$}bQG5xӞJmQctj5E՜1#6GA^{}!拐"p~:aiA2>no#^t߂3(֬̿݃ߋ 2?%xe|ix^?k6miWLk{3a8y=}sq|ΰvI絁X|P'O5}ЫguPϘmct7}ԉg_I緛LpZۡSxvD5^qaWݧAW3q}&6ѳkoȱr0:33/BӶD9^c|9~8ϴ7~l_˃msCqD^S]Y#o(ivu֨0 0嫄g\W`3ot.ۣ߉︋wgA.'x%Ijd5Jt]tKF9.|r^^guJn>ϥ|٬S+gVAFjEG;ܶ/f4[3p?an>ny3`lszy'(d˳=>EĽC:;q B̸ E,z̴.N9/ŲU:z;| Ç~%??;.you4q:<]G镇OaKO/{kD~AB>k|^M[ӣLڣY=ŠPfX[};F-XIЋYv {τ^s>˕<(,(zrϷؿcV-U}-ϒ XeQw3=F{c|y)f9gp fqz~w o_Jwt*•dӡ\ܬƔk(rxOfvЂqͷr;nY?[ '`;"tp=1`:&+GNb\)^>qE= VX\ ]||1ߩf/'qa~Xߋ~v۲LXfVutx^QXܚiC_Z+~Êi벹dT+>zA^p6~d1JP {C+xȉgg޳A_g7AV/B{^C Y-Ϧ[)–/ FazVq9Gc*=_^/)U?lvhBǼM9Aa){j%XH+ LřcgwYǯ`ݺgb~?!b9x)صˉ%@X y7#A θyq=_9*|8̉@LeQ$ ﴎ_Y߃:MT a/%,/=i*v8DbI,cY>oI3KY{T3s9aC}hwl â{ryJT[?qL3rUwaUOrͥgc @6 zr7o@ǩ7}^wPĨ5nɂݾ+Fwa=I^5*3.KWF8Ηg#Ϭo|x|c=qV)֞Q1S~V}(5 8YFaFSr6B6نuesC_J sd'd޸פDDaڦJ. ÑKM7_Q9}&*Zr.K;“h@ӆع\Fփk&Gp>-hlsmW)ܩ.UN=k †Co1Zzܘ\l8}0 Sr. %+0W$^!3YczQ0gZB?QiϺEzqx.}ݧ+a=+!yOt>ցW 8jB7n;rzNNt ؏kKw-َq7nlȭK5_LxP7yE#{19>pm3|'ƧI^cI^-Sb^t(AFEzvb0g8`v]@\\e=g@^k>6LK](ǦM;6dmzV:e=up]}WbE#m8Fkfְ2l MŭY8Y^=!>/q~8Ufӆ/H XՏ* SE =rn8OOs׎$<2d#v x]U #!'gxtCt1Fag^-,ra\+ߝxů[S/ǹ8y jz96X~]if/H.p?7ʳ634@ݒNMw1,m0ۣ RPI#ޤkZ@|sqz=\k)!ׂxĝ^rB\%e\×_Ӧ}vt9⎛ڥsY_>Yu;Vy? e{;݂߬?l~KۉE[kˁX6r5j{M+#k##r{j\?A%0mo<56;5>Fq2? ; =ݐk:Ҟ>\^텍Yr&0Gy1%Wc]筤5^OCd}#wֲq+<"a^) ?M#qZ[sWГ~ !Gi8":zǏ;0ޣ|# !?a&ݼ!֛ZΨk )Kڀ](SW8?١vqucsNўT[8KK]RQmyav~(^~T6,<ш(MPz@,^c+8 @ L჉wGbx-&oxhG>^_lr?}O~Sgaxk7"Qwi?v*d#0wHɇO47g.Ӭ߉cޮ]8 tS|׫^!kTN'`V>38"C|oaLؾh|7¡.@rɻ[z _77A;]/z"}kmmOt~A{))kŦx+^]Ӗ|j([H)W:r뗇M+a/a8=7Q׆Xʞ+.GI׉b7aQ>#i YQ%OņKeϙrz.d*׹Ċ6/.7ՎY`n3Bng4zB}3M qsq$݂lu&c$[2gCL!gSws)Krn'k`n}9kNǙQtG _DA7%!~";Xpc՜h$'ê^ޠ^;odNJ-2<Ъ?jqyw4Nc?@F>z:|VdzC7ӌ̄%˳$vi׬Q`qGȗ\1k|wPgmwMC&WA1d8$/bqɃ4E ؆G]zHK.vIVc3.xOۤz:ф]|VNrh yq-,y ~f-urt[֡xxøDJ~Sol왒kN4)K[ǧIƑ ;K_n`M$w1+z?` JLI<^IM%o_=3pĹX7L.q[jHr x%ɘc7N:1M9):P\Y^!b+/><~Qgq.yoB}˯82Pt򌔘ċ߿_wB>^#KCiI\"H?bܒ|1t$qW \CkΉً5lW-D6zB.xoܜK)}`o?'}#2XZO7=%:g# aT%?7ƩޣE=U5v]U,(^^A6/Q~˺FB;hCnG=Z? Q쳫EuȹTڂ[M>'XW7+S#/kDwf<[MOy:<+H%b1PNm~6F?C ^YA<7WgLDwBLIr<.A{`Z^m&<~|A>l-9u~QgasG{x{9޻c3W?bԇzLƤ 2￶<| 90#yY @W{!_N|l=čq~GA>Jg%x9wB΋xS)kUOOIʞ'&sb3mo'Y):|!(qX|@9p׫Ǐ}E;ReY"ՐPhB|8'm#jǡ~}kSnH閏>X|?s)q XLNXr~ufs-HP8)a--dLs=̳X+,\zr>f^\|ڣ˰֏C{Oz$xapWK/^ybz${=:;,˜zBlC+<[FQg"Zo|l9?؅ q |NńJfNEÿolzF++È&0nip5|kUOo`{VC6ބϪbw:W`>%ջx^w=7R|2o"fEŭE py.1 ܍t>TGaG:}w\tqkOzpvzJN֚A\m;Y}3f(|f1֥%awȽt<ɉU1;9) J]ڑSz8~^|1b,Neq 22-;ǽlk336W=NOϲ위 ,9;n\/?zNi =MuO%3;.XCv{*ᝲ] }PqoTz7 f_ wgC/ٻӋЯޡOqϛ!ϫR 8lb^آR^[t5Fy?tNdrL7UO9qoDz{L\ NT;!G2&A !Y\5ϩaP 9T3>'O6Y^GiUSM`l3nSS7neA'ȫ&m#S阋`P9ϼR6⶟~S{/phg4|Or@$%[3 '杖a5sȞk}-Q]nw-w /aS^2^ Ck#0K sLVԹfGH}^3#?^1S(d:<'!WaW}-]\q=K?yŜũ~Dm<_%oL.\?L Y1SMȹInE~bH=(w {Sy'd$w |c>xŢkz9|1G<Qk/} }6 :(_rnzF9E9 >^ȎINuceV]]z8>*xwoOw[fA[L͆Vs'^ݻ 䙐3|>Zp™=):%zb}>?>OOw'~_|H;?KW[q=״Wuqa z8LVlkݐ]ǰ(C,bCy<ř}\X]O"{nOT}rke^, m qqiCM)y׉CgղNGhy4[ԅyf%Ƨ+ ?$]al3 >G8tY9> -l`Qf!Sr&~kf?N,qSl*99A??O$^`UAV/O=)[oD?f*z6wB'[|mAK^{#FAm.Q/fβ~{uZ؇u׳r6Jy[\d㱗}mKyOTf̻s"M?wKWu~tDFݰ'[`[WX. oSz6~IJs1`KN(ǰG>oY͎'[}Y=֝Q1O¼E 9ߐG{.dQz;owI#宨.OK߯;Ź"B4c;k'+NSSa!?շ\r;k>&5q´쯨WOȕ췐T%!7"{+̵~-gY,OF5[nU3'lf5-`||qxΝ^wAw\+7ykV R˕Jag={^_Dim&^47US/ZQ߂j9E?{@dO4eЅwycj8#Ȼ ̘< y䴔mI7(h |Ok|=~a϶60^sFjuHꊛz uoO3*198`-9'9u~|x<:[D9նT}[3оހ{<&}G Gq@>:|Ƅ5=lR=upd6+[^1{ٙ"ll&t|v r~~5~?k_Ewt؍+Yg|;%Կ}-'> .|eN~ƽ9s}9_q ,NKLs9+1Q(O@FR}y ##M^b^|LlȗpJtK^ފ[v|rC/kf %λ.5Pe3OJV} ]ݣc}Ta'3k+q&nF[ [2~,״9_r ?r=õdSƘU(}E CqRq68}t9`cfsxT3zijkC6O޺O)z/Q,'C'„qZATgTgd.`ӫߺ 㽯?}zogU5?WHy(b=r5k7ߐjE 8(r^T938}R 秢}Ki/U8{q؇R_wOy:t{yx<z\cye5`36ߋ{~eݸSg.vbm$䕵zx8eoz@w~2x;|42ɗoqW:H3]nx-s5C;7S|@l8c碷د gծùSi;N|&oTi{rvdɊy?|!󷤏_~ޟ%\WsU847sir'dza'C-օoƹs}zbͼ&޲bʪ-'~\m} #^z Xhxe,\l>si͋WrS8I= &__ǣ!>=T%s&tl^"S5z)Fu/ Ѕ:_^?\sK;i9wX~\Ќnȵ7e"1u=g_l 9- 7iLq U4E=摸7p;geCy>1..ԧzw6^c$KLr8[xAr|p8 IFF,ϳk]ZUWCߌQ2oӞYY]_gY{ 7<>ݠdXD˒=_f?&ojg䛉˗[|c=_xM!$veCg|WC;<{lvsG04VþZ{M5$xRCv(6'I2_@?u_ŹXEz2t97׎ʿc@ o\G`ǿfE?RRf[yi|\ZhηMN4[mkk}|y_SG,cNq[1:')sc I{_y~ /HjZ\ą>nqzH}Ee}~/߀3I,dHb>yF0(}9uc}1pƱ~9^ad> THr;}0Z6=A\#?scc57@/oL9KH9Jy:Z޴C1۱zܹEq~NM? u5伉Dы=бԲ~w{i\&4~b-k_WAXWr=%9@ ӰIJ=b!rw}r六?D {D5ےfHK.b>wFsmoW~"Grmҷً5W9イ_~~~%1'|8m28lq-|?ݧ՘!H|Mt U5˻W~D;t}x~wzwP0yS 8 :{ W^3%sv]3 \7Ymnuz [g`?ذꬎٮyQ{k%Ջ7p (`NZݓm3Gsb^^H{c4My34Bܗפ0LۣfZc b|ݙ&MYZY_ʘfoKjO͸|dq|DwV_ZU`ϿStw.Vt(?s'Y"HNLh-v|BXz^%ߟGKb TICC=K^ b75[x1bwaje<[,I7jv|>r ]VijU1]vXBvVG֕?lxq}syINֳr>T6aۇyM?x|d>[E[VS=Cڇi]q{<^//^[}^})^{j{yN(Εo!N8sȸgRR4vcpK' #ǧԏ٥ZŴr5}-1XMv@RT_z'Y}ؕS .z0gGw̑&ˠ n|can!o1'?s?{^W^y((J_{X5sEy.؏ Q` 0{_Z+=1ջp?ChLM vd\e=ǧymXͩ0)Yû`R5>5借r_6o/ޭJ$5#>|`ߓ;w1{Tc (h_^&5\S=RxOy Czeʕ+oTnùٵZvFMP $~-4١UOYȶA+a}vD禝QieX T덪6f_ 8`.w2b?Mf13?cY=d>/!mH֋OpB3&<̟fyx>?? z3[WnxY^R&s~rYυ2A96WiFP}qY b8׉aI<\kSmz82aLM[ h|{zCxz ez1^?^q$7GTv(l~[ Hf=DWx<dulE˪ۣzK-넯ޔ~f_wV>?$)O^/^OGM5Cf~C?19%rw& r¯̘go/tua.[浯U|a{#kU!<DZ 0\pƒLp_u qVivS}GF] ۰?nVn+'p?ɰre%aGz|M>9 #ʫi. >7h{A[QR:֞W#1vi.idQ<~ ɲ泿[9ވH9 ِGvunײfw #nD'꣞wB^b/}x)|G3װ;+*)3N:77 WuҙqW xW؅!z=OkRy^W]8Kfsc$qHEok?,)\6ڧs؇ίř7'=HX`wWv /<deߎcr̛sߑf2N.ׅA !ړǰ_ԝʾY9[- x/QĒ{;q7 au ;lp^ EI%`j^}ps>|MxY_4`P_ܽIbޫS9 _~R$ʉ엎et9 Ed-,fP7z3+ଢ܋M6 WB_/>MwrO}p8 dOG\CLP_cOc>zKx3l}al[dsmڸ8wy=3`vmG6- ;7ހ3m+2ةv1yͭ /b|9aB#_FFke@}muۓ.L\"pF&ĘKyV}Yy[ߞ|Gt+aՄzpOWւL4;c2OԹw8w相#/X!f'K9>{!@;p^lJO*ɫW@>UCa%7ߖ= 1qos+Uo{;V]aU\bcS1Z~:ŹKrA`?M%}/]qqJW}{@C؉Sïgkiys]MZ1Ff:L KNZ!<g Ğ:I߈s U?C=9]9$lKuX;3;Tأz'g*na~>_@aސ={PqK)8xr k7,2$kuM-0#ἛzXK!WEv%!o͏F|DY$ީ6+ B1Q԰ cS]%uPc0>6غ y@9#̣)ߍ[mCy?=p'<==2%ad8}F`Xady#M[Q3q|81 1:abecv\Xj]T|z%`#s+WZ|F|VwJ}')w61c_bEZT31({brf ,v3WmIMlS`nٞa><9],#a>|ç1ul.s;-d|sUO/ⷊy=9,|# \fn0.o4v+U">u&\Wno43n`5dz!$~Qlya>gs=Xg|C;=.w1ؘ)/wAavC9zfc¶=ƴ ?/z څUluyO_0Kf}#"UQ#qԹ2f\G[\8kG>K`3o~}_5l=(?{8[H}𛓜6?Lҧ3'-pnn;6l!gYɂbsòz |B҉g^x߇ GaNۗi. z'Oge8-ߖ"c q92|83@.5EaS)9 }٧SUrb4V`!9`8q9+yonQb9Iž>?qCmq~uoIa?Q6x|?t :ۥ3۵˟JV x"]NJbA/H3X+8oCJ̹_}a[;0 !4F@oN/ kʡ1E\5hSjϣ/qa5|Ϋ0oq> ?dZ~o5}]#}wajdmõiF oLvwZqN>q8`"yO{;7~F2ΒZv#zp}P63{{EZIu]6IK:CֳG 4/DL nLgާbWvV}yJu^{?! Q^Bزzy+M}pf[fCiWRGn+l{or-y}LqvAXC3 {mg^ 2ᘦ\ߏ{dtt}O5Uă4ß5˼S m͎`skF%G Zv-lp-CG_5ڍѰ%NwF_V4/dXnX/0~1x0h͕o8==籏wZ>(HLsOٸwr0Ts7I\Ռ3IN5;˿*ĸy?yOT[}ѹbSGt9W=#el ͉E3-tJr,ǁopzqV3o<[c1*w>y^Sz49Eo A.wȌb_ʝ`Ϲݟ>ݕ^tY1s[]xǰ\S>OdOM}cm#ʑ[ gdIhX|q{dx#cEi@.ij t_@`N8'}zv q}^T&\py.;W=sM|·[a{KE 荖ʼn2y*Wd*ε\irUl+KwRS>bɚֹ+!<}r牸Uc@Ky 7sl9i={נC̫!i/^3-zy#"ˈx ]}aN,vFK>(7vB!q]_mEF}WoCM}vkR[jǝoyI9YN4燛0C1ux-9싍SblCEߑ\i#==T.=scβۅqμ5zۇ壓ag^ߍb&\55YAyhX~ACšk8GtU<QC:VKW"Nv)97;|M}q- \Dax'G/ y,z<Z9s/=]<5틂8~o1/g!v S>|3`C_6wxڙ dl ;Da;uw*.7[ zq@yJ*gQ2Z#\q !wh߽S=y#]ϵdK_xZ-qNaz7}g&_ bM,xA~r>m_ SEB&~jju^v89G4d}sUEa/+3$_(1^H5|,pʯ7I &d3 s~̴1ڀc0یS]n3wȷ$^SUZ~sU XI.7ƞX`gLq q)w?pTK˹o+nلQDZ9ZJ;tCzO>2-^A[98`>1M{!sPas{[m&ѐhd\8}Ro㰿ٲ}a'"jN>!ߧ'>,d/YΑ?M?W#9Πldød#ڋ6wj+\ϸP'0cmέ1D#'lW;M ]o?%; ;QЬ͐~)?Z{60]~[]Ca}VXI(+,xkW~+RJ>.kT8eI0)? a|@ToRوlikEYxսQ79nvm/rM!cgp\hb(:ncgm/pn؜!u[^4urJ5>+\o9HCT͞+gè>xf;IrBcw?oS KpR6k䖷:ƴ6$-mP{,>b +}_ Ćw 725k {~~S^syZ^LX-?PoY#[TEؑ싉M.̟S1TGsg89}З̞Q|zSS:ug+ 5ȸ%ة8ၦ\BpEJgql#fʉ4}D+3SfHr8!;mVޚKY|1|oCc8cV8O& #!jƁ{2qs+g|OFVm<ꙵprIga/g$ğLh:F6܏̜cΔtna뺪s5[IDb2AIIhtqJI!*%-kh%H$ HDTJ i'b3!x[kl]]ko}dsS TyoP%Pup3.fx-'ٚLO5zi˫Wh6ߪ,(gY=6ƹYj}0%ڮ흶SMgbzmE{˦{:4&# V2Ucq21M~aF7f;nsodOʡ3m;o7LXu޸\&98L.a1tfy7xא=QN_R4bmG/R3.A1ʖSLZip#(׾Zf? +&{VxmFYZ#WLۨMVUL_MK0:1hヴ>BP#~6{h{*0>̯>Wi||[ |-ȯIh~bgE?:,}hcx_'ް't.90k#a.]f5{`\^l2VkϚ!, :ߚ.4nu|^eM~s9=hhljc4AC?Ϝ㙁MiwRꌑUϮj3\6|L_ ėgy;OK#gq˜/YZʆLoB?56>>ʳoE~-kyJX/k[lTԆm'9:>LGi{%ux2iY~#usjzo͒wgV93^6Y2rsoݠ]e"S]= 'yusz-8_l&JyG5Sΰ_}2nTM15s*gy 7o|AiMq\n\j!)ORwy8NcKO=L}9oU6EC)5\ebkMm}q?sv,.lgκAq?t ӧ?vmoXXp'kh gu1 C[\#s[Gm%?fFLrީ='^r݌Vnج,и؞b3h,:e9״ч-Gfά1A2ܬC9ڳ3CccÛ>8g{ TW"N.\Q'xf-Z97<@x<<K|<NMYe󁳽22g@z\*ڦ֊4OXTcE{vZo>. qQ V|n;x@\>u2V93RmlggI_X'5>^e/2nkmaK==c p{!5O7 ւt&Jx"盞K֚PUӆ{f-IsM/Py}:n9ǺiX7hΎ>x諼9G{-OϮހ c SXSb'b4iZ)kHz ޮ|$>s|4Q33I?PF`Mꆷ^g@ߚ>PlBLd1 TozېYV0_7g~_1cagh/k3A#66Tj'}e/$1?՗VOWssNik\3nsTuN8GŻmv͗:յ@LnoŞ^}SV[P_,sW3SXt:s,h,$-,o\fܰtg C Wlsf%b0}6o`n X|~(j1بW:k-ӒZfzCͣΞKvQ6*60N]L_}Kӹ6p=T3ngi< :#?g[3] !ZPu-V&ÜgV^1;aC >2o߰mi>fz Z Gs:c8Dh2ОEkM7h@I?+Ay'5b`gA$xӣ9|'&k۸#sLn zÁ*>?։y(Ng6Hl5q>fAjFKe.Pa)P~b.%刭yոA5_O!.nԔY LIӾMqixZx>ӹc 616c?yZ#>[u\Z-A^`룽a9UsZ4[%r %6_Ϙ]:z;o>>|-OaX;̫[/{(6ң|^7YدOOkl.NX=cӞX>$6\/[xb~3}~=gV⦨o9!IF}*ܰ 5.UKBMjZ(Წfz9dGY1NL9YM3y̑7FWYkX0$~5Śjib}y0e9D8}s =q0ja+?b74GDT/zWzSD$1~_=~ū}[:*E̾f_OzqVBsn.X>"4X/C.fʗʸ+0DI5j_ 2gS0mW#~gv\Y^y?˼5osRNgU|Ų0(}ޗr-dKGtgQ_+g;???$[w_}{bߗu8*oGR+G[yB&TQ 5fcIw;0glx~$SEOՉ[~E9o諧IoZxkzs[{*ʸ%Yߊ7ĎWȿ;>-U̸2%OȚAy_d!7\E#ՄoE}CNDqIq2-GWW[3M#ƃ]6Ϲ+_W{}E#\7wg_|W[+iS~ 1ef:,GycI]|T?:,W̬ŜO=< u7@> lF}XJuʉ)14LT-酟'h='ǯz|V]8k_ϙMX|W 8jtywb̵/eyw u_+rmwOXa6d㷏V^!O60Sg:xXk'?')yC,yO|? e|ρ_<@-~.eZޱŏ #_oavԾ]ȓ8Նn&>-`WrCG~.7ʙw\/fa& 3*ca`ƃPݘ^Y_L0U`̐al:C^a;G<>.z<ⷩP˳_ jafMzQ:96]b^Ʉw9G8_:ٳwpks!tFz7Cθ[EҽZq2c6ko 8iq=`}/p 7V;$.Zp}İk,XMMƼ\Ge<s%~+ԝ~JqY_6huw7<07GM%^;VӼCb?W`115XZQqyR^(b1yҥz(jangǪr{x>]Y!Z >I#? 6WZ^#3 s13Ć{{"Pn1*du/1w 8*atY=!9LZwY85y/u(/&s^!ny1O?Z}YÀ^۩鮋0.ė/o6,y416bKdmkMjǁ=C6b \caqs7ƫgw*TM#_rHg7bf_֨zhD1g,wS suvvF;\Kڒ2/|&r?纞L &O=V]l~E-SY+?*nj<0(K)R0!^/vqNkb1 fܩISVC̺|$vlys_u^+/l6 ߦ3!ur5;w:b}iǘ9yd'pF\Cs O? -V 54$ΦMǬ .1 B-a^f!W{tOCOuտZ4z}|=cX^VWŶ0/"]/y;:F:g#t6:9leslQRuϒg^Zᅴǡ<qny߫vR^>Q"U]ഏM~}ϸdU%1.;4'\YGdm@a&gCJ;8Y#OI\r0q?|^7˨e61fl!+mT"&Wb0ھBШ_"9SŒ^%[^͌+zEƘm Vk"ZJr8fj+M:[j߲-rԕk##D}P13 o?>j;oJW ?qS͟5UesJ^uIΡ;P7B=_l0o5c{.r1P.caY|b<o{-Eߧ8e-cqϗṏXaTrqAŒ%'vb_y"~2s7Y8w/q> fcf8Yg)ra'.`6`q3:wV7h-M_ACaxߖkBըQD͇8b~5_Ǚ̗ ˘Ak1q:+,4yE2u<.{Sj<9 $≯ 6g(?W5:jÆf28^~ ~N=vʽ/~.1%ZϽV Y{CScf~vV)MVn%4ĺEGoШ{~,{HcίmөOW7A\v)d33Ҏ1&rkqg=\ƭs{#.^hu+bm9R}|MqN_9s;?TzS=_).bYO6ȵڀqLdz8mwwPWy!^Ey$wGoJXp5B9T=TvG]qӂW h}<9533u}Ȉrۈ[gܘ@V{- ?^ȿ_.﹒1g= )|o]΃'1Olr,yWM͙@RK٧gH^,c)fU{s5GXWj-N1Lܸ4y6=yg|x1e}+m7`Z3t0xwF1E\ \D5Mw(\|;6|<,g/rgry7ssU$*1p֘kYJt*VW$7q _#Rx5#=s~y똡S_ æ)yK1E|E2V@{{jO!k:r>C9,9YjjGRyav~?a*)?߻9ᅬsu82Yj]!$ί-17SԆCI;O֌^ }bo*yNO~}u8):g[wq9c8Kc:bk;4oD.e,iu0|8w;F%^a3o#6[ΰ.ynYyz#0VZKۚZ OOiQE{Fk:LÙx<3̎܊cմ{MSuݬNsunZsb𗇎k}: i`h`<훆 ȵYn%لrYXub9׈|.fRw:KdqK#dwaSbxDZrwR? '/^Eu;BMjH \yS\g&nWo;Ec^+c5x713\͢zގu 1湎vy+cNiOX9=tX50/ {+1z;SԗWuK\ENĤb=a7aLWr$fcfm춋~"RKBg6tZlaѼK89+o1Drew{4T?`}PnTM -Uh8ˎgxuK+Z&yCa{0(-B}2d`t:Čz^B\-^$ח;į/e{Do .ļd"!w5g}kjfh7`ojEkSH~\iN/i:2]N9ڛڤG?aW̔aycq^:8'-Lټ"[B"krdw?.$k($o!Rw$6Ic&gU|isG 9yk-yyVd~sœ"бY)yΎy1hI`./YJB`e?#un>Xݎ0-6N*}ag8~~kr 8s T=yMpR*3y8\\VfHZo c\ 6\?!;_U0/}fX9L3ksW( UZ/8^<cؚ,@m~9Ɣ<1sG\R'90Ts媰u7)_;a>'3qT+`_=}-wu>s,UԈremR>/lky'7šjjuT`_pJGdsV>^7ȹߘ[۩N<|nra+>[_ tNY)r 6˩Y_lʆjciG䆿83F^_2󬽜rpS}9S5QDs-br_@.zdb_+ 7_ g[.vl7%1 bXUl8̾s&3C6ɾY.,)gy3:spE7YmX K29!~h6刓 xCPhyĩȺ<4X&>(.|,㰮?_B^%cքQEx*,ksh[;3|[%\9;r1ϲym!8W˹gsǽ'Tne^ް?"y5kGQ;ˣ=+:\cNNZn1wGKt3f#tp= A`ݜFu%t)X8E!XgKC=I̺$6[#djj~ ߌmyz_/ Y79?Y:Ʋ5O-{z^˵3\_|pOiƸ$Gp&W$Vsm/fհ &zj7#S_'am~ֹu9kRmf3Qgwa=XcD!zGmYi8I2%zYwsuHO ^+ݬ/yuI?3S΂kk0?,䱟kk {~__;.LΓ+umX۰9=N>6zF*ٳ{rA?\\{{yY ;,b-w zf#T^!C ,e5Ƹ"k&XgVìGOwԬBB )y>^Pe05V:N144 1S_r5ɝ%:vֺR-zτZ{*9 ׬/:=j {Ygw{Fw}{4>pV)~u_0Xauݬ7!o=u\rx) kLR'ݬo=;;%|%r7F1uRT'2h=$3;?4{`aoȕ>!Dg.|c<+_[Vƺ/a\5v`wq}ˆySߦ5Bbk5n>/pU;$vsbgx>8D.,_~/ع[> rO{`okٓYײg7}ʽA1?w󆚨=Z/!ЙCA,`|Jx@rmG ~N$>K ҌKD3|0j&և[?")t7M8&W #Ywg5Y[[e;e}*Ś3UoH+/{B_ߑs"z-q~=ԾWVa2oݩ c5r}듲߰Y5Ƈ9ܑ:?H2~2bς's6sb r帞>j95z%G| _1(kѺvNH<5T'~~5Waǀð6iM#)]qS[%bk_(!jH9ר}$0&F]V|Hr]ƽYhYڦc,/+}~ޭƮ0FnrϿ*X)_?%fxcvm_ȒKuock;'sXԴNXg{vS}?&*#n=}vgZ Yc-uro;} ׹(Ux:gBir|/ȓqYyy#Or?@lKF_/_PSC{p{g f` !i J7/?99њ"pTȲ/ q\b 9xFg+Cf=歴U NQ+É\x칇&]nQ_*Ey'ZVyTJlip6a~nkF~ߢsurrMKkΈoZx>(~ϳ1%]a^ b|^X6Y[^+v139`5ҚLg 8ꥧ}.wx 񍲶w37 ɺ{7H*kge|b/ "y83.F_W>C4LdZb5[7OoMkC/X ,GT'jdO߅&+/fT8.Cp-o%W"qz~_kŨmqIz3?Q{p?[H~\I}:r@c9jXR^Ǿh-{Œު[ir@._D`E[?0?|rj8k]ڼ#y⁏KGp:I8(309-*y"pggX%sQ'4FksR|t2x x8s_v5t=$3 cG^eֽ02 y/8r|>H5.aCjFWƜ\AY?qTy,YNHkW~ wy?UojDz\ӗYE\F~{~2jjLKY"Y-H*#4tTog}Y7>uM738}ϑ% v|=:ϱ5a'Χf=!Q+{-~m;Η8q%6^n{}xRSŻ."mqǔr1Crd<-)HZ|I\ gV|qۅ} 9pA>seW6L\O_)oGw%~Wuy}Zz'P^~0 };{%@p/Z>DH,-w ޖТFԴ؋PwͰ)&ZW|xs_%p|=8{#u\L qSZ{Bz_J1B?y??.I-"3=-w<8^/yk"LzIwF(Kh=> xm5^-_=>&_;C"Ջl$mYӒ_ l}s̳7%NwN\!ϻKg%dzv?ot"ȣaV7Du ɇ|{q3Μ׈wT\_G}BrwOo0';ڋ[z&lCj8L1ʚ@'r_,YyҴ#XǺg%xKv߁R|oAlv=Fͨ3g3玙G'+zfeD|6 ވ>&W '10m9g,M|<odnQzC+f^}^F#3Pu+BPw"Y[37$kxJ1rSG3r w6RI"U|O^bi}3۲<%; 6u9}X(ǚ`/9/rGz7LdqyB)Lc6䙦dAc3XRRy8r~+881on':\}ͬ36ͬmf=>xX} 6:vrB UUޝBVb]M<4Ubsh ůן";#qj]ؽQ=eo0Nl`ӑmHz1u&z7,3u{f׌iüxKG}?}!rm{?ǺVZfSm,nU3-yX7Yo<*{@^Z}Au9ߖ#Zv4x.sD9*'b“W:W>G>dh;c;t^Y ]g >֋d|-!OeyScLpWX~'j?I>&Ї.)k& R`qN>ppӈMߑAZ@|Uޯ S=&>5ey2i#xmN-|,{?}m1fa$ƍ2#k_z<)h$7|3rJԔH aN^:+*4jMEyܫvjĹ7*9o C^^)6{8%kwkq[?(b5 o&Uf{~Z5[rUgcyÜk܅ gH&|CboӖs`!> ;RcaY4l&xO3yCWI.o\VSįfx:c 'Ծϣ$$>MkUɷnL|#S1}ߗ88l}C6O}}5d/c.=?{[cy9dqzƹm8~$T݅Cx|1MK缦Y0 Cn9ggn5D-En}?Dkħ[߱BwSB0s-ѧ,;ٯYBex*:"ߟolԷ1NY}kt䐫mHsFI+ ^2SLl)RRψT;%lEގ3;:rnYe-B v&t'5F;|ƨi^ yj^Y/K@Oj0Cb};{IpkXrƷ5|7ԇa5FMXA-OBS!笖Z^`|+7Q_Е΄3sY!9SEs:,Y.`yֆ?5Y7r'x}TqeSF8  e-d4[^O¹e|oлcYȺd%1];DzxW,Z&3Dif5]U+VxXRݣSJ= O/$"j#㆏_1j>XĘt?PM$|m,~䘾 :'IL5rˁR[sK-~JY_a|@GCWZq cG%E΃,QWg y򥨵B ?-:\9Ӿ%+$~S=fL"GMα69 l9OAMsѠalXbHaK'I]r‡0htCzf`ae] x=~~ka-'f7nC9\1/q|yOSwunW{e->]V۩T}Ut0Z̕w:{;{1dQ.^Y[ QkfjOPG:^)a."`Mmo:/z\49?D]!z2>U7qy׾&umxj_U_B-6,Y󡩣{AF5ڂ+QY1 ݍz(E3a ;dO4ζmoNyoA=7̃s%prmߤ]CT"&-jwe$]bābF^ Ur 79eÆ~'.pYE#;y\N"15YLN/qma3iwU)~L ¯\gx}{%tkžn;[<%:i'i}TqK(VZ0η5Y$'-4cmkǩ:G9mW8d|)?%qj5w6b#ZmNsỳ~wQoL}% :S=G{Ԙ+>TץN~6b9BOx9E9}Or/dސv#^j:j_WN;&wx4, !|=z0,s(;<Q$*zuE8zN~Z6&i:ovbVM ̬f-t.։|6jbb:30gi/1 3LF6>f9٣6!R'')_#3أ_/qg>gLnot^}_W/aSb&OWRy0~l4 XgGNR[y7 xrnw{?Um'5s H+_?J倛o )~zgY~o\-PgEEyva+s#^5uϜ,:[b,ۻ>,czTo؞%iҴ1V$o Nι+5bOt.cvy;>y"Mӏh,}ou ?L͆]׶l3<^)u'[aMMu٬P :໯!C.,|o_diy6Y!j8.^ǭ\aV峲SPuMPB.b5ӌ_KƜkM>Գ/WQz|u=pO$\яq:I{tƼaVGd:pU8ٟG*ub/ zKZG)BF+[ILI>cLok{/UM%?{ٟ'<%6qG27 uϔ}fWC3aXOA8xf g63ԏsh7j3S=HAcj WϭT}8]._YÖuE43dr>}H g ЏLWSP{S%7~'Sw|˳ WɱϼZl䙈0E~GvDոƹĥ+ZO%Goo%bV>)F,o8x\Rg:Q;V\#WuQWϬ~)ޘ'VZ8LnfʍʚuW!t φfsZ?Ϝ^/,3i>HMfye5E,Q5.cdk1$u0rvuf16'ǮkFGQJ]=ߺ7{Ż:/6xV||L\#Q|3̆OYel CO2w._A-cJ'ka"^z~[s;YFȯ=%ce?J|`ߓ>C;p \us~}ʴW:l\k\Z;Xo&~17/1(u| ::iۼT f/ų;M^}l~3ZුS`%~sVqK|:nYy=35 ʖctJby;Pwp<3kj*guL>'3Td:;N%1ӢziԯuUQs*ǿ3hS?GswGͬ]vqa?HUcy<nejb=`J39D5@ʌ6#ϻo3V'9MsagvUgИiNN`J F D'31xlq~Fo<_*>c9uO.'B #x0Mˢ1w۝Ԩ53Hk̄Vor/|y}&'}gstД[9&o57ʜw[R/ПuDf9m9BDc.P-o"]F?h8l9~=z^Ϩ:g v6הckr]*1h5dGۭȹw: dkt:KS3}ei_GJuƆ%sw*k"kks2ֻsʬ#9A'+S+7gCwu:{9pMgoU14kgt{g:h y{ 3Lhմy.icꍚcjx4{?Vc"Qp1 1>\b y=9`.4%w@/;U\|D0kqq;q^'Mۙ:ise!馵5>9xMq \f3@x߀|u彟)YFM`M8Ny1kq𨝽Qi>VZfB|Q9EfZ>78J κDkŏG{0j|W3ӑIj=~-\Ct[tfys)zF o7o853y:̹igR%9q^v0uN]nS췯@9_2=b1(׼X>k)KⳎVFS ,@g ):At}PJgP~1,{, Sk<`pڨV-ϩP?. 'c<Y?${T7 sG/c5o`:Jh<8H9W&z1ڱ11*9;IE_`<~9Tp^2QVK/yi 4}ny{j 0O#1O}:Ϭ~>v,h90yF~sxdn$P|И-wb^<&1a|ƀ};̿b_~>|jgUk j ɓ%ܡ&'~̣[eC/cIC5|l1=5VVl/׬N,fΜ.osiwV^:5NrM7-pNlgT3\xo1z #i\gSgMp%ܔfO3~b}y(ϲ\âO?$YӶsAC@::jA1: M19hݨ/ 5qoTU9@3T. |j:,?N,@PUWaӈ;XVwD\DYbwu>hoWbMNPp{fXvӌZ̿7Ӯlj/^\DWg/`3fQoh.6flz)l1M)qv6ģ{=z@LEW,c\ ggHJ6LV SQ9Cw|6eC|hƸ]c$?5hܑFTs/𚫍/svvg-VӮ' R]7Wc753WkӶ0v(& MI{~_1)8γ ׉s/Ok^0g]Ac7OCf-h!sGu#߯߸~_2̳M~wӦ_wZ̠{v6Mf n6?"0>Y/ˆzO:-7p <ӆǤȡdw7qnfeL7<{rTgdL-3Qy37kDcKr C94<3bgk{`d"gzm}bӪs:lh볞x)йF;>֌4X2\}|M} N{#:6Ś]Nf cQkWwq ~AYōsMy4m~%qo{L9:At ?lxAÛoX*1cnq렼:o8:krͧ5NVFgv6;zPPgyjOŧ^]c_?qa˽fygmQ%٪aʫϚNhsQinhUY]a},h瓌%Ny 4K;h`(>5Nu#%<ck*e3E[!SMszgqN!k \W5i\F}+mˬa@Vyv1&4?_-o.Xa:3Lv|f1Cl+6yX T6\b.P U/)w)r;2vƬI^k:G\giΧqh}Cy{:zA㤖h:?땔YO 2hG=ƺ=AC`ʞE6;a~ßmGKxXn{D1|ưA[qZrIl0hjss/W1nu&Q֩-^2!fq=SRN}E~fT +[Vo3s`OUsgx6]1=>䫅qb4Au̙kq55ŌZkxl)[M&e5OݳfU}aA4Wq`Ck2o{o_W]=mҍZhEP"9'.8Dm!32ʨ3ͨ3x6(J.&"N*jں:h;n (J.Yryνu㾲ݜ{y>Yji;^IET)ݟ,Jt1omKI=}$ujR+*i/Wr3BE~ bg;3ay۞cAgʞx&219*3W99kN^NQ[m]}f*zm#y{H/ᤖ~&i^=Pn@;xR(&|VSI߾KKB!x} 4dę!~K<{}0?侭,Y=~:c:.gh1L&t>p?UOcQDlxr_I{I[ _C]xU,Vl<>1{ xs* cqfWs ? yZb~fA2Fygcgo~9/D>)ٙǾF/oVd=sߕ1 z=>g=.Dc w>Nqvh~'ns[L-@A6\CZ^7^p!yᛱ?= ,tuW)} ߆d 3:Fnɐ{̷VVT>b*f:qI0;*'9:l(alOU?]I?g?BμdE8 Z}Lmθ%*_/94f*>b15ތ+,lga؀+yc^j @w&\^+V&o9F'^ү67yU*)d3Q33<ͻ4Fåk ;KCԙo.m::Ț.υ>ryAFz s:J!kwpϾI_il`6:n_k^ ?½s/OZ˷~~5:Md%ME {b aYo=cIs{4^_mVsUqa~6lb%dN72=_Tڇ gsTa=WOqEW}Y|'~ -KBl=D؃a_9LDip B~2"E{ћG,B@~:d\U>”d5l!嫚ۭҢKK&7g_>lv8j![o>يBA_&+lo^9 ]; ;y5)c|e'4}gl2*Mq=O:9qO>vɆ-Ў!kr*u! 7Ki/MʋY>y9|j馼No1U q҈R#mm?p}pϗ8z9ORB5+cr^-O$7nU59WJ^ M?9.<&# bJ\%=ᒘmm O>ͺ6c{A[MoxyZF>‚&w{oNU'xXqfu,3d&W^jTv|P>KBφ  x_ `/{jzxwV8t8c2odVkfgƄٮJBƟO&m83w%^?pcnyA%dz#6LǪ]ӚXM|!xPkce\WKNȡ )Z`Kv]No$T|NZt^%V=ZsL5Z}kx}[!;(ϓN~ K%c1W.":^$i39 mS:Ylc!--;%f\e9#_\W>s0{nP!M_;o6N}rܵm?GT %aV͸׸Tu9awѾ?V8AsjX3~vVbFTKo 1_7VÛl=Z}>:fNxC33 ι^p wG]#~/k'/`Ne} h\Xwx?\ v۳e?#W 7Ao \sxΚxW3xN2ق}qK3=>EAýI=D_xybk|D܆:׽&>*):cP׻3VC֏s |-({'o#~a.嬄EAK9mr|ق2A!I.}KOõ"ɈVWHN+tZ`R"ްWNkV$_Ögd*?Uj[& >w8\uOPqV>q%5~#Sq$%fm8jr5833q‹y[w*5g|Ot?:ɯVO< ڣHO SQzJ_*K3{@/\-*v#=ms:iW= ]+x^24q TO'8K;4ewblKYe\|ͮ(Nuuem<@Gz=U\o8/HvuZ/5ćUӟ'x._ m=;S~sa}BNn-mG^tM|WCUT]qמP=gpǫ*[wK585QuŅHnqv`o-_;:: eǺga VfՇ3gRNq/_ qb[[ ~0L?KRG>r|o g>8D[Wq7gF|}>g˾Uxv.qk yLN]OZ >-DŽj9&.ֹf3Ysp@mC..as4XC.Ɩ6I0.`ކVQc{sTߓT>C69ZZ~gmBJ _ p6)p&+䄕,ɚ>tNaelIOV36 oz#+$/9$}iý~g:|ntcҟݠ\A]XMPʂk+n{=XϊXa^*Ν}z#˳E}!$sٌ( qga?'um쉜_L-}^ߑ_Y|web\guL0b编Sŏ4l_ ˔l 6wA}lK59cmq ?Z?DDL3|>;:T֕g:&6rv/;jӻb$Cʄ9!N4庽)c! x]kub|kW)lTK72|<^z֧ sVogX|1^8Kyҷ' E'照Wz?*`{/ܪՏ^]/&MD'&w/7(/zEOzrEyG|R?銩i!_3.<KO_KF1I^ܫWe|^y'$nn ⽸c8/?;/NE؈͑N[O:~? r _?U;2'ړ#ZM0r<̋ߊ{:*s*/FZkrΥtg.N\>s<Ƹ*?3?qn->q*{ɬ >^~O]/YP)"DLxG_Ψۇo*\x]ORN._UY~yZz,?+NJ?}`q^A/ } rK#&dFgۤDN9icgqgbenyʲj92S#`>AqoA?ޞZ9k3v跞Dwqh7{3Oo|]^+.okObyvIg~<+1_?tw9%3bgp;x"j43qc{^ŧ&9zLȧbc ck`]3qNSaW2ssWҗ%u@?C^+))MvynT93Zoy$ d&"bg~fͿgcS_QHˈ4V{ ϪY~gl`܏=~O_=bY\~_WZ{2SԔm]^:C^rx߅rTCUZM^6C9!QV~m5=[{x_ %؅V1RD,Veg{xǵ9op)Ζ_BQrg@o^վ^3 !v?| 7nQ?׸c)oGg(u%<]:7@5ĞWa ={0f/YY2ykN>} /։sĵ[]g!Șd򎕴qKn [37ӡ9=kfĭ9L!@:=믰d~_v19/!/;qhd |#CQ{w@O*Yt{u`-Lr_ƾ$fly`8/{W}5OWVKe_* L|m'VߠݾG~'OIYlKG;8I=c)69b5֧'WWG$^sjS~G6l<|2# vgp\wL"e_5+8G,!Euw#qN:P/wZqWU1ָFs ?⽧*^+`-zB7޻My|X^RkJFpbY͚SLi!>Keyv_M/lٜ?sڑZ°`~وuWL|o)$mNZ4zk,lwA־"/WS ^r9ȳM"t /ڊT{<2!wu=iJ}'yKw^@CFv,݂fm8nuǺK_UFf;cmej KgM'J-f^<eVf~ ڠ. ׬r=-+L7jzLq?׾$WUl>|q}R9N꽼@u kSm-h^@~A-{3~N.x&aϚy@}>ߡ> o/|da|Ö2?3dlΐ\ T-gq#wοyl6>TϨW#X؞)Κ~~m.߸ ~Dz/@{w]Bkz0Ҟ*iα|:}i;7{U݌u~Wc9񃈳We2|j{AXSgWcs𕽧[O˙|Z{ݶj^}LXj;KBOl@lsy__Ŭdz.1{_`c=ܻBoixm[y4x?q'hi 邟SV?Aܿ}y9BN vMVt^qZ< >z;uf_;{y.99]/%1mMdw^#C'v}=u8uNKϊ7C ɖ% zO0+]Pi_6aj_3y%Jy=&+z;U6vcsgu7%>u0uwMl >F{hsDK]>P,Hdh3\%?kpƕ6+y@.`1 uq XSq]ʋ\H ;Y6ء#-25?}jոFC_n*&Xwǧ8jǿ9<0ە3_yǓGXCyUO(^ ވk0g?{Ơ[#sy^ێ-ޗ`J oydĵލkdzoe׶R}эC-%l3Gq.䧦Z*j|;W[|9g>Vp]l5fFmɶggQ5DyV,;uz1|=Jb/>Js9c*n Jجd][DztEތk;x/M(C?U_Iw.˱ČS2u|.FO@/KKTø0be5.Q ÷xuZggxaRލa+Zì5{۫c ÉffNjJd:v:cNnfx/P,˞A7lr'ÖYSml^*tVc]qq sgJק# YmdoltljĽy98# {.4Cĵߏri,ȏ0惗IOl.胱݆# =QS>=@EؓT/O.,b V M\=RwYÈ;]~>[ɣx3֊klƳ~;9Y(q}~ 8V0&,]+\O2ϋgx嵱a kKώ|XHOm`+NֈWqcl ˚s=>w(If,,lͭx@lٴO& {}9t/np&+ZVnҙZi@:w@mnFEFC#qRN+SD<@-e>m]Rٺr:LzS|[ȁ/Q%ا*wFcGoF]EߏjoI^g[J*S3v滳m8jvR\ϯԱOo7ǬwvJl 8Lй%i`^=j5āKv[/ Ukcn Am/Yu:c|;2XsX\Ě~yS‚//U !t{XszE^y'GKs2G`&Cg5rӑklooE6wa}{z_S,#c29WU1 TM󔴁[՟Rߚ1}kJr@Y/|qgbg'9迀 zsb%岾eӖC~{ >6cYq-.=Kg5Q| ߍ=OJj*Zʅ|kt*ЏV¶ta sӥ]Oj̷daCi0_^_Y5e1GK[SL;SN3 9Xk俑.<_O~as\ [llNN#r&ۖl,޾9Eȍ9n>O!zCsw-U9eiuŜ|?}ŵOހ_\Zj.+G\}٩JH=";vb[g>%ii ^Q K{0^Wsy|y ϶6,ysЉ;'/U/Q>!DMRaЬlG@|хϯgo;L)_ޡ]Q{8_KNSt|dܦY.;sk+7T\sI#demsuxUNKճ*NKO8w ] m:o3Ȱ`>͘[\spn4k664c@c8C=@u g>8 {!og *8S^ y^㣣aՓW؁=^KڔcG_ ;Δ_(ƹ a8w_Q_O]#><ט/?~ʪs,473̾!3o!z)>#I^[5Ͳ2~lYճsUN-JޢةUscLJw8Xd2fg<[nmuL4O皜> [} pƞ[N%y.*+Y͈9ϑFTeF7a}Mܢ~c]~ׯ} }bFue5gPڡgm̚jV؏qnMHgηEg=G'1{q+gW¸MIJV6%vy8Ib--iQn꽬g{8˺P?}Q5l ԃĚbڗT5s |U9ٲƛ!i׼Gs"EӜ%Fzy³VG2/ cf|}QÛ! BRSD-I[<7v4]^ZM~bM( b|/fnV rpZ8\58qrrrYy"d\ʳ՟ڦ%k5 Qo8=OG0_ރCz(cb,.1wBiW}(x_.C5ٖoTN`c.fcpכ=Ӈ߽{9} 8%l7ir-]H1gqCÐ{T/M1gudQń9"-1l1N^RVD]/vr^XNA[jg%밶M]wꁮ5v:d8O-h 9|B=lݚ-`~<βpWVMt)kN؈spw <ϸ{Tڨ}-]_rRŞgαۼok%? ] |B rc`.=91νMu0=^oK챚Q_cUXAv jf<]x^֌˭c/#XǼ&~p-/OQ7//";Gk3K)pƠ :WXl),,NvJfm{ح2΀]r T؇څgOc Xo`ω/y|nDȘWYʅ>m1,q^{tyT} Θ٬I촘31yؠjo^ ;|W@w' 1_ؒpڐ6K9>!ߋu/YC%|px݉Rs#UՃgK<.&>m՗zLS {+3fݡ.OD˅PS‡qn Ʃp|鋡Ӹ ~1}K?.u?Rsu8qcg~ B"_ =*o>N.y&UP=<1}uUͬ{-~b' Ɨ5ǰ'*?2~?Ι(Փ>SEey~Ҍd+3eĢA>pj/z}sEOwiwCz.c(/(F?v.n1 6$u1ӟiyg+|7إ\V5ʩ}tz#OWoTN-hǩcf-hI7\5PWús*乨^o@??>Ӝ"m" O[Y5ҹȸ Mzm]ƃʋ`QI8 R}p\jQCKVMߍH,jW^zrO}Q]}%V?{VggAY\1O4t^}Nƿ1 OS1taKק=;_J OrcEu S8׿P  a p IͥYwϩ:^H-_!OUCVQ{MyFʃ \x]}eJF6{N:On:_![l[Ka Zo8=_bM{R=gnNil#䈞8,N?aAņ6{zXr_6r a?hM]y5<粙q1Y,<9ՋfB|K3gaWuq^x3y\jҸzԌawU/aU#鿪%z+Jt.>WqcWLZ%‰kM2I}~Ԓx㜖96i瓭uI^,G\^4Do^rg-4jrF9\L3 Omx;|9OE7]qehUdtf7Bv%87BV;J)Ǘ+y!g-lsZJZЬ淭p*—#|.offͯ7{و?f#>f:vB7E͉ϝoC.eJpd8,{"rڬ>biYzw ׃Z">o!9 [C_=z& *ϹPz_r4'T3L߄ %Hr8[STJÌF5&&zkTQlҹ {PԬ b}+Oš~KƵ!!t:3] 8댧_ G %x[b:e=E0-ߺ/ =D-8Z[hu1'#XYľLTM^l}9 v \06#oC+mXl|yֶO`%:OnP}8=î=A\(v.|$7h;b˱ѥspzw+:ڤvf!/~Cj}LhFEqL;#XV/4gO}u;>3!@1fv0s#i5ߘ,̹|!YyCa?Y;ma<-;Zٱk}MLQT]T}Xm^ Y^+*.y%IΓ3vޭ8X5%ޙiWj !l2R`Mo,>EiAu9$[ ,ߩ($ߟ}q/v|+Tߡ3,u{;%x/m<2s?B|z,3q|׺݀n܉}z6 vjf*xs4XwHy4aL̳jU: Xo w}p'OdcnWrZA˅'yν-R=S=%,B,LX!݊ˌ? vly-fm'd7 [`1z&xN}_X}M>|ab1Љz4S=dJ~͝([l=ʯAO BmE[Yw7C>ˠx83^YΆN%B}tdKd+ֹqLei+;(uO0yrꋲ١A7D \N'+wE0GS~wIg|)|htu>|I|j)V:b `aMϐUy4 ߬{ܩkli^95\g*7[ᶟ&bnP\(πlX?2~d{=d޻ޏb\E6rZ9+?.>9 ;ACwC^1ݏ}O9ٵ|ج^N#r^kuix?˿gt|\eQz{zbD5y;_[{ )͢55:NkM9t!6~ NֆՈ8K{[#S}lZqum;ul"ϻGď1:QV{krdќq^ )8O}%C~ը3`8d> 9O(l'q )x: |!?zhv7tcSUnT\/`#b:^;~3l+VחN>å? qW<RT>CݣʣV+཰~1َBƏWnFlf\5=QaO?| >'}>W1w5q[>_N5obmќvz(FnSM5ZOũC0db 6 oVۼo\{[CIgxccsԷ7Uqp>hkSwdwP qcĹkp3y$G% O#+*ؚ˔ x8'z::}֪.l r)Ueem;MY0bvFKYOpdu~v39fzRa>^ɺS=XQ2{Y./rW#FٳTJN։؍qF%Hk_>UA>}_/F|^Tܸ:Qw7af;zb ij-n+9ۅݹ,YcL`52!T菌:ad\V<]f|dYܯrV{k̡[[{l"W{ed}wUa_e3?Zo-i{zz8X,9YLW }oQ6vj Lo![8t^ {^6u\#'_Oc}4ݡ\D1uz}{799wz~b}9r^c@EN3aޫ/gsܑ >2G Q3qNo&ݥ8_Ǐ}nTc!jS\~:!.Tb1ͪwpx凵(vqQaOJg;K;Ww8Gf?a0ׅf^]fbZ{&(:GqoTOkKx9r~L;ئykVW]2wZs[LxOPUZL= q&jIEqo3{):2GE{2msѠ5R/eo}2ذ %|6dH|uZ,ڔ]gL[La38N'X.))YksQ y|@ܷӔ'7,s Zcc9wJvO~uBGG}_xumQ[V/OƫY:/j}p?Mݷ96vj 0+|&!'!xU{ߨ7q.Ht>rN`OX#PqPÔj 5h';| Ӷ3| fdf!;t ˾UwK]]xr̗Xt7(\{M4'GO8۲|zf]c^O9s7e9)JjqOwiy>n'9k(/o G .>#-݁x$+Kf4-q gqxV8~9A͇!Õӳn/v_}A'eCGw8jnM44-xj:F7g͆ucsd:GtQYNWiq"8 @|GbZΤ0^ҵ(m^VnkoSs*j5b1f~rϢ4[fh/583<}yg\~G:gȸ^ OUI_]h53-#{i '^swQCBOR_:19\xn[&א<ڜ|q'$muRr[T\1@dLYſ˧zkM[aOr]kcwejBc#Q3^=wy)f9>Qh9ͳݹ+Us7/jE|?hSM9gÃۯg,x^<͐ryC!h/齻$oSۢ{sܱ3eϟ,6ՎwC,>>f6,xOJ?t}+~Ì:=/V>ri؅W&jr<{|'gǴo +"]zf=3kdPl㌒GW{p|pQWLu/hhLs -?Ӈў*4G<66+kv|¡e=PTl’֌O{I)s@Ud&u?]r<|sXh2ې!^ס99+Qp2sA<& Yl9]!.aK /]Y\2qYVt^^y)[ ޫ!w=f wEi<99ua?az7g\lʗsC.s3>l?ö/z^y\D|@x q&#õzռ=㾻gsA{qTn<5kL\޵|'k`m:Ot3NBւT20.ck7,(V:SwVȟC6iؖK6 96ը/Qךuѯ{K8??ֿbnױ)IMYUx-W;'줚h;ckFt֬p{f6}\ޛǭ5;mmۺN,Q ¢~dn/k؃VfEs>r.~q^n<:k2u?z}]w7:T6m,2>mٌ֒TW`v_l֬Zج8 Ftck/yVڲs[=t֨[kE6{SA==p-lsY4k}Q3#ToCs:3lbѨ\টks{p5voݧ}զI'tg5f/5]=1}a]-=S˹6i3B-dO/oucag<Ǒol;!'$ْ#O(wkz~Z헌dc2ze[%vf3EyR npYx甎sT/{ۨk7@Lȉ .EYRb:8(߫ES4eSMDu%ՕsgtC39ÞSک&Z Cnk&}"yɻO[Zys6벷a |i!S/mjDy6aAS1#)ag~Ogf=(GY^"Ds֟i/̩޷E.kh'9Ѩ9ڠ6v i&=_4C̟7<?k;ΐ|De>v؈>#uTg!?/%۪X҈ۆ\[Ol~َzn>jnYcrs rfc> 8XM\Gx"E{6z5=g^U<1pdrsV1L˪5p:~tgI1,۬| =oFo|3Q7jEY( wgz#Ϟ>6U\Y|&:01~AIUĴb>۽]P[ssVhξS>gHgkhGd~U'TsX7Jiu{zףX'."^ϵxwQP>_qYSj rYYX .˷OD5A7&=dIgrcn/ ]c]˕WDU?ڽeߺYKIh{';=V)Ew4gv h\>ag?V*>CQټr_wVs]~}m3,J=N9YǢYmU3XӺ^UU3Vuu鹺n}׈W+/1pQQa[NʟϠmq!洆m^+;"̹jN\v^k3G57|%ze?ƕ78'VS61ߣ"c@z#^;3"[=U,KN~{ld6X/R]X1>흺ΆCQʾFNęÜx7byVx?FY{6ms"5\Ŗgc/iYNlY_<.x]ù([*GWk󱺂ݧa,[Z"=!}9w_Kerg6=+v)۶zl;dכw{N,6>ټ08,2=(csöe$S Wu˽gjۣQݯpk)7|Lz`5V;dWժY닚YSQVoY)7^o;nǼ%|b˧ngbsו;l#idz]},^Vm؄[y/htboy1 -7:KzZfShkVvPD:}֒:.mA{碽,,wi9wU]sX,sVd6;bvZm(FmbV:s4c3NU9iGx'1cSE%ۗ%cwxwDJ\ߩ}-Mۜ/zΆ|y}rC|t<eYzZxAq$c[y{3_8jl*qdszqs&R ԧ,v5 mj}^2~6,]14;wLELþ}"gX6e_6la5C'{ Z^32L3׈gO3Z6<31 $-?ן?,C1)XS{ՃZqJzn[ 5A'ͼ^Ȣ|i%h:ܮ>f~S!6==Y-hZIeLD'>fe'S$Mdx?Bp$ɕKP/ɗ~%~>_ [~7)=;a,nZ3Z`\CgsXsMM~|h{by*#cڽK?kX:d\9y,'qkSb1/g^Ӻ@= "Ia@1M~>gO @PrGwOīC9^~ o㽟!,ngq/u[Bژ^T۬ϘdJ##35*jEI-b2ʳaNՐoj`a!,?|,g}s@(~sztEų?-ڇ4]Ӝq8zZ^|GuFȴzPZ"'>a禢sp9kD|7>'|'h?ܯ?.ݘSGܯdpY?inEq}/a_brOLjf5ay'#FM^.Wåuq%9}Żqx9}fL^Tgz!f,S7qxƜX-gk9[Ν 2w_B(W@ߓpmPߴ7f|ncyZ>hΝ"F֛}LY^lilfs^Sf[W3$6Wol>ċDI~V<&aG]QAݽ@<&7"~39XYY-Eyw`}HĔAf{;'8X%?xEAϙ _|q_ZLmYpC0 [ >ˆNr0Y1/ }-IMχM8Xbb$Sf>G"d)Cx!^b]b sܩfSڃai!dB '?CƿGx҆s8ъσ=HAO{|ZV=zgjjR5)GGeh6<K&YM '_M qF6o_UQ89Kg=wqN<Wnt#eC>|F/ a&2 W&ݜ,cyًjiD㩨'}rޣă7:EYOl׳<ۇx~)Dֻ 9y=vV!z!0.(ؼ%ymU;>j"q>n_H={ >U>bCb|co$p\G ϙg03տg\s#p?&?sCYW~gz[iq_#>ai &&<99X0 g:ȳ)!W>p/!YH&ɓ|;& _<8[[Ш.YEr}%%Y d|Tg.,d8~[=g b:zԓ2+朝o3QӜ 0(R`nW; |u;|;'紧/KOw 7}\~%6wۅ Z,ȵAnmpxS oq6Lє&t/'2>?*;GL/&a~{ :zMT$>}:Y}/8QoeuM >e5|KB?uSx,~wx)t 9k$'xI+%Se3Oyb.s C<:l?= ÷Zϓ -G包zHVa }{}`SOկVSFv+Sy<45<Ј,'V햣 Kx3X1<_/C[3έCm"U17M+~"߅s(? g,_^<7%wo8,Z}[}/"B H3UwF\/NիʎG`uϩWhc4\@և?(:3xGƅ܆]=M9|x ׏³'rL$qNg3iZ؝;ς<.Voܟ{bk.8^S6\Q>1eVXaCLOÇτplO!?gWR(߈y3lmW,ք.wb:3M,u(6z19|a --A~8{w+E)/Gr"=ߓB|}<~&6ƽ3o##m*1Ӕ y ]fxvs_=UA<'9_O>w oj# 9M&n]9y->lFZ9S_y e;z9I_33.nlzqC1v( ^({8*}[Kw$jTH+(hz$8UЭiL+J7niLuQg .c20n !IU}[魺ֹ{<¨<7I^߇?YSW)6O? yafx[S~نޢM*œ߼1!73ު B4- U9pC8zWG^;x(q/ E*G 0({l{&wDɧ^qxO٫rţCRW5pȅ8KYUXlAqo>?woS<k)MVSM/ظ~O7䀿L647BFWU̐#Wb A^ۄmM~jʾ+%g9AFa[qWwoK/E^*rre/{y:_~ 93΅k gQU_szղ`%.Ëb}vS},IV~pv_&͗.@|y,*w'6/Eȳƒg?\jRyW3!F[u?Bc{ˏiޅ__-xy?i,6>ݥyqDŽȟ߯951.k6n%gdlu 2G0{_wng?`[43Uu= u&_8a.rAޮI!0ooͅ u̧ %j[k!2poF8ed]3ևgds+6>[fEF?T͉{<ܼQ7;U9/S.Rt;`矲ǠNLo5y5Sq&a Jb[]u}r{څJvN9tSrq>y^I Y~𴏦7ܦcEsG+el>1(wx-@a o3c/*s/ 'k~=*3gN} ːwYeވ3ke_Ńs5;&G|֝nzxtcn#j5r⵻rac̬[NݛwxF5_,^L.<[6$\{c%M=I? SxK`+. Y2.MV@כC5b@6kxp׋"otw'X~lX }~PVˠS9߅5v}ByYKʹ=BQ^Ƌ+ciN g#xVΐ 8~;kO&ƚ9˿;qEƫ387뿔!7sU ޟfOL|od8 &L\S%ю,9#7"ŕYPϓm9snV# r2KSN0o_*2UsSf\l0[=^eM>hsL&INC>a kfp[|Bx:WHA<6 >6f<~jcptqoWod.]=mЭ]{/j55(3@޵`oS,;=ʥ2f oO3CdN]#SߵŒz܇M5QwA>P=mާ5I(,|͏9W5/ދp;g?Prdr{4[ToHq3Ç >p|9yn;Zq?F\.xXq-k36?y:eĬczdW'kčdmWO9o6'S?x3ƶ` ,Y>9u bہ?M<,]{o_rEِ7^ŹW'VyȬ˿ d<g8%s]Ur|K:Fz^}I!O^d|׾~ g 1#ڰY`Y]}@r~{p { _K{!ǰgS0vjvZU{L3E.0>2@.CoNӻq?o`} o]$\#ܢx9#7,gS;[Fh1OGcR5/LGkMCɷ`_d%aS*I](f}>Hf5;4bݡ.m~yD;/hv#?G}+lt YyGbK=!͐eF}'cmR>1hzr6pͶu5+^Mjq@7#n@l.[A0맟.z;='a݊o͇_g~9Jނf/9c<^3sIz,e@J\:m<&=0,ͫKʳp;tuD{qNvAq >D?2LBOy,@UxV{/w;"_?a<^;\g(&WL:ڄX6=8ox>sы,_z գ_:\i]GfrZă:4>8f8Er9#`w'4cYI{Ys>鍸"癹3d1s~5lk='!;Oiq]əSC&=ĵ5 Y#W/@ >w\\>QM_}NJk}= ?_Y/frw8!N6Y=,<=Ƚ_} 9OrlznE,}gcW'M?g߾)i}O&=xs1[H#koT& 5\t@~-G8z횿.,R!"s0US=][l{v_||og^oM41ޢ!/n9p+Z cwZ [i| k6S/{f=]~qȿMsH^V1<*y&p/BS@5Fώ  (8sA\%oVlKumqVsB~oA1k!;N^AWao~.ḵ*6,?G^$8L{x{F10T*ݧ&UI>1eyyZr+;{s=Η>T*!s|唑t@—55@g58cI|$뤯>d{q2[^Ҥ|/ ^[hqң?cpkv6v+~4vBҞp*S<+DlUx2X1Y Ug.0iN:8:ٸc>3A*c]fj'ʇ:'&gBl~r51[UROP_ M~'dHda콐љÁ9x;Q>^s88!94[A_9a*pr~[{Ԫ]73\b8hoQ=X}X:cT Cάg¸]H5\v{$փ^8(^z<)hs]:Xx=>ӟ=|j]Uc{#YUK5;>y?uy"/\r:%;q`;aϋ:V=/>wX5q=O$f(pȇp^y;FGXa.tY+>M5ɽ%Y] Kw-lOqqع  4~Rx]y"ܕ;] yQG+#&ENs`^|k`g3|ŠbchG-κV܉nuqXrʴ99L;JWoTTψg/~[̦5>o).հYQzx8}޹﯐KI͖s;T߮\}f? }(/>gc; ';qm$vyaݎ;vk92{qЌ /"f>Zʻbl!cN8S5[EN3kq4wB? %^om>f_SܳOKvTS''þ5ݩ*gkJGN3'&]`5~9W~nObw 5'NEqL[-(٠pko+Bc<++h{~ 8U.z׵\|pEqDP̨o]b;mi.|lO5y[,M?z(8szvm󮀽 v|{ Q&ȱ)QsīU:xm~=]mB>Qp4}BTeZ'< f,}-IqYk_1=1>/cx4_EڊX}@KC[]r;_{q>~SI{8+?y>]YgU[W%,߱(| L\751sۜƟ5jzDS Z9'~H>)s 9 w dUl=qjZ~QU߸ҳ+wJ!|[{BC^cuq W8Wy"p]S7" < aسt uDAԌŶ9ug9o|f l~03X1yISKk6nL1LDŽdK=Ź!.Ň%a2O)1s%Yab!pڳ].rp™<Αͤt$6SoeF݅3 LޮEᄍ\(&\ K7k׻- za~6oxq5ǾbBoS*.vnZ_#nܤkVogkNp{s=1%#|~ܦyU+^fsqI:v{ď`}x o+PkجI7n2O#h-@G VL3 g?sS!6DLьagߊq9i%kN&Pd{|A=\+w'3u(o|1 3^k^?_$S|~>\ Rp/~\_c)AWmutf>_ZB\fZaX,!cYoy:0'99כ)ߥٖV3^&~ \=p]޿s0_p3_Hl|+iQv9TMl^yzZ9r.=6˃D崷| ~V\]vEYsWbK%lKp'/[ 7K,XHE<8KWU^DܭC^p|qǘxmgӌwx d-?ϸ|ơmト3ãAH#p(5Ɠ@ƬS9ytq|.^L(T6O NU=.bΊ%/thh*\[d qXiG2=8">" ۯ'oB>| srFv +%b؞]nw.';{ 6@YY\z>y;IAkJRzEM;ߏ~{wOF;b>$O#W'<.Y//iRcV.Χ=]6[~ˏM_+>}4sߥT `^'=y5MZs̥'BG-|ּsiI9PT}_=1dwp_'ݚq$Q:rʹ0]s6j1s}5!f~B?- }mg?,ANؗc$W٪̿ G >񴘻DsA.c)8bۛkL[LQSozԓoMgnUaQ"^FyaFݯ<9Odk}6|ǣ#',oOuiFEalɽxo~f6#jy&KI4l{9LV^ȾrIea7). X便s{ wf<^E#J'3'͝~͸3e~g/#6i-eƖ[d/kXQʢbbf˪8:;ۄe٪ݹol_b瞉9S߂ۅ1WԼ61X{ n` ]W^<&?;qL7ێcÈol˜# ̓?+nN8;q4cwzJ puE?EliDUTzFNRI`qfe;ĆwbfrARRR?{i|2p/;KSݿ~ kU*{ƚcb@|N#8[߀<_iZ_ Ì./3mqF41_ONs7u#gެV.| d\1ϊ>Țß?&yqSglvrg~^{;|$ 1j#(_LˣVAܰHsUmqݪG,2M_ Y+nV1֫˸UmXR1ziժu2'G,Тn\sJҟ6A>wΤ/Y;q,%6018dqx7Oc:Wcr\K=Z|'uEޓkeîʑ͌a榪5߁_юOgߢj"&)kDzbq4sUxr@L4K7VWDsEAkfw%f}ÝPyqͷ ԜȂtݪ;~IlݿRxj4[72IXw=cϫߋ/Y<\ OqV?˭¸=݈2zy98{*>\ILCk\cη6*69L Ysj#Az񸨺^X:~Az-yO l㸖>88:T.ɗCwOmjQs/d-!x5ؤvT<%#pXmx(Kx)9[ڧhFբ 35dz|6+h͐>B+LEՁ")"O"f܋\49 doV ϰѭ3*`;]oV biqϪ?=aUXDZqNhŹdl:Z{]{s$ -@o rBՅi .,/zl:;~ {9<ܔ̔?!v*rg=Uc§.KYㆲxc6aNf'߰E߆#;yHP&|wJK|S4q0΅/.o*4y&;l!GΞO# I90Q(,rK'8^f;A^kbKӹS}w$N سͥco{r'j2담mxwg_}8\Nkco%oS9-^zgdip~ŝ;U_:^vNgw *W*ݤ/{- |qE Gg}pmia okԕ΃?.?źB=p^GREߩYID5Gpvo\dfT;w|D a7RUd Iw [a΅?{y}*]|Cjw9V!ѿe̠ʍSafVlǰ? @SI8~?E%7).a9/s=Io\4iQ[q=9z\<Γ0~{&VkQkpo¯o3V/X ,9{z"`%W[3wso(͔4kVlX9r#>>f~n/ ls;0Rl{!Oݣ=O$ $mۙMHU#K&pd_f]^3k4Y}ç0M̌k^)qΨScuwe}oj;l_quM+8wrM u^X^Й^0glbAy9r.}rmk6E?[gU6S3Ukbb"Lqoܑ.(NMA6#2hꂍL.]E孓9OkvFɮR}@C$w]ܦe=L NȌ;Um`.sܧ~Sw35^ٵp'flݢ|c9gS=%|rEl;-XThc9b ؽ=*Y#qKr':7NQskwЂx&Tם8M }[*[1N2(~ Ze3،IwԘ5;nyםΗ+2N42~cD &Xs\8/: 4I/Tg[|dP} b3@if~\#ك)'3^%)cdq$Q.rNޖ`cCלLDuHW0鉌ϰ~ol=|np;7; PkƎW͡I#mALҬyћs$.b..6g}ȇr58ﭐ t$c~z>ך<ʑqNvl|؂s}N?j&jXKk?"^Hs2~\}zE=ͭZWnVYM<ƓJ10qLsmP\{Ɠ uw=?{KUsⲢpr;K |+|(x^֬D^=ζވ=2Ӛ,+܏jn8ނcK/CwlwKx}Yǣn{Ǣgz_nÀK}& 5$> lYeƀ 68Vv7)&LU{_Md6`99ql̥kG=9 XG!>pTM$۰YI9h;-f1zdQF9tḢn=5l&{Uvsd\Ř2-1vOgk߃=4+nX =ٻa:w@gs;=qw0>i!#=  sMzZ;'X;}S0\*mug*oge3%)(H6q} l\fa]Dƽ19T> S:u)obIٗf9ڏ8-+.kd}Dr1mu}sjE7,xjAveBmdl-]>$~G}iUܴSgUq wvڥNh;ų`9q/r>^>Mp3xoykMc,j7tݯ31۩}o}{ 9ͩp}qw;Xب:&by%T<[p{ )Zd0g]7ywDrۚSk$j'3eEfǢf2|] ϒjkΕyxUb㾵x|cQ,U\݊ cN l:}3ț v>Q=e^l^bbiVd_ɕɎ }[|?êJ}ίOFx:03r!'Nn״G;"_U&B9T,\1|L|XE5Z6Ϊ.P-\LYH?n+WmJQL(oخ3M٧U6rrQ.e}vO/yM{7W'~vݞZ|hCoZ͞xlcmlnjpw*ެ*:fݬPayZVp 9<_P ^ëߘӬ`}0V&E>::uZ5^9-{G3GCV˩DVova0#qwD e-Q3`ziIs౞6ei>],ݩ)yސhmR~/=n#ݰjZɬsR=&Y[]amhw;;絲U9*8<:YsdvH9rkY~)6-LOۨAdgtyod,wrCLy=Qf ⚮-)konk*;XU}qa!tr>婳 ;1tK=\svJU_3ܢiC6lY8 GEv~g?x\lg+j#IU󮋶]v?(`yʔjf)cn 7pF@vHVܪ8 _6*[|#k Ʒ\UײycRMS.LoM,Kݸwsg&]o6#_7D ӊrǣhg,D~1C|P 'f̦WRA0G6FY 7{6,۩=TÖ:H1Y%|i-^G7,TbI3oOIUg&^|mb4sԈ>{f2wk\O'YjLwkQ_O9‚zMa<[uXf2Q֦`ޞ,3-S|ú\lzA9IFYЈrwj]7gOf3qK.8dJ3^f?)y1'7aAᏳ9/9m1)f{=[%·n HU~Ki*xrn/_=gy ۠)Fjn3F=b#Ǣl|-f]ϧݘǡۼ6y6a9i{aDFe{Nȯct:Àttzߢ?K+4 L /YTj+T7SLD7893b|B3VW3ZӌEc^;.=_q,Gty׵$ZBz\^[MrBk0vz.gEu>TM W\msK oؗnݎƿY)fa56ߦE1Y~#ԛ1.i^'}:Ƒz?c?pu_6e{C9Y^͎DY"~W8\^?H\G8wwLHo\O[V֤ަa\ ubNUq)_w)ͽoP9[^sy6C:eWhs^/0ןcQY<汔x,2H޿û<)=neqtMq{u VfNz?,l4Xm`\9FךZ=ӀYuk ?ܪ^3e@,%~oz|ɶQ0,wv6ӖX erc_nXWR|3e9i9G6>eأ6װ]3MSKUdtIv&ƢϺTׄ9eZg^6 G2[f/&fű|VzdX|?LjFmnnu[T׊I,oَuzlUuRQ\]3zkN[˖y/|Bڼ6hbaT.WU_ds=Q6nf#r^WSn&%λZ|o*uRsj}r,zv&DٞX-)sc^~ɩ?Cs&b,1mnd\KEQ 5x?T Ü| <~D֣ke1ʸzy'^o;%c.o'gLR{> #Owgo΍閩~2{lvd j}7Im>V)DVc?yZdfU*v*6?lVc }erbg`{?wfG]_i9no0h %{z(Y(wRKN]H'\9$x|!>k^ |ůyVR8wRQp ݪӾx-~[uINlyֻ7]a llj>Kj: t;ݾlfߌ{se@n5rMѤVn- %M{|}{Y >?>681!\{Cz*IQIXkT'2~HR ?KX›?ُ{sa 's鑸YF5?"=u]Zf)~dڟ/[EFf=ͭ[V O6,` L#q4ݷX# ^'9?+rxXGی^ _I:‹gK5%.\„U0̤8Ȗ'P>/ s ܟG  /fNrոi]̦n|^cYMGOQ51#/~#lV^gy=cmoWfΊVלpz8rg~3Imj9l@NKV ˞X/;~9drMBBxk.Q};^"^ǢgnȽAxD pM\ z_i8k*fnohϮvy`CW]Gݺ,s_T}ȻHU㱫foq_`đ%T7lަpdK{[R>x3Zls۾gWmjof, k{Yf{*?yi](ג!߇\zʵRad60d?yumӻi= ߾[q絆l.l˾[~g@u9ˆsrm\Co1L^;ipf~-ۢs˚ʸlTueH5\ -'28' +i6 td=Ƞ>mI)_ѿz'#fXd{\I< ekY>I,Asl][ ^fN;0^=&yoۅMOUZ+ OQ]<_<ݕQ1JyQ{6ӯXdw[LDVk^rl1gַ$Y]1k{>\篓K-tr=He1m&y\DLI!pψm1\kG|<>l{X < r$Y6#lJΉɧù 3Ё䈀5.yKKptjh;&C^rܐj=Ojr %WOD!dةe[5~?/ ۶5>}NR8KHyS?K3&Zz^i/292~ Egku-%q6 G#^!,R+mѦ`K{NƂ|&}Ag-S/ E(݈qNLp^c|ۨ״y X"e~F6|X}d7O x|yw-oؠ~EM=ނ'.:L3@nK(>d{ߜ$Ʌ< qN,U/mO,(rc;-d(] Û&}&wX|9HW|۩n1wbbB4}Xc/Ô;ˇSE;.:ݰlNtsD>'D;kp D-=2y4d4Os:gę0~:<76m^mɣ{FBZz}g|aB[nțJXFUalPv\-S{DpNn|"YKbO 5 c9qa*WL_? ޵,&/.R=`\e;q6'55pg숬'&G kY$q_)u,Fncy\B7gq> 4}>lbx:d 11q&7s :/.B|'5x?XA| q G;{&~xCd\^BwQ:SʡKґcٌ_7)ȗ_qqhDrձOD~yp-}&)r)OUoHSbWA^'᫐U10'4r) #l3l:q#-']}8%~>3!nwEGЯsוֹOW=ݻ#N|\ {wpd{^@:]r݇z}H}޿YcWlwu1/>.Ayrcaly3J<Ǒ]Sr$Ɲ*J#oҽ u^mgbb-鸧&ŕ%Tx1#嫄5L\|hMxv㋓yܛnŌ+!O-}z<^ĥsj޿:Vf374x-#x+NTU\/kXMVv#rvA/BOj ;?AzVK/½"7qWwAg[uPm%gQ tFF]b\9TXgMmx qjEoA\CNW4/ٻs?˜ xE7M _"&㞅Q؉u1IJXh&ls>{<{}{ME ܧYm,I+ g!-2KȍcV%Ջ>ȉcd>? lL|bɎ=r[Bd;S3EA6b΋ܧ^W*.\s(1NWZvpѣ8KU/>&`D嫒i,bb^\/6 y쒿;O=ƧGCuK|EnN㘻7rQvȓI˥G"'GAs)ɞ6CN8 rOkH37۱ :D=iGHuxZ/~W3[Uh4s9qg(ll>{r5[L+2Eb[?]9^Q7HL] dwNm<.#ң^.NL+^/Ãr]tFX9M̉a7*o%.TgKF_Z.⿙O ;$;ȫJT¬!3_RvV4ۿbaY<֨;%cyim㾲8X6xog]8g VQM:rEyxo/ϴ+Hwr<^"*?yߌi o NsSv69Ą?_מxO㔏3g!bęwOFKaȟc'ނm\qQ7[cƩ* l q9z;yQ.,F WoVx0* .-ƺoõS_$lsCx)Kݻ!!s9auGAϧ|^;>/x:^zr]_ uMu ;W/Z]h l,D C0_Ͻ%9l?A8X:՝ʡoؘa<}/ ~9!O$}CNg=OI -JLr Mug9Nik g8l+FSr-݄?ߓj||m\],<)&ۓ>0hsb<""!!>;ONf=.LyTvlrٱbl_ կGC<cbz>avg]En>)^g4!q^T /#B*ū_|Vӗx Nb,Y{#m^tߓl4 $\ 7fL.SNӵqrӜEM\95a`?^)-\H4!O kpODI}!sCʏS7fS-/ {*'fp@ZuiC'ͷťRK$'N4^ieNP_|^ yq|aũ|\Cз$A5j-#O.>:ץh$ʃOlCd{|m0b3ִ]/dO/:K.K .#LΎ0-ƼB5G 5>^g9bč7ݥbMx?R.M駐K=u"a+Vy)oIġh'ވ"`r1᪤I5%C&1Y`ZR[!Uxl 3C&;XlH5T:[c,?x 3rEaܰ3>&)'w^vb+#53'YQ f_t~\'L%wB?5s?zc*>j Q Y }D>MҾa\І..l?3\T5=cbI|;y,$6$Ve7YSNχǑ(e.sHt/V\"~5`䢥1~NT&e>r01>[\N3?loWhWOM^J<a-I ߜ97Xw {)gEa̹Ε|s5gEaGͣs8=>' _eX㙖|Y xYΖp MyśHre=7y\K=,Fl<нe_OAN9ݫq˾\ﵳ7J9G-ӽ)=IsCEŪ9 :߀:;ݎ]Xfmo?-ԥ$>6"bl=v99xAB_ܤ: 篔oc=n&MoɿguH+j|FPrzBL^%X͒Ϡ5XS9\0;qn+\W;Lz#2PݝV NljȄ܆K+`8J}mٚ OcqC=oB 0m;W2e.x1Oy>%mFA|ONn ( >'aߥu8;goS-3f9\^>U/5X<vjb;u-X;C:xN7t$u%le\_ncIcZyi 7}u 1>zOYcnx9->ߒXv#QqW+eߣ gJq#@{ y7c֘ނBy̴ !NBl'ф#:;'_3NgaC+fM{]GP {o14.7%t;2lϕ3'3a zc) ]7MeuJ_S_|zS촠|<unSg\iC~#z|}T>KHkֶCu=O-p6v;\ Њ!ʽ/ ^c.,.yjuW|S3(T ۡ<5rW>]KQ~?\?1;doW_XIwukxͷzNݬk҇gocHu9Zj6?vlW>+Ҭ õc9*q?ⵐR>OYUաfsg\־76|^߮&ͱd-;jZXb|uW[ćl&?ʌ_ 5Ⱥ ]xQ/si ooE~VK)VfM)L|JP5' wDL#v8v᳑ ~Gҿk,ߧ5]vx(6<4FB&u?|wb..MqzY8@1l▾zAƲ7|[+Im+*>}R&m_-u\^&UalEΜEpCchWi-Vy[ˌZ33 /| ~飚qoS-qg<#ŚDž!xK}6lcNvMjևel= uyQy16f佌Mf֛qȎ(n9Ϟtv{ \#y7oq$gk+-7xpޛUWz盧/ @XZEEQTFQ8:SŢiI jڍqIT0Q5QB^jyιU_]]U}>sΓk 8? 3Lߓu̳{ҖnwY`9m'*aijbG9gQmbaqTul94˜c,O]kCP<{ s>gbXcMwoxR{sF[1\.a+nX1UZOyr }|fz̘~$ٳcr&a+ɻSz8 6/NL^ "{pdݭ׾ 8}C}\2Y]Q;=lq< uyMlhoްY͌c5&Y c;qCmDm^wZ|E:CL֮::/̜l|[.0!4aS!g73-cxAl'5e xy\c;W,*G]&V\kjK*n#z,4 cUn q"0{ѥ}ν| ĪXd#~܍7 r+1m|=%Gx%rQr?Y8ݝ:0!yznKwr Ò7?qţHOϵxm[]+esv5]o:x^{elzIp8y q*N#~(N>'smKbۅLެձ܅9oDhc|<+pؓ<UE~gއ{87wBegikc71}QߟL'cd"sG􉜛?9vZ1o_8Fw֘{ | ۿ4c5?rPu`h5dq qlJơ>.9kTxlvmؿSTxZr|8'͸z#6^ab!/oeWxޏ7>->Jq?EUzk{k }!Υ;^MۓŸ".1]TǷbck:@bƚp_X>ܷdzz]DS|s0;x]YPq]>O*K3f1O0z ߷Au.|<Ĭ郪4+[mx1>cXgy@ yx4: ĚEOIj`rh+t.uTB€=9/-p!^8k>'lZ}/ CYKc&4lvx|㽸&yl"3RKd VQ@jG]7>ET'5*+wdkm_1kLf-} !c |qφl{athk%ԅ>8mK-$Ȅܦi/t7d]K_߯o69Qqi Бz{3C~^=\'?ݩxf9G g{x޳S] 'Z58^}#jǍ(l\8vZ6P fmT߀bgV,QҬ2 ߱ap^߉q2,g*|>,e|^. *ɎI^{ 4JHWyodžZBY#6ݫþ_\ˈj u7ȷ]ė/IgcD-:.=u9ebs%n>{Â" ֹ $1DQvt#fYc\/sx`)cU$?n!#~6㞟uGڇҾ"'31 {m¦L|-x{bS"OC?PFGWuDaE{ lxs>ba%Rŭ{ީ<֝ 9|H?Qe\zU%Sj?YwwOX_n2ᖿD\ y,`L>drBѮ#g?_3A![ܮ AG9ESCܻp}g9:N/WwKsJkQ;_ כO #8 SX~2x g]XCr7inqtQ,|Rk sɷa|{!1Ak|h:!Ymzo ā}U#N{4wS&{IEs8/E{3(mĶ|M( kWEŨ8Ms9SLdܓhLeԇ g۹*./bqe6 mT^07Yclc'x|֒^;c /y~KAÌW†?>sń쬟.-7A$CƫuwKQko=w:qs#+ct?M Jߩ~bIC^'Yq;Qw:.`y~R5)U[vO)#VPQy>7!Xs8ߌ(tMaXiSʘEqDؗQľDۡG(/<Ǣ_Q lg9LݤHj?m<9ܯ}^ΗjP+0N =Qlb6-CiªAېK7q-_d5>E޿6/W1/dqҐq~z- qTTCqث텐{-oD,xD8;=&>8c]l{-nZ rܐ gLMATXҎKKbۏq( T{TCQz_G%9^Ui#'w{bЖf>">{/ʬ$ٲ']m˩Z Ė_#Jz b8yiUنWħi?˩oZ"z^{/s1t|q|FOX='`h۔tAFt"ޭg=ۇyOKNRuqo)U"Ø­n'p?+_-5;3[pFH@˱&K 4w::o^K7l']njgSiS;S^7N!p\j }5Ia٘zh פRNqB!÷p林.|\q`5VIX½i~~K$}S*Yg\{d߳ӊˆ>_$ƥOOjҟmwJ+(g|SBRgC}s!ۻ!ЋqĽ¢pGfXk 16wǝ ҉`ZEZRMhBo\T|6?)RG"l ]+ ²2w۩ ȃKv+kCQ2]?d] o򿸦?F"b\8U}plI/V6|g8kHYyĽgSqwS%:4S |s(h/}߀4 2 M߂n$SyW/wյC;!5' l\I 3??"ېڷ~|J`4ƅyq:_lZ~N3Dyak' }N1D ;qn66}&V{8><*h` 7B'k=k3;aWYFso/@Q=Zp>9IjuφbM#lw#vu!8Xd nlϧwFE~1~#Hܽ+?ne6x_GFYB:pq4i;)s&?z׺r_zpU9ո对sFy!{f9x bZK1l l m7 雄{}<&U>>B/]JߎOR|k 7Ϝ<'p';w.>#?!#jO(zݩvգ>k5T=}M;{+s n;bmwPj\zT{ kκ ET=; ˯$DPnT͑Gz[W-Pj}A߇u_½ i;]Y]oo(Y;3/]Fh~=$b2)g\өj]IJ_o B;Y¹oQu ;ކ8xݣ]jjpgO˔_P7~{5Y4Ւ20uvԹ7zsRY6K{3+iٞass.wʧ\#i!\ko$_>+_*D1Hŕ7sΤ/HJ:K.rsrw+`?z3y[[5}>w^{nGΖO\ \^Ձ!ۣsT"N~8MV#VlG qcr_Us.̦O^sq\YZlq{b #zu12i-y#=*(}D'bZ|ZZAS geaC˜a!.؋y8]#ݰ ˿rQuf3۬tjGg(WHGozthi]r~kYZ #xn/stVυ=٪3 :#lViOJߏ/>.{q6mu|=XӲcR]gbw<I8w2jk1wæogez`[gKa†vn0SY ]-bӻ#1!u8/L"X (}! m3{a;w.6yz+|;qzusiFf#½h k U72b c1k5]Lܟq.2gwp9Ĭoq -Ϛ_dXoWoѲ6by OڌAݽz(^y2dYՇ {Uѩ3@wدP~>=P{cg |^Zg|xK{` Y_WDYk!ɽ^] xU|<͒*i7_fWg 1>'ǵ;bH>&<>ͩevY)(Gu'jgy큸Kٴ3?|ZkzMGQsF}s8C*LJ-pxEq'p_>93%/RoJgظ4F#csro pQŴڑ n)ڭm>_;­QX=HE0/:ELpB~LCscG3yCM3^[sNQ,9%G$^lFѸ$+^)l=-Θ e=vQS Ηm;^΋pfbF39X8 ن9EAV`ءI.&"^v:?- km]9gϕv~jS/z|zvqFESP%8&]:wcEЭN=:m|=F뙽oʹ|rfcV ߮b~)TAn}^v8vXl1ŤM;fXw>-o|%5ޗ111.NzӪE6'tvE2G qՐSʉUs5'PwMZ a9 +{P|zt7z;g\1>ő(51O,xW׼3[ = Mly s3cփsWE؋UK6~hj'؞kn׾61U6;]S?F-c}kȮZmJz3 w8x4ݥ9ڲHVq*n!{Q/ȹ U`mX NC/5vj'ߗ]Y}f5W<.N@p=w`mJzn}MflÄG9UZ5Q~N5">-}z6N)sp~9٩X܀Ku+v^_fF\<՞.#w99{$ns|yijۯS1,3so<9ju~K,?Ρ53;ɺzg7gomkzkw 6e۰5u9avwG&߽oy`-Y)*GY[a@5'1++;|w/=oiwF65W ]ϗ M=X@d}ߥiFtۊv 'P]{ѮF=_ԜoQ7vc[/9;[;dlIC]6vodx, 62 NҌ_94 |V7ȝ_?(<5 O1qn!.MEKv8qmn^knP6`^_T !&|߬s\hY7N}b[C{{;͚dڮف=cSdz@d0RA|;롧V- $}?ϥsS|.xJXBl+vs:;}?߷Bže1>}~;lGbC0- fNm;Efg;fUỾsΝ]tB᲏ǜ'- #a;!ZMdi1g[۶^qqmX|m} ".:ƚ 7Vll/xs yrÞ?zd_nq?,,X/Վqd/>iBȹ_ŭy# A^;jYmw .ψpU a5fӴj{jy$ ӍFKmCd{; ^loZpNa~ʑͧ 8<%!?Czj(?8mnAA7p{-98#ML&Q<vxl_ӵ+N7tlN1Uv:5/<̚L9ZLQ6\P[3jfu1evXr{b?,]}KY s9CU&vBfg0N@2~w ^罿RpQ.c8_{'L&W\ƽp/E"}IqT~-~͑a'[CU|vYo#^iۣv&vw꽁kSN}e*I;Ggxmُ "hXJ`!io7.Z𸟯1^R/ۛ6wN:o8q Y̍ҙӎ 1V?O걝,|*t5˝szѦN7|\]6z Zb=mOJݾi>I]6Zۏ>jղ=yDeGAgsFv3Ox͒mQz }꒕gbcUekc;d tuI݋ù=1w#7jVkV<QwzUW-9 \Idr4*+PrܨllۺIa|&uֺT٬{Zwӂϭ3<s]# 5_+:nEYe{l{|d|>G1(yYe;?:p?^BUgO|֤qNcK|!kཪˌ~cLKI>auIMrs'(G90\5mr5ȥM:yMԪ GY~ב(eXiS-.8:mw\fJ0DrdӮUcup?\R=6v9C[orتtv4vnwK^ٙ7KW6z:evUNIL!ԇZ'=iن[-x[dG^>}:c : u%]fbI}u\#WRT_/<Sm!:m1` ~ 6GO^aM#yt}AG]߬c÷Ћ>+^`<kaKN+eqiE MQQ(u:˭,|>朱_6J1{Wvٌ:l|}%+k~=ɜrڡ[U^Qߌ$N:klq`|N5SW<˄߯{EvGv24ٜvR-2.ڮ;ï(~ 9^7I=f\wVUX/g]g&3I=^Mii~vuͽo(ؠ|o)r)a"}mYRÑ)gnꟴ=~OO6 ~ikl8~DC3[/g`n\dؘ,?+ۣfGd5ʣRjSqP8, ځ)#EeYyي}ҧlF!0+ݚWߒ2빊#Ls~Hgjt6YNlqq*?<ԫRYA|ҟlr?McҥvȨǃ)h;m+򪝏Ho[;5?]UG.khs[6Cr:=so`(hbQ<=?G~tKvz.(Z;66ۖ?3n,ynYlEg5of)DKɍGgL1^64WU{~Lּd] ck> {twC>}]->?nvƣl>-_R{q/k],ku5eDjV_>wwN}֖ޛ,zܙz|ل^OsW+WcYQ=(;cL~Ǧ51;UV~c}~.2?ipaVqگ\Ft/'6uׄR yԦ+up`V4S%S냴DK<:&8uY7vs"r]`qY kYasd|ڢ]usȸf&풞fn;wȏ]ڻA5ǡfd겮{|T6jۋQ*>]"ܯv=Rɮa:پϬϝZ:2d ѧ{U3RTE2 w6< 4K1!OoFUlˤ=dcݲSgk9qoʫC> ׹f6$[Wq{֫ۨ{W=Rh>ldNz6bsaN= ʱ<.m(͕X|Pnj_>ǤKӸ{UsYLwXm9U:uz:6a:HyW+{s<7DTf5t*s[3%gC هrGareP3 [eҢ׳\Ck%ۜr-nukdžg)5~)~;<|kszqy;{QӪYjw>uYFXP5ŻƘ}'d؞ #a6%`VN6{pu^XC5%×2kw{pOal-k-P}{nZL ֽfq. l?r<[m^畦bO˱N.Q;߫>mf"Wsucaf+ D-_r#^+z$_qGf+5ۼ'>n0u]7%Z*~YX cÝ.,NVLe {kݭ^۫x] &&YՂW{\z7㮰2X3 iNA1wAۓjc`Z&!_(F{oI~!sw`~܋7&3 w}L#.}G_cޗ5d8>>1#"{$džzi}&펭0-hׇMQ]P=a 9tjr.ǬױAr;d>p/K cai0 LSC8i0\:=X|`A)^k}/A_O&|J{v7gƣ iB֏zzr`;Wkp=E%ذQ1ߞfjn+x>GNvmf\u8WC/w/TV@beR {>)bqI-d<⻼?߉Ͻ2,*|s _$grZȧϐ?ŭSZ|v?ͦE>YMN j):FNx7^CNjݦz^2w(W4=]`N`Lgf|}:Q9⾫g}m\Ysq.?ϦsrOOutu!T^M{ڤ=<9twC?ES^=Vke~~ _1!r +]/!KڠK_\'*Kaܷv3n*o!lZ㯢iD'Y]'<+SaH(4#In4"|B_4$cj7>mF%}ROϊ;AN{!xڄi=Bl>3I, /fJgV igRulFzlUqgIdث5 ~=.}[vUmђf}~nX8HN9CV f}Zdu^WC5bO;\> =V5hO"珹XԺf8wxV2Xz sg0'-Җ?={l64/\7,^({5ڇ,K}wI_0ݢ`;LNYo-KEٞϼzصU7%{#~A>Ӈc P׼VGl8 # k6ystK.A0ūE.Z*Ns6}r9wF3,],w'm8C3c3N.X E>u)NjPQ.]WkwoęVee54Ë-q[_A|h}];Q/nԵ{,lzV/М/땖mV='zس^Qk_qU;Y]|˕1v,l5o52ïmjv;6-[!9tj=sd+6(sMF钞_834,A7sY:Cֹve<%9홫`ǶQbqR'Ჽ뻢#>Qn@9H׌lk3n0y*N3YVgދk݇펚M;7_OCB|zfvC/߂3߽i~N0ffuifv.N{7Va.? .u .!ǿKp#nQS<|Fp>ӏcx8O| 5[ WO{'jk)V.a#_5=} NsaC/l_[lWY~ =ޚ #n ayeRV[cܡwyeqsK3Lpͼݵ=ֶ[cD/E7 @; +yx*/n@ h#wbo~ ǶÄ6bF^ť83njY yڔc M{|xRwzjlUVތXk_s@Bބ;K'gSXΒa,}L})WsuQ۽.يMo9Gpz*)T>/H:|=U DB.Fʝ7,;s7K;/!@ ^SQ$n s~XJf$5ql<%&|Q*TN΅ﵧ|gO;I)܎n"mI 8Asp.4jMY_#Ե[-?tNqP*kwW;nȭ/5z.~.jmCMnH1n/9\;`jU (!=y,>?-Y9C6`:Xqj^8?%:ĦN]o~ =!ov5!><zvg|-?\"Cr 7ys //f.pw*B^Ia u?hC`O>GtI")p^.v(~:pvB8K▞\CzSӸ\"g!'v^kfMj[2㎯Ӑ1`d=QPץǂ.洟oal.w'~" r}#@<< x&/۠d*x$.ClgŽ)W%Ɲ()w'~?L'a?1Y5})$"^تCɳbSݢE_kr˜jJy>S޺}|\2P?j<ٜmwC.W^iKesIدD~(6|4纜=$ruo'<5.~ clw6;||{A}O*;շkNO: |t2B'i-|&Q̪FNT؅vj _Zvz|;/uF9kwl6k<8=6ǟ! cj퇴2MƽZ9=es*rƻKIFv>)^HcpPq/|<=;!?B|ƣ!;xn['B6:㞵o#G&ӎ$wgq <~q^hQFvd5Olx+Q{*vz\};[6݀jذsuؒiBnbG~iiwOTg.0f0.!Nk%?;WE QGA._U<'⮝ >Ưrg N<;͉OnQtL8(_ꂝ(Ч&Ou\Cֻ?뽽> y#_Gf54%أ [D6#O{mlƔπ<%r+d=Lx)nQ7rXX_ 5mȻ:F[}jzޟ=<5aAV6lgCg+$7gSrt8ׯ3R$/>B^C\{kM>ct;aQؠi K2V|܈IpϰW:EnJmr|,sA:~FҦhU'[}kUx?Z+o zZO[BRFpz?9| \O(!5W=<<6>Yw{mr{r.c &CdY^Վæ|gSr#WYfgEشJК.j$ffd|ndž9>sq!w01e41#SM~%:/99i5կ=e+g5 fe;![7_<6U=/!xeٍt$aLB7ꄜyzt₧ɖgAp˔qoy╫;w!K};ڮگ|<2m !9!Q)!giC2eﰯC2flLY9*+N'&R;zCEqPom72[ܓٴPgcuOGph2]9B(kOn[v[|C[\|1D?m 9j aˋ>|ʷxr-grEvqe~W~ ?sW 4at'e{Fqax kW ֵ#)}?Y)[Ľg:dcuC2Gcuh&X:Y/ މ{Oo|1 Oo)I79!84/c2^{FG;1>[/PO(Os>|F4`Ǭ/H*lňr4AC ؄q  nɴݬc< , i}{?҄591syynϱ>>uI44y;(c[»w664eZO9/e/,NU^q'td+w.?:n˭+C+7;h/Z~1߉ܡT77`2*㳅1a OWrGX6Xײ>'v֮X?*?~j LA{>3P6z+\t3=!=~xz ?% 9+ 5]䴟T/nSn̾}1kg~IV v>h016z 5TpLf枭4Nx.*PIX.shwwY3p_߂O>O Rk/O|gށ1wqtbyxw"l0.+/=Fb8J w7[(8vaML^tZ/W% ձwMQOI߀3)NJ5ͨ wwlr掿o>TJNg%9N숳pt8~Ȁg!̮0},^ >O5zJ>p>Vdf'n] s*(&OiG.Kɍ׼53yd~Pjt_l}+bX@|vpm{lQWvC3{dn HLy۰GACD|=`P?g5`ٱzzNbM>Y_izl eS^r}$[`hOٯgr~8d9cu?Qc${6ڛԕCn@Z#Iϫ.Gf}p?W=/?;vެS~}0^ dXc8 _1%-bB6k#EȚP><[1@.;3exUL7slaQܥ7o%a~=^/|`~ݯXzw>7*,TT-/w _BB3gޕid^SoyՆ#!&DlnP]3O9ڈr*&xۈ0цmuԔU6zxљ4L?776(l!kEn3rO. V|f3}W4Sr&2ئ!{јlоb&ΉXrs&3nnOK=FXLd=/:9<}1g ''?Q tγtr$u8%[|5fXuˆPgYs:1X#N~<^>7}c5;OqsXWG-F6v}T`0xŬWk^߾ub[iwߛvO&u]1n=3?nW^~?ħL7*Ȝ=T 1ƽ£hf|'bOLJ+eռlֺSM^K?~͖v?f{ rwyb6қ,L,FfS|]}^!S`Kio?5k 7c~.~ߪ8/uVC~HEW%}]#p:xk} !_bPNAFw\Fbxs8>U#΅#n#&.a6iNvɍsb4|Dž!5srţgi{gt\wc -|ak9gf+n=A7X-l4+rf^aVk&x brE쫞{*^^х +p s9EKwbͽ?{nUC{]Oa{[w?gqyT3n#92ٰrk,+crO02& Zst0(ߪ܂1Ya r=x~s黓s/U܋ko8ljڔGu !>؎g#&هTؙ ю>W+kg|Dg} Mr6X۝oYɅ_+ ]1ڍp99K,| yvsʥ!AtdmB\tDIoכm^UJU7y\- . N]a|rObr"[I,}Ӿ΢i_,[/&p|^zoֿ|SOkogRqR,v✷_3Gn+{kQ,\Mg[E\Q= ߝr2wŵWdx_/ǯoT̾T]@V/.1 9Ő&c|U[2OڡSyۦ\Xa@i7ۑߓG;l~jq <݌ϨĖg3XMr6L>ovϱa%3b̾uxoEo:T5t=1Yx+>x?rkop;uzclt4a|iz'3'.y6[U+;m~?/V׽¼>v1:q {9͢Ϧ5CJxT x wOnk8.Lv9|]$r8HQm 7G}T= #_$_@ sƂ#;ecOO/{ ~bXqk=%] ҷB 2p_: {DmmUfv]Rj,Ft6"?IeKnwog;asecV&Y-a@5r3c}2%؇n"z1_@_Mrz{qnoVf̼:}A9 ?o'1A]YL$^*qPg3x5e y9RxlvM߄Ou]>LMn?A{}BsG0/Y|pt.X M&cϮM 6~VBlj# |g$7+Ƽ_9^=}aBK^v'#*# ʸy~-,WVbǵez?_Yxt)~4n&6|s^}/0& u/d}"ߗ ܯ[AZCn&D3V~/%2Cg/UO@]D QӼ\B@ *c#:55 4?HKz^- x;_3'Q#uZ_װZίXRXOi^8 Kĥ? $Ď[3.B΁̖B{,D<{؞c[޳?Bl࿪ʾl/Oǀ~JU9gK'PWMx/f-즠 t-}aH:\‚探 L '5&u ?91yG$Y HEC~d2{2 #Y,{T"^ d*~k r´$VH{ڎsV7r)eMj^^elgý$6p܁k8ҏ ۾MVMNjGeaOqXAI}0Ǒ%46WBeR21 XϔKXϹ_q)D8WT3*+"O|-}1{G NׂldƘ=Iqw~g\qwq?] G3?lk_/Ifһ`WLnMxc[Ծ?\SS_oǘhwW3c ZF~"N/a9İjԩ#1{'!nGyۊm>a_|+ K=[^8sjڅ2^|OUx^ؽkhw!AZ~M5{T7In%-vˈwhn6g;Sf.ObbNj´ m-17WJ?k$R[ÈU>/Ov s;ԫbaL tiF|\elK<.<|ר;OҬKI jX&Nj.M [xs$毇 r["XN<踨>/O;ܕU+Y|{quO??+_KlzN ݾ1F}- IhʗqDXys$Ʀ aj8'%(q.ypՔqi,=XIw\<,jAx \tSmbrT_@1}]Ps"]2o׎ns!o2^!bfOf-j)tAs#z:kz63Jw޷C~}NӒdW9*|geINv^ؚV:2}Jq &OX [̳W7侜W)|`Aut{nva8tYd[9ه[#fW;v Nlڴzۜ N)F<ʉu~ 3YXsvvT$4 _Z}sƶgZMc!3nijܿ\岾Tq/^ :^C=sgų+.g9UA RO.cfU>þjN]9A>5Cgqcʝj:=Gs`jǛm$=6a@e#{ogW]es+U $@bT:DTZJ6ЍzĆ(& R *QIT Hlĉm5آ؄!筵>}{WgJ [ܥD_G̝ȩ:+;LXB)iq_kp[׽ўHƳ5߰ŝϴC&+poEwp zgK=/?W7ԌwrXЅl?~ sIXd!b&VA_cEMl?oӎU,7|QM ~_',EK`6ߒ]5%-2σ9U ss#,g/ㅽ18B:G@kZe;,i}KUcq^剸yUUGcg9G̥I鵉'$Kuj/g12zćcΙh6|}w'(y70_y#u_1EzãL^vP>b.y<&<{-M@}<bgFE( aKmM竞߱~\^sq{׼[>mfTîKkN$_,C_럑M6~a ӓob娉m"}+Zۋ(= \.a njy%qvԜVձƍsjQGTȫ7"]!:ŜsYyPؗ u\ݭi^m1kCKm%ȡ ժ۬ìsΩ<̿w,-ri25Wؼ1lȕ;M?!g>@ \3l|ݤg<_ϸ/8"|Rܢ}bm,~BR($滺Տzq_i;ns=\_%]c͹k!%羙vWyt0R@Iuxqw}0q&+[s7}>OM}V{hu!> qÑ8NjBog18d|wgա]I7NNbFo4|dzsl wEAN?:pGbuv:Js-U8"gNlbN#ψbY)o"e(ï6Mnǩ6k'hեzO pYΔ3K,3✖nkx~7ƺAA64 fAg&qfg~||) E<[1^{_мW+b;saelJx*o⽾Trej\ۓ>Yͬ53km8+EAs_gzb5L?4wWbQžfbr0m,q=t8ϑOJ W+j B?:z7e҃5_K/^%'AilM;dK_C>m bJB',p8}@Sxˈr)v|ڇ!cØ/;Ǝ:ءK9D_t\z:.k*A_{ݠt*l&9=&]1gOZw"B|!<}ؓmyoJǝk1Ll8rgӗǬG0&k+dr9b8qq-sG(*՝s=}'M&-83xٿ,cvb:ZnX&ᑃF%6&Ϲ_RjqdXqF|}3ʃX\%t;e@/.C ]s^&Q]q;'rW@c()Z>,z-&g·ϧ._"Qe\Wz.X1oQ;p|~Zõ~vsې_ܚpfpIs%6b6j2amuk´MB,w[# !vcZP;!7¦]%i#TzF5 gzEfd;㪻7 wYf3JiVOtc׉cՖNSFqL aaDԫϪFݦyb7,>Ws;mm8[VGϥ_&_b''=Ƚb[E;3wo~t wƧC&somy&rw\TWgP<&xV[:ɖpR1y%|U=Jz;8Faoq_3T9GxVK_z eĶ/zy‰Uqf6a W<鵒{%n;"6ܦ` ug+3گLzwݥ~raia~-xX\3/4٠e&zw@~9a _[r0,~Qϝ;d- _c^ ִ.1>A0ӵ !F,U/mƹ~j=ɝ[q0{wk0ĿۇoU*^a UaM8fm^yД0y~RgY ok|lvYqq]=?g {s|I|h0" g| .e8<.ߘ uxⳢ/r-Q1:wLҥy2Vf)S3žT@YveP7b-ӄ lp52.c˜+Ł6z 6/LZA>"[ۉW}U\GsY8m147GƱ<}hl񷾃X /|,= $8NGG:O^cⳜCCM<;6;)/⪧wg=rȊ;cY9D:xbx.{(sAau_ ?&̾mꥰnpIL|ZN̫J~}^)^/z(ߤ<8ʙT=ez߬M4#n27{SF?kUo/Tx^ĻlGklqݘdq¶nk{ o^%nu읟 !ٕ|9ON )% obN^}8 lN}sy1ROa"n8ݛ#a\g 959:G[~x싕ۂLİ\-mebNG/rF_T(_ e8ws|rCW9KȩfwMl7jw <1 ޜ~"yos΋xǝo~Jgf|NRS(|!̧Tbb҂{*94X]|Esxg`FL73{Cy {wL^(&bzoƣáO;VIg('GƿIg]!b h9?͙dSQd +̫^u<Q Y GX)يj?w@?V^![9nP__Ala8jګ#>O{)|n9O_ &)5Y ivȶ:?l^X/B]gMs=ڤfab_:9JD7?llsvW꺧}^8f!=f|ϫLn(WG JJ7bϩܪumG׳a8~# e%d|Nw[|=Ec9Gk-حdu3pTx˶S&qգ0)7_|qiw79݀#n9wey-< 2;{ip#錻=^K'8v@]ȳ~s$.SgEq5!\^WKyM6lٴt[!9axSxTœRrNz?lv\C|qk[\QOQ-[m˄6mxOlq"t,۫[ďx_o-9#lc,pNgh]m"iEs ߲}kFy`XFV_۪:u@wD ȝ5);jUd[fu>G<ym- GAÁF> ^a .6㱬"z=ظ'y{O}P\nI]5q9ٽ*کsiKc5w%=&?6}1ʝʷCa=٪֊UgSivwEq7tc[ƗS93qῐCg3hu^8S[^r>@ՁYse\&5+o#qF(ϳ]Ҭ40a{roy/:yszSQqV8'. spr#0"'SR[8"ε숝u6+]7~VB1[G[h ν_Mi}-87Tl>%٣Ur~"jm@wt)9.0^ {f[aW $l`y Xzs zy|f9~Iǧl:z%WBm>3C rYG"T/C+Ttm.rq_b>(Kceg/>AӍuAɨɍc3? Eټi<9e|ǃ3?eK9Abo>7kLxcq3nnj+EQgck.V̸Sn+5[vwF'.S92֮Vsl{ԬN5dhqF}@:=|_4ݨ Tܚ|޻19?k[1~׼ƗЪ{1W~;pcj\ȜwXMr),{+9}bbGOߜd:yYQ2(55_{ͩhݖ]u}!ύ7\'7=U}챉 t+&݈k<١pEn5x;ypCIg;lk# 52'^3оE{D =wWd5lw>3f5 h}p.[l׵N:}<6J}ݷ|NA/bS潦żq"Xyq׌FX|:uK{oj'Ldvf\\˚?05cg;bͰc\uǯ$k#Ӎ*ݵݝQ6_4s5 ^ 'kN4Uu%ɚ,?-=.l<ά`FY2lSNy2%?6/P;ֺiy)`CVgqĸ}g ]f2~UWwqU_>.MOy6?3{Яpx6*;Qƽ3J;ΰ[uYߨ߃m^V-`V9kwQ6,wM ?냺&O*~[W5 ~Fk}.Q1gX 7Td2mUΚsYY^k=~8z,|rJ:Y3Ѫ}[[es:FnO/*+lats!W;x##PϷzcfew.kӈ\fQS 5~\]=|ؘ;=M n9pmx?TɫN0(z~'ecA-ys;]~G{˃A%/߻<(yxtru^X=~V#x>>#qAuA}̯Y)[5/h}Z{=ш' -~F6JޭS 04QY﹙ꛛYj=3>b]ڍ%\%6u>W2g ܨǽYI}}0jf=!u#=ҨYmbƨ;o,qZ㋍>e=sT]=.kVX:ݡ9׬MI{c^g!O"lcHFšilTӱZ}vcSZVfK!TGJ6_2MkAÐai͞ҥ sB0uMy?5+Mfi5]N&j=V֯أWs;ۢ<=_ܤ0"Xh^uIu'divq1k*{|͚\dvF@נ`Kr[=$91AkY^9QS"ZWgu]w?>gt_ſ,w`>yy wGd|lŃ{x+ guk),달& zV-~u+ZyfbShkZlԼ߭~ްJM9_ɏ4~;eZvtP@::.,G9{YE@RG X&owLָO٣'椲<^B4j AhJMg#IemU缆a yUqv:ˍ.V=d?3*_n|k5xڷ>a`MJ]6זStg^1Њzv8ۋsS]dsFf ޾TU6+E_}9}gZbX7{}[<e'[9Ww}͵,յNx.mxO{p󍺽b˧׆l9WvݜV nk|"h|a׷EfB6Sm_x$2>yTč·uNHqn}j lm3t|hvF5S^u9U]Էōy:K %!e8fm6zn*v )6xl׃>Yx}duǤ,k\8g>V| U h5 I%iR)M';aTӟ%Τ?gv|G&q'Y3xxR3v~Xck+;)dv[5WMr`펲^okִVj5]vf[[fT52OOK Ԉ#S ץuiyҩY.ރ9IO9uҟ!Q;W ㍸?2X)¢Xk~0 scΫ>ب9?lpjs4nռ7fU9WMFپa;o_v܂'6mQS&`pJj_4].( Bv' }r ?9|tI.d ӆߠ_-ΰ{ Y2'GOst1ލaVHulΦ/ui\xG 2|FoY-:xdkټο0eub0ЈRպ7~8T \.?r]߽._~8 NL)-] y_tϹ ‡!O\IGdAp\<p/4d>} QB%m{T 榋4w#ۗZIU5>ی7`rkm7!{u/ Fla)0x ;>WcuP|\|C/g9ZxY xgv׶VkKq(;}C ]t˃d3?Ce<63Ǧޫ:J_d5Trpl)1{([aodsN_Őmn]Wr|OB.HVη=,I˵Nvz 1cz}T4?1`G&n H?oǡ?kmRaUnM+/mjEϹ l9g|2A51T3LVlbX:H cޓr> mltiHiI{+~GbքFs q^y@woͿo}V~D*m,7Ҋz;}Qs&pCd3{#Sߠ|lOy/!cf( >ю(P?]6ۗy~/~!{?&xSvnH6態KzѩiRmnQl&*NUbu}ǗM|CaЏo[zq. .oRIߐLEoU¨nmP}cl"scg1И)nRn{ }fY(dA,sKKm +Bq6qωtf<BEaG{36vbߡ=priU}ħo[o{B r Ra!,ݱɤzN׺B[vPU w+gcu˗qODXaY&sDqO3~1s*뭿.q?8 Ϭ kNM}ĵ_ ,M 3nUn{QVGUN8(?0[Qqopw~:|/F_ аo{{>g3J#jޫ;O()۱F̛ͥ[/s2J}Wr1rYALyse'\3!b7mn3 f!(>璗K&I8_$~ql\ĸ7@ ϡE&_ ,sN͉k|>j// uM|t"}  yamwH5͸z6sh(&.髧/lAs3Ŷ{zh{6qGk.kpp~k.µ&n4=%!7_(ukN9ߏNeD~@qwӱ!+a&m㬆n- O Oقq/r;[a1GW>#Ze'}vH=saAmyA{B_ID<:rVq'3SX#}ebuxYNS{Z\'ƥ: ȉ'nx %r(^ K(11\ <06N&9 mg{0l~CY-!(Gٌ2+}6eQ9}2//5G\?rZM#MV?BR$+ K~PrK3%7&e70i arr: ׎]"BqDkރB NqtΥ'63`s߅ם̦cN^Z.Ō54m.dpM;ds\}NY;eT}.6h r}\cϻY^+H=ad;iGߧTn|)G/1ȕ\´4C>aqS@f7&W, CsH|%=c}* |Pvd&G'/.ͣ/{+(1yȯ]TFy@q'^q jqXg}.w%+xF= t%|}^b`YYU]>ۋTLL[lgW.4gS3S` { 92T-R)#wqAiMWI:L{/got| {<5&BǎNYC~PY}vqVsG]Mj}k\vbt15sDb(Vȿwu>%V/Ό [fد[!`ҬWqwfG57Q9u["ieiV[%RrEN"OrN _b$wG YSurPhB^OLLj.W+'(͋-x>݉Q>1r^qPr]&Ð3fr-+x7b(k> *>. fQs89d#(`{:?<ὶ}"o|GgCw*Jߦs o'&o4;A m__5gb 㚸vi{_2/_owpqLV7Y#/}}_Hu;3mtZB{z?ęIVzz>W]TQ}͚CVC<ߧnBwۼ-<p_E==^$_t$of Ϊ7'o!kmtHܬxCgBq[B@380.~d]Y| u;{y*g6YTq{`w_^2!finxtkj&ke_|5w6GZ]OI0pbKno-FjUvη2mNSrk`o})`:xbvr e>)<<&ˮg>Yɸ(N*rƒז}hRq}UC|Hq4dlw+)8؋:2m P{ebay|5ޫ|׾׊8U (|P")~ wZvg\F~tEx'殧;ɼ0=l쪈' q/NXsS1\P/\)̎ݐ+/GcIƕϵ5>'59ʼ?S.ɨZdZuwb@ჸ~v11YGd]uKglk8O9'GYJqsJ~qXw_?<=لbrRw-ߠNnK=~Dx6ŸX<}8C4 uhxlbcY/hALjg|58z%h|;wkO[pk? x^SnuW(.&G"sA:>9>gK4{|Oh(9?SևvÎ v9#z%m_xKD*IOA;cw7F8r4qחy 2:ކk/)U[; 4@SžSsk륈{sS <k^<!ϸ,E.[VG,YK_)/r7Bnq7bø+q<OűB;ԿTvqc6y C|3iݨd^&͡e+@#oloabXK,cYzV}@yNLszgkƱc㷈?!%/ir,vﲿu>27kŊoݛr:Yӈе8tWRS/ӥ9O !IPDvʛ̦?lHp9vOTNXSL|r^'+ CyDzMK97PSzRPMg6rl|U5W'9>oМz粙,GM9 vT7|[S*e_̟|*fyOĩ?Q~g_b&Uَ(~Ma8'Ki#K|r\c r>yΝB(޾WxM^+P5]sػ?~"U媻W }AG"~=O䷈Ϭs{Kr-,=-I3R19Q? #d}XRG_?cOQx 8ȏrC$_G@[|]K>`~.'ea}rn8k=䁱}vٸ8 ,)F$Y!G+dPqg`-Z< ~-a w,V`&ݝl}ۇsTM 4<$zub4r_3\D'p{˚Yizq`CrYvly:<^ OJg9w9a_I~пNߖ=s7!j~ij#*uό^ĵsfomKN{q7dxG'c=^9ZwSXi<t1WS]e0~H=@狼=`b\}IV3,1~hOD[ZO)ՂvRgS $sjk[ps|S8sUͧ黡셼 V&6o:>s/e(rE]'Eӥ-ޜA/|/LF1X -;cl T#bߥkw.%<~YO> pTbD+G_vqEU3({{,sݘAUՌykU9zc1Ymc͍^~0nmml6;e:Ḵr]]]{3h<5|P9 ^#9tȯIW5ʸ)وsoWJ^%s{&PTmD;^(cOoP,m6*q-dJ1g)kw&]4F_lPO&gAȏ4[ yTIsj[qXmq16{C1ݖ6x$o~^[,0Ź̙٧I/+^jQ|zyؤ>u6z~ii~(15)WqZpgl10mkڬ?9Aq9'#SG}6ognc>Nׁ݀C~A8Y !ˏ3]L-ƈ~k:PN5cՋ)ߏp 6Ο@ 37۩s1\bVWNg{BLHpqb|z$ .kxޞX{^&/cυ{S~jP[ n ~n&z{kiGH{c؏|ׁO'kGpӅ`o:nb0^%5ql1eS@ΟV)!݁t.>O!?'fFk9“͆~,Gq|5MY^ 䛥ϡt=FzQtz 8sGBNfoZOW@xM_>1_DL6X5ٲU-;|ք9 YxwRea`ܜϬٟvM;<"m;X}I([}Ŝ{8d~j 7(lc0{`vB%5S|ty{dV51u9{U[-=_r^b)wZ J|B9Yت^%kԡ:GS:ߨ8w5^ c$6_z{Lg+ڿ^PkGHxռMqX\X4+mHGscBKA1_V7:]0Xy27$֧^s}o^sV^܁^svV6g g"nѬ&m#G?4ͰAf?6sl,ƁT˟{j^V:J8u5.c߭Ǚ Oz quX S9ޞ}f&=?L*_9Όϐm~~s^ɘGiU5#M?)ϣ-#G h8Rl Fޱ>%,e;+OΩdlbgX-Ol~=}/[ާ gu IwU=0q/Ԟ U^ζds [qOf?ٮ՚y}+9O#e˼|-õ}5.x L| eA/sd#B01}E<?oc6[?G)T gU y͗$6.,Ɓ&VwNrJCw^q])6f?UܻhWh {TLыq=ʺY·$X1+eM9Ԯ~2{8݀T̼$exߩ5|Q|.QV{l8 AV&8;ȞR'/[rm3fT Tztj V<_ʣ$z|*g9>[]{pF/ ?_#o9Yk!{X5 ~üzՏNNM;JʹZyzG?\\j@_}k~#;Xsqp fJ5CYld44xoV_c>J՚lƉ5w㮏T7P֧<ϸ.˓@׵6;z#dzdygib}_?!vpo|6l dM>:i LJ$h^&U5U܄ɖvg'&qbrhf1%{ن v(/m8;9Ӛd]d)>l0Ynq3.xj;%C!l֛|Sx.?sT횻|}xsI~fmUlš/8wwbuMSo}+%6v k̇ٛ׫}F]ν8u0~Hӷ(>KgOĆqҎݗ6Cηǜ=D<]߭Qe~06mؘCjj'֜j{\3|VyC ubw;g{X:ajp\iGC>ywVy\ة.\Gz0bqSLksn\vêӏ*^=XojOILUSp}G ~oO8G-aMr5/樉3z +~b&%SY .6LeР}ufH=?YgSᬼ);N W .ñłG' zVQ1ugߍt:sGa<SLZmxx wz3yc@}.#8w( u}ia]|Οi=)Ou^Gg}]a6,g M=5"61Sf=i}[;>M_\.c ,R5οXHN;|W/?;{S> d.iti-oKA&T+:rذY\Lfxbr7s aolgWP#]#[ {DK!ߒߣ3"&sڐ{g:OE _빬K$'}";a #Ub*? _آ]Ć-Wb_h0G_9n@}V0smvfFv1M kVE zk!e^8mkd0snBʏz``_ay2΅Q]@7c9ڣٛ@&gB7+}z'qW4|fq޿ Kb"1+ MŶVg_#Woý}Pvj89 ;?e\A\9UޖH/ƁWwqZl=P/kY(8=Uj6^kޅt ~4oA?#>:gϯ5KS?)o=qϹ_Q. {!cTjNϪVUZcd{m7E%;B8/ީpׇ,2\6ٞ,{:.kTm$nt'x}Zd]Mbi8E[dvw~</na0Tmwα§abHC+p뾤7S ;7Cu>׳G'(kQ>X5A0vfVyoJ9QꜝE]xn*toÐ ޟd^>}e`<j5k- TS+Bw+OW]Nɹ{rs *Z/5fEaBYx54?o 3_7\=1Aש]ͧqI _2V)^ͷo r:6,㹚.ؔY²s/s dў1d^&}㥰GBN3Hok>0;Ryv@> gJ_JK&Gu)VDx}= ]8}uLcuP}:OWxz}پ R_ :&u׸{Uwz{hHv"N090LCϞq(Džf;W?QE\ u 2U m)_t]LP}k?\Сʛއ1G=?0AA<fU}em ُyu{BsJ 9ck3:eE >C>&9s2;LUO]sİ&*<';7 6]48 o[VnF`[5U [9]C^c=A|2'4ӗr?}]nJ%i ZےګN^Xup}U֨9k&Fr`۰|}/}+4 e9ա7Qqݲ= LPv_*ߋ W{p]b4d7z/ĽN_{xVYЬg%N}w&+x4ԠkI~[UA'>"<S!Ϗi o͠|=d0IY1'9t3̇jt>> 1{kz!/=4UYlgsiXƷ==cERרEW)aOb 3ze8{;.LVq!>x dH|w!gDX&ŷyn3. oKVF$Ϗx.G|ؖ /$fW`盜?,ﶎ&1qC~USeovN$cmCa5؅PIy q&|L:I \бgkSGdq!'n!o&zr/|jݫzkfXksÑqϵ v,~ު2(f^Zgw5V-UBv!k>33I^/SCΌU;o 1΄G= cO\Z?k[Agu+zfZq_ q8 oĽ 튯$a\DJ؜xY< ؕUE~({5S»?Ds#2 k]imksV\U;iH&e^1B^sx# |yùT_&ȗީxf,"J/7Botua$+|Pzlw_5܃x`Jr^{ܗZ~axlP.1 _1yy\f]Sx%eǙF^1L+gYlDNiςk`$jUE}7_w-le-o 소e|64<蔍L*ȋC{Pfm{l1֥gٿYݐp߬7v" aybbT_Jϲق߀=ϋ ;\ }yMBLs,5Q| Ӯ%|Vg{bthu?DNp aKxBw p@ܡyavk9}~>Z"ݪq?9m }c, ,u|Or,D|?jی˘vuq0eX=@Lw՛9[?YQzpfSR*Lf\S+am{aғ^jwLE~KCAjsG{N +sW| q{3$X@|(|ܻ,_~E2>| ΐqIk均h^;3E;&_l63{n\W [ P\{!AJmЛT&[([CS|9\3O*zZC`gswʎd{7Ҁﭥ;{H /B#*(}mFA@**NzqQ@$ *VnqI%=n$k2p ꪺ<ܪ~Iwuս9Y=#jS9)T7{k&ǯ@LYR w_eniS瓰S _Fŋ t ̸|'6lgY}gľfPXgyT;x凚sW}tpy - t;\?5>e[haA3Fk5W=Sκ0bel|.У+.qG&ޒ8mq^ ˁYs}fr\z1R=qӄGIC=iOB^ΝNsOO$ڳgN9=(Ղwַnsk>JzB+f;jpEk{^^>,gΎ%GnߺG󪧟J`VUf/5Ycl1Yv4luqN=a8.]~g< օs Cwə.AlYx6+wڃsa࿸灜QsS`;jei*+lqX-&hx 3?7hش;qh3[N-CbNĬ)։+yr=r Vg7ԗp<9\%?[z1wHCs,pxˍs`!Q]6ʄɃ8YA\rMOze?dCr|ֺK[3Or]˹ .$s%q*;˸Ǩ$_GL}C†[q7ʕg3s[|{m_~ 1cv\0_وN<w%߻V55a]9Г@LYA;{|D|[U~جX8/EFߩvjjGvׁMɃUn]¡ s[l͝G-ϥ?SqC~3 L؁vuʋ%?+!Zdjt8Y=G]6,K +?߻1;Uz\ôHW߃qME  5;^Ur=9g0E@1~8 >Rz2 |S1wgO||dUnDlv>~ U/jwe#ydM{N 3ޑȸ*҅fh8}PMCKk:u^\G`{iJҏRx'G;OѷcBՔ/_)⧅ l;kyO37~3 [nd*ߝ?䅷XأzyiFD-菲}wn)(lTdgȝhͫFj(Oy^WWbu]Pg1'A@5noc0t3΢aScl[!_yPnz80|"9ynjgT:3|܃o>֕Xg0O㎉s}+ >'㣘ƹfͱ~KԷ`9xNX'#FrA?WZ$nx cە/.! d\"<%>p. oC_y{wz+;hnfwzL=?ݓ7! ~_P(Y?z"_9>p۰upa} {P>mu\TfߺXިc]L{oT->gָv*8uqqs[eWgv׿?8jڋ_l'2čӯ&|1N{Pk]NyrfBƏ"v칳 5]Ӑ~[/*MFy;,F~(O7Aq;сlSгj;f[MxM5+'VۣL ]- 4?ݸ]>xxzmuaEѧ' ܥZ~GUAPR "u#.'d!mkbsy< w.uQkuB4;۽vy]8J;X3:Ff44ˀSn vnoMe|-J&[y1)]#{Uؒ"lR|q/ gbu%K*N奈ElӯcM~&%_hoUd^>j5qoLg%~񱳯Gw0iwC{wGK3mTs2qm1q?'%=_ ?=KCsc+@㾧޽bOU~@$Grs`U99CqYp:_$; xߘLψӜ=[ϥ;sM8ӜU-\%_9pD>13pV g~g1qg3&=8).aǾy=8bKuaK} >ۈMs1{p#uϣ1+ _qz6[ׇ(l?֘u*uеnՔ3N绚vyN~p]d#B}f /ۛnaab6Ν}m+Ɏo]a)/U.$%$Qwfu;3!N{ܡl^1QצkllmW}&M1Db:eU#/?ކt+|Af?=Czι41ٸǮCxQͺoV0,p3x #BYfvr buX8}sg!̶߱Tosboi7{nVo1/9& Ö՟>gw;vhMoef[v aw,:2j~6R`i5ՆEY8n{8r^c*].嘮^OIEyaݦ8l†f<W\Ү|{xg##oh:e 6yv;q2\/ qY:ixTmNgo\nx=~TƁG]}_R;^h9}ȰZ,"Y7-5<ߐx\αVիRQ{l;c^f[?{JөaQmSbqlRo7,=M^>t⯥s$ste8RT$nmơ]%EaLY=';Y 8O>i }vg{#^>Z4;2"˼tnW aQ[鹌~?.]7?nX.°8h 1RL'ۧwَ#p/,]vn]MBMf|DԚ-߶;ۇݎF.!p[f6wkd<̻Tt53 zT?';ʺ~<+#z~j*ӈ3;JW8ߛ<S)f=ra +ia3ꁚa$ٜ[_du)>6llcm͘"X,p]3U1*<,k룾YӎrA[{ETggCvvNug.0xqLy1\a#;-NtyXڢg֯Xn@)̼s&cyYEYq<^ k}qLq^uÄQ/p:5qM6᳧ rnH}ywgN^,wXSŰ9bqNs zKaa6?26Ob?e!d3Jx}}VsgUֳ, Z0y s)-|d(#'1.lyzm֩!j3M[5⾣gm~jrejT8-Wh , ~3oFUm~1&wr-fvvOɡlDo[`~@nLd,-VW&Yu^Ƽ/kLדۆg!__&T^A43`>}D٣qٖpx5cz}wwH$km)=wm SVWe,Ϊ!>/kuI-Z9(]d`Yly49Iu؟ɠE ):n9 %M-}˭lH3?bܦ#dG}Fu^Y:s~0n*N?93\_љ{m _Z׌7)BܡUzKVp8ʹ1ƄO¦Z,c M'{Vc!;Q oz } G!<5㸛 jVۣk.ɇLdys.A=R>p qz,z%{k=,9\eƌ4{[Vaֳцe6k˥UI:s[5x6_{\uyBaX͵~3ۄ|Dy.zS,CY ɭumUcAx|F 1MmhAϪ^,vՐs {yjJc}rYfUia=g?\k?2;i3UG_U 17z kS2&=PP;~vp]9.;mtI[C yltg|ͺFz<'+U#h zCT]:#w$gnpevL7lu'lxrr9u'`ykSNhj#_ø]Zv=1=Y$G=N)mFq2_(7{-hR3 ] ^SGmZLƕ>k;Aeɸ+鋞goNu X6彾_3۬3?ځo\XWXXò4\eY"yTՃ8(.h%'Ysz}^0ny|Uگ+9i_(`}M8dT2Oq5*l=aP`I0~aSc'ٌJ~7 UyǂGx0yaaO+#S0yG]=u8̮I"ThV6ݘ-{ oe}tU6޵.CE?l ;FV.O;]xuNV=EoTV1۝+.,foe}<nb;߽QV7g GճgSwmsŸ 匆#IV p,^u&,VĖ+/^u*{ O/ژ7yXz3e~ٻ XNnZ=~Y?p orO->e1vsV+GUgAF9hڐ .]C+k~aʞu_r63T(YKjzN<f}Q[z#zIfZUdYՂvmPsx#͟?ۊ&s[>nz4ь,;n{.dv|gO˷ <=gQzyqvZH7e~yAeW<-,15ۗد{v/|ސ-r~R\yYt;?f=2Qw=5s9-rSx<:@@{>*+Hׇy 7*7D0lfk-`wY}Ny,6Z󅖻nlpc7L{cH=[#Y6y8%P=:h_̿nO=cT0ykۛPnSGsu/#һq scM{2!NQ,M͸޻]H-7(fx28<=gUND׎)Ӟ{CR//H=98q =|=} ??[Uʓ ߗ Ⱦ܀$鯒wK;`O@伸OQ:zkϕlh_2-|b5}7DY]iXd;hFLeZòXlϬ&~޷CW[5Iw=2;y ;W 䠷`wcIܘt?oB0-x]W>GOiWI@SមOGvy߬j![δ8}kk_"l8)|@[@6b{@q= ALZ3n88ԙX״Iփ/;aiKGY?+Wd!ǸJ詐i@KnG\.~“ [}븳:^ |Z'~G.''t#.?I}{n{)/^@b{DنLF+uYqq[\ پQ儫ڏ8&?68eXyYů7u rzwx.gS 1ݸ1W,@-g:(I[;/OCp{v@p3о(M=Fg!޺{l qj9a>w:h6>|b\I!˯Dꞛ_u>ɬʼrCV>cP9;SiȜ}g3L6{sgQ_8vNL_ +NJl]}٬Pvoqz^j?7V5[N}ځ?: VƇs}_\=m{-m^;>Kr~:y#tg}p(9VytUiQxoh OD6e;%kgsĪ̈,3V6y2KJ{;@X\雓u^忊 ?5킡߹a6~rAؙO-b>9s~h + 3݇s} R$.sg> ,5QzTYޔs$Umbcjx/{K֞IlLm]l_"9 ۫jgleVY8{x[\B^|EkWcMizLO_wWO/zNSv\qֵ'nJVi̼jM'^[7a O(f!kx^z w6yl_{&zO]V?'A@I;/ONӌJOltv'x+;'/{IoyS<ݹR[r㜤9"}~06].Ejm x7x0=vwel=&`WrgTwߎA*^Ehh&uhKߨ|9˙lZVꁝwb{"lZh@go 7 v]i9y skv+6,юNr$s5.%N9J=>~ 5ғx*)yEXzXJ@Oov?b-(O6C_U|}Wc[>CsW?d|oYl~58~@F#L@> Vta:Y mװ;_#.4~OCM; {ɗ\\΅LEx8jA#yI'tA[!celhV\58%w&>\^?Ƴ[Gz\u᮪w%UĀAC- <7/ |bqGu Y [!߲c)zabtG._Hr#!Or.xθFM}zB ~K/HODF;.Y2$>>[\`] ;&հ)l >|&z}4omy}V>b ]SƆqi? mѰE@|ORvQ%]!e\ڰBuQp2wGģ;%|z^sC0x"&7, w]B|ꛠ{'q߄'wk]LX5)y #.>ȳu6ҿ^k{h/cn{ A6W5=VTU,ɰäۉrd9-/]7A6c½_BKV>937#E^q=/.ٻ|'ۜPK:]`u'7p lrk0zgr ~~dKNSڠP_ mg ͗gKRދB|^lWMf3CƬ>;-qo@ZyofwO[ʿx9[ OŽxR/À؁6y{!?'2~cr0_C q6*#].Y^]yY0ik|>cmul;*ywq{T1:u ڙBX,ݯ|1rW|!Gkv;ScةwSwhq|Sɻ{ ?}י)mT2R-/29f#S?H59eTЫ5b]އܥףxnrm(UXO;zޜtjvsa0~S!Vk}4%b.#?)r3]c&XŽ]{p^~/w,ţݓ'8^Ͼ@̗zg2xgL$D9??7qQbd0D*[`hm@~jGVZ{v1۬;,ʭ>S¹A9@y3c 8㣸^/{HI\jqM/nAp/ 8^| OЭ*0WMc1帳._)J^ cZ^H >xg&=8lwiL>vrT|c?oS̜"Na69'i.f{ikAw? zFα(s i $usλ V{,{ܮ~{b(izo;)zD{_/d(M KS#K;03ng%f.i ;7f' ϊr<*b KTe}->fa=Z䳂w5ӒvshK^7&rW}DX T{U_>Py>Uڃ=.Ԏp6i[SO7(i:>1=#3L98WtvBs+T.ӴsqoWhfcd~5A+֨l8/ho1N"&kC,F>g vssq=c+n#:} ɷrSފ{RWNub+]]P&l:󓷋6^ bN1 e\vC@ߝS 9P-OluuL+%f~cr.o'=]6=7fd[x'>\_$nl\_ ]*M`11N~=Mü Q[eٮ Nu΀ &O.@B&tCw*W'Ζ0{ǝ`Y*?}睈-~#_(.zAղ^6s>[&僲C M9F[as IQoAe4iq|0FΚ%U~-F_;$w!R 8E"',E>8>}vv# v7-`|@52 x7~*nR(s6{̹,9WʔjI~ġ(۫ m {g:V+>'b ǀ׿_繟ŇüK8>>s>M q*"}D$#8+ޢltn=Rjs*ַVaNXKT1N,BE__?Gz4&BPtsDc9C͸]7cMʝ8+/^~~C, OJ`ຏ~bRs@)PlqLU.V]])Dz0٨T*tb1s3xG'ņA})t89 >n˗ךQ=>Ԭ }! 8i39m+m|j).Ƥ.7k廕w +k+kgs |;^NCVI<yqoזģz[ߋc=[όRڰ@ ѾWޫq3X 9->$ օq^ܠG5o~wҾ⋜T?NF!e)lNV }EO#W֘mKM`Ze:pkے0˵|t!Xx{PQIQ>lSs50c"1n&Fʜ8NyڸfR?kN7IsK9fd.] u밸Vޫ<7s.,Մ? ŋfɷ8:d3 s_{W!oq6oXCg3x06e>c5~~sǒo˫VxKL_|q^砷_{Us&ŗ:ya /729k^egYci|Xq>ӯȟ:CrcUtB2DnaӛS|Z[+? _#.jtϔJN<6U+SOg#Xyz8_->!i^|դ _p iq4b)3?.9B$վ>uay1b 9fNɳ3%y=E^+t2iS-!^._8ְjt7Cwo{%{AN3nWk:1Mi֥5+ !ynw3kkqnqNqh^GM&? ,Ap⸽یRkEV{̿Z{wZAbe;"1>=)!O?adrO}vя#CjwN ?]S<33TnA֋-r [ }/ߪB<¾"IYKj ~3o__x>92PW gڰzȹaHj Rm-xN!xq^t|niv ^GqEb+Ǝuv qS/Ŧ7>^踄62a:p72-oJ,| SGܶ6seiyk:/#2'iמGUk+fl OT8L txO+g :r2z]n4ݬ%:7x^lFN+ss.ʐgy>^!a=NϧGGΖbPىT?ZB顝:#aOE^٪Q]^Z23<~Yz*cjI:Wi z/e_4pj㍏wς-mv+K&'+G|cuYFn1;utD(aPypUpm9`. ^em堛s&rOy=l3}qxH&ެ-\b7m 1t341c+\"?UK/Iu~lfٵm5a#>C`ށr̗7HOc1ݕ/coI.Y67x4׈S|`\մ xDa9}|^hC @n7^?HOAXF.ڽ^5Kre.OE},_ER*lC?H/#c./9r;SnS?vmib͐}!쉻])D*ۖk'e{3VF;esB!!5CX>,}Y >. ZK?`^yث]RYz/}Y/= [o廕G0_P6Ŗ]/bd,dqTw$=@ls^'>!Z7O?P69:_fXz0 U|9FȾb϶s"tizab1eҔ-6v;Dy!z[Ð7xrpoYoCznzHu ` _r7w#U3d|r'y.9CxپOrk0N1&A_#S~;QXR{Mv2=i-7JPiII^+IؓþSJz~. ɋߥ7!^KTaȿ,o>qrY5%+YɮU6M"ON,e7Xݲ5CUEعxi6 35xqF]3N׮?.i'eEŌ ,[&t2>c2xe?շ6|lɋ3@mt?M\LwPͳ:'sE!Xp&/mxeLT^1g0R6ۏL MyNn+p9_p2GfOnLvbr&2#?y118u>1|PN-zιX|Q~&TFdvץ;tUV!ثN ~%90HAΧ ̇̆2~8?"Bo+x}Ei(&>l>kcz?wQ3W>)O2A,sNOEs<^9%v{cc ]$(_c>[Lϯ5s]ne􍌣NO,@*֙>ޫt~V3>(Y lWOy6g X!,Y;K8\qm rOĔ5xrCud17`/$3(ޫnݩ/Y|eNlڢZrv nlq&~G߬,|gKmN?{~b q0@=蟮M[\ 9.h?/WyyW:q#{_{m- VKy lx+{m@f̛/|xjWE^1~a|z惶jz~$Y̜ =֐ΖΫ08_˜mIzohWU>/-MZfes\pLs_-&Pqb|XOlv׹ٻ"[L`Gu~椙=9]WD\X{x3abl=po%%8F~+rzBGKB/TFq5{zCOsL]f!n奔RqX,Pqʿ2/d3>/`*"Ji`(`X->Mv)/NclpWq}z -Ffftqv=?q& DV9)/y5o5ZtZ3ߛ4H=^";e;Z}N"bQM{?08SIZX5n*~n1]}da'V˧Su8#sKUK/.YQ.fhˈB/<7,o3\vU}*'=_籈븃jke~-33]g_3zb_Łab{A+adkJCՔ(g @ cz?؟M}$}&|Ma8fSWL}cseCR=|q^ \'}6|}My\?cE8+Ut9+qD|:ȷm>b\.Ci Z[|Nd<3|5N9mnuuU3mlX8qSʇ1ZI3fޮl(B%8%_y~lK|ndb#.05sh!x.^W;F:}͐wĺm sKw(ɜ>6wNk yulg2,'|lg3_}/ײ|6gyNx ̩r^IB/-E/| (՚ii+xɧ#Ƹzš;0(Wg~ ^χ}qgzt:9ӱxrj9q1=l{;;z ͖s _5nPS/\~Fb|bCu'f{`(JXMylt{ödi[Ň9%k׼٥I(J0DNqEs<(3yg>Q_c?HvӅ Jȥ"9xMQ9 6wƎ6po5o؜!jlZ9[ܩplaݡc/C^a(L>,FDgk\oC=G'./J˜__4\ZCvtdgOI ,ϞsRWJZ=aHX A9bO(G;~L;fҏƜs+Qge)]3vޮPƿ4F|;, o0>{l}^K\O7Pj0q/{dY2SA}LЛUxw 7L'|v_4ޜsOΘ3* U]X-1_}9ytAV e8|9Fs a,dW[sg'%ꄍs{U`\zulf`yиS(E?o17|f@ |^krsxv?{Rwfdb C^3BCnKq8 ?^M~Sš3VٟR]u9e!%7?_:^M;z:%7枕ІVՓpF6t_fߋ6L??q-a#\~I2!1^P5eരX]ۣZOߧ$3cYboIA _e]~ǧ%*vC7p[=cuK_Ӕsq?ү!|uK͸<'|c;pV9$&*.^ MA<ӏs9[A/O?u_X 5v2ܚys~{g2'@5{/jVc-7 S Ljya 4SB7߈{)ƴ,}U9^OS({+N׍BF+^$˅a?.y ׷,W6J;] t#,˵Uf6}NXorG ~#L=[br 9=>-0^=wo,6YD3&_{7@%&Ql{☏` .@9 ~*c38G|x?'UC8Osqw+6)!J>;+oL=S.}~,[9̯mq&~)a]mWgdOlv<Ǖ1Z" T_P\|㊲b+z,&asu7*NzI|uUБ =/kH9{ k׹7'o\9ljwqi/f=rG &fb;6$yr<{ +b2/i~>a:⋜jѴ+<樗vϽG zq^. `=#_sÙcb{k3e,RuW+䗎-߷ųeɡZɂ}ƿyqئyc޾^vIw*NY,3 ͣtk|}bZc93п7bljؼl] UüL16ī 5˳Ojs({\Ǘb{Fo F9U60JwNAי,֙/q-E,0tz x Gf4կ`Ǘk>6^{ZwF}0[֌7/c"*w'9w) o_1׼׶aߵ$۩o^nB]}?e<OTӞ<i4+dWb9\sjLǫfl7qC>-εڲLoᤠEnk@3 ]V ?1݄ʥ=]W>?m`A~'U`%Ѷw_!^q e)%EͨҎof/^s"^xW}!E|M<[Q&P/R|k zpڤ% onhٮ1Y>)[T>f{)@'S4#F l{~kIڋ3Jj.1s&2o)UY_ XM4 ஺8]2e--U+s* 7k֛}?GMuΤ/|k螗WؖZdrS?>͒hEf(a!洸qO4Ϛn^|̏%k]c#<};;p]1kVu>~>6S,Y ٺ`Gd v&Z;Gmu_KgjΚ8oݺ;^ϭ⥈!N P?o?,S$`!?},1jZލkc27G>>YM *.+L8M"`LU|gEa.wq<dO٧}mЙ9M~3˯_#gqt91hï3ElIp>fU2P2{l/fYNbc q79Q1SF{rCE!Nï^Re}s0޽MQ{^kw G,Tha!S;KnXa$6]VrÿU~<k!dB.;ؒg,e3w.8lq~Yփ#I3o {p)|ٯr01vy|w|"U^^ݜ+͉C q>Jx.+l>g恇#hJIu_9xآKď J8>{&$FWz>zHgyZ}.ڡ9Ⱦ8b(n;G|KGC9/<Ɲqs&uSzڙYb/چ >>;?|[yDHn426lwƆs>98t)ClVfp'1ޮ$P wq(OcEbuU;dkWio\Qyѧ5D;㸞b%^KoZȟ;NWicUwf\3w]ЅO}Cx‰3Nܒenưt+z<"f_9l_[\O8еA{ kSq_>_u,77| tCۍԣ:O?Ö_z\hFQ1 ;4w7AF3y_dz?_1kvm'|@6|ϭ"'PLnDAw.v+q g=kw*@ Ք;/ yd89]h\,6͙򁤭r;|Ր Ja=<󠟊9zqw5}f)\y;0C>9FVɒZ·ͲܵwL; e;Psk9n>Tۢl| :qrV湭rrkُޒ_qulpG)BzW 'twٮY ώ|?] {7dNLK|փUVO;,D\ef4/Cq :HA~(Yߖc}Gqx3@Z$w,Ln 4Y/ZGχsWQN|j)7T+w9#-^'y;rp& ܑ(ogdrl{/t"Z}w/NlWogmM;IYv6OWَ94΀^53Nا6Z*m!xJ-1g<p/k gzq|IҐcH;@u#n/ ^9{&n{|gP,؝Ȟ}΍Z&ϲu*cd)2Ρ,n1ɤeW اv͏>?CطVK_?1yA1/<版o׼&}5A1UWy@rQKT^wn?a-wCFjUlJ/ȳu:5N:0}T> <.am'.mJgNx s]X+Mp?{9nh$wS=^]]tJ!fÝutX3) vȓY(Ub{A`b[ϦKlVs)ξP+or:w9~T1hej|O\,SI{$9'~-]=-]mNMo-scYZ9{[[>ygOa#]umי+ZrTM7jLi޼3 .LsZ,AQ}|4P,hWiW[TC]/uSA&/\(2̍_y3wFuO8jg {˓ 2Hd\;\g6lstX~3 uw2Ț2tۀW ~վCت{j89߭Pj<C9Cr1HOof9۸Ǝװ_J Ni!5J7hV zB)ㅜPSf1וií\pԊvGީ\~k%<s6 2^g*?bW îT,ngi^O. VמYT+3>a|&tzF\{ HC8/߉{?/![͒jgv'qW:ob;=|;y͒wC1Hd|q_!zzr/_w<9c~U%>}I8 go6/ U ۔==\XBtE>7fXgIGF}ډF19OX\ȟ=%!ٔϸK">zstHfR'| ~9[9qi< Q'!rG㬷 ,YmvLBcl\>Vh_kw pepG;rybO|v ;Cs'-"֜|ܸT |ߡ|Ķv~͌D敧z*AWitI?p1qB%J>M8auKrj[i#_Lh_0v]˴)?52Jd[I[. i +'vqkAOُS>YB'р}؎P\vTgdCg |0&\_a+\tzm2[o`''|k\˽aN9m^ɇ| xԟŽ-!Xߍz-v=~ <ѳ&Cfȷ1^5ο<M,P|zCwiw t=9(y/IWou#kW%Ron|b%L|n-|}10c9 $vJ>hj\z$Orܛ_d1ZyAOz赐ۈfbޣsFTrNBk'B~WBrGiXerWacs)~Mnqn ߮;,{2>;`أۦs˗qGA^u /=!@ŋC=;)lg5&qq9MMnV߈ø7+ɫW.9eW4ռ_[^(nԦĸ~8.9s_6!WӣrV5ԏ&+R|Ƒx>Ϋ,&͸pTUwB}Ѷ{P#/ U |ҕP1$˰Mگ1r|3 #ޚxm t^_l;t]:mv=›K9fǀ|jpCP݆;wrjy3pKAFHE\~m|B8*ZI?1-%*[;s<|׌?z۽ ;95= a}g6\3vMx0,!OLobJSY/`*nA%sVy9u>Xd|N&2mS'*Sql/ukmVn`F| {ݺnvO '͹,7M #=n?wm{VAأCJ^ir, vpaUg'^Щ,EXg%.O^d[H*qmg\M9C3C]Ig|,ue}'k ~ \dG穏k75L::i-f6ɌPNxs|\mdIeWPn1[<v [VwߡP9Gy=%"g>E>UoR:kC a;bq[+n ȳvqa?q8sX7|z~^qL6{fM6%a(ﷹ! !]a+31~B*:s׎9&R}yR?ڛf#=jo\EgLc UX &2Mu9:wJmw[,Τ@ua9gF0Lgy-A%lc'_hk;`)t5=*{a Ļ<Ί5 GŽj6{߬WoG'`}}FCEa\Uڎ]llAI]cd~Jc]|5v!M{RVƆ͔4~i/vԹrҎ=RL%͊`m<%w5!` 4@uFe_u~nWkOI'cLZ؅s1g@\ܽ6zULSs{4o1[3n>p2Ҟ_ck:?fr\WxNԆW[xs<`J=r)Τ3Q'q1ŬVQ'_*wm R_'.kiKf{awh]NmU9#{MfW)Cp6YqfMU9'هk32o{0}6U.;Lq;SSR_I| Ӿ|:hg"XHA|,}爝4?U=u>m٣I*r2K?u-ر't=Y\o3 jRuT>(NtS-^+P Az} Z 4ĥ]b?*yaӅ:_U')Պ" ,X<.ݮw b"L /hrˉ N˛N8e.I@rr27Y35МNGv3]19ѫ- ȳ-4Oz<+~sAmVsJ~XUHo04^h:4?oR2ݞ4C{i/ovs-Wk2{^ԩjXb;LQ<_G|P\-|E~c1Z:S(O yL4_3Lnz`9A>ŊO*Ϝ_ |}bI-G޺HC<}6\gl~*ׇs5L;g`C up8$yI1٬AA9m滵>|nz0RsD ]Xr&l#Q# sS[;&]}&|=j.27)qHw ʬWfV|;0E]WsF 縊1.mU9NQ98j9)+bT5.OtI˻ ORG {0Fț,}άq8Aſ{L)*i]͖r@J=fGT~Po3fԟY)ZOj=TU^j7}fFBϘ>1A/ /Z(xB͇Ym9Pz5GKx!a5Y{~|}}L,кr| z:,Zdei5)N\кĴي01Q܀=E}֭đ;g|X9jc,0/מzmhXf}.>P1 =<+Vs&o׬NU&1 KxsQv~B3!<ż]e6V ]9:0S2jrڰ YS1^(n^_q9{fs71Ngz/oo7MߌpiQ?S;5GIh'ܠ; sӺIqhVc܇X)woo|b1qŕw,׸:ھ:1ټŭ&{X C>kblmwurl _L `_+ϟ mvL^)ֈ:OBUY~Ohqq ޷eRK<7xVG5jŸM^; ڟbBNG=&GGIF&cDGh}x-A|\'cu#Μa69UU#R1XP𾀱;R˼OZ\wRGX\sɜMu{J O860JW7(Y 5^xH{U5_s3t2In> qHp_O=̰@b}#]$V7zVѺաhl0AQOd\|z_v{taBs[FQcκ3oEl}3z엺[mX5^EnL&n™Uw0'Xnc=IA9S hWWbS{{6xuIDwsQָűw<{`8[O'brP^Av]/9 ΚVV˫VDks)97?(Vlbڳ<3bzK&gl`9QGX- $\?֥OT\+m+s[+GDװ:سE}Y㤬"yŜw6g5K %/[>t?&~QM̄}HNѩ3A%G;Ȝ\ux6^Ybe(B_faO}xZ= łwYn01jr!9Nj-hor1xM|rd*f,{|~9k"NƬ܍'?o/Sw|. L %>늜 [徶_l5ffr^RoޅyOw1a}Y!N|ѲQu'0ٺ^FgW[3﹓;6FkKg/9b.vb7/#{=^ǽKI-Z/:x@cĞt Ɉx@j[vEoNcmdv+Gj7 c̑!=ΔJXuj^~y*#=kY,-o=2O%žS&/{C{kϞɄG[ZqJdv|WK|uO|ɩI!7k?x7vG}j7Mw%'9G1% ^K/G5;]Gw/.&gGx6;HvyTb.6h qVM1O1d;>ǩw'xd>H}MW-LuB:,@0"r|޶z/'AýLV&mWC&x;1Y&{'羝̀\!;=;>Ľfq=*ǎE^c셌]ʳyO<&yFP>/p$2G}ګ29Y)NsrIRr`S G1WDo& Cþ1>w^+2uw=|"V,w wHLS"W" {wx)C.1pg`8}L{5[K._=ȣ r""8ka(6b-P´/HlZHu3Kl=[xxe]޾P{^7DӦ;S[8.[졜븫|M3ߔ| @sfz! ת~,>]|rtor0[3뛜a1sn&~O#d H [ Ϋy:{k=)h(,TvRcɻ+u^u=%þp=+ps#|'O8x9S#g8_* SuQauwbm1n柋Sǫɋ;"Î؋BtXr.B)y0ybp~Hq3#mI+߳"gs9])qNE.n~GpAv٫%E erUu4<5)˟%IїO߿4V1lǝ5 [&1F-M8;%&&?=x_?K~zp}w ރ-6עoaL(qؔrI΂ 1_뷱VWn;F#%&Lci@m]7Τws;7GpwL=Eܹ ߗWX\r1L=n.i Q#iXsu6lYX 8Յ\HZ'WsoW|$"V3ea$n6}d(:}Asf fws24K1:vV#^DTks<> ?g> 9vEN 򠁳Ը˻3$~bU9'^o7'n1\5;_q>)`<'^!îr W/ uF$οq~;g21["6Mc m3ޤyYiF_zӠ[nB} Y9  qBwE`O8PEw؇Zy&/WG 72߀Ebo^,rK^b\-ks1fl۬f1N0k#ӹ܍iT_=4r7d^f=*3IYf(.|yƒQ:k^ vdX7T;F1{XHŽm 84%ك.߿q4}\'r#>HL]"1D߄q;mҀAαcf;qP \ w"}e?+0td|k >|?l Nj_l-|:ov]Λkp %D:S9 }q"g*14bؗ,yd_,6܈jc\s[/qu /`.|w~&xQyhlynԉZ=J&׾{64;,XH*)n>dbcLx'?,8_)rCnHƴEvВ\EU߉[~vy{{%C5 vǘ'O"_xw)SBNsN{+fRr؁~ }^Kl_LY&XXJ[WhoJ~3L{?mO؆$]LOقcbY6pbrWh2sU򸁣PdXJ^|OѢp-P NDd|WG"cB/en<m%"'?Z1V3&w$sӉ7|{/36Cxo)K=&gM1gK^%@yP݇Oo+qJ S_1O lN: |+Jbp(y[ɍOs07؏Il|Vy[n_t8h=g46x"g,|E򹟏tfqb*7'fwӴM@[cY9YY)ΐSjվ"?6Z<'pę='BA~]`ܿ O̸UΚe Xzb| 913,>[iq".C1fʲ;!a-೧l^ISOS]߸9>rKz_zh1e{{m,:j/o;+."+b< A$_2{#7r?%6 nc=;>t"/VJ=C]:fvʑƷėէ&[TgɉqQp>cJ79ܫX!?Dɝs橽ި9faw1&\կ1Q'k^FVJHD_aOf/>{įm&z\Ļ$>/?&GOk>,vȦ. FE_a{/vE E.JdR( .KHw!7>ͳ 'r~H{"MFSNlwn669Xr=9c',p܃~֋Yt=dG$6'rb;_$:|P3/tѱ# ^&?9 v{ô9ʵDo?F_T1Y-sel=[#7:qPk;=;#ܥLZүW?!ΉqݍD|/ϽEilXkyڥMyOyj߁?.`~|ZrIA~Wϗgȍ7g_'~)F6>ؙ\GЁ: N]meCr6׋wA-Q.ΤӍgnb{kOx݀An1.^"uYlE! ]V]nXb1Nq;fXk }V{[c54`#9rgMJk`5n?G.GEk6Q+ys礙yo+ `CY ou)pQbeMtY}{X}{]^%~/QϔM8A0˷5+O:W燴v4VNg<[ {| ^1}|ڨDrț 5{11XbNp!F`rļ?.VML b4'y qH 5a[ہӻI-`xwE+ rN EȓzXqlWŎVڞM9t`GW䟁K|7laCyQ7}֐5 \fV^;^VY95s&ϳb_ 6cu]p'7pD{-cgs1"^_DN=B,b1igþ|8FCo1~5+δ]Qg8ףņ^M __90PS18sCuoXfs5̜I] 7'R b^7Ӽ3b!xrwXO Ċ;?6.N]z|7MmE #,[}rYG{Oџj6/?GVG'Ο.vk.Dl^sp?x;ҍU\!?D\'g5C&gWh~|e~1xkk~O^VrLyo^A/$;bn`e1lFY==O+B彞@H K?EE~wO6^GGcᗰ3=׾^L 61*B^(>IbGoOV=m$~Ԣ_k י;YL p b;~X^H |1ଫn| Tw){ɴ=<")>ŸcoF'ο6J3tIuIr=/ѧô>O8ֺZ8=%9$&Ø.cik-w/ORvCGO "~|ؘ+F)? kC;DKDGL 쿣r?-% %O<`klqO(5ٰFk}ֱ-N5縕gSkZg*|GoO"oÛ_ Bzj ̰V!2|ϓ\+d+b)]Frŀi9 pI~&8 `v|9>8~N.peGϣ}ޙqu:l{)W^ Ϙg><t_5ӌc3aqwR-8Mdrs䳎/9VSGaC;_L8þ,Eo y(!/ Y fuo 93"~p=ߊ/y%cVƨ>" шZbU r e,\+ιz31 kYJ㴙v5XLs0?a}ɳx^3ٓy3{E،w;3LПa-v"7À~,gR{]>b;#jɐqk㸃ZMd?#_D+}=`y_9gچ;B=q>Wo:SlkP;fiwXw'+ԫ.hgx {4L"fzdF9X7>N)2H8Q'y5/Ly=|^/ 왞bXyg|nC{;{‡)8)K'נW>*`Oc8O [>yeϤoY&]VXg>&~~K,n^soYCgYy5_~6c_b xefo Ǟ69+Y,vu;^w؏RNmq6<}}U>= />S3Kl6ޮ#>}c7n68+wis [̘$/zf6&Cg=oH >3G> swY~Wg^зm?$>rF!ff?$BlZ8tcF8Tlrxm!i&+G8 Y' @s808z&;T^+{Gw=ꯎ5OiV;ŷ,$$'9ٌCb ČlfxobΛ=GTXVƷOj]Ig"vCoh7u5KSg#)<Nq1 &;Y9G{k?jo׫v#3 e'/"6뱶 5C̙[+fWn:Q׳/*~X#zV0ODr<꟨e9mu}1z7\!F-cI&XΣ,~a3+N@p8o";AfVz}zb\ԛQŽ^m~g>1 03~cf/jo8@N^a_/圂?D=[a'ru?)83doux`gxE%+w73Mק^:Ow%kߜL%zC+w%{8ž1͙_F|A.ߝHE{aǝ%2:9Lk&hcyOk!؁0:GG*|e@EԓW%<91'W$ҙ3bԃr'~foÖD7#rǑ7mjGceNr U\X{JOuf"zLJ[e_Oq # !])^n%t,A&c 9$Z%%"Cukac?"poEt3d;η7bN!K&bZ>1r"%Jk_Jf>|E_8VqL nS3rߍQ<&}~z]xs#.HdkrK-^8s%/^Zr|}v+C o"{+ſGN/&~ub-`~T=^6KI,{lsGsopWx6gH.JlZ1`e$퐼qε<2`쐛mfq1gr[qSCo ӌEM+Xv)n>sfഗo sLϐ{K^**2wqkG[ۋ2?N_7hKDi^'63X_E|N[.hGeaL<+rhblws|w9rDGlm:L1!WC~K}X= }_bB:1/p1D|ǞU@Ȱgp_F\1:_"E㷓bԍ/)f1X ≾-a2{]|+}8{0ج=?Tb؈iC_fQ9?t\d +:^fozB2/qێ$?ܫس _O lwhHb0r.ȧ|/NEߖDx0Ϗu ;[nu>BQeh/_#2j,;>'g?X㱣2+Gg"Ύ.XvY;E+ɱW>KQqt-l_99)z2QCF|uΠ?cx/`OEOOWշ^4e)݌Q ì/gX?-W{%}z||Lǻͳ s"mF:ѩr;Sr'Ce]=:Ͷ`5+'/ n߻D^UPxVa/zhɧD53vviYN^  l=Og93VS̿nV {W|S0?侁o sqVs#{83q88`$65vDd؈1~*/0sm=8Ɨs*~#V@>Z?[o<"t^l)~ asY׬{ j|$l}wcV{uGZC-1~ bw8 XVgrՙ'kC=#9:V!d̷&2Fn| m j}"S̽*ZLD'z#ufFbO>(a*g򿢀-36Hr$.xr/rF+Y_ocѕu_Y|Mȓl/gM">gx5}ZǬP,2e՞G}}w1)f_O/s:Gt;?πKz5Ә#x#G$X,~Utr5<ع}JΟMgYGC 9^۹3*|*7=|ׅpw3{#cgH܀G[Ŀq X*y g?#Bw+tgPk13[y=:@^g"gFXcGڇ8r'ڼ%ڿD)"EäeknrԿMne97:;.0y [y(u/ {Q!u7+O'-2^bl:ȈO7>Lw P1JȰ5,8uv:xff&}ޟxmšE|m؆㌣{/ee}P%;S x1Z`g7u5\qQu͒lyQIO-5qpg֓ msWzyD<\1fX면Yתޗt/gkzzMn#H=S'DG&_wf(\:dKvZ@x3Qwp̢q b#߲Y5i^vV_#OF>]:넯F,<C#vașaw{][̞x]L_xr1DN0$ cX{9Vv"hp(?N~|R= \;|O ś\Mlfcl"Ll^/]۬n6v5pʌ9&MwПv-suQ2kdc= SQ' X}=N:GXO᛽{G8l{PWc?0Y0 ;m+xZrQͬ[{`ߑS> x+#'ÿ#n*}2>CY}{~ N۫D@󍳭/l UsYκ}bMBO`+uu"`}l?%أ0bsa6/j ~:=FZpwYױOgEb}|,%1wylWTq4s{2=' j5y-;+;||rLBX{g_H&$_ngUj߸8e3w}Ut}@vkX{*ooWn_֘@} W;~V[)z޲6E$։S噵b4tb-[A~>T.+rЏzvI.2?`ܜb$lq >\Il\ qK#ԙ#yISD,!+#jzq]7bEDǾ.ZWx[cpײ60g]&k+'&FQA>3}K"pzxx؞_qK9G{U<˜\{h7BGw wM?>xun&,c)}nOvV#̵73/6;:y.G#JbGۛįsep9ҳswz]K\gvXy&sgk>V"GwaC|8jK ˜"1O9ogۢ;N,O~ |:=JwWwln!t .:q?9;ُa}`8V߳`/Qla?nr9uc8Urk`M<,^V :b8#׸<[~)H; ?|56\CNwKNimdS7(9fS^ yJ&r- 2ݴf?_dD1; }=bY;s/z! %>8v {=+4`X3XzG4,B9(Pz3vɺD:2[ugh{)`ĕϐ\~oKgDۭ.Q6yN0h<D]4a&l }jgGOq"u.+,A?S9RQwcwjRst9sLY&X{&&>:ҽ'b>3oj?8AId9?< ]#6DzbgCyz{|/ĭ/K[n(9$^o}Oзc65XGqDj慈OQA%y[oay[$N9{8#+@ okJ墯\A}=,b9ݾ-.\Q}v#=ʇ;Sg-o(KKeGq,&ef7{bц^3Xϩk~cv.C5{|#;M{SUu/<8SOnyϓ\BJ .{B1J =wJ>KNgYRypȕ5lwt^aNb>뉔騫s~ʿGf/z`QcH*?E +2\/Dlm\1&~yFbD7Ey,sAj+E/jӋIQ_vvFyy'N?-~F[p'rpuh>I%<}"{io4dA\g9HnaT/^'>>g"ׯs1vK@1ExGHc&|u6x yZr|C8JNy%Y#oȈ\=[|#yuHLr:ymO.=+1>YC^3[9Jt.<qm""Fmp,[OmCcNC z%p+9,9ҝ__, bf|{D云3%ʬ}绉;V; yo]p ~zxw&&Fhݢbto6u~mxH>APڧ(v& \D.Vӝ{qqW_5e2;ܜ'mQgptK4V Yg,bKf!q+1ek8o-Wg۴=:x ݹm;CN_pĀXbT;h^&pQ˨W+˽ۣn.CٗB׏s^9,ulc 9g`׎{@|vϣs]7gdJ&\(qXIⱻUގxnb ik!8H?8厼Nub6roGR_K_بO(z>_gȸK~Oa1D_ց "&V,63x= %M6ǎ(a$q8''9STInbr"ӣW,r7So|K2YN^rhG;.OGaCP珝_"[Әz)b^ 9h`uDb<90Ϟ;s;.j^Q5%|kϦmX4y\]LdYt+^ة\qMŻJǕ"guOqflO8H e5Jg/~] 4@یM{L7:9{'r6 M[?GϵνF8Åױ]}]=3|$u1c$ݭ"+W\'4bo>CJ~e8G2XJdw'J^Kwoyj:Yf؇SY,X̠qy~ʬuιT74>S;_kBگZ ߱bOVrηد C=GboSP+,\sD]mS*gZ)b'{]rr4:"yb~1W>bc+2OD3V?<ܫGFs \ޫ_7>'aCcv 3CAy>ΞrV5S⊜JGtr>/*7D-ssֈR12X-P{mT*O˴T 3wo:LB;90gy^Q7Z,w}p>DJVny0sr-=BN`IYFBl}оT`=ŽQ<>wM]dy\এ/8ebnCAY}c1c%^'^=glܦuXH29fu)yUM /36|y$tػr*>4ٜv v2EYMَq OQ.kH.)~}1S, nqqwD/9>_^AW{j3Q3P̭Ryֈa8{o$[|LBKl`.(Nq jt=l*_\s.X|LJ^;`;F1 c5g90>% g|9:%{NҮ3^@;.j4c(5>ܙivЖv٩ͪP/VxZCuYkb>4 wT.kr67;mh?s%?5O`/ܖ;MX.+* Y>' ODjæS<> S{g9s-B$Cj-.8N^{!F&^kcv,eLZـ]ب =Iwvn?B?Pi<^yIzSY 97OA_>`5!%?Lz$Ѻ m2wl(~qvlY3ZQMS5.X^uٞi)yƗUkV; ?zI\T1ovCfyz]uOjcZ(&Y'z [L=oqO1exYkiSi[eQ5hxˌaQ*aY-PkO Zt;;<#3\G4l\}^Őa}ikf,nP6Ds:(QAj1|v}=^f8%Չ>>zQ!xHui+?7Y{>(cst?L!Tl >ׂI-˟g3OzK9 Z}[rUmE>72͑G<[ 9LxN}[7@s <暚+uwT<.w;Duɴ?>Lۥ1ZUY;nOad1[jymbmjMO+ϳ#,4Sow}ʆg 2xxhd.6ͺO%"KrF7{7Z k8D;]erMTZVI^ ;v=N'Vk%Pf^3V̴UdPk4Fi5Uh/XOVop}8;&Vڑne138\z{nj ͭakϤ/u?*_Z>!u0.d5݌aKpuF:ke k Ϛ3^A&U{-65{7xA ez>+c/aw=cYܫo-<_9;Q3},~GQ{4?u_v=O0X8X,4.RqTn~NeLx.7FhY(nzp?w7igjt7ϑbmC 65n'5!a9"4M6wЯu[F9Î7u+wwZ'[O}g 0dd8T*[k7Q' 'Wtz^{yêgZS>3 s wv{_f<4mvci51~X 5b֩1ØӜCqچ5樟sm6\kLf6$K`kb̬L bO7]bpf7f!2FBpR?v1nbK23Х f3hu1UG7 rh}C1*uӳSgaٰ|6`X2VкSƞub8w-WLz}e:Yfg>>%+5״2֝b;NV>kfF2Zgtvz99(c9-C{ysع| ԃ6o9f~t|[}l/Z쐧̺g3,GR\z䱔9гFrLlI}E/b}Gn&cxTbSup:K9~%u8fijg8ƚIXsrc8æ;tfsڟ)XX ̚=鰼=1ke-916|ڸrvo4NβJZzOwh5zU}VR[g5mWؗb96U)Q"!zyi{QG&yv4'Y G+/3onC2ЕN+_OYvtU w9whW[dLvBWei+*fʅ]]sueܳ.W|Kr Ax[|u{?ѽ #qB3{ڵ?GF1GаËVjR%s(ݴ?VҔHq菪:B~$reVg|ޟ5ѵE"cy]bܷf _!އuIyU}X|](y+(:="xr"gA_aZǯo{?pRϙ׍#^c>x.[kyU.5}8;NS>'vWmM_BëÖ\K,g0[j!~~1MM}z] ]sUsŮ!Quf?4gO-{m3Fѝ,ܩI==΋nDS"3L\zV;kh_b1fU'|}溴Nx_x%{48b":5iQ]XT-ruܤ.4}_1 *-"#lS| ?$;8O)y-0nsŶdv]&g&_M)>s]O_kceLqdA7d/F,=1ySԎ41)ZRh]BmZCqCuNB_jrxR*%rNpXW;U>!sEνs zo e?gE=fqyAgy< 3gϽx>Esft&Q_;2(vD)j?f_Y?@%r1[)'q_Ǭ\3/\snJ{1nqr5w88g'&zPP; ֙NatS\an)}A{ҧ=|_-WsdRtow&ξ[V| }?Τ(~l|]${.g&uRߖr6^J}D{w`ؗ|LƤ-k2N{@1U}?CSܕKѶNթP^f4qytqevr#˵?]NpA)DwyRG\:e"SD7gs`. }Ul E!ܺd9T>'D5cI) ?A}{1u;KuOr57ve?X{A'9Ϟ9Vc-zJX'3By6WpfYCLZs)VnL*z{aش#5-~H ~_|3NǾ+O{8")cpL+9?W9[[o=2"V{;B?'p{pK'C{\LТɵu 5ž͍1 qY~@ _X>eG'S{ɹ CQa(>sN#I܄yĬzAK]OC"7_+z+={԰*M-AwYς^ѿWd^-{Ež£un<6dLsIXw?[ޕu?w ~l"^9Ħc;mas8\| W{1!jwW÷Eb+ +M\?k"!:4g{"rRwؑ "Gs\yN2urT91z1}++:w6KӇw$į}AtXoZ4,0%!;{9h{L4?9ⓚ\ÌKTp®޴s ' &-#ōLx+|FlCQ!v}=3I97c7y5z3M6dȳ.8=ͯu"y+rsB^kV]vvF>GܓػW$~;KoVо  Xz޶{(x5XͭVoAYEn[[5x$q\ݷqWspYtE|_Ž?D_Kfd?s䡽:ˑ{ιSmjRX͹٬~S&[pv|g$N]+[pvt'SrgS#Ei!$̽*_dk="y%nPWͯ)EcVs` pƈS{tܭ}qƻNuy܁S6` vW\,;$}xpLuf!-++;CX& Cre ~\x;s]L?sD~g U?SOWd-'8j5Whgw2$~E5kuVla&h],̠\ڙf`?,vZ ~d݋IA u5M7aCmԵy{ ςsso_<@uv{59' gv'b.g 9+o=;c7l#{3-|E-n=?\c>d;jnxv8~14.fh#p_ܐœ,Ckeיw,7}[X!;g}Ve[ʶS=naGW`%e^f|ˮ~vH Qy)m]1ڨ |hƭkob %>?R=W \t:#raR([;!Kd,G?YȗxC)*}rwSwsLr5b_KscOsO)-v=.35?FSl }gX~b'd|Ppv3EJ^X/'o܈q3'gtI}'yբ a:Xż,tbֽ.bET=8s!"gZMʅh1؂MONQDf*AeA.=)<9˰?*ѫsclJw%Ƌ=l=s͖}),%GjC&'+5@]IhދA~3͵ufu:GZZZrދK3-DmSrc1x?*g 9?Hw ;_dLyZ=럡ͤMRLfcsc20\%!<פ~lj3:k+?H0gN~4t].XU9#w04v#Ovf}):߹^pcAlb(Jv1m[Dw'dEn"<9wg-vN A8;q}ϠMP+{զ?ȁ ە n M{|lf8)6=—0nQ.#^Tz_|\$};Q3E^oEkqd0?]W,Ip?.qp>xh "վNKa}o3\GI̊]A*vawe=t/| 띥tC*B OyPQeqVlrns/_G<=+ȯ]|/ЎӮCϙ->lgG@[Dl[b ]3?L;>YS*<81cL޾]%'Fsg:o!Wji?syr9p{>2'h'I t٫M5aUS!}9fùį5;aT{}hqNp~D7l!">]ط&r8)?G=؇>5=̧onEclxu|5(o7/2KI|R>BܣIq+w/!owAF >0\! '~!2%ƚI(wɇr^'ry]i< k6A_8+x?/Hwv)r|3؃x_;ɐܭq?jfj5Bs㏙{D?AQOe;-9> .>:{'AGG\>Ns3 n!BMܨYPS,B>mg9uqI}Jp0U q+u?>MXKϦkRta#r'akglvAwj`t#7,s>kle3|ˇզgn;O[L}q!tݕ}hqgxOj0'*6}o{3q|n@4SR#G j&Y:F)Eݫ?T; X0n=̟6Lp'OCF#s/8x =\,{ַş.LyA_zwࠎ(a˙:ʳnN \ջQCY׈9r&:#c6%0˹ ^sWb\aF4 q8ab;7{ GF/=`1ѳ&T {%0 8`u+w{Idc ܏)} y<6Xs~MR)8:׼$γK=C|#D3e'~,t`댏a;׊mpriy^HI: U/{d=L 7~RӍi"bs$&ϊ]%eY;Ww#TwE H>0Հ5?x59ɓEx oɵýs0QU༆ {u]9TD|N |*u\ԗ{զ~#->#Vn7_-PZY)wKV>o1|wgD[s&BV^'g^'$8 =yTG9#=Б;Jg3KcyEGeF}#M>|7؇PC.Fy> 3+-bg~/A!.n)|cYG:pb/;?yIn) #w˽wLEso%bM9Ug7'p~?1[u#,&=a A\y\X:pa+D {\њ#5{eSO5O&= ?{ͯ3G > "OLtޠ4grdm:|rvcuNg-8UDD WQ:w|4mE䖝/zky}2Vpg/_N7 E,#Ta?%Zc>>ُ]@s=u3D`X#VϺ}"_7#r⃈3?sy: q+͑,Is_Jw7$M#zֵӇ^wA1WgoH +quG2^~`>w΁@~a'QcsB#pkfl~@yȷ-L/S"٩Χ>$KCy9^J2{wbkp9WWb\[NpWd  pFLP+D2yu%+@p'q8H5 &aNϸ=Sg+gENd=gCg }?q~ꛯyǞb< Q~wp7v\Gpq=a>a@>a=<ry2Lg%vjaEW7l9ww{#%Ys}3'9_לb-g*" &E2u̷ NW9ݛr߸qf(:g+N# ;h#z! pO>#icWvaܗ)O3#'g&|pDUYA+6qf07(lvSzi"P{;1[9E?{+j qlt?bCdͤ3T<=kQNi/je89 ]fήh$ǵ\)c [GߓP7G"#M[sZ/C`hyrɢⅈ(,kvz/ޗFZ=I9=X] $Spw.ZLX|Fdb 6{aE^Ay[OʾqΦ \쵧MFB, XTtIS,t>h9n8nʳ$g;˚M^s4ȱ_>mB||[Jy ybXYfbײse]*ׁ:.7&:JcvVdԷrw <[ Xo&g c#ќ𯙷RF=Q!b >Vs۽tCN浇u1>mS=sW 8}T_Zƍ^9ӿ3 ݿ.Ys|X ych1VyD'Bg ZwL)2`=WglOPǢN||꺰'oh#p{Wri^sZ>N´J?;|Ygg^2BLu/m`pn>(]&Ms E؃-1P|1(>17gaƙ n;DO{pOȳg}~!s#5jj7:D=t@nY'`{g-|aq˭Z2;<όznkz篲||~w7kmnZx9u'S?js|Ov/:{\'WPOKyGo3PT^dWZ[q_mp98< .6rYmꦸAt{Z1m1#b,ڿ!;d|وՏoʙ~ķj#sh0g:v'{ng#sȊDI6h6Nbي:C~,0PNB<3x3 N'/\ⴣ؟;½]Cw2U/ ;gҙ -أ~\knc/||2^m"1e5닔ⳇ5tQ@D|fo5J*)1+ V*9W=s[eU,S/H7 \tb6qBr*u}V1fQN`Tn5N8ϡTI/5{wޟ~G]t;wZ/zd=^륫)>WAkAws_vMIӉ?@ zܨZߞy7F_;<xx8Z/gus=܏2KQE5іx?pCiu:>0}`y 9δ9By{s`~[k^s]Cxv)=Ljw5{vfӍ x5y/m}*gZl04w_K. 98s|[/Y̑:gEpw4~`BDZN(;וs̩ v/Q32wjϞNЗB&;4E{'Fo;f/~O^MT=~z\\׾Okq{eEOCTnX6#6+d l&kPgd~@=|T ^ڵVwO% 7S+)83GyCVF䋞v!V9^Cu:exl }|#_> dS9k29ۈÌϥ:|W@/_Iܞ,)e(>fڮ-@C={5Qt+>;=`_y_ Y@Mp?]t3 FG{&kܦgrL+Z_L̦3[(_Chw h@;~ݵq׳ΐrSwZ37[NFuKiSrϦK%ko͔%sㆭq{37ɹ9E~~DVE''sxi21>P:Jb#9o8$E v,(j-kXD_{pJy,<KŸ&ӻϛ=Fg?gLv/j/ t6%2~3^g6x_e9˙Dɽ7$6g[?v"D|:zcKɮ£͆@E9By6mZaXG‹^s:)r䛫8ľ}1[83FCBFdD'z?l6"b*G|c ᾍˌ7Y-rXkE?p)EGV;SFyc7UDuq 3N']i3sf`v0*Ƒq/g\_P;ݘ`G\Ě%um5VI#A}F|>hL!-'gNXr[:|>._˽6܌;́FLT@2k  El"w#9=Vݨ}* qƬ̞*9"9֤lsgm~Z~l7xW`gGGf/s{XS?n6?'g:51fjN2:٣֫uc' 3?<Q'ݛ )הyK<d_q zpy=m%}Bsy]ʹMArw$:הc?ɻ~^4~A2Bk:էbqƨ1v.a^/z<?ءFHl>j;Z?*X} 7gF6ß?@l32<Ўe!sÈP| f\יI!S/ѷXv5 \36V3ۑߎomȸ{<&{_g}#F 9A|ʷ=^u#{)p׼GXs1z7rVyq|2PgĜ+ŨAu {GQ&eu= _z\a\n+>Y΋yrw%%b痹k>'gAb#7ƌQ=uw?[>9rدjutdv:'ǵ9 fbQ9=ϾL+ѳ+D)x Xf@ }7}v#M>>f!Ol=NV9Au&G亾8:x{Hc.Q[/ ({@fjk,I8=6ID}uO:Zny٤UbǾ#׾ISI*|3^l=`N9ZD^㙞٠/Iw&hXgncxbOQ;k- Q_Cr$N&̆VK&羗g]޽*gunvwy/ڧyD<ݡym ߻\@>,`^ Л*#4cwren<^b /ׁn_R1Rpm7٬?UO}FeWf,?{}*@@9U8W{sҧxy9Yǯ8gC"A퍽gh{na/IļfWPAX%/:5=o6ɑw"Vw wg܉c{aGj{\-Ɓ5-<챋Nj$1v/q0:co W 3'0f6/r-y%w!u @M.'qޣԆSoo0{^BΙj9;.eWۊ]_sWsΛ$).);O>Ҟ=|5gCU9cW̡n.rzaB@o3n}V N+k>u9ؿO?u}8W{"aMXleqeAu+ZYD}qܓ=^VdZoLVl+I麃GqB?gOԠa5MmZ y};^yl+[|j0;3^gI@-Ko>(2sw*qo5\^cv\Ծ}CznbL ӉyOS[l~tbZ [&v2 Np)vM^/`[MS9ڠ;8c8\|ܑX۟c Y/V7M_MW:uk3&5y>8>k{y7z},}9rǪw7QF9<8k,~(m%9,ջhWX_ =DKZi^"Kw?w#z 1W s  vBS9:uN\ka gvA31~/ۀt$-?ld{ĵ^~`^ y3<)|?_k] 8"PsV+0>Y_#g7|:Lc=hON|6ք·6m$Ae}Æƹ_Y绦bi{=0fLztƇϲ zt&ziY2w@/=3#2$s+ZMrى[y*> !3_{m>e)Γpf$ÙFO[>NݢGg8FXa/^x,gsC[(c`o)#'9h;|Q"O > g3nƊ23^j^w XG՞"aE,!}b^^C|+::e/G}Fgvse^sgE挏$Wqm۪9 @a4zYuvxSJx~`y ̾,kVX2gzڏڷCuAB  }^ǎ;7hܫc&]sŇ$ cLv EFx _Zẫk[tRq[=bo7vf>`b{-%9oZ>ɜB$MDײ78?(m+q<闒l/>93xYyY#+_%`NImC5ӻiX\hX""349ĵH0t6I)rrwZ:#JyL#6X9hDئXKxZrofƂ;3\ʸ#$r|"iDku=)ˉPGrȸ."o19av G{s[cP_@zchr}[E1mrf`؆u/%FxX! gPl3NU3≰$IU[Gj7'+~%k8h;F >'~:U4A/zP`->eɱsO_|o3m"[P(M1#~߭9 ygz4W쓋/_H%.O_Ka*3Y%Vpr?6~)R'z' پn;ދ48ragS&_\3E-mu{ky/~iJNGQQ|맘૔1*2YЗ >Եx"Q)7 .ڕ>Lu~7vt: GzbrMŸV Vrt/=uZ\kFo^ d$N; /nK{3yN0s^9wjJtn3E8/?YfƸ9o<42?))Bvypo)ᅢ8!ebӗt"׫SN yx{ɲ6;8i~B 1+?j嫜7}qmIvRY+$u7p=V+%^). ИV^;N7۹b눕rI#u. }ckރR!/W/r+q>%G{d5&;&Vp\+rȭ%Y*vWV#N+q^>o a'e6&q;r*ti!C݇9ԕ ."^}3Z)l㎁r(|aeHԞ#:u"5*#&ivOϺZ#5{S^o$ufKƟ9r ǘ-9usܴ{AyyߜA{:$iyTa<˘1x=㽝|vpqߕ,'Gs97 '6}8ȉEpȯ{y VKJ朌$zQJoOKiF^@iIS߹@~AC-!/ryZ8bоSo;_VG*3dia=mE0p.>Pp](ys)/Mw樽Ol\s(gߐ#vY*s>LOn[r??' BOzWۅ;Y_IJ},ۮgV'^8N97qmWuq/ }⊶xO3\P~oxK  X:Ygȩ) O9bAڦEgݓ-&>\3 <4դ6`wž!6 ~O<򻱛8#VǡqnIuF;o[nN֩ pچ6ʫ-ti#VVzNMֺN|bEp3q'7|YgnaMVBN-w W?`l#NҝY,q"wI|{2熁[ľ2{ѳYIΥ>$MUYeY)+Fs #b\1FYG՚f =Y?} #V'{-_kgY.#-s7oSG1ZTzt[SHv vqyw#M V,ʵ<(> T(˹zhcV_7M/4] o!qx T?آjDiktvS{[x=a8<#>lR"u7Vvc/,(o.RwOq|M&:y,wH}K#2Oz.S^'b5}o<ڌ. x`+s<=Z{6l\3lS͡' [mv2C{-`5t.{nDu#6Vw2gGzƐ:Ӱj[Ý1!Rnug]ڙUbnN[/enc1J nk3w-e'< jpi-g;tq o6er\ښjXs탖+ߙ([\y g~EgNd3{e_~'_f RR[n9~*=m_.y?K}I|k=\ya=p"6볁%'Kސ͔S/mV}앇 gm%{1泂S֙f5Bnbi(o}n?u3ژ?<]8u/kC8IºnITlR&Wנowo@6O{{Y[+. b5:8:3f#@^(cRmZO_/mN81).攂/#:Dh\Dw݃E9 rמ5u`>+c̋bWrE5)+0z {=Ǿ%r ;b.`sn@b|fxNRrfG*UL9Jͫy\&n&NpGfDgO4GMȺI5%e7]mw?˃':,Ցbc-}5}iEӼx/Yn&bu6>+b^G_Ŭp{e8]Y*$o8Lǫ{q +v\[>X1|>OJd-ֈ,v,09KYz.=:~}aKc 7e>·֭mr`r;g_r|*6~ g|5lnR_qϲqDm᠕?`36L󺋬OjL1^e?*>\>j<^snfgט={jQbSg/2~{L^,[}Wh3DJOK܇sZQU0g}@eQi${Qw7Z_uU>ˉ=s:/lXlpwG!Ї5,k}4i6QlL=q/p+R?aC{04_wM &ǃ586v7ѧu|ƷG(m&aᵱXwe5o}&8%Ul;`Xt+-觼˴U C,5اðʻbY^YVNY)O >ڄ֨:D-O_tS[OLSfCvFy%ڐNG7wo3i|v7u8A!^S.nKvZ-nd;dIC}{ys7o:guƺqcvXo,S*&bD1[p*i/^cq gT4GN{;#{| +)VߟӔx8e*)FwpUV[oWpU7[6B}1 s*[Ч\ab74:.r}-y*|\ 3>!2ld^b: W2@]о5륿6h_Z*g6X=}h*֪ ΰsQm>qyW0v*H#ÄGheG[:8/Se=U<ÞJxBlVG;;:O>ñm%Y{+7QqZ|фփԟŜ{*i?\de;̞L:úL7 ̇ [LÏZSh;w2^kϫ}I{w^W̊Lw7.~f; 3w5/ f;h?lXlY}ϿPmgS:LzuA( }ۉsv=kuӇ6X\sþ"C\\MeJ}.2Wk(jvc_ _N3| 5"{j7CT3:ke":y?H;&9̈xk#c_UTlt~N_jCgiޱ<+9oγg9}O uЇ} mbDq2nV_&-]hPkqBbZ?{ U,\X'ei?^vB<*{qƨ1Xu#ΜwpX'&ebXHg*{Lџ3V$jZq k(w-NCYd>Ÿq]SfC y<Wվ/Gre^-1/{N"ցVfxL|ѿid)f-gM/o<SC}Pk\k}C 52&-8L㞪DwCb}{Q.n-hLv/ƪU{YX@dxW[2n6usF4}o*p11R0N+1Jm#EE<̰Z,s@y+{"#-& ]c+h xM(byPZG_;aU!.PLFy`dyފAeb]4KSkxy+u!nϣ0OOC`VSUڍĵ|Yȥw!{S? 6gzv(oqFm ҺSpZ~XHuhv3U5d21!C<75k\8c^N^WfOԎ̅Z#cs?*gV3xCHdqwCpi,7;7hx,dYN(9Ɯ[Ƕ|.kmљ= 9&ڐa&K ci s5y[B΍7)1s x*)q߲Wf' ٽCKfs<ߕ};Xo{-;ƥcԙ:a+g}5vsbn[׳߳gyww9vn>ZClvb6R7Z뻕o"6魴<ࠎv?ZGOaڰ;V3-#t> Bdӕg4K}nqA^#/`qb',65M\1b=9FNg{ sHZYxba^E+赜0m~yd,gޅ8)j@ya IM;h0]V ~;.#'5 [5kh>|s637a%{Y]Eܝ:huu&m{ᆀbP|3䰉d;kmh_t 2f#k0Z>JW%c>|=_èyOq4v01IqKAмsY43#Y/c&ƈ87]G5WC[l폲Xb v&B8[m&ⵗuL=1?k7N: whShJG},g zuyX=dV;\ECnkra#Մz xR߷v/dBg;Z^La4=y~8g4gb;)JCY[>DkK#.^W-[wn2fN1{AsHmϸٶuow9ݻ?Js V?K 9y#U:ƭy3jl*ٞII|)͗ |9>L-ߟ#geXғwq,',wKR՗ul3g+qrֳ28z|shg+mUjG\`-|lb#,w cc,<Zo7:;dzV;Λi}grmI&_'3'lq_.]",y"/51T.lG3O8Ч77}&iRb}[YN\3kvЮ2N.0=(%wuԷǚYiv#y`{kf;h3B.6Sc1\j }֥dY`D.\pLW⸮JzLWʯڻ-}t߮D<\W*_+9n/E!M~ܟuECޓI#r;'LO2$a vڴXoɤ&y #z 4vfkC=:ޠ }XkiLcIX.t&b[Wmhu?>+Y}9E[ݧ|7>_\u5 vnoѻHbiWP=L3A|oκ<< \eؽꭽUk C塶u]bSRO"~\%:1r:NwUc#:AgyVڨw9gG~g+^1z?8"}ˡ?u1y9C>/Dyjvw8gMt$]|~V[ܔS)J0C@<$`pBܧs_0-6gAW)}Id} ?̝ZysXCĺg*Rw[_Z4׳νϲ7j}Ri_p㴇2_kcѰ _ 99XQ]uWXPd<=["㼔^!D&ܓ4=? 3đxp/w8;8>GؓϜ4)3{wvOD]yw-L8kqc~XwL ,Y4{5cgT+U7;QVNqL%層";8GlbS+v|^$xNB~E]"ynQllA~t;ݗ~X؃m3e܆MlR)?f3ghd_yys:8sQdA5e/ ړ2n2;6ع<+;ͱ4P>qӉc_-FXJ`kE|Cb F>>6y%%^I" h_1=WwZ}~`/]I/E9<D*,,gS ̰kr3:KW󓃆d"5we1956nsBOd ϋ~Mû抿OgE_,`{ݛ~23Dݕ^}#yrb L. ^9S9OMWWpB+¤>t?KI8*;% (r_?X_!_m~h~#7Sߴ/B~2uz{yͅ`GbN Ɍ?p6] M=|pgIlnFJF>ykrh-y'D;$E%K_]=sy&q@XNMƿ ro=,I^2`ewK ib!s&!1 ?`aj8 6tL /%bV[.f$Djݻ,-k9*7ܟB(rnϝ$չ6ZYƐ'#S*t|#ZpvY2g7Oڷ:V1'~qF2U 1v`gIZ_HUx|;JM.\tzǾd>W 3lsU_#t)YNN8vpg.1^K C:_Crg{;,3``r} X/WvҊSS>@N}Mkڳ>A9O#mԚwևzⰷ6˹K{uPB<F#uͦ+jYnR[K>OgwZ sb3c)~ {}^M7rw׵')9cVι“ߒn{)z f a8_rE')yL˙ܔ?(q[d8+2w~*aW=j!ۆ/N8vm:䮗Y^}Q|FC >}q؟M+~Sdk\E.⧎׽{@qK]yV~C>|]93W1ܷ3]~y:V-%)*//r5y$%}sEa FV}ޭ.}9{GeLou/bk@u>Ğu>y>ƈΧ ~ܷi#5]\~܃/C>?7b/-8\{PBMs\'y>R[]]'tll9byE,n>-UUyt2b=̃6|d=T6UqY5[V<3}gqFn {,?Nw3>S){څ9=QUЧqy ;*>fC]>&FZNw}ZJs'(W)syh'U'z_"'+f["*{AA˷PU!ه=pca޵+ٮuF9Hh3ڈ1{|+X \yE{vgFܿ?9[n3Z*A~ `p_Ȱ16{<~w͉U Iꏕ{(c -*;-QNH\9i:*~qrU{t'$$@a(((HmP@Ӄ(jAEXB K7kZAd%QQGp/cqq [^9V5twu-]`b0dXg.~<?S׼><\o j6y8o3]}:C 2V]Hx.t^=GK>ȳ zxV`ȍ`]ݬ,6_*^Ax=^-7jφ0_ʖ3_3J>i6ۻ98wn,}m?$|K3.nU؛i އ}R2FcVLOܴ0GesI!&^lnzn٨.˥E È/:e"qTh(MG wb !^6Jg緵?03}|uţp$w ┭iN=Ũ \/&܇Ú`#K1_S`^n#xfZ.)nvdB]ʁP-Xmj]fzsQklC" Ђk[<% }2=< n; }ϫs+YT #uvsU" #^%cjҌɭ̅a7\|D/>?Z:7ƚyyXu\ y=(gzgen[vbn/zD|kZ}gE_U9lNyIv_}4`{9*%_N?c 3O'$C>\V[T8xϿWw>}%q ?jz> ?9%9L93ۻxo Vb ڔK٠y3k/o.Wϯgh%.ƺlҠYsF578$*c̒>;Duk]IKw˦4sÏnDm~r"}"̯ŽϗO[dɾ8A͝ Y.PwYu;ooGT/m=m|N։đurIz>aWۿO`<+>=9^ 9*oTMogV [I=(XDCҋīyS+^Zi ט}zQyq.Œq^ F^׃c,Xi:81YBUsCv5?%_ov&bcN g^ mq3oN969z!uXj#WwhNߧq EO[!6y^$.zsENw'{—]dh)6O׼Tqa|T6,/3ӓ/B\\GߥK:5|? δ'Ik~&91?I_3j޵$zza+n,;INNIrZƹ|9gS3yz/vH]K=23lgb ?';pQ {X,#~|*@|_r u6]S]]am1rT/7}0~89kυ 6bW7%n7F88PZ5s2A_|by{LovLK|؞s#w5uAG̫f6Ȟ%|D9T-1->M}RE bc =%?O20][vܹ&ia{ڏ-ʬ]YMχwʝ IJ>w'2nWށV6P ؎uJz֛yaˀ;N!v/lf=&0f)qY$q<5FȜ%sӁݪ: g|C&ߩ8zjY߶ 59{`m]u-|~Mn4Ai1/j{Z r$z~.y=VfNW| jkqyon՞'[S|'Xp5BS!^V1\͸i=@bc. Gr^z YNzfSX > rT'偉L?&gRߧ kr]> ;6;w%I۳,!H+lIz)c% 1?BndK.k575t!:e|W^kcurJ3*CRc;Ḱ !9Gcd|{%݃!C򀾐=E)dB~i E~ %=X^a(cԍNS_Y j;7d} 0S%R(DΒ)8џqg<=łz퍴VIAu5x|u|ժ;'>ي&\o^}?W'd$t;o:Rr/&e|JL^ nCNDv8Un'#~HiJ;=dT_Տdq_w@;{7[ѼAjCvC9btת|8~7HxzUJ2<>wyL,}x|;>g@[<q6FL]N‹;G^ʖ>Պ^9ϝD}l˗Qevx0+op62^兡tj8!g!b<̇i$g2X75x#^wgL  X4$56q֊_r&t/ydayfA2X=<gg>nz~G<~pbqrq s̥?&![?ɳB%Y>aNR1|=lkMwXm1r!՗S; loAq.Cg|e^{d!&%oU<^ߩ\؇E.a%>\b<3CxfCu6;c Op|Ƽy7=ă \9N80>U>'%t=Aqb*;&1lMڟH0Gyg\7qH$9*՝/bxw! r@#/LIn}wC^l^lúL ?[w tf6>8R+zͰ3Er;_鳪dһ/MP>G.߷Cn_7<84s<bLE;S5w`/=!q^S+P0F,~5( \WY\W=?([QO%90qG0~`w9N>i^&\ !m[Iߜ{v7qɎsM3T2][LgàA_'y]ȁ|Ǡľtwg!Ua>?C-Xa3,o_q0VR,2cn<7 |IP9 gj~;#O 0|3'|#N>%|S#G4aN|s%?*O0dngeb} V߉Td,LO~n=1gnb~nF⺛?ߐ'\ѐm 0Gy %oUi{'7 '_r]I;}XS}_9ؼWB_^_Ku{{mbRs oOjb&?RQ;ե^u7 /_HSǩ~2\v>KЦ~F.#WCN\3ڈb/^ o}J[{X^ճعkwޡ VI<|,$r82`}݊3^>![\~k U_b}+/&;LNlHgr y=}9MEI7y\5%Y>&^ ݦ^3fr~gխ#ŠrXR1+z.MoR>/nc!*:!?ކZ'`T_oH# <窻|i_8Tph _S{r>L(#_{{ va '_̮LlTA|7^gM:Rn`#՚>f>o%OX:2?H<[ϖlz{3m̿$#(MW@bl_}$3lhy-/uE: 0&<^U!hRhel$SװZc:!͞HVM]Gx ~ے[XFk}9smgogcC!L2/z*A7pUҖ O‡/ (9NgN k86EBuFx=c쨤Ms p?!0F A9ion|esd(q;Nr?n,y3{^6L rͧ '"ӕa2 Z?YO)PN>ǺPi5t<[ wiZLdR^\{fo/q$qB>V7fw^_>o*m#hzR}힟=y]s'Z+ʯ3JS繊s#a|3_[w#p e̞UWٟMT|Jl۰oFazz 9hXW>v `/0yιx9䛙2%w˩{|4xRe Ξ9C+˿*SOjbER/6r~ʋ+S ׋xbK\or|t̔Ikc~6-ݮ__9+4]V4[qtcY#^%~HS5/,ٺ^]p $m: &`|ۓ׏3f}, ߹^Gr[.9%ca5Cqsj¸/ӔXXXꁸGu8GⰬneܖX-gdov{cͪ ~Vra_8p$֫׿'7"~=}QՄxx.0 ɞ49#k8w:-ȗsj1&>l>Awf/,OɚUZ˜X,ujDlxYK /W} 0gP>[oUkuM|`{IR,wa@sKvvOqzb+EI}"b_|SXJ|;bcsf?^4sjzr&>mުhZ [WfnTyOY,5-53oNݎ4\${T;doy_}_쫷i`MesMq-6ZXq-Vz m#_&,^5g뱚_+?[? gӥ!c>tu܉= !Nd>W,7f_|IH=HsG_=zEsq~13GƬ#[v(ϐ\ok$Y>jěw,ALy8ծϫՃPоa#m7}X=R཮k=gyhsyf wJ5o뮤Mg6>:s[!?rW#~[!/ Y~lEJcivzng>ZZ9C++ 8sU,Lϕ790^> ܧ~Wǜ1XprjO*^Z~ɱ}rAk3CU_uKU{i }4,^ 7 th_xx|f 돲&9E`ZqawnR g2e<|d*~튃b(ݧ,)Sћm =\yeԬS ?Y3 {;mːj@mʳ4j2ya7CԤ>e}f{t;d K\qO+9Һ)/m85\fHs:7<g#7Alr=,Qxz2Guqkx0iԌﬤqoIZߧx\u$AW9լ.R~Zbv x-}Ȅzog]=1&=Qu.a[{T99ʼ4gEh2/xDۊ6xc3!zmR,L\x8kS'BNW&V>ϱ'$9 '$VSN^{b2WúGA^-̾;晏p_,:QM;#ess^ g[fdg^h31Ȉ^g\:#װ0 _f݆JĵoOυs%3e8(xކ=n(=?U=`{/(<mT#Κ&;a?Ŝ U׸1.L=ں/mB|sW4mSݬ7jԾTg֗xgs?ag5qtmbu&_`y)g&-K޻Ny!g7Z s-&vΖ(bLz`c=,-vr_a s45;As\ 9] #:tmׇ6OjZ]eܛ$`#M iGhQ~JxB=ͲC9GzX\]!߬2Q.?s:+tĵvnIf{N6l9ScO>kt V<^epͫZ9bÇB>{)wV={b<䛁}9ߖ1+A%:/E5=|Au.>y SgTo͚M\.T2"g3~?ͅ%# \㇗d,F52O%Vcl7꽂NX,((Gm gP3QĚd~f /j!OZj63HqX%ۏTy?z|4˴(O;7MnS3l쥦Y:d|j9度Iy͇5fF1šUK_K m3dtY5 HE=z7Ͱ;W~y*bV9x9˵63œ8ywVǸ1W;־1Ff߹8G=ʶK8q@̽(,}5YܶGy[Χn_:ϕt. Z^蓮ZbpS_y8|&΢1=T&guΊ=m.}]$_Y_bgW(Mqs2[xgoz#'`f^7൘3mLv$Z~'BWG{&&i1FXq0.Q-^oW 1!ZmKpq{}}ynG͵ o`x6#L0uit-)51csRƥzˎ' 9!=L}MW1G\$Zݺy°}rl%Ms(¿džk'{Z2ֶQg6waf+1o˚/Q!,^_l٧T6J"_M^sUt$t{f ê/oRb}~> t~\=1gqOTT'ufkA.A2m֬q 1枯|OUt<7.ݗwϓ^i1\ȋ:̙jVX(SO.far|nYO9V9ᬣ{UbCyzjsE:7m1(>kƉ1c3 W+T8ԟ73²!*=oA2\!.o^}!wipL\ay][+pڳq e~5&1yŭx|iΗSw[=hXg8mPv=`cr!!m |ak g{4^gUgį /cqK2]DUNϮ.fsŕU:<-;=wF}hwʵguZgה_]Dc"e>W>]}bۥtN5qfzo9y\uBb.3޾cc{L3=r,{''/p:q{sm7,>o%ٴP6LaƬss䄯;4WMW}(v?q7[x8@,}+?x/ҟa/> GcڤV]h_#\ϸzO=63^HT4|#vW1rg軐 vyVh;dYsu[\3[SsAWx } t5%[n,M;'Fa6p Ol_'Yv.u'l6IיByطsZ&YY~_?6;]z8ўOmȈ?hSV{?*|/Lr3}sE!#/tȷELY:XGWqV\?!=< r7!#Mg7W!Z(~izFs[N/O8V\8>g'A|Z&igL?U爺V߲z&msV3Sz{ eqt_]6z?_I3ȚT'dtT<_|1a_^nY{g;@ Rjf0Nw`_o.: s!BO#ئ\r3oq3bT?tjjKl<#=@jUODȸghg]J?|Nc|+4m?C.Oxndq }Ø,S:B丫UP}{4%5,e*w9kEw]fzWl)q}oMEG$htvTKہ.Ҭ۹I9y AngyO3{ԄU;?2l,nrB(FM:tnf>d.mm)Ytl K_$/Ɯ;/ ׂf߯&s،y)g.ۭƙQa}Ō/5*W[a÷Y {8_ hִ+7ΎZ_M†:yktޑur)y9X/_sӽ\z bY-!aDvosQ.ق}~8fޒŝ/Ys[se5eydg7 E1遺Nׄ0ڬ{+CA%9d lS98,fr|3⹼nS F5t*#Cr<6O\ܝkTg-mQU}Ft\kx{.m #iP_=^Jn\5uoUߐW90]6?Pm6p[9fY*{ե}XxyrDU4;>LÞ-x<>FH4!en[ZLo_3ü:9ACl\~I7Lqݮ='`| -:?%;f=k$k₷-\yʟ%&鶡ߡ>uE9_sWRPds`Đfg{,az![nؓ5TwX/t&ݭgΒn$j~:&?{0٣}5od4>~w5oi-woNlH? hWNE}cLSYU0;Y>ڼf6\<0g3*'+0>ӏ-:Wa5NLי'lhf}CŬ,9W5\@2^ᶵT,Ws#f5mEV"88jXg o$~3}e>Io)ׯK٪Q\z k+w3{됝 ޮk%֬5&k?Utcc1(Y->e/nm.Ġ 5ɮdX9o9'ںb3=GHF9uԴ#^Oн5뻍փZcrQgy0>SS}f20NimߌH/l yaf|_&fsr ]c智/_uv|[$\no3ZNcjy,mAzA-z/3O+5mn_H֓ZyoߔtN,avIE:Jnciu7k}<}m_w,3_1Fa0v HFp]AkUuAنfҡ1T<_hܢOK6))[Au]̖ڬ{xaRhr6A~lj/E-xOy:p'l .eZ[\+$C[YeY7秞To`|UwCk9=sf(娍Cxk;Twj֢O./dgЦKN'7X +Pb tK>ҹwQSJX#aruVy/`s.u'VX6tfR6mȈ~oLF=Wd N|_}{F34sh+[iޟw|nOyݍ뻯)!<'.|VTݙMft8ǕՏt xc _4sWW0,0HfنQvL8\ U&,O&a?i[*]qm6,:<.6&<<_g3⽨J77eajL<8c0F,vdι5_9dow}U|\kͮ3p*ҩ Ōm&>J򲻴wyjk2wE{amk+봯7[x/Ҽ9ƅe}'#ő}. ymԀG,1[SPS+Ik$9j/;Tvqđ Sj^kAUflQ>ok0mW} \_tx@kvxѝnx}s{7Ƅ;VȶԗߞƩ3}ɹnE3Y/O|]RӾX`@Z46;1ӈ^c5+ԯw_y5PQOZMzQ洛3i)>dtGګ[ ՗Z<j̗r;8Cg![ۋYZkHkMλ_6mryk<8lhc2Ry&e%+#Sj* Igjl;Ԫom߱\LDbx?-۪Ex{6-OMѢ4 5e=i|Ӟlf\ޔ[sX6,32h".mwTUsL6,>!N:vK~SvM7a>˅Jv*lJW^:œ}w^^瞪#kٙzVdnK>4;3lo ;6~RT$\R:TӺ64r̩ųs!}qScz1XWvꖾq&7+ޫcgK͈/^j̯4{6Oir߭zVS_ɞZ^-nOn_F’EE9G|i]k#"yV۩WdG{yź]ʔl{c/ :sX>+\MNOlyaك1,_3$u!31Rg|-MWsY>jM/mY\pY*KNŬas7kHz|1 ]ō a5k6!]W ;$ w1ة}a6X aL6ae<왜j;eZ {]dk5f#)fLFݲ ]3\9u}ӪUa&?g!i ~-1鲪 uK#ܿ7kooM=R1RYIaa}^@=o:kY10cY^{TZVx][5̕}V̸F,[6䱄_+YωՂYn8돰~M1?נbv|{ j;e۲\idȰsysC[p6\iag7yPyc z kW_վ'e6{nqjv>qfQ׃<~/_ˇ,R7[o<ε>ӽFᕚrWE;>$uocH=vp?y:U vm}լ(;z>ݡ=B{?o"™n?Kb/rqg*q9i5ZV{,mZӹ'9Ȝ*Uڥ&ue;AkO:ֶzĨDzxYƠ(mPԞ =;v3+fߒp>.|iy/`1ײNzt'أ ,f}zk@6;3rʱqٕ6{p8g&w1԰׏ʧM;Vx,^]c{]{OېpᴘjIOF:egZV^f{zQ]^/9 n)VQ?.p?X,i 0U.fsYꭗjXp2)=3MAM(>D{XZgRǂUw`۽WSyˋ͂TجwV>¶c)Y5]WΆha#'9PsQv!l,f9q$,?ﺿUx=]}<\bvim& :&\P$|a7j] 23P?7lXXgVb?ԽN{L' cV”{Y+s8ɬfc/=/]o8þzutg|Ϲi >-#+qU5sGn{e7Fٝ'G 3;;EsWJy*{>HyAWTvk~'շsY~r#EY(R1x,k}nEZUQ[1Ӯ"̌;+L9?";KTzWSME՚XN5aI?9{aZ]Z/{^zg[sUyclfǪާiR}MqZ #N,~s,Uog"#/ZufOFYJz|'%KI%Ja<Vd' qObW&bNSaÒqsl0t1L.{Khubֳӈ{Qz^}^=Wk%}s<\6'QVJ>pX5uʏu<$/λ{w'@~C9#+EB&9% d>~0͐lw!\V6ymLzYw,dnٍHKyXFh6(ZۯsYMuv=>?y%}/,\jg:][5i _.<'e'}n9fVG<[bz%V uމ/sϾYFqq0P1f>v˹mgPR8 rّ%=ۓNԡY5\?9qL@ε?ӫV+up]EepπN,%.55j,w |yX.WM^C#q,&+~~իs Ynvfm`]~Yܰk#mnP\$:szŠ=JĜ]ދ}zyL@șPuNڂϘYy{2K M}lTqaX1gۊ5ޣExCιBc;,N=&ݻ̈́Z=_ݵ3u#jăƜ3_-&f-<¡̳'M1#Iأ-zvmt?x=myiN9߿C32.I˓cg;nf 8c'ct|!^ϐdL3嫟kZOp WӷnwJ^n)P>twWؖŲO̩-ԙ$Mq lF\pENg@7Ec*>=\mYI_wMgCn'z쓜?㽸_U_l o )|Ns 7?U/3 {T#}:G9^K>/q/lc½Kupy~lwpvnI*:$mqÎ)u9Pr["kŖgͻM8tg5i^0gs]WrEs6r)kR#O} 䦄}kJ܂{ā rDFa9Ɯ c3UG٫Xҽs[3l.V?kay  xx40EsBe{O2i3uٝcx whOuX},! r7A'8[f}^eQUڀs Ϻ{u?<*_?ǹvNħIuxk: 7x \ sIOInE<2C/$VVcC^'٢8vn-ez#USF&2-K$uOɅ$o+^W]aƽ0ɉLjsOR(4% us:7%]!8n6 {_b|r=>i7MlH'|Zx$wbb«-fn;>\ }#O[.nWl_7ၺ\ǩh3iCYPM`λsH$<82 \s?h(^8:*?5B.aɒ q~oO2?w[g+W漢s΂\ |͛䜔]ћ=I|H2۔cz= ۯxx6ʆtz nVj&4jE|I#b?b??K,aM8~ƕIȟKnRr'E}q$<|c!7Y|7oIN'?gZڨccPވ>Y}kf.|LuÇ@Ĝ(+ofs#>kn jpo|C9:3uv& fYXWōqk(P<8nk`>1ɇy58qq2 H8/>ͷes~SN M&2܊kA ?"ͅs>'6KxypI=k+8i}Vom@}gm)ϧey6K3dvȘ\biY+?-'yq/5k6dV}C7؎_&uzK^5ށ-&ǥQK"Ͱ#9ꜫ9ߣnsp936;W/y]d">gOBs<͚!,9y3eەY~'ˣno+Ze||ZHȑk}Q3?&Xp/? -` 8k!+wozgkմ0TLxf,sEv%-=k |;%]uY8ӏKN5Y=za+^sﳮ4_v@ٞC`Ώ_q{^*f ú'o+˜?uM)ogݱ@>ǰl[N3!pUN\gSOv3pOM:Õ1&^;_r%G2Bd;_Vќldf a!xih~}|}cNL 3!;U&BVn<Y ?Ֆn7-on=GYuaZĸL0|Ls:K?<|l1XdY{h{ &^P.:^Wfĥp}p?_ev bqȯ(ksuϣqq}e|B ӵʼn,u暑{oRk+߫ڜ1@L;{s5F<,xZ|K`s5O@1^k:qv!T߷#5vǖ9Foɶz>zRyߜe$-ydG8{CqܐK"[wO`XJ.H XGeqr[sΒo՗ox>Cxcϔgþ [#a/ +7G$nik 679Lʲ\Oo{ṟDʗnV_Qocd}ӏČ j鋊mNq'g⒓2lKMcl%:gj [zT\*Lrf&)9+Cݤk|utG~{N1=*)^zC'|%auj5N?3X6%Z?YsxG2:?}gd6%~PvL\a~ƃnr_5,^,?,U#,ͮ"6Ʋo7˰p9H^X^fO'A;E١G۳ذ[ڮjA.߇rHo9y9+lv08qG|w;bC0O.L q:NLNː3gC7yYC˄ߠ]݉g]Px O/]Ø{_͚=Ͼq =anDz(>7>hwMr71,:6[,N|kWugx̦5Y-2b5- 7|-tȶ~ 7[{rKƄ-\G9q yokbG(/Y:n\q+|kXq6F9Vd2GSE|]5K---jk}~0ZԆkNۀSx/:r܉^ϹU=Ƭ]-~F' ![֩9Wi>o{;~^\ĴAA[nÇ 3w>SmZS[ԇ/ ==Zγ'eRȕ.ͳ3<[Y~'ÛeLA8qi-?>[p]&&Af+ԭkqm}ؿWUC{ǰ&} ҝ%K'k"f[gˇ +h֪nj [Ojڅ0+j卪%9'9mVOS~r ĩ a6^J;wd"}ELyGQ_ĸ.B8Y[KE~˵rluQZv?kWU`rY<{ObrCʗ31?>"w|>Vq4o`/%L=f. v{3C<߄lwy Mǃ kc^ v:FIqKY`|YKz"'75oTnFòՑXω΅7DuGCfVKC s[MONp G<=Aԩ(_k]*>0'cr\~ ~?0_lC|A84#ٌ5'!s~!d/4ܐ6֢d6/̟*Æ~9N*0 zL~qMsߎW} :0L䵼am+)ޓuKu.=G U͉xxq-`˼5wxuW;|?Y3"o7.,3:|X@/${MwoN= PIGϒ}m`ظM?|+N_5){pt/{?*}ު%AA[aEFQZEAaL8U$ inEH%5Cp#aFGAYVU<9*߾?ԫ[9Y`zvp8 r~97r8lWxwO7z󞒼?EC,H|b,&f-O|!V;O>1VLyn_U_⽙x>)؏6RDǸkI 5MC_ {qޣx?R>6QW YU%.jQw!߳xs\~ +W;5kKv?#۝ר]c9s`=ov|A.kq9"m:.GZ8R-Nؼ8-܃=ld:,9[os+eʐpO,^[uME߳-Sb=&.ou3,W%K4e\{?WotG>1r1'2%C/RQYc:J/1ۭ3Bzycӣ] D~XAgMLisݨxEfs{}lCT=GĬ y)o {:XQ="%|~?ثܵ~>G_:u`}m=Q?k'3<@UyԿZ^k^P]?y`,ݫyӗe|%ăbT>ߛTmGy8_]QηGYBͯXg;gdO>nŕr`'P&L΀.7EUԱ`#FM|"uޛX<>\q~>>[rӺbR^㩞3:Ji"Vo\k u:3 q_,އe W|{y8wܛ>^:ҹkc][ަ*(SU#- e`+<0PկHN_/I_bELԬ}ب߆)1PxY')yl4y%?RJ c)ި˺Wog z?s⫿hc>Rjluk)sV3.uAxz5$*>5KROG}/?i2z\bY?/]VC G~ۙr.g+%?qA} 43Ęs,#}e;׫.c|M܇[>2>`Le;=Zxݳ?Ɇ׳aq|RͰU\\?Gg[sv9KmЭײ!{r*Ka%?:!F0ڼ!n?6"߭^o^-<^k"?%xo>څ/@_Hɭi}V(Q  _Q y+^vzrv/n :~Tܾ|DX-;C܈uvN{44K#9n:^R98 .~ kǧ"So,+&7ZL l2g[F`N/ާ #3B{C?^/ cm3szʶ[q1۝no orHSWW^qJaiډ25֣ƹ'S΅Wp`h_xj~o{񪉓j)^{fȒr^/ggQWn^4n8Nv_xpvd\<Mqqv;9=&'YS3>Wj^=헂|Z/+ާm.xfLj39 ޏ6\ɞd/ʧ$X-W*2}g{6;Za퇥u]f.\6Cwjj3'oPJ.w00sӲI5;^\sI|{^Nj9a֭ۢ'X +[<'-uL5y_s7mO9~IycG;qg BI;5i+:SXV n?{+cro4Rqggq>a-^ɧRY3/r}zټ/Sٱ򍟰sZEߛJ_Hk=Yoh8i69id<ʩ̾5=c>RNBOtD3eg,pqōc/S \<5oӸaU6.?qy/M>Xyۂ+p=72.6<'s7ܡO]~zL|A _.cOz7?sKle`}]nbhHya|?vs.+h  3~g =DxF9X}a qVr@SES#s^rM?29uWPquB`L= _WU4Sd{5^jJOۿA9mÙwP=xb^3܋PV85d9{ڊkwvbW}3{K6ckt#ۃq; {؟Xy3VX:ky1h>F:G#TW$9 𞗻oH.Оk{T-V_'$d"uaй~)rak7ZiCtFTA,X|X;^u,U=xR6Ci<N>3o\ކOED̳&M|lOL=9?Lzv8l/楊 O.~1pbx:c >1(WqaXyM|λ' C/TxMK,NQfil k% غQWʝSiLw<4Ӿ#xQm3;Iֿo inwZzf2+ 9f^!'}k?9~Fb́ylrys9l维sx 65p5>[\8;l"x2ͼ)#IӤ8ي4_7>o_yӞ֣~6ėkcI?cڳuXqw~s]'|h)\8fXHĩn}-Z43@y/8g۫3W߻y_܃'\7/Z}x; IA8@`pi'j4N4lS7i9gV<펱~-]=m~1YiI.dM#I9R%^ {{S-߬@Af<>sp=2eX\R5?5fg瑹J VxQzCZB6|ZܬXV}Ϻ}Mu p>S󹔵W󨫟ásr?UOgW M[_3x!u,ptmGDSI$Y. uhz>ggqSو.뗴v+e]SٴcC)X%`#OLz g5)i ^34;qw(؁.i4yͪ.=a<1m[࿎>EOo<[/䟆`ZeK&aǤg-~-{g<9\}{E<)zgR9}|U^#>\urУ 8q!=w﷼ w(Y]=.j_풔9o5ݦݾ/j`=(]>|\LR̗K_nĢZY ZE-?b;`55HqJ&Jyx(Vkr01u0f- ΂v$l*ɊSPIxm扌s$Sj[]J^R7d(/DZWѮ'2=A`-&W>9؊.o؆d#2;&X}v?FUO˗vf[޵ӄ#8g5=Rs{خverLl\;gW7}~i#J{"I|S)>c^po)s@3ݽ2r"j*S.\-yZ UY᳛ {Ni-?"|1IsH67:uZ37T9}]> Z]S1ag~_iFq/g Qsow.yʼfDpJLhm%ϥ}z` yTϭobK0s,{_sO3 }.uPZ% uo{os{qs3۠>uo׈a/>L1"w~(5b%n#^pbg鉅Nstux >O:!>8u_|'TCtVe(L\Ew ~f/-]Xs7ߴBsa8p.ig[Q{oVl?yǶ]͊{r?37}Jܛ ^A/'oU)kfK7Cr<7fy)KyУYY^ϸͼM2c_0mMX,7=,/ϺTXu[dw =d5>6Cs"EB )j5KgP<cIGlox0?H|ޤygsz]b!JnrŅТCʥeʟ ",!-*7LqQ>RgG YT<^$c`zI-OL`o D)SD8O23 6~pl0GQ},w;vn gsv>SGB^_('[ܯ.߲jo αvk |:̿%5tf4R)y|/͔'f\aʵ2x>pאRgCYj{?foGU?`ΣH݁OfcnD ܯvL{foZ}[gs1K g_W}~Q^~vp0vׅƹr]޾F֬]fؚ4{UۘԌǚ^d\jj{.ܬ݁sRK[ V0 6?}Fj ?vGw ckƆGK]?v&_tw0ky.bϞ vzhONn?-D-ۤYc|a7d/,W;Ef+|, u.fZ/VEe|o%@53?g8׾׳m#>3o=t* tT+U-Nj{Cvx_S^KueI;vp04qPyw(:{8CճqY|25,y#59"d?90[;ۼb<~+\Yt>9ƃmZA֪־g{gd/؂@=#`s>!G w%౧p&#`^~Xsecd ^ Jf^cIsfw %"fu++@ƽXYl57#ShrϦmmNܟQ/n\Ҏs`C ۏ;Fqǐ/螑k2V'^NKXy#d#ŎafaͿf#>Qo٤ؘgx Ok2/ns_If^۰ :ƚ?5%ˆ4_6 8¹"bb !΂Cd'4˃-(hOϊflݠxEI3-' 5y(t|mm-›ڎ ۳^\ڪ|Ryű>|7SF7K[Rc([=v4qFMSjFF,Mc,7S3K枝ctj;<[{gm=`oMkX(.1ȯrn+dhoYe$lwiN+pb_qϮL!*ޔ;xS5-W;/&Bg޾&;byG^ZZ]es7ae6ӡav;jj3SJН'3nO#Y֌^lއ=w1/92O3O[S-kW+v_e>g |$=\+m,iU|Sc<?w>3 d-UpROLgckU:ɜߵcsvG cZ|9<ܑjZ9X(?e'}1vRF;!|k:krgyT=5g꫺ڱאb6R>y׌ϜӚ/Y{vLD[|- f\Ezq%<Ok8w6<43u]{+:&Il_"1K\o+r/+Y<j_iKL&~84?y?^dz;5;UcjA\ۢS*w_ӾA0,9RXОe$s;"nQ/O`83elPxه lQmSIsx;e/ A%dۀĸǑ!MxjxJCڏ}<=wbjnPv$ @1D;dآ,۵깨e+8} 7#dS1;Wˏia'Tfx#TnGû4~%)Zٺ}TcɁ1nA=.*>׼.3sWF5ڏYwcê1ԔVLcXs3GiEwཫ wknv%W3W5y>RSԿUa8Csp_Ѽd0^~poڻ"qjݮ}䉪g? sxc}_K=?irkqndy}XmMaygkG?ja}ͼ$bq?C%@Eiζ5N?nS/8?L u(N~gڡ8e~WJ^O`,鵗}v܇'Roz ["1!W}9#y-awfd~m*I0 d_װE= ^ C}gi|:U'NzDfa"ن M5a9߻<ܨ՝t5G䯭i?rug[}O@{Ah6Sݯ%?d$ ,V~~ 9yXX<ttbq!\쟾 Ll(T/{9p1KUE3PVqyK/,բ9椙9U5%ZT۬(,ɆN6H~I,cI{YMޛ̻wkYy=Uv(B'a0[z\ZQNiR1f >'} ~{oM!ޚV0L3? >M`L;o9'hO&3+P|Kkt6czD3,|Cq]Yh恋ꗲB67~((f8Lw_yĉMȘ|Jiqp ̽,_m>a_j;e2r+<6 ;nnԸW'O1"UgFCVaQ -Zܭzkd>s>;u?%l--5x5":n^']*7( ,NcQ58d3ˣ7O<B7U~Qa ѽ 0?>]хδcH6!;zFȠ0@IeS*߷\*>u]Λ^mQ Ƕ;q%P'0!Gfn52y66-Fẇqw|NMgqbN&f 0Y):n}. cKb{lAҐ޵ *{Eϫ\ 9wD|*HFbE8&4>ƜyrS~{s ރOaٽ>ה^,TNvD';gx>NҨ"ۯYI3n|oqnu*r:k,鳯ӽj(=@ ˸fv:Sunc:'[ZE[k)%W{jwt`yzQŋCOu6测ۻ?g/oӪ%~sS7caz>/הW7lD]E^ǯcDr*(f"9wuesFk#c*xoabM}C3zV>AeZ?s[>Xg~l kx?+;L>ge!hkvv<~weRh!W1^]xtb!eMe3iUͶ-ZFqJGϗ).s~^9{ME5+ߤpF CPlhn؎(O=u1W=&:sǖu79vϭ+R_gk˕{Z2k}H:&SU2ks <鬑 ;enymy:nYQ~sIisxUl_M:g;swI?I5Kv%sˊgo@kqeC]hHe|ʐ$-$cv>L~ }ג] Kq4㹺4s +x7.qrՐ}V;+ k ,>Iާ5!,~W#}eDlwZ#gHnE :;L EU+o5 uߙL](,H'{>wIr^E9T4:~;3a?ϻEgkZV3![kkdn۪o=6Wbb)K|ҭ-~sZY7|{ 7$|كJ74垤yg?i֛M-u,NO@kVCq>kz>n4=R=aHה"[8"g3knzkyv{>2^YH8Y2|!lwy3 M~ x/\Rz?˙{"h!٦6i73lQO[k3O_mv*?_{7 kp@Ol/O~?,+5bMىzĽ7j?mXɫ~^蕼>`kfhodz#W8vrkt /;nMX b]k.?TzUlPsuGt/_?M7乲.qۘ0^5 ,wג˟Dngރ\n\9^ Y,IbTמcuC%F9ΩŰ;R*A_6Kع3le]_IsQCeUljz|a+NZ-*9zc͙z ~/L6)?f>lŀ9%EȪG䵩/]ʞ.q_hgn7QPTNij Nݡ|ſC>Fpn?S(]=ܞ9.M}R9v$%͚rKu Wd=WrL.wD|iӡG?F@tguFWUK$犯7Naղv =i]Y9A[|OUqr sf(CZ^Kq~fޡNIog|]A3畳T r?rjǽdSݟre٩ϲ)p[}s^py87=g38K2ՅG+-}Qg`cWizO%8kmve zs6=e3{NybBi\Wc[#|I23T8ba}-E-sIlLuY5YC=]< {&~)+XN/{Q;=Yl=u&shͷn6uq}qM߈vkX=eJgk˜_r|C1mA;z /[=t<{J]T^{5\XSbD/N-G{3;fȵbk֮z-Yb0wpn<.׭۲=,w_j[2Sg5ӮvZV|ސt{I7w\o囩_fsS](xn)36>AiiN^\qZ15?^'Os^50jOa=kx:9oߟNh;B֮>W4#c3t?K%)o>,VwײW+W<`{;];._F_Y/)^h9d`[4ކ|_K,14ވR& 5 3tP+4;ݫ~I㿸Y{LlPq/Ts&>&xIih]ݥ\#=cE\0fNc>/zUQ6+MIaAR4Xz=#͞ozV_<$Gp?lV6E}䖟~royZASt/nxuNS;&ᾴ%WflR>x\Z} Y]R}PkbV;;@{PCma}QH !K :tEsshsztt!wG'GDOGkDU~Bvr1* |L-m vZ/'=GW<=u]bϡGN.lo-YOK6y2nnrۛX/PLsau* 秡/틣}{ p:7ݢӥѫ8K/i\aSҙaޅxX}oAvt{ܗr5tQt ^Z2%9Q5m}Y'%-:%ϵN _><5OCzIxߓUծnWÒY>3_x$<>w Te\B6;5Kz }тȡM;g@V)wQKᗤK=w\=wٽIʋŽTG3qͳ:'whҽpMOCG }";<]wMc8r;y5&;@gXy~cʽ[^پ9߲)i\fO sKfyd6tճ8Z;hJBpWA=Hds |7z3뜸#Uxvx7v |F̶,l3l'ixz;6ux(χݘPV ,vzxN견y]5ٍeLP{Is?3{nLr={ܡFz*tu6l@W_xON|oϔ8W{gk:xT˴vU|u8X9Sך_6G|BS3DY 9f mxGMAz𨤭.=}12ZԾ=]ax/h5\ol\!΢zƙuV|ߍGi7lܿK1v F`W#޴E-ZǙQyl{;oFC,Rlv+4oOgc8f+xW;d70cNșxGxnb%n'r=?"\ %˾}k}ьU,N?i]=]O #ܗk]m,7Jw.e#drk]þ15׳)"]ߨPf(dp6j%/Π1mN{;(Kӣf\/~? ] Fj97KOc׵O;baw_[xVⳗ")v\ɭ8 v~nvWJN_r?'GhOG ub&en܋4yѮZ63KQtEG 3$gaY67٣nk"}cσw{2eKTD @v}[v(&N:q&7[𚟐D6Q^i/[ۙC{Gxw. sbL5 '9㼯=uU swAQZ^/d?iqw Ur]r/ws'Qah7X ]>x],l|f;'ۜo }? _O 9l~k'%,wFG:t:ݣ_]{}n KŽ't޵:}iU٪g{Ŀ9؜uUw;|ݦG$ҶƊ*ȫM,O^e`"xpУфc6|5g'N;:6 W6.Y8. K˽u1]CT3rwDX3>!48I{7l]cU5;y|QIlu_M2B8kI)U9? ZgnQ#Iwzc & zH$(v^S./JV8<7Ky<&VlZLUKRww9fgt"/;p5xb-GLmXɸﺷ<>yIL6Cnޗ>&RMG=[r<&+&Ff|ywL"cНC,>9G-zAذV;x0M-#gW7 Բkm\{`1|ag71q[{kuaG݆F 8(UUmG&Wg|7c浲mGNa<:-ʾ-?ʭ)(>a}e%ga;O̗r}Lk\A؛YQ nUPV~tVvY:cC=aA4&Vx!]"NkWWpߴm眸CЬ5>K9彃 |VIa5ex&>::A{!#qQgA/reG>ݥN1:8zL8ܯ,{H~|6ߋ_q̣#_VO`2up=r>Z ;B&Qُ9daoMe{ l;D3E]{IukiD(zqzyNG#Xq52_)\#W*_O SCs _[c*rC9(3YN[mA;~^MWI^nd1.1/v}(WTuNÃ<'8c>6k=uxڢ4~ 'YJ:C1`Hj9Xp3q?T\crUG`\oSע=lU Wg}Z}0ɡ@h)dJ:mly?_~A@Pʷ((ܔk (3q89R2r~8:a9m:uZx \%_c6~ Y:yh7%z.Qo׷;%W$}~9>_h{=2~~bd Okvv`#2?fq|JKYtr#V TAͻ! /{>琳v<+_E11s5)~ W yvڔSo]^IsLWcཙ=Rn-|9/|Nո;V-29IJ~wW}Q㋇wvܤ:yk|G[>tk;C>3r,A:lK5x_ !9OFùn7FܜM vFl?!ZWH?,k6N>/Ë%$5trq6s8Xs3Tqb1[~'lž˺l5oݣlA, {gn9"qӊo^uXU9ҷ3㹽ܒv3]k̝K˪Y yJ=4ϑۇڬ{mP܎{\~[/ћ\̗4Ʊ͏`{l>(+Hh,()8Vd-B|N?\v'tǖoL!W~{Vn>{q ޓ5YaQ4s(t6llZ@Op;i;ܘp.qv y~ϚlcgNkd񻔹$tծyDnjK[eؿű$}E:WCzݎ< 9!q/v,}ako;0\^-6gdLÜxaEq 8o'$\ss5|73ަ^۵ڪPCŘnFc~()Yys.q3E^; "O1?? *=$a;u ܂϶7ksڗ3YܔH,[#m!e+{%.+MmU{ތkx?ȫv[_d!d^H1]W8ZUcVC ɢ{$*s^?/OJ:韱 vrqKi,NMrWxpX6tۆ\Tz+Nw Ĕtˇ}cmA~3ibamLgRwy__=)g&~kqWޣOU9܂݅kVڙ ڝi})"'W_ic=RJnL}gKG<(WbRuiu\N^{x\/L` 0a^ʐ]!H=+<&O$5`g~3E^پnV]z Gf͆mǽfg,=eM6xU79!#7G]_r1obއ)ܳč1IIx~|LY?(/-F܁^􏤼gz杻1S cSc-t!53I+_W}&oaHx/pk%eQ+>O$Nq=Y&.sMn#VF͈n_S]9?KEH->"|d(z>/po"uWؙ^^Ň,G_>ͷ)R5ʁb~N@ʡD< 'hyD{}b(ք$Xe"\;=J?&ڿ͙:k&,'[b7ֽ_7|g".>exqn3l%A|WKƑlyyS;N` m8-}r-/>a ڸlQu#5< eAnvyn= txgo'˾ENJ∯u[_?2ce;Mgw/9o yc]yOܡGV:]z3*$`*0`lsW^ d#W8!Uf1Mj󥈼{Ama~ۃ";[fo,U3śN.= þ }L7cGMxMՙb̈́|Kee^`evɚqx߳yEJDpNU!\<Z<&9V%ßs)+rX¶&<ƺG~sٶtZub[ĭ!:`[3B]9 \aڵA !kbN;;97`6ı q^Z5I\Ӛ}D|_h׳{,({d008s̹_٩wW(:=06.ᚊ>2'$MV[gLZ*\%hqEΙw\INS&Հ 'jsR #:#bUK̇o>'xyX=b_[bZv=W g =~bڈ9,f"?HKT~왒0yx keN勃q9-7*']"opd1I^![YKy7357ˁ|3!R## +[-Y%WJG9k+K)sS=GHkȎV>^U==Dv.ќ[ ~Q9򨏟I9.jvM}i8'w(Ί'ԯ{n{{KveoΞ}~Zy*>XW+N.Ϸ΅]yc&x&F`/3ֻ7b.0y Gٚ/Og_ߓNkJw-KC~]xy_l/^aOyuq՗x`54*sT5p{K04A7yoy"[8{Ǻ&7Ռ7@?y/lߐ ~|Y+E2K1x\j|UƵ8=ۀ%b ʜs}1->ۉxJ=I7yHj*0qSMGY">>[~-UX[r9_!X"u?sű!+Op:Z3@.~(\F̚b)fL.ΰĿ3|u3=܏0 VGĹyxvV@]rPq朅6_poliYuPntlޏFûp=TuLcܪ3G9K/rݽ <+Oh׏י>ĬufmGY*cڷw 0')'٫& q쁻\}%I*V] y/ӰɟN Ue6s"iζPƌ=kHH!ja+tk 5Ր8_yϣ;_bg3S+PgxYɬ)3[KދvM>4 ]Uxv7ZSc7R=+lD[FoǑE|,7yc>~{G8* ݭU鶺|_$ߟjs/cH99)@. =~#-}%>!fﳊy]hWleʜ޻!^x6U-nSYT).7ꚛc а]5Ma?kt{vt'(oG/vGMԻDss{C۵6s0n>u'7ɖ[}fa2 CI~sת{%;>+0(Z'9/V4pv?^v&h.(i·ә 3 ><3KeI>|@(j=}`ڦey=$b_š(l9ʙ3)=JZ /ewf} (/N9<|ޥrzs{P.q/#~>xgq.lBr<9V4{+ l{=2WʞSqP_x--T-ޥ"9oV\AW2{F HZ]gy>謔{]0' VOPJ|ڔ^NȊ JcasxSY!a<4<l:Bko-B 6Ľ 2KwD3ƩĽ9~k9/]~=c|1F:of?1{ηO;\?zI.Z=qgо}f skdςL߬+w{,}>ߠzDQM`}`||~.ȤC<؇YߓqnlBoN9kf.nmⳊmr/Z{|`b78s(J62:d5v1J{??#<ͫχ Q aߵ >ؙk7LY晢nc4w"݅+ʵ܏en3H K|1QNUo%`7Vyej-c`A(?)>ؒX\8VLZhk(.{r?f!*@~E8;۵ooB|\J;TwkwNz{MY_)Ճ6۠2w9| mƤCۏě{89*myj={H dՠ4M? J4=L# t) (`kwI7I ",q#QG5 3*3#'T?u]UC\gCPũU|L}uq)8ĜSFqb (Nˊ/6By}yB^IV{%}&xF-2]3y!_yGi8ϊ}XȚwћQ;#*s9O>x7^݅{$ FiE6;{q?oG_n~䍲k|GaqVy_좟J _l^O'C}+QLJ+Zӽ9MLީ^rM"Kna.T:Gp<~ {z`?-z@ gV_Rx79Nmٰw÷ҎD|.fuU1sGbL>853oؠDs~zq YwRI۰C^,0c9KͰZb>X>yJ`ip}C3'Jqڬ,/z =`bژlW5Y]l: =r1{s.&=K5I~ 1y(,ySIS'8X\~"y }D} .+z97rne<Χ(0HX 5~ʵyP0:Ā&[N`:5a;g|Nkh&;bK\7xeXTu_yE:G~?Zi?/13YCyճ/>+gg~ ʬix\v2vantqlW"K=A1<\&G`ߋ݋1vЏ~|Ưfa^{I~]w~gEv{ƳYpXdgA !'vsCZ?gyKo#iZ3 C(ǕL/99HHTia1,%6N>y0.U7dz[~2KOm_ķ!'j/ 6[gǧm_ g 1?RLI2f|Z'߽ܘ>kax=>`TzS@-sQ3 !_X-ak'^s>SQ W/ 冀qya!|Iz,*XX%)G{c~T~ \wz̸Dߐ3_b݂y<>͑_hOx! 5&tȵ mr3jy4_u/;߇|T^2@N rӧ|R\j:Cs9@zwg^Mb~0}|`K&ӝIj뽜WwEG"_Z^#1|2kLψ*~</&k{snգvDȻ8 olnmEn832QUڴ&vsEm\f=A|7qQ-ؿ9TٕZB`s`qī53^F3 `k+ψwœ+̈nh&8 3{O蜤ĴUMB.8Pa(ɈbHy5փq<\_,UK|w;V#Nr.`Ȟ2~}ڷⷮXyt<v&2>"GwՇnpz':^6-iX#&{͟5Og:jWKzQP'XY̳ ߧ,X}2E|eVDp-o}U[\ڍDs%&Q!2>G~i5'_ϚhwϊEnˣkNE5iLş?\1mM{ZCy_O?;m60ù{mm?32C k%kl|51gx31E.j\꾕7՘|rkj't/Z޿J|=Ps*y2s21__N'zWwX!}3:9)It|O?{=wCjuQH:cNV mzu z3cװ^ > 1bA8]Rzz/u_E/rfsX++:|̓.sG[M`,!N}߹5 "|ׇ,Olj76#^']!C<$ꕢ#uOM.nď1'8y y,/߫vcLn-*`/G9 Set}h&EzMQ#z s0S]xPO&|cjFD5=E{.QFwq1]YB9 :o.81Z^szQC>siΟDfn.qC'Ŏ@^Z(Nb:Sn߷by {GQf0NkNj=rJ ]/ĵNn8xEi"3n,6ַVYI؈w+ F'_p^|lA4w}`;uhF]נ&P̓WM{L'0'"1oCt~7[L c^jٹ( !y47^aZON$iQm!{mPwb$!o<6ioemvU9{)wrqjԇvǹ%A*+ٿYM.qPɛ/+i LY7 $TΓ-a=M[`)K8{!ghgdȁݹg)--]*c-lg~@/cvRbbs9 qNQsrNrO͘oyƥ='74%qg>Su4CLw+_cb JD1&;#G9r6{X5DNl_L]/jw@VK\fncb'qDCkt' 0Y3{XS*9\\W~l$z>5ۋz" &LC pm"7*mU;q߾L"Ljyl549/k^,g ̛WDKs3uwRklvWts!!a|[~ǒ0?qtd]I}O{I{\/l\s"Dts&7_nl ?r)șurLz;;Nײ7`Vt[!K_ b0+9Ю,D,v Y `?6S;8BĬCL5f^ {6{jO6].4!#4|9ýM2wniåɔFh+Xg~cȿsǟuvš YspA6 Rn{$fWac]/pϧb`9Y&S$R3Ĺ(k+pg}K?mAwN0.!{|[·ktY㹇i/Ǽj,|I<ZF]ଇ߱AUrg+sxm'y ~Hk'{`/gmZ;v8c]2w-1 ;qr+'%RMkBClvM3&e=]܏S/hnbי|&zK"vⷿ%r^t9`Vif=A䢲|ψ\cbn::T܁ߟN\ߊ-0xut[:<[v#;(*{ӳܕ%cvq)`uI95"Sj_;-VͫQD~vAM$Or@}1UV{c+z3_sx*3w<K^nyf-.&S݋i#2?;N|qV&ޔm|vCHU~A"~F|O-3mgKjJΤEOW8Rm^  7s4sVr)u3_eL{gfJ[+#5M݃_%z ?]'[LϕP99DwGl aq.y͗sA{ vEcO:c_`v)m vзNqfEfmB\%6}~`QcXV0;<'36g+ ~Ebfkqx2P`Lv&b2͎Vsn_`W򙎓Ls }޿YG+Ey~)0zy9Vєͪ}%P߃k,ⴈ;5=1MB`?})ˬ-X莚uYԿ.6Ƹ)Mvrf9 sRb43l1e WhSʮqAԓQ~Af''S8K A1%Wc**k$ej%c~W}oU &ie|]^!a1N1gD,+s]_~2u om.Ft6$ (S\xN7ZOӏ+⬍!7fTjX8\G/74,7;%z71%߷\;loP(mz'zMF ?Jikfa״D~+"^lVz _PmE;somwwac8>i0.)Ө珇D5?TNc +6,S/2evf\[Nzo1brk̿d'7𝳵Ffo2McIoQ-vjfQoW٧:98 6s<;;lǓGj]뭋iǼ]}UMZL_kxNc~A͇Թ lڵَ]y~ fVaa+c Y Ӱٓ^8+sk0f[Ù٬ DxKOPUN6Re #U :UXT!ygu3?WqȺo6™yOQaG 7X jid٢siLqX!pNyu6:C3Qmba存T D 75jD۠c9'ad6^Xe b,w>c:?bXe3{ga$Գآl@6߯|9Ş\dl~2~ d[!8mrVEFD_ծ.-|=519^bi_+q8ziz9f1|6uXP`gڈG)=Qsf; !W;w 6vl,.\hסLI\dz+?6'#Mw`ggO*[}U7wSWW-0E=I }.fLs4l|K}Z3oY]h#>$} Ng[L[/ٴGܹ9)zr?o/# 94?W-ϩ\^g&SWM-5pm Kk s_q2vsˬMrA#^\eeQˋy_A| {1Ͼn5=X1[F̃ha}I/xVob1[bM5F F{jlwd!ktoƓ`f{d s&|\ ;=<jhg35u- QS6z/xmöDcAIK||kk|{R 2}Sv&qᴪ <|Ӈ>{uM5C{trsEv|I*5\OS7@F>88GeLyc6B_@+s;?_ɵل^ӵ$6)|e[oB2 zBy+!ثextCy2f w;+γEoytq]lWqg@s~%ѳת/QN%457O^os^,y;u ƨn sz+πqW$h[+i5ʹ[k.S\_1vBRYQO*,OyqO]'P!29"עyfհD2=<"y'uAuN==P1u򌴊6byf> yZ }:ËA&=Tu<@r<0u~_\CgGk&+XBeE9'gu[o6{|͸`s1RvCv.-w}8u8קv+j>m_s}Y,8QvfjDk!yK4_sܳƥ$k9ނ$f n@{[4V5Lg+;&a6Wd*{c>+$.@(Ϯ?Yey":l"zϤ\79{s?ŇeG>)/?{Yu=q<rJcF8G2-3U@zcNN20KV}Kv;kuV8Q'mp94 6>[J- # IB| &MD?r&%˝_g@5~_]uxwJ4]*?h]_]_,!N awaf^~`oRfES :C|nj2h?~sY濷[OG^Ì= Z&JZǔZKޤ;4hVhгb$(6x,{Sn Eś .&w!Y՝vg'L3^bL}Ϸ6^/1]菉^p6,FhoJ~66< r}vG.^'̏ǚgpf @3^L0Sat{V-/;j5;ZlmtsMQ},sI}Vm!f-WK^!ígr^żtqwݱ.7ECnČ=}ǻ6Ƨ]Njǽ>؏"$~XCtow7`^Gf-k9~vt딿ىXrmrqW.y9Q˯38a^˲6sȚ3ط<7c?YZ}s[MVD{|4q"rN-'q.bdgQcl}֭Zʡca75m=rOk\VjM>nJzѻ0gسS9>c*WqS9.C܅ccWw. 3.1sHfWp}*%UR$O~cr!W^rZdcƦ}'m| k2V?QzJ nsa'P#] >A_zEr3rρS{kygb|%0p|ߓ~`[EnYx&=Fn|VG4s? 6üWkn:39ns7M.GݕvDϒ_~4 2ehOcΞ}c'r̝_U6j?~N>JX$3_|ſEZ-3]Q[W"rѾZNX6gA56 tNC0v4}Rdb Kg󚞁t`Y;0j&:{ҷ8'2f??QFcT@n[6^ن:WmYL;n;yo]Y\3?.âr>*2J &e}ZkNCw?+~>saqO9&Ga;~-/6L`'׹"/LX&.\jC/oޚ wV4h 4ϩ{ݑ߱u # ;.,D:rUf$Icxy.y]Fyb'K?i ^[6dCLN0]H4sW[WěƜєlapVc^V랜Z}dyk.;:1ϰ[ṿ\{.tlb={q~6 :q ?73r}r'^ř]cq%셞l’q6dzp֓hb觓vSEv,,'avsbh bv`|[ðտ8ݫ_8?]F{f=2[DVM"cu_7R˶wp'G=KlV0҉3[NI<ތذ{=vSsEZ?R9+ZIm[lRa]JD^XÝ1HәWsCrw$fCosqOr}wwpVz 1NXc1û-6}g{69'gp5Uc?GeҞ=0E" ﱺ$|V/}3ͫ|'&!{ ;O5Yynxx{_1Zmv^uõ*ϫ?N6cNUufG<@wtZO,Y=wXb.Vr\9oǝ_( 3qs\7}WK5n(H\ "x5)V>+/D)}7׋-4#aƻ1Ú~Ğm7^k)7Y4Ÿu=zc"z݉xz wd{#*q؊Zf9߇ik?SƐuCs!r^Sq^a/o>B]Ar8P9Ǭ` ;[P.=|1b6p<+/!?u7=:n1xPm*g2uFqؑ){Y䓊#۱uNi'e\\cgEb,nh7,ƥa"[ nP1,=d^~3Xa3am>]Kx uYtYFjuQGu&/+p>9XVwS?t)Y?O<ڈ*=p~c[Il{p0s\ِMu}\p)̆quw|ԓGNKgN:/wK:c֋[3@za堇;摵]%->'7Xm'㳘{\OUm:sv'Kb q쾢^ߧzۨ;#_`{yੇ$x0v>f.#(sYM%9 >M!gāw3g5 15@?n1ՠը rǓ(? Sг^z\AܝNmEwOm1mRΗ rxBe6g cz|S=vd iuWf} γļ{|6K_vj;ڻa)alZ5O옫K]^,[~2xaz^tfA9?\=wԯ9!92Ҽ{fgUkc:ŽwŞ{sث K\ ۓ|3xs]!^䥿$>cuWmhR;Ws{Ǝϰ8%ngX3\iŻ._zC.Q_soS[%MwCWrzV|+fc$B=^w: g~]u!黌*^cxwWEKbv_l[hb^x|下'i B"wH쑋DDَ7,9̩-B|\hiwxv\搏PNB"9պW㾾l EgLcnwgWmqv`[ y>V/vk~qL'%ܯXe_'G7,ny~Ijzj,33l.M#>/Ki1(nL̰sEP9J6N}a~;GJ8Xb0{)!xPtjڗ{k:b͙`Ws.r7> {*SY,}נzAZ.L : CUz#.9i>Yyx;Zn~폙܂ jd{ؽGwDbbamA#Q%V;{ްPH͖#9[b oVm:񰝏|C2?L=ֈM=~+ 7n)=/C{5oLYMZl(=ϝ˽g;ϠVFhS~%fUNO*oG)#c/Q3q۠]Mƣxm1pFLoN9ڳ zΉ9;x+GV)wYw1O4Z+WCOOժkmښZ_V3煍Ӊ*7`N}qN+!uGcNϳ5F)*sb IןPQMqbӼYU _p~{#2ICvNnY[}ػ=7x%/r:w|"ۨS|zַ2kUC}jmab9O_}zlq#>.3`uEN*a3b)nؽڇĠ)uձt%krx6?*x N>[P N][Mv[Mo Y3/z!n3: ћKvҠx #K:IͿ%/[zza?;_lʝw.[q-7/s;h;ɏg:+6>uӻMm'Eg󚨌GP"rL}&-wŻ|B g#zȡ_^'~؍u\iOkcp AP+[f t֕|Q Pu +Cxj $r8{cS^Fȯ!f2ͬ9l_vsW^bwlďkցNk\`6w$ ufə>cZpT ڧ/GeMNM^*s֏{PW8y6^3tq\毀s>5=ݼѸ;#μpL#sI4?rk6 Ae]pcEoy6<]硸I}d)~v{>> Nj=}"\{*Oa~9z؇{yb;Da|h#z&̷㥿g>N{۱;7ؿ׻vd :  9q~T;!:TMcr~5iz]e;;(Lt5gZ4?uo)AevwXBu77Ocb 9@۷_/c 8KŹcn)욬 c3J::uQ{ska؇ C.e{ف3iK H?Vuk~7. xo@nrvN7]DWcW/;lʽ[F {*"x{g3˼2<鷴Jqq-}Fq4ƫo=sZ!?-\[#N4Ԛ >:9v!_=ש2vԒيG;O4G :iў1LDe2fJ}Dm[b1QhSJܯIm`>)ד/E'2E9Ob-ٰ;9/~/+]Œ{,uZooTg[L'&o_qj~ DU Spvܯ%þ-3N 0>հS~J/N!> wC'wRW远 ~"C\5C{kQv#'v< 5CU"O-W_K利%JŌpmR^>1FA2Jz3Y/%3>3x:c=Η25%ۓzt9Yw^%U?]57=E}ݹ-ѭG8"'Ⲙ|l l25nZXuEmv%&Ckqߑ^yk,&V"W2WEdmt`B F8y>=Un)>@ \_fY{p" \e2Cz z 3;.3=p ~لk⴫c`~ '#Se&AAn ,s/<7o4\og< .t+b@%l1rGj'Գy|IO'%h-G 9K˞1kYz _x^ _% ; qb*1}z10lp]W.>T/|[>]dXh+I!|9[q;5-ǎs{|^UV]ô HƵz?`gy^Qy'0rmsZxCO̡8S`U/|njE6nz0u6xk$fiQW5ʶߧbjvbPgg5dy.k~ x0l>&yu nrٚzC"hRa^h<Г"Ϩuo'0Ab )z!f𼭴9ыdod>}\ѯ }:0RU8/0!Oe=i~rCN3`U> v|?fqə[K;L}PjqvW107 /761Wufs=.3qo̡hnu@Wc|f.(G}H}9ǸH;F CiAȡb~Ǯ=MMǠaM^&Loo1u*XW)fql6=@a̱ߐM-Gة| C>^ZO P6-jJ3͔scf >v~r¨"L.j֓AOmb/#}X#aeUKcm53l]|NL~6vbZh}mzNP{6cpF{`Q 0,8x'o:y^ٳ̼V69ú}\A3L/p8Zr|9.|W̷@DTk֦⻣zS;49 ){W2ە&(4īkƁ<TɣD2~ڝ۬>@Ny` 5ܹ𝬏Z-+7+.܉?r.W,k|*ΙSO0 ~4+3Zy}l*3ڜW %Y!BNsZ'>yXʶhv*/ ^M[=,c9)g. d93rbi>欈+2t֬2Vqf>B?ș̤yKD^gX:hQc =ylÜ)~ 31l^yD/}W{ϿENtr[d<Džrip]^c;aNajU7/ k0n0^`b8 vм5 F[;ig+)8ğ侁=o&.k'߁sxx`dN!2< |jq]Nv-O]-{HlOɿv)9yȸ93i~m F jy"K<?%:[{93cOWet78㊰+DžPf_0naSBSw /i,z85}߯(y܏;]big1:! f0f*u1cYW2%:=PcVˣl*q #}|Yv7Kl f$EG*)=<]vx3"˓z6!CV^\b9-f#򝻌=)pM_kLWSu|;`=9=UV)jzUr8>j*7̜r1bffE/P#\9b嚢ƥ֧_k}!xe~9wg6׽0qO;j<;lg/)nK}8OLu^I9+tRI7*wqK,0O$|0׉:d]myAU?[\eMEoYZ^Y^{|R0 S='1e}a޿ڊ] rpavN1㸂_?cv@.'2lQR.%O[@MVr0;~~baŮĸCHoma|36wsڼL/6 wb>m۝6?Ǿbi͗"OŔ^\,L6tWr[)$'uwL9pY &. qI:Cus]+6{Z jQW2WBu :C՛;gKYO_&Pq[4?d ?a pc{ta}[}p28j{EIGi>z7^,sl&o>74__|jGD>Y7)EN--%^rG gbPkM I3^>3sT|0Qm\,%;!7Gyyy1R7%0W.=80ħr1r+>U,pۍǞuÙgN߭Lio\ "8/2Uv߅=D#/3Egm.f^H܍ﴀs\aVL"V@l]cb" _)wԳ#wߐy_*{萯J'N7?[=wO95ڈ>c ~OY_N |gJgmR_Fkf SU'||r2&w8S~F-muk}!wZ.mM..{ʻgd,6_m5p8wa15%Ok4+^B= )-yNn.sZ}B!ou4gSb>a; '|Sy_M_bHc5r79DlÅw9 #cȸؙ߽( {5ڎE`E^I ߟ9if0W F/B.`=G3'A`crQk7~O ,簙#Z ^RgrK.u؅f}eZw_9o=pdV*_s?n'`D{i'MS[#g"+Ѐ>\;mHP0;i^9NkcNyPoZwךŴc֨=DzΈn/en?y<.g_  c4 u2Q宻1 C({as+d9ڷ7 F^ s '\Ӹt*sr7ҏeXMn'b]e*zwɶa n<|Y^ۼΉFy:̥,V%K|YVgíjTPyx49|Kn0vSSNzaG÷ُza:1 5׈3tIX.p&l0la`mdY`-5h_aK|9c} k~3}nѧN7n`)yl)NFT۹]{h?=CdC5mc27<wәky?f-ڥ^< ߧ|qT+EgγQ4WY5|oC{|Lk8bj|KMUaN8OCJ:sgm-wt˕ةqګJwM$ϣ3v7l9l~-Doo3'sju>WbHy1k;F@ћӚ仼 1=cld?a9=kIGV2ޱy5k,e qYXXu.{[f~z >џ9mD0K-ɋm?_j{/[G͸3a0kkw%ۇ$sm|rxe/:0x3oOӾp&P,Yb؀NO8Y@Lwu0a6m@re\Q>Wxm`RKrBd(c2; )9,Yê3mob,9oZAK;k|so5'&Ѳac51~ αA}ߏԜcٌU+r ɇZ̥nn{oaι_BNdUSTC"g&~JI}'/b xN*-^5?MpY=!cg." .-&x'mE5l8Kp}0كYY娯ǔ2n0{F-<2v|MsYzɉ錇d!N^ݜ9ʑw&:7 xsgfqMnvaOξ<ݍ%0s=qFz4qj'`3&༯%>v/zq] 87"1zSVlNwv>8Sc||(KLY s8y3瘃 ZI}j]#xbWR}Wd^q6J.%FpWɯxOzyXL7!CgsB-<ΊE&2n_]rYB{NwoN6ʚl-I~#a?^= JŽ\ۜ,?.sk{ /~ D.uN9׈Xs~_s\0;f^:ȫF%x[gӺh{VdS=r3g_>lF_>v@.=Vpg)&θe pJ.+Qi~'=pV2, M&2~9 :0a }GT5^nzgJLD:` 04{sJ"eO/k0>A>#vhcAOtuR렭aĨy|\wu6~,Z,Vd%)QZZ{E%4 %4I) JLVMBbiJDH-/rYj/TbZS $P9{43=sg3P2Oyr>~v8İGDI,Ԩ}c4(c)y7~ё#TOON񘽎wN>[wsK{8b"罃\#x0K8lybW!$!/ɰ0ݿtelf /Ҹ-в~ׯE^]EL0rI=e`51߇ķ$;->kV$gH+\V{ŏV|?kO땗\wl֬QW}?,Zkr~:W9P==nVrY~99ZNc5„ƁuCN+5&m"rԞٽٽY,Mn|*σ"Kgl :vk Ƣ'rŲg3!yG+੫h[k)uͧ|v}Pt;sǵ}Xtsĭ?p"kZ_tD^bnע=%ۣ[b>6/o"^><NyO5 )w! GpQt{8עj0~Lw-k5a\tNŌʌ7-z\a1=m! ~"X\mUMU0;> POf32DrtہT^~i1ÂYk;kݣnqa~O'#xֆŃw?M~աC z +Gj/l=zY^'3kb;c kZ-l1Ji|VsQ7y{WL9Hes1OƨkeηW;=u{[#<(g6L}C,߻ {ayErKk>eL?R>jԊiss&ɩ{;'ֻSכsGQq`eVrae{ly?=BfK !kחO5'|>'_md`ƇN뽾ʤ?Ys5D{0lü6;ر)/SϻVI ;ZOnev; <}_U15+`tI 4T Ga;-Z<6BYZ&+8֭6M {;Ϙ~4ڌ֨4d}` ՟uccn!7L?\hdC.^㇒8Ӗ;kٖI3a7;y f,`c6Tr/㌷5znns>Wze1ZG{Ίv5ޟqG TYpY/r_)$yGM}i:}Gڧgס'j@~v wC[`aiyvq]$k6.>?k|Pso!{xqYܰۮOnלr<5eյiz0<Ʀ.9z&V71@/kSq^`ybT`OOl%Qm.P|f~4C;Hf욷7ݝcfhy;/?S2ӊ+ϊ=}ȔoGz9o$wZ2[2|oUK,PgN6o$e={gO&nygxc>&M~ۨw9"?]Q铚G1C_|>N[{=eU=xʥU;c6+[k۰}N񕽔`sMhL}βL7T/=̿-}*)ʿm6> 6syua9H>:~-64({1Q4FO;=k;*bZqYh5{.YP3;^r?MMO56&y>ݮqxWck1n\~0>>GB hOP>8g\o|똶تiaohee:n8]VnXhF oxt'h`1rLҏo҆+_WG}-ξZg'G3\q>7RT .]+7}Lg?>a^}sZS[2L~Ϣɤ20guuMˊת-m7GO#n6kcud3lbܮ<04Ĩ\lqO-#!9]xlr0_^tKL}on6̫cn9êXn[r~HhxQQS< \\ijxzL_4~q*f4 v֟v~9GCm']VGڴp fO˽T诅A?VMf5oss ~Cܰ3Hgoi=V-O}ְM^Ι+;p+:f5h>XQklZWl^ÒrqSP2ȧv.S)⇃.٦]gA_Xb̖~vưŠU}zkg\3,0 ,/3;Ӵ&Nжy!g&KΝ7Uר;nxnϩXoy3tl[`xր|=ijy]9Ǭ.W0l}vg>֦^C{>Ŝx}S5[m/*4,\Oyokt诵K1{5/X<m|Ca;z)4[=`\/2۞Ϙs9_옍kw k3:Ohż9Z^jǷvMkg0FUܸH`y}$2>eX͔65kݾsy؎7RrUcgyl Y{ kӡag~Gcr QKYU{;ﴶ\weX!hL<1<L5@Vi|m_d]oPt匋v=زuo/|p>sVXr~ֈY Lơ1׉~Ħl2hl2֎<~O1| _M90W6 WiGOש[~{XmM:es }kaܑ]Jmp>ϙ.JXaS>|xc=~~L 6βD}ǢVIm=ebٕY{۫Ci}Dg_g }exu {Mܾfa?!ϸM3caVs:zfXikxlʢ₫|Ih}v6}FրjN{_M޳c=}/͗i{aFlFv6HlCm.f#}!,/z[۟L~Dv/ӾvPqpY>yL87-P=1k=v5=mu)bPo1YNg#-к(fT FZc,9LUoKa>8;]b~ږh-vհqո;ϡY9g˖a:9翔] N,͗Eh1bi/pEk,k?ua0q3h=yEހ5('!~&]$1{⑭) EZ38*Q/l%&lɖ@Pj~oE|C.(ou9\+rfu>0ܹk;g|{i+z2nW;;I9\k:ڽ6.>9{vSomν~umêi#J|||P?k#4L<^_=veoGG 1]} vGRwV'6ýMEfWr܋Xws*RV7 8B0 2-wv9`7]/[mmuntB1_7_9eXni4źufX#JwVg R8A,&CovcuDr/3qg8$krX'yV~w c:ۊcꦱ<htAn?y6nU]^r/~TMr?v{( 0r;^n\]1u<,7twLL:P OzF#]de=c96~3ٴ 5?'zEgu^/zql,ֱ`cRIng9ca,1W={,}ܷu, FO}6.-=l%?_" k-4֖ծ~Ad~?ya"r0CNېc 7b~6uwܰ֓G MYx\RTV#WgZ4~{J|S L-O$/ WpwEv?{(ѥS{ѱeHp0)ѩ򙶒-fO+og] YtvPH=WŽUN>"M"%}7wc~%9 )qkfoVx8k{n[aXl뱜˥qmie3v]NM"ۃr/|X_x"~ xuՖ`VsK,(p'GV5+)_'sZra2f9q`opR4*:8 $2%gng_'vXW gLL[9!1sǮqFOAl@\u|?}PzϏ b/'K/}6V-CYR6D筇sž8*c8> s#Ǟl'>ı?ϳbv½&E aOzR#1Ef~ cN3bgFrc屐{ `E=&V[D=-ggW >vr7\ɿFbi~|n_tb'Z狌lw[Dz: mwZk*_Q]ʾb>N1U==ww =agAn5u$a'=:q^:p\^+E:?>vwcF'yo4yf+KdyY$ N!IĞ\⃓bnC`s4Ⱦ'??7|Z{$&RN}9v:.XZeAEA=-th8Uet|pbobpAFa>Oα ENjڟ{ ;/u/t茠מh9{Me=L11h6`n>q}gӐ;{ll9mT{Do_86B1&PE79;gEy' 8199ύ81v<.K"!myc?O0ǜJcv?̹B&ՠcpz;v֒Otc]|a}{ZIQX"*S2$|ə8^s{M/OsL/7f-Sޕ)ֵ1 {僱0 8gFw)sv^͞o ["("ا<ۗQ1E"XD ?q?Ǿ$?|etg8w-]WnsYkpT鎟D'sD|^2\-ߵy9[bpYWHAe,p^Wc'-UN+sm̳q|[>-ءW ױy=C3 sψ;,Ä sNl\GV9 ]\w'UqQC \k9_:ϊ w] wgŽiB>#b@FȰ,:5UYߝr9,8:b!WH"q]%=Ş\kvwS.w&/&1b5_}X%c2.9 ?s|@]Z8-ȕp'M.L9& TX $/-尻yʃx z+9+p;_k{$\gj'֐tnZko>x|<_b~wE'OP>W;y&RYp{ 7{ͶnVY,W?ȑxx]γr-;$Ld|Rτs>(cM)kSIXҭ+uyξ\Z'#Ǽ~?\BJGgsϬvN|A|0C8A9}8;aϐgvΐ7S1;&`$':W1#V:f!G#RvY!o70 *jϸc8xv{G>Mܭ6:rfpP?C\:Bѹ]C]8kS,2bwY-aW<.yc Wg xQFS[T4+^$oؙ ȅn9mG2VOm̞e9ݵrcgռ$WY)̶ئ\MtCы߃Mb> N֠39E_UL[/F]V[NHm 䜍Ej(?_). ;݁X5XC÷ܫ{>Ƴ`iX;b(7RE^6er>?.2@G)q>+tu_t$+ tUbqPd&>{g,G\43J#qx-.4>1g7Gk7686 {_< CGwLuR;p7uG:XOF@~{-ň??fOOpGM׍b;UeC˵` S%V: }U' cj}LX:]c}e-Y,}_6'\'Vn;U~&L݅xvQɨCm9#MfO^F{8?a_sx(tEG,sʋW/$PGd<Z@3% M|a[3ncppגĵtߧ}[Y~]^~ f~H #:wc`dtQUK8or ct!wGz|V.ܮpe"FXۺCz"OB,gp v[}m_!׶~"kDdZvqd;6im[w?#42};q}wjJW^p5ߠ]@ ݡ aPWXYn2~!碓<"^y 6ao3O,=+˙@4Dn#r8b/kc ַa_JOX\wT=,8Q[JJc޸./5iH .@*/yDfP;\8zDɥ ={$:r֝ q_En ț?Dx my1VO'ֈawtz{[6`T> Ck^FE *K u wPWꍱrԼUeLxYa0<[I3?V^w?q t75 -l})Ӽ!㛇$i7;ݽ19Wރ>ځQj_8Mױ]lKg}-H1}£& M;dLazVg?G$n$j_WiӈzS޾G"͕{~;+;"CFyG|`ylN픙v}\ܷ_18ޞ;-mx@&_,S7lZ}m9%;}\]Bx(0sDMK+-qC ="S݌ V%;ytu?e#3߻kwzh;BO>5!n/{Ҿ cn*k LM xoѷɽww{TGkw2~}{߿tNy ɛxi!fk's hg8 QM1r vιEll1؃׫^;Ҝ >In3LL Mݮs>b>־Po^d|&R31x5ξ事vBkuSv|1f~6[y>BA-=a*)qɛϵ ryW:mwA3CTtڄPU=Nf ?~`2|W鹿t]1oTo9Xs;y) vfkwutia}^p#1N8xPn,<+nѷ-S⾮CΆk0RL ܂淚Qfbġ`o4EOro2N5-~$a5N4T\ƹb?@hL{Ln~8筱u5R7|+_3'(g|` =\+S}XPf88Ef$jP#v!_r[hS'oxCВul C\ޮ<W}59jìi){}=_ SLn_$a@(dq38Eq>qٕ#ja/(L!a_.l E>X%vkF:yk"o3NtwM{N+z ur?#1E֋JEyMGX5a‼O[y'"NjGTDovZk& ?WWnTȸ\NǮW\n}ACw<N$@7og6grUq`匷~֒ e oIZ'ßG>r`55tz5VS-7̗$xFkvU?`vu4kbl|r3z.;By:eXXN/F"6)~=xwكo⽼O4yj0'2CD0#W8H^V9Z/juK-ӒfmXQ.kEnV>?V<,&OL~3siϩ+!||cBd[cf3@^$rڵf~nlNiwZQg[}[kѠ~| J ٧E9F/|5׫lSgYo+73">="~&܀  ϫ짷 "ޱq/i\N![U }UWG>M9w}<.0oFr,)1?z^?/p.߽ H.RGy܎=h%;o=Gl ]E  R fz*z>koZ?15" S1?_b>_s,~^X?uy0y|qE[r0֮'9߯BKd^!-Eb{3#;+>`p<'Z>FD>ub8[̾=+^RP2\E7s2ҙMW0=-!l^ޗcywӗoiGy+CSb')6Urܿ$mɿx}¼}+䣂\@m9rvþ7 :܉Ps j,t ?H_ᵆsd.Ml6ݱ_VوJ?3þ)ڌqvG5\V#BN,=GA#;yj0Ezy]K;vlHz~W]u}Aאe-`MO1wE12>!GEĦ5e: [\'yO.[c{Q^{0FoKG~O XBN G+8YQqjd'u\?w?` \盢ck|+L3{rU0x?s&WDIQ˳AWgh9/OurU{`E'1!WbS]BلfSAQysF>sHM.0{~G#`dۉ,02> ȗ|1}j:gr;:y{h?:0q>+E:q([erQ؝N].2Bd"W0rɉWY b̝E9n,꫔ߋ8%gfG[ vء cK~\M'.gjkKWEJgv&-^.- 1<n7Ni 5G]mv 8ѻDNb{Vr8E.QB39{vLg[r~^SwG!պVjAYxB:nӦ8`d'RL)ó{a)Sl_gXU׋|ꨋhL}sJ %G9A,>f"k_#2ǭĄ:u@{f}3e5=s\yW'~ї4˘Gg\0dxA4r|>OEڿ\+ϸ[(61~|c%jSNJ;/:"ggߨv@h?+,z8Cˇ-GDgHq֒h@ѐzG<< "F^\Uy1{_;~A\h3r-r 8J̷2#?[箘>6hn5Mq yq^ex Wdɀhu=l |_-yƦEة.ftXt3tJ-OAυ#wSl*t2jyI8A l+5?lõk'ؑclqiNĺOfwoy>X0>ce;G^=1g-pvF)#sxn_X ~#9 櫼Pmw~seĄ !8>i|2ϣ8a|6>_b0@,#ۡ~rgzÇ!cĀ->Dig9c;ci68b/5p:\' >9îQe4:"Ahpww9ȼ-]2{eorC.LyUy`Bf|MxW\=baW"=c/cc5 [}XZ$w}kܣAb$ N/_v"r?W{"bp[t 4lM9ĕz?Ϻc<PB, |,vQ`.ir."|ل+ VQ"g"}a=k6#' 8^kcc }c&&yt62nU3nB%ɕ%s_HߑUuT.rdS]e1YD xxGr^;#Ckt@L3Gl~kl6nx+D?Ǝ'ƀH Ď56x~9Om"' {l[_EDZCjiu<D7p^ l߷|nKm8m[oi:/ttc7\™"b5e$;c1I~6Tgx<1k7?`"4eqcx3\W\d؋m1vA[w&r޵K̡Myx08:,9l 87d}H{SmH͸x)lB>.0Hw]iܝt3\9Q~7I͇\l WokA\ ;$d-L{Na7'km?YfRMg|M&sI=&! ^$Ǭ*zA^I۰=H9| NstW7Lc)0E 67ʩQkG=B=a1|wǺ m]C ɑX댧`QN<璟k?!>`jsQ4Mo5@RF}]Ad,[N #-Zcm^ )7Ѣ˸RpsP1l 6x.YH=/RF XSЇf/K#0P?F"O'ڻ2kP5Wf8Yb'"g^qHlAUk¬JH€_x:eZ۵nO=F}^v#fF}`pEw?gǽ?!5ǞɂqGyץwZ[1/k|fZoB{k1=13Ԉ3~8E~zT}|yM_gϤ^Q,6$\;/5 [>YC.>'Ma^;˚0w$: Xy}v;6kG YGkjp؏[rc'ж''O#κ*qvax2 ?sr,(o߼x)frUg}TwM|ޞޯL>M]$9>~kG:>c8zY:u!.xه˸_6uYuw/{!46 u'Hc ;s]AVg[%(g9654 >$ SQ#oZiuh;9e3917OAwc~Q;_o`/>O2k~5VsY_ϓG]61 MwTLэsE-Jد ~v D_~984v|Λnƞ}mqVn&km~`Ԙs(o<M<苾uo!>{_f6r⩢>@qփ{2z`gra2o?rx<ϣ*L9/@/Gw,F>ÿm}}1VN.pT#zۉ&5O qrppT"ݍ#^ ,m|v(K{G\V7YeysK5 s\yĢ|d:c0AK($_>j9kbBx].2|$?C_=8m^<}PI5EY6H)?-EY|Y"wKfLWg\4`;؟@d8ؒXuWUnh:ÇGiּٯ3ݝDی]yB9 kE?T_`r :x ۘɵ bt5؅o||N?|ӐC͸ᗣ TN9gǡW>߻w3W\.#žu=9Ww 9csN߱| X+M+[^Fay Qˌ:K:#<{qV: 9wK1>bDMIa >ěAO3<9nϭ`/z+wd-G{s^9A/A61A|. Ό[|9(6yh#?:Nk"p9a$%-Ya}eքFuJ_fѝmrx>#lBhsGrt7-lO} ?ޡ zIw^6ٚy` byڙ9ODƨF޹;(0;c̆<)rIh0-u=cVV5`knk{ao<Ӹ´af s2.\7o[^y1꩜\2g< 9zg^_gE9g܀O䧻ŏ+wnx/GC`wHνAF" bY'^(_ 3Eb3EwmaY0@9ŸWdEyEU\NVL.3)#Jވ|ad;m dU%?/.ڹ[Fn bCS!yOc37P3 /'z C.X赼7V)xs5Ed1/菱~_5LsdW~ӝcHt*E6gXa2U9\ʟs\{+ 9b9XлNNy{K}6} uʃhm#wv+rOsN8Oo>cٽ|{^)u<|j9a:-; v3|C]0z+f1[h#s<1\Sxf=ND/M#^0+NICx/3p\iO&UⲸ#lnÂ{|RQy{g<.iNdD a5^{N-YO0F|2Ҹo#{ / 3GNŇm8WD|4cȵTjvH.2׸n 5ߩDvj+F YmG1DŽܛusVogq2wKLYe=9濻]y57, B.Y;s=5u{⎦7d\!xW`I9/E.a_ykWh[48+ۄ`p|Z3Tb ^.2];yE$SŹT ';+9' {)SeŽ>xQ%a 5;U{eOC\Qʭ<┇IPMz2c -ɂakkZuA}d/ޠxx1}[T<^5CdfYX ]vpIw5+k{t։;uPWÊM8z%}SNyR:_L&kc͎3> %+~5f?. ݩ&ƺr-ǞoΆ᳟:Y$Π= } \ _UR|7rd=eSvǽY\Glg6ցsea(ywÞW7pXgX5/H*1K=OdOb}<92<='IηY56]d|Scݼc~5᷉ż?!'"V5hݢNRc ow?+ l.C{!rUEϫ<#O;$c6byФšrq4 +&1ݬ_Nq|^ +C3ޙu#ŻZg1~b{}k|`fR}K|a8oGcbGLˆ',^nj~1|NԘmr}2b==E5!]O[\syUwz_,,] ,gܚ t'W/ys&~_mɰ=ba{ˊ]232-t^}լ&0g<}f~n=. ^{ɸxPCf}Cs_)l9OWwra]zmCi=w{׉yܦl1א}0|ad|N)o(:Lk.*g8ul>BoZ#QKvf5>g5^S,Lkk6=CJ0&Xۓ]ֈui?O2hXό!gd12l2'VzMtLz>@S]_e{qW 5j9Hś|r W.>|ӡ8G3z9|" >ΘeMq?3|b!CN)n$7yreϙ\+4MrNji?^o s~gJh:/3|;\72MLaű'T-^#1]4]u!F3,Ɠc}V'ٵEKw;vyr}V]>kշ C@턷s{\aӱjZ2hkn6dԮrūml6Ν"tДa_,:1P&Z\BR'6k *g]_22liey,ÌKw~4>Cc4!ms[-j8l vЮ^q ڵW5`1sM^"c{rd\]n9m~m}WN)ӓa-G9zkЈ0^ɰ=yu3sMX3oqY<)-Ԙyشլjc>mu7-1&}yLX V^I^7Sut/$w<~ϧߞw}}}R, S!Z+o>ow]VOn#6njٮ-'L6gN7\hu (1Cew-.;QP'e 3BF@Qbe%5;9Z#՛ ?f,684{O{&G,Ɲ868_C|b+ǻnνr/,/x?3L2W JqHvyΕ=oX/1ɚz_͏}ظi,Y5e״,Zj01g(Va!s#O#P|^ kh!Sk 71S_cre?!Eǵ_d7iN=bBe^+K}4F4`l?l$q~0:3xlX=.H'SzviGi?q?^gә\̙GQг^2ۼh4[);ql`r$eߩt>w~ZBv-=W1;S5gz<)3,[QZG;Zp׳B9+?,>B/459<kW]}K{*fn=G4o^Ϝ3Bg-oO>k-hO3xOXcKzsn|IsY۝^\yfm5uȺ%{|4΄^c_;bJz=S]Qr͘/_^fr;hL1_wL>GsU*>K,abhGQ0N(mM8k䓮X|Q35`ib;2&::U2_TJ턏wsi;g':L%f/4G+iѰ|ݱyq~?_fVՓf]2*}#ͅ4o.q)5wډ |YfT_`k,pa͏^ױz_;9a|,hfbV՝-V;iQcwMq ŀ-Rk7ewfsܗ|'~<([.0n0T9^:dhXTG[$V7aӬ~0L"ߑaszNLogOWbYz'TBO4W|)o})SSO .pgŚăTO;ka?SfOc=NqI~;i8YP#oye굔Yi zhb3n]|,QYrV1w>z6\?0q=?,~15͎L37X5R37E?*v/5W6x^g~if#5T˚Ȝny7+lx\/zF3|uХ~Ac iIH _XX%tv%;_鳸S,al>{|=X:)E^^rʮg3&KԜǻTf{z+KI%+nKM^5fU}@v^wQ1WwTE;cyϟ}oNjYz|^c’فEg[[ϧ [Mt7ﭪ^I: k"DhL?)^VM"ȖV@P4ZŖn4lUQǴNtϢN2ΌtԠ饪{s{+Z=nl-9, SLg2Vs2R3l'{6)ZorCn.i~kdZոTmRj⹮Hg_tn@{I-R~ X=L[Zg{ֻ^#vvS9Ul7LVjls=nq.pchL;L{6Ck 67[>u!3;tυyyم>bb̺{SDa\d:vVwn~?w(ϛ*.yb_-0wW] qc迅c҅?sz]w68nga;Sc-.f{4oiu-)%3vk4tWj>A}iŅei)::+DGNg&bgSոc7h nPc^kl5f'Ca7k g*Uٮ1 լ_糳zI/Fhwozd?Y&g괸E=q:wqV_W};;?!~X򹇠.("ĦLs]~|6'ZWku=^%'k;B=Y+)-xk#.ZLYvEyGakj %?=P;Jm^>ucZR{Jyjvyυy7dPrѮ.q'jv:C 13mj?j2j$G'؎Kmniawgkgx;SKuA,~\gzkυlo~ppGan/]Y<˅]-JSḐ\zgO:yqo.ߨ~Xr3i'{Mor{1%o4{SCVc"x57Yyҋnj 'vṱßFV$K?Eˑo峦mIon=ܞK|Kt/F'>|!..Kįlw ^)>ҫ]nT{wLz?[o>obʆq3}_!\B0?=n$s,?|$ qN3-} ̖ uN:zaX9]` ~; ,XOG)zED_ MyΤ{ =tldz< t5pi:e<xG&|}C|N.=`vX<XiUJ]r`W$6i C_OO%C;'?D$%=Qt_imLU~fy611/D4M7D-b#՘gܬ03:ZO9~ԇZj8 Q+w蘤hb`]I'Pѥ#vK!~h!주EMJ|OuvD"yCynO{XFO&5~X(fAuo>Sū }.It6e !ZgsϭQНȯs̅PWݍw")ϐ)pƀ{؃r)|`Ro|G L+V'p<$oq'^Nxԉ s\˓nDu8K<~GO^!:":W{c-"zG+\MIS[cV.7i6Z'5yQyMeO)#Uoܺޞ]3lDYŌoFu2B~Ί:٢6|EOm{!ڰ}[ 3Q"=9> =GB 8})o%v*W^N *FIQr$N=|ӝIl=;XŶX6Aܾ}a:;̟š _8xiFĐ*0a1zn]n㢃m p0sI:?I7V)~赗raTj8^䖰ӷq_e뛎p p869Pwv[&5x]GozVe˿gso` :PpȠU&a_|B |(#_/\.y^z cmؕ?P -7*;}=<0u^di=vXJqut7;LC<^0pp9%&<{EV2x{ J (z?i:&rR[KrYq|7~D;cV7>9OGt,0ςbLp_{ L#JJ؆dySȤ;|Q>0|1+>;DU:2hHΖLgܣڥH{7C~U0~^fs'HdƳ1NIK90+-Ӵ1v qMOkX}KbZ/"_1.{3|31[.HTI":S%pi}rYo=1ׅ-v^ݽp+v 7 pyߣඣz2N8{ vVpr㦗FON+)PQsuʨ}D;[ O9.ï$.\z1G+<1ywk^kiua/fu &ey| &yYi1{<]}[i7lT$c/pc؇48ŰkyW~S[0m3+w14|vN{GO\I"Ó/g[q-8j\^iu!PlņͣBQ 6cӯY݉V]|βbSUvF{x9Xyp*o|~dQnp}\ _`KI~-u8c}԰%bn])vg(v{"Tbi bqF`1ZØٰj;mJvx@pJv˙0ZpCN ;ְ^7r2Cm7tXc!qERc3U>#]Dp_:i*[O`j%fA~~ip<-k;6053^>P])n9Q{XȘf(ֹ9:F.Ǘv9^$Z\㿗80ȵر+F;u+ٍ# >hW!K5"4[<ׯgoOi~F?? 5^Qn2n_%ʤS)JL=ɿC:D.٪w^Ks3xCƾE|kw䵾p|'x2b5+}2N+`B>L>,Q,eV vp6b%*"Ïm-(? q{?1{+~jfeZ`kw4R\˷ӾqwXy 2>}wyݢ[sO+oprͤ_)WVGQ,2FYK7Hbܐ_[˱!_[(9jb!).߮2&BY$Z ܛ'smiQ` ,Uzz6ҟ'X8مyAbzJP;BYO\a!-7GވWQh%ei zR!96xHYٌ5F;c!Er]@/f\fW7Zg1hV湕|+WrX;g +\lB}e1</D^}cczc"x~'pRɨE*O7YSh|Ec*[ߗ^|J~9O}ArB_}{B{9SzꑯgONw љɖjOtK|VfL{Ø!r$DY(Wjou!?0%gRc  {kO0&I)G F@=>fOXbiq돜[Y(37EKʨ/$:Szls (ojZxQÌ9?K[kW NXE>DsL{{HİWRuC/ߩ,2x;^#*G^Ggw=M܈zy aS1>f9gi)ǃe{;7P31siߴgN!w{;'s@93O%|8\Q{ޥyH7 F8Eu07Q+Y==n }ӌ7qCfoTα? 3G܅zƪk߮M[yN9Cm]r8YJ|Jy*ϰ~KoӦ!˚˲6?7$܃-_<ɢ1kdKD}w5ܧݬד?~>J}O9 {P./>joOО^׼Q[nwo` 'Zs ,Cܟ9-J $6;IM>ze̥$!7aCgjĿ.lQ<+[sxޣ.Xs{139ٰYra9%e9WW%K]9[5FOW׏ͽZaa- ^n r]ǘUuAsFOO1c KSy9vcCF9n^W,H,TjrMg.pXgi`{'U5b5˓km?"?k~"vs>2HӏީsL4m<̭guv.xMw/>Hmƈ)9C*{վDqξE1?QwDYwH|:*qA4wT$9Y3_@~9Fhguǽr_GU6 S1[qv)gNa 1½>ܯ}`1Un?zTje-=Anuc UYuړ95*t s!X‧ϗVߐ[F=(Z@8oLao15Ә}u_~A7-^cߛfVL`nfLI?36}}>e;hnwMt1Z#~+gc k~/{gԗ_Ba?}Dɏflg?$_'.C zeA^ ~∯uq//-^L֊iSɘeR];;]g~('1>?bXeeNXEzĬm+%ڋ>ރ; ~ "[BMPԯ,ByC]̑K礔ףy>*Tz61szŲ<^#.?j6hkyif0vgU:M\쵯Jؕga ! d%yͦ ={DK EW+ gL#5q~/}8/)9avsqL =!PU1s%؛,aG1Z;}7oV1/ҷA/.c?i:^{'R̞,cA. 2V_ϸ5j, \OQsbQhcqљk/|'[|6&ުhr9 *rqO푡pXW\N>>nי.ZupBwe>jDƢ0H&3i{ym? [>RasGqv9t:~]ryiഞG ͼCr9*sVm'\>#DgL?nou:[!;5s:M;wM^g+>].uO[hKvfooiޥw4f#XK{bnęwL[%$o}(R?2>OB {byJuf|&gI{6x;zoVU'Dܭ 6 w]\{4}^d}kax29<@]C1z86lXNǟ^Ϙ|Nl|z; @c[X|lEw ѮjMgFf}g6[9esSY7V&ahwuGX|Y"_X, )ofƾ=ozLaeu׌%`[M8'GƼN,ǥcz{>ιط;UΌ@e^EΈn96όsI/x~K:M Qa+tI_1J}s D9vz=q-$g]a^@G.{Mwy:1R j+l=csu yrҞ~|ݚ؎KJnw9^Qf :=˷Arg3^qz󴷏w!~:̣W6Ys!e1T.Tx1z[}W`rw}] #ҳtmꁍےu% r>?g1lb\0!?6oAg}Lhl"tgA~׋sêuӁ⡿}7!Zg[{7KMM5^cg"YӶ^DA?tۢYvMk*9۽8"FC9ojvߴ>`@M}brB/$䏳8&/g{-ANi<<5H3W^k[L>kb}<W'ͮmq`K->]$scp51>c,7wbNrj:Dr1U .;_ST]SG?c|1P3]h~kz*̈jv{W#Mgo2_v":sxmP_B 1Oz6y+6Ηנ'^>u;Ps^0lw:SIshv={dؿvw~!*n^k]rá?;l&WK/6Af?@S?f(l;(n7c!A#vΩMWq&biP5wxɂDqsWW&%fΞ)?2| Ȳ10NQI4a{K]g$-zم2 "YCRb-r XZnWvz8J䊺,bК\Iu.ҚcVD\窯C|=Ht#J_R ?p%:MsKJ1눩e쓭[3nXn=Dy/qv?r)vJ;}zW{Y:߄^İk|^4ψ9{85K+#. |{k=!!eZLj}/b刺Nb?pNX>Ev彖?-rQݹ\IQgV1)y\g#~0C{,S#It^ Ξ:=SA1߆|,4FckL7}>g@GO yrk>] ϻ |Jso{~.`STLj{v؋+E{M gPWvF(%:;Ng5}=\4T F/{n&9<1q[-`qى{-c4E+LJJÿ+$9'ZmPxXCB16w/WF 5Γh1W,7 k+1lOM򊗁Sٵ0[`4y5RGgM_GqGęw?kX*_繙}iMR\YZ_?*f 9KYс\/hW0&Ӝ^z{E)]DD2eyjaA #ї@ɵ[Ŷ#dFr"v%ў0pk~@K\1OQW4dg[3.a5nۏ59bq⮿2bow)WS\eEw[m 6|37RG mK9c}8kN;_y %أB,WC-9Qh^tH\F(|D>s.\K`&9r5{?)τN㾓^۫joÀ 3kDž=Y&11\.K ܵ(o|$IImTWyMqڵ?sD#?-E<9b9-߸GgKlv;lVp1/l/ dاDcROIfFzjK6$ߗ]k61׋ K;`pl ;:qcyuX(z:aȫ w>*sG{C.G.s_{݊m^(G,W<ug|{:W9r2"&Z%E=X=V1m*6ߚ= h[/5rs=Zs>c쵉+g!GF-=~1 |\1/bXP,0?Zi||!#jX1q; W.ʜ;!j8z`x$n-1/FqW|~ՂC_ 2_EUs5Lp7VyyƉ_ J/'gBmeh1bh 7${-}ߕv5%yzc/X-ZܟךlꇭqcZ.K^J ?4ufsk`Vmǵ"golKؘJY 5f\j_Ź/U'6w󿹽s m.KZ'D΁9(%6[߉]z=W6 ={aWg_IUyd1As~Y=8C*%߮:ͦ''Kc$p][?t3Mla֌OFP^Wχa< m̅d勽1^^qk;iCne񿓈qj3ocmZsA!C]`K;b aZzOZv!Ù?DU^{a3,ιz_v9b =%p\s~^y>i'6SOZ9x6gdp!׶ 'barK fMbιۖ<{& <u"0}%fu6 ]/p,>MTŤY/]a9?Kۀ!Zus BKK~@ 4m< _zX.lǔc`g* mo3|.ө]GyC:RX.{->2c&Vc^F87O"FwՃ1[^}}V=mؕ03~=fO:=g[k9+/{OWs6D۶XsoB<<]b;F֧%5fGkmmOcOlSnbŞuLP|Iگ/iQPlBIgIJ[v_:s{z_=v(>%[d;-pȗg0TݯHJlh"(w!zx h,>w̼Ls߃$nb;ɹgs; ſ7GS_ج_^ėWgٽ j\bGIq٫ߺhr%:P(ĿNL[ܤ]iaAݘb;şN0rLԑgLY؆{DV2_m6!W%{\S EQ fB]j ׌ Hy'}65ldSl )b$6Tdtsv2 qxj$&K)MA5bk.1Gqf/y o]SuCjcNV:in}Pcߗ٘}Y:F=V1Z/Y36 2@̅x-o%Gl:蠼>ˮ7h4]Gx/1C| _Q8N}""I$gm%><{|z_u+Y1%/o ٌ9ns9wΪ2N0Gx~po6M߉N6kREvoG̯QWwo˃4wfC1 dA7|0;Cv&<jnEo&6܏DB<_VV}6[''I 7Sw\v&PվK S6硼3|86 %v#C@ qC|,xLNj?4_wFk7Ss^EE/{YԺ}D{z˽m9+B\^b.K]"N5Ws}$ L(aua8]}m`Pg-b;.EiX֛b0vwce5xy N4nX^DկQ9pN}Xwʱ7$rc:껣~bU1_'=?3,F"WߑL@deswq{Yc[o=6vn:C85A3s#CF.jc.5UT=רR/9yD<~Q9Wd M1.kWn=orO෉q hkb?r\h1|~+)Cļ<6x7: ޻ygkɽrdk/9&|>@&g)\ 7nv+@w=<nh%K|Vސre}#ݥ~)rq\/$v,l'}ʿ/w1[藉7{k}5Ӣd{/`]|`s|k`lAI0BzoqE@ZF4賳vu}~ 8?<:-I*~|\Aa| kLAĩ%?hs):V}Iߑ6V K z6K`=}7spc :Sp_m_4SSΕEUWƝ!^Gf.jt&E!>+t`sq}e`8mg<2':\o_syzEVڬ˜G~GfLyƁt5\W=Csmn1|jz۝Ƹ8{ˬn Y=^$7NK]/>L;|a|Z.9_qfcfv~uSڇJo!#Dcn)c0W,6nxO5ǠˣfC]پQ^gfU[w^om(g쥿7f)9u6\}CyK籖N X=/!B ?5_N=ڢ%G_gy1se+^REVؗ|U~1xeQ{g2{1n3,}})~hمa;u+ٴbThP׹̀cF[O`Ʀr[(=eϱB֌O8K:CծFBCΫu= bkv(cyڟ M>X<nw/vj]5 r Xn*6_!։:쌫38B[z%N Y)h=lfO#]LN+m7s/PA8Bld͕zM֛<ed9]n5nڡ^\uqf{f^kFysjě-$^q`?v -B|UhcN{!d>[gKiB+vri|uA횭.;t=b?}1m/mO|*F\')^uKm7pa")͗ + ~ w$a[+5aW1{u7[W惧56:X|1f~k\}?nw9҅8_r鰛BGKS|Y!5>8Kmzqyn!L1}JClsګ,2>Im^0uKS}y\qlZGKWŽ.7O4Y8;/`go˱ #ϱkPv;V0g>;󤟳)/5Ybj䊽;`}1"z(w!jCg "hϢ)S.LR ؼow3Glqm\Uqե `YNo *uCQڱ1y OeqYj]b}?ԭ׵b1N8}"'#GF# >?.Y1^s+]X*Ǘ 5P~杁?t:rr uMuͦff~+Ff=Qkjh!p<7꿥 XZkZh4/ùYAL^QIwB|-rwl.piL|Z.6Cϣ'?g}{i܀.ߧ6]!GўKjJu3P= a +Zż[WmWҷ֭v,PofXCUJ'Y]>N+ B>ϵWW U觯軷Ӧ4lh` ѴWVˁ']ӾFbA6!>0;&﹔}!pFv&ubf1}vff&mJk Ea ~b;>Navgj!6m69-X$OdoV+y ft7n3cE 5Qj+TǡWg]8 W\h):V uZ?7zb ) 7.>Wi_۬b=tI{v.Էw ?̝I.Lj1\',nc.gal4uyj=|Ong#QBb~Ԙ3;Ԟ>6z/cyڛYSwvAJjlfUu޿nvLvZм,}iak|f#GvqǢS#N{N[ihWg ̧عlu vL oj?cBgYFWg f # u`ktzʇY+幕ܻŬ.aoZcXcy?^ςG槫V>̴_CR&\q4auCͼv esj;{cL˵w[fU:Rl0{1uZQbr@*>uSg}m~>Z3xhij+B}(PS?!r.s6\0u~ơyOk~}u3:~j|+ux5_Gke;_n+ow!blP=~¼YN5Pf15E_>l{ڻ-Z@>tm =Ͻ3hzwy[^a/ %Lvb =|}C(!ǰ{yȅ{\>5[xڒV}vktT#G[`lzOjE1WuaٓQffxWH;5}-Xܭ}돮ugL AwfL0G^s#DI>#Q=BNʰ{Ennbf7|D\{}fGyVӭ|neF2ĺ)hz%)yMHj֏k[zͬg,&nl-&]ޫ5?s9g΀=O_?`Ff B=d)؉);ڣeyxCm^Y:cZ,*y 5r)[4l7Gl깳tָ0:nuΰ1ev! }s&ya;[ ;*oCSgTft}e _wؾSgVpZ#L8Y.[X)fs稑O8pf6 8k!Gx2!n;r BgdY|]?66h6n-9S5]0+_oL[]`aΡ9/2跘!ؚmz؊u)>+WnX7`ỽN2C\K\+^L8> u ^ŧnj^\)2ӧ} ! n;CM]fD<8ڊ1|#m=^^r-.񯥳n/NԎwz9ltal{<+\iAr!u23n5sg9tQnMhX!ǕkSf(1! "&r "<)0/>H#zIch_{/zj֯NZA.RrBOׂLf4r.ߏp9N6ZX!^r<ݫr,:v-zrkt?=TiBecX\݌4ϸ<61v̈SDbF&+z-xZ^ xؓ9SK~9XKN[3|MQ4+9ڛ&.!sa~Rc].ǮѤN`~)ci#/T"z | 3G[\N+e%"Q`p(Ɲr=%wσˎL4n')b\'/צ-KKq/Yu%{y]D-gzG-[/G+Eyy;$~`qk܅~H41Hwј 1$!>AYk/RzY3Z 5s\16H+?QoCR>.Ă3 S|>?<.%E[uKwO'rK'WYʙ.3q Qt}Ik/+MsktAsR9gGMn/;v.Q .?C7+hzWdTOgj_\G:}j<~w.Q^dGE CXg1%OO'Z ._zQ 8%o\JTކE^?O]8QkzʩN[iX-b7ސ_b+ni9"[\siz<:H6ߗ.=adYm'~}}OR`IlM/h\) 0 Sğ <J>:B`p<D|%s':7&2n3p x>JL.{E^%"Y{ӡo8piensHjٌ?(B-ULʺNa#_hX_ frh9ɔu ň v#F*u]cpHn0'ߐ/@ \X"DՈc}<x=0W(E]b[ۉmt?c9o$VQUvxB^5Ŭ7qDvPm4[@_!\^spym'sey=z3Z.V7 6&60%?%&yY^]LB<]HKgX{;&'(4} xb+j=" J G5*/̜Ow̧_<@K?z I,{E^Q3+U9'1ǚlިaٕ͍;U!vtܘ q4ΊEJ G" pRN">ӹ"OSʟg9I(r 8=$6ҷS 8ʗq yR1buNLyx((1`6d$^g=y@;yE_6ɃK紡x%LJx #pNpc6imDžؾxǁ/:Œ>/).r|/bS`""?x6Ww#ljȉn+"Wl㦣[wQh7~??5=#Й(VmJpp>=&򁅶\5rl"Y$1cKT,קVH_x@Fhuh0`0If$ mlqP]1/i+-'P#ݑ}+H:~W.!YKt-Hcp>v</%w /Ꮮ=]Z` x bzpI,> 1pqKNkc^Nŧ(Z{wؿ@3f-׹0dm-CANc\%G.G?LԿl:W#i_i\iY'Eψ 1.“<^9hbb _Iy?p3QNRLl^.Q.=~2|qJ7Dȣ`7"_'fl.?nCwqE6W6#]r Y/8!FμUb$b'=9c&6<&ۀ(:75֣ ڈ`/u6Xw unu5 e""8q} # 9dt*8Z7 E)yZľV7GJ x2!7،4͙x}v8mA\%o!akrUQ,JNHb:>b(zlN# nux+ |c"5nݯ,qوc% vf7J ΍?4ήJ{sjJe0PLBz[v eI  )ƔD4%*USC&նN)qLVҶWh@HUa)1lB/}&yEbَ' Pt99Î=?9߬.n}<>aMe龉3ChߙW'=5AƸ7[i»D1;o]̶PPn]5pæ4ߵ{moh_q >Sa.3}5Ny?z+q_BF| eB3Oz}LqZٞrΔ\Zs'%Ę闑`+׭V̫\g׾BɤL;pJOau` o-ƴ=^>?\ -V\9<OU>?x!O8Q~_.W~W\kS!_yPg'Vk^7]?Lb/_ն^ z{'wY+n}k뚵Y9[ bb{!-eG-88NcFgu|=>yX!!us7HACnbnQM=skho}~צ~uo9=׼g5ݍpp,[Vfr={?=[':]NN5FS~Gǟ}Ěj{@t=l[ Zٯ_DN˽}"Sj=Tϐ1Dw|Oy ycjᇏ$&x1%j%FnX|=_.1x|kDw~ByN_,gK|r((]~M^/saoI!SU(&Za66.1Yٔ/1:908B@.K^ ;Ôo#{D;Any'= uveY ~T%v]aW^#g[xy+Dv/oIq~7GnɉJ<æMg_LuZ]Br?*M4̫kkcFVweg|Eg-@yZk9ۢӹ^$*r{L51G2/OC?1#Evu翣mPq^+9^+{ُ!ޗW*ԞfĞO>w9eU>,鋣v1WO\m+y?j);Uo|6~<{W߯*~aG0mRG8XQ=%OKYl@gQbV?s8>&jrܳCjȏo\zR>{ܤw/{YuHb7w^Ӧ}-~ZDguCq@=g!mF߇NQ ">A| L|Wyɐ7/ym N^y.1z!&/$bZ~ -}K=h-U"§'g{3nfh])qĚ/GxSnVuśє'ݬsjCk>u89>IO#iD~/ښ˫ksB v:bLz }YKfX~ZW "S.f=yx,qüH}_vz~KG4Xb,0atrg9Mg`+) ;fͻ(f`|/T놈N!SL{y2UV'E,)s,>G [;b,@Qh[dZyOƒO[c8b)p_WӶû!yCElj;cbG'"y=rmãw) yg{X3r/ieIbq>"$xv۬8#l8?Dh{3ݕr"﹃5J`}܍l:ȇyIi|Pl'1XkC䎗k=E6΁+\3֐?j5hSnrӟKr.ˌ{# -)jsGq<UzpEп3[+궳.;TkOn1񞏤G~bhpQ[eY9,[ժޣqc[MKu @<8'1mFզiQElr΁+,t\l7g {uǎh/E>e^9 ĬGPWm0&;Uk/4RFv-&Wt`ω@ #o)=㣙{ajrr:pɰ3򺯨־fTt{L;iN?U~v) `lcWD7?3It5)h%.idz@%o3rmsy7zU/EΔbxM*4/w_VE?S5Nl\MIy'&9c9\+V9Gg`n'y3zBV/Z΁5'F 8b^#pvk`9MǏ|>θٟ:c:kBNU8ԃs۰#^eFqabb2iCd/ p5 Xmcw.q~zk=3ife/0\vmA28?,v?9wla뭒BOV ggFm'mҰ.LyER~6S=QdqET氞E6Yfn~nNbn2P{6\O%& &kDdkͣk.F_B|Wz.ؿv|(Se׫~[]j뙷u_/I擭l1Д=R{~0l7idgL>g˜ǻ@Sy¼jm&Wȣ>_w6X:n}3}.-bcS TkOZu vV?_Υ?@omcg㹀mH(kEi̸sH48c <|;?{]M֐b]Zs$E8g-?߽hCAu{>~0zqˌ3vODβ1VsF]¾,N?!2TwrYΕ6ߑEsXv1 Gߩb=^c)|&5{i`4WѧaHkhСAۼ֟!s}N-U{g<|C81';tm>dg}I{qB˽$Qg,{3>ߞxyJUvLڜ<Ƶ;pP_{VvH_=p#`#CIP`|_M!on+`.brۯ!-E_xbsmAL!E?S&=k8f|7ِZ@)dkD_<Ǻ/>a=:嵯Z}0){Kcq%PHj?ZO96xK}6ž8#7_OT3oIy?̪ ǻWgDt>{}f?`{e~3DKkh6'1kzُ;Lk+_IrBY<5\(hPhe_~>yrTXq ^b+1LwffTcw{ݧ[3<.f ~}//q.Ed_f.3;s-Џ|V[*2_RU_cʿDL~pFtqH`$[ttHrez`mJUvAC'缶EUL{~Li ~r>oNL3lO汃3QGynOxf.cOin3!4j<qY4ă1|8bl=Ɗ8vìMgR]jfKş9TtTZŶqoyvGŬYEl fKzYmڈyi=nɡ\ƽG-~Tmm. Juo;d>|upq[Lט5F_cjJfTB?y&"&~#i6UE/5rCdvn:GΦu[5obVfݧ~S[/AaubOۄډKڂ=>o6xy<qķPaAs:uoWX qYcܿ0ޥ[b'_aSs եr?l^c[d9><\Z!#fSmE+Ng-ײ'՝߬~Wt)_>}v0XN|i ;a>2{FV 0S?T련}5@c(a6Drݏ[ۗ]y)F5?d9`6x `^C_ >+!- f8\d)9!g0gt<5=` 9Dr<^4į{wKL\>WArSEtx8YQ 6;C\ 9ߟFYX=c lw[5x>*^g55sوLNU`𕸿0$9:TW'?gE`9Z<*ZOgӳGY"s!G~Vy9iHxXDyzfϻQ0vţD|95j[Wn}?pS sG94oaoi[I`~T{T{|gs͘ 03 ;D'7`C^n!6 ; *@Q>'Z i9װq+>C<6EWTBM9 ;+٣sh5̚r)b Mw$\Uo gT^q2掭 ui`907W7p% {Ǽ/M򷟒WigƘHw*oʛ4uOZU5V+滃sk(lƤ^c8Kfܭb_Ըr__}@̃3mpQ^簮:o)ԢGcBm_x07Ӓkn=U%Ԏ&,69#pv5;yP$mωd J|(r~8G.Qoc Θ5l|CfEs7WsCgøe-.1lH量*B`}b P]~*GqF|5 a.Hklp[A,w#{ts]CTXB_gg@=q;za|[mOi6+8f34%<7j;4]1vFI+v > "y}Dl|8IaϧͷE1srPJ%zGZ7CǸLg~*&Y*9'M@>5W|SAr^{P_ x{q5KW788kZ Qzh;B؎X ԾoPg׺)>aW7Q'keqZjE~Do8q z8}Gd{E{Lul>ɒʏj@kL?jR; !~G}K;\׾ѯT}vm䬧).W,r{\ZM^Ty"~`/aN lΊ|.-B\?Lj_cوD6 ¦c'[7O?,~m?y۸׷|yU9}6ݪ\殩'}t s!pE~!xy6F?νw~2砕o4ⵯ[>[){2_b`[. w[X}(+h}Gpgvw>f~$1{?İ,;b} k蹨ێ_Ҹ7\K9GluO =l·%kgh 'Mej/.YXJQ&4B]HN:mG.q,v}Veb;@"μ^G!Gm\&yMW}&(OG.q=jQ5ԼEٵ1W`=bN`vaƖdܭq(*ξo{v8sȡueW"N4̵މ>垤̟[IZ_J_׋;lp;ݓvBS|7W~7ᾮkٱl<" }#580 q @bw z/TkEo&>9t4attX l9ƿ~/rb~.>> |kYg:3v)d3]%9q9Mk0ゲ~U9\$Oyv&. B5n>. .p9w2ivϓG̘PU$n*;y:kLl(!rC7޵i@[$ 3

N`7U'_ĻR؆]r#اHZC^*Umrn{Wy6ېZsE+΍&CM{oV?oݩb>: Ig7alΆ9O7| [lG6Wga,U^uj'^?#bojWWS/ %>m5}:{E/Xg.kL`(u~R哙CܤY]Woy:ĘkO*ތq{(goq-rEntXq[9p!LreߕTC˝ð1'`n%]ua#^/ZDo_M@49ߌm=չ7Ϫ.k8Om6>ysE;Kj&y/!pb(_o}AvO[}Xʹی W;Cs3n2b UoiLe~( +7$ķb>rAOᄽIY*$G^U~Ds[d؏^N;6so2sLvȔvEƷ]ke܈s=K)|}dգW-WDqMYgSw0'E%vg˹? xU99@4E1;҉Na|)Ѻ\N9`7~ N9Ǘ\;L"1*YGdVB?n+]׈ bj"p.Kw|d? !|N j#xw0r8|`yw?uU{3a볜.-=*r_7/;IΰE]`gh8ck5!meEwI^µygU5mS3RebZ{<l8 ]Z2;]ѓ6dyp}L|'ٍC@f~AY=!fY?)| au& g'w1.yOXGXE D׊tWGؙg>u3V% 5&Q&3;4nuG(_rïaȉF[1S.Fg.-;>+:P\UGOD#f^tur_<۹_9->#z7ƾRn0~svhxfuo!bYSn9'=]j:Eb.'6Q%u'|Nb^Yk1~Os1/)bͧaOĹ=3՚T/9xCY7/sբý#>OлW&Oe_ q3|ϕzؘ#7o+/mq9o'O{?cc`-,[@w=xrfb9zMS=Oe)+~nT9ǮbowCbSW.}]lOǫ$xMlb:뇊1=4Ԇm6M󤶳޽ qm.pO^tvC}sbd塇, n0`Ɂ/:(jA"?D="k[ pTֻ5|wm41;E~b]^gb_׾\Ḑ rڟh2>µhr%Yy8;Ұ|MsU|vҮuZS^΂8؀QW}uʏ30+vsE}<v^فq:WLϺE{}AlůEF2B^7`^_bFP6(w,휠ͱ};omꐼ;<=1aÌm lk3rKcN[ Ό}ՊwQ+rbzQfn,u\e([ OY:h[ct:Ծ⻣s6.z35ث4.UO+S_Jshgo1  0qgS kqy 8+q^kI?g/ދMKe5!n]kQRϊ짳KߔsqTQʼAf6Z^kOJ3=|8}w_"uu2^QNQộ >B9+.YNA[>Mgb>*ӹW x :38ۃlt6N+/uJYX_9Xs+[rΜ^ɱ$F=!D}g_~"gj+cGri!x9^Xޯ+Iɺb6=:{Qxj,t~؍XԍGg\ֱ+xV̡"M'L ^y^>j3mP={I캇sD~ }/>+-~؇pg#%+gˋK[lrȤǾjŤa/P_X-qVɰ2}S/uq<͵x5yqYsE]VIYv 1oWTJݐ*W镬ފMWs@?5Etc L5vY(#[^1AI OSZLcONxsu;9iU]{>9BY 5Yggtr8d|[N{[, 6:| ﻈ/=Gٛ*Y"z-6eo9󻿘No=g%{~} ͬ(G{^\, 56^fdc#u.~F^1ӂ>CϣqVrOj胷N2PF;9v6 Ɖhv~6z<@k0tGcU6hiYrߤy5&as-pĹ0ސSΒ!C]X|Rπbի,y)_up}N;!wkz(͖?pն>W aMGw+5^nMkv70f}2}"uQ- v%켣% =D b xPfqh3N35ӕ ʧejg/A;RmanPitFʍqBSQQkM3]oto[rFuoYmmP>r~WԊBjVP93⊺F{YltapS\I97_kXZrńgqaS X@f^rd~0')yl8yî֘[Mt{#oh`Cj [&fpz0 Y͹кդMOހEn)~=|9*;˜crl316L9x5c gee\{SGKn^knگָbov7Nq>Ƴ˱qq)ٮy>+{ylS<ׅXd8`ٮڦNv=FnbCTfA` KM7ݭZ1h9ɫ琽w?mv掵α:%gن8ĭvF5-vX{Y~ny olr!HBiE7TƝD]66֭kU%C{(득cd_2 [mƻzI.`4hᅱg>rt|J+zx¹@ 7B-dXS-ZvTN7m0Lu)ubܯ%#f|MOl^3 YR}K:EԌv@ZCAE,ŹCN;!& Ð خ w8?.T"0M$3UM#.+J=ʃcQ7],^g߽f6d 9lzjdgנ4`f6] wNFB;-k3^٘ǚ#jίNibD\5vX_udUәaQvgޜͦ/I1|B}hU㊀{9;FC [+1&\4 AQ?*vG3db]TnlQس7Ǜ/#<æ齌tJ.>_6o7\f dnwr+p=l'L([xt&uۨ|c!!`Aމ).gq4jRoXP_j٭Mcxg-Jqֺ8B6 mY.潼M*Qؓ>k\_.ON1ڬZ#}C6a8Uu[>׮eӴͭDUCV?TSz95Tؓn6Ϣzb+[s}XYfx€ '1|V`6QNq;p&6=knDK4ɘ{lrw03@3NU0rՎF4賆mb[iָ jql1>S_0,#|.JjCn{+6vg&YbWCܑz^V 0 kue Թ̰ɘ@\kY~!E.9OtN9B?G5# 1Y wQ;S,==Cbu/^(~˿֘p-$W7];OԦֳC0԰x:1ۯA^=7V1Synq[t0iYs5ͅ>40!ψX36a;#vC0>s;kb/鞙0ErIskk[ kXZfu[ c^ .¹mY}.mNaNkZEe,.9&٫u è̔;6qEۜ 1⿉ժpɳHws۰ӵlOfb͉`'ܴ̞5LG1r>{i\7_j47hr?Ơ~sj*Ozzut-{;-hkd7-_j ? r=OCGoY.,w߬xr_n^æaڣ=`|~ð+f]z]r0Env{KCIgiQ4]xKcV5MNi-.ĪMg{I)%l=9!ѾW@)>&x]:k33H{)EoKq5w 2M4՞%ݺF66Cd< aWO,:-LC. .m%I B Ng/C#BU{d_11vojY|MN;IՆt f?jV_`,iwcA;c=wJ"e57wϑC_.r>k>IzEY.} V6]8b1Mzow\I[ܰzG| ibyn{f4U? d]W\Mg_e vzZN~O VY>d<ַ\h}KCo4:mb鍖3w+i1[8dN{J1S/lOu} QG{IuuZ0Two`՗h[UOZ|sk#~)Ӱ {v?tE/O%Y,; \"XyN׸ϸS d-7>←?Na+c4:~Ig:[&=.B\1:<^qqnvmKX˵6.wX B9:P~ǝ_)-m]#)6-G#Y~]~w8?JoY֖ײ7?S c/*dKQ#mqw*:z㢣r6v=[X3!@+^%?)?pCGSv y/w-c'㟧iIm;SGh)v Ҧ*1m=3 u"+qYOS/|⌽!oW ?q/z+{cU?olS{_Vr}A}{ɵ}]~?1n6{@/zLm=92[עn1y1a~{^'iSZ%~!zӀ {Sg +P-ȵ|,\BUpb'NQd%^˕r/ˮ3Yk>}Zw^{}}wE bG^;Bw}ZBg<8y]FǤur0s7xtƨa<1e8I" qn@[pGȀqg;-:/t>}Co})邨.JFW (=Yb*cigtdz"?R죚ϳly#b|2yi爜F[<~8V?͸;!_%@Q})1Ef}3ٰ9=7ӎ4aj v̲ [0ìPp|Us?7x:.j="K}I#~nhvt ѣRzFz,wTlWZ̿KTq}[쳪W?%oӬZv{ONp;]{ֵe"}<?_O=jd#a7{%39Qvj+t(9Gbo~{lj75X 1_MX}׍lwN ׍ZSadxRg,%-~'l܋ϦA+|e$O/ߧ-h#Oٔk&KӀʇI G/}%iH7#ע=ap-N޳E_;_lSRR[CVׯ1 n:{7_ikdnsۘg(Uxd\_Dw`t-F߁=|w3_d D&qDqN#Gx<|<%g;p>d;ף+} ޜh_V۰*^WGK|Cu6웗ktPL5i@ d9և6Zf}5='C~$<oSΨ(c3N_Nu,8}.W=I܊} [Pe6)A-D;)v&a`~orSNR؍NE.,a J4$n49|M̧\z9Qεhm¹`@ߐ뎹bGIO0 ^_&vJ3H<{t2}%L3D;PANt{)nܑ{pƕu1E=]g˽rۮDv?H3: jp5Ǥȵʖ'q"I7.b@̪ZCOnw; V؆1ǐ"Z+_LNp#7ٯi\)6⻢|"GK%sg|;EWn#$Yɉ^RVU1Nͼ?rw<мo+6Wg^8Gm\'(!vb/p Z^y8'x>k9bm19bn9X+lи@ALp 4֐\\M(ؠ}>#N䗿,} |K {ҿx"Tv]՚6(Y3A8l1Y 1W ;| ѫ{(`IUC=gF1qxZLr[|?#e{pSHǛ!oN}Z"7Msof{ܫ?Cl ^ք;W|AT>pOdAΒ:y770+^Uo?üPAdK#k>ً%9aȟ<WP/_54Hvp!y/^Ec2k\BaְثCVu؅=D5i_Ha3WZ>qq|̃wI*!8ȫ=HÝ07'ly]pKJlQ}L~ֶėe#;|Gm\:$>ߊş#\{ج6ɵ5-{EQ_uv0ifslvauF̜^kubZgؽ6>6b1Kv\tx6bHt.' R.p*qgyje?V"fM^+iLnS͞_ {mkOy xg|Ğjv&;Hd}_Ebp۴<8z7Hh(PJQ RQ,KxM%~qLI[LR~*g<π'vILVk8CG'8O}3Q̫u,y[a3$6Kc/AZg L)—%ߟ<|#|=j=gWks0U'La?8]ko6yt"W5aMNۅŸ-;DO2Im+F.xѱмO{} ~mȝ⻲Dxqi+SMu8mrOLL•q峡y0Ic=KXt,2|\2U$I4/h/1VleօWu 1Cc׹YBsWN{!&҇sWұ^9 }{WyK%6ZFDtDPOc&nv.߱H|/U0S.{DΟHmߐk\॒ 8C:~ y[+W~g+@ |3;|ݬqԳ"NOpm-]}PbW97]&  7\{U^?8O?78j/SVfζz<>Ş?!S|a)X ւg$8i`@;2+l+~ל_.?pM୐xevH@C^X1w QE<~&yz VO 6曫%oF~~#rMeMSb,bldM=g.N!3Q Noj>}RqoTg'a'w 0TB[$Dy1dsYhlEl{OkfJ'z_ :U^F7!> !FQ}1,CA)MπPbZ2>%lWv xvΔm9|W.#t{¾f:حO;Kv\"?B|WB+<ygxvy&I\| aѠy+oCY&1oy#8O9<%p=dcƉ|@&j&ʍ|(xh[~:Ő#p*ii0_< {[ an;FSzwϲ16VEZ"Gu&cI <78p>/ۓڭ$ހGY?a}˜]1x3!9j[6y`Z ˆy5GݭsÅ׾]dOT/[FBos~4k{+X|,,W,|g{噇}!r9'N͞cq3rpoôEI)Oi)xq]Q;"YGR=nY_ݷH~hJ\;]:YPKorۊLJd5gu/ru=ɲ$Ebx<~g␨g&rm/LF1;~0ci!}m9vUCqGObW!q r-/c_&~bݳ<*+Ś:=jsm@gw;zgوo}!pT́W仢A[}5+Cfw|t^9}ͼb.ĺOk2~fiє{5$]^q"Ec"[GOnqrm29Xx^;Lȳj?:g2 W8[+fk.i}4"]J6<7!F$pRK\#4ow1<y\/CKC~cgSMriq_.|XOrk\0C=I2Ǔӷ1ԁb+`g_=ox.3nPlw|mb/hKNY}VXg3Hh>[祴ơ;8>48rx:;T}WN\xzpV;8i+أʮ_6.Rf ?oq5>~Eb,C^1tfQ,v!ͱ=]_aǤ:d1wkxb}(+xɈ_a'i5 4nCKR:j{1uj ؁[o@oo~aId'nQ%?Pz 5=ڈyԦ<6RWu.8F] r7Rb׵O{sd68jBr}/{B2-?l/lߚ pSc9g/D4L #6;÷3u$Wz`oo{8ډD^?coxZtw&#?$B*?O|N418p">O~n_Ks7tQhڮ0#7H]VGK)cfY; SCKYe>/iFlH)1>+xl3F~ 9G†_I 5]|AbNe~ 'Yy {TQ3l0Ea1Ƒ؇؇yXq|qasbM[; ΠQWyQu4aM[`!7^#b!<;D=@g7RO!1\ sy/4, Ͻpyo7,f y u7&}> }u>fuUƬ53^'C3pn*߽ʵրO֜#@5 ~;>qFĺ~L$~Xt׫>1-]5ޝKD^s}DʭS!bOI㘅 qׯzݿrxMR൏h/Ē%"{? >4G^|\k6 U;sWwn-{)pԐct&ni8=Q 2b͗!N-}=75t&XX}Y̘a_K͟wlVw3>DEa~2 C7̒[8Zry;ḨoC\Yd{l(KbG~je,v1R.$eȍ._p|cY"g&6TR2Q_\/\h^p֡OWx+`[ *=P+Ym -k{w6YxFKzv]s&/.InY!#~8}6 3ʵkUwl3QI5L4?:n= |'^WssStf|FW؛xpm$m}^{B.wu3a+ߜ+;ol'q%,C[8[c/28IngX|;sJ6y}TcqZWDVW,Kjc~Z#;ݗ/0¾qY|-Cw :;/TZ=<9dc|o`Bե-1%8ϙɘ3y~3|/?[3[)EvXtkluCYxBA'}o{njrA'~{!.^b|!Z{z;Wuk}M˱:־aqN@2fe[_b;';,57cz>ff4OPqs;yq&_!'@ C;[MW]g~q|"FwCtk%A!2;uUU1g{ЛZެ1*d6Wi?~~"÷q>|J_Yf^wh@||,֞t7)_N!ۄ"%yIt8;OB0ϳg_絧|Rƚ:7Hlu-~bbwF&|mbW,΀3暛"ڣ'MC$/.yψ~wE4̛r8Vx+vhqt'a:9s6 t 笐s:˳o3oybw_|=3aըߣs%gL"n}0 s&|5Iwz$Kl/\g%.j)ҫ_3'R}=bk6qb.]{EBo {Q=;g͹Z7qZk)7ą'i{ /29[m?mZo#ԟh~VG[s| 3Ęnfb3+v .#g-yv[q뛥nѧQ~x[-7i{,{zko`ΣB{liQ"q*̈́ sw:,Fk}0E.1 _W1D=w"wX\ W-V8dFig._5>:>̌Kb$4 >*n%mB- v&b!ĂR,EG"i P l( lm %.3s$b< Ӭ rӺ7yh+^\[@]fzW$/I\ ۠ Ŭx5qxOؓs?wZm4&"_e4̲l_j,_f# kM><τuVX>?0{=cp9WjJ+OПU\kD?cq?;G03e;Z~Iv8ݦ{ xa5>bB1a'/@L91]}Z!lTs<͡ ėNoL`VIO}P~KbVvopN@9PXxyK}?ymR*O0gɀ,2gM{ /1kSOz4g;c54@/wSi TRW,gl5P؄Gr%[O:_GIg4*@=[{3oE[״qg_y<,)5/eްYXKsj昱bך}ERI`|~6}&jyOoN95}H]D/:qFJx%ߠ/j7s1VhqKe;fu:}[)o:r=ꊾ8>!T{WqJ3N^~G̙ kJє.Ng<@!O~Ro8 {p-nq%<7L6ngx@1|˾:UarGrnV?`.P˨c7 4нߧ7;h1IgNikVg2YTg _l׼ܠj6(0).f={>{$?(z~qruWm .Q}cV̸_}"؆Ei!Xod~R1c V<4>(>Fe?64&fOGY}VGicCo52G~,1vAOkxua_`t9Gɳ}؄휕EՇܿU{o[ S2tƭ75~/ڜn״FQu㣮q6vA!+Z{S;ڑCLwDNgPo|XMѧ{)w$o~{Y{~xgB߆x & l%CL}7iId0s&S.1R~5=%"qJf:9qx̟xv'wgu?;hsaW3[W!=:0mg:7 q/El kjws~#W0^8QI7XGY2e$rkt^ǢOb>3rw8 q!{#opW}S5SzއDVoW;uܲ8npѠq[+ӊqD?m Yt'bv"S)Ȍ{K\s1g70GWckq;Þ:k;XX{Nc3iy1 }#geZC/u/\OəYTod;Žcg߯Mz`6+noߒ|䃢C^廀# :a>|#o,nqxW/fe,m2]%^G}=%Af^c>k<~&k~\mY]"Cxm/do:;1pDCvm-sf`)=ygWz}s&ϑ\Z_u+ob;K&\n~m_̕8<9g^tnnVdY'{ =1[+vz! `vjalG9Ԁ \|Akggri+oD?~N^Ʈ4Ry?pr)!yCY.8u}Tu;1Lro"n 1munvat O)~X>j]NbNٲ??u!i{|}m$`C[?ћy%)v3Ӟ¸J'CA"i6%1~_\D:0{%:#.^>|rS)6|3aϲ.> U|'r!q uC5fq1Q:ý):n~\,^\B.z\](KUK>|}bǮԹR_obkYT C}D9(wC UUߋ`uؼi>ml+v8?bX[L.aT-Zu3;kd~|׷I|pi?,+Fcjؑ~ Ğ_Eol~{w:vFp3=_~W,w!/„COяZ=]7]:d:hv6Eqo=:Ѿ~js r7\p?'u CcC^ǬYOr.xp/c^F6cN|"5D+uTFK] AWaQ U%cܦ~^3#:weC>jNWs1]s;WON~۾.t9ys峯.gE*0Pbj,.Q[_xWӛoJAw 713؉%֒vP>!nJnꙶ12voLx/5W/s^&72^|}ͣ+o}wi?yǾ؈嶅 {d&Eoʾ=7\$?`Got$=^?Z*?nc^ܗ>6ɼb+Æ5L-3w/tF1Am'3ZŤU^A!VNQ8PþN{jnj#"$_碏u(cQu9fؙs%SߗqFɷrVu3=hE=Dy7sħq1k.1ane0(嬸]euº0&\H{8v&sOP/aO6Cq7"WI<|ذ -َ)0!j39[véOZj묿pnwO9kgs<}Ufuh G뾉d}~=ѽ>ឆ"ω{F3֟΃<[hg1G]֥icn gSvsr $^z}Xiwtmzl?,LU%1.G?^.7g]\wh1YȑlƢqpor8O=Ks_ o9Z䌝k])↌c$.i88m$z7kՐx}w̗K$;cYҍ®͒jL bN;ug؋};iW胔'\ׄ~з̍|ӽ]NScCw>B.c>nIzbH5}׳GxcEiؐtYlj o5վ&dT|OqW,EVb9kӸ:ٗ1[} ʻW!w^Un[y- [ފِ&y1\8!Y8KN]hkj2b6zgƯVOw[hW?%rwebc A'Ew찟zgOZ'_l͒wLɽƧ2N,3mBѱhGp]Mjp^U%WNmKElEyuO(m*=/ʼFo]qsp6iwɷf!GLOg\؛[/klIA}^[98bS$#&G w5q|һ;o1Fq{>2>&W JpONS>oֵrӸ;GdIx>| (e'\d=98]ְ7g8 -VyoYȵ|?ꔿ;_n[{&Ë,hz*y]Krx-nY% sY#]%׽rHa%Bc1sʀC? PZtEu4wk/c!%Gp.r-^bֱS5ióxp>>1kYnc.3.6D~e=&YMQx_mo'Ǚ#+Vx}w!/s>zŁ U͞Vc5Wp֡y{/GMn)| uU}v]t7NjK{uصךZ1}kg(S5YGs5CX zy-p1KMb*SNqS&~r?*R+Y,Ym^#6ZrE4XPZO}v{pa i>,?#-/4YW֩Ov3mb6'x[Z6gqX{5CccԽU[fU|:/0Unaz}*yAnʭe9P7v|eq,K ӌ!yM wqgL1] OMCL1GUx]t.yVlS2C i~dA[l'oZ+u˰ً=vG,k0?sOWWԉ65?%X6Z8OcK È5WP"G\'c#|õT9Lb؃2I DBy\\@ }o%  6o'mz0Aظ:nfV$督6N7&)c5aUŊg,ǫ9kLYj!8 wFcr*S7QrՑ^㳖mDw2=9o9*g(S]W ?mY 6|AyTL53/kN^2B~1m^ښЇаxL;$bbfߝVv0`6t۪AztYkO{*^@vfquaǂź#6[0`53CJ;{Ns{ͿUzJƵ;sLhLuX_H:W3^:DEk/5"2Gjަ| c :w:-bNq>{\ر n٬U9fqn!Jkׇxz,1ksY, m0٬AgkgU2⊺[PG*}Uzet/m~>Zd~NYs ;dim>bCfov \\7ag8i3IF(kxU*.,w&L4-LF/هݸ5Yc 3{Y//j߇F qNnΖ`mN|)棱BɰӦd8]1us+beKZd'm\sQ rq3橚#j-p=n؅|os)~v[=BM4yޥD8+cf{',VXO>hrmv=BݦI{/V]U{#Aj[eYޝ5Q>LߥZ}j#yx49?3!2ydVnY{6>m?aѠe|vV :K:ט y dyv} X=[AgߴJiv+- EU9ζEy}vge{"_f1ea>?hװGv簛qb\e>\OIna{-E[{Yų|m+1%OҞ~gsXT/rzzBs{q@й"̆*9PY5-kXp!nYp\y:|2mn.5{auZ0b{NDv.*XŐS.̢[شnݢ'6=jYlz[鏎-e*<ᾡE[^%+1ZΑ."ʡ~}AgQQ 8Ia };gBm~a~8Ы)/{,Wegs,{e^7Usj+kn>be"Pr*gVw#vpYf sy_n{t>9c{毫;B Rk4/ i6lJsA^}hصOstLv#|hq0fOϰ ,'uԾ1uW̿ooq>N9fz]jZh}Na'r޲A\j%|O4Ԛފ]{S`B1M3a< NטRa#0'E\mvH{G%>;`l6y5|p"к.8 2VWc 8Ryj<, $?OkUaY 8b[%P3;7)g<+,p7ŒIa+/179|0%1pRwWNد3b2vGoxs- YLu"LAn ^ʯѨ}_q~s$5v2뱸ZjV#8`/߷pzB,~%a;Xcc vaoG~Or<>t KÇq(2/q"0u e:kvc…T{N󣠏-hCMB)V)`_͔šSSXMSg_֠sJ|l7|"},V|O9fi=d1.4.*f0 }"!>};vAQ ^:+Y[ z^4U{r 0:h;_c…֝ZU 5)pZnι3t 'JܴI1cOg,fg g7n9yC}0n>B 8n0iמ$+639rz IJ+fMNS&#..i|O4-zWsnrfE坱<š~{w,;lV`rogV)o E\BhoeY0C}A1 ~GwqϬqFfnb%޳h؅>]5;?=3Vknf)qZ^A3KB_O=IM`:\mCGŘ2-ipߤ% 3zVlhlOX8BG0ȳ2<;6%ÆKŤK2:Mj?Si}櫧q}۝Wƈk}N1*%:Ww4EW gYYW9gMp:Yٝ^q9}GZVo˘q/5giSX>$q>S-ϙԾ F4`X}#?vÅvB+n]{Qb1Zlu~B/q;VU've)p=j.&Xョb\s&ߪՃB8<:zg&=c6E1sj]alEA4鰚SQR;#V3~b;k^>\޿AWcz }ήɜ$; 8t)G- u k}MhzOW|ˀKLv \nl>n=VJT[Vsh}z$,hQ{Y)L`u%Z.@*Kŝ{y!t [.`av'̂iDgþbg_?M_mtsЅz}fa>žb|bjjr|g__Q>a[m֚t}JӴ%_VmH{Ni~ˬ^i{mӘR1>ioPbxsg;rp.O,ޱ6; ز9g4mn_8BѲztl7;s}Uwu^=/l_뾋lYO1 =y^YIU F/^mSY~%ϰϕ~I]|A訋g臨1_0n>;S?BΑqF-uΕS1`L7K<>vEj,+l?{tHn:Qf3:o|߸ˊt3FsZžHˌR63t=;;`aϣ[ Cu އ>:uUz;7ȱ5Wٹi#[#?.grK rS t){]nS#~v~5,Vٹh؅^Fv~ﵹ#tJUtX%сS1s2m=.ؠA'gsT]ybf6+shAA-DNZ9AޒXJNnr|rTO{b3Mo|9:S种]Ro}֯}fm'LGkq~.qrw6,ޯZJKv}vZN3H\l}.-C?cόpgod<}jz"J+\PC1$6y7prdDoIO_*$z=#?"&mqyiokHQANhC4>0WYfldtp1\<55q˭mj33ug\}]tK|r'4ʸ'dh~*? Z~vܾ ϧsZcچBP3[;Ԓ[f)w;43 p>ݏʵ)œ;,,3qg[RW 7պ#fc'&7K_;3f4p8u=k1.U+_kirx:S:Y0AY*/IC!98 ^$2{PvPCwh(6/J33*QԿ&~y̋:[#?];(v&ػgO~nL0U"kbYicߣ|bgE̻`^ېyWN[l\qr]t4۾Nduah(Z|COyr׉-5b7G~c_/,\O_诐q~s&,+b=}(6\٢ˇ^Æ) r*F@amEroYO`fJ1^Cj9!~=Ž8IA|NWjy-O'廜/x3Dʱ}l>"@CsB7G7ؕ8+1eT܏ȼ#V:V7ʮ'V)ziz2TeOc`U{Zt.HeP2B[ŏpo [ݧ-r\U?Wua Nk}YrzL):+ҡ͢wFM"N : k ^8}JK; vu/ ⢗># E'}y6'҂MIϻFlnctTOufkoQhMiA- {iGC~<GCpEz !`e.o/DMōrNoJ;ʘ _a]n d@,QyWؽ!S".Kɣ>g59? F#nN+_+Ci}Z/*c)t,Vhr}~=矏qw-V ^< 57IaͽC>,{p|g޾x͋=.m"71( 3%ǝث>o%+o*pϽuU[,<}*žl߃ͨdy){6}X/DΩӲaz UÅg" 9q*U noU[Φ,<,Dx=Ob]s۱?9v)y.Ή}iWurk|+_bt_yǜ a 92}V; =8`}TD-13J_}Abu+{j}?kif[{'6rr*}8~aY"Ys.#N+{"# xp)qy Cʃ؊KE7IQ]xKlY#ưS `Hpϗ\#7؅ ŋk*ք!o'/}ة||nۨʋ ӂfB\ΖMKA[;zHY⯟rְrEic%2DlVqrc=8eopW߽>3g|ҨY]o!8ļـ0+WcMmRܬMe$t\]l6|Co;#^ay<|kS&TyfQ rJT7"7)])yq v} i\?wFbU#Wq^}-\^ZjE^m)>C@mrBwqo-l ݮ ̷Ry|A{^)2X&rT;q|;5,i},UnxM^>W1&mbf}/j bQ>S%6@NSSl/{İ[{'ct8:X7*C1vܷtpL9XѻK~\n=C;%?J^19~?\Bq{S'Bd;+zU',Îq;#{$z(z7WQ!gD] 8;zpf/Xl&?JNVv؝llK{jZAjfGO<>Wvol6ñ1*G1Oz%>졸>gƱ$x,]܍ϤmI yʵ>.?/K'+odrՐ?zISBGqt<zBr5Yדr9/"N*1/hmȸC Ԙ6Ć?ÊGBwZguU jo_no]ћ[ ]џ|[̗˹"_+^ qذ搏?ȝjo/oMA"u9pe%^t6> ʹ~ .M<؉,]d~ru\7VWq/F2%_X8׈C̆>y< i'(Smt!9ލUQHt8O| x;8H+r;lFnk%/^S@?gsRp6g'Z5=ro#+SaF$ӕ$}ɷF3.r|2XSan>0;? |?չ_z%zynz ^Q\>W:?t]8n-B]mq좦}lh_-5y_,ϿT~5qV]yޕr߳sCqXd$1|EEKV"rX_'<]>ޚD{|%"|Lr4K*vyc>bhp%ѷ+Ex} T9Y|v5MGuqS^q) { |gDd+ 639C po'r3il<*!;'͘F8G'kN҉RXyđ&bKCSl_QfqB,<^!}Lb ث 9{֊[Wo;qP30~is%T/TYG\fW5D:۴+/ ֡W@kpO|r2U^DaV&g:ځr.ӑ+.>r)[? ~;r">N$׸kq 緕=|UDj'2۳?'5f\FW<8K[ %O:_bMɡ}\`>D1i1Kikٕ4`ig: bwW{|8xD{ 7kmq+r?d)q)v~رJn}rna% '/ 냇Zm[o-_~ mY\\-և)7}ȯ~5q)MGOڞ/>+4& IsVOܦ6Qee{=M珱g/ <~*29_tOr¶nW1#׻HBt^=!%(vuFv4-FW8XgN`/Ji?Hcy 97l)rbѩx(.g4O \<1>hNrCPBRAv8Q؃Oǎ]^r9J;bM5w̟".[{=YP [Fߍх:jٱᛴU{R888Gl2oDt\*A8()X7a Bf졺Q&v 29t6e xs|OLy>}]d}A5No7}'7ԝcb:@>}-CޱlauNLi9$b}_6 >On2c|$>\WjW4i=/u}뭿XwEnqPȭ$(|LZp-īw!eI>>Qǥ玙뾄=cnlj}ܥ:%yb]+[':{bFױ_f}Bo:kX`*;Erpa< s`M9Ǖ{uӣ;6دڙc#g݀EgK}~63?fs=VlVVav%:%1Q~"6!,{ZWn_cX+6Pq-CF3[:mJ+{a3n'=7n3_n:t z8+#7/1>+~4?<>Vg%z s=$ ;uFMm|˧ 3_j?s1W>2ļ08skC b3h/ 7:Ri%9oaX2i[P|40Nk1:](y3rˀeZnOW {3UYvX?r{E%;`##٥a\:s; !Ԉ p12bib15-:(;sq{.^LEva5gk0ȲAX9ɍcĸN2f/gf ڝ9q4EF{>aп3C$տ_nx}eyIփj6#7˺r9 !~BE[1DgA s33Wc+3v}G?Wٽ(՜!\D[;G`v5rau= .Q-8,p7>b1]6^:tſ qg-u"|~دa _jNq'8j?]]Si225<5$M8^Qo*UxVv̀k-B]OIl=lx&F:cc_!a(ރxA?+;vXN/f?#4f=i;P'C#A?yi=)GgW>^ 0R#?&U]?Sm򳨻7nyqO`u /%Ƅb(:X>tv5G}9?7>kB{r{"P< +aޱ> ;[]1{-稹?Lbypތ8.f= 'MCCm<ֈgާ~5'M+rn#}rܫ9J a;c f]v۠kY9)}/RW&(9qXtB -wǡfZQڵyq(;wލڿ]"V{o;j&rJD$ngs ]}+o̞7B ,G)5)wQ{;m.+p/~ F ibO6me^.rM]Ñpx:ӌ}ysDgLM{5gM9HS|Lk}yu!VGVǜE ObV||>`ry_#`z2nWQ^[ @Aant8玉Eⰻ?⏉?bƿl ?b.Eȡ2+? Y4 ˄y6Tq[ wDff+uɲ_x큻 U:cEfOLu|j:}gN|زoy:[lw:)OE"'e|;~3?]dq1|[]uM /V/̻{-9Gg6NcucԆoiuŮ=s&;#1z{0pOzηgnE^5\z|sC!n tlف^j9R/bxJޔ*rȳ_^gwDw1/(r)qY9*%„G.9cWelE b~ p[03Eؽ{FY"9}j4?V{iWX<=}cgx[FL}vM\NkKsZ?+EkݘM~|.ֽ<#C/|FI>t\3[3dEd3eQ[Uݝ>cȤȓ>%mڗK}s]3 @b?)U g-W}WZ=y屜wD{A~?e_#g+:y_}56o| և{j9/uyfھka5bY= W~esN?ލbo 'ca?ϧj{=N/2_SX;1# )SM<$cjM_3haա;Dr l+3O%V&1Bb x&w=:l:oj;MZdz0߲芸w2?fKT73vLY~2U9-'5;7bN*-`qb+>!EzZk ШR{TCHLp\ wt}~[}?1M̓}Kn&9:lj.|q:hMvFQ9}Y!39U1A|G|iS!sSIa#o;)? t66\Ǿ::Ջx"[gR}_<sGwobKZ<AvSЏ^W }n0lhnݼ8k {-I)vɝ$b/*WůaȣٷDwC$õIuAۃ;ֱ&w>-Lox!^0|(ݿ]|๟f3|6ȫHѝ3MMoo4x)_#(f%63Gb1ψt1|cS%c{*ž>=*, _G6I?Kߗ>} ;@\rޔyۃjt]bv=[~}??(# /sIkUy~\.fga+>R5VK#/5C}<"MsQD'k{.K|"qaq4Jݧ$R8w'\l r/bZ1j{mCɬ+aW̿;a)Wocˈ̉_G}Nea:}bvu`o;mMyșiL|g`??M'Or~gZ_rN\\"z}b XfFCbXrr Gy׍a5GԦ[ۼ ΀iBbž3FN71T8ߨkW7.P_X<]Q^$R za,+Fo0C3 >n==Ĵ7ʵld_wbH&wLێIaW_9RNξ~G5GY?c52#& Dq&hk6a֧!pkB%rMl\V;W[~luìmmn׿,+sy_&3'ŬX,:'+^G㈽B>C}?Gt/Jtft&l=P-څ64`Œ@+ bq혃A9e/z.b̆^7u19_c#&^MGLG! )tm" PgGZ,Bz|_xeU6=Y siWbB;|ѷ=%W.gʙ4#"üzȽ[mB9F_(rK)/S.yvHy5wVu7W y:܌+xF q3e> 2(rߔvu.E,2/Qw,O?t?{;.Ly,1z|3p>0S3ϝNرRs\b"aFqvpwR{׆]˺׬iyW$G|1g테 uQL^=OR޳=)/*bE-4nVޅ`w'M:b|7ZjS"W$u9kWsoתB?y/0(K#^r> r? ƏM⤜ɲ7^|G6O]z~зg:f&)gNOuΌ[f^W-r̝04wS?+:^>Ms0?|0?vXE:o<f`,q g$^yDH̊VP::0C ${iz'XrG 9rb-8)ab|>=xBt"f8'&ѻ*E-ŎN{}NG^^+ObEⰏJpcQ^k{7H\6NYĜ7^-ݝVµшqGqfPv]O; 5 ]/)ljy;9]Ixu=i)_y@t볩ЯLhlas?AYB jmkifOPO'4c @=>|=Zs㔫P0U{uog=:up'\7Y6gUmiÔ[(mQf{UM @=Mq)F#vCY׶Y 0HJ7؋a}~9_}D=xfMraGꞽ0Un)3~S)㥞ʹ>WL3@Sb܁6jP8{-B\r:_C_KwJݗxZ":,?GMɇS'WkSUXxMZ9^~8O"':'4kKLgKOGKNZ٫Iܼ}*S6/rl~D/SYWl'`ijܦ8.1y+ޫ?v/cp̅Ww`_B,;>;Jteݜ9>(/?-o~l=7oarv=~1.31nJ6g9.~;$Ӵ/zPr>! M9}W:">r^õ{.Oخ q48׫ 3.7YqWQZƬ:IB>Zy%:: ϙ(17/v'Y>a ˭3zY/e%@N="W`nsڟ%x`t,+v~wZAf?T/¹T` O` #qnkùDrzY;+pVX![Lrqi3=ʺj 2pUr?WgVgyk}V)cgb_ \lzsqU}Uկo", n Kp̴ӉFI N%>OL n_BvB7kB0g$L0fٙ鮪~Ͻ5y_OUU=yܧ'{[/wNnZgpkouC7ջ!ݎfO+xbUpK15 P+D FzgmTrK="jx${m_B fz ==nN*=zfփ]5 g.Ogq-ۉعÉ;KOC/ϼEq߃ݾ'אvZ<6S];1ڱʏmXn%͝Xv:bn#k>b>ƣ^ =XbUQ#^e_ˠ h!FX *_C} ؂fRQ~0hއ͍}뺞vdv &1iGJqץ8ع̽g٫Tǡ^;z N,먮@U7 W6hhZz=ppDO{&D0@w6d<#yװ%%u:̹>7U#Y3XMmI_i/aFtȕuVk~ONLsqWې_:y_ۚQ"FnT)ǘp]O:xuvI1w9vwdcϥe6P5tֹsCđs8#!y,ŀkMh9aӜ7<ݔ "ҙO(L:s%)vگ 3qܻvO4w|*[rZ|NyX}؊4о{Sĺ(:X}9rs)0Kh y>/cNQKއ=`H9KQOIvqO?;?G㖄}KPp=OߌivC\@9^lR4/-}yqͬvyΤvΏ>|Q~pUsaP L Ɓͪ&=˫:܃\qbn7!'%;)>e+q&Bbo֊r농#x+r@ êao`n>lȊtw+CZ \B>aJy2 Ny,7sM6d܇M<C5t6"jgb?q,}5SoC"9xx=`yȲ3~:bGzqze79x}BvLgg*յ֬ }ڍIa^;#Y/!N^p:)$rKj9*({_}a9Ր0Blv{ȅ'vѱ&w3ΘIĨIn"N]KucErzn!?_k!;)0SSe%x#9Un~cGۯf1\{wa}jQ> N نccqK\:#ݪ?YZ޷gF}5(ĭNu~G1&Tc )7a+8nW.6o1qGwGSp|/'yPN>P89p>p#EN͡-9n<aY=Y]ڐ;!kI_gt\ݨi>`F@1Ŋ}j 6>ބm[5{{)Eb\|Ag43yM8|I`KO2As^OwwS7b|HG3Ǔ938ɔ yЮ0锫?U#wmHyF+[9J pWg3teϙÎ֕Pg*}ړb2=kj)QLׯꚦ*;Y1"gu}Q89ǜJuGMܓ;Hn~]€WsscgM3:a%c})94U s@K!B"EMp]I zB]ݫA\ ܑϐ"/1/t1d٬ }AGHZUn}E\)s~jDqծȾ-3iX;| lSݻYc9:\ke =nHk΁8j5Opu Cܿ%枃&g_9V_neE5C‘z)G5:U"[N;KmAм"zcmJ7s%TJKVS=3f=E-D.~l3UQ*n35c)q6ż>k1bўjT}lz6>5˩XMsΧw5E3j-k.sFjb.uZ̍cReviKZT1r־c+d^T?@u=hBb<{G-0džW[toB=gTϏzW4ru%\9zz?9lz F7%gy# *B~Ov+,F=P֝ĜƦzVS{<%6Ip%I^guԣE'kWYCs }VX."Pue}XbQ`ȣML\q*2/Z>3zׅ3{ >#lmU!ߑ^YD qb=CQ'kK"^!'M=h1~59]Tןmk`9ᬇppD?!Lx]_(%~zsr%"-fVM7FT޳8/q<+Ӓb*~kgbcX&tzV~sCf/ {;_+f yt~Zy%0z`8 0&^ONY? zBFl.E=@r3p 1jF+j>Efxi:?{`75cwS)٨w.lCvĹ~OZ0>XYe>˲ g*XfӈФ8un2MP|PlZF?;)j *Umꩿp ԲcP^5 rgHQS񷘃2+ X"u 1GQS`auǔMur2{yU֗W(^K<&Iݜ;LKy~/aoXuL<=$JaL]\nN`[ /m:Pn(Ύy rH[0:n?ݨي1Ղ*P|og(pݻ51_so ww\NOrpBە $PsuN.Ki1m=q 1Dԧ3ȜzYv"Ws礏tNv+R=tC6Mݿ9lڱu>qrumXM*"v6ZT!C)bճ'ڻ{sDO\ޅA">*ǕCp)tx k9I>nhz;0T~Yؓ_cc&O߱fu 3{Q3T{]3_c/lf)_GP̆ۊf |,EOL>g4WtZ2.X̭ a/=ɟwbcs_H`[0amMy}qumYlTOvb=!=|Hz'?/\v֕^0fZL1痢xg ݏ<+K|NRS k3E-_ }(1 5 _{ES]GO`UXWCNIWznn"q6p)ÇԻIMyY!v/>ZF|6rB ),Q1!>1F%[2CmlDƍ֕Z[#Ws8!UΤavH)KLjYv|[쉡}_c泲Rv)l9<){svT9rA=>D=i圽bK΃B8&γ~IKbpIAlUwėacy[oʥssK؃?b~wye&8$8b)]3U}:!zcb[o!_@ۮykJU!cr|d u_ w˹E{A+C;8|_,D'{97ݝ>OuѲO`'+o'_*+_Ux#zZLLƴOD_#isf]kƨ3+T\p>lCp뛲R݆&q3ecHW}cX3{z{,P]_c6?`~=~̾:cme?o-9{rvw^yo^w1=_aGC_er~ɹ_cwU|6d/tPC> Rs=p[]`yJɕ 9a;)koGm&Mz~pw;f{,o /q=?^\`I'gy7Y~u>7w=hg\ɾkM}O3=c' gr^5woAx>0W&?$ {6f<%bP7S.sɉkA0S}@S:wЮLʹM{ngw~{Ϻ/_{<~&gϲ]ӓGh:sv;n?v8~|P>^1lr_6}~d_=>}x s읇?!0CȱEOa=je'+>ΓT]Pm_P98(􃁙g*Bnpp2uG}vm,1~<{|cfc;ϋ٫ۓfo.dt@ſEX1s31nr^7{}i 7o2}h;o~.~jYg|#[QJ :\砪O |JqQzX9[rqm`ͮc?kjϻog/w󫎷dگ0}8.f{ 3ݎ9sNj.&{znv7dhqA{3 Sݘ~v{-}}%vL?>?5ٿ>C,pAO5Snk:XN.z1280FǬ§M:ϰ,yoˇ-kM{埢}c=>i:idgzfb4~G0GcO)|Sq3.'/3n1qH*><`u8t3v^^h^ c}7b3ln5Gv>{x8ca\@v6,;9/\O8B%S`-um*m}+GU񗙍|]Mlߓyo1̞| G^#c;O=ٰ^Vj?q*!溯^~7vJݚl~l=dmv/;p;ƚ?o7P]Pu}GYXϻ|eg6Sͩ1s.}9&jgn{O3;wY|}:eӾ;n-rݢri8a:s}d̿wi{zbQ>+wd_/|gݗGgvgXv}qߝw.L&0_~/ sY]Gϴ `iS'FC=&w l'TﬦzQԂ^,3(|'ۯ?1||]VRsswb7nT~(u;nr̚<;bjeY{ {N{د/߂뷛=i>ӯ}O{o3kz|}Ľ8XBssL`Okr\պ˸l`쓍YiX=o[ӕ&/]6,man.܎}_C`Oڱ{ls7+G{!#>`jĞ5m+F䙾yٯ;1rs3_}gWq>Lg}U{ hwSm5)è=U 5/5O>{{Οak>ϐ72F>&L8έ>v=WxLnӧ_~=0.#>b}_skrLϳx 3E,S>2\a~\xwv>=*r?.zc fƓ$#$Fo'ϵM`Iu-39gu_`r=m?6,b_>wb.:_|_&V~vC׵g+rKa8f+c^LƯ5;|k3>hŋ~egv3LQ϶gNwsscjU9䀙_{6 Ę8X'յRei/wqo7L>b24f>?m`{9?jgt{o|3w>{˳}Hu}GQK?y_{k vB}Y;{@"0[WqyJ{bCfyў:v1y.9Xu5F3SowK ^S_ =nk'~ ߛ;K̏s?8 ümN y)Vpgc:?ϱ~~_Gya򝛾ʻbfY~;1?7,n]w=1]37>~}F{89oӅgnvciros?~;pSbbD9L590rr7/!PוmþL߭am؍r>WM{d߼vmas( 3~x/]gMN3Ҿ~7Y0Y])ص& M1`9w{n9bl>vܪ^Şozqs.M70oR2/t}ї[;E5^;rO#mbg8^{b{Y_f_=tcGw=6:ޞpLC6=A^o9/59w}I򜵯/2n,_=b # ֱ/h6-gvRWݑW!O/S=<[~Ⱥlp607w~8]n_cw8wW̱'Es8(69> {ϸ˵:_Y]9zZ۵nq[_3>r15#gJ(86ޒŬD= ~'mbNApg%w]r}slh4GzHk]N^5ߥ]fT+^ >i[#xd±xYUm7@lGeGwOMZ q77smh!nV7 γ{>"? 7z-S%g`M'i*#G>FpGh=Mp^[4t4ok+YO/^|q*_gOkVAr9:kmv8-Z7ߜW4fls>}vM7_=.Y';ཟ{5AHeCU=B^Q?z￟K-vM_2އ--1۹O#&Q%v{nqw^ghNnu|"nsn<^n_߿q]f:>aoxa-7D~+vg|A;f?d:yܷxquS-ꦣ#Ěf?-ts}l˜Ao)a4=mnK|by|`1og7nr}"nmlu[`ɴǿrv[}u/|~T}OkOd;bUx1tdbWqV3Ofk^sm3,arM7sdMp}:Qpg[fY7cÆ_^k@{[M}{[ϥMڷ]aT78+Nl^jkX'7l1UܣmEP6z<E=e{\u{]#mbs9:gL۾F{|7q8N9?LO]}hvGss-fi 7~ h17pQ@ s^z>ˇ0qCq\--;i lT?^0x=8(=+{K5~}#߰ٮٯ x7+˃1\w>(?h{ E=f΁Lb(wx]Xes هPZ?jm~}[i̱FG/}$npߧv?1>d[oιmw rcఖ}%󿶯_8=d|/v{>=R0d˦-쨼~n^bxךȧyo?9|?얟 vviq^hfx>^/QXPw&um`~cg_-xϵew}_/ Jp&kS2n4tKMz1G|w_}ތd+"7ԭ݋3Y~&[ݭ xrc7 zY,Ob+=rӜt;X-]΄%nK^e}Cm:˯F^-Gy}עaDVI Og=3[0 bq㼞pa;c;G7Rj*Wª..P|I7)~pd[u>OptȮ~0ˀ{^!`9,_K;9L> xى' |5c fWΙp}KqrGFǗG?o5vPx#9TYMޡ]}"C]·#Mz\O{ gYdaS_"?{jɸ'z7m^6s69HWzuc]7'M'|*0y;M_lekcp&x]~&6 \1gk!|7c]qjT^memά}ޣug [֒_,=Z}ݮ/v{s595__n_~ :ث{\9Vᷙ?Q5|>~9<Q5r ?z-ȿ落9%쇹gGܨZE|6F~[hu7?k ޯ6bnwe; 7}紐gk_o OzM[svο S_q}I_yo/uЖ~V37ʶٗ;|>rv>=q41~5ǑO)X[~̕ha%շ~*n өY56?F[ԙwjfǡvρx/zOןxW<=7_r la 5%ψ)_s<~߾~}?UbyO=3w9:_x9nX}CS4zk~5/7Yukxd[g 8?"#7 nv-& ׍eG_Ugs^KOOa5QG?k_ 83G̓sw*K6yM~ ,IUw~X4g1ǔqn{f,j~u9㒝cj{}{nW\c5k?t?^86AfD܌]kM^QZ]3=KXUqEl>k> ;5b9p÷K [gwA^f̽8g{qSK=Sg3PUCl2kg0hz:sGQՄ~.ׇ+zav"-Pγ^/q|co322^W}~Az짅w|^Dn9Eg&>λ=aG1NBgY§ y{]aamL gm=ujQ3dy?Sewܗlkݺ d\"b*Om:ngzUxe_=M^Wx\ kcLM}? 2>i.IԾ\4`\e[en'b\Y}v\QF~>ꀃG^yr/>ׁX  8/s^[aɿ_:u͎?_qޥY{^w"p9m`f-ftgo^=>BQlF8l✁e옽Ƃ1ΫqfG`O>V07~ S0sM pO^'7g8?a9v*k_4௼̻t7C?xnm!3w1B׽g-u(gܑa^c=쥜y1ֆs <'cz)18w|u^'ޭ g'q>57  cvmne1bs[3\7`?B~DN[샙4^Nό<&z53Kْ=/A|#W;'a?ͭl =SO, <=Ǜ^pяVұWY\D0?5z<ǻ[w:t >k2 |ԮsˮL} _ ֧0S?S}P|m i65wٽ$}r~mn>%~r^ iUs9V*Fv1;E![1Tƌ{̣=~b 0'gǬb&]q={\@)G,涶 ~t3;o+8\9_;b<8lq̮1M'>h1/s佯_7jNpG/ܼ8Yr-SuNL˲]a3ZN9F,FP~c{VV;3\Cעxsʇ;m#{f:gi;.n}M.!kyvp!#x3ߍa?)nao3x!s)q {GyLN\쐜>u[; 15p?,/&R9aWDΒst-^a}܁3|*~ۜr}Q+6)a"<I9_DYp:a8^WL*5 ]žΧ_]=}^YUN >qO^ Vm,7_>`,Ž#_h߁^s<):~e[(a.afw-wįiv sCyU۳)5;u{=ZWM1ܬ3Gſq\$f-<e{뱼.u?_.ko}W_$0=ۤ&=nQ`˘}?}9^{_xɵ}Z\T㚽Yd:9uNna#S=w9!Ȧ5F-|.jWG&tRς9 {|+[ ^{\#u7OEZ!xyQs#s/x{ nxݷ3{Ȧs Y(ǼWZ,k_&C!{p^ flR!zuak{g|C)I+ϵ`=Y 4>j/^v\ýچ81G=㝗hk/Eߑ6W?s^H{3V~ yLQcfL$IYug4ccjȏr[&ΠۉsSiq>aQ3KgbcG ιz|b4늯_}{[ޓ9fz޻7!m|561߹{/YQ-ā_b9;̵_v4[k&[yy}Yم_#yPFUWOx7DduEY?QpׂsՎ֎W0=﹅)p>5Q_O? #ƾpﻊkS+׽Nx|}Y9_Lw@N$<;rCW?K <x&sNlgWM-!bOBnfyׯ?<;7 lj^kq6ix}}J߷`W~}7|C|Nx.=^ޟ-s=M+T+,Paws|3 0 =V#^N7רvL1rLɅrȈj^9c f1G9ۊne\;#~7Qxm<69Y<+E~{I?c柞Y/~ޟ%ya26?l2pAKkƊɌ Ӛuy䨍zB;hd{ȃN5jsQF5' 9׼֌W%A50[q!H=?b4uŹ|C0  ,~n[}lLca`m^Uf3|Fu[:>Fy[yg740!sgz9-˧{s>3f~shƂ{8oSf8~dB@?.'7>pek,W!)jH"k@t=b=Νăp'S&KlDٻ=igo{꽘9+uL VgQ={ݞ0;I7cٛ,l{vw_E?@S39[zSi·7wZ?^}$iCUES;00kOx淇͘ V9Q75ދ]<>X6}vYc-Z Ǭ8!^/ogзFf [0\wxm;OXrܗE D[_jOCƞM\p! uL=N' ,p>vm3=tOW1b`B=Z'3lo5]AO=2>|G3Gt"kbӊja%p7=74d'Ge قe!ltSH."68~:vOw]ļomGhngA}&e{pd{>`wxdw)17f;+f}p`ڎU%3XUfw8x{{Ӯ)W1\Ҹvj=qgdv{}4j@lf^9o(f{Mb[^^Cb>d5/k9GWt}E6FcWYo7=1o13BW{I!rvԧRGJgeRK4MG `{t$]5(Şxb~{2a󕬇5˚m圂F &ts#h GBlort]Q>{6ȩRZLfdcot{řm(>qz};#p c3w+chU_a8+ٮI.>b!=IQB 757<ڣDs!Gמk!>؂an`g9ۋI-4؁TF:=(snMl fnglQ7b?;)fY!{ʺekyi]`e0;j>is:ʖ žrqzpVxxG;y{mW7ה_ahN3;}{;1[:[ļᚨe\q/(IpiȎϦ/rV}ro08r Y#ޮwi|o'6*,q ǹ?L[ [j4h<8]'b z2n[6$CњlwYc&U%uo=m4yqFec sܹWfY7jZ|wQs ȽZU\!?|A ϠBvN'jө}A°3)ZX'5hOш8sswo fYOUeùmoCE$eѬżx6>FB#=սsCMw3pNbӵt(LH)<\L 3#Q<ĝ_S`rT3 cne \9u|b}u|"ecbb _\싥۩dW"W&5\GK] aQԊON''zWBorȘdY ]D5s|F+[T3louֱ^pDvh)1vyu?J}Wz_64f>%rHZ:$"0v]{A;9/(~XΉ[;$rVUg?}_LF>/Kc|M}QC]9_fu+{™\Ў/VXP;{CGsx|T;h:W\+c-r⬧mၥ%OU>aNOp ŊU}_phCw6E(l9eaPǮ܎jXq/s-(}x^a blSЙ'>M)<+^NUYM?y xvF%><~؂YqE!}ic)S^E󗣗׻٬fboA 9/|)::Nz[X#;]Q]þ 4ov@u6{ړ/ڃ`/KSjAw,Ǎ kfY0v_8oTmscHsns֬ '&z$epxlfoJr}e{ +&޺aWmYu75=s;)'H+olq%aȿEsSS^WP7kt"ݸ].ܛEG$ !\7 {r 5Arw_sa:յQD^D2'گUȶ ? g? >3s}%|lv!t8%y zTudV |}#pĴ1qE [_cf|8ls kb'6d_i p SЁKd]KG㼐L8mIw素s)j6G3 tFw?2ױ󻇜̛opK=}՞q}:;6h:jpGEqa-o󲳧Sp 54N #H r&1[Sqø3tsٖ\L\Am]6]&[{}AUJ A[s'[MnKjBWC7V%+A_[I]f#_o+ncwMIx-9qBqf*{_X}zيzng4{U92Z׫[1 1烏fepkl損سJ>Rkϳe>.5(jNۖM ~&~gxj'L%qv v^!|&IHn9#='`[=Tǰ["#U~%b+UqD e;d;gGMrn͊7 C [VR6o0f 0О1%Kyr'd'a4g62zf۸ \jbltzqF4.\a)vl氣q'=U]XH aB.{uU;өTN6e.1i 5ݭFufBWik巷_x>d\8}q{ǝG+T3*m[ֽ;>r|9W?$=Zရ{kڐMti?y~p-{Oyĵ.z)Qܛs7",7ߏ5+pRt3oíg?b!tr7չwA3Sݗz^==ynV0jؓlS|T%\ }n`I6#3!3ú'?kNˊK;xvl!f_ޖb}(肧~! הaQqvΤ3/3NYh NQ*|El4'PlEcL*'aY 11F9m :'RrG3NNʆT 3 b&_U@2xߺlI'39굌yؒ=: od33z5m<.x2䌛Y젪p1' (rM0ͤO$ u#2CO=r_H.KUq~5?*ck<+t}&Ed4GsqPXvkdwRS]si\>Ʊ<۠uKǧćD=شlRP{vLW>ֈ̯Dz:EF\.Pl%֓28mnV\I1^s{.ƝTxlW^lNKyf2b!Js)ꜝNU=-}/o'֟u7)8d sLx7yOnz|swZ>+ q+}aǠ'/U<"@!>.x=n ϴf8Qk쑿&\MQT*̕3&0]h`ɏ OHw0\̳XMc׊I1|b%|0YZ3I&W$4\o s;չrܯzl K+by2(Ea%r=\YrL9iَj굊>mG6j>>G']1m1\OlZ~`κՊk##Vˑen!n^o͂< wV~>jWuf*>!]R>I=˕`1 @؈sj%E=vnsb!2OU> u6qnbm.8T#?j {uJu6/3ٺjx͆F&ޚ> ZL}VI`vWo*^Y_{N\Q _ѽ].>]Ӷ]QAg=߫fR`: l=70XWt8IψNڵtecNKOK_fdG3ŶRɵ||:5.cWɇ[}cBAL,)Χ:>?}e};Yss9RyM:),2܎r_5WwDHCz܃ZpDYrW| qVZg,ꟛ5y[˪F*S߃ne⑶M+xB)T/rߚC_wS]LҔG427y5 l10gXȈΥLN3h3J|ֲ8$E^\x98$8/;sq1ZoYUGXpZJ)Oq1P쪍:HN*82m uMA' mgTg>d5>cW;3"NBOG`VX!3Ze3EsS;lu#w'; W+4?Z񂲽"O'G,6[Ɋ`pTc?\\:.߫vǬ,/5t6[^lqts-S#Q3FcUG$wGy)әTuOUt ~Cv$9? V~͗S#^ WV3mȆx^s u3PȥO'hXCCnrC~W0"س}F=,Rjo=YBT)Lޔ5G͘IIu< ass5?P߈'tqR6ѧzywrAsͤf~0em@ jmos6ުb02e"_ntyo=3vp"]8C^W,XN$.Frf%M=,,&Ë)jRkX:f.jsZЛsGe=79NQ?9x<;I-f s̘>CyHd:n*3.oz9_7s]cqgSfe rQK}So]\ώt{Y\ti}a)ŧ3&^U|gf;+gtRԺWK㌾Qn̨E*fz0< ?;Lcƿ QÞ`᧮'VLu2LK3yum?oL~`b~k|ۢv=t //Ы!?ځaӊ4kGb?Y w*rXmV :3[ߦe?9oVg1ϐlWly/sX |$¬zx-QF+M܍[̧zѼ|[7ƫ ?T؞|.kN[n ݟTף_035w¿vF>Tq8l[Wq1@o6E"mhr]'?#^˪4.zz5 *=$s9;vIWFLS/\C 93Rp8RFk8G"rq>{ڊDѠ%+fоQ?K]u9x藈ya%eXЭfK + Nn|D+qY"^pP.gj6#?YbrqdHgS;ƿˮOhC2/%μIVyߍ)\یGp}=`^v.]BL}1mݑXL[ZN{VΥK./b Ýg^L o>k%UYaG?ﻐwX.aϗ )jKq0;rz#UwRfG@|x{]gc]K4*&g5]AoJ6fR>.jp]f71lJ,jI_Vx#:Φ׋aˉl‣8s6gǝ_Pe}ŋk Qox<svm:ɿ]Lu_I`g nTl@GAN+x {drT|)xRe}# rP?cX{=|Cf.Uk~4]dgi=;ӾTsx0޳jq*D&"WNDws^Z->7Y_ht,5bS4=Z*fEթK_Ӗ?q׽B6q*3&}e]Uy3 3'ؕV$d?"V܏"yx/ ERL{saZ>:U~l+2zHb-wZڭzO[Kf8փ3fc2g{n5>BXhqpfĽǍUxDŽk M{x \|f :>iܼϽ]ܣiq4?6^OS#_q||%<VC[.㌍g MQb'SL9ߞ¿ e?읣1v2,[cw^.\O9W8YQϫӨ*ŀlۣMi3dq|yP4=_|;=i}<_.t/S)|y4>ۄW]C!YZj>x:\@Q2?}/ [)כ._w;vq qʑѷ yBy^*7827.j|9.!Njpyx~xRHsu='|Lrl@5{>9fN?g of !֨jK6K,~8(4V{aWzv8|<i l]ğ]:Gכ Au?rBNkҁG BW#ҳ`Y,y#8Gэz%w|u9k|NjpOF8Ru8͙uaˡc)Ho2_|~p4}Կ?ߙe|8p z(gފ 9sS6NOݜ3AϚCg؀?9^}6.,Yk$+ 9aEXb^T8="ic~w>[88ˇC*Nj>;5ϴ2\7.˕cʞ Pҍ9=L OvsgpG"pF?uo?x@?7p| %Sh$+>UJ^,aGɀa[鞶E7bziqL{^gK^Kjbpr>TOQ#f<ƇBUk\6G1rCvZ1AR'9e@4;G-/PyՔr"ɵ%X~n 3aJy.dc8x' η-0l;]=7%+ݔhrL5ж7κC3fm/8^e̼nSHp2^x%v)B멛Ro8- ȟH O18FPR!*r<.{*sq F G؂ܿ 9>eph oPLBΚpeSF%ͫAKI/h 2;A#eOBx1Cy1M\?\rT6ƍ5:̏-X-tQ9P1.'Nۜvr _fw[?@p |!pX$ESiDȭAşm7k֮O!0K{+p;<yK:e\) 1[[ ߗS oE=;)w)X4^H߫x#9OzCƒi-q=8g@~ ^9ytӼ mXLՠ3z n9/Q7q(+u$o"< 1Ε~Y]?O#R.%B~^IDn:߉<;CM8 觉ы kE,?kSRፏo#/|~0lPܗV_{w $ vq <"2.MYYdU`4~-,N7!*o^<U1\;i{T7~cH#~&{':sMGp<?0j*y?OM>=<£ ?(ll"2`l7C毆s[qx[aOs3G[ ;wUG[JKcíP=ʙৃ㚏'kZ[{._8Vp{ӌ~ !6 i[br\F~T*XȰk'.<\Suo9*rYcxC>v=g={}R^/\mww~j}4wh—C38SlZqųr>S>b!߃8n}:Zk}*#>bW5w郎\b?A.w[LN#؁(e {C#փ`4F|bD=ŧ:?48J{l3_^B=Bb=|(#|_!5WaS-ɣ!sov y/b%c~q[!7B{y)YyjV-\C+xcg빧g]+1s_K~M?\V>$ 8?47F̟SKh$t̓*6 v1;E%z"%ou ?Gl~yʿ;$̱pzc{-UgvX6E:G߱P5' }-FC9QFݍ+HcUݐN"#0\{N9uPb"f#J^]cKR` ^u6>,,,ߏ돃Nz{~Z|y/MYW'm7>_s}Y"CO|B6Oh V)a އu垟?V׍:qD?fUb -W Xex~2}k}ױNZze8MVy\9\ v}ܝ1߂|~M|sU_axࡐի7w}o7D?s\OKu܀9mVuw[Eonݼ/j>c"W=<5=z;c9>B@|ppGYl۩裬S(<2^{6,^}q1t kty;q- ׽OxcqaɁ7oX=_c,7iϺ2ˠmi(sB=x_agn{Wb? ~Z#~ؘ1?kP WtPEY&jy|G0I) o<}r\ȸ$S(_2Y~khKx SN̾I{V{-Oy:l9mLv=ʼ|O,f$~Ƶ tp''$bL zKKÿK v{$3킋H܅1mIhIm<#bϺ6[WyO/*ڰ }祉oψ&]IcsLUjiNxϋ(aSAoZoAgc 87_JrU.{Z'8v\̈́36˿i9\E"c݊ؓKR-~/՘xVU^(:y5O2!1K%k#I䳛3WW.'ss~ָ:׃stvB^̚t}^tL%A Ab< B- xGSW?$O."IQl ߀ w0W5#^{t.l7+cOR}XZ!ܦm.c%U͞Y=nggWN'}~FCHe>iIb nߕ`6BCa׾_bbԇ$Tq]UaS>\ݥNLL.ڋ5~(o"M/!\v( <U= Uꚿq˶Y6˚I-)ÿAG$n\ފc6ټ#߫x{`'Ϟ Wa#n}Nw_KOmv+qI$! Gģ}LllvӼq؉Ƣc췵pr+Vwsi󥽷 e}Il{8V^Yc zT*sApV](.:ɭKxUh"^&.cG !1bWh#>)@A|4ŏvgK nrJ]K`ol?J=`H)e;V>4cD7xܟ$;1CLyqK dޡ9Q|r6IC܀K1]Cz/ o.uqk Ù&i|!}k{mQY?lܽ-vKي|~É<ڮDG!c{9(GܓS$ǩ@xE?OjB{}{bG {>>|*$ \w@f~C 0^SjU ZܮDakmδ^|C֗E|uQā'B9"a̋eFnjk~N>{}iK$F}#8˜ƺjb76 Mp_MO$ 5Se vstо-˭Iw'q&<>-iD,v^EeyWnsN.Ykfɏ=. |gsOwP:GtYڡ^ΡP.ݞj4y>pX_5\\'Zv'^ܼԺḴͿdcͲ)}R#1׋,ۨ7Q"_H[yOۍo$}ǽ{->}yZ;?`8[pQ[r_g^3WX۴돺/GB{MDZ )gYgZߩu_mE b'z= I:z~~g%EqG2D|^ƿ1CF$C[ޔHMqK dLXaJ~}*0f9Ye|߻o畔5fcC(oD_NXc+jћ+XWrKg)&o3'eYɄ-K:|ą r=ΰ+@Ɨ}4d~:{ʶ11&oꁜMg)Ml?~&9)V5Z֋-|=F G[,Ojy=ˮl^h&6q7fb#.d+$y+>8t_}Mgw 9/Ře ?2yƞ> NEVEZVѰSu.rtP-rKT? +33t}8O:sX|:$sJlWSC{$b^wUE*{((b[A~5s@|T|s)ZI4:NN!WbSz_'>ۈLYzsL ΅s.MYۓ&ߣOu;9h+}Mf% ~q,iGQCj'1} }5bW3:ū]ɀ7*8I~a\\ůdqgz~\U9">ϼ6+U=0΋Ys3pdI>w?xmf-,9/|6}Kf9 3^-AjyXC{3m>h,F{8̵a]mĺfXs+zwYCRSO-; [+_mŔsm5H/6-lK̻H=)rm(|m8J4Y:# uCZ9dޯuTR[7.:h=>2DS/Rd# ^~Xcg"7J leO8ffk/ﮅ=w?g De{yޠL{G*֔VaGCy}b-ؼArCޏܫxҿlN}5~|n8}k\Oxq5>JnSrȚ@3t6h9wVlv }X.J˦CН.^g UQK#jH]IG#q#u, u&~ Yƞ>0 _)'x8'M|׍}飬Gg'.0}$2;Bj+-xdkLH̯)6bb7Y>ONl_Fs9n#ǛM>Gr3a%lM:;͚/E9 9oK jODz,8 &[X+x>n~綎k6ԹnP5sj8-ڋ#Oy-ڇ%>W'ݤup3|*SΗK{a&j *9 ה*)1tGK،`Frxԑm {?9r{j)C|`*y!96 k#c{, Pf e'rOJ 89ges͛n/~7B9Gy!8dnu.|\_iDc!R|?i+?qWE 37؎D"iH=f=v񃝹u$"_9 ]w"SE_4eb}J3ZA{t%nZ +׭~妽+&]Ge_ѽ/3}:C]ⷆNa9;ORxXg>'⃵Zc9إJ!~/y]uiwB8]iυazՠu'Bj4׶hz蟟*t %+=c v"1Q#ScWz=IȾz~6Y& ~C;_Ř\#bD&1/Og//̵Ҽ 6vG BGR">fLOUe_׭|7sdgee'ci?Bgđ-XKNHss{.>񛉿Y 8gdvH}Bn |q܂]*%'70.݉lc'kf^nK#ѾWO\yG:sNk*-߰-5X6稘".y4mfs(r޽ֻMRF͗X_'siJz/ŷPy/JiwRam2KfI{O:k8-K'!~Jnx]FWg3Oo%:1Q{~Eþ*scI!vA94|~ :^u1߀\8;O_Je͗h; Y 'zE3Gr>M"`}6A? 3Kaͬą5y1j=d]GELSE؎6<{;Jg6x Wى(~׽N'D0UT9-#]{鬱SܷBFgk=k%؂w ՞m$8]%ڑaO6g>#m>͐YϳrHġaAH$No'5|=iYӷ@ӬDW<"乀5q6àwaz~{s=^#r򹳽I֣`o~2X Hۢι2*E݃5&j'؄:{qa껮s`;Jm@]{d6u0X |W@O_;.9}|qfb/'e^Bj{*AֈՙN}rPelxuq}Z'=Ml! yxc';F|Nו8w[4kŎOt'ػCRauWL{wuĵ.{T{'SMi?Eэs`s fG3(x}ny|lX8X XbAyuI/k[Gt^Zf?쇍I'5^w+|Frkn琫lm*k~S01_P9/t]V1,O9ȵR)bk\žIY1[zzt|,+v>q:;/3gϘ=J]C;sBIDַԺW99i{·]>Dz_k}Kvp罔s#>]ms:cuTI)g5يK|_֯7C;a38_Z]%zeʑb/ {/=$&y0&C}~e?KxO}}Gk׳}=s*6wKm\,i9AeF?rqkL[n\gZv"܃r/\4ia8<- ~4y vLr-ۈ[d1𻉛g9"N^BpAVZk\~,0q7|"xzf9R}V߱=+x;6ݤs+A91fBO6(S5̲5]tBe5J ^|"OopW'JiHKFdӗm)fΞcf/qwq>r \*;6=-)f'DyZ"|չ_c-st\f rN0lC3\ߟ3`(y77/ %~46f~/Py+{%~ڃ}N,qrK63cE)r(q9fto[cˋV ri~s(6u(8ߡ\4鍔ge5MZr8h(>X@m-Y<VF,)q_F!קu9_Hܗi'4Fر8[1±eޟ%v1cߵ#5OeU0_Ą%nU+E 9uߡFP?|f;{q>μ>jcs坞:f>Mc[mYڧ3fdb6Tq\P^P~L#rNЪ mʖmsȵe55f.cQ+VrkXAK^dqUt1R>Nf>Nkd9o(lR9*GUmxbdY?Iz>js'VѦ.7,6gSysüwXشx{ez8sr(.Tqc3}{ٻ?h.isZ&;Wרʡ*gĉv՗:,:Cw_{7hyrpZ کZN($'7Q5Ya&EnbjB➟?%g e\?k쳛)>1ƴK+TjnUN7N檕 5c w#{ɐSq>:%b^',Vr<4=WޢfJ~<94Gx߼'VL`D/y*2b~d(y'U s{7jcEiTh|fNa3:+ȯ6|j*m}r>o| }vO.,)zaV-wKq#(q&gArۓK.1[Kk!8艢bm ` 7ܯr?9dVcgtJIߎz#[c wuϜ&^IRz鷒5Qax$hoD6iV׹Qwww˴GclG505J}n:/bP˺ U?u,;zƽn0ƦzghV=/8j3][oVg"V1agjg{9Sep{;*|gl/gΰ] ZΣGL5KnڎLƣLGc:391{n:/qlgմ6a֌ٮiݜTֶMi4;F\N3ȘcpZ8mY~w{-&Rt>rnCl}X2o3cZţٍPOQB==f3v/+.E,?W̱vftzn|EƘKsX?rl ÎK]u>dUlNFnvG3dضڟ ^#6~m[ ,)#UMOm~ ku"Gega&xij!+ttr>rMktFP^1 '0ܚn'f~b9γn1|Okrt8ЍK69Ҿ(^XR1QݚҘQ%?Miߏgi2NϪ[h *jEܲފM#db"x.o7<]^s/9%WLkН3v.|:V>ּW 1: [ʝT~3ƚikz 2TejWT =h^ԴCc`kD甜2;k_|МbLװ37LN&1[)i̙1d;̞Tg{C^60z3[fPbX /7mDaC+]k|W+fb3=Î-D5(>JP.tN16eg61]pda,53[X]nշ}̱w#rRP_U}{ o ߬uÝ]9{kttl/ X{g>q4 *qda{?Hlػ(qɾ6uFy3|.|l{w3 :wP󷎓r빹V,WS1z]L[2ئf|2xOn\3h{ove]0]if ?[ok=5n A3 ̳fdul='XɊρM#QEx׃0s:ǬFolLq?l5xF|\no,H9_{kKAk|bFLi4a9y;ǿ {3` oxeGZ[C-!/Dry!w`$c7_Xf/9yy`OabKTϛ0Yt|rVg)SM^uXr =ߢ=U_[{QNJjf8GllqC^W~J3&8*RV|۶Yվ^Iw_̽k|c 5{0meqe D>a֣2@=Gdž=~s e\Qqwņչu^ uT~+pf@rw_wpu}߬4-k/k9{:)3P|U̎l2Ov8BPa5 2>O]tоgQasf:N6ku_ 8΅jaY9bf ͆ӊs֜]f _u\uJsF5yjNhz[7bMouq\\طy]8/VJOU{~1xl|^jţc:>joX'1gP{{vﭩD:Hv;hfl/9{hb 3mZEFy>p?Jc˖lBd>LY(Uz5]&x~{T͙A:,&bEmRXr55EOC-yw+>jOgeZ\1Z{ =s758m:R?=D1^)eHbnz;Z&csYÎkT9Qi?QL:_IMהS0fq{'1u[~涸l W텭 ۱s [*뱘Bk}əC3N{4m4bw^Ǵdخ"U>*9W̆Uc#Ŕ~⩠SM~)gl~:}Z);8djSxZ|ERsq:kvxb"[woP{q/Cf1c}os *}\m̗^kPNL^ckH"r=aQn6)5^#a͢So稣Y0aZ7١2ɸ%/;\}sL]Kǖ)F8bP{"a4{2SbXqYFp~geuvS>rsu[LvD΄2S~Vq5뵭_Ο\V(b2A5мeƄʋ]ྗz/ZފRj#rZ ^c3A"|EX9K󑍠y襢k7gErhCl52_fCփZ7~׷E 7zuӻ-bZ{ݡ=Y uIXeck [fN5(ʽ9n1T(s^W9tX 5kZ7o{Vu̧&ޘ/1cx3{*vm5t*wo~_߼yEi@5f=hGuufQԵ9t%[ZT-[ n?8gͅ~탫u{-4ߗkȽ rMj֑,:lWtyQZ3[M^ý;>QCSFBwwWo,(z|~%XFL6 }V=[^yMMkө=/٬{4W>epۆT CPmڔaE^:RPg}riT^+|' [<'iuK{=^9^`4xH-5->jx^[b c\jڻzO<r6 :=V3`{9Ho^:pZs+6b!8W`{ZUGB9o,qc3" ou+o{r 8V }:w*Qޙ:OMˁ8sM2`_amnhj}zH|eҷ>7<. &2Gk|bֺs og:1OV-Kk~fP}'hX>dbm7,f}4lv|=dVSQ102LjFg̙ :zZ~39NB1}N~m? cj_U9ǮiouG¯|;.p]}Z"2ccS 3cXpf3x{Rn>bXΘk=ttբPgyMy͘ |^ܭrN롬9W6@Tkj0_Uo1Wy/ׄ-NZ˸#PUfghs~z9%gK2MCfhkVw}&?Pb;: x/Sr჆NK|)ཻ=U,gu*9_V~d՟^ש=EӶ'/R&M~`=֪:W3<`C}m3>ھ~Ci8J|g=8XKۑ[΁T!3:/I|4V(~4~ tP{/Y\ Ԍr̪\:Hc4x`MovG)~)8QzpL+T=/j>JnѼurpy 9i?.zQ0vsy-~,tf-ׄ;7Jbs"VP>2ӱrN|+d v\yJ*V?[l߯V|gl:mĪjlK/o}ώ6f mgT?O~v?2{^[%^Ѳڇ+}N!˳][*9q~{AG5!@9s-~u󳖛?5/1U\<^lwۆj$H螢2?K~89F=8AcAc9g7(gh<: t;dX*C1o{&ekDmuU1-q4Κ7bjufhX\rZrqaq!.baWg3s>SlFcƉP)GK? AsSǻb {?ޠ¥H"πMGO5l3`qô3fߦi3#'ڧ=qֹ.f쉶Լk"' 0nCS,#ah`^oS+蘞Ggo\HGΟY Aʇҭ7S/;p 'oIkviuk=ZX>/cY4tsyH(x}lU u׸k.06[e>u.TS>8 rz~irs»GxL9+U,o8Jxs!+o%r}Փә-ۇ~^8 b >?m1QNLg[^vZ?gv"BoόټslZ. >v d+qj$K/ɕQk{ΤJN7%2pZ$'RyA#l6s >ïZ╠ujy%64Һ/l}ຮė}d(5/uk6[I1s5P1ߚ3[xv~",zt;<CwS19 /`A6m'\ x_.?6גgtLxZݲKљ']u{t{\Pu]>, ͜ϊ^OξɥR:bqFPۯ36{ל` oaSz(z\'CY5j2<ڵM{˹CaXONp𜋽ӬcMp4?4SAmIp-yr? J{Gf?`SüЪBllӰ&fx}h?b=Mc栎Zg<]p{|F8뿦롬7[ؤ^Κ IƼE6_!g_Ϸ=2^yᵻ!_ Y7ig{]{ڋuԢa'(>hB?k*Lf9[uSΙ wtA{MNCM xn;9eܗ?o |o2@[nj3*9u[C} AyΏXѴ#WY)b"/Ga>rhM3B9~:xi>(.nʻ(ӝκND·x%dz+ݹ۶("(!x\6z xx};޿}%9J8)mgS>Ni|퍙g3V+XmN-u(ƿc8HYsx6!};`5N+ۋN߃(Dsq9V_ ךJkג"n~ ݋Ryx6Ҝ3%!ӌs25Ym<b6@9Ih}#E|LVĆwL$`_;` Ϛ\twEޯ\yW7Wq|݃ǯC]<v?|g׭Et4ߊ}C!{`ʽ> "^x|dz6d; "Kdkfyg3c mƔKcYV^bAy/VPM ޲=7xz SlYΰ#>sy$"\x_ /.7. WL?0}BvM=3d'|G-)KK. G~{5o tvz}x;"K%x1txJ8·r2\'G7\+bszYϣqi?Xq }Z;u5ce/c̯X ^sHd_#Xa||m?Mן'zrvκZ1NtTcz0| 'ձ^ÿo|ǽ¦_4i4n6(SKGB/H6a%gh^mqĒդZm뗨"8CYdz#kpsoCls%s ro7/>敉p)~r7*u&;6D1ifn\y yoDCl`3!<{ ɭZޏ XPm矶1,Ug֩$1慶,~Y6 H5_XP]4f;<cdL܅O5Lؼ-t)dN~ʼnbAi󯫉ӗQ[oϬXC>zI)Q'4o d9؊>{5z<>}"d˃gZ!گŽ9{}EMwOS9 eL>{d=cL/L*z+E܁F\u(v5mb5\hmtF_}I/e j Y߈or&7ςO?%np#}%8Lg:勽TqI0fMLLpMQÙüa]zs'̝//r.pmG ' d n<7Bu!NqPdٗT/j|q6u+ dۏIW"no~gm0\ak9xAdcs Xml2h{^KMe#wε*.gCoẰ^#"u$nFb>y߈^.'>A/viy>L;_퇥UaUO;$S :6w`u^|ݴdksSo'‰%l s_{ ]{5[ssWr6~ 羀n|>?9mu[ĎCo_tNvSK#k?1]{rd#6>s5l`#9|>-e\+>S'椳>Xk&Y^OkogE;a=e}e Υ ϭX_g׺ ǵ8~5.nÉGX׶؁NE8>y}p'-O!9)r_k[b{ƞT?#Mbckve5R[.z"#?fGC| Ec}乌q u9˟n] OxxT~'ISp2lĀK~g%lޯs'xY*WN=rnL2Hb >GwKFa5Fe)o3gxäهgl"gDy<!p*oN}{7_+!,<>h\?G3vU+𽿅#8s{ ;M/8;ˈc/I 7G295u k{*sLm 2v/8~?gՕܚ!yk%cAY:9{$!v\zپ~3O&1cۡDέW8 c<7;D{D|eOikDOq.Px UGF4C޵q/m(?}EVR! g˭q4߻j|Z73,hg kcmجD_u(1rt(c4= nw x@q_ODegX#>|*F S߅-txw'm_x(\5iÅ+y(ULBfVi? je5y gNj %?b(כ똥VfsTC ]wMcmN ?O>_EуpL'{]ո%z7W +ys=?ng?q ϵg{OzyOOb?, >1hbn ͉&`=gX&^?Z}ɆP=]~nӞ[ +KL!j_pYSt%~a +bxˆ'>8n=x\~CrOMΡO3c!܋~bR:x՞9J|!c<p~|DVdsy-,XzokI&zv4j9!pFtG]hܺw & ˡ㳠cW}6vAoG#6&bWտ雈Iv8{8Aj2̊.D>Wxd E_28ҡN:Ω[ >f^}KVf1f!oy:)"vfU~|=]_}a*vSoIL!u%9(NB⻉ In:m? sq28y?bc.Md'FڿrVᵎ~^*ifH&bb 9UOd8ɿu=V`ӡ䆜eq(4nj%wgW8:×XxOs|3**GqH:UoׯrO{jm hk±a6!|7~O&^JqS*&W1#trHߝC9e\=g4cPCɺ?P:̇3PZ݅y㶘2Gp/ĵ<43bXc|v3ϐy}e'?߬:,K.J q;Ts_X/O;ĒPue v#:g8xmJ>7"DoJm~3e3.x-} L`7SԹVu u%?׼_.f?"?=y^z/S۬!Z㳟|?A'Sz kJu{{Z=J2eͦ? wn+$wxHt|l{YEǻvfa!~#ݒ;k<Ka꜄ oȞ&&.ov%Zsw1>R-%Ə}x0b!QT 9KIxqJ 7uxߣTo?wXN <ձa_Ѡ ~ e^p9|%u:GLRK{A;% ~0d\\sfWa5/~W?s~'Akgߙh;羂r_xN4;.`GI+Cr#F5S*D|*@?6=-tc%$m΂~~_c^H{72"5rوg] 5 }Ęj,GE` ZwrDcu2 eo/s5xrC_ˉm&9(w'<_ɽA_'>MbL礽g٫Ѷ<̄5la昝?9n eSs[򗔸hopDtZ!ϳ"-p zXDɺ??ɘ70>bbK-~E/Fַ19RN|}^H!dJ=Kxv3.:<1h]{V ~z<-+6dPL\X7u|.qKFjz=LoCos?~|k3Uyv{12[,tD߷>t9sqW}3YCvl kO(e~N>HKnzKSpXN|.sM{{fsc]|7166ױ3#; 3Yo')ϺWMqBmC:S^i=HEx+LUj/EoabqT#5a9m5ry_{(En}]/<@lj=\7VtXl}>O?I{ON?։y\=ub$EK CS4>guok* ^ZPL_y9bbY0[a~9mjUem*pX~Ɋ3K\2cj 2Ϝ>{Y0qlIqzo5!-\cmkZ^LzofLrb_whßZ^aٔm(>TT_$OFYAZp qwS̟е~uI3s>̘vvzFqՖ6c_sFc.p->sr@]P8=b"r-mkxl|!=] |zg[K^k*{gzZzdv uk=wgbg)=5O_3|4^[(i&kʫ~/h-agmۗo殹Kj%>}0tځ 'MApnMtramߝl:кr.e+ s (G7[WDQZ/u]xC7ڻr9L{طUk}zR٬ܟ4[?2- c9ao :ݵ೬_ZC)ݟ jZcNv=2,u9NH.q# {1 ?j+w,7g|P.q8?.ۙlٖU#N[|.m ͷq]31}Eʍfɢ7eoUСfŐV'!?lt>.snSgo ǎ}W y*suYO{Rk%H~z>YrFf;L$ɆՍr e>FMLnoY12_ۣ}/7#u|4f3}UQ%~۲O{G<(@[͠zg4'yg4yb|R)ήk\ԭx[[hC>;OjwWl*v_̾/%mڵlݓA[igb%ݳ'G⓯CK v|={ >{{˵ -BM Ifݞ\ hjys BG)vUq3#~( ?߫yl1eg[ >)X|֚'kNY ,VLNkwH5g $$<\#j@.7ַ8!X>"m_jϦB(*SP K^?+#Y`h7`*}NpMDZum}Ĕ(?Zπƫ"kYC~}Н8k7T{ Tņߐ{$Vqs/*ϾHhhbߧ:[Ym3[o{UK arʇzԣnF(B8k,fCj}9Z0wP};!qyFV)A.MmzVՈ~z*>ȺVcY]ՖKŇ~Z5Yf;Nf'7M_%{< >a]NYT~_(nX5]\b 8i]_w\<4W"dr )x/NM*݇bJj:CZϠ3ZA9Zmuΰ3Y&T.Yy}^rY9bWA_Y ˽+OzOݕBj79[q7m[ 4XS/h5֐|s9Xgmsv\ufԳ MXwkbɺ|}| {w[--&{Ҽ5)ͳꠥq^ ~Pc !6UӠaUAԆk-Y>^^Gs\(xhy 'AK5wmFYYZ6ų{/jCyz 1'$uC{rZ" s_x*9B~c~ڿ|u+DsIdg)^x5몦Zϗ5RN Pd>^$fϜbY{C#&Yv/Ja%rR>tVN4 !ޢ1<6ZkR*7_2EV\[=?\RY~ij;oPXy@lbU5,i#ۢs6dSe1ߩof;,\A='"ndH9vU[_ x.y kLuF^}c]u[ˊA*bWFA+n~FeZyNbѾ_3aCt+6L C5jl>@ݑkVK*1 rT]5ƀUYǞ|h54h,[Wc 1>qyV&= ZߣyTr*IƿCsl661S<׳ W|rևKV Nz|ju)>Ar]6GMrsc~ ˇدpµosZy{%KI'g.\`zq7䦹=ޢ [^Vh~Åkhb4XDf}=gqϕ9VW1.1tvc:}J}z49 @wZSYw\RKgלJ.;FKԓ_>I}r[ղ,T]/\6ûf3e:f`znvy'z1ڞ`>u]jEeIræ b3]<&> _FW{j-E"cϥ0GU1gZ%`x17 g8m;^>cgp[ze4Ck1쪭;,jKeZ87bO!9vkMMx}mk|Β| 1u]+cۂ~Ss?0 n8 (׉[a*BWx78Ջν6C\5e^|!Lə ݉N3=p01WI= iC2cβB>|ZoBCC5V6٠}z.׎;R`;s=2Kt!~؈s2{x|ڏ3s2=uImq?J)r0hbo~><ܫE{ϙ&,θB?c{7I1!b "ҟ#筇4Wn55Zr`R\Cz@3txtbpfˉ6'}De=l]O h?ּkү?n?0|j~+ۤO'ڶ>;4囍zu18`|@Nإ@?/̟)̊lqJmO2gHY[8og^rp9c{5=fp~OwB9o>xu ̜Žĥ|&7|sqPg%| a]˜kk ^HKޓi*nu 5Fc=mg*7u/?CMz-n'|g^Ϝ鼸]k,kSٯxfg j91S7vh|:ebk6jGwLkG'|q.f9Occ+/QR5։:vF秗Ʊk”%YJ%zɞ0`;q|WYzf3M*uf }IIF|:Mދv9cpzkx=@J@ƞvb9+9uIvH}-g-J9-vNZpmYJg*:D|kV/1'k}/`5fj.0U?1}vGq}1#~FgM՘on{~Nzl@>|7p#b dĵB =~r^CUOn59WLb58׼1|qy[ˆŷ7u_^2\g6U~\Vgrb-1@>{gY^*V+l}+lmr7QԇI>6VH>cKkx8z\>qݐ@ [!q{Zk2ⱘq`Q?g܆V\p*>fN6&kdsڎ/:>Řj9kN3Vm6%^GvhANεψĮ:6:q_'&.p5 s)`}]$wdgzMKy5jKrwPg3xhyLG _9dbl>'u=B9_g=^RqܧkĮ& ?Gt뜵0&Xt5x-ٹ_WJN1G֌'a:JV|jNپP`ZKVS<uNCu֚M[H4rҼHˁ U&3K聭*q qkb: o_HZ*s*U#5=4X /9cğ`m,gWsvyEo׽7`0a.Ϣ;p76%VXn _ ԇs'KC> q2c%K初6cBLXinE}@?LƸ&kqzv?/D[`, ,ڄwb]Cr|-'~_aS)t\5=$XW;녾KyYO0ZRZn- >١=\e{ݟՐ Cʓ/r/ޠ{y#m} 1p>gZ{<tQS UrB6\~ȂJzKď1Jd734"kĜ8VyBoyWͳVr@#Vg\P<5 7-~o-mпylsD^@+i|T-ǖsnI-=5-;|{O5uf9 b|<Y湵}^0ઝp?am6߁~Foko}=@q3P4GS Y⟹Ն>/v>S8Ac3/u?~km>Mn*Fnh׵Ë u+ߎcyqw59[ϋ4jG_B.%0P]ory{ sj!/=ՠO_5CEt9=˫'$s {tb=q`Mm8ˌy[;#66nR9"c.?<~zĖvN 6gs{ ݉͐j>cf|#Pa] Gq@qŀEsbUDZe|Ч^Xs^|5hJ`9c}+k~Xhm\b fַC~^oG\6B|ܞ?x\)j0^a?OyڄY#~Z\b }|H]ˈtP;瞟Mtb1v]+,z|r {n:c=-2[ g1kH*y]XŎנ<,piL-sd=Sq 嬜_v3fwyi9ϘE~3 _".\g~`/>A:48d5?avH}gf8tcn #.ږ#rkkK~5>5ו%-Y'(R4k{i9xoҧFV}}ކDO j5gi57[]3BRۀ,NF عz}]z?h; Rو"4f?pfqj15^PY3X_/G3n}WD9k0bL6#6}pF53U?3=-)ںYCsy)81Zll?'ΰm:9:5|=޷u[|>.ŚrL􌞊npzHk!gs̺ozba>2|Ʀcub]}Zf.7ukAWՅ?.qMlZW3 /B> }ֺ?Kw Gփ駵B@xb+ɂ{J<1Vp,9n+xixlVS]X1f lFpZmv6x?+ v;&1 D}e> U}·`fH„==_ԇ>cES]àʽY7L=o{_瞛MSSLlÐ?[*yl9y޲"֡O0O;4;`7g' WnnKA30'_ձ!ޔs{#7[jN1N 8fm/8.0_3!wyUϘ,Lܘ!:yYg7Xf|Ўs3ԓ/q݈11=N,@->k{X8$oB@c#[Ĉn'F՝q81O͉Ig3O' #K|Cz~Axѓ{~ha]Rsb=4OT>÷f>ayNJ׏r.rI;}'<kUOCF:'f/mbq>J!gthN|u83=u %=t==zH7e~HV B ^I0]全?1 ʨMYf60FpAv3ވƵߐ14sEL)?u>oh&W]=\MpQH$ΰF΢6A9iҗs^vfĘ*!Ï#Ecp.|l\Tnf׏Z$0qɉKϭ^H{E5֐=7^<: _Bn.ZN]1/ֱ!=n"}N? qĐ6?_g ITZzj`4{- 9B8G%ni~,ǩYK̃wy_,j6C'0f,E#F0c1tzGv?.y[\ΙL=W81[G#ػ2EZWxw=-E_\]`L{mھufkaup!_ߘ^,㡊mlM'<0Gog:svp8Nj7KL;v@|'~Ho6&ν>ϋ>ױamSxn^#9ǥ}&.,bEϞeXbY-9[ҼVsY#x&{񻱶koDÈ$=+c?ÈC-a/Qyv@>ǹQ[.6BS5&p? 0uޅlb^y:1j[MkkN<[C9 {̵R\ \m>x~;~v{>kwQyGo?,d=_/ ,L*5LQ|n"^>É ͧf_܎ "l 6 fn^p>Y:Se]'՟}r苜7Pu5lЯH0+BזY3`::;x @lxN'uxOFrzBNLQcH,gV szS_ ?aDsI^)vg~o?}azFc!?s1˴ϳ?tv{ s+ߤ29 p[gOgp^ODRлYcka;t/s1A<>bȫط{kjp^g.tc'?k-[y!scɠ7kyw?Q]Bh orMC5xm˙l!fLki)x}L>p ׷\6j ;[{'v؏}_o#>3\F7޳szNƟ5d|]Q6{/xmh_ų㏱tn/4Pa?֬3ˉ׈ct9yr9!gm/bz5g,h:`8}dmZi0'{<16tm18l^y<5/67=wr%*sj [XqJ=bC͸-m ".wr>!7LP0;?q,Lj8=OϿ9׮u{9sdG8OZsT2,1l~y z&V 3 pQSmY%u@l=Ilg㙈.c`0ROF Q ϊF\8_5 ku\0[u; Qpr }ɸZ?Ϟa݆J1v >gz਎X~Uqa3R^|K1Dx!qu۫3/Џhp!s?'ƕZ;!'|,| 8:s]iqez_a=IЬ^Xkmpx݃KCFpsPt,v~d#?v58Zgucx̞ՊV_wO:ZޜZ>&l{JU%c>rTF#d0tY wڲy߫gD8f+a&c^S[ I3u%8Ɵ~E08d?NK]St'b1,^yt|_*?%?:hh3v;1Cm+wn˃_؈bϼBpYn 79_:'!0-xw.w@ݶ2E.u?x=6BLrgj<.Tc-c^b I&J7c 6<6& %Q^ְ;P2MbW=}{Sb*O ?3 Կ:e:[g˾do*tβ3wY_+OԙZ }f;0B0zP|lƘ;1w,~:f-VYV7awbأ cw9Iq<nSSbŶД8_Ͳ9:3^&__+b[!<6g@e+?rUzWb㎫c78S:|nQc6Kv53 ۾9 y\y_ՐH&14Ѽ6K:?ȭf/m1_^}35Ė:@~E"ks<"lEFe)`Z^9s_Gm8$g|VR1i=TU?٘txgO1섔Br0Y]cl|)0Ye\l^Y=fe}bGӿ;c>z\>R/_ ק5u.ΒV1eI}M. yc:Joʰq͜2b #Fr9'?O>8`@ȭQ[ $MnH\bm8kIk^ [ۜ\q.Ϊ۲|q׈4~x<^%6^sEe%GTy0 ay.:g} gk6S|s;!\kGΗp}{g4Ɯ.u:#Dm-00LO~:I8/66<."kg$~fO{bQId+6ny+urqL 58]K vn(6vԶU|b:v<$?O3-?)}>icb=;3#r-_ ir1sW+6;[c=0y6c(Ίmb/Ȳ~/'͚<#a7G6e#rWo/3٣zBgՇm1φT֐z:j c/ą31~}d-9';y;]/ӟs/ۼ^Os,!{\t~淈~S~u%OKlͼ{Ay vSC7eg>dT7}5{c&㜵JQv)֔xN/rq:pcsuLӲbz,vF@'N켫}q{bKb?{|ibG/M| ;>|}퉖lditB5!n'tUȧz\3Q\tYDzsa\k)|5s^:\O_ͤ >.{sZto߷ YA֬ދCI?y,񱜥+4ߟk[1zLm] m^ wo^Zrj3<ͭs =Ik׃'$MN:'|_5mq3ιgzb[]-~0f=/誯yGdrn%k_O?*?F^:߳}{/α7RyjUZa˱1='%fG┌̾-A iHe!/2?¹i͚Ygc\}>g=Bq,{C\X]%.N~@l.k\ 7ȳȽG7uv\fk8gsO s;['=7ØtZtMY|3}!y= [ GwR\7π,|,{\gf3m-}Yf*ͯ[=]m;<\~\{%{ƧŮzWGl [)|;~rǩ{wEj Ь\/3'L:k,?n߇9 Wӹ&ImcraI9y{}i~}¨=5|'5?\Y^lkr v ۾Y>+9߹\~/+4ƺS~ٓ_YǺK^룲>Ο$߿5bgH젟k=A|y?^vn4P~3>~&S%^ͼg9n3aoɩF>YKH1Ŗ]oeYc{<;=/6~Tlmk&zaGnRsW{WdHaGd#*vN\|l1Y6K_X1}<+.tj为Iq ^׸h B?hsA 4d7ש O)gy!vC[ҟ> Oc k~-?Wi~VC\/v g×nӗg 6SF =Pٌ"`#<_4g!tH\scm֝?z?g֛~[zϑk$_5ze=by|Pl3?#ـ[>]sZW,C%ei'k&_}{ank1_0k׈uU?9|x};W :\u3ao!E|ss)VvRRú?kV1M~/=snkf\lײ_/55v%Y?lPYPмQ}ξѸ?懠0W5g]N腐~ӖC|.q 4 kt?t>glNy5f\sW/kvþl/0WyҊ=(KcX9'y6i>M'ij-q6]q\ԸsNF^ {8WU[6jyf:fkya'Y8+8jLgɫ|?v|ei|P[56)VcElycobc97G⓫гbW]%V>(#f^ '3{LϜma7|ksjaBC\c:T?Zq]]uoP,)t#RTYB7-ߨgPgYS/n"v{jS>٬?mL;?5zvķ|RK^/z|}[z7v޿:pp/8nX9A! ߹㐴oZ ';t"VT,q[,;en&yE\x4{Y@Yڽ:_S nِ__}X㝱ԏZ8\YËo<8|D^c9'f>`Z ;s :~@w5#ZVcr鱁ڱ&;kF}&]4~*@W;~zًzgM%{3VSYm.^,[}EU(/7~[mU..9H|kh;qf/3fv}Go]짹֣weZ ݕB35[W (`6:]k7*c~݀sGfB=իcǷ{{KiE{N~~XwU<2\ s|"j>cr/6xo_PV幚yaZk[떿H DY~q|C򇳚t*>!Qnϸ|'-a Y zhq˴k63z}_ 'u2α5il犗X ʁYͲUy|< JnjY?S'1[qWr.rsWUM`H_"Nyȯ7Beׯ@> &4˾~o<%Y`|bONy&'-7 ɳ2>CYh.{jp$ö nݥ|Gٙ_ϙo >%i|z֙ QiW8V`[;Z ȕPu\=Ãb434sf~55̭*Ϲey#/l5Go l@uE֡%5bM5f=t;34sM!j\gxMYD@7?1sT'`>o?ԧ,v}\=V7.[r,v(AZ+/⇟Zk,o2w^~e W侍,b&9֛/h_1sA^%[ZKi"._'.lu4Z >+9聾>^D@K|c竬g)P c<,uX=4XN׊ƙ.+ dů˵:_.kXs=Jډk?jcC(jYNv"qM洭gZqb=ZYU-qۨm9>Ӊ?x5rXO >pϹPY n y ~\K,uq*ًk9j_=%^'cYcX=|zSrar_3~Nq1ͅr[U9vmNjItBҴw 0&֬c S דj?y\Ɍ|߿~, NJ=^"ycU~n^q#aJl(cg ɻ'Z_˖gF5fm@kbZ~Rg_vշ[.8x9eg?|f#Yvclʁ] b SS8 腺ޠ)b_ZgYj΃lq}c \k{ \C}}h)^Yk6k}agWC|Үosbimxꘕ-f|r{|܇WkMjj#փ5Tf&3czY5smUrї͸ײ1`?u|uϺ̣wf-[98K hO9s>]lux?l=WoZ]E-y(秒}a[9wO6 ʗ?& -7Yǣ K[ jὩ7wh)Z3_\}Z8c:#%<yA7$n8W3vu_c.~dbxJj*!\⚖,WRwU/V}شkXc8mzr9mfٽszO4ʙ})\,Uq;hLjOg~]xlԆ8#j+nx:D s*sk!{:m ]/XՂi Qߨ_``6%F,gX|WZW_-?kOSy[qcA?Q(&gM Zr.́wh+%^ wle#.X_}4BvWtB]]u\\ }5^@Q@5_nAn`b8gvJ5)_M I-[^ V1_TY=<>-1^O}3oeu2gyy},4K:3Eզ87`V8`qcَt]@cɖ7ThN1L^|?,4W(4H>VOed@n4oiZ_#^/MɞT qö7 +.[ >gl;ޖ,]i^OHڗZ'@hʹO׏a߭|I~CPhM,.ԜZG]\(WeԹU]7x.poufciM.Å>ql5JL8މg/dsPtqQ}Dq; :%T6fs\C^kuǜ0f2ݑ+@o ^h}wPnϔogmd=8ƣ^gi\ |flN]Y\'{ BN>FI~]I'svHs!Շ\R@ EUb9m>{z$&?=Jc8U,?|GGWvЎR9VzrY~8o{!ߵ nyyε3M5~Q$fyZtzH{:}dTkɽ8Z.291v 4ydS(lbkB{,4Z= 夫f/v}Fqk8Kw{MXW,5_lCyλ3`SWVY}|6l%KblΥ\~7 HKv]୘{L{uyqTZ17(bS9(mr=8NV3Q5.6=:~<-ꭷyOAq_̤i[n%Λr|7IBuCґ(9PRGj7_y^wD,1Sc1cD!b](r1o.Ub~>yzwAzVV掽_׶mUqf!oΑ^|ϊa@@קmp^ 14v柽~cxy~Zz{S\'8A< =G~n7y)$^g'A7'ZϺg̟! zaׇZ]SvufɛJA?=y\y@q|1I=-9K&iBsÕWxVY_҅t3 aH͟>`o:im:˻V)b:}9g߲)Yo˝I>8'?se>k3Rwm{1pM {|1-b ӂrsQ:1)sx/:bZK#ؿnXn=&S+ uF\QHyCZpNC[! Za?aÓ|\9+FYB[/#7<C<#|OVC^ Edj1yę}9u>7 q[A׽P!adg˂K󙐩\hZY@}kVK^u1=gWBPqȋgUkO 뇒sff`Cv&㐇xb`[Ԫ⟹}q=&ao` n[3$} KK#=9b| 7A>llM_c6a@c\קcU%?,}KZ7̐O/:!Yʢp?A~i%re"WCCy,Λ?f>t*7Bə'U2g#"ϲ~˘t^m~-yy6 9fmc O⛳1}}l/ou>򱤧'4~3򆃐G u뜮eErVY(zZwotY7G6E匍s֋fF|qf<7".[?;g.QWf֒y.|N?lIT[2Ky'x=gCz\GO1R/}nFM>'*Sb gF>1`9sarF߉i$ LY-Qx|vs|=}Z3_>']=u,mNWWraܧY\ÎG{O9{Bߑ8a4*a9&1>M_A.rj+ێ>lk?7~1k Cױ[̋]1a~H[{Z1/?ĹZ;bpf:5e8Y5ӌD̙un\<ԃ,u>>coܵ9;C M[\o]a}[uu^uZjřqأ曪wĚbϡ:{Wc6ΩΣ?V{ ~!Y XEK3. 7ˆZ i]x7t7=81`{LQ&ְ0ɐKPjhO:fEJqa<{*oN؎yrF!3ӱkk8Egļu.ϜF[3'VcXIv C@]:fu^K1MNN`B!!ntvxZ2k^1{v]kFfi>Oİ݌ǚ$0 m㭯&uFI-V\_Soۼw \c 8-'nǘk!0OkL$~.RܰdH{}/5#|DG3 4KlϑA79p>SxR}jHtv!/1~^8O-?A.i17P<u1"ւ{|wq6kkzī׬1_\ β z5ΝƼ }[-Yvٚ㷈=;pxarݖg5_~< Ti0qq*{`[/Zu-z=Hslv|?z#*旁bylk{شMfpW >6N 0j98_ I׈k[iV!qO<6AºJs˜3PB->} O^ 7۰=ƌ*:k+#W[i֜}f)뻼Ўϝ3E;_~gFk#O癟cO.WXU͎ٝjrڧb,\<4f'``|iFXZ[G,hLbN8WK@;~R>J͗~Bc%p DWا=IyNUq׈9~N> yl^ߝ^ u-i9'a26id"ָc=-[1>݉\-eG1rq ^ž?=N @ P=q/uOg \1 {uf[zVCث$VwRN蓦ϻlfgCCc7]_2 ybk6B2歰j&2}t*4#//lcїz A+x={z"bؿ-9rfV=vZ˴Ĉܪ\poP59ՐDvw.\àK[Z)V~OIW tyf^ \3xp뎎Mb/7XᚂZ l.ȳGlG|n 0 6+ZsxƬZ\31z.iфXܘyE{N܇ո.n4+b`Ns.#۳ /{o~ݭݻww 2lde*Su&NotU7Q'81 [$/j P/ .$``,2`k8 s!;3Rwym]-uZ=9yNnĒ߯p}!>}q=>0Q_'#=;7Ԣ))&3N\ows/|#SRqR ,tL>elסȄcYlRiW+ 3`o]t}rڗ8W¾_yg.}y<=p<͵eUdlw~3Gq_|h qkV|ǜrC_{ohj|w' d5ۻ s1[y M-t\gy~ٵg3QKSOop:i&l ̊ٹ6c,հo/7~z]~cE5 01t6Y/0ms˚i N _:c,п5;id͹mOL: XQPu?Grn3g< r'T+ץ:a=sYz?d&40_; 3j5:peg܏--e#}#b}C?M k5淨)?N^}fu\FIKa'h8R.u{x=G3fus卸RvES}ogX5^ _p^6r9t12͝uHpH[v.EX,qӉOuM̺κ5.چ&9p!I lQy}to?0ͲUwRokyπjəzܮo KkЈ jՂM}荸kSǦ5ҵƵ1i'i \`; o8-kg1vq %-τZ'{^rޢ6[_Vq Gl: #S<+<ćζF`;ܟȁ7:)Ϋ{<4+.-x2U.jq<ׂqt/015=vZu[c'o,˯{kf5}ڣ9Zc=|ոߚ5U 웘ӻeM[8PgYe w>ŘC[z);ok;λ<{iO";5qp;ζx&AzBG2?G?)x֠gq31ې65FnxU3;_4g;|`~F7G]Wn'{\?P3Yա5cr?Yshc>&R^;tD{KsNa i3xȑؠV=2bR~'۳&~^yc??0(KϨQQƌ۰=cGo7u,ר1)qgc5uSzY܎&}wP?znm_O[mʊ *Їp~@2d5%5ӞNv[3]{=6b'VAO|x&( r+[|{Df`{ ZpϠO6#֍f-d:2cal?KGTxd?`wgsY^=8qČ o臸+Ϸ}1]7o{ig|h⚊ΦV{b5Jhg-.)n~-[#3t|c_,_4N*|Rubgk&"|7\̕4˾瑮[v$82h FVGo{Nh=f^ҡ1/pUSi9|⁸^x0t2q=`"oYr}~cת9*xuti5tl~'mZҚW`~^!cM;m[Z8wƑI?PXk}D 37b{98s:u߿YZ7<doa~f^T?t,k)&߸Wz3HVmWo0\k&hOF˔2~?b:8FЃoKץ:kH13YЈk7ߝ/m蕉>䊼yMnIrį'3zny`N*&LzRKSB}癋ŠĖ-оR6A]K%rIvvB=A {;zJ'yzxk^Eź0(;:0nG }B;f`@&L3f0Ԕ[NS #vDanxܲ0 #ql}]J'@<`ꨚ,mny;tAqνwZ֐3~;J* L=:~7 qL ל& 5,=Noc.G\t]q7u:SKEԇ׏=^^w:s-aZw# :y bz[ޔaIj n%cr{\7"@& zaҐ1d{yho-ah z;wT2g~]QUEkΗO7US}3Y+n0.|7EnSpxMZg<)R*k.1%3+3ýpULz5ߧ}^'d']oKz}v3}h .,'k>2O7 y!@2 hU4}B^pVW'6ENv.5| kט[ x#Fr"8^]nx==Ǿ$o8ek~|t煃+v2fhk+SV2v M`RAo9g$~X~)zQz[^L{2B88bۤ㉽qjCP3?7ZVQSb,+wǹ|[qiتǺcA/OU)_Ɯj9&6xT^GAnw19!fv{ } hWXǏ-kƮ0w^P=kCXkܗ)m amºwqFCW֧իE׃ cw6O+<7ƜFN ) ۬}oyE{:J<{.?`-`2?0l/W81W#/Sa~we1d3W߱(~[e= qf[u̔6^X KwYDl:a-a]'6mckhz] E%ES)Ř|h9O\l@k|}l s\4PV+ ^?3{ŏ1z17Βs!Wϫ>P: ݁X NpIsQNzWI_ Iiwc=\:㫜Ѷ {X~agp 1܁ڇ0x] k/>x4 >֋ 7!߇>K=68. hMG[vgSJ\]`c3-w1"Ub~Bפ}H<-:ewdҕϵLՊV~,klxƌLUsY9>Ǽ(>n#-p `ϯy; vY|F~h.̧ǎz0%5Ћ3_Fb}{93Y ^ C͊<_DuhY["oh;c%8.LC##~ǽtm'{=m_ ӢD? kzyZ&ҙ'4; ?\gMgc^Ю;sH :վQJc~jM^;՟X_\†tc ѷ8cmi\ 1̢{wy `|}׊կx񊬟sԝbkYo .?znOa̓LcgevLҊɀ= ';9&m1.E-q;g`ǽ^u95 !O"o ug<(>65'կKM/n3gD60դwyώpn > ⾸嘲R-'>ԯ{i~p_3@,ss]ppJ̴gk|}xo{dG'LjU'snB 6 #?¹~)kY|g3>?Go v̜}zqf#Clcsmhru3"rd s3vĞfca9,8|=G>\q|a$+ /ٚ~-m>[>n~ nn kng#WU#w >7`? 91^ Ǡ<M#ü:#X=МA_/~gȇ~.-nxg[cQU ?`=ڸu ZxM_Zqj-G}_ln?֎ l hG5 lg|Fy_ -q eO:@{z2Hk`>QG`Oz=r[U_u^[6!+O`/n_^^_q|~W=2ahĵjągzf9zSϑ/YG~k(XJ,>);FOL}g^܄-SlyOYqAs㬮˰v#9~)l>aZmۧ~?S7<5,z̫㚯{[~.pU `_o7|D < q/oN5Sk̺5jAϱCϵ4qńMs>%}bS {=nϴ{}v?Ʃ6(4ؤ~6 3 {k7\CuY~ݲ;FixZ[}tS3ͯدfhfxdCy2c3k#>#?ϊM}ƍo8>0`OyV+ >nٷ-ΰ~=^n~"< Gx^}w'~ۿ3o bMiy鐜ǡכ/-93C{.5xC^gE M2Ȥ71MI>zn9nYAkϴ`'=6F lw- 8v'Zo?un%fx2<zc~3uǥw qD#tjvR2[d>5XxSue]B>s2g[grLz|$웴KJ֟E*8A6o,s9X` -C^ Vmh CZ~zLw{k8/;oۄՁ\_;KYty } ˺آ㔚 ,^ОkXym⻻39sEA]~qhWȯ /E;Ʋ|nSGm=s}}ß[qB#z˞!?r׏$^|jy>M5}h"Y VX8p1]b3u2q!L\mzLϚq;z{ `x^1Zr_.r7c<{Kv1Ef_nim~Ex϶o 1ĸzwͰ'"v?~wPϯODHZ"i{`f~:5C?̡A'8ᄨ/޹iM*d+0=[jǧ酕5S}"\5P{vJs{n?YpO q>f-5I  ?z]| Sٖf &@)L;:ςyS=wzjZ>Ol̗~sA{X`W@#ktʄWl{5p\9iX7.s3kov?qss 1ݸ"bhz=_NI{wmCܹb`{=g13r F^ȓKorb'. ʓ[uav7άHuCSm=qT`cw,kIq[G)}ә۵,L:}и~ߞ&j?C{eCL3{`{3C?k(AxW]WEc0pLbnSioU_ێEp}Eu'Yc'01܋cssoB.յGw- ox0c^xll?;1iOuX|Mxr-z`xpy'M31Wpq)YEE vh9Q{_yIび3!϶~kG|= NK#c瑩Z>f__k&>pa:_5l%si֒OF(c?b`66Vcj݌ܙ6zjoy dixㇰ9e>ԞgT>_35꽚mc֔h_M\ pC sA? jk\{WM1.箕@|L ^pJx91ȥFѥ1w0o1ŊǨF'DN3z_;mСb~b\-g NΔθ(7wHc򡁣>4qMU!~Z*Nَx_އ6z>kw^qzy@zُ} "3qlB6n}XCy[6gN\{WSz"C3~"=oo~cz\;MS̶..yȘ[k s^OU_h.lseyc`Mm"n'q,iC}9xۖ;[ 385j蹒9hg&FNk{^ פ]B{kzٹ v5?ǦΝpMϺ~4O86_d kЭ[c̊H<ϙLR^~|H+Kp#`!Ve{VkiMܫ7`؟amD'/;(znjK9¾Y݈Un+TU>_|igxvqK_ic~kYb8$钽c45ܠ1o;W>~/`o)߮42lLy [VLґ  A17 3cQF.{Շ~?6tq}ϋpĸ8&+ՔydHZAFvseehqMNI.<c ~5r[ >ή8D;C:M l;i{{wz3\EFƦUfd@Wk^<_NۄyF8g&"!׃r?(y[L:/,=-YIU 4\/1jy_vFkkWژp̼ VL0P͗w;Xgh W:'0m>1Gr3gaȾaդ!]C鲪-M|Ύ#ԬV0MwhEz59s_k+vA3z+ BG|u|\hcx&_;ҋ<.c}bi2z;܃]+=ݤ[ ﶆ{Ŀ)kQX5ZN51SW-k4f4١IS};chyg+f|juıhƫzT3fGCyHɺBmeNmxp߃s:}:ӇE#Ww*3stjcjF7]9'*9X pbkݱ1͈4Mq+MM˚h5ڴ;Nx}_Y}gGzi`8̥8߷tm9X~ü'Հ ;}KnV]@B3sH:& i<Βv-_ -5xP] ^ȅ>xmP&m*7s~nmyqYHtW:.Ļ[ߦ==75+ۄqמo!//u:GnXKwnLX5K2)}\Xφ6uf 35vҤ#iFj"ЄuҵkBa -rv`6M5?\_n5{lgK+ojOF;j>oo̬==죒'4htM\ڡG1qBP7 [/ŦuI \7H+C]}oSzb4O3ӭ9Puʾ{D[--2id -*qvd]_'l)g0plxҭ䋱[ExO<6#֪أӚG*Ӽt`jLBoD \]I=ǰVcuEq ,N=ee|yjor+yZ>Yzz SE]A ԑR D5r{t1+v7Ħ>#z׮tzyXxΓ[uP/xg㔷lY=>|>5^qlݢC?oSyޞIӿd5sP4o4k5),Rܴi'ٰ1N[֡{&5=48{>c[3Ϛ^?yYsQA?qym8[.y !E0m؏|طܣNJyޘs5{jY{C>!TGG߰toGRްiB_ߡoQCLzֱkdGm#Sܻ|o,V Nfl^Cٰ>g9b9bHhkI \ ʺ{m_ȑ뎩9=G=Sܪ.q=-3+l[3SÀq&fcΌ>mq"4nVc.cAZS?-ΥMb Y=ύve!gup} ty{3j |8K1a->M#)Чz7aC)bpoS|-Gk*qƼI#UVF u,c=L6Q;/g1{wNVgqY͓KwTSCGڰ}x{fn*B\Ec5xniYW˖gF&^l]Xd ߐ4/G\ Ч0_B˜@.=1.[1ff!0JϏeIL"^.C!3"X&Ž>'}eÙgmv3FLy5V]=_|/; θi9a)yy-~H[yru+8z}w|~8k6aҮHa\Kc;v/~gܺ+bfqb-qa'{9!_-ֽtca׀n}ļo^bua.!/ 4 OlcP#."znz ڗ^Qn3߰|ط`\zf>LקV = eή4Yk3G7M%90vM\聾RP#)f^9a㏱k^4IM'#] #ߐyqY-ɞ,ktyWWh.!1چ>$aG͓{R9~}7afus͠;6_X>Yc pG\c4jdž/5cWDjă˄7l|{{\#B_4M;6_w:l50o@;_U߃|bϯu}gsme?L}+ShH-cvM|Ϣuv:K/sEȿ}ne}s\*͚TؤQ'cʘx1vȋFq~a4t?Zx`cbq͂+qH:u?疿Al]sW;W7+L Y}|kP,b uyʘ+_oۧ%97am Y5+زGO4kmJȩ": ZGVg j5 $xu9_ ܄4rg!N, ,wfAqهkV<N{ y,k)g5 >fl!xMxƄdVݦfJ5f:Ɯsx4S_.8u{Mlz͡5}+8F~ 3h7 )83"bc4S°1O}4'Dsb<>fkK^A0ԒЧ}{K:M(݁ 9Erz!#]}:ֹ435BM3k7%xsngh0#uZqZ̭7Փj#SφՋqTxuu^Kn+#sus[ boyuз-=TsGW/8Ԕ?+_.gV'v{:֏WWJ [{K#8Qwq{+`{MǦ&-[šeN#<'ݪiFF;3zҌW Pb{f㬚0N)Y^3+`tģzށ?`6߆u}qKC5Qp7jBͪ}1  yݜwԃww1!ތX-T܊z>gAS?u>k9sT!< I҂݊{޶eet΋;684.n-lއ9R9q=OT.,`](3FAko5LpBkbh {m&o\j\aΧWEdp?k"m}<; u]z\36N6|2Փ[Wd<uL̿Y#*"軏pN|rdV.!L䀾W50| % X73o6yj9U+7G9f>ONڞgXmrma8cC [5yg8#UU7s1f@c ~zU@m@=j_\Q׎IG)q߯K|U}.,H鑧:-iT?lͥeWΫh{u|vǪdC?nu?7W8 =X}dךxO+Oẅ́}Z}U *^ų(?P+0w1 nZ.ctW2tbamC[vT\5Bz=z&=ްB;̺h=>˜3Έ/lvN\it7fꛈc3:+Xwk)^MuїYߢ$7\O2w 38sC~ZØq'oh) 'cǵy{)vC Os߱͆D8"C˚g^ 1<3S*ùrj>eO4u#SG| y 5%fMW>+/9اΤ~ui%m=󾏶s6|]szTzS'Rв.вəݚA taT{p]!=5q )9-L|x+GQ0}H~ Po bs)yc5&SYQf i+,;1`.5rLz}Cg}ly.2oe|.@gWxMoꍩ;r$14-Po}ZSơu^̟jTK0W4joy}f YW=jy3z/**ƫL~xs;cS!wLxd=u&mE;&$ith`}Yus39 :ścbSrͻ^ < NqaKKoϜo{sX=2Ų&i ԣ 3JP&ݢO,O=ཟ|N1JϯMNk M[b?gJm̡_x)߷0,&)Ve.׭0w+6^=Yƶ$Ls^2Idx"tߘzľaiE`#q&m9uZ&ΰUU^;wKf |Msi/x/sS@%}03Sw {˦=.{uE]b^M\:}єuԈ n[ѣ"n`Al%R])}ıok̯9fܺ}bʻs E|rǠK"٣}{\سI10^ū:&^ZEVlIߠ~y]4>Str]˼2~Z emϪN{`x5~ΥTs..f >9{Fތ=3H"~eƹ&&Ǯsnx+x![o<.q# Y 3kkV;к|\5uFjHኈE.׉,}W(߬8 򶖉{?\uv|X^[)sDWE)fȏ5L%ۣͼv{S zf1ZIяR#5&Gd7x [ q=zz7M=Y_pY.y- F:[2's\I[Q>3Qk)~۱̱T?նV`|+{g-cMǻuX{xܪ*9x&{ sFj]rNX?ڡ {=mO*ǿ_bl4_Hg}Qr=/,M8}uZ2־oϨ߈S{74ߵ{11cބδ"}MX_A_s\O}wяAlksJz{Sg=J~ZYV87~'o?ck"8~=`Z!m||ʙ.YGi̺cNYWW5 H9;^ vg<]w~VKۿ徠8뇚x\9G9^ǔwbQJz&=c-|l5v*%YӔ<% ,bLh5cHSȟY޺gG1ۆc၇@S"ߌyV vi&<2rj{osoi=4mTa)k̼bӌ 9of-ɏA#MUj%yXQ'Gqf W㟲{ b*ҭ'xZihPLק+japXSF-W3sa- e=m@aBsotwK#.t. =[Yiύ=xƲ8^\b\n1mr=GƫgI75Qaoa3_=t{2}5ь[=gE}^}G`}cQKՉe]ek{&f.2.o m߬x{NBhe>#T?kN׫'967=:M[/0#r\k-O+"c9ZCҙwL`y##O}ܣZz}$4/ٲ=Y19)p|B}U\X>;VTu^^@_-.zCk_s{=p5Ep:n 'tL/5ow{C4 Cn>bX&nT(ٖ{ hD4 [YWOk3~;`bH?v'344ZYk՜ce'P. *>ÝtH_rxp-Ƥw-WB\ ֆcG b SlCR0W~7_8 Ig6ݚcB_L< /92CTމ`/;st&fY{>@Z ?DFNe޵רzge}|*5:osa}3Z|U+#"׺V?Ӊ Pg"6<#6 X_ Ҙj5B=g<+~}CW>f-sSb鱧3mtn*l\:1(>w8fI,BAn}4ff sQ3eN(]ZԱYyZ9#I|[f> ֆqd Yk3f|$xHC3 C]Sf2f̞%K[ 6˭/~a;0M|V̡QZ-M܎'h=>yQ\6xK4ӽ}Z"G\@w؟O|?dI sY\kNFgh:uh|S~Ӯ>0|U˘t/ oC|\.U1#ZW/XnѹjqD3JΦxܒ~9SL@o)V^#FcϬ"k';0 r;8rM=I>{Rs*mύ3WgzJ|`1Y7&M8_}<5/97zzc yҼy`&Ћ\z <ޫ;<˔W7qLr|uy-^7J1{6%~^g1^5(t j{;^3G x`qu_ Bo q0cDgޛm<^0v-!$י5֠UQ90f6.%1ipQH0uN'76X_~2kPvg*C)Wg廳ZYFbyi џϡ6f>_߷"}CSI}y52R|wp,ǼN>S c X,?ϜlXs4 aukY|]?t-sΤ sd3kWL ,{ s3ׯnF3?j: }a[)9+I1a#ssp# C컑qOؔڍG&nN+5n^l\:LK5|nKFnqSWֵ]"}iC'ͬ_Nx;{i=W;]Z};s4ul̔+ǹc'?Q% P 5g/Ev5v:ɇo<> ,84ՇBkƶs}r~YKG~^1ʘf͏ w<<oCe~&Su>y >7&1cU394xVmB=Oܤ C]:-=&P)k| =}j ڳ1٘Xΰ葏̘q-(кǬ֫g%=IgP·3u&a]Smf 7 Zҵg+a.~݄}O8`˾ pQK3b5z8>OLyIWaWtLuq׳Q>zF{^Џj ~,X)^q9zBF,./upc2~D9sPc8. )>D,kCγ68ecҷ(MaPlk}ő:uuV-c&NK"|7Ԋ{js.V'`۹W u폄 6p{[Du~fpٵ糱Wy ڊqjE;sc+R0Ŋ9cNq#Tܦm̜ySntxIJ6xO5c9 R!}2  ko? a]~[/[$^O_ `n7#ES8 x &1;ɱ^+>&\?呿WIE 1Yo)_Rhd%^ }1PA5Ief?O­{Po558380w!ݣoڪNWfyy7}4Yw(~7ܾhװqX1V?s,~I}Z}C|3Yu}Ѥm4`;GZ>f6Yik265hjb_٫Sȁgj7S#19ؔ+;/Y yD{mdY2A?ӕOmWƳ0~go[ٞvyC_f>B~V-{(Zz\A|v؜n1ju=z+z\-scӝkBJy;rTW|0[Ю'Zuv}noyY8[ (%sBmGKvu SCs,k*LeI:IfKF{¯{YcNcP,Z}?p5 k`y5'vЁkS=wا"O=8ܟ֖nF{vynf ߬֎0IywxbS﨏wm&"g}ОxvTυ![V ?#7Bw'ፔskAf\7yY#&@ԗ/4,8W)q;ywPߧޠK덼O* h9+>6Do-L?S1' ׅCqϫmpG&P3n+jG\;sgY3. 3i>,< kenqL0^[)x{ S.'q]> 4 1ɶhxV},Cn< Db'BϸZW)0Xz;orH^gŖIgX"j<uMlgax{ΑE\ #۳ M$~\&#f{uJY?iʫ}+FȑuUx|-nUWoS9\5_y|JzǎXۛ,mֹb1{< 7= !oxlz7}˹j Ymп-8RS@> SA}Mx#bX6n~b.:,dsi٣F-z|w[q)Gה5zm͓ 9'-|}doL<6Jw"> L3P?`bnc L| GvgG}3 C]M_Ͻ<4KrJrK13~~}Xk7G. ٺxc1]whзhkXz5S}k?p~OM\9qgN=pH]fh3by]frɛf6B{3E<0e*oOv閜1vZ @;Mϱ{qȩAǁZԲpp[359{ﻯ^? ɦE |fkFWin83G9jE˪MO8[oo܈q[v#9I<3|A`9f^콽V[۶%~VӾZ|l ^z P2 e 2 ; HksX+{c\s9F}1v>`7_ +h7/3褻D g5wve`R |#s+q?Dۂ{ȔvŽ~!qߋߘ?{Ľ]ꘚe?T`ȥǥG@cb7l/=GvD9BzfLjӆKN抄S׽GԢM[ƭAC/*?Iwu#㭴 ֮|Ahh}+8yЇ@ |KGͮljsL'͑AQ;+;X}jѓgw *|YToڇz_[yXOy` o f83twjlCXX qvx'sx8R?U{`!FUÖGĭIC&>ӬKyDuUs(u vyŔ3 Fs1ls9<yƝ.ubm<^wZ0<]޾Y}wfYׂ^?rLL9L8ÄIyu\1:kl]#S.|ɍ\ZExM~ ?˻|=Qg˥5yvi&z V)C0םzф5`+&ƌ _8U7=ŸmCxyb|:#M. ya̚0{w@\G]북Wy3+B@M\3%?"G~n{5Wfuٻс]XLy֜grHs:ԣlyZ8po/C?N@ ;^ rY<Ѿun83=M7y =zb~,sIz1 ߡ}wOv|֌=}xmsgާADlec2߭n|_؏Ю+367{g增nƆǾ{|VȻ`"zE m/9Aw#>_;_]{`qSzD^?Сd/3 {fkuqhBzApC??e(4<B<Ϻa͸t(I\_{B' Zam4/gS|CKjH}b}]bWk_YׂOC+V+Fk28Xyy_<(4ow2(SgwC;uequs ߡq:`Z:.hQk`_?웵[3ggD๞2d5d&zEb\0[}n=׎ bw7y̱ztg¿s]s+pg;UV'D zŻ\Ź P=S )ϪH#$]sM~cG:9m=E=Q`83# ]؉?#fҕzx Uw\=cgy{BnLo%n38 :Һ'70nk*bg}o А몾-Dz_iF5||z59_㕟罅Fi 䁥Fj?5q3&.`c͚sin {ۃ٫9N{ Nw6=-&'fM-)k#@MR}g&mqkKO[h"@}|vf>b.5<<;6xOM;܊ \-zsC}g1@8١~ <:s;unsj9]x|fnr~tYX{DM??˚ʴ{4T~~1>3];7fZ7'?yKbQSvzbn詔WVD*\vY^{#C矒8B/sиt=WLi`zaQLN3C ܥG^q&[  H<~w-ڊ |,挡9&G -ʭU4 󅆦YГFϱP|4@sSDX Ã#_dzcz^@{rwm~wV7y eQu;r13ޥ>|bFaNrc_0KamN,6h5kk90ys&k~|sw5eB^w'xu σq1w׶fc>W×W~ҼMDA+3g>>1y1ơfo0㜸7gC O{) |_3s7"w=7.5uN,t|wȸ1|3}ifHrlgXм`M4Wj2V;ϼVx@WM>~mI0ui觟8Xn |>>:7LG!Vd|@]ʉ߁Y>}>d~%o'\!YsKҰo yˌ]L$Q| 30O@83rT#?t?}Hql@?_~:w< 8RLv6:cg‚cjGr?@%j{uֽ\;+TՇ66͊yil|oxΊ^{~ +]`if6?\9dUwٟwkҮ5i,U'  |!k'wXL^ogL^d?2y 1<.Kif>-}m+հpAqr  '̕'N=̜Ýl~o_f|-r%&mdco`LzTxFDмSS_8qwvڥǫ}ÉS/|x+P y.[{ sjjqpx1HKR)?-kyÜ;T%r|_16`:wM51&}k }}n( ӗ̝kjJ;NZZx3_sf { צtD,P_ u]#pK K,NЇ'c`,_LX|ma)/!sce ':1g{mg@wl'v<*kGU{Yx^myzT}3x]f13_ʵg93 ^=Py=l۟A{ <ʌM,8hE,>Ժi{;3fS5h3MP ]۩I[z;Q~1R:`짊\YAa>\)--5k6ω_BEE M5j>VY7&޸3Wܯ<85p:lh 5s\d|\Iffd잮ӼmCtH\z=^1pݜ˜'|T;h޼pz&_b‚glxޙi<9><g)fL=IGQU' Re/ƽ䷳h} ςw϶s~R _w>N$޸O񺟾Xh LGZҘ[0ʵn`Fskk 4Ӭ^19>1?\קhBo'mkGͰ]:?W,ǢmrxL=?STy(tZ:b÷s}V{:3ԪЌ#U>H׆xεgH +Ls`?.gYQrے5aM6syi;rýzw sRw\^gOjѨЭϹ?Y褔S,̂+jb9L#4eF qv4:I0 fb/sF7=|:x_X5׼wV3Ԣ*ɯ4ޣDlP[9e)#zf?=yzV&8ӆEWwxOvs 9#΀|84:`?2^{Mت 5`]\wԝV k}ea?ss@J|*c))nu/b^ČGs xJLyV P>?59slOЄD9Éi2Fx~&Xg1赿jWO=2)4c畡A:6U ,xM8cCчyFyyKHϣԓYHc_ Gݭ?T\Rλ5ls7#ʜ˅Kzs?@'&T;7akm7yj٨ g)R_II?saSogHm~*?9W3o'}|+S={c+S:'~4C501:-ι!^O ˍ׃'p7mG~2#ÿ7o M[Ջ~}uUi}B ;0LfgA~H! ɁEtam{79&5h"+soF} }y""ni|̘{w10.̭7;35y= l+0{tny;#>QUW,$p>Z%dkM/:œ ڮ%p'C1tK{j#|b= }+džޭiΑS }- Zi͈=1w^S\~]q^jP#[C䳮07:4ݽ8cƩ.ޒK/:F;yȆy,30|VJ >bpЊ0WxVr-&呷Mnnk{?7AwL'lZ} iS|*hdž֎/ ;_[{V|{ 49Maf6z۟=>on uк~CKb+Cs xuoLύkyb=ao1uZ̊hQICWz, gD>{A^Ei Uo7_ZYԙp.f`#[eI_[b =v;*=[~dS^{/+VHC5ȹk{ s]~;5uY N~l8&,z4}C+{jb>1G6me\e?WcBTr.3CwBw6}낳90byq5f?St͘uU-0C:)k?ws|n07ő_#RXz>~ul_ĊBިS/*3#9}+e|icxQ u듧)u4..n b$ޜ}8_m}/ y4g3}m}ipK ?|1p/it\ >Go󖴖8M..,ꭙQ7xaۑ6G|_:!sb%A $ ̝+M2#` YKFMq5髻N7.X 7@NyYž}- .Q ))ycאcc,,px]:mC|"VGrB߁ s,շK pXx ~#O]s]7G&\k48 o/JcΈ3b,rfC~.IZkx? =|ie돰ť)^~Vx#쫊y݆k^K_!5#ks i'y o *~T|P]<*Q~x^">ko}pcx~b/0<;Ήc͈/&&m.+kqcug>Wk%_uu;s)cK_;nXpBi ˾E='RX==K[& g-8rĀ[ jVCwk꽇'K˶}yP뺆`>8 yyJO\,}ޯ%.1{/ZŐߙ<֥s)cv-x̷>Oºԛ~Ǯ(Wz~{>Qc?dɷ=橇VGCކH~6L}"_5p&Fx_z?ﴵQ7|GY,loRAG)z ^a\? 1WwO}&T|TuLE kgeomr>WX/_X3x&oȋ?Y/ߕQϯar.\y Gr%O$zԨe\/Oꩰ־yŘ+l9r9m>Z̮4J9..eG ꕅkA31f{i[{V]ӌvW$[77B_,{tyu몚G?["5mf9#|ߧ?{piԀ>K 7﯈*V`uyI){>kӼ?9ȅ#'K 4G>Wo A-579"7S&GiqK9RT}&ƔW/n3 {&C^/MemOux^ 2SrȔ煞CxfIF7vdуޟI߰WK,^i2gd51|5mPշw(~|;w{uǼ6||vkaMo3;=gn 3)0Opx[~Gf]ڡ si~ }m48MNwxMN?BY9mS'puCoO\§7>F@nsϋ%5fO_>jn#fa .9Eʳzߩ7!L֘5_y >4K]]0ԍ +N!m8ICZ6O'GMZu.peIˑjň:3F9U9f|lA]=dܸ_.'{Spa_{wc\ؼ:t&Xذx[}&Lb}yrek Нb̼a1H;ަ?Lһ;>?#ү,DOT=T+T8%'.ަ;njpE1{eW{oǹ{f5fLހko'&!#aX?]16} }#^Z>[['lK8Ӟ >];Wau^Ta4X豖'bӚ}=BkV'beJgڹɣ"a[䖧ҽt{!Єk(LWwaq-tgnj#=IG֐t;ܪ/AqޘyrfS Çj|`38ܪQQ ~߉TK(u|YWO̸U#Ϙc";?[+AG ]=lҴbnي}Z#ئG=v){KCq 9nZRn<;l2on-tK+ⴟ-zR7&AֹιKC9/ϘE la \g^tԄo if/aT̝+@~R\1OZ\ws}ѢS;ֳqfU)*4Uؿ}_k)8elXf,fSB>gN}a[7E;3iKeEu^ҝU-k]쎊yob3ALg\Tw310h-f Y2yKWR+g^f' x{ڠ$Ąqgg={ynYk^-k.kw<7+FҪܫ#zw 詐-vZ`sý; B\P3Ct3kyэt9_0erKV)o9F^x^{^ zd*b{V^1_QÓs4# 0⯞t[ܵ?6w\w n9]d5nZ"P/ /=f,\s|d &~NZy5^]ֻk4w [5X{Lq_ |='99б"L|tE|IWSP/'4\eY"/@zVwGI*-^ 5S}FTIC}Jێ wד8tБXhnz^s MA+.X^7c~Ÿ~n{_>.4üRs޶5I𞘎a f\3cbBN^P3Cʺ{xIRzޮs {^W#극Emsy#k7~g -4YzGp͚@p5w:[5hk(sӌ̭:zdGtw?2qq/f% N!Ÿ[a]?;(P- #!ߣ5䉦daL^껯8 .zeO=Dzj1G~=a:ggEf`^5EìJgS!!C=@k//}i_τ\ bؐ0=v +IGyǹp$wTaFg =LY.NY5-fqqf~{\4ErN3u3z+0lxY7cq wncef+9tXk$&[g=~/ۇbM>ˠ53.*4k8]+EZIu_ZG? j;Or m N'cnht/[hjv8>0PO] nҡ3H>Z_oyO8SߪQwd9AԬ8yJ t:@}5sPV^Wymܪߴ_C(OP-qk1X׀*%`H?x/=|6cskaE] s%?]p [:1yF[|i{\h`j_s>anշ=qUGb}nzBZ{R)ѽV<=_gM}ߧŚl>.1NKb ªO]rwXCļ̱IuYu̻!F/-z.xH€Ã†vߧn槗̹SU|ά`."'Sƚ?:K?R [sC_&e"IYS&púAsc6f~/鍦?ߎEGvHnLk%(zĉ?0[+V>/WO74)nOY@. 1Ϯz|=4{+Р@ >O{^tzG>).wr}Yt]bnƚ555yot<Zoɚ{~qMwX{sXr.nd>.\1 19jq[zʢsd>l;~hJĨC }6xk<x~+Fzu}ګ/x=[epvy7tooKXժEnEMyCC- @'kS}W3fmA#'<aUppV "#{ǥ7}qC5ōS lj G,{o3MĊ릜376Snk?nƽ5.la5pŽ޽$390sUcnϦ5cQSK䚽B]ғԄ;A\~#~M?a%b/,~-L sЮ߄'jկfcEG[]~qM>v;`ĸ;5O5ybBn tVW]X9xRl3ޭɳtnWB?<לz@[1z)qZL&xg;) 9y06y"/ G?5 ZFi&-iux#6\SƏy4_H>`{ϵ'9N׎^xV9bnbq=9`/Ԭ}esn^a)g>|Gu{(?kXOڧ[zF\m͈g rL9u?]OtS]!nmbg+qth}Z̞_3sv&V̈́?տ95|zxT>oy&/ ;P\Z -^SiNC}]s%c |{y4i*݅v=S4介y sz<»/uoZ^ehM~ןML+0#a.'-rʚW #v ;xb^0 1d]:*-7ߓ4yۥlĉuATg2Lc>U직Ȋy}O4CSK< 1̩LO]f/JTh*Sm~HU5Hq^ιF k?7x3p>[gC틳;DmbC%aޜw&<_|FP=iagp_Г6猆e~uvj]|c|5=m9\<'\~>Hc4N>5fzѤ1W\wԐ!^ۀN,[u1NޒC=iZ|]K1kv~I’:sbgPǧy)nX+ڼd፦ ]}'&; :h(ts!$9c-=4G1^2Kp6ӺOLxwh^{`AJ~>GŚ_^>:-Ek]۽OSg^gwc&#Do7W#SGO:?6m^F8asM=ǴspGO*yׁo̜|sxƒOyQC;򇹅zn/>'8OZ7|Of ;l(cMVg8?Y5oo?]'=q& Ly/V\Qsbm}V3C 0z0"ߑE&bx6ФX>AM*ކ 4Ci)0Z#`Йa~s+焐 yw<|Š[ρ38=me/ <p^Zqlֱ8,F3OqY hγ[nvu3hkߏ!(}|\G|Ջ&?_hQ.Q+n~׃b?G k@.}rIj\ھg…-}6q}7O'zCФoE,yXwIgfw}g"z p<~sɿMZϹ L+`qML8v] X\XgЖ}zK^ ]j^YE/Ƶc \əazE= *ST#?Z;O>>[;RzGSrZr?Z`%'\8|o*0y2wVϱ&|_-fhGyH9G{wk?<ǡg6?F^QѬ6^eϤKVw*NLZV]}Y `X85 EL`iy ׵ٱX5b}Ù=<Za,ǽ!_5O'FOVEUߩD=W|~Z}_yqIɶj ܑiM=s?:Y*=rtcc_W0Mk+>Cې 97fk^ zZA=-яrli^7Tqϯc4{<ҹ>0ҪU֬׸ހ+Nn=:k]x]ym?9/"~^ ޻zk߲Zg;KJ:HaBD랺2K?S]S7)5xyW|mrZ9'jBCtϊw}XA-V z[5%ɄGly:g?mŅ/ 9 +Ak??Р3T5wp?,2'5bbnP^9'5V57 /K\{lEOkm[pd9,zxJ鵴źtcCsޡs  pGNA pNbq?*=w JrPqeGV!c:򸖶kxʄ77O fX y'pE븥5vd8-I@MLL7m6|S5INK _L[8#&nE^ i x4aI~u -`>'l;f1ӊ)y KS]tmO&čG漚+xbrAʹ>Ҏ%czxɃ×]kqkx^CMpSְ̗\_A}Irk9 sM,[y&}f Ia5z'Ԍ>23?;Ƽ- v370ɹ%_1U7|#kn?_\Kރ|>([5a[9Zs A \AsMn.kzB yFʍ>1kVMwr:Z[9#>Sͻpܐ}f9Nq\:=u u[VUO>cu=wэgtw&~^R_~ۉiUó-( 0l{Z#]=.s0/LXO/`@<Ѿs*ޛނ|l׻ S gtS'v ]|9Pۀ*_WS@+!'g77:-`d7B~rd3ԇ#i USo#Kɪ 恅&rdsٷ95z9 Tww昈=>E3nF3cOR"]!ttn3koa6z~ڧIyyћqw=БX80 WaCԈic6R=m2Ԓc}߀Wzq3W-Bx~;`}%وq(m+CLhUxsw5{x.G3PQ߰ly-4;pď|αÿsxB=!S uK]bv`s7Å#*3V&-hAlGk}g33#jD h塬yR=80ձlIIs/{WZ,P~]јALZ=isPrh:Lq}M&Cu:!7rw00|Vy3~!ݠ3xVj1D:cqZwZk<L}g?@y2jQq-NÅXr˻ph gqbVˈgɼQL]y׾la ~7-O7ᒺz?$W*E/rnugx}7n[xJdo% ?gG>Jӆ񮭙 ?͠#YTËKbϏ!zᓹů^O7#̚k҄_99:A{Z.AMm^а[kݜ6zm`9+YpMIx~9$߀ 9pٚy瘵ܥŌݸ[5{s_{4|А#9!9!Kϳ1=93(3α1rYރeԚI>xA̰Z<;*K8"G9V8iUwa~ <͖D-R~rnC\֟ö%~w-Ak$ ĤǞ:%?oo0ϸNꟾd> &t菗lA< ~+OY" T8;g~7,WS #MԊC #Ɛ?25yqjjעW @q}O_7sv/+ڴ~!)g|PQzY.36Kh9̗Ѣk&8x퇡E6O,2>{!dÜ3FXMqz9ދ3ZYA^5=bNwX{u ~}Mq:L2ngu՚mu71KS_i?%F&űmcN #_Z`5[H8r|TӪRy8!%~'1\ǭT?k'yczZMyN,fsk4柴'&tWMML٨Ssn9ƼӾz z|=ʃ%+tRKW_O3oߥTH#S.W'y_\{Ȇ5_NRX@{Y ğ_=6Ex2I#&bivP2>1b.rřnCK;\)졦VǾE~&Ă})ˉ?[X;iײfof>p'v9;ﻜY]2D|w4i r'kgVӧixʚX~wdynM5g+hT-",L {Lg~ábG PG]φyژ[3؃%? g)k?k^UĒI{wݯ-y5y;,,0}SjqqF'#Ҿzʻ-F6\ۘ٣^IY/4&2^Sέ841x]ŸBEF/XZBЙXgNkZqԪCa>O[Q`nWΪ|Է^m_ xޯ5C\<5xXH NyOٮ0/;Kvcg.6ap,"+f,#rC[yZCg-_ގXk1}ek=uG/l∥kڽnlOnF#r?8cvg iF&q$؉w?EO+_51$T9XnG_֥>+_{ax.K1E~OXoCwvѾy).OrldLͲYqJͲEKx׮.0Ig\yf.kJ*x[|]pw*'[H;v^y9G}WQ7 zӞ\SmG~}S'f+3qg}/S^et2"c s%a.z%y4+-uq@S@ڤW g˻_O:M2pv+SҢ]IKHG\/>WR nbor_~p &Ml |7iu`07S>1k#/LV޷n 6 ӝý8#'0] VW ްtf—9ioQ? 9_gd/P\_arL>0N }zKDE㱧q載8`s )Fg~Ӿcu+U "O>W1w҂P \18t'c7z:.9_l3:Ci~Np=>s[n%Ǵ<禭`Ҕ5ܩS /~j󜳧WX&U{y{uoM=:YF~ n\|uyOlaGBM=l#/zi(S0#sOss朞7EB/VB>z> N;H,,2co-|WcnNy|놚[#G<ԃ^z@{tubM3P}rO[rn,Є)3Gs.|ՏGO U?1vw阐ߍM~fXG]muY'jEܜأ ɟ}sk40Q'&%̕;Yg~?gl> .?0qՐ#MB"Fn[1^X\Ssvs>b |'3!G}7sHޜ&j۹zS@s^ ~BS ?O?w^Q'[2G18yO钳(86JF(_/ fԻrC(!v`:hxUl|07 {d<]1ɘNz/Iú9s^2CcXxN~hЖD;Tb_ |x~yThaKΉI/CϤZ`+i g\&?mط{jQLu[&#aK{W;])^1Z`jSMf4kW1,qSr+45bϵZ{ >+y)sb `'0amLz.E]~cs^ NWP\)޷Qxo+>1ޢ/d~`ugC\Y}0ʜ\#e-ݒ\!{g KLS#!sMē+Cuge;( p+}44[7!y;k%ֵ9 SLiA`?f0:䡑ם~Yr|gq}\p:NZlKϹ즁<w6- Ql M=4H=mw<s"sbzIיfZ2;K f|9x^4ʕĘ=gsi ̤1I䥁g[Rezo8TѸ JS\fk!sIzXy=Nn4GM;K޷L;Ǘ;0뎵%-jر6IS, >sW-M\YlxGl#sۓK9W#r#\'kԐܛVF>3xfݮc IK_ <7K]j/VX;N:'ľEm &7.[/3!~yEzvh3歜q}^ie1:,`]ʍkV=E>Dwa1 i̠k0KϞ'h= 87kh&G뾰%f]R}2 XCo]O޾Q0Z;]Sp{2&}] [_.tm!)=З}rZ axFAPff&V!}Ь \30@~ Y=s/PC 4KZiewY[ `E!|SKDs&`ݱ}Pb#Q Igxpن{%mg_y5}q9%|%[kba~~ow¾^aiDy:)~(q;lzKNr=7Kf]y@hУB5{u؊f&^&,<8fN\0M|grcty4Q{/<_3OxIO-N єah@f5]uω_e-4?X4l\wj+s]'nsd.0whqK̕sQ ŜG i4Zi6zPBSy̐[nüT\$ rtx?+f٘ky䉠cGތϹyrA9wJJGjv\ۿOU:I9uظ)r ~FDi?KԱ곹0b:ulfŸͺw:7Qͽ`WF{gAӤ^2sgU'?JƎy#x>>?C_3֘rsǿ1zÿ>y{1hI/85٘3j9 }queY+39/~pkA9ı_)3!լZW~\sƌCxn.RErjҬ>BgԸuB?&U8t?sG".oe<:mbCwyחVP~ue)?Xɻ["t?3][ssgFŀIڠ?c]O~L4s-wS>Sָ'53ώL>;;n<'w0Ks~Ql?{ oSěbzV†fܫ='aR?'1K{+M :~x#whB>&M+h+'7X<%Oűa&w -fܚ7g,ń5v 1}b||3ufpsS8xgHz}$~=Lӫ`P#Ttȫ 5oz_ }7w=Iu84]CB_;M{Y7f5I|o6k7U @LVsߗ%Ьx^vX1 jN%k)U ٛ|N[\cFwOF=  1GjC3[ |GUzД}Wsoԟ? 8Cl?Ϭ"کi0xC0ùݟ^W+K,8g>P|w$sʃ ح<b1k [ }Ŋ1W^3pGN}Kch9.gw/YMkz"ܚM]-۸z PX0&,yELT&/ 4 |b.U+i8/D/ b\# I_ۥo{I+&|]i^ԉcbܤFN هݿ}1t~L+8,WNh%)Zymѯ݀=<۳k{I#:wz`D>xr ^<׫{0:a~Qe ѵE8j@ztݛAd*s|̷g %'ӜmQ6Xgs >`oXisK/v:W=_M^vK9WsysfhiΘ+g!p;Ge~4[c>sy.Y{TU0>wMy%p^9#!} 7gI񼱶 >2zm=yͻ sz"7{v}ˆ&u9y&:ri2?RW$nsE]N!U{䴡ø5Y?k^pmR ;`_]%j}9_u8ӓ#y1aOf5 {CuP`P38܈qq1".?%kē*'0{3.7/vN g)Q=XRD\bZ֞9|4Ԭ[5C[ywZL,֎O]wte?F\n y^W|C?>}{"S-8-w;24;{&0CԷu N۳w}"oLl1{U>6j)Un(<S>Bg@u)gٿ}k-j'޺} t_2_eLМϜcfGCb$?ejc!L#fU̿HXg+- cV1mg{5!ꅯ&OUz Bƌ+9Ӆ!{;3ϯnƐfݷY`!O_x^M*_ؗw^,~~+Ɖ >*Ow~yN+77R 98tq p `wxt4ohGxL^hbkMLL51';E5=2g|o̧nmYW+ ϼΝ'ݙRHWvNFێSj&#fvFFAnH{ȇ5_,i,򳉕3mfeL@`B*Իȯz }dh/bܗu=tnOUOFz7~X*3`{)<šhZL~{j)nB96am@#l֒rԷER-jk֜%f;Ͻ :]X |f4*U֞H,Ѥ.K+ y=YA x55 ^2G٣泭k3|e`#S }e@]"D:=C7āobV||^^۝3&\/7p oʹZNvkSNyBYxp/;b=>|xe >7 +?ʧVQ~6W/t{OҼ3D߆?߳9R&:x7i7 1wЕC@R3a|8~ߜíZʏ yC1y~/յ0u?Oܵ?c>掝kG,pjQ'RgiJzfZ&_uȄjdS`WvY> Ę p39%X;r/X(cp=@G6#ŅWYS.]s) ˥ JjጃFnEr=Y=\̚ _9w 4U Ux<bИw^V<ߠ`qbaMGȱW?tC/}ߑ4০^!泀ZG&_l0V_ajufz3ۚOpN ax[;Ɖ ᒞox_MqLYQSO!=̓|{gF{ ͰCF9c0b<Κ"X;7ȁwqGkGK+.}|e4Νsinq]r£S`՚^Xl߉νH>Bg[-oܩ,G|ص CUѷ6ƅB:\}*_NٳE5ȉQ_cy K!*<7Ŕ SxN> [nk0ƞ1<~Nym?c?s>y~A迡5gh}SrϠ=k/Eż:17taqjfM;Sf3P: $zc>RAnUk濿P_>]/}Is4{YxdE~o7~5qT;LpQ }wMԻ0yx k30[1:Cq7e+P+M|1{s{g)kl8<庤l/xҡ0#f\=^'_]ϽKWM:8":Xʛ&pM֛}Kh77kx>8k<>5؞8F~vRi@r"fn쑜1f=<8p3.R݃Ddeȗ_6U9f? Qb~q94>5ů?0M|;F'G-[VLV?'AX1>g7Yœ=6~q/uh`|赀&=tgk&G(þ#քY}]g{*O/4m7:Y׭swYIw-sSm[CFeu7uw37~سۚ9y\:_:f`xNg|\ ;,F74r cȂX' l=7zzd-)븙Ə7WQ_n/+~OL =ȱ{?Té Csh^Los31sKm{,yԃ5dA/ {}}VCІ뚆y_m{# _eOW`LkjŭFsa#1U9B74x{N yw2Yש6qxo*&^#(Cl&xzӈGZ%[24O:5vWhfT+ŋcDK|n+ƙK+Cr̽NMx1yU\67>gn{y/sn:rn^{̩-?gӊ|B|%pw9k.j#CԅFz拉a],nθz<⃱&|w7|Hg>TM=UfbN0g/Yo ^/=B:pǸ8L3h 4$"4L»1дA}auyI;?bFlQV\` nHa֘Q[*mYh~G/F5}K ᷅=,l\ YG z/~ĕ]䬈{4,WQ:sZ8)dׅŤGi]?R[!L8#E|ܳ>eUOr+s}ìm.L=#z~=Znǻ547+k;!>?4#?0N uűmAY^e}&I]wp:Yg;88.z`Gha}Y n<9ㄼX[}笅3~8ljf]/SsSЗ ߫~n9? EN,G{x0! \N‚@ľ33ut3 +kj7\gзJ[^oM7]`fǀ Hzas؊5-sMGmroŃYjvԟw߾ĤnkhДLZ-8EȁQ{u-{c_yҗ{\КZ怪B45fw{-QqLXf{w MʵצšEW}:@(_xW<>ca1sJnّk|eMQb똡XzCZ-]ymʻ 3GmğDZf;C{dP]?T'a抜v3/1>`?#fy՗>X{ w qmX-gY]3m S[M5#rgϙ~3dtm.ӕזVĜ=`žl){`%m;yu 9a4JO9FT3qEEִ^]hEI'9\wZr/wuZ1SC>{#5e_Krqw Q9bybBUp/͌WX5<ja?|okW b`g!WEҟ91pY]_Y;iVݜrY nT{='x&?;sOJ,|5Й _w=ڹI}g3w{^u]O0;ۡW'?!e,0#a3Q~:ohs+94}gJwwK|vۄxTW Ν<#W+}b-bD=\gE sgҟ{'*u'h|^%WɻfX #tBY{+ygXnf_:3q|Xrh Q[= t=E{dm\iR}7 櫥ƞɛ~gzεjj_w 4s30[yk+[ge &ʿ')_j~Ε+g3M隣4u0l?ij9OS-23!nvN'6zc/!s2ܵε4o(}Pf(qC=kΚie}IRw־c/Y_<7qE%uUf*E}^s/Ȟ L=-&oȟZ`hWWg`x34_hO-fH#^sjՊ:']ݕEMu4S=g8ei[cF>g©ЗrNS<|޻Dޅ8N:ֿ:_}诿{[rjMd_90*?`OPp LڞʱWF̍3ySG=!玵a\w؜R 8δ?݃9>X]I}e>~O<|-S+)Zps o\1FDVQw0"`cɤ9+UDlƈMppsrd;b _h Gޣ?#x,dM}AG+{"iGx=0{6fޘY)Vۿ{}y!~05>p4a8S #FLϘ_5+k6?οU_M&7~s &9R3PMkQy  phh"/_;bjEyħvYY7+F 0o3/eӾG#.#gP hS AP_z/g'Ăw}Э_ ,l]UYjј14/3SU`U7|#A׾s= ߓW17Wě~"@}!NSTS.찱)5}1B62 ?zc3+>@u3֪,vI\s>c#YfLN B m'+?ި.]O98tк65~OyBMIQkoW̳rmL}eJ4ok8H`V\`&}З5 2kg0r<4o5?KyCмkKboč_=l_aωLĿ\Ae[sG&1_ż5n_in^8g8GguτןdCqw{wbɺqŞ7[ߞz |i?LqW7iUVE10}2ˠ [טحymΔs _%O]<79n ZEAޗ̕}T~>;;+?+{zb hQLt_M{59 .>MU#+垚q_1^_$k!?0ءi.oww{4wB9a]3! z׆&N~͞|儹ۄ{wfή=3{.M}/EECn_{6y۬O Yѷ|{gwٓIQчI5ֱF/LZj!?XZ{/?f+| *EE9{~pp7+t#;+xGT= rp ;<uJ%hUL[5f ':udV.XK0YH/b'+/ȕ~6#/ _{[;N.<5T8&lY rfܧд LG1ߒ~׏s[S7ZAڬBㆹ/휏{̅򓭩q К;FZk8/):3*R]1&'B\,k3&/ިثFAy֔^i?9- .ku43I2:+K츾(z-o&-xs?,ň>mn>a%:kzU^b&C֜%e5 ̈ua/VJx,?Nȹ3t$}b&G2'>礷k3u%wwf)o;~8o3O;9?[Xx|Ľl{͊wXܘq` +-HbҜ Ms0]й#qbZ]cƏyt)4 8orqS`v'Gw}q8W.VGTKϵ?k[YkE&m΍Is-x1qJ`#|&z>,=;5ziQĭ1O^y= ]3gCgEN10Wy xrBKy*Tmr%kp߹ Fa߽\dqswύ'Km = hu8ae|ON [Kx8/<cWġh1~fȥV_Rg0z1Cr|j\˯~7W5x̊#O*xl'<镋:k3{WC}u>1+-ɡI?pU{"WAJ7X 7L?ȡ!t]Ks|6ubߗf[RwVWfj5>W{c;q6|\ѣoDk9B3jp[o҄"G_8 #-է(>B~P'l%xL|/AG,Y}WL:‚KSW?瑟G>-ΩݶoM].T~fzzn˻}]r1Nkݶ\L=vj5&r3ni x-56G˄XNuQb&9<4-s@|f@>8*Whbim?7S?7>I?*rԋ:[^1OĽNkuVJ/? K3mާm[|팷h z{%cKeWT +Gc'L,Ia_ =W9ޡEX ]£s̱,{9FM|y͞:{:fʠGbD,mX*p&W? '-W>=EAcLv|{'g%StkSKN{5T?_On:SZam{;>C&RŬsx/rШ{=7bw AD W͠MC_rOĤ[>fn4{fҥLYU]Aqz >5m?M<w 6S}㒇0ʡbygǜEMD%Пlq{|ƽ-qa }~}\gyP_Ĥ,K:Puda޹k^r5'ٌkjVcCzs6hQok+tߓЖ T 戣=tg DZ[z)JP~oQ>΀t#_3 ia>q4{V%o L5u"{y~7c'JG= M|.-R9{"g䜾rpL?yvJ_S`~l#`7Y c~C5k}W7rZoM}irg S==<$wA<̚ԘaO,i1p>C |U"9f\xw.3.3=:,wKVk[Rڇ¾nLhƊ1bߚs̵p!}9fH^1#>yzxױ7sAwUg3׵rE~fE\#1oڳw §<&xfVJmS̅YFoV,۾'of^+%evp̨Crҹ \"-$ W=9̘؏8gZgr%5s8o NW#C'9x+.w>0 /uƭӼ ೜ZԤ]?X%z̵1sɠidz]0L$4Bu 9N>rt #B܁ɡE+!U0:R担.pnzA{G`a]9Fr~ aG߀xw1zͷұ"DO‡:GNEs+Ǽs?ksƥc/~;c^S'^dۅzX5w?r}#'s۸T!nM1gL5Ղ{Uknh#/|xa.֞M,&-!jgj>[c]v9 pE&MOAπR!tuUp 5yf,L|?j]y79|[ V=}NoYL&x'Z+O9Cwt7m]O>8=pɸ1oo(O.*LJY#46qҐ L<uZ0 S>P|j=ճ- ŭ[\+(ρ5 =֒#됋|e4-mDMG{ɳt_o=a[oy=.(ND|P,PżGL#QsԹ:~XNǶ&+m*.ٚq)#Ⴑxܘ#18ޣzOtyV!|s;Vs&Ow?/#KY|)j3f/|{~nsg1DZ}zЙ^8gvnŇI#ٝgu7Z< B'߀߅[LOGՙϣ vl OE;hQk,zNMr:5ͤOPUNLJG?>-9>c4 V|dc="ox}O)3sa}m7T5Dp#kƌCń{|q514G6 _UG[9ؚiK_OsZ~%,K?gwabȚx"fvA4 ߿೾~ǜ;\I[̐<_\L9  ij5;v3wYc# FF|1^jrMK9|8sVs/C؏5_wW:cҽoNx}rDVNV|V+bK|3f5;4>\A7N}Y{<\)fO;C^y WzjiIDj Ys&;Sw}bzg|nMyXolϘ-x!#"5F=F&m%:4ZdI]ʒ/j4`f>fnz.X`0U=$b.602nY3gdx}l$ª3BC.[&9 PCLq81W_%s]KRCdi+Nnmo1\z=YnH߇ux-~sJgc!/oba\<>'maM c>%h ?@^3]'}eP{O;-w8NWxx"& ϼgxдOK9_s7aװfT/M37 \"lfX$<ǿ]'ppeUzuB^u7-c(▞צޛ%{nnڵ:׈@qA0{7 saq 8=[7mp~7qMc{^~c?̯K\N&8x+Ӭ Q;+Kbr7qVx=%gbI\R9DgbGbB\tʿ!|om2I?bV1>aiދW+X@b=zJ95Zٰ;~^eSXf<|z?O> <{٪\_ih|Y=X<'mIV$޹F \4F3A~:h~a.ǿ4S/Ήȝ"< 9gP;kfuQV%A>?umBqhҶ=2gU ]_XyQqTSaΨ33b}^ IWNrmIEL= f}`I 0O^Yv=x >2Ւ+71/9\ /f ƹJg)ᯏ'.G|WM_oyFe׼w 081~}3"?uV]/f3,Lμ00œ65Hwqi\}~)-"?>k繆D,`4+ĨS 7Y2gWrOSZN3e <)c{zcBc9g |'3_PfeX;}ĵd\r'{ϨJyuƞ555cYKoW-WK׶8#'B;~g*'@]m4f#e_r XsHs ҽ/k;7Gw\pV$߹Y})/a9Iڬǹ5uڒyK+ \ wJ~a9!-#o1b;o55{Co8M9lxvKFZ~Psp[P#cE=\\ZQ;y3WP;t~ ^ź1oxvsf߂ԞV [x6X#obȳ^XK仴|K:j!8 a=9cq1h<[zf~9g}E/r!qX_M!Rl̂g.b승j|/]oت2\W/9xthFm׵й}L~P{/h4|rgיּ*#󤵯:iM<3\;v|.<{e/bQZ6kgk.2!'瞓䞡8b'/3oSa&ФwGDP3n ]>Tdžww Uz8u"-p?gI$YOM.Kia-8g;Y8ܲ&_Mpԛxc[Ȧt?|=ῖ=7z=I`iqG1>MZ*aa([ω;绶/ŚO牣3iI޲/qK1jdбrgL/s_77j;.L嫜cx!ka}{S.XBVWF|oLsk);/VizvO(=Fy[Q/6.R;z,t&DŽSGtx/M=UsME*|לK]}LB[_ئb"tWK֓3ǚC"ȱ371gϴ/ K_{oQSef"펼KUc/ GB1wŽz1s7,~y M}.;6YOWq> 66柪iow1kN QQ! }^+4uf~Vȿ`Nyx;W7ȅq<Ե9~7m3j{4-iZu&))U^=c |L1U}E72ZG7%:vPq!iqomÍoM>qQ~2y|յf58"Tw&BW#XMxZE|[@\okqsbf#nO sOM\I}غf%J scGy:,Y( t#3zxfቲ>=z>'vt'ȧ:?m:7Ǡ3rM~f&.N#J| ϝosfVTo?rEoWn'&zoT?}t >w>?<6Ky4?~EyL xl.y~ԳݢOלŽxMIxgѻ1nĚUz,&L 4W9?9* saW%qu]=Y\{6~M4WSϦ,3/\!zgm\S]:ط:=n8莾kߞ`=ב|a]Qu'~n љE+tgգ7w@}g!o}Ҿe xA{s|رog.qdpEWV}Fb+ a /r] "̤l'~qτy*68cKV_̐sj$i~!^jGBSw&LZ5u:__'|wXrWP0jOA~lT#@cW{ ~#9tMC[;֞1Ǹt=oxOȹ w8|@KDCyc^~40xIL7sn3y+X%;Eذpf෨KW] _ci4JC[%lkpo9& ʼeІsϏ3]F}r[9NY#߳~}a#YT G(v6W g ׿ZB W[/vmE 8f֡y@`g{3BCs71~'?wjiRקY$S3PC }rj9/3T} 2s)G<f9@sL3 L}&ϙ gĴL8 J׎Tk]q/,<  `gp| sy0SVU3k)5>tt랯m*jOj-{\ yMyeH`#<s Ou/#uV7<Y􃈃BoV9ZВ^E܍y§]ȱR3:Z.ٟ>=L[{|]{X75XH`1pf7t~5IXZ0t<M7Β}UZ"a|^=W+b4#ygg\+SՊZbfŜ~cjIW!>smVR?-S9ۚgZ+itB˟利΄WY[13 +NU/"gC_΂Ckl/3v.QnkHqdҮЌ{jucQW9V<uNW~&f{҈ k?i]4OgJm*>b r>z1ԛ[ydo+o a|.򞵉1C}Z :7~T՜[B)wb?L1 x3֢E;<5ڭó9|3 +򓨱MLzzpt}HJrp.~6G|`#Ei_3P¢[8!hzX#>$+<e~067 qq+ 2> K~1L?yMՅkPZ_9>smsO{8<%񩱾\{٘]smsMs 왩o@u5rA~%9Q- 3b>P{d+֦K_}7 q%MsN5=5O~>UNuVAh# }zmSpЃ9;ZUy?5UGȟ|=^ M:M^wj;gD3t|ss4b^d@7C+ ϊ#W|)tQ5񸘡!/eyb4铄~J੥{9Vᜋ;/p>)nYo:C?+ِ@k?̣Qsx#G"gXX78-Ƥ3&iQS_y/m̷ ag'č%7-'Os:PߝNt_|cLGMJoz(Ö'][g\AcɅoek uh&N-CMxnhxL鲅+|-ͳφ虩y!BPZ7ιB% rVs ̀xR0 |MѩcI06N茸%#ҏ̐ͱ))k_?}wź~f=vbҔH=E&=\E4Y Ӏ#g!π=ޗK :l)?Ar{̗ /p*6I>ҝ=vX3/:4mXɏ`QC[cL}UP0nrG͓|ǥ{{uǚ\hIn{S\G>r %2V"®3H-0ёEpHnMw s-sq]5nٳkԟ-raZ߹[1OK8>1~7OsX:&wM_ qЄ$fʘ $FPnB5siNJxt` XK#^c|ӡ>T5q3~q=:}'CŘl={<|;X-zKN'yp?2?\br=[wPeI\mBǹg]bCru8a#z }4FgKק>Z{~3,Y nR++x'E>ɹamo³g.}}8ˤ=-y|ȤIO$OMPNئeM{Tx/[V?0d5-oh9/McvBSy286SC<[mf;?3;ϴW=_?}Gnl9R~ ZA ,} gc΀1C&_xڍE}XBߧFYkS-Z[_y8q|=^^2'f䐎x8&n.nj&A;ǶkxY.g>zo8%chR&kGkke|6oM}y+m;BjS+ Y8bs(ӡF=Hj|nZٗ,ݼ4eO9{F|3שcZtbQ&.{Kڸ'k3]d< |8BR2=7̓_e^{M1*3 u3o1B1v^@|i,<Ɯٮ2>OŜsk5G|g^gcke$tme]C E0 5;=b䱣9z5V4#x  3)}12s,61 yhXԎa&=zs.2.o?n޻_-s},mfՆ\4]WYh¯eN6py=`bם<,੨yЃ`;Qc+y6Teb1=mٿƑ[ Єihf&vxhVުQ#gsW{w֜FC)3pz)}yZse+À,7orٌS t&3-M\^Ah'Vx IG 6;ȹ1q3㥗?=s MT#q;^=NyWC7w13*^S]߾Z';h 4>4Ǫ>>Wϴ]}|wu׉&\\qF 0zBfL3萏} ދ;5Ł U./yyZ:߳xt Wې׌{K[XatϴYRwwk>珮aϞKlA;co#ڼL-Am?u*濻%zCCE]r{~z;-cc i:&ms7n-~UK%'Fy4y 뻏agⱬ&{5sk ~YgEtCAxz:ϯOhc$i̗w5]8q)F  qga[^u؛?qP^Si7Kܒ&ׁ]>K'4߅7k)d[os}m +ѫFEFcPEvng;W };C1n&ݑ__ɹBy}qSz2g{:9k>~bXSO5`ɄеؐZMнxvy6k#z3Ly{>{Y,곜Awt;S?ȋݐ_yַ_S/mnX ƬzIccܱ8kmG﫷>|Խ k7R_f,V81/> b=S95N/ܝV1׮8kb(yY?8>j|Q7Y݂S=7-ЇiSE#=) hklz{׽f,v'ǔ?0 >380UsF.<3dND(_nf[_`E7f?|߳P>!\"ǣ3}iX\]e梂C9:r-Гn3_J/ 1sos90ӑiX3jg+ǎt~ۇ3PGiϻ +m8ŏϘ'JD˩l1&< y֜ke`سxʫ.wDTm O g6L.qS/;l*fGoվ W>zZ3 ?nӘEǠ-ק5FsTG!(8k{42Kbj=YiojNY#֤cW"gM+[̭ oq#sǪ ?5sO+Q_ ,'ѝN}vY1?Sװ1GVgw@?~aiix"leTLPAgD30*!i[x_`?&Ig1 8Lړt \}O/GTʌhWiBse'iZ} 94Jρf^>@?Ө7> 0ޚ}}rmmհ%苊Gjϻ'KCUu(4wS@>i@41ʾ/֢9o!}rgnM|3=>zscԳ+0 MH/!^,ƒvw³|Ʃ +rzU/pSrͣYCǑ*[^^6TG|~Uo^XVgIowU^e|j)ܧȒ8 }輑s_{[ŘO7ס0`D FVsfV^+7數st_rBcΆr1O}C&ngYmj:laԽ}Θ_qϳ8';Z{;sѡ/PXmĉ.X7wn{>;[T+8fJ#^=XuoX q[Sv]wy!'۶wNfޫq=`nX[]8;w=n[iccMIwa9 υ̺9E]14%1{zML7{iG/ws]88?9 | vuߛfK_ݥЂ$GVhXRKkVO>@~l91w*·oMW/NB]sD;"7,}e9ĴzLVGh_۞"[^3K@sM5ykveWV=!1mgE;TlF2/L8loj \mE:c ]k0&๵x_+&S#m7lx[3)7yßfo$7y/П>uM D wxe ͸T쥷(O\t/,fހŀS}aO~pZyO:u~%s-LWg=͟]v͚H+rSU&uÌkg ϟƌ4#M 8CƹL8W:6<.qIi_X~(1rq9jW9~GG=<7Io64Ghnjku?\?%Q"8T快~ ̦4#DSӌz2ߤ=DC3^\09fwJޗ-7?haŁc{q=׍}ϟ!9fJp;3CI1#~sMܬi193Q,f5M;4^ov;$}[U N,rn(bCiԝD9^"" _ǭۇC^JįWZGbu+qʞSg7(zۑ,*-]14f7/n Xx>SѦ/P3/)k׍!GTw$->_UEu$M\U<[va9m?;/{~:,AmŎ>kay30E&n|5iol>O<͖*'N'isI:YslYnA:^~veܿT+`ǿ c{KwpEhGK#D=I,t .Wg߆XkqL<[s0\~ᙷw( FL<4P|S?|긃|neIJ;񵚁A:W w}w\u3 FoOj4!s{Sⴿs! ^K#=4 3ΰӭ. 큿݌?L=bf40.}̤=s >显QܾI϶UhΰKX&j4qsy\{`Ғ.3A_YS wG:d#4wtOO<{`/|RL}^XQf6b6b9G&[{:{p<҆s]L|g*o36:'*p ĥRXs6|z}-HpG3~: Ɖ6 -}[h ai?0DnFD?5T}L껮7G#G9vV~6 ˵i~,r3 [i؁M>w:N_rן}CI50rw0y mw_,S{(< .٘VhnFl5MpM"V^~Y)|1n;%YNZ𳠩xk sLW SO0A ̸L?8ЈSHmS}Ƴ/~vMxA}y#gbcs^fqUzE>7~b_מKp3qzpG2_g_\5e;ϓNВ5kso-? y93u*G 2 sرiWF{|F쓞_NM{ 0 mb_V|m12F8s_EM^ɉ(^ڔ[=+M>-=aOԕ10WW R12h!g;_v>B=W~/#?_ȇ|OVg3/bkn񹞻!. \lb?] hM5 aohN~5q7zI7svwI2ؤ gbj~^gjwgюJ./|xxVͦ.}]q62kPDq}č\9a=L Աt߃X>6$GL) fMI3xcCo>_7Wj#lUΣM; 6&=~aTkcك?k^` z8)9=˔/Gp=p̋蜯+-z Y!Г޷' x-Jr!LbAW#˚ ֬}C߶X79\{'֎8*ykb8c5mŔnza+{oMr]mʁ MX)_vac|= |v7v(bFd;g:n,^g{[KwM8/wmд}ض;)^IHC[q]E|xqOޑ' M5'_CN@mz̑ +.X/Io1i4.3đ -ja`=b l>o{CmrX3ߔ_TrkPZ$+Bb'#WĠUL;$a^1]vb3Zp3ℿߤq>ҢnVxhGoʞU~uf⠣?o^쫙v\bāKVҩc=\qJ96zL|p^7M{ .K}m ~/[~,WpwdsR3'Үܮ J,fHsPodLm]uK?_8#1}3Yqn潂C~8zuz:Vꉏ́0A<&ݾ:[pu_v̤ΜQN'?C(L>|or_ORz?l8gO'3l]Z1PbEVWm>E/Is|R@[mwCT,4 ޤ2tױ-j݁Z?'9;ԂL_\ Apo9æ66νOfMC]ߋys^." Þ w+)w)5mw8繩-ϸm"|{F|/3ӎ͊|E[1! ^o>_#FMk_:| IEu{+@şy|ғ5v,k֓ pK&l xft)s` =g+nv1H ζ|G5zg)]z#]׶q<_1s)z(mܮi]pFڞv˵u-e[-皟,0A#n]ĕTO!zC { Ӝ3]fU3rY1dtI{ƽ)L03SS 3>g?ہ+u 941î~Vy`UЇ+6=~!lv4|S< KkAy`G)}^78| /.}Vހ|c=Ϯ>-i{Nlc@ü"d˱ r)='mϹx^;o9| ]?_/3ʻyiFEw򷊸Sw&OH<:1^yXb=׉tkР50cU@i#/95q_} c[,S+[ MRg,] p1?nlTZ{kA\,%0a;5o =[[T3OS͋>q^r 萣wv_o!FXPzn7zn&;7n KfZ䘧ϰ۷&l`Qސx"g{w!jp:Q |}1pGyB/G%۵cXh *K%_2kϘD9kj-[z׷zMTO6n_[AYlorbϼp-ˉԴ|a_g6>G`}Z6+ôc~vIZ~193%]Lz@ه1<Y2= ۯXsM?if\WBq 7m5s԰ 2,F~MN qKvȅh9eHMѡsZ;OMxocQzZa:g&j8} 'ZO4%DoƿM8WZOρyͻh-H;g_ی97q_]XВI~ϳiZ< ia^}'Gc>ۆmêf`!Hu=vߚtRߧ?ϰ]/g:1_s uARs `c>q>V>Ϻ yo}0b3v]y90 / vFI+fszf5{PQ\vsT2YU| _n/^/~ y4kGLyY:/rScjlAH>T}߳j\){̽ւjMGK37ΐ>uQog+bN zOy| 5N|Ɣ&kv<~^ZyP@[81b90 򹢻Pנ,|rhx:Tj7zFC@p#$rioO3򔿷~\ض]'j0彻ŀu--YÉ-|-YšwIGsŚ>>_w^a!'W&nDK! ٌag=_<߉DŽZQ wMh[Jv7b94Yocnj.}>8vďc_i'à,=ǟv]= jbwNלOqiύF~K̷!mafgxk6FY#ݏ;EWsxV_4:$Nq#fhاQroM l۹c|ґCz|S*;GUh߂)1)vY|czn3 yvEX6aak0/|B7H%S}!?[{16qXx?甮dY+ a\7@zfylߗQ)υ۫}p5fgϘmٰGUen ^b{;gR9`MU+ccZoP`jq! oi[î|Fzo9nަjv3r=Ms(2G8E+q{]On-B#ʋU_ 3X Ӣ]T>?v`ҴOQh09Ѝ>ULqM~x_w{Du^-0YCc I0fTYhi%/V8l%k*P373E{{adƠD<s1:/th6Ը։ݛ[Y:sqNmNDY=y4g +<所sj=x|1;0_մSX3,^lmW:yn{G{v^!T_<ȶ3xj҅3 >M-X̠N֮XĂ9t3}sƱ٢ Goܳa[1츰*ħ-WYO>M36ʘ;r [w</$^3zҦb}Yu)F{/\6Ƅqm|.N<=#ambЏYۊ{+ڹ-,k;ЎoifYPp$|jVƎ3b?EB;翘@߃akW\RK5ψvjs{9Va`gnX9e{_sI 9iz'/r%'N,jK=Ma/;Y9CZ\Su'zyٖҷ^rXJ~s{]Z [or/W^*xĴ6xk|cm=aw;84H\X;fq泉QX8[#rU9=]L^h~6koĴI1i6M ZxN|N>x}.LS9<9v1BKbnt8Ry>3ȳ85C~;0 ]«/;qwh?gZE=e5UڂE~Һn]W&sb3iɤ} }98fނv.co \pplE"Oo0]d\򎋫} 'I)bGr2f1ꌊNVߌP}؃4f..mW1Ѥy]Ҷy7ykAOvkwS^<&B_Y:0Q!:vnD/Ϝ{;_]u3.z)jvvC b|} I* ֽm~Љ~1b]\Bӂ_33:rF,7vUV|Ϭ xin`9ځ/AGiiV )vL]^ Ő}_z;kM^fطbpf~$sŀ3[? mK ?4m1|״_qŏlrGk=F+k+:w@xW-W+y!"`uXOv13`<}ώ灘9b rM^YK|~~ϿgMMfqW7.j=Ӭܘ連ya#y)jKs^zlA6p&^v{J \|ŁX؛v^d]68#ߙ[p"-_g&Na5u\Mx.^sO7Siٿ] ;1{З,k^1~W=SLpsSrj%oAgB^̱mŎtV{o \HfhQУ A3з}3/ f5SDΜ(5xj‹!< b kaC%&\k,7ݪ]5s!ۉ4uK_ 9E\NݩSS}p+ɻ?]mң]𞆌fL6v/"C=S]_CƲ~#?Cln؋Glu3b聅6U{`ڵ<>.mJF̓Qv1jمin~=\?f\[apCs% ie'?Vrc`*F}C˟SqZ, ^_k1;{/ʸ*d6Wj$&[)n1),{M|NvIĤgrd{66שgeq`QG|>Qw.[a#[bcc_G_1%~ߺM\}?~>ĝLG.1ag%k9q琛^ ;28'~kr 7tk/}m ~3K֙{'ZV{Q Z0=x#i+ ]qlǾ܃/k`2|8o&rw~VؚzyNºO+n2iw-4Aъ_lԻ[|°o)v{̳zeɝYE0O8{S}ȒE Bt8 Xe}>TB.֥+v-굉Kb3ӆYZm oŞvs>3oOv=7&[~#Ӭ=īKO8~1`|ɟ'.\l±8NNo=|)݋/&c?dgF4o67%@˻;&]c|ŽŬh[a5ȭZKϸyj&C;HM.nǻ6[ 6{]J 0 X+Ǵȅ9=OUXx%ks=CvZdaqzyHWE>Ǽ>}^q]&o&E}Or-Vw vۿT1OGx2K [>L;-ni^8u?ʗe׆ozu:edi ;Ӽ0 N |nA^g[x߇xfNHr i LW|z/kOghu2~5f)ܙtk H>|@<;L悍v-rɱ}yXzZ[n={4j%c }{ rcs4던Cy‚Lzy2L)ٗ ۘf'9Cjoo.;tcFz z3W9ũWp!s|Q5{yMqLŵu󡃁|‰w܃'+/7~Gaor?>@uVzh#/N\/݉8|3\Sk ?n/:NTč N w&pdy>h,t5l&AİwhZ'C30mXs(.\:}?]hNTὟHy-k+?:/Ko<>W^R„8urLӶ)O? ?L5 >^JΘo᧴KuB…Su:h6s a 2pϞ&)]vs8#k ׽hڑ^oQ07yY6Z;1Si+>5j  jFI?sJ"ٚ\~9/wbki^妪+BZfY᜾{NTwM& sXr9 -jiivLwcI_~~V|m>4݇>8g9K B3b&| 佭Y39ۘNoq}vOr.X#5 L$=`fV<&M{#ntwtLljb+ޛ0*槿|P7CKX<.?2'k 쉟_g&/|-09U>- !51dr-|xfpŻw19k}N~W'߸Üy~s4PtCBh\{63̅sCz1+#;{:Xwѧ>bnԄyv ͉:_}ۚy ēZ 5nZdl}3_HrQ >>Z\~v 3h4E~#r_r:j3}i_- CrhB9żw͗&x~{*۬Y92i ɟlvB\|v/xЁ@^@gѓ;L7qi})}GGψc\ӟ +/F=:f^q?:nnYe9uaWKFNu$WϛFr7o8m㼛.ru}ޱz0 { N}u¼sBS-nn{?V - pĹ?Ą| =Ӓ{>^NK7\Иnt{lkb놕y{šrw7 `ants-1.9.2+svn680.dfsg/Examples/Data/phantomAwmgm.jpg000066400000000000000000000044151147325206600222540ustar00rootroot00000000000000JFIFC     _f =" C?`/}>'6wE=O9x8{W  A Zg ?DQ# 0@6̽"8W"^5dQB$ v¯e4|>&U&-pC됨W3y' rjuZ8w]ǽHf5S-V!+,BdVK+.T*՘mW>gORm,д 1DvNɏ6)TANE(2 Jh ,PO[9U]i_A  !1 "AQaq#2BR456@03u?{qčù%[x)Dj:ȷ='\t ?Ĺ\T(f rv``2Ƅ $5Һʈ17 |4Iǖg$PЖgsE>>Μ6KBl_0S_0P+.(`w%蔇]a$eD,fܔLO.sDkP +9q_,0؀RHRHXw5 $*^vݨ|/?n_H*qhڅtW?xM>JOl v?z%p.3ItEZ8C49iץ$O*,6l4Þ8Uzxb&[~¨Xz|DB6׸*QZrE"wnУRe{\|x!4(f࢈Ԓѷb8bRY\B}32B(KU#䍡 ȅ=". Mv.֒\XV"[LnSMzQɸ!!$\Inv][-Zu@frF? !}ٸbO9F;ܾҲ~lg o }K2:"'=PQ;;d1rE^nD>~KOe\r%.."\e\hx[ts"|S[i G#>k}$!1A Qa0q@?!}W8)2ΰ!BY,KiEzGBБLP#om -5B1ϻ])@K۶bxxJf!1qcU|JI `Ƅ Br+ɡ!0x,`@.4#0u\k~l*gVB;bc!%!PfFL*A*%JRfP'pʣ`eL盝bFBXc"'2oLLZ2q]#d@^8 _͋ DBp08#P l&G( " s<,sYlͼFU0Z6q YkN!kVӊDPvZ R)G"GGZ"f@ˋi1JR0 -t઴%+]\x`錋R<bUUdՎXfhNLTmo%X<^$ ZY x6u$z Q<\" (7]TnSRj$"`aPbCxR8 ¾(1A \hL5^, !΢N#G'9Iv_/ants-1.9.2+svn680.dfsg/Examples/Data/phantomBwmgm.jpg000066400000000000000000000047251147325206600222610ustar00rootroot00000000000000JFIFC     _f +xXn&0PNCo39@Bw|AB\A9$&~؅Wϕn?d.U^џd'Az# 60@&>^ }Ɋ^enJSQXv^Cbur!`/_jjUH7%{g 'd5]NNF 9i$ hC N?+q #Z3)O6aEy3o2|U/09Ja~Nd$XT.^AW0q%S]T&YeSTid.$ `:͙abLRzceda\As jRo?J !1AQa "#Bq26u$045@br3RST?q޶-QJ"H\ 6̿OXsJFvLjo;!`tXjZ֩! $^u>+&+2-7qM2Ojb~lqDe;R/ϘSw(qtg ʮ3})IU+:ƃׯ_gޭl H:NTVL=V9Wc7(UJIR=tZPm+"y 6QDA f͔r?Pf=m Bd$H4zRe>crhTR:kK "s(uC&Mz"C~cru- iK}Ћ&r:n*Dwbޫa\,YMnɕMiX=rv H)=ю3pۇM'S8эҵf]D [?nI}շQoc{NP5Ub20)\y :vp^DK QQۀH:-4Ӏ=~q aIW ;iYx\Y 'p)71ˆ*(n_M镩lS-nN|GO j#ed : kTdBw>IIBOҜ4fIR2|%#f~}) }8&LB6q9cGH@Ru0*F|،vS6s٧˞l@DR9kʅPUTcsP蠌O2mĐ%!1A Qa0q@?! ef i2M;_"ӕk-Ol3IUċQA9GE<.dib1q߁*zYb{4yvd}gZHQ$Qm9Az&Q< wWʲ驦Y}t}xhHL"8OJdS138?ܬzLG%GCnjٴ5dl\(r~ѷ}A+&MK:#FwCOPL]XT;]s`z鯯 ERz=q j=CM+OC>Zً,tS 83qBa{/ok=lA(T];;3"LgH8*IɏPӷi`eqo8TQI*UӠ@@`M AW+E U|[mn>| 3wImmlx9a]R}A@#!1A 0@Qaq?[h`0'G4& N吶cv -)VR3?#ʀU@䘅% }"fmn>̡kf^0y <@64zZ* U$Zh%}r3H;}?u]U]&y5k˶-"y"${Ue0@-Qq?o";͇" ;ćnw=aΘSL8Mhj 3A, M@3^~A@5p=>ٴ5dm;;s݌^/b.d3e5:oAG|6e,= D^V&T-P,vhq:hg㕢Κn/0p^58G+x ԕTeo(R0Ѡ^z2ehDpfGA@x !1 Aa0@Q?(wBpĠq) 2E*/ˁS8bTzrraȭY`\F@0p!°j <=j T0& wxP\Uv]ǺTt}pLI*D&,$QN±8ZW3bw˴* JJ5d;=1qS〇8 /ŕqgEGtXx% [Dpm|| U@"U %THi5!b(0P@jÌ0k)80F}Y:|?6HCj_eP9F$x} T4&8D84BUuH*8N!n@*t"yO4"jyPm9YCIBg\^q .UuSІPT sMDYVʢ"y>bcsS8:1"D&P$д'ants-1.9.2+svn680.dfsg/Examples/Data/phantomDwmgm.jpg000066400000000000000000000047631147325206600222650ustar00rootroot00000000000000JFIFC     _f 1'}t g8aݤf+3l ?:[H$:wë@-ף/OC!{I;@7nW:}XfL<`" 6@00笵ݩ %kI~i=be u 5TO$8r!TfUl]KJ*zGMSlv`evR7HӗM%}>XGEܠҦ911Ka}9b zi;Pymc w]ߔ*ﭛP}O@GHY=N#{XIiзj{ֺ݅*ԫMYWrWspCI;!|lA !1Qa "Aq#254@Rbu036?aXDG#ut[.!U"\)'Ƈa¬|>b(x\gգMbSb:Sj,GpihxK5*ji3-EZ#mr}} n]taBM#guMഇ8[F]]iOA OBLc moFc5y/ j2(I%9)͖Et˄x{d2L鮛?ݓkZwyTDZmxxg\NI}>i&Mdj8<1u b_tں49wP{|UT &{f0kG쎐HI<;M&0NbߘE\ly2Dt@=kA_ W &A7Ne&^WX8'\!^^^07mNBFa1CzNdem_ιޕG/K$]r!ΑʗARBjU_3=.wt{_DQ4(xJsE GHL"t|cPr`3.0e͍An)No(|`s&^,l% :j^nUL卭u A\Lo'}z{"L AD@#!1A 0@qQa?q\L!K:XUYpApAI2/%Y(xGb H-SPD9Ǹ@DEPNp3P&EĽ% 4AD(l+TNbiC?a\ bT=EJ U@4T@˗l*H@%hݔp TǼAOdHj4 tC¥PQE-ZC7)R'TtԽ80@)_AӒa=L(#?#(ĆHpTZk얼nyu'[?Tqy\A6yZk")uB 4xf kR(Q?#RbG9w!ׅ(] g1ל!kWL^jf7:p5V/bwt'GiՀF @ants-1.9.2+svn680.dfsg/Examples/Data/phantomEwmgm.jpg000066400000000000000000000035661147325206600222660ustar00rootroot00000000000000JFIFC     _f {&[+*~}7͐'7 ?8w0:tzgjH%=aWD탇tad % 6@0"er}+iH߈Px"mZvqiͩ-ne[3mq{|(F-I ny>)irBNw [c{rESN(˲l"ƋYY Xz7D|}SV~mIYܸ},śc+"i8n׬tYC !1 AQaq"#023@Rbu$4BTcr?dfe@J #Rv7qC,H8OGD@G2#cKK\2}dfe@J 45F 8<UT$^ Z=qw翅p _prT^OIs[&>J"'\3;DeI?|:Kux0L1uyMW W/Sۇuu U* $Ò-l迒ctlׇAûJxBsۄ&=HzΒ7S-H+F!s׎ʱ@г~s Ц:vr0K2SgsX!"`) yBY)R#A +ݤxC;7ߚ1IҝWN\S:";@! :Ia*,ՊiX~q@ITl0 .7 Ѭm:T-~d$f"(t'n_*c]O&`~B#!1 0A@Qaq?YT3U8-*B1LjKYR;P9B!w"V,<$B IR%P X'M}\>:Ͼ^T:b' 8)O+~_Nc 6uX!R3 wzmV"/U, S<,u.BRT"eJ:MLe&='E**-ÉKG˗d""@vcv/2!a/Z^ʉX?"H1ٹ+6 q|IȐeN+dyZ y!/ˌl܉ants-1.9.2+svn680.dfsg/Examples/Data/phantomFwmgm.jpg000066400000000000000000000042071147325206600222600ustar00rootroot00000000000000JFIFC     _f I=Ã1pDN}xNBtkt>k0|Ӏ4 NSXA{o ! 5@E,d7pR)^ Dt=2>UKNU\@~^Ac/?BtUD)~{i./uTz(ݵ%/ڤU%kk"G=Dq<EJU>cW=Kgbs~訽gm'W2XxBw}`U"ͬ>tN ey{6hl_4jݫ@  !1 AQ"#2Ba3Rq$067@bu?Xa-kUw[i#B7a)۞V-n-(DT^˒;{/0v|G-~"h$Wg~.W4fȌ=ٯPy8 t1}?9궟#ǸY15H擆ۉW+3ydFh>Z#.dUԭPe50 /^u^F٥2 qJng\l`m놫_QɄ!-2jeQ Qx/Ҿ{ep'oMOa҄!4B(ݨwo4a 8rd)04T'´7[N 0 =[G/:RW!ĀN7mC\&p6㑬^~U 'aη&Ha&". \R̽EW<5=VO84 򯐩y>߲$GPrEDͅ3a(Bxj{Dɨ #`o4$]/pA0A#@!1 A0Q@a? *UU BM+FQ"Xa2a#'MNhse@D=pM@ +@Hvc 6;D ;gGCHB@'dhLU+ .]PD P a$֐^8&M`Pp?#B,R/ KR.0̔M _UD>\X^dgmcDN".+IFΊ&!MdG*NisNZJCa܉B@/T{uDYH${> )ŸtB6D8v8<*U_ЎP1`=zh`pGants-1.9.2+svn680.dfsg/Examples/Data/phantomGwmgm.jpg000066400000000000000000000040651147325206600222630ustar00rootroot00000000000000JFIFC     _f ~1%cKqwɅa!곒N9}Vr@#K>05_`M n8nv>?X te<# 05@P96")X k76hLBໝhPRX8+@Vb*P6_!3u:kPFXʶlCt>W)sFeQ Ё 2;ED(S#J_2բOHMF_+rӪ84 B1ګU6*y{^Ϟ=?C !1 AQa"2q#6BR045@DPru?e:J[թ|%ro8<,j% wd,Mo=T(qe\,[B)%֚7Ǫ+\pp.KcUhMN=${laiTZY|Nꨄ'm KiNDMě\@+E\V[{QS!JPGf>B- RV@=xk3 \PЊ"3f[=.,CD)rzHهHmĒzq:ܝHmF) <1han n8VwTJ"Or!*H5erra0S:jۭs 捫fGeLz[;qa4"qNCO霼O-JZb4'ofiaI.FZ$|3veJsxt=΃$;;zݫɁ4 u+Boy`y K~|~F}>0" @56]ފK8ZRIвX[S-zCj7G4l5LY"âf`k evCnյ T 6:^*gtQ*HJS[U∠.D9]HJz͠-Ҵ$@|_Is+kR;#S)D]o]oQ,*F\Y)Jd o- P5'&ۓu8Vt!:ɻjU-Py#^@ ! 1Q"#2AaqBR03@u$456?껞|Z4HL[n^kIF{(1yPR r7:KKT"Jbc +fI߷6im@S-t{Aҁ߾6vԴp`c8O)n8i-. Ԫ26oun.?'[x1a1:_SIq=y]J)Dj]I_Hn-iX@M/ΪZBV;%4\dkț;y3 nݬi6NUI>G )RBСڮ T I08,6M363. ubf@O_{\ҸV*18jx0IF nKx65#0s9kO%+ tC>˻/JuT VGi}!2}j/c !:}R}bU-kjjӒdA>춍B-j AmTJc,D&6ߜquv:{ '@EV-#R6w})oidʲd2gWUER.'KGeh9CP{tK[ Kv-4 ;i#$Zo{ tePb$$d>$!1A Qqa0@?!Sk:\9A1|)#d1+&(U:cz٦ 'P` ʪ% tPBHcnxHNcLcE$Av2)"fUpVYx}$LsYzf[M_Δ1DΣӵ03%ڂ!H@ UAPZfHDVVw.*sVGR+ wTdKEC< N] U$Uюa؞u9 `+s@ޅ7@BƇ1TY';DfF&*sGX#PO@h>MȍB}=֙Mr짶q{x>  !1 AQa"2RBqu3@#$7T?cVI%8zo?mw#. ޖ]Ұ+P Q=[il05Ҋ'f]z3KȌ;CH4ӑ9ҞxO(&nx]r7X-+3Sm'O:Mu5'|6ԗB,HHydjZ֩! $R))O "1((ug#@ gm+B%B`ցu E&k©=Sfz0Avm6̪ q m.e-oRd.#48 gVÄzhWZ)NSt&!r5 NP\m=;@=RJyM)-WZ,bF-$<aҴ-2Z&c' UiB7YAxҭED9Wo-/é%&sQz]oRs%auE}VmPّ=4%ʒ؍+sf8oVkTp)D !S>cpJiJ A\k8=՞ㅹm-4" wYOCGj!NL>x%e=1Q-z:@6au¶dAMJTz}kE9hh+ghqf꼔ToE8#=6nАDP';rG^?\w];_V]&~tpx'{:C(pTր*"0=>D 7OJ"u@ӓBLrv!vS􅳁[ <$='e*;Kf2xΐH;1t7>LIbQ1`(D|ca~ @ #!1 AQ0q@?wFՉ5SbT, Nw'`=}o2*WQUa)dH9^C ~4ʃI-@x.5 *J!YT%eX"t{?R$ "GYSӶwclein҇=}M=%f=y=Wi2t#԰E@+;y0c{Pm9iAxLev ?F4iSC5T /FPRg;WF'mӶO}iۦR_{v=oԷ=KgnSE}ۢmQy궨gm3U}۪mT|/>kOFlsS}۫mV~6o?c{՗OnmV߾noQпV7Zu[u[u[ukuku ku 'ߪߪߪߪ__ߪߪߪ_ߪߪ˨_x򵺖Pߪ۩_߫+߫Kߪ[_kߪ{_ߪj_ߪj_>T[T7?/~My.nnkʿ>zʟzFVG{}F6`ants-1.9.2+svn680.dfsg/Examples/Data/r16priors.nii.gz000066400000000000000000000060321147325206600220770ustar00rootroot00000000000000y@)~Oy!m<-)\]`CI^oײD$`B?}nM]y_?~#W&=ɾq_v  7佽/;ٝ#v9;Q#-sD ><Min}B W9QU\D%We0?ƄJ>z`X0]CY,: 2m1/s5zg{H4i/zlk`mYi x^ZH?/A*U+2|9lu&Ǎmi9IY=uorhX VvNkL-3{If[Gz̳&뉀4` yҜ4lVxrM(Ʊn/u>0NS/Gc_Qa/ hؾ_7-Nvm._ey [un۔ef WLo--=#rvI8mlJ=?ց9ߪG{1z߷8,FY5[y}k z)M|1_oMցʖQri=>^?NDz7qlѣ~L="e5侻/rRGvs ϥGO,@?%}nfT~ّY+̴͏[{i0Ew>6hom1_-pۏmo]-o@nu{-Xoeww!gqMrK]Oy~г e}ٿ?zzHq5cs3o:/}/ ~Ӿv7 3cl+ןy2c?#F;S~WI?'EjPN,wkͨE4rzʴ+ڸ 3s<9K6jAk܇żk" ixo طiFQY#:ϡpE6`ߊG\s9#޿`e({ԁ<#1oU0֘ϿDҿ_5{e%_%}| '--z0k3r]Sh]^ׯ>iɟ_ov7E>"ڌs?%r)NOWRijĵF4xm6˽={l-{^=0#[AXlle--7mߛ VׇSO=rOkvv@ X{W3@ly X"fu[sx<Е#}\3@K 2E}?l@oiٷ[uάRǀڻ?ru~v@6ſek}5c=|m/ ""\/mi>D@N.V?+dqm@>:;>iO8 qT2,mk1}P^#4ʤU_oÓ[6v9r%dꑝ4>Sr?-^Gku(^0?iٗ)Gkxצ[s@XoGo Ok}x,7D_=Z#/c\j=fڿy=ͱn "{N`<[# &ԌJLfs#?XxҘ_5auud麲!mMhk"@Gn+}yrYwoAv?/ _G6/}._x2Ͼ6 o֯/Aǁs1_K[z_Լ gLׄ}g:ACo8|3K?{UΊiՒl3gm`ĿUccۏGmz_k,j_m=Ě*k?1-W^mϡ6Ғk>GypFK|yW}8/ԭZWF@(olЋWD@>.KύZ$kKlZ+-ڧ?˙#}歸7v# ~Ͼ {"V~'Rȱg 3ٶ}T)tD9XQ^c zk-ݗOeIBO:|1_6V\czڳ`jU@Zz{x>NXe_[,S}=WH} un߲ƶre`\^^ז?kVϾ'Hm/sK#^OgʈxKo9^^kc_^6ox-r+#i#[_G<3+(=$zf{_)y7wBHyw?=9<`ants-1.9.2+svn680.dfsg/Examples/Data/r16roth.nii.gz000066400000000000000000102227611147325206600215470ustar00rootroot00000000000000XSo&zH HHh ,($mw+v X)] ׳=g3{{w]\`}HS<_w~-qLߓU‹qT¨OϼyO޳?bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bX,bknom~;׎h|=88Ho}|,M89H3:L ;3$OTUU=i\cQT{ }YCo04񗷿熵e?7_ bm_t10/,kU \_';Bt0#R iֻ$9x^?Vѓnц;W)e#=4LB X6ܹZG8cޅǍ* 2XiMVus/^8qcyύ:3yݨIun9UԦ1B6.O~Sfbh0niۓ/pzM,'BʭQhj$;~B5aƊMjN5 #iC"t)^+)AuM˻x8u4an%APtyI:ñ}T_B_bǑd淰PZeSk<;B]6h3d+Jܔ ھb.EPpK_'ٷ2 i=6ù^"s39h*ؒbޫ6cpjy~n`/T^A=)kMz*hv3liJ%cT~,>]*m;>Ǿb Fl벱|D? L't g /0&t_X U&*]'"8ډp ՒZ_ACWVɮ)۶Cu_"t[זR\[vx7SfB"u6IDiʨGs\PpV"J9`HrWH'qO(,-;AC [4Y.LKrV-E(ȯMVB EerOY"H{> [bu-9X%4PC̰VQUk.g"\hzݴ3Ӥ%gWм \0#BRzR6L>tJ{ S*l6WnqþV3 6P4N)1 ugKEڹGOmB;c)ղ1\|]OI=kh:3QZ[I1}]>y7HsxsQeZ2(e ؐ+AU'xڃs /UjbX.fU [mdE*ïs3J4wR;pV51MS,p:}qe j8} >l0 +}Lacvw:M[E1 y`o>oIѡ ]A+yӬs0ov9]k誁q<Yy§ʰU6>^(Ġ)9wm +ChO'^ǃ|sbZ:w{ qRGp_,=RJ6#O<ֽ *%lZHu;* ;`zw&.Ȥܾ\"m6J wHѥGj ;FW7tdMy0Alq=D 8 EK4v/7jv20+?ݱ~Mg_jfݗm%t=:d+<&FFm13 ׵yA=C azYkaXq|1v03CT =_AfW/F H<SM}{`O>nXW=#5_ƱH34- Jݳi|OPY˾\$O"ڟt?ӸإQCV.bLꊩb-Q%"ER !@~%+H>3mJc$Q)F~"SZcpg#:O1~}6d6:ϵ=t:="l 'CŇi{Kq 1ZYvJ|X{2jAufӜ1:[[/%mqGͱwJbf/MלJJK|$ 3g* mlq%gOZWKPhU)uʧr9c7Hi:_K G: Uհ 7Hgh`ZQtO?w,{Նe !3(z~muL^%ݰkY} һwiIu},+8o /7#s /;",Bj74®W#1G)#<]0{B(x 077h.앩di~DQ Ӭ4QDY;:|6wEXok SDs fhUA)DMnY`;g<=G< A/Z 7i1BN-*%ģ$C:bX5@Zρ@_BhMD65M~Y?˸I׊ŁBC*LLt:3&'El7=, e% ɯX!=,jTCx8IWx`^Oל(ʡZD{)0v#q?/ vû{n!ߥU/Fg;Lix"Js`)y_&X79Σ?/ m1*!mu;H^wݱ[." }>j3RYO}TѸ"!qAeg(PDyj_SB[~" q 뚛"=75ܧг]ӌg/w/e;);:\@;{Nȣ ϡ°"ʘQNմEśP U4M%3aAP8cԘ GaWdmq2_9*۩aqm4&=nO30 mQk`i>f8!jzgi)k+t5mdŘ0-Q6z7<3z!c"V39B"<-]3u&NxYY5i0Qn8nR\ o5ǝ:Z:?[DAFFkN_kR(u=lZ@wSLj4zdE Rߵ44v/iL:kSI7u5 ɐ[erwvůrLvT]/bg;D໎*2pͧ9p Y "ʙL}%ҫ-}u9|c8x?IRC3Q9*78\ + \NTز\oEl05| ,Ca-)N`#)r+qhEr̜K.춇u954z.rh(}?lM.52k}]ʝ(^8ZPLs)%SμO1or3d0.UQ;s0ǥo^F kM!IR1z?ҢZ?^c[vHÁzK1mdzʰ3Hi2(ncf|51j?#9N{Ro4cC51>p<]猤 qz=f3ue~OpàER>LTNSmCjZ!~\Ȣ~S:/ uxDZ7b 9U|.-L/O!N?hv^Ƽ ?wovO{Ci* y"&챌#m}RVM=%Vx;pruhP [+Ѧ?ajwg/bh~(af't_i#K== y,0YjkYt[yLk&2EIi@< !BU$~,¹V(l r4X{`QK901͹26+Y&SX?S.ڣ"+&jPKv栣G,iO )49:Ao>f4Ks,t+NN35dZuʯX)+0miM}>=_QNjz!ngJ^Lm5O}^TF`SX~BZs."n!\0SpBP` XNm4*gS;ѫbryHۖ"_htqz8E'>#qAXKj|fnagOMQ񨈺5Gz=q߶8ڇV'ޢX2Opf> 9ir-9gCH9N^KB3t0"nazX6~sz5WUgj$O9L]eM/Glk(1 (̄~`m>M)R[/jm㾀KK >!VYV3Vtk7(}5dWUk:#SfWZL~GT R![w^F'}(цCHߩp4 =K43681q έĘyEUtN.ReSytsh1L&wbT0UpJ7GA%Y5!;~"$ϦVG&]]@JhpP")vzo4UrG9l ׋0 6h2Y]bCOK i+0{i/y\_5p1QQjg*31C:TMY@ =_QQU*켛!Ötp]p\e(0=B(g%ff"l?nQx ׬]"¹s`S!Ԑu=fpУqG-Vfm@H-ע6@H|-7žG:hUb$~B?f(,ģ"))V8Cfx Xbi ( 7kHn X@[">Dd[B} iLt->An)aw%C\Vs"SLS1[R\wu1i_S|tg2'U5 X…*m jTOF zNtzI=[>C/Bi43Hv7Y2ԼnEGn0yNnK~$=P57478 ZxWxS':|c5|Vz[OLbi7J밯ʶp9G=.}\Ib*@z^S˘*hEUK3[Z2ZC߷Pi3*8Bsl샯(lmUލ崼G 5ɐhnB4%\xuaK-M{r2Z,r#  V|Tw)_ szAK^ V[WHVٵnZQn+3>t/!`12- .87 $[WK?dXƔsvhXͤHlwH.2㪰eP%~1yskq2&Ta]-tǠIZ!T6(|j r,>͓[}i˭pf-'+fjꌏ>LNآi fmU /ǻ`Q+̡4S\Yo,B). +8`F7lo.:;V_BYy=uhZ&ZV1'zzn ;cS3gtFG?7~2,Z~YTK|be-Z0{=x3>RG|&Tsio%_tE$dk#O꘡QOW"1tk3"LqѢkGc:Q>ؔǷ2b_@a Xa#DzܺÓӞX0G\=q۬un\7=3w8_5!wfËޮpDk' =a[/XSsWGWshcZ(Fk\f@6#1X%Fv!rsLdU1YM6D^T:Nʤ\lmiۖK>~Z@8Z跻Ƶ3ԟH39-_*)ԙq#[yN(?~1WP5N`\b?4G]T%[NC|D3P`8z`dr!찲9*)p*e2"ӄxNKvyu$)oYE +/C/+:IcRiRzODIkL#N$o*"EH5.HV)?FM%fx0guغ }ݱ_èw{bu/ox]7qT١:="$0y} )Z..Hv;r+ɽ&"_յVTa+{'upY#TÚմjl=[]F瘙}EkQ4oPj&[~7,r%~yM=Ç6,+*FE?R:Χfݵ%4zl%M hS3v8!Ss}1ޠ|W(qZD=Zt֣g;tc7AAl1MDc'R6}[ :cr_sQcK>q1FW&zeVW)!;WL<.k=f-x.*lSSDΦ`٠z+oz'M?Fzf?5M> w{<ǭ<L'!eEn7Ekf6PNn Q {p'pb.ڕCS멼-3;_)*xtK'|OxrǨz!b)s(uE^-$\VG.~sj`I -x¬yZ¡jR0e.rhv9Hog3Xf_M$&}ה ;fklaǝt%>v4ÛUgۉ,<WUK%˧ZN,I*i.-p:? Zi[䈻wgEHhlաo zB~ G5"%DZ9{A/!%l gΛaSP Ȣ?PzSZsLGK97CWo+taUݒNe$^lm Xn 5L8<+4AȪ28\љ36Rj3ߵC R{{w{@k7:ԵУQ{=1ZTi T .)Z 13]Vl ~ߓW+Z/֡GK=Tvgpzݏ f5Ј9$)+!ſn'Z>*t>J +Y!Emikr RYsUY6XG;WMvRkijVA&XXcٯt:Sxc7#8r;UG!F>`Jc:PL>{ۥ u5j{ā̞]ԳZV19] qo-Z1+vxq=M|?YQxI@S1O˙,rcofIœ4PHݮKc4|#Znr4gS;pBk J7ۚ^WS4Di?k(; ,ѮO54Ϡks ze rSdNb|;4@Wxg%A IМ`kXf)På3dkaK=PFDv>}tA'/\OrçX2@U`G;Z C,ʷ3QΙT}q7*TFxwyQ<<K#hm`sq[4Wm`:j'2{ܽ.\-#OIcjDj]CW,W \#~G;p%Lu4 L :ܟǜzt':+S `NB7ݫƳJXr_w,!h/:a# Oӭ/ihO aJ@B(f5j"bVK'XAr9yX!P;f9W9ŗMmS 5t%)w8^nD ,W<-gf,[j'DH3˨`g A3Qf%UlD=GuQWQ^_4aJ7a3 &3/XA]z}xcvk0{$[&Zf˱ w*А•r,ts opPB]dJ LpyT)@ȷEӕD4}L}ޤ-94[B>3Om6'>_ɭ(2yFy߉2b-Y sRw]-NV`%Sbii5MIiew2{_74\nL]8JN*D=2C=pkѹ7'+ n]aE \4I?O!PPM(UM\ZN6_EWH-֥ciV9Irɹ$еb8rE7%֝VgBEI u/aJ=r9^hUJ+0S]5ɑŽmjܐ!?chnК<9x@rD1{JeQS%ͱC ϙ%Zm)'f}H-dXGZI"4hGtmj=QG=E D4䈇Qcm#;("Tlw,i{԰o2z.m /|RU'nZ{CnGӣ'ڽ!֠y5rpSe+M,1 F& 1'(rl29[O#`Wl%MPKKYt(.[]]Iynp+HW;R]]рgX f!`_B7{ s l,nd ,̦tXL_,BpWBjdĨ2=W6g08cc) ? S#.@n*hxT1Eho%!*V柧;=LbnxׂLȣH4.fЩ;1ԷEʚ{͠F[h9t v}CyU]nE;Rte4M^Нu|{fD/1Ya9\3L?Sk >E't`(=q'Es_y`Uw 4Zz਻;.i`OHhk̙)NI lkE\_]j 7ۂzW2C=7*qK53.?k\=mK{ I,,?.m{# {\p+G*˼aD{Y LF%‹*1GFKtG;3s2oC2~t0YJg5T*io-Q\HJWPOe.M`&Im%yi!eg9is?(fJAhZBɡw>RO{} 0۹Wu`9r$E{KWpHm?XOY4ʽJϷtmei9|utBjԝb\L`A:(ghQCv5uJ `^EhGp=Z3W4U#U S-3'ipu <\y#MG?A-70VDfD&Rʁ­0NvݩQ?Cd˧l}c;E93vY%`n94 TZaS-Ц.5wDzqS*kkMaZdٻbӟ=aҋmh;KUFp0K9"*15ƷdGLM]^QzK'*%q cJhb2YPDw&fw?H%A}Rԃtj#*%_jz*MCN} (q_ ,t8ea`o;z`B駲p99[Jyqt/7#E,]CViB@ /lɏhrj2nLv&8[>CK Bт>20yP'b*DfdfZ+U9fᮛ<7䄚˶XOfӀɴzN2OC2j+آE[,Q)Y4zq`]0ǘ9uZ}vSw'G3[ѥ— *ȭ)q'ޘãLOSg$&w8uZTש]w`G&[Htjdh}lYt',GRߌo(`"ͤ/L>|FMO6M9TA͝8RGƌr<FU=fw7u3u6ƚԵ8fWGfR!e w i$SٯH"CQXrzL.зH:jhH0Q8ZW(~ù -1޾H|5z"_2Jj5^s5w0wSSG5VaBkvA/[ ^KQ|zh,*V9 cmQlf1\jie=fE浝 Jag4pFLfOtUPD-Q"jO1Q,r?C uĭ.e\rЛ7xI6f|Ye˕hلqZә CpLQAs-'}̾WBS'7KmM.5Isދ ^ӓ_ﴽ,SHzGřdYEs/;(%L:& T#"ńĈE`&YAs:ۧέ[suwsTuЫ_W4+5ЉzeuAZؤm^aA7?)/Ws(h+)RjE f.VTEj?SD醙ӳR)ut+MZGo  EpMPba-EYw$(29C?2"#A|5BCu K0:Nڳ|XE~!|$JX 袞MJ8X2@!^>3}FxfG6g+TCWƈ~.Pɏhw2NPEV5\\ NbͤORJnqڌj Z>gPfq'u۳z[[ut?6 CHί_*2|ՑB\1kY%< Q'*#Coy 039fh-=FkmH A]gRP3)Na)!ͻG5yd;FlnS5q&D5imM Na_9$W }b`RR1 ؚg4v_-ݗTdk-Hd-Tq".baGY f~L]P)a1!2kg» >3`b08h" 3/ê,8$%>lc= tGxƂFfHeEm8_ TơAHhk M4ˢƁMF'$ 3m7즇Z\f'T|V.@C ڨi;m4S*Sнj֑*ֲ=eі`Tv-q4@ Oh$Sw!z~`w:.5S:TE^+c@{Z#`l mw%PAZF ϔ7T ԛkKlpj# !k . ! Y aepq.q3E+ou(7b;E|~fG8ayt0{`h)ć,QlPc,Ancm,6 j>mÿ7%Yqdk4-W“@]h/0& 5Fd3ر}sU wD~&XcgC&:q3H{_|VD{Ǡw[h[5|eW5J !cdhPG=Hba8 faA\Sm855SF^!y)<~j6UI1="6G+Ziv{6mKEqg֣vCB_q*肖 fMЇ[`Q6Y%.mJ6FPFH-5+c Hc@+`Y &F)ؼt!b>:g G'])Y3"tzg>" qWU b#*-7ưz2[1Lb]|CH>B嘡b#]@؞V4FG_h4y[V=Mj!&sp{Aj96Hl )[}%T́d9ܔ0ps Vf¸ Zy0a0)z[ ^ 64pZo4m˚Fn<_߁+FX)&cm. Oț 44:Gr6E{+ni8p *fTR|;U{g(R2cߢ^|.WP.P 9tj!f͛:)!V6Y6޳K+E Om`^o^ud͑!yP!^Q [[G`8 n2؇8`Uc#GD5=1BH( # l> eV|a |<+@z"/w)D(g<=p2H i-dv#vyr4>ҹQZ?k~*}1S W YL1Z &BQ%D#a{(VsZb$cF8d/mdh(`q_k\v[!tm [CDe$JM)>#Ld0Dy/@C9&7kb6 XM ZЫ34m+A\!%q?V^~avW r1zbeg+#|%Pbl)řB9|!6_ư=pb$;#Ú|$0re$)$}%pƋQ|8`7>b2d;DXNXcs3*MmtW.f4v_h}5 MSԃL6Fr>i2es~ i:h|y" Emٙ7`{|貙}>Cؓ#Bx^o莡p ֡FHnOt u'SꝵnO=C6P|-K7Q^# X,Ĉ_|jĹvJ ~O42Cb R+=.f+}yT! 2v_8,'n"~;jH8%maNX!6-0fo$!%G>2ދe#YZJAG#,a6A %z@M|]nRt%'2R ,r9cEv a@x&g㎋P5Ob5|8[3ZpM H7*rpyE'ILϓuZ_b!N"kփٹAUtl%1l #F#i z t.<6ĦfCy$İ 1l=6gg BHqS* ׇܴA!ZĨN~wuhD/Ҳ -9f9mq4l:T 0!v@cb1 6w“Vp>i sUEJz|3]r.vivebdK@xⵞ@Q3w.,"O~$C 8)gI!C.):K]U8JgPXN&?fx)D^RC'KWFbsxFH{:{ b1$yBhg qmvb~g %IC } -iyTD5R%Bܣ35δO[Q/S\qaFЛB Ђ5ʦ0i?-ܶj$^M~l.]ɥ)V#0.%l>M,=NB`E]Opb0pdhpje/v(sv)܋L\CMEM(T iOBJa@ɚ,an J`!v J[U#:x-;3zMG=ؕh:/;HEȤصXMBG`lvgdWGuS Nmut5]%oOCKJm눑.ׇvK6#̈wŒ Hu~X݄J/Њd槊+<=5=0[J粬"1zy1/Eu.E!*ޟ|Ul Lwm+>S+cdy25ci։Q/yS>Z1Ʋ9`,.ʍl ā2=$ӄK%.: LB^7rH_P3O>E4 xp=d/M-"tuGkCҮHxA{[O[kС4a9 WF>eTͰ=aS.Z+nR;‚q(MCfrNأgC%G HmOGAvЬ:clm~t9L@~Tc XEW0T#6Ő2<b:D} qUZ2I)%k!X{ ʔVS8DJ'~)?hԮW$ ~E2o7 EQ,Ӥ^.\1~R8/!>}G[#Sw(P͑ g(>SuU0 qݕȺ.bG1,Urm8i"`62))[x |K+ѷ_ %9nxG.7~W.Τ?~Kڐv^U(Π{HhN.Zx ՏZGyJ(nP.zw 7epi}hG#MRKUmtr#)e.X"'Y{8t-[ {ZCȑ$V9vURcv@6ő$;"~@I"**O.zC?൐4#jbm3M3\dyM46|UÚ-t&R.du=Bt 5F,ӊLj\@?'Cn%Z\DսQƨPk_õ󵳓GY)QmD:-3h'Te\إkT]U03YH /tCvJ8Ab% \t`X{e2kAZ?#dh+m[G/&歔`}jVQ9"|NUIz'1ЪRU2Kj q J)5ÙeJ0 m$,Eמ?+E+593KȚma. ) ׈P_Ir~AoC ŸrK}XOB5 jccZ|sʬ>דhZ6*Z2_ oa 2=6zm$DZUrxvk2`@+Cxt])N%ա(0 -CW1#r0IP{m,UbZDHTG I+M7;Jvڳ[]+&"3htZ@Yvy E.eXM;@?7VuL %;+Al>QHIQCM8ClAm="FUeT@)ʣmg)e*)5CSE!hpHj FhŴqٝ{4b8L:f_:+ 5]%Āsd8`wuGc;I"L<<-3OX(%.Dy6◞(D I^eXHGKȐ]A٤Q@{)Sl+##+d\s+U1l:_jim=LiطbxE|2m(hOn~ӱtk9ٲu޸6LhhS+3JlI͑%z6>_Qe,?`lєJ ch:ZNU''-^B{z9 %Űq-U)AgU7E'b*K-&%!2aǕ,F\#q}r1Ig- `B"m8m bHS"aO9&X`"p↙A;upss,ttCF]jievAn3hú tkMқIlH:$3RY cS_d`J 0~#B 37uҠTpzdPLK\Oh8 `L^@'4x+} 4@QA 1{ ?Xf(=5W7Kף0Z#>ZtrHCH/~nWPj3lFvm;T.ޕuv mo+ZXˏ%Œ)_〓kKA2fvBx0w4&lƯ#q(Y?N1{hKeZ?W3RRJ諎=.$zJ#61Bx\a*>RXkwk.g0-1XYe9F bZʠu^ dF<-n\B[Csp?ݫ^@wPA9T/K)&i;ѬI5B t݇٣`Q;̾9 dcKHL"cD5ro*ENݰJ8:}G;sҸ'tnZE/e&< sMκϤXJ:zz8 SǑ߈rΆȻ`>kpX /z[G'5k%$=O3>VZ Lѳ.§ ?,&GṿAYt~:NDh<$\4D'Y&Eq1`p}.%܃.V}8FU&HsQ4ݹz"($xԐeOe \_3pkؒ%B'1K@TK|lL`^_ W|c]5x;Q]BfɆboEpNb0em"lpY J]Dh'DryA!}R:EVټMtg tXHh*/::zTaO?P|% ,`Qo;pApvקrac'>Jp~8uzX{N s˪I+կT;=Ӟ{;+YegJ-ԍL>JdӓbEG,SV IbF zz"`.V|0c 3KрN DDc9M:j^]B:/UE@j;C=$Uә%et!ZVSvZ_Y],)z `< } `{)cs!s%Vt(YI _k(R+6X1>?,0mSy.C JR>%ª,SdQ#O a'XNbK>13 2xi#S8া,=(M/y&UfCPCx.+ 1Q~M=h[!ZDoxSnIT""Q3iaRwk I:j:y:h.aZwhMû#M;PIQReHk%69V] L0]Fk6RE g$^~3O-mTdAIۉSIjV4ch1]Q኱=?Hw=M_%>TGት5Xa]3hؙ`Edcvrq'^o0d㪉xP]Hbn+\,Đ,J,IbVH{G.Γ-ttTW C+hc7ҋ@QߩWyϫ!it9j`|]DnGGC.&5>X "ܮŠ8|?"WBxfۢTA+I|XB[Dؚ,` >;^Bg e>%3no#>[%47M|iT WSHR}~:HgbuenD'R Y5bBZg!w;l_{"t@ C0Z(<7h~:hh[la[|^S5_γLoкx-:`()*f5k@ M|j!F~MK܋c;Rhqd̈;6A y7 o\/ęc\’ f;o=xj<pqs̱l/ȇ6BPi'FMtF\H ˱'祖*8BחA{ы!j9UMqz)&-y&_^.(xf\0`c5~b 0(.}l?`zD8)5B67hƈS!D3-iÑk\&$,oI](m3(GLG/]04O~oh],*AL=*SDȔء|S;\%+dW%bx|dyZ,*ƨi& U*@O{\A >`eI"Ԅo@u袚`5lWǢhuKwMlAE}aC}140biثraSG:M,6d8.bW}AD1,Y_G،+{Q)-B E s<ԇC ߢ؞3ٙWL$Cno&K:m>7'I׾-*/;R>?rw ڠj|ƞwp|8}XZ]dfe8VC)Oa{ K%8Wf1x`gzYc;s6sQ&Vb8pÄg>JH2iɋ>\NHߐSY^3[ "j=Q™v|FaIV1:AQczpa"|_H1bƉ|)"H>q8eqC5xr"Xj2rFS;+) ۠,&s`A7&-C~} enRٟ-ڈx!E>i?Hx5Ys>̷L?Y~#Ę&ƠD60f3=BW'1, -VYb*K֩Sdw7.M a8BSd\qR":AH@3ؤqg&HG.$C,]GiC[PvTTд_4J2]L'W$nFIga| 2@S3TdYy`"u D(U26d):^}4n](}*E /"w!]DOѡ?M4%F~d !Gadu "iWb6%6J9C8rHe'-U1ngΒ㎵ 2=%5nR r^My`||[+Ę z%Ӯ@o cK5pzyULk,nɠo4k`X}EV\##b$ٷ M=k(a)6S!FǝZ8Ob.x.ktS*St5>Zcsm0xe$Ha^sPx6OWq!oc:xef8*&v`"S$n>\ 4r:KiA\$>ݹRFSHۣ۟t%,DK&6OTò1boY,;Ě8fF~yԑF5O8p]4:K.A!}oTC[$U+vPl* 9H1E$ fL'C89j .@ Ƒ#B,`9WWbp> ̙v4.x MHm4ab հ@N/A3K5H9;(4vtۿ&_qG5~:Q\Oc<Z볙\!?pm2nmS:G(W1owO=%`S[84E㻅g2"\kc:Q ,KvlΎM`CY~[,p@u6>>0DBS1BP+GVB1W`).kIyF~(VŌ-_+t*=Tb ŜOA4f$L5zMd\1ijbʍPyXV#]uuqYuqOGxJ3U E :t3ƽVk3/EC]pkG-c1/Bwbh`T[#_$b66oB3\C)>4>=,`a9|Y㘧܆㧋1긹9>o=H9o 'gnBG)c7+<{CM4tШ*ӧ)jԑ2pl"35&Mi |Ԭ!@GGnC C\G&{yX}Xk a2zU>ӺAnpɇ[4Cl{>.DLppB?/ h5*j&rWJFfѪP}v"7-1/FQN[jJ{M 5nnW\ T @*jhbyk0=5<-[DN…6tb[# (izQyb\$|1TPlTLgFccb2lmU3-k<C\1mb?l]p\)@n+,H 39mg/-^x[#X b鿹dX vPotp)b`6XZ&@6!1?gC" ds2ŴPJ3B].*Y e8U*0,j:hV?w}M_VSܵ.-˝&]xt_F{͎)8Mi^;%*Ӣ,.PBЦ5Muw5ANzp1tvX"x5OZoM.FR R K%Ŗ6<j.NuݬdZCUU*ާ7_k썱9N綈E&_CX*|MBhk*{R9mwI*1'7f`#})>0Pt=AO2ȥOv} ^G`=Gwʙ tTch`[6x}T2Di1K,0`3Ȏ!@8 ⮋xeg ^b[Ocն8!2!3dmӧ픿(wn15Һ*Ȟ&(|Ǯ*fe!f ?WYK޿xj>=8x?r84]#7c+?w|7Րfc@sSŹk%M;Mzq.'ў34o ~T?c0 ֳ[t}dMfOaK[n7KcVjN΢ TC]0\ `7>fpf6Ui te&x\g O#D4ª4}rpp6VV :[U]%=:VrJE 4Ɋe#ప賊;W#r5-K̬%j-Xa/H]/aA֘g\|.!M9p@ c F[IKw} MД ".V]nAe7V?RzC#4Y, Zlfs JjM |<-c=pHIwmQ!͠lAiƗ6餅h7 SZfU.cNWl۠ءE~;O͠ݲJ վZw4E<k=MC2( VX"1S3z-Ե|3Ba]/itv&l6k w>g񰝝um1q<,+ S9e z 3L0ipׂ5C . tPg.IYJ@vT҂$+Ds'_ j󈍻O+ĎkF2Q[GE0LPC``nƶu݁( -ݢ|}|9{}b-`buM<@U8\֛`+n{2HOWT5H~c=FȹB:7;c/f:QWb?uCU} al>[65Ŝܷ  uJ_#PZvs.,BJmX?#޶ {ȼ.m.Lft,q~5uA ڛ\/ĵ(~3;{ \&eC;BDth'lnR 5'$9F~7S3ړ8#ӝxB,Qb&Czm1?6}'sxj#{wR?q߅e'6lYadSj.Z+3l8,VݓG }ftȞ&Ml?Ց)(x2{hjřw.%6 =!џqƱ?1/ [1TUb/{.u! se/N|y-;SgR/zsH<>w\å;{C4m>Xnv}+{Ί 6*anrT< 8r)g~,rЍNIT_u`n[nhrv.a.uhU)R]bى=|Y8!}qF1&ۊw3ul3Rx[*.8D&pn7: 8k#׏tyϝt7#oRr_ }Tplٰ˷Zr֟x׵ fHCΡpkm;&&ë ȿWĂ ,"nl/ͳ u,*Qi"+)1xgiǷ5Z|>.AyK ,u܉Z/rk -s=Wrc̢늬yo95*U/l}7f>ƾUFV+`ƾ,x5w2Pdϵ8ڙWh6He* 9#ceǫ~tOtMLmm-vxnN,xcqh/NR3`ر=2q 'u[+*yb 3pW D;xl'A0ave@ypkƶN F\lŞK_儧:ĺl~tfn<,JC͜Y̙m^ְX9+:k窊~<[+Y`NO֗ ̽ݝ_bʬq8W迡az:KǤ#s5vĔceJl˵wϳ4݆KxzSo˹f^a,ڲJ92399{ Xύko.o]G3 !"v:dkE|Tj6cǂ.&Ys[ka\ݒ{tz=GqUfAbh^.#~"1ˌw]'qBŗusr #;мREK{H)]O56}ODx67\GC4Gl/G-s75k4;l`&z2rz)،/?"):O{q {ӿƏS8?}03{ƹlV,Qʵ]WW쩯bzF^ȕy5ޕҾ1q'uwd`8qf>d_1=/Ԭ/@p32EI+/lXct|u:QBO۰i@6u5SMKBUqJs.>kI}9e%u%zRʘm f:Ns?gu[Gi#Ux\ɧlߕsP+4 [)myk{WiA`kÒC,Տ{B4-@~0 (A|Bl[T-5ݔ2NQ(r]7#uWY7Xs,-Oϒ]+L#=|6@(c~8ˌ=*@Fj:xgj{y:kVA6Babj"b9r-9p-뙦VN kBCigu3n<9lWߴc6nϓx=ڛl99t@ϻ浲#ma!s\sk_f:j ,TXuW!U$w`r9 ◖4H(|xEU 8fÙ:@FG |/w෹haⷑ&&u#4wgV$;EWp+μřg/VIg 4ѭ[])y$W8֞+pF% KiC-Y <{d%Üz+\>"ap"3]}Dwb{[AD\zˊ^+5 Ja" ?[ey^AS!7HyA{ 1v>$1Wn>8 뵋pOjͻ1"sIC[r N\Ɲ}UsoؒLXP'pe g61!$ m>𚕑Sj}ŖO*gF53⣒}*"c2F=sFڃ f-aU5 [ͺ2 os@AւkEwZ3\pod yf^Xd >x-9'|? u;1jpLiez4닂i8+i#gFJǜp!$n=oqA,1\+6F?>ixTx%'=5~g| Dcny3[Wkw]p^gp힂\D"Ax=QSO,5 F壛'm" -8ݷ5ǾÄٷ2R^b/Y{o9ߘQ˒Yը?m?"2Ơ Ee8"~h2|BuRKsTQ+x{vHcuE򆞻٨rBj2#m'^Wڕ:`;>8褁zV:*8/|?[£2sROBؽ*-iH.vfrp5Zc+ _naJ G̶aJ2~xű}Tld2 G#L#V;Gpb`7: ;.{i G>}L/&>1Fɼ*~pkqkz s ~Gp#>Bg$6Cpo,J&FY-$$}-Ii7Y]VFrQzFa(BLPDFq k׍_qh]2㰿G+Ua_kw{I'>gc[JYOl |i'yA*a00Iִ7|eF1M2-+06(ʫaP CGtehYOB ǘ Ȟ ^cӗY#gV2YBom:)E?6NkFss' ra^,udc.:0–wkdjen+>#ZǠJfp 9d՚'ݾКQ8!f洫)fͫ,a 7jżUʠ$"〵*9Gnj=E*gd;:q``g4sI'v6&QYK\_CMF乶[ˠFִ]W kq_M`n_pr,' fR{Zr4 /؈Қ#Ze+N$bka>4.b8ےfefG{ ]06>^CSI(<LFp ,EYue_\? 2P2%O2.v9 7]4lƹܽTVn}0ό/cSЮ],DsKLِLşH!w=~[֞ D(äR[ieI/Ѱu)F&Eo\wu& >]Ԗh (#wZ b.J5w[(;]U9gb*Y2K>2FA͊>R/d6UE2Y^w]%=s4lBc.Zj|lo;pڍ;;hYn}Ƒ"8 3k\U0Rͧt13u Q^qyp} sqM2\a`o)d{ 5cDi*~Ǻɹ(]9XϜXRWak H=`5xcv.̹'&BE vl`7ne͋-=o]#Ja/!"loFcvVJpt,8rF.LER(F}8 0q΅x#y%3Rp^ln0NzkVq\/[١Xˁt-^Ewtl &y8%ɕO\v|ǖҳs<`,-?1EfO ZͭTL @%wW9+GʅJ.cd|Q[)xAy41WQs:ٖ;: -7h'w1+Gںq{G-BthaSJdܚ,bknYq.0Jp4GBZ8W oc\T $`$2̟n6?v 0Q$oP185VST/^}߽/No^~E >Z:oaR OsN1w) VqGJI26mfG4/KFҩKVOйM zQ w}*âvepSZq![h-W-OH?>R@Zr>+pgj|, zt 9a-Y2%mLo(80=߭SSx ^ײm3FIy_z3ʛ U}r19?VX4†-|K/|`% ԌaHâ֘gmZ3&83ّ[ ̎pv3jxp{72ƨJ_j pCwqR`Hǚzjj6b( k}.-U#uwaT |Y[$&\8L.W(a65PZx| NW:ie@Ows}3#.y=Gkzdg^^ck-T,&rkޯ+f+}S pe&6HDq{'dMCΜÔZO(>ĆAqPL/c&*Tp#žݨVS%Ğ [e*>;<ԬJͨ>׍_ΜaZNlHcSTLWK?!ѻ#X坥ZޤotS/Gczь9sK`&Z$0C 9WïjۢZ: r`o Ć8u35Q<مS\7ÅeXS{'0A,0E-; )㔔u+x}LkEEi1r*{]h[3!hqX!`X̨| ֌Fx0Ŝ,x3p)ۏD_0tnEŎ84ʉ3íqx)/\B55 \'c<1˒׋(̽Q8W}rTmC?ʱ#ӜKmxb..mwU|5\ɵVNŭyߟqf0hi̅}]BlsTYjQ70N847! #DmdٌytY>Y{&r^bOk7AslToඇ BϣnlUęY;Μs͉l'гkOif?[WZ"IhMP)f7͌Ʈ=aظ$(Թs^0WMĦqN [MҒQ#-Vߐiσf ?]? ~qkG\'沺*a<Ui· ODɧ7|)őz< 5K,٨NwżpMWDmej h2 폗j,fY%OMSKDoV9IԷ vIUqM9l``{{rG>;6iη nl*8&;jǁVIDOv7Wm ɖ4Ɩ2)36)jx~O̤2SH=G~ /ݖNZULqSzGTt1hʪw%z9qbmb;o{8c-FO^t koKzUӵ Gn`ciomN@\|C7xz-@B"uO-?C̣0x AN@lt )ucvk{]Ė>ä0Fdxm٠hԯ|ӏ2:f1GP3@U!Ia'['a2ex^ p~wAëc5dȭtjϬJΉ)V.ZL9Ps6i; nvi+ pFt☓ k $Z=%oEz݅n͓ݽ;O8 ׉w B nldx#E~j#7wq᝹J%V@s-|{/,zO:\KJ[mNr0Ip5ZkeM ߚW3O]uC;Q?.}-0['oB-;}ߣw11~-̖q95x A Fijz5Qv\u~x 2m0l3ƃUeq!,>΃[.=VWq"~.:uAxێk073^hG{9R,uŒgbttؤh $KY/Zˀv|rK'\6JMxu1~|qw σ;@}A*wsL] lnd?R]Ł/ndFqO&mw .\E*¹cw:کbrtab+3%ƈٸInvq^Xg3z= 6 j{Iyd!fd0SuZ֬/8s^ p~=O* әJpI񹏚;og5|[[dz.>c&߱҉ŸvcTǸ*F:qC?{q6lشףw.L8Qnވ۩^6yi:Ng1xTfEOկd|d<Wj6#d]o(cv%b)4txdϫ dk7Uqъk+p+0qp1&c}>Du*׊t.r,MF(k–xCyud-gbʔ癌Imh;WK .|ٍZ~F_w7=<҅9q{m*.rEQ ot6qsOƉȊKl#;&az{bQ#1V#EZT*h$ΏRb9-[^5kJW]FޜÜlpcNT E=*x=@My怊h뛉Ӎ)t3؞ɫh\ =vĠg0Ϣ1u!n8>tqeu>Òȗj3^!\ڵNO|+W:$_, l- F8)p>6CWwfw1L*gcw:~/f%'朑0ˉ7p";.6sJ;sx,As>S*.čUqξu8Ҋ!$OYzZ2킒g^^㴱v̷toqxÍyxDo 8fX_0(gZZ\;UnZb~*aJ,OO(=;bBphۇґǐ{ : h1{WIN}urpeZ֗m:wF`v^ŝ=7&*5'|$AOxꬿ}Mx~ϥP CŪLtJ_v ^UTߎ{:s/vXÁK=8z3o(dA16=Fu.iM1vGUA[]MDYET[ǎ681K:jFQ['*X4@"V8s\YjtN]Y+]rgf3x9r=6pyN<Vs:r֦qgmX, )[lC_y㠁vu>WN8ߕ]0ʙΝG >5|&cp94QRE-]k ?7SL/l)HB+,?u{JZ;s)kԤ=rA(•2Pki5YrWsy|>JDNIg#y=kx@aLCp+ vXpi/t22呁=rLhqrEg-S ?'eo0+?R/^E>d=os4gE$8Zs\eKY5xq%/Bt Y~4p\@'hG&bJQgU6R[qV [ 2;a8(gAVIfV㨽mFrB;FW0-ee-5xjy`ʘZCIFʎ59ޜִ&s2ksTty\[xӷ;GF:&,潷!/FSO4j ?GcuZos贇 $mw‹B-vvԑG8A k}sFt/re~}7Vsa*;H":2:`W%WAK=WrblM?q4踔n%|/Eӓ9$awH=UAk@)֗qKK)/R-$8Hn06/N㓈A&Ϩw[+l4 %*Mj+a+F]0{pV8fCߢw [@O'I!5w/`JW&{rr'WZ8O[vU1ZJ 9R,_ZۭZxm3:Nj(W,aof`_rN C2v}C냟85oFXfyN·n(ct*]R.bǶh44*?]Ի#%.sO@<1&aLxl-bTuh\ϋSݨnhb'#Jק(8H/aj8"* .8`[br.7Bd/% @̑NOUTgOGkyt->Uk!kkڌX_ߚxu'$ŨRFb^Gn ) .gbmOXZ-uHf*9 y]S$HQx9n|94 ߜ~҆ʙE# LQG6[1wsT3 ?<}z.0ږ$QZ)Ô-05 a/xO 388;3.CM%,L pxrL۽=y;vrI)~hx|rUpVŰ-z>j=J.-b_|Dw~0,|]"'h#H-E'Zn6v<e, |D4$YD쾎.c{zn|wYAtr8c {fR %[<3Z-r3Rx%V?v:(nfmEQẰ[;;DRBDZ:{yفYvY[Z<zz"5=nPh3Bc䃗.-@ZsAc.mZ{&\9AZ^k6DBb:.\Fh1<Бm9f =HOFC #`zV;'aLHKl勗X51_lcnoϫܩ:ļ΃Owep {w6d *gjѭ ݄Ezh4+v;V{`Mߪǎe]Ob 8_ZԄ) 7=.?߮f}f e&MRmJET{[eк^eUA5%ܭCM&\FBFSѩB+0 톖P/d‰9>=ˠFFc Ud ' v@ogKySYу^q.mgGͩ6dcm^&CjEbDrD)[`PUc:bTEWCϿۚU u'6*ck w3:.stL볖wɐO_jea0]zU˒zјJm81/p-uˊ_Hٝ1(M21wV.޼/:!+i.Kd 'SGhHFs~ eBfL]O\Ұou4]Ym?0.oTrM0(uaf|caw>m'D]A{tu~ [ט _`}3!j$X#T::U`F-z8Wݳ6 fϪ7 teq_+Feq ?Xz3JT!ON oG/V<ŌMM8g1!hqjmY/~  x}$/piTl돂d9M_wXM5gY:ZjO>J'U^w}떍B4F/7]'[6ve8K~_ϿVA4_b*Ah3{MХi:gT $i0ӸھG |f{g!, WƤw?=.~Bu&vuSlkG,}N71&>o{q2'sqSM._C{ژ;i>ǒ [qI{i0Cwvɶ\`o>ԃ5%oO{ަ?3bNK րz̭ZM59.mƄ0Hz b;7{K{ ͹}+͹]C5FN~zȀW݊nG!gnu|) {xJ|tDşӞ<~`ǫgm91hـ`}` ~e ]|zp'tiٲ% }5iï+RX6bkJzݠxd8@AwԺf[Ʈū:C6uT%:x UB_ePP Ep6'!rzLR }1oegYp(s>dM=<kwՍ31Fz2"ƍ%?m܄>f>_;C}u:Ygh!hJx'Ay!x-j1*FuŨ!=ܒ^x/ ;c~ lRB'}8TD+aG˕ofv\2ہB\މVZLߪy]K t򿻁g2#Eg./S/LÓpKt =q^/x>`872z`Q-`5)ݐ/c^Co1" q?n.)ao?0sDlaFӤb_dAmcZ\&ukq:_؈scFt~%9xuWvM=kM2`cNk*3 j} }4Jny3{7[oEB _ XͽuhZ/T_ᣗZuFM3R.2NA;M!x xD8f̻: ^A8} "Pme@.ݬf2j=s ]=Mpgs}ƵۖƬmw`"LX%X]__B\Q uGyC,;/ggh 4hxiLyUb4 COm|ZQޛR=-BfB]߮8w_瘷[Gƪ3.|fs ykgw2;ljuɐọX0܀ OO]W [M5+Q{ ]D_!}XsR4ɌPҙ#cO=ɍCFݚm;rT5.6͜!:Tbřx5 V3l#:Al6fI kBTRj!+C[7fCO] 箩2΂xĜV36EZ|.Lפ+mu-_Zj ]"p$lav.?UhM 0Iؠ}bJH׻=4!ldK5RaF +/jUݸo"\8ƙ+K\ܞC1܎8;K0O'~埑 LETn1֢ _ ,r/%Rd*:LaܸՊxx> VGy?_FM~[o5y}: qD9>a-ۣnSz>܈q G!l( pxHa+kv^PO^5TJ`UV)[~ft&?ӧA%+XqL[l@F,2P+s@W2aWk0P8}ڕ)&5t&VmD륅xw53*YDY3MU'0]0˄DD M {?tuիTX"Gl-XLAY>V+@/jf`zq ek,;Mq{k9^L-oz27Qs`CD0p<{r W8r] X~цL9 q1CqӡF ~l\fbK{;ɀkꌘkL 61=3pS&Â[Y)Nn0v){9ªv c웯{hQF¶2V ra\'kNlfc7'Z3F׋Yۼ-]̶m'܎v>-tCYN9z|TeyV:m5gb?y#gS\J&vRrWw#ӽ 9Ryg5j&GWh1﵈zTFd`-ƚ1="b>e5;ẴVo3b ,rz!lDGdg (*竳:(=\dV ԄζT걼EC,8}z1UDO.F15{FU @ 5_ƭR ID>dHB}iK oǫnQ9\;Mʈ j\e%g63'GJuVW3Oh 'G&{^ڣ(8k^!lZ)N ɖgaMfՒ_ҭГ+!B7-1nR-8Jh,,KkBBR}k{qbn{91oͼƍ5\ɞݻYuE^Cu(2؇B Y>f}ټR^yX YyߔuE\~ ӏMvj6]PKf{Rq| I ⵲ " O/xwZWc>r1)bQ5ܷkq-OQS/·x67~<`VcƜ9H㗆|Pb5 9@eF'.U#^ؗi;؃a^pELr]|Ɠ]V:Js.uVnTՍhCu>ƅ <dK%&YgP ~ p0W~nOWNl:h΋S*Qax ͵űpt -8j,{\-ux;c0@7Xl90݆vi2Oθ ' ɌEl* RYi)qx*~B1h Srg9R6¬x F[e\e)̧wf-W61} cA>zĈW63SX'7|ezL2R3`a1SļaK9r^ 7==1ם+b+i8_C"ĝ=t'ύp {Z7;dT; FF1q5cπ&\|\[SQ|Tz|cDγ,k/ wV8E,U';H6Okߞ|Cv}Oݚqx4m% ڈ뚰չ#AؽגM.6z5yډ[= ~:W!`ݻ_z?11{$X_OAz+tOӗR82j _jB9»D#>3V&¦8;ta2'EkYHQ;hC\^'&miUYCQ#;iw)[%,9I hrkSf7FD/.#g3)Q=eMs$lދ"?o.ʕpa^Lb >(8 n~ΛR˙)Agl"k 6q;tci[U15_`9X+CGƭtHάJ.(s0t{̂UYBC.Q٤wptGxc~75~{m16+Dt:nȿ5IW潞R{0)X[8H=N 2r暂Dkʹ|,RǾ\Ӡy7_JU*W|vݗWУL_-~+3 CX_+G5bd>um9 x{rHOzq7l`'O] ~@S+k"> <ǩ ;;a;\]f3Q\vÎ_h[*Ab"@Wy^Ac_1JspgWk%\0po 37uhol#qȍl̔0Vp*PˇwM^ f*hTα^!2e'{D971!KMsl]ymM^GUt(ֶ-8% |xo |T S$^LŁ|8c/OZ0h(Pe\͋Jm!lÒO-N䎼򀝊HپM#$\wEItQT׭3 v(cdEeQ%R^7rX8B$/ F _T0}>ɭݽUE Rd?%3f$7%CI4Kw8WϾl͇Sp$9 d2?d7HhQW=_ܴ 7(l{6Lvqco+o.X#c} tьQi6ac\:ঙt9)J b@%`C:Zj'wehA1uV&ؾkZZ zQ į؃:}\}Kq01.x[رKxv*yUpry2aH95^Ja^-)C{[ -e\D>-_Z{2c/D`-;jɨ*6S򝃜 |0N/ÊJ[j9oJÎlss%xr67ĎO7x#^ ?>nYE޼EY2%\7~ۖz|MH DxQR)CExV1Dž|PjD^t F|þX$j̋Pss/"Kڀ읏P[Ÿ2 9=a#f9_WIx<& S=?zksK~krzuQﶄWKe>VIE jHػUdj/%wTqHp ,ݯV28ٗ}>~<ۙɹ|$<(ćB\b{3dv W~_ȇ|Qɰ<{mm7sm>SZϱb *+O„rޒIB. .ll\?ؔz<#|P+C:i܃j<ږotp SDᱰ9;M/X)Cy ^nȳM\B1vA9V,//Cm1ֽ 멙ztx|; ΂֬FNDz4>̌ Xk"3vx:%CS&$ݘVSɎr*^*S εS{'evn!hav*>kw[)9/W䐒7|;Sʋ?iђm49p75/ Zg=%2ȅ}7JEF>+>%>tN,jb)r+p7.nɂúܨc˕ _r^ 3NFg{)$<8Ëӑ&vugm\o"l: H-_Cܯ~+ol'lxYYNCPӤe nƁQx*a#4fw00Ͱr<(,ʵyX5. 1~,l-R* 4 A0a` mFc¨zn8>3Bر|(U-T<[&a6t'g*xz]2n4qre/UPS :.$gwER&d˧\[aA8dտS745=~~)kc1BZky[3+٪s(x %G(<_r_HѕVXq![]s"77ֻ6דO ?Ppegz7Jj[ܩRwas̎Bvn)L[\ޙ>H/ C~<Ѷ&6'SeM.1tKUN<; s:3aV2C:j& Ӄ>8PuDW`qnʅB)ï2e8 tDtc 9חT XƖa~"= `b%7XX\*KaGI^`dSQrO/%9·ruP?N!+qgulL.@H' }p!}'c{| Z\YH.²5,KR֛H}GpJVޡ!̪U7K32̝ZblcƁkL*a>)fJAŘH1xo#8] >hHgOS6lb;//Y镉X't;>y/.\ Q}"b], 2;QoL5٫j.\,쁀a2LQBzSgB:_^ˠ;'N@{~qP ~~΂2o{x/!m5ŇmeH8Lpd9UJ6SXqB&d>+Uɸs*̅CƟĜ}хd2KEokQt8Ys!k͹x"JǼN5M~|F/&N򉒯u})PS9*lå =.I]1/tr%cDoZ`++c8==#Å;:r4'z117Q . <{9XoT}:ejqN_mquA?-R>b䇍P^ќXI@S^%2 dcϊ=gX r_b2T`Q 4%\$+b-ZuMa7J9A%-mU<",OƗunGG+#x ]vz~B⋭tM}k/;INÔjL=C ѯ_WBCf Jk,ĩݔVSK,<9ܝokmWwc}XS$ VP5E z9j;xqD/?\%er\7:ʇN݉_kl?km͌giH"~SyEg&f -[kN=~ȶ(\ ncp~>cKw@` 1صb,W|TIE!{gͣ8`hY%8(TaL=vƎ&˳-yk>2_jgi`f,H)}h.Rrv9w9r>/~r.榥-ӭƎlՅ{ 8;r+0? zw5v+ w`?87J1# em6߅+P=q37.?% 2N(X/ƻH95`Oj$t)U[wNO/:=ʝUG\[BQOu<nۍK9ґoLSqG&7Wg]9Q|Ulr{is77)7dnSGN^>G1N2 ĎyϠ# }nBRY%4`R<)^/O1B8 W"dV M[cNW>,g6m|a|im$2z+^=P R񤿂}|x/3UEq挴%W^T?~/& Ս~nuŃ9 8u3„~ƭ) ۑs-'"ϐpM#29}vyÔ5!%sfkxE]5>- 4gZ5`WBF^"!GlDoLnG"3ӎUϛ}_'Q.52n,sWi&w q"nvODm{buC՘4CZ-}o3z%74RKdž (T#בQt%"u_>.d"}9뤈sԛO=zPgo1'=ySO#s. s/>?I^|BΦ f[2~"2_rcB+/N5^ ̉w;;矮 ‘loˢh;N{\e yn/ ̈́kK,80Lj XbF#೮vF{D@ɂ7Se݇\b4so/q6 ^ݗ0r'Ut4 }9k/kJ&ZsaPzCd*zȹ;ʇE'6R¼}|xC.&Ԩ&-]bS&|kAZRđ(y^kꘋϟ~hu'% QRFdC1F ߵs_3\v^l֋9S`v7굗pC1(]Y֕]A26;a#k;؆!h ]5WQ&thx5 ]>b{zgsP3y0 ە e`BlyÀػ ~m,E~lQּ.뱻 [[00P[TD@D8g}7ηc0ZL=5dÈuۂYre۶3:VAߐ.cl3"d]Բ4Ʃkc颎zoHJ f|CPޓ'8L;^Y}? pzUMltNBZ5ʒ2#v&6>6vq4(|lW,oK̲pJ!# gn1ԖgG2GX7(cq6): ?_o`ij)(;jƘeA|ƕr\1Ѝ3qG\)ͫc1^^=ٍF<7ՃӺz2Ó;]b" ?# -j줥CyzUW.3n /QUo0n%ofz#N]96Mcgn-Uޜ}B}?weiL< r<3Hc}6NG_ |-f7nq+s'Hx1kKT=9O)=Ӊ:#o=tR+fΆ8rOcNU¸~pV}¥h|O£L N#9 Ą4m]5 ,Ru~6刎zj121Ỳ暪]`d'(df!Owg'sm`zS2a!-U&f+ޙ/a+<ыzzl-ϖsK3 ZE+WcY># NFc "5~".S{hSGnj*̹v97@?oȎ57*/4p±# ޕᵾl1כw=Džk(xC54Vff˾a.S.ܷՍ;qgS~8WK}] (:7WN_h4}[rajCPhPy6n^ğ/6UEbى`v5cdFY[٠5kp6Mfqrf!*0 a3T2ψ+2ǁ{з7xxS\+"s3onrVK29}CFU!ed> F%iP*t p?_~ƋgXw|9Yse\\ uy&GBq瞪񘷌AKd{S0-C5z\ę}.nhk4ye)zŢ~j\D}YseG8u؂nSXn'Dt6Ff2jSbXJfby ֌JCqLSy5| o ;)ܼEGkj^@ ;}H,рu"==Γ5y [fl5uxh{j0w ڧpvMCc\LOyh vqg'ÔֱX6'n| +\C.ס *bn24/V#9ɔ/ڸӓ1+9a!-^b\{ @ۭq"KV ΎLFD\DxȀJl#D[2a>Ҥ_ RT㻉7i,9WYb:f9&S|D֧ 5ryw kTK?6 ke|G}1{ePv޽B5(* e'8&_2OTVCgig_ &r= hr:5[NǷkYg}œ"9OeO?_\bnRmU8Y-)Jj3gz>;8csBphM$Dµ_,;1O$:2c}<Thh'Ƃa^ߒNő꜎I7Ae<ܪ }>+ցavt*7'oMb6bJt}&`dǨ-%' PFVwexPj=kv|Јr.gM;L9-טu8u,.B_ F a/-ڹ'}!/*?S183&|,o>BW>9&+V6f͙95Sy[&WQ5"F2NMXj}b1hC|(@ֺ* @rR=j\uSs{Np[wNmvZiȌnķNC&"<( Q 0bQ6ҼQןhU|=9=Krp7V7.:[3cӚOP&o+42YueGR>ü1u1wuJx iHK-2XV*q6蔯{nLoGҶ>so~ȍF̟K?Mb xxfk|mFAr.WcNAQ[j1㟽™u 8r'\oV[sYm:&}[Plߝ o׶4d&ܷB}[u5.D"[{q:ʥ%NŮWL͈Okj]MI+p{#Wz 3|1#nYyh4irq!n;_w\n #_"Cipbܸ#g$.W>O,7=U@D/z؈^s\i^lg ͖8.~;) 3?celgT^OAqkko*uo{_2+}C_vy-cf|h=OM8j ngcrks]> uang(p:,f,6CY-n2mUy "}BZa.8MjmHwʆՑק;ӡ#\VԩYz+1<88X4٘k +B -i[#;,C!o嶴5Rx'Fp\z ` ~ ݾgQ:ojkN3t9Gc+qlk wv9]t-҅go3̄O#tyyVxlRyO勖;_]ڃgp< b64ks9zkD#mOGb\yZGt/֮;EX0z<ƶq-ekt~~ <fK?yW8TN5wb,ư0QaTu:B~)A?^'A3Ie鈂A{08tC`RcuZR}v98N,TPʅ;=2WVj`Oؒ>LZc`IFjg|5D* N; y?"= *5."-V]Ioj3X..;%hq 5\4cg f)͌U.dcӓw0]fhhp]9hVՙ9\1I>86 iӇ8dc^y!c^|< Ǹ#۱!ʹQڳ8 tLix*j%#<#F(9S%l把Č}w6oŞ#<9y4}߯]O :Re>08]硣:G5㵌8βW`k~.U㛱h6q6]WaL$</PsÍYXƵXK7c7 n1rF- oMlf@2V{ }&f|~[bhahq^LA҂m%w$)%"_gHuЇb1uzҟ⾝?ܞ[8BtZ.Vb1Qҽ/VA@ /|ޙ+ґU! aˠ}.).c:<;L;mtaL/@;:xiL:bťS-o1Yj1׷3ee&~րUZYP yjVx~cnn:=~8ң'4m) C/h|C,4|s61cc_MQψ#_Oom>EP,t/G>X/퐹H])?Q9u@ W!.Ic#Ѥ 4zǡzOyjzsO}9Қ/evQm U2]Yk8roҧIO`mjüj!:7Aoov%uW-S5[j_˔Xm9$繳/+oUzFj:^$ q lEeh 8ǘ=&4~б&bTL4Nǭ;19c'p,c0aMŸ). 㮅(#34{(*/_տ/=u|?Auw'&6c;- X큒R/&qz4_ 3qtc\PdCy7ߌÎg[.{uܥdrs-t&                                                                                       S imOo_5s"aP;@'?0W)9 VI*bWcO%"Oi.9O9peuRkRuߊKvVl&ה"r ~4oz.^9veXS#( U(%IYm1Wq؟,_B< Îo_R|1nKmtC^5]A'p#M#v hdVU;=Avi0iqxRZ{Y'Qv 0Ix0|+X4"q `!cfx4=_Ahc')2!nF-߮W)9LZz8垤9۔9+5d̐Ǫ8zrrIMR}T-xqnWy;]⟣$<܇?`2u9_~^ ~FR\<%9E߳7῎@ L.jpA[`0V\Ư@lY#CpH~ 0c3|3kOtj[Fr_buhWZ\V_Q6*w*6؝ SN|z% Y_ Ku(g%P zEHB\jr=ZHNa ߻䢳?&ͬ\ 2EtQ-[LT}Cfs< QϓQs;uc+.fܰ ,7Jr|(F)LLy6gUc]~c<&5_*#WGQ=iM5loʧC)"0y/ckKꌱc)b6;_*ERP7c`J9YE\SizqN"{JMz~$r"άoUUSQ9Q Kja/{m~.Dȕt\T—L eեX-5:ġۍ=poiG)l^f}>',7en jݳV 2`|Z87sD7L_Aqm\Մ ̈́{p@mZq;ZnҴEʕ-{ r;L[ظSĦ-:r{$֡l;\D-Wa̞WP^wPY/^KvtKyP^%\e6l^mFz?W$Mǯ5?EG1CP[zlݜCqIg6c R}\<#~I-J> ŵD n_1N%?~?&JS9..Hy zpjL5Oam=}(k#(`@;jD93c9P1ڌxtk^ͯC!&<Ֆly_i"]nȢGK6dB>]jI(-{6g5Z>*\uFhr&'A/4hqyg'hf|BF8:5t4@uo P7-VmGV=~r<_>DcE97՟`w1zS,8 J0$5`*kɀs% !=S[z̖ǝyֹ݁4wt},,pe 8ж-oS7wc|Q5oklHL3_LYʈ/YRNz 0ue$.Eڛ”k\2͖1n͜Yg༻&\n̗|ڔNl\Nŝs:gok 9̓mtwqHGVvT0~)sC.h#u:Ex{'~COG;!kP8yk.+ۥ|ۑhp65G~bBmNj\yw3/YGXKj1U-/Y2ϊ5j6ɑN\ڍ#:y vkl⍂Ln߽?+O\4tPMMuٺ$V:X9bSLퟆSF \CS0y#MyW>3LJp$+gzuKʆr7 fزnZqP5QBd9QRvFו8X+p3ݣi1'Z30ȑn8ŁV s3wsƥƕmYʯ6{qzL.QCN48a!H<܉V1׉sr,t3>SQ#w@sH*}(7tDƭp_٧jpYSLKmV2 >_&Z|D'U"[-j?oa{4v⹱n,\t੫\MNʌm9U5.l}`NC,Ո5X@[Wb/8t,GՂ>}e:72f2ݖv[Ƨ*(`Et]gY2؁'\xM~C<߈ӴftZY5UYo%rऻq3ez\aI 8a(^G< >1i);U[4q^@mq7:˱F_̨ڟf\<)lDe!+Gșۀh3:QY/̼ɂNv\ʵqlA)߅cXhV7ʁS2x/Zˊا؊e% lîˬh܊ȜObzpWqr{U7"lz/WOm0e%XF%?ճ<l 1bFKCoΓ<ґU5REY4 >23c{.NfK]1a>~fSD,?cAw%z8_R`T>Nk˥rE!z#ϖ"kI5^4KeUm6Mu"bu09};S)nDTUN|2“'>빲PWt9RAD g7<5]תJ+5aJ}ndȣ #Vy*0`m}gh: f[1|e|iij ?r^ g1+q ֜1cB=:ة>}J\xk'`uwNusW*܄:U3Ǻ祥'2֒:;Qk;e˟%Z X83be ,c(ÿ:+m O%=X \,jǼazZp_ ɽwpw9]ڱl,H_Fkp\'1bn-٥#ŕG/Sfު^=xo۸s :#*8ٔrg5(;Ē25O2zR^mΨu[95uر FTscJr;^E7D`v !@W y҄1+F$ČRfsā_ \g;ug#9ۍgC\ik WU3}Xr3Ou +7WznsSJ5fMzi`\&m"tpǃcl߬ZbX T9=BgL?Ռ YxԔg68Q:F۾thLt!S.@+.Zr~3u5gC{RZ?e/teGz;’ݦq[c Jj[wb {db܄RV2ոB=X4^N5>أ]Z٘.iqb܌`mϺT-A_Rb8h+ì\)+ucIswvW]:yV%2"rw5ڕ-_k~x%hڼZruk5j)WS-J|HƲ{A1oF҃-".aoC+'U݃ј{buR5lЍQ|(;Wnl6։#(a}+8ߙcjύ>+_5sf#O̥5t{3o߳ndDSC'g[sI_b[zL]bșP6 { f3vK\8̕ Uѝm9C#=,c .܉-AU 4yx9.~']51k-Ǯbh#5WģPc?͸~ѣQtӱ,rqW"wdKO `:7ZO[mBMWj,r㻭nLQM8#Osa&uw ;Ɵ.SB+wF8R/KÄɮFT*Sd.omJjDP~j/{1& f8 OK/}EW\ N50>HMF"<,0=5ҠY1ž3ܘŪ/xhڜv?'"T=Uc]hk9(ґ[Я3Gtpbi' /oDMzkX~{Xh}T㤴g>il@]ޠjA) nKŵ{R2 H`՞*U>&tÆ#]YOzG'?t䙮scN;'dD7.l¸.|+ָ{pf+ r纏. EVi̋tb¨O+^jm3 θ 8q# 3]2ЧK6}zfvqAo+dIQ:|չ2`ϑx89/4\E%-ٷiʙmh]Ƃ|Ӄ;TU~k@>AG s=7U=+;x.Ήƍ/܅GtCN4qPrDXvWBqn/Y{3$_]Y{ 6w9_z#n9bͮRc)Ou/8&_5Һyr'x~wU[o;Xq> ]xMϝo{ʁ/X0#sae$}ޛcʠKqVpLm>1զ|׀l#jL#]cάḡlC;ux6~x0UĔE6Z ts$>7~f~`R3,GPޕ%#s;OuU7Nɡy5=fpQ3U?Rذh'&5t.lyō$UNu..?{ }[whܡ]# nĝb_=!DI"$ܙ}z5ݙW3Us;'-ս[{K;gwx t|aw6͌d ]"Tf.?C IZ-{pW=~6㘞6ށWBc3+^&M)O~.>n:&^ԫQqC%U{CF^|ڋ]d %wRQZMc*n U|<׍dkNmicSK}-(?l+ρFJgR{ȱ7"z&(Ck._1`3\&16cj Ԅq:QOݔOCjW9oQ͹=lR' ̓8{hl\+7se5ߛ4QjU&Mufw%̔Eo-Yr'>{UK>JZXpDĘ\7v,U ϜW#es9[U!-u8/e &R%8sW C39-}c)-81a ef S>XhqμSɠ2j)'ϊ9מkE D{JWcmȸ6ːFUujS5˞X?Z)P@W6=`_~ oqmc [$`8,\w)XAW (kP64bQ5%puotf;TUaֽ^5 ;8KF,n:cΏ yxl-/fc]dXkqI_1 &lܑY$gfsd"XGeY2Wp_>D}njf& S|))Cb¾۫0OS蔡G VFȅe$\%C H&ALjcϢ;@9eP[=#L2_ִ8oM\] S{GiسtN\:DgEEv.kG)gY)a-pgM3d] ֥y 4n&~ƝIA>R,N|pˑ[АlL{<"; [wvoQ"Nf +xeL:` h>VmQP ~~qNZgM9ΰzcīL8yxmPe0-(ƨ1HI•FȀf.pj Ps{KxJŢxvRG RsD ta+S_8v`UOں4:weh۵Gߔ~]1V%8;Ҁ֣8_ckmc^[,p%\+eؼ\S2[sV]$cNΟHs90=}^t]q*Wo渥 MFY_ (yÂwE'c#KBf_Zv}^n2N|!}5vSQx/ƞW2׺s^'vtIBUJz˻z\:βrI~2#4i8'T#iLclۖly-WЂiu0=zvޑa(bE-f xuczKyU۲15e]DBwicE3S/Vsd{Y*dɳ%,3y=Kc58Q/a3;?r\猑r|hp@̶ugͳ̿cLl]D1Va$8]ELF0P?{8_0'^OC[Qɷ~NX 1^fmԧO1ϗ޿Q)h cr~gUUA{/T蠆])c4&%9;=ϻO:y wm3gj!#{Pl&2>O6}(1HK6\jX r؀]ZXp[&p`5'XQ❀5Gb9y˓p̂-hʣ-9@߈ uxwE)f/ʇۇ\ ґ|*/di͎gx꣘\lPab+%kVK¶M ޾/c6'6;g4cv^f3KL"%7S95_8w҃'ٳA3Fypj,.Bl b,ʃ/⇝jb?O1Xcܿ:@;29;Ҙ̷ǔ#34V]j}zF~4 c˭=cE>>@e.2 QR^ŋ5Q]x|$f:w1{+O]3'r eθFjIcK:ܷ`c&Im~-.8(y26=j׌gQ8%EO]jͦ\Ydϓm:݂y9qt5|:Gٍ u#p%/t %{|<8|T&dL/ׄ9ބYpj+FfKuDaҥt&̈+Ws`e xKWJq=^x|>d[6& 5R$#~:Z#_r0T՘`]5zق6˕6J%}n)X_'_u(* ,諹*^sjWnĬ;y%`95i]Ɇ\HB~^9&C+p׻`Q:l^ 2 )'pz{¹ WhK ggj*>끥 ÁY.lG%yx.eHǩM89ŁN܃o{pJ{W̫BX( (y+ok!߇v6oS/D9I$DK_A\z˃[ĬϒIO.𰣳\ѧ1ۊ` qh]c˃X]zlƚ@3p g L{kϡ_Cqm':(x]FߡuҜ獅,ܙN,:N ޜ,07|/t9o/T06U9 {(y7}*\n**:J䣂U̸v*`bv*2gߡ0=Z:vވ|'=^I,7u [_",+R` .-내9?t*\8ol6Uᘖ#`fLM/:Yw:X8"N3288Sq)YMcOhwIFRf2 .%g-WqjOMier|"fq[1gxcs=O&24D+fΤl5WŪswq~58 O$-V7dLDT`)vYp)Fe4{x4Qad-.X;NfXb7jz>0{'l~a'֦஦Oؙͬ ̑w۲Va Ϭ5ڑ$\v_I,57Rsm4^d% h?Ň4UK c(yU`nzq//=W]e[WЄӮYqD9m18qpۻ LP%{0ofO< ~c7DzڋPss.m3AOm'~AB1zP je# (E|'0{;_owX]l#g ('JP1联R%|[_Ke|?^R*\xO<꿆^ۍ"/^\"RF$=UCS#\Kœ\= G8.nE.g=gG#ퟧ\ /_aQ^6(Eڗ n{9ɸڔ2ǞY-hʐ/2.]cSa(]N(;esX£e-m_e'\ *~!p1 #dLtƍ'?ѭMnM V}aYhZ`lNlvMZ;qS^ָmy[!IRAzxÐQzSSh>Ow<- -`Y{ uv\,5jlgbJּ| 9ೠo}Iýon+xOL4OW%~1,#say0iHJى15C 5(Q}VDS )u&kgzt3X_jslmƀ,DqMCѨ\\?Qq8_b[9 r1%Gw+CjV u\[Jػ+XRn*x9_/)WآNɏjڴojNrc\'+\)v'F1#@&rI(Hɺ_?/!W4''3!I) 96cl,G=N6=#P}yS`}׀XMC뮧k΢KQ*l@3y.-ֳ!{O>F°wpxg7VB-υ^ٿT~AŢWJ*Wpm+T"/TrTx:BVa*>rtfץR ݘ"5?7{㎶VZ! ϿuٌމXwۚ=j)`yD8EXc>)Ss{ ,ihMOFro=ZS[s l͇~Ur,2L_Lz;XY2&՚8R7. YCJ 7F_d\dA<א;uԬ"b:Hll))>RB_;|"C.PZs1[m4 Xc݀,|*AL*iHKF@7st9~R1?]A{*Vp9*^W2E 2cV[]{0.H[e Yfro5ߒ>%KXtT̵=+pŐVh\]S8w%X1[Għlr5 ]Ԕt~7s= 7ďcblоȀ>Ͷ!C>L ѫsJPm]0ӯ*YYŵse9Jy*CO͏f*T2$˓n"s+ɽuy'=%uփ >γ&<>SЭmf~Cч_<-1j t}d&(C<ɘ5)ĔUOov[}9ڔ4Qv??؁:f{[[p[YbLl^J]=0ZNּSQ1TsN~Wʋ]e,{e|)Jnen+'2F쓱\Al^Ɖ;ܦ#f;c;go+NlNmė~lu-ގ_8pJ+?v4&70<]x *O7=zSZ#"@_cdʤwfj/nVGwpc#:gQ=>;O+#hU5wEebs&ɖr&/f5<~ڋ7& J5ͪS090 W\ zX8^Yk$[N28,٣Ȁ/h|Ik0#TBgÇiok F_a*ڊ^S>zVViʯp9.Ƴ|\/aG_%47bRzvTk%mK쮘e4 _#f𼟊L%VpYV*ޚ1ٶ|fđ j-vn[gxuB#X)r61FK❌۶xRG_sܗY[_eԫsv)/}󼾌>so)b\ZL s!?J8'C;8|l1՚g ΢o F5/q#o,k;6d_{9h#gGj=Нn|=_HFs1; _kRù+~h\:JDt>򤃫۫I[yq5Ȓ1%2mZtp*4 VTq?/i)gzSqS)g.9]nγdMw;m' 6_Jv7Ɯ};ֶ{Igp&/k*ÜRGG9Rڊ+!",chʇ7]P$lma %9Ovy, dEg[KX`.lvawڭAO ?]Qέzsj9R$l|˞-x Ȁ_+p-fy x'o2q q{[3%,XzNĝs[]q"sHF礴}Է֬aN͸bׁq R4G6a /Kp,,K#UPFw<~s!'w#HG@NF=):r`1FpBSТ؎L]|ȍsD w-bǻ62N;} @]gN6͓Ǿ;ҫ҈C{ȐMR?/հxp^9 ZC .ER~s5|l61p{ۢ73Tti͔(/hNbFlM!Dlo#g|:Mbh.79(xV΅k"Jʕ7:RWƦl8Đ]gգ Dֶo% 0<*h-&0:ǒ3XQ# =w]3af,k-mz9W*9y7..x^?k"$\_ny+D̍Ib%個JNb '5d^]LkFD#~> @DEӟSpua|^[S͑rzI)MRv!jgb   Y )BY)m,/ނ=ZyMGlr&Ǿw~*Y̠4L`햜ڝn!R'Y_ycjtװY5?H#: w>9 +Y!l-f[OM4k6c˸*/Fe\rQ XBŨ/`I;N"=3\|]`|lڷ _[!x9s+xOJ6ְ}ko.[-xR*itYz2v3f3CvYi xp9?=Fw f ^#=fk*| 9Pod]P]4.g_ 9S o ] ў[{곢u>_z gj@Us[ >ham7ڴ3e2G5pJ~fd9M)w*b義hh=.Y^ź%JglF2D|v7 URKE^ qp@%=ёG*n!~.S7zLG}4)yv^ BiOQlY_ף{6gyŠ23nokO?^sbn:BL!b-D<h«.e+b-9WeDZS]% 5 z`soLV|%g(YPA [deN>ԯb}*Kd İbb.@_<K^`T36-䙭rW0⅂G^xM$`!dNuMp^FU'3~Ϋū#Y8{f$iÝO9G{aBvXS~ ɵZⒶ[GEg=X & gOE;Gh*xC/9cetxeTLjFŎ*{NQQ%o 3`z!k;28Rx]ГBw|Kim$|^+TnSRO vk"au7s>cIÑNѡCb1eHMXo/js݀+8l ꉾc|_thٯ"o9,bU+s2<|[Av)LE$L&XdQZc^ۭfNo6{VMesxy:+i]ӃSC6ءGo)n4aWlB(-q*..+g/&5E֊b"H}OHx ߲c{9ĩ칦eVc_U,\ vYZŐ6c8o`OGxsFkY Pb$fLC>yZܖ.O]9Mܭ$,t Xཇ+lMi8OusRW'צc\Nl[b^;~h ֯q ~jm4\zH ,J5l!"{ =*Y?=kFr{JEW[0b1j؂DlGM03.Xep mqsL\ ~9ibN])s1jǶ9ʚ^2Sh&X~84 Y=0ho² z7uw.'ho߿-3-F؉)[%W-vg ;2M ZSp-O|{\*9ZrW ޷jڡ&! hݵrv[% 8ȇS&z7i\Ul6U<.V;M8@}b5v VT`)H{ghC7ONt0vE?Gj8pF?krG.\Β.ò 7o XL""-R>viamA;B>vRύejxsϯϛFϕlLSmgOGda2uqPg6%k`cn!C1ľ\8q!Ot !)řз`vzu Vk:X^ H=voZ~ˡSꠟ_:t/758 mнe-$0‚8r7}_kX.=6fS5h(4~$Gf ~7ErZfrrLfhA `\ =1Lx0j_peY{8bgR2^r\LM<;]çdDŠS9K wwƀ8; .{17ZM:ɋV+9z]LX!f7kP1t0]sG&݅ϥ۸;bʀS:#/LY+jT6gW?f86=ohk =7Ƹln%İo50PVz\Qu:|wkXef ʲy(䴊M~)^ƭ=9HN;a>hx؋{2zZR{$h*,MY@bRvQ{>b6ś)}-aۅMd4)t9%h7Ωw 91,ێkF3{С(A#! 1{8UT!9S]7S]x!t$B9X_Iմdt]Q|3!GIyĕVMO5(π17@]L |0*`vahrQ!s| /7^\'@5?uQnϵ%Voů %`sh'a.m1ػ$534>q}k&*|I)x^cS|<\__ o?Ôhsq57 ǒp6!M vX1ڌ,BR|kXUILbkuacɀ[?Ԓ]G]t>(XGYC,{!#gX*6#j.OOHjc%U\ ղPڲ k^-_aP:÷"7ct+)(^rf(XAbֵ3'w|`/w^8f1~"`ͽalq͉]o'/w>W*jb$!V7wzz*TsQV!Rv\gΌM#u}1jT,#WtW:`ä69+*&apl:  _}ث7xWr<ܓsl9!)>L7Dv}E5(D"S<"bn:͂HX_?ǥhc.usf19|(`F\@Wmp" R ߽;T̬2e{pl*Gg_w߅I1ܽҾ?|(uFdܵ܂Ne"Q򙉊+X`YJN}`,M;:= }cfl,aF섉f3G!ж?݇_"Bp'ο$rZ A݀k3YEry#a7'x{y"dZšq]'V1 ݾalqqrDž+wBqwBCH $!>?ﷷoϩ:UweUuQ]p^{VO"K,h%M gwQm+ɤ;k8I@%_qvbԤ;b-G;rfw}LXM7+6zDwt-z\ϡ  Vӕ%"/ȥlj[DP *jk`L@Sha?V8~6!^]Mw1ΣSIx+O V{= Gjd4I~` OZ5txUO&ԡ[ (0-2, —Xj ˍ-ۙ7]aŽL޸pK+.iv;t&ΟHgt"ڛH!S)X=lfғciPJMo6 Ϩ=PBWvѠRZyO@6Ob1Y̌Cf9Opg)ږK/~?!fݡRH;z nFCA4mF";BdѭM/4DRiZdI'z[N:bwmѮsw!ߡ.QSB4[Õt^4f~M-הиK+F~̥ iˈrJVE4I n*/WMMs>'vx]¼&;b`y Srcy:\^ETq-yP 9/qk+#Z) Fh=9ZL0<‚!01_deg,̀5[ m@M cQx߈quF4eɒCofBfdUQɰf$䘐kFm#gTDĜ:3vLkΦIVoYS݁T{!sQt&}>ʽRۏ/mMqg|X\C WXQOPfhEh+bx:=:ema.+(*xi򁚏"?E.(󩾶:ۡ#BiګMu}3P͖ғC Ԟ焝\ W )b[+Eẞ}X~ E8(gTG̎PL|:6%NInyԢq5MEBO nivbx+NFZ1{,sdX0w/k]1ǐKamNL[ޡ5/M+ F  sbWOZiwbig| 򾜺~MSzjV} _fn㩶cozdNH*GK%bd$蜣Bo&"hnl-j˜fl`48TC@nKy24dz?L6Zpw1!B3r-hdvg-5woxbL/,T7݋i)ME;'4ǖR]$v2Z$Ɛ$6t*:58#0_ :CO&/.Įo§1\nd',Ȃ;LюPѦ9xGz3j4w9k>H+h)t7*ľה>P`' Mv_ZӈiƊ.8jla`{p{n30{u47DB+JĊ[-L0̂W&Lԡ )@R9(d.m s0 HtG!gli0I5 "=ԥ?mϠFЖaEe8R͛=<xcHRGy; uƔ[ܞeD &::2.mA)5i ,h϶=C?>Ƃx21g+= Ff% A9Go$Cv>p+ #Q j'hT Xcx3ʘ,y?GowoBقaUy& a2=󀹹`Tboh0? "LY䈈YD{to#=f^2o9BpYNSC34Ո4u^䱮3fLCOQfN0a&obD01LX1˂P@H1[  `AL[5Jdډ]=T{Ud.NQ+YYU~4 IXڕxoS>Ck*L 8shqc|&3r rƮphw_棽pCS8q o*+~fzCOڊMO Ʉ T5MQCkUc 5޲eS8tP^K(E4xi+L*O,6ev ܑɾ9Z8T)ZW) X[1X~'Q냵t]G- 1'RrByw>gy3tq*ʝD5ѱT$TRɣDŽşJr{*]ѣ:ӹyԦ3yFF٢fGGbcwā$ p3JP[y,SUٴ|N(>߲HC?*͖;pmk(klW+0ua믚jOi+thբ=4Xp ðYw4Wi9dyRJioψ'ū 6pCX?v8@y^*xyބdXN({SzEۗߛ@m+7Ŧ`Y4DE{V'sÃ,vDlA\&^2z TQ7ͨP†j䆏y2fƀr z:Ռeo 1̄ԉf1h3^w7a8=>6QCV;L&R)\̞.B 1g:=nLm#vz$hJ2[nX\wZv`4M/ҁ ; ħoRR iDޔF]q#:ϡQƸT!&F\oPO&\aťD{`zoA}Z^(Z<Ò{Ow4P"h:Ah-vqC(?p{ J*pE1zdtD]="Zў*VFɤGKjXi{ٚ#gmTZk+XK͚\&TGSIJ vg;ฃ֘ѾC\д'n ѣϊ8Zu(H@^;[N[1r6og{p0/3v=6#鏶:,TX7# [$Ek*,FWIcMMXCzHU1 C$% d6Q6CSOن; {˩lFgߨls5aL/q} ] P zK'|RM(u4, 3C M,̘WX, G; T(m:GNo=v;Vܹl tI Cfh _ClboɑOTSl^FǥSu<o$A;f3F:M3ண9f50Ь O"$%]g)pEIg+3 I/Sëf{i&GQ+_{Ҁ"6K#%(c}O)nf<+Ӡ#S=L4! uxj k# *<<(/ ȬmeEV(Ar-ڮSG=7U;# ú$xT$@_0/_=Bx#8 a-mUI=Ws ˥Aیp۴.=ƴ'w@KS茢ERB򎩡N^Y>F%lìz"\?#A19(p[DRFQopd YFxb}Vts"= 6 =R-i1=7+;cOim|"GG_~ MtDHR`,Grg/Pˈ]f,9Ffy0DNS30}DiR><Z|//(-AL֑2,uR?9`G vɰg;|َ:uVs[ q;6x=ꚕudinyA~| z[MwTv퀛W0+2 WذU5:\X]BD>"yxo ;Ӛ}5WI[h:w=N*z/y2il&aci *BPе;k00I!N$[3!}vSS;icq}*k/ )VN;tbXCL~%<-j1TG#.4tpwD|1P]ׅ!8c'XlJ(T@~4}$:_|ͶiF]Z11tݱ崦[%qhG8/t•Ult֓.8s3󰼣vb'F\)r ٮK :,Ԫ1d;pf}x?{bg#n~ңy5VHw,t;Xx֒ "$*M$ؼLؘi25z|B͂_Ϯ:M3Mr1d@;=baZ'.Bo-ETRGw>~wքr:yud&^φ-Ios&UiQT6GTӎE,82sݰ[2ÅoQbM?CNҨ418MgdΠ[4DASF*j9[\02!z5RಯXE *A*k0 Lj\ uusyO˩n^se(1W ;=M+m@F?h^Wmםuh"mi#HXJXvS1}+J`)W':b  ra2Q;jjTw`mĬ(#^ѫRҙa&tKvxG_dS =gNĽ@ʱo WJ\ŵl#}).F Q.S\ -siUsDl\LuRhu٘p8^Em ?4__;LȳM3fݺM5!H%}W(jQ1C_;BZ^݄XqB<[.VkxmB%6XĕA6Lq(}@ aKj3<#\r0#Q9BΆ2&F*Uɽ[ޙghT >ގ@( )ΉrqUsG_?dqpfwh0:F} 053@JK0a){4F.Xn,RKOݏ'y oʠ*';bMN2̵ȰtKڗ6W02?kt<+u~7<G^$4.N$~TI~l ~i"MbZ*[NyF ئ;)z_Mr}u OxZBq4~D*pSIP?F6((=6CRUEYq4ezn'9 ^[4VJhJ*fXB:$CtQ"V#z^+~6HXRX/cNuH;ĺHfTPK%xOSVpS"ww MrZ]\Y%y8p/t}Uiw`]YIR Pl`eB>2:3 -ԅL_!E m@PKJfrw,Ŵ0A&#)``;GL_(=")*_Z."MU3/9œy],@}C2O_;yq01SR̫A\ au/gD]d;K-C;Daf/yJa'Q$;HIs ׳ A{RVҊ]%4N.1IH&,VhP rgIQ%C}_wT? xBb]/@c.tA/75+gedP6b,xbas+pq: ;OH! S]uC7ZD0%ԨO ZT60nc닱 {-6RJgw}ZSHO! b^7_/%0QK8e/ņ0!sq]Dc&HLSkh6uW' z~굫"vdO|Z;O_$ekۓi;h_tŠ{Netp)9I/Xs|-WT/%]s V EfQB 8O.ϒ(;z9)wt^3xJg,on#v)^sg?TJZH]ӕ =T tK#l ~k(уYN L'U%f!0['>߹XA f 9GJ*(8Fj&>eSY-b3Y, m hos" gwbG.  #%Jr?@9.1Y >Z "jMn4p8s^IO]U!^"]6 2! +Mҟǩ; X I+vʅ24j*CBe3RCgE%݆tu0ĿA~ 41EvD6@ҫ:w*__he3daQK )<,T?`Vf5(&h<>քwj*zriV?G8fPCT1T~!ŭdt-t)㮵4X\K-fQUΦlJ(40!vS%vCMRH#h{[}hz RC9̀ p+H 7`82¾Z#)YCWDxOm|s .92Wac sJGtC{2䈸v.x,4.~3,"!Z ̏CQ+pu;xUBj"_*4^톕xKWuP}))<6Hz;JL ilsR]F=XKmG̞r|l#\>ڞw4;T.4]J?Vۈ` ѝȰ'ݘDCy?P8:_|־N+Mf~+i٫4#̩$3>/ea],B4X^-b-=:3(GZ^R!A~Lvn@""`a'8v27`ߓzw-a#ʳN =ܼ}]3.tŭ.s1t3G5OBo$NJPD*uзR#p{I N=w xT#ƢC|lA$!iKpʍtqC=%_dIkӓi:xQJ_Gl邋g,sdc 6n_q D3.g =c*=awzq~sJxtz$e5A-]B'D:e 5b[߿Hkmq+džΧ![)@jWP(˴hUH=ÂP[ Nxgԩ#Z8r矒O={E<]S@f%PڈG$9yo8Cf]No2 (s("r1' q[HXaEl+"4pGyMG?r}<:GQ9t<2ތǾӌta;`J˨\.mCe )76=G 'gC#\FVSeE:Z"i j(GO8{i 2y 5,>xHl)X&WT'>lN%tEmNzBQ$J"Jb #%FQG1<Ш@eSw<۠A $CC;=$up0cCEk(xZo|p<>\y(G+".PՌ,*ZBkXy +_h|t*z~}_ttҴTZF(UԮm@yᴮu vf#&`_uso\Mv/h&ƕURT|@V'Do.2* $3 ݝv'm&vmw+v`v]"tHH;ϻg<9Xf/*E|HxTiËx}K?pow%e"|-~}eXHd9ޮM,4 c6/4|f,l)}|Fɗ\A>*~l#VnGN]Uef4KVo%2?M9F<]E c4գÃ:xn.jDţ>qP .s@2a E9MT zixFjxw۰YwG^m>l(eϰ7Ϟ d 1U_=4ndйBԔ3Ck9OuW0{13P^C_OeKgy3"V`yxxakұ<)@ \O#q^/E|/<>83C1f ;BeHw[4ڙ8>S*^gMxFïU*ۘ+tEVeX99v}no+ =٘gsPD^/3㰼5 ѸE%rURnci٫T]Ut!H%#)iFur(k%/u vLk&N4xiO!,j'ItRe*^4R!nmrc[-P;ތViض}vpg]\Sz}gh-Aq5rђzJƫST-0IR_90ᑧj^rw%F#;Tr~K9o￝aE7mĜG<”^.Zn:gB!{̙XeFPcȯ62r4sbl xMLpZ!'gEb~&$ ?ᖙ)1W2܂0w'\?ѝZ<ssM#%5 nuUXj]Fm*ʾ?W_ Q7NA= pL{yCY"敇z;De#aTJZoD|tQsst5Vb@+61aF2X` 9lB`ows9sB ̝hlDNJvdko>aI 0V0Y^پfUYt-s5˜ON;^[ *\̴ROP)I-9~ =)_k5NtG%E#;?@[': 2"̌3` t5K)ˌˬxPeKQ"ѥoB֙K'&F| N?cXN@ TG"3l=G:9%Q֋r,-Oeg|xVKv>ë8xEw$F>H@7y.揫C"vJy`w1ɒ&\pNFh?![6#[lO!rnO0*3+q5[ѩVg(yRM՜*x1+-:3=7߶ ' [>HǦ\v_˼f,fFC?-7`5wZJ"sQ `r5 R -=FR7$|.qj:F)d=N4lTK;51aL ̍2[gXʞ?]x5U`fJ:.WGGO4i \.y>+ХɎX_6Ex)10͋H4qRܼG!E>=Cg&,L|Sxغ}-m~fӪ(ކ{!9%t<a3y `nB4"[3 ȃR9)])Xإ q8KP Z2k?i/ _"ܿv^'>kp>_ǰsQ: -wQ>& /g=6s5&՛%3.dUg!{ Vq6Cw&V_lݞkWrwfA[>l./g C ngWEkqV uGKx⬒ 9\l ϕ^8@)C4d};,w\'dЅ#6ґezہ+ni Y6 e%tPŴ5)ٸ(}Nt.,^͍9wq LJ+ ޛ|5 ԲL`-8q7ʶn:؉)1V)RN%a-ǨgfMU͌lxg9=jOƩGQ~9DZOsNs+pnqORH#np'cKY!z".Òp=>>ywb}pշ)M[|3n*Y?ϕٹݶ#B. ^ ̀fh. ~~՘ 5̂qJhX׊٫9i*)ǀy+& RqGT+R ]l^έ Vkv*9#WƏ>*~d"9vpczq^`t`5wͳe@=_u`[|yՉ99vj|~O6,e”QP6 wAknafF)VϘAjv5eD>f}TK OM;#Җ#:H{Qtĉ-xB`V<ׄH쭌AT$f[.4S}Xҷ^ĜR;^ȦqiKð/,Th3;r`ox7墡U& ,Ó++ưrl\Q~XɝTk?D&݁_/08  yq|i_,?ζw>=B#vMAd\6\4]ʹU\**_M4eV$<؀x%+m,1awD澷xWX|We6g(4{aFHTsXoWRQdʌG񊹌Jj^G%Jˈ2eE w_5\L}\sĕ5,ra@GT{.։eؼ͛a*{Rvb{sʮsl`6^= `-/=0g .q -6<Ğ{۱ tg>`!SL7[kx|jV=RƔb4<[ ֘q_>cدk5*ı9(Oߠ\}_#:>U PP}G=T>/ Q݀O 8[tyvv+rVdXTNws '^"<"ƆC4Ыje>V%"s`݀6:bl8== 1\СKao5*Bt4o1PNq(~܃ýCoן(U!usZ u[8킌ޗElݖXt7¨UjlN s~ݖ[Уf CFL<ͅ6/ˎ٧ar21߷'-4ޜ [49I^wRqT5F 7ݣxltcN;.r֞Doo?dvm g˰=Hd+vw ׳Whd R3*HcD,XywAu{W^`$ovl2ޖObہ=PfįYuʞZSo;>R3&I!T5a|R3l&8GXqژm2_|Ht rs+,!ÛIXѲZT]+e?+JDH\NQ9Cge4B?( ϑ~E^ec&30$y+@2pa\*zty׼yLm@s~\N?٥6U1.*F| 0t2< Ze`lX*3љxm{+aIܓnȋ\)X)ٌ \^BJs EKMBu*zؽ)[;˘T$%K7&-]vIeoyp}R}z mf'N]SD(Xi 'b^c.2ƥhnŪXy~OlNO%xF fI9pU `Nnυr5`GnpeXcW~p 7H =RrJÀk#9+6/lJ0J)K1yHOĜ0Q̀..?Rr%Β^|GüA/&7&E<9HJQ=ZbAyCJ:E8ǣG8(i yyRʾmhqЅ$stuXGn1s`jo{vXQWxCqEy _9e 52d:@i}~XLX i1F'# Jv݃stTïKȘ'esJ~P3h=V& 'Q_pM*%d1ŽDZ4螳;y.kG[ô'/} ֣Lޜu lޅ=S9ОFtbW(հ[)%Rs ti[5>aꆷxr|gFUaWki#=!B [%YFnĮ:6aK~_ѓsyGo>K=3}k,y1&aH5ڏ섌`F+ǂc! 7]"T7o'c{uX/aOaz1bV%^p.ę'ԉ82%؁[P;FC խ?*^AF2Xf9VpU 睵f$Î_Xt5_b}9 =e4AI[|} .DƺTS FÜ7h4CʨtE݁o(V_}S F@'nM QHyg-13Ȅ+k^eɓVl5Z1EL{҄kyLSkC5odl!Y[W2ڐD*1HGc:ҫbxW(}'žg.]q.PpM9$ʂn+nr: ` u]:،4Nvb;םb^Q<7߆wZ}5kJr mxL.S[194+0\Y\$;pnrj>Oxr/S''<'Wo\>G,0-?w [t:g[q+5%xGLVR{)iwʄ KTKA[!3s;7;og'HwLA/߱=p]9&gX}y_e)X1ѫ@اA( R᪖f bŊ*Gw`a_-?9YI ?l]8ȓ.iˠYLT䬍 aWrO}.ě0k:|@ۇ1(N]oƚP*R]溜#N2@'5bNki3iyȂ>Jy!R}~ң!g3b{"Ƥu͘j4̊GRARZ7Ux TߋCdwx5$²[:Q~og_MΘ;V@z.Gc Z1}QխJt_#i+G^a [|4h1Udcaal\e$͓p7(v&tz({ /ߴ”gm735W Z\ͱgk`c W<AMuyS+U#%4].5ZrLk\kϬu|\ÂR,KƼj(a$s3l?SČ:t]Z ۘ2 JnH=g!3`Z3!xమ>w[2Ps}c2SAѶ(Ϯ߸YU-A:l܀]K{VDC  NHg^Kr wtg.uᆵ. _a? HXE=-Ĵ:eĈF_SC6g@./~*&E(ROBE֨SCJY-a 2Iǩ H`T>3F|$bw#QZ-V,cCtpU| m7g11f U v3' ,ҰmO,ʚ|Gp c㌻X9[\ iI0%μ9d]?GrSX=j`eRn[åQL%bm1|ä|AO#i$to=0(G\_(A |`-v5@|B_~`·giPnSc+]z1(Nj.s+:%OQKi# f!;pMr![=g:LKשptE|{cO gP|jZv,w7CѶ/ާ:,8Ҁs}uŐĆ<Ԉ5L/3eԌw "%[!(eRꄪ}ל"󗂾uh.IrIgN#ga} ifxc8y69-~nj1=1 n7pRtXӿ!x] `zdB~QđgD0G=z'csU' t1㚽ٜ=V&-&3 6r .p%IǴ$\B<|hV #an)ztyM.a9)w`Q;8xr7wN p/k/RrcvQS}?Q$+vh.\kȱk}CBG?6Сh5v'HYd8cWcc;`ؙp6!Fn;+Y-".pںـW]ZrKLy-t'Y*0a2~J3+ǜOq`GsFy*yەcD¾VH C,XNG.h Aq48gllY^ OoT 3^Zhgd g0nCu?GVIfތ PH:o- rd+;rԙ/s\zZ2FmIrhN5Z/Qz%ο@-v>dbRB5rs ]jJI <8|'s|4ԛC{9r-yh1sZ,3YoEҀWWRjYcn9y ^ C"\|7[z6aJ4PmI)"kq@mw IO|ؘJS?4cdj&IiQji)mm@Ph;JzJ ^Q9cq&èkn!dCZ,*ѭH~5:<8Yr~1yJI *v!ciN-\tKoQzyNyT|O1ij?$;dCY g~sڹqʞF#;Sڅ.|?ٍm*!2˲3Tܼ߿ƨo,3~SڜsqoR钆] @9Ƶn gvڃݣ}ї;7{aE~&-zOӇYjOETp&3*kF)%~(DS:TR9mux+܈]z6A ;C1|YpY9˒p g (%L˳9C9+y)tZvP?Fƃݥt0fq#^9e8ӱwlBp,6j8OIr^Q4V%tUQˁ&\-pEBNvbvweZTwpC>_Omp:tCG_% 6ƽ37HI; }$BBN]C_ܘXW.or2+~T Y`w h[;rxZȍ*NY$OK^Μޝxs4a*_NsuEr]Vk3}?iրբϪt6yGP!!xJ10⥉ܫ1x t5gtl/xri)"hu톟C}&rq٦ ӭXB׾1[O=^ӹg^v&n4wd{FZ{7 [I3We)X{E_kvk +8KЫ<kV㨣wThϥ'0>%[ xv!":ԉxPDBzjH^qT=BO,о@(q/Uy4l#cv8dxkڊ貶 +U^9ΙlەGTn7V^v-|ߊ̴,e”; N$SÊd\BL5b]¾B]h͛g.5Ү>xڕ.; ܴS: XYY:/C2tߝ7X,Rligʙ;qO3۲ယ&Tv'!ɡ&Ѹp*J,_Mv5ۣ0\? YCYcbNwV)^vۑY v El,{BL YH'U$eꛂ%3Z Y? y1M} tQ jL +Ì:"a^ 76 يÇ_2~Âqgi-xKrV>RTL,1MŦbM1ƜC;\gk w^fylbNJgr2'F w=;\։M:9s^W<C͋:|q‡?x3wd3_{9YU[jQxĀѿ%XN6帏,iI*n$Oj?ZO&R\9,9H>=Wbބ?qǁ5 ]^ #bk{s ޗzjW-l@uuښ8pk^۝lXlHG`xd)iеC. RP=2bra2f kHufڇEy'{(8a7Ϟ`noY US?˃>~|ރOzpzcjܩɵLt;dʜgcOx?*m9n%82]͍8|F FjCsẏ^ܼЍ]z6_+.ͩBVu^wpgi?^Ǒp]9t.)է11{:0%ϝ{z3 {D|/c,8:د}Oz9J>]xLBxlu9#pfIfmxWs:2T! f=|~!0x #eWqx'BTiC;n_=c[wNz׈تÅBW]zEhHy;w!0 Yj\qĝrH3I;E W2g'֎"ЇghSfmNƴ='&fW#f_cՈ3ux҇ FvkS B G`:jԧEeBNta-~۵] +gݽݨQu-PZhq/Nqk̞yzg/0 u]#N0!ŝy [_lyzY}CPz(XÕE/1q:]`9c ai%VT շ+qN 99oP^=|Nό!N°ht1<BA>su?Zݼ[`*lTXS^^ W)8}/Q[#l#gƻo\Z1vOʼ^zX֊GZsCW%vTD¾DT_'Goxׁ޼Ћ}e'Dxw+<ǴL}ݰkl?X; c teeEÝǸ39W<ە_m3KgWt 5ؐ8 q(LýR?W &3pWݳOsԠjr5I?5=*~˻<*г0S sp7=ehwW-{PQ׳#T1S JbI ~D_8u*ǐ0R<+ƀt=I|κfŎL,qeS wؓKսZq==5F@b'_I8a'g{IyX ֊ѝC sPg]\mY3 )sxg׍\0/Gh[][izk5znE&1"S8EK^8dgEV*l f7 (U$P$.FTX۵!| QęoѠ{m+3:@-J(lO^qiM04A{0w6Uᔕ2'nWSz\ٔWT-ÆX˔: ֚5"r_̯B% +q q-@o x{+z_tp4ǝ|X¹mcJ#>PbFe>ӈ̩ʆb"'1_*b^R侽\J_rO&zyv<^YXtރ=%?|s\1֙m[@']/~Kqkbb/~mX|5䵢7Yxv}4 r-Ⱦ7{h#R>d'34s1}x ݳK{c/[g_y*=X2ډ9ӅuSBz}J 7$RŸ {wJZ*)Tdz?y}WlLTe9ڼTh+'-iz˚\,Xۜ;d/cjeKu^Ct8JTK>LyΌk-oA[2Xܘoƍ0lli?%*xenL3>͌wYrC{sy1}}e߮ R)dB~R+26^1J+fL:yQq]UHmڼu&!y9&Y%Lttf~ %. f!cɘ{֌m1ys4WT8gN f(D-zշ4ns1k c5L#8=Lk%:3\+Ҵ"`!/6n6cC. b\^jߋsO|Z2"043ff=6S34ԡ:Xm@5OEzL82\ϴcF vƄk2)f֫B^^ fP{)o+qg#DzDļD8#VDMEx0TJ"(w's'-x1ʋ5ZsmA?nsiފ]kFl%\]$aD)۾0c+IY#ahJxOw2/vQp J\Νܪ=_٢?PǾt٧^@g Lqg @ә)wbaw9I>f bnct:owQbk/쓯a'JݒQ( !Řt oar?Wr?ekF{tXoؔ*r Fbn?|9[y7uKyާ.GӳӀ:^_>0ݓc,MŻ< yȇs:~ܰnjBxbj y|(bR%y"R1oY*dI>D~R&^*\a''\߮DoNSI SxyLua %X§VŹ-cf=dnǏa+Zq%o>͈o2 O̚2&c.XT`2urY}%ߕ'd9 E x#Ⓨ" v#;X1y 3/)|{=:Jp g`tGhAS##cT4l7 Rdc ^OX wQ⯪,=^~bZܺ T`}{J M?Z 9s; )KXK>-yeN8DB%/AdJp}"|21li_jRvi';*i֞X#13EP!;.SةRd|s)GySy+NHyYsDB03!չm M m>6ܔhŎMbI8.ZkJ^_Ea//5h62&$Hn_ҙ+{5iL un+ي/M;/%FĊ!ofѰ6loE/E^YΠS6Ģ^= _~i"zO<׃bp@ . Tc /o+8W{Jjt6+E,m6#`̊Ӟc,> k7a4bޓhX&!`]&f"U*7$CoT,h6!#\yhŌ=!~R6+zc ѓJC$6C10ڛk^Rͭh_duWS,bw~č 7F#}27SS-=ئN ܦR&24_m)S+&'1V,eZ<xM9TG-{7Չc1XzC`Mf`\-Br(*t\sPNpGS.9ygz{t8ؚR=u)$\vȓo{2~[,)bFLjVɈDgodGw#6Vg}Ζ`LX@ 4|:y))ÐߕRh5V0SLNyv޼~jߗVt_wixڦc?TൢO\-BaК^s UCx= 2q[h +jżO6& 9XTl\(S71'h/My'oKsś?}A~XH"1{}ƍ;rX+G$]GF) ` )Kqwjd`:3dfOt-`4172{% =)_Kou 7Ŝ2L*d!e4'v G={؎kgڳ{68Z21 &O֣Y8[K]d%LUSn=k??/a3a::9h1_A%-Ϯ# 2+nB6dКRd0jT,E2 [?tH=sC? j#8+Dy_1/$ޚwVbA2tpc?战oK E;O.)b.b_R7IJM78?ΔP"g f;xPB'\>Q\[q".;ݘӶ..E"\рGy XjʈQ.XFF7h/4rt!{R6]k$t{'P7Ʊ;$)6r(pSx˵\DzΉ!mϟv\#6̵`k3FQg*5yx^R ש XCi0:[a> q?E[BZEKVҴ-O_[ѣK,_ƙ;%XvnKkUXE‡q ѺZ _%syq3u񠿢^^le{S#KBS+ct)bP ,r@G*;%g2v nwMY-` _:= sXH"޶ra%w.:琢GNtta)'F:V(fp(WpapWg̕lyJjǣAV|3Lj%]\;(I9Z|W,VM6_҈t/y g%ᯌ.uZk?6rYjS^!BL--"h 1K`?8?Mרqz94 Ŵl/3eM } ,GEP;1f2-^^<͛&2ɒqqi 6 :\1DW"{%spMVӌk+sSUI=לSXTogcl>Sz3׈2p7VfK'pc]8Nȅ\,#.OT?#zo>bnlpCnIvf&gre7>t^3guc;sW+UGkǩ6ܻ֊w`A X@?}lЧj#F}?k2i VaH؄9;Oo9㯅:G r: *vdb|Tdԟi(V MgۈT>pE;XSg)zWIؓ~ZZvh/.wf3; /IXщ ٴؕ\bO v.ځ8[ւxos\;oG,ΌMca %U跠ǻDGx{c/%#u_ mBh On3l,)*ŵx)Q` ~4w4z{.*^tY?d*.Ү1֐bc1eu>oա";{@cfx}71Xs)}fB{qԎgA (C 0fGH7Iμ~ә9[B&LSo'6(\ƃ]% *0gv]X)N F4yf 3u2f)q}[0;@KIQksLo?[\|Mq3{:~~i_lkAj)_&m4ԚWo veJKXM}C33a`? pbb$ɮ<9v> xr/|5f5^^\nnBEH9J9z1cTUS\]/(:sTصD:i_6Ol#Qh1[%UjOSQ I$Fa(D]6[r0i#6fxsLE&Pe{σ+ X|PYZQ3[-o]3*]ݷ]8N.i]#8j3یup íMTƚp[)wfܜ3sl؆_oO[|znĞ던r:&۷afϧ1-$ 7xC2:~1;ZVtOs#5f5ow'm8o9(Z+kؽ?ar6?se[{ϓ.zHT}*)Č[elBk ?j݌bo*31&C0:;uEjcp£'̬xC°&Q/ B_ۃl觨=+`e+61̅J;XLEB;ߦ1yŅ/=땐 VRŕm(eȲ<ΒόS1΀-}swWT|ywQl_L2ퟟEZtM[_ʤ:?u]`p9LAzX%Rn6ďW}˅\9Eƭ8M;J᭷#em!Q3 w^Ɉ^ʋG,p ObE 6+_gm*/`d|TDFThF:dPD%X6#@"Ḱ$CPJ}^ghlLLDt lAkMT'7n2MwNlIb %OĝE *b@B!-8/u[RL^Q//Q<[ jtٷ^R )C̸97Z4dO}YQC㏼Ca-rmO[b6&c]~il>O*{ ^n&|yAp #z44!]z 3Q)X#UIT6 1ԃ7[M>JIi/I>̾Vay%WUJ&Oq%6!EZ):|S0: ׃ߣ;1l/SFyh>UΆ>cm.Dž#]ȕ#s?졐K&xRL \%\JhU9P[M9#7.=<-E*YL2NYeIT^mҷawjHy^3]E T cbr6;(2Ç4TwN}nVX">lNk2+fm>P"Y |h_) 8Lϖ+\f#waPK-QWǕ?Ձ'Yt3ng@C+aw,Elu;20ӤJQ:o T9ߕ03W8HM?w4_6Lr G-c[aBhﻊ L@"lȲ;:ۑ),(վi,Q[vlv|9FI:ǂO1"z2}Fz]1;(Ix?XpbmJc8sҋqdKV$EB/zWbۚ7㙁i 78Dˁ<{E&\UkM9ӈkOqM}IVK娝. mR! xBSH p g2g79+Ƙo4ΐT^?Dg"\*c6=f:crR&Xf[>)FK1P?/XFeѧS eQ1V\W xh՘Nj */D\SXUnAKe;%pR9KMabƴr?Sr؀7tiFeʭOѿg7xTiRRqbPn6{%^*Ze.}YE٘p ͵ \’L-wf̔0)q;]o,sd=W8]Uz)-1<xL핈zj)P_^J|܌^kt2j|>3؃TŜYL\1>"ؑ{چ[2-ĘWÅU3 p%I0p ΀oQ9Ugt5.ڕ2G|Z}*+%^ƟKdi2^P/qd$!.vf4WxK,^ ? žs щ'B.-º3ǔ"t.@,L(mI ~0ThX̯5ϟHtK>T5\kgܤd%s5vV=--f"\-bgt2_2fcb|{܀ߏThmQ9:ƌ?N!FWaZZt=UӦ䲢u=hw:^K%ߓ5KFeܩE܁85,5p)H_!^PI{9~o<>=`1 6un*ugYP݀Lc~L8_f1F?C}譜'l\ Gx_5t`/sea5*kD$rwCK_SEpJ܈(88Clԩ׻WokԿ@jmWfWmZ8!EG.%KXtt[1ݐ:P`|?MksPE;`)[)O*L[R`ߥY7Ru w^SuzSR,jsF\$3QP/X^ {5lCWipoIh%4b#M7㤜9GJI ?*y2߇H8 ȅ~Y eFF\]g4X(%|-PmCSVj$pG=:ř5rG:_5LGJWz3z1,'~ēǏg/@{#G&*B0  -H)rU8[+qO#O7XgaD>}c\qV-D7۶\}[t(9} 0ibX69Rk8sU*JTWף2k0ԀVyʬi iKBFO&{xrZ!;Kl1P>P+G\+C7Er5`F`u>EY\>Ƅ}Y0iexH3gxc3t-yՐ׈ |8,*#EpU%fX &|ĂxhSdF`9)f#}LM>jQ+[p氖ߞSz}WM@:QQt;GӽYVCcfk|^^ /LHV̳bq>tYlP+7ڕzvTT٦o23{\~ V.^~noQ/>a3irL=:oܱ Ýxr[w.srd̛xtvn~yugfÒ?zS+1x/D:|ܒ64j2gF cZXQ5^){&gF=ugqg~hyJxt'jC22nyFBn(EU kPme`zE.I7SgAm8d5M2]˰tV1d ]"ZB }c?.|ūlV:zCB}XƷ-Rf϶Zp0FFM:|c : E vWzOM֌'r%QdIY}3C-[5'iv۔+w>>DL>eō_uxq 5* ޔAo9N]0V%\Sbz~.rIEӂ \X=V旍6ҧӧx4 ~c| o|?~-(p;1jQ3`y \_aw*y퇪.c*tإYGa u{2`%K~9Oo!Yz'ޖ &]7! smF,y\b_a~Q ;д&6t2T5=N3Y3$ρm\8?ҁ͸yKPh\\Ghr6%q8:%Kp{=ngV,YW.=rA7Kq恼UzZh_IlJ[ܨ чpd šu/a*Q;PR>Pe6kqHSTpa_4)1yܙ=օ?},9Έô8Rzyu,Ӂ~:%N_żXTlF}շtht?gƅlY";yf@k8@]u;q$cP  lL5ȇK0']w?qs T+X[E({N4'r]~Z¿랶W~jjgI850}nj&,UktE۟j<X&?pWϨa=I m ث=mh3]1ߵ# P~E`y/x. 8ogiQPj/ufM5(~.*q3VGGcؾ^<5oy{^!F1-Ldff" ߦ 13z'%a~:%}]]P֮kF@T5/tL d:WS4m(!jSc]nE- g&3{ѧG36ka؛ {2z/7Nyq0j,W#oix&oVy#-@#2 6Ԓ#M9&'5q>;c;!Y`70E)v8uT߁fq݋nkvqhYXV6.qN2u|?6-_P]M,4Wj_vRÃvPynVjRtT88/{ZUO kcxi5-͸\"aشM5ᦇR`.Vt GjPD=1[ϐw?)o)^لbڹ8.<ä#pC2F:d84˲Z V7ɔPҬ?nĂhOs75;%7:oҶk,?7sZX3Cw5z,A7WpePR4FNžZڀJ,J m :1bs7ʿn؄-/&i5Ekq^-zG#գ1eזoDxux_1c,DȾ8 Sz'# _ϑK}틗ݔgӆ#:<_.fأ"@sWcrng -?,9"jn1Za5PտNCwD揯R\=򐹧 cMN3^ƍ4d 0uּB4 >jya>g}gvg"އX\TySυ&|XjʶFtkȯSLx3ΘbNeX*|]#!{ucf*;{|oʕ~B hJ]q@d4_Yu#Jx܊w,$ȷ5zY4ɁqB7(3,L]_͉K&m^ڬɧ4&Iߗ54D`շ[P[#o+ebɕv8غ9@lxI= g-&b 3/fTu)~ ͼ lMf+%>P?ĠJع&.] HHh v ɾ.{b{WDEAŮt"7Yg{b0'O{}%:O9LEk&IΈ?|j濼MJۗ.]W>c3jZ 564K{۠=y9zϲQ :5d05 86xjey.,{OQ G>fcu,M(FCd,}+Y'c'Xk֎d8QDTWCəi:6?u}B#kU<Y !]p#WҎ1>(Joݣk~G;ZZ*=gdhomgYԹ?;Qц7vaڨ}Qb^Ԯݿo^bWn07"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?mw5鿝-`ۼtۋBa3MkϿ_iz5heaUsTGnb'^ޫ_7YLN?h]Ầ>߫6v+'-ax%) yxW\~`}xgS.T6rh ѾoZL߼%uѿl?̦7rph -v" GK6,Zrgi |zaK1,x(4^Wa˚hG{aMg h5ogcw {u')u) [hȝTTRVȏ5!y2iް6oO8HH'%ር$ I Ђ(!q)>4zuzLmm.]i40z濐& otc> &7cӜΔzeՏ\)ɭM![OSH>\NfӀ<U(D} MmqGQeu 'G~sfmyQ41FRp7$ESم^ >OS}ZkV%NQ :p$ap/id<C^* rj S:2d?ms줗,%,]N Ӆ#Ŕ2vruQ2u+&|_up'M*[*r 6v\υ'DݤPKK,1E-z` aSZp_r% [z`H+Hea*;H.怯}gf%2{^0Oє!iO$ڲ C]RH0_oν i۬^Im3H0t,_'{!RiȲ :%Stho\ߟv8jy mYa]?{ @V2‡4id ϵB3c]QpJ Bpb5]TF%8ݴDbMln$cuaow=81DoɊ]=EyitC1P[Ҫ)-YYT*FηO2ĸ{~ #Yv!Bl5e *[a'z%RI+Mk" '`r!u+FwHjTGI;[ \ MZ<솥q'=3q!4ڀX[a?}O9O;N#]j3T-Rye)>:JQM)&\OU J-n9O{j;DĘ*Ғ)doZvb)lmҎ'hSߦ4]k2?OZ.tǺ4dE$} .fƼf/8<3m8WMd傿r1Yn uB˦ɉtG5e -){8[`qСFK<`}nR"7i`k:;^`\MvJ.ӛIty&1؋lh_i_ThBLP(_#!,= LQ eK m1aG;ۼ!`)h0\zK=+O7cFe m[G#rQE\^7,vX+vgz(81N(oW<1 =\"842Vc'\4d&i)Eeg M̹'A79$g#IZ3lיḧZ;-]E E>Ѣ! GuN%H6#mDco_Nc^" j:i4`!iGCJItz_I'(Ԫ^!【&8^̭Cqi &v'^CK8ZmPy~aϯvutzɩ>{u*w$׮ |km%H*54rO5WP|J(xuq dϼeG>Vu1ݼ ZNcҁI$m5DK7ǎanT-47lOΧn32sC/G!*GoݢU}o*nA;zc cu "rGJlƲ?ɱ 3||=ȅoL]0J*|3~!Ƙ:Z;$ TY9~-Vi6hodսZ|pCvXcgQSDs;Do]N.)HM[bl,.`t{C7K'Yf1H"썢yGԲ44#czaq>?SvB2DY) 7!wLW{U]8C ,w4rwܿM{ l;dsBE3J[cpC5MY@}nfSX\=-*_jRzs챀cvxZ-,Beнsts*ׁMR(:JPYvjymqSd:r};vmC&mm? gv>j7*Qe5:{ (&#HuId!=EO Hȫ|~!5G3ޣY^,$US~.EKZ`U'T2c b g:c?uǛX_%Y'BG{ax$ >~q0w)*}Jˆ&X=x~Q?ea!•$87][ Qa>d1t%5p z_E % _.S AupY2&QUڱ:B_y ;ng 0Wn6Hٷ#4T-Wa_R,\I-Ȧ"-p~b}|ҼS DDM87NtP8OkSWdXg&rSDp4$\yR"ů4)CE0fV(jd-Ug{:x,v~y_h4%*nb"x0IR;:0֕9%8Uin` L.vTܵylZ*f) ;&W(D)ɥyӣ;qz㽟M4yOC^WTݵN0g7I5V:;d:s*:eGչU]G+Gk5Ư">98a̛DȑbLZIPDorQu}tn.GkDP{8l8T h'<#"@kͶD).gi!uE vS4%%p2PtK1B9g16#Y` ::swLQCl9-el<7mf+hr}!I?up2=k 9ǻax5Jzq5Ut,'}%4Q!'PO;$_~NotqQCȡ)?L á6ԇӥe^FYq.i-ZS҅YiV)x_a{}UǍRDdT Nk9RV*tBQr7*)RE8 w^Kpnƹ S%@DڢҸ_[`5Y;wblnҭZkz E#F^I45g-Q wHRڡv¥ ॐPA:|ŵLvQB芕z 1sBsRd9.bg9,vie K-KG%ѬtZt#<ɢ?ygӰc9T13W2v=ec/[pۯ K:)E7Njt};-ʳ(tG 1 dvnܳ[]uCF2` G/jiв8 hG=pY %2qV#:))9Kbu1LM85MPGaKkid.V} >̒,#&*~~c`R\4O_@f͖zZT Wk5ڵ+k&ှGH;48A#J̑j9Bc(X S0EN1kdʍJݧӇNETfVHהj!1WRpm1uP}!yt(4Dc\\O c'Z*?Vi ʦD) qfjS@3ABDͷA%;\[뎠\{E`XA`%ZUqdйP#d+,co1:&PFw' Loug}98Z.(sq"m^tDMӲ+ܢ5yz{=~B޿iEM3X`B>m1ow'QT=/Rgl@PT0-SGƌߥ|r(Q>%7.?;qC*?%e9ܧ, 3fX ;.d#L>/ÓǦ(_D]?s6oXƷ5<)<&,)8LCk0\2^0=h9NQ0pޕrP;nبN ^Tüz gvhQh+p+JBK #<"Q!}|ګN"EoH{)II'bO$ ]BxTH#O.VwF!a O8.X!c *tmwp16J.W^0-5Z+_DGR).fV?-q;:j 8>0_ .  њ#$&oyl3aw0<14EhG!=(AJ*mϡ.PGuj;6DhVP]%U0[FV5~%fO딈0Dr|V"%JܫQB2\-ƜHSBW(%Be:|{K91_Kcߐ[:+=8H RT =>}nѴu R9LoЮ6)wKST/hڢx: NȦ/3,c%J8k8OƺsP qhrԟ3ĞR.kiñlJi𘾹_jz4kXf^d]ͫd ov[3}Tg#S]D[ WKvWo/MgD'(љ'l^C|'-&MW!@_4xWjoD޹b er@k3-r5XFCѣ Ip!# [IRx_4:4vp-e`}+qJa {[cyI'k[b_%?KC?x)@GxJ4H!%b;0~|ADĩ1>PL_!nNw6'л4?*b~wTPQ\O)|-g4c8L{O ҝg†XۥmȒ}щ^t=cz wW7;T)*~w2DWxB/pjtH/:2/ûE33ohqj5}e~^G{\eQ(DmL0gI }*_!B"m[=M7-H]B|%I4n*[ "P$¸z)˰ {Zsr!k(o%^q;/ ^u _ 1&ܪ:ZWAk>ai> X `պUK^;ix%Aq#O|BÖFє}I4(Lht?f? z~ϜAJ2cGMD,K! sXcy.H+xLzlM-,Pz<KFZao mM1L* wBV\gT`~P(["?~߳@mtUFojEVL)|j.±JuS!+Ԙ"DzB`;7,ckc2T;dXaN^ShtF ~02$aY4|rI9M36:_I!UϷ4RD~4;,eQÂTjle^lSsJM{Z]Ƒ:he iAŭ2(o:ðV 1wuq}_A.6Ei֠<ȡ_n|yTRdS󹸴*{x}\˸Xyɡ'+Jqf_x[7gn ڗXF+$ Wyh1-(5Pu>"uI@J-4(t*]D׎J̰ +sCV!fؼeCA -j^O+oK>J,wǺ[sWg=do<aAyUיwX\S⸵6v7C(㊩lc:,اrP]aQ熑Oeo=5hC c^ʖa)6!W٢55Ĺr8݄f嚰 o;8^ab =L9p0uSWJOfk}ϤvI9B!/TqiR$0~qfZ}j]U\fM[)qi`/Ǿ3VYF}o"H*4gN|'Nt:-az>p?`J (HOzaHZ5%5b-q ѭ;~p8x=$949ʺgx'XչsAp >/<0lFLJܐiqn| hr :@*Wbl fQb\Zx`~Pvwe=Ι msLޖXPE 1ۘ =kO@p6O;r}x,<ÖS}O$|M* +hF3xYB -I | e?{CI]OtHllҢOs{Av?+س]< D0NE -N1j*E﮼ǴhUZ|o$/rr>b.>:IŨ.=IT( 5]][m8YX+K 0t –&ʤqr=W=:[9Ң pxA .AP-yLůb\6! B&x.Q)w BC|Dcxx5ͯMisho/_7GOZPj|~/ȔJ+-|[-ž|nK*ɶk}[H5UcjM~PN9&X0R=E8=<| md0>Vm/ <1L0jNVc9ֹc+rֹ#0 Gl4Y -m F$KPpmn-]tIM><)@|8]ke g;DNiц,..9 0⮱q9:&zK"tW-}jkI~"v,fa]fg584tƯiЂN)ܰGkĘO&1f bS{h!jk1 ,vĜl]e 'V&R׋o|Xj{ z\i2Lu.Bo.װp/?90]O+|IMQe}m#E,{.m* lAw~eoqݰ G_M3Cm˒#X'NРt-x8!E p-r3wrEGoW\IrLJnnX_Qvb75¯b2P{Tu</.ߨx})i2øTP3I$0L_uFXK:XJIEӌ5WR<Sƾ&HC@Cըx'CBl-La:lc:膋7杲yxK'hD%~X`Ej5sƦu' )4ǘL$i4e~{@:ܤ􀻔RV Jp-TĮytC&m9RB>=Mq+[Lޡ*\ .Sa 3<TE, f6@@4׍1vUJTSnxc#8gE[[m <\DsT!g=:0&\ xXs8ہqJni<[\'eNzYeOSM$nO["r(.TI7?,B:x,_C=mcii^_ 5A|x7fhr(*=kCϡkX! ġtd5MOh+qvR^S,qo)L&ʱ+z+(C5Ƭ$wנp l3i4@~7^VS ‰:uT"/6u?LN[CX95t3 \l8g 8?&>ԧ)pk (eed-^|\pک} cRRpP$|FNtbd9q/ܳ% sZO:H\K.95.Svg+z' 7$~Q` %JdS"48;L=b-f,arO x # ѵ0ZF]'wI(V7zK),vVƠp(XOw2\K K>-jzFҘo"ht j5~RgEP hx 8xg6<Np-3<T豨!D '^fw 5^^hL8e65.6au[H`h :CQԘd:y4 ZL4"]FS߱-)6\@,>?10Ň!bJ0rl+t#͖#)g^6{u)5B saJ[BF籱zg-vUŪ:,yħ4UbG%T**U q.x2'M|^?埡-W%~Q,9BGΥqˠ7cOslzNSG g^qtz2.4̢]K<&oIsSj+yDoXq^@)1Am g7:xVa-TEeբ'6\RBOLQ1'yxsG# !p\0-}ś(R^LoRI^ԑO~sd^hWh0)N6ݸxߟ^̟q%W)Êiø8ڕVH"1~_n8`d6銛=yG- :paq5 n#5t}iF^̟d{04xIҮє+W ̊e55G=XelGn's"l5և utb]p eJ<¦jpY4r@ZcIOco[/G2(K1j+d)sR/U8G:a^eEg=cBJG06M&s,;)ߩN%gQEEhwd>46>j?u76a7P _6޴|5}J(/>GZ$}+CcL)(>zVF8hiՎXb5RE{|NjQ\:4708_/ Ray M6hejD70&ecygT_y:0$J3|r8?X v8g+kpdR:8`bE[[sg2t+ΑjVQytd!uRJ'J|b1S9VӤ\Stk,߂Hwc$& 7o+3Oz 7&39BVrj́äZ2dәT}ᖡlڲ9FuNAđ忱AU7ݹ;;݅ X vww&- ]<k[G\9za z #\mNLHЕ $lPq %MGW*`4V-5ok?=7始T>ݚ?,mn~ 7$*o7Ѩ:~ &pO_C`̔7&|ђzXpD3je h[qu.- xu5ZS%,/|uEصlԸ@Z ٳ|9G7<=y7ExYѤ:ON[BO- 9c߷%_=G9v9{̯2]ͫQ{9 7J*,xo!m~]=Fe䢑'[nB3s>.%jukii g>Z-!CKj6Ŗt٭?WbR:+=ZM?\tK^2J]cBw!׃wlTƻPc+<5Ⱦ4qfbCGN*6J vr>kqIkVt~#(ػ3;rv5E* }_KŬ)72nܨQ!}LU /.@_eԩs&)󌮌߹q#1k:\#TЙ?KTĨ.2M2*ٞ-'[1Vvu_h\ '1`s\Mҧ+3miF6ӎ9K;&8q!w mgtngcv0^Ra.)Bϑp%3yJD{9tTכxr3=h-c%WJ3cJ 3wġgu  VRa?,q)g#Spc)NCT4E\g[čGc/߸7!WMzۡ~_h'dGLSJhR@r .Y\SPdc޻Bb ge,ۣIOQt]g|?ғlffpER> ֝41Cx^lcJ*sHSnKϚ)9XɊ δ/cPhR̻$,r%sr9S%l|ݎ͸'L*a5fxy# 2p\ad s3ciKn}gŶl}ёϋY˕SS 'k;B`לkVf.M%}{{) $|=P%y07kzP+g83r^<:.Bd1U HW'w qU K E:p@!FxB,)ChVbˡ K*kFgFIf8|ך+L9 aQߑ6J[OG^"o4:h'j2Ba*^w)raQ0n]>T[28Ğ=mIk*:bOl.bDxOTTP珜#1u糐ļBFrfQ\sY)= v^@˝mh̆}F=T]9z-KQ%K3Z$k3x ksX77F<9Ԅex55uB}mG)xMn'qE5Yb 1G6E]ۤ q|3MgRQ/3=vha~z|Q۴Wn?+ɜSڸW\(v0+vS=1?LSrTNvl~RpX}XN*'co;;Ѿ͊1(;V\OPCL*9h-Ց|`&9P0ÃWTI]&#&اZBn%gX9)r~-Bfͱf:l sѮM.cϱ\=ƞs>?_| m.Yr/"x0kݿ;ce)|ʰVY ݕ50<ƄGXr,{~M"ֵc-=رfR*ipA:20Zs#7Y)V 7ԓ}dlyŔ_ +3 [^={2|9P6dMP'ݕ&gO 8KKkc% y3}8z鲢M>?g#ed;k-+l <5hƬiگ7t5̳>D5?MY+T;?=D_פdˍJU#Ut?*-P>'uWzaWg+D)į2{!e&*Z7dw P_I}_aO%tjokɹkƉR%an)t6bte=ڸFT$gbA*|w8bV(MWW9'gr4%min`}F\&.+S0y{r^P12eʖ'0[觱j^fJLPa2%`5[ɀ]*~)p#VbbR.A_9m.yMجX,`3<񲥘ȚAh9Ή&;#p͋.&WqydOKD;N9;.]cvbjZJyj_O}WBVxOͲ"ʍLd4f!圶FɲuJ:JTBIe*4SSCε*~FJq͎a5+S:ϖ)xvO y2]8œ݌1eg̶Zǎ)3f,<\斿`v4wP<0GYy #,,՟T9M?s47ה>ۊ;g?6\26l?ȍUetH`/ ~U|K*QəȜK׽h2xhK xWu@MG[Etm'lb99 WpVIW8ØM ހZSj,QZ0XvEWa>>|Gh{ .@&ʟÃM8t5H{L5@S6:LbV6Nj]UhWR65p\QP]'ʠKb bJl<yW`)^~_^ څ[ dSk0a~}V&L)We-,e :[/5zvOC&A7 VկjyDڔU-nx1>P!/`0NŶaj>y={zqpM/&s!ZD{bw1Y3Q<'AYR8wz^'yxʝ_Zwvs7È;q.-?"@]CǛ{9qrOjud4̊gG:Ь‰"g/%qQKj'tDΝG=>mAS'$OL{cɱAЊ+ϷwE`{cq߭pTh<^ɈJ*)يW:L*/"q&܂8v|Ťc ·+k#JEl-̌jPv[2QvuO}}b52iB?$/(rV"h@%~Q6帹Դs:ͅõ[MNȋeg°lָTW/˸id+e(ZznO1䶌"sjzr2,LGc@dRoQP4 kGIaݙ͞hT"癩r6ȗ1g\R*v߶\1܎q4-ZFV loH3ݟ-{P*3pDi`s(EƓՐsl;%xfƣ4?T. o=?Ƥ _2!rq)7~fLm"b^ܰ ?Wή-jQ懴 eNm=ƭ12:S3+XLFΐӡJsTl@5\!S[ٜs)~fP$l ǥ(l[/+Q W:0k\-V=9 3;g8I̺bq;wrCv֒Xq)s.^ ݄dBTl"K-UՓ[UtKSf'**SfFA&Pu}1bd,×|C yfB;L%0dd4,C y@]՛k>yw/8#r6RT ΐq@Ok^f:={ °_=cxj.Z웍-#x ?G5ю}^c4`\%bZtωٝ-ҝvh&w2͒so9gyU]R~TTlNjƫDMNv/R񼽄aLxaU${D^oZo_nq0x8z }q/nmf8|r;PR]fxox7;uzDJŽdvc.ҏfW4 OȰJŦS1;`+~󳱾7lAFyX3Qwp15`/ٯ9k!.WHC;ǐ.\TH/ kTo`;:]@Ky_] 0'bIA>"/#WUf%yj*Qrڈ&r6RqJ*Gy? cR4 1䬢hϝq:|v:| ;x<<;FL }h)" clA*.WW,eQ3^Bwqp< =["3>2W(R0nXXBDnB~ׅF%ou[z(yĝ]-e3pp<X$\7 'ש8͋;3z FXO[))R6֞t4dƽ͈@z-瘵N E2^89bzA45#^ϸ<zM0m/lߕɃrpum̓ղ L{a\ާ_|ڗhtܹ~גG-|ga}6|y)Ɯ͆jsGbD@ҢzV!D &+ŧxp+ |?mqd/컙ƙc6~A 9w\;M'zC¥kEm&Ŧ|=|R6a]Ifډ0tϜE$g'u@k,SM{;&YFA _*bǯ艄IT´+Zslc(~RMV+\N'2$gNUܘ,gb,&e\Ŏ|ZKxu*Y!8D(Qs2EȳoQ1 ^?f Nj jAJv7b|σE ډJdBY)f3;19ˇU <}ajvC>K+II~"^ b9# w38*hMfx0۝fzܔfʙlmtkZ7*n߮ϡ y13r>l9NFg IAKœB쟒[3é>Mj0e)x*6dJ~dhᖭR^?8[nPI>FZ<ӈH;uqJ<0Kf`g`gG#=aQ3UZ*+S|23YYod\?O[u":^ʥ*e8,CGJݫO/%/+ 0AMrN T|Ac/'Gq׮DW8y^-#01n*] et΁ў30Q+݅WgҨCԐhRA)bW%W`lpLMXo6ZQyP嘉DHmj'P7T'k`u ؃:3zy! Qg1VM?H_\C+$ޫw]sv]̵WiiÙIV|ÚO[Sʎ?rYh,<SpXpC[#t7G<6bY)U-p3Ϝ}7%/QT WqbizYIz9gyXfW_!Gd~OŠEPGjSgYڒOsiLr Wdt< 2n&%20ɍ e,2IF d(r.m~ 9$IF`t17A82F9x.._ I0eJcS9ȝQG!Y56'鑰\u7!5gĩ'G;v%ѓ+y5oz3"(FJ>Ujw樆\8CN:W- rI f%x^3-ͷ{ 'dqmvQ"-Λaʁ~LHNQ1Vgy2Xa!@ܓ9|~HAh/@`a -pOJ"To^ ;@8F8[]d0]8ݻ`?|㋙Y~i?޵‹/˘zҔ(y*֋y_Mߛ-^d%Jx@JT:%+p[aCTGWa3;r&; 4ڄ̹Mj.p*< 碳k CN*%/6%jnWQJ3<JX\ Ag5V$Z)#9 RmμehNJg]Ɓh]y`y of 7N)0[*ZF3zĤL5~6vӗGX4 =ݮx# Rq9 k}LXJW<%K-U<2X454Ur:EB)BqoEo/[{.tvc|[vn:ڈlߜ f`ص%az.>FU:l'0vܿԝ*ű[=9̃#dZ6bj:Wz 8]\f>Fւl9Ӗ* GQvō \Y wo-+}6]V|NB~>w  :enPuĥ=M?;X0?Ҟhjl:Q(t<ձ1| K2j/JzHT4T򢮂^̓-Fz𲋚GUjܫn.*% CͲJtUrC]a=;XxZm2׸sYWrҕ.,ܷP'Et!AhQ{85yKN߀{CLù.ߦ`}ihB\abY|cyy7˺:mvA=|toCmy ;ZJ8YƨRޕO9ۭR0~=Zr&oR'R4AJf-s;ox #W 3|WLeL%|5%$rN%0mӢ٤ GDͥ <u|܎olmY‚nZ2|-{%[1ˌ3sSR3FjIOqcFjEczfxDw4!&0m-ũ=6 /@q(2+6F|wڊΜ{]8Jk/2G#54b=n7 &Ôg+L>ݔLyDl{ 9"N7mBIk^r}X$?O^.r$9Z+=T2Feg,%{+we;[vcB_&j1$]\1=)$f4ڹԕb`O'|w@g(N){"mzn@6op_ٕfkeɩ1Μ9ȑ;SmĊoT-^-vr84EK-~yH hY /pfmWY4K% v0V]` 'ug3.,bwwv>/!C1ʼn8MQqR) t pdgpd1{2Ά[qk>0l F8ЀvksCmبCǛx\#_~^<; Ulu߿X7;Z\tAl9A_ 4fPźԧmL5_nN,vWzGy%HN"7rwN|]`^.Tf05k2\\Cd/q7Gƈ+V82!ZD.xFšFB"Jż/-2 ]lG':#vbKiN\…Evlق[퍨C1Vgs <רN!wgHS3eWlgMx.}a_oUSÕدWuTF- RsohrYĺbfm0%.0^-쥂3|3 \%vn".ߴ.pe7g7.߸8U\ʼn9#~gk-Ϳe |cƴa@=.답U=VCkH9|[ [hUi4A+II^4svEIsn;,xfUhpF8LJ !YG3j}mxĉFx`3qK"eᥘ#ǔ"[*wWQ#g"r7lS9͂ Y2r5 Smsхj;#BBEB֎&br Og38IǞ#|x#?rw;75fuY`-WŊ7I13 83Őix|-Nmqb.UIyhSXkޙq:Sb ]bZǝ2wѹ+vѓ0jeJDRw$G&~stvvdŒC̋81ro>U2Öb*RVݫIgZ9wVq}[5o~.1[-G&$ջRRaЏץڀ62K1}aa±tbx&qdBnuwvO[|9̐t%O&Zλ|8ǝCə["gμ;ڊUg]y:,\="͔s9ten<НyE/?|o/z̖qFZq;'tvvaηѥ'#ҿ&Y0}ۍ_<o1ncs7]ҭX2FlI̙ĒsQiFgtN%C¤h)ke-e&R+֎X>Wݮ?躿WטwLF"/U )]WDl EvT6uP;F촦KJ[#F M5Nì5ȕ`P5?DN\l݂fl(=`QfgבB{B3p*=9=ؐ_L4d!@{NQ̢^.,k;DN3)gV"0O v˹rnm 4)}ֻy_{&.6{5HLBu1?3hlÌ: 7ʍ2DזQMRN"".taFvƆxЖ M\[a>`{K ߓ0eZu|@ű1h i&pݟu.o/Ksmscka Sƨb&vQpe'l~7%JEUKנ= Ύ7٣#?9ƝQlҕ ^995ߜX 2ʆYq's1gQ}U2y*TqRǦS6=N3mB_vqSǂ5WMne8F3T3t΀sz36ߞMؑ\8"ڕ}*:X½lXg<8K?{(}{v}۱vT;@QAQPns眽>kX<'뙙nSTc77;8z37;6X}\Ԛ99̙yI֒ۋgϾ"tmoyܨx=;gٺPiv~ xHOHuc&'n 3֫=]F ְ cC>`^w,ѱZ rxpR%?| 藴`O:a[1vQO˼μz+?~pVZdm@u-'*gGEAB&7U_u' RUX,+spvхpb5@Gj^бNjشJh);%ICY`I6ti7}a*(~wѧbr" ?=И}kM3GnpMA߿3/bNS?ٰ֒VkޕxyVD -5A -K]mz^/:7f ߬jw>FuGN|H !C 3lUݖT|C<_Vk'6Yϒ7N.gTso:#WqfgW޴rgRW&n1qojd`9MrgJU`׵|toΏ m4*`+TZoД6"KfcvS\ N,;N?TTwNK)&S{9c-{d%fǠVqx>?7m- <1ݙ=:q?yϕb<'vkbcGvo`G:ةjy턊=ʨ4;˶e/[Qf:u+TF|yxjv-WOO=!`S&CrE9ŗaTFEφ_4"f}b>H-Vp5/%jN 3hG1h}yO_>^Ջ{G }ɠ&t^gfDw&6hg@g$wAe,9 _A6(GVIFuδt0FgtgXS_v?shx椑S VC=vS1bf\ٚ7W] d->}:ɦLK]K;>f!n)U3EXם,sg+]^ \.Ffͯ9'B[ÃX3&J|q>rJ<Ƃrr#˸PO4ڦlO/ta<"J},\Xą!NȈz^R:e<'{;gIgV摇./1yX) XW?TflmţS߱ۢKC9d[q;kαťbvj GyrߔqQk%-ԼC͢Z7&'?uf1;WߺV>X!͞; |Ac#Fd:Tl`Znẅ ֜RޣK{hpjl}aZ,d]MKix3,x?qR)ɕ|TX'*ֺ2b-˕v. 7ĕƚm†ŀz0?@uPD"Z {|w~W~=tzlc` 7RzZyG$D\EFIglg:лӓzxNb]B-]! aR eh>IWA,'`CgK[bUXrikN-նFo[r{&8#++8Jo95ҝOœ٥ģ^|V{4ŋOƝ= l}L %][~ m! -n-_OQ ;Nϝt@ENR k*v18R| O&V g^r:c˂ itWH9YƉ] U&\'}~q+?]?v,k5y,`԰| ǾAs`ͥD-ĉ_ss-I?BͭMuAgeS{R#E@tBXƦ!Z5=x; }XDRdgZsN%1E- 飧JMI#=gt1vu8tW^w`<'6kx5tSuڧ'=sZ8`=N8_&~˂އ-85K"! D<]VY7D\Қz{ >,J 9St-^O{F |/s,kf&&v375u[.,Ktn<;\xm W`/TH6kEws4=7Y=;PPpݍ#pF$X}"xIHYu G~ķAxNu?rf.<`˛Tl\C+u^s-Y[|5*bc‹W431sGꖅ)E{* x耄͒eL- CT{F|; ||1k'؏'ػ8=1_64UVT]S7oB7|qaG\U=HK,VfZ r=GnTN\ZtӱT[;8%fIU'?PfR)smYӽ%W)ţ!8}*kna+pW\VG$'u9Gh[Y ?rh=K<493]gfJ^V42fwnnhFuwdy&l716SuȽ+j~B"֦Ƃ*D`bgx`}fi).x@5fklp!">6Mh$(mwR̞"VkcE

|`DwnURRVgAIYѻў"tq8 e<7َsw3+Gʗk Tr "u`t]fdϧF>tf|Wg5>tpd9aYEƛ\։ ){9’G骛X/]vP7Gv(xOzFmh5o/򸥖*5H4 ; 38|ZE̓ lcfy]CGIsŨ٢-w~tѰ{.|@Qwb<,ޤXvBE\|Æ˱9!a,>{E{]BP31 ~'M& ǘ/pC7bN\YcOo1Dܖ }ϚYQVpgRndNwGG#zl$km_B|m]_l4+6N%#1TYO kG{SE%v|$B5XbNJ21fOL_YBXpS"6˷b s2Ompk)WSΧܧ%9븁gs^pNu383#YtdR mg_8พ>y:T;Z9{/|?Ӟrf$/|ؽ˭ap62gbH%|Xc {\oǤL;i R.s_((P][Sc^HYgtbC<\ff 82.yi`g>yB/&>r2NJPsr&1󽊐9 >`xC8]~}"+ Tx̷~CK#d,%k91QMJv!g3:L J",XRq-?Kv F#(8&e#gxk5;=d۞WK9r}e,+c=v|wĎ?$ĂR )xBti\k-h9׆R-MR0&8aP-z# K4"ї!s+\xO^bDhܛ^D{ }^Ł=ײC |maf6v]ٶ ]h?N̴2ε lS^JY:?5nh죁ۢ `j{.==;yL8ޭŌÉ𲰤Cu[V,p<;,rƖJ˞]Zɠu53'\Uu\|TX@h' rkg0ӮW2Ltj+j*:&6rwO i\SsSqOA˭ޤ49HnSyΖ Xkm?)W-t-c}iT.vߠ8qw.S\ Q4E!)?{Dv}_7 ` ,lO9?.Q2 *B-d ŶUf!bn- IBZw1w܇6>eBV=V83ش$VN=mŲL| >;.#u-D0@W3 Nn,x5;61D'Fe*_$sJئJa.1p\Ui`TWcl)hͰNHyJ8ꞔ/(g stTA ze⹖G\5T)JÕC+VWLu;7yʙ "̜3KKI-}- bwV`l|b}eylzKWa/ۯgXq-e`ͤlǏrk6,z)4k`s4H`mKw̺ƏDY+5}:va׳bƅkរqx/ fDւG(lGvT ?7#ޞO10Ê#U|TX%b䇳8zcM?brX4- Wz>O8iSbcT|Lv( 4 W߭UУΙc7&>yqʕ+9~o#Oұ<+g ?2YbBω VƳt σVĞe^n*, {)xo1ž/TyM5' sWsl%GUpg`$#?7+,5(3[ƹȍ#ޙ0_.&X {Pf)<Moݒ"+ NXSF Bʸ_$"F9Δ۪R82$b' tlEH)|S-֮ P_\ $!H"{b'2qZm ty ǿmX) r\+5Iyu-Wl僱'ᾡbNfk,xئ{%b8Z^%H8]_cty3nitx;>K\\P`A+ U\1L jU*Ʃc6R"YP4-蛍/-Lvl'!G+Ȥ*~(%9)j,hf :XߑV6ܬwa WjС'Wwg  >| P5:iGݤv[A; |W˞O|ߣg`n20hsa%w씆[`-l8MǤWȗ` vJP-ǰ8 :qdn_w4wsuS3.x?C+O1[LrnRB -p -obvm$WLv4Wtgu&~6p?:h9l:la"^9W0)m(/$\LGTiĺ9)8L9%I5߂գcY"þ{x>+djzn3qGȉ"CBfoq.k0}XX'3饊LZ/Sd $XyyX8:6x;+K%a͞y$fyDHy)*ؖnE!vm&p(G: O۩XqA`k*+ =W5- H˦т=#-yxI.B[82+E?ɝӶu7\8늙KXK'3dqez&*TE~&Ltd ;ZGaǮ0qH;nBFubSQ-% A6ߑnςf> Z!?]?Rk%:*[ C9Yn! Gѧ7x l#ph4= kt%YA9oвz ܝ4^oS.FW-E%h{'Ubi<1EAoY&5)YU f-XΦO1rؓ#xA}[x7w6#v=MfaR0A] S9x=n0rmG-!+|aƳaZ6ݵeBw)ǪXO #U^{^)s5)䮤x1t3.'nkƊ1s#z9+1׃7}LHEױ>-Sǐ*u2<'P`[1_DYe'ːz,cC &Fy-uFMوZ;K"a|BV lpIbf+k?Ĉ0}Q[ '!{Et&{1GX꓍'CnN޳ƞKǚdYe |3QZݎE;yDbJc\Ց5մ?cKє *|Zx]4y>dbsC7dLY`D36pO%G_KW`(uPo:׫\s͕v^LnO8: p2(ے_p>] MrqUQ4AhFEh'܄s > ݈+5v$B_|2Ϣ^ϫ}Fae ;' =[lfyYPp757bI3.Ys|#a~Ki.MCu4 wJ~E=;*Ȇ7ZwO19o/?ș\dBz#˛l⹁JnPrsŭlQ͈nܗń pv>Փ[+iQ_\9͉W!3>Dˁە>O5Lܙcd2&h[6l;"6puB/8睔qmy,)OW1y F.ᮜ[NjWpWV S`{R>Uqj{L6Tokjy:ԕZlrm1O(ĕ ($ͽ=…1bi=+`[ko Kr-zC1g/DaFq1 _!sD4|7guGpڿ@Ȗ(kMz$g`!ŽQy 0wlSd`Nyy36]ON2fc%l 7 WC"v8BT }lxNkNR^aRp9b tiu^ה3Jb}t)}JԎzs嫍 xK;wyL/[]n[k:Q~eZFY[Včl+bb.vemQ$ڱͫ*T l'j*pBN@[n(~J0ZYeC}7zFq2wp|/Nzޝۙ)2)uj~y'>%pw_3ݞR-mk_}EO->Av- d}p {{XK+oiS,x8"ƭKPIr%u _BP8ҵ7P<$u^ģƸ Y3)lXS~>x; L*t,_ ̦\tg\Xo'yN^?CؐMq-''n\-C\ ďa9oNS1JhMOptc xřAيtt No V3ρp/kY͉i=9j o*idbL{q]'u!tEE,8B?S֍D墤Sz;F%'dQKňSJvɕxk9 K >ЛWXlpifLunsՍO/x0=݅o,7gbN:yˎꒊ!3D!ЅA;VGpȅJB& [񗽞] _OՏu+3ucALpx;x"!{o¤.F *y^6Wf͇w_GVlA0( P^A~P*nqA.Fգϕ &⊱jA1 xE.ǣYh>pSB0SqON gxٮt}\ *[h} ET T±5grY Jg#uLW2=wͶaXowdR٫Ya-S= |˲d4ק qW 0|.ڔX_g-Sc@9- l6w%]vIَSL|De\%n\I\כ"o{1;_Fr^+rH3S:L?c͚2 &4M)y0楑 "f,ªSwj/U0gnywg80g::q.,kfJ['̔"5RnTpBòPiu*n43lYKpwm9®t8[×o(k2X[P q.+~/y {-9c%]+îvp\R QI:nϰh[/opS:;Pпoڭ_Jie-טp;v7.'I Ε SiվrPr߭N%w"b mK6Q3aϓta+fI"(τ#v4/KA꩘4+R}zWG֯ \f'_/Wx(Oa_{ܕ]B[obxs/n:@ݞ,-udZ37?VpXAi=vp9 N?ʝp8} =p(,'__.l}@$S%2.00G=\aG5hZ!A_iF}d ].Ėwl*2 Ⱒ; ñ/46Æ"HBqT"8&n.ǧ|6o <ߍ#1=އ|8qufȚ5:6_Cpb J6*7a/[sw4h5=CC-kvT n)pM7 N5۠Q2nsjW8gnW' \Q}(s{,;zI"ZR/gWS^ͨj)K-W03늸j?XpTMlf5(FYO1|& +ƂA~+^xiϒr97ݷ՝*~ i.д;do<:4;d>α|)uWww238El,C! M|x{X1;-jP'#u<^uE4gmBߣMSwũR}9JU^WT"# %TFM6RBse~qJTUbil95G۞F^⓾=ͨP?]nd)ؗGy|k}7 scfQjgz`Xs7t?Qoh-k* q9qVG6y76Fo6u.|{ʕ*: #){N]/ ܦUjI&-gqcfKĻYfɿd?Qv:a̦,|O8U _ ޗށv^-׈q1'aK*[ꌔșY_ʨ]zC9{b0x]<<1^?h]@4*?]󿛫7kֹ-9.cvB&I\> d9]j;0Vz37?&SUĂOPNsΞɁ6\Jx\ӰXNk e\ji䤎oIqOB-G6*|atXfO?6Ɉy̾ލgyѫc-!o ӠkJ'pthwtAPD^}XTWU 8o1%n ;N-c&53̑/dNo1˦y*uܨI_-K.%#8p Qw0QU.0n&0آpح(K\KTli8{|q 1:^'9 uaJQfu-ǀ;-de΂̵L>UZzVuˈRS+#kqS 5zxXn%lʛ8wER p%ӺzQ7T| aX|\[hi?,3py23l.g0/'3;wg>&L@UԦOa FQ5<΄Bo"q2{zc}2\l뉴bFºH+.ǣb%sdkXL Bk\xILG[w]PѠb:p0i Xe̳ņe ܿf_ٚroRJ>5_0JKnoĞ,Gƞ?.Ӏ \e@%gk67ZY +أΜg ̌[SC]+@ӽ#}۰i3=3dg8aUoV}FߏGpej wQm:=bDT SbǍӬŎ *G +ǰ2 UK lTza5p;OpͧiVA+!Y"^/$2ӄϧx!' {7g*Mc d2uL_\W%qS6܁},)2F5y ƂclZzx^X/4p^ s|d_b%Fı:,K5aX_;~}Bκy C-y1}iOC Zuԡg.cl/-Uyg fQ1ͅ_PsJP27. $!6azPe*=o1S?Xq%?7I x'qP 40Q"^S[pe; Dww\+uk_O`4(Kڢ o!O0At\LG$>gb1nw$}mTJmml\2@O, H˚5uNҁf|4Wu;qcuO)ys>1d}v#64mUkDž_ƙ9".kwX0a3^G?UDgE꾙:E)2lu3kB 5x2EujȮgM8uV^.@c,p[ 1FԸ`&{?Qgb:ok3WXdGgP-q:|2+Ϟx>%W.bcѴB80ؘ,Œ]Mc6z\"L(ƞ5#Pgd I^ 0p΅[Ha~}[)S}ao""01Ŵ?;~BM6.-s\'| v}_vFo<.(eJ\7(~5c/0咧ftƚ#91Tי=zrL%X[1-Gp }3aCߐz̫ס,uh:uիr*mÀ/Qxxuu|_HFꍓ8Kq|s/ b}=rV}#z0~:|8i?գ[EE/XiK~CrxFd|r\_ӟi" {Rjn0Uǁ9>`Ixon). _2dOL4N5K>0Ca9 }7\z fb֦_н\2f(QaڈtS[:t/ߢ1+0qs=^7`wuhĸ,Pfp@VRs:Qa`t g-니ITx{&Mx+DŽs4Sn5!N%ϝXۙN_ ʕN,iIӵ6j/-nRmwfctűy`Mn6aZ w_Qǖ\<}EG|=b@L#-E?hTDYr[翕1;KXV#q)Tj|5HGԙI?NqǕEo`3eFXqUv>eyx}V^]#v(Ua }NYh#ZZC~vtJ3w;o3H̭Abg ZP>Oh+5z;%X4DtR՘Rl3P S0Gb!K'm.ohnLôw.iA*Tb4U:D5闤I'3}kҎiߓl)kAGW>^9{X5>%}q#2W`I 7D[]מ7Р{=0{"!.8gCh &')f2c!KSF́ttٛE4.zvNǾo; pWPn[˻ct8>g-NA ߧǢ:|cjrнT^gN:E>jFk~+4#~`Aj{taͮt]-eHs+KqƊf3ടy/*7J{f+1GBѐc8'RV=p8d8osc-E>]J|[v D~C1j缄Xz { Xsz:I?O7sV$}틎'#173T)ŷٱ%sAKa;aBf{،o?00 ٵr1O:eTۖCSeج\>ʼGP Rϑ&2~2)<Ćˌp6")rTL!匿3Z98ye#d7j12|Ӱ`GB{ md )>`䋡CF`oE m趷_7"W* ̯_UcG>*Ӧq[)O?4cGKn35X%8ɛѺc~۝n0ѥ 0(֦b{ypJ" a5~;!%H W~\[31\o ܤɃ΍0)~0}>a?{@]4U=u6hm+NtAo'qHN2ڬVL4=i̮(FG.O*_i(*TwSg82ҍI8f %~NhzƤG#3&ſ0s{cG{-7(ѫ[`VQF\LĨ3^/_hS֔yǦ[31K;Č:yfT d|P.^تFe@g2&l_YWעW2SDƩ2S+LeBOK3so5dﻺ?vX\߽p'T]߇?gDh_>gG)[_gJgq2=؞ ǁ:c >Y#3j mkE7u9x2\bgޣxTF}&+d}s@6ǥx2UxSD4V0VUùՀ Y2Yi/X!tg"zF_jIK@p2“beD? ]IEQ!n*B?Z8fav)E{, qoG%Z^&*myeZ1֡ c`A$ ѱksyrS}Xył 9wqI]wҠfK~\\S_% zԧ!Cj^sd!S`{LhwՐvgt K)5u5∬C~֭i?ˑ>~Zt4twm-͜SˎŌtcN7cG; ⰽFPPW>_#M5M[~b_]7ƔNZ_kyT6wI[΁2dLw]ΨVgku><"8۩Ÿ#E4}Uj,x#(ՑY{F!4w){E(~&Mԕ[~;%Y![E]BeUfEE9_fƋ,85oZ;qrW"…ZLǢ[SZ0N<4\ ה]k(MF.UvwtkBLP5$5=Z HUZK`+tbj.rY|#MovSpn#oh 3s F4Ufm2ۊ8 q'U~҈r"6@a\qz&M7AsjL5„ڒN]\]UuNBJOUJ\C$j6!Pwi0F|%ٰ 1ȍ-X7Ɂv˄t(Fm@Y||vU:H 1W.|d.8G)3-}RDG7ؤj4/WjUuN2cꐠefox]oJLx 4{ҀSNqPjKZp ug+Oq1X{ݕv:ak37c#f>a9~˰2]nh!F4Jea>KL. utb}5o)5q꼼L*:X7l7!ޟ 7EV` sBLϞOC <3_7;@ ESrĘWfTJ@c?flpt )$ZzZ x {b0FGwrX8ӂV֜YRWy*; _gg"uvo]t (Ŭ%Lt=?G61Sf{m|+Dw4й^;~z?>K`j%C>T(= nj}cd?ⰟP#rVt H9CAWv `")_VIHZvBWWhx7L‹`;|,KfԂȺ݉B @S8XZ}R֍U{;vyj|`\J9QMۣXnEpR OĻkq 尩dۂS{ ! &W94`t:'3ޡ<$._>^&}9_t#?6h?1ǵYpZ`rKQaV,Ԙom8׉In\q_\c9RJїrN/^7|ܹ,_`+Cݘi$|U—."|N;c< cmnwS \=SD0TSXs%L137x\RXƀ2VpIp}]Sם&̮z@(z9f߂VYŽ2{wĐt.Vb˝z҅ɁB8YՅxa'T|z>"F9b\" "t\L., jh6S] Y]JQwX6+닛8 71B,?`ψ[CR/Qpv>:.k6.إBTQ>ME|R4g7#FP 8U"e1)zppws3Kʋ(fNs@WwrWLug7si+8 +֊y"՚3ˠjUmG7! 7rfD \b6؎y^$> Qo(h{ȋK<žTe+9}:1'X ~v~;#oBC`&^z4jRlhƶ4ʸL7&p|]iC_ޖ_p/%np >gq*26,ŠHQ y*\G75]}jn?-FmSax3ԏwl|_Q1d+}o>Wҁ;ݽ4 V.>U#ͰvV`MEfz z)~$퟈R[x$ʌOw8pV _eswYKx׃ ӏs1wucse=x;E%ujpp|.MIY P߻NtR'F/0X{\߃:Fv)?JlI)>-j8T```T-|hЬИ/[[SJ]؜-as[)8c>까g9KB/Zԍf 䲁vullߺ|a5Lgțړ6Eѱ gn:'Ci^3›Dm?ȋ#Tlzk\Ӎ uD@~ #v8;Nhs +=rbԝ-oAo)lk =Dί-qLh)#Ḑ?8nI[E|x\˃LxQd۬0ߊ5McHu֙6!zU5 j%G8RqUcT:Ea2wxOoVh*qOO8GfQ!V+VjpjD ب҄۔X /bl]g5WYs`W]:q ސ򼚜s*O~3Kκ! ˙^ ryz;eًd Oߑp8'%ٰG=oy9zK'9?܋-ۼX-޴aٶ]І"koÍn0ax6<=9eCx& G\ &tN-E|`ۻkz"`~#fHxrP*MresܐCvJXg"xNĸ뵸+Ц"a& Oÿ\.Dؘ"bǹZ<ˀY8v1F<:͈eh9\tFC-b34Ee5F3[=X?ޡ7V!?:45yq} a;F6y^ץx:!6Ӡ^-?WsnSi˛2R랄7zK^NAT9ͣܿ.eU$]Ƭ`Z?| kyߨf`7 y>y6ߞ)Όe|"<(ȋɜ0Ov]0ړ X܆{xoF=O HYǓ{6gnf-*1QMyf,v_*0w -u)hoɴm<ܐZ6E穕~tyziˁTEف2Fr >΍mX! <"1S) KjL?UI>9]e4 05zq0-`fW}ȍU&tUZ }5E% ;>籧1YcA}5;\ϝzKP`St(2F2'\fGv[ciG-Yqә˜H|W^;#SIy*ۍO i7҃QݙqцVYV 8R+?[xa8< #mDπ4 ܙu8h 8^=OY80QiC$M=;DVQ+=I$L z@1U[E5&{B*`pTK627nj֌Ss7jK}mmC%q]epCΤ n1\BWBF{0FΨOGI̕x$/6GKBx56ٲ9Izv Acxjī9Hu/=uµƬ4wʫl40"CEU#y<9ÃF4Qb;qf3' f 3zpG]n3•>,,ua.ݞjmx@$C[ڻiKՔT)|́ElleLT (ui9fT!j/DBE *`lD +ctP+}0o5u| S`x?OcJb^%8};*QfU>feܠێ۽QJIs'HSEE|"~?P?H9Ѓ;eI^|&M $*?O9?ha:u!Lr6RR?LEݲ1nn=0>ȝ}\ɉ1nL.e3hzSe<S<)=Z)r^O INI. vdu wg9p[eǾS`̯Ftgp[ 5~-\{zHCj)Sa9?E!&~ 6徣 r w阽$ה?Z?ʐWO<R:* /#a%~(y& 1 /؃R"POwsv*eyd5op";͒QG9nJ6wc|lG )i8: 0{Q4enA}5Fbو e5?ąQ^L&1f=΋=C@9=gx4&fbn?Ս]p;7/g3iЉN;q:[Ak曛3)oER{_'TcMA )-˴F 8aY8G*l߈'_87{t[bhow9?v욀+?qf)xi>K/sI맡csκ 5X2W՝;yyq-ԛ2YM+$<^.ejg/KF2=`s'{x WsJ VTgEj[v}ƁmX݈hZ-P:ƻ1 ?^Rȱ:t3"k\;qWe)gK9΍ \8HʽnrzpWH%t~L?'\.tn qs3k;2΁6<̅]x"ԙaN<߉+7–Y2b!K}B6+YļhMdjswg97% wJ_` FTF^AW[1(E/!*'P9^C:Y1I a*'m0 ODOJ8˓gi'ЅR{'^K3ԓ>)3rn6\OH)'+>G+jbw-`Xkοfren[álp {t%8??1yNw3d55ȐKndC띎owzp&IU󥬸}ܸޠGjCƊxQ=>h0u ,Fбh|ބ:hh_+>qy\{AoXQeVDߦ RZ!9-=)mrNibSovUhv`:)d-jBe*RnY-<6C =)|ۚ}qH%&^M;m-MTӰ`;ʮVBO-d\CٴH;Xk:0I}u;#<Ј>}E{#6ƎCfp!W:!25_q7n;-cSw]) Ɖ휘+S\9a.s[\#g:p{{X[$Ɗs~GgǗBx`k0R#ay[ dVDp3kq :}To_+9([Caftq a_εx)ͥ"VRq:c6kJ Fms妅rG'튽9o7 zN:0:BDxZ#p2tq.2b9o;G)֤250Eiqؐɛya9_ƙ?q<&^_]K.6,^UX !J‘,{"NN4[-YU .1/T~eN8,sgrVg t‘U(Ӂ́.ram&ڲk:; {*⭉ l١'3WγrМ_lMٿƄ& 8b^t)ۨBe8:nų]O`MHv-3 <%eܩ 2SXG3#oREǾ^Փ/xr| Ϻ΍qߚIÃb9-/*hE aGLsdp e@c_oUx@SDdz"TeA&IjĒ&zWfa{ht^0."kΧhfCHz7&|}d'^#-t J;\EM΂˸WiΜoya;q|;d8#F;w82=4~jJS1τ;r}9kXp[ ˌIkql&o< ,M9&~yi_joң';@0.~|sV:c*%.[hgƼߜ+aHm#Y2c<٘JAXjfF)8}.)8'uѣ)c;O*=.j\ƽ (ѷTU>쟮4ǐ.kԸ~@uVdRHÑ'OʩpKŖٱ6a&okvw"O7.6vgw6.s\yٍ%8ۧ ;R)gO3ʙb%w^1Ҟ88JZ3ʘK_<Θ&ܞc̻fg^F<nJ|D3 ޥ{(~ KFT)L3!IXõy{!?56cEvt_^\4ևCq[cNXzi{5~,A" J.CoL` KgT<K"?cw6<.p5x sh,SICqLp[[C.¬Acȕ}?lHi~b/%N4rtwNLw~BjK0y,< qupw^=F|ȌǕQl͒ 8yL9%`…;0wD+ތQL2>ҷeg1d/ S g# ܩmNm\tؕ +X0Ü'l1ۍrW~O>қ_qr_8ՙ}ܝ|=8;L<(qc{Ͼ;H _bqkg&?6ЦB{kr=9m0昽|τրg*ׇbS󿽦Ϡ:hQER:|G-rѦUx^y.flȆMyk{ɝXk¬:HG{1p*&+sV;qSw>l/6ubLoZy{q+u. * lDLð5)hq2 /|2iw>W4'#JԣQJN]$5VoOaC\^b]*jbsW+.٪FjpP3똌>U8Raj\_ 2Ȃsz;}xe 2v '`NK?($cj*D<;m"\OǐW_29^y,~V#dZjc6U:X]Åg*<%㑥2{Piec6sbx2w3krZu} ='cq˾7, Yzݕ9jF=e84$El+"Q8~y8V\Q3ne R^NKѾ tx֒W8VR:oR|z'?1#vh= ݙ2Vi|_m';5W рe=0ԑ[dv~m)m3M*2vXz] ke8ٽoЯi2sԲ퇔]1-Ӱ'. \9SuFq( еsgqar3Q9x#Z &)9U&B{N;/x ܊|uoQ0BLZh4R1'>?p#;E3}Ìkg0y1T~vI"U&KG-Œ9朏_TβUISK[-߀ ع;jR:<K5A_e]ޤc#l!|xƛZ_<9ރsȗme5[嘲rߢϵGxxG920t Bރm38dc>ftAj&/Nx2]rjC^ 5XJo3.lVyVlgYh3w^Ƣ$3~x.kBB9Og='n&!Щѿa~ś󠝒ű8=J&=DA㘚N&baCQp!U&p1ϨN>znLJJkS\0gayx" eHScW;Vֱ{ưF|15ꬆap{s.w]8ב܁}¬y˜&KEãFj1MOq)Cnce&B㠬Ke[gxx0v'nҧ|!Ah-]epHQ)P딌hҩ2krhs&Nenu"n bԸ9^yzDd"!Nr>AwCW)~z ¿}m: ˡNw:دˑ#yjmTUT"p7j'S&Ti*NWal5rodޮ7yckCk49_9{0*‰ٳn;XRۀ]5Nًl|cBca2 l~s|aA817 16n$TcS&&$AU\DUN ~g0[K:VL`&#bE{03ky /Ӕ96G!U\8>ۣ~ɏz-Rs\0 g#9rkp_'28ԧdu-,WgV-[Ś^Kie?8c|<'MmDN>|Ґ){Pj.fbuyL95<[rp>j}a)$B} 86'b^XT?}l.SeMN׮]K\ĂK<[QOPs=[1o(M|R"6&cߪju7ɕ5:;Μm\~_wsz!c`M=.)A$!%1 ڃ. qͮJ`Qr+ڦ"f'gDx*q\]~2+M^W }M)0۝zM=m ՐM\]lݪBk*}\P83g];x"9]5ábԊ*qh^^'^]ȍӚU3kB>,GDuឋ&\sᕊXؼūSX9xĉTX߆-\ň#X=Q]}&eGj`=kG`x~" v X*Y_) &@N8捹ىO`3= )TRU[KQ^^2Nsd| +S{Hϋ>mxφԋ17)ЀT|Lݕw$gf5Mr{nZ$Q>S ` `J'7]|#1xv:4ay5\n`SI͇y i0V_KlWνTj*u:KD;3g[z}-{rc-T2L- W`v~96?>I;k֣.+lFc:$iq1=z3il;4Å3;tWMRgAfQ jœ#gvk\C0eb|l蜏77|ޱY;[#q66dr딎[< a+^+AG EƧdiŐ]q4ñk6`+3&M Uz[ho5U‰meܥ¤r:ks3xօQ-5܈"yuzleRi/V;Dݡs8 5]'4䒜r=V313Ίe{q=6=W!?1<^\3ns[ r!tB30sk.O8,4~OQ3 f|2? *\}_T8:eDQMh1 ߖ_6*~Z WtL*ݰ)q|A/܃ɛ=3?bbN\xj6JVN%#oU[ŋ-iB?=إ=ؚf1õ^te}m*u1=hy|\nS5ٿHj9T ggF6ŠFAWj_aq6އuO*,`sE9# ]^%c4ɲh5N>ͱ3MJ%޸?JI C0h; 4$OZu]I.(j 5p8sP84U6T/ .Ao\P(UZb+j[831,>F 9twZ&Ufemre Nh1Mϐ^Xнm1za<Ra/VҔPѪBZ41t^.-۰EN EE4\u(Jմ'zUTչ/=BJq5|#D7Jl+eDhnGhA5&,FJ:b"}7<֋~aaVi'Me3:VU y-O"&n"4\ ̯qgwL]3 7uT9%-,o?_qQr$HMWG]XMGa9- V\f.^S;sH6`scȇS*,a zj,ÌS2pve&Raj#P94/$"UX+B"WGϷ,nʔc\6͌rrC{c.7zNଢZ\*EӯJP؎ Ŏ-a1e 뚣Xzm/:H Oұ=VY_S|^_g^.(; [f|G cB#Q"FVf X4e"9p>ƻm7??MImh# vIsV oX^n̬L˄ʧ ? Ų1 Nys13 uqT5A=7AwJBOD\RQ0 6%IU{\l/)&=ťeZL3w?G D\&y=݀p-&C+(~1䬵?6^ "e09rӆDb_nH\(Bxq#^ veA˦\]aXaݡIN|cZM>[r '&}N&_)Y&ڒhqDmt?4g]c>Y07~)#?G,ͩ5֖ghܘfk5/4 jc^,3[Gs7fWt6 Yqw0ܬ7ma*v,eqm憭q(2q*2dJ97 0f`u.;*QJkTy; aAFdf$=r c6ӊm9C#ШN#;4ѵ3U6;.nЏӈ{q MZjp{^{%U rN_Դ3j]Pu&Q*Q՘<sŵzTU /t_.ߍ=ol9>EEO(r1gUk1j:/Ðh1YGk5zȄ^q mMa?3 T'cN;0н\ډ2@ň.>{CҰ`CS /{80΅ˏӣܖ_7YPcȑsmM+A vu:}b{i\^A {wlWm'<$Ӻ.)bvY2oqk]yAv]U*3jREr>Պ׆[ u9/ ~Lb5΅2Ċa=Yzфw5SY_kpCz.-5}?N.n4f8?E4hn#L9j=>NƱWtz_m9-YK]8 ٳ@a.UX?<ggN${MaV1:Ͼ4.ml;x3zTa\Ϸ9g5F`:"w.0%=vc]ʙECu:ՙ-XRG#ڄkȜ*:O'?"yZF·hYXI,H͍N :i,1M;=xK 5XCfmǩfn}ΦGؒn{WC1"U9:#$߾ƒwhc\"7vTYb)%IA06RJ%YF` }m7N}%:8jsecg3YWkBڀ<Жjlfc*<ԣP#^fɶ6ٌo yMl5xn6;gI?C'##Io ]"T']_qLGvsb\kC^YcH.ʏ5ah_>7?NsKwq :wsuWɭr\CailSe}/J'(~ U "<>wncPsC! S,÷b4UPCsMKfb|Ԋ.l̝7\ wD9ro8{XITѳ἖Вou9LpИcd&ΐvy:|FdhkhN:lQ1.B" ثM ɞ5af Pe|H#u2SDrvMB#, O6ƍwyKӕ`b7/~;RMK;TY!l}洔;,_NG+fIݵ,0̋է= _}75hFi {?rbrӞ4up.,.ry3Ӧ o5P nӖ>&enΥFE g¿t_견-u&Ucڪ/z vj`VA ]˪ ƚR [pb3bUC 75|xFRP:^x;[XQowF9s!^¶rZ֩RQwgHR4vNSR6S>{IV_eC*F0>p,'&%@ckW _^F)0g]=3L4HFAM`-\xG˅:ur5kt_CǑcVZkWE=}XK3cE'&ܔ|drVr+[jrfGp8qIv\eȩߍx9SP pxrY+7]c`5(|-67Nuݺctz-u务L/3+׉qh+ 1' 0Cf0ׂ&ذl{W{s^OVwNb,23L9T3C>9oŮ6zĒUUttZ*gt9brONjR޷͖9 GZ9pl@+i]r0#"re|9r5oNO~A]zy .J"ku5aȬZ t3Reξ g s隃:)g=N\ɬlV=ym;Bgsd[q`H{Nnà}f lFWO `R Yqfkv_nA|a(S>mz̝ɖ2^čo1!:Ve пTrNh4-s.hs~n`Ky6Hkj.9+ە^/('oM+0V||+K{:FW9|bڣBFX]obaz:peq)4Nʓȥ P<_ 9Kkz.of3 {*o:fe<s/ɨf/߷5fxshq֝OGz{vBQQlƋ-֒:_eVFlYyʀzwQXCjJdg3hF ?1=CX#P]&8 4c9Yig;ץ2gtӍSmoU K4EeXxZky#5_6Y_p3 kdbtꐅ>Yv"sq4)ao±FӮ :{qn];W}o{PZn;٪ڑW{9R=Xcf?p{S+T".?!,3 ;zfc_hU622Ű}-0k^ kuvzƉO5r1C"Fp ZM@XT/E_Vf98d ,\(ʲn];eNDig?jg }DK~|ŕeh4Nq[ZrNcZ4J=䱌Э^A1NwXw'•Cјw#bs}r l2Lȕ);Al1Αl)a9߉UomlM: _pzie5v{ܷs_K003)Qߚckd~9.xSpl+IPLƣ`8,d{0l3&vݎ^{ >b@Q.NӤwӗsDH49b2Og+wv ɍl8]2;9m̳‘'QՃ Lyt) .+&m+/e$IOkkb4wNG{;Ě\,,RDtǃdF^jg,7mKu<ʃ>3]ؕﷹ2qG7~<ޙʞÑQY֕?KyƙnpS] PһĄ}-ƘT#)8kTA=}ngܘ1 &#/2Gwܰ{m O%(>?6HIE<5,pטB[aǙLpeutP7f=hMNSʙ}rk7i#s8G}f˥9?rGvtdYG~nLE:;jDUΕk]}n9;q'gy`%LejFlH ^ieEfyK+qVf9go\ )߇JRfjyI*eNS*}T<>Sbxqz~ZD6K0(0;/e;[.11ge+ֹOwT2B ո/#{oWw ; ĞI 9qww7Nxqww' wfkkgݩ}yߜ*vtu5|h̓Ŵ$cr()3)ud*`:?G4~^Fa( 7vRuEE?OwÀm!s&&dV|Ă#'3 ^b@C=\ХP迥2:Qs3TTaWOÙ5G_e ֌Wp}JyT7üげ{Z{p{&˾\sؘ{LX2ٜP_ib5 iH#-6,i`A\+*3ELdxsnS }$a㜈qկ[N' } v+bOΙipUi}TRݜx.ʈ~+x^^&.9F̔r~'e+rj' X'.RnIq6ִ0~}ю/Уc{>fB?#̅˸?[m#KjnًqaӝY9Ѝy0i]O{p9lFb^^Eg=R2Zű7eYG8IݮJRrW/%mt;P/)iɓ|(OV<>ՌOԡr_Q?F*|WĢ]Jp'濉BxھT{Òxzj{xW[Ɯoj)YĎ81+rbj7^YL_})7NW顄)B~LOr5/T\~K+{8IG e ghhɋr%7*b{! (hz4`;FTOdN'$Z7?dR>Gݔ!3lKו}QJr$c>)_sv|4zKq9iXPjP@ݟqKX&lތ?EQ@߼ڳQΘ}z5hFOPs/K:T4]x:ke36fLm!]pA;Xc4 Q񩛒3kH͕*g69^H&sSsC/LRcL0 nX_]NMңS *p[[DS#p_ elݻdN;>_MGIA"MBm2!"' Mv9ߔ,+7FJAdc)^ӂbĜ$\k\- h '/%=yǪT,WY'{T 57LKg2[:qjV4 .Ass,Cۮ8@7v,enC+bɅcx8w"R [Ea[0v̸*ڂ.=5&<=Ҍx<ߐdJ aͩ9oGs3{x93;,Y'Hy‰KRV+Kpc\1:asJ^;:KhŃu̓O zSەtMR'93=l83؊m[pPSc+BBr 4>O.XNХo~x"f[:@ۄlX\g:,xW)}0a<(dlWY&b~Wsl7JΉbE%c[Iyy;p>kwNecjVʺ H:7&K T-Ëf^l>*T2rɳ%,37RDw Ťuح1dܚ_(K9ssHohpP̶wugs̿gLl]d1Va$8]GL0p?{8w_0'^OC[Qɷ~NX' 1Afmg:c^,1b-SpL&ѓϩ(?C2^! |Sp4&%9;=/O9y wo3gj!#zPl&2>O1(1HK6\jX9^np9b.--u-V8](N@՚h9v1`_0g`1;/3eV̻+L"%7W5_8{ʃ'&ٳ!3Fypj,.Bl b,ʃ/ᇝjb?1Xcܿ:@;29O:Ҙ̷}܌#34V]j}z~4<ǖ[{NJ||x\d9Zѷߙk8Lf'S5XuT/wc:W]3'r eθƖjƖtxh LZ\rLA//P0cU\o -zԠυo%ĊІ1&\DZoQ>`t/;s]AWq]vUvEx'z[AN k)~uTq=7Rh#ܯS*rghK{~^#tOvݮ,Р%d3ͱ鸲+_Uc.t1Q[71/lt\Y5f_I㋕<RάO 7'7oo9(b1>Ƀر&xK7w.OE+~V a1XpxFUMzOCq?PB~{9o y>/` )l#:&`/ڙ70*s8k-u>Օ8{bLN4wH[U㒉9tvn|So TP;%/z1 HY*RcOot0ΝL;e appiw>NcafF90~0< 6]k>qcG)2tjnNggڍv⫿Y}]sqK6)A˞<ՈM̉/x}'l:݂y9ut5|:GM6ucp%/t %ܹރz <8|\&dL}/ׄ9ф[pj+FfKugFaҕt&̈+Ws`e xGWJq=ހx$|FmytJC|lƻhT~EWTcu5֘g ߶_Q*L+FmdPI8g-xO_UJ^P7\}%I>M̺Y™|,&~ەl4ZU%iaor0'p{ F#数/` v`HG8eE±u 2<^-08=rG p Ty/*@O֛fҲ5xPxtU"^6z;ypr)]g3 b9k4n*aܶ }y ZI"1'Zj' ;,"f}Nyr>e!Vڡeݍxq rQ[XhFsS.aºlrxiuu9t pB[xx1NC74O;v"c.WX󢱐[8s։EGi|K[\rލ=K$]λ MsN v-|u[n*‰*:JQ*f!kE`yl@xQ;IkÜRcRa8ޥͷ27 :8`y!e\\lX}o0uKIզĖ Ăv !r76e{K҅ORQKƽG$fG9ya+Nk7+^Ϟ?QSڕCbøwؙZ{=5sV l{FXkot.|h4:,H]gʔ,{=$X~ QlD:\G;=.`XsJn+ >մ&=AД~A92 ٽ2 ZZpCΉ2|.\TYvl։g3TЇ|aamt=߻5ON7]Wd`M)NO֋f'%ǍCMm_e'\~o2:LLR旄ihmS?*<10 :YK͉ x:@ѮIv7n w-c{"$Ij1GoR z^W4Ƌɸ⾌M6(TDtP" [2.(y:Lrv"zLǐB~0fM)7JDT„ydJ&F Ńڙ? ֗ߚ?[1#:<-h|P4*a' 5'Kq>VjLe=<ʐՂ}9)ז'n7V&ym).y㗔elYd5m7bh&1.ޓYLQw#˘`9U%rd]֯ϐ]kWHS|FQhobe6LmB 3> mk]MCҵeХ( is6kMcgAG?i&Vb^ scF`{B\X,JΕg,_aB/}zeʒ1?āߖqi P2-MȾ1r"%aFܥf]zoƖ]#$TIŃNT*M/e`$Z`VC\u1)>Ӣ X=yb@(A1cnּZu]*]}sj?:]LܽUнfJk>n͹>o_D͑ Ċn@> KONAҋ4V{ ;V]?䠽 ~+UŜro+%sfi1Ջ.=$2WR3s]nKXtL̵=+pŐhRS8w%X1[Għmr5 ]Ԕt~7 = 7ď0A16о؀>Ͷ!C>L ѫsJPm]0ӷ*YYŵse9Jy*CO͏f*T2$˓n"s;ɽuy'=%u΃ >s&<1SЭmf~CG_<1z t}d&,Cá<ɘ5)ĔUOov[}9ڔQv??؁:f{[[pWYbLlQJ]Þ0ZN|SQ1TsNO]e,{a2ϔ%V?X2npde#W/q9鈙ۊ'G)'&[s]7nkR#O1͆ ;O;Gx?E M0f^6Ocf<ט&2ڋxG5]&\Ĉ}LNH7[WUv * !APQ ]}.4ā]=_U󌻆'xV|InMLpb t$ЍLt* ᣉƴ䍿 _a*ڊ^C> agPz=eViʯp9.Ƴ|Z/aǺz@%47bRzvTm5$Jr}1W{h.rFJ7OϔYq_˙>JNy:I zqI sER.C17_`Ct<ЖEbIf|o:S^ 2hy'fd[eAV./ QȥU2b{/V񮅚:L ft1<8b}]:\Q3=<諒I*V(9vﻱĞv)@\J:&ހ|ٙ+PYϯJSbvhفUSeÐqϝmP@:L8%-l]qsy%\r15uu8 +So͘l[>qp{qv;7أ^LE{zJ9vu\NmT<%裏sk-2ՊgWyQ_ܹ[ω7smy ]y9ӉUl#t&%ܓd>IDj͌F Xgg?7ȅVΙb򗸙`H7Եepo}4‘^3f#5FnMr7ua/v$CȘ/۵UX)cwC.%M WyU6Ul板ZdɘxݍO6s-~[`a8l};\{I댔3=ʉ)8©SQލrp.7Y|uSsS;ph;ic.cߎm6xYKDz0ёfETu?1pH4[ (p\Ʋ qY7=H"ȐX1HfjFT3DʧbzC;{s.OuS{S1Ѱ঒ Tr}-% C(YTXu ]NbSO7dpskZδ ܱgz  2`J8|Yޭi? śtl>D\(nI: ^qk\nלȅ8R~Q)l3395+GS3nm.XkqnD·,Q@'Iv C}B%Rdtv(G#;?9򍐓;͑q]# k ĞI9˜V#M!V)CMhQla. >sD w-awm(_ev 1ς/xc'wW&A!Qcϵ$a-^a9 )}rN/<ч\I#kPm*b4eoe֛)Q^\ͅ $[BRQBI9G1w盠żBForfQr 焯+;nthMh!ΪGqBW{mlK`xu T ~iA[Lat%g.Gz~s#asXv߂w[psS'.5rTro ]]~bׄKX)ٿNܿ[tKN2jv۽xy!֌FF8zR7f?#V;KrzI)MRv!jgbK L;FS>݅S1X<\1u{ ?|v5 J  nimJIR.;qr5(员g(9VMg{ S3X>Cg?񶽔;:ӡ ,0xcsq %41Wrx ё|b!49uSpFCr$!S<٧ZB./gx7;+qljɹf-fzlWkS8x:pp%_ !r,z<\Cg/עk;RXakk`"p dO=q<~NvOJپToe /TSJ%*QOn&bj.c5puC#>2 3秸'~`]+qLt ]#n}{C-~8AAEW% Gwz҆mrE#B.tr֞hWR|$PBE喀9-$6}Ԍm7 [2LlǚdsVx1섒w7YαCuK=Jܦo*ZVW,Yb%_ 3v6cc2&B|4 ́l6ͼJz# =kU0B\B:oKiSK$ޝ2?Җ,vGl$ K l5Aeg>‘<46 dt:C];Zx8Є]`W:x&cOTxLBƅ$Lݓ H+|Ԁ[sʎc2Kj޴fJΎQA2#@5˜P‹[,ᒭ&<28Wcxn &_ uH}5 V\-ySجȓgYP }) 9Ց:S4f.W9fܙ+Ț9KҴk/j/0KT+j-kgKn1P%LG<{*B9LFSr36(YYI'(JŤfjkTXwU"9܀FXx{mGqs5SA/ z2S8OBB_9[N&9խ`fg -8Kԧv(KFBn shZ^/ cp~='s :F._E}7ajsYfŪV41'ex" H|*ڥ 3R`s2vt:JfcEZjy=ֆ;{0oXZ5*=iJꬤIw5 VsO }jp\ф]al lFXU-\]Vy}|L1Z+##d9){.xǎvVlWuS]Ur9^ieekCsX'-ގh]+/5><0^)n@}^𴠡-]r$HX/@{!W* p'/.礮N\MǸ]7r/$v}Ѧ?_3x57h+X*%k<c:"*9&}Λaf Ď( m GNd |{x|vߛ1pRzRŔsvb#S*jQRJk1;!]!E9B ˓Y5ȹn‰YOIWMygm0DӼ7<ؤ5Lﭡ)|ɔo!hZ>-c2?XF65k&E,4Tqb1qkpc{nmM/)dqr4ME,z?@y$b_yhl²Kz7uwn$h>-3-F؅)[%-vg ;2M ZSp-O|{Bœ*9ZrW wZjۡ! xݵrv٩oa#]^HgOR[ڞ 4ljm̌FVZ3IyPy8LK#oV9yS!S4ȋ~Uϐm%kN>Al}_qR2"u !)ٱз`vz rV: _^ =v>`Z~ˡSꠟ_:t/758 mнU-%'qD1~byaجoQOj7G v0_Hn͂p)7Fт@|3e zb~ r*u`FsP2g{aЉ%k{:c@tZ]bn^{3t7Vr0JBoּcBy9a.NWƭuSƬa01G^j㙂o[ո8~;3P+u3_`5n =7Ƹln%İo50Pz\Yu:X5^^2h3eҼƃ*M)^ƭ=9HN;a>hx؋2zZR{$ єUXO/j*[V|l7S'Xv EhR,r6̗v8ޕG2\Sv\3ҞK,xdE! i\;ӿSJr3n|3ՅIrUAO2.3{5YM)JMW5/6rJ\ifʕM⯩g?zǠfw]0%t]9T }8TC+^ŇoNЁKj~d=2^hɰ%Voů %a h'anm1ط$534>5Arb JYGp /1) <\__ oݎ<Ôhsq=7 Ǔp6!M vX1F!N)5*s&Tk1H5:Txq]~d=jI#}/sWNl! tRrRb5h܎'w`1|٪xyy.bvzY(voل50("ڛ1k\/V#9 sx g1ڋƓ;>x;/_llyÉ]o'vW*Sy]z+XR[XKETmw(O~|);3gƦw(*F]@?auƕA03cE$ }l7Dt}Bqg1@px IEt읛F 0K\4cr0p /?/d{ FwYehAQ?N/[dKll; [VP{>}ϼg^5s8q=ٴ|o?N.)I*}S%ѲI_EZe/ta9hSbYf\{c vӭ0}`mUN#mt%r&OhӀB,iEa\-\kLa+;hㅌp4FƐ~_↾3nM.m˽*z#.&҂Q4&jt"_/';J3fҞ4uoGӪLE#^]N꿯!=|[w,zݤ~u;{; v\xf,4'r>vӨw4hq bP5=8UJSҦz|7r)ڧPT:tao+&0<`sVG3Ei7amVn`O \ėS;hK2vNtY:v~$R۾qQ(X)FTƚ0tfk 0M--?a^>!Γ-jhd&5̀W]cD5o@7x9G9bQWMt5h7SxB=ҰCaTߵ8)_D_fJyr)ث1.i]x4BCgg'ޙ9ƌĥ8N REdYT@N-3)6JF>4>11Vw~R@?sn"jV贠}Kl46vwQg /eTe0<:#oEȑ*BR爭 l8gcF*Ǯ%x.Tf-$?(#":<7ˢ.ԺY-MEJ/n|4#: M1p̘39rLX[󍎘+1g(,mN@[ݤ31?fI+,G I tnxt+7=h S$Cyl]z ,f:AMԣ?F iSQho% 2 Z0"zf<2!~3{s?kfdP@d;=Mњuj:s 8~H9!m4M~9n\^HY/ ΁sг֮S3 o7g`c\I^`3S?&tsCiFy :YSsJXĈ0ңMjyhSH/JOSDHB5RG>֒-,'lwٹӨN$ =O#,~ȿH;prt">lKP`0Wl&Sߝ3unx^MsɐOUpơHb֞؋91TpvL]qqx;3?n<Є3_5úHRC:VĻF|i4tB1nllő5|o9_0҈7Mplĕ=\#Ѐm4c~=}W!ހӓhĀr#.4bK#:l3Ng #dhs;10 }{mz%=L”@v`jVӎ. hst9~"Q.HP/uߛ< 4 A=v7nx7{f=&Čbw8M7>Oۏ5m5SeYGHT GyJ|(%Fl`e SɆ;]D9(#7}s+_k"v5ɴJK!nmXG::ᗯ@& T#t.l-lFlhU/ SƩ"!< 0G ƐZ:=&dZSLV;Ɍw11d<|hג1# ף}S5gpמU+2]o:L{*jWo ]m}q)Y4'Y}lG#uY+GdZjB郍AyS pá]Fgj gPy܀Ì0Ǚ:MxpF5p q OW7>*{K +A"!yy8eqE[q!*f'JiL \>Z*aD>R2|KWb4}\= kLh9 e2=r6at õNG~ŽIJ!d 9H'1f ѭ4Ք5 䶮%;f͘Ky_S&0s'4BMwbڄm¤wfo!w3r4n8"eν nXtK!Cuh0NSYA*l=ĥj D|aͬ}GS(?/tji^zPDvTP|sd83_ 9Z24 GdjMM9#Ԯ"va:|ja3^zwlla3%J9ۄq3xf6E$i$17U e*&>j>7`Ucpp@V ZTY!c} ϧ_iٗtmKz36P%S:E8~y,l/ܷb,ͨSABVN`1J+?,q7oOUԨKIfRYt@LC)GRo}ojC[D~Ԙ3 d*3r V6bjNu-&p1PG0ՀеzEq֛3z7Έ?OÄ[L؈@7lFr-6ԸLs \#^03|k`ג ;~kؘm $`9mޔ[:9:TvqOZ ut]r4ntkrO;e:54Li3H4nEaFo>VzI1=$aXj`f%$QxR\yEvNG)I1ɤVkN+rM8P@ 7rC332Lg}<q) vcBY _ݫ!ʀC H6m*\ưA:T3|J<P[rqšJ,ea@36OcӒ]Q??AktUf*ϩq;A l t'L/v8W5Pܰ:J[N9օ4wE7dGNaC:_#73܈CthtʀF1 π _0cq<}KІaW y]̜Z3r9^K|b1_ p' ^< 6he< mXŔAݠ_&RÖ۝LZ>xMs_e5ٲ6E4_ ,3Оes%PT;ޟuBg+bS匂\>r0%v`ӗ6+Ș G>"|<6`֎5rƍj9]Xw#9Pqa'f}m'܀z_;@S&x XA0$i;]5"J+- _7=}֙E./ч}=.oΨ֝ ג-Vޑ5,bP9 ڣLu^H-shXV6uXGsx{)= ؠe=X GZF@VyFq49Sa [Ɉtz\tXINj5.jaŖ`> !bv6+1U Vr=!Pzޏr«x#&G,.-Xv4%iL;ҋ\qK=߾|ס?@҅~mACW5 z?=<=db[T Ypy>Ůx[]0UZ%ojq-{4Qb{+_#V gƍhwt\L#ҡp2'pӀ;cxÀx\ Z9o2H!Cc0{\ H2 wL5\k4虢Bn+Qϰ. `i+]%h'@4@l/Ҿ M|Ftӗ5"pbqDQΎ8ӡ_(ggI#72 9VEj(-[O- Ƨ((cR_vU k̀+#8Bw oLhGg>[,.a]O|k J5_`g-&jڮ.=-{b?cQ~lmPb6 WCVPr).ֆT[,3ٟ:cY58[J/>PSNV4O Tޢ"`=:`Pu!zQ 8U82)|Eldo8s߈^tbrŒQskL8n0ƀ?D?ZiЫDe1g=C- 41Z_VQ? lQcs/-F4ӀhNڭN: CY]0Fѝ%8wZGO]9Fi6 aqY!YN h\[t1;–}bwd!q$"Uu nlņLd1=_p.0Rk-5a7"itƻV=pAKDP<ᝍGH꧄+ît]G8=z4x6E/rϐan71Ft* \d8f`> +m ̪khzT5ZAm)}sQg_nլΫnm߳v-}I#bPԋ-4A y_N'?Rвb%BWFmHF5{v@t7;a$.X=Ihҟ[UY2! ݏa,0bxgq: +kzǓj hD^,Ӎ\5 XaBmvhB/gL{$ÁJy™jk?|Ǭ:x7 f/Q`SxLb{J0v~ܵNOO^hp_쓥nQ8D%ombD= I%мl ?̈́팏f)s a7ԣIz b8`d%%, Y~u;@7:-0mWµ4"SzD :X, Jy3ߝ3spav9x:k}٘Wk)XKGjdz*2hˇO̾_ IQP MEXF=h)" ,̚iDG텘!щ2g+hđx"aDM3n^0!zx~ k"ܰ$܈uuf)xҧ?Ys|6q.ůlbG'UiRk_teGgt Z6a~Hp^\'|g+q1Ҩi/SsOLK;D'S`Jws/=Mi :TR|%8،g%*4c괧ɞ"O*,\DO _u€|şj|Bw6МRg[|bHP)жC;#"úE_* 'pc8"8 /m9MUjy&iBC=C_fVb}G-А{CA'et:RGgbU J[E{6;`Vf{;IrK\&K}S~j z4njƋ6]7u6Ig`7k!13KQ'xg|x ōI ?N9OE8;8U2v{ j-cM&q(KT(IaH)8_3㴨&@Kz2%};ҩd-GGZVZֱVZj} M?H'Ff7 {:@QQ˴hXnBY->}n;|(ak dp-Ƹ4K8PԐt6EQhSF쨠+УR]1efݾ ںjpj4|sEp \78ERĊ$*Bz''q3Cav{"nHL'aJ-ŘѺt q,GcD>O|ce-iȨWE! !Sd ;ti\vpđ~|;GYN(BQa2,d|i{6Aڌ#`@z|}Y4 Z x5_O{\C[~QګԨ:bJNskj@_Vq%WD-ki;TۤUb w:*>613mC׽7sǿ﯊s5W]>2 ynLUL]XОEHbi^8ajUpQ 5y c@H "Q(@h>MǠRZHy/prϋzE[*ɯejDf p`gh5V+;\ا=UF)"2(e)B1npB4c›qp٠i::ԯtOTmvboֱm~ '(մc M:o`[|h"a63`L3.*BR4. x6*҄;MܬFl?*ƇP%,Hgr&Gt gt@Y5&*&o3% |C#?~Sbޯpn=4L&iͮXX ѡW5D B!KQ$X<&It}ǥWE;է`#,xк[hW8\EgpBAw0,Or,i|*ñDuNW*6N~[ah@:6 Z&޸ctpsR9e4CBD [c%b(EEFr.ޣk虤%6W`sgN1[/ /gpч2G⠲VmŰЫ^I{D®?]MlOʥm׆>WQуJ2է6([blfe 7Op;(-B&2cf_Kq,Kp{J(ӏtٿHZyG&?,B1 i{m˥qq6|eH{hBI`GnXq7>Tէ )Ӽl:|;\as$zlAcП_ - Bg5.W<05Fj4Qy-1Iz0^iG+ jzK"ՏCUg "o")|ak8i^_fΛLg.[6H)tVLʢ_=hWR%^M;m0!pqgsNwĬ;<w;|%rxmS),R+1t+{ipr|x >c=עUu1 +d;` /,KX/OqcUuN%.G#b Jm{h?TL B:qk*g8b^w `riSƌU`Md/Q5Wk2xoc73}RvtF#| _lZ@+ZaJs+ɔ/c,-a&۠-g<6 -0zk)P{?*Q^UH;ĶvJjH]!슇v*c3[\ $褓#W2(0 &3>GܓLE{.OmBkWғtTnK+ hrQCƸl?.E8i#7x5^zW,+;&IQ#KeX4$j|c*4ۮ˜D`hs[V.uLy-WSM/ޟhz!ŴJM9Tcg#5,Ey& ͕b119/dX[p~&hʆ{ESOұ~)t>W5rq,'LfЅzUIyDJYfz_S |/B? )I2y "02"$hMWR˚Xa@z.M??ɺd_8v{l8E&-Msb;b?/ 󓠛Al!ݝ"Bzx`Y'BHm0sb2juXuq|Dx9d_Vp(2tB'LNEԘaIAWkTbz q+ ɐ\Ezd2.E#/2BܱnA2{)Z'8 AyXXhfTO~vgd,&եgSٟJ+IuMֳ A{k2Uӊ1*-OMG}HY ̥h .AդȡWRiL:MKWPg4;=aDoqi*-JӒik" 9OQJb8iuKq̥)EdwNa|)pvB@!qT%ב7P |Ddy>:Y8&,P(sRT{gQ/A#_W>Q'8b8ƃV?Єڣ@ƻR8\Bw?Ҷ6_ȩe%=SO60c#Ȃ{o6OqDP` ѦB1Dΰc .r x&Nj:%~+Q}VX" ocEWTN#gSr%xϝ69]VƇ^59SBj[+-ňKqo'921[8.2i>Vd} wsv2-0ݠ7_CUwrd!KkH2WD+Rքc_$|ny8c;A,mj:PA6SiT]$_%jt.y>qB13%7*"rxFE_ӥI-*kޥSOofq?nn-o؀Ϲ,7Nmr_Mq3倗 ?ƛ:tA ?UHiU;fzK~I'$b /JaIA|r1OxSƃ +9bqkiTzEђzf)ڗp6^1Yh<NrĘw\xv=R3gI (tW,nMc/!#\f8`e;8ZzY -4eэ(r7%Jk(Othc }LmZ|Xf~]6sv"*ෟ&}`!26^ϤGs(zG`\=T\l>VQ_$_]O;!]l }oE4.澣1oh[=[Ci< `|^L)u{d1|m%ǚNj|kïk߀| t^6rTgs|8r+3LEXI]Ÿ>W X,.b#ޝKوw/rde O{x^ad Vs"ǹ>\ ̑=Bo*Ŋc(P$4жUbt%vo1_x{9cq8ܜ,AB9 zK6܆,z(I6?Z|3],~s{,ec 6n\$ T:1N{ ;f@cmau ǔrL Pj*qFO;E#D z*IJ2}^Zz~&-4iAQ\,W;53wv : lg=&Va+6v bQ$SFiYH*zڜ&,z7<3O]1BY#ڶ$} ׫GXF+GP))Um!b9:OzN[L.#` Ü"KuL_؜,ÔW qg #<ΰQhc[YD 7i2 EPY){LyB΍ah)1Ver# !*ǞSJU#K@KWe|W + ďyЛt&KH\]@cY+pp^WqF>_Byմ5:ڡ om0-/G]RnhUzM mȩǙԃ{B5eMJ)79kޣI,98l@Ȝ7ff!4YdE>sYhc?|z$vhO"IkM_|IgZ=֮far޴kLjqs"`VMzpNLwf꠻c}6ako"z'Jo턲|D+§F2n;O"$9e5tyv(&= q$Ý\&3s /1?h3v-bY)$XQ.EPf5XJ蔢EKr=&*1ʝa|V h6g<,Es6`Xar?a[)sJ,_+j:WҼTEit3['SlJ +*)S--mMzRKqTe!r=? X '%@j\g١N8(g4{ ǣɎư17X]9oF[mRKݟ4J=3^cM{55oM]e]YGE[a;c[ݭX.c؊؊ (JwJϺ]byޯa4L5P$=גiX?^ůZ*i#Erx@/\mcn~ڃ.9--s|H*l*0s~hN]5uSN*Ν S37MRۧ +3ko6^JNR1NhG(iTͷ5,4հ٨HO˦ hǬvjzuv<\3K-hfӗJNz5/sxWiyt~Rj~-7bq ,Rp0pЉ4 W1{ Uj R󊏎irwKӎM9s*nhGLGDXpmS]I5L 벖=|md)RD7%Kq_f20=h\іbNòX̭1`m*L)BBZayW83k1a'`cHsځ_?XWOu 7b 3$L{檵n9;T/)EX1)w|Nϯ3 } dkss`X>_}¢ϑ GpP ; Ш/6P3ڡ-DŽٳTU]ܦH#*qf ԩc5vsLmp`GzDkv<5ϛY}E:EY깡_g+ulQ 8!.kz4z>ŞSFt$Kg:~>o3=R+ST.QP '*xMkx詖Wf7Qt;Rgon8p {>z-O77h2d%+L"FH6嗉H9 4 wkl{Oxu.j5q8)OjF%c8R`B\F*<2p$ fQ2WGft5ޮ1C86':1W7TQgJ^{2dXh!$Gs9pd KQ?7ˌ٬w8xŗż־Ed?.k r~bkWl%ݥjZM|hÆvG*3] J-WH6~+LJ҅R3zwad3[ L}#܎[qvBtOڊ]陰Ւ;۱U%uR>9f}o jQ"joWˇbq]MLVfqC4|pH+we|gi*+{LEG3 oX=م̝H,q]O;]iIeo:bIs6Tөp\z%3"E|mH 7<[S}x~m#1s9&ގA0z|agHkp 3 f|xc!ba0""~6A{!j}c }`)v|{ zp'ia'$aU2ls6^o7#ǡ"֢ ;d7Ă;b`_ %4]o`(AT!q[4[)g:%?led3Ԩ8鴂>O%z-g^kd- ~zNLMi>܅g = ߞ㭸93Z_ϼ4n=y01w7JhD~g(D?d>XbX-#\ތS a7hٹonki?Bx3mrܞt[U;&ՍRE![&n2-GY 4OvcK-W|Cj|.ēYat#Y.\p0hRw!jNDَpI fl ^lYuKs/&|Oouz} u@}0<›8wwG>=x$cY+#V11->13bS1OU3iU(gh-=g s?={d҄w:"gJ ?16k0yK 2JY*>vs[){-YƂ}TVj^b_))d~"7rd3%_NjWzp"'TPGQR9 t:fٱ:[N˙ŘclѲw~.q "pݟxZ^Qsgljy^)2Nf&- gZ:pq#GqFnT.΁3f;J`B2&]Ɨ^j,x:HE+ʸ⾈ƕq,~Ǖ1~yl;y7a{|Gf Lދi`!<܇R-=O@y)B _|A"sp ^O4k#q_3s ǀ\x-%@t̗%J&M‚e 0a(4yjKm=?;L;Rq 7Vε,"{ aڠCLxI'ro7d8ZJaI ^:v l^ȘƌtȈ кGWg87N{u=wPqŒktMArv|v_NqLmfUbv=S0l;G!g97S;T4{W,ŧNyÏ0= lE <pQ|F y `t2LD~K*f1}Fpoe6[f/;^W淶烶Jrّx"! #`k:Vz \xwnV"~H5Ǜ^N80ߒV\A~&d)$tf>s]hrZ!c,w[NWDm { ^wkɚ5lV`΋9<+)/N]0Gs wЄn8L9UoNZf\R\5i9yW8{ 97Ʌ5.BpfD;zP2 m-X{ezSP 9[œgٻ{Ky$UX3쎹# ǟ@g>;\/õY.>IƂC R:VmU. P! oH8_śCx' nEYemʕ;nF(}>0g2n `)^nyhp'b=+ѩ)pP&ݒ bvΩػPӝ,&e?i+V7N,厹W}_\qav?۳j5s 4g{f|TkL ŝaߖ[9åC 75BC9zA$ukc.&㜋j v҆/'33YŐ3_dSsؚ,Ѱň;e c%]wh, U=R0r!:Wsh/%WSYhr4%K9ۗ*F*:ogȘiCuO[N\J=\}ȝզ$rcgvdG-uӜ{61ewew_1 ~Jl8voEpߒg[q~eH5mӋ+*{Ks{ 2%L>Y^}dƣەԲMt5b΂{rl 0Ç"R7 pdZ6ʓ罯P-zU~#QW cg#X >+uQ-Ua8dh yV%w-rVdDXU|Au '/0<ƄEɰ!v9/s+;SYp?ܮY. S+F/~87iqgSF0`W)FBqߐB5L 4ss;gAy&]x186C31s^2f j >WvqY/u`S=IqY)reV 伾rz6rOǸ̝&eTxS/0 tc¾v)#0PWQbx5ZEう˚9㙒cK-IzqI=Vr>eJN i4|vՅsC ڦ)3no. 9ְB7H"[PGj /CЪ(?cL5,־hm I&5ÄۊmʥnƼ)˱xnUBDMCo x_pt]8]ov> ^v<pY#Sku&R?[9El2UXxfbx dIaίs]7+z¤ s>99#]2$aw84_|DNY⸵Yr2+`@ s>jnp2x3G˘g sbN䛅ʛyپKpoiI.ت ܅DY@D 'YFA=; gƷ3ZfE{&yo@'vF X'[jWNؼ+!ϲB!)2cB~#22# [veG1s3ϿwB`mD mTr: Rj1ό2egC*g#691RO*W_4inU΄B9MV̸!ΌM%ߌ)ʚqcT%{7zAC7斿}3ۅSW"2rZa66!ZgȮLQ)ðqr~` *yqȍ~+\chIYs'RЁ9~#:K8Gq5uִo'<00/?\`BU~/ оo ,9v#oaH})ZU 0#ހqީު1xkcxn 2ا7͕~NNLN˔w0/IDŪFYKˋzq/>jJjk^l(圄BL;f{>Lo0?O|lN1Zɘ^x{-&?Ʒ )U̘hͧ8l{?qeqg4qa]L v~VԏVBnum&g OC9-&Z÷rEǹ}'^sO㏧thF4ndHuG՜rH_5Ӝ^PMFTEfۈ{_C 5fJwl8[>E`(ͩ޿\}^ FkpViƙp8=*yֆ-fLnCsp<=7`T9|*Ɣ!{_Fg<.LhᒈKݐ%q_EV`498ΗM1q_r51&91̃yQɛݼaGNhI&ϵxx _fV0r$^JE l񼞘+'|I ;3.PCILp㤖<ͅwi&tw'I)BU|jxrrVpVA",}oaPFatX*s2g:t'Zsϴ\7ւ;ZD% =3.=8pʼqV{ R#33Yr&9D%ۆQsD cVUL5 HCʟk b^Ynss0KyBwx3Cߧ 0ղq'Rqgv6帵6,A t')Mta'מam>Nug('gs㞖5s$l1ƀyXq@mg|}Ꮕ `ȉ1)$+b1,4)P肸&=q+<4Ɔf)w} \yٍIN`^d$4S:qS<5HpR`+Z96VjWd`$,}4PGה$l ߄<Ա8AN<~SϬP=ײ& 3|XU8_hܻ5%$fkpր̝X?`[DhLPvSfc1L!k@1,a`e!ZAm=2b}J\X^:ƚ .bw!lERsC=>vcȔy;/wdRӋ.pOȽmlk35f<'cpxtZ dC'ls[lCuGOwŴqD՝ED.J8sX:{wc|T`+mbwĴn)VIsz@Li$a\.Cφ9ZZK©9-gjc,&إa̬Ub.+Ud+kpeY杩Bg&ܭҲcV^2p <z͔G:g(qe@qROw#O[pR<.鸤OE +w ˎEbĀo eUVK>Rq Ψ䒎y2?%q;Y݆T8CÕlXyseg"%T)OKu:ǁ6lV ǥ#= "Q+ꇤx 9$Y`znN-9ثr1TKRᄆqK|jBݛ+I}o;`7D%buoag4~YGyBޟD+tqx +g`vO{waE2'C)FC|aՠ ؘzȸ+[XdVT:f >Y*j_Idπ},éތ(u{fOzۨ37(9R _iIƜ_ _Qk|̽0hF(9 wL>,E$,f_Jܲ4tqC.[Rؖ;rtGZbVG?X1k>QƔ3]D̼*j-B=PrMVLsY%B Uwc-uyq1<.BO{+ֵb/_+;0qayz;qDL#fTw% jsx%L4}+ck:yiEƿLG,0Mٳl+#43OVEa7XWr 6A >ȄKVrNS>|(-39pP3g]ة}\k>`WN0_Yޅ?ڲs^c3d (1JFfVZe>V&ܱ?í06-T3PtfP|9=ҝ5^4lvBZrtuA #~Y)} Gϗ=|Кzl3;Ts'~WĻ, ax l:Kּtʊ+ŔZZ sL K 0Fzψ5|>Tc bfS+NYHg|ŘI:E(4æ3AVTZ BrD(wξ숅7)Vߊ*WUwjlQ Y(6dp*@5c]NIWX*M '|D>Ƕƌ5fx%Uǩ#|0ޜնߙr#gVmqa3g9c7sHg['rRK4WՆb~`“Luqgx[#h f.aD ompzaO;$aqjbc 8Șza)2gkchͅ3ly|#33|dܳIWb*a]"Sphex6N~+qzx$e1{q:n9gBui3_-$ONP!`D4 i[NwRl.Xu_p&؄ Ƙi_V1Mا ƔzCYSFR <6?~Fe 63vn&cD%fFG++JpW^MpuOdun q5n|܁q:6risŒa .>'ݧlh̶&%6;CX$/P=3įHE}_6ݮŬK1~Eބ&|<ҘL$b?O3ǘYz6m-yN*'_ZES%wsX{cV)ز$ u߱: _î˯C8l9a,a- 3) 0_1Q22R/D:} !(+Op=>J@?6̸NmxmGbcݰXw>zDV1ӄweׇ8n*bnf,\֟BщhضlA?qks0_f*mǷ%S~@3Vհ\ӂ[Y(yy셌heKsJ=3Y^ :'- >}M:}eGb">[&%Śo-&a0P '9֐ +"R ?U+1;}Z7ďؙ ;o?`-ŴuhB ξb8WNY5b 79m7Z0W4*foCt* Sps2 riL]^.2U‰]G3l1>ɇ?mP[ˤ&)' ~ 6&lLLДc/ Rs]!`xl A1YM'"9 ;z_a)v kv΀ 6O&ܘ^ҶPlΣlh&T\5IRI cٖlv:X2[œ}Զd#o&,?rm~=Q y9~"('|tt e8ф:^Z3v~z&/y [Ǜ:Tujͭ\MlsodFs"g(3\#V:pY#mpp5tY`&FU)y("s)6aiη2>㪐mo2s6Ġ6a ҀAC|938vI׌UbYx;[D:~'&ʐ2_8zs &M[z}gѵQ@؟`v.&{@+,o7M (/a?jp.ߐm QďU&|XJ/s?#`Z;hAZ)k'NWi8JF*nQ9\a4#$¬K,j4_BBCnLFȐp$CBayIR ֫U'M8žr5'A(;f/?:{Ajm06M9z{-!jGmud|]J+7V$ܚn^ CK̏Nϓ9Vc˞FX:r#mحec̲_/hw1ls'8Jcѳ< W㰳`f%11%MxzEt񎩈BzjJq~P(T?GqgeY4m,3)V|mDt[Sƿ=?Yr+f;=8uѝ'6;^гtI6Prʹj"CQ¾F?\ݨSsIpҝn4Bij q! 8bEZАfp)mg ),kǝ ]Ț#ٜxr4/ 8o#^'Nuط;|ΐ[[$>}YhrV=޳`kȹv!CXS]} e.΂4|Νxq3,zGHJ G?`f|?WgiINb?ò'49ݱh+,unBMM 4諅+aÉ 4wl|j1>2먈cs~7[;dFł2dL7X˺31\xӗiF*]}yqOb/m=d3ߋy/['|L'&ʗ)͙X`,% By o#&LSz1aSCޜa/_h-bnZ}ŏsrU]=cJEѭS?7ėp( G% O1j0הa):!%$℘-DEteO*2 d\5U58'es“ ^LcWy2PK,[S v6рy2N:b{x4#n')Y{3C7(HOgjIM_odt8~ErwfWryV Fߌc?Xk2BZ-Kydq-3tabɖ.ɨ<9GnNU-T䠇w{\^ CЦyfc>*W`YR9!Xh-y:wK~MzbTD0DD'CH`k ܊ѿW{>E~xf &e 0[W~JR,NDZ0K>|NjVyN̟E+co.RfaR=YrT>GS "{n^!x!ϼwgNWp-m‡-ᙣ_6Hrd>,\ -5ɇMo>{o9'H8Ri_G #"w.q7 vyTգ1*O:6V\ٙ۽!Fqst{`O>>+PcPi?ڂ+%MhQ= d`_93ҡY;W4(_Of=a }C)yx߾W /\:aB 7(EVǴikWmqܕlL2J{IXӛle]ʈQ*z'}-R21a'+粱;q^[oeZ9l\x{LTFim[qjK4x.e&32U:Osdo -ߛCդlx*2)LK_|!` 3rQGܲcW{1ID"E L`t: 3Q77zJUY\JooHR6UNpFs^V6;:ϱ#s`oXcр*aT(<6jZ5ao1X)}̿.bS=(rB2z:[j MEk Хt= ;v䊫L\oyQSʽ{B )㽥(Pʬ2ΈQ.b9/>J͛م^|ӝg l+7ӯrN(a/*ͦm,֒Z|KiAu;\ h*䆛r>Q#>춬PJ@oKha}h&sQC~x3gS]gޠi:[3ʅYSyCBu*=Ӡ .4q}r(.dWqm疣zWgYo'i~Ӗ-ܬӒ:DSlʒ%bȋAl8r#tK |i¯5zΥlۄG`>*lӛysd cŌNqEoߑggon|.o~[ߴ p|֌wve:/~'E/.Z'f_=!uєʟ{ф-U}ƭ[i}8kV5&gD,xzw,3T0ct=Dmt85D%z5lж!Y@1ϯ4~7a_}6`B^jߋZf[* 0i5DuxMx\_;ja-fV110_HoRmF=e9ryiAmet~ as>"`m>AR^m)&)'yI7gV4}Ԃg7Ӈ+}.c۲ 'gi?K@'elN´AެX cY]HX-]9˽IٛbB%,k'kjqjv psy{ue:}{10U@b'(5no 5DC(}îX]ٗ1?* v6Ş~_)2S>Fo((9ӟSCs9y\1> {!2YSSl͍PQ rT^%K|XryVbފ3̶N6LfMCLkŋJʀNvad'hA(~a6" vAqؓ1Ix>F/#3jS+j>Àk7olĸEX< w݀\#lxOfp?hr@P NxΩ84NW|uxiLYtkw#Mu?献#Wcw(@e62yfq[aʐ *u`κAt)mmu}A^GZ@Kʔ\̖B&ݔpA)ޒ2v-,.rFGR%eX^x0ևB0 -OmeVXF l'?Dƈo 6Q}02wH*Š=5f," @"ePzW &R^ɦn44/6΃qL9,4!;kOvbwvQ۝خڞ>k@'O6d }cOd:{j}MGb >NAYbП mGx0+Dž29Pwl5$A)tjߗvWpX4&RUF,eRCʠ3g/Ak2t65jF;׈ya2kuݛ?ڊ)Lr %0_gʯ)bNxz_4͗Rޒ1)␐b63\s搧F<ק z'q &̓y$y.Fݖ)ѳj8'?7cSR:> d|\>DFs:Ǎ[=s^zr;\7ʕ#);w:s!^Yl͔HSxqKKmTCu9+2pQ6#1 *tJZ|W#sN B֦M."!n,pwsoss;݀bu2f,U%V!U^" ꩐I0c(QXIO—Nl[9O8K8[JuXw%L ӪسMQ[ 4pvPtklw܍) 5՘v1>E{14ff>ͨMѮ.v\eo3l?zЧ{(k=ʛd=UȈRʧJxE>S=8z]<8Iמ͋J/pb]h6ϕϺi#3w9W;Ƃaȱ*/K>}ipQ-B+56=S`\>NLBoп!G 5i{3)&/t/n].JRҁm9KOg;hoY=$C4퀾nL{ >ڽ+:J+gtj+_\tASW͍FTtv>\'e<d÷LXY4m*ՙ:Pmfco-n (oJŽ7p5^a;UIѷd9~NUP@O2G\_#xU]E>'bs˼Qeǯ3;_OPL6>:]>2p<1{RK 9oȸP Rn.>L3t LQq-_Azn]s5ʎsnر\}M*TO`1gĂgX+c_ga*10&lʘM9/N{t0񢅉C?^ȥ~0G̲N)xeN3.J9ADWvhteMwfM@Wrl P>WHugwʾ~w8Ў{V6,9`+r oȧ ҄FtG/LXƠx"i0{ɷug5/C&*}ێ=# a fVS;f 6Զf+>%aA Rndk$ TgS\&[=U]͠ȁ3ܹ'ϜrC +HsT!]3yqJ܋;x}1z(3+߶rF^ɱxՉ:7v9.\8͙>;1ΆE?l9%Ӊ#yaWKހ9*5.3,CgYIQ6"q5:Z5/㊞a3Q!´vh5{6+9BEfyZI=[3l'7̓td9 |8{ke2'*3?筜>* )d½YtNۣ9ŧNLJ`:t6VF5f4i ]0a+^a(s:<֤@?.ս`ߜ)߿g`Ӱ,^/K0a6Rq,4_1*H>Zs;WZ(fWȸTJ){ 8g)3oJBnn2V|rg6.tt;i?΁5\Yލ8Q-Y& b::[\>ہcpa+~w`*sY1cv`@z5+Nb+^ZKIKA:~( Jp]^I8FsCZ:d#s}oH9_sLs<oqvߕEt沌e%g>,R]X>Ě{iG5Qyu:t`NFUlʢA權6䭔Zb{H;`~Ukp:tAX%h/tD>c=n''90YȸIb r~ehY¹n]xiO q嘍lǍj.\؅9gL -CSFsgZ q?fĔz&GᭇͅW 7Sp\/ɬtTMqc ;sEIP#iBU\۷ ڧasvC=mpY2jc~O5l+jS=k@\4/OΗ ̋XēzqU8C ueb#[qbZ=Tyύ\cGtec+=h3n6t3WXrz+ qb|ARS }NlLL=;y7_}9 &= @Z1cNO{=4a j17p[xms ٣M]Q39I‘-8CΩۜB7!iu>SQ=> Ańg_ڛGd)iRjCq2# ߤ}*.Vcxl%~jMuUiQN (?ބ8B*ܽB"g8(F}:Tz¯QX_X ǖ^.4m 3rg2n<ˋ$[NJ|EFІ|x>V!s`nmv4f˹5wPO5Mo`Ȩtn,ūҥVThWn7# l M+FqA#embgzlet$z?4?3[c*C jB7 yL'n ͘;DWQ, ~XB 71 G+!? !d<mDB:/r`M.Uu Qlq9/¡ѐ(`T42FU4ZDop*r_Hn%Pf0=^6/_lmxØƪ3 >Ɲf7ʃtʾ?X'pN;o<ʓyi'#sK`w(Mb{$n?Lt|-Aɬ:S#z|_lƾ7 }V>0˾,7gSvAwa|Z`=enLd^!gws-SgZ<2`#mWi LV|6ǃ1玐ݼ;܋NE<%ڊqOkuZÅ嘕ZÛr,/;G#.~"> 3\x-b4 SnpTuy̸Ɯ[sԄOp Cv ENegn nb!s x\ʭlP% qKWRWΏ79#ڔ?7dY>ц0w/~c߯xgyIFrhMj U9Vamn?Ƅbb搁L22a#GDp-ʆぱ:7`YU,'1Gy:q}+-r䦑 2SH 17Z}.`I!#^7Ч}+mTu_ p: :j㗅_9#o~ݾe!bUiMr޽AшTx^ӫUU ~dbNa.WpP ӽXԕrsnآg_"m95:w\3t?Ƀ6yḦ́4\3H_i,Q nE 4f&@) ]:|f 4Vu%LF);L3+=\d_vo$bR]^jF')}~jͬ@8U6ja{Un@ěLH| V'M1橲6-7P'ÊE] _T˞8sr^qS5!8*{nQe1/& `4M|GVC\3q8!/bܾ\%h (KībGE 䙅n|ւj;o=buR 0^_XҘO9r@~r`.oDJ-Q?|48`˛?(y?%U*cBǓk}lpP/G~јvz|ƆݬɽE[]ke'*Q5mNƁM__7 U-ڈ'*;2qdWDԎPk =χ{-図263 _l̻'þ\ܲ\Q+RqO ^οSkOlL@Q*|3nlQ6dh'O?ǣ<'՝[̋a WS-,\Ǖ}4JS*qҥnvB'=qE8ʧFsw^Ns͙6vKJx[Špd-?31ee5z>-B]E\#ʱ}dF\i"v>,O0/D:{:RrIYʺ0ԋ;^zodܔ+euAu:qAOiqA[gp_K'|isզ|3Cnn8j)/0CG0[F>ƆХ<]'e%y4n##ݔ;H `FNiHER#DTMf&Oz4 ݭo اҖ~91%Sf3U4 Y=LԹ+QנMɭI`vX#O1L3++^"{J 2.s&|!a E6PEY u|z?G9+Z(KQXoIUb4XI&Tuqg#'Mo)1]׾0Sd̸\ V#s* uh[ U8x=)P*)Š,ix;f nN )^BJ d>7iFwյPeg p=.𤁏%"+PJo79 svOR Mzy6<5ŕ AIS/E:{Yg1N=p#M:bn?͝2k{'5d"XǏWx*Bld)ƭ(@0 ƊMH+sϖ+[p/M5寞P+nX.~][bL16D5S[6]c;+_9#|cXvsr>\Kk48} TUա*g{j1Ĉ%6~Ό)i[B)\Zȸ{Ny҈%x{5": OA*4BNwet% @R@M>CF\:ʌX1a ^PgN,= 7oL=;߯GFňG{qKgb 59w3eh[pҡ.{ÃKg 9'lg@UIm#*s/frM- mjl@jou$&Hy>[vYMn;ϖ+~e+g)4౳B|Mǟv1DΉ84)]U_C7e.Κm8#s.]'{qbk#߯Ζ{7 &'bͳiڢbӝJ~ =#1mW2dCs[6fEP\;b"4aI-;D׳f3\ᗵ랿G:Ob|94%CB0oN*a1|0j}_#׳6W;$')KlXjs&<T#;ϣVLT8Q7=b~ DvY!oV#pw0-s/r#]:\:tbI ԨQ {BpNՅe!Z,V2K=)l4 Cx ëU 0`.[~]oG[C|wϲ)Ə'0>_nVWׯfnc[],F,Ȃf/{8dO3`B|ir=vjF j߮,)k/ڳ1զ5:ĬP|_ ~SD_g70Bq~WEn|kD675I^:mr[>qQ+7 wbZ nR8U&zc(>Wq!ZnD8u}v6|.Ex'9'LŢjETS, Ey(R{BN N(k{ŕ7goF jmġpӵއøq9(,'jCSJ9>TcX}?6g=ɩZ, ע`1|Veq Ɣq}&>DŽqc";e48 K2\q67ٜPѮSUa;Kp`6lAR|[UYMxy ZS:i1:s6*}<Rj4_3̶ƜceĻYkʶkM2497 [O ̘s{?'ؿfF^cKzUQPHi: SqAs-^/o4 5p Dh VZjEIhBBM vņB2{󷋽a{î{QQ(**""]~};=ws8o Fxf9WBoT^c TZ26.ȡ/E jicS;4A~FR3 m[Ŷhkj v+NB6D8R 9.Gޣ#NM4 `K2z>־w\;!> _wsţ{nUjUP4j6=;'(rH{ܢ 4y Qn}65$KRFu)1F2x8nr qƇY\r_lH=bXg٧F 6҃eSmK_uZOߎgjs}o,gRN\ )zumxK p"7 0I[G' =hs.tV?{BO QyU}*ujD-+t΂d 鞽P^1H7hW:Q˅'G#7ez0,ʞѢ4mʯ4rEMʡ\8˞"zf1 9>)7BƺkoVhZȷ.PWVfߕb}~[zǼo v=s2aj*?QݪkSљsġԣfY;XQ1ѺO}Ii/a>a:*}MlE߹?o+lo׎6ѝW"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0?N{[lnL'mb.vRcNv~@Thw?zNwRw5iwu%q3tЮGo}1RtcK/_]Ak.qL-XaiWx1UQ6 ״% At޴@r /`W(N9oߑy,'bo\owfSA˴/b<H¿yӊ͍x*{ߑFXYuK וji`f=EcolBD]Asݐ~ %`=C5M_Q^5uCa a_G- a}{qm!cwkmZZI)+pF 9]ӨPu::9-kQ#t a`k@QZtl?4 /cCeWUgcPN#WSiƈ`gv0KOШt7\~'w$4 < 2sJ*M7Ž%5rX}U`qh*~7F 14wX?hwӴuPK#m_Rӏ _t=gIζ\I_*U>ogc+ ` lYE/U-ٓo3E|sD̐` 9b{:R:߱}Pv MKߛf_f~#vQ0Jb`ZCeyV -f_mgRblhIWXlJb팣|FV ҏ2 \'!=AQRt\W;ic0D{ޝKi>g3=7tH7s7ٜ!$|""h|#E 4n%jK-e1=rhgLaw~fNYj vt31BZ1jh`Í< {&FF[RR޹јb~YFH=JuO}i]#r7BaS|㣭f~v ;꟩ QB1c~Ҥ:9]x\ ^s^" Ak߆wסt]gI/]$]zn3  N^Iۙa!6Ɗqpm^;XtZ;(IV2$qd _Ď"zzՙ䈻痚'pn0GM79Ɔ>K?)SK?fP@di_Jߛ_^2|`+iex}(5 u4n-WQBJ3xM\0S j/{Ȼ񱮧TJ4@;b%TG~_Evb#=A[CuG8 }|忩%^Ȟ(Ax)g Z%ɱ|$žF{̓|vV00w/'L~,ƞB`c>1hhqlddfrES 2-,wk]oS{WzDN$MoFDhVwAqd:29OѠk)Y1L@OdhJ[.U](K|86s&Ƕ>N-ܿSbkau+dwBD CfMgg#XD_Lp Pd! xNaXʱ+ YzP,zp~NDw`75$H]&|+ N|8kJ)\MIAhﴮI;:Y=O:۷.HW8]x@)O) d5vEGN7C )]`XYm2> ǖ }@*Mh,"!Y|nF}MН%F=C 2Z-}+H1Dmdg SzQ@ռ({84[Ь=5ڻvTnFw#ߢ4l=a&NslRjam&4?"崸L*CR\DC*Xgwh V3`1s $xH3X_F%PۣkhtdOИifTik98 >a#H͒?vPl\}]YXrЪ5@S8PKdsm(orl/[O$|4#. [y|>-@ܣɗ!⽟Ein~,Yy9mݕaS/nbfΨ.<5VȭA/,Q5t֪S@kk9"/^o8['u W61Q ]JB]183z;~;ܼl=cP=*%+!S1>Y"~O3GSL"Z8*S;LFSR&oÄi*Bb{,»&"<Msm@=ztu<%DXSC=qeXh,&Ig2JG !hgDY?)nd[㊂`|RLiy=ŬD_-iȵ4YJCWO肏5c2>p鎶tujEȉwD?}m;>o\N!0bVNB5n N A~>P4;]Sh:>HaKCqWؠkѾ^5M %59+\q`q$se^;*KMY`/|\'@ 5mw \b~= }2 trjܼ G9d)NX㦗5L/3/T0"kqmWzHaWVn|:6>'[Y/Ȣ>3F̣yt,;q((OKa0e4,M}_j:{m!J?Tas'a:M }{i#خ+*h5*mp*xpn9(Y#G).\A2!bw$*5lgr!l(le=7 Fn9ajn^&0WC uqT nH{2m>g~5WI) g-pܹnA Cvp2VU?O rq!~u}Ot2 {Ty}%Sم{ Uӛ:판R`)*gb:1ypϴtVcdi>Ki)mW"2 !oBwJ 2A%y cM'h6?P̌NsU$GZ)+4ή qRP1G{ͪ +|~y7:|jՎW~i m %hՙ5t1`=MɧW1):L-!Ii#M/z5&Sz ]eFQ +`XD }gw+xP^BJbVhS猁 #){kʩW9ma `+%x- 0ó|XB? ]ŷ=mGkRB)<6L(B?L B(;}VG6/Q" OM%Njtmq`|ey3h\{/*aBMݐBR)#d ۉB S#<G#Q%CB:L%À.͎ӱt'j\I'4j>>>Cj/.JSzsY~F&В:9 {S!n}b֣\:|;%F Tk񽜰>%"0(5܀ ^P=m>KMW~F]]3}~tJk̿Uvvw?zҝ1Yt!k!oS?ujl?YmD'у-VABw5QH_GUv_NJ,i+G޹f\x[Fj嫰Go=R[r\fX#-WKͰYXMoy. Y@7G_I\a\ՆpiFO6rsw:V'ReXYKm׷l6. !X[U#o'k(٠45vNU, 1>E^O}5F78cC%7P.\LB@7J콬Y78l L1Ĉ.Ud!}}_QIU*~\K-nrlC?$\ )(oϪ%~ 9lYhF`qY [x>j0eM;1g;pCF u~lvà%r; 4CI%m AѮ8̕`K8C4.{h&FbW!#ޜGt{EDш%(6A3cX@צ 4t}JhFUicbZ:7PHV֕ӡָu,WO*+qGՙm0tćvEJ٪Cr%]df-q$)֧SPb-6@(Q^EU\L-4+u\_ w.`L\gT P뙆кzc`2>) J?3'】 asxj)jmNјtH'%+Z.Cv doB$Xc)s,[4gM8MҌ o/yQg 8&*3à54!f|@́zqTE\5뀊#2ׯ#& 4<9V⻷~?0A}t _AoEb$9;+ a\ɮZcUT3VUK1>cpw xXρL:|^׉=e;,i-{[jlP^,;9OȠ1Iq96!a9Դ(ڦ#K\ 2Y=]MPB5EA=qv+TIՠ*w WWo;@A>~}A*2Di#߿_nJS4C򹸺k~e[Dh 7]X{VỌgk~f_L[4pQ󋺔 3cym9Rp^U"5O3Az%T?mQ#L^kBp_.U_%xFض6fcAn5ͰU@9U`c1߳S0 WJ0AJeJp0bVÕ*jt1%i?ݯ~obBz7u̫$J*<)Pt:?)NfQ q1mw ^Q)CiF"{7L֪Dd8Y Zwנoܱv6OX&?R Nbl ?3ԹW-X:7RRU ;SFz<,=r%I|H (#17cz7!k_a*Mr1<f87W]8Uh C,ZF-V|u Cva d1.s}p մ}MN.f $2XtI3=wE!}=Bj8R+`Q;ĜucLqh[8ε,0G?iQR_02^Ӧxs=9 .g}3)¾eSlqEE UsTK4uGO*}A{`˥XpTCV,0AD_ch$\d5U \1™\K}r)lAiHp$e^clZP15I'kx_:U)ow-``jŹb.yK m M}(/z0Fkt ƹwRhpp;T|~F}k t;BG*W@K6!4ENa~G_"HUÎF, rc/iMLPBK]4zCZaJ0oMHP'TjϺν̰ۓgu |6Dc1lq Ԑ_,R+C8U"{&FORlqʷXH[~- Y~j\:Dn ]樱,M!*i{GPm⽱+`y:z >vƲ!"NV6; c9܍1 k)6 y@5.рpJ7S~~Xyh.SSDđ4XYN8Q7g](QM[9TOͺ@w WI.dkDd+f +_]c}{ Gqz  jܛt'u0W;;]fz +ݰZ@%_tևfY|'P ę4m"}}Dަ){u͸FM[|L9]u!͊z1 qm|<:R&9~̧~S<>|0w2!TyO!JE[F W*5RFnXF'aRR4q2̹F:%$s[fTXTa!^i4:Dlr,"|/d06A#ޑ87{ݤvdZ+:BU stw'MS0;nS6paG,$c 9Үp0W }q`7seJGۗk;zb׾hƯj% ^uX~;h̕YW,vD0bH))w&ǕFTLGNfSз38VdQ~Qχgų0-NWEĕ!I~E*r(y+>NOg(:lN&Yh4ivwq2;ӉMI#~gTݳҥyr50[yyNhz۠^ 6?D+{LaenX (`Dj h LynZ5nU(AM:P#^+IrpSn+03cSUd651Μm1 +59Ut(!_]Iv\i{|?D]>%АgXƿ0:/D}1X.8&"dZ!pl--Υc^N}yy`W(' Jt8AǽEn+)S嘖$GrG?9{ɡ&ۢ!ƒQ;79DUi{U=zLя ޶C" L{C8"o&~쩧q%{}Gn4b9T3u[/ciƮzNyx)v}f۵&Xv>5awȤmi1Lng9oH羗P,:%f^Go}>w^ZmCرu 5y^I`T8":JIнtmU)s9{5EԤ7Yp2U3cՐVv p7\y*4#4h sRW'1ݗ٣_vx:n%P%dFgѪ8%qHheer̰<H`kjڝMchn:^̟b_5N.qє?W#̏6U&hkZ>ͱ) Y C_&OrFwY"&8 WpX^SBpO k xBZ,U {&):q8a+4rQ1&qec9t]"]~漤[bJAYK8MMJߨw:ۤޓɊ{Ѥڨ.>f۲U;5ݷ^黬`mHsP7 2OnF7x>*_~AQQ70tO¼/ Q101 0;0Q,BIin8w?'Ek _y} ylz./8&Z"V.#/@[lr(vRLffY4jQ9My6Zt[ă2:hS>E4R=L:\gv3_3rs( |$PׄdO3K)\%Y:J!|o)Q{&NՄM`1KM!ʴG[gڡ)[81N c%[ ˭ zK9G"o; Xl|0A+!:N BUtl._D_s#Ry[sv.~Ii+#nCL}HYCݏKphK{t2'FRրmta=C5ˢ~~I$|^cZPtҊ^UGG=; &r ^d~+ŅsnoZ.<;Nꄚ~8BM)v/G(Zss4Eh1Z syͨ"GrN&*̿{S#?~ e.ٵ8o@C]WDy.Z5Rud(ϧzUbV3t윫iR*"?ԛk95hA5c#C |_o"e+E~>Ǿ`{&9Zgў*K|CvB>AVK_p1SK uVHOdӘ5 5'SٌZL?S.$Mti:hR5 ii@R.?o~T=]ͤ͢zKiXOqכT!bJih4aa.eΧrAGO+H"Cy&dVtHQl3? >0#-z[l#CwdbDgؾ &èsvIbD#yPTP7Ey 㸜 eB_ibZn:<৔U6fRBw;Tr~F8^OjT6r[i|ēyA/;Pz <ur RRQuȖgjj,4zO5ݓVtK -UO;MTv"he f&Q) I0ԴHq4OE b<;Y M^ 09 JXtc}0$ا"D=~|h#,Ya87u ;FZ`_ݲO-N=|tC8~uO|ʖ氿DtF_i.?!q0Gaf' gZ83jxyAFZ*B}pHEoT6c_C&XFX EU޿'E{^t@lg'< V}~C%F-#{O3TΓo" +gp 4Ĩj \]OI i.H%YtNTf54HOh4wk ~#]^Zp?qgeJ6* ̧E51bZaa1FD/K&=/uIOZ' 4tPlPM~Ѷyt&@@:RLѿ:R 0_,A,< H kÀ|"bPk(AZMf*#L졆>iTtB)zϓu'ZW#ԋ0G-\.t{9SNyud\Out8Gѵ}xks+{\ Dʪo84j.f i;ް5G|;D+9H0gcň>)|8NY2oQSuRgo C]éL"zܤ]MQD)H\PvM>%U;1 zHptb\[!_uHI4P5D~({Z.e4^TjJB<|r,r=\6_"Wf(0+yHU5'}upۦ]AE #Tx%EyiW4Ӽ74G s٢ rTqĉ^0Y(GߕR,O @fKpWz+'7: ?jDXW&'дUK ".ve^E鈽t5-[\+A#Y~O-9ͷ s\vt *^rY_ym~r++ڐZX2vaN{kvq; h":Za6rqH >T + IEr+d&ÏU7QN]qnNW Mk'Q~*D:Ŭ1ÊN <{n, y%K @އEJE(\3ChPGY5Pfi. Ag"E$K6Đ-(=4{ ?]3U(טo#&}`F.Ɓgu1R>IhY. r.ej#"0j5[?Lt8er$;rHe8&R.'1)CtCջuO qĞHW#6+#wڶ$6: f$0p>'•6z x Fc#AM8z9|yTG)ݺY0hgh:ajA+֔jD뵕/ /tXv& _u\@S6/lc~"Tss =c&)gmRp]o7+Tp }[m Zs =ZN4.Γ#D'9fXˢ:O гykXzTp|A"c? +6J)YOe)s:,;?Ld7.{4::_RP]H?4ЅU#ҌD6ySK[r[ A4A)]BE^%Tp3ac6 ˨fB+1h/M9X8B 9Ld@Rfp.~Li y-1@7Sg_[F;'|jr6CZ!m>-7l0}blfmdwjү6Ϭ*?i .yL^ƐX+ߒ덟M7uөwg!93JeYgP{=Ր[:UIG`@=YՑ&ޯ,ӄ+TRI7.Փ:\7ᢑ5ΈqSgXNrrD#XF)5+0,Ƿ}u&4wo#q4j@&Pa|zڴ)Q}W||3aR-Rl`m-8m㍡頋)5dA)Iy"Ÿ"G$JC"hŀm5G\A?G6"0OhnKZ<&QlCj02"` 1RDHq $AY;mKw,%!@Hn:֏&J9(=Ra!##J=%q%X5h`rJ̡n4bɪߑKME-z Uўo)CU+IhRGTe!} @HO>$~Z\`H ~:Ƥ#(Q0)5*zy;R} vo3ii=i200\ g2E: \S H|!T $1t2T.=^aִVG?2\"96K1tpD !}NË?4[]~<()]^C:dU|nk,ah >d2U$Cb Q0[#O(y:䵘j=)Q m0T&Ӻ3ɕ,qdXn:4Iwv@V)fMcVMB}7FT A%(it EK.'&mi'Z+(DKɷ=-/hލ4`!Uv{KiCh믥W. J|⽣8GJhm4&tRUq~:Vv^W$U'{P|ʸ^JK)2PHJ>̨us=j~3aeRA XTEJ"j% UKnxV,¢5I`,U2tӅrl,` V32j37(5Op9֔1s>.D;Qt;MM[}/͜6G36^O[; ]h\MSg/@+;iN c:9⃉~'\"W<)1ŔXs(%.5gy&.9C 4,&Q|@(&2I?-vRj)閑Gj -QOIOB7aԡ\JT6r_;wiWzС]~tZL$<-J)Nvdy'8nwBL^K^!vHv꿯S4ޗhI߫cZ~\OӱAٴfy:M8KkiO귯w)] Nny,MgU[m3K#5?#95}$MhȭywV4ɮndѦr SN*Q^C9hPk\EvXvH70<}RɑB 2U!,ĘpƊ8]BVB)-0Y?JmQuI鶏:x- t.m E=IC~P<ݙ)DTG7y#:FO:)0z O%(<&H-z껧g TZ51-9w3'yIg'~S|Z4bvWѸed~*w>Q߽O^\(whNarsny7Mtjk':{dhƇr\[M!)sC{6SZgH˗T?mM'ӱ n+tZvSGYwUE4~d1y \.bC[CEHz%B^& &!ifs;uXԾg7$2{[ 96H2\%#_j+| h#.| D[Wә܍tk5tZHhIqd\C:̏~NF 9Y0Op:At FWw' T׵87K .9%\SN= gr izL6[%u7 9y[WsVZW*EB ]H1ag?I?L+%z,DZuS8<#MV2{-,iVJ\#N*2>!{SQ%Ɗ Ak9Ncs!ۉя3 0xa'R8! K zb.^U?ă|In˳Ik mmNѕ>d9%kLZbo&i21[E:ǯ6ڶuG::,4h`Q>\4)vP ;KSLWКlUH$6M%v*"sة%Y ZQV2ORG:*' 21xahadr}_k]vDVNLezW"SCc[[Lbr0LcN7+&0Gd3x_cY"w)'#O{@M_ݵR!a.\$R$yG$ ,F(#jxe ļȯT+&ϫ"qz!? zE( z%]. qx3{Hi? :^2L:#$5A-I 0b:露\ L>r/ā$g7 v+^ƉtǛNA* .]BM, 2u[D"ކ ~ow♙Kx!D"K ls>pFx֎Ѫ: Pj*cVzƇ&QKiWؽP9-s peO(O C;k d}.E"1c~|ě|XsZlg ̗SqZ#>.UZcv%V 7Kzs3b,>&mFAy;*[/)^?cvgqZ ']Raz>P]"N5?E;W cZ} |uyܿB/@Fz'' ^]g0"Hq ӳX|lV/\-h$EiG n{%PҘ2&/08JV1gxzx0HCoq"~}\ǂRD%8~j:RΕbj*DpseBX ӧpVs [a~s:Óx6rvz8:U;.BV?(أ|]Ai+1{~ѻsw!p]qkV#A XqER߸>Q29:EvA'xϐ)}$x=A Rn/F=㢗^9ZK>M ^D(0a1wc  ?g,KQ(AU8w0)@#:*H4sY#4aqzȸ`Ch5\-"P?6X>f3s}_eP᪷ri*k 6-gVq2q/n~ /pڂ{u9vrVыd!&1ad n "f?{b0UAT·ɠQTɇ҉ G޴"ѭ$}Yc :WCHaAL!k%H;XaxKQZO)D b5x{\f}] rh)SX帠@gdbQL"uQئM*BhZ/p%%ѻ%-_-FxoUfIl1L=RءBb?*2 U؆7O7Ƭ-$%g5iP!d>(ǿсeJЏ 4J< PӡY' >M;iߴ]bn3\G;!Qn"t[8,q^&ǙRrf+"7FQ?O#vRg0,B/k5A͇\T1 fہ/Ê;vxiagNWe:nKA2Ur6/ ;LQ6Bb"l="Ie|hB̰< 5ĝ:8G cw.ius:R9 O?b0O96 ¶QX9 )~|8Gdgqk%aLEح@F"cx jCbn²u M Wհ |Jhtqf#E!us>C;_Тk<|?Ř_ ݹRBw4G9*?#-O[n2fG zoF7s|9̱.m#-TKm)ߨg] g(E_@_U@j6(Neq%Q|f4(l Hg9)D,c8z"B Iq9n;)B37?D0zfceI68-PK+fkb|7-T] g`_ jHw>_ZH髇;\]^ F&ِZk;TqkK}F=XV*^r(xUOZb{OX⫕'g\ka: K g$I>M>{Y`d1\Ny8[! o-j9>!hFg#(ӂMw5RC9W}'ͧksd>yRDQ=Bh)XE9prs^ZiʟS}("!4`VkP6.{֨e39!$5O@DLl VWPLW"ŦaheJ0ńE%K1Oth=CE;L=mη1BM*P&Ĩ<qNlVղ޿lq#s㫏Q嚸wJ_xS.LtR9bj#aI O‘\S(mG ݳр-1Րr-LB3z7Fmhri mBT_Oܾ 2lM Nay>^awzCHm!BX$1VÔcuBxa t{Y+Pnxs cX\`u^eU94>W `+íƐ[e]u׺K;6#}| WIi{3kEIm.ӄ3-+qp >2ǝX$V;8 %CaU5>Tc?% r @ oD9A tܟ%+7 ̷Y!5D(xf.ܚgad*Bd u*@FfO &h[c渝glQec>Cn}4M3橭{#׻ 6Đ~~I\w\XaOѦ&z8_.T<5%B6);:u!XnXnYC(t)m!E΀yǢOAm"!F_Ӻ^#CY#Y>ڡ|d)|lfw'#9>4SR@.އ4+^ e^MQUχS^z<{] hNWUR~԰_ 4 LE8qxZc [8=amaNGNj"39 X\( <j dIp ^Tn>*^mS#,1m xX{ڹfpecGӶ2HfCd J ;,[n 5 t1Vx.wB8fo޲_K F)s:!R=s^ՔF_YdI6 5Pen"(V2"+m;U66Ŗ8M1!u%)>|x?LߕmkQ4rEht!KhZ1aw-lЅ@dn<)1W\u.aUqb3X$'A%'&Vk6SZ~bv!!N` cB4IP`) b$7*\+xWC>bLc$"8K/j(JV:BnMTGWsZfckPNJ5%aXYDUZ sy4wN wh2_mAC@)̷kAh[8e Q6F}(N,r "ū2la1 ǴDP[*{gzx򖔒oC!e-jZF ?{˨( jF00]pvlvǶ;@QAQPn9=^byuM<eK< 3 kO]h7['yW.]z8_6B=?b` KhZ=mSPrb.r@Tϝ0>ڃʊ-Xf*WuQ7ȁ՛XFN{z0p+cۺ gpf'^QM;~fqnJBc=(cLz5f 3;5qЏ53`fάƕ3kI#07co93JAvK?:.bh5VaMrFybdOl w8M$4<C(iK95?3꼄79Oj~zF#3}pf3Lv}9)ƛUכ,>T̜bFV mkEYXs }V!fWsJll]2Q?W K܏' U?Ŗg8kk13.peB/v姏nCVmy%u/GHD BX]~-EX͎%B2g WnwM]x '8Yz:Bu 9$P˦jfE)юNBcL{Mk[*ޅx'F~ɋ0Cc5OZպ5, } EEV~u%[ aּ'Js)uWYf':o#9[C&ڼ>^tn![].|͍O*~&>;qEoB*{TUu[NS qH{ZEow;V=K.hK;<ZPt,2tga6+9%N'2 OtN5Sugw 5{tS-iveb_ ܊uV`82 6k[rCEMf\2̋+Fr>o틬 jEbY|.xǏJ[#^Jѹg gF'6b,yV/a<ȓAM<&Ml̏ ۙZ/xGhzi{ ;b):?/8 JLcsmӎd|9DQWUBoG.3rCVeǾJvWPUEOK~T1϶ksXlXV+loO)$ʓGs^-g:OLe'fj-gW/`A&->Ee,9 ~EO>O+${δt0FkOE.<'>wue(39s'~8I{Nu7z %$OH9pKIt5oȚwC2t M\' f˙V64Ec|*Eνx'V,gŅq51?A7N(p9=k)_y'^[>ThOӁ\1$ϗ9|[ XꨙqZ/rs3-}#Wp\iNkżԒU q+Z鏱g|eg 4n8Y{+^m%[)LS1z+\xvcX{ ⭜ϛ[2|P-ODzK?O.hw`0LV{Rc$Lx!vL@V ;>A!fot-Yݗs 7oߏb[('y( 6+RbM\&-?qL3kj <9NɅz+MpaY:;F#ÿx%R~c,a*Hl8x%5X/DG.cq (`](Que0NA\ l*eؒeői;dža7)%*Yhx3tg(y#.cvfyPÅ'繳;_}}8;s.x*B; |ac9Gds;Xdd:n庅J嚟֜R?Khp9jlcZLd]MKix%-x?qR)T|TDz'*׺2|-TvT.)7ĖmƆɀzơ(7?DuQ"Z {|9wP~rzFlg` #72zZE'ć_EzI  ?G|ނ 㱡%խ U*-5'st) kKQ[K'qgO[_5SK ޏ3Q+O)P8#3p2=/-rAb{#]4}-;3Ȟ?a_؎yزfZ91ݕ2NV(qC#tUI+׉9j_:_܊U^wgюe&6S]GűPF~Xs)s pʂݕbn Gh]:9xg[j{A<W~De!D?p>)x~YSfL9p} 3hP(xi/ĕ7:ωM:^ 7{N%:a󮓁-XxxA/\L]?KeAWϊ%}Ev"[cUW,}ky>fAB[EVcj֟I odAr'f&abig9sSSg޻9c{Ʌ7pLiбV|@S(pyI递cnqg8@" D0n2<}@z=̪q=1V?qS66Ts1fx[:fZZiu/cb{cڊoϜ Qӷ~_?Y,6y?}oMӑ7# 3BnHR `ĺ UUCl$gjumYWpl?6Qq];!~=1(ꑀ-)@^RDUIOx+<⪦I-:fěZiep6ȑmQeubб-d62/9p0K*tL?26䋘/_nsߚM-n IS!p\sK>Э(X{wb2><"e\)o(6BK*GΚn቎[FBjC3ӑfe@(n6q'>Fn41q|Ngvcyg;/c0hmm,x\J&s gHYC`I_ A8m?ĸwxchC"_Dq8=mS[b(]St+ ( .;/&`T6 J>zg?=bW;˒:"#',Z˯:K.m%ajn3>a "wpd:iOːd-9_|SQVzOU1GG~;} }Αs<ޅ)_;;soc{x'`ϟv60_u^'t\"UpZ[%s5[> Ub,h`Ӛ[[ʰqjpSx悈*-#y9/ֱj-7220۞^I9g 2ڑY\Ձ&ns(]ͽ.F612RƷ蜝/6\ pmt?n-kQwh`)Fvq/55*b˺2✈~f-*?2`ӥgx{aݧVJD;61iFo-AdH*ك:3~(ûn<<_`|D.sQ^8U+.8NaN1kKţ X}OD U~ [t́a1gi%Rf1*WIųEؑ/QWM<,p|+x<@sl5J]Sȕг#3jgi豒vܹ]NGW%h˟*1[<܎Ħ_nPŕfEbFyEu d;)afT,Q^'J"s`t]fϞ™q]Yv_<Q8b;]tdi9opi['^[Ls t=RT4V’x mfaC t|00rGkxg-u\LA2$JvO┏iuOAu^A1' fr8`ЏC9X#)#G!sK/'mƲ.6_͡Wf1+.jO$yxz- o3PẂarοĥ`9sB~j|{ZWy7Jee\T_~\t݊wS򊍑ksɞSO"gF61ꓒ(*cb;F"-<+N+@11~--WX}+hھ9]uzjDEO,Z"eYbVTӏr3T",,C,Īؽ=E\.\ܹ ۍ{Rǝi?ɍvѡX2CE_ZhxZrJmTL K9.N±{Y,oO Zo ;i Rd!s_%(P]e[ScF^HygpbC<\jf E;2.yek|ƅN_M|c/Tl;V[Mby"K"}Gp#kcD5Lž[؝fʶ=05epb}orr#E_xz= u-UD0@W3 Nn5;11X§4GլHTMǕ\Xm0 JɬJ8(1KRȚr:<.6r}_%ر͂DMΒ%}j+镩a:qRd[+-W1p[ \\0ՉSD&pSln/ff֘Y*^`pOkaG5kcZḋlDe\C~~E8;8ނ/Qz'LB<,{lhW"N_h0{BSnXv`86~$J[i` ]6.\ aw|T {U+∶>bEig;mJq=Ut+VS`\9}xoc^44ɭ>`ѴD\ ;0;s>3VnNƊe"UU3=h9`w#+\|VI&?gbv˛ŅjWy]-,kk͒tM5Ü5|brWool='fS6X0D =KTRRVã=_拚NJ*-0j.|t;xj 9~=Ye2%CL/8P=߯SWfHj:Zi#< pMs" YʒJ,zifRrMj>Z>TqyjaHVg\;jS'8= .xJ2:T_aQGϕEUj p{Mnw3+?_$|+(;s\A5>BSf*GcdTfiR&.@ Vh<=gv(Vv%}%٘_-q9Zy≒ ixqoWXC3%bޯmˢ6 4k֔%) 5 lA^~ucZ*c~TC*8!aϮW+祈 l+RrM6ԬZ͈.۝* `POn.ucG32]K*~P59+*ѧPZܠ_zVtSkr?rނ!5W° !0~# W,衆>UL25nRB r o bvm$WOv4Wtgu&~6p?;8m:|"%^W2ɻm(4'\LGiĺ%8 =%-ށ#cYž9x1+frz63pg&ȉZq CBfoq.k0}X\'JJ4\^S&?e -^^ͼ\,V?`'NxےAklh)ͰfχYzw"'sGQ-٨G YrQmVeCةm To)zv 6ҩy#OwS.L@mң+s \=ʑ8/]vj_⺚ UM t@Gp#G-ұi+l`K^ϤHtzǬ,MOt|ڑ':j(~ GZ^0pCG}taw(6sG8sڶ g]13=Viy=kxZalglI%*bH?DLa@H;xg)1"=fB(xجh(V `IELr%'">"5]m¤VrOdF̪šrImuJVP(؅š[\|4ڞ]lA't^˼0*m2a9\v5vZ,cXk~YCIt'>&J&ξFnv7GPrƖ)TvEqX2||gz oʙ\@gkD_*>`Ͽ^OIׄ^du##B҇߮ruWڹ{17=Sdy'ց[9ﶁ gz pN3@C[n=mͫY\x;?#k:eK~Y'K=LKwJYiq?Nr0^pUZie #ߙ+؅'.ө'W͔&9O+%xqOsg(VI>_H=߄]Mm02$|eIM`OcCygQUypŽGױ2CPϞ[ b~vp瑙^͋3t=`qo9[0zG7v7u lݖ-Ebx_k6+S4Zkx(_JmCzF˜zWf=3ʍӼ݇S}yғ lL@_حWq㏉>9VFӬgX #pkDtۗ.f=KXy6>~'npq0dkohH0ꜽ|W;bgS <}R,|E4*uF\~ /3np&uajbfJZ:Yrx,f}A$lzI৴=pj)b#n oq{fٳg(G: g#awהLRB@GvAg 3^4tga;/\wb7j$4{JWs f#gP'm'19Éi`H m 9*F甼5MͰL-0q`~xpC wͦ+6ʓRtb>5oqU r6Q٥ MמC$ Qq$3=80Aш#:~,x6qhZ4%k . bq%BPm ;7nby{ؾ-ʮUe>+f|vP^3蟍ix- .sX[)WPj?1U&(ӱpS{r*PѶ5#:8N霃pZ7"ڧEE${*NH3T쒣 li->ЛWXdtifLq勮nsՍ.x0-ͅo,' gbvzyێ!撂 D!ЅAF;GˇpȁJJ&-[ҳJb`?#7Ap#cxsy+](<$H'Pɹ zײUgjX>W?m9Udr0.Gc(= =8ԶWФgԴJ&234 i8$> }p>mٯ3i񜽜- l6w]vَݓeLxDeZ%n\I\כ"o{1;_Er^+rH3; _fKl}ᖌS=ʞ "bg,ªSjk*3wyog;0g^qu&ϝ]X\Kͼ=O)vMRnTrR5_jnTmYKp{mBf48۟ ^(mRX[PrI!.+ar>^KkXkCK]AT=á ,Z0~[ *YqIu022L>/XH93(VrrԑIBb7ύ6_(:|9W^5Sמ0h~vk9>hk$-yÙ+΋ai-| ._ wJΚgl͆eu4!R0xQ,j*PAf.o@F4֊ $Ht6!y&RpQ0>|dLaG[ |9Nf4]kK}+՜4DƤjJ3@7ƴ8ՙV#k֤̇~ =8"܉]6ظw߂Dhfj<~Z[+)Zd!S~jAeHv^a(9qݧά;ѮÅO#ߍzQYzĕV(n'7jɸbߔO #kxT˯ut\Y~+)\cQ)6eg"DQc#L$V MF;ӂVWMͥJ27=n% ۊp?4{J`lZ27}h4α|'uWww2Z`z@n[(݋g>bzW+v[Ֆ?KBn8l^GhrߖۄG}08SYSd2+)0FZC$XaݼDW_²TK%KԹc6ecXı\gc4rRraFy\S\P)9 cfdf#CòP$}NčWqw J4Pwrx^MT,a0 ;c\$ + 81ϓS~[ [2o*ndj%g/mږ'ޒʉE(w}! #KC̒JZm1}={-GF!;c]q+;rM/S8_^媚krA%دE동q){ 53.d6]-^58]"C~l yJf|׋~q$o^0"[Ap㠕 OIT71_x)Dͫ0)ІK_ ^>k*oSwذB9ZSzRρe /%w #Fr` ?yX"#֮ü5`F-oMj2|5~{gi \޻<9zu6-=at} 89x |NGͱ{GtQ ţFF2|XƮ-MtspxO{;ٕ)j)bIFxKjyꁆ=\Ξ+tLeRQ1/ n>cG){s| M1HY *g\OXFM[u@&K>&~{s(X~xH2w1.t9}wߏ\oa2"r~k͂0a 2ή`g)v1#%Jgmݨu.bO}9#`N{' 0<: {]'q_/Eu}&L߯e@/>ͼ4Q?Ϻ0+paz3c֫hRЭmŀ )SպlH0}ӌ/0 Ѥ_X~3Do[.ЗX@K}DtKH>ު4.եicאCTN55`s>kGG f_{,C[<&Hƚ?q6" =b3`3O76>\%1kSnd)]y)p[rz"s TD"=7=AűG[W[Zv3^݆y0+RL;*cfz+}&pgk!;ԩ2N5KG1֜49/P7Pt*daD4W{ry;%M;K9{>\dOLٰH&гN>\[,7Fۅ?a,v 0<)by0xRTE*62䎉 \kxÊtg. b߮즦El tPaSvXǔg."t=V|io>Q *pX:VG~`()~;3{`wAOiq~U\m`ç[Xjn<{ςaܚdJ:\ڞ&ނHI~p;- {Z' -o?8Ie~Q%L=5 V;CfrNԖbh [P7qf ][B|.%)ҟ&`RLОF|:e9.܂ߞ;Ҹ%Wj]Mi1p6w߬ubjfS)aPw|dP'8Ü湧j< Glz`qP}Gŋ;=0{Y Ν?Mu$Tzm-Dd3v'n51ڑۛO}EzԴ3s̐ÔJ=,,7KpVI#gƥA92>ßD$gcB׬ő\i\dN6fioDc>%ʊLWoW\\р:3F[As9 ě랃YC NXs&cG`|<הcP~: _%4`\YPBAUq ߰eI+,g}Cz(co-r`OfKYōqNi'L6TCn?-N)C=jwFaT*D^;a`qr:cL@ǯ;]+6ZCKgWp67vsg/5[hw6up%ΩfibȓeV͆ !=qU_Hޗ%1( #21N޼8"C,xq[7ٜ>C"6h[W^FtÖյ.̒0\7#~0WM`UwgJRo<ц~_-xf Wq6CB,6H _bjx2"putl$96\wX]5x`9Z<)z W7ffjEv|׉K858TE58o6{>dB&n2ތWVdG3dP7kpZ|(Ų=OHRa#11Eh\SH!_hldqI=hv!&Gaσj Rh2{OҦqzfX $s0۰ܾ-GT?.U&,1]'cF_gbϭ|o/0]#6ltCv*pl@`5ƭפ','Qq }`shSߘGE&bgԧZlwlx5g4dz 2nd9Up_l(c"0>"s:~ÉZIfܩa͒| [|NKat Pjބ"*C⑑v 1+ZN^w]9g{9oëzGv sBZ|ΕBǪ_\XEfQ3`dT 볈xk64x3ˌƘsn5A.\Xە.'߅ǟy?ʝ1.,ͱf*#K|w|KU}:ϏSgB_ƱU#fb 1moBzw">x/ cn-RJg|TLD K׏ա=.41!U.kdzANWk{kmm Uπ\cO\CiDUepHi~9=B&`X(x G`BG4fs&[YɌ)f}Ex2-AVGVvO 3?[e Gva7R:&judJ]+mu @Om'joZ5w{zݱ-=j˸|ڐUǚ~,8O~ iݫ, #-jN뵨?msaŎpX܋@=Da, 3Sqxڜf2U)JS1t?ewiDˁTtڛo4tϦ-Ƽ`?1pS=n;8!o3d8N~E g‘z|mzksR*jl^3X "QՈf5C{i ?^z#E&w1@[=Bםaz+tO8E]uUz&}Vjp?Lfl(t vGrgGc/X[/htxf"އob<8B?z|#u.EzC_4x6pPKc3WҒ :CQ)Y' jHkj$02OXz}{8q 9[i(1#K]w陀SS^!s[ sH*E%x ^@,=SNvz,هA(ϱSu,\.xd$f'5o:%S %w@KnpV|Fol2 y%R ~34gWxM G-0Ӌ#Dž-6΀64yR 4)mRɚV77RϦOW`j2Һ#- 0};X-Ċ/[;ʭ(DDrV^|:uxKsV=SVj-wLQV Xm-ΜchAqW1@x5]93" nDExw z2:IDY{2i NW% 4$]-t:`+Fv":~[l@G+uFK6p'1c=Ӄ=lށm8d ԠSzVHvy6c@8AUAk9W0{{z}/3SӪ4JTcp͟sl_(n@Ud6A\ -*As*Z^*M3M#,BCt)nNF*{QD!dW#@CTYB?kS}!c,xe 'vs'"ܸT¥-7?c$hO=F26oDra\SeAb BrTMUhjFtk@Ƽ5˘h#nLM)6W14m'-tVe٬\Z~`0D -cף_a, 6!):hC03\cLy*ѝ+pLŖ5Ƃh3r:u+TK#UAY 0Ю0톫sr}z E.UyQ0C^T aZg7:󆎰3i@UT2O,~T >M^"b FWQӃym9YRk u7Wt,J+qҽ+`z.:zJ4U}-:6#G#p}g2( /!;qta&x k'81={'AGQW] V6 1Tc*tgCc~qՙf<)Nu^ܣIPM:7j&M 9yU} i-5 #> ܲ-O^ez|m]4bdCjRTedVF;\\w繝.xؖ,-X9΄ 9{0/Vm9HiB#+P#^˿Ĵg.79/\^vޝ1Fr^UVmQuMhGU>%ȼ=gCFYXƬ`3~wg~nWM<Fd61iUԿ)Ӑ6pt.|Rx{b1JO4Xdy,(݊62wz¼J_`Ÿ"MhCt5rK(̸tt>?GC tT)G.G }[̠ Kѱ[U`f9n nB9|U*ܩ%qC/GaO,}*\gڎpoJSaݑ!xz_4`lـXieC+rfEn7M[+grxҭƍ\ڕT͑AyqGJσٞQ#x1*Zΰ>NqY^ ;v6:+tۀ\`IXQJqXJ/$e_TJ@s-!p"YtO+;}Ƙ( &،UMȸ Os6;YJ}2֎;=dGs~U7FP}(wa>fcKbOk=W e+fb#یn/sc»}A|g N_D~?u?܅礝y9M{sp4wfyZ/Ls~TGvh;_2&gieHj;(H@e;SS6x?&zp=9M82KP);xY¶=(< it[&ϓ_%|'{ArfJ=hwđwH8=Od_K 8i O0PJӖ|xl-[K<xTά ..sUa݅~/3cfuBг@T5{aڻ8#<*J Pe5\":63yAo)*c; 8x(M✌|Q{/nX_}qn*/&ckąX0_,q%=,dy(+Ba7=صq8<(w *-.݇-2׷ӿ=c-f%"lTL`Z)X e>d-Ac:s0*؎2uwNL+\ʁ]4{g((QSp4/=Q9<ύ"ٓY<&W%-1D-OgUHq lnDX/3n:ʆn7Nb΢6%!Rp$tCAC_7{+je/&d=S{Az7洇WvEBK-F\:4ekSll%4tιB>ݎ59+ =?n t| 1q|ԗ0 _XV [ :U⚽8RV=6o/1b=tCknD|bb l}A[1{CU\߃Knw^7 "XYrY兘-tK 3'n fPn( >n|}=Yk+c)ŷ͓B~<'ƃMirFOJxQJ];OK$$Wntk.o~*ߺ|=؊<Drv57*yI.gG9 Rc.o}x{t|9'i<>7םK1x/]#a(6}Ś1M]KmkK.|<0ڝ)yXɎ35co6}o0kc}[8yRpoO1<+TcD' k9W޲7G Ӥ(fco闈i*u= 1oL-AYb.nt 5'/窅}w}.#<%OJto9I1G- L95;޶'0čM ^\{6 Ř X^39,o9p9He#)tvRb|"5f̵vf) L G*iW[iZk7z.!x+IN JY|xNԊy9L͋Võ;= $\ab'ϤM=]aC. yYJöRxIF7f26(ųO'Rp~u.n1Cg1W|֪U,ȌE͖Nsm@یdy#WV!FPrDL_Lj1V#0D jn'zua$B \1UaKڜFߦⵍxEK}1XP{-9pe!@!2_{8A zb:g{A)eO37~{N7-1. Jc"GT9=xsm,Ԛ[lkoE(yjy8Rו ׇݗLxQ>țg[qIzɸ_<ީ%H l{-S2n,w8g?FKjR ^yUXaSV% Չx eUA:l$_Fx̊fmՒ, 4)&,]j@<Gzly-*ǝ):͞ Ktke|@[2Plߌa* \ʛRE'J;|d[ #S[{1}{?ҩm˵> Tmy(53e *肋#$ #;A7.*98ED=~*כz+Mmak a6<ڜYb$'2ӕ0NۑoL-\z3U5nI>ٳk<% faD/1q3U1sj{GisGmRy˔C˚k}F<ʐzźEUkFW\U$g۾3s7+*X+g>9k+7; ) qv MnVݟn0.ƃnfx֎\ػރ>O(3NsveF$ }öD$r c.߻9S-uPx@Ǩ-Gӓ\݀:ZW0۝ \.Iūx2.vsSY?Wjrns}aP?9=˨sW=%ś2Ko~}-߿.c$UΌJV0(9W$t^9BwQEI>*q2~zLseHm9'HJf)KА7RɆެhjŵ}xGCedJ պ\P PnK}Wp_&Lʐ)vr̃k&95SrPc:XDjxg&FE;^qk1B5 GIG؟x ~ۚwX wi>/L}^xhԄ+zE.~y * 1"ߞ݀*/ `z Jb]z&UHrZ,›?Cj*p GCԻda:H ԅ q; ]}JIvi6^\ _,5?"/8ފ ~9kWo6X(8U*|;[+9hożw?ephaEEX!k'~<>Y2Bf!aA"!#mwgCӬ 1{7<Il%OUYІ.lG/#gw[d\&X  mnE{'ovC XMl̙*豫G zkg`Z"vGα'!Tސm-;mz<_-BOџ`(_YENxDۛefy+0yvF']T{ak{k+NvюSVڰF8B7Sxa?4 "eXM1:h44;n]MGN80^hf,jى|voQ =IpL4 r@QYS醅5f{at[&4Ӱ7BDt}cI=9LJTC$y]Υ8*\ƒ2 ^ 'ez}- lqr&h Ya+lgS:v:H\b>ax%/bh/Y{j=\kMYaWl00Ev+X)5AoS/&4b've; ^/rG3ʝC,(qcNݑjx@Ctt7f. h˩>ސu2!NIǻ(ے2 NDԦ_V#c/+ u澟-Пߞikno %^:)˜7x.KE3ӊq\!;*P&#s 2N*h4ͧb/P0 p@B"{ɘsR̹W8!-GÀdY{G@a?ݗ!ۖt,蒉1ވqAw.`T*Zۇ %_=󨾂WH7\SRWn >/Gs%T&zbCtYQۍ3=p`lpbWjrKk-գ|ǹl{M%HEr ]Rb97eyus*#F-m{7rع֤bl_]m0ԽF"u̅( \l3HDx]A-x䩜4Z3tE+1'9=Nr?ClۥYƂ± j e*p`.~"=G9hA] M<1im[?b{]h Y;˕ -҃/'I%Vg61;XXn`ܳ\s}cxs11Iю;).fߞ47r &H]Ѓ2zpb/.KrQm=Y.eh7~1mS\_ݘ;YnP?˅9+D0pKAԜo{N15 N2de>ozW3FdH狺^xwEEkF1xD}9ZA # >ʆj*1ɦo-BلvxԌ E ~gȱ){9zqR7#OG9jeR(LWi"W{*w~qNΑI,bé9ߙ9Z̸D5+ZnCjUi:?kk߯k 4W,.Ac1C:|Ø+ASGhҴP_6 +Fms^,ۭ4UI":IB\O%}zQgi΂0M},>#;GL7g[t2R&5f7k5FK^ifAEFsbo<|MG%V<-łEy,}(".4[W*ċ!^JރC]9[rc.tps;1+Y֙ ҝشȍ^+@ꎮ|ܑlxs%6KK}s9v5g{s69}7~)t[t׆U2S'NJ0F$nij`qQ).whD\34/FɄ䓌xӹ7g~U%F9_˞ܰʼnrnԒQE lV %XЈ)άjE{L5yh|VD/f#LX<،q^ l N1=DaTEP??AY:3E>G} \s'wNqP?&˨?ԋ ].I?9祸r|wqN u 'Ks5gNv|.3rfGB݉{hĞ5aw6:KVft0Vs,m޸ï׵貈77ڣg3n֬[U|za\$iiW+U:oҡ皛f_K&wfRr&|_+/!<őg?R%Hաm&;۳kQ }`K mJۘ3UFܫPcP JD\;:<iZMLlu]jP|TXy覚 lKfS.?nD\LOw.Pzp';{a;,z؅{w\ջ >.;n;Np@z A@ww>ukέ}}_U*U!;YYz}Vv6MpcL,Mœ[9˕l̓9d wW/[~1|eΟ3ܔ̸)ɔ'ڲ-O=1bKx: n*/K5w4crҦ0]1;7$:L:_qeX~:d0fMsjWA9Moӈ-+r,/vHcY\Y ׄC=i})͙ܗрԝq:[¤Y_-C9CUgSj0Vg%u&`EmOF7MĻiWoxAs_[L.zBB[1 vqC-ZۓNz,ve*7&˩}Q{CcCwǶ|T}O8k+u䮴kK!F,jă-x҂҄e_|אffFt߀[|`R}oMQE0%%]&ϖcpx ~jTBR֪oBGñMH>B*ܶA2v>nnO;VEG#*"k˱C3Ι&un^W[ʹ;"<:7xSM#|>4ӓ-}YQ\R 4n/q!c*2䲫f `Υ-5۵ѿ:#N`6"#`cԪ4iݭ uUC=+0, k e%~h`+Iޛ&|fZONp|`LZ|l^I򱬁&7&6C S6vSwi1h\ G *Jb.)y.DbƯe]MϋqH:R+tD ~}?&+TRP*ֈey}r0OgƮ!w8oT}J t'xqDw.uva;sFw{9[_WCֻT6٩"lΚ]?uycQsRF[+m2䔱eؖwt 7LִdGCN֯^x^-,<; .'K%uW̆G|Vgm"ȉ96ڔtA5r%BT(MQ43p椗|mŷ^lŚY޴<{VSt%#. yfHL^2p2 MCb'8~BFJx)}"kNcʙMޞ[qw {u3ⰑP\Ŕe)3O!_p;ܸҝUy:eIi i>zX)0MTYx~@jT'D(NLDle7Y3x[03ۀ뱳3O n)ݜ6K>f^<ɓ{zl+.̒ʸ:TL"LKžXl 0dUHb+$?z w~sl z!{rI74\~D#PuƎ[,u,D(}~$gp[b#vqּ)3wڲ xL p+Nf¯kp_jýνO;pM.£2 ^ vRaUiP61~/]/1cNW"=7`ٷd5gh̘Ffͥ۵``5sN fTrxf!Hff:5w_Cd<N^Ez\RaͽSY?Xg!/Ѯ6U*G$: Kwax=DNp"po*WЦb޺R˯TxKǗr |N eV+#5t3?0/ɓ ]XЌkR%Tݶwb-W919]iru&blR  Z\{ɨM_)]k%X?& &\.0I)Vk@̯9ݶu,`B] {SؑRQU~C1B/hF*X.C+p*+}iښ1דq̻zTIǒ\m~m˵IVo &1%uh6ʌY10o?De¹E1-BX`_L Oɷy~>IQ?c0A,k9GO̕Js|PYx#YE!*!9]s"Noy(ؚ[1ֲA6<Ѫq&'cToWtA7 uEIX?}cIk'q5%Ӽ+ O6Cg-KnE,MpEiy6l`5pF1ZV$`{v-®\ hfʍahMԚn Nv۽vܶL9o3< Niu. ih씋Kpwqc9q5ۙjrWpƃ(JEoʅY1ߔۅ F4J ~R%8\*X*D$ebPa4.=Oeާ3E6?3iq)Z0\|WwhcCi/ ^|CYo2`_}uvץ9e+@Onj+YͨLT7qLC9-ؑdS&|6Ey q?ƴ61X97N!zFw`]GeDQ24U#9ɄoۺÃk9ibB A誚g\NᑉF>{pw#EZ0~jPu@ RV#X[c5x jCHF18f9:?"q4*YO [;WK6 TI8jd,|\*Jx6Vm_'~+{~ W* bv^eꍬVj%هfkH_CC y86#v+˃| _t7DGd;Mr`7kM X)իb05"֑8%Ý1^ZQKXlǀO SyiMkh16u9KgT5Z*a6EScIx~RŬS37b5n+<ؔ]z58-\ V|ƥOИ5R۵hhqg6С1{sb|DNր>|F>Z6~> "ن]̩9Ԙs:xjqe >eh]0ntcҽt'kiZߘQ"3QBy []rg,%zT35[@xl/I~\|4Ipߜk0ݘήulc/ i[+ܺۄ3ruD a"dM@?r^sK@iɞ}R?7 }X8<cUdDZ|sRY>ڏ,-u-2bIޝjljsܩؓ><곑!?56sJfL̅7":LgѲ\+%HJFQF4l?a$6T2{,r]5{ ^?K6U1cVM4aDWvE%h5(_#1"buXkOICެZbvw95|Bc`N @`.e:T߮ʻ+QVV򶪜|C:[3+'x@ߋf>X܋Q!gS9Aә' M b $W;?dA5Λ}5y-r0Svcɘάk{.Cmn3\ņS9ݹh'ݩǑ걞we=5{k+5~nVIx\? ou?/<ky#L<9ۯKiȽ'g`WjhsX;}n>e´61ʼn :7.>/ܹمcm9=ɀ/2}FߦnR{ۯUbt)˅V`KZ {b̃ٿQrJ-y:Xax=ῄN," ӤUɉRܶKqOJϊ{k{z`t<׼xG|GfPeVʊӬ9"ޝz'tdsCܥΦ{+GcՓj ۠q_:?FC1i.3`]3v=i]ЅG` ߩ9mo ^*2`y:*q|qoB\G%Qٿg2 4LĢ )J39h~;mh܈up-)m ^o`s7<*z ݓRV4rOo;=< | i_ȗ7!B0w|٪\1?קe yZfE.כ9"ӕNmnX0ш(;nc%ӌ'TwM.2!!0Wqc153;o-Nt;3בG꓌gQ[Vǣ 4yzGhU rdKr)D ~ q0~vGdg(<]c,jlic@緥x0 o2c0|- xcKO]O#]ƪp sDXנksaB cX4?TQmb^ szq'ۇ۱>צj5:,hDg;L+T]`;:w"Q]N17І6|Hfr\3Yyp,EYxs_ۅhRg÷aɅ\|oss.^S?`e`5|u; ٤Ny+ЮS*:|t{>{z?ҏ_iҪ{p?gcϊ'0kxCޙ#*xOKuvܗ1V;JG dtѱ^ =˜Btxc*->(+dފvK ݉ڣq&+k60/hqUddHi<g>Gl| BBsx a: FQ^9Lìi8 3}:Bzw̔2׿ʡRpM):F;|4&/ɾoVhvs ܨ]m=SԖ(\7v/zŤZEM:ӡ](GJF.ąjWKh"]vv洝(:t-ǖw3C_+J]̎yH0کG^נ4-(Сz5ȸl!71[XeW_5XZga^`(G~Ю=bk9""_FOpPZ[Dt2kOfK?6߲ilcXgtaa}Ip_| )賶nejW B|Xη-)+yv957u꒍/?èv1&Kc根J^mQcH=F7;']Z,Eo9Sx*m0&܅/aL#_bc2LSQ e}o*^s9*' <ܶO^A@]A%ߠ˿=o|u[w}?'?$jKA3t}NnjRg 5U[#uU/-o([-]2=Ѩ}GC+0+3##1k,~x_3 9Jv9.P\ܤ IR@ |!Q֓PtL7Ie׻Y}mrܴKYux{ zJ0sd1ž4\Xm Rt ZVm#:3H^רC:,aƤ\1ݜq!oqS{\i]Y5 ?5Sf]ۮr6d6E{Dzmo:H Pw^sC&o*DwߵYץk9JNiUKX.j1Y)BvM{C\ n;MOMnWaZoJSn_U]h;flmLF4ΔW~0!F1s?|~/b)L }8iu[IŸ uZsT9Q@M>Bo,GF+Hl{{ry1<ޏwWi X@Z_㩈>xcGý2_;7GCx{.Gcz45|e1OX*λρ"Uh,[n%DqA;yF#Nź5ǐ&3sp0tmh_|a9:')2,6CJVoҵDM@:\X/&*|`B"^ʌ#* qjJM02` W=GRS#m}RҾ䯞>esJqת 0< ~hNE~u5E2o<t~/Lj w՟SgL.l}!tP5TK&_)  bo(ghH T7+&xWN/;ɽVv70_A=ǿ?ѷKc酝&sGɩlb8=Wem8uxTڎx#Eɸѱ:ҹZ`"xaބt8^.n%0[nڮÑG3p3Wq;#&[p@R,UV\Sޱqw?&aƗ1 wP5I9AVIkj>Ö g\Z87 sD\їTϚ3.T칲1P1ZVWo\˥kX(y? q;cWMs[vA/HԩC׹4PZ”5;]on֡ҭK}4>@ɿqdf!/qCoذE)ip @)P:NaXmYm2su١slݎT c^ Nfb3v5ȹ=Śp`k񯖪44LžNg_cv,m_ |?aiɬ ~]ehR\^'qR\3,ǞUPc8-ʶiI>Ys3[|=@߱8_ iuϚA=mX|Ŕr5[Ya:8@z-uA^ngɺ4!:4lj-8FBr4dUz\͐oZc-wXK=vT8ȔtM-@[_`"ՅX u ş^A{oywnxs7gߞ+. 0ZՂspV:Bya-F b!Ro>7k=ʙM^/KV ί5+;PՎƴ [;uy;Ӏ-_%^4icjq?HuF -Nng'jmv;x(tuP/ud/ۙsz=;w++-c=,ol8Ƕ70,hJZ3 -k;O|JOrqRBt>7l\խSK`xh kkLKU_~12s6=bGp'61vfZ5*<#֡0cޘn)vٜ x6M4yq;2`Q#^/#I!] BԪ7˺e9k93.FT{aj:PbOEBy)icc~ȯ֝o}8ђ.d\Uˡ? py;TcE+ə6?vAb|iA!0<Ń;5$TހG~!v1QRjhĖ>\‘ic%f܁M]+sWYrǴ2*ŽZq}rGqL p)/o0}.>9:gp8 oPn~UfQu)9;5iR*1X{58I j]# Ԗڸ|ziZ[~!ըjXvzvD߹-, ߪRwmK*:C0V%6{_aѩoQaX% pG"=Ah6ز3g:wh@3Gg~8(ga-R]4ρ lyrPXr[;vjW[[sx2b)ZiⵆL|ǒV2zeTkơDګӳ1_[ps&m.!{+lmʫYrh:sk.xd%jF|lL.?UT< v؍<(F7gvde'k-5<#jEmeỤ.hݺgzm*L Ÿ%};f_.)v4\z8|JMߘT./`S\Y>$}ܥ1|Q/ yxx57󁶜vMGr_CljcW[r\TWz߁rH{՚<ܘibaF>3r+sԸp*+ZhqV.G&pxqǩvj\ai?MXCnR-tWnl#6ͷ͜kѧuq^;}U\rͅg:4ۙizә&]u5} =&LIAOQ9/vOΝ]U!}Bq6;uvdw*&{d"IRg3kޖj5$ U'G TdÎ\, |rԞ[#ʩ}ݎ]e{8bp)kBLƌMҔ0>C"@&ԯU"TGSU%Gt㠺ZYߍl9Ksyq Gx Wgƨx#MtĹ.tW6\gmsЅ[Vȹ}mX)O#?lXg]&(UaY3Z?kaH<ʉ5߉b)̵=ӲQ FC}3-V(- P6鄌走s:1Z?A~W" >zȾR.ƚ|RWT":"-`Q*vi3ʜ;xW>vcG땳V<ˑUɞךR'$LYz[q*+̶5wfN5S!Oh負&ā?pt0F}Aբ({>CQa9̴%9Ɩq֔MVK37rr_YP@.pc2wMr1w+hiZLSR:ίAZXowĢkV\x{1 b"Y _Ca04%ej)ߙ! ̡]z{XXzZ0bF%Ur2g?|UFwBzU-֌1g>'bFO5K̼՜Nv\(XwN)߅}cXh}?܁Ӻ9Ӓ,ٯؒe%֜ņWZ%kZ1Ќ/)kz>ks*o5q?j1XZ2CNdm YdɻVςW>60̒]::pv+- @r;GvQPC~n-1.eO)˾s$Wr4c^WZ*gѿ"{>aQ/p=p})?} T+t=$ʭ xY˫~Y0-{)oGJpm^!]UN>ѿ~΄y0! 6w^r>NtwSu8\NNpE*h+,ъ|rd\c)cѥ,-YN>} 5xFoq1#MY%@=ƹ)6gESYkWUvGogkJ%.?؃ٺ9֎kVoaL+̱1 U R7[z'jsc׿lDG2pbt}O;X"bM ,ә( 57W^?}-\rQ,kӞ1YL/SVC{/ߌ.X6\9c9Uʗ5ˈ=5kÖZ.nTxyrp|<ēwlX´gNl½L'؊/*4gTiZG+k0*K8NwleTfU(9i֡S]pt ɦ2l22JcFѧo1$!z '4eQ g=n<ɍO\W^ paHoijRfp+tg.KPG3ssJq}fEVTgloo"tG"zDY E銳rz+1M96 Zd /nvtƕ6يZb0b\oG Hgh7w0o. ΍vUov Gz;܂=r{ZS9R3jSb]21aR)ZGa*Kj~B!b۲7ބέeua /{51S]rPMChT-A_FQbù͜Y4L K9UK]Y=kg#ȪDf\|}جڞ}N\Y-J)SvD+>6j3+S/qۏ?}=<lPz%V h~`|h$_xR 4S,ve}o{W6Dv'sfzs#0Z}sWj4\|\C'6WC_bOCChs>x1˝I.AuY(oƕ/w.]@Q~=Ipwz_^>,يI]w"|I,}^`ӡX?-cڱӅ k/P-ܨ5іsu9p,Z;ކ.}ox܁[;ĀoP݌'ƚgұR;fMՖxɄuxүzq(T_$_O3a@G\}t+|./FH\A3B/nώƓsow"'nۿEg!_Ovݣ0egu_e鎖)qkh=qSS|qzp+vUtѽm+>؇'TQێ*N.gN)9񮚭~*8ds*9;xI릔- Tw2 dB'&4+zNg_֧/5w[SG4:rL M9zī_1\zD':qM]GJgL4퓁f?qeFcxH]|g J] ~ӂ3ZKm\J>OTq:X৅w7Ep[ KNm</9;RpEOxd;OL{}l[YZ߻Gϯ#`:_uѠu_:l}d1P!#>OZ  1D4 ktB5ԴT~{%ҩ7ig?K: {ϓ񚙒1C|お{ZxrG&\u؄{kLY4тx(I̗Zg.@%3Θ 8 Y<ǚ{Ԇ}lՊ-xp O K"&)<w6~@_s }هO᰽ MGm!{Ulv"URsH3%wu(c^V2cW!G2p) /J~TF.“x~ge\d}2HǑ︻qM'ʚa[x؅뷊yJMMtH0Ėѣ̂ZglzN&FxTqs} pv Loo]mpe qX-\.G&ly؍^T){T0B,y Ah-{q4;wG?'턂7YOc9%MhQ*9CgxИepaB>MKMXz. uӝr+A06x{YXؾ3ˀ/WY.6JȔ:pOF58mG.g o^YU}`jκEZ6.c7mƇMؾ ;ﴥ[3%Qg+NF.]ϛA -;K3n3י! {W,t{ͧ\5 c[p LջcJ~i>|ܜms#^!doǏH*|GwX#ط w7w5QB96r3ƛk2}/C}fT2 +9օJ]9 G9rl1;<tR Uh{9;`;iD.êO~'̃E~s>]w8ހ&5nL|!`>f~FvA%~-%<4z5S Zf7va;L祬Q> : WNL17d#]YX5Keaj\1`Ce#1[?sbfɂYz|V-Q^ e/<ӗ=tO4&F,5%1ʄ8FiRS^ѭ99IDtUspKdžfƮ,9(rA`Gd4 bRkG3buTz]u Ddȟ ywcNa[kNʟzsz<@M%;b(rCo+u }3/ }CcJXM x@\BƗASQ57Wr{=C{i5V|eX:* 㴐 ռC97w?ЌtSlbΒtfIxqM2D"R-D#&_2Ձ<] dAJ.r)z0^lMܸkҊE6Ų~Ԏo;sΓfd^5ݜ'n9J#zb Bol֕G8P=sGp 3^z[[bAH^N gUJ܇[u!A1Ž{hU ReD`Hƙ8s0E87ܐ#9Gk0;^f-V7ڜjqwk"?u^qoMˣ-:#91W2nkFl.Bߝ%-l\ߓ&cMÙ|.a9 >TZٰش7wЩ[e==8EJΞ4^|OЃ@%oW-YK^jo+٦%42ṚR`CHO7Dp^]T}XϪv>_5kgn>x,&= MB^G`m1'֢`RL8 }+z_V9 4UMތb\s/gG\f lKnwh "._y)jƳIz*ô8DSe12qK6iQ#hXCڑ@t ӭ7+dcHCkJY~9CX֐]غ_ͮlۖə5(l#dx'ո3.YFm47fh RcL)es"m(~cЯ՘pFV3R6q[R2x٤%lsWX1V3ACnPWs{+ ]q6 1bxwC]Δ6Fzɀ'rJv@Xuװ"n{)\s3KvjτbVp9> Xu\Y[7vIn[m+9Xs30|=_Zs.F4$rCܲe<^BM{kU3Սia:\0%>3`3\`P ;-6c}[+^L|5Q ;+'OLpdC4ЇWY_0tFŅ0K>!dx8v<Z̯u1P2WeVnxrw2bq ky=9o3rXw=YUS+098G:|/{nnKs.T9;ypV%ur~y%g|c5Ç4dxPĝYkxZƶ.0‰ٲ{6+3%[$0Ij̮sq) ?=GKnvB;?s `V<gyv55⢔T?}{wFO #3yɂ rߘk}jt(G?*}Vm*.ƗVVڑqn4 s 58DгJ =]N;~o%iVs-nnȏn"bn8ਗ਼Ut4VG9pvWtXdxtۿF#0d@igmȷj 0(4M\5dԀͽ^ gC6mE( h}3}te/^Xטּ`->;J̼`E xl;]1Z&קTPIXC/~ɾAPϝW<smeÉ}7Вǚ2u%bҾ"=T?; #OϵM!ϧ"ʘSTFΑcmcFFc}#?W÷8)Őe/A#|y%.ZN1ǵu@9 *HCmU z1H*cMw&93D><&`/MrwJzN9q!5o 8 LN.Z%ٰd/LkcaMHzomu|sV0v0, >Mg1~dbg12j‚~..t̗Ydtl:Rf<Ř̸ę=/y}C6ՒV/Mxu4 *U|̆UKK_~{Հ8T.c 9U()w'??Ã%Bfϰat+ 1ev!^4oȲYp{GÙQp% z07O<قgۛsqGCc؛b-~F7 +z Vآ:<:@(³aZ>ec*+1ζDђxT*ֻdu_#+^!d9R/V 5h<^ zeb)=HXsҋ?J9W("I*Tryv|ޭUM1$&e8Wk=08 _^ Fұng 彇sf$\Gp)ǣ襺~#W<8n yi?T}>^ktuU'[FxP 9xΞēzrR;7B@(-ij>jH4p|܋OxqOo6SK8Ӂ.B{̀Pl+ߥx%ch{z-4O9iafʹLY׀ OO1>^cl/Cwqb7QA#{ʂM,ԅ3u,8A[Jޚ( |+4S2 {*isKm>U 'iAJFW3۪oKرWX){Ec;g‹E;41i2osu^AnI',Zt]kBt}?zen]v5 gpJʼn78SgM|΃bKg؆+S0lf!cr!":-ڃ_\yBFc3%QqXKԜ-DشDp=݃x1񍌛7y˓Y_,ڀ[X~>.NwJH@kfښ|%6J4]_AG{qiJt(ޥs61{PQaHE,O}BkRp_['XBމسZauO9ډc\PE 4p9}d4Yb8))k)VZSJɜj68=Ꙋo$4*bNˌxהSnXsXo'qT 7e7 `2{ٖpZ{?guۣ: c}.fH48cǘ0ۓnhOڔ+U"kn& cY9/Oc"c9^#l`SJwu*f2~%ǻ2N,cNηceL"R8> ?Wۇ>{$ 6#7<P=Aj#klSssopk|A`8 G j.hzx1Ʃx4g osT@Lϳqs=g|=Gf>r#.bĠv6JMʎʶ'G%#R[ wwU:N)2+!3ܓGx9[Xqfy\2kQE2y^ûP?ū4`qƬɐk#v^ هӺ wlϞ:spSebݘ7+b _9k~ ,G[{;ozp0) l3XB&o}:Z{;G!G:l!HQFܱĈ~9,ߒkp[qs,hݰ\4ULn}͋d|>L W9)aa*(xZ [Nȓ#se:ri"Njo@W=cP&#] 7nw? u7-ڨ1x,BAg Smgڢ]ެIj qM#JFXի9obo']7:5-aح]~V 5ځK^jګ줊U?GB([!^r_7 s}9S򉐉f+Hw8*ݓ9 Uf\/ ,MYրG&e`x}@7S^`{ɺݭ93u:òs/#rz2]A1_J]ILjG_Qń߷Z-'S̞ $/޼-]PeoijT|];_nTsw~bYSlݙcLPRJw9>kefwGȯ5K퍇ѩt|/)bo9>úx_h*jҒt& ftv /aF4]e9t.HEPjD.t+2g 3 קY!wrF4$Hc|Y|x+Ji>ʕ^)ط#zI͂*.Ur(LΕ6ubU=T O(Xg4lq^AG?(h*^ ugz ~3tܿ 7Ҍ'xƆ5wmh͸ͽ Knc[%:ǓREV!sNLATD S6q4|P37M{,Qr٥jިU1UK~rfs7Qk9]zkwJܸq=5\pGU|[ʂc_q6UԢ K{1gMbԔ1ӋҮ6,Td#jw,{ /zyH9'O|nϙZJ|Um21 j=BȆ$}% oS'3` 6 &L6tE&-cZSꆶ_}VinbХĢib/wRo唅6CΛT:PMJs# /g/)٨w(MO oƽua`OkNhȪm8>ٖk-ށ9ҍG;}뛳l}xvLWY`^QKc<ۄ'19zWkocL1 }Lħ hmǛ-*< ]YF>!2QY};4T.^l`\ajxCgy˷mвͿҼ2>|Aw*8c1W΃\9v ]GD{N%QY>z|4ބV!7Agl"y m3$=mkV5tgۂ]Vir./c}Jl v@"'r;T+:嶆Rȸ+}䴐 _++qVxKL"VI$%ʹऔ962&$# E=Gcͱ#9OfTpa3sKsx}5~U9|3s`Ӕm^۽ҧY4oW왷ю-NDJZsě0ƌWC~`)Ɨ鸹)֙P Cr_nj)Pɞ Լka|dO)_B'ѸU ؋?$VLO2n|SGz:ѯ _S0@? lTJ~Vkok6TQU X'}ۀ jҮAz:+ j~㔩#{[ޕ?|9J&F\Ԭsv,kHu-cΙÔRΙm9mOzb5Bߏ{ceMš2.}#mjBYU T9E.O ^4;9f=/#/g83-ΤCyqsG9Nqs&217G:`< L0G%bl}0̉]_926؉ZcwF;_껲[w:ю!dB| ,p?>R]+#*(vSe;5;kx/or&^wC:N_6cXc^?de}Oq?ȸ$ÓoǜÜ16jS7so+Vus.vJLXO]$ĵXU{QvMt+&߉X--(sry+tI bNl)ĉf|tˍRVYrPsr.*)GJ~7hQjzm ={Lp.9OugC=42力$H }%%K%7R3m̳0Wj\A(rZ:)5GJ Z`j 8A%2s9_cO:p#ݻLk w-sZU%/p;[Xל'uy2~Sl 3 ٯ-ˇYc_snmbq''P,VcMoOr Wn #ՃQ:r|cc1X5r毤xFe&s+Zcep iJB1slY*칛Pج1 o~׺V;M9 !(}cμ1ŋǿ9ѻܘj؈r RV?.ҲG<9oSKOoda%tT|>vԘ0(X6k/t5]0%ʛݛh8apKQjW z)_%N}7E^J^VpR>vcNg9&fd.3jsL^ }M!\ myg vζb4c簶Bob7Lyn9K[ns;njEF^>N'RsS^2vLqfKx҅'>Y!CmG,֕Q"*bq[[W /׵ԿQs{_Mnw}(ZTLgȰV҃/U)"3'زRO$8MQ8j䜆+?@: \AgL=B+kv.hΈl#o+좢7IFŽ=HWt#e.^yKswr@E m}U[wYJuli۬nk8d-J2%XĪd y3wi;Yу%yK=A*6ۦ/jVW4,ZfB_ 3g'_w2gc?qM4ۅߊm*n1_/5{s$^uPs03)kC&z +/͖ZK:p{~bM"yUYHjN#1Px.; YilJ7O;؆LyݵW2$_H=pԼ }QG ٩g8z3~a1jCXk)"gQ ҰĹ ʼsqR.j#1v%aX\s[;jsLl^MAO a9_yTPAAMs%?D+ٵJ˹b>p&QX y2rR0wEN~mPWo5yDuc |U0Uƀo]iQYȚ&&gP)s)H0x=2 E0߲t&gLjNG]>l fS05gP_vRѴgj8zkY=eޔ]`b 6!{)mYЊL7:/ųz0jhr樂v sdagNUw)_գ_e!WaH63KZrXxM85v aD\{է0yAeI# {>q!sL2?WЁ=^b/J5@˱y8s. cvaßȹDmaim1wr<Gq-jNḚ@ɂ_2ʋM҅7_@Gv3'slݩ]H 4 gBjD%g#./doiSLO}"}8F"gGA[x|.đ/O/{tބ3ΈfTUYWk=2c+e5 _ayJ1t)all1sТY62f#_.h’$xUFa*d_7N#儫Pٛ3jH~Ssٰy#L멥씊)ו|ьqo!dj<[/hx vA5c:ք/?T9p '/OV5֖;&ۑ=[[n^"h6=X1@DžLd\Vc\&u%_PZ'V\%-FO/[fhum7!H[4X@wj9ȇj髯  J>{V:r֌lMޘGؾe%o$Fǧ7a5>~'h%|{ţz{E?:#N4i8ߊL\\f)kSm"bJ3y,/W u \V4_ZVK ^(@^e>-Y xPyztP{+}kTűZz5O.3~, 9{`,xa$ÃMPm=϶RnyGŜǖAfސc{>=e7|-r6ls3oF^n:IGSf&GYqJ1J擔FIlcHO V+j-Y3 c6);,=lnM;@1z~$";'5ý?sL?SaS`ƒs[[!gEx~2t3_.x`2 U`p c ]1Ľ,8y)B ֥`v|xR *z [j\"v:`W:C~{j`[Ez(ژ*tQ%ּ yҒ{i5^¿^iY*=6*Dè'6R݇#j!s><?M7KD9C73`5o ?\ 3Q07_zAI \igx뻄_BmMoط0Uұ(> s5 ~@ BĄ<=lnR=Ϻӱ+&:@#O1ikŦ\L\FX=`b|- *9a*=*>?|0&lE[]09)AQ7N&l7ew"{bc7v`"؉X EŠA${s3񘹆e}_o<_ǵns GPR!1bB cnҁB]鴖wj^wg6qW~9\)%yp1 WBQZӯ+ԵÂrc(f1qv3b/#?PhC:;XPz,.J)7t?>@WE7}z66ϣmX-*ݮCP#RM]k@70%XDlƣ2]XR19[R^1=(5 vfP;ngoc[̱È q>F/Wžmu7iwU (JOwzx )N)(J>̯QD I=hNJKޞWsSd=j /l& aX=&mvAP .ۊLD <7p{^DW'}ӱai4{n=I3Fͥ4a!9΢4j<;Jۧ]rM[O>#h9vxڂ& _[IiW}WDCQjЃS4Q%%o.'ws/ҩS*EKw(b չb2&;gw1bC#66f`f&rUABE/XplR2MJɥ%:.4@ eR3` #tW`[jxڭľ SƒZ5:jjhdeT5\Wȯգa3H-!GZW#Lz E _D_q<Ϡ݋n ˜T:{J.x6ۥMh&Hxldw;#׫[c_BE:Y'P٘νCF?7fb~NOgn)]BM]Vo0;NH=hoJyl("rm3yopO3&p޽,>f-]aK ]PBY֘TGmQA%tdf>Ϧ}.ԮEAj_n|4"&Մfݍ2وcF̟L|ŭ J|`4E4-htF܃irA9U1oPQ6̼r7DZ0H" tضX *_0t1EEG&0&KF<[ H_iR2nllAZGE/5RǛ58 J=z1C+gC3ӓhT>R=.cuFa|X]82CPWfU:dL~5.?>[6d]@3<}!m)EXA_ώ'!p{0eP~ty(vN7%uPq g^ wh4MfF<i~iը!*GtG([TFLaKij]Ij ٖ:hlq|-E!Vdz~A3f}_^>,߫y /`j/ҽJ@M B3xaەpafkg&c=T(@D Y<%N` DhL5^+p!{|=< h`g/aBSw, dyK h.[.6h>o8De9\ldh9#Dc)vWBf>&3Yc2?ǀ5跏 C xHtry7u a@|xH*JW%5P5 Оq@v6NqͰ $OA_=ho%/FrӶU>o=M#ykaUu8^B['=P0ɈQ*֠w_#s׭F4`=ƌ2Jo'*+eJd'9vh4F; r0s "k2x5ouLi5{|_9Qc͉<|nXpֈ  $Rgy!` жXM02x'?p0{=G"5O,' F0{&_:d.v\poI1<{t Ve04 zn: #0Zl UЙ59|ѮfbztTL^X]}M0o0\uCY. /nm3Q47&ӧH\yܵuD;?72]o>vk!D4gL:ǝI%hwu{bnE϶4=ۍ i̽n4w"hBˬy2})>h5/M8[G^< #޲؈J # 3[{"Z)*4!$cD'"0H -*@%(Ŧ@ <Ѱ_n)qi{a.5` C/Y*‘UJlbB OL*wdg;$<3pchOIo?U%H^`{pu7Ђ7ʾ;lp 14U˄sfD#s J+;) `Ya4(3z|hN̊ç[zxjݰ3Xhv z>g?r'"ϸ%aT-,EPdXk 3({d[ dn4:+ 9KזқY.j?)\ ,âN<b& O@Rg9RY8-GTK«Y|uCdStu!aS$Ezeӕɴ+_^r ~~ |]-1d0rqڞ^HtG vF\6kW{xw\ G!cMf2 7qCd#ˍ@{X~u(9k@N}^9F9\=V9!oY9(m67H6ݎtӴJzbc#]=Z3ٷP [ bs"$|nuyv8=:hSFjWjD | &NZ\G 5"{T; 䉟K0#rVĽ*1iDX7] ϿsỖ1@柳=NϧAo0R:5Gj(m|XsIE'HeMWӭ~@!E_h8z0-f$ZcSoe-‡} ;oŢYKEsҩ>1J%+Vw34_MxG_Ւy2sT~NۉjLVa{+x%8ԑllb,qyu#ŏkYL P_t` xli~@Z%|qxMN;J:$p F,if,ń {Cj\gԀvRJAkE QwX3MNl&5̓X0.L:?1JgZҊa#ijiU﷛;,`f*ziO{cSKT,rÎvx 8XtYgm٘]f=8}Knsp̹ppDb\$ &θQ#NL>݈=`cUVzjĀE^ 'R1:ej ת1X*~H ]2Th)R"Z+RbJUC]Ǜa9+bRp)uj>@n3Dwƶ릻b8L辈|zy#؟.{ 'k3z1Υ9yuRr%>?:,#\ \F=;ђpfmG8DsBWՈUck b~- .Vc9f\aF' NxuOB(FspB,Z0K &E xdaG& BƑV:Vp%Br=$ZL:\ORK"[J>H-!qn2ƵlL`uTʏ͠cpgIJFwІ.!ٔ HOư 6ca[$9hGPGH{>(TFa5v@Fܼ`@n kLXMJ`k`5[vx5Ho۸+';"FK.!R-aM9V+n6jѴ/ۻcvLlD/W#[בa5:_Ĝl%wOkBt ŏO$?N%MFx{:A?C>tqB[J5Pc&q8[!(K`1,y":a`.sxviAM|i}eJٵ,Oc̫Yu?GdRh[.ŰiY-n;xѸ€fj|.7XxQR`|IO<ځW^Kgȷ!5C~>U4hzWQ2^u̬_@WTaLo(%Fg\06 )BTZ:{ԛ-o{gs8'ģ""x-~f`;RcB ޫLxXww<-5ۙa0&:/V E_2B 2¹ xdzn=gS9SI_M%Z7{mp@n1$*1^@x.^tD+O_Zf#a;E~';=KC;ox}M´l,GK.6R˽2' Lĸ9aB9CJZPCG|'qT8r3Q;i#i+q)bs5,M [nwE+."*L`%)ЁL2\igUWZ)B*ޒ+⾈q3Fp3^'TGh{`RK8hbuzCsL3[Z%LoNޢSWzڝ\Mk{B+LNb\\Fyvz'8`.BQekQ@2)<`\(+ZinXAkhB3r "n:sAi2$&%lYh7[l*lo9}D^$:Q@s+ej3~YP |LwMG!j۬Ft,kvuď}ؚZM7]!wo'Z]ߑ +0gO7#Q1ڒHUM\X‚53G,bO'x| ֶ`r;<%FAl-'JFy%'m1pEpӳM|@Ia'chC:v:!K.J&XKo\܀dX9Kep7Z^[}-L:(}]\@?p1."Ї9h9ƣ Jj2w}GKfnjiVh,xc=l<#jQVABD1^ GT|d+ErI Cm'r<Ÿtk%nlWa}CyV뀰eԻI2n$іV`GS.~5K!5TBdQ4'xMrhljJZby3K:Ϩyf@_^wmP㾕yCeY0*?jE~vx=u"$愕Qr$}%B+(l/+J ȚB)3 1>dXE ;#33_K7G 4L.wp|_bu[pzN6hR\zNqti4VMVhL;td!sA UMбyp4o}_RhH9 !yU.MF+fѩ&hʅ8E~N^O F]Tz23V& t9&E]7g<ڒZB6G8+Ɨ59-a w5ÕB>sp ]g5Tm@n(eڍ˴pzސ\zrԒT _VKev` GٓP/4&Ҳ jhGou:؊H>K]J.SFL*=I.T1"Jq:Mn>!oa]*g f.YXScVFX#La||I^EPE?G xJ#xZU8VGi5>qF9^"]b 2^\\bX}ah#_9 O_#V١؈TGAk}A6ň:ڧXTfxdq8qѓax#3<3H%HZ$Fy& ;@ӕHXD2sEFlƨvHWG?k!2 (O,1,gxmB'D"'Ax `2=sehu\l bkRġv.xpxq1JEXχeB;" delG0˘s7XטB ϣm5>uǛP;dab.9OWyVG0ZqG\K]m.ǸzGqa lIz#r<{O]ȴ%EyXdF!lgPI_2M}B+iҰ'lPbz/,|ï8.jp048e=\Cj"C6({HVȱZʩ>F'&;ޔN#(':SqֽM+__w])=cA+\jĝ\Cb~`- 2ddE/RZEk_O7Zr 8[(8,X}CJ,]Ow;ԡc\}v,qJh.潣$S2= t.3>i{ + bmW%RQCy KH>/C1ٹރP=U$B\!o=}وfw26Jć\2XXW.Yj[k8w\bOjFn}Mgq>64c1f_dOwr UPwc,9v^2lV *X&y:cI#6,B")zk6*lz$J'?RZ}GSc*(́hsvXaƤlܸhI i,teC]y ԸYogxO(FcaUjoh-UM'B6U ~*v =NVaiVJԼxv)+>+X[`C+]i)l0oR2{E48NĐW6=~O\L__J?R$8voO*/1i뙾%E6X넽V<aa:Oۧr&c?;`#ޤۡ.PҔK <5P./R ܔ_+֏Z",'C=W-u_X|\8f'}p@ |i{RLg)"ҵD+mZEgGYaK-79]Df2**,%oXxc usE9CxrZ]4o[4b;5qR&Zeva>1w ayV4w&4Y:}=>F#wY Nty,oDZ3T~;h:M'zT0j? >';֩yH̃rS`N;FgV8+bJqb~{gw{rbA[n=vbX(Xt]zswZf1{~ 5K(x@A-6`t@wkyxHω ƃ7')Jl!Rn/<)W)lž/Qm# rEfj*9ƜkKas,=;rz;bQb̒G~ D:N@ ?4C8 ӇKnK ~NGK5LRsn5oxx vI:na>?eCal4߫ě'b qcM&>>&ፇ2I5A4gE=?NNoN`{jH,wC;.XcIec:v[9ǂ+lxXgk"Èw/V"O|MGH+ SBݷ0TF̋Pxl B-uibq;scĖP@Dh4 Gz9Qces>Y]S<g s?={dƄ: gK 07γj0m+6 2J¹*>ssj}joB`[5Vq*)dF uS9֙LWvA+pR'T@GPq 9u:6ʲcӍ&31ĈٺM>}Lo53 ^2O3^E)2\fV-6-/q|G}Mݨ\)gsdno!eLo<՜SͣY- #x#EWu,!G"U;7QrFJg η1ie<{wc xL;Mqv$SG0^TBIx}AY9] _v]D 3b-')-息Rb- :SIǭ-i‰1Nܲ<83˓y]ޙ{S1ZǷ2ݝjz ݜU$;~ȴ`Ms2 _$ h] Ǡװ_Fg3w?\&|Fgh5gMAh5Dǧps8> |7"|QyuF\B@ȶ=@ٸ@4Br9zlWoj!_ef.M.Vzd"[j~ Tǀ:+IB/=pUv]=wPƐ+O‡X;ұC[i%Gkn%W#y $\<- ֳMb=$pE Org{ǸT¤hW3h3Jh!gqZYs\5`R;nO%5 |q7z1A81&莢l<F뵟pm ϓX?)y9/JUq# n=ĭ |}G`c'8?Km =;*m&QŅ˾=v XnksJlHnx~~]JE*a#8N`v+ʊt,oì́KT2覹 &I}q_M -@uϭ]bN}my0(dX1 @H;ڍFFp#TQ vK`RlxXɫ x㫖/Z}pi|}ڷi@t\]r4Q 팹d󯪹>@UJld.Hxx #5U_av@Ɓw,+Q+Ls Xk{`t+7戾JY<ikrv*QUt8,3ʐ15҆|ƕ|&ܹ֕;MݹU|Ɏ^ȿ'39a;n ů0Me0 ~l{ȒOYqQOe@5/m˛Z{Y+L ,հ7.%(|fs9DxF]1 䉈W!n>N̆UY2 XQ?Q'*alS]-ŗ1 h!Oݫe^Wl IUwtþ1sG<y'y1> GmuԶ~KTv>"QNǵ\.fV- Rq %?oL-Ϧ a-![j۞ỏFOz o9 1O]gZy9߈.*x^90Oʌ"N˯+hRm%ӣC섬>ƍef6ŝ.=y!4ـx]yN4ӕaʇ1~9Vah6Đf=/Pt0n,ןW- }-{V:pF-M옧q˛.T@Ύ<͞SX6MLqk|w]Q GhxZòZb Ն ulk"9nTC*fۃ&گA*xQ?lX7G;1WM5at&|AD8Sp3#MYe J1Ļ  `Z6ID}hODK, C䡇pz:z}er:hF ֐L}s%9]ʀZWab |Qtm14ӰrܻIj&HL1T0+D2>ru,I|>D^;z\Ҷ17*;Nqa8q;{fvűs%V13*bŮu, 4- Ӵ<+kqKmyN\ۅv]É~9s;[r#/9R^gEB15eK+e?LqNźZϜ^ ]aLUYS^ʛ%ӷv!]*E[ 럍; x&{ZgTcyr֭ś|q΀E^:#WW ?Qt\;- uo!~[(Ru_=Nno횩w"2+="zm1>0!wRq.*o2},sZ-wy;k$Z0nK7J7bRya)S>R9 D|d4yE諤^ ljζr&ș2=eqflf*Af^AMkHU'oyrs#O6Nffw#suu8?źt=B5<7X.mZ&1rVb/\&B~EbHJt[(7{s<2ǝ\qeZ+7qN/'8Ҏwz[wbFKZ/%RN.Z=ZNK:n!%\O\^P䃖k+1% G#mD x $6(' s v?}=˛hrXs~"|ayxyԈ[r0:KٲF7tᆏL2s|G%{ް^dD61O{7ãז4CƄqltk=2ຂkd cof.= 7Ybg,n@߈ze'g-V&RO(8ový6x=N`؇D4[8x>/߀?ەE}fLKN؍23c>g&;@+ǩYm`!zGPҫ;WHY{Jn\BCDt KnDkl ¸s!g+4EӒwi6ˈlCP1I~_c ҆;萧u8.$\TqR93vkzi!zhn*-7[%13o92_'?Je[b8xkbYWs=GϾh4>cH ݢ2ᱲvX1B*Nu"\ұpbg#.gߐ*7p5gp;vߣH hK{ow`ڤ5~ c\#/zX1-i IیPm1j9ޟ^?܅{ZWžkKj[ѭ7TI*8lG\gnJRZp;&ji̙K7Ҷ-Ιse9q)$\{AYf,/KJ/䬮:H`VJz\qmC>iY'#Q+ꇧYx91Qi^l-rY>bŬ*{%c|4) 0cχ"F'ySʰj/=GVrn6rJ~q:"I^vиXHCddjWV Lj`oźVŜ3s018;cz#i|6PA-}τY}og1yf{g#@gIoґ6. Ma2;nfQk;,}jKmOs0gG<55<הO^*=JKs.s)mL V\`cvt&+mrᣏ{7L*} e Ѷ"V lDwy3&ujv'xk13AO._aCC 65"ڷp")POtx`3gfٱ^5 {x14Q1#$ 3᱘-x'КYqq%RR#`n}Ras0y_aq!x3"^*q*Aufjs|) ƒ; B~u˘5ȊB!QHN<ſ[I@7]+T9[PjkV>k0! ĆxN%B"lGijӿ@~3˜1Fnj5"o8c'sږw9b+sc{wE: ݊?8흔 I\3fkۅ҈ce}suhL i@阭?cthxg<._oKmCsK+aW yS/5c$4_)< d-Owd{Ll)oJmfFbŨt;V2>ݗ>:S:cX\ߣqgugp6^.xB1mu<Ώʀ?3fo1VLpc^|_(|"ѯyyἺu ` G/lڜ eEE0Mx)_ 0a!Jܔ˼qИ{mL7d1Ň0vL)+yh_w*km۾4a2OQr_jkt2G wWz`7nZ'cS7 6gDKb>|afg}bc7آ @)(apz|L~dY>4?#V̽6 ^?i8s)LXlgcȳ!EaF3:|K6V͆?ٱmK:`3vHI+vf|Bɲ=:ifNɘe"*ۗb;VWkm|8 /WZ~g=ҭO~;KP$p9GxʜgI#1 vPZxq-|ܗ~ mk}];ن[%_gY L>q_r)J޺dX 'hO(3BƗz96&B60b+2T*y.چCp~- pO=ħI;gI2 se t_^yՃKe†r_ LnvLeՄkDl̔;M1L7`J|-ξMFΠ#8r;~t[ 9p(ptgF+`ʹ~t2O[L87LQl#X=@Xpu lɗ%L~ib^22v{,AQ,y(\}(Ҁfy/xX4wqr6 <~`8>5 ìј;9 7j8_!lji_n^7c ج]y{}xֺ!~L~}@O]o97фwÂmXqt7 oY]-{:nsA=o`o÷jx?P4:At. 3Jps2rE!L]V %%2M‰=ƺ3lԐ}qT/΂-ﭔ[N|$"&ؘSK}3zCS_ZF*0K).u ߉us4>mB7c蕈h4w zMeL' 4c\ ,A%.q7Xې>*c 5mG鹹Ȝ'ъ'v%!$3-wddCk28ld1\FaV&'a`h c!ah..7MG,l[YSMGɯ5~ge{Y05xKߪ^K^h+*[AJ;"kir%3\sۙ;d| \YH6`h5]6*8xVczQ>?Gɵp #;,S^&>dcJ\rMMfS[ Ҙ7>g/ 'eA3VEd!l֙Do6፵YWb,0o՛?r1u ŪVpނix܀M*dSE%QK? ~EXeϤU2AF?hsu,c]mp4=<fcQ{;7<= 1>aSC~hS )&I3*6ޤfrV5t2̭8{JA)c~竈_=gvNعG9b09є)X~ВnvG8:W*޺Om6[mprmshx7ɸs ߿"n%K8ٚ Ax8Qȋz*yr]/ތ44;v,)1EB׏|l&&~vSYg  )Ǻ8]ēX G6~`&+堏k;%c۴?[asGw> \?6t#l!bjIXQ|LKcXRcɑ2;>̲gKd ;z{_hg5G媸Gý<,:p/\t?=q\ $gfd\S`jWyq@ϔDNK/iJƀd#*cڝBxtKC/ߎz'$`l/P/-z6f^oku,'Z=-iրG۴gk٥tQbqlaVmLǞdd`ϛ8 JҎPɞQތ]=^cSD !q6#3c)1eKcՠ,,:Ff6d0ĿF|:c.EހwQ'2+;l t}k(>d?| n 8^I!ٷ׌&3|چm9;E YZbÍ'뤦o{,eI3^`ye8'&I|ӱDsQ0f}4j}OۣT]MQC-_pJm:ɐ3jpK!?Mpf=}bԑ:5`706T*:X)'aq+ 8}3|n8,q粯.3 f [hBive +Ghr f z -@k^^eރk5d4ތm+9։$gN;u+ YQf/-9gs;xX~kҰWk Bd+͹_gAD u7+:w<{2w&K=uG ruyŸjW Q \|kߞ+^ N|+Zegfh tf8G۰g[=ߘI5X_"碹W6f*q.+CKbѧ, ֖ḳeՌ03S~ܘm&ucOGԹp_+'ڳD~ '';l+,[E-vDb̐RMY]9|dI0|i^qϙ%v"rfw>'H㰩M8zǐ?1; e;P (Z Yw0:E!n]]c|z3brnҀ!'& * FymoUuE}#qy 5"ZT ,3OՖBΔ9ڒ;|WƛJ^hV ]+\1Ӆ+\<҉8Ɩ;sz6ʥy~;N x=̓n۽hp1O5ۓ:3fVKۧ_ٸ[ %|TA5WkHO(tg 0׋K<9WsMYs̱<o֌óؙm#0:?wáu[VK-BozGK ޗxrW!Ȃ 熽 Жc}b-jm])!n$PݝO 43y׾ZwV jc5'8tk>,mLÆXW#pq'4b8Ԓ)B8.}A؆J 1KJ]et>i[ZB7&A7 K=3W[h-N+o6^g-!q3~hXUpF".aG,H%=ˀqfͼ:(dEO*nv 4z*O+"VD`8b%,؃ T)ziOFٴk~@Ckz zF9hA)J(٣uޜ_v;R͉5bZ8N,e)ZIاBO, 5\6Q|87ezrʛq>L-}Wx3=_,Ycq4ֈm{E`i":%c:P@لrUe2.{ W(M?^KJϒq4ć1i{o]~`gDl:ˇcXl8+7xs0og8Ї{y2# hsˮ4|E֏>=LStzrqoG?Ah^ǔ&n%Śf{t_#/lF?h6 ]rd>&)Dqt'uw ?KfJzN!+enmJo`>R CζKvl}lj8BO֧!}r={Gt3l>J9_8jS}'ƭfSa.Jgu{Ĕ[2΍7KxL (|1DI?niلҨΗ WmJp(K^)o/Y&ˁr=VjWlQc($`ݜv0wjiP> BЀC;wK} Is {Oqnz|S騙]ܲ BlłaPt)Q;uިGp%/h0`]g%w1kVYےx]/(>ƾvXUaA_ /}nVҀc];$7rl6z"Z4;UuI+ѧd3<tKB&bBץ<-rZorVUP/gJY)aiޓ˘՗>|Փh;F;2 υ7^sN.}=VœˆM,ڔLSnjBM?WL [h*kJ>s?vZԄSo,/O5~K1ÓgC\'_a&}2żvUFIjWҨ].<Q~7fb*4),D.vefZdi@jSof|Q ,fb~ƅ%~c˗km(edKQT_/}^;6;7 a!m=߰2՝||8o= Čszs~V6DV nCZLi*7> &!lkj':eEV)5GlEC\f@m nϴ];bdRivfb֫OF80`m( ?Ĥh6^`ktK5l֢J8'W:SR렶POi`EUNp܋1 fb%ePK N^KƓ_$/aVT#N)/WW$祦RSv/rJS.iFMxjmԏBfKvx۔z)pB2.͓h1/(X!c=2Vx;PɷJ_zPg+^:\_'0]sƑE=٭FD>,t)Os;nQ_Âns\6[ Č[m^oƦē1~ 8_ĽwyţjN`̭b9X1kKTK0݊o[k1 P)J̎AF}nylw@bOPQ6Q՘ݲa=p1x:23 }r^+=tjg;񆿌NRy{Rjnt0I)c 1{t1=)]=;)29GtݯWqn'|H)C4ÅDo͵VUJ>RClSr%kg W~؏B<%eeW%;OP&0\U%3J1J[,sBweuJƻR ak HE\>֕-]ɂM߆̈.ZO`h Aȯ|_iHbp|GG$<X ޒ,D_)F<Д~m=F+Ų*f`z?5GۧASj`' bV%aeR PF^4|>Bαj '!N2awR]fl-wI%پ gLSR 3حakJa /oJ;]]hjZt*B4l ϛag#W>Jz ֮?)*|uVNBOx;8_٩2ka4$͏4X֣)zrQ_V彡Œ= c- 6[Pγ;d$rH*_X&treϾ_ƵBUHΛM_qu%Ep$ +sM/5%ҏ<HNU&Ē#:Fc6",7b4Uء g˘A@* 7׻2k?lǒ\ݵn5{Uʓ)">5 WQكJuW\p%,6SN,`HDٽ?NS'ZVtAk:z=nj5d??>Д.{R!S)3ᚌ 9}\o%eao)aR_bL~Lh_2F Yaۯqb}?kþbУXk4"ΧKvTw[YƛHXk*f=E+X&xЫmRt9ADsZj{B` kw[Řb&pKm"}[oBOka]تґ6siP[ObGx*lbu VLW|>HBI,8ߟ2|Yo=ɐXΖI#+qsO J602CʵOl^4x%y>z pl[JQ7O;!{*|N`]u`igw ٽWS2jF;RJq'Q`l%x R͖t^rf_W0 }AOL<)J~‹3.rcQqXv 9vf2u ܔI>çUc)#Oo~sP'H(NVK)j=^Hxe7z s^2TFz'o;''r>'.nYjˤpsypCS]լApA"> qjNj\±uOLldI\}퍹k\g:g. DLˊ+P>1`I5g`qG#A&"PyG2nG%8]pHM_+iBY%Ns±1 WN#W~,~!z7}h`#b|L(Ĥs8[0ea%Gu-EM+g] ̛ϳsݹ jS]ԏ:i23kGyXʸ־Tp6u8l9#2.Jb/{=Kآ+?uue{GWtqs-EݜD܃-0؎Ivpn_;#oBRdcǠޘ7]gܹܝKx%)lr]?]%[]"9$0R1=Hx΃97$ ٿ̓GQJGQN! [)SjsEJs/vc'Ҕ[!eߦ!|̀7sniˌaqՁ\S^@vgQ)~1e֞+#cnnƖLy乱v\Hn[>2pG[3,!☮".rJ_oI"{6̽Ɍq^|vӝF4݋S ȝ[=F uˉco}ƚ,ˈ7x11Lӄn Iq48k|CxLZuuM5a_^2K`#)GQ%@ѣRñob&w4ሳNx79χ8URnȑq0W e4>.cH~/׏VR{*|ہ]ÍfcjZۀ[Mbuvֵe3!eWJaoM$\EߟiY&:~Z3g-vUw.S{3N|„$+GWSu`Z6{^./3Ƭ)6 Cm8 FeG59viX7( :a"̞ ͘d MEB dʝV֎~ <.g2UKw4!mo-^Zgŀ76lQc{\zݙ;qL;oNVQaIKvȃ^TT4 |Z|7/+C:;0cX 1ȁBOCWC<ڋ)VTsdR3O&QʶddT-/Ŝԓzt@S0|PmnV֜'Mˌ &τ.|' =$"ũ MqEX1T7snKRëY΃2a'K$"V_˱Һ KJqAAKЭ j󐠨8I56.æ!Ypˏޡ#aXUB-%1}ƝmMYq™6xO{2ǍǺ' s?䞘FɩZ X.sDo.u/o"fy׃-W:2 K1},|&`w&.EBu@y!1+lӖM8el'bǸ2 Wxs5F?îo犋|6ڗJ7hSCT_#Vΐ{խ&xLSQ&f7Pp'%Ds&Vaz:2$Tݙ|vɘ(eX{&ma}M>R/6DI~"^e}=󑷳Z99p=zt=l+s`P gZ#xe><&B_8՝eno-E՛v";x33f;TpS,l*w=5{_[0Mۆa_L8٨zu#l`nY\*݈#MDmQ]ota])"6pc} @1E!jTMa-87ۈ1GL?/1fIh'u5/*☉B$dJh~]LH6hb7#¥+J~*;z&k븐ɿw ‰ǼL9l&o=X-jQüVvG }ˇC~xFʉ]pą_yq7spfoN:Ee3gm%0-C o31{q?-r~Ej:GSmS3֌} kS-Jz"2 ?Fُ[))ޗ w,َS]Pf͜E{ذ5Spsh[pĂK,q%͸G^5fSZ8RQFz[3%8Ύ/m-ˁ@NO)q7%B\O(=|Qt7vgZ)U`Z: Ocm>>N ,õ1Jc71T@oXy#9}ƙ1יC"tkqTkwi1:GUBR裙V ᚼT&\s׆An7e}-zkBl..m7?XSτW L[yJ GxL*ޝȀF1nd`H|L럠gO8m?5x0_+ZRX/jqtP=;5ruQy阑-&n*caVi5_X%Ը!ݱ.,4remO2=ks]ӡ8P"!z7FA [8^y ^Y c2nu z4?KyէxcB}M'|~JL/C(u6l aF+3s1W5*RWeh?gJnqx6!>ƅBn,BݯEa"/ ѵ繲G'zJ+jpb\z<$atԔ9sZ_p`;.nixr UՒyIkٱ6wgɟX<ҬxTgXHF" ZY1;ۙMiyU^AU/&[-~lˇ^jo(}NcZ{9[O7fFmhdOL ,Μ)4ZA{K!Wb ބō\ zaYTd#MvuҧPB]-|BIW ˖2GƠ]^K`7 <8+ >JspB 6 Q-I0MVN0Sl>ĚwС== }b`4 ZkjΏmi"1v'm5L(wCngr[ ⶨQbW lSDoq _> oUad*mx2ꀂf}yUf;lVpb{%\񓻈B83{s̞[Gvf;awS:xz#h=TC- N?3p|$~;ɡX_Q=j|ݔR\tχqonv<37Rc]`;g`[&#_. ^kbt`j"O-]+MQd`hNL*ƃEX6 13 '.IY6 [i_JÅ79tEoTm-EW`hK@f1r7ՠ*8Y~jqMhKNpeITxq_:px1'v<|:ǏxwYË1jI2i(͎Ch$KERNW'x; m@~CUGa]σB,,LEʒ=FDCgƛS%8s}-⏍&Tlb-}bл.+Q}vzvȿ=9ty*VF v;x;~6߈ia,?3&^Jyl\ďEآnOtw9=9ћ=)G.R O9Qf5xmgHX@wqdQyb]֪<؉낻YvFrڜys+t^\8]>o͝c8=՘o3kF+ؼ>{0do.NL.-0sH>f~8ގx(Cי|Ж4ff}o8Yjt玆,5`-Sc4bmY۝]ŜcюdʅuF.QVVcίCsTnBH8.]HSF9j'8TiY.4i\XҊk'k0.\1Ex]kÑ!σeOšܹDO8Fl̛~ 4pEu}pnc_]UVZ5ȿ 3RTŝw2#{W;}3oGL|4@G ܟ1MӨƙ٫t׳>kwz3 GXaZJUrw%#B>]7/t XՄާ8# LiOMw$ k>\ osg |Hr21kG&?TDl תF\<-ѦI;TwƠjqz%cO6C[q9=`<̃ߌ\t.R0hBZŊphgZps ɩx4#0I(C70y]aUb@?N4߉*-:CqhmsK |!pM4,(Cgc?U5*^F樂M+4ϳTezT'Qyo>zw*'}htYW/;-ûD=)G35+ǖFq݂UV<ˊӚp\sö`Z-Tcu-p}hVw[53ҐMՀksb{|ӡF:nt#SEx vcǝ -HCpQF]GKBMF& <پN]EG(4YKQ6}k6X^ XF^BtҠiM U$55Nö*,uZ2UcaWM/vɯ[=)PWHcw6{.]7TQQ+XPARgܻ]o F7k5$ |LpB~ZGذ;>N(j=E-.RPSgS\ݪBLs#]IWiqD{N߫s챈F wsŧn%jUP4LSr =S74 ;z7mjXV^ |F?)׍1.2{sD>N5k\|5ƛuYu xEK_Y\r_lH^}a hNi?ltofR#DOHћ,>鎵;2.9C?n#[Y͵|[Ymϔ/:}f iqB7kH p! l tTqDuǟS0m_ޭ|UJtQJ-י|-lkoxg[}MZ>FGmMJWdtu Dt2w4YJ(:{alJM55\{B׊u U3z=<9Ի$Y>]c{dB#T~@7HU2PoI:3OЉCW0rto#jv/a>a:):aoMߵ?`?˷kƙBji0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ZD]Zl%n\gm^^Ql^0hz뼪 ;~f;Q];TӚ[YhWtG 1FtcK]F;o]溺!Vڮkz.q\XB) y|Bv mTڳ/kKVk*>Y_Gqy/ҋrz'^F3[FZ^}3N]ѽ܎([ZQڤ.JGHo-㺥Dji`f?Mkw ?ɺ'a=}n kA튃ft:a4}JFyԱ B64.jm߷ `r AK (1e%NјhN(6LΎ}h$O7:Bw=A _Heu?N[uI|haqeN;^&S?ɹ !HKgrix"*ņ>YGר:OnjVd-gv]KSmRhS9 8\Ew wjUP74P%5Poud$5O$j˟9 GJF+m f^XQ崑>D&!K%2J+W ?^Jcyge (3mӨgRj!C Р}GhKfBBvz *OI?hW#{Pk"*hqW,aLQ1ZMy)07=0 v&U,FG$5L璒B';G^!$.2& hvX Qմ"cm EK.L#FImŅEϴ^1-^SۣFơVx/F c"Ģ4sB: 磕SPtV"خ jPAT}v-YK>ίrzhV>]=Křt{)Q::RPW|*wJ7 JY%bji;Q K`3KdDiGce]- FX)>D_O5+/C[,1mI`r vR5yP3NaUۜn1M5ü\؛`w ]Oq*Rb> γbGBofkk a^4PjZ[O| wjTU#.G+<䂫.czL`ߴ|(vu44}5aI<<~i9dVztK'2Xc9a':! UpNI}7Ң=>9"\#WVw Hpu{U aaA{CZin~O82k^;Njt6 hTIy; K ql$ VPEPKdOB=K%2tlBK=RZ:w7%Pk)4.}f9P[\w#iŐPT'~_yvb¡;A[#KsG8 {|忩%-\=Yv#AuUU }b_r00sĂvN{nB T>a5.l/>`-ALt.F3ZzKpO"$+c54JNf\ 0·svrpk1^>!a!F8h|UB)j]J}Zf?5ޫXф҃M64@,->fW|1Y?h \&j}r9r.wEPHBظKTg!fDv =8#v>c2%ZcJYS!;֎(]-MKRܼD"&pH˅va k+C #cgіx(ƒ|,kYt)|pu +5TA%v+jzHLfŝo@)4:~Cz.i]N͵3wt?ut{vxwmq"5;SR)>'FRɴ{.|{WEbj-KϾ [jZKE8ImcW\vpE)VV!Sk0l%a.x{^;b{ hEU}Hl<j58Xc|w:хŹQ()d\#KaQaM7xĖ s`>v#]F@:VӔ!q¼Jp9(/ 匭$:8hV||@%n3._ݙ3Exadot/g+oc퐕Q:Z:`!s,EcFQt0;m1!v ® nk8ٚԧXwcke%))N^3L[Enڽ༛>3oE +\ؐFD5tr *os:v$kmq-J7;Ð2;TK}W>L1M5=  L1sW4W$el8uGhX\|GTv,ƻ&b=!6㋍zuw<%XSC eDj,&Ie2!_FgD)f[ᢂ`>,<Xv|O[aѠg)] < >kɰWAJR;ƜmzB\##߶m)|ofg3dA^wp}ѶRBԈAK*u>P#[W  ЮF8!@^#Cp _⽘t316{iK.5fg )> ~[T%j[c[ԟFz0!1 >(0d 'Uz\8!Nj<{\6FXtEx4b_*`3U .P?Bس*Jr^GVFH)0T_J3q1 1uh׌!/di>'46s\Jx6K;PTQ%yGa5'h6?xJ }9nxoh t* CJazgWيo8_☡ f׆BJxr>QЀ_vq=Ećrk#C0P wOK˯f8{XM3*Оi7/M&Z a}#xŇ}%~ #CT+>Mџ^ ^%=oOkR"(*5$Q~>1=C1!dhʷҴ;)iq\IϻRGG;&c>L3)ؿbM4PNXL]]0!R}t v Pn?6̥&jyn>fA_*[l[3ݻts\]Z#d43zJ0Ȼn_-s|p@\Mp\o9 ) 3hKʑN޹f=\|CFjD櫰GﻠR'Z"<.Ma$plk G ,EFs%B^ rp_'+4$H'zD+,9i2QyV!!|4*6 1T5O:2]K_¾QTVyD[:Ns>g hnJ!l`,W`+Z(C t6i W ˱n6*,q Akf|M>T=}MkNU9xfuݻ~Eqn*u/!?EZδ AiirȈS>Bb N_XSl)^_B*kg2K#Ě[94/m)/=TWkv M6%B^SO_6g6Pp9yJ _*?xBHCUkE"F VbEwP>\xVGCNj5TKbva[ϛ#ROihctZ$F?-YBJ.Omr[dm"?W&N)T]N5Ƙ1P.]AsDѩ.[ۘ:xGF)ૌ!khJgC΁}6UtSE9ra|*ȰV߿(|'p.}qU4h~o ' fg˦qYķNxtZ-q kE=|'I?hܕtR xGD8ƝNZ_TѐCjZڦ# \ 6Ɲ6?]MP EjLqxxs lW{ՠ*w̍RWo8@A >G~}G 4dI/7jS! \\Zgqv?!b| Q\^C'5W6- ^MnehDu6sxF!( 8خW4Rsi&H JcpdSѧs-T/Ch H[lmhcV=Q@FZӗ'De:1m;<J)R2{l`8-1#oE~Ĕ/ghb~٫0*H{?} /wSJ2"2*ӹ)t2+*WŴݹE4qr͋h#cv8 !0U%. dS4hSUnPOrn* yW5x8<9NCFVT5e1-gcB̰A3HdgLxC~0@pL\W\!im9, #[BC%Ѷ(,0G?iQRH6"Ӧxu9 -E߲kj /=ʞo98&7M\dR}oz'=⣑@$AK=Y9cq [c2+L4B>۪4z!"k9X>$Jj&}giOqz>n5Y#@ |H(KYPE͇&:|)5gLn2F~t–5t8%ʣY TR?ہt9ힻa` 3Uy2Y: F6~w+`Jo(s0)S#Rt?/SpH»gy8Sh5tw !c?$uwN1^!QǛ`J}* i}^_Di* /ѻl3<"Wa+\@yAGDQw71\E?$kEؿKD7FE[,MΜ3ƦZ*Cﯼ>(`U tMcéw;3gbGJYTYڍ K;E09 8Í)6@rȉug c4ܴBy'[wCeAK5[kФ]U(&L赒s,\vQjkA07"rƂ*Jν=ZDR UN#H0}veB|nnXsxCe.zhA->>9[|]km:j/BtYhsɖY"{ g3ŧ=)~qҤ.. 1Drq16o4<{GV?)z3% ,x]gT8/tDІFߛ볉>xc~GJ$Wc aUc }Xn8رZf0/6TP({u>ƎG+ "(5 Ѥ7l5X`IWScp~A^Ɇh5F!M|+*iEPZ ~n CdO3~VhI-X˂i"z+yaHSF%rU6Ge(Mo qI>j]e ;c_g,&XK lC-;& |xxޥ>SޙTJFW*TNEb!n 1/⸸7 NMMvҩ9"hbF5m`RR=5n5VM/} _Hޡ.W9*Q+er4q{Vhc@|g\>T,v <>,C*↥Vj*q3ۅ4;N >& }WGR¬Դu0T-_֬Hˑ,,pfO{C\)B!K$d-=SG)} l~ 0>\DocM=)p-Evpm󗦸{D''$8Z5b0}Tԩj)~jSQB ̖! {71eqƣ ̞c睅ZC~1|y6ìcTM#]:4_"48 X IB.ʞƸmhNzcAVΊ߇R] *y:*:Q&9~̧Q!PUKYz>>AxK?!Ry[aJP -Jl@F+h7ZFnXF'aRg_)θbR#a9[fTXHak46c0lr,,z/^6mޛAޑ}n Fm =|ZW>|O/9?h st'M#S7q0eGGuZIqEKQMi9ub4wU.HqL/G!5ܿhqgصڷs)[J1\k]d+vAN)sx]l WVJ]A%ӑ--=;v>HY԰ ؏aFhq(6|R҆0|ȡ䙮2:}D  D"H1~!Ξb>`BgqgT )B0 YJYBrSE^TS_hJOD'*ӫ5!G;o ;Ǻiph =[KCd%5u6@D8/"'tE~N7 ^PaE iKԧр+t!v%*Z#ͺ}mfRSYH'Ԑm] /٣g% čXG9JrA#{[8>wFgO5#)j1w;'V(1'FҮRyH :c=Wc6 ,]+aAv'{J lE9PE7c8%R-Y_Pƻ~n2@G>V?;@ubhw$O{=NͿ$P]E7P $sBP;=nz=I0FQjaYs7ݣu9L?)lgz" 2;?ܑcF3䀗o|H#J?2U(_{G.| lW 8P%MpA  %E)1"8o͡KLoI#*jvaFxEӏi3ioXCt[UOA8=n͘#ykڛYLbL>_Ƅ<[D;cn pFxe1=p}F"b> `=NWϿ3)c " B?lpN?o(cTo^?C qjPc71W<Ԥ5M8}N0}~IJ bʙ@sվBPµ,:'foḅ>P[wZRvvѶ[m=-ox yEMTpT=m?@9u4DRWt;]^G\ep{~!%?|O}7=?( 7NV tFp2?jw(خQ XBS:h5Z[U_tw벰]\*vwb+6-vwbb+HIwϙ̙o{]3{^[ K)BZ9Ϗrƃ]:xޟD ʔ.,okMoc0HD|ZkL8Ƃc3E=*`f'mwZ;m#w X/@rRCfgƊ }dYlޙ'O90\cvŒC;q4G޺1ꒈSDR>.c9ͯ{Aƈh3l@)uz ٶV63Dxrd;H%r~/Gv4;}ڽ98\g ?~6:s 9!%BjFZۖa;bx֬%d{ѤuC-liYdI-q}!#Xw rΎopqkXq ;?n#i8c!,E5j~U-*YL[sUl&pax悆^y@ݒ: L4GWw%/ O^1ȓ+O5O;a,g@)y|[Wc֔rĚS40a[}'q;vvO9ftF`1MbaOFtZ#8P ~.G~v5&gg!01o`_'Ṉ$əݘd#4DȺ3 9/畟R:eSԴ؈*ί "Vd1MdM-Ό'cLTP݉tY<߁ 4/321>ɩ=AGX%r4uգZhSt"=gB״ v!̷j!0z.t+1cQ)]FRٲ?ff,ķnѭHw1!$f>‘Uxg+o3lʉ/Oł*;b %+8Fv >3qTـml0VrVƹDOxEqr]r|+1]ugF5}MmtC {f ^QmÚ~N$:uXpެN"%xm!}q\C2>k_U"xEE|^} _5c'+K؝%lH8iicl8Лqub=^[;J Pa$ᗏsZ+\fKFoqLzfqog aW1c[<*ʀգJϡĞ ycgk.wo׏F?0{gt/r҆+zskϨ9/ XwBIH~_hμ.g8ҕSObW]z%\<#cL =x;u'x̍a+LWsuw+-J¢Cb__9L)j1u=p#Ξhɀ|+ֱv|цO.TjI:|3 Ù^?`b;!}؀ǧ>vaWA.USRi%)–>6_FV"!3k~-4/|ǁV?٭T[T1Lȯzj7SQ@^GMuaY"JzXX';˃EyH8'r.܃L,xd\5>*BY!8>~D$ĴJǸ˩-LLjLt[Cy Ԙ)5!pHo>Nmjh=8m7FtܣCz||\VF:l]Vk T+00r|- 5еaLEVr 5Oxhx5j{V7UbRi\rۅ8W%g89g{]d{̕FZW,о d0ࠨ@?+ޛ`LK^k4SMXu`0[pgۄ>oKt<ЎSXS֊=&U1Ly1؈l|n )pʂj%=7{Kt6R_ 5Ku#Л Omzp^A`;lA͐"2q'%UQrL[nā)t M̀T|ܖ+]+PYOJS~k& Ü0& K "#/.[;6.Zgנ@k\3㨾seb#gN.2J9f#fJVp)[Vtp*֙#FY9=Bxy>B%)rf1FI썌7xL>*ή/_ΟKeԫ3b>yV_Ŝ]c=m6&G*9'_!Me|C/eUqkn!wOng8^eHW=֚|߹ņy,ٶ΂g ڳ%g>/renwxIml|FJ+[_sa۰r97\ņ;}y;.@KlgaԻd Wte؂8t\4 aE@fvOj|Tx' q_ %H512f/%|"Zw!m 2 4E=2d;9[YIs-aǻ]mvڨ_u8TsW$Aw!QաR?,ְO=9ʅLo`~vQ)?5|l6f`#{ 3e'eޛOث*krT$IX'́W* p\sbwgզclv#|+Lku[ykWά8ؖkX(R^< GnV7{vkzLwG)Gs런u 4w&P:`GUyXRtVC"2E ӴGw'%[{mi6v9οuYrٌ>ر V ai(%GA˱ .񑂯xT%g#K.+}).(EkD6f]&x 顕6 'xs 骘x^Σ#5QtJӘ13`+=vjS#U˞8hL{_7h'ijw~FɺGX V?\i-GW: _e3̩̈́ڄ715Gy 彼9Jݮ|^O#LX_ w#!tcQ ^I[^.`n|ޓ/#rʁ{Ԛfpn9JۏW>D׬70>EDdq >NHIrlCOmxn-*\I 9*/Kr^^#M;)L-v' xv <1eA'fGtE@Ҿ)Q .z1'VЗ ЕJ*7)نJ=&cWL!^ arqq~v[ϵ?-JE,-ìjXv2P |ߧ?\he1%X^n0]a*1s Luyl>קמX].-DoE;a^0X3gѼƓ*M*^M1PN{a/ }@ҋx%eYR[+8u!ղH;D~\įW)w>ȃ]+=ѤXγl'c ƺ3ލ2\Sӿj/:@ߐf|ǹ)-{P*]p)tCM>x2#-ױ  @M ,NHG\ݔ? _T O1^=;h^VLߊc/h9)Y8[X=F!z)>7*Ai_*t. ژ:ynMt9Xg2rNUJbC9\t͟T:^[5F\. ǎXb)Ipc[K9Fb?ޓ3@@1}YQ̼"n}>:#DC8.  ѳӱsvmki0Z?>B l uv\?Gs?W{`T Y2dgΝ'<>!x7aߤ`WL|a߽3}8tڀ99t:񉉔j~S&*`f*9孂3eKv,Z駱B̈}8 Y>0lOGsѴe#sZP̹[8s_B O>+g~dţ!\sNtg''YFAS /NQ1M\D•$}*ᯫNs lc,~RMQ䕂|.[_3Z* nL31W~r]26H"g] x} 9A8{ǷD)۶%&Kk?B3^?V+Nn =բiE  ܉Jdb shy:GH!CZyפ$>CrV!nu/@C ay w320:;$OʮW;y0ID neYr`e-Dž[[7l#" 91#2Ęgss1a0CϠd l۞.S73}T2&QƝ?N#o #\@= 8[QVO`: pZqes1ÈFZqgg'!│AGs )JC9odܸ@[u"-:N.e8<]GJݧOo%/Z*$0A-rN(T $dp/"tf4 uMSa$+kWū:// BrȒİ#1)v]e σ޳0QU=WѤ#ԈLiZAd)bW%׎0&K8N,24c;Tc2T9g8Rx>z8 pœ5pE&A=\ stx^/n }\ݩw UYn@%9 v4$>K3q` {N<ĝMԿԊo͸ ͺcO#=6aY9UGx+Ϟ}7%,ScU QqRinGAzs3a\,W}#2bиBN#׏7,zmͧ4{&a 9_(h6@yR D7S3QA Hoc˄$fE2pR9WN϶TT$F`418pe2Lӝ G~0^:'OԽ[-!4gF>όih?N? v?1!ʉ#G/ހ%y+TJIo{5m)yGmG+ٺ^)NܒGMY6Ę;Jqp Rx;סa;=f^}0Œ|}J`ݶ=Ԟ޵!`@+XxmԋVTrOΜ"';纱ЏwMd&OZE>rn/GcxpOVΊ_;6wsF? }slx15*]FȘ䮢R؋Jyb <\ ޅ2N_`סJZH[t zw_Ue)cZ(%O'rnX36ވzp/CN>eȫ Әˣ̘xܒ;0\hAFV!8݋Ƥsr=qHĞB_nS֞*jרxv_Y +*p@_=& G sDB/mx2wo[ҧA%zf^Bd4~0:7AU Twm`t̽[br{Ac W,/01"1=6Gmr*기6S|eJZxt0z96(.f+dV8aNڝgND;dc'v50;vo0mqoO~ؘ e=z"XPO^TaH/imzqjfI-ZBW {">>I1?\avQt+nʷ nKX\`#_ \=Z0VUEuft옜n,پ΂'f pKnK>4eDW];^阸;} ՟(ӖL;1;G Ջ˕tj?HABG}-TQp4 ?]ppB}9 }-Du6 Gva`{$g8@$Yojbsw@̘>9ߏԡ3ދGw]c7BG꤫`9Rpk%T*?GiY*>0XAG\+v-_PѠ+\p]$lc*bvNJ.gyʁvKaסD$ٯ?HBݙ9/ܴ x؂<)$bVb:Q#Ŭ(a"9N=gčZG c㫶Qd2mk?_[溶BV28NMTXș@^ fQ󂹆/NkH`D)? L{3gt'ZT =XZ+Fϱ`(s6eFU0mM5Vbhw?br twE>9&֊_s=Ur7:)۹3_:647eD]myh> 3B64EQ6vʀàt4{?aϛp|v 1<8Ԭ#6uF#X DX*.eI`FO~cY=NߡC;N [hZ/CXO-t80υOtm zL~ոc,ۑ^?y1w.j6 g( 86 Z?oco)-xƕY oi+M*?QrDj>{5JJܱCʩnvtdCƯJFJ a7_$z'#\p#gt[列3ڐ2b|^8tۦ~}G=P.U^yVCh+B81qDWZD#K1ϭx;?K9rh Do"|!f)9 ~ts 1ke,ㅮ2:Wrac*{D)䔿3O;;E#t{{⭛ d?lmAѵikuHù'אk<&&°d`LUЎȘ]n6lzG8}"bA9Brmcwglkׅ㩴es~48c#N/2zchƅ7yœi3y̒GŖؘ#cx3΀u(ihkUntuKK\EN$9*XvR`JPdLdo7v/d#lR+$?a|ePCsq].|˄ztY?pT+oهgGǴ۝߿ZӾXwvյӴNF90cS*X4)ΈBڐ.8 {1n|ˁWp؃j J̫lp[Ģ΅͝orPblfMKKc4(9vqX1_7u*gG ͉XXROZI_DiW eMF}m"]"HDW7vf.zx pc[uvGnP8[1voqh'K|pϱ۫v{mx>}boUSҔ H%Tc!}n(աIz, 绦^b m ͮXWM2^eƩeTU'CbO&Ob W1b#EƝƋ..)p;^ݷiŎX30C#HY_7=:C7fBVh\զh69~OV{fuKϵўjs{JUY].p̾zǃz\)3fNdf-x(Қ=~ M.y`WkΥE,K1Oߑg:F WrDo'h]E/}dCέr Q;XĞE<͉C25gMf kKT{\rEl=JBE1¬C$<%bƝ3fp#G:)gB-h37+qHZg볓Ҍq]̾ǰo v?p4 Qs#2#߈O߅mB̕ _R.4VĚwXdGh'A]dtNW] $ _)e){吔yD|2ٙߜy,͉sh;{|aas ͔6Ӎ/א+hQ+k1nnt)CXn6&/3zq~[cKoqq{+QLNDw83aOIm2f#_5e6.[N/Lpc^g6+̭."LQ𷭊ݎ))ϓsLPT˫{_ʇ<9d9r nʻclXu֐ǂzܻр-~s-wY{2wR.fK}4rn;p=_W DNH4AZc>ɢū?`ְbNX3; ݏqL:Wci+u֌(3jxdR,i{?]Lś=pmX x I04?FT]a\:C4Ly%'ad0i3t`K7`KWw٨5c *~ik+G(/KͳF 0 e'G{$Ip}\Is?m,%o%sMW-CXYo:!;031r*'v5{߲KW,4C"u&21jإ+r0z[vb.]ەͪ8ֽB-4׍,H0pP=:flTgSe)M‚/Yb.P岅E? :t<Wc4kq6@VNȅՋ=YTׅ?j7x@d䎭n#.'B'awS o+A*v.s݅yÝJu{Kl̃79f augFa6R1;J.I6tPlc|-5~2y=SS`䙝O]iڴ=m(Z`_x1K`='Νl3Ċ[Tk-%C!?q䪾΄0͔v d֜'*6#1 jE8<*\ٚ6r9;D+x \z۞-s㗻0q~\e*jt0ʹ^8Ik+_gvM&~%[5;0&Mp I-Ps5.u"c>ډr=۰n)V+yY~ލ*sTT7HwiFW3磂5ښ}Taca.BB NjY1M,^mLůMehIˢlOtb\j+/FzZNbow^rdc/o6d?^U`A|)G ܹĒXFĬVsUw ?D-:hvu Zuّ>MU_FV-_h~,xˬ0@ȞzIpM&tUF3}ˉw2hi!aX?]mcmp/}؅nA:#Yp)1eK5U nGvhFah'h⌂LJ)1+/ nǐpd_nt޺ ?>uo7H ׿ N$+ͷ8pIEN|&5<8ٙ5z+ 4sfE3g:;Vÿy-Rd,f߫J}hn8t9UX+F{>;YqQ~c2a{`,ΕU*-ۂ?Xz/-tn:fS$K*Yb^j28c:sɉ8pP-gZ~n|ձOnޅ$8 i}CNx>Ff{Ȥknr| 7,Vp5Xrs):~n]#ÌY/*g^_3~'vRN+1TwaGW(i g 7Ŗֺi¦-~tOt&]͢r?qu4=B P?a|-=xX뀞~seG71[L)ݭ23¯##wðq1!J?S3/o\w'^ W_g&9=9O',^73.]a[bR TcgrWCRtwE_aljNSMKBY s.>c}Ŝ:S⺶zB¨mr{bZNq#?p`e#XGYUyړϜ&ЕS<)ζMPy_,P׌fZ45[)xk'{iQ+b’!G¶Qs)]90,Fll[f[y1RNU)r}7uWY79fz^ڎw wgɮm1Ӄnx1?]E"6cO[C~\n\zNƼ?(Zh;>>~BŚUk~{?`.$,</.!;Ӓv+b)Z{nlebp?=jJ91/#=8uXgn/o~9ʞGy匌d`}uČX[WXW!U8\}͌;[GqkKVmi-H~븊 gjyT`&zZ=0(R{#uby #22]lqfy3^pqw޻;진 йv|Ds( pk{xڲAg ӎHr0d: ~lV {)1# `ψmrpK.64S)f0k>bۗZh oG1Ͽ5g]wfO~?/,_Oz5( ?v,$O+E0UUaæj &H1-^֬/o/QNam]zB!pi Jz%blhʊPЧ-lC//%oJŮF^B&sJCM.Y|cmL;PsŁYi b=Ku Ҳz1ޑ}/s0Kҵ8RJ^ nn͹^ Kƙ!pXw>`b nt3ȗbR>:*a| n6JCΙiRb 7ہ=u&iaO#o5rGG>JFT73rB{NgN#c2x-btb1d}:~ZOLl,OԳ-%=𗰖lMӰpœO @BpXܰN^{*vOU~/V$ c?ނVv{_ r{NB"n4|V$eTFMqi W2Dh͹9:TH'/[Kxzsb&\#S0h&f<@3vomɹm򻒲:vtC*.=[TgW 7TKɔL=dՉMhء^z~$sga2T =Oj*xD\_ƽA|"p +>,¥P;ŖuPgu!lfgV,rE]r/kFF)A_elb`@=/Oj;p$<d;93=~ƅdN lg`tknZEcq0/:%wx:z4c ޱo53TٿTT+Q2f͈"1hYتz1cC/?GP;ޗ~e0޲`5"j'ٰɳ*t{"Cpl>ԛ}{E}nәx"oJ1jIs1W?W1==v sZ9QX<d؏p{ Tܖd`Clo5TSE /j;SGJ[mŽ|u\Lj:Lwsw;юt=gv=3]k9}=8a(^d;etpQQЂ'N$4 U2<* z 3CDn"n aOݶUiZj4räiv܎/+݉Lߝuޞq%wvm5wdb'^i 7C6Elk=h7ԍ O:Hgr=#whfwiy\˵ϕ"?[vٛRnX m#Ύ!K'ǚŸM(@yX# k[/lŊqvq-+zR/EUnyOށoS\}x w(`(y^ǰy!9[Ϫo1EšK }7KnXP^pRdUM9ណG|7Վe`%+9ȸh#4.kVN1D9 mgSMʾ6x""5Xfßbݺ_2RPW ڧElQ`{ \;)d2!R ;+_s ?3)ab##r`R+#^F_$ Fd@ (D,]xVJRf/f1("\$t>aCo186\W`Zk 4KA]!9UO,d9+}-Jh?ŖXQnƊE?137 Bl:oJvp%b,]>l-z1K~޾m*#cIᇣ6Igf(J+H(*BqČ(5X("⡸ ʼnPಱ E^a1y{5R[,~jD̟HeiZvJRT츲1Mhnn lg.01#3-XKpbY%-SsC5=oiⳁ;" `Z[.|)y\8 ŌO43}Mkּ*prƚKǖ]V+u͑jfN}kp:2ў,LfN0ى`#״1lgpZjs} Ujqoo iצ.C+-h4ϋCv\$i6>dBV3V#nz,RރYlY{ GNxI8o<ǎD Jj&Fx GWsn|ՍK,t3;c*6\"Jڡja.l6pB+Um`tW笘e)l.yH y7+H8恔mNWD̫#ee zU3KV/<ꢡ-4\=Lm5rqtGNSqgG#6ˍO;QӾPY(y}>姥T^nsQq ? )A`vf|UR39X7% U*ůE|fIۿ~Bl;Lbyn<م9(o_/f~\߼x=R1 ޓBAajR)y'_QuԂ6jCsmt2,8jO\h tSccp;t gLmKf$zPx@G؝L_zk Vq|[ءHAõ~ou\ w6y#SJ^O.Vp >kǓ}tnb9Y+Cϵ l%nS{*yssb9m?qE:Ci-br 6qV =|]haWͩxIy1Wb=2Ŏ; -7[Ǻȕ8a݌ :6PNWtJBvcgnYqb.0Jp$R&C*a*p0B6ʑ_`$!Ӑ/̟n6Up;XBL%;F2BU :B9wfg!gpۊ"9RG-'Q3'YsNk>/a.VߌGI"6m}h^=.Z=E712 Goh'|kR,jW 7%xg#Bxek5G)zԒ\9S#ws'fX0ΓNԠ{_7NlĉsCT*h*cjCa*Cbz]öJ-G(kV H\.f+c|bTy/iC-P 5DjU$iЁ6șNܪwf+jV8Ӿ~tc*m >~ Vl'RIR~mg>bNUgp~2VB1'hJq%w"nl!FwICO0{8 )RЗæF)*U\Pt!`[jDq;8ǚ=; S=Wr-jV臔g|Pך%߬]& ǃ"~i_=~!9/1"lY@2Նt.Dpžݨs3-'ā XD˔|~ZuZZX}9hȴjg3k2-haqr~ ꅊi-{x)\A?5TCT,]V<,ő \0c2ls{ DU&z%B[TXKw4\2Dۅo3aG7ԙi=ŅS]7ÅX bN'-W3Z` v*RI yi$LkEy%)9v)SѮy"h3qh%ah̨x֌Dx8> xkĩ,tѓ#P*FV]舃szq.?sxZ&2鵊KWZ~,WT %X<6m~63K9_c%<>˒ee{D>y~nE?ʰ#ݜKmx|5D.Ez.mwu(fk7iS)g[;7~<̤. P 0c或 2TőlOx a'[g.K gɯ22>a(}!wcA#*cmRohg}w`g)V!EP{=&/ħlS~rnQv)+ pFtr{ 4$Z=#oE~݅n͓ݽ;O8 Ļ@wll`E~zfj7wqݹz>3]_dWmTpGh^ym8IζL=tZhvSF vɫnt52%NS_҉J UpJ-԰'{5ZGws#c1Lp.L[>6:NgJYI]g<}gQcpo+ڍ !};>ކO7an<\i X Ăsh:>1kuCϣjI[ b~X˗R* ^l_]?|jt[NI5I}˾ǎ(t=v8nא]d}>?=`c\^}ͳcIkDo.\Zg}+|{~NA`HBɰ`;w O2!wg3lnygvN'E&zXPI\}sF \~C//orEFuf]nf ;s}9_)[F/Qqξ_u"~|Jζ@k{ΎQp"x@+[2H!8dl3t a4[c7g W,uB{Ͱ 7Z(ב:pV+yʚuD<7. %G;r+T Xc$>OY:Z0异g^z\q̳4qwQ 7?|U ZGyX دqRNn`ihaq*v``b#o[^UEq8%bG{jdQdzN|6<ebx!Vک2v.O\OŢ+8 ƕ;xzwo6sG0&U@{L,ÿIHK3!U m 9f)y}=pjhYÑiK=8f3o)iɂeb\GQ]qS GuuFYpڷr]MD㬤cgf%'e^[Jv˓D[9 JִY9؋\Ybp&Nuwݕ/3=ݙLY\+t C*9̓qkW8qS3l3-[?Yhնzvcz ~t#<ޘ8h+qaOgޝ Ⱦ|*e04QP' ]ky:U ӚcGeG j4Bѫ(;N@e} |E:\ՅW<\&yӫϗ":bKfQ ,DЪ<ތG2->ě7c$lDHWX۶/wRӯI]z +ߡbI%YrD)Sqy|1Zx%Nr\+Vrw nkax{3^'>g3ǿcN7,휀IЮԒ*d<x تHJpSyuڰgK<ߕK=hӋSubO&rH.wa.0Ĕ.:ƕV+֭{maROߖr`;_Qvђ[_B%Xs>lF ];ޟfY5‰Ay<\3Kyyw< 3%XibCа:/[[g"n<'Wŕ8U#ܒ֛rPe%N8ؗ~YW~!&.~O~ څm;h}!ο+g>WkAݘ𼚌8_&N5Y䴋 ~X#JD|͌|0?lf_&#lŕ=Q8"kbH&][YÂNyI%a1C䜵L!3ѻ¬D'Klx~w`iM{5i3_d1¾q 稹J[ ocx;_~os90c[*80 ܲ~ݻǹ= g\~LϜ '-{NX (12Kyڙ]x⋉c蔤bDƘ]樻~̬S#riY jymRW䴬O Vq0)k(]16ǛӚdV/GIMvo:9*ܑ6)ٴކl1M=Ѩ*z5֬;֞R5|Ŝæ= 8CHq_`gN?ć.Ù9ӽЕ{RΏX~ԅAwPMě\u@ M3=NEM̩D# ft`XkEA2co&jk yPo Non+Z 7BԆb{TGH|ϨD\,2n1p_El8_&GVOKTL035JyÎgaoR㜦٠7V8Ya0{-7Ϲ:-?LǼXUG|V)t O+c0? +qsxٝ-͕-rܸ΋ݸp3ߟvʞÈDlvږS%G?)whڢaQ˹t\T`2~C[V//_.% QGop{8OG3&mljhU*"5R`JF\dj cD6J#12@/I -{ SPF]~t]^<ֳF%c1""iZ0::~&4Ixb-~o 5Wgyܶ?;oem,ݝ l- iwwwmw7vawmz- "]"-1s?ϼ3;0Xv//8v:cXO l5~#lDj(ثqu zwG$n Q8=KZp<6Ǖb3'ҙMp.:YpS4,8] p)2Snⶻfi|-AyV&}QDL]1Q%7 ~HjyQGKA{a> VWˠT'hzW͹ɊvlE!1.tcJ*-+mI-3 ף 4TiFcֶp U7"/3c`5-"0 ^拘]B=2a6~K9 "Nr&msWI+6is3.;"giЄAX FDoP&i?_ď ag`4 ;f0$ޕP \vaZo'iqw.yv|!.7i&fjO<{ޒOr_bD#V?WT\1g |a?366JplŔ",ߚrdKNj ?LYLSЧ>YS7q(*NDpP[P:.(" .YϟDžiLwCvzc=.l-9u̶@-a'w]pϨVjZRѾP9"΅F/Y!B%e8Fˎr}4O5?2MZ]S6+X߇PUЕ-9Mۉ?]ON,7w敥|ؚ}aMRGI֝~yȵoya7f;"πCGl kgDހyxMiNZ/Ӣ,Z*!*.2)2 -Ű:5z_T;k>KEOش9ҟ'`RLF|>c㗌9>Ԃ^:Ҹ%W覦KO}'Ҍ:1m;([;=2̉G})0&nuE\OVa7p7pUO,i$ĜtD߄ ܬ:h4Ō!}+; v4ӥE_mwi^ZvĀ{O2j>3uZGQ9Ȗ妴#.iD߸28;- >ID}6&-,Z;ΕlhtМfJ4BhxȔFJےkbtu?o^8gZ1V})^MҴo*n^!BzEDៗrd}1P,֜!=>k18 FTx/jgO`\UP^BaUq ߲eI .gC z,c,vf;SKXՕqNa͗LmLiLۮC~ڜK]uyz쏅KgfoAV[iǏlmNX3ӈi\:hET Z̻ˈz3^[mӥΐhE"ܢi>{Emو)BD S>tfS'kv3ͺs 1%{U&5'id{%ƺ M9-m?z_ ] Fvyo2afr=14s zwqB-'Նx<ϟfŗ]a1 G<~Po 'ޔ͹'6b黰[O{N[WNӐrA;os?vwĜwSҀuz (c|tWŐ: %oN0QHu_bIH.φAm6v9!{@z:6GkW3ZP|҆,|)fȞ<&qtWhIm|ᛇL{ x?Ć.YsiCi F\5gO|yL&!Axl,⿤co|:Usi|Ì4YМ>ip7LAjJ͛XJxd<>-@'D/ꇮXꜳ`6M]=ԣo=RmUv>Zj! cկrl),l|MB8$bSyއFf_js@-32챦|>՜یx5]䅘u{\X,?b|)H7FĈYc͔UFKi||KU}/`=B_qUHz 7#Bfa-moCv( cn-RJ|TL.]?NkĔGTm|orbfYcsxd?mM&Dt򿋞gX3>Ǟ #=V!`Ϩ$MΑl;%Oi'\"@LXٌfsM-x:ʭz|AVG^^ yYm۳[J6aG4J='i@ bj]8ɕzTUA[MnPe:7a?8CO4on° ܯm@vxmX1ݐČG]y'͕{[$ +p& C:2ߌu⡶ڴ b״&}ii-RףK!2VLG_O!?6!:922׌BTLpg±fdi*C/ǩHo8CDD|߂%˖'݌dgWS]u}kCV0k h?u_LYfXWoaWs WޮEIl+vA$ ca՘30S)oJQba?~C)֯pA3 чi ǦyЭ|6whN85vo􉩇Sq}y] y!3pGmmg[ }GE^BVQc[*ԝ+Z_Q ǰr|FrOSM~ɊUޛJ9 ]7;PvΆmf2ട5q&.-^MξT?fp x)8~£$/ ..tx[·S1Qa  H'cuhmMh%b@fu}-yVZ2!gj0ДOx 3 EE(,=m|k,J̕`v~9h;JiX'4=ĄӃ9Q%x ^A"Svz,9@(qt,ė[^ka>h:s %wxؚsY.Sn6 9j;,Kȷwq6Ϗ\K٘' b3P Q (GAU)6V*P3Ȋ4pfn;:8_3 h)e0-;kei1V~m8&7jrҊ(n`D\SbV9'Gwh'8. D? <S/c_lB5M®pڪU֪'Uu5 n/7GldVӌa6+'y;J+b Ŋ12#^nqqȚLz9\K@Y~laP/F`R1҆ux]k*q.Zk m16xإszq2>|K0wHg{[OY`oW}_m wZFmyMḰs+E8qr#ה:n-GJX0r; {\߆u9h*\A,2pq*"?bpw3{*Õgex:E,xẘLeJuXQ?ъ4ߖCV(bj{nLv+Yqؘc~q E64neX =gfϟ8s)_?Jz\_o\!-s1!G3fƌ׍pN3h\=y^!zbq$ƿ!ʶ>-t:+Bv,j/8=~[bVb)l@ƈܙ˝=%lށBm8t ֤SzVHze6c@$>ƠUAk9RW2{yr3CӫF Ikw1g:͟kp\&ߪS=UwE&>o<,D{d+A *Z^E*|* x>;`A#* b b$}J$ZAA,U0Qc!cC,xea\&pj-g-Ϙ 0ЈֆT갢Շq:1Oĺ3UΪD7o1[F @ĈԭP.TiD5>e4@TS>ۍd[]0SƈT aZ%4:3gi@UT2:UQO}6F؆S(S;o4 gxc9YR{ 07wzrU%V?Aඕ8Y^+`z>:ԢA!$kq0CiYXf'^mDVxx0_KFbz_-J6/b߯VJ{n=S\wt]b K V7acC*k}s}[}2W /}Zse;ߔ䛂npUOnF~ ūTc*p&*WRFd^^3Lr,,ScV?;Y3wrr& q63UԿӑnPt,D|Vx{c1ZOw4Yl-$݊6*Lg?3ҁAu0u-hCT5rK,̸tt>m?gc tT-G.N[̠ wET+0Gwab9|U*ܥΓ* XXR\n=:έ-xU6*(l_DlՀiXi;2G+tfŮ?];`% xеƕ\څaL͑ρ7Ч+Wvqrv%N?wg{PGN ;(CHt3-p7㪢 x}9vj@) WМF[-tnIƴrrp_v;BVWSEh>+/}O$+&،UMȸ= -lvb'̫̒Uд+pT)6~oa-[q`߈ŕgA8|-]QKv3ŷ/X N_T~Nߣ~nsN<|sp4w-ry_LUءrDeY-Μی]ː&v&MJ@ wAlzg ~b&sM=9rPΩ|UʶݩeyRnQ6ȝL//;K*Nʥ[ߩi̔#u5gAuqG p`3Pʴ^=->b/Zzr;rg fQrIp|YCr3fVg 9  BU'؂S[^QE=U*{ztT}aH:3•IӀO6WUI)G->!Z]ð "44_Nnd,K+p.S܌YUEKP{T6˟`Uj0?GGL=kptp '!2=/;2Ϸӿ]c-f"laUǫRxbgM )Wb@;58^3H1sOSD|O@m!`RZCwz/nlW!ոwcuy!fx z%W~$ԝ :<ig;83ѕzjʙpOF%ztGx qgO)KʸhIyQF];+7,7:\rKTuvU3時 GJ{\+ ; (wk(~o|o>k_/NWp"<gwkLžخ= vcsWۄ1Y[r'p1nLsT=ʂvԝɝ3|;@C3#>g;{I=0JMR3OXsco4>Eja_"zTD7Ug~co sq9eh xi]W-.ߙR)9%xTs}1doϊ1 ~ǴiQ`YW=q\W6eJ+C\6Jɘ1 X 'lo% 9p)8HF2>]elՆLf͘k2^3n/%ÕJ]woŦ魩GLŠNB?+8E%/8d7gVjl|>\˝J-=!Bň 68=&^dhr-<3Pf 8%]k>"H*ŋO^Rqqu.nK1Cg);pZI}Ɍ-m-Ȍ by#VV!"ǨPzLMj1N#0Ti/jnza B1VamcZ#>nWaFVA:tig8*d$ R%EMO+=ޞoOSrV'd,: |fo>ʳw\>VMvV^N`w-ž,ܚo[|koEu[2vN)7b0|}cy+T'y.GmKY{A2?q؊y̝. GmCdTƞl>ImTx.&P7k< +ljѪ#`:BӺl)@ ؐstx/Mrdao dLx| Kz/nң[=M"|GtgNsfZY?֩ 6T"/7f56¬ =Ujxei#fοYqs99uqoxrb']dkrFVXWܸ\_|f7g Ʃ &Cɕ[?onlo徭Hn ( qV]t%+eȑL%\F3U#5nEq_ fS95H#c( 1i$T1k=L#E..rO5wj[yWRX猚!`K*ZjgwkOj0cYɃfXh:Y˪]ZįDŽcULy4ZoA&]}an"ro-(x&RF2'˅9"xyqo6d ܠ}O^m-fOZMfoj5mhn򡥛3Vp}D+ƫg75ͧ`"C&*CYH\PF[;^|lPp+%ܸCS[Tñ]<[x͌۱}̃34W\-揿fa:Ҥ.B1f1F:5t'L +x1RI*jeID1&]G0iS9-ƫr?#25g;fL6`%\x Z>{+  ձhzVc[*ۧf{rab ۥixSg`7/Z?Os+{)CNR%.ޔ[z{%Siwo<Q|*ܶ&oݤX/fx0CQ^lX͊V\{ч0߆+/gMo/]Zj[ ͵`/eYe qGgݹf;Z3u)73%/ >߽>M4x9Owebt{hъ]1*79~$> 5N3 n|$^QY؈_eS&, 7ư8ZGgΪ,(Y5(=TuWƧ9KX6&3T"@dht´3u2q5ܠq'; ]}ƋҊ llK0g%"7BTH^FCr*_~@ >B:ZKA+o¿ xڦcUǯrBx@_x=9_q4p-+j弰OZs~ft{9)R1 YA/5%zD~srFEi|.d-%.0IiS$gco9sNK8=1~h5cSWpfkh~xI ?氜+#ȋ<`;YpQ86IImă=3x;vQՃp܅o15q1``}Gce ?*th* xۘVs;K\9ʅ$io/c9P=ӥYI ^䍌C%7]±5ŝlw,0.ʙ z֙O ہjXϑ2Ғ/y;Ru|V㟒RNm@CzT5RT% 'w@лzEk iZA1GxD_,;\Z|Vye^ydӟ8jMh]-8B(Wc^X,%yo>V(ړ=yr'LMSu%'VPkc)TI2o>,n[!* ŵ6\ev=9=iҠvBtf:bڳ +1Fּ_hEN\sۉbsQ̃&b:/ᝫr*Xw;ɸ`=Y/canTKZ[.LE&d> sK O:3։v<\y*ȅ!~b'抍v< c?)ͪoRgnojD.h~WLFT4gnK`.Uw_w<-3j@Y?/$WAt-)"BǴ(|3+FFl>vvi i·fz- @ξ9 9xFݽxϓy3Mx:ۋL(܆/!e;Ɩnز\sMdP^cp=EeOVƿŦxo=s~o4cf8ٚ[h˙VAscKp `۝% 9ߋm=X.c(97\䠄b6+sHm1Ĝ1WAm3Õ~s-f0,8h!+y߀OPʘ1tn^WaӉ(|܈9; o9_ = IEGӪlX֯m^Ȩ+P, Mg׈T 9=evGONnf3vS(t[[ %nz )Up=̛ܲ[&zQs'/uwTm[j#T4[uleHLsniQq_|ҿ( pC/foŹ9_/7wo~jpjvY\tčgNI9?ZxjcWڝ*̃sO%B3 Mμ6ٍ׻sUGNyhO߿]8s 'd[kGpZ#tf|%䁇-xf\j"5+Yn!(5,A:Z5><;r6J<! >alĕc ^ }se:GhѴPћuk#qO,͋E>uJ%& Zs=ay'uYءuU@7y2x=Α?NFڤfMc&mY|kFǚtWdtֿBM;˗lle=+y).΃zREdS W;+~ 5_Oy*;١;vw!ٕ5(v^T:3;i+=WŁvQC.|ґlx{%C6kKs9n5{s63b TlPR ͷ -U2&ǪaH~?xf%Eڡ 5 b=~g@ 'wrM>ޜՋ/yq\ =qՃ:q[n(Fm%%nyP 3TgV >#Ч-yC"u:W} 9ֈb :΀PT)3?blXV_LCYY cY'$)\>fļvCcNn#4)?wM|v<;N $!>ukέ>}_U*UZz}+׿>gո('|8#΅#]RS9|#'TՉc?;o3:1F4ydfkm0)7qENZE;m/KVK-ڼzW߮hq5^_Ubi*WES3SLV!PݏsysRtbλ:7t3^n=ŝ>U~s$Cx UVJ4KdKw;ObG_N.}9vwS3T*NxUip*W/_[k{|0`)Ft]=дU;Fcg4Xa80ߣ/GL(NE(4]kнg0ӝxp'[Vyz; ɭSߙ\wcL*q'\up/Wwa';'nCt#z )sa&\nʍ&-sR ;3*&kQ>Ddf! ђlXGb`~&uz(mL_Cq]2Hj"h5n+g#nQښWQ ٢b4:j@E鐍oq09o{(ԃg>[Ͻs|o6&^)ϺRtPo"cuRH՘G;t> eOIG]2e\n}QkC:cCw6|]({MO8s+]\i;dž YՐ[^9*x1 ӈ?+ f+Lyڒʼ ל;f|_fm5G$znY(9SA^ JTQ \kP|G7V" mGp 4 x^A(|*] MV :zՖcoo}ngx#= \黵pzM onLA_wF5l>ȍ+^ϒfZl8ƀ2{wSlt .Uy^1e3.ymΕ׭ضSaq,8ʶBr-UEni׷*_FV['/+9Ép#zVctJFՇD<[?ڜ2ovMjYR'Y&whTL}* -.9R*B׼O2%08Cbq1: _an*(΅CnocȲc΅s]9ȕN<8Ɖ͍\9PCxqOZ. \JHwOsnp`nXaK.w#^sOltOGӓNZԙy?tx.3TGvKo41eؚ dwhl#>#UJU_jt;?yĊ%w57C՛M8rW{2PKnՅU0΁x'ltcnlԞ{r_1o ~SFϱM$l`jgq>9_ʙLjF쭮 ( kH׉?#;Bgy$DcTR`-,ъSĜY9I>^ вO66o.0T߈qe}vƸyx3Eǰ. ay^|\?֊w2a rRO.t|}ّÍR Wm ߡ[;Qהb<*(ða`Gw} >8$}[J=xIԿnj>OaS\gb] j`csplӤj1T^EYJ= f^ܡǀtiT2TQ(WҠZi.oS_cڇN" ɸ=iyu Z\zS^2[&'ʬWFpYc'dO,pfuSZ·~<, /u%w^w`#Kn28ߑWk ك$\ o{qms怒65>k~_.NVfNbt:8DWr_Yֵ4?bu;U˱=#eλdlRB'4fdc@CC!x8SJ?-;w~d{zU:rNٯm&ْ5y>T5ZnO`PZV{J` #5JNݐ2+e*Ʀxk򑼾5Yh#c|$?]i?בcx| 0UN薍g=be4`2ǿ dnC>Xhϩ}<[qQ ]Y"Ⱥl~)YuPp'nQ #.{}AN2_=1D9l2|܊;],y]K,/X*^;-cguV^I"4qCPf}؛teH_ 6 xqcp#lm^~>ѝepM̳䒎Fy)h.&$(tvȮy]Ԍ~`u\ *dɔkq[wgqB AqFS]ހv|&>˳|PCޜ۝runm>AJj$mgxx0f'n֧|'jϞ{c̈́e&ۀ5Vً;oBca2Zoy kxAqjnιĨ֖e _t3$d;NgW+ X1+c1%2VQi8% Ü20/hkUɖdkIrC~ɈZ,t/朖qKF 4Vm25?g&cGd"Un*< IؘSǺ58%l,OP5B۴h6krG&jˈ:Cz|>ܗҧߨgrׇ=\Hf@g3j 1)QquƺQj{gv̀6rx-9=ϐч`m.)F_չ9W/7@Z{/:O "\)EA'aHVM,ĽX&C;7T-TyPrG Zi&Wk>NkI`o^^Х?5֮NSNrqdtuFn|ja̜Qop=Dv ׯYqAåyVs|5ɈkvP>M\0Ԅ]{[0vxrn;K}Ykɝ5h}CfY`Dgz>[dhE2GawʙaEqO{ fހ uYvj,W]AWGR[>vҦίʑhw^N`h fq qlPeR:n/pz[bGؕ\8ٓM㈅Xƃ\YgGzRVU2GtvKCL81˿sji'fbWkqh[=n:iaּ>ّ 8e7./9ə&cl8-Y/Ș1=pMl\ ;&1zo3pu,^)mWʷ]fr%?Ш֜m*-kfwT̫C,^N8myOR,O_'׸6(ҥ)IR:6HNHJsk{Z` 8 D/@bfj˄NҒҭ8=3κE;o Ovf*|SMVVCfǘ+'0Ŵ'=FyU/c~&?ov_5; c u.YϺr–W933ۍtfPgSu^X 5n>Yp"|ŕqo|6\*@IQٿg2 4J„⏈ 婈JS>`þ;i̐%up+ļym cS7<)z ąn)i[n)}n{;]< |eWw|<4`Z0|92vj͏ʈÞѢV xJnI Ǜ9<˕A-nPE0VfS(;f%c${ve'wfuߐ^+>^[)띳fG{:owNV\I[T^z?=çq*Ah9_9!O^wE8X?Q;#_4*CQ=l6֧x0o0hS8Bc۾Vꩫ'AGaCUNF,Ͻk-1)y0P}? 2Xζu–TYG[2?ʙ]8ғ"lΐ ku*~bj|Y#Hv_H vUo@p،üHRz=工-z?I!qm$MO`9=3{tlu7S8VBs Yۜ{̝Ǔ~.lgIF|dPc@,7,RL{)޶%FqHYQ5xDKi/c'0([;>2` UXy'~~7W[_÷h=9s8!Y阹-bA&@tTO 0*soyj+d9ֿ1#`FQ$ۤk%A!qtj4*͇Pp/v%m_ٵp' tMHu^Z\UT}[$Յ=ع=?ؚf0õ}te|i(u6=!h|^S5ٿPjT"?ΌGm}_ҥ^ ռ"he7UmZ;DkMF. a(,TP~8|Ix$g zA=L<JzIkzE;-#Q3p &й|5=lsuJaz +3}łγ5 7l\I_I?_NFwثWtXW4xH4s`YrP)Hb6EkخLGO$>;A.=8-Ǭ Zw <7/ EۧqCk7Eq[R~-LR4gI%KIOHoeWᚊkjfN/j\}ë?ũ*m =njŠp3aƩ 8`M8`0] &z-h(p=hRWU5B1 QξW58&>kқz4;jT=Cx+c~< ;qQ}{8 rHqpj #.)U%k悊̒ }nǾ2%$c1kߞWF^Ow3IZRe; ]䣣*'UT8޼[+Wi.jI:iI'U, ɹ/`.A lsZ &N0-Ҍ#f1eQ9n6#*yy# [GyY|3?4" c! !-n{FZX>o&,%0G؇LhrL[Q*38\o l:.8&Xj#UX#J`?w $o-ĔUXV#eмԧױr^ОZ8gzz~ftS&if<Ȑ- x3͐ #Ǫ *tk<u @zS" KKHlT uN:76@tk|w.=orR> zfg*0/sV X^azzʗ 9 ^bre#z/5Y.u[ s uqT9A=7Cw?BOG$w6?A当b;X{+f7!,} T_IkQVҡ^pP/ϔ1:d]ZQ{t.juxfXu~_h#sP:>.3N+T68)X(ҥXw\M1썆tj?p                                                                                       mp; oAmwc O0LbFg+T/W6NVI*`O#l-~*}@>p?Š /74K-nK}~b/cx\] _SA^KyOv*UuCQ8B}InyVGxiH*Ho0?x !O'G~{6 :sYRHC^,~MuVR\7ɫWix>k4[ӟngyڹ[.ٯH9qaY\iq$lB-0.hKNgHF;G~Ͼ=鄢Rc#a],.x#o#,nd1t@s_Whsl;t|,iH # lzko"Po=ts$70t*Uxc ^l&h.ǘƬ>OUmT.V>ֳϋ{bNW'CL~ض=""p8Yy@p ع-Yp=U`At#jyƴ02|=.eW9NuJ$W6Kҍ%_,~F iΆ|5T[B2anSFBl64X[柳acdkhoP;aj8E\iFN9b!3ߓ3C[t09-LОUN5hߪk۽ sg!p3YiŽ[s6m8E l΍8X+c TTHUC8ӿVQ{&-IF񺜸Ҙ[Q-G``}k NpYON]+O;Se;_lnF OF7NsiRK?o:q-?*V~b]fFm<_%5Wk; I]hK!Qj0g ܨC[9>FEÈ{V=fs$",[ ls\fjS簋^fy6_|P ߥ[3cZCeE}Sg g ̖KU ^*Lb"SvUgƺp {z2|o 5l9_-d40Hgo#r,m[ ‘K>~)ɴ3zeh\)z\^r߸jPݗp]obl=O";'jam藉 q8X hyϊA=Yrل4KY8{ty_[Tھ_ G^n4fڏ8!4hb-#L9zBRtdQk\ՀoZc9-[s]8 }a ]0*,[7X~OwƫqRG뎁?&0+ f_i&ݗI6ɝ8|zRa\9gl5TcӂZBw,0%o<7vcYʙ/^-WkW>|b+hcs*ѧ w$V>[5eLJn4i#j~ >(uuMNjkɼXGjnնj?5LUfij^j̫ʟr65(;N5sc w6:WƖpK޻kX81L%k,y6 -isN;MHzOrүݒYm2o/S \ߘ>Y k֘G2?m~62369lKG66rbL{Z1*<=ԡP#^fɶ6Ɍ yMl5xa6gq?C'c{6!UH퓄z9ӑ1]ʐJPt" X#W!27Ϊc#~֝o}0\Erʡ7 cșpqUay˒֊?vu_Rb4`]Wp*}} DCAAv%^ZF 4d {m1VuՂO^Z1Ş#+wHG'9cj/Cp^s[{j=]qre&8d12^ZoH\Z~RS5NP}6W ӽiSCg]wFhرC3ԠI2H9Q ]~#k8?Ԇ[<zi=[m~)NTR.=U},DOZ[9ϜRbeb,#FDؼQ})MáWXxNд$ޞqF(d@zŇ6̉-O;2=-i\XTF4g:ε S nnˎ_j202K#OכL3_+YƀIouYRN: 0muE=17EkRr2݆1殼͜XgfXՐ ~1aG9r; /iq-o-r2wىfXъK9ڐCsa9-kU)(Ƨ 864v.3R lo}ϒ<uȿlT`3  .Rq"1k!;w>ˑ'/oYsυL-⫐H6Z}3>rNxځ#7~qU?ǚy{޷/6cɞf,0D#όy\\U.+cEsMLd>l mԩ[U`l.圇\9ԕW6Ñsu Mn8ѸSzcu\XԴ\Sb4|jH 6T;8=0# O 67<*mdP%EA.&˸g6֧c5;r_ gw#vlemXƅZlՐAܵǞ×y5b+?+,RMބ)-L>35x2gAj%B58`5pX'U3䳥f}ČZФ K'*{=Op7gd|>kf.B3czʔ|?E+vc̷`5C;9 5ֺrT7'ɶAvioɋ4-[X-1Z _O 8t|p`ga_xRu(.:k]/SX#,Aj yS1~cKTLs$<}Գbn-s.|=܁l옜N<@] H3fڰܳ$KxhfVV<O3X6<'28#Fo.CUe8t#Ѫ6ΐ,y]':r=-ܕ5Wqwp.х}X֜wHqN:L)aCiN'H5wƀC[߁f˝xh#- 8s#^nښiQk| BFޅ· >/\*QoKmsA末i'5N5e/ MyE:|t3s4/ODLd.+jwj1Ҍ=98W~..\g繛ܠ-vƄm 9M%+z[qa+Xiպ }5M%' FcxSL{*Uoh} 56O|5[e g+%?[ 7.ugDgulɌݕX>?/f\ϮA9{N~N|9qlYOiU0+""bUNtcvRN⾀w#^oeZ V&c&}< YcA&\_Ua"\QU#ݫlj4C?23o1c-;p};[S*pfXG;Un6ߌӂj-طĂeVٚVXkX2/)kzsiq)72pGv}U*ly_KM 4f9/(s~g+Oy73Ԃ;sV+8_r;vVP~n1VeQۙ'}etd²v\1ѕ%=y+݈\T -`ڳ%dSO,X xwWt4şNkʥr|XS}A ^exNw͙ņ=tyå:sȨǔƦ|/ok|`+9R7M9';_`):.0̅~92TZ;Ɍ[0%/eIʹ҂-ؼR;'+6V>35nJ; e=h/Fo Z,j. YyĄ{W سɊR3}ǍSmg KnnḎ!UcR7ƙZgGjuclPY8>*sRN&ֽyiX> }21TD}ϛl+kOş.y{+H۶) EHv=Z[`J狶,or{3.1j" 62dwen:\xnlV륜ܸ;kzrf3G^tsZ+s2枹lɤV`NMiri=MjhE FfR&gjZ\z#+Q[1ZtlNn"$Q|):,l}4ba=dČV&{ž ]wO}rcn5Ǖe[⛊La)4\h:؂U"ٟc}F~t*o|\Wj^^-[j\ǮVA1_vɭK1q kLyMơx?3q2m )vM?'MV|H gW޶z{vn];d7{PZƮ;ٲʑ{9R=XmfSuK=1ތzn5oʈΞY?7ZEaMk~|la5ڈή¥u~7z/{4r0CBFp ZG׺T-A_^j9MX<ԅA.veis7Pf. <Yy½m ٴڎ}ֺcɯ*M\۪q5.CÆ\˘LLmx.cBtzyߺ/S @Ч/K@r>}t$ |ELN"~LM 27e<+s([JMx`#G;=ÁR3_}3W7Z|]G6-P؃-_dkqx9>XUqC47^򌗈? GaB4]4Ō-e"ϒGx`-.Ai\v#snĝ OHHHI\w[5[[;NNr{.{ D?Y8:JL;LYhéQ ́!D>t ,)8XɨxB-m4C q{;VS 7-omi+rN č=9΃p@%b'S/m 'CS$iXQy\<+)vIM],_bSm2-"ռky*ݤbٽ|x|'ZtkOW -#xËݥОIJ[7ߑ=j@FD+Lr[puwA|X |Ëݟ3zcӜP9!,IIf|Š=$ 8[OD5vKҋA*9_}6~f#wވsrH:2 Af8 f9]еw=Ѓ>][9էd,Nޞ6[HL-X{4 ~û+~[mz°snèkT)qHu6|H[Sp 7Xǘ^*ck~*|g9$LӞn3~Z6F 4V0LΥ+l#cr6ix?S<..f )6h/uX.čtSµ8~3S! Rt:O+7Rc'DaZ&\+MC |D Fg*.OBPxb7Sz޴:pj Og/4*A*?yA.ƏEܸ؞お;롤Voᣒ^り'-<ʓǧp1*m d,]"'rmCހe\s⌗#.j?Z9aCPGl /[n Q?zȅĺ p'f uណx-`s&cWxWYnma Y2reR')/tcs&PD?GEZz-qRSQm%7uSJ=4kKTõ?sYlS*ko̙T[B?lOʶb7"屷"}Fcu\듇ןQgI.}LhǞwMaf%}o~z%ؚK4 =T7Lq/c~z:=8uy{|1ʓs[YѤr,L('&cel.|@#v~jiޖ,mΏ)0ݸ8Z3n~jhbT6eh0ɘ>"Zi&g̹HnZ[i(6B wp\5RM-zj8eG:.oNǙ]4RŰ:jVj9/p9<6`nÞH ZęPMH [f| YA۹kc=Ǖ#w)c>{7,xl4(Zq4LOU;`r|e^V|̒j3a@dnW1 }EXT}a6]ˍkرvS=4fZXQnW.Jj"8ߙ+lzBнr?Y֎F:Յ:p/3˪ܢ+=C1V5PatN*mq(0g +.p.ݍ> -zI{b17]wY. !DAsPT77ĞF8A5|tܗGy˗7L3 AJ.;'gqϻyQ|ą_snOZK5?6ᑕ՝dne0#,;K C]O̔V0%yiҢX-5Xk9'0uC뚊q"oh+i5ԂԖ!2ln̉&tM5fN -C1h!vg9 uLɺ<$؇-wό%>+`RK̮ eO@#|́Bc\+O+WFyqq_ TۓjdYL;) {n+isk?Ug F0,?W=ӻDdv5_I uE 8 >@(J~jBI')Nv⛓:rphg\p9Xk!JP[|N*)M>ɕP&5fyy/ n72ˍ-⌙m)֔s[#o '6|#eX2"O┐{C1o*0guH *aéNohɢVlMQUMq "583&:ىa絊z /+=B"Gv_F_0VyqVWn qQbjEy 0r.[7e1/|2C8['L:$D141k6Ꮌ%h*X9Cx#ǰvP,Al)`K͖$1);u6a&45Ye[301 E B*OF'(3՗lZv0l ,bVDUaތ*{v*@ΆNJTpL5gPpl%R- 2ʞgEV̾gLn.ls.t,üZ^CTϺx?P?{jVٌ;ƔHQc,<ČC5?ffk\{PiDUe bVT"9w}W[,u><꬚*}zv'Z(qv/\pA>r2jŤ,3v1M̔EO6}+QH ^ X1 p?lq#cHYyݕŢl4wް{oni^mhbMG$\#_R> ˻$JSVݲg3T2p+bP9/`}["]TljY./\Ul~қ9AK{rr-C҃ ia>$~~g ŁvIy5!6s (1 Mf,,5'm93wЭ\ ێ;*ʰmr&y <Ñ[eI6޿ Mz1^VB__+ټ/Y9Hc; XƤ^-djRyU s1noum(zjZ6>fXs4]Q L!rk?Q Vl1ˆ6ׁQ3.LLƉcػgapÐ1/g`5[8^}+T֝۝lLG! %/#$Li`uH%ven38 S[e gY B@H`cjZ(Fw!ҪdeE77: w嫿X~1ps*6.@5= .QMpģ%>#W<8n4+ }OS~FP!d2݃6b 3栽qM8s|;ڛZ{pw_7^r*VTÍ \zW6ٵug=7idke>|χ x3w ^<9Nt"*{C54xq 6RP˄,YdI+ LOS19:at^rwqtwu: vd{.Rws/ Y\w؋Լ5^<5R)*ޝft3bV`5l8M?f*vzfGA/ҮaԌXeC=r 55]{,b2 b=k L{p.)`82檜2ly4/I}X:66rSs~` J<5l8eᒜC(2a1gKKp֋RkWĎ+͸ Lxg mb>.gU#G9#‹1\q\AiggiKZN쪦d.&بHũa2淔q;x3>a;7mP73Z1uƵ?}\r.G+ xu> ! %noA]wʔoh]; 6)+жpK^FE07SEa8w~ ?C"Ҟ^h1ݓϹaGV ]-Dpj:ڮ 5철6'bw5J=|yFϨ{^Ө[˺/?]fE6ak 3^#cŁ9F<{E88Y}] ƌU5{#S0"da`Q5ctRhTfނ(2 sVSuYt̕qs7ExL$[ W )GƜt}Շ}|1DUbe%wcy}iU526CE7@j8CJj(䈷.(4\+]#7AR#m>6ȃ?96 ':Gd4u(@ 2a ֲ> z)}z}w\r_zk|*dYj/H-o;/K HGaqX:=]&fcc!?؂vԝő"ag6A~ToeM7EַfO7iK~s(ꅾ2d E8~-FNf9&dn3yeF}Gsb͞.Hy+`L'K}x[ ^w^TKAJ6CpS{y[K=cGm djm$*j)€Ƭ^!?ϟW'f'SU DD}-u9F` X-F}w:N!%.CPyDec]7TH1Ed%͔[nA4·nM<oM;oiOq|]^Elg9{i;L{b5G /,\alZ,b~3kT=y:DǦ|&G-o(8ox25юW`?랍{\\[)f<KvzgǪ je,ճCnck5*ǓRE8Ow`K%?hp\O<il Ol^aL7KaT= BO. a&' 7J\a~~^r;S=ųk]OIy2=#ش8MR0Z"$kh:(B<ޜ JÄe!pNizV>0o(4Rv??,?_F4y[pWͲ|mT5R\{!R|Sau4q-W^/uT2\WJ*n(>ner5K+QΡaJSJMԬZɱUj$c#ص-'7eE;Ses MNRnq◫RN('.ږl>˘fGm0m&$pBQ3Q+Ki&,Βx-նѝ.{"tGM씈b#lZ&)ōyfm|+0vq>);I sٿi/=:h_lݞtW=tQ:1wVc>#<\ˇ* SQQ>B,;uVrk=gm-%OesNTowcv d2vQ3œg:Z[:MR -jozrjaײHjĿgZb-\vd+;>@tv*ȑ(eq|cΠ* ^ s]b4SqscmӡQ/MAȥz0|5򮵎F~ cDQ9d []: \vkqP10]>Ex%F̕8ɂ%~'wdzEco=mYoYqzPFTbџHWW"{s'aykkl qC'%&ӆ֎YǕ,LNF #;V3*Ñ\94Dn͔ʓSv/-_*7B~VpTWGnjK)u'}rf}UUXIJwoSg/lދL\y3ˑO9]Ki)`33$g>N'eL=#uep}Q k8.~fzcMcG.ĺk3 qaΌBؓ}^Wō|2™ۅI]U\] |2avtHq2J=TlZ:˗۩uq<)NSW6VCנU+iN+8͛l]˒C\ 1:# U ^' soVtv/nzRJp ܉{y۰7Cٷc-;>{oX> UhjE -\]a%r.![ ̓sJɢjUrQ'%}"L}YO:F gO˘W6߼m3w*y~kDϜʑq`}%vx0@ÒjN3֋CYGΘ0/:r~[9/*&'Y3V[@)CBz-5 >2߳ oRp=Fq{3{ WYwNlzՕ/Yϓ}{Ӑ5۞WVMo1M>Y:Ċz[rKC;.)/=rfa-L+oXsüh`06i\Ff(:T!P2)\طĜΔcy\QLJhA\~ȓgqƢzy7nC[?޵6y OAHa̝2'w90 Ƈ̈ gZ/[-o ]B=PsD7UqrԌ8vZW\ǁ: ;͐(y+UK~L e:m'cz%2@F*Tx_}$FJ:U1*U+<'dl=v q 0ci>Dj/ѵc M)_}ִ{Ⱦȴa1s>sH+7su d}km]̇GޫT#Լ%tQ/zɔ\"gEVBg|W;d\/] [Z.8qKd`ψVݡhs Pv0^L&W =eDIxͽOvI_xip2~YGLپgj8rӅ~cQ?lG:6( d* ұȵE%O|9lpP ^YA{l֪W#[pNd<٢bC5C^y䥒d/d.?ҍvchW!׼jgO+H:Ξ)n&Oa8&ٰB)g ar*MCT\YA=נf, rzX*i!xCn_VqZ 6j*J i@G^˶Z>xER$AktK9mHe ns** z>K/AO ݡ%'3@yNWQ^E]5?F٩i7p;.ݣͨ`AM;|e# 6WW"e%i|rÆVu? Mg"mp&r&,Oo@5 vsae/9]qԏME:7ǗZi3\ϔz*NjxM,˱|tZKQ!MЅLFwϗqRf )Ds[f:{S{*-#̈́Ï/8$]' CZ'l{KAx=]`/ 'vi?!peCE!N<,f'ٲ)昐iՌRfKn~ZЪԆK7Ϙe[USܬ >N]0eP=]=k'9}ߪ& g[9S?y 4+a9n/qjh&l§!B0TOfZPq5ű[oV e3Y'}(z+݆&L2bZ1Tվ2(BHޔk |-By)3E0\1p-Oۺ1wU.jqX_Տj5]g:l1[BmӂolJN}b>>o5c`TgsՈ{󋽜x+R^jB)U|0C'wȿ/nv?qx 1!y{@x3ގWOcFxI7È#luyVd j\KQ匹'cnXݝNUXtzqm0CK$DvmÛ_P\8DxWmGs 5T1Q*vUyqN [ֹocI17h^c3d$Qwj_a0\ qfd>Re[0j~zPl6L*ڔu#,[Í95Ԅs*0Έ^F\mac:7ĽxSRڌ'Zv<?6cbEw`3w1>\ӑ7'_{BQr\n ]8{L7uf:ogy)k{q))>& Aٍa#yqvj$ٰ_e1 ..q7g.Q**ڷPP1]Ɣ>›!䓘x$v }n KNQh,X%n>p {˗Vi{ŗYzM|~)C%2}M c&ȸu(έۂ1)Lua\?!>6A͋0=ƕŎT oSj/uUΛ15n =Fxrf)-ŠDԄk.pX1ˆa*q_TmHx/21GX28ݑVZ?n$$L@o_Eo8K ݔ {_b7v &b'bba bwwD@@QT R=yf`}:{UvzG"njp.N2qEgX7N\m~h5-Gڜ/tOJk!Z73\q %`H&4u{7pmkp+d]ǪibQ,MV&RazS@(*Ҏ!7?J$?؈ZtRc;F.7nHmD:µ]fFyp=YvR\:WO-Khrnr3*Ņ2 ٦¥̺j<g0! 02Ѐ&@m LnX\!LքסZAΖx"_K )3hE`9nF+Qɿ3͝M+ib-:dF6xa@Ou@z [|£|FųN%QRH1}a ֬Ckz~ (NoI"jY@rBOgaYr.=wmL.@e%4TQAWө*ؗEOgLJkN_)|gn~6h_b){ 4] 5[@aG,Йo…4AX;-2sLjgv&$2@#f$P:tz}z-7ѡtDV™Ep0lJn'hTȵ8NC,G_GTl=.C6jTB4Vr "0yze_L*0gr7w`7ȓLx~w)5Xpix 9B{5ڬgSb3 eKӅ4l+s9i"h^aF7 ?[xt_1B! iGeϥVTj^}hVs4CZbHl y&v~Ȣ?h4@,ɥmyqG>jVH3 >]+O[Ҝ kb[\^T Uqg|"O/h)W~B*XBy]VI+(jJUQ9RI]PY;,!=܊2a:7`G;#4j=cc7I>(>Eҥ[)>N=@g҇(`U}ݧghvAķ!᷈>{M'㐡4*x5A S *9}u~\v5śMh߲&H|dw[#'׫ѣ,09̋ȩu6=NO){FyB oͤDr,яRۧ(]VҤ0 F{n /y\("rm3yopO3ےp޽,9f-SaK# ]PBY֘\GmQA:23>bjעfn 7>fBF bı#Ob\&=%wAA"~giKں&Q=!$3\PNslσG),` 3? &Ll8ºe2`{0^|uƑlH!K9d `5q8xwC[|gv te\q]zqd3?kB5وWl#4rc.Յ=q%FN)%FhDuD[>KBz^cp=ix:lߣ#h1y:4>1=IfKu+P=VY`Xg^q:[4g!K]q:ue[CD)Y#r㳅lCӅyp= iK,=Ƒ rvW C(K>39ݔ^#B /zf7ݢt DYFgiFthTvV9;UmQWYM/Ғ!%2< Ԥ,s,up:`@[C*u5f1֯Hս} #=6ȸăK*8C= eJmW…tNmSP4She*d8U₉%.K2=b%FP^l(05ׂ]XbJiF놉Mݱ,'Y.V8v/-rlUNOؠhG!bdK]ECUX!Kѯ:01S߿9\_A}LNf@#_СIQx60? zk"-2C;sZi$=Ŷtlo yHI{}(e75Buӫ-hTns8}qf`h#x>VFL6bt5ynՈY g&\$rŲ,)Q>>f[happ|$y\do]=M5tt۾}^)fp<EXas%[=j#5€&/5wD5C,/3!az7 F<⤟~.f6#1Zi&wCYu8ĀEFQΰ-)Fppo#LNp7 .lN8b%`YY=+rhWO3mP"U;aW?L8oPc [LƿvԀ ();=0R-:5Wpwmu7F@bZH%7n%1qgah]ݞط[dz-ш/d#MsW.ZL'bfP\qτûx0 ы=i0,b`zϪuBc _I@B1IDH}"yC0­T爒[l @BvL mDB۾> s+tfzRRbfxbJFV#{8#!^y݀@}N:x ώ(Fj=>35Ӏ3 >CQz aq]fz=\'P<78bk robpA"y!l.R;KpKa['fF^xt&_/#io&K$qDZrgcSM9k$3\P#?; 9xu/ Ӧi0)Ő|Zԍ<5CԬw]9Bi% O-VAjjDKEƘd:0rq^^HtG vF\6+V{w\ G!cMf2s7uC#ˍ@{xXu(9k@Ns^D9F9\%=W9!oY˿hQlo=xmtJzbc#]=Y3ٷP [ bs"W66BZcFxN]58*2tk0UuZK\^H )}`%Zӂ&'8|eka-l/9`mWs5V;3[$Y:@7jdp =ozr6JOk_vܓ#CUJ=@ǵL_Z52Kw5KQ -EJDk;P [ u? Ȱ+vcXgX\JZ>w[B /ѝquRޒӞY\1o3pocwmQuz]/ֹ4*u^]@!AT~'O!}ˡjo+HxשQ@Fd6a.a3++?UDjD٪5NL݇ihaZ1l3o#bi8'<'\!Ł06GXbSK|aFzS)q!zk27KP(/˧/m~]eҎ(Nj׏ vmYl> .Oؘ8}p3joP+0Nj\ eXoEYHq# ].[/5;Ziz=ad5޶CNL&IDf̞T's F5tۭ5vV~)抡R40b[+.XFRW!\l4DS/ ͺHyUݒ xH&M>G GLKt“.pB`5~mX#ί MkUbM+V~ogZi>Q*+^VSU0%) 3N{D8pOOo'CLc1ӀvV:\Ǯz$3(FspB,Z0Ka .Ey`a^G& BƑV:Vp%Br=%ZL>Ż\OVK"[J.H-!wގ7b@6[:*QZ2)2|7}Ƙ%dYuwϽ >=IӸ/SsUgy4| UL-B\(ӁCOh tBK)ݬ5nwĆ~B\0xV@[NC~5zW#W0>Ywi UǥQ_"Ny4=A /P"LDr4yFp :4bqg_dX˅$@?NNqw;jEH9B\52Z!YPC}T}%Mi,ag8lަ[ɝ;>j@#2QaT2J_Fg ove|\x29D"S 8\B팢dJ;b[ @TGG툃|A uKW9TzPAr n!J{fR@H WbU #gH#-}=X+čN˅ab-~۰z5\Vhޢ*ݡR< yr&zi{[sy{*sEP«Z7PK[!<6XxL1c'}r6MC!?eTl&xpvW"Bτ V H)$Õ*hqVx,T頂-|Js .֋*)NWJ4gt:SqټU洫-Z9-~)մw ,”$k.lgq"ě* g\BI]X9ҢTXcRWTR-Zh ߻a{-SM Ve7X}W?=Sa J*Y%6!/` ƸbS5f~SOԿ#jKxO$h0\ ="8LL>, ΉЂ:=dJ mV#CߔGhԓ{yuT:mg 5_EyXq1'Rv:;'8$ +hĘd( .*aO VXAfH @gtIq;@b]#¥8|Fćߔ3Z{cX^gS_T2*)O\^Ku| -9Nbpldp/As_:;`6̣AwQƻ7|uWgM9ӸiTxiItTЉF ⱱ-B/s3:п7+rQ2{,%I 9|~c,m(^GҎz<'$A糲"|kG"d ]E[PX9á zu K0a oR:\sM./V)faxy Ӈp_&Fq1ܬ8:V˧2|Άp%ZZZAUMWx~XGRZ |) +^[Fl[&ZGE;UQ c:)cPɱ'CDuIUXP: ]iB!/[ Iet{0̹" t!F3=:G[!C%g[2e<4F݊Tb֦~)S OŝH'xJ Dtzq%9~#n⿙j@m}T+.s"o[<*[B>RXIK.TlmQ_X_jp-YH *>%;|.+4 \dQj'@P)@7F馄ˮxdm|)XA4ZpĨ+A .`:Kr;Ì1tpg6^`#kh;Zbjz:>NzHҪ"&j-1|1мƛx9YW, @;Ae,v _drb-v(0!YZkAU\0a |͓Ts{hi'y>^}}D$\@d- Q.~6K%5Y\BSfS4'xM~ѸՔ(f03uYEJ)3#:qHO$a}+&ɲiaT>VCe-|"҉D7'#i+~Z!Fa{!\Tj@ rH>h/dwi& .ReJ9Nar#aA._SkGZ .v-$g[ھ5]_NGwжp l\`AwDr[޵ŇܒD+hQA$+p^LN304WV! lScV q+ * :HAgTүEcʐ4(:@2,1L " Υ|d.E9*Y04P)le1Kqtht^MVhL;td!kA UMcP迟i~sq ѿАrJVC\~%VͦSM~ t3~K^OJ]?4z23V&ӈt9%G]7<ڒVB6G8+ƗW VA3,#e/x \F!R㧯5g;+Rι`v-&^tş\i=dBsg(-_\lCCju_ۖpJk!9ao9r![ 1~a 4MG+sޓ[2eZhA}dqq.=9WE^]jeF,%Q@TB~SΔTs_$~n~4{N,mn"N4)i/59q FϮgKB>U+#A%_ѥOH+-~XD׼)Y"㻑a;&S< |8_eR8!(1HO _i |OU ]{5H0KKR;!CƋ c% G;Ba\9"ojQzMu6P}Ne?L9AS0-x@F9"!Db,<.A"13Y ܁J|P"q-oȰ]! _q3Lj!$C@\ iZ8*.F'&ޔA_)G:Sq=C+__w])=cA+\kĝ\8`(;L{³[e&7)78_Υ ߾np$PpX$ޕ8>/Reɱ-iWS~V<{MM)(j2z bw0|m!ڮJ|mc*/U" VRdft|rƖ0`G vzyX F4sVJ'.pR;ZA9P{|Ts0j##7?j\ǘ>i2SAAYr!%dM`z$0K"'g2I[!TA6#QNo =JKSG1e @{ k6&dEO`Hg+:Ũcg8Sċ|Bi/Pߴ0+ R{GDnѭh::bۄW%/ҺK|]/4q M5P:%ijKg^XZaJ[Lc/=xIݛܧ-hqj&?s|zdрR>/r'3}IZ?uAYx.8Oʑb8k:;8"$8F\5۠Sq:tXj{˨럜a;ao/.0/[QQEN^b-f,f`{k>HE-;󌓎Z/iMjdUm9Oi5̞t\)d%j޸G1_ֳ%]#4lUUC.\w`ɟU+#M8Ƅ㬌ZZKuv.WN%=1ff,yoΰ SJFE3(2Oo}MCx&9%w܌I褅ОPyO;Ϯ%|XP j9Pf`9'v5zK(#ZݢD)7,N\Pka"jUL : г0/~ÜN_fA 4Pw\tM{ 4|΂݊u9NǑ:N*~٦kO{~j4O{IrC;Wk{φχX` 5ְx򕬟㷆l'hN˗Q9;*Pxq7\NT3),oH hbZ[Xdcu:3`46sXc _ O}sz'-yg &㠦2qV33im{Bq3t m˒t!}SCq%z Yx#W!`~uuVu)ʔv5 mKl+{eD5zoϗ*x#uJGvc :t-8cW[S +*Z(L`qł>ղ;G`|9ˆH亹ޘ*D, ]fj/#m CGjoeQg-̴`0h=3fsaDGZq㖯.,RoTC^~4M*_T8xH/ |UWKP57ES<G@_v/jz S0W#`x< مVBY6* S>W^6co&X @Xw{6trKzV|ѢV9/?8S%(]"#;. Y1}*jĻU7%zc:j-3P[ا=]+=_$Yrg+6mAR߬S󵿎[4a0 ?q#.1[f:SWs gFG8aKZh3Gx%U 3dzz?-8JGkum aR[ҁBo*ifR-*5[<z>,^{6¹k٧=ų0Ǚ X؅Mq;iSh/:5,bbSLw3ʘvČr#~a?p.̓ѹ^ f5CNh˳L!֥`e\4T"1pC2O+߳|]vA90qWT'bҬϨO!yʯulj%X7uY8jlLy Zn_+43GUIFvEVOA=_J@,\TCysM"S EX=?w*Q7[c1Hxnul`bvs^ ]JJjlWs|wWGsN+^;u z ;sE$V]:= MP75 = ,9ym;g}6upKDW8p΄.vReR/lx?[)x]`Jx%/U+-񺏁{l.‰]ء́ #Yl G.V1!<CQYi}FD'8$ -ݸ4;@+mbҒQ'-7)7wiNis_=ߣ 1?} X/FjmTCuϕ ȇ]"J?_!V&A7SjpĔ{(CXxM̫zC(a0ߐVl9.]!">y*z4)זL WWUYdSm_ i"7N r+eWxv=H3zkI/500n>g(+d|~ʄBzi<߫1ȹ1Fæ p0-C9e?^5E#U>ĒrgVMuw gbg6p"=*@?=CZѽڂ4te<0AŴpC#in;+~.?` /R ?ħypM w_#E<7"Mq) bqkcDƬ!8%/F"Ѥ2 }60?|KW|&g΁"Ɠp΅\UyG݆^k#ޑn%>5/ '*q9Xڄe)&̺aʑ 1oH },SZ+8RǝϬEj92ノF/ɃjL!M¾P`*co+Z2_([ëȷ*:8ӯIcBC kFO:nF@S| gCu7{{5m2L5zxڟeo#⒉B/gpUȦݘƁ۩hlk̕'~X]>;RC!VKe%GNbU!q#\45Mf$rU. K`[:GDʄH[0pH``˱:XZp\ td{fO9|qwzQ81鏢t|~j.ܚgcD,>iO~"Ahqan<8cX\ Ųq3;B {y 1CZy{eyᒏMSY_Ok瘎ܶxqNG޴*\;(-vرڂRxYqV?3͖g<0\ޣYH1Wv)EFr|-?읂[W횎]X/ynC*'F_ B6݊h ,Јoh` gmBx*odU>&,e.Rl^U ~EDkS>s݇W_Ū ^0bŇotWʻCF>GOXn,Cn%j`ƔKf9 Je7, R^jƏ|p܆ 'ղՄ{ۧ!; ^hoeҹ8,k{&a|t)3*Yg*߂<.U+;+V.j:kL'߯q:gv;*sn3u G:qEV8ILeZؿ[Cw+lC9Gd2M9?]`Zx S`YM|;xg1MsO@Axz.ǂLׄ=Ub/ SQ9ѡ^<s{4s ='RqSP jmQ#%q7;?=* ae[w[h}l\!GnRDq2 s~ܬxi K/֥|>H^#z\Һ!6J{Ns V8~;_=3:ؗp[+s5_o1b4?C`aK<,/B׊ܺ;^3tnWtf_.cbp'*~[Ӿa_92v,cjޭcK}-+ݜOIYa̿ըQѽK0uw"%K߫p%#ebN#C$l>O߫j&=_]`9y"a|.ʐ 񉘰SiSpw<^1 sGs:Tg6}jL.^fc8O0U*$"v2EMZ/U'1N /}R`mxKlQqF)F1/1gcf":1Qv ʐϓ*sP*dl`\!gSnH^km8;LGub]2 a^j7`x_Ÿ́fT MNDždvKƁt<v? CD_xmYiߗyBfrF6pu5 .OZqx.cNt[_B 5/C#/D˱!>aQ3G󰡷S>c3虬Bp9gFb$lݘ =Ű3fc#k&9s&4Tjٳ%y㩆w(9Bԝf\&ω:eϪsz$ƌW+؊(g2Ё9qH9_i K6v4O^x@}>4kun[ <'-F#yܳ!:k{~= -F2a8=:Ǒ}G=/ZFf!};; 1HC3Q.fN,LiG)Kʟf ^U.J]s-߸nM7LYvOE4EA(L\1(+* <[VwK)S01[,}zX` |9cp|o18m6 ɀK,f_}Nbsz&RuԻ͏>wEOXs*q^ѻ._ulx1xK;;!u O"c!bW$z]577`R3|}yOxw܍]ԕ0ϙ[0V*#s խ?)꧊)sՑJz.8o7HD睿z${._|B^"Q_]$Iccje8cZ/ :Ե%JfPPsʇo4J5|+v z~URwsh>#U^`n-WO00†l/a`i-7,4t#KFXpPfT9CJ=cqy=D=(x T,"Gjn+f%3f((ܖ~[$cb)0~_oaCrf'֥s=pˎ겹-wV4=(e[9ߌ'.b0̙s;]_ى6)p {aA?o.Kag'̘L/AMO1q ÝSZwW>;]É&fz [̓KOMY*ZIZ*);VI:5Cv[iK>8_H ^߻cE`lX6K"lf$GτZ+=/u8ޒ;YLe=Ґ>FBz\Qt !<iQ>7#ot:9f\0WÂ7iTGv FjTsALٺҘ)v漰[ĿR#/#)761*CY :S/н^tsc.:J1ױI5'Sszgw1 R6&!R x%'(we'7v;&كycya=Ϸf@Kr=r=;9 iv]7(agƔaXnOHW\%}"VMHGLN1Eq:וyp3w^n#.Lp|+`g1fӥ/s4*SY/a\DD\YG"#j#S8@i  ߅<2F94rj>ճ0<}7бV)@♅a/ALd47} W54yO|^> 8ND}2Q?I9~*d , nE2Z#*W ޗTF1K#q$&\z8a'<|N1O ̑ޖZ&9=t {=_rb܊:L1g]vV[y2`{oF%Wc=ZQ2_;hnXr'vV7XgNOF~^ERQg;S˙SπlyڍOkgȃtTuK,6)9e;I)uS2PGKI9=f€TXoƷď)B} B_Q3cb%j7k쵠>( LD?5~}bޘ>a>:9{G3_=sGZ&‡u1^<[լ,tMUC2zѳoq>zFa/Xy*~Gtx,ĀRZõِpAT,i-RD7[΁u\sՖy\]x!\J_rAi;Г)xO_7ċ|vLF)vbfus6S;Tb{\'ۡO}0wnUoccTE ;CڡjѸ9H]U*K|bx헹pf7t9 ":m7QbPKʵY&a~_)x3;[/[|ҼN+sO z慣7Kœx9,Q`Ϗb'lӂM4HiȔuTR1e|aeCۮfHs'#񚎅g' ⱮẅD/߱36apQ]_%&g~y3c 0X~WOwW#ϔ{ʹꞞkZZT[U3!QYnjB,rϡ:,Z1؝{ ;|6-kԜYa ^>*t sNI6r1R[,;1rF 1LM[7 X݈ ܳ2LH8O4lZ׬(_fǷhmX3c_yؔ՟Lyg$PoZ [7pjz9;/a4e׷Mfe9B~w5`w>(,L{eسބ b81Pӭ jhdP7n&fGYG͞kH)I[`T,TH^&aǍ \g._qx6{Ǐqߤ-_yvf/2f\ƘKG訛m=e!]penÚ lmܞC8ɬ.dM|ɎXFo ݟ)V)Or52BĀJ36=]ڌ18 Fm.h^`c%Rc565":r"9*@6tx`3fJ`=cFb :iE]Qm4hhX̚ox/̍7X'SF{Fweszw>Yo=KYE}-Ĵ=#aP#|œML׌ĦxoKEuK'CkT)1̡Z$u0ci69wSB( ] *e`^+k~fܱlxˊj>X(2~XG7Ma#:ϼtZ'ad, | p*T)bX wgG(BURa\'-xf?󑧉~!z%9Θ}qh'RY9lhh_oqE*8񁟜(xk:x󎊉cVLM >٣dp9_|Symdfwg+\*/W;eSU|Z`0shN㽮f\.beacVLkbkpm"]=`BȁG1',Hs(83_;WEh0bV# \mcM)_5'94[ru/KdŗŖL|⵩b^v2rvy,]#XP҈4uC}XX6 wpt"3Zq4b}JZ#1wR ɂ3nrj4S!,9_ǎ'`v A~P|| .GFxVC1o7cIJλnV9%VMb=8㠁X2[a[ f !:%qؚ(i(O)h8/S6!QHkmw-M86PX5f]|S?Q^nǖ*A[;Ǚ3Uv>c/*[lb԰xHFV4mJB9xO9Sb‡O1&\ #Ϩpo)Xy֌J1wr%w(%LQu2gjk1nZodG¤xs]dA+:;rƉNv؅!ݨ|β|?{ {BaCm)1KΕޝX$(zcÊϸ ]bfk:.!/Zx 'i=UԧFpkALya1J.$z uǾ͟XuYVΉ6 'XlQ?E !cf`R\OK:n U?0v< smGx3{WsjwwV;=Z2.Vђj,-.mu-Z9 ~s:uBaZz|E5g)puS"iI&b|k)Wsfow{:zqW+kR#EwH`s&\̈́CMi،͙Ҕ)( Mĺ5c`FHޙgة "#n =C@ ~C |gK3P2<4f?c>1?JhH/?cŁmyօ:{An\TυUNx@D*xA2Fc+-'1&NŦ9Uɨ~j:V7k=oTjW Et|=P˵Wm'fwgcLN8 7ÙM牽RG|||!f&C%vhWE-4.<cai}s7p-?k,0teEFڱ֗nhBC'gˡfDmxu {q{OZ/Zg^ 9Yj^iRc~mf'M;ݔޙqjYZ{ &qmn0 /O~%Ղキ^b,SbHq4zf`RwQ%\~ӎR͌wyMD+%ZĔ0O"+܅=)~s"7bD,bU[Wai9\g+qt1MC_m.|wЖG, ,e}g  iFZXG/wzpwj5MkCn>A]^%Eܲ˘F7ZҘgqIK}oxEa:s&Lޭg#_>ugw'Wv7Np`!'Xq3&#ιǯ'h;cʱ, [E v`ܘ7YCc |`EP[x©=8 Ӌ' -cMElS eI ߻|qww!nD'@Us3ç j]to7O?e"%2 mNcCO~F en+F }gڴ7 Ѳ`^1n ~T1Z-ô% a3 -FNtV>M Q߸:axࣸ9g_ Lm376TCzFsP >a& 9ΕQL oR/ZnU5m]t{s^_.cnn+41}ʨqH' ,>Iv]qA^{3qme16ՠ)9ˆcx+%V.)m)gTYc7Gdi_9 =k.9- :X]|Q[-OOֻ0&wd.USW~dǖ0ݚcU5%8p,8lHXw#p~Q(Y>FRktlEp.6|237|ŏ_,&ё(w' c|cLvÝ鉨?-^=<gcL#Z0.Frm>װ_y ;aT:bOX}Ax; ֟Qު?fy7\ -\ ZeإU(>hTCdvaz;KtLǗ%,sDC2w{%SM,IJJ\:AGӗ3@qb6Ç}G³$,^#qN8Ƅ{E`I"$cZb͵X3RB JX#iB ?H%XOWtǞ*cק*jxQ? clo!pV,͡ڄנzU- .TpA caˈ$c|9]CW&:S B_kogѬ)zVk~{h.V+„$@Ѻ]ڜ nTcmh~ tLW!Gn[*o1p[>I|[]KŬt1ꖔ>7cB`Cb}ZLY[[=xc%<ڛYDhW4of/=>L%}Ug6Zl)lQ gR.W?`^Gn*˒sH̟L-Gߑ== X[ˆah 8;7}g/3Eg,-Lɺܼ# m>U}iC{^T#t|sq{[>>F+zbĀ)̘;̆o8--vQ;{j%u:?ߪE ̗|Ԫ[O3zs R<[O_Jw 2{3m6ۊ/8M'c Y"aнQpo;*9߆#f*LΑ!,2n/ l.6^^ʦDŽ\zǚOʋ¾(T`sy#MhLZ?"d?r SD 乊}qn^~`/syJ=c!@\| kK&8ecøK,8#MyrLz)͚J던>ʉ;YL1lz/t>3K3쓅h' ^]5 49j665#g~r~ ?5fF?՘[QɟU<>Cʖ"Z|p zʟ6%*(Ǔq8?2o7G<l|&M^{f{0cW.I7Rc/;vc4Ѡ۹BxY@5îTڌXXF1KO^%h}b|!!{Z_qd#/;t֖<ْYp)c1f_#8WB-+:5hdΏ?{&*EfdҾzº<`-|CƧ1so9+Wy**|{Fe /2c„y[(e>(Hż!R؋⃔ǚJ1ח:O$|X*kpW#A٘'6LהOMx J$ait\I'qrFV~4dT[?jz![M6ޮziudJ1C{J{F̹+ea$aYp:XYvwa=0N@ܸ4 fD+Lx әxWZX)gdj,4p';Pˊrl.٘ Ăk]^mq0n5ƟNģrv|Exlj|H,ƈB>(2a7aM1! mA+0+l[ mm; Eo hIؽ}UYnJڦtm+,UpSNrΉxG1L16Ӌ9 ^ik\b}#X3ӏ%u? g Sh]T4^܈s(H]Meزߝ ʒ0ꄜdR})彖RNl;90~}CY < J OS Gp mIH{b`; f!/M6{€a,].CcV Sy~>q&RdTpO!V$ K+>L^`_ uiǫ I2c|O6QM;l)wqٮg:*(^}:WZ2~+a9 N:܈JzX7^~Urp?57|7Uʋ^4 a:;F{0ڜձΞ%.(51&4~t6FobH89wj+SO= sK!8qB7n{󎳔ۓT29IY))"`t82Չ'9 9[T놡/0Bǟ~yHT7s%hK,|ºW%4 z"S'MЅ oF~^QI5"`S5+ѡ&&c/Lu*s7c?"x>HluW^ІvwlFOoT2.-cn?ݏ->qn?9sW/eZ_6~Um)A,$EWdӊPz "h5ޏO|̾d9tAGB<kȘ~̇/3^^qX6v >6cg:u5|!XoVl$jaSŜkʗk=3D2}JU|L΃&J>_$eR<.I^ %>KMh1mGyFxrM#tdwne\u+kݒf\XsI8SphNZGT".^^4){_+3wMp}Z 4  ڐ_,T,uP/Kiؽ߷e g P;JE6AgP4^D)Х;WQD1ymQ#v!w9 =RC GUkMRvi#cah%GAw1MӰSE|ٗ4A/qUV`xz^-c- j֡*:ښEfh^Bg]r̝jstb utghwsvg7ֳN6tGnVL||qgD@SPckݹ,؝='w[zr)޸ 2񇻔3{ɸC`RK&+):x1/gD!wq>{#*,tG8s7ݓV;҅Br rk7du63>uӄ۫u忴9ɫ%ɸYs10HYm=7\篁2NjusND) c3`E?!σklGr_.ᨕVrh̟&xПvr)cw]_x9L9"OUpgTS.cп5ϖ2ÞC8ie5,wBwa.zUW1Y+sSnfK˂X sS}亘6Rpp(  z0]k""X!T̿IR,㪦BCxOdof`Ozr4N9*'7'{+A Ǚ:q2^-{1ci M`)}X=1 Tq+(k}՘ګk5/h.|@mNZʶ㘏wBFT|!GLCwZǪތOP#fG!?otSpL_>gJ>,6RTʸ>GɂizTB_un<Oo;wS)ڬ5bM5Slցl6R Lë`( {q8 ?JLNjsf=A."gKqeޜϗǏH8᎜?DxZ%a%t]*r?sg+1ޒ1ai<'Ymdz"š.t)R8*ǎOM&|IځYߩb֜Lh$T}(mzk- }so6+B\C:s1c$ܙ$g/6Rp$9xhO}Szl)&+9]+9&7E6Iw۞o]Nהkm62`DChS,T+zIlpP-~DxQ7 BpvSľq-Ŭi7\tA]"NnՈ=hW~ݘRE 1\p7x7t!l2̝NhyBϟ=̊#)ՊԶNN<ԆxТ_PtWbI-^#ڰ:=Toʌl[#EVڶ+"W\AFik6ԯq^V >=%Dxa5uoNTTLƒXѶ4g2P'Yp'`@\f OeXa[%8UQ_ UyHPc ^b, o1/,HGq?,?y3Rc<›-ܑ x*VL%4M,_#v{ gt1b FxA6fD)5IW 9/ʐ׃ׂW Əe,dcʱO"&\zK}`ݯck/[xwΙo}j?Ǥ8ҮV୩6Gl5~qjut_2n#"1~O_l!xFCMzɁ{=2vg.:ͥyC*X0Öl;ۇF,.oro&>&.<*`|c_k.OtQɗ/\)m_V|H]bqgW&[4TŽn} g4];~ 7$:|::%CwqzLvy*DFU>/6{N/lbP5G=ϗt, ӠzYԃ_򭝄s$vR 纰2Đb)Ι(NBt [bϥHȅ~;"]$9|ëV %:?U WbsTFT5qep/sN ,yW ykKkwR0* Q8/s9e_15ӄѯ-[ǘ?7֠{:2!è ct Ȏ0~)1{e79w&2'ϔh@>9pڜ*GV;>G;nGBC-|iMs6WtLM޵YXd'm#[&g;l7Aڣ8os뗾VE `{-3nZqq57̰ 6˦8D^'g܊Q9҄N$~$A'7u2֖V~O'ڹn(DGa2O Х]纳{x Z~nx.h\$aCC9,t>">x/1ı|{u#[Zᷚrq}YL<C <2rQƋqw?rk`T m(OC~&o^lTy:lc˝/w,EIV<*f| `Ҡ[ml<'˕;i}Y>!/&G ~bo ,ǟQ2 zԜ]l: O6dmhpWQ?CЯXq%SiA>znǗ5}GBVMC0b(&fr1<{ 2$h!g917?Qr]+6[9Ct{)ݾ4Lzƿnđ'+,|{`/mnJzbo=A`7V]n- sGiйZTKoI3k<81Ȕ61> C袙t\ )c ^{#wtc/[&M3fjEXhsK/B]ny´o~ QXeTOc}: 2Ǘd&s>1GǾ8ϟYR*hDgZ~SFQ-x~لJ[{?[*uyܐ6Lͨ}JZ\EwlS^W T}QPOyp`WW¶rG^fVm/#NBn ՖPz 8N 9wn&ĺxn<ƐbI}yp+:Ԥ_HyfULï aY|7z-]]%Ƭpf'W>q{9Kyl.o1>+rĐy5%zW>])8L [R9s}7v7]yU2)YؔWƵ8.@۳qXn?}ΔLŜ:٦G bwTҀ ve|9\ISw󝆂UWΞ!^ LsdHgsv*SfOȇww.~v_s^)ICIv,>FbTīo%²N`ӂ,)ѣ2 o`y pCfnߖV`p - aVP!Ǿ/1c _`ޘۘ Nӳ:H *u8iiΊRW&1Ќ|ʹ"HhKNZ [&aM76c,-TxF>Ά(:9(?GCp[Ec@?蹫Iy.o6d3.jŮڃ*1Gq^*c{G3Шs(rÀyUoHY ;GbTN4 aCc\85 n0"c+:~{~ox_lj$Z,C~[oCfYho&e3@tR/'XStD8S*-ERu|{NGZ,]b]H?XQa-y-ӁC2_%jNm6^U8c8սԽkkU~hG޹\+td)X g*V{COɢ r^Xbʊ' :Y;"p""w{e!O*pgUJpąt]ad5{pbZfҐzx-¼Ssc06K!jOp[Z@Ɩ_#?q¯w|"taZ|XyԀnƂ^ЮΈڙ=M6zr))8<Ǜb ϭqOT K89B1')vnw\s{Գ:B,+{Lis՚s rwv7ޞA>n?UxzuJ [ Ƒ0=FAB)FQ5Bq~1&dnf8rA/Og K8*':_zw91hs$݇>ݾNX;> 4dtr6VGc x?= -Yt'ƌ,1bzh٘G7س'tpŜ ^{ݢ0#,\?ԿrY/6\3IYEp+GŚ]ps;h;2yh*0~/Ӳ}>6uۛQ8NQ76sgkqnFz,X^63p ܅c<쩸~">W 4GBo)UCv[H?:9=3{L xWOΆܛmRmժ©eۭF4[Op 3` M },7/UY |b:QwNg!afūz\rňF&dF6˙|,uGfPUw%Ds98{_-@2qq:ƙeC! 1ߢP353"-q)+4?BscoݽMGa|{j́j5t 1C6MѨr'x^Jق{3+&k&\ХX: iț8Lx=ҽ]Ν]نN83+tRl}/^v ZtE5S#.]`l(=f1LJq6tO~lxOnWر ?=zsh Oa_ZZ}o+kcT<\ %ǫDUΣq䠺@?>O 4߉d/ j/75눯zCpp gP84 U1.R:s+p0؁v)pe;vziJq=aؖ[S\~Lxgq<7r,p!2>I ̈SϞ9h`.zt,@ph\WݍQwwwB[ZBKii)^:;ߜsf33ՕE ;;e&y>-T5+t02 _cg0[sVe[pâc:D=Xɹ/P~\hZ 4=cFuv)Rp!:px6=gzjFZt8i~ÂRh-H H169J.+ƋLsޯcUN,|k\8=.(G* +P6 Cl V4~I6,7cJ_?]?);[rhc GKXtŸbuf!གྷ 3Z狄ދmSBb nCag齮iqs+xLP2,&;1 ud )?tU֌ˎ9R_˖ͦL/B^OZ" >D ~˫bx2gFmxX: 60L^>Yj:0|Ɇ9MepRԐoSB|o w'n4x6gopb:50%m[;!떋}s30'$XP7N`+Go=fݨ06 -5q=5څ[9p=O%8pic9vڣ,丬ReuhkbĘ8_ڕp)e5g0no51|۾79uU_I}k/ +iPxqCP~<}ov"kq47f/̄tV퀇Ƭp>BɽXL%1.r2hWn4~GSh';̜8e:#UtCʙ\ўdh'fzFѯP%f؋aK!֙ -&_^ڣthO?AN,6hR0L:O`1%}nXqEѱi] Oa_"lXT Kh.gIlʘs8ޚ=~xz o2:|+^9#ag >\P/ ? !j s:.tc߼2,ŕ#pN$N`e%=j ;c~%|]<>["?A%A qD97-3 /L O0ev=fAKI0ۇQ(4\W zn9mO0jjzaEry -v5bH|hjPTǘF=w߇/Tn)aX8o~ ͊1<3zJp$\ V#`%CFX; 9GƊY&1_%[lޣ?SC:zPBuP[9An4Р-Ml۶jOc(Gm/Kt[ܽijI`JxӠ&EQ8z8A{go}V֯Y_5l6ssh nqivWgi8\{W{ 7[=?="?+]=1Y3N[<7 zE=nc~CnA/k-V-x,Ա:@CZ]CCp jEpo8Vۀ<0=ZtZ'_HjkW{C87y0&G1fܺs۞D]&z] Ru7Y/hr> 7G]3Xdm=:NgXL>»יoP9ΦA<&k5)gy3M{Π Z]ЏJ?&B;^h.e=䅯÷[vst֥ۖ:1 Q3;1Z}K|h 1-L-w=R.v7%8sV<0ێUYF\okqt`[J0ER7yl$TrL'.yD2V[rI!ZE֪Xg(ڨ}:~^xLJt9]X»Jkp/, xC(冓3.s6Ύ|`Uwzpţd(70_ڰVqȝ5tY$ayZ`&r'?03D\& wɟ/7~a ƞ>xh q%RI\, 8$ q!~X3!Kuff)8{2 a8D*zXpvI-Da]s.zoƽb& ˜g8g@!2+g6~\y-c+AY#VJ';U4Y+9#/=#7 YpqP4:/=Mal >b}1Ӫ5t { :-P[S:7Gem[K1a ,Gߣz[u><C NQ>7fNrq9'9{u^|ܝ{5Uʍ%Sǔ?T Ž!Yd>z΋ǵ^nP8i| X1N͘8HBJ+VOe(wNV^Oʔ[d4Cߊq=.3sBx9ݒں*[B{/ZJs. dZiOptxYӾ+*{/XDv42.Xi{u@Anlۛjڡfeo6Dф!hsң114eЬӏ [ywͻ&UƇU&hteACF/kkKfOR[](18՜ΏJlJ0ߞ9ShƓ׽97ٸp}qf! 0[aIe.SɋMԑPM Oرmk00 Q wjD'"Z'c1%М{b^ ~hsәs9d)kyporѲ?R܍]OKa}]W4~'0pw0,t*\"K$>{< l>=`{!v;C\zAklo9NnfS:֜E%OݸuJdCF|a.݋XQO]|>Љp Vtl֎ٝxQ,'|{Fm̊wx{l~m`?~jz<5$[l{^~QI+CA >g}|?}~%%}RL-Mx91G&vx5ڤ;fu 5No]+ModW3KSɇ k2q;ۇz;?}XNk8'H͵ܕR~)a8zrRm/ rԘ 9ԉ; ݞI֖-/6M<7fLشBMִ4?Yz.rd)拏׻Xpm>Zơ. Zq OI:J4îN >o~܌V\gk'Y( ֢M=_tPL1 鴼 ;դGh5b;%}C+S8gyݮH +^{M%s>tK;KKE~}Yٓ+ޕ+xsoYnk-9FN3[Μ~_ܺRԶa‰ۜMy]e-qi3e,J'aj֮d;'_ut3>tÅr8dWv&WYqOOӲ5ZjUJeQ3wΐs{qj)(ewNͰ怡b*#W7uA n6wPZCgT>z1x{}ŰXX5MƚpBHfg0 &z$T-F6 -uZj^RӦ̗}y×8O+qtb|'^meoɖ!6</-9rk >`M,Lo0o NtSMO3:̢7hW(yEmr385c>Ζ<ˍE,5;B V^tZ7=RM$>]_c++nՏ1qt;rqͺYmLFӨx\LsW z+yX'FwM!\ZfJIv̬tP5OoJz} ˒=Y]ΰ ݍ];{@ٞU[5 F:h=/Nt7͕JߢYjn|fG--|Ia|U݊ƞ`/{Fe/]f)m]|<ɏCXD/+Z )EQi(סŶc6U_lN@׸ /kؾkO?&MʶJ ]5pwvRg"%*̓o16_]"|oL 3G[Wwտ%gy;#](K0ߵt=Ϩ~:iQio5Pc(rg. KOxlՋs+;vkGq= z5Ԗ;lYن%|0ݹL\xMc^~ŘDFbG)/r`'n#NpblE JwrU]/y朖#gD$v)2,ޗc)Kpox݊ʐpsñE<ž[QslLX%gƞS{ZcS,ZBR7PS^jFianm-3~Zx5̄:f7;.T?⼔\ԨK44gĆn`nixIk޾ekYhUq 㘼r]:sOWDӫ;>`Rs|J#JD4 ]@}|xFZߋ2ߏ,z ro.ZEm5Т `,vUX38cP5/ޭƶY)#:sW# z:hba'"tlbد&p9=Bc_{ʋ3+s+_>b:Jk~yAE#O2DBX/qoO;TPaӐ-!:Wmk¿.A.?ZBfUQٔgJcoWJ`S17a'G<{Tl!v9Nʹ re|pZ-cje\;-R;W?j䅊m+c;0<>3+ug-2y!O8U2:LÙY!3ocs 3BSz4ʌ̸LJ#`ӞSx WSppr2juNB/89>Gs}{ օA)-u^ 髓s\C/kX_x ƬbEƷ!zj29]͍4ܔn]G5|x,ƏWj6p IUܳ؋q){4.},m"+2_ 3g⨷ :MOULsY5˞زp޵I;ϐpO-|hG11ouk}5r^@6 U%,vi- 熹0uqn+n-fMs7qg2xQr 3,9s*Rf-hoqkȸsuQ(.WzS 31O\Z EaZihA9eFDޅ/l v,2czb-Ni8kkyݓC`6=nT30TFNNL+qPaRfKXᙸ?,VBb$N*sDŽ A퐘Fɕ4-BѦ" =jJ)+!ߒ3y3.AZJVx˟cRq3Nh)aqm?<# *kKS>'5׫ݓKz2'6qgˍ4nCf %#֎KE&3zZm{}mc{rT7rq Ƽ4{Gx>CtԶ`_q$LH<ś>cb zl2>/e+.oɰf zԵ18_L8yV gŗa{TrJ~ዚ~QyUm׸1v5[w-@900eR5q`q J/gUss] y̏pH`{B^?xNǃX͕{9%%EeհfE-0 26Mgl=hx,o 8#n;5Ĵd<3MÀik<~q UjVv!~#Yqۀ8%=B+V^nWa֬9ΚjJ-W[ǘl.ürDx%(/\*jx{-U2PITo(iݜ+`IBnJRZ[s^9_t m:/߇Kڸ%WAKl?^{ǽ5=SsL.NLgmxy=;xOW| O6IXk=+_f7ÑAqؗ~E&Vy&#&k75,(]D 둃̽`c*ީƟ|I6dagAN Or⺜O~ rr\^(ӷhc}N_ \Y&._$~G…yK?ݒuզ28o΄Ŝr(^L;j]pi$n5s}mhNRs j^FIL[?U^Jڷe7m~N˿3Θ}u;WrO'{[`FMlٽ+#<\SMD~zwݩA WeD/%|ׂ-8fE&tmcLJ/hZhWȹkŒg1c,dp5Shظ1W `yω1!ܟxb7'u6GoNN7Ñ[_3ߘmUyt 4b3Vwu>ʯw0 cUO%MV4oxϦ{2WZ0, FwU{*{ig`^jmذbdrvĤbۺJ.C^K J2/~S108^(د5Xø J8x3-ʁg<C˰9ВG:u&HɚjxIZN)j֬N?6l<.y\+Vlbʟ y0݊307(gS[-?%+MW:4|e\מ 3}-{n>3yR::e` kܜʬ#ayP)_»[ϱ|~LG1-/R4%oX\ώ~֛e\t|971>͒m-s052-9nק^[Yv =±tU*xc[ֶe>N`Y7z8JE{Q{a_!sԖ/ՆZ3Mxun.&LO׋4tw-Xv͎K?u} :~x:VlIeH- ky9BM:7 1[̶aquQz\KlSSǪa|aC><0܅wIyǂ}"17⯥(ra=Ŭ~|>;bz~~d]-"9 7:+UV)%K~LF]χdN'v. ĵm%l;7/~BtաޜL\٠e>oWQm[~_̀9^LYO6r\7ԑmeXŎwXʎ[֋7T}#H]OLWնMHy윌 'FM%gmà }7$ O\pI 6m_οqt{ ^'‡};lBG:j9~6L˃OUƜs/-kJtt87WvElb'A#ٓ~\g:ğgLgNeՋaC"d)X\V_"i4칏޽aYDiJ xCHVuJrn?;EGhw,Xl#/fXA" s1?4W)spGVyǰޜŽ3c cB8$۟5L~eq4qQUvj]4܇]جOmko;#:sgWe-{ Æx)(4"3"8ߘ*yOpJ0Ȇ-jsER e2qw7>&cĴJηX'ۙP+ #Wp^;yf/]9Ɩvxews[Byg0hW'U8h?Uy!(yЬ{T2(ɛ3{6s5S-8$ܚm9*ƂRy6# 3T¹oy음GJ9/\\}gJ/) Q:%@Q="S,"Ϸq7ҵXE6f|Ɩr^I?+]Ҳ_jrqQ3RΏgX@%N2l%G/'QrEF/xLgZοjڔV*z?MWv1R$ē[q2C{lcU3uw9M+qݦS-q٩x/vK>\dTgTwɆfoXE&vKD/`mi (lqRK)Ա,bΪ ;]v3GC82-Q=7f'mDSε18r-/cH=W2$AӴXѲE-14+2=_԰]-[::4S1꥖ݍu[5zf_>6p bxs3v铉ws7NL8k!=/ = ~[̜yj2vL (ks ΡʧhT42ܑ:{;m&xPW^R N\vמr#U{NU϶!ed%~RH LY-Aȶ2LWm08N5Pp'( '"4̟mS^gA_Re7CL?>T0ޚ #ej2"~\O1#LIUt/֍}m GWL>eH;v`+37 pFCD5 ]&<~֞B.@'-[rWJӽ\RşjxunBOc%u\&cTGR„U !}F 7g9zgJr^!2*="ߓ6v/˛x:FP*:k̪c L/kag2j0B]Wc \tfCǞzBX[}xczulh҃_*)`u 2J}[ 6UcUl%/o,槌 jjf6w?(xjv7~A޸61dzqb uؐ[G5{?3VZpCkβg'al,GSW=M6NĠL~s]B7EkN[q*b@f,1]*[@q;̌-nh q~`@k50W,0f, tw?e^'ЙRfEhv?P!ݧ"&$CZ߂[T geG?Z3vd/Oݹ8X捄S(&o_?ȸ:VɆ_Y ٓ5Ě+ tX F~I_;g*"Me`־YǤwaV w|Bވ/Pvu;! X=9j@b!c`ry%\Wdw Z{nt9wVA!)mO76>_l5Y/AB* iHU&o̫rvW1?]A;(Vp9*^W2Us>2soP+]<,27PG_5^1yݢ%,>$깞ٚJNYU!Ѥ\;qDKX1[ǚF>HS)wPx8gz|.?P_[%XwZC3O51} î#m>L oLjbl铇m yd%20=v3}.l{hӝJIÄ;3Uuԋ)TW*%5K9x#?3E< ) Wѣ}f}Bb[cTcD&-Cá<j5!1pHom@k`uh'u 65-z⶛0;_VR3꽪CŸ,rE &(Zu%.!bg56գ o%89jvwIy%r>#4R72F+i! VȸNd-r]RiG'ls^ƅZq$t18#>kk ?l#7'%GNvN|f v.F[fT[]hN=em'qo?chʔf|њ{XqdC nGq>tպk TȕiNs0D&"b+_9u5Oxhx6jVUbRi\rۅx%g89gk]e{̕FZW,՟о| d0AQV:;vIrǀh֛y~E`.]bM7~+m}Q5Gy-В:yObk}o'cr;R )EDIR.)Joͥkt 9or9G)OPP'EA0Z6=el({uÁ+#8n7Q+v8mOV7rc@wfps/1yj-/dӴDaϱϱCaj/Xq 3txg9M'X;ٲh#>&[vݚ7V1ь/XgʋF\?-S Dm,"+ \WH*QB[Yތ+T0a'oӣOB'1} j >*bcrӝ&7OyS1H77Sa[t@e>?*MϊM39gVat7,)DF7_|>wl\ϮAR{<3~ser#gN.6J9 vJ>Vp)[Vtp*Ɇ v|d1 i#^DEGc{K9fu\Z͛U<&GsgޗYWΟKeԫ3b>yV_o=CϙQv(/V Rq#TI0DZOvJ`b.jz6` S Ц2>!2P0lMe#a_ĸڕITZ30ȑ۲W3Ttm^\]Č Ulo9I5b*'a3[r~'fwywYs) 1d;Bjлhu_M~kǁlcF,x܈;03ݴVԙ E|+g 3.q{F$ʃmz|Q۴幯ݴW!38 S0f%s%\,v`vS8]1OWrt.6?f >Cߕ1A7]τY<+V]Cn+%41Wr8 ՑBԼo!T9P_m: ddС}vY0N . ᧜Eb6qwafͳfzlXhצ x.jao%xeƯI`}t`B.ע{:֥)ze)WD@:3mͥsXVʎJѰco.-dR*itQwz20jsöY݀Smrl/e9#;G0g/^3=|>FǎS(a2~"xJ~\إ-߶F{]MY&/ss_U3kXHEc7?}u0eǚtg%?Q9 U)#lY3TVwVźEJgdOj~"lxlG|3"]DB,s$)[m3/j{HB[*."sQ}dl#qR&Kyn]zp|G1%ocċzFʰT$g`Q*88*bNpۦ#Ҟuw65tiid&ZqM~w 2Τ`JD&rVPq12l=LqcOc3,<}-i;Isd]}el3Zcj97~Vs6X _@L8kryi^M)fL1cbOn䶂1OKNeV )أJydIN֡~[n*|ƑvOivWbID.ģݸ37F.pXE}1ajs^bŪV41e4 vH/LOE O/īQ4 ,Rk˟my'"Ԍb/ЪQq/NUyW%Mzyb5lOÆ[+&ncP|Fheطq%"1u%]χ]mlrBT0 oI;ZA)?vaV8Ȃvt}Ʃs&aa0B{ ^dO 5Hq^)k>=О'fgC*RYcnVkʶZ<xؽ]֡coudP&̄)Ud@ r.pB'pE5w9zSř4 T/<tP`}5S2^`㻅cm Μ5{J{F,sr)/dm#7%p=8okzLwG)Gs런u 7W&P:`UyXR|VC".>iPaϏeOOpfގ{j LYϹ ZUp׍|uDţ*9SZr_Mq_[#q4{o{ŽH4^hOݶi87_װ<:BY|JA}1;t<)3c6X>[u`ﺃ.`9*Th9.|k .&v'^7׃CZm8|%5ﲙfeR]JUHoWRħ65pTgQP] 'ˠOVCrF1 uϯ:(ڗ5< гU-n'H b޹byaؠb`5?Ts^%\oC{2~g'E8W.c=bH yX} N-~SOVy2'(7rރ|$f&ܥ[0*kkzQ#p~l[c]|fIJ>l@ˏmxn-*\I 9* Kr^^#M;)L-v'IyxvL <6eC'v0Gt~ .z17N ЕJ&m7)-3 zV^%:oC8~|d㘹#~fgUۖaVz5N@m(9a'>}c2eB?,/hrͮDJ T][mǵ82NkqS1[j0/Vqkh^ lzBŦ?R/r$>hŧ{x؋[2,{ ~+8u!ղH:DA\$?&}cW6{,Ig0_sgPdRؙjYtZU xD6_qLU(z{.TWWo&aEe4/g&h8lK m.pc)vU)7M_StarKM tp-w C#xby^ҋk9{NnJL{#Yq>/nwϠCz];6$``ע陁IH2g1J!)tpǝ2ph_Ȕ\q&o iH>˹Y8# gksִ݈b_+ŧFeP@*pn-FW /6?xF6o%5Nl{ރcdt~`gQ쩌)S;ؐj4]F'<5+!rdHeر1/`P:7SDv4c\k)(Vrf(fgOqu?!ַs85#pi; ʋq gSy.}h^ޮ/ OœJaRv^cΌhATD߁9n zr?:av1*&bhX6)[w#}l> ֋?T ͑qkC.Q ħd'vhp\vb% r~!fv:v΂m<1 Fs wUhR:lgmԂoDEBg5#MSVɀJNy`L]"464Xѳ $G& h. qDx< j9iqGb]%K˹TGʤ!bZLϋٓ-Vxrғ=h,2˔s{3_Bگ**\\ƨ PtM4碦{oTҰ{% ^cƋ׽PpAz%hm:~z1~vv\l-PIu0A#U7j/LRA/%Τoּm7"XY%IM'Ĵg1,T|DM*NÖi! f%aT-lٜn Ro㒿P.oZ\en>y֣*BrQ<S>Xz e_R:z\CB_Aq[)#J>rUEh_Kѡ%gL8g;gPaV}\CI2% 3c)s48/ڀī;<~7jOo>k0ya$ƣy;1- #xsJ&hRA_}8~)w7Oڎg"gKXd!g h&|E -V4JJ%a[(pڬ9B߸&pK%ϕxHcjl&N*W/Ď88 ݃}>wc`f!5 "An;$UFڋFLۈ0tW=939v gR2ޘp5hox G'>Ǔpe G?; S j}Ƀ͊tLWPϑ2w?W ~>K\ !kcl2M/C6|e)ƞ˂j/x^oKQ_%tL(_ r1&誟#{" ƕ6}!^I;J N."Rs>)[$s_B O>+gg%u"4e9,H"O.Oⵂ()_*b'䱄+7HD_NS lc,RMQKLN2,gNU\"gr~r]2.Hbg]b4lsp(u)Ǘ?CB)۶M ~&AfڽzV̋z6E )Ә] 2t{'^)yt 5ܻZ%\pDcs ]x h1\}|dfB4o;+Ř_ &:?Pv̓qwO2:Xp/sziGM+l9.܊_j͸1ވfkaaGԔm|2<V4}%Ԡ%q!LRj0u9{z%cUlI/_(1ujdBGUQma|u~Em{=3kCRsq7?tWxcԋVTrOΜ"';繱ЏwMd&OZY>rn/GczpOVW.Ns-uȚw ք4f\sܔs:e[0}9}L>6~ŋc<Ϫ~IepLx+~ĞD!Vr%su(tŏU,SLրGfVr>!7w^<@bxP½ eBÔ29[t zw?Ue)cZ+%_ɜrmX36ވzp/CN>entifL>n.T#s!(KƤsr=qHĞB_nS֞*jרxvT8VA4W0TABǏ<& D sDB/mx2oo[ҧA%zf^BT40:AU Twm`t̽[brzAC N"{[Ә xTܿMλZEf/ <@RkfZO56UrE,SQ߈X>w"Ɂ$0ܼ NqoOK1溙:|lWSb?Mc~{oO}^c;.r Uoe` xѦF)xub$'JFƮ'q {(XqLvCTQp[Z;)B!/t`週^*Z}pgN3 tlxjǔt &nd: Ԛ-y-m_yҔ]uyx wc ȟ(ěӖL;1;G Ջ˕tj ?HBG=-TQp4 ?^ppB}>y-Du1 Gva`wo%g8@$Yojbso ̘>_ԡ3ދGw]cBG꤫`9Rp+%UL+ݴ,i,RpjZf hM{R.&1|Ld'3X@;% u@sP2{ƁW}!~WoOĜxfZXb\Vb:Q)#Ŭv3wF#[۱q-[g;u0OS3mzZOý Wprfݗ3YcԼ`>56Yʏ?сBϽg!L\kŘ9eNæ̨cJ< g(/]GwPTI km8=yS%w㨓""=Νrgfޔu鶽uJ&,@ 9<F9h)Ѹ[.?o)ĚGlBS`LfcQǃX'~bD]T)ڀ%QKK ^~b /75҂7j\/fTQbc%G Lc>3QS$F;& nUKKGeLTʘ4R"   ,}w>p3793|+OwgbG|5цNXlNѦ6w?Qr|ʻWگ@3^r'Njt&ҪЖ'Y ܈_ xn./Ǜ!ٷY+-սm]/:=L"evg9IyZƄ2^*y%6VKQqJ.NT&#J(!839Jgs+޼a͐I݆id]qVڱl=H.4{|?vĤښpY n-\0BDl0\<>'PdQ;mL }]9x*mĜL8؈Ӌ ޘ.qus0g s^5Q%>28=ވ7l]3Jjkd&1ǜۺU/^)bqgh1#lpKօ ͝/rPWclfMKIc4(9tqX1_5u*g&D ͉XXROZI=@DiW e&Ŷ 1r==άEo/rn,ru`VhBfqz<Ү;d/cqgV69V|iǿY1֌w^Q1*oj< :4iYEatǔ[r;޿B+"3s+ynje/lɐ|'p}ؓ_i],[#fO\["}[_xU\Ņ9#~;=-?+zmtaD>uU=VCgh9|[fcMJjUZmzF|5)?YyZ;AWԛiK.=x"y q[7(mVguI3qBp̘p`S6hCQώJ\hrɃXw.,bQ^y=c$1R0츒#;)ͨ/iY"{OaWA7ِ5*#}fD@SfqV1=uPԋKIK9vi1:؝(&6 tw#y~3sf`fg}Fʓ4@μҕfyXw%4ԃ޽(jzVrf PM{z0;ufZ1`%#M̅GLi° bzVE+Y$av_lb")" CWUcrhnv,AH,}7>|Z!?_zu==nx šٻb\k zoIJ1;o懏b^k_[6MwCccm=Von4c <ǽAhOJ>4\#`VEBOudH%+Ήhłٹb[[8類g8GYddR>Mō>sܹ6c9g7|2/tL3#6ᎌ;ԭ &(Y$?WDNh CRc>ʼn;:ﺁ%kcb`Obʵ T1Kpͧqn0*ǝc}M+p4{ed?9E'P ց<؝J+K=7q ߕ1 [|-nMwd҆7nΆO&y>Z0jLWX;' =iL`)Z+uqTk|<2FO}v-td~'4v.weF |S`v^|vW@YFyb7ZL1_1n߯B,L-MQi(U` .)j'ad0I utKx;|uMNlR_j~2ZE%?W?#G*_TUIۧMy~:NBåHs7NðPF`7(bBƵ4 q_bgּ괫 ʸ.|2yUCWsӆ,Y_8 Dx˨VZެcdnѕFlƙu߸rN]76U(M5jW'JΉ;ކ;F1’I,^'^4@+Q59p_Oױ]=}?pO.dԗ$+@(c-9%?3-mrWNqHFz=3cpf2#Luu&k|87wkʋЋdt~Thj^˶JfV1zd6/7js:tְ(ٻ {]aF.wb@#8D=3=t 霦g:J!RK3m8"ۚV"iIG4~CG_q϶\;/hgJ;; ,L(Q{ނZ}+~UŊsL地LA*^sG5-ѱ^#88ѧ' aYX-td #e^nAFF2\n`F~ p4g& ޾wQW멶,J7p1S SYwxn5]rl/9暂4\9TnWAzvUK9{%hys.#T忘}g;1W[T+G+0- `P#{.̵'\DT^qb{nl}R.~ )ˆ h)ݮ`ґGq`c4"L1ZLKjvyq]4pD=&8+FF9q3ƁgNsIu;ن>8Ȏ۰-Wlm?[%¤KA.pꍫn?6VoOȻWĂE -"s1x㴘ң wiy⥞S:M4ΥC |(m%0~: 5TsGV9rM'6ƅY.,DZKP{+YӤW̾³]\ϵ2L1V '3{okmSf-0 㟉\ȁ.<@qz/W=Vg1VuOwijhw}nmMd`[ ?)q\Jd%jilj:#9,ƙ W>A1fЭow9Oڋ.۶cڣCX?J|Ir<Ό2|#2H͉O52_6GÉW>VϺ(3V4wcD92⋎WT0N.*)d4uЅTym13E76;ڄ`T$t2\ޒxqgpQ[ێnI%f*^bl s YgmÜFgXAu\xr L|٩梏&^{]XT`4[.bVEćͤdj`Rhu9ۚs,9ť>@n$C1s@y2t f׌8d jaE\1 Z:׎psUbsVn~W8| Ƈh=J^෈*l[ G-rw%|W5stS-7-ϒڌϣ>!12N{Q 3BU Ԟƍ~u$ AOc{vқWEkKfo㺮j+4uGj(ؽ4+rcnDFNp]?'W8휑ܝy9ԁ^}<7k\tmS4ҊIf,uqg@7xRك ۛGv׌Pe_,Tjof9AtܳRK\$1SaR/}O CH\܅ibu)ŕc4%QbDz6!gL;(uqZ/x]_W:V?fcG}X) pƌbn RqG -wVpY)PN{!6ksWþ6݄g{A8\<;_LKڣ`Zh!t4XhTٝ,xiO57Љͯ9z^w=xy0kyIw-t<2T˧'\Ls6ӌ^G8e{a5ZG`5W͸kz~dΖւEUǔlϙ- >j̭-y 0y%^5s?O+]FgsT,Ӗ]y8[8^#pFl$cYCbxMǷqs6#xߓu5]^ΩRR FI5#ωX(ON6eE`]ḋw",pӂ׊dÖ"&Ϯe Mc/sش1}+\WH NM r) Ìw#̉bzQ"nO@hR 8~@>%>Sq.`uD̿7XIRR8xĠe.ȗǴlDNf^py;? }d3 Po`{8휎e;t<` #Ȫ{:vDI\=3Ȇ{vI*g= ]MO*(lm&exX^#,5PhqHyn eVJԔPym&q`,g0{>vfBgV5j;;;2Gm5qEGwV]WtpbgJh0kP \!Y{ #7^ OzDç2vzwkx\ua F - K ,K2v2z^GWOǣs%m] f쿨 W@1Wb)۰Ae۷Hzpx 0.0 K\b1?4| qO&hWVXsicXru J NL]u'%HǷS:z/Uk^}  10QJjT_-/s -C^gxs->w-ac)gI> crVT̷0kU"e'łke5:GJ N;#aNrd x~5/Aǹ0O s\adN\^ȤZ u=x訽fY":zbT"aa4>{c 6lkg(9L`ԲAc-*8D' 2Ypֱj̜}^c9dKveVz1/ЯGnf#*G,51>~t/n0(2]r܆ޮ"V138Vbz+5OA}cea{ HY_} ~i'{@:Sr:нY51+J4HD*ǸȯC~<>4n*E|`Xl^G׸K¨ZѸ??#yvڧIIJ*=W12F ve,vB#;1žwg>J*nM5W~sgXgEϥ/O71 c81ftmW.YhÐnR[7;iO\ 3B t\vT8/N@X'qksgN0׉k4Dž"8 ePKIJ칯MĴ__sRq_C ,ȋGv\$fނC8/Ԃ{YsLsg_1UL׽ !gq4;T< idQqHzguIq9RL~h}q,c*ITfs7Aσ] 87q710D2WGlTgS5\Rr3\}Ȏ>g,gM#KwC\Ⱥ[1ǎcK y$4wLNrzfAjB5tl(WW-pt:hMsʙM"E7WKWd>fzT~;*1>!>9x:g>" k1WLW,8тs~J6J 'u_:͒UӒBl;Ϸp ;Ċ=osñQVc._]eR` >+KTTv:+Ȃvlh͆ vl9m5["1?Źs(LnKA m?`$\k0{>3lK"WUK-;9hwS]|AN.?g`Svˋ%JW}yO-{+Y4Wcy2PS]=[&kJpVNͽ}V91۞bJ|aPXا܎WZH9;ˎ<弿Cˆa)WũxQU9Ogb:Ş:YYוWgm\$r({}p_;,ANF*6Ӫxﲖ}Wy㞉>ׂ-dNgm)ƨD!eBd/E )e}>a4cW1Z*,a 6?a:XBL&O۷d97,s6szCNoqE2>ZNhbbK M]|8ގ}qp1'ײf^}M3'εSZ*Y!>\Ƃ :-5? S55(8sO8RkFi|h>٘ʜ,yiÖqvX :j>RpڅJbHv*֚e|;:&83\ҕ.tuL,\^GE΃5J UqK=ic@򩏘{rZ& $c(C|&-U#yO)bt4w[ó4S^+u尩UEh*G!'7k:_A؞rܮ_/ε~a:g\zb~"g0/аKxLYՊV`|_-ܚRq 9r= ɨ/_uqp,RQOR }Xس2D=:-la\Uu_+ׅ@'ո00ԝY=܍1lWO}Sk?)fw=/Fh9R;gZñ0WK[{UbS~VJ.[}GGD< %qVL)lˎWآ]@s5WP(F/9/ Wu s> Ƀ͋~":W&Bݧ5cqؒM:x6Ypޚʗxr7[he.Ee8+ =-rz)0INoP1]\[$gbelTpoo{{pCOػƝ>.fS_}l#d(0L&ix0Qo͢)ҌcoZ6ݳfb/ W*HK#GWn-/ܒƎuF(dRP/PCĢ,FTd1J$_m1.4}sdg)^!E/Qw] k&+lK~2nUV)p&NtRpq{ ~LpFjN zQ Co~]icdj/|6Nwrm33{"?ii5ș[<mZsiK^.;_/kH+|"Ĵj9 '|8ŖU}K5_P1ꝁ:zpHdgteOʙ Up 𻫁qBp.L[>6*ΧKyM}'>`358Mw裈C[l[pUMX"ٍMbaY4s wĘޣguP^>wʵTws_G}Ȋ÷,jf$ f\䠙#=F &1 #:{O\lI<)Dp߁|%ċ:vQHxo)»O#.}\&Ua@[.\#ˏ2OS𾋔c_ڱΞ-C`G26S`+8蹜vrIňnܟw6QhV_]9͉ײṯ1!DP\i6XqR)thk47wGbu^#y B_Pr{ FZю%8Kjn(e O4u\W} <)_$ON o lct|Iɿy겊|5<JY K7K䎘&Bx{?eq}GOꝇp6á۱q Vo@ݘxx&yQn­MzlJaHEԴ tYl~O`cP2N_Qw 4;9އ~ʇvw_cNb[[Ttz+ ꈑxrbrܼ8X`cDuѿilIm.A۟)=d8/ agYsp>a&<5ιz&䘞ʕ׉ \ad}l\] Kv"hbe&k]O1p ۿ]K5dNÅj˨l]8|igkrӡ=ݸn]ޜì3UG#e5|^.an2^ P^I<_7zVrJwHo3zFaKOc»_Evg |n{$ &Ǧ˸6Zdai+Dĩn_:'g}䗰m| 'nxY$ndX}+zS|3I,Sw,S}E]\P1N_F <F=Ȼ-4w2碃9x_9[zr8*ܼVHemy}9ځsb[K4,x@=+[0X.8dW#{t+t*XmnUFF& 5ӞUJnֱIsJ5]xv\n?;Kvw6Z_֩Gq|cfkif99oTEzXrɁ90ș9F.{Z`;G91`I8-CR>LM )ٽ݊ ߞBmyyT#(3J?88QA>ǹlx4Ĉ  }EDWfY4= s./K̿| 3oM]ܹqî!Tqmӯ o7j>7;nCx.˄l`.WKp243Kz8p1@I;̃cV֝-8A&ƅ~57ĹpR_RMWb0DE!ؕtJh>3|-*D 4Øxp1WK`G!WFZVIo^?bF~O sY{Giloq>/~M;m`.].EÎUñ%NpY%W JgLMP0-γbx)opomU,wV)H |«dҥ q7 e]1|ڗZr@79.Qe`)9{)[I&]JXo {H5Wjqiwyqy+E^\/dro_Era+-tFt2_~Kl~ʞ "f/SvG 3gtq` sɍ\XKˌ=_)!*HP"J6h93JUJn42YWp{C¯t8$۟exFEl9,M<ܶ|R+j|Zkhnyz9v,JqO<JKŃauÃwp` _Jm+{Y'v<$I3. Smu>2(8Jip{_5cOAvǜMBTLj$-qĂ g^ N4LAک2R }>V@VM.ਓ2g#{f1弘ae\.һY!hOx/lȇk{f`-Zɺc<}c2WQqCO n9D>,+sd#=sDauzt{q%+N⨎9Μ&T )50K'yƅm\yc霤d0GU\GKުn-'װJJFo;k6mųuYXlcǯ:05hnfcc!S9Lą3zK0f1ԫ)y; MǣY#=ph-Zϫ[Xlum$=Y#YϋWb͹j;,_K9ᔔgl0+0h!BGb8W5Q/}ZSoU3:32ZVYH G!4-2S0^58v=g/r 2ef+ _ޕѲk=ܿF)$L%;=tcZLO拹ޜެ6}9חkGKoݝ"}~c˾[.A_:w5uT5m5q];N4e%RwƹX;Fʫx34A+|w&.t/tc}˃\ZGqG;*xM~S1jAj~m:FKCNWqpskeɁ9%hv< 3=DatT15pk+;^xe >ݟ,AG<Aߢ7:gO4;x') WWdNp@FY~C~C~[(M%Sa+<dK_uB{1*5fu٨7V$Ya0}6ϳ]mb;Oh [' :uoL((,Fj\gvqa;ouc{ƺ)WJ:E`Orj;iD? wjU$Vk s)ƶH3_*_*n5 _@=q~.y"0t:W)nɹg+r)(E2NH>'ƫϸ9Nb|c9(vu+rdv7W/Y0("OB1i2$81RҰigZ3㈆뮙xekNylgMiCEL|oN$|C;Ľ\-fY79-٩<'!'J ڰȖ{p+-sԛl?6 >bõ>PrF_FOwv8 E9fu6yB2 >q5(B}W8g=p3Nȑ_uT ܮM9؅ mw׶ Vܶ[TlN<ߟgqb}}Zkaffˁ<9#+걸 570;4sVRk&̈́|\?+״va45޼8?}Ikyдn:gmehOYؽ.`Ĺ?TTr_;\N4lk b»/ p'j39[&F.b!JUl.-s͔yJ59}&'R 6y& 12wkcly/kWA+Nn>C:`1ƴTӯaµp6 zvé0` t(d/DwI1 1Bם'IaNć)Luwm,`B)j Y.z\֘_1Xp=kiBEi$}qDL_ǹ?0Y)7r6*=K \sD"j(c1a _gf`X?c=AYж.FwJq`9 |74Z_m|p~ŵr;4i {Sni`S nsx3F;0CˉKeC{ǜv&.Hj4cΎpՈķZXn€8QIpmg c&/b-[vXJ'ΫtW)t1y"$V—]h-O.M/ü/u?c`nG& ŊGg1:'c"]He Ev)V ?nfHi1bO+q+څiƙ=81#БZl!Y%̭>tǎ)y:6&1>1+Vok!#4x$=o1M,-N*Bd.2 tzΐs6ڈLi'UԚBBQ̋&d#ޠ|l &\i{G/Xit!îp.qsxƚ' 5kMcL`ĭxӜMˆbcLr iL-d?hY6<ģsVG^g#|xřf½:U" 1}XeK3ߓ8؀Ly9D##׽^ױ2*a.'?BÖ́ՂR\;׌Zlj̋ބm94c֬ΔzoCvT( @ĉ8uoS6V .i[,dQ朡@ uK2v= U+K':r[>YjύٸT(ѽ6=X}F$,s#9?bՠ0 { O~)1@Xbgz^vWbSNbf8reOM*ө#Okmc^e8]v@k[)y n,SXÍ^%c ~DM.45b +سΜ Č;[*@˽_|T㻰 3=38r/̪߮V}FgOfAr JUľOUPS0_ue٧}߬DBknSѽ3W@ƋLU2߄/gx!'+{4g-SM"4 L_W%,pwt.gB#uZBNWcp=qM,p 4pLiw?1 h"0=wW\Ʌ<ј>:4)&:aY>2KU":5,0+ksniJaܕ_O"ms0eqk5vCN6'+ræ4)0cu!3icw&QCDb\ZD~)߻a p* UaB#Bۧ{Z[[~iX9>Ԗ?hƉwЦ=/ ]|A}|6AsPjs~ku}[p~O+~&8{{}_q}eúbJET 1YX4??)g3^ob6vhb*U[Gp/_4bZQᚽeI=wg[`r?-\,?[!*-`^||b`{jiD]A'Kw ~`>"v$&#BWaf -ӀFrx7<6 m͚:'>sd`3Feq?NsˤR%/v bEof<ˈk p>i!שsV*W4,nt'~}8STgơY1Erlu3kB 5" h ?t:eN~UlVa:bgL`]F4:kqF}hM!ܬf+sQ, _<#'|NMUBZDPc>dsWKv3eVxZyE  O@9S4j 49:!Iym?|W_ FNEo`bs3 s. J&x>/^.g=a0o pǾTMleV ymK.&7m8)4E+1RDomi0^-xhg};15+ @|,RnX, Aܕ9:ckAz FFPa& u"~|Goe3:_9P˖Æ3ԩՄc+`#a}'~~iL&Exl,f7>tM>m=,}dBp,@;-нV2f.Q´4"?"ek]Gc6,T`zo  Ј gYn+XU#d-Rx,w$DΉQ"+!7b^WU&!-6jN N0ahÜX;̅^:~3+OOQ+#bXkɔC:|Ï:|S-ʚS&>!W_pOzsG~!*s6&tńw }07ʪ$ g`N,R[F罕\f.6M׋Șǔj /;0߮7y"ۭO7uxG] ZZtHs-kKLmBK(L\o -b `x)pe|h 0ɄQ-B3}D1&~4Q>%bΜo?4kߞRl:W1EoS;0-Hkd 8n0 UjlĿ hIF.eyx{#k+{{r>.2d -,)݁n %ݙ;o3Hbng ڬ#5i}Qa_7vPej0#:2EjsǢョX|{:ospD |XWhp}dXђQ{{-=[ՀOks~~3a\g-~hC&mIafAKa}k$=>j h=bP= àF~,ҡ~SEInFkG^p;qȅ#8Ξh֚Y1؊8 {H0b_]*"K2,q>K13E!2LGT ǭ(˃c3>N55x\O 5(mViAw6+SdUs*L9Սl ;z<%Ř#NT'lHkb$M%zsG*҈뿕WW:՚9tkno4{-4ʘ(d~oF®V1jTvb˜ꝄIޑߵS̨dUbUKCxr2:Ez0d9vX\}2q~8nŸh[߮VsE){;3753~s =؞c ߁}N:s >Y#3r {T׊auu9t2\/g8TF~Xe~sTlڝl0/: '0r~[h`slٳdY!d S sU^G5pߒ&4z{)7*-ER.wA'-!P<]1+sT8դ\5"j1*,hq"[>+' ^X:[nIv`3;V^'C/6_#%'M~m\˱L/V8{9 _=L"njc>͎r!>G2&|΄v7 iw^G*OpǯX1-<eznVt=wp BQpF̌-ݜӚǎ_Črc7cG; ∃F|xT}PW~~#U5W9-rq.y,CUcj'mگb*K7^ :rj w]ά`[ >>!8enأѪ4}ƿYN9e'L$z}@RuXECh}7ߣ. @Q*8m)ȼT q2< +*sh2+B*̟#B!frт/X3ډSza.\!ubÚΙq!tya:?Q\RƌCо`\8 Juc: ԣmCޝkȽyo6ԘqhU}Y>z$;Z/֯[rVTwtMRS~LǢ[STe9x*֍27V'rw~)Y3PZXFJ%ބhjH"j9zZ0h5^KVԉ]0ҝgK΃*T&Gz\1h^jeƵUs*Lj6m>r^qno0QsjN3ަ֒N݄\[5Oc \ s5?@ ܩBJܲC$in4a/dt?=N4"KZ{'wcX8nٷ T2eq 買ցh#+<4\.QUIP]-'ʵ[0'H{xe݃5ؤ4:,7 N6c* _!^=+kJߏ%h'ȀEbT^ fQ.Խ.]yЍK[ljǭy܌UDFuF!e^t׎.|R̾|#!.TfǖƼ>U1`&`J ERLŚ5e߀o? DʼΪd=.lƧP'Ζrc'W1PuvFLS`GE/ R>Z/Ȋ@ >Ia@ 4p Yx>LqO +}i%iT0>N@e0h>U(1 ^ًݽ=[\qWgl m+zU41,kLrW9Bi)c" ';o~Vtua|gsf8GPFq3{pQW^Knc%wɨtʃa=%gH ubls>ڨ-&/ÓET{QzF|G.6ԯ.,& 8S,Y+KXU.k߮qW*V/[z7Mƫ~8P 7lb zc3Nlifd^Wa `S8XZ}G2%̫vܜ˭ȸ 8q [>Xd>7cqu'4Yo'vaSŨe|w={OF|WOEohs&&q4`t2<??|$-k\^'&}Et#_6h?ѧuXpN`r$KQ$aѠ<Иm8ljƉn\PcΣz Rӗq9\'7vq| [i k7,WW$|'m48ZJx9n9a=LY_Up靂mg2Gz:̊g՜/anOߞayj=OS+뤜\V..aV̄Y5BDߞCQ⁙pUbI%x̾k1)TiwVY1(vRW0iwqFՅxe'f.aTRhA:Z`s2kjxS\ YC&mV=÷W8`}:O~ b7=HBd\Xq1/e o`v򟛝=q*q'!2xlO)X^jn\9AR9Id:%cWS)P0[ 3e2[Afzpw.\)yb.qeo /ObgR9k.oe:NfbWTBp1g6NP%XԆK6ϋvWj nA!ny.gKk{›%mr-75y\r*O:}ɷ|uǛze'9Ɲߏ2c{|۳'u56Nbk7ЌE:Բ4璏#]"w/6ԙs tz(6|@{My ]Ki|َKB)Ex_Vc5T`O`pd-|NhҬИsY=[K]؜%axpZ)WƌwRw^9iz)xDEL^6y7g.!eVR{d3' NOa_)Kr}ůɞV#^lŲ/m K.徂6Tq+O](en4p-OȮ7{jãY >|ϧ o{ȸr\VWhJ̯qdL oݔ2.dWhMI"S28sR%&ܪEjCLHD<s]9YiR-+q6gQ?3jS}xrVr/N:\xZe YD6gw(ǜUȏŝ-qMM0ϔx +hrX" 2=zڜgOO*''z%.cd%Sd.*)K9՟{8),鳔A%(v ߵ`HO o3qszx-jcm=Ca.8)0F^%(̍+E՛xq`/n.gHƸ4to|MBڼۑܲStwɡ( R &;81o;? ;mqqZl(zZ=p< : Pc@ΛW98631KШ3A|10Gs&0Fjcgkq\w/ߒ5-M[az<_Q&NEݒ<(x9W`йNijB>(ףSvkBT= a]*Z,hݽp}xs/*gPP[祸5 y a/F6y^Ix>16 R^m?2n }\ږ>rQJxe^AAG {E.>Up`93{r`<ߓ TWXIޜ/o.M aO(c;39ߙqsR9 ndv' 3d^ONE^ln /oF>p d>3,Ou`G{K4֑t6%{ӥٞ,~׆br$z$@_ix9 /eGlTWUxc./?1`ZߌI*nu~sJ %,߮VsJ{( bZ-ʎacF y^:\%-_!,8#.jݳ1l=$L\Ďj vk09IvoEVt_FL*2~>*a} T)}ړhpo*o䪓 m<):S7ܔ{qTunb*Ś5$[WopbS9'UyA[^~6,i$79#S PUpšN\הEYAY֜9{.|d# 9CjZ8 OuRGȵAcv%~T.WcE\Gz8~I##vw'c|*U#<4Pa6t,gz~9{Ken 2zsGVdK:xg/.!w%R&nueۗ\eBU8_̍试m*؝ cXdS&}>zfqHs=w+" ;Wq .p:)w5;:3N?iɊ`gprb@#-]ysN),7>7th)7v.gz*;N_cZ!;5J,cT,Q?q~OK=X)DC z)!G&)jw-^K!`^"|anUd)uM;vu2xExO r@qS[YE#&!S*`pz 9,=Jf:ܝX[jKel(a-9WL6SK%y#8)3j<Y(x8ћ9oޛH9H'g69[6'COA~? F\z &]1x:)%X^UԘ\}CF s .O*;TY5z'%HnLu1d;gv0sMb&ݖ0㨔$pcL?-\e.ՙwٳS >hhK{WC6Ug-oٰY8( | @ŠXc*Dn-FԠHk_EC|ƶJԞX;ҠS@wFZK'kn[lz Çx&+O^#+5.sw%y~͆{P65+dx@rn;btG%)3 YNO{X~qj{I^|!`mx0HhKƦ~2G>h+>36mL u9hƝxݳ0a^=60ߝCcܘ8C $ӓo_yRWW*eY)kyc3wT=/aBnyz&l uYqG}Ėg۱4;6:X0\&O6|+\|zHCJ+Saoس aM:yhCqg_ko[>c | 阳,ו!wt1eWk૚ Gv@mL"^?GJ.U;v䅜S2xuSr=NGe|3Lδ@Ow]R&c%5opA]w~-v!g1l+S܍N:]0.dS |bh؆̿cPNͿpaV#5du2Fuz1WX/WpL czs׮)~+1sN7Hqinl|E;ݹM,x=+HENqΑO 혻׎lTd?GonWK6 JOi\7b58¹\j–x L*=i D`d1dZS>>@k_m-s\G+ ^^/*9x'맢cs"κ5X6O:q{7wͶ֓^2oji˙ƺL3C|xlWoi-=dNt [jarmbtN_V&%ȌƧujɘ^.|9C=-:xlO^80~+cpO Wp'xpOf'ŕ|0ժ=%BՌ6Mx܂TQ]TB~i-^ {> +nRq{sS$^7Rm+m'gzrOozEH߶foz2ZIsUY=T2&KkZS^odDH=ZWaWBԈ~U>Ύp1W=#Gr81_p:7<'gswtqg2 Ɖa휘S]9qs#[vۙ=k#rLdIgsaGNy**U ֻyhsklJ U֊VeZCezy3Oi$7R7W5u pgtcnU8~[h9Qݖ[1tXinw⛋?فCڰ.+~p`2sʭn1;72u*`oha7._O?RYCSCs]T)5x ϗ] ilUΗ=ХsNTN7~gl3^\C'z9OUX4djh7څ}Ř-h6>WN] ӠC{Mfc29" y19ʼnX1+ yE'ѹO2f&Aso:d}h'Rk<{ޕ{=gC_f(_5 Ui)8<ݍ럻t>וCW8OK]8 r u"4ęfw؂-MYi \ZiŲ 6@GcaJ?S~ZUo<ˋpC8W}thbZ.]k;{p*o @/kr 9ŒZkwƤxs[Fc@z2ޏC_yrj'{gF<9MҵÁm֟Si OkÂ5V)΀c2pD-nW25kpAK]v7Fl>фn[h5بɑZ>\=UiՉ&;1Q)fG2i)Gxr{z,Sc+ӟ5\nƸ []g)SdC^Cujhvj2y[}ī%9m=Gx3K/~~ñ "Z|- 2[&ĎJUEg}O1e;,Tsvc^ԙ̿'lʏnlZA/i ݨpL;z4fGcmj͛쬴ŧ1bLw4⋝Ft2q[kƪ~\Knhx+~Dc4hv~UH+CŕJ%atvMCbx ~8עP]ޚḧl<߁K=yțGqi#tϱk@[/l٨Q&j],^35} ۟Y8g\=ymCh;! =%}JNcR|լBU-d4hF'áuH٧Fjܴυ yc.èm g,AD-ǮlKxֹJ;1A5wi஖籾\CE ai&xѨzrW/6ו(B_oiD91f0#6.UraE>6lFTXw+?MMR(羢 wWĴIwp2J f\CWexM/ݬ8(x'Ą^յx4Q&G`oȇwws>x|-e*6~?/6 d wXjY8^EWe9_Q>XkfiP,Ά>C;-,mD-Eѹй-YvؑW+3Wnr?]čU}?7g Gi/xz7B7}4N O~ޡ` dD߳<^s`G:*W5vҡ=+˄Z0H5aɦ[Έ,æx=w&x(Q3(o t[\l)fVjs%s!7.̽Raɪ}H'Wsa\ciɉ@3/Qv\S[k)mʷ}̘eňFoPS.Z==VyG}=\ϗJu㰏8bϖH,:UX}gkk-39݀ߞ>FQT_BNɆ#<Ɋw |7b^\3ʆ7T70cV;ݥ^<^ʽ[3'D\(|/ps[{ Rq CTe\4D_ x{fec mve9Qo3hѷR,=RPӦL#mp6U㺱WldQGDç(cZ9lhbc]~0`+rAͷޔry/#xsjN#3Ч:m*(@d<;]B\ LàWxWAd U9[%Mu9_WOkrDH-l35bg?ǜTLTe0LS0󓽘3ו͹|&c󰠯>gkvى,ư|gf.-Bm*dp tHxKf jScXjby)VLG1LSKy(^mZ[M!kj^v(U[RKP:\ƺ˚B6kJ(O4@kj65P:tT;d Сrja P$4H&/@xl_YmyXv! ^Ok#*t>? s?gOjdLw8N{nca7rVtL;wa_ .t4tW@83_Fw|)ꯐ}WKA^ߙs=s [iq[X&1(ΈCy@:˃y> ѩ.ӕȭ4?/{H?!8R_UZMB"g&em·SA/H?wM7/T>hsN7ژ2:=n<|Y7ik#n < |BK?_d¼G:Vu~^\ߟԧ#̬,?T\S͜pω,-Mh&?)1 mcGÎPOI-ctO ŀt []CNa ='UFn 4/V#%ٔ/[ӓ1+\8n!-^aL G-q$KV*ΎHF$\Bx]KmDY2a>wjRַiwmq< uV!<ro#0 cR[U> kdzG>gPN6޿Bz5TB[&NAVOqL?U=tlĭ45` -,c_ &t49ۀgXϱmsY?rp;g˟ص;Zjw\G{ !ּZIm~RPzAqlVͼ[خ']y"ɉ!׽}FG!06死e=6Qi8! C\20f"í YbϐwooMrc~ Z 淮:,o=qcF /Ve*‚p ?i'&`hչ&ήD,$e`]N5XbgE@sb:^`RMVoy [ͭUڼKovvm}x?O_{?Pf(LeHG j 2v<\\Fw8X+5>t3axL5MqtOʉ1z{Y(Y|Funl“S*Ċ =+[͞j6a|LT(Da\`k7^=+0Ä27V9rhK5GFs=nn)yƌ>ù0oa1^&"W/y3/_e`.t+EȹP <,HJà W U D@g8>9%k/[3؀sfs[-h6j!oL4hE0K'zlwM|ͅ99KvMji)8^6剅?QUh~jvQʛZ|ۜ1΍nН8Ґc`=nݼ"c=r`Q}*9HNAqf DbdWr-v u@+6V3&k e6eKѼ&I_,ꕧ D`zW99|xo‘^nj'j[tYKKPVVV2Nf\ lyύ)c+AxInSfF}`|#[2Fǩ~ f\:>n)p_LPC.LΛ?r<_yrg78P;5W?&E":m`hGvX! UBl MnmALb9 wăs\\i''I/3$&nu>a2wd"XSen3վb$T9εf;Z]>-{W"F1-8ލEx7%<w4pbhU.-KI5ᾡD}TzT }qK'>yfh'Kک1;W o3XsKsk^Jf8^+Z^rʼnMԌt/4x?/D8U=|U]|4XqK5p!nQ{[ʈ;l3ܕ]J݉/{Xl!kpCP n\g$.{cWڎ/Ŧ=UYITElx8n/IE9MFV^;jK, k@!fOCm,t_{|8MS#tI LxMMn06FC%B1>Û|\ɑC]u2g&؀Vr115 ֺrN:,7zZuLnyT3쏡n)9e9"8>4\](1Ґ{ʖʼnקбp;9oTf1|'g4zx`U8 ц|\Sx0 XіVא./ɝt#4zՖURw} ^?Aϴ9t ka4Xh%kݿOq;%jt,u&wGuw5̏ren'oΰbo`̹u\N_K1 >[J [!m^EUG u'[pP}[p N}Ē\1^p*C7{3h ~>ȃ<|/C_ /ݣ21k:=3-FlT%eh> 7?Yu:?R߽Vˏ&$i٠v$IS°c׿cK꼩:{=H Rı-ޡmrZr+=zy1^m3ԄuyyVzls?KKʗͷK]ڃgp< j64Ohs9zgDe|CqऻFlx n@|qKN%|f_ csᓕiq^*Fe DG|EϘ 7U)^Cc{>q/›1isK^k%NV.atf$*&BІ( ۓ6" n'g|ĸZ(fxG&^.GZ._+ӀE i}WOv7+炼:Lu+džWo7EC+sJqxZkDc~.נ$m-ԥF.5ȹh!;~Yfg#dPK50_+-L``huA)-_%8`%дkkZO3>w`hr(A'0)G>)߿w =L TN(lPh3'P08Ʈ1Vmo-λE5kn[bE6Եret#/XcC:xav!V\͙)Q3349 GQS=-şZ 2%lD>i;t8\u8rw|F0xOe?#r! ~KЩ݋sO`㌋6 VCW -q$&sJ#Gql+GOK߽6ǪyYtDwtz~cQy_yRse m4Mm+KN)BD_63fĈVk6>}kf Y-n3MԊl:3_9Ƕf{mЀ,j`+/eRvast>=w1r\{N)0 KC͜D`y4'tM8IL+ڗKpg>z)Co|3 a. |VZXHґ*;G )`72SSl \ wc5wҠm:p;m>YH}KY; 8^G>v/5q3}఩&L%gT?]ެ˰z„&t#c^E!~uAPuĴ+¨NqyͮIuBW51o.JLYLvCrL^N*3:Ro gƐ8ƕXjv˃U_JgNHHT(A\R^Ʋ:x>zRw #Z6uVES̙|ԊK&[p|cN24ckcfKMR8sХ{x`”+%CmyXM܄(%5 "-ޛ#ŋRy C:z8sѽ+H{ߨYxq%>pc_i:,la*Qp>*+MjxbksQ&?ΩC X >\)'"ϿEϩǕ_"JjkpDZqe>~{7k _HG^'cYCJ2jj3Q1jU&_LB \v`6j .V2fPc95RV#(1W# FpYH ͧFM_ݔ=k˔g̔Z@2%.Vb-eLɫs޿zK#K_$ˆs /f/*CNSty]>`\Gc|Y,-Ix ܺapeqNBسRə~ o&mܵLM %W)x=GE,֠[Gz}jb+=BU( ʑz*7J 3iF~Ҫ?Nб/Llj )"_^_n|1 oۿ[۸L ߺ$q!/UCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjW.rhׄmu6O`pSϵPSn9sDl!UI+cgCO-$W>phgK?Jcv3)GMU_ AۚhGӎW:|~|\a Ԟą&!hZp7_;QY%4*Т̀f~1hM)*,2I!x8l X0<B65v{YztV]g̱ɒI[O 7`6-oRY61eRUңI$af%YhιSPetUDy藣KS! d ;V Nn*.=Ok6j360Rt?XϷs)~]܎G{G_.5;+~ `]Ng$ϫGvmI9_GͶL]Yґq~-ڏMeh$0 #q.}1KDHk f\ьv}gUj!CTK`r(MȆG\XoIr.÷ϑ ~(YC^M3{CGI ;_G`CC$l h;㴸(/n~Q5gA߰' D̷o8WY_qm}CXرZqVݯ24.GD{95Liebʠ7|> 2 :%cvp_kR*S ҕ[->&f|6X3ai'oY[Rg=Oи)-Vk_hюb̜-,4e{;AJzzrbNSmQQYc2P ۛy˴BKj/{ln.Bȕ \fuL:PKa T4 C<S>T"ؤB &}[fF]muϞ[1kR\z&ἁf6wF>]Lѐ]M{gЦGxV.M[\Rϻ .籣Ք [x= HjѬ#*~@n:͔υ"[&Lj|qHz ]櫳W>k)jYkPa\9d[-VQ&-Š 4#ue8[~9Ni IǶ9x=מta\fB7S1wC盳w;^tqK:ҳ̞lxm)e˹6j&Q2v?b{i^AY莶[yJ1hSDo+C:UN1<2@gEr8WJuҦ|e0l ;E3;n.gLS U8sӈ7mx-KΛv?Rux>oӊ\n#&Ib*zQKƖυ[O9ɜS/!d<5NGv/ ϕߖ[j5;9\wpdftlQ&^SY<NI흖Hn[+˻}k[@_'q~4y}kmÁ˟}c|ɂO,9!ek<b`mzdeyp(= R /|Q7jrv5/3]6ϬDjܚkYlDT5#'4?6ij'ѷ-.X񭭙LּZGXTUųD l[1 \)~7)1}d{R:E+;q".¹.5w7Ֆ5fӣ,@olx̂S30#m4j ڒsq /O{;`7FDtRZjf~\ԉڰE+>xj(#}skn+PmߝΊ3]9fT3К;oS9􋜣Lߔxn1rhNf.I:Y/f:R Y*c\(^BۭK-ɑ7ǟO1s3 )08- a*kI}% {>ra|ݑy4wr᛽ 2͕γioAiM]mP\lm! v՘fk)KV1>KT*L^"A^mMƔ룵h{9YnK7^ViYp].P70c^eʇn.9qQIVwb+0~)gsCk%u:xw''Cw{l;!<0qK.Q+Eۤ?{qx ?16:2U.Ty'̅w0T8,42_ܿΆ(x[GAZ'8 ;A|?[L[Uqˑk>q`5Z %Ҝ|dkrVs.+jsZ%qhqN@Pku4椯8#9Qs;'p7n8նM6фԢg *ʝyǍ1+?OuvvtƑ6 dgOyNɘ ߯Q5OON .Go.aW#p.[\J}A[r' =PiS++^,Uw8Kwt.egn HQp'>8 \ډԹdnƼm;9t=ٲ [ij&XaNfLifƻ Šޓ}pxȖ1-௃;ˊfرt{:X7kpn/VQH^Pr -L%S?5˜Oڰ/feklΧZ]\"ۑk8p5҈g6jFa 5On>{mƩc V+,tPUƍuٲ힦VYv]R1_:N#t YkÔN4Y|>ԉg V. rb%eC 9k3҆nZq`5ݱaW&`{|KuJ^o(Ce-|ͿbHu~mL$j VO?9+D/jJ|E!W-c6[[{Cg_Nj?#O]uZ5ntv`foe14W֜̚{slcílbCb#z,3  1{(y1ۮvg1>͆qVnfNZ3P+sJx•ה]qLx} ,iuڃO{D՟z `g96IV }ksYSF5WZy VsCBUwPkc7M4^a4°)'1ˣxWcV49c6:Q}bCԕx-_w$;WsҚMMs^9FjN VjhK^L]j@V6ǬϩXt=d`4hy~r, 3p$1߄axdw_ ?= [[^Lm oT$W`N*0Y{qdpƟ(-m̮bGm#vw"7+tɝJOw6V\ԃz񺭂]șgݝֆ]Ls)wY3 wXRfB\}\F/Z]Ziuzn'F7բJVGy>Lj o˻H1(y>gpsT!T0J|<1#8{uB{pwsԝ=fl+óy-PSqUYx5-'dZZDt KoW1-TaY3 hl)F;E4> zyvBRP8*Ǩ8ci^ODGzgJhDž㭹)7dec`e\iNq|^40OJy+W9rg\v-,uz˹%[\݀]5yx)3(Fkڻ#݈;1$DHB 3ݪڙowjwjoޗSEnXw_[ƌ+BӯXn"JlXxNpvJچhcfYj0?܁ftNQ>חHЍ3*?HŇ*YXîB^ƙeȨ㌸ +3f?yfof,`1B>?G{V<>O{rۗG|yMF'w/sD^{ޓt4D)){Fjum=30WO]֖6<ƒ#y0Ԏ%r~X/|875#pWԋ0.uD7;0p=u܌/ւx1D?Y8:ZL;LYdi(hv"f_:DꕜUbTW!vǺsւޡR}kx%w< ᳿mi+r䡑 ĕ <9ޝ9{pJX"O45_1}ND8%iXQ\<-)I]]N,_fcmr"5kjݤfXo9y|'ZtkcNW %-_jʛ{8T 7߁=.jfO'FD+L"`-Fٽի:;BN`@N>,_W=aP9mBY4.ݓ/0O*| zJSFl=%t-+Oz-j鎆x#Z)!8J3#7t4B Au:BwMlశrVe>vْFbZlڣH nm 1 ߷yoS1ĩMCbGL\:V[#W2^vpӍ>*A6Z,1Nc_jkdLc%\Rvr`S35\^Ƀ!^R^H$;~t&to/񛙘LGY60-ߕI[8 #JlD kp, &WZ3pbv:NC㟩<=g _ [C#Ůiwm魳t)W* _iU8^UlZ\DܸĎ<ず;멢V/ߨ゚'-<ʃǧp1*m d/'roCXsጧ.j?Z5aCPG /[n[_EVl)yBÈ~@Mc;U/+4.fd){0;a0YN+jN³l,EhBsucr&U;%\V0A*%tTrs'6_ f)x3{ ðC~ l3[}D#lҭij_߸?Ь? /XeسywO͞xu3Nqei?^^t?CԴsѰV}yi/M*tHo:_>z.w2;h1l7-m{s vĉ&Y*R'KP|Xb+{}dj˟J9̎Z)JdF[)m-Xa6 GNg(]N+`6ck~aL!'ε ;V!K>oΎ6Mnf}Yrs!/54[Rnvea%阫<73(eSamyt+lMɜ\SϝmkWvaGQ-LץA$-2Qӄn, FJnX;u('Ɣ1s6 [sBʨAV\v; 3RobX^2,d{bnMdn׹1 }EWXT}6S˕+kqv[=4fZ,tjW+fPWw5Qg1b{Q}JQ!^xC'QwqAˌ*(O~̃U]J[<}W8_[\?=u-L;,hUlrPT76Ď9^׵|tܗsF/oqC{?fzA轃-T\~N5sϻ{R|ę_qnZ˸5;J] X:/CWH 2xPgW:1e33hilŠ(VL9Ěsωy/L[ǺC|a sZ h%($쵭 sR ]RM[_K]L'?)-n,:rAXwG2y3Y z,*[;6s(%zwй{[q S•Q\R*7B2)S,8 }''aϢ8p 9wCWu&`Ò 0dc8KD_)h=#~aȕ}0X0Ð#p4李v/4J [t|GFrV?sT=+xNAv\(-Quʛn4D]xAz 2c6z#myq%ЗUY1-żlMYt^2~^H؆\~ KGfB2:¾9'FsYg`6&ጆ,zkE.ňXۄeQ5u&<gƄ$;2?܃8j)9V}]8;̔vŜ#D=/DزfeCո% Ɵ\sqou_Zm%k+fIxj%_l36Qsr!ʅj>X#Ƌc4UWu|*!>V1kHRRU)6.+3KT:с{T䪠mG/UyrSo>+A7 ko=AK `ilښlU1!afQM+=FW3Wbjc9bJ& 3z)3-c3B.Ǘj<5bλX,t[nTƼ_nE*Fx%SNFcO2 4I̟;i|̚{83^`r!p7tcXw'gbp=[*a%AIf_c]Lآ MbMfvdb LJBQGiQ%}H/sXOh>Z̈́ H=.읈7Ub*1cڎv]n`CGG*9m3G*w khz@Ζwumdz"+f3g c&7D99ax,!W]t(=[5 nl|jkK%(ڛqBjK%KWx`.?(u"֪21TS"j ~)طDOyVGY oT<};Gײgsz 3]sV+&e1)ubPkoE#hX(?>_]kb|^3o69a !xd-pc՜Ja)vWEM)äb86aV͉z:pKW1.fO Y4,4;x~lo'LZIfv);[rpgnkǮVV׆'6enCCk65gBs*q9>@δh#;]WpG4Z<{Ê-ft%1d={FM}f=FyيC r_}Lٶ{%n:ad c+ 'pW;-f8땎 ]"8 OD(p ::t|˓;JGrg99(TZ:$tEfM~c4VIXUN?\۷h~9z > Csih\S5r6lZ:ژOLY #]noHؼGOYһ^ӣȘDŎuy~'}X(-1 %ir 5?jj "|P?~s@MF9L}z]-^Ξ\GƥO\ m75erD|CƉ{(;w"GϵM!',ꙘiR.mFl|K.ӄ#TN[#)p\_3 !OC$A#~I9.Jwc[yA7 2PÃAjDy3PdUw&8#HvxTLGO^FK*>ޯ` Z9N}+֍lLG -/#$Lmc~`uۛHnsK˨`fr44Ϟ'ء!))qk^H2b]]8…b tϩxd'1C7ZpY {W>oްwkڼ6V|zĕ{S ,L gӳ 6orT-,x&(OkhRˋ)&͓aEBfOes+Β0ܔc.Hxa5'ŘdXܟ®p38#zZgXL[K.no;F yW4ePԊ}lʨshYll )h$ĀSy֔c]9VZ'kZݶ_jY뎆}Ԍ j:mT )8sxO-kqHK zN7gRpm-*ImZ0K5*ebpDdJpxV`8_ fRvG"|Kz8;]CnCG/ g\  筄.4 B ^!c;m:1bS栃qM8钄es%^|;Ƌ[sw?W^rjV>aS-7.q]ͮŭ;ѿ/M_9^*8_/\tNjNWIor^Q'y0od8p4NjX]&`Ɋ@KZYH8wU}DwxUeyV:arϳbA8ZڞF~A̵gy xLy[\S-]%]B@ASjQ{yk ;NDs8'g28Lp ;څ=rEAV Mjw('d7WWRldY%cZi9}i(CgZlTp9[9Wΰ^ANMTŌV+b-q},?^B,bEHO3̰.k?eJhm' 6ũ+ЮpK_FEpˈhm;yu!}Ҏ \i1Ã9aV ]-thG?R9]u]E?%iuam:M*T>T5FVì:=}4+a^Sb '_+18; OF* gĭJ0vli%q'' y=g Bۢ2DYؘ%Eqׅg{!W͹^<ҋf2&Jbh92a1օ#{f JR1孒+Lj6=awRep_Vk*9ዒdk#(II vd c>7Pދ޻$46"w<ķP9ބtf|@̓ ѳIp Kw)8v-zv<6' o\Cuxx( j!gS4ZV^d& ZNLlMf\pٌu[=7эOz~{+xtJෆjˇk/T*{NV9RC-YzN9üwĞXE gړdX> >b̅hjɩB">gSFIq~ O߸w?t/:iX6֎~IpP7nn2T/Q˚1t9 ]%8Ӊ^BPaϯ*Oȿi::r󴐋WyIQ j}QKUY"gnT,. hBy]nߛ&aC~"mt4CjR0-'LN>k<|9 Nͽ/mСxr j@%6BZQspz,x;[pyI&h"x~6E+sل)ybzQ“"TLհ|**PYֶ׳-Cul"./5BNT(%xg6İuJR^ En \ Ә/)΁Ԉ Lh"PkV\mAwWgM\զ=>312B!fF̌ۗ_5KZs);iK9M>unESdtޜ䋡*5\Vqwiz֛ٗFo[#giTxqnxNɌj~;Bx)":NE%^F~!p>rc<0O(~sx<haV0p, fAgalQOjZ4muhp>5CMMXѳY;\0vάA`|^:&4\jG.Mz*lcZVP9B޷ý|_ťUV'B&mߏT/f؋+ι眫0~`: òq:) \RVJ k #E<<1 lƒ ӼT5 vm[ߚ3Ðڷ-; ͡7< 7NӷB\L>9嘘i.x}:kr,*b]أ;cb=X͛2H_J:Pqo]u;ރbYdo)0t;b3L0f4 |յw){b`v2_eODԧoRZ;=[~ŨfB0$tJL t ~6U7R Eg1/%0q5{%-:̘܍C/!O?Fwp[_W7YKs7f:qE^kyXQBw WH}TZofr ROa~TcySc_l3R\O1cwX;)1-ϷV , !0hOJ wVj?3߁>,?HGsq*TxȤwY%3^:P+wrP5b?{ 5Rz-Dq0G,K_Ѷ=;6C~m"$/OJqfL:a*6X] ]MF+ wNC q W8Wkxn6RTNE4cq:τDĿHFrR9JXЅRQ-\U:fxZt7 /9݇^|ఎު6ċ߂TS L;*ܧe s/&EK9DkI++1i5q$1ga[fI$́6E+-/ֈ˾"类9/?vGX{Θz)OM6I١!}6,rѽS2 PnmcZD/ELZWsX%6qYw/v,T>u =?Xc T Tt2_gØG^ySgxs[aGP?7f۶/p;-,ӄl4Y ͟g.aƔKEtogsrб%i鶞 -++TR GI/OMS3|s2\MuFzQq J6D39׆='m1#,%Oeslwevw`rwtS;ՃgZ[:MR-57ɽZu=԰kYN3߳h1Ζ/;0g=WBϱ'8QqR#my%#bXe+AbPw2v*nnLm:t7J)?Rwf4SRa:޵ֳȏq~|ax/aBVN>GZ6T CW72^cf*s%Nrq %qku }?BJ䨭rVPr;n񤠏V:ΪRhR)mJ^M{r of9){x)ͅ1el&t&ܛګ8ddl<Ɏgܴ O57yZߒWkFkz;0x#w௽N?ԙ81j3}|ϓ|m.]])w&_:q1: _𽷫ʰLYKf\4\J7ySf:6p_NZw̓wwӱq?-Vi%y {[rK!d$*!=d@cnmÊ.ŕ[Oh"Ӑ;qq5o|3D]P};ֲKӷIgpwWUiδsn-.Bȹl̉*,΂n3 OjhxWŝUp9?eI=8r|,g^~drکzfrvKͻoThᆁZp9|:z7Ƅ{qwSuܒy9P39QzwXښLo1ݯI Mp(MHK-+oXqhp6i]Όrr*Uq(Դ|37Jg+1g3n3I 9/V|yi%RG`X(!jkӍB)䄝:n U;OJxdr^-w6xД蠐eZ'Sh5]иyiUǠݹMg׾hXiAɘ4֔!l8'=^k{SErNcGi#+tuaóz ՇxG*vR2+e$LÀY?N2ine((r#ZIj6a_TSW͞ :uT>5shU#lGޜ'h\[k`&ʐ2-Ju6BeSiы5/wH !RS|`lο봅Daˍ&<3?8?SEg0{| 솛iCY%5PREBw/)i#P܊`W x'`w$uGxLڝ?H)ØWpĔXqΑ&3]觡zF~g9ZΈҲmTl6R͓zԢė=-+0$+㎭Zj_^>sq Il3[a RTBH\)J˽2u{K~]GqeO7vfʴc .DΟr6( O2ĭ1tIuȕk J?aRX l'j6yr' 9e5ղh. x خR<)+EB48{EtA݆T|Gή=})4;  | e3ԮWSDÏ/5\_F2>iCa"&Q@Ub178[ VB%UnőmYVߖ^ОK$Dz'!l"bIx83 oG~[עwӏuldS:^ZJyzy/ޮW%筓8+ ^Kqp ( ys1R<)R4&QqX'<ύ8K#pRg'lk=bD|+K鑡UzAbT5Nxil "sS3ѝČ&xۚfVt{Bn`nd^e߇c>T5wrC F?=u ƛTZ5pF$ȼ&ά+zQɗӷ0@Ͼ}ߏ}Y9#|ÇʓZ&^A{ FE0@06XQ`iX|(wrNZ^)(;nwwdL'hjG_{pb4}?d=zAO|⼋t7O.'d>l((0؉%Ø,[dY2MYڌpO4|{\:5p~wZ_ nu[x߹9!5;?::al‰s},XΜ<Ąmcl7W8oz63nӏLvx^#w~E *|E'Xs3jJ8 ح(ewLq_+Jx Vḥ1x )-\ID)6"9\\>Su+*y@yZuܿ'+\Qcc|ح/[o0[+{_ςvXMDjX<88~5b ^b`?B;爌S{*Ђ?rޡRǓ;a7;킟%| 1!{3ގOcFx3/È#mu{VbZsQ'5cnYÍUX|z m1CK$DmÛvPZ8DWmGs-5T3Q^jvS{rn [ֹocɝ17`Sd•(Qwj_cp\ qfT>Re[0j~~Pl6L.ڔu#,{ό9-Ԅs*(ΈF\QvËΡ]T^)Y[s\Omc; ~:6=PՏ#:0#L/a|x&mB%x2}Mͼ%pb@@|9E5r~ 2/~g;:{>UJ{{q))?6A8F|ٍa#_E8.,lvSv7m+&&v &݂X؝؊zbt#޿~35gvtpG9~=1O YB[KIk 8YN\{!_Ez-&]-^Dv#>VLsjűSc$v @?"Z39 &i4E#ˑtn. ;J>(` zF+i4zeA,yOzWKQYה/6~³XF&sP Qr"MwSLqr9f,5^2äxS$Sˌ:eܠBb{qn?qʬ%dXn]h,ey|%uXAS2TҢuF2A tn&hed bP; a5סcuyqp- JՀY>CH)aZM(L^dQ=F/F/[wQ#AJ>>"BJ~#GNJ4R{1DQLŁm8tŸC;ҟ9:7 n@ աPf,^ `33M}@DПEi|4}6N"]>4ju)Mӂi֏M!nΖѥ/oy`[p;G7d\E 06V%gљO;)#, s#)+6F a`. '.s};-XۋiImihJ!:Eɱ/Ncs(#UdHYM]Kgjׇ_`]_iu&XN bUt\¹XB^WT11FjzzTb*P| }.)GC0AU*D`/- xūZ=+u9_=mN.&CPne ʼ4I0Bk(5[.Ql*EΟH'RpҚ_IW+O..NOx`2ǗZ,zB)}Κ&궻rNS;4j]{~ghn #ZK\,s.|̡?io4py-ϧuw!kULf1N8_Eh{r_eMl+ lKQXԯ0s`Sս"%m3$گj. VL%[hR-߫imi \/"C9+kԳUR,د(1IvwcY4(6UBh[ ;VX\CaA\Aixaj<>B=LK?KX=} ڨR'D2,G b]"DR0B9GЎa GRs5[;fb~An=,f|6-X) Sbh_M*IO6w`~l9/费%]D8v*xn4FKrI U5]ޫF^gcK>n v jxE^Ӷ;!0WP%G]vN%3т:>E>i_hȣtbT&[I1ts{9 TLsi^bMH&Mu?)xuQi4w}k zru8XEci7VӴd؛Mߕ PKW7SO=>π:̽º L(pi IUIQRi?K/UB]SkSt]Fr9֥kQØzh@7WӷX*ĿP! 3z%ZjӚhǸpWZxiZ1lpgxiQsKEJdUHCћg4m\"PR1#Fؠ|h65[FU֫@_揥Z3rkvn<%ޮhUx+xW@cW {'=Y8Y>,;aied\VBsyULxFY4nSz{K&d~ӽeB^K&蹤~˦GygJ:f_Oqx:X`O6 /GLǗF[Lfv Xb +lk*+[agXdZ_KtkE) UdWFɰ<:TJ4М]lG=b h[8Ǣ#_Oո}IE&2}v,sLG+iIKTg.x(uASjta45~8ATפ C'3jtecZ #Q=:yqNhwE 5萴ٽs?+'>rwp X1NB֫hcfvOo.GRv4DҭKI߸KH6qۋ-a=%.nTw6`S:32M]S[*,g lV Չ2Լ{j apbvkg tb -d('Cxr)s”" Њ%1nW+lA.ZОk^L0[L=^sX'sp[QD{4yd׮@qvyDZ|Cxi{F*L,^|<cPo94`c*ә+uJO!/.i4Q:hp}'3ƟCJ-N4bɋx+J9+A4T}&hԽf4:A4} }^ēB;׍ {Qup/۩vE_^g٘9Ns(/u71Q3* B|ݡǜ7`8Uv :ce08xF [[g-l`(dCTAN6:`psVGH+98kd!_#:3lO0S`R(2!qq.vAVH$CY5.5@gjUe*Y:7VrTXxp }4kJȧ:)ѣ0N0o1:G4S ˶YKo AVXcSvrGbamEQi%un9V/"rJdq0 *bupb~Y{n8H֡2SZ`b5x untx.;аC8shL;ޑ\hW72ؕ&kG4Zi.CƝ-qa+nx?8k}Z犗,iHenBHSa< 7!m=.d6lhvL6د4| )ݥ(ՊQ`=M! %/<\.Z#\j?IwI,Ų]D Vh"hkCs:0rgK\q~HswEnz\5k|׻dW\G0Mb f6 tAt=IPL5(;C~ NQ )z)_╥s@\4Y9WyT{w(<ۅFn% uR6!ޜqb98ɖ5HxEvGv9h :#0|s~ j%[q$Fj1fv^6p7%";}6 H3â fBNO %+ް6"ihԩ)8E ~nM6CS\,B$Y 4gdFX luBL~+A>dy5!z*EɩT8$^QC$8Mc<̻mpF~|;JYc?1a qE tzs$*,`~ &A^oTx9PMgJ7 :1vc(Y)DW,bmX(?SJ6OgOcc[u'=+=דdo^Nk+e8ҎqrXS\]Lc)sh5囖E!:nE 1Xay]d-Xb-MT iq^>\[xx=VЙaW35xS̞Isb1^7 b |>_].6r9@1 mͰh4Ktm']]Ef߷Ɔ;=\Z=j,qYo7˸."e$N%ϖҹ@*r%roz;팥㈒lX~t+UX`^;l\e#glVo4#nI lmỗcm_-XߵC1Kb_NiF3fKՙpxpmPs,46u__Dk|w% RHbbG'Sfh G'9IZ,գ-SarE.cU}RTXIr9\V"J c>4^1 \ `)faAxuO9|<ϷG%6>, 7g GEQҞ2:;i Qc.v0Nkҡ.tiXQI h2v #A,؝Ƃ;fbsq-)C1p1;`wl cQ↯h%ŒNxW*D /ZA|_[. Z~q&Fx1@ӔxV &1Rb'TV5Y-=O nA> 7N.CA3FZİ>e;ae ʝaBk4lE9tUˇXzrpj=o0l=;"9<ӱ_(gE* 9[S@9vTc31ŧG6PeIxz hį]\ŵ*$hyCrlX$)x_֕*l(%|ak M  rlI w~3Ϯl-@0 9+LйŠdoX@Ԫhu5LƟğs%Qm+C9@%)QLS, `f.2C6js5ؠ]/"or1p8O*`}U8U5(%h1 &,BN1q N1fl:ip{jGXUHq:" ce;.BaG<@rRb&t5ef |r\X fBLY1ϯ jg88LCi/LrBOo[?@sœfëi^w#tK4X6+eaO+dq>tC'Jl a7 Ո\w/3&B{f`V y(;39"jG g] -TݨFT5wV)R E9"c|w>LRPFq<_l0 G-1 ܼ>;}kssyv5\sm5w\hQ04˜xOQ1Stsj&dsY )Xa6́G&0V4 fJ3sk K   Rm4h@5-c -*dz3Mu@KX 0CqvN tfc#<B)ܷMA=ɟ/^ظ,JWnN3өtw-ZC7'Iw ޟXXjm((tG.8] ch(`> %IIaK-*wnn95Joa•-"WƴSjzdW.>wÍnֈaػ{k3CY`_H@4 gSD>ȉ5~k)$.MwyƧSoA~ʹwEē#T(GRxDP 49cIG$\fX*q!5[D|9[!URG m5Mo.=˂x<)*=i O~ ʜTAn)g֙c9R޳z[wrNPp\"ֈQJI1R |nUek=^vvw7`Hm ; 6h3J ._yr]b6z=E|SӶ_(qr2A}VLsJIX+BX',R+W%^1`&an'|׈8Y௰}e==Mc&GyLP+e] lbvݡ8+p,F999h[q(@\!xL kSm Ӈ,9,0GfDz'Kh8 3FO];>4ómG6umTԐG!J&3 n^ٖp-p@[OH a)Ӈ62X(ArAV-*x:T WWbg 6(@<4*^nV7vdP֫ԢeA-*n[Sik;;MGdOGy9c)J(qLJda!o3.vpa;s>s6Ry;z؟;ye\ٿG'3#7fUʩ)14#K/0;S?piQ"qGXAH ю(IG$;,nMRYJEb8Y>B/ǒotzG ;jO>8(6ag$9֕K08\1xZ!X"H0M|:80e5[᷅%L53 4Y-u:ZNgsOo?soˍSN7Sc(q~RÑ2J|]G+2~SǏ4֘c |Y\c?=&G9JҾgSBk}Aqcj+ƊRl9J5l+ԐgJpM1bwvCx3uc VєmԣsQ]uL=AGSI3-ybK 0*0EGiawY l_! S^!iLxќ9i1En9pb*[Fm7m(yP=/$0F xDt=e۞sү2v15W=%YS\ U+̰,& bYh_f,2m {TVs!k1(B,^a WY 2gXv-!x=ƻXa[9)~S)4xcj?hј"*ZPE/MQ`>&zoś|}~ qalm#lFhG.u'㳽vDܠzjL5JCB^n sf>]p?*'ll+N'XOp Nˁ4-yOiYuEQoԱS(ց<k>,Eu+>i=v8}1L*!01ǖ$5K1NV:H 37_7A,3RK~c: Wvhv@@>Fd#c>2|ϑR)t4JbWW)SOQUjv)9H @?ue<ߨfx-SL*>n6k\,%U2\hQJW͇H6z%xlጝ\1YB,g GO=BI+N̒|> Ncx6 _2nꮦMʡg{.&ﭦ)da9aI-ZBcWxlqƒ@g/mňX)² g q%d3dh[)UA^.2[ [gZ`6y|cC nϧz D[YX`Ua;-fco*HL}^SOM:eJ# 9VF'R4;[-k)oULad7Rv'{}xmCV>u]JriIT!-z^GWMK;>$"yk~VR%Dqg>XCl򎋱9ٯ,h y NbD2p[-|txP1^nckE}nZõc,[D{Zn=u3: ?@.YBɵC*+8߳T{$ 0wkhaD-CwQ!'e8c91 2u 2.n9 \!B2ҚHӠ"bFշiT ΧLjw+!@a|58 VH`rK蚨rzv#䇴he,ɮQBX<=D:p8GՒZm5Z"gq[KS迟e!ci@վ5SGҚ|u-Fҙ4R]{_tQdONOj}*&ޠpR=tU|4ck}ٸe.rh} ^)UڇDwHސݲ|zz])6[jqjKrZi8yb(iQ@19]b~RlEg^DQJ+M<^M(W7iszL57Ugh\R VBq.JK4ܳ 3,lYEn~4;.6>75+uK\P-e$r9 #=?Ǻ$MS)¶F;6Qf(2:)_:a|~KEhQ61_v'S! N5rg W¥\ͅ\6Zp~OۣbRlɶC,d]_g .n$QoB]hAָe? HGcT%Bޛp."\ Nk)&5J:B?r&A NXFm7xNW9cmҗ\8b [ذ ]5eɦ#45)I=iR.B#b=푑AH6ƙہaWދ-`U &nU=-ѭGm~JZn_'hr$R|c۲h,DЦi0Hu'|/s& 3\9AHx~sud6ғYUE;7ҭH.[df O''!kB}IhT.4C*=,F0}^ \!?C6ccO9uVTq73\blVȑzQB31 gܹF8v$~;)#1(ou\li-1 U@E R'9=$K $I0Gqh{gn}raF0;aoonmQLDE%DN}usw=ǽ֬f1s}0B@RosTicl2sbѮ0 >Д[/r x3.-Ŝ n# 9c=Lit}EP~'7;~wI?CWρ>;M>?߿|on}/߇.dW^%3)KX9E^Pޖ&4ceLxxS8.TC *04tm h3<_WsWg%l^]!lcfI|%Ϳ[=FoR|VA\ig8933~c^9f%_TZ9+9逖 w%g&(@ASz^r ]5cSK>Uz92gN2VV*XA<5;򬣆j/hyM тpʙ{Q?܎y-[|\eȬiKy[Ώ|[KO#KDظwT`zr<}\Z8)7~S?0ϫFp V^+?mN>*g^5?5f]f,{o,SE5%;8 OX`uM{Ćx.:wɨꬆ^PyO?5᜙D|D0 ǩ9Hd`9'u3YJ(+pb[`]9&;d$&G^?UWb0W]MB rA!8\ a n4"߷`R GI ?XQ/te/v':=r'qʑbXK<_(g cY}xbt䃽b|ٌvlA)4* oqq|_ʏ=_⻆j5HT2%'_Spו7’Þ5~OgxG5w$3}_Jξv 4SOoYpJ9] L7Qgcq2LZ`(QȘT6Պ߈UQTA:Ϧg!`:TuL-V,0v/8BsA f0D E1HIa:Xcu>34Xg.K_OrFg5SKyw .fpv=332k{pstvH~aa ?Ĝ@ijt(?↲VYaJ9*\=ϿW$%c5TQ@d@܁o\mciny]:sf+[\|Lj3`lsW.J.,sN0]R; 33J0KȩJ۩f?h*J16 ZT1ljtQ, 6)QܚA[5ˎRmW0Gj6:Ъ+~uf%E | gjNXA'JHמTy(YM! rYHZɽP '|)ƜRK*QWQ To(E4!? Bm<}r6o O;ƺ;7ߢ_)⍚lвꃆ,Mj YÌ>Uc"<ߔ'cx4r2s?3zإ+A{t22I+ 10iÞݡﵖ/S,5Wo+沆 4bp?uਣqfvg.ʽUNg#Lz>r'㯷*fIl>ZpTixj^qo+:xF|P ]&AZMՆNGLVqo4Dkhٱyg[(ȀN^Ȋ%lOnk?{j9BC纮C(ar`0 3Q^iDIO'.3ѵE0ȫ50ڊ\<9[iX`( ژӋ}P~-*c\\ɘ<3~ø5{ҁo{,=7~ǩbWqF5P󲝖_T;W)F"zeLC_#_z'`lƼMȿJx~)X5R=>w+QMZV@1x~+4cRuSc^c rlUrk^>̯6ޑ.4{Ha,loS+sT"R憡CWtv:ƜR7ђSjٮ}wqgcY_(~Ml+YrŚ{i7 LQBW#(~r6q_5C#vƙ+(ҁ6\x?p;}^hin:nƐ!1RISeίS lbo'W@!K%; `ǡxn}ƛ8|7<-BrQ9q4Fd84 iY2v> 5zu2RQ/# ̒-Ƿi.ۃ9%qzFG'v|918N/VZ+7ƫޟPQh2ʾ}?7^#^ϥ@3n)[E-аOJfc"20X֋+\%.] !> KTe ۩!gt%*Zf9۽6GF %"zvtaD3N(3 &Sϒ^*+vcN==ch=8maFl,s[)b3s I9qOy㑔6dQ ƞVQdGlxk1Ȟ:+\Î $-8OːnzZ0N-҆Gd:)!`X1-݌xR2{lt>ec_՘27^D Ǧ@5}="9,it~71S4htV#R0^cA8cwvzϔ칐eL &ym:)C\gn(*c8t`ф: -`g[roPMU!W`Liy}s%3fsgdؤ]haCZ%^s* L9 ^k`}K~~NNLm)rvcf?wx‹ = ߞ㭸Wʒ3,icV ގ|LGqn~7"8 R~_Bb2ļ :G(|3 =AlѰk{ Ca!xۙ6]EfOI-Ycl![ Lb\IU_-h`юG 50[T +ٶ/:gA7AtFB1c©=Hޏ9~7XnkcI̽f񋇘r fq>V_ xۏЍ[8O7״G\|^E^t<~cUV0)G-,Ɣ~7#bS0OMiU(c( w= ~?:RJyv*EDO ?1γj1m+7eE| 0 ngR6*Vr)(`5?u_S;֙LW7|^NWeN6OZ>2hle&l9M&cj7SnU<<90 /^Ft- - ^Pq)' h/)g.R1}--/vG u&nT2/ΞJ?2t{K ӥ|*k˷Ԍhg\Ӳbk nV)(A鉟:Ǣ2$7:ƤW%y1(N5އwn|3O,xYu wQ>y1&rװ%d1sYVz@khlh݂1(=Jr*Ū$݈SIXҵ >f4G{r5m^ZJ[n:c/N4ǎ (9Ҍ[VmhCօ0oT^f׊FEܚ,e7C:Q[ir]\>E˞%9:[J7RlQLCwGvƕ?;řgq7nrdІzn.9+{q@ę39 @N"v XBH9uQtrZ`G(uUNTmr=;5ډ[7:gfy2+9Cw{GkJ}伻KE"'ue?%ix(Ɏ2-Y-L#؟qxZU~Às ,eW,BA~ӷ/H-g?ǎ[9`3. x6olR@xQ.Q>.M6xe>[G{&d9=pUud/+I^~_g_lӑVZre~[{>i1WoqowLǞŸ^ /ûU^If %9Rh%q 35Z2pRSd9}5-t҉ trfY3ow 'jZ3uz樸Ccv]fU%!ymZ=”]lfW&ù.Xdb 0_G U p oZq4+sa ] }ÙIl[hWI\e]~*Nr]1,el5NCK nbSfw"Hnr!Y*l49;ŠGO8po;[QZefs|T G7Ŵg_1gLꝌبK1O!jZq=X*tim!Jڤ9dVrV} EΒ&b[lE)rK[]hљ|ωM: fg;=gZ#yٱǞ~ Y2.w~[["dK 8Bg" ;ZXǾ^BG+nsqG=Gpb1̮q ;XEFp5?H 'K^)u]+L9k(`hOE诗cl<ତ)80Cjo{ZWqXWt1w69}#W&;k#lόL w߱m[-yY#{$,ƾSvÔ;kSl^,z>oV4 yo;^Xo}XԎ730͕]gȔ25ey󙈧v+8Ea3i-0J *d,%O ؿ[5BlX'(:wN Ow_ᶠ_Ƨ8nlۍy~t/rWd#pp"*èS~k>E<ͻdp]FmOO iaUӪ VF<; d2 SβJο-2TRnbF,XBE){.͂8cܮYPWC8'6f`xLYu~u_;7p%9{Z2$̸.tH⺜+ 2z4p!+ r;'OVg]߃׍+栗r];Ż* MҚ9J=;ݯ/%s:<}zbUdK8;] /vk'G^fϩO-ibDƸu^7䨋>yZObA iL@2>$D6x/t] 2M Gٰܑnm\=ՌQ&0ƙs)Ènr,_X^8?Тq"~GĢ(+N~Gͷ?g/Qvg|} 6b9sV2θ,ckVaj,=Wg21vm<3P9Ü߲Vl-Y9"csrSy<, ,k9;Os*+͐p {"iiY9LG%OtbХߦ>rrÆt ~=ʅ>ڰN%* Gh ߢFSx'SÈ=7?-aW؈W-SdՊO^۲D{ud$n@'F >wfYGQ]Bs>h$ 96B:5yJMuԜ[+I8]rrgLW;>5F̾%aBS)t{1+BL';Pv8^\ vex3C=7xEۖI&!^e4?ђ{:5>E!e&;c:2aN?^?(NGQdOD%h\ߣ O8e Mj8Ub^_ >/{AH}n|ǒǢ4U a?ʸo'kTLb,gV |,I|1DwF=bMM#6kv\.8qa8a\녽39p] sY%l5 |®?σy9XnUu}_ťrpbܫwg 3WMu`eG~YѮØe1J})R*kivZ.WDn|\,c%ERSi{ /A<~ ǵ뗍xᇌfw&xFeo3 9yW\m1& LoQI w+ OI}/199]M\/bf5_^v%n•g̅;3ωXQ7N#sr{ |4qJ kԾmic %t?jV~R/ {ygY&TFdhmV[.}/Q4\Þ>׍F3kqI!e2fQsDӪyֆ2̘̆>E:il: Yp-I.5g1^AG<κ('품KݘXEVdLDJĘ+sGH5Wi'qb']곥';Md _w^_șS4=$fk%܊.bp̝6:8+„y4 E7Os3̸l+C]/2y3S[7>ƻ\ӑ&fZ$[SK_I ^jʮ˘?N%CXK><%( Yߺ^ƒrĸ?]<%dX.SY,⯏ dk-44:[lj2!Fv.3Qrix.`?#k|lALh̸pG bJ=R1Wȅi4ejcٚپ?HF] s0[u^G9X{ɔFF_D750C`jnQ}QnfX30 Ba$=kWw!GΫ81c"C!a){jG&4wyx!<Ίn5G͛\OijOLxX9F.aw ocͺca] ~GƋ1sIW=3e.!U"zGZUlM9J(e-zs+zW>sPQB]own-VΩ yTdLi"f\.#t69Z3 sf>.LX$DHY40~^ px;y˾[;kub> jt,V CcfzPjo)*EM /@zG|̑8ygQ(OqRo||ї)@g [:ucBƈ_tFXUYh3G~B"LEU"\ұhbg#.^uJo)Ss ]hUb4)e78fm~z1ԍyՑAorǢP+{bs맯D$,fJM9K%"Nz*S3;ru=mn#rQ+f5Rrk!O U_J0a5Z^^i:X=RZm2UUnI:"q^u{hXwOCDDVU"/b(ᮇ0Ayy{70L/ "@5<faپ`|5he&MGڸ,6OU v IN"h(=yMAs0gG<3㊵<ϜO_)#RC . qimL? tV\hc̀vtfU6'[9h}Tt{.gF>ERXIiT*ʌ{Te &ĵrvG4'q,  3 ޟbPJvj+GwZtc¯ko'R Ǭjyϝ-c}*6)_PGDŽ,(f=!|wފ3O(՜:Q L CKEDb#D~Le>BWti܊,x7NYHc0vυR -~aOSzY"+2 mG"9$"z'>vһQ okc5kзi z,áb8V@ VcSN-HCM,O :i>"Ʈ5ͽ" >d*[ʁ\̙;\XY<܍޻3,™VBi'K.[/s\o,-f<7֌w*Q#5ۀ7!1--Lc;|7Px\ƻ~`$ TA{tS#/2ΰK׎b4ٶ<JR&滫03J$Hbt;V0>V>*S:cLjX\ޣQgugq6^-|B0mM<.ʀ j_7jWf) /7_Eo, Ⴊ B a{/ B\?lޒ0e 8.xsoƵ0971cS1ΘAzS 1e81]aobHe Tb#yeƮ-,*V2GwWz`Ơ7nƧe71 6gE jlB>ziΦlkBS7OتeSPѱ j&tŠ H|hvޫFǭ? ]?i8{7R:<ٌǘȌ{!w:_ֱ?la8;69c5~m+ mS+vȎ;?aV)ر"K߱&1A8.Z1l˶=n [A.+@#)I+ &B0CY5iyoamtn?:@7[}F+f|'喹2)N ޺`X1'dOʙ3BW:q~cC62aKrTjY.ڄCP1~"`oOk&z^Or seύt_р{5. 럶fi c`psd㽮f\&`imM{Sp]2r`ҐGa~',̌(:; m^VC؝{h'4bNG#8Ҍ ƙS7'96XrMoKRK&?T4!2Rv}"= #y8\CzeDQ^ &[<,}̻8~(V >eY ~`015 6|ìQ799OulbZ'i1O}7sIج[{ѭAxֹ!~LϾŸHvDf~>f,lيZr+gnjiUǙt|Ւ~MB8?C10,$$AdVBl4.EO1o4ӓr'vxS}nSpܸ-jx]4u2$þ,`;p7sn06eh_a_p3Lmh=~7JyDD9ao[Xs1hP쎻rngz+$Aٌ]Vp1m;HD-@P'8x9 EY]4'D\\inYؾ?q1TK-t2|w>z,Ouπ?GYfm U-|-u uQ: ̝RWs**t g(5]69 ;{`zqNxaW(cxpm͒tQXݎ)h,/DBc~n_L10⑩Ƅܜ$Y%mVmϙq}9A~dk{Qvu_#~tWvFvVLqτhLN4rV́Utd# J;7V4tǰ-dthu6f Կˢdy%aPL[1p2q1&򢍎g8sڃxU/F54;v, 2ņĔc9x)/N7=q<²86vX>]+)ӿľ&ʧaiYOp@sRP BOY#v|ez3owd;=K.9YQJnVs 9 p/B\t;kq| xIߘM'IF *.Pxi+8쩊ߡZ_QM^iw5 _b"~;!`w?g{zGʔy L[͘:vuk'KN wcSc$7nmϲ[ͻؽ%9qW^xTi1M fㅳz:c6ŝrάyctS:vT'J#=t 09 ;cT/0ONcD;9+GNcoP 75|3Hu(Si^N,QKpa,lS;?G^ 6|CL!rQJA81KZi:TkyK=5hw.qep ?T Y b"3JJS>m(gXBk!UBcV8mX3{r{VazS:' 9UZZerc~mnL?ÔC8Q-M>K;"C>/~ӊpjW'[֒‰jfVt`R,=Ğq½;R/tmWkvUhQ+uX`ڷ x.NJmY;ά {eKo),Ԡk ] \4k[] qZqwwwww%w7B` {pw^NռysSEAmww.i7p&+Ƣ,^&{ς_ D=&k0HgQ|Uz|GBzK^(AjI%tS1-(<80 /$htOYFllοcXJ>k@^[=y/[ gCĊ˾<N}hC3Og- ܴCkp؊:4&u^sߛc]Y&E˚Dn{crGVj-C5y3Uq1ʖɉSzr̗Sz2ԕGt/m=6WK9S`|<$9 ?S=IunF*fVߟ k"4(D˺bSzŸ)Qh5 Ӗh0H_4C1rb~an6[t+濁%uŽ%5X-7YSjfz5o6ᰩ3ڞ0/=mXnϿܑrWM][„kwkU9TB~! c{w4]E1R^cx~/s5x4v~ŲطFGgo,;Y+fB摧;4u?˫c7jJ |SqҴz)B\88[!#6!cGX֙#z*FąLRp*e4<{^¦Dn%L ;tT$'gHy _DJ8opj1I&Jx j 8 {:cݑdar)q1OIY!Ӛ{#i;˸yʙUɹErN~G{[1ȬR*䀣~;i Mvn^;ѲTLx]Ǒa`RwJYT9o6e58ãxn OxMy-w'lW?&a2w1&l/Kq%~kŚWPrƏU> ]2zN#]'gGc ?_Qe{h֏]iyGO2G5[t7j>]2U(8_UK3-xf/#DB<љ8E_m^o~ 8fNط;ZX9  1֥tږLhpk?W6 A'ES4Z6lo0ڪX6Csh`ݹI=C})8c1wofggMihZއSL{([я[ MmxB9Xu1w p7[ZңvB9OC?6K~,TuAc0Ub2pW/ |Ԫ[O3vas R<[_Kq/}Zo5NucF?~n̘71f5?;xl-D$*ȵ?;.lĽ)J1UPǏ'q`?2o7G<l|&M^{f{0c/I7Rc/;rXc4ѠBxY@5.WꌿXXF)Kc^%h\Uql>Րsy=/;srGkKlɃ,Y8ߔMyz1gv!B>-+:5hdΏ?{&*Efd5}0uw x״XrO} nc0ކsmW> T<(UMG(/V"ehDŽ PkVR#Hk/bR7S/uHIUڈ7FT1{Ol}2)JA<9H$|/|g ?N11򗒋[mNB|v#~FlĽ]_Ҁ Ɍb~)i1箔n|Wg/c}d9↩zÔZ:ҰoB8gD+Lx SxWZ#2Ȇ+]xcϫ"xs)cHs%¤lWʬ8#RNR_Ћ[t%Ur(xk5e~ܘrn#_O;_&/Oݜ_7旞*+Y%yrdWrcl%3K }9oZ66E}s %=|IW4CM<;q7O:'VHk"O1x3= !鲝A,~[6lL<^k9t>~EO*g|^W0zM1zNjb8&"Svac(o8h \YQho5|η- HT!#Q : SV k6f9N F$yz0,Cae]+p ^m+!^,v~;%]"es%|%ar&U%)kӵTO9MW9'Ο?=BPwoƸL/FRns|([{QreU"hH-*bL?53ܟa&TɣY2VtQxor#QW 0#u5iaBwn/+KrޒIyZJ9Y&1lV\߂v<-MLfó+0(C>ގ[0X?O1H3 G)$G%!}/[ '=V~4 1xq 3g\#` \u 3̰ed?ϣq0ٕ % 0G{ ")Yq' V&j|: ;].UAdƘld9-v*Rc*]#tTPT52 tdW–st[*oXcPj.WqA%onҽhjtw.4a95"l5߉!ߝ=K]F9G}UkzcՄQُ1"9ܩdO>69du Nqn"g)'y_ets$RSD n.4qd9O׳str/JG{(T놢ӯ0F̧~yHTו7%hK,|ƺW%4 z"s'MЅ o{>D~^QI5{p婈gPhz'vAϺƛoA;S1tc녞b2Eɸ!JȖ3{Rn`wЁW8ӓ;kB8$ *r0,#7dz[2W#wg1CbNnzk1}ŜϟmWc*HG%uYqEJHBWGGJT`X+;ƟiǺ09;Ih)gVzj]A"cMg kz1B4W/R/me6V,墋R֘Kv["[,zU7xw!eu}x6Eo֓}W0I{ܜ"aka>mV}]68t8sЇb,\k-,`c=RP*+z'! P# NEaksG %ϿT1\4h8vQ|j+5.-{.毱A,n'a< {[¼6cg:u5~5}X1O0] M sFw+_co )IV39(|ݟJ' |xq7>/aR6bĴͣF!7՛[ݹm MreױqgwKq}c}֮FExN©i8u7kM Q zӤ}.4= +R<FhCymkCoˊS]A /A,aBo,Cr *D"_@d(hA1xq71wK@\ySF96Eؽ&tH+>r:]3gnKO F+/> n<*;.-zM+尠O'`j`򲃨MZhk-prb l`N(b7{]k}ح0~e QP5Ay-]?vaEl/"<̍b^Aw܃]ŕ?*]8؍e{ig6fB>/fqA!ՠۯ)c5x{_[C?fv@ߺ o۷u3_Dۅt_-WϒR<) q>f h^Bg]r̝jSstb ut.ln.gɿ5Cm cx'Nf"$)ŧ90$ljWgs5wj~Ӟm%'}x㼌˸6B(w)gqH*)LBWR^qbi_>oB*Ngz}baFTY(&zq`o9m='va 8T 5bn\:mf|1  _鳮$Z'fsx MddQ:pL:nbYϡ;=n"/+1c_gP0B>a䈿TVZÛ˙o*}3~ICڙw : ti2~P%T`c.ԙNAÒbXH9EY$\+t8 ℜbXS1&I ]d<٪Γ1ևy$ՓpQa=9ٛm_ Ξ]8ԉۖ9*l{KLx-ДVgõqֈR!|OYZn_2'4qIel[1x'dI%rȔ:twūzz͝8 >bvF7#orNm#e@s,jG.te\7ߏF;A3$|7*]#Q3ņjo&jc/T;:&א !ao6.:=86ghYt} W|y숄KCYV"8Kץ"n<.g#1w- 2'_6dt/刕"9Ʊw\tΙΡo޻=˕/E¤0%V9%R䦈&6 o͍tWkIMd]PjqMhsq+vO4Ofl1łKuG1LXlHtx±nr8DpvSľq-Ŭi7\t^]"NnՈ=hu͇폹1ԋ>bno b'nCZm:cPƑWx1u\?ۏ+U>ShqԌ*!`u, XrQ+X`S Vr;fxet߳g&E m]f FUT<4M~7nxs^A=&€XW -#= ӇVBØB(^bXʹU>L񢆻7Qe,xW2 gd7S17?poxyyEY͜n-kK3c\O 2=fr)G{ }_ǖAy#1FC]cɐFcuR|)0dFoetIU60;{'d 9lM1gʆwg%\4V!8G ݹX譗wTײ\&zS<ፆ?2)$ @%h?9sJOW`PLuQꖚ4iA7ZMUH;AQܺM\?k0_BShUqq^u۔)Ne7L߭e1˸)DJ,)79)DrO7Dl?V2RfO}.Fʿ0W#7 36anF<ˌK/[3 klΈjaAft [5G?lnBK=ֽ7΍ qvтMŰ"<}]!z,Z`CB2эIiyEN+s"0Ă:5C'I*?%B,Uh[jInJZ(p€$W*6˰¶KpV !5KY*lzY6$Aǀo" ?\#űP[<ؕ_{/ff؃x7 z[¹#Tϗd%\=K&±.<*`Bc_k.ϾtQɗ/\)mBWή,,MhЩB{q##d1,ϊiv 3$:|陆\cVa~CwqzLcvy*DFU|/6{N/l⬘P5G=t, ՠzYԃ_򭝄s$vR 纰2Đ)Ι(NBt [~`Hȅ~;"]$9Ոp+Nێq9*d0#rv.֞9:5AV9ԇkDl#tт.9E0΍x2gk7rbUM\y9ü y5q%y;)d (Z9ڜψi˜ckP=VWaT1zbdGn?XJI=yXSȲb;2'ϔh@>9pڜ*1Xx~Na.юb$2АR ~9FTqO &c,,Jȭə8ۍo!/Ukn_ yIҚfXs‚p%Sv̈́xnŨiˆM^|Q'gyf?ԓ: {pkK+pb'W&"Oͷ99Ғ.jDH"[%g0|'~bǏ8xQa9 ;jr0]F!MZcc<.ۃ濁Ro1% j1̂~%P\C59*\t 8hkշ2וkRG0_ 5d\*cdS wz`K3^41s}jij*DT ΀Vd`ȇHOEG8avqw&7ӧhoᨐ:8\7<)d2M{Zoy阞-t9ce?ol&NKMPx 3r1OףJ<ɪ]@ ?Ȩ)c[wVM6՞,yߔZF5Zݞì-Q / JnH9N>{x|/ճHP9eK?#ugx 6 r\ЈM(|ЕSpL+BLZ[#?!07?{pvx;DaFI*+~ Y}[vᵾq6긨 GH:^l#>o^4v|ȃep N)Edl5%bǪ*F{Mn4B݇E#%y')#D/bHs=:ߑ-rZ[M>,{]&f\^wnjN(Bɸ; Dg*BnM4cm5 iȯ\؋|8OǁmtE6Ãq(J@ELuLTt+${rG9/i'ń2ϿհQ-`q J&=CA {MGቆ -j9 vQ3 q~8X2}||[wh-l /|Wj.>ga]Xdmvq10\ 'J>[s%f+X#gHn/ۗF:^ܝI֍}8D%Ow 2 QZI1UŐ[h=]4S࡛ R1D9X~&^]?-3v5"a b-%Ay.a'c!K wJ[jw ӅrC%3Θ?~W=.:\0 /sUMy5xl\=_ps8tdc-a6}>ZhZtX^wvh/JN4Lmⷾr b`#C:Pwgw0fpsUz\AϹ8RkKQ,wTIAD`CDs0g_%vJk\y7q/_q ݾj 57,fjP 'OÎۜk1ׂެ1tqloɯTgMe%3>%%y??rCo}ԋwEgE#r 8%Crphb+Īiޡҿв sΟk̵a,s m=2cqSޙ }i/&QKMelZ֜c{(zAlQ83 g?_ŇR:]^@/j!wc5ZΆ(:9(?FCp[UcE!UڼGn bv_zv|̇x؞;/ 4QA*0`o~gfexE*RΑ0*'z˅0΂b]8+ׅs)~`E,1d;mVuvm.DP1P0E[uIH09!X$CpކvШLx aQ ZT)*!eC|1߶\x<߭pJ_.,f2X(Im,4qnvi/M!ȷ}.nЂpÄ:gQW~|FKqGGCۘp Kfs\07.p4 {|OZqTSɬIp;n`Ӻs<Č0y;FнmW"FY.3z=?9ѢΖmZj}kŦ5LR[wJeɁS<I?kOx<`NuLu|JՉJ`x@:jtEwA, A %Þ[j4we/J!"^u760l72`q#\>)=q#*{{ nkU~hG :\Ԕw3=ГFzh'?h}/[^(1em(ŝ8^qgpYsὲ'ak߳*p[M`BICC`y:/0ʚ8GZ-3giH=<a|ԩrs5lB8#> 4_|-7 4hs+`c<"ǥ ?_Ei="SiSSs {iB:#jgƓF4ɑ{oe6>=Q1,u|NS:FjI/gu/ߑY +pm2k:2ݕx{]1W}6-Z)luzBg!:| GCQFPW&f!g{(btV9ʎt#?r)=ūx6G[}nש{k篁B^ ؟'756Kt٘%FlS}l1HƝyt= ~zO gۋ.ƙ=\̹>Wk- S?U9NKջj6ni$Fcގ:hsq[L  ˍfM8KWp$d,k>v >swxwd(VU#a,_ea|lꔏ7q5 N76sgkqnFz,X^63p+܅c<쩸~">W 4$W!q-L˟ZucόB-f!fpTcpr{vk0y= l֓}l?܂oB xm&yl>Ӭ{oK܍;rpH?k\6 ? gtfK]8Wc_Hw,[]/<*y?dbL\|qfP}Blx4jF`W^{>.~ MǿEwocFQ(bs?}h_͹]o 쐴M}a4v[=B'+ݨRЖJ@H~}{ws8[XYk'V8b,߆S7bhm>2h&raK /@/=vJzg^|L!2NO/m{m}Z勆NqA/HnH ;gIi*5Cر gp*&JaUl%/yX<.HC6`W|NJ8 ¿%bY♤vdcpg?2{~gx)ВS[2g)x2a.5.wfte×U!Ë]-=1_/*yV~ҷ 1(>Ǡ恷̠ؕ|L í>݊_,AJ5ގNn2<aו4~B02 =#tS9-8zi?V@q~QTYq [L_kv}Lqz7FƜ6k\4tL`ȑ f[pt/C9H{h:)i;!07\Exiλm*‘3GִcWaEؗMGr,sӆ_ifL# v#cKi$'ц;ƞ'2U&Ga]AOqv,y'@ |0u"L kjPx3ewgش; #."> NRd}sۺ9xw+CQ}-eΌ=lДCML8XY : Kބ-YB.Z1LA[P6A}Yz:Xn0ľ ">G&sf1L(.RZ%e_<{ǁ6To6eza|D:P:WOpi [̗H> KGk' :Co]x00^!èK v;Z*v tiF{)Xq&%÷zfmqw{1]s1Od$+0f1B=_q]bۃz륣ޅ1YhdQ=ډ]8k3Lh;LF ֞GlX`qYHCO=OXtkWeJUG_fkt9ֽP]oϰlۿ׹}V}'ٯtۆ%â}\xb9K_հ=l5=k/vPfx!,lr W!0i8GTSX=/i@o>%޸l߁$q,wߛ`}cUeG? vۭXg4K'l{m>maG}~##xh!/ǡ&ex0% OgS&Qԗ`Ϸt0{s] :gw >{xy+6ʝF߾,_nC.樚GD-&]0N`u/Lnr>06Φ[ IM ʪvoGiŐ \z0S zoi 1'.\Cٻ{{ZC,JtATLKC1:AwsƱ_&[*oޭ?]]2ZpBMp՜ g7}}XpVܖ6mZ6Ch7-Kt]=i? c*u8pwlEfҠ&f}Auվ؆ cdu\J뎥PP`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[;Sc*+ ^л~?6]IFΡ>O;Qpjxcß5.4ѯ>K鴳aOaa[Qul%R YOF^آ`<+ ףےh_Kkj5tt7quozk, dY=E=*o VOVY`ɅG. 0Iؚ 3`Pn=ոoVvfކ.vntL sZVnxjYא:Qgl0XQv9zau>?Ῥ77R4_p:S? i y2Cq0E݅yJ!6f9q7~!)v0_i_ַ Qk/\kaz5L{/cgt=¸&q3 ڵ9;W{KLVz]w ReFk@_njs m:!,&}?Y`L3gҿA(%MJ4e*XgLS[F-ji^F1}t{U(AN㑋 RZA^:|k?Cm(oU!73v ?b o{IMA#6Ԣr}|JaWX=aWP=2 bw6=GP6Ԛ)2ld#Kg:r3Gw’ M * V@o?a15~]J>ˊor̊nӨ 2+V9b˓v|d˩};v!o`Ln.- j;?$K߷0M ǝ1[lnU?۷8);Ky SZ,cv.tiklYv,2+X>z)rGd/opbSi!\Ɂ*YE`LOkx :FΩ֬檤@fTѾ΋$l~,UC@i,ym,pQvluØڃiRk{WXc̩MM&ِ+Ao)łQ? nq2^,%/n\J>SpO4{Rri/v޽1/Z1o'p}9wu3y+87c@ e+X-ՆQ#U˺ݹ*Sή K,~-vt=bd79R%;+Y|;9/Ht9v|Kir|^i8pdXHiW]]|Nsh$v0cr.Xi;@Iծlۓ;eܮa%O/6H`kф!h})#>9bz2htc"E{`qaUqYmQqZLQf+Ur|=[M5Ӄ,R=%cGF5ONɁ\b|D2gT-W7q{;'C;jS)}Kc ׫"t|*K,$|(Yʈ͂Ø%Fs93/K}3GHgKoN_(\唌ח,|IX8 ;* A+ %褧{ܭF 6~5|KZop; Eh!hbxp2Ԗr^gVtR6^kNҗؗޝA٘}7#0~[AXU>g}׏w+{ Me\„ `3gb^sMaV0b_=>v/uH?Har;0 1&ҢXqf7L:_xى̨xT 2~!ao4qZtݕ.(r~- 1lSp#./k>6wH-a[4ZlF[V~fᙰn.4xZz{.d)亂;[pM>Z|C%d,drc_LWjnKI{&5t ,r֑15# 5%o h*}r͔(ɝZjX/˝U|Ły/ʞ*x5[]ICD\>j<5M~Qs?o5U1n3ܖSZfF6NCұ)Y7TWY:bu^?˰F~'~95dC#lj? -Ud 2 ]JO1aeL<?Q!$ܶT55du7T<̾>C}8` ;Op<-܋/xqSwvʶe,x_P:7h'CK\Nw/-C% pY˹=1>KeI:𥢹'WWa'ܒsgV3_:FֺQ2{xgx8z N>a A,Y'A柂kYH"̿Plxʿ0Ti äjKl76Ѳac{vO\ř YP_Ccg%mbLtc=*mboL0߉6PۑWZk%)0(s%Gl-AC{Zt_F3;sD:pgPZśC[qMJ_ss7 05_ٞ͝w(Å&n|̛>5\eV%<˕Gh+,y.!u=j#K>^Poyrd6劢rMp'|vJN9ÊV?0K2SzNef{a4ۛ=՛]|ǛuJew,Kvg5]+\VJ}PmcP+^jKÍ4co8i-c}#cD{vb'Ihߎ=7؛γ|m]9v'yPޑV\i(A|[|nSC */_'C9W)/Dߘp|9AΏƯN,K!PQB4whK /wPW.Z+ƹ:mUeUh4\d\b>͙NڿΕrK ׄ+AEߞ4oe]̪dUwyk x~ub@_l]Ux3_q'9ԝq*ʆPRۉ%o+s_Sz?P5wr_;6N"LYG~_(_*+VrA/b~G_^7XTs]R qp*~zw7.< ֯F+WokHKo-o7jof?wXVy'֨1-c9J'}˶  耋=;3Kpgԝmo_Cs17&R ՜xo{(b.ןmF/5lKÆ|88̘T ̰.ȕGR8Nkɹv-Xh+a6ܑeòO֬8VWJ3ڞ>tۈ>}EN2a+|1⢜qj{mwy,=H67erhUB7~gu鮦o]yŒcO" >ܨc9kДT/ l21q2VLF)(]߾"a?Yb gm\{I^?pA= ؂1McT9Bl`ōNT``/x9s܊s̔,Y#О5ڝ;OMp1:, 4:<릡<5nΛ3T r*n<FIh)pev)Ѻc˭y]F8+6eIE(+y_[1B4O"2PiB>lW#D*T[*rP6l qd^|a:}c:3j>Hq` WLUƛ].4t‚Z&|O>ti˩ǠN=dh{ & ncM,S<ɈUrwаOKN sں LͅsO{ǦzS~ƗR -;q|eĐ(ru}x{ӛ%Ji2nid8gٰ%SFSY:ȟﰶm CwnZѕZq^J.ʃ̌5szdMP{.X<'5^R[7M5 -+lŸ>>&\v(utl49NFؘh#ޡʗ8vCr{:EF]-mݨ8 7[KV05gr܂l4xӛ2`&a:9)_W \qnid;Y߶,l듋+%ٙAvj;>&Ɵ-n;hg]haOR-fx0u;sa# 6rwp)86*_w3sÁ?0? 2q ڷHXYٙKwe;ߟytdӵ|Z˯Cٿt%jFD6>|CZ~Qr:?JNz{e;ڕz cL=l tx85#Eox1;~{[SCsq_zp3螀бو)݅rt2} yU"%xrI:0}&~|}Qn<^גqfhW笚Lq=m97Qam_mC>yFe1DB뵥X7*'aæ[ B؈US m /[|DjU振dJӥ3a˥Xfс/ιK5K*p?Y3?aZv8?rZM5ckm\;-Ұ;e]s?^Iqs5w^blgD-F:m%'E{Mg='2E!K8u2:Hi!3w#s 7BS0ڌ͸LG\Ʀ'%d>' EX fc,qN t-2kqYoB2/ԺiUsث̓j)xyh/5lHˍZ{0GSvoT)HY GVqd6[=C|.dOG$DUu+H"Y5ˎv۰09o߶ [PP%-ͼ( [1j!9̟vҥA ǭ d-c`Z. `ijq pՏ[zqn3;AG92)syu;*0Еs;1Peñ$VH(aQSц4;n9iO;=U+V<%˟E/4'd%^UƴS:mmuN Pϲ-ءȌdbQ>8UK+\y nڍf+Sƶ|_YCOլsBKpcO,SH 5{rL=**``O{hS&ݍĠ7ѵq/V/qD bWzXۥEņkbr}-〶 v\䩕.l3Z®<͋_Gy7_UNJQ 3hV7؟iX{No< 0c_0mn~ΟϟkW3myszmj9pdg)c̛24z [x?}Lg~JUc{οm~׆nE$S8&J'OioJ$ 0$ -G1>?#-KbnzaaVl7my%ћ\jR5F˙LZj&2nIY6P^=2aO9xZsumcNX~-ǭ65 F61f3x,4#`Q\&־,AT1x/s%,xa;&V{.1W" }_ G0B"[(&E>ʔzos>\d:G8WƊhȷL)7p%^\?[NUwhe ee*nˏ|^C!>W UHS,2=:sP9hɣ>_ۙK%lz Qb{Z&Y{>ڮ.S-))*ìX46_ii N(lz>cCE8A'83z͎q$i7K5M^!C.9f /WԁŸg NAW~⯌3켓ZiKWܬcjn1dEOY:Xa+? #x~7hX1Ϸtre> Ҕ5niPMA^/7EŔ2 /ȁ;lG%,tbĖ?[Rpk^.gٕ xSУ/4ʱb|Ik6>%eqRN!c9=Z<֜e[̸V#ߌX[u?58C͖Moch_R6ՓJ;Zs,Iuy Bc^+)QW0xѺ}󽸤+_t}ng>ܣS_z=[hّ95=+@'1l|JAk gкK:._z)z#,ٍ,ypx7MG_xdUyF?%+NUvck iy/w?7gY\6ԗhÝ \Y+{-T&|=5{<4lY=S?El-¦98ׂ$(噏 ⚂n- qr\Zh7hmwOu\^*6t&_7%#IR+F2Kd)73a1r9Qn`/Z ֱN8GIK#\'Us+mQfBM!VA٨4ɘv0ޑ[5] /Zymol3:ޏߌy)ٛ[gr38q;6llnլx,X CU01Dd.}Z spn).1=tka+0S.nfG"|NBøԌD\/Gmf<0X$qfHFjK=4zχo8? ~~|_G=9+9xrn=9r n}i|cS2ݔW8kT|_obG|Yh9Rϛhφ;GI3Qe+.#qw[+Khqc^s.&k.v㗛b#r$,.x <&"t{Qjx~S3-?++!ׇSx;; +y ijcAϥϴc9bz{>|d~[-[hEqZ{gn'cuV\=v-SaK&a"&WmkHfn:?~i͚WxrRSs {aA|*d<^A6 o0a'x0e;i(Za\n$-clYʖH֍W_ [M)1xTys!X ]Nt٦kx &{{FOSԒ3@>lۺ0pCM]sWH+9߸z3>F/CJ-G4p{wZOpb9~6TƜ}/kHQ=3_/2fc>  Zgz?:Kn1 tf\F'AŅhyšJo=@'htuP7ey+wNt )/j8) o;#)=L4ԜZ;;/綜Z72\V ᶔl?2q@fʬ CK*a^<փM+zdߴJ΍gɎ?ɹz -l}q0O^ ~}|ҚHxfENXJøg/Sm)*51(đ=GT.ȃWjǸn/F~ڨ>KY 8 ~ԍ+ZtZ}a1&`L͗494 τ$w\':&CA={g rVߕY|-ӰMVAeJ_Y<ұ**O#Q p~#]W!Xdmׯm(TEK;k%XZ,g }9qzy1<"'i/=G7' ~|@Kq4XJuӗ k]8 ʞ8لK=KGWlcG=qe[\Ò!?,O{v ~Ɖr$7Wt\_M? fȶ:JŬ"ki9.ڇ }8&ȇ7[x'O/O\RS^Ly''欴Ng]+s.{. +7Oq+k6۰! z<)Fy6cQ2j[86f!n2Z0ƀ/ {WX?*EOP+e9sP2_;R~%RN(eT)Q7L.BY~TwGdwX<[?z\2fF<6_8tetzBf:Xc,曧 $n'ߒ3|V*䚖*Wū ٴ߽ߣɫ}ݠyOb1acCn]jH!XQh;˞;) a?_XrXg;.H7F_qHʧ#d 59}/`M(|No!֊fߞΡ&">TI}T2k.p+'NӧLqH|Ⱦ/QJPac3Q31mI.o3=< >SК؜~:}\--, =2xk7?Ch/?@k\ 70a&NE[zRFz>Xj{.KzJvSQ%kysx/7\pK/$㲛26YC*o'8&ÓW=E2Ӯ>kNu~`5%Cn `̚rSXS}ʚ&,31d8na9gY l6ƢI[IC\D-DR/o%rTcr.{FsCj& sa@%ߝٷ}wgeQRn*dO)VزNw)jvljw3YnLYSw3c˘`'9U%lw$]/DTW{.%scT$OĦF }˳a:M]h78AeϙUmõk]B7EkN[q*b@f,1H]*[@q̌-nh q~`@k50W,0f, tw?e^'ЙRfEhv)EhkSs l|͇~os-*2LϟMb;YY2 wq\,aFB)LK7Aίd\dAܯ׈uԬKIObuQ]} # ?𤯝3z\20k_2,xcһ0|[>!ol( w|aqV}s5 Fױv[0}vּ{]+;_|vl7;{ɐ6\y؎כs^}FD́ |5Y/AB* iHU&o̫rvW1?]A;(Vp9*^W2Us>2soP+]{21Xken [fJ_5^1iݢ%,>$깞ٚÕ:CZףIwL1KX1[ǚF>HS)wPxx8@}ݶo`i]Ϥ<>Հ|Y/c W0*D߿1-7mOf-QY%qsgs>@V*M&W=5ߙb^ LRɰ,%=Y" H˃DyH8'r.܃L,xd|5*FY "8~@mS[ 趷 @1Sk0C+bf[56/}5Un8d??đ!:f{Uq]YLlQJ]CjmG{gJq[5s S9|wK|FFio2eWr`}C.; G>1ftKeU:bfzyki Xŀ)'pMGnfϏ9ڍ;]-S]n}d*Oјz~ O27~l`f|њ{XqTC nGq>tպk TȕeNs0D&"b+_9S {'<419՝fJvVO)sR5R{x|N Uv'(h Jk-e2N6s=W޺V?ڌ;b ;Vѹ<ΖY{iVѰhjCaj/Xq 3txg9M'Z;ٲh#>&[vÚ7V`ƗߌXgʋF\?-S DmHUT̀.ҍmT(w-,@o*Ƀpv,.؂e$₏J&;X )tg=MS^t M T|ؖ+]+PYϏJS&baYUSK"ϵkP^A:L8%-\ș͸n9:tʖfÄl;>uqVwNP/^^_ YqY̺R.{-*棏k+ϥ2ՊE p1G9 Sk?R4J&};ܾߣWڐ)'q2BVףu9NN4+vj-C|M(S޽Fb e,۫)/QtM§|7ڋlfHEaR> ֓=gxޡ DÂ(%9vy, dESgHX`1lv_-_IMΈ9di6l؏p 3[վ8Մ|!wnapK`knkäl}əϊ]Y۝xR[ G[;J`W]@6a.̸5W|NGΩ$|5H%hkx8Y3]  GX1ڡ(ߐ4̉/N$XG@N>h-u c?Y6XTТĞL]ߝA֜A﨟s%-aȎ] 6N;mtů1߂Rye8ѫ҈CAw!QաR/ְOc <9ʅLo`~vQ)?3|l6f`#{ 3e'fޛث*㙫^̨2:|3o9_޵rcNe͹Ʀl4Đg֣ =C6vE 0<2h[;n˸KN7b;] Fqń冦\l(rz,Wr ]CȼbWHX)?\ZܽCJJ\U1䩆Fao-̆q5qȨ}Bj>1c,i2.=VIU+X.iRΊW1/UKg;FO`|A4Wf\P1h?H۩z|Q۴Wn߫) ŒSx^QR.;sR )ᮘ+9VM R3DVE𡋊 .tg,b ¡|7Õ+9xVH!j޷az(6JNU_e2bWKM>,p.gbMDCY8[%V!}~5ڵ)|=ZGd kG<oEYk>7 >:0MM!kѽgvzRak`"x lݶ9|-a"ֵc-B4ƛK{ YJ]T𝞌=Lļ\ưjVy7T7ۋ|dliĬ`q t_#ѱ!J楌ꤠ_#k=vii+s'{UW368a#g;"g#_|_*6b*$_':G:r/iHu'd[=FGl$KERy6%{co@/4m?"/?Yx:;&tf=-?Є]`W:R{'#L2Dd!iUk+sVs7f 46CC›l=WY JU7X6c<fsWxn?Hh  ŰWcb /C?< ?Ō)flV,MrV0橂xZdNq.B]y3ϫY8u'k]|Ҟ]}q DB}{lZm ;BEE{W &<=ǁp0TdcC/9}etxi+TLnFε*zAJ|fGai-7D-眆rJۋUXѡK8h7 ~cQC VDA_LدڜcXs~>͂Ҡ< SS(Sn 2jt:~7*g[ɼ5c{؋-j*cTGŋS|UIj$ ӰV=J9  ߭om\Ȫ`L?ӻ-Ó0'f8&2稄gn5{qΜÁ:Yqg _ԡOu vW}azW!+[\2U(=cطvvv tX;U0U2yFdACs;>tT|0_!=VT'x/)g@wgզc-h֮Yop-yzl5\_` 5"6{ =*YI̵qf%6W[0f1j8% ~` >Œ[{ބS^C| ,O{'#l lHE7S*k-ъ1wMVQg"`K1:b\n9( 3ai2DUy(P&lj% .Goý8s!ŗ{'b*0cJ^VVS~xWcl|cr4 ՙ3&v1a/PcψbNY.3 rnugmmC/)#hnbCGl*OCs KjQDcQh߾-3}}s._6vl?؃UdtX` ~Urn|#*UəВ7ӧ2 8SB\8Y}- +8$^}4Ӡ<ыόYMLr%WiػU}I4 ׯJD&)cddM Qk÷O#MG 1͙Ǝ<։߆恦΀WbgFqa.L`k`G~׺[| LŸG:fp%7tdaRj(#eBw rzߢוuXr*N=b~G.0-m0EgǮïHI25zsφߛFOl\T'[ygMGla vP@#dFbѪӰ׿w א{??l8z.t !-ɱ%W`|~-Z+:Y>X3bu_h .N~~СG׾AQeXoWjq#ـ-,8oGZN} ˅C 4hvfߓ=3>E-ѽr);χ뙰o/ƷY(OC\OW1?{d'yzOrc)=hGRki]8+ sl?f1'&5pjF LaX]~ashQBMOzəSI9G]9mI)%fgd4>a}`Ƣ刮S>Xo;> Z!E/i›^ ]a2v213?0JXi8p .}&0{7`D<@(ض ҫq6eH_?\6b D =ca6Vbا$Z}NOmk==Qq\ >X_5R¼Xaĭqf βy'O7T TKz9c&^Qc/Jn(r7H9֓W`qB<?e+zc-uXHX?/S&}cW6{,Ig0_sgPdRؙjYtZU xd6_qN }^* ==+r+70좂n2Η3{4 xd%ۧ+x撂g XchiMהCh0zǠfn>apSv>\ ]8渚j8xoaĞS3#d<^EVoÅ -n`3萱G`m  /صjzf`t|MXEep:aNxNnph_Ȕ\q&o iH:˹Y89kZJnd1¯S2~W hB8tXCe|#Z7ܒ]'=12:U3(XTFΔөJɝTlH5G\.{ݚVk9Usl$lpU0(Q)";1sk\+V]9 sgOqu?!ַs85#pi;? ʋq gSy.}h^ޮ/ OœJaRv^cΌhATD߁5~ 퇑zr?:a]@;e::ֳy@]؀>6`|eşq*yws8!(SqbG~pA8M;~ r~!fv:v΂m<1 FsM7y蛐ISpE?X~ݵOѼ(U1SN,CX3 N˨_Hj<>"xaߤ`WL| a߽~3|8tڀ9l8񱉔j~CG&*`g*9卂3eKv,O‹`!fD¾`Gvh6h2 ڎq,tv R+u,,R) g$|^Ξl“tA` _۳JgJ~UqW2F}Pp%Og)iD~.jǫLM. xQ5f8>z * 47XۦX #xa?aga&|1*b܁T;4[uCz$mRŽaݚח֡\B3D4 qILk}3NBGۤb4l=`7 ؝ YX6sеqM:Am\w څM[̍g16`PzTEs`U.bg4Ta+:]JGy_[ 07.|/Ų|]GKrj*QrƄssVqj)G)J꿗1OWLG/)sNQ4Oy$^ Q{z>Ym<;:y77dpW*+1'3^=Iۑ"L$l ,dL8H >&cR)_ $lp} _N>GnOslM4‰?s5[Q8G{gnX={atd#mGJ٨7Z{Uۈw}NѰ"ʔ4'g9ǭwX^YG.&`ބ;Q ohs< W}A;qdOL0epߝ<جH7q (|>Jϧ}V;k7Ĕ;}z̚XB eȆu,ŸsYPm῰a#*}I=sbܿ +!_.w$]ocOwָrӦ5Н3+GU|[i%\^ı"_jw'y 6c](;ɧpT][&l3ǜE,$9+^+8x2!ũ2*Ix⚘KKrqO$)D1?Z6R>/z) dT},crTY%)r&ɘ'gU)L-vٵz/O6AX9'Rb``A5uė!AWՊyBF|!%{wqCaQnz+%V2a{WٹĂ p\N! a<ߡxZaB-ƾ}"^J1/Ȅ$pކz?(J_' , 9g&ˁin/foD5F0#ƌjjʌܶȌ>s +4}%Ԡ%q!LRj0u9zz%cTlI9^"QʌRy-ެ1hR.o,w)cT2>tW>%}z+yRA' Zl3࢜R!)n}?0at_4GNy`]/Cpfd0 K>û¤izi>3`b?&{´G-V:7_kDxS#~4j /W0%Jal:Єt8BSP圁$H-j$p=4Rj L؃z+y!0vm拏|?Hܩ TYf@%9qHGyqw>fgl)Y 8ĝMԿԊ͸ ͺCO#=2aY9UGx+Ϟ}7%,ScU QqinGAzs5a<,}2b"N#O0,~e'94{* 9_(h6PR gvȩ Prn){0XG2a&x=4@qrSr೭/<.-0B[dAxe2Lӝ ~0^:'``Ky͝1GGj$O3adG{_ afJWMoWy3TJIk}{5m)y[m(ٺ^)NܒGMY6Ԙ;Zqx Rx;סa;=f^}0Œ}p%L tS{fh{׆y n~` ,ƀjE9EB;_Ovsc d&OZY1>rn GczpOVKE1+O (x 8'7`' W.8ꇏ|1+6.;;VxC|:@|zNsP%Oz3s~1lro~Sz1wCk%W.Ns-uȚw LYkBqP39nJU9-ќ>i\OUfn dαj߷2 wLx+~ĞD!Vr%su(tŏU,SLր#U|BIi+9񻻊Ja/~ b+p{8}])i+eR6.#~2:)cZ+%_ɜrmX36ވzp/CN>entifL:n.T#s!(KƤsr=qHĞB_nS֞*jרx6}_Y +*p GRpNK9e"g{YʶM<7ˉ7-Ӡ=3/!?bw^m렪YSqb*; ŶV0 -19CA_ FŌeA'=K-FiLw"Ɂ$0ܼ NqoOK1溙:|lWSbӛt鏍ߟ,4YvC/\=)݋4LE:MW/NR,)H(O]#o?OZq {(XqLvCTQp7ŵ v0RC^:F c%\UΜPg@lԎLdu<5[Zpp~Ҕ]uyx w#`W ȟ(ěӖL;/w+Y {*[i~y.*ԅ|}0x[ĉc068J"BqHiu1 6z TߘA1}6rCCfN1pT7ߛIWs2.WJ:G(?WiY*>0XAG\+v@PѠ*\pMA%lc*bvNJ.gyʁvKaס$$9?HCxfZXb\Vb:UɣĬ"9N=gčZG cH[.vBkalS3mzZOý Wprfݗ3Ycռ`>56Iʏ?сBϽg!L\kŘ9mNæ̨cJ< g(/]GwPTI km8=yS%w""=Νrgfޔt鶽ur&,@ 9<F9h)Ѹ[.?o)ĚGlBS`LfcQǃX'~b\.x*_[ޔvmDo h%}/?Wq /75p3793|+OwgbG|51NXlN֦6w??b_eLw_5f"YO^sx7ҪЖ'Y ܈_ xn./Ǜ!ٷY+-L.  k&q]^2;^NQGJYC8YN=cC_sWο&&1ǜۺU/^)bqgh1#ō9 _8;_P-%ƪ>X͚t9.qbjNUL:;ɥ{z1ʘMF}m*b.{$y0;ɕY'6^-XVф+009Ү;d/cqgV69V|iǿY1֌w^qQ1*oj< :4iYEatǔ[r;޿B+"3sG(ynje/lɐ|'p}ؓ_ӺX=wv0c;bU'6wp 8e8=8 1}C˴8?Hȼ)҅"(ƾRpAcP#&zq=B];)p+׀L-/\ %UolCKz/4SWtaxd翜}ݯv]_rKs}R O^"Ɔ;ˣ<ldb6 #RkpnZ2brGd |';`ݻ zTsAdмPᣅ`Z2oe&TM7aXWl.Pۀj$WJ 1f Qpw.$ 98[Ȃg 4y{#-'ks,muvq߭][®A9FC>r%C׽Lf[0l3j쭑:LޫǀR'mAWP Kan$zz<PPJֶ.A V-PXl8s d𱺕CU8T?_ps e~?zx\VcS_r2 )P[plsU2&tcg777|uo\CE)19+V<іciϴbJ%W6sayR;)6w  Ejh,D1"ޱUGNW q=Zl4ྏZdLqՄOv3WKp§ =% 535,`p6~@΃*phipx-GdЅcG)^kZNnkFu'v!% 4: K.1fF۳xq<8qX+EOD/m0TuI\S(ӈCp@c'<㈐ uK-ݷ8`n;Jtab ]9RM<|@ hQu6C2ZiN(ybv@4d4-Mk퀞vÀ4V2|MQ #zI aLBc%[Z'^B5WgPM6P =shf h'i,9T$f:С#3C)#f"zboޖ.dJK7Rhv^3-Vz f_"[GZhvdqW˰1Z"Å7L9bE WXDF mnu4~y:T":}/p_8{@q=ϋ)qg\3險nĔQڔ2jHr%D'6nsK]%MJtP`I Lyň=>.]&iw]]03Z` l C l1Fz,cm-Vk"XU!~b~&)i%y̲D.%pĐz`ވW㌈dxL˶_u(KSad%E `DDhe) Y Bsύ|$$]]2m[w7>., Hs)Lpxf[U9J{i|Qֈ_`uf}P!WA:L"YCT^Oc3h:YLo7xFn`p%S bκSU:t5ckhNElwIq]vYJD-C& a CaV0Z"fl3Mk"qr9UR"u#em7_}?s- ҳoa7; iߝ"TgY=ݺ@=3 X=y0BgX!<VxYX9b顡Vr#]Ћ\p㌘]e0p; _!~kC3+Ӓcn*G~U)\ Y|kE[n*l~j{\F<0!uuX۬rl@ N=HAd-ʯ?=m>S-石;'T+~,so[bekuby'4 jLPgMXk}KtH,EQSX1'h_y1dDP>{ޮI})j_65쯡(r-F`39LcK|t~caTwP—6G!-X!ǣ@e֘VA [V`v錮-~WiQmձnٗ_mYH~QÙu9fݶM8 ?d,|ªleLnaF%ڨ䌣+@.(5-uĠ#dzn#zr: ㋷`>ƣbT5ǜsdqlMj?xB NJ0"MLw̱vj46ٝuGw9uk@iN\r}[[ڱ{?mC cj*Q2AuyՀ&LЧi!A85v`)2Ӗ'c _{~L9 \VA ,$(t0`B>3(IVCxW|OQ[CYŞL~kߣ~kj,53+x5=z5TL,384V#A7$;8rGTn TFbHCTly3Q"W?(N1gp/T*q)['C K[@Гa|ou K]#U˭2!ÑlmŎVi@5~$x͝r-Mӷyf%ml3l}8Qa21G(W-vc|t01b^A1iI_in'.Gu5[VE? |-yBy4=sa6-{'48PïtH)ZvC˓*iEI&DSg矤WiԧTߔQ{ ig^(bS>2 cJ=\э04ՀLe`Qx3`Ax[DWAf P;Xp7Y+L^gCPTR})yӢsfގ nH@<+R7ф>Z`gKpXV6-K\\;l+FGJQB25ZԀEkZ[g ΄n&D l3_ ?Ga +pq YwB )A6(CF -qp {70љEXhhЗ-:G?вqTu!ӛ(5 GscPK@Lj׉ai+DI'Гɥtw;QvR>:LUEGtZ˂%sZ/_:l. xR \Y·= RZC+F'.єghԐ{)n14b8%QVO{Yp\cmh%ưv*q9ѭ;1LOZi37 lq 76)৔=ݔHbAXӭQitc-LdOyjJ)s0FC$9"slaXʶ\Ca!n}Y9Y(pNi٢QIclX"V%# c,G9`]?F<1 𾨘F.zyښr>.H'sU;WAM>&KW>6/©_7JۑErdlWR2:VZb&$J4B;c/gh#Գ9ȽC[zn}6g,紕45^N!Q|AS l"6sϟRAbl%@ɟb|g#6/-an5zJ&ݸLhK\M=RIUL /7KLG/Jypz,D ;mj 7r;֫f-F(Hb\:Oaj!`n:lYoE ?CRqTN^hJzIaѤ=Toe ,O lXĘUrF0C+ٺf!c3 ߨP>dٱRdz!:0gc>%Ȗf 4QU` yvSeIԿ/EnV"r9KpFL?)m"l$99.H:nSCrslhkwf'eT|J ޡS 6j]d!Po"`x9'IJ"?#^3\; !eMtw!I5(j.jaVcb!r7p`A|ΟXr%È.*xx[?Ojj5X0,[2 L:6bAk<&An%*$6c_OC U"9l P q90C5<8@KT! b  ֏6z|f*l}SzN1ttY! ɂ|5z64[y2{qm*uʥ9h,:ƻF-R=G{E f4a][ik) `Rac.w>-$[Ee46EI0Ge0Kgb.Ǯp1'qۍ .h)6g!>/(1̟ŸV9>$\KȵW=2[FGЖ_є=ӓ Qԗߺ\xPOtETS*FW&S]rsGkPFH2dML>U]F}JN%W>Dkk9]kx¶:6udz7Y@q|#FF IW >WD"5JMb}pCJi2#JE 8ScU. W!_E=[>FW[#*"o5k(FZ=>dS،k_gG'ɸ>\?ԏ|(0ApgF) q(͸' HGV=:<`K-2z`5*8M)(ALliƇlZ5>v8G.P[ui" ̱Y|Q k;zuT˾}/7Ҳ%k:eGduHAA]EߦS|L;SX-5T3;^ %4ȃ5,4Pfm*4oSLK2Ӯ?nY֥OPjX#-aH>+œ* RtDcMeI3 UOʬ**f^G Y,ƈAj6p#&X A 8* !zf!6C݆zZMʂ)iqJ|mSN%/si ||ODڼϋn'r7M3!VG%.Tik|Ƭ/,ac ?$P, ϥ ֵ]4Z+U,XTݏ ѕ rJOrȸG7aMI*YS(6-zK`6Pg)>PA{ss=&= #jԎdܹ }FIPHOdUr,!o Ǩl\fz6bK\r43MKZgd5OƁO⫑{<"N͗]tgiP;c7-.8a>:43ZIG=-$HH_ƩQ2tbCveKE:MB溟\HKRe1eĮ%\Ysђxt k,8Лݏp0s5 N!хW IjojuS7/R`eo4}KEŭK@;_! jZ -"\QCGs(2$3xZaJ$GGZlԯs2B]o<5B_擠e&XJ)K){s]Iw]K;VM ByX]w8F8%<6I;M'݄G*i:Cyv1P6}!05&R1 :n⭟3ʱ {Uɰv NXPTRz'Qi[Ȱcɨ,pl:D0u-:E뙝5{ Rҏ9mɻ6!Sv:}lBDDp"HA,o'_ Z5׭HbR,0cY=Mi4-9t .K7ݿҢ>qiY=lANhTh(Fhǡ,œR P`@ <^ n2yuC` %Fx=Eh5\"D<VGDHo2-C\slnm.Mᖒ¨Zw`EExyD术=kIqt3o0]J% ƩPomĖ:ԣw,;P:NvX/0RtUH_^"sxՁ3SX ΘU%NEѕn/Խ:Ү~"(czL(]4 @ǿЏ%tG\MUId B jfz┯R4kDn%@jD E„َtG0VEPGݑq |ޥId)>ofpÝ 3Rz4Jw)񵖍(kHx |?Z&^I$ E KR@R%mK:,OҀ(#d i]q&{`[~\7ci c3"-sk.\ؘ7SLΊIzjՔ2fɡ/d3SB,,*WM۔dݢVP4rZ2GЎA)xI:gFP~_•Z8¥Uڏ2(Ũ6^r{.Jc7KQ,ʻ@Ex2OvމI$ޞMͪ\\M<Ʊ/0>gxw[t@*n#  bG0 `{LuZ;$~ѣIT)2.#]4 '(F+0^ge8_6 I6J>W<G7vTShsY<\^aQ.V?tX:VJ5TQCGsͱ)aX+J Pbs h3IDu@F!8Ϛw݀FxKan#Jz0\i>X' k 0 HskRbgw%C9]Mrtǰfk[J!3ӱ0i#o`~tkx3N1)Bc>dP[D~1 Xŀ ˎ}7 X@5|euU C\Df4 I< q0;۹*;٥on<?AS?³;O$M9KtySi$b$4ҩEV[\/6b6->oퟞJ1g'Ѕd.`K[1"uT^3Gh` YGR{'9tRFUPFzXiNxrU1d(́r->eݥ'=?k[ uYQM/е5"\]"OLo4h"C2Y!B!:Ƹ'yh5M  "$^hǓecOuXI Q 3rDWñA Q!e'JtVxsZ-e_.H98^e>PJ\rZѱO(&^E *hORFK{sJ t{'ӑD2O>PT. t|hj܄G]awE$ȉ$8+̙|z7C69߷Drɏ4Y i4|}|¡DL?m*&%4"Z|N=gҞ#,/gc؟$ZŧN71#?Yøz0]k'B#b`?&Gd{8ax=^g8Pg68RuAJwVp ,7% v)`5ACxZ n(GnXaa-I|g>Sڏ7`~7K,&kvXc/ \1S~=d|,E' 4}4S/S?%F4;tO-`v+$0a=SOsɧԈd1ׅz7F5VB!}rH‹CiMj1ћ:;3/Q2M;rЗ@xђ}m>GoQQY<^zD?jp$gܶ%fyf?9P$$ςfZȻg #- s -3/.)6brk9B&,1q ۫xH㭋KJpz *Ǎ`#طgll_AS"I1/&5}fAޗуg4V9>EOz]8E}U pGO3ѐ˧2MJK}H|t'^I3/_r;Gm#(}Af [/$kO+(J9Q|));_h__%%[B.Rh^:-_s-sTVUKOs(YDFU:-!VZ ~r.6hxRϰB'`#TSAlZ`b..|mz N~F|8`?ߕF ؠW wؖ$GգNGu80BI,wfӱ4>4ч!UqB<+ŅrfPMW# %cN5l:!?y9.(总JzC8Qw| *Co ڔ2_gFtBC. pHq?5hz)T֗"=oI>Yb`gӔtK׈BK_DxLfT ̶A~Sj ~9W pPɳǯx H4T y *v-`VxǂQGS7U]xCGܬ{4UohWHiZH*Is^'iOO[н%>edEk~}xN?}^б4ɽOI}p"swwzv~ |/Z\IytsdVp N5`vqv vRiqhxav~8Q7o*z)g5ӐM:~oU֨HChVBJ eݠ@3WamTxtV }hpA k0t} RD1R]Dp[~pZ)+}BlѦIKr0+  |:'$VcWHy@}#W\SB6л]yܥ}{?=z.m^N=S<_MTH,jKoI59D@vW8 sxr5:JQko=(X$[Z}+ͤ\Lq' A%ԯㆊi2' p5F&1 'hs#H3orw;lJt1'lqB= َix#֥f{g5DfҽNwGa4R>c|=߫!cRM yڌt7b V`4-JlqmWmuY  rfVJŽ`k? H` :X/Ǖ ̰A\cyf 6_Gܼ\Jxu8mnHޅTTK& \SOxSIٍbB+£Z:9lT:FMw2EGм1:^ܠǩ|X3mNؓ~ߕj{_pk.Y)rI~̰VN#\,c>ZǞ,|a ^Bg(EA=e(@-/D4f$e oD9co̽.-6sTNӲid+͢r4]b_m҅Uʧ^Y:/(geEο+ʫ̢m颭}b Q2|D=²;e8CSl!'΍MuF*g, 61#ZaTIN=%`#EGP~^[,,<ȖAsLYJ IڏdmAvz i~!Fe@X'0h#F{Ľ4׈/%x`qk> S1$x"~2h'ǎVz$T{{v..0[b|QuR@42oƓ, 3C??q'wsQ]'.,7h"J^B>e5^IhTbHp;'ɛ,^o2WR Pi˧U64UшF @ͩ]E$*ˤҾt!z,n/98:RQ",}aaF+ȮwlMX XrLȢ;մvU8Kk("'O4s!r^sgjbB58-uA({)Nn޾kkthu:lc Qt>`:4/|^HkC,#| +hK;h4)tRʸD&PFHUZCwA?УȄCj't☰~!hn00,]`筃\6mDP7}ݕS7{KO=@i)+ŋ;͞<$~r_!ycz!Megʕ[͸9XɰֺSqjoW03qPjigHAOxb|6M̫lH̦u[XXecdQ Mˑ671e~dQ<W0벅{[z 30~yy ð nIxs/r!'{6 Ιr}g^r.,À+Hk2#F3= HNo|VZo@mb9"v8:!:OFk.x,a2KyWM )=ӕ|p͇{v+ȅmnjB~ cFm,7퀩:ad,t*{JJxDb>V;kMb:N0ZXcȱ{~>%r;Ow]-D-Gr3~+bx6\ +83QL&xrs1obvnɇJXp ~+ѧU67z{3Z۱?s#_qfާBKc,Pȩ'5(_/f%qS#O6N\,rΈUִ"ǃW|̓rh;]ϋ7cn' vX{pzQ͕PTrWO.8qtNWe9'v:.ak9=xl+N]NLTue-+u!f8.Bvj&Ҙ\L5ڒ2WGjl6B~b8ꑀk4&z+O) 4.W3P YeCN̎kezѓ1:ߓ]B̿Fꠗ.!^uGo/RMz=F;<`MMlLe-v毎LqG%{߲)ۅ+b*M;Ʀ'_1k[8I΀*Te/3e`-5ͩ"a3tO1YrgΩpu3o#Zm] /=.N-Ŝϸs? ٣`v{Ʋ12dc2݂@?DvIfL?gPI!a/k1%ҕ)眙ʅ93-ȉ/[|U4Y)̭^mI{oЀ{nr%k6aZtWqD=ȟb7:k R/jx m<[Fzt;cYY՘~h/FԙF|cQOʉDl^ltlY{G?De!;W t89\?ŜY‚ߙR LnVVА8&l֥WХ+GXp#~0σ/y֙n,Kh>5ab]B"~ٙyȱBu~7f<? gDO$vk2<*RawNͅ./$'%OsbK&fw5m*hҹÅOmb]+2b]/$^K3}ؤ8z" k"`3?8Osy aTqaS5m5ey9Z}s慚s[ }wKx`lr6 9~:|tD_ik{:';kѮLT Ua ѩίмU尘[aޫ#]fݨBBvOѵVg,,f.+EtmΙmXPnB =FCa'? H¤Uc4إR2ьyՊ4ϜU F|<[9%p(u^S[rpu{_no\ y5ҿ<>+Pe%+@hl4D߈T;\oFڳ7zcm9U o.v.BK6NAʬ|$Cy Ui'PwcniÒ|.]bǞ x9ZD,ޔ;fmd|8I#$,JXG^S&24n!_mNڥ.dzĘՈ<}w¥;3>8t*wv;A:ۯˍu9Zuy,95=*TqM!$oI4~G ,wbmJ\9/d0 vJ2c+{#GtiLM&'!3y=^qR[hqә-m?01or6_!*M]`N\<|c~`G`s> f$[!\TVb&-sh_=4v iZgwb@sFs!M>=Ke\) dMo<Ø 9GՊyk59#Sj}ߌo:a#IjGd<_ځ6 lҰ kLjRséa"i9Sh-?w䲹>aƁ5&idKA:s Z$T k<((d" S?d#kbifCm-s,OHˍq8x"+=ml͸/^o,e*\7AM587㒧xֆ#83H8&ъKlҎ.#]9MCyͅ|e#f߈̩ѿLP+m}t[: %m0 H/b$4fC}!a6 5 3PhI>}T|Қ,||;*񘰇j]''YEoh36[/4Pk޼h9Lդ~F#֏.j. Ȅ_(W11tgS)wiZ })Ӿt7 37B| fMYNYaXFtߊo?*V:LX(DŽuxSW>׮NT[]éZX]X-%\6?9+ (O߈~֌}_ԙPtؠe[=΄Ϧq- qfW.y̺=.,wr?y}gO|Lj.ly8%y'\Kcs[uٔɍsU-Yx:ʭzƀViG^KF^ xYm۳Z1Js Rc&\Ҡ$McZLǔ`M㤪:hr*_YSx*1d:ͭB  TaFĊƦҰTG>۩`_lEWn 0lL-e]-jM:|%xUm>yIGuvުCtT嵯%a+ڷ'Д|MtQZ]}3ޜo,?֌ _ Vk_꼨7ZC:~sb.hGϻtr3㥺WLQ[)?Xw9s\DXe`L0MW.bkNurg€DA 2RyDF>{Hn5P*:OBw;gsoݢsvFz8jqyw}唏T&f}񭹘"/!{F`"IhY5~'Tc_FGf730_7N]:ÎFY4ʓQ' SgFX8-sz5[ϲsKH䷰wil܀EsH%H`ZŮ/G`NbҠt>ݲ`nVÂ[qnwKemS0眣|ÂBӘB%x~Drh]?BD.F9JY}Ty[_A{wc4v*vM2 i񞖈 s:3tۙ{E|ɵ\[H6&t٢!MZYEyʛq;tN@-:kȌӝX6\Ƃ ORpT?gq2gX}8ǂ:U ->עI?h{ ڨJu Μ$T5"uGo끾bb#,x.*Č-pbDd':`]J[H;='^Rw^ ¼p*;i =jX̂GO[rl 5a_Ye߁upV'50xaW_ẋ]mz7tzDݟٖ+*UeT:1j|*<>C4=!=]1.hp}6wt\:cG'u묅tR욺otON_LG- q(#GudJV+$6[S2Dnj,Ţ"# ǚ_p';\z$c\\~Z'Sy9s |_N#=%5K]&afay&{գ<}Fk6/07 d@m:r$87tXkǹ%T5w ]ۓَibNb-><&8E5ۥ4{*5VY H&߻(2 asR#s_ ڞWaZ,a:4R7bLs!hDF̖$_o)*jrp*T.̟Cù1tޒC0ƙ\L¥ 1V_#Njy.wF7T.vi2{)!vv&*sg C:קM#ޞm xw!o4̄s iYTY6WX-Q?č÷m}t>  `e@e.+R})gww&YU]]_8bè#a0b*Tk#TAQO שPFjp 1=[bgrHn)c[OCsxSW3PF7i*kTZϨ1e:kp ؐƯj)E7Y3Ctx}ZP{147Vt"J?FUvL09{] rMEaW͈\kb!k]ͯ}9%Ҝ h}Ėםlډ|eo޽LOր(G *D+y>b~Uyش bV=2u>یYݥK{EF->ԢA!$iq0iqXf\i| Z=Ra} Y5ŀ( rboJ]7v:SF\wp] ?jo̴G3LbCihoɕB rV]!7$4>\ӓ/Qߜ7i2Uدʪ* gUT +0 Ej 4g?> r|\ގ.|CTbc&: ⛘7NF CLPǯ7cDD}Οhi0gΔqCgV3HLQb{fGU?<\ϹȈMCs3ze?° 0JhrX b\N):6c *a>}XNK`jVI~,GAB >mnj}sdK? c/plS3V5!* Lx~ђUBY0ڳS vI5+pT)6}(Gyږ 8x0ʏxn2ޠo쿕\QK v3_q_g ,;CS}'|@A& I;!(a=ZER=bRJ5S}lhqf]65Dx[92a;[NuI;WW0ēs(~} 䜺KKWlѝ<,Wʭ 3ƝIE)_Jt;4*c@2wsnf.8pL–SBסR}Nb22umW|xb,پћw ۋAFpxK^xqToꭘ;ț#<؋}n;Z"!Dҭňc6?B'Z"=iMG {0YF2zA&Wfta`_>Y٨O%šܒahi>:IJ0O6I+UNܦ·'\`K݆PǔJfZU?B1Rcr5~5_G0|=명:8ɻ)Z hsq 5W.KFjNU6kUWLS|oyAӓzr*/d'k(ۓ9땜I{/z𾧂ٟۃOv)Wsf@-9𖗄.(7$zqK{y7K?fV,>ך{ZQƇGxz(BM7*#N>칢g(@ߓ!<Ԋ#}h)熣|Kk}o-/٘'zTc.ӧp}^C8RtK#5A93Z^o,OhXY+[[qH3 a_Ǟ-5V<2.E<lSKιou=+g^<.SmONL yU '99\22q'Oj>bZ'JQFgRmɴ^ފ˦nV*aekіG2[3ci[m\pV2p=JA 8持4U)JMJzSu[uy#8"y9&с(zY%Lttf~(. =)cuɘQh4ckl5>T9Ztj3ISpdz4BkL \,,j{::õ =z6\+Զ"@!ϭ6Xg !c*Zjguk/Έİ5̬~3>4QCZffiEUZͮ}z-6c±*lrmъqMkF bsl\]`D%۾V0c7+)Y` h+xϋoEMq .|7p|O=~`1v7s,̾y[t+g~)h;3o+ꪙpx.4iAm;.*l\< S7>2zTEYxQI2L (ǀ3xZ|PO~fz۔|æD]5Xps-/2{0OPS%19u1}a'ƶ9Y7%?t|*l%C#i\ {8C|t)=)o`Wo-vI 9 \|&en b(%)y` Ɠ|8Wp>\i>4^ps`b c` >n[=sP/f^?ڋ YԊ._>|÷JYNjyvnbT`*rY}%}IFr^\;ّ݄IׂFLc ^ ]ZBg= (H{?7 Ɵ0x k?`fdyHkļȐ=^pK@&,9u7W~v=_OQ9L(Y5(=TiSOs"p%j1kufD?蚉i M3`2gPKF(wi/k+.%4-ܰ%BPa);.̓ةRɯ'ś J:/8fϑj flCC'kr@1 M cξ6ܔhŎUrJEIy҆W{Sۛ{ Z+`/ sf,8/M ΰ~Nܭp[)`T62VJyl;;_ coֻ-Św :eM51 L1;@p p"+w߃s5؛bVѠY)}.Qx&AcWt?0wa)^ d0>T=y~=ern5s/9 c|ߛW*y7 S0@軚b6s'n4J7CBILO1}c ǨRs<1eX_pi[OV2q/ߪpU;u9by 9;3Vn~V''_t;y~s T-fYvrzSxCS1ax2JE_8;4$c8$D~1zCݤx옎CTx/Ռms8'~S~:2T:j&z<#p9<ܪ) Lؖ ӽEPrCq5=~aoh9'L8ҚZS)S9[IrCe=9'+LΒ2)m_ ;:VƴjOF&zq?JLaԇw&z)R^R*-d .ɎM |]p_0pƾ Wut^DG1VH553aW^PʬQR5aVŇs=y2TSKօ̝9t?oJvXƝRvV3:R_n4\Wv±;ءƖJ0wkDS]O`LX@ Ir>|@lJ0W%"7"j@$Z~/Br&v*_[RW:AaE }`kno~m/4I9Ƃ$*襦dB/>rNΗpzh2͛$̿d%~!)l#gv:rc_AIX=>.S4sRܖߞgiX5a!c<8?4:S2Ɲ z[Jӽ湂JX)c0OxVGk{]B"y)ÕRvɑ+]Īg#8B_WIwCv\;Ӟ}سђiߌfyRׄsNel/ArL-U2Uuq?˯|îyq_ hAp[{Zr 8gikuMŬ%Y8`[5*E2 _?t(=s]? a.Vw&ٚ!+[`/pTp=,! yѢ'쐱O9/&)-xO=~ &vri i·fz-@~9 9p%{'7{{d7fx18ˋL0ܚ㊡ze-3ֆ۰f\{Ud0^1Ģ'x3 /3׈ #.:f %ܖ6()a43q 'JM,q>\(?/F`U]Vp$;S3 o2gr8ә3J8;HPgLwka.9rvoýksl<1o}JV1Z݀N66"·M3W-k7kBpF_iu,dP[x/di(r&mfl|evONn櫧> "cZ9(8KثE )Mp=̛ܲ[&zQs'/vwTmM#Us:4ذˀfhEMmKQq}|BzuN}]!wz$qwwO`!}LOOϝ[ܜ~UTVo>+=Y 讯A\kй?yj2۱$c=9{*fcT ucwww?ڃ]bqӦNV8/w:g1l3t4GΞ!kmVf^ӎayV3^ )F}+FU8AB1i"!'u@~2 B2-f`h` Pתa9;W4hϫe \hݸrFmWrqFh sE|F'P79*z`OFpdžj+C<ǃwm3єmk@}TZՐ1+yz9"Mh{Gi8#>!OX= :bB̜՘$ܷ/-M[=FrQʏ4`>lΖ-ٷ3(fk\Xىڭ<+O:#g&:n ,ramFز[9{* ]mʀgl^m;NǜlM٭܄2svoN'uBZ+DF#UU0=d%q/OÜBkYG>*:|MfFFTɥ9/K}NWWu-"ҩI@K_ i[t`Ù9"%νƫ9ڴ34Sc^fo=>݀pD{΃ky1V*4`K7[Od{_N{g}?؏7Ԕ-U^LI'yEԹWʕ_E-AdC,Qh*bY#=GU$K@h(=6k&E l4NDŽ{Ĕƙ~eƩ=;wsRTsy;1{&:UɃ/;s 8#7Nl:ԁ=ʘs9Pc2cKfnNF zdJ$ 0,(^êa[bX[I2D!vme^e0[}!yuZt!_3f/w#ŵEd`7{ѧJvAxėF\ΝM\ހO6,_Pud٪l'.gm:, VfU=PPEU[)46^ƫ]G,˅V>m] _cb35*1mH%|p]5ZӃ:,ua W&:S]{{Ss'Ypύ2]3ypcOXB-g̶ }6]e.rS^~nD1}0*}ڭ*{`"qSU^OHG3b$x~C3RtQ2'C*/k sg|:Kӡ͇idFB[-wbO.F9Տ;p"^^KsP+OB84J<؋1a/7pބ֒#J~R2z>IAWleVg*TRn%ڻԢ@=lB%ڌTh: >~N̹ wQ6<6XIYW=Պ 4wWwab™{Z_ysC3az1݇}ȝy@WcL5pV1Js9:L96 g:Z-㡟\rɄrK3jɶd I{޲cآ}>OjREO~v}:" Iк"g 1GM7E'TK1X;̨d?k<ݟ~?3Y(iq< ^U5lؠosgO#bO[1 {?Ұ \$EnjL=GNxƗ|FEK/O:̱ee6?VQE!m2P`i&N QQ]QHgͣ2φ}g)/;WtbTzD1%3ܖ] 8d*SchWm2!tZζM/zpggV;pX{'\f=\ү4Ty1 >cg]' b\9PW)x{e|^$cJ.?7d/5X_ni0θtY_cͼ+o9#ER F&'#lw.P̲,6ف?K͘dz]uDTYR ״lXoDx{TFxn9MsWx5Ov=x7[*bKW22nmJ}8ٻSgu&rBt4H_`RYӛX)4HqlO=ϭ^\TiuM8!z8XZ-Q9BVs=uߝn%o){aO]nieЉ{cc8`WL/I? ,4?k}^V2.X=0xd|ܒ;-mN] ,7LJVIآ蚀K&+.Y1Z(s}>Pd.uȋte_s^Ԍt8wveX_yVlcž&~p1r6u/蜁F)*h( %h:גȩYw~êTW*yefɶƿbqu,J2QេaR]?%ԑ_~9==ɀ&R~c|H9 w5̮xsR18|D();4l3OսF+WoS 0fK#&Q|؜Ok LsuD 6 A`³/h~%,!IWmsZQNJ߃2?>aHzq.7Ԝ9={?bPLR ԍ{(*0uOAq1`eh&,CmOu'껻3v#'lң|h-᨞#S1WݳѰc 6e2+aϟfLØjTW{51Tx5 UCpr BV%-5WuM:1{_fHn>~FF%zYVA{N~E6qB =l|%t%ReJu.f?_S&r᷽4<ߐtk֫r|;?:7N]c-}k1g:*zqw89-IJ3旐zҷ{zsBpdm$FwXS^J|ՀrӃq^n<0],ybb4bY?Ra11n'Ae\XU6 `LJ6t0OM`5 ~ɊPmNfIenά*ؼNS;X*/SV~*}?PΩq*Dp}v#LT 0'_=bQ,TQL5oo]b;-v3s.vB׏krFxZ}P5Eh蓊1vc27C*;Fێcƚ]?=ѧurN#N7`!M_SK: yȟ}I?-ݽE A"#R (93qpBn)Ċ6^b%b ]ΛYf\z5نgQ}¼xh7=?4fkGP1l-ڭBJ4Ok`7 ġ+xsϤ֧FTDjrWJ=V>jQo^Ntv` .tuF|lcϡUzpmϟKKF,Eg*Jba. V O1lyđTlYϚDɐztcT>Zp'l^;2Zf[Y$ zkWghY(ؗ& Gv掾Y`=- )8RhQu2o-/Eyy5*(s Phɨ.L"]ODк=pROܰC, K'Mcʮ,'A-5ބ ܔ>)f1g"fzE]U^Λh>IK/sƭtdGrcۉU:q^q'zae.Ʌstzdy& yQ4vxߡL135[Ni5sҔ\ԴNU"\ЏF}k%'c+m |)T@Kt<Ľ h7'x3&oB΂Dž |VkxOYɊ8 ݸ`vHR.;TǦxj o Ctngfކˊ~|zy㖚& #f Iߑ/rTOzyN4mͩ)z|[aUq_dž5_SArptb1,X :Zbz9 /|Ky[05 !dV*lvSK=|* jk|ٻy> O'XCtD.ΐV&KjpT*%=.=)YS%3q` \ aEgOc:Zp[K ^ɰv؝==)U6YQ0</d8 =^g~ 4T ոxoq6XĈ{Nl7‰ECFŞ{|+rSP)n]wq9p'a{EY,,:K#.<w!Lk5lRɿs'/=_z/7Is]S7ߐ7t[68`<urm[g\cjH|zWkL !>եyyBfANۋ 8,ۅަNMn9W;0R&(?j[%;vǔL * _QK:NwZ XqtGg!K *T+D xƏIG<4Tk/Fb-Ɩ7f.K7[ kZioBoCoٶFꡣ*'O{#W;Jz2,μmwSaD|hè֫qo[TN`A:{r}aw[I*V)i _cvur/igz-|^dUM9KC<}Ԕx7ӞM9=KrD5d,ޡv->zgoɪ/Ho ޕ45+_cC| Av_a] {da,5ٸ^Ѷc:n}ty:+-zfdi]q,°k#]àG{tEBPe6diq*ǨTĶ2hRb̸̉n=o,9̐/µxu2a(J&=[udWTlht-=K2tYAnM93چz|e)\5VOU+' - wQB+;3fƒ4ςLD|C͔HLw"? o*\"87:fB훘l$Ƶ#"7Z ]\B;$nnXB#t `gfFϘS<|NchCVN)#nQvۭE4NsM7w)˸(]*{LSDЗ\P)0j Ai-L`"-hQ푌KXSz|1RR Ճh֭?ˇϏ}\4&!h/DPW|8~)8*ݟ%@6QRo?^'AGҜNrVGQ1G pts8!0pB zsUuz ~]Zp` B6c})b9lV{\QOd: *ۯ@n?.=ͳ.s^{ 7?~/hecW'qCk;Y,?Z_Ʃ3 R%q% ǥC"e|wICյpT'5,Sa,-Ʒ{ehq|B[/2ʔrJ3}_]KN# bd6Z9dw)&fa}qeuo.M2M׀^+k![aFǨ=pe<ڧ(,RVڄPҬn7sFibFxԽ^{[aHhPdִ'idMSΏ U Ux JJgV1VX5aĂΪAuaAG4)y`OmɦHX-uXP8i>ݐcdű[@7_RLN_YcѰTDF1##nã1s\ e>v qvWήDʖ"L~Z%xx*V˱ZVI_"SGZ,f”\6Քp>pC;#XnuYΙET~IӮJP، Ŏ-a>y 뚠,૴Hz6GbWdntfչAy%Q6 ¿) X Tv:̐ =.sO?ANccB\k#&Hsq{G_h Pu;~k|,pYZy¥vK׷*Q: (ʌ98(E7ksnm=C:mZ{\j7ǢOpm<(Cmrp}I׈z{<kVAtkOE-pWұF7$##1vi$Z"2ڌ(/k{LFQ)0!WqC>)Kxv2)1kk*QPu}΢E(8x"S#m~T֮^ufKQk08wEyr}Ko%FN /Z?.Cxހ3p|]?aB'?bby/KDLܹ ͳ{Nd AcM7G؋.Rz o.}yd<|G5k[p3gG_ (J^{znh%=Qǀ5n( ʕz7K2>fNsXVh3D//ʅ\+j߭Îg{o]wSVW !                                                                                       fOۆ[)zXׄ màvO`ϵTo;wLl*UK`w#w#}"_>p,`` 7RH-nI5} +',mXLM _SAy'B|ޯgF^ͫ8Grb_@z afNx-==<ciaRx=k,5leOꭤ9ggiax:豑k4YӞjg9`͜ -L?RNp4.5 ACj"6؍]VQuiSF'yȈF;ҺϾ=#÷~-,*|E#0sO_gkhstXw{Ӣ9neJOΐ DtQ5߈F zcj^UD$mىWJ27k?w$][ ͎mkȈflcC9< fF1yDh5ذ% tF%Axۋe``M-;}@N lg W;@kf ;֢}2Z/r28X-N [~g [8p6BeR 1`J77b 5.E;*QRk0+nxL4J`ʦ꘸8p #6fI6qМu[Gp알2XRv҉Jl-w5dg=jt3ޱ=PJ\}K4~|#3>\Į66jk?I~j@TmdztLJ^՘4*յzTV ot]o|ˎ7Rh:݌sע"M/21cU+61m5=_Qh6IGi;UzȄnI*ݰK J˓1;Wp^?HH.Q2_JOi?Y M5/; Ιˏѽ܆Q,ycȸjL}x 4Lօ?'~]pL1xs(GzEN·:<6Psge PrfѠl&2l%:U kn-,t38w[-K/n:w*?JG}5yhМ\ It:y+PE&fߑ8ބӯ#t.4@NoU[1W|myT!kk2NTb,t Fx<./KI.?̰˻u1׀>v]<(MA;p8X._n1s3j94 u1DEn,oLȖ^r)we+fWIx$*8Δ/|lLɂ::LGgWwO%nOl=x+ :)Ǎi+|fk֫ipb[ 9Pc/Ue8NDh"KLUNwUTe~uV)Fr+kQG0`2U"rȅ*FIR>FWH/UF+?vioyI}'%.%e쒬NkPum7N}%:8~F\[֘>T;+}*7eC6TƆgG*~=0'o{~Fn|Ht(J[!3O}ئ4\N;zU y}AB:wnP}nCQ@DX\e(iPmɞ%wp_Á{9Q#ld@%]kmnñ-9Mþ8V8Z٘6OTi -8 ֩P;U~R!^-Kvl߀k ԩW*n]j[IušM΋֮7ם.BwuT?Z4| !=#kzȖ'yӎv4w,.rYךܜ[ٰg[ؤ͸Cr݀kKW3Z\jL]mJ|iič1괺Pܥ:ʰf /8y3G֛Zr}C.R10]cg~..MፅYNvW:9t=:Z2aXp%=.h#E e%p&COG>%yY?K*RH|HO_PY&ϼ `U|Y!|S>a{s&NFA `ɷ͜yWәu5+{p_]ǁWl+W煗qǎ>YsP{ԙ!'$̄|b2VpeV6TmOQ⚱<*\e)ߌI2\3-k@cwWNe.tj[m!:֡WJ)6}υ+0#;w#u5Gr(K6g:;ĪSW0pU^V=)ssU=n.Fx g^ 访k nT\=z[2u= EgfsֶLI$sGzyqSeY%/6d gf<O58}6:YȽX@Cu~΋#͇aA2vh2”=9X~\\ژ:m 8.ɔ&ڿӂSWXp%u,%R-8Ĕ]yLME f~őa b0,1y 54`u:ݚZk&[R6-LޘʼR;r +㖸1jYd}`*_3qfM*f"RFaf2"|B;j^F0I)7]C4q]@c|p_d[pZXAwf՚S1*rU8c.9Ȭê2儵UxC72읹.ލ#(:w٪=~㔮 g˦t0s)5gy%gZrsZ2Su 7soEMe\MNPfL8\Cm6_!kPCϩiC y+ڌ_x`cM3]hy]3Pq#*7 BXGCw/)_~`׻(,h A[gԮ= *'ʓȤ hS=F(^.5xV73̘ɚ=4yCe<s.)S+FMx_}ƈ0A 3uNb>NvY7>j;PgtซPeIdS^g)*s7d* K}V*E])e]6}fh0Lz7 q;)E=>*$´ %dECudܳҔR=٩-)9@wbDx[0!5/*2Tϋ*5^k+TYW:ẻLÒYX,3cU,,٨cIx. >nē/$= _0 |tmk؏Oaj-tJح=&t:oqv3"M2e>Φ즨Ymзeg_{r3RfuYK ޴rJ'f G0˜vF>nsB+;QX{}<…~zwo Ʒ|[TG*g/yE͆# w.sXe/5: >T1fuu|Y[όPvul+t~ ޾'lgG[  ('g܄ec:B{ LzQ8u :C#%0p-F߈ܻlvE,)-K̷(hW&bo:8Oꕜ^zB-m4%݃ qS{9N Jn{*go-mG;S'Ds9h6דc<8r [r`1V-yjFܫX0h0EeYœhğ9r3WYTgtMi!g'wJ}ya DTՇӑ]PJCEc; #ܵylFC590.=n J{&\_n$cz]Dީ0ad{Χl'Q[-VqUQ~ ֱO5g7T2\\629_Ww35\Va¸Kx{~wbm|c7z4tfu1W;LLVG,\韇oJU`YKS9k¨Rc'DiZ&\-MCqw%ԾG =G*.NB PmB=[sm;tܓjYx-7 kX5?E;(”s`Ss{{Uӱr:W+5S󸕒Wx$[q4f%ks$ܶ[ ֬8_LkFCcrb^&t?v\ІCX:^\/7gtPEz~qvtZ-|܇N=iXj={V򲥆Q;xsYgu\~,k{?Aʗ>\D7L񑃈Vs9 j*ˎ;/Ih'p _mY?֚Xx~08c|\jaqk{|fg]i73wcl8m)Aá"F盱{ v4:lݎ{D{< ܚL kGĔ];5neضQ~Ø Yzb%&(3/50n1堒K锫lw3)i3ƒex}Jg Wٲ\m*ھW,~`fS,}[oXQ<d2z[/_O7fwž8+c{ W(nlf䚉W0IgO|^yS |[Ʌ74K>c4|P[ ]5^wZo.w{\9j3[8qچsi*Ey.柧vlG6Tƽ"7$e +lAC9=拹c'SI{|(} :|V3_kYKj>J|ٵ (׃z~nimIxui0Ŧə(nB3+M[w~i$̟grgGhw^<@)l8R!\|3 SSc#^15_-b;"jγCMbe.m8#E_r7VžGUˍ;)osuʸbv]0o̴21>JX̑nS,chgw4VJ<|\gyM' puӜ*6/On;̆u[~r<Cg8_k\<Ƅ]qq+fK, k0U>k!;栨om0؞;իZ>8˙#|˗3u|'p@KQ*J̓+ó^rӓR=ev<82c"h* zR6pU:3e533`QlƢ(֋8ĆΈxOL^|G])60g51ܒIbɑ+~WcKF43P;{྇~ZYO%3WNe()13i M+*K%q~/JR[O>@cɬ s)u^\X*WcIysFƄ~a8t yp4TPA;zs1hC8IB_)h5^~bХD847ǠC r4說vO4L;Y:>Jx{kvsA!T=KxΡ_ZćSkyc4DN<'z1Rc6i}v-z*4ޘV"^XjCi=D:Z)?-s^d2\+âx'ξ_- GNѲk,luYŜEɆi•JYTG:7gY;jȓ8b(9N= _ UWso2䅆ǰ;wiF1,q%0y_&G"NH$ WfXU˜| \fTW_ -eռMe:XKP=WV 7'{sW6jʁˤ,"+@n+B84KU\ۏ3qW9a<eǮm9{$T,<2NvO1 Xx;+{V\iC1V!b"..!Vli#l2%Bߑ Ր'ZK)Лڬ:J+yƕ>2e|O5_&9rʋkM*/y"݂tѰ-=^JqWwf'/cV6[ςu8Q2jFJv?{}}VU+ۛp2LYLLhrѥcQĈ9o0{׎Ei\>땚-{\*~.'S=GtX_Ɯ2VxqFgWn sޔjEq 0rS7U1Ƴ x<}qOF"nA#6l͑:j`p)õCtB&ֵ7Z 6eUfɄ[$΄faol&vo*ޅUIT'DOT_ZYQCVG#L`ċY$1嵯s ;|̙'Wlh%'Opp%wTA-ⶰ.#yԚw,,Ø)سP̏kd>7m>lEmu#jٽPΙ(;B?~B%ٌܱٚ:7Sފ)5\[}aG,A3odHʫt/eQ߳+~&ક {޴%7`oSOBL ϷY;4ߤ o@p+ޣa kl>Ö'c$|4ہ期cG{VÈIO Ű4/XsmW[wu<{ls;8'ܨJ|ifq͝Ai*N.lǢ \a:'F\`OJ9|sȹIe':fwYeP;qF 7 TXgŠXt8gZF0p=]E3aX$AfrM迩K-Iн1j@cV?6cT wi#fne۳g9DӳȘM9=|/.xk˹{AZcY[ 15krs|X?~OMz9?m7{xM-O^槎^KE%L±=57 ټQ)_qΜi #gY瓤|T{E4)A=G ? ;0yU M*ŚL\ F<]q})N](< ~ Qq^lۤғ8X!o0 P䃌! %ҵ5Vǩ:Âf:y8wZ S4˛pC5 m{-,Ssiwg16'b_F0{בx]q$&4 Y1۾PF?BU54̕/f v¾OXx[rq+U9c m_Z>k>9)zkxSᗦGLrJɂjrOܶʛ&9i^(:{ͬ3Kr35cɐ x<~Cds1Fq'1OV\֌ m~6(c=*?AE$Hec}xOASǧL;lM9Fٗc ?~MAniXKG¼iF-tu N[f:1sIg8TK zMꘌ3>*8&I-ZpIʽ|ީ 310* %8ˈ*0X/sy{X- s5\:\A.M [FA 7g/.<'ĵB*K^.em3b0gqp'A;U)ϛp1&Í :؛Zypg7^z̹jV>a'3-qmή2/"#s/oy3wJ?.,o' >)UޜJ}S[<~Y)ažV&Y˔uS1>8 8G? 8h}է;D`5;֚,.ЍS ;E+35o0旚ְ {of~.ŗ7D/]iF>Ts>ܯ׳3x3޳b([N q HyWi?1m]xs1x3'xSFgM$Fڟ̘z]¶|°˚{Fv-:nX<`V|mr,5ks8mǯ9$Ù]i\ 2 o>3brXpD7k09+{_X&HYMx?'LfaB\DuѹMtھfAٵj}^x`<> ~OaݯwU!C98v5­M0tvJ22?1>ʗ  SD4dDia5UU4T}5ghXA:ױp>?U4=R #Ŷs]l3#Pۍ*I, fCD6a͟&\۱[~>@ԫ`[ ~}; y/A=5օ r)Ȋ%6\X=Nl•N;s#vՖ8rD)eyY2%VqE5oxQŝa9YwVg_umM'˨,Н NɌcj~=Bx‰t|qK$ӞZ(H"`>r_c<0(c<&hn^wCO`#2cִl%nA]liE%pusʇ{bW0\yopikMPZ{!&l!d% \J-[:蘖ռ;SB(a/pw/Uq]Љfk@d2;Ixƥ cx,,XQl5 %8ڔǥa 0[Uf?o̩mfio GXYv,i!_YqӜ^ӧoa{r"Εx06Γ 2^B֝p5Te|C+n(qO~$݃2 2Bu .DʮXOi*WlVϰ:&{gO1깛q\% )p9NS`ګ:uY~]`յCyiKFHr LQ`żtbLm|hnǣH7 mSGהƔة;ǼRWOs8輎y/1Fq^* St7# Op-4`]t9.5B/1:mc2_6,=q5֜Ԕ7/`*b$X;+}zMBd$*G1F똝e]~kCbVk3{/Աkykp䋍|&H=%1z5 7m{^>V1Qnj'&x)ѱalXkA&f>[f9Zش*LɯDLjJܯo1|יv?=پPɻq_M|g2$R-ץ˨(a:Ow|@b7cz!KysxZlã+[cT~еO 8W`' ^C~_jLdu- sJCXm1 jz SvKaH qCKȊ&ecnks] J_sW9D՞~8zN[cj٭*旫2ZE5T[Mt \a 8*8䑊a{T/ RqV57əŘh7vfljcX֌{"E|̒c=x %;00Y㔆 5 oL5EXOl<ƒ oW:qhm.撇"J2 0ȈכqFKqmYgw,HGw>L9GXn26T3qoyˇGO->X 6fO$ 9^*'9ew6[}<Ԗxgn!#Gx쿚;OYSvF|0ڂ7dNgXJ6a0ό+z3k$1}CgS1Sz5a9敒6ZvgBKJ.+2?BQ[Ռ8%LF z8Y%vRq#y3c0+zhc5[ݘ!L_Arj'yj^YmǸ4+h)yУe ;Fd#=ݚ#s9O)}}M3!/<ڎX1*ւ!U*~ht+_jD8ۥCw_K*`FS%uvm= \ ?m& hyA`i0Wⷠb@:dY%FZ䖻;ɒ% ; ej֒_{رnm'^Ԑ2 Â?אz//EVHVuV957M8-mߕ򬸾LF2#=C#8rH]8''I/_^YcT((9#6Y5LEoTܼY?X8B}UPEJ9wnQ'5ϙwz#ϟpș\[3i`g2nh1Jnx{qÚ2I>bO;̶ z}8szEPfȥXg#vf.ʙG>^\KcwvF|2ҙ[I`!^(b!/Äy2:3LFM[XU[r+}hbO*ާh5nle?gjXE^GU@ɟ'\7vLi$tB\ۖ87D*!_r,jpN>HNAO^'?StE5ZSB<q*Ő[ )8Cb> O[ >$a,g}g=#([rUzW/v$*﨧Zl*au-g9vym4\_˒zNW0΋wg#/:. 25{˙um/ԌK!S=0ݵQi)8N#%--dfU6,<+ЉM.E;x3oraJ ݾ 7:w/{f^V@%1 Ǟ0O}5,Բo<)\7=Zuy@Zf'*xR@F =4W8jZR\F҅}J,T96ŲiEȤ6NhΥ`NT8sZxC`}us9{Loa %x=|0dmZ:cS_vnrU 5z;7- 1?w#>T2Czt,uW #-4G1l-'4K-}+9_ʱl9?Nrxn>lpZϥx䁊7nFi1mow, [dwf((ֲ_HK|h5w԰RJE{G͜` ׻i_YQgͲc&l )Ѽi.Ugc߉,T=i0}>45ϧ 0/ ~5A3S=+Bu%:tX#)}@h aba֭.!DnY'cU3%[jp[5~BꩤK3QX T\U2Z`_`Yׇ Ԟ}! 8y2:lXσoU+sUi 3ZCM-Ϳ9@7&nlȁ-;r;~}tuq.,iq>q&v*}֢vcдg6 ß8>Lժ-Bm6N3aE5K=y#QyCɝ!Z6ڬ/:1p,Xc<-_ 3s7_b?nu ؎Yn")_*/r_$pDwa/q`3]TUFj Vg(nG ?đڲz|U^Hũ$ҧ-1lS| gTmlp[NIx D+E+d$ lLs$!E52c֜sL4lÇjMk ZIB"߸ B1a,Ljjػ_|9* W1g-'v sfWkG.1<{b:~|`ha. n-a.ؿ9vBv v0oaxb{:Hc]8Sڑ=8AM|`0BW/ղ LCq-hx%c@o)6N uo1Bpcd ~( pιr_䥳ެ&Ğ*KvO3ᰣh _0a|օ1=39 n1\O4?Ɇc;t؛i}Ȳ|; c\Ïlϋe}Ul}D41dih;R¼n|:өؖ׿lݮ+5h imfxD\'zl͇c xuqAcC4:Fg5t32gd={ PcnZCs^uN01`Kc"faaq,b>mMbn`¤,#pl5^)CJ"--8_VKzCNy..*)+OnҷǍ \Q}e>3u<*&-1&,2M!.F?qHM{'R4 G/F;֛ǃ=\)B3rRO{ZX;3>P]1x|;zEbgZ3-L"̿x$Ʃ`'05}28IYw7*6d*wާfM5 c- ]r]Xa؁(b] &"v'&҂tyv|;;7;׵6ꋷhyM{PLNNKVeXhWݡin:BYjg;@V LsZ 5H-Z3%[Is餯xM:Q ZMRrm7~B;>4IOHa_MgV8C>%W~@43"!f)|5xc,5Ap36#ck"Ӓ&ZFLmԹ093 a3SON]]n\y]PXxp)w(a)y' `%} ^HKaӨzyǭ/ |\%ř:M7XVSq1ӥ\ZlRDbJGi'MKLQBv[JIk v8YN#\z [AFT &]f 캫Z@9v!>ZLN>9TțChͩ1d;Vlby'x} #QZ)Ek⊢vC+70y*|[Ϗv3߿iQ:uCq:m'y!?SYx>IK:4|_l~[@¼z[KSYW/6|lkzihA-A)HM9M&?3@83[.`R1Vnk{ 21b {v ZhmܬN/ 2ڎx( W(!^eG\u2{9=kQ-sR궩&ӏ%pN ;]\A5㕸 f1; 8QgnH-XH/ta&\Lꨚ \+N8N+ZS԰ZAN=G38~:U-.g?^Ubްڶfq.G&P4o_X*Q'?=IC ?8ZzRvS` ,qŃ7́؋HCj!Ǎ6Wd?L{ޥ3E-dmnJc3\ʯy50nI˳*H4*ͪ_~va$ <G~;?Q\ʸTD׊ (2.4ei|%uXAcWҢuF2BFhi3bPa1j8Ӣcy5p`- g~GԞl`{RB} @aZM(L_dV=FEo/F/k$tQ!A- -><ҠL |![ю 4R{0HLv8xp#vq?s\uH]?vEmG=n>Li0g,+vf-xlf#?8?6PӰ4ilZ8&D6;iZ0RܛvftV(sP8pH!RgG\-JuavjFRNyhrZcm4%,]-Gm2:Eb ©wpjQaC T:Vn3sI>2tX'H RخR"jV[ ^E}_U-p@nk wt$Ewtr=. XW=ZB]Bl5u;ST.5Ѿ+n{G{4xG\ wpow-F7J 7.5Q]E{٦S{=Cs\grmesC.A~sy.~QVŴu誷ӿk3_t-UȶiEn?36QݫlD^V}"٬BkT(ђ*֔P*җSJʼVM=PyK,-}Z܎c=bW'e`^bc*V3c$H%)rqmC6H*~@qSB`mxC{;Ո!G Zx(TzR 0bz 2OcK9JsԘpD +F] oY~-Ffnt b V,SLm5tl&=Dl崯̏Rd^ӣة5r-99Bty -{!+ -%<^+L戀X3\TC]vt)xH JhHק}!щQY4oA?Kib[Gi$:>h4+_:zgShߧ%=k˃Z͊PWE $?rAys[&됺7)Чe'0W]<3M O)sƍBodrЏr7Zj=Tԯ90'yOɠ}{r? a~= Ϡ3ac\ k顶h),Xofa~s?am_e+#K-QcsM(:l؜_t2,8R6 4g'A =ZatN$h*s+bn_{Gj,ɶ<\ˢ ?hJZ ea$[|t%J3c'gHaǔ#a"]*,NTc2%5ɱh9)*m ]RcB$:<RdJ󟽣cEO)߱?4 WXb Lppp 9Ğ?zfEv(=68`J9Km%x(cX'l!˕=rc(}ڈ=u([$r%X Y& .Vnu…3*ñ58I/=1k :ܼqQ$Gl#-%s D~/4fz96Sv[`#b *r_(1V뵰;iØC*xB853hB\ tٞ:`7%|FU`O=Q#g"j= &QtϗD .KS&wD M_O&tgJRt.>ghzׁ>b.CƒOvN3F;54Rnel#A f?11]UJ >xx~I>5Z;y0Z$UjpIKUHY$l9^QY14FKmvL3d6j3I2Y_IiKJS)rnl1 ᎋ\pG{5xĜS̹sgD-ӡGXf rƜ:ݮe\D2-j՘$Gs1_@|!VH"#J0ܒ"<dp l7B҄!SNykOQp+7Snaޚ4].ԞOM PїT-h"j-౵pC"HHƚZ|CL1s7@g&.X%#B30?UY Qam%FQä9G:)KWؠ9\a&:x<2{ѱ_o_#=o=U wJ%cB(mY\QU:|V$jHcq&0B!:="9cGp9vj1;+okrnaU;.hPD(l:,i3THcn xc>A[,d6#hv6/4|X@ޡ{Ogq0K" K\kĘ|F )RKPq@X|+08Jˏ4dy> /?_Ԣw> QtpɺKg)l"hj0Ey}eA[bc, bkj-qz7#mzXpTkY]p]쌓zg?9obߟ3a3jpP5W2Vu8maE 8S$$X|]sY8gpfͣ_-ŶClj.7uUMYe,*a `_|"1>mp}%`!)h :" ȑ|<~+F/SݨBCej}:~Zf|r || l3*9.DqT{G".nSE7l`aA)nEL0o8~hx:=)rÆt:N[=/R~w_t{oZLz&g;&bf%ҜQOc0o ֺ 1xaXd~65Qd_{Ib.)~4ч#qp Z Qn(e`pb8ΈdKghtPho sJ,`~9FjFNxz+QM'%lH?Zlg9 tΓd_x9FaL)Y]>A]? ym=u/7\O~K_דa53{TrA;) Mclq ,6Ƹ6Rj*0.ŃCT&:cS&C DZ(=AyL݇& 9/t0 Nk.tiXAI~EE2TGX9k9wԂŦ SXbb6\ )4H  QJ%T/Ο5Y}n:*g4iǩ7Sh5N5MSm[ 8X'"bjlyJCլus5 aʸqr8( ) 30M Z#VvI}l&ZoBMV{/KzmCÅ5ՖSmta[m1ǻcI1 }^٤wY=7j#Xvl! l03O:MSktFg5ԯ_ANHfBXӺRMܬRlS=!>E}kOC8hcV dLe c$vnz2<:=33|\ 7Gٟsΰi?jn2T^}i0QAX$)TݮZ\02`"Da=ZoM.q#,J1 'JtMR^+pb0birJkq:Hzrd r XƏG9.γv\"NWxC+W lbW5"sT\w/3*B;fmgV ᭉ 5}p#î̔ݠBTw %=s@g!afH6ly8Rl&7Є 4a[C){c'u;'8vA`h! XCdPwtSj&S(YYa7VÁ{&0V4gZ gp)&YZ vg3X[*<]"øUjPmt 'StlI4cfOwWߢaѴzS -TML V+mP܆_'8^%|U[ %jtW1$0 y-l_cy;TE5ͭ8'pDZcЯZ%TvJw*Gl k+»CVIj"i|2&Ykzŵ4jH9l|D#^Sxv'MeoMq'Y\lYL h~@ jT |XQfۂpt}DRh3ﮡk0Ve캃5Rtqhs24uB8AyB$C&;10bY21An4! ǛJhxDSφ"|xzzǑmۭ4zb5Sȥ!EtL)z1E ׻[#b AvhR[>uq2a",ePF wj<=Hڢ O*A*|mC $Fo9F\ 䢗捪화 yKGSY%mk5;,`ic8"+&N@ 5Q!sٻXu|  6<9[-O^<3k._wsq^9M sv]weXťv%Ɵ *؉4(a?C*,*P#_({ڢ| O& ,t1,FcɧW ɧԧ?U2 `x1X1{G ` k.E3' -/,$?E*R/>np/S-‰cm鰴:)й'hџƩў'v1tYz8v?p%zyaA8 _x(l%XxxǏ[cɑ͇/h)3.btҢr jx%Ѣ-g0}~U]4ː8Lp>T ro?xZ'xf 1h9)} 4yMHI K,%&b .Xsږ24M`x`:R>V< maY6c,HOL#Rb۫dXa\hM5CpJhoV(`lmOR dY]x;aAd1>U4ek&hGk6Y}YO'HpGUREU4i L5rLke,6UHBi2|`41&bXþ[+YYg|@ҡ链֟u/(ZlQ)&ы SXÄ-e(R^ER (ݍmw] cV?xU} 7$:*_+d7c0/F~2~"[2LJ@3e?os3ާw/Ü4`nZm|~BgTj%8!?c/Df@ V^DՔ.'/kxjn9Wk6OioZ-m_GM0=py Zb +>dw97ۣz1%p)Ur,I0fƹqz mv.!x-;[`k)SO4x#jұ7iј"*ZPE/MYhFzg|}v~bqad=lF.h{Nu'c=vEGܠzcjB5/KCbZnSf>Yvp;"Glh+N'P[Ňx N40-q NiYuȸԱ S(Ɩ+Qd?%G1^dXCGeȑ=9:f pAh6"Li fȩ6Bf k6ӱIMv>LOWV}MfAƐ54Ϛb7 Q NZ#m οC#|6R)uBc>&̱0Y IqB8•ӂIU!R V\uI)y?-z~Z!%owD'\YCY'SM)})+ڽ?ZSO)JW%$[M*hzj4 ,l٘o'L "E_ŒÅ4|Pn{5&0cJ -yTZ^)UtlY!Wf=]ܟ59(p6v*J %/%@K7C#dr?'g.Qb)=XKſL1n?wDHnBjbNB,/񌗶b16E; 1pɭ(v̻r03 @,DiG!M8>Ag90|1ڎ4ښ@^KڌW|2l=i׍6-4t_Nh Ƈe .H;Y aH sT?ݤ1M(,%U{rɖ#Q5\N961៸zk-%uuN#1PED1X9/,>Y13c s3Ajj<#ͷT*̎%SDH}2y:3vt(',p7/x0: ~,\xkV6߈8ofv{/H?SOˆGֵ*QʏbhWKU$kj49"Z[.?3mn^KfGӏ;tمR©#03|ٴtL1jbvW,qpfBVJqD*r^5"9Xp &B':ᑙvpb9[8>z*bx_q,f4QxdzэƳ,z#ScZz:)ΞyHN[jS !*cL}FOSHk../ %"{/ReN&+JZGHgHfSň]X&Bim U%mtD}/ҫ(C*l+z3#DԛٽX`Ua=5fk*HD}?&-鑧{LY?HiIoe-dY,;xq9^j۵4c:X0_%9Ӷ,ۖ\Ftqk*Σ%hQ\U\5WOS,ċo\pO-@O.&R]*aYCHŝ]pB@y?MI~$Axg qo0耒 ;_5)[Y`Q[<xp3V4d/~K;*:fP4ǹKPpmPN,!)]x>laX'BK!'f:a3 2 U;-2.n!\.B2қHRӠ"lNշiTtEaFw ;B/°>`_M`` $_0GK9MT9=vœYJ -ZK+@("Q$cVcn]\Gk҇?IJC:0{L:h(@TIu$)Yײh<:"f\Jk1q*̜hz̢%3 z2'V;St5e4]B (#,fO;K[{; K8 *J6r7*D˫pY$1B$E} P^v͌XGe-<#Dv-ǓH0Æ<%\VԱ rvvLvk&M1n, is86G5Zrpa%BQ)kx/|̵a_x(Aueh8.8bN\vŸmau}ĸZs{boKkC^;V(Zŵ|a/of*>N%>l\ayM4SUHkߓsJJ{qhokYV@O.Ԑ{zri+IWA?}8D=7<~*scݑ:ڕn!nY4)/ 8uܳU$ʉ͠&VoxY=ΦJr=,D ,Ԏ1e;)6buH!;n"|C^RM9.EO \7aW^\/BB!L>/lxDSUq;bµB 6P,zWO&b\9UX8^2s`w[+5/I ){P trS+O \._\7 [p~Oۢb Rpmb52YX=˅,Һuo{21ɸU+D)I$M*י#5̛`Dem5&۲z#ZqL;m=O/rdH[N# nZcɴ%3! puS,0ULfšMQ "97͕XĕBNX-_=U|hGgDb154U$(O>G虰 (ZI `^jx|>^5>- |̶WbkSgu0wgORl"ѱBάc{GMxʢ[aۮ0k7cѦ2 #'# -^׍>ߏp·VEĊΕpQn;m)4#4=AZ*)'%r uVnv̵tawv?W]8/6pEK~fLICYM 0֒6YRKͧ e8O򒯀-M(oSH*w"L̶ Rr/|=@o|([%-6B"43Ò44a&{fϰ4;;2/̉uM]XgE(9ySm4?,gT?=RRR?5𕗐ǜ<.zAFՋm"@%&bblF$)iIx8J0+ %JWC\5kо]!Kl~Og <m`ݝlZooM/lZku~o˒e\%dPC+YpL^9m s /1~'S\D? {)j}~[ w%F>iܳ[ }T+noiæ,]5*B-lf`G8BeoGynU̸(;hE$-mf79Q3[@+`?|ZΐRČΏjQwsV$T\.^3BN*a 0v0v` =_D5Tz=jjK=vsՎОYN LN\ۧh$2vkZY2DR68݅hԼ {sL*@̳Tt\z,su5=+=JqJnڡV:wͳc.|ёc]JNtĢ^=ɆO,WKb5\7v{jvj|,aznlgq8im:{ FԚ"eD<;kF; -U{K6BPI F@T'88-~I =0-M63P'3,#‡7(.ىYqϿ{FGv}7~=6NKN5 U(jޑ5 (84_>WH}3,ɵ[nf|p^![,&ǥh. 7]8ra%…j6DȧnawHop_3#5f~I{|=q05ȸoǨ>G9?Xe;)g6١<%!x*-^ÇrfWv;F4O'SpDYF5R2#zк':q=']ܙǃ^Ec(pk @=ZX`>zo;GK9TCs=?![%"ˌ^-K#KKosZ'9JjdZvne} #9(oж7(Ͱc_p;;hV#4UeݣDKZ&?vg!C'SjݥJlk]ga`t:#Y\x wb'Rs nD݁;VqnJ~l]}x&~'m _+C}<A躍ZkʃC>n徵!?&+͘{Ӝ#`Rq;zW͙.QۃIwƹ~C*ﶴe=)q3;eOL. }`&e/5mX+Gͫ#U∷J ;)"Vy؝{kB}?7%ζw):ܧbertmF8E.gZsnEB<=\tzU1-^5\WO2&1Aʅ2N_ff-66v[:oȿ 8:ԉKS9sɐ񍗚yx/0:QxEm2|$eseǾc | CU \p^3pQ0] C8p7ٶGj``~L?y3]ir:c]HEgu7͹R^,˞aC xtw|}{0:FӰXisߖIZ|_ gp_BT堇tCs.R-T0k:)nMY{mڍv2E8Q<}"1g a)Ð^E,6 wyVSK9haCr~h懋*.R\'KK"Ixf53+kGf9mg6]ȏn×\mB_UZoOkM蘅6x+m#oY#=\;ɤz3)-wj%Km{6驶<<8b3{rbG +OY$`-cMCRIen״|WGEndg6䙾"N~m~0o̦q%K?Zf9p֔"DQg+vS.~,¤xvq5P+*`[ "Hmh!<>¼,RyZ6t-{GrqV%w-PZ \<]yW\oUJ[hɬKxp?L1֯Qծf.Bor,Ug>KgVHŌkE\ia\FOe%3Fy"B̫9ۗ)VŽ.*:{3eL'߭r_gs>9n3c E;qY9iɤ߰7aW2 2ve;9 $,\`d=/?2\k. qv/yo'~ځn tQck'[›O ̈́?0ڷGlaNM$N1s6"1r(غL Y 9軎A\sq}'\Pjw+?׳_ׄ )^Sp\WNFR7fbY!ItuGxxsgIn}Ƴ '?Ķv<CてaztpV+q;.e k8x'۱[#Qo|_tߎts_8̒Zkup OhXQKq~c7Hb[YytO+)~ ^ {@ Q0{xlFkWL`t=,VHL讬1лgg!j:5LVPP8|Ɖp=2l!)|T5:42_ZS`U"BiEȖ*>hQgJt\FJPM&J8c[\͚^-E@%cىw8<>"< kqF \ܚa,(a^;+h^O͍Zݠ12fQ3ŠLJ;ۇ:IdbOmU99~}:>m=•>ز6[*ǎC!h^A '[N;M9fn0Y΂mhY{qm 6NNgk>~e,Ή#]K};NNSUJ77щJ} 4<]F:nz~m,ƹuNJ3Rl-b$|BhDW snIXƝNw>/V8#MTM9w`qh<_[L~}sGw{&>'CD=B] ^#fcSk;%(=7$[A"5M]y\oIĜmk!'4H#Y$c2yӊc itܸܽA?Lj` Kk\Xql{I~qqlȓk2C1JpV w‘OK,%*$"LxҾ/Ú -AZܾ;^3pNW~sf.e`3 OvdE'YӾl}QqRv$e{u*کeK,ᥱ+,OJXmʿ?Q} zc|D[_+q%F&egCfso%V_<] 8.{ڗt׼LmD3~\=Zp{뭾&c\uՓTLk)xq' g2&3QS:nK=0k7)dx#bsG ɔʙKID]" rb5 YKIVȒL,eluR̍b6H8)چTx7bo_j̭g\WZkc>@up,ҵ„Sm}կޔ]G[pI244y6R`,٣h=&T2G;0;GYqٍ n\Yݝ)trd_=X2䶌"FKZ/RN* -qx-ǿEg651'LxOGN4LFc_a=i}НM1P1.b̔^NddF2[or^32XTpR-/>~ncXSp2,w\,{`²8O1&Q\ WQ!ڤc|ZH9Sdt^ŲZܣcrƇIɘ=a10DZTHlPr#. u =GcN7?ե&>o}o,|B1N?$

̠~ԏQ󇉀eLFlMz ܾLʟ :?gõMu;PH߱z4zs=esy)FI@(|/h.DFTIqBͩG4_t2b53̨A1=UBW? 3c+6^mxQ,yp x^3cH$;șSÕL);[8cr[ Y2攆yj-CoWCu\ U1L0kS/<py=DnQM$tp:JAaV}襖YqBGkNвrՠǏLI0Co`OV J]ی`$Jw6pTt?GΤFoU3m_Q9[BgV5LN!HضM$\@&ڳbx7( Nc ׋=V31bj'WP}q5nfY30 Cvc$?+ES"Ϫ9ATbbz x=ja=Z=nd 'ocMKޚ: -f}.VQ1;$\}^bpE%8 cev۔OiYG=# ޖ#rCS,vzb6,Am KkNE^*:0~?EP$b} 39d{OÂwGȊLFO_3U6p"-8>KLH}H~zwmS0P1~gq£Ct\ŠOزڅw}YG) tSQcЁ갢K=N+2wƆ;pX& UQɡr^>lNN3ŸUyY!R̿ 0l G8%vMƆ>>L]7XńUj3rZc_ŜD'j;ckN\8É6@1D=^%v5>VĠqb5j+x%t埳}*E ":tLx1٘)Ȁe*uY:gP(<~ M‡-Y٘ЄÞZp*S-JnR;˒sҖܕsWkηa3{qD /ή/\{^j)Y#o250ZȀ ஍]ڈqmc0iAXwm/ӱű}*'4UB:pB*TO6t3 Y{xga ?H_"6^=kǔL,"+4 {zv3ba1Gl QVU#8(.:nXߒ>휍ĉ8 co'cʚv w`X 2mSB4LEoR>ϓp_6Zh vj8JYϸW3g-^Ĕ`63uW1'l~uťkmpnqO{쐌jcgSll¹wQZ.qF}6\<ӎ:1k_,ױ`6KFt5W\aOJ&dԢb8DaR lk1vלoh;%SV&܈LJʡ3g:nhBptM^>Ω+vY`x4gņGERn)\ HXXuC~Q 6+9 d|+) w8ljݶMl0/Ucs0p>e< *ŝزӄ^Zs3K')9n-6щx3э^=>ʓ׻38םֺ G]šBi.i1 ɜm,GdNwHY2 [ǸS#EMg0tsNW{#Fj{ VX0h9ϊ-b<Ez-,c tP m2R+bnd.4fzoosfKӰX+#66>W+C~gVQ>6H30rh]P{;6|a#S~gƒM ilPm9kXpCEA+P~*"uw6&iQNrLLpB+ȡj'9Ar;+:eۖr7^fl%͇Uq wo1z@(%EVJ,\;c,,ƼhK.ݭGԛ?ݞک5[ce&aG<6g` ~N1TsM<.I, Ï`k[߰Vkrӭ mS0qnNͱYإz;KE y=%UT3k*޽"jKXQtDKs(1p̞m93^/皯Nlw`EG9"O->>&~Ř/CS5 Ϧb{Lx~()VROy*5/,52PC:i%5NbFJLS Ⱥ G+"3RE|ol??>}Px=0g~K#0v k!ô-u5ٝ-[: ^@If)G 5۠t8HƚULTzS~+09;M^͘ѭHy{&{9BȨB;`df\ŌCi؂~iNKUYDDŽH^Mرsۘ1uBn =6AGw RTGލJ<1e,ybBsc-B%?yN v ݸ 6^:r =ګ-n2KuB̫M9g;`4H(^kB{W[ŵۺ q0FuݝWwBH !'8ySg8g}SEAM}43koc_3f~τGZW3H-n9 ĘuM%ps c<ޅ/:4& 6zC4>?3o)]LLgYK}j<-bL?q\ݓߍcj2@ hPm$Zc*Xj.1=wg?!کRQP/T+9ލ9Y:4Tgu4d9]´8a>Wx8J4ZxeXPw9tvt r,3 Ş 骥8r eT6ɍV\|!kߞ˨Ɯaͳyv?^.)blY=Ε/ؽ%[2v&+RH-cjn{)L?q.3ǣן[Fsߌ4T#kR?PwP|]n: ֡>!&/pO5iߴӱ-"OTG_l&C{1GπMg kk}-kVc{}Of}Ɯ)M8c0ǯ؈kZqʜζ\.7/wyn'DpՋJ춖 }rX{^e",9[.^L*Ov E.Wb};{ro-cn( 1vȨvTAO wgT]Ϟ(/9Pt\cLεϞ,m+ wV8KJ(ovX/e\_K8W79閐59xZ?kيˎ1c) ;­5bߟ^RX{K]mG}2V3?a[q>u޵2>^u~6g`S\Ż+Ѹ?FJkt%p,cSWY Omgmhv<ģ㽟н }J=0ot-9L6cngm)B!!,yϯ:lw_'}BxDE{eـzkOXlٽ/~r zFjC%JO(Cӻ]ɜ{)Z ,(YtAx~ %WLVpq1GlO.D1+D|Ņ-QDN`,ǜR5zXrA֍ds> n-C Bt9J隒N}طPEÎ>TEu/+x滐a -8߁ |*55[Q~DlRգb5ՠ!C^fl^FIތN17g yGj_t`=`ۨ9jw'b7xǚX ~EP/'M7尳ּbdB['° wrBW=AͰ~FGQ,\c.+JlƨuSsĿg=𺑁$]`)VaU/8/jpc>GX6WN_b]!fdN ~}YEĆ_r:15gIx^JG1op+MkOtq\jۼ9:|3ЖDH09Tҗf<МkU pVKJEw<ڗozR9A_~Ј)k" ;cp8; 5_rTFPΆ޻r؛Gz3)[Ŀ ܷݓi0Mvg'kZO&Ł8]$YzEl1-؄=Xl5*q`tqZ ^砦{IPk>te0>\5AMݎ'ZG4 JS2dA>}. ?pkWC~coTUxXֹvюmv"3ȓ iF {~j)eA9v}/R& SM|s:Kr=~Ԕ+Z2΍IyLJ)|:\E<_nk݌ Өއ GŠB?)tX>ėg41h(XR_ Qc($H1_:ܩ3b!H_}w(IK)k'9pOO=>/LNǓpvEnx``q.HR'bhLDU:mcF\ޒ5mŁyOϒ{ڙKV[#r<ͭ@H5Jqk0ʼ `4%&}p&Ḟg סZըLJ-j,\UQj\_SXȚz7ƙ. 8ދJ \񬶂v*8g?LQz fVr7URBO>-@O[%ܹ>Α~.rv *n|~Ssƽi͹#5|y^l'Y뮪@#v캤)yXAJlơPȸ1=ቅ5 ;v-‘8D̮tcd ^2n(8ov;54jF0σjlF]Ծ͊ 1&<+w_׹eh\ l=CgMy--ڳ zXsw{sn#x1zC1@;>=b~@h?cJsMoDKL[[*h݈aZ_jJR|oj=MsS;Mjͨ*eesҒӛ3maK>͂.+g]fJ^Ѝy*>ׇ3PƘJ.kCÛJvF -7jڄoF"2՝YkWBb.X#c c\=jĦJt3tKi58cF_eKi1:wŘVi4Glaz\)7wdqۊ{sMyz xʴ1ItOR^Թ76<(-B0%-N#7~] o͟:4^j|[S`Zz=2> hƉ烼Qc7^CZ+yM}<!eR$r7)u=HIRY+o˸AMAۉ>|Pêi͹25er_ oousFU1Xr./8%[3m)Y%grVy_*v[s_(^ͭ:ܨƣya,#gļ*LwK8Gם?oQ_Âsb6;Y ČGkm^ÿ> twǻQ아y /%xuחBH.ŘB>(1~/+veI & "MA07mMm{< ѥhxT#U3;`x]Gc8+ :\Wݨ \5;8wSUF up_'l|N D UtNf,lbHΈD9h*WOݹs>8=yQ])r^*gd.RHxx+Ӊuvv`@;z~6Cv a3 ,c[<=&qnO 3؝FEwb|xb=F.i&Hw8 X~Ç<<((ʵ9X5.F0~4,*s,]`4<-~dOt,Pؔuẋ5}xg **VQІNlE씳TM2%c~/WpR%46|ArPʸ l̍k-)^#&9H]zبmIy&Fuj1݇ln1Ew(I)FӕL\9s7/Y-7vZaͿرsOy} '\Dt*}"*zPJk=Kݔ4ӄ c'and$ S~Ad~C/=H_ht.!?V:Fo=3?1i"M}?=GM{;K 0'ja}'a{b W/ґ(.IJV,R֙JqG";,zUCxog!e-x>M̫o<ڝx1)ܖ&a{_"֛{1ȓ{pVr~ř9ی۵YN'k:l{rmVIWR OJ0W9"6#O ϣuNjS{ 4Ѭ 5Kˮx¿k MٝuIDtKAw;Z3޷9VFQ( s$ȩP~ 'Ji(G-&ה9.о@2f{q%W5ޥ뗈a0q,B9[D3s;aԌv2ez1zwz1n(FϗT_?󈑒ϗJ{NHyJϋwzps)%%*NLq 2phw[==#Օ;;qTg:W[|5 751Z]983IHLR_ꔽ;YX|+g}Ct8?EA%aMPє?St眀%W2d`ߊbdn`JT +F ^T(Ybaqxq/qH'rNnKw9S1By@WM+lGs ++ n<.mt*mxM30 S&Hl(݅!߶c#Oوԛhm pzJn7c,b'#{]}ث>g~j/ZJA^=ً9Q}E{9[\+z K<F9tҍNoŠ̶as+ވ0`M~+r ա~-:ڜo;ux{DZ( C08 ZUMo?;w:eFt Q2|ka5>I/x$uCW uUc*`>wb Js^̗:rF)EcK$uC% bN0͓zq 'ߕGQ,D|q؛+DrRGbi'f2%dwl7^1kD\х:Mvϙn?ŕ#߻0Qי/)ЌOt|,M{kmi%v)\A {-mZ8g'OVmw~[ 7Y߹qn+{R̓ tĶZl]מ7+aZ'k\:Ӊgq~vbJKXaSv;cDZ )j3l_/%-yfCܖh/#L,((6x*:Ő{՜joЭ}U9G9Gԋbw;J⥠y%7*M.|Y(hDX6ؖNLM[ ӤiM:ubN#F]f1浔bks 2+&tO,t bfw<,Zc;/]qaWoNq@e4zˈiQImoxnS9z+[`'Fw.6uK.+wˬΜ m56&'B} ?bC*^t P V1 ƪp|i])5݆@aקPOfb\=k$ .cCoJ9cr<՟홄s{RÓ(nʒ(Sne{5okip„ }ƄŒgm(}okvd|| (:S!-E'Turk⿕e5:c԰rtm@z?ݔ_TVlԉޫE=-xau hUntԆ tb1V(y5Mw7MŹG +){yЇlbHb |k b OXm]ee8QqYXDi ,ǖ9pKޠ `HGRDio>T vf&a72PH`d< 2 Mr7O|,o%b3N 7Ajt:ȀsAsF ` DpQ"feQ|n?;]\PQcp¦vȪBd.{XW*|yw ؐ`B>C!0Q<>gbI a-87H>OB_/ Hi'uC)O昍"dĨhy;_\clb ^O(4Z?I !GwrʉǽL9r&o>-ؑ^t_/btKQr_.;Ͻƛyܰ՛SjL9ӿ%QX8 ?iaE>xF-^irA.1`z^!oCiLXd_GAc=7Կخuij o!nYnͼc^en:|"Zxea[Z`-76|8ˋ M ioFM+m!Ɔ[pgKMřeZr" O: lZ;i1IhOnpԂ˪-y%)̸\1fL_Z8RF r^(a#Hݹy w`nz΃b)q]|{ŕbu&C (;E [,>QGŕ5XGi\Ei?'_n&1Ɵo3x3V}NT&fLq;.ߩC:1Z=q_ -GܱlR(M^k&\wۆ! a7$P=Cua2ƴp֔7e#C:Хz:]EbOǛ,i_F|̷X!tSֿasU+]- iݕ\~uT§Ո*Ĭ\-}lrY؝u*KۤŇB,- 9o["#W"W柰mC}&Cp'JpM Dz`e!3 ?ѹoάƭF\0uyf?=MߋꙁR\q?( ?;`b} 'N?UؕYlŻmis9<+О!>jGTutԥ:;j}fD5eAFl+ފ+w; ~ 鶬o0&hBǜD9Ekp M_A)ZӈJq*m&$f|_狐 $<-*BAt^މ{hɽ\ЈO-8 ]D }#/츴!l*ľSGCȠ -MOrn0T:o]H VF=hz-ZNEKѧo 枬C[ks{!TVȲ^h5*GT0J eSWW ~Uc£ޓIIW%K*9⛜ԍQg"Õ;r"{ɷd?K!0 S ׆l9# 9%fohyp^kWM_=0Daowh<ƌvX=Jİaq=m{GкVtsoN 8%ИV 13FC]I衞7L\ͮi!ʃO:1b {Ÿ?2Ӑ>YoIZ .oDXn9-!3# k0cM֠~hfO=FՙI6 9vL#EPA>"#kMRڴ%x~jXYj|0OyRVL؃J]%W[TQ[ɝTwI"~sО߉҂6;^}[8NC~ % jsjqm^>N "xU^<;b&Jyd3{iK ŒOP6ӿgGN~(L 6-ErCָ9238ҵʔ_% Z:˪%gunϩε8z}, l:T6kvT[/jq|ybl-cz(BsXeK@kz6*?cj-%z|LkuxUG;{pe2JʻNM*F o3݊#8!+t<5j|Y Ar\QuƧyͭqr/,(H¾ }ǚy(_"3Lv歏l^Y=(e@!n`gEEͰ$GUqk[Do3yNߙfDs~~nB~l{9Дtxc#,/CTֿWrltWS) Ҳ0"/GbmY_? _]R ^69-}0 w0/f"}Wkq =jT娬EU{uaR ]ؓD,1 &\R]x̄s5x{kFم/ޢTh#Y GߝBxrF߽H ڼK6Lx{a:76O^<5sIls|qj5kW! }0&ӑqyqY%d!މ3~:sc-bf^,1d>;ijJЮJpz^@Mk_uPV3mCvf)\-w"\4SbX~Tg|Ujd_FԮb\hUÜjƞib#%2Db#'j1b6lQvxA;yG&=g}{pM'g`wt92g({ޘCxϔ+o.rsL7̙{{n9/SKaj^ 9.oy-o1ۀ29܁f ԌrP[ ƕܾ[ dH(*`|唓~<, Q6#- OG ^OEq]o/*LY+xג=N:RΝ_Xwt gKeƬzS{='.A>*"poR>< {n]4L.@bXBWe"cj,JS4½c N+D*}F)Dͳdz&3\ᗵo:b|9?8)ڃ0O4>f:c)1㨗Fi0N&/Yy|3ap/ɗu[а" pw4ux.؊#TׅO C3Adnl[;@EnQi >w眽w|?kf3<)^MU{2o4aVJV׺W }6sHso¾i޹O 6%1+̹9UjT!hRGnrTҧ30zI_"`u.ѾA vDΣ8;5{c9ޔpV2 >^N,KopVy .}E|ra4:כ#Q'd+! -&fR;A*j}z`<ϐ[c 8ɥ-S!fu?}_ۑmmWk[|_;ѻoVi&tLyPM1Σ*n;U _x76bM=әv?Utk֭=́eY`uV=|=mF+;qq$6/H Hi.MgOba ʷ $EN? }hh˖":;>:5ǥ]h0="#FF=꿼_c6+k:܍U%k=-벪u$Ft*Ok>ؕ= ;?Adke [)2e@rls \m^+ς1:))˃œ%*HEᯱ6u)$xhۆFlFؓaB3sÿr+j9W={m4@lT~^=׷bs)^m7vP |uO@0ZfpA㨱&FC8P\jikݜ4K4>`˓ ڡYWw\?]x輸 )9?7]Gxm-6܎oxpԵbŕSf`usXWp; 3pMP ѫ6@ϗKƮL% v95O?0dVlrDlڅc8{/<a򩉈~x`O.U1>o8*ŵ5e $,2ߗI +k,'uC3]I{mnfƈ}Đ# X՟.MڀYmUBe*f)IÏ_whhnhp{U \f`uGHvL6L*R[+e_p߆ںTn5dfq :|FQow9#ovuszdN՞it]pD̓Tr(Fx w cZҞl(>S7\[Nwp$9޵K0eP;K!y#qda ~;TNar3_+Hw砙I%:>8{Ĺcm59YL5W4ey6 9fDSN)GXVUyw']۰+YsN 6r| tuf溢+ ^֩۵nq #cdO§tS/%1$r~cޒlXDz ~ 81a,,OYSYS{OF]vU֡qOxe_1OTvmϺf6T泡v<ΖU7Pθ*Rf>5bԳl4}QW0>[γbqZnR^ڡwh$+d9t\ݔS]bQ6|Ċ(π߉%~ef˯ꖖi’[zb>o &?&}ۗ~,qA7|@U`'%v!Yw Kmk.Vs0:}ّX?}`])&9!2.hxN,Ki{6&DW}^*7˖;(^H8OmknѡmxG{4qu3E%>ߗ]oUoġod.k4_mn 1 Öͼ7mO;)O~MuGJGh(                                                                                      ƛX|l}9yJ-z7sjo} ߉}knּ@s}Ņ%/_N<{ryvna>,pB^ˣ-Q/PW/l|׿B[Wf{,k) yZ}s8픛!ڈ*L-ֆӥ7.dj`{$dÄW$RvgڧY3@`Ȝ<탠ǟvov' k]Y{aP>YoR$sūH+W7^?Ῥq76m:p ?gCtt[Z!=z١t$V܄8 3; -hAFۿ!ZݲMȽvmqȹn Xϐ}3CL<E0V܉>NNuhSi>պ$ԘY/5?t617t&A6 g6t`24 "#`H8uhJE )3l+ۖ6d2(Cus ?j&Eh |tYhw6|; Qٮ' nW4uU~ Gu1K{$F;f!X+N8>k-ߛ~Rf F3MRͷU\$Րq;.iGnrV5bK{*^WYvk6~XNfPc(Uӳ^nc6mlj#kmלFGtsrvP7fVк-Jdj.scki[f> SꗫMo죵^mೇS-r!P(r4ocsSA)K8CʤG^η[]bvqCktۄ 03 Ģ-q/kqΦ)FArX`Z4Ɓ;xU{xwN  (iڇw׸s^;^yiII{nfI$t63ZEqsn:j~?667f 3FHV$C}0PQc1iD n[,'۞}`^&ey{凼Y=ƍ lh4߀qr'6lJZQq^*et7_p~}CZYƖkMLz[;#C ;nl+Z(| )DJ}NGre) nUKqJk֘V#(8ݛ rm=X^|I.;aǫܠ72fK,Ӊ\fF'q%OqldrKiUۑ{xsa/:z3T%^Hb̡'\Ɗi#9oww=آA̠ gíֈ>k9W^S [yw'mت+7ء kta2 [(#'6tc?.iW+Ma3Otji~}Oj7#UKUo#cX~U.! v w(?C;_fM_t~fL;HM`G}4[fDDKVa0o[4yߛ6k.6d!g 7:pE!ģo*7W j)v|@ ٻLˆOsP"}COtTO1 鴹`nG̔bucȶhL oRȞb\0= 7GVˆ.ڌl]7b:gzӛO;GC$%&{е+/V״wc˗^9نZ[R}ƚM8-[1ၜ dg])._ݘ~mxOa˕Lrs,IvgG5UWכ NnÙF|iGKly9]@ع$\;n w7B_kQza'KZ*7˖]7̒\aDo. 4 y ŸtӿKBtٮP5dYO #*`"݀,J)F/0i5L>)WXࣺ*^5SѼ“ Ovd@/ᳪ^Љ'p~}W=+{vf 6u'ol%8m!I8>ќ~p0v}M8=՚c2B)g?N+ 𢝯c.qc5Wwgh k\a:ܰCs\ɍ?Õ bA7NQ7m[s`g]9wWpI-CL*n!o4n;t(K^@/c'#+u:<_uxiȾe`уBƣTa!7f%r]"Zͦ*yNw&,jI76T[3#7l`nžlT`=-1TS[`^WRS^ʏ5B}XltN׃w)7 -~,<O8P?3k=`W̒,'U+OzVty~rg3ъGWbN9f7H4>_b g;Z<^87io%7ZD%i N~%+v?1G2[JCOdv7zf;Nx'wOr>O68Ұ%{}p`E+k9*vɉ㚂u Zck F=:ţUh;N=Ew<؈YS>ҙ=IJ:sronܦ䪹*n~b MU|g);,m<k$ط+=Aw@BV{Ùށt S87fAbh ڸw睖7}nSIU(kDHt〷1Y-ޔM6U8Q6|eJ/뗏e|b8gv,a Kp>\(ol͠xkj'g]m \D:и3)/ ok$6}z-~m԰fe|J{rb+p=U8QWy0g~7#=ܾ{odX.#Isax\@c{\+uu@ EX*5S˝h֎s9Zt [g:)X4P_-8bX3jyqb}(Ƈl%|oKo6n=8+muphӉ]X.l7ωxԙUE_=-1Ō x:g 4.)tX ޼)ãr^Hvd WvԯuǙ}wGߘfH' &ֲ=f,Bo#(O :a@_v4WE?b }(Q0 ';SgL2_6W"g(KSXX_OXpW+x 8B6.<2#k3 , &rm%fK>uKo>g_|^wP|ƘJWx4>[`ˣ+;k7ojF:3-gX)kṽ=)?M^p? H_h6D^<ɋf<2GcY2nȖq,2`{'S+ǗL<)1 A# C%~N,>+0BG6.zM֙rd9߫8)]ġmgN/|IuW' ̯a}oʚKV-1# 5딹Ë߫:3.LGz0ci̹OjlОCA*[῏k6ΗYn=Lc!R?^S^swUd;*gr 95 7s"/fغs'uot⣺j哿6W^{{ 7ޫVV4c #sw V&`8|NÉ(|cG>ƷO8y2P}P ߸QG`h1zUg]ǣ&wbKa\1gKNX&qnKt7%A{~|?%ߞ--5 wDsڑq;0J#ߕ|ߋXΊ9 n{p>M?Օ=xx}D鯠k"B"ܔșE<%0Ԃ؝LJp+vᅏ3d}} 'ڋnSMb1(CSSQ[ }MY8^g(TZזѹT͜e> gr~co~|C-uQQchbjnWLɽx0ؒ# ٻY!m|9j#~Y=n,>TWuFv;\#m.g+k#wςv-i<˖G8ȃ0odo]6חF_-4\ԟNM9a?mcBeA4]Ǯ3D:wAM[m]+fŮ1mK׍鶯ߎ*C:ڲ G],Ƴ;<}]xu5m5ƀ^<5+FexۇJ}9ö>-|ȏn|Η|hʓ3Qo1 x`*}!.B^ ;/Ǝ(݅8K->{dj-f4N1-ӆ|ܚ:ϣ>g'm2)`W}]4zVߋ R`mKte+'y[.LdB/[g,io>m</?K!(Cr<3ic㍈nG>Ğ=WvBk4bs‹2|Uq%Gal{Nڮ|əyz\5NCoIc_Jο~9Roվşv;\˝C9|[sڂwrq2~ 9*ԑ-{3'wJ\m՜n$eØt/y4OCߟ#~z0lSV3a8=:DWu}٘7DzѬ H\7Γӛ;ZreF}hn5L0tJI׃jNXJ>,x{l)ǩXҸlĔlGq=Cl<kѻp+:믪ctd h ]]K%=֐ZOc>Yj8[ƪ̨+4)gr.d/|O~\xJCj8=V3Tr&YgY\+#긲EslKs3o 2![rœ7biʅʕӦ;so0~K>a D^= 曾r.IlI('&&E26&A dG9H'fisP!laebB,ٽ[ky5_Q3a/k(iޙq#lף8)%RxkVBOjw`P-!k1}T__NyךOڱ?SJJ*0Iλ[cl;?ڣ~HĶ suEc8 = 3faMUXS>Ne/hԆ[֗N]`RkZUa/_so?sf35N}xɝ}N؅}Q,)-ǷSiX. fr6֟C̩55S#Kr߰lxpLX1W1e)М?(haxKuc 66FtN6"PW X\‚]\_LUG}iJJz{fE<+`TUŽ`CîPۋ*y]ŘWnɖS>6?\Ɲ8>c88k&s #M9pT{Fxx26/n~Y._@Z$Lf[MFӸ4 F|D=f]0X~fTf]TЋ8/u>>@S93wظs^oq,n1f>( BjFӳ U!*oƒ1G 5¨O#-f4<`zxg{ m!ioG[c MGVcE2>$2w ۵7bF43ө%0&m3+1^I~tK<q`_va05'y3ڝQt|a 1D2]mCwTz^*9a(cuhˋM073gc)eq] fG9ZsKO@\wz\q&|@t~`~ ! _ds,yWj$ ,}k;LB|)߮Tn;d?|p]_W!WKupg wNT, r&f2 }&:۔NQ-En9?`ʳXkV&lSςm1n#;FF*q(Yz- evْN=%˜ׇsJK u*~xb6|!_^G2#x1q;1m+],Ja ;%-Y̒lgVN?PCdM8@=tjŠn24/ r6jɣ5Öo'etCly)rsU}_.&lѩl O/LJƖā]i>Y)}9f =Ss+iXGK;__uv>I(G^ Q=_fvć{Ncu~au2iXV'_Dhyik0/[GjM43]ץ?F󏆬6a6%e%[2[)Bҭ#9 b*w{eYXq; dfIir}x␚16Ys.55kēGzx73q|Ν;rA57nV\EuC,obAR>jRgIvJNq|r﷦yQ?p4'QIj9G y|nҍ8}90.+ƱS𪟂ΉQ3 JqR*g͎̍7:8@n/f>ݬݝެ=WùM8ƇKy܅oӕLz1U \7A_nbyx v(&s&4KׅULHbyMm]N>b%#^G>R* (BA|RSCem]vou4F5gvS\'/:u-.9SpGǗ0zj10H*%q޼_śWxШf`;gk>j,g )KM.exĚh`\ck8}<tIyZoxizJoN84HB#$]:zLM)۔b߾-/%LJUhX]oQz5T`Z?ۨԬǗ׌(ևa~U9؇>֋<97'\j*FV;T(~2طp{Hd}^95 NmϡnuPtV;6<3EwyRF\!0/Luqek٭B(gZUo'8攔~8 nm=Y{<9{2Uɓ=9Þ }~~֘Po [x꘍]+<}o=Ǽ$Tl5bx(7rzݍY`~Y>, \rWq1h3 :@t[%a) Rp3,^WI:gNK^'7g'yu՜affVja[}_8-zULfOV규]|!r7p W7cx+#vw/v ,!3YE?`98 E+u[F8%36bRfESl?{۾ۗ{ l Vb vbEl((={=sg~\3d@5%$=h̿ZsU!e>n%ȜRjʼxz01AUG422󴔉P0%w:*9sSz+h2NC'lQ&Gbsy7#7RxYL~Fp6VsӯM<{f"ƵlLiӂNu5Zl(0HD[U\ClleQ٫/x$iwp54T᱙ =t;q⭃vwn'Vq.t 9lvR/Vעt܀_*(i(+RR<>^lT7~bYnH y ^Ds-!<c~: -o*0aB Ü6s,R'Hxr^ڜud ̨Җn:3n' T46t/+QyY&dE) <ɖ<8{eL-坃2| d`;9[WU{>RrK7IʶRoK]Jٳ.ɃK:Fqp,?шzw~ ujFew͌x|.rq/8<78w;=Ǐ<Y7O9O8d{848\W1Gxu;B?WHAZ~-YutɈx|%|p-6CfY F pw|76?ťِggr?=־na=^lDwZWJJ+X&lFޕsv mlbh[ K)BZ9/2@. vr eJzH ӱG$~BQluL8ڂc3E!=*g T|0i߿{ѿGE Ɵ12aP!-5k~f(ܓeyÄ0VȟW-9Os#/8E$2\e R0N& B>{Qml3CDoO wP>&g58E&RXe>õPKPc331]I.177VCaihZblMZw8!Ͽ nZ֖Hb7DRmMS əu* wbjgxt0ٜx},mgt^~6$VxT.+DR/řs9 r19G= y!5ݍm90 ׎؍Y,bD YwVSJU2S}1ZLH"ˍi"knufx3d"ꀄN噈|ٕ7y]0<ώINElnOK",φr4uգZhSt2 =gB׵ uu [w-][]v݊V=6cJSԥe 7Xo}ZSH|RVf֕/_Q*?b %O+8VvE >3qTـ%ml0NrVƹdϨEqr]rB+1_sgF5E[B\X,2%3xcͺ6m LŽK"%5GDOI-tTY,BJp.ĉ"\D̄p6Cry&&|Ό,ˆ{8bw.y#!J /総2V ok:jŋy'{ f:Hl(!>ZB_>zΙ k=zA?}q}U>7+6~]{D{o8V+qj>{Xh>\k^v.7/8]]UнlyJ:b39>#/T`X'bk߭ &"Y~Ug ;zTOWr.?\bNWrU𼏌935;UZFLFCWWͅ7dLڣdH f'}pŐhRÝS8;Vֱv|ɆO.Tj=uvg/?P߶;%XFC3OL5q} îc|Vߘ6'3˨J$fafI-zCGG-V%Enp13Ÿ3䙘" -`MaX!I]WBJqMm8r^סbT@[ayFنwdNC5BUlW΁]ƒj9_QzMƷ2F+y+.V; G>1jtKeM-:bfzy[ki Xŀ{b)'pmGnIˎ\ƃ>͖) v.ŷF[vT[]h.=em'q_?c 0e3tVЂwpC#:ga=>9O+#FF;Uڪb2G^\_Bg tm@"Gvs)S͓=~՟$lՆfթxv#zY8^Ι%.c|wQUls?`p'>pbGwCzH׎+C8Ď?w;p'x 'j;Ѓ!rwue^./q"cM`NBr*,p"-ÐGY6ݕDttMG9y//nY2NI\zX;a֦nX4 l@s_߁`uo)ri'X93G8b|/ԥo\4ˍyi1\#S?^rVl?'ov}O'+©X3)urYUlicn|9u7K8G.c>O{ɸ>{$^f35cG( J1k=)}9{{ҀmL4,PrNCh7_xB!JV4UpV|FjW&>10NrnΕPtV!LK 6`FטCtݮ0LѮ&{5 k [mKZs;&-g|^=ԓ)?*V۷L}asv`ͭ w8cwN]$A (@w X#qh8B̜PE❈aN|%pr F8r0F,ԉ+T5V)Ī2Є%fʕd9gQҲ=޵nFOGp7-<řWx*8{t5\"+ ]b )8w9\6 Ppi.ۿ>ǖjSk90c[vz^՜Ę^ FEe %}~ˉL@W1}> -dt,g ^s3Qk$ohۚsMh!ϬGqBW{m?Dn`x T yiAwvݖ9 nĂA͍ O3cm leˍMPCX1 ^y2&SLs)P17$g g5b^ULP"~? @DEɸ2 >\+ōrNڡh9ERvIrVyڅG?Z~3tpe\i>SqA 7!nVl_Goӎc_#i~FfpL0`VKNmAJzEHXI6pb~Z5]4l~Z͕B$.]TvM׃S 6b`@~1)5`ŨlEXZKp 1v.ZAʄ4< AN\Rs7a^YÕW{'b*0J^QNS~x`~!/ǝhd3g`mb>GǞ Ŝ\Kg=Y6f9چ^2SG'lÂͱ !1vW`cHŧ4*M޼{Q[f[l l]bƇ~4_8 ~XGU<3%o|фWh5"w@MG[X ֤?\k-GW:f S o6cj3Kuy8/T!]\VU%>2 8[B\}4Ӡ<ыύYMLør%WiػUwCI$ 7* f)cddMQk#w M' 1͙Ǝ։C߆恦ހTbF.T``7G~7bILǸkO0u [KnY&t !-ũ%`V|qڭZ:Z>\z׀/z_C'A?У\^ՠ2l+CVl3#-'yݏx祆BcmՌyP 彼9ZݮdwO=BQ0t\3bH y8}_^)[^&`dB7Ol7<}lDj3M[~aGU>B׬70?dlqcE#NHIr>l@O#lx~-*\I 9~*/r^Y+M;)L#v'yx8vA1e'C'z0.w~; .y17VÐ b*%G񮛔ߗنJ=~//Lġhp0l 1fcGx-f|KsR: m0+*n{ zXmõOhaF[Dȋ0ƭf+1|`%}I.Զ z _Hy'̋Fk,;xLCTO˸3ib/e(Zz^/3䎌"7K~3;a=y.Z}U(( c*e2ݏ weMJ<7MΆ2FHx.֝Anf\7%[xYq(nxwه΢Cݾ;6cb陁ʼnHk3g1J!)t]2C Sr췡' ZƧ!B.fHJ i! +AQύʠ] UZ2a^:l~Dqq omL0KjtwDN&: `39SN*%wS!!VsiOyl[*VYF\V c%a~~A ܄pc[K9Fub?ޗ3@@1\YQ"n{>:<ācZ3| wc˫μÍ7x𼪼Pqf;' W*^*zRn /̹U|*eyvBe*Q`~',7c:ÌqXV#a=ۘ lEx\4k[/U1$GCOEc!o V)SU!" pca. Qӱkvmk i0ڐD\o|&HbY`%uv0>W!xN85 ?dbɮ4? .~!O$z|Bį¾I>¾{i[wt5&T:a;k1氥t~) OLT|?M[%Tr[Kg8=XPgB̈8(ـ>0lGsѴe(O sYP̹amRL~LX0+oa6f͖tmNz],evcC"jscm G ԵUX ly.&nV_ B;2˥>`fs&JF'ظ+yAcScJy'}p\gK1* Eȯ ظ gDAX63<8kvy5QjQq~9"AʌRy#ޮ1hqR.o,w)cT2>vW~%}z+yRA' Zl3R!(~}5ax#h"&XU-^m`$7, : bP΀<;XS0|uM4NԛFk4L\*$(nYsjbC>M5L*Cs: Gw=#_d?FK-b>!VW> \0C&cґK-]{mwiWe%v{nn<ĕ9ˎY-dS3w5S 1+6&4n̏=ĄeTq3 Trf弒/qȸy%e"fY\+g;;%G>Rr..7#-V[&14ݥϰ˱xqar[lJl4!0P])vv4 @Hss{LL(fNl$>zq}J0C$J>WfwyvŬĎ-{̔eCYJWZ!+sӣn. #-טT´o@O1gw?\Oq(]{Ue6G0U(ܓ3Hhyn# I![K8GMh,bP-1ʓ ]8:0KZ 3bhOZ"?߱3K_mSP田ji♂??OsJl_ X6+l2Ԓ/y`==Citft`933{vB>~x:P` {z1e|zA'Q+Rƫy 0 -hOK$To];@_IrMp|# {`|c~42`8#k!1ħ#^xDgW19'UL74Wl)fҋZ+ Tw6*95MwT1T+|5փrq3nu`ּ՜wMX5f:ӌ{q SrmMI3~< sk /ws U;w0ܳ2Je{nqX9gQǨXf#4FvVr>)ww^ *32"I/Ѷy(e2,Plh`3 :`_X6uX߃dlրky_XLQ򕡚(Yj!LԦJnߨBe >q[rN#;90?ߞщv";i½\?S1v58l0mqooBzl'0E<ܓ!!*;8LQ^4Z/tϒ[ {G">9I1?\avQL+nʷ nOX\`#_ \=䕜c,Z84VUE qft옜n͖l_gSZ3^% *MUO pO:|O!Bx{ƒIb'&r(?z{NZ`h8Xx> &᧫¡bN]7r/н!Qa9sOGrEsJK&b V6SfYVcM^EÀ(/DwPT) km8=yS%wS"ʮy0; ֱ)'mGGLYspy*rаSq \ ~ނӈ6%텦fѮ3Ƣ.: ORo"| T{Sڵ5KB+bWP* Q2s =y'XsGґ\W.d6lϨ k^K5c[*#Έ'tNwbr}k0ֽ{)+çVD8HuWƐr̓Ot jLոm,ۑ_?y1wnj6ە(<6p$}LUʬxφ{Q7 4앦Jb#0Q1}4|o"]II;wJ9M_ݩ𗎌nʘ1qDq^!V |EB03793l+LwgbG|31NQXlI֦6w??b_eL_5f*9Oތsx7ҪЖ'Y ܈!_ x~./!ٷY+-L.W  k&q}^2;NNQ𣳜FJYC<_-c|g/v +%X%'J`e!fS}}yٙ/t۳o߲IÆid]qVql=H.4xP[s4 ŒC0UB;2cv VFKT,,q ߝ+O- qzw%3.iLaf<&'[qkFIC[^rcgoX~^Ie]4.[N Hɾ/4+}S)[-wܹ;<۬ W9@ei"jSI^DlcRwL7#G{:1wGGu+ߐmp/otn]Kz .;ͷ_+kNrܝjG_6,Vv!bJ{‘̨㻑6|~Җ-$ˊ!47潺\H[|O~oݏgDzǵ;`=ZMRwCL ba1gs9g1bV ( "9g|ou_UPU}]o|])y\?;z NOS]ΰ %(:8ܰƢ|0k%jE,ް1/k Z|"ǃ*50^ F<gbWFV;rFΨtp; o̙ylS~=O7K;-mq"oh\zvh1SX=jKŎ7)%鐛H-v8*tuԠD-GBSXP5M`E rNk }+ ^RIqu[..vDtnʙjҨK9TChEK0u&Z6X.(1}`@p#$'dhg{rDzlݨFF=0`|uv }uUf,#Z2Y7r<:.g2K7"8o 6Lh*5GD&:_Gf㫨w\Z,.]uGD;w'jnz|۟e/ӡ#-Hm4U~X4,͞^C1g ڻq1@Aåx]ƩqP7;` ;^66fpJwDg {|BH.#ф(}&O˒%t iSvҹ<~L#ޡPs>fYKqhTB5Xaz|YhLh `R g6P  lFdz,cm--a}qv?AS}2}ZA3-:Wlpj%Ra%ވ7cgx ˲ȇ:*wB9r1,B!ZX pCH$-u;X={M?K'nznu9eѢ %=xވ (omD7;XqJY:=/{%$Cd&l5eu<&}<| +i&1Vk~7xۙT]{l<Mj䏗CK;rT B*do)5Qàtkh>dX`%"4ѤF%SSQH3o̍41 %!R+zݰvӘ(>)$WYZGדq9&ZK 1+* /;:JcJbVx9NI.qF.2fDŽx=~-e|le1Ld"5`:ݟBi៩eJ9L!Ve96Z @!.`pBϵ(aS RvX% "f1duagޮ*iB k)~=nn{Ow΂;Pam1DA V:Pa#d4rY!J& |N6Ҿ"Oη}3 _&%}YT@˴VM6̺]F`K4C;5U"A_l%5W` 1ܓ1ZcjUV,|f 5m6]5u>[B=oTWONlëcܳ. 8طң몳3֦TQ:y6ZK+ +3I)KAOh1. \:;/T6G#q^=".סC?=ykHtOcWB4(!FI?躶i3+mPh<|,C˰Iͭh; '_%H1pRJ0kD۩YT俘SN{c[[ЎhH]C7pUa_6((c\l;_f}.b?Ň'Sw0vb9MݝB=ۆP}|$Ji8]F[ZX:0U.t9l!$'L+шAqz*bt &W}4n^Zq:. 0 Q[YbܡF\GkȤȤIc5ČH<|-AǒS=7Pjra,P#lLzFb`#כ/|8B19~TeBd!..x[  {3#cX)R^nPw)dql;Zhˀ|Kj`HIO>vb9:T}9=ZNoAߛ֛%k0:8QaRb)02U]`:R~/H>0Gpᄡ}fYg][=DCbG.Mkle|H=N7:L{-L2l!xG8?E"`3Ïl睤Ӣ7iT'ޕRG5ig^ Tcc8>R a =Z\ѕ04o@&20^X3jԠE?x+Y| `}cM ֚CH;f_BOplYﱷ}W^:+6̢ t4 m j+ƀ%Ns){Pi&T,-j`EZ]\[kB[w>o3ߜ 1Հmp Y^w#K'U(Czpp{71݅X`ch=8C?'ұ>tA)% G!9 0G §n2&j cD kET |Id}rqƒt's#_Cӿ{2:Fӡ5,X2u|-F ܮWa[;%ftû:qe3|Ԉ[|O\ɳВ>*]ߠǣhP INŔӵD>.v EǨ!o!6Jq9E-5LOUZ4Je|'|TF9be| 9L>(k+Pv,?O 7ɥRi`s[D4[h 7,1 qQpwX[_{VrS`*j44h0т9hDŐZ.qbB3}LGz`gOE4m>I 8XB[<Ę9 *ǽRlFY'%oۏtD(zJ}SL*ZMc I7uT0 yX(Vgjm<ŎlxɥawP ϭx|™|+hI#jLZv+5t Äl `?%8M!DtDx%{ ʏ&OD ;4vm'ng n}OS4ngdYD]MyBcȔYHr$N`#L`cjWv0B X:#sE=U 8[(pq7Xg XsifzjrLHPJ32 f[C5Eaa'K*la|xk,u_2|FlK%ck{5u=]Z8MAԤ{c=F2RDžR2\6~nq4ғhA焸P0[I`8#U6 sg!fbVLrCi/heה2<&)yb w+냊@"Wъf b T68ᩛ 5jR{ !/C/;9z RT{*ffIc ׄ;<`m^Z۟Wtz0wBr*' {1-1/}hS…c§K!ߩeJ(pxN+&#q%G t^:=Ô ^ };Hy wL\[\oc2~E_RH'pd!ȱQR0a- /2@wfB)Jax W}XwSev^6^$|?Retp-8fGW+ B 7` uqB8G15dhKa.m[xR5VcA( 3(`@OLu:6b~E<&AJ$4i_GU9l P v93C58=_f&Êz1$%"t> ʏVzlF U ZRı0zNtt*Y& ɂl56l4YqwEyʣ2zm,Q̡SiL2D!tc(-J'9~V"\J+Pͼڠ1W?!%%xdSn.M*&lwƝӛaP"ƀY"8N[8̬/Vs*%Eqy=3}qUPc R>@'P%GKw5_(ʕy+DD5NCmo El|)K qjz]HNS-48w[h5'l_$BJ)dzK`#|%&ThXV[Ň-R>S)fq!w!D@Q)>ϔz˰+T؉pu.FQ.|y!0P12<3HWY@mjG=H暑$#*Sk7%J= r峠v音hP@o=% $3q\t.J1Twri/1_]n tJGdupNA]IߧQ| D;SH\^]wx3\ĬEr.椰9wZK T@rn`9D|O|gQLzC4K=h5V)9XY)$F+aOOɸEwA)MN,)og6|:McՇUT +k3[lGb`D(+0fq5ȳEpƝ[+6B",V8>bkGceX&D.K#q9#؈r.r4pZkna_\AqD=GKP"lKР!ML j&`ŜZ'=]5馃 Fi0k|L DU85Bl.']YRF$mI/$Pd*h^D,k 9`Ml -pb^5VQl.2çt9o{ ^.7_,%^#~ $Q֤$tF;QaqkmJ~p-**Q^"<*>Rp#" oOWbJ%F0 ;7A9 lㄅK~ lT@a){Z Xą <|JFg[P܊s;>pn-c=?kBJR올@[:XDbvM8q]z,:ffZ)½D0|]3%쿉Ѻ/u4;] S"SDQt!2=)ҢVtk-0 +F!^P@U+J00GOo+T|bs%lЈl:Fjm;A/ʇT&!_cgq`2eќx\B!\'K0\,BP ְ>d )6X\ L_ZG{dEj0vhKd:&лn-6.MmxF'5wq(oeavѯ\Sdx+O /rl7 G:DT;=u}wj-\\.E-!=#\+;'G sl]B;:z>&۔ˆ.wcy>xyf/ル 9Jpt3n 1M#Ǧ *ki-:ңW,;L5aU;3N!:!4$" ޳ѧA8e2 T% R|Lt6VTCit;vNٔvzVSH|=Yb=֍d:WCe4N#m"$>2i; N#6iHOv#mR/BK7Ÿ#7 Rpۏqz6#qqf Y3\ӝhtKu/UQկX#Ӵ mAC>gb#}$vA5`3}g˟$h.B[)nǫU|<7@*0 A\ 1J3؏2an'-殴źrQ6L#zF1$P ", VBi=S)ͥ2G| = Nbl!ŻX&jx Y<9ڔ(`^׻tȞò4-) htfcBv%By/ĜBkf XP>Z/2[ ą+nQɠm0Ɋ+8QE3hƠl* Ff_)-#N) ͂RZJUUQCͪvK9QDç&QaQp矤ù;H~fuuOp{BKwޓ= !T[d"I<ܬfek*Zatd-WB/)4fz;ʤkTmU4TA -Qz5흐HmYԤ̡MUe p&D7JxwVD9ZU ~ץ]$U-?5ʀLM#!=N*LBPd~^l #!:)m~1Zep!igg |w1mrO | lcU0~g goEY%Z1N Iq O?C&,d:pKZaB۽:e=[2|!A2aR*}/Dh.2OYAPmnf!-A#OԻyo[Dɣ羥9J_ ci4z5μ,+s|j\VDyt0ԧЌQԴ=&o@vv:r؟&̦'[6H$Ʀ/u 15b YT3DH6L$C1t9rƎ* e=-1u5}UC(9ιiA5.6h96Z! kVA l+&y` @gq 1 HbVF؏6;^j]am7Ũ0#1f;)N4%6͍!0"7CF, ɣc-`*[w2DP@)~v5kx7V}>oj3 =X̀r KϾ|G+[4Iq-uU)3C"Fjh ı,x1n*|f9td;KO( J!,$t&fGo-_啟3JOl%ٔF27X ]ov?]򿓳;#=N K\"Bu{G՚u`1YPH{'8tR*IGSzXaxrU(́2#}ͼKOz|&b꼼^k{hK7X'yLlנN agh[ζ8v׎0ڃkmlBƩE[)3 %Ýy2\TXs%*.^]f*v R-Qv,9>Ԙ6F>62.ZL!${ D0Z+G{ڡn=@jSgn0P rc±^b R"y' tRP:ʺ\@?~b`$xFמ;N6y݈:^yD0?j\g ߺ&ayf=9P%ѯ&ZUȽgKK3d2ff|Į8:u.'ǣ'>W@38qrWm:iXebd얢y[eـEFL 7bMG1hF1a{%qI><:2-Χ=Ed5'M珴)ї y->%%=s;ztN'Q^^_<+940 dcr}ؾ\cU8uրYM:UPqTMZmr8,0M Q4}P =fFRNS]|RΧO )zwfaAM-FRrh)Fu peJX$rMp*ZZDŽ,#>xڡC;ޱGNNzUSҡC3B9 Fp~[ =X'mu9_Ⱦk2‚ A)zdVJ<:qu\<>1~O4"=zqqZ"Ad8YaPa3C0!̧1~Md@:~Ĝuwr!;I jb+: zWE %46v$ۿ(`{1zLڑ!$VMU neGl=tɊ^t}^{;}i(XLn>tϿ 6]-r.Kn%Y!GVWmpr"f:{dRpzf<}ɠ q IҼԧc qb92&q5lY.@_GM"N5eU}g|vؘcN:v1܄OFM1Z##sUMvHWмHqHd KLuo_#Mj%/ґhHz6^ߠ)ǩl3a{ߓ_J5.X,9 kfXgj].T;'?PRNzh߮VqaN6Ĕ;燠]4C31C&d݃,\ŧ|;Z ,`]y#҅k;1yWm&>i&NPgf2WWF* =>5X;@*˄L-sEx^;譮C;BM\Tžܩ!})wʥP o+gb'A)Џuc¸#]}qxdm=A+vFH>ˁ4)=s>Il <tfv3eI58܆*L很a嚌VGS7D1F c.jĩ}ݘ}s|FzYpY8VnA^+×uJl)b,1Fv}GNV*V*^u {3t9Da 55g8|//_l-y{_TG,=K y?)P8ӂJk C\#Ǒ>6iƠƼҀr6sqW!G|?p>X$Sjms9ups!O &M\"vƖ<׍d|܃A!2h_Uh.+FXwx8lz-UX\\nצo8u| OiqEȽ n68)n<1י Mp3f gei3zLR3Xp'!X4r#^mONFmɚ uv>&wK pp Fšgp^Q$b4bc]/fu6# 'hp ʄU*·c aMkuo77CdP̯CݾO6Oؙps9MaNet-G+5n3j}" )Ӹol~;Or& 6U#v2iqB1b`J% 3 X!E|@~j? ٲÒ?W8rn+sqH>\yk|ΙK2 +Zݑ3Zt@h,t"7v)q%T``DG<n߯f&-Yu]!LȄ6N~đ|5Ă ؠ*ann+W.;$Q)恵:lec=c̥W,ǘk@ Vމ1Տ'{Ia]$KxT!-8\ o/eg1dm!&Vj+ 5O3>M'"Q;& _:y-E@㎇s[_9'J鶍 0䆩̮k+v(Ԙ؊Lp[LxԄFs>ń-7=F wJØHTf-mG{-`ibfiqQ{-XUvAicD-2ĒSM1bĚܙT~ ?#yQyߊR D_y0.VEbzs3]坘"-l ;ʎ̶V fW(is*vYZ?j%y>B[e.?tyJ݈X[hpAOuNݪM`Me!CW4tM{91ύ[/倌Y.,ld=7bmDblz sk?>a.0^|~a5jΆީ^H5+ɛX?5xRl}=lۋyم[_Ix3O9JX%]*TUc'GW%FPlX1]3Pp|kcµ޺Y *qT:ֆ0(-y ۃq0;h9OaɅTrbs%_l7fE){ԙCS懘rG}wkkhbԋbtv76"9~vB4#X۵ʿϨiydOm.)נ{*Bi#bj;wʑ?f1 #zWbz|҂󛔨A}:\y2~/"Soa{o׳Ml6RoiwѐktVA/$GAK3jLVk)`Qy6wqn _y--Ο-,cZvL~UL` PVI[OQaD\ؘۛ1tk߁L4b?^2)s* |edK~7]\c;8N̛_ΙY\X/ñ`V|K0LV9ߧQ7ĎA(Lc쵨U?XkTʜgɠD-N 1T̀]/sH9E=ϳ) {sMRec Թ`<`|0Z1̔c6qKyx]LK`"~g8/ 읍b4E/ 1#[ 6w`Xlၧ5P[oq mQ h0{&_MѢA;e@0W}[(S{eǗ] LecڧdO|hxx)OaՋ0mX\c^qFeXe cz:u3aLLpd`8L`; [:Ɨ3u8ɧG݂LXHW阵k(3iU*L㐑v*[vڧX`]}z7F?2Mev=^! 4`MQcI6~XBX&`KE*>Fʄ"=F c2F|1̈́; `#k:sKGsb#wW>pax#r,Fth>]rtI÷Eܬɟ;xi{:W _0h|uBl7]c0?qee|vcN̓[F罕\.6M։Јǔ-r5/lgV[[gsE<[o6㵴$'.8Y0.džӄ^ka_97cdxtI'`"ҧ2 fmHqZ,j&cFmx6_z6GV+VGyxY;[̱{J`,Q͸F|;X'4Q)A\-kieURvSe1WfLWabt.Ż;EQ[uĎس38ek ifϩ|ՙwS)no %ܱEvL3D=5x&.j5:Ueh%B7JK2V@oG4La)[8Duc^,= 6݂ٸxjP㫿TyYK48M~ Zt4㇃,`=V=Ɇϧ˴9g0?1?y[w)r<[dbߚ,4NĆ7>bkhyOjw(Lᐔ^ 2S~DX4=wrF7)K/kkHdwYXmڈ9k1H$HpZ}ͦ:cnb3Q:]Cw iG-891Mc*2|ˌEBېOB4-x~x h\Ɯ?R"DCKeت\ʼK@sRׁ'0n~r)Jc7iS#LgI"?|˘]ȿoH{{[b[}"nԵM >InJ+}^p;rș9ΎiƊY2ȒNt9 K01/SPu+N\Εߐ9料8y\uc*]ٶcW0ӃߑL.V55xLO 4ެƟS5xlRȲUbr ;z< ENS>$] o(+;`ZQ7I[ z5~CQ _YsKFL.K#;vyzT j} F5C'GA/4hoE2eF&Rg^Lē3 ]u.K!/cgVcQs!~auΫ)vntRZIgn6ͰLOS庬9nN;GSk={tfg~F.aLWؒu2_.a13I,*#>c°0M{?3wr<*̋xÑ ݨW"և2(&l}:,,bkmVY?*=ߨ_9|*V#mNek5 aesŰ6s-:;d`vY{E;,C`w%ZڴfcjV =I#6kD˷pGs^x 7'ڳ-+ss!yQߚr,U/B ٸ; g/gK#&]j^qTami{ÀE|BzP{5‌c~V.' fs^oKMΜ8ɌͽmiUh-Wfqet ;tPK?hȇGi߻7^z yؼ-2+ġO1dh5tԦ: }L>#瀫6LwsFi /pR 5UTnDux6G|l̛SYJWaqg%> բ~`G"2,b%!R5$M!d @CYDUa9Ez 1啋vVÅxl(\[q9Sn5'Fqx;Rrߘ~( WgacD']& ֧]*69Xv/j0Cn⏞.h24Zr| +v oV ]o~#T6}ea>,Hfe;m4 <d+\3 ǔYk -/SNwwkBԖjHk%Z0(5Z)K^Ⱦ\Mރ*X&z\эh^jer9Q05yֈq-l:r^qnoN7Qc3jN5^&΂]\SرA. FxSTl1񽛀MX"d4WS#LyЂǬΑ]hʯ掬d7VۘD_?re 輷VEh#+\\Uп:7U#Q'5[0;H{xe݂5Ф4<,䠷 N2c* ^!N= M?kJO%k7HSY- XZ ݜ#)·]x[.Ǒaǭx̔U Ds uV̐217s!m͹JY8a_b3\9?|ӛkzyp%Jx ^[]Y]74=bi4!9 WEVgaHYg_Jމx$ęSmrˆgTJ|g ա?mBЯPt ($Z~^]v x 0V{YJI|nNp+ u, ڠ~~-&/ÓX{QzFq|K.2oάNRqĝQ.ŝd|]%"&wbɿ풋q^ǁ]a T`qbs W7#2 \8?LbojŏdKWl;A̭Ȩ[*qL6*'ؑ 8|8oxi3ߡolúBK` zŏ4B\7.L<~)|).9i/dy><-s߿\^'&uE_TC?h7QuN`r$Marţ?ȝAy?Xs#\FKuWOi{rMv]ٍn)U+ӭ\@J?)_uu˶ F(wn3ݕ'x #LLSZ#Lɱ'oZ"%3Ӕq W<)g> LJ9[U!n|$3ffMѧTx`Ƨm8= X[?_+OZL h@*Uڞo5KFЁEn|ϝDu9t#{yu^! aDDlIx4?-W)5XPI., ;.dU0+a~0#/PgNEXBKFй˿]cfe=EOw7{BTJ<]Sa+'$(ESO5t3dD5ej. eS2V;tW0K 2d2KAkgxp7Qy\In.qao)/bg8s]Wï2m2+ !}'J݃^jÜ%miE۫B 9{z[Ac^TIzRYϓ,=xaDF'ڥ^XP ME{6ZN֣9[S:d c]+ŅX|ÃjWb}42wQ`%㊰qYVT"G)>2fp+ S(:Ɠօݡ gP{L.B?'8E%<9lE6ő*lzɛ\Ǖ |^#DuM[eß)! ܶGXNvލlŀ~Z|/s0'Iƥ#ǰtU7%aTDi eNڡǧ\ŘWTc[1:L1NJj˜*2_BGp몕:8z z.,%\h{TyK7UѦ,6<7j+kB&%aBʓe=p'{0˃uC Ύ󠭧;ϻ񡇜9_ۍ8=)Wwk(O '_/~KaϏbN/}a6,}mj㖞=ژ?_ξ7U!/w:Ʊ75xOns[i͌5ކq#y%HOr)3dʙ9̋Uȕ!9k5w^*̦p9V wkpr}狟A7{sk tdWz?w Wϓ1蠔 5U8"XSDW >N]ީvW%0Ϧ}Mo($nq6`x{T`NB>(ץvvkL] aU*Z,(^<>V_#uhg@R׈zP~0ޗ C\X-KŻ_x>!Vm?<n }&چrQHyef^QA$E {R>Ur@w93yr@<ߓUWXޜ'o.ItaO c;11ω9 ŋ(1ƓY!+̐{=9a'z _棿ԛ ̗'{OdNT%˭Due䚲۞Jʗ2e |'9[uS΂;uxImŴ3T㕐Z<ۓq>V=PV@11z ӑW l6G= WUxck-nҌK+vU.~{J M߿]OףA|( bZ-ʎaCz&en8:EL%-nJCm"ԺeazHܑ(A; ]s֓ֆ -=Vs2z ;7tTdrTNK<8tvR0';yT1aT^ɕ'"ǹDq ;T)>H"c}*Ř_7'Zg=mr9'}Si}S /Jxq^/W9# PUpE\DŽYAV߁{|dr ;+c<1Ǖ~K?dž z ze:\9n0 x$@̮xn"n\ `+D<5whR_qk$^݂q+[w+Gd >Ns|!BnS>OJG88 ( /Sѳ11.'a܌mX͋ ;+ `0===xqeܮ/4bߋ#V)x msw%LBTeL׽U8 E觕m* ؝9cƦdUF=>zfvV@3]7#B "`X_Y]N?:wjv`v҂N\ȀFZy*rSƳ|nFQ\ؕlW9m%kW3*U2#hp*G4KƠ=qP I>z>@xj#x/Ղ%r07~Sa*2uMg?vu&{xC 9|ܩ-LBLܑX C+p9=Ӱ75USq7!*y.O)\~؃n{0aLd,-cݙ^DOG ̖z$/6G[JX95щ6۰9A{-_1** q`ٕYHr+uu&F4slԗ2"CEUvz<^;S h.L7zQ_L?ݙRvQ2:B4sv!aA3vq]vXk#%ŀM{YngK{gfS&6 ̄$9Q10VVE6caͫ(H.VFjqP t*K\gokt3:Ƨ0xgm1C%^ ~j1֌Xݕ?\=- nAڬG[XY'BvÍŨ2Jk(8A* 6-3 wS'{ă\?"eM}e pu{x*88 1guBgmF28 ;B5ebzlg7OMuet_(^˛ O{)IVs@;κ󼖄7;qGDR)+gM'93Pǁ1{Op~ܗaGln-Me9ӿRE}4yZ797qq."9IJtL٧zz׾c8mȂ4MR}ŝ}coy˲߳&ץbl^[0¥F!}9F΅jة x8 +TmyO؍rNQa60ē'{v)4kٷcqn8KNBr.tF3Wvukέs.OU!;ֻyV~ɚ4 \UGP68m:~a4xDW[R2&<=ƒk#lhّ]Yr̓^`YZq0xQ.Vɫ0W+j?FWOC27KRaUJR+Ō#9zdrYl=VSp}?eK/WvTpL}C>߈}pb@7epP?+\;!׎<Ј z*5|㪁J*uk6S9ٔkk-i}.@O3:<7AHʿq7 tRa=58-P3G tQGOM0;x''a/?Dq*=y؝ahԝNw`כ9U18iS'~s1n;W۶l}͙wc#Ltp{Z[2ǧٳnGcb`yFȂo{ '6(@_8;U4^J]MA &LA79 VQkU0ž97O4hOkdȂ6q,G?6ⴕXK1Zu?l@C<Ň>4d~`^̽kcϟl{]WzuYe3ńwß>_abG |531S)=,Ĭ9PI)}Sl҂-h1\ؗsP~-aK-wl~9U1_{Š-Nnɵ]yב9+сus\` h3ҖԜXʙ/SyF3t)y-+v\4͖gX^s~5erM;ҥJg@he_JN-}EOǝp_? ss qe-pr{D0xڎ{͆tڐ?q?Ù>tރ+9p-kU^wm@˳4Z˘+~Я58Gv>KR{TxR՘w m&,*$acϨqĆ1iN@~)О ;b`⛂wp)G;%'ppFɘ߀jYƃF>̑.ґgf)T'_濜Yȱ?Ӊ =4o˷%mm/rn3*sZE[2|Vs7-^ϗ59*V}-"ҩI@K_ i[t9b% RcP6 8ԘA#cS=3чߢпqyh=O7j5SflfɞL|}/ wz55edKUn+ARIevQ$uUr%rqk-vO摷l9Ő.KչG1JzlQϑ`%k4#y.MפcZtobQLp,?w6`jw\tޝ9uc*wby޼˝AlܞɥtU+ƒdM9xsgOk22|L]/0\Rj1H,ׯäNQ ;v2$z:Vpih~*ldafLYc+y;G{qlQ3=ٹ= SkQ%b;s;t>ؚr^˃:,uaJW&:SxSs'#:{%xkFeg*?ǞąZ.cM,d-ReƮrS^ynDq}4*}ڣ*{`"qsU^OHGb$x~C3R|I<'C./o wB:"Jӡ͇kF"[pbO.!F9Տ68p"^QrP+OB84J<؋1a/7pƒ#K~r2z=IA7leVg*TRn%ڻԢ`=nBA%ڌR֕h:0>q-N ~Ȅ$zfEGջZ+{0Q1wk̽XÃ/㼹1؋Ι^8‹a缘Cnn<|+T1ۂZl8%ƀʜDuvO}.lwMWYm;o֤oqlU ُ~ސ'l"u/zw}}l]Tmt `X]=¯` -!E2ўy]IN3ң碓g &B,UfTbd?:ňB^ b2΀O KD|g}V"q Ϊ!xT1Bie.~cW6>-ņ / x3h,WJCqL4)q{u̬A.p1lnq˓sG64ߛ'c=hؓ&q qwsg;vf6 O %2 ~b[;kR{6} 5# TGv l1ؚ d7]-;F~ryȜӢ X.?Ip]1ZK=U2СZN@UTKcbV7e}ܼ#1~O";4_G2 ֦٩s1 >|K~9(4ija_%j?IJˎ]$UUdl1ϓYyˉZ"Va~̃x` _^r(#~X}YnEQrBVÇN:0;~% 1lX QK:R]9[r=O(nj>O+Ncm*jb!qp%lӠ2Pj:Q*TaD_9q7;7O*zsU7yr>g>/Ц&7+j*D8-"\ HǐQO{EkG4˃jSt_8*pOz*2e{TOiec65vͷ>,H`'p:5{='cq%nxþ7,3Ȟ,°7^uFU&O}ǹQp"$uiqYp2sq Fg+XFi?{, U>#޺wFg",]3T XEJQ6RAjJ֗"I h;<f*_f,ڍ=^՛_{S)Ûe/ݹ0ԁ[mښkR,X{LjgQSEYq=jO)3`h۽EF-cRRSpH޸4<z) Q#ao<K?:{'qf SUn9xs-bQ:XyM xwqW<fE-to^V47GelK_X uOr3JRp>/$OZmP G(:Q,4Ng jsS>~WB1 SahEe%`ךxVC-<܅{,!_}xڋ_ܩ1ޝs\=6:ߊ-sLD1o<uy&Cæ3!3:@%M'¯D<FgZ95 UoXJezoµٸ̕,X;òW,Ǣ$3x>&S}1MMˎ; hrI7&c Wz1A+%cqLzށ {Of@1 4Z>1j\̿"oH5cn4bYG-R_Uhe#KqO }F90_e IbM3}׽xpC_>^G'\Հ> S/F3gp`{6gV 0j\Apo uJLmS~!$0:F|js܂eMh+]\ LBJ RSƉ]ȉh1fnGd8¨vLF{6vӆ^f]?3ڌtGk~1 P.9VʪzڱFYˡ^i~@#Gc,ՈۤD/*(}i߯h9NʾᗢMU٪U#k.ϗnkzu_Nh|ɝ?"9{-3flζ^y[腜G $YzKH^B=>sqtNF[-/.%>f 8/7hǮ<9)wpCԬÔNlj昉!Ihb,a * S&wdE6{j32dBJl9G *gN?~z/Rj\0 OY5xSRa\x )(S9+XMj1lwTk-= };ᾜ4՗>}JSZS_ v<ՊM>Đ;Xs4"[*sp> jCQ)$jwRQ~ 81b^XT?l.WaM!&XK̜Kܫ;Q-z"cR,T *BQ|!bGw۔1͐ʎ.ѶqflgďOi]'ܲˈ sX cd'!O&\sOKwi l{X!ٙ84!w M*bGBw>'co0@p;uYjWioOnmA0/M{lͼőUL8-[ )|™8*^53%վ?Z hǎWsTu>gI5х.ȕm9JYa1GH|\4\0rq.2Y*Ɍ|Lݝ7$eŷƛc4$[G?WdC]Hk}y'sPcvmθUHMTX]g~4W_[-fqOoX[iSRIH=OC0L܇p0نvиzLJ aF1*kP o,x\8׼4{8#ҍ '{-oXMokwnB][e*дO-SA^˶80,b‰Y3WKC"Qɡmu)Јì4ف 8%W.8щc9-E(3sz"*Bpul\;&Â1ᙸ:/uoە(-E2>_`43cGKt!nLIwh_O7s٧V%>{߸<|hGu+\r pp&P㒥zm.'l`#9H' uk{2=Vkvtn[3iǞ-򽌧PSޫ;?>çp:Exsb)Fq [fn;doGx}SGUOA GbCw SdX}79,SvFQ%2WH%B:<ނNl݆=l &]V[Dž+19<#]5P4 ֣1oGU5.=1SL{7u,]aՓXYxT~19&?#A. pdw>tL Nxyº*Bkq mtܶ9tTܔ?3"CvH9=3{L.0DC6ܛ^Rˠ[I;et23'񠿍3pCb e+cXnP*%%u#ꎜǩ̯8سѵxHK.h'e{}0h9-gXIe8-? WyoZ|AI)R3|y%APrTi6JGWv pw^ɺl ~splR%AYz2Q 18;Ve"ek5π\(*ƊпD~ 35hl6DLK|w.=mr<`R>rch3 vY|8ؘ MLӐN ~1/}3b>F0[T}!?|P,)7ҾX Rv̐=!{O?ANcSB<&h#fHиTģf/ƂG DE{ڳ0/fVT箴Cp9 Jzi2oql-N%GwаNWkM .S5x웉VKa86 o}C}){4kWEu!V} ~+xQ {mLStJ-gތ,/kglFS$#`b%qC>)o(efVbE% 0)T랝Cp\D (çF]_=fϑZ PEr9aqK垿JI:2(Kf<_Z?Czp|>bb'?`Ry,O$Lܹ s{4Nf AcK7G؋Rz o>}`,5o & ԬuaW^+:})(@{]F׺,0W-"5̗fk8> sUZWRd(rEb?Gkwv0h8޿uUNe^K'(                                                                                      Zpmn}~lGmW^1(̓ۙvh>>A =h}|򸛦R`et 4rdž;9Rч;ێցcdmx.o<@jqCOk(_>aٮodjRRM yvzώ&/_)y$<ˣȗ`z aVgNxm عT>~sO:́?bzz+)g4^f0}<~BZH?pῬOv3%`܋-?cRNq .7 Fy5 [FAUpfWU;me]I2ǣNoO:!g,y aț0t@sO_Wkhsl;Xw|liH ! lzko;)OVz26"To=|}$0Tl+Tx2#8? .^Lj6׈yFBe=剛.C3VrPƙcMz By*G}ZL[??>fȭҗV_R3gS?~aw]#o;m6C: ,tVĨ`\9QaZnhu)l:} ږ s'cZӡ:*U[7m;IR^g>^FYbrM~OqUMXy7r&^t}~‘ڴ Ͱ}|<>.ր>VωkbNW'=Lm{ %?}F܅Kw(Sm>;2E#s.ڡX(j V/ٽC.Ipۺ .?djnmtmG4;6K!#g_ 斈,=ƔI蟣fkÂ4hbDu|7- jc>,7] c3o"h1^(WA?:=DnE3nTu(֬eq -N [~oō۴8H6e.zm03n`j\QwV*PaW< 6q7 +cҒÉ+ظ%p!s~eoñw2.hcI)'*mq㳭\͐ݐr Zh*q}^W.%Տ Ÿr L_Ԩ &-:jG$kգePň:$i3Mգʵ~"vfȗx#Վ38q-*Rb,[ 3Yy1UB8BDUd5~goUq0%t.-`flk(HƜ\ma¡l#p!URm|aM.2aּD8g8aGrFm䍡F#;2Sil>H:ŸpR'v~]2!#fg9+v.A*77W`jU1Vl˰\dV-PW<&V|>-B,K/n:w)V j2hМ\# VIt} *PE&f2;:ބ3y&d *^ᚭ|˜*h݂myL̡Gkk2^Tb,tF x<3^:/\v 5Yaowho7RO|6tH-wpgscc|ad7d콻E q߱C IRFWH/UF?uioyY}'%.%e얬hp }mN}e:8FނgX֘>T[+}.7e6TƆoG1X+K˙3Ցq xW)O#ѫ>`j<,E|$UF5}`ȏ4͍n qs:uqM%ͭr\#~lW}/IFZ * ~f^tcK ( k| a-K%T%Ԁ-|츶=3Xs>znhg;6]7\W3wpzsq1[$PIךpc cDN2)2!#Q6Ӧ{U;&CKeB*Nգ'EƸ\EOkn-0:uj*U q'CK|ݳ6X#9+s q߆kHeBUM5Ua"kv{+{\JlL:]e(u4Ȓ2/cTcJs~߉sp#,BH/4yȚ8)~eG|;;g,݉shkފ 76ɖ/6+r3.0ztn cˆkò2z4CVA8D۪ң!_ZqS:.#w2k9l̑ߐU :̀oYmv7q&"W*wl+]i:ʞU-Ĉs 8ѢN2? ǒnBoG>-yY?KԵ*ӝR(^OOÉ_XY:ϼ `U|Y!|S>bΒ{{6NF! h7͜yWәu5+{t_C\ǁcV+PEyǎ?Zsp{֙!'&̄|b2Vp^eV6TmHQq<*\eߌI2\3mk@cwWN nh5VͶZΐMлU%pι•C]vʼn_f8w#s5Guіbtx^k+3-=c &9S ]VCz;}®Gu;"VW:&gQgG~Vr(D3eGPb/\-37qY[{VqUr13cKm4݊-ߒϋ3j1fj c,uFbl^B:S4k'@yb1}ĔӸ5&*zNpg`|gȫΊa"S#z(+_|kjg,ʚA,XU`Z%+FvYgun|c l΂[yK[fUb@J/??c%VA" Q][Һz&X^y5cƖni6 g+IXm4\Cr=[2%ўhO]fTA?LYefbpϒ,-yJQO38}6V,Ww7+;xGm0]ơ4Y ) t rGZ@"{Μlhۘ6_ ~Qw!= J{|w*wD֝0\P9gkqQS uꗤζ*qN,^DgCu?WUʰFQ;5`aʞxq ?peggS3Zu{nPr[XcL6dJ޿˂VZ@%u,%R-8Ԕy\ME g}ѓa c0<1y 74`:ÚZk&[R6ќ-Lue~N;ܕqK5щG,xj>gh0sw 86kj)p3 4b/4h3~6F?4VZ_hG}tјlb K{:F!:g9Z,Ŵ'x+b"b~ ?},ڵյc3 \y}ATaY k>oV3?Z6>o@M7$B^(B.{W슽cbo(b RĆ `E^ٝ}w}w~93̕~s>tsY- 7(#SF\V2P)jxcr(G`8N-pc%|BF+w0]KM\c\6A=3a7pZ~ŗ$ !(1vRأ4ymN tuu)<|GLf8am?'52<Ư*Qb T;l}7S`cg 5A1 z3S[$?HG@aFsh]HmOsiKZR@/RR:AhKnzVw6TZ6cZ-wyH^9G pvq@ d:xΎ af-8&*qj%82]@un* FfKp])k̔ qd{5>AW 8~I LSX0o!Bly`>4PKS<Օ=Q$Kf)WFKkx+rqL#zUKYc|0ca%.)1C*p pC9taoVun:`NE?hȢRհZrh~ɝb=L͕WB.lp߽̑E}v LQM7^|h-D*!@{IۑR(X/W#Zb};w8H )z $;a]mJ kJ`p[ M" o<_XFb…?]H>kVdf TڷY6^LA붓cav]~A.% tDi1!)Lj>lѠԸlK vrr(P V@8[G{ й÷NdX!6VS'0'c"`j9t1Gp"Zh1C9ZFY;mN}@qI?1~v:'Џ :l [NнA}̔@08EiR4w{bhd#zxNB?v%\tqRᕻLL 46D"q6ut,4]Tw^эE1v9~)tV&yNS7 $]QZTfM%R퉯+ݳMV]&s#vO;[I/fUùrE(\#Av )^}UD6I`ad]~te_-+񵏃ޕD1>vSJ(AWMq :7M?}Nm1ڙ*=ÌlVȳ0~H&ҽp7 ͔jOiFg!v)>?DpqX_j$Wab9(9P5zV`uRdasv9%PnlŠIDTna),q5lX!ta-Јt|XOC&fcJ0 qKB E2);ޫ6(.#WYRF+il@*IhZ!KCM V C*bW˰/>+OK-M1G8Vp9x*0Q8zS<EƘcqȤ[!nI?bOm**o!=qznoF7m?ڦ:s93ۄQJ.n0] 7”9|ze;`"p,p)gZ|TcK 5Ubs/GXtyB5J4[egDDg WD7l @e3s8E\>— q6CVcGk#. Fo>4@x&8qWH1FT>6e'!["IhN?Vݞ4k=ٗHI{0?Eҕhn+2?\G]rP ,fmn $лjLtS"l^sss)P_C f~ K^2tv.-2\(,{,n s ist[MD̻4m}DJ}N;mߦ _G1U;'C[{ 1bYk5)d,pm')`jK.Ip{XMj,yBJ3 ?8a T±jHk`wI jLQk44_[Zzsjs0l) "! SM0< KM(Jxk QJck_G:6F~3t.;<-9KWiuYC~C*.,LMae\1pH\Ha`,#w/u#=/Vo˕XmFQ %XqFhPA_7l־H/Ƕr5Q*oVƽ>ڧx[M+.c;F93D MѺK:X!-=B`lF {*a!Eo^9"Q->-GJ99J;sf@:sSai],gzr o8ͱ. qC~6Ҩ,N,G8p"u|YH#JF6?ΧyiDZw#x||C옪,x"Tҍu¯jvgP@1FXxG)~TSg~# F6g#tE}-0OkxW$4w 4sm&Yyg)[YG7aah5~2,)(/zAi0SjnbjtꯆWiR{g [d[+L&B7f:8:3̽h HV1㪩ug%}CǮTQ=N`#~AB܌3ЃX=s_L1_ikt=;+ '`-@c+1^b[vUdx@~w9f&XalG i`ZVmU9gFVQ؛fڵS.f 6ґ􂙛ev+zRZMs[>Vмi4]*+Ȓ>({il'|ek0cZ{:! ]e+p[> ךd" ۪d54"Va,BZj /72hdCA~k` cнdafmŌ,h!)A!eݧE4 M`vİA>*waza‡ t:N*-T3PtxK!9SG_ 3t[S1X d.J`DIi97Z踣>0j J,.értvCBui 6O УP9=Rjf fBx)iD{4߽wj=HOJK_=E"kf3]x>&n%2FZѦetٷђ=lf"Jcr)`#_"HGgZ YG j9:{U^-J/{o,/[z](/=9ą\)ظrMrH>%MhZmIǐ]-ٜ@7# dM"4?)R4j~kO(l̠<#|l KC\jlu)%O4vjy}̥z+C#Snh8yJS5߫I ^ja=T"4BCV̇ol0D&(y,鷔_jt୕=: >k=LhՍ^HkJtWEg掴)ojduwGcavJf$zY%2z2TH)'wS^@#kbLcn 7^JSUӨe=:#k#g7dﴇf w"Pa1֘3f«`41DFf )W6-,--Est.H];A!|\akĬ"Y9t:yD;ckchZ>-J;Gfzh^A083YY1C- ɱG33J\1.ZDgfj5<7 |ΰ 'sE~7$0^*XpTǰzsfZ #~a6OA>Ӎ8!tP8t Ѵ5DyImЦr2&R$ڏ0t5>.32.z k tX1}HEl6f1EdžOXJ'^#- 67_Jn\Q QދUXvqƓ3 (K'Ə9k~.v怯v^ 0sGO>L7p۳rSSjq"('U2?[Cg 59`5QG)EL<]]Mͪ=E,LL}upq83z~$4,?Hֵnq}TY-d&*q "6A$1|2dK팋<ީYGxqZN~J` 8dgLZU6-H>?#ig߇Jy(~j)a&-] v-YcLgY?{7f'8joA6wkkOhD<ܼuquQ  F `O5NjۨeJ,߻LJHIr)Rv.\0a:{=YEQ|nrq3SP7l_SҵviΝ\Rց=M_u>@YZ-YO*W(zJ\7: kgzʵ 4v=Wcs#бpX $m,-b+'(?(Ak  dž|T%)U޳Z *3O :,6RqFfߐUhFuD/hA#O>eJV[~n-]>JW(A:þy ֑r;M|4`xk,Z= )hn;Au V"9[ei;(1`23 gֺcRb 7!'Cg%bs85Q$_Lj dxMvfFM*9oU&=ŎWL54.L~o 7"~@?mlNmcQ)SȌBY\~jVdz!}˯!QkVRJSJ QdX{H dH%%OTH%՘w#,Y.R *{IIHi b>9Px6\K0F7= $O4m)SOmh!xǍ06PveO y0cT*uj}JS^h>2Ѧ';W|&^\2(pq5'gm9K)ZpݰfhfǏa+|Ls)6D [L<" UZ\C No숤*W)Q\Fx1 =ިSceL\XSP f%tvdNWФ1:8fjuZh::K+nݾ$ZcvRpmX*ގKEPL^b!=&D\W8\8}M6 WPD1F仒BN2#7^rf2ݮ*i³A hcT:Z g2|ϖK s#K#GA2(^b9j""HU0C ^|>чo]0C1lЛy).3{* tpXԫC2>rY7X9g1 K"LpW+ߛO1f2}]IW܂xAz l˲h?{CB=J*`x < fx} 2AJZ NGX2gq.FxF)aa$rqkFl oy D*tS㷹ט^L׸LU :~*la@rQE 7U~M*[t9lYpo??ٴ`P9Ņҧ}_ȫc~gwp=iI&Ͽ{߼=BőJ|)ph QǑpgrܓr#z)@@9 `a??cb?3_(81_,r콣w8D֨|v7m$X Y/2^Q 3;3=" 0{Ow,俥aqT'M+cz9Qq6h) 3FMMKk~)ej G*&HC#.j8?/^?@ᱧm ->V.G6(Pb RNR2nVRYQ#+Ő^ #,M1 4+ ko4;g  Vmrn-*|@85)b"G,a+DȑD_sRHYc.Z7ȟD_GrO<.#,JBڝJ pL-ual^3is3Z$YBl<Ҷ5UIԨxB`37[C9 Pjj *+2S@?p-Rn7Ԉf|4Q^ Jp+yYD>SRz-cA>ʘrh 5E 1!&E~S?{?F_R02mte^)ٹWPbܚO UՒЬl~Ň]<51FR)Ƌ}Iٕ8 99LMRW9vDn3α\qLG$ n^wxok! cGIHfVP XpRDoҳ4tM]='^;z~;LAYg>{$ˊ<2yYOW1Ft*2;Lj5LP#h3;h7 t" M SIh{]?P?1ᕴ.&`W{=.Uw6Z8جƝJɰVU¢*j4CKhq2JZO-G7SD'66'L~a` aPc_?Y|橡y'f8CS¾1TI9Lމ!bjG09wA\#\i/4W-NhJJ6QT\E~J> I]wQ;1sl%mVu[;.a>XA2Rm]jhJЉo^V%Okl=N+0 Q٨9d!r$p تD$9I1%F9+K}}DC:;#9Lp! w= 1;;p(0_XsxBGaJ'66hcdyΫN"3# u!2>`j;#\<ŖN{Wlpt[#u-l"Iz VASKo1=*&J1WbtP sC5fל:]טEs}o=S(#/9}X]'_*Ǚ6j =]Cz~6 N"tA>2>VA:i `jp {~#C?wof셧(2;7Mll tcкFzYJ]חP㡕u0$ZY4R5}AOA5 O|;i_̥\k}@!eacU𰿶lEE5Z`lu-N5ER^ 0%RXNhjoP]~ߓe-ÌCLaG9R*|571/We7ja|U&[nqef( ` 3)Lb1c6y98_(`?DSVxN 214}Ak~~ɖI,ȱC{UὮ xY]i Z13^Mk3X?Ua *н4xFr߷41/AҶ_}r|U[QAdؘ&Vdj)̦,ZLb1c7k*KĜ{ik6|ۥ^C<_ghοNKiVLJ K`QJ+jInlY! 5grc`9Ox#iNA' b!'˭T4;o=.`19y sQPeL(GqB?qH}URS)L!|ϼH| R%M,):<@V#CԷz%]sϵN\<3Xæ(d-F'Shnv2 , =F>G~2GY-ɦ8.vXNJTS?.eHc I>&Ѿ !n@ӶRs*h8'_&(9&R!YbLF^oi۲*FhhxUMt"4ZWS[':4]zx8Sp";𓲧H#˴ƒb\a z&9}PvbC)1O)JĞSbc5ίGDb<֭԰匬ND#^ꢂ{4\& ;_$xE  WvD⹉-+ :^Ұu #fmѺP=w;60yi'3I"8(ɽ\M&] ŸI*̝#E)c{Mf*}ɐ o0[:b;a l")Zga$㏡H kݟpTӓZ{=(2ϑai ~JpY=>Yk= m_xܲ M)V'/<֣cᾯΏjS_͟XvUpz(zbR%HX[8s[t9Vs9[Ȑ\Uи?ilۀ](8GjH thGG*n\'F),J14@2%[+)$h&tƳV`L'4PFٽҙbj|EgT~ O]h]GʞIl cr )SKiLkh;<\` d>1ZzЧZ.[ѧ36vfPTU3K\ uc ].wyw9BHLyAξtXѱtk1 :M~L}cFJ(C/w)>M^fjg168c+K {Q׽"$Э̕qrgCZQˎiIfYyJ.a@W>1c- >Ӡ3vqpV4IJx}W}5r Hb?Em4ؗf_A;)*Ḋݪx>*ĸ@eoN 1 %Ͱ`5xDdz<|)i (*X}lce[r;n&k-hR15*5OWwhwiyKzjd8+,<`<9 L6`z; ,ڭB~jۮ52:ivT_!'n:9z2y@֎N)p9VS@uDp'3~aqOXS &L߼T^4]HUbpG)C>FDxSӁ(|噔VE&o-{>=*3ڞ]SukXl'bD#7 pE =[@fC4<|TEilXOrc!1j 7' =%'4:'tjTci5.PC46Nc#Qa p1Iz{)MG{GlQH-X Do\Nܰ}Z lrLOmp9DZ &8KwuXI t>r\ۻPڶwD{ =d?)Vׄ UOꂚ?;= ^UPyXd6&(Le!l Sig|Eg?rmz%sS5I~3|kfY|#xNkwI)y )M/xi÷%zYYt zבZ2}>l":{+:4+Ƿ e|>ҵ-];X.hsZ鄴jpG[g÷=B:wn!Ǩvd-1'fyYRalzk!5R TQJa#J!҄vqN|,cEfj!'J;Jzѭ!ɅH{0Z;a;da"w織v%_cO|qznkh?I+}ߦCȺ*dŨP3-mm!}>ׇrSYE:ғw@;(a.83ǸBUev *1BFX2*~!E4l&i^nTlM\ uJMCOi$wɠ?~lk܌j+}: qS 1"8ZgϏ1ѷ Zh7=a&0vrhXflŇ=bH vof.-zuDsGL4rj 1s:O3BCR L#4 ZBUQ3&?<>\%H)[Bl:[+1ӕ|ZfFjѠdxeَi1MG1UOdl2Nmpyz{8@T *Lm*V@DR,-A 1|UJOATԓ,F3^E2߇ "Dwѡ$(VלQ脠.qFf MRPe47ˤNw)>^=Iv!cyF3JYBd+7%%ϷEW-)hK>@!UtHA˵[q:%o7M~M1LΏTUto2CФMd 1{!t= &c foD;_lda9q`$6jt*CU02uWg wF3 -?~\8H־iM*z>k9io{)f* 3_xe s@%LU@6eJ$q)QB(t^.se ū8PvJ1) G?hR:j@L"30M *Ѣu|;A5.^WRg8]#U6țNRoB26fz2L!L1/$j|IKNZoq6XaJ\#Ej+̲êrN}E[ ad2J FM iMVe=?iUNVג[5Y[@4ͦ|]%ɍruMϧ+%t"ѥ_ܱNS(N-}l[GښzZ:LSYzhrӃY#f&p ;57AJOAk,sD`/ڟKNR T WW)=tݨ hKjșEFh\n#Mjl EF*$.R egNzb\az/k ti+߄[kjpFZ ZtΰH5jq;Z:be#0}n[-^+0` wt3ZDSgͣuiadǓf֌iOoZ<Ӎi1do LWpň6.xk댜D-~Bǿ8ljr\Gb<VН')=6 ̢(ֿ5X_"3X;K(KDf42=K]ɶؿ+}U*hs~uOZw(.#y.vgn~.?Pj {m֌ni4[B!'%[M0) LXdV{ěj@r[ 4F+{3u床,ck|'p %S] +5tP؉WTփ.W8N#55R!PO 2XGp1[Wd AH,Z9")1 *UU_8yl>q[ EXwh{GҴxga' *_qmS$̵t)ZQ )GSxrI=Khwm1+sL{:;/ ɥigJZTc-&1W"tP+51}`K 5${'rvhr(sL9կoQ:UӏԷU_4Ųy",>ƝH-Ѣi5v` +Q/YJ;&XVCQq[2o"G.0bn,CFSlcGw)Q"Slo-L6&S`i)fȐx0& %"ŨWR&gQVb+tbXj$Q#~ ezI.jl{5wnj XCvz귕Z`/Ee.HR%1f9ӴJZ_\(xZTj`Dpfٷ|Ng?1tI?͙iģtj\-\CaGi/F?*%0&Læ-2u_ㇸwS3tE}Y#5:dOS<`6-\K3/vMy[F(xr=}]Ju {>UOҼe˵\MQ[r2 3¡&bx, `sa <is GXpW ;JRkR}z-9L圳d{n^H(z$>|H*%ؐB}^4P2_zgȰ.AͻH|!G^sd"êFz(j3[d5jԼQTpKP ~5y*d*QBmʐ[edft^.it27½Wg׹3&J1]G\?h;-o~+vramfu R;P 9wQ4H_ㄣ[ePSzt+ȦsRg˾G'=7eF*9|J{Q%RAm$歇kiFV=*Iӳj5 Bqt^Kó/, NE<ɷŬ+|n64̷fILp kLp`9}r{S{C,Mo! :1-CԭCcabA\k0vR4X:يԘT;W$*shUHAyWh }JNihwZYX2 0iy"GDi1 wT˒ؽR-R,]0t0[@O&LU(1@" Ӡ,0Le >TP0{٫ϼZsa>y!ЩɢZܼD^X*R'ASin}}i)w9DfCiV a\r[m+"jWe`'1Q*cSs0٩VέB'&'=G')236R}3%|h"^!v6P22r()}ue> > Wm>H;O"rc9x$kvFr`W̲ʼno>8ԞyMrGq8edkse !&0 5ps 8-;V: n@U(â-Ч֕'7 ׬JҞo܎,m͖zk`R*ޤ8n)x>J9^G*FJ'nCT>V*h0/PaW9Fȗa}S"o"z"=w"qtׇJMr *Y@ӣ&7 G_.N#uc>BB0Ρ91 Ӏ>8cBWvE+b8~6sHmS#lh駽kУUy` (3M4AmwCMcr\m=ZITPǨZrk6 _ףVς#kGm2TCfi4XΣyӿ"u vWGN IPLb{ vX&<98n (bHG{f~Rbz7vVANbWIQ`% {L&@@ ^ҕI0~ fJ0Z2g5:3|ٯ9~Tp k2~^`oڧ,$NODk.B́O6u4V~E; /|`,/s"5nc!&'xXWsy1J'S#ZS- X@R)^Jq  1X=Tv~4@{&EF㶑(ۋHRX;e,w%?G cҡ~4]wJ G$qMZps&jp!\]U.8d8W.ǐa-qė]Wc-&OFofa>AxhaV ~l7'qd91l@|3m;~I)wׇf;){VyHT 3 Bv@2 ]ԠDO &Iw#DCWL"e*W/%*q4Be(w0GZr61~ 6Ę#%2a^,ЅM?_| USOfJo .Øܳiۦ%g|㈪85_Y 3?ګQ)S0v j/AX:jIHb_Nwwi=-;.qD:PߝXw;KW-t_ICO_A2iyJEXl;]qykq 9ì< ;"jZDM`z0G]j&^F|Sh D@ç<0 -%Ga7?=$phܼ/t?eJr=|% Y^D7ЫVpbAAZDsPgx9`3, AΘKK+*S%E3~&E ȐQL T5O+{ 5d1,S/K WOxt5ʧl'L4pv0zvSM/9),- +O pp ԘبF8&/U‹D U-º1c7Xb2_e_D)I4KA!;Hcd[z/Q uh '| iysGDڭix?|9MĢ8n;$3闕XD9o5" wxnR-"k8b;rGt!-+1KfRc| k'"\kdp>eZlA'~lrЇeWfkklx_~-r.9342׈-ŲH L0yu|t]-"ٶ}{X3} GafVJ%>QE9450\PV ߇Q4W-t /Y f+0 ;!ɹO8ۭ?,`iftm&})zu"^p=#CƨSe7\,wBb9)b\eb=f蓭ah=ŧQ?iĪBr=\JXMByPthϹG)",#ib8u4G8?Abi d˭J/sƒF(" Z:kpPIZxotFiN)ti#N@ȬPLoꈺYi'Va2_JT\TguL,{n7ؠx vҊ˿"Yu)w;׃F^sk1 =,r 96T#ѐɾc9?k,qs)f!!&nGZU?cxV~rpP"dCU4P3S'RGA\'Nc R^qHa-\.Ft%Hƀ,,32 xCgXؓ-Cs2unΐT{n^Ew&&ԭom^;7'ΘFg-ioC ;08Her9-*+}K8x؜SgkSʹW@p_ƽ&q1\Pr|-"$A Ų0 Ph UA XՃF98~WLYS$ &xM'90!j;b!d/l _̰l1t`\9]=EuuO-sL}K_F7n9n2sTtIi2Βb*lq%Ylq}c+LhT_NˆPtO򰮢l=)rn7(NS`)r9DD.7*>@vj839Vk2ΰ9J %-fNf vvHjf\&Y=kl˅7仰R:`1^|p~M>Y'tMw҅NnQ7pnû=+)@ʞ 'SXZq-FKJoz.+0e,`LXXXe&8Zr[ඹ%dxof}sv&%.Ѣv3;z TU jԝcX#0 WⱙbBϊ0V*ASbrnaJ (q Iё'AB# d!&!{:`h?uY`x1TRO䘒/%72:Sw-iܻ[cAxp.Nlp .4Ӡ[ӹ&K(п*VϿνzi:HT{pPLtd6aۮcNK?JW"2DȰ+QL݇$*aW$<̺a>x\pn ^S6EV2' {>^+VEQ*OBFАHW6YO_FpK2*_'`"KJ{50,ϛbq0 ưpn<^M")ډ=ޖ! cհ{8GY눦ֽcD% `Ľi*2(ocL$5^+GR(ZeiD% ,v`ч-Fqƚءa<ȳǚ.BT:}B[Oh"Үߤ}=ZRGQ8 )aE8nKT45%S C'!vk+GfRc96xz7h-=Jܘr9*|F0 6: 2 bu[M!^-E4[ m[Tp Gpag7p>'ʂUHJ%77u-&?=;k t{}O[l誯JsZ&I)4@m.c@~ 0g" Yi#MeN8yCGsň=E!EO1ePar>j l<5(q cUHgnêD81XIlKZaM'k$nׅx2J$&ä-r)9WER;x=| åvxn_xvq$~%OeKНJ_#1!ǩO^/+Ey6~1,zł"3 ^qPq DdUXx*ê4cc. j5 BDp`!R؟T vlbRo.2lPiD?f cv hfZn9;bw:.aod. fU 8]fSwtSm%4CYY6W3tc5}+nMszF3}k$Sjj12&)q糵Ш£' <[.*TPkxͰA%c 1@i*vn#tɳ ["%"x*ƅ5J;|!r8(覀)KؙC.p( y(Ӄ8A[4 ֗|Lk?WS٣Lr,ZShx:SMBch4Z6# [5⃆v`EX%ʔ㪀'^sEЋ!u^cq;RCNҭGRЮF E*yFw帕.E\;T(;B,1 {|g Xɂ{D%&:HCЯ<=@qߏiqGiWΡ!tk<*H8BҬsba6#x*x 2͡1$'g `CP!D]'"IM2 ?c4F4xqJ͑ZWa9*gaPnx5@s<~Dy JhB>'U ~)9(Hb։x^ __ g9*fBo^_,Dv<rVsz3c Xbw,d\6l,qࣣ@@;bj%xHch^ݝ0i` 2:h0̒aMJČ+B .0l#q>BJiϔ2-^|jc!ڥᴝ TZ/@8{,7Z"S/^1pEeu5d^BR\ȵw)<&<MWG`H Ӥ̺ubpxf9d"mqEC>9O_*>"Y~ 0ԙ\>cl0m)ෑ1^0;4Qq=u;VI} OotW?]snK Xq6ߩh$5Fs8_8(l7Xxﳬ "mq- @Ve2:w MNO"Ijf|~]=TIDb~(QiEf)$;EC3ix3Ua ?0¥&+ $Mhk'rN m%h49}u82 r,aα1X5-MLǥOE8_ nBu9@jJ/ %_PZƄkDv6"l;#j̫`sCR/;ulx0u-P^54}!7hC!23Nѱ RAKkh12x"L*`yU )X% C3$Z%ΙBL~Y;,Qp GM4>5g^fظPڰF*]UM ~Ff8]־ u"M5;},C: Po09ƈ9BqoPBu5$.7csGfu!E]x8o^~H9T\qNT j*:Cgy)f-y2"㳨kih} QlC9x\1Wܹxh,Gy R}0'4[1_`R?Okr/mQ*_*ƗxB-e}k)/">,.@{+eA,>ZLޭuUoڹ+~uВ[9Y}HU!_hǵrJ]UCgZ0ʊL|3m'[cE6*FXATیX*I!7%Lʷ]cd|\7 4h.^r9\O 11x(#w!6y7> !kK۫1m[cs=pz=pe^bQ (c·''q<~lYzX=hN$Nԣc'V3zSs FUO)G!f0aljDS :s0z73> P{Wg{^{z{_?RD^#JkR#%2hwU4M9$PT]/Taq+D2u|3bӃph2FD%R}MXZ Ldzѯ -]7|܋K 8\ϱ .G;˯XDof;tU]Ѣc }YLU2(`Gj3jiՕPЮV+?;ڸ΋vӗU鐣z 3яx _EusiW)qkj6LXc܍X'x,Z.d%R1^? \wc#춶CU<&rWC > Pe/5{ezIKg0ozYXg^2!=a==O="iCzM_Ku)ɽ }xwCL`'h_iM%^䀷?b>^!b+0'A^1 7Reg9l{a=13?Tb;ko@E5mqD/QRcN;HBnyXǸ\br. uCVVr"?рOwzvqRw˷O}@,m,x~1_i;4:\[ddu,s7ʵ"ÑO,b̦2iS>fVЬeQ@Vm~Ҕv1uWGK*Qޯ*=ۺL=.|5_4!VxWk0HCOk:`}i{pZ𳜃>JsJ5 IQx[S:Lvh>>gXe'vG'f' ైL.73VXs÷LZ/#Uվd+|K{v$Qۭtr_ՃFcȬ-QM! i<,X\tnA}#+K0a9(,E{(c* &ϯƝPKQ!@fR4>ej4ާQQE4r L1G`T"M6dcp^2F[1-T=I XZ&(94R !q$kvیo^_@ӇG?#> ߵfx֕w8K L9dkf_I@KBQ':dQ59|j;%Ϥu4L*]OpV<[Bg^LAdt#;My60`|iek>plbk\\}̌L!s*J|b8\RZ FctU_~?L8Tڸ;).'m XnϬ\cP6dVki ʬYx[m3'3t'[H3 ,d8AhƥEXfrktr3[sLhG&;If~xpQJ; =fQ`Uƽ68@[D`$Y:)+"mhCj0+ȶkcA+E%pf-> fpA Q/2\4D,WKuڧaFVQQ{2ΚM%_$ ҦotGaw9@{ӝud+<#EUrW_6gksnByq+S~Q͔* 'Tq9<%YQEVST| ^ clj0A`'w^m;&S@8kd `]߇ DI}{I陯hGTJBjz5^Egs@N5O= zɋ .3)eho[UXҶ}h^=o~D~yi{[7ٷ޵'MS"]۵pwpwp+vnBRR T(];{g{5$sNrɱc$|GhUCHhBsԢvI/ B˹3OyH/CJU9֙VcpSU@ƚ ױ=K8hf-X3-w&ۖM0˙9Ӻ܁ZZ3ؘKYd *RXG}sy䆚/(YC/$<%S0RiB.7G9GξsƴV1rH[*eʘd+vCRbJ6#*Y67Z[6:iSU>ʞڲ:kyov|lcXɂ*pؚu6neHΑ0a Dck<5{ Ap98\ATpg}*ֳ$˂pVL+~5cUyc;ߜ8˥f$V/pϿft.`ûݻ^ra1?srL8=h @ЭlwZ;eBӥYh/, SĠσ,8m@b|UcL\!&ND0cBh<[PT9}^ۚ =_wӱ{}3ʅ.\YH2F_eUЊY9H)k4[CZ((Io|&q`/!wr!?y|d6MLi]Wĺddܪj$qq&ok͑V0Zō\}ƸlYjMɶHv6ӎ@q}[nhӋ-'pQSd ҿͥ),S1U"L;͊ED-@zsn+U+ͅZ{7, {q1T{Vz<񏯣gv6lG;h%y/P}[}|ni.`KYuR⩌+`J"+FO+32ᒧf^.\F.{eV|Oͦ|sU {u` ZqZ1W󀙒;!e!+xaΐ_Eo yI9陌SliP- e4uRIφJix+L cll|fN\1ϖs.͞ ],܁s9pgMY ^&VtTacyqc*n'cw90,35]y.YXTyĔ[콀aYV`,H?b4vkx?݄'Cza@kb3 +%3JENbBfSKLqΙ'3N_k2a#jUL :У8/`v/X5? w@qBp+.8|ņ]['"5߷dR-Gq«Z|(Þ3ӞSЃΕj'ݳd>j.Vlri`Ŷ:⁚vkypwIE 6^o1FRHURn#<)+l9_6J=]ýKTxE\]g0+>e`L74p⚵8ɁxZ .bǿ5{ OP1&XK{=|D;*͎9.,u .hOլ)i3Z&K~4^^wR^p m>^ޔ1UBmb/Te25ߍаPaI' ̰d"= MmɞY3 Վ}D:GZq/.,JoMռTé6z3))vPXHKP3'%Kӱ^Q"+,GH?P%3 %0I@jz"͇b +EUש@RoW ә;g,G)?Xw'ttK%Z>hi[$/W -8c5 /³m2s"7!9~gS\@?t{)j}&~[e#wF>i[ }+noiæ,]5*-lqȅZmjzKibFG}q*6Oi}!0tK3~K V3Q*f/0Zͱ;ռ^OcZcmϦ\8g#{7hf;g+?Ky^ʆGE8D4j^٦\ ]*:.rl=K\EM zR1lv((UN]lx \tdX'n׸]81WOaS:.QX͚ qOͮSNύm9~'ұMG{0O<nQ*ΚNB,c_ {K9j/i8$Q}lJ#/ F: W8pA#Km]8p;}nZknzzn:C_gz):J/lb_㯀ۡب#89/:4TQg?J^?U2(d}_!^gRXߓkq̜ͺ+༎CjY|MīKj;Ddva+D˅r!^R\%=jZ0ϖ 5LPgK[`m^B7NrR+ڻ2"хL}'؞ONYs :cEo5L3aٳU )4w&l$s|y"bJǩD`w2#^([Ʃ梢p'Ut[A[m̚)jL pNRW>U*K8cHZ2=̖z+!(SZ*dǷ${|ċGh(3W`hz׈~ȫw FZ3X13<'E!{ba22 Ð~!oǨ>_FY?X;){6Y!x*-NÇUrfW2|#)8 FVo,)uϊzк':q=']ܙǃ^Ecwxkyfez涰b4+ |dIvӉ) q%sͯz%}FBtKD~[—F3NK% $cNr0!VFEsP#vmW7n;PnǾj'LuvvT[LbTEZv_-i`dC=W|Sjݥ lk]` t:#Y\xwb'R nD݁;VqlJ~l]}rx&~'/m _+C}<A躍Z'kʃC>Qne/!/: y+̘sӜ#cRhؔ(+LsZ(JϬYƺ~C*ﶴ=_p3eOL. y`99Vba_c`+5Tq#*)d ;h;S8΅L71ޮI~wg[TGS29 t:ϲgv"397Eآe=tzU1-^5\W2Ə1Aʅ)2N_ff-66f[:oȿ 8:ԉKS9sИN񍗚yx/0:QxENJm2|$s~`t||ʐ`\p^3pQ] C8p7ٶGj``~L?y3ͺoh|,܃1 ='Jr*$]IXԹ 0KB/lx{ןr|g^eTjeMUxp+ vqpJ~BTa$\a+㽅bnJ1_X+Z+ 4{*=IB9$82[F2ӰDKN B_wu O/r~ \Į+- \ V [=zv0WaoJ-bvXLD0vd Zq_cuYToqF:-ڙֹa'gy1o]خ#u|[%c^ ݮwXQr=?dZg2MwO$a hQFיװ_B}@n>#y34 [3n@U'\O!uԯw>sX :lud[|L]Vx%^>}Gw6oL1y&=35 5"͂/- \~Oo_l͉kWJ#wc~k>n)|cbK o w?,)s*7pȚ4ODv5nr1y2I'ߑ չ8 7aKY#2V<.{߷Vn ><ƣ16HL{euMmR?\(/=ӡ}F?vowY1GNmodvkʊu,kˬn#(nƑr1L z&㾰R Ufyi~ ֳ Z 8QEt *ȑ3U]N D4Bk.Ag[q|t>ltי2;ۑ=X=݆/۞¼,Rykͅ0Ύ6=įY؞7W;00͍xS4%ͧbء$UOl(Tskf鬸/GFxDȾ]rǧgú<@5V{EDTuGu\]xc 27>Ss.bʓpk9l֔CPsL_σ_I%ߏC}44bK/?RUN[(o.kVM^ Pqu%?oSqgþW)FBȔ4Li)3v΂'LG8.Cfbւd53 9׌.(x^/OʌkBNK)pJ.+g#){Y.ItuGxxsgInyƳ '?Ķv<~MYYiÜ-Rq%iέIWvw\r=TqO", kqF \ܚ)X8Pv2{y=57kytȘ^GI+nuŞ۪.sbt >m=•m{~aǡW"ܡ?uC7hdk2b) =Y-3!so -Irlǯx:^#_5sk3uɕ_vR] d;`TCy_a OWi90 q⌔#[y9(Gsyx*I)~9 ~c3Uk[R&4qg;)Z%4{ 8HmS#ŕjSs1+c,Z7O74:n/C2÷_{w]->Iɀ(/2QץHsjl2eq::%cύ',떠3}<礁J{b޶\sB?eȄC'!'Gg ,o#N+6Paӥr|s%ר U3T`Kk\X~|{zqqlȓ2]1 PtvM#gXKU|IEnq 6}_4*A [.U}OvJg.J ̶?\f".ȈN}cc:HTS4{YrKcVX$g?w4:˔f)F*Ôy M0VJB8F&<]NJ>egXcrZQ7t +@IQt\ۍ9kkB6UjϿ.N-8ɽVU1.:FeV9F@$Zcl@2ldddaJ:sJMw]xFvMb&%oDlhS>R9 @|D||XBVRl5d+79 et[sc/ z<.U^mō ٛs?=וVk~"7P1t0Tlukx7e\Ҩ McT5>Q y#vĝޣ,޸ƴx7Ou:9w-r["#̥|qb)|u8o?y3_'f̲+p85Ӑ5*7-{8f"d ]qsUJUԻ 8 X x6IL\4d_ƾkd~`T4 Mxx;Z n?85/nGg!cRy}6v }Z3ę6x0c]njϒV<ͧjޝHK ӷ[pm1G|JƠ1ꔅr1CqRεJ/XrdϤ!c~.℉",<NY1kdz|c1u}_Ä{ޞYI)j8qoaPh߷Q0w)ZU 0#/܁ީުx">haDn 2Nا=9=y`]?څ[ˉ,SAˆBzKBkFq5f Yq/ tXq Ne,~hLX i_1$*w=[4RO #grΫXA˝{tBaU٣?c| Ә8xK67YW`Xz_=t|%s.kV~`#  pfޒ%26ΎM׻s@+}tb؅# h*U]A2JdBf[R&k~ xr|b`1G;41\S0`Č*f~]%u^s^^|΋3zis7zJC)%b0WvDPo0%DB!ucwv{Y/~ ›01^N\#ff _\tE܍\ĕ03~5&Vfr6`Jk(eRR=%^q9mc߁B:oף5 Ę31KiB xE!yw72PJjN=aG }w)aFUD6F !h߰lEÎbdY]ܝVwKxH~BO\P9k;5\9^ϴ*e˿5&p%OinZ1֒;|5TRK|gmWj3!1F&b$3e w=RqK5m5]4G13fmJ%pJa2~հ yҙ:EQlσז:q$KVz2'(+1ZBަ"M|AO냕œp) gf\6ؗ1y [WW>λ\݉f:$GeWE˙J\ᙉʯə?FZCvZ)+>8E|D-{/bчEbLX6s2lf‰_(WY1敎Zg y:^ˊn^5Hm]~{2Qr f|/`?#ԓ+}lDL,8fJ%Q9[iB3gjS x~H$l[G&o dq^Yns0u'^[iV e+= "P'`Lz[ODld=ύ0+n&j#HhXh_Zs*FRqK|aƿ)2 {\knq<Ϛ_4&k{츋?BV5bzdUQ 0|no^bB{; _}V<zΟ(8j=d\qOU-d-+\xי}L7!:~:@wiuVΘ0k>L]7IXՄ*3rZcĜD'j;ckN\8É6@1Dlp5@0M:da )v3 יfi8WCX17r [feaB{jLypO^*5RK,KsI[n£rWvj߬9ֆ:č-8;np壏vϒ7{Lj}d ѮUBT[wmBwi#ŵjf{ W!|gs 탞ZcݵPLj)GWǟӌ_V F1 e|`cS=]s0[l<`ÓXX.a El:G;6z֚ӏ)E@EJ-V+i&ND2"c:IXGȑ*LAYo{FvB0eM.Ph '"j`$#G$@{MG, ΩZU#נgyĔ"S_ cb)@yi_Dcmq^?Gn\3%OSu6R,Am;]Xߍ󟺰z+](˅E0ݚߗ8%TJD)ӥ|#EkLEтgF[Vc_nQrxƾB9k:%FT]v1uԽ3=QCJ`MLy SoFIh\ƹ-pL;Zu ^ctme) $j2Z32ݞ3OEEpŤ:,>Eaph&Xi\sLYs#2+)Ou:OC okz7I£zy8.ïBgaQ(}6=H`-և#~a1 G-`/Zq?&jpԜmӛ2`N_= b<)@\ ,زӄ^Zs3K&)9n-6x3^=6ʓ׻3(ǝֺ G]Bi.i1_ɜm,GdNH^2 [f\g _ɏ,ć&|j9W'`+𽑆~#˓-l9ϊ-S~bDW= ZZ[揱g:{`ӶII+bnd.4fzoos3:[bV!&6T+P#?3`' Bm^LI`FxڒH= !(+qZ$HkgFh}vx~i'="jiGe8[eA[wL-"m.sR/bmh&flnQ9X!Ew?To+?7D'O4 =kE#OscuXZ;O.z+랴a)Jmd0[O}Ղ܅lll̜=0%g&#!6͍}a ppEG+`9xwm}&io|#7SYp3>oAW(P1kjwWK,b%M񲃱GQΏe423HI&esê'xL#a}{ ޖQ;VbbW9nYpc9֔ 8-a^:M8ի07}Zwďݝ ջs9G@c0/JD^bˎيkZsF'{lrHGMzN߯MV5۰1Cx6 ps2 ri./:RtBAQpf'[;X1g~qK9HHsg%D!l-ؾc TK~J R]wl E˱;YM'"% z`ncG9 ۜ0{QE?tф=LmO,i9ҮXlld&U\=YR#&$3 lvڑ:QW3}DԶke#o&- }~}P y9#`g$ ťF-Kq(3AMZ1~F&oyZ^P_:Vw?ʻ:T7YT#*g^U'#p̍9q\#:n-0JkC obƎ^5ZOQz5 .BpM :ćLFN_el0ə;KYO/_T9) sh}­z6=RZ$E+!g Yk ^_mJM%N(|(GF͆cjq~~LC  ^ZaE|s{oBLZ,^41aJ4P}q)|SadB~gR*-Y؊8"~w`-w)kH?_gPi:8T5^a9a4#&B%cqmC /ËZhY62~&<8ٔP IJV5ݖ:cίwMƙۡ( e'Qe"{wjc!aj$GD,Tbvxta/7*޺;O^ƹm){7Ӕeg+PnqB,n%sVm"<o<}Ʌ5T⺻z3¢ٳS;fIcq%,6fldA_#55Լ@ϔQm/!@[묻Sw,5n@i)Z9k{uo IFr/ ɍ`͠ftbAƼE L *s2D`D4x `mS>=ݿ{ Gk)t;1ߖXՕvE03u]Dlҕe9p%Х{g?HfEf$atJF({?Aʐn+\8VRvbLwwS.0IbIzF WnbmWQBʁVek_&iP[П Ќmy=q 'OCB'k Npʖ[0 ڄG2pM-/0qo* /$~:6̃]LלLy݂Yp}3n],'\#23S:g7MMťE8E"& x9z-ڭX*hqSwC~2es9Q`Ȓlͩ\Û?LcN  thTu]9\ SJX NYlBe?G^ޜ&)2UR[U8΃ 9UUD-Wh\QMM}TޫӰ5^9"C1 T^hvo]l8= 3KMgRTXBBOY\sBDwafs9t<̞n)f=Y5Ɲ\ح53z6˒jH jf{1sD馿p> Ƣgy֮) O?m.;݀'iMvQrCuz գ>!%qϴi uS!OTE^jF|}V%4y,#?afiGѺ,Үv=fn46|xB̹nd!'e(K&=0:~m‡&\܄Ֆ4wMa> ~KDA 5-(xuQr9v=^Z-5YQ#Vգ5t!BKX橘c=ǁқo݋o꽸7ǻ/O*GuLȚD{ N>C=\+ŭ3Ì5w.KL9k-<9Ei=Y@\-K[-^B 0@>}DJTڝI5~TI(Yz7#B A+6ʄi6(DblWz[Чcf~f,6}m3ȉUOlGan_8//>o44b˜ ŀ-j16Km~aKN7g= `y5If^P|%fL/z/a\ƾ\ޕyѯ7ᅑr*bHPCNJ:dX{H'c*Co%E!ƍغuĐ2rgD2~au2&Αes{ˇo Y]ˑ#ټz ^, -#>0/=qxm#&wD [$<>}lnraMY5RЫl؎a4yϪjJpx!~ŏYpؔ1qط/F⒏xnI)oХ}<\؀vw:x+o MGρX 0GxLZGao^^ l{uf3O+cF:)3O2 h Sb;gnI1U0JӴFfrNئKR6(v fJQA@1Č%_|% HhUuL|؍w:0ЁK<6Or\Gd[69_}y Sr[;T_$TAvܚ)BDNPޠĤp|c%U?_j[JS֥t=i[: r%CƢo|)iuge&<=~W gUa}f[q%ۅ8ɸo֧H)t]\˻*dp1I؝J:>WpT%_9+d_Á/gwFG1c9߳fo pE*T|6TM?nmلҤΗ WB?%thPs_NdzMח VjWnSg,$9!` 'l!w^wOK YsP֛)my:j&D 8<7EYP`Du=_CpAc6i1.Zg vى3y{X+=V!|i9e!l5Aղ #s`2*$^Wa#t{FN6&r,ES5XU5/jpa?CL`c[,ub(W.$dXUR.9]%wTrR5(dUXJe;-]}GGۼyo)gvsMc)/ĩBAlM 4厬&v!G5OΒu'1-B\{M͇cMx E{J*t|9G+m \3dB9 )9` fLU'2ja׳N\kLftP/G`ĵJܘU%UhRQ0_~4.AX͖ y.ל#x1-wn<2 M0Ȕ18qօzh"dGtc'7أۓOh^kJU-p``KiZ,yυ"C& sh[9+_T{:yDfJQ9%\3Dr m7dIIj 1^Vd<\\5M.x/);ϐrŏͶrr_`QT\ƗƷTnK RZo4ak#af<m 8qX->Rpj9{Ie H*7MףgO镈"1j_cң(f}i!jT`-Fw![pRW(mܪ@lsYfF|#6oLLņMk/N=4>4$% +1y[Mn>4Am5n]y-Lkr嘚ZE|lL#v@c/$x솋R-gPK 'dl@Ƭ8#2N.wxG=k RRS9k(i?ޗ|Y9)W4&<Ώv>~L^աM]%;i>j6P񃳂|8FLҹ*g(y Wڗm*zp7h`x#Nwƙ=٣FLL}'vK9[ߓn9Pˊnr|.;ؘ Ă]^oģ 0a &\ݮP57 {ab>uRE4i)gBp*ts"cvܽ9FYSbgi;" pmx-31mU "{dzG,3 o bxT"g&@O C2Q+z gt i$nRK/{W%^Ipə-e:*<@^*&TqN5gj ]aqݯWq^' ~>v!B<Ӎq^=)H8:_XH5S]АA5Tپ,o•xoÂ6D,9+u-7{qMT?u5iaB?w*n+KS ޑJe*s8wts`f+dAC;|f&tᅇx-BCo, ŸgK3 ]F)(;>o^t#BE-^j7%X$^_,3}OFh8()MSX,ͯ4="`g _ s dP|8tHēՐ&1f'[خVA=J⤚Є,WT>/-9?<%k6*~=[/_ڪ84ď+\|D .t/ذegˍ}LkmNH[w8vwgRvSd/*zl"_JrY7S3V`X{U#tg\͆9G ސ'R8+yY]I x`xnN2DIyx<3݅济tubm<]/65! [~O= fp!lq3t؍&COB}Návxl/nFH{8 fغ<Ê5YX9& &1A$2sR<k`24lOQĜp̗_|yw jb +؂Jݩ`\[H?%*ihBw_\']e1}הZSG̲*= A+[>"cLZa]m{<ʉAq2oS蓚V}Tdu. t̓'DyٝxW1jc=8ڍ Ե7bLg&v ]ωbZ{3lWW'bn¬G;&I1OI$/]RPFF"$bvsx1kpf ׈EB/pc=h5ۓOy08ە]ʅXvvvL~aÛa&4oʱ<+O =p!=fO<;-6ܭŻ`l.ma|)b9 _FS{CO6Kz9'n`bT᳴OKRw~YZǠiYW@5ǗceWũnZ"2=\];;8 Yusa( [al_ǹZnLrxc;Wtf'>KO.;#KrN(H18JVqRzpq~M18{+܋<YNgrZ3ivy߉};:QY"#hypퟍH,:ڊ|>Q|S9[5T^K58OJ屎~LRD*Ly#?1Fn1܉3:6\qYkRp3hN8Ez:F=xab3,r9o<7΁B̓!"ܒB.R#"AfY|C̱\'5ÚKX$cp94><٦ޓ׼1^'7=i3D('&{kA ':q ހ-3ci o2x)E,mF FQ$뎆[ZL:ث=/.D1`NV瘏BFT|!GNG/:kG#ϺP&7)9c{Upz;;Uɹ1Gv2V4PoB1H }a<ɏRo;7Siڬ5b63jpCu,+%0ίM$_EH8i^fzqZ4w-w>[Rw+O܃>vʗBٖWabk0eXckq##$b׸_#ew${4ο}"1U*Z}Ĉnp*@}JmУU7b% õ,ڡ,QM\oNآƅ1+pY_\lثšFv|؜]ϚPF qل4FKIIYAk &}+, qU)8{GC/Sں[X+|_zoj8Pg >|I597Z}DJ:\Pr<ЏFtAte6GMh6_iq6=hӥ 6œrKfE)'U#$[}C{&~ĈWQX~.=p^ tgk/PVcaJŷ2\8lßc=y'p/ %y ]FB JLon}sɑ˴<8>܃g{r_v#tܹV]ZbC6?6\UmNJl9ȅ.מ K~Em >]͵Ÿmk#z4/6Je0'$àS> }so(Bߥ\pS7s djΙ6Vˎ}<&$*پ#(8G7g+jyhV>."eR3ߨi򷘲f6htb3˹ɺܭ /6hfl5͂uw1N&Xl z$:FDTNE`D\f30Qz5(/H|8G-\+ [HXЇ3nK䒘{Ŝڦ 5y9릈O1ԋ" _H7tbWnơby3m)6^pfrϕ2|:QζfO^|&R^M/o:sx9p {ޯe^cIfc_f|ߌn4z<ÏX[_LӑDZ6x+H>fL2}ϖ^<Ƈ ?$|/ d2JƗeL+h6?-aDT(= l;%1x&iFdNflzۘ=kx_fL 嚛lwjawr>$vhя'U+vno0W1hx*Fٛjc"SnAF |vF Jj"] MBB,WX[jnsR(ӎiL8(~ap|jf eXe[%U1_ 5yxY5*Ypߢ3bOX][ǟX?]mYq•făGy7rW X(8 JvyxepfO1|ČŖ٩K0]$~aO&.AJ]uiА y1Xq1l˞[8u\vIĤ+2~`y}p_}EL9@%ޙjs16XswjS'YEW(%K6l{PvqT&OENC3^3ubUeHD=K&Taf:2û$TM=|ɘ8Xw&maC^6DhȾ#A1޽ oW!trr>H{ l˙K|;sbP f3uhloPpP }q '{2P>Ri}`%_]S;?~A\m@{{^9mנSF,bq-6Њiv3zIë6Ar㈮:롑8i$Lvy)DFu%ˆ-S{k8+f2A-򑁁c!! *V67>|g')DR͖A&|Vs\5U"9IRЏEF!=.EC^ ()xץ~#.Y@!tp …E>Jam"z_F $pW/ֈ9i;u"a o"f_s/yW,y+lR0* Q8r915ӄ1o,Oǘ?6עW:2o ècjtXIIye84w*eN)/4fWk=>s5 -V 5v|4S]$oJCDe-󌸳6lLOǁYXb[&H7n~Ǐp.6.ܜ(tCkw̸SfťU4˚)- G]5eaL:8V&ŗ \ ec1>EQr= Cxh|<; +0bD-EG.jʵ q~|H8c=5,WO&:C\Pס,ʡQ\Skuu}Jc"*!+E̱LԨm^ojf\{ǎA]~ R3Mε!rF5rT7c:7ӧ6MR1('2`U[20c>Ò лG5@+[SĀ/pLP=[ j M.xVy阙-t9cM;C38M~SQ .wiOb/tlgҫp;+˰ql&Mݼa^OFEܨJ| 0:a"CMJJ/EhM6֚착/ZtgboYYZ/1;.!R)-JaXκ>dbN}( HT98U@#wgx)OU6 ⤞x!h|X&a?OSs/vb\Ҙ vexX)ËpgtZ h`FQn~nT~0w*I%>l|:.VKлO未S_p/{rg>+`/dف/0BuJѲ*;̾=w} c͵ H^&7GhKc2]Ţ*%'#ԛ(f<_~gXVk-dxR{*^cpc8׿W&1k. ti2.N?|Gnm4bmu iȯċMD\vV2M~!CJP>>Cb] hco=ɾܝlN뫚UaγrL *1Z,bo )'(Ncz^> O7fFehhoǤ1?ê1vvK\ТOp>lǗ}OB(a0GL~ -nb?x>օeH6fwC* s,un}jPq}9 (Jƅ|hŹ-ݙčnԑ+-by/w؊}~ݠcմ߸:u ݰXot~MXX?NZZC[OŌ[Li!`؝ە)M1v+_*snӖI3_ܞd[<0#,N0k绑Fgvo U+`I9 iwؘG5l"<[5(sFL6ΩU78c߂M›xsٷJ+ 9Heä~ތ>e_^vWN%tUA͹)>]^+ث겝ݶ^_ ]\1(lAwI?Pl(^ is)n +ȧG&.LN)X)jcڏ48/ᑅ*5ň]fjg}vSg{WT'cz!gJ wV۳w҅KCo_eLhq%.ZPW9H*ĖZ<1Ù?9:2QVv>/6˥z]k*:H-;;wHLWQEJTy?͑Al;̂s;Dsz\AϹ8#<.0~;*u?O#E"NMyqX'5D;+X[`Iɛ-׉9sL\a7-cZF$,٨E Uawe &lMu5cAMor[vft7'&ܾג3{L64`|H;ȟw17/K@7en#Z 4%rptr?(Ěi~!rhi 70]9ט)Ms椹>4PRct*r-k1Zk[yt9 gl }6疡KhX"nAU8qn⠇峃֜ξqϝ8ڔٓa?=ܿ]#kB|<1ߊ0zi2i(ɎShOEZF.Fu48a]-aʼn)Űgf -ɇ,kRte7Dz[{fk9 i5+M"4Ȧ =ظO#|z=N, XѶҀă^Jax$ рuX* » Y %ÞZFtey/Nabҕ-760=l3`q];i}p#*kpUa]-JL^eMpϚO9S֓ӥw#*/C1<)pb.W2{N% ]L* C|HW#v s5}LG: }6M3糑F3\)c~_iGc<MrRjE`[]IN[-uJZZ{E3w}l7#HZkw>Iȇt iG!gL![Օ5ذm :Txi\ŁiWŞh5G+q7&u? wRmj=GFMh B_ + ^idIvrؙ<ݩZ^tP'.x*F43E9j Y9PkU~LY)ƶX% m#u e|RKz/kɸVƋpX:ʍ ¿-0]zOLi?&6)q51w3eselRi-/ ؠܵ̑YTƟ+;Ysm3jm>> 06ݫI. __6-Gp)+`l%{-jC٧3xЪ<7ϞF0+%q(Z.a#>r B_hZ= ;7fB~3Ǧ`LhbdŖ<шb,dkUJ5MZ&sxAS輮f>V͗ }6ܞHs#aW z܍McjdĘܜ*c5*ul4UR%7)UǦjoH6y$^tcp̵%uoAQ(}͆(ǝH g.`S+̲7nŚGK|/ {aP= Fjs>Ғ1~m2aV0_E٘XcW8 5ր 2+r._DpAjvE']J6P\Z9( V雱!a5mBǔ^C??9\|o 5|`V ǯ'aQ|Xz5VGb+4tǞOuxh]yOA͡ASDS 6o8*ŵ5e $G Noˤ +k,Oo+}3]I{ m"ۈ}ؐ# ,X]MڀYmEBe"*ǯ;P@9Z޸*3 0ܺ#[&`&C)2/K^gCm] 28>F+(p]N\pu[C?惺3jOu]}DTr8pG.Y+ڥ=V)>S7\ZN q$9^K0eP;K!yp#qda ~ۥT7Ocr3_+Hw砙I%:>8;cm59Xl5W4S<`i)'#,+?F;S:,!kNaUFOnL95\Wx{:u֍3׮bz,SSi űߘ$V3^?gxe1chOIǬΩ^]{OF]U֡qOxf_1OT߶mǺf6TӡEpVX`ҵ}W;de|ו 7GxUM9ZO`%eAȊD}xt|N,' LJ-[ZKj.oy vtzb!.pD){,sdΫ䴩0Efv^ٟMbjnVKAO0yLtC{n_X߀o훗:b4,څdi,=p@X}Sa q }=Z%jS66_74L_?N& pD1.đx0U'5IL 5-þ8c1Xz_ tiVG7˟A۹Pa$]ƨY2KL2Iw ZA;t[n%?4)kN {\ӿݏ*¤'pazv1-\203MH\ fG"` uX䀨:Aw,yܹ T]{kF-Qvpx1S༖O{|8EMMGkZ^S^9K]YWmӅDHSA@xmDÃhskC]қ`.djc{g$dń~ npSKM}֌82'O{?kݛ]0sWVꞛ6ԥO~ en۫ySA/kܭW.|sm7xP3D[vWnuّ99񋾠isМ=`{0%zѩ~.FQ&|6X;=з9?5L0gvŕyz+ghOLmvlޅ'}U漽-tUNލUFRZhˈS&U6/iJ([cZn^lX߅k4-RlEN̼i --jfI+R9h%]jߣ$\F!瑔V\Ë{Raӕxy(k'#1s+ޫo'EJ:sdn-SN5EO[j̙ANEϡ͠ֈ9k1WYS [yw'Mت+7ء l +taO2 ]chYr|1a +a#Dq=754p;NjNgLUW1pdX DI{R t2o}z7e˘Uo#cíY;`'v:h'~P;7p~!=ҁdK߭i`)\9#7]QFa2}&ءC[_fM_t|jL[HM`G=4[fDDKVa0o[4չߙ6k.6d!e 7ڛpE!|G5T,`Ʃ/]țצ_a;{*w+#p+䠲SD,A2[9bis7p];3 ݎ)0(\ǐm1|Cߤ,=Ŧhz6=#Vˆ.ƌ.|ˋ x2;3iMeRͅցkڻ 7ƬJqa֖ԜfrS[Ο`b+&ܗ3~+E83>ӯ :))W"c%.0,]zuXiĩm8Țp7 Oµf rsTKzozh?ȃ%-?Kfet07O|!4 y Ÿt3KCt.P5diO#*a",(EȔeڏ4&~{T/E wpúj^5SӼƒN<쁞ǛOzrBvmyF;_^q.ɑ+YΆ#P#o)xHƒ_Fِ$h? d~;wþ&Fj1oPg%34¯a4,K)Go/CSpcyk= vsdqaZ5p?LU`/Wss3_ޚw9 OvdI =iDAx/ݝ{1ݑhţMy)$ >]b GZc',:x }G̣|ܐV"!WTrh)d:*C{Ү8lUtb*NLA98<<8~<ޠaKzoϊTR:1{'85'ur}5֎;?[F#o0:@L*Dq ؽF|5̚ AONRG+;s^xq6WUs58{TͷΜÒq^L̓F}{Rt$8hž7A^ܱ9?œORіf4 *G ` h>ĸuJj4 CT%RDߘt9FOnMk1hQUhmcѦ<1B~^f!fwgǚ<>LÂlVs~ng==c-卭ݞvڿɑc8r[N\_NkOvVcbΜj\{['Q9JD716FSÚ͗M .Orl%^nˉ25ϝU<>|=B]><Ê͓%LXi2X /wJ%vwMSA9ڛ!cx+˪;`zab펺$qye4_zl$a\ªL-wA[[k1%8lwtV`@mv0b'F<̫ʹj.aXUٓ-ذsv.<՞OS@|'ovxρMʎU5ӂS8ѐgRpLDĜDȬ8?͔ K|UEɰ 9od-9!MC?|y~iggTfé,B"!UmYFhѓmxJm=coe#kZ}Gscט^9yΗ{8d.tX> 4.9evױD)år^LV2 ;ߺۇߘfHG &ֲ`lx=)O t8聾0Zif~j6ɠPĀ{'<>ߑeā 2mXDΐQdb}^?a]9lΪ%|4l\}eGf xb\裌'WYd-7/gQ[F8ckC.gu*^/W|x7ǸEZGgC̱#J~Bt STkOnf.oдtɱ?1b*I)IX<ӫ4MĞ8 ĭ1:勎?}.df 쬝ҤmCp˃s bldvTsea;9SnƉC9Zf^ou]BT ת7ެ[ᯟ9oEg5}|˓Ǽ=8‰ü4YQL44X 0m+t#wp|9/hoƖLi1ePk;4Y B,m, &rm%fKJs@ULQCcմz|>}p&޶Aq6,-24[askRꏨ;B|-GtcAzFc~+/p|*┆[ѕХG:213,5r]_Dn|}_[pv/uK6D<ɓf=2{%ۏ1,uPe=,i"^}FD{tLCЈ4|_.,+àp5/ ?g/߾^`iucw+NcJ-h[ qa5;sR/U3AM y>iez%HĚueoUvʌؿ1{Fss:ZsR޹m9h[e 1u͆2+ͧ0">iWD;?`J |lK ] ~?>C_m]ィ::6_GN0 ܜIs,9aq.-YEJ؃v<ڕ~*N)TuV[ZzS2܅}9hGv Nn+|Sq=Owg 佛V2!v:LR'reH[li!rȝxMPCç)&JS03q(Ze"{7M'cogr bX//e o^T]M>[\˕ӺyrkyOOU1舆_TV7]yTg%ֱaڊZ5rmEHy#1=l3 y W87"šww_>xaPHlng.rS_"g^)?D8^ØR mSǻjYo‡o½z˙?H8.2g~5ٞ.h oNm]9>zy<ɼTz $4)^6>wDuem B6(^dlo{ .O¹F\[j vqVuBՈ%gދU ZK/_ jfdik7G]e gU1sR5[zx%/64to.Hwvu` kLfǿS Rמ/IRQ1Am2po4}^NL̘Ìؐ? h2beU#Tkز,ĢzMMEn)%g&fXn>zsCԛɄtՊ NhJR syWn?^>X}l ns|pn_ <IEhe*]ʃik͊`0 i?sIw ;;Yp frg3U,ÊZJj U%kɹkª(+<&'uh8xMہQQwauI"ׄ]J]vNl=֓&g5ŗyz;G'a}ƛ~޿̎Ca_zTjL}vTodQ+<Ɓ9+p緱t9W5qf(WY4*[>XˡԬ??p/an/nKF~t=ːu<ч<8+5m8=1m+E(+a6XI=;{~NWSk.kA6߂mFd2mgִ,4gLyP<;mkO)>þ ¤+z^L3ʩ`n\^6 -\x=ɃZR3zݞO2$2 R7_fvޜ*,|jaΒֿ&=\wG}̺ ~ h$R2$y/?ڈk~SHO3UNhF,uћx^^/NffnGlX9ێk82 ]vdb;%,ubccWc/q_~9қRs]'oF FÕݹ_:rT{(l'4dW7)sYU-{1wJ*DbKx@MVal ݊l$ "q3DBF\mj&1gFB|*^TX>3{Ɠ7 Z#aą~ƈeϕYFf~]ޅ{ _9h;v ,MB!1kiݢRaKMyXuut#]v ^eC)YWSyˏ O{SN\~ntaGFW// `<٨bV/ˆ:.l܉m69Ϳ7ҏ-Ft>aqִhgi9ޖ7MJ%19f"yYu_9^IKX3$bcFu"]p S 2bl|4Թe(x_XXhKvĭ鳆/h0[5TXRQ`aȔ)fx{tB'׷gP-!k1}T_Oyךڲ?UpH)%%ۤKE1rfm?{ FAy1=C|Č٩xn2k),:Vpk'+|yo ഡ&UU>3Ws /VfַMwh9Nv߱`F,c?ĜZXӻM;05ʁTLZ+gzo- Fq(.B0 #pc2^}5:̿(%G9[^RvX 93;!EB*48`.S5Qs_ҹĞ^:O. U7sF' 䬡*^uS3+tRP>yGaSȥ8ؓc3WY3S1`l"ـڳ:em?ˌcڼWf;{i5j7 N@ߡ hb} *Ry=e%/H >\ q‡grou_fj|Csb/3u˔4v/zp\'mϟV؊M[W-3(DH LN7@?Gc<\_ d qLꖏ;욄_4> uOfce>GU".WRA?Oa\_ӏjxɷ~Η:7N >@8#wظq^'Er,n5f> bbFӳNBTak|Qh;F/[hx:=[^+!ioG[c MGVcE2>$2w ۵7bF47ⓩ%0&m3+\Ị@y=.da~OD7,,X1F&2f 3̓2௭o3 |ʃ/Rsܛwy/%77er{rZ7ztnsˁNܺA SFu0I/6SϾϠۘ8Ċp-^gm@ tѫJEů`o'}cKnbO.4GC_l7=Us YGK[__uf>I(%lua O|/3;^NsY`6e0:D,+CSp34{\ 8ô5&ޢ3]ץ?B1amx%KƝKT+ gd]R>4k!GsX{VɰUnҒB+V^J1)̒O! Sclg=g̩]zk~]ٲ+ƻm;7kvolQݬXĂ|ؤO>"58+򑥟oN~4{'QIj9Fbؼ>V7a QUFZp}|xOAD} 8%f%7s华jЯK{sw3咾x/+R}>ʗe*ܯvn<5ڙ2})'ռӋzsn?δa wwfqPowL/D׍EH,oq ?"yu<sdÄf麰jY?} Il?&&#VB5z#€r9;9n#הPf`dݛz yQk͹< c3^%}Nܑ>I5ӓjiq^WŋWӨ;b`ogk>l,g )KMtRʓg¢ipy_0L|GM&ႷR'2kepCF>xazRO(kebmTG$6Fw)۔b߼\apowk^ 54X6jFzq< 5c?.a_UN18ο=2c)|nMp.G֐wVg%S]hچw,N3pYh.SFsZQ?~{o{[ >eVLBL  PP:s}|^3;y]qmz8ONjư."r܅ Dk@ɍU\~SyeG#6AN />7Xo>庯 FC4 mH2Ks3Y gjYtЃ^(3VEi ޜ/0S`ao=M=U GhQGƬW1ک{NM$Td>C`z =txם6Nz7Ϙ$vu: 4S`/́k' |>tݪh: Oᔚ#*aǦMM/8i:Z8\jEpˆ[q2&bN2;27ցn1LrQe8-cNG%g,UqrO&c5tҫf N$aq[ yK'yp/x#ch<ŜI`s.ƊqnU8 /X|klɶv-LSt]fK'άФ|Gn8?m%::aٳ0T|Ea*:__GۚZ<6Btg3NuЎ5mv\Ċc8^%wPsaC5nGFJXT1@\COo^0WsrUl߇{yS%KhXjz"3&rՊ9$_ro,ck1l)Xsc4̱8K< =^zBõdBTd_{%[ hkF|uәxҮ@M<IcCG2UȚbX pm5ԃ7Hδ29(bQqJ몠U '_R~)2N|;N2 "<kϲc'/!oE}ð4$6G!W܉ׅ j!51_pxop$5r`sy?p_r6pz C.h2ZMҖte;UTsA)/X(yS.Cm5"Sp@u լ8qȖg+K %8̊xC]qg1TO2I2`: n k7rWw?Q_Ca7z4xmVfYt6wRsh#_ճ`SM r`kO Hi7LƧe#; hk♞JiO{5O\:_ aP1'*x:ZI %^.aǑ4aH⠑G9|ubo !9hckpDR!^_Iht-Yx=GP,:o̪}wM/ jqW-2J1BcW󵗸..͂"SSCXt[ۺ||tcZulh҃{^))&*TAF9k,mlb([ʨ) rR`Nl=ށf:Q}Ӆr Z[kiXz >#(:[z&\e1 *g4T|1q{ѿGAVEG rǝ4hCn[jH_1X^`'Ӟ-:ia?_ZrhG;.Hn^2>.熋 Pa3l@)7uzٶVVӽ(ɑab*)@αMExĩv{pg R3ZW(w(x]EЙ[ .2Dtk蛩him +!04f1&;q]{߿ nZEH`ׇR2RF۟1W! . y[?n3"zZz:Xj{.K{5JS1%)x{MD(÷"\p+o(r6Z'Dst-^^43:g3N~#`19`2SZS}ښ&,{σ20T(Na9oܙqilBwXᛊ9v]KpTg/eϮ¤l]v3t5dÀ;J;wC7&|wgE#dnLVgF3_`UpD]-@x7Gȯe Jt|qLoR b?cshwxuq س< UvjMKHTt}^_ekiڪRrM2Bn@1ܾǷ7p GW⥠>fڕ/Wł*;b %O #v{BL\iJJHʸOs`Gh|>3'ׂ8.縿 rG|ƒo}-qNPWboyefiK/妐>{U ˆ#v<ޜZ3B#:kgCY5bT$=KE*t4a]Sg^OSҔKgn*fxNLW}̞do9brd|7JBj.!g%DHYtXs=+ΚÔ:[֡QwN6KϷb5?M6|*v2S÷˿0@}۾c]Ć<1ŀ}Y'c7j _wy0,@߿157lW.G $dbFq =&\g.%2ަ!b~}S󽙊*8$+ 5و޺<܋^R<}Ĝ i WЭm&f}A?>!twDHø+)-LLj tWCyp11]I+" f4a6/~9ڔX4Qn8l??ؑ:f{]pSbLhV ^Eخ*mC[gIs;5 ՜b -ㅮrW)⭜kr͐3,b[H=r地M-:fx{0 {ԉd=1F|ڔm#$eGNrN|jfl=G^[x;I C4zV͸1[2[J7+o;L3Ч[VEV5$*pmeF!Cgڳ\ /Gvqb ?{'=4S]bu#7~+muQ$\gh|vK>19ŝg^TIۃ2.-J9e"kdtt/o2F*$Ы Ic-crN2pW޹aV7ʌX+;cOa o;3Wѹi<ΖWY{iZWdjCqJv=N,\quxo9M'XE;زp#E>.|[vÚV`W 5 #T7~:7&*k܀E.YdT PśjGc xrv= vYh;W~lE"0J&9XY2nzڛҷ)i[Si{6v.GE>?+MNJ39gVbtw,)o}n6m߰h]*sqDXΕ 9Ȍ*昍y]ÁmY΁f3GD JΙ9-L'yeb%{c{8fd\F-[T<.G_sgWޗ+X[Kԫ0l?)xN_Ζ-?Dk ū4l¿Zsﻶ0o%[Z5waR{E,O=͗geپuf;?V 7g~fԚ+lבs")_Xd #cM7$Iz+C|@ERddwfF#'CJN\%p(hRheNPn̾ܪ+g"&(PSWpg,kVV#w9MeD][2V;u4~ïѺׂϓyu|uw|Cځ7H9JbX^ N-3vR;|l6f,Gglr^OWѵS٣;IAγEVQLI o%aM 6\AUrbҡ(?NFA%-ze WWD@:3kͥs1ٍ[CXZ%J6 ְ}+.#f2*itI{=9Hx!Ԭ)679??DO f ZC=k | 9@VUPBW% *W7z.ܖmqYW{J}tvr,o|\$_YlE?&Y;O-±>p|ڙm ]R lds{Q%o>UOcHaJ6ߢ/*D7JEϋj^b"%_3w'_w6c?2< }w WaM.!b]~:eRѶ7C\53@Iu$G-rG O?ҹV^r6Qp8Me]#!ڒm71eZyd!ih ұ(1;w 0imSyk;óiu65cuiid&Z p+a~g&arXr _q0;0l=LvcO,8|h;Q͖sd}~Ar@5KQܛW,&<8( CVbXN &Yu$]>yxe3.~ؤȋ6+X|W`3yZA"dLv1.BݎE'3~̭C8}"2%i#\ N=?>U\  f*A}w|Zmt;ﶛEyG_&<3ǁBi*f!NҍJ:KUJI*&5QS_buQnɱu8ze V3 92w8Oa 9Oyg*ܠ152;}Ǻb#β}j'G1yq8)4͟A:^. 8d >c VD&SeKX؊eP))n wge4nh58[>05věʹj*#UWKS|YIjD [Ѱ6eބ]"al߭2ߴ*0exDw:s6 cȹz`nV0o ܝr-ǩVDfX(藌bt)rf&z2ƝXS_mtAtr6`-:oxu aq44Z_?\Ni/ۈgH)ol-ԠoH)8Rv{;-g#cX6 LX\FNĚR\RsޜYjW{}FTaZo eǕL"N'S ū1j_06_1Kqg9XᩨgB '/YOrXnsglniCo)㨣ehjaæd+@spՐcOT*M޼{Q[j[l,]bƇv+4qrZ\_UJǖ\ƯƸ_@-ް|lwZ $-.V.5ۇnj@W !pfKqiLƘx;ئqb=tz˙[$=F/+ߒp45X V'?\k͒FW9V~f 7klǔfpB^DZRUӗR;[\5z4ύ|XCA2%Ujس7Uȷ-wcq ׯJ fR. IHO;h=/:8ѓmXnt4vNr䴾644@xם1YO9mBD v׉x /6$}Sf,䖕l4ԓVJ9[L8{@lcJpK} &D(++ku]3 0}[Dj`ZC[a`PY_?םjsᮟ9*٨)OQƒXmdL隉Q'*zYOex Vet݇}>d<-Ķc6C_[ŝ?PZhbJWв0r>{%38Zӣy_j .L~^-СG׾FǑXoW-jp+ɀg,,8oGZNCK ļF[X!*zpx]7 zfZ X_ w#aL ėǢ{0.vxly_FoBD <ج͇IŻ'DZs潰 D ¢z8}G %ohCayM$bpaNbɹ*hb/eͽl7{SzGN/7K~3;a=i,qZ)}/c*yُy seh9M<7UyrFDKy.Ɲx0ݕ:E01B-ub );t,SXj4MN<-+CR #WJCsz~Ad ؄pcZ8ZZO4P0&Paqߋ]$m/aI/n{^:<ā[[3l wcμÍ}7yR~Uz3FPqF&[`ysf=~hCj* sox6BŬ;#Mƒ}0bYwXnFXaYylcΗe'6qzU߇m3F zvƐ nRp >DDPܘzG)!rvv΄<>Fsw\)6m?VWmSp,~oPS3JcJӿ2DgM*dn]s!Xܧ {GUao%"X0g1.['FȸH淔|bm6Co̐s@9z,/`c1pP4;`fqh۟@ȵС6™s/x❂*Y2H:2& gxA¨l“tA )O;ZJ|Sq7rxfg2na5?LMn xQʠ5f4!z<3U.jBQg-OO188F`>PC6KpbR6RR]fTߩg7u&hLYl΄ּ x&XţQmHNajs~ fgRS*K‚ ' 3$ ds\(v{r\vP{xno\\en^yguCe8VE ,&ǡ^3Sop9 ݮ"om@߸r59B4+F@YΙ;8 WJ3WWBGoEsNa/yF_{Psf#>ZIˏ .]w̐;Eoo3T4^)O"c^?WD.w7OڎϽĞ-eS3"G Y,T9+Z%! {Cװ0]ۿ;Zc]v,:]<4M()0dC^٘pY] P߳~tn^ $½ QgeW4&2Wvd:"ՖBƌ>l 9121/2/bal1Ubќa]Sq|G:vjLlIɨDvP8%Ur)pCo\䷏.0liFYEc6.IX6=8s}qyR1>NHw58zsoL/c缑s)ozqB?ȸel%29]{%KN"4۪`%ebg>~uΚbX#h FAXY^IxyqCb u1Sq|(k~LiZ)v:߀&BlC d+Yx%׎0*SOXdh'v:‚tNG{I"dv|5cq$+UHwAj8s"vwȃk.FˀuyLKq` {wFurbv\A[8f7fڄf]g=1ai9UGx+ϝm%.S=U Vqb?]J_URNcy9my.}E+> R0h\!T؈ǛJKlg=_/ PJ jG=e,g8$lHn ^)9\ٶJNSpw)!Um1rn'R9v.}^c 0^:&`ʾ !g*F:Ύ~vn6?1!‰mÔ'oVYY=FtUm&Jմ]qd: &;rK3ecЧ(ǕcB,[J\mz9܈j 36#0m/eSL鞮Y5J Ҵ;^fyS.YQ™<9cv~^b?͞t$NѾ nGC/ "/YyT Gp6gIsqF ɁK$t53M; y l*6:[%Vst )yW`lòI15`! yi bǀ nN7KK fs=S8{O)gk Ic / r=)@9n|[ZΗ,/>OKVvc-;30v'i,No5pOovafF/lZvGw-bC{ m>UL=m C<ܸzjX>LPz3gCjnq&8䠣{1ZcN*'{ؗ[5* fWjE t~ASDn(vki$8BS& {elȓ3xؒ*=2G? mPpsTe YL!^F7ܧ9&17t>;~l>>c}9؀a q?p0lWV'ĵ+C5-PZcř])ܾQ 2O֋uq 'ޑЁ]g"D;/;nɂ\7Cv0l0mvoD5zl#2E<ܓ6xdR Fz|NkiٛS^)cH)R5ۏ'%BOs=I^ˏfʷ',HKRuᠱޮ*Z}rgg@l̎Iilɶ<5E[rx|”auyD1!`7 k?Q&vg,(qb/w7}+Q*?KAbGT 8fzp^ Hl8e>޾@fp:D"D=wsN௺AjmW7ly5N3z OoQP \ͣU鷮!w#u{^e3NxssĹc= T<(^kˮ *tQA nH9pLXÃx҃gxpYw^tƒe>9}8=z`?`w0'%q/[p#}?y\W(iUΤ`0/9N=gMZGck36Q"?فb}`Ǹ`KƯb V2SISTaun.F}C1(/DW>yx1VʞRq)/ʯy0;ұ)&mG9Cˤ Zqi.*QC:at\~ނӈ2!fѮ#Ƣ6*OR_tw|(\>%U[Pq o6U75<_I7qTJx*ΆnjSr#&2 gY;<NO;\usCvZnìFU LA͇(nWn$d]qVڱl9P.B*G_GH8g`ɀ^>Qf,y BKT -p ߝ+O- qZw%3.iLuPTK.l]i+o}b7&&bc``(twsw?yϼf`98+Q!L“h,¡k5P;F`T,kMqgT^eX ~p#^ؙ=# ztCmoq:#.23À|7#gĐt3i4T [`%f(5bXgC Y}E_kdߝz;O0[\LMZj!;KǪp2M 6b\ zPDsh\V6uߒOPɡ2=TsbݛRG~,#͓!nD ',㺠-Sy ]9`%=z;3ހz=6—c02uf&H]gmĨZ̓aAɐ[/~E|Brn},%YA%uE>Cr˝/U@<˷C톓tw5,ìdCy4Eגp0kX|f[VĂk6eA+x8:@C7:ע##OtBb{|.Cw'v tE tp YN{'Sn#M7s[-Uy8FJb =R4iш{,Gu5bGptMRc$G Xn=wРD-GBx+lay&iպ?E9yU }K ^ZI~mBR -" Y:;;LFҨ[9XClhk쯰mFZvX.(1^؃{πÍ>舻\pѮpغI(볍z<`yOzN#밫DhnMy"crz*o q-svbdRKDtn$:_E;quNLj̉n;+z'jWO沀ps=@+4{(RMj%(-df-y+lsP[kv@AåxUfΏSRW-65$[G#?s`;ceo3ljMNV#ϝG8jqnIq] XN}+%)@W _΋񒙵7r pbR{̵R`ro9=zcp FMGfKOw5|Y~J[ L߷-ai)&oTɺ'iOUKI,7a[8Ev*bc/rNp<ŋFl[M7w0{aUJc~hJ|㼓#a<xm3r C:`žU! 2X_ e̗0A3,̬(&mk_%unM_Vg̿v,%^6SǮ_q,zyYF3K}DTЕodC#Pƀ|e>ۡS:19!:KUh5[uW~8#W. 8b\KjuN~e›Uz2'TnF41jYh"+6fZZ(d+ :m#66+i'F2|UBD 9Skk i4WonXC >x4sV].JO6>ޏhhZ1BOX#mEv08PF< b]h密-,vD|dB}#f57achaRB߳UK_NSs`7q4\;G4h]#NT0 _ ƀi*.å_˱b|-nxİw/xC٘ )ߩ.L5N罏R,k=-05oH)f}+ï43k`#͸?6F(G/ ! }0S { *SCvZ?a@d# 2n9Qz&|c:`ЄNt@&.^*~MϦ*I) 2>η"sP0U(,a@kz:#0`> ڷErrdX[^[!Mn#҄(}:O˒%^Hn.ө&{JHm0|s.+CiϹl =?[q* "vA6AN{:I} x;Q۵$ǹ{bxlo^֨*$JEגivn#-.fz )_,KGZl[$Ͱc)0J,b5GaE!qXFzK+M]jiZTA3 u8̼pvMc߯ *vs.IJetEYI"K)ur)5i6hKY# q7KqhT~ 4Haz|^3Lh;aR3W6P ] luģFdz,cM-.Z»v?NS]2}RA*Tb8S`P^cވcgx 'r:*wB9r1,"!Y pM~uߛsŸY,]>$zfsx34x|v͡FZX5PCghVFuWXrB)KQ  ![g aYIq"Dy0y5%#hJ)j-FO1`;NVEmGјFx9Ի$euR9&{Iq< JCa605FFDIRAvҬk(sMm>?Z"c}7}|ٹnwgѾ[d8z2D6sy,a,KoZc-Fa}ދ1/UJ'*!Y&,qľ%:IP#DdV`ԉߴèM9MVþ,_M}P^Z oLcsC|txƐyJ9)VBĠ e1{!f2[L-ʆӬ[u:NgJt]܃^rV>C|/?]Lji]JuY7g^6Xuww!\O!Jp'Mm?)zoTR84p䌲Pp>3>pB@'h1LpK b-o?jHis,1l %Ҡ0.&~RVu-yـ2&Sՠ` {;1$L%o؉4uw hBwi .ҙq8/+*ZX;0U.Cr' $M+шAqz,bt &Sh~E&%6T-`v9آƸC)zp-#"F &p3ڜxz;͝%;k//tZ|6 G1%Yxt\/?B r\Ife|d{|14Ap b\GưE=R "šnRɒ{;ia |.cK4?ȹ3z 5ɥ+hKx==X`tbx5a .rJET5vc\7`1[ "D>"x ҶwNdtokc>}-yL4- sa!] 89,kп_00yɰ~m*hEq6{&>qOwR?Aů)O-"s5ig[^ [TcS8>R aJ=Z隣 9aip7ހ&#La`zv1@AX5"+p/V("$ &7WPc y>Ңszyyo8yH@E)h\5mPK 0#56Kmb>6B%X!Ca j`EkZ]f\YgBw>o_] !Հp! w^u#b]NأdJ4= R(WvZc!_P{wH LSrzߵMM)x6XX؇>v6Q#"j`Y+Z\Oǻ[/1/mGSM!e٣q(p*1^͔8AKypX}lr|Fd %ckk5t5]kZm8UAԤ{~Nxvǀ ر# K) lGnSW8RJX+ uàB/`u sHa3\Yo.,~PnsZ xJBzAEtCeh/ \Jy1zJ*CTg%Z ~"}iX~A:̵v7lmYt>D?R8Z>Z ͧ%V9iΟ[)\4 Yth#~~I'\h |SB3*$.ґ5 ;pqaA9mýF(k |s^zX)ԐF"X˓C>^r)PDc3K~Ȑ{Eyxw6>g5L]-Y5A׮zwm))G*rB=gw޳ʗ%\< |jZ g)JY0+9[C7S6tˡplI6"y{되vd*ͿQ/C CPױl"+ذ\ѫdcUPU h3`BJx,qXW87 ׎tgI4rG]8\K-sClP[,El@Alr,Xx mvI1^E*8T/Ɠf CF2~TA[#1>F@o1| Jt)V"7u4($@Ul a~94tl1S hDaa2CR"McYhg7HCP~Nֿ$ݝPgIOj=B,ۢ% +jH5g5J?eIsQ=TF jI[CsL"fފCC(-BǙ9nv"XJP˿ڨ1( >%=0gn.M*& l7ƝӛaP"ƀ"Njfv?9q6sJQd\o G_E$:Ũ`.GhdF!`P2+\>WJAtwWUe\ƱĂ墥lD\)` R/ ,}dX`d=g #BUxߠE7?51 SoQ3'-$W࿓@a o%es mG '$XJjyLe({TO$xAK2 !v"7cdoe%Ϭ9%Q*4Pkr%5QG,0f}RaŴWe͘IGQT~//)ĂcCaUxopܝPA<-ER$ yAyTw))&WiT|yTiMp!o^F~!b6űM혾kM8;GQAY0*H4S"y?}pCrR#lqFEpr3*T. X 1j!=#@f[հQr|[*}Ϣ͸Url<\գ\LCB`cexfi).)Z |р?TzDmѣC 6׫CIFQWK0;$HgA\E?eѪqtYJ9txDoJHgHMb,nhN>",c &+,keK ׈Otޟ xȰ ]}K1 4# (֫M-I~?v$\F55U5'(rbbpFXxPj-˩h 9l %iףԡK&r+&דՔipkX6Ps|jO|N [*:Mc$ӒFQO5ղF0;IaT`I| ? %wT(l]I.iZ耗'`_ǙNxpx%\Kؑ'eg2(^ >x=\Ĭr.榰9wZk T@޹t;\G[#>Ez-EYE*qgZLnРy-.5Q j@h~F-CEE(̕`=aA6J+({:vJ^+>59GоE\#YS>jG0ZZ QLzC4s=`˵6)9XRHx7(=<gq_u(oRXL&SޒOt;3m HӛыuTϫC@hW*lGbg,-QV`:=njgBpƝ[)k#EY-%p~,x%`=/X<̆sGֳZB搳%r.%l}Rr`<%B(1EUZ@#hr-nYI7[a STPYE5 iZYJ%zx٠# aw=XFFd9ߣ6Җ͠^ҏnk>m{ȔFs3>h>YbJX.V![[bKYʵeut{Yӌ7?˟漺Hsi`iOzЦetuٺ<x7F;e,)c79K1~ b`KYF!8Ph2]uX'.o(6bC5^RH9<,(_%_roD Z *81JG옞cUrh] 8,nW>VsYGxH`|K fGW04rxV(?V*ף0b=e9`ʄ1Zʰzд\r.ē><~F"+pd KF ̹$FjzU#}]M+nP io@s)ͻzVSH|=]j=tڱh>?FERI| eYv5FxjHO˻yⵑ&3۠%ban/ Rp>۽9x5m8=Ml.TЩNiO](@lhZnuձs1Uц>UdZCP>qSE#x{H:i+7t3\jQ&żU**Gh5 hǀAèl?/Y -ryGV"Cg)"z5/ZqP#kiz-vK1ɒo3rSa%oVP]54{KӮWwB"eQ2~5Vq̞'t SFrfBJHb$F(Ɵ4>d7)N8T〄zt?2Y "xwbdsep9ISsh6PDr)1gW z8$ؾaW!g?kŘrP[d8$Ŧ2<)cӀ!t,4"pܗQ҄6{u8|1 0nJ#%De.Z_\dBZr;GdQow ZЦG[G|K)ps:@jirN ~QLWRW{y=ѕ|RB3DQ4yyJw8D7U8wOC~s Q ϭ/U 15b YņT DH6J^bkeV+5¿|Uz,j@ƄeGGK|Af ,!GUHQ Z`q, 137af귳w`>3KQX:v"Q's@f%w>,$t.D-ߪOԑV'NI*I6%fQt E9_)x69H zQ?]3;#g&Id)`s+dj!qk?j-*lS[$ݾBI{1#ʩqVݯF<,}RYudަ?kk1uZQE}/Vӕ %kB\^" W LlנN/ aghkޮ*`;a+gT:­#$Йq{otx~mɒ|.y(Rl_Oup:NEj9xؖ(F[xjL#3;z{ͦn=^"m|B=P7zonuWmRA1 a}Up#H^ Bd~aC% {/R OۺӔf.9@-Ш:^ o@Rz={3J at"zƑˑKmj?Qƕ7T6 x]|hJ?GU~̜E' u<|jy>7ѻr hD'ȥSh6zx8>FC ~\T3>=ȧlA}=mlv`Oj&D_kX/¬K gg5mXB>T"*=]akrF 8U xd#/X@^G% *rW 680Ȉ{kָ_PC[_hJQLLߵ[%OE5;l1I;2S>ݤ$AFp ~N׃_b#Ӝq"0qu;LϐCܨCIrγÛKHI{w)IOEhuj2ڗ[3.R8M=wRstONKRF1yݠ#ӗigC:is$8CP֝43IX s듔D?i}g+T[!5/+q1*RciBR,}1czah#>2u?EIZOr?I]}uq*odA~'2ߏ&ݦ|x&\3/9՞%aM?o5Z,$G)RQl [_iֹ_O%ms$мV:-]#Wмs6UC)IHFeSE ii6hxxRx˰i$(a/P7f |4ByHb j)\t ?ߕΘ9AیA#5Rak Q^T{0z'&z%T}>O*iC{cx[eRL w<SƊ}]rwȰ{ ][M{b^8„L} C pK%'i/>g)QcY8z$>h8|1kSKaCQAwgj4A}tgGu-M){]DQCRН[Լr\m;#(~ATH=rr qvXmvsOffMm_ wy5|E&1U.`]e7 h{ ]xMK%֟-ϡI`w2ϠKaF=Z`թzz|Qt}K"(Pa+8AFhicav<<2N߿⥆2GhE̠>: hBE :`y`ze b(оH>XC \В+rb ΢b{.!a־Rd dR@{,mbk=rL#&|傮ۛ #~juZ<̽o@%'Kacb1Sbpƨl鵴Lߨ[:Dggݡdr/{K&|''rjGS_J4J}J}ytE>YO{*KmHhM aǴs>HkR8ʗ`,uOw|ͬ^_g Q dcrɛ\l_!8yƀٍ:+ٞNƀ'"pXaB<C3{Tjqhxz99DQ;OOXR"rd 4dQA@z;Nhˀ-r>cWd(&RN!-xxF{}hpIk0x9u} D.& tS>epY)A׌To!.P m'il@Ya4"ZZH+.2t *{;Q?KY{o}VRu'TQ~65Va 1<`vPw3Je;Xm9|<>FjNIPh3);Ok2"#U~TTYc`!6mV@X,G>}Ոp$-bX&i_4uMNlv'Xz` X.vFp>.ň;CAr$W5wڽ^B;}%e;" [֘6%D;>G!JF+p ϗcE=OAWpiPF;z;EN33%Bl; ŹBJQ,F[beT/ƁȖ)A 1?g㯾v!;(DCɳ{#jzPmb YpWme7P̢F|H>XЉ~\I LUɢ:r%I/߄k41*7|:U{ O]鹬y0fOO b|v8&@EKn [1{Yn4\Lh(AA=ާA'Q4z8?3[3iL,Z'e.a Ct_EM6ko bm!Ňkk.FY8gTں lUS~ M]a; >nwFN̾vB *i'!z?‡6#,Q]F=bjY:>rBn ?Z6[.*PXbg{E҂C o8jN=MYϕЦ#ѓu`KTFJAdsa4 >نӫ&+lpco1|`DۇDӔ?hѸR7o.le+=l,sS,-koa1}=N[%ScXp[Etݵ²؊ ׅ݊v+>X(RJJt;9>3 Ͳs,w*>܉g{?I] >P d*I:9[j줫R^NMi*:g}(N#'EE0DnsQ6?V~Cџ<,7ス6{N3f,.b m*qĀA;p:t1qvՙ.X%]YR( ͅՂs< j=  1ˌ KBX)o>O9Sf|ޒ^Ӭ:ɖn6|ކUv7FB^ٳ-SRT]Ā`m&pX=>1gr}^7`!wY3՘^ܹDdžKZE˕9ffΎELCbݵx'J |I-0>Z(EvrI?xү'|%K &'8;wy~^>v]+=65Vڌ3oX4X4`b)t*sQ+GN/Z.yT{x;g0ehȸvuMX݂Ľ? _$1b}W1Mx:є^+wlӵ͂pu.-GSbϚkR:-~91ᥜ=.zrUgwt+nqf-M#q>™؅p\rE]~إʕyv?#!Y ՜K6qWZ6<ŎJyԉ~ cRbFBQUe\>#+QC]0ʐ㝐V9T0oM6(r w?Xlв nĠB:+)b< B>!FC_"fˆf|/G}LJr1 ņȘv@i?s$'^lk㭃}l%ϯy,L-_]A(@7, s;bJh&dr|>`:TgCzhN\ SwpvM:;DUf*RgA 2ӑhT(9ƺ:T:l¾F(fz'bܙA/UMNQڔo6碧vn)=SG7oKhwkA7onjJΘ~+IH+DBƭ \4/p:]X yjȜ4Gnϖpa?;pT}#*"nZb:4\:̀Ӣy!x *LMt5}q6=a6iO!+ l)b,1V6}GQ&W:^uKĽpg0w\#~t<qg/vM}m= M뎿/.C}~Lp!FIX]1}]"dxlxQy/v#bf. xĐ6K=8~:?&BG*iQʿ `c?sXoR=?&(7"0 *jۈwhpO'lŔͩ.nf {/%nYc"5(Ұoly svD,mAlE&kpb!,hL5 3 DD|PI?5[laΟ+9ʙ~_]J.Rk|Fsr +=;FvBXPxto'S0) Ġx=e >݆_,)+F#eη8n^;2=9{fP3Oc*էߴ)EnbXŦm?;\vŜ[ 9db՝S}n1r8Fź¼J@ehBjeT^q}}ӧ$#ZKM`5+Q7}'$D4F @yؤ[T „?x8׵=vB0Zߑa݄k:\Z̼@}nf̜zs^`IB-v̈m1/x0و~!k2Zft.i91^`/QdEtŒ&,'fwZZ4kqt32'3=R+;H1CN Yky3M|\up\1X4,@e?oԐ|אXX6+gƗKH vfj!&[As1gY2=BYy!fhQWVX:DF t8b>/Ч8Dߓ9@x R|CF{ױ2:o1O JÅ7'6 p\ zjj/F{C3&ӌ XB;Sп1S0 'ԝq$9NBȠPh6o eðDЛcnb&艨Hr~LcʫjܫnZ,Uvw5U軬~DK8}]&\qB+hb8.mUBUNۦI-IE!CW2 u[jr` ]rcn4vbD;^]n'Kj`cc[RK*D9:=ł;fgG0ÎKL9)J."?u.K5 xDqZb$fMʈ뼴s7V /PV1pN?χ ?y?Qt`&s0de1{՛CcsG}vk{hajp676!5a&uA½_~G1/k~Ɠ>ѪBߔOQ*z+a2#1OF-nn8Yר<5Ggl]/0V9&f|9͓81̘?^Po hIIO?ʐ72}3s(qWwG0t-w5$ӈ67Jt ùX4wv}4~ç~[鏋fO5 UU_;KeW<Ő#evȗ͎ 2NѢuwiID5KmZt=T,OMV0֘ZҀ&Bxɹe(WlW~d~?HEVGTؽZZ:وyьѰ5z|:WC9)pe޸Wp}^'.eo\y5ԯ2c?Äk!ܴ!w.ngd:y$"10'Ჾ jytNCK= W~!!˧!mN!R*!Tq>7ݶ`Y/bC:II"XmmȻKmh1܅9|<ș)$, ps-zgwj:QC#Da\ZD~)߻a@ p*cB#Aӧ6{Z[[J4U :&f_Zc;i߆&x/ߪv*MPg j櫚_>DoU–?1/>>?%u_`? Šzۼ;Lωqﰈyu; M! =1y[ i`ʂ9rSGͶ`m=ٱl13Q ]͚~'Yۍs]Z_8Ŝ>ߍy~>rNi!׫rV2W4H, otŲ'~z8STdCce2g?f`O㱩"38YD Sc bJK~:hmi~ʌ^竕Mz\8D}1!Cwh,\ṉu5PD<ƥ0^gIw?sj" &)#C ڌ-=Έi۴xi-aڛ\C[xj̙WS5ק9zi|ioPӾ*Rr*! ςIE,Pͅƻ,[;J9כqTVx=Ⱥ{/, Rk7)aUx,4Ɯ|ނ3H^}8.ٌ,ڊ9CEEÁ|cF;PWkѯBP3-4_6Sᡝ5 on]cr;_bYh(̅a_ BB]4 gp 4w6Ѻ&'smz)9XʞV aόSLN&3:A9o_6`fĩR;VH1Ge/QL#pGDl,f`o|>S|ې{TXȈ>`W?pL[!Vr.Uܨ <""U[ ]G]6~VbҶ74bW#tl„3,WWd㕰@#Wb{QܗEAW?[+!7b^We&+! 6N!N0FܡgY7̑^ڳa+O=OQ#cYkƔEZ Gkr:T᥉*ON \cfwA,0 c1>!]qe|r {d`V=LS[NB.&֋D߀͹j%/le6k7y"ۭO7xGU tHskE:LmFN(L\ = b x)pe|4@?@ l}U=B!> jJpEZ"a(?cgN[x5oOVl6WT>EoS;k1-XkqZQ-T`7T?قAj8]ySuUxP߄= NEéXoH33~J/H}%|S$Ꭽma!=%lW괸7_W糷UfQWS"o|+.G\=>8Ӷ[ d |׏E{ݰtL| ~Vd&SRe q}5hoYɌ{,{IOkr~-~7b\ ~a!C~20cQ%4¾Xeo}՝w(>b0?|A#!)uXdCd-ċẍgk1%ez93F?ŸH~v$ gl]p k[o=c>wFFi;y zCfNOT!f!m񝱘!{+(J a#Ka)j&jy%}/t}F\6J /F:6':uc`rj-'Z;9aitU\M5zQ~sUvzs֌K2Q4N=鍔ya<%߰,? ;.xt~XkR<>"< NV'y[UysHn`7LڄOu2[7E_ȀOMy1ԡ5JP7ILܿiCr GkF1I(NþY'MX֧T3T38Yex__CvMX{Yjk_i{G_Sp$%`/Jghsvi &rԌ{nU7.c;n'LX,/$T9Gv뱙(S*Fw4T*QXSm触ȻT 2%gc.v+Yn Zxע5*۩Ug1B>8**r&nat\~Ӧcvp3B} e4Ç+_|+ÛW9)Uk2O|Veww)sg=6f'[3ͳY-8ɻb~f~)_qխ["~H>O$ z7^T|z W|)J>7VGń1; # VuSde*"*,EB[3ȋtߡǾl95XR}2q~oŸh[߮6sU!G;:3m753~r m7Ćclߖ}Ns#?IX+0j3 {HlN0!b]?k&x$UQ0qx{?MqyMEgc^a.)rC7i9V] X:Eך~ ezQ re^Gpْˆ4XX݇l/-EXvw=V'-!0<]XcV9JƣGi dg SM9NdgaoKRSd[v5fuSNb]`1/٫Sk Te}!Y8,"Qy:4>ǥzVpW:dA{CZУye*Q'T?_#vbZy,Ʒ)ڢ>mOv(;~YIp̘6ai&lcM/h83{3dHة5sA}>̫B￑*ū8TMzqJ =kOc c5 ?@ ܩFKInYգsz+47T[?mN2"3{wf3ڳ~-X[oCv1a2d4aF5JX[!irWN€l\`{1k2מoŜ`ejQjt Q]Qު78Ha{Qxl0~GOcKU~|t (@C>ƮjlmJ:8UeH}'v=3z\gr=8nS&Ƭό':7BbӔɯѵ+G "K>2B*vt>O0bgf%Zl8^¬8C (GJ,nWp`nX~ńϕ*kҊ5-ȼ} `#ښF}#7%̫܄] Ê|dPU8q[>ǓA@b2N^pI XVj0z.lEy a!>+'´w;G8 0I8'#˅ů`6 w~o˫Ĥ㑮Vi-Sat\ys( 2`{KNA3W=1FFWq=2^&eOTRh g,WWݥ|'4+˘L6ӈ.)~&StYͩyVŞ9:RO-;qJg1{*e#̪g>r3dVmзPԴc82,ٷS&6K2ϊ9hnjb>ʊ*G&-nm;݄%x^SWKA8nߔ^l)x WR!K5XH)Nz,ʒe?.dUUC`z0/Po OA8I +!&_1voXypyH>^D?8Tt8~0q g6JYf(4O+3[ 3xeR%9t3.7؉ωS\Ǚ$\^R^ ez ϤXpT1 oU:N[ebWt3Br16MR'˞lnܥiIB'\5{r[Nc\A'yPQǃyaD'|úeؐ uy nS 7g<5BƵ=XRvtݓsGyr;(%w6?J/nLHH>rg)b"Cߪ=sKHcoS=\XJ΅-j|T 㗹h}ϤҺ<ܑ`xy! ˀjۛS0_.Ei3ENޡǧ\ՐWMkm!덚a5^ fؕJ_DE~2xxoUu3ru_oD"/bc V7FlVjƧ ,ЌWb&f15Xpp5\2qr)Ov%UwEk<ϝɞ&owmsN;=\Yrޅe.|ǑIj=&ZW xH8和}{k {~'[wz7ߵco+hGe /7م˙zRnPaYwbUx4KG vEw7n:wA :;? < rԔv̛)孛2ˍ;Ra\$hsET Ѯ#ӡ.~V[p6'+ONg m業"zq^ir9"|B6oVkmoѫ)l+0gs5pS+nkns3 *3޻Ī'\!djgu9j~nyثO;''%wƨ*WNqV+'|vsse3;vep)#BwbF{uhGR/˽9tVf smvs^1Rϗ07ypW/Y=e"7ƥɹ'E˙IRhVp(L u%wɡhy9eLg&~,%.AZRiC>=SiE@\-zISw7 :1D d7Ca:ck2_ˈx%H¤k| Wȍ:y[p2rQW$ sĕ].̋#42z=p5o7nSp4Odo/jOxnM֋"1^{{3z[h)C'ᭌY=YD<X.]_{x0#e\ZN?Nܥ/yRȞ܅w2i;ߍ\nϴͨd!֢FBcZ|<ӷ:*y\%9xY)W LZAJ: B!%S/E086{~^r?Cml%Z&$5`*/<[by:˒|b:,BͥuMC|dtFR+t3drZ$ZX(S%)1sF˙:@C=@Ypu߮d/n{&;02X*3ᾕzrV97z0;ԃ2r'`"OVK^|z]An>3ϋ]("+\#1K!~NJl8iWسݛd tgkz=q;]yɍ [&%7~>*e}V9xXα^TU'*y@q;pTU P _j-f/)ٺQb$r:,OZ{^_Ii_OiLr1*E@e9 n_f}XtJ_[4eWGgE'=6Ue{-0Y8( | @XU`jDm+F(k_}b% 9wA)>wxFKgۡkn:·S86=M 5R htg:2j?4H,ှBzrfJԝ3evMFI+MFH8pv:g3OsfK'. lXh;,sv|ZhܽQoť"9j|f2(1F*+(?epބAGT8 r[6j0d=cp [6_Lya~1kwx|28Z z|VEu ^_8N-uCkl&/.g@wMo_AO7/Ȩ͝;yz+ܘœrN+>ȓS\=p]ck%ouT\/x pw(!n$T}qwwww#DQBpw S}]3===w>tYk>8UZb;6W֑8KӘkP;+:71b#tM``! I"$.ś!tbh /rGJ8I'2v㮼z֛zsu;8zqFOonwo*=/FUoO:?%+g&tCnsY$ct#mgCĽݜp-|7ԊO @[չ~ujLgLU>b]WM.QDZ'Zc8MgQt &KM21%JL[QeB¾w#)7^-QȿLPG|Mf|=яui>3(3o~ \ݰ!3ďGR8ܛmiG\Gy%ӇpӌKI,!Bbx[u%=bť4 UGXO[C4<9ڊk"miIF,A3#/̑怜ӼY|ٝ:s~rNmSNb\TEv&މꜘsхc\y?ĉz)N0Օ+_;̉\TYTpR+^9{6`iC>]1J̀R⏿T0ǧ䕘ҳ"Iǟw#ݣo'0׋SaUʀRK=9zDri\=VU;aG/WvPpt}C>v|0ȇSx1қk}8IWu}؇{K?oאkFQc| g7ʼmΟr c'JCʚM$qM5,DK%WOo^/p#T~)EwMN VtI=uA*lޓ\8k>쩜+Q'3|헸s1Vrݛ?*g'>iįu2sYiVWn?8{#D80Ɗ9.́vӞyf{s^)+뚿%.0et}e{UNhPaey?hk 7=oPt~;snwhLh30S?e•\5RѤI&?BK]ƕ3hhϩ+YKZu?7No){`OFpnC<ǃwl3ьmjP¾uL` :jؕ<5ɂѦAw4}|kO{m2C*VļX3gg@-6 ߤ u KFpk*s"_1n@؇-٢;w +6;Q'4sI_K_83ёu]` i;Ž-՝Xҙ/;PӚ!#,ڌO-جڎv:%{.jaӭ{?ؙ[)lߐOg*3 w4[W/]%'GbzJ|[#p/3HÜBmQ>QOsGcUs;oސ. 97>Ig=b#߰ڞN\E:K5}Xϒv  h UV:33Woۘ}LYY[ >1'dMdOG쟠W S|S3ʉ.8qG{w'cxS_άuVfpz3Gdp OT֩~Nʑ~9LU1e 2:@;r#MMZ3ZnMyf\^e`+6gG{C;Fd1?jq| K7ugUcb\USO_Z:65 lkn0;eޜ :͊s 熨3$G6ffnCƸTOHט hԀC'p+w\LJfWi&[ٱ]'r3_v>w͝^MB:*Tp\›.\U€5.jn :<ƀ-&ew/FXͪn PqQX3) Qgbdu:&ܭEfٙnY&lQynzՃ Ϻ3;'jD>'6͋vG\LWna.<̎v2nAd#={ *s&\ٔRLx]aΉ6hlfO|E?Fk\-ɺbCg?3CRu-?<:\m+5J܈߮Qƚ;awY ټҏfxS76JĵAxħ\Ν\ހN4,_Pl56ۓ ೶ S*K`]|Uw3KEWղ\h7M>G£Y&XSQ--ӆTw.ׅPzzQם.L]d3g8koojdd'ouo~ϙ.lڙȓ3Pمm>ȐE %oU܌SzԀq=ʀ/w'-C̹&$ïxaJ\tA:OUR%7Ygct$Ec Ɇ3cvt[SŞ\8Ƈqǯw"en?V ?9Uxc5^_fo 5Gݤd|(=YU *Un)^k:Ԣ@=oBڎTh2 >~ A;x *]{hC$^jM]y%ԕ= \6wVn?!ԋΙ^0܋gC>nw纯l6ЕےfZl8%F9}W?kHp6ˮR4vnj_sE۴zM,|G{HE< pP#zm\tLADS%=ʜ/vM^,`kָJU|~DW$ fʰܼJpZ #%*+rӷcI)ʄ8_㯊024A 6d{_^y2-c3#P3y<΃1g#[_}k؛}]n⛿d m*Թ&ߓck̷}MaW=R> k<g?~{9jPQQ\*DzU޿b=pdnΝ=2ř0r>A>^,\?aA a Me̍/,<IWO𢕗'ر2Tɶ(0MD4 ]'cQ]џvX|F#(<PxѡbFʙMfv=O|3Mr W)x{|V$eJ=3b/u]~__ni0ɸti_cͼ#o1tAJ,F&'#|w.^Sβ>ّ?K͙3]uTXZ ״llDx}D<łw œ;x@*>•>[pl)6Uj])Iس: M 3r@T (>|s޻3f7vliqlO=u|݀[LҔ릛r`#. 0XŨ a̺^N\7Ɗ74av}ĽeT9J®aPVKaFvOF`n1dJvp9N2 {~\(HYW}Ji?Ǒ~xlgZnF755be,br1R_j2!,RV\\ex`]Cp}D.Zg#o*FǿPx'vY$?aL/I4(Sh}  zu;IBt3U&Kْͬ9攏Tβ}U)h^-_ ع;jb:<?`sep /їE#|9xQ+ڝY;ەᩎm-"ǔ=M3}=;Xb6lC|LL4^s("K|ԌbU|*+%Δk;Q+[wgѯ8܉CIf<*2]>>ܪ6UQ%0'{ O? xG/`ZX$=5vӡ)>V^=/-c_jlVrTݙ;2;kW$u~r.@݈]xSZɿp+vXuqP0 K5HM1fDk'3n6,"?`HΒd4pnd :$#= ;IC=v+cĩݭNIZ߭A7ǫT9W^ȬR9Bo bJ[kk? c\9INu9bx=_UeUoY8-Z?qWRx֧ U6K=+5x\|͘˅_\Csc Xm8_9{سn;XRveNlŝ61͞iqXN2 Zm~EPzP} 1q- ֔y v5d/7`.V<>1w`ԬSac1TI".ň]*-C%+ SG&i&ubEy03ky iʜr"J3OOg=rYuΟ['H,Ć׭qEN28. 3Pf-f"MnE_mZyGo'|9q/}:J4>>Ly5C;Qcg2Miry UP}8vÊ[P? %؄_=P4ղQL5F<ޞW_*wN[L\^ߢPl5W,dj` '+ad[U1nF\Xc1c1?<6MqNcN7dl篩ǂ%ȎHBuϾ(~៖ESD\+FXcQr:gg"ܺ]S;- "!K~CBz7GjJW4B_ys-r}½͛ ُzTM95[AU~GFWTI FT~wC>?VhGVϕ앩p- >kʉΎ9.GZϬoQ1nh$>aĢ\dx$+6o>c)|xSՎel;ЂU8{g}vIɑ2/>`_*CnVt]bX ?E(lJ9Ǿo0M$2u1w J| iYHꜸDj[%ըh-T7MбЊ0u;a<vbXB/"7[sez3t)ͷdՙC#_ž-U zV%s zeo)mMte +x'ͪR/D |F=UGAm*P5ȗV#U1c xm3QvXz )w32neaQUPGX_ fL#_56;0T}_ >)ԫso [ Tn']^gɂ'u,KfvD.+U SÂ}ӎف6<;k֣ng،uHVcz2#fg;4hX܌& eXob3p=sW}Bz\Ю|>LJX WMW9T9l3`zM,+Gis\쮸~BJl*ψJV ׎^GpZ~W0~bsѰP4Xo=Y1U8 TCJ'ms6w[o:{[Kj 3Hm B>2REiOyDDݡ8{6,OjrE)z~g@cfc}{q=Ɗ[? _^ӲӰnuX.CӔ:Rz\ 5x֭? sSl{.🖃U2 ,f^xP>k?a]a~0YO`P} :~?N5I'iYE:`.C1q$ $Щ !Ry};*]C]lEm '3;>ѧG=ViaեOؚ[]+>GSp4'^oN^a"-^`#m@)tkɁYK#4 Q[[a߇ ] =s1F#?tT_V~sg]Bg<n~OhiqW&OVVX=vbuO h`!=HQDqfAۆcׇ*e% VJu*{'gi1-CՈ*TcDs=ndf<݌Sz\tgaXM棵Mw硩J oRep]6+G)\,~I/ y%B‚xdqv`w| tKExaFX]@)UQ wlc:9 8si(oi-OoUZ}w1:?,@WUJ㍄TT8μc+jPhSvt8FN1~i6R\OmhX/uX@8af>݈cͱ[@7^QTN$̯,qh6*bN[=lc0s6>|Wa1kPֽ; Ӈ~t!HRO$C|"`z-;L=m֋^VLr̂˦qBCN0tCnhkˍS58 r=\B1i\۱aر,&oAv]cV4 Xݛ#vd^؍Y_|^ hi,6eǿc (b,_SMʬ;"Q2 `L8m'Nl[n w1C/>gF)ji!ߍ1ᅯ6`]&xk3*+Dh= òA|qz- 'EOacN'inLa: !hTjQ3Zx`CCT F1/DbmVV<}uA~s^wH#+2^K/@aKpwiʞb~7՞C{L,10A?Ya(k-ty o.]Pyto1֬qnWԞ; s!(a;]_⩭qCYp|?3_1_Z>8TD>r!P}ome3[=>TU>LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[ mM-n\=us"~P[ vpk*Un,WjX;GQ~emO?7XHih~M_QHG;7+"j ?oO}C;B~zyѼJs6kuH_ .#wy'p3߾;# SDUcmlcFKEWgqRDɴcE?(A˚xW[N9b~|7ZBѯ8ܭ;MCѬ0^NQ jٕhVuyHGRZ>CF8+ ]P< ;nbQC,q!`!af}x<=_A#ڦ Ye+( A/m[8nɽ(OPgyݭ|uB/]iP墝:Gh~\>ͩ,զ]1 Y[}ձ먼oɧ/?jcszs5p28T;/Dq#,G}ZSU?0fЍ 5{V_RD3gSRoH;Iq+Fq <]bS0 ZR._tIC9ȐQ:Aٚu:)AzC)7,5&Kc QD(zU{l?O|~e9p_˴-Y%v@ 2]Od ʥZlxNW K Fr@2qXH=;+uF|(/(qI{a_@nop;ē;p  7SO Z[pv=? t@T)iad7|1WwNۖxyBJ/?zMLgnW@#jlD1j9n̂#L~9:ldiN1,8mE4[NoP;cb*8y|csE!ǝ' 7`p]%ОYgZkYSKV92Qַq5EE܎_YsVm?+ʅ n 6Hk~cюJTP G{8>Q;&.NAq˜YQ-G`7=&A ^ɸ''ٍOqyW#}ԧf7#5iuѧz-^T(+zh.] zB6F5]γ%4uH^ISk1{ _^GkFׅՈ/zZ=ͦsΣZTBb,/sXY Uos2 \~6QǁLcH/ki3ZAey2f]wSkd#B콕Д 8s1{&+^b9RɿKh`]Nbst|غ0WACo;ݶ ӺNbwQ2oqk]ʹ~AvF\c4)ݢF9z bŅv2lníq:gotfN]#ZSuiA5wrulBl:ys+PM_i`!:3[c.rln·fNv<"uCg&t\|I]c9< +:8,Sl k"3_-oօ@V_l ub60 ށOqPqR=bg.J3rhY0b& X:߄KЎ^qwe+gIx$9Ό}lTŒ&\GfWwOnOl}6=3tSySWMbk֫krbKpFK^jƄc p^4eƝj<)eS[3N3W>u[5){CbX~9a7lyGg@}DycWH/UZ+?vTdEE;=qq5"ICj5z'cI/0(z1Ñq]dҐX:Jc FƃRGRoTRFS[Щ;Nnc̠B:Oa@,sAa|O G֯/=Ww N-qg6l=!prߜ0RVUF=4s`h+dϬlFߜ t[o2)ky!Ul8->4]"X24h ϯ3]-ߩD m8mשR'U~b!t^mj(YsӍ4h!jP3X—f]f꜠WIušP-΋V;ם. gsJ5-uSe"{w[KLnt:?v\1HU#J zn$F>&0zs,i1$=+*nhрs%YP<]cz,caO|{:f3\iD9Moe}[pK7[vh盔9Zqh'}\5dF ZnLeY )=SWE#ةѣ_Xsc#w.2lg‹9lTz3+λgE|nk{^lym+GSݕN2t`U+&,6kCSԽ‘;uN*[Ƀ&ok}R~0Jq`EHKOñ_PY*O `]|i!|S>`⻘s:fjNFAM`MyG˙:urkp_]ǑWZlkWu۞>pP%{ԙ'$ܔ|lkRVr +irFpXqIDpU.2䔯|x)SP  w+Hn:oǠkV[lhco&:jY1E\ۖp]rbtGΕ\g\Ѹ7b`S>#\H´7<*ђ$T+/%=QXb]37siVve[t1XsmaKl$ݚ2ϊ3*S6ajs, ǔbl]B'AS t Yц|Čq 4ae/w.U⌽{dl,23D9R3C>=g6 9bɪ ֪X3O;Sc Gve={Kn͢Z,iW+)}zmơ+:yW%ydkףqU1?K}L8=j0e=Fw]0NT lvsYm]4Zƒb1%с,dvNsJsw3eٰ/޲dKkŦVV<6 |[yJ<^o*Gו8ަ_g*?5DKqGv2W;n1q~'nZ=oڕjh͹/aj ӥ2Pʚ8Irߒ@- GZ9p\Gι`K]&5ӢָZxMEsܵF!}L[DG~NOfȺ1t-N8HqG$ U3 f!B%:i0/LB<4Z5~ޡK3w.}ߕ흝V9OoaW^E͎vڄ 9.Ɍʽ%\+zYq{R(bF<"_ n}Y}3p>y*64duf2݆tZ&[Q:Mބue^=O:ܕ?'vl]U.?eL;f(n6S*͝D}#>ecLj\JvՉd/‡Bl8'B s,q]BOj4Y; 2v ')9H`ZJcia%V86ȣeny4\>,,i]moz{E,Rkg:;Jz]9OLekA*#$o٘3DHcw`3{pB_w)[֪ѡəj(BЮW WRnT q G]1 ,a= j54!7"ԁv zylB55|c4&qcoQwJ䕐j2L\\*0:K4Cnt|d?+ 9#?J 9ƹX5QcBUm-n{!=n1L͖)ϑc%G٠mR0CURz$i 9y\hۻi_c9T&[2:ws4uhA?\ERW44 ?Q% qJeПWaI͑uC#m#[$/W C?kpl .X~)б^e0!Ifb3G}"B l?~6Ӈ?iwO~ӫfZ`*F+#dڵ.Fk/U9 :zE 8:h\HƘTX6S__Hw  Q>F6JVP顆}{ QPG? о 7)I2" WR;*20+#xo @6v5 1Gp"OP?wsd~< XOZ|~$T`i؉DZG? rȱb 1wT0UDG;&yQNvh'( ~DLhZоأx.qp. )p(Z" z2meg`[dkX\cΉk(ဩm̸8H|*c/k߰HSK VJUM]L)s>F귪Pm !MZ۠EU0(^‡=*MbR[G,*Ņ D0h#<THPq5Jq}K["Sioo\ʭ0Xa ~g!/ @2ϴK5h'L4$>MEߒѯ+v=.iN:'R_L /x\DxмUq܆ !}GsX}|yFs{&r07<.e:"Ưp6T+#ąj,d|c?Gvg8(^)DŽ24PbgKCi, n,l۬t-z|$: %_9tsA ])$BCTmg{|,|dV]a[Ÿ-jI`?szU,~uU) \Dl^kMN8D V_dJ~¡k*\)pf#.3 +C^C)OC2oPiT6zyNJW'+ʼnyoՐO"}/F(UX`3LǫWfiJ!Fa̒"})ÿJKXZXDiѪ9æ3vУ:RO : YmS5bǺ v`])vOX3xHSibs:?k8ۙ>QBx+1 *+[Xp*@Z9%q . /qQTNBTnu-IxJ+&q/=N3#^0r# c8Hk;#- bamAe~]EMџv,CFk>* '6)p{30%M7ΦW^oȧ}$ފn3 SsڣB/o/+lq;{EUl{. ls_x+Đmbev%H#Cǩ`i[#\pc X Z,xARS)߻` 4(Z;x^}{yo)Vx:BnE8?_jz}p0h%^w=gcJƖX~ evŖ!ćWi1E%ݢvUk@ƣRB/*OYh3X _*vuthk (YZ<aR`m ΑQ"BUC /!O/7}I}F*X^' [/܍53E]2OF״GZ'I]6׬rV_466=@/{T7o_v^;^fMߢ4̅TegdUX-2qs1W ۧrd0<3U:\gkᴚ c:VJO;ø Tb GJ~>bzXc Nb1;ΤG( -;P^- v!:bzA4 2K©]t~8]L@%4j9 {Jne6K"JGw>aTH[ҊeK1+%o) &-\) Hʒc&b9& kt) >L=Lk œ 8\PaN%ʎ+f#w79ZEɤESJi_|5,3,,PYA͇ QJe4tKh9CWha&Q q/q>YG[ƻFxk<78rJe]Zt`^3uXC 7ʙlC>U!]"o``3Pdq}Yg Tt\bsh?̂USih_!E~4}2q|F! 3xhȗlZEbpXGJhm3?||zI`ư:,N+qll.ZڽN-' S])0N79a+)^gWV4pHgx)OcvuJ,+ hn=0 v=%yPZT`-**q a3+(u#mjg`ߗ;hJz"l CRõRm$T%h*edteU>thtTbu_ ]xMĎ %>8ngn+-q,jm5*D`zVh";e55?)hDEm~o&0K!pqhŘ4Pii{om?:ӗFxx&Ogxc]WM%sq1 -uK)xRC vdk4{5R(ZJN#)p-_vH*X\ )gơZ8;5\)R'H/nGYh#h8ąIٸx|@.%J,HZ6mFvGc5ٟ1B_3gub4޵%r| ÓP>.1D 5,Xz;2/Z?' >?b|%Ìs`#ݳ.' X3,ڴF It"%bpff2~6] ӕ27ўV9C/6ak8 |E"Xm%,RDs9Ϥ-gu9ƎyBw)BDhR"dhU87_gpGr}K= C>YA ]Ց_ly C8V"g:SXwBv8a's lmK+_W/FuFyz+IԻeH0 ;#nHVcKu`P Ǟfp62(?.bSlv_|LuW{SJrI*ϖqbSXXu%6 .IoK3jiG 5{O̸ܨ$g. d<Rt\>cZwGcFxLcS  tXZrUd>ZA4 ?Ԑ+;HxEZ>]e02G!(qݝ9w-0>1%8kUD&ɩtRakhڴZu̯qٴ:DK]'ךbXpq4!7QB>E Je[* Lȴbz_GO1$L."U`hxrF#LvU%55xO}kLr|yo tP=S jjꋆxXDqʆŗiwMAOR)j1>rC \p&"s)c6 \d;.WfzrmB*J$RƷ&fKo &S|zad7^z1V4Cl0S0bѝZ+qV*Vs]# JZ-1G8ӡ K'HzV'~-MӞm߽[(`wLE~WЄhC5nlE8LY{PSjm/̳Fn,09bH Λ*uSjZfg2ٶMPTH0#pxU Iڞl0׊ wt3nPV K5ߔ}J?ӮedݛKs?"FяQFO `Mbr%Rq$tjD3FѰ~a*.O `jS Ԍ86ʥWГe dyݢ 9{Qd7D| YT6B/RJTRPO 11ξ3s?g!6Qhy-v@r#jӤ@}c Q VfM|NA{8>IR9 K*[D)FO rk!ҽD_G%.!ϴ JDܣ5mOLd:ڳ`5ds9j, 6[me]^M`[EY5IJ3CeMa7rR?J bH^MϽBI/Ž:zf+c{ բtkQNj50loG7JlXJ;6Ujq9\NWc|4^^:p=9@~bz/#jn1Jxhzd_ lXa 67#^NiD ʕadˢ?JCΕRPr,~1tgc1*&_iixiaLKjG;qj ϯJlРHWf㰁M 2\"hlj" GȡȑU/+[,H6P9T \GωWNE~ʟd"^q,,^ҕ%l72&#мz~mHAraR 21͍4S36,a%7ekE*Lbߩ8 Q.NЈ'! aWk#1%O6ߪF*ɴVT܂ ,h~JXKɹMG6vlO#ѷR0hɯ,>н \`W (H2ٷRH,A&8!k ~%wˣߩs I_iM~w2O9Mȥ'itʥYI݁x/k:Z?Fg$PJzx9abl4|#M i6UMWKE7zknxKt(0a.-PaqnS^wqJ(BUp k8`%DŽ(%R/5PbAȐ8;ܙFhmv1tKl/dk|-ƬzyaYBCPH?P,nO C4{VUg OM<b3Lop0^p >F9^a1N1d=k)tSM4.p?$d(dcR}B2f?Დ3.\v}w7vlN{?:bsB.O`9Xx942Dß,k5:ݶ2{T:bk % |+D wo\ÇYv<񰯽-qS/1gFQYAW#g<{.8&ǖص"zGʈr q UOHk b{[#O*-B RO;ҦEUT.ʭ1O;"kj^Bhtw~y'eN6fxns8.Ii"Ơc1DU[dzg5bNgV(_#TEb0S9ZwsEF |밼 ;th-44P >2x~g :(!B`5n4M9[8 oA3 Zð[l2zdDh:&/ d)B% 1;98r.vxD74q_o1\p ,C9ST RGP8 59C_B+afbw 2zg)0F^?e]o _qqe#\{0&ʽtL zH_նGqW})7 fO3BswS`3,W-2|FDhFG2]}|of8\"zA<<2'm~I|{5 1F^) Bj wv &9~*YR CW*NUH#C[+)2#ڱ1SUtNR+:Ȝo&zנEÍV}̙l')` ͍o@ ?WL;dYE;4@\fvmS.K쒢=*5=:brW& uP@-5>ϕ~{%vԡ s,[bT#O $S_Og}S=ԣ19Vo?ꩆ?T#= ,^'ak#>_6j:ӛqt=})]*bffr_4jʮݍn*\ڻt>j$: IWa~Wਿ5-&i!C6-ViY$Їsi{0vR]%d͠_9@_o'>EK6eE5,Φ=\8HH09G\ܱ"4$W4 IGsITJm3:k>XƔc4"Gs8™:tZ D*\ס  "\U83*6oq4ڮJiwewݪxCgЮL+T(F5ξU@QLȝmQS fq1™^7_< |;,k  5zNy6+RYECQMZ|Lsqu=NS”d<¼TVn"lg-z5je]Ndž'%}hʑt ƒV*(x2NgaC%tËy=/TAS]G5cVPGxN21^,26 N-'e:fвtkrxCڮ{$=w. g#}iȔGDU\ c ԵI oȊHs5f[g4J3(IO҇IT6VՑw#AQ":hµX|B[s4xG.a/gtVՐ R`.qh'hutj& 9˗Ѽq6 F/=W Jx^#==ƀpbObv6\er K7v˗yzͦ$dmKtc$ C b6ѿ2V[1%Z1lH`̷Ka:w9J̽_#*gmlrvD7: VwP^lz0ξb+t-tLgXFYh}VpTV%~IPh"-`~ލ^@%_G}vYoh(:8 lܣ(eP$9NyHU*~߿\jN/[1QT@L.Q1VLQA@Q.|35sfwξ~]g9X_ә/׋K!$BMPbx9jzz=NP*,"R3=?MT;Joa>Z'HuyNP9}#>:\ը倂W!OۤqNurO^Gs8Hd uZF}Ӯ /'I^>A: mUZWp 8P>pc\fM-r*}ٝ~:lm4M\!3&̧FнlmJDUShv:M`zKQw/?1Cr gʔ0Ư_+j^a˾JNmw%HC: nҧEFʢ$괎FG : /%|TFW!۹X`(L6@Xo L[fVa4E.FCcيG4-fwȢz+yM2F#k@2^ e/M L E8N 'l'kmWkn\j ]n1Es:+Ic;?  MNP[yMp~jcO1>FdBNl$Vm!So*̟OO-V "YJ1)vpa<,` eƘ517J9LZ&ѽG |Ce! 6hD )Q0%H4n,-^&han4UrVwRRGH'ȈRn-phS}k)7rq`:ԗ&B9{(N`ζN8s'8 +xBob~Te4b:k^TB[ _o FJ$VtiN-MRZGB!Ix(04RCC;h!z.db[6`Xk6znEmo-BCf6^vJp‚q<-K5F;{f=SF{ĽT=(F;a<{J^ȑO/A4?Y!D2[O nTz}7~nF!.5>\"gm8fX&oOX+VHO^Ѭ4`=هc(]^MFYd1HnY|m0PJ2sT*0w)`_ fQIF9}=OG=SJw3C/xV|2]<?RtDY;!U5Mv2,AWKSߴI+8<0|,]{\O9z ]_Q҆$Z#i~Q8?Ӳ~ y5R#T%҇K/޶7.h4=E19?\QM~}m!Tm߭kt飃u03^H c>Jٟ~M tPE5(]n ,e&({:m#" !}" ڏ(QJryIy+>MSeCi\) eU;0U:T'ŵxVL-jq3(Y™Zl3JHV"eӒtҺr IxS 9(Pr@l  zKk|cKL,.%Ye;4*dN5_ AFQ\h3IIp#v1} &)U"b]oyZXPISIw# J RA*:rt=}z4eT!m( l{Ԑb}=)z҇dLyxY~`mQf"0<KQ|ʼ^Fˊ) T8Zt= 0}A\n~RFoKvC@;SX<ҫ_DSϷtw עn_+P@2 <.d IPqQßD%Dd8Y d%_ak\e Ÿ9ٯ&G+F,]*ShVC;k1s?>P!LQHџ۩m29omO36"4n)L{.ыΊ" _C\Pw;cO3tpG+GīP@11%Qkҥ3%E& KRk mAK(ڷ ~iz>- 2RZx:U/V͠) UDaH|h"t,"/)zD  kɐ1E0 fJ11CDU*Ӆ0(E'9)\G5C?ǶqWrmX7iWћQ D\`_mgd9w'pjXU`) ۨ2?_Lөscx]%}h2 ,sЕ|:%Bf4D.+%`) TN{2 )rw_,3+ޮմN;L 1f!avj a2jJ%֢o-Q'4V]NhJ,?iseީ2u5u4^5ªE,?ăp5Qy%Ram (ז(d9C"8?:d YGze}SSBǞPt}CBBەp0$Haox(&ۉ`5CqLΖ%ǒwLư=#ߠD9e=p702RZ t1%4g'4;*oH_B႕I1sm sYw;}r0Ja:rB~Gj:yG>;#`֫1V  C1z5쯠Wm*WFO(+ih't@sT*a?N|T!b prCjYX{N sKH,Pn2LEG4uKz@=$ϟ* j$O- \]Os2YaΤG(_ 㢙}#=ͤ,=3Ŋl8s' S `!!vG֛WS1B>z/:23K|p!^]ZhSdb24XT89VĜ2<.6SWZAhU ȻNFKrKehZZ.4jio#LK٧{0E dX(R^m6Kst8X]M7֝6z؛X1<ͤK5j]NFdtl;ELq‡Ȏ0wD v*%Co%*Q)f+5FekaC3]@Mօ4HI2v*-{ZϤRxw7J^6SM+}i!n.7H ҳ-"(k_ov\v=qKLbr}) yxfg){G6V +j..=8Xg5]VXt9-LpLF(5BC),a-]aplyhۦ‰J רp Dxn崩3} /T#4/c3Da!{eiҍjZ7FԓuuBm8ŬFسLq!>!nudyCGjZ /RwpWeX̐; %.Z7͡m!","r;aq/`or ;Q1U1 ETeٿ+Kz2=b,&oXX(PDwهкo Tx;:`OKltpY_Fd֭^ Cf|u*b\m }@ZXcɮ俰ƨ"4&kc~*X,SF)Fcrqxs]+%ǝL?`/%j8&Û52]nJj4ڇ&=J]ϥKHo.dzP p.h 2D?A4 JpD=ޡ%M` WbPS #0UKR {ا|%>QcT5naObC5bY <fFh"{aSM1ԥPv.Nie-$_r>#Aq6`o91G%*BiLFr{t%FVdx;C5TL-^y%EO ׇ(Cl2A3eCkxFVgY!g(cm``/)vÒYI}@'=c氛 S8pA#K dVx=n: 0L)CôҬà &`636G*2U1 [uw5r&^4B͟VƕaM?s~`#jf]C~WT*Qe 1dj.b*OVYWH#nǠ: .$Gu^HOG{{bLC,̗FFSWA=:Aa;&\!ܻ- a`9*tTE -H%;ӷ-(YbpY [E&g)vp_$.bЈOoa=}7v738(laFGeo,;hÄ" $F[`>3Ya GSmtɠzU79x,c+Gp;[(B SO()YRcL E$ث/“b\ ý<Ycofb7+-p7 | dav,u˻}3HhחQ^gi״h[$vq/X\-S~r5v D^H'{B3=fìvhc ;1Ě8Lr5%'wT4p4.XscKyT@_X£[*q5PijFP &f#n,PAѣ2,b9WOӒC9Urd̔2s\;D.E7ߤ0)@ )AmqzxaU1/Us:)߮ho귏NG14Lpk"P~#~:`6UShİ+&(a*sc&'_`X軝[8,J 6Q ) i+WZ΀(>~ḻ-FbXg)FW_5>?KI)2_G3zk.}$61ko , keá%=6DÕVvrӔ"꿵}˩`-^J֮ӳju GjfڀCU 4Q+S uS>SXt^פU"ܐ P}b,e>(^5e`3 ^Wmac/䠰O3,^8-6G) p T^i#ӛ_5NɇNۈb&z w_#Ϻ|C3xvQL&%5Ϫ-D1dїL;2U)DI-&Za#\γvs}<E:~Ӡiz"pa91n9Yl?].So4(uxk&W>P_cD$[-mE=]R!D""Oi ΑB`W!v׊'DC"Ž6(p'.̾9.'1# 'E{6{SpY3iMM.=K1M4OM?W4_ v6MwhwAR 5QkXׂx,X0=lbX#x{ ޳l-!¦|_oQ]$W*0*Z -%/0c%o0*O^:rhR"ƨ c+_~V0-;'F}"`)az킣b(b1X:N`K!l_O[i\T !b>Gr1;!O0./IQb?dum(U7ѧu4L;c+\%8M&1nJ[@_d[{b ȵW5||"~ZⓋ3B}?k:(Be:L#Pi|/Ǵ8TkLNeS z\v[Dͯ4>|" 0iX&PZ70nvCC7ŽK1EQ*D]W".*9p5և*sUBHT^x7L<ByKhBʚ[Djh;l^BXg6 ubz@l!^ӖC]2)_*1ڡ{'.' 9`jo 6r%[ЌЪaPlwsCR31%Q4ugh  9ȱ0îQpxpԕ<(A&%:Iz5H}!O9V9kz#6ӳy4C{FA7voĈFw fuc+(1ۉОa\u  xHds13m(O3<#1>41T2g]$MnmdBzz\e4r&ֵU,{.C6q9UM캇&ψB ^A1 d^j!^m ú6ǝ&g'W0l%FƜ=xAr0kI瓔Ra9 I-X)(Tr\!~w1ZxgAX:eSԡ#eEz667@+x nbS*KHGbo r%{fa/~n֏w8rn6]Ugfh!GN1! i6$a!no-(`W'|%NʰX@!#PjfX5(Wd(N>IoVŐLJ,}4d8u"\`|;l6f7!%LTatm1z  1ґ5nܿ`n,X2sfⷞ>х-KIa#:UM+/olg7?=ܖ&90Ag)bYfQ*JJhٿfZ`]zl}}x䎬ylYVˁ`(.x0[K1hS#AJg|~K[}8Np݇9Hr~,Q[lnƇeƨ+$9A#iX;]Ti>õW;S$4PN`[:6YR!p>1b9mnV"=HOK:~u蠊S\kur{ё.I2_~)ejuA2 =S/-xx=4K,KoӖcdc朣Si$TKVRk}qU1\TeZM.!o$Lg{a \ q"cUgi>Fhgu1`ju$ФNo.$,(:`..$qc\!aOb58`g?:ΉV6cp!m=Q+F;j {j Um;7u mRO[ߵP& 42La |['”V1Bˋ $EXx_YChۮ8.wr~ZP7bSAYBst6z#- %…v K!af ]6G^S=*3~D*>}F֋шh3g#JM# "2Cl:6r'B'3 U1nB|y ^,apMe!< z^V6ɭxy5ӲU J-M@4yA!eh#i}x*]Í ,ĂpwWqPQc v0 3\"z衃JcxZ@TM;4M~yfӛAtid%QIE䗥9xf l9c aQ~oY|=_޺M74No լJ# _2uHFi}6A|M];^.wǺtށFRS,;B7gP\ZQN:ԁM#TXq W=6IC>.%pIUx4H-طl\-`:S.S9(b) M,dzI[1%ͱh)w$es]jcFz53._zF{Ӗ u5S4{eژ;\u1m)^s TQfx7 .[C xxkb |8LVR@8_.jRȻKaG-laBdXRgcji7C )G*y-f=-5Xb/Vs`281;_ : KFC޼ OթW~L9Y$Ϧt߰6&7KZf>N_o4 :^Yg.up5'o(`)ϤN-$sh0- E4c#%s64Lz5ЊR+JK.\=oЫȰҝ:ȣi]/MTsK nuoZ5ar.R,loa3R6x(́-|(X$FkLb(B{[yakTeߘ26ؐ2 +cI3+k=tSF7G:':hzCTWCba⍆}l/iObZ&on6#Hkarc-.ai lQ>\65 qH%iL_kѧ6S$ɛiTe}K'Ŧ4myL"i8-:a>;N,AǸxZ,aUm¶цH"}h)ۨv^6#hZ!7(18R!I$|NYl~_D7җgEtn ߿Hs܎k*{R-R{ i|.uȦvt,E$ъOn^4`C>Mgd6&_H[Iw)35U鞦P@f5dP$& ќj M xh{OfkrL6 0yC3qk*ڒHS١ :҃-=cC=N5dˡuHz\7Ån'Q^L&'RQC^Ud""fK>AkU]Zm 4Mۚ ߍ.oL<vְmra՝tX.mw k ؠ()!軞;8` `Zל,n餁fZuLZ◇|څxD8j)rM+#g5ɋ _@X%NRPEƁb*R9G]%*!O n[,`3F~\d`e DQǑIS~#q[uHgz1.h8kvi/Gƅga(RvG8s)Q#4 ,WsF8 䐊s?Ly"IW ;] ?l.@NI| à^~X4F#V/[Ԯg2%NgrG%]:>`ꂻpY`/e&.ׁJ3%-skPP>j:":ƀt ^֝+p\5?|/tO|d#k̫1@I *jMƆ6騋бMٴpRwjr=gڔ;Hs>5og *s]?r~JlS O,K9%EȥYmɮ# 'Wj5Ȓm%|Y<1.J)Y2&`%}SV%P=Oym- 9Ǝ D#pqvlƆ1:!V_s5\$a :.dG?KƆ>ݍ1ܩMFS2%B2Tܞb ^4Œ˾cGK"~^tZdW9G7a<BK&OovGV޽=QT[rv:(懓bNy{dB~RlQf4_lEQDUP(τ"'dysZE0Ffj[,jѼN;mhi.:vMWw_Ysm;GƷp#8S?7~+pd#c.1šULլU-;ZǀyJnp+9 dCӦǻkjq6*f洩#b^D̠52n֊x)Qʀ:8tu͑T0Z \ytXfCljvD2ݞ{Hq=;o p!7RS3m52KqiC0E ͈C$)DF_Kn-%-RV4#Uv|hKġDd1^4^$(?A+螰#aM}WiPNg`]5R⡌~kNÌb)AwGqC [)*+ r@!C &.DzFu,<ʃNz#iNFއlp\׎zMHZ#mx~5ˆkRUR0h?g.q0}ع;n<ʧ=\L<]ܚ#dMV(vΔ 9% ֪Bɂ9J!+'xbE[EO+זr#ߤZ,EJ%(鑯aW:tRd' -׍2龚:lg];0l+۳i#gvRSfMZ F͌tRA'S)oB/)wivFY8̂3l-8ڌ+Pu+6(@ł|ͯƦlՊeo ϶vφD.G:fb 8=u_ݶ|\0嶘+ZdQS\,Nfu CNt+óV#VMǭ{H(}9OX#~k\zv.rhGk)[=IInpɁ^B'.W;/ЖZ={YPE 23t55|fr@o<'d{+6w^`*JR.P.#L{TW4iʁ'QJ5U݋TQɱvz,30gX3#w?yRq֮\ўzR{:(iXz \sw;8饐 -lmXq޶2c(AȜ4խƅ_Y P4|u8<=ehT?x7ha<$P ~>oooѻeOBkhUԳW[ #{8BFK"\QU`Y *-i?Cv|go45NاZ*(+Er sVջdE̞SZs/Y-S:Tά&& z~0ARpތVHkƜUBuS5_SK]-E8NI5_ӰH֚gb2d9p^=wڙ5N ]HQ'/YɣԼPɶZ3}))vT7?ԗym!+Yy8kQ7 r~R}H g[p̒" `73KQ"Cĵ*Pmߘ|- ź7p~]h=ioDs{\|B}d^]c[-T,MBXŊUcb'-RpQ?So2S' 멊94LVsv5H+Fxt`.҉=8P4ÙA3]3י \o1vd5vq DuYK=CJ8+eC d )3XQQiFiW̾Y): FabyAұ41s#:& '"Z!9pk>zH/GT^ ;odYǦKF͕k4\EC?VsRA^͒b,;>bW,>tOF\_Wy}N|K)WsyQbTTB4s̹"H;TtZv/5pe'5*=B1JnئF:w̱W~wbhgnո39WOe:.UXWL"PΓM嵁[{TGX#'бU{{n3c<<{N[^Bl-vKs9jφh8(I l\COk[E9+V8r^K\9wą7ؚ~iy=zᬆZSfB*bh?N0)S?-ǟA,MFh{Ob`/z4 C&$1)?hfߵRn3 2q*9(D _k;f|k7}f_ȈC8>':W5PQgߞJ^TqX >+ϑ S/ů5Ufɦ]sVA,,bkDf^ŝ6)BtP!Wl%=jL3ώ 4̈T{K_`c˚A'k7Jn֍IlabO Yh0Y:^^Fzmi[[XSW!ڌ-%aZ^>1kl,̖ckxWJ'e1*(dqFom]}?]~VϙXƻ^š #g:v=Ȥ%v/7AH!_Ga[窐uaO2HZ *_ I(#uzOaAs}ĕPEDxh4Gƹ(XF셰!8u>ZmrfB1V3|pW6ȒWeMj煡^8F܋GgE.捩ABɸo;hzJ.(]Q}MlGA^ nnkjȦvt3 3ybk9#䵆JF'my137:S^܍gM=l둞K kfd#>oj=uwEJBDuޒ {]&ߐ%f5Rɿ։9%ԓ$L51{z-;2춆ёij7\iٝ厔fسڙ?99o'FoMF>X.ۋ+bIE4 I XK,׏.Y%&9^[c K[X"݂,9ln &AKƘ_ѳ'MM ȆTn|cW 즒Vs+iWؕbo!\.YgڗQ R񑓜_K`VF6u' Qp8앒J60b {0u3}]ir.5ޞ4:_Ŏ *50%H{TDBp='Ld 1"6k^;{c(fe8͌υ6%2 ˮ'ku.m}ܻ}k?AV97?$lo:"Vo$?=+󾶝 D+Z*t Ȁnp.IJ*bG8闃m(+ѱlWs_N[7ä1{랂BiJ1G7͇m|Կq^U\N*eXs@ڦ\9#b"tPP)@D8 Oͷtaў;:rx3_ra[.|qō99N|ꩶ|vy,ua|XcD, -!o-[x(pkg",oײ=I mdmL~rOz؅=F83ƍM,4̎h.T&arno2IAZv =1c[zTTo'0c|5eӍ8_iZt-|B=h!TQˊjC.~5/„~ex|qPa >M[xx۰s@yg}e>}y͒h(׮WQ25miɅSesQ]zfpV1Y;GlYҁ%VYpgLd SĢ xS6\`ΟN€/X-.c%Pr*Ezf Xl[`';w_Fb͔1-Ҏ^||]"Ν{<' u(Zo$cɱ78$ !,kpVc9 _OQymd|}_A˺j:5g1^F.Ű^ݢsq|zt~ZZ{ѻEر[,öw!/Gc_4臺O_Vmx3K5;3 kw0.* rhh#9n7u7vA?>reIg(,wDD% QAyKCud\?7pl]c)) B4Fg֌9ץLl$6R^y#aEKhq' q_֪J*alU]0v z|ϻ8#+? LF~m}-6q?P\.dk9~ ``ʒ wH_wxDm=+9%{@fKj13 eW*.ۍ<cMMMQΝ<]D f?qNܭy~+զ|$OF?f E}6nŁ\!(I̭_@pvLCfgXC'U|A B gA~ CǠSU n0Ȟ…ݍ_\+wX{ȕK':1ߙ6tf0[K83NLqNş۵Lwq랙9xSUJ1G&mGTX <#0pn5/rZUr S?/wΖ*GL30(y$)@2?&czڧt~ W9LnDS^z.N'ro͊",;]"z)30:(OotT&^ffcJX1n[O*Ldd%/EC-ّ~0rz9Rcx( x? {졤N#4ԳE2r->^F sWrvTڼaQfoocl7SWET*r(Z`܉V1 ֜GZqQR40{ 6|@,y?ӇrT$ׯB%*pd!z3Y}N lb<ГT7qOF C5oTp^ŒV\nS0`n,.9gu9fzx+].jskJ9e2e=F\HޘiI)+#^nѶw3,#1W)ZW (݄׹ڡ 퉞xo1,2Oثm{9˽o;]]7ƕ.L&)o'aL!ü%b%e㸙g-/ݴ:fE8Qv3pYb+e'2…ow*#?L¿və'c*r..ex"&$c{0<6GR!Cl8&`ƥ:~gY_F _{{bA jKIU?Yo&k=/ҍk93Ya45\1Rc0%2!s̩kUUwa0܋Oze9>N2gS1G= 43).+Bb}?m5ΖrZ٭s|6-͇-/6rNb ^|b{d 3At8AoPV6xGcX@7-xtܽ ӅT*C]bf% .`L8ʘnl˕ɇ] n&`):7;Qn9.GG|Eǹgl +^\7N?ŀ'd)/( OP>); Ѩ9ERzSs! +i󧞎ysiTE{!aoB}ĖOP<0)u~j^6#HvsJ1g,3s^evliv3愆kxQ5zn3|*Ɣ Ɯ=/~S\h!!9+.J㞊mckdT9ӝĜLR* 11Oúz[ ĵ866El76ybgN`M˽&Wx,cְ%aVWiHW<߰s{`y?æQe&L<ɍw{7&vu'K)BVQ?] 5<5^Ce9 F)8^bv=0~%.p1`}|oQ`IB)^s~D̟Z|mdsEϴ\;qmx2AˊRn3&f_[8p*veہs,o_zȂ.ߊsgəjRS92*g87]ȧ{,٢ڜ. [ג򫙄k }ԌW\ m'R' Dcӑi/|P >7&cS溟F4},b7cJɍxiG\=9^"zOеL[ů-OQ*gSr6k>qsI#?ry7=%#Os_q[zLNƖ,]-edӎ#EFE37;a~:$ء 2pg-nMI^t?ct~'Qϖ䛼kom?={kPߤX?c`k!ΒfAfr>+] Wݯi_Uajv-h@  qM@hY b1zV.z o۔*xꗚ>Y-w0tlcԼ3'zػ5w5ؒ篗L|Gsо~3d.>4ڷ$;su)OEP \2D{gQ[ #1'tʂ.GA߰WTU'!-f"arJ}ѻͩ_- W\cau`JP񧌂2:xmy.{◁sgywm<+ 1zI_#֜}M^2naMK$_vģ[a$JzT̜~SL,jaV_l6-SkIE^*:0~^O,EP%b+uӎoFe{Om;Ȋ'LF+p":9=3KCěKo00kWQk~{inÖMe:hfIvr-_2mUԆ^H}Xީ.axc}-۾7 U^Ur^8hUNL}3F0/nh=(81zEzX5y ^&c'3Vjhmij|sX愎}.[S=_msiδ=`*z.RKxgAu3z宐Bf]wHC+z6kܹ a0,@87xg^!4>xmhhßm棞 kzSs16$[+cA">#wҡ>Gi}mwzdS^BgLǸH b˵l\aZȟx2 ;aP;^_uDl G80>x(-3lvԕnفC?p-;m;[Z΍ٳ=P㑂2d#}# b/+X_ox~=ķjz[ / b 3S [bmP?K&j*Gg݂WJQe|`#s]2Gz;g>XwX!d7ly Q2,RyvL$gBQ@lQX*@*ON'7 lXg/\8>gbdLZbbWKz ;*-G!%("}7Id^[QO%sM5VGFѽ ?d"9-Ki |-D9鈵Û`uI"^<(@_aɘ< ^!Wt2\\;ι]Yٍ%.ʃ<Ɠ#]Ya/U&x)fHR.< WiObͦԂ#{^VEhsLzA1]w |?8,Wu1XZ_؜qv% ]b2hܖ jgfqӥ:LqF _]@hn&Sp 2h9]ɄtZ\ ex6ZO Ť 83,2hYc|Xgm:|_(.?{N"ѳq2u~> FX>t'uX%X3'b>m}BƷ2ሀi'!֖#pdv)GL<p6m7cgVTo3S 6V6|pw^Ktg^L?z0$׃V{2'CBCDb40qwْKdI7<HY4m[藰R#Egt.ø{5'Bj[+XK[v!x#A ,ln÷X0ʁoXS;$EZ)?E%w 5ph[K6ؼ8 u{bCnc!} ~,[!5< __DW`tGm<9I/OPNĀޡp⛈o'onW"ZoY/z tiFkZo_:kw|IJ -;x簌gyc)y)#%JDur>ء`M L̂Xx.W8˫ q vyn8 N[Ӫ܉'_Oz.9uyI=эu۲$%߼01m- ~jB6K-6d͘PSR/m?L9 fܬ8;9u,V"psۚMUV3ʂn[r%߉tMBk:v]:-mg0dcXk[%<3.439߿bejN62n0p} llU\9QR<"drfdOCrYس ld>G8; ѧcE}H 3i66--wV\d85jiYh23DiLhZat o{Somi/wTۈP=Pƚzک\/teK&v;v*'.-rb; e֖nk؂k||xKw9Z}@zϰME,*ĄjIg .v͡ 07>]?>*x`{Ŭ ovu~ZX!o╕Vرok?p#è(oڟQv&}W΁X<7 6=Oav%+!_~節J=5% N2ZG(XV˂Z8ׅӔ4j }MǼ[XX'IwC͍8\^?Jt.2ϖws3hN(,%OX]nY}ʊ1a,Z6 ww'{ ]www9uww{O -R{q3?g3\k`mB疐ls Aɕ(=)Bm@5I+v ;VOtGhLX~bwvv>ŏu>4 fRI|ԉe m-v. |/š0_~c3҈&48jMh&|^<#s`RW`+;7_tp/K˱+9f3^Rb^:Jŕοql2}t6Ǜpe iߒs,,yaЁsSK†Mlvɒn'Mx'I\iTd}mD0s4?9 D61oY\;vtw`d;{g]g73P”-vNys7>ubVOQ^ ^5pҰ2 d~}al #/sbj[廚E^J8D)'k}=(t:\EiD}%z|#(e-Zʌ3bJnO imߢۧMIyt nx2x>A,zE?{Rw9#i;k^xr/V>;s ;ok(SbB~Wô9g)0:kip<Zt6cto z0UKޜjɭwykvܚYq+Jڀ]a&rfX4OZܮ_הAj`fXka> 䅦Tq9^ZÿB\5YOoTԹjNU#agNB^eڬ(fdcᯩ"N吇52{^媣(9k^#hr!N5 gcOqVɖc^;ҫKJvmXcYh3\)KP[+hPεZYՌBx&ۑN]݋%+G{3taF4kU 9(Yf g3``I eb22e=K~1qzL9&]ۮO5}z>9yIm}|*J|K| scAk^Xӫ9 1*y61ڥc{5Z 5)z,5_ сN9'+|93J$x<naL/@: $G&ͩxlhND"Թs Z@l aZabL/߂>]VsK1}x\>!;V>.M yuP7?@ [RJϙC6ӯt, M?͈^Qns|8r7ͥdӹJ;IS6Y͗C=9_ǝk\{.s#l3Dm%*xZU|yR0%wa/FOFP ܛk+yK {l9ZiR Ni՗mș0K%2nk _N)du'8&sNx(;27 X>οSV%xoe˄7`A#{)r.X>?eqC*GbϞ(>c$&FqpV"C͵*?B~i D74:?b/X_1i&deCS鈺Y㺀x&a鶚.h:_3>'Oǖ?m PDقROѧ2Țuo]8%\x[TkQAj9+8~.􃄢VRϐqA&:KE ?S-W9|W2Y.Awjoˬn"gbo8;$Z3ؾN*fC|{~ >A?#qocF3wѪ?=c kqLn/jqGbN4-!83=QQi˅ ]_N1Fq2K+V>L4S&)QsDrh/_@_2T·b+ehG9i)[.C@q&aSX-wެ%zegXu4k ySd"jc< MS 5B1ȷ?fPUmBէk0Pa*q$ u[ڱq'm'2"Q˜_!+\wAS3 ^k,ngѬ)zkgXV+_HU\v1eSsެ#c1 ?<m%QVǾ Y8yIA?=W {p~ LTT!޲aiQ6& ]|ћi[[x0Ԏ6{pr_rR)+%x,OTyXp ~Xp@٫͐h.Re+>($#Gνjmxq |3{KH%ڟyFט+k5C&Rì.4;SѶgjyzO2ž8Šxޞ ^CtX'3d1s NnGŗc߈T[FSoy.&Gat:e0-n突i{yhv<%-;O\,g"Mޣ< @ۃ˲ l+qȋ>K1B;8OϏYaΑ+Utz)*NSsóʗ-_Qol/gNLcGr .ctGO^/EKV ]y#MlLZ?*d? Z )^\~8u?O1X@E\EB|^ kKұ`5&rՉfK!eVMFJj&rn|Sgi]t\g_AZM"aP4| )Gm #\ƆDљ3xІZYK}V"lqf"teQ tժ#La:%+,}Ut8ڵgu8t9(rOOe%~rje\cB&Zt?WolhFc \ *(?#?%bi4=+R:`UͧLv'6gvW;lm]xh qϬ1s4_`(*@ȖhwMjxο%:4r@ԣSV #כzX¦>uX|πFO3c879pm7>I;t\7MT3*v`hyc"B9[9z4*g->yr|D7ULΐF? z7&ϟՍgRSOiyMTބ72v.{A7ek8?l^~\=^h#Mn֏dYo+~z/Ӎ; [^rJc=Rd=#ܕ 41Н&\n=G]nOLi*7>'#|KԈ^aHOg]IhcpForb!)imlH, ZbN LE{+j^+- 6ay xG#2#,yR\ϕl9+URIA`vqO;?*흚q*ڇ ElأI4f|w5wopH KUԟӅ~ܟsb9A1# zf$>Gɇuq5WFhr_î ت!cq]#.?;#oB T'h|7WsN`ҋ1JOv,|2e:-A/R) `swGo4wlbJw+]_[1;ESCiHc=i#~ު?eB/ LD)<{ς_rݚ:[qehe/#yjߏ֏Oh9([>w8u" N0I<c[,tۥ`*=ߋulS.[ ]~\CkęN*JyFA?s򀎂r4b5kO.ueaC~3dgNɭJqsGמ*Vő2*aOvOsE#ܜx#}=7Gg0U;G^z>c(DM?'.{x_8W|jg{UBSҥm?@0x#f *ٌ*ޮd'-\[. EjoDW?ǹ\#]Ek}'WP3" N'? #L\[i;m4ҙg97'Z-ax|jY>lڛ6E }(ҕݪ|=-;R=嫒g2x,E=3_~K6a=Ch,yEvբ \ E{+XOPMr1m1 ~|.(<8 bTqH"5,T!j̕Mhɏ_+(q bY;KÇb^AYrZlQDbU5# {etUiĜqуd"òsQ76)wNJx"JĬv> +\-F>|֋FOP쉚o )K3%|=ʹ븜' żݛłMh)F0ؓe^p[un6΍5LfEC_sol#jd_i8wӱ,עxm*Wt, [f|GȊ=Bq:Ņ`P_֐㊪L- /#pYMŞHX(\78$Uhxq7w'_v'JkkG {(9]BOW}}3gnkƨi *zHnF<";&-yMPnoŔePUI7֢ -rqjR ld aCx]bv"z{msTLT%ů/fb(a8 /gnrD,wz32̓3'd1mTr;K93ޞImy=ԔD6 K38>ks.gT=αa=ZȖ_]&1 z?qD o1on70|:tj_/ص|WJ|II.^HSo0Gh4.:lGc4#m"ˍyk~ *iU̍*Y(BZZحJoSr^58F۽\"E2-ӫ҉%lɃz{rˊjP;;F&0.Q΅H[OL(wdp3gʋKNyS+6BrNUrKޯ̈́3}ԗ_M].fOFTzE(&ys ^ËVڕr%q[.7fua|]aT:u"NEq}/Em{Vi8_L>,f=2_ <=F9h#p뛅6yH(ÇҚ~>|6A<3d OL~3NKVk? /9Gɶ*LXsLE=6~<fŭ90}3g\vf9m6W&ݧж8&~ b4|5Ԍۦ[R ^mmxf#ׅy'Ń,!]e5ZP蚄cJ V)6,Qva j*t=b:{Us0}{4ŋ95H^ܜö]`oy v3֜%`+(^bp9=ƭa\9oɫ1w#/ >@˯$RT-X<2b 9zTrzUl=V=q{s8JXNB~z?|m|2DimPl%DI % {MTl} }ۙ]q -LJϘ5[̩lu3p`@*/L _GHʻ/ MRa=9iYt/2P7}y([CEƛ8Kn1&, $U>FFqkP~ ΡSQ0)h1ûd)2u-+B؛DOl}~]k.їgXMCynʟUj55c -칉/5?@{ :T%w1金׆ɘO.h67 au:LcF)dj{b6tG: G!h Tt3`g |21s =)9$~ǰ`[u^[/F՜kb@ݗ(P%ћӄ+zѨ뚉yFɒw9>T-a]F[zswjvQ֖^ٳY+v秫n\4ݕ#rd}j64aǃ|ڔU: Ym~<ٺ7Jr˜ ^荗P?=]Gi[ -jT)3܄{ÊG8ﳂ}nѳ|pY G|RrI\ރo;s}o/6]95֩sUÎ'hD,@luؔsyyJDN5dp z)φfX$l 5!_Fbt9=ٿ@EZ쌁:A[ŋx×c c8M8[2RZUxo淞<;KЩ^ƃ~{TǓY$<ޝ>[Sk.ΩB }uedC՜ZͮxKCӿ%7ex 7h#PmOig'qZkʵ6_ŭ #G?TK,㊞Eh2F[Bb?oz՛#d><]=y; br''kz\iM)ּhl̓Om0E,%:7 qpD5,bZ; 1M  vȼhWo AHn:bvaK'^=cAѓsl?6pLpe9 U"c*x&p w7V<@VUܗ(';پLRRtPoY:3T NסELޫ˔ |1ј׻*|X æ)8`МW6{ů0_U|BxDHČaP4`g>&0uɶa ̖1}*Aa~*g2\CCoqd Z`3ޭc[^}mEe_U|לU6<8kqKGo&$(H_E[ ~2 (4|NV\ws 2*zy_x}ӑR_uh6Z0\cƋ\B³E2.PF#pF.z땝,IkxeyGjfoQr$tbS%%g*08QU֪BuKm֢O-#hSRieDATbO85:{>@E]hu{#*61?л1| F}(dͽ/H6NMrzgʹi/˙(QҼ/K!JfXH m 7+0p6=㇩`Al|ӄݫy9^a[.ykU٦1oդqlO`:<4xۮ_W(.c +Uf<,t禎yVW[͇!Y.:RP)`ZQ\.:$gHO:F2q΃ul?b] N)G[^ V◺Ud}h._?beE(~bVbw`17f?H'd3K|?䶌sG8_SR:,qD_._HfJǛWCWs*.cXH& 49Y(;hEuգ<)d l7srl__McmT}+&Wbv2D]xI0Xs* b]6 hɿ#^9%0x= wGt1@ Å|tqfp#)[؇%ߤ<fr}/tAwbғ}9S?ZBmg_4wcf@G~5wvgbɝ24٪E ].ϝYɊc[15Sjɦu땊e;:;jOCqfQ`|s!iU -=ϗw6Hؓu`$!@% C8E ۭicI}^2e)\F 6*<(@Km>* ץ{)JDڃo8oFx53܋>X&mY$AB&59kGh+-8l7~.labz_D $rWoVK<8q;;vb.e>)ncbjzo N(EW kKkw1: P0/Eߘ aזkkP# אn\1zzbT'8dNNƋXe79T*cvw7ag}> bN5ipޜ+.6{>!wCƠNR, Rr 1?Dscno*Áj[iIyط6m$rO o!/Mnp@x9˭҆`%1f4T1yx3EeʈM|Qdy2f=܋9 zr[Kkftf'^_*B/÷=8%Ҋ_/Z"[gPu‡?G,|RÇ׀tamZcSۋ 1'G )݀gck*jb%8$ґKS=-D\SY'9:D 8 jcCF5[ ƵC}+cک Q0;<}r9/Хhȥj.@9CB萎">-{>y\̀Ey^xhLǖisJ|MÌ,H]#.k[O2wk46\^?<,ōMo|S|>=qFS$/t(k[Qq7uiqPmTZ%njE)֏@ WJh_4ό;~ضB]!.0Z^w8Ϗ(fu]ivJ< tA 2gjV;R/Cl/Rp2,}+ܦ*3צ8@ǘhz֣8 3`o>2:Y -i"x9a_\Oʼnv.) P#Qq|toL'9޼–Vt8{ 1!1I-؂qZ_ \܄xT qkT.Zg#*FQpn}N}PwU ssߖ|\_8u]gH:Q,c>o]4L5Zt/'"{qgm.kS\YO01G`K)uJuI6:य़){:qwi&٫KHXK"t8/!Y%8 LL Gηc(*㪀@=;~ 0ݠF?hQ#mrsVZ;VA+: gѢk2oK'Vu*K"r#P2iyя=4l]z=5'pE%?xI#ē^WU:2kc.vzl#xq͟pB7rZ- ԚuE`ЊzOn`͹ğw'+χn-n3 -eܗ&OMpԬp_13S&AE|ĄU. '.7M-]}F0`}#ΐ16fBj\ާ =$3I?~W=. \0 /YM5xlRSh{6˭ps8tfc-ev>ZhZWԆtY>vljNTLi~J f@Ro%gw4R}h"[:spnvEXlPLT)AD`Cssc1W,_(%uXoȉnчH8c7DRa35BDl/M~Y\)S"7'j󵤶k8nYss:scSnmy9bpI1'-͹Ґt{*7\{yXٙ8<w`UTN|sOtitux”pmKySUf,:a;S]8q/MTe*yk|F_=mH)\0̚3n'5R#b^*>Ah9_(r}^`)H^F}h/2xK~q_n\}mu9/P׈DB\2Uic`@g8]WB ӣye~t 8h7 o6C E2uG7Cmy}pMn+8r g Gԕz=MٵÚTc "g]G퇉'fu蒹&p*tbwt 8)7bp'^=y /{zz3U_mfHS]ܹx}L ٓc]@E'afH٭(\݁b+vaw`؊tYs^g;Xy{_3 OLR/u' F>=ÁOiYifܾȈE+Kyгx6U5l#pgTXU:,O;EZ( :_&Ɏkb UxsSqf'`6 -u˘*?ktF<Ⱦ ݘzHŻ <ׇg };3:Dul2,Cahxt;N(.,u9':AVXp-٨էpN.ٰm ZJ6dn?%Ag;3cq>WǥS+>=!<"9h1kjIŸ?&bdS|yė|Sj.۝mZ0B6& 5Ӂ^_iiOd͟>/q}R`s/.kP[Way ct!a1/dL.[7Sw nd;|ss;t6_o5[߰2.QJni^Ԧ7?߿^# xmOڰa'pr;/yҭ;B %K]ԹUPguv,yk *'>E P۔kh3w~7^/ leW<\T'vŠ39p8slkIYKա[wCF(&OfUJzQFQ_m8߻g1z`\?l^L tQJXo<8 6T"Q߈KLjC{lٷӼAݙ?ߖG0;5q(^3.aʞ#:r uF_]SAV½s-a4Lǁ1\ޜud̞Wfq<ݝi\|^*H󧏕 kz&U&{i^$ljA]{9:|D=^ń[Ҍ9_J}dt=DN7)՗.*~h@ylӽuiW1"_Jyh=Q(Nm^X2 Mnʲg夏.6MWaG˰W|/P; &zKٿpu/`PQ*>zqRBѯpa1r[8U7^1IJ󧏕 k;] M˄u9!(V[1q 6SKʨj.w50c|0ŨA~=vl߳hSE>lƍO\lAdּ*م;L+~Av#ט43x9{ ng]Ș TC2܇V۰|A8FG0n3Q{Bw6kW|h7CGkldb@bGǻ0/ m`)F͟>NohIJ\R#A+1G="_,`k~yڐ*嗶3qE1~УSSv)ܞշ eX|5֥-D7Mk z?_nd f7C4&Ü^;͆7qaxam310_]6Qvvk&DIGqqZ!{?'az+;[6cOAݾQu$K)8X:2b2Lw`+2{OtYR/GQr=v/_o^*GrIk Wߜ=T!\5aQ9 #M%F06NbV1}󡇜Nrds?џm˟<@sp9 #B=z7![^ܽ8vOUT2*'!*9BǨL\_C|0׮ְH{'P7u6#7>῭ȷ`vm#K}Dtt8®k>`}N NヅM8YFedFMǏ_waj\nzX8*HJ,0&X3-Y2i{s:cFeƋ-oJ6]f䢰gjt˘9?bX8\vQ8rP!-k%uCJi'i҂ 8rCn9])֜jg'>SkSHέf`ͅ;8Ϻrtƒ]eP*@| M)8(?b2'W!bWdi,\a{h',. \47B=?9o-ϲ{sMVl8ߒ!LYdID᭾1Tp~!kO~ZWEwT?4[l[HʼnWRNs:7h޸^OI'u(/.$rcBFx y 81cְlO1ktMjGӐ*Bp}aIy1dž,\ggìyӪ3~ՌTr<5b^}]aIzQW)y}5L3N͟lU|4JGjՐF#VfG><>> 'bӋXz%&| ;V\UjÓ_Figء'&2N6f cMxm&<؈ŀ/VT4~/q{2f }Eb>A4o_EK:+qX,])i,;p_@/}N=gBbphIy4WE7)U pe%^X]qӔc,{},{ / Ձ4xyk" ,RY8yԸ>jip SHӦHw\+& 6)i]Jy+՞τݏ2 '5WqazŌ/0m\ҿVe1 KhT\FG"` E,KGTL;)hxN.Omw&6@-LsJ3r^d`RU`G:o,[vlohoіN]CZꍂ}Rvj4Ѽ:6C&aΩhSNh:mn Yb?C?Y,{N ~w'qe:MґQ&                                                                                       vfF(d@mf>mC=Z[o w`pAZhݫrVWR$,͵}J|vͼf}`Eyा+5-h(5ʄJl !+ZsKk:wW!ꔠ};ۍߥ-*?1Pgr2^{H}@܈l9q :JQ^ӯ4Z9k#DA_cRQsǶx[ G߿Hsw_z{De`9tCm{`ʬ,4O_1^S?ˊVD{ʡ)B;nInPchҙ9/P>pEwKhZ +3iG 8h ;ҢmT!jql JA GhZ[e> Sڗkj,֘ axLy0Th h\%]#RQNp1sx+nsu+Τ"_^!%(ie?.mHLx1D-tm 1ztਅV7]8h=7e|Jx|.8a*‘JݵޒW_Q[rJot<9-}u4FfqOwASN`S j7 H߰ J7@qNѥ\e3S*z#y!cwōhdǩ*P A1w3ډ ʭwـcCy>}w4o5y+s8sOĔLh~[]'kƺ0Xǒz tbX#^eVyGI/*sO ߬v~V!+2.hKs tIϥu258ŸIpM-l*۠h| )B*mN2G i qҼF)d5b SFs,WO6nu9 HCoq8Ppّšײ Q[o˱/wVn/p-Sk%m">ű}lLv\ӓ{݆AP&oaRԣݡ&[Ԝ|"z㫯 tb4~U3X AS妼֖j;NnbƉy\U3*1̟aMݓ<]9Ėҵ3 5Vi˘.tqϔRt &<Ϭ YU.ѕlXqכx2ʁ=eS%G&܇1tD .5f%_)K$e|."ޭ%+8Ka)$Cm;]l/nR \Ê+9pG++S݄|d΃EBc=8Ԛto}6ͨB~<=ޙc\y-q-#Zlc1c^w .gCnސ>>ق ~^~vMDp0Û78уyKc aHâ %hŅ(;d'7-;_o>ITsI[^,i" 듃]}!yNHVh+fr,Ĵkcͅ0t= ~g^9Q;e)W[W-ذ6pgPGv>ihG~T{%7SsA!<ʞS<[Ɔ-ci \87_"'(8ଡ଼LӊCuy|]>=alx;r=$KmρI\jLCɍ嗼Еu[p!ety?K- րL;ja#NMx}dj<0AZFhǪ KBС;Ni %+f?}NcPN{z[n}10PQXD3V#R[9mO6:؋ntr'lWw풕FμTM4\^2f6o\KocFY Xs|+/1g R/_U-,yъ>x2*Xvjgؠ'l9%gYa-&l#qG,/.|VcũNnƙMtԣ'ώ|Þ! MJ՚Ԅ]ϒ6|w`m<5]GN\<%DX7Q4lx wae\,yjx)scǰOE2dqJG>5#M*3N}.g)Nܮ]g7.>ةҖ-9*Vv6m++gleI'&p.= L3,8# ƙ5.9@Zxqe_{ -wbW:_3,Yϳ]`XK6pu5SI%cI6\3đ}msW=U\ZG?ڻ[Ke } tYAz2aξQlG\[퓎\$7!V;ʤ( ty1#CĖ1j$4\ڍsF\XmOvٍܸ]x'ى9q#kg64}dּͤΌ i1˶Cd)^rr(?"$k,eˑSi]ϙkTSaω[}Y:]C}L_1p\!]@ij0(|zcGL ϙ x7)TRjA.rb d7[r;7JUQ}5 j_L]M}ñ#P':QPsp,&޼GkAk0snQX%zfbp0y'-C~85R=i/c]X"4kڹe#9ۄwb8,7WH[{2 Ic2vfvElẙLXc<~/ѣtx=dT,-l+YhYlYB"^}Xҋ̔4pSQ׫0ҝCpFww\dvM4iJ8|%+)E<ŎY2IeNƂyt1:Ğ5=|s |873"šOw_?wx\c̃P]݋W#|:11|TƌjA/q>Miݎ]9E/}@KoŴNQ i8X;OwQIkmm_{΅skhsP;_4R2'`s%Oo@GF ڟ['B*tH:b4<8OxmPW560Tz-.Hƹz\W5tzq:}KxuKNdY54"lͱTV/æjΪd\%ke*r`Kl^\J=ng4\nFO3=˒AQV|܂fE&zϣp%)hW}yM_"h7]5#0y#DjRlYQyPvY4rdwr;+9ޓ.n|tB!hȹCNjxq3n*ȃ8 KpN0 ,: .$#m>}Ōg&Ĵ(RO!?gW8\ꣷ_8ČcX*؆k903_v`R{;YȦJEO)}J.3;|ko^|ͮ~4lO7Wqޮ|mٲ؆jSNݥi)6Cc7gP;ɐ%s;xn}& =~gLt,c Kƶk-dR$%YfFnj8S(y1a 7.EZƸx3(ԏv}ޫ]ϭ崎ެX^ᴳz̕Qϙ-[8K47=BB&elNfM[;Cm;sL@ƽn{';,70pO +r ˷~2 {b >],g2.lz |8|}of:>rV%U"4ڌ=;r[O~zj&?ʘ{|G2Ԙ?Zl-W9z;uTq[#5y܃CrD#[ ʵ}L[_N(xǂOY=?DCJ+1Y1Ϳ.7`lJZ8<ګqHzbE{9.c0~G<Yix!3B}*)lz0` y?g nW^4Ƶ1͇Oxa;}Ktvl=o3dEc Q1ȄýinJ1.%!E3C1"efA w{r6Tf_+i<ϝ l!+B^u;%0:ђ S򚫊\xu볻}, GxJ+xpSm2 L1zs7dyG2&kiA9.l^@zdޜ!p;T^cU<|À} XBae*+qEb<*B~3psza^ woRq%۵RrC;zD'3]ggNP}](Gp*,joMxHn4"7[W f=xU|“ ^:qvf` `S/Q+,F6Ǔ1?}^ 5;"+"D=o"y=po4I/ѳ"c1nb(G}+ O rε&y<42pf661|Sy/k>K]<ԇ|X;{Qؑ?Ё :R;v2_G=m^ʰogZŹz(r3yiœyg soBd"Z:ǀsar Woʹ)F{ȸt1 Qs9dJ3kgm90XP ‘h4‹=6r9>M*xc%:̂,Q`ݢ|\ӴjO~Xsʕ=i֍tϝ1;Mڼv-Zss0e:F<^YZ#2in5:@1+W>:5ҽwu3%7 >OSUT!_خW^;|fn\_ۗ.*zwއ7Io~l宜с;-]9*̑֜4ǒ;bYͶBtX 8FU7L8~xkuuAk޼o ^0 HvU;a eNϾ yhA!V}=6kGx=>^]qع1*QB;Ӥ҅+7ї.)#_fތ)̷pef^ >Qm~P[Ձg⫗JNũC9CzU4k2ܒ̺nĦԘ8׺%N~oī~{5p\!]oW],4fv]{:J; 4dE/Ӳ! eYɫY҈'e }k;JFc]Η}>{T2ˇ=~l[0ޯƛ] <8+O:qvmOVܶQLCFu4ɯicOyW!C*ޜ}# x9,u:R0m`vЎd)gx.ۇåI#$ܔݯQބGrtxca΂˫L//S[ l=SjsV~ẏ>>ٕ2m61v͙9'<f{>M[7;f6~Gx(ғ$NƉ4y:~k1ZDi \O7de7y>lթk`+Ou\w gdy^̗-T]ǝ;_4ӵK! Ac1K$Vא;b*cR )FOg@2ϻ#5ɒb*(GDV0I`CGG q *G\L~uahI΄ %\heO 4{bϑ;}9̛1S8/{o{[ X^;[El1Q,;ns}ٝ݅}z^kO-5E@*RHe'|=9W*2{5ZO 8 O˂ç6ՋEй4̈?Gsooƅ xMWѯJp5^^x(| AMITwLc<«ih_pG'TaM{ GO7*&?~UPgBd9cTR,T o諹4ASj_W~$=ř樂0]5iI#.'l-tCul y8W<1( _l oc  prM{DwkK wo?-p:/C5g9T1~O\.Ae.2otue'#{\s$3zxքS!8\Ę|O{О8wh+tz}BK|یBos#uҜEoZgUWK8;{r~K)P`ü2_>R#]Ĺphd|V`ok;XŽE= PCNq cǾGɰ4yX`YtiX=TSVevk 4~ <V ;}=6k]7hz֙Ox™ݷTC(c]6܊1rɔt`)Xƌ2&@!JnsTr"'h2ZC'=_6-Up H8[{=W2Fy˓Y̙R7bM,=u\wIJolXrL16 8j@Uh7no&"&#KhSpSSf6Bw҉7ٱF<޶َYcGK𶒲ijkrh@a/?(k(͋PR`N ~Ooz K-YEe?\ ;jƴGMUA\рf?fםn' $\_ɽq46t/+.Zٙ*fE g<ޖYC<8c}BL{)}rn'f`k[. j(O;2~%2(cNcdL" r,;;sv;P'a]y |ŭ/?5Az\2F<2Gƒ8 2pU^y;@FjX# +⟫ O=aQ*6zȏ65Oq LOqe)ܷc3[~!3dp;]nÛƦlgi*ʹ}E ,˼dgO WUӡBN)8L{jVTp0OoS%ےySf=uX6ξØӟg1T<Ng#`u [NmQsw?hGKѯWhҐ'e90ҕޛy7 rFׂQuXp .w&<֞b.Pd)[ F hkJlO{5\"_³a`g1+x"VIP%y\])}nz}Fק2N/ŽdzWIxy1 S$ջ_ԥ/nfM{to×B9L3bv 0:>ϣ2(0u>_چ{8( L=vK3?ƣglçӊcCeBIU ɩ_#emgd gfsOĨ\<]@FO9uj<;J ;sb7݉.+]Xʚ_ -Hâ`Faz3 ֍2d=ZM?ci{= ¿ j}k;8 EVtX/(GCb y!\0cyW=L{h'!·Qb|d!`#^1'zdk)h~MAsrFF ̰S\!f* [N'Gsd:rn"rK'Nӧݳ {=␚{@O+Fb,άB\o!3ODIڰr1`< CO@k ?<'mgҢ5ku˛ԬI + c߿'{H4~_ƎUq !KQ?X]YmbqUKmTlvX' ޜbcދ64›ȹ W |(2L]o~KfG{3<+N[S-eX2Oà["?̔kT ^s߄ ?[qS=:lX:k6_tXr6c0 hx..@/%8_ 2gWaB.Er3Cj vaPߝ٫"ɋWd0X̺SwUO٬Vɷjڶψ*wK3ݘeMMΌ#gz& J)D[+߀! 4ϐ=G1~I)ǢcK`ڿ \h7ڴd8FEiUmU]Ǻ]_{9M[UzRZ=6cQ)]R٬h9-}| w0.8d<ġ5x.賹resQ`gT,z2noW(ˬ/[*;Z£ Vsh5[T8G)hvYƱ%>3Ufloe_69ȑsAM'(*o>ȹ"Fz|W>Y/>ȚQj!l)#)?𤿝3k=z.F3阾' =]U~HM2Lk^z!]BV׎D?0c{%t/r҆snϨޗ X/ʪ߹}ǧ I*RU[ 8j]ީ?JpS1LKuJf <'g4 ='z>۾5Г_BVj&Rs59w*9Jʢ_5Ԣ tmgY_tc4rw^ qm.U'u9>$gȎ]1pO=ߨ)¦*W !ӊk^ n7@\"M.7=5ߚb NBL/JZXmHO!<[̹01Ux]db'е#"}GL4x @ݥ7ؘ3ٸS4iMaY l{ NaЦģivgaŎ 1ZX_|(c\RRW \-"WhC8VߨmfHv)gY\r.:C+0PE0rnr9wB_sf7Hϯ]أ'7`uG3VlÕ]1/8rBwT[&3c2o 2mUeğ&D8`nݽ<ȔIΚZqx= j¥Kq>txEgUCҾaar j&=kϹ 2qdg/6W0yyCCǼy/հ꣔ͿЬ*O~r{Qpr)E1OG\9f%R\ 0ݑ?Ros{rqƴK;HA0ހާ- w%4=E#\im.(98C=]JKI3]ed(5JqM i._#G*xxy+o)6\AE@$^}wXk[vs .f{ߌYI{ ]Wߍ}ݙԍ%TNqնڊNӪ@j S+\Ƈax"ጭr骦Z_403%H\3)YHt)<<ڕծLxA!KrZ8)!GJSZ`j 9Aw0cw4woGEFu2ߣ9GlhV,9eͭolȞ-.8i+vcOjeh+)DoqՅ׆Cٱ746ȳ9i/,VQo|Ysś\1͕sߡ@ݠa쓀!N|!rr9W9 =2VEk*,Rdӄbʰ e5"GS(n?>ߵ:ΣGLAh7˭},4ٙ&yW'zWqZ5$bCT*v 4"pd'Ppr-_cK5C]y5]E6>Lf&j(aZ9O] VEeS%~+Lpo' >WI̿Qp7+kkhÚMY!LCbW{-?D 0"i*ż;n˸lKO1b[]m+&FvɄ'7F\`oX]C̼>9GKY!?\Zk$ܹM~g b &o$[ ^7{̼?Gq\/ZoUq]^E2vLqzIxʅ>X1="˴ue]i>Mq!E#vVj?s2FNo}5}{92BS1q7YrRK?S $j΂#?ܕ%G֨aj~C;>tQ]9d|MiQ3a_80ØoR?KJs%_)L2:LRqW4^QPU+7ſt,eϝ ER(a#;/!άVXͿT"mNZ,<>Gb 'kG<W5^Lw=xS̅t閏ƺ6~X,j_m#h#'qSk[خDɦakÅs|,TSF% |'gW 63|>dS{fxs.ݗ >`YKTtXCЮ!GHj/P袤WIJυٲm;.;\ەNC-pkI*j\5TB-#SNY-o`*Zf`}YˇX ,ϫ2F+l>h=ϩ{|.Ϭ |Ɍ~"|4ۊ\FD6>Y 26KE wpg%=Ց T\=T=~* #3SJyZ ة9g9j3~fiCjx% HYKroکb)o0ᾁ1R 9wpV +tq6zkf^ 8 N4c"/ߠ`mO*%k  1щGz v82Zg>gısȜr)<5D{flvSGxUZ Unvm^CMxr5TdcC)8etxaKULjF5*zA $'\CëP IMHg̵z ʴۛ<*vZJ1"/r HʌJَbIaNСb˓='>P4{Ux \G;qg@=t &B.|5a*s\hFV46$vH/LOA/Hw_#QZT֘?^'OFՇ $lUS]*NJtS@5$jت6 %5&b cnce\IsfcJxo~֌Jj"9Ky+O_gh̉]yUcgg?wm3e Wg V= [c{GxrAkY ]uӛ'1X,hhnGׇn$2wRs LJ6$yͣ U4k {!ls鵅ZUKq{kd˕b:[ a_2ڋMۛ+أR;əwj9PjcM}w9ei#LM}M8}5^]hp>}zp;={ggC M6g/VkVB Ҕ+ɺX=M]iKMkcl3x `99-G \"uC/xX`CK.Y ^cz#\'Ҡ-o7][ޫP$5̳V[4ۇ{kX_Wij &pz/KagkLƘo۷’جOqtt|tӯhL{F !Wh%ij q=|W$?\hM9V~f 3K^oǔf@BDZRE>ӧR=U;^ %},1+8 n|i/'S#V:PkL1ֳT<$m|_5ˡ> ;CxK0|Sֺ)1 'I{򣍔 ͙Ǝ<ʉdžրsV`g;:~q6accGbfpma@au<^nƳu0A~/?¤??K#m-q#RX))[.R&sz Q Z,Gc%6Q0E Pxpvk+ֿicSI]21# /c׿א{?? 8|&t -QMLj`&|vMT,K:^Ϟ =veZ~jW?tQU/ax)ؕ[H2I ۑ$s_.}\21NVj>Ts>!^nUì{r~giT,B{5 saHX;E(sퟡq[^&PΞ]Wv̚}pnJL|N`~F|ıF{.FnAT= <جʇޔޒ͒7_#6XOX)pl/EʍUxv g!~(H`E"]8VNbOOV^QRsgHRș'|[pZ#tXdpN2&nJ==b+62@wrQ0ku}5 z%ۤ f"arC?7Z֘:˃0xDgD-:ŗ?g=8f+fq+CνQKOrQs#pm AX i>#2/0ZW|6Ml tѶ[3 s?Wzƈ8>g`T9 .!O$x|D踯IƎ6{n[kDUAX-"鰵sVs" :vbj~CG&*,0ViJN|-d:؃e_*<$Ԩؓ}5 :4; C("=EQΜuNƣo#HWɒ .ґ1a%<(etdӥPZJ3ܚഗ >-W曊۾-'"&NbӇTjwg eb}IZnFX=^)qx@iT\nn̞#yC:ա2RsP,?Voh! ]/"oU8~)9B4+F@)ΜΩ^; [OɹJ꿗3WWBGoEsfaO&y:|cw:|Dm<og!!״s$/ gL?%U4^&_"c#^;KwD&w7OOĞ-e3WD(@rV.8K77xبb߸&rKW%{Hti+j-.흇mpdt4܍i=o\[.-2otgt|˵51_^r% )Kk\8#ƀ<%MV' j0ȔrĚMZ\ ez5P,+3Pma/o^‡:Db[kpf/|9߭qxO콑]^1"OjH;Q%LQ1vץ\Ƌ,xv9~ MXWY/v 'ӧ_u?2ѢW!\Ls9ҳГK,%pD%bKR&Ky욄 c\NʸR,8 ?EH8J–2>#:d._SclqQ*+E6>Q\9,*c\)E|5^󭓱,)+pO_ 5u;&v\6Y\i<嚙h\6[qBcoV/ףtW(Ƿw5,LNT%h{-8Gg@;76MH->@ rυh:-\<$ef,._~#y L"t*ÚD0_ŽLVrL֘q;#4bd!2FLm-9g<А'3$V7)GcK>Ƥ LITA{%Qk%CFLx'w,gH0*sOaX77 'C3$abL0V !l g5ܯ= κ.28Jy֋!D~'u?&Cw%Qү-:LtAٟyO bŰ7%q8tb$bY 4}S'Hj4&9PLl> Ӯ5XS0>|q>MԇF+&XW&0_\5LØL>5rb p sǗ9$#{p6W!ݥuMؕz=6g0VmE|?H] Ue"v;nn8ȕk.;ێӿI-t37SRra+6V&4b݌ȄTծ<}\6ܷX#P6L}v*y咒u y\ms0=,-Bu)f9/dKk>v)+Hu6dl8qQNl$>xs_S2_FuQZmKմmqd: &:K6e`c4קǕBSFK\zKQnDC{ 6 1&uK ?HM$i}.a%4ڀ)筨j6QJ;OvucOdOZYΑ~ G/ "/Yyx Gp6gI3qF  %t53M[ y l"f:[`8%Tsd} L)yT`lòq11` nϽnǠ nˎKKss@=S9[{O)GkL ^ v'{WglsLAQr^Z/XC2>#/>MVpc=%;fG~4ApOoy8gczFO_C7lm; kg>%L>aq<Ͼjf &(3Z5RϗK7%mR*^-Q|Ǖ R9oNmn:1W͸sW5*ۜNYL[oNTSϽ+q3|?r[@V9=3*?oub-^&Qr)%st~;Xrլw'2h*)kar~wWQ)œd<(an =O)KvuYRH9ػ{˩ gr/pSٱ nY30:p/CN8a˝ ͘K̘xԒD0gˁ)F'2Q:I N2{}e] ozfQ@6Vbǿ|@̆9e`YV =;݉7-[npa?4>0<WCU'$u-at1}aByCCK 叩,/832=.C wwŵ:*D%_yx%*$δnjNjuEq |T.^ˍ9\/>yl/2uNn,etkWa?u#:Oev&ckw%\VŃ}8f7j6ܛ5tZMNޜtE2vRE6rv,zu*a; S8n4b poVio(%-ʙ4\řݩg̡}^vlpٖ-l{Z[XN1^5}djn%p%C rAL.0s5|vR'F"&Qd9#?:ТB9̒_VY1z+F)kظB+"7Cb8\瓯MUq<ԂpN++xaT)8=ڝ gfޔmu鶵^ERzKGsٸ$F٨>Рs:.?o ĘGr tuG#vXgMf`~X~bX\D|(/>%U[ />S1p7𒛚GTjأnn*%<gCW5K(] rv\mrzrwZtҝ3/ ;.ad#]^t9? ϟAj(:~VKЈzXRp)m/v\O[Qg#sQ5_E[:K^n델>C˝8nTB}xg΃}yYK9UΈ2ܑbW n;q?`lxMI RZ%3JГBxU NAͻ(nv4 C0p}:jWf <M>7Ұ{*TUrDj𭉚Bh۶8Mʩewf }=nL,LEQ1AQ.w~y_3 3sxq=0|VN8 qNq=7`HGT3|#DotO5م:W'+0%E {" K[u7t0pXby~!"0{Twˀ'&la L89{Nknu< h\j{)ΤAb!^ۣv _ّ Dqv#^sB8gܮqBT/'WmFgb}\t`;t!ոV%oS L.GGu%Hk,дn-,Y8 .it;%IYjtQciˤ9_ZJn@_mk!T$NzS| V3S%EF>Xacaspkq|< q$ &i[TGZ(kpӿʖ5/F `rX ʯ1C> /f`uUF]ԣ68r LH3" ϘcT#Z) d!`Z*ɑΰ">poeun !ȿ/I{8=X]B Yj;KǨq2E-%A:W@mhlF&uْKQѡ#ykB=RC*lf,#- nB g,㹢S^y:berG kDŽ!F,d3Č'͐1 ք{u'ӀV!WPȑG$*AY"eAok}kC6P?t6",].[ԃOJwm-Cc:#fQѡcI4 u{,>.@YmQ-f Sۣ >@u<cjuh؄uX_ 3FT@^7Ԧ;cc#sB,gp;gcMJv53NU! ͙kGa7 G`˸qF<NUoP=7b@Ym  ERYjjzkTVX2།9qm=uw. K`\æFedVlI˘6kTqƒDgy(f>Z1Xs}U?Vb,](b[)'EZjD`pYW̬üneDZC/u\%&Pu5^s@ h):_O<#Lp9[vЯ]r[tVE68,+_8"y$KEFVu ol,AjW2NGuxфm]0" >fLtw2: _Z' _l 8eo'hza5(fF8\0#sH4c|9b$(#/\Hrp&6gmu .*=wF\~fč+OZC[¯iFzeDs_$Pet{--POH[8ְ Q(y&\O^ &2ǖ;[gi͇1sk;ӈ$dKeW8;c'Z xʀq3[2M5&A- lpڦ򱺱_pzqcyx~v5cq?G4\M=̰geZRhUd_{eLH77ZxS~`I$~}8͜DWJӍhcڸ#VL.6ƶ.B#;GhW%;bU#~=66 11stz@(DXXͪJϹz L8 6qۄ 3UfLb GE5EE RrBK=xps A-:҅ 5/rBRQ|%f](E-𤀜Ose& THڙٯf\ca%6FH'/ .W}d0SK/Ѡhu8ˆ&& 6Qz뼝c#DzxaЌD&^"~OϤ i1 2η!#s7UwF(`[3z;4b>-4We sXϗ{O^[! C bt:o˒!-FDn/+ө&JI}x{iϹLݾI2 b!vC>L*ig=y҄^F:9 ?wO[TUSeHM4;uQIcwtĔo&L4~1aeSGtReX K); Vh#XCeBmYPhjf:ь|:y~,,ݻG.b _xKSQ?y]UbJ\LjmƶFm.v`i _!T*8lR#{0Ҁ/qfZC GE 0DꊾWĴt![x b2 Xy[^*ϣPHzHѠYhe_BWX1Bl0Bk>g31*읨H} @HƶB\9h]_݊W0ѲE޲R{62& Gݲ/=VͶGVru7 aw VݝQ!rRA:Pi)"CTRCSip:QHhБ4p9 _w u'1c#k w]Rܱ("]0=eG>C!0B;"|t=MCZ r-;i`Z]}?u- urf^w8Sj7BN>q_gY ݼVK=>=]x8?Tg7X<VxNrDxCcK=:(ڻ+5yw9cь7CAfĊkC ~bH#Vb5BWѽ GP$J LM˿PD +q{DM*xס OmHbBa=26k% 9ꨨ }ZޗwO*ٿSl,P#t*QO5Lm1=Fc}w>H0/Y[fHTW:A:3X}KH$E~EX1'оM 34_&tO2v%+GiW0\f l"-zNTqV‡.SX=HGW$6H cjv,|f -Zi}%?SD]o&-vϸrW3$Ӆ%UPu^lq~XaUxx"aRF%䌣+{@]P2!*}{& ^†.ףMoy`YC*'1YR>/4sX< hb+"?nmoΡ||,̇bcg"S1|Tŕh& a5N S'33p1'o?ulK,[7іT;n+`l>XTW-1Wl!Y}-ƨN 0MV3N-(>mt?`E:7FPePBB[g#*>]5wg!Z7?ƀ_:왮M7Ԭ£"JGB.a{Tvb![="P2+iT@ Q,otOwr-Gؼ**|QI׭ J`#pďhSld{2E"aRGN2˔!u8૱aC-jA=ב3,uр$/p G2ڦZiD%$Kxm*Or-K i2ZKVi8^ab1*1"Y] [gzXVi/pwF؄P^}fy{}Ú='ECKrG6M llEd $q-1==2`rfO9^{2ZQI ~a7}qOPCis{ShRIVa#5*w 䘰Ҁ&HΘAZ܏5p3n^iGk8ZJ p3W&QİB&`ufJZBr\+ލ"w`w-+(8%yODѹωlL...*?m#=+S'91!lbjH5.Nυ%`z|!^S뽑TOmjZl=fKk 3+XCm'>DRrC.Jn/٧isTu*Q~4B0SBXC"oĀϣ5P4c` 刂ƈ(-HX|ˀN::uSuyOλS%HbAXZf պ̮s3}3$[6|?L&04ibH6-硬9.sX_%uFy6 rTb*gEi19H3Fj=.r\dtBwoGz1\ fakO4m.KI 9D"5Ua\%oU6ig#l]AȧG:|<)yG:ˤ[F ]ia0X$Qo@Z c;1t6 {X?7wogӱXfN]IKQݥDEGZϟ^E-+V*bP |p.őN +M ̛ÍǴI(DYԝkj=OF8oNVav%bq1:Q ]}] F ^{%VU ~<-\0e;; sjpyd 2CxUn6J\u >gC>FX液I%$|M)vFf`96h\IYJ.8o FK^.JؽT4{WPYH^tx`DU>q ;V:a?A5]_@PVdldrHI6n}Fs/\D3-V/H۹ƍw-YPWl*^C+R!)%ß?w=^0޻linxC"\ :]N V-WANóSz֬`€xƕ\lGCzLG8q;`%!C4k:YoYd\kn"'}iOJjG iz!͘N$jIURZZC9.q8#Xt'MU>9,}0-VLJ_bz)IL1"$! =~va_yp"3";™:@j*0LVpP#Jd}gG- syB,%-õclGR:#5QBW/+4 ;:p &Y8p#[ 0^!G]2 mg.xR$ 7`a0 4kDOk8ho‚׈%Q*#ܩ8rO7\M4R jxǩJ4X9VJ - u Xhf`HC`|Aֿ"` NO%J?A,ۣ5 i+H%Ef5K/ʴA'-+oS ō&]y͹LZ$y'KiW:ֳ̉dZu8MJ7h&F_ M—gɠlڛPHv8;6KTp-7=48ȏhd%Cqy3}aSQdFUCA0(H 4V!q? =8#1Nd Lx`¢& Sc^\BHG%lbE9[O>FV#J"{=j(FZZ-f+c3}<F(:p(SѨ'Z!~Z{Ī*DV6_ 1 q[ hH͵vn ngTp)Ryq2rYиTjl0mu7ۢ8Xck~Q +;ZV~y/Ѳ%y{g:pȸ ]{CQq4jP*Qg9}ZBs)a툻FAkXOcq̺F" ie{X `KRّ4oSrHKR?Ѯ?mtjްNVRRXla]GMsG,EWG/FQtFKP%w s)~3-¨1{fMĸSB -t\E:\2s{h?O/FhV#GϖbcA6](G*vFBސk> ŸѾ^\#?XM0G1VZ $1 rq0+To.87~HleV^)=#q/:; ɻ,(}Bߏ'^_57497C:<  P>Z^cYXt~a7KKi`:zt kWq`]EHt?DC(==$Ӿ VL߅49fO%n7k:ELWv:]>rM`pVjlf@|3 gBaN(3΀ZبQ5q*t.A1fobo3)\Ȱ5Vr-!{?l\bz6"܊ʷ,rC#gd=O_<"]b3GKHblEhQ,-&a:#h>+RbO $RRVqr ~mP.[2"&tH$k/f^.Nר҆b.nsіl -/Q+'e9$hF(qieL|N7஫c->nyXM\?F%m[O: T8;̄uzC눒pG>mfl?eAjLX/ Zo-1c3Ʃ07am!o9EHBʜV@v(j̗||JG{}Y(lƇ"5%W1 m&B/vLV%ژذT%3G 3_ӡMK~YWqa1_u N$hދT@ SU@yt><=)~fts jl0EmTu=v/̣Ŕ[M{^X>9Igc IѻN{mZJ[#:~P:mœ" >uVw =_*&R,bo"'b̸)4eJQ!p} ij-z i@|X6cuvX/@VRtPHWExړY` Ne4})(є>7S(q5ݨ*i<:Nq8'Rʨ%ڥVcg5 Ri7b)ΒS߈a4CK%{_^,_Hu,!l|sKܙ99< o)l,h`GpNO>/۽XTBWҠtePp0R^F?;qmYAf-t %85.}~oe}R¾V Ј`gfvA 4ҌytJ/:D֌LQ r?&H1 =X6) TD)])a-d*6?ڣs%[$XwbLЊX'qR(!E (RBZ׻Ȝ)hl +ʌ*ثDx^?D8[/@)h=%!| y&A3%|D6"!Q*YFX!47S7uvgЌTRJZ"=GڅŴs)*hTPRڥMM>.8AwP"d!VӒi4ZVo)o]7;zӔq/гàYHJnje|j7=es}]5 &i³x-̦Sh68>ZCqFiD XK*hBGjz9uD{vRF+/6F ?^Uo!Smpce!1~qV2,czяTtC77zhG&؛]1CpyCZ[&|>`E挟hdJ₀m&`&Z僧5^O!*F q`=YHic3ݎFWP2c崡 1BٟZܼKo;+4tOfmm_K#9-~Mҟ$4U.de7huy xYk5֟ͧ/ Y/(T-=yXE k(iqqqxN1|Q_q1ˇq,Å9A'vVf]c`;3̸+!kg@Ԩ͖`G6Z\*f,ܜIO^W[p9)&mxXF Ȑ~K$͕a0%9`lfJ0oWtg;Z cC.U,J]%[ez<W ӫi%|Swt4&κG姨|{G} [y&J޿h΋$zJrT\$ @7>ߧ@_BӳOh[uԟW?Y)~i(>QOFuE{?"-Y/䣳ɋ^ɧ8*ўF1ijb aX(Baq`X>(Wph3L0-:"w5z*N`:+2fP^'zN_=jSd*$ 2tUf*<:>s?l0#NbR)Ch*"p-Cχr}^is0+ Crz3V +'$E.ɄfL;À $Vԓڽ#^D#S>f:!;.%D;GhF)q/8`MP{Ƅh=R2_&ŠL.fd \er\tdU)/^1W5<,ȡ<&Ēxu0y4@~&RU<"[ w!+:ZTO+X*:ѻ4ˉUEɡYuHGy`z{-C'ߕn˪ uo.,$O[WVN Q/ƒ;"Dv2(ƭqn".'$ąAr! q!Xw~so Oi6ZZ]ݛz"U6I1ɷ(C>9Ljb7ÑO"a,V#o^09%EsT3ivc漕pXB8Z\͕[uCtHK+_ItdorQ)Vʉ2jwfd#g9ځm8T5O=#iF*ΌE{xU倁3d02n(P% K,Dxs/,دޚXP5Ւ%|מ[ӆW~Zqv1-r%f->jOh}^0g7b!A9#+ EEA|].Zr\{`% tKQ) c15>̭]Թq Wը7ES`#x:xBk蝍F}*܉g}?zJ] >P 9@Tg:'wsu1nvjKUx9-6a~ \3:UjP\<+*$=J,EPX EBތ f5݄+72b6Gj/ǝ ڡESDu֡K1ώehgf0| vЍ3hN!](d_]ZgoBpt OdN٦|o@ENY!s\|g,5݊lai_ec)g+;_ jQ/EOE fBnj>VbS< ՊI2 Ts]8:V(s|i \)K,̚ܛ  ,t/{hN&kZJ/Z 9Z(Evrq?xҿ'|%k &g8?y^>\Ux+9g] 6% Qb إX \TđS/x˪: G{{XrH. S`f$ k’-HN w8&Zl&m1O'P5@׉(:<ۨt-=f)j: olc5)Iz_NLx)gϋ\ŝ<]8rEY En q&v־džC{QwrC&\Gr(OeR;2qbu;nm͘6raTU&'i(-fxP-̱4#x/dUbsTeX{M6(r wנ?Xlв+nGcRP!FP1U!z!;,ec3>#.%SRbJdLZLL? 䴟9x/~5m}lVuo٘Vr}A(Y@7, :bjh&=<|+u0΢ Ў7-tm_Lݥ55O쨧ΫTH5HLGE bR#3Qr\uttؘf1yJ9c:'irp=Bny.+7tezW7F83=ƒkf5uq>U _1]JjVt`ݩx: 1 yDӒ'^#.<1߁vr[Oc[faodb55"fqbڤ% x>?0 Ƅ;2_C|.B6$bD) n38t_:-ɵG,U]VG0!ozDI8~:?%BG*i^ʿ `mE?sXw%>%(7" p~ kPiJ4FbT 1͆vPfCE 6a;T2dp5Ej,TQa?YR9L|I j Bx&x@6C7|~jlaƟ8ʙ2.ARr:)_vtь<,qd/䎕0 +Ř_=]v #A§0+#epD-ǯrL`vuĎA|5̔)zlTPe[};MSt!ZlJfccWސCG@)VI1S.èXDKT#- <\/OEkg7}L6ԄVQcuc ob"ODn\8ܾ#/ Z|qAGdmR &\5bst sxœ' 3&61#&^^0f|Ja!Wh2Z|\psc$(D_7 ɊCrO)͌Y0_k .+حZ#.h8jdFo gN.zo;:JsΆgP&z/ . 1cxFw/p?uBbs6r_|/W >T9 7^BZ3S 19;Ȃxف~HG>b6TR1 -jKhG祙{6gK]0ӓ:ܰJcPoH/:VECX }&$,w}9a0z#OJSy{==.;q+GSv,̰2_%fo%uҮe/1NK̞ ~4z/mܪMU8~*#1BJ_`<p?Z_~Թ8R li2CVKػޘJX*dzd?p)˜?0.olFj,x {|3}cVo^>c?M'3q}z+NwWeeߔ~OQ*z#*a#1oF/i8Eڛkn5g~ ~Sd8_je=N +k 2fZ :)Su` DFwf]. eLi{yYk %^:]EZX4wv}4~ ~__凋fO5 UU_[ eNP<Ő|_6;0Ԛ;P[BQYg,9{6a01<5Z-8 3gQ|ye(WtW~dF˟D$Z`" Qlj#*QKz\lDf<`/hX aMP 3Q]1h{WVE"_l}k&Vf Dgx-r23ƇE퓋ےl H?~$bܑXl8#~/>.*1]Tdk1ԳpU2sbz"5K5H8H]G8smssrK9ë1Ԟ,jV̚#\h#LȒ:)_1Gg0}xse!;4~O$7C{0Ā90GnƑ[]P=&vZ?w4`}TDuQǘ,K߆kf-X[5S峉ArU j5X>DǮ0„ zpwԡuWdXjج/FʡT (Ah |_αB" &fn)Flg'MTf2k KN.ovo9tBqt8`kR0WC>+>ĀoU֞?1?>ޱ?%uf_a7+Š3X{ȉwFOIȿ՘ 4 eA1@č 1昳ގ}mY6D¨Lm.tХC~W gqrV;W+N5w :=].کñb<-dzUVʦ:|EnXG`1>7qh6v FQ]OXSuxlz N0T!Pւp2e.|Pje6}S^* `gjLPc]-F4zsK8nE4ݮ.)dU.%G/0뛃4oC/ 3#+St7e8#m⁧P_oJq-+Ԙ3UiPo#tsvm6#}T^TF] s0S.r`j.4gaoTAtç± YE@=Dyɀ8|_TE+8 mVê {}4Xd%rޜ;1Hl}-9>ٔڒc8SEÞ|cF;H o"Zxi2^ *bC;18:oĴ] r;Kc<4qWA~m!>{3}'PqhMSV6%;mF,yeB K aϊSVgY&=Rg u_f}ٔuJflW #| PF1o0ccr! :h[?pL9[!Vr.Uܨ 22"f@Uh|}?6?+1y[54bW#vj3,WWd㕰@#Wb{Qܗy"AW?1/Zq ZJ{HMjmy bwYp; wvlgJ[;S`ӯ(҉1v,5e:] עL-'kr:TI*ON \>`|suE\,4=b1Lōnz >˂UVSy/.PDإҤW/o =_c5j2ACBis)s-Pi賮V Ř坋}={D½]L1=~b{?E9_0gSLȃhp!S esm,_vǵW% 8;v鿍Ӭ{kVVbۘ\ RTU†jLŴ`UumiEe6WeDoL~yN1FUA}*{uj-c!MUL9݆:n] ;nw"GwdFkQ ~jp4$︌p`D3G=*v9zl&ʔվ*()6jWS]mmڶ;ɉ1paW[lW.#ZxoТ5*۪Ug1\8*U9uMnaL\g`vp;|πI7F W0nw1Z*`Vk› \ tmE~y"-zKIF0+E)2,[V9@)ǯ(˝c8vJ1NhxXO (kQjQw(RdVs窰\15Mj;0i4?wa~ˁb FCv 6u|~$m;zcG9$x҄[ _ҢΈ5/y '3ӬE4fYJ(b_[.БPqt+<,%;uENXZ>rp/B_Q 77j3OCcz\kJc C>`Hz:/L%$b΃ kCL-24E]ۧ' asQI%N_?Kgm¸Ɯl̖V4 gfqf Gvl?afyPҦo#*o Z3غ=3瘅C~cLI \0ȑR3s]djNO7QbeP_ժ,xL&Ddb}/IhD>PثK)a  ü:8Qg=j8OZ*rX"+,ϑTYP \4 1Nٱ˜IG1Oiv"垿1P64"D=;Ζ@LKATǻO>zT}nzmwWg?[EVkµ^84 v"8 mm=n~U&h(P֦:j&Gr&;uf3kh U'x#VPJ{6 m:i }o/c.t92FwR9ٖ5͜k< -YWȸvNi93\5a7[ΠB8BCМ 3xИ93]A몱V;"ة/=(;h)-ztIoEBfF3 Yu~^*21 c~g&;95dG)OFO6<V<\ 1_; 1: k uK Ĭyh e;ߊܣ+Ff5>UUa!U%oqa{Qxl|#'oaU>]C' ,Тw.k백J{8 G[;P|߉;3™uxqÏ󔱄ՓDG sVr17ws>uLFQG/8tl9#M/ΝxPxm"wTdM'njA'*"PkF֕?w8 D ǚσlف_:=ߵH[ϪA6fB@,IaX)uXm34cHUYES$|aBsW'{lj+ Jij Z#R^9GK5Yqq!;:E'9 3P-Z NWχvikK%UaZ% iJ%-G]uEiX^B^t?1moIKqqAx [Dtք<5]Ie4ˑwu\x#ύ̅uoO|3ޖ+9ɂV\oO^\sԉWreqRvfH R;ߜwgdCHl&Mi5r0ba;ڝII~G$NBq˅h w}mǫ¤푮Ui-SatZysdmGDg~wΧ+e{x嚔?;S WK`F gf;3e>R!8)Wlхdwc̙'y ( G`LA BӆstL :'/ZKܧݫwҍ\^!ƹW{!j~>mǙp8Wai_|~09]iuV̿UI[f+L9t{yM!^6៾ )77\)x0WR>K嵵XX)Nz,ʒIe?.dUC`r0/Po3NE8I +!&oֈ}uoXypE>^$?8TtH|EŔp?AehSanO}FZUʼn,3tt+Ozə-xBLW^#TIܹ q|ufq?1l%eqnuB)4˨elyc<΁~Μi[7@GPq3c5܍Fx܋p=77{ q0U7zO;^Г=8S_\㘘?1^qxcL(Ң1~.'|g^~\U>_ѭk(TTð9#}?hk\Hx>|T<_O#!"`V'q]3PSkq{ѧz+@C"<3"1{DCwC0Vٷ>\߃ovYs,N-*Ëe];5Vc74Le.Owt)!m1eG {YW=칸̘[2]d\[#gNB b)v8`]:kf|ީҍxM+iiK֜C⬸Y(mW^Ru\փ?}ݙrvg&9ƻCƒ.|ܯg{x'?тKyÑS/OF'{p{Gyu'˿gv,О Q܋DgWB`~Xg_u2]0֖yuӍr2*Lqbߋܜ$^0VB`Y=ڕbRD:t'ytߔwU܄-<_uy o1Kx>O,_MQڼ/{Gjqѕh(#|gogۙ?_ѦsT#?w:ƱV67pO>VcB-NTb zdH 7-z5|SV7%P./ӡTu[q)3b"YjԞ^`+Ίȧu:iV~jœ&Wzon5 U}|-#n G&]an*Ů|YB'oƳ2z Ug˨.rݗ1pZ{WnSptOdPԁ΋#1^3{kϨ!l ו1tߺ1k'YFCnSw]d#ܸ䵜vKUñ=<_ ځxې.X|4: d:f+JXݎiRSɀB49E= ^*oP`{ٌ/-VW|rT/ӈRLoW`%+JL:+ mj4bϻtxo) \%# >{ hy^[׀y;oxWa0j.дn 5ngą-F>| ~RIWcO(e;˕ER>UrP/7f(9Syh* ]a;'yqozqYg |$W {Bk&3n̍τV97z0;ԃ׃yi'Zq%/>ˋO>\ΠW`ߙӞ[j̷>yUH< ˽lxLx)ι񾫌Aod|Uƹ0͆MӀFVӘ>ALk}^ ó=YjCc XH IڟܿdKt^|ÆOؤ'Y*\1/?ѥk noUX& E:&ߞ6s > 9˰LGʱ)# e~X)aѐE`Bl|h ٘y &cg9{4Q/Н]}מ {b3w\+=\JrTʮ9t;vidDq^T'ƏekOq;p4U P (5dSpHm\h)r/lOʓ~ܯӎ<7*9Dav\ψE4ݢ,sh˽n|d! 71ѕ2VIyb3}r`%uke{L)2U>\r< -$F@xn!o\ Ś+BwThgT_spG^tGЄm#g'$6PВlRS2P,'05LAl$,Ft5B<. ~B'0j-GQM~ړ ў|8^رT&ggx0x7|Ntn#se+7req7zr9O'|ntWW*c6'i-Նt[:Tخݩ{9fmExEnggNK4va~],gSL/B7G8^]-^'MYbϕvv lio~i7]y6˙\h5Fƍ˞6}ł3֚N{u9J*1(Kx<*K#u/_ *R1dO<:| Dj~0!dd^bY<O`lڭ,E{I\?cW`g7p!_;uES;a+QX 7 {l#D]$6…sX{ZjO-}iܸ;'vg09BJŽ1֝#)ltcc_)ܘ.dՒ-*[ qcBLLx=ϮF}R_1J`d*c'!c9.Ojw( ^5f/p%ȘoOCUG^r$͎L-eQwgI]̘HG2qbQ,,s`˚],xDCzvc^U*2 YݒMO\ UmňvaݫopX KjNÝCiЪ|/ ^ߞ6fڛ&Cau(Ux% U Y8wpR JlkQ#sVջ!io])Mr $g>s~"V(7j}LOptgm9x G4+qesW;ruz*44V~qgcbfoE Q;M;B9Kzfale usf;:wfLWּ|ҍ'rZ#0x^Ñ7sG K#OJDJ80H˖5vO/ӆXr+n&f|קګr#ns~.Ww*%xO؍nڞ!kq0q QWƴ wr]2K±r n]Gǥpww qPݓ_{B!q IH1,>뮙;wMss?@{yfCm;7EͶy<ݕO6%l}Бm}zVWaҩ$mc- SPzzѺ'&}[fɮ,6r!|YLzgv"&í3כxyд3{Lt \Yȅ6q<زTÑi8ˁ3"׆[lښslYג٦L}lwڔ P槑,4=~5NU\S%6ެË`|>7@:)skX!~/y3F_Y tjg",[ x^t?_7 Y<ȃJ̛ɓs7fԗMKCh5f+h&Fzo."57^/S މ&xPǓf-f/OhTNjfyK> Қ>|0ċ{0ړ8EWsċ{O-h ѾTӁ~l]-WR`Te֨JXYi 7˴u :ʟMEjE/詫!ʜ؈G=е?3lUڰ'c9{gcTk,i)vlD%Nlp(kQq`eGxlK] e |jʖ<˖o/ptkiξ{Mژ=*(15bz|R^(Uz<زJ~*-y4VY 3Vۆ h w.=L+(ƹx)jW=thbgZ>7о[N˽}9gx97Zglj7-W{ٛg|h˾ߏ=x{ 0v==MyjB{4iB֝TSwi~F)5((K.PgIM^cXv*CsnTds+ZO:>ETcƍq<`±~q,F/Lrl'nzaӳXcǖ?YdqzyޖP};޳2cZ5`Ԉse)+Cj5mk ^rW ^O92CWb#>׌$?zk(lKzPi؏3ysOh,A% |MZq!C{k/{&dsgyӿ7O׮<Ζ'Ra OϭAl5vf4wg>zևoR+=327Hi'S ErRTUQJ)sI[ H᷺l=UNTg)IzxlQgHŁɨ@D& hJ bơ,L[͌9#\8וs غ֍u \8se.WNi۔t'/tc3;eZ#ܸ#G;`#;[s [˒o- 9_ 7Fܘn2NβdgK<4t÷\+_Z1p ׯwe?/CL! 4J`~:h+J&v՘u|GriVվ1˝]zR.5W#c>?%X>1WjJ7۞\Rgǹl7.k]:ç\%dF)QE_%留G9QnlW@E:>e}} 0)BP[ĴEV Z\fI'v+ ʙiƎTsbTΨ.,§ɞlڋs#q#wZD G'Z͵=|ざf]cnRc^~f@1]&]ܣ[#0c<2ʼ7G#(VGHgEi?jLYpE{螻Uv h9Bw1ט[e+Os8/5h1ξKҎZXzi*j7&J+#?jB}>9FÔ4~Vy(?U*U 5mHv uGFX |/xd`ݷ81/=#P} {XJH@Tn>:fAd{4:j3{:1E>woȽm]ݍ/=1̃98҃g=E~.snl9ؙojlӌl2eyXJwN~lvMk% e-˜K_pU9Hx.G#=xJaVHG؆_֭d/][Я< .bt o(g5ƒ:<$S'\ .{ЛOxqy7Lnu xײQ6㊱GwƘPQ׃]ow|9x1ĂuΊ:^?001~5̅ 4)G2Q@Rt+,ª8l|R Cr`;4ß#1U&qX_PXyԆ#s;=gK}'7ʛ 쬪NUWCW3D>Lm–XQSVbdL S\'};Nz D1[/,&LR[:E #N`G՞TI !Q>>enQ{0aOO)AU2i%PS=6>ѵa:un[|-TwܓFgw jʘw݀^xLvO w_/nj*ȏ8fZ׶ȪBt:9;z7q-gC!sh:" C&E)P6EHǞ;_ٝg45ӑa[e*Q' t>"IxМwag=̫wU5 9j3ָtĆC>s65 M=e١S|| *X Wf gõC]ם\ܩQ;T Sq"/"st1JƤ,h(j`W/8.zvz_0Y:]kYk\x<\VcA&fʳ_yMyXЁuF\Nw_FX2@iu3 e˯91ȎnjWh ň4o83\oPu; ZDf54rU֍F  2˥5 HxZzk,[fT 8y 3Q1J*F8OU~@uf>6QFtZYNTywn1=Ɋ\nǭ~mɵfc3~:TWpEv݊FS yǬD[GS[KC`A)[#`h%NZ,{3qB*•3EH__y>IxXT%g<6בW'vc1,-#pZ_WFHs.n$ <(a%1?Jb(l>b}*m>a,K9Hs^T??n̰h1zǫ`+hF|Unw(gJ Q4rNV/@dZ[uXu) nOKL>P+yKFp/z+&~3#3j.`|#6[u:쬄]C6fG{jx{lbf|)ْTG;}A~WHAY+$eZ71#V8s9rgd.L@ī$?Oͨھ -6=?t {pG.*9İ !w-Lt/haPiߏFG(iy l 3O]R>Zո А[ vF.赥n-%Z2lCοƤJ>=G/saT\Tmev֤iy@7nzG+|i؇ksYŰZ/>.8rN+;ܷo[}`*>OE׀MJ)1m"VN!) C`u&o@V^w0uH7vuue{NڬCWPCoD$tULj&ΏNr4I:ovl͛>9ߣ9 {.7d>b^e[WGd ~wN ÑwS"O2=\xp 8E`[3`0>SnBu2jKT5V {oVf'wu*jCU᚜ɂܒS5z))w$JYܿ_T=kTM~47S5ybl,}zt"VDLFz]ºm꼷HKԸV|4h{ر'i>ŗ Loˏ+̑ u1P}ţjU<*H\#9vR9A,ַLI?1 {%i+|y qb5ԑ^OMԵݣߡ0nuR" fp J+;a4_Sq.Twb Ǎ7a@?<֥e+ks.(c|:5b2J/({I?-}eKvE\.E2bIZФܾSU2?#J}6n~CT!z\0Okߩ\הոJGuxk'q"=ݓl-<ɞ8=O{@ lz_xVμPw}*k{j)EB+ C-Z?cUw*3dG;D'gNs#+[aB~;o{|(4YVoJ0jI3P˷dm:|sĚyKɚ,'Д9>k'{WvFţh=(^|u#1"ty?؆ِ+nYD?EZ>Ǿo1mr4#1MIy H*Lyke9*+kQN]ԘTKbs~Č ,vQ-뽙ݖuY<[76V/_h6v5*yof|SM?^̫}UyMr0Cvcluݮ;KِqYݏ,vFRQb bDžy3Nwg.\`@ñç}3#Uq5l ] ٝKajR W96޶˟ܧ]gJlZRjuo7ܽ7nA8Nx 4zLxOGOɤkw6/ŕfVeT༹\q;4Fz<7z,[T/H_tt76lsmeÜӎ|kC]yUՍݯڲ.TfUuм7{8™'-s樿aWa/p/B!URKju`( sk%[me:z!u%ǫki\~W1:Lw= 7YE\&CbT"Vd" ?KaAz,k O)Do0zmŦF6˒s3\}-h#pk-< ȳAܳ7!0g,>-Evnwz\ßhӴAõQ(y M7RJjKG6fC(ٕ8-|ʒ:OfeO +¡/^oR}PAؑ+P CdX5 fgu1yB(Ц*XisU/F+Q7cQuu37|bOk=.|NJZioa*~@i@ҟ1]uа3,Gb)36݂y1Z0"ǖ93ږ+f rJ`[5oQ= 糷l'dy߷wBQ!>LWع/EX}žq7G#k3h.6hE%w-nOcO Y?VG ivLlݸ~fDb0!b+_&JF+MeSPۭԝ:hp]ʑ̨>Bϣ4:Xz xz WwR dlx\=>TKHY^.Ǎ9;ΊE:aitwn@'p}y +|V_Q'G^6fmƅ 79i 'y^WAy"*pot71hL#n:ovL&n>S d!.ڋ]i[r>bR~+9UڍӠwB/^Gc6K0ӑV=\٥ ZrK 1ө _ y!- u1:'QhZݦq@5Pe u9`1=X*s>E[r\Ū!hc7)v,=G: &@Q W|B˶op ??at]ZUQO[{3Q탲"?N>E3aQ%-;P)q3q@ϡazJpWPUz _:,@D*WpmƖSԁE6dOthֈ5j%Xs4i27OGG%ڨ4YD2D_ԕpP.qpV(b46ؽ#>VkS-4Wp"Na˜9]@-q@ژ%XBTĠݱ-֎*yC&k#hM[fJ֗k,pHōᲖY 29ez8Нj!Qbp//׻hu1|J.1O0 Y4cd:Tsў_hP盕7R wtN~U91@j63S[W_){1YFb81{?$ ̀Add 8/^+էYjnݎ}/"cj8.Y@I߮_N]/Ɓke5Act}XNJ([ENRPzlj\w=uU5Z(K5:Ag77vxo!{jAA.)nfzKA8j6BCзC/e1aH5>/ a:uL/~늤*IT$                                                                                       kaoY]kG _yLv; 0>>A] ןP ~4,RvbÝ|YI4;+ڏGoJgLO2P꺎ubhȢ$A~ 4,p+W% ;ߑcJ_`V"Ҋbv'Gx-~N\^.}5a,*^K,7heT9ܻ|MX"&ROf-yd ^;8 _֌ǻ l w!g~ l@ pZeq0n-&@ZҲ TPy_Q6j:J1X]x *R2V[ˮݠ:p ,tTJe2CFilP# XHݻԷ& sV(/F,uY{$Ca2mǹop;ē8|Cd"U6KoSrm>*,h BL' hoj|1WNtM]xyLZ/??6(3ͲK?Qe[ 3˄M |&DJŀ|M6538+1^3Sc+76x L*lf b!71ᩡR-y e c4f}=:epļ 9MB\K`V ﴲܸM#!j.*qk=Gp@QʺXխC<>MŒcAX-NZe=̩zߊ26}` }pQ[BC-sJN:Pa n C7^sL]ѯv^:Uf+yh"]nbnӚ*ꂚшsi]ܳSctڈ*EFJU/z gpޣzTeDR,_(|Ze!np \ST=FO*`B0uY m2 s 4١2}*@d컝S؈[ ]+y93| Q_ݝNaK??̶m[\ a WQC ] ;+ѴQ3 V9qY /"TqjlUg|mFN3bk{iemZ䟋N?p&n9`ECFr?kᨏ:o -RA> @ ϶Ԍga;\( 63ᖁqƎ&Fڈɸ,}9nV|WeBfRjͣG;HkvdH ,+ǵ0ǣ ]l ӎA?&0;Xo|\ j%pצɦojÐ^ 拭|d9mu8+_FQuشE xٌWZsKk4<2/eAi 7*RG}ZF)VOxE^?~BY+]6<"8b'7ca6r{e&OgʳterUIwez懄-9=ΚӌYԅ~GKgwRKӮakt(QV dZ"gwYSedɒ}fY@p׉suNe~%صތgZސ^T[ ]4f`+*cS}{& XCQ`"Y؈.:ݒS,y1#uZ vةòz<_gGU7!?GޓŽ݋REf4,eYf1=rBGVèxP]BVFi8݅\˞MIµ]QPa7O}خ0+]l+k'QwtjӋ\Dێ-aǡ7.îQGDLXZ/(Sbl[y0-ǚeS>|f8G6]םW#w~FSε0[QAے[Zq#3c@/3!U4zI4OI{JСGyƸT %O2r7Uk6=uzT QB%~WncNҮRT"(L b,93wl8Єo_i0z"tV wi+] Gǃ;ѣ-m)K\:]/nQe;? caj{{9|Œ)Uhh﹆?!]CO1dy}۳I;޴Y l#KKi@y6-O 5Vњ7s.7.:tlCҀkuJ%tkZL_ЃV[}07xUZ\hDr-d[2ĉٲ=͹>(uMvWK7p:'X[bgtd3i<ږ5̙Ԁ,8ЬA2?GSo@_'<%l+ = Ÿ%㝲b9Ix)?1!s/<(F %IKbޙ(+3Exh9ߴpd#5lan˫,eǿ:Ǯ6倹< ϋ/0 3j0f7}NJѧ؀׫$ą{YR2492]Ay4!핸(WӾt%LjH[9ҎΜvۍ+5,W[l>7Oj+=V{׉91cgw=wU{t1jOxQAM _m*.;}H\/ ӻhsEn_%^h,LvCd yUXTʾ&(rd > ֡];>w#gNlmYΑWIMk G,,  1gs>+kƐ ySrUWu|1zqLjy2c>l̉LiܒՆO&:QKŃf#cGyeOe5jaУf)2ec:#U8=_p`k1yU*DzpֹVH+k+3Hߚcͩ+&ϣ*p_%=ۖ ẂWl{&*oR|{3c-;EGasLOS{q Gpwc6Z9/643k<)N7D]6 V*|[~jlDՕ8F_w?ףd3$;u\3d}sRT*£HRQG,>F 7C ĨGR(e*ptdX(ǂPGHYQl3rY@54~^ut$8fA0uioqf=(^$-.謂V`.L9}]K5M:~|/${̐,/9B&QH*62N{g\!f#˝0t5OÆRZ#;\;vP'Mxa/k/tL$O@uKiL=Աp6e"ü$gف?/6[c+ʝ}N>\ET%k8;ݲ9WK7ЯK9taC!Ukv|gLg?H''MbЫg}zMBݏ/~6Ӽ6~,OTp.zg]^!լrZ6 8p ` >Xk邰)֍9n חw,\3yyrGTؔEZJSR : a7g[ĸuE aTn ;GUE-mpz9 asw4O%+iKJHC-1kf-ŝ >IpQ?llѫ3!p"2b^GGKoƶa4|O E 22UqNX5Ur?9nf[᪊.Uuf=-)y/z%>Аi ֵ]ptb=g¸l#|C]D[ HŪJ_YO1˖ m7|^TAW҂&# u~QbB;Dd1ZDw} ]Z;#t-"dMLE"+x gNYkx91GO8`VBw?&`J~ƎFShv"/:+HV Q{֊p=રB{uuO[atPBu>RY(96'Rݢ]k%K^퀔 Sɴs&˥r(`aKKsi<_D'RHZ~+= g,psG:?LszYoL&kj~3(#Q,2MdcME~ gw9c2` jӠ] 4Xţz٫[DS9.idXh /a_m `3gnU 4. xsl0WK喙켁zCa1,v6 .-p ?ѥK9:N?&N9LOin+&O&I7NMG$)$:K4;)=P%m"zXGkH*0͝ :q9fs0yp~ ?cL9GQM ɋKIcV9 gpf{:|2 1p-rn3eVkOZG+VD`ؠA=JZ9̮ɠs^,A<,w㰯=Ũf)f7"z'=N{j%uDkQi@1D;V&_[hb#oәg^GM hMm%#Ma04% t{_*1eTxlq2wO!O5Bw *xRĽ5ڼ jYI|tfcXx ~ҵ60lų(cT=C}=`юޫ'^66=@S(ɧh8QJ_דC5Kvg􈹥Fr; 1[ڷp9aNCg*ĴSäo[<mK=BK _KK,0ڟDZ68ij9 _Zau2H/(tN4%KߩUJ"]F>SS &cSMF"m9GCЙ!k/b2Dp069z%V_*C0::/p0J*qgܷ~^>%'' O\;,wD4L^kDa)%S){I3 C'L mU,ІZ/gEyԻ? Ĩ۬FM \n:*4x` ejߥF&v2۬D$<_9*FJhF$X *KZfJ)E<7Hc??V,WIVIݜ"'ш47~Kׇ7t%ZrTOG:12"8dPP@=o0ū "+欈VlrasX'8r]kO\: Z 0%h0ѵ}҃Ae^.^ .GS_!qµ|Tq@[R[t ~ &( 7o>7،XR->c#vֱa [ dih:b!f>ݱJᜅtŌ*QxBt[HT"εU!c:`G%ND8÷ㅸeVavph'F.jܝ|̥A R3D֕qY1}XJY*!V\j78<eyt%|eR*;8`Kt"i6i:EbK+JhBbcj+ntGj,b7P^g$!Bwj69 L6ƈd!1'G#ב϶td%]r+mV ZgIkRهSb.1Y%v2Ǹixa`/!x,gp/+`_ R:..삹;]0+5t*qAh7XsYsx3H'p&0h7wwj9QgrC ƨa%=g帶z="NIwTZ튧\1>Z `p<Þ]:\I¢ ˼Nb[PMU8 :IA~W3_B{!xS+,=c0;"+̉{!,xx\DmGSqT"'ӑuc{ /*ʫ[hS4H E\(mvt`s%+[Y"Y2` JRYPc(&/&/5]!uJ~jؔh^GJY+5硶W)}WZ{'A6׼{-_8%w0V ï^ZlV2xjpæi kEã.0 DQX; H6X6ǂcXΦS)?JJxş$A1 y)1{N;g L'>wZn77Χȗ4b) JLamVBJGC?T@вKy)! fCpl dHT`5b96)`d 6R\a m҂dGzj6Pc9Z+싱F nc2օҚylm3}\G8F+fg&mr1-pgvYYM1Mcb).[BihGߧ¤J,yUd[EPMhtF'љtUXDLJhS%hJO-iw -uE=&h![Ƶ ա4I6=uC;:Uo`逌Rxvb jv0‡ԖTR>utz s;6ѷ?t|93xpq!•XKm8DPWgܼKfOR#>Ř~-8 GLW>1P n"'\Bm ᫷35W7uxI.1>Ys)\,gFUC;זe䱐T'xn#*'S3L0 Ϗ2zA}Z81})W#vqBLkK]o.1Bv<&Ep+ZoEINCSڲN7 , M]ݕk MTJid"r٥dd%:r|e1'-$" 핸 |8j儩a˭p3UL*+iPX#1XX9TU^}KhK&Eޙg&9<XKk.``V# D) +6l=:ʧѭ,i |"dl cs7X,[TKǒ1zC -'6_r |`#,6!S䫭`U mmT܅,*uW]02 !lS12;qq +ki٨ToQqI{6vMKw]gMeXS^SEsa Ӛt.=ypo4Õr8ZJNò(h5_:D'TT g:$۵X!b_'Ȯϟn Q`H_8ȅW8[ꨬ_߈L(Z&mB[vFcٟ2AoOsc54ܖފ[2n>|?dQZp!Vz\"sJZ4יmH j"4xXR,@@z\Kޓ:[.Ӣ_[Z]TNqn}OcҺRxGc呤 jW I{6.>7Ҏjﺼbøz5f@%Y>5îGKw}-]K3#H 0OЁˁ"4d8SSSoW|`l䆞<=%Gf'W;"omimw|sHlis Y@͐jNW[rޠ[?S;zGHYbKEbez&/9KG7L0G5[>`t%CLнݱ)GOX2ʔ3:aP=X%U1 5hZìN)ƗL7at &r@I{Z Cb.Xصf IAjO=u:FzDF)RLy;hB: #}Lf h78׻k`{ryC-Y@1X^1Ԓ,~ c8V#{*Yw9.osªXD[G~ͿlneZW#]j<ei- #DӜ1$=q#_:a <bH'!Įhs"sf%RTJ)'mb&?Y"&ϧKxxG9`Ski4 mV>~5]Ƨж|&|k F83Ḿ.] W `4R\`JWG5!8?GdYgSrjpF#d𲳃)%@zJS@ǿfSg }8J)\VV a"[86[3<<.v8G@h0|Zb-ƨ(f+M[rwƨ x8!9Bt`pu&ŕ sL2A.1k CG#׌?8ϕýIE_ 1Ƴ-<)A,zY!ó*S@/PLT5r׸.W;㽿3ftsavhx~&Z\.^䎽[+Lb&c ob +;dMJ\ g1}M6TCHLT;I ?M]o''iUA5bap|x\,E6Z&zM_ѷMi[_!? %'ӹ<}[рq%F8?cW̘, Rr] NcE#Xƃ$d g z`npCQ;S 0pnJD fُ]pGGkг=K4xgn_`kdaȘF_]cl*=o 2FTUr5I9l0v>np 5{EEtn\-YYh;c-&E'H̥2M"$MPG93zA0^ '$%*3%rBH" .Dyuw lYhWh9ʺ1UHQdHĮ*ܔ9#SHӺtem=dNLi'JKjo9}VIތfDm}d@=*f|Z0EOďMhu7c|ZdwjȿKEbHy3K]⌓103 Ò c(oI.=d<Ƽ3<]NX8Z*dW)E1Y4I5 ZC%g(ӿ))] tS!_>Jh\l qP!yߑQ*|V]Ց=JLa t؆ K.3!$ʡYt{;rp6gܟޅ%[ɤ7 J*ޕ@]PX O;xIb>3:S,nn;f.#݋&zWHxA&n 2=llC{'ѻQit LޛW%ì1.OH {w?'Ɨ9$u7ǽWF(XG.\\] 3īJ1w#5v@dC=umE&o*sћj(P*ܩx{(qQRB Y"+ 2;dЎUB9F{5Qpz+N3hV ϣ;o{w:2;9x#ر<"yr*iNoa(:Թ,Kg1_D O淴wE[_J9p4pbPѠn*XyY.:gWT &'5qm\s-:M#j-ڡ?HQEo}%oSL"z`be9& ;}kh;EZ3،36yw~*Dƽ$\YMFXW‹5>ḴA6EK!bba??n[`tk-,n0S*lU8Aivm[8We3v( uJW# 29-f[a6z}~1R7e*ecb)-Cw쏿H)E};ATNMk)J\H#Ɠi`4)?PMn]On3=}h^,lc xSAo:9nE/tc{*1HS HyD ^UG }4ؠEWkNab3:ːqƆP{]"Զ̥!ShYD#3 Ut]AIeUT_G3)N5K3cAVV` EZ: )52ܹĞQ]55nVv Z|JCt8:I2T: S&>)"UѠ;W Im=MksNO_HutyKYGB6}dWj:I=/mMHyVEY@4A5w -}ư,C]e.ͤjbٙ<؍3ֳ4R?(y7BSs.Qbs:ihGNN!u(Ø:"JILk (B뎲jO#8PώGP?L)t!F'qm@=4еat;Ō߿GB4>B%-ac=G{#ɴϿ=)3tU1>Y3P3%JE! !\s/ԷK.wNMgR(JJV'Sd,Ni\>^I-Fv3\uXAvbuqH^ɐO|+gIވF]JŤ]WFSU} ^oGꈳH ?oǂ:t:ưJ\BYoTPZz jƨZq*D0P_j5# qv`MPA14+l+$|):zfO""c_@?=Q vWs`όʎ8> ݄[A.=@r3,fÒc;}^=ɻP؆RoZD (n.;eȸiKE'芻xuh tJ7ga,lPƼ ?CzS:XL_=KԷr7U>+EZ_YH -[j~QƐ p8B0'ZB )%V˱M.J8:bÍ@"E6ٙFb\҅P7&ҿjQ ]\ #7!Di{טN&ѭ}T?|92,EDj#-&-Pb_#Jb8UUMY48Mvjc㛖AhwRPKi՟0ʾFoo~@n-KX, )L_H,Ldsk{bF);jAO3qPU ]B$Ÿ wTa~WG9Nj!J/ cd?%&핣qk>w}谰Jj^AU+l:|t!w q5X{rHu@G3iL~P`+vTa4%vH9 ٗ8ص_(5qK-}Ƈh7t'N[cnG>}߉.G sv#ۣe@݆TKk?\N`de#VF\.0U!#Mkw7m5NZ" \ trN/}Q9`)E`>J+?/iGig, հ~%TB75QlBkV7RDh-"I O:TEj*kª*+:ZO\Q=\6b=b ۡr68{ϑcA.m;:r]P|GErjB!5S᪹;FjQZV [:]=*;[KTpZey*lP>Gٿ>9tH״vW]0の\qm;SCMDR Q`5n:E_*~agR%zf*1?F?Ygs_-p pe% c4nA)M4$)A(зʻuW{ 7RN`&͜b} opJ[#קr|=.hzg؞ t8T{b%zA2\R'mAg\{ uz<3WB%.m/D rH .'c<ٌ!1g;*tQ u:уC}pҒS[б䷨Y>B]Q62,jG]\;¬ x3>o`jho V '^aDg ,`: #HR(@Fd}\<_]zܤ/p?4=1xax#q54-ao*\L҆fLt ePIH:%s2aףּo{% naV1[DFPl[1K|<>3^3;0;缹~]gnLgCQ\/ s`ɳy9ތ cm/sN=Oq{:{P?oMa>YKY7gbGXX|= ;,ƃ1[xVjUqǮze;LjtusEn[fŨFl\Qd(|_22υZ[YV -+oG.ئ?Mu)hnB{/0wJ }`{uV˺}}82ї;kэ 9!ݐ} MZѻ9ǬKqc Dw*a7u>G`ZJ9d7G@!GW33Yl')}trc[-Ļ/بz!19!͝AR.>w ( [nGТ<}{r>a8ysg;sj;XSWis˚͵PK^"q/Dh|~GO䫅+9(Ug8z*|ڛ] >\V}ts侬Jϼ>LCz;ks ]˰>a.rS&cU|.^H"FUpO4WnHrfO[[S' )pN=9wkEc=l}>{CD7c)H3Doc緟+7NJ q[e ra~^,f(ii.[KZ.={.YQKw֢㦸P꿪=WD/pL\a-c=Oj=X˩Z>xm9ǚ,`&&lӬKaW?7OWc0S`?϶(^sףo>*J|e3wz40l#(1Ox-JᾬVOmJHޖױBURΙ2`9>w >V%}kph_>cj&qdkL= |4ܚ.| xG/GĎ`9rQn"XLCԍykľcd|dO&zҕ'Kʉ=h;ɚ8{olCp5 "=@vhf2f<^wcշ0}}8ٞ@tj6UZJ~QOW9KO4,ߢ*,cފABedw1 O|]|(Kpxx2& ) y&/ڗ!c'S.3Xi'3~ec`[_ˈVRu)E&pqtwWڏV=;F=|7ys5]8Txܥn oa{f)oǧ(5 o@e81;G.rw1nO.xr1wE:ʑ=Xq/LM 覻a{.z{mť82iuԱ|3ȉ'JhWNV2ʦi$I!g4LΩ-dO>4z#ζ+~R==z@R+M.it8x?N\k7kPc\r~<foo+adM9j) MM s>xw\3D̦?RK-9ކ 2]h[)њZ;g-?T!P}5 ,m#_>hK_*)vt+.sqo,/j9 f"ip<6wc].\"7˗7rbOx3M#~`nJ!4Ji\ aAk=0R޷4`ٸlC/ft{c7C4$LD}??Z/+B].Zaڨrp 0bFleD3F4=}%l~ҋ1jԲSkYPMNPRYz֤7)(]M"Foe 3t$/0l]!2e$Jơϥ([03+\- 34`;gU=$2v5(15wd'n?Fx'{ta}sJ =|إeˊp=Rt ogz> U*[f$ɵS  7lo%ߘߣ;V`Tr^VFlh앖Ȏn/$RqYmxJτ Z94Eq/,f.j_$(՘ɗbwUEWpXF=3QQ( "b#pɍ3Oxv7,4ֱT_AH%+melT^:Ń@ȗjaxSiL?Qo^ky4Hǣ::awoJ|iMvv,󔫒 V;r;6P CB42)^ño`ts{du Mc򑛘}tt4 ^ag3zX_f}#d7pǿsb.k7m;+bSdס<eiQ!(vޡƻXL::A|홇b\y=l}cV1N[z8:+5stUZ%g\Lm;nmp뮫0vI>yv# 1 ͹+5c{r-*v; 稙 & <ڴ=et,gGr!g+Y`GB/# j/RKB77ԲeQ+3qYN:(”+/aK\;SVC홋c~`x<bcJ`Pe NmVVk?5oբ yzvShv[ÌXf<ӹM4H¬Q719Լxp-΍7?cLi'.-@9pZ/20 <ruOy%иe&`Oݺ %q"ͩ,"tP>/Fir.˜[%xw0_NGqdDHam)u)d猖:ډzr%s'28nºt;\r;~ 3 ^ǘfز ؕ$kX\~tT _]M%]Vpa)@J:Vms+lf⣞*VMԲ|MjBr 09Gͬ K/?Mn|>œ һ/Ϙ}agl|1f_To-sPl9)0?|fųp}ys->WʝXX |X;L:&ᮕ -F39pj (tb;x}3kfuGMYjV J͌=,[ݶ*_ 0ڙVvfܔj˩O])4g s?6\hAU0PϚŖ2φwr˂d)%U@xqJ`^Zd=kѱHqpᖩ;*^>)Wte.:aN1ĺ9pT~>31W,Q^:āAo8p̄yΛ1RoF9l3L^Ō/*x9J^s\U\R[QR cJAjޓxsuJL ^c\ʑ'!K:G, .ñcT?|m j?c' +,X:NbL0~|zz6ڏ+4b/-sY^Ճ})lS= ͭxň|*0gL)2Z K&{?{;pוǛr<+v wɅGǰn\u@"6C`$3pٌJ{vpMOO]i©3sr|Bmuԕ{w.3D; 74MGKliXjK~G_UlAǽy@@=9 :^8qm-oeY澂݅T{= e,|?hP^e>YM !xjnتOv,լzM34\a  >D#dsV:̍Lv&B`N ]+%_Mmf!${E`tdžqa/T]4i7GB1E F_exkb Sॎ޼%jxGM :ia:6Vb?ښ,YĔCWR> 0g>Eϭ 5[8Ø5vrhl%EubX?)C-0s!ϲEjL7m{G1f~ځ&n!qJ6Ǔ]|=Xư 2 䝚k~^ŝr;x8ߝþH83[B/i$CePAk5~a v٬a~K5 kVˇ<݄{~c˼llRg~4c }"➹"B]ÎFݕRq[ 1;QMa>Hgq(ezkwK'lyHy<^" W`|]Ϋ}ēmwMAkPw]> MvY+/Z&xc>h&:cλ`^4~eQp;?՛8>Mn4@ϳ*>W=8?͍s7e#o [+V,m{ӆ;pAkRelf9=LgM9eWB#l_߄4vpm߅Ky[:8co>?N_9ެUj0x/jj~j])K|%wUsR-1V,%ӝS=ԷU3Xf5rS?4,XN7箈j,3Ts=bْK.0= a>י[g1.VZfV0ޒcE>9; yY77wӰJԛZ \?!72}ZΨe%OYiRtSysJxҞkFgpNoԉǎ< W@_6q#-eM`q>lal7~ftkoTk1"6{>-Aamܛst,q3:{s|= YD+2-9ꅜu=9rDw4lgmNB wugNKb8J;_ l??DYʄ-;O̽Kd 3jG_ӇҶ%|ޗ/hyqbԼW2Ioߕ^)fg 5Nˣ],;f^h-[YhDO5e`-^K}=tx-7#t1>tt;`ϖUv||ԇ-MVW߸qz+oĴ-.|̞W;0fs53o#ʜ ^q~^^GU|úJ=|u<zoۭnz<zC'oqT 1jPQ3[qdu<7Պ[p9SUf;pآ L9=іQD̓f ox-ViB=^᯻~٤e!O|aP]CtP2^_ (O^xm*7%b+b4Go#>۱r N5%ߛpqNjD?cS/f9oa{߄ ܱ⃐qt-#fskƉ]ϕCz ƒۙr_r'}ǟ7(ϳPr#zCRux҃IZi?YK0bՇ VԦ먌rV{*9YJ犚uj~ o% y)3Lun =̝ʢ֜1̜=ZpOƯtzZR~M1Kx=*`dsJFʹ!؃X9ƅoyYr43Xɚ 5ڪyn'u[[K_!g_q{=h.(xASWr1D,ykWl_gGXУ LiaΦ}MÉ}?5T^iCO^j1ư49wg&]#p< ~f3+TQK2F͍Tt0'`Le\sYnյn~/%:{gl4qN]S׉Y-fcl,B?A87~"K iN  fh8FzB݆ 3li Wr[Wr[9[dl{J(K9QxgoWE`y rAWD̨rN|tșwDs[ZƜ{ט6j5|)D{$lڍљpU_:uyu,UMq{Ab F":áXqrf)~ǂúZ [ng]<^W)eK Ұu9 kK9;) {iv]Njl.|djWj[G(nL$d"O HX[X%2:(KNUڢŶ v9;%{1+ك,X%1Ϧs~COx٤]h 1d޿cz`{|xSK]ώg8yv_I6ܔrdxߡ)FkV)LĈV1/ԘooZc=G'8wڜ?6yv'+警M"d\ȃ Px;\ɋ֋]ss)돒S(v9Db^*"ڿss<܆%{)dA3) I5³+`4ea54 C0|MG GM#i bZ&~9j70i&41r%[u~֬ڎ.8S.r/FfR.:+g/J(x􆆝c42 kyhԥjDs_4a \(̴:с;2t3-'ow:C:+8pIj vV9RXi>RNα&/#n}ϝ\יwqGd5%bLB:կc)lh*^ 7{D%܇C|0N6gނYf53,8%S^ܩ" .eOjF5H wO +aK;YgKsgLdԨNMRzLɰ*WK9JθnLiNo/"qbQ-s`MܝcQe&t̨Ġ0f9+E,z9 bw=&{~[ xcv[AFwF!cce Ĕ0O4‚6X2[i k6Nc'-;]nC[=8(Dv?Lep5MHK*4y[Żd0J" KON,?nN&3azZoƆ%5Uʮwxt9->TqrG%}f_E+a-gN$1 ֈ8NBL wsX ^gHjέ0q?dϜȽ FquE, +1cH ⶙0YSgN]Gftk+kI9NVr'%?_R2W5T-p@1RŊǁ9ۼ/wj\XcãbwT+rݩ/GT/%/$ Փt1C;_|s+^ػK+ޛ`,8 D*17~Ƨ"2| ^^?% 㔡o &'X59a19D[*3Vs$KOґӣ\o٩ȃ,/e69k|Q0K:^:eu|_Qz۩5J:{q&Ulދz2y oݪDlL#~s!>2iv: = gj⃒MUҰR~\ż܅oyRN|ϭQ00w}LΥ7pSPvp.rG-:ݓ8(ڽ?0 [=3s8sUgEAl!xVgBvSͰ &^g;sb+V|f_(OdjLk!?;5Ur+*cR|̚J6`|~J`+.Q$bo'Fs7bM9#׆o3ܔLY rҔ`du.6ŇZŌZgعj,^GGQIJqE!R7~4SN3eK 9a8ra^W֓HȍY <9䒔d|6IݫUUGLJM|8ϛ[cձԼGAG2dyBkl}׆m^57>D=WK8ڔ_X5\٩Le)L;|$XPy/H2ȕbf:{=&9ԞG\0+kА(2٪p.74_b/u7:x5ޙ)|̊WOĂRX`B-k+fiZBs/nj 8EPT}S l+{7b'v, ~W0+YԋM=sI2V`1=V;A:|"06rbJC ͨa}1( ɕ+핹}$apCdk.[v zkwp<+3z2ֱVc+XkAflٔ1<†y=Ovb'vV#1o'.l^4{>ZJ>xة[G5?OoyrEo9!C#G7>־اY |}"\g-ieov3$\|՝M<ꆔyjⷥ ~ũ^*⒝N]= 3~y';*q-5OYuuP=&ծĩWPU6T0eh+jG|q)}\E'j:rW2 oMr`{i۪Zx4>}wXN T+C"xp=zr0yQsKAqI'{2NŸWFYH(!a'_WA'YqX%pSzؙN?Uƻ bGsj- mݰs]xB}„L?3g!w|84ʙ(mB% ]3=Xˢ>,T9J 4P"^{A;_Ii,e۷ 9j{;$kgs̞(~B>ިf<ܒ\+6dC8#D\Z2V x`?$J¶.ׁSi=9ws6ו˥OAm?֮u5밥 Tf]\lÁSXܚK7*$v@"\ѧMx>ON>|?JOگx1e1{&,g…0 ktĂYa?J) c ߑ%ܟ!\ϛ>=Z&dRe[K] 7g܃+nWޜJ/l"+fEsvcsyrbm,R }׋a C:p%rڿKBη 6'a//ٓY: ·,#mķ79-;I3?yazҸܑ͆peYvº {ͦ!^W\< mID\4|^si*;Չ~]yҝI8a~nl(T[Hy~YCwa׽A#ԑd7̕{DŽJPg/N>.lgnS[Nν |J#<ĺBԕ_29d͇1ĈE^7ZWc |E;]pKaMX?:SkJ8b114݆% l籗Nl[q&bPr8xOۖK٥܋-/WN%ҵx6*^F,GInzFFLngSWJw+#yz ye f;_Bb"P+&m!ee:@~\x/ArBlZPʙq܂*[Nrr'ݻHX'ЁMpeGBSѢivm]zh;èa31EIkN!an1V7޴d[pfbvՑwr_ ;) A8Vn^Ae`=̿DZ:24G6'fȝ-eǕ^&δi4Pȥu:̓+/KkN|u+ r#v`'EYu8 e5ʠM~E nf>g1&)Ë]\Ĕִv|Tah'֟.b荭]ivKyl)7^~DJIsM:dF弸AΕ3% ,Dǚo!yDU+LMkN{#kw7}/pFdgCJs& 0aRhnC9 Yc0m|o%NyX0?d0XjE:)ނǟg͜ǧ F7;XSI{)>7B79-jvFڔ=Y YUBUGsFa4;f?u-YWȾ=˰q%|}6o q}\ =cvo^iBV9uf\⹏ J։p!Ȗ󩵎W[hA3en p\[1Dl+KIXާ9F%U"frกlnk{,mnR̘+n49|kaIR.n.A 7Te-"v PwɞFPʃKzOM]ƍ%3Ӄ2~ĝ^Xw&y2J:7$0p/~r:\*ŠD, 6fF0sV]g6݅`lMҌ~5N)Fwh6ƮfR|Bi '.&8(G{9 'f8}9B2jt ?&_r̾;g{Rd|>Ҡm?0VD\PۘRK1'Rń')] ygNl}[rv~v][1۫Lo'.2q>~V0ؕ9MD-ə׍+_󵳔;QŕzxݘO`ˮ|'Nr B.紶ˎ/XL[XSr SU V Nx#9ĝr Kʖ/蜗fYx@ɢknݍcQB1)vqf v\Œ YKfN#mF~F8%`Xxx DHi2x]1aUbscs(ex}ف:3}/톼&yEEx߻L9q7:gc#qD'B)j NƝ# }&̋HN y-\0dMBaς;Z򝐝S}h"ى}žyl7 3q uܓα]X(JwG# !̓x"ɍBw*l+mE b `e+sd3ub+FC_1{ˠ*I7yk}ݧJҝo_޹n 3aױֱ~"~U ϟ(W` v u1*d^=g:S%$,(REu:jkh~D#GlX3φGZ+kgj/{V_qϣnjث6ӕcnزkVSZCs:@s.d`uVu: iVA_Mu|00f5|\s:nzbH`.~akVeGëcĿfŹx~D3^)hַS"=~ v Y}t.}WWݷj D XNep>^=2%_&lRL:R IP:ޕOno8QkE\!\oAy)^˸o vTGz:6Lk+Uđo\ωDŽLw`֙hgޱ2rf==nZsy=!- Sr$u_dX)fTsS0o?,9#?1o]" L ~Bk_u jbSe.^)GN%M?|e3jy.{2uɽaQ,91(_xΤ\=쌷t ju;RߛQϒy5w5S_*DΕ8)_h>7a2+ VUX(Dv@cz[tE_lz]v;5vlrΞ3\ m*y M=9JܐO-ut4)8Gn;@S2 RNIr{V[BÍx d\[ n3#_̱ ļqJ)b?XATl]ɦd@I5[CZ3ro~$7r>ؿgMw2!Jp>:f洩#bۦ^T̀2nՊx5IJ98tu= g*YƆ:cXnCljvD2ݞHq=;nl )ʎj䈂[j虾ȚkTHe)O"IXgOgģUq2 !%7͖XB[% +.&`;S>#3"N2j/KݪDOq2'#utO܎0ZHT꯭zy?HoiWN`[ٵR≌+~gNÌ)EwGq X%*+ r@!6>?Fgu9 l=͇N&zה yN"G>et\׎oӃ\Hg^:h!Za4Tp+<ϙKLv.ޅ2+Ws`_ZsB#SJ__Uq^7rx#:5X(Y8G'}YDTxwNJ-pNǔ{b>{`Rz4V1Dqyڂbw2]n~=ς6ٰH{Wp5*&V0G C G( aW֯pro[ٹLau|>\-Jusr4<$>ypڙml5гe <[`<-:SGW3^-T.sBh\@%[9@eJ>#cDiϗ3M9I԰]-;ī8w|7U ۦ!v!5g\abNU vPU?5E#/U3l uа4=hĖA3́0gj:Ѧ;7}tFJ>J'N5}dPIǾ/k 9_9~Ƿ%X'WdDo=ad<]^Ri% U5ehۦ$kQ6t'bwEI?Xw'2kw %ibY _8}5 -uu*?!?) y~s\DL}) Oj]6~sRc4٭jyۛ۲=+|ZW\Ռa\#v#OX0ڝ\64&ki;Sd_뵚9Ry#Ba?|JΔR؂.kPgs1V$T|\3zBN,a"3u_nDAzHäj5GTz]jrn6YسE30Ӆ>sYq1eOVkW'>0Yd\״3DR68.J 2(72?C@LoT&F[GK:˒1:~klr >-ƛyhT_1T0jIdk]p|a?ͳ]| k?t 3ުjhxAǏUj)43~@+&&S;06T@s,<;ߒ M=zt()aw]}\s .h9:eꤦvG>FM;(\9x̕/:1c3khʙnYԫ'ز)yIfɦfV0 +ul^ƞ;?ʜV=3_cY Khb ?\nZ~i.uST-Q %+xM^jx乖} dhgzreJG΋vb+׹N\xǑϬy䷖ҳk5e^k&V]E P# &61e;)Cui L>w*;MGӐ|hpFQg)-JŶ 'Zt-䊣WZ;1[{ܲ?ѱ}8saquuJњz;ڜA{ܸ>m2XlUuUk"^} -ֆ!2 `m1ϯD3q %%VS4o۱ vTqcl,TK{{YН;iafl(3 i}e\fca2[#^ uǨ᪢p'UtuInw!9rZ=gbx9pJk*ɚ? hKw#f%" 1Ìw/T!l!>ǧ=g>DGf@00>Bx DA[42wGx!8)zv1hT (xF쇰89Rl/p 3! ש+9N>Yd dϫ&C^8Flj=wtwEJDsɒw )]e&ߖ%f5RĜbIN=d[kzOØHpۮ΍rGJ3[̟<ƞ*$MTt]eh=^O}sg&f<% .4fo_Ķx>1qxU.Qkv4-ك QpcNDZD؍;pǸcvVUDZ4 cGxnlUZ~[uxBn҄??\q/y~H*e-,Xa6zŢħ`LׯnNM cԆTn|k7 즒ns+oWȸؓ7bo\Ĥ.`ڗ R񩓜äafu+#{s[yu;TFIa%i1ЅGK<Ǚ4dsoOpg/\bǻ~}*]*gNz9lΞrwX5/Q#ʃYx9Nw3K!]Sou51qROq<537kY|s'..rPg.iA2rl21S7J)jF^ad=/=qd\PUp7/3i<z7;0J &‰϶58RScCuϫV<܊g,F~/=*Fkg\[gϿ{>V YIf0b&<_cW6"?` B9p^#\8 Vۜf$:~wtJۙsx*~ ?w[&v+Ox+͸Oܿ[?:ΊY_ AgX"TE7Laϡ\?_ŻClx'v01 e:c*wNXe*Zpx|Lz{Ea\TNSA=ilBpR.ӚQ_͈*,V\ D|IVk#g;M/6Wݘj "_GU;P'5fLrFaܶ݉b}vAp6+BJN-F3'̿w%.1™?(<66nX=?o?|:86oLYJ4\--psϴv|=^TKxp#&y-}wQUn& YBXt9o2ƐĥIXaڵbtJ\mXr󪵜md^WK̾Y2GQwۋoWs Wƻ|'W'7 =ϕoc4ՙKxGfu37|aؽ%5၌Cs֚ƋqoxVdZla1+xn3?pbe#\ w> tQSk+G›O6>Cl fQ7 DhxVÊZb[AߖJȣ |NA/-[J_h۽ZU[$b}3¶o4qD+[ÊO[ %RK>=X<qvF1gidnţ$#Nxi}DE۟*X{MM֜[Jn&甋rֻ"ds73dL6FL`M7p4 k7hU6 yy0,EfdKoqyG^yyZs2MQmd {e]57zhyt3FɘYKIH#uaZMbB/nQ8^=:a^nqvMʱH+M;GhD2r9G~uDoJqw:K{6gάėMͅ]{PƏO]Yuڙ~ vRE{e\L$% QAØyKC7ud|?7pl[q%~@sx"IÄIy9Gg֌Lj$6R^+ae;Ih {+p_ުGJتc`ThW ?7pYַwm %u y6V `^/ v\M_,DIT'mohTĽ&ߣ8s[] dj|YM~!rzfñ< ~AH,D]IJVr4p55lDnڏrޠj&IL3W0'X9E2>tծPsjY=ěN7ٸV;pE$0á6[1J7G>̀XKU|IYv 6ޡ7V̂ ,EWsa=҅ aWWdS+MtbEgСlyQ™Rv e{u*کeᅩ+,HXcο?Qu #zcD[_+q%)#bv3"%w2r^crZ^cA&!_W1D&.I)~£o v(T=NroʉSp""']"z)31: wq6: ruwX1;O*Lld&%EK-}0rzSk( _B~n#4ԳI2r-N1AF s[Wr}vTڼmQfTo]jĭcl7SW1E"Tn*r(Z`ܩV1 ~WΜGZqQ240{ 6R@, ٣h9*WRy82Gqٝ\]](tvbok)3䶌%"FZJ ʅRN,-qX-Ǿ3E71=V-cWpzo6qZnJ'hZ JupUQ3NdŨ"0̅#6x2'2]no<'jޝpۭ&#R1`n:ufz+]!skJ/9e2e=F\ŤHޞYI~(#p^nѶw3,#1wZT"8 /܁ׅڡ x"i?cX7dW;`s{Twzo+]ÙL,SNșBzKJk&q3u Zgvr}571[,b*;kx,~X[ )0,*Jw={ PO3 35_U,{=:v].g*DLH̑p$> y\=2{8Ǡwɨsc,zx6^]Or1m .`gLWZ7cX:˔mEhМb)=O9k󷞎ygiTEXxCB^dJgl?Gɐ^^w{l8IbX$gN W50ʖoӌ(ܧg) 3T#ka`IU-0Ɯ=@W".OG# wKƐߐٜW$P-%652gNbj&f|)[ICda]-y҅ZXuGm_M{gN`M&G[y qa7JC;"v7P<frv{-e`?*~hy@͏R9۝+Y󹃞K)i+ra, @?#}}19Qo )O;q[-ױ4UFk`N>kvmJ!àGq K+3zḒdߔ=}ls}ݳG~ J曜+8ZH!뼷Y%W *ƀ0pV5^̨Xa 7LvE!XR`bS}j~\gNT02v/b)b~> c:\̤aIp.7z1`3Gfhx+vy `W8ܸ36ێ;xv3.ӧ&HFoRU{KXEǀn tg=6;'5ލWet =ebWx8k1C?Ytǻ~!"[<tUC:%8t=:b1d,;>ct6oNZ !:)n76 sX 3kNjir8o;R|e|QǛshϋvu߳ `zw ^6|zDjdF)qKSw-o1z ޞh_{bּ6)`ՅsFfkIj8m\] f+%+؁g:,v墍DY=^s! `ݎ)!N.*yĚ:2R뢌nq28/Ǘ] V^q=8 3erDqp%B <7̚ꋞ&z%i-(KE&,S e@n1x3}iTp_q~$} +b6B$~A'q~qoaowk#>veΟ(:j~d\fF>d*WuaQ/ߥ*8]EmQBGŊNu9<ȝm64\VqF%WyW 81ݒ~Gȫ0QZa=_8Px8%Ak"6jzRTNOf9E#2Diswzj 3אQӠ3f`LdtA&/ҰfO,2p$<[݇B#ob}-Dl GDfĊKVnPrkz 4pI;lʣr7vm8Ζ6ȝjsfN-~Ƈc7{Tj}Kd ѾUBT[wmBψcZC5-1)AX{m/2ũ*':ǕB:p|_*@öt7;n5"֪'"EH'b#RN-cJ|PVCJ7ƞ۟8#0 ~5B$wqE~z|%Ip~FN_(A6'rsТ4R#۷?&IXx%]aFplݛ#,RU,/ź"ԟ8x*M,֔&BD>ͷ]bx=])õ|4N j{}9+ŕs\yz2,ҕř6DIRZ28Sr)K\Oxf;o5ueWKBcRpKXLtU o:wFҵV8;9 K`i~cgcsld%4v8[>s[.nSk֑t,*,u1b1LM7Fg:r5贤16[ZT yob5x1>ZO 87, rh֋VDŽ^bu|CpktSnΩ+~`x gņGMӆn)ZuH_~Q+-V> dB ) 6n;dmI_9f*B| w~bN3xaŎMe6A13լhce7Iw$w־Ō^kO<nJz0 EP#QzG²`WV VSl'LY0nYqcٿƜ -(#Q:;U+1;s:އ5HQ;Ikp=?? ͏a_l}m8pZkvۢ {7 1amJ!<)I!ExפbRVcy yS5pa瑞[hz1.sˤ$OSL~IvVlTQ\c.E?Qw Xw8lF;QMzܮ`Ďs9f;DE3.439a%Ӿ, X ;۰xWM$/>E\k6=~YG3Dк"w6-r=|}cP qӱbgW$ ǥ-p(7N5bu ôl4FYLhZto{c-Zm]wwixqwOV] q]@Bw?9{}TuAM}4?d][P"foukz yI׃ ۃ;6̍]ȍN9[:s 4d'i-#Y"ʮ~¡o_qsHEY*5ݹTHT%wSpX/nwahg܃%[]ѥA?';m^_#CN,|Q<*v#y[n삞0ʕ~Irnlx#CAv V&X?c}X2å":]~4f[Eނo[;P<@5c%bJnö8!Qcb;<$`,\xThc3ypM \[NsC#<͸=ې㍘€%B֏|EKm Wj4TgmY]؁X > -u9X6i'׷/T-`c![JN6y35W4Moh0`YR v4#g>v ;13ƹƅ8Ü#̸5{?7Řq/8B_2'F\]kL}S0<3s^\&tԜqbH +eNSFIӸJL )Otd}ltGʁȀǦs4P~Px2=Zi1oY|vqctG[NeC7~3R_´vKuk?u]_njQY_#A5p2:TyT`Bpb,MŘ*d_C{_pf1'Wk]=$ts\UChDtFZuKo1 F0:%CB H9[q"[ TwyQ?}faoԼ6*ΨwUagNCY"VU\Oj2q'js:Yr1kĵ9<'$kD j^eeXj7.qnHS/%eh/jIjn_'d[s 'l=8wHg!';VsKGvfŖF>OuXwEѵV<4`I"eƐX58å{e1 j]\ӥ{.b^rOhtҰ-  شM|yZE4l}Cv8nƊץx]-iUs.{}W/^o3p.$3[=zБGlmX6ƂL9c0ǯyȘ[sڂf.v\";Ŵ`w \⇂.qYW%7x Ņ"n%bEGj@+O .ЭGrtߛ *0Hi)<'_7xr}/jMta!K^\2#{2{aޯ58wbS>fZ볕n&db/o.na9ϋc&yԇe*r~>b,Oz-\~uN\yүr.^KxG|yJaLUЈ"ܛkKek i[s9KhZrNhśɘ4GeRk oN)duM>qx$;7/ހCk)D]bkF7;Vo|Gт^taGl c+J-šcEX>?e~c:bww K>c$FpZ }F7]*?Bi/3VFW4;ǢDo9i%dECK~(w x5/LҦ3INh9_2.lňk'pd~GEȜKE%:qlZHJΠ&20 (ejpaA :K(aR*|^R. |O-ȸ2 V'k:p6udžc)נNL72i#f~<2OJnדs" V0m&h>#bjeѽsT4*1 si ݵh[EƼp39χw{X\yo1ဣu8ǣ<Ȃ{+3ZCY5aנGq ۰y;'y3*YDoЕ)NԹn!)/5}fPsh'܁o ʰ8I lWZigagmxؔ7kC"~°rBW=AͰpEF;¾W`3 ؈Q?.+ 窉.]6!в$,/_^ 18v3jp}7N_>ܳ܇Վr~%;|y@Csć6蠌sPke4tpYʡqRx.N1zAw;[oQOG 6*lwU~,P7\]m7 _Fjz~|~ݏWnҫd+8Jj-n]c3ӻX_+F5`d!m97xsHo&dInb''N]އSNoo?Nbh^n(zEl3)FYsMp]j%Tbt [;Ġk/t7&8&WيXvsĿ5_t8:<`^aP [' sWݿ0߸}ëmr,9=L`\R}J.mGwS2r|؃J:¨Gt 9Myp܇92z1ߑ{Yl levOt?3q]E9h; K^=2%GEQws:+ײeMtVo/uYm]xS{MF-j6ʅЗߤg\5]fk9Xr*أ-Nbf=>l`z< =՜lԑ}]cQIyguܹCKdTTV2sӾ)颖1o+ˬ>|Ջ'r(qb|W^W9s*M,Ԝ1otsnnF-G?tPğ2,yky_#?v]܌SUcb/O7~Tʹ ?щ5 ;w.8D>UR^ 8PFqvƑchBi RRkV`C5`LX̖h*sJxi 3#vfa],xa&l³ƈ k!ttev34١hVikʐ]ׁFê=5YzO L0f2ɚ7qm>)9;wVL7-۳Jv$gx*b[8꣒:!cm>xay~"J&VsWh3.Ԃ1̓}g}8} w F{݈Jtɍ3tK59cFHǁɑuZ0a4g4*1m&C;؀99T+Tߴ,{nѳ'vYsOO/3Q!O5bW]&IncC,5I{gڅcЃ*LZSk!WW[j`[QfӫRok1PCc0Кfy>X؋j႔fZūB'p;1;N.舌Sɨ'ŭA*:ܒqB\JMr_VMk-hqO󣭷SquX3~jN3U||S+Sl% v٣`7|e{A)8煊ܬ Pl7}يO;{JȇS$t)]R` {hZr5NlaGk!HC{ë5؜YxG\.v{x3 ac9YI%sB&4e͎7(`oBp,t sa6x߾>&QsҀ;2 qedg`RD́LX8eqA^ј$8JO tf}~n0TGNm /qqgמ*Q+R.a #L^"6均Vl5arV1H)Us qs;;.Yr͓ =<ΝY޼|J.y"UG>t*ʽ*7{R-rcNc͌K5S{? c'`N$$ S~AdnՑ;_htDHԌn)7V:Fk3b08VmBh]?=GM{}Zao!tUb`#YKfe@ NzB/lukzZ|k }8Ϗ?4T ̓L½JdL7XYX,+eLT2Ɠl<8pWL/T)۩$ 7S<9r+T9qЇb̝mm:,`5 vRQ&BǓQ' '͆_ >SKg =0,ya rNȑlմ'b%s}ޏ?]'C=8.Knz_0fOT|Gi)xXKdT'dYyJ'+x2d1GmS{'JX̛7pD,W{2:=8;0c T;s+;2֖)ϭy=ܘuLgqaC}tP9u8VX[.`pJon2'.52vMMdjɤޜ{̛_SNdQwFUI(xrp/ <ۃK:ʙBr9 ;p{67A|]tjzrO-NGic .|U}j6築c0 9ϡ+ }n!ǫb<̇A`&E>\UR*a6ǭMRDNV~8U~5Qpl9{t@2Pˡ*Γy}}yS-6qsI[ЃYr\p|  9%@>HckZ ]d o`/fNuypL1 }߃[Rᕠ n{Ù8r {^ O0eY1j3R˔ Wk2dI>ԵѯmїMk :ǜE|\[Y9;aC Gr) =6*kjq{S>L؇]U |ȏ:d3عZΠ\ HA` {`97,qjLV\g?I_MvckFǐu[M)Jz{ٱED+בRpE|dkO735h2Q}.p؜kmyn-_DY% /P>vz]s:neXseA+6Ґ#C֎xZoX/UqJZ`} ۴pPO2O^ARnh%Y;޹sNyQԋ .t̶lɷ])cmy5;eZgʰ.\2әlޕV4bCfvƘ5 ]CF<ٶ7_Jj(-M1B/<2"\lS MN>F|ۄ6nGCnV6䗦`ss 2&4KLtMfW,TiYx^Cnޜ'$)c'i{'X)L7rSmS-4#^IQ80 5~(Hl ?b}&L˼Ey 7c3jeǻ56`ͫ-hx”q}͙XcwLYj3v vͤ$||>%?Yw~|U/ٯ鵿&[_Z`=L/>əH -C[ZfT[gz\K&*8¢Nj՜ɍKzeW-W> w-o4y򙌱|v@ܭ .䠏[NRyz9lŔv <5jPVDvtGFoAa :5h17tzôTE܅Fϧ. k# #w8'ɝbL߫'{˹9DFl7% O? 7~aab~qa܎z[2_ua!.)4bZCM4+Vy`eom=w4䭺  7<01!~i8mp7͍qЄ2Lèb<}]_!,^d#B>ŕ;hqUAOO+8|bNG7ijÒ`btxo E2v߻2)։E|Uq( Ό]=3̋><<̽8TRdB9Onk'{sMx`7g0[¨lʉ{R~cgQ"6{gũR|Wi pw޸nĄz̚l0i [cfSNP0k7l6.⽕wm&?~@}෕0L u,AUxkqfF4`(Z+v.PsխǣLڗӊQbȤ40Tq;(72^דIL*4Q2dTKYzN)8 Xw:ӱ7.^II4dߐD>ڹp=6t%^\>ڍ;2ڞuidŲ><V2}/LAN` ͽ9?yRB7_m;>|F#\?C;{NZlӠc6Gl ,>Ȓ: 7TDM:cϭN%v硉8a$\o#! ziVOܨ杍3tgC%sĠGP NzKZsko}~b)gh/m3C )OꔅBdd ihy ЏFE#W\F3H %P_Skl@\B&7yK{̃38ro<8mjɱ#X'a{.؇ÿxVW{.J[oޜr\Lu ^gƙ%0+#^!c6 ^_qN*ZAtE3j2Wu!ӲڜcSJzg22 s;/ U#RSb_>f{2B/#vZ,Ԭ8#[zP>צxC^nˇnHՇ 9h(xmy!wԢZP)ؿ>K,C4jO Mo!.XFخLIB78A~]?^GE5*Q:fGDtBx\j&1Ɵ`g#V}Xuh{.ۡKՐ:6]9)*Js4 40JW3)޲e|M)ý˹6TRq}؈N-(*ѿj1x&5qs&F|X!tS6aw%Ky6Dž4rzRqj|mh[a 0V\͇*wrFw_wenzENXk"!d1&pmk !#7NgTf~#V#h|Oݽ`QO@~fY%:a Ebb,_dsvԾ̉B]Qe(+bumi+bǍe|Wډ3C|5x~#"tУZ{jfx;i9Yrp}7n9 ~ivg~&4"zFWcv<̝#cs~ [Jq.]g||_k ?r=T xZX 2ߍ<1ϓwWY"L{ṠbqB` g ;w~a%`['E:棍_.Bcl/={CQ#gi.* y[~k}Mlv,\>}1ds =w{Q?O;= PQ;!z])n 蕄=KkdU Z؉)ڔGZ n*Uq7/:ʨ%$ "ݍ9qBɳb?+!o7a =ﮄ[CfYs+PKSpW2n?ð1Z߱.!"d =٬\lo/rWCiv:dXXA"KZ[/ w겈jyZ!8^Ym%q8S)݃}faĿ m=^{D Ζfo~P n~Ѥ#KyD"_)յ< })Zl@9a?ć[lU\dU! q^oj{rnk7&?ve+ͯf[ׯ;4c13<y_?&TXY*aQO=dıcqmQ-@#&gUЦk6_O5sدZ* 8Xe^~@EKfJ68s/)CӅ}9VXwSva{o I~k!Pco{~o!N=C<.)aPY=|ˌgS]rۇ2ož:<=':>OP&g&N~(lL6I-A2#ָ;1 8ѭʌ_z<>Mu[U 8Kj3"nˮ8z=, j:T 89 ~ob#:,\/s]uxlTӁp.+-"pS$gc=f=>ZKuVWT~7v$*N4Lk旁 d@C[Sg9v1r]u*Wpn@D\pl7TiiADac$ 㰠oj_%V.VjМѓ]x[p2O*^r"zƵ~QsP3 EUcWU ؒj1ۜ"w/p6oM`Umg1mhe}P0JSo_Cݏdp.AR`ij&FfȔbܽW5;+C5>+iSf\8߈uXn˛Z\c˒&3݉zχ2)TI_O5?˝583WGiR@74e̾Whv:,'yvz辀Dj#oS-<Ux5TO7E/3|Q5&̙\qp]/_rZK%MGiNât}B7tRwtf`GlÜ- {ӥx9 ŷ-h Fg Xb%Tw\"^MQ$t طX9 SBm &Wpa\TͩC;PYYv"eB)݊؋$,6꧂J&(`rQSUXm,9@;7 ;T t&gI:q0$uvzR.dӆ _鮆͘-8 u病A}{uUԁ!Ge+uƻSSss:T1Y蔔ȝ b2~lvffG\9NŗpX41 G% ɸ }o퉷ArFNw`SgZUڱM+n[hX<)m?3F(ܧ[ \ VI1I҂ R^-a|?lFYW+9πYuіm\B%__S@%s)Hϝ;h9#jo>.FXQTq<åiPFQXL~O,my\ _m-lsfNcUP`LTLz}E姰>u5x đ?W~yIc\Gu*HCk)b" mx {0LáPG&H\ du7d)٬ʀ[^Qo=1e̊Q2'9vtFT/ԣ-z3`mқɁ=4^Kʗ2-ebJ$qI}Cxp}k:j;-\4ʀY9p/E񢧨~wየ HG@,ܘ [x9. fbEL?{9= MIz3ʌKYNYsЬU".v;Iei~w_k^'H n=06ν ۚgnl :Q+[dr1cPR[WF~SilMvJzwe;hTo]ky̵̗~v!}VȀj&M±0"5'( U4\&C.FpS!Z%CΥ ?Û_+5X mWkZƯ:Fɘ]ػjrglƆ݄Nɯ02yĐCрNR'n=vdYKiƧ. :sVfXF+55Hmlw;h L3 [vcecL4cܔ3x{ S3-pd Sd#4܋[l8FC{X?Q{|w6kWf4hއˣ k1f1,8X]6lUw'A{2mR.Ti d}+{vd-xϐ3Nҿ_dh0W[G=:7ct#Ol}לUX$o6e)$iڅFI_PIl"Lw3 M9ˈ'r1i!g)ш QK{o֗P~ 9C 5;_BoIUnñz tx1KئOL+xzR&X2YYUx g>܆d$^kr0ncu,7a4IPT3c掷0{඙oo3\ܚ Y1~rbN³Ѿ xc8 \]AȚu](|'?#Rq쵷v_2e΍Ӛ.bf<Ą҉ ëI ќ\[ sHYs{8IWMuh E591׆mYȊʵ|>Ԇ[32131y6^DfcWKp7,N6*4oiڡOVNt tZi){(`EM^ڋ'flzvK¤O`W򗷸8^k `))6M&˔V&<ȈŀVd4~Y/q{f 篹}y'bw#%j ,څ$?/} ,>=>+a3"MPQJR˥= e9݁5Cb}'1XYE#M*кYkɹb swSV6O}TYr,B3*" ݳs!AF|֫tɳΡ(QsI shB^ 0{c-sk+)~4x.QlhtB*66a\>ȇ8P;Y4Xa6P۞3כ13 ,aگ[ɩiM{+k}*Pbkk6Ax$7xߏ^"{tzK߭Ϧ&\݊'ر5pY˜#̈́uh4ԅYiYך29Yq,m\"xءal])pMktJr5恾&:{^3~T<O,GgZ4.qy.”(pK8Ø9vЕ:qZc3O'#ؓJu,qJZ~Qq^}\v#f497_q~C]ZXV[mLx!A~Omlnd[}FSHTiO3|l=8uR!NXc21i5Ff;c9Փ:sm){շX/ÑKtȈN?nëܠ]È:)%^j)Gd \ GG#1-quOO?A;w[q8V7 i]9)6|VlGulrT өât85 JJ4;w|hQsM2pҸ`7ޠ~#vĜi+Wb`?s-?݆'x+g=pP7jgq?8z 8R.Vt#ɥYMx6՜ ƿ&|iȭڈjp=~h "ڧ`90e+x>Z+Yb>7s>30dW9(8.ƕc^ڻ=eg첱Wr#>`͋Sg ~v%[2>?dk[%RAc.77GCc.a=ȉ6nBc>u"놺PXys7:ac]ӫЦOshg^nS seDCe!nm͟?۟ץq/<+ï nyx֌&xs;O~ilɓx<,|U[Qə^\|zÊ/8o?taOe+9b+>y:ޘdw;Al^s4[ֽ,DTɸtVNSwT}g;^٥_ y}Œ qIw& qd|PrY5у[9Sϻdlݒ:fΜn9pekr)s\ vXs -k 3Ɔ#/ӣOs|0鐃[i(7?6K.4l.d7* 8ҬzmO 7ċצOf{Cc>od fzz8R|9bᴽ`#z ыĘz1d[f}藘0t Mt;ِxڙ]n{~F_pCm=t9^KTck8b5msMzʨUܿގsؿ9g,`󬙿؂ MYHN&0nQ4NmW}}GkdHcUHc$g~S3! cin|}ٍ^:gvTG[Ζmͳrfqf]4qOCKisw<6K}o)c-qچzOxq%_}c -wbW:_3ݬXϳ]`h)orkj.JFy0ݓhsړm\z#2)wWpI]J@;6 ׋ tYQz:~=y#YX癏 9ػ./1'7sTR,zXh(>fFr(c 5G[FSŠӕɫ8;ht҅Ֆd 8 ؅wk#822W;,clhbȽ1X5'Jؐc#@P8.%o+XSSiSϙ#kPt{BQXWW;S%ud['g,{V8ukwzRp{Ave҂GVbN%4>_mݣ5 {SG,:p}Gԓ0BN].¥&h7 |t(GUҾ¸I8dQ++u:՜s;樹㸊+Ļs'}S)άcKYё=8[bZFyÀq.cxU/,ŽSP=6a4Tder'7nSr\7?S U|oĩ;iŸrJ_o#Vi{_FwÁTq焩r܅vm0 MGIm܀6;Ns,m*tx^@/bVH|b X+S~~unfJpX)H?^6V|iKc/r] 1bj{05 oxJť?qrOpe64mjiH~ 귷0:vM^l' x{ ^@S=,bI?wNpf\##)khKrNin W*تl8,nvӥ ^rH5;ylOү clD|KE_dGl|3jDӏ!|o'Bws@[EvT%g 6B_:v?"'bJ.?g[^.̂/qMq{3r;^ز<86:?A=ywjv/gL+6(5ehsu`^73V~1a 2ӣl\~ef9}$9jOrb8%KwpB+0шuS{:R*Pro~s8YIX.8\+fP63"K xzOf/o MMÞAq R^2&LMĢ)Q=xr&|G;Xb%n^usA璙+ftY݆V0.":>^%ؾɈm<¢n,vSp' .#{%;hke3el[Ý\ޓ^x~vbpo N*,T2zsN#yZskn^|ގ:V'yGn2N2g9ت!3cl%h(GȳPcrV!ؘ̹ԊCs`hnan|b^܋üyG+$Ձg ^h39u8Om{73oH{2u lidn4glϮ@HEZ>z A1{ZэK-`_yEkr+_2КGVzPگswOzr`HckF4S۞ ιg'' ƛ'?PZv!J6*4:NWw+a gɹ[)XgL_/x "?"S*,DUXB < X|+0B ^ ey{3^aa:$C1g5Ӗ88?ߒ 8'an Q۶dRDHnnfzDņ`|uzją۠r=h^79 B-x5RƼwWE7rЮA1m͆r X{_0h;c05>r8'P9SϗϩY-Pm<88ГOoU>*iwO4ç2uv5=X/[;c.Ё-,hmnxnwXwu2M>}ǃ"w9Z>Ќ1-< ]*XmC0T}Ê3'ńs9qq}-Ynؓ2ƅJN-RmV[ZyQ6™M8hGvYdCA %++R}-mg--Nh# f0m3-gˣlef̰ :!W?-1](|q8OZgܐYUjJ[W^j|N\Džӻr%hDj~WZ^t~Γ]8,X?φ]4mbM(bKC>Z78;3nEx3'>Ѷg]`݌P]كׁ7I ~ :D͋a8Ky ٭7""hV98j' SfFh:Rcaf8ʔ9g[p_;8ܓN[CW_a-"}GK/. }3?N\|P>4\n3<ɛ9 ߭8?be6ۑ۝y_Ҭy%ݷ C+gF1~V c/,i^d"YPvuaط Wg_vaX=" ?CXX 1C.RaeE;μNnpgc%yMur3 R=97_d#Ô\IMl/ta %Czpb'>73ai\ Q_0O4] cr$9?و5_j~)${1pˤ.=>r /+шM9m9c:%loKT_U<վՏʻn\ەoB8b-m6㔝o_puC!b3[ڱO*P0lnʠ7NB5e#$3t!J,ȓE>Gea]>E{ _9!42KG8b%A(dP~--KQw.5|Ԁq7Q*2cneˠn\6ԋ5>rfPnr)/ZP3O]˩Y㉚53zQϙ-[8f+27=$CB&lF%Z;cmY8s UVch_}&q%3ɘt˶|2 }j;Mlͯɸl!1qBbi6pr~FG YHsȭu<멙ZJw`HcY_Rcxgɲ r"wFj7Tpx#[ ʵ}L[_%aC{~g! Vbnb,w]L uYMSP8?ϋ¸qfn:NMU>ZSNdN4tX؊[{pϟ>ԏ\y״47&*.:jNmxٕĉ}4Ŏ]C SX;Lŀ8=PKzձcLcJך2-U¼I,J tGqq\Hą) osu=C\0&GMp_ghHv7]fV#ͯ3݃H֛:8| C3o7 V&z2J@_aគwv:ޖysjn˭K}ΰ>Tb*xMqR7/revv<=NfbJt8^HE_/7hMrO-6]7>nv|Ė2sF˸B) IŽ85N2<߈5V0&lq֘&sr=9 _ҥcYMqa"}x![-"]kCg+ٮ,ѓK<)X; s|,O-r׭ܸך/;pFJ,ruŞ;ѐnl6σ7^ypZ/=nnf&<B`.#x<__3-2#Bܹut虉kr$Fϋpл?@82;%@L<3ZBdaАd|KٚYX׀uNLr.L5OuRnkv,`?.˕#=# 9#6hKXɘ6:|'{B+jy>`|h@A2N3Mkxn9s{p5$#[<!ft%we%㒩<ЍFýc/'$mۣQm3Vr-MU .ay1UnW'-ںѰҕ3jt]Rܹ}#V'.`@ 3ccEx)i:"GhzRu+b.5S[=_] pO[7S\qkRQD6:U pt0e.tÐ?b {>㙚ͻis}m_V8rh{JޜϘތieс;\92̑7m8qGHmvp2=U GUndx??~Xk uuAx`^0א .dI+w qi_˂}-h^sf[aجlZ)vƦadžTMDa[K oOJ|Wo/])7gǾՇͽ9L=oHKڽOu[ {=YVׯ8ՋS(ch˃We2WSc4R;9VsK\r=d]K>]`hlvӐcLDw,,X1F1&gJ#ȗ*?p핈|ʝP}̋vee7a_5r7xpzGWpnu۞u)NG8ʘژنtRpEh:$홷5.WX6.Ep 3`fl7q XqށNVrzVCҽh;\ڶ,C>?f~ٜ:&Ȉ=e< 0yV&\^$t|3HeKVluԁx7݇7ʇ1OYQׇ|xZ{Knzj n f kM`e;w緓^4|X+ܗlzȍF)~ 8 3rF*LJ]Agej{xZ[?*__1'u`Yj4MkcȂ#2ӂ3(u7qXKŧmH(/{i:5Д;)x C:qA&^? ۄGrj+/H*~|bӶ|i? }xė];߅˝yX摎5ȞFXc)?4~9.Œ)c8i?BēۃgpN4w,Gr`fy$ƒ3ؐs~ر}44,){SyUW˸[vE\ܸ]̟7PX‰Ԝc)L)*N}Ñ=5;_Fzs6h*Ëd>K\@wKDOGqVgf`қ072ovsl9-8$IJX;[@ӰM]|KtFv^46B'h˪(fN!|9ŊٴK)I-н uRˤ5?z0|+6*2L7qyA5S|7g?c?hSWvփo{o ]v؁؊-b݅ݘ( ҝҜ{fΙ3բaG[ฺ'ϕA웉>hҖ8kb9;oq+^ɳ**gE'$Re)y}3CT˛̱I4N\_l (V6J^!HWm12-`пtaZ-;^E d,WϣAXLo=ݰ=g!OKךOX 7,*CfŅ/sVAb\ JѢ.u3bS.+wf2^+NtjAƼלpWAJ> Vpfc5)uC~}шc) *aֈ#{ez~3ƜrMSmqgLxf''bD6=Î7qA,ϧC5AfF\фyw6u]F.Í7xcxҒ?;P9M!&藍5~c/FmT>X<ʖ~VukW]9uɅl#cJrM}5'*yZYJ/cuG=9ӣ|*&m(pK(c˧=Q<^qh 7J¾ ݖ!N.yp^Rmـ{p` 3ڨy+~JPu`)/}sd->g% Y.J8L81Ց"["q"Nƈ.$9 䬍հ솆}y{c6AbNrO>EE,(f}gyrȞ.B{Q%o.xX2[<tc3Ԅs>e`J|Zuﻄq =_#n(ޣگ /0 ȈRKs1xs:)xm O yc .H. (pQrv`7A,UѺ)NŌ;oa vn*fbsZ CCqm1tcB>a]媂*lzL HMXzw*?ЩpV$T?SZ>7លV4=̮tp_"͐ 3XldN.zdu1e^LD/YjSKJsTlϛz{%_iXnɺmz$5ن&rي9@_<0P_W`,U+M:f[Ņ+o3!p,=9נ&rfQ-_p"Pq": W F,I<Ƣ As_ha5L~!2w<)nrj*:@ŐR~%RN$eT)A7L&BQ]ٝ_u؅~X*b+nWE *!65yT<š_p8|̠5 Q/O9W4dycX~!7dP]n[Ʀ`ipɱ*˸󀄇~+X$ܖuCɮ" מSӡRUN9LA5 լ<%"8hӷ%gْyKj}IX>ϽǸ3 xxQP8 >0x=z¶ӛ }\ m30׻vнX;5* ^2)Ҋ_qDc,]՝W{ypp l4ԑ/},D'qC|o³k-vR>(n!N-gpmTg(tAmD-ZuxxtZlYPtoK!cT=p/W?֮a^lDwZJJ)X.lFݑsV ll)R]-I)BIr#eƃ8xޟD ʔ.ƚ~_!)LǒKa IFaR=pQǘgwĖPŌ&5B&k{Z;m#b;֋*mXCn]bH_XQh5;˞9d}#˖Ɏ:.zrO˸;/cDvj6ً:o[#f鞔82CM[zGW? GpVJ)T^wa҇%+9+߻DNxEr]r|K1^qgF5EBX,<3vmͺ6eMٽK95I"LI-tTY(BJH*"ø\DfB}(j_U*p7zyY9&|ƌ,ˆ8"w. YCJ 7^oe\dAܯאuԬI{fԊ:Hl(.>FB EsZ9hr63%78&g3F|ņo{ gQ%N0WbO)ۂi~k/rC!kcY݋v<Μs[3\%jd :dwBH~_dfμ.g*+9h rS1緊rU𬯌934M*%k_Bd^ưjQsuv+5JCb#k(u8ye-G:1و-9:|tߎ6EHM,8S{m.SWI x|^Ȏj0x_1BôKK156; ad%30NS}.K0gZtg2)oQ0LE{bP7ՕJeyRݚ%GJ]|IO GFxs4qeag##—|GLt ݢTxD׽h0Ԙ3Ÿ噘<aU hx.Цƣy2qGQUzm, eK0y9֨+w;amx;IƑo1T38L6{Ksd,Wd|)Jn_2npCw\A׿lA [ܬ#f޸W+NhggmL9!ņ;rs=?]tj7xwiLi`6uU.5܂7??wO*o?q܌{e)_15/u<݄q>q}Zjj̮c%(H|uEȵ,ԈJkx8'[ə2Wj /^k{5$a˯64NĠS _̞䜱Ro2vΗq1Wiɞ<~B 'Cw컜 N}/txo1-ysL7aיDEa]bMc7~+mma5<4d{ץZn{XdLNq羙*vz!g'%E/Qo[Fs5Rd<>]'ۨx緜#+g0Z=dd(}Ӂ+"8n?0Vlʞ.o~AZFb*3r-/$ӴDaϱϹCaJ=/X:;˜ lY4Б^on|-Á ;NaM+v4DcՙB sAnHUTW* J7fRU`*ްPLǛ?W`|÷ѷ9\5Cȓ?)bcr˝&ٛwcn2nHm9ܥ4嗾VlWsfPF|+Ȉ ozPj-qEc&zגvLjIfn9:iˊT%0>ێm9"Zޭeޝ"|ߋ(B~Orl/)lnK_˸y}5WqV}u}DFZ1#Hygelփ;y5׎gȁ2XBgR !HO<Yƀ@)8df4b*X.g?2˙j'M* Y:'ZcS6bn3gl՞Wk?!*/-h֎2.ǒAӌXN =w\6a03߲ę =y˔8ZkB!˴weS]i>Cиb&΂۩HۯIW+ ŒSZ{^W\$vvU8=1?LSrt.6T3T>Cߓ1A7\ׄY<V^Cn+%41Wr8 ՑB|`!9vWpFC۫r$&{1[BH} s>X&sC5сno P_n= P>YƷe_Uakx5v7n d]);)ٌM=yr%w~g2^s2';qZw.GF yg3~ȫY+[\2zfC/[;;9 tX2_ahc2Ar!s.aaEBVTg^l%3ߙzu7Y396QX=®SXga5(SQho9-7-<ݎ;g?9[ ` ;2M ZUp׍|uDţ*9Yrن7?oڣ&x۽ A2ޠ{zhMÉCÆ*&g*䕂.bvZS61f;#lǎld|3u_k-Sɢ?oɸ`ڝQ%mϪ?!yR|oL5e2]JUHo[25p\QP]'ˡOeVCx<0|2i5 ;Y&FAEn|LGcGkDAGNgC Sygy+=m@\Fqa6L61s.0:u$WcѶܼ‘h$gV)Gn&|zQrqe}~"#&k_3L ;@xk j 1ksLMWoـcy艒ə*D_9{=82)LnYu T/نWp)_Ļ} 1MCBmprL j3)?9v }-+pw>Ccu9=F]ր_r:azᚗ54ѣe-n&'H b}b}oA6!j>Rs%o]2~o;'y8U.A< x=`EH\?s(I[^&KWc׉C#-Ko wƹ_im}%5o?ĨO8d?6Y1*)0I·͚bti ώrE 5E˙SIx9G^j9mJ))fhOl+b|aG@yo,=>:1pp= ɧ7ORHhuq@/_a2qR13?Rb/sN0iqqfLϴ?㙊Ԧ3ӫq&me% +M8=9l(zayF٬J İ505?OVz\sN#t:|k)oXnĭqf ɲy(䄊M~*^M>HN{a>hŧ{x؋2zYRI˱(u Hگ@Aį)w>ȇ]+hR"癩r6ȗ1*V3q w W;T=Wp`B C Ȇ4Mԯy\2Bu;_Nv]Pޤb} ?i1Iv fBXrY$5:LިѨ;@]WL |0)bahv{!i#9;/ZЁjdO䕅Vg 5obhGgcm صjzd`Qb:ʦL,Y 2}K2$f0q'LGk'NߊcҦOCҹ\\,AXBV#~ CUZUZ4a^:lvX01-ubs-[(8cOe 99WTsX%2?ѭXau{.CjTc8s &c`FT|+J95 +Yr "f]1Oxr[{xanc͈6uʎ-.;7 ]U83ڪ,Y.}h^ޮ/9?O~M0);6ghAT@A9n2K{r-:bm`[L뇥:* ֳY es|O>l3N9r|{9vڐoSq3b=@Ԁp\zc9r~!zV:vʂmK"Q7ySpE?_i;yQ=J1cN(GX3 g#e/$5DOUjr! J,[=1޷ B~@m ʘÖXcM\(tVJ>6QT l 7 ͐q`Oy*H? > 0=j&dzkD<5Aav8ϐgCm3眗[9-*Xd`9H8DLbN91c:|": U7Srx% %kp2~TTna_5߫LM. xQf0z_3UkQoMO184yG`т8WN7Ŏ q"TVTR]f>Liȷ^E*>3ܙݚ7ԡ\BS/h\q G'ۤb˩4l=1f"N,l,F9(k' .p0 ޅuMTϕ=ʘ0K="X穰Xz ˥b:_CBWA8 K v9"4/Aʥ2DiΞ;~X)*=f_%(A<]1d&cEQp{>w N8ߍSjLZvnwx{켓\ϓ=yk1L Px~b)9bo$pUh;“?zE2N}&h@S!_rDq|\?Y^ U#Sྜ{΅b xG9Zmi8bzA7g\~Ǒ?1mODN9}fy:opH\5wA}ەhԩCLϚǬlg_lP[2=_*#lx/G*D,{eneBJ (m+b|0WisF;%Ur4cw+8yr'-1wMނ %!r NxR$.9V}Xg(Б"%YZ /NQ1U\+ = m'9\b6Y?)KT&(XRA>/VV̩J7&˙'cפ 3ؙgբKx}* q(u WP!s~dmRȳACPe'5 raJ4b|wOâ ىWJd" S؜BhæY:CH%yߡ0YEխ D ae w321`tv8oCIğ]vDۓ˜3_Q4[ Z3n|oDF0#ƼĔܶЌ?s + r>kЂ-ā)98=;] W l2gR^dL:*G(Wfw=m3ZVbVOvbe;j,kOQB+EXЯM۹ Q7C>{9ˆj 31Õ0mZ  ?]ӵ:]jfYS/XQҙ #D1YB;?;幱ЏwID[d+rz4dP)d' ]8:%-:JAt51]ϷR*sRr9'(jhOS]߿b,MKd {_`OQ3-i.;(GOΟaALEQOB'Z)x5Dž;0@{2>9'c+%卂ߔyN'|gyAH7vW><ou_ \ &ꌈ433{c~8m;`o<O/cj9' UT7|Ї-LTz1wCk%nJU9-ќiWVVn d1jv=+{;6O+9: ~:Xp#&Ma,WRRΧ#dRS< f^!JwӖ+e1R&eKn#=B+"Bd<@-JY]ם9h!Fԣ(Ԁ~rR!t5Kc.2cqK[N5b_R Dǹ^&x7Ř C!%jnvg祚1 ~~3 aRpvcK2 ,e"t-cKTGE\m<;E፵P,E)8c1b[EKh sƠo^oay=K-`CFD7}oVQDžKC5WZţCM&Jn۠B2W8'rN#99jw:_=; n'yqoK1:߰{[1=a67 W뱭,te"_݋5LE:M/N൙RvPE^62v"p':EO8G `1SFmB*HBRN PP-lrU;s;@:r`vLNMlWgZ3rK^ .V2./AtO!.%NLΑBEeJ:uRphmb,`#ྊ*F*8f.{pn m8e>_CxQ.b3&kՂ` $vWdvC4S' "߫\0vF= u&bx}|q;ʘ~HxX8!5 , avx%<IqR e3CYܰ ؿ\0J +rwpv3oā:P/~ ̸Xe<6ai/و |-:< 3~hqb}03~,^V@Ϗ/m:Ym.zmmmŘTE#8Gf\xAGI-3hTZ:uܔMP"=Ԟ9klݝXEr=,# jBR,湡9SG ڍ2cE:]7cW#: ~ {ÌԽW+NX cv v0[PɑV+Cx /IR GHY|p^;ћB򵏣ouEӐz_G+@`0x,mG7XUt ˇFhJeCx Ig){Iw{9aI:4oBX4|lDaG:c:wrWswtZT 7hgNw3Nt8:ńuPlU#>DZR_ЄK h0K wY< {6"}Ȍ`(GZ]+p' kZiQQmw(a{ưiE9qI1݄s ^TJ[*§auy2|.G1PAghy{-c:Z_],( ^;w׈&wƝqnhwg8wEcl^A&2b|u݄_Qd<ЈC:fDhpB#wT~]DPr E6,+ED::]E6˨kLZ(yDm&VkXkmd>W_:^?j@-[R.-Vlp/9;lq@GE.`^9_s4^w(HCބO\6lWsL]qi}=p{׃[+9n =uA 3[^*%EU1aM 1,G6ZdD۽k˜fwsfN?jDBg3eÂENeĄ \ƋNCͤxSꨭW4b.ٿ/gPhN.G77왾o^`Bŋ#wxK_;lYFp6xHccotVׁNp>ów&lY⊡?l8ezêP)̽|jOUhg9g({8C] îYfxmttނFR#STXS1"A9a gB29,L+8mG)i+z+t?ozuwګ;V|h Ŝ*ZÀz\]c@z#^0,X eXGZ.[Ů v.TM }[ݣ̍=};,/ WkJo #ϖ įDӦ_czm!] {tl dcg;߭lj:?zVPVX2;rbϭӒr\9uDbzѣ}Y:'b]GS/З0̙9#OSA }4(Ei 7a 9L8wx~anxsjoli(_ov,hOJįٳjJMt*Ҫp;lX,2c3r&:3L :1hѲ"d@G5| uO13S,i.!-E4B*B;Q2Oo}i諛 ]gij;thI,$WX'g3=У#S}\t z+G愳w%߼QVPIa76$Ќ:ZQ ΌM 3Ki@m:4h²Ff`E)"n1@'Er p˾CX×,U#2RxJsԺ\:u/Λѣk ]򮜷zoE#Soy ]RҕO4PhE Ɨ\'ܹ$CY%TpZFZ-&aPqzm[kâz(uC/4sC_!q b XvC;򊇰8RC;|OMuXBۣ'..%pDr:<VxZQrDQaӇfz8D:pWڸyv`т o k1C aF3mj/K} ʽ'5*Hg(ġ6ņ}8 'RTaC'ܶ`΂M&9"ߦoc@!4z!v13gG |Kzc6;57ܘ%yu;ﺍn|@Ʋ=:b1>ԉqnD\3\q*͂سPD_)rcD( ҩ ;^K{(;9&ΈSfs%IԽ9-ap3-6pMg&` Gk V!E  tWbE9I0o/vĤXx?6Srjs:AW_ޡI U{[Fx]e߽niH~S|V'Q*~G3SEA>R# ])X%g]}ZxqE;+zr4]D 3\G|@dۏa:%5YT@) Čb,tDy.6ǨݷrVEJ{a0ݍnyjmF[m7}ͩrw_ۡx ,ܿFpi$BQ# S2}D ir\"\|*AGב3,uD6p 8Em h5͈l{#kxOi'vt-Z [NnNe%)km0<]8VaB1b)14I{ UcĵzPy Axc Ӗwcg "MhdDM \B3m&AN(Gr ɱ ׉0Ɲg,b_g 58Cg?$ٔ޶/>k)1OucPh ^#DqƗӃwȣo;Qy'֔247ʦ*y1 z JIƃY*ı ^+z-Al=c(G4{GR㧡-%mK?"J(w!\[E1:%JpB"an6ʤAQǺGMnm0 5:EݷRlZ0s]iF. ۣRͱW Q+A%r0ކ3ch{=E?Wt09갿OQf8m#7b2g e'B yKݿRHFa+}Έp.9Aj̊c8#I\f xT31JI*?Oiy88ƘRDz%.ɣ}(PF~bI v29&Ѱ'?ڢ 'iV%,{O[֌}&.B|F)ea YLZڽF`:CM31;UNfߧǪit݃fCa~)817hS fmGhJ3q $$DSnx;2 9hOn (F٬@'T(tbm'dfImD=|>^g[m[ӫ )tr0iv>14P b[6zcLw>^дBOA]KTPt%8F40'JvNOӣ=&h|-͐c'gg=~fq)-E7q9BZ]T`sU,$XEM ]r1`lmSlE/sߨ4kczuɂ(o2ƽxI'JoƐ}|eK?M,YKA4 :Q:A%<ᏈMJT5J)JnMlaeplr)-*Ȣ䬯4&h}^m;Hatc/8&kSiO-Bl tV :](w 6} ?eSDN[9ܮkH;ƶO~w[5Tx4XosVpR#<AJd|c;ϗO3\'9xpH;^ΉuE(>ƛ(КFy;>γqrwN/ӗ"f~Cz1m #*L3INKBg|c8L>1ZGUB'+Q~H:/(JFT?Uy T˥xJbG;"$BS>^Xd(N&m_\XpY<4|G:EvmKenC%s*L;f71$T5:$סէaN߂I4'FRlE:o0DSJ oH{qI[pNK9BJt)㢭;Bň O. HLڐܻ<: Zzzkߓpe^J ;UtXSEYzP>mAiSQ!_yh NWҁ2 :UJvh|+"O5LzMOJ|^gF@#NH#Ifg:0X@0ӋCUkWBaez%bd航 6 .ig5-ْDi\QKlƵ/С'g\'>\>ď|)z0ZPg6) 1+Ȼ@$2 jiZNz83 n?tUϕP"NM6 2! [Ps}zUG/؜Á IqTyxMM[([(M)ٔTQJm+iX 3K w!=Wek3cH3hqQ<30éԀmJ(-K jOPba#oIrYy9 f%9wJ{CG2VP N\,GL^1nËh%B|x7Wy0Ft8_aX=vil6Wag!FGފ) G'!lPd:eL^ 2%}q=(懾Tc4Wb_*Dǫ<8⨿x6\[E+\^a0xG[(ME=?4J|h1a =N䞜6aWIIGD8bgBl05PTzAIԯm ;oU8Y$Fa+N=e> i|~'~[i]{R =[REyA'S)Gd 1|mƖlkM>E9FpWYvjT fܹ ]HP>TX 2lX95oxcH_6|=(A6pA; vDf>8\|51j̑Rd"RMp9Zqac0a\ EeFtbJ)Vy Vqb -P,;m@_=G(~ ǎ\\w`=S6qXpMb33`f0Sn2@s/)ME^]j F- J_3B[n߿([oolcEdUF+\Q*;؎`; Lg06^}\2uk6ܑ$OLϲHP?P¢xJdhۢ-\Fs_r Nr\J_/E$1bpf ̗֌OfqDYȯYrܛ-Erd6 &(ь[-M ]BGzGR ]֡e Y3q1_F4pGyḶS]ɣ:gЂƥtmi0QmweTq%vˡe]IڢJ޳!s]NLLϱ{Uу74[@b C*x^"=_,ۆRg"-bL&dJB<54 71dMa1Emƻ3F~zͥh⩿ö3ް-v8aKДE RC *jYE֖9TAQts:SjZkrZh r?Q J3$+j0 ٠%E¿/N#c f>fjXB*9fu"s8z3yҜS٘[NC lxG=ηR?ISM{}BFg6nhm2졛'Z>qRuSJ{%|wÍ u!SaA WX,ZXsY` *"Hk8Dw( 8^2tcTXY}DKRԛ@%-4xC9z,YLm6© vXPUG/߈0g$,L'MB$IIsH;}(B^mVVc2TL:IFzݡ`6RDfL UF" &9*>ʠ7Wxքf*g[2hwD;=\~RjʍEЍ2O)|?}vI-iTʠuecgH8"$hbKExQ2̓!PF$f[:#=*̈l@*d#*ď@jHΓ} "]% 2+A`~\Cwx:I7lܐ#_!Ċ 㷑bZ^HJR`~ n6#֏ahӂD<؄e4ۭiwfJKOH0uCX"T["!6[)<$|E]?(qUYħ6&Ӛ_q2P?oCgЩgvy&uxMK!.fSD:7҄u(|o3qn.3lNgr^ Sz9b*$7I6Ԑtu_)o(l+a<.ǐ9T6V< ?QtƳN ˩`5mUN3l>0a+%+^B4+ƇI"'cmbX\6"y ^Rg8<܄ WOӠy9VgJpQ CܓL\)_ȡ´rG}6e%%d_;Xt\8Z+Gn2NQJ# B 7J|Ag\[Щ̀%(Zqow5]0+jg e+=wh%a9GUh,qBJګzp ڮHuz󔃤A|l)AsL!o.n>㭜H-B91L*|jߟE=P2ܷ<t%7@ݥsP\i(͍s #1Ԭ\zE9oQGΛ&ƌq^]BYe'Az8"\\dvɝ\Gp{|ߘEoj#+~Ra&-TCхDZ*3K̆RprZXFcQODڵ-҅E-ac{JB-"DxR j1_b0Wo.ü@ך{O`78uvǯv3⊴n 8 )YUșS 8a_PCWSAқw4%ȧ^9@1wx͸ĂI2X"EX~3d"q2t C})b#d =\]`/EdG`f+$bXOU@ޤG 5rU-^uRF{.餎Jy/h*E- ͩ(u&OIy>IoI{h(pVg]C4zpCaשvIOCy;)gK OhM[;%!=F/.iPaKzRZ=N4x[J:Sh:C$kYTӌQ\B,QxT )D[O cߊ*BRD 3T+`YLs!nrA&0kD.O 9cjr4Lףf;pкM=8E8d|z-`zU}S|OI|^"AN7c_6F3a\ BZ#.4q ۫x |.KP+&Qu0,ӹ4&$>=Wt y]DwYtAڽwy!Gi4ݛ^V{a{J}i[T5+{(mK|ȥ I7fM!l7GrW48%S"RM%7?iY:<.Rh_jpg[cƥyz4l+LRvTt$Qhr.j;ΰBǩ$T7r >\1m+m1Z5BxS?l]*q)' Z:`·cHHnjCRZےH!v\ SDBpp+G~U HɱsN-pbƎcv/҂= m %AƓ+pOpTb^ J&_Ժ <^% uPX c>)G?VsўT )c]@Qӣ7aKɹH[DiۣG#{D%Nnѫ̶+=Lz̪ [I3lМ)&ָQߴAxd X>{Jf~ q-ވG]΀'Db͙\O˿uo XHROVӃ QES3.1$GQ',)Iß\ (bd. \yi3tb3633買Z[Pc{f,)3CڀQ)-B$%Y6#: H{Lu=>& -yXR Ȑz]%ϖa`%Jo;a '3Iްo7Z/.(9w^$x4Y\h=A;;HЯ }K?B#\O F^/4@~JPkwrC.-hDZf>AI$N6ʦ iWI#h<]uG+#@[<#hN=q~!]}嵲Iy7Q]jz!bkL!L:sxw.#`N6bFqv' (9EL[ib180ihJD#ͧ٤iMR{umP5sB>1d HbbW!F08R',]3JU:Xl47i7a'7*gkKg5H\c_4iD~'qzrDUGrL6A_ qX{pb\gy ʌcMȨ2팎N8ǸHh--S-FQ.7d 2)dkE06XMt'ƲhpqIH]j75 „|m>ݑIumiz~ *id|)m_[JE5C>nh-*e"?Qpc3_S[_t}^<4v0:.ޙtۿ(!64|6I)U"-LU -Q@?.p@L֠aRT8`TJ=NV\J+R2"?hC$s#?eT M C9vq݊؁]xۢܢb+H)ݍtyԀ՗bZ>&b^ \%3:TjX\<)*4=J4EP\EBތ 5ݘ+70r6Gjϵ ޮESDu9ڈg۰7'f:jg.’B7tsLy';ftإ|M&|~p}1ۄ)K#p9o+J%?>gN|hM +`E*@c_ڲ5JWɪ|.bmƧI8f.HBiLt2K;xIo2Ǘ֠˕¬91Ƚy諯{ZL1DiAA4#58Rdw+:u'1ZA~{"v̀l"1aK>s, &А YaT^ ,nBj5 s6jhҾaRp!FWd1UIx肐fyрٲk\))CA%2F-rq}Z&rگ<[>B涗1{.?Dž{;t?J`·Gx[~V ¼ι7q9. H{w>卯]SvJf&Auyu*b)YX4$G#5:oYcj$!#4d{1E| zjrp Ҧ|)?udx_In2gqcR;gS7cA̸ {&{ȶ)$񬆇BƯ\t/htzNpOrE=sR-ہPڊC-ҐBZ|/$i7Jpt}N*\^x•X`ڄ[O p*;WsP7Gk3L}EgHi[n86ۋ_+Pj˄J'vq8L|W^ӓJqhd6:Wx|?:M%ߞ6𙻏]a=EU ȖMe/)YصayTLV&T_ȟmo_F<ŀw_bmN4d~|rďLZ l\%BN=BMb(S!'yR9c:'irp]\nyάW+y&ԕteZW7~ qbZ/ej4JI|Q=6 clk5"<=߻N:Su|O„*]qHO p`{s;|{m8f#G@y@,Mp% ;3S,y͙ߖGٝyt+vLoM%Т:ϭt J8r/ԣ8DS9S_ yp*UA)#?/X5q7>BD:dtakA/M |H#|g@6͈3zb>kWjrGr4!G F"C7燡- '-7moC!&7v|p1O,' 3^WDbu.Q㛣ҠsU^ RMMvwb&oEE'_Rp \ȕ%\@'UmYu5@T9}&=Bk& ]=ڈ3խnPgn]iȲI6‚Op@>iT:`әp9y~`/dנ>}rkVÈ8=)%xR wM5%vȭ/x=O:0Æ|9)Jۮ"GPX-1{^3X뽴k7V zQV0hnH/O&sqdLw/< TIޥ\1b]XGJ,x {F۳ƿϘ}D&OoũjPwe**&haJީ@J-r[K{+oV&A'tͰ,ϑ<ocK9kƗ-ƀ4'_ˀ; 1q/yC%Ԡ˘*h-z#.+!un!RR+!T#qoЎ+[A FkR{"V[2+pY vbh)֚לM>=rt=S´Z<ΩЈQ߰Q纣2X"tGouAi%z0:hz7jw+eѨcxA>}96S2Í-ِ,u>IlWo-{Si)$4 GvAk=n;o)}5C hQE:qxԙ~/z-5LbFN,& G@(L2C (Ɣ-[اAM( V"n|l@NF cz[>a)fjs?%};+畻K~dTSzN=)!׫rv2W6H,?nt'x8SxTdF>EIn2w=?d`/㱱"Lg 8,Ęx+X u8:W+u?rP { 5bd7r)m0 HDm<EóD|>)%}s] ua|di–&kԭZ0=`C9Sru6B.Z K[s U</ +d(3>"gJBm- WpgywuvG@: ?`J{uMOp 6HWk(7lRe PW.#㐙~@3T{C/~ 60U[1S&Vd"{Muۊ,?57:z L߈~ފߔPĻ5ؤf;7Qgr9 ep{.aˆv?<ҁm\&Z47Z bMnQT*4I} 9, O1MW*Bۘ#;ށ˃ WVG`gj8AyKK+)v_4 R=}U4`|xt&?UMkhNv"mγ3a\Jی>*`_Y޹;.!?1G;w!6vSt s6ʄQ>%c6x5wwY}IEJlӂ*tCUp\)]zFk]qJQT(Ud2O`_pfi5F*A"Mw]6V$aSc~FGli\}Sر) aCY$Kb JZL!/braO* +\T@2rG]^[鿍SC~bEla§"X,".)὇fNT.fAmThpQ 狰Q\.DZ|eBB4C/SƊ##׹2Еwo9s#K-rޔH^_Tu*{-uU֪r*;T Jmƥ(~'Ar'NaXQqqoXЭ{)U` = MQ'u[Uyq(#nh7ڈO% ΛGQD"*n<0ە Lg`oxŕ"(iq3}`j >f ktA>/KB(pY]}/m6mlo)%-vۅ)yj"6IicjzZ߶'HkNrk3G76mo^F̭,A̋TTޡ[7tKik~f4PDteà*'v(U.,rgX7h˽6RvZ,:u5^7RB5t5;)2ùsUX ~4S?}i1for 6v|'~$u;zc{9ՈHnߊv@A^jQTgȚFhY踦CrE~MRky*2iOV$U"CCw_̆K*kY%-E7Fs^ͱK}{sM)dLۿG2 03]SVj18Vך-?Sk5ۉm(6p!b[?kFx$UQ1igO{?a]Vg"LI[RWKhW˱`:[ҩ"d+#B/ʑ[yu"iyK .\Cxé0dbÖ" C7L̍=CC`-N8BK1iNFmA\%k#GԩZ}OS'sȂ 8֘d,Yo-I&ducNb3b^UUBnMY8$%aEzѿQyJr.:K DŽ2 |7tiy^GJ$b΃ 8 +Et 2F4}5k;O)ݏ:e羢'et:}=\.1c{qz[Z5ۉ}3ع%r=>>.tJܸ[ci\U2sP-Q 8^ /*We=vSp )pwy|`4E̶dd^Àr<(ߵ/T`EV+PYÇ4R˜P)\4 f 1ގD=WزˌIKx1O.Bq4x"垿1`64 D=ϖB_vLCAT˻t籄'v]=nz6ͺ"+5Z xUCv8 mm'zlqU&?i(HV&S4YQʣ 8w-O81Չ5 \Ӟ?c fZ+x#WPJz6{@ dm: i })o/e{.r9.|N/vs~ ok 9 ytZ6(F9S)sg{ք98OBBA 3 y8!1mA몱VAc_d{1Q)wRR[֊f,%_ӣTdBӣhe˂}NLsc[Of5`G)OFN4<T,\ 1_; atu"`.i(sV=L*O!jiVSU5rkU LSJ;[sMm/^5{ -zat !`Gs=#O:q)Xwˑw134z3H80ǯ -ӿ=ci5>}߁&lӍozq]wHRޞk+"k8qS :Q)pZ3ACYp'`N6d/>V |ŎC<ݒy}V ŷ1`lbYfI G2L1ڰZj݌"EVeu6Mi1M#8?ܖs\9--,zK=*o+,7Q29R/Ȋ@ ) >+@;JXiq: ^x,Q-\Vj'Ӈ)Snue(0c%Rp=8~cc>Zd]pEiZfJ0&;+:_e9iJy#ύԙuoGvoÕJVdoKW/{9+8wy;1$Ǚ{]pҝՍd|6̖ sh&[9,.D%vnBiUi6ĐӾٳ ueWY.~wd-qj5oGμ+du%Su])x v7LTa_ٴViAuEvo 1d1k/:Z{B̭HU8~[>lA`B1#^7 0:|{_toؐ?t<~IT?*4G9$d\GG[oϿ<^m&mEo4=ŧ8Oi,hHs(%ƣӪ?țF`}3do['8qC7s>]W+dщݜ2_@S7;1̉ɋdte_ʸbpFgwa@\h~܊{pЁ pO2߀+9m)Ϫ2G"c._Бxr/s+wr 7fsyp| ^GG̪r@0Vw ?é K*+E\AZL˳bb(0ؙʞ˄KO5G j R/6I? |7DLƣih=vIXW.ŒZLvea/UL*C1!۬~/CpL!-~zq b6d>HDT{\Xyс|F;[{͎+zGn{JדR9< ]S>؁d*C s{1*Ȝ*(c\Y}ҕ ]8ق't9rʔ\?˝O;sGɷ*_GJvf'sZGD+78tgOTE&v~mFhn=jǦ2J)Ɇ3혻-"ܖ'zPTx;/2HO^_ް !P'#Уeq-9tЕ} g:2&É\([ͩzM| dB74tѩqP XZep^,ñ)Pn#~LϬ!:N{Qu06 ^1vud<l1Wu>\߃\q7C;9\݀J]E)tի񸚚ws=whxa9'ӝyp3\߅w,3B''ډ-2s-T^(fj;^^)$ϾggkpmuVMp,PT07~v|,bG;iOf^uscW27BՍ}oo=@(p333c;ؽ#&w^9O`kl؂ EZ01"gc/Ԛ]r u j8s#$…0R{W HX<ѐk򧕔ըR#`ԟ흀>U 0oV< :`%}^oU=hl(e=B.ܢ2<_^/ߪqǦ6*1boƓR quJ 9 ޳ N2̞-Y2{awPCS9 N]t 7Nyrrx&ovHa/0ra@Sf3E0Ć!#]x]WUr~>΃E^չ[fٓӃ݅NB/y3<9o/*cPOVrgSެN w!sYt3D&ۦ~b WgPхC:a=1h_$VB"3\Z;Q^3F??)ENٮǧ\`+FÌ MXÀAtzf|][?@q7Qb*%~׫_"D`3f窍>>ݿ%)*Ěn_նMpqK76wI9l RcZr5!':P.ۮܹx3ӝtμMr΍s K;sx23{2hˀs.N~<-Ƀj=?ʓ;a?}SV&lNRfT+'ip˔X_xOcJm=ߊ8D@CwD>vkmoѻ1 +0ws5cps+nmNs3 )3޻Ī'\ɔ\Ϟ虆;̘Ze=ϻwopmwNIpKsݕQU.,iv}NN0wa|rᙎ2F;R幌oۻ3c|nǕ3;p];zzOޞfwZё.vl +?qȃynO-3ܘ relkyRޞT&A&o @$T<9#48̘Iֶw!2:^rrW֒1VÊ[U3V֢c%nFہ*<#GgE#zi_cֳX8\rU܉J}AQY5Mw7߄M^PXΘ0MkR߂Wx̓Ag9o yF \q8 ~q]ٍ^y+*x'Cxnn{n(@x.F^\EvS^oו1t_1k'YFnSw]d"ݸ䕜SU?c{[ Axۀ.|-4:+̙w2hgȸXݖPSIB49E= ^*oP`{ٌO5)W )_w^ԀJ >WWitVhȞw 0MqB0+S|Kb0F}η-UNjc*V[׀y3{gixSIi0_5BhApcr+ xѩ+5xzzȓiN޿"{*83GxpW9Syp* ]a;'{qozqYg |$W~zVLʷc,8p rx0;ԃǃyi'Zq%/>ˋQO3=y7jqo|0YUZyR{Ysp_2Ɵs}WGIWuuile”:J6F$ybZJhP;pkw]8*Fϸ=HD '!y>`W8 o඀L^^kPX$X{GA|0raJcSF HܵR [4"a $̳ eHҖUF wv]{փَM^sMvnr!(.sSحZ<ΓMR9}F>!V7v6dg?!bP!FfܒdBRk q+ 8囜v ;򤬟'Iڱ e9ݾ8ܖkhLg 7{>2w 7k+\X+yNYfÁi2e6+Tr VvE/84~o2GBO0_x9,A`w%p*k<ު/ I T؏bUPa9|_C'nm"{qߌv@jE-)8%8,|doFlDH_S 1$A9P3hA?:dm<͓ ;;<3HVz>vc'>7qqe+78Ƌ|=9j'Zړ]>yrH7+uaVGatSdn*LlSJ=Yc9^>zffdC#mgvJr =E`.ed)sO:S=#q1Åg|a`_ +QT 7쳠ꗎ6LwRN9^^u=\al,c-7ŧn/oP}b=gM{t~I}gJ0]^ z?qGUBcV)],Ǯ*4*F_2reL%Q]yq݇vz{gWʒe't$7z(ټă]Gǥpww /߸+q'B weE?Ɯ 7E]vz*ϛ~ؕ:}t.FMx,[DSa?f!Tc7Dj`*,5` voƗNtί;܏ϴϧ}O׏y/n;-W5%>H?OW s!#G;qUEFMܼӖٱH;8X0&V#|NCi8~3+ ]%:R*\9g>aψ\ G٨ea|$^ Mb9\ e O˒6=iQ"LÎH_[n(WgE=?rdf`^<}EL|Y_4{aǫxi^Cv>1?p7C4o˩ء7O(>7܏×|1·-x;w'l3 5߂>7b}MZ4fuy8676BkKtg w*WԺS{^nn~4ƓQ3|?Ƈg{WZ1ҝ58u*r=ޑS#d1}Ur=vY3ܜɏLVު47f~A!\FՠN5ڣ a5x~Ł ?t΄h|= !ï_CZ m[}dz8|wuV%y"4ix~''iW4*Wd9Ry|W~yt-gj/\O(f|4V㈍>Á;XӀýz7My[JJ+.e|A6boF]\c co#h(+BrRCwsKXt. u'?FN\p̕Wxsjovg/NͭbnT/^tf 7N?Əٿ;8382ҁ6ro3wCμݝ8o rw%O4dA67qJeVש2Vh1Md&:ipq*9ע>W `&nPFFV+Kq??l\MAg"\E\oĔExm)aOzdI>B5[j.|8ڇz޴hyL;z>9՛^("Kk?Ǟ<  xuSy8͟3ʽV|x_ƹ=e<ވX0c5'f9M2 (fp8Ewb:nK/WUk}9 `@?V^ W`'Eۛf7aT˓lSUbUVXA)\UkIuM %\ T?͓x( q^' &KE_BT9EԠC%~dX#c.ۍGzr vSǨޓW׍v ݹyp[ v}\3/u<;Cs{az?;rX|i֖hÑn1ypX\c8WX(#DEAKCOvcμ]1Y*Ġٰ)@] D(Y쯤A ~\)cy|֍˧h?iIXGZu??R7:*zOFp奁;6dVW`^u*LWgjȸ<9ޜ&NwtFml2CVv^i32oRT_6s)r|?4/;-a3-w6k^m9Q1_~ŠNnUM\yϑ/9-Ɂu3\;߅uvjjN,o쩼݊Cy{)I-n盋v7ɖX.s~5erMfץ2ʧboohn/]$G`Jr|]{c^ֹy8Ӭ|T8Deg=9@gfk ر箓ƇS}<v\͉5hKS~4ZǸl+f#Kz[v[ץL ^yZtM0Bu.R`C6H޻`xªQ:Vf`Ztnd1Lp4wN7`jv+wƝ9EC*qbY޼ӝΡl}Ğ)tUƋ}lg}@Ϯ|ceY?}1Wǘp]1IfavF y`Jx 3,Y(Rab0^ݕeƈ/Cl* e0Zz)?_yZt!^6f/uCi?'Od4|#:w>y ZFɐw/~o(yBtdURoe;yNW6iRy2FB OųR) x1o]ti !f`7g)sqMjVu8L5h+]|LAb R}#nУ|"jK:(Q=gBm BsРm 7e2+nffLøjT]53T5 g]ypIo0 `J[k]5yM::gP^.޿Fz%zYVAk6N}FOqL?=lL%­ %ޞnqև/|ԟ{k3iV koJF4%9JTy\nf9Bm?)Ox44Iѱ?13;fu' *)0d;^y¦+9y3}s{:0\I 뙍~E(J(D4lQSgE5FRх5v9ʌAFHu2.ˍۍ89߀q49gU=.(AdҾ/Gc&m1.0S20 ' B,kQPOIX** 1:\Veez,>l8fu<[i|؛-\Ońrx` (>(S.#h?ZXPqE][f8|=/`WT&nc]I|hcAUza/pM|ks閇 SCgJM LEbΗh#oز5w!|3d#~N34| fظzgϳ[]"W'hVim^) ƽDvfIO`=98RjQu2o,)Eyy5*Z*s Phɘ.L"]Oк֗ ȓqW> ں ,FS1qG6ܓ_n\Kӟ}nEU^?h>^scws/wdp#<ÉU:vVeaGz JU_02}v9]3 < KR2?ۆ°XFU-'H :nʏkyHEj RUcvZYs\V}?5#mK%UCL <0i7d32a52T[ olx-8ݤw5{8#;ҍs{2כB][wef*|W5[o ^k?,`iVHonEEv?:[tä,,u}uU8.Wmgz ,.Gas,쬸&U?l&k%O4gFH#א29;?e?x;\B<4(TM UhsW{rJm)%&oIˌ;͜Ã6dA|~4WǠXlP*tl]JD{2!k~^fgth[K0O=͍` n `8sC\t꒎Rw0Oh55}uŇC' 0ؿ?JI"obr8O*-$H㵃Hj(j5P(3'P80 NU3POu UZ؇yӺj.-eĸ;]0gz " WcSgяgh|+䦢Ыs ̟ɋ?bE7U,/ۄvhrz!yWȽ="9l{^Ohn#0, ];mZ` ҔkO 2oh.=P*Z(_r[wTz~md-_Wtt_Y WK5zRd*r MU#P/rEcVƘVSNl>+q)A<1֕FhB]1J%xA9Ct>_9:iKCL5,T}t>=a<`i(PxiB(iVK7;$1t ^.M[yMh5IkPlFմ'iM]O} UUv}̱JJmVqRX5fĂA5jA(L /wţ Ѱc 2\8ňo2Ői#eQ/ )oK=̯,.Ѡ-TĞD715=lqCb1C~x];vl ˟-?/J=S>f~--m˱v(9$äErCK};3sdv6=|86֠K=^N2LR 8#g!uS&<Œz,ƹ$? Ųx>j\k #R zt}&L=jœLw'JCn;4uN+Ņ*yjO?ANc}b,hv fa[H@͐huPu3*|{N}tHYB;Zy⅌k[k$ Te&\WZ쟪ë 9l6ҡa6Ok\Ək/ pm:<*Cmr ?QO%qV8L)FMp ґa5$RmTSK+gތ*/ 9FS/ xl%BqM>)( efPb9% $9Ub FӰp\H=$DO AYP.ugH"\5zvKr5Cz|0{ʒYc'8=vQ~{=`'< h[1`qd<c'p,{ bu9"uJL fYkZ'\ GgI{ʯ5rY fsp˥Ӻ/i.OĽut ׏}G맆Vu]冲<|/M}q4쟉Uahe_HQa<ȵbY_o-\} qj`뒬ۿǝ6PNWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA῵Z5v[<&2=}| I]L ןk]$r<RY.jX{+W*z?Qzsk|qQuuY~k}HMWm2NX&EZOA~ 6:(`<԰ٕmgoIRn+̲<|KˈGJOL} :o3 xEKqwû KԛK3]%2kDEFu eM~#ȨU37;ߍKۍݺ8 M q8t'|_B5̓^ui]FG0Қ{Ͼ=B#C~ /|C!:a a`&f? C.ٖ9Ҁ0 B,b+=&OJz46䶤5X!vIz j/ctVpve:GX~2\d6i6ψ X[z8VˣPyO.ܔOYrUfnFge!6ezw!~_܎G{G_N3+~ =xOg$U#)V__3gSH8znwt3F:Ҫ?mʀ4$ ,C|,ð0\X_Sd\xIoր;#k5D\gx%C8w6-@3~dz䤹){~`{bvخ߳]L{yK|s%ߐsGށKWD(Sm>w3E9me~x%g@g`ʨoDsC#5pv/ǀ8!nŅpIJ/??zUln >aU\͵ 5Ռ tl67Ff!& MF\m60HA##`K7Qvt44hy;j1Ȍ+۬!sv9 U8S#̸oW㒚ߘT Cn8fZTh]fĆ-~߆CW]&+༮:wF7>d% y5:r(]A M% ~ի¥B|D⁙OwAScGZz< Liڴ=~@V=:P7%CbjTr=\+7:Sa/|ݎWh:Ō3֢"'L)Ƣ925ciS-ÀJ4õ*=eA$[|ڥOJKR0#Opn=Hh.T2R%&$bt̙L5/; ޙKѽ܆1,yuʸ6U~*v==0ὴy^O , |wtG-%)ⶕa"orkY~vF\#5(ۤɆhylԚ u70m&TR5ԧMKwbycWvѪa?M[Z:4*W;y:H~I0 EjQ7qS47zDLĹFʑtr>_45 3o`b[9sAgڱM_cfX0|,ng%}zMaZ_[O?s$;&om8 ]+L7\UD`: "7}1E ^~`/l9R۔;r3Ëd<_jUgg>6|d m i3У&ij>%:҈x$zEjʂXoTx4+p;]%&r*{2WU?dllcIh'n 8gFsU;t?`?+6ň#S64YjH/%KpպO~u`CCG~mG۠[͸3tKW3˚DR5&Fxڪң![q}:#o2̅r٤#M-9!U_2St/e9MyVNVW:9t=Z2qgZp=m)E e%xw''_F϶خ}Bn/?0aKY?K(p*mR0„DHѤ[6xHB~w1T$LUXܿΒ;3eiV,\ǁ# +Uyuˎk>Xw v3eWCM2 ȈW+d9YDSӴ9$UF)pBZpn'~1beLlL9āxӃ#]-X7dMk;CX+1H+wp].Ny8˙Ɨiޖ =z5j_Ed$qOJloқ[q% g ű׋%20=17A~QӍjL@T[F9cT˰ƥ_H+;e|Im -V7h4zB͛t1v5Ӄ.e+2BMsH T@ciʀ*1 Ȧ5h1[M2جRU^ᒣ3Sei }"¨B4:Hk1#HQ"9FͱDk 4CX "J4`]5,|o'ePOcR {-+9`u3v(T8^!TǬ@Fm; ͌&q`ycCPx PZ9Ke_,ǢN f~:j-^Ҥ1]pa}-Zv)a8.-霂6yY8Ֆ2paA#$N-Xʒ )+q[ĕZOWVs#3utsC7R͂Fz$mG/J13 INn<>^_ʧe#6:}r?FsU<5dq#\hoOQ{yO9w mq#FmO^E~}SSN}EAKLA Yg:!N9I.qZJ(G08a!^B{=VأR({DnLDb3#V9Q~y/M4sF i&B2{!g7= %Y᧝=b~"+,1h~#C_~D~ƇvllYCKHR,PPc(آ:Q+ǝlP˥љpNF*_<3,,1"G u3T8sCo\,J-BG젂n帬aUX$p1~=l`7M猡mՍ417[ ؑ vz{rb55|£4Fi/)bnSw- jW347|+@Kt^AwϥFR|)Ua~ h0qoĸek36鿉*h#`75FxoB~yEO)UKj6PzZFR jK@q@{?aڰ3;~T/ګhEm|h\Jta8043Y˭y!tϗwOs5}|=\2\F US7avS Bζ .;Y%ڛ"on#%6чω4;#U{3u4F]#ESD\yl5ѕ%h? >rF X:`Z@ Qjojk,c CԿ'/k{kR逅(S{Ԩ_Gy(nvC3lTHu#UR{*20#xoq  ^goxaRv?%;yZxҺ{4#ƥP8OCbgA*}@ٶP.WCW#CgY/d/I*pv x%D/TI[޵#/]9:0{CS kk0Ώ1v8n9 _u2D[HJ>CS۔q#PIqE1 ͫAoOtv, 7SEotP18;$rB^*wcLnOG,Z`ұR:6B.rpJ*q0JsB)z10 QϬaͶé)vΜ&+?٣ez[W#$T^2-oox/ÅI[C shcu/W5O}yoߢF]+\kzb5xlT_j|حF2Ln焥d8Ep-|_)Jg3']Hiyo*@o|o_s^vTN'0:eEp̠@rzhybph2evGDuY`{/-< p07,οe2"F q&X [F#D,dtc'j8>vR{$GW\lpsFXmmgs)-&aôޞ!- e5Blsz?z0>pHIF6',DS/ 筴UCl-fWX“|Cj,DwۤBoC+ЙEH[>)q2L r{$OzmZ7:IQ&i2+cʨZtY6&^c!F`)Yhvga(g=Co;mUх%qXyʦ[ ry% L"k:C8acktq5x>| LWו%4I!yDk 59`wWĩqN8? 3l1G YwΣ M7~*o%貳-e\gh KSrdRk:m3xx^!@LYR_S鿕*\y,#uhKu]`w`=~Wiৃ6=.W⎅1p T#X{Mx;Mp3y]$T޹.K Rw)$k͇9HMB$N7Ŵ=6H Iv)팣?"iyR#c438-7:Ҹ9Ln1g<4 ƕ(+#*oLޏ8wmD[jf2ؤ~JIwƼ.654^Jgz!tSv;Fgͼ/ԇGin3=e[MӮ: >wl8(Lgp1W[E>s%;ǤH#c ǫa#= 丹<"^U\]1Z ]p::\Oª y:Afٝ87_Ƿjz}Os0x ^w@~V />ֿc FE^ Vh:|QT2k 1sG /H|A'hᬭӴh4],::Scml`,OvJQI*DUc +&O&/u0>$:_5J4XC~{1wb,-P׷\NN_SkZ#;HkeP׍%dn@*/ZE=+ OP A}Uo͆]I}}ll_3,¬ 4Âb$wķbd & >WSҙ> z`༊#X@[G9CT=H/jB+"-EHn3>!zac1;N$}U9J'P%qpg-00gb\ ;Ak z \Cnyd1?.~b%hmkKBJK#v<6!T ,F/Ezm yX0aGGʐ_ CB7x\CcJhșflm/LOخy5Po9ayK*1SFzi^=3Wyn-)*́7Ho0oiHTc:SYg]VCǿSGn|XpPuB~0U)a Cj7!ʞ1/OMr7m`y˱bU0f:Oc6XSœO❱Ve"ù|dY`G\dUm(,-OwgÚv+hd1Ȣ>Ryo;Ti 3m[HUM9$ɡVſc/ ϵCE-vsCI7= +Vv6:4UZP < `,ĸ{zsEW-U@4$6ţ)R¥S]&N8_+[(pV2g$a-%hefZ7P),(1Z-x{9Rt[-Ghg*|Gp[Mc= ܈{oӌf$7W-ǧ˭EO4pD=yRF],.XKi»tF٬t[XDMJhsYӤ)9JwӞpw; [슠zLB\8[CYSv mJ`鈌7bxtcF|ah+ӹ72JjRNjJЅ 268Xb{?0Xc+,ũfz"@(9='[\ .ZEp0%#h"=8WdN*c,]d%dDypj_^Ri0| >ѿS*\fz},pc(ZU-ZWASL:ût[U9cD~R69c+^cWVpLcR G$yRL[k`=-14U|J(ߨJ)'BgVPFںϘ swa􂙛ENY+'Q%\I^3?Ѭ!4UȞޫc(УIoc Z,JrŏZX#1gL?-s-毰86nUV&"GcԳjdITZH܋?hK&]iX2l~29Kx Eh-0Z0x'uڗHӸP. 2LQЭ' d/Itl_m~|&â ?Ҕp)\ WxD1qFB*(CFq"_mb`§X%/`%-U &'Yi6#9.am56Dܻ? }{[-dI=ȩ2c|t& O0Ÿդ^Lhn*%4#lgý +8hj(a::GfQs|.CW4xpRutA|CC!r,qN2=$8S@' 9%HƅK&XOs(v')΅j[w-_>AUWlF/ (B>}fPK(H nshvX5 ᯉ!:cqo * *|B~s*B },@[_ㄼ-R;G3&cߟ6!/nfSKtN6CK}: /):l> ӓ+n01+!ln^]>Ebh؆$ɤ6VMGX,Ra[`fv g5dz B :pt03v{eM~5S)QrUJ-FҡG !GALXe%,\Hsˠ͵Igu=ƍ {. "㼝49VG]&rM6V #3wDoc44AVPL"<,6Gu.n*o)0NUȞƴ6h]k۝V6[O Ywc0kNaKXb9SLV]xBuW{SJpLTgxtFq:V]1G0Vi=W hRz-mgaFjg037+IC3h󓔝9#g'0Mō06U&^MZ<z,vθ1\T-A^W}FjfZDŽ4Z/#qG~a}zLkC[Ԫ} -4#pu߽Z0,,o6RNJi2BOvx(MNW1. |U1 weq%ޙ ^XZ\¶zxiKk|Si1^D[50W(7n. x8#9|DwaX9Mw-1;5[:< ]jE3nenj+x܋}La+qe,Ś#erO䝷RCt+]yiu rOʨHSO& |~;BHdX j&ۨS`j5<$-ݱjtA%_PԐ0km'k>Bq l4.Dckp#lun ,Jc#fӶ43s#ɾ]軛$Ue< [Og]`3\%4CJ#\\G{PQUI'A_iժ߃wK!Ⱦ-8{l30^}fXGl:iOaqS~W!|l4ʜ*5cy.[͔B8F;#)A)sE$8-XFپOs=Ԙ)Gyw9O*CG%vTL<~`B[B믅yc9S2}?S jh-1*N*b4$j<''tcF]y 67G7}&nTtb0 D/6p^!B'j'mŶWmiv ~r+1 nJge+gO *(⮕ hqWAAmN Wt}Go9LtJShm91!F8c[H'))tbi}k?h&Z2ft3).Vzwr="^Ԙر41V3I!K<#n%r)Tf"dXcz[KO3$/ o3SbX Y=Z<믆!R #tx a zOn7vm/ [{z7n#u. Yя4`;:; "m Ye8ـ1Z(iP[ .؍ <|< Z $ա{([c ո9U.]"b=%Pi%ʇfRdњ_$o,ر̱*SyŽwNy҂v l!`fnO`pB~(MU5fjEQ8ysQSb/̵Cb\"nF2Ū"b eJŽ[juK#a/-Ϯ0em]ˠb'5N j$RaZ&G|\[6l 8M9o(xp Ո~Sr*PN;R?=~EJ/-gRgAu3a!>OW?_i޹ǩ;G V!ߣR4ʓM!BÐ *MG{$Hen@%OOSBi*jB?3ƫ65z$4jV Z4Q#dX&rW|n%kBO0%[Rr9Rl|\ocriZ0|fјPc&?|aaiX6NʡIwShq|ða҅+d'چT6/PJ:ϮIT_O1)μ3K3$P{("YmT?TbXip~+aQ&->!u86 I2:"SƇ~1T֠S (k1D_Hu#qyGYGb6}egj:I5mDbd5s`vV#R\@l<0?ˎ]; UW_Y&gKb .6X@2ZrFl 6JebbG> >ZYiCo##f/avc:#gMn)TJil 5g+ 9?GEĮ`f|eedwx^VϰArª:fS+^eZq&Tu~_cM^π .R)h12 6<,Ûp:~hˈ\n~u4|f:ɤ̌zobE8VH4θbn~%tϥߩs A)Y_id E~wɸ4'PUjN0CYWЬa$H.=75}cw㩣O%=udͿr6qD{豶iz*ڪ[Mth=q6Sw B0z,کCj<*׫.Ve 9*:xmРv mBX C8A*L?>#9r\#V֘; }Lۮf-DؗdowDU/9SV\t]b (~4neyϪBa),CiR?rՓ1%2}WAlXsps=uk yZ XFLW<ȥi9 $2tR#mq/Akwe&L&C2OSR=at*fm`d{L;x# ^Zz<򅷠t8{Nikct~hFe=J+N )ˍ00r>Y78BzWB[Vh!896S2E ' AՈ|OȚ:^T dUXqA]0Tm}"#\\aW9 AQkG wBzG}s•mf_LZKǽ=k>Ak _Fxxq;()+3o2}X(sRZc .bdl]M{l+ֹ ~oMɥ:"r ᱥFnHwCt3p7Nn ݔ0|82MT5FZL]' !gu %g(Tz2"̧{}koZ $ FVvB:ҐLK)[Gz)m^b2ܣ`}!]4gaP+X:Wk1fqE>6ajzKA|-^ Ę.*,yGx5wW)b~ (1Whڏ*ۧEF=y:,n`f_F`5~Q(ǑJu ?90K$G9b$9 ә4<&?+0 0~SDm^G K-arkIW,h䚷t?1bN;aDŽ5 .'Dt;`r{ ZLet>lu.^[J>yp6ŪI|Q'Q.=uh/8X檐r l03uڋGS6wѿ: ?—JĚ)>Z> JˠtܺZ1ƮB+4 Ôo(KĜ!;eiCCuտo~!հae\B67SlCk4Q"Z_M <2U:WVPAH7r|슚Qz=QN%^nQ^ 4OŇT8@bZ,)cl;" 7,59Fv,QZHgm㙯qTWcokr٨Ffm Ѧ'LD'>N-sç)&'5ǐi|,g~B&KT^'Zcwx[@'|-Xo z_SšHbpNp.vcK'YQTk?+Υ*yvG=WeD9I8'onIk=bg [U@jp+%3 \OEUsXa6rE|,6БԼ{}{wm+굹4(`w"eL1ơax&ƽ92iZ&7)SPw(0ZLi0XԘ[xz OiR^GDa4֣ up(Wtcy9vptv³B FR/r拓C4٨r6axn?R3 c i%.-acpƸ1~i '[L : 8(l =߁qeU!xI]Xe*ÙOj8b 0]ԙar6)А#_hS<ĈZxÆ7.i]qs;mMd`RFRo*5=M_+Q3faW2%d*0ZމrܩW+8igJt8\B%b{K j\286=ʠyy u zTB8G4}5tM $TY2 W@OAjiKaj$V)f-,tJԭKn.AN,"I5h>o܏1]8 ! a|,cgh;ltj,^' b/5]XRkuǿbvCז C]\w6U&RUYBC5R'k=1u(q_ }Z\C& GVVjYЗ iё]%$%NCYEditWRT}$Y\G~oibvD.Oó(9놓 GZ,ע^*tE=`׸':(}we;[[Q[L[l[AN|<>3^3;0;缹~]gcނc1f9r&cLJѬBY= w:ْǘ2ފ d<^<0  s G~v83F6O#pdMJGM2]jt~ɏhJzo]3 %Z_o7,[ 15l0>5Zk - Ћ:KOWl;3:b8KsDQ[Mޛ7zS'SxE ^%ԆL8 4P0MGf3Nc[1&#)'}āV1t.K?#vV]C WB-ثҚڱͳ͹nn?΂Ҡ=LX Rqsz&^ KGIcS&zs;-+ac1:-vҢz7[fMJ{(9{;$I k1[ 0a,Ljb=r[8$VŦʋޜW`**e7G!GuT1+Q p cvտgc7lPBæRz܁d]mchUo}ݦ?}+3)5,fOvmɖj?)ҔR\nEkSsмI62Qz¢d*rQܧ -8 {+|֋;}\Vž||/se>FaLM!-Skx%?WbeXf.FqS`U|n_J"n+%J=!etgOp&[g٣}Tia~8ĜŹb}}Bĥx_?U]߳WoїYcoSӐ%x[z mGjD8Am$)djAqn4|ĝ W;WDO6{sl/^fCOypӂ5|BC7c9/s%83#]J,M1@wB`;2~h0)|K2Z~E(Ysס~qD]~sLݾ4~acRCZ;+ު nJa7>ˇ29Q9Zc/;7~ۯn=jաKZ7ƇO|YKʛÙ:>l5S6bɷ0]^cXov !#m4nOBtD<?V /`+͝y #9'[r%h å[k !'lf  &< ?qy&L~? 8і; )*6a* ]Lkœޭh5Kzޫ&&ƾiHy/7n5H %b-w_nQ#{쑖"H/5Ԟʎup<|DŽYvtE04y+Cd|o .}|8x;@X#1P/?_]oĄϠm9"/0f15沇kĎLLoϷ 9poeϫ~h:kj\K6qL1r޺c(_6}_¼G-x}/4񦺛/ ;u;*cśGq:^T^17k4͚=G,iδ{E @[)#åVw,.Qs̗> ]A*P2ixIkĤ_&z_Edu:׮ߖ=0ns{x5|'oȖ,LnYi8\V3PP)>u //?ի0.p_ ~1C, yh1G6W68C·ﭭu*lBXjMqV\D*)ְsԜ_M PB4]>TѢX͓լbCOI8ƃ2iP?E\1D̟loʱ`O(3ԭ9]+P*䐓wU.sA=x Vo0y;|,Ւ_w/#ڄ.`h98Y8YX9!J)>)GW31̀U~Q!M9"lm–=%FE3p ȩjTh}r/.JW7`~w[xr: [|Y ŊcLJǣ_:'=ŶVk* W5|w[,5&Qʙ}e&矶rqk)xT[s8&\y{l'a*|qj+% C&:^-:zŋsr[sS^,LGs23{a⮰]#Kzyn; n)#<E>ĜlAxO}-v>chd/M9Z).DŲ_?;1!{a}[%Sa$葐{S ?=_OmNw(J-@ kWSm&nOécpĺ?=,whor)3ߘ߫Ubt ] ބ9+9h ]_𡅒j}M:aASJҩ*bɞҏ#\L= Oݽ;<>D&aз=m ƀhW4c5?Wm_yuܐCYhh ʯC|Ĕc0W)x< ߥaWd̙}vn֕D X7k &uw_,\b>̜L8c * }`E*fGkt/a ڝKG[]_R3IX ya^1/E(>a%U+Q:NcCnhZU1PNg%[sFa4$=gCpOuNTǻ0nIză!~'brm[g>Mzcjr J8$r 7<ڼ=t"c'2!g+Xh'Bh(%# 5჉*V,RK 7ְA˫3qE.Z*̘#l*.ݩ+d {bk84Q?۱#05`RG`:zaR٤dLkCw}߮C緵:ޛt䎚֍!&<׵ ޷4qOѷ0%?{kxt.pLva|`6.-D[pXI20+:LuOy%ߴu7W%3=ͱL ޫo^^۔!/wn#ia V h1.E{=|98^îm&^QO[>&Z˾\;ILJ;5xU%kea#E|SM7"xf>߁|#0w N@e%yB3d, vP%j0p*aSTLT9>TpyqL9?D9RJ>% d. Kk'j=Ty5+լx5sUfe%˙Rʗ!z϶L|tOY]AXh{Qc֯„LﴌMԱn;-+-nYR~yƙj+(0!@hiωq]xόX<S<8m>r,c$^4q5g^ⓒߔRusGsWrI]9GKl!䏡Jx_=Z6 򬭆.4ިfY5Ϻ5QemwRE18pl8-h|Nlggܨq(Ms ,X> .XR*d_>?U}t:|oK&+YKü:rof E|dޕ3 h+O)FD|Fρynx 8cϳ`qGN_#(b)n'< Sz:q)_[q}K Zu6绮fea5LcjKR0irnS1e*wvcF}P/1aJ-v378u/'~aih=? V?0&څiw>\1K. e-FwP%*wE^tMe9+ǻ[d@s630!ǕߙB]K[0ÐvsXl9_DeX>+G͏0k>zٿ"5wDU'1&L9kG]3W& :I>׃݅|#XʈR Ûnue]E2Iyÿpfu^DI* |^<  |ICB?F׽87O)yy9بʀmbkmzmLĽsE918ӆG2pTk1+REa>(gx~(mj𶊏N( }UNb5Ql%$Ekg}̃NEPHIU$⋴Y~mu3< mMo?4y|Ys@-2c-~6&j_~0g<`ZMp-'iㆎxD#]K{ Vj2VU 2n㶦 ƁrNk̗8G 4aPcaV6aԯbthzUj[ǔI!r?:Zk}x6޾|)dv&Rq4 Ǽ5ZOs}#o.,<W ]bchI;sE O e;'LۖLπ3&H}/_=/ ƌgxbY &<[l@Og*ɘI'}X.UZ~V1y%$( ,\9 ,‰u/:2Ƒ?:8>%X Utf֫*~ҋkZ s8@Fͬj&w0kX{qo>66Q^{ʐΔ淐s82[~Zmǘ6=̚Q̨6bL[U}N8"vTFEO&0_ʟ4Yu!=<4OD|&7Y6jˀ80u;eC6FXES{ԱXG~`/Ϋx,ϛ7*}X|Y_5l<̛F|;GnT,8aVtJBJθ S7vX͸wɌz.LBvmEkw 9:|cKԌlvlo0XȾRx`3WX(Ӟ/c>ܖYp:3.`Akb5ABc[3w^x#UXd-%W* h/j淍^D\5ueB9ךJyc'ftAqyw&ƀcNtۓ~&ghUͽC}TŬjT1g:zZ˹u5r8-ұOƨ咜9գ+g>Z.KOx=1|m\3701#Mټ4i82UWx0,7d/y^?jfzE޽8.@~46p_p;g_#ZGqR ֘Y+νjSLbV<(gk& 1#/WxйJWt,$kj%9Qò+ӲS -vxRIȸᆄ[HG&el\KDsHŵ;:G·'g]>~ia {aǟ83Mb(]+`Ռ,8e 5f1+Mv׌û[ knļɍ VԬuCƢzbxHY>r[/bU (ecԴV05uVqH9_4P• B&pa]#f1ϧq~c٬8[pC9cѼ"8]v6`aWs';ZqKcޟ5#*ڦ@]ϤS3ԀMj0/̐nYs-Ǽqsn ^rfW`-O-V0KE3 mr"w>S.N2WpeOO.QtIM/%l8ZF]+:1{ݯżU̝7D{xKYRŌ&Jcelɩ_kSf[קy>9'Ϻ5Vcj3<$ +P!pj/#nH#.WM dö6ɞ]z9N-y2r;py 3=L7a2]L#t쬣6UæF*^5 c" urL;ni8=f:1dKfqZ9S>5=ܨ,r.ѰWRDgV qak &9#ƅ/TAE m`r%F(٭nk#qLCi. (V"w`q5slIIܓkFϨ՘xW;Y,z= {sO[z ^wޡԿ:,¨ĸD4{]#0uA L㍩4cLxk|^˒MSmX+ԁmec<ەu{ }'J!S5cCZ8US_E2_Z+93U\䧤3{pmkD|ЅY.|ENlÖjplb<º8/9w}u+KnX% WcREY_LV*O1+p@X b|ώvM9۴w\Zcb7Rɹ2%/.J<_ ^Ju+ 6p1Cw8#Ɂlynڂ'b3{k UQWaP%:?TDnٌw6izj: ff"`hdH_T+kH>vE{q!ĨFl˜W-WuQ!fgŞy!i=U!gb{yr 8qjUXD| zc[yW.VΡNRF8Kj_93#_Xo8-YpcKȳC0fj#f'+|FK1&#8~+ bmZ5So( G\pU~ -OB5~6cN5fk3?el8q}lBEC%Y. YdzZ>n^lcG-;k]m6Xbt?9ERNΐr) =+Ƶ7䖲\7V1Ƭʒ\..lY2K(Rso}.z C;N̟aeCv51?{-u|zlS4KmW.WL݃?aWbj09` 67YPÒr~x&/Uԓ71IBn"Hh+q*<%Qs>b2Zr q0vy{e!eWw }#OŬ̗Nbpb?}o.|h&c  '}bhKqge{0}dkNm[~=%kHr2v:e0^G _kȶA&lɘ1֦ʊ=my-;Nq`+'ζv1|(I*Hs/Zjw{(]J~W1iу+ػL{1~'Q&Ÿי֖>qGp575r窛󚑒ߗʙѓ~T%(dKwO[gjVNhdvVFj:H?a|4+qUx!姌l{~?<.j98ZJNR1l'td^ r(saICS`7͈EPD< @Ux9w$W!ŖIm99T%˓/ﻳxfeBI 8sv;W ?;݂sĔFƈWcg9)D_py n\šϣ3J |Bnrs,5 q֝KHgEgQ.lo-!{{bT?':>o-eurM86~{܄-d"ȱgTWΫ-2~(VҪHI {07Е8p ȀA%;Z4y,9_f }Ubt^I|/X-pmGYJ3l-p6%p;=' bL)zbs9 DŽg4 䑝Vr͆YfȋY:Cļ"WC d#0p;xd|Qo8_Vȴ˦ׄ>N3Xœe.Y'N ]hA^\gI_1ݺFGݔ}Ͽaz`rqrtf_~iI9֞ZXՃvk|9΃4vV O,5yuO?C}ZJ4 Gٓ<4~Y sMi,ѻm-ف{yʍpTS1#|]B27wE,8m04x7%CUaCtK!|Ed5D .N)yw}٭ OxT|3NA~)'-7jJ*ܟ\xl'X_W;[-x 4V574I}p~+/~ !>Ƅ}r1cNk!V,k ~-Ov`="7s™ÅΝ 2-^io|'a O0LŶ|G5S~iO>G{9Cb#[۹8m<[̛oF$;ș;1N܌@C6c@~k`Dirhbћ~޵~y3\0F.ǫݦ\̘Ζ4w6|Ri˪l"bM-irۅ%`l dHOPn!\wQ CāB{)1y)7ӡNJϔ̪w{ | GmpK>5Gf&s^tc'9X5ku4ka| d3-<Ϛ>7#Ox?vM-% bȽVlfVoBeZ 㣑d^qص+z`v`.KP7ޭ4Y j^Lg.Tx9]Ō;JERkm4rv9w6q:{W9s"Qڙe]Xg8V%DyĎY56BmLe CY{Cp-% ye*#0!G<6 cjo;QVWhEm-tx;g8+#pLwKUJ#7zd  )ܓKq<xOWgEbNx8AkPibJS~134b.qfY"Zrފ5K3׆58}/?;[o' 8u93xfΚ@{ʮct;QU?mobQGI'x/K|dF NAtĐ:x#2䂺 uZiHOK3r#bw8Nm}*Pt΀m9;i^̎*13ˁ$ߠbN +qfn3'Rax3r+avpW3Wlv^8A`7W3> &;Qs؉ ![Zrz{;myO@#6pxkbXu[ eqLX0Ӧ2k9ݯ{;zŋ9qX{6u[U]fw iewiwwvwwxJ-ݢo_޹n 3aױֱ~͟VtnžFNlå38뵱La~wGK=w83K 81G[Kʏ5Uqp[+/lu F&̬+$#wgrOEJbA@_(=װW<?CGS`>h"50}a5D,[zAOAxW np5ʳ1N ֜ɘt#wט39lJ<گH;/fag !18>O&Jr-g,yt_VOE3/jOQg야Ɔ{;2Mtv]݆1~֜ۅnڰ-WQFMpS:-GS6bmvwawF9Qʝ2/p)uS=S>3𸆷 ~^gu# DRρI΁MrOh'z0㛜9[h'{&eb׸$Fk (S /j/WqV8☒Jy"Y3.8_s}`X!_zwC!i>w˸w12^Am =Z8g_ƈBv񂈞N п،JQo'L_bn{ljFu yM(`NZ48N? Cnm P/=eRU_j pJ[QfZjõlw_C ll[6`GY|~ę<Қ^rAO"7*iSCc-Arm(㱛*`.9?/T|Ӓ-x=}t>rf@-<3﷋+E"VJ9-Sƾb7T!%Jܩ`>Rky;oͲڲi;rQg&\-v|leHJQsȚu6kےeHQw0a ĸc{<5> ApI9\N̔sw}ֳkM =_wӲ{}3Ċ;80 MM8߉]$ߑn\3+V 0s#;TrS֪KM?ZK ls[ ˒w KFzbT6MLi]OzwdRn( 1cY:s5sgQz9g_mYjMɶHv6ӎ@Q[nhϳ%Җ꫹옜[먨R똺ĊGjܒV[J9t* Xo fšMa 97O$*sKNXc7-${f 9c=irEIP~73a'F[Dػh%~/P}뿶u mֻ\ ,q3v}%S)W9HXYEW32ᒧfP\r{2WE*ocR Gq~zq*Þi)t~A|q*7ܷV8H>*.|s4mh`t-@wvjkxx=gɎ-tg qBVIx $\}R|o9ۘ/\:]KxM:)3oOgY1k:q:{ N<+p+.lǿ=amf+On8x;K9%;1ʌG\L)03]e0Q1-T_ 8.qx:5 >bb<n*4, Y?(68 6{ \c ]?V^> B`3ǂ9_lPg-uT3fတAS%Tc-972m{Bq3t6H>顸a=9x8jt0 Z↲+;WEaNY*'V<^ P^OQ}/;Gj|f :t-8}W\S ZȘcuYG/&랆├?Q+>יP֦SZ73ߛ2ʒ"M Wel-W1t5K:Ygjfà̚avܣwdn5͟]X@AoUUTͩ6z1)(rPD%(C͜\,KzAFՏm_"P&`b,F$)Ix861+Œ Suh߮%GA6v3coFG)?X&zttd 6uZV}P[R^FB՘6gc[d ]~Anbr.ďO ^~騭VF lL6d H}ڸgǟ ïx䐋K?g2&Ό 4Ҝz7\u|7#W)f{\bL1'Y-ˋjr<:; l[{s`P>~ĒǯE8*D4M:@{t\`={깦;d87ST+gK{ ~ȴNܩvk'qba[cdÎg\57⾊]K{RKx'ֲMG){2HSY[h|b'Eq/tņ{h7LQLΗ$>r6{so E9 W8pA#Km]8p}nc5|QM1C{[1JJ%1RLU'Ę_NVsL FT'88 -~I2vg+j+$|~ڌBMjIf߫!SK>^ŦC6?TļPʷZ S2EI ƝVIdöޙ5S\EL pN2W>VTo2HE&-a- fDX24ڔw޻T".?̕4w_1/B>yocoHkx3#5f;c_LFFIu/#Mua|gi{vLʞ Y;xx1/w-b\#!6ojP7*aԣxt`ZiɎR) 5pO#]m@MU!s+04 ?F غ1YD7e)x5Vɘ^vhnKןJN #'VY^k`}#zк'9q}'\ܙǃ^ecwk{@=s[?@yua]=h !]1*oDOHV Rsiҍ"NnIb=dj5#9(ж7(Ic_h;;*iV#4SeݣDuϝpĊ+fp);Jv.Y t:#wy>ܘx Cwj7R!^D݅-|l*Al_ss{x&}'/ï}G&l/5h2GļXʌif̹e1O G\J4uޕpk9 elgt{OgZZARD~¾ϸ| 2' sF㾌he*a/X_[EJvUr[-;)"V<^Δ}Ns>Ӎ_zyФƍ9q-Cgr#(Z-dٳz;NɘŜclѲFb0&ae8Ä,yODѫV7T\IʄB:H0E TLߢa&[ˋ-9qYcw*V#gub#A˜t)Uq^76m5#hy-iYCU,fF)(A*š2$7:W%}i9N5ڋm;XV L>駏`1:0};z?s;Cv߿̑1jyun'&|} gA '(4@c)uU:6je9-ƙ}]pӳ2o]خ#|[%e^r۩Wx]kx=?d3[Y&ܿ/ D~ckdW,BzE~7o߸OH |qkc l˟o@-[o1b @i\S{{>Vc6 Y)&1r:;ұC1„ă{UHZ  %[qКf-\X™L7zc樸]g[v^bÅU%!6% ]aΉC ~;c\s -U2ng5S|i8e巬9w5 8+']}Åa=fC cX&qh[:fA೰X_>-4Y.^Ap_ TmFthHaY GNmodvkJ,oˬ5nԑKv7ƹ3&ĄDzR Uyi~ γ Z 8QIt+l߻#cxC/+ٻP ,.a?i'湅\0҃»,7q|t>l|ϙo2;ۑ=X=݆/˞><бoOkM蘉6x+c#oDAp2)LBn ;X^?N˜kkiy̕]y"#l9xClN-T$v]XfFynC_ +&WlQ ( P /h` gu Bxo7wBLP~+ưrlZY%P?h3ڥ}gKv^a^Q).B"z9ϋ>tzsÿ{>N%5ޝZ6t-rpvt-6͹x󮩸߸|3Qd%/yxç TX*W3m7Xr5NLǕX kz`Bt0^ ^P2JrvUr#b )S#lݸǙhzkyF-LN\DN6с=uL _eK(.z-(,Wƽ9vl^C,GV|2ך 9` mxi=/,u^hb[kgnAqԜ *ZTd#p`+¤C(y>yk<ɻQ2|FFlMo a~UӪ?ܠ-cx Cd)++mՁ{^*8$ ܽ}zø W,?8xݧ۱[#Qo<_rߎt _8vi*fJd_#uUs]gl,!Fk},,y|O)A ^ {CJl cal4&Bl83#{XY[Kݜ`BwE9/@jUih( [ECu2\P=O]=_7mn鋑F[c,eqe\dK s%x:.W'`:% 3mfͺ-4X\@pN.c">", jqFΎ㭸p5CY8PvR>Ӽ5{L"oT`Ewx4Ɗ j6[&3GnTdSL r^ܬxe /եǼ|>$F?bUC6m\.qLBqv {w±O%VpY%_op[F\>-s H;abХw8~tolÅ{<\qى_ִa0[_sv]I-~vkf :n|i d.fbVgoOT*Ũ^e;QRe_p-1gcN^&C12^Ѳ\śB|vɀ!/C -q@:.Kƞ% kB6S{.,8ɽvՓ1.FeV9F@$Zcl@2|TddaJXu2猖ʍd`foK%|2bf9cx(X쥠^5ֱRrN)^&1Gq{9pwvR亼cVed/_i0f+ کk<O7Q10Llwk]oʮ-q)E[Kqj0Gq y#v̝^,޼ƴ7Ouδtrd_+{-1䎔0^Ջ%UFA=e-g63>VO̘e x\LCvT'n$Yz*pј9&[gmO) M8# tlddgMw=Kx"L[OU7[Α:1wZp]GD&cX9eU9{x _%:S+J.82Pg?rD!GvsΨXk7d|!Og3u_{ޙ/yq)j8qoaPh߷VQ1w)ZU 0#/݅ީʱx2>hbDn 2H٧=9$޽|l^7[^x+E}"f&eg_ݘpƅ1M]q w~ԏQDRcnum.cr`F2\.h9OWp -_fZhI?F4s>^|9ƼD8>|vH[&M*㔊SYQMutkŻU02"FƠT{ B(VKbӥ1Ȳz7ޟ/塺>MF$~BYKdحzU-[m1--sFMzid`T:1Z{&6yI6_MYqM=Zd˘(".MΈ4LϹjِ/u)Teu|/sIV4?(f[%N'.B7d(fOh 9P3ĸy4sn'J9$7l/Cm'cN;'t/|8Н.2,]BK \湉jʮ˘?FΉ%Cvxꌁ+bCAKX!AnQVM$t t:EPc_i)|qNhͳ V,sӷj@jx E{8r&e5\\xLRO 2ͳ92&6zs)ul,cJJl!Y29[U2N-M,f:0s}CKf4_ tmޠs8{47C .+M"9龒,9}lt]/45vN:QoO϶;&Ճyq=g'f&,êQLduFko,Cnd0r|KP Bq [ z3WLTpX[qe}Ϋxŝߝ9NJ:LHr۔!L%2v8'q#W {7ZK.#߱<4ԏQ)vE _yy+ij_?mxʼnzv2==U[lW\g<8-8^YIhһ5o'|w'&={א>I{p2.m-i_dzi`n~ⓨ[>CpYaQUԵTU8ƄUFp+ȚPuhV1 q`G-Ny̑^,LWϾM_argrx05K?FX1R<4*ū9?}*z&ѳXtz=b0l'8sT& SP soJ꨹ϖٮ\0ߞ](x1BLR ~HYyI۴z߻ vg7K|vLFi*`& rVscwA^ OEo-1gnoo1]k0Btx+!n_ ǭѸkDlJ#3ID.\ɍv=i8+2>}aI>)d"Jv梘3*D,# (N6od,;|ҼNsmOcX;c{ GyzTJڤ*5v*'sJŬѾkvGQ+{&cck.G՛Xń*ܷ2 '8ቔO,TlwF~׭(]jǷpmX3c^ yԜ??QNY}EВ-yK-//B=Rpn) wE@((/EH| l!""+*ji`_m |P9+gic|6NDU(]ӠBswxf#@kHÄ7Ht^`ǭ,`>߉x& {ÒǏr )59+ pS .[m{|RQjf8?P1m9 \٩=|[<7NYue+}c:ꥢ393)2ZJ&bfVY2ڂ}-gSz+0.-3ۣ~0|;0? /Ld7zF]PLVj)GWǟیW[ҡcJ&P&z<*dAB&>%5Pg)X5:L ۃIK."c:x¿c2!Ǫp:Q]*f>휅ĉ c|ǔ]*B0'j`N"G8@sMG, ΩR}\]MjгO,#1{4ly cA,;vJJAAl_-k~ق֧!'xmoKz7GpAU_ a Elqlܔ eւuX [X_`!KƷ0ᄀK਩9 Ao +s Qe81MaobPe V&l҂KY2IqUPkimaͷN[n{ǓiYxo-YْA\|Yȇ/ldζ,OhNH^2 [f\g HXɏ,‡bn9~0a5LCނ|6ʜE m~"zLjW.= ZZV[揱g;VtP10R#"n`-4fzoos3jRXjt+˕ŦdP)()OZxv߂ QJĠ!⏲ogq_"9ntn&c>b|􈨁Srl rfoS0y iQ'{&Kz8{/rTJY.ZcP1D6cWF?MPy+Z;lzcY}ή[v11`%ð-AIP%ˋ\!߾iJ-(S;#nִbkkÖnl2ɌkTp7Ì5Ʉvlvڕ:1Bf3}ةm9ؿ"c^~Q ycWl>o:8U+Mc9ϳ633t^GYLn폻 ~񳽍Y@b %.CtX;/zU7=ȋo?q|+Wi#q`=7Mv`Zq"B8x-ڔ|AZ89Lg`rB5ruȚU"aR_$cN*8۰y 5d}V.eRV͟ty6ȡ'N`(嵻ܴ5j6vF[weJ!?A97S6 ; +5X?b}*XR?" .VksCUZ-DG޲/W#}1aA%첡Q+Ws E4c7 1rowEݭX\ۘKF%Ey&O.H2$OQќn6cN}tMƙ[(e'P57$"?}פFjĝkM'"`| &؅&8`GW+Qz/|B!f { mm@q׌oeg+ ۢd܋BI忿윀[2qQNE+I>4͗rm9 UЖ@3;3,C3b  ]?/ ~v\DcP 8kuOc`8$η`wDO9TYoVOX,fauhB_OkcqofXeDp`gGx$)G!́Ff/X=^h6Oow+n}o1X[0 svޔ47`+N[Ñ&%,^a"ܦJsamhpK:|]W |L~%,b6.6`r/5SeFIk~lU:w^5fDT_!beQM&MPm{XޫӰ^9"65D}^d}Vԛ`]9== 3K`ƥ8%<v#O^\qBDw.aеo&f39tĞ!a~DJTڝJƖ5y$(F!GB2aeR ѺJ0C b_4UOGL5C1rb~a~>|W4#) ޲ZUQ|΄賅n-&d`oo.0wѓżiK 6*.ӓ^=r;jo׵wu%ynI|(.a%_T2,\=|σ1Smyg{7fgblZ^b&k2rG2|fu2&ΑEs57'GCy~X<_Yq F~,F?a_)GEG [$>}fraY5JW]-[ØxDzjJph!־ŏ{Yߘ8w#q~.ߊTf|ԀN2#7v﻾`El$~C/ޝ,^BQ;4蛅:oW#$n:^h/zӋ!NrlSfqpCFl4Z,*C4]*-Y։c{2FŷLTr4*x?HƇ 3 tP1X$G R/vRr{j|hUuLItЕ:Z3Y%& _ L8k{0T-jٜ/<*]O-$|H*/n4aW"އwVLHz@0u%&߀`nW |!bKrܘ7Fw&nJ;O-&'yxTpGo8`_5K.O=qgV"cgJ٥3ېü: t5P]]5 6~*x3"WF@x",N-܍3)v զ?}fSЂNl/ipЯGkaf!ԒD,8^ D7'HY`lk-c* ;K禪(Tqd%W>E|2 f›<;Rbwl۷%8✌u݊{vJJXkF _Hw*HWUt>jejLռB1?n;PVoFkS#P] U8RP4}mش֓$a/oЕ)NԹYf!/5}AfPhu5"b$v*m).;k1ecS߬#C0 /"%p6ǾFY0uY?}޿;. H4V#cyq z>tDm<fG[85Ƌ~prV9}KFMvX("$-e,)h[yC<ڋY%b`W4w. lUp5nB}MN [ ,Pg?uVΏ^u?^KjNRp,ć?3i[|ۺƴȎ; Na}7Y9Էnͽ#)D#N4-Aih3ڴmXb_ ~.bHnn50MKr̔#|.*oTcХ7ڽBu <(&W}يcXgw窑ieC2%=OR\w/{b Cޣ| Dzɶ l3qȃq^O2Rp{\*d ;txiJNUqsVƛ̈́\6Q;O(c@1#߱b; ؋T UtN9~Ҳ '7q/n:mBphK9`/i&J=PrWnPk$4>` lu!]u=0AF2}CZ/q|[ g騙ݎ& \ga@a6ZO1{:ሽc7jc.ZgsZɑnxWߊژK]VY!|i9f!l5^4բ r`<%*|7?}Zh.p3k9Xr:ʱأN`f>l`:< =՜5lԑ}\ЉcVIy誜gtܹCKdUUTQ2cӾ+颖1o+L?>|Ջ'rHqbT2^qG%u7\X; [}Xs)?zSo*4H͠&\8y6:ߏUMoJsOmʔT֌7 {C]Cm(e+[0\CFU]MnKL3*?1 'G bKjQĻBLӨ ѧ  P}PR}Ӓ3EϞl3ZfJ|C4k@Pm&&IncCYjߋ:ʹ`*1ekMv7^m5nmy-LKr嘖ZEz|dLCkv`1c/"dR-gHK N^Ga2'cV\#2N./n Tᖌ(䅦rPn/rZSiFMxbm̏?5w)pLN .SXR0e/KX` V)x_j_vO yG77r(?GsdW>vbSN,5=d fy,HzuÞt̀uD 8m_j; 6e&N%߹1]-y~%nMOt KB)eX$Cb# ~ޚX>J'޲,Ĝi<{ό_súz_K2pehe/ȿm8ݩP+QR%3>gl5# d0EcK;bjHLЃ-UlW.%[ ]q\MvhJ,WDB>/M9?<%i6*~=O_ڨ8,ԏj.>͐b'Cٲ6a`cZQ#҆=6Ξ'PnrEEYMW3^\Ki7_0mfjJ Wp}}%ݬsX_ x,ő{s‹wdܙ൧ (cIK?ϝ=ӝiVHG6jO_a^ar,lQO*1~ rr@ sW/czo6}5Vl+!,$EdlЌH?D"y:MyG92;mM|جU ӛO rO]ȸr͞T'.u`Qqr&W|'b̠雈qrohH@Ѳ*v'n nq-{h|}Հy3kF 'ê-ZHQ#DOX5_]gze`LXCb*2t_^)[=pNM麻)U;?i(p*O rIJ(* Ssc1Mǿ>LRF)'t՞֙1|IpXCǺ>0E/9M#ՋTc* kKzs%kͤL-vKvՐMjޝȘhI+1ϥOb^2i[Rl0"Lvl3H/k]٪҉{1w9@G`ǷTLAŚqBKBq,8aREx04v˞t1,5h0wa|ƳVg_Z_z -_c8Nfyυy?t>=Cr>N΁zK QxIϱbu,Nihٗ_[)rq 5UC>A2mU𣚖|DdUJ'g]w9ӏ9=0^Ũ !hQ0Vk{ǪMx9R0rF5V91j:K3I'*4YAEƕXtUpy: 4ňP]튲,3T/#`E"OÞHTA(Z7E4ZP)3$Ccn&bOm޹o!OӔז4a~jvSpQ' VӶ7ؽgƩ'xG%|nm>*-CC[ [X*`NyU%Iz'߆i+.ioY9ZԔZfζ9QB+/ j1MH_5Uqd)#) _h;P^IŽ a3o5,dT;-g{p w>va6r<#Wsd-[z1 ir,BxMEx@u8V kh)#[!og]h~W6{#G}CO6Kz1Ǯ`bT᳴OJ' oA YW@5g<Va^_n[Q7MAJfmRb)ڗZ*ߦvGU>ǗdWũ>ܸDJebzT9P̙-Cw7vprcoWgյ`yq-&6tlvLy |qgFBԵKi% q䵹n\qݍO||ƃ{,<씘7/9-P~wqv_9$JVq75Rz'xsQo~M w93ܓGYF'QMa^<=u3 s7bmnZ/bM3Ri׫ z˕?8ճ% 9xFzR$Ƈ=nkX4|̃8ޛWK+'qfۛ_9oGwe=:pR+qg.|!;mxV\`!5?;\l&kpMNQxoDǽ_u} 6HLiV31[6 Pߺ/9@4ti˯ m6ysl%)KT%Ϗ3ZzС97?륚~4,ow!CKp_T)+%YM}8^i :}ـAbsƮi|iE{:qk8W@eA2K®XseB+6?"cFh[;oAk!ub_| %LVj)Ξ!tX̓B3*ws$7r=]4ƙ=XړoRہzkvze5<ەpLg˞5{UX֊ic*hv!dۚFo俔qZ+d-b6]Bw7c~^!.S&e#eB7 qrKM}gIB'_@7N\'XIs*ZlP11_'dwacͷܫESZtͬ<}4܂Xe«I+InP)0eID0 GUP,T Z8^n'gD)c'iS֡WSk΍d7%kV5>]͙7}䂄%֦ EL˼Ey 3cW3laǻ6oͫ-hxܔq}ڔՊ/ vD|| _L4-ǯUaC_#+\c $[=ZfP[gzlK&(8ܢ lj՜ɍKoT_+rQ矌𻖇7\-a lJ42=K&T 日4, qt} +`+5Qz5+0<Гx2{|yh;[{q?FɀrR)N2w/ o)a{|A#\@;N9mӠc6e#Co h4[Frq=e}ld?VǑ]uC#wqjI@F|m iSJ5[\ٛSn}8ӿfE_`+{S/IT\pF ^hq~C.2dj1c^lEqtXf^CaCoלtHшؔ؛.ٞ/W sLxZi'-h@-Yh9io!/lYb~~7 C}x􆜭4JQ<ϐ;k@ N/|[% x> 5a|'|ͦ7H{o#pKlW$ hЮO2%VYq_V4#}ل]k1a\>kk13r'_+rُ$<$ #{a_cnomɜ G|e><];EY:\i}$>;]p'~+ +0rd-E#uDhRa/'^jF1Ɲo+F:CPסLaQ\CmuA>!؈JȊss$4*0RW3)޲e|ME)üɹ6TΨR dlDfzmȥ-DѸT9}"蔁>-lx]>"lG}<ͱ!\Ko4xJ*".xZy阕-6&IT-`ڊkC9LAڈ,0vcM/(pcqkz;C SQ ηw\ʻiOb/tlҫp3W+8.&]n^H/@#~fI%:a ůEXȀg}ݙU^(#bumi-bxWڿW.jt^EnGͰ|vԒs952,{+n.rڑSXwςLi9De hcv<̝' KAb(E8\ tOIy8 uc!~/:U xZP 2ߍ<>ϓwWY&'saG̷Elr !Db/w<žKZ1 O 1uDnC+ LØ|~W㯒T\P@\s,@٤`YDaΉJ8fy {~wz䣼2vBB#48C-;3ח`Wm>\ɀϫb4qS)n*Qqw/8ʨ)$ "͍:qBʵb_+o7aq=婢[}&fTs_]sQKqwnn?;rka-hKHC~?[qcO6)s=Yp׋l4Px9>V0VkеВۃ d3Z]QR9O19 Gk67QSs08d3;9,l58; f\ɒ-rNg[>ܭ;tzuD 6a?`ʫohq-Cwٰ*,C;PqVca '*>[sg+Y`H/e\ǛڞҍI]YnOx҂ϧigͤǘ&ݓ%amۿѱm߿Waca( Wkjm=h*0n;l5|LBngRஓcS%%9RU?\ f1v6EZܖ͋fk03,ߎ0 k F U*`QĜ=h1m6r^-WC#&gTѪk2o!&WjZ[ãfR?/FW//l :*N܋ ~G;palpϔltNn[>n_ Y\10l{o'©!wI?OPQ|ӌgR\rۇ2o:<5':ύ;rSg; %S[u}Bd`xNO){X6 "/\೼{U (ȹTќUZk9欘#Ŭ0*9+fEDDO=θo>8wۻ|`j5V- Gw[s$3.|j| g!gN/r >4Ǫ [SXS]Ua#8&ՄadGSzlp V 5.+60#570  #sW*&/=.h8BɎ5TZ޼%LqE|h /_O:jdl$|˓7bj|sxAn.:z5KCk (|4쑂C^`?/iv2InῬRsxA?Y0C]{S^<'lɃcBMzZl!&4X sPXX#gL%=|s]Ä6Ǫt)j<˟xpE%xvYB ^0L}wW@H ]?[wŀ:7:>lɑ_{]_ݹ7%[^ 265 JuM *yelCcibmי'Gzrjw/>ͩcxh;ȅc~XNg}&sE\8|:m2zO9pb1{eA2.4ܭ FMubZW8 kno̮Xg\ce/ 1Ae'nZVJsy R+Mҭ<nKƙS72'}&36o\iLeu/'iIJnjމ޾f73bL2?wvK;lId9dJ93gID\pO1hs{26Jo6_i^KzǙ]g?6g߀]S}'6@O騙%E+]M1ń 8XV=k!_ LAE~ tUCS'&q0gdT"XSX]|O^n;n?DOb h3Zn&4H3 CZ{pyJ`F<(Ff,Yʈrk~5M:jMC?a֍A ⍥]`~ odD8ԡ+?cMV1ვ3[nKLENՍR A9zֺ^ƭp^aVXaBe{l̈́ ~n!MY͂[S[Ϝ(FAϨ>G1s\Y#cp[نGk>iZ )ڣ)HsA9;3kThC{xNAL(n`R`&ː߾¬G>̃,\cU6F.EHb%"B~$?oļƸ7d]FSJtxjœvce:Zt5a9 =l#.DZt>s9N !(GBjEdHJ3 ~3(^kG ?*eS7bF"]$IpY˳HtY&>FXL)r zn4Qgm5h{̀G[p|-gٱ5Ul-aJK7clf<1YGFe-C.X+WI%i__>M / ~R0S\䓨cP74 e7Prq7y,:j<6]ic%6}ٵ?mb.Ϙ4~LS`+;h]a} y!_ rJnVO!O11i0 kn_X7x(IoE v I:{˖UyO]H;` 2!WsUa~ ?ktx /ƹ8ؼ/lxEdzz<8Q)az^ uS۾Zp6Z>Lj/=;#qg}ؓV8wHyu,yIr3)Rڳuao-RW :1hNgA? ʎ̼}]EY;Kw\cwK+Z8˪x۸?&UI7X;[qҫs>;Z7E/هFspj5.0޿vB\U}IKk(                                                                                      O\MjjN6haAmz^MZzrivv!:"h|@mϥQjKkI?I XHe]4.] m=XUSAyZcc͑Xڈ*fO)ֆ$IiM0YؚY0k8l=7UDž3kE }0UiFr"6 ?IޒP ^EZpiM}=0[coojjeТIGN ٗI1n-j~wp% 45es3n7:nBRP JKڶ!67\ u3EtA1fܾ{۟Bkإ (S4FjڴѸj}Gytku˒PkLi$nWN91{­H92C.\{ m+ˆҷ`2(Ϣ)Z ?jeVt] 谽W:> Cܭ-=m9MF삯y U~$E]Z_"4=GSqĄ6Vi-x.IBR 퇕$ ayus Y[Y9M*[вI.k*l-KW3V1"bM};TQz$B;ǥ{96xCNi2p=$8Pa̚-x:ђ,8)z8r v ŴZR 9yA\ /[Rq`p1cs`,VCHۏ@="3i̒::ҩ#5gFD1Y&¬O^P Æ6D{ˠ-DE;|Vc/?zfQ>+S3_N61Ү|5΁5lx)W>NMLYɁƃ]y@I:6_,gR`&̶_[O4#7mi. O)_[kg{ZN6υ2DyX8&>44_|101ہfg.[m?ܩdqC+t6ːs 0# b&xs8kL#f@f>φ)itݕ9{sVW ښ)ثJY9myi9'XKKbIcjp.Qoh;O 5湻ѧ[ϠqAoN<&Y{;ʥX#ڕ!z֔գ[L,6]yy[|pq_9'ܝ|B3}l=M@?>R =Kk8IH*Z(| -DJ]N0GfS pܲ돔VƤr*Vv9#G+9͋4p,3LAo18WC-tQɈ;j+F\oLʰ1/v4%3:Ҁt3|Z%qcSQ&ݽ'<|H$u6f\ʒi8Uw*]nlÖL CR (V{0Fj1[Ҭc"#52}߬ƄAU Suyۤ1˛vw(NFmz0U8pB# K32,Z}dT[wnqߍM>U3{!4 {ޭ;zN<ܚ.rX6ΔgR-Oo00! Y wGmSPMœN<ĀP/基,1ƀ| ߀ՌXUzэY~LJvzQ ]7tx yUObЮq0]jF \C\K$mr&o|מ-%%*I7~IKߓKMz:ڀ}?_i<p~7.}ĭά(oUS%ڳN+ {?wsr-qL஛ƴu5&ljܮV|PՋjz^>+ Xl6K%Y)]{rtm;Ws|>}Nz'"UۋYos[KVlP՝{0i;F^ug4fOntD/?w+ꙻpr}W lȱfV! ]&fA<ĊnL̀^01ڋmt R1e]6o2β >|o[ʈ!{kC7pBZGu,:g)\87N\0Wwvu&|_Zh`lu2V>FegXvxR\Yᴾ4os"zc EaTk.~qy0p t9)ճ 5Uvņ{=}ޝN-jd{!QEIt UtAU\d;,9mŤ@[Νcü` 7eT1 qr|t3_3kSp'#:D,3$𳃆Ԭ_ϋJNf2+>E6ymD\=b̡n<3ݛ }XMox3m8ي}YpZc*dTo,]Z`>JڰQk ^҆[N؇JY.PUdYO}X7Oڇp' 6&EPd8*&x {dT-E69-SQ=5iZO9{0'泪4ߑ&:sn}~̝.s ,zoqִq#oL%dQ`?q~&2NKw6P1Rl)ozכ/qc WqcX3;z\nͺ^G1gqWN>9pw qDgحJFzv4d˄Ƃq)F17x ^q2>"4u?ڊBYݞ&9Ҷ r_wamc5 {.Gx0ކ~~[a%[;N'd:\ϙZzF4֋ܹCݝx<҈0 Jc+;-nkOXz.qݤyT%Óy WbPlc'e./קd fUQ2agiyypv{P΁,=+R\XAc+މݯ*YO^] =ƎۿXf1o\7dTln?ߣөםA^6ϓ7ٓa-]i<Qlz֯CmyN 6T^jN߄3ɞjy {Zź?;R=/tc4klšiW::q<'nIW,@ɵaJJPҫ= Zr)ql;Dbç( Ęϡ-qWM+6[bϷ.'06QIpGQԖtueJ;xF/!>|3\>Nݒ͒L^_Kp2, 帬TJ?n=ΑtścÆU8ސxp( Ӿć[~q o& 'ʵϏ w϶]3c0/kŔrG굱,]ξz^ ,்XΔ2*a?]f^iTOWPsIEPROXxޝۺf{=nO# z8K# ʙm8#o9tsO6H'}&JƙO1AsK/Bs8طgF’czæ9Gc7mx93[#[5wT ,9E[#%6E]eG~Í.TeK7a^OI `kBķTg'o0 t;.pbn)l>N{UlUHELig] teܛSYex،…to]q|R&ӧ's&Զ㵿jLX|/%#=ixЇQ}~T} ɡGu9Dɀx{OxdKt}#fX~CGZpҒźz9wd)󍃌p1ħgx cyؘE<~ٌ*+l,?d1;gnf RRWRO_~ó9EEW.:l}keP:3J yjOFooF KMî!SN2MNĂf)V5}hbv}CēH,xߕ^vsA璑#vtI#ۂ0&?غ:¡,r 3cNdQ }F4b]+Y5.[uurOxSz^!}x;;_Ť[+bbiUba ٽ?yepwVzoyͮ8QT|3A1|ԩ_# ~jJ0+.\gCv{ gl |yLY.hRǜCij0H]zmGL>nd\lKGg57ēV\)uŒ' q _JoTtzj~Lۮ'fz^^rݕ8%m,w3ҚE2-X臼ϩ{8}p 'N|v7qob[A[mDpJ o{kxm}3D΀˦Le s=nʄtCQSqro ]›a.c۲|\; n T`{r;뾶ߴw qc2Qp+Fp|G6?l& *29 \q | aI2c_q uhрYTBjL]xt}D©Kn,2c^gF6x8RӀ&@nab7g}`s͔[(\z5.Kę2.5t;[K=ZJaYG]3GJ^,|З/[px535ӛ#qS_(9-<<04o.}lVM}ȏ{}Ɨ?Тg4p5G7 }W @ 4ߚ;PVgve/i6<̊ Yq51'{ I kGs+ZzD>Bf}$M2.Y౯ry;0q2 [ƁtP`nҋE %zn|={ Z1V6|ԩ[4nEy*9ԂZ2Ďj:1 _tbB[ZdcWS{/fqw^橭~1›7j|y?ZP9_9q{6/cƜsA¿}uЄ-2́-y1˕\mŔꛎi6t+2c&0#~&zMqM  ^+xYb?bi,螃o3P}^2we z0-݃~z" }uls^,¸Y輻L*؆.|@VO+٦!ԜƔB6'O@='f!4 eϕyƒ0\ w>@r\k*ă@0 j*B}j= d!6/3ThDY&ܼÎKݹd7|yՇat'i^\~f'aFU//'`<]bfO.ˆ.lLiҔdM'OC&z[:C}tiNlo˛AyOqywȫo!^V|nj/%cb,K1!#^s# cУl,|e(6<aQVU͵j˚*ubp^_`xkqRBn'6r9[<,CXb^n9jV|2ؖ  Q^RMx=t a&j.ӣ]̭'6a_x~;;.lཟ0=$/1e:nƲq6AFMy'9- pU*Lsk]k患^xa6?nՇ(k{+R9[6br|;mcT^S)wm6yȔHGT3qRxk^,Š;r̜ӎy|<ϏIx̀+1 Д?ʌiߔCe.K0>G$ϴ"lP9XT̂^\_;Ԭ[ݩ*`\{\5b"tTWUC)i~xr`ʕw:P_>{5fOqbO~X4֊IzBƀ1 :kiOK7n]W }-ͭ=܁݋H60NkEo;Z_(HdTˌG_a鑂2֎p*j6>G<Ƈ(^AgJK(6vN<;Aug`Rt(ϧ"/ /_I9}gBΓ Pbly-܂r.8_yRqg~>z9uB穑 SFӔΘxN`s33A+ȸ~T"WCߌ%17ʕ;֫9xmZ8қax؋inqiW-<4+CHJokmxWJ4bBw.měv3&sFz5R aY٭l ~ǡ߱'S,v+if. JƷ8 X$!ZzLd'/)eN/e"? ~\>܋+iӅ X.r`IںEʥx_Mp!9߄>7lx%; ĕtDC;w"]o yn󮜋&`5Upo9uߜùpxmFv4R];z:?N<˧IKú\k^s'[X€bsCrQ}.S2ܪvc-[Өy6]=j}]R6skǮ,Į7\qkcSQx:T#hd%1EFuŠj1H1ȁgTæ]t]Г 8/%7N >PœK8Yqxn7l9~5FPm}TrpRgR]}?Hͯ6ɘ{Y-߷t]-S3H 63c4iIޖ]YAsm;4Q+)%mR1:t=#M+\@i?cξhè!~<+7GY*Ljo459Qźvjzޜ4HmSլ[UM ;.CyW8U?p1gٖ`F88(Mxgw[?Rj욁 d u^O#W29]21oq&ˆE€U+yɩqܙ;u[T.ufLH7bd{C*L|eB,#~:a ,z!`q,[B8u}sgy,?DgkĢdnyLڲ4tn)M1y0Kc JGIh"C!+.Za'|It_n]Ook_~|:S&,+jj913iVsLYs%]r)~;M>lWח5񡓆s{ݩ}wC($\OE pυɌ_GbG˝beEzyNoIT)~wZ1ؘ̰NܼW댹fv1,ۤӖ,ė`Q)zߌ;hg[ z|ѭ) s̗Tƭ̟yۓ K7וK]xP¦QJ?{[v `iP] b)kq(V(.E @s=ws3˚ٓ4I;e;;N4ֆ3%[ؒw,1Ɍuv :%gțv.5ݫό,K棹51¤?];hGM#ҍxɜCorˈ}\/ e }B&gK+KNl@IM\q"gz6NWr+h+\#vj5'_`x3~\!vOpn̏r\O=C.О1|e&[<3++{DVbѹ( Èj 0 4`t~)7osec6mIH ad [ĘF8-Taw.Ku6Nٰ)OwYfIcT8dm8ѱ*)2K7ȝ|yᇄzp~_G.yl;9ÿ3| ,8` cZWUWdʈnQyb~7ǜW2n]-bfOfL+s6aVǜ1oap{ۇĉz>q:03O&<ٜ'ۛqQG^7%Qo /C^4?dڠ&6(2N*Z"n0x!r* S=~hAH[^F[U#JUF(l6P͛.WƗ3U_$d)kzrGE:TIqMZoV(cgP4 _eqP9jj 5JW{yiX5 9\Bp%ڒ{p`3ȹ+zSJP *tp)/}wd-;>g?2$ON ^,1Nl\xI+Yn*_^lMү7 bo-8K_,\x] Rey'H"9[B+K|=پp5ev$:Ȍ&3Մ}H98 k{%ZL>컁kAԿ-#m.X󌱘śp֙c5yxgLyk\Wϳ[I Cf@U!N?tݪnk2Oᔒ#*a&cMM9):Z8\bp˂[Q&'|v2:2'ցn1*#r˙~Jx<9X*N_MF{IϗMKHʢ6RNAg {pmO|#gx=%b_Yc.²ӷpfe8OXk,v- Sm`t]kK/jַh\w~7JJiͰTxa*<6"]AoM-Z<6|pg'<`r;yb1Nm/;*ʧk8(h#B/G&P7/Yz1Tslχ{zSHiXjڭz$7&|يC9(OrO,j17)رXcT̲8 = ;Vj\X4Q{.=jAm6>M41 [$˗rCc$46td B I=ƢAE_`9X>! ?=- pU^%T T3䞜_exC l$')v]\p=ˎ鿄.فŹ'< w}?5Rmwxl.G8t*qM*_};BzXc +꟣ =^`Q 7ƙz C&mzgYܔ1ׁ-h̐2.7-cSe8]Vh55y@C"ePċkiPJ[/N+9Li4Pr0 flʒ3lÎ%⾄:,\G>`̙8]:̫E|gz v=F?׮r?hy ,=]:h/֌~ppԣkC&+v(KWzoq8T9/ r+_ F>a*0?l{[K. 9^s'V2|@[+5#z5^Ļ.]/֡$v0:ϓ2H/0M^W^88 =vK=?qcu lUFtױr~lp%ԯ133ֳհD6Qj65뷂j<7J^8߉: 'jnPraY+k,?/}Ag$Zhg…Qe߉z\׵GCUg=ҿMj}>z!gIl̞i^X: 6ņ}>\ؚ3٢3Or`Dvْ;qGzucEONPםWqW` DNVKr'A&|3_+8#^;q>^\g#@_!ld!tftLyy)ha[ֆxcar Zf8PhΤEk [ܬd5ǵW )꿋7v{ GH0~ ^#&ƎyOKQ?H]^m%bqkmlvTgJޚfc1|m{q+o[ 6\#𱘉f |W,㻱&5'3$\ʪ3֌p;'r1𶮘Y]fʵ2kjNY„eoy`b: =işV͞M KOfCF2ƕGK_~)C^V&fC|aH.тl8>ێ?Y˓W#8HSo9+جVڶ*5wwxOg1Ӛ5FMTQ͉tY4W~>}\zԝ03Up7s|YeQK%}GKypufW\ʳWܙdߪ1fX|z6r!DϿ~]X zXqf kKL^ο`n;GXxHʕ%L'uhX퓌8s%󬘩c| ]ܔ/?<+_ o݃~&Bz3O61?}։ٱ]5+D\Vgq1dʦ{`Z< @|z-ՠiϥq@\"-&w= ߛyf CMauf2 cK{C$<[p21U\m20 GȺ  y*\JnA ͪ0!(v+tW3W}s{̕c[{.оq.S? 3]%/3`xj6|F,>_zD0/6֐<|Vnp9,“\4_;aZm7C/bH d*s-)(h.sOSIVj)S2uX:zUpQlMRy7|nj0c߇f<hŶ03cKSklyi$U~ {~|vSH{3i:Ί1/̖-V ֔bf|o̠ZS^1ehv= _D8Xe@}KpcfK9E{W󆅆%:>Ø|%U~mω<mGͨTFY_j8*Xͷܙo@)5)uf`>mN娨g)bzӜ3*1\AZ^\xZAM5(\`盯^MqDoKZع23'q}Y5)u-:PoL;>u氻{TpF[wNݡᓾ޼HM?G{{9j#\FM<&꣟3E+ Hc?)yF_<]ϙWx-]x.ݙnl)v&\A2>dxG3#MaI#G?VOÐ,k0{6Xg߻t`lσ|n]_D8p1ۋ_++TÙK }C.nMTW>-۩Yys hK}HCi+S{c%x]w f# ~\$r.N3qs d&61 g@]ϱdu7{M(Om&|Z6{$,ac c&P) k$lՃ=J9sǺjΗ-MwUYyRjJxY aU,o$pyV|yו5AR! Z8)1[FR\dJ ;A0stvUz*t2ߣ9Wm;Ēj-Xrښ0a=[\tBWvgjl+i9l ׆Cٱ768s@d|Ys՛ɸr+}@CVgufF"' J\P(iRh'NWn>'2˃KEZs+C32ؚ3UqfFQ45yWv2b*B¿#y.Dg^ߜ]aA?jߐvu2R?.b`#$K)e_j'ǖSk;+x-MM6>Lf&(u &fh5UMU+V+_-NR}W*EɌQr;wWxʍ:z5g@Cv^^Ů=Z0KU)ٱ[dY2hrh[71&<5،,x-7rBCO|R'xM*⮌R )IxN }Fv7m-̆11H}zAnwGqD\tz'lSs}rvLsFKyʅG>Y>3}bih=*|qÝ[S ׵̿QS۾&W =$fKNnA*z_sԙBlYpR~ ]䔆b/fEyrB&̰(Ā߱z24iϔ\chC 9&+ٸ@//^UR]+wɿdt,cJE/Z e#;O)j+k_+: [B].FM 5bA$O!G%B] tîCXk]RU@e5LD1;\<ˑݸ9̓lWbP/kEs}D/PN.|`W)5Q0l>lSfz󀟂ׇͮ Œ>amKq4t _C#Ѯ!G򕂟j/P袢7%Fυٲ;.{\וNC-sq[M_;'T;_kW! x[L[0zǦFYh`jZcCY.q#*xaD%G 59wli5%5,^f_3{;o ~ې܄/ rM>~:eRӶ7\u$G-b5 ?ѹV=l1r&yvV{plC%۬㎗uh鑉_PF1p5(Ǭ&_=0f"لnkȚLxɵVg"vOO_H; v!)ySssTs$7f4*MC>ԇ4l1[*`ˑJ Ұٗ[͸"l4Q\C0JVץ95:oąg6Ɍ =yrEw}&s/[K9@铜8` Ǻl#EG3~̩8u<2FO=;6ELq b*A}wljm4|iq W#fPFrf l,JN]bzej^\255PK5j~A $_Gk3p(z%#{39roMQOau'_yPRNIMsbvm$cwvG> 0}j'g9q8)=5\t.ēݸ׿zs ?uj9Lػʜ#Ya)?ˀRH$$y&#T~%Np:^HEqL̳D31/A' svh͇ lPuW͙{Լ0YT4Ob^Esך]6,ǕL;S;/S]p VLfVJWE)wT7]y=uΜՁ+[qg _С_UvWaù0xmU-z%Cz}[;;8 btXT`hcyӂvt}bnC\QBEKĬ^b/1y8s6lú^>Z -ce3->*[p3|rړM'أR:) a;;PfcM}2s@ oiLKyO-8}uΧкxprܽ7> )t6ڜZ}SjP˒JK"m>FFfYH| 2E}uɄz:/hчpoNb '{xza[5Fx1TL$vGS+1bo(6Qq{)iXWSPg󥜴T % vXnqg,jaCo)N#ehbg0a|wlաz]: jQ\MjI޸s^[jZz w~s./G; ?,f8q-G \*ucyTǖ\<.ύF(ڠ-lw][[4oOzqBb}]5)yt>}-E_8˔lވ}*,-:0PwC'Wa9>~vh _`_P1&l?!a8|ﲙb‡mM]ËݕHm] pR W'KπV~e;|b))v`V01\njy݂O`>F_y3~_GZrrG6,J\%)K.2}zJre}->b|{Lxw }Gǁߴ 'bsBC_W]詊 ($Do%{(=82O.q+ԅ/W`E/}u>ĆG&n>%89i݌/nBK8xYwg>Cu9-JրrZbOzpjt^vּ70‚v8)=TabXf k8>!oՋwN>BAptXh|3scܝ_7s(_I[^.kg JCO9pA[>[t-ù̲^Ga8h?6Z-Q,|Sa+66<;‰.j+$XɄ*:*9V)iZN )SGzrFk #!{r ۇLFqp {bЉ+;:!0&N=68}C ofxqK*79,2 tb  !bFoۇ1}<ۅo1WX[߯WV#_"RVүT$VVs\}j[q9=Bү5H|'2#n1cHͫ%' 5N=_I{q> 4=|m1jRSOϲ7w_!"q}!BhxJݙ932)0ZxlWl&O4l 0tѶ[;Gs>09}=1}9NN/EX3gO%ex2Fg&M"v5MmžUW?^i-։&r.;M~<[LWq[%]A,ZX;"g`_^֢6x#h, vDZsXPD`yp,BSc CNaX87ӍBClUE*j 4|}VzSgϔ ~%c0wŵh))2+߂tILiqN|3Rm9"?`O_7#}w'!`~6d,tj5Nt]CQܘ=GawCQVdE,&7֨rwr:k䡿{1(\]Esxm+Ptڄ&sv9BnSq^ѕ[f ;ƜU gK)p^_ݨXO=WaÈw'>`Lmjȵ'omT0*Pń!j//1O-F"G[tLiMWm}ޯOǏ\7ɋ=K%(9z gFbRؐG?Sp5sôHwGǿ[_py7Gicw & յ}/6R1m^~C݆An{N{צH5hʝL:f&,x>݄2dZ(` $c\/DrXTJ=Y Kym!J/P*GWسÀ;]9FӦ^؝ڨxOŵSՌ-p ( O[lk3`]ȳ;㉧piT_όXUl9˜))pioBiO\rQT+2ڎKli,>rMXJ +`KJfU)Y)fLQ03@krKT73kk%6[c`JZ=CQkjC"OǷ(֯e'6njA=4`z|ߋiukP1vC|h¦I*GGHA MG}_%$ösJ0*>82۝dǟ]vXߓܜl[ 3n`DUFܱÐj#Ss3>b9.&,bS[f,Ut>L±mi1y9y'l^žcT"^? /,UiF1܊C8s~]w 9ro⫝̸i?F dUb Ru?cwSѯ,:f%_PR.z7ޫ+>6Γm85CFpH7 h*LI_d(cH3.΅fLdv4[gShKκ2,a^_S#'zUaބRT:4rX=~8 B* S5b~ R5ڦ:,&ަxӟ6ՕN: (~gGss、\{őFvÆmy-e8:qgC191o;.-k3nleB.͈OLXfNk.\3'lYK4<&X5kC՜W`gW/[QxмΜuئ<r?+< iߓ0`LԧȈkǚrK,g=o/CSR"9^ەr`uO&I`]We1JSqȳ-/U<2y#f)(8zKLLӝ `M{W"3)yt(~$|?=֋FBc\Pb/ܗ]4NN 2oC{ mxGV#UlQ'e$'[jI,d̒!r;_}h |kQutW#ʍ0cH/c>\0}Y[br4m?D9@8=2V10͝`'h/a7oE֒8G)a <;ȃ{ =j%|l jI3Q#")]MLmk%s6:'-U2`ni8N)yT`llVq1`A {i) t nˎ7JS󦛳=S8[{ 5ƈ^ N' s 9!@H/o@C |[Z9ΕC''y)+Nþrpw#0'à*' wIG8s1#'6,3;ۡx ~h22A*FD0'Η }Lx7G8FƓy2v馢 Wqr^:HKr\0ř7;!kd;&3q i̸݃)Ytʴ`sr^o}_S[Pl;GpSǵ͉ݶzrTYUY ,ѰL|LEys% S*q#ybCy8_ƽL`*ZGə)c  (ࡇ7窘d61k_wfܻ\lȉ y!]si[r? r@{#"4d{ZdcN̷'yؗ[iUj^4,"yMsC_9$pVCEN(FtUC sf8%|+-"6 D-sc Ki2XL~AZF7ܧ&i7t>d.>|B}&+|Dw/>!jߪ}q"k3IWbGMɍTܺ^ j' }ɺ8aȅNЁڝkbމvv͒{fow:axX}3tZ8R ׭S$^LM^tZMNޜ|Urv+=ltE#O>9 u)i8FX~LT5^ZmsWJ7LF'wfsf~t+Ղ_7ZMOjx^-9l_޾@q5 Gv;a`sdgC8S )]0ְ!4¦:/W6A1mLd?ZL`ZoG5 ߈س .!pk#*?[ݔ 5y1S̓ciZZMAg%T9ﺌԓeZM=;.sǹSn0MS IoeSpL놽O-qĈ͂뮨:leojMg9z1fqz ˠe)s(Q"lvB$u^J,66y g "̞q\=8| l++ "}86޳u®6X̓^|ԠȄIj |6Qldtnf$rA~W2>s xCnXcWpW 5obcs{  oaagdӠ%xiړ9G"_̍7M Dzl YNNrMߴE#h֐4O Ar|>ʰvDZՔ7FQ( 'O o%9J8Fl}I)~Sl xTFf+a @zWY>n0S;B{ `zÇ͘1aWMHC ,>qcPK-B9Ul|qzy(Y܌+t<4o;\nV>z/#}TMֹ\cX;ŀj $X89;:V[mO#k)e@)e~9B2?A^"ʷ^8fsY.bWĪ\pz X97-nnaEWg<; -,`DQJwxI z$2x%ր䲡nnV{X'n ]f}J>6̤qC]KilRyҏ1toB5.C˵wl]Lbv;.h7҄tÄut#v0{033C0J{#bT V* <_?RD#/2d ŃP6ŊWGu&.'PSBuE!Uېz[+An:fU;Ӿl_a}Hؗ UG;GiQ%b%;bc?9rL#jh1.h؀&Z,t|94Zu WswtZ펚.XnBQ<7-8<و͵oV!D%~T s!`:#,:h=bG̀>:d%1]q7ZiPmw!)aFiʿE9vIs ^PFqi].uGץtzWʜz%|%q챻h.[;wӢx = 2"cwǺ:-wE#zl\FF=2`|u [Ո:l+6@`-ZL5^{8#{<ݑr?,2HW#(=y6+ED::SM6ʩk,/R*k-d~'*YIu?bpS=elE5;6J[TQXAvgA1 -q.@>xQ G?ΎTb{-50C{#=qAߧ&ذ]-dkw=\p bhi@"-RbH Ү`Zk_2@cg_#Fo6uϙY;IMi@8cq /^;796v>>tad濜]WB[Ƕt|=qa}B;nF[& C6zltg; l,Aj8:Z<{gĦET3|Ǻ`6ӻVDM$w@+QNhGÝbe-36NI b ԣG)ɮȒCnps4熫/xTQS]SRӍ$F z!7{prZ򰬁^(qr_pmk x<:1 K,X GZ.Y9 .T u}䘸S٣Ύ]}; і/ ouv N ϖIīDSХh}ZMǗRQ;xų) Dʖ M&7pe@y&,nfY0C1] rD Be*<^B=Qv.ɝqbę[cFk][iKfDc@_*x\Er<&] {tl`cg;dܫ:7zVRvX*=tbϭiy.t:sFb5 4(k٣4L2"nxp2 o&zXy[ ,9f٣C rY ΡsrKhE-lS)~c3r' [ _M7 :,̀ 4hDgR'ȑaO/$yoFGh__tIYBts>U\L:S*G/}iȫ[tIJ;dД.vSXH 1fzVCGN0i1#z6kG3_|Q^XEa0&r&wV-(zig„FУ-}4bI#QcE "n3P'2 KqKpOr!NXEEªMPx*sҔZXix]GWcDsPi x;I!oBhlW-$œ?nl</T\GɰM3 &{_%;I{SJx;+&DЫc?\_̱=MuC֍ME ] rG]ZSB'Sf!fK/%o?<Gasa Q'ŀrL Qm.>bFXoFG;&k0??:e@i/w ;6}(o5(&7 LAt/fk]쵶Anew玟[IO+-CJ;!19- Xxp,?HRNcRΧpΈ4Cp <<a\Gưy= < žRH&54РTr (}$^ kYNwmk't+:+}E҆zh;waHa .2D5cd7`㭄e @xc ?Ӧw=Ndmt]jsC%($0[h';Ljo'zˇt>#=AϞzäzO#ƫB\TJ 2̣4& rG>ȯ7H5(޷NH13D1Khkv)x 6㺁:Pu bՈX FxQ[wE7Qs]i "/0K!yZug8ϩM@@Z7-{ ԫaJ=8p{8by'\>żG|*B$(],C^ jEZXƨ\^iF3O3ݱFJ16a 'Bm*F(CjȰw;1ڝyc(_b_g 58Cg>$93޶>Pr Ata@ep34^-@Q.v'Vwɣvo;y7ִYֿ;,)n8cSs%çZqq SJ?e\&#iIZ d^`XM>J!ߩune쑻m}xZLJjЯNL56(>WGZTRG::3>~ȗeRu{d k }}{ m=fec".J8aE. p=Rdi'q?-TV1v̱E ʌ0-Up]N/.X͌J %a W9T-+!eD/| : Ux8C38Q;X/tljr@#i(u+B)[~S *Gػ%t bx8Sز'hԱ.Z?]7v;o:q -OHC+|;.`}sѯQ_'xߠNzJ91>CaͤjXRÍo},F~ʹdOonVPn=F9~˜Im^r|xiSWLXA;5.nw w0;9tR';9~*n ]c's6d#l| `Fs;Vk;ZuoNa{684\*IּG Ƈ7^-@1Z,a6N 8ЏYT8Fr(m~)UB?h:GF28hƸ V~o+QwՇ.:; EF䒴TR;8M{tP`I{ߌP(e)2s G]S!S㙃{D*d+'| Mrt)PDC8c:3KdʐuYyW6޽e=mIFWz{ɣ Jlt5=ew޲—\= |j,] )UJ,_@Wrsn0!FL4AN1aYt•NXk. Pg*Ȥjf!*įnr,vc"-;+ fkf-_ B߼ӫSHE)L7'}NIT-p-WY8}V/Xw\J3<1lbWmepƢBWi@|bk_-NUAyPA |Ű yvT )5W KR/w Nq,W ׎s?ts.I4iwxK1_E{f8µ[,Ed@Alr^x:mb`%|UpBƓ'|sBFn/Ҿ9\^G#f1>\Cb0(Ѯ@?<|TS@.kiT6^Ȥmሩw@J aIBh2quzl\Pd'%觴ps Ca>ё)d?td+ Y`B*Zwb3tɅe1k~E-Z[L CH[IкsJdz+> BiO$aD iU -ݟL%Y FC/E'J9Ag`MG,ڙX@8/;ÎKD^"Nwj&g!Eqy_>7]OTP TP d(5OhuN R ^"G6 Qy"6>ҙ"rme(Cn68s}1+8!'_eR6 sF"gبPjEu=jNZ`F gLkjTQ# 6t `7#la- c&>Q(u[$h] q !bJaWpVm"Ďᦧt h]grB h}yOF5TMl0|U5gQgOJ9QTXG'QuvS2BJ^6yޡFaksD)$ ?eSɸ">Q@N/~QwtKRN˃ȿa1]C$Um{o~$ox84Lm5D檀J$[ߙ-SltHو{Jm(\#ťJS.^Ⱦ0QXX‡YQ]Fy6>mER(2'Pq+,t((69>Wr1#{ B  'C ,D2o2.I3ڠGQ#cp?7._`sw4HaÂڵ&H#CvӔ,^& s9qĘS!Ѵ/O+'B--K?c7(w ҕ7NüR)(8b}b C% ԩ֣ٿE.jʼB EGY b! P}h67j75( cAϪ'rkt!m~3֭:dq?]^̓s͆=|t?h_GLBH f&8 ^eRJI k[KvxJt<b+; wHx12\y%.8!m"w< {U"lmՠ34c3fkqpl.:.1{H;!k KВ -јIdAѳ9 Ծ rS@{lgc:6v2 ),tfC<ρ71U+~I$<ܢ>>4VCMQ[`jт@ @v V룼emr~|i노 aP)$EGi16Xl#8ZlƋ|OHnf(oEj{9ɒųlO >!kweڲu{K6\,ߤ3Ut^k%"v"%N2bјPɄ'x׌ud|4D1KxyHkxsCe̅ Jg`G] 3\x\c›K{)I$B.>/GQ <ؚ½9tz+Q Ic!Ie͘(q:/6-ZF1T;w` 6JX>Ѥ;4=9{Nt-&r_t?&FQv ޕS<>'ʗQ^NxjN>(}‡ {8ki ~YӴ!=sG-Nv¼,daj1Rit#MqgRz>v Sɿi9ݧ/HB[Y^(r(bJ!G96!7tL@_\Flj<¥!rxيQT 4Ȓ"dbk%xPsbz.WܧɤN$0X*W!!"%bm(\f,\&”BLȱTJQ!ՍXASh/˄*3h1ΝaU i.A[OYGx~F|;pl ) F 3"H7ku̥JE'MOϠ_JS`Њ6̧+fSi'*4:MbLugt9:j#9%baF R:?͇8x1͹89p 96hwt3|'ڗKn9ރФ mA?Ћß[%*,vA{5`3}▭…M! 862> E܌"oWXfl̥*"GhUP6**ɱ^9Um(NiD-R죴?k Oއ8l=CZ-C%AʏRD(õ 65}# ٦L!J)r E"f9 ХQmڏ>l{A;G'ѦtSfϺr2}ٳ e>mh1FeBY/B) FbD 5`13pB:N[3*MHGǣJ(P!*>#+`%nG1Z8[i\Ho/ut.!o !Ӈ;!|1Fͫ&z!+2IJ {Ÿ@SAR#ãbТЯ9F5sKhSSc}KiO%H0uS !9XB\ |{ 1 wͿFԭ+Z?f7˧Vd" \J~$ªHBX=^H'ۥYEYOt9/$ӔQT9Ư9K}Tq'^:osBOƯtfRߋn[{JpE'CLr:Z,5ӾS}1=AYtuK9vMb{ ~KuohٓE= 鸠SVt0kqaRLx@uGcD0Qm{pL} Ըrʌ+N0GbCaFt`z]ɰ2KbTb=3N?-bSо `p-έ/ XM.uC eƥR|k-)*WzÒ%@ NU/l93:%30`==pNhKHrSJ*DNDz3qf~9]FsYfa/ M:F(4;}eaT+Nhz+)]XZ3wӲd; $E~OtLoӚt^S܅<ڣԘtvA"8XDZnBܚ }*[, d*n DN=B%T7KѲ/0lE79n|GoÎ,.+ZFU!.+,o6kD'AZ}DZ"Djh¸ G.\G <:YdF[Ʃ9grP@g&][dDc3Tn?֡m r.Ñw6h,rSRYr1iON8#ʸh0QTQB$ǣdB_& =f54VX]kU*Ar :)CXw\kl"I+58WBߑl+)B.}MIޟec$%P~44!TR0rD9 h/_Jmt4Gf?PFg9)sH ѱԬ]~E[oS1M{>tc9~\'9"owBu<6<é;dѢ4`6]x<ľ?j(5XiL;jt uL;P>ECl s`w U{>ZDR#´ bGͥZS!b+oF8]!\p@q+nD %X la{xN/88p$IFSʷ50~ 7Q s˷8bO NHa=l:H@Hp.׃E5\q"0qu ̫!n! sf;U-$>uZN.4t֔:B쥔~=<E8Yd|{-S7!gzUuK<$N Hf.#m1'å6,7bl+B?̞oDWr1\%IPFP5X7*Sy4:$>=KWt]*L׃iv@'jw41~^VQ.s\1qk_/SK4fK.UIq 4k/7Uh\_Ѡlr?SBab I'L%J)s @R+tN\.ѡa[+eP;谺X*ixcܐ9a- _$_n p˧ЋG# P-a[3[]⊩\Ɉ8P-6~!G|ty:@,juf:C!)4r#}CHGg,@9C\L!B5) :!"*80%΄mr \vm{!-JGƅ'uIO>+Q968x >_h8{>YKaQn7ghJZ~F~ѝ-A>7FQt%E xLAwnQɓs6 Ж D#.Q@xHe*-=2V>77j–u%d*tIQ7k,K'3\~_/=6bj' r[:GC)`WN~Z 5`z_Ië)y>;E0%߅8521 x2N2?棆B "623 64׌[MXTniL-T&K]Zkm;p;Y^[=X4DK=k|K.,!aR!ģbH=H;Θ{=`~zĹkX |N '*h=^ ;ѯ}Kux0\CN\EIξqAtz/;Ne})k5+%4y2-9?F)S87ʡ;shGi>"i_"]sG_v} {BuɼK߇⹭mt}nZ=v sr]MT9zlxb9;?N]c"JjSDN/;nM14+&I|HJhXnC&9a%WR6, 1ISaPgaVĈ"B.vx$'_EgBR} n[/zAq-.n4ڸ57=ąw!+FB I$]ߩoVݽw7OEդռcctuOXXh{s6,0Rǜ} Qf9[O`o)kPU(aŐ!xӣ$LRU8sڪuO*J_4fS>)Bk2Q7jTހqi5ؽC+WgY=r8 ?X^ՒPpdVPkcTO{wT6z60 ZxF3*r aWILi>tC*1zӵΌ:Qy;ww~ >=\ܾ5A):  [q$ܲMJI>s'y1V d-֢ieG8W$z64bOM*ڧ_‚BdaJhψO@}?hH/jWJ3/iELX++r>y^zZ}k`ʵdGo`s ޼ۘt|q=a_ƿ/6E=/ivِw=Žr\/fY{4Y]e%-5EMNUSͿ!XO\VoH~Ü;;was>LG2Aw^ctwqμ{ Va T̫!w~<|_Ĵ7DC*z%F=vX&f˦f|/w<bLq)~U s"ga!!ȟx3onb^{ :h粍:.ۮ-s0>&D}A0YB+4;bZp=kyW`KE5oGSS6L#ڝ'UvV̎dQ ґhTHmV=On G C]lL/ DrIS詬Ήո7R\܎sG ND,n{~W&.m-8P;`n8`7AS}'+qG"1~^fܮ f@|-]b[=|7hq9l,_wlf˝츸U,-8Ќ+呈媌UG[hpn6ty()s&}V`#}Dm&zO(="_6ʱ厈.hw{j%Вr}-Jm9"T8W:^wOY[{B\#Øx ~//>_=l㿖'/ܼ-= K끿(c/ ޥ],; a{ rSJ5in,9+Ne`{ȵv{3V4z|JOhr:s)qW!G|¨?pϲ5X*3Jt,vyCj_kg F3gr: o^f1MȊ.|ʍ]Fwuetch&WQSgF pNxt$&=*t)EZY&| Ǜ3пw99m[MƄߕȻ,␞f4:mB)vYqx5X1k%{ ]:c0\%1c#d&M.][otF~Pj\ruI?p137$jOLǝ0#/`-$-u-bZҥ1=$fׯ%pl,~KT؟φoTU 4, ^7>S,)Au܎h=aϓa?$7ˡlوgP,Őͩlӎ#bm#ƒj֜PjIy5S3dT1cpE*,T^?"vlhoL|znJe)儮B@Mo1d~:le̟ҁ>\݅Ƀ>‰ ;UG[y]˰W\W;ܱ203BaUʀ?#KQR]f |:;8V1?ØooYqj;~c˴Llg^Ǭ`Ì(F9eV շ1"6h)AJxW\7z:RVJ~N(~LaR/5Pp2M@RxzSL9bt=EN|Fj [~|* uyQآ7ȷ(x2߹=Q9(75!Ӽ 7%j\V<n!eN1/a&T9:ܱRoa>?J -&V)3H6c,|hq#+,ڻ<1؀ ̱PNjJݪ93Ɖ]KV!NT̎vN9ˉޒ fR:m0 1cdfw,퉊p_{c/h~(Cb6nagbY59'YyvٖWH;>nTPL zKjQ#,3Ut_/i 7V  %~`cjlaEy+Ausg24]֮R hïSOp_83w8i _6{WK8-hs6$Nm%KT"GN(K>է^5|>_Cΐǵt9d"o? y5#^/G/>|'Yy32&TdDT L n)Vâ"=/ H߯8Hĸcqx)Go|>7V`xA P db<+DjZdWkp\Z"p{&,-fsDԜ"rUz|܂&#i̧2ڎ~tnɛF|}N9%an R}BvhDHoXȋ?k`,]sa3[cwjrL =|BWԽ`}X$$1P3fXl5 \bzB|1QԨqX[osaˆ- ϗraoc.t:#yvH9cda>>|Ʒ%t/R^`ޡ얢vBQ*E*RнhqE5VA5 /joԂ>jXy @Tm=bA|~bcꌿzWD݌Egx # io0y/ 9r=0uG J9bqK'5am5XtQY\dE/zbNSeZe_?͘^ߤG뵵xcżsVʜKcOށoa3=i 'lʳpⅢdWl2tP Uy>Y3CE UfzhH:S~>lU -i|ƈnZA@pe.~/Th &<_&nh2nGչhxx3&¸obcѼB86LAFlnCBqAfZٮSPa4UFвɁ8/I۵}Wz+6ӫȩl`\L-"\?xSfk< ڗ/m~/ mqWJ\E*3uX+BzɄ;X3@l}8>و+Lƌ6cl9KɉK s 1|0Hv5 OF"z3^ Jb#18:OoZqHw"8߯χQo ;C}Y4 gH Z4oQy7uN]%MzKi}֘BXښjft=S]*|qV|lTy025y\ql/@qdža*Z\=.y=S6bi> :hUY?pL{~C|e-[H~ ed<2. v@eԃE>7?š'` F?+0eG54bg#vjs,Sg@#΢R-$D-DlH?}يCъLGؤ8._.mS>nͺ\ʚ lXaeͿ y"kͲ\#p \ ~kounWJ:Y}'IjCn/1]W+"{#;އi gg&j0yS)vI(2]7Eݒ;n,^u~LPSmDoc\3*.0-}֗<7f{$~KpSNAZ=}ݜ^ ?5cjR B.v5Z`~M@ڝӦ6}nίiH[UcZp#@nӔvN0+sK#+2 3TLT˪0l1UWM/.AN_Z=)s%~t[:=rd$Gviǰ";nML֣:|Ux*M1]ŷT2=-OTi)1# B٨1Y/%GT8v{31s]+ZĚ,%kjJ|ajNTT,lĨ}&3Ռn ie+9j{W5~l/a=~4p){)r|De_X͍aMhϱvo(O0`J#pKIv:ObZyeSޕT;~٘ T?Fj7c~89K?bG];鿍Cllba"^"".)'fMVϪT%fMT̿qQ I]"J`VϵbB}4S Tc+Þ]_wVÞ%6tds%(tگ:S{]NyX_+r<9f5, ?3 `Qg,<+`ʯL@K8ݺ 9y;h)qT~Q38TCGp@^mUz.a\U1<"Q.H y꫔FI({/G<. n` ]?#O92X,tIV$6OÁ9'KYXg;X9Yx_}y&[`YzNvHTs4]Gj}67̃⽣,Hn %:ˈ} 6}ܮG=R.8)=-ۯ{u,X9BϏQk9_[qY(UPS@aMvW<hjR9Դb#Z9s+qBH)OF PJ3}?K&J©?]^6^|ƭ>3c&ocya^} $XX& 0bhNq{㫙a&ݒ{9k7%ޤS_iC= RŧRv4bYZ:GUB'y?N̘LM iXg-^kmy!LqMg'n% 31]C*>𱊈ͮRhY5޳5l!’-̒M8&Ș ƴ٩˩** UVn04Ά|Dbvj SOVt`NڙEnʱyJʎ5yNAU TP-J9C>*Vypb%Vȧq/ G#|4cSzsO~hd|'bV2dICZYp%Zik~ig;ֺ1r {[_lLmHjYx;*#?cplY?`㛊-{q#/f~E+9KǑ'xBm c\x2nj{h@KFB֏}H0%{p2GnSy RT\ӻФX拳/`b҇)خSۊ0жݬ0KYGGBxo%Z5T`ԎS*<~\Q.aHq!Nj# yɐ̸-ْݤ欼eȉڜ[uxWUؗco}3pZ6 }I|L3EҨ<5 '\K7 资cB =>G4$bP%ɵ9jMQ&mi?CGbwRdqg?RZ{Oh6`K_s|cs`L;vlPc<'ǕiٷyR΁Llۙ#YȳƑO0lx wQF3.dGy]'1q+0ckTNOO 7S`ET*eWbNj"uaKdHNWG:TWث˺ITx 8<Q3YWk`7 ÊW-B 9,@rTQ5*0.XW 9 M9=fUl(|2΋Ryi'AD `E5ދ粚j\TbׅbFCh9H`6?-Mg]~íBhҤ*Yɳ|~n*IX+QWvOO[o?ݨg˷;]ՙEEZ0PʎTyy&΁.I)3aTjXDJ9ٌ5pŗ&hAWNc8wnÌyo5rq#uf{7*zK xO]fbвQu5^.*0m"g+q܋& ޒ:oN"p;-j3K :Cs;#Z4 k/н=& =~Z+q׬][з݌B~T159#RʫEF4>aʁ,8d~5fTK__=v1a"3t#ʾ7 F;B,LõhJlZbWVQ!U&op~Yx_X% g>q7JOA7 4u^53$lBXX*͐-l)~dnGyNہϚ'Mx@ʪ:|&႑3L-C-sC/Cv4e+kGvǓqU{D\%=Y'lj[Љ|X+U}fA5ZT_zm+FwWvgiw-6<lKl=[kP%n53|R(zbiօbE#mf/eV%krT)g8„ B9ŞZ3ʜ7a ;<>yeb~GL]o3L@'}~'YjeRXR?}Zn+p*D+P/G}Ӧ6Tg뛰UDN*M%: )GuZ'rl,v| qɅ=9qsiwrgvɍQ ì8׀A97]lI!T`&Sb|:{hK9=ږ]ʼnk]8Ι{.|Sĥ}M˞Y]+e*^=m_*0L֊5-Ⱥ% -!l4d}q ' ~ќC b8* Zloĩse7~<+Ѯ%&|k?~>^)0V 5Fí6?3;ؘ\O4`t2k.L2>B$<(6{sSt_,¹ [O9;$T'yI 贺yT˖eMDy]7. 5_™\y;~vb7Gw+MiNtvN|݉+w HgnweMOYQ/}P:pIsYu&7%kHםvd'OYʫn<½{ڕȸ\8>• #|rdk 9 zCMfډs~p,ŲrF:a#V))3VȧY^iˤ߫gpɽ!5xk/Qx0lF-JGIƲIٸKh0^Y<'lIY b%>cٯ'q"3?#=bloAݺ3ov^;Bg/BP# epwHtWO )>;JHS(svK\9ɅUg\]ߙzK>Y.>WF'7vs?ĞcmǞoRځ츲֞xm+6\ LxWYD5#wa'Jt̓ 1wyyG8_ŕ}DNzOFRNS^ΛnC0"]N` l =h,~(Y hQK?˞qLJ"!ݝcJ*S~Fx= PzF\Cnq!&a;7šJ.[*1Sdaw-*js~dOqc{C,#7`+T ߅?|/窍n{caL? *0C7p#-"vxWH)CZrn-f8G֛03XpЃKL?ƍ8:ց-N,;eȉ皝aGx$;;[:pWS/9o} ߏ0PƆ5ܕG̓%h{=4+ r0g*orGO~=ymsf+ㄘ;?۾U1~q0x;aL(Ҡ}G{`|9~[~5x\NA?`T<9X-!uBJ#*TLI99y%Oez+@C"<1zDCkyBOkj߃ # SrJrE)FWU U`?+g!%YSrM#v}hFfr-['tCܸRكOe׍ܑFW2ύ=d<&LjϑZ^rfH.̎~#f71Ȋ#yK[8je2si'vnǖ)nB&pg@w!_:EK^sL+?ԃܝw*x0:ٝ;k=?ʃ=X=߷ckxAntK)8'u\&Jd,vU8}5ZG+!k7ۉw︒.5™rS $( Ge)JL[5Xk\v%  s7ak";/PZ~ƐzwƀE<]gLҤ(M^.{Gip)!|g| 洽_ѲV!{wnjn 9z!LJXLԙ+Z=Krsn%2ƩnpՍ}n0ҙ%\8=\gu/nTqgxg&:gĈTzݘ9ʝqլoӎ%9yW{fP{ 2uB'~|z;GG{>m3](r4u/<(Ӊz~{>ܺĻHq^!-ő8#Wlq` '~WF { Tz)p:ٱ]&ŷ;cUbD~FQjAÜ}0vOZaϚ~o jn~̳SN`ޯfȭVe\:5Ōtӝ-q2:yW^tqg$>9TH9+=f{s W{n^{n,@xq' =ޓ["1^3{kϨ!l=/'SW/veT;ueV-"ϕG\Y|7GrGY;qC,{MWp^AQ2Aw.R7N B߫dO. zELηwrrWέ݃ ˸%Ν_Q9y;x7]d$OF>p \Xߝ}gnnr:xUb<5,R pѕ\g]9Ł[Swr(mZ};iux/#>B#}?u+>`8 3;) ϶&Al7~f(; o3-Q-᯷w Xma߽yjߏ!}.]/XJu(;V͙(x` 8F8s"`d(Y)a*kvVG+Uwwg;.1v/6Cع+'!`Lcѳ8 `/$,WmJx\:?*z-[QMyփ |2^ر'YpA2 +;эW \1Å<ǃx,=WtvAwu%LaJpZRͿ1@- ;73rτ`8d ^w\#;s"/cxϕzgib R``y9C#chu "ґV۪dԅ.yNϝY$ȇܡ$U74o isin‘-Lw3㯺3e7+; wfn۵uMlUe=<oM[}oUeaۗtuKC4>9,*Aߟx6{Gwg8.5GT!xHJkhO_!ӯ!?Vv/;A9V%@v Ua/D^[RhL(ĉy\x!vkTxg%˪=yz|wٌ+dS~nIDwN5g/*~/;˿)?xrLxQ֗0ٛW}sΏ}AǝcΜ~юty{)z%bW1ڍ 2jbc6•S0+ æ`cָwwWƎp{/?Am>Y<Oj86Gn(sywF];}ch2ʉG%!7Rm5Maױ63cjr}3uVE%񜚃G3pn!)I tH5r; .|_"6OrQ/BH }>Ab]'MɑmYxeɘ<7#scTbP1_,HS㝅:Pو[_E4yeÛ1xmQSvCv^&1?t'⏣4m͙<إ'soCuynpMm;7E6}<ݕO7%luБ/m}zVWa$^c׭ S֡&:~UCNMÝlԒ]Ylƙ~Y^MKׇA5Ǜx{д3Op氍lc]Y؅37q<زTÑ1i8ӁN3,׆[mښslYג٦L}bڔW44=~5NQS%6ޮ#`|>ou!csmX._7}v@7>%бW|c׊0o)U{9 ᖁbnZ6ĢY<.σψJ̝sfėM<\rʙ7.xrzOvW;ެ`.Tt3^5wd>ݿ+wZ#+3ڎV`#gv④ w\ڊ}/ĜO_A*ܸV U̐=[Άnj\I(kL͢'pЛ[N֣永Οo6餢/f=dP:VJ$|N^铋FH7KU8j!;x/xҬN)M?xLOv{%,ܓr76ifcSy֋.+ṏ:ÌYC-9%+ie" wAQiSa.UW31qmMg˥z xf9EZr=:=8ڝFsLd5W =E;Ń=p6nz˓?8w>ˁyq Gt {ǚm;.~ʴ眉vږ ,l۞l!t0eqB#ax-~TD"(BIICM\Ou砬)({}zFcbtzasaSUyF<5~^+aEf|хgz$ȗɾ)U~-s-yKSɟ:ĝN^ OzPwuc- )_3U&w83~)N6eD'?ѕñ]6>}ځ9ߩ‹1kN6Sq]: ah2ۼ4V4oxy_ùޔf%^lV-]ٯ#wXՁݹ3س=gرa;цV#ZŁ-wY0x)C3)[Z.[jEӬ9|95'kcv4ԈimzRtf1uUZhifFKh.L-(ƅVxɡjuhbgõ6o5}&ŗ{r;/Δ n\ގn[r}/V7`C??{Dq,oFzlsHsxh(2;0@Ӏ}Xë)5((KŦ_PgM`,=ҡ9' *) v'_*p1F;es?OIvgXOjzGyqg$9rd7Y>߁رOGV(sG{t={hKq X]10Zj-Ɣ'ٲ5mk ^r7 ^/W92Wrc>7$?zk(lKf!Pi؏sysOh(A |MZq![O{&dsgyӿ7M7<ޖ>Ra ΩAl5rf4w>rއnR+=2fT+en*NDS٩5 /R6재#tj>rER: U#|?GE4OF8*&5! &G!|Zѽ1g82ͅ|]9ЍjX7߅nqWr6M߁MyOW:;q[;Y[:r:=7!k{Z!sa\cM醼%3,Kv2GƔNVA"|Aɍ^ %XG`a=&u/۔#3q4"'Xf(ʣHkϣu0WM{ݘuzǎrn–վ>ӝR.5U#C>$x1(WjJ7ۜ\Tg9l7k}:]×\%dF)QE_%G1Aபlo@y:>eCy1ĺwj)>>;!ĒRyOF;-W81c3ӌ`n}<>۝=Yt߅ϒ=cr#qcw\D G'Zͱ`=|f[c®Rc^}n@q]&]ڣ[#0c<2ʼg#(jҐ{?vн{'d!5?bMc1- W-u碱^bД}9as,TnJߵP܄v|ŋ'z[s,Ci$ݬP~ b+M 5mH uGFT Uk/xd`w857=P.>XPu͂n4htgub|ґ{۸_&zrSsenQ1I' &*A4uyEǒ{]);fjLVĖVe *&ald?E{T],96K3gm.\KI^_ Y C%/vոKÄۭv 6g 2lgjIXōؿ_v4y_8ŁG̅ZrR҅Oummo>A6Ɵa;roUU*\[;H{3~P5e{]NnǞx-MvMun#O^-UoqܴmUSј-ąw6Ğ )P,{OX@dynfH#{N|—|N?gw;Z:DjiV(2JAL [槿cϥxd}y45³`[e*Y; t>*KxМwg=U5[ 9r3ָpAnk;^KA ҍKx`_^~Tk} 7(; wWNdv|OSFWbذ:"SWURM%[$JN$_cF'Ս!sۀg^cu1VWMl88ƜKg@n)sP䨨*x#p6+Tb26`.W2e\B>|N OdLswPz%m-ZN-<|Q2:/eAC0M ^gĢuѣ4ӟ;O[uoWᨐ_n dbz<M.kj[XƂ5*7zN( \}oqg-X~ÉEv?nLmDL(|k[bQu7 ZTf5n4jU֏FW 2˥5 XxV&hď,]ɳfT Xy 3Q1R*Z$T~@uF>4QFtR3YNTynlo<Ɋ\j Ekt339?+I8k"=nnE#Z)IxTT.$k<>ǑwW'tyk7!jLa m8+^`9bi-1ih n,@+<ҟX' aJ/3q;zܗ2ϡ>ۨb-3,Z=c0D,s%|œ;ͨ]U3./BQ Rթ tKƮeYWUW)rc.gN}؃aH TvxWqfD_b| 7b/#ytg%1lU ;fϮ3:H)<~v+A eoXjE`uٴ™TP;#rg^',' UxnFEUm!ˆ;RhtY!՘7&T}~F)JFz&Ï(EObj.y<[4O_]SbF+~ A8?А[ vN.a蹵%Z2l/g_Z>W0*@2Xk물u{7r_Z?\oVy1֋O=8 %*Ҏ)mĖ}-xʀO&ci5`3vuRCLmS~D  !Mr桷i+x=Ȁ:du[꺺2a='nѡB/!"n{(^5GCc]Фc6f nq&L=*T_uW$^I[öOQr JR#[d?jÑ=A8rD#т||X 0Bl.|EqJ ?3bB5,VfjUdcv}>Կ؄|6o6pB/g_W~6ǚ^̐{벳*gqpB[.l):6[_B%[857GEJ=L}uEpܥgx&͖!ݘƒm\&!0- 7nU"|πy\N|0L Vp-E-[1 íhW/<6YT]UɂӊܚS5z))8RY\_zz陬'h"%nj4i9TPZ8%+D,72%o1g 붩B F,VZ5^Ѡ>c|:܇Ы_)x3/?bGJ3,٘C9U1W+!G#p >&ͱC!蜒hlhbnAL@$G)!n`[E&E͠$WvTb4_S.Twb ǎ3a@?=ѥe+js.N/cau.X׈Kʐ:4op ai [{/:{u) Ӳ0$/&bjQP/)p[JJ޷(sM]ڜY.jP%XV8v }aU}Fh^i~|lea5:̝PQp]|ϟR&K # =e |kӑ+%2΋j}4 M>{PYqE]9(]q9 FBm|g7֜Æ"͸1?o-h2@YUunm .ơ{~ӐS/>'als痲h}ag дLz7 aVIJg..eboQd@G N>jϮtn'G,+E;Xۚ=٥?UxBW-8 s&pbV`5w|Aw}pdw!Ӵ~]M 7 ˢo76sg+q mۮ˦j,Z^vpǠySuKVO+A{4;*Mjn<~ i#{#^#ǰg5t/@b%USf&jp2* V`N 4Lā.}ofT HSy=b^,èu]nDÑ 85WgԸ䊄6m~Х cΊb=zXs]]Ū?)\_]shs _Fx, ۲qa&m⣾nj4f8FI)ĥ7UP^ cs~mh> $ћ\ ]B7J;l4)Gqr!.܋]i[៴=s>cb~)UڍՠwB/Yǔ}6K0ӑV]ٹ Yr 1é [޼ty})- u6:hZ]5H¥ t1=Z*sE[r\E'`?6l<[v,MG& a8.mT˗PI鸿}=%C.wceE>< ?d@G 2G[jCpx3(=)1] U1~a]ô]jN S0);=ա[#֨`/ؖAi6Ү_ ~@8bJ,Q!hp:TI} RWtgAF[#UȻOXc[OZ 0V?p'(v[g_EYl}_,20" :`)d?}ni+ UYr\65Lb5 >^ES&z ݩ[%I R|_jU-!cyf16倵P?Ba&jLƨCU exEy#pOo${UXQԦQcfjkEu+c?_0z'|A0B DGae6"kew;,1|^/w22H2,F }ڊz8pMS_hx.YN8ޤ[㫱W]OE]iC49Rj1aY=b :]"z'[a7&5`mqڐYߍ9b>3J7@i0[_S\YX]=Ф=TŝEw13#¶äq% !?!_{)/,sIM 0A\Z0hL[IV{Tzn as,;.֐8]f5X:Th#X#a3wg`Z,jDJ]JA`ڨK5}y3J҈5X:݈'L|1,tS]\ϝYY%RTnӯZPX Π0f(q-kUX6GJWeUiR(ى=VzM^Xy/o$k>>sl,ŒRXW [I;#Q*aAx͎NjGjmwf®î(gva?5oeH-&{j(h>'1&^ked]^fK=wH g99pj&h"i{(IB݈hMEPs$"/-u6֝پ08Zan+Y?h"; 噊L¹588]7hrMբ~&ϬQ[j\'OWpe6*BerΑb ?үQe mq[sٲ`?}-dnL¸Eg+63)LkoUYglN^W8!8ߡ f[e zo#/_>yٮo%*HI"{߽픆{u]Z2Z=,E5f%"'fE}k|']?H~:preeZb)on}Rm-˟,sY6^b]<~Bg0Yӟ05pKcdI/e;<-I:rj_C94YQGiKB'4~; s{ i8k6 Gl;X\GBt (N4-0~<}^=hkdCBdH i`@ۯV4:ٓe*#Be1n^v:UJ\KvcR <.0b6a#N-T?D+w3VqRP%aUzBtX$﫻v*ح yz̙8rL!zxھ<_ب/ W';n0­6ƐCszPN=m+VaTq(C0 cpmJ&j2O{Dvej"eِeu %ێhKf?KI/"%.qe:c$\zMց{^"g-xER&ux#K=tp&A=8~u0A=(0ODA1|W'i\ϫ'}Lض=bcq;08ED"U6s/SrmWcnV!ʅ47wj|9 %h^] ITH^%2.~i&Z|1T[#sabSF&P}ΙS׫[H8}Xnv&hL6xi'M tfTo&f<PYuxn_+vZ<\*1w|*laq75Ub{-u7m#y+J\F&4U7Fu+eēI~g&XaRohIKc'2`T}hőLd¾w.kKheNi*lu k:T}9g!#֮+*e5L ŸrN_NZ@喝Q4e" +Rd{bz̙WQ\m;6aC&U?qxF)-pC ˃-آΐJwU8bTd~gv0e'1WM m" s 4پƳR}*TuR2Ă) ]dĎ-yՁz\q†VbΛC 8 _½Ը"uuӱlYveHy?ȻNn̨3~h(\V)q߸[ݗj,UbX5J4_S͹ڞ[Zr[$KŅ4k,lȰBUFn/-Т)'h!yLx{PAf&:;ֈ3u6e#2^ ]jiU&4nΥ<&q#at*ri.E</':.9(DfE[w@6_ym}lv0<!&H2ȘϝL8g+(4`P5|!#k.~eͱܝ'^,(mUc33^O5S>#E7tkGO(k<Ëgѿ=Cx\lTQvf,Lf3^mp\Ly]cP*k@+>K$q3p:iL/YXYjnY 2O\߀? 6K|g3lv؊ʱvloτ64coxr{.hD fVɘtux: TyaaY?='cܛ#EHLD*"Ov ]2hsL;&tgbk=^YYH(u)DjoԞUệi\hڅi;%\EaUZqW8 e6?}Ntb~{v^t۱5eu:CqADu%5ZQ2?%F걥 ׵esjGhæuӉ+5r G2U ږŠq=rpD p!/mУ/M}P}4TOP+lPf}?3ƕbhv/}Tٰ cUR"_*1V_U8QJ]R㚋u!emy+՜xʆ M?TNJTVW.m%6/A_[ۢϜ. kYnYv"1F9c“_0w fa#m }!קo`OoЬІF|w%4r\ZX򎧼?HM݊?[yaefYN7oȕ+ XViXJB bښhLD27ǫR# i&ے &NhlXIo"vdr+ /so.rJWJv8ƣlYќK 8BCpa[ (q-Ç?q,v.326S Y=OG]/ 1)+QY8{y$@H F\v!]\{{ޱ( E {mogvgγ;{ s $Cy61{7ܭDT+iiǴ[s=rqtQxdenR9n:QwƂA5b*PDEjTB'Im^Lzw 4oUvwsvSOtѩv))/Nʧn4]Ka%9 uŲRZ4 [ ,2G|At5vdXU.j_wF'O$ػ_q+MR&U-=mrp:6%εZdaG꩛*-X.m;'TLc\/CğMЀjLRX9J"XLOX痤'P[dG|-f4_Wy2l=2\ .n7ýZ17#OJwoi濇W֝N#ץҋjD%X^D;Rt 5&i`A=~DW4{x][YpYdbw)!\+j'E'crJghqBWco ,E{g h3m:aLd7t3UQUt{rJ&y/̿令\hJf | M5Cה "~_>B34Õ{u[AKYcd1|PT *CVc#v-96(]m"_v?kp8_ (HB9F N4DIK3|UK}giG[@ȻI/sW978!9S 4{p=l,. H\C4pv zdqlʧ†@<f0SDZ)skzra+E-]7Me5Һ <´\= Lg.Fr56%9Vc (V`9~aV'9$Ɲkbh ǐr{TUHW="LB"sp`!f6>kRϺyqlE_iX9\ f!\/gw >!Z㇝=a^kW,6y#G~D~6lQMIZOV{R(l ˶qi*p;Kj6zVrR?mw.HnA.Pjt}ich l#Q%IX8U)ŭ j4T t$‹eȸ!XsM2C?pdqnXqбN0!EzfYb+}$,F5 ͐; DzߴJ8Pi@Q~D;V%[htyFr Gߥ3ɣ \XKG`2kAuKjT8bA;%ƨ^ Va:~tȫܖ; Ю7I p@;sͭ*ɌƸ %XWv0la,TP?wf9,ޱk54ړ&ݥ',6™|r,]zrʲjuƀ;`3\px}'rTvTz*@WGH\ .,439A2_jX{xq2o_jW9/ICYAZK\4P F>nQC|bUu9k~V[/Ҡ3ګAH;nT\!$O͟T8&O=' p-YB|kiR8jܽ<ʡ!}R2Dޝ Wوa1lMlldt-z\:8ͦ?"TVA#H*DSXr:áNMZIa/Fb:Dpsc]p T+$Dj~k\pj3͵t[Fu&N>}$Gבx%]rkm)C=^tҖԎ!7Zb0a:/_Z58E-[J83B |)c.[H=Zbm7Wwużz؀ߕZaՀ!TmEXwp'\#-cIsi@ >Bp\R+"Rof' |%`I|g Ëh[L$5HB>ѭ4c=KqDҲۤ;J%GiFKWM'rSfla'E ``=v".RҾ#|'+J*tq*\4,ȽfW: [4-m~XqzFe4!ͺk++|#tn`d_l{̑f3nl)v"+YEԓ:p''>`)$.6i-\Iʨ> bNɔ{hcBl%ebD]aaOXy2y  G.E)j`W2G=BUسV9me>wr>_iDZ}7l(& z[NwҒW>zѣy 50^ۖ\fOd4̍4džz)5Kk iv@R['|(E hD4~X9zdpVFLY 5v F0D2ρs=BcXXɢS)ho%ſ@+8%Wm{$8ANXG2H96碥B؞"Tѣk.Y >P"]fhik֋JC÷?V!TO_KBjl! 9rˑĠ Dt}4Ub|zXb\~œ Tp:jUTg,ng눽2d7H=+6&Ӟz_j/ؘ/㡢tuz1F;wҨ9_\3rx/҂ @rS\Zѳf[x$Ktws>LS&в9OzSl*5QeeBS`Hwuxv K⸋Mݱ;dz|fzXK5]Q1ZSG 8.G[G> ~/YONMi*YK5M'[›жk{cJ̝|ٚRD5_kil+,4o:ES8 K՛?S<$*-0d_-M¬_l8d[ZMǾW'.XrQy\u~7Sh5N` ǯb>6Cëj>54ۃ _-'|o)*FX]O6ƹ`u3Ts2lN#+E[FIXDkbY%rmӸMcI"IiܭTR~ djBN"ol&EH6(MSc, 𧟓Ҁq)uέ"*jb?+Ҩg*]Jg2hLA!7-.dYTF'gSJ/ݪvGYndTo41H3z&Ѷ>&b][)qfNH]0vu2QԎTR~utz)st5m.o%t|9]` D.Z(Lk6˦pW=ړO4}̝ͥPEYq:-" ,4<-4CG5 K1P1n"g>\؁/⫗ ~Z kzb^lY+Z 0Av-S˨"S]-]0FM_]0/2zE}:82})G#R8!F 歷AVv8*tSRbr!rPt[79R$UWQSh\tOb͠~yV0lq7тٍ=S/ȸZ?;ƶr lwpnn-?=`'~q-Kʣ{siVN#U0ΈOU,7,!ʀ hCT R(Q.pA~'4+t y!_RbTHU8DvjW#L2BF /4JZk/PܐViI{m5=wCBX Ә,< cT{%.*Efc/4VEWQC_eD&mr\CsY'L WŁz$u\ȯ9/CNC{H7C)R.2?Y@Plh-uT6 nQ_z68^-;#͹Oo+g54u{2n+`>WhzĿӡlkQţ'jxu@|g*Kgȑr] tNW xA 2.Ff1 ml0a9vԐM\J8\LkiߜZVE&k|Ÿ2{|YSH.Dȟ.XK ߫ѥ>]1RrGoK@fV;#w4N)>9|$5<̭!ybNnFyKrߢ;mbO=r0][bD0ʴ :_|o2qO4)|JgWJ~ h3t3!wB5cpffW3z6M*!b~n*ТW[`W1ld OfH0(Gȗz 00+8] h 鴩&]LWz~.^1`rAAbEm6k@3Mnqov??"{QzijXC9Y xPd.jɯM&1y>Mb8DP!tq411[i37Х̦AFAut݂$3B}F-NtzhP'RcA|q<;\w*Ϗ)6@%!p.;b{9>,9ֿTZ/t>hs{քЇY7E@Z4{j"{5o0LL#VRMQ n4A:Ov>SR|:5v*,\ENKtj #Xd9V~gxyZb Z-}+L8 o5%^+q` l0,נ+skgl ϶n0R`@ij['ˑr|(CnrT~A2;H6ae[JO轤ɢw?ћi*?14zX:8h}En|M6]'_KO.s'yN[ɠ+q{1efa5̙,^Fr}-P`g("SG˴O`a22-bnf*{AZct=TE6=dw=բw[z1dLY.&{q7t72lﳰͧlUF_iԯc}I1v:.j()I Jl8\*$pHzb+h_Hʺ)0M2'`L)UصCrr-НZw5ͽK%mhREʱ-;dApPGUY?%Qۦ9qFns7PFsys}#irgES& +ՏnLFze =E=[_[=),oejغ`R- Z(ծPvkW=N=ZpnZ UZwTf`|cLpڶN SF7{?Vӟӊx^5ɤVVOR^2-|?U $=!>qbisV5i"D?r@bl],($Hu4d0cUAK_!BX,52?zJCvՠ-uxOcTJ|yŒo*tIS=ԈS! Z&Ȧ]ԭ-Y{қT"CV[g7߃Mbn"#3s?j9ęjf(a.yC_+0@\&+f4x' \`RNp5X/JMr{6Eވ%kw_6Fp\j&0\C G^ekSkS?ҁbK0`ml b[;m3`x%2#A6A:ztaZB1dLPv oߙF+:lo;.2xS7Q}W:I{ { ԦROpF?}iGY>u(쩍|#O<(W }IR~RtݯCrӎ/t#.2klzm1~<zO/?viz`(w[{z'n%M،R8DEޟR.MlpA`ʹZ@S Nh(W":GGV*VerR70ۣ˟bD,jU]DLZ}+&}" LЧ ;V[i S޿~E4M߽{ɫcݿR%:0"j 33Wfؿ yP]l-/̱CntY]>La]kes$8m9fUx3^75?ôȶ5_:Ɵ`x:ϓCU.c! 5H8vL`9ؾ˦랱t72PhSeTvL.%%%toZ6TԿ/z(:ʩY-E h82 LF^b{NOn=|YоK@#=v l.t 2މ֘TlCK[?%l3gkR^h@Bmp^7,ѣ-0z}MWvǑj QV-^0h1KOJ|SY2ܗɑÕaG]}#MC&)3F`*KlS `,b8853&^EQnjdCxݦ% Y{QI;ZuT:1S :ǩ+IeUTWG3Xp ߙ9XamLvVNHJvF/9=Pajqw`A:|N5@ԣ%vqt3qB\>EO 'P fӽD_H}#v}GGB}d4@{Z״5>*jȆ2f008ol9.wj 4U^QMl)y(]o tH(:Ϗ"EH(yNc?S}_йm^AGwtq GD=]ףAUZLamo, pC:ucA:b!et4V^ vTz3&Bzl,#nxh|$D e: "^JiFZ^tdmȠj{RJۙb j(!gROap& S[\Km%9,~ =m.Dh t%ڵd;h_$1ZF[0f?["h).xrd4D)TH4S ,y](~b %e7@Or6Wİ팾*@% \nC;rPLGQ NC2 a|n .[X_}I/rhwj:GPJWڵ:;fߝ4b˄l{Z1ǩH5yl.ę퉷81Ư3'cZ'Nv++` 任H-*HwOus"?gfzt9*FYbPƽ:z-jƩV j1XZƴ5Q 1Rm(.vĴT!6`oݖ`fN= R[e1 ?Sb}3Se!L>YٙR~>LJtKëo-p=Br3l k{cn=)zPRhVH=)~ʈ%/FKԥdEW-=l+)4n;XA4PJ$Vw/8o5|JMqw%M/d6-XSl?ft*jjcgadOM+3Zy#KZv?<깷d}Fhk:=A}k'|#G跢^RǕвe&B16́8@^Uҡ:N*D jULwUYF< ".1Ǔ* 2'jaj,?D@ԘiG>caMasA+v;#g|u"jLRC-Ǿݖs>Ak]y&xi6x~E;D(!3o0}H SPؠth[\lUEYtog*mrH\C}ߚ3KqBngeZ Z#+*Lܑb-0o0|!M;)~L)p$zT0e BQl!UՔI#Y4z :,0[^  kir}2* Vovjo@f ["7TC0 ݟ I.t0w-GvoPfRDh5`f~[Eat7K.A>ݍ-a"-&- J %rwgw7;>3;|x?9{@O*h. Wvjf϶7ou.78!+Z8-&U=?k_ofBC+hLN=vM;kPng%+$b^دᕇMCd~I m{-b'KhgO (;†]DSmDT3][N|Ef o07/?I}ߟarQb/%詸c %g5%dL|`ͶzZV9H_Y``W8bV(y);Qp&"\.e#Ml'Ȍa0!>=Su<~@[J}\ h#vna`#GOrgOf֪W#l]6L#LdR٠b 5X2 c3Gv+-;1N',&OqidOMźN6Swr\nՉD`*U:ktݳ em]_o7̇,f0M=Եk"J iؓ^Zv Ʒ/Zl0 =guƒyp{:rV]:/^MLe%'W:PQg 5Hl>ƍVxg5R7QN_K4^|FKti]l~ "mG_Fy%r96 c{/#QS7100 ?SŜjKvhø[lAR,K+ý%Zvs--ď(T =aq*y(_83kxƓ۝| ^\^llN˂^EA Ωy9? VaXzF;.gKӧau.^掌'㤥 9.aL'nHfwG)bvV Ml>iN w macE'a3.~ǻ ݁ZSwi]y.Q$n|}7lAJv惚rմR|*޳'[+pnMM#_,D*^T+Kñ^YϛmB/mHs)<Q;bi0𷜈q>5&3sq 9ȝ.t2uv~v 2F7? `$Ů[c3"7, ڄ ls3nOB3D-pg|=Nl0TB-&ZM &uUaNRK~*&nH{ 75HIĜd7n^c䡆 &p_{<8 ]3q/]1Ghbf1+,^']F>p7/̾ GF`. "IvA >>Ǹ%ŐsZ;4S?琉` )<͋9|wۂ7EQt\`鰞o,(}Ơ ɑδpW; %3ULs#ΪxnvmT̐1s3H O03e/,9x_%܏ ~p F]brڜfnC0"Л+49T ,{;^0/,)^Wx uNñu`w/ĴX?i<A1# '+fK >aXy_˵CuJz}X!Ǩ0,#`o }_ $}\cqs ki5 8"A ǻjpͰqj/psf;вZcultXFT䆞*NPBP7棝<`Mu%ԿߎmeX6Άv2]]V(IFٷ蓰;4+Q+@ bάu,7X#W1gNգmXρ"3N)˥eB9qەb>C ;{sT٠em/D fy'@`Υp>MQ3@]L|Pk n;qPۏ; o-/g\-La(%|'vW}!,l Mn󿢺{|ėo}/j~TKla&,^c6xM#{=[|Rft{7|@ $Źl|ƉkTUCKfx1".}rhK+0s\%R&zգ[MbhĨ􍰦3[`d.lj?RUtpl-ғd\CG؜6c)r!x|*Iq<[ׇb>Fe00v=*RB{ &T0Z525R1Hń >H2@A2i/ca)7Oƈ8-q16;S_ogUh$U`jV4R7"H!ғshk`_,Đ 6[vc}W7'hSR/9j#bF}N_0g:3-86I \;'&I:8vb}kn2Eqz!{bd ^o~`Ѷ <H_0SpY-jxLS,0`^Y6]Ɂ=l_+4ô]{+f^9h'A>Fu. 9W*ZTX_2)e2O);Jt5yfѯC?Wq5Yxlߪy,@c6b_WO|eIv/v-򴓜 W[;q;0@"2=Fc_puTm_ =[4& y*DkYɞuZ_y֥*oM3>L/)ZoEl4 <)-O`ћ~L4l:Mo3]*;7/rjOtLvg=_,%{ufnǺFE*5JKSiS1FٹQBX'iu>rEh_oЮ7Jq$1mUrk栚k8oӗ[AJ;U q8.6ہcxk5&.?<n 1׵wT)mP2~ZPW`R 1Qі݅.p)< 9["+%<z@c/ Qf5OQrυ^Ax. ^%td&]-qp~i$w bu|Ou3~i#"e2 οľ#p(ӿ+iPWmKt>Xk˴l2׊nCc֭Պ29 t 6)jQ>qGJ0Vޭ+Ɲk?y.̗3i(m+c|2j7x)d笶ẩZ>ء+r.]'h+)O-h % l; tQ?qڳ@fY(Љ" &XBMI*/KSR=E×e\@r&<3e|!*[*cjl,d;,}&@ɖTYbW&dL)cZ _נw9<-aŬؗ;S !P}lREsOAQ5 m߅fNlϞutϹ5<0Rä^ܵJƎ%V_c~B77vM2q5EU zOtk@n>Rpk!J*v0K:nfQfQ3P}uÛ,ĭhgeM閜́^"ΰ~DZ6aT17F*5ޒ]X`S 93X ;'Ffak7 LKo5Oֲ~ pK gnjS~~is#4B4(Kf` ga{-#adؓzZڭb)>*UY/\?Wk9O`D֗qXVBPrXܭaVY`T ʅ q6Bax NM ]#]Mf#4w Fp: s2Ľ6=61>֙m4[oZczZv|]_; aZ&9Rk0gS0H!ǕU`"WFuP?Kuvrd =,)yR?@-1{gDO7ݸ Å6c-ou K3LmЂ;Xp!sjZ9NJ-<ÜsrJ\˭rg<61WnD&?Ҁm!ҙݷHUN h+ϓuc3yJ2 -T|4\Up.s<%.SP mLΑ3N;WImG%%Jf,Tr57kEk_v`cEr#.M7ģƼŘM4ւɇUyO3a_R[碣jz)':.V%]Kj-Oz3Oǫ*p&j 0H9%B2S `p5Sk6 ;dl^Y mmVyTɕưiYzo[au_L[2o>bӕ>BǨP'yqw{xKXCL'հVݓi%\-dԼ_丗R6tggщ ExGD6;pÝ u,iʵ'}Ǝ-/˦vv)uv66`qR CCñ/boZ{y7:{sE5/PKrSwWBo2[;yl3XEK5|X\f;5 \=n,pk6o¾Et #fZkc#: %?3>o*AЎLw,5e.?zygRfx!T_Q=Ew=8;•Cdv<ϐ//khqm*l7ԇаv'`vM#lvU5Ӧ#A`8%ysU]m|BHL:jK }7#[{^\(2Ix)OTɦҨ+8le.H,aNb˚EW`d$艽?v.t#y!6L=(?+ef-fPWFkhI2Vzcb40s~\sbֿ`+{~^@d+i'̬-|YE'׶pO &A +礼Cўkw,9%{zʵ4𬡚h̛MGz'j=oºk5P Vb 7))J7sAjVnUN¡'Ŵ%D#b>6vev̙b= xTjH?0T3loN^226ኞRt+`(d< Mܩ7݉+--_ٲc50&\|ސCբՎ?8bRE NdLG~rvS2b7? wj&ޖƊWݘ(oa{dh94%0Q'k3O35ǩu&*9sEɏ% s܃J8x߄~掘2BpF r㞩b/pbgse~ MXtjc.Ӿ?]Q_2_ͯs*,x^^IqX)7ѦОY ܄xr>.5޻ #M|å]?Ӷf<{^D9Kͷ.*.g#JfQdIVd pΐ1l9H |p ߶C+pq ɞtó&薾ڠi1!wmu&$n2vtg"K5XSN-6ZS=cyW,y’,yšdּuߔ# x5ш׵Jw:U+ye3ͳ4\IE۫Y~D`~N%o+ȞRn.fa1K%l߃Vyd^ )sd-=ҥl$Bk]nDYwg~vn^` K7晐"ntoĿ_Û*/|y>;̱_ [Ns nOsWC;fc5|ߛdcpYy(Xޟ~/)Y8? ~bS JǕ2Rqf3*,礃=!RH12'H9UlWA`2s͛!' ǁa{ޱrl[| 7缻р.Wkk1~M@.X}P ]ck~YzŒ%N9Ɵ1ƆnBfek{LYlJ[c1^f6˒[ywq$Ŭ+\_y=b 5]kx)ޓmz:SE6D**yu*u)Z¤X!;33 kZ&>TxXɜ-J Yl)/l[sԅv1"tW.h"7[ta7V`q"{ _rhdCla6< c>}^{0}!h֬9Zsk;9JR+ J%r&z*|f( /vk$EN9Wuj)/JIMpe'W!p+/mquGZp6<‚e{)fB#!kE-"s7|`5+u/]UХ&cw;⏮caMb:'q%\g=Nk3 m`JSmƉlފ.ڲ[_.qYFvVb.>'e:? ɩgf! -Ub-ͻjIW翪9N$?KٽX̽]9t=3rT.hl˰{9Yw#ep C8t %^;~_y<[ /1pD'Q޾J"vohϻk#-"Y`d#tlV!e6d 7*2&bX|Dpl_Sp`@%Y5a&2gV g2u+[ļDjdL1T"x=Yʊ-tss UJ:uRҭn43bBJ} 淓D&r gwv6{gǒK%ɜvSM;Ϙ* hUa+j0f%t*GXj6wRYru+wڮֽ<䈱;qh ?TcZ'R^e.LƄ%L9[N ۖÕǻ3e V_ )S3^.5T8dix4Y˥U*޼bneƂh;V0QWpw7btK5C^wUpZW9B\쫠!3ݹ.IĢ|n|MQxݚjqtJ"ºDU_&˅u5sw"G5 ڗ7>^E42V%bֈ2G7iݠ$$MO:z(RDt#Ɯ~WqҘӂL1ɂS[8p8gre7tgyc1IY竌ydHj{J-jp+bSUk)N9 *|ubb ޺U)1?˾pL+F7p`a7ʃ2tWRIˆ Fg)I}op"^6uK;~`s+_W7wLY7Qqh .vE%S8lܐW5Wwwc+yPTBT2b9+ʽ?DWQ%*15r~E`N-f񊏄Z9#$p*1>1-=_Xo8r15=qSsʷໃL4dz=f-+\%Ʃ06"ӴNImbM \=үc;b|Q gD牢cȤW&|wҜk[qF;;NlL.Yby(XZxq'h^.nkawk +;PF[G $ 9)f"k,rd"~Eǫe9ސ_Uح™]9TJ[we|,X*ɒwf0'ۈf>Vt 5:o0#]㸿ݗv!z@xz{ntk=oRMygѧ#ڊyc,/7rm^{=e+Sδi6toF*^b[MDC0tS9.c w GJRu=M=RNvsƞt"6t GD8;潳dt3 >41Ո:|9Ò65e*>@Pb>ߺоm8ߎ.]S7ZA[S0/*?R :}0b͆46cǭyY8p#o5kGt҆4z䭁jk^65**xة{[%Sf yHܹr ز)Be7=~mW7*F\ޔfц3ϙKWW LƴM!e\ӎauL^Sxf=}+?ٿ丛G&1zNwR"t0֧!{0c(K.GvݝO(hbܕl%æ{{'ٰh5g5mVR4?vxOƓ,TWcGIx(X̾ ݹ\<%#GHȝ=vz=7̟*'Ƙ8SÙݼ8#/cߞVL33/#c>mH7+6hX]hm&}Ʊ;0NOwr ]t:Z +TT*'\lݷ8  #u '.{Is}9E<ޝ^,ŊZ>e; >?ٖ*C%|Cr6$1uLr0!G-u{> 2gi>')ltcO8".Ӎ?n+L)7cǖ|2†.R=đ4n\ZO?)g>qfGsvd>߭i`G9o 5 R>`ߡ#u{apli#917ŜyVk˘F._WՇ|_Ebڝsg C[qv+b=boh>26^;Kyf)HLCDl?FdZ0KL(vCIR,1=w.p%0W/kZpt3V6粍W!o^ N&܍|@ݗM'٠k~3H]yQWQ}g\cnha&lRhأ&̉UumXRfKI8s0{ ]YNݍk%\# tr-_Y/>_<S;bEs~tF=|7:_fiO܊ӯiUF4&\hδGVtbLj"Gsg 7K("‘ˏ@ `\| Lކ7aڝX;*~5 {(U@G_5\[qg'wd@=%T w{/ǥW{𭞔-tNn|ɉ?Њs9[%Y1&ٚNF6_?X%*C=O4kՅ6~7glnwKg[lyW]*)πc i:׈ 37vՊ}mYg }Y6ˑ.Nb&H9W"|7|)xr/w)k ÜQe2V|1Ύ-˝ޑ90t zrm!J$~ Mbgs>ȝVG*m|z|ØS;Xr-rdwڬDwW͚_Y0<W֞W{;o7w.F}UhhPwX1*Վ>xڕ+9sls#|-4㣷g~܅{Q}EG;"{_,-Ъ!,J$|6ȍ"[hS~a,g (@wQy+5$ N;9jg], ';6Nmlh<ڈez,Wƿ&{Gd!Eź6!|wwקې-}.:j)LlxЂ6Y+;vI";qظƝ¶%*8㵂Qjޗ*~24 sV9 *R8cb)Og[^A\3 ݒg/0 ;}DL'C|_?P8(ːܵV:Đ}OPac ;'Zӵ3a˟\jqrf+~Vۿ[o7*3.^B́yyL^+šZ=1ƛ ;kI1J]l {NKn)8&ES6ꂕpiaWPgClOTȄދ<`n9VL#LbJ̸kRN2検TJ8# R Q?,]뾃GhΊb\7`o9at}\89\AVt6f&,F&T)II ׀ox>G`}BH~7h;>r#|d&<\S`gtzDC?Ӻ )rP<BG޹Ș^yJ!٘{,:Ê?Y) ٷq6NE" YImJqlу#[Ne9[zpW 39҃_r\x9+Jt:'_n~$[FUkdv  n]vwwbwww7.TB$%E{?ޱYo1 ;8&pSeeU"&.cdzz 'cmٚ1o\Qa2GȑE WqN}PM[vGBi`95 ƁxV6 ZPI7~' ^jeLiyTu0ܧzs.gN?M+Ŭ`٫B8܂+{b}(am,Tt0ԌpI~ƚ+~vqsyl9̘c6\Aدx M cdlmFf =yVGW˥2%gwPqa"p@ +>)kmgm1NĶ=fcIϭX*ū"^*]Q*z4pBW`5߆WlSZv\8ʼn^ 2ގyŖnU.qhGC&6/01ܫ-?,CA}:z1883M缟j qYD'<xl2vh^C^_ lO(Ler8޵`u"H\XQpjAԟwet~+l^^~p(ě)Xq"&c0|߼'̉FzI L<ev0ln|O\~'M :a̓Ō9B/UZ ;OP'ռŽ;洁 )slVrZsr[Vϱ!}aWLKNy؝~}ٖcq5;VtW^]-Wug2*^jfNrɆ|=،~h]>{UXJ#vny\/Ԍ*_)v9 ݾaEf$>Dy]B0O/N*؎7%U0L*BX5 c!wg?~$TbGh¢e |= IyH{EpT\y<͎x,|_x;ÚEsy#w-SsO5mifI t>i6dm߾qegvdR#St.D𖕉}݆H&67"F~_! .QPwDo+%f)k~sV <7O `-y[`5_ s⃜[ -r"8৒/{X0r?-02Trb$'Frb;\ӎii5̅GL之ZN|b=thY121 \kx;ѥRe9EWwJ5V?p |zHٟ<眮y^F|/o')5HCУ" ]D$b@gք<\W?̴X<j@9?QǒߪQP. 2 4p\ totZGֹH/EJE)+/O jlC֖u6ӳ7qsjmWږ:HS[^|HBiSG=Jάk>b6%?͓\L/ 3]b+5rĖ5ݚE?9 ]#1:)ocL x$|w}1a V-`K%1Ujd2Nr +X <3qWEtmPFV)l͉8!85Kb!Xd_:oI+hncgJTtJ#E|hƩPFh FJI 7Ɲf4_dEILGQ P΄"7=fesZ!VY3 93ڷX-Ԉ9ULU򝶴0E'=;i3Sk3nfn47wv{[rL)/K\fi1+yDL0Zs)1'SmIe.IS$< [1f+B3#}8^oeD?eM ,a1+U ]|}r&@Q+= 4+@w"?.{Wx_2.\m-/ᏁFXe56Wr3L<Dž{Wpn (6:ħ{4l\ɗ[ϵ\gpyT\sLƚY>ALSKv-@|([6U¦6J!b ]OE\-[󤋎Z;Xv jbYqNsݸ9qg'.fքj^dpYDH u _;޶O(~#F>4؂,8ƌoJPq;6LCټ"|ϭƇlՊ?ފ.˒?iY1v͂fBNG*zKb8=y,*jԿ̞f_۶l#2S1 nn3f̮•VHyp92&۱Rg-b0',C!񺃾WsNX#kEXۖv,qH=Dh}YGqQFݻ8eGfx;rz+]y\q;v|φg6%<]do:5ek-uOvHYy+6Z/1BZXľ2l\xxaqž/U- si 'k{c/8?hi6Ī.\ʑ}9M O\9ƍ >9pK}C-|x~kT^ />߂A6Y)Á n,gjн'7q6\r4h`f#Fq_>Jвmũ9{Dm0E!R[ f5gL5KH2AFW3Q}4R[gQjWѰX7,iYNS _hM#;wdGIu3s޸PL\ɍkLT|RIU<[ËhgA#{뾊'kZsrEX- ڑj+Cb횅H%#5= F~Z+A HjrU ZGQ om- {=}_p%zX3*=+hfW9/[q=1KXJLTǫe2{3co~Gs^)C/tT~Ko`lL6e2>.%?i[ڱP}JU|RuܐUuiϙۙ3wwT2.҉hJnI~J~ PK dzz5ZtBc[4IQЂQkCV&D7T{tdNn™9R<ͅ];ۅe`#u;9Ibc`HşgewHɓT/c+*(7] Lmܟ-E\%q]֊BT?#ی>zg%\/zjTՑwD9 yps$pT t}K{|5ndJ=g:]b4kDh: Nܦj *LC)BoسJvMWs]Klhd{{p{Ɲ2;kvgx N}+đOrNdyugz裱eF&nlmC}O[p36[)\aCov=@zOWzkR3MM*WEbڕUkp%8qJb;y;rrM}? kWs&F3­&ʜ&O3>Wy.4>Z.>̥7sn~wPOC:o`gH{ WSBq\am+fCРυ o5ta֒vo=>QRv Rv]!2/P359k57qtK:ZJ/)Y%oPwks,Fas6cJn^U t3J<\p:N V_Ũ;&F^4`/.\j۹F~=j^`^:Yځ vh14ݽ%w?p[e BWmj rqnhAZ ٦\a]'UK̩3]XO-8=M2F:ixpoh^G \h}Iϲ-r.oSJpj1J|ǐ8!&̽`L pNlڲ 7o^L>~Si>ٌ{k.9d9cO涓< o4 2A燐; zIρ) aX?FbfJ-b>ďy<7͑u9d{# p1b]Du+0NJR.\ 'A`g҆WrGͅl`D1dY)$YeF?ttO^ ZŽK=WmgV%)w8r[o#ŋ؊+l; {`F ۿw]KJkbǨ4 sO#uQǂ6ja m#ڕǛj2تC|U!gnJުOI <XuՑ3M-L3ޕD4)EvL hcwo!K(|yG$~>6-^`y[D>_E+>ժX//0l~|]DKp_MuٌX>t!&=z%ޙ/e%z 11 ˉ-pRG^Jpfýk-U47璣Eߖtl_;?2?qvT!y"<~F;y6$x |LXI[*gJp"%V;N+t#7q<7^9e5qbu6Mb#۳;m!ω# Y pKuZLTSeP͸Z1㲊fk:W },n˙lY`_9N.}b55(;Fsa &9鶔&dvhbg <ƘJ,KG(= ptuD阓; |6:nA TZLf{x/Z:K-G郲aW7t,Ԍq%ÌR,}}*qzZ"q$n0vCa'wV#vM+;\I_=?9\gkaÛ(8鼂u.YڌwTbb<a0@bN WweͦbJQwM[g 7!U.2|coqi b}SvJmùKlf}i%JZpj8m5T7 Wv do͙j17֩CZқ>M9&̞ݷl;pR29FkP;%Ĭ7ޖ2u n3q0 uڣi?2w"|܁ F;I kut/veTc7Vta#;ʨ"?u\sDɨDQs\!D.UxvЂRs6p/V;jO w~qp %tlNWMvҳk9rkf[S"+}ĵq?>4!+s'i&0(\ΠiJAO;Z^kyn\\~a8em~VE5/TR=g%`w8#ًXE0)F܀> naOvzAE7t OFvS+?]vIdǧ]9h'?` 7F7tg]nzؕ{8B*3Kձ?(􋊵)u?5 EX.u>aKߧ(xC~IXwl"'Ω$@Z.mdZO8سp)iZ1D=# f4=Ԍ.9_Bw.N(➄}ٜeq_͍31kih"a\[H焄IemyܕyTvgM[x"NgC˽R&zx, `E#VWHS>&X=}h.;ΌL<{}=y;;JM_eyl{ibZ⊂y#S3tNxwKQ{Ķ?y`ɫNBǏɰs~T_a:|cbs=t\=1mmy2ADzRR.UHmofmz 2P|t"|/ː5'fǗZZq  aJ [(S5]i cfLsvknJٲͤ\]ךYGxk:A-^d)|Ng!N46}*ν m99wE~R ]ıbʒMSrkmڥz1+q?l%Hǟl2ҌXvj yJ`M˜0PK0bL\3U0Ҟgi/?f<쯮gnmlg!dݚMj~x"WO2ۜRe[l ]ie{+ Cm6+eB$mXa&jO;>XgQ*L{̝X?Gt,f4 4c?QR  Z>E0M)DߊݱfTy8ŒeB%!fP HGw_pw:l!&9 ?혆3ub%Opg뾲[4Pediw' <Ȟ m[cpVg|x4 mk6Mo?O}A0\<|t)!&Ǡ(>bp ^RYhֿ@&NYMc $LF|B|N"j9վrvَCųR*).gg9Ӿ7jNϓk/疛|ظ.seG<䇣G ~H)x"f9 YpP# a&b`C'#R̵/%y2t>e"Zp{U)GS\O[Fd Lœm M,&GFX,B;}:8?3I{ c|ݓ_fD扯0kS5Oا"%ts=71{U+{>YɩjBv߾,P j]'c9qH;0z-iԜN ^<(S-9g9B_a>iyP ;cmVN\_ ֌ ܱ1G>K8桜4luB^Wl(_W\8w 2#yĒ??XPZi=%tϚQ_y]7Uz_l#F\rڮq 6~q^:*]7xBa1 Ṩ^R7_c-eO&˸n,'\lS,L)Qj:VA9j&Nd՟kOA_vs ҊޣNH 4yY*JY \UE Oēy5a$f:ּwP0)CL| fj Ӷ|DůDTTc"3{*&!7=`@bjǏ U<D1vsȖz5 ccpn F +s8W/lnIOdEfYH$'Ex?i˶9*]Sa[BU'2g؜L`*,)o;+ 1qx;h*Jċy[,c;$iT=' jx{{p#7VnvggcOp7"5'f!2T4GʕbƮaVY`%*ws /BbBHsZLTe iCZF•83+^:  <3 -ivR9Ss;Ο\Đ%zMs)_]H(˕ntGZNU1!)*Zc8\BVoQuMzfE ,ggO5f_V: AO?gM(<{+z]L]~L?O[ ۘ % anV;Rħ=XϚdL8"U8hnɝ"13ƒ0lYsѢ !Wswy1nUfl̊Y֫`Z7Cը蓰  Y w@t3.w- 'FJk+&[PKX1d5{yK-Qیoj7‘uoKͻsEK;|{9%l^XVT~g-E Mx;ݷgW}*%e)Q[ONKH5g(G-7z+-}AڌX5&eDf'챻m~NbBCB<<-x|+3m.W8tx>Zp0[ksܖOLy{o;F܈,ĎǾ0SkP Eݓ!'V޳X=ey!% Ɵ+&b<hΡ "jy|M L9 z <iITL6 _3\DsC0;~iS:Մ زmW{n 9F=+pQ>n|~aG!x~HR^d\LEf>Z@_$*Go]P'Ў4qgqތۻ8_}1:h%6d7r!2Q[rOnpz(nUcDTxSp (GDۉ9Z 72x8%^ƨAɾj,}W74[Cpmf5ZY3tܶ6vxp4WĊKU/mI*E,3 ƪ_wxvOĺٸO' /\T J龜*Fhy4Ù:qw! '1K\7 r?wn╙">0φD\qCMw|`w6ZbGK,wʒZqG9i#zԎ!ލl\Xv͎c=9&ߌ;-x1/z[#]E:q>7{™Ki8(!q] MisĜ yu@L99aŠVVtnNsF|I**O d?|݈hrG0k4_ءlzbA[Y"vwcT[NnecO~3B_Lm[Vp}Xn=PU#Q5Wp 3q&Y4WbR;v~b,blRr83ǘ*uN Ikvj2skrעVF=*CR=Xźq?I/hki t'd;"ppA^O1Ƀ*qP/4%CĔmxwmGNM> _] t6g@12CF0TVRߘz q[/[RΞ&hF~&2YДƘVs,q ^QajBǎz.bɬz\ZOtc] /*'nuAMpmMnm/&oFW{S XڀZí8sODJ(2֛+~xp#êͅ]ϐ4,. X iHDl3B3S9ȁzw 2WRը8 9UD=WX])bTK-:ɤYZQO]ZśPyCSyʖz-ؿ5'G'a&Wcߺ{"]i)wXP5h܄ ,z mɡ6gO#N=[H΃5őzZcj"ס8v10-乘mK90<}+sa}%N{9kq&uޠ':8(:u]N -?AN:|G5W翙&/?=4oΧX9ٔut)XZܥ˾8Ջ7OKV慝 >6,gG=T8oؘZsڂf.v\.#Z˽bboiCK7.zSφrǮmDO .m@ :*1Hߕ߿'5zc/jMva1K^Vr[3 }z{N0+Uakm6tǛ 6|bGG~rozr _b$-] hKX*ŒÅx5iQ)t>[~EG: FRP#BaWl9 +_ز uK񷰟>M(EER;xT?"/6 j م֣Gܽ5yoXzpT ŗM>cMVX`E 9Ыڋ=ʓoFs+;qcgI^\~؛()wtvŻ8sJ)Oy0v-5`&\UѼ\^W;QtJe|kBηo^,m/:)T9M,M7;m1y˥/|ys]k:Sh>W7g;;}/$kFЄH&!{Kg5X)̾9kUkv|f0榃">ƺ2;U Qf`Kl<3^Zw9.KTϰEf| fG/߰:.vũ> פyp nq`]N=qBY?iȜ1 ; U<,B6K+5S@K6~pp}3,M9Mdm*甝 ^*ejul)8((a JU')_GIxw|h.hd:s彮%8pHSעbN302yO~<ʇ5rܓQ|WŜ=<](tJ?Ê IY|T|5WS 2:nw^!x)ϼbNw s-=-ᝣC((a3\9D͇*?[pKkPBw;HF5jz|w~|uǏ7ҫSr%#Lw.7+vT6bL!mxo&fK8ȇwy1 gpǾ t? 8c?0"?Ó: ^1`&L;m\qׁ?\mh~@ZU8GNcѣ:Am< =S;$6 :}X窙Ԇ?|m.#2%3rq{R #ѳB Fczɵ̫l3q܃E^lL2Rpg\*SɈ1,ao*R3!策1a7 l&NU[ۘdf\Y=Tkc/U1XQj:qGl֒ |KjvzY)b/y)5܏Z0{/k*D~\SB|^#BDws+IGa;Fuˁ&<_&M[8e\)l^fnO:pG!Źh?8ooHޙI{'lÓ\ъlm#:w0g7n@؊Jȭ@ Jip&#j2ܢx UoK\5wkyS{4rB!zUbG=Zz|ަ5 x% =Üul‘\ЉUIyuܻGy+d5UTV2k3tQXp· f~eo>ųKl7:[+ŜxQ^|-^UBe6_m-Xx%w素:yOw՚=.|UEsrvq[)9!VqM2 '9)Xe2ޱq%uY0Z8; }tk)C\-L\2wyЏU-9hzkIoɴŭB֊lGJ}q9Oj/) 4KŘξmjo~ ۽[ߴс0|ϙEvw`:~ E.Z'gC)]тaj7aKT<ٺʹ~= S2pdZ"A[L{l|,/L*ɨ }3`P}N j!w-;۞;}u=T yz<= 4-9'7갋Au!;Nll<S6݆K|C85 2$*ۣ%ur)ƝA Z]+'0Z "-a/Wc~d4F{͟m濋=%~)"K7#&֖!O.vg) (%in"t}raQc+p.μYAI9 Kʃ]|)e*:'(i&M9|)e Q_}U߽1]-yq5L萏w˃FBcT$'$8>՟V' ޲^ƼȌ_sF_TU˳D穙|t|pV,C",ԮFbMIC(_fgl5#d!hwvtL=S i)cx4߯d{aΨ.-8AIU*W>)R_䌓-ء\je(Z*mRlez8ؚmks$n`|+3jDڰO#7۳{lbk'|SsnKvNjkK})=-XJ8 Rq/<5N[O9rZ_wRx񁓌{SB:9]e,, o3Ȗ;+: T%21u: bOOv_p1 ү sًƼMb}Naxj#,kfHx, mq<<.(9X3!ј(V \}0ց?a?Vnja^|җ|yG|"S-O-R1~sݢp7*N9n۞\sŸk*9醜g$|fC29(r'"7v)+XR-t]fV䥥&<?,&#q/ g1`g4D\Œ~-A݃P;>x ^K4aa, ɧvDsNbfv8re&h/ z@9Sy5V{ KavWtN߸E64ć3HKhIl(eMTr-%cZ΢) %cJjNGŃ~̐ l UQ ]a'lpfc6?v$6F|ňWqTy,Cˈx: >X#4ڒe\~]z3)3 .[r;4]5b(y2&[xJGi>ޓml<8dqL9,4);$7; 3ȋ:zrvWv!b͝mΆ]:,`3E=v}P> kAOSP?E%?-F=W_( U΁$>0>C祝 7=uO@t.ŦFm>Ȳ9/\g܊}VNi-'WPb|5rNʕl_Դb%souُ?pHJ9z˙yZ̹8)+E^FB`IދqGnskٌQ}87?5xPWj{qc_- 񜾘xrkXy)URvʒRC ^ 4tgeG-8B/NuC\=Å}&͎)-m--xRyׅsv.f,l2)Bbd 59EDZܼWchM˫\4fEB0|՝ͽan*;1Ow عV'c \Um]~_a+௕ 2 L=2f#a~ Q\I:-y{y  7%r`Rm]ޝ̽(6QE=<+iÏ34 t wJ'ǹPsk1b"<{1ͨM *Ѯ.sv\ȯ[y1t'?֊ f^¬GrIPI4^UPNFۡb&mvMd _zs6/pe'i9σCϺI 3wG3#mmʚwBi8LUbUN!)*הz?͡Gu;K m5tNq83 jAҸb]X=:E#Z&N.’å/Wi9O>wrg'N3ƍN3Wk~jqgʚRw+x-ˆ"dt _{:O3(Iv_7q<]?UV >7) 28? Yϫ9a%}ݽr&rڵj7𣭉C6x'g5oPJnɮ~LTt L,؁/1!f]1k#pd*p N`1xeĂX+^fa*269lʌws1+^dNtN1򡵹Ý?Aʥ>+gm 'piS mɹ"tL`Fbd1AtN#@{pG;)&ܳڞaALYc;&|΄2eCvDŽu Z^'=mflpM]5_ac/"<_VfVVPBGRBGOkD?oZɔ\pLB&_yǮU|>JٝdV#<g HA@ {r5u)y}Co;wnYZ1dNSҬ:zvl`D2h}GR oxK$ XE.⟢&_޽5MǠ37Ϝr 5{IyRǼJmglz|瞜IBVitINW]93;ɮ-ӝ q'W;ڳ0܁S3]9;pkƾϱS6}9Xҳ˟clhťXH: aL;|v['N*.P?Pɾ+l/aBwyРۈyQƅ^Tb ;{+W8x[>dnom٦Ι2 qsa[~sf*+Z13`LzM+ƱN?z+Z/%-y& ڀm4]gXTPBəu?ˆ͂'\ҽ/g~W%5QpW}~w䖁ܠ'XI*ZlV1݇Pݧl c.C) Ts %P_-Q֢u.y;k)*}b+*ZY3E|:ܧ* v.lS!l7˜^t)ZOV8 z;$;DdFD7Q$<3W~զ,Lڀ~- ʓi>ޜp~7pf`r%1qeZ'>u˓Hx'{:sWVc(K.<XKntK ,GpE%8GW6`L>˭[0ӀQ's'>7Ưzkɐ?l5x'OJ8QG- |ٶF͹ϕ恦_^39~Ȃ#$#n r0H/f3ړn^;XNR7&Q9^œ>Ry+E2cIZw4 3 `h7  EжiLv֜o.CzkBnqƤclc ^ů ],5 gMw.2ZRPl N'ӧm S<\U*>hCgwԜ\b8zG?g^ )+e.V`M9 Wf&Oa94 IUɲZlSmr::Gw Fbhm.uzqn<ɑA5,ӆ筝@L#C/'1{Lo*ܙқcJ87-%9z ;77(dxp +T. :Vks ]{ftĂC-cˈPS0nD؀ izlkzlulϤ.yh,X-ۊq8c[IbdV#,L=|Uld0ԣY,oX7챤;[)?I'a2)9&Ȁ_kiN(JALݜ~((?>'q6 -#vW~ECb وT-Nj˖řG/@gq8-T㵹q%Ǐc#%G{NiS\+s7pvoN?- 4Rc(Λf 3,!:ZuxYG Đƌ}gAF2a}YM?̿FOۍW iix}[v{ƤrJ_#nZ,Ҭ83;rvh5֦DC^m˧sŌ~IÇ]F_rPF;1?GrBCiEu0 S qxS[&y(EOm)XǖUo[;S78Ã['%9rs783ʂp{H2.KpC(z#^exV\c"h>9!K8$fC|yטxvilROX{F8gK&3ׅr.UqLi3"!+GlըX-jΦpϖA\i7 R!`9ZKO]6T2uc#:ңh'!sB1J&,knY9 2?`3:<\,6z,+ڜ^"^-5/\aWp}Xԃj+nآͧ+1`Z!V wFqezuX!!'ifn%. Ѹ33ИŦ$t3kp +eb6:M `YofEҰJt)x.%XԀ}Ǚ{3Q1^Ħ;|^.[*og>j&]DG BvՒsg95 n-rڑȂLiE Mhc^̝K[A)۔*\p.]&'d⟩8/!}k1~/&TxQTC ȍ<ГZ"D㕰#!.-d gGwmmh[Ř1_f`|/ly ŏp%܃Q,W??2} ^_3:۴,(?[ \Cjcv^BTVNC_kqgkmM*vF}q`Sb,-E+;ED[?yIbxGG+xQFH uJذPntȉ8]Z ~ c*5fcޥ8< N ?B3E9h"~姟eȯaS,c115"jxER_ůx<DTwƛ*ZŖv_@K5 A5ӂ*pҽ?+`s~C?=#Jq0xA0;;3ah@ה ѵJKYr.kI!*ķ@VB(Iu361o k9zpx5j:RqSy )F%imݘ++m\9U[Lm~,H㟐tف~fwHY\FGot}U8X=ˀzd[SGJ$;MhS a`tڛޢ4dڄthHI|{㍯1U8W&a#ҦhX#\y \߄rt-{|F iǘaaL3omH{U0*bW3qM8! C kh cKi5x74xT2ȋ1GT4knjڣdӺ=$}\83;+k% 2e/v׎v:4@]04b{8( "#UE<}x1͕A} .c3~[,0Gf,u̇m Rĭ4bݪ]3uxO[w@Qu}衁 M4g_s9bY̊s91Y,9W;w9Sgf̬_{_{_18Sf窔 OO]NH%h'ºPkgȸ!M)ū;iHHr0^) `9<{(z\Is YƘק0r<^ӄNɓ-[T59rLMVoUjGZ|٭:;WSmhך[qW䜛Gٳt쨊銶xyt)ņaWW"baG|Ϙ3AXe7y汆r,5u,R]FǠFwQ~&k 0[*J{ '6'b]{ ]- 0ǚ^sP{6ۖtTp sZL+~ 3U>+i9dN:.~ ЦFFwaqI<]Yh+AdeehQ]t96{q%#lˑjOv7-W/`L8z˗.CWx2 >s0pf.O`n E zpcY,䇶l?IN]h+%b@V dX1{>bɢCp~_aBG>>xOb)/`b]KŏzVbȑ!&4XϋsQTT#gl%=憆|cOۏRQ~58e??0KfOb3z!>ać i.H/tCoz:@Uj L0ʒٰ]~YŪZ~v{hWKzD.;Pm=uz0)=7e@1 !s aG|Ai!Z'7юܴώ/Zps MźupQZ~D-DjfC\'[:MZ澔W:wk;7v Xk(Aj;kqa9pj=gvQ~^\|&Fls7u4g2>_;N?pd?@5}ZԵ1<|BPRKkqBÃsֿ  ٯ9WQ23O䴞^<j9O6S3"Ѷp3:K] ~}د} Mzj)ƈbl T|uMU#v< Gp|\<#xKҡ# nP ,c=ŗh\_M-luauδmUP`ʨLTJz}Ee*{<pĠUgu^\Қ4;n]=ґVQ6,F=1c ^< }n`§V|ϚӡRs-WHe*+58 MCjv|Oc>\˾P~J׽(傋%wl/Mh_#9b0C^nbAvЙ+=ݩZ ^t0'U2ڂxt ;ʢ uWf\d*([bdT 7'`9W9|:Xa!^Kƃo ^\xv@O=m! W3aGFp5<Ur+=6-Y3\Ȭ*jω~lޕݬ815 dxW1EOb|LUz:)ȥG+i}2TˠLLYWc.7_5cZμAj?`\;.iȬxĢxTLIE[I52X+ ;6dV&^MX:ϾpzCR1y3ⵖ[%g֜"4k/;LsR٭=VW pv9$Ć97a[4؅'SjgxIn*WSnJ5_"+޵oPU&hOW?#X^ O֧n>69VRmg/-앏{SYtW%}8+,x#c[2̿ qsx)~B_2Ғ1~M28^Ccי8s%F *r.]@pAYc%mmL2~t/މ=+#w&OX؍#+9Ą T1*~a\%c̝Hjve6|jG ̬B+=EqH}6܉D3Oj ;h7F9&4H7MCYP;tN7Ȍ8Y3,]N9.M ͣaa356yHY[FYP_n,.a\|Uw G2eV-Ԇi /}3{(v| a+U)[x߈O1_ \mQ+dtoΘ\'8)˝; Ua< Oƚ%XmvOR~cwda!yܔ3yX aIj9(UKlyqu>E bn u'a\GǪ'qa|\rWV1?'bj+?Z6sw G8&Hxo"]Y.?_j8 O',!)9] ៟w ho^ea#s9aÒ7vܿΎcX*We`UsXUps~1t}_h{+eLӌ/[򑧂Nqxs9s@sOs+~Ϭٸa6ed*&"2:C[BϸL@|8VcH}YVP/e&◚ ߯ZT]ͷvA `~mof=D#8̾>`mv NフnKM9EN2 ^%zѺ1pQVXaBa;l! ~i¡kLYÂXS-,AaϨ2?@c0s\]#!mcq[ݎck~iz޺ ̩c)=bJZi;v*0vrrd;{񾝂?\Iri5 Lx+,c(Y8!S*D(h<~:ˌqɸҥUԄl#܁sq +s$+.od =bβD#Nȩ >54NסWFFZe=J J3 A 8AkG *uڼ7bV"҉) ˆɰÑ\] sH-DFAf ²))u8üJw٤֦Z4 "?nc5-8!׆mؚ5V|6Ć)Z͒qẄ́Oez1us%IURWµCn'WMt)tZ i){ (|(Ggbl|zZѰwގҒ ?m󗵸G#lc{'3eAMyu+M13!_N-ǭ)#)f8>?]!Du\Ӿ}%-xN$Kd!|ٺ>`遴Ya q W}Z'iS6}n**hqgmn8%8 ZVRWx.O&35Lq{g aCht/xͿ-]s7A/o͂:jTiO$u8Qn>%)i/Nvmv*%?֗L g\~*°'WBpAyŴ/0m\4Ve1 IH\Ƈ"`w?U@,Ir@vR`| 4EژTC֖pzj97:: 9hngA=? ʉ¼c][DY;Kw]k dH]:)xx۴<='MiX;[ҫ>'Z73D/ه&qrj5>0_?wR_\UkIFh (                                                                                      ^bb]ТM5DF><[G {"ax ZiޭrNSR$m/u|r|VfCu`EЄˢ5Ց~4 ʻYk|i7{}л C)Z_USA֦ 8픛ڈjL-ц,I0i'2- a«װvѷT3D }8l隴k f;_aΊ*RdoɿKi"-qg\4Rw_Oo8 _ָ+۬ ZDqϵ71s9΅%l -ν4Z.0)M{^#=@_HYۚ7"mqsOj.n!yE2fpf$é1vO8s>=T|wh߃ˁT0[*`#)JK;_>V6y ʦPXZN;s5mzފ/k{W`-QxpXҋYݝ%1as4?0ӫ*RZYD.Ù۱zX90;Dx7k+0b)tZ7CRm϶Თ6tnJ#.+AwYY+KG##]DA|:|zVcOP01*7GsE c>b3I|`M+ƑQ{߲@Oxu̮Aǀ; ͮk=aO8=}@ڮ}=Olفu8c93#J02 f񪕂J:X+牜C[󊱷w^#$#~-|VJg@]lbeݭj=k)y)WE^y ~GtSuWftU=%d!&sbIi[+3D!jV"AxOOĩy0P( ! /e&r#7kL4?12xd\S+} 93CKP؀K>ȸ' .npW{[a8̌#+Ynrv^yoθ^]p\A3'*ʇwWqn{k^yiAyknjIt4ҠV4Ҹyڅ7 r Q߽zAڠt $T$}|Ju,è4VNWԻ ~mY~wMt]='ߪ@q7b433Pvɐ4emKykV:3h&ЛIlі6r/֊qe5e͗~bhc^aV\xWE/j wo+߬t~JLWpe95ҧlhҚ=;x,|C{}%6 BPJ9wqB,Ɔe81yƬn1N?pM{շX/KtĈ?fëF\oLʱ1/u6e3:Ѐ 3|Z-qsSYhZֳ窞^\wГ >UWp^2һpI3.Zml؞k&׍jۡfM7weC0SfPE!p#5 Zy̑4zi woQkⱠM"hñ`'a^v=~Vj;Fi9ǧ6+Ub`?9s|,?͆'yg>pS;nH ~Hd 9Ҏ#K&kg=74 6kƓ95 ~Ho#)}DDT,3sd3Gf~|#O43`\xԋq.K5z_7`f #~U~t;oVa]^tdϳ vP+9) =K)+ĵD &g.~ZbRq/)n{{ G 7g#.g V7~ 8[r녹'Z{sw: ac=YӪЦ5Ou(W^nm'}˘6F<<ӄ-B-݊+ˈ>Ʒ?Klf?-+Ϯ iyxƜ{s;/~Ê'#7< yX!$S2e 5_T˱>xÇս1܁V .jǫ0W!}c[x;z11Iw [](>-Mf^Id-V^Swջ _¬/x[:2\b\ЃɃoF9ڝu߫ Ur6nE=sNiʡgoeJַѥVteJgJ>lO{Ke4M`q<rs $w_{#7j%VFL[r!GA;jbycN}aMym/=<4ZFcC7i9[ GzynCOc`CW;c@ à f{_|aqCյ P.mˑ4-V`Xw#6VCdT7KEƱ6(#U~aL/Pc9ڱSOa oTD7v3\UnȆfM8musjgGȭN4 p0'JtW?;nCS42-vO/P6C[&VlԎo]HNpa\#(odK2NՕ گY7w8r_OKH3eC)-#)8'VsAw7/X%W3;C:tLn_'voX$޹0NlC)[Ů_k1*NEa 7SuԆE/8wM>3-}W%` }iI$]MC>ˎujf O;N HԑG9RT:q51t8YD7_3sV~1erB6._+I/;i +vtYۊV16":>%ضјm:ʢa,vL3cNl }F6b}+vY׵.[mMr{NzS^! }x/8@۞<ٕNJntdB/'n:oO}=kڎs>}T LѴLyEA8cjhD󁥨,_0bj gghY9kbbƒ]ja ǹ}?/=hn|f ̛ýyGΫȳA<^'2{G qX/m7SoH3u tIdN72`l!Ϯ@hEZ?zt:-FqHl5{KJ;X|SkB%OC^?7Â?OYko?JߥA^41԰kn7 ؛BUl\S=i|ʃn,g1֎lgb9;81m\Tf/HNi6||}V\މ󰫳,ѐ%?];wQKl4@dđ9|FtvUQ6Ym3'b^?5#/԰7;2~Vl^MͬX܍]ȗO H!fuӀs1̊+zu4;,v6wSWn=kb!Rן^SxUdfhr9  WJݸu' bw(ݸ׃}趫ٺpFhiI1S0-wEZSƷu3UW9}ǂ>ЎZb0-l:}M.Xm}pTum/3'{pŔI-8aQǹYnٓ2ڕ~*N)RMV[ZyS>܅}L9h{YÎ*WqOsgK[4<{L&N4.-(܄A0sCt1ch)|aI e`_6#u&n~O@4l-v,[am ޅ,|ͫ*i0Sk5rZw_bnM4*;|xMhbϩVkŀ<vU9Ҭf]?k,=bs ~8;3nEx=;£κ=nbSH<tID<ܫ0fjFGkĜ[&%{sn+L w3u=d]l=T oNյ\9.xEcyq`KOVd;g[: 4 ^wBOˤNöJCC򴍮WӋ킒̥?Ҁ$!2OsckX &[d|͚/:Amո‡_|GOP3#K_9/&h8 Uҭ Ó]/z^OW*ΎydItc5mY<؉. 8 W(Kb:&RѭmEtex\g%tGJƪ2OAװ9 ĠzLME)h5'fH^zsq7=C!]/qUKz*9+4YG|^x%]Vjw!y1y_M74ܜ_W5y4֓5[?p *T _i>͋aG}x ٭7 BhW8fGWfDh춁:Ҧ]c58Ҍ f)y=d49El]-Pӱ2XK(_hth k} Y>̗F+mgM5nísq;at73.mm&eo'?̖N?A(YFŘͩȰ3V4jVdzfܹ{fa(UބƼÙfO\Y7u0#,45m;FEއb4$ljO=9l;~IW3+.oAF֜לcLd2V(2e͈L( IF0[ϫ_.vbX5<=̓XTM 1C.ښ.A`]3zݎ3fz ndP'&ޜ*.E|fn6x{\wՎ-m1bo_pu}!>>2aKg^ }r' Jq1e/egF9kzZ3nfl, n@sD>B26bMC֞Zӣ~!K\u/k]GqG,됍=sm&jφCFּ"w8gxO/vYᳯntcU7]T)W+·t9a.5J*>y{ldT,c~bI\6BcQ>]8]<9l< 5kЧh-'$ۯґNth1h]_KCHRO,1d#Ɯ`Ɣ2ۄ[v2x;|/08̟75ӭgWqJG֌07}9L;zpymFwaNlɚ/MiMF?|Btm)oZѼ3?4?KN!v6d׺}/{e7̸r &%__0; C2.T592A2=Azh,>7 =NS`NR׋h !j:Gƍ0ah%L)5᏷V,oǡUNV9XC_8BV֭庺W_ a#G~#K+1Y1̽.`D :$p|[DvEw9Ώsa8 3BRB?Mu>XSNd/h걦5 /ϟ6ğ;xWtw_j.GZͶ<Ƈ(^AEgJK)v<;^gbr 8]HC߮Q 4LӾԚB7{[lK?#<\xsk{"ѷ/47f͕)[5a &T_ft`NXVnqYb<.BqKze^+wnPs,۵Rq7:zXkoI0^eIeVzUXބ(y#WI4"w.[Wn3fs=y'h|‹ _:sV[a +:oʓ/Q; F4Q}^ n*ECL\&iE0~V#,v|E_؛~ea6ָ4+[z<º;TufcuP=fhx27֗Zc}9~\1‹hӅٰ#/gi'ڸE|eE خ {>Veyx_qt!9߄?+Jxf,8cp54Qc[,t`;r')&<4Pܗij}N[dp^_-ͬ.ȝüc'd]ۭ]3Qq#-Mau ,y9EvnS-ۺӨҍ{v]=|]R=mWOKNXd]טG+:TD~:ܩAǀ1*V`2}>cH2[UI pW7o&&dƥlt*@Ш*c֋\5bj ]>ͻr}?V9'qH{_Jn>'|qjGGnvp'ݴYc"]QۅJEdݫN"T1GGkO#gΆ]lx gjJ)!)]ȒVlEcѿ%ZfF[ndlBFYObGl:OØJ4t*krl؏j}ܘeE#Ub5ִ~HM۪ꥊxs`OS~u5 wz2 Q3f^3f4}ljƜmSa87jU}n 8-\+xҐO0F=4bE/S21 dalQ+ XҘ' z%!l ߮ˣ]jvK.Mw}_\îэ'K߻@JnYo #Fv4ILhmO' xbףּwak%-uQ1EEV,lDPTL TD9̜3gs~_<3=, U{I=S^HpEp>57{+3aR{]v %^)^yGiv*Ќ_M8 ڜZ<ڐtb(n`9ĜmhN;flbSih)pKޡeZt1+l?ۜ',p5(-NJ`4#ls02zܷWmKq73O uΜQBg=Sq%MTXT2Z ?7(@ES1߯O|'sGI*V@ɾBXduS,`UUq-";DO0|mj]F hckY4`pA~w3tJf#=6oN' btf8=`O6]+5QzY'1ֹqs.Ӏ5Ƥ3i-2%#əNӕ\F/}r*6/" veoW^HCO7.hϥ,9%' `WSF17b|$d~Fn;ekQ$sMyUi|g S]f1z ­FvҪ.O?֡qg-[ฺ ΕC쓍~F4i526{N}d!`wTl+Y`9J^PaAlxv3MS1Wd|W Ws{Vȹ36d녘jFbп1;՝"ˠh|B8;i/}1~6Ӊk!CDȮb)}h;ڑ2eͱZ$ǾYpZ`e%=b@f4nțLwg\g6Uw6M8v2)=S%puEvOBl7ޯ2{%ۙr@j81cP+G3u'!|&Tfbx)Ou6zŘWQ/CZ6)orìPڮioV xu'myrLJcoFhk^Bk(_Z'* Cj7u\dڛt],1돹s{ G+2LN'aMoQhߗPךO{5e'~X% Z0gkyYX- C1!z\B>p'ýr!~{pp 3ٚy+~Jp9`1/}g ͻY~g),B7Ya9#NJ×r;p '^rry;zsiIx1-Ŝh.|<؝XQ̆)w\->.e \ ¾g7x6}ߡ& 6N3b@]6=Z <”'* ᅣE 8<Xoޡ/ /o0کͥbT\檢jlzŠl LUXz՜p(?ЪtVdT>CF![L0ޛ4>hoȿXrE>fW!.e*t3fA]ݘYG402Pp%w+9cA}4AosC1:9SELa2^t1)eMTr ˣn̴p8tnHKhوsL+c0zt}Y*+h֗hp>@*]ʷk MNy1oaDlzǯɗҤG=XmgQoapc >xp%3\D[ep6do&}QP"'/{0񦒗 dd'JSœtxIϳ8G$rX`D<ǎ#`7Ą XWbL6; 9^nbX<^s.3Au>>z+0Ik&p"X"3ˆ+F wndcV9/Ofp7.P3_Jy; ^6sVn95 W1%|CIl&%;z=T8[>;{ NQ:`'ĆX<۟#e uJ7 x|6qt:gLw?03 ǏYͷ@9W(NEvwoKrn(]ԴRqHiլsHfmO0`k=oI-[s0L,q^գU.'=fh@ߐtlWnh?g߾5ˆq-v:{o- G1ܙ[]y7pm'Z,>YB;# cK$ E)wm9#F(hmbd%WR񧭚'\Hs6<VK\dZ)fQΔ0bbHܓ!3x:QBo|_qxRw|pG ^^]:(F­\ ޝsr(صZjѩ~F#FщzCaW=+j1R]cS \tB^i:"^"z~?az0ԀZV\= JJ)X!luFߑsVl-RC뿛HSFm<7V@7v]vx7(S:w;K~i8K.}^G|3(ҡŚa)p}*lhV? t*7zmdrfrQ%bϭK# +͸%زMG:mA 9wᢩt rןe`M+Vֈv;DӕÌH%e19?q\ !GtT]:\wUQ:_ĮN _°(6 7Avj Fȓ 4aWrik\dG[S\=|-}ܝWe\zKƦk|$d % %5;s D\̚3tG f~GB -C6:%է-ilf߯uypr6F"ٟ͙.Njc,ƾr ǕcGu\~Lf<\= u;X10߆GkWVph)7 .JSJ2Wm֝3F݁f[R{#c˘`g#9U$lw$m6,՘]zϑ+dz> >?Ґ365C''X=ra<79fr4p8^3kFkzuY!ܷJ4f 8:Nzte0c:ԦU7xoƣ[2bb)|~B^&Ι/8@Q*U'~+8V6% >5q' YfY[9ljy"TΪw<fH; :NN+RNh-+J/?^ qSSs*q9SE_`ž,YÊ},|17bIL46ǘA=)O܎r/3_:LJd RCKp1Nԕէ#&,ùZW_~{)̟U`B_]|nkLœV3ԞrQ- P2#CȾr~ X% ܮf}gN{%WCbmCv* $L #:-CY{0z{[>`l( o}_Qi,Ul]w#Bױ6[0moiEu]n(r;^x~|Y}QsV\qĆL9.U`,?~"{5NJÏHA`#6pL9{S0S(VpyUܠdg}d̛AQ'oTKD* /W3 mݣ%,=,9"'Y2@ŠuڦMkqGgӿȂZ|t߆6ZEI'E}BD\ nۋA˰6R[=>lcOZ _70.F_05jJo+BҨ*$gcFYzޯÝ\dʸvRޢ}Q󭉊*>^TW)NIOK#y;$uZpi#3_!3]>=$31RK62U0C\oTZLgceVM@Ǎ{`j&u &--{㎋3L˄:/gc)n(\^-+F]عъ8ꍚyjnvKye5r>-􊌯e!*)X  G>1ftKfdUZbf{1Iz=|ΘS=7'E{Nq|aF&l7[[_k-x=YC0f䊶MM![+u䥞Ȍqea>>K -^mSֹw•_ZQu9_w#{vwrgk_9S C͓nry/=O$}g]26a[h>fh 6uG8Ӕ=qj!Z/*ACi}m-uW )?S./tdh5$JZr-1Wxh*r"OL)T[Qr@0Rʶd/μ}ӎ+vZph|`ciKV'6v`W,wco1\yz5/`7ӴBϱϹCaJO,X~Yӵxw)'Zy[d==>&"k6ݒh„dCB VQnHETW *涕RU`*0S\ˋ߃_`b#Ч9X\J?*^J-%džH+(5J|N`韆p[%jtQi-ش-~7jM+Ȋ Os=E&kl5˸.q#oN3g~kɥ& .y *D ->mʎvT%[11׆92Fmeѕvx'/-V^ B~Or\)n~K_ɸy}1UqV}DF:1wn9w8j Ϟe;2څmΤ0COUƀ@)#۳UN0b]5,cO7Fγu<}%]ۆalކ?wq|az2~]\ۙz;Q́V!cv{/WUchn\4ʒ֙μ_N{9vRVz,G\)yWÇΘ;V|Vq_߁`Mb)rI,6#1>7i8jsC9k{rG'n>nO{ujrqs\,݂Ɵ5gdoG:{&,N|Gت2&T%,Ĝ߰n{\W*l<)2_C1ߎd`5۩?REp)YZ'bn;MYeTf δ/bXn]%>,%ts 93$lzݎM̸/T`%fxy+ ٙ8͈:- @x) a=: I^6܁ BN"XG@NƉi)uJC8UXR<Ѭ̖Ív!)hVͱyd]k>N3u4F|Emn`g<ŝG8гʀR}@P/`8oS V .R~r9|6dp={ ۪ײTtŴ8On漮bƬ1ꚐTTT痜[Z1t瓠żRFOr:9 J{.΁-9ИnjW)tgCB/aGf|cA)֌3g4戎Boaxz +nFkknhE\?!7B$]n~1E-УWv.:rXT`ja$p | ߱|-o'er%[yS[/.%xR*ipA:24Z ÷Y)V')}~``0Fn؞ zOG8":slmdEPg="go _8k+kvcåy3}9貲m!scW_uZʍ~!C5O$qg8>-ZYzנ<CtXjJ+U59v?I3XVUUW*BX9E|̈́އ"|U4َfl~kž/l==# =ovp2^+c -9ggKm'd  ř|рn1< ~gaA"cs K|1E߿m(xjd]tV&""d- ,y ؈+`W&bgtxڙ dUc 9nM9Ke˱A.ilŇ'f3lomyރ?1J{fJ) 0טrb V7a!>9AMC{:O! wBrt&~5|jR5w`۽Dɖ51*ګ)J>捻Q/5OQs7F[r:#0zXb}ؿqTbʼ})xƤ[r%5b:82VFcFtcDŽ iǕ-+̈G.hѧ {\8ڴCv@e&, E%#N^PsɃaɄ^,pdӎ*`f?J+vI]4B}av.ehlk3cu">^@-w.3hD D+nue<;kcEO1裿'`jj"qp=Űc%c;T؛q缦&v9 uɄ۰7V!$)8 |HGU<#s.F3\W6ڤ#o7=Pk4Y`K7ݷyp//*~;'籑 TKtŽs=ʐYo x;QEتCepb]t}|3Lyfhd_kaѷ^p<<Ѵ1G%@j_}T#>7K#hô|-fkprFf 8( SFOU@sY~,x‰KOy?t=Վ^T<=ا'Qol7h[ ع' g] CL'#+cno:OZv-#q+'v⮟8n (ٴiO܍s[-=ΜPTL鑃'?CU!> WFV"&^GlLzY^ql*jCl]Sc0L/- |Y 4[0 h^CT}u:W/4zrO&Ck$Ԣ˨ @uCff='y=x ~ * U3<(mzz0Ω(iUK8f|Lgtn0>=)a89浯b~ uj?w1n/0c%0n8Or^C'&{5ѥqzz*~jMd8ŠgG;Ь҉Er(rZR:S1^h$oǎ)8ӾXzbb`*nw_,'=#=~xEʔbfUS~bϘqoaD1fCx5gsO DmY(9>w NJuO|}jdv1D^1.a2 0S-y|.'ӥלxm.-ZlCA/pk CslhZ+bd#TO4ȸid+̲j =}'+]% ;əIņ |d%;d*uQ3-'_.be;ᯠho7 :Ǡv1pQv>B$(@Ns<8d'$xrg|]6;e+ -8T A{"t;ĬCQ蘵fcl z/ؽ;j{eaQr&ʦl,Y r}ʐ a c4E҂5mǘ) 3\>.Hj!Y1V /C^O+U :2bZlqDqgCFCہιq{ol V<3tVr\Qb5dhĖǶaa 9xvnREvl\+ 荨Ly+LF9 +វ9zr$wv'ݹ}xǴεViVy ltdBUlC.l힬ٮ[6՜_A禿TE]V2k+BV`sc^0qFXbie ,C.MW1>{sGomŗ֞<9=q<}7ˁwi8U = 8?קXuMtĮY9ַA L?g`]>j\~yt Q.Ci+b tѝ+qjF:]8{:NO$}D/ܤbwlz7a^XWaQ] >hVZloUČg$BT򱑊o*Xdd %^+X>CAelߟ"3`zL/ A:# `<<0ZCv|3-j9缔'ivWRm%ˇȹDKbZ3ꛄ]ΉEĖEn-B%,( IOV KLT5X7]|J9"r!U%h^XKX[(#r ^?*WpS}/cR6 1h=L |m'A]|A<">uIX%hBA_s1 78ڦ]Dο =[3>4 9DE >*c)_ ZI f%ou!Tl[m3px"X|`vOƱSq53p/v,f}1o#\R[lɋm5fem M):2@2$ q88%ǷgaS|ŔMˍ>(M&8^ɣ +l9 } s"~}9rΒbEDa}9lH`2Lw3Q s%'}1jRq~92g)K9Kxޝ! NeMĜ*e[8"SGJݯO%/+ d[ T $xp$wu > '10mu2! Q['!b rm&Oŵ󠬛#۹0w=rH0^L8ۘF\hEU ᷂T,䚑S3Gx` T;f6~uq$ 5rC܇ZrB#w.sFv̆eYL:]g?!e+4}ޝ[UQbcN!C= Ȳ`޼ ;0s00یi tgˌYD(tA`J{'s2v8)2^(聐G|WuG|2Ow!|ΛĬ:.+Ozg`Эk82Amb1?|닙}q ߴ0ԧ{ B1)'S22֋IVr/&+=?Nau*G/%}guS2w[TKʄn|ߙ2`{ncj!Sџ&3̄OSgJ\3fn4O1偵ո_ Ưxk}0ᗼ]pj{g͝;JΎR2_KBG_5ioS8R˕HS\UT Pʓbp8m݆+i+\ 3$\WeTu1P$cF(Pɼ89K Y#羝 ( t}N>+ːˢM9wC5/De|tq-C[:bŶawr25RQZ3엠fiNBBBn,t+ThA :Jٮ3xМ>U}Wi/ ֹ(ڥ<g̦0ll a Zbm_L_:>ce^6Θ&tͳR.zc,(p;QˆӤ3젴~4ՂVֵ 亽 2-XF?.S0aFT=v5lja8ROKg2ag#W$0ݴ,Wrz+.șvN-¦XhtסiE͋5C2H(`y ,_XO'/&R@O:/rhy' /$A-aF"f#T2us M=IR G +;%& S`Y4Ç'FJo Y:@́ omYMtBcvuf G;<'dqȚ;\w|licIRPb<7Ho^|$r&s!GFZWY mG mˣq6>LOɹ+]%k\Ð\;,Rl$ ` NJd[ڣk%TG+)8":ΤAk2ߝz&9ԴgFStLNyB58/,ƁԊӝIzQ3eBsypτkxV>M- kkg[dwWᲫ.un*W$gfC7OwI 0q=6b`O o8 WZoZ5W#ޛEȞƹu?V,/mAK;RoH<"Yll z֌iaSb8Rl"qgc}k@NUv/Ʋh.|KEB:͈—FKvBihMuB['$rF 8a,W zfil7}TxIF%vV0; Hb |x(Cl,zm $XaM+,8fޜ3]MU'rSig;u9Dd~s}LoP Gvw:2:^yH2_`@>67cg*λl5N6.:^E^=A8vD) ln[;,ῥ"Q2ʲ,so2=|| ŤP+<2K MxXք([< 6vƈQ~a.vMxeoq0팽~.o3lt}?W: pbhÀb5U`1Ү dZ whB:b=m3y Y;I C8`zpA Zv.4Ph:0?\?ޫ!f?v+Zf.X3}ߪ $@>Q$$IwD5Y&PF068 Qƒ߶H y);tDWغj'gzêa>.h |ₓ &8RÑaQ>ՈtphD~7B(]i ,#Ÿ.RXĉPE^(!Z`y,̨0&l/qrE#WҾgͿWV-%63nO~,|'ٗHet[--^@hkj{1_( &hC="L`-wf͇2skh;Sdgd] 0v Z+68eoWj1vrKPbz#^N& 6W`V8mSXXyA YƠ7\_EFGW#3} {a\KU#C.)>(@x쑠3>nkin4G/]o[}_&G$6DЌWlxH> ۣi2 9ax6Cg#9bĺ#nq+&lbFV Q#|`a"OR `e8m|k\7pj'+gDdbtGYE2R r {N%Bd>:ޝ"n>٘ k)ש.~!UJXk{Z!.1P|ozv$OBR(%~ 4* }#L,,Zh\lX# ^9#qYFj3+d5^5p* t:}_j^0w.bC ]41F>~4(kŔ2Q04l%F-{Ò&"ܻ"Ay9Z)pبDz&=RcH_pvZCwLh#W  Z`a/C(ba+n1` rGh19,'Q'e9#qY)\9W*V fa 5s Р8E=ȐW!Y<8.5$4;+oB/N0o3ogm6מ7N=K&.,znumx+g١q+)| Q\vEw'48rL J1ҵvQ4s(}I 7wn_w= '밍u'5ùG:Sicep)m -0[N"q?*Z1hBL= k)إk!0}#Mv|aֵ֙8Xҽ=zmlٹ.51rk3h|]NKkZD6y/,!|Qn|/iY_l\~?]ͭ/N2;gEӝ>TSD=Y߲`_; ?ź!nan U7)/7A<g2Xe$#@$>OňrSCd; _wO{3v_%+Ei~RM+=0IE* lԙ o$*O)0ԓwaJ-*lX4<+hYGg4luGSxU{[Fyd\k>ЫqY~SBXMk+]l ͼeq ~HXnxx$d1B[h2.~;d;*C\Q팾qzN-‡h.נMo-za^F*'2#|^h,K>WDc?B( LbUuɟӲg6|;t$f(^~G"aX39N@ g=RaN=ʘ5{5wёT;On_+aL>XT~:ė)6B yA'yd.iF/)k`J3ܣ;'^{4,-JdjX;0E&Ei2&*.Ǎ-V^qZ*Vc4&wh_pK bhW=5>C?'ѹ>tS)9GX 9 zr1/ħNRTTA[9*XV aG %V]Ƚo7q/VхQ=TOmk=fjXme >SJxe^!hҬ3y+khv1|RBXCZ#o/;KDϣ!k, 9ˀƈcg ,*/2Be~&||١2ܔВr$e16H-@:ںj2gC:[洲I%9'~Qg(6Nkfnoԩ"ΰ5e|+>j}EhL aJXy*^FUg ~O55vjƋ:TN&<:l_apk8,~M}G c1=mN y̹QbN)RgfZbZ!c9=O'_1lDCi>'to[@ ZSl=>H`%E Mq%oB~aXvAαmcZx=L:eS8Z.Υev)iiϾ 8Cf2u-mђqߡJ:8O?̠n4dz?tzO*V#Ie)VݵKa#'^+HʤOka%wl_k2J CWO(vPa]ffI}W;\.}gm^Y۞WIitKr6eT>^0޻haqE.&l#V.S@NC3Q:Vp?Wrrf-j09F׃ 01@QayG5h,mMQ[W6΢ \a!,2,wa29F33ff)]Fќٷ$yE)~L&CL?&OK6>[ fpv=VҌvAtyoKrU!x|j?M<ܽH?OH'_n: ff%03u8>PjNK>&3rapAru#9#}jOm J_d!PoB $00^nci/֝[ev ^ӝny$V}>R%tP5?j&6lR oOm'[ W3^I;%^%o)1FɎX=O! tD^_~8X;=1>Z")бPz."L54 $ӆ@2m|JC|h daX!RA\$Mk-nL˂s=LO~AK׽& ?J)J!둕yl;XγCgKҖWӦÕ2.>E-V(S=O :,NhJQM,}/6]LMip"|?H:ֳ̉~Ru)P25Ho%Est9piOb!\dn[|c9VL_ "%->.jW2Kq_+7苳Ո`<`B%0ܔ X"EI M=QBEP[Kp(z*^pE/%V;_LnOc@$jSIA2 .c؈sbm {p̛ =r P.o1,OK1^I\-si/%(NdO5ohQ{s_GtFL㈪<R_'R4rȡ҉4t![7g$%h"mXDJ,%Ӌ+C(U#f!ň ;Dai)|doCME؈UK˶Pdn6WY\lcc\b<`.UG3HpXyYUrb\ R`-hEVU\ԮL.?r]ٯU!A"E. 4sBwZG(qʳ$xX.‚J=VexsZ߹< |h<=3tIycy0JO_Qw9}RBar), '\GskowQt1بB@wnzj KRY4w2l}IS?G?mtj^Hn'+)9ְή&sGzU VoUN(Q6ZύbtKqG>VQPa3F`/2>] 9*B|)Ĵ#Rlgž1lUV-`yܯQ97_HS ?Exŧ?vh䣳? ͸4PY)[ssA f`$9Z2^KTX,2h 4[nj bw-13kJ!#9+R[(`*B^ wTO*Σ n@4M>5+c X^AUiׂhKqzewV$߹ө#ua}ydCss>> h2I"!0\|`v2[lEKXζ´5tKY_o͌4;?~ S<-CR@PsyHÂBx7F6/f K%;YoJEmzw `AM 4Xb 36G(7\OKJW[Gl *9M z,BZwr NA{~k,d_DB[Uqps9X,\'0{TMX́7_X=W#~C*6ɑ;Z EMS=6o` -%2`҈U1jLtca5ZA& FlIO.fgg*ph /iKF 9Wol@/ggҟe5ki 춫'*j.yTnAEFHDۨoPIE{_G_N-#"ԱxM 1R.FJg.bQ[`X+Lfc E2:;.w|ES?Ii;7M~J!-ipg :~t( Z߳k lO\r$F4!J $]c^~!Njdˌ(匾]aavj]ĺ2+2֌L!z z^&1 @ B,53 Seu*?]S{d*6?ڡs")[!CEXwBW [+DZb(!<Zɡl툠d`5uKW'1dv ޼`w5p>\ ~&V%\D7G;sQ͢*YF[Y4WS7uvfT+Y$Eҟ$z29T iR*T\+zK)uR@C$R~A(m{^?A<'`G\M]Sw'6MwHQEY^ƫ(a4gLښE{:'ӨMo+R~%oU`M5~Ga 3' fP"~7Tq ̞+LoRnehV.B\`W6DhY:=iN٠&Nv*j$  dߋɑmwe[#M'B4ĭ`xVGv&DM/oYe6fG*>V e3L$[!VZDXO%8^'% Ҡu#ma`s lzT0 2-B~_)f#ɖa[֏#@HOڀ_iNz>-FaԳ[)oY@ɡ>9JՑF4]Dg^҇9(3m]ϥ4}~5l{@6\TAՇέŹǼllzϷG'6yW5RT0p!S,ͫ#"0'u?C)o4me39]naAy!V=?nQtΣN+Ph[IG,1Э`[9ʱn|4/)χ]B\∫gCd=&؄aGagg8E)fpN C<l\>ʱ礐OU`F):ub~ ͅKs訯j{d Nk'4"$}񏢐y>ڄP']Qok3cUɴObEJq&LCoR ]u=@ J}FL{a>;4]XHR[ln.Q=.ܞ,}jK]X2};)6]J!ɰRjYGehӗ~R+A-[|^B>Rdz3 u쩣-l&b\8"8cf 5bE?MN{)qiA)MؙՄ$#:0N}/.:`-0Rܞ'eOk)q┐Vp@UI^Wˣ/l2?EhŒ#SG=n?⃔SH5 +@!v |9‘2ż&zit@Cgs E0W i 'xr XK(-p2|{o7iϨ3f,OMӈ2ބ֧؟ԦhE4qsJ(t w# d1.ZV+o)o7;1c~8|3/3.֐T{\fv]迉9%{NU6LlZ6g;8#a4#5=LKs)_B_XQ6FOxH*@mT0 12C?Uɸz+ <`zznnǮz&]e8 Og8JOi@XrflA8|yU$I~GSʏB;(ez=1.hHVoÜ '8{ zv  Nӂ qB0qBI&NAYAI%rα*Fi=~ 6mH, N1s=}_NB2'=ĸP"4q8Bd^ RڡCk ef#ȍ[ 8)>Tq1x"4+b< W~k%C,{,ȰédFрK!]n>:>|OֹePߴIB9POX9rfii[kp#QVǜQTYbݹ|HV~'4:R3VU8W{\,İ<%:`ON1|g4{.'B}=\/f]=vFq* "uJfV6*\]E[蚱pcV&=1K5T8DO̠I}R"a >_eP\ 6M;č$0qwwwwq!n]ȊB  8ws}~[ug39TW1p:sҤJN(W1k7gRkWa̠24v({1\ ɡ;+s&s 8j![kraѮZe[9 *THRU\9ю*-Yo#+81ςX%?޷fA9cذ_ȸ͔>f qh*_51<d(6C|Ƃ(X \d a&=8MOh(t+y?Ռ[r$ 4StΚ= yI"9z6c>\BRJi&POtiZ.oƈn-R^983ozI_0*'CK1 XjWFl*=h\#^-0.7`h%ʠ,ݿGvg0˃Zzjn%|Ff}z_^׹BF;0t!Wrt~S^_gYi[m!6 <%ZC*/rTNW+tyIg2_W' U*tPi'5k?bgħB}?hH/jW㑨ߗ"&jPI-ʡ:xs'ڲFՎf#/:#':9Pu=#l:F6a!%ӭ/pp|y/ #9RuuF,g#樂^ ȸ{Rp;_We,i0R/4azs3r)m5oӦ4P}dk1O]ԭ |ZۣyH51:d];)dƌ,e%HjUn hcBaZ| /K+ʩp%&$)C5Ul7h+րk2K.D#: _|?z8*i J?\(ځB眢#ϝ~JES:I8.wE)j%^M-iJW9hƝ YJ5p+BW.B_; #qm0~Aau.V5㲑{0ઍj,!fK *:kqviqT1stmςLq.N,.p,Zstd͙|P]Zq I6#l8:'tQC>a<. S0vE;{+{} =gM39+--%ڊW,':RULLHr8->i3a60C͘$c2w/:'vUJE/Axss'~rWGՙ)uޏTcmߨQe dkp%ݭ *߭ac&wLv̀B2<}zOe5:ڮRpG;@<8Y`xI3΅)pkH+rP;JTUx\=[̔GJWZ|DԘsHۿ 9[&F{0R!IUf P'Z<#d7*9K}ո\8~kth"dm\VtU<0:3 kG+4xM h;O=0j+vƣ#a:)ƶVKq-r1c8ܜ{9 o;BN2&U"Cz- cā͒Oߒ,[25=Dp75(I(tk!6ipzzO:5இSUaz@$K!b\<4=Tyn٘$mw'5;&afoh*Jt]#zvLɳ9.?Raw> jE+ViX|o| XSu܎h=aϓa7$7ˡlшgPŀͩ&lӖ#b#ƂVPjAyUZ3`Sjb ];5 Z[k}<ߩrr.P_F9k< P[ Yʤ#6[wj+.Ouwf Gp|цnFeXp+OBX703BaU'-G#HaGvi?dXiSe/#em9 .[15{bF%_3lY%VzhsڠΦ *\q݈rH-`P!zFÆ_'"8QMoḥV:.jq9mh{ xU*P3&&Tƅ sE=o~oQ>.dS{#:(7տ!ì 7\V\mn!cv/a$cemX)ew}7Lr&a(w! w>EKLq#+,ڻj<&2H $6WNJݪ8*{6Kj!TĎ9ˑނ fPm0 1cdfw/퉊p_{codk~(Cb6nag`i5H8'xنWZH[>nTP ux1KjRo#h,mJ%3Ut4_/i)7V  %~`cjla7.FJqb z%ZW".Upt}e+i:]) И=R!70p,/g"pAo(k~r/myx7J'AX+J봠ͱZ̲; Ĕ.QlߝPdyf(󆿈^%rj*b9X~+ 1'TMKoϩANI(3֐jrv*s5h5 j>gXP53ro;N䍕|ܐBtش\ѡ?E5ŏXsbyV܄+(6ĭ8]Drb),~ϛZ1P__Xeշ6CV\*G͂U W!Y׼D̸[Ne8q_/h5-Nksj g:U)(sWe)1D& ogm;Й{<ʂ'6Sk7U啗 z}u0 bECh1x/ŕ˳QrEa`B%DT,Ke3~ -;]fdgJ)"uSd9+4xQ$Pcjd;̘:6d=I/ՉH4ƴ"ǩcJQZ\GF|Ʒ*)t/2^`ޡ얢vfZBQ*E(R㏺н4i~EVA5 /no>n h - 3 Y_u36- -cfv$d8.|BHL֏G -GاM( Pbnz-:טV|c!2Fejp&uȌ>YǙ˜ʖ?xi6kirn)Kx笐9"W5,nwÊg>0}2Ng95 .6o?e`O9㩁<j|*gu9,Ѐu&|؂Z!]59 /U))FZ\^)dtg±Kh=_CD lw|[ū8o }/x,^2V Xw_SO6 c#1Rr|{eͿcL8 Ңk 6S.f&j̫1AC xdw=GGݘ2)#zYVP?ꍁߺbGah>dA_&W-"uSUb~ ѠVgh#􁥯XjJZ<%Uh"⋳*,V Ta|l{ ༔ߕՌ*'c/^l"?!<.خ_R >eCH7G(kE5!?>]F#lZ^X,ghF lNMxNe*qUBh ,,l0NBNt| ؗ8">8&.:|9SLxp++6fη׶ cDr ^si0KrIηEj&ŸxuFN!,ݎ_:cVE0G&vp;N` UAj++R&-ԨQe:}ݜrV m?Uej.Rl>?c1]v.uj$(%ص;Mm ϳ+ݎ_Ӑ;ƴF])P%61:+ss#+2d 3PLT˪0l1"&cJ fl)/b. 9݂OA 90{;eX-wme&szV "B+ sz-xLO EvS1EEvL)Hv6jq/FmGLKd:7CݱLz>eʩVdy)&S')8AމIᰌ Ϙ-4|T7u~ʏ9O.x/E^,Xkt1 ?{9x ؽ9 IminI JZLUgʻ2jc/0HmWs, {Gl_ sG6pv^M`@l#,<@K$|4^E=|DjY $ =qbIU.s;*ՠR!6I%aH\(6!H+T.)AO3~̀J5a;hޙ|pׁkXbfMKF0WȏB̮3kU[lE\̃FZ1+W?gpy)=>e1X]P~e|m\AֽOOȱKAS˧*3Eeiơ:Jmgs)QrA:nS_e<6JJrT-Eo:mӠ v 38)ت"4Nba,UO avF9;@#X?:`u A'lI>G}dV^k,(;t: DY\v_{r>7OUt)G'e|GEBWςU-]t܊DBڗCU5e!_"y>Рraɾ vt4o̅,Ӎ QR3}?Ktc%zuqOenW洵MpW1߫q+̘uXtvhqdC?^1|4^ǸEj*GuX aNNM7)ys+x񩌝- n&QaIޏ0&CypŜ#z0IWwl[^y81S?aĉ[ (σb ' }tn{ϻ|XK1J-叙ZkVq&d|kO}h?ml~rLӧe/;B󃈏Eb6hi["+g!o+CכscMsLthS)c#U#U}ũЭ2ݒa`ߧy+(X-_i9~ \?օcZ񀥌k1uTeE|V SG%*OQ.^ 4#}W4ŀ~ ծɆ" gFoә.ؔn{#; o# BXJngB1Ao^S\ǚom=/U+jEvX\>q/\B_L14j0WUJ -.Bz-P-&C;.@ir->.o6A@ĶZ"DwSq۽}O~(YYcS3׌_mj7Ö;:Ԉ#kqeZmDEn%TAkƯa0vH}&rmp ^]hє R^ǑݘӍr 0ekD'SB翦M3Fz/8J݄LlzbEؒ729Dznr|J]{;G#*v j lyX!Eh<ȳ"T;JURxG\6f#lɊ^yQF?/-$Hxaꌿ{Q\VSk=`֑P@P S9Zk0q&-iPR>{}(r*j<7fr~ջueJ6S܍;||J _I_4XIsC)RXQu9o3ٞ5v\Æ?4crƌ@+^)ǽ= :i箑u-b.tֹNxJ@OvwfKS4snMh(Ϻy~oa6_•8EoQz 'pUޙT}8!z\_uߵZ\zr -ŕkZ.H nr!k?Z˜)BC0@s+g=X~̌ٯ.;z\M~emι 4p-?0&۶༕5ϴZ1")AEl񹲈GV-T=CʿJA|n鿍-1ޟn39櫪&kfHMDXX"f6)=K1դBjǼ6`l3Ƌ25x3 haVlOWeaכi3MQ>0On"J1x B!{z\NŮ_7FN X @:'}~'QeRX C>M@X^TyV*G(LLÊc>i*Nz M"u Ve'QfrN #x 86Ғpl[>:v ;pml#Ϛ66ޒ9Ʉ۽̸a5={pq;^˞=L3 (paVLϠj݊.ex[*w_J)1R=4ȥzmÊNȃΜmDY{lwbRgrRṦeY`Ia|2P6/&he Nmkњdޒa g[- X#h_I_u4c}v;3H+q\}*g0ܕ d=wpcgY+faRʨ|G/A46&7;?Ǔ4 *An'\NBqɁh |ǫƤ垮-W :/8wa+)GrdhG"7)VW#w.:l`)^VI'.q:SщΜυo:g{*vspcA/2W>X{rdI'.@E:`w9&ّ0מs x1}E|?€CpΧn,qoGٝ7\\U8ԅ9Qy;>z;OɻO]窍b.t^s,܄SX+J5 -k`٭#FX< ):xR@nCSKmؒ8{:ʕ|bI}];>؟4z)\9ÍDŽ^щ)[8RS˚N a%ψY$ q ]Z2poi ^p77sI'vnǖ)iB&pg@w!_:EK^sL+7ԃ\ܝw*Lpep7qef7΋w/9 sz0_Ň\3ъMػ؜m9 }`t;w {~[w{k{&oǒy =yȝ;ko{jE8r]w ~d͓}ִ,7ie/qu斓| +kc?H :Z Wkَ{DžtNjǾW%ILI9_/v!ܧTb:.Zz+-thnHDHtߜw~ [yi5b;k}pwm3YJ4xua[X}/Gng~AGrZu߹OBxW`3Ucjkr,=bO&ٻ;O;}WNMt凫s˙N,8'~qr;;1]8|GGFQ#߷we(woU:pu;x׭=3keG:u߻_rXG.t'7st';!6Ӆbg~Osn/t!?$4n<;}aWjd +nq![9XݑUEQ^({-z>U"Z Tb .XP81;Ф_|<|*{B'o N:dgG8'މ*_<FGNBǮޙ;\i0Ãמ ;Pi;^I};Of䖈vW^3j;[ϻ 0x;uaV-scE }NŅ݃=op7newʇׇY%x[.l43ā3iЙ;r2GqF2{iD&;e!Ë_0sG RoIg%e_%W9ޞ,Ǵ|o+056P=vㅾa\(rcd?<' U%w'4!!7W"n@tB$+4 !a("YUj$z\Ɣ^.LǎϑG{zY߃>4ŕQ޿BG>Wp^.AQnL#ݹHQ \9%ԓ ~֓˓=9K&;3\ݻ39Ϛ]B8v.-qٴă-'&y2'߇1 ߙuw;;Zu.wn%(S=W2O *+ߑ ]ىaN|Չq;2uwҢ> }޷J\0>#DAuc XHI8Iix5 җ`6+G)7x{מi*wnoذ6Rl OS~tysQ"$G~ÍXTce؜||YֱWChk4"0G.>7KRߘuR&bg%7hr+ Nl%FtƋMvn !(8qGv]ʹg۱[cκdnIM\sڍZ]qoXSξJ1]~C$,դ\J-ِ%δsh7Z/jOڃ/ػ .]'x t?Oݕ!!'%,CpԽs9uMF_U&^ZO wf+Do6POd'wnDqԗ{pS3Z;_ɵ.rg:g6btV:H[YnjiX-Iou&FPy*lcAY;h. 5՛ Cɼ V͍v XfXv݁ ގf9μ$^t>s wBeyK_bjM =eQ0w2 hF N%ohUӠD|LAmB:vۦa(9^PM"B2VnQDZɟO(=pa4":t1jc w"gU vAP%:-)t(wLV_HWϕw9m4,[=`nyՓ zq5/z#GǸ3ʋ|871͏F':Q#ƓUe*bc_2HL F}Ġ XkE<:Gd ѵKvwę/^׍wdYd7+dCAW ^< w&;Pى]y[۳*'_sc~wnIwc;oF}pb3pb^#۷s6l]m}<gEg=6lSfNc vOGtT9(.E |XWO=?ِX ΔJ#'4[[hX)אWk>%W!iw'*Wx* }@&ԙ|l)G<蘈p=QuJւ57zN8q%[aP2Nk17 ky>U`mNC];y|'kybwx';InuhGװh{%=͖;Yqdkvgz[S~է74WQ:_i8s<gBNI5HLxyz;Xx+ȕ~l4Kİw]5۫^su%ֹҭ@<Sebdm*T.AR X bI;Jcr*VkkޒFGܜ7c>>o6r/ Wn\FN1R+d˷]m`i˞6Veh u;P1n0|Rat11cHϱ`[ʿóܫoϥxlh~uZ-wvL7:9kli)(&9pG;0{ak,yۊBlչLɳQٟZU]+9١MiU0h /<DzsחG;1'2}8ʃi'5継fW,XE#.$5} y#ءyG1>V_'X{ O}[-epo=9dȳc͸>Ғ[4ȉ7\i΁Vn=ڍ e ]wᘮ.\ S$>•SɃ[Ȳ^'Z$ٳm= :2{S+Þ;qqksK#[aܱ܌a>cuX`6Wiiuhw^oUJ! '|M_iH>n4+),z_ni&L+Q_Ex-QH6GJoD̨݈jʿ\můi# J?A<\̄ Q EΔo“UT2PCw#pcnxדeP1*tqMFr2n:ɦ֕n{@'Lcg{/uU.\{цZ vYv;ɖ0ŒE_9!ˆ}1p5#dݎƼCחk~Ȑ'^e8ɫe#RezZ*H> 7v0%ohLjr0Kcئ0_CTh/4e)?lrY^,CdZqj?z{glչ>i/`uc'|eQsc~W[gT<7*0I=sטFD2]p'_a5vϙX7( :W`̞4zwȶL=d[9^xs%ǽ}'[u+iGGVoz7oijvxm٩lH%lt(+QgUzjC= e°uF |n–uV<džYst+iƾMʈ= abȎt=W+P2@xmUzIfAh.Nb}i͗Sp9xY>vѕ7r nm5qyof5v"qj.Ѣ<|}j;HNJ-TẴgQ?CVhZj- ӰWFb[ egѭCP6:=xzgkx%2b{^bCnA^ 2$qWv<7[O 爵lJ;dGY\kǔK6-wߗѪ>%ˈ+kMXdVhk7MY \Pþ]u~ʹ WŸ`i!׋_KM#: RA(˛S޲q~ iF a옐ݩEf^>ٓ#޺h@J<7-rTيݘ3^xoC[.tˈQI"O[O2)sVѿXKڪG:azt\̕=Wtl6OY8t?(( qk]6&o@FtWgqWsegN]XDžS6A{6).tvb6Lp+]s7Gt`g+;nd!Cp[{sΗ9 !Ɛ3 x[joFLQab|ERQ ~%`L|_9'Fbw.IDnԸI#\ )fHgK 0c #֛!810Ǘj|8cq-AB|M\|ݧQ.܋U/=yhǎsr&]-JtXy 5TM(S"K/)2}3.2b)ݏZ]Q8(49\[/#M4wbưx Jd>+m5]XQNL7r#7Fv`}g>O`udw-O8k#i9ׂ.CtYEZ2֘$FB'uK?kuzkm yܔ˘[;*fr2=_Pd8;Z=>Ip=7CBtv@T+2oecLywvM,q s;yT F+ҸEKq^!Эr ӻ kY6 ɅD\ {/ﰪB. ez_;5?mp`_W;kǖz$w8o ceh9ZW: 9-xP)͛٬nvuW!$a¾$̟REPUm &w7Y{;=ܘd}&`| RQ. w a:aޢ xfc,]uqHkR 9oHXFϞPJ=jƴil-`Hg%8QSÑ_]y(ʓZ'N ';sx+NL3[85fݿgH3ܭpwO.ѢZKp ެϱ3MAW&5ac; ׃IJՍ2 N¥m k*9#[z:Fְccz!sEQ:EvPێ^8ɍ iFyV QDŽZ<.Ae S=* gřw9|7:Y_q$̢|Gؔ}D|UkDB"f,Uj;D1݄g8wÍ;2`+`k9O^iķ1&Ӄk"=d1=&-RVy\%('P6o^a-$幢*]%iٕF\~)n<\Kafɲ|TRfvޓ,\hzC٠o", M/4)w۰X˖7Ql˂Ftܯ̽fH4ς|x:.iD`i,.K7\L4f%sOtY5Y؄kՕ0&'\Ú.Ϫk@F9qx$~bBuk0RؙUQl V6 XYx3 0Wšeh ϒg*טQ3?Ǽ\+_pQ-[e>iSUAȳ&T6; 2>f%BGteVUM?1 'ԛb\?_%h띄_l#э':0t+pb<LVѲ6D2|5uak;0VL2#LVۣ /!31,Oܴ]vN0<~ y{U)U&MJVR+OU"OO[q) Ӿ a*eG(0,JӔ*Ъ& uݓg]9val>/_#d#u'mY:ʛCy;U]2 si7,}9[l߮ 'Uy|wls0\<†=eK9϶3;X!͗RJ*CV ߡ EXyhج҉@#,%oPj]7Sobu'Cgc].Au2Tv hGW7UJ*0upSgynmʵZXɒ{X(/T3klߟM_p~-#= P?pc]TbU>Xƈ%*U«j4scFxs4ozvk9/f~@I9CQytJpe>XSn4tŧ\[T+i([&Ԥ+L^ {Xb=Lwlօ3: Ԣ35[=GT~y\ҤzfbWu,oIuGy;G֫[sxc$SZ4jpC-nۣE?ʅ뛰hi9ߤmͽ*~?,KGTܰ*CraIz6ȤR+v>j e` ]-.uYi›*\²Sڼ;Ւ8Sϕ<Ӄ6n^ulh ƣ.GrldV&Puy.m{v)D@O+`SZ?w.Tr-{Or9 j3obLGƽP/_\eEZQK 㖉XuHV&L\c&W'x=k5M F~O-jcY!/C\1zcI.Vf }IvzPY!mHS?c/uxTJ PTbl:uУ |ګI۫8J+iy(:7#K=5܁h#&g?ۅ%0|'$x#seg .}UޮO9sN9nnt)G.򠇅 wD;Dˊ=ص?Ugfx"6,< 3_L<5;KZН&fb[*rX{-n gpsOvyʼn sg.X N̝ PܽtI.-e0e f)֛\m}oǵ@י|Д-hxh*Q`;r\Vwˡ` Cgq'KV? #lҩu[OKr3ӥ*JpZ!M>pJ qOӛsVƑx8B[ R;ʱ mgʝMy=njC[Y3:PPve6l!|u=ofC;z S {3sT9ߠͰNXu ;V*q2m65dSZcϨ ea|`7y\Տ5wGT%x8^:Jar%ո#-1##" Sk>,o9 " ?>)[<[S-.v vK9Tvஷx oUoB2Dbzh|~_Blty?ӢIo)6s>wxqD#]=KUn؄{.eWJVӨ:acy'wN.e0"?}EN/$]F%kMk8oέִi;3h׆IG͸lSR9<֤Os4{r .GX]$JBŲ Eu|[Cae3> g$\*Tb6s[mAs5mڽs:?Ke7۝륽4%zr:6bȜl);8>}/Y\9ZW#KMƔk}Dɱ`jv,篮ncʀXKgt\@VƜ_w P%Iq߄e1]zTNq9smg~aJ#RT&z{4,'.]4_^)ƱE|RsM6w.«[d q`\QȗZ\S͚TX ;egAgIkɟ^+A{$'*]z^:y3"wcc'ou/oCUdyjq 8*{嘶[jglO羮tSH5an4ӰM=ҴD㱋8 Gd5׀U5XQΧ8;Βv|nitwC"3 a:@o(\ a=?v,Ƀϻ\G}Ght,׿ZoR87:妠4f [$z¡na$SwHoAzecO6'C/ToԢBl y 9Ek^Ge&9VA9cKpao.ERL}VeMxt *S$7kN}f)f2 WL7źaÛٺV+29W C0e \aؽ LnG~cs:&]ޛ#tVԝ^sݼÒfoHc,E'Z#ڬk.>K.ǥ2\_E(NӘw#Q:c\a.gONnWbvg ï*6gN![~.?3a(M&{_|,hÊ!Azu3,u=Үr$_NIƝ?"OSْ8#k+Ѭ&~d ZascԆ!b^Y}`/ c#X.*I[Ã6#,_%Ϥ;J7GC24yk:GSgqM5ZU޿eJOsf,|m<-o) <#B*LǑ# Ɔ3xh;B'-{o,#t,[mFUU oƵtNAHp.tlg}9v/̕gQ9\8I=ҊpC!N/ Oa#$yWT)X%3g@EUIp^Iϕ>{ErwAw?h#IsK2^R$aqy=1)*>CO\+1Y7'@#h>yCM񲛴L~ ;ݘ!V$:OIsvs;4[x'wN] ,M>Ag7w'vxg.}nAQT(#&-ķvpl.gv#^KBJ, a?:uT7nFW ,P7Io8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoE=׍hav`tԶ?ACP#'y$4Jz9`ӽiiIVN=_2x &?iF@i[~z5 >QBCIhO@ɒwKy}CRF==G g'"$uD>n%l{t&p ɛ #'[` g{$FZ0It"tl)'k+A˚to~m]lhg|+-Lz%y7!hYr'cۨ}z Pg'Mע > -n|ۓOI/9x2r'lvŒX26VB~> lyND;nX`/(w=A_mgNRӒO=* MÂHG*}J n`,XU+pyڎkBHQ^\ѪPJ[%ڌ8]SQ@]JfT{&+EڟYpE\z_2igΦ tTâ&=H{ih~d!xd 7k Ŵرr5Fکr W=]vxEIWi)ܾپܼ܀Т&=^tqoMwcH2]Ty`Pel]WAW]rP%m'wm.NAP8''`m t*WP7|^ /YI08qӇ2vX\.,2A(fvmBS?.ޥŢG5X aՈA"}3 _Kip޾>j(Ϗ^V鍥"-SzeL_M}my00@L:Βͨ\FTo- %a0Z [cJj.j~K |vDw:f:EXxa׀m*nz9ܝ0oB.*maZj.5VVvМwq|h.~ˌcnϰ!J\YKvנ"7P`{z=ۉy:)c I٬Zrj1ٻv>듎+Z44{msV\]a_Ckq`qc'ۀ׎%kKy? دKEvg5\yF$Ô ;]o4֩~bvW}y+ӚF39I3Sptf/cVeB8R%Ԡ%~z8ZAuV଄[ӐXr9;D[rV*)Bp* ^snWK%c0},{*\J::,lO %zO8~S{;<"5l삡k^ ~w5v ?7Tc:K3NU٬@̸ʎmZYpG&SJΧbMC9+0H{dVު {j4"BM.U1?jFQ1 41&DK9(q5n_2jc4e2+pcfAtBʱjYz }Kx2 ^^HvY!u5HDfG[gΕ@϶{n {t0ڍ_4j_8sN[m*Pad=,lĨa*,uaB_3V\ڊԍ7_63NëePئF|irQ*<1}{qW:oksM^(jfH>˖0ZãyؤMYhK-^ɧ.aY,1]{\yME^ʬFgiFNlxLv|oʁ4go#RJb[)cO΂Ҩ4i~R0Y"'[wYSfWZIJrJϩh׉scf}UFضRєg.W{s2bTe3=;& X}'Ǡx ]1xXZ^g#'4T%j[uy_P| {!PXtLYl͎mty=e^5_1`T iտQwN LwgDwຮr /ְ*Rcgf9Hϴ{ڵJ ιx}.7ĶS a7p%=Kk ~ e+OkoiÜf}̈́_1b#W:p[h2\; &Wa4]iYp~KKb}M5d>F]ZRGEإCM FFgj,c\-zR "x~ytn=b ?WYÄJuЩUMP˅XkvX҉ I \C)E]L)w=3ytl8cWQo]&*1&'THQt*96$ul6^Ц E/B .#Ey$RQ6n"54(.UEX3JfJLZ無qPMeS "T}`jB#B;U\䳰9O`\0D2’l>f~♚{.Ro9u_qJ8tUvu|2Q54 ]0kGk~]9JTgTrRt刈^^ 7OHPSz3g|ꩀVZL\96paKۭpV$-M4?B#G^JݠS(]9=i~^H:P4zjEJр:&}iְL`_Eu#А-C+8a =Tc2!O-Xo4VEn*Ld>x$aWO3A^GGcv4{ f>;mz\ToՃR%4B=UY`iH:'UELj˦K`7V:~~'1崤q{(2E:thsqTخtŰ u/EGf`Z IsbwiRF`'-9(5th:~&%469͊&ZN&̑n ̫!1C T'9B]YT&95kqS80{td#k_ -ޔG/gх|WO\x93sh:%rͥ\Z+xDߦ\O͎'n6ҼMylM 4q.w{jyg'ͬ2Z6hf# f}O"j?is)֏"-nd#ۗ,\62y9JRh)AzK;: R`79f!^Aktp' .sBew$f%w{G{03=y 1]b[Yt}Nk6:u42\{.DKp=ĸ\wmQ?Ыss۹aI[z1#=[Y`*XDd'BC}1X=UJnHzQDϒrnw>HCo/PJnt#),{ 4ļl#\St Gju宬ȍ<eQo>/ , Jh5s"#$@H)BEJ2|Gz7wh}]&(w5RP'< 5h61 at;ڣ૶8^l_4g#N̂]P=M)~7&}NLٙflx.?!QG1X'B%*96S^c[SĸK :^#CRsrDZN+i,_AeӒf4LU/)}(J/F1}?}vHgiNs4>FSƁ"G/O*x֘73a6n|cfe l{WT;58}Cmܘ, /=4"Y:52_(qY)ؿ@}.Ł{b 8gath4>`69qah^V_C uTfv*69|B_Iv;i .d?mѥK=J?'OXt8ÐS: {jˑ%ymp6Y,q)rR9g1UXч$Ojim; $YzS_J5,v w&9Lmzt*è+ OM bsV%Lg QA7M=Xj| ᄵw]`${*Xj1GgtGJM ԉ7n\GU,[sBzP@џѳﴧMiWB.a c=k 9HnLKjCh ӊ9ǒQVp>H}Rz/ΘFK0H-3ЉT:3:& >g3'O)yOoo_kڵiO!tJ K@R› ]$YCWZZPs:,gKw=wX5z=pNߕc\ ?tҶj$xx纍P(1 ,a'5N[ |\ϰ|<N^ Y[`ϥl;*.iI]-0 QpN7KBc3ٌ'tmz:("ߙtk^!].- {4Rj <lA] բxo쯉*y='0 \#Wxz4JX z~u-.p8a9Fv"9ⴛTsZO>۶âtՁҮ[4}h[“q6db{B4ҙ/\L/-bRTwr$ϒCvQcHthJ\V^_k[1>zTp9k]\îڹ@""E\Sl \'NbR(8cJ~ q'`%3HkXdrS P!Y.zE&iUGVj"µT%U3NѼ#r!Ik ZկjC$.T WV6jRE.BUs )vL^jcŁ|QHqJ p,aOسNeAMr;{Coh/Zs/:me.ֿiqknEt+7=1o^BM&*ZmUMCI{9}Rk,aEW8b^K Zi}ŸQNjl L~ Z#nXຒX@[G>M55@/ZrUOwhzl cW|E"tr -3BL:ﭠomP=1V=8Ɩb1F qZA_44=Tch~6<vµns37'GSB]EVtDE tkz>%aSL`JAѲa%Ky-" xĖ8[<UEoW8*UDN7RwWv⏹ _1=asZݮAQ5NqҮx1X+I~343icb퉭%f<9lTEѵiEfN*YI#+O6&qt_ X%=ɡk,s(,~%_jZTiJ:94Y"\ #AMRl3b!_cP6(!Ö2 E $,=ss W9xmOg|b^K$,rsoK$|f{M<}$*qyX0gާM?4%Ba=]iM`;r$EdgE{ ikZah3)R/-> bZa[ĩ6;*#gȪA>jE(œJVjpv"ճm:FjYu '; 񣅘 Zչ6~E{R5i@K&79#Vbd5j/at F XSO\Ze)|dq# ʽtI&Xp٧iM4vKrJ9ʠu{;4?xa"uL!*HE P۔dȦ/bK<툨 zl끢F1>+w Z ZC-\Ӄ0+ &1XL(uf}3@)6Ge%`DIr߯ZEƚzd.77B\#H k#l;Nʡ"W{25~ACiT|Zf mĂnwlf "~H@a6{UQdE#XdkХ;4i0y}z1^@_V]=8ر6gs^hH`i!.>`I 5Wʱ9aYgXAΫxi>Ӈa>~1Urmvܚ몉tvխS*=V@OPǜJ˨"֋b>*Х)t&#F"ZAR0)rNBf .gdJqqS|P,@P`@V:U擄J!^$ FM8qda:ԥO-^œ*ͥ/+-!b7)q=vad.N&7=ynٿwszpE06FDsٕVh1L?TDkI-C12;e'ڨqV7;>s-PޔR\tͧ7ߒi4-Mg&Z-:kc`VO(TThztX=.Kp<sN`zԷ6mPCtxLƃ5z\{?㖅I7tZG6f[.qn}OpZnjiim =͡rH\^J6I+J{_nGSo?driGxwmNi|JejkKp,ZcתjCO] ]C3C*I 0W9`/k SO劅=t(7iz# * &0%6¸9ek&8a_fvhfm3[tHFS* oI:tuԭWx~T8+LMEgs^Dظønjy%%ohEC6|& UO;aFg?d,`;cfv gSu8fzB|cm8 D&L?.ƤC2]UbZ (Cc* tĢ0vmʧYLѦs3]MN1*{H9;hb:C},& hm燧ԞUn?a$<,A5*ṇoCj)0.Ȝj)h]k\6Җ[K&K R=";VsXҔ{q-t;T49G3Nk_W,*>vc{îIpH?Dvx9j^%(^JS!ߟ/>S{1lj $Aij_Ms7ܣ մ-ɳ bfXMo] Lc4OR6< ; _]]Éz1 `Uq ht2Gat07f8%r|8c*^êF,ű+ldBe&I9mcWm~ҽS`yBs暮y묉p0n%)/3xh'qC:JGǿfSeu @NͶ{k<9ëR0¿V:oi;z*L%qCePGJ#\y t6rXB<#PGG:")Ws-̶ilAAe #'q -p\,%+ sA )sL:sTPmFkKcH<5:Πx{f_>Lz F~&Iv89Km"@ \k*6^rMԚ> Ln$Ch}˩/pp2 3g$GPH4Քt7m0=U c'njn2.]&/^Ek7cJ=vCf{%ڵveJLz^P`#9v+јƍ ,;B%w,ZJڽ%d>Lz=v?yp!)\s`4 @sUD4 }tK~:r.~k*:ΝxL):lIf%b$"ҭ"č$+͡t+{q', *SmF5Hc8$cffXжBJvQba*Q];4#;ܓOwi`>9~L 8Jh L),z\EpbEKDRmhϡ Ժ ,7э9ԣIbͥoS]pTQ?(\Gf?h0R[Epp].g _u“Sg;`+{|tGV?C=ψ-_5WỢ9D3OT7㮝qWC^-NxwtzG%*pj+{B3vȧC(bR@ca*:Zqͭ1J >5=g|fhw}@1y49V﵄e>z,A"9]$H9HAZYM-'Ō/O"g+Qc* 2xzJCav֢|xG STX蔪iFJ5tL.x9,0Y| MT20)D;B)OzDT?M+|jƅЅљ+i$ ˢ+3h eo%s0KL;4NYTuGAohw67p뭰c$3[sN]pFWfg6xP#T8\̷eُ-w֛F $t,:шZ,/Gi!=s bqw#ܞE7c Cay]l4j̋4`AԱMۃ{t`*.֍>N[|iE$`mW9"9} wŞq*,a|=Zfx Ej1Ӆk D̗3]@jF gECv|!nQiuxSq(xUIHeUxc!H߂>У=atkMiYb<~I^H}Y(aL~+PѡvXԫ sth.4܀.g~l uLNd5r'tKN0>B?IUAk~%˄o]HBzȲP[4NO VӾ?pkUw&V L_(2rdeXak+_cv9pQUd-|f;C ._aycz8`l112]0*dU=h¶VPN`nP#"t7~[ۣ 巇4SZ F&?L VS94|);"J2>./gKб2*a:aYXiUǺnn4=H='#5d~ Kum<,h7T&'a[YGqkhTJ~Nim$xEX 2qDoJ6 ȭ4^:hA<7g)Fk0sc=H-+ph& aX=rsaH+5fYΎkڦu ZJ[c` na,qסF( SSDhvn Jh߀|۩~LWZO}Yk c"qAr5aƿ~5OZ Qׇͥ(e9NS@„+r\.W\9ZVB}d|wj[#źjhe%~7خoρ5|ekR㨭o9=1qF߾?T f\z/$Rڶ)V>RK=E"LdD vÏqZ@ALgt>Ƈk ҡU7 bY#E=u=-ƻNLM`s_1&81fp> ҜṈ?:~yjSmͮaό8>qAɆ"ϰfߡԑ{5GdS̅XhFR{kYs^lwC7[JQGE~Zۨ¯,gMo% Ƒ$:q/xOJ,!؛Tk8$sKȣ>߈C+ݯ'W%/Bڣ BwW)~e>=c4tCɷ eN,o@j(z>*=XD<5pkpqaw2Y`bϫWc? fX)5Op~#t(a UB?W qw=3S5yyO9sாךBs|!xy;(.;3o0}P'Pأ4.UllYI^r{L3Dd,ɥ!R.7౭fH@dqwv]o2|NInt XMdUfzL^ƾ`و w]eŧfdz2,ȥ{G掸|TH(;>tkQǡYtt`ߞ(bge5Ĺ:0U]E0$WB Ƈ0`a#^ u3}??Ԙ_{hڏkF XX̾FZY^ԸUtC, 9E!"̒ FLg°7 ijJkص/؋>phwt? QP;`G?GE1 }? nlDwv ޛ;N@ݑEou.\[Lyp |3VXEn_7fktL;wuڝMI]r{աCie.&KbrҨ!%zQQؙo~M`4Уtdm7]};ۥϫdӆr~mH2yP;9[C=֮i8Ix O Tኻjxp%>OtG#Zob({+QbA .5c{3tqC}=*1ᇴxA:GU+ T(wŇgx MJ~Gt#gT`9Lj|L@,  z=r p7#\0k #t(գ~j8¦yر,K;Jr~4UN@?<'D19 6j0~PR ë1r-mXD *(6-u36t|,ljԸzZ{S)Ъ](m9Ż RO'W1:OZDش]q<`n@Ir,=J;yR5= 8LF e4֫2 pmcҞJl&6@VveZ -8Kv}k=HZ,enI2Q>[s9 }5)ULW{G;:4?-i쪻4ʭK[?9`xvFgs6lg+cBl%J+Nu'颮 Qj1D,%xLgXG;ؖD!5c6u4's}JvYISD@RSo2=>E_Q+4`g5z1?RS+Źvqxq2] lg1`ﭣpo! n`nTDl D;V 9y:sgZkf̬=_?מ=FuHUZ`}_~|_Ǿw%0ƈ 9ŏ5>| -cgܐd GxU&G+ج5+# 93\3D~_N?Jd=Vɖ35a 5(jB̓zA;- {14L;Վ|_;aݫW}.LU7;ax>;2z(x5ӝ>َ=[[i^? 8|/4s >95f~,mkO͠8Mo2thOݥkt楺Qv\rYzւ^;m+(>V`jUzK}ZתzǚK"C:f)|.5~j4}C׍Kk|xsSf/+K^eIUsZj(c"2g#;Sf2aL oU% I#*x<]O p?}JiϨk`~:YẽWk:BT/_6x% RG>~lSee0{ZU]9+FAU!N.!+Upuy@G&>tZŤ_bzl3S}߶2x]}֛BY@Qc2׎"𭝜ܙB'S'lL'NcGs|eٻc=DAy0>rã1M61m6087q!W8+q57,wbhl1^Uj:T09@ϗ9S*to?Xx -"UGǞVдT# W$sғu|{]C6hbCU66wň#&dc?wcy+ ^%_D-{>o7/̾ G`. o#տwA>9DŽņِsJ;0?`W?FaXP-jp9ՈG8x>lċy-[/;dEU7wŜJikoi$~/=|*g/k9lg]Q( ?FIw S͸MNg`F簼zFPXou#6%"&L|ح.2QopgZUҫ*|9YagT}#W߳l.Ǵ*@Y(l:c?L)E0 ⅜*_1]5̒y`!6W4ఇ=^[+HXo/~ԄZpA-%ޔ_URnM+/؎_isqg,h/Exn9 f"yH<6|8D=%JT<>IźJߓC1׺sO]x4Ǒ+3ϊ{&6 @ 'äyR2!J 1NprV=II*ײ_{jm3bۼ3y7ĭߋWU<] W#tH?To._6!Wq칋ߣYrRNln6bexO7*%h3^9>Ya&zӣ[Mbd薦􋴦3[`T./lԁj?PSUtp,-ғCd\}Gߔ6{m r3d(ly$ Ê}4&:T|y8_ >lj5W|sCl#^™*_I饄=Tk9MRvfE3-/Dy*JKt-<9'ϓ}>7噖OʒYaѦa ~O_?B0l,Cw~U -cMpL4<ZT1澔7~:pscι\$p;$B|H\X3LGBh&fVX&_`!&ksY?bNՄhz'?.g󐿺k`aqA>#W[%v gLs5/j9msihZ<}`cEw&e^>\ 1Qs4oz%~ w&a$45Z_'>Nz%ir5d < 嘙2& 7<ڲ%*eGR!gYdGBh,y#|8_ͻ\3nof¶AK3qQ.(Đ#㱹|*.ŭ+& vŖabӡ{<7GbjHq* 2ڤ`=_f3oԣ: 覊Y;T֕F<ӵ- rKƬ11 ^Ǹ΍׿`_<;g`BO_[`4_daȹuJ߼m'!j?М[lvMX3nh̺5Z^Q'ݔon1‡TZDQkqh tJ[`}9;ڍ6E 9kv9钜KJ9Jʓ,nDD| `:?|NF˞EpmV3,YDIKRTxf )$硋2.'9ޗ3=NN2qnL|GQ 6j>UTd˳*RR`KTLS2_ >.cZ ֠gY<`؛;fcq鋁3v<f 8Ck< M6؛yu)Q݋ /es'isJ8gG,nN>d+44Wp]++_*鸞F`fԚE@9 m7v7[rSze;Þ#mƂLhʄϔ3ԔY;Kr5cE1[L2j4c)lbğ8hް[2/01E5;Z}/4>RزyK'%ڕ3U c= :[𚙄X<S̭ 4tfZ/.=ws[ omFSjwXnI>[_lY==y@ZY帾jvix*-k-yRm+05?Ehd}JC"h" ׎drk?.x g ,SӢgt<`%oQ+X S%k*$cyJvqQL_>TCmzL}32nzdh;a˕LB󭆌<w`?Nĝ+#]g!,wFڡpOdžva_h; 616ޙm5o\Ȕe- 7\qes2A6g^aBO+ .iga޸O*y}L욥^g 5uWdt8U# EK8u~vsg!o 0rl-{*G})ypG6.t刯Μ+b}4zĠX(?_U1[&_;lRSP*OS ~jy^.6*`ݸ k?q;0׏gK+㜩Ȍ.^B%VE5/V!'S %T!jz+ynU%* &MQO;;@O! sW:Q8l N 'IGDY~-[}e <xä#;Hã>{_밙ʇ59UCi 5{^r -ϖ*t_r (bɒ,X3fG ndUͩiI+fd smk*q%udȿa^sAgJM(gv,3i[!ϿX W'xqW7xCXL'ѰVՓi9B-dԼ[R6t΄;ᖈ"wd{fE8A]YÔkC5O훃M<@l4Xe6Cϝ'%i;Xa޴ *ouj^`9Und8۷GBo2]⛙B vTh5+(fjn,Nv&j>zSFY0TMOac6oEt fZzkc: %w 1I7 d{&W~BwP}/!K8j3?9LnYs5U:Qӕ 2njjets5GN9Ίt '5hC 8-P}AG T 0Ƹf4†Z/hW6A0er(r?@Q2d7UեߚLJυ^_J.gkAw3cR-cǞj l -:xs.9 PVR`߉xpT;&JY˘{8#MAJ_iW2 ׂ1# iOX1É3R~٤ެH ?*:LƊR~rFf.ǙtNlqJ[DvzRwUQxrMkawpA.R1S^||ԋLMQߺ0oE-ܛ|̚V0a}9j 3VUae^'~Bc7!L^0 w{qvk>u,oGjU~XJeۈYraM6EQ"-S,kM'ς(0;gη2Ae4cBM ,|B17w,J**:/6kiC5>2h79wOzr. ݅usjx|OPc(حԬܢ!Oi5BLF|dʎK3ɄԐ.g~`Yg 4-ۗDqexilݭrl9oQ󡡐}$4rT'p|`<7͌;יp9CSVI-24ɒ}y;}md  +xmVIB=^*~ݨE!OU1(XaX(Zc .x;?qV Wf&Wwdt[}-}b&hH~0EV̧84,gb;wڈ󢃐j/ܱ8{yĹϑ09&̀C*\L4n\OY ;1쎆S4$EэWp?e-'pn/>;Ur&ޔƊݘhoaeh94!0Q'+3O35'e"*9}I%? s܃K8߄斘2RFpbwb'sa> MXtjC.Ӿn?vd~_Su^=çUЅX0G%$RvM=ճ2 >*}YZkg 0[. ;m1>Z7X=΁ox9I*ro\T=Tκ*%;(y.'5[_Mo!gZX%0z6wQ>E|Ȳ6rٖ9W;fXy&tkd5:CF=3p|6/X &z. [rnX۳qtO D'.@1q!~z+3Vl7dw)7\3ꐘ}6V˅TU2-qq^2zQVnR6I_!敞.t7q3?s[?7vX'ĒyzfZ7WzE qtzAm–8-ЅЎh :/&mbQh6ǟp×,^f d) s f8BFBF 3li[s s;)I$pJXS#J9Yȇ ަ e&77uaσN82_CeȻ6 3y?ߡϹy].b7Wwl].ʥbkqOMu={cq l'{eMaX^a}Jt53Nݦ,6d1]opD3va͝:r̃b։1.H:W,/欗|V bww1=?طBM^HdTq#9 R2sJ^%Y#1E+\/d"wgfrf}aS$qӧZ+YIC!m$e6)x0'ō}M]G`"Mw,rEF9QC'aAv:קc#+aqƆ!ڐ~GdzJ4hJ7Ua^CFѬY-usZs+;:JsR-Jr&y*|fh -r+$YN|9Wv*ypu\c&I+#;9yn=u1|ޢQU ~r0 Z|n:]fJRSoQݬ۝PkGWr0A&M1}-^Pָus610r)4@s6ہ7K\ivƃ1xJYÃOdӞil~Ɲ7{I"B°2^!:DD׎"vr˖2K)\9D<~ą7]+nE$l\V{6+ekl5d{ 7*2Fb|Ww~~O1fք"ĜY&jGV<ǑꞮTnc QqSvvfK+$9= $Q)QIb H T[ )]*N{]х2ɑ8RKb-P洛l]ySa@۬j Y^I+qc9ZԾ¢K:[]D6gAG.D~OHAe8S8ɐ*v^o&,3:ln:av"[n7W./;]Xзz{pHH9Zv>*_ASl4E#)Z.RMoϒpsKT,3<]׍Gڱ1 W`uܹΈM-9Ǟo:s41{-wV)rzTrfZΜε"q{tv."s` X#޵ۮ0Y.x?WX־wq*./%QX2 3VvgʭЖ9?FzRʖSY/ V+9'^1gWRtSk,xTJ4VRPʳ;d%V1YQ|KRMsapF|*b6{K?kƵ6cޭ^$4qj B01Q*Q1-^9O$; yR$|U3B)Ed@-F6&ʈƜbԘ24ց{8+;U:_e!#^j&nO\*\#Mwi0Y<SYƍjOEȯ,_ŘȀ[13 $)r^4TL6r%?I4ܝMx}#[}{[aW3aʲ/#OLEQhO=} !/}7w[kH W5<+`3Nd6S:Hy'ȃW{ٱ%34䯢JTvi)2s0I6+ŬLƙulǍxđsǎ3Z75| =`̇Lge%UFccQ|P79brs]ѷ^ݎU1 *3pȹG^bx'w#z/14C&4\Ί!qb#gg.rawWBܵZz 4|‹C|Ϩ</'AWt\c Y9Q5]*:ѕLx+PG,9y3Æ8QFĜp;ʶ[ } y]|y%?Lo?Ǵ+yѿ!Vu+wBA3&?ՔqV}9XP2{-&OXl\ELnfCyf)^Gdt7b;TX8\¬VnRrݘ;HD<A;8,ҁ1%]D`FT1)ո)͕{B2a(]L׵]߶3uXoW2 Y?rN±Րէoo2d1ϵ`L/k^=fNSmy7_9U3g >6K%oWS\öb'_VqT[=*eޝ+I ٺL[zrr*TF|Cڣ[ v]\nLifm͎l=+Oq51 >x@oKeLi]%;xޚn\+kPT OB;ì{sok:1opVĩNPQ0dfm<qUwR~;dT~od ѦK O逝?#A)x t< ٻ; sU7d0 >nSXg8gww䅃v݊vnyed'# fe kӣẅ́O8z,Fns[YC]KEBx\y~ٛ*=aEuÈшΚ;RGpb4G;:o9; ]3\͒^c7c3*i8L<.`S7Et!o r7wsfs"ȶ|F] yEpWx|)flȒpL-ՃP%$3Drv$Xgv0w`nM >Ϲß!*_.տj۱# [V +D`syGxɌ_̙WlŁmyu\uPw% Z+(.Yw0mbw.c`P)F "C~KoeBٿb1ߊ4TI9BHQ"X \bwޗ孄_\;ʝCs4g=S;`y{m]?u%^|aqL ؜i0ɎEԏvgNn$ALE# 3Af_t9^ˏ2q+6lĔ[{fej wQ8X~k>X=RNȠÖPq4y>  ^i7zRV;}޸G'{c`+gObl58d>URT"t>AȌq8ZzF E,o5;WbcG'tO-5aifgC-8ٲ\ϞqY6Ñ.YN{bJ9G"f<7<+;_{rk^5wVa ۈ>f +>cǖ[]YŃ^sІ=M&ߐ}2u&){~\N)ŃV2Z?=f-9ږOZ9;m|;+mifͯ[-RKkuWL?K]FC&%Q>>Ɔ4VN.'vF\Hgnh*PK*M;|Cއa;1-uǨ{3"eZ5d^Wwq`BOQcn yߑ׌,xWr\J1\w'$W>[#DS5J!L5Mޫ8}<ǖҁz|_~sQX zL 5峩lkK9`xz[Ef;BRm^=/|+3Q0 c`RqAgq*l,bDK#wvsf6lӂ+L8fgzڄ6WtOkіe!ctcFĴP+l$cn'9]WsKqVlL)X=7[g[.>fÒ}72ɑ`U K>L%aq*NddBy@OCe@3]V‹a`ONYσ\@#ܹ2ޕ?湳eqesg։p/ }hܝX֕Huq#Vo% ٨5{8%u*NyEv[x9 \{NQ XWU;!+i*eoʚ8ԑ77w gʝڃB&.Դp%6.0ϔ=˶.w-to0tc~XL\=1|𓲎lL(t|Gȑh#\\DIr'wępf{?T?ޫ<c,zS)7PCS009јz*6;![pe[K9 E7Lس9L#\qҞw{.Zn.10m9Ѓ铝q̚k?=5qA} "5!a1t-=j"xDJ.9,1ChfE56ؾ |*lcB܂%."^*JbG=.~ kٻ[qŚ T;ɖ 8r A2Ӿ[9sj U ܣ!'#[[#螟/p_!KϠtyzB&8;N5L#{8栗B1F=Č,&5(<}a޿wX)Vle*b*ULZx y/YӯȆ. e/ұ8Bz?Ni%JoJ?iU|_lƳNJͿ@ݤOk9ʌ,.W7Mg[q> sUl^bڭq2VϱšӞU2 lwk!zhǀe1̔'ːٺ{XoÂ74-B|*yFx /񌩎_9T+:r ]"3=Dq]B0 O/noK~@?M{`0dܝ}(֧_='"Uw-y ;Bx f1$qn3ܐ|@x<H͇ /„Cqu }7МQ.8KW1Κv@O~nM12q_ ;8cugg޲0rz]=[sY=^E+o2+bDKQ0{TZ%?l9kX }^VEb>lׂ VwK9򽌵;+ɮJ g: O ̿"@8ɑWejZ s#=*xnX&"zc̻ EҎh|oBeybj#F;ejNP\uԳAc=Rq0O')<°c>|?U2)LΪdl *=IŞsl}QJiaAi  ) Fʽ 5Ȭ8"9G7`<Eb]K%OvG Vܻ=P-g9;ǓVY&Ż(IǓYH.)Aոs„,(3 , PFL8o.G˰"(0"o&"g;\~ebL(<U)rb |Y.j!5״ud\sW:rp3;qcq%uŎ9f֬#s}#U/'pw\mH(^%|$owK%*Y01Mm1kdW˸Y+)0YAU3G0gU*k`Sb:cP':礩 GZյv<9ω#8)j) yM,ig>C'!k̾ѴX,HD^|6^s%Ǭk4#YĶ|hKAĜ pL9MnU"ǟ"Utߊa[ KQ#`V N~xf=_Jfy~xf[˱]J^-%e\(e{SwVh:Ԅ ͸o*-8%w|MEzi|x/>.)O@^; V"qV<2=El_kg]fu9>r#E_lxa5KsmUB0hg.v\X2+w`ӥϭ9tOx//8fk)I6X>3%f)LJ 9C st>=,X-G2Mb3k[GFS9+*Gm^xYKʹ\;}5qs,;TrOgZp빮wޞM9#3k|T0Lx|u61; Qo|D\#} 2\lifim7e娼|^VaCSjҷ"4dOt^V}3!Y6аQڇGV{1z<4p -׌Lۊ(FdQT(☎&3h=gv-h}B"fK9JCGd |j8]O?+p8\Qj`@#Y3#sU;ΑmyR1֮\ɞývX`%i\zW^'d|3Y)Ef&cf IaPI:UX 5{%HaI "xb&RM`GĢY&hUףhlY)T%@(G>{_v{|^ ? V|O:Njar+oOO&JٷGZrj- 9l8,[vz4Z l8zUgo‹a pUU445Rk~1*Fh|kU9/k'jN|nl+&x˙ZtM9y5EU2%Ch,8H=?SWfpok>Vc'h - &)y֔ѕ,{cVRr!j:Z>TqjaH֚gBzfNq{0813hS˝?H+O_*9鋒Gy1XÉs/{WQ#2~'soKNS3rP( kDZ3tehiʑ8ce83LÑ{#`7ޕHZՆJX*Gժi>=?kDؙýjž// -晒M^hxmR䛌+,e_-C& *ģ5Y* V|1IHGєW! ux 6 jM~W9cf4ȭlx>eJ\Zn"@zԌ\CvCn.4&ji;]D?YRL^}Z_-jIidFը+|q"6WL\גHz LC=+DŬ&T9rWx$HCuW,N6+أӜ8݅Y>ϕ 79pۭE5L uEK=CEJ<+eC df)XPQaBiw̼$kaj|mQ,BT,Ipv$N㉅8gՓ\}?0vj~`IJHuف+qt~/ӝ T Sߪb:kxAOj.d~WCǡݎOݾϠl\X[LycKyz9>ïWX9R"pԷ3 ,S.*:-rdJ \QM U(%oSЪZf:w̲#tމ#UFt̂VWe:.V󂕚? qGNu- >aز=o)O,{Z$=ft"Sg:~`˳]LΫST.R@ '*xkx詖W Ė?;+۔;rg'عrؚ~iy=xZaf|i*bH?D1G0<0W>+{bޓxoDEFߏ&9$ #BCMfA܋eJ5KOATܰ,{|V7lo5;39ߑp|V˚-9(rw7'ԷB [(0LWx>jvl`kQԕK1a~L-85|#>8${2IYg*ZV2VFom\cc.DGNL,r=/^nMeճaC;Z㧞tfdb;Ԡdz%Da*q:_bGŇfnC7/.*^ i(! rNa^[>b^`jX(#mpX= ?`ׂsyHgJ_P-- ]&#" \D![Ѥp=x>:YyN| p?f&o2^l^qs.Q۸.|OMgq^wu\po{_ȍGB/,inT3f_7E3 =!69|G\jN9Dj ?V 쪒v3 m[ؕ c_>\ĄA.^+ P񑓜H`ͪF)SyyTJIJ60 z0y3]ip.jOpg\b۹~=*^,gNǺlƞrt4(16ݽ%ΆɻRjBh)/0 a"I  +?X0賄Ϩ7Ϛ6ARxC {Kd P N2UĚ =ڲl7ګ\ZA9GSW)w#ӄ^m͟jn$ߎrn5yNL'/M=' 7X7;?8DY UI-/+yos69掜͍4no7OEq;Kniǭ l:BK3g٣Kk Ƙ*,KQA8::D٘; ]|<7Iw(~EdtP`\\p  oÍ }Śvgw TAw-ïY?N[D+rJ,t Hn@6sU=І8q/m(+ұt3WsB'+QQŌC`B'1ݒe>4%߽?¶~.XJo&_N*ڥY~6M)rS3켊= <^ARfk9C<)2=wv g]ӑUm잁s|J= bp 22w|h=lu d['p6)LJv->F9b''x\}3~8[۸"oBelZ͔T&*~Euaݧ raaj3SVk"**f<7-i/|x L9w)ߩNe]YQy&¦ Lھ1y<y02`/ ;Z!ο+mgW=[gq𸙆LH.N,̫J~\'ZƍE|Մ?K0̯lavGJ'̘!5RGt is>SvЯren39.F>5WW,9R.ܕJ^ Dyʓym7fRۋVjs;O+2 [r[Fp 5eE-7:r3%G7÷g|7cB%W2{=g}=;W:q{qn<ˉmy&ƑifTθR"Q7 WixVòZb lbǷ:6rQK*fԣmARxb,&b.oX3=,%#D\a0 gONO+罩hR?GB}4 bQ ݃˽5omG݉\+1DpZS`bo*rֽdf*mZ<*Öc&#tw31e矃6Άa{Z"c7,>g"zdcO5N*n5.I 0o(h^GuZ^2R+ȣ\9zg6ܬ[.Cjg+/4u0;آbRl;p29FMbo[Zo7则OpG? vu;YjdWEX7N[l=vXgMV.<(wvG<-;I*d?`dA9kqdlm4qLCZa9}/C3$c܄H 5a )ʸWJX^=aw;RZPQ-KwNB~E?A~ ~g{~п?]y[5= kZ߫q{*7eQ 'a׵.mj#1w }nl{7F دʁd!)h]ip_ Kv8ऊ/֋8=ϟ†~;e3 J=б79?О]ݍA_]+wX{ؕK;1356t*0H%+eLqNŚZ:_ϵV'g/6*Ӕ?QyCb\|~x,{K av8 W9-)gc^Ce 5ǘ-c0/ƔYpA7yA6Be?, h1"}Ub{8! kЌ?qLLITduJoh{ G{=2Ą5ezT2F+2pU n"y/|'=WX:ΞxOWp7+Ww=.[U#-ulZF̒YԵ{0qk܏KzE>M0eT=E 4\0(\ƠiVbGZ[sZ ͙Kwo>{);}~R})g%`w8c1l>`Z3<셹G}"jzH<9쎗Wcl#\LƮteŌD[>=A<;O2r.|ˆj0D[;*Y[K3R#w|Ugl5{_`s 8~¼F(5| oH$GTHyL͉4p=ykVS̨ B!Q_ÿn(꧿r; [>ERZ';cFOSZq9ӷkl -~1} ƈN_U%RHˆ6wGի,9WKX1$4cΔ&1׋Oauha.<;ǁϲa -ΒHzbّ;}l*; /+'7a|;,slsЈ'By#.uKGg .0U䆑v<ÍO{r#^lY~NfbLѵ I-OI*gSrܿ|5:蹸1+-,{|7ayp'~Ö ]-iabNk~򁿎E 4m3 \E6$l]T +lQpqаG DHk,~O-~;lΏ,PhihwU6|(j!28}+ WbQ~ * oUkšm~(Vo"1RF.-xwTGNTw72j=D<}We]|3b'=Jnx =1M\ӊ'2LZ Yu[c ovyp8֜CγDt,ƥJ؛sXƂ:vudD;z wW6RFJC7;b6^r@Ln a\n ˎEZ{GI>9g{f},Z(Tط˂Kˉv}hZwz~wgO]e\zGM|8啮ORpP#,鷯:ᤂ|Ww>Җm" <^EjSr@ _)sYo0mjD\hv4ۃ(Lz ;cm6R+'.FoXc m%XrZ#_8桌-l}B^W)[hWۜ9w3m0#yĜ??QZiZ=KF~du)b;)0p2%Wmf;T; Pu/NE bW/-mXʆ?Zʭwa>9b˝rXe}dH1R>wLV>w{MZ<ŝSWZuC3b4TQ%cL\eRqdx^cP;^ m|COisM80؂rN>Srg-dvĕnlɁp-;Э;Zxszf-ƬuGx`z~2hPŒJKVYwDsaFŵjj  lG ħ3 n-6bSR{OtnO-Rse|`CS]]\e;'qĬUג&aH l}*UBUxw;Qd=}% cqn4F +s ?W} 6|7'2?gyHJ<ſw[$2s/arIMLBHhݚĐC," ,r&;f".o'~JUE x0~ak9rx}Zx5EIC|0Fϵj{ʊʪn,rqLW||ʂ4~]RZ2$Mʗr)HT̘u<5̂6 ČCe}3VEh3Li@!?bWQH\gwëڇ0@Z _Ȕpf9 .]>TBgjcjSyb33V;2dyeܳAW*0ʊnfi4d|Z5:.*cdƵI恱~ߢ^a'q&;VB1aY< N+f1Z-X{M*~(<{1u)j^> |釱v]Ƀ6šw[kpgɸRqa8hjΝv"Lڜ56Gf\,HGUQAq%`.K q# wwwx&>τ4w|=;9῾MS7_qN8gD-q[?aZLM)pGtE|0üOX MP|n$ڼv{h׾j17@oac63dm?+lUyߔ39oN357aFф]P59;lN-gKDثw]x+&ԶX%bdZ Xt7nGuzt 4Xq ;'՘]^ѕA.6k^tWמh}23.e8=[wr.\{:;6k3hg-헭V|Ѐv(t(O•j!y1 uKSQ2N8f6Ɨ=UYso Y cvyOO=>Od}&92>:/FFJg8 [4j0]Ly_}Ƃ`wE ߚ/ZuxyEj -oR?[Ė۱#M,pS'1+ǁ-ιs`GF-x;9+1V+Me8x;4)t iHell[Q3\h,ސ`7+ aȖ^/D{A5=6}&df܊ x`}+l+^wCo/4PNv",s{NnD fLd^g(/EүHoTtBLIAnR5œ{J%lKMUq0%O;2=d}^}ts>5"8UR,ţnN4oM]Fr?ӡum-!VoXjE*h6 /p巈v ]xnL*[Vj^YD|ΚI;IOqGЄLqXyȁbwNv;ŏ >4 fRS%-m[S'iE,P | AJ?7]zk.=)¼hcsW8JJUX]s 6fx&0b#PRAAkuxi*!] 6;K^vzvcUVE/*LSX8AR4]LyF6qk1a2/w8sc< n ⾓\mƘ~mF KޞaygotܚZqftno"ϨN8(7=DعM-xM79z=#:ZjsS#~4c ;S`ҖFb髼x4R1\Ç?̄cZ f!CҸT[;#|]dR3*X j.iJU'ޘ>㳔kFElSzO0zt=uhX!bUQu6gp']\>ӱ^9bC95NL+6ٖli0ъ}rkGzuzrY>žMKqҷ4K`}&F r Z6IޭZB־3׀=8: {{1{qV~qb8tsfn6lhuX\uGjQUvK|"9i _1,*vMNz%pٙFL?CmSқ#=}Zr+=> 1DOEvoq'郠M.-f3+&>jX /qK Aª<͋9X19g)ruKSX́KDBD r}xSŴk\U})myy[vXQV5E|#b9KD?-0Di{l%НONxkky&fwon>ԙּ2e70){ <{a58{ 1Υ KTb{-Έz04=řqv|@Pg 4/gbVO͊:lJeᳺ KRl6n0hK S'bg ܍9RV¬x( 6f۰mJq~)foa>Wv 1k|(AnL"T?n-G}chS7ߥPxk&_4cl_vXj [p;pgO1Sļm.L%[.PIJ*vroEWun\Λ|//VpHx3]J򌊟Ô|S3͞Vg`#.+`Nn.mu(3#rWb;+".ܗə4We2k_|[N}<-|IveoUـk)WD]ؽזzգyҍس-L~+a!aȨ y_Dɸp7RZ˹.ZT.y-sz]x5hЌ8eLڪY-?W򼽊; ܺX.GLۡb@% aW{6LLr t*Ly7~i =h[CSK׉<)ԇ󅽿Ռ&O*r* ^}D3꒯{x1۽0ot*.,9ƌdN'=)D!!ߞ!M8쾉!OQ}A(X|N~"bԁ:n߮&cyΡ&6]۵Xc˱WI|AO8;Q QEy R+ce U;&̄) ^L[ST\y\}}94ˇ|"^ʴr fҗe0Jƒbw l߯I8暂-axÆznU]cf̘߂~t$jW_nzЏ} 44 c E^vR!ØXs۟\aeFkj&& بGj+AC!Ŗvl^IɾL06ї48?2y[|۶ǶîN7.`}7Հ4t"LȒp0 qttvmBW/!:-ĿO; Q-;\ 2C4g([.vܫOJA`[@ B٨鞋A~crBdFXqPAMS?8 jadB|Z[lWC~co9lщMDnlɛb)b5? K?nƆ)iZۅLB?-8wKk8pg 9f!*?Z?WnPo"$5:ʵNDC0}cD^ܣ2QNr{#xS9sOOC>-ݳ Np~y&n1(m$h#qQqtx)E{vLNoh=,Rն[Zr|Ea-pfbm[UcI.L u QE'提3A6MskS3.܂۽QS.?%5g– ?a2v%{an\pWǩ}v1& F%MR{Edh'~F5.xx7 ^rz~E8(*ƫC}NER ƜAzٲm'1Z Ba.Wand4n;Mme{:'  J%hxR#=3V"glvd% 0O$ev90*GQ[wr W PRUA`otq_G?*󝚮*ڇ {>2>Җw'%Sj;L̈́^jݩl86ğwQq,c$xf5_}uj0=2xckX7Ǐ ͸?G|I Vаd [oJcB`f)hi"*+[崙K9sB<ݑ ~%=y^.-Lnˋx[*F;0\U!&#;1:7xUzag#6N75`R,_^]X2*߮&Ipi0ݛ5 1_ E*9٢p|׎DHWȝB1U+Aݎi|ds,bk]5;)iGŶBWҐqjSOع! <2cخLcc?SR?yQw3弒MOlE'qc_SXP+Ҏ= 6Α] OW|GLDn'?hG8҇X=V`ëRew.l%:iu81Ϧi%v=bM6VKFi4f?M ^\օԮ<ȗ3-Y`%ܼ^fu!ӅW K+pw=JSwsxY,m"dfwSs:M/3(Yv}_Is;%>Y?yf>67(6 ?l Yu9n5<}lf :i5򧽙(06z`@ }RsD3*NLd+Lc?b̑Μ}͙+"-Oŭ!YNy'C,KJ[K98w}y0[!8!jrv SpMKEv ^̻̉bsˋi^:K'~ŭ)> x%m˕̜s#oŽ',۔h,cNϋ$뎆[Z6ڦk5 zǜGe8>.KeTwBF\!GMm@ozkĚ:ޜϹR.78я/SO+9ܘtav6Q섒1X azSTٟ~2b n9EPH=2j)t˫hz )P4I:l\Q#CZ*3`+p>wЗ8垒?Bxem-þt[.J6>rO;){Q0qX4^|‹rqgb-;6ި>׌[lص0ݞ/"m@ug?Y5fcQ2,yZáiX:lցxVz/Us'TL6i-.ޜ)djʸ՞,{ɹlCR6xe+z7>whoʞj]y|;Coq,WÑ-{Wކ][9S*h3pNwt&o+I#uGZl)/<1"\nS6?gmF;+u/ GϞ~M4a\rFN̍@Nwմڠf g0#Ld``4_oPguU<ʂ^ + aeo$ 4[C'LQ/|zJTDDPmvFoq-k^< H1vU[-VJͱY>֓ sjG`_,0Ob ONzp2Ԗhmmƞgz+,\kVZo8!o3Y֖ڣgwnҦsCOAw݆CEi`Ԫjq-]3gZVo{~ɸt$+T5M$<ѝgXSk./̯A,}ueT?9=.9䎆K(oaˈ6:(G6ΊxGR[uZ (vdl3Ò>O ZM&Xlfk$9E$DDgQ<$q0=~LL}\m9/ʛR_H8Z6R-R.,a^ kF!/6[_z)wyS%-ɭC9|[򠬯3CPy1ʆ[Ҭy'Ȏ2ʙgBl8]G, 5&ŷqxt-,cǕzL<M1-YQM#"V]1V@jp\NQ.agɘliPy8Ϗ5=GiyœK%`}*I{Xbs*Qs'ayzʍvr{IN(צ0u..c?jae> [PP8|7= mJ_aOPܕ#mM z}j?)=L$,a1Sm^4' >$P2*ۇ>zS"g2YCCowd-xرg-o)sdb97g 990^}o;nII(pO@^93At/ ^)HTDm3,e%]%LTrU3k8e z}w-W>0[3o,yqPmJ.⠏[NSyz|Ŕn jPVDZtGFR#Ztkbo(8g܂yG !>k#p#v:QIF1 L߫7e)+%XNl9%9%JO 7}01?ָ1J@C[+A Y z0Ø-œoW1%su<岷v\sˑ:N]O@'PͿڴ1i7ۛ: 5 Q y]_,^lƣ{Ϙ崺ZŐJN7[RZ׀ϭMdoGgwS5{DOER^;:>dQ!-ulc] v9ǕgA#Q]lyYó>"WA<ĐX]vN?R+%aX[6zoo aԓG&x {]U1hgtX*)\C<ٽ$0r7[raT\)Řq.N,8Sj-v3"#.nĿn0%o!LgVXŜ'Tb$LWц/?Xxg8^y Υx>Pf:gaB 6Ճ ꦨfy Yݖp| oNfPuĈQxK6? 2P>V[VĎ<tGiFtQsD 0ZG~);(8ZY χ!r3ק9/@ۘsNjY#vǜxX[P OEx*C8Z/ ?q}!n^,Dڦ"ȅxLP' =m{xj7ﯲU6saF,pElJ> !X[џn9@G}0ts#x;0O PQ!z͇Z[)a JSW53!}U"n2ւcrCjV򲳜O~/=~ w,rb<23nuvG+^Ԧ^6l\Q-#1L} nax.6EH1aW#*/},u!Rn}法>Ws}UJ*RE|iy=;+9TYt]~.0ӟt܊}ݡfǪpL`h,],AdR\IzRb]EYӖ]&-1Z jrdZ|:xS{we. sٱ9v-n]x`f3i'yC|}r܏gXZF` npї_c++ g&\̕(_c?%B9 a0#c.qecRg^xg[!1y}9?v4dUcN3f]Id)+'޿_T2q`lU!`+sƴRl(M 엲p+Yıo?6EO+0e>L#ޝ-29kQgɎ[٪e5XdH6ݫ5֖,9 ș^Ki:HǮ8S/.X'kOD47Cب:AXKC<˳,n+>UbNbS/ >c]AFwOEifvDl(mqy[RCrcWn_9*Ӕk6ZqBcB 9cifCm|SE/2Ki ֈ\d>;/-;Gl,l o n .^}>ՄK@)Y=9əfKc9r7M]F7 ڃ;d6f2\ӡ6WȞ/N5+ܗv 1z9H_Q%سϔc\6୭6rgQjkzq|/vvR3̄Gr2>yׯ坁6fg /y_f/Z>_°<^7ڳ%dɲVΌȩ{WX/ LޮL[]Oh>-9ח8 &zcbg, )w1mEL G3J9:؈ztyi~>PL6{n8‡9~\N5[1W3{Wco ĸMgPw5> (ÎG輱x/~7so]ujr&7PܰO|C)tNXoE+6۬CrIc9F'ٰy˘Xk(Aj=qa9<pU:ۃ͙c|Yb559p]٦.4dve|Y ?q;d=BusF(6)mb8aA9XWKܔY1y#Oq^<{‹3}oNP'it2!ŗqY\5)){F% )+h޺f>)9ÁqϜhYi,}!{4E+Kyon*њy϶S7*,p*DZ'}M&&Hir}xΗⶆIw`f|]@uV ۅ9"O<ߓOdn|ŎXqT4ŠzCGC -G`s=Y{QQ6Rvi=ׂic2QY+ Wƪ*K֜yuYc|'&}LGK)>G8Nx, g2t٦YpKgJJϷ0~MWxrf^uijVGr*\ɅWvޏ=N?TrNmWw}Im [$Flx1N畦f=ijݕx1ȃ X#~-G{; >, 9QwuE Orj.~KFH[15MƑO:Ȍ qz2}GU*VvÓK&z?=~i+qa)(`kO8v 0` )ؼJ[qMښprf}v~ł3RHFW f.Oۥ!Szi6@e;8 Ĵ H30SZ[k)n4bK7ϷJɁ[A,?CŌK\BoT#kS&Lng,zm2s}:,S'S.]oκUrf+BI c4l.>/nc%kI~ - G„4ljA]{9:dvzr6T#0Y)/|(idvg?p@K>2>W1"_JyxQ(N휽o9'\AW)^;̖>;3̃7]89-|sa86=[d#?-%_nZOSE#H 6G'Лm:X)ߑs" ƈW$E*͟+Avd{@Vs!(VD-ؘ95FWB5M}?sbTƠs8GƎM;ہֿTtöm]ٖN#Y u1V?yCMFR[]ub7*~=snD[ 0g |0؄n8U 6,_qʈ|f:u&C_h$G|CgX{Mb0~WŶ?q}N*|t˘vjqHcU%rky?]p ³,dg ߿۝ka,O2:0etFreL=3os[K] $oGMl"p'Í9ې'pi`>6ɐ Q {olöWQ'.Ƽ钁a撀] p qA|&eQ{-l}&q% ޠܪ) +4zl?Z։,|`Ȉ0R.xyտuI2v+_~.>\/@exǍL5K[k`^K5/aQ9 #M%06N1/~b' v?i-})?MiۖL-x.:d] lysc-VwP1=w`:e*"&Dyv=@ثȲ8z)9?~}fn \`(Ӱ;hw+ dTcgvXS%8PO:jGor,7 '9=oa4}v@BĒ#5> K&Ss/#_gĻ5x%5 LM%9(_ACv2&{k?`_1],.|@s;b~o9(9]sB)CTiA+(G"o箔wkN)õ[$3=I΄GRa9 :U2.@_p#qdQ ~{eNBĮ"ȏXMX,]~A9h_ύ;?9o-ϲ{sMVl4ߒ!LYhI9@Z/᭾1Tp~!kO~ZUCw 4[yo&ZJ 7R;4uos 3''NN(&.$rr1i6g"f<X1903"/Q+*݇+5;Iu=v5oiީO ƁRHc\ҴӨzbQw4YPzyς"~ɵ`&פeW$^ vhϩ 1Ƽۄ<ؐUv4 ~ٯq{2fB?}E( o"%nz,.ލd48C cI{뜓wYe-\'ڢMb&~曢}єkϓ U pU%^YRtxd.SCuxiʱG&A?Fc_4ykn(XIӵHqI/=)dz_ftxQu=.{E_o^F[/0<?,`Y=>h/  a)SZƞN՗jm ӜҌw+|*rA.[D`N2QlKQ/CY#Iɔ&Wfq$9mK{>\9%z}A>5U󰵃E S.:YN3tl߰                                                                                       ]hy-7*6.,_MTn6Խ .l#?Z{5_JJV\Ir^]ٮ|침/@gEƊ:φRsfRywKM-n 0R@/E)Zj ~huw>)N=1Gl ú18#}BڞGu }q7K+ٶ=sSfF`yLMk2hoi}|8*"[P~{F< O4K?^- Y1W䛉vmb&*vV1vL7f];sfa%-YvmONp!h[1v1(hU?~p`?c; 8*FQM d|0uD ܾr&4bR4rm\ΈJÅ3)q kǕx>bvH Jq'Ǣ㥭p hp޲FN#L8jvT3ՏY Z5'L6QRq:ky wfwᦜGNC.|eH],MY|N󧏻 )'لYu[>Hר-J7BQMѥ'D\2_)uLJf%vuDWq '~GhP.PpyO;a5e9X+A1|9ĈwG L9_4L0fN6ՙ+yV3u,)[C8l 3,ē>0W9j%bt\sA#]Ħ{Lr) ®g/6\Gl~"RUڼhYOM&y16/iT5dtS,6iu&cq8 G/Გš2 Q;cOMC^b+F&vk&V869QF4g5<;lt oxdwS&\֜Yy;m (TKŚ.l̠ۚS+X)xp$Vj6ORoc"&};cZOVo>p|UNƯj}!=w”2RmM81]6QX5˙m=3\8 rSgx [i|PݙuʒNw3ݺpC1ϥ}o ߡgSz4< 3":b;0;xZYb73k m9 z7+:`Mpk_н?ԨH/\Eo}Hl3V PK~Kq>J?7In$ٌ^!ܸWp GVVXӧ1uќlY/ԙzY҃_zR9ԚOuo}ΨB<=މcx-qmCZ;l# 1c^ `n!}~B % {;SN/=O}GnXu9m+CDI>ZdGq!MK؛{m==[+eôƮ'$M5zYfliz0?4 :LeBtw3ڃ;e)ȫ#cU 6ʥ ݘ]>ʔ>7sid~O*^07NԋקOf+{Yc#˾md3FSj D, A&n6rt \8R`hAy;=- Ce[nbBa<'%`%L7E} |FjlH yʉ]xwF_tC+mѷ%**ƀǫ1ׄNbfx xV7,9[f'w-to6f? 9řfyqpAn,md+Nu`p3lC <8{~{kl4>(UkZK:v}Q?K|'`R)i0j8HUV7gʨl S\QKA2dsJ%6P񚡊ƕnWsA?/Ρs#kY|sŕ_9veGK yNJ,--,i(DcSKksO<5qf}b cyƚKN;}8/E CM7XD'WKD&%c%9庚 'YT>A.\3Dɀ~6|p߄{.%F;7 e|M؀gS{#bK$IC$7!ZʤO(tyo=ϑb7”ծ܍T4<&j FqfW v$Gާd%#s=b>fb#khoTeҠwo 8vG9`hqz;x[+9r~ ZzpvO*vsb,9mc=`$1d&H4=h7FyܹН9n8͝SO8n5m i82Pb7mD۝e& 6V\iQJh:f~}OwxS}'Mw LYHk] oar %caB1Yǂio͹ڜ}A)[d:)eX)tx͟>tKܡYҞf膫x8st /&1;kۆ\L ץQ)^wb,ywmihě|iXVT '9TI[iϫx|U˵}=gZa CƘqҜ%z)w瘲1O󝝌fq9AL-ki :{̐1 j8O E8j!;e&PR*>>vś/zq'=bX -ixB9VĠlDp;jN-^l 05/bL-S1z*OCLgw*Y@{Yῗ̬ށ]5s+͛bv>9/*͆ܒmCc,bW[61zed`Gu^D t#ש5>^lPЛ7򢣊><|ǝǼ8RV<Պ:0[.QWǒ6\v@֕1e4.*c^tRP/ΐtP)*_kY$ZgEjN)ٺ*pZK)qO|=̕sTɋ_xGLQOF9\>kYma^Uk:|n/cP&>A^6/+k|9+FzuC+U GĞP͟>>Ho9@/92{(9az}'twvmq1)[ٲXfʎLPx+"R>!sF*DOUXB < {X|uVbE8 ~G6 >~ 8:ǘπ[о fV /pbj4b'moƂ KV3ѣt뗻R!^B(d\oqsc:ZpF+:,G-x.n}(̥/aQDx︫Ooi%#Ɣ)ٚxş} b3.ܾ؝C=X̕V.\F'}/itFdnN+3C` kbwvutCD8vjS?Gcy[TmǾa>6;^WN1qҒ<7[ ݒmu3 |=9HwZoiEH'N69WnsJO[{H'mNs=jCdgvElůMXerf/3g+!.zF)XZپxX6#Ю+ٲlE65^}Xڋ<甆l5_W3~un<“wkq'w~J#j~rO*z)ʍqz}K&̩X?Ϛ<hԊ&t=?[,bK |87 nE߬x;7?\ãP]݋7g$:%"tbTRw3FOkȔ6‰j&%{qv^Lȋp+=Tmj}=iv^k;snMmvƞ hAYuĝig,Б8G{bVHI[Gli0 f&ۚJoI8wSuezYS.+k>+dk%^rhOWA3o~+6;IŌ,5k>lmHڹhyFW[gϸ:3hHáh# %,+@Xo j )|ɄSNJ;ӡL͜^|ݛWfo&^==[`.rSͭuSQѕcibjn9a'Ö;`G[ob7ICڒ)rO#&[ U=\xROʹP9@ #Us̹.̔FCSZ1+gG+=蘭Ϳ*:t<|h(8i{leBG`/9c/Pozs{W. eAkFu7ᲽQi1&9Պ{ρ GOiʉ䌴S1ǀ2)~ւFT͂1fkݛ yWVDY-X)cܫPp1ȒQGvk˯V<‚Zp%g7%R/YLKݵ˗4+2f͈LG( NF0W/kozE1eJ; VbˊB똇˺]'Hr#7'3{ՖOO2Vi: nl7%<6^ Y KԘms>w=Fcy ~ł h4FHn0#,ڄ- SHOKe'4Q˥=>z*Mif{ĒU6\ہ;2%yr/:Dx6?~h/Oe6^<×G{N w{ovA+qPnV6 Vr.]NKF19ۄڱ@[ 9C )ia W.EZ>pfPri/Z}T3O[iY3JȚ^ᴳ<lj+k;1[TK6w}}RgI(* cތiG~jN1Ӂly;Po^`WawMJ $__17 Þn>_`r.l2>AzH,=w3NWOd+iƞՕV׃_ *I ek>"tRjğ-X6іë^yTXMwFQ!g'^rm+'LxǂφY=c[qh奕׼?Dm1 &jKZ:<ݫqHzf E{%.`8 ;Yx!m2pKw)), z4h y?g n^ԯƵm1ՇowOxa;}K[wq|=oD9vgq1Sga~: +:YigPcj`Avl؞wӖIL; sa4%?`HdyBΣ0iQtNz\S߀'YnHAW#vTat9.^FdgcקbD8i[͂rGbmmb~*K<77euV<*FשxSQ Yu9;32; 58~+j37l)qw.\PqϵKߎW&X0Yǘ_?>;nQY=¿ʬcou`yiufs<\$`Pu~AVqhCc)pY hRN&aoX}ʛ"}zVˇn'y~˻yɑr;ʴyOj Fteٹ'ʋir[ZuSڕZrSk^nKm+7c/b4_T#ڞ}~Mom]- Ys1i̖XW ;R/Ve\ѰO #nN_6̋tM*=9܋`|Or3/V-+|a.8k{p-$ C۸"⧦t`{ry iF<2H-q@~(Lf^ RYN={}'$jOޭ٘UBwq+%TIcOUqJ5WxgYjǖ˫Q]j}Ȭhّ2_1[J34V½l-;euMːΈ' Ħ %27aݳiV͸ᚏOr? jGs ǜ| p,8X;A<[j:إѮp}ˌi߅+) A)-Pࠚݿʹ㑒j/r8=:O8i5wm5ej>{QdF,swIwcσ&q㈻5XPS;1+e%0Ze<*[5_bhA[o2ߚͨ{xMeUdc&ՐaU葍o ۦWc QǎpKo^#Py{tL#WRɷj,W6XE>1uU\օd.؉u{g[s>19M!9Rs<_Cp}D޵cl?ל-x5$% ' aq3b4#wǘLw0ț6ځzܷlqO3!`g9{ BIg z6I%BOZ!OJ(vݍaiM~;ٞcw0B-?U2v [}ð5yfTJ@s ~ X =NA;;c)2OO$?E O J 5^S6Is:m خ_5&4KDž2bZ͌IˊMKߛsѾ{P&5iNL'(qBƬrvj$7}oQI8=~p@WvvDw~E% aʰfTq#ƶo>q w\~d] ~) y>ޘ/b xgu 1XCUߘc53C`tJ6p̗:4ţ WU2|2/UЈ&!i]sFaω]y#^( a2Vy0P,a}7&+9;X.}xT[7LwR>/f`9۫J}d̍w F>'dc*f ?amkH󽉌f4jAs4 s{~6I!CːYTSS89v#_eʚH葋3p)Zd)}j@f4i[LX 9g7Uw_6WM8n#Ōs:wxs1}3\왖mgF̩ㄳF<όSX9*.O^`[8(ҡE7.l/<لK-ͲwxN|bvM}|lۻhT|Sȗ`U V'3FYoZ+!g@=-mVTVC#UޜR1ݦXƒs?93J7!2: k~ȹ򡘒|ޫ-s0u.U@-sHt|~)п;R0áe~R<])?;Z47O{f9мxXxtV9N=o)rte|3S:p '^rE2ŨKOMK\qSܺ)}{R/VK'Kr,,bCNzp->.K Z xe_G3{k5|?*]j|8l1Ն㣪a;{#KJr7$SKp!Y݌gGX7&|sq % 0r.{g-Srj9ƫ͖2|,bIgx;qz+aX<ܙՔIotxK.8; ܄[@u&b+1ʘ&8]Ԡr }`7܂m{fBGC,}clcYMWxiRp[]'&Vt[Dٮl[mX'nO-%ցm\zWA,5Qqv)m$4\`ōh7śKՔes5n)xY!gnMzQ_O{[?YC%<؈ӮXpd)hMÓpd=F ַ8cJ}fp'M=?KgkGwF]uG\Uzy&=m7q;m E\C4ԷgWA,M<Ƭ _ln3\Ra)w=7`z8ՀA4+Y=ao}OjV ;bGj!uF?- Ge1ܙ]ysیQϴXx7.̏F<dBf.IOȿS6RNk %#(mU<-5"NC ^?Y\"JvB4>UD M*BKra!2ji"~TLQ׷>zwB+\kjE'^iLaӞzdb'$W!.,ˆ,KRtG8\ۻxaz]hʍ^+(!gMMR։uW9r6Vl-\h"r!'x~j7v]vpU7(U8%}7@\e?C/ ~RJuhc%flg:س ~@yg=Ʒ-j>7 vAv X.=}-s2}fgB3{b}Ylg&8_1.6\2ݞ\uɃS=$|>Rʍd4!)wߓ3FŦ ?{RmDl;ӃRwaF|0I9#8p.m^fG\5*#p ߔ tl1ڤLLӟ> 17ƺ.CA?8V_ޱQ6lk深U1u )ڿK7tziA-L3q{L0ږ˓^:;(ꄂe=OB$;![]PskO,R6]/!Ֆ}'zpl;{0"Ys֒a_=5Ch  *ܒfFxS21Lta:gٚ ."V4=Vxt.(Doe8[k rj0%GvK}{3wb@ ʼną J( .Re[BURWC֝3Fɽ,yXR{#'H'gg#tdm6ĵ{?ϟ /''3>>I) [Ǡ3O0Tf:RMz2NCUYuMu=l[5]SSiL]JMXbLQT*/ ;xr}LtKUG1_cb_]~iWLœqV7Ԟ_rI- 'W0-MȾq2,h !ܩb}gϸPKFچŔٝ6[}eINJlQ߱l? z|}'xR3su9Y_bmaƜ i%ܔgw Vs>t= sTC>+ #6r~[]FB [&`>V"{5NNA4֠WZ8z=>*=r~ɹEɜ %4(,9)sf>Փw+#-X. ]br?ݐ>GY|T5ܙo -N]]mдBpN9 ,e'mb ]ĘnW޲? ď1N GhsX]lSxG BviS!>Յ[Z9*ƶyٮ񣫐YY%uwrE)c+IxJ CG&J)'R04˃➖, fWi z9:ܝ >p#3PO! ]o|_,ѭ1r R6*0ChdZ̔eb{Ko j͈?LMJZ.]A;Z_VRb-꼩GŸ(be &,:U.cli@G+)*d2+R򝔒R˔򚿂[("g)و9걔ILNlIIeܪ%b9O? Nڮzk9)يk{sk-\~iLndvsM.~4ކwS$??cM)o{~㨩 7dc&5aL'K^iэxtW>2~]S065h] Q*\]U뜋Yu/. adNl+c|aoxM=y7lT拘[Ѥ&#pe/>ZFo- '8k?vK5_'9a9{r] OПpJ&Lo :X ;y%Xh$C$}=碉[nϳKY \ϴ&ʂM]δ4e5xKpWВZP"K]a!9͕g+啄]XA.-*/)M%BWK.婙2><#Nɻ2Q'V\tB\K r:-;m cL8 O[c-۝؅]҅ETpezk^^oğBiW_bc`Ӵ{Zٵ23x)'YZh==>!ke6˒w` 7`nRV7rQmJEW?*fPY"gEJ4SLˋ[(g\;GСOB'qkj~Q0^J-I+ nkLJ|KI`$O9ҭU50lȖ~rv`5&biUdDyw~آSu~6ޅs\Uᤑ736vbn}~[ V˶SkG'g߶RU|:Г*c/B~p| m~Ju'}1UrN}dLJ:wogJw8Z ϝg:2څm$7C<UgV8c p}!ot1-{kt{mFmڲFk#6pe 7n3{vnkBl+tެ ,/B1d%ӝڃ.2dsGoT,K_])3נΘ;VCVKiOK,ӝo-2#0!;)8jsS9k{r'n=iO{}jqK\*ކ4qgo:{&I2 BȚ0&Teyqe]W,\ riO)=nxrTGOBD,sgon;C9;b~"[rq*RlzÎMx X_` fy{y' 3qoflWoƲHK|oşl#_;b+=s@/rvBm;1S׎X5Ҕ]pK K{i|3XβޛuQk5iuZf 9s^WVCr.~u1|2d`={ ۪3tŔOn₮"(eu!(hO[ƄZu章DRJ2f-:F.{-9ИǬ_)tCF_Puf|oA֌1g |ȎBoa]W>܄x575s}y/ 'E r=1k3E4:"qCvI^J^?!7gEd]naɃcۂ/4ԡG= e)EtH@zkes)مB=XNNe QS[/.]%x*hpQ:R4z )CXiVxp'H)?~{@@0FnؙGzD22 :s\m_Kr{(]>bqbVp׆;cgpee|ܽ!iTFvk5E7}䌈; _rLlam)+]y7?YqD}]݁ ڪ`W%K)YXW̛7L}7BG^Cȓm*AV)iܓj:#xG X/嵾RВq JxnֹqbGc9;lW h떍)Y-q qu.a~%DI9s4%min`CF\q#;«O2"0uw&rVP /06-MuaO3T,<Ń-h=Y6`9}l;VƓ*;zSғ)_"-F<<$VaDn &[H<\,}SMؼ؃gXrW{a*4b\;8DJc uA,ߤXK^dRsuJvS[7ZW!9X=#gn7,_4ې\[h˹dhԼ'=)t!7^L_5B_1[FFU+gfbf^uxgͷ sҥf PϠnj5xO>?>tYhF< n5Ԃ,hcylED*ڦ #)H4HݠLfXhVVC^nۭbN/6yFE=%W4_vSШ8h$\= Po#-rܼ W1m|ϼbX=ݒ- 1#o9 [gׇ9Ww#E쫎@1+[XRFM}ppi{bH'j[@wy\{'1uuaF}S:?q4!sM0_ЁBVRW9意Kb \KƗ4͉]JOܼ{ASn\~w}c6K/'vRv>&dx9s4/ 渒'2&=1M/1q%n6e9ZlkM:fx߳ Fޡ"[idCɥ^>=LyfK^wh~$q|E'Xs3$?j4-Fא"_e3݈Mƈ7[0%We<Ѐ޾N!e0z]mk#QPS gʡKŴٿ0([c͹u=wBS䜳VN zpK2&DXϙUXz:Θv@ʇ0.am1eƭGj/ pd^31E2q~{ 6]i=07(_!)b^‡~/1 NKcBpf\ i2%  _?f}+q-e]hsf+?)ͯǒ_Zt׵2lѫun%1̌$?R1/RB{lR]1OTT3_(jUog|2L gx~ =!%"~ vjw~Θ |uͅ!v5 s?1ee7N7;-f0v{4"|f2ahm~ischVDuGwq2$2ZP2[ޝQIB?=]#41}hE5X' J.EOƪlv;yF%2.c|)b<ʠpV##mz -ZV"xT6$?p~2j =C'*]z3O53.4^ c%IE) vH3g[?F“.j~⯩GntƌExw1%l(%莝;S{Iq쯁{9d'ZAϩmvKW[p,v8v9G"1cO^]v0߱w/t$K-Xeup:L>`xLvs<(>]25W3v;z~)[*. ?rn%gl]BbUeڸJMak}(bcQ7̜jm;Ɲt|/gS-9g %C{+و*,]Jg<=,cVËs3ðkF~G~O^T ڌɄm$W+:Ș'cl#9߃D$binξZn8J1s%*GOX' S4:?FO.M2Ğpu15S&!;z]c΁1F.:-)a wr͒rPo)[5^G`"̌8,ހ0Ro#yh*N iQy$<^Frk+X6DeZ& 򈈑?r^.lҝF`1;eF PrR^,g#lf']?*DE^5{)y^&8z?e(.Рmvoq88 y=Gaɢ8#cŦb (c̎GT7xRke z-fPW&$ZzۚYhn M+oCpۜX$tlHöi1 g'`-lݚnM~ RⒿ}_~Xs4h/64+B`.WC?Ǡn -\TLxx?z[/ΗrbÀ v-Ņ2,/G|*<ɗб %F;Օ3wy㘒ӪlRέ> .LVPy"{J8D*pǐs<|27=puZLYq .wtG칛{-=_&y)9BIUr$w҃Q࿁6NQг,2r A Y#]"RV/%[[9pڪ͹B߸!䖞 +q.FaG,\/G b#Z]Spts ,<Y}"u'\m Շv wbZO:k3AcƩjYd?ze/ NKfs>J8̟x3 pxg{?ƌ{_ E?V+1]F^yF^߿{N ӡD.uj=L9i x!ӈgzVa,(bԛ|/*FJ$.m@5)engBF)(m'Vơ[ؿ[{j9A1jRJsM1Wl83_f J1^؜p\9#K6Tm皲(E\SʷrTQb!1Wm3WŴ$0ՈP$ as,/gk9BF)\1Fj!ܜ*<)d,.al)Ŏ|;6^ƫӱ0V єe?b{Ob@ 7 {~B-E,|J\N-8'/j׋Q 7je}'(xbqK[OeP\-Z18<-'wf`S|Ŵ-ˍ?+S&8A 'HL8G11X8"Sc(DxqUA}(x\N!&cE%g={{0%gaDcxi`[C} ^]%Fcrt\0gaܳ׸ Ƌ5<߹1{`I6TșMɒo ft9X߈Om8R]Q혁N!{ñ{X é1kaMؓ:;zy1a0NMe[xEk,УƜyŅC:sU{xpv'Xp5k<Ėp WҚNX 3IC~eF,5%w3v*x!JN(gw׮( ѴLء2K?k9?R0dB Hif Myd9XY#M9RW!r r ]2OBD7fJT*hMKQKe\+c{G 1T0!qRD0WO]ȟAh!'?9 2/1x;gMם]\W{ŝNK9Getkan_t w)t_k&4bw^*B~c)c-|m]N37IUX%~ |C~Uر8ۤ0o^t9C_"[0 ӌ[kr Yg˴ٝR E?WM@9{y Rv8-QR^,聐G]%|@A|[E wa'9ю0vWy<Θnޠp9?ܻb ?|ٙ}y ߷ˍ0ԧ^z BW0=ܔ)żxo~f+:1٣UIiiraJ^.87~:%i\͎ZA7S55bƐOfµ1C7'͘ jέt36~WK)pjnhÃD ΍T0WK/BG_dE5 仕 JZ|J*Yx,"8 B1,rJ9 W2ZŸb[xлK"eiR}$|sbd,)dQ< Z IvwJAůCHL]w#~OСTo-`er3Gf"rEH%@KG9pd2;+A0ag'f{`m .:#3~0!kns~ &08Ƞ[xk1m!aϗrQ5=2Ъikh[^}]աq#zBtqasK>IJL1P*8+m![b.P|;ʠsY\Wc;PKnWܓ-ӎWϩZϜF\wz7F;Z]a& wFh3n g\dI S]pBύuL+ È&T5Y7UNRA{*ks8WPdҊystBfpwv =5!Ԛq< lJX,a3x.@Ͻ<[dXc5PǓt@튬$aD7j@ &;vrں ǧQIMb|*gxp.\.OjqWe8nP`GIu \_\ƂW@߰¼ʡ!> >Vv$@hwv|yG7ߤv}?i]ѽ94QM3#hΰ4W672LDe_)gy-V ʟe)Qٳ焣7_x.^QPt-.:!+Ƅz U q$s2Qvn0@܄G cWOkH0##\9Aq5`p=MB;Ǥ^>#pv kd(aXڂ+d"q6Zzu7tuwXh~ !|cuX?U3/rSln-"GQʠ2ʲ,r_2=8I^bε^ۡv^Rb8;^&W㌛5F4vo#\ Ͼ5 hϰwt#>SBzo"B"AY8O y^IByp<6ZZa),tiGS y@'ь̵ҵV{h݈4my|L/͋V2.kO^w+Tĭ9NXO8`a-mpW8`#nVrp5/ϣCS֔oTҞUtΦ^2 صm{,}Ky%ěG8Ӣ~;77f iyik5zl맆vƫD }-Ejl刜 wQ)N>Mဲsc`bKDo#5d1ͦ'g{jVm6{[o#?Quͼmojp7k(uZEh*kUMMnXb Xab+-ìQhՍ 7D% Ph'\Ze!õg\ {]0~1Z.w}_Wʈ{I81|4֢ 1viX45سL? P`-`wn4߈W̬~Tz\"]1J ݥqU[v''7P{h:0?\?Ξ+!f6+\b.feCF'"dB+po6EjI`a^e ~j8gez6ê^̽j1lyg#dpꩂî96zl1|kxZR X[%ėPC8gXViAF-RGs_Tӣ^Ծ!YN{_1^ݓS}}۰KO^ tysWf?<)jibE[C_FFI->5GT.bslyN+l31n2HI6![>\1 hW]/^vc9#e,8d!o` yV(gl&"y-E* |Ƶ55wŀ}p_f1rb%vHQS9'Ťb|^ tun4ߕf Y8ku+OQlDH6=Kuh㑇n[4-PF!ǭƖ{h< ;GXp--:,cO=~=46߈ p*X"j,`Uӗ\kRG2p봸{J 3L7KcGER)vAK/yd {wbwsƬVȼWKεtTQNh*?rb_iIxr<2FL1s}IGھ, I9|6+,,ccv 7`-bb+_1.LJPDy+עqyu8gd>t[&:0@w-X}v/T[yۧF;ZJK+2LӪ0+lXb3׉yxw= nz#Fb%Z7eIRJ#ķYOC(?o˒!*ܚOo.J)b#:pH? {{!\&Mf(K vx6ӳR5>3uϙqO#|NSwjتB?#b#;|FEQ5U&Rw^M <4A_u GAm*4ò&ztw¨K"DfXJ$.;!d4qXFjS+d5n5Ms. t}_j7Wwנb ^0>F>4,/Ŕ2QP4hEֈFM{ŢBܽ,F9Zp\@Z%&?Z,eٴ=~tr'JV>ٿ*'5tJ-vY zs :;`^!9/˶R +>ԶP/Gj.nZ ҃N/0bƇZ3- -[#[QC{O'jR&QM =ni laW0S q ۟P]V$oA516}O !σ]QGEu>d3Ff^tKhes֊ޏT]D=Xݴ ?; ;n}bvU7 ʝ/3B4̈́,2bB5DȏhKbzSR@)y/}E)|O}$( CZ(p~&hHԈxq-*S~dX%!xq!db;LʳE '[Ék-贺ڝ)γе7wiRc/}mKHό}{;8C\o=]Hմ:V8g^6X~wǬ |L TNr RS½ %Qp }pj n ".Wu/ `^B*0 Eb|o,K<[D?_B( {LbUɞӒ6|;t |0`66ՠ~CrH> PKAo'3p0'?it 77sm;T;_f_+bt-XDZėPl&E]%F)cNp]z .I;K`Jߥ~fNHgvǑqD ^\J,IUvbTnS(LTw[qZ{4U®)J{ќ>;ex4;aF.Ce'{l:`) *!,F}AJ!t/fk7 E.wWE+%Bj+#gc+6Z*> ¹ %ehH. fb| 3$ G|ѺE;  0#aXb^n@'1eHqdy(fZT.\,a&K4?=XNnN\i2VKmnleYaXv`t׷a1CF"@\l0]fI;uCy3G l[6Mla?gǔ[oԘ@ *|$|?o;2ZZI"7)}~sSissch8\I!bNXũR1fKLf@ΘJJ܍u׵LR#BZ8)너2܋a .01\&`eq-!rm2 5#_:wӜu 3(o-}`F[v nob";h'1 Pn!BʖJ_~%CTHbFQ0C˫ hi@xoW5_ C-VȴDZ,9k{YxݞiBt8~jhW{cl3[ Z'C1tS-K JCJ7-l⟱0x|(AO%teN<$wJz.wt&s=œr =<H5jw4SZ:kfYűBxf#cj;)|<8FKK80ZCl[h |/osFRJf^b EW,9FΒf)c 62b+(WBQRSL*Oeطer B86J8rm7Ngۇssft?\IhTDZv)U`|6Ş_o8r_:őPLFYaq>9 J`8#E1 :1VPFW eyN˛!4VOI[>]W@P[<>/DbX%hAllf_]6-{_6=n柡F>ѯT4&r)maUJzڽF`YtJ"3u-lтq!J:0!G?VMn4˫tjO*V#qe)mVޱKi#:~ +Nb$ji`%s8 /mOn 8RHHU/E O(vTbGdfI}ٗ=N}g#6/ah*4z9|Bci2*[Ccll؞u@"H$zVM^l =^B8dz*im_Ӊ6/ɕ6~—4&RrrߜF)4u\:q҉$7(%6CrZTC94h{n;H^y#MVrZ\Mj^vKnO)z M *D0}z1ʐ^NXRdBl-2)-ٯU8^a ȿC Yߘ.|1Lb/waqO>֜}[ev ^y$R~;ép f۠Tµ[, I,o+uE=Lh6YpYhōvXu/E$k/#8f(Nd/kP{s'pĔL턪\ 'Ca1>MZ .YJ#DXonzCͰˉznȦ _ɭsJWx+͍rjܥ[`* iʘ:r(ޛ_;@_%Q lrVPrBKߒ6yP'8GRD F9T:f*$f8y~ظ6ű[1}7Xq!OJz&W Cxp=z [5R:}ឍKvGER`zqydc $?8^a\,.B|vb";kiɖAt͸:6׹Ɂ+03z|!ᙡŸC2,$G  n2.E fiIX.j،.?x|MdQ"A,E. N )-RCz[@8Klγ8m\yz-[Isyb _y{':x8GIc?]yK1 a4+ȣXr6RX`"mKB NT^O"cg]1Q4@%;X}b+,jZJfDeI-LH;6ҩ{!H X:ʥ[K4" :4RTO6P5Ki幔RUN-ix 3GwI )u[9cghuI<=^ñ\3K2I-GZ1$$aa.N>8Mm5;a2;8oWT#Q"@;>Z{qp~*9s h~^ Ux;A;Y 5:IfGEXalFRiWw_Ӕo(A{z ׮|$GpQ=1<\' ൔ8Gla5”A_ύG)>5Bib(Egwܟt_<]+}D[ߏ k]hOo_#fATEH.zCe!8sMGCu@Ҁu,Wـ#ÂUl͸LĿJO_\ DGh+Q孅 p4knj.ӢgSE}h‡ߣ/ɻD(ڏ 6{e띍YT g7uTl^y.*~r+Xz[` +`iU6l.DŽTmG.QkHA_Q +E1/^;.ӶE7( \As_;`9XqedZ/Buaqv̗RH=v6mV#`SK ư!Y񑷈~ཱFhBʜ\@6(rw|cv :PؔK=|5Ô+B5壧&Ђ]uR]BGzFR]Qu kY3 p.1_BW!df&O|إPTqCwii9]cyNV@xyU]ͧbY1VӮc,|ʴZ꽮 $S$-rG-zMqQZfOn"Ҍ9s}v!zhWxxC<)baJO ZAvWc&J,V 1}ՈFS?v}3aPjät9~`{6zX ' `YY`ɾ2aXJA?QM*K}%-GUN#Ez13).A_KY`]=VQ+v 0H*4:KBJ} J,t;}uLN lPV!H0)8cGlztlu`SF'RN\db`; "QbtO`T\50Yjn"%܏b<U 2Db[ɇtcD(dP]9R4/A w9G%T8 "'\f-]#ƀrxY8 ĵ"t$_q0)v>ΔplRF5 rdUmaWS7uv~T+Y$}?iIxb)ӼOTPAeUdZA՛JK2) Bi[bq:SG8-=Cd*9CDIbH(J6^6EY,)FnN~_}-tӨ O;^?I%Y>=BNK&EvNh-Er>o ; $/DOBD b pJ-N0"w3TU'4_$3?sQ^L ܆q;B15b< ƹB4MsOBHM h̑[Ê! aZ^V"b~!nyHp%x\A5Z6`-4SvA\C2ZV XB`sl),>j6UZ!=N# -uo(ZV3b ژJk~%/F4dz5N,˳\_R@O59t9?&ԹQ԰>MXwRfo:|_o3tn=R? a{pE-AL;`mu$Z]Dnb[b= r^)pAKm0ɰ_13C{*X%CZ4Xb1nogi|P.3KSX:z<I's@dߣuhՉ~E86yN~?Q[fnYL{$_e?䚞J6)+EON48koə}2ϟ#gOEd)fHǭB KotV0%F݋)$ZJ (_{(iJp~uDͅniXIwѦP6^\!.B8af"}_K]CK6vS8S^U`g{#$Оq{ox~cldPkɐ .yT舞eWOh[XگHmZnl)DK'L)³SxL {  Q3ÈoR=hs@x O) Z) 'Gj%seh+# ᱖,x2{o7iOӔ-GMGt2ބۖ'@Rj=?%܈P:o"ƑˡK-?Q巔6>Jhb̘/ϧ{`> # 5dlKN>6p67r ƟO˦%h\6q886R Z~9!lZXAޥ3<%vm˥L^ }=mGޟ"<"} >*|iVxJ[1>k} G 8vuï@v>`B < &:K)V?!y`yʐC 1*2ؿš̫"ѭ/w4(>mR &amv$=Rg.FNb=!Âk3s5pHSaP?&쬂leĩ5bSbS#asr6"R] ULRSHkFc}u!5"%Ѥs)%}=vNG;0e=rh =}|F<6w/կ'ar;y6o=?<3u.3׽9Aq+ִBEXcbG^#(!%&ɧtg5 h+KGD 2pҗh:Cw~$sҌXٗ_y(Z K-_@uG9 2B+~c>Gx"qȄC:U2q]SX8V̕!A `j. $4Tfp;lѶ]=:ElSK0gnA+9Hl',M`!vѨbetX뵘Pf3l/w@\݅X[ —\}{9X sJޭ*=Oc(eU[]ҔWe5ͺfsT.|f?AsNћcTx=NCNPyyݦ:p2T?rKgIy0oo 3͂&HbzKCr\)^*!-"Tv+M?( γ}7NZ-4<5`i;Q@&%~N:Ilj{Ur`v$sГakyHÑMn>`4 peYpb>bge@SL6Ȅ'[tVCR`O |xE2<ƾ2tŸ6`Eñt$8FCO_9mm (w|Sg/|0|˟Cqa} ;YW[ ?P3\:懥 Yh[1/+ƾRXaӃ4qº(^ϰWN'Uc9~htKߞ6bp㶯q~ EМPz ΁޸BW~xϜV3QR&j9,Jj8ɳ^~_1kP&JaSءp{V$zZ411Fl=ER~v[ZR5Y9AáF$12IT{dSYaIy8Ԋ ,ޜ +Xk>e-[LiS;{:=6Ds^!hqWeY(,* ?g^oyz ?ϗyc֙1@z%푋9!/t NցYXT>?X-䔕3gh(w&h-NK~D#r%gBbmVܒdKvΞ+cHkF'XrC%7XrlsV}L޽Q8ummH=eN7Vm[a}d,+ ̈B8r)ˌys2 ͶP[Ráb΋e#eKm=^oYF3B5 #,La}q).,,QM&)PRlKx(jZ%j"/=~50Vd(±pxۘ||=q߯]m+{^!3{ \/fY{4Y]ed[Jum }SeL0ŷ (C1[Ģ>=w"O"8<,Yez˜(n-ĽJuS F q>4>HɄ-aR:zjp'ڱFݞsis܉jƉ>~vtc+k[^Ӵ`88>:FQȺ:c3瑷2Ψgd=I)/r4rp/Lٿނ Mjb[o[i?97̀Ӑ2u#:lÚ/=;)d&.cHr&5 i jcR|5Ʈ誠MsU$t.4UnS?PVTc{-)Clt. о6I(O=IH۵C~A$tΩ¾[8 nIzWZ |֩kV蜻yCH_3LsNKuM҆_Y%Ӡv*Iw^ 2ͧr&z]xq9LReZu=6]मjRJjz1^0g7I\U` {ICŬmФk1^@~Ppݪt@8ebpO|IB׎^H絏}{os}}ly+&5QҌsJ,GıS?+ G{^q()sI3$X5ai$}̫"(_]b.ޫnRZl!Ut~T؏R%Fmkh3KQj\^*?͚57h܉G eτyœk#4qsĵP4™0@Y-xDhU[W7t ͆f)TbDo'\b@Zq@04ŊKyОԬqnYRbDBQUe[b~5#q=-2Lk뭐VK9NalWTiWaj/F|oв9w?cJ@R)UxfKyQIٲ:9[\" dZ֌L<$䴟x/}Mo/C>\+/zy\(6?-s0=$~Z|.>:Rce=yl۱/qN1Axc*)RIH4CZ\*d?:'E,Qg[)$B \RTuz9i:Fk}1zf>󜩕ćJNDLwL\fCSf X.w~7Ek= 7vl:k:-g'ڙ3ݧ8{}ǖiێKXQdiaf|TO%,Wc%ܲF󒥴˳|.gxK Upi>΅ly>c9n><|ڨ;ɢ&h%{Zۨrddp_x= SgZn៩ kfr c35޼8N>$z3]?w;<eHE X<- {wH  jÈ V˞!cMfi1zR$}1sp{#fbGa 9L ]6K]ѐ79)Tϯ43B~Y8˅7/kFϘBvudM^!. ӻsp&(SgFtNxt&?*t)EZY.&|Ǜ31w99CM[MĢJ^phO3c{s:B[Z[qD5X1s%{ ]q.fABDZQ&:`K8Cz>~Cf9T-uyBZ ٜj;82Ά;X2CݚK-nJ@Cg@;EJ(XHnR)21BSݔr*][A "au&Tg_A?Otغ˘?W[sa}?;sYw&v('.Zėmh̻\^cp]$~rƹ90/`l/8?= 8jJ1$ ^Ow`Wy' J0:~-+NXm!mvٚl53jӴ٨*u&;! lJ'2׍P K 8i"07lX*F*B"N Jӣ[]aYx%MܝҀ# u1BQy.r_P}ioģ(bX*ӂ6i3AR&hK(K+E8. 6U 1wAjE!&tWq) ;"̮;(r)W=U]zq-.>CL #p%5~0Ǒ;!g+XiƧˍ80TM4]| /.Fix5+178-&tCv/Rƚ!{f!O%& \jCkʎw 2א{I[I UiUтSkD!eϫRݿ!ߘs&nqsA%N%/a~8g`h܎j5E4+]oˏsW.٣ꎅfއ-HM!]oƱ>3A_yGt&nl"E ! KT#d cT}FĘ x׽*Ps}zfh*z~5/"3asNlFM)arxeAL\N{%U^{> ԙ|Jz|ɒdO;G'rHGnF%:Gy'pfw8ۮVt:F/ 80^?쇅9n0(waẻj1d9ǎ.e-,x.eR;K(2 Kݰ/ts6}d.v Fa+߀XSuxbEjc|7-N{KUlDHU.EL1xk ϗ9~%4کʣ)/|u'!# o~ħDF\\17!Jdž2܈-ݍ>vhгZ(/,b|R#ەx "fOW-lhkS",]۷HYWxr5pȂA6f}A|,V́,{J8?5H}C>;.ǒU R(QU@.usE.pLkHmػ'$q1C^f-g8|er }MWmз\# M̫1ACTxdw=|Ɠۻ1#;{%tǥt5>}F, A>n<30o[7Q߂%toB~|>G X٦6;4X LрF jĠNMtNejqVUBh ,,l0IBIt8YEJDM"=tb>wik֍劗l8` +koͳmϨ8k1eEjp#r4A7EbnST*:E'jCnO1/+Bc^ &Itks34a veʔ td17JLG'f)/odsFl㟅+;*f:mo##Qyi9軾 E㝃5czDí}L3:WdoWll0!k\Qŗc~8Kc]^;鿍C{llagKʇ$\Se̜"̏jT%eM\sQ IZ.Q%@ZIJ !GZvI zkT([aO./p\as:_2fy2F:m*Ree*b':U4VeW4_Yi͸1#ӾHw|Y,yIu W&;ƥznK GT|_=U@U~QSvla y/6*f>1h E P!X y*Fcet@\I] ܾ~c~Gs%[ՒPds3iO,ꟀSq!ϨpwhsT"=K"b~=u&[`YvNvH\{4]Wn}6̃}> DQX܂T4[s/#NcmǍ!v5=*sI91`ociգkXP[2QTPW@AMv(VaH55`HjZ{]9ǕpxĔ'tdlW¾-b ;8*+r&aj3gavp7F  82V Do1Sc"Ę)pVG4!+][_&eHQsw>/>ֹj:R~d^!;\Ȟsաjݽۖ ~XNlLT$y!/pV`<W| J>=s7"6Vn,m5M~y2@5' m6l~|\˷u/;B띈D6ie["k 5Jl.ʒ3-̒M86ؘ ƴ٩˩+ecp;tn04B'y+ŜDns_8a3 ?ΕY󀕜k1 Tg D|Z s {۪Hq.^ 4#}W4ꃁ0)݄%nˊ0wg`SZGع$i@:x* )MG _T%uya 91݄~uf!gM򏿜."S]E_1ֳ4r0i/MB$Bǵxw)26Y.ߔSxz"ʕ-fR6\U|,m)ğ~0Uw2/ՌKoY9g>9𝑈ٿT9m&kO΂-~ВN[S-5?ڱՎs8XRcڍn$ŊV 0(ģQSFFbïx6}ReonL/y5g8RV]86cZ<Bq/B_a Umʼ1_Z8nK5K}pLB u q[!֡U&Ca+.0<[ֈʋ0e^>FA|%o/juVWBsT! 1|6U'Co0dKv!'Yksby)ZQs `_E{9w…kY8*%1Ez͒pK&ser-m\/tW2 f2okJ%bޣr8Fޓ=V+di5iOS3l!J/b@'ew:CX!g C~ilgN;Ʃ;>˰c3:||\Q[_ UКɫlX,98R\,G`F1-6q`;*:;{p7pfprN">9%tkJܴO9cBTVM6(Y-yS W?^iP):^Q`z,a)wzpx b/d^2< /ߵ+PEV)PYcGթJo!r^bȑMdbp[rf{᧗ w^[ R/M/30Vjq>R 0U&ir&y6?D-զYGp+e4V,_ЄqYV A]/yfrnlOQQb&}d-dtOc85|s`k-h L[-x:VPR{{68ESf4+g*FJ \n5\ȭ֍JA^R΅V  &lTd]"WJL[ّ* Cdo=rZy8BwffpH_}N0uA뫰N }?X KcSUw% X.dKe&gFyЈ'L9šCkOd cG +: O7{#I@ڹ`fƘ$ Ƕ58o-eSm~VWK^}*~PD E|*Q!Q%o8M_0ejGoC0So7/a>oSkkfMDX\"j1>g ζ|Ҏ-mbc!TiS5U@ʟtAXk+')a]h-X4ٛfk"VeU&LY!L0̚\5 zs)ٷ汵-C{)/AXLgT~9O1jj8ƹg`Z,48Q ;=r

D7i8h-N| U}g쟔{K 0ܷ z?Y2jC1h9(+/I'k99n9ءEG|Rq8}۟F; D_\xMCq ޾ aߔh9L10sd|-/S]ڸ7bZ \m5V h~&QY*eM.V畟 w2H,F }ڊz$hMS_.EZ'"'*(pi=Wc{q5᛾(m6hrb²?5⥯cHm&{i(F@T |aryz/틵yɲ]./ÎKǞ=$OS+9hj&h"f]CP?;6=BM D^\Km; }#ajyKeݥɗ7:EvK3t[sgkpp6o.= ֦A&OQ[j\O'⏗qu6<*BerΑb ?یS/e p[l5?uk_Ɏߔ¸Egk+lgSF4lj3"pi~ӯ!hb5B5\|4T`o)EV`EDj!+B?;!,l >4ޖG+{H{7TJw͞#k=@R\\׻2ysd\ޙ_(W6Jh췊2SA'Oq|iROxAϰGL;Oѱ6 *1dy&{q2w`}"^t!ޯ`9r' |j$QP:+ng ZCЀJ5>XʞYb:WT(nfI@y= 'E0Gd!OtH5b]_om:h03 _޿tU׿:+IR(wj Ij o R7EozrM_&]T )E _5- Rn5;>"M](/F6 G-&Oǜi |u5.UHn_ [03Jl7䛲%[Q)T.T`Hl5OVah >{L9);mnfLhiS=9t57qo5*Pim/4 3l1;~7G':qq[UZ3vo5|-ƕ-OcK_̲m[T A#|8n29wVIaKF /T.yjᨏ:C{i6ͨu}?"@ϷLfѺ0 %kj-=M9Z#$blQث\UZ})Ͷs j9q{5@ bY.Ůkw].cEQ,(*H{o{ܙ{=g9ϟL% yoIEs7 AE,P<@B%zד"ݕ+ͺ}&`nhIܸ-]gV}WgmD{('?xvxCp:? uuqAeE&7 ba2ëz33wI4 }i:IQSV)ub#T"i'tKbcl4F/ڸ1+ 3zԿ0jDv(a1%H9%vANsBM%j }YkD3z0w]5ۅ'ǙS2]R@ht.]6-bsG渠^msb v 1T$"-pzW!E.nqc]xC({|f5.m{Q:D!<Ɓ?(i\9>NoY>7-K)6*\O*SQJkchZzZ]F] (j[!#>x*3k^{ZFgW8mSc+($my1-,L£"Cd-hmPCM%ƫz^*LZ댡]pW@MC bT9bj#'xgaKT{sŸT lt KU>xH)ITy߄ouv u.|rhnir1bc֌!PFZn!e< /8h ,O_Qi;||aOUVoٻ)G(/]2 *ӻGM3PQH1e̩ SA {]I-S*[T%OEH=T.C4-)r YXIZ\wE{OKwc",Oо %L&XHڊ8_FZ }ƌ#uYOD\g/-pS/7*|+4fո.2=Bb&K&'%%zq5ΨpJ.haA }xnأpq5vI?!}&PvFhݹ4b] E-'Tk~FOH2_G^5Ҥ>O:IVK-G ip\+ZERڽXLjob4dJ"[aeh#,f9O A+'V03Lmgm%<ҁ,|"'MUaFg+\ ;wXm+8NA.zTZkUG푠"<aFFg9;OP(!^5*8+PW\!'6~134a^yt8fO,7}qoM^ /.鬚|`NCR)}3ɋMyW5^[-ǔӒ:KATpyOb#S-%6[]aEw/E 'f b)aw i2G〓V\7W5th:~&@Kg4+=ֲp]7epWb^2: "cteQ>4NA5}5xSE6Sռzz(sG.(0=`51ǔ D;O>֊SM/Ғ1Cr>z%nlzˣy7ep|Âf7=.?Ƒ; q}h*(@v3,zُ#j tU@S7rݏw,\21y9*WTj) 0i0 %jĐ8f!1\Cgr{39\.W⛃=n6.D,}=nIq:nE_hhf "F%θ/'O >" ㇓3zvS`n{w,2{DOvtVll^E3HVOv{(d%4Eqê:Wv#kY^ImѬE4)zEoW~}Qz wRtNN@XVpgOA^uL >џ6r\w;rB=*D!9"h bL>s7r6FT<~qe3j)_vct{9+v8^l\xs+a>M}7}JLٙd<\{GFc"X+FElп%z C-\#;Az̔kNp:_)x; 96E?( 7Hp Zrk s:-ʦ/aMKi̙_@'SiT({o0Kbk- ]f~Щ19Ѭ{/2Rtd 9As~ T)oyؘDkv/38Ws%S5Ѧz,6H\0 JhaZ *2+#fq%L ^UOsY 9Dtj{OUGhf ԽRGߢ47RdB=N8G:w.;gSD a)k1xgrJutW9RtqR&K!ưYZ8tF9'QwN}QL"zuae-iFBnﬧ=M>/W|ĿSv>C0TZUU_yI3aU")AbSB\ܪ!jIK~CA#+UW [+|2\b=<=zѠ] 7`sC ub b;I=Q*:[#gv=l(~ӬoMiNWBa c]V_Ko$}4]:chu1[cZ1q:,e Ի.R(Sg-,+t(֣{;r8IunAB1Q6XSNzW5w\HXWZ'X1[E%*SoσO&uXcjYt[ZpF Icj KH)fq<`yƄ;:`+̭px }ԨRCmF%̱H^hFFD53!g%s*.b2H5=q˶RspcxxRU%d st)LNׯ$j13?yFGRpovSS,";-GbhXqC.2VcR*Gw9ap(7iRN\[Ky.&-)A`^pV@7wG38pr1d+2WNcZgt$Dw;[',JK濉|>~"*imṃME(ߔ7z `utj FYgDE5Rh[tHK\x6kx" ߲5 !Lu"U@ vDx0H# ЉT:m`Eo{o??(|,LO+~S~wzs+Ź}nhגs}x>ЁvAFQo(dж4gy ]nɆK|W22X}n|yGss0;$νe2Fq:H<=3+V4gzg%>Ӡs[5wS1P.;n-8g)3~*Suϛ6OY^6خ&J)3JEf',e#%SF<k  ^}֠' UiDLf"PzLdD:,mAwݨEw ўm@p?jp"D~H {(f:" o#=[lVӹ{4WM{ѝQ%C5 `: 㯲]m t 4,4zUE^3S(*slj3$eytF$jUJ\1F!vrVMzI2`/f8"8عcp ҂W *?kpM87D٥P_$ݠd:ݶKn"Jn&2xS߅'Eu Ŷdb,DQRss9r[fY?mPe^V$ǟ |g i[L86PD3?ҭNE4]:=byItԋЗ䴯L jX(H!ITìAF#_qim _W.0y?LTHmC < .`wtpгW: kFG_?)hLz?S92ns6o[>eGvs&b npF2Tw $R@ħ:8J uYn,Έy ^k{Z]<00#Lp=kĞ]F\n}%n ]#fL"6PJz}*Oq0p#^wcAuV3W{)kG,=c;G {+hZίzy&nUG֣j"_TU3NѼ#r!j Zٷj[BP93^%Zj7K WW,'2y G)C) H.F>`ZfwA5=Koz5ջe?s?i4긡l(WݱE_(k j0e>_eMd8ԃtч:%b=f:q浔"O9KGe`l=OHe3:L?zVH\L_ SĎc,y6I+~(+:<`k\Od1I_QEdoE+[ִ P/RO>r-bZj`[ĩ3,#SKd"bLiq+iqĶbsM :FjYy QEh+uBLm NMTEW=i)4aUwF-3S[[<xEj 㹘䎖̂4Ò*:9{ 帠:nEQZvɝ(ylWU4pA}o  r|Se5x珮x1@KsP1JETK1 UXV<-@>1+K}o%!aMn |>WZFc7 G؟Ln[) U=L|h"Up5+MmR~2Hh/}':pHhp/=N0BR^[kUcSWBsM>IkkJbЂy$ !{*2S$K8G!h_78ıS%jhͤz̾9s]G8Fͧ.e6hm[kyxχk_;h8f*hp# rt'>-&/Ӡww 9O+j!An;62zƯ6>wZRl7+J6Cg>k(i ObT8"1.8} CE( \\{nѴ6O&fׂ{%+ķwX=~\Br*&.Xϋi\T*UJSLF*/wVEӭ4aR%&; ].Ȕz p S| P.@5Q`ğ=Wea;֭4aT5N:]7Rxwb jB$eԚTP޵tz s>7R\U1<_F[qmq"ĵh my8HQW޾O6Ee8CdX1PYn$'>ܯ8/᫏6~z kFd^hY;)cZ[M;ז)|!өN*Fp襀uƿT"(hy ӗ8R'H9`ztjlphSRM..'}Q?`:_Ӗ͖xw .X),p͠_91\+3^ZC H%P6̾]3]Fl&1f_3 76aQ?):a)BDG>Qt[5-\Š $VR|zL/8tzS:h˳v(“W"c`V)TThztjvcs`GkK *t~) :X"-`L܂>>O& l~m7=t-/ݬ_{71fM%υ4DZHk69"mcë8hWTjv+ ϠնMF.q9^8ˆDwO`UX k.8sg qh/iygYu6_–Z*Eb)/oM\іZI.NJFR8L{UMftg!ařv6 ki1FLȤ~2(%0hp/IISGChD|و̶S!z'xxاҞy9$)/%ۿqWZ9>8A?Hu>9)!5ʫm,(ơ%tH+*0 s +(]i 9i:z_DW^ӘOh] UecP_+Iors龻#5Vh1I2|X8Ze̓y7"-Za̩lLT >cY@#my^Hy4=lT+5y?eˢQ bO<<~ VJPWtrŭDqò`hGq|dw+;EdZN9S͕+Rr*d%|c|8x2VM!;WwiBj5meab\=5f37UӥjEh4j-HWW<8Ʒ7qC0ZX%4dpWѽ'0:3\cN15\N&h@]v'6f'Z/ ii~n(e 3oR?h. }uB8"C|3DfԭC#`4>me28M">jQB<:5v*#ЛН\bU-($t|l8/Op4Z"1 >~z|?޵9jPVV㕧(R`s5|Vd,";1$Vfkv`9$xK&<^Ѵdj7kr񰪇ZZ C9=*뻤)G^}s;R}JV34><͠F42 c-m[z!)WK,lEQtec  jBNpBy%}QcޯAN h>Quajh o#յɥ1y$]EZ`[dwa/I&m=J ?4;{ߡ6wlG1O/&pj#kYK714MATk[Sl9{:"3g$G/QH=Քt7l1=UOcV+O]8<\;L_LWkeF}n^{%H TjE:%^PbCvИ J,Q8A%-%zVI$EtL&uޜxAUyp!)M+9Va' *@>/¹5FkImFd>u.FG?UQѵ=SI,p[/Z-i82D-ͣ,YJҊ77Q+́Ml¢J^s\| yMtn| ,;{C^ lH 4撼4fͼFE~H7$|Wc9 86d] 4ƀC6bf=lÙ6: W s.%FzW@WxAV l =h'tCz 6pg@it [e|a|.{ݰgK_挖 ^[b-=b0>1 LPC4V׷5`':+ mo'.2xS 7^O+,VZŽ*Op-jH'wm(F?Aĺi4ڇQ֔zm)0ɠI4ջs/ԯ3aFTkvv8|G/+?vi:o*w).=F7W., (y,E{}#ax!ya!W G6! =jwݩ^OuXG3 Ft5se kagrR7&k0 =9_bw Z H Z}+Y%/N! YƂ+B8),lSM~"ɶ4U?gX9cO0{~q|Kt`+IUbm52CUDtY]>Lf]{.Š(cxp[J ތbMu=D&,3޶EsД)0+F*a Oj15#;c QT]on740$)T)/Jbq1ݛE?" LS{au0q><K+/Ms}#tm8#`]BzіmBݠ2ʋMGFN8@F"^BIOh jBo?ƫ&5.&|7Խ!x29 1Lw鎣0B5ZܪGYL)1)S %9 lk\qnii$Z;?,QO,`J.0]kg6NȢ vѓc mSC3uk/PjֵM ytz/srPJVI4#}[t5{; vvĴ<ԉR l!GB+@=DZ:- bks54W|OP*[t"Wn:O> h\EB~}B;{eI MImS)wu 6+ dH!!TwqlKol߹ç!(\[qzzdVP xKKI(:̋$U~Ac>3ugEйm5NF;Ovtw: bD#^7$ʀJ=&3^T({:xMQ!p՟]q1ĄW1:Y^Sz+2Szl.ën5 x>hxX7{]hubGu} ΓޔN7xbJYYLQ`}1-~y>Lgrg}kʘ[A `w-mᡛ=b0Jo+\b37 =ɾ:ŦPIVs0!Vk7JH-AsP55*#B/`A.Z]Ϥ'i1tAxoo?,IO:%>PDI&9DTӥElq+ƯCEhJ3:y, nM (+ٹeTXB܎?h^i= 6Wp^Èdg{?jvd+#@.^8V .+8]nlks~%tΦox9FI_iD mA~wRɲ8gQl NmAMeьu!$hC]vߞk:MpBm fq3> Ҍ,}lbfh̵5:|gTtt6h7<*>gb $؈<@68׾ԑ[5m( -VϦ:E)Y dJ!e p.z~s/<85p6_YMN(aF5~֢G/o=X _zj,YNJwѩhO(wYaWF#`zBWXz/)nE>=e4tYB%`C~2g`+N7; _S Va| 5pUh8WK;R :bHC9TehС3U'p~ye(h.WdCOW\*ĝHt|L >;_w|heʜkg Nu"xܾ9B!:f% q@i[wmQWUd7ߥ S>]ea`{؉\3JxYYMrI., qY.b#KCA]\1 /z*#Jx `^&j{qǶ|#1աaWkW> n~[p%Ž< F 5rt`:5VbW-N`W3y]jH&B=iEwe. _%Z-JKpB">*ƈqNp"r\e邾d`:bg2f7'3~S epb77k 0a5JH:tjğRp]Iw\I}n_ݽhï1t?գCie/j:KRarҨ!%6ϣf,3u}0)N$`I4ä(]7n_vs_ߗg^KI~S#C ^3fu\)ű$I}9|K3($@t f2!bDPf#b1Y# Ō"*%G̹wj3Sϫ[ϭ]U]Ձ>e? DD#RcH1xD@OiSG4Lvdab8=RpGg)QuC*&;d_q-E$Xj"D^'۠ߟ|<ȸ.R]BI|!['Gh!s3YyK}=T7%Etr8 cgc31A!tѐ`t3GVxYk?UM nZD &h3 .=baoh(aIhaEؤZ)5m j23=")6K! Tק'ߵjT/5Qߨ`:dz/#%u09ԏi8.7qQÊ,Rb09!_1BA>CĸY, cT/V  9\ !-s4Vm.s_? p, JJq]kCwX1$mvҘYMLV{IBokk4IK601ieX^:Sx}Md|ĦK`Ay3dQ;f9Y "ؑ'"x]a/{qi&HkKYtLd3g>]|>&6Э?v-GdZ4Mj qQe UE60dz\P-P}vRfd_Fqur9+i*~3)s ہJ"XaZC>.aF%zW c|h-GC18"j q,k'mU@'ua 4 2gFHa c[b! fKi-e%ȮɌLZn=57Vt)vgt$Ȑ4_Ls_y H`&"}q2̅vr'*iq87Yini#え8}B,-D1@z)kW80Pdй" 1FK 88bI qg1$ #18IJ[Cѿ7P%>%6fV 2"]r❆51ŠfX ,9婉t{sX%abl[PsPU3+.8Xk6j4,Ahi&'e\q?%9Y_7E n0Iu o#T,p<"nP7h즘W(i{5j"!iO{D(qh e$&Ge|uυh1zIphz9"\ b6;)f2T3dbPb^wRߔ7%r.LjNHtM:^J!kEWGdJpEeł-01Ʊ4Q"I1C 3hAL qkf$X- k`9f.E)OS>ဣ`:O~dX)CC)\׈hrf=KX8BS:7oy͍Bۥ[)r\NF+/h}. KBؗb\7ai 9?hdk^ NJvz[J^y$EKT\J8!DCj*T駷 lSyU |ͤB|(;鋡d]C.Kx 2X 帺YrT@S)v9qm3~zN3d8_M{Jst@RX{1d |np̜W1n/JɌ I_@ )_@)WETV[J׾p*bHv@7=z%|X+ ex5\g}Qb8%앂7F;XpI&]p5^Cѝ(e -\XOҼYy1TذĘ")!-sx$s`#c![Py)?>T .mZEby8|i[']; ~5j]3nRm3: ?MKE&lh-2?WJ11,S=a3[afFSx*ԗ5bJ˷mKS3Sley D* -m|*foL*.Fi&\(q 41䃺rkԟehI z%ˮO(w#μE7y=g=Q]zIimHGAfFH~v{YO{4n9SF%eT-fzºE,)Zc6Ǔx8HFOэPuj,SݾYըWJyM/fou_fco11LE/RΒbםOx{RSr bC+H蚗zG7 (}zn {v* FSb^V9$85UR<+C7q\']Al_ JU^4I|@Þ å7dZhV"_I-}YT)I[~?\ONTR7$h/E,<2[n@~Jq{':BE:Xo)Yf5҄ZjIu]np?NpǮvx+HJdav]1p'uIc3)NmCkhn0e`>Ρ{]'SED[dZBXBkM`IX3~ѤU`QtK/H_2XfJ0׶J`2PRft I Jv. /J5MZnan '47tME*J atiJv@=70}mE]/@I n4U˦E/5(:CI _|˦T'0&{kGsW1)*1g'M7~MILΏ ?LiJV2qz&Є]4u&50Z811Mp0 }[[Ǖv#M*G@9z12F>r܌GkvrE+BL[V" jw4G,5m4mZlM]AhVXW1%\i}?MD8_%Ba{d;bgG‷&GxxXfIﴱNQF>kɢǔu2n-:Aqn)6;yPrp.%cf}Av!(ի1e4X>I#ȴVeB:Uj i]=MDc =PH}5s2u.Ɏצʹz\+Js[[XEW@c-oŔulXD*KP&ܑK27Phc(1Ov .HU$i)ZCDž;h2XHB }l9 9*jP%YaeΤK~ E >S$cHb%R{#dd`5 MHAmdZMb:`]E=h.x'Rr6D e8^̥TEuoL`a%M7J ^p"W&Q<1)ePw%v:X:YV\Z̼@2WX59f`m)E(!B;1vnAaC7pEi"1xʕQ=eb(%HE3KIa3{ՙ~#l18rK' khS&Χח}(*xi4/mݼdKeXG.vڼd ]qiHW|s)D#Ep9e6URf,Q335)[iFj*&A2)i:Ϥ4vr~J8i ea$4ppT%iT%duE<{خrݚx@q>Kfadб7\n n৏9/Z@w9=,? acXﮋO:zBc'z .aW4Ӟrt1o#T2ܸ.zxhAM#oOT-|fא|';`n2D[cDʵo]1:$@P1FZIpu$h&㳽e8_$AhF(`om`h"j=u 'u|Zxd ў!)|8G?S}}KNk'PTC &YbP ;#DHrWn&M ,>O̐_ ,8Y }5:q M4r _MN Ԁz:hbzl}qͤ׳^7ш}iGʳ=w pN[^&k!}C!\yZaL>>C.E#]7>*'p-EF<ƌXVA7azql9xf/ac,u HjXho7s>`g&kf~~RX#ĨLN"/1,8)ĸ }';DxB >^qm1hiV40s3$[Cx(}^JKKF ޗ^$gz0N`dSP_G2{ϒar窄pu"eXX(Ř{rMZofQ.ª=:a p߀N.~nc 84Y[A^fl4sVı-t;3W~b< ni n #|>> dI\MLF_*ǟ uC"GOFD}%x1U\2㟈pW# W qd7J1| )"DL'|<1 ׈q{*e(K&a[VƑN †m?ڰņ$}1~?W'_l)>\PngӇ_m:)CV9.cjSf~e/)nf2~ )BKQ)\+tb%ٱ_(kL`*M-#z{Y픬E$8Jg(]xbgGa Ra;N۝hw[zѸ޴dq0;M  #F{lp`1iXToeJ#9w Kxs/)yfI/DVO1LY$p)}3=eX!. > o3līx%^0L#gi|B/ p?snfr#3| 3D6#$<qz(n@f5nm-4%MHH4z6s##MrV 0Bs,7\b'!s U+V36~y%4zU1_.*Y )&OuQL׎|ŋbC4J4](l(ueSK,mKIg:ܸ&J%:@4J᪦^+qVrNY7[ ?3ae8ȕaWbRQCĨNegUSd{%5O&HgLNPɳ1SDpWƝ6fJc͉QbTSJaDlRG+񁥀HaV% _k@McȖ}v>I^B0|E\NF :V\T@7=:9WEzO{w]?Wٟ@o۸VR:3Gx!|Q)v5d2¿jVu\I'ӯ1 T^E!ʩtH yWyfXE!Bd%Bt9'Fd .9TŰ$ênR39F ˰˹b! fNqB^uX&ޙ1FF5?? &p5[4r?0[WkScm\l2@7)!>Ŵ4 B>]Lqmb$ܒ!n:D$ɕ`Vz"ØWRPOxgI;Bn`j (W <* ppJ1Vձlq#] 0Jm\YVCǻcH>oTgWqbJ[۫c #5Ƣd,|3({]]4ƷUW)M*.i]p쮣1_ʭr}VGBH4ko&D }ff+$Ă< ,>xzY8]"X}T+`0l^\,0^o+9cN9;̐>/Ϛ1Jm=/:UO}ttJ3>9J/NUV=Α~_p׺|[5FoK;ѥ*K,|hG y< Kbظ{LŚh1ֆca8> vi1ID_ Qۍx[Ł-Lh 7SF" ־bd1J$ƝɕqkR MD6էB#ԑ@ZC:(%5?."C!}cx[g חx?Bliga[7sgy5ʦ1ܝg/fxr8#u%Dg:VR\@{_֢R*U*/>'U˟ NU՗*dM!;=7zP XiqX -lb衧 'nc83<b't.]㣦/Gj:RDajogɡ.@ g 1`oLTMã#,1e) ㍱tV4F2S-o$L,4@ǏB$QbRkװ4W.£pƁGS<ơNA{f/_q.Uuh nH51DMN5cVKxAf?rW hM/u*,EK67t5xJMRL.F\q~,b{aUO{K1/jdK!V"01lraðkQDh)¨|Xr0 -<SC PpW=, miҀqqmjEZF֥/ȔnK\7&Zw[AU1givN@gQNЄU#v"uQl8ٶQk#V6[ð>~ⷩ#N `rNKd8#džV <r&ϑNm]l` Z.hC]Uީ#;л+L%,bc;įb÷A",qBLu"\dl7ǫTKؔZHfa=C2(c07a2Xj_y*d[d}Fgѝ7iCtݒA!(, /o˿ $B[sEb8gj)|hXBiN]k p|\;,E":#B!nd1( 5Ȝ,AAS XHbػ: O q@6* VrOmG)YV4EQt5m]VBvN=Ews<[%ƒ]dgCk83c YgO[4"?-nHP$C%)R1 *rl#[ aTm:Bh,y^@:}<|F)O1*? Eubz@ ;<-B] W!niʒ`P o|lEn<|g5j|bc+ wrGM]2,Κ Ń&>FZ& j[B#I=QuIj0ẂhaK[w=r7/t}-VK<^ 4A:|QvΚq 8YZz~Ŵ$.66@D]}sP`cLea#2x2l&FDy(aE.ѪX#kgf.qv0i;yOMbTIz)J HC.ZWڸ>Pc q/×`Va}0LJhK`|at1N, R"VW$!Yb1y/1P /^'RKO4~3:㤎;u24İl#l 7Kc+6zFa)os7ca0!v0gviKGgA.yR0]CKᷩޮhCpQcN0!;q EL,%tGE*#"?O25 2[^:( a>BCR%^ES[d a s1-1s$46ba;{jQ ,Q&@%%ioy<0aJ 3*tGKgj†=]9 Qk4ѓϿmIZasl2?f L6r !PuJ:h 5M!(*g9ei[~n1to}hӈS]u0b) 'p>ac1L8 !樬.[rJ>6PzjG>*G3JsS#iWm<ƻ9&w5#Ph ص k0E핚XCÿd(+99ͤo~PO9/h[ Ԑu_`1^7Gw[|[C?#2noFJ߮ۿψs|۵r FSRl"Q j|YIߵUdl.Yc%f;s`ݽ98l^|ʢ_wYRĜiGhiqj+=Cg9)i u"}>TگDE>4Cromq0ƨfBTsrۿagF00]pvlcۺvawbb؁ -!sYc-ւY9\|i83z828̎}93?x߬65/@H3#YEX{P5v4@˱844_anxX(v+6HƮtiMK1Neŧ9SfXRW-e٪H s{݌.8A=8J8w'Vģ/>q`}n|Eq'sgo^u4[M|-}⇾|7S7Ӵl2x7rr/-q!bfCS+Et/DAopPEغ~ζfsb䜢1Rn@n&bWsl -C^wgmQ>ӯ]GձDc~g8Qm*1I!XNZnkn`Nj.=`j'Zh;.rq0· 07?ц{a+Χ""Η#/ǚw٢z;nh̐F:Yi)kbN wv\fWy|FX{o ^C `d~+;⫑>VF 12oY;ȂXѹv9^bI~$_VX 0s g:x_ůYiR"h_P1 MF38Z{udE '~Ĕӎtu掼Š9csɅ7pl%ϓ2Fs.y>10f+A qg$9P* ?E|?ЊN:Ҵ#QWk _Ky3=7\/6r@@=[JndiEvsɎY+K*N$g ?6ܒ+4>Xm+A+xwKx.Jkj/#2+/FhXm93M4>s#^Ó?c,"&Y^.id9zz  c-ٚY0a5.pD,?{knсGЅE!WpzK2Sb$34' PRэ`OQ|ɩmRTsG?=T7:<:ۯQzK.kbzaRs>b҉ " I~݈;_aC:'( `֜ݖϿho`Ge#|ŝK~vqCyM>gϙ^LŒCfz+]F22v vf~ !ȬXaib):zMrLU\_=$|$pm+/uxk_owmĦmOlX& "Z$}1*3psq-:%y, =zZ0ז;Lj Hw0꜈~"ZxQIآy ww1c}8]zḃص7}tӊuWh"ͪmy{Qoߟʈ{}ذ;T±4 .'ciP:NI | |遑%̉cja2lM x81ߣ߉(Rp2pK  s: cwNЗ*ƪs^ '5.Va|yL/:w`AV&'xof@YjvO{uihG*Fr]U,+KbnM?AӨ~{)O7׏/PsSl9j6-QBO]$5q܎U3oʑIYy֙?{0=cqfwhϊn ު?xm#ϴtRdfAEm+h7%W.*^nu|=Fۋm"I03s+(eRnvc,oq,Qس{`D TbKxBªE2.~:'BQ;1oz?Om.}>HAt![1/cO~T1ĈR% o%׭♜;`1刑oZ&&.Qs3_tck.< vbbu+6&Nm%300L9OM ofGURY>ezbu^fbڟ"okbOآH;|!N[9 .7r";戮O_K0rq52TpfxgF=S[9f+}YɓgwH% ޫ #_g`΀ Fó70K.ϓP#Z^/pr=p3>Ʌy"w+y"MPg'3EZ;^>Bϖ ܵFMǍzRi{hWMHǍ)4pU?u@iuwQÇT,ڤRɕ38>I̅¹{WZӐ„|'?V1)Bʿh$&)9IlyFFR ,‚~`W!~Nt dŰvQpצ`"|ęXl.%]M6;%g,UlV_K)~-"> $t(_ W:g!ݚVz-PnI.Ut^Kr8TofuCG!VYs99^b,~ #kLQ[hN7iG=;jgfhtkl˃\(]̘̱2uMl[L~ZzqGGymk\\{"9{wpSeaIּ,p[,sNs_d]Fs䆖9STsu=#R<Ɓ]̑'9r'i[ہ8lrZZߧj5sOo5Ӽd!& VX}ƽqh^Hi5Ӥ4&ဣ8ǚefHs]1z4 u Nl胧lXu̿ɵ?2T2-ar.v% ?]LVlaVܵT6B}|oWqhW?o'e(jϪB$NO@Ɛ;=kNbs9^./ä2[aO6ݗh:Y͔͛r'ߺq~w>%o"t31 .Q95Gns0Ǚ8+4ebtWc%T>fxdȇ }e}OW)lbVE~rZ)X^O]rl\#:jTlo㪡F;pƝ;::ω/fs)G6pO\(̬sԼtYOka %#^Ǚ*)t~8;Њ8le8 k'lvVb]K a+_gZSOt\[zgB~ǃ'fĜkpl(T¹o ,i:g` [޿KjKfh#[e]miŖj~:]l+[f*9 >Źs(D8NF[Dk\=1_v԰x :&H75|cycT91ۜa, CPKD]! ʕq'>a< Zn樳*p0piM lǎQǕqbl#"74s{G#B%9@˦-g9jwK,8sS FN%$#|*q1|*X!l\&RvUH9|-V;&*R- ? JtK`șf_7j*WjxhBΫ%\Cd@ĜTÆ[0Ȧ{`㖗8Z_e)H>i/q1:١xZ/=~ƃi.˰]Utaf>1+-G񑎪WFR\pN§6h;A>ؑ昹O4hW0 |@/ zUǶqj%G,h^VHäWX!fK[Hc|^~h5;hXˁZV Wh=qbD'Lq s^R܅v5<;4֤g*j τi9H ~!g*:xໜHW JcjO Q8}A)ZfVp_syrK>8nM:OQ31@LL>Ma:^㡍ɨm`EUK -~R^7r"hHͬZ~pf /@Ky[ذ;.uaNLve7pelw_}icj(뼎TyBƺ'-|vo3 &Ez5 ]|n[P~#sXǀO84IW.]Zr}ݦȸ(قU.(1h=|Ļ._gh6N*> ^+cd<6˚yy(/^e9~lG?ʱ=˒KBlyl.u.F.mO~|=\5R^-y;ߟra0Wj=hԕ}]YBll Oj50N8FnnǃzG8zm{GY2hY<ӢIv6j=i{& ^bk7Q3ݕlD}u`|^AlU̙\Xk ι̜f2r -u ofBijbhߏDKwH0KmV4vdžG'qGiF<> GTiqTqQ]bn6ފ8 LħFz*m""]qfLWd_6}8<=z USozo/ uJK>)$ľ O .F*\-fNJك2[`d; N}qNdyaǻ觱c F~hNlcLMĔ?jyxvWrװr{}R^%sꮦxqt5nnoc=kp#z9sbmWbo8q3U!&^ ooOCjܭ0QH1_F[e'+q,-FmBuʟ"a8|V"V0v::G1=JbRD8K u bP4WFG[}> {?>QdS)PdOx&]+erkOr*9/P^5ߎGe6fBIb˹[\ŞٵP4 _;h92 V"S[1(1^[ P1"БS1Ǖ%r8kTnbT7ZUWJ[w/ftf'=6q,~-:M݆WcCQo؛{=KAnLVcaS+Z15(1'q¥Iִ+P^NWBOhdgWfbD~|mIq7 ȇğ;@򃒅Sռ2v5YĂ?dS Rs(nbZFqB/&ose;&\Mٕsx5o2#BC͞ Y;ӉV8rB\#a&3 $ٰx]#-Dliz|AyL!a0Sô:֬/'p^+pz^T- 'Mse]7&3_ wpOkY[aճlotb1\0IދCy#\h}#gFѓrƟ =8Tw+o֡wNL8}a.ހ[in{ ygId :wxVvyO\_w/Xu{=B*F@t! 9ە .'KyMC{^^A|ƓXL6L[SHp); S~~68gt,hmfkWiЍ1n\ܝ;|8!ӗ'=yΖ 9{tUj~'7~5qW'0g3,}[*qy,zlAףOaRFk#vyA!4t҃qiU(=ŒWjS^#m^ڵN_r+T*4P, |M A()snj>6CW pw0T`O"cb3ep ݇9g׍]"'Mpak;-Ttƒii~Oe9{ $6 j3sĎU+Ab=𳑲Tk*I&뗔ށ>Ãj7.fЩ}N؝%ypݍ3ܨk4׽g3[ #;\{j!OJ'ٱޑ-ỿ30c6q<5fh}Ds*ޚ\2c3g|h|՛W֠$Ɠ%2~v`~ C9!&dv`b'g0)GVbQ@"Ţcl 1~/JGAޡ4@9 +ZCe\9Kͫ V; nGy%ԓVNVT/ccT(쒄|8hѷk~4ʅ}\Թ q>hDĿ\tH3>vޤl#hqJnJo2VqReǙ)R#p W>zW\ۙ3* eXd ynnnGn taɖ?Zh%aX-5i'q<_yvn:ؕY?\(v<,H@p9PpsUJzױU=gkY>KţJ8{Tr0.a(C#84+h?pe%/*5٨nRѽJp\ +?w\[Y$-S}r=V 9o>]߮m h{Z.C}ٸ\J U5LsY &U*>e`FNH{ #)x=k;qT +nm/0GHCKc0 }ks2&/@2keF LH[3+تXjnwWe~[l3]ΔH/O. p8OZ}!ZzU+$o+׏rfz˪֮}`b0ޒs@^`a/"a>uUï}U[ ۭ8:2sd^YTo8O}IBb7ύv_,z}9m૕^3SX=yLߴ\/Őq<^~oK3{32 nЪKt\,Jn0gLhf!16ÆZ*/kކT7*qlr>LEn Ca{u nV ve_-_gmrW/ 9YrJ_"ߍJglƕs;†g`ȒӦ;B;sEG;6dS:+s*a\ !8-K1ӯ AJa欅v|9^ɂR洔%kiK4X5clh$zש@jr}^R{&{O&xrE'wrՅxr(0ZƧF9̑q'=q.=q#ϝsRCṺkL8{#{S}"YR+ZopN: /3rv>dNC9TtQF{~k!q,0wNAv1zkK=Z:($1ih2֮Ȃb[p| tk$ 7^͐zNMC'~5k=/ixu RGD%q5ͥ*pxZ?fN8(TΈ{2r%9JA.~2HR=֮âxV/j3| ~tJ*YaKչZ W]eH(HǠWsr:m=;z697OArvoD^l(8GowM𤻟{ƸsɍI]]VpRFN󅟔m C.f==C`C~ߝy-}iNl-8"j0t B\^+ꂥb_fV; /j΁u93;^0QgrJbfXR<nŸU/p;>x?֒1l9P)lڶp^ɐ%rNe\- 꺖ի;۝`@DMNkQK_N˰?<Þg8K&x;6H5u IDͫyXpͪ+júwg-?2#ўOql/vɄ w4`mߍz8T" sC#UgkU0p?GZ{lkpD/%mk/_F+y~+'6z_8C~2Fыvxt6G"y R3`ƟX\4_E~a͌PTuVp~G&s;8'zVo/^=/\ie2J%<4Goib9Z⼂yCS3|L[ŅEoxhb۝7!xC;| z`?)'B-Ex䥉)y&lc# :͒rJt/w]Ş -#n~wEF sm8car [>%z]0$qPi]1Z<Ģ-č\ U\;́z1o.3M=݋Y_8=̮mlk%ݛ&1(W2[Upe|dJ.sqw ^FytC3Pg{!7 VH8啚ӞwVYȶ&]523UtlVʖE%F;1\w . >z4wkĀv ˕;+Z^⭶ ) nNǣQs o{#1W,}Ȁ",EӾ߱:2I2Nh# 3G#a\w-W -s`~gpb-*Ror;yi z!&w}ғ5޻ӱnFeZI8l?PTǫC-3pqm7L~vnm!-1, !mU uը^el":1QJyړ]h:f =uIy-e\zBʉe,.S*(4sb[{~)8*seKmT 9%#Q#%c ( Qd$=Cع>W0vûW>^{!  o^\t]%M;ցeFIRrp= Ukq|AM.<̞<ˢ|uGɏu|)C9;.ت[ T[!k ԟ'ճiпox]',5nQk}jѫUFXWKV^)tZ,/ņ"gC§<Ax7bg1c5yst,y#ݒ3FY$+n4sdwV 䂧R7wΣ$Ű(wg1a)}4d4;#:.l1Z]+59ڤqown~hit̶Q1 Cv8C)fP Fn&)? +Z5iҐ-x@d%y:ȕj%4-|ŀ7MOB04 ;~tx 2uy c&/0C8Tob!u?nzV',ys[2ޒ/iQ!^FC_CQ,+ p7>N6~ MM[Sb\Ѣj6_b!&1`qm.SH̽ 񅭘0foWAG Ю8 ncpUBuۼb,b sXinI;-;OvOI-off ȓpcOV01}tᾖt8>_×s}."l6ԥSP``R"S#+"GW{̽6 ^E8siZHb:ǀX=[.kcVD-[yB}a/iǷMXǒ?#3/aviؾ<K,㱺czjbӬX o@aI4LҒ}L3`«b%cppzKB9hG r_2J@ܷ} so}ohntqBϨZfkA!71ф6a}N|K͍F|ǘy ڈ<{khVjNaQ>ڄE)W"u40O-*\x&̓={ksy՛K XA){f~fI4HtL;k0-gߧ"o 8|>FbAv<6Cəhعr.B]B=< <{bH]mi~7؆{e[.a^+Ž!<6 ~}`Co կ5W.PH`qtP[Ea"kuSS*fuvhq}sN 1z}ExҟCNa܃@V/A^k׀N=xf7O-&s dQ]lngueϭ ҵh5g6-w_u(ι Kѩ(GDi"E#Mccjؒn6ƋQf[79(k BG,ݕBb7m>K~B~h3HK렼V1qSN-A5lZ߅.ѼO|s>aAIC+.fl]YSZ\`\uraJܕ~ ۝Ŀ;:9+E"L0TǐJk:;]s۝; =&̕]ؕ8=Yc14d'Y- iʯ}¡oЮ32> ]f#"SkVTMq2)[qb9T=Laܹ͚-cydFWltx/W-[oxcU8y D ۍmQ z>Ƹ{32y HJj z3ge3 Tgc1K"~n:g4bcf^qTB5vw 0 S-]$.fJv؝W ؔ"^ cX J.X%Da_lMBV@(-f8sSn1`xC&>gBBub^.JxK9ˋx7K_tppd˳ R1=%{L tK_:c` "lW'NMĿɑa}/W0DK{31v΄D}ԧx%vh)RVzqwO~7i80Lz [E2 nXȠ *!zUgZĈ6ߝ=*) xw"`b kPT*xla/I[^l׋̤)zVw~<#6,cΔ{&9H8/x؈kZq9MmT$W!/wJh7ؓ!nR*w%]*n:E.k^ËDܼKĊ` Z݀V\S}oX,1M\CM> q֞|T|}=)C4F0)g zaϵ8vac=fZi6Z=qQY{srq}M)lC1-~-_cr'|di[9MȸR)9#!H >/q7i b[3ϖbgf\vQJ_n 8{+zI߄-Vlte0Fw-쫖lȆma{EcQ2:Vu^6f 86{~+Ѹ=W/%p,cSՈ/O<?ce\4lAck&AN&x I+(3-Z·ŁlWIt'<@-g"sNpڬFlUp4GV7ZYu `GwEKn+aL*h\+g'mUE[RΛe W!D)Q 2>q{ji)gW%R:rNV)8&`ñTakv1' -wfȘŇ#fw~<2_ɳ6*nUpb)V2} J.]?yGaɴt{hTaʻ 8Ҳ"E޺ cwעm'=Ɣ|o)gI' ŘOUy6Hͧ|5+wf'|yc4[Vs eN,SBY_]Au!FQm~B8E{|60m΁۵Xٴka0{Njm\,1G>dX/qqpWbz3;3|#Z^R+ce Q;.섮 LSST\ư#zqh'zy7K&K…^%Q2XN0b~(KQTl\uce4 VQvΗ5Ǜ1s~ :eGz9CGɮ2~_-/{>ćU<]0c_l UfԄ]:>(XE5hУ͋̚h5ً)R%yqЇNuEAwM}6p~ 6ZCvq",sd>,,ǒ2$w.}98ޔZ nb$|O{aoP za\þ/Ƨ(~N[^O&5N wXF> ѬobEi z.$LD m<nG[\9-֓/zs oV;(햜jBUo᧌圷Λ2ћx'sH9Uߎ 4W_Ql>cO3zo5>Tpf˩ʇox۾I9J?y#lx/[av |a02πzv6Εodͽ<ɑӵeW;Bk2kOxo04?w̓Z^w&dzL;nQV\vӞ]iGJAc,DW9鞇A'~ar"fZ0]yP܎\5AMw)yEx>[ڕb_f ox:ׂ/ڱ_Nawy!MhwSq/o۫9Q# Tc8W}B[)gZ/2rTG<8-ˈ\qǒYvn>HKf}/VZ'}-aJs60O NMg>8ɗ3r|xԏJ1s$ܘ`30CfO{ܭfn&-ڛuLk=4O3Q;KY!\'`hLD~v"(ݣF\dbv@gBVXV'>RC`Ś4h< }AJoM~O&upRt>֣+\Mp=/KbgסZլM,\Ug\_^XȚz7ƙ. 8N\)xV[ŝ;Ṫ?UUz_*fVsW},8*%3?27nɿd\2ʝA\>?d7 Be&_jXx94}x9v,LuW}x_GuI3OS󎱊<ЌCB| 'l`0ڹOc0jQhVT1a0]GO -CuX/f);wa[8.V7gUzI29 +80oKa!*j?a9llA-e c_7W1ew}lE[pG39Om͙%[^pWs0̒7pg?˩}}n $/ T/Ed a31hz^dxWwf2z5 11Fυo!V#c*&7ԡ{/-̙UHS5/1a $g5*1}&cB;X8W* sӂ۳E׎e=<܄ hƉC$P!c7\C[yMpJ9 a9¾5HM[r^_+^CEۉۗUӛse^ mƓA~cr? kƯ9#\^qj|d@_S4K.{Uf_)9Y[D_x4!wngK?>Y+#oHuw8GםIQ_ӂsb6;Z ČF+m^I0iu8'^ngKQ=/ 1&Qs';2 pude`2D̅,;faa2^јd8Nw.ݨ߸[k[qs'^WRUAPuqoG_*l|N *DUL͇cn/qY?~|Q͐zdX2 ˚~Y$TBΐrk+t+'7Yp`3]Z\W4{ ]4`(]G!4!;R9: x| &/O7{\0vAV,Ÿ/@{O&h(4IIEU}XQ$> M(hFIg0U# _9Z1D d)&]ZjvSlmY M?엱|mvjFk_Y9E|䰚7|;SK4h]8p61ҔYuvRʾ2qUPbjznNؗaҌ-|'U2n O ؝FEwb~x"!#4e[;&X~oy_Pksj\ bhY& dU:MGdtK8 бl@ߦ䆣#=lvCǻJgv(U`+*ǕTÍ6|`AUދ͟qm%q$S/4c%=2<”H!yhɖ1 2P9WRك>"Wv>IYR%tmRť&<;8s%#qOZ'wWDDkBfma ;#K<:^>OGw!PM`^TƌۂlW\MaW ûT< 9=h-4o^}VF¸k2sKRFK֋K[=8r T9rCfNt2c6mik"^i\} IL)( Yf`HHΔIcpcO Jv0:>CMƵ+h kv (7ex& 5zS qL|fo>uI@tx/- r`Ygv ݽos1jA;l,Aƙ+飩f\>++V% >b/KT̽fy?~B> `q g_r&<ջur[~ &΁e:$y- X))1 f`)cٿջS2B V|TFj>[*g'r>!)= /22~T!KFXoZd+9/zzr{+wsi9љuLbN=/7Qq-.  YXo\j$$jcw5z; /~_qu: >b`oloMozU?,4 9'p+\ 2wE127`JV%, TUYdax~7wHoJNnKwqUr1ܯJ&Цs6٣gk}F|;MIvBO/񦁍m{u30 S&v'|݆+>ejRi4:f+)YbKO %]h_3Qs3EɋfH8j;Qʺ^ɛk \X7Zq砓n|m^.߁66L}fF4,1XS9}iqA|M6ޮÛc`\>nMBO06j&v^zo@_y)ǯaRHV㓬 ;oADnEJYWA= f|wwVa^]i[}N*lR(֗b5'lSRg#ِr_ton\*r ݫZV]]+;:阳}cb;|~ gECԭ6ҐR;9ν\~Z›h)9*i52zzq1/F& ݿʣnv(zppO }wΥyTv|1ӌE^MEm3+B!|ܠˆ^:\Ci(kL_EnC!OѦkiD-}3hLF+jqϲ ɿ0FYnY _qk,ɧ,4Vж?Li}?+9p {@piW FᕏjΗ𔿊}}y,|x<Ç+L=m% x>œeHξJZq%NÍO 2=uJbLyxfdz)o3C<;>:a%C%,ӛVfrqq8{ `ץCBO axKoV1B-+C;53'&J ws, g}ߝ[R=R ';pJ;^5O0ayocJ1JlB^ k4AG"%mfkxEmg5~mHb",gF`_BGRBGMk@ozoڇb~gg(xП78ї/+9 Sr 4Q+a/7uoLmbuC57Cmm5(͊kT^. F7Zxœ"q.fk9p)15i:2]1gyx☌S(O#Ǩ]ƛR>?ERn:d#on͞L":;_p7^1k ‰wOvϙn?Օ#߹0{y3 }Nk^% {ϖ7Xr`14BSUE(Q'pfg=kߍ~ww0o4IG=1Ehh[\X(p Z0r/e&/bvʓ}\YkXVgС97?N?DnB1S=,<2G&XM=8AsE$f[gsm<ڒN)UghdB!S/zsm+v`p?wӕEy57w͇]P]&l-v#,7ܧ'i1j1@L0g@KVZJ RԹ~T"+&tO֡,tKfW,7tŝ\8O2MThs=񦹿$zpl'q㹹žAlӃ581sܹԍ?/ZeJGN +S;sFXr/+a);DgS'g9?rbmkw._ƺR\y{uMK4ZZvn 1N#p? 9'[2 .t06l+ mo}!%Pѿ)9G]x5xn~ Zf밍;ɘWj[>4KJy +FsS?-OmK.&*5_$vz읬ca&l3Ì+O)ZMF8lӌϲWHơɨE Ga(D]0a=z7y{q,٦֛u87^p5;-TO)=nH =(k--C]8|;[r-Py,chiYfSO0]͊96%7Kpht-̖czL<a옦o? n4ĕ3zvbz9cn=)k<ϗ}8{{,ĄzK%_aq"_si{Xb3*Us؍]j>^-27]×\M!b}# 4e&f%1i1.O1lW@e:Fk ޭaZK 6;S0{d5Ի 1ԁ¬OMWC) RQ9~ ZÌ'ԗ۪䢩*`Ge4= cVaXo|ӪF jۊh^.(;܈58Aqܾ-R]pz yGcm|<⾧_C7f{z'ѼQ?C%kjݛo*G)R%Mz񇟔y0 ?83FaK=+]+Eٚ Y g|?À~M܄oW&pUK>7\{Î:V]&lGGPvv|M۴ :){hBa~GcTC P,6gLuŎr_SRbJNѻ Mڰ v&:*1s!M6XrgW)3T!tu+? ]xpz ܡo«LE}59y_N :L1grQ52ޤ}"fF߹dKQәh"j!B&CC/, ;:ܣgM\]yCX5O[9R{,CQJn%w‰ Q1Gr'/YH)r gḿaT}gȝqgOߩ@mt:Ȁ99Y0CۆQ&fԀxx[[}ӨnI_\[w#"DM튑US]bǮTzF)!ނ~PBdaУ8H>gbG Na-8.OF?s䴓ա_'UHsFe fbԆt<.@)d> 61hfc>ʴ#20 oħ) :y[{G'*R]n~r /ұ.E[EgAOvˆ1xK7FdA&f &co)Y͂`->|_S l72l \Y~ӓϋ\Š. =H%$t.Ņ61[cQu7 POB'_8YVa5  4/>O :Eo߀{!Ա+\-n8q+3NJxCwڊqc9eV_}E颇hrΩhPz=9ݺsĜ#T̊Y"%xԽs=wWEuvZXZx : ,ÍI,Чb{>lѩſ֢Vj-=p7vkG.aǪk<2'wj`ZT[ ᠙1)ίsn|7-D%8Ff!Ic1nnco]K/MUkZ: |M8U?2 ܲ>944qtpYO1%q.V\vKɆEkVz LGÄ+ P{/czZt͵;%x]NjR&.ƨKEuė ؜G_0~_q+1>cܙ5E/h~cSC_ѻ3-ނIGdnkj%``op)Fg2/&N0b]jBʍJĘpm.CD"5 _0[dۋ܏fX(WnJ[ERGx63^vYmұ'+^U vˡ)~@p@ _4 zZç{wO]k&P㶺4?^:ѫQq|QɅݶ83YKSvc+M-9ݑlZoV5yZ}#h}q`%z_XV&-lCItه~^9څx`&]ǬU\qa%aS{^yx*3׈N҅Nvt+5;_}Njr~pCN5dAmMt9)0'JGܿ_T6iPXlj0[Ut9sz9@RZ.VeUQH98p[KEɳ*L]9ˀsX!空5gnlۦ 1v|U?MvIIu/u@sNikĽErf֓sAe/3&:=47MƊiY_1WT܏- Η2ǜG3xs\%k߷\rt~=]P#wR2<-}_jqh.:#bt򐹲"ʰw_)z6w-.۬8FUT?M>*vCի-޼@Wgӻ< Tdi|3 yE̢>hFZ9+FYsGv*"4뗎c^c?18uz}X`ңpyurbrۧ>f~1ϣf.cJ}8NLǏZY1Y+ QRRҖڜ%g\)r#gK/XUq>u8}/c.rM)s'xqU)Blߜ/x _TךH 6U!ڎ5AÖYSχC7{s>Or#;Ǟ4u^VGLB߭YP~AMCH!Cbh'kz|\,ʎ[Z S3b![T, /RZHx+;K;< ʇny6UozW`L]< gڌ^2Ԫx!GV>YP{ى^5և/⟳j7GkLLW+pnyl"v >FM쐶DpuNkf{7e--+YwAa1Ϸ)T" +J .<J¤0ys7U!xA튁*'rV d]w;nhf3´JO<\D˔BthQ% ϧ< 8n8rݥGX~T? /|*3b] 6a+v sb|{Ãx0o\ 4BkʙhG>q \ \Su/4{r).kf&_0bp}OĞr+^h9όjcQ]/ V?x7JQcS^P7x}UmbƧF~+d"ù_x„x<粴پ_qCsqϘ ^lm ;-~ w*Բ'sݱ\·n,8@^G\)&Xާ!pLdgirzwgGZ Zb#\B N 碗 \+nj-NDhx' ޡ" ypMGO#<뾥z dlOܞ\=,\g``B'Ÿ#3{) ɪxaHGO=m..90`J `wT'g&M.d 嶷Zl_FFܳŽ9_%߷Ҧʕ~ǡ٘I:\fLPsḱx=͕ z\2F9iyp-C稚yS+hRd!^voΆѝlO}6].ۆc|heLٰFΜ%h.W\^M:ݛ-;Կ{ӇoMԩoE7¾Hoê9 ؽ[ΠKLxU'CnM7_~:.+ǁ Eo= lƃ^=}vl·Q<_xlfRUwfp0vib6Kߖs)]ƬxiJ0kNwslp~{~|  1Ț ~/#֧ĭaz#*G#H f.'Bg6GkqC1ڥ% e5I߽VN궉 l_ bSZmA7Y tm>GtgKQ C.^l1f;ZTҩ7;tps'k:RpNv TXjOԌY¥Vq/*tbi} i@ 4ep] q)fGsX#.{}l,4]$ V_`9xrzc~, W oz?W1_kSʩGI#5 Tzko'wv 1C3r\2gգߠ*p,\oS2:a|{z0&Dž1l }jD%a}rKrQw }(Y|{&?a_`.yʐsy:A HS0go;Ob^Ews;1N= 9 _C wCX;4N>/Oءk2fEqm ,1N (޶,&Kё$UaңHM:#i|RDUץ/弨g|1| FTmsiK桍Ĕ}G>xei, Ӈ M p5S>uSi=j-g+9hL=ilsO9w#12,;_n⯭qQ&"2U3CO_!]mDabR(T?6`[I$ GI4JnFT'uu$}}/E9h)b=h--ژ2l-J|6bNG|y!8qeǯnNӖl<0`b~GnGOÃpί1]\ѹv0$`Y 0>p¬a"a'X8_'Hkw::]W=L}R=je /'w\e`/'w1)پm;HogI=ki$в?Cy;Kw{}^g^_~-Tb3k>) _X=֫x'7l                                                                                       kZnmU݃6nyMThm?zA jOצLK>uEkiY4kRޫk;[_恽|iDeX&~ަMRͿ*E'o#j=QzN7Lr$et=V?ΔX$&`wyQwSM.in(>CdykCf2nmcZnR/ƍDfn Swa?p p 91gED-h nǽн9ܻ-;a}4J?ῐswn1`6_P'\&K3\2i]t~$= 0O88g6݆RwZ?t2sZ؄&

*-6"jG@B|)_pCK~>YwL׷䡿.kv@)GŹDA0xS{na& X!>}‰C"sʔҮ-go4fvDhP)޶SP'ۂ\G+.8;mSBo?zٗ6HF:llȕv Y CJ}2 ΆÝsĞf,h\g 4mon6k$Ty@ T5DЅ#𜕌m `0ܫЦyN(W LCk,f3?lwsw.Kéhg?5Hk\PY9!e(ke.Wm&Km0ftiы,ذ=n9q.[2f|jI8i==֋9sAgs190rkqE+XǪRi6߽w9-'na@R@(I58Ux"]+0vBNs5(,Eҫbt-c|Å]hdiwPР|̛Lu`JKʮE M_\>;`\Z|. $aj!tmN\y؝eNB-:c՟9N᳭#O{{,Va..q50Ȃ}3zM΅45amJZ?;KA~σ^mn့dU?@LH hdc~f}e>MKDΪeL.b>f3r=g;#_@:%Hb]5U{Ftu`IK^&M7޺݈ hK.׳:In^REд u#nqb=RSq:S>Rnc|gU(9hu]ض%U# E-װPǝhuOD#L|yw6 Cګ7%MX CzW1 0LZEUbj $g) gZRvnhw< Nl.W[am'ײ㩶tsrōaBFcVuR8BNϕfóT\_k/AYx :Oʽȍ܉bny,>壠feM]:̞O{~Q'n@%C>q[-+uͨeM8\ 'qG(43. ӶfteH:tOAx+d4L6a7T. 6I.OzlÌ(߯2~2fk]6.wNDzK֑#[xtoU ura_K>bWC9:d,c͋< ~!=6Nǻށ&Km1`'Ga5a;bwXA)IXx-qYFs_^7C}ްpdlvЍї]hB+Ww>ߡd~'mR<6ͅuy&?m۽q5 ٙ&T7cj%.`RS&=1bQ3}2B%83_uƜ-:F'j5ψ婎jL%6qg=g4F2 9b7pb nHg'^ɡ%Tl;=Zp2ᬖ U˨.ˣ "a!VzqZuA-w,rȍ˔KLxMƧp/Vט:NjW gVY%+iXJ?{Wspe7.ɗ8l-LuM}}ʅopkGjn,dщ洰"ZBdUeM圔l?hqvMV2J70b?YRvő ۓp~kN83ҁ=5u:G:{5z4/<#.ĩ7T\4Hş=,wv9wZtpڿ0Њqo.5ϔ_| 9z)ٗ@7"[sBd^ Yx嗂1ȽbdcɓDkG%~a61P8C ۻƅZg\eƈnN~<5=+?d%ov2ab)9]z_jŚ6`kilȢњZ{T4m>,ͿyZ#\gmAmM?fܞyvslY]vDIe*Ǚ.\ߙ!.v]dC&ٚlhcSWm9 Ɏ}oس=jr@ Vk}K5 =ٚt^\]g_GlKw#h4Ǝ{]Ʃ. ǙݹyWr %{:xDOɏf˄qL.T~Fr2[vtt|wZF]C>Ėר`WPWȸ۬ GוSbOh[\i)2ЅFj)4\a ,S߆ly ղ;ո C2e4%C^vTP'^xH9+_No 횅y$[~EN-H k1 q|K#ZW ?)k'd0OvKʰ@]53'; w[6 d.A>:x.h1u RUԎBտx;Gfq*#7olR:lVlc(Tѱ;=16ϳfߖ.:{ 'e; tU΋;'#)-d6pn?JogWVZ۰xCUpGWf̘]l1 x.i-#G,rfU̇ӽ8 b^ߣc%w,IzgO*SGmTpi?9pjcw R2VIbzfތM3ˑQ7ѣW:2%v|\3Шi12n~u8!B͸t[QO%Щ6AcƺM ҝXw /_C/:/~ f%J8ZcQ]T7 uؙ;@w?w3xRzAJ>kn}o>Ìsc\M=o9DT0FM C:' K?bpwG'hLuVi@jϽgc7蛗# 7d<N^ZVpq[rc9ǃK|oUhvr/Cݕ]9&zpc7va[0;4ձaV4=yOԝ1ؖm[`d|Y"cFi+J^bAdaO."}6nOB tê֬XbU%,~&uQRg68ʕ5tޮ<҃hՍ=8 QA3O:FLhld)j3XZXvǾ2K(p0z 8 wS Oq16:e> - 71 JO#!( Nס1v5ʙTLI\MpOu/rNCQ}&_M,ONם8fvf w琶n95ٍ iiR=ĺtCReҶ;jAլRTkcݏ:8nɸB?jbLFnv2+|Z^f&qm!d|YMZyXS[6i=shh; Mܔ/(B8m:֗(ץ#NnJWo NnD Vxi7iޯULcp.t~9v[*n̘C#cZ3\ hC= N!W3)iӇ $oim}{=Y9қz}k/zw4wS֌?dɨ^F\O; X8ֈYpo qH+sd9Xȩ ,mLE)w7'2cb qf}雃5o6,0uη_~"|]47xY066P9ggeܨ{^ =GSOll8O}!;k{6̍?xSQɉ<у839-jUCK)6]O"0=km>Q48<[Ŀovs^˿=ZkpsN^͂V:[vhϲ~N˅\xԕhnڑN;Ƴs(攻^+J/~ ڝXߋۺ{ӽz3d7OxѤ+;QݜYx~FO%xr%arXl'-m(NvgL ^xi%8TϜ`F9"-MJ Y7"_=@NcSJ ׵o(’=:n֎ ÔpHؗcbRڴ67I#o\Ybg'r;~[1՞)a\ME\Ovf-,vĥ|ilp3v?A}bd\ Jv,Eo1Fm6E !$'}'ղ+}:v*^3 M89k89U;&wl5=iy#_F|xFǛ4q_.s;}o'QrCwO~PyVO_Ƌpqg l[j`1tT%b|yjǦljvؕ\bÃ,ѐ]b+[ft.5bV0|_!q̖qCZj =ޠxS&J`e\雏QwQ.Ԯ25gܑ>]ʘLŗߜi;ߘjJ1i`.zA[gC `#?k5t@rZ{-lGG -G Tr]6; ޤOD }VppOyB}isׇzⓊ~awb(/7cB_6\Uߑٶ=;n5C&LD6NV;sSM:r,;@]ƽl{y _c6 s2kiz+b^R?edo#X`rSCe |̐8|{-Θ_Ϲj }js{Cw~Umc|S߃?ڀ?:L+7fd5Q]LEp_Y%gUJMޫzI#^6e Kң[bGqfH_KrYg9;K-º|.¥ǂ3`vp:^kgY,{bezsH7K^{ȏ3r/wC%tgKvp&?H2G~nƹ=xYN݂ښ뫫Zsaq{g.,sK׆&1Uː3^7!;m1y=¿‘串 bz R~K"JߡC,J7'Bm ip:9IhL]F'Z/T|‹CPȏk37{*%O"J}9%‹W6iNVv<9/FcZ,_@߮] *HfBγKiSn,y`ףּZ{$5$CNk@@p  ;U|;weUun~귬{n~< Z5VƣUe8%dMǪch RC6h̏4fFl9ۈs[)]{Q7Auu%bXӿ|ւ4[bbLq[ !/|%@bYWԸ)s ƷZ7ȽVn|؉nQ6Ċ{>B I9^\yFˆIZyx% 3Oc: ~BGzN7ϝ>fmx7ƆWs-QSH?=h6GlfAp l1 U%ث;v֡N_ͯݖY(a)dx׻2>YBu41dX(\dL+fs[.}ÔzR3GfEώV$=Oq] eFR-a]&X1\ה ![ix"ߐlxDM n`Sq=[87]_4G^Mh}\YAX 1n%lezC+5`ObRxg IǾFу•y㠔)ipP_j/rD\ǍyP'ښ25W}t2`{#Zy]8jP;q6!nsX1<]+|X=Z(&gUG:[P안5GzYy+pČ"ͩ`̣m kSZ s}.@H>R=߰b3wIwb^MQjw1jN6J`8V+>#?[5_bhQ{o2rugY!oE 2, =mw!~VcjL|-.7ؾv`í} ge>޿E.5InU2__I١'ߚ9\;b7cPunTpe:qIVeoMͩĜ iό $6`u8f`y.K#ZE6& fʎy:ޒY3HRp١?+F3z{4S%.pݶwDvVi87_;sZG;ǻ8Py/'pvg1$7l@[4zlxǦ)ķV,0b՘<wˠզk63&rBo+6*ٍn\ޜK5`7ܳ4qb'd(lV$1틼x"ywpeFϽܸd=W>:Ȃa?L6Όj=3h؎5x 'n:"/C/4u!ϧE4Nu;> {fvUIR&]xtqU\(M& ;$mkpȔ~s+rk<(%CFXY ޜ %QAslx~3MSН~1[QV q375di֣1__Z#&º.בs +hb9s4g(tt L~aeȬb)89v#_eʚH虋3p)ZɞlUV+4Қ7~Z`r c2jm Fhel=\ۺ*NP*h\L"֟ObΎTMNštܮ`r~(d5n@m| 81Xj1 ߬_ -f`)^Y Z S)ĮԔ w|gj"2!>keƼÞY.4nŇ%ViT.ݥUu^/qj=9r;Lt.=ĉWܿ`u1jSp2%WRK~#nٌmZxR/V)"N6j>e7YEĆ, ϟBw[: }e]J@z+ʾf{ :1ΕkeL]fzJojjc9|>8-n͘{gkN V>ߍھ1L^,gEkh 4)+-q\W6p6wᆧ b.dK8r6^.SƴֈKՔs5n+xE!gnMzQ?Ovx[_YHyg\S(<'~zmo+1iR-ٕ.R7Ovp,ku97.is6=P5_r)qK;źPߞF ]Y&xY<՚#8oL#Rz(x`G۝Y=e7`z8Հ~VH>lv'${߃|Ԭq&ߩס} k6϶c3=wz_7n-B Fu#3F>b0?|Z ]@LQ>,>!N+ch9-JU񴐋xA8 !xTc Rp+E:ƙWFUGUsje3΅=8C磥tQFӛ2\rw6*6[ٓZ}o[/bsnW0'dvH -Ɓ3mti2|ĥH|k_7M BCkAO?!1^s+ KQ0X¡1i9OޝyڸׯnHahnO(E 4W[\f1iVHϬG|V&:9Pj[LzQ kxg-IwB޷מ|;TʕwlA'B&-R1O wp`;C"YsΒ2< ªgz>!k+QlIU%͌XNeb̙0܍ݯ.`uޢs5~]uU8DY{n1v=n"J(ȩmޭ#/i[8Srm(Ntd.LHteUGJuugAƫ%tuU܄a5Jo ra%;2zrv1QyHLNLfêL\|長~= ?hO߰I :=Æ[ !hCiuФ'tzρ.oh?ePk隚p(NC@Z%tRj`c:kSѺ[~N,DwɝGHf19 e>x%e[/)d72ғvXhĒ26 >t"|$GMI8篹2#Œþb㶦Tj> ϿyɄZZpbcnsŊHl2~mWzR d^Bg sU."$B+kbtLfG]>tKUG1_cR?]~iWMœqV7ܞ_rY-'W0-MȾq2,h!&ܩb}θpKFClmCNb ČNG-u:g`$['%`REwl.|Iq,T|]t#Xh5BcZ~.ٝ.<¼=оυ +aFS.l U=xNJZ)Hz0bCKGHG%G/"9׺(S ѯ3sJQcU0CT!!sJaxS췣oW( 뇎LT=R O$yQU`hŽ,Y"A̮8$psL;O |.̍Ff<>RѫS|E?#lE"ۦch?=CddZ̖eb(إf;5SCV}pEЎV3X˄:owK1n) X]ɭʱ^Uؽ[ъwJ9潊9**aCJx%52|'䚔2aJY5J6b?2jdr:%gRN!6-3=Ή}[pT=vX`V\˞l=ո#~Hfrcvorv&T!GwZy{D&<0Аm3 c:[J/ ilƣ;2ҥAZTZH1#K.ndֺֽ\,h={8y ٿi75&`5_l݊&5).{5HmY8Q9k[nR8̉c٧X~Coh^8hW3az[Щb+1B&&W1,=M}r+y/=]׺h0l=AL"-X̅_LkOS\Zh, -Y)ԥ~:3\yp]_IU*>,;"xIi*rZBWw)O͖Jޫ1}89,bZJؾEЙwo1d'5G&[Do;l8%E,k _'2ޘ qXZ9vYP^Bz ҿ\^Be(yL2-/ blqS9o t@\+vD1xp앬Rp|︲ȎlSQo)~)wvDU.(m5_PqX^t ^xyj}nܴxMB*pHcƙ?8rZ 7WT>Qš֬2q6|jH(9r+gV`O^Yd{{J8~c%\Vm۔<)cS% ܗX_+ԩqv /~񜮔޻q#)k:B#]^LrS!?̃aݤ5E°_l=݊g N;?,|DŽcȊOfжap-nv:ځ^1.ЁjWq&+_j;w'8v!d.B|jp"+MX:ݙ=h"cJpT_A5Ͳuŕ5{-:}[z H5}|\O%}Z|kȔA&X٩ONA&h<\Yۖ8qI{ S^rv7;'/};֩7Igp&6])%4)v2Ă+W#*" *`˘nзX2))^Rzc?dP[ة믤GOE,sgon7Ky;3HL)'gEt 7r=3%Pɦtw zdǏ w(zg*iX%/X^ g4wnFG#tu4mym"7w=_%H/%[x2Y}CtWGz*aLLz)&JhSލ2oÏ1Y_5[6FgEġ*&7p[ۆ?欯(<0G#[2Nۖ<`++7=K*&!l΄]n 1Ec.itGxnslx Ox2@rFԭd}JƗtȆ ckAIWbz!؊K1{ [{VK\#/j)0!dNwNDrn&WG~"f%i"|fԜY{.^sF]3G\yrzM BQi-ףh#F̷<̍M42*6ɨj+X9{53+LpB{> 4.5Ӵhd$`apQ|A޻ YJ_k?zTotzM:&$ĦȽSta>X~5}#ONvUlCBfX"gq` WQiݥ\+WWQleI]ѷ19/mw)f=G=5eoz`:(2AU_=7Gf 6Cp.xb[3Bx/74L3l-6{6N m9o93dL3l Z7 fS`NJ턔`\ch߀_ʩR9{qƜ0ȋlRWƅ-NGta2fߠ,~6O KDV2>D#ly^_p|2kBd]3K0B/ao ty 41;h^#WRt:_4z@#C7~iѭB_עrl)Gu33N`O"dc^lJ YA*^+nKR~yh{gUzV@"E+02$l:`qK=c?D3Ý1 x5J,9hjWBj[Fctz ӻ1nn~[`܎hD?Dd%j}2ڊ:Ь҉jowq2,u2ZuP2WqѝIB?=]f410hEҵC~X1p' R.%OƪæxrScGJyEĕ"f~u+*\foȔ;ht("6n΃w sv]c[| /xM:cnz MDǿ3PK||H`+D =\*`2 TaZiz]NZKM;1\->X;^^6Xeд֝l~Z ־2*0Blv;EF%2)c|)#c<pV##mߎKxx-C+ IpeB9ЉJWS- $G)ɘUɆjN4;yZ ?F“.fUGntƎC?w=0-l8%#聝)L۽#48b@AĽ Г^{rUCv<ɃזZp,v8zƼ#g᝱'c.lzqػj{g`YB:$L,] 2ڔuP:L|?`xLkx`P|>7xzf:Ӷƣu\~^ŕ,K¹6/ڑ%_eڤJNak}(bcQ'̜jmvƝQR:sY\JΑѡZ= lLGT\.3[ؑg < ƕ0ڲ k^.őW6C"29u6al; ʹ^$2f xw.P';ڃ;޻ܽ{#l#/r-Cx]՞+9-_JɚJ*iSy*tn%_Ju)36Eǿ*00ft,_0+{|&@.0#fO)16 ^ ans|k __c/X%7xp[}.]|Lꯈ~a9(F#["j^:˂ a- s W 뢃o=57(N-`RR3sS&IT8IϦA s2C.܄{e]ekl &FzbGK=5ft|# O0SkGQp;9H9X#̎A8,ވ~0Ro#աh:Χ iQ%<^Frk+X6LZ& g]j;+i7ڍAby/Lwf8獌/*uYΈQ Fd)hĹN*~T򽉊ʽj,R򢽘ALxi#y &P\TAo9= h?zcْ0#϶Kp2Q(*RFLjԄU֓ZS~.ck1;2!ђVԣö\B ohVy)g09%/HJ4lIX<7wIeto SNrÚ{yJuԐ1=vo@nAe ̦ǣQslPr9!}!6*PR\L,ʂ|^G-K| ޵U(9k]9{7)9JɎ'F ~2O[D{O Hr~Q$\,׮3t3IPôUǐrO?bϽlD|;[S(% CI'-z ŝCbI9-,]Er.L)WHFВЭtS8mS|orK/ϗ@k#w(Gs"bZ]pLs <9}#u'^kՇ tbZ;O:k0AjMTRʘ_ 8/Z{ݖ|fDP81%Df}i>,7aCR 糠ܑ 7[RѕH\ހrjD)edBFK)('ơؿ[{j9Q1jRYJs-1Wmx3^Xa&i;6a(9 iz,(/WV/S3moʢ)t/r窟2VstRMLjYgb^z_D\R#b{C _ pB-nl }blwEƜlpk?";:tv~C2?GSV`Eh*ch;/FrTG7ÂZxb&|1oqc~xfQ.w⍂'*LkEZbǵ8!jP<1RncGx%V?91ڏU;= ؽ>轰 Rq?#~~bh0aSoLSM9 YvJ0 ~3ᖏ4Ygݻ9!77fF!^j_MɈv.jњ)983{ Zjʟx㳂?lE9q̄kţbSl^GP/IX9 8wG}uȅb>^(Wh)9 n ⛄$V-żS%B(᪦"Nr?H.WTM_/ dVerIFYU^m ߬4s =Nq0mh:gwLëÐr0dC1LAQ7F at{aZwx&4܄4c/S?I† 9+YMjFg F5X<Վ, MG8K#rNu\ X]n^j^>s΃w&,c걝+9?.K|]ۣ1YG9u{ wk4D+>Oc0[N9=̈́6\Mk:a&&= <Ԕ\HةWxRɾJ+9u=4 ^v'FS>0b<,1gdHEP7 7N2sG<sp4"| s[wɨ}%1PʆRADlT^2^,X;(8ZَW ˸4QQo&X)y \q4ޣ˰˱x +´)q`-=Blʝq'F6=ٱ\>!͵?:-胈P#i57v:(㇩]`wYBnd?oTDnTl1@EE|g~ok|08su6~c\56ƃ>xLbxN\ѡA xm[#أ-Md˰ 9QZ{{Ϧ[KۑMnX}T tӢG ?>>C }Z81 ڹ`4h?FbZ\*t¤dЌ%m1f#hB:O.odFk%Ͱo cwLj5 dy N{WѡչtAV%c{)NB[*Xht KsIE9`3hi{p,$~;*aFm~tCʵFddWk$_ % U`E4 ß'FJO Z;Á3 ;%FwXk> *y.z_Ț쎛\D^;6ôIF$0L(A%)rdU1RH!bEcUwՈ`9Fqz.lI+RQNϿ"hS|H:,O,6 + rČp[}`P)g L{'-Nk'bI,äxQ/MjDs#vAfuE,SO& įU.ᆁ\NXZcy=VqʟbE DPg#)Pt_Q_Qʣt/cW:#+ΌGv' Un s$610̌#G2`WOj H2C]M1q bp+5;׬#qzk(XڂKx<[zo;ZZr7#}RCecX?U}3!(bS>lfۭq{SEAee]@KRtd& 73%BnwȎut4dB\1! 7{UhxpWItC{#=5WJDv QR)"xH3,B'cù vZlaBVp24㌥aWj71oϘiie1g%-CWЕ3hZx, NE zЍT Vڳ1Gqrq\E=&QXs`h"j&\ vCFbCO`،K +vŠH3Lxh/1LEt&.1@ i:zqJSSuh)"AJr)0 LJ;:­eEԩKxGuIohY  13R j`H1Nѻ,a@ߘ\{ !a@7Y쮴?ǟFch_jc =mQ-d:R.cvljh@ 4~Cq35rpaf(~;uGm Ew ]G] GJ=`H@+1Wt06qeB!l;4F:M ;앨g wR E2!aWXV,MY(o4۝O>EВDI0xdno5+U{!7R}sSf z5Lj8wuG>s ĺ`zoFZl^3Z<Ú{O{}hD=FjnZl鄜 wNnpM5 w]p hCb5V`h1ҮhkZ {hw[uhG]|BY;] C 9ap/8wNNmtaq9/Ytb-r`}"ON"DŽ;$dB"wDF~#5g0r/"زČa?LO5 2{a=\j ThY=Mp3î9vn1|tΈ:R"XKJğp9B4XViaF-RGsWÞԾ!ZN{BNY~ͭZmSpm؅'iE6%:PJS Q%f=KZZX0԰{=>Qd.ƻD[n'lϓJ4̭!ۥELR~-vC pw&\InX/x\1\[2M|Xcɽvh O1T"5-;|bĂ>x,3a}7#kl PS0+ä]xǮ tyn,וf YkXVQDnL܆h6=KУuin[,-PFal0 [ 3B1]hvN7t? |76b8fa"CXXO'Jי+2'8u:ӣBtSTa8QbF -D]PS7>:9?9\61 2RK->aUJgx^]Wi'8=m_I I5|4K,, `cv; 7`=8pb) xᄾ%(By+5ӡqyd>pŃfb+ޞw7s 5c`3ψv{5"Gz^Թ4"~Mɤ q17#6wŻC7 +Za&<P -]WN^sho=1&SGe4`-E;RrTS j 5 Ҡ8E]Ȑ[Y<8Ӗ˒zVzgɊxeIqk`Y6X6ZjOJ=E$N, a7К3R.j<]G:3Jvab;Iq)&@z>2Fcɷ 8(!DSf]‰:levr :8psTZ4pFwq"Ct9$2Lcy \MuCayv06EWO¤Z u-i0&_>l9;Z*lZvv;UbnF }#C~q ]TKcmǓ|Z B_+Rh+)b+C] >bvB8k.ء3 ψ/B~.f|/_U:\b桕PeBx5Ǽ5T7@M?jWBZZc^{8(bV`#'ܲqj|㑍7~I~"H|쨣~Iorw.nO{:2 52oRnAv5 Bx'!R _nx'3Xe#?N |,jiwI妆S~d?$]B>^I;jTRRiD!-TXB? 8lr\g+To#9V ~C bbLʳG '™g-褦ڝ*γӕWwhRDUmږ{[(tXqx_T{#i j_Cӯz[zara62k60_[P:9*p{ (07D} iLv.P"jr Z⳯j2~l7Q1\,(ͲE?&Ӱ4.]Ri=-ybk[w@."'0-H)ֹ:ccS-1<0р~ߵx@G `p Zc(z=i=1sjOI]xزm۹UwrtD^1so&jlKb#)j7J]EsL%(R7uiJi;19~LԮ2(^Ki.:LI5E$%75e*7Aj3EqoCp'{0/:Rk["NjM$ oq6OL!V*8ܗB܅%lK^Ӊ[6mRF"j #bmJ{)8*"~RctU 6 mgkDD~-xko;t;0YKShڿ!ɷeh̼\|G`}T^8JW͗q*tOEyЧoH9:C;'>߉ ,anZ>".&EP2q> O7^!j9 4+žUZ'Xw{̷<]Go`LGRRzױNVx: _0;B(E5Kj!lH>JzyxhO>u'3’r =8D5ڗjW,GSZڿ[fZ_"xzT`j;|=F K0[]J ‹~ _)e[:Τ‘]FI}]f!0 /kSCv1d6 y:7<hۿG6{͟γLݻOu$UiYUJ V,`cs{ͅ1vo!6\pO8YD&?8_ h{VRvKcXzZ:YE땔c1G4Jtvw"x18X[c/mnI*l{*trƅNR%=bxy3NT%GA'/9m87NۗyXc (kfsVƕdN1'w%V3p gڠK%Eda{[Tax"j )Fo( JkU45E?;PGm  S1i@QGR( 2;i1:XY gH1ƑA<kYce4\~QgK=$PozO6ep!Ί6)pѸ>Z''i%,[oݺc6/MekPAV(%m}=@p4xA] {`w~@"U蘻ЗOߡC+F呤UQ6n9UEdcAP_/E $eRsuG^Zȝ!v+Tb[U\dcj W ;0f2>KE'.oq0v֧zB]w>q4`g6Zc;6zbl.^sм|DL@˗( #Łr(qv+9cL+mALS!d;hq33?%Wy="6qOYl taYK\ `,x2> ?Z5Ѝۥt6+xfxBO&Ji t~ݷ$j`н\e0 C,QO4K:^2N%2<n5ӟ$,<6~J!MNt4ɤM+)Fjͬaa'PjxI tc]?&i-V+8O!x=de!6Sw6 ?$]*G^{)\9cIu8ĶhfSïCr<"9 +8)a`92?R%0J``ܑ9{xp(;ͮy$V}};#:wfڡ•,|dc{'+ܕo S@ u%23Vb^ ӝ[N0hA ϯ"~::*XE7DrYLc^ip@ l Lc\9*08\e")i CL N8aO MpjD3ZAMb'QyP-$F&Ψ}&Gs"(Q8zgϸ#_)&7:Hpa? fqԗk#r h_._18oCÔxWjT_բ H)tUyxDM=TN [1QS>Ƙ^w$qbpW#i-E(_C|.ƓR\bG>\\va4ݘM2>3J MpS{̢WʩqrnkjH6.(c4=0o xky1o?mI`# T5d)Ɨ&cM6ߢ&qM!Iz/st|1+$Ǘz$zԸB6&[1}7ۀq\!*z*_JSB|H[D R$z8|㮝~KE2{t eVcȰ'F~_/t!m};69lyf濓}Z+(BGb03 VkN' N/ogQJi)o_GYz {h,Wь{Ip'0+cT1}ӄ4N2,@7?Һ4-^,?< erw3RbKW-~7Z11Ą<Wkp]%0L"TbF1v5P_8/Ž%dpĚw<`q1\F{~"5٣KV; x3%{EBy F|>>U 3M?NNWG}5fUiX^/ӡG S&o^- =l߿([omnw/ςƷVe9\rPyE佨*l`cmpt=UaB S{E叺@w|CFi4%QƸ$9H](rs}- 91%F1`]Sx؁ݤ!z0_*J y҈XQ`ƧBY"ZkBL9$6f.JT`V[D8j#@" 3e𾅔9P\vJ>:f)*+po&9W.K n*@ MZeXH"#@9RFF(-~b 3f,>c-"4pGe ]@?<}W@1yt6 gӂtu 9` Tu9vˣeŔ[MO/iM E$=YLQ"N ;᣿FUK1xv[[xԝo^`J7Zec%{h"Q)}V#Pg5]hOzU:LsWRZZ 8ԓtb^* s/FID[wAE{_M->Qu,>^mlHE{l=l39ڒ٘f'pήNC{G҅//Ա~it &g?Q4<򙾷/ Z۽[x lO\sx/F!@^OBVp7B _05eF071+ aE !e!^Ib [rpdxOGs[K Z#B{J&^"D%FI71мHe+gܡA Qc\H=$uprs8#J*[f}tW1Y<|Š'8h8UElGz1{H,ȡUiN>IZXN^Q J^BSfRd%ӣyWL>R16˫7R4dRӶwct {NN3q[{t-yĸI(ŕJ6^4Gw;YŖ,7-J9?)b-Z#z ҤQX{>xI jPdѯ 0}ٳE| UG(D% vHawO&DØFO; HEc (%p/Dx+B&G ܌aLO6HpfM8I5YH\b6=n٘9+X1avbl]0K1_ B"L' O)N=`J?A^F,ؠCf#xދXfD]b;SRL&F=\%!%@m %@ҏہ_iNz>-FԽk1mQ@ʡ1L՟i?2N(w˳\_R@O9t1?sca=,S^tz/έ^%cg\Gaf1F*`mbyu$^]D qt Egm6wctba;PG;9)#.:Q_ vazFQ؉i:'l.;Psa"ɜK; L[/EG/.kXH.i74v]o>|o )Vf#2VbE/Y9#Th*#a]-rBkB:21 4C4`G>%ўq껯5xv chɐ). P =fsh>A i!gmp4 W$6Z}f\l!BK \gL)S?Gx;)H5 #@Y! |<¡.0Ŝz*kx`[!'Vf"*Zc<9HFd5f+]<}U$%gi R}ixCWF }cMzSj]?)%ܨp:k&DO-?Pה&9B~41n[-(teZ|eF2Ovf'鈾aosm]"yDPegӒIu4h.^\.T`Ɵn,{VOi$59:OMl˥L~ }>iǞb=@'t?d+-LMGhӴ:*DOBҴO٫t_$}Oiw{oew{3 ݍ mwvmw+v`v+z[(-*v4H{Y9>bZ̬k ML?α"'#+j*Cy79jA)G = On֦Yq،~jRJyw.Gؗ7R 1!0m+6 %s|l#w6eM{S9d^+(S7~jǐ'e=َ'ܮvF#m΂w ,W3-܈B"##zXw%dM[lݦ~>q4b*p_xMo4ن9=à|,Ǜe@\ WWL=]+s$ 9oێXѳMto 2 &pм^P# WYHywIMW&y3frSj]]%M1bO.)bJRz4]jHP[g#g;q'FleUiAuSnH2]rV k5j%WK8x51+#|gSe$P9~9W Y٘MFܺٔf-o-i}3sXpёٱ5F|]->r٥wГRB y0ՊMX+l ߗIL ZK.{Lx͡>#mc;nƦk>DSO9qبMH|"P6mQ9.WƳx¥nl,XYi1R&_ck6bbA"6ƈd徭e;m~&۰AGng͇Դx2aK~ `g&ߗnf\rT#yx-&0⫄+9)G͸8IB>ڈ7#@a eCλo-v xХcVڞyVѰ53;/0e];j,`ץ\IE^[WCc9{c1G=ζeJ&,2Cf*`o 9m78o ՁS aϘTgr8ޑL#I9㎄&2gH-cnb&Sa{My7'`UOyc|NLFGQ9 ~|?-1IKDOGWU>zƼl(]l6VLwXvnG}l1.B30mo4糉\`}'TO6EEL Ao3hwFqNk:Fŏʕbo>=>aR4 e} u k!6JZdrP36VrVTpIɾrl>@L .2@go۱Ē{X30ۖ_^w`n ?:[f9?Ps0f=>`M6~?{ؒ;wksásl5ҧq!;Qf_o=Lq=kZn>m[kC1v4s)Foe n⧜ }ӻAŜR 9Q[ q _1=\%aX+k6GQp:5 dCMeT.g7 %+isXJ=z%X reG GjpcάuV33:Ζ+l–'[31V5l{6_~ &DRv];EkR$6kpKySF3p3`ɰbs^nl YZkFd8q#CO 0` o< NQ͍ ΈT=Ɍ9F&<'1"#E߭o\Ual7(Z՝&Z<ե|^[z|qLSij^ uЭE0\ODde;B?/&E՝O{'ne"˄٩sJλ2ꩤY1s+ǘbdp[u1qZ]s SE?8! ݳ1ga C뿠1kqE9C{0㩚 uMkr.Z VW?J=gNq~7rS7Ro 5Q׎<'eBUb9~^>fl&1g6ky 0xEø9"?fa% }%{TpF%uX`7xцmy5F2Cl}5G O!1ƈ KVGĐ%2>(mjt] CeVi%#gFܳ4\5Uq ZB"r6XkpnN1@KhlՉx됀7_p=؈Aܴ4] E. &ڀ@s5 v[#2θ$U(5xu -ã & PF07ڈiS |dv³?fAlvuJj^*JlWb`a=Ei1{NB(J3Q◆}'b{Otr/Cbt< Ώf_zH5S-ٰ(z NYt +hl£ 2`2a?ʸw'jULW1]SΜgb/GS^^gʋnt'tf#ov>%mוCk:Sq*hÑ;0j/cqsܣg|E0Yl c ݌<ݪq뮊K-J;.@`F$ڱC=:؞+0-e f%d]]$_ >DR7R!ؐVF\dMυXNl!aM&P}T`ZpoQ2Vj ]<(d/<VUv1g  oT QL\=א=-hM\ڍ`jt]('ks̿82#ّ9qNO;lmԊK斔oKČKks!#Οhȉ d-*R9uz/GeBrTt>#$\xm6xR WuBRU)hTsu%Hx<1p.LXw5G!þ <} ǽ gyo{#`@rG}F~),ij0{\:n̅rhpw~*njivəiOU +}7#x❿ 40s9S,PVbS$c5MјR~xO21'M3OXidNK!k{f,pFу)< Sbxk$U|!#xUCzySXw0Fr-Brq/ކʼnGE_xjHZs^b<z]9lȸXv}>x&~Wұ(19^Nđɧ܁]35ĎQ=NZ ] սlV.Nwq݈ Λs} #,ݮB,/#=Ðbq( uOfEhIU>O8|4XcZfiQ?FEd| v~!pǝMo[5@T:\TqR zۗK8K=Sv‰n;Ovc g^[n˙SL}P? W\kRXҷ].L7!CNۡ7)s!L8 qj%vs?8#~wNsށ)=mcyr4%<;ـk2'dC%i?źB|Dx]/apD9~ŸX:~4.œ "cCygo/(~nȍL8$jkЫ6 :&A;;tG}(;r~&7g7ht6 t`? bR 2D|v@mk4a "nHEn1C{WǂTBM!C5d-:0ߕz.rf;^Xh{+u%l=^EX}.OFeW|{%r`6 XxP醤}VG=ŪH*( f(:ނssΙ;J[GwbnOKvR]B!OE_ge NS>2fr~_'2<>`C>3=;#ᵿ?wV]LjWl3 #Wmw WsCv*a ao`x6 )n m?R 2gavދՇpib#vѪDD`u[?Bz rdV WcH2 [qjUF5#й /yԇqx܋q`g=bNyc"؆>&_Gg-]/fzqH^F|ʖ)+\L'W7]ַ b˃f̛s xE{xĜ VWf?m ZBmGOnu]qT4\DWհ(ʼnF eOwbӎ|T3lcHE'}{#y)ErN] #  cIR:Ps D(G߸00f[-T#*桟cgU\Ø^͹ьo(GxD577~! 1 cr8ij=sM(ӀxmXgx1;2^Roy>1bg<Ak6\Wb`N%+|qAX81 s\ ﳕۯI\ &ԂE\(x!VBX)u ,66J wġN,r[^t5cPdS6s_'1oC-EcdrD쀞[b`^c_c:""t~ @ҩ6M IU O[Z-͎eCsYGOEݡb ѣn ^pVIxKL9Ϝ yK-a"{Ы(qx:+iӄ.FLiln`Mo}{)isƀIT˶Cۮ#ftM&rg`;ҒX;f~C߱5c`?9/Ƣ5jQVsRE̾wF‚NjZRmޕx.zq&j$ w{7I0ԯwB7afl`Ǝ_AWA{f&F`*YC1c'QսJ _-ef*$\cs={ ,F&*r0[7zӱF7ie*:=3Fʀ)ͤl&av5:g=C4^ތ I #z}Ƃp|9?{S;lfS~nSnZFD[$9iiԜB؞zVܫ!aO"YAgab<\%o3gW0.X=ƚ,DA7Fa~R^oUTqŒyWKL aTL[7`k65mEU֤&piW] RPg5۬[!&ŚxvUBRl+ |H@/Pc}i ^FFF|-أ:2@C>dM*Kh?=kv8Ξc'E;]=3͘\ioi:Y2Jϧf;RpMx~s6µcQ(;~F`p=%=윊0MjDpsMjy%T th WJ94͹d%Oek>[i3:L{iq~T$0c#&q%o@zk_Xm< p^UŰ cPW6mh#Ƙd$/*ņa C|_5DLj\Qk &L)>܀1+p|^9-@,B/$惧lfA:'֦s&/,EҖNAUcCI}_9=nvI*CH4>sz:|,W=^j1m=Ί^LiةON/[(XLj@5Gvfyxga·[.<_ZQluKFB}' }wS;\R|"=0'̌yf>H!jX*Jn#}Raw"2ٷ6mGrK3X7z6[CFJ97(6F‰$c9FH\-?8GZlSSyX%Gw*E*g4B|J=^zdLSi3s3{08׃7r3 ~ʜ-)R1l7I]Ϻp͖r./7a}MQC)5 )Ũo5W)pJ'8ϼc`poXHZq򭓱cj*ZY=0wrɃn7kW3!8y\I'`v eAVU{S5?aU/934OMsub&\ߌLk!׋E͙ռńBj{bf=]Re`FE .}NCV>޷(N)r+A=E!S7Ĕ۱g•9ߓzpВ yw>Fmǩ¾,b;qw]u a_*p#Lkp]ѢOg`OߛXsL;a؝t##J.`:D]g kk'7(-57]5ؚd%N\$G1U\S.f۳l[YSu_oT ~:gez 90? ]X@Mm;;Ȭ[Q2 "IY辶ҎDj+o{:;[Nb[Z.0sak[-dh_<]f}v$ /Wߥb2Ƒݙ۞;lE#wP5b/x/WD~(⭗:VR?8y 4QYP+z¸{ xԍpdziUɭ2}sgS1ԥJåߚl[EX')cʇ&<yFIM*%cYN܆<ޢTFy.5:Z믘b SYuД6N6N[v?l7 vbet(fk\$ }AYk+~~ʹop蚄5[q!& ~V39B7nA7cu]P-n)a9󂕴1S;I²Vj5<مI.wo&iXz|PeڹW]ޤA|iKd`Y9Ѯ\;͝{QZ3z;J͜wlVjO&怓ZLou8A^Z{ %Zqm3L+Ɂz2٘L(h݌9; \^e޴ ǝRBO^2\F۔Fu.cocO9'Fy6ό,ƞ9;]1g(k nVRfEjEZ^ |4Ly2|8n/c=?isFL?M6)5E+^!=%/8XHmV/,R@Bpὀe.= q%+'*X^DXEɔCm){yLyp៫<͞oZc zO9~*cxkZ8ǀJkS.Uؗh6đ!v.xՉV՚qx4r)AOph]#V6 &w Dx֔ea-U+kv0a;ȸa& cݫ||M{g\X Aj3tO%,J>Y'">kL X~O@`2g&,~D+YQFyOL3|R 5[ՌR|<Ϝ"NՈmKXD#+!W k!lxaɱi%w'_ܸp34_=BC6Ř}X[(焁;3n6^Nz/`׈ڮBU=ZqIzi Jƽ݉ҧ]uـqZ7yrˏx;t/y4oiys/:ʑ9,ۑ$ѕ*\"ˉ ۍX҉-8uW¿,GҰ}={q֍u"ȋn|Ys93緤U//y7gh3߄ #5~V,Ū6قw NDO=.VhQ 2RE';s 9[CWZR3rn=AGg8?/CPsh4N| p5 ˱$ )~EP+Vj^)w^'[S p&Ɛ?Q3<b?KlšOG( -/窉\w`8]$Jr[)VaU/BrȔ]Ʒ\>ȇwЧ9z^d;"ONU>ٌ5x/{pR'?S7m0hl{}Gal O=3{e-7ʙI.$u̍t]nݝN~1h.:X_^`@^`X~,ċzEZlpcq9٨#vR߰S]%ڗb.{5flwӊ8lElHwg{Ņcݽ;ʅ]ٓ^4ɱӽ8כҝk9X)e;#::.ld2F+"̈Yfv6؝Tc/[ooFe^3nmӜ SZPV˻ۅLÐB?)t8zf 5Mڼ{Tx^ۄ~-h;ۜw^NQ"VJDV zip?/GjA6, =]l#{߱`xkyXz+ľ-ObV=^o`z,8;^̌eoW>ȓ7ݸ$О-W`>N֓=^n_6neqL ?o-#9-Oqg;?޹qU ~dݾ-i {s/O%6h5| s6ev-8TM]eǬ)nzœlMܩ1ΙXpM9_ <-C?6KͫѼcޥ@"au喡:63%<#4j&<À'xfC<^JR2 .m!:̜tοO57Eޠm -G?ަ4BY_><@7k잘$Lʔq%N6yǚkiyʃ~~><-8.ދ/z%Fp'ĝ Ƌ>,S}.ߙ:Sp\4%;4Oa3vnS[L_؊-&<܍]g|8C3˩|n'e})ۛq|эFA^=]AѸeqo{l"SgWF糮\ƃ}Eφ/ ^F}BZ4SD:Lř3 qRLE(i?Ŕ_t&/ˋ1] }H&ZSq>}nrG͈ܓ J yJوu٘r4oR8)7],=mh9Nwajbk L*|XUZ=TꡱXfSƊ{wg >1}w$C@H !ĝx's٭wgS*C:]_9MƟe|^ m+L^Sc<ד9 ^>ɉ_=.'w?ԛzq71UrY^3mki%\ *dMӗG}Z%aclfIaUސ{Ίc+71X1[?ăw5{8kZyTwT2b۠@]bC*S`Sfw*lv{x]P=; 1z /5qɥqLR oe.U/WaVW ۷|_ JX>*cJ[V (CL\o͂u%EQ<H$BӱmUbw5j6 [G/jzJgM7͢s=%LQ>L]|9]YzscNg+y>z#{t;&d;1v#}}+5>\0_v[|9b/f ϗ> bU_v˖RsdUfa"LYoEߕo%ɐgړܸl=[Y0i7O|f:3Tٰ*ߜ!_Cm-h, *4!R9'ޣ/p^+TꙃsJ8YgC4`2,]/AaV?'῞BeCgW:|X9*U(S)iQwSS4̔b<-c{˾bmT1X +n[Mئ܇L}88ҟ}o4Jz'/d:Q'҄-;U|c}*ĘkW'XC={`{/H87efM 2MTaOyEMwH4y4͊9pęw==E«%'b=x`s-ӆub9 =dWԪFO2;XޱNW\ΖaіP.eH :#c£fk2t¿Iz`jo!V`|{10NDt|Oѡ. :<vf@͸U~C3v7=}<݇xWmv:}/.."llB{?zǹ$\#BOƭue'\UnL-8誑`8lJzC0aU R(Ru7fX+N;Lם:{as& aD$oVɍ  \jq-XzՉ΁ٮtB}%ocin|`Nہ\ۍhϠؒ%Ua>')1yA)oX2FO¬^H '$-a~"Qڿh}3R5xfx#4Ωq=FW?M wnF_#:z|@wg*5GTڮ* ǻm3}~ u-]|Җ/2<SpY*Sy=I8F).j}y^i+Czy Ҭ7gndv^=-m7uzmxmrwjA'I8-Zoǀ[0yAԧ&:UCNNÝ-lԊXlƅ.Y^1~í<=Ǜ$<^B4\8l'qX7=q \"v,pblf:q2s-Wp+Z1̌OMx+ˈ?XSEpW{TosroՑr0>7Dڏ>q6,/};FY`tl/d"[ yQGp_/ -дRYgD%N9\ΝRSZK?/eHٛ9yxx1}8fj[%LJ y~۽$\<ąՖ^b=Ά ~#7Ah+&> F=1PT>x?Tnf ͳ\v͞#w:rI8뼸6ƍ_=9wyFǓR˃N=y‰ɧ]9+?'wni@('Vv`L=D'#!N p\ښ}l/ԂϦ(@[KUa"kU̐=VgC75.IN(kL͢pԟN֣永Ο6鄢 [g=ʯd?P:ZJ4|NwBۥ*҈~|2^B]/I Қ///Ep/Oxsg/frNS[?ҒOjqa_-2j闬XI.iv1a8gXu%#daJe`TE1kN6Sq}: ah2ۼ2V4oxy_ùޔx [iUK7ĩGgVmqfkpiv{6qbg68z [8_=.K^iư& zn6<ˎr4a>{Ƅ+ef%(Yz<ڲJ~*-y4FY 3BW#nE4Nx{^&|z<(qr{DkMw]p-}b[~t_|/p|wupۊz9r'\iqև>Y(99m!UWJܣLʴœ ~OG/C5fe.Ԡ,;A}$&ŰgXz:]CsNTdSOZ툇O:W yޕc'كcߛYƝHrlgnz3}#g_NPr(t}`Gs=} m2FjͿMƌ',ز mm9k$Te T9s^VR>7ESsV>沙@a?~I٢+p5^פ>Zw3~ Lo4ICx̜֨4Vc+WO`N.|8/unѳ [)sT2%TgUNU%T`@2`dMyVS T+zY4(.~d?hOFh6 ף{SΎub+gq;[պn+pn,mPq#_ntVDwn<N64Ў80{z{K#ΓÌ.֘ӍxKfIYVdhM(ƃE%80KB=Iulcv?҈k2F- AZϸ47~ABZnj&TN<Ѫ\7ۏ-}9};wA5U#C>$X1h7jJ7ۜ\Tv`9l7/@KQde# b̒ Lۣꌘk]U{ ./Ft}p -`Rs n)>>;>ԊRyON{m783c L`n}>ۃXtߕϓ9lΉݹg.q3Xm>K>@ sޭ1eW 01=&4=ޣ;c4g<6ʼwgSY -23ze5Rw!NBjd9~7p ޛh_6]dCn,΂j#~rz=MG7<  |SB j[+RQv!kqP֣uU5 OvsAG8Bc|oU ^ U[,@F^uaO=gwn-+U7z)ǓGx2'S$n\͝-]-c̩aN٥([*rSUEcV?1M)W]`@-ު˄^ZǰUq+C߲Vdc/Xط /t k(5ƒ<$S&|' Hb'%'5{]>(@'tԾOAb,QѦTdn/gdd;/d"͆'$vF0X(\\JUPXU>Yʱap$BKt@|~U`j2Q>+2j{vb gƺ;0p@܏#)œ 4_\z]?˕ӻ1Ս1r5BFJ蚍f'GTթ9_i5m&5#&ӳeۺ7;ؚ|M;lTw<⟍ϐ1CՌ8IQ=31 3~>3^$P_#>Y# QQd;Kˁ F)P,{OX@dynfDc]N|Wf|Aڰ:Tji(2NAL NGS߱b,$|;&_p,M,|Gؕ~Dw|UbрTewZP* KPF9ԅkN#;vb='c!;{fε]9 }Z/}NB3 y5q4L2ʇbOųeZks( b_:g~ L7Dƃ8gr>V4\/hK'nqWs c6:qI(3it!ި])G0f#$l9σxӑZ<Fa~Jy`3_]XC~X}ג(;wW@Tox{v|OsFWbذ:"SW]URm%[&rI(_ˌ>OS}=V~6X=&rplSπ:W*=QU,GlLW0e^i=eй\;ĕ>A /blsPuSJ6Sq"_EbNˣYP*, y7(>zt|aw)ry u-s*K R'=yt"=LLϕgyeMx뽄E,X:_c^oB, /9w^c=o83ȞLW-h 4\8k _qusf!3?>7NfVFA#TU`l;;0\W?|h({!X 4yޜ*l8VrTTd5i~*?:#x/TLEtU޺C;+{q[/*d{s|^[qm9.Օ8k"=i^E#Z)*dk}_n̨hzŬUdN|Unw,ğw~J VTrNV@dZ[uXu9 K\bx%v;kAFbaȴJt /D-t(XWGa㐟|-&>W1oViH-Ҏuu=:Qf9rD#EHA>jI5PihNj}/̯P}kp/Ka٫ZG*5DŽ)m ./mf'r :{ve=6 X2#vΦl'ŝ7q^o"U] Sum+(|nP̹p3=+KϻtCo3ӕ'ڲ*ONp,u1{,~d, s仩Pk R/f5C?9CG'㺫*L=4YpJ[rvo29G* )U\'=5;F,R*\0Sux]"Ir(\ )٨|W9+TXMj0bwԪ-< }=;>4ՇVfzK_~+aP'J3,لC 86V1W+1G#p BdwsQr'Q ַH0 z&y*| ;797N_Ds3.qA=%Z>Gݍl¤TbI2*6aZu534m9v) 2B}VF,\R7y s._OKg{;mJQp fŅX!y984wcU ORH|K?P2S }Ο͵TYaj\㺼3ŚfRߝOE;o9cs/qvA%cN=Jt Wu|VoP<3g?^pC=9]"'KU*^} \{Ws={Mt 2wB!GƽwS4>Ck"K F..@Gr`>צ#Wkx(ٰG|7`C~nsԨxOزng.oVL +n9F=GhVǾO1}$r4#0omNyH*TygE9*+kQV\՘TGb >tfx7xVLrei͇XKf`6cj6sn7=‹}YmΝ;$ M>kP , 0`o~gvtE:Αo1*/j;8ԟ 4S&^KY@eV{ٵ%k÷z>?cmd:ՌD+#p8} {m&cRS]P wORw5r~1\:8W短tRv+Nvg^Ћ^VnbaVJjVgxB-8 '?L8>+sqEݏ(vFQQv:t,ym= pK.\0̓r#XqZ.QdXVŝ 71 vIs0xw>N*91cp1tNDmWbҧ]fhs&A)=6Zo+pG n)I2<qh$]~_³ǃ:m>^&Q-[&SSrY㲧<{Eֈ{X"ù(_A5aDsnoeΫҖ9g<ŕ7;]cs=ة̦y# abgY٣Fߤovʛ__UBK1jGFwdHG u[%;e ez'qj W]\ἲ'U`U,G&}@bd$—g" ck2}61&7=7\æFO5͒S=wrSTݭo$,#Ϧ?^APi=b}(Ss ~羗Lf ZǓZȑ{<fyt2aչ|#P%OS4)lVAH\kUx.M%7qopm;&એZ#(yM6Rj"m)bl4pdz*Q-|ʊtxgu/ aozj+K'OАP`&@xF!LshO[v*VY!YÑxp;F yU`j{|Z }9'ȪGlW4,ըBр4euסa9j! ϱ^3'Έc ¢U$j{/9G4]Y-‘݅~ROrM!6v*īp+a\̝/u]MX:f'ˏAgꖬI+_}4٪!q-Ma{ŞW=~JFkMhOeUPۭԝZt0SGqgS}_Fj E1Q2{Iߴ%KF49S9_qH^a?\֢k? gfzp=Ū?^_ls_Fx, ᙗ۲qa&]⣿nj f8Y_|)ŷUP^1 cs~mh> ɴb6Is%ot r 퐲Mvb4C(]Ҷ iz|8SA*

Di8'/hN|U}쟔K 0ܷ z?y2jbz8sPV_W'AGR^bYmBȏ8oCSXP}%{r5Uz:,@x*}W0ƔZP̑ElNtiވ5j%Xs 4[i/e?_8OGg%ت5YXW~ŁztgA[#UȻHXcc[O^ n 0V?mp'( ~[f_AYcEmy_<20"nmvٌ[2_}nY UYrs\75Lb 9BT--%IR|_'k]7-ucMxz 6〵X-/߰tdcԡ*ÍFs2ܬļLǷZ{EXFO$Ą:FE݊*ā!F0.Yh7Ƅzns'T!fO@Û帿u;)a(ҿ9^%f{߸s}XISt Oq:(Q2{WD7ǖjl/ƕ:|W`QeTzMRZLXaNHX. XH8eĬ&1Àccm`.o6+z$=T8>bfl·ä?0KB=B˛~*~=-[X#ȶpE'5]21se+;hb-B0mFY^jWSqNA_Yu\-p.Mkuш7Gj=3FvL1ƹ9HZ)j4TBb 2\ê x5nTcW9*AӍ~܌˧"}N7,}n 4dyAUREWPL~Wz\vn)[%d̓+_Hi*M*;~\?ҲXk1_ 2ʼ~p_E6LwBI)VCV!}R2<+\ވKbm^l˫l闰ұgI'թmJᲚ yФ$n/EQs"/.`pg?co$L-avl]4rV`\Zzi"npl N%G!4h5KKUy~X2κΆBE,u[n9RqApqJ5La5!Ȗ]úSx`+\A/MY([tiv :eIs6++M7J&V#Z#uh'C[(VQda^TXiNR,]^bsh:FŇF"beiJsd(ÿR+uzO0oK; Fx@NQf??t?T_}" ["9tOqG:FaRe",$ܻss4N~2Cˮ3u,g}NҘ\[M? v a2vF? q)$@{]Ͽ;֧ KskU vEʼnYoNl_ę7p\tK}ZTO?_RF" _{;: ׾/]qNJmaUej'JQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAж{m}~֎L䠰; 49lAq}緵Vn?LxDvRv)aý|YIT{ۍGok {,EM]Y]_iv} m"jSA7btG^ogG]̯pO&oy!(D¬/0=xOG;> ڹ\fpYd}ѽVXf<75>uyt,e=<~\K mM;аZ- ^w gpy(Zדexr^5Zj0JGuhKO#;i0 x,|]d[ Y>'^KwuyEgDiC? ۶|\.}Gxq(RF=veFs3.ڡGXUEBC{5['J YY]Ru^_~$Ry+ ͲK>Qe] =Ӕ~چ|9T["sajSF&R}5ZP!M֩?_H8}XnFhT6xi'M x|zT&f< ֡ ¡[W`2xVbT%n!nk0ĔZ~KnܦGz=c>#Lq!pE,YV\]'<>OOe^DxmN\e&-К#1,N> pC4\ѢN9Ra+on K7Ns\]냢зv^;Wɦ?(yl* U.aw HkZܲ3jv|BF#Qw^l@rjjq}!@ $$$Fl]{mC޻{]A,vܙ;swϙ{νΟLf >ZI 4 VWM?TRߥ,fW专.x 7Puz2)yؔ'AM'xՋzh+htl a2 l);Mc:~5ݑgHf~|.w.|^V_\fpML3hL+<^ߝqݠ AU0T v w1<8Xm;4mU~0\Of'8K}v1{cOibv HΫvմJe!k VhgY2,uU3v1KHN )utex WExRhLZӉVx8G|8 C>ғ|>0qs(d{ܤ'bB{U{{ӄ3M]dL6!)qԬ}&/tk?H׸aBl'46`¼5pJ?]S ?!,B[3UDo7Q1.xS(;[|n%.mn{lQ6TCy?a?R S|9ޱ(coZ+9Ql GH.S^Fkci¡:zVSN] )[ *=CZמ*(r{I~5ٌ)ع}vCg;Ǯfgyd[riQdw~)EOO6Ns4'8}&׊R*/cYex!2kh;Z`w%69b9N \0 |T 1\+p-B͆H-H꺉n-Z0Z1qְ4Q@8KW9,F%8YB-0ͦXS!6ܳ¢OӅqtcH0z^ޗPӸhz~렠L)V4{fg\{S_+GPv,|GY4mM>AKNٕ)4&7} %BCnSNb2EX^_!-ABa JKtd\ sKg<`;G+"1+dua*!k>*`♩}G(ޕ c7{ %4Q >jSŵ< ک$aQ=f &Tx~Atn&=b?WY*xuЩUOT I˄X$kX҉i# /&ǧGrlQ?(Fu=C(q^q0G\O3ÆzHӝYX#oBT@yA ZLBdGb\˰åxP@g|MiCǶfPDhݹ4r]*E`&*gMc)uO`lR&ܷ Yto5B[{ȐOZq \rvEZ3U0V@Wq]gp#FbSd8h@KC@+[ A>nƿ|< 48¬+4.)NGunl0m#9Yze#tJES(U`13u1FGG8bH#*d儾!tD/ 9oeӝi9u{Hڈi{$%}ma|pxv!DK ^\{.Ż6(j]ZHlݰȤdm6f5*l$SsPUӴ(ĝ,{аݭbzK=w+ӾXZ# =@]э M'}h_Lղ"Ӊ4ӫUn~1fs}΋+RZp?lAv}E"Q2g2`@̒AtU&[WVKZG/W-{f5L]4&pAK4m2H?FndeV|$=&b4\ z0>U2*x4Ҁ_{_Yj]W^d?nO 襄zvFr%s$Z%ϡ/)`a&CKD0kqrck-36*F.t6X5$/5xN D0"w%VJ-f<( X?E;D=,|mSHIdos)\4]Z'7RwZ2d.8@s*Ӵ޻)n)\Do;-GbhxI>ʁc.2Wb2*Gw)p@LTXXAlV:pr<=tpSb"8+;Q|n;NNvufeX悼Θ/ |/KRo7u7DhgMoc1.w= )$7ͥh8$Ff-ZZgP[5,.-RR`R,j23_9j]"\jN$X; ^&`B#@'Xg&ު4};sRDUJW7sFw\#iגsy|>Ё~9(7Q>oiҚ Gk8@.Zdf鰌.XN: Z j0ѵ}\%(]U]Js7wPawOm=Ca @~l68o:w4uywMfZ%1}NMeҝ`vֱw( #6ud}C"ыsz2 3j_E f<1o-S#KpfvݨAЁGP?q"DeH(L[g#Z7N*sh:ΧKdEW6&\c!Nf`Yhda$nS UE9nh6yʢ[rY L$k9MU2 q"E(7)9Mf 9-=m˷Y 0C3paxm ʒi2ݹ&Ϡ;P4ijQUSĔY`p- <9_ Z6`A}A絥{]I0LV"?&6q\1=d̤Wo0:MF#d͜ԓb_.&zmҁ͕_=4T{hcF .r1^5Ǟ"fR[3<`BSjCK VcZ%fwB Jr558e?s ^:uPL6ջZё>Vazj?\B&g⫾iLsPOdVX̵̋hZyHqH+2tbmg*1y+7|qm &WcCn1bt^`@j ˞J&ڑ(_^Z,8f,:@OVRkDڡg=Ʃ'Rc!N;s/ejl> AK=tµns;7Χ|"]Ŗh)@EtkF% ۟PL Nk!\SL 1 +#CA Ǖ6xTMi&Ŏ9B6wWo&'lSskPzT7S] ^kEo&fVmL*=_~E0OCEbz=',vQU'}@3n)4]a{-o_Q-VxkS%WXq,Ǧ):pvǜ@7H^8-ʘ~g -u(;>5F:cKkg"?1%8s5m\oրf^Moё(aW#toK*$є?hhOzSb*GQee88;OqqWwܷȓɽcBcqч]9툠wN} _A0K@7sisTZ4k[l'sKH#rB1R-FN>rbM)vLT⯵4 \4w3:; >'%*[oHSu<$1d_-MdY),HX/c߫3b'TWa_-5h5ZӹjXT O-YMTҧFbyr0 *lO\5/ ad >F ٞ)6ƺbu3BG2bGȊtIfXxٷiue4nKrFdR):7Ji0:[$Ӹ)+*lReS.)rOf; zzL7Bo{T++uEzP=q`$}=5s'\M&cmuL6G!m Ǿ"" 0rlLfr.\[AϾ%Z'8F+Vh/kkmyK?h*L^KԴKr29Xf{?!Gan[,ɔ&z'ͿQ?Hw!YL[Ny4T ]bA%ʶXo?:wcEt,1ͥY9T[xxGp][.Yqֈ hGT-RP.pE~l@ӯ6!7KiaM m4܅:,]0e=(|jNdVX!ǤwbOcNӵdMO.X 3OcxK]SEEJh":PLӃi66<p&QCuD&m \1@{E'4 7Á$y\P\w fGplo08d A%~`% l ~{;2h;:mN.UtlgIk$h'=*$xF^3T`[Bx6f\iol.!hM\>ȉYc&^,7 4>GR\1߀#ܠ7 >J? b-f9T{G>~;V:/ťx— kmit,=4eNiO4)|JYzPJ/~ h33_ -fvC  3`pgW3z6Mj&k d7Жc`CWF&0g9{z|e@a==d , caצd?76$Rjk;&VݣPE2Ab Ik5k@3Mnsnu=?"wYś)B5Y Ւ_Lu0Q[sT#kS٣w%msŪOXD[^'^Ϳf l%z^/:tDzh7k۩D?1,=<]p;Io}]lk"IC+]mfaQ~x۹3PT{*= T| ?&]$c9`Qi8 n~3]&ж<&5Pf83qc ]YAJlhDn_G7~@ x㙹1@]b1ZT*R1G3 Ҁ2&Iu)O>E;Os\AN.VJ1w/tlFYq>^huzD,a~k#|tޱ%~o)sQB c |]Vxlvch5,wm0+r9.20 <|ƕ8>.waUO <67C zRC1H]6<>殷ثT3$m igh.}|I)ѨTh#_m$|C0-Ù~5l6TXJ K"ٸ|z"ꥩ,̺iixHZ~r#d˴htC? =v0`7t/ރ;,*1]4[ )j+Q[5n\P`2&/ÆfXi*z/)gOKϤC, M>>KXqUEdktK~E:r*yc*>ΝxB u}"wK:IŔuklnxv27IQzVux8CW]0 FZ^D64]t,i|`3fu>e[MΤZQH&ԒBۿq7})x) K,Ϯ$IS9R2D9(++5H:\!V0kSDJ-+QE9J#>cHƮQȑlS@wKhݵ >9~B XJgJfSS5ͷw#/ZCVI>fH6=%"|ݘzT4IxaNK?/:µov0]pZ@4 rk=\W ~C[GLuPa3=Xʈ5yaB[@<?uPiܠ펻n}]:ၗ}E-q5a|"cpZT@'Rd:ƍ0ޏ_h#-[MGc2i ݕT*|;Mm>/ΪԐ149VEKBD?"9DJ.[9,%HƆu$e03Ʀ3syc]pCWjAS cf`g-:\I}0~+=]OԘF45M?5Rc|˩:og~OnGtaZ]xvVRț#>Pt6,O.,5.<\I'qX6]Ig|PvV0. Pr@0zs z.Ȧ]ԥM7y`^)FK8IJ[fdE7[!v ]iGNpfoJr[7Ix:шZ, Gi!9Y v8VlϦ_z<}]FWM*,u.HEO| 6tkS>+/֎9N[~$`}&j.x0{ƫ˜1D{k3_'LkX *ƩŮ: :@^v07)qZ\l5xPDNPFmr1 %SzXט!vSbʞH/7̻.Ї47uN}):(>J=ב~dIIƮ[[ShFʮ ":/{\/BK}7GI^D}Y, C5G]ZhvjnP3-BhD{]B h\J Ԡ)jLwsEeaa|"F/CU'|~68VFqSDBzƊP4Mw* оߑd8M5?ʙ|:?]")w` VTSDZbjKx3sbl 0Hq}̟l1+fKqƣ; Rfoi- -2zf>l3۶(qr9&vk" jI e|G!ʦ_jo:MLBl+WqM%\kTŰqjf6M3͕k37=\<ߔ5X{wRO;J'GcW2**ʫyw, {l0EP%I13\PGj̺k:Žj8nQϩFĮ:NwDs|~dZ IT3MkAHѷEQDE%Y䝒F_ОM'R\⎨6N,f6)3/PMyCS-}|}+Ի42%s9빐M0ޫtO㼷 4#9gr)صLUE)پ;-.XR-##Z$|`S-Fz$%r- >} : I _Gmnd)4~Awbw*vV$3N>1QEv5tyc,@ʩס}4ga_y_rB L ԒK,cYncIG6ݬSY/HsKU=a3(MeQk4a}P#:)ul@^qᆷy St89~q3v3"uk+PޏT(=Ħr 0NoYht&j]eC8X8Ëk&@Dv5EڨL2CT|v]m\ ш2zc.[7Mw+Q'JiBrWNuo`TDk(15P߰z'k<&oP#`Wˈ</ )0#GU_ʴyy(R;*L"!̜+68WG_Koμ(9ZD3nl}Z©VHl.ę툷45oM3z'SZ,_AϜ8c?Lf<>4ҀݥD_Due4]%m1PF:|8{4ɈgڂṈC>%G13զ]_GX3+;RHo:+EG" p&X16ޞaE68fxС֓{ PJ- {>|C227 k zhEq .aKO8.f\;G kPż*$֠g/8o-ZJxL_rZ,ONѩRi^L([`Wf>#`p3gvTPàe<1x[Ct9`M&/[)t7yՏ)#Eb@S/b𮪦i4<Oo^jc#Nŏ!vhPKhU}zAQc|[q@nJsgkp`k߿1S黄c[ vR mc/K_$h"v>Jq^S~<ӰBR.6K$3`!HgD/P3gu?C4esz4a J5u3E[~#_qb xrRYg sa!Lgޛ54*Oô[=p=@ v?r!,i!xڔ3\%} ?!b:#ƺ>Y!>hO^]˩DuDU>Yc) hX0SnxIWjwSXlUyo<ܞS;Kg+~PXx'+6Pl2uPIK=3N"T I W" 0[bB.Ɲmմ)lvc(V.u.I>=i]۪ZDiƋV6_oR? j q)Z[ )x3ML13oP)"ad)]NnOp!i>_tёV93pPlx3:ݣ dH F,q1-)@1\K]B;!ekH0%č^DC#tP{sudf? Z<·X5{ōZD2hcz_K+!2*(gjXcXS g]mp \ʒh_I. ?Ryn-]k-wĬQ=cT53#`:ʱ8K24)N١M::Vdo*MD~A4;>ɶPe4VIӢyY+ٝRݓ! q/$f,/%,;Ƴ) ׼2ΝD T5 .*TJ9J D=2XwՊ\51v=ٱ˗s3m^`t6, J|R68)>jy#9<X::v\$TKVDA|?IGC-HhMFZWLی+NydDfyb sa 7Y>J̴i)ݭUUD3rc(Ƌ/@dl7ve[7ҽ()0L;D*( +e-m*f^o L*.Ai&\(q 21)taNi?K%~G#Ң1C]SCNI~79}zx6Vu~M,&/ڐЃ#@dT67::j]KiƝrקJʨZuy$hmTv٣->Nv8`i=w*Vox}{t@UE^JOɑUe Z:ю+iZ@]MF"ڒ0i&R9bW 1oh,5Ǡ2^1%8z"ӂQ/fѝO't9"hm2t~ӧB} :Lu%U^*y ݻ~>}0 _Z|$0`8C _w< N*{b Q/I0k#9r2%uL=?8Qʣwm9x*)FUbNR989EŁ2<{#C7qL']A\_ JV4QNOÞ&[ 7{BN_ۥGST A?UyS(k[Qf [4_uI/PFk fܿ,?7ZjKgIuMnp?qcWX8bl{q@d%21E ϮT Çd޾Nn؃khn( `.΢Q ]'%Pg5㓉>5ȴ.2 Ǚ HkafBbHy%#t#ciHmn@_[=2 ͕<ן?ho5L35ĮM>#}E21E~Ӈ,E ;h4nBb9QJ ?б{(Io59;88`.1:K|gJ)a@#tų*)'w/3٤}E!OuZ95Tv|yI䅟X tvzMRӧ7ݿCTM (RkbwMcQ+>PǤYAG [_Щݬ<<-$٘=Hx8R3)Jkr@H%~?C};jzG{:JZNop:}o5}XL˂ԘF$ϳMkx8G>Ҷ*a88gbc fXPHKL?1 /}KwSX:tvд=\-IJ2ZETu|7K?D_rXfI1WHa2P b! x  xzͧoJ3MOZ/ gn't7tMƐ*J`tJDr@t="60Y{b ֪e- CSsz}I1[}˦T&'74&{ᑴ¿k{3WgT_Q2546߄fXY8UkBO[/j`j:Voo;m~f0bcM H"~SR,e2d}=NCtW!C xFZ\F)Vz?xU,Ϲ4&bWY zI)TJ&t.B:mqjVHmS8c `Dk&q7p'-ZAZ!Zîlpe͔@ow*9^v`ϕcP Wd8ߋ41N68Pyi g!iLތFT)Lx0}V-j%!,Uw=^C9J8H뫌0@ +_V,|Bipv*:#7)J+&W:yE}OV%:5E-4\GCFy{h䱧4wUH9jy),eTMhZ@6BfT5Af^Bl?]FBnyI*Cj2O²E; Hg8'6Qb)JY1at1툠/WQܯ0&$tEX&V HQ%Ez~_X-.BT`Oxƈf fs b.`2*+a/(p#1 0Ê ;cܢ7 cG=9du 3ڥciz2M3P!-p -JiR@2\1m1ޘWeR=A&Ɗ Dt3?dtsqwKaɧRBhh)3;@' Ig{9}W/'^yeќ$J$Ӛ#?Xn*dG-z DgC _H>њ_Izci3JZis u cjhp]L^dž;KXdVr]@V(~u-4wC<}GOd{)6XewvJ-GdpuJYKdxm0"&gPÖ` dX>Wt-xȝew&odedL7gӣp5kGWҾt2{sCH2N`ωT0Ӟw%1)jK{~QuEуyJxRK"C)I1c5BSpţ? M-uU%.wdKzv3]Fϥ~E(`!-54~l,;:1*uWye9Si:$Svr?e^+ظTAM 4B))Д7佲"(wm'5zP:>mGwJH/~@ޮCZf O)&;*vPDذ]l.3䜷 =G'R (͢~^5d]&>6HVyrH/̗@@37X&¦(ҟPp]B|beux1NbdC2Կ/pMU)Zha<)r*$&E 1CȯvJb^oڴ$篣C~OPyԱwճRy0} HM%4cc=qɣ+^ѡn)_NdY8.:6VPÌjR$^ET=?|m4ߓMn.?^M]M꧆h_\Brh^d@5ZC`v`k3(K9h.4h#|mǎLoAl6&Euw>62kw&Bڨ(/S1Ŵߺ{G9Rs6D38N̥TĸyoTPQ% D(HQ+)AK3)'/E<,jVLIZ̼bvDKJcw:Y0t 1+F&LK_$)eC,&[R_P;٫<aὰFœt42辆6Sag.KySԇO9 ƕ$o_D,e:|Fp>aBWw!]I:2hG e˱u69YVfjWҊ9bUL.eQГ j?E_i̤2)cq5QeSASq\y@Abu*s^QJn7 23 ܷDln{3,58h ~#%wgc̰8zos 衃,4F@qY1z;b|S0挗aJkrwJqx045 jB?R|YCs賈 o E$ū0'HqR `>)r;ߺt>0=In$i%ŕRlLb\rE{0B{%loӬ_W[鮛@[F,4?PL!3y-1׎[㨐EH f'[bP:#ŎHvÝ1L`@{L?0M~BγCC$]4Մkh¥Z9N6Uubu8D@X㥋7ͤ׳^5шhGʳ=g p F[^h!}*y"1|| |X3Ӝ1K ^7*'pV"#>V[cK,-K0=bR>kѓRTЋk=2eQ rqt9f,ac u HjXl7s>>$`'&kd~%dHZ#¨LN!.J0 x% ]':x\^ pl1HyT`pg1Dք-oa{ҍ>-s%idžqt~ K/#\h t@}_ 0{ ∯ڎ#uw=g1]U"{ߢ_(]')p^yp r7p3`S[Y>NǖzP7E; \c5qt[ )o#Ɏojaղ{8[ZBZ4=_b,W}B9$Q&'&NSOwCGNQF9}x>E\rqO Wpx 70|ƩbDU=VP #vWQ&EM 7ñT ژ{NGhCs^i |ryZNCuԟNbn9L^_g= (p>^P*5+zpaIw꒙>Œb `%ƀ|T,]C8;6GJM]`8ٳom#Ez 5γQI/I}hn|'+-Z>ejM $Lؔn]wą'JS^)0k|Yyrֶr4+pr"<0IQ2&Ș^&& f-[`%ُ8P`\90 ,f30D!]l VCYM>vh8ڑܗR-0UGD03JM[a2dX)"HE4`uۏxzB|(ǥL !a M$8Q ;~gX\%`^1\=6d"s9+F( XriAlU-}LpkCpu<8]GA(0}L%%"Gh\Lec=6a9TI2 HeLF H{+,"|òhkL`JM+#z{mM}$(03]? >ߔAlm9)ǚLv2\Ėyd(nKJLPô9b|b'+f&>4×0Cdo5B6 `v lVCV ɩh|b:]_N"w~SF}mePHmpVurQ%o5aP:lcJWBW2׫uʨːbQt'6Yc eh'/p_Œk\жư &@GW@VWJhTg r=ڏ̠s(C[< @wɐd >tٶP f}s+1c 2ĵ,ޡu41yV'?Agu:ɹFoolb,t 7Q}_?E>rd2xwKc 75إh'uC|fj҅, ~Lvk0%􌤵&|)sT2vBWRv|54r>N5?t? &p54r?0SW kS.c-\h2@"7I!D]Lqm$T!n2Däɕb gVz,KX$x'<u3\71yZR%BʕB(!$Ĩ8|sq :zX"-x` :AUKkhCpNjeݞ*R;n} }p &8qG 4<~*%4pc9 ]u*(ׯR?N GZ|5KїÉfm,E";Ǡ",`>C/ +DT Nc1])wl ^-2Gq2SЄ ::+B-.PSf:J5ՠVNZ^oM5 1V\z2$o,al!F_ӺZ* ;|$"wK%X*Y˥!؞A6sLM%ގ`Z5DİN: "=\Ϫ~6Aht.^{6$LZ2k6UA 2DEc.3GE-awrh` B-`\˵[(`= ?II!zJX+CBJQd)ƌbd!)KAV@dP"6>dgd{` \krik%f*K/yۊT>Yf -KKd5ΪhNyV'u0a%X,}uo,a#lPiƞ\)JH(C^\xvBM :$E6y8#B1wbr6*XPNA)oF 1/4>f(zɬ*H u _E)+K" | 1q>ম9V[a>4p_TlMLMgPuTo@/4E:mFۏL ~[[-E7B,"B2K 2ý:sx! ~2vÒJ}|:Mt@izѯF^mYYItaYunsU%n^Hg,ܻZ5کy7hb&2t`c 1cp:+^c\iMGѵ*`F x1FO=0d L BT \xl>҇#J2Iz}\ۨժp UGcR6m+TNZ,, d5Fε2wAEZmF1=X0k>4;_;/4yw#]o&.w!̺<hmnIl5E݋,֌faOY-C> v;N 6z*o4\bTq]צO\-:t6#a*6NmyRI7϶p:\0d&R qm>n!/2H}3,72ǃ><|o1XPЃ L, R"NJU #/% abC5c+Xj {],J-Q?)k~AO趓:òp|),5.k`=. q[Cbfo4džC&0O2 ۙ3k;մW#vVfw)P?Ap4jh:4uXiM0-ϋab)Ed8\,FH<RC}GWi'Qsr[CU!Iw/[h?c+;u8@ ̴QU ˮ;faz#ěr9]-͙P:P7Z4^reGC_J?)|c^ͅjLn 665 =ԗcN#i+֐Ž t!da jY׍!drlG?"x|U%c~Bǩce[z<͟K:8̥rD1nJ E{{ T,ꡢƈwª.\l9-:1k-*|ݏuji~ҠOPt6Ozˆ=D u4<Zi M8pAu /opq鵶x&b'>rk>l9k$b%n8`! ц`a.MLATE4>jkYTw'\ީrK˔=>W4SuJIϩ ԯZƞ$W6w4oؐv1B]11~ib;'q(pVjk`d?: K㧙l4îfSA&;آ,5j sbc[R6dэtpWMa E%۪aB Ia } eQ|Ll q3jl0ƻC;6 T[iUvFv?a >fs!6G9#c 5В:v;RĻ=b-`bq\0]3Tb{|d/#f|\e~Ge,5z-KІuS܁ǜɁqpg^Ɔ~n|ݹ~On?YL` )a+^" հ^[tsdJu8[?,9չ c>Ghr#o0k`rert Yfό8jige=U\>ўjZ)W帽*|iVnL G&]͡j?quT9=BPm E aCF^iUL:&nteg$_GVix9b#y gq |c47-в%s7ɸv uK~z2/#'Rߞ#~jK~Ny:Ŗ֚xv6| JߪhSJXX]+z| O7#'/َ̓9j[RLPsYKN'2ԗrI+y>BÎda~W#G Xej{gFY{T:ēϜ+yREם(RyC'9TߌfKnmT6=ܳ+Kt\f/gP䁨2|c _cc& y2? k!/ϹsAL74Fʭi=Ul-㚍b=ޗwuM~v,۽ݴq #b捛>UG, Wj[%P 77Z- ESͻ^GG4EضaX6-A6|,i0 ËͶ=jh`ޖ81Zʚ9qC/m#-3ٳu;\o&léw^(̡޳72-Ho #tV~ 4ghƉ,T, ;FTp,wM`=r?(74J)|xeyBƳ<&0z3VL,^aXʑG;2]8"ٙ.;]qͭ\3ם JƀBt e/;&Bh^Rv;\X3,fBF"~l-Jq/ >"+>5x> C閇-!é sdwj:=$YޙsAv䏉~K/gN;[,ΉşQWRg`b8k0諈G*UDJPp>rlt _mׅc{vCةCM|P'BW^¿*Ƃ+RsV\k_]hl1 }N+%Ǚo^ΉF;ʎ[6(6r@`=ۺFndiwŖY+SϬ*N"g+O6,ҜT= !XF(A*w9Gs%t1uKWu4&}/e6<s8<-l8֑ 9rG{>J&ԶpŶ&0]˲R.s+1t!^=?>bLTYh *&w0pKfނXG`fk\KA8/a⺻xr tHD\ hU}yMat m'x/clGW?wL~V*;`ПH p1pBU [H97PCSJ1 )ٟ1%|mzOl$vlo0> ecֳJg[Ki͗Tt42Ԍp1~F?긩zz]OMrfy/<܆F12f 6(C1mbi:zUrLYU\|P}7$|"p@ +>,ms_wMWb.3zֵgV,v%]Jf..D¨h?8elNL ȳE)xRD;.ĩg.LjK*GnvhK&71ݫ=/_b4CDɲ>^͘cͱwbd&sO jb+{HyAD_'<hL"i}ZW#|W=Oer8޶`"'[s*|G9B3p|~4{{2>%6-+BlJ8fb$,LÙz{)W?É13 {9x|,N¼;'bG 8:Ȳ1>Vb a)5Rհx5/*v.' lh$[NcIpy7w8XdrdG;<`L=" gǟ#PC<-?Q1ؚ{v)hb}9$]O)wH6Mr<*$f=D8QF/L=RټTG*=uZsr[V϶偕6܆/Ӂ;1-GouvzZў7:PBKps+EK&k`E&qދ_C۴ݭ&z>SSǷ㴼Dϓz{fP9/I(˾_疅>ba'0&ڿrA&_(E6Ug`X{8njE?(6'^? +& M巭u|wU_;IO$}xv#Qw!ȇQ2/ƕ[a- Bz"x oy/Zĕ.k,@K.iAE/_8{js=~ YĄej~ u׮pÙĎLud΅֟\xiu bÙ zqsZiY~_5#(8XA!%VXB̂b_W%!"' pC,[Jxo |/gB3;eNڝUdWT3}xF;iF]\ ž^NL=WcJGZ s!*yibXf9"yatFⶣh|BmΕe#F˛N-W\r2AcPs0O$^]l(ڲ=zi&6ijb~\؃L{6>@|ϕN<̖O/:iwk4GJΨ>b%?Ε2PdAƉb.W% E֮,\wK~n#MLɶ樹 R91]8 PTlSu<`╩vT4pj{68 ' uX{6\ioL\Á9#jbK5di9ږr%H0*1>M*<; V%`K%1Eɭjds2Nrwef\RYu Q~#:Du7^A8oc!Xx~vluIΙaޣ> P~k~8fqD|l)iPFX4< DRq1z4@3/$\D 0N!3z΀˦2 /D1jgwX F׊ƃULVmifzvItl㚻܉ocw:SȉmaÊ>;7]_ Rs -7jy[ǕM*frK]ݱXH O3s֖UKY3xt^&㍿"uj5Gni=MɈJ560rqس:ٖNY1ԙ.-8qwÉu#ufH{JnFk`|&bڬ/ƅux`H 0wU_`j,Z' vR{[r )/XKRżyي"z&V-wH8踄YPzX'@u1]B @\zO3\y6?6PV_YF?;E@{(y'VʈP9:XΜƩYn& 5P Y. +%~b>3twK'CA6Sguf#}=莟ufWa#2QŖgڰd=i6I-q"GޕE]tww | 3. /S5Gs06ƚ84cbLW眘%T>dX|dʃ |d@7lfd }4wU\E*zh楞\tB5Íl(W̴ wuvG=g$܉38q0SU%Åc>4Q*LHCisYq8}Kq~Yp_S &%oD|aI?yì=f^C·O<ލyĤ1hS?0M{ pKO[|xO*ײF͐Gw41 ʺ[z5$J9}Y= [")c>Dž 8܎FX.˰CTtaV{>ʶ7Z֌VUo ^{Lҙ=epcxOv9Y8'ͳ3>հRMauie:Us8`FE$IBO.1 1K_[UG kF9^E" _2_eQ{-kM6A6h#3&;rvڅδuXDk_8񋊇k4<;#-+h"9?ԓ򙏘jz6b( C|>W#uOaL |YBSpgD.bbʰXZemZx Ú.W:e/g`ow8sF\zvbybZ^Gϊw:j,.r1ԗAx*[%b/3#Ґu'~|0g2rLEux$o=!qPJG)k g7iOO{ad?gFgF33gU2[5є45zC_/4̐rl7UFm# ޭFX,^4ch]1' |%LHK'jf[#jxBt\6T;Eowdnܙ=;R2Յ\7˅esp# .zeD`:*v&R)PXg3˘ϊr3~`TMG&Oоv4COfޱBHoU֎Bx8,z_p)D70|QnC8<Εg+)Sh|k;kyQϏ&$3~PTCKšݶ}ǟ!Y8 3hK}#qدڞcg9[658≑݊\QC%}v(i]d3f!7~<̔. к 0c.PEYְ754Ax,\χ42q2=[34g|xF۳l:aA7)2Ԍ}燳v)C8zVS3Tih;YejR\[b%lLpoo{p#O:۸SfN6Hpcs=q@[2I`t=/MdO}58om#GP_&ãڌ'`{\/aRo9WiHdkG )/ݑ^:#LqSSN\ׅX;ގ̆`g`zuOkĄEܫ0QŴ1_Gi+~"_b=EEcglAAy7ʟ#qW Nw9z15=bKcJxJ!m4vlHVE']{]8u> (nӠx*x򤰓r9_xQ W(Cơ2 GV13mtfǬZJI(QůQo= kr,§lKJnNiT p`D{TsI%~\pF:N!ZnE۶v݅o͓=;O8 ׉wmぁBnjbDE~F3jtsFJI%V@{)w@|t[B ~UʧKL[ XswL=lZꖖQ+ؙѾ*(KuLTS5Vm]>1 82~ _ -\sjjp [a D}GzI\s=yd+2wӞ4b ՘ K廱ia,>F}?}VWq"~-9M!x߁W+bSaopVpkmX?ds? / Qs_(nbZsO&p!|]E*cz٥fE 8^`rGKi<,-fz& 4jsI%as4[:n(9sA rT-3pa}w7*  gvp4iQWϳ.׳lK|r1]*B,Ģ< .s"i\χ{>77q7&݇bnMvbJsN`heԴłz4҇1'<*C7n4dbT=Oj6#dU( |%b۩RPji؎W9pU?TGmSUvPbJn|U`/\b/9\(gGύR2(D[ -.*y E`oɔ繜IXf^\vuɍn<6דc{y2d ;-q⎺T^8=#,`F-l'br+.w(zA/V%M$ TN{-8Zi>8btokfж+=]nvysRsN{э;9Q9Dϗr } Ohjv<|nL)qH~Cǟä8vrB8 #? q16ʚ}eo:g>Edr u뜆$V`MH>S!(Y (/IVs<|~v}loaTxbtD|rW2rzshoĖ]Gwfm{T47?yǖxQr͕&n!.|ӕ %wff:+'#g:2߉Ubj3~sNGn` 52#h!amX#57i+ <_x ]} 3)>ֶ<*H`{09Rpk3U Jz\Աu=jY>KJ8{U|0b( }+$4kh10u-2-B,4>%xx _KJagn·V"Z)!~afA0NAB}]ayڿ[߮KQ_{f֋B@aeհkayy^nJec LOT))ηbocrGjYnӐ7hm9ow+wMPfɁU\HUC<a 6 )V;t+6kN39ž|̃+],փ滼D^\/dj7rD.r1NLf`BY _~}3Ln ;rpg*.YrDˈ k5bA#ݵl>#x#ߎ7:twfYCG^YĐ>Aah3C+.&<6WiŜ^Tr *SA2uf'=Yj cӇjcMAf'O(]󇖫6؆}k4kr;fmp⶧*,Jn_~~/~ 19nJN=vpG92GWyƙm]x2Ɖ萢aL2(Qw- 2N:bv ll7z6<CW)-n+ mBx#>}ŴA[f.gŨX =".]SUJ׷'4Q+X}đ=wzgbVK]`j"8:sZmŎ$(Xfݴ!td:-mX<ȉ:ҧ&R[6ixBAXt N>UپS(Yl+evk9_SҲk=un¾n4K[!k*x-=s`QN|:ߝ3݋\e'.\xcN2jx)M5e2j*t@5u[/ E\;CXr\!-$0ے~J0vi3cfʹHYVևRZR$ǁrZVlID1{|48OwC4Ϳ6~v]̽&Q?PP>=NGmRQ,ӂ]&Tb SQ>;.Ʒ hS-HS{4va#Uq}KX 7+N%#KeXRA׭&h*5*L$s%3H83Oλ6<}5Ӈ ŨP_=րcWȥr5ބwŶIqTx,xDpLD둆gc}H?DXQ75 t弮tΐlÍlDqƅ_t*0Hg+cdLs^_[uLqsj<XagrƺNpH˨<9|V0+oPfo0hztE8q-Go tX`O'=Iao/`JW%{rjW]#vUWFX(y2_:ߣQ:zg3zNi,= ]ڷƾ=C=; .BZ=:v' W=` 8xJ>3^ `,<۽>4g_7fz\tuARq6p/V9*Op.ny.4vvdIϦ̴2e.Vy k^n\4Kq9XsX[?:PH33࢒ jkvM-k1f'բxmhU_kN^?<[ee-I݈a;S~T/̹q%\vCa=4bJ}sIؑ;`g\9h'{<`|7~?liaDlU: X$(%Tq%=g??0RvY>Ǧ:!~ z RWx1|= S/ 'в~ck4lAuD&:Fw( 놡~;,}c ͆,ߝ~ʚS+U˥Lc=-Ԙž]FjrMTm9[ftm|x䛈2! ط_Yv^mwP`h;3&)lMy-ḧ́r~ֲ<\ZCIӇmj/^\Icmh[ooL ۢU<9#2)ʇ0O?,-o#321ܱ]wЁn Ok1דO[ZX? ̓ǟjwh`p% j@oUq\# -g0]0y|N_e<%ӇDM#Nj_:{mgzJjXes\]Ґ:f^w2vhy\Yx-'%]Z M>NJ+W&R4rI8+E',ټҜ)"*FjLU8l yV|⿏hctlb9{TsM}"FrM5W#"Z)e2\`~&P`?o<^.ًy\yj#oʹeΔ3z`顛}d :s?Smĸo90M.@ߊ|թWY]nFR+p%Mp͐8 ?(:ks5Vr 7gj^"-aGήo|ąb=}b\-= ZJ.nc,x|)|Z< ]u¬/ooë0in _4ݢp,3]~ljuf:h&|GBfr7KT|KR>UI97Wrqw*lsb8J혂ӳS\=;غX5b`va˰3,D'4F6ܩֱK *FUi898DZ{Ok5;I`..OllJ;1]_djwhAO^\h޿{k!$&S1{T'd".KӜj?9r{es,Gvܦ))!gWf:Ӿ7SjfZϓ9=X O{hfʸ#6X P o0r!i._{`:얼Ď |sk!MiSiJ8oA"ȱfKOL|ߑ Z:.ptL wU0.D3D®)"SRN.f~O)wQP 'ނ97_5&pY5/=?f@MNdz%)D%Œ<9؆򫁍4Hi3ǒtTRq e~l .&N}Mexk߉:ּ +`ҧ(eQ({ 1otj<^cغ<70v79\xaOH tOdr.粦&oϲ 7^we^O#%*9CM]b'Ҏu816{['na6F]BSת8BAQ6si:fQTX˜s9lsΘsΘsnDI$Km03g(i~eކ㏱>Aqǡ4= WM~(HT`yeXm^6mÓjPMSv,xe=OXqc5F-_UVEZ CrQ`S7,k6oy~<@H(^e: e#k|heCuv-3,bX)LncS_= Vbd?[MR#pLL9?'y~ >|؋3?dž{`: ۝kկݝmcjO#[=܍T7!P:,W!:L}ÖLxo\嬓LբQF֌(z.̈́(0GI^cL ~NC/|8Q3:|͂۵lYbœuCo&I?ax%V$ʲy_nW8^̿AAwԺf{mū:C6}B%:x UBÊeXP ,|O@ČX#,oC!iv1oeoeZphs>lͦ;Ѝ=kwՍs1C"<ƒl[&0W|gϗ?^]߷hXMv)tUc\ 77/o?WPcX1dw'M?\\e`4 ׯMrP_5/JҵchʀyHݎK8l s78* eC>oi1NWBw70Lw[~vh1SmE)~b6vH/q1ʶ1L{M;x:LkRpqT~l.7X0;hR1 O^@n~nߣѷEo4~,CH.)co(cd le05ŗ5Y{DrRu8.~{-nRg:G1vo_ WW~bHu9c^5{ɮ X>՘皲̂|^4C./pN+QRaOEМ;53vksXzE%W e!4N1q{jl6d>#0k+CK֚=SՆ?.aeHz_H&`7eX~ &A1US.6S׀ώd8f%6MJq-kl]-gwa ұV+:l[S跟Cf ޱ 0w*ĤX'"[BW %ؠ^mdD`ȕz2^l*Ls6W%漿J]ô)r4!h3^9Ե8aY=71,7t{I` (G {)Z8, x 8{/bĶFɞj,yU+j\&:|d"Nܪa-e<}ߊm]lb Ma$G2*͈6luΙ:0ZftإC%/8* a}CWP Ʌ|aoBRUlt{*p&Jm)75{=fDlzy^0}K>5$6ޮΆN&?P*&oyWۀ +ڛpۍ <&܅ką+9,Ďqvthā-4YZeypF_"l2~."s15Zn`ITW-Uo)G. Cɽۍ;]:ֈ.kuyZ)kIڼV֩Ocz*"e{m^6a|V  X;Ni j+e%e 5U{s *T+Gp(mFjs}T[5T{ncg|6bq9A;gn tlc+ZÄs>] Bl?- wpssZ/+?ѽD"c4Gxt:aEi9*7C֞ Jk,8#*3"44NOfk⧖)u)?8~Y.GуFŬR1M>Bn[QҾ>t83 D6"-bWgvk6vw'1u%.a41۶uP;c{ҽe9YiX1jґ#w0``%&ӣ*G#=I==짯`KL2Jm~}G翠5=LD˧Sż"QwPh6ksJ(:Eb>e5{Vko+|+,rz#xPDB$W @gB9 Xej ~]j.6fC+^jrz]f/J5W^uym%ZXSgvWt( ,7|gwdz/8Z[h,,uKmB\j]<F4+/!vvc. $dƚ. sgl`"NG:oG<Rp!3V$we֯I7CV>0g]WiŒ"m]Mm>Ҧ~"jsCE4}ZZXl!ƣkb.73SBޅ\FjէIVN2f6AuX"mbá4I v|L.|=(Ħ#2709o*R]{cu8{1ޡ˟Tasl4P_ZH4(͆vrOμ ' _d66) 9%Pc"~EFl:M涟= pU*wY_h#MsaaTtKо cvӻe[WqǍո} Sph=rdÚ翙)eGzWP|ш}?벍v=X`n-YztWZSżmū9 ^==1ם+6ҕ5ٿށAN\N\vГq%EN9Վ)vFɈH7Of= heE ͵eض'4\|yكee4Y+*9ed SByϚ'ǜ(Dnx<_y[q3F(a_6&lDuTx}YņY3FW5Ð3ļ Au8rķyݜMؿ?oҲxf72^¡L MzO?% _~ƪt'`@'$=פyٰmg#vI௮aRN5 P3u\y9}v*EbD8E '!mF m*Ɓh/{ f+9rXxY%yqq0^¤?TH/b\Q:/GU Gy%{ÁnIx"]Z_dĉxJӍYRn٭Η(xZɝ:rn["aף fTqap ga7O/-Q)`2MJL}'6} uh[q{оBDSSӎteO/%ci͈w!TY.\(gڲ9h?&Wa\}&y2 m>Ɨ7qXu6{nbSؾ:&!n"}t>0c.}:glٳK#lzo($V>tGޓ>hNf@'IYl$`)*f ;[(PqT%W~%|sQ'IyaemppLOV_塶G)~(a$!]j_ڨSm#t)x>Wk%\0h/ 7O/Gthom/G=ؘ!e޻(HˇT]Q.bO*iLq31i'l"㓎Y֛ːOd&\b[W,S᱗Qbo:r[lڒ >C> ӂS ^ܛ&pP_`nP7rv UBy[ #[d x=m7h{^oѸ_{Qރ~K`,uSljd_[< *Gi[&x{CF8nEܐK,xQd.[2ǎu-ϔaڬl@JF(5Jqch0ʬc `8, ^,>Wj)rg7fA>+fJ,uGuXр[XϣԸx=u۳__:q*)ސ󼖒w)9w7*d@Y⌯J:yXxƋ fa//>ItإЙŜp^o|9ћæ->,Ԓ[lKkA/y2"i{󡰏|mi P1HI@Ija'}isa#~Scm^i^m[ʜR^ }\?Yx9cST\C?UF)-6ɇ޽ MK0p 0](asz}?)={qZ9K̷fX b7Ҧ[oMfYHCS=? 8sx[QjU1Zwu3Dm#t9.W)}ۜ;smMǖc}&<˜Eb f a|rOjox; k^ۓ[Q#v~ O?"bgX׍$}[̖)1O[isM=Njb'K#(}vxؒx<&o K~q2jgQx&YK1! }OEjƞAz[m '"a/Wc^W 3{w?*vI1bG#.3ה#W>,v!R8OƦaN2~jmi9/y_AI79Jy;Pn^oUtLR:RrxHHC>L>*&Vq.o Rq-*_.H!'[831םT - x37{ ;do>,ol}2Ɨ|yrVf)lŝ 9N+pw;a2>h/ &-sSY][LV  =w.~UbzJC,6>Oja/*cf5J`MZԣaV8nGZ#M! 4p~^DhvĔS3~jر^AӽJ7٩)RrPr~8(eJN?ނ~*Fkw[8/W{sQo7)vWiђmjrD-ngȟ&Tb"{Oe"$e_9Ŗ Oi+K|(]-Xʛ #+R?Cݸ% sOfsjoWPx0Ai U0NNg{c<2S€Hz;8ٳv[zq^blt:q;^wp6p! %e9gk y[Mn%) ;Fi ZڜoH`[` a449b`kՙgZ  h{mшMY}XهF {HG2›'$NlC%RLM&r!_ e*mjAGÅ 殺H l̕*,(QyH_tӱQ#ے#L]Zk̐lk6brUq)3UL|7) V#FWvZiGmYvӝܸޕvFw %'^TOL4L%Tnu \tv,N-`2TyS<+DL" ~%wE{x䒎x./i‚9;+Nb62ԃs̿&q34|q =<ܪ.4ۜ ]][{`r7,i hupSGD7V8ȋ}}PK:kIOl,euWr %RR)^ +cZޜ}%_}`]w)cZwvZxM"8HE°o FqeM|$",Ua\eirkO.*cY٩b®śg+y2BK̋^ڝm8h 7L;( );$'_9j3U;Ct4e-kөb Z5}3 NNûi(R Q ?7-F`(ϕQzcqk_ W?YOfui2 `5}az/ [br<BRݩE8}Q'tMBLx,ÆFMٳFsޯ%VFS$,3 Pa7rN̗di>ŇOJP1/ {!vr63sp#cSIX-8"s=R<!ْ4딁ѳjфA^w n0~OU|Ki7_=S𨡊ϗ'Tƽd<+]\.r^ʏ*);HE weeG%8B/Lw\5݉&9ņi_̨iM-ux\T9+炳p~6#9IjtNZ\%`&NѠI1&nlor]?<$ )/pk\ e *^ץ<t9bxq?XVoҧ NjɛZosQp:(ˁ {Ӻsس&#x@% ]vz~Bϔ0l'ݾxQZvG: R^Siq4ߍ_w`ƪhHۈ?oRv8;!;La=?JXb|[+o{**e%*xW2ZT1Gos'IX̓sxqD,x3tJn|ڕ򝘽Éj3ښ-y+CD2+wq <&ףM>Z\`{xsLSP .ŐCh}W73GLwSo݁+6[ǯ7`ċjIZxᕅ7q26ƣeଫ [xn7uva^_k;+#v&QJmQR)ʙއ"'PP{X 2L/n^& 1j\6\ ;9#k SuZ|'|q@{)V |%ֶ[`ϛ] y77s㊳b޾,Mrn𫋌s˹GdxRC.Koغ3'dT{I:ʘ:d;`w>w>n\ށUƺ,A'Ј;gJoG,x~-7~tvWY-Me(R.9nJ8K͈^LSZ ._Ld75uL[n4tb {4\OGN6U +h̊bؾ/Hj4/f}XfÈ-\?WҝޔzөЗVDC sn ^7}*7TB2C}>,:QR#gYm]spMޚfXEhQH}gS阋ϟaXw% t Db+kFK!_B3%Bvk+%t??yzKUxyi.l\Ar6;a#k;;g͇,59>gpَ-gGK1asT` -7u(bDzo<1\n׀Pgś/xsLsOu\8=7wzJ^Tl 7u/u+ˇq x6o]]ϊMymB7Y*ֈ7jQX=#X<^3 Grн ǡݞX2o\/E]کlz~ Hh6OoN6\niO=p9of\?W&fI7MJPrtǼ&gdN M^XPֹlRE8畊=/87 PʒDN@ UgkqJAUj/q.D14J-[V3%;4"Rbpq*j~G$HqF4/}G 9}ZZr~;3<9[^lWŞ}ۋ.KXO~-~؍-y|ʙyq wzhwvwta1ҍFPϞv\$xkh9nf3 ͣۥ82+J&HMqo?I{^ j҇`dµQ#"z:)Noq` 'hɸixs\){qi1u O|I<|9`ekdU~<8+.vMr=kHu5W"^1&3/T}j~u!t[gp`<7?°/A:c; sF@ǀ3@ib aE։aN5(|)?'_ὂy^Lʹ+g7<rSة_iNrҜs{sbA=5 7!21j6K39r'n((6W2wMU߈6.D]xM*JL=gw39兀Kx<> MJo]a7XUhy9.jeUTuHQUa[*eDG&芇k#`eղQ :ո N:1r;rgpzDW10!?ޓr8%y6ы6˥\?Փ+\=h͓s<9ywg5Ә+&^KR3Δ#NZ:[Eqz KVlۆ[9cbvJԫpu'm>>ofv`C՗0\:Nt*Cۃxc$xo.T_/fNPs-ᐈIl2HƢNq13'UgE]+:v`#yƖXi/^<62y'la/`+[zrt[ g~򤭹 3vb{Fv@8Y~1!"vѾZhs}Vn5Cfl,-kFGsa#"e!!NS:硙8e,fD)BHJS[Hrd.Tx2d]٘h!zB?Gr0Iğgް˜Fʓo|W Xʆ2ʤtYȚzXd8" 91zc&ZWcxL,}%X˱\ 7J0{#E ֚[sWkmrJ/ yXfYhXmy'q6 NenMmcsy7aJS:nȱ׌mN';f!cEmID£27ndKrg{sn<ۋJxd\sX3F]mA6=/gcϷDxdIIFsh-~5c4wb$\tR63N0OoPTk.zrhrnrh9bBو N4rfz3披ּ6ۑx~ozj=Ǐ-MEX1о.73L~Gxr0 z䟆!?"S,X}=:=a_NBu.iKz|R#B~g:.V{x2U,M]xe}bԍ8OrgD3#ws\[ʶ`/ Uوk@Pk1x†ށ}s.:g#O#~d܏E/T ՟!gLHEn:nlZ9Zr3fPD&&}ŭȯ(H@_:΅E )ߜ.Jr&8Nkq㯕 إU\M#  7(xycJv? _GBa T_s7&SNhV.znj$Р~_CaZ^_,%nɮ\Ǫ=FtxА2<>UէCAg:3K'ܖ`?aa,zK Ȟ;WߖIٽ1Xiw!:R{~6clz S}Wqd5؛%Vmu3'^x?<21)0}8cTc6 \20);tZ%BQUEt׎ s ?x$m^aLw]s>ssSF tW>jNQߥk&aۗ$4V\JT,dc}N5Xb_tZޢ;P۪txަ˙; 9qJCTo#[=Qjk],=Ĕ3;`pi5^gc].tś gkU ږ9_1WT=J],/`u)?w EnȚ<++| #}r2abLT*@AB>OŶݐVVa)]w䘱VloƷiW+һܴ݌rMy0Q"U:'~ХA2.9"\s0% C2oBBocyTM{Q RhXk!6W,0Ĉ7&sL6boG'lֈ[c jXpjwjM/a5L>"z*N̠HjslD@7i {]ZWrT.j\{-8͙&(hΩMyމ*9>6#fh(t~w呃ƁP s̯{ W@B#U/s`H oh8w[)bʪfՈfP` Z ĩoi͟G@.ow+4RYuoU{\>ܷ/1e2#0guL~i1H*81P[yci1ʪPVS=toL|9?U0u' i[v5 Հs{373/2_h);2ZY/F|I]zǜs{ oiRm^Oң$cj?z[3~ yqO<3}\Yi`à:} M>7V39+ny虞(\) c49Ff@ggkq͑l%߭5h鳽UĪ1EʿШN|woiCRQ2o}0Mލʿlgi:4بA˄יtۚ-r[fI\=8_?c=;OnV0Ё= ٵ4CmVuU [c%c48t+Ϋfl -]mg ͘>̖'9s^>yS纸|0>̘ P8}Wvea027*m9Ok0Mk)elq]+qF4,(^CD咗|N_$m )b ӥ)R7KC{ 7u3o pi.틃"/fQٿmΆ.6ʆȌn|C=q-ʫzIO3 ˮ|";cR-. 4b v g|ەG`+k81O<\ƅhFq+ˆbY>:L,W=U@/z(Zg҂ر6[/6a:`Τ\6~CuҔ{=TTMWMކ*]namld9T"q)Kv(L/p)G[ w?1將j{cp+GaSRЫ%cͧpӳfZhepxhVݤ]!B¹r\śmhyނNr#]:z 81!Xe,*Uok%>}kL"-W]EʴXr.apr8_:L=JZj$wZң uI/R*ۇaIjKjQf|>Ŭ=.:'̐Ub3r]Nc&<>sp]rm.î~C_ >Y阾%gXL4zQ=%nPrqy94h5β-E$^G@$ޠk%N_N1ytE> }( S6/a'zfÄZQStG/Zsj0J!N`,\hCn.]ޒve\[E96>T#uSeN0~<@;815cQ3[Zd gc-sd q9hFkv1ïW#l;4n=~  0_-ۼߧV}9|_ oTo(UeWuL\JnZN(h t@X )c J\3-omοM5cK9աa_4h;̐хrY2.ϑqR+5؜#d Z)s|62aL~6iA;t9B;u 58t/*E{[/Og7 m[gnæc)Į9ƛaIġ[ͯEh6X5vpURl[j+_0ICWI-9 y(~˵M^iOb) v |T}&#} 9+>Z6KNiap5I77FB[Շ[jExQYMc>wymo7:!-X /E3[>E`\H<>Q`Ԯ4Ra򳈴 tn8NL/%y+vE0䙜EH^|X>YLѕ*;atNdϗ꜠qV5W8W/&jIo:tXv:tW#XwĠJx1 J1ޤLb?L:FzE x)- :s+ P+s6?1X隀kI/j׮cmsg%wR+D̔u4|#0uzV⺝?ݚK4=\4"VG"W`` ,|ܑ+2cs&?B`ZAL2~޿ttp޴RC (@{:|ib%S-g Yr ׷7RS6dU6g\^5z5Lv ~l6ȪmR'i}m:H)JRs̽ʦw/)>ڋz/Bhs%"J|» *B,]㫹n Q/T}DEY"ú9{q[OlGi^o+snنFQhlkJ-&|=Ɯg?11G0s_i|FaX20&[ށ}*+Qڮ*u}sbw?ANgC*#FHs.i+hI@IhyPzQgj|uOFQ݇@[Қ/e⹴1:i,{UL38,ȝuB <: kao5ަ{%KP-Sn9Kj=@Mʔ8_m7%9G*oUzFjv#P?2x?pOWwyybB`bY<,ID ܼ'axdIS?IFē?S| 6C•kL-_!ʫܔ^Czj/^=_a?_ᱩ^W{p[Ij+M7Omx 7]*m?_{@q7Fa'.Kd:ZE9왶tj߱                                                                                       Юծ˶Aamv2ع '~סBM!eUKpEv6ĺR)˛{Kڍ_恃e3){l{Hk[!qvk-dZRÿ)U]fgs)E*O,[ :}Sar؛$xV{/ +Z߿M-.VF.Eݖbk [;,P'n-ev>H  Aۚ`G{.W>j~Ug߽-$^=.hkʳ!$4^}G;Rw2j֟a8Sa%I?hͽG¡\ yL~Ā=:WJnĈ#Ր\E}t= X1?UjނO0"ڗrDAg(= h; Wn5?+o9ԢW+[~I l{ בa~4U ͪpuEh~Ɩ12·0=75apC&3K$s"5qbs{gN~oj[ owrop'7P 58D1)2^嫁ΧXx~LƧx9͘o|8>m@7JFUr5̓\ 2ytCb_"lé)0cN˚6M`!s+8 C񾓌f65:|:neG~xv.\i=W^FҢhqPm)Obc3>MQ2#>XQw=NǐktB)z K,W ͤqf9"ޱ!JMrSqcfTK :.E(q(qmh..cZo:_\EµK8M#Š1lVbaP*Zir I@<ގRiuKmL\=pr36.]{gͰC&6KNYC u&>LΈ:M{!g ҡAߪ5x()Rg]~vڂ&L4moWiEgjأ `T5>TJr)EٔO{;J#-8~ SPd\m⋶lYmNP-;]!+bߌ㣗ڛâtm4r١.lm@5Sj,SCB"vļɺ [`N_xӕ&n\H2{~(畡f-㮛:\Nc6mo- r{w2uȎ[xJ]0dcijN5<4Hsfq9vEPYM 1E.lk-藉NI 8\Sƴ 3-ϚV6^56eh/355[1Ǜ%[ ' Jͬi p.Di>s69_[z :̍C#;4b>sƲLtfӸ? L:9-*/6֏hYm>O} `~8?>5~fK>VXqf#N֤ET56̫ň:,0fݙ_pa|k^H*FaH}]5FUbRT˻|[ωz)҃]4ޚd\Ura8 ccOpv[aI߳6߽vuӨRt4`_'f֚t-j}.c%ĸD~^ETR&3o}Gnr:o{usdWn27}q:kr~7紴6yӌfd+S8Zݜg֚>m^k%zG/گՠ~S߽vQ[rd h;1Ѧau>`wXjqa4~GCL˹8;o񤷎`nŗz|3B;kPSW 5Xu_#|UvBY-E/ R7]k(ڋ9Q=O0L+Mд,˸} Xd6̇D [ufuG:Ʌ/VitHvQOݞ9Fܿ͊mL9MgeKXʘ),i%WK}KU2#A^LTn qڴ=SLW+ee Y9)jy _6v'箦]sYI6wr+;əȌmM8緕ѦV2">߯Bo'l?&kHT]1Ǎ\hŁF7ĂO`W7Uϴ_> &y߽sH/mC8e.Ⱦ^[s' =iʭ2DGe~a:wN`#:ٲR0Ή;0c#sby[7^gk 㬸}#a- U=J 0g9aLm-ƚy9yo5\c6@K4onǒ Zȇ4^;\xM5G8Ҍ^~>I/-M贜]mx +Yf|ګͅϲnmxc( ~kB6 >Dgrujxi˥yl{\qwrc[wi-3b>Sel&AS s];r -wuqaN{K]ꎫϔT?e|oi7n+7vBWY'jpESL U6%U2 2s]LXg'U_h91H6ęg*XzםܸFrN\MʜmM8%-T .9 |,T9]ZR1i鳠6<_3>{q>>ye56a`Gz;qfM֙s*-v1W^Q3>Ѓ' 0ftfļ9v:'VBe7܊{O8rx%U=ԢuV"Oec~;|y>e٬|x}8/ 6{?Yਿw M-r1a}OfXSs.VٷTIbȨ2e ktC-_ijfd,g{.qr>,4ra>N)x/K^=oI55Zo5JŖݖZ5jS@C$u^0SqBxrm7=CZ/6̘S[F?ԳfGxR:%_Go/=G'}\X}X >8Uz{eRɨN-i8oPk/[N2RͿ V`zzw.@f>^)cr5,r_M&hʖ[Gs}<80Ip8*燨8Sb{+ugJGB6 jm' \N4B=-}^hOJG+[U9b/g^t-}>y˸;%Z\Ðݭ5x!_3 &:,SgE ^+l& \;{5yNHڜX1ѦDQUkpm ?rVs ucK,ikg̮DV\DOPv&l^> g&׷ỗ\Uf-K-vxOK^&؄fbT㣇,[?>s7o_&3ŊkIPwbιwϓanN /`4iOt(Vt7z:QJGn|BAƞ|YKTk{ oݵS_06.1FYb"q)=> u](ل ]!fp/awP#cuϴFbpuw{:@ Og+甹czBշtrx;}g 1vdWẓ쨺o`#>oLcM mAפ'"{fOxڌ _y" 5׿t#s.}OA,tɚ,YN264hcF'j5^C ƘA\'`pw|X_1qx3b>3l navEo]*I6#W#|_ 4֤!-X)ʁLKw"Uu0wf>XNcQ}*_Ͷ4WwR嵷sqCķ\Ywҙşmimʋd,Qӡ~P 6zI=K)}P-- ?"tx*MhN5H0V5X ziE_S~agѮSnj<̓:{p 7);'dpeBKW>Vkə}nds{WELiiFtbʘl@k^h%] KN f8v#3\3ѷk) R$N59_W5\5XW_2Pm(s3Ѣ_Z~Kǥy8]TA p~n^LEu˘NfΞ6U u$nW^I53| -jr2Su஻ U=ey&fnJ]G&OuI'~;G3/.F'g>`\'p2>xÉypw/OQOm8uvB_{*rJ+K"ϵhS( alkE9ڲbKgk|j‘ڦ\pĐKtrMa7oLhTφh1"04*|ݔG(.;YcN`֕bI"TԔFvDnwbS=WLu%_Ugн^owV1aԻmM5u9O߈O.Ђ30cBm͊Vӕ&܅?TpSoF+xAӓUW. u祽^8ѝqk/w~Rxnojwʃ:r ~Xn@!gWt$R>c3cvb. z:rn 7f(īOh<J' 0e91;ljq?]{9z!o֕c|9\`u;~U ]iwLXϕsA{C>Z?x1nS~bMb>Q=_ݟhp%E:,SsZ[`p![K:ʾK1jP+:P}; +l:N|FNrR*Ӧb=uv;u6{i+.,F"Umыszxa'\abo6ʼAv\؎ر]wR>4M8Fn ڞv嗖36ciZL8ڽ\4X~j730+*yň~|Ruv6ύԠd%|$qj~G_ؐZF__οk+w]i͆m@9|㋡ΌJ=dª['2'.ƿZ)3kq5:}+P{UX?k&|9Ɯ6֌j)ԩŒvX)z09@7Z!eK,opm# [S&b8,[꜃{nh\ \0Ci_PnUcC=S5Ιn/RkHc؈vTc\mNKҡc *q[%˒,?(*a~ԗ0)fKhv,ϺJ *LJz42_1)~k!qqW>kMm~xr ϧʑkcݸJioҳg Kfhs;zNOޥq>#-?[:fy lߥ ttۙ11J2~`zy4 6y(τ^&F_g{=ޙa˘S nŽ*V0੊\r4U.X *՜@[=(L:{<֑}]eD6[.*FА\8ȆϿT Uu'j3ĀVѾڊ;mxc=< F5VƓe8-teM>H RC6dO4fFl9ˈsZ)]{Q7^{tu%T3L>oAy-K)-gW g[ȹaUb,pc2d})֧i-h^FqԚYNTs}oG>ǝOwv\&"I;[jahKNn̋+lL>h)Q}sm@ qn1gW0gY GE:qf\2`x^>b[9 J0zl&spi>֣I33=y}X(~bV8^ݔSbU8Iïԗl#سψ6.Z|7-^w9:1ehX_Euh5ڀFÚ j΅Lx8wȫ`wM*ڌΓM<3F<`hog[6:B-oGSlij/>4 *ι a F7sܒLtY%–>M LuؔSlWNbZp~{>ax./eypoC1ƂV[Sg3ins@O7CP[9?(C{4^azm9G:s tN hu~ eҀZ,xW0qgIGaY.+UH1F={5:\:N 4ËIq*i8tz4eHflφlx=Waj}GFf,(fA& RYAzcg$ͼj٘UBwq+%TIcOV1}|:^9bZ1%:Ln>sdVH-m^Ys +Rl$A;e2!;dk3OrM5 O5h{ ]k>>wF$ڛIB+* Vs1б+D`!&߯MlTo lC] ؿ܈7y9%euH~ 48forDYe"F <$GtZeM>zT:0- .O5(靉+HK6^ ذ)<]+|D=ZH&guG:[P앀Gzy͞uy ˓pČͩ`cm kӅZ sC.@wH>R=߲b׳n€ El|Sߵ1"*`7OL9ώamLJTbcޛƹ],H퍔zx򝩚ʕ/v3VEL]FrWfwi :qhnh>YԜМ.Ib_)h% f]avk?UZtncs7Lq9YBksiJNǾ;5fFiF1`QwrπK:ܴ-G<WU.L÷юq.4r+%' ].̳Ir.sC- Q*9C[ZM>bϱ]X&6C+GA; ,Ԗ0t][f4;GuyG^`ֺHJt̀?e|CEW͆gzl:N|d#vW qyW.hmk3c.bo"e̹x6<*9oNL'(vRƬOrzRpq%ɍi_eo1Vσ?&sP+6rw~Ń%u䔁 iбfTq#FwALwd0{.?Q B7>boWQ?€:h7 *w/YctJ6p:4cpRDm2/UM@ҶL='z򾟔^(!o/F(f KX)J V s0֍:D|O"X*.Rps{;3̓zT2 嘊>ari>wN-#1;GsI?A8n1I1Խ ZL55e''ڎqLYs=sqK)Ek?mi-\Y~祼߃72Ì y)utk|$f*L[&)TpTW2rQ^b:9>n|\.tLKFw0\#q#^oiz Ȇ˳W=.4PNҢW|1⹯<ń˺#ޕN{׿I(4J uawp/D5f4 .V(趜udL|*U[FM2H3h)yWWU W5\]m6]YY ]-&w(d)9`͗P*#bra?'iq[-FkṼ l; >1)z^C+P8Q MPz::LMµPF>癿q# վ|~3مݭೄ 8s u8ѝ#wN=xMXfo=,Ur57]ئ'El)$s)_!\z۝[ElȒ).p R:{X78x,?'-妣~&6ЄF\0ӈtD%,_&\RSxx1Nv@74ߝOtv"c6W[9qƑGhxK[SD\Jb.IB9Re JGU4_шe\Ξ\8BIˮ>(g&%3y[}#BnŦ0*M/p9C^A# 1Y3'6Tc۫\gbhe ~ҥг5>XsڡHҥFͮSQmi8P ]hw-h|ɑ=ι̑=4}.,}C\J9sݘyvtvcw1לPsCγ#mJNh:ت\YOE,$LOpgO7wHyÝLVMZ=:f^;pEbMHDs%Xd֣Taf wf=]3נk. V܃Z[&1qx*Ŏvx /M Ċnh<Ǖx ;mF;p((*)K쳤16b9R5%=y\ػ ^SșdC^|ד^(WDrsk}^lb-8*ޔ x&Doz>qlE7(ɧӚ7䕬O?gtOSbw;v:{_, iLϝm\ p{42c -Ɉ8]`1mFJ⪄;䴶P2Om+pC)2RP+X.Rެhg:b8h~8ހyۥ"$"s|=6 8T1+:|J!ѧs8z^Ő ]w+,:w|h(<;^+`:[#7Ǹ<,N2?qbkk O Ktղ7QPusjå3ޅW=8C—|YF2\rO6*6[ٓZ~Bm,JJ9z+yR2~?,Bx6ym>_42_FTF-Abh/I$Ыcu):W]~9hLZc\N3wgvއ7mk;u1uFnS4ZK7v~͵eWE]L ҳxA/$P=' Ym8NAo%[T+By^VwC\qOf|&tyr~(Dp-wfsM3k.X2̡eaD>1쾶 Y[aMbKŸuydj&F Y? &o͟+jk$E~6i(' {N!,VLf=mR;5Bg+a<͝uh3d8@U-M =}lS#]SS~=V '=x1h]D ѽxv FCLtKUϣ1.6 &baT+foK]4X̖M+&tX~r]xNR>V gg%ClmC.b ČNG-u*/f`Ρ$]$`R v|C^l)  }Yq,U<]p#XH9BcZ~.wٝ>.$bjh_a&S.hKU=8x§ZƠ))Hz4bCKGJ'%Wί"9׹(SFʜjO#Jzy;Ky܅!TLRگ`p1n;S,9Rik0]Uhq4ΝlN fkYcj4s߯#q|ô9|.5z ѷ3rJQcU}0CFW!>Kq8SFoW( 많MT=QIO&yQU`HŽ,Y"AX$Wps9w \Ą|N-FNY !xc$ADMDŽk).J[@&z,G<ِɆ%UKojH LXS.8f}XI=WkPm=㎢U%ԪTUȻ\={k`x?bP8xzJYR#RJnH>Sʛ nj9FJF̀RF엲LNlYI;eܮ%b;ѯgLcm7=6Ɯl=ޖ_sj YƠԖdV̟{/SΜ0ڜ}xw9n&3'B{l"]τ]aN%N^Z|4ɐ6PhƖ۰y'E`.@lnf. gZ{>+A2Q+V\|R\K r;];c cL8 O[;̖NoZB>"*fFk^h_tBgh}N^up)'YeXh==߾[ke6hI{ l˜xCJ7 @987$" UJ^W K,b%X@/F;ٝaK8\K܁cE_LWRKqAB#;ME%cv9޽U50lؖ7M9'ck2½{lٹi_FsuPᔑ 035qbn}"~fVͶskGDٷs]9sy2% #8 I8nc$\Nە<%6Jέ/KS'^"])}pnG̵t6LGWLrS?ƒݤ9YD{fŌ T 'cWO3zhpu-n}v2ʁ16ȁjWFvf+_k;w'8v)t. v]5V y8wEϥ-iw}g%[8x/OfYR&^sSzZN_`Xk[]W?%2 py;Y82e G9aBv*SЯI.-7R^43dc%fD8ʙOhNć~b~.r8/526`#V[j!:Hao(b2qB!bHsv7cyK`_m#_;b+p@¯rv=/rbYj) 2ᶖ\gŽmy+/9r쨧fFIb̐EyH91_##nARrd4y#fȃ45XݾkʑC#r3Wvex%*jNGI|1f&C"u6w 4dG^?Ye >Oqf1GY(yK`K$w.' !}XݔŒmE[J:wbJ'Tqa7#6KyTRM/c|0_?xvd/: X'# v@}oh&svXkҌl889 i-p~Kns#LX~όwZsKsG.2TpX9o ,&d@k#ĬT`/wD"$o) {'/%ĊѵhCAb:T\~ovRrKvKpN]xƉ'!=>4CBvfe3i:[qAÃ[[W# ׫§ysk_-{h>EfpMcsNoF zޔpȑSCn/Dm|n W4qç9LG;nee|<#i4[}vk^5E‘"km?DҮ#rn:BnXm[Xp9tHƞ.KB$Lۓ "Tc« =mM9Wiq\%idǼxnsblx$Ox*PrFԭdJƕd Ĉ5Ia|=-< WJ_b4(m2<3⥜G_IyRġBȜh9щ&!L9fܙȚ w*1+Hsqbf݅8vy5réu 6N[l@eg=TQF gGyGHi,dC/8s[t+yuګLjZɮuJF*$FuNJCEXFF=&̓Y; -b992*6˨j+h9{53+یw{> 2~.5ShX@i2rS`uNt|uPv7nUya?k0"0a#1ennAC|RG/`4(R16(<T<1(mEfh18k>μ=*FbS'[iTTD(9W+FU<3T!0@;t'MFiCH +phܨ 0 hS}ֈl$e@mNy3/ܶe;v^v\ł{W-)8lϏ4YŚŐ*7}$6láe=<;!ZK 5mWy s&>P=̨ojCg..t b s`{wW) Qs'O-䞎ܠI]\b7,U 6ƒ9q5 yn[\zX ,Nl!Er ]ʬ_̵rzVU1b!}DlG1+%VyS${ qQ>9CfKp۳?7{4nOyc*jM#%J* zS1B 1^.ڵAJ< y(TkFׁuŜ|E}^zr65W?ݓ1fJQ3S \~7c 0jllJ4ĭٳ>r) to-,qJ wg]=Zq-;ر_;+zJ?ScNToX^'-ӾN"UA}d3_𓸙Ei8ದܸTr\lm^364ԍCr\4qri>^Ε_> %O*eLzfΕ[^c*xikrz7zЫ Fޣb[idSJxMuIƓrΙ,狷r:uʐ xةäpzCt{~snLyK_h~&q<~CgXk+Ks==ѴJ [1"_e3ÈOMֈwZ0%We<߀ޱN`SokϖCs]+-x‰$<(_&t҈S'y(B j5dJm]\Mk:{c\x(VbTdM-3QgMC󫕘C\ő9ЊQ Wak>6qnxDc{ !B9)xT#$bpZs{6N m9w93e3l- \?f`NH턔`\GBcHۈDtwcE 6k)c3dqAG 69Y=0w( sdaս[^cWڅY dk[0v~ 9pQL/Wu-Fex]Hv?7=xS롛_Zt↘Zt]M6ݶwffIi>IćOy܋mިY!=(!XŨg*SSNjcmzXʯMS EϪr\wap9&=XsP Gyj\~gy마߂xڝ{3j;tsvai}O~{4H,v(ǜ\\g=k~smӦ_Fjc, \"u*\jaSt9q.5tGGks)tS"bG?bwF08ˆ k,g3J6-)8kF^x@ړ/x'p1H ˩4e1MXUHנh>b7CLT>fQRxa B+\x$ÙZŎ ˶;f/1㑙Z Dp@6$?qa2fAj rU- "')ʘMɆAjNT;yZ ?JS.a̕in&tƌExw=05t%#]O9T}#4@A}b<^UCv{<Ƀ7Xp.vXzܣ᝱ 'an츍-zط$34>qc[&.lIdmJߏec5S<S}9w\ ۝u9nC4kY8 u9i^u#J1I9X ίh-hQŖǵ3O9pɍ"t g3-9g-C{(٘*<]J<3k,SVǫKsk5bXz i /q I8V "9<1KO@Gƹs8XY3}xv䞍Vfy)хzJqU{2ZJLK?9+[+yk'kv)閪.8Ps*&D®M:uUAkP?'Lò7̷c|i낍;bxca9א $lMqF؋o=;Z92}G96NRp"{>AapQ(n8㾑X-CrR17{fRX 0M΅q`ȷuѡ?o=57Mɼ/(N- RRs&Msp_M#+'M2ޏp*,Pcj0M5G-vc:CXnF2pw|nrX+8rY6[}Ɗx-cV*&Uz G!t>=G^!LpGο,2=X[2.ג0~GErEh_keBy#ΛY}\UJv<%6 .JVPy"{J8D*xǐ>u%[^8N܏-w=7u$&eF*iFNNyp|? 7<ڮ.`WgYd&W h!tB(3zgHY\·, &\J΁vx[z)xĝWgV$< qb.gk4gQ8 s Tw!D\;%lًi;oN%]pv0cd)K\d˙F|>C /fA3oῸ!*Ո8[)uS1˄⭐/WRPNwq`:sЧԤঙJFs1Wn83^Znʏ&ic~>؜s~<*"1+63ed{s/+9tR!E)Rgy消ˢ\EbzBE\\#b{C _ p|-6Yz@9JF()]1Fjܙ&<)}e,%at)Ŏ|76_Û]3c)q`Bh40l4웆hlgG0Tۧpi-32?v;=P6U>xt#ՔsblβcU5'ZG ~2z٣' y13J >fNF϶3t[,ET!L]T6b6S[_d.  NYr{"Kىe&+(,yS/aˢpy<`? tV;d|EFYM^mw<ے30q\2 '΍i`[V1q~T<I-!K6#Ɣuu!u`dF/W֮sƋ1hP^҄_hNN$ *dw7%<,7s-R`єrT;f$6|uGbq<Ad8῱AU?L ne؍zي݈ݭX "(*tw{ys\1X3oySLM2" ϥ^M!O[eUSh!(ꊒ0q%4r-OBJWYCu81u9cT9^<vŇ ro\LʩW4GOk"51tKt!K1=b(-3@nF*XфkN+0[j^zX2'iN8WAgsы.h08H f &m#:-z3A~RMPqVN˩4T΢;Síc w \G]יQ4;m]ُ.kO]?Ӑ@j:M;ń6{ꋜuU,aAX1LzaoajxbPO\+6->VaIvOpZ+~wpp`(N3 E&[h:ȆJ]Mݾ1˔Xn3&#V:a'V.=lwކl+b$e9^\`OD‚#񄍩s/L8`@!8Ȍ髬2S3H Ɍ:3Rq;rm `7w4C{k +Y|]Yን9??XF_u1 LISDPTWLΗу˭':Y>rU5l~|IS/R.;=YtgHΡRiA&E)$WEw`zO>V1da X}(wFKOH} <|DsNS܉4xsJJ1o^ V灾c{g'FTx"(̆ =y!7ܼ`MȊ={L6b&WHv0]3lfidׇ0d lja#<dUb [A*A9ch5dL_>AF~ڕ:fٯG}}>\'cDbg29:G\]UKCPbp̣y=iou("m}m9hv#XH玶OR+Ǩיp*Vnx^\aBe\b0Ε.S늳W8Xt\OB]12 >`#ƺbܪTC^m;(ミ~>ц-``؊3 +[+Ok_CZZUF2`D+R6Xz&HCIP0P`w5P{{ufp3+ ug~o7KtoDqv3 BiT=XIx7}WC]nQb NmVe9Tz"_ H룪Y,wHHHP0ς91uaXrSN+NC%\Lp a;0`S$*7U)9dyRHqoN'EhX\`cAG,z۝WK )9v!֓^-%t{S{ooiIv=+h[J` 3p+3Q)d9{<.vuCOw5sۀyGa} |<x}6zꅶKPj7FtjF oqogi [Dm&H}@}f _SYfd2ÙbqcȌW5 8Z4U@%CN얻q{9 c}qNiuӷOR iéyDސf98Б~(cWlDŴDuYǝnjifG|yn|LUpQ׀mf\nF|2Ί{u\Bvc=ӺĈݵ[g@/Z/CzS4't@H?pk H*;dp19-jiwv9 -2i>тW&k+OT/xхj95oΏtѤ)SoH'*i\Iu/8fu„9N8fWɃѸ=o ѽϊ6^P O'|R/n4 B,̜ኸhlB xO<нH5Jkplu evX~ۆۗxa6:X|ЂkqmtoM_9sI5%O˦eikl: i'ñe։9x 7#8͂6F3cf5ԗI_d*_;so?}aQBq(eJm"1gQp%sڃDah:kvq7D!zH! 6Y:naA -ѠG9). &ZF:toiĨ$סZ ~0`~]#Z֨0ֽ+")$8R|x%aGw $ H焌5e%uVI-%46vo3'vy'ﺸ`GMA4N+Jld!%,$?T>+1و[y]Gk%<*G#˕\) #7^^p_/x؆*bЃϰA 0#M5A/8ݥ97^%P{%?#qR)eh \ x>؀7 g4#Т0QMpȐY>?ڗ+ QJ}WЭ\݀QzafR-Z8r[jj=Tz1.eh*GDA!'nP3>dƘSgD5$P[ =[KΆь4nSPIwlCŁvk 4hD8eWK\T3d.,\o>|<8G"tHP œf2<"j jь'4-y㘫"[^oFA9C ƚzJ/D{WLXE[~SқT>@.Et#Vluqo'D?V'= LʀZfm*)VAzL] |wssߥk8qQNGǺ.wKr3z^. qSը`HaA x+0'Ìͳ"Fn#7wfЮT=rι ?ݑSÐl!)NN D DĦ" σ?Sw 08FoMmR G7KEeN1MW+٢hʐù 5!PWPcJh8wZ&n p ޽XYn(oU۝1d{ }QE9$Oڥ/]h\+o &[}ɩGd9/P ˈ7&,>FfxDnNU`?3{3}DiR>=xQ ^񃘬#eX%r"yxo:.5WIk;[~)>.fҘH'L:҉Hz̓dACdpܫF.:xŘ[:$EYBJh^~:nFPΐRNGݶϏ҆Qw,<{9i&: ;nSaK0%T:AK`qL8gX=*[꡺o #lwVLHЮrZݵv8a'g˫: [Nfay!JĸWyR*M 0 G* b'}’&h@D=2Xz׿EhݵH.UgIiü\!ek4"ߝt}M3ur>~g:|y\L ?l4 bB8Hryіm~dG]ˆ=Q/}UQMM.5Xpf%<%a9.V{`u#5!WMe89 ^|Ĉ_G:oaSF*j99X]GE:W 'CylgZ̼BW{6@ɚSr.Eh;-Hc6Xc\\•㵴qXKGGOQ'=O(/ I-=q Ki:c6f堤; v?Sd8`c4TG'f>0;ʄp zVjqՊPj;OaF:g wy4E6UIIQ,1 ;YA(Õ,Wsqi䌃1es7|K;QGa1+%M?(CJ([!XZE&3Drp]@ZfqveR;M}{~Z' VT8//Bu{gSʬZtt55iK- ±#N!7!}iVh<)az;A}hSa Y7lB&ˌZ\nb OK ){wI O\T*Tb[E\dChg-W z1&1&CLEk./5m8kӋ)tcRmO+si*VEܻ1XaxAlx3V:U@RxQB?duv k1*Z071BRK<0aęXn*5uRO'46fPU` 2,+Rp09΁/l-Rq-]ZL"RWh =9KJEI{$ruBu,H# )*iryN'9@ }_1y-SkڼT4&]KSL4R]{J!ohvGP%`o7"Oeht*Fޠ胤B7itI86+}Dpb|)u^8 v03m Q e8?%(T0YdWO ZTE+a/;erREPOGr4=.b_Q솽yP({ą>B6>9BCZ|#QrzVVCN a#‚WO6M^fa^wd ѢTj)$Ab8b#3?נՇ̰wU!n3ae*zp:qsWb"a.tCqݣQ~u\ i ]p|9bvI~JqQaBpqZ]S&HL^Q\Uڅz z~괭" d Y|Z+ƍ_$e+)i1 l+i{x9TJNiD 2L~+T}GRx BYT<&'gI-]?sF" w3xB`+7f|7o9=Pj%D-ԘP}3 ˅XwoxSl-Hـ. ̨#%f1a &!ŀ27DaN1|dtCU'؈PMsW'4z*l&kau+e uGr.F}§&j>wH+$ǂ D/#">CdV+UHnp+`sbLz*qYPYh4Z0$.7:BoӋ8:"0X~V˅t24h,Be+MNʡ_~ C̫`{C *lzs#ƝZ.__he7fQ ,Tgff+&h{d\f%SӖT;H:99M:|RLWsu2:ƩAj>lJ)ͦĊR t9,LOW%Xb(4B6dػO&3%3h|Rt#7£T=rxȰ6Kj ?cV]^y_ =ǹ|8%̱*uxeΤw@g|iwݐ1pU4.~1$"! ğu(pe Fc!(@Mqj4 w lA=ߵx"MBfF%!gמ؁)A;cfw~cs;~GPٟ|4>mq1{ʥUКF ӏ{(V[M'hT(2nIG6$: +Kk^ KvٿhNz΁VܻA;zVR7xt 03 w0͚J7]͠b:E.*\SAo&p ~_n:6QB/?iµʚ.g~ehg,=[EI $z2!^@~ X {Wb| Fac69]\2u6 'Ź$FϞd'z)6!INmO(kzXFӞqjX&=]P'\KrCs%_ G#x-FR$kGѐ_M 2,, hśy&=Af}a ӳ&.5>"}>'"pGyMG?s]<:GQ9t,2D~JP'LW9aoK˨l.mCe )76>rD c}3GTSeE_:q4:5rV'n{h2eUn`_ݍ&lߺl#Ғhm7<}[uFW$vr- np!ݼ9L'SEۤSc<]H@ ѻԭ0^B3G9tA8nQg7+}SiM DxZ % $ 6 `ŧ Zzi1#=DJ/ 7S/uh"Fr vwsl?FAUtUt/ + *8֊y, d'q̜/u1f0}g"ƮB;/ +JJ|CU]VҢx2b҄ba =B&ƣ2 X#\L|F<'W:a,'ZBcg3r'R'Gmse]̡ JC_I<OJ%N9~EѭLG*1򒩿{$|C)tDF~+$˚b]p?5@.EK11kv$5(6y!w)͓htjw *KS?-]ryIݦ1)AzO|-钰v,#"ߦ-KwbԎ pBC#̢‰Vt= 4`%!\<5f2(>AZ#x1zܐCsqpx (m"%yдwRF[7x!}%x#DZb#%FQ1<Р@ec"}s4.#@=<<-XmB<%oc1&p>\~ NE\|Po6-YT(V)3IK?&ѸTt39$|7* ib*Q<˨rU1mG}GSn^8zOG;2גPj=q_uc_\Cl/h&URT|@V+D/.Ε+J``d%MR@OVgЦֿiЊotoWJ)#\,,J?M~pu*2Wmq}E| yAUh CR^"p)B"D c~pPZ=>6#{+C} ($P"<Լ!#W?.G0J+$8Ez)9lȧ~t<._t:lL7 XؗabY031^P"&%_)ߗ`yߡE.&\GZN7 #P6߄8l4IܮRLx$F+\%!%@)#9H~84r Q&/}0(ҝɴgͩHItRzOdRgT37tn6MEQ횛4r1J6n]Ȃ>/֕.&ott;߉"Pu]8"B38XO?$^\@&ۣiIgזQG\8~ru-|JI^Qtį˩jG5hZN2B _$rt/cE' ʇ>K>[3M>G(f`h@~kǫ3E8&B%!nys,oXJ/GQ`r)ZVrdIY; &;\҅{)ŧ*&<\b2E">^c`h*\˱ o>`=nB2~֣Xmœ] =\!k%8T_O!az.?%+H)CBx&0=Rq'饿CF NӀjo$< X>}D! S3^A줟ӏ$LM.(3EIm4=]U]__[~?EcQꊕd({GU:ٝ|r{JFKAN$_1NC7JѤ+wOI1p]qa|KS/6OQtzZ%#T7kԨ##SXW,@R>hdo/%- m`B &S_ţ"V0LJq_z"t"-JxEX%e<=愽obahr#W$bdxUa 1tǥ{\r;Zd}jjkDD3ʌ:Lc-2㞗s+!᝔Vp $,VcOfrR?6 n"yj%-RmWi@]YFk}J;Sr4u1!ŕѴp:"Œmg9 ) Yw!v˃4*z|*p#t}| ⥿!Ud㎓L>Wpf3̢W; yO~Pg~&zOwQQ6&g&V.V@E.T P$CϳϷ|8~>k-afz b'pw ͙i@e1uVbT[xzSuc>ɦE*Dޫ1svZ2jrN΁'\!g `l ?=tYGW&߶0[;13?wB($3}dj4at٘:#--/QS%Kڼ]Pk1i E1FL ~SgKoHn!'H&8Mΐo06Ɗmx=-9r̚짲e/'ioI%*8y3%WW3dLdk[+&6$|ZI TmS6LcEa.%`'ŵIg{O!-g/܃v=ܴX%=kcy4t#$ unԯ<Սcp=oo9Su,{rqIHoZLbum_}wħb|giӬHFXC|dJ~jTJyv,C̷؛דc!gb oW9(F)o[m&,'d'rS1$@ %GRPY aזTg9r}35j`%vo}5SÍ_e,42g}7XrL_]9N̖ q'B#{jBh,5~2i\&*fl1{!0V6\Zhol׉p\[('d{}eHMyU< /0`/=+wH꾈kfֵR(^?ŵ71q%{m:ۊA0at='UQ2è?Qqs(dK (cԤpua~B4+f)fD^+ba"׾bʉ,Rxv-a܀Oys%7;^mEJN3a*ܽ$Dؚ"zUaC$\i!eB=nN/OF Ժ*0%N6b.bHBʴuz4]bH[Fﲧ#9qr'FleiA5SO4⧝rV+5zZq5;'WsX[%ѽ*ـ'K 9Q!Isp%/1Ue)͚1Ύz+gd1#V۳}7kJ弽SEbb] y ŊLX#, ۛIt2Z .is M^B&<:Zz7p}c'\O#5xz\6(ccD^D` t]T 45s&>elAK1Uf^̀h&W/wd } 2j#{ Ij:Q_%7[ a7p-޸yx߹ "_8fVSM$9 [¿OC>%n;z 5y(DU`zfhX. >*y{+(-1b> fq6W|0L {⎨eڻ5aZέt9FI SbƆ]J̕񃗊.*٧Hs,S+^3 ͸ [v0 Ȳ嫾vmcÏ֬ag\mBk+/B4lḻtYrN0cM{8tFZ42dZc6Hm°cj ~z<9r{eN EǴ' i! JAO9m#:/2}ӻ^3ĜB9AM71J5c9ķfwxjΠx6碡U&,JWcxR6iRAr'|}{~;ñHqWLxt}6Gi_gV>Gh.ߨDn6ϐrׅ Jady -i2=fN?V A{g"s#f %/&DUT'VA^';ՀqST/5cTjjsVM ¡n0_[D {o>ƌU D_¸(1?O[Bh/:ίxR5cyp \&jNnrVr5?oQO%ϺN`[FA~_ dW)-uɆ'Lpl}&gadd# \\ۧʼn a'jgUAˮʹpBmWY!8'V93d3x;}1ݕz#\.Љ^}ȳr[m@ ^q;ƫAGq- ?j_m_>Hr7p)[ug]m9cx`U6eID+8u^lcG[n)&LW1K_5|sU\ Xѐmĭl˂ZG2> JztUCe>Vj%!gFܳm4\9EZ{Q;UcuIA'E/ j]'ZBu8ģ8xv6{`{7ݍBNN#@p1îRe"b+ﶬ3x8> W'aA&J57t7[+1Mt*x uP 2#k xsOmGgbwNi)0r 0oȩ&'CoTqX)3\t1v9|ؕs[3?Ǔ<=iԝ}۹һ'~`J/Ǯ h%O_>Sx+ː1A;7 aƳa2#k_B^`dou1l2mbmPjÜ(uG:m@5EJ/)*Q0vOW2׈=&4W>ڈe6G@sx(I䩟q92P97DʠNj9K}8նGKm9Th"?{Y~t]6âН ob{$ GW=Uco(J2P9{N^6'=9ڊ)8/R}, UWO-4Gܶr;gB'8eӵJh+] ęR7Ѐ͖Ʉ(㞍 Q1Y_4M99P֞<ύ ә/bS_W )J*io+={Fg<Kan];ͺ\䘉`K[o覟eqZUa*.d`vԙ\1ņ1m)7UO!E gLrAL2@cn|&dE2wed3 59FVeջS/xP*W?`tpu)甐&xƈX/>&_</@%2pq|*&rty־Lk@s.Ԃl[=aP<Gw(#0Uƅ_85/3}v37߶Δ ӄ\ABJuYYOMFe bPӤ*Oo1[;ʘ\$%gH7%걉坜k]'vNeojqRz od\N][c$(?XdOvUMv%exzR,4h36e#}ԉޣ]xx3$Gn=(a?S+*1R)3F[/R^ϩ?dtl#8o!'W3g5^H-fʝl +SX.{d _q9I[R-הT;rBᾒ]N?:Fs}.zRiYgb4lِe0 :T(S58j3}-ÞfV,ncFP`,aNrħT !6!Nԡ*iR1"H<,dbN$f@ /RȜBte>^cxU&X|9JP·=B~-b X ð2ίDRQ&.܂ ѹ=>qx"ȼRdoG+rb39\yp#8 Ξ[Mۖ(a_"0AGƫ8ŬV9 y_:20Ɣo1KOSUx2W4a8M_q: ;CPۦc~-%\W<);W!JDW53qciXl'avKv˂9XQy\zԯύqߏ0P ]<;E1zS%Z'qLѳB[jY!ĔݯPdmĖoHEѤQ64TTM=b#}nkfU9WK1[Ualh9ԅ9v㳷n̍[8һƜW|9/3E|g'd 3Z!2??~cBzϻx<7^[Ir^=f4瓋vȉ};2=:^{Q3ǪX2anuk.G9[%(#Xۯq9skf~Db lسO1g,#KX'pEB4դH'TvԀ>o1Lykz3A8|? 5|2cl;=A`tGtFBu-.(8{A\5A*s`1B,(o̸S\@S>&Zg]jc>fJƕ&\S$\XpJCW$}_ɭf37a m8-g2 R~39yҎz.FqgwprcInl̫l9c)H70: Ml9Q ^ىWc/b~~XU2 )Xؙ9kU2N dN{r7ȉ90-t-Eb?1O,w?%g)8hL2쪌cd c8e»\HC{X>Q_1[VJ©9 qD=:IXߚs#rxNdI\(ᦄjįokcoVJ_>;4ur[P8* F:?GƟbRE|_5nA"nHE5$%bq D%Ɯ'HbjɅ\xKúlcaJ_'.^B>DBM!C 1$-:0ϕxNrfh;_`;3$l9NXu, 'f!Ӳ b906L *xw4(wEXg `,$Nӕ ng99x#;1'ŎMٻK6R?q%<};1Xp|beMVU98p8~@(ֻȂ׾bQ<2Z̿)`Zs>4bILx궚jna[$l_R=\ } j$NF>m{Q9~t53Y{P*.Nhv"ZQ~`^+F,Ơ" V!s]NѠ|zU)fD":ƺ a{Cq9UqtPۄqK謥˳w2]?Jerk9ՍzpW偶ftJ5"=z<@gT`vSt^ +dSgi [DMG ovÌE]pd_@޳[+UUHE F iOsbS|X`3heHE}{Ӽ"K9̗sa1W2)9sK i"0 gqsrWT{uؾL3 *.aLWh{ifEw yrҐ}iҍ2ސ}^FJRY<Z tE;0aŖ\!}U0IMAq[P0zޝh [`΂ +_aobe#Bt|@ҡ6[UkI O[Z-MiCwIƇODݮ{b ֣. לpfJNJM99 qS`< ѳ0%}aXiRx湑i¶ lj|DBӅڬ7Ԧ@_p/%mN0q>]hq"(“o54\uȿ06;_{:캍 !-cXt]c<B _>wPoK y&_u*0v}=z4SʕaF\҄S-XYev,T9g9*iڈD?Š^2'~f8sv\Rr&Uxt96o1{z|@ڏ#(N¥SoiQ2KkaL59S%z)eOUSJZ.[.iKfRrs1OiUot916EĬ|[cċ-xH\$]YQ7P/@xDų:1V{2ڌ1sJhń|uZ<ljhUjtHJ9ܒgbھ+Gt#U4c , =KÎٸrn:ק6XuTұզ}+ͦ]em%Pʗr6T9Ȟ9zVܣAaO"YA§b&?%o3gS0.iuX5ƚY,D~7Da,B)|RNYGp2Y̻]U׌ ]6'}0f ̓B16k5}EY psTY_5ӤZ"&ĚlveBl-׼t|ǻi_4úd,@̃͸<-^߭Z2C>h̍*K`?9=;ΞyC9m=2̘Lɩoi:IO3R'y&nۅBpsV µaQF@kp5ŹŽ=옂aU0Ml@PSMlT t( WH95͹x%Oezk>]aĂR"+a sfXQ{Iu躬ֱy!ۇX i^cAUx6.M}pnd&%0cz#&qEoHGē|^i8*G"Xfѱ(+77#ݴ[ aCt`z֡8]>"&g1].MmeZQQ86 mQ&^?UUAlL]KY:YXi`D33JeX#';+G'F:q:'Fa}$"bZcżDMl.P{t~K Y%Q١5jwuүxV G0'd"&q`:"UFiU~qzW+|~ Z)휕@;P_E3+ve3v37 oҰ}/,6U5Qu_g+Q#;M3bɖHoGώp*|P%CP%}1OOg"1kX Ey-$6{Ӻqo2J@X7&:C#}uyjiV15`)7%R p+16[R>Sx[C-t*P}2+eyh7lJY bB?M4ԩ鷎ޙ<W\Dߙ~Ҝͧ*Ѻl3Q{]uI&Ku\i4 %̫T8w"=`B`gQ|z$Z?vBѶo`n \yc6X걦 6^&%-}3) o7pr4]1>?LBYH4^xL%, 199.5d;y/7X4/ ^nf/rޫzxD;9"o5 7k]n A??knlxCpkLj''M5>.)CTB-.h.>ZSǘLx)G&[0!l4 g{C)mm@;T9ZZJ yبa?5u7qucZ,Ǔ[&Цg-<4ErA>yZI*v)cN\tKřoPve7Oj\yLBI[_wSL8L˱ <`J'SRo-zG_9Ӊ隸et gil%oä8|AW= %d|D1MEk5O_$W*~qmV^=NY?6}t/Vi2TR ׵8kt$ <Mo$`AVE/?hki_co_z1[[[J<+9MoVJ)>jHmRgR+˶ {Sq3er+a˶jk^4e#g=d]vAIf)z|*@ka33k7d`wU*2ҰeڬN4tcތ]ݽWߓ[1U"~}*bAjqV-f զ*e3mjעm*v|YX5jCvi v*ܶG#_~o7(w !g*Գwrw%"s4?X%=zYp5ϝ6Sjaq(G.tg ᣓ7P32.C>c{Mέ(َ$qUaeA+9)i[NOWq[7G*UE!_ 4+rZ&BbEF8~i#گ_2hqc _˙މP{.LpaE3~s7pLÂYǷ t_-q]Vuj-z`(gˡ:XF gΕk3/j]mUޜQg3'SS/ʹksW>ӱ E\Sqb/O2>#'OWc{jFBO.+R]m\cg OBS>W:Ku'dsC  1FTbM >Î:j/]sX5輦gDs33̚6``Ex]~#2: i_RT"6F;4& üSP6)BKaVȂ7ЦJ1CT|z9mc2 nkBAJUlC# mFԗ;jSJsrǖZLRgbOm.F cM9{sNpLO&tYt\v\e~\9I'G.s<~tptW:ma/F {7Մ$׀ EW.(<ïs9#KڸSڍ;*=8ɝlΝs<̍s3']9GGyrX`EgGcQ/’ xg5i)d X|f3{ȿ/L| 4Z|<"Nـ, !3>-#sn1iŷ=nƝ=Փ.+ju,7{"؅).LF/?7>j_ܸ`354u_=B˃6ɘ9=ޮ p4UjY "*r v x_C|tx+p.~`4]Z93YŜN]BY|]0uCdPe D/80 .N-܍3iuݶ?]cfӮJo Q4Hףʱ[>.P/F78+_z3:]%=t9ƍFlgK ]S=xn7ݴ|Wu刾E|_.|(p7p N/c~+MTl~_F\߁cܨY_VkʌyiKB"Ov1:ěV}|3҇ ^0oBr[beF+xUoF۫{' ЧpztR٬ЎƓ9ŅIΜ%+S,{AnRSʛYl{ ?pW8eXT΅jWVi3j^)w_%[ [-?P=|FXؾEcQ2`#O]VOU#=8F'SAp7eHT,/_U|R^@̀j\&wjFl8G>]Ye؛t<[C+c\XӍE9w+gh;-]ys_vn<ԑ]\8Eb!b~fp@SjsaL'xr@y7ot׌|xӓm =٫;uWEzڄ5۾tÉٞ /loeL.1ms'lVcd>L8-7:sHg&fpԕ{92'ڒteW::tF6эTly7߭}kMi 0fjډ7*}qZf{./(DHP8osv?]Wch8 N-ăPkvk[C 0LV;t8(:ǐ. +=:>͍޹׋ t}yܛy1f 繲hГcyq7 98їӇ4i!Z^%Mr ER!)3MݨͰ#2.Zgs&ɂgĠ*vʸV 2Fji"-~4(i.dC0M&=몑>{t>ڣ+loq57KNF ,E5XUW4{e}:OU&BMŚK/8މ9n<3^ܹË-w/bozx1s7};O'3}U{[ys]%;ǝdÇ*=?ؗ |Y݌qϚfܞݔMx܇gMg޺q Ⱥmv]ܔҼ*_Lhʡǚ˃,,`Ӌ\Ca6]2Ҏx'ăSc3x)e5hsS+puvWio~ 8DD~CUxSvj6[͐L9:0pwhr :)}I9LCOoBǛh7cJ9FF bL[S/pU.oF5xo\b1:I!cJd̿#L95U;;w_P\6xݥi 牻{ OHBB `ޞ٭wgܙߧTsWsqW?8v|ć#|92RYo|ẋQ?0ڋpc zRい1?E61ɭV֐=5枴Lݘ}Ze_pq{ Nogl1ph)2 ZP_ZPuktypA|\0X;;'X3ٕ˼'9k/IėuR~]z-Gm5ELI*0:{F#zԨ?ػ8R À>lNc#uXGkfܜi 66 6F1zlXP_}- Xj lVa+0nczؼǝ*4P?5h0)Zf=]fYxOx0?C3v OMehS/)3ym7)a>̊UCme[F>ܾ\P?mU*~VLh9hz g Srޔm5dT7񕽔 .cR ` 3lC m)?[)GZZ\ތ0ܞqܞ]]٩ڋy%ŋΓ}yxӴ] u.Gi2P =|KTؐ; F 3^BDTHG|Z{0be1GDR1QElkiʼaW 6 {/[J'|Hr1ŨWj%  S67g>v &~J"Zpm^n-W;_Jx;kN/etHUr_ejvi#eJ/v1;s2+,㰇93>c|P_F*s)Ntc,9t?k !|2d?ۏgun\^Ǚ 3J0LSz, tߕ%ᗣRai ^\<ҙMlΌE׊'ym#:jtXnL/twCW}vb`-5,уOp_ K5铅gx~O1f^YaJh~>FX$VW_O?BGU`Gd,L *Td~ěIoq-Vj1xX>o1N-1Ais d#~ʦ2d+?ԀlHƣ5 P܇/얰L??؀-JexПXc)@.2^$FH 6m^#5s͍cNv\oöF®ξrݦ4dxnn%Ũ3Kw RnW2>t9uܚ,RFU·%ELv@[8ڱF(LM9-~gTkF3o!f7ܳ=b.. M0 ~;ЀT4jQ* DȠyb .i)﯃g<,^%ÓkS<!Kez=JBۚD C0ڞ-:T7fT;W `Շ{#cSp땽!趔M[l5ƾ\ӗ1\`2o@6{Y\|~]Ɇ\Ԝ^J( )KsI'վbCk:pc e*5]s6 ٨/]ɸFS &?Pƈl)H)W>҇\Ȓ۰縺r{ m2=yj~yGRxě|dֻ_ՙ9z-*&c-QcbtIUް$ 듈ݓ'M 3VFX9mCQ5&Sk Ԑzl퓾B>0nPGJ_} Lhsf8F •30ߒe^ }eh۳GS'6emu^{iGCʔ/H㢔svq%?~!j _IhT9c}\ww_Ɲ_. {'eu{ b1hje2v+.vdF_ӈ4$xcJSb 3XyryK~SE6Xj^o?oOI0ԍ<͋ҕy0ɻ}!U–2/FOkOwjAجžy諉'r࿡U;sqm~}Hb୕v,剭ݽ[C.3hDԗ '*3Aj2N]埻)CR٘>c%cO/(vIhڎu؃S9Ou)FM,BQ`? $şI@}1Ƶ%9/aLVpwO+^WfNܜ-x#;rd5?Rӈkjz5r+,IljXeXĘJ$$m*}_U = |F48>F^$DbЛ5],~_Y4,yX ұsQ!~+Cr/D"Yz d~Xg_q;_ow&-_:r6JH9R!/o.=yYviO)ӪaV>|lӏ|9^J}<͋O6x7l9R VV`DͷMx?jW**ZA<W[Lr'yܝek=عcHc%GR=+3Z`΋mskyr:o.P'16ʅf\ ók#U:pv1ʊ)-x?Xp]4{'jrošR0.7@ު?>_I["_qfPg腫Ѯg|< /`bx̮{I)!;/^D4̺$5I'frM+onT yc?|.G?fy,eB8rZKƺ RK.k-:I;g {gvur -S)A$z߄ 7یqprW T!g)ҧ Csxy3_q[W?ʝ\x܃r_ggNm^~2a>T/ٸ1'g$ɋ].t2iy(ča]+篰A$b [:ufDYӕOWk|WxZԧzcBjZuPOLUPCg^E\=Ex]E.'Pi{fy>Rb" _fw>#e/x KePfig˟"ec* 2̟9ܗmiG8OGrTkf v,S劲T\E3bF], Ce`r<60&lȘWp>siՑB~,M upp z*__∎^S|؛}单Yd]٢Εݙ1ʃ ͕&{pb\!ŝ*3]uhC;nYl˰dF,2!×c ՍrZL@>T{ 3z5$&fa:|Pٺ#mR~K.ArZ.x_wչp7)uN~Y'٦H9+}&G ʹ/a{s_9֏Vvɐ+0n:4Xш\]kCMmk6RSzM1 (qA?KHsj=uAǎ* fh_Sjtd ǓGI8ݕ@kT 53/F"/;*e=onoN7|rqFRs#=9tWu[lqՍmvx/Aogˉ=v0x##s6U@k^g^(5+@񐟈>;Mt+:Yг[ 5KC7!k^eݜ*Z4Uz0ߚyr4?mO?9yy d2T:W' 3q)6 yo 0(T-^XU3WZ(f2/q!~Pf:^lԋۺqrޝ\\M[m25,Wau.h.I<ֈ&}&v-FXMjQ_ I1w7 U#X5^X=!gѪ [. -8#֍ޞflV͚9|͛z1'h@սl0ۗzqbj=THܹ?؍\ teΔt[[3V͸&֜xCavlojc-(&5 E׊oH5LbZ:k0]X1 YWz0]qao :=҄_ZPƖpGhp͌6ivD#̯D|\T~Jّ,|e^Џr?82Swaۙl;.A STem=ըa΢sLݥڌ+4[^/ɃN4U|pM^a|So<1[1eP%d6ԎreMg}/3}S-ܨ=}=C,ɧIlZ,wyFՇHi ݩNv`̢Ě,InKLwĈLʈ/wɜ'l-:%%/~q~AGXB6ԇnY>\?ԇg|%Q/O~/l߃okM m(Fɲ?;KkD=5f`^gj=aE5܂ _Xr ㍚_: {W6n޷][Ѭbs1kkzuTuEx ?CX4א{8' %)=ƻ&û&yh/ICd*"&;s~Fz1[xrLHoB2d eXjY%8V_ y!+(*Ru40ž-,xKX q}W[[#ָo7fwg tawSțG_ WBw} ON,O/tcӥ hDs%"s`g&+ kjSw.g+LmK,xLn&[YވFc$=<;Kgs_OcӳVy?CAh/ 9XF93UWR#EFGCrW`=ܸ-b1fW"fO(BE:v{RWO]2nC_ ܘeʤJLP͔;ËdLȼ66)5/ A < -cuoWlx'A3[3еom-FNhq%s~; qVv aTK 빳7EK٧_de_8ѕ!R&6^ޓ6f^T#Gi^cP8֎,,6ЮB zhq==Yoʑ{L5Έ -Oð?c6#ekqGʃWBdTU *J,3 B;cb+XŢM4}(ThWNNNl-ȁ{O[sG0校zWa\ьyu[)3e_怏nrN >;=ʓ9j'#G^nb}O>f\PiεSτpCxNŨfnl yq+׎-e~/n͎͘rO7OrVw x{%ARϢ(9WCT/x};}{z c* gCMPc9&b.J:/_ˌ8[nZ,= QTQF&LpX.ܢEY4Vm>)׃RP1Cg9r@OJ{JSBt_elc i(%x@QWBHQ+ |W^`5Yjܞ%M5_hpxhl.sbU~Xy0%[՗`.7p፷Ry3o+k͹bnc󱠏 =g~ʼn,ΈgnMA/}řf7~EtJtiUZ^=.Ua͈Ls +:WTO)^o^;!TEsuy֚W8J_(+\AkKj\ PᝰztXTYZ+lړFݗ#^R%ӗe/8/̙UڎҬY{ǔ #TQ=|W)l`OAo;0ypiR8P W_؝ \>]/ )KÂtGY ᑙnԂo8s.+{,8ĥa2ǿ I=҅#l8>ư<4 Aht +5\sm.(w1$ g!izQ&r4fѵ[,]7v7kjrk>TZPcX 'iie 6}:'aǪl~ZF֪\kM;w!e,&Rvxv#ҝj=7ϱe\sv7W 6Cù.N!l==[&1}. ԲpA LƣW>|FnLLG~*o7nlP6leh3Q֙x>0WS-,\+ݑRi~AƆK bo +ǹQ(=aRz4u_/mc3~BFZlM6L=F|t۔km͕{ut ^cOhr9ƣ0/,C:;:RzJYʺכh?˸*ۏ9RVKćsvzROÍ3:3X:[0 V;;@->&H҉?qX;X:t uR]BCR L+҅6U>h5US 熧A]*x ] K-w|sLϸ]TS53QD g]Nypwt_\JWoA׶Q~10XʜڧaCE6BrU *l}Fp\ ~*g~J2 &p=2 9g6zMs9)_z[ urd]l-fÈ,5J9;lxZݑ,D9N2ZlzEPrYyz[./>l̓N ON6<>;S1o,Oo20% n@YܫPU. }t0'6O -~͊0]N2*7eBR_R;X./T9mdl?zןU~ԬBϫ}ZW,1¹И7T5[yo#hq[/th#1alƗO8~vRTcZS~%eP7mM8>i1_KsT>#p#CQqǕA 6Iq?1+/ţi"tk L;֑޸J/NYFS+.Bw11Û>E͵dl)^٨_BHӱ+FoHޕiBUw:rhK%c#q}na)ƌ;͹1oa r^ ϼ(~,=} vFd\u(FXcAjd"ܾS-7%j=")ދ@Jnj 8g>WdkqD{I@oJ#|xp/$~ pƾlj朜ÃB*l_pZ:Nzhqr!:jE@ĩ!w]5=#u{\T&1x7gvNw'zW2{l>ĝ۷}4>~Ag" [LI:Ja6 V!_9h o9w[ ~3aXS~h3z eشf(dϷo_VL1ŀKf8F=EhLoZǾo1m$t#0{MH~ )H¹H[Tyki)˫QR=XhDBwg/Hh]JZ?&zqb ;qA#NWX clxz@#-4؈o#pG웿mG-y&oԡ#dN=…Ӌx|OWV[s9-@^T}t<ݝY>VY(^߱}k %ʝa _9pGֈgY u V({UE8o]¿v}ykG9(6tx(f q9=h+ g- b|c[7KT_%|}}>LͦtSv'Mf:ϗv^Bjv5`fjjT'6i|˗==:=CJŀ[qIݏN-VI=nihsP+n8f2sΝ,aJvfȧ=U5%q5_ ;Y3Ú:pE+ޖKx.+Eǩz|6ךIohRgVMo6{7Wc*\,[%PHd z%o;mbLTE<6*U<.@w8hgr=bb,\=d~.Dr[֡Č2knmf˙6ԑY4ٓz7;_ubc#>ۮΆk{-&`ţh آí _ je?=*0n.2d-svqszpƦ:no{GaX'9UzIfHLo p5O1<7' #׳:W0'?qRW1L58VHYvխ#:+wȨO,ċ2FwZ9}Or#]:T:tbA.ԨQ 8T`cr)F^5_c_X16Dݴw qx8e!,d7hcHWn&^D X=zjE7}u_}oi4r몿b Xh?],:{}ƖUDY5wgZk|wΰfW{vu0't_F/eT-njo S.)VYEꐪG }Є[p-óhȍSXԂ+k NeXsoa38s W~B_Z|?LJYX*/8v_gT6fP\Ո Xe8+A'↢Q3_}oT;q N%aƮ%.jz{]uReک”ztձ.KWzfk{7~ >RcЃ0,1.UwjCҙ;t'>〲fþC-.GG=V7Q NnCq{F <[ x%a2>@q[ac''Ӷd_m 7YI1we)_W@}*ƨp71p Ћ ϕ )=lmucxnH݄։-#m*դ(+Sa׋q2`kr}/vȷ^A:E^IdZaoh=EIZSC\j<㢹F3ڂ>!v܆χɠk_c147݋N t_{s_:A0[ MZ/ppwaWG)>MQmL0 + d}y' nknN(j"p4}'Q8(ƮU5VcDhgP-VaT m0؆:V+pdE+bHz*K%{ 6:;|0O}ő4cyQ y&FzfDm;9Lkp^pqL?=4!}ڶЮۇ'i%t~לGا ͭp$>sʢ nFOTLFz[5km)3DQHqf7+,s@^%|ujaA xCO=@RZ/wx5 \2ceOnF컪]Ycr64{hR՘3TwY.irlCZX1ReAB<۱YF?DwJiDj#0l.9] icQj nފ=G/ }b /a$AQ?|蚖~^j GP1uv{q**cYMqZXKkXCku9N1vq~?j[?Q$c`;a3YpT:E~҄tݫ"fwPz^iQ~ǨMIb^ɶ`9 Eϔ4Er_KļV,kq( F!˝,};>k®\l }3piXAYz:T ~e:# qfg&άB"L|RExpZ,_uT~q>SQntX<ŜiGd7+#^0 S6]j XEXQtń)WqsGa 9u QG8buo/(*Rў7sg7U^k/ +1z]V\.qWPv3>6Ʉ+*Յ0\Y2߱!nC1?H?\[t1#k6'+ta*ojp HK!4ɕڼ{C4qN ɲ|;,p=g@2O9) xM=!L w?N!T\go3<(HuUp 7qڧȳvsmF/QoڥTDzi[* Q* =QKUX{<ǚg4t\?V =& aYPٲu3f*UG`j 1eL%z)kPnOFUa8')y\hvIwFS \Ys7gI& ;)JN Ymc5{o4t]0f[pWe7ӻ/m> EIt_~#=<3UrNnDťWc("*b+VX^A"wBb#dQłGʯuAۚxgiMgn6o9g?K|~ ֝ơhRx_ǦaP 9h(}R5=Z?1.W9w^dSփhV8m` $.8S œ*Zފv0&G10]zῑZL;f͍w=W+Oc9]mzmB74\P;T<)pzS蛧Cu[V]6k =hD /CC CǤsiC@9;b"$4yVZ~$u?Z5GSq$h3D'Uq;Fq<_k`S0زt9 cy`@qѪ?ѾU 2~}4]o}JM5ZshK 6(vk?@>-%³o-..T=.wj]/i(f9C^0b! ӥuThG#c0!J:*\7 qF(/h/Ϝq0;|~Iز5g~o9O"~+" Tވ[:Њ0A%e@Pm5'$"@H H\Rj y;_ۯ.[RwB"-T(P]ff֚fܻޙs$$+[ygWӗ| ŰqoדPEW~)sn0{Goe*:fjዏmba_Ҝ)42RXLwBeĐlJku%@3Ghd(θ۫8Yi''Y㼄yeҭH۽ʈBT ԳsmWFn*ZMxrx\HwӸ,≇3u\L:KdӍhV"-Xx: +֟,sKo'9ՋzJi֪4- b(y&HlH?H54-n=qƺ"<gGfXb-L3m0mq~@צ ן4]%{jBOG_I&6?Mpc#%h<iZ]5FTҀ,.ۡrKC@%/:=Қ|l˓:ۀ Uи0 Sx dYvwf'B&Riq>=b'lBh'6 tq-c+m#nk*'x1Fq =LamF{_ޕ^84̟hؗm _UԶXA3cXXnZWutۋXm%ʰY[,9;).'ְ,ËA(Bs`?[O[Ypҳ|1r$ (hg6J>raNݣTY  n7їKt] cc-6F >WKa}Kqrhhyȇ V$_})JbQן>&4 ?{ޝѳ"O.<<8og79K~&[ BR,b<6l?4y<%zk/M{ r?aΘΓ`.RLb6F Bݝ7zŵ4l 'p/ o$b Ҍ^E//^ ȡffx%8;qgI9f0Yb l\pe9jIyΘ+ѡV!TlQzP23~О4MN1z ݞn,Q3K>Fc.a *0&NaL:ht%~;bF$5҃#n `;ݹ`UsmE*čC6~Lpn_}XD}Njp{#f;9I >Y[K 8?\B!#9QҤc[}dQưTZYەQL%||B|g!n%SLJv+Q4h)مR]Iu)P DCNw*(7Y~5Yco ]kQXzVl\6b,Y_ZIӳhd26ߡT| xLj[E)BS! N1׷ \}86T_ac t+b2ƍb ,QG07QHh{LBspΙ""3aeP+Cmy`e_EK ph$()>"b)ama,4}.b/ 쬠a;{i+熅" ;\v~i> dJdy.=4JA4N,*&c1 .(PB9l*|:AiL5KplG-}ÞN]L/{&Ym~园NN|tᅱm)֙ "97Qj'F;$aYx,ć-bÀ|q?_aJ:*H(P[Ub,qb +ʇ}# |C_I)37]4oξL3Wݧ)Pkϩ8!33lrlL$^9}q+"1 *-zNK.$ ;Z$Q NC YhkTM'+~JLhp+o"16%!dR[-`aaSt'Ii&2Yt +r]jHc#G$MRƠ.XQ]םWa̜rګih^"CNX\ ȸF%*UT;*:cTEN7aK[SddP/e90xRQO VOS/tձ)a ۗOn4ːKA%\ kiӻ*6M:Oj]@384 ?+(+T,V 3wɱ]5Z!^!9&vL>'C22`-,? csh.o9X%FxZʓ6Q19^ >G\PL*ܒh@D S'I"ěk2sp-CQ@yY-ZLBX8WnkxT@;e=^6ޯ4d-)B?VP Jbwm=RJB)<(!4. 2hި,l]MOwy[Ȑ~P-NkvWl;\)9 D+)Ac#JecS1 d2\`4<[F? !$Y4N}UE6Vщ۟w:<3̲i3XNOXW="ScZ `U|:` +$xH/M&X,/Zc|=T H֪pbv% ,Ubm$wͧ^(M9xGq'hC^Oh>/*M9OiRZ|.ؘ+ H1GE"s 1ZY@'TЊzSZ ^)q}:h :qMTحtƨ6t;E[ Ǽ 8/M~2ˠ/{5ΘP{jot|0Iu+~Ę4/4X8F$pU`Q#3eϴ6Xʲr9-j7ؘzp~yfǿ~3@p#+ մUA;&g?|ͣF4ÖA,t5&3 W鄵 %%Zc(R0FcG?*h]mv}^㧵-BZ0==K-0wޅϴHz=&mM;5r8|k-F~+(V-R+-Q qvKZH\̨}bl]MsIVKI46rƺZV^4,r"4U1Hʥ>qڟtS hI#G.SJtk9y^ĴB|cx v]%孩[x%Ev#3|޿y_\RJKnmmo("!X ǩ:]#d0K&h}L-UvxCvT(BZ|g[5L[T%yp FʂbzNLЯ1i51g qj!jOF HT2+x2ƀOPj;`dnYԚ )nU;"~ytfJ"-ΠshlYIz p>ҙdz)6EW;CҨ^עhPU'ݺycEW}Ƞ4] ?dŶP_sBr X`46M2]>Gpѯث[:xtxVw#p :h`بF+%X( q0e8@ Slq)\l)`]Mc7&:N@氜\KT]pvB;*.X~Z\EV{h5yV8S+B%w/(n `Y9h0uqV!@i2.z=T5O۱vhvIG>%T.[H\O]6poo6Q//r^Aoyzh_#z|'Hk.R5״S>Pg+ŸS -GebBm!ÆN0l'OfZ.r`[tF:%nQg%R *W> w,K 3Go,"'%gmp4Em}.% g_HWo%+itr/ChY%t{C;GѨ|:?t&ڵk6~G/!C.CƫXcYKL%۷c*1œ% L~ eu-{鰱+캹b^W8J 0+ո!|B  Xg96ܐ >` o|K8,'W{l𶅫> 9s_ey(w? aba !Y]Z"BuA$%2ۭvʠ{)Z'H~K0>^wfw7̀ u`atXJw4ć-siJJhahb? nHFLz~Oڿ^Ќit;,F}Ӆ+aƙwkϐm!Mt1|a|jF; 9xE J^V^΀4XW0zT]\t}Up6E$0G\MUg9Qw]ePw5q/\Mob.X -aABXUE!aT:'qup7ǿSxYZt]Χ]Z:,ǦD vD@8@[TpKAE&|~,B̳jlm+ Tw7; ܒھOr:Ѫwb<N]ײ}ߴ<<6z<`sܘ‚Mߟ)Sb$.b2mB\_kZ6jXGL.&rb0Ev-i߄`F ϫX;Hu%zHA7ݫcz=_!>M~cZ98[5m]$hրf^㗌ăHR\FЃohºPw<_E+WPi>MOAr$_t˦*>p[b 9;|tcNH%6 t;H +sif^$!'cd /6UL!F3dYb?W/,xVodfWq1`-Mj,g_QM'V G$-qPyJM~2נ8 ]@r7 J!./ r`p2!"X^vvJ3g 81L`Xck3(13̤x2_,E6/9@WA;+y{5o&n{CiW&9LSSi Jʼn,&K&/l&e@6,J)ZCߤfx6}X!.мu8ZfTE/x|J#Ib|[{d J)SJKa.yfVKmuI2E!ۛ-!<.-pXᅂMkiô\z0}]+._h`7z[.C{\_|TF46c5}l W̑r [8A Ro5Y7H+ Ϗ=i{f9vMqωq=v ScrS;smQJj#RQ8w#mP8ExUMm|ҬS4OU3zg _cZ=# UHϟR*k&֫)~)t>3gb\I22-^" }ȲwÕ.᥇bpր1`P S]i vTG3c)jsahȱԞܛWRutns?я:rO6h ]x'q3C[at>$73| 1Nhdo/%%f5cB9ز+Ѓ 1M?ZLfHUW[2|[\;5&'rո`iW+!٨ލ`FZd3|Jq3T'y3&U uhyP&/(p| {NKacѽ%ƴ*=/Hu -3i7p85ꔖvl7sfpݵxDafS&΢f1 n MTE4gX"Mk@9Rc35}OV3m7>ﵟ:ҷ^fhf}xI昰T?(~i!/ [O1 Epor<(LF-~'љ䷞onOk0tӮSo HtmcX9CqMb= @z9 bsƥfWGe)n ex;co9UY3hmApjH[Q17Ƕ'%F<;Y`+&PA)$/4fJ ̤+^c"f+_p7AWD~ң-pYv ֡&Hg/4:`7ɰ@u|9F ~~֠k?7D \1Ҁj><۝ qE!2̚b0(G_/,9*,o[vi{*Zx-Ŵ(WWǘCcZ& Ų,V@Y$Mm5 WA]Ͼ i V\!=45@]^fJ]4]ΝFgx։k>RXS4p+D'E\tZKm3Α|1>©Y3٘1P?Xa_xUD_uJxIhz,cU+RZBZOOi۫DqN(X5R B*/ip5Xo.>t_{9{ Oe;*/WiR>q8VmG5whJZ caj1=RCnW#3:ԝWQk0[}t8C[AlEu>*5sx:ۀk =3:g[sgN 9>Iڭam7#o';`w<-VqR -c}:-MA#|FY(bjΏ`-gѪOY3 xƝ ʴ4 f$(+F `;R=%ϧS߳hr8szC~ <q%>Y)ޞD |]6.gV1QFG-0_*!]TvJƳg #ȫ3M.nYbn'cG::9]mFda l\Ǻ>fxjj zVEQH]6xnQC?I#iBK/2 <{ uuX'b)MT!&t|5]i4Iğm$,y8}%: GzabX?]rg^7 OVn%Ck TP)~9+L%Vlb>EP-bv-嘰^o9tı2g|UZ4b{+z6hJ*1JOx;F5O(ޯDS.+Bn WcC3Je}өYz A3( #RCb.Gb5Qhk|G?ݠawJϬ%;dOj 8b*c`%M ƋwagaXdzXQ*JbӵXl\ui@a;>=b[3pqj|.^LNLСO;% 0||WQKg<هiB6M|?Sae6N#ѐfmߑh+v%lƤڱlH9Tk2 Zao.N>=]wbK9VgW)r){no<H TrQ H MTE ;X WرѡR!JuWb $Eor 9Vt$6 ݹgpD-R8iQKb:갫<͊@횞ǔdn-B+-1BJ?_u!1iS;`>Wfer+X30"ݚ-(wE`fe,gl1r'8c5F 3B}nZt/ka c(־Tg ߞ1]@O H鯆ofآ)^3izh}U[LA(WEP,WBO篧u6]̤ "hX/^{M.9Y_a>: !n̦}Խ#=|Ns|y)h _ ]7dUw Vbz0}?7#?Uu(ayG?+vvƀmbWSk1+N_H:'ƍ@>[a E7њr;oҗ22mEoc9h YWhȒt:|×W>,(O`3_C*/7?E;gDbHY00s%r!'< I*`2gxWŭ% ʙ,D5SÏs7IрT[\e|"%n3Y?[azc=\&JK`IquiOY>u~]L3V^x4ѕI ~St׿r˞o40eT%]^7Xu'Ћ;i^L-V`l=Hٕ4٥.=H?Stg}.isXbf~!ž?ѡ~?IRD-Yʁ- C@}ZhjnP -RNrЉԠjruFUv  U]k"Uq&~oN&[΂-5h.@j 02Emt 6gX;gg0J0E5dn%a8\⣺;B˱Ev]}>LgO+Lm5PD9=*x?Iw<ǂtȶqA|v`fPBrL9\B j^ fg|D۰a)nyD(#==NT<[FegZ),/G3iߤݒ)YuS7Zz-)b|u2;XQ={ٵk= K)Y@cI]%a3m!5.ՠG:^ң hoF1~_t'9F ٩C(㉖\/+0-Krr8rlw@M!iָ9%6.NAs i\),P_..ׅYrQ94> pҸPibnY||1kTo:S/#JKW]dWBgќࣗbE'5NXV##1Z`[-ǴV+1qAc71hO4JlUqT.=tB,Z|:Eկ_^IhoE<4~3BK:-ccd92: -XZeT?gܞkF^>7hZ2gz\.Vta?E>*)_-F3(#p3m@acC6G xФG<4[ \75GVس)C]DJl[.Gz&un6U&8:0&B"cH[5~&/L $IXF;M1~8[<3\`liRx4S)](vJ %d7Ң^ccca'%NuB 5`f~ų\o]rOr 'G!ʴyv4RG*L.Ǖ̜\K\o4{-vIM_ݯ));[H2~lwZHl)$85㌳n&cZ uTA/8/VV&f>X4x)=~SPI;\jN#;^G&n/Bo |qA 1I-FPv Q<X<7P3Q6*L OaZҡmO f nΈaPk̟m>fǮŷ:HQsƺ}_iY^s*PPR*qj:!9B`)--qp =Ƈ,†5:QzR[Jiy!ʧs^^Fb6a4@LNZ`j :U7)VTjd8|f NKIѩRi ^ʹM4þ|jxB_Zv?yr/qH9-!L589@&@u6:)4צP p 8dl6I4J2YѤ&墚B(+|w>}WFׇ7Qs&2ezk],kA-4-ܠ$zun}nrVܱZeN7tF04AvW#O3ZQʼJؤx34 fČ)R/\,Qx{\[+%0U"L-@G߉{l Gh}^Z'F1{DY b`$3q-d&ABx?#j~"DZV+(uH`p m1uV@{bdfByF0~&0+>,m%"GOzc/0,#bh <A'1kS'V_gEXW;cß@3P|ZN]&#miݧ-aɼOoY cy={ wURؖNWlk d:(9f!\=8=qyBl AĊtrYGD%e$oDʞl7 ' ck$k!R|0IεRXjHe`lv(vu.9Ou}z).W p2bjABZ #z!^|>YYr:H6-BqV+1:DiU<,?(?L/E1) >fP (g7T{a$q&rz\/Gdž 鯟H-c.rgCwX Dmw׌&&$?Dnkߚk4QKC|0DŽ3!h>0{`u'!n5C L&E혙7N d!J0`2܊`G}IrP"P+ǥ=F"-;gG^$2@өg\68}@aN)kEV(4~j5N~6ţZzGlT ;H q!4MIT5fnz|%WUzf*YSHfi!y "p0g)FH-0]kc2ZP$Zr, 6*`;S e0/AϑRx+0K@!w41BG1U32ddGh.ӳcBO j4#]鬤#gʩ 1"S5.9ҪwT0G~&8 6meBg;{TäLi4@v}ouK,-D1@z)k;0Pdй"G 1FK 88bi qg10@zc r|eoQ=j#e'6W  B.7 F9 Na}sjOlz+6vyj%ݿ.\Jy湵t9?_k1^-$z깡PU3#& .8Xk6j4*!hi&7NpcJ0}n$C2"ir.+PMU2fg\ׇ_HݜBbz^Чf=aġ 21աrlgn?!Fh1zIphz"\\"mvUd)HO5 H ļv)or>e)]:ԜfznWZ+VUCEhEqX CF:&85F2QD?)fH9xQ<SB*j/;7V  TnlQӔbO8hoQRgP 5b& 9l!9 j }Shr&+q[ht+][Fcш]t-|%A})_HR&2 P2 ӭa2-pͫaTNbK)e*]Jq](DuqVj˅gwÈZ Շ[TFTnՂA;n?(h3 icf.!I%X]H8B9nA}y=T1]{`RL?ܢo\2֯=TKH R)qo=~Ę?PWfΫ߰XYRI1I\8ϰ2K<1M2?)<} I&U:=OTĒV7ƶ`Zc8CL{7dN$K(y/|)!%6~ ŵfx4RM`*dr|^ Y_|0V.{y| :ɤN9&k(|z:shYC/#sǃ4ڼi*lXbLI- x$Fy1wE έut+AV6$< x~-ғHZ5j]3x79}2H60S[gՕLc|cXY/RQbf=xH6Uȉ/*ԗ5bJ˶mS33ley D) +-m|*f^oL*.Fi6\(ױ!45uqkԟe*vg}~B{=U'oQMzȉW/OGbTD҄b = 0"0@Nu/ic~=ucֵ1f-~}ʨįLOXG FeX= AKHKzaT}UJy)!:-C5) 7i-p$v~\I-֒ݽ ,n/) fb!5;[ f6p<!ؕaTƆW?S؋0D'P/_dVpV{B5Ƚyr`2Zf_M?S 2f5!n~;k!k;xxhx6ĚY8.%{BKߑ'Cg.Ç4mo %>E?WI۪HLS\ a5yHK ^V L Z,@4>!>QA~>ěR F3K0cwY9uc*B_GyhM2L㾭9(bDrjY@ybcFg(x u{BWE߳*4VDSuW5<6}_px앢wRkJbr~!fL+CibrMi`% LMSjRÓtWLبiXSj6HtV_R|c|$`Y0i{8lSokg~2V篤3|Fʿ>DU5K)ctzs.I;J +<=S`Ipa]*HJB!8^lZ~[`6~2j0h5S~;]||#j`rȅGP4qf "b-.9:+Iù2 *U).b?U0 Nc ^HӨm747j"U&lE?LTdqp2u8I[I8@K]fo챕)H!C1*c4PWU>"4ߡ4xZB]ƞ[A\KmŴGXn*jI$ufM}$d7M5ב|`P}>-l^j^ydRrV^Jq?KB{E8UӖu4pJ-Ej/]I^D!ZKi\ WC8uk!.\T€KvNAjROE +NͧM'(}-_J//RFt]k;iUk&i5̣ I;)pGZ?IM jI$Wzc-@gjvƴ&n sK+#jGTrcK>r܌GkvrG+BqL[V" jw4G,5l1A4ueZDBKɄY:9dUH:;z9q*+'iy29wr1NU|ڂjoWOC\p#|* b|YO-n]&tw XNvLݽ6kc[p@+rnnau\ MPE ,V1 Xr|\ E ~2{/ECF10ZuQE:EIh:.ARFScKɩO\PTaUK/pUWuj"(I糅zI,|L<.+Sk-۷~MASbZr,]KWӝ^)VJAQg#⃢ Cmf/$y#K?rLp{] ]NKquoKsZVJ34$ҞυtxpX'7]FûU9L&ȿOWm!iS kb.FRBwRK 6S˫|2wd; ZD#UPj1|t9WURJ*P:y5Syb~)n1Y,Ê2h~B]K{|Ōwt&cҗ *n άCԞIGo}z6%MɽKo$@|Z*@:ƣƼ39[C1dz@O"mѲNL/[qnn/a-[Fp=MLoK}tz6=B9tJ_=Ne-8n^Ô9 fSMW.(gUW= O*92h=3vX#4E W=Jz[Hm2h٬*uG__o4A.E1 io%*tc-|_L U߮ӿ+yPJ!D=p5AiZa%,<額.$@3.|oMy[I+k)¿rvRw %9(sG-=[B|O_tN%6dxZ/U 0ٹx dرPCR,-Ć|L7:|Hy{(n -}sϒx~<ʯRni!5![wRΓAAB%T!6E \BK+[+q"'MVx)kIP*A I]!o7 o"@~-B+^@}hӒ:-osH6n>TX ;VS2dVbI5(&ՊJ2UD4?R7C&?7{G!'WZCwݫ \0xYMQ@K{Z6NV yjJ5p6 6ž,~ce)ͅfeoؙ:䓺HtCq.Ǔ/XfB6.DHFA=Vet:XWs6vYl9 aLN!d:s)bcn]'k,#TXIƩ<\ILʥG";,j /L^&$-fU @ӎJ6Y"犰;Wq C"gTEb< Ξ2\1Ša{$"s6 oTM'㧑A5} ~FΥח})x*4'mݼd틈eXG.vڼd]qiHWd9@gy"truY2lDJ)MNVfᙹbN#pEM" zڏgP\73~?nbvJF4MDba$4ppT%iTД%duE<{ڮtz3=>KFah7,co9x ϛAhݙBsl2;}.>{  46pNA#d8^ӌO{&ǜRPɐx]N N : @ *hm'2L|Cq{>ά!y|';`,n2B[:moz+Ɛ`U 0wah-F3` QxffkW19Ksvdõ|prnL/I<FO"HPi/E/JvF fӺ*:'8LVq1'}"^[J "Xb]31v#aE|,P!٣| څ8W% )B)?Ik"nOGm{u *]Ƃ7qh>уV Q΅zX1VǶ6NL_-~Dɏ%tE;ҍ5 /ayդd2T9T(%8"p7 +)bp1D~axZ#+XQe0I!EB:bȇp'KRT j־ŁO6tRM6hcn6nІ.6$#3 :k[O a%򬜆r?>j ><ܿNrq!^oMšg7NHuILbI00;pWΎQr{S4W:T1t.I޶vϧ $ԗtn$>4XA>IsJ/jYZbvELr7pŧJ> 2ktYy2V L85i wa_"RIIYa@XmFc6TWi! -9G%aR$'J {/ž #k'fUSP02apN`F+2D.# 09>.3Rǘf= W3ut|'/$0Y}VQT?Fa VC*ŀ&dz$1RL_ Du;,$)Ļ2Ƚw,NQOdVq>/P 71* LcA갍ng+_^ ^YL~ j).C[DFӵ#|O)1dJDI߅"͇RWV(rm)4/ZǼkbW*qrPP W5Ju[N8qT[fl2>gzHgp+îd1iQ}^bU0"ӸɸXrj55ZB-.?ɸwɔ~40>h`.b~)4[-Ԃ-YJL.C#p}1 Gv`uMLIu9NrDh[[[1F"T?O n L=ޛ.''VJ(pJ C{kgז8 `fec\ $FܬLct(E@ ,ܯùe4v:;5lp>A>w<_HZV2KE;0]ˇiC+US{z&68Ֆ%Ӵ1jUd;OUd߮ۿhOǷ}l+q v g1\ߴpq:nWWђQOyjԛ, q\v{0%􌠵&|FՔ9 vBWRTd9%K1)khX}.j Ѓ,|8o W,lO*@3 3uuV ;uE+ob াN .iNB!b-l-9BfCdX?L &Ixa'2xuXz">x>}Nڡ&&otSX_GRQę*É)w8ձ mq#] 2Jm\YZCѧ^x7CtgFJ[۫crc5d,`9=Lq.ixbUJKhrZZA5[q*(ǯR?N GZb5K$їhfm"AB;à B`C/ +@d JaA])w8mכ3`WYY3<6Rck@[cuحΝNz[K4㞣T*TzZMq~_{oXZ?֏vKc UV:iwY >.2ЁQ< b q.35b :6K oގbk $nIxn\,`Ulxr&&)8d5 I#'Q4[$1H]3x{3IL&Bc+tc<cs!!ຶd}qvmt0좱kX56ljhKw7dt>^2y}B7)'CYb71f1qb&\UбqߨtWjq'"N6qV >5tҪu|yz#hW㚿  CZ1>#/<7Nyz6:RAz(<]4zYC*b/ƻVBC̉42mj+r6CaصLKM"4NaT_>OP9ԹdtB[`@ e.i gӃB]Ƭ& vZnki݇erT͠y[}}|Tn+(zƂfV{PMΦ6 ^I`.]d|A ]qԃs!Ml[(kͶEeX;0_?m&Lj2H*%,"*G"HEB(UKCl#xjR+ƴps ga "<\-&5_T+S,rKigtY{6D'-djЀl_h&]f2Kt`K|[$IJB$V)lGÅZ '6kЇC4x'%nG)|- +A3Έ| >~ 9jXHbػ. /mT.i~Lei>>}Ӳ#s[1'Ü2Dݲ״ui y&YI3i#&lՂXt BqbZcd j&4H_Tl1MLMgfPuTo@ܯ4%:cJ;L ~ۿ[=,`g):gv|H =ň:(@P>af.F[uS(MilHBqہ$Ts,y.oXE~6=mwֽmu65GSS,4"=R֢(A/k-4K@3;+iOT}[Z8U~+c.ZRBux\)Gt֪үdN`A4Am!;Ys>n '++X[LMbLo8MexW e&2{aİAI0!Ά} UGtcm\z%Ͻ_iFM\T𱙙uφcI|̷ 'a Tlt/;s6F)*2 0[Ƈ:<1jA䨉>A&mL@TT *ZGUG]f]-:tvףa*vFmqRI7Οk#uia^M$h@}Ď1½F#ͱ>F[a9C~;h})2 "%buxMm|{ AEb"FN pr \upB+DoK[y,i'uߩ e`3Yak\Ѱ\T}?7 ~"6vFک-A,Ogk8KAj1 noS] V&N0>;Mp)EL$lGE)#"?O25Sd.tPD]äs/I!?lzQLmM4t+x8Xv<SyPcQ FͳBq:VXa%{ZS4)WBXV?Zx=]6ޣ58;%^\ߴ3#o17F@[;k-ʂl\i uhJW{8EqZED09j &HsȬ4F5dyBi&]+Yc H'Y`@yxgzp1Ƙ_F77ƋqXL{£nRR9mhUX7%mIz T3,衢M.\l=Ǘ:kE-*|9kI ]:5Ӵ?iPgT(FN ad8$ $:RO 9ds)c.3ب .!!3lߟټFYp YP6B`>&4@wkbJhu$, Vk,]Ϙ'%. _5^yHO5PJkI{u^H(Bu &Eq2ߋK,@Š3%\7cF])d,T3}fV;l#ƙ\ͷw[4gĐ`B{xcۭ%LVOĖ7`\o-8I\Ad h˞;:qCGa1t si c`v~!!x _fnt޲7QV+ _qflK7q 8C8cm6GÞ?9Fo7uz#̜Y̙veLj/F^r8+:k~<[+]hNO2 ܽݝ_a8S쿾aߘz:Ʀ#s5GceJl͵̷ſ4ÚJyrn*fZ^el=ڰf{J:03;9pB;̓ Xύ/;\эW#]G3!k"v:h+_D|T16m˂.L)5&=7/q{K%8yZ>xix޼]FDbo5"Ni'YkO:FLyvJqc\9n 6lD9Om'*h=J_|?e}H] :`\M e? <>KNwG}BRUd埄6n?f$8i8B0*)솇?oƁI՜N5- u)ƫ̹%'s,KJ希[<azN0p#?cu=Xލ3޹IU:ēOf+yRك ۹ɝm:Q@3rP/ϒt-[lxc'k^P1a}Qex!G]O{)FҪ4-@~pX΅غ ?X91TrN)m7uWY֋9fz^܆ _wgmU13BXS? +ȌXЩv9<^bHlVX(0+f1ނu%ݚ3v9 KSwa6 ?|m%(\;np3bYrp{9^^ו|1JGj;Νe[\fËL?ǎ= N\–cY#toJm3G._d˩L,'R"e=<DWbr;g{x))xfkj؆p!#>xwHWQ"_5I+\ޛ"ְ{E{~AO8$֍ϊTi8&ON-;95PCRJ1 )ٟ0|m|Vm$/vl0> sdcJ{kKnT73|#|ō>~vqCM:gYLC6\Vد] Mۍ eI+{Ff~KO󄎮KeJl ,x'.΅ 6} UEZM;YۊXU3DtQ+XB0 U~o/ӳ{6110φmI58<ds;93-ݪڅf 9,ĘruB׼|ǒP ^|%KX&z4c5ޱw53\9?4Q &s":hEEV`p;qoko,Q?ɚ-EL]eu7GE9~_5ϱaibV¡4/'aYPNIĘ | |%̉bjQnM_qx8)K>w~{q9BqSq s: ? RSC /UZ ;SAj]fǭŽ|yw R1ؚv(hb9%MO*wX67Mr<( (fD\?AF@M]RٴTGJ=uZsar[Vϲ6Ԇϫ݁gc;;1-Gmv㈋v:Zޞ!KxS9]"%7rލv^B۸ݩFz>Q]cXzyf9I(˞떅ebc;1:ۿr~&+EVUk`P=HFt!lbZǞīibގqEK }7KYP)839wS3ކp@#FjC21~_:KW q#csG^2qjm/p  8͌bqJٷ̚)8XA%[B̂b]V&!2' ?"\- %=H3P2#g͎*(Tu#7<# .iOE'Op⻿=cJ+GZ u*yidf9"yatDhx:@me㳖J5R/d`>ܧ/raHx͂Uc\$~=+ 5q|y~Sv7Q</89'PSO,5G7[Ea"Zpo1j{snu]LOy5׿fi=H|kFQ/KZfUT(BR/8-:'k_P ++7WqqjdC֖驏г5w6QckuEfڳqLq=-u&|$pxq# \4>Prz]a/ 7)aAr%s 2NHsؽ*-ih.vdbh5YS+)_mfJ5GαfZ r&_~Ej6 TQw9V󘃉QQρêY*8đcY-2qmqWG>3Zżj~r-ksf1 =K%]?bdC_~Q"3o"*&F(XGAJb>[ɖgd"`+"X /J~MBr8,0COU8}b:ˆf*.@8 3ؼ$V82L~ &n 0R-['y`^.\(|ػ+w㣮n\ƑO<ᐹ&>ܡaåJ>;z'`,T̝b!}ΈY>NBCKwG<(YG1|l&6J1WNsWUgyEG-t\5}5r1p {N׸qGGGwnuʁ"8 3k\5/]V2B8~zQú(<|ǫVy8! sqm2.]}ᇾbo); 12TSrQ6s*9[Z䕈3,):.)–y + ޅ{;18mp 7-YdLn|R0-{i +qT{3z5XS-nvfeQ3pe:,bdz8~ۡ\?ajX:3Wz?Ǯ8!` 4|:(t{c`שّ92ۑS\zӋ%\6<UXtTzↆ/|lqw_5o ='fSVlX21LZD2^nyxo1ž/ym- sGOr<5GUqJ`)6щUu\oGq.<"r(7vXd7GhԠ`x㞉.ςa6fNgm*F!mB/V%ΔBr> $c3l $(Ar< fqO@Cq&)RGB Be0dO?tvӬX-Ra?9I-:I€>/c2.VߌAV%$f'4/KF҉HtO} Vѹu zQv~צ.vepSYaa)+ۆ^ikzeu-S g|, ytƉ8q 2] +*ڄ+Pp_cwzUǶ1j-iG̨h^VIHWT!fKkc|^~(5ثhXAZ拴,jeI+0Ҧqd$GJv3_P™5<L6xgj9H˽ ~!g[*Z;xHu|#^%X) ǐZ/EHUE%Eaax )20VF*.Fy5"±eܝ'ZŹ:詖ֳ⍎_j'y\{u%,j~o+1a` nNoi:ߛ3|z8cXk`XW) g7hDχI&6c!lOO6OO ]_gFg/gΜRʘNlDSvSՌWk?i!ӻ# Te:ڨotUk/A1Y{ތwk9/)9M X,0-9Oo߬Zzq=o Ց ;q2gvHNuLqc< 6p;9a`H'dO#U'c+*(KS;=Bۚa\?9?G[G <`fe$X3 V$쿗sA~-ln?1z; %;ܞ_K:<7V|Rp -Ww򔣞*46UIf|vaE-wIaY8 O3xlK~_a'H~~ث,G<3͹4ԚǶ@ᏌRlz*;D#T\IIj%2Î)g wa֝VO]υ-c6Az.𴵆UacyiF~:qcټ6;s-χGj<Ǝcts*C͘z?muD ST,P-+y h/>3ȍʜ838s̹W}߆~xky愖:ala\jb(?Da&mfvdžG7~X|^F٨4=:wplk4yx3of 6-5RlL돈xKT͘RvWd]}8<#z USoz// yw|(/?&s*/TϑRv޵RvY&~<Ϫc_cȭXtPfaֈj,f%ƙnU[K E0%쾍nU2Eߜ v[ɍZެP0mldOj=d/Ͽ @)!BS1ꚉzѶ7]uk.vdzw/xu8[ng0#;D9k M]\xkn;mɫ^ĭHNIb/KXpi#ttTq*kNH8Y$Wخ/k>ɀM'<{gPcp lÅG'څ6#)s>ڊ7i- X"߉ baY4}q5챺cs h{6X cpFG N5T<}ׅzms-1M*ƕ E(>?…֗1ji=+`0xۃCubƿzz'{0{VBq ]Ai1 _mCD2|6GAhWDH@)VLzfP1Q0,J@Ʌ{(sڕ ߊH//t 'u)T&+ 9Ŕvթ@_+K^k&Q۟dpJZW55ѳX$)S9<ι&7<}xd'dJvXm`z Tmy#74mɍMۣIf?K)7P7@ɛm<\($jf1Uz]mCۆvnt͉>9F7D`=W٣W5-<~;&RNI7m)c{4} 4ZAx+ȭ ύxA{ؐK<)F»pkq a.vJ% קap" %B!_wBQEΖN1Zw7:jP;_ðqrN*eIt0f:صđp])GUb<Ï=: ^Ÿ(u/8 Fq?s};_t# 4['`]I\#ӱ88g_b~MgMmܺ~+Ty m2/#]q'Mu~t}lL'Nu؈\ zW];33ˉ|* j3~sNGnP`52h!aKjd7_0Vp#y?xA \u 3)Ζ<,H {p9PpsUJzױU=hY>SţJ8{T|0.`(C#84+h63j[dU[pe%/5Y$cz2Tb@\)V/.͟E ȇz"Z)o>^>O0 sT' }rw}]ayo>]KQ_[&u큖 ;,\ .C%˪a̒s'9㬆Jeg LOT3䄔Y1b7رv#Kp֖iH |«T4f Sq7 e0|>ڕYr@W.7Ro``EZ󜍂lov75wŚ=L7_-rW./.*׊=ˍ\0х ]~Ӻ_ Ͽ`ڗ: &5M9f3 ,9E^է`_bA?#ܲ鶜j^#oǓy| ?wufY}G^Zİ ~ah=CKwyhcT:VհQzQЛ#K:cܹ#+~5'f¶4}zS,}_Q:t6U\W_x[r:sVJaLm~mcⒷ)(xݶzfEÚ~Fߊ˩8wҌ BTKGɒjN Zk\^_çCeFZ&mvdvP3/r+VtL iӅks}? W.lਓJdbC#{Șv^qy%g/W ?'coGaV<ړ^<7Ƌ}x&=޴X>LA4 x8&\o瀖>[~_H2 ?/^s3+_*_pJgl6ƕ{wGc8צB;qeG[4dU:HmGYY0n.DjHCpa(>y4FmFp"[d~o)[򶒖4\UN&gj #M<8Е#j03ћ/zszӚɬѵkQMvoManl܄TN=Ѩ]j=z: 뎵t#7sf$mҷBvāG:~ k%8I#gSO*\+0$Hq5_E^G΀JF}S  sU-'4K}WOWu=qp3 Ͳhz<wI3=RD!`x:̘,rnn)WRU*¸󱯰%)}}53Ơ PzǞNhhOdNH`9~C@A͛05J{5=`Vw v_5ߡ*LEADl_ǣU"4'vН[w,;rc%\`Zß^_t8CH$4PEtlhl@!GR`d&+Hyrn,=C>[x/Fe#8i6;\*0im^bO s3Ll}cc,"b#j>]#4 :uk'N((,Fj\P+vvfw}uenbF7.S.TcgaD"6;%;1Oz5n1Qyz,{xxK1k m8-CgoUꦊ[>*=MWjlյ}X'ї!sڌNv8ETD}S j y 0Ԋ+ 8 +bốPۏf"ѻN-Ts_3ŋx0%΃+=9+.ƑW , #-e|js\}Qн{w9c#y  f؛)쐌e h} A܍9qȌ? *SYm jE"OYpE OtIǭ+/߱w2mxx;O:~..kGD蜬£cLaIX2[ao .OI纶L4sU^ On4tdg] NUrA@+Zw3ιd`M) '֊( e' &g=G`-vR2HR֮“xvoj3| ~tJJ]^{%tV6Ƣ8*FӜ2a+>9ڶĞM= .BZ[;v' []=ʞn\grebW\S|+W+ .%-}-iUz[KXTևSq1;Fug 33x[n£y ~¯)-gjq6=;-V DIԡso$>XxH>3)!!,<>4_6F\xuRr6pOV:JOt犷.Lv<[; ;^0QgrJbfZS<oU/p+6 e0Μя9@(l7p^ХrMfgk5-9nXT59E-~/}8iA*;+ox5[gAj_0 D쐃&5boz@EWt{wų+0:>I¶ltfx;><ʁs<m1a+qUf" sC#UWkU0p?jn,}C ؏%5quB<]>~ʚS)Y%#Lc=%ԘžFibAuMXm&O9Kft/mly̤k2л_YvV-\W`h;3&*lii͋dr~ֲ<\CIۚӇGQ/p16)7r 7NЯ?jiQ Ĉ}xگ.G_ؙX @7n'6ۓW['ZX>AFO5 U=WˣTW0wujo6P7vho> osS&<>bXX<A}"&䡟h#4=%u\9Qmly$NDzRZUiHn ./rUpP,w(壀߽;fɇ?yCҡϱi zI5TlH(LK64g'6^*e2~7re13\2t͟8kfgs.g_QrHsM9#WHYJi.0tq_GK\(wg7Whż<1ˑgزs?fHxr5<4i*Gclk,qLJC=bvnkaxG#6s̘Vqp{κǼ'47Of&r QEtk&gc׫]cPd >~6𡣁 +yK2sO@/m} Mu|6o,ga*Wj;гm+L jdFj- K`흅~?aO/El Q v?kwKKv'_BL1kY;X UӤGE;OZefT.zߺ Ep=6nGa| i8􎑟9S M]rv~.S,ökq oqL40xj(d5ܶѽrjdztu[m3j[< /w9p$h J~Dxt*ي :XrDzvv0d ޭ~[gl.w$k"Aɱ3ܸG7=L'elÞY:}M y>1'zvM >%F $ю)>- ص͊--ӱnFmZI8|UX +աa=-m9Lt̢9s9bFbNsnsآbVA H9afypUQZmtu{}1qzM52c;bt%-WCϿM s5G9 WqV:r9Klȧ/SFW.wq=ήeI?=d6Ŏ_ ژ^ :ZUeO$IA7;:.{+e.aKd 'SGhDFs~ eB3fLYO\R?{`k6o7:PW5wAhN0KmGD]A;ts~[W a"Z$ZA4uKӐz8ܳ6 nϪ7 teq?+Fq [IXMΙ%2~G'Lg+fƕ&՘k yk8-S%x&sn~Xt?wa:p\3 [ I 3VmScy ٨s'rr4M\ %]hwĖyJS"GkeGڌOfM}FY*{/∵ 1&-]]VEZGW}Jg!& !}yɖl1Β7U*BW=A<mfM᳉4^,꿆4u6f7_۷pudEA2Y6Y0G+2fnjdT<_{|'O`t3§pXyD#jr:uޫŰWŜs-ǟVn 5tgdEv|ܑ<8ESyy~ο%o1sj Xjtcn6j&lAOwy+&t@ <@ޟc0}`ZdDwzt `:m:q}lD_u+1_ב<$8J|tTşS|~`kl91hр#`}}3a 2&q_%/!6_>!T>f`-[ߵ=a߸!uW\xna0XFl/QeY/yh7 @Loߠ Xv5j]3a 6em֡wz>uvl-=Ѝ=kwՍ31Fz2"ƍ%ٶL^ii3E/P/~qmٱS58Ƹ^o~޼o/ ̱c1 nO~87BNi_&P)_5.(Juchڀ y@ݎ8t s7:j e>oh1^WBw70Lw[~vh1g7R8Tl1c$mob!8뮷jCt~Q9 ͺh I٦,<~ -}Ai[^ws=/[f53#w|_Rq!T Z|_NߏkqGEkV Qp#Ǝ *0h!JrO .z+MvmeƜ8ϔUfմTb/$fx[ [̔ XUZ.ý/G/"b͚ܧ#g:/Gc]/*v!: yuk1yU3tM>#9]M /]$ʘw[-k#li‡8s>?3.ߴ4f @+\Df`L,Hںp| cj bX= VwwWd Th„/ 5f|ow(xGwCrGłX-PzfڽX=¯CPc D k}\be]3b͵y _UX31O'aGр]P9<ᡏV7ĘWj-AqTa Ywp|PY`<u;vNKCo#`ɝ8fj IW||vM> {?iTMr;_3Nw|r셶#0+}~hR:ň nXmg[j m9 {3Hǂ۬8oO~nt%x~D2hߩbjY ]2W`zzjBmH#Wvx=MsOj}v צU҄T{MoZ RP\ư߸)'M->m'FW'hݲ_Xs2l1hPN9⣣%e=/qY]ֈx::pY=+ue)&\?Ma4#۰gd aذ0_d~5 \Gi^.&b@_R">2+p*Zu)77r{=f$l~y^0}I>n`m͟me] L*U L^kV7q%m7"wxu '8su Vs];ƛ}`gif"wT\C_ï`cr[)(7K*2\VTƂ %C+8wZugA]h6kS֨oy&oW]5N,"dTև e{m^7c|}V 傟- H;b6|JċjɫXU <~oڌg4dkآ@["n% ^^V{:Dj:4uH3&Tn1e[=NX_qT\݃ߧDh[h>gO-S:#pb%F:hCg3Pw vFJ!f4 mihG@ 9`:N!Kq~#aX3J )X=$a_nbE")7ޑT_M9f9KGgjbIno/GZ8Xya3486סBU9fNlh`Ñ|gn6<+a*GnHr/p)G4ap7Y7~jeȩR Nk5=LD'SżW"Q Ph6rJ0:?;`B[;FmCw~^%x^UWPuQ$}{uĘx u{7NI{p̍uotҊMo= /'uy-J *\_'zSp]'\FLoB>FTfʛ3M1o2nԖ 3ⷱ;谇:KgbR~[ x= s lf]\ꄎ}SXbBg[cRXZ֍Gb%LKX_=HM͞Qզ.ebMꗫq{DUBQ0ҭp> eT㵅nY^\?]ƈWJj\eg503'GjuVW3NjL|G. {^ |1j/:'K$3f /mQɕXa![Vgwdz/8Zh,,UKmB|r ]|F4H+-vvc. $hƚ. wgl`"NG:oGC<\' HDҦ^"/ksD4}R/ZXbwO^lfD{-1OWMX9ɘu~a; :{'z򘩄 aUO v㇃u姶|T.|}<(ĦC409o*R]{c8!P͹_4`WLFL-V$qx+>L]=gqܓ31‰B8HmUD1}>"#. O`Kۏ}Džc* Q/v惹0*_%hX 1K  2-+#Qc5+CAw,y"gZxڰoJc7bOl])V9XaJ`m8<ҕzpT1o{r)kEjvu*wt gw`Wӷ1rv!v gyQSN#JR22J|4 ӭyw{4ᢢ2lG1M~)C#r%'~`Y{MIJΩb=1Hr>r&)7a1 j]7ϖ⏼m ߗa0]qhCV6":w [*>,bJa Y3FW5ÐyqX 6`% wo<\ŅoeD7d8}.C.&ty~ K4|Xtk"};ܓ`LέyL4e~g--FA,{Ϯ:lv_P'}G?"vMLFDD%{l`Ơ]uX3ٺ{q[C5.XأQoI*D8;q}Uٝ@'IYl$G`)*f ;[秫(PqT%~|sq'IyneWkpa_}L F>T"Ŵ o˰|W pf6b=.?gk匿%y|xHÔ{ċc$l!eAlhdw⭝pEaIRxNӳk:ƻ-ᙧWl_˜ 6}Pp oSȻ=o^P(^fȨƛno|y/;>y ?ZxCmzK0h>#06~эUO][k.xm^7ʓ)N6@Zܾ; ]>¯hja]| |q:1~ή"~X+`TǍs%WܴWg+Ѧ( daO@2= 0/L+FiBuDZ U3F?62`aP ]P'SnVկ p_"HVqіr$1؃R >%kc+3J^I%*8n3}T'2&`!Md|ѝ:z3~̄Z0֕xTx*~P6›޶a:7C;<>9ԗgD-߇C5lx+e\,J@h>ϑ|c!b>tc+ g 91D&[Lr1g6?Q[u"⽣\d"kvjO9vk?SkƲQ+*(=Ɓ]h1(p VxwӀ\5󯃫˱bX~[<*̭NaFmUcњ MCEo*WL+A2d3\h@Vjt>_wx+ո>jТc#Ra*þ,/GX$bYz<ӄ[[ww0f<<ٌ%Kh;Ĉg ʀl9|#tE%nìi7D6{v)ŌȍƍM| & C S x N䟏m8zᔜ]xLWJv$gdEAe20q{%{p6{/RF)_T2m7wh%SZq{ z%Lk-5da/2\ʮ|+ɗ}87LV0@θ**P}xXIMK1p+Bp.g0ō9gh}uF3F {لqUtO[fiӭ&3hp֬j$O1Yz L}\( *ۺǶAiΝܮcK|^iL"}2i\L@ug-Nj2&"0#VcZo^&ؾmZ^ zY |YWq*1#jKuX4Yb&^m!c7]<9oU <)~qu}qkvd Ym%/s6|gV4ׂ'|i\т_DmeKFfq:(PUlBA>XbY](XoaGa7}Pps~{r67ΏG0 )½.pځ%}ثNB^.l9riK= sIZdi$tSv/x[2&rwǛP"NA͂,<(„?K`)&"FEd%ܿ*g5YAbJo ق_$_N|X9?޽u3rG{/Tآ Rq]73xCެ\s֗w2/_}P14O>śms}>V# ԩc_Q,|<)O*xK.ch8C..ll˔8Ĕz<+|Vt6xotƯ0 WD]i'gx~ZQ!/0&\1nQ9V-/@m16穙=:<xR$ dBb,ԬFɾM@z4ϊMXk"dv/qJfLL9Q i14 Q0U'N-8NIU*GܰEBА~)/TrP17_J|ƛxI7dNlU&jqs?C0Z{sC-f))Tp'紤Vԇ>e܂E(Q02Y=,YpDx<ÞS{rƒwd#Ma Fl/cyfJЕiRoX'{ 0jJ,Fg/aomـ8x1~|m-M/ʑ4[=hțjt,Y81 OZ!tԲo +/x_X>kƧ̹ [dDLD>MEHDo0ɂE#j6aT7a')d%Tl ob:S `8{u[uO1bH+Y5*+N>l˲\ƐzWz)5xE>60P͝.rށWرZ;L8\K'CxR1nH OE854O_ͩdD@K nw w%ƩB']ӄs2+cv2ԃs̿&30|"p =<ܨ.4ے ]]W!e09]G@/\'t__~;В{ZR%c9[JK*9 Td)gq/1J$oN[Ž ̒>lTq ]a;;mpdc&t$b>b؃ 72:^Ce@+h&N*x& = SpLvO<O:^d9!t~-ΰ0d)g N H,0sb& >+MŸ*}RSbι!yO'c7=:N 7`\<a~ U& ?Ompx S|+]_Jӽ򩂇 U|\>a2񔮘wsKXy)?#w{0Tߕn<3݅9rt'z}617QQ . < ™{9hT$}:okqN^9_am&A?-?`PxI@S^`+\wU *^W"t9j x~/ XVo' Nj[oqQpq/狁 ~u%mgG9 MPQGJxt>)avO}U0ΦpCo~ف!mjI%5za1U FpZ1}CX7VqT)c*=Uz}9z%;IՋ%b Yθ(Ws|NZȅߞLf"籕XWK1}irAmBk 6ݩc`O ap6$@볶Ը1ΝNuƬ܄n R6_/ƒe/GiTW^?)hۘU)jl㙅nы¼<ҒVzGK,M۪eR-3E*NܡNGSd>_e^ܲ\JbQґm]Ovrpa_gG.6ceY=BmNL;|~ gB{)V b%ֶ]` \ #Y75sb޼(rn˹[dxRC. ٺ3'dt{IJ(wVuel Gy<͝FxX;@7.*GmY,2MnݨκFstZY׋M:l5DހtU n&0,X9ym_3L?(;?Te8^J,z?>* 40_-[w49~9}\=tEFrڴGq\挲+%W_Rq/ &Ggl5_㯙0kApx2 ֲߨD":״r =z\F#84ER?11ǜqLnB&?egPpVGȹ@Bv1P(Tς{"%>4ޛZS<ŗ>R7 ScLkYlL Knj [PqF@zL~b/k٧Dބ}ѳ?Iux{F:q .8ǤzWB)p̈́kÛ,8(Lj XibF#vÁ=#gd] i2}.Fȇ]\1W078BMڌިmՓ)YӛTo:rz_֪T(tha i%UБRz('ʇE>Jʼ^|ixS.&ܨ&-bS&n|kAZq4: 랣;ӧ,l%+I /̅(1"2Qnچo۹RoDWLɀP%{TJ8;g ϏFRnj#Y++޸r~ zPƒNtnjϜǎ7YFKvya6u<Ǚל|#̵h>UԷ`C&~Ɛ WC<ٱ%#uB@Hsoo@h/cl,*,v Shpm1>Fr1:'.([>t7D(8O^\مSss7nБYy6x͛]H]'| 0C/ܧ+ii2PM&7c VZZ- ӱgԻ|4wUgSkp&f@P|h;L|~Y7^C.+T)'i8D x_)]ynqL po WNr<7.5qK΄ w##-g ZkVe!t2q6USW/x]^Wu76ç{#nZ祙ڢK;M<u ƃ8Q?צWq MG{#α4>֌ʤ,)C %GOWp; lvT 久hv!eZs^Coy/ e,Nĭt Ԡiut-Vi0J"eT=0fXŵ}Ъ}$bFWD],=JEo袞 IR 6͈A̅oh15OKK.sg'{K܋XēozqE H8ïb9O83b5/1R>̙#FhJ3Μ_0ڜ,-Ӝ8=Ǟy*̒3yشPztev^jcI0߲ӻ? ܖל;yލ@&} EFh\ ?Bk+>Z2OK!wpm7̓GgSwy D}f\#ពJV(wF*BiWK/sTg]|5i*b%3i2O^ZBu&FsC [^mbz #>aΨvpm{>] $(`z13,ݩY r?T9;S0.σ߻S=̋۟J9ou=О&,666Wk^Ҍ'ϔkf1k-xΆɂ{bpWo}X<^F)ߘYE<}OF\ ={26|MG_ C4]ޟioK\Hϵ+r$G7nu [?m^Wjt9bAK)9-Ǖ 8[ Y wZԵWa5:{4pB"ƫq Uv?E7`!AWv$$~MGj`Ę]vJuYӄN߻;y_'˹y2n+ 2I4onbbub܆:YPuHiL}^4sciu<ݘZ0%WIa}+~x T q{v4' ifӹ%Ӡ]QXq[KxDpӜyf+vZipۦoDdBtf." '`J'XQXޜX%^rʎbu| [w MNo]a7ZUhE9keUT$Y-W`<8Lƥ04=UG֨e,t&:Ĩ˝=]ԃÄpGE \"$/ڬrTOtWOyJםm:KOc/c$x-mhu*5vҡ=.7 ߔ׎Y b?lX͘3&VaTLgxo._poo7l6~YsϤX2_F"71& B rj%? ]ݒR0e_ (EuyȞ=>'(72Y۝fL- l:4TuH\ζX,9: UYT ͇,j/HQ|ϊA߾PG 4 2D{tzph5,kӖZ +>{PCpCLim%ѓ{2؉qP/z pcʻhC՚\1@r'0c`sfiY3&Ҙ / M<&[Gw> 偿u zl4NXBWjDE%1p iai/=ZʷRl'LJEǏI.AC.-Ґ3.7ew9 !g\C eQсxݭ5")]Dq#yܖ_;9yicb+⟏4 IA7JL ; <^Kb/vgąS';g&kOmv\LVN߄`R#_0o6 kテֵ(9GI1 gsƜssqTL( @ HqO}UW_UյwٵNqz; ;\YWCZ|\Ō~xlrm~ҀY0̹lfq:4w ]) ~n[>ӎ&/e@?mb>*,QG|XnEa5x~Bx~)iu7r(Wކ]XUN|u Zd c1č/(lu1mٍ{T[zEmZNv]GքRMP.ulGTS,xzEߤ_X?eo9! 旚pOx?,kc\tg dpB<s 04Zܝ'c:M֙S̗Ů҆P) pYwʬ[kKn0cV:OR}if'BG1fʜگZEfIHZ -9>:HĔ0= 7.L1BE)Z!A21 6=;a{cPm10"~ħi6D\-rkɰd9 |XiяhFUv(ƷB•YJtz @ط{r6\#񃙌[xKKrc];o1 F…Q1!JcV>x85E/vw_ϴ p2M@ј: AK| ü)9wMpVQK_[cR1B4EǫV`TZ:*cI-uR׃Gr[X;>\IG!-k=TAw.L-#tc}[~30 ״r9`N"\aPNYݓf'cTu?D>`MۖKNѽLȯ4 3~r ?4*Ɣ7SG{,\^撏^,-SM6[I oD$pGŊfUm!?bXĝ@{}ժS|gSZ),c+Mq84x۔n^y8.]zSZeͯZCp'[! T8Vǫ591;v4О<îlVmǩޞ\p.cϑ}m85<,C&Ѳ~jPWIRw<4)߅X N- `%ͯ/Ogmt˕k Db04M̏0ŎߛlŌPNHZ:{+aj3T(W 7MqGn#Ԯ**%ov&ř ڧ6k2s:F#=[ p_xMVqU,3sP ٰKi0|ԫr; A;ܳ #~kѣ)eFOATdZ01UpxW εC(tO?a ?aOL}|TVfCs'vY9+iʕ.u% „.h]U٘>4uPRSzLr6މ 64لɭ-wk9L:Υle򣾢H3 /_shbAn(\bHƘ\V;XS&Byp lM鯯%*xCEkuX38u3u:#ܝv[[wmɞ)qvPK +KDCL{uѡ)u?}¡24I*e(Ra8qC77!#NwiNtjך;C+[ebMx;K,޾Gs!گ*Ƈ2_QLT}xؐϖ>_˚~lͪUAPQ/fiĪ5~4 N%ihPXPAG7C7fc1]l{֑iμ1ƅU]-;+^vZ08_L8aAs' K+~?o&G`9Wem#bu@,Ձʶd  SvJܾ~51,.})p=Wa˖{~ ndΉZ11]rqKcA?Y 2,Q&|`d*nmp锭)ed︩&X#gO6b[!7 c0{;yQ2Y/myFдIzn\`JV`ϥtZLUUołG },W+JiU<,'c&s] c`h-~p׶\c,-mU jֿ@Xx"n8d-g /buQK1|XǡIyX@pn=vlVcj蕍6o`rF,Ɓ@aW+AgJHȉM֎ُ'>'W?u>~^EB/Uf 4y0OU8IvWAmբ 8y+یIѴBZR4Oڏh:~spfC@+/kFKgV,ѵ}wkκ68_Ee8>Ww0]P!Syrp~&y.bߣa;u|\8kFz~AY-<SHZ)X ?[>N![?nODL_o?e/}R``[L+hbW$ Z}ȵ4)arPf:,_aF,GZwa6|aeL˩Z\Q܌N5sZ"uSEg8"bC% Gш8L*?⪥z>٘LXk'iSXnc30 ĠUس4 aN BtcF0\?ǩ.Oky@/"?C>szO v{_I}fQn{NĹ8owAߡA uSktGZ=kQcuܜL*aeSKkfW++qؕ ;m}=Z>Ap Xj#'/kx:|Qőzl=̌8j:ǫ '7o` \bj!Rq( #z;\瑸"x#8t32*?FݱaLinc#jLzf*7*5VISJ[cF+\N71PKC>[e9߭BS-UaTbxccY8bC3.;boZ:PmÍRlWf8m~h;-ʩj,FwטY:%cIR< 8a74l3*<K2^eD(KQ{W9MQqwn̙!(ѿN+Ye_Mv䆟s}Z}֧Ku #yP^/d)&ؑTݥՀJ,BT5ZoxK5: f |9F3<\sLx#[[[LU/kB| g ̘sWjrә; eߤ> 7GZg=tNwk\?/EVbNʼҕ`t UrX bKC[CAóX>[")Li[tgz! 6,Wce^j冼UjtإW y}+F/U)^폙bؐY's0铢~3gZ-5#&iPs%V(1`yǔtQ ZPi"%h">B+vkzxɧ:z??9c )J#7:ʿP!u-y ᧑85GwpXߞIAq|Y!E/N{{GZ:PK1P?M                                            RT`ants-1.9.2+svn680.dfsg/Examples/Data/r16slice.nii000066400000000000000000010005401147325206600212400ustar00rootroot00000000000000\r ????C???n+1AaA ?Q=ke@ȋ>AF͉A:A/AAg+B[TB,3B! BqAAO@ARMBwBtBA2AxxB蘸B5BBBBB OBK A@>g?!< G@Hӳ@@c?~@/AN7)B3@B/BEB+)B/B&cBOʣBƀBtCZ Ck: C C%1CBB0%B&B@[BeBB>1A\N@SyA crBBg=BB_BcA~=X ABBqBB CoBmB)B'ɮB!B% CC.CCJCCCNCN C{C!CjBBBLBG B@Z@pYKBG=BDBeB=B5BBi CȀCCqW CĖCIBBB_JB@! @jBS Cc*CyCC#uCU5CC^BB{C9C]Cq[CCCC@Ca$C'C$CUCngCn CCpBBBcBǢBBqByB"B%8@HA}BݡBCdC`CCBXB8CCI4CF Ck`CmBBňCVBcDtB5B<@BwZ CCtC&!C&C#CC CMxBB_aBB)B\ CCCZCHCBB: CNC*C CkbB{B"B<`C= CG CMB9BP4A<=ABͤB:BbB&CCv!CCI C BkBxBCBC]CBDBaB3 C/CR$C'C@%CT^!C!C"C CCۛCCrC'CCxCBcB8vB ]B1BA@ր@|BEBA CZCB 8BqC&C-%C6#Cơ!CCCCC= CCwC;ClBn CCiCtWCvCC<CoCm Cj ChC~{CzC:Ck? CBzB!|BBFBBBCzB>Bv4BYBmA$CEBC(BP7BОC') CC C3|CCBBCCُCCaCC-OCC& CnC^ CC FB BB-`C CnCL CBCoC]C"Cɍ'C(CY"CCxC-#CƥC{CC C5C C bC8BC{ CݐCCC#CzCڅCC(BB<BB!B/B5Bv"Ck!C CS4&C&#C CqC0BRCy C9CƂ%CS$Cq'CA CCIL C#C#C#C/CCLBFBdUBX-BBBBZB BBZB.BBB]ACC\$CyW#CC?CCCB C\RC C?CCCYCb CCdCkCC_C. Cig C/CbCbBhOB#B&B{BBB%BB=BB Cڃ ClC|BB.BS$B1A&zAJB^B9BBBVBqBkB BuB"5BBBC C>CG"C#CC CCyD!Ck C3C CuC:CC4CC}YCCK&C,Cr C0 Cv! C`CC:CUBM{B%BU1|BSSBsB=BBABRB[ CXCz=C)B+BSaC^( C>CCp#C%C&!%C&CYH&CWC* CBBB9 CWCCGCE$C@$CQ %C&C!"Ce0 C}C50 C B@B C CCC}CCUCCC91CTC<5C{wB'B׶BBPBBĎB,BBbB BDUBBB^Bw B_BrB#BC7 CBqɤB0BC C C;"CuC>C CUX C_CCv#C C  CKBBB:CB CqvCC[C;Cb!CN"C#C!CQC C? CCC2C%RC#C CSCCdC CCqBsB: Bv@@5B,BBCCw C#"#CBCaC~CDCW#C%C$C?C+?C CCrI C C[dB(/B8B)BuBYVB[B7B C C־CBB,2BCt C CА Cg= C&Q CC4 C<C٦&C$C%C^(C"!CP C۔CC5CJ C߯CCCcCBBABʿB'BQwBB=B*8BBBB!^CB.BBy,BB4BHcBpBBBBpB;cBcBQB7BoBB BŸCZCRC#C$C&`"CF"C="CoCjCPCB[(BB|CC' CCbCcC C^C C' C2#C&C?%CɡC2C5CCBYC BBJBXBo>BX @[BռB%CCwa CQCCFCBRB B2C COC7-C`C^C%P"C2$C$C*C} %Cx$CI"CC&CCCChC5CCսCCBBBBBBnBebCC( C4 C' C CACBKB BBV'BVBB,BYBBYBBEsBBBB^B˓C\CmC&!C)!C# "Cx"C6E!Cq C'C# CTCxBBBA.BC CCsC! Cs Cb$C !C7"CCyC>CwBB҄BB}BBRBB6Bi`B7AC)CCC"CT$C%M%C(C$C]Cm-C0BzBnBuB2BrBBXB?nBBxBңB.̔B[B8A-A?}@ԾB BȧBDR CCC`_CC7 C3CRC CCÕCC]CWC C#C CZb#C&C#CC$Ca6%CC< C%C~CCYC CC9C1CaCg? C C?eC C@ CZC C-C*C}C; C("BݳB';BRBDZC Cw C1 C'eC CCBCQCrC4C^C6C]CZC"C#'C&C&CW$C #Cw#Cm7 CnCLC CC CY C*.CCB*B*B*B-B38B MA?BhBŔBBm>B\BB] CCab"C#$C KCCBCُCICx!C C1[CūC C"C*C|C_5 CT2#CJ$C C1C=C CX C]` Ck C>CC_CRC#CC# CC96C CFLBBdBCCBC CBKBNBn%C}(C gC CIcC4 C C[C?C C-BB>B6 CcCC/C!$C*C~)Co(C'CQ'C%C#C3%C CbJC CtC C`C|CL C'C='C#CV#CCBaaBBBc0C$iCtBPBxB5CyBXBRB0BSB,;BB:BgA{@5B͂BjιBBBBBCCߺ'C+C5&C#'C>#CƐC#C#Cg$C9CSC C*"C#CC "C?+C&CCC]CqCBuyBBC3CRC:C6!CCRCfCpCCBBBBvC C CvBKWBB]CH C C}CC C( C# CvCQPCR#BdBf(BX C&C1C!C-i)C%(Ct$C:&C=$Cؽ%C%C#Cr3'CK&C@C14CC@C~ C]n%C~ICW%Co%Ch$C>CU C[BBYTBQ CC3CBv#B BBCB^CGCSC CkBBBqO@4BףBBBBBBe/BC5CIe'C-C$C&C#CS CD`$C߰$C'COV'C'&C$C&C(Cu"C_&C*CCCTCCe CACBBBiCI CC CCMCC C_ CdC BIB=B+BC&CB9BBC^ C C1C'HCcCOCGgCCCoB}BuB# C;CC %C)CH'CТ$C$CjC!C'&C&Cl&C,C?#CCC?CH!C1&CIO%C &C$CD$CC CDBJuCC8{C' CLC 1BZBBbqBĢBBR!C C # CCj CKYBlB!}A@&oBB1bBjB$Bg"B^BB C<C<#C*C$Ci'C;&CN&CZ$Cmj(C S(CW)C(C%C?&C7'CY(CVK'C!CC6CpCRFCZCCBpBHEB BhC C C"Cs>CCCjCSC CC~BOPB8B:YB66B7BBl CCp CCC3CBϙBa8B-gBBkBPBC&pCfC#C$C7&C'C"CC=!C&Cم'C<%C-0+C;%C"C"/$Cm&C !C9$C'C7+C+*C&Cr"ChCC C CC#gCC.BFB&B(B/B{C~Cq CsC4( CUCC$BYBi@Ւ@{RBBBR$BBBJBBCCCC}J"CQ'Cu&C%C-)CK!C6)C +C*@&C C@#CҐ%Cҫ'Cx*C'C6C?LC/C{CTtCLC"CBBz_B BxC":CDgCCCdrC=CqKCFC CKCjC$cCyBB B#@@}XBCdyC˃ CCCBC3,BB̤BzB aBB4~ CY:CC :$Cuo%C#C"C#C,T"C Cp$C/%CO$C)C-C"Chs&Cy*C(C&CԒ#CB+%CV8*Cn)Cg2%C!C2C9$ CXIC1MC CCCbB:BIXBBWB6C CCeCoCpCԦCQ$BBQBsBBMBCCC"C8C CHCNC6!CD&CC5Ch~*CN(C $C'Cop CL"C'Cܴ%C!C &C?$C4(CA7+C%C CwC LC/CmCCCB#NB.BB(BB^BBvC¹CCCsC CpCFC CJChBEBːArAB6 C6o CC^CGCǻBBWBB B(CW^CsCI%CO%C3!C#Cs!$C֋$CB#C!%Ch#C!Cb#C#8+C2/Ch$Cw'C*C;$C)Cd%C'6C'C-%CE"CBC|CO6CCCC)Cr CBB,BAB8Bg CAm C}z C`CCICiC,BU$Bp jBI@^@4kB8C5l CCCQCxC>CCXbC!C^)C@ CC)C&CPM(CJ#CƔ"C#Cq'C^ (C %C"CyC9&C q'CjUCCC1CCh CxzC BBSUBCBB3B]BB1BB=BBUBC{P C+CMC2C(CBBAɳA²By-BDCBBBUBxB* BrCC^CȯCC&C!C 2CCp!C,&Cg2&Cq*CE%CWtC!C#8#C/&C%C%%C$)C#CD\(C[&C_C^&C$Ch!C$Ct C$t!C}"C>L!CiCC CB,zBBaC8PCRCqCo|CiCSC@C C'C BTBs_BAZBztC0CCC*CCǢC CmCfCn"C."C&Ci&C"CV-CIW(C)C *C*C"C !CC;_&CL)CY$CCƚCCC7CCzBBBPCCCޒBByBnB:BT~B޷BB CЋ C C C C"vC B$.Be8 ADBBBBB^EBzB'BNB*CC3C CUCwC)fCC!C'C0CSC %CRi'C!Ca-#C"!Cr Cy$C$CN'C^&CG)Clu*C$ C"C.$COC)CB'CjN#C'%C!C CdCLVCr*C2C1CC^CCCǿCeGC֒CCtCC BYBwB?dB$B&Cf C}t C CI Cq C C\gCC CCM CP8C#?#CH&C?&Cf)C%C%)CY`*C+C`&Ca'C&C(Cq'C9C{CۏC#CCCC hBmCCCy"C9C7NCBBB,B0BgBhC Cf C CCCRB BBB[B?AfBHBBF.BBXBCB|,BB#CC4CXC C%GCEIC;gBBCMCCC'C$Cp%C%C;#CI'CI$C"CV)C?+C>+C2#C_Cm#CPCօ'CNo'Cc"Co%CsCCCSC~C{C C{CBClCC C, Cf%C'CVC CLBB$˔B*<AA+BBBBBQ~BjB3GBh!Cw'C8&C'C%C6$CZ)C:%Cu CO!)C)Cc&Ck#C?#C "Cf!C$C,$C!C{!#CCCrCCW C CCj>ClCi C#CCk~"Cܐ(C6HC1CCb}BV)BBA7Bq BBW\Ba BBB*B3rBB$B$BBBBLBCACe(C)CA(C#C:CN'C)'C:"CJ+C; )CO CC|CCC@CC* C9aC}C|C Cً Cm C= C$CGBBB28B^CC C Cm CdBnB&BB޶ByBV ?)B^BY#BdBBB2B:BWPB4BSBBBB%B$BwB/BBdYC`CcC8$C%C%Cj$C8&C'Cs#%C/$C5"C`O%C'C$C;#C Cj#CL&Cl#Ck Cm?C["C"C C}CCC-CCnC:%!C %CG"CC C͑C CCUHC:aBBBAAu3BpBJB"BBjB*BB,B'B BSB+B1B|BB=B BeCfNC *C"}(C#C8^"Ct,CNN$C&%C)N,CN#C,C_-Cz~CC1CCrCCCRCp C 2C Cg CB B?B=BB COC CsB;FB"`BhB[B&Bf{Bm7@/c@5B?BLBGBC#BCfC|BΨB B@B:B+BC1"CCC-CCi CC[)Cl$C%C(C+C0C'CCZHCjCkC*CC"Ch"CMCCBmBjB]BBZBBBB BBMuBBBBkzCWB|BB AHQAϦBeBBvCCnCC"CKBJBBYBHCpCC C CK$C CG} C(CJ%C'C%CZiC1CC4CC Cf$C 'C *C"(C"Cf"Cn"C&C"CU!C#CX&CJ<"Cx|CdC8]CCLBBE+BE1ByB$B/B) B6BVBEBWB7BafBqA_BcCŨCiC5C^ CCB;BBBCVC3CC_;#CHCC DCCWC#Cw)CQ$CN(C#C:=&CV,C#Cr Cc!C!C8t!C$C5$CCC CoB,BBBzBvBB#BB}!BBFBBB@B*B^VCCtBBl`NB&ARl ABOBBrC>tCByCfC CBK4BWBoCwC]!C%C@)C3%C_!C"C(C]V"Cyi#C1%C0CBB>BBC/G C8l$CX)C(Cm#C#C̙!CC#C#Cf&Cv $CoCqC= C;LCCBBlBkBiB)BfB>BmBBBZB9BCBtB_xBBCC CMC%CN CG BBwBޑBGB1CĎCCUDCsCCw!C" C C%o#C$C"C&C#C #C7(CU"CgCJ!C"CSa$C9'C0s$Cn C CC"BLBBKLB4BBBpB#3B'BBABB~BCyC2BBBcB~Ca!C!%C`+CF'CL"CH$C͏C@CՖ"CY&C%C{`CCcJCC^B/BB~0BLkBlBBrB BBSBB BLZBBB"B"nmA)>>B@źBcBB6C;CMCCCoBBwBH5B[BmB2C…C0C/= C"C#C C#Cfq#C"C(&C$C&C_'CP!C` CECC C C>#C#C'I!CAC0BVB&BF0BkyBǼBB7BB~&B0BB7BoBP CSCrB(BFB0@Ax}AB=BLBƤCC}CC> CC(C(C,#CU'C-)Cm&C(C(C$C&C8&CMCVB BrZNB`>B@SBeĘBYBXC)$C(C'C&&CS%CE,#CA$C3$C"$C+CCUB˭BB BBoBJB'B.BBB]B/JBB/BBBBƒBgBAwAtrBBB@B'C7CC_qC C) C{CBPLB B;PBB;C CDC!C C!C$C{\#C0A&Cq(Cmk$C)CM&CCڵCkCC=C $C&$C^"CCH=C'CBrBQBBC!C(B!{BaEB!@[@)ABnB+CC׼$C&C[CpCCg#CZ&C%CA'C4i%Ci%CE&C3%C'C CBB:XBH3B?B8B;B1LB;7BCf$CH)CD,C7*C!&C5m#Cfr$Cb"C=CC~B6BድBRJBGB؍dBpBkBBsBJBx;BgJBzBiB$BBBjB@BB B AV+9B妻BTBB)CEt CTCC fCsCCuCECuBB BC: C7C7nC!C%"Cմ#C#CR<"C#$CL\&C/'CA6-C&CC\UCOC9RCZC;#C|CCCtCaCC}B$B8B|BaBB:B^_BK9BCM CCSC]3BJ~BﻸB2BשAcB%C8CCk"C~(C((C&C"C$C%Cp%C%&C%C(C#(C$C)CB jJBor BYM5BrMB"BB1B\BBBoBv`BaBTAABBC*C CCC C=!C5 C"C<}CCi1C CX CJ%C|CC*!Cw!CB#CK$CU#C.!C C:%Cb *C.CYM(CP"Cw) ChCjBbSBSCG"C)CRC$CC CtCkC BB-B.B=BͱBQC-CCC CBBB㍹AՂ=OJB6B>CCA CZCbCi!Ct"C)s Cg"Cm&C@;'C%Cܞ$C(C.+C٤CB-aBE#B(BNBB8FBi9B?Bc{BB22CP8*CU(CR*Cz)C/'C%C`"C"CCHvC-B BMBBI޵BBӅBd)BCBeBByB<,BrBB=mBBB BBhBBBB^AGBFBBC!-CSCCVCcCgCrCCCUCC;C CC*CKCBC_!C"C$C&C3%Cj#C T$Cy'C,Cn'CH"CCDeBՙB BB&C)#C5$C>&C#C0!CsTCCyCQClBiBByUBK CCQCOC;CvB=BuBq&@RAHnA=mB!BL%BBFCc CCCtC(!C%C)J&C7z$C4$C7$C{%CmCiB"sB H=B{JBYsPBPB4KB%UBB'?BLqBB C(C)Cao*CV(CB(C(C$C#C 1CCRCxBVBB_BŜBvgB8)BѼBg*B!BB(B%BCBBcCQ%C{BBJB4BEBfw@[_ABqBK`BeC8C) C%CjC>5Cy%CC:CJoC#eCCu Cν CC^CZ]CC(C.1!Chm%C'CK(C'Cd(C)C@,C_%CCz@BB6fBocBdxBCF&C)CC&C!C•!CK+#CCdC/C-CBauB>LCACCnwCF CvJCs>BBUtBEVAa BSBCAAT B@OA@BB.B BC4C C"CO%C#CB0 C]a!C"C%CtCBzBXB˜LBuYB-hB^TBI>B?=BC>FBvBBC (CW7*C>-Cj,CJ+Cj(C9%C(#C C֑CCeBB 8BBB&BBB_BBzB=4BCBtBtBC CsCBBD)BZBmB•XABjBoBL4BDdB B:BB&CB\BBBB B}BWC9CPCpBC CCC!CO$CJ|'Cb'C-j(C,C^*Cz"CCjBܴnBN=B LB[BjBB CX!CU&C#C 6!Cs"C "%CR]$CY!CCECpCcCC_WC CkBBkBHAXAגBC+B~B[B/>p?B(BBXBBBɫBBC|BBVB*B]WB?BBKBtB B>BIBXBB>BCPC+C.C"C&C(C~4+Cd)C!CCMB/cBQB?PBaB[`B`rBٵBCL C #CrJ!CT %CJ&Cu#C*!C1CTCԉCyC-C C4CBhBX7BgqA뀓BBBOBB*BTBhBBhBi5BGC=&C C Ce&CU)CW'C2%C%C~&CX}'C"CCjB7B߈BևyBkBnbBcBdBօUBjSB:x(B-B0EBC'CA-CY,Cs.C ,CF&C5"C0$C3&C?%C.'C&C CzOCMCSCRCvCת CB^ CT C C CCCwCC:C,Cd&C CRC?BCUB)AۘB{BDC+CP"C> C Cl CxC[CCC CpXCAC Cc C,BBWABBBC7CC9CCv$C~O%C~&C-C+C!CVC~B^mBABu-sByB5tBwlB}%BzB#B`Cz#C"4$CQ.#CH#CKCk$C4:CKCC CNC#BBBƍ$BJ2B8BDB-BHKB2qBDBB͌B CCՠCY!CQG'CnD#CB&CϹ)C)&CC&C1$(Ce#)C'Cz%CGC+/BzBElB{B[)}B/ jB%lBqvB5-zBuCwBEqBHVB[bBBjC&*CF.C8-Ch-C\*CN#CC#C(C%C$C%C˛'C $Cj2CRC! C "Cm CLCCuCCw%CCCbCG>CC$Ck CvCBKCBYB]AB CpCA C7 CC|CgC C*CC4CCCCCxC0Ch C C C CC$CC@CC(l%C'C'C"-C<+Ca'C CEBiB$ZB {BB|B_rB\zBB+B;WBݝCCl C"C~CCeCGC9C CY|C<CQBB&nBKBAYB~dBtBBB B,JCC \'C+Cޔ&C[h&C&C`$CjP&CC)CuK'C!&Cp&Cd(Co'C<CB%[jB/WB}B0BVtBAUBrNBN_B_pBBO7B_BZ(BBCu(CY+C+C+CΏ)Cm"CCg"C4'C>'CEw$C%CW)Cp<&C.$C&C,&Cߖ)C<&Cۖ"Cs"C)"CF%C]G"CgCݮCmCCC`C:CCGCilCjVBBIABvxBN$B C CTCcCCCCCӎCC8CCb!Ct$C!#C"C CC CC!C%Cg&Cb%CY#CrCGCe$Co+Cw-CM(C؉%C:yC5EBroB|BwB߀B8B[zBoBuBBXBYBOC"CɘCCUCiCCR}CNCIHCC$ C* CCJ CC>bCCC CXCCx!CO&CP(C$Ci "CT$CC%C$Cr%C&C"Y$C C$C 6 C#LBBeFBooBvBLnBitZBPBTBWB]B^BNB0(JBŻB,CZ'CQ)C+C)^*C2)C(C#C6 C~"CZ&C<''C$C'CN)C%CE&C׎(C&C&C#C}C[!C&"CY%CV!C:C'CrCC׃CCSCC8 C%CB\@B B BwC CC CdC^XCFCCaVCCdCCUCUCW#CJw%C(;&Cgo$COu$C~)C-(C>+C}+CyH%CR#C5M&Ct#C"C$C'C?)C'CR#C CCMͣBQ}B́BvBFzBjB\`BbB$mBlBBZ~BC CCCC|!CACpCaC(C@CjC&CCCݩC<Cn$C"C#C/$C$C$C%C6#C C0r"CN?$C#Ch!CF#C#CCaCB)BEB9sBIB5BĀBUZBbbBmBAYBHBuEB=BsZBf.B Cc,C.Cd.C*C(C~$Cf"C#C{%Cm&C 'CU&CH&C%C_%C}%C. 'C[$C"C C 6CCC CJgCkC|CCCu'CC CCCD C#C7B*ZB@0BCe CsCCCC # CĶ C C] C|C C CScC:C?CRQC|COlC %C(C=+CM)CU&C~&C[&C$C?%C(CH'C(C(C a%C1%CC}BqBmB{BoBh}BΣnB©iB#mB}c`B0,hB=BBnC!}"CK$C$CMz$C#CCzCCXCZ C CC/C2CCL$ Cu"C5*"C#C`$C%Cd$C"C"Cb$CK#C$C#C#CǼ"C+CBۊBc8BagB%B{yBaB)KBzFB XBQB0Bj+Bޚ9B2;BߴvBEBc#C*CF.C /CN*C%Cs#Cӳ"CSR&C)Cs(C'C%'CDn$CZ C#C Cu Cw!C$!Cn C CVRCrC?4CC<7CC CCCCmCyC=C\C CB-B3@%BBCX CC^Cc Ch,CNB3BsBcBBB7%CCXCCv CSC4C]" Cj)C*C(C''C&C(0'CM)CN+C /)C?J%C L(Cz(Cx&C%CCpB-B"~BxBlB|B/B B*zBշcBrBZBCێCf%CrV$C&"C1$C$C̲!CF C EC C7!CVCC92CCr!C*!Cy#!Cy"C#C$C-$C#C"C#C_#Cz$C>&C<#C Cv\B(rB8BY\B@?B5BP"JB5B'2B0B3B4B7$B )BIKBGB+B~3B(B,1B!xlBSB#BC# CF(Cפ*CM)C^&Ci'Ci&C\[$C_%Cd&C#C!CpWCCFCTCxCECH"C@CmCe!C C$CdCC}#C1CCC$CIC"CJaCCyC D CBBA_:B^BskCCOCd)CvCrBFBߙBu2B&BB]B+B|BmB}GBJBeBCN CCIC4&C.C-C'Cǣ&C&Ca'CQW(C^a*Cv+*C)C|'CCG#BBBbtBsBoBBڗBB*diBԂB'BnBfBCKC Ce"C%C=%C(q"CC!= Ca!Cw8 CzC$C!!C`[C!CG"Cj"C#C$CZ$C&CQ`$C!C!C [CCQ-C ClPBDMB8BRBc[oBBB,B ]BBŠ_B/:B/>B p>B[lBеB|KBC]C##C(C2 ,C'C#C#C#C$#C$C%C6!CC(XCZCC6C{C C^CC7CC`ClA$Ct C 1!CP6#C!C`CCmCŐCQCBCa Cz CS CwBoB[)KBlX@}BBhBeC CyCCm CkB^BuB\BCnBBB7BzBrBjBdB-]BJBHCCjC#C~(C 'Ce%"Cp#CGv#C"C1y%C'Cvc&Cc(CN&CH!CCBOBhBsBpBWWBGTB{7BVÃBqBUB?BqC*C>C;%Cq&CT&C$$C!C!Ck"C#C\ CC!C #CT C#CV#C0$C*"C!C"C5#C#C޺"C!CCCjC FBRbByEB&DBVB BBQBB'BףBǞBdB B3oB"BʹB CtCGD C[&Cpm'Cŕ)C|&C(!C/ C6#CJl#C UCZCJXCCi C C^ClCm CC.CC<C<C1 C!Cw Cr C^#C#C-!CCCGC(C@C C CClC(lBEBXl@AB |B*C] C CCsC$CB}CXB;(BkBYBBCC"B>BBXCC= C!6Cw!CV$C\&CF$C#C%$CA"Ck#C%Cou%C%C!Cw"C+C۳BABdBukB.BwҟBrBBBSB)C! CKC C&Cc(C''C%Ct,"CJw!CD"Cv#Cr?'C\$CC"C$CE#C" "C^#Cm%Cu#C4%C/C%C#C<#Cg C; CC,|CBB[BhBDC C sCzCBBB˧B;gCUrCc C\Y CCCx:C;C=&C$CL%C%'C&'C%Cw!C;$C#CdCC@C CBtBBBCԤ C@CGDCaC[CC$CCc`CYC&CAt C~(!Ca CTTCCMCCC{ C>CbC#ZBPBhA/B=_BEjCCbC#9 Cn CCiCCC(C)~CBB9CC\B BiB%C'C<C= CCZCCpU!C~$C=#C &C&C$C$Cj%Cm"CCr Cƹ#CZ C2BBzBטBAB BBVBXB|CCCfCC"C8#C*!C!!C#Co%Cm'C*C'C3$CO )C)C&Cԅ$Cf%Cf"C#C2'C'C;'Cb"CрCiCaEBhB&NB}# C.CkCLC C2^C<-CiC CZICCC!C.$C\CS[CAJCDC#Cp%C!C(#CT&CKG$C"Cu;CL #Cz$C`C5C CB5 B6B BBgB CC CrCCCC;CCCCR C1C" CN"CW^CR{C"YCs CA\CP CiBWBAtA.B1BBCCOCCCQCeC&CC CoCCӠBzC_C):CCCC̨CCCC1C#CF&CR!'C$C%C=&C!%CPQ!CC2VCC(BBWBrB BxBB_BC8 CK9 CCBPBmCxCK CR CCuC!CI&C&C(%C)C<(CG"C$C$CӍCCLCCC9BBBBnCbCXUCCݜCݴCCCYj CCiCCCCCxCȅCC'C&C:&C"$Cw."C&CE'Co#C+!CRnCvCO C NC&C C>C!BBPB%B=BQ6B)BBoǑByB/AԭAzB5~Ba:B88A 0B̦B`BBCOCCJVC6CsCC0C- CCCY)CK0C<CDQC!C)!CsC#M!C 'Cc'Ccr&Cڥ%C#CE$C#C"C&"C}CC"C7CjCCOCCYBVBO9BBB2B B%BտBʇB? BB;BB*BlCCw ChC-CE Cg CDCtCBA"A3kB0B*Bq+BĔBͦBӉBBBBB4IBbB$BiBB]LBBB BBBzcB&B\BB,C/C|#C&C(C>$Ch(CQC'C@#C&C-(C<(C C3 C[BSUCg CCCo C C# C4 C C C CC CܭCCCt:CBʛBkB#B"0B`^HAZUHB$BXB-@=NB]B\BJBBB%B&[B0Bj%BCtBrCCMqCRCCC CŭCC̴CCCCJCCW!C #Cu(C*C.%C !CCC CqCCCC"CC,C(CLj C݅CnCiC*BJJBABlA(IB-BшC CCTCCZCB C|Cǣ CCCECCC)#CjCCqCCCMC9_ Cӹ"C<%Cp%C}"C4"C$C"C$C&CS Cά"C#C}#C'C)C5H&CīCgC'CCPC·C CBDCCqC CCqC_% C CECCC,B˴BsB| B_ӰBBy@?)A*BxB8BB$OB֐BQCuCXCrCz C4C9C%CC%C-CCCTCF%C(Cv(Cn)Cw3"CiCm CdsCC_yBBBBM[C CCjCVCSCZCC_)C C,CWCprCH~CYCBBBBmB-BHBٳBAB"BBrBBz-B-BB?gBaDAEAB7B`C\, CC.CCfCC ChCCğCho%C$C&CQw&C#CI!C&Cz'C#C0!Cv!C$C $Ch$C/#C6#C;#C(C6%CfN%CL%C "CL#C $C)$C~ C"C)C%CL#C!CQrCl7CCCxCTCCmeCxCb C! CQ C^CnCCBBHBCBB&tBEhA >]eABBB"B)B;]C,Cx"CCrC`/ Cr CCyCo;CCSWCCCeCR"C$C #C0Y(C/"C4"C!C^C{CEB oBIB@BBCC^s CCqC CC_CCCu CCCCCBB[B]B.BِB),B_BBwwBBUXBB1B͜B܅A牂AB B'C) CQCC\, CSC\C!C$CH%C[*/C-C.&CI%C&$CUI"C"C<; CDCGCCpCcCb!C +"C!CCO$C#C4%C %CO$C#C:t#C'C!C%#C_(C!C"C "CyCCRCCC+C@C/8CC( C C|h CCi3CCrB/BlBSBTkB4BϬAaT>uABtBrB>B$BC>CeCCC-CO C$CDC}CCY[C2#C CCWN$Cop%CC,U%CSB#CCCS!Cµ#CqCBBNBaB BuBB CjaCW C-CC_[CXC#dCC'CS/C̷ C^% CCUC8CPBCBޯBnB)^BtBL׏BTByBBGBwBBaA]BִBFCNJ CCZC\{$C&C%C&C1*C)C)Cg*C _&CwrCYCCMCÓC CBC CvC<CC Cv#C*#C!CCCk5$Cx!C~!CC{C CoCWQCa C&\CC CNC!C8$CC CCCVCOb C1C6 CC&C7C CrwBrBXBBBBHBA ?E@cAwB.BCBJCWCCvCִCCCb C>qC$C1C"CLCbCC4&C4=CCC C KC{k"CNCCCBlC:CMuCBBlBUBpB WBV"B7_B~C|C{CaXC-CCC/CUC oCM C CC#CLB@BB B=BxVBB/B.ȜBmB *jB pAQCAB6BB C-CC#C3*CR+C+)C!)C}%CtCCC(C C. CUC~B[BnBB C>,CCMT#Ci%CG&C*]%CAC#C4CR|C!CCC5"C!!CXrCC.CQ!Cʺ!C~Cx"C_C0eC0qC4.CCC! C/ECUC C#CClC`BBC:BBi&BN%B3B߸AsA.̘B(BjCMB!C7C#CC57C<_ C C2XC'kCRC>kC4CCgCYCdCgkC| CCICW"C CC1CsCCC1S C+BFBzB˵BBB BʌB*C';C CC&JCP C^ C C C. C%CCCCC BBNByBBaBBrBT[B;BA,%A!B(BB? C.C&C("C)C)C/<%CCi|C8Cr>CU Cy&ComB\B BBBwBaBPCC]CS{ C($C%C C"C$CJCtC lC3dCdC"C#CC CDm%C!C!C!C~CCC'ClCCC MCS C|CF CC]CC=CCnB:BBBBBK)Aҟ?̙BknBBCBc\CmCyC CC CXCXCpCFC_CCWCCCFC*CCCCCC C} CCLCyCYCzUCB@BB=ءB0BB eB BBY~C CO CCCCCiCyCCC/CǠC"dCB4BBتB*BBCBcjBBu?BE @@!BUBBcVCqCC!C6%C!C,^CACa CkJCrCtjB BB8CB~BnBmCH C C؀C]CaC!CK%CCC.C< CzCICG C" C4C<"Cf2!CyCCCNC!C!CCFCCCCDCC"TCHCX CWC CCECz CBjBEBBBpBr2BiFAwAwBOBrC3|CBCzC C'CCiCQCC@LCsFC|CC8HCJCCDCsqCC%&CvCCRo#CVCa CRCOCUC̛C4 CBwBYBBcBVyB<=BNBBBjB-C:CxCBw$BB oBUBBBBBBSBB'BBBBBc B xB!BF%Bma@B2B@B8)CCcC L!CĦCCGC-rCs(B0BpB…BBBBJ1BCÊ CCCXC$C3!$C!C#CJC#C C,BB[B[BKVC,C6C"CC-CC2C!CaCCkC)CB(C"C'C)yCC5CCH C CC CnM CKC CCzB~^BBBnB(BPEBB*B޻C CBBdC#C0 C; C1 C, C#NCCCC8C.CC>CCCyCL"CBCCC. CC CŗClCoRC CO CBTBBB8B@BRgB׈B6BuiBBCZB-Bh_BBBB@BB@BBxBёBBHByB]BBBUB B6B@B]Bs C CYCCzCdZCɰCBJBBBdBBd CrC<C CCC_!CO!Cݤ#C+"CCCbCƳCCBBB?BCaCCx` C`CC`C CCCBC CbCtYCCiCsC@CCC C;CzCE COCCB_mC|B8CBi=B)BZnBB%BBC#BCCTCpyCCCCA{CCPCl>CC0CC/C;CCCSC}kCCQCBB@/BٶBB@BtBv@BBB>C ChCC CkJCjB>BCBBvC CB Cp C} CNCrCCh#C C)CdCChtC\VC(0 C#CB_BBB*RBEBCCC<C!COHC'Cm!CC C)"CTjCC6,CCF CCuCCFClCWC C C CC@CCCWCVB#BBzBBqBɆBxCCCdCgCc CC|CC\ C CKCCTC wCCC]CC߆C_CzC C fCC CQ CCC$ACMxC8 CJC C:C}CCB5qBZBB.BB*B~BBBhBBIBBBB*BB-BRBBY0B BBuuB\B;A?FB_B) C4 C2YCu? C(oCbB5,BۅBB!B(CC CDCC CݷC\Cc&C"CPCC.)CqvC CCB9BBBxQBZBB2CTCCCԅC7CCHb+C#CJlCCW|C[CCC[C,oCCKCCCCCFC CB C C{CsC ;CC-XB+BcBBFBJBZC@CCqr Cu Ct C CØ CC CS CCPCCH<C1CpCoCCCx"CJ0CmCz|C̪CClCCC@C C. CCC C$/ CZCBBQBAeBBzBeBTB'BBB˶B!B&BBNB_B}BiBBƬB}BSB8×BBUޝBsAtIBtB'BCoCB?rBBխBgB*LB JC(,CZCz3C٠CCa%C C"C *CH!CnCQC CWCBBbB`xxBB~(BVBByBG CUCC ChC1CC=-Cn!CCaCxiCC{CCtCcCfCuCC<CvC(C!C C; CCz, Cmy C%CCCBB2BC:CԏCRCClC C C<CbCnC=C( CCCC[CC[VCbC"C|CCi!CjmCi%!CJC-CrA Cx CCtC?C+ C CdCgCkT CCBBB[BxBWoBBEBhBBPB3BEB$vB8BKBB3BIBaBࡰBBBB|BӱB~tBbޥA)A\2 BB&BΛB3)BB=BQLBBvBBlC=CCCCmg"C#Cw$CE!CMCHC CCǞBB;jB/BBjUB$!BB(BC; CebCVC: CC_CkUCn)CC#CCՕCCCC=/CBCCC CCݛC{CEOC| CyC&C C CCKCCBBpBXCC CC%j C!HC6 C CRG C:C=CsC>VC CCCpCC%CHCgCʠC GCY)#C@#CGC C<CCʺCC CC~ CCC$C BiBEYB,BvB~sBnBBBZBDBƇB";{BtBAB/BB B B2 BuB BBB)BB}LB9!B`A L@>bA,BaA?GAśBB*B CB CKCrCCC#C$CKC_CCb CCBMBicBCBùB BtB BB"BrCC!CCJC CKCTClC&C{$CCC)TCwCDCUCCCC CQ COCfC!CaC) CuCð C C9CT CwC CkCzEB2B}C/C C-C  CqC C CvCC CCCiC C\CCgCqCCJC7CE"C<C,"C: CC<CCXCg C!C|C}/C CCTC"BBBByB *BB$BBvrBk{B#nBIԐB)BBBCB8{B&iBiBBh´B4BBfBB;BLB!B@o<?2@.&ABtBX;BHCOCc C\ CECXrCCGCi"CCC C11BRBB۠BpBڐBoBBBBL.BSB C*DC Cv CC*CGC'C-C)Cv'C%CwCCC)hCTCPCCC)C7CכC Cq Co C=CCυ CjC CCU C{C_CSCqBi3BCA C CTCECCc C`eCC| C8 CyCVCCCCC)!C !CCC!C0 C\!CDCC8CCC CCTCC2Y CmC:C%BB֌BBB%6BjBeB׽B B]BB?B7BPBtBBzBwBBBB BB%BBƠBDFBwAE>j?2U*B\BBvuCCV CX CdCGqC5COCۣC+C$CCB#_BTBvBVB*:BBBsABBs8BCo CDCACC@CN"CC|C CYCC/#CJcC7 CqC%CC CY[CdCCCCC`CbCPC'C*C[CR CuXC_ CQaCC}CBŽBeC C# CP C=CCFCgCMCg CC3C^CuC2CCqC"C~!C_C=!C!C#CCCC<@Ct+C=MC5{CֳCTC CJCٚBKBB%GBDLBLB4B"BBqRB% BNB"8B>TBBB0eB+BYBzTBBBB@BByBB.BSBrBCCCCi@CDCXC\'CCyxC$CvCvCCyC-CWC>Cm C| CJCEC+CӺC"CrClCuK C0"CbcC}GBʛBBBjC%+CU ChCACCP CCYN CC C!y C}CCDC2#C 6#CLCC0C+9&CYCZ_ Ce CNCMCCCrFCm]ClCD CNBBB6B'RBBBhBBBBgCBWBB[C}B_CCzBB3fB2BnfB^BB>BByBoB.BBaAQ@DABBBB B(BCiCECCݨ CR CJ C2CCwCb C CCBBkC CCxCC?CibCtCcCWC&7"C=C C#CCY $C_ CCzCaCCYC C C%C<C"CRCCrCpC[ C|C@TBc B96BB}C'+ C CCpCAACR Cև C3CIC'iCBC1CCyCW$Cx#C C,C)MCC C C CCVvCCѧCCYCCt CJCBBDBmaBBBBBW5BBDBC C1B3CC[CCsBFBfBwBYBBBByyBBBuBQBoLBoA @cpB!BQB2BfBBYBBzBW&BsCC +C*BO6BBKBBBRBhBBBB9BCCC>B}B/ZBBBQ C@CoC #CgCCdCyC# C<C!C!CC"C)9'C$C@C,"CYC\CC C D CC^CC}WC=Cd[CC C CC\BBBC*9 C CCCCaC) C}RCʯCCUCCCq CVJC8r&Cx*C$C"C C2C. CH C1S CmhCMCCCCCCT C CuBunBB BgBBBWBuBmB:Cn CCF C CyCCEBBHBQBpB*B,gBDBcBBOvBLBfB(A#+ABBoB"B BBj;BE[BOBGBUBBBBpB]'BXNB"BfBOBuBQ#C CCN C CeCCCCCC!CNCCfv C CC:C?BBmB*BBBWBC CC= CIt CC C[CBxBeB BBuB3BB B[kBJB(uBNtAB'ALJBBL1BBB4KB5WBTBABBBBBcC CC CtCACICa CGBhBUB.kBBBlB%BٔBt BUBA\BIBCJCCBMBV3ByBrBBBBBMBBB#B$BB C}C CICCYsCJCC.CJCC#C6rCTC"ChCdC_!CC+CCYCCbCd~C hCBCq;CS!C%C(C C C; Bg?BCzB=iC* CC1CCC C]ChCwCȷCC CChjCuC'Cq#CG2CLCHCNS C&CC`CC CCLC`ChIC]C- ChC BFBiBCBlBUB ޶B^ByB. CÛ C1 CC9"C8C_CNCjBBMB`BNBuBBD B`B3FBSA BjB>B~ CwC%ACzC}CABB B7B!BvBgCCCD`C\CBaBB?BdBBOBBBæBB".BrBLBCCNC[C^C݂ CCCG CC C/C> Cp#C"C%v!C#C)$CZ#CYCTCYC5CCCC C( CC* Cz*CB CC:BCCBmBCЬ CCCfCPDCCH-CCCCC~CuC#C+CKCpC Cv CC,Cs:CC CCECVC CuC%C;VBBdBsBREB'BGB TBeޥB!B]BCi CC1CCvC#Ce C4CCBBBbBBdBT;`B#ABmBBؗ C< C[CCCC^BBBUBC{CECpCC)B^B6ʦB)ZBxBQBnBBmBBB/BqWBXCYCjCLCϐC9Ct[C C@CnCŧ C C CnCGCG,Cc#CC!C&C]&C$CZ#CCCCK@CCCn Cۯ CaCCfC/C*CrEBiB&C CkCξB BOBCvC=CCC]CACCCS#C}$C޸!C.#CD!CUC C>9C"I CE CS COU CZ C&7CC9CCrCCpCZeB_BfBBBfB~JBF5B!BFBnBEBDCC`C1CoCgCC CCjHCmB\_B|SBBI =BAUAaBB CK+CC Ck C(C9XBBPCݚCCA CgC>CBBBBpB&C4BBYBBByBBfBsB CC7CC C}CCh CQCC&2C,CCgCC*C_%CuCf"C#C#C9%Cq$CCLC C/CCC!C"eC:aC:}C CʵBٰB]Bm#C\Cn2 C{B^BBnpBkCECkCVCГC~ C!CCC$C #ChC3!C\CyC CrC͐ Cj C\ CCvC CC%C CCB$BBQBھBBFBjBEBPhB-B$CyC<0CCCpCCBCCBC7CigCOBB{BwզB#BAo/BB C~$C! CmC-CzCGCCܧ C CCPCCmBB.B)qBdBJB CCCCC!C )"CBC^&CT$C Cs?CjC0C CC0 C! CcM CĭC2uCRCCa8CCiCBoBBBBϷBBrBBBFCv CRvCl CCCHC CI CC{[C-CM CsC_BBB΅BP=A7 AǀKBKBhCG C' CsC6Cu C CLCC CCB)B9ByB*B_BuC C5CeOC3B˾B!BBbDBBC6gCDC]hCN C|d C@C~C ClCCk CCv CZ C$Cz CCU"C C}UC&C*CjC CD#C CyCQCJC-:CJC[BB 8BB5DB&CʯCCBzB1B{XBŠBB*B[eCC\`Cg$Cw$C$$C#C$C$C=Ce"C!CG1CMCn, CZC@FC Cs Ct C CȽCcCl CzCqBBBjBRBOBBBBרBCUC2C}C:UC@C~CцC6B JBB COCTC CgC=BBػBZMBJ*A7B[Br C CXCACh CCi CCACBB`B}BB!!BqC(8C5C_CCB/BpB;vBBBCC C Cm C C2CC- CRCk(C CaCR CH CCfCpC&CJ#C3C.C#C%C9%C7%C"CW"Ce$Cl$CCCRB_[BgWBoBBLCc_CnqC}BKeB=7Be#`BikBn)B BIXCC?!C(C`.)CX`'CFf"CC Cq C CCC'C'CRC%C)C6)CJ'C1O'C0&C$C="CC CB JB9Bn DB B Bg Ce= C BBrB=B2[B]BFLBs:BIXBy CMCK#C$CG#C!C#C!C."C>C C=C CC`CCC C2 CbC |CCQ C C.CBuBpB5BݖBBB.BQBQC CDC*CFbC CC@B_BBBzBYB'BKBBBBBQBAA*qB'Bu CC%C COC CB4BMB|BBBC[ C|CQ!CBN$CC1$ CGCnBcKBVB]BWtBCPCB&ZBBbBC CC%CC3 Cr C+C Cp`CCe C~C Cl"C4}&C$C'C!*C*CO,CA++C*CSv'Ct#CCu C6?B`dB#bB|9BCECSCC C:CCvCCCjC2zCCCa C-CzC%B,0BhBvB2B BUB`BpB!BzSBxCC>C%BCxBQBWBB}BVsBkB BQBhB*F1ByAA$B]BCF C C): C C3CaBBGBBB CfC4CjC C CC C^BӇB~B&BBmBBBxBBBB CUCC{CXCOC CCwCC\ C1 C CC%"C(CS>(C#C%C.CzG0C;,C%CVCZB=BIB|GB/Bz4Bu"KBݯBl7B? BBNBiNB5BCBB&-BfBkB[CCqB#C%C%C"C $$CK#C C: CC"C C CxK CE Cv CCPM CFCM&CrC| Ch CBWBMmBB]BBBjB!BBBB~BɶB[C~CBCC1"B"BBB뀨BB&BB)2B BO(A$GBYBn@BCCCFCBñBBB CvCg CC\CC>"CBy$CyqCG~CiHBmB\BBүB{BBsBBBB2BC C]C{CIqC]Cv CB CzC^CPpCH C_H CTC!C)C}(Cm$C&Ca-C40C-+C7 C&`CB@B B]9BV'BJ1BX=BLB>BB+B?BQBV;BLB߫BBDBB CC5C$Cݞ&C;#CC$CY#CXCC CT|CCBCCCCwC CDC=$CCCjB0BBLBB+BǕBMByB&BB BBB@BUfCbCQ CYC BBsHBB7B4SBm$MB;#A@=PA0XB̼BTBUB1B9gBLBBm BCCMCEC"CC CL C%~%CCd CB)sBxB\BsBB9RBrB;B]BqcBVBϴCj CCCC Cz CCC|C * C1C- CxCK$Cݔ)C)C"-C+C*C+CF*'C%CM/C)BI]B1ȪBVHMBn,B=B;7BCMYB) B-BB|B8HBXCBUVBwBBpB?B]C C~C4~CL,!C@kCjD"C$C"CC CCC|CC CCCCC6CC-@BSBB{MBAB ̠B`vBqBBBB-B/BBBBґBCa CjCf CdCJBdXBGBB¨BDbB.B`@A7BBcBg]BBBRBiB C/CxC C%CCDCQC5C,Cl7CSCsB8B`BB_*BفBB0B,B^BBFYB} C}CU{CC, C2% Cx CcC'CƞC$ CA C6CCu4&C'*CJ-C(C'C&*CcL%C=CCrBB7 BBCBHBИBBNKBF_Bb.B>Bs BBCBmCiC C*F C C;XC>CI_CCC"C;*C6C C{ C C8 CC~ CCJCyCVCCBBiB[)BBvBBwBBYBrRBBCrDC+C2C C CCCtC=C3C C$C]BrB#BBEBFB@ZAE BB!BA#BUB@BCk"BBBtCy)CBhJBBOBBBrbC6C:CdCC C8lCjIC C0CѤC C)CUC"C'C*C*Cq%C#C}CCFDCCJCB BgBՕ9B,CB_MB]B;BBaB͝:B*B?wBBBnB0BC%CC~2 C CC CCCCCJCfCyJ CJ] C CŞ C"4CCC>CC60C>BB8B``BNBBNBBT9B=BC| Cr CCC C)C3C4C]`C"C,DC L Cq C3CCCHB=BzB3B~@D@ BoABT#BHBCC6-CC CN9CBABXB@BBƸB,CRg#C#CsCC=C>Cl0C^ Cp CmMCCxC-BBEBBGB3C C3FC~C3*Cg% CNCC CeN C3C|, C|?CR C؛#CU(C,Cdz)CCCVCC} CCC8TBQBB17BKBBJIB;cBBB֦qB wGB`)BchxB&ByB9BTC7OCBCCCQC:2 C˙ CCACJlC CC CeBB2BɥBiBBBoBOBs%CRRC!?C.C3CC+ Co CwV CC3C2DCΚCCCBBBB5B&_@"0><@U9BHBCCQC{( C> C+CBf+B>BB BUBC(Cwh(Cj%CYCC CCC CvCCBBaBhB0BCj, C_C6C}C C/CGNC͸ C Cb CuCHCb&C<%C(C (C=#CC'C݉CNC CCCH.CRBR.B/:BguAOABSBBBmBRBBBBBQB BCEC&"Cb&CY$C3!CICC`CԪCCC|BBfB5jB>jBBC2C CC$}ClC7C]CCC# CE8C<%Cډ*C$%'C"CFCCCCcC%I C0 CMeCHvC'CBg(B#?B.BeBBBB6B$&zB5BeBRDBy7BBhCC }BBvfC@BCC"\CCK COC9CR:CqCpC*CC99 C"C{CC9Cd C>CdB}B%BxBSBVBB]B`BCC0BxDB^BaBvBBBBBB,BBBpB BxB}"CC-C COKCC1CsCCǦ!C $C#C'C(Cq5%C:%C0$CCCUC@C|DCGCPC6DC4CK=C>BDBB'uB.N*B0@BBBsByBBrCmBGB[B8B'aB `BHOBDuBBBB~BB BCCC~ZCC&Ct-C!C4CF C\BBwB_jBrBMB/B&BBHBBBCCC! CCC3CCCv+CQClCgCt!CQCmWCOCCΥCBBBNA]BB>;B,$CB7B;BB+BqEB6BBcDB;zBB*˺BBBJBwBiB BCC?CCCC$CC)CCO#C"K$C&G*CA+C)C%CCqC9 CC;CC31 CQ CCC,pCUBiBB[Bw)B;B|BBB0B_ CMICwCBB'RB4Bq^BaB&BBg?BdBBBuB KCC1CC CK)C(C#CuC C?B!BCB6XBjBBmBՓBv_B* B*$BxBKPCJeC{ CCCCCJ_C(CCəCC CC'C* C* CCBxBA-VUAhBB BBeB=NB:B>B B4BB$gBeB?BHC=C%C FCvCHCCCnBB7BUBBτC_C@CC C CYC9 CBB]Bݴ6BBBzB{BtBlSCCCG|B.B8C= C^LC%C&CC)LC,HBCU CC CCQzC=BcB;BpcB,-4AyDB BBRBpBBBBq.BCvXBSB<CoB"CB;BBBnBDBBBBʱB"BBhBBdCkC<C %CA)CM\'C+C/CT'C#Cf< C C CքCbCCC 'C;C~C/&C] CrC&CC8fC@CXCpWCbTBBBLPBFBB&BrBϷBR_B:CYCQ3CB(BwBYB>BB,:B;BD@GBC CCC1CC/CyC$C#&C&C'CI"C!CLCC`C%. C0X Cԅ C CCC9CIJC#C!C*C+C(C(Cx)C?+C#C N-C~*C!CSCeCB57BDBC}k*C,C{+C/Cq0C!1C~2C/C,C-C)C%Cp)CZ/C/CI0C0C g+C)C6N-C.C~+C+C.-C2+CC+BB$BY$@&9?slA B<C C:cCҝCoCCv CC:CyD'C I&CU^%C @&C 'C-7%C &CO"C[yCC C!C C5"C!!CQ'CN+C#CW'CO'C&C(Cٔ&CJX$C&C"(C^#C)%CCC9CbCC=~(C2,C-C9-CA.CO1C 1CX2CI2CR1C_.C'C'C|+C*.CS1CG.C+C#+C*C+;.C0C[.C*Cï-C;<0C-$.CskCCCmCiC4 CC*%CZ(C+C,C'C0Z#C>'C[E%C5#C$CX"C)WC{CCCCCKCCnCdC#-B\BDB/C CCȧ C# C M CCCgBqBKBEASB:BC CRCC} CUC!C\C^Cd]%C%C$C9%C4(CP.Cw,CH)C)CY*C+Ca"(CZ(CXr,C6.C-C8&C$C !C}$C()CL"&C2CN*C%(Cu0"C]S)CwCUB CE4CC*Cj/CU.CP/C/CJV0CBu4Cp2CO4C(4C7.C2-C7)C>H*CԷ.C)C.CI,C+C 1C1C՘0C1C+0C)CG,C+C-Cc,CM#CCPC"C%C]C"C&CJe*Cz(CG(Cү%C!C|C"C#C#CNCCCXC CbCC*CCC C{ Cl C% CEG CiCCBC C~ CCCJB: B8Be?_rA9BCW C CT0 CB}9BXB%BbCC CzA"Cs#Cw (C,Cz+C*Cv*C)CU-C7,CU+C.C*CB'C(CT*Cm)CH,CP6,Co*C$CL/C)C>!C5)C!CCW!CGA(C,C0C3C"1C1C_2C5C2Ci6CM5Ca-C/Ct!/Ce.C>1C*CQ.C}0CU2C|7C1CH,CF0Cns1Cx,C-C*Cn+CO/CC\*C/&CC@'C)CEk!CI!"C+%Cч)C'Cl)C(C@3"CC"C_C+ Cd"C!CL=#C-"CV!C7$C!C !CCACcCcCoCCC;C\CCdC-jCNCrBBֿB <@AgBCg CقCCuJBF2B,B{BB$CuX CcC;CZ%C(C*CW"*C*CS(C-C0C[y-Cd*C #C%CR,C+C<-Cm.Cn*C&C(CdT2CA)CR"C *C(C%C(C.Cr.C0Cg5C2CF1C,.C*C$CF4*C+C/(C/Cv/Cb#CO &C:X)CM)C&Cb(Ce'C(CY*C-CU+Cd+C .C,CN,Cc/Ch,C-C˫(C'K*C)C#C>#C#%C'C&C#Cib&C&CC"Ct C#COk"C#C|$CY3%Cg!CG#C+%C9CC&C"CC`CvCzClC6C`fCC- C[CnCBhoBh~@B@BCq CxCOBܘBRBBCBa{BBBC C4C@ C1"CZ'CF%C=)Cow+C+C)/Ce,C/C=+C ++C-C$,C8_-Cr-C)Cu'C*C6W/C-C<'CJ-(C-Cl+C)C.C1C/C2CK/Cف-C#CsCC CEy C C]C0BBrBICy~C%CCC3BC]&C(C:#C&C\+C-C1Cy.C)C-CX+C+C)CM$C@&C A)C{!Ct%C&C"C]'C!C!Cd#CK(CBj!CC Cv6'C""CTC}CXCCW5CoCaCTCCl:C5 CpB~ BCZlCBߐB*B}ArC?;ABCYCTBBB]CBBBBBCCIFCpNCsC?b C8&C(F)C )C,C*C/Cu.C-C+C)C(CY(C$+C/I+C'CO*Cŭ0C.Cܟ*C!-C.C +C,C2CX.CYF.CW+Cˇ'C^ CJ C^BkBDBB3BdkBT"@BjoxBBB+BսBGB7C'C#CK C]%C%%C(CK/C-Cx%CР)C)Co,Cq*C$C2)CR)2C&CY(CӉ0CO%C4!CU"CN CQ"CB*CC% CC@cCW#C CC?[C+C&C݉CRCmOCM}C֠Ct|C9QBBBR1BB BBgBig A51@BkBYCmDBBeBB~B BBB C5eCFHCC2CCCט"C'C-C/Cb+C%(CM,CR-CL[+C! ,C)C](C5*C&C(Cπ*C9.C1C!,Cx.C^/C ,Cq0Cf+CM)C@)C$C !CC8CNByB3BաBbXTBvnBtnB(BP6BBB CC'C"C8#C(#C~ Cf"Cq(Cd<+C{&C+'C V(C,C^%C$&C<-&CV,Cr-C?d!C+C%t(CUc C C CC+%C|CdC7C~>CoCClCCBC?CC>nCCvCFCOBBTBcBHB B -B7HAy/?Q>nABBQBBwB8BABoBCwB)CJ C* Cb CBCE6CC2UC3Cc&C1Cn*C'CK)CY^0C/C.C.C΋*C+Cd+C#*C@'CJ+C|2CcM/C@-C]t2C00C.C*C-'C:,C)C#C#CqC[B]BBΟBL(B_BHyBBB~BB zC`CVCcC C| CY1C8C\A#C^%C(C(C.&+C*C.O+Cǘ%C&Cί#C0C3O*C9 CC +C_ CBC#CCc C !CO#C5 Cg"CC6TCC CECɤC+ CCC߷CC CTB`BiB1BY@09@c2>?oqBqBBm"B7vBC:BB@CCSCCCBnB֕COC CRCC+C*C*C7#&C.C!1C}+C,C+C+C+C*C*C,)Ce-C/C,C޷0C.0C0C0Cj(C*C,C&Cʚ"C<CC+DB[7B:BsBM BBOPBBnBCpCDCCH C CC(C?!Cb$CF%Cz*CA0C%n+C-CV+Cw#C)C'C!CO|$C/ C'CoCY"C7'C"C=u$Ci"C)CwKCyCxOCClC1C! Csz C;C#9CCcC2CHClCVBB҉IBH KBTNBBjB !B^CC bB0BuBBtB$BBjB)BªBB CC -Cݿ,C0C*C-CM4.C_-Ci-Cޅ+C>-C +Cא'C(+Cv(Cz)C.-C;1C,C (C{1Cj.C%C+(C:&C̛"CvCXC3C$BRBݚB A}BݜBŖBR=BBNBCo8 CsC5FBYBB?B~C0dC<"Cx CH%C+C٫(C+*C,C C_&CX3C!C*C(CC"C0 C7'CԀ)C׎#C#C<'CxBtBPQCbCd<C C< CI Ce CSC' CCCxCHC?3C6*C-)C*C-C\0CL.C*C'C%CC C5 CCAC`C1KCCc C B#BZBйBWkB_4B-lB1BBBo0B|+C9)0CY,C+C,C.C0C .CK;/Cg+CCmCtECSlC" C߷ CCCC CB CkB]OBjBBKEBBbBBcBBjBZBBB[9C $C$C'C'CO!C> CcS$C&C+C)Ci~)C*C1N!CQ0#Cݪ%Cvu&C($C&C $C>hC#CޔBBB!BB~BBnKB܉BB!BBsdBC>*CjBB&oBABB6BB.)C5S1CL0C$C,CaQ Cq CCCv}C(CuCֆCCPC6CPCC\eC}B3B֓BLBbBUkB9BB#B(BM; CC%C CCVCUZC2Ca%C%C(C'C7&C+ C2C C*CׁC@Ck$CeC=$Cg!CC CBBEBB9BBd"BlB'zBѻB_B{$BsBDFiBӳ>ABB}B%BBBPBABBGB=BJ[BBbB^QC|(C"C!.Ci+C.Ck4CI.C -Cy+C)C.C|.CR,C,C.C-/Cw*0C/C)#C, Cq.BqB*B?C_CpBBCСCrpB1C3BBBy[BZBhB"BVsBMB8B=BB CASC.CV!CvLCcCdBIB J C 2"Cw,CK(CV'C1EC^7CE@CbXB+BCECO?C2C (C~"CC@CCBjB BBiCR CBBqBdBoBBBB>BBVBABdzBoBeBBZB,BBCBC}7C CC)Cy.C/C?"0CjZ0Cl+CT)C}}&CCf C|C0B%C`1+Cg.CU,CE+C|.CZCBwBBEfBB_;BVBBB4CBB|B:BBBuBBlB oBkBuBIYBCLrCHCC'CECCBBBCCP-Cd(CB%CCBBBkWBBUB(B B& C=C}!C68#CucCR CEC9C~BCTCC2 CCp=C^CPBCBVȧBACBB.JBMOB'TBߕBJgBB@BvCCU:C4CC"C.C60C.C.CR,C&CCPC(B6BvBC8(Cs,CK+C/c-C`-CCB%BbBҟB[BqBFBmBBBB0BB.BB#B@BB1BaB.Co CCy5CCP CCCzC<%B6BBBۼCi*C'CCvCB/BByB[BXBuB-B6CC!CD!CIC*UCS1C(CaC9C C$|CŐCCBB&BaB v<BBdB=BBZBBB B0yBCQC CͅCHC!C*C,C|u,C*C)C #CAC9B[?BjBBZ C")C710CK.C*CW*CX;CCQBmBB Br4BB B B OBBSBmyBzB13Ba8B EB3B&C (CE0CC\1C5'CC^C΅B˾B+BwB"C&CT2C 1C'8)C(Cg3%CnCC3B0RBBBBTBiB:B8CL"Ct"CxC-C)?CCCOV CmJCChBBcBH@A$B`;xBBUBSB=BRByC@] CwCqcCC$C((C)CX1C0CHCCB 5BBW{B CM@C!C+CxD.C*C+(C"*C%C)CC5B|BLBB>B!BB BBBmBGBp%B(B|BzBBIBq BȾBtBBPBiB߸BBB"BpCCH'C%CøC!OCFB,\BdBBBYB B,BBBBeB*BYBFCTC5 CUCC3 Ch C CBBqRByBIwAAATƈBdLBtBB{B BC%CuqCC]&CO+C+C-Ce$CC)BBSBBM>C 3CrCG$C1M&C(C'Cr'CJ2,Cj*Cx!CCH CmCC\CvCCBBB}BPB|B=BV%B!BkBsBɎB1fBB.nBfBBB,(BzB$BFYBCbC!C'Cʄ$CQCCBBdBBB5kBB}B"B]MBBBB?CVCCCWCO C)$B.BBBwBHBf@(ʤA%BBBCB BVxC/ CC C@&Cޝ.Cl.Cn*CC& C*BBBVZB&uC CC*C[2)Cp(C&C'CF+C*C(C Cd2C CC%C2CC^CL^C Cb C CLB55B+BEB%.BBaBB9BBBB}Bx/B_uB|B;CCV#C<%CD~#CC^BhmB6B+B.6BطBBBE0BB8BBKB;B^B> CC_?CBC1 C$BBBRBBA&F>lQBiBBBB PCK CC#C*Cl(CsC C+dCփBA`|B$B>BgB}BdBwClCCC{&Cq)C&Ca$CC CBB:B/BUBBSBBCBK+BBaB$-BBeBC C CCoBBB,XB\WAmFAWIoBBpWBIBBpCjCC- C=B0C?C(CBӒBBMB BbBPBB9BM C*eCT:Ch&C*-C2.C .C2-C,C.CY-C(C "C%CnC8CWC)CSCB PBrnB[AABBBþCCACmCdC[Cw C%C(C#C2C:C.CBBBzBsB BԙB\DBUhBB1BBBB$BRdBcBB]B7BoBoB[BkBnA#B-}yB4BZB$BCC/C*C B7gB2C@pCBZ$BB%B%BtBgBxBoEC!CCC CN +C9A0Ca/C-C*C%-CT.C.)C,CC C{CCBBdBBB BVAHBh>BTB.C%CC$C\&C"CClBBBjBHBBBhB@BsEBBBWB$cB.BBg?BBB˙BB̲BᯘBKAA#@=[@]OB BGBCC>J!CPC BDBB%CCpBrB\ABgBJB$B cBqBCClC2 C&C%CΉ,CC-C A-C!*Cr=,C.C)CC*CTVCB B"PBBBABKB tAGNBBBqB`C CC CۉC)C CCkCn CY"Bc[BsBoBaBBQB<B2vBݴBBB9BTB BBBBBnPBBB:B6BAAE$BBNIB>CC7=CiCBsB߁B5C CB,Bm|BBCBTB9C%CC#C~CC1CKC{&C8&CL~(C*C# -C@--C:W(CiCr CXCZBxB|SBB'rB~lBdϞAABBBm$C C6CWC.C Cr"C6!C9_CgCBuB-BTBBBtBzBBd'BvB1 B~8BغBaB NBQBBO[BߟBBuBՁBθAH@i?BB @C>CfhC CB%B}BBxEB BxBB.BNB<C C CũCCbCSC7 CPC#CU&C'C`,C,C&Cf$C?:C C{CCc7BDBNB0B眫A=@-BF B]B4B{>C CC%nC\CC,C C3CC9B,BBB*B?B(B.B|UB(B$~BBR9B9WAKBB?B !HBCBfBA\AogBDBSB)C#vC7 CeBABJB&BYBBBEBVBB"C CCXBnBܑB:vCBQCC.oC$C0D&Cފ(C6(C$C (C%CDC@C ]CTBVfBB eBA;?YA'BJBmBJBC̐ Cv C CU CC3CC CxCB BtBBoBB&gBB{BGB_WBBQĥAvosA_AÄ?VB#BXBBCC5BDBTBB B+BBݸB)B&C^CKCBMBBrBC$sCv"C CCC:CU C'C-C+CC#C.C<CCrBbCZBB:BqBѻBBBqKBB߰BwrB*BW~7AZB=BBBBxBPOBHsBi[BwB5BAB'BBJCdC CR CC:B9 BQC&C(C"C((C$CȓCCx CFBBBZʃBLb?sABwBB RBV" CԕC CCC=C CC CCBB"ByLBgyB6B7B0BA5@1B;)BNAA@AdA9AnB?BBGCC/CCwhCBwBBBxB܁By7BWB kBB.BA`?^rA,ByB`CJB4 BAB EBmBWB=BBj9BHBACB'B(BBiBDB&BBB@BB1BBܤB:BB9B'BKAE>w?XB$BneBBPB0ơBSBo$B'BpB-7BAe[AzBh+yB[аB~MB2B BB :BBBeB6%BA6%]BBBWA@u<͵? u=BX;QBɞ'BG`A;AEmBBBӼBmBĩBaӌB.B-Ap@ZAnA@ ?=S{lATԗAs0AA~jB޿8BgAe@OS??y?6p?x2=ɤ?7Ad@ants-1.9.2+svn680.dfsg/Examples/Data/r64roth.nii.gz000066400000000000000000100240541147325206600215450ustar00rootroot00000000000000p{y33%l-Ubfffefff̌̾fW/cDD(,U*?w2iԢu-[Twޓ/ۯzWRY[9fYc͟Mm{|o>w܄I[ D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$D"H$3~+>B:]}MCNxIJ[W~o"'RK>H{l=. ](6|ٖ ASk֓M_Jv՗>,G"qM$y>~Jb~߾wՑn#ϽWb`mH$ʡ%I Jkb; 1v—.Bifa/mI1{j; #;[nN: k |i5S깾pxPpq4WQ:Q3k{ZIiPaszjsl'{p,S"Or4 _,>j)V/*=.nVj"V[mϤcI' z2O鬴ғJb 776ԛf}.3GI'aq/i``p0uWQq:QO/s f-Q)0 70X?>p4B7ªùp~, Fۡ-}Xs]/_yDrN78P$5:`'>]zEHFEMļPxW#Ԧ]֧3`n w\'Fj XFCm8=[(m,',rR+闶ңo8&=S3%QqݘUC\CX3={hcwW􎳥9[~kJґg/v 8ЖWaHvdP*]<آΰV|SXSVOKOa<ņ#آ<6S|Khm rt@ggÆq^*Itf]%($*b'͔v)Չaq$?4D; y ľ|&LDDͤlAo|ox[_[.9ǐaG$<2C-C<O^LXʖRBӆ=^[LB؍Bʃ‰[뻊|ז2Ȓ&L!cC{ #x^GVb["n{=b1Y91y@gh C,@)҅&eϷt~6| Xێ mZ *bq%kʏ6,{cNO\YN0_QҴ%%{Zrm >Tx gҋp7U#)\YσY\s 74L$^h7o?^zAƑ?2>x9 k:_eKEn~퇥"%hԁ> 6G֓O#EfYr0*ZM:OumYG/RƁkn@"7G1v ^](0Fav_3UZ5e*kvgI#=3V a;x20ݚN޴fMgEƐ$%!}PJjs}Z2Vߐ*L٥YlψE"d/CFNG;~c,T$Q!8!kpP. F]ݟnϺBKy(_'x6n!n5An Ԁ0ދ޴줌^s)J]+smƄl! ']]3nEt}uA,m*|,,H__zO>;W ?F(̒|8Տ! 17-1ExE°^1=˕}9Qc|Y{>iOfxKy>3ث;O_iLMfKZ:p2eKLu ,č'rite:H6@ç6 a=mL{@yMjKZ6Էv@n'3o"aE~&S1Kx= }J@[帆?>؉xI˯\;o!K&`ђ7ÝYL}<(4IeG Ź@3Fݕ¹I ¦Q[>p0εSYnI+q'k:j8񙄅Ʈu '^~-sj|ݪϽܚU>|N EG$tB ,M7̒ZQe<{F7GchI+"†%MغTL5ټ”=*E sKa6+nY;^Fw߿g%fn ?=W|4xLQ4)߻G|[d8GHH5z is'A5}m͓i /hODmd<;ʱ&lsI0ӃvюmB洵R+oE W^$O-t|{M Da "%^J7NzWI τ߭zDZX˳9z, ̲<'⩗J .8L^ƉاJXu*~Y\WH#< .>HsL&Ό1Sl.slae 3:1A&q<>)hoP#u%QdT?I35@olzZB0p.[hI Vݨ ^lVj$7'jqZQYn>rE A)MP `NajL1)WGb}̗6ǃIՍ̚,`WH,Z m;_\:1|{-e~xufrz*Ҙ>!==?џs/`# Oݱ3^Jətlңߍ[7_'id94ϓy*Uyfggy.4C39ԋTnfB ~Y\M:'5N|0YuJNrJ8WMić3p)gJP|L_Ci ۣalGl ͩŃRwHCv,51yN~R&SV3׸˞ȷ0x^gdkF3d~]H+(Ke?C?wC8~;Ҙ2=E3ٻ w4ӳflfcl~i%VX C[ ^=efJ tͦa, h\c<^芞UEy_=ٙE_A搇_xqd;Ocv g18ךZ%XЧUo ,xbcC,fVxҪB/j,"6 .!x.3Ed|(!ǺE(|]ESng#(ϸ(Ny${0%daSI g?х]DJs- u&G0ɰN){3ӈzĵ.9qkА@4<l¢ȺYdӿs,|i˙.L/\w^ cm}5㒅j3SG@ӌ#3>:Z,7k'mȔ@JggXbn-Fz}Űy[Gy07?s[HSf!!EtT%3%Yt7T4]VI(LMInJRA'r-v21c ḙPË~5L]tj<SLpr9GtCn7P[^qat;C9<Ȟx+sq7/ LJiy࿹]%uH=W ݟe\vf(KJOBW!p|f9crYe+³:m_<1Ă )u'ajĀ̏|;)Ϡsy6 \(!= `$,(Dk}<ƓΗ>/'yLy6*ȏc˧:qsNy23/MX@*Α0+@?m9žٶtd KO $>Zer&=&s _m\ ;f}WNµl<_ LUHڄ,wch-h떑4C\5%_)Wu$I\y@M}nAvVNH^̬)gʶJ(ad‡yfCӟX.Kc5_&H>[ ˃L:!c1>'u 6㩕;r'6'qGL 6-6`$mZyc o^v2+sb??{#)-FU%_囁XvEW`f1=B?DI5 gQ1-Y.#7c_|{`ؑ_j2 a=+rf<׾yp ݢ,@"K2/.Y:;"nqx;;O MB5ٝ/K9 󤺯?ø0Ǵ#,t-AN,1ҦhqvJ*dbz*Q}Ϸo.ħk)]|y!+wsrF!-δBz(f;sza{W2ΖPHXȧl.^ĢURHAحAΊx+ĚpjRZׁgFa͓`ywzgسRˑV0y.| }N)b oh(aHkN m9Q(LPrs6Nje>f \@ujJAn8S'[K?y[Lb6YO}vLٰ O#|%]Y>+=xk/& yYbɸ"YׇYԏ,|fG;(dx6z^&yƫa8RpƊ-k|U1e&JIXaŌmć0@%0/œJxt5:mqu!ɹĞ)|W@^>?8(k}3P|~*`*T;$c~*WeQLI\ :]kf-e.x=L "^bw+1\AReYi,dї"NW"T#+^ӶWW\"~3V M1D@.gjҷI֓LY)rg}YμtxZݵ!>_cH,27"eYiRIḫjW%g;r@#4Gj!l:m:\| mx@- [ vUYL\sm 'SސϢ}9Wޅh/񠍪=StۗU[b.שӏVr; ΄Zj &8z"M9:ݎ_χ#YH0lYߗԷ㸲aI |^iI.XO,'{l g/±ȟi#WtJF<"ノ'3߆{d?'#P4hDWMw$pjUԼ(cy*fh0M-w1x-Nb2;[nE'3SNhXALeJ8cS_%  Ǡj9J,9^⹀a}_EN.Xwm)}B(N|i8^"q@Y\ρ y̹A&ѓGjxp96%W䙷5eĥ}8CU5 )yjʒ2A6Gy'Mac|9o¡HNCZTҢv$&#bB|9SC#x윌ߑ(ڽsc#K&vJ.bfd='bBD'л#qFs]6G;1#ǔdTg+t0_[sF$eu\ nk;ǔniϮ!d'Y*p#vڰƱAxkDbW4Y!ܴunϬmwLyF@4˅;!9l9t|u޿_$2Ķ+QO=VC Y}l\A4eY$z?jl?k̃Wavy6-qC>/~;1=%z6a  JkMQ0w.z+"%*ʏC!ï[ i2BJ3JWB0U_Μ&")󫹗XIޮu ' D`pZ)ezf$4[3Y7F>t}oz:ruWQ߮u٬>3V6ݏ'Kq>./ @ѓ/#jU0Pi0&XeJ L 5UQ1Uisj$aWX{sQUYɈ~gϯՎh8g=B9:\3%ȳDW\ff͖ M7Mi͘KVxpcBޟ'7,yZM%&L[*f¶jz +F-g,0-p! jh'aIp|b[$ч. _%~#Fch>Sq G).gvc*l"7&fu`nMEY7ƅd2\ t.lU<[3w\:c/NEѢ:C!7mppfŸD~Z(=# MBk!mpR1yI#=;j[?KCYJzz ~d76R2n6.$0#@$CT$Lp|ӟ06ס G d)^tPCQ PujVӤȈQ_ڔ|pS)JUNu>fwnRjy9#VE GF{iDž%VX4[8ue䟱 )tXuDĹQ\ehncQʞAX&-tzuQaY)<=sF:]V5t5\SYp؉)7}99ILvy~>ZZBLKq#2 D˳xJ|$ϯϮXS>ߟ^VUõb"bLs vq;8ł-v|ꎣMD=-K2U(n,p$05LA@ iqÚR.G>ϥ/H!+BR~;ꞏ$sVsSzFaf\߻f/VBC&y&l5E* -jzmƏeU5\7`*L.oWX @j<jF#6\T@EGػlVUZN_Q- 6vy_Ѳs fv+T"9oo ĻЃ+k͹tؘŇ-M^1,ɞ +pPm3Z*\Oe2"MRf‚;RNb'(Y*x]KWk`ʘx׾P{Eܽɡ8F{0q7,e,B''tu>?Q. c뭛[K/)S߂SC{gfZ9W:ʼn/+x)eŔVƨ >U\j_iŴxo;'vaߐ Toa_YYHVɏy ڤx/ h, Dω\wf~ Z *)՜AU@*w5pO:KߜZPdɵqDԥc S6Lƨ,33b bcKdTZ0o1yR] Fs[;ѱ4AiT3БSetV"J%ԫXתz26@V-w{joBt@bٚ6ui g33wwޙnOG  A]0|QN$'݅!ZOY7U^O9m ~ӄ3 Oflj@0bnI1w!ܗOIyYeܝ^L|Wx)X%ϊ5O3AMZ`*O3^wSXH:mE޻N{߷xa`O[S>5{=AdKlUǵvU_-̛:>/±w!G,|N$4rzW1{3`}4ջ|όęc jGA$5$Gَ͒hE VUءlscWq|5g,{"[6@rRy96DNO̖٣_juwSm1<h[\2sg; >{ǖF.keݚX4fh=乨\Ejh#|-j'kQUgPCDU- ohesW2xkwCYޟNQ,J̺_9mBc z lߘʫxR'c((^Ot`}dqO${n$k- ;t?Ok ?w%B#|Nx~&op)_1D_ ~G.$!,XV|\Ix `#:} YB?=1B!MKk?PzrՓq-LP2bhזf$rDEۏ(0)C!u,Ե<*U wIJ ~p̦ryϫDZC]fPbeM-1o;.$1D4c1Q,9eEO{6x&u\>c8=rⲧ9ٞȈ%cS3ymNϞ1HGs5 `O\?_vdW*gyсW vߚV6EeLfl, irޱE=网l+V#QOZzJP [QV,ٙVuǚx7^u%h?us;ӝљy>T@#ZDv !cWwrh!eswj]wid:f[qDHn E{ GTNe;:ٓٞ,a%C/$"Gjo=+8+Mibnn^MhzU3ӣwe4O㏅Glg>dx #=HVJθ%Q,!>GXo$G9Z= doɸ4p)6+T֏^s(gE[TLYf[=yNZtE앿nʣ"M,dA!kU9ɣTTVJރb~-$}M1*7JMKVX*CR\ ~%P;#n 5]IiӃJ~,c 9.^;ċ.^g+!Z??+1hN>nKPȱ-k:)LIJ&RQ ^nj ߨxaSj=fM?Q FMbvn,7(lq1f΋eN9 wMnsƅf|;e$D󥎁r]PϷ!zQ^*ndX +;NJ99"ΊsrlxNL؟#1 b{ ? \g:lD=ntPy8Wt$L݃LjCEN|ȶ$Ъ{&oE}ϚƑlF=~jމ5[X ]̤`9wLc$ƅsp nc2@IϾ\ F9QZRMj>Ӑń>D:,ئC[j^3]v9X~6 OTyTr]roqL 'JcD3OYP4̑q62Jܚ7ʬ%LX 3uF<9YYGj6WcY]ut~`G#hx]dutѪS·Jՠo!|D5Q$CM'f j0pѓw8m n3yPFh9EE)i*!Td'>"i9˟]9ϡ%j8.j{*E2LۉI.M:xN4_K×(~S|3Y)f i jxah1ELJnF2ӄނq)I$ 6q!w:#JJx|:0ww)zV1&_Q72~V?3p{&HE7kf7sEP1c JWr_ iT!(ckx.`&8bio_NM_vwPҠ#r#i:o,DBh[C;So'5ry13ø])m\z7YfryYGKZ޽3_f6N12,gY]ROLkEs# [21H"PSmw:BfpΛkp +z9Ld؃*nGq?g{I>cI_[)C.aˋ(ϡ~f8ggv0`\37Ldf\7kJ< hb`"=z,aVM*^դ0鈊ȡ%=[n~,в*4R- j8$Tq#6JO8͛6ɏ.; Cwu>@X"SGRI$'fQJrdKF1)ݩ߫ ? Z?̺ $)Kj:h+f5#Գpgç9c[֗a#2A i`h5 To'ZyQBkFFv52b |+}r#JU 㚊23OJL4]l"綑Mfiˌ-&tױ J[gbJr{>mIzJ=ZSgs*fss@\ÏK<~$a4)-Jy<1U{r>06JEo4^9y'4pMK|a4?ijbc,e %نDޥe$gj_7V>URrP=񵰘Z5jE?x>OS{ i9Tf$BmJ=O.&3Kdծzi R)٠2,D3I^(In@1S34)̮E\:wG#*|]Ծrbܜϒ2r g\_ܨ;RgL;N,I@yQ6E*}8D#8-S_^-yo" |PC)\|A6RN,g Ӓ_d+Gt[$rcP9"UdTZ.dv9?<5\oTRR fbiz{3+98Sd1]zTj>=N!k<}7cZm|*Nsnk!OHX3A㰔yXݏ7&f{boTrVE>ISq*PiRY31~t;Ο]jYM;~?PVMΛVNxrd cp7m7%j+TӰ.DsZ^PcZ3>PF BS<*|ٻ~ gD)"Xz^k|+A҃f77Vʏڥ,{o⌸{Nbrᶘ C߈H_O s|f -$`K%P9Wi#TQi|Bd~/?IvGja\E"/rk$f@4 $NLC63p2-10m){Km_JVl}7B"%Ju,S6"@ ?_OaLҷ`Ŧ2O׶]~se~"!)UdL8 mR/m1hPǸF~DgUI$y= N &]*yu=6P]s'&tDfѵìT13qV*}m+zKO:VyAO{-3_υ& 8K;+mZd]Ȏd=^*zn;[OtJTQQ( V8n^L.aXb/*6+y'΁4hbsx +*X":ou:Y%fr50qT rp;FJ,v (FFj*SዎFԱW[:L#io [pp (y*P+A ZsU2އ>tj`獟E軦y&xLCIy1ƟWc9.t7`rW2N ʌl~:_Hd!wk*a*as?$4b u"[| BnIW#lk#u*QTĦiѦP"2ӈMY伞~f0D5Ay$sIjxd&zf9Mu:f ӑxOO&<ϛ֊2^ϟ+ӱ"p ډ|B:r|g2+!c|M2SyLƦEDR oe,+Ib5N4ᔣ ΊcE'u9Z;q:rjX%4TLl9}1 ubϐc])g@UhSoUepӒ&50qJۋxO|̪*)I (AQa۫8Ӯn0ukZkub_q+k\K{D,M%) N1tiNzCg y]Fe|oYʺ-1sjZE_r r9p#qKD2>NvSh{E=ͭ0MpFƅe<)6d/D8 MSez8waA&KfXz^|y"AwJe?To )=c\;=φ0:nKr, [MekO~D'ѦeVd0u$$ѱL\f`V5M/8E S =4z:gH(g&V,^1V;%<}?Ge\iK;kmzJdSy;_S~O[:s9\d纅q/Bb)-Hv*qUUEC--.F9:.)4șUAkc/#a*x^*o93^E=Dt G(IQ1₊s*VQ$FOt-foجqgPt6ֲevr,&h~%F'3xBpdNd]ہxXhMٺs~F3:7fLNMcW|%} .LϠ}8θ닣 >Ed:ss5:ռ{gxڗ뵲 E#BpxmE?wGD{ ڷuoM7DmdT1Cy7ܟuaL'PO5x6E<׮w3sX4g"㯭l^3DOmtMJpLf^]^sMͬ?c Gؽ6 hxEi*DLN#¨U>`vdŠj.f~ټ+AV4/Ò$NR~52C@[5Tפ31F;blƺ;~/d}ü˻+S8."7:|Ě3'bMTwMaDxOx]p$FM$ C$vw.)|lݚc5 35)GNE&JuqrMdn`~̯Lf`1稁:3?:+[jCE5py X&~K6|MqLgMe}hO5̨TJ nT!v7 |?kN|`WoXYoFx8˅M8mrsxBmby&۽~ {Y4[dET~)y2-b; ݙX-Ŭ0f;# i5:fOE/p=K%?[ypo8pk.'፝cvh |"A+G[ /o2Cg% Z ~^ șV&d9WbI\.(<,FO ?p[jKTW¶c DΘIIַ%s [K-k4,"EUaFsP qTL\%oșC̲dűBf0F.!,Li(;@3{37p2w83ªwm7@'=obfRsƻ92q>LQ faj3na0T +Qh/UË=ϔ `>88R٫# vNT~[~WX[Uw=o˽!: ]K]c4ś`'}B0%iǟ/hR%!vjYm}#&wљzǢddLĬC!ϣPrPkRVrԓ1KBV+䔏;1O7S&1!"|Er&Q"Ά5bη*ꨩRr",ḏZѣJz.3tq mk+h\OD:ʦo [b4+ ݌ ؖȘ^?1A쒌&wBY^1geC+V1kyehg+jY2ˊ)=!,M7d؎a76axq&(͉ebv<xMhRak)y#49ׁիtH?O+GԎͩpPJY*C8nNH4>]u̇_GX>M)4 bsX:\afOEjr2gJ"Ǿ^e+*F21#MT,=&n7&2gE)Z*kWUmOKPu%Z1kqyYET 4Mxs&CojpOqn%:f'.)ID9E˗M]Օ-ԯ kufJNPm+;'~+ѣAXԔĻJ֫s^$>jf']&[!1`U q@MXkŲCkp+C(pKrlobd-{F6}oYN?o @yvXܗu8ǏG2ޫmcVŸD7vigb֟a 'tT>X=/*PE8$rX)Iz 6hxĦsFY""f2x~)glĆ&_V sƟe|4'jku]kw=uݺ1u=C:ԗ[ryQ*ÜsKN v=r\Lc, 0頄Ke~rI8rIB4|Kɥpt6ႄE- qoQLyELXE\aw=5|8wh%9SM;rfٜdL%|)ƽ'rgKxV}n(,{THSC$e!+m72CKLKf͵rcx6f4m1<&a;8e#?q#R_ ݖnͨo 2M3BJ"g%&ZGK)Tٝ h0:A9CxܪCY343+tN0M`xԋ`ڽ s!4n[ ʋHh&˃=ʛaXݐ_{ WYƾs3[/(dsyχhR=u\!Qr+oA_92K`Pl"fE0~Ө,f`S;nN5kd%v44OWaW@bOI`/alG𺬦W--阿IG^gx: TqХcDv0d{z6`h"?< 75 R TplI,^JI0-dfakI]a3rXR-)\KRqR~R毕0MNʥݹܚͪlxZIYb_f]gz.L7H}t&8էբ]鮝[p^DwC܅y#":^,Aϵ0iAūFیb{Yp(ïfE/;k&x8O1fN4ndO W S ;Sn^5{v`8;[aTCd_ i>m2NtLh.F|pq<ϼO1ll,>I&!#c1]׋e=x<S8LY\r[pzVo^5Be?b/q>j M:v3v&Los&)8MwDIH&N(j&ңmFcE5f39WcHS;Oɩ̉b'`x.qrfN*"㜒aZy0|J5l{%鶞~ |61/0i@A=(֩YHIUJn}-.ψnnJ8Տg[T|vPJ5-vt.o3k6nsEt>aA24$-:)g)wJ=2,IOB 8G4{Y {Eck:mR898SsRsWG`чn,;SYAv\ӄm9֞͸8ӖُS!Kk9v >1zV_J2z9ZYًFfIo&3/YnSM˵~x?9st5㝠NÎ)ҝ QDþO" 2pB#[m2Ru"#|rZS4;I%+&)1T-!vG9=M +2BU:'U$iHrcds$ѹJ,1/I"sX5?sO*Iix.-'i2 QT,% ݙ윝ŴI$g'дr=I/aUC/aIMö§'9N NW=-L`PtRX;nP{0a]6DžOWaVf_ʢ2 1c9=A\@uN\DBP^qѬ %"sR{Թn=,:ғ:@ןn虲LPOCǾJQP6<\Gt+/*yUdĶ® d]OPզѴl,Hxr&58I'zYVs)T,0tTӣ^b5n+$Z:W+I( |~@{lj5rp>Y#)Mxl_Ŋ8KRN|5ѿ,$fd:gۋƺA<ɒGG vŪ\ՆT.?> +w§8&"jo?ŗN#HKQL¤B&z}_l] Fo+Mr2)#bW{O'yMKz6g,][#še'_q^O&`E͆M` Ձ$UXp▍V^vIprWsg L]]>$,'K\  !lvBˡag7ߦ~F]hQ e>miѢPa\{{ս}rrK&C>kfo|CUΘ?ø8 c=nZKd6".#Hq<]NV9*TAtO9#c/+39lU=e|bV:9L`w:D;X=Ҹiir Ol=I弶KkXR-UIJWD+t4clvͅVlˎi$^ZȘcIR*c̬Π5ZҪp5S(@<̝d Yhw4We% 9q~s(*Eސ~tl`:TgHJ*9oW n%A9ݤLX2;p2I VV0IYW"naɼAW81ғ !Tx0Fz+£؉26ȩ+)t\^ʛ1E(r"\}[9VWpO6%( 8.c@ACб+1wG`Ռ3(Nb~ocΝ@lYEqfO"i.hznkV2wVc<&J]Z\+:lrVtm^#<vb=YX~ݝӢI+b ^$ 8[Om#5iUٵBjnrlx E\!˗gB9El:+3!sey^F/΅z"> ȼQž V$a#a1KB_;yfGt鳹 ȕr}г-*8rڝ2H2#p)WN.W|1Z<w3_uh .?n"x}1~3@1ЬW&)ښŸͪbҥ,g \rDGD2.X)l;}k1>9;& kzw-9߉7v&_>08ű*'=([@f ˆLYV>\w-Y&X9NdIe"5crl2P~u8=-&XwAJtNd(kQ[G"_wDk[{u*է>ENFk:NђGD5ZUcSMB#%G%x?Ԛ ~Ve3eM>93sL%ý3`Rه ^HtTS֐]_j<$Sƥ{’Ug&5XrŔSMXՄFgI#&Ub|řjjlvK}Qr[lW`J|g)i0W%swOlFyHi[NU 5^ʮ-eԌ.2+e4:RHnI+w(匮 7,1qs>6f3}{"D1Q8'g,~DKdԞAn dɜp6HD,9/$Q=Ryc9\^u)}jtT¦rtkx=3x sT ߮_&ۀ I71$FyГ F>4TЇУS( |Hyhzsp4Ol x՛A^I\MEbG4: vdTk2mcjV?E6ݟ~hjNVr'(gN4׈[ms Vp:ND:8ߛp#5L1*V=.tMbGLubZo긅ss I.-rs]j.h,ãb @KLXB$n6gX;3یݰ?#wt2it\&G%`*hЗyj÷ɞĎR`- jzT]G>=Wp|H5^ՌD$n3YժǗjs97\, =ަ!Kv2fHg\OUl}J䱠W5+3^eg=k}>^I8~X( 1tmDKq)TJxW_!䀒_~a:g=<݇T>]b/ I$-Lx&;atOƤ*KS[ܖP[1G6'-LT_qVچŊhuΓ{OwGxs;q*O .!D(dW2]OJV2FK'Gw*`1s3jm.򣿖MZ"k#(oEZ7.8<2TkGB%Zb-&jd ip2gj)݃ cz} {r~Ύ"e YG/1&z g6;&:}׀0 ɳ̘\ǒ[w"sDN0k2ݹ+pIbe jO_ȿUat`A; U!͋D|Kpҷ\fܦT|9X; ]sXx Kg)*0, H^M. xx!˥tV"rD ř5 Q7P 0pN+m1iO#rre!hg".㨛42_?gyƣ?_?IMB.$Z6/4ikܧ2ds=bQeR1Oc) 3*S/K®O+xѦa GrG<]ac&KHSBYxY 1 N`-1d\<9p=~Vg͂ݶdrd_V [ kG:ya6m:َ#]+GTMLj1a*XQ/O()8dNza/"&G=vI9۠I^{o<%v&x΃m#}A$`X,Dz3&)%MeLL{N aQylL!_A%>#Y7?;' ?GE20S8h[F5"b<.㷯sU bV*~鞕(ZUS^U\?GX54X]E:\mFHƆ9%,)vaʹ}sRp@5;ƨ!Sr?T2˹CRǞ?͙d0=bSzzš!Vkj,"-cEKxssۉ t$bR%%gFP7v&_m9\0'8cO`9wKEϝ*tvTO`30]v,5^6ފם͏ǂA(y2KޅL!fG#^qK|8 c_b?Vx},’nKxJ-O t]H^L6C9Uw|rzR*Up?DAv{(䐁eS lӃ!6' &^Ǹ)]'UM2Ff*#kh |ʅ3aDZDS-1H ⹻>I2 u.OnX  թfv+BD!W cM$?'Sx#⩓Ox O$21#11 cHGxŊa~R'm|i29vӉNH}zzӣ>&F=Vr|94~3ѿs/:j1jPigN)QKC4ӱS4r>OQ 'EΔUJv=X>̕.ؙ9oΠkcF7@TfM#?,Ƣ HF$NS۩UH?'ׇ82Lqy61KUpAM_5QT4S2չ^b[[^IPSMxMrp:EU'pI΄uosu!>nx>7i1c6rJiD1&T#4,MG#w!#gaƐQgc l+yV')ʐީ`{'-!gAp[-s>_omEZb̔Sz2wo(60/MCv0߄&xu#d *1,2:H1'vg9}Ӹ1r25%ԚH^+Ŋ2pC6PLME6^&lȝXj-0< cHaB̆!~Pм&}v8Ϫ^֙ѓPC]{cTOs$Fp)te`Y%[*yu z%X/x`%St}]KktLQCZNVo9nr e(8֣y KHd Nxs$Lk[Ὡ1iä??_`q",R%̬.&uzՃ* JFnaUjNS1-+3TB`A4Ce$>֋q(;f3.:7KxL@_ҧk<&e3)֗1^ 1̪D Mz\Ge)fMc!Qn,DmI ? X]Fb<ؕ1yi&7̢,rE >3%U1+IB{d*ߥg&HƉ)MUR)ߒtA_Ky-!cK9~K1TAB39rռ~!v]-7*T(k+wEtfٜ*: cػ'ǣ.Yρw۟ VĺCq ;Ql!Í,1jWc1練ITq6j8TbݱvոͯdNhYsABRKgMswu)΋1?ďQW~wLsj<-SP:tz3MբzCw1?4Y?ϸ(gE5[>JKl:M'4)Y¸*5{"xSqURw:jZ:C߆37p v"Wpu +3`_gZ3,raf榳C*%pQqZPe&wZ{WdޙH3>Ww _4FHr9=' Wշ|vNƱ${+6RLh_2RMKo.'RFRn $67^M^qKQʾ|aN+:QuGbAakB}Ds@4$0W8$έJ'I˄^1 ~p/Ť]Ñ|g2ZJ+8qNƺ26wjǰ/uEdbq Y.̥:Dq|MT8Wuh&U_sL%oW2j%nVŷ'8C05B(R(K΁u#/Cb\#/1<]̬AoP|O.[V׺k,LW6Ls@&i: ԡ"sGDk6oЈb[tzjQS5ѵE?"zajDK+#VWƌrtR&LU)名=x };hy>6}-"d0ɝ{=<6p L?AtЅG4G'kGa;_й<$F&.zw=H&nZ1%8Vf<,TA ZV2=Vñqz:8g@״ԟi-^X ǃGtq{Ba)\Gq4U|"d.")}Se-.ǿBJ yPfZh*Y43kYZ-_%V±;3q!=OU:עUkh;]͵B%-rW`Ѿ iyt enZwƙVӒlmo75s᪙#!y+NWᴵl ѕc 5JaDB eDIi_]]eJd*.n7wDwqsz)%l6ཧМ6XI>*)LdRAuo3$xOLA\ N\@7f 4TP<Xg$ͱrʈ^:}KdPtTȧHݩ![q߳5{O5&bS ҃ͻ[dQ`mۑ7 mtPNN\i2 .gȸ潈cn8.8!Ls3q0f/WU$ d0vm"lAچQZ7͍t41bw5YC}y\cPFbJXuh}YuUUS5ǫOԾZnT3*#-58RZM+K ctԿgJ, Ìtw,ci>SL^Μ[IX$nNv@eT6rVy4U0 Qr1rWn|( }n8FEjVRPcBVԳY mwT`"eo| :O9,k/湨 rkGg;unq[KjUrmE쭩G%_,t_>5Lv(x8IɞR%QT슬Zck8+_b}+fG,0lC Nۡ41PeDu᤮Oy[D V{t,C҈▯/nVƒΥ-2.z+3)Te_̪\\rV><__FJXY棂KT1S燂Oլ2J S"5hUlShMH=8IOP"hI9 8ޮKx4SɖiW*$۪PdٖJ$TT8Dѳ;Uۭrtxlвxx?8HFH2kR34j&<>S<*•F)e~G<4 QbUFl0wM l>?0)f9v4>݅0ԋ+C5ށlzw]S9TnOdG[Mqf3[`tlAEWԗge9.Q e_$MeQy&dLcKGrk`(0X"J4L希 XR7bzC?r4z B&O0C)ˍ}$iTH"6 㒈KBK 06sHXqR&;pxKNDCD_fNwI},ӏQ/ϣRK3흄^`~B^R5K[/1_Ү7s;sY&OdINd mpb|mI"䒽lhθ^xZ6 Ɨ0X+t;t&=+y0w'Oƿ dp>ѷ^xe~eLޭޢLBDTN8cǯEe\TirNA`n^١2Ѣ'eJ0Dݖ!6FŪr@#繠U/?5ݓ8`Wq]Ry;BeI>7_@Bl9ӏ t+Y*YHjfio紅ѕXVA˛4-NZ=?t?!dJF|aA%nV%.u<.\61?EҐ WKYکz)%x+ĵKp\#4ͦ3 `˓9ޜH#*V UmIo-5?O?8◛kMk/D̑}%&|RlH3J%]󰋋@6-?9I\ǛAVf)M#zk誴Hаzj=zZ'/D*.v=iOeZ6k[%;z+tEW+PwcI˲RsUHhbYx s#A'h:V46S,ov_k79N3y,3ut7JgQF&Te&ESBfѸ4#I"l|\&cNs |pƌ1Q0FD. ğ!-%N2Lˡe* L1O*l^v,~)? cWBb1]ǔv!RDy]"#Sy·~d2bc!e7R1~ui2҃,6>,j Q0 ԅ"[WBetcEShFI 'SuU y۽/ˢՂTNgӓ"ݞ_v̛:2srFťRg%ZN#0OG;ǝJLީҹ@Y'B*:Ψ~BGuֲ_*_55OfJb5 y?#ޔ`4iBfD6 7?'7q⭳=ݖ9י Nܞh散xbTgS'➹iw܆9*?܎f<:,ʧgRqmܢ [ˋ^̸Nhs6 4hm@@hsiy`_/IXpu<ܳh"Yn,{~tG"v$VO&3"gӸЇssqB,YCaf02IK`O億a_1ң+ /-nrJg/x@!7azq΋Dh^z[4UY Ÿ4A(7[$$̟'<)PTLei G1{]9Hq:PAp .VP爜r"^1:J%˨gTJifl{4Nx D,'- HBa ӥ)D=ms+b U"ʩ8.xx r RʠErU<[Z5N({ ZvC]-~G`}zh.nqUװiM!+3bLAM+1)RïUP x8a|{lU9`v]xsIO>ft7!7ű6IY%nFb.>ΡW(uQq7=ҫ>5x!֔݌iǓ==#JO`^Y"cIMȬhBSm?LĎwnlf}G냐qÞn< xf#W#>‰o# 2((5ƪxBFZ\)sJv] :@Rf(e n?b12}]El}$DT2Z,G@|i+fRq"-` 7*H2.GTJ])+XJP`9Wz]`$&CӰwl E}*\M&jy:ӨJaU:3ey9]ӹ=^r9B-:aPB P<9FBbl. 䈥,rP-h9zKCjhhb5hLI2Ա/IB?vs=(\Yڛgø8R9w$kywX&iǀGEh~.j]'JӃ~_)djO47; ɤ~I.m[7E7lM *z)rsٟEstv4s1*b.$%bߙ\O(DЏ$cɵ8-=u5Sr?gRh"C U1\g N8~iae-<8=QYj0ReX$I{dˉV-|Of"q2@gY?H+SLyx-匛h1IYMCw {b1 qh\^][[y2+V=GI%?{+rEN!Χ"Nr(-i`SW6cfӉt21˥jE(alVDLrV%cw^W<~,~I|oYSY`Eqa#aIr˘b /EZ <@8rU%GW_Ow ԼBՠ&\ú&4MW=N3Y;aٙ8u}6$ņy&v\?Ԕ5nuqwE*sAhK5M4Tpwwwwwww9]++5Lf>r%Y]ݮ ^`wbQ`:ug̀<yL3&)mMSkWJdǠhfgi6JLfKè0Pky0n附%1P8gFl'KS[, v_ʣ}Ȫ$ lr55 kq^> QV05Z똼\ljx-[4PO5Rn 0^ה5[s|Momś+^p|X)sqWd 9lz[L VO$[x n1RV}.<9],%[g+YYNO9I fWpZIfn7aAO±",J)g}2.d|$-_![ u 6$*پ)J SKyqÎs ìу^sh4)YCV͸{Um$qIș=Ogp4 iRtGL \ʠF sLWݎviE3h#4rbvh_giuJz?fטI?Gs`u2ٽt0%=AN8wioSFru%/XOyD&MfL k.\ .}`> eV\#t-_g113>S$ >l0[1TvKD6ʒI,/-%Q~s,bw1_sȥwSBRzMUP룖=PʸQ&$uE&kT ‡փ5:h'y`CsI.%B JD)mUEg%U__ŕ)!Ov<z/p<)ۢ %. ESRdkG&[QfG[_gD1DôW7)e;U5xbeף]V 9-*yX4|_s(.n_lߟ>GiCœ42 ^w,cŴ.b,P\I"[/m;Ki#p =Y{$% {{,< rt ēcA7RFPgrhKc륧 9-IO1L}ZH<:-5sE'|IT;%eAmvs)&0RNΝr\6(m5 E[o"򶏘JqQedۗ"%2ټy@f ~PqT՝2Vɰ.a\l ǷY wぱ7|)x)*~ 7+%+ 2:N/v_b)ʴb,J" hF|UeYQgADsu.C"r#O"hw ENT"POíz${fm ϹpBɝH>LpAjٮ!5/48 J VLs\d!eHMTtb_ 윯gj4P{~JRZs&w äXϑ/gv;9Ad\PS2|e4$G)d8[Bzq )|nepg_GNv3xQƹbgkŅ+HA 3GoCdc^{̵5Y΅͞aBY?*ghߺS8|*^P-2x.8U&u5 st6,FYm\`K NYřimOXG9'zPc SNU /p#Er=+6vUޠdyIh {z%Vw# ة3jXh3㣘{ə)dd .<`c1m8[CiR؆:P3a('p҅Sцlp ]5l{"S˕(y.)d֊!B ~dG0g<Ǩѽ@_?OLQN\rczCV 4k;uvخSl;)|QK1La}˛H'y43 U*650\(!XHZ`VɵkS'dJ) Cq#^A>B'=KlV/O׶"KsYO98 Xx_U_D֖}og1Թ sa?Y^L .07ZFș,]̢Ha?5{«8]#vKRqïXf`JBL؊kYt'(I+ F+ صw'u(XuKzҾej`wA|[jX O 6~Mi c楸WYL#j(Y\A/g9/˩#S|) H-+b}j)*TqIcS|ιlxcXs/~|r egܴ$܊S=ĮNQ<]P<1}7d10@ojvUDK ކÍAuL%.HΆJ$gF &Js! ;lFM@7a "k0'IC8C<]+=_Z7HVȍj.m$t?# ՄCikU2ǗS)2BኒyuX' cfg/8cDXȄL=9|U\wDI:&!p- EhX׋vEaI Ldi$lBìĊ_;Zp+S!f{9ld@?f}n-ZՆ鹣ٚԆFMp ںtUXfC,:uO9.hCx%^?X3^'Xls [j1 MU۩ d2fkYN"%is_O"=\TDaJ-W2@I 5}D7*ŶO173_=X+=1Ě/ō'.Y'{iofDv9x60eO>;O鯉ơFù)rA'CMӚ**L'^LrbJo=a4S/o^Ffdm{R0Յ)tL.:pD3{$Pٚ;)DžҮä!얖.mO7rAhsʥxYδqE*WrjoTrt mRS&Ci/sb^$1DMf,$ ql=_'Wr/WHXW)2anb /ZܬWBt|5KP>r~{`~ĵv!ΙH>6X®fr>d?*}!-Gz%u]{ ܱ=_;S_;|Opg›B<1ɻMyT$ ]Y Yˎ:FlkS~Cܚ rh\˪QQx@q{)$b;=oyTLb}N5̲.ϱQĶ1` N gNL@[ʵ"Gy0As1$sv6c0QAt8}EYy5Wۺq"½键.cv J55!#=3_9 Cд5]co?  C-m7yxΎ>o@,Y9U%5a*>$K_*RrBZCI7 d-'(Xځ>HCu ~Z}N #>dalOcBܟy|=U! 01{:=;ze75dX3NA{Jyb|`H*òO-D!t],p5Ė~HzʰYLCӏO_h^NKO&Tx#Ӈ&fKg#v@-4 mSBE+Mzv0gJA_^nĴ9 fFCzN=,c]`G-QLo){{H |Þi]ΟQ,BQ\ʰxI"&7 )P ՑAg,f't)ۜݘ6oCE*cҙ:ɢ,,=Yi j| [7<7%{^*Qq2>.>W;sփ0Kec IT%\L',mwSW7lp`PgX [-=^[lK7ͥYfdwcU3}X9keQI /){PT,VzE? <+E&Dr/URʥ|+fN~ bJh>- bҟ35FP7_ΐcL_,C&sT^O-%_ Ȥ1wM9 JrYҫ =[rKBMu[Eτ51Y:Jc r:LWR,>g6P|@ύ: [yHj 胎Ov$ nJg&qa\[ʱ|dx2WJE.*q"'&{r7mϑf>Fw2gHCH#5Xұxʊi;*rlY' DnhőI@6~t_^W CGN"a 2r8=I]Ն1u㚢cրJ)Y;vrŠ <{e_Kpz؋I|Da'K&{5H `>dɚ+3)L׶`1k8s&aR's1tX\F5%EBp]1G80BmM%lY\SG1k\)SH<r'ҧC7J(|^6,堚Q<2aI#JvbQXǹoMр<}A݋谰i\%cGkޞ!vN|FŃ~-u%yi0 tԪTí1fVPUڑ3}q1c{fU9_ ޤbiC[ȟ[Dkl[}%ti\R mV¨LxipSxk:<{wQdxUQ|έQg'>A|?#JZSs-5zG\[=r VRӕ\^y%r4V%6bo=]r'P>&RSzy?{@.bn Ly{0oa؉1:өM9'`R̃7o9SϝGY> ֗>s\J9q4n\!cK"3oYՉr{ olwUx;c9s-ggQއFa<4#qPHpfh_۠w0Iq\"SM=.sDi٭G_-<:i3r3QWx)"ia4EKvHNsNM4tLA2m#uэDf>Mr63Yⵚ[v.~AˤТxe"5씼\d,565iSj]*2NhJвXF9rX(9RɎJ[X"ʒtfƥ`L89y-_h_>PK ni8cSMU?QWJv50W"-E_.R@ZF=pFRTIl{e1/&;mFr,7Q1EBލO}`!\hEJ{(w`1 `/fMf4 fm82;HK62:GJPO‡u\YqхXBL; .\7qE~^="],fsx:G>8-@3?)qu FT٦1۾%BS?o6}M/4-X43jqP[柴G|^y/ C ­:umSU,W2鍞)z?k"Gm㷂SJ0/˥ ,o]bɨ>thɱIp!7cœ;ے3ÈDsl,ؚ(jJ}H;oJf "m4148aOE*a.m{f(p;U1,![) Jao[X?4I(%b_1*6ӏ<;ٛno=v֚Ru5c^ gl*6p$I,yn Ke'-F֍mD;+i\8ǚ "V }$C_৘U\+lw V ,(e2~WkS[[1+wMχT 6{_ˀJh'T_UR)1_A ^)9Xp 3}A+@}s=ン/ ݩ`qJ29Oυ{giڢ#ႸSzss 飧G k/ܹJWZ6F-ZNSA2 $8;4b8.{ٟg:oEO<1aG;7c[B70665ci8Øյ"5>(i'xvQ;rA%(0x{ҭp +B_{q)-Vzӻe,!qі3sN9u1i,;~A`G-6i}ˉ*G=\u1n*y[A >KGo %5!}4Sɀ8=g=Cij[*/-,GO[9XE]W%zL5pGt 2TM8%7:l4NǂG/y=%^'YF?p u@\3d|58ʃʖV,4D<}i5օ F[nϥ^ĚªOe}n1)gJ>gA@9Ʊ2>/ qw#wޓ DCxК qqb.ccy)'19+5>tYԲ fà?c^dVXfw#Aں#Vx3fFE?([QUV쾜 abE+9ve|,gB%m4dM/^O0WZNLM +K͘WZo2|b^+%{1j[.Y,olEL~whɛԶYg .V4+ d` L)rflS\4y~8X~* )q=$#+=aMۈTh[`cl"sITsَc=&p'mbyg#e*Mse~)I!lⰇ/7ވg8#8sD6g2jT0SiYG' (fyZdZW!ל6^sA>Zvk(֒[ϼ#:&,KO='C /]lR7]OU_F:ޟ18EZ>>KCdw947 ^RM Pv᫞}Mu\|ꠜ&{e͓b~ ĉ]:F*0R/0LfvuGeq54μA\8'Ǔ|,hג`ib E=OE.މ.r: d=W3j/MBOYB. oR VJas碕5wfJo;ܰ]7e(MWŘ4܌rx n8j.\jo_<?lMoH_.fd\RJ$>D'ڇ>̲O9Ok{KFN &_\1ʍl+ġ%ܱQZ35kRUɽ9U nN*<*@+Zd[gw 44w3kYLEA!#sn@WD&v?Ljfq$fⱮG5JYдOKPL(ǵ*+̺[˨"STG; L͙]2 ݑzѹ&{MqH1l- cP 4ٓ13PsRoT2 d%L6- h[|[Q8‡Ǽp/)'Su>1CFÎy=W'Vy#O" g6< A쇐'{Zheev02KDn&2s~sՑ%j+.  -_^S,wnl_̀/,2+)\e~ZKJBqG륤iܷS]` CZN?b_IINLgGD+5ȀW3uXLRF$BEXFωn[@w]XF-i8֥[^*FrD9_%HN2r4֒Ǔe|J3TW𲉌9Yz8 P: XNACٵ|L=z]q=.p)=G¨&T} eC4C0:`Mk_ ݣD< D\ȎS_mYJX/5xIbWD?$8&"B]N<>~}&q\C5ʋj[ʅ(N `IX>x?`5fe-o'XuB0oBH~F2x?yp'&5)j==s֝~ʤ [ž&AxuC/ɒҰQ,3U;D tb>Ӱ_ԟgL-Ctler&9IX66Yo32P1nbYAώ:>df9ZJ;3~<(v}wџS'}j!bΣ҆Rɾ:.WRQF#]Xƽ<,7&`~4sbx!<'eP̕miǰjJe/2:eEs;0xmgɿ-&f# p ģ= iq87 EFzrEcV|_ȉ.45 6?~vd ӎ0Egd<_NaO!ϱO(x3ӧypgSŨɋ`O쳽YqjF)fu#S9s gf-p`]3xiʐ-}`~MSz)m#_VX Z?te_4K$xȪM֚6F`3+,zg~{s>4#t]QJ'`K0fY_SKFkUDdc$g圿E16Wa!)I15Z]+g\%S+Vj)e< Tq-COy<峤,DEuN=hER&S7Wv;ҭĝ~<GS65nbrOBi1%Ms@+xUA-ϧX,J3"؎E|zȜK؈%)e\.t=]cBڦ`d4V҄z8 M0j6>4K 4Y̢I#YGfk{қGMYg9lk m&ds|\  U0 !2 )*aɇ26sj`%(ffbϙc.1{f|/dƐ-ϕp]kU;Səե}C)P@\1y,nÉ#iԕ{ȺE eΗjg#VUu]oͧ]ـ]xhmrwg](3jS5-JP?RgP5i'1j[}qTV_TݙW:Wҿڴ$X=arXx ,SBp/ZŊN pUѦBhk]Ӌ+ |Տj©/؟U?;ֹ,__Y0tԘ{{>94̫$WR<ɻMZzw!y1q9ɳMl vC$"pKֿ9bqwU?Ɖ8/sފk0nC6μ H~ n05JI<Ø=1-Bv$EśTdj w+Aa3Æe!o[XÖMU"s@;Rv׭OJƿ/$fvk'3˕ʬoE\PG-A.$p&{:17ȍc/"B͛xa֏#;HxY0ӏq>tj>fXfxŅfR94iˉ(t3˨D"gJ.ܮdM`[/~¹~#|1rD y4o\I41%,^o;ϒ‚ _6󼰹h|‘HOtX@Gv,]`Ω=4wkkꯀFnMsT" 홧!cW4qK7t~shcKFXO'ٞöp+O`ޛ-k;tɚ+Ūv!aXTaOC > %„JZf9Hj8*p.mdPN:2hO&Fв{ B5D\("^,QU_B*h=ʩZSWގxd}=ػӉ%5]ӇYw1kœn) C*18㌁|&ڭ?zLS&^|'>*ܵbHv`h=m_ӌF:HnbΈ qHeŢ7zSP=JݨYכhX_N4jIue1~LK bֺ|6e=9FqrlϽ1 " {nJq;qƱ xLbiUF*SAo%Ěq|[O$o[-ʉvP4vo%pbi`~#@KV-<*sOER Q~.,qf!lDL!It]k#a-|GbmgF JltJ h)iu *ʞݑ=!; Uԩ5o/al1#|X9m˘YdFbI$yhĖSƏQ}g8Lh,Xo4vWrTȖzTzFe~)y1WKc,e%q:Pm6[,RHxno3L(CMPX'U=NYp.U_\^| _!z!<ňMŝ;K}+nzwۚlC"1wS]$U059W'Wml›RUx_|;kȲVo':r(ϜvH3LD<ߦSۢñ_E?#CNh;TatKs3-慐o%3A=0./w)o2s#>P o/ؠ~]O?G=km.X=WX.-r(|PARGsQJ>V8FpnSF`ٛhNO* $h!d,7d2NχΔ&szuSD|qI]Uդ$'(݊Q  k J:K􆯪2KڏSN)r }˖^|EvK7^qM#8Ӱ?/-spxCgG`N1WS}qvc(PO Bz||uhkDfad{.qbKg _,GdЫUD4WIݥPb#-k@NIb7td ~KL~]_ Ѷv%.eqH/W`>+2S4q]"JS,N*˒kԕ߽pͶ,B >jrݽ3ƑNL/"F֫v Ӏ-ѝcZ>v /^"fx+8ؖ$aWSmQvcg.4WƺsAKjcg]glkǮ'vړ5!t=ki0?Η=2Nw}(9C7⨿ 8"юԯVL ãXP*BFiL36 +b>v"SS}Qğn|8If.`+7wKL2sUlA4Vhk ѫŲI<Q1!J's 9#ɑ!pg֫*vD/~Lce|dl.Ӓ8oÈGv 3cb%VZ-{Z(;DEn|v0 8F[ۄ$;g_Ntğ#?3hUKu5JN'qD$^oǮcx4 F= ʇK̹¥maLB=>uu؁wճ0CJݻ6aPKޚf|WӵI+qƯ\+I7 u2 ՜͙-f}[Av 2G'5߃9.I9D #0~ ILdb?Eb=%! mf8c>͕a<2rn JJl,_/¡91Í^k|<5OaFjvxjE|Xu^5KSGb%Йxp֍)1Is:~+3x?oil:XɣlWV͵f_3nf fF9G5V5Fr,|e'S] lV}0zY['c^`EͶL !*;3ù =8̑1"ĒW815d͕(6);;B=.-_?ۉCɬ/[?[^OYlT^)PVZ-ڍNjw֔EѥMoAa(JdD \Gp]4[p5˃ ,:PeB=ug3SP^U@5궈I[٣rX)+Ysπm›t3ǸpcXC95w.l0 FtFw32?.4A׉4I蔥NJ1x fQ3z0eOR'nu)r#?/8~jŷo+MFZi(zo9n]Tf`Κј9b~̍wupZL#PYjȠFF%hug¶3Vr%)s#=B!CӉhk  RZ͌Ϗ]YQ(uzF0b0@[;P`uv?k!l;DH^0 @A \hCl1CTC4>N)3N)=m7AGK zYUw6%.!CLtA ;܌s0k?4Aljfia+3-]%x v}o.c*8ߊ}XEͰԹqLhG8ڎNܪ<5Ӗ|z65^\/COPTGZ2#)B& Ϧ1س~-K8̉:03Ckתq~ץ辮[.dlvua,L-ϝ(ƍ(7`~:0KwXpHՉ ފ7DkDo6 ifZ3yRP߅*k&Y=?G@MoN^+ڒsf5xR#c^Ml:?Ӏʶ}Ռi5Chc3,ǿ fwjoYKŇ <-CiuJe>p}IR{hʿvA(0[&l>p] }LDwEkmA02Î|;mv#*ݘ7ʇ+M!wFsa%;tw^8zw8q# A(4Yk :i|g^n#ϊ-A Ď.kj"qqiK̻[Y]||,ee-~=IH?}뚬C1bxb4*Rgl@qFjWtE*Z0؊j޶x]b͙ZwMݞ\WLf`cGՄqYEB|Rd5;,QKW(*޽j.:ڷ: 1|pw7ȍrFz6:j\yU핪I Eƒb߁#B1{% 6!B8;IJ{aYV?&sJP#1.C~-j͸ax^/n^$ +1i=4H`XK_u.J˧\Pu8~'I}I7Jc;Ev"es]sBs!{g:O)V~JJ'[^>T)sVcG(I?yjIrn"%MOyU_j3z;_=߃c8 GL5ꆨԘxf$L]A ObӨIFgL⽸)n%|\g=`؉WQp{zzX\|:X]6AiS2V,"ĿlqTvW=UT)m{?JXJ9*(ٸ8}ٳM g ops%?~[Th :=I1UcEv㞤TVk?^ʰɵJƸaiKT4.(ԛ墴qXQ6oEсb5{-6v_>hE(qtxVR> j,3_ uƧ5N颉د1֓iVy$x2pLߡb(3utk9.TF!^XZvqТ`-dE/+4ş~bl)_jSt5QGވ?J] z.^MM[MV]qc;.wYG~*d4IE9БxΊ)܍Q5>hX]F|osQ|)fo?ѝZ5Ր7Gk1vƸC 9駋W&Q X8^|I,qg*o*C㛙oX?SaZ."S13HT8њ&~$A/Z=˄.U&oФWW-1݁'|iɕm6?ރeAQ3# } {~GG(N*> wF&$u:v;#Pp"Nj|\mvW'v^3Q5;m ۉL LDwUOCuu(Y'6 ~=a^ׁ{-\0 T-- 6c HHZd:vq*~8*Fvo+8{WGxZbH\]ײbBM. e$¶mO 3ȩ C>OK^uBkO$VF$59"M;|k0:QkW9`o’|MWw7y3S.DAHՃ:F6 U8]#(6Tg-yl]:EjpS)=w5\ jv>OU,4īIof#&@}*>iSb\[fϡ>E20RCX= k&{?.XgbF='C5q{؛: ,n0ҝ9Z=(*Ӡo><=i [ҞN{l<DŽy4j&ܑyfSH #ʼn Սt:TZ'}mXšF~ ڏ0fَAEi!؝ĹNP1W_R'@YutR&.P8u8[gPkϜ :/=9}5GδQ|1`&o~ϗā0JC.y@7XY_^O*m/؁*^OvG++ZسL_4{)u*-Luih`d%@tCy_>}YT'Yk;lFXqqRoċ$On1LؕJʶe,#ǰ>]TfwλԈʙ]а^i3; }qL˕vkJHAkx;ѦiyUnO_e&GZ\W/c9F@e<#.yq &yʳN e7X49,D Q57&査N Ӭ\_c1Ƚ3 mzAu٤>1z2kn4<ʖg1̛GZAh`7N6nщ{\6A<^$ AP2NUU S~5| g{03"́A<ޘz†ъh1ysV-Bngf%p~tӊhyXL(??:ѻY fl^x[]] #%RMܜ8lt(<"SvT O囹 b^,TX[90&ݏZJ9F V 2ܰW%po[ džٞUߍ<@á:iR+džSiGb745WDiRGO=@g6~=Z{}Gj9/*zy=u8 X&>t$sR1E dK ܎*:NAWg6K<*?eP],ōS-5ɚ_L_G4Oc5?^B5=|sa 4شjo<+Jϕ qv)L!ÒޒHMckQ.Q)zQ.%sO7KoKu!F˗=pvS`EQ|Gv[f,՛Ҽ<|YYǔhƺzי*#NqeV6a11&(<œ#Lukݦw .Lnh [ |b*GC5 0su! }ذ1x[Lf*M?iX;Ū[_}hfآ`fA8fqe6/c&#t0ۑ}*l: aTχ Hr#?dcj4k'Y>gG/xr 5'ќ"ø&+/sk%bF&׆}y|m(HN7dC&U)U-mƗS!kA%>VܞYZjH[gWs~a{ 1kToZ%+@%w`r g"p(5TKhPJLg*mV}Rjud CA0w"8v+;Ҙ2=mٽ u6h3Mz6f>34Gf54db;mY5}#7Q|?)1]Lġ5'g =1 ?;c GCd:~?_V8ޭԳJo\sԵfG3r( ą)K=,{ EwEI'.=5>PH}kʾhp5LN./EIf//|t1E`tƏ~f'oKܝI i; =y=TC539LxKi Gn6U |pf 729v}M9oIM[r3-:~ bM~CY.ke1q$憠Dgsv*DϠ"sm1i uwCѺ/[@Sݯn>_-dm@%G(n%0drW*n0Cӹ8!3:iw`FR4;n_*Ƒ|ʦlǖ>FYcrz4\kDfЩ^ğTtCkbK_tUIx*ĩS) KY'&xrb% /` Km*?;{ch0ɉ OQ_ʼn6\7CҦpd%:;2&y9ѕC`˃Z/FUbJpTW5oX_%>iE(6nL6"J'd(ń+a>IT}k5fh Á{݈)1?Ά{B=q,G|tԹ QESgV] c$V/Co]zM N y_dD;b;LdtN<,|X6Սrҗ9Wyed=@BlqёݝH`0K]:*l #U˓4D\͆|0Wi3 .'s0/F^9Cߠy%V5 Y]Ⱥꏻn˼ɒ묊6ƌ? 'vߕu} v%'ɓ}\9lAe 7ޣ;ӦV#i}=2vYAyMꞴ;.ƙo'1/l?.>'K3 ,rG?"ly٘թdm1商Zx5̀/+^CQ=ffWp9Mbeǥw4ܓC= z7J 7{S̛.\hd.}#uٙ u0 P5iDzH5Qƒ<>)zlxCN\cZrо÷Do#qJxn]lgQ|,:yߛϐo$|wnc0oTw.Sg;&QSwtKH,FL>y$EB46 J1cio;Ѱ^NoG;ęsr SS,Lq>i GCzwZvf+5ja̖sՌ8yo &P*NcXH`r<s&ˏ_Ayj+[Xh.dR`%m d&w =4b_o#Z_SsؽJqFPc_7Kl|)ƊX1 = xv.i~ɛmɻdC6|^:ZjQX{ڎiS׋7:®5:v̨r'!*NcY['yhZ0ʟ$J M?9Ac ~ !&6aY+kq Rlϐ6tjtGszO>D.[.:9űL HՔ6zْͫI.V܏Fzy`$)Sl3˥$%&,ϩ Xnϕ46~%LTgiI0mgz>5[B=[0v@[pw n4-q'og>YEu5Խ91j`Y(ͦۗys}i5nDĝ {!Oiuኩƾ3>efZ5Gt{0K್80. h4G"xޟ['qUSeg Y1-QM&Ά`SF3[o&7QFӅMPJp/ r2;[tBQ b$fdɏ,.=ȡdNNa^O.63FW9:sZ%:2-eMJc),o`% TܽfqOJƭ>ٰ9Y0{'ЮGfWc`6)$D%jH".adz;~A[-WWq& R̎ev9>t#|I0+ߩ{%V̜[|kZ!sRoP:Ò+,WV<5ávweC 5}LxjŒiDzGS`1i?n >%$d;v7Ћ`ʦOJבSGYJC}H7"9#IՑv2H< sz[1 #gXhze8Ѯ;n]/6%x0;džsWhj3Nz~c[Z vn ]~:q5}w8IM)tEʅgT?&v~Q֋~; m8l9lzUoR4  tݝZQE48tKʪlXÖbYZ0"d鈱p gf2tl")o"a{B4nca/&lm;V5C#RM.{땨!#C$NfJLg|JQ+0XK]X)#QrR 4U9nԜJZM)ce {ݝ9cZS5ɲncQ>LRH=MM Vꆙ4bd^m #z78PA X0h__V9)kL+MՈRqLiGEG׳2;śۙLܶ,զRR5N|G]AБJ(WɴUZJ{DfDzON; ѓ_r7BoG`_j;S{)cu*tpW: vD)05~ugR)c,x-9w=z}ꇛ .7{8g(5704+:kX[Cd[Odܕ[i>hϥ?֜oΉ^و#8kV?lÙlGӊ:-4> kˇEEKx[$eSNrdr͕}*RX*0SöV昚?ed3X qm1 `9ڜ_8̱ZNDl8s~&{* s]d߿u_>U4_4kb /L>8ٓE=1'ͱxnLҝDbiDr~Irk1\ $N%.݉Yif;FG 55h!WC͂CXlݕc>8}[ưsЗ zȇY[RڟSXi2*WK|`ޟNUt*ͫx%kQ$#&(JzR3!}0;Fv].` ޖ}(# BL)kgƌ 3XF`z8ƥ02Ԕa;_vwbs,l&!.[ċ2s[3ǐGFx͜YKa-C1JgJbtrGyvG *f*x@*^*9z@ͯJ+cL gR 8`ߖ؏2G˞3v7K5?4<̗1ģ$p)KUWGnU:bJr/zNY Nre KqYLtI,veM/DpcxLD:G=I{T&eFG*32Of; Wڃnc&Sa`aA .5Q1ܓlwgK4 1F%Rt燇ceMΔ|'ԣ.6X{LD\3?xP7z6L]4jCWQҗs I7vNDoaɵ0mo +F.ڞop6gq\!\ڣ(eR l7V`ؑFcs6nDQ ZA>4䖾nj5Tz\RE A9me0x JiWUVe\ͦv1f5i31!ҕ]I=jB(;2g3nO 'm8-*d.Le刕;<ޭXDa/"[GVczr<M`d6v 1e wc̕+Z:s+6'8%J NmwX!Ԧ,eB5ʤ=+Tmʫ5އ0.侕=mLbF(DL~ B0>OoS_?wa4OE;[}oX}. h̟ Y>YɺX,- (& )B+\@…D.OB#ǂe2R#WN\"Τ\djdm%3B)%$Ve𽆜cUSZݣI >GZqʝ0i:bJzGqhi+Ry;HNzf8ח;cN8B1YL٘Hl@-cI;px:;l; 8o=ك8@/W64-Fp 9f#.PoО[l{Y-bh&n LÅ`~t%.7"'n nFM3^{3g(>TpZI)b<₅<h9gcKiIBs!n,Fe$Ov`cͳ3ήUiggxY$s Nr߁7&6O̝&,_X1r_.gI>Ko;'ZaOm'C01iؙ4Q(7\} (js2!]o˅!ɼ_URrQ5|h4LNWi9Aɷ, XI5$^pmO{.}*?bV2Ua2_|QzbqvOCH܈c69ltC{lsRDT֡X<@U9}ԓqD», 漄.4)dDy|K,]JDa5LWu* D>X=񦑇bnQ-H1g?H>ej# 2:_pDf; ~ԛS7B]@y%-Pq-dxD:zr_+]>+sXFΡJe͐`q+5 CqkWj*N,umtH%l@!vT cOE]6WRz|umK5юB~ 2 UtkL\2$nlkfC""MYe۲7[gD$wS600*"|?툳~\9X6;ő㌍ʯ:2`.J,v){V8p<Ǽ3eh#cP2NΐQ9Y’b* mD մ_Ѷg&fQ(5'Qrq]7.*,QQwjTr^IsZ*.Ϋ`b vXJP *އUS>Ǣ\ʣzN І=/KUA?J{JНs'"0L[?ϪϘm8 'aiN̥nP,jCy]?ȣ[~Q91֕ ^$!˹{'-RC2Ki\|'%c%?(۷RWsH^bÊ9eM6 آ*NT xYڣ Z/dVI˗.\OAjtӳRG=l鈝G&x. zvFRO!JIRo+!LʯuW,;yqSKm,C86 Oy<.gЈ|:dz+\]ǖxg E'"Cti fV]E.l b1?OۣtMFq5E.J^[i+&uO6oR9CI(n#$눂v<бeO-i"ꊊ36jn:AôZ0$ 2\Q f4\M]UDP^Kb?!4(o1V}*:2{%d ߾fq$#Dd?/soYov ®CVɎ(-+dG1 K.!X.fK1M?L@)VrB9+^ɠm<-g9g&N?]1+ Ki啴PɲJn,Ҧ^zV줔; LVd i"tQ)~]Df/*(zmixުe#=VT-&jaF [5Xcwj oVYǑ7ZX NvBśiɯGz >qHY9.*"\4ȥ|X&efsI\νb2>c8YvoY߻EG娐W}?Gyk<JXl r?1=0[HÚT4!oq4Rn˒s jE : I:cm;=͉& )^;k%3ArQJCNjN)1Qb}B a-A[,ת?x&[>_J=ٕ[@q˘PNg v@^JQAEh |)bfW)`l ĉs/8gBqV 2.c .a'CM2Bn)>V _y['*QpB *bix"S̝ U5 :aãsqS;tiSz|=%E}Q󹵆:o$^VcQWc5]hq 1rK,ϻJ7I}R$䮹yt@ȇkXNW#рm ۊ5_%U$)CЎ#4aIN}Ȕ7:2 7i FF`g)ɬp|~0 oTV`ռՐP4=~2;Xdwh扉Yw=|ujhѲXJ}RS~oCuu9%E͂**v)80\Ay!C+P*&o.@9)2џѬ 29H7" N™%Im-ږE*%I)De I/#1Y+J4,ƫyhNy,`[!JP(A;5a}&m&/I 28[?i"]73'}s1Wz%uJBi=({O[9*,4|l>B9zR kصSn|#z: _ƛZڭ>\Þ[zʇ &*lk1uE-4LW%(D[qxEGg)9IZ Q4Ffvn `BO 5k?;*fu&=[݅}M[$=SHd̝((E Zk1)_V &pK$gX8IJYU -4vU!vQr vKTƟU;W@6EAJV? !`e+ =o{rzk4VWsxZ2$ʊZb1֮e ('/]E$Ec\v29y4 Dmri;'X+FtO`)X oJ+i+<.I a _N~U1\G MEhGhYRG{jkI['mi: PXZ;2wH طjA#|-I_4t԰Ùh-Kj^#RN)H[,U,ګ,LY3$ͣxn+gGv}l"iD7x;1({*'ǏLMrIolG[QM jg@Ag*ڌW\ECVm԰:ܩx /ss !qn^-j؜_MXI8_G/:giYv5#_O*O|0]Ǿt5SJ<2uDF戲D=c({+]+&sUmiV7+4G_ Mܭ5huUKVFDd8q~0#dM뇳+s2?E|XJ.rڌ]yC.g"8rƇV3;Y:U3䁞ʼnzU?6cjT_&ӹۦO-Ѳtr5#T }CU{UXj妧`gT5Oӳ!ZZtFb ݤ­eZ>&ZR6kU_KQNRtyxH`g J2b_?JhOLv˅\oP$~zܩm"<֖Po%Mݬ 9#|Lt flX|bW3%_y4f '`w?tJ2{"U⎔dz0?wx+x[ζ ^VEsWS-54\XZR頧=溦x-g±0uԨټTE5 LAw!DKYsF.k,Pr[9:U[LlafhX iė#\?O|]b z~6_iܡ"6$vܐ&}ۓm!!NѠ|z /‡2 jI1xd޳ĺS`R!٧]5Us褞ۧ?պi C ZB5\A{ <^#њ7f-õ8aVT\!r5]yr<$v3[Z΅{&hbAloT2 9z3K͑E#rV23B&x'krS&Ss @__@Q% }Ra Ibz,hJ+ws0c9M%}2+6$0cVIl:JYZE/TR3QȨIe̷,E/W*TP)yrLWapPiZ'ֲUfI ߄X0R:~ LR͡iJ2fv(h])S"cO7dᶿ5LUƚ]y䑽;P)7J/c\rb6sX{>cksD*Yv}ʢas\83yh;7[2 :$7 *T xÊ7f[pu)+b=Sฺx}Jx,Oc j%ɾjVzk+W\ˮy^j۶Y\Gͩ){V{׭_[àzz4|r0a D5*,WqZ@!˲Vw>"e[x~J37ĶoX6O TةĜUJiNq b)Qx`}{flzdG*)|N\BAVe3- P4PLýJZKyu u E^TߤH`2~nؤ0sVw*ۭLv_ϊZA| 5|\Ĩ92~cE4Iqam)VH ți.4u #loN 2N6&LL%E6/ej5|A'#[pCբ̍;^ P56x-vܞSPQ2+ %R2bEV5>U$3SMb 8]VT2zR`R Oe;*ÿd(X2k_u9~Ay4=}oMO@4߆ d2QN D78<̣}H)BԥYg'0*>v_1 sY='ՓM %#u J*#+bv .EK4%{O-g_ DŽ5 ̄t=z:xbx^uX3szm[:YyR΃_ R޹I"_Mʉ*qpoy LsA ~SXUȾ9Tʤm^8t>!D݃wwm[ihY&, x0Q)AXysL̛{X#9=ejȨ'+F{'eR2FFg)\p # ̈́>z'tt\[6Q38wk|^CC?ﺚ˯tRӪU^蝒ݧL5 URˋ65kRïEՂk>QC(5o+7*U03o|#57 4xVWPwK(xu+̤_K0)6=+i'V%UMR9S ֖RZqU@aj2.D .[yG1qa%V‚q1{w3U 53MbD~zFeq0˃X @V67㿊^N-s zs$=5Ju k1}5tܤ@5=!A=<O Dϩ7d! Z[D,&verKOgΌvlzM3,T|ݰJ$!T~zf nēEҸ\̚LjG:=b Ҡy 2GT`Τ!IDRYUm5$9UJS$X"e**ײYBNR3e6*RJ9-`a` DȢ_,'yqL%$*"YR8Z{U4d񌺕Ɏll.!ꦌc d6Ϊ!MȲΩ:LUQiYq@pjRGXS3VQEɕ c%C|n/z sw,T ?ʘԸEp\ LmRDKH&a]99Z¸TR2,9_~@wSJ8*(9T'ZaIJާ%IuH`òLc48#z GqДРk??޹z]Ǽε]izֲvs5]O9CK1%&/%!fAG ^|]7Q1"c¬\S,ݭ3N_\h͆a?H4KPL/D17.44ɐ. &˗ '>~GY"QGW }{Ը@E#ךsT 4 :ae0Nx/[ކ:) {Z fj:ՓfcuOng2=DZZ6 jDBPӠJ͐\)u$>m}5W:"5h|U9"Juz{Y\PQ;jmxW-6cϮ>6-gNjhZeSvn[8k *?9'!Grȅ6A*+IJשK*TeDw^bF/%a6+POTTH!dv"B/;ʗp^䬜{l8*FVT惔+ٓ!Z%WW`1*2;+7Xβ6e\xyY|u3XU!䫜 J9 Rhac fU )q{X5KIugO6*iRNrq77]kbSMcwuOcN˺$ 3FDZP箂ufV2skܽK:jE _(H''*&tzD[4emFg:G)]D,bĊ_X}c2U,՝½z޷'}gaO0;~tބ-H|͵WccQ ч޽aa "&=ݙ ɼ0!|-ju2L7h:Dʼn¾TV =Wc'IÞTs㈆*=>S ., Ly >|*}T4d*667Y/bhttQTј狖4!Z=OuѮ1-Yչ ^28{EqwBy!Dnt-ffA!?ƽ6ՇV>6adN&|<ׅGSpɩ#o=Vz53\9!u{ T;SʼnQ2Z`U։A9ftkg[ jk*6~qa~tvF>Қ 3L1c iמkɚR64-j{d.(M/츟ʥ:_Zqn~$ 2 +K;i  ^󄻟 e {> wD \:j>j?Isnc5+WOٮeOUT@RB6Y.LJd_)Ws9+^WJZHOE~E\}P%?rQ;AB,-1/ڏ* F({՛"D9&'de8 2V/!U]z$jBL2 7i2TV l\G?ˮؓ%n t#Q::ë]VYJߪx 51wYƳ'Z;{**x]RNUnKXE2('jak1VQ 1W'5x*y|0RIcx0X,r"6=8mOwϨI2 O Y/T|EmX'B<70gn J:HbgP'ledר`B;9:uG[dƲ"uͧoO M1ʍ04!Ey sed6]s6#8@ɚU䏨b gTF+q]DCܶ}y,ix/;Ɔ93Xgk!j.?N#=NG huT6跘.9bCvl%c]g`chc;n_$ʅO@%[.cedС!ۍ_S1'1l8sԖ}L?uvg8/(L'y +"ȱodSi k]#zd9?y_9VkQ.cr%Kѐ37_qJnY;cxlv?vvo~"XyXX൰E'4_ӛFŌ9Ң3>p>;뵩jiN/\%eD q>-qfWb%F/9?.ϡ+yi%YdFk&f1eu%"+ZόΓEDV7PdJ$(FeM}>Y$<ᙺ?a2=)qU7wƷvnC41yy]8apJxwH^Nl?VXQIVG#+fWUxK+ؽ.+#7TN1{9;\W;LX֯MТM]:,3aFs ̰Aؚ . ~5N"d*njc^xt:#Կ{+dTM/Ʉ1FN8$o*|h{zD "%]"Dxi趇RY ́͝6,px#߶8S6ά`3' cVgNGa.ߕrbJG_YJ+zyKYNJT欂sUΖe.c# Ҭ? >滟f&d';gm"{&D @q4c˧p?@``,M`aқݒP>Ɗ9&YRr2Ȫe$~E.vGr~.R"$,,LS,ggt6]tPf i GRԣ2)I*b T/#fYWĥ쎔X9?} v.{ww~x",bΓVN|z?+͈Vr6!U\>\Ű4F5Wr}TqcSy`OйDВNVl%08 iz{bתOkќB)$.‡BVOqsh!gP9 4lE49>e,E)Fc?%sBGh4#Tk~F ;%=޲7?uscp~I5x4Kqt>w04Èg=NW# Nɭ݋o $ge"#R* ,%q!ehna 㹣 F.foDNV2W)آP~Bԋe)n\sJULW|%Io͙5pM'KӞ ciY/.zK1VcƯ2jD`tW60=crYCZhy?Xdds!xu)r!9lRQ .ΤWf1? ӹm(0cs'}Webz6/&٬йlO.`g΢u4E:XѲď޴0O^=b' ͞{iQ۶\K,WkwSc_ŗWsyP+8E\=Ruu] gΘV,@,4Cm1{[2=fZdZcNৼS2SؙXݜܚLС=SrD̛-f%;^tDԙf 5TiȲ܊sWZnpf*K,58s[hZ1+FtxύdڥHO X!^1 Ղ0$~ Di6̎bocK%{-y v˩}dۋpJ*cy!aϺfȽ*]T\JG KۧuG>8߷5% ds9u BUǂD<8g"MigDNcg­ٖ}HKdlNɢ#v.P S8<Rͧ4&rMήe[YB۽gSn}:-y*_L>;urB"(AgZ)㡓_P?dOw;#Fۣ-qc gZr+Owͅ8 I~X|m`697OUN5*Rj.F岊_=*o55gk٭@'qal͉>6Dk[21wO'f&iPv[u'tELff(v gt hY3XȞ:g"]9Ŷg֠GB]O:̅MӄG ?Oz!_H_IiOJ5]ɷJ.sjcYNe=Vřʔ!aNZ.G R/rnPhϖJks?`&cl'%?8ue UYd1*~*"s|2߮pr򝱝gd3*p$ƛe+}[*vk.SdA:KK{G 3Y!E\sh 0kA\>hds7htKC '%k2A? YtKaZ"f)L֞.D{`В{ab΋ zty?όYXh>Cl[;ڸn6M,:Tt/> \ ] _Wvɚ58Ta31לͷ'UXI9Hϱ`_1mg0:L#chP<[AĮ |6 xCfpk>#7R|xsJ宺֣m=1On] >#x(جOnއ=1pvA7OK< 7+i QRI:DF.#?XƇ&C8ja&Y*O6fҡW&2R[ļ \KkxE1=I<\s%-'3+SaڝA0Fb ?LG?H8WNNHw-D۶滽̪fs USKe5O9TbG%Z-7ZOap9 `3v] 5f/T28r$[Yrfl:S*fdvbLFF<ťDj]8̓0IeȘp6;'3fN"g=kFF |~cX,f;>&迨e]KM"i Z]i{U..q9dX>33Eԗq/U(,cQ^۞ZF`DFx/r?+ȃd%WؿY]]᳥?LXYM"#d#+ITI%!D$ \JdXƴee,#)wL:vQ.;Hfw"6Mf$ucHm(jS1ܛyD%.-~mгJ \5#f),9%q"h8$|uR?0yL3B0DŽKO ٱN6ۅE߶ 37>̻Jn59TDOX)ݷ6b`Vmt1;I0$LnÒtie.{6x؎h'691k-MI,tž63f AqA+Yytui|0IAt4熡'WBui>ʃf!5>>Z]rD| _<0 e-eóxwb/#6ǎLmO+3Qل$&LtBvq1A[D-RU*UKY Wo͓e4]H>CWHX)+M !&O}S|\D~+!nD.i'LI82W/*,'JAedf^2rg Q~r|N0WN nI;H.W0bh:4.'CFw$- ~dgK4&'D""xHDtSik0K$_Hz Շ5+)nF4,n>n)Ԯ$*  ZI F+=aIg&z ”A=3r:N30&%M,Jݩ 7JzT#VCmZv_Egm8N's|d,tɝeFN_[u-}{gh+>cM hl0)&aݍOR = kVV(M~]IM۪wcjSIĭ!r!{ZadE}l ݲlM؉zm.nZΤiĶgܜt  fb%e\/EC*dS}Dő y1=f ͘FX nX+3X7xk7M |&FM9?A#7 VOgh'yҨ+i>7.L&Cm˙bSF׎ >OᤂcU ()U||GBtOcta$_w;-0܁9/ƆJ;ۺc< NعrUyXR2+yM.y2l'8qŘ1ѣŢ8YIF9#JŲo&h^ʰt9sh79i ;iJ8e>8dSF.4P}wE44ߡIX~$=D c8y(7'gsv/RY&Um;E#5Þc:8'I%d6/ݿa>S:r@2“5sxp!{szCJz\ZӘXمx\32UT͜*fWӭu _O-mj(2:x0|oڲ+ i\E8wLqS"sWqdc]̵%`e^4%(J׏(ڗ>'y6XJvl8i̵:L]cyyC T7Φ氰??L€DMdyrOyIXƼ/I6lw&rN0+pTQd2Ζ]ҲrVVV qJ&8+yl`nd_صCbvZ#!^8oDj9\h#i[p=]ԇF'5Q-#K,-&ܹ>a#uh9cCf#3Ge}&md SbVR|=/eijrVX+H\JN'Tŵr JjZY,"W:aƀx 2Mڕ[=j 76>JQ[Y̛Sb>MBA6"_RJMw%\]e}~JzANF?']L=vZsJՉ7ݯuM3Oǻo⃞75^8ejd m@UcVES}8NG2p[8Fhܗs>l\[?F ᅘm%؊=& ÝKD=YB}/*8ҔKsCylE=GaT%b5B{ߛΞ!?Z'o~LcR RbX˾1 ?sxsg-uYmyk7WxGx5υofsVO=Y|m;#͖&Lz2}wNK K n/ ]Bj#]|c3P6J+q k՜:WEJ>W0 ϟʪ'M"xKRJE 䚁~ \̚N=jo~exϹ@|+I *($e%3nUPVAa%yq)\ʼS9gH!7d_$#ko2u=-Ͼem0 25/h(= {$5I؄SЁ*#I;X[+n2RRWb|gg[ 'RV_%9V rwírjzsm64a'rRJMљϕmLE8s?ԟ²qY$!|QYʦ IQ})?ɣrcY71w942Md˕y**RƐJ4[TSHJ(g_Z! a\NpjtƱx#2L]g"<܏Y@p>hGr-SG#q{y>U(;ʎxj.Oz?9׋X0H|cg5v4ae(޶e~#A!9)*$H\ >takр#d" GSokÈa͍8|UWwjVWTWn#vV`smi0_[ѮIɲ+EH#nZtX?.fIws*<{xS/Cv)(:T/(/udNCQ-]jȸSKZί]5ֲѴ<񽼊GT{ 2(Z3\8e#Rn(A JZ9}U8ή@X>`z]HT6bf/jհXwON_5"gȕ\6KfXfr@5 91yzMs-rZQ%5e\R$;Y%ܞ˦/5Ӽx4%Č&K-%r4!9-\l[BHc^i.SȑQH{cZ1fv#q3k _jɼkϠ|5 >EB8Fcq)OS #28oOvaWsl[I/'yPޞ x[GՖ:=߽9jXWk7Tk ]gXF*'d0VKxrg!2f>e(ZTaW[Z8r|Fʿyjis]ZXTs:pG'h0`{}+K|%d:7:뙼HY \L5߳1R f@D-ci2(wy,IzHyЭ?sXO(J̐, ;-\ԇxъB%O BŒݹr >إcV@?]7 ۳sٕn;\HR'& gvFJ [k*n*{9]w *6:Ћ_G;17аF[F^,u{an|0w #Xʏp4Y4Qq NFަd\<EӶ˰B^.egU_D5a.yb8:Z7dhD3@,a&Abu e7VLMfgm6G1_5]rl O-.2ӽUzv+9ľO::-QT>RA/g)wșР"kOi\X&sSQ`%xUrmw>G3 a8|:$ tcf1d)FSXR7kmSe?,ւ!5–x0A2uRxwͣՊysp{P ]Nuګ܉(<,GSP[ҷfnuE <"_Ea#6I(_ _ {rJs\Fu\Ɂ[!h_n`\mqdNgdJ,$#j4?733cX4<2n7STFY/9u*ȌWpaEdEc20Ryz_ca = m-GRmB8έ\>Bi$ߢ,/{−&(=sDvEn+eOzKʜ~\)KF尶eɞlw4J,ǥ+sI8J`{s5ߝn9^| wF?GID&e3K0G 'DTC.mh5wqt6 4QDQ>8 |+q)}0ZL鎏6gűRO2S +gg'TĨX3@ɤyLlߊ_~etѿ?-&hP|330neX;ds|>CM浑9z Y(.a, K 6A©IO {"$SbU ! h0_^2s7.-#Bãn 8 2~qT^tpf*Wa&~Q450>b-9TǨZlXnj8Xǣj5*j(jjTsdgT}g%E6OWJJT g" 9=.< 'BN6ے2J8)3E]cAr]=H2HR1YW7VcX*`I{ tc%?*xL%6r&v~ n˦mo:5ESэ5ⰁmeEpݛ~l?ʳ._fԽl&7`+gm8]?q9_Ϗ)a,mě,J+ 6s(6E Bx3Љ/\hk ]\OŹsRc!MrV񸟌Idd[n`"G]TƮns`OB_υj߂hÛ#B~, 1ܝL Ɲ d։ ͂;.M"0LCz! F$Yg锄s3zTg'wKIx/]dv 1)Yl9*Q?ZJVpb$ ˙h 5kS',dNC\0NE(ev .<~f"Ց. %S-w2QFO-y)%m[)W,'JVͫP)gqy94Y̻zҨն$jx.J(H~PV?C;Ɇ?2YSEX4y=GB9\wuXƉ_q!7ܵB8/ej[Œ*N?g_Ww_8rUJ5 #[}> a?9ǃhuɠy3Qh1h'Gx:׾,eU!Bct*I4?b-ڊͺ m;5JKU;%@Jms{vߙ39'G.r Sy{*^eU } ;FOD@LWL`\ĝ: .&b6;Ҹq!#DoՉ2Eŕ{mh/ta^WTvѯc{ZZiTԑ˓e-6jk|K,6`Va8US6Yvs1%(*}*T]|SA Q+Qۚ|iLkLv7 '#i<.3bt-ق[$saeyL\ bb׉1\/fBcIWLjB.۫r9*Ũq-ܡ*5'/] *$tO}2Y[Es/asu&6]GU $sW2es 2CdGd֦v!joƸQk?>9wjq;ZLt?i ɬUx5T Rgk8p[rg Ij 4A\Š@N^lo"Y-i\ٌ\otƈƼY2}[WxLhzQEƌ iCO[nJVғͻu}3Xԓ@~r(_CK4R̥>P԰nZB2^ܗ|ꨃ"QhϓT9qA07υ ߵQGb;,ٵ9o~<$Xb,"e1Mdsat.mI)aPf6!bIYVƏ=\J{r.u :O(|_VmC_+կaL%Nm*nUAJVQkk7bvX|4Yw<ŻHڜ(Ǘפ6\,'_*9"fI5;znqx'$LonY|g\7gUfE[6Ɋʬ:SŤ* ?#K".FJS5VωRNUq>scX1DB2V9=;VVx,Fy'=cidQk"Y38qXڟm]эw9z\0r} Aܝz6~NyшCfXzXb%yߦQ2%&<""(MęF̞HGOO6;ds۾RוQ<%-ἊJ =;ՑSLIQ$--W<#!~^(-#OZE6&yDK%+6 Wq&[bLcv@6eV/dzjV[x9e\3VCݼr*ZVa J)rtu+XU:.d/-ZHwR\TMsk!XX)Ҏb^ 阨!Hםh=x_MܡjFnjn&ng, ?VX9K-X& 󫸿;(Qʣ)eQݥ]Qjn$IdFhxVE?V<滱+с&$q:ƩDzo65 GO+W0(-ABʨ{ f/w%.C$ew6~c1ShkKSCl_ƄoD^vc|MpdN"/d*:ę]8oC3slCӍ^lYA'uϧ cG@K\d ;/~ŝaddģX 8MCe _O05E|-WG9_ǑˑTB5=1Va("aEzM$ji{ǰ~|21ɔU' KLg[ZY"Qlc:y^(a1qto<j$?~hOȋ B\Wb JmM:1SZdllQYK VncI{!XƓ } J38UB0A:lOW3GÄA,e:} 뛃<M(@{yqE"ilÈR ;L(gZ6*|j,ϑ[JBnVʱq5y;KT{ju/̯a|nPR!jӴB7f^jWrw%>bI9 R/F@9rr<iϘD0hGcB]ڇwZѢvHugn1KXf\hhHa^fb6JܵDle%|VʔS%qeLJdn^ K=h`2^9:&11={Z3ڇC72I<DM F!~2| -5!+ؙ#*̛B\Sc{2Ff4I9qKc&+sov&yP7t·ȖE35ڈo.${^utŽ4/kЍJM~*Rň 2J lRBAzPll*!hd,9㊊P"ZqZ(lI8ԓ9(t̘q,|rfR*sd1*`s/)i2 KU2ؼ7ir&+5O54Y^JpC nh!R^G 1xC]hff~Ƥ',d:-OsoObm s^& Ĝ+XRVt:~%>)N8{]0|_*Tc$ѲL˚1Z"kٮo%TNX_oJ2&dֻ4 .Pf0/ %+2J)$p❳=:KɿL%'Ng<5~& |`l<oF$0qN 饣By̟}Ic8#4jnjuyhP.Y8ψ&fDeM)ưk}xx͖3X7(Jj+g>FyT6 4[XsGdb[HD &2OTUDOOg?" (d <,A &H[@Wjַ9L}TEݙ*W1ھ*vء~5h+|-kTNh _J6qq0kQ66qeћPJBsc)&a*cc2c93 w<,oOM0;/M\Dv= lhJ6DOr.8f3sѸgwz4&kϟ}yc@>>eF"SX#嫐/7Ԯi\ܘIω!t`3tĤF[{8a-;ZĬX[.Y;7]veUSGGb>‰"+ Ə`f)qS p 3-v{hIR_'rlS& )Td| 3,i)k{1䒺G5)ǟPiBK, ݕRL3*(٫bN?ԬX-JV?Vgrx{:nǑq`NV|87%{f]R!vd_=,d*=͊B&NaU2q6O!kJ m @2к--Z6$'>/DGfftH~D&68 Xeq3!PA?ph*G[A[g= %*%3kc []Bά2K _Z@}|tJ)$R^I){a  ȣvy.>]Ĕ=``THVl*a;K;{,rIW8ޛBYz6¥t_uE27J8'-u>7D^P>^LɞܷEƖ41ses <0":LLiMr|SgzDg6!aV5C! B8:>MC1!huM3cs(3u ,ә#|p B' Mofсce[l0;mJX}rˌ=8/ Qa2DM5JHZ^‰5[TD5!Bg]k5qγFiY̅t+f\VfxT}wIt*W ‘D [`s$TaM{' >4{u`aR~.QGR JFM@ z[UxNH_}StuBFLoOҞ9{"y< 0< ժU.6cĨI9e(`+rZ(̖Dɉx%☌ ٟ)V헫Y:al alʡ}>A X\ަR db16N.a4z8}" $dzpP9]U2~ˉ^RF gkߵ(Vڮs+݈ҸLCQ;HD?,]>nQ6h3pb#z_=x)ſ4[]&F>kGW~X> 4+{Q|}i pQ3fֲӞ@S5kq7[OE.Zb.sWB7,KFYj`Y0pja{:/E$Z9 j*cL$x@7L,S?8bwLl5qƺG{/ʹo÷fr`muf rGox.n_l#:hv&j.-`Izj=_=K&X]%x)~>3$k3F`i0O`g'EljF?ooeIJ|2=&X[?ƙcY>Wqh"`߉D\¤Oz2/ B?9-H$\oQQx WdqMw(,Ȧ n7$g:_H[9_3r5,%#t/y;Py" Yq2, }|)sl` c:;6;_R/*-[rޚWqm5.C*P.PcKj'$u% KhM=eNVHNd^#G:= j-&_k;tO"z b̝km7ޚG}Nx9treMc?N~ ."!#bs= r"߼tvۦpԃ9#x+4⏛n9e'QAN9Xq_25ڠBQIrb3عW66۰kHeulC}GL{Jɦ`9ݝɱfc*ӖʨUĩJf٫X{W9b/) X26 Z^'ݖp䈄Zf. |>Ept+$"} +H\1W!͞s >|ʢ{&.9|}N@mqjhY7 Ck\ٲ3Pej i\:8jXSIw*ܺV{yKL3嬿Wޥj|f:)7 Scp3: [b@4vS7g /\ ɟ9vsȩC}ɻ%hj(+Or$݈3ۖ˖ xסMf~u;>A̽dˋ8#SNozc6E8[Nhwݩ5 &7cG+j?|͒/FWǶɨ|Ӓ <5q^GJR. )8AO? ]jNW`,\Nl9% ΔkGݱ.Љs;0ܠ- %|ИpXFvpac{N *U- j^R lR$t] )Ԛw{:2L=dT 9YU$- mӿ,㗄 JfJd) ZP% T׬ |*oC)yHk<3Ob6–m@ d'FѦ!-0_MϰdvBgWQmxğ?9. 6-%HxpWiM`ؓa̙= \2-\گhXH 7@ʡȴ'=Ym鬡ԈSنBȕP]4toeIF}G2jA,63 ےIx6F`+:~Lic kVs# 6R>QWd -'еwG~m;VO6J֡:v?T49*Ȳ2vϛ͒tPJu(^ɞ żּw%U*΄8TL1 V<߶W [Hψ[K> ⅾ_]rF+\SMIsJp,eK39]C۷%d*</J\cOHl3f3%ӓS)yk(j\X(ufWtr1F8^n/v ,NJ #8s%GJ^ɎJQS:nxpfG )dCV9|Î+#i3҂6M(1QHIHnǨ"orF-*?0:/m!{FA~˴lFb4] d-AU",)`sStbph6\`@G3Mb2Չ.Sz[_ׄ5=!v'!) i ˅8-rblkwg ^d+8Kh$5f0-nzaOΏAXy,2!{M2Cj{1;sS@ЪTlގzexgZ7 3Om| k6G_삊?LË""FșLI5S6i8y\rZ1,#gLbab|z+آ/}aE,R4/0ܾ2ңU[]C*YQ@c>0HK?56HggaF^sIwW:P%v'6 s(Gm(;b.~mOZsd]NlyqSŧ5luW.O\NaJW= a}{1W6i5_BZ.~tYLvqih.+r{qD5T}ݸ2Øiz^h4miU0"]&Lυh'岮:hQQC%>ȱ$TȇlgMg!adq)R(̍S0f5-(tz8u䦏%/֚bkͭ&;eqM4=nMC;G0N`Ewwcuz(&m]m |Ye%K$d\_v4jήݐ/lHڋ&R)|E0 3x)h)BivFEyJ~R{ōTRð%jpY^*9% pC#"OgʅRX9Oxb%lUrjVU$0 .0EO!4KoC !dƛtNx7NFs:&FqG!j2}.^6;ŋo >/eS'&RModTcJ+Aغy 90Y?2G2t`D%'#q-bb?)q1s*2VJʹܼs)r_.ei>1E|+dND!jS3O|Z?F} g2X5ߤq.?y8+?lBSxl3LmZׁ\5$ZNnEDkB:~]˯b^Wx}~iXJ 7ACv*E9.xM^  YkMW3v17Ǟc83ֱr`\~='p $6&9s+=mɑ63}<`X#~ԟcLS-; Y5'L^M?Nj' '+1^ixdwy_=ŌIJ;6>3_ǵIL*>R)׏Ӂ}p<}7`*Ë1|1e7ƞu%u _4Sl!c֤X/'%]z{**i0U.y(h}xө?O UK9kBo{M_c>͕v~G|2I؏ ?T7vᵵ-7LC,rq#I؊ ;/pn eđšܞKxz؅е;QgrȾ*g{NQq,MF%C+Yt^ǧt,^Q5"ռ|Hkk] +]KYjf.!%W XoSyQvՉvLɺ8ӁN`dB}6&m;z|Xen맻3Fq#9yqz8Ւة6/eHKG[9|fX8sx\ #i0!6)|[mD/Nb`cܘے& 5%n^9|KHh\ǽo\,P⶷53\i“+8EŸZsxXNy> F|;hOeo"/g(LJp _wB>#ġq9yL2-jFd2V&M'K I(.QB|;qȑ6R=3;q,ؕwצ!NVP*fy?&ՔQfa9Jy!3?\52Y9eSf2*]E\@Q2Gm_)ˋX 烾5~>n ;qjXc+<.cs&U*W*NYLaI>V[Jv1SB5}s{|I^.<- u4fC,ʱ]@Yxrקqk8H%dh"E3]-s$'a8B։>O< @w+'[8̍ZԼ3t])}Ԗ; kyl09߂S4-|¼-ƠwE*I儞swٞms8e;V`?G^Zj'qL%ы*Hsu ruXz5jNS߽q ѽٱM,)r4}hs#+p/lk-Β f/,I0\;{6)3ֆv_НArN7&̢K"~e_z4Ydwb} Hحpg(e.DcCOI؍e@*e~T{`l9-ջb20Zχ8w2|Uݗ*龼vH/M%P,n"ՊOPoX3S^G:[oh;lZe8s&+!f<]^BRtӥ y$яYɝiK|D^Lg /伡ZK`RNcW.9;lh,-wS'a1U-=5`LKjxBGZKEn}T$.gF/gtj 9gșo_մsװR>/ky:NKrrdM ::r0#t㟴{c( ؝e'cNyԖ~ހ#l#t \9dȦf,8P{~#K'RNT5|sVˡʹ(zyxKWxqd t9D.*2ߙIJpκ?svf2Wuط|VN$#q,oq84>:Zq"Ő G= XLZIKՓZ@lo$ѨDL`g)8:u'[eONtm͕; ڬJh25wiᘎV=WMgȓ1jIPDEf_Z+w]uT(]q@M5pPQMd-zh 1M{];OÁXb&m d-tRʪmk(۹/Z4pe`w>s0[ FY EM 4HKΣVDIGw#or.ocLT޼փ_st!|9UUZ?pRDžbR;3}N?<˚w'<b<]]ijX͗֬]e87R'<4k(OYTOɗLVUKdHZ;{s̜3 B6',Dҡj0H.G`7%_GB7b SwU4]'.^1ސϥ)Icф %?> ?ׁ3SiޓF|idX)~Uّn#ɖXE -ʘm\NתNI8]y5zL%o9R؃jdKG 3U4w/tLjfE2btψ7[ey^۫HşZL[-vkD~ eSD943kgY؛ǨN~)g|nJ|]W#U p"ɩ؟̡ĴbBq|ةtw x6QcH+cg0+=~ca7ř;}86#؜Hց|]; :҉3|5b4usRk[Ffb0GZȌa:|N$:{4& XqЖ] )ql;yE5kc&U=ējRTEoǪYoOMhTTT_"S*ÊTn35dxi xKJ8m]‹MgXci;Ȋ&`=M"czxS}:~.Ep!9>2y(&}EaUiϜn枴2[.V"zVb|GB<)t*g,Db>X틤S]vzLʃrKF'mȹmNlv7zm 8{koTzʘQK9 ]A˶>TW`F-ffҖPnCt؟,U SS  $i`>瑆 ٕLta=u(ar8g#x26OT/A%jZÜ"!h{ˎ} z}#w?$ag 򢃸*߾D[ƗC sF牸YDR7VL 2kg93\9ە&,yBVgNK8 w7L1JXq܎SW=֙>i5gݼ69{̈́crNQ+plO~V?(8`fâJv)vp ^#%!lKi9'\.i>qY8܇Cx2-{ 24" +-5&q=48W-=kwH1VksSe{ kt:'J!]Z,i; }ǫI$Wj5Cq2Ԍ9֞ ?41)DQe}(ofq:ȅ}FqS.5 _oNL=!X-Nf"T[M_)l4˥sJ:KkJXS x㌙+e|Xiɠn.a<_a˛=I:Yx'~(&xBծaCVYw7odэʷm/bt"ESd_Ҥ3ҙӒjrSyv{^1 ]CWްESti4S0{l95ԍ)dnctFxq؃ ^4J6'Km j6ⱻFǞ }x'A 8_νx0f.gB" +Z2M,fW彧dIVXЇ!+, ,MxLR]e.qA/m=90ҁ]lM+'- 0uTI@YYnQ ?A).:Qc9Hä6Et2ͣPۢ=gM;Ov;G? iC! =c7Dm0Üi77Pwgi{A9ޚ*՛ѓCrু'x3-U45|ȯ iBoݭ9?Kc ihi gviRA)‘%wiMy Irh}uj\rN1|Cn\y Raۆlp7f6Q`˾~ԛ-wi,h fb [l` .9xݙx 賛'?jalp= f)L;-ٻ֛~9R1xX$΁]Ldr_GC5T4?^X{_ʸӠ پ<V- 8o]8TWzoj ͮ`6}2y)G=Ѱ=ؐz4xM򡕳;|Mǘ.ܯO [޸.4ASGر#u,#r1YģuLG)a:5ǝ,Hg\8.|iE0Up }ZQRvְd'k~($z&L!.4;%Nk~z|؝|<\6м{ا`J9ӢwR?9]뱮 4/'\Xtcч yen_]9VD40d]D[z/F>flGj>ȷiqni /6z8\ _-5, m:]Y}&?oC`gR^:ilJ݉|} ~)wFKtJO>e8f=.,eʌP< d#{mԀ3|t? ű;U smͅ :Q0>50Eh? V%l81mb9Z/uG#x +o,2]inGٮԳgv;[QXOߧ؞6m7#f0M'~k˚ ƃ7쩲Ê͏:.&y],?u%QsAO53U #~[qi}й_7"vp<ցGyZNnWv7kL2L3ܘ]C -싮[Oy`|5ckm7s+=9?CޛU\3ղdo>-/|A[YPqmuB9v+RLjiPa^|'}Q?+hjCHGTs|{{}aͰ~Hdtr<=b*Yr-#I{"]L?9\SZ4ы=p_H͠L1ҝ\_] &xߐu!7/Wz1/d$S٦;~Qp!Z*f_~~-=nTS[iﱉqO+k9'Q#S|vTp=XcX_}tg[ʐoL!ɿ6F˗NďYØҁ:Sb[@3y&s!-v߽Q 8G!][ Ԫ^*??QʪzLaH֙D0htσy/qrxSbÀ)<8ش Z3&4Yg46WrXyq*/r ck9;FS犍j -:Sh EgGR'w@ OvTZsi37^Hm>wWICo{HKwP^=D􎸿^]&53[.TzX׫1dpg Ewv.ܟ-q oKTZA5z9-Cyfd1f_c$bj)52tݮ.@{* L nȝ`0ia _)ի4y:nkrl|5Jʔ)N/_ShW<#|"MUrx']y։Df6>n!gǴ2g|N6ٷQ͆Ρ0 3YYt>èkDyi;.vds#gsa o,QDzd5Q%t*EmK!Vqmxj?q& ܀X.fW76W%d)!mV #LSP\(h: W(Ouqkly؅?N!Ά=.qyrI:p##^<ү (ͥDQ_" siQ) LmǮy< ZB8?f ҶP oB;`glϐ{r61ԭ+Ϛm9QxwnԨtW%=yM\.V30~|Lۛ#aڂ|i(`J]/YcyȡNę;ʝg9}" ɹ*^rȟs'PV!79/AD79V܃]\3.v3cV#kIƓ\n1}CB(d*s_J~MLdb2D`-iXuf6݅u =F2fS\4ň-bIG̉3e<NJ ʺI׼VK:/7McPKRDbG^T8+aL22]9'&0{:۟s\gj l+d5euS&q53jNXq=>3oƓR^ o>;mȘjCPoNǁIt4{-`DӸ}"s'rT燰'9PQ |?\ 'J,y QL\I$d4 W73`(+'weni u\V1b`! >ͼ/;Q+UVKm}yފHW:fT[1fEITN%"kYD\0c9{&T# U8PśFc4s ^D9t,enl0vv߀e SE;s3m佳McHJ dJ':f_˅}D{霭dXy*9  6q S_ u7iʉR%[ZSHy;+< oqƋ\ǞݶerTjp%+G2'R\<Ǖkyt`,Xs# S̎Dc+ ^jF+N3V;E9l˕|wht!қ zDYSRv*|y-u >F!NZ:0>Arw?ʐokĶl;Hp?m1 @Mu@OiiRiݥG*j)KO+e:Ş7mʄ _.H1rvob:eha(R\X ´7.̮qX ŵc˄ 8ߒýp_Ip^BtM(@q$( ]B9mܼaMn[[YŅ3|00?#9OS 0 =F(y>-W~̶cZrx##\(e ø~ +}jKRz^d3M&fWU2:,m*'5S!i/Jgr}3;KwsHсI_nJ}b,grn˚:UK| !}q=ߟ ^aL;дoyq;']8tȎo,3ی1]~RjD#سW{Zs/CӺ7Liwہ3?7BJ?}tixRc"})٠brr͑5C(H$OwZ UrW {Hu%& fě|[or#WfJ_E!7qf%[rC7^:x+w8rV,4y.tE ;RqrY)y.iҎNIw~>Uy$|)%,]\jS{rʈJ2%Zfx=AH?c2%E٧厲JkF1ٗ:*Tv$%N.tfO3gd%Ulfz$ 4cZA3v;V,sa [l⺡CoCN?WFe-:mKYM+!GYYzޮY괶7vݠV #7]/طM=WVª) i߁#dlPЩ9RtlW$*3TAqn;$8 ֽ.wwwD{]ٻޚ3}pUQ@{ݬO Jpڽ"ϭVZÉ"v^[C>& _# \!aJE~i+݇Eȱ j"!ܷOIU+'uzm{EFJ+Fђd7{ŵqX{UW4Y0o#ad=\dH FуQBFW?zCځf۽0L /N 7& wgl/\'**lh)vz*|n ^4 A.'nr!{ »i bP?Ճ[۞MnO(U_S⓯ S [gL7rϚ?"(7 n F~ StgZ.>EZDy[+bZqɚUhԵ? c%I3Ϧ/ڴV΅c;N]_:@?V~Qb:7g>s"q׃YE;5;5s@{sovݭ3ϛ^ hp~OלeD;"enbnQfgx;~L)\+pIZKvONBn_nsLֶ!o[Q'hpƞ=8oB$Ao5a‰B!nLq;^b^Y7[CVORPQQ{\>X9`E|ox) oщk̰#"G[Cb'~ F{~ChްGثuMj[@yM(XyP8Qp[xsObfXs̖I3$jta*+%jǓN\pUsnf^ÚccʜGqa_9b[d#^(bRX|I׷{rGuy(6峵!q`h=1V(=?su~N㙕_qu5NDB͔(eV1|Iاz[^=I#zqB(sCC|mf$jQ9I/GØvNpcO.fg'\9:̑ľb6Xx>yG GN:I¶~eTm־ʔVK',,)xO>ݺ)3.{S6˾ i%j|$ٱVۆ ))c}NS3~J@V?"0q9CVٲ;ӒϺ?ݹ]J)R-v*lgq-e]e6u_dR,?u|ygv%c9~khLp5kl?g!DrW|Z#a=O:`)Vjlipc4rO`zKW@$sBݡL#*V1BhK>AGmu8)Mʿ#W߆<)ȑ*2~bt?tߢVWW#4qX`uX$;}}򞦭w;~P"~5_>r?sCY§c\_b<ݙFamb-{,3pJ8M) Xh{@|cġ^L@2ХSW=/=-|ˍKz?HH dM3Z7J`u}a؆n٫1 q8?C.*DXWvHh7`R6f s6K,jG3>/Yh@m{ÏG]e8UߜpqqǞ£˅>U1B|q[@+)kuo(,4N^l|(pi G;x7&NcK/*$+=F!Xgn~X{}CKC/5m|1齊]7ZB JЃK4^'D&Ӱ'E4G"YhH ~ ‡s6o8 ]Gr:W{UdOyݰ̞=)ږI[bBea3?uj,/Gs<+ߺxb/s5E~vv⅂/vKnCtʢS \H/O8Ӵz u\7`#)MHfRӇ8pL## y8PvynT199q2-n%Maj?glE \Q)aqlƵ4b]xnOH2Š8YΏy\B<@SEj;) qP+&O1Ԉr'Stˁݏxa=5i'ogU r֜3a_\QmKN\!\8 sJ?i;+pl5AF؜w+)yY5QߜL(Ƌ={H&3S1Q$5Z cbvrCHӏ̚lbaPDl CG?ܶ:3|{m6xwarF,ҙ>!ObdA\G>;RqsFO 揷 /*J[o ȶ`T?[]y$i^V{bDcKZTh'pS: *ū)^i7!3\okovJu‚4*2yJ9&)\9ЅM:d6cCOqbj6q9KSXzϚTyvTB) #ZR)Ur[Ȣlxi0ލcuZ+ºaHR'GTzXk~p [g ygYG5tW!D- y'r Dl,gxԕ!XNR"zuCzjXd I΄Yy`S8xv ;}ad[ĕ WYh,쥙\ЋG*OUN\ෙ˓F3KZ: D7oHJ> h(ϙy%|e2屺:iN9qiTN)QeڜΡ< j-/ZZ&u擽'f\._^O sQsCː7_ΜJC'paDzy7[Gy2/οrWDsV.tTXRάKfi;8O7 h2B[R+bTAbBzDƞUf,䈾y1JP˄HnI2 9d3ܓS5ϛas݅WfXN35战(a%)F89GJMvve`OMksk2w-F1 q`4WeŬ/(a"'d3K='{`EA:uĜcn}aMmCԭ2㆏ⷯ;֍A81,_|Y;#pʭ l 谢q"eWڌ3G;Bx ϋlFh1=Q,+k6`l偸ؑ[<(Y7KK0mv3'HĀp>Jd3HD_'c3Kbx1B):+D=񷋘~4}r Ev/o/%gnq.5*bb4tiJ.;q &^v{$䔣s O"qܗ >pb%fV|b];czlXgƩ"z'i{PM07)'xӐq+}3XDvΘp!nuݎV oJQ~r͛?Q̡x~ l7|-@~8%ٓ<N*ɯ2[Br vmYaHCvHٰ/34D]E!+e7zqmLoX3HKe}v #Kxq%11.[38㩙j@>fM8N!f Q75sFiɞDZ6BBx Y1y,Lݯ4R$8 M9%?5Iǵ14$3{}! ,`|">3Cm x' ~ QX^G377S(RYٚ&G juO bG(T)]r߫J%Ud[0?E_9PdSW ,CxRE‡&V(y]3߬KI欔eѳؾ,|t`\:=tw#rאA/1kE_7@E_'Ţ9q74y3KvV6Y5Btދ ZCGx -$G-vӐ\m>e@.C [^+,Spgrd썷o]cϬO\ʉT4h_Gbp!K_l`US± a@? zޞ%yC֟S!g5vb+L_?ﰣٚ(_x[ZԺ/LQb*Dj=G[~$*xyP(~'[6p`B>sn'W0qTt ;X)֗8ycWxFQlSE":Đ=C LY,=ds2Gޝ΋(솑+)Nń O&w=W683T$Tetu1_Ws&$gwB 'לkG(9ɲy?I[;N`N;V4.(!!;[RWV}OWVdʣp"ݗ> ar\h䰑 *^9*ZIC@>kKCQZ˯5({qUz_ uYn.{,>L[e:D5r Dz#PLy؃̮Mn#b '{ЩŽь&lܪd\7$N;VX3Cwv GePb#ȯսRDc p򊦪ʍ`1Lԅ3aE0e~ ߕnD4sǒh#NQ;{NbR؍䀆6\;oY0:G<Cop^.j:VҦ>'3rAjmK)-8㛕 !˱KL׭ݐ"MFiIKS )sɀlkzy̫9^=ݫJ2N O搹~.42O ec&?Ge1*3 Mi8n>[C9S{z]3QQآ0W&`830m@~MlE$L gqLk;c'j,&`5CX3OTu׺[n Xpr 'rym), 7s%gٲ%XB-s|7岦 /ݙ9' /m^KUcWEYVU͋:v4O5LVCc\YIFU2|ܩry LjƦx]zLBo6|!ǣI.g캨d{0b3n.$1#P dcELpތ|3QZQ++:G ǨFx+iSbb¨o&zcNW* 7wB ˉh_xV"Q |C9P_ǫɵ=PͭTɦ^=`bE) wK(8cÛbq!묈4q#'s;j˫1ܬ =CX&o(9#jѪjn: Snqxs2˓3x5|ҭE7 fT:~ʈ2eLTUI__b~}&c"zH őXG@1U]elm@Nn"c=yIsLRN{N5+(:\r d,+GPDzZ<䲦9˰Ys#,+ Hd=|Żȟ-$GmtHpn)O!qykS/'G)q96#a>*Z|9g8.p ?Dju&2*Z9Tt? ?aF=ڎalhR凖}Im1A0rJ&ӥp26l*R<('GU2ȫG~-6uݪbg-KWOb$tȔFF(b,[{D8UoؠۓAxZ,p`-W I""NB}hf$BE<ۏsS Wq)S5I62ǖ\6C1`m {s3(k9'̕6#髰f0$}2"ҌحeYm{!7~,i wÈ%Y1L.c6 #%/jdA^N @g@*/K!}Ɉ,%o3S*u)_ˣu\G:lFmRW$6?6Gtށ>O'WZr)?&:ӧ/y[/}bY|?V舼"Mb7f(3BUQ8DXrW[ԥ5,]&|Ck_7Ƙxf_(b]Ңx3B؛r9T[@ډԹRǐ_hٹ v7bȩ) ly͒;%|ו۔޲JͫYcRj.WsZ rB> ':>2|Zr3*5\ɋQꝰyh[,MƲ@Tδ}톏 [ΒeP̄.i 9mèjG Vypٗ}xґ](!2K#z>`_?3ns-ܒwFm ÆhqR;K}\iPgżXNMO%[2_}ߑ 9LX~&{ኢӵxC7AGng#fqL4av OBba^ cc/=2Yܛ^BbW(׃LlOUQhTǻRfs36O,DT"49[qy>{c73QSz8`AQ&szwZ1od͗އ*c\l4;6u)gFbL`jv2iI3ӑUCH%nv2]sCO^~0,3熇9RL#U֥[rX ҿish+ fX&0a])gM\yǺ5qho)@nh9dBEki'|'Pl`PKdunMD46ʺ9PؚϽ0} K4R&w.S)p x]@Q刜%yH ֆ"oO{$ {&L9Gk.XHğ]d˼Px}$A"蚔9+eK!!B,Wv'&a+f`Y%?cro&=&½N7fu~Ϥ E4/BL}@~)z %adzq-nm-H9儚?$ShVRh6[P[vc]WR}"ᨄq֜!Opl`).39"Ӡ\$ˊ\ ѷ%ltmYoL#;B z"܏'tCvĉy3#@nj#0SYSuqOx,Gz~Y5h]򦞵YP[O nA= ֱT#v ~`БR*q~Mcekԙ K~5ᰁ{qXSJ܄r5YYz3dw#Ԇo$Y>(+֝ >5rܩʿس%(?ʼh#is"z*Ͼ j.)w*n.ua:Owug(Y`VD߅_ٽ: IF 2w7pW٫9o0կǼث \QZ| VǬ*l9VYz}p#mCƟ&Niuxeͮ^trfȘ#|7e*'˞ G & #mn _._O)c1'xee}rttxFy?%!E2zF9YF5sj3roݻx1uJMHW6xGk([VMZ$鲪k+HےCm@7Ւ-!"V,ƶ$wNB^"EDiѧm֙4r[1C JlNG9 5[wM/}9Nڰ,Fswce3+X#_B,.K`jr}ϤPYT)HOu5j}b,㽲-8[L9O sq1 j8YgR1ԒFq 2S5|;\rZU]LTWȞ~?Nctc_R2᥌,'yXM' 9BǡЗT+biĮ8b4='TlX?6Oy>.hdtF~Q [TFj 6]+{ X."-K RFW= %|VDƚU0nP!%A2F!9lˡMX  eocHHrFXLm#Ml.ݽ[39@fMiT~?Lykl$Hw7pyh=!W[ǦKOuZ`D~x_侺c6Е[2]mG8L>e$/j $WԓRꁄ4 st[e.z+Òr/gYR97UлsMxRNד܍)`_)g|+ye+Ͽ)eLK9a+X;/9umdlto|l3+5SHHb#S8g*3˛MI.Sđy?{ o[؇"!9AM7uy~~.O,0{fy~cf*:I-m`xL~=ZcZS⹾RB9cxz.M\[K-䊴?<4R+9k4wTU!*\m嘘hr GWJ_ٱۋޑMP Lc?7DVF0Ué)>%Ut1rFQO\%qTtۦH :.3'rK=.u&:U{KzZ5!?bB{_R-h]O&lpf6$dɪTdSJ0T(剥߽r L` B[uwRj7O]qA^x$IܘB+GJwPKc}>{K*>˶7Jsf=Z~ʆsy ϩ;Tr~K] T`lCn+)oo P4ĜTfz 󍴽bzn9fL^6b?Xk2{iK&L|;e SCuD񵞞 u^XǷa:R>JndD)+?0es1wprt)[Ŝ(??FzJ_3kWXBh<+p&aFhLGh, 6XVL TXDԶnȮm,\\:RBf/GcEfA;k[Ӻ0ؔT܋7pXmިǔx:wB5X4hq2w)(/Rˬ&57%3!t3Rik3 ih#elVd5/¬%fX3u#ܛ8YUˀ*ƵTcYݵt}h'jx_duǴ(Sʷ ت5U6JbE%t+$c'v:g$ջ6<$GNq|rK.A#%ǭc!ɢϟ'.Ѧ .WhKm%N28'a* fK`Re gdl5R/uh+FZRe238)?<LnoHez\ޕ;ܩȫ8;UB)C9-qg3K./fج2*O(P#kˡrcI_k)C)am ^-Mc<1=gC2ܞwJgin.TWJ v=X;T<ۣd{}.pWe }tX ssz9$ٙ x'DMqLlv놁 Sb_CwOǖZl֪uX+T?5(^ڳ*+z (J"]gjv~RYzxn<TWȊU SCx%?3%/Y oŶn$Kj'Y'39nZ\df31wYH#4V̡v|H#c<+6P8'>-F8K"t~Y>H|g2),FEh^SAMCu5Oj`BSz1b~ f6*$5 QORע-ɭx(avw6C&e[ɹK}Ds ]:иAYv2'X~(u©é9nL@?OxUO^?P'f8ަvvNMw<%V^BbDMhn"{rJ0q&.ПQvVr w&2zM>h+O]wLȲz>6pGͬo&|>'}0c2s򷙗Vvpf^fZxx˜&n,Bc3y[u:o1qMcoD瓘1+\%WƋY!Чj6SwSP^!{])^bܜϒ2r g\_^ܤvRgLۥFI@y87A*}X"E!mGt~3\@nz dбKax=5+5*$,V@u0r~n$/3]w5٢T EvĊA|"F+|5^s11. :>'9'$C?xz^V/%T;\FZC n #~/=|w&@:f!uοqӊ wNםQ ^O/b %+bլ ѰWZ)NL#1QcPZ7{׏,ȼzhپQǛ To-b<_zft&R\QeaIvf>s_bf[?nfuOa|G\s4admAZQ`&mfB8aV VcE)kHu-jHMJOuoNK1KFIR)b W0"?T`Y] 2﷔MȦTʺIXPsz  T(Z1Md1"|MelNY,b<%>@僧}TxUb͜d "4!ĉˢ)Մd+0Ї hed-cv2p\!řl"q X#s4ySh^xk;hYǟX 2vLdGLt+Sbf_HDN|w&_dcUA<)W*`g'x&ZbNaokܒ΍9Vʲf?FcɌj2&2VBq)*O~ůA"QXgQPI!V{ƲuP_j:n7[GT VSIH V8~}R^N.eDj.*ٗR6+x/΁U9gX":ou&Y%fr50?y*9TJxN齌 DMptN&*S᫖ԲW[:ǁv!)C0 y_&N-T8LP~Ĺ*fa#qZx[}:vgBvWMDbtSpGIN4;#3spRtu˧<-XܙÙݍh5;E*Ŏ~370dUb1VH)c52mo>Fvٙ BniWǚ k"jTĦiѤP*2g\8"Dg~9E~o&cQFx"(bv.)浭GAF+ ncS?]tL\e-utYmk-8|*2΁$bifA{3H[Ng!JXnSםTvV1뫡CG1?X4BeM8h>e<=Xe5:Heb gDOKV ךFKP;pPB3XVTEtSeiӐ&5%2qj1ۋt_|J)"JQJwPr}1a]ʴ~*Tji8nŹWr.6.FC$DӭqN1w< t/1oscw9[u붘i~ĩBkɝb-I,n:q?{8g)˜4ٕ.>􈤥k*Sœ:G`Ӆx˝90̟yRD_?SmzwN:-Bï<=EBюo}P}>`㏥;sxiK_chfC{r$&F5 5$^WaZwI ㊸FE5?NJ2B1qڽEZRjE29WD^^WAؓNdp~?#@r$5Sl$9y&]z&1s]a"+{]E_[D&רX=.ẉJ3M4,皛X@G'j)e'Hf VzmǴ$YUޕ򱰲1捂F^vgBœ?g/[Ͽ%O`*kR{\| l*R֋G}Cx  f^{a`%?T,((i yX7;f5鄫8lVPKLn$s;T&~23h]DQ=&ۗ3ާZ jce"1L8W6p#u^aNFaazBBDORa’j3y§o auS^Ɩ^5WcCJy[֮De8DM%y%1{ /ơ]1[+PAdq4 1cwN+}Nt$bVJ[jU j]JjTxbrE w5){SA+4\jc~ PvG)C<ܚ`" -D+/sH2 ӐϠP*Qѓjol,$P:Ħ3=#wM9Y[Y̟<=;QYMѥƃaAܨE~O|p?k|r`wOXI?y`;Z h:zh;pDגZm{R7ߕECNݗcgP/n˒xZ6ڻ6lJl05veb &/rWWF8f80!<h:dLp/q7%^j@fW㎙1M4c`L=z|ߝd}s=&>F[G\/೪3E}Bz{N ݊xKXߥŤ*a{kĕ0YNgdmt9WJ(-tJ)W ,O?QrGKT,R1[uR14-J@~W+YCIb6.8k=༩ ޽3.ed eS+{;pR0m)oO'1t/.$3y@#k4d<ѐZ X0e04ܓ-FҦpz\8R'4xBߧ$F:Ӫ;śaK/~S]&p.˛+vn^`OUN4]RiaT=mmCJWUe.nu 76Lxѧ _cқJy'wٹv }_@C8,$̪RD4oHhDX3ϳ;b:N92$z6Hy#QZ_(֗BeD4lIR6GbusBഭ/a_o|m@, !F]]J\Uo(' 4x1MN&'f"N"J &' ZNn1O.iw*B"\;cPɪӐ1Jl>]'ȱ|iX%&<<ʩէ\H#U6NO#wX`#سDǢ U;k/2;CTXe9S6& T}1α]p_ђ*զ(!?:rwm,V#O `SKYvw*RBr9I r+Y lRĹW̉R4*)N|gKo#t}e 9V9 ЬE/PTf Y÷:Z.ӱzv},")ZKchƎ9SqJ7U1|,mp~}C8nRp`͊y=Ԍk?[Xe2#iHz&0InbBz/gf!Kdbvfy~Wwfˀ4e]Ҏ{R j,vfٻyB*jyA5'#ʁx=kȄZ yן 5DG4X5.zzu>UaX{Xzݏse%o S/Wl%`Yjdc֓EjOj ~ʖެɘX~Q]נ%҃i:3̷ ݌y.M 2Arj(¶̗c2uˏdQ8I%\*ge(V‘Kmͧe|4[J.>LÆ .ĵU 3Uc2Jsa!ud T*gIܡLY*esq;s7O˥ݟ!h.#B_yVُ/IXj |S5¥Cl71c9:q*L4k#e|ѿfS8wp,G!'Kê1w ]4ǗYuݑ#Q{=rg8q nԺG#qkՖ? G.~)[EԅGP=ә+K{W>OT"*pg&乌/*cAY#)9KzN r1༔frNN2b+nSRS΀\XG|j(rO)磻I$ o+a)7{Y1>3d*W5u'JD0p V)D ›::yi>TMj\(4o[֋;(3D9´&~55̕{4kWLhB#Z4sbWJNN"۝2Q+?^_4kݔDez۹*"+KԹT1+y/T(*s;ُAX `Q2v@_?77?=ʩ¶kbmgnmoѺmٹ܎k]_~ WFNC1Dxb١l{+}lc؇/2]cd:^ʄ%%D9_O"I b JjhGǑZVs~JOՐK 3rDNc|e!siQO =aӃzsDwthm"&%rѻW'3kB$t&%fQzӪ}Kgϯ/r<-q&Xά1GMɤf`/OVCrx/3bj'6{;w򣆳f3-tN0M`dx5'y;-~EsMɈC)Zݘ_{ Yƽw;['(fsAymGhRAg@Q!>4F6Ћsd, B|qX_Nϔ㻵;Ԯ]FXFf^R27*{*O„e˘y*:-7i q㔆ku%c]t8M,a~"+X%墥3CFL(#ٛ2ÉX,)+f#t՛e G99'RO־FaItۧp7{HpHŵZdXHV,)j)vR{k6ldz*2s@|j Idy4\}28LơŬ>UBVŌNOD\2GƃN+U f@1`d7z^k"| -,^%}D0=fB]9,x0*YM9}b43b5h1Ν=NT]5.C0Jy:ԌK:_% Łl0'{x] mcI^xtS8GC}1C#œx}fc0dL:48::@:{{2)sY/f 7Kk]N(;QRMtL3tӂ|?ӗGܰ "jjs#{{R9ҳ aIuh:hkYxQz=Lo3qNdm Usr*g%sb1<K8lN*,'LWm4$Wt7uF-;#ആu*V=Vg`[{x77%UWƳ-w^;Q-|c˻e ꞍK\qe~6؏t\LzX"MIJctJfsQ=[ }Gg%ihnG00*hjIgU 'pjN*Z&Q%,}Mt)B*p(2Xe~ 23:Ȇk=7gwݢ+?]:gZ31p*dp){~!oU>hJ˯2Š&&^40eF~o2jVehv/:=Z2G[; :Y;lߗ \٠ãc1R$#^ۍ/NJ&O^c?&ҽKętMے9Sũ8Om6duo$~"gv;A:E |}gO!me>{Ml u t|y=לHדzsicz;pXIvfD>ZA iok=R9zW|5n,a~y98:!MCib"'FSTEW;L!c^}}Exfۚe4=kEFRs-K5hYw? VLR^J9as$9h~'`%WdtN*9'Ib[Ӑ4K4MkX^Y3*_D$ng!52jNŸT*=ݓpL!}[NlP"icOyJ39;7I$g'мjE'aU;/aIMݶ'9]N NW?-L`PtRXGU}0b.aZg_aV?f_ʢr3c-OD^ 'd~;aw!H> "gDz(&ƓgC)(IC|=N&NԓGbd5=ATPS"-K$D:K_}qd^ As;QܩKD'0CL|`n! YE|?T- :YƁ%V({V #g1.KSyV09c"{yq&SY{cq}[GFB-2fTuKcsc(ЅnkO> )< 9ӨIdEԻn}z: ґ:HOznG똺L@M +|jiy8e"W]:U 6 $Ȉ® d]OPQn*xrF+#9E+zY-s*(T,0XϠ[Z?UAI1ZR`pj ]kӬY$^?DlMcg-V[n<$b$>&ç[4Q|H'%3722D&Nn*,:L/bO:T| Or2nELVLlX7.Y(\՗ qEClU㳰Rx/|I(Pjmq28yA8Ir KHTDb/q xkiٖ2*rw3tהSt]Gړ% yr{^c8l -kň A4:I2snWZx@G5r a=YEl:υPqλqx0NNFf'껹 >^67Simnp\?%),?s|OٔnHcA vgE?wV ׼K7jPAQk4PpBnzJtVsc,VLB$6t)ێ066OY?r,^R'foy׉tմ , wD[N:X-dH*Tƫ㷔P:X:k3ߝ{gp`$؞%3Ch cwq`<-~R=*Bt~DŲNs(FB[%r@"f?uL\{[wR/uF)EBqwwg`pqZ7]uwww}}q7yONNd2u]kf-&,[Tly-KdVضU>cH1yC%t`noE|gI].k6-x0J(=Ϥuo>[IjX@à"֤bf gKI:鸞:HGz޽ski5ysWo/J.ǶV\L1c&ۿ\!lJN/0' ,r ~T*~ƪ9))sPVO xu0~;8n~?o񸱴ЋVc:6%qÜWܩ+I0`?Kg Ңw_ޞDž5%ϮB%3X`J\sDT2.X;츼j;0!%& Gkzw^~:(;iqƚxdz:7}])_ fPOƞL]ˋ6<.٦_5_dNcb4}J(m10~w:?-*\^FtVd(DnVI~Y{$j&nMޕiԜ`T9YnzύJÌI\$#^!Rf-ыR-s#42BS#J\O 9LE֍N.LrEa2hӵ?3ѭSPΐb*-P 7zVTploC'bag~  c/&,ƛB^H.a, &Ac81x>;|:qVjQ$+$s-. ?6XtRf>ĉҁX7M]P$*4N$x&Z=YhĵJHǣY5Gмlώ\M?D;z8÷@ˀjfVKZ~m˵fz }^Ұ+ӥ*VX㦢yb 0Ğvlȝf>sd~MƖmrs=j.h*ó" +BoXJĽ$m`xs&؎h #:yL<ѲGDD'b&hЗyb)^čJ`-`6 f4g6Trl(5cL8D$YnS u _D )_ `[e ?LFf0z= I< 'ugF}Q,0r`m/㼘כ X59r*e81iu1c ?*45I ^k?w(Sj^SЦ L "\(#(Wt԰!E;2k1,$doRt8ĈPެ ѽp DM k~a6g2×4_>^rzqLy:{aH: +3;ܗNP@0_,-\PqF֎g՚is֋{_ wFp};;a-۲n%xdYT1CO* ʪPUlٙ|3j|`utEH*:zӹΝ. »6չڑPi7+xiDCsݧuGx{?]fqO3Iu[l wsnߜjEsߌa`$`B?ڟ]38 7咍9ܜ;)EX(hƆZj+9+M職r˹M% $ӈGG1cY"f5,b_ahNQ&*hmCFoĈo}ʔLgŮm|;sۙg)2 ZB0:4W8}d12T`0Wœ* (iS'g#9]n(X:+tB'}YDb'.`ҵ[+^O4qH4hHts~^Az(6#pҪ&C70:Q ٹQ'q ^7>_23L1r򨹖˥u9#}gP[?8"rzB~؏ > 9.YrNas.ќIm~>\qg+,N/W8kjz 2k.:p`]T\}P2uRG 6)F3*a"&_B-a )]hکE3ICI #|UR28@ *; 'q˘ܖF\^dDxZx'f͙?ٷPd9/1$ˢB[s5C 5\!2fg/9YTRfѥ@<'c7ۼi8.8=n=RB9&S$+b wNyZ)Cl?dlbtݖ x^Sa~Ӂ,kva^;V;q ;m3ց:?v;`bϑ%n+hfr&7Rݤ䧗6KU27PzV{rbgA3Ý^sL%l0dOmDn8}HDҧm$a~h%qM$O*zI{Ҙ, ?t]ݦFb~ۅ>,{hkE(֏͏NlcbG8Q7hG$mm"ӥq|6c|(UnxL1Ǝ1imXO姧l5ê/*FbW650W5/6E-TjW!Z/䜽n WVr+'} .'oMoͨk|#ZWi$wĢl|J"}3/Ÿ'cx|@#bH7WzslnqeNw$x\$/x@oaofOdwa?IYOFK)NT) 'I 䐡kjד' '^'WOʶVv *c[{X,QxDYP5H !XI  s6_Bnp ݥ_fq>z 島a2i>l KLGz G$ȹ Qsqҿy}b}Y ,x13IX͕zzuУ>*&=Wqb.v4}=jпsi_h5HV -d]3y85w<0N˚=?[ERT-sjpZ<WḭG@ "=UQ0U״D[G4U=u;e5c.盐!yRN=+|Nƒ61@DaeMc|67%}Vp?|⫢W3i$4TE)jJ(x8do>I`bb&WExk4PkyJд6ϥ _;8>0I࠹ M.F{pˏl?6i]cН<֥Xv(ھw|e3 q,i9/L78&b)AP"yˍϮmϜ&ܿڃDgg I2UrGRGDɿEf^"oHb~$ 9q:룡tNɈ6fhD$g`B}9}6\mA4dY?[jgS*i~Xɪrd,7qG%y2ĝJ_^i #x̗$ZO`e< F`& FтO9+UH&&KlƋFAtzN!Z_˄Q 2ϭfŕrhm.2W'tI׳[Ⳏv⛡G{Vj\خȖ2ǾŌW p_|DjGr(19n"`. G<300@Ծd&ݍ<čŤ*v $RR0,b>_E>No_a .#o{:K:{Yjί}9۹#=v@ۉ|mŁn|NDN ϥaW!뚦1h{,?F%;D=<7oz'vkI5 CM`j95d[Fr:Jt؝EXDbĴ}M4*VodRHòHV_R7WBmS5 ]_E* ,m1h&a-i,LXK~VS="0̚YhPdK#d\˞Dz]sɬPD kDz[5g"kоc69e_*ֱ他IZN<//(p$9w֔|͍n{^26!Ӄ8u o͠wC^[#j0,bINc|͓VIXkVAe Ÿe|3xHu~*LR/JWg:*9S-[g0MfN7~$zـWaje Ûyg%2}^;;ql"}Şk&2 Ȓmև~/RBIg0;M}[6AZPKA0I~~sZZwu?]Q eb:BF?(.'ͬ d-/Ɖ R}w_Vw \vŝ*KO|Y'Fx\4]ct9y[%svu<&. bL7Xt#&5!\b޸KeбI%V]&vB7p#BzNW2ik kCqYa d.Y)]^ZΌ1~;*F=fq }Myq *lb*ooP׆5'$SNjpu>+V0[Ο7*yG4C,9I<'n|Nf{rr6?u4cڟk?bj,T:=vs4:W/m1F|A7\GyE.g&nܨ6^):BM͂5v?EUWEW}썙Q0]K^NL*R![9*v`fhɧ{DWDbس{rk/"?6. z@(Â餋`mLŗdInsg1.yYLϑ=|zݖ0u>Z1^3$:Z<iXs'NAJ6ԟ-'ib˱& fFvˉɗ"ߓ˕ȮVb_S<oˉ,ƌ2zIj.g_ alctPȴM>nDj r"Y-i e:BQu#Yjd#wOa_ED.҆{^m)[lkϿ;cb݋A= @> t<(|Tp>F1rJ覗+K< pv[" y\9R6/ Y(Gb?<ٳ5llNYx6If_ g4\bd>3 4N¢E|_LCHm̮p />6gCS &Lznsxg |ǜE:%u? Κ,~e;Em #Xs-w鴺%R&i|EJ\LkS**)8)$L4ǰjh>qo;yBj[c53;sKQpƙO|XBԺH i$׽ B[rWuM!Aa\Y5.}%wgc7tݭǚ/PL#hT&TsgO$HЧ[P?nPR1FILdxFʰr]sքv~ޜȉw X-GƶAl !~A]JǓnj,Vnb|rE,q&Jc6ogZϊ+p؝ѕU P%+Z,kqUf5ލ8*d=ZTHvAR'rk1%Xي)b('鰖+zzvwPVg/踴MOj5agQ\j̿W1๞BX!pɄZPsLj+SEŞJ&I`FhxVE6O<'ёl!$d=S0ӉxT>QTϺ?NJīZ4M$ON11h!/n*,Zed=𷊨`;+>G>wVMcMLXn\!Ԯ5 :h'pz\Ccp`?RndDRhw-M%.k ػ;'pΧ|Z1Lr)"i92$Pc?Pi δPT"3W'%*e"MYw)w}E1wGs:ZNmv*Ǫ\-cÕSI``Sj~8s#SY@пz?"ʰU4r~CV >#{y:6\QNOx;+xWr}BfD |RO攔/h㋑3q δ}ΌtLk$X" *Oɘ9|U T?`oB|8;|(_>/Y!_.STNu9+*|)-x26(lpƵk n3#6-+:~5wcc7Ɵv3"!Z;2x QZQnx8{1e+FE<~m@K|%4vfv}&wgA.ds#ؓ|~..JN *R.S va. l,R#&XXH?RX2}A݋H-23u_-Sv8nH62NМ~wf;sq)-wfI0+7bC+K"yu -}bN3qļہ 6䩄$Ds ೫ٽ>R,_m*S)󁜗9_YEBj!]9ˈI`eP1 01T, fJ0`;B7Y|A>#LYD't".@p" ȚWgc*Ac9ѵ#?[-!Kfsc4]h4_TmN.,bS6 {;dj*1Tle2J~(I⾭^~ ƭDر{4i˃%qKA>UԷJc} ABOOT Rʯ,Fn*|&*fѿ~^Pv%B66wE3.gRƕs)AP"Zqr(V~nC:K~I* -1Y)dMR*sgU^ҊU"0T!;6yVUVWuu+7oBn)xqZ2v)eFQozqOٴYƓ1ߑw-,z>ܑ6aNVLiq xTVΙp!|x3c,8 [Ш!a-A%{Ch8f8˹W 4U$ndJrȦưgc[Ot3ŞSga4 5Q_3V.C"_ }/̶ae/EY!."=M=Q%H*AfTbY9wUNJ)5öK~(W;b~U4nf,.ħ ZMc DYޞMfY3`/ ,#Q Ueշ9+pD󟕄B%;''cJޯRbee EYM縗_oE";1Ș_I$2CJo=2>|b8ٽH*2+xQc'M;e ^,gx?r4Ly)-_ⵌvpKe;RYK[ַީ'z62 _ g`=tC}&~P4ŒWBsk-&~*cc:[cV7<\OG6N舝j?̮l<Dxea>9d",RD̅Gnn3nU|"莔1R["ŷJVMTPRJ|&0Xɡ8e`^I!9˦> "T:YWΏ ^JKT|fwM1^$!g&یcW[KY+~ )OxZI 6 QrJłj;iuSCojjh4hI6q Yé>BțspqkÎ*XƇgg¹$F_8{$kygx..<ېuh~,f[/Jۓ_l!djo l;')}N>0CnK .~!|39Dsvntp!:ooc>d'aYq\KH8TЏƦ`Fp"LLiMr|gzDg6!~ ׈5E!HMB̼8:>NlB $>'2qot6}Sˌ?ɧfHX GzDe0i^:G lcIKyXߝ xLԡ2ETM M<^W" 6fN]7+9:S:K?elfXiݟ1!XŌ;RR>ݪ2J_Upknfrȉp =3331;f$bfff 33^{U*)v=0$UKw (BízB= 4Jnzr,A~zY`_a*)_D-Iw畱R]RYT> k SJ=S4\-+r[KJV^H4gɛx͆mrp"bLxw &Jє30_?hg^E7;OEsYtƖS":K3*XrWBC+;nqun#޻ٛHo!C= zNNR|+JY`~Z˙N=BOCiŗV g^Z/;޴2I==FZ!ߙQl־vD(ߖ$" p.Opkm&F~d)k*6bMf7.NO&P!Y)@؎_3lyK'"8ʴ~l{Kt7z XoSMGZJU_PhD•1ujDmCgÝ;y^L“K OŎЬ'R!r^8جT6QQS`$'T\R `X9?_"ۯ22IÿgkS2V-)"\%DSކRnx^KKq(ït_"l+uZ1?IsM|Zic/*0>%A[Tz'F1論q&ߗ<ۆ6ۑ8M>a |bם`=$X exQ ek3Yd%9Mg̟v30GRXڡ]PQ GL=9Vđc82IT.I4=^zz!2 t10?1r1ž N  –gBC&x uTD,,ݎ2|)C[rL>W{ |KMcQoGŐnϭ+eeUN G-2WI2S𽧊c\)eeZ_!(7)| k1.vy =-dd֗r%QJRNQ0 AL=1܎;3q KcX0:wx)S38^#*Τj+jhw5|`nN"4J&lT*Y93"oͤ^ì,#9x?D;k#9h9Aa B?YOu-G}bd Et NșNbߗge҃9QcI4?CY݅{tbLBכm)q鸾˥*qȈ94L':l̉zaI:{ǡ  n:q'NAdqk64U?_#̀!ɘW _t 6+܎1wd>bL$OXv-']Q BOE8(_J ؠZ(Hi73Y9r97à5cڴ@뮝lr C})0KPfʱZVN NU1UƩZZFÌZ9fBr,^XTB Y1WSnqHq-et*O#Qg|>Tb;4\%2/hFEH -Bj.O秜F$ݦ eX@k|, ćk83ݕu}Sg64m}/hY4`U (<I}\J:MǸ_,-Bm˳4?wjػLˑF`q׍ph2&6l9sK2J%l"Zk%L1vO)Q9~L-s ⧔d?&2 ~5]E5;TؘIYجb'^WS~er?>O|gG;q!ȍ&ڏ ]#ТxEa>q\ y%/Q8ithY#aL x6*bv4s)c܇`# NX'ϒ301iSprxa#vB08GH8'Cg- w¤3VqrY+ #G]!IWȺrE4zpn}0?va@V:s` 3JkTӂ:b}ț\M̏-ax֟? .%ٵ4\6&39&! walŵ,P')_+I+ ( صw'umX}3zѡuO1?D0 LM%W7bvҷQ&Jɸ䴅 \U慸G|SIL#j*YLAog9 /˩-sEK%-fƾ2} W$⫊fT+*$eDřUڮr ! ˹*CnZ4>s^$0/z"'6xcǙ#7, 64vs`W73z$mp_M"Er[ÎjZɛ0w1cLGӈ?].Q"Lo]!jGѓMǧaH qPjŰO@*acnM,R|?0rb˚=Έ:H3@[2f:pd ^/γ dz59alLA{.tыW54+`Ô<60h` ؃}^Y|^ȮT9OX~sPՍ˃!eMݧj*B^Lvb*o?aQ)7ji6bZ.گp tL.;pD3Tx"Pٖ۩YJAPtNkΗhg b0%dør)r!16R3}B1Iݦb{vp :5 UU+ۉq>toWoelK٬?׃yֆ_ܗLIBn4(#mZ$F(}9?ċ  gb񴢆T׶"SO֔}r%,S ۚwՑ{ip@ƙӝXTիa lޖnqׅ> 濍5?M{fbiG=J|OTҠ}5ǩ8wWqkd=i_i)I\e\ .bҟ35FYL(-~*DJIxU[j?=chFs rZѻ ޽ZsKBMV:B_1mY:NR,t:X|}"~k䀞 m+ikW;/^0bo92TG ;YHܔ Kr7Œ]Wʱ.|y1ҷUb~>K#b]$eNdOhoGڟ#-"})'' Ӏ dXQRL*6e "{9>0Ak!ZV*dSŽٍ烃쓀"}5-e./&4 =[s4śx|!Kʵ|*O;ktw w229SB%]S2|q]$w(E!K8rOʁJlk+lSrYδ,ZJE +31YFߎ<(9*)jft_85ItRr"=ʣCcw QLEŜN'-;ss½;߯6 w.̈k!_v@'4g`o Xͣە\4$+ 7pN䇇7RO /u",`oij'0+428NJgc9Sm,<qP&;DeMobr_㾕?Gr$v8ur&avdH?{ @~D ep?&bzšVl'gbzgD.\h:ٞQ@٦`&qW+*vViǢQyi oz B\I2vo|)Q| "q%[1w? L+&3aG1ˏ!FP/2Y2EvUSHB@2EaO87/G1j:sjJk!j8T{jj8`Pb@AN9-yW_􊿥4i %򼄅RF})WH5hSdzi8a5DOQS Vp{[_o=;? ؗgyQhը5а=R:ޘ[U2WVnKNWqrE%~UUr:U۸tIZHŸ Kx+܇qw4bH>}fv剉Yy0ts&`h u ܩuĝ%^LY |;۱IΉ!rHa[ɮIS=jyvڔM3曓()C~:(6\`Ix|hƃSPˉ02eIZN܈K+^_F38NHbژhn\QR~]Sd3T-K-Ǒ&Sxۑ/מ"tT{Ʌ|Ϫڔ4zLu,Ht䘿rOszHYv k4W&ZTF͐@ MhYCjW圚uW"Wn!Cc) ) RR` 6UeZJ58Whx]|3T|@&DQp'tC3|>SJ51mjZ淚U&U䢁O ,]q-b|Xk[Ȼ.ו4l`-s*Ur 's3IdD?T04o t܁ p(fdmƻR5 + aLoRnZ1!q,O'Dne4;2+]fu+ ekt, 5{eE8f)c2|&>8- 3߮詞qu_鍳MSڶ'Ls!T ͭ'Z:|\o%,`ӔO]sە6lYpҚǯyA4r ~T"+}#cI<bi-5OƉTbfSU,C93~ۺDCa+14м'Dv+m*`VQv%2tV(ruw׳힁no`G:^hI+f4?o걿Rɖ]z@D.qDgM%UT_zHO:A_ N/ü<3\~RKFEkmK@wae !uϞ aǂ>NddgZbcY=צVqsK1da>m3őH !CNSD2 1\>kƁ 'aR>0N(".*bXϟl7cR>Yxc$,EXfc\Ҿz+1lwNZ4m!_|KX6=õn5}nl;$΅5Id! $ϔd*{/f)!fs.J9ۣIv0t9䷫ѕ4}Zd =ܫc@%pJԓq/*WA ^+9(Ssy%{뙱SUjeIo6uYnWkYs]Q۳xmёxA)=[^ߥynӳc%5Ws\K*ruJJ ؉lp}{k-gh wE98[tc8.{y=goE/=6e-l,y֛F̞&4]ԋa ;(Ʃ $6>Et*FeȎǗv<Y+UiGH\K)Ɍt# "?F"ȡa0_QW3ae&'g2Dk%V6S.vBMBVnGxzڍ}h +˫,7^F3Yk$JҫJ TB{Hr֘KHy\҄BMEdS>s23Rw6S9i |As5O(y3H;lj=wۙ8Oi5_0ߧ:&ӲN>o*ja{=u~,Vҍ|Yg|% OZ-&:V~zڛNϱ%zt*֡md.a@d<cvc$NPrO:d:>_=9+KCO)0ȅ+nfX[GuᚡCwʼnl$WlbǡGeeBtd2 {.-b ZKF!ϭd1)Ì8FzgD6J c'Bv""=Id`֬m Ɖv7)OA-N&2|ǏS)ap| *r{Z>b5v8aMN2%8 *%~dp lS)ʞsȓvqvyj$^b"}A͛nd/<&yt4Oy+S_*- ᄁbkEeyqi<thiYeh-ٿ?c{is2!1oOEKf-3T3`9CREޘAyt>4ɦ,y;C%AҲݕaxl\ŗ*iWJ| we̲U04^5X;]0Ja<萍F"DVw0#S?ӛ_s|xXsN̫?ďQc׎`f`QF~K3t(ϋywʗ(,VdunՋ$N ۳~9;Ȭ"4 (Ọ"juRȚ:l?={W |X,4r| qܿb8j.\jO_<?nCdlH_f\*#[!-]RZIz`\Cp g[ʜ'%#&T ϮF7_N2n(obu j\D7QWRw5|}DEa-=VۅZ:ncej" o97+^:iH]z̬[=꘵A/%TK tfԳ"01L/j戾q$fⱮGd,l^LFf!ΧKQLZAuIðK fߑ"X4Q,?N1)DK7ğ}$}h=M~wҬa [Bdu?z1n8juܖ@N .7k#+F#X9gPVȾ|fj靔!Xuؑ=1H9r[Qm_eֆ FZ]jfY#qvղ*tp G$n$2ssՑj+. Es -_Asƭp9nl_IRJ VR\˼q~<.Ut}> jƎ1KI`=yo@x=U ~ ž$'`H_%35o=#tz`^ILa1MK_zJ#T۟OoyF|`:{fqMMtR8c]YCeOi4(GV9əXNAZy2Yi ^4272&Jav:9 =i;]Gg uN~76.e1HŰ2ρqPPXd,#.i1"4[Ka(Fuoؕ"Dt's@,O!tģ&п$>ak7G{1SmKJ3\ʼn|V)8^owYCfGW)i OsܸɿIn4:dsd,'|'Ϻ39]! ˢ,φj?P7cft➖5.h:yqhDZǼ*ӳA:6 2hAJY>>{ٙ,0.`)wEOw ֋gGGjh6BC\-nLrdt!`4 dL$$@WHP)[+Hǥ*=@#y$ʹ[D̏ln Or44%yr*%lg:1l ^&06_4Qoؼs CvQ;Ȃ*ooD^00n '@<9U4;ȇE=[1^64N `R3;fc 縱;]=דV,{Aִ f^t~Mss7̒cv\v5ug1Q^~B1?lfhۇfpLAv?,RBXbjɮ8Չ9:Y- ւp^or4 b?7s$ēZDqn*,W-:Vk_wie-rTcFAQǐKdj4!|_)c#-jTS"?Rb9xӺ3.Y4'32׬a9^f*d.PRgq\*ܬ%|_Hht/a“y)T-R4.s$NuQᔧ a#{cX=cmnV]ڛl;Y=yDϨn̘^Aω,ѭh!t49g`S1ݚO9hG@{'v^_aן|I>YIFhɊ? Ә>=l:ˁ(bg6=Y_gxn2\WN'ZhuM>);+V.>#XtY:[L{52RY*\pVP&4bԔk51r?H `hb"a͋=)Fҁ[ < p@6Igr\TsX_Q78,3B=ׅE:AY@G+S&k1Ry5vZܲCI:k.@}5La]qGe.⥣/ƺ3 + }ư)PBCJ))"rK?$rfQAN9nG+L|Wp.?Șv΢~a$Q̏d&e'Y~6VVdHK"s]յ8I\_5,  n;n;B]voz紌OU@Z9g ˛}IyO/$5N|{^#7ӗ$M~uoGBq$M=kVFŜDabhg)ݏǵ; !TJʊ]=|CնrK$3GoFOq;̃B;u Lđ#-͉cl08oQG nۖ\v2z/b\\$4f|qt`3GSYF|έCwfNp@-ϖr]2䟮2޾ɥTw a]^b'ph|X=~d"v-kv1K(++wҪ.mԮtl.we'WÃjƌTM!g(߆.̟[̠&D6&1}勇5.יϚIu~՝{Undf% ӓO9`ɝRWBxse7+~:&lYV,0t`~}oOvDV DS},shq< >;n9v@-fnu-d?+$B4Fƒ5{\μioHG%,hiʳc~H&oH1r{tS=lj4L>yGQ2,O(퍱O =AsE97 so$y.aqsNM bB}͇,Dͧќ?r /n}J=8NǴa,ʢtF>Ǐ1{|Ϝ7*=%`XO'YL"V%~KX+,Ns~5!͈p*Q(j%RoZ hб ' wX'@SQ<Ƕw4oH6~)k 篽dK.#T4Qcnݎ!ߡY pd4h›`~^jP,#y5"kGY4;1Ѽm(@• 5\cw"޶,˱d.TűXsQ=sZG^ #t/Tn%&G}'fV2}3\;ø]!P,'mIvL 4C|+9=G;+,omʥeb6/g_Df_İ0;c;SbȍJ#x57ax'shzgv0M_}9?߈L?΁Fx޷!giw`%'Y>%Qxt\c%ktC`h\-0].Pf}[/;b͔p%]690Ι},Šټ7ki1<ɛN3pڍYL#ߏ#W27,gbq]UEٓ@yusk ;1A}alH $զ'ưmq= ۻѺ$qG"Iןal߃_ / W:K6vEoS -q)w`3Lxă/)>] bЁq# ;0q`> d{ۮ݇n<9{6 gqk E֎èҋÆ=5R :/ %y}<ǥJZV9In8*.nb0AS;1h0O&FҲ{*y,fsja%Q1^j_B+h=ʩZSWENdx0}=ٻә%5ӗYw"0o͓n. G:`xCCM{|rϧRM&L}C[Uk͐: ]AG29 u̓ŜarʊEynT7O_|=nKS?zӰʝ῜i s~뚰rEнzm Ału=lN3wzpYU9\5ϟ{ h5c(3OE/=ƍJ<^/c7Yj%Ӫj&U2շJ#j&mq~|hnGhgVعBS}ٽ!CKFD WS7 sM^KXvf,)Dz8ZEkmwɑzBO7yo8 %`ja59֞Tqm&Kuޒvj~]|\K7Y F3 u &Ak9ďsģ&ŀ>cGr^wj\q;%{t䓳I5ƶCFS7te mfO& #H_ӜoKeoFvau҉z#)/ƦXs)hvG>Wrzc NhrQ.K8c,q崱,B_0p4M硼SԹuzs?#BHkFX$x4.a-|˩q8l#ja\iαjcW2֦+'gGU{SM?#Vb-/1lrSqgbnr^]*PmH1{Dݔm ʗY^D f:ƽ9MySP P`o̶ '[΄|鉱H۴j[y(+gl_q?ڎ/U,+gnB/ɋRˠŘqԧSMp|NG1-/ǹ/_߉wOK'se^bbg~.lwMC<._͟Guh9Zp_>vf/\ xB.d_q j,mKKnWJR^Vˎ2~"+M)Ƹ TZ^iI3^e[1t=7.|ؖJGwpP-U{  IԶrSygi_U;JyiVαFo-m;R7/M3{܍G[[lG3RnU4[=i%h|kxc@ٻ,Nƾ-ѶLg{ȞUPƵ4\db" JəYrFO8K|)Y#7h-8b=i_h݇F`\+w~#؜KJe,~INLj-lOu唗y=Óy܉VfL"p_-Qz4Vjk QŲI|CQ1J' 9#ى!g֫*vL/@~LI`eLӓ9g˰!'v$ vNgbV3-Z;DEnv2 +Z+Ø v9IRd{g5Ft$?3iUGu1$4JN$' ^yoϮy4 Vqy p_»`lgDG7&lɽ{鿜[Ln|6S>6i%N';AcSiRڟOhÀƌ!(CS*-Zdz$g}>O4ٚzBe{/rRJjn|?^a\;]b$|E&0.}Pf{uނEp2[#XwƘpsauyuTnD,u^=zm Ẽqvt1}LyaNXWn34C[y窞M.z4\èz sfR:RK`EX|'=N'z_E?:yQo eAʹ/8qɒj%o+bLFZHq\wڮqZ3C`̝°8λ%8ks1{(.5bP#c^ipe Ex4 \ۑa[L% opfǮܬ8:=#6#Cbx2Nh73D=qgHζfLP &4?vNcqƖ~aCl1CTC4>N)3V)R?vjrݗmJBR鼈;܌s׵CJ{'/g2~Fu`F J ¡) T1o>Nxfx$깄 Lh@ڎJªX<-|mjEUSQ?, @pt GZ19FdB& Ϧ3;8~K9̙Qn923Skתynץ辮G.tLNuae\[3J4;QA h htd{O䐪+Eo^*6lmHlsδaYsza`SU 9C:? G MN^9ڊs,5y2cc^Mlݬ:?݀ʶ}՜h {ٱV_3;7 Cx>\־$?XOm||Zy`+ ͗ ۏwD:t"F_SQt{p~/M#Pk)̰JweJPzȃ\sў/N^ΝDR 7yZNEo ze>hecXaB0".#zy7++QrmEޯ'Ig QRv(;ƾRR>r.vV h#.׈_m j{CY4K JcU{.4eS+T]S:mw`27|ne3)ף|nf!>n)S%v+~u^5ZUfWe:޿ػFe|FSKҿc}Ye7luJդU)" & ֐Ca ֈjbW&sJP#1C~-n͸ax^/n^$ +5m;4H`TK_u6J˷\Pu8~'I}i7Jc;EA;9H>ĽuDʎFmOXbӹ^iJI{̨)YEq`ihwBBSdKBg'[z޸=.;U|U)B#nST\RR}:VXh: T$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I?^U*Ӈ,Vތ|2Oɕ;&6IcOkr4rLT|_b;Rh?ZL)n5G{_(O+;n+FtP$I閼W}* y*%I'c;OP-IR=ݭT$Üėbһi>1KmF^oDZ]ݸԃ=<=N0rmqt:^nKJg^tw~5H\/$nϰ{m/T*,6$jtz&N{,ދƛYNPvۓ׿̅ŧi1%nm2R'ewSżOҿֿԎJY體/SLNN0ޗ3hf׌=\35PGɼPI(>&~)3-$-m Fla6 ӆn+hF1| Z<'{#Vʹ}h}_?4hM5y#ޘ`@\rfW3G4u4*rތm%EB0xRb4czU#I7u*^<3;e9+3mh́D+[bs>:Otj5GhbA_] tGxF͌Q*)-bܗwJl7ihxNƺ*.2Hҫ̝_%榷˘NƾiJQ5S[ƛôZl v;En8'Ea栮=2ʤ6z`2 qX>+Ws@ϒ@gՅ3MӚkm8޳C'VC B1mL SuV,}cM?.iv_}DA[7 u(cJP7R{/3ߗc<9ŕ-a ܮf9[̶V0v<y[ώTUdWWv3C˶76E4נGn~ 6 CSzԌ )W믊oʼ}Ē|%o]ٶFu}5a{#I'[qchOTY̓ˡ,/&{8VmզhS%V:s59<s2me'8]C%#(nB  qlU:%%cW,E׎d7Ҫ-}MI:);tnOf[G%D7/"ڎn<½x `j w;v=#B/K-"2$&#<WE:A{^pŤ7P]v3ڌS4'ekYԉ^%о$kae!BJ[obJqr_=Rn_%~t q-?rk0s#Yǣ\]bڽ=U&?Eai;vY3GpR4={#l;LY_,|]Ӌ=҇s?Fty[ ?~25فmfTMXaCt77`{Rel "#Bi8kGDžZ̽lc|u"ݞFt{-k&0J&|{*2ڟJ{ 2⣟>UGoDaa8M"y]Ӊc:*.Ӵ;ͷ._CzS 6-oz.\ؘguo. C;1M\ oP$rqfDz[ے }ԅSĬ7c+{gWͰf|W1'Q^x7 &p(-Fp0 l:7P-p^D%ז9ph\ ӣ#PVǹs] 5f)oԏ{2$QӠ/3SeGrG1[kK]6-d_ȠG]GR-BE7myyև3/e2߿j-gnF^<)𳳤 [r'M #xBq;qHNuG.ɬIV\it͇~,˷y-o]+XȓN,s1e<1VdL[\~ S^ S<爵tSUU9H1].vZXyҖcيi1ys^-BLJng4f%qnT.Fӊi OǸ ?Xb*}ֲDo/>Q4=I4Kcdvw^2 cp&s|wwx<ٕ]`oOhm+6q+pAyM§B  5MͼIY>1v\ j)NF|[3rAĥlu*$_f{q;SLx`Ձ:iQ+זSQfinhdW'+z"{lzJeFxGfYo*z?BxǺMX^0}/RmژI`ܣ2GhEf_3)XQ>2.uNשVd/V ƿPFLU:'PCOa\DZRq}FSl[_sBYge;3ȴg+t=$iwZ;T} YǀC)MtjSߤQcg{mXeӺj$/_3b[1.͇Q<|YBE^hƺzי*ScNqcV6a (<œ#LsXkݶw .,nh-[ύ|b*g :bʈzmbˎ&l1-4b"nY}c3E!%/֗( XOĦM9G<`@l'^Tv8_5Ƣ^3۝(`JZRPfJf(zf=lySIK,OV Fq E4㯇sM018~ч_6,ы ^5%aHFLhw3Z-ȝ/By 9u%hêq98eeEou*2F?l[<0 36 PT x.eR^-0 ۹MBӧÈ>kI%u2RVܞ^NYjH4[Ps~1cw L6kaToZF(ɖHEdr Zcd@y ǒ'65{R5vJF_Z1̞( !N$ntLbۄij v/fm6vtB-FLS mصaY -Y/YĞ;V C܏bf(&tC+: hs͙%lsFQ,iĿf}}ߟ;|x|5ٻ:-X]kf}Ta3Ø- ȳQhؖGLY(ׯ+-2y#hM7$w٬-`ԇ" ZA_0wBc dʭ,tx) Ԍo c2~yJp,&"ICi%pk)2ٴeX0ό[FĖ1<ǤAxU.;>O.*b4׽zLRw/#-U-뚸cWGr3&jMv86 SޤLPoTɽAD;Ts/qw&1$X1|.MP"2#]|N2QM ұXBNmƩld95}8`EM;r[脹3tl'atL<5rИ8sCs&^cgwϤ"k$m&0iuwx'i͗KxfW]X^ͯV\aʊ攴Y1|7H| n7cLNy~뤮)a [ q#sht/3AL'ңƃ ub;е&Ho:>݈@]U2޳pTFR#I >Yia - ֨y .XLr< "RWqb &9͈jšN̽II>tơ.LLV-FKUrJpTW7U|Mz4^`vO[P^pl3Mfy1pS4GaΖP˨da `P tzw;eFeO出FPg9n<儯z." .ұK2䣷.OkQ' 6/6&yBug1*7A,΍yt9ǜв`m aYv.rFGzxZ8 %>Ci6[&QEQ+yp"~aÉ4^keir +LoHC9F#\J^oXBRv+E)b BM!Y a̭N4;w|sY/fV2j,MR 1]Hvd7l$eR !\-'\=[t >nǼɊ댊6!&?'ߍGnsؒSn|cgwMFf贈{d_b{6={Pǻs*[ԣܾkt# 4j//r,[;ciǫ&N3!{4Ѫ{)v ɚ=_L.=-9@z]H|lg&q/?Y$^aY/Z6 \|A=̤願p|rϕ7J ے~;?[0($q40F~5Y2̂g Hɖ*:3pn,ϣ|_/eQ^.9|[G̦|(v anA6ਓ Bw6#Fw碻 uf{pja25{GN㫑ψ ܶ $~_dq|6|,N4rGۓ4 ܢyB> `3\N{ A|^8ݓ\XFXG==9gihP *>'20TI+Bqۘmv̂A*vj1+kƏ+f-OT8Ztw 2G2G!2p(/miȆ^@+$߳yY-P7gf .}k`=3փ|vOeI<y5e y r5[2|x5 =CѨBx/O 'J^cwbzydڦ0'E_ 85a,v+sE9y![$r9ݓqx }fDg-hI0!mgz>5[Bz bP"ˇys}wߛ5Hmcz=V,20\fѬtEU>Gcfsz ,?IH6D_6@'3;ѯo]N٤ۋЛ!Xx:{҈=;lN1@}#БaƓ[εC=9%҉,S3y%va+ nr0ь7NQ IqZ{怶ˆc "oj:sLˊ_adLBZsr>d6O{oV{w)ww+.-B8Pwuww]owݽܿssG '6%߳t?9t3a{}-h1Ώ tʘXFJZ7UK%dWU 4Rs纆Y|8)jv:o˪tj֜'Br, Ù]9ωX8f݃'18Up- |7۝0sp*m9:7M wje~tOA'Da G4YxJ-k ׇzӇYX\Wd9#ZkJkLs [>BAȚ gv1)d!k⼩7P6}*O&Vҽ:* I+܉ 4VGrߑǔ# 4|‡ mT\d 3qڏ+әv}Gٳx"ﻣ0___GpoND)/mE5kLO'6G8`iMo\s_6bc)䉜 gr+C*>Vɳ05,k[hsLrrl E;,uϘ&ԘZ8Hm/OMX 2.9?y-)l՟yh-kҟފ/*W7}>k['qI=1qxmL$ix6}j<]vDG)5ôxj)w>Ρf`t٘.77;`Vl W=ˍA1c~OϩxXĬY+SKp%~xxcYN%P* 7p.dŠt~Z4m),I%y% {kHIF>%]׏KўީqzhIesϊ1E$͙{ #3=l,c3LfP ܙޗϻ;Z`M`MD 9~-M;8-,ՂY a-ðNwJb (xz[ *f)y@h%4j^8z@/*#g,`b+8bߎ8@ˁ3ܿa\}4ϵvYP \qJEDn" ӗ} EM_^W9c UDޣR}3Û2Xè+l5n2͋ݓL0Gp#>Re2lp7 .'dCi;5oU%k%aEoݳƲS: avlv?sAiE+Ȏ$G\qjkO*=փYºX[f/-E >EM("i5+ e<a4d Km#O*­R;2^\ɣ6x3x,b+#'v2fdM6JJ;xBKjYAC:PYdit m##Zcvލ>ANğ+kltؒۅS<҇ 7/wfP=[. NiG))]9C0[;;'rB2Yrm ;&Qq5Wcly@XгX؎va.6\9,cRKlM?V0#=yńwG׳4&5*p%Wtdm=5-ktL#};oj-$)TʖX }oGgF_w¹{ދR_dbxձD2M°r>ގNcyrjAwn;VBZ&?z6)35ḴzB'Mfѵ+*0UɝihpQ4* HtJD BgpZZ8-i>McY8,= )&s*RH$.wb(ςerT=OA֫<!&\dzD(m0ÒjݪRNK*)Cq-&p>um< S4U%86@J%AEWw?ҝ<Ȋ4~Eq̹gL<#*=?) R z]No=g&+-'x>~<u g='ƦA\<覥 +C^ z[ 9pˁ^, e,m$a-Wcntte}A½܃gMq n:Q﷈M#h>xi79 3><c# ?=Yo-_iXL~EO6O׆:fPlxR|PaK2PXǞ\Xj_Xg\0ȩ^LaF$E37ڸn+ΟHvzH:1ͼBZoloWLu}P]8rޣMexV[(;v`|N0y6f[? ,p4cʁc %"@gp5$VKoR?8|Htd+F W n+Sj2E2䯋ٽ9!O,NǒdM m>J qU`a‘2ˍ>hry6ؽqa?GkU:94^Es䵩-, I)NBaZ@wI8=yI mdvd#6{ TƂ4 _^!Pޗ ssqӼ%TgQztdIh87DՔPD9dݫd*~8yVZ>dkyHSZ~r٫t٠-4X˴$]rm1OT{]*>fV2Uc2֟|Qăqrb#]>@C(܈g.9lt}%{lqRXT֡D<@U:}ԓ\|L?qTۭ, .F4-i|s]%cR뵌Pe* DX?bBP/H1%g?I9cj# r:_p$f; ~ԇS7BSHE%-Ts)bX$:zqk}"+sPFJJ"͔by+5`=rkWjϜ*GN,uFx"E'(wEہn+<٩:(dg)IEq9֨ϮDmJ\Z--Rp[ SSD|)m`c>2(ZύyLQ:ŵ^SP#+MS(F_9Oߊgڣ\ى^1ad`$lm 1NZh~ 2%a T8tkdL\*4lkfK""Xر[gD$ wҘ6pp*"H8턋 C^9|2?_QcM˯92o!J,v){V$hǼc3~Feh#s`rNΐQ9O,Ke߱T6n XIGjZJWi۳Shц)=珸迮mPOZ 8"yU0cX |=,fHT%k b+ѫnːc1Dwa=gΥXUA_J2zJџs70,;=Ǫ}ׄl0i^̥Rn`kxU?^ ̧[nQ96 Z$%ۥ'-Rc2ϛ$4h9/[s)%UBr)YLyx , azF![ԅԉ$A/+xHF42rrxaS䅓 =:\!}(T͂nXhS=q u:K˥QcR3wVJ s]$LJcNRP>Ic> 8NJW%zpCىPhZ?YDD{DQ [B1Xf]SP^Y1C$YIk+Ĥ}Cb6 `$}uYdQҮz5E5V6j9cᦳLq;-ên.ǵk4UEAu$P9ZK;io[o˪ /CWJn%s'#'x>τzk`vNm=AAޘв"F}cPM)907*JhA KY36d^X D>{z%د2J.#]蝾VLW+iۡeX&M-I+)[`Db  _+%c<% QX'vUCFX1@Y/i:L h[ÌJ=jY@4&b#uܷ섚{ a'|h \UpUL1yhIE_'K3'M(*璸gQ3o|9Ӊ;Fs(>֟_ICM~҇B]@:qqȞe⸽1L*tn k0őhFLGiK)֦iU$tg $1h{|zWE*-=:i(;T5ZdjT1xa{toQq:V3jI}2*%+PY5Y*g n^{$ Yɘ]ZBy }d_2617 (BBq |-fRdw[֗9 5AʇE)R%eUƸ\$_ATP"鬕Rگܹ" X÷XOK54;j Eg2N5LL= rRG{j-WiߣSk-uhH/&^WX\Xb+﷕DlJN8آrF#קp<8C_95f[Q\ _kE5nkՄ~y$QE7ž$;f"3ghe5">MMauh6F0}$^ⅹ_(x7K浼j˕e"P|"90OL*-z6װPh%BοWq,w{Gg95lUSKɁaJb jSU {X~L}DἜfe Yi 2:YeΠ1㈺?،ppW,c(riV2 nRBc De (C1+J TB{yW2+E.EӢb~z. YJB4&6|/c"vG| bTo^ԙ+c 9>\$ oth,H=sHTî=5r;=1T@P6n2P>TO!߷5Ra(D- n4(8e](._ CL%*\Tstl|1uN'~k4k6Na@.\c}(Z9ro^׺(|]ԙEѳ<,Fߎf;^Pd b&I=Ǫ[!mlJ:F(x!p[LSs- Os>]W k_KcZ!G8>T3wW-v5dԡ#^ZV=0i;zZ7q}WsR^ƻ62g\il%V6֌UQp-yBCܡ*~QF͹Z.89@1:Ҳ$z|:ϫdE|ei6zBu^x5xEXZkh4yFUE .*̮Zozzs+"h1R|4H3Y1/^P߅.,fRRnM)h{2VFuF]6{Р\f$6Y|)ߩ릲(d?@t^}O4WE2M%c CO|jKi*J#00()PT]Eqji(pZbR*@ Y;Ք w]!|!4ͫe@Y "+\z=gK@Zly]È&S꬚L׳/Cì j%dLݣ#A`9l$4a,w2š _vjc&# Mܩ5 ۪>2Ȱ4rH;WJ2׏`{7sd~ M(GiswE/Y\:_ZLfJf_'H[M`4ڌe`Z~NNj÷rqa}_e3;YߒÃ/9<_E*BYLefia!{<-c.9;(>JV퍒(qW4GMD <4FKa ' i!j svf:t0P{@rMs]~ XjE˺E45l^%)x^$˧ -d9#cX5/KVCK*-!r0Ji4oI4x'ދ6 9?\j*QcehR #~[QH>)䵐g/x`=w7C¤jA#yߩd޵¦?IfSw!ٻ]5nI60tQ_`,Osbks-F|xGkjxִ!Wt8 8[yq r-tO3H z n8G1@%xqUVy"l17GӧƷYRHr m\ǽYtK}*a?xUsB!}F2q)x$P)Ŭ]IéYB]0zC6'McaVn?TߥbC":&c)4L͡TTR\o Vጜ:*pX|+ '>W_$,KIO)0WAHfXV'|c=$)0*+ Pș١uV(*TΞ]o!}%k*WkvcOήR VR.b# ܭ*ԯ*|sY{>Ec~msD*E~}G^?PLJ0U!uj,C<$[=E VIBK?7{#øz)d`^ٖ\]mʟf@)8.]B{}g5˪WYv@K:n @jwZ ]`W5rįjկanaxv5r7Qskwn ,ѱUk0p+})+-L\7ICXU\Qr0HȲU>)b*|Qr1Zq2}bI(Z_s%||VN`r*b\v2T"Igeu:LR7/N^D\x3#0MO T 30Ŝh!fAZteZQQZ+-Sd6=ҸfJAbaE`,z.s["o\ZBiz?+>80S`!-+4wRr1#ƐĸE$%;Dž9 KY#8cb̋WA [79DAV>0󯅄biC$)v^ osØ}[V6s-j6o\J4ZHۅl^߾R^L` +XbYϛs>0=Q;{yb^ӘZJQm49& uFSl ӺojYVia A?w/kusfUa T3Npj抹:W KUtZ5!ZQ1+`T1|EV} Ռ"+KCR-0]RV2/d,]R[șwTN@_QޖD'c`)~r󷤄4=œY}_DMOD4IǷPMÄLGg/w^Y8>ȧ}b!wHqR,V}Kyy񄥆6idH,? }hh>eZzᘰ!a ĀSESO nkfw/ {K_~$0kB Kh?<9fɸ".EX['ŴR9HjO4G?%UESB,G0TK>[B5=XqhOwֹ:~1ׄV\f4_g)ļ[JLsGzhpBO "j09 3qg54kRpNg Y5PǫߪN}S tYBr쟅OY4Pr ćrd[) V[NJU^:\WG$0lvH,Ö!.f.y^"z1++!(W3 qV4"ͰL?W%='px8N S̀_^ Nbe3[sJD f gczNaT` nF"iN SNc )(o.n Osu2of:IoM1iGl49Lds&N&ZL獪bT3@1:^) ( Uʎ%R^~ h%k S֪a&펆A8bM fr v_@J,iW͂*VϽbқ2+5ѼSL[Y8*acs)7_!ְqV BuNcVM ̊Fkא6J̈́*Θ -䝹-*tVr*'p{K蝃XdZe], ﳔZbnWl$cJmR#}WAzj%( ꐂC+ 7eĎU̩"ኊs*5c|ta ZD6,%,1!Bi|M .譛'݅y\5-g-k7W;tSa*0[Rbrta(;ےm—u0c2Y>܆A9&_mÚ*KLb//|!o}v HAQ F@lxtç.Uq2`ڟo*WOLj[]4bWNQ|H_l o:c˛P٤8EJ:zMA(jf^s[6YD,3pIeS-]/jA$Y 4 ӓZ@_W~'2A&jηS#tZga-ǥ> cVlކuvs;D!iY;Wp:].srHQ+8]-Vp@!07 6W>AEU%mWҼNe]R n.#fX3j>@62>>UPySI! ډdc('@yҳ RA$JKE2 dOkU_߽CVYžA )p+gZՔ :ДrDcbVX'ouQdșyY`-rD{*6TɂJ:guT9~K{Gs*بĶbaGi%Zmme | %*9~]I %VtuS 0t,ǻRA*hhXyy\*VRQY*TPrKeך8/XYͯ9Fвn)Ho`)˦7EE,sG:y#5l^K%qKtc/MdUT\@:=t-u1'8:="3ˇ9}$>/fԚY}c2NUl֝BWzs 5o@P{~|ޔ-L~͵OkcQ ^aᴩ"6==ɼ4%bzu6Q26i:X͉Z¿TNJ?Wc;Y˞p㈖j}11cFJt-,Lys|"sT4x*C767Y/bhTtQt⥢拖4!Z=OuѮ-Yչ C_yʞw.*݆iXn"FzoVǐ1^LF8gb[ʖ:2HJuGx~)G7R^?.<*9u@` ֕˥2YaC[ &pt*\{$ C)hu]N;+AjƖ Lpڣheʹ1E"9QQr<#Yǹi&H"lKفp~nFt]WnF͢gZpA.u4¢=imƚ.rl@3$U5 Z#7bɎsQpx2W|aaףּڷv]!|"D qwwN:݂Z,Su֭ՕTs}ٿ\n7 CV<7§ˌUw0@m53M9KpD?l RqB,^ae@е+=MlJ+Xijhc==x"c,<9\SAMJߪ`֦rb_B5^E{bJyUg kU2FQ1gօ返~ k}hlzWG8&X#(F.. z|Z*]+N]+-(ڕ[Ϻ3׻E# x,w@+}XAD,<^=-dF>Wa> hP)R}d]LBx]Y#jHޅrARBTLY!Qk`~Ey-V3膳JaJ_-XzEF,re`+y~$`f\jxUVr&/cI$,ut1nmḺS~^c|0@=1QiL "<<}t}d|"ǾN)Ac˱Äj#hE9N{˸55_YZR.S$NN+ 9s䖘OI(FH=֎isAclGB_ u@=l8P̘#1_Տ/:ùnh%= },\NѬW.gds9FNuusX͋9܋ua_6uK1*$Tb\0>%g4.%pM9G.s^Bs Yan9J)%kfb8Yyd?zYb5vB7thԘ]H7FC}K K}[)1( li[!½7='8;30ve?kՊzA(xSIa 9;Si %n33Y".mv(t8Fӝ5Yϖ[89t}W­ ˋq.ne*9`Z,Td:*רg+yREâ .FI^N[yJ)Xm9O'-ݐ;LIi/6n>(|J]'skf$}dؽaA7yi0e/e33 BoJiw0!PˏL) H`r:$nyGv6R%$˶LSLƥk46^d@. h @P- 52t)I""X'#z&䶔ESY1/ýf/.y{'x $bƓ|z? Š˅MRp볊V\:\ɐMUFR9WrcSxjoG9/cQm-C`1BStwǶEG^#9e=IX/J̒BÔq\NO$ wqT kr|h iƿ F}MB6C'Y ezL0uL!=3ۆKC㙶d/!G7q> {:Q3pْk-06ܒ<6_pF&2%"/PT\&1 VpL 2;p(f"vvWI$% %'DhZ. d>ݿWEYRD]"֌Qw胰Q80v=Kdcl1bJ*1͞ߡH zfi r=*Eae,I"m糉Sr71[&)hoHª ~e~N&28;[ &m6  IXv+Zy{ϝwX({"LSĶ|vtL*^GQE/͋}iE |COYzs=\ΎVziMBA{~gv|yU 1VcHYX#,xP_W٩ff:SF JDjꈎU mD3~ۡ>7#:: UMɩdsm:5![YbVOOhg`#J,]dXG|WZ`Q[B[V8P~xЊS\0u\;;"=џckTS-E7qZŜfk&XM_?ݔ1W } 2!/敒!&m+1e>뒙Ϟ"fHpVwS ,g(\b&U34PN+Ԧ+R2BFfq.X+s>~ 52a,;sq 9fM6K2/oe+z HM|lC$LʤJac^ӴO*-W I8.v>oNbUX2QgE~jvi4M [sny*720'Ŀa )O %];߶!}V$rBG݉]NLWT6!31'f~20JtLSn4Uv+\*.D咊_*Ogޥ@;10dʼn^DM`n#noF.mZL3Ѳ+U0~ޓ#^&5̹mǣdLgB;jrt+Cc6Dug *3#Crk53N#oMO~\ _~kp{R(j3-Z:{Ϗċ+Kn})jwij 7cOc+}=zz|4"h{9V>)f4%*i$lFudKcf,Zg*C٩9r ^ <+vJίuJ|tYT]JrՖr7D&Gi`uHOZ<;sfL)͑h/wu(_J(?˚-9Li='Vm$̨McYDq!2Ǵu4suMuҞt:nK5 p>]T M4de56j %3E/ËYs 1d3^ӥ[==3bA}wrE,Yg&iSe$|p#x,mv<*\&TYv%V1r\}ʑ:ݸ qGpm9{#h0EV2 w8j;Ib=c ԙCe w-i͈(ypbϦQγG,&5?r"]:YQ3VzX ?VeK 'VǗ 'wK8]?(p ϖ pFˮXQLS5w!$01L͝=JD>LAsU֖w}99'%btNcl$R01"ae*) {g1hzi,R.ޕmiqϥ~1cj$B1\ťiZw-Fdr-S{Kk nk4]BMK۹3A*9U3AU9{Rks9/Wռ<9gdic?):n[AP+:i”ųxpϞm$i:$4gc}ʼn/1!#J<327).&P#Oz{,m0jqF)Qq9sSymD7 eRa?kZYKsa,u܅vDeD-5x'bMg^Mi2T̿Xb2doJr(K#oЭe2ac3E\6YIP}Q9]+sp&*y*dExzA) sK&no[J)mT὜K},w#f_1ʫUBfI{F1̓3?#EFBVHIb>L Hf1jˊPZS4ʥ|m?&rw=J \5=z),>)v,hn?(|(yJqpi!cB%:ǽBGmo[v AOKn$^J B+y^2WSOrzWҿW5+[W:n$~JI[&W~q[g7Ţ]'<˴<{lKn# o6͢8a&_dkܞcS/} XQJbf.%|,m*xŲ9h畐N$pMOAs<_'Žqc;/7-yvuec؞1f?BڌT!,$C3Gټ]TDf9 UFs򺊴4v2VKA$MG#?JRSB}E1o=$[-™(E21ZlN3">ci#mO|bc\_1#(PSFb,&WIw X3Iɽĵr)=byg dL4M[ƥxKCA't wJp<ʤVHOo\!de)YX D# F8L$uNrY2c㤼s az[o5k/ F#f:' -B%V|r{BhNpya򺛂р]m1G'bLǗ{O[oWp~U9yi=Mk {:WLΞ{]YtI: 5srfۆ3s\)3>DrS'썑CrSN=J&TEI1?T UB]ƈE<ˣ:0Є Oio65"ZCԅi&2w`w;)ܨA\€m NfPּ7*΍TJ󚔒[$T:7D~(a\b&~O g9X%3]>jl0}Oڏ atz$ESv;FM0Ӄ5m!EXPehގG5%瓘̎)KP]B"3GJҔ,ۦ̪&vDgTۜeM"`tZ s0G`HYKF( | 5q{G.Hrh|NW#[F'F*Q^xr%W?WqnV+(D}kwoTslo56ص]*`SK M+eΣ0 [Q*3٥oϡ3}u*1m-7#|29[i *yHI 9~A|lwrq<)ylnB39BAz8m1Lӧ0+EBB7>jgA8H:}we gF3 }8=tXjΪIv@tĞ7&94Pd]2&[ҹDmhTeA%\mgLH.,N?6rYl&3YXYaq7}dtWY [n !Jff>I0+A$'ncҷSBƻqCHc:*I gVx ?2YKO\'.";՟!B0I; 4pڄ݇#> p;$"hCY`A4y37,kpZ"7c"viqHb\)޶CR6c8VB()js˟;gbL>5N{$a V8-C14b3:JS6vZ 8Kͷ,<\YSP]H\Q Ei%,5Nԅ:C%+<M4m,zYzSW ZۍŰhLH`ׂ81E6:LP b:'ۃ~31c#h'^O8!riGg`o1_bY$SPWb("=ҍ Gz΢,k=:.e]wc$\Y¼{%MTRZIȑjߪ!m jh[*ݗ*&wQw?ʪNQLlL!EyLz E 8#E+&1&oVC;գ#3h&}I[QK9^J;.RS%J>&?4c_ct) t KE>Ӿ5i'4?k~i]Α`9'I\]Jܩ( Y G?=o$V'_*2o%2E0|h dLUJARTp*U,cPZW|&od! E7=ܟwFM4iS6v)\ٸ.|\J,AmEo&WMT Y؈|1K ]"_c)6J.`UUլa;Lq(Vq[3M#Hg69+轴voV 4-Se9nl3WnM{xX| S3 `/a6}ԴmAC٩o֥fqdp:k$/xcMQڧ'gѤxnpxVaq\1b6sf_1%t;-cx9ŴN)&RӺ*SrVY +bpZJg9>i;joœɓح?&vsB{Vf>v1FW,`6ɥ݀4d- 8͑cxY΀J?YC2n.U+CDvKԗ1%=;߇=X̻fX`GC7yɃn$%'kE nRC4hHfDr43c3Xcm/nr0krO^v+:m,~#lNӬ˜OFӿnSa5u%pA0y|JH?p\8ZsKX%}$8#},t$ocΤHIZEոVVqg+]rTW񳎙uĶ*XO7 QK8C!=Q+/_]9h2Ѵ^Wa۞_;@O%:QAm9d4`r]I8$76+]{Ҍg v7,KDW=dmYcٻ5BW?,c=[ }Vo]C\upE 왯2d[ϑLYՕ=d`N J*/%*ƆxVAkk3ob 5%VLcE"wWX+0"Ggi*osHt"+4xJq\δJ$ 9kC(M),ӟ2kՏ!lODhڕ\.S7xWMO SE\q+d WrXVIZ#ߐ2qޮr RP -R=E#~ـxtcODs:\|3$> Äph}0uŻ >>Urx-WW%zQ(+s=* 7]֛ztf.Ƭkx$($-ˆsavcs$a*gApI!)M'p=3Vի3U%VSɰX߯b2߰m1D>S,&5pη?oTc 8[&yz|FX3 D֒jphuӍѸcӸr'3R)ҠR^(3՝ })~R3bk-r,SxKEol 7kë>cq^ZmπiH{ $!g c5k2<ɜ wobAdږ ;5tWc Vh\e\ *^@ K9 Fr~BcQvm0nmfz8-‘>GBo[a c U.,039ÎN8џs{};փÜxtǏƴ?9zc?AvSgXHjoЧ)*i[;5l0¬y|3ӵ|/ald*z_D6CtwG Xf#n-/^ݚr )8*GXcFykmzO2db}ΙpIov !{Yw o'7j1r&1$ܛ3د媹>sm4-E&Xq-VRRG*qsbnlatIn$GeI\Lr8y;.jɄ,Z$LHenI:]H=}-}3:0GMع՚/vdܱc>FL.#;JD6. ]GH(@>e<}YFR:RXIϛ*볪.TM̤h/anazWqoO оKaza:{A~Lޖв1C-5A@:rfZ'|싕?~WPw ^q<EUgQc95˃JXEL"׷mxX#:0t1)agXM䆑`">&g0֧pΪf@{ֆ$_rװ{REwgZ֠Rˮ,:YBğ,f*V%q錖(yYF٫EJvTR1 |J*YR4|T\'8dh4θM -"L1AL;Ж)C2j\u_#|iL\1[q-w7E8c#{&_ ?R2 ŗaR Uƽ"zHkAcq LT~LgV$Z7,r(R-׋,E#INms$m-Y~)ܚK.tyǖ82q@8SŴ1TbТ'^KRfc)?贴 S^"T?l#<:Ǵwl>nz>3֦nnl/k(^OC9 I?*Ռb(vE?0ji{%< ?)^b,B x9?mb-}TW|xiF8Mbahkq(QqbTp>ERT/l",8x')ҕB-k/w{5X TإcFZ^b-j鰨 ѿ:SHBp;%ܾ-g\ݥTVpc%~T E)4PZ]yLĨ&ai ֌ɠ&4Nfqm?ƽlNssYݭj.vg$jӥ8$,$oPF%Gsg$+F 迫^*&s;rFUFBijAꙌn<5`~rG$9Oa#㑇?f3` hT6<M/>Z9,N~w)[ԪQwfDOeWќn:y߽djrjTT%C>4T$cpi_cAtݏ -S6A: p*t60E1&Yn w)M ea:/d<˭|'G4\#}_RfMx?!+}89hbvW-&pfa,(09J$];rvxAIyL6-O 8)ΖBXMǨ!nMF f79){dJl3%,638 '+;c?e1e>k 9 a+x(2Y &inwb5[? f0 . $GFyOIy n{E/&h[ISkQ*i^5M/6+Hu߹(fk گ Uy<*]$̱k4_+69).zֹJRRD?9"́v?'}=8Ȅ4s;McSkU 4e?W ?H qgC'i`:Bf:Bʑ|L9 qOjGy%LΤRZ u4>|5T'Gp :17pg.yQt͗m!pB\kBӬ$Neq o.!Be;JP)mmGKYuT4UZGüs8? |v}VFB:o"\ Rg<:YѾ i6Ek)yܱwFuWcʸNKVMײ:2dsi?$fi 7k8/U,٠[%)ZY9q\VJ?RB+[Bx3I]Lf!{ʭ<&f82Ì4pC<9%|Ùi"/N"vC> 7FJV Z __F}r+Xؤ Tj|YےY>Zw.F T{[yjțe 4ٗI^׵NbĶH~y&l{]ǹcwwl#'ß.k|1ʡ䴄Cqh FmGeۊ҅XXžUn?\E"E FܐQQB:Qԇ>߇>tI>ʕnk>3,r:>ͦ9Jqoz;r6w(qKdJ#($0 ߤS-ɼTci^{)[KKƄMrb))}u9_ݴ2ZQAS1E˧,-qXnMD^dZ6Fk]7B4L2`ݑ)8Q,E 빞>e;Iq$uLzWEuk-C|Sj9cUӂ&b?,sq|u祊#WDΚnC/J0??¹;H_1ԏӻ)] h67f wgX-~ÍVFևKpJT f+1Rz3e +[绗rVbFMNa͢ X0{Ռdu9p_ߏKc1ŽI\oթ 3xlt 49}4[!ݻ޼)LZ!iU\&nw>Х]ICB!, 9h!CwdWDb-/)?~} _7 /5!=AމJg&y&O4/ pzFXmυ)ėg1u$DA”ˤ@ 1X^&- h{ˠ¿]^N P wwK$$$h9>sfɬ &YY<\ɂ,*c)-UjN/eͻRWQ jcD#_UW.eL*CMY lvV>֩8)MD"ˊP IĠ Ry{bڄjQŹՌPI #2`'A .q5[[k5xֱGg듎Ьj^ETs`v%_˰8G[j/!1i7ۍ?N4},#)w-WTz}]G1Σ+e_e&nJWvcoS1(p|䦷;8 )ꔆWʩ06S6G-;5XjZvT#hz,/<88wC`x'v= DkV1y2n5<ϼr#ǓӖmAS7޼kM .̽Zn\M^m](2Djn9\]F3'G׹J⫕؇Pbe*ٔ[!KCԜ/\E 2bA, cS'/Zμi< HD2bЩ5$ՑˑmI£t,%16)UI8S㮔)o%U񵐲X1yvW2\Kr,TqONitܼ^E}*rN/'@BtqBi\'q,|!d>^"}K[\BZEZ~UQU񴲆)x6igW5,saCuLg\WEUE%m-*.+Jb5S+5ev8ڹ19܊=f[Q'_Kt{#w= tge+׌8 [Q8GYk/7eN"tp4I$VY}OZQz]݌؎ܲP3X&#) ϓJJQ4kMѶ碉ꏢw{aZ)"W,qje{nDò0.ĥ:#dfxd!oo~QQi%D2:|[Tc6lڥ1ٶ#k/ m! 4tXBN%\-h KS#yçz8/u?!JDs pl]>qvCp0Bº(&Q f?NNRvxvGjQf%&ykd[DCUx-J^7r,Va֧o+ZIA+qnUAW ZYVb2u\SC* `?nN,.~)K2y;˒X+Mܙ^r\98d[Ar *yq[VZ-fB3˰ZFYPۤZfIYS1\\E^p-}q_ T#5ze2vmOc0ډ=TvW5m?XXkVD^f'sFRh=#v{.[vο9+51 :Ӝd4fޓa^*&UiUJ7 VmRRr|k9YYH̉e` }xR̩m)>)XNlfB3 9?KB^Aq>⦯&~]jM.k0kЩ7{ qq^hFhvX mMyEDp3"A^lrC 4-dtj J S9CzyC\-zw='O%K(#Glhp6_fPBba4 ZDؚ"a.w:ktYl=-Y9\Z1N.R[aFYer ʸK SѼ UTv9'ߖӫWwVװWDŽcoZ8UŞD9;WAy,i/慨IWqYKfĦj_fktKk8E5]ԱI`B/?{{+=Z[QFLrvF,m:amXWX?BW$GnyQΆ@K+&!ΞSv6L!f0&NQ>sҗi&\٤"M Ut#\_ҾXQ rUJ*c˙UnP5Yʧ d&U&hI Z+K9Nɉr+a2a ߯aވZ[kxUÒ5MeѩZ/rQ ݢjݭcWd yjٻKI5nͪYWIU'ss)G_QJU0kgd4j&jTYrnx.f|!SˁhmO&{25G&$4{wTr`WsGR7#烓 e(>:F" J-+{ª \rtNJ%n_)WH91(#E<4Oet P ;b9ݎ&G1p*fC9ͷA,3WnŅb= xwE,H'Ϗ&𹔷T,`FR< ){!szcO1^* %G^հ* լ 5L5GBu8Ilj[::L|tNѡ*OV\Z۟:N=jmKpTYM៫qWj l = &$'iEP2gt9rš-pYL dn~V]ɷL7$#QMt3dAV6N9|l*eJl-ŵRshb},MMK<{ADƘ1F{X68~xX,Pzefk%CiTno1+ኅS*:8>]FMsL.xNԋ͈lEҹ+!h51 y%.M'e)oR/xWQ15 9G{+^SB#* m蒚:G4_R2>./Co_) (%B&tV|?)y޷4IIbddiX҈_L~CXN' ;3b9<,EqKWHWhڧLyTŃU|KbC%wUl?'C*j6TZ][m3V<alX%cV?v=_m6rc0Jrm%&a";c1#wA<LG֍om_03.NXO"n l8"MRH̥'yl.ǘ9Ciؽ+= wh#mϟMygH޾UfSX+嫐/cw'\ؐΜx̎%l@(3uw´V;{:~#3J>Y7țɳ0nĸSN\b3GF_̻Q[d$(Tp&0@AKi)g<7۳KэY8Km,[NReYb<%Lm۝Gn1^W{RȃՅ =?FrtUK eTf*P|Y^-#WBG@ 8-%94Y9ѥõTbfRq6i,z6W25?e>W2tX[5|h`鿳lǁpK)sxXL͞2OAe,g 8VЀ*NJJGe|%IQޔJNkHzD;2[ʕ84#9l彡yK­M?Wh~-2v(yLw~斐Ib`}\,RI.y/hٚfRJk_D3WusRL?sMRXԜ8fs#10A?܏Kebj4ѣG[:̞fNB#kO7ObȘ7mGvtpךs QSoIbxTPo{%kJtE ˘+tۑ%$>W2~1o2AF#DbFDF@ŬؗB,s+H ~9)$V{JK2 rt eF 9cKPR2Fxnե,#ozi Tqea/@OCg,A'y(b>"]BX^Kf.Nd☐~`>$C" Jְ|c)yOʗ/] igra(J 3<,):`tYQ,yY+QЭ/xca%ㄭez??*~\97Peb~DZF6 I4ug#trc+}h?%g(ZI׵9Tp=>nޏpV}]4v{"9`FҦ2؂G6(R[ұ!Tus1Y} "aMa^(*P6;0+-OQOeֻDtm%|ʡwR*Y>Hi78’~T&ݗ]GLvԙ-Jx]0i㺞lD-eVZMORr87zhɑ6 m{b}MiD[|Gr1 _8F]ߤ֤OHA$vOXdt‹EgA-L}o wh< >|_߉:hP0;1cRcëvL4/F4* C7L--F=Vʉ:'uf!Z SLIeJ'((@[ċ2^*b_[_fL?gm_r ;.dK!{K#Ɠ9:KlV@h1=p[iǯ&<52|.e/|ul='_%{h͙~s|iE@1'+ڣ鼵I*VN2U1KǮCex\LYL()4>ANXy c͈Cs';v>w^^hNz= / 7)#:}S4XЬD=EÈ_OL;n=폦j,WgT(CTr:;bj^:NXRU? ]|i7N`_g:Ȁ) |gg|#NVtEMB>R Wiph}Oæ0-?Mf[ԗ{/u|*ѺY'$Q sIk)C %5Kƾń_@Ņm RIz .,,] *Sщ"|,1 6T"YhUJ!+ZJ[Rn/z O+ ̮ɤy,sK|n>?3$ԋ(_z !A 9A ) o(0Y 6|e4w6ݵn߃=} Yʃω#O PRzKbb ]y캕ԾSdW«%h??ʱ^l !7V؍6y`I _MaL ћ)EҸ*Z?^>֤בr-8nY_D<^y?l/6Y fa=4;=; gIzj]?C$)Ar+ut[$Ћ"n46kDZK.Nn#|m l_ īx 3h0TL|1NUD$hpx)jf *e' =͵M/f|{D&O6?6?8[T ݙa,Ӝ89(s]u % ^ޗb2c^.wK_^Vfjrޤ9Bo~tBBXl!7 3YΏJsuR̷Y"sLffmAvY<fn_Ms9`Ps Ii(JnQRN0'Tt=옲ԜEʐ]1q?0EkKd P ~A93@֗*^˱Ib۪-cN̰ ajJVLqt<O,ɰvxdC+ LԖ6sE +}O㷓|o2SE#n^d!agV ٘Jz=MAc4´׎wc0 y2Ɍnk̨n1t O}tS/2ӳhHd74&)SP{1P 1:zHv9[or Atޟ¶c(QcPC-Ļ}_šJ\n^}G#MN܁g"(6k}\:7txO0L5fr&/c!.b(9o)>D2h1OZc5sJZE*y*o/Ι:0uT`"fu.C y:U{ 8m9#osJ$g_[I5 Xİ6H|k\&b &G0f&Μ-ټNJesmPgK;#$Rt(Eg[W:|5=sfrѪJ2^W ̦9ԑsܞt}nMNuaH{&a=K:h9K6x~\I('IsO9/DKa#"w&v&?3YHvK1}#]k$2G#Μ}ui_4xרI|mk7V7ķ D0xx,rx/µ\z^JϘQ #ǛN!^4a=XPvr_4\MPa,#;F*Թ.'S \Jq+ecMnI]S mNPMV:gj\fidO#WĕԖ0["Nv1'(bCVUL[昚J7_N"_y (=BO%a 龥M]|D!^ & )KhIB ?/WFJl*xϯ"Ym)-85E5#`0J_Q/{̋'n8[:L$&řD4AX{x ;yQK! r_ʲ9l88?`ӌ\fgohI62N8/SP>3M8zt2aD7)FSIPbX_Q`+Bֺdcci8kƴ g0L8ɸ= 9tUX1lE q3\!qBgƴ`[~8~E;C28OX=~: ڙmx(G)w"xV`P9?fe~v^ّ-}ޝtU7: 눷u3&㢆kKn,<;%fS|xQLp9丞PcQÉcJf%*p KJ`ڶP*P0ʔKRw+w vy ݫ_M< ^R B 7fo#Or칳‘* ;q3oF:hbKak\w6vWuq:͖+ܘ0um\ޠ2~ }kDRi 9ѻ;na$ (vw⏉ {ƎJogRͼ$!MOkM‘\rR}.B7)k_L LTˍr~J|8#nZ6]|JXFZ' ;ш6o61_+"WWX[.0!/nZb9y7z9l$!C6g[4>zpn+833mk=Y՗kYF|.fg">_R`zIR (8ע Zs ڲ[RѠ<~Dob?"ѵۘEY%49\%{(صK΢*Bz>×MຬsUrJ G2D^ n͐ y^ii1~_t^f+/ghbG8bߤ▔7,ʧ$2!ٙL=K:LM40qw4"'l[VXWh^-UYΨo-p3c5'ml6'mF0Zpq ;qU)ϊ+~쏈Bzוctsγ?>'QJƶm*)s+klmNUU{;lY iف^7D?剌v5fbqsfa!>DKٳՇ9q~Ke~@:0 pEjYZ)T ?$%[Eg8oyuF0YR&|OŐlJ^|ϧ$S1@p##,oȲ||@ޛ^hƦk-g/zKP!& DV^=rHuHկ:xy^q+Ag`Rc߯mQ2?^RZ52ұ*v5Jk<|P,uItvv}*Ց`{ [rV~p)-O`+]%jS0ӷt` ~_c$nGd3ASѬ}GvX}v )q8zHGCk+8ùl*c8:*+)#/$1w &X2 ;ÙkN!4XC,anJ$yۃ;l~|*YI 2coٲ[aɺ֤ plzuh{hWh\O?o46ZzO4vs6rd?_y13\eKSC=4?W[ F[9IY=IL[.!Rȃ , Hcpjx5oAO "c ӉR,p{#eNt & 0K sI}bdG Y7Q3DkVD /p_s4C71;f`14D|#*ǩI.eH-_hd9}x+EBABKYmD:3X# ~D/,z/яAxoy6U%-`O_1ۚ$=nX{nEr'`?=s0QqKh?^lȑat4S6c<͈I2)6!Y𷤛2*d6 al4Ks,vtݭx:U0h)s-/ 8^6sn݋9_$Bdlv{9re5ߏ·T+DVD֤ri.~Lyj2.ѕެ;e<4;'c{ qS9X(YvM7% W\jZ9H9޷ydϐbj|#dN$!j{'P#OK}jmDm*f1h15ߤs a8+ЋQ?|jJc2Dׅ=(Y.ߎ3\5(RV.ѴDC;a,R\ǯbtQP'>gג_ÍZr yPÑet,0#C?2|Іuq6$~5QaGw$=sr8Ù9mG LxY!NGR!gKZ G8Γ]S8j:%Ǚx$w?Ml |;:bojIY+;aăk}( Xqwe{0;B,+櫗c^aQt01` 4E8ė2\R)iHՉ?y13[Y>C 2x!O`weő87҆8Б3DKw4auɇry\کy=Mb@fD1A gCH5 ׾.dr|ߗ 3b .z ֔pE`As[1%]e

tŏvͥEuļ'a Sqe2k'ٿqj<\dϮčؔZ*K 6UJ1/bˈ+E GJٯ+AQ; i\5Bjr&y\@ʆ@OH .r·î*6-㡼Z泷[X咹j<玺R+=XZڽԧ6ztOs\USs524Tl iô3' r<+,FǞj;?t-$n],Eæ'ffדesc$sÍǛyˇOq/fQ8HmuvBK{ՍyeeC ;k9Q]I)eDzk=5NcžJR-xN=@$QUHpSQjUz(^up@ja¸5Ns36 6L*R)?IOX ngm ɜN4VF}\Is?XxYSwG2k.2JUOaC5稠f/p^]@6YUͱelWe^r8߹uQ) 9%+"6*aLe+R*KMj5qn1thE!4kO_9Q>M90mcZd*?W0,t|CǒEfO5cmc yU9k83[$;'21q'Wiф jqt ݱ.cY+RǟUo#%^g 700v'0ho f5qlҁV]1)N/ S0% ;W+z[p&јa6މ$3)\E~t絳9UJbf ܂y|9]TLإE;%aԘoG1a׃v^"|0hb0Hk{ޝ841#JVۈO$Ҹ)~>8:*Ȑ"'_* c uΑA.c6lЗgJe7UX,jb0CMk5kq޲KJ: o2U橙Vƪ%4+%X5 RWYĮD.䊶b\=K"_lZ"{9+q,V[7fC1lg._Q);EV9*Pq| N \WiZ+S^}MbkXO5#8o^ŭ|J'!&ЮG2Q-=j>#= oOָ1}A?!C>e ܱ]A#:Z\wfTN:8pmSz`g^JKERCR[?>'Ԗߔ;=n9| /ip΃:6Xe{fYʑ8yͿ%Ux/%3kM)hj)˒Jh#*bRÆrڕhXG%.my"4-bS1P`)mT\l)_U_3YƼY8izWNjncI48>W_]tR9ʿ.:XEYCZFdh+yeX-]j{FGWg1`\0Q.IduXV`[hhƑ=-UǿxBBB:иi6̠*U&5^^$#%P$zX{pObcO` s3/zZv"4óOL"CDza8Kz{q}F2dG3dxEG!?³IfLOsv]^;fLz&I=(uYZznPBq~ 41EY iޢ[pdkNDsRgD}ZBrv|f1:`72JMzLt*WFAV7Kt#J7z6Ŀ^4tF |E|*?Іn8FE]8Ē;LI SzvTor/"piVdb]YzPrҙzæ%-_1oi k3sjZē].A]JQWyIs(%~3F1)÷1J˴ ߖ3RK^Qh [4[tdlҦad20ޫ ki\tRNK~ȉPqe⌯:\ |) 9ӛⳞvnVEZLj-YEӤm&%L{G-if^%\PG( ȏns7gWH'{2h±;Rݷ#Wt?^s~ͶrfC LؼɔEǺ7i;ºt"DYq~++fa4<3gulLd]wYqJ7FlFE^MO!"x7:] ,F(@wxqߌu}|r*Ik,y:;Mq<_rRhX14XmpRV2Eǟ* 4j:{|~-󺄱)-d}ߥRǪ3xڇ?b29KO@t0kFlc]Be4>PJ2F.QsᬊUū[UMH-5SMѳlH<쩎FjM،q↎URCeZO$kVM>b5MnhX&^7QX‘;t + Kph"UnZyk3g}^VF{*+w^!\5CMj52 Q$2u,3RX^ߔ\ߌWZh֗M(=H/VШu|ğq.r6a1gq?= tº?Fxg2eW8ҙ h<)-q,,-rX&/%6?S€*Q̈́ە.\֮*2{1a7^u&uJ%Fgx鑓G$,w,bb[7_aj<?t+ޚyц?w#][{qK릳|U3i1-~Ufn-ձ"BQjɳSL)sN橤A}W|w5;UdIe! 1r]GE˱PH=yN>3-%g*55N (F'Zi&X]{j|_# Xmi/: s=?!#ٹݏ(&9ҲܾijL+ jL(֊l|#wuݬj>qbjcvĺ<ŕa_M v"ugRsş3X]m,vGɋsfܚO_;bg Sa> ]bP8VXxHvCq07y-f0UQW幏3{h99y\4CaM0wry7ˌ;a6JG[Ֆa6ґدl͈T̋IkQ2V0hrwL^ʩc2 |RTӵ_[;jHN`{ӘJG\, _B*7r c8ssW3qm0Mzp32*ĒWyߤ4sm[/++InW{g0.^Ix/JDwq=>wܙ݉6,)3$9[BwBݿ̙Z _@M5ٶԏ~:0 WB25suؗjWTMf %42T"R̀g*Ƚᷜ'⽱gЛqV>Pm8'4(FKvp)-%bÍvo|s'=N`Lˣ"5*tF/)E| Y|2PZx,t)w*y<愤2~ nlIc}1ԍ&ٹo$=>ʐN0ԝn9ICl|e$?g?AA4oF73b-84 G {A=K`TH: R0}#0~fC GGPџ.;myxՐ>Lxڝʌ2 fN|N7Zm 8yjmRArl:giG?ȣy#_O׃UÏܨ@n "έ8iȇDCyԍƤ%1`κَ|['q!K;Л-K2O*1IׇPc{P[M׭#ҕESo?ʯh}GrNËZвQjTK^qR%36tq"'D1vhȟ~<Ύm̻ "t'QP=M1"M>">%I/W:)e*viWLbƭʷJWڜJ0"/s(ٵچ\)EF_${~;yFII.dlw$ĚaCv4ȇMSseܝTgH1#npz8NJt3WR+Ф"vZ{},(?r%+y3tU<7~WD7%( *b38,LᅍˎEVtd ^Egio<C⬣^55LnSH,RcC慰Pcn,k)7GS[SzRzr8/纡>}o$>o>֜e1zҏAv`4<)TiѨ4~K_9,*_Y56QE'NnV,mC6u5]ɷaW_͑;;4RW{OdySd``5{8x͉~3[҉[@yms?5IL[ Aط΋V1䀚|DlkƘP2u~\)۵7/VEjok=ZKϥnPBXSDd~lbO =Jse}2b˹u9Yܨ̣bs[5ZrOk8o Ýz+80m7I6?DZx0f)v"WV{ n^i+)`uzpyPew(Ua]g|1sk 8׊!ĕGSJe}N>NeP l3O_bAfAV|F` g܌tR}\yt"t sH^1 p#|՝rp`}Ʋq2j.U9hgQ|L)4쩡r|U3@OB6~CeIAyŊXMx`gþs;J8J3Oc vs̻тzfd^) x`gY  ڙ9-\`9ϫ\1>b2ߖ@7J)c;M=Y#M8n˖ ֽrf!ESS9'u^[HpZ&v%xX?Vtq Kچ*bc@SXfA\a6g9^.%खDdw&͌cX<4f&jm'}BClI 1:٘o@8֛EMϑ}Xʗ+t7pĈ{;zE4ȫDg\ɽIj zu"i4kF^ c=mFa  >V=My0ˁQ8C#:ѿ򜩝Om(gģ1Y]Ȉ eܡ:jH,fIl_YW8}øny ͍D ÓJq6pa>вelUkP(C-->h8[ö,Ɯ jc|⼸1adKɴÛe!|Lh?@mmcQ2N~*E8'YπKv,}đpwƎaaC6,[`n$`+~ :{EoR0Fᨲep9+_4xMjhY!R=> -WpjƎQ!OB[݄ÉKjM9q+[|]q˲vsug^K4{iCoua/}8̈́#m6~gk^aSv峉7FУЈo0)^U-Kbz,0[A𯑌kC7Kg4ĥNGos]ojThꥦ2|[tߗ OZx55Z))^LXF&r#4+S)ޗnq6?Ǣ׽JiֶgJIz\ʾe/a9(=ƬwDtf oR~Þ%-E f?|cƉtזaɷYcE  _Q9W! ~Ԫgd/@Le"#Xo1r><'ȹu5zpSIiPGPzÉգiexa eD]-I3!>.Xż35 Qxf4tr_wxrz9Θ֘萅RRп*)M8 \j1t4Jv]Xlb=& ַ6ޠvgr%҄^^gG8e;-'}̽9wDI Gf_GsM* #{XtécH&a$[Z2N/u$"lj2F!Q3"_*ŝmûTQm{Oj?vfwR= /d[Ġe4W㿵Ed)&ev1/3_yHc K)`:hNU9kmؙ=pL'] .#J^뮭+#o?!:OB+vՒ͓d.}v7g FiEv~Kco;̣-/xhn'pLSqAV<嫆gN4x~qAsjboMG+l#c'6xؒ9 Atǵ\N]2\1Y3Y!nQ'=CX䅪g Sא|3ǁ 6|` ^vt`AYsڟ w#QLߜM;<,̋ةWd%Oy*};Pؗ8Nf7.twc+;yU_CҴ /U4!A}$ kը5sytD(;RȎ d=]U@/w^zZcJ<1'ggr蟚ȹQĭH7>촧m;;6o5*K?scOvT f0suy˨b>4G}*W5z ءy$X31ǗzqH?iQCUI7HV48'D%1hl:/{жe.N(9 ʋ̹!LD^tvȎwlm@kW6.Y-6 roM3DQ 鴏Jz4J],gvaj>omo"!nX aLu=yh͖dYZfPZoqz{{s;k wnk<`'rdrgxRҍ C?ΞGyh>\>"^3hQu_}rMٍ͔PrcP˥ѳHqd@N"۟!ݎװDz`oV6_/$J8VYխPZg2q] mSYb-}6ea#Z*m(ֿ/QQ/O2:PQYw`'RS-҇礲ƵiHf|Q ۑ<8˜v*?'4|V:ÿit wQ3Zs OA_& fB)Y13Ғ{G%9z"YI)ܽٚXֽjB[iɨپ ڗ҂;57J#2I'W/7Sj 8Z=|-,>ޑګj1yBe,}cd7dhԛ~lفi\7ދ|c'Ň\WljImҞo\ya.ܩtg{Xrg-Сg) ǕRqg-qCH;;!VX⅔0jtO3}hOicv(ße)6^ʤL+[%a$e~;;K_) RFRd],J\-Rj߯:Q7ЙxlVp ŌQET Y0ȔjeFzט;lYܙmn.e69\𣆴{b_GAgݫR{f"i])vh嵻Gn4^+<0XG*z>迧rk}I+G$+H!s(.q خ:MKeUQVgNq=4ivd6ni&m[kbFOyrllweIbQCC j(ug*v{*}jq7MnjGw*6 F7זzJc$s#{kI+w>h&&=Iiٱ{e[WT7ʼեs+[k;)WW< 0[;;Z[b ?>guFE+FGYvWqb\x24 N%kɳV.▓UjmqG_ؤrg mZ ΍qSGױˆ#٢: |OemCޜ[M={ۢ쭍7!m7몰pox%!V7im/^|o㬍DѭOS/RBgO$BYy+z~x[ۑZN\c,͞v({7:ލ-mČ;ׅ =ZW+Ww+fSf6L!ec{'d^Wa;"o{ћ <W5Gn屬Y99yHa踡냎,a9"&c^t{7Ñ;)%Vڳǁa\kc8Ec6*S{~nS+p B|)mV|IثzK^=I#ixGSCxim^}gt Sm4AB['=N*;+Cݹy29(VDe8Nodo,ja^ 3HQoL6^,7(Oa/\ ߥ< ^tR|) Į⍮O1.a X`bgͤ@ts=6j"V!y"Ŷ 7mHm hk~_6GF'̦l;#Z\1CkLBW}s*s){|ɇc / ?}c5(k3D=4/߲v^!OT ~,{kʾ6p9B#au77ie.?PKm.޻u)Z=,t8xR<@xgѩdv#÷#q&p$ mmA]w]䍠(Vgv0jOɄD-p7g`@e֨YXbf;^aLI9o]<9}Aq]x.Kt?_vF[=(lB1+64>_Fb;XM0+k!v?#a!^qPq6^tb p9nQؼ/zE.j?ه'aCSO}Axs]J-*1 rqcQպܓ3Gg'aȷTKز$I&M,>p̋[M}j :!xrk'Q9Wך'z-'SК&<.X2wFeە?>ݸř#Z IIFXG41/\pVhYmkGhԊSy`5f)x6t l@*!OMu2㳪 LS$%sے>WW,ȜWcӷS"wVB AFXs+(zY5GQߜLƋ={H&3S1Q$5JbqrBHӏlbaPDl CG?ܶ:3bm6xwarF,ҙ>!OcdA\G^;"SscF/$[z^%f Sή7| d[0 Z_ƴ{l/+U1q%X-*DP ) BJj$`FYckeS.e7I;:nAuE{bfBSke JBg]&U's.t<*Xy 'ڞYƃvZh[A;UhN/s:#nfC쬉3MU O#4z-~\xƕD$@ydP$Z_ژ̐v#*&'e@I~wC9v;.-LÎbYY;lCwet`t7+v+0| %XR,eu]CgyS 4CG8кnY6ߵ P80z3-7ᠧ'_{sŃ'W-qX;[c˲X ef'V3 iOB+1HxlȔe>̊HD\]%\͇hg@rYYLRrmJ[ePlq LTWB2ќL!@+J1,Ʒ T x3~+-DWf%Ki 2-h6.as*>L2!ٱud4WZq7; uq譍&t 1,_&ft BB}wub- ֞ĶoSĦ76#*(@-zM,h+,…/nHj_gTDS/ut^iǝ?&f֏hp&;ʞ,V1ᄏS-o4[Q BS0-d|=_Xe(IMmNš̏N-.wEo7<|ق2 (" R_@˂N'+!zYQl74 -d32%Y({GπglўL˯\6ќUDK1=&pz)ae*3YB h7b,%>{JUرxg /:/Dn^b-/2av1Dҵɞ~I6Aĉ=F6䜒Ӎ9݂C{ŕ1M KrP<ܮ6߼,ݿZ0*877OQj .-t$* Vs9z4u_ :WA1^5l1V<~_|I~RQsU8'Ak|34:,Aw5vJyň5iFn5ᵢ%#gfK~RMOl;\KmFۚuȇ!S!gEHf&p'w>3ZxOT>n{ 31[y .vdJ{0#}F%L]bL~5Ν 4|L|c(kd ufIG>EDGd"7W2VoЯ7O.@Aet{>-ΥOZElW~Щ+]~>KFt©ɴ] r9SbIGcKtkrp3Z>UVNn_aN5 j,3V}Ĵ= Ӂg&pvxq+2XDvΘ=r!'ovݎԿߐΣ#9!娛73D2*)8™\oZ0d"5iq K'yLTJ_e-f@l?ڰTÐֱ쐚a^&fhسZ *CV;Q%cJڳ ;KiHELf6h4 gV(aerC-v+Ikc\95-B ǰ}'rLuvm?Vmj ܦN0N4%XaGu$f읤☉lP5t{v|s^_o`USwñ a ? zޞc%yC 6!g;\L_L[e*D5r DZ#PLy؃̮Mn#c '{ҹŽ#Ќ&lW ɸoSI8w.f+"(Pb3tZ{ͥMUab*捝 °,`%Uߒ˽D4sǒh#NQ; {NbRڎb6\[oY0:Ψǃ3rNbK;Z=9qp)AG&25s9;~c*r!Wִygy%o~aoFfZAV'7y,yZmfUL[V5H ?0a[ }sg%UlqVu߀оFL56{1-Sc uND3g'8m}Qaɡ4xe ߿ j]_h;n1<0AX;Tа%M1\KSi2_1kZW|S SLAn mRxKND0׉#C1 8E4RA',0l)TXl1CṔf̍XUsC9u?gky_[1ت(K*jFx18&p ?Dju&2:Z9Dt> 8nF=ڎeQlhR凖|`4#aLfK1elTƝܿ_N*ΫuX+ّWŏZ(YK:ZS.J <8U )%xIDU)8^lZ]YIp^DZA)'>CĎy27W;N{ٺIUY(w՗/9-?vItHpFN5SǏtTJCc fa9~1t@RܷCC̦y,G~CQJ}YϸfWbb8oY#c`Pn@W{qISWpEhjWTX6B 7]'C& \8 l6*A#I yWz5)SUI6c $6C1Gam5{s3(i97̕6X!=FqWa'!I,dD[˲B@v:VFn8V_@K ,(TbrC]1MmF_0 m @g`*ϫk!YJR fT{%TS0+8uGu,XO{UOnLHۭQd#|O'WZr)?&:ӷ/y[?^}cY|/듽^H'P\5O52)QfF" ط /VOkucD?$n<֍?s ;PƩ{=# 8EWs7<,sF/ts!c-$K=mSGj(D- lx͒۫|ו۔޲JͫYcRj.ud|^9a1҇CNt녡}8e >,/8TqW6U=\ɋSyX[,MƱ@T?i ڢΒePԄi =ejG Vypٗ=|t‘CK{C%הީOA \ ]o$[0|W,ձ'΂ˍR󬘷8#=թxKc9=ÃgRtjdrUrլkWGs~YkWj$Ioeޟ;X͵&EXN6YV tQq7{\8PNpzϚԇ0d/r3\QбbPzz:ȭL7V?w$ٌ6C&7yX=0E97X68GA$c̣(`V9w?{2G|ch SA 7u?U.Y <͢ +d4<~?5Mtɫޖj\eA>⍥atĔ^98s@ɇjA޺kqZ"E̛:/"ppA'Pf_2ڦ?~5Ui ^CM/Z4s!:X5#jHHNXqJ]K잛r҂cl07rbg¹w+%!|X`ej#D'/⃁Xf+5g:Dwza2s{jIvx*-9$ߴ9=` c0gL\yǺ5qho)@nX9eBEji'\'Pl`PKdunhl楤9ߚ0} k4R&w.:RA"7(!8D:9UKD 1D:ߞ{BQLѡ驰sJϿ [`! 3ZLɖyHF-)sȗ/ˋ >2.\̟އᮐłeTǏU@ 87EԩQ<Ѽd qS3i }GkѦk)(M}6 jLLY9UXwvAnEP1P:zdDrj0ח$;$%6W< z)OS,޾Xjܞa]46Io;&3x 33)Nx[ˁ}p&I] u ߙti#g.{YeEE[R6e,צH>cG?!TX.T\Nwt)9Ћ 㸫UIU-%ֹ1yZԥr=Sr;#Bes*gsqkeOC;[18 ?]GQ J|$,ښ"ָ.L6WpcՀ>jB[,I{hGgjnh w,rv9TGPAts]х1DYcD !s=W2H_5~rL=E 8@(51{u#76rmW4{k;|ZUTC:1+ /b'aӇ_\ Pېǵ `r^FIhEGi(oD119 ɎTDx(!09 r(—Kˎ[H[0X 2m+eooΕ1Dϑp>OD2Գ'43sC:M7:9 (p*f"ZXs/*HS22[kJ8XUBJ9iNC3sZCb;Ds^˲Ɛ9 ꝋVKFRKȗ {frMa|3[͚)l1?LYkl$Hw5piX=O!W[ǦOuZ`D~x_侺c6ȕ2]cG8L>e8/qj "gWԓv3Ճ h= / EᚰG]41dԱ?M#V$ jDy+F95Y[eUH J9Aq B՘JjMC&j5:7(5vϚf$#SwZDE+u]e=7m6#yү̻Wb?:3|W kH(W,w\:#WE[(۲l4S /tpPl<#-Sd [*a\ď-,âes|~,k)X[N^X%<.uF9㶗ģ (drv1IՔ ":.ŰYT΍eR)2^Dwb)[i zDK8CKZN ΫKN{jY/ݧrk*=;5c>+6؈q&t5bA4qM#,dxo6Ո=>q$3Uد/}!5'p16/Mv)&7K%^TJ[BX֝ls'/ QI1]~l^`P76/&с\%p)xn.&cYChJHJ'l5}0 Bb-ۇk'ۿiz,붃|O%K,Tu,w>o\CdF.n/i`ؠzOV3ոul@nEjQQm@uO#[k9S̈YL\ȧDdU*ӊI)M[#YuPQ콅WUۯbacw`KBAIEQ@\AnQw`3ތ5b͵֜ Hi׋*,<6<̋wqV@{Er TN&9sc i^ĮB)e䏗9C-9.~ě.d+!Jh??+1dN>HPȱ-".uQ0,P.L@\TU.@;gZsRŚZ";y&7Қ1m4Rxو#cM˜ fu6򧦁/)FD73픁HO=zNWzz*{UCc߆h~SKj(YZʒP”=Vѥl5sVf0sbB'M~=?*=ά"t^v{\b 0hI1hGE|ȶx&Цg&D}Ϛl6}%\U{w )1f'H˵rc$B88Oʴz~3a'c_>z Ĝ FIfDoy- :lR[*]3Եmrel> 5Et[$Eڑ.}h"\pf]D̤v},]}.,扔."krxɩ&ٴ ew#$jK0'}m grĔ'2J ڊ' 5$v*?ec,ERJZEYBtZKTdhA|=q32wvpFn6h+㧙xdbm VߏB;#|nhZCqzޢkQ?I;q撖c4۬bcY1U.SaeQ"Xi"p/âsH]TaV] ^i\nNbSRs/Ύ~ӋazSVV apFbhGɔ߉pH-&xD̄J 4\qMYQ*ּ8 E0be3K̜׍podU-FRŎjfuc ӿ"ۮ;FIR-UVQ*UD.*[Q&ACh>i4XU ?#0d4w̶\#e>r%W\Bu W/9n N}D>q9˟]9ϡ98Y$M5fQT6~e09ۉI,M.i4ǯMe8g]BH_*OQ2X"j= ,ce26HjBuTG1 t53wwFP7FzV?1xFIE7gfsEW2S)mJ_r5iV"$cs/x.` &{\0fO6Y7/R~;B(mT;0.U&9#rÓi>oDT]iÝZ9ʙSS%m\+J3QB2 /*7ˣlfqJc|2Cu6|+`4ؑL}mS9X#&pY"riSG.]4l˦8Dg>*^h\KUVoҳaHݥ/6qI_9?Nr [r4U\Fu0Fg` zF,zu ܯ9-9'E>ndY|UJ%</%mo5DA#|bI,9Y9+G.d0euݡ[ GZ!/_ئ ku#,t(*{p*+$#Y+gb%w6DOFrViGu?~t4-ԝ%lK7r#LG&ǚy`&8>etT/ܷ1@cKhD띢OާEf`ܹ^lt=xS >h]3b-(?[&79Έ_4@!# t%r 5v3S>/U1l ciϛ!p]¯b kôL=rvCq|3vJ,R9TJۚ|\Oro ~\ =n9NqIx5L T9Yx9$#Ii ztOUȫ{t٭`cOų=JW w9Z ұG=p?C✝рw L47fnh9x,FLE:ttlYfZHS3鈒ᥬ=[n,а‘J4)[@ qfIf'GL,Up'ϓ]+ . t,*Fu0ve~q&7n)>GRI$'v1n tΡ3)v^t2f(ړ}z0Ӡ틡{k@b҈Ŀb6\9]3w9|3&ztv}9V"}zO񽖞 |E\ /kvF6o2nYȾjƯ8ONX*7Hq5MFr8?وrLXgBO- "ռ*x.t){c[AJ{XU0 =$?_Ri3_B~6\l{IL8)Jy21U{r>8VJEo<>9y74rNk}aLJ4?Ƴbc pl}"2hja*_i?N'j>UPmw|.hT(<%T>PXW3)tL?8s{!/W;8\!H`fBXs${-JRJ-ah9kwg3dR6%tZMNGx;ХCde'q2Yw!y>9*ԍop\5unCmJa~Mahx4zSR+n%yh*fL&W(ׯ7lYl'q`/jp',m"S񁆱b}j,;cwyP̊xl磞}bo1q̍ 3V*3'yieanG [nF%:j,oȲ>-D=6󻫑L|\gDo=Fdz>9BX-\rUqhe"}Jf=5~GK>U{Rו%f,)#{!r&ϕe!M zȸk'l|d]a$ʜa Ts"G,%]NqضNxJɿ'_< 䦧pII9YTcy^C~R\1bMnȍ! X #VMRi7+tW陼TTvt ^ оmTJ-ea",-p)j/CM{ Jյ]!~KY)+`ۄljLDu 5Ǡ@@X^OՏx^SDy` #GTF=Φ$b-ƣYs Gż_W,If͠(BBIIH,RMN3 }Џ*o[F2fw.~ }Q &P52jilM-{sQqhOߩl]‘ ,0]oBJi>QէcW{,4ln'o}D*F=/~Dӱ92? 'EAh^w|j2˝8-`8̏V_Xd"^H?Sp CV%cD96QS,Qcdg Fp5qi?Ⱥ&!R IZIlM "su#BHDz6]gz|Ptf2e$7*JI(fb^۪ydf:f9EuZfВx_GFւçr̟+hA"fѯfp%gS@ۥLB&-W{J.8ai;DҹK4$sdzQ B'n"|KKqf:7vI9[ngLi {)fڂ\-#H7oS9s̉O]HHZ=[<}v?]W;qܙٟ'Lz~Cl<զqw,Hʃ_#^$J߿:XCn8N~ D59m9'p[Obk"i@r `׿yL&ulhY\&&.3qE0PtlCsס*j]$T0# foEye傍5R IK̾>nqBQ?Wm&4`GlaÇ {wCTWT'SN\Nٹ~!\*~JC zERa%coQ0ZCu6KUy=qp=;kL^D[/#j#[3RPRr[EaJc{ {S\jD%],sEexD+1=D6 dzT Q-s"lsi6vFI6 ct397f^3Qd!JtJ0=9~$qW{1s>߃Md|&;rw5z5 - +;n(hooZ/xY!d..̩Cx[2t ~/Ε'P*/ek7`U*) VNłi޻xC9E &'l))A[VJBmϩ8qSE Ϋ4R䩏8|4G%UQB5] TThճ4jyIu%g nv<9Qv5>3QSS1)Ċ!75n yp_ y_6eAT6cMTHI.P)bB)4zZLKGC/;6xLNBw*A Z_HM,/fJV0EIō*&WԠpWh74)B)MåF:i'N eJ{2S F/R`Br27L H/pj8 %r(=&yɂL3Hl:C 0﬑הsմ]*i<čj^dב[CW/wv43Sf91Nt-OU ߆h'u]_4}9v,YшU_ ic{@as(ScW&br1+>,wuex3mӹ;c)3 3OVBwSr쥖 Tnfze ?D=ԣ'JIX0q:acnuU³r=XErUK~xQh.N] g }Y,F0 ^#욱KYxkcÝ Z E kQJ >:SW 70ڭ7KQϊ]ZLz6&ZN\\}&A&ޖOs5RJrQ "H!CKo)wĜDE"Xw*s(Hoydkܡ~5=(K(osA ΛJh[93r^L֐XVQ_>a,"S '&.x"PJLrL2꽞 4IٺYO iU,aΐLS{ C=Yb$m u#Bg.}Lb3:SٛJ`zo7u0e粼9"nTDݵۿ*FF6tUU]OraXycÄ}p=+k,zlpg;:aK,% to14˲yL¬*E4NS꾞&*$6Hzʺ8SH< #4#MW;kl w0Ůn})$\ATpJ#)5iQ>zT(v^'̬!^ibE] {Hd2:yb*]!/POarPVȣ6r41CBV4(W6bn$U>cC$DҋLW8ֈ=;\BȺb+Ink1˭E/"u)ǽ Ұg^5\6V|K[DF%IǯtYhgLDƾ4bd u5c׾B#+[(`a[}W.f~!CCkROX6zzb%GxT>'ay09Cxž\āēaF0N?u'VExvlY[k *!atVǏWBy}_f7t4ݘA^C2{,$͵c? = 1sث棎ޅzrNUbaãZ}Ō4Resz3o&i%:hYu]teRM./̙? /vn~6$_vHX>R-_ޘvmDS6E ёk`Ib8PNb^+SpIX9DF)fx"΅RfNQIqRw=\jΧ k$k,#TȉL]]bQȅf(r|~)J025tIr靎c 8װc$< OXE0v̙TX M̌cimq‡HlVf\;*YO G6uIr;{Y,v'=3 _"Sv7{3[ o7.vl=ޓ*Qc3;׏$jVW 9W>x%tYC&:-^Ȼ\x!Bl?ŪucJkŲ~t+C(x[z:`{/13Th'þ,R{rh/7VM` ?VfN *Xi٧Q◨.5uw50Ys{BK3ZzeCb)jђHOF4E4-{y>Rr)f6\u!J>"QZ #cU>SM5n5$gpW΂V,8ޙy _.дD AsIwϳ~|͖O²WK?HGp竞.`Y9йOMTd\  Q͖]~wgl[*ޕ]K6)$O8OtC%~ r0v`Rb@Á )=oDZ(?k]a;1k7Lվkauq=騰]ҀV5 7緼3f袡<Ȫ8i?ÉKp_3 PwNjF`Dϕ Q!J5z7ɑ6.pHˍ?jԼU!;|#vU,ofVG⼨h`ZK*5iK8T#\7 /R0,y8[?&P: QSRNF$_j]㖏b3wL~#թ践R&,)!Z٠bv7OOZUNPPC=:rsM+W~t-W^j%r+ +Mczg omhԛ'/tcF3n-0/h'޽ 8$Y 0)ե40#VX;~~|yK%o3^֐pf>n`EL&v0ӧ}|ryl˹܊w??@FWr9姒U {PĄLY3`@` [ ߄`8«$CB&!k:I7=ax2LH3W˸`Kz~72ϔSSK8GǛxg+8qwPwr><;ӎUl.ԆWq~٘S;('Cݹ5'm55}(@lAsim#{LƫA8q'0΋1l&+/#m,OFJƤ#96:AQ5{bk{~>'Ua9 zʰ0bFKj3>4ޛ@C* o'EfHQH;[YMg2` WϚlB.{Ld!@ǍqwtpW*kFСfXҙ/)d{at80=ٛi3Kƣ'ơ=gM,/3s4!fҡ c1ۃQLzdt6s{NY ^r_pzV_^7@ُ"obWC`ytӝLajl{!鎎z|6! 0h]OA5S걂>B )⼺0mMj9Ԟ/继k\-KgPl\*-~LdiNGT?S7#RJ;:,IOC p;GٴxƇQYESK:R894SsR2*a)ˎhDstH!OT1sWGaя,;SYA6^ӌ9]ҁ-8ӚOS!Kk9~;*@UZ~6>V41q) $>0{W*Eõ{ג9^y/aàTx=Սz nDGxqz8<P2)HtwU5]x'<4kܖ1*N9}2mư1 {#9W)Z;{: ih+0kec+\[D#y,U}D¼,փMCہ8Hk7#\ 7XH{[ ѣk-]U_pc +elMy iJ96 b.ع\F`\)8=,k=7K /4U,էY/2G kYA3Uj75mQb}Rb {C#IQG8."#VsR9I:Y*7F1m]͚Q$'1u; 1Qs:RI=잔g 3r"fIWxSp؝YĽI"9;Uՠ.: D؁ 7Y})zD𬙙_42~_&;[hդʨ`{x?'ŚeКҊQ/z0t+/zSR?Z1({V{R?O]'s,/%D"/o$sX̀]r4&p T2"{&B:x1G-t3<ۣyq,~tȺׇٖ#x6=XO]QO_`& ;8ySONMR1CM.J4hT/9,ao1Cmy1p~DErr,V >ʌ0)tJ-fbjԌm$oO3DC%:GLj-66)YKI '/au? 'RՏ ad5LG{.X%Ωt6y4I?˜t6O#'NeϘƊi|3}K88(Ny ?͉HIgdk Ns8,Cec&=R|@xswnex;n \:]F:)N,_$L+p\*4hIN!>(ܨq^ F iJ16宙+Lms3P.gtv-_" lNj6G?G#A\60+Sxf2͂=̇7^ggxP0Dd2[`YW(hb*$wYĘR,MY ŋMƙsO dY?o 5Rq`FS.AhaϥخsBz=w*20lL'Qﶆu1',HG =c2 B5+x6D|\Ɨ=R_udVɃ$"#NG'ua8JRIK'r> X@u3Yq2vJcݸ pgcWNrU_.j 5VۏJ'C%NlͷmȬޗΟcM$%/!aR!݊Tկ6.f[ʸ{ UоI^SNѥv=kOf.pQX{в18>$"#&~,F`cf$|ι]\Ukq\Vʱ s'kRdD>B9e89mz`"zL!Eeqx4wC{/%= ݤ  P#BG9-tዢa$fXzc1˪,[`_9E帘^.3"<%l /nDu:bf^l<8+Z%uk"RG!=nV%U41l\ɟ++iqKdUxMZGDYcK/#IF؎4;öujMNw Yp3t*zV^1*Wb$ ˧x6ifư^=ޜ'S~iLfW_<'e9sLq6W5-5lg963I:ܺ:M7C#މ D[Cp)XW|Ge$GGs KYr;9i}Tr2Y˷JUɘbme!)Iw986^ڋFȼLww8#QYDg'GSTߩt^Q,rb<}{8R[Up鬌l9= 2f1=yqt_:Wt'HLry2ғ,ÇDs&Ą0!!tUF2teeќٗD'$Z u2^ۢ`C(>8cƵؼ dp r4ǧ1 R99 r:L3սzȾ5R*V/6=+:eX> U?*&ZT7-tt'αF켧OJ~iRp_+ Q#_c+Uª.vF<#s(n[Ҏ'> \;Shn̜ýD*樐#=]TᔔR4XO*W ]9N(^B:OYgޟ{gxXZwE1hҒY8aN+T {#L%l(FYf蝅W*qqM eX\;C 揓ᒫ$&Z͍J6חsN\aߛ{ЯBZk{ }Ҟ |E~?Za?gKj"GaIgPz?kʭ!#1|mufUp\`z[ӥLN\Sbog~erLi$V`^ƫT9I5ZrjrCC ӹtoNXd'p2K6# issv7#ٷ E~ML331 /׭}*N9p6!Sl3l2 ړ )HٟF{JiKAuQJ6^ʞmԎ*ir Z{9w*Le1͛_b6 k|%la$.nfqJ/L!Re-ыR{-s#42BS#JTO LE֍Nme>s*(B%n\J[k= ~fj5WPNCC@-hZQ墾} l!#X4h</Nf=hKoNE }xY =7Q7g' jOuQ<[9_|؟̫Ex̵4$0æj4! fiJ횇"VѠ1u"3Ѻ-P@#4PD=͂<؅0`{}v0Zn"!J׵ӕ:R+-1`{l3ip-Z3=GiPřR5cejָ3a^.L.]?kr91#)E_eqv!jJ9UXk B o%M!7,o%s Z09la4uё_czt <&ah#S"1X<1/FZRb)d0uS3e/ȳ^d_&;J .HymJp|!na?K{!%BKl 'so ]ϣǴ^`1G^_q̺/JC3F%wza&QBcB'ҽU0.w<Ge5>PQɫMV.9YkJ^ޗa]D E劎[ CT^40(RG\wіbOB&%MCI0 pNFfsx֋!3}IM5G4GS^9Vaif APVр#*ϊڱ8zXqmyqC0 HpaG>LA|[ ⱄó3*xɾUAYjutqvܬZT5:QYѕtC񦘜H*:zӹΝ  »6չڑPi7+xiDKZstݧeGx{?]fOIu[l wsnߜkEsߌa`$`b?ڟ]390岵9;)EP45 uT?bWq6Vos}{>gK .N#~haŜo(f'ڰG/1&LUd>ۦ):č+}߈2))͙Rϒ]w"Sd<N2>!ath6<#pb4 n`'/QѦNG P_UuN蠝N"O#rYbk~_{ z-pnWlҽhzghѐ6QlhK47UM(nat"ݣ@&t9ss0O /;l+xDN|\2,ɣZ.lë[9hDAmTd8IQOCa7֖SX/@Q;>Fss$Y6!$pٟ=_,Jv8/qr{;M5-&d\\;p`]T\}P2ulSvT6 DOoŽo!8fH`DfHlP܂C-cژͱ єOOjlU3_wU8_L*mjحafj^l+ZբJ\kAPƹ, -VQ9~?+uKƨJrr ƪ.Wq/LAr|*ICZϞ?,l8}b3zyڡV75X\ݓIDƉwٙތFuRFI8W|rǑ8g_P9(8wSMj**1^)Vt9Ob3(ʜ8j#YchC79e?h= _I*' (-bbL|]^|FY:<Os !\9YŅ;9q n{U!^?ql 'f=9 KQuQ^$9RC I#]Ozڈ4{v\=)bZQSmkLaNFqU΄5=EZ JRX͞srSS̆DH_H.EjPą"KX<( y(Ha0M^b=X8"D_<eZ4+?͏KE^C;f);$&5+c WAtl^͊_gyV`d1VTv5v)L]@xs(#C<UxkctOnxrO6Jb sbo6]S93+r1/ X[Jur,|]!w>r6Mc$n'Ʊ}47]™0aЗ%GSK`E%+c&'&XS瓙HRN-\ Ǡ*UH5=HdHϣAULk:\]IJzVrS4tKoBlKJ1Q)|Nƒ61̉@Daeuc|67%}Np?|⫢Wi$4Te)5%Xxr7$0Q1NIݫ&Z5Z~ht—(O hL,8hnMS3\j ۏGMEWt'u8ȒE\(2#l&2."%Ry})i'52(%b7܈vi`=MtnO 쟗ѷNuRHTJ r&w(~ &ۜY}ɏ*'yy ,6_i"9$apK4^ gę}F(LFİ]4SF#%"9RrxB̙s9 j at%ļ6]L";+PVNK*VVd$g=dw*az11_h5>,<ɛ0 E >Fk =<۫98,ML،chw5Uy;h}-F-5eyU5|[͊+5Hp\gVsN *gWQVOJ lPAo+ Ԑv=mTDSu<-ft_S$Rïa{0^| "GY3v2MCD)s 72kXk.E`oI۪9Yu \iT1vw%KX3ABBɡKgMRpgMϋ8ʽOl sk2#S{9Lz70u5Â,v1?4Y?W\/I`efL/aC OqV VOI? EilGg|!t `^,FяD/ 9|qfx3k"3eSW%p8[vy"S͕m}h'/Nx1p+R,|N=߱=-~zԑ'Wa1E :QYj2~o(㸍r!EW9ifeVh)ly7N{ 0Pu|u\oBԶ[o̜ݩy IQ/kÂ}DHk` Ndɜ[A&)&vӍb&4n.IMe.#E7.R9O䴖8qN7r6ҲE`;}cDCbRI)峵2[]Gu 'S+S5ĵ8a 2Rӈ,ڔ.DIu/gU2~s%UzZ$V^αUP+UԳߠ kAOHf%/+Yu !Rg<:dr'aH'r8M/BňX7~`G>s,OV2eU1>B9ʯHc˚:7~ΘMzi 4o6 zw]|hR&΍ZQl㕢.VY/X#j'STuUtu+ޘcеU3+)J鮒rFN>B^-tEtx(=H,;v~On-ADF9aS%sX0*#X3#;y%cұ] I̭bl#sdݛO@'k]J8BƓJÔ|/3^Ϭz~UG:rx4{tC7|&fʅ1 |Ph"N!/MN dR_SXX[ynDj ;DZ$XJ bz`4Fղ LGП"⣢|+މ4]3& ڲTS"7m=ٺ׀uĪz`ہ}@ yPӅ wBc4M/WHCǗ2y4:D(!s-l^̵™(Q!nxgk0 >lm 4\Rd>3 4N¢E|_LCḪp-/kئ.nznIt%mt v8a~7tb=OճOR1ǮMl)0Dœq sH'Zȋ~r 쿤E9K}Y&*XNVgWJɔ|̷ˍ96qkcMN9Vɣ~Pf5.ԼO]XŐM|R38:4a9-?h0#Ó1YHpG΍w|,`|\\g_/.{p-7$ޫB]Xr xKRI1`K![:r|n){gcg g17 ~B-B X;Wҹ{:cG xX@+y ˣ,9:)wy(WqR㾊 U|PrkBos%+iDl?hy25J6F%*>PLSD oTpNi9񮔇+XtZUlQßwXhTdG5U,VjB5'T#}zFT;{\ίĵE%u,-Aͭr,¼}&-7GRqh Y?8eAwݭI^5}9:UD9F, D=_6ZGW[\oƑ=¨U (JFSJ¨eCO-.CUe73܃3"q*O8LE{LJ f0&| O^79s4Uq&`y!S8ٖSԁ? ,?c&6B 9l[N>Ct mEsy4 SL|(n #[#g_Lii 4Vr>3t9RKjWBRz { ގFҌT B0"fEzU$2Iǰq|21ɨ*I(Jݵc$ctUPQdrr Ebsx#<ңL~$|TORV"ǫ0:ta^nh 6.tN0Ϸ,k&}V^ލm</kZ"_̄PQD̙pb VSy: 띃P5deI1X$rU躜 Vs˪L%GB马3QnУ6YD'Us{59TOzv.U_ a+1`h%wn A>#LYD't"@p$5ġȊWgc*Ac9ٵ#?[%!KfsǩVc4]h4_TmNBe=3Xdl7ue9vq0Tle2J>$q?I "F`XC=w4A@ZK8률zɪ\[.I!DB6̍廝.c M7 ܑl?S;2[ͧIJUA*_RME/QDͬ2/ՋPRvl[ʸb.02VA;\?vrCIT%$t̘qɬ|&)y(L*dk/ iE\* x[żJ+eQc+q]`J% +8c9;۔27=l,LɘT{%53N+Sh)pNIlKa4䥉 (.,񸏖vZx9ٝ䞰0}.VGJg=wUyV5r?J\{tYKƤ澩B!иwYhCwOvCdE搩pS"0'8cܙ;_p${c'М>ߑw-,z>܁6aNVLiq xTVp!|x3oXq(&Q[CZ"Nà P`,_%Tĺ#S>ÞAl=1NOg;Nņ0`hFqR[9>jM|97/,x3҇yeл8\ { 4J-AgX;*W'E a|9? bxeϫ1T?KIJAd3p@:6qgӭY $,/E<-HTBUY)G3g}HqSFH[e; " xJrQ/G!/[e&^%;[$HĤ_"c~%XLi*Ѿi[\`"5/xVN dO wn! X~jh@ǽ:mXǮBwjo oSO`5m"4Z6-{,>ۢlʒWCsk%&~*cc:[cV7<\O6N舭z?̮ l<ѬDxfa>9d",RDGnn8j;Ӹgwz6&[E›}+DkQ%峐ϣYx+ԮiߜI̮!tP5s(*[!OxȦAhXo]M>]Γ\vųҕ5MȇN|Aa oFk?När([k XUy˘3ޖt,ܷ"n7q9%at&<'=l1Z^rI'o ro]!I,I)Gǧ TOݑ2\RjK&cD%Ej%)[F@k393{l!)$yٴӧWd+TVXez5 o<DgyפEf8uؚٵ"d2-Ta#j,װAC#tڧM-iӣӢ5SrKNQ%#a=G٣?@ҍ5k|xv6Kh5sG)8ٱǵtCnl )Q\m@γ9ڞ>fQ;Q!7Zx•6vmL6 Mvwr7w ,#cʓӓܛ.- \d)OU,XfD O˙oCЌQXL"!ޞFQh1H&J,}1SoT> 8."F[r6/Ρ}ˊ>uphZ^Sk*WY9rjV [)'g*~Qb)bB S2>Nr)+qP>%BױĿDYQ2.bT11/O.tlY($|@\?K^{ѽoDJMq<aidHXڵrEY\ N`+p(2^ZjI%롆ըnZ/ db9$Luc<:gzq`(S<$s5.5*थh S&gO`!ܱEV4ʰ3y W)6`bJk;7拴>#: 1{`F$I/:- Aj6`qeR&9<ސI4{雘_f I>a,5Y0i^:G NleƩՇg;d>AImCe\NJ9#dDoBpm Yw dt.t.R8s10-"f#1w1}|,bF ̝O)QelWnu n%xĔ2m)e l#f[NJy/1Gs^bZp\— AK>pAF>*qŎi$bmC4{^'.c\ƶ*FޒQI5|șMPZN`k\xu ڑӋ=1XN WPHɢh5?lz@#7jY:A)BU K6L e| &moGx2@#[OLBx;16~I"Yf-A}HSSK.:Fiho6ɔ[F7[Vܡ@)nFۤi<7vsy{V4}J29{}![Qֿ I:݉W0/0/ND .pd rBGw;\ Ch$Jdr$?Yc{|Qlv'DthSoq~.У֋52cEGmw-h(V5h׳9oWL0$̀. iݻ~QDb~K1Ďجg4$)r^J9جiT6QRS gx%'R\ X9?O"/02IͿgkS՘RV..B ʈ-e %yRY2&Al-֩E_ƞkp/WD-˝5}YASehjBH>$7{`.3.ܚɝ==7WBCsjzj0WM*TtOC殕x\AytO丐 JdԉH2MCqÇd(k]玧 s՚ {9Ax{)izyN|ykXUN6| jVd?ҕ`RBÈ]pq>覌l+:_%ZIL.I 3^:ZpIUՐR:h_ߏc:˝ 'q}OP.`q܊u-x\٤v4+K'CAG:Kc=?Mx[0ƃBCBܧBז(i۔E{Ď LjBҧ~)}JY7^BЯro -bRAA>u\\"㇔,Sऌ ;Cm*_}%?e$V^#6zܒpwZJ/zB_Je\|\>|1,k1K3:RzOS磆u=PʹQ^B' i${Q5,J_zZkteo1,̓ TM&g Phެ!TgLalj"x5xWͧjMAHb? D?I1Cnp, &81!p{ؑj#{3/n\ތk'<Фp%0kfx(G/s[t&|86i\6Fa}tBs\4S[PYqNJiSʁQ>BqmNٺbq6') H2K: 8 xH9o,'_PCAfR*&>UZsfbIG7[=+0L}ZH<-T7kE|Et'eAv{՟27K9w*p k/U4} .nEam_1*+Hq!rH>>j9b6oXNFJȹSŠp KX2[fma#\xЩ7R[Fb+ 9BJF} W%t(!@ ̔Sxs ٲ8n,0z?mG3X:U9բPΫ*ꌯFT˷ T,2Aj·O!J<=>Mpqo(gX~E #0tlQ1EZNI Wc.ux_ku18?C7k8^]?;9rKȽПkŃcЖs[3xL3ա$Ps>wu m͂S9%#2={՜=C< G/))E6;M8{uJYYBebMb'8jP9Seo'q4*cO3L_tKS0_G%4+Dw\I8׬}*o'}IAܿ2`;ąN?Hm Oha8uحK\; zQK1GLa}-[H8'C}43 Uj63Bh%DD:v`ɵk%bJ  y3޷B¹F'͞[h'3E.L]ɥȧ,/:^گ*ؾ7ɳX~Ar #A,/pt@"u.0[Gę,S̢La]={ʫ8_#nKknLW;bFBGىkEag (H+rˉ%'Pڻi6 }6مڈGms@]z*_$1+ow(M%_SpR nJx)ߕ|V9戧n VKRL*muP9e\N"34;)'ņ灘2/SоӽY(b:qM+B,9>Փ݁M J{#[sbڼ1_ cvƉ9ٚUړ^;v:6aog[O֧ܒ5X9{*xvAJ)𢂄!r,>rǕ(URYh,ǸJOEp7[F3@JUo}t vSQYz}+5\#z@V+rq2sC>a$:, %"})<)pJwxq'yfVTq{3_c ~ ei$SS2&;v]o S1Okꧠk2x35˙Q+}0%\ިٜJ~}k42B1\ETW&У )bY#D-wR IC٭*\{m̏HjAXKIqRbm%,cY릖ѻMu7*8:VɆr7)l).at9xk,/&1TMf,$"y%Vl=_'W2oWdJdvZ[~?k$pA)1m9"7!ޘuĦ'3Y1kCY3}'mH Z(]BYQe'[ZQ9;w@Ѐ͝;+ 熄~&YH`עx)$ bU4:<%*ؽ[zjbj1V˘ZBltx/r~/)!@r1+ 䫒5ڪf% [q9gK|P"L|ҳGո4OM!yN.6G R+!,JKj/M\; &pJt̔ Tػ-dAx*Ӽ&0"R&mUr6R +Zjx*:ʑeS2SyfkڇQiA3(OEhx&=#᤻9.>o7OJFj1(>$qĕ Y^ߓOnT"vW p%q DB%B/wkBxE^DvV\ "M)Y8(&k9u7ݙېԄ rr;$]+W8 HY"մ">Kh_!_̰K܎ϧ|Yğ\pcB=Y`ЏsM8yR6Mci7*Nq] ۪rg$ aa#tϥ#05+ zƇ_XVh'w'u(ۧ? O#%?)8QVCoĨ[Qس#}3lji-#, (F*7̀-F}.Hʦ^LCPʥtb{7twGɝXyNJnr[z߿i.}2/=rp%\oM`A&f%ϗ1XK(y͹T^O=%_ 4tK%ڍJZ߬ mO֜P`UNxzk虰&-KFaݬd~=.RSA C'엺zQOOak18ڶUU5#S~ A5}ЉN}]°$wp'+s 8Փ}B9L3\FR^įDZܿș^mChvpE=a<D9Vtn2b:d:ޞ;V낐9s"d&a+P°QI\ʦᴵAT/'RׇrdLehSJ),JCBYуbp0^}p粯cJq~؋T 8C`_4SXkr>ZsaWy1ks&b\/st\\N5׵(rbܗp` V0t<$D3kU\)WH<92Mҷc97_^żlY?A9y:;H/}'j ʴXVpG|Kf L!;ܳ 8F;2vmw^o~ ]<By[so eg_X;\4$kW= 7qI䧧&cGHSmaeK[ȞW<~'~}#t4 iȒNm(էP(f4J "q)VK) !pGqO.G3jd:sj j)1 oPI*^)3FI+l '{e/z?4uF}-WHL%|5V傊Ǣ(3Cx›=魫ž_<,jm5m5ةUhr-ouȬ+#D8*t+9go*m\:HZHi0Lp:qò7$7]!hcg:gz) SxVL& hBBD]sO88oj`7rVd8?q'lzph(c9B8ǖDqgDjIZ>Hq4pbs٥N{[8=ߖȲ/My8q2z%Q4͘1TE̓4WTAh|}F#+xVjhH*QRMjOWyt p B:3;x7&XSԜHQs0~ݬ8|g"-k80AëZnѳb_xSIz0 t^O xnƋl;6" .w̢&,k@V|j%wJC8Ç[֘%vLH"'Fs#Еk6߰^ќ0LY~B&}aNs_Fώ[8Qv/ %|,"|E<Ǘn.p'^4|P[GwݨX6a0ROE147iyÛJ#ƑpB0Ml(7.5¤4 tL1mM]uѝ^Da.M26VcZŭ5;zas5ghհvK ^.Q0b@qZ4X@.%'d%jXBIc v,'nk:,xQ`[,r ~NeIp w:0R&ٜ͋]ey-%C^_!HaԜyj»WdO,}Mj[o d\J7fr{Qzg9/ u&=mGq,ѱ~GAΝO( E;CڛUԿ;=QFΝmD;+i\8ǚ"S\AFrb6Wk=K豪ai!Ne :]jy*xk'oL% YBfOQ=\-uRO!&+!zx*7d; ^bnzZhXK-\t|i'N%U9Gǩ:.=K-8ckV2Wϝ::Vr\]M@Q5ULJ޴X7hp|^rrU‰ټsJ:-"wkt8UC|0}b̎d<՜w4gVt4`ԆDӅxnHЍ.KFarGpPeSHn2mTʁx }(6`WЧuMqՔ(4s&2bӤN,7ЪtqfZ "+-lE'&g"VGkV4s.vBMBVn'xzۏyzM w©=^0oi&k a]r$W(C搨%嬶(#I1K .iJnjJOa?Y؞\tZBA*aS; Of'ܨ)o*ϪM>ݴ4 b\G:U:t%淚 jP^̾jveLg~:5_M4tѲJ tiɹ&ܯDøi=plqL~ee0=F\?9͑ǟXDž8>&pq>{/S1WIRÂ=:8g15 qѰ2qi4<hka Yu;e{q2L!1UCf uTc9-CRDޘ^ӹt94ƓXn2`u cUǾZ.RR}PFaqOL;9C.P_e}-Ҵ Lڪuu0Geq .I^\.iN4mص#XӮ!e:?G|r4lz'iER'5_mDo2jI7#z>剹4YH_ X]'{ܙeJvcnQk8n&47cN%YZ3)bE&q?M.OD"(ט@RʇY6`i3vbdxk;c $~c[D-厭J昫Y[*ͩUdNJ34(>*ur@MKG1m|-$U=bMVrEkRg5K{^-31Hʒp{];#"8#Yz^He s٢oI\1CFDNym+|(M" g6~< 䇐'fueƶVUaٳ+.n`.;9)|ӃثN,QYsQ(-?mݰᗍ' b܍dG}i$Q{H u37DA2 sMyk ]b 3JXoCt依B=T0w"7zNM2xPc2[G?:F$iY\Kzr5:J"۟/$}N%|P{zQ!M;I踥ScݪUCݥO(FV%2/dY t- %gl&aNTN'!iur:h5a uǘm;Gbt9Kq 8Nv̷K&l褟lR8)rA{N}c~QF])vDNs(=v9j_rk73Tv$Or!ԍ ;l䓰|t?`< %-ol XuB0hhLhP~F1dwyr& j,N߁^9.d?rc ̖FY0^ xda4nnjFi=+fU] N9\5k:xy@=@wZ*ձZ6 0h~KX66Yo3P2bYAǎZ>Ul9+p<8ҡOGC(T'>5а|Gz_iC%|j`c-(fl=)[Xν<6&bq4sby<_09 ΕmW ;e4gKeo2cE ;2dmWſ, aHv ,>ۯ#7*4N{;qDQb^'2=-0ǖYn^\Eb+>$la ۅ07&2즾5yYjE1{8s/y0` q_k7{Mt櫆-ۇc0i6|nQ'{ 2؅K0k#sȣ(7Z4OM&(dy= o,k=+2O$xȪn*05͖pb ?|8 %c (l'㬟 =%d J"_2PZGˢX5_[*,иZK驑qC\^+ghCgHyd9k/|\eǰS+K`2|y"vZ^}jW| SsrԾ=N(?{ēM+!ڤܶ%Oq =*y]I-ϧ*Y_wҌHj=aQ '1R&cFr.(t쓽[cLڦQvne!Yi.!mt3zGMpj64G`)MfIMXOf[=q欳y/v`k:Csۗ1Yu:#3kE5p ^Bt`SY8db9ʿK,lfspYAЈQ0gW;q؛)l &9# }= @4/`;1 GzoGxcbq tۢ 6Mcr\TqHQJ943B$F2嬊VRg#E){ij&R.^Q)n 3yǡ1B ^3ly4J6Sg%T=%Tl9SO}i lfR5wH?HeLIsoFCHܢ=4/(aYgK [U[dq`Uts}߶Y-/;6g9v8r7czdȔK\8ڕ+=]Y\dϘKwg0';l#{8|Ã!4: QrnJXc=3Cxs" P1j ;$2]_V t>Dݮ-{5}Gi8*LAK\Qa: 9ēí\" k}wwq $9k ܂mm]ˎ=OU߾}OZ91o̹;GSWBί/@gVOq`ϕsC9O^Hm pfM3paG3/Vp`?z8c,BttX}Muri3†}5FY؅U;mT_;yZ_|1Q;^0Fn N,^w efpjG=BGmn EnZhqs&>~V\XsQqw>_aiIfɩ'9`rxqu+:*۰P-cpVAc7wO/,GvS"?כ i>yk8ryƔ]$qISͦuy,|@RktS_Fm%UbFϪ[*쫦k"EYӸueL\T@ڊLƬ}F3ӿΓIN\3'i\Wk,*`, `_x`UaA!Ua=rooCv@vF;Py,GsxIϹ{k-zCgmu->(#KldaiG ewua^2n21 aSʀ[ax0#3yM*nNd:_fHYkxs[2q+zs<3ưܛ-8zȌl=ɭHD߽ƥJcɴ$> Vxr5]0zdz2򙅜8^ yX!PC^Y1[9VlΐeifΞug;Y`HFTm0[G^|r^V,ca~ğVg;Q"&( " =&{\iHS.$`;PRJQ&_Cu9Nc8dñHGp7:`ߊt*q66- 8ٺU*%t>XNN%5(LW gbxν֧4"ȗfea|J)i_7Zx1w%d .|I״grͽh\v.$IǏEi)x?:vsgBsNeOsyb mOzZZ\e|m';_SqȈuv3f-[rpO#]7#W7FZf;نCq :c1 fUwSHE!l{ b \X\ϩs`!)-GQΥ,J܉i‰8G :O2/t_CԹ\N/*b?.rV5O5ڵ,x]BܝDG]N,mן>̾Y(`lEVA43@L&nCebUiz<^3T9I{Vh5q`lÄf,2&>+s+GK+C~Cqۺ}dnyTʞn4l͏G^uc/'Z`eocv[hVu /GWs5u狙/LXj̡|o{ wVql+QiL_tIkGkWjq_[0J{}gꕡQMѵjZMaO5"&mI b&{ʗ~QN m,kdgc(FT̠|_6yVe<+Y~v;@ܳ=aXx-_z/?䳓[H3¦?c2hыֆLѣg3aS_ C`?;Omrٌ頬s 6ʞ=kUWS!]; 4i4 o4,@\G~'<.֕V-Fe*G`pe>rQ7 Ń3~d5]7tRS5YxUb\qT'CUlK##MJϚjr_ƣ(OLxsFLJ _oBv%6l<`Q<$bs 7^݆?5TZ=)mvJߕljŶ%wK1۲>t\:ۓNQ G^\?W^kVHYC=;=БÅu3f9_gy`$'mz-Jp2 ^W~)A$t4;ǒʝc8/PqUǼ+x7޹DLCY* jy=yċq~te<ꋁ]8'3GΧa +QE*.g`x:-dxZ(bعLcśh BM{ 4ƐlsEs]r}Cg*RkM[%ힲk6-&<3LzV*eV,66I-6){~trh@lkqWm{^ut[gf9r3-;e T)],XЄs Pg.n `|iWmX 0WqF[`ƐKR'V:qO.B#D&NȸF*GEX~U,8_ %:qhĉ7[T5v!wq߆=sXlGzq(Vfja h7 y-0(ʲO}|Ŏ~4)_/N{zRŃ<ڍء|?hIP&o$t(ŷLՄIi54IϖBU0!R/sJ;#߷c5; Asbu?&{sx~)7!~E0u=ӑwH茪#&TkIUּxD'ΥlU7cu^.rՔ]1ehU( |hˉy4@eIfV%ZaDOm3NwGBt Mx=M : ͤl^ *{Bva1,k.e3n1}pm{cFSfXC*vfw/x{M?_Ovҧ63~U]c UNtOw#ƪAESdZsoYF`u,9k xU@5Hxl__vwgFY8)wn[\yAOew3S8WϛWL6 ܩL /氻2-U8t:ES҇!/H7{PjicIsy!˝Ƣg;9I@"VQt'_Z) ޼|.^$6Yp3v}03\fS[4p[ԆNƈޢ>(Ϗe8酊6I y>cOl?>/WmJ[Dz%927/&9=1b08g,Vedh62,X kEcP̤=s}4:p-׃ ,>>r^g3SHݐ1oz>4퐈|/Au@)}RSYe}5 oGrx[]I@,ɩA^NpmfN~\hO7ɴ9hW_1xfq;4@ti'O-&7\Y(})9B:$1^Z\br1άtG='Sݸ<ύk=x,Y{#3P̏La)Lj%$B2/3e:ݲYva@қBt,G RĨLP|Vu"ڂ*#3nUkJόV4O_͖zx+wn\(ua B _*gmPwFyΙrGKMKYHOT}I}:#V4]]JHʖg iGCV;mx`F1['`,ߤBY6!ᲂ2'Xqd#hr/!wE%P+cG:)q /Ko>?t  FYRz }ξLH^!YF[JnLlXo2;,w@+%zx$T~[zAPxc2.Th&#7I?|ֿ=7=FӁݕ{V5AWuL\c"7?C]v ag̛";oq5na*?fh{S~؝\wɎiНn݃NHR57KxY^*_3/W?ȾoʝGSGX(3Cc#K9Y|i3|UQ#{wû(l+f {h<4ݿQnAw+.N~ ]X*'=\)?xT^-ޒá oE lAԐ-hrSyv[?kE|E)i[q~E0FDs >U ME#;A?sF&Mm'y)ij-wӶ4Nl/'yugMH;ZyȃxO4>Kֽȵ ۷R̆H.P< iXNhPluᶨuA/HDcw]oVSuޥHHg»"󉄿mO& 6PaH1J]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/sŌ1 %̇ ꊴ.-4Aq"鳃nq)b[[c$o#w,ΓέWˮ ʛ6wV#UL!MW~jZ/_>їj(M#៌=Q4S:lT\wҐ~'.[>/P^17q|w?:`6d#5!RמNkYRFri򔾁%kq͙g=?ȷog˾G/{dU.3EkhP}Rk鸔Ӵd!VGiO3lH4۶ARO*RNI0ڟ7pVɨ׍=\+PˬXޛItS6C5#{p@Ӈs:YA@+շ&Okn0sL.ڨ쌡Cyȱ|dɬ3}s}9nU{ҘKKI vU*>~?FZfjmHn$5|˖{9BZI֭LSM&Y,Ů^"e[Mk]rA`,OU%W4+vz+/n!wrY鈛~tpKE'Kb+GozT$Nr+rzk'c I4etSL3tk.ԛF-/,wB#;:hPrsȥS.KcT?qFMNxtu$ܳ`^ 'چمkk7e=ڲ ip֑:٭l [ȧspm'޶pdǰVcGT!X+rQZSO:dh4C㇪ǸoП:翜U?T伷ɲ򢮿e[rYR۾~b;qC g*@QENxLуZJiMoԩ;Hkt%sMsD8K8ҫȇtl'n7|f\l-Ѿ*_q%r/Gݸ*<(ȿ%ۏzMm8mnș?1aO7[C5q$/>q1̅?Zcty0kVfpsvĝ5h|u +9eH!֖o[3MdgkLIN\7R/Skov2WRW\7U<*G~.ަ >"m [P+與0ĕ]BI eN09\=4⧎^?INEbj͏V]c0ٍ8lƄfڗk8kAF%P&.Pۢ}!z͌v!tq"ߨ3&Zї+#x(ot}?۽MhJOvB?0tG0#7덑,:oA0-Gzp5壟;=XS¾~hf]lQrZ-qgy;@j8)5bѿymŪN[M:8:t|H{;0R~؜IҩN5!=J+~uQGM*{v"G@o^KTGmvH4$ӞܴVSơe?nC5R{Z"=qby$Lns0ȄØSxgmL N{2žOkl=g06)s-a;Ƀr03GrC8ZZIvg>Nh5WՑ|vIbGe@wm^O}=_,Oaeuӕ0#u#C؋N֛ ύGd)2Uv:Mv^C^PH_3yk'N*$.=/~|:ŵh<͹`S_+x2@8/G1pp k;ƌNT߇; =yCx;U K{tpǀ+Æi)ljC}W}NGwk"y"Jq  U3<^AԆ0h653̙wPeOs$͎g.{#+&6һPN!lG0ʏ;0䓯uO/4Fbc4m"xБ B/Ѷ>u!\;瀽 KGcɆ}YL{bD<(4Cz(61eGL^ oRdI[>upq6S-nIWζAørrrg y&QwHPxft G8z*KG/pe_2"#ĺ}To_XfKvLhΞJT`P]H&Pؒ5[45dja 6E,wB ۰>Đf[XqˆW9r;k vh)Gdɓ~_[ 3?xHܬ|>Xg8GΔ(9zjO>q6Jaf&;se=OзFzdX $)em&C:36Xl¼)=x>s5}T4:Vz5TrxOEwn ClobtiIS2 ~O 9{eBאE=Y6;Mx'_iҳbyKNW{u"JG#(*Da*Rgn)ՒfYi IN$}pyPdn7Iš hj R>Ck{3$Zm=0r # uhN*G*71!O Gʒ%6k\u6wtNg/MlXҚ$F/'^_a XlG egRkZHH q,حF48;L"mr ?+OZmG6ͷe9z]p ~ILt櫁T9qqE僃˱ k3.< o-m(.O&?@bj{>yHݏ\SWVvgO3j<.50yߧ|Xg0wʇx;R^DFB֍ſ lɗeS*|{M`&]L$DMۍetҶsv ^q>"v[R׋ /geb~ɜ0xՉJ W:)EeZ]܉.mC(C}"¯fa upŞAY$?xV5_ 6+{8#VuVuvgi,-sY6LhznL ǡ&I803]}!厳Yy3atBiB*W2қbG:Ah`?NϩW~4ыOڣsr4Fo( ¤)wKٵ0H`18<ЇA<8Ϝh 썹{-l3^ٝV|!'5ErD tEIRo*ax@!֣30* %O`Z{,თw$挦.)VlYYx^<>1/wsu`.wɭ3IJm0;;B[9ݔ9Pc&w\>cg[Dt~ ? .QnNfp.;'qtXrҁY~4R?Mx_bL䆽"jls,&Q=s<܍)4? O&Cq8+b\F>ѢASs>k(߆ӑmGr?Tr5O,*zl;g-{}-!s^\?6kH3Sh$ݞ [ˇ6>rds41qHܢ3 n$X n_k)ZWa!5i-MFil/{w ¯(f2CnrG3s(כo.|:VܘN }PaXt3lKvG˃K#~/m.B1 ;}$.}`M!%NC _v O9s\:f;l}’to* UpfMS7x;꒩ޛZ#NueF7Q18<ӣ:L.pfhݦ_,ױTx dm^!+wjk"[:`Br3ذ1|ۂ&sZU?YxMwK-;+ ƇC!Hv \ǒ9`nQκkb3OfzH«__2/g*%4EGzU¸M Hhk'V[ r4^ExTK5CqA -&;q9iÆ*89FgH npoG]`doz'r3lyMHyY>{`lU!sLGڷWLP}">D(Μ6lI&"*'d(Ǻ/e+aU)~k3FH&Á܈;)ݖ wRAl#>ʽ YA3gV_ g,,Dw}2&$|(5"1JU60&?>,~9k0gBMr#a! 4q&Nxdz-Sd\mH~5$%=9Y>yd:oT ŌUHlfHQ*LW>e/ 3(#e~9rx~^1ץhF4v@L&΍>˙Z;?Jq9>x90+6 :`jU- {Fe0eeIGtVA`c&HiS;_M} v%?œOC\>bAM 7?ӧ#el(}#X=v8}3N2`lZ?. >?+*.*G?"lyŘ5n5嵊x3Ҁ1믁j`ؕ2_0toQ=+fV׾p9m$'aYܛO3l7R xSܛ>]dj:ʗ=ԆpWR9QyOccq,Vdv-n,7y}2r!Nh*dƍb:S|ϷEDo.$u)ya[=<R~څlWַTӴ՟Kn4E)4T>]rr=SJ!c@P>… ̭TQɻ^l t'ؑ4̎ ڪ}D> SOs3|A1άuA7̟rn64Z6ARI<=)JMp, UJsg_R|gʹ%LrLeJ>p#6bj-55gx=oJ cr,A+ `}v&\>sG7RxɆIlH,4=;W q/;FmqKS/ztntQbhv̬u')*^X$-KtRo'%M?Hn&LxL.W2l ek'vSrB~QL\r-YbߔHn59zh]3,:OѣH V*ܠفl[Bx >zz37xօuwcĠ}Պ V{x<;CRT͕{29Lhg^&hxrV Z֛QW ϙ"TaG ~&s{tNgzx5VƸ4Ϻ80?_zsۉٟv'FS>){K9rضԇFLss@VmjLNQx !_õ(cFK&nY;#ˬw,cȟ;΅L.Bc)uI¤EXRN-kQWH˩~Q&ԭfH^5| c҂x%Z-PEy`݁)60E䭥Zc_ŚLUfV:tl0oJt| cڅqprFOt+rB4K(3JWIrfb-J5qwOB`O-^P;;t=pι߹#k FBZϜ{BdMɔ?ftbA(8:`>$,fv^g!Θ㉕tJJCD3p(wbB8SDƔ 4|ˢ _t 2Mpڏ#әv؁CE6lO373L002#֒W5|12 e׎( 2~?3'g3ncAx^% ?4]yo|F3v{0mLp#!sɡGx9n("cJ39PA?pPEŏUPs!Xcw-?dޗžlj!kg[eƪw>bCjp ' dG0fYroC$1GV@@|$/_@6fHm3`\5ryڼº¾/sGt$)-C? 4c6 #̡ƜW.^q9UIWP;cr!ȖSLO3

1GeN%J7zO#њqFb//8Q֍=oQn<9:֘3̘Q̝Q>8*H=~!dZq.!.,7_^{q5Г^N5_݅ܘz܎dG)9)gi%s QsVN%_!RBA\'zسr`y1|(9aw㹘:FQ:k#~ dM,d^l 'f:R z# y(Nl*Vcl\aFH2q=]Ogb4U\"t6bLv_2Zm۟ʭAx>s拝OF^'TQ^wR $' #86n&{'>Aa!ߞ!~,!f6OwOy\ΚVUT?28lD(Db{.JU\kȱܵh=?AܙBžQ?-FPLuyFWjvжՉ-83I˃۟7G11j2?,Ɇ#9r8ȞEq}x1+-lud.d? NL慭@oA][tbKj1?eh8ޝ("8E2>@n`<*y&uer->T1t[mk]N"mA(\?cewMjkJdK]_a=`dM'lI }!s4W5ϊo+ *F~qפCZ?]0QnkS"o%$Nó)0 ݧ ģ,"oRRX_Li>ʃUhypO$;zP3LG2y!JfMWBzso3KP*a_a]4J̚R*DG_wߗTuK\w+S|Lŭ#X=X=S:Jc]+Ŝ ;G gFXfLfDC}&p{F_>F~XNDR(КT;$ 5~-Mk̃Yy|ebdwsṸeaX;\dJ%zc<%ES~ju5ϧ8vPɍ*#gӳ,`b+:bw8@ہ3ܻn{p숳((s;\WEbaOWf,7C M_-WϜ1a{*]kTQM‘a|GZ7)EM&lN#M e"2lp6.: U%e%aE/YcU1sLi-vlqc?>ln[ɑ. "94nQn,kL6{4R]깆ZYƝ]q uƺ7+5vn7=p<ȸV}䃐 B,`JI[1Yn[ѐ2k,5A2܎inu&0="؇p2$/TpN)/qX*Sy*#IJ)XX4U{5CLpI%w&;Hޫt=85y1;ĉ_lw_=go6e1qyJXb#9;k0yᑌM xv\cN%(9#W⦐rU>f=?,l2tasZ dqlO ܼXpAl-h:Ֆtd jLd xfA$40kouk&Ɓ~qgױ\1a.6\9,c2KlM?V`ܑ@",S35ͱzBKfѵ+1]eϙƱ$dhTM7Nq,5#Z<*y5ziE]e/o[uw#5YҪ 'y%7 Utsp+eH_3bq a*Cΐ Y?DFJf*Rm'R+lH9 Jڱ'kcq.R/[\ZrMn_6`1'1ܹGH-Csd)f'،w&V|Xi L Յ}~тy\8k[}$3nK F=*i-rlT5W3cT)43 m'v4߅4řX7(H$BQ%2;Fܷv̌I8,pN?̏O]4cagu߯ /"eI哄&#~,Sn4y&CX93\ HĥJ mT4X\΂jMSr`bSm6C="6R}Aai5nD[h)|%xꔢIYhri 6d`)jĪ^Q hp^GsJ1{ NddEpmi?# 9\A&fZ0) 2 Z_No]g&+-'x>~<93ȞDpc >%؊3^ zɥ[ :pӁM^,e,m$a-Wb¼ntt%APz^&|C7O\CK`su0wR;wM dn-hOZHJUS(#O.,珃VGLƳp.Lȩ^LZqE$fnq3V?"vzH>1ݼ\F?7|V,u|x_]$8G%K=ͧPvtzWa]K@5mYh//E} <PKDj>c[IR]ϥ~pl̗>t*ʹ񯌏!:P)Ȑ*bϖDDʻ2qn.#n?7zѿ8Lε^ǚۻ|i\{9g3+^fҞN9ص+gn#'zwH#!wDZ"@GMWRV k wK9wL͎ܮ)">íe1f.hslONEq-ȽJ7?&d?+75Y9j9-qvc Dil7zױuu4!IKA ;UQ\IB44]ZS $;ۛR@d Ý;a(23vsNy pQ[w(+G/~ Z5Ԥ슙S)BRa]Ӛqaj<rM+Efsr5ʐ~̣fy*K0qS%J:zTVwYO۞L6m 1m8ӜsH q)Uqp5p~*rљWrf+F0/G$ dqUmx%z=sr< n,gk &ue'B /Wk3z WBԢ} -p@ģ~=fGjWgV_!RގJUv>!dOP$}uYdUҮz5E5V6<5?#H?BwvIV>j/9cᆳmLQ;-ên.ǵk&4]EAAu$pRK ߖWSG_d_9blf&r(m|S,ٝjLr{3 ^")~6%Q>PLR?㸡*i3@FEܸPFrgT2p{ؠ,{TR/f?˙TVI,Orm8mYsJq+} ꜜM*8]$7_3@%?eS*n|:^7khȀ@+(#2MdC50RmZV.Գ'Mآ+lD';>-t؉-=E8Vuy4ˆe|_&fqQRƝ(ɒ׾č9IOX~ؼ=±}8&_?:Q^P69*[0ʡ_ R&+aM{ƒ$m(I(< kSM4Q܇Zevvk3M4KN}"w>b=Rgo*-=:i(=fm5jxb0-ުtP)c4jzMMUVpM&c?TUrIV}g9{^r} GKW'&w}#Q:D追X3&+""~(%'ٹ7?FD.KYIj k:G%6"/XR55d&V3,@_.O*֯d[bWk@?}ZFku,,s;Td镼WE==ϩqMհpJS{^Prԭ7gxv 9GiVZΐY "#U 3{mgtqR?|".ml\b-^H }$ePR< b i&Q,p/d}t %63r9bȢ̈́T1A&{+$%F{az*rv^<V9R%yTx0W[e8D7@q pʽolOS}AtCGUSj{@P=|DK75-נ㠷cTtd(( U0xިhcUݬdcm QtEvvm d"/J5?F Ѫ]/sd}];'k3tgY*IY@swv\mMğ=!ml<&P=b3feS$ĩ=!TTSy5ש/iWQ[]JgTuMCq\6hkmOG323%e`R;h*/cu1HfL`.$_$2:~𣏒 *9zXnjzĨy;\ǒz81T\KOEtZرykπ>]] =/t(HՏ4r\Ok:MrQ xFb9b>5-*'#?@ ${]X0k:z[bO=V uiqX7g`TNAX}j}ǨIk.X lc7FpAmsbIſ)xSJ=Z呁/fZk!LW񫎊5j΍rI5y-Wt#Бx^->'˫HܠK-CmLSUsq]X%=epQÙ'jT42 :?=L2H(,GSNE2F4+[E-J+eUT1_cԥiwKܬ|RL#Mrw*(̠z*84R(ciQLAISy-RnLJ#28*)PD]EqjWi(rMZVbZ"@ Yg]1+ XC霛_ˀWEIo1Ck&yE,buI[#&/]kGꖬ9:ȰI2rh;wn@kI|›Pw19!dv!Wj|i5+y3+ٖj|5Xd N5i3j1yTPc%:MfJw>zk xY͘U~a  l1砎WTC7x+rlmzĽ-:dxoȥ4]EN`_!!1,x0tgnk?lYSHn fH32eS얌A{8?w(yGJFA^E\55P-54B\:Su`PE溪8gⱰ25hniزLMJVTIOGD[X{Fn^,T2;;[Lqfhh _hȏ]O 6`^a*Qce`ˆ&V7p;G}HoJڎ ^|z/o"?j(A#yߩ$ݱ¦?IfS[Iob6\9wj^=m`xOY""B×Zk(_5ij\4L=E5RՀ.UU'P2=nfГSǹp=z2-#,Zc1GodK1>u$4UU2fEEHdmiEμ',8'gd C_G$o61)Ѧzj%,-gDgjn{kgyYRXIQ<򩬒*%aYJ*E?x2_Y*84]GM5c%:588 F!IW[i8<]EBάe`Ur(z]NF9*][ɤ?JY;EʊC;EBNεZZ?ƶ9*xJܯ0_Ukꯡ3znSO~FS~XPټ!+IvWY̘`)qwdW.l+_Vr@>ǒ+kXÌ3:5EԽS{Vbsy5*=j|_MqTfo㭖}bo{U՜j+9񳚧k׿mk]Mt^e"zt!~5?yu5 b^J;1WMjE(9$fYȪCTV>Gel(GWJ_a$>ksK)ƯyR><-#Sg)pfd.;sY0t*:㦩ԛUD$"G/I"w< sp̓oiڦ' m*ٙ\xCN3@Ų -R-w^(j-e))2i\5I%I0|*Ia=W⹽U\7[-YZr1O4u%2;)xbsbܦ@#i9 rg"q&>TOwer3/j_1\o>(d9 ^YEZH-PM7Fb6:7)зeikU|ʗп8*D*`۵|F9 W*XTźϪx\?+q߆@U'ٻޓXVپQËo:.>|nh dZU-9-Q5V%Xsqլ.jƉXͽ\67P+7DUÎj{R1_-WVEY?G>QL{+pj~T!ƢN]= Nd eX4*xd!g19}E~h&GyKRك+Ӕ1?l Σ,bt$lF"ꦩ5Lyx<=T*n*'d?:~Y~C{.U?KoV^pkffbtgMR/ԧXK5LbHe"j%j*hi&C=u48<t5Y̼]C}D4\z!:V}Ԭ EoTl'~ gYh`k ?tU Ucw Ŝna:53mդ0hszZt^,ɞ3_CE?YW\J2P("Y.S9V[u cR65 }cT/f6ͮ!]̲izոQyYqHtFD3ż3QSUJ}%do{P9o*Y3~f)52q9+LS3PT}.+n,cJLi+p[| `rS+CF9Vt (GCFX%ʜ*.8R;F7qU1wWJ1pPC:F2`(9ڡ)a;?o<.c^l4/=kY ܩ#츊"/YA- eIg[ҼM~F#kBrKޅ0;8dQu#>-C[ReV0e/D3.A4ɿ"h25]mμؗB^' }ش`e;,|*lcF"eUNx[_&)ftnk 5[æ5. :Z6o c4bРJizRH}ˆj/D&hyD6rpTHuF8{yq\L;bێ6Ӗ7[ڱwwo MK,w .Twۖ1֦*ђ+ )xaKT]QfI%SZtܥ\I.RbӫZt|o H iXr{yd#7V CeG9 +8O%ENb/hTy'Jf*NE5j'2h5YU`yR.NLx{v?i=DD;;tC"w h})MisΌ&[/\)..mUxc}3TSU7$`S:ݗu {Wz~$+GάK"co#P% +]JQe_!ݫ<[F$p[ ;K*Qhk+9[(yV_ה$TbZAW7 z3KNOr+4HU1TźJbl՝<ڤIKŧl_i^Guxq. Mⲯ88V:cPb);}"hꇪ3f[ՌSzKWV?/CݕVE6/7!h 1;3%X>uf{ m*`hÔB NaXyRy-GXf`2Qp쩚t4V ެe.{txҢ%^:^0~ .LezP8OW4. ~ gzt{m)QDjA=hpalAb<[~pAgF5s`^x٦ 7cNXs {>7nW|@(wLɾe6{렪mVTFEQDu(" ]t݁3u?77sמ=0k$bxܙʽ3bI_Sk!m~B&LxbLd1jä"[z[\bJu3~d`OmL3#+yTܖ+2eQR1,VR93J _Xxj&WqԫLJϖ@r KJVqb C$lf;DaQAp>vL3 ԶX <5_P$ll O7%/~ wϗ prHۈ9W^<`X!ݟBEpiʥA=A,>٤?ʢẌ́9<Y,DTp:Vɦ{t$|xLHԆu.*mCfѥD/o'\<pZJ}urƵqMԁoe=bS0s.KdDVQ§k\i^XmtG{$3ʞ Bk, CkzV;eoМZ*q - ^u@HOsaId*֎VV4Ϝ:C xXˢ~LJէ!Q[l:& l >mƴIveɜRgs6\H(.=,, nS}l:^c[~!} ?\ eO'04ʌLپq g[5.2,>w?nl¨4 n^\B"~P0>GIjKcJyQ'eXZVAJRZnNRnO*c2V9Y¾ h&cvci ECʵۺ\Zق3m~?wwo~"t[yXXY_ՓŌ9ڬ#=c8wkRܔ&_C8#a]x \L.EIЩb͔,gr^cD]؟I{&LILS*Ƨ5PB: zf_CÊ25.sШÍ"ǧPS ːT`NAX9*X;C-{>>B^n e@k?fi֍9ؖLcP:Ư 'O +r 3 ҨhX9]l[Gv0~e(F\DC$Bdž--Ƙmړc?+GaF'4hySvˌٽє8iXi#oɸ~w l,ɛXGaN iמ @H0θC&ǖ?+w` !-_rv!=']f08k&XTj|Hal:VݕXφ [9ʏGYt}_rȊp,)WV̕;( 9g)xRIâ1'DNL\%d)[ΕP8!2 n"[ D^lR" rH^ LO*H:gm7º*Pn&c PC~$Kx+u.-eA&7MC -怪~gSހ8VM"?z +9YF%TыlO߸t>I[L*9x,HaSr?6 xhh2廂IR>*$oP1R"wIqIFtb1Md2+Gc/AToE7zOpO7dOݿ\x&"QXr J?nQ*+ë8VɅ'eXF~($ْ0x6~͹z;̫~d) { S I_ɺcӢs"jqbz^K4K)zZk@.6 Lyuk6ah!Zh/lh=Ta-X顦xcNIw~4/>j<R]]4!G7q>S g*a3pɂ{14̂@pF*2 Ob(g(,A}˹G*)/81p!| lYW^4-aTNFR _H[LB,-\NaLxgʌ(l4o.L~!ӆ%=8?b$cNM11vC)Ŏ?H4gY r3*!dd<J @3Qw&7db:F{c*ӨN|Mn38"wI$L$aLnhiwaޢM IVHB'䱳-)A94/򦝓m]GZ}6=mΖVzn͕BA{+* .祘M+TƱ/$-**>2v0)YǿG=*#\:J+;cنC<ь_vMdH4NccJ]eS:eM{&d3SJ6eO3Gb8؈bq+N4ȬU昗q(c_kT pgdϱ΃ؽbé 8I4Lf{&&~6XE#;ވy -5}rs)+!b&n/!>딞ޏ")bb]0X">G9IʹEL*bx[9_ȨI`dƱNY}|3Ds,TS0ڜ`fk=|/2h\4HIlLT$LL$VNbC_ҴO2w3g /I8>ɶlI`uH"PkA~*)4“Ui0O܊dnqvwދň<5(`"'w?WD{Z!n#δ>JgpŌ9xFES/r!L"kq޲- i͆@ܾ)ѮrcƈR^T[9=LUx1&x&f-9ˊMs51v]"wkb&O fgˮ8Wv`HfW^vEO`G>VqZIʺEd8gpt} BukCl[+;Z9f&!,ڔuN{eu®[GF MYAzX>/cΖUF H+K GYg/܈VuS<#hPê<_Fq|>mrk7PlxaufSg]U ,GZ1"bcnܺs@>By8٬CV3]1JAg7sܼqkIN͏b(Zp 9.tؔ|i箘ȸG g2)kgH%O!= Q) df6>Rv4`~EvdH9Y9I;y?9j,-X&QCyU:P~I"†9ˢxL}f *w lkGU'AX *& 잗D(#*qIUS#/aIA}!SaSˆmN .=%dD;:Zm}&L߸G|B$r&2b8WlWSr,>bR~ٗӸXպ,p!PMڢU%miv|, 9l.p`FY|_<|m7}khsg6OyS(=/Fwsh/` mhÈF{O(Tj$t+@{*|0m>g40ҿ?(?4E5ne㾸w`oC6Î4MRN)PZ$24gnq![d/RQJRRJJY}U R,Bv$+$@c Dw1 nn#(-B\߇3!LN1"6ch%eo)iSUKƈ{KbFP*/-E,UD ϓRv|isI=yoF/`2&-c UEb,;Â'c'T4vIp88VG䛩_GN"Íx(b4[#|t)VMp:'p41ټo3ajۭo .F#. :'BƥF {-Bp.Ѣ^`4BWfD#p_Ĵ%[ζ;_]Ff{VNOJZU#~ >yޣ+Y]c"LJNDLm͙Δ\/Ug ^Le'X*ǑȶdfsN>{ Yp߫ UCL ?)Rf,J䓍x^6DɌ:/@R|)g7-?vfb8)7R'd>(# `@AH"FNn{m ׇ!hQdt%^J)qRdO%!t2BzTg,>ˤZV+vBҷ8ĕcJR U<2+}[~Yĉ4JcVɹr13B&%,0YM9פMR>GƩJVKdjj j0Lߝ*S-Ǒމ bj_S=e@}D0:QTZFz$wbwNd&'sIm1bt&aRmPLdxdžYN<6ci0:ϋ 4̑=Rڒ?> kw§ahёofjȆ}ʖ7g}+_*47XU{78 =UN&z]i 0-sZʙt舍Fq\Jַtz_LT=fL ]iK4_`0}<[ QJ^mUfKeKC:IJ=NՈn3LxVNo\WT 8? o?}J 7#ҙeZ9tJK?ƌf@pzٌmY5ҁGn=o24 e4JQ`}RJ^Ηq64:Z E6p<;k2#ˇͽ\h6wZvzeOVpڅ_=׍+q,I 'n> f.)iaZ$RN,¤o!Ӽ ZMBя ~ŔLgwc/fH>9ƒd_ $1PN_ 3Gl8hϝ}< OP(n"%qD HEv^4f"Y^xlNeRbnqlbO32Fe2/0cfi v!ٴ??iw>{3z#Y4ɥ.W3qm3TLD͡K*>ajZU1^d5d-yba ߴfk+'PʝNBqlxD.*~oO{ &':m OKEٵ Qeo-CP[ y>ԫ9 64q6`f:^`}LIگ9,>|uD&StQL;xoeɆHDsg ogt)rs'Dc!ȈC؜)&q%;ö~XɦHhƱ{a"XЁLJf}0݂;tϘaTs;NBO\,WW{<7IgG0{z+>xLBh!=gR4 +_=:.̹.Tpy4RAqpAG|wլϯՔ*4+9v_+"A4;Sə՝"! s0b$J,8ۘ QXFt|&eM&rF-)xh ުJX^6(8/(RC'1@[gS1o A{κ'n7g]]#b㹲>Slɝ32\y9+z0hH62NޔצJJf卵,fqM7)#b:J"c%)Tl9?.)Y\-ào&yhmOgqF =ܟF证EiS:wȝٴ><اd yX|1k1U]<;s>r"zJ?dm  qQpN>+bɭu2 cGy[ ޒ7qZy,.9ǶͪYA2:UZv1su681zG'G+&19͐vGksS_&lf&7{ YC ZrׁB>db獺]t=+|B5݉b YqLj9DƙEyRd:pOOQrn)8Z)f3R,ϥl:Ø)l|gs HA;3Tld HbZ2ӕrkM\"m7wXpus_$,~$1Zs-\A;G7i{x֛_t77{  Q.>Ib_HVbuևw<3ʙ:wĴ3F+yμ7fkNB-)gX|"fg?͍t4|{Ϭx>X\_: ɓSBǂï'BIG2S{&F R+q¹+<[AڟrĔ1_H%U ²qwS?~^}jjFAiLץ)?vNuY?ҽRGoؔQTVNZr*#Ϲ ry'MYsրLWjz;!m2)Z0}ZaP+{20m5[$85XPЎJCɤ]I۟(k fEP6㝥H%im%e϶"O(:!E:V rw2zr2r>8 a'22:l6E1}g [a$?gM~ %IecHjE"_lnƒ3E"mEc)ź dW1E\akRWЫIz,nr FPkH8 Y +Ar1v(C dx7+<[0Yӝ6aro `/Ba(N 5xV8"o Ū<_,fXnD$mI &=x`1+G0]k=VaĄzA2煰c;Jc7s$n2gap|I!);ir#=O?%Uѫ3WUeX=d|ZֹhSE!lA)e92dg]#2c%]nl˴6n4q X:xCΖm 2ZZNm%-)O$b0TR^nL2b0±Q}{L',2hߪ)} cM7Y+[ jN5F?OAFúRRCpPƤ%dRAYŬ锏ͫles6so42_F-BT: gO}>DB럂o0jX6͝t-a °MM1BrѓQK>x4DaeyVʆ/%H)q/Q %P [NYa|brasOS%G8.44Y(]  ^3k&ol,P8ԍwq^l:Ot?VA ͜9U{/xޅ݉Op 7Lfy𻯘aJ$Oc)iL Te8R3GP?X}0,nh ЅEZ tjt'_X7nsQ>~,eDOMa5#Tz>L_AOJޭf\gGyhGi ksWzwySzG.oYT.N6Ms{E)sEmR]Ggk2\݂r޿o݆wZ4Wd# } $ht(pLy6L eI&3>a\Jˡ<.Ǭ x'۳5%`$Q|p',2y.ZPD +NeNDNHC8s6-c;L!n>Sk_lIkˀF'GL#;f3/nmfDNm J-٫RЩ^=o)YϪj3I_>O~WnqϬ ЮKjaz;AzLږ_7в1yC-6vaK:sV'x⍥/>Wig1<AegQ봣9- C$KXAtK<7wxX#:0t1)aȟXN঑a<6&g"0PΪbG<+QD'KOc۽~jRCѢeJ-UTsY|>?KZXŮӕ=dSR-"q 3cãZ)%W f\r^Լ\'s}qXm]θh^5H2զ]k4V ݃m4$A[#;[Q )ߜ#f\®6g̘c|Ə3;B9*),Lr?Y̳K(AJ>7gU2i55&,^ͽSD}gɌ(p4n3P̲5X2Wd{.(пmE vih)kl8CbK of]t',9ԁ ř*%t]` 2P%5Aަ%,;<[ T^ʄ ԤfcW,<=i1 o͙`>eϧG ow)hq'gr0BeZ\jNa˷<5@~sg8%9WA.#㖋?:g2@ jLEּ扟7ʑ^^N,bϲV:)jdoT7+#'hN7,Rn7DJI5J+Is!D`E]>]1\yjijPj|pJ5ˀB&g 1 {8nc‘DqoC4q$-JeOcȳ9.c8 _t3YƵUVE 7Uѽm5bqt.Υy:PK*lra%*Щ('{U)G\U2ӤhYɞnUBi/F%T|TohM IYR3ެTw l=6dX`3QÄ=-**AͶi-$ #yuu%% O;3DOc$Yqo0ȓ,OԲ8-Wa$O '|N0QSī{Z eiNI`FGk(8ћB* $ԟԟ~lI?;r2-^佘`wm8MD /zU4m&&d>d3QTj^_* TdD5YFQACTn\IuJ.4T}j)sTCmx]ɉ~2,.@əq<Cm_Nzq,3:iⶹ5*ҿԥ˙%ׅ73٩C*f&̪|yL:-'~o)5e+gYO(Tٴ2]>ɷ<'Gh:Q79\t7x)De1lG.T89F+(-y{9E FjV8!4kO+jυ85$ !4IBXNʓ>R&>"@SL]HSdY?fGuZtƄK(FB deai|>)lcީ\oDӌ4%}RDf٘KbgJqYWVU`!g22J gg'6PԘo1tЎϪH5.>-BE y#Ձ͐V: nëtD*xoTKh|&[ȬydTV^%M:r!bfȮfj5k(Z" UTϮ]¥%3/!{E8,{d%aڷ $v"/ń4Kn 9?}} ](tU1@~8yE Do#!dCTFsFףŢy*gr5 2%_HDUhTNE(d>5@o+>pU3wy<&iK n?ofu3?y pQ?90x -|߰"%LZ$ڎ"æ/ ca͟7s;Vӿ^N%8k 0DFD1;匸)í>" SH2/D'+[*nHhʰ<<g{3=҇/~,TM8 bQd$2'$'9;4%H6 oKÝ4To%SM8>e˿hnNA xRd(ޖr,}=ɔob[<2qF8EѲ!<CP nLbD2Xk.ɲZbuk0n|p-okk]J g,kq\Xݕ,%1z!ξRrY Xʭfj6}8+i# <HKn\0ng7zyN. ? iLNõ=j ޕfMh iVSt璮BbCv'ꅞCY6%+ePH)c>(EyBm*pE!N?SAA%t y=;G+mL;k| w=F3OԀHX$["A”&~:=JJggE:roOer[(qQwr6,gվ VU|Vە_lLBfnecGHl <4|}tYlyP ⧤*\a5נYˠ)5zP]x56T3Z5ߧk J^VR?%(y-*t?6}g+n5bLϰ-QWqt3gLf%C3Ya5P+{1Ȟ=c9VBX)Swt ]̌ _)&*ZIJvZ+=St#;˘S̤*({oHk0>;cFpw`pw IHHpwwwwwwww=}~wW Օt+i9G$ĝףY6(ӀÈs7ubף@ lE&VK+5A},;mYy4ƛ6{q!4ۉWk|M# ׋+_&:RmܕV"s߈~Fug :r?CM|"*4sC6'v<>5Wm>k"lK{|3o"y8*. $t>ad ]e$rd[hds;sỊ b5$t+c[ b|-dl?V&Zգ1'SE|9TѮ U WU_tzT<` )q9Fqqd"ıGc9ȓx4J/vaAZ o(27iy5+Rfm6YTUb¬*JU񬴒k}*(+E%48Xej[5:gV7&[l+ zXkɓvtMs䎿'Lp嚉!i j"klvxb 8cBn:VJ44I]CkQĽb۾[*d"w!yJY2"z{Ql{.(zײ#XOLFpŲ'FQ'&I/ CbN\5AfXNah/3,ˤ^ -2T宺*VAT֡>#C[%{N5$jC3nʦ]>cn,JmZH"w(bl1G([L* B8Fɜ1|jkBQXĬ4ոa~7F=?5Ga78 #ع)y!kvh&}, cy1 gp~D-J%V^bG˘FΏ Z*@cv)qǖb)* U8et.e9f*{kIZAũRꦉ$S,EIޔΝ cJoP!2/"5(r ;dYVk7E3L,jaYMMj'u5SZ h6KKȍ:ai0(k{ϗN챥==Bizk>"=]7;qh3;LKs"۵uY٥ٟѡL`D$+o1v+,0BϨbiUj4G{\20hN,J}H΃bNmKI7rR{>0b63<NAzΙYJ(V#y7}0Aq%y;.אR -OBR:3Yy/>pp9VVaE)Sx2Nq ?sƑQ$ӋM9r({%,!VB1qtN$ &J֥7٫oMv+I ΌegUO0pC{w`FC40˱JѴ;i&4 3Rv/N Nqx#8?ƍsx7ϋIs\qw偍'|>ϟ!A4]g7sSX\ 34X`(t,hIJ1-B 3Mqd|$آԾc*ۺ%3+ 9vDʫR_˧]>ug#/%~1URAQ䭖_K5Oz,֡kgO=͞"9ySRrcKU:nQ1QƧed&&hIz9F͉J)bf ߯fްd[k({U͒ռMaѩ/pQ5]]ŮjհwWW$5g] 'TXʝYPLX~ & RƬZӠz{Nc7/p1_[ :iMr |wOdM(Z졲t>o662'v o<+п# )!A\*fsħׁ% Q+1؋:˗bMigG.\"p ?-gHzN^w3&ޑKph"g&:my>م/䡹7أNo6/$ՋO1yihn|*B/_"Gq;(PF詟̪NjwZB-DIW#0*WHpQp&: ,=cY7&؄J*HF>"8.jϖkg^9KP{ -Y91 ըMSYBPe)Mʰ[)z5)ṬV:\\ʏR6 \𨁎TtWr_xP5gbt̎*Uf)kJ鿤L\Ÿ=KxR.J.YW^/*ooXE*.>&ڰ{j 9աRI-*c*VTOn-aQB?UBi _Q1 4}Oc@»{2e3C]hboMyZmLcnOO"aeҴתy9U`K"%T pIS:lo!/ rV^tDZYQL7iϬvmͳQDb3-,YyS`u Yk;cAn+.;Yκ^뇯u MmS:Ea tiB!:j]x8/g_ƾfH3RX\pz2gϨlޯl^cjE 1yLo \*輞|-~^)dT5OSՈ0E˖a6<\;v`tD$?#r)dMH&IQC.C"hX@׶47.i [)t2ʈ%#cJ짩vLK=8>u9*O A~etI-vJٴ?J `&PWdR.m3{lIEXtqK鵼?.˵2%_U2ͨ kݛV$~]P/̫fܭjnPZAJvnSnVܴ N+r>y}VJ)=V]K~J E]Oo\x>́IƹWg,?NrzW- uM(!G_wi%տ+!Yg*9ZŌUTT5M+ }Yf>ULBSXE'Zps oVqy-VmI9 s%Vq0{,@),IGV/0Dr?}Nc VԿnAh+Gqc[~7=+&ہ &N7$Qu t1dAV6N9|l,ejl-Ƶ\9shb},KMK<{;AD¨Q/kir 5(^wm)^IQ,du4\)dQ= ldta!WrWFd`n_ 2/m\vB ՇQ_A)2'g$1&/]l&#].wС ^<9V(xdlᣊ rDezBp]!TyuF.lkB.]9wJZCy<K-Rh,Bi-v̙΋ZY6sҾbFtD=ikW.tr|Jّpw;0}*XPUYE*v5BG+9[ Vۥ 3 |`DT?}6؛FMȎ%\ƭ/I4~Xy\H̝ lZ>fDa>Q&vs# - ̝\ƍnn*Ԝk-ag,Kxy^d4#b@̂1aK>"DX KXj^$aY';=r'K Vq([r(Y2Α&y V)9S"_KhK-KZjёAGKFK}1Rʖ#i/[e&!x$R&a+IaI#fZ:2:IN:v/eR2?yR^c'=į*/1W)/r˙+Pr+~N`ToB׷VELRZDS;158 )g*9뇰;? j ߄QKO+1iQ͍L~ģ!qdضؖ=⸅ڛ>$2n|lLLsJH!,m \zGV1\dQ13];ӽ.7)јg4nQXe&1IX^ Y2ywI΅ X2yW'&W yb{O's|Fq<!y=y7|*XЉkvX uHB y71˘p*?{h-xgf{>"~81 :)e˩T*sx>KL9b7󵵘}H-몌cO x)BO*ĸ#RD3 {F٣av&?,G^gy=WK,m=GrI%xVZ*1K3);4Zev=+ɃY2+J,Q-̚b>4Pc4_Yl6dqtٔɹU2<,$U&ϵtgX2wI ˨GvWpv9~1r'#2)!נ$!׉:l;+W\&R{:M8Q& VQb_CPZ5ރ1ŞSrGćfn>Qho=ێh';ڮ5O3,ḃ<(rW3)0W躷#H|ff?$mDLci3F ЁvyY/h+Yz0WLsSLQ^_ͥ݋L-g'9 TpE.BBF͌jBV;%'Rý /@CG,A'yb>"]BX^Kf.Nd☐a`>5 cҀbu,XňV{'grZ_[^"m=Qs@CɑSf /.8zti5 $uex2&RF 逮fK x01ǓvF(ш4\e^:פp~TFY>aY$zRݰůhDr8; EcKdd4l(}''9@e7 )\Zzf_Lݬc1hph߫niʰc{7Y/|oQa;Rv? 8tN4S5@II59JNVsc[>_:s>%w!ND}*eGyTɡrnLah}ɚ}(/qmfune̲XWpNq@ULrV/mt)RkSOe\ @P2G|(bCx5Lp"#XXȗB75KbXjz#df?n\^@,>2b@6@=ѳ{P^޳1DIO+X s"^dq9}|Xs8ŝr)prkcMHfrO('^# Π`A38UGňj5 tt737 !nm$m~.v0 .˻2h9qr@4~J^B2b^".wuWVS'Y!sDX(h9VȄ>>zB6o$'fdobE&9ۂ4x` \)_j+0&t9JR1 Wɹԗq%ZF(^BIy_*NrcvLZj΢ fN|cO f*ErDhס[RL.C^ KQb*-ay!A7uc+[x2Qǹ9 ?u'C%kJ|;5/m?8o'v\l̷f i8}Ϭ0F^11яfx6F#i:iӧ 6u"@n dm0#)<&cALKFLϢqJ"eDLBm1d\#=L`7le˹G.q ێ BFC2}kqy1p?,+qP/m@׺tlLhؐfaFT.k4tNL^>/G`%oTRu %|ѳcZl15TV&3A% 2uL`}:*(N")G?JYZF3 JVj&w%|ʦGy|}A`M$~3p*WNW9mp{f.CTV%8LeL06Y >RcA9*pX*Fs)2/1JYw=Km5&c`Φsڴ5Ɯ]lL=۔b~kX+rnS[4?4w}//Mp(ل ߚ˦|aIa>u*x͌`\E )iChr;E1752sԶp]gjGdٳ ~)4C)hK|Պu2-g3VOjPR !9> =IO9"CǰMZWaBI%Y%ެ϶Ўs0ĸM- %*_;;p(qeXg'vƸd3GtJ/fl#k AM#am%bJ3zxB'8ZTO9r+V,I ?le!$tOT0j'ʘ,<27S^:BƼ UpϼHyP;:弯#MDABOSJDYd:c%(,kÆ6efNqdcc? X9ϏOaw_eRh*rqX2tp~8tAhH(lMg%h%ס\%d,Ϧ lsXp_Ɣ5k1m{2= WnP/e'/y,ǎSك·u.0,2gl:dz‹Nd=8l/d9k oW8 @\kF6֢'zme|z"a[)1VxKIPkp-۲fW6H Ԧ7v;T41⼨"Ȫ3rׇ~Rx@F5Lf"^ k軚 C5v.H˟+cewt,`1eyT0AzdJE84;26K՜_m:Z-F#q(Ff3.=QeNgso4ˋ=(~ǫ^]Y saz7 vq~&S8V.o_vv ͱP,N K#8u#Wǂ9(g{b9KFj)]w|;R=֗#6 D*X]Jd,Upu4_i&wtPZ ŘO I0nOE> /Ʃj?0 4:- a$?aJú0THNr B,.`K686FSfiɜ/A `Tp c$g:v! k0f:h&Nb}r&<(p^̨lT~agH&INg?ޛݙp:?Eh6%BN}`m*vVcVg' 9ن) ]ItÐx[7aߞo=Nn=?.>=^.|]ȳ>P3e/ ZL78qLzJ,dd"a"|l$uf.T~u,1ġ#4]C]^D?Gb/IGo5IJ`W(&wI=wV8R!v}g6vp'l)9lN[Ħc)";Uwd w=G61^hvYelPQ>O\Le 7> e]k17hi6_BZ6tXBN=avkNksX34# ]jǝc%Dۘt﻽C3/0dPfZҬ`8W.F"CTMcm>m AőjPbQOg$M˦Ͼ[B }˰tRkay'Q;]ƛb͜ۦ1k%pz8↯/֘'.{cɯBesE ]nNC熺23S{8ӺƓ}џUa4̷bvPɗ.CD܂^kΎP.hͦ.Hڍ:sC<,d0&צnc%12և贆sb.%ieb_7UbU()U;r<y5C)y! 2-+hrXM~%>RΙ8? &t9gQ:) d\Jde?na)! 9aer=78ŠK jlrF5Ck9c]7^lszѼq̉[*r (8 [Tm-8 ":+QJ)dF+!t ߂,Bm9-gyGwL G7: _k?{0XE1I8 &C"_D>m_ց;"Ȁ[-7%?R&U~ld D\gA.7 g9Pomh|eynm1G^cR8VR 2oٲ[eɺ֤slzƏ{hWhLO?o46YzO4zs06rh?_y13\ecSG=t?ײ[&[9X=ALk )CvN uHRG\D_85?qΚD\ v'B-t.gxRX8ӏ( =őr' _0 .f 0KshI}ax{ YogVfWtD_n*jBU݌FC.jG5lӒ]z}/%̰RZ  &&q~4bM;'';D?5FTǗWʞb5Jk'?ݰ˝;ƃtEF4Le\,8z1EnCrmlĴcpu0n&|Hro&@ LDQɂ%ݔS&`VX ̖M#4בBicI*<РCƩ9[w1Wq™eS1*Zȩ.&"` Ñ+~w>cݦQ/f-fޯM&MscSwdeާ)YƁ̵ؑ89{݋}GU9LͲkjIRcHQ8޻y͐bB)-!Iȟ R_Z-i -z tJxc/Ç4tH.ڍ$}]ߦҧ=nm8EQ-kEOoM[L:F!Ņiqz,T[Hje~xK]=uܨ'uiWB;R \|=r\I SKmXgCWsUv q~G:3'ׁݜן6q4sd<~=O ht$ey%pc<5Ջ-X"!nq=GJwl=ی.M&!ϷS#-)ɰ`e_'x0q pWAw #.ײBz>:lLA;3#ڐΟk!Z=Vj!g~g'tu_\Fbdo}l_e0B,̋#qn q= g:h +R]3C7:xݛ<̈bdΆyk*F :Ndr|ߗ *2l .z qEbAsZ)[@rn2@toAv=BtcYcE_oAtd󶾘Zj[W㖞."h5NLR86wJкīziA]b ?~+iHBz{P'hϽ"|r@əFz[Oṱ z]Hy[m9܈F>Wz0'xts8,bd:04ދBO;ƪM</ nN:;Kj')?9tG5~ᄡe 5;ײv'LNک`>2'p M9?n)l/?2N?jɿ5H\5qVs=Vծ2\se`>`FoJfTL¦ JW"/":W*_D<5*L(Iߡe} ^qIF22_.cW91*FhŸ=;[#]٥;,=ĘıcffF'y3333QsLgNwRYq)tu]Jb2iהR|v\2+qS]uo;>Je:ͳM< Ju,X*PQ-T* SShVrT+v+2@*[ {jTdR9uqQ/W۪^ݾ˻HE7D1VJ{o? ̣Yy e"Og/5]xmmKM{<8S3K\Himʈ\xl|gS8W7_ PnϏ%mJ<=BV͝5lh3l'k\'sk9]krӬxA} &S]HH3 h蓃PTF>E,P;qY:`k4pnu\(#m# + fF'1)C/L"+s%'s14ΪٗX_.,刷 կ;dws=5R+h e UPUݔWƖ|9Sƺe.!נ ] X"XSB_ 5Et^Ć%lwlE ^g))XR>+F. 92fkх]\Ӯ3d]f{*MUplLj%N W伆O5,]Q%#|⦾MTL ѩ%stIqIU/ǴTۍ(Dd^DtxHKm12MZw*E2k<ֽ#iiQ>'O2^wY;͆Ŷ mHpku bgdKx$ '?oҰ0襉=wXr6Ʉa&ލ"+oZM+IfV+ Cxre"*KzJ6 éV#cӈo M` eЄNu7ʵkIJ>94 '"Iq:RmE'cce~{n,dh"g? Ŗ}މcg:l0 We܌Qcv)}`L%o]\^,-a2|6_2*Ӽc ,|^J=y>Bʊq[%l_%f,v~E5~>n 9qj8e+y\ MQ`u7Bn9V[ v0Sb%} &xL x.\(v> ِʭi3ڞt^EtSZ<" Ij'>$3ͭPl \s7TXSHtQ;ض'do{Fc-8`@VUw|b n*NeE+s Dn~(n!UGqK\H=x}w[CF(fa2Ϗ)x29ӥҒ+iyÅS]952O鉽EZ~'Ms.eHGKdΥ3#5%w Sjv`K7k[<^'umJtwS˫# j,Vbf)%̠Cm7Zjq UcRrڗkhTWɓs%MV̴-8Ь,fzKhR+%Z-Cʘ?[Yg5[ixAwְ_ͤJN/$4r9kPkC;4Ӱh , [d+}f5wVUm[bN`} _>qTd[ kΑ=-.q ;z#JV,%BC;ҤYS6ܰ:&5~$#5!&PZ-=m<nV ;$3䉶O`(Ep /{Y1dq&4óOLưQKxs%}Tz19y?'瑹L/gD61lųIv6LI%ݴRoIˁ/eК ՝-/%-К!7^K'Vi]Nt֘j;br]UV›ef m7K=%UTj ݅jWz6[9Di9]NFZ{m0!t*2ߕȊptϺ2&RN欭$ b򨴝Dq!gm %7hKdC'0/`?.w4i--uU_mفHqI/?+>KZBis4B <C8P'6)Y,OƄv .6~6wJ&JQUȥJ.S%c+ivj9 <~> +J͔؎p VJEӏeVƝ*NIv>U0t7U,l[QX‘t /೼͋Jpl M/ܝڹW HeϜ]JNh2/wY} VK%g(m}|BeQf=$ƴcfZ0+1W7eSJ9f4.]?= dw2縌3sWԟs~({9cSǛOq"3s*kZ6Vxzaθ9,\G=\֗e<ϚR=ciHG(nʝ*WZME.k+Ki4Gy]JeNq8v{97]H[xDz3~U$7VzlO6M%97qEܖǭ705CY>2?xrކmxɖvxsk$Mdυ7/FY1-]dn5Ӱ2RG+$^ɖjs%${Jx(a #\I/5vu]Pox$cIj&YŻ3*Jk urbTKg[.Mڵ .TQo羨HL>PH=yn>,jBQfO.u'mq|vDuÛk=eGGǜ3 {^UwW.z`|-'Gs?3'z D>rs1h3yw“a&񭶫k{ڭZgk֭6aG)SHHȵMލLuɣKkaH8{s̜۳ Jv',DaJ#3H.G`7%_GB7b(&?i4u}/'i}ǽ&`1KS-& [Jbw}g„}'V(S1#G:͓TE1-Kk\F*M8h;xrjKb9+H)*֯TPF[hrIJV5.%FSFvXxC͙~\k|])S̓yi_.HYg‡qIcijLZeTP1'1GnJfbVgaI$d`2b|<^N ̾ϋI^?Բ0W9SWτ99Iq_'4hMμCHD%3mߛG fP]߉3}3r4urZg";ZEfR0-|dFp~q~Hk?!:k4&^tf*GA:hW轔8VNna,goM"8& YuOdz?Cx]J7:V"p~mwꝌtL `G<7y׃?b23Ks$4'e9?]Ԗ0.؉m9y%d.W2@m>JI; :?JQPaVB#5L%jZ** x୶7l,$Գ )fhUT-^édiJ&QRJ}It'oo߽Md_Y8h#+:˴BA">gՆX폤S]wMڃ2KF'mȹFbnw:yd6ԑW #C?dž2p7θp+㝨[e)&OceM Wv{=t$v/FWW^s7iԫ̺D=͢f uN*8zk:yqG (]ySoA~*6QAv,7L^Z L$TKIMWmv5۩PSAá W߮: .w!?܆ݴa21$MK! p6G|oؼT\Ȫ`d kE-HG!<qQ|4 .Vug6A;rmEOR: fyM;1pm'2|+I®ZFqU0}qic͉L#>"/&]&fIxLZ1#ĪwθwvW: |Xʟy~/J7G0^Iq?|7U]5L^ b{(+8.J奭'UmN5"DgQG.&dZd ,XFmOqup*&-ӕqnE93l{97όԎ`t4q sP)BYvܝd8XZlJZz/՗:؁4͌\w==gӔ V:D~MH'z3F׊[C@֮r^/w*-֟ KCHoZJz â^vot_ʗN̒ 5b1[p'č|_w\m\jϑ\IV_0㨽+bŽlpcĿw@2y+f1Xc̴YSŜ})ꟍC()k$)v~gO9S9Aϕڹ][@ySe)=B}F; Ku+qnľ`߅MMqgIwL7_ÈY>ͪ" 5LҏՕLN>* *jOVr$Df6[TapVFrJ[agL_\YMoTFhYmޘK9̳ \Ēi3(m-犁+1J6§$,D`k>uq'nSɲ43vf m;+OIVp[E9uMe{? ܑ Y sFqlxum^v-@{l!4ꥢr~S2@ODB7F`pCַw`>fM dgŽ-=Awv!U33 94iY[HHz&wdj>©@VvK+څɴ]P:Ƴ"?us7>7Sj jY^ݙ47eP'2 v^膅ڒJ+Pk4u1ߐ:s½2bwzҏn0tĘ;zE64$RȽEZ`zw&Y 9M>lrE$W}-[/1ʗx^efJ24-v߾/{}ޒYbÚx ׵~O jx0]bSy0׏xN "yu6wCoLWL {ZE_%q7=lX2ВKz~#PY&2~:URGGŲjd?4B9\;xshT0;IrJ%rvs{gOFy,˓ﹸlʦEB6S_QΜSr^Fn)zpJ2\1yi_NO299;>XE~/ܖ]j+">}wI_3\Hg~5uHƩǴ(.ѴW]w.[WV7F䭑D2^Jw:!3/Ɏ6 t$_>gvƞKt O>;VOKe2uV(=׶ajَlyuyɝUlCNv:\HS*ۧʘCS5SbU.#X4'~ܰ"ÕCXg*gEB0oi*%I$s8(ʮ*fDF[*dXGGض*™Γ,qho7>E3 I\:6)Ϥ%{pY+ʞe9,J'E{|Ңq@~~-y9K=\'~UR]=ͨSm8)?ܑC.md/\.0ʏ~s]ooϢvcCZGّ:7#f&ak&ʃ7쩶ӊnG}> ҈b*QQS rIja\k!t)ߍ&u`@Ӣ{ y "erjQEׯyJ=Qk,x]@ wrdiMf0LF[8JBnH^q "ʵ?^Y#X/K*>rGY2=qk5ꚦ,2N|rtJWZF?O/k mjRҷ_7{l K\G4ߎfI)F|t[{n˾MǍ/>JBcf8pguL,ۗGq !G2f-ݭ\(R ׺5uVDJ)iXb<k&}I?+hfCHGזkvMIfφ^=2aXFhdyE]Jve8[JR)eD A9pf" =LisӌD/}Rp 0\KwNNq}.KwҶjvC֩x4r|M͂}RVm'X#.Ͻ,6Wzܸ40ܾc5{܃VײOS|vq=)Xc8_j|tOg[ʐizth,L!IGi6FۗN3zpT:Pwz8Ŷ44:5Ҏ== j{`8xC?ujᥛƒ-Rb*cn>z/w8& 㵹M z/RHmۮ0DHz ŦͳSexa eD_+I'01b]WlbхZF(<;J˯tQ&{83›͝[g>фERER}U ϥJ>x!^JC! !On"]S~P;zsۘlP͒mX>Ri|&l|Ad 1/]?W^#ޖȩC%ȳL;jvd{rjk43tHiE6/asv؆Ѩ{"sl `Шv .RPcw1=Ki4|s/[2(}Dm0 QM4cgvu#)xDI4A@4q _Ǖ,mX+P$O^g!?,촟1vRΠ'>^!'?y•7oxN4h略aqk՞}vlks.4\l J'L4,q!h|S?ֈj Lsӂwv]Ȗ2G,s@$Xlj2V!3骽._E&K$.BcZLxt8fK\Yˁyrn`,A3-bЛ2|[( ZJ"2:WJٙ^u.u!Y)x1f~Ɏ)[GoNyxٝ=ܙڕN$?g{]גT6,/I5U+XQ^o`֧R̉S3-祲&:4}, 3$EċrGuet{?IS:y"ÿY<5q p)϶AQS^7eY3+ʊG8fYɅxf^ﳒ6i|>t41Ƽ~/Q{%5۸c]htüT^ :aǃ_%`a8j+c;Mcu$ Z;X|j$n|π{%֝5"T#=X~C´Uռi>l_nB\ġc$pLaF!NZ90A~ĕ9:I~6\:cܛg}_ogN21/H1jnbcXȒ\Xt7.Y+Eu`ۄ28q}p_Ip̕ h&;6HXۇQr‹yÚ8 6³ g`0?#9OR I7*]Fy>-W~̵c:trx#"\(ẻù~˥uz˽y^gLʪ.ctX^6T Y;^j4\*U_5Pgw4琬# I_nJ}frn+9Ջ} !}q=ϟ/al=:Ьoyq;']8tȎo,;׌]~RbDV#ٻO{p/GզLiہ6;_b~%-_[{4"s1@z6QlJ1a9~y?fCl)tdAQ᝾J.L,o|gkrϲKe[KWjDI{^o$fW02_dI5/а\x@v.alB6ypNo;A[LyT~@)ql|x\#@YGi&qΏ# z ܲdgU>~_lfԔ]/o,Q@,|wB| Ŭ ?!s~bdo,'K6z,zsw2/eYqM"e]K6R]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAklN|%+RZ2z7}&2[÷5>&ʥ_cyR5ҔbRsqKFF]d;F(Hl/|;y))ݒvK/+߹=2cG(ߔvȖ&y?#W&ԓH_?KIOK{=V͸m9Wz__&apcM#1. n n`35IK9JH7 Hwfc|V c;IUH5:>}"}nI7Ζ|\k@̉*N)dE+Ki:zPAg3imc=J(=|vjWUdc FL3?sAmKMI%O7%?)1-=$5u0e7Yu+YqŚm[kV>;dž<&/GTy nk`ubm=2!ڒ`F0\Vdq#a0& %Vjצ&IJzz|bigz@K]/gKSo))ǷҒ:~'V͔_6vv< yƛGS˫Ch)ArN3>5O>ꀣtqt)_#*qi0}uLiEd;;Qm`-c-B&Ť a+'qa23sSJ;/Gft4<풬Ȋbֵ턑YnکRrP9ҦL_eaWl(ۈka y+lp1}9ڸ+wgVraʹޯ] :'^JRhډg/ 48PʧNsm{v2LlZW1(3 ?&T~(|foݓl81-Pj[TVy+5 N۳(~& z ]o qf;4ڸA?TBgO$B!Vtn˷v1. ?,Yݥ -ot?x3aqw ӯ Mv { Wo 3 7 + n *CW,kN2iO9yV=wDB7xq j cYr,csLБ.qC36YYd,s EL =opDbS>[[k5s1ڨLsO<͍+;p|[nHiOC5O^[BNICqĭ6u) /:mso͐zR>se#U)dj:#B6X-Qq]BI7ⴃ9|6?jmΧiQH]tcW`]蘓kOvgG8pVØ9޿#} Z\ȮLq{nfg!| @E[JAk>F3|#aL@'R'}3 yHbh1ӍI,k{D0>;&qC(m vg0w\𡵮'$I7utې'e9ҡ'SnW[o6O)RSU"-{Z9Re|od ewsm9/ڍT'.Ƕϊ7fpFcy;Z";nO9O}<֍-<2> BڼأÇ;πLMekZ;q"U%H]u$p6C "kP)"9MBBsc$oRmxVn06?,oʥwAhN&xg*F2қZ:N4.cZz;{ðzP޴rLKDESz qG[ ac̒IFXwaS M l`a㿽+FqI ¦ґPh8*g;)¬ηVǾqo=BHYLBS7ܻbO$ez̖眆.5zcꩰo)K/P/_EBZ kѺnWPU6uh+h,;3n\ErW!SKUxcl>I6YԌ*bD](m[>Ѐ[uYq˚W<82}ՏLFɜ`To];ƏdQEi"*qz&{t`Ag [fc&jӵj)Uvds`!{CJY {&' ]R\Ek"%u^C;F׭Y:0_>l3)$P)=dUHkH[g )M,R0چߗi_*;=0Wm& !Lp૾9SM9q1˅>B|qڵn__v^7AOT ~,{k޶p9B#a57ie.?PK].޳uE:xPP<^ bėv~t쌎%!CJS E/O/[9Ӹz}@u\7Yy\[ј|rl{%堼lE>s]ݢ}_HՊ\Ԫ<,?ً'aCs(~BcaKUx̍ҿ (}`qaֶV80ړ9n<8Ưĕ̮eTv_"Dg/:}k\](J|fJ鵩 B1, "7XcZ{ L#JWI[$<3 wY2OZŲS0Ǽ C۳73^G'dOn$ Vn j66`s {V& \>c#)UHfRӇ8pH## y8PZ$\cr7 d ZK&Ծ؊Rvi18ۍiJ1`i(ܞodrD9Ʌ'xjvRFVD|fP-aijaU!pyjҦU%(Xs*̄upMRB159sp)=mvJJ0r!]hM+6ܩ?lV z7'fq<:CP[Ňn=rULPH6 p Rcܰ=±8&u2, MѴkVgFL`wm]1LHE:'$g<#9(wGs>V~jWnuAVyW”M0hk+1^:Ke*B4E2p_;Kҙ`-#ЪLxk vVR܄@̜r-WI)aq <(ѫ2|)̚8lp6u!c02bU㸿ʈ\¢/xڨ#4ʤ tU?KxW~Nu X]Hz56Vjb#IQnM0#*ng){eYL_TCn[|ZPAԢg{"k b8gqm>/c?# 6vڐ2bC Gb$lHrw&|ijaɨ ct'ۚŮLBxFda/^<["pͬX4ұ??$*{bfl)gݵR}RJBG]'UsZ/t>Ol#H6^lzsk?R% ܒPcGB)" Z&hb+.A(a*c|=_Xe(IMMNġ̏.wEo7<|قr (" RW@˂N'+!zY&Csz6cH׎}RL tv>JE^*"ndY,'xu'+ ~4eRDIܾ^BXn)CKQu,pgh h3b,%>t6*'xg /:/Dn^b /0avDҹў>I6Aĉ=F6䜒Ӎ9݂Cä̽ʘF%9qh nWeU+o^_-o ի[Ngi_ZCefd$* V}9z4u_:WA^l1Vՙ~ҋ9\xjƊ>U#nYF]krtdqkWO d>dq&='s( nྛ' '6Hr!_ɿ I ?4P]2sP따ƣ+{<^Bȍ'4H io]DbfM9SUg /1܇dw;.:a e8q`yq׏+lt\<5#9+ugwt/(Hv8GSbͯ:lpɴH"?=_ec# o_v3p|x} vIFU5 XAnExT`f1J=zc*#֤Մ׊֘gJQ-9~H4=}Dr/mg!uLbb=3k=ٌb{jǥYt[@GlFq# xP܃o6*a*g5!NxQ/y@T}g<2N`gĚ|St8G@{4O&rs ~>%%=}r PFB|շ"3(^yia_SHBntiJH.9~ &VwI)CL)$㎹/-A|… ̬jTQŻt ;tlHPaA' <3hqƏOCǡt`m8c\¹Vّw;RzCtm q ᇝ.Gݼ#QLǁzׂA NC?_=ӏ`j/Ϸn)4)bі5dĜ ,21COĞZXTRK_{3yWf5OEGZl/3Us.%>PxɚA lO,T3+W± tBvچ-.ΐ|S3g6*NXeÌm.$2t4ڧ8/œF=t3&I \kLYKro8{q*(3(W`s_Yl]2`?&PX^E37Su.kfyu1x?L$"^bw+1\Arltgk+ljŴϕtWHݪa= h^gLm5v9+,7fۗşn̛Aud];B2&0v_"ӿ "UYbQᘛW%3د{9t{#P66=.V0>2^%gdvatS8-' Hn6C2G !WߎIx;za֕$WE{K9|V/DA݁ΎtǪ-\m&R=^A iKa$ Ld9G۳ wrxC]K![E}[{Z; &`[?N·tmdzq(lvqd1L0e?'аJhTpSfSDߓ`ǢjX8;J9AIUrm_>I j$F=+ ߉{쟐Ϝ[|́i<633P\3o]kʈO P :5ݍ)yjΒB1U6ǎ۱җOɳf_rE3xWV)K IHs.ԑp?Np&;'8YȚ m8=KniHbLHȈ;tp"đ]ng&}t⨊Jr6bMu9kJrvGUryB;BIO*q#wڱ'qhEa&PnJ=[m3[)<]Y>)Év_r{2j')pŒCF~f0,|+ǿK.~Fɫ 'W9q;[[peDohUB4I(V#p;U'ϔ=Z62qgx? {f6aok՜ĉs bf{oZ/Rሒ| %PDatJIun5GatƝQ=xv߇^N\-*WЪ.ǃ3rAjmK)-8t?[c:NȳJ'k8ZĄסȜ(c5+։XQeC4_YtΣG`_j!iJt\զ 7A {^ ac[_X)3aH{T{Z5[3¨vzz*Yys;)TY1=6Ұ/;}p~a7+ uS=Bck[M(ދ'<қ 3Ӓ8ƆtU$ppɀlky<9^ݑ RNH根~.4ʙA޿z21 UM&4hGczhmat̜)=&8Q2d.Oag fڨlM$L ke[ 5w X0C }ٙTuWYnX Xpb sye)$ ׯs%۲%XBMsZ}7咦 /ܙ) /m^9KVcWIY%V2T灵$hdiE=^GdS cn7 SMjzLBm6|!I.g|_{rh=&xtӄ5/4~V@;n1<0I6rӮGV('KˆE@y7 5^w_ 'sDhnh.cξ|M_ۑ`Ȕc E}мomt+Gy.2WM՘V1"&rw(FhL- .0;N*1DKZDb⛈  ٝ u>fOoUb?u\ÑUZlz1^Es~ V-V$ 5EaB. ypC=>6y&nsvG4Wlcy65!Xջ{DԿ?BW֕ӧ,=zV5t3^SEpؙ)789Lv9?p֡qr&۾܈Jo)QrDUŏ$-6H/k!EbBZ4jq;M8Ŋ-|ꁓ'M^D#=K:n9U(m,?L9+G "=-C?rYPʜC,trJx$0:%$Gm(pv)7w!qy4kS/'G)q%96#a>*j;Fx18&p ?Djt&2:Z9Dt> ;n=[eQlhT凖|Im1A0r'ӥpR6l*/#G%gU2ȫG~ 6ެ|g--UKWOb$tДFF/bvy-"qlP `-eܧ|M$E|]*N:Y/5^rZ%A/9 TNK?vy@ ,U}dev 'qsKas2 $3A u`>CZpp ?$5uav*y,&vޘ9ұ=6vV-.ve:Oj]9WT*6my%Jl/HBXr ft$2 qR%:lTHF6?El?t yѸ")ETW3$!D\[>Xs +Ɣ6b՞Τ9D0WZm>BFqWa'! XɈ|K3b#B@R|W+0~jp݈%Ԭ\*JqLSF"4x<̂ /'<,C"2"KHS̔ 6`]* pE-.Rh}hݥta s`d})ZK.2Dgzw%oK;Уw,r}et Z&"ʌhU~,,H#-$U*t]k_7ع2/r^wgqHNiQ} O!u- xk]cȁ/F|jX4{tedvcmq{j=]29=e4~pa-Yr{oS2wR[VLykLj[ťV+8,Fp(Évw0<߇2B+PQCe!W{d#Z%([x / d DKLWn806-ʧ&tNd)FW9RʃMˀ4ZrPJ,LN}J޾f0j%%~c kqR;K}\nPgżXNuE[2_sϑ >LX<S-g'VEȕJkVM-Mdm_$ZgZBL`b ؚbgY1…G!Lc s@;y?k"xP:?Tpeҵx]Gne#frD4av /γ)ȹ=/Ʋ?:> "qo=mE ʸ;ٓ9Kys( y)؞DfT˻fų6O,:GT"4){[pgׇ!)|o,{gΧ#q1L>t-VS5Cl־ Qȼ"7_ztªhv%m*S]ƌE\1T72iI3ӞUI%nvr_s]+O^v0,5纇9RLj#UޥYrH ҿis+b8&7a)gL\yǺ5qho)@aX=\TRâG54xkֳ^!D44Һ9*5a,@bhLf\uH)sDoLUaiCpvGu# 73#5Xbd=<1:慢ȃdCSa?/omi6%[B4# zA~!H)^)bryg0bx,,`Z~L$d"^?#oQ@GL:_HӒ)9L!̤dG"*P<4Xoŭ)'Pgbddfe(VbӮbC CAɩ\_\cT.ϼJ%?MDzm {w/kh};q%511cw.]HP愷 |܇ gԹKypA=r沗%9^VJ%aS nxmA^Ġw5~@|;>\vbG7*xɑW q>66Um$y18j3rR%Ϝء_V=ROzcmVѷ=i_GzoUt8SB"ެ/Ʃx Bk_88>qRkF7cM?8dj7㤢(Oٺ0b}ȁ^bFBOh5>-%ֹ1yZԦr=Sr;#rR9'QS!aR5tO{mk\\k& 8w 5bTE֭"Ȥo4#܈3ak74;I%ܼ]g9Ւ"S&[bp<N4iS)~(TqpSFpc܍]њg[)}~f$$)t\ENr߆7Ɩk"YޒHr~QXNlb;;gusg{_:<30|ψ$M1w˻n C7{9݅]K>O81| OQo?ws5>+e~PW 'ԡ1Zpⷘru"(WI-ձΤsck8.!y- j.+aj> vH2ZU]LjX+cwL 't1!/N|XوFy<2NQ(,%! GYwF|]GLd\e\+<"4-mfH߭(CyQ)9iѕblG>fB)KrRƔ=|VHƚbV'Mѩ`Fr[kshBlh{Y;&AsӪxi@jI#|wD΀),VF4qj [ >?k$r~ {z. cZjjtQ>V^@ȯ!WwrSKɧ,e3N-dJ4Wz5ZJcQ5ЀFaz߳bu2=(\ PML'`7u,OF 㩺Q yQF|VYHܓ[DEnF5~>ӦйZM|6id/ݳ!IdNs<+]3}dOԣXy GUR+5:&| >}%ϪK[Y}J{%~[VM"d{K̐~B.MpJ v/^32Ev+A%b3rQB<, 8:B6ɧBl`e[Nυe<_L\g1n{1ORqr6rZfQ1ݖ[8I;q!  !H@:;퉻{Dn=ܪ[T 3߽?kM7Ev$] ά)t^{i CI0A1݈sLE|˶~a'б_&oE}ϚVal<Ds?WFDkDJ>IRrmTcTB88OJj-;0װ/W@bTqT$֣3 )٭` u(Aݨ}Y,?˃hec ^Q rs2!>ʆ0{p+gG(a4hRF">u!S](Wr揥0yDdy^#LN̦ch.X&A@n~>ksh6=#Ṫ%%5RI?IX7H'i&S94)R/a2- ^gtX __thkLss $0{FnY>= L0:obŖz:tmEW'i>HEo QNT9 KjRqnԸOIDm c@vmgBO5] v}RTo-LSx5pm(MIe?aqgi@A>䭡8bݓhJGiTމ8PWY1Uh@m`HWFS"Y)\̭yq&f-1>̨e9/qpJɚj:*NJfQ끎cuL~ ÿ"ۮ;JNr-Bq d "ѻ$n:>jdGޏΙw=9-<{XHGi#T[N݊N}D>q9˟]9a1S8Y"yu;eT6~e,9$b&s`x HAn4Z]K×Hk!?UT,19?Pz1zolro jqJN(٠-cT:ɛ#'\nQk= i뤡eh8\~,*ήs-}qAItR VӠE"y4%V+_|^9r'7U% P}m!tE -ΣݗfqF<2C|,SVĻiH&#/&4rnoMD&ұ$=ci9i<ޖMEBn[bZq z(xVb>Dr55EXIZFKDh!uZVV/&~ ؒcxJs=lH2vW;4{a~5oΩ9)t=5#ۮr\/Qh9i{|{24GH[x%kd F}į,1#vuF u/Zp¦cꆬ9jIH(UwYf.I|.Efj4ϕV% 1m86ߍWޤ@\7yhfsg-]ύ(#Xk JVУZs'It,e2w>zB |AT{a l 1-܊5Ѷ\,rlEOqz<ŵ-:dkK+yyag EZ@]eJ?5 "Ux&t)cQEJY!2ѣe<Y{d~>g&]?'18 5M.ѹX# qR/80U{r>"fJlߺM7sn" SinƗ9tÎidg*[a%DޥeJ/gi BTsoُ|:+ʛ1߮Bq@ (UAɱ!*u:,ձMa)-Oz~LNJ~r35QN$-e(#bm:vw6#f[K }D]=ТiYP&.R3σSsؕGF6'NXΰM.>=="{U齃(G#ẅJϲZZ=qGbG<>h'<0b0rf&v3qFdnfxpĄn,D##{yu&zl1pMcEo壘1+xjUc\%&Y!ЧJ6h9ۃKPt)LJFRL9%|/is H] k)l|&de!$ʘ T]"ۇ-%sqXtHO$+1rS8nlP.K'kiNE~r^_+dh#ȩ/2L?lJL^g%ٶTEv/:A| Ct5sv̐MP'>{'9'$CH/Xd^e#'C[SXswL!iaR21xGOp>BF!uοfӊ7 gN7a eM >%^‚rV*Yb9/迲2> MCY6Zq]?W&x\"WfF Qu '?#Ku|Amh WQ9#SM-|#Ș71\":d#fctIۢv2HT J+xkqTŬ %ST쯢pR&pjQ!ڢ]CRXQNr,R1 ."?ԓG]9z)fo)+ 6%Syo*>$S'zcPMf,EG{q-&!~; ݣy+Wΰv>^nGi 1^" |G ?dBaXU9lH$ƅ#QvCd Gpg5NgaMb3VS]+4"9EGl" P2d 57N 啑P%POOݭ5sꧽujfUxOCziքJ^ϟ+kB"f/G# |)GQ~"z$dVB r,wRyMK -c ]ĦY&,k:GY5iAǪMC58k-rw6^jrJ4TF/rϗ<9T2ŌQiekȿ_K9V_<i]}D9$n/=q]S%$%a29UΙ.?Pv9(2D_Sq^sŹW>s.cи6.:="R34epgDډӹ-+ޡu[9cNAUX̿N) r9p*[%qhBuI2[>Nsg.sHEy; \i},?WrҎٟ'@ a{djM`꤅ҫu]3 tPw?TNo8dcߺ1\;=`oKr -:F.F''[MeC"tSB?yH&5lYLf"hXWKK6kܵnRC,= U Ĉ>}k=!Z^Qs\)G$'OcO"2+G#0}&Ҕ;S(ٴȏ/}߇ùgN\NٹI1JQsJE*ZE-\a:9b8oQ,ZEu˨_Ƣ.)z\ wާNF'I0%}Tzo O\Nm9bi*!89r]SzN 6r5}ߨx0X΃>eMss 5jjV*̼+"//ƭ _Q %U()XB@YBmBN)3mA7wWgr*o:NK:.#hΕsaz]sH8cǯ/Vbۑ|871Gиɦ,=:;si|5u]0gq#yڝ EvxﯹomEO&wbaCBp) lj5`^x`5ډ7a61wެSeJSrGHrT\ߵH ̙c@z{ l=a^ӉZ7i)_(:ufhqYtyϵ1q1˲#)XKtЎdE=zWjOwGDŽ77 6ҷ ^\2m4!<}і}.K5 =XpT@Shlo|Vy^?bBH͐1[eda`AAҋh3Kz'sJ^&Ra uE9MƖsf >M3حM!櫜' ꫌Ierj$(率fm-6JzɸRU}JVRal&u)8S|e%{m$iQvɸT#0{CK|\Xׇ_.u$Ho:r?ו gOvcu&҉6\"~Sђ{?\;}V;5>vN0))A+W9r71פ(zԜ\ew=ļߡ0𫾑z==&2O j6ߥ R ݪ+Ѕ!8^zvۤocB{6;V-u6,dL >Ԛ!\7>{S=![c0B@sR*;vp'&*R D%ΥlRN͟a_QR&~+F׿ ybt/A J[_LM,/erjT1}DdA UU!sV|F7e4ȘB!MťZ,Nк3Uƭ@ 1h19|XC#)2ҋlEPtp?HDXUWG-§ y _ [dJ >5dmdC#dFu%ƗFGq1]őp+׼>oLT\x8˖im9Wdbx&]iDBı(wbɊK%th6[b5na׌]BuOsssf3zL`Iɗ,% i>(˲yT¬%HꞖ~$HZ*8DO<¦c;# Wk4cd #Zk VX=Ds-Lt5c ̫G#?xЄ"kPNqltuL:56YrO rG؋U+eT;8q(z4S^L>mAU4Q5Žz3unG=9:CH[ۯ7B◰jX.jk";`1қ#vڞDzo-_zPsp$|[o֢~KF7|8fԣvIS~څE=xtp%V]4nE\6C\/ޚq9sR5[>WpF)2! h4$G(!57(EoPSdS:VMj 󢪎J5-QbBɏP3_˨HL y~ BYk={d$3ٖ˭1uqSDDV=?8Xg|.fWBH)l.%gI6fIAξ<ҺRƮBJ"1t}.VQ;z|*X9AJ;)i c:IXrG~%}Z?KW]FӪ22dDyؚQsMCW<~S}a ?x(QM3fhjFMBԵ|QB1D'GɚoJ=+vN=Gz5{ X9м-3Bd)3mfkhW㗪.;"Qޓ~'-qkͪV6bP޳G*^ѕy˓g>T)- 58s;ً~aq@a[gP=o||XSŝȟ8ۍ;Rt=GubR sQE5'3p@ ؇bA>l{#}ljaOX/1]gk ^Δ%eD9_"iIv)rhGÑjRrrHPs兊j"#4$_^\ikS=kE|K,eG<чAC93IHn7i<ɿB=i _̚Gmk FKI-ua.Y *\8)J 9/E] g2C—Mɤfz*Gf#sxUu"oZBVxΑFv>"\?3h"òϡ&\pݿi9}b4#cU1ə=\5#Ey;ԚKz?'Śl10n# h/{cJsqJIpbGEI!3ZFqt| pw?`sYAxk%! g U+=(+q'vXFK7idqCon$M=W@b`m j̊,Euҷ8'f EwSr*g'sb1K,ƾϢ)f)©9\jDear4M9:'ߋù0L_})άx?s:iMܜ]t^J\Y©¥5kB[ ~xL*5+S@++Z8{QG,d6#*(WqPv a.jux'f0gx t`|OD:H]d{'8=wW|('7y-O$ފ3O}14\%s=۪إOS6dko$^"g>A׺G |ykEב]o&x>{Ou=~ 0u d~QlI׏o5AiuPIvfX>AF [ba-R sȯh9JM;J7Q0F_ B{$:ɌlDxMAjR1_ ٹd).R>p:$+-7t/ֱU,#჊Km,W WI$qd*C[ E<ʡɑ$(U@"#sR9Iۺu*7Ƨ1Mj͚q$'1u;1)t.I{3=5 [eD:'6! Tda;{Drvmjѿi)=56^5&+N$Xn; |jvBsڧ N I'^{[߷c":>Y})&VZ+DO4񴵑83y_Zؙh߲* c{d?v!ݾC*j3qaI2nC<˨=<Nq˽pj7 & Osk]'v]o8LݧXZ\JDԿ3ؗ_L=I1:K_'viɼv(?"S=qL`xFHeFRPO) Lޭ'o_ aa itѠAal@%,%'>XEI%VX=X=BY͒yPO"Uk#RVMҏ..;6izCשlXq<oƼK#~Ig67>"'c9t;H=á֙Tʠ] .3R1 q憣c+ܩuK`8PY]H>WaThtCPQ0dm'aEs&O,d9tmd]#W((gFZXUQtnTɿJGrْ)l9e0͝S䀴g] Ùiķh||xQ>Bb$PZH 2vd= - N3C ;+SHc"{#SY{ q}6GB2fԲ *}s)Г޼hE 649(VhF-iHO-5/S!4U}K / :-|#e5NcUZUdD) `W.Lr_FpMZ}1+8L[-zE/W0ˤfN2Fh~KMG(Y2*NֲBWRZD;]t ļy]Cd Fs8$1oȶFNNfnd.L9HXg|#3پ0HRHKr>M1:Y4Odtv=ux6ԙ%=mŋU36B_?> +w§8w$ z|;=T$Ih S t*R W07Ft&ZoޭJ$tW%M'yM%%l<6Y&0ǷQmM`ym>;V9h6VWGT{4T.a^(vIvPpg 4]Prat9.BܦHX,eOV Ns!+HN^6lK'{cF2!-/oֿmt6g#şC"=41aMMn:gV `yO/jKؿQ@*J%;jX[GW_ 'lDCo9J:V̒m*FbMϲ8acT5!ʓ\7sm2{VWӦ0ח~~g1kpʓQgb1#QQ.JߒcVCp9ȸC&汒 4W1!Vg>ay39VҩHC8}f &xvT8>˳DŲNs(FB'%r@"og'+%9ή̢nN EU3@$vE@PЫs~-Mz'>Hr7p=vؼ[EbRªr^M(cѡpW&B*h\+yr:殕 `<3?ʼnC\ӏCeY<]c񩗅tD.R~iOp~E+Z":D6@SZ.Sq:I8öܺ:M'"ށG[E`#=XWlG˩Izer1c9mRazZD-.*YTY$U_2f[6 IpMl 6Ä>wD="G:ٴ>B|N.^.doG)%`/Őe*sK.ƿEΖi 縛b,{MDzD3$+OS0ɓExq>qǸ `3(p$03{`@sQ;OFѣ6[0̏3l\m.'ڋ=Mx|*#\Ok/EJs@x@cI٩ ydג_k%  ^B2TLqCG[zbŎ]Ŏ{zw*kտi ) r>6kD[EbG[n9>|0+UmYq͍ӣH-drZ,R-8[O-c jhѵmbjn&rl8 Il+c|9=61>cz_  ȸžހt'bݟ&v1s|:ɹ#uƌ9[HĪ>L92ڝѿPƽR-r Jgb8-vN)=㊸ig{',c٧힙<3zbT;Z'5guF+UG=al("FY&4뙁W2#pqM1XN4ʘ?YJ"Xds]9,6}j1.9;Njkzw-󡙫zƟ޴ ;)1šXƲ:;b)]ݙf`w꛸LY͋Vv<7.8j f8¢ck,`6[Oe! w;>\_Z iN WVI .?o  M$-ɹ2i옢 C[Kw8#뷖O ux2F*DI?0=f"UӊNgp.{"uN/8vW7wB2ޗ*YNRZ&P!頂T.ݛü>3\I|7ҿMIv7EԌ]']ڈIBO8SMM A|&㈄g3:J81_iζN-{zgoC8)eT*iS9d-fTeQJ#%"wkLZC g* iڨ}fK|,+)&;XD=CPB I `06 O$D u,'T_H[F"~erE!rheQйS5*XA{$ofw|л! 11D?vI÷㍽iɩH/{z Qt(aQ厯Y|9ppV/jQ8+$r-&/m6L$d}B;oS N{n: Hܞ 7C=;܌CIx$ 2c'mDmu>ݘk)9xGO NWH;OGUPkZC~m˵&zE^вӯ3jFY㢦$x@dW-mX=ՑMƅO. - s.i,X{C-E4 Fb+L=4߰$l5gh;3Yͨquh1:O7OXhaj,cFu1-(YK:R=y*/=9NMfQ]P! Q\s[Bʁy'eB}BJ/ylg<ƷY:Әz=nSxizixʼn2#㾐ՏFv&{S{{ևUp(%ۡ !=tmHKQ jD͆O*$͔xW_SN*~VyQf|?0Ľ1_# [8^g0%dP^t_Ƽrĝ%^Ic`Ây2GB7'xޟ` oSx͋i>&vˣ؊I,&T`ajqA+Phu/ipr҆s%';8?^ z?WvTe]-M15d[T2FG' oWq\ͬgK *I!vp!%/aδ<'\}GE/1:zB:2qk I:+ۀaz3f1;kw$#=Sx,N3^A!k2ܸ#rI4 l`'/QꀂtdA;e O-Z|k~_;sz,7wjShԵ0~ L>" lkhXg*6O~`ZTsFF'=vR 977#8}=֢׍ė4l&$]¢esy]QeOFO~GYWO ? ~v קN1#s:Q}Lp2⊓/X`g>8P E~9>lji_M7UTmsqXu SŮgsYtץ-гT*8LH{@nMyp+dDwV!bD-EZʴ V;@@?%3`n .l0ic"#,D gn@&єq}9?+k~|#x=6ݺY<D$VMuapa"F3;S|AKD5Sr˸YB<)8^m@VzҦaEp{]%nc.&KISR\^< 65#Ob%5b\fyp^M;2|-9֊{lXZ^4nZ|am*ɖ#K\3[T)MLj1q(YIO5?bqςA9]{L2X4s sVº}= soϓpz'DmCc$]JF/Maρ<_Og!osq)E6ī%?G[=zC?[M|=EpoJ$Ǜp-]tY "LK n}aTcZ9ڝAR~:W*nua+QU5Qŋ suQC5UXT,1sZj>qn1KUP2n*g\%ٻUTk9AM\`9^\UA! cL2^)=<``Kz1,w}aoo{[ώ/d2J*iX>ԍq qӇ\2s7إ܊,I|dPCM'k 颷d5Gl-8?Q5JDB.~ \WSK\C1c,^KԞg| rG9ȏ+=1g6KbWxL[%+zxnaOfĎgW!;iy|qzd:S^9RC I!Mw[ ON=SNiaغ?jckzsH4n ™P"EQ5a㸳!hii 3}.W|nj pp?)}٩_R ^z)䲶~"^ϝn)^l¾qԉ[j %L0 edG#y|Rmri,x1v3JXÕzzӣ9&&=Vrl.6י4~=ѿsyK *DER*:XCn-uZȷ*8HZ g)Z2֭?+dfso>fҵ w d`H3ۡ6i\)\ȉt*%|uO lfgFvY`(Vdm%5tQMp3SJi)e(IZ<oF Ĕ3p1MlOOyoy\>. #Dʇ9"g1z콸3z 5X wQ/Bh9=(GGW8Mp:e?xl1rl[|90_9Op(9M2gd \Zor[]87dKlՓƞ* a`siWFݮdLFm(b!ĞL:'G*W>dc}_᷶ry>  < )lP> eȦ%tWzӼ&8nc8x'̨IC񯎦1:TdJ"jUCC 1J^½Il<PIޔ #EDO{6YC*&fH<^*(Vr{9S?x*c9ő03jeƤ  `.^5/*$$+q."U6zŝ<* wJN5UNCZ,=DJ ܗNN|) $ΜfV49JxO[Pp5wr} G LI+AU gId^_"ua ށq4r"z͂ Il>H[3n&-<%>Pu2TFU9>v/~&NQhk03boC00À%h,<˰3AX *d bSH D&#=$mxB™sY j4`t%m$6]B;PVNK*VVh$gQ PD?Wɒͣ~\ΧWq\ϬZ=e+X(Aq;i:~ BCTtV\NRػuD0KOOpn1*˅^HׅP {?晁Bێx77ԣaRҌHLސpNUI|L~5-siYXGGl*i4m,gF\t[Ooo+y>5˒/Ŭk€mE0.0LڎpG7Oo }F{+6k1΁kv5Ǔu`S&ǡϥ OTak'Vy〜p+2@rC΀xi0Y`[ K0OÞħ a[.[/,^D8UPcWEOGgmM} bpNVE8EN*n)wOX‹Ou w kFObqɂ(f[r-sv%Caf*mmgëѽ}%V8m[JF`wt|&j_W_(9tI䬉 )ay #]=gnMpj''޶AzF7$|瞉NC\I?ƾzQ+HYkZFд"6DJF>,_#*1Z ^_՜mloĎƐ7a I;]3` `ڪqcg+6=.83}^;:p\<Ŗk/`nE[?sƒifu HminU!˫\(oO!Of'e\([˘0LN?d(*%Ŵ2-,/b{ywBW_B>|nN1urRt;ެ i8&Qt;yZ$rnu/ &l0wKBr\6;t)Ƭa͗yj/#gL-[D־XWs=F|W^:N*&O.[+ұ9[%p"z$vr,Fa&Alq^:[$4,VE RRC1\y%#V1ѸxqJldJ\ogP'(YU Q&SyҚnidMtauh9t0fcVnR8p``FXyU='Ft.nj)1 .O)2dOod|7KiOH"HXgNnέ< 0;a4Dd~ CEkGqdGHʉc$a'spdIS r})V xdu<8ཬZJZJJ0TyzԇFh K:IuNBL΍̦\.20= 7 c,Z_>Jj򲩆دcj_6iYKQZ[ijԿgJb(v搏<'K<72{Hؚ-BJǪi㐍j <;wa9 IyP"T5@I5{*q(iI,ӑp5ݗC̍ q0Pgg2ӃVV$Au&hΊJ+>$tuXGrmtnj=8!8߬[_v¡N"dk%3N.VMDrȈ*aRʒ[q%'d(V ΥpjG"7O]m`K,&wd=cv0uT:ÃXκA> 纇~^lM.2ҹk0+۩7BbW>8.1{3N%Xe*ʤ,O)ۙ=s<Qnl]sPAE(Q f;ZYCK9 vs&Sxs='M#KF#h64ܔj/?AvA0¸K& )9沠6K]$x>gI:z{07ogJ -r؝嬵V`z)5:pan u8&f=U@JfW΅dba-pP6Kx&>^AaW|[A VpbkKjVVr[ +WSJ=׳U+D.PǝnPT`%*";Q)lRnj0V<vsՖZX2a5q39f~d"7 c:<*/ԱOR1捿 A xt CS⦏"/iV%<~_B39~T㾣39tX+wzfhr.fGs4DZc:yYQlg5v,ߍ%yNbFtx>Scm Ni?ihX3C0Y@P΍u|7,tcYʙ=kWx{u]h!43@ d\JaHf峸+Ƕ▲9v|m*zVPm: A̱߃{=+$vH`O*wOpH/hy%9[A:~V'0]'HЇǸ]1_㾊 UXPrkrfJ~W≆ՙ:JeJm ە,{z:S%2w5Z}R9r+Ļb-ci{WR;?VШ *4/*Y^[*B'T-zU={\έYu,%Nͭr,¬aM(5oJƾm$,e7p䘇 ]t"q .gR%նt=bw<hwX;QV!.pʥkƱD&' 6r l,x[Ǟ]?c.s$H0vcSK)5SB_fl;Uf*JդgX㠢Dͷ 5[^𠑂;JP,zQᥜTPMj.׈|P|nR0P+>?\wA?Yϑ)UZ PO`=TaXLJ9ݮ{k+EIϽ 6\±(Wq*6a.I2,b-DWB14%+S:2ɖf3-2 !d+Mh:}8tUiA?`vgBa~ y]X.\z/D"✘/hp[ ̲[$t{Bv^f<_`682kn#6- ~%Ĭwac+7ʗ62,A:y3p\.9z0e+F4>ŌsK4vFgv}:wg^6tDf;)1\\E&٩b&N+qR)R̤uaY5fR(u eLhVCz1uHŒ.U¦wY WSJ|ϧI>1D!ee=RRGrM[LR+'gюVOcVLԪnI*n;Oe*l>fy.4%Ԍ'>GD^;VMUb-T,{ 3su4=ǣ*$ש:uzE_/~R%b[ɂŕ 'JߨSdJΨq72U/Y uCZ~/:S/cec@1N}9r⩑mxsGڛao-R^ϓR17&RI1p2YȮ}E1BԦR=%Nr(x_ f0X$frU躜2Vr2N7^L&w!$MLGTSQ{m+٠GcuY~O b*^s꩞VX~:B>V`t[ dr4 CRPE&'p4:nS(/G0/69Lx3ƹBeq!t3Ncqz2yTו.gO.ʤqI:#Ci}X*c .DN'l0F6ޣ|7N_nD,ԏNˏ!NJͦE ;lD1ʇ|#E,y!i&/7Ce ywt/S3[ɧ HU^2_cM.QH̒ͣŋ:6 yR8u #FSuu+WobnP⌂hǓt+<3i0'yHƌD:L9mw$6SxV'&ŅJz;WT^ZjEfW{~b[ utί,WϪz֍vGOmgVqL _1#$ұOj ?MfJ x73^|wg94iLFxZ)7>p䍓˝ȻDGnMc몑<6"gknn סĶ !w?*aP£Rζek+|x~Ǔ:ʜЍ139 ZIj/OcOGѤM 9* OCE6n4}$(vo `iWrurL6~#F{`L&#иsp"'-XMAF= 3HM*g,-C(+e"dGWXVʝ>e= a|)7xe˫QT=Ǣ^ zeҿ_cSE<: 82$yR̗REeb$QYRޥY_F#2,'u9˩sDAyW~ ?3.$#W E_u*'SE/¤Q1Gǧ2TOdܑ1T}2jd4VΪJ Jj)[DF@ k9#;L"!(yѧ$"W+dVX|5˩ƽo<˩tDgyרERSḱutۚٵR/"IfOPɆA*XY\b{ qj7aN6FT-6FOrؿ|a{j.Yų\]G);34v8 g7766?4? 1٬Fw+nDIiF)S(Mc{/~(iּ>/ /= |ʁZpxjYhʈZ\*~p7: I\mG9Ҏ^SgR3A! ܙ2zrL2=:8s90lPor].eZا*{3-۠8z,4lcQmD3G?;KL<$θJ(˿h&e)`݇ה`/22ǔ!<+IVJuxJ1+dU[ŏ^J,dy^cp>u0Pf+]I6%>YJ.=d[:,6H>6CVfI~.&fŎ`9 ž󲟔O=㈉ekyҭ.%-$tk)K;av^μp5˟ky!D_|-cŭJ¿oZ2jx9_A9&qg4 xqS\X`6:9ioi?gb)\F XkBHggzGypRך}U€{{1g21 ؍MCKMwf<+C 0>%EVވ0\#k҃ Qȼ?Nd\6+)pod&I/Q߲'$݉=8P;E{d$̉l#l~j!ua<SRSbrBוLNJ9ʉA#qmفc3lX^]Ţt6r`qf3&[^g2$IGad Ay ;b"K6]"]p*fbNkKJ 4V_&fc>4N,,@Y%|/ir} Ⴔ\V2 S1Սm&oYl:IV^F/F3xJE]MG35Ďsz kWet6ב r.TNmr/``3/Κ;8v`_;z͞~4qc.!gN? ._o^emc m$.qA#̗\X%<)6tk~_bo;:aSuS'EӆA݉,öJk^i+4ad2NRy 97:N%}t⏈w3D33m9{0dp3)lja[Gfv}Ϟ#)vT tfۀB|_VNo9햖󣓒i  pmM>MH]{M<ýRWqܾ˼gل=;DdT،P>Fʉ:[˴|(@?URlRR.@YȳtXlrFGuan꥙E[<~)}ƣ H{oF۵[Ɏs$cꕘ)f-˶XfffffxLOϙ3wdW$ڭV׽p(ï扥t{PƢl+]Z1KsM|ja/;%A]T$F)%a#9pɈaVLAA4 J ) M^-qkHZRMZrgOc> ɴt*z̧G|DžFeP"ODeo>#So,N~O$(\;Բf\4o§bϊG"__pBBT0$rvW`/):ے.qN rU^ KLj?Z)X@}tȴ,kYnL 4>φ0n9['V+5t%MF,|%g5-Z>V=-')^n3W.Cm<(D]:$t{*tk]YГ''Q. snYF߆e-c݄rU[e,)NVзSr^9NVh[0*fPAJV>Y$URl(8(RsTҗ,.Kn ?s˨'T>QK%8e2d#+L%}7d/ljn )$YAAss2Q?s Yg5ԝ̌w|Jv''B8/p<9ۢ %. ESR$kG&[QfG[ ^gTOgcڍ+›Կֲ[X<^1ڲ$ E|M:|=d  㯑lH#ht$qN}zj`<$X zexYtek3Yt9Mgԟ܎7`#),/B5$с0#OqNJEKbϤVGE\[/-'46:Ta\)^3iac#A\vP ]Ya4QȖtQ2$mKwp k/4{]}%=*CĜb ᆔ+ȱR.%y d0TpX՝+f{)+WaW|-fs> Jy3O—lbP$|+) ˹XNrEhXOՅ nǝ̆ű̠ |ʘ~?y  S^b^ PoB-iO-|j`N N4I%lY1!#hḧ́^ì,M#9 EC9k#9h9Aіɋ&}?X~o?׷a7ѭ8pgn8?"(eϊ6sb%=rhʚcQv7ӎw)6[<1Bϛw% t\R^eRZtĜ|f_@EexY0 \qq(=Dxcö[NSPz2~\$9Z5.4ݪtyT9Ww . \H|RWR>\*XֈF^kJ 7-&dBkB9%sH!Mtb5_ u윯eJVx{~rRۗLet`=\tJfUt<'C$(aCrڜ-#d}|H[ƳUߣ@#=i+rY\M EZ^ؒ"L Akf&ņkزמ}rm`sag; SP;v ZOk`-j&teGjU}=R"6.Ksov'|'])w#;6-(4p%WG^ 6?7L{z9Ɏ\I)hYJa.`JT#JC2w^/v!?S1)5 C8- Yp!{qZ@-Kgns'ff^/}Bڅw{m>bEj8./1EgZVSԹ.#J~İzf-IsnTn0E+ڴoԵ=ݻrY7m؇R`Bq$T`:U:`SԴz"t\?dXVb/.fnqHt*o|ERvxxe9WѲSmC Ĝߘqs /c2>|*o>^E|}Kx\soÛ^ʺs3{U֬2&X.) |R9׺R t^-7UZbX;/JfZTT;cܓcW٣js49zIAZ&IȴR5pN릕4%1vO)E&8ڶk TTr 2&Ulj%V2c/UFt pP`cV΂ETn)=}8=^5q✊cۉh^EPj /̟' uFoh&x/i:c]u2_TRSz_օl<ɔ`c"f*鵯MsuL2/gx __pn=[~} +Yr1F3֘KՎ:y[ !\c3,[5uAggHW2%#ڻi:]ٕeogȣz>P fq))&@5dr29mW{ >TQqCIw#9+\I˕LSIx) 򻼘X&T)!WpI^G>݋垬gܴ$܊S=ĮQ;]PQ<1}7EJ+dvOfՙ !pӍ8F\P% jeni\i!;ºpy#j4L\;&yH3@:Y2K9(ul!wsSpEiUY"egɸ5 8k1K*y{'2a,}do_`R$]hQIyma.\ cZ$w?]y|XJ'Yc0+"`GNd~_x?ۧ3XƏٹ/d;Vuvk/zJ t$~8#z~Bh!=dˢ.|Sų *>P`5^·UaLI5<@aRB#F vJ2mZVQHz=k [ej#T[q BI?zHW LPe?XЅ;+ݘRlY:Q}]N|3͆L)·&OM$nj6{Ѣwy1Nq>e.)4|l'Ffַ-F5-TKɊ zO 01ՙ @qWL)I`z\&N紳zo{j~x- B[B:+.cS΀ϕL3-fT }WQl nb>-9}1"adcw'!և.,fÈ_Tz\Qͺs#Ȟkm}ɔ+f2;pU]n!ܗC0mgsBX;&mh)ZU9Q0{9b$'ZѠ%;-l.d}Fz<ܘ>τ7ɟxc~-wN*gC&gTtw79wX@Et75;iRCO%Ň |U ˹5S&y4UU\ͪ*QPt@UUp"dᝑ7|jOeZ*)s>RD:^ffZPwb;S8's3WS,`S=PrQ~xtܮk ri&e7w|D1_ixV5kPŁzv܁)y +ؾ]EJ9*S ۚwýv9j̗iN,l`p@Oł=PKMX $Pf@-aiL4i5N!ew6d15>K"I]X]l9-HY,մb>("8_b1La nAS{G3^,h۟!s9yD׷w*0T 9bGI a򽆉'# uP5oiP-Vʼv4K B$|.X~sv[Ӄ)hA$ "ߤ?I:_vÞi]Ο1,BQ\ƈ9x$?VFǶ iūq6f7&u `PqKx ,d82nVP[˞ Ѭ4p{|0[7<7DiG=r|OTӨS-LĻ\~yߎy)VصʸAtE c -[JY1.Zqb''yr7cmϑV>Nw gHCH#uXҥx*Jreչ_RihVđQ@~Rz-)G'҅MY#`9ގjI;T⚪aZBlʂCXٝbH}qocpz˸|*bO M&{@-),}Ȓ5VfU|wS7y=2k8s0jɹ:/ 蚜CDu_DAB.p~9Fɱ+gM6k]J|dS+YVɕ 9 e'¾RuF dWMţ\3'+}9aI )oC|_^t^XYt.ؒoϿnl;'?Czp!ۆy0ttQ+IX▉Y5gmOH=hs:r/n;;Yxl/dLv{Ηł7Oߋ|ǏVlU(nׅ\ʙґ4 A3 {0՛ynL;l7mrXQ]%'#qBs{FЁMDuHd2W*E]EHY%V;YMs,٧DhW?NJl8/nT5Ej£,OcBBS_\ggKq{kP9^ Hf(> (FoZ N cSc!2oQ$1I+9*_n:9d쬤uJ7g?4kTNy *Ir<2V'Vs TVqKŖ J3Ea'ea9K(Z^T|Em=G$ P6&b?oyDWxnVDHH _kxkҪ9j4[jz˫3AC:֫ߦ TTb㡾X/s_e1̍1#q1 3;% LXq0ts&`X ܩsĝ^LjYс c}7رIΉ!vHa[ɝy dONSxfIQy:>(Ν6\hIx}hÄI+h#]0I:N܌Kk^Gr=#-j*-ÖEq^=U$6 47۟͵I 4yLuOt䘿uozO,{I0,s ӖjQvxV24PE-jVRs|=d}}%HLԣ/,+erB0UƳrT/ZMR *oJTVpsec#h܅6=(Gc9SJ5k:EʼnT%Z5LjX|Qi:,ռzXk[kȻ!›j7q~ٍedzd:9⹙ qknl@?Èktyo*YžxaL}t, a oRnYa8ӧƑ;`QWv1W"59\kWK50_"~H%%w((ۘE$b^ MdmwzٌXT_b-[EB֍O}) Aw;C΋F54;t?GO^PMf fm8bBXS9@uA%^Qʪ|Xw` Gx2gcY4av纑+cOo /2kv;{SyRK 6*[JWWn`>84CTBUzՅf_ -bn ;x̅zw\i?ܖ'yWKPG''=R)8"MSK(yj"fQ9c2fQe`fS,$G?Pj1m]0]C׍ThD rƈ+QJm[Ut1_dlrTqx{M2d, ݵlG1;xj>Uǯ[ZTbo^СcV %TjkS;,֐FT-kiz^5#6[ƩyeW1Q&K2X?Uw|^jɘ~thDZHD=XBH}o6'w1%gFٕm۰R%#1Y!DBl,'9.3che#>]8!=xמ8Pexw&*bX0OnR⋈Jeo[XoJgkcd^L1_1ijmyrw7=z5 Fdz",x;Um)\ }eqi߭_$EY¼EC:1B6gƶCߝt.gчʐ)ECz:"+TsS|UH=$~:;Y2NA-I T27KK~͵o!Z4tkȚ-=K }Ҳ5Hn8qW_\˹s5-&˵7)+a'jմ"^r|ӱJWw g oYoLCOM6ˇ_XlʟczsD[fMm r/ͳN]hL\| E21E^ɿM8G/%vjJo%Y . 4Snc.2MȂ @QH:r0 "" |LW$1!= ^Ae^тϱ; j 7U Gp2 +˫  -7_E3oik$ W(SK*Xm.!I K .V 4QcF2RO6Kii$d-!Jv=";ll-˙8OY-_0ߧơLki]tQz4DVQ6Q*|iWZ>9Cd T|5Vca8/,,WK'#[EӦ#k Ui:N~hYjf+I4sϖq<}9/KCz=I&~-rኛny֙Aݸa+Fk&mq"r<92-XixAXݳ;&ʞKX1'5 q(䅕Oe}n11gJ>gĖa|!IỲNd}ƫ֬m L뺊,UG:pO/8ӝ[,8fQooPJWN2n ]h*Ǜj[L B\rRdݯdCLbDiB\!|ˆx80dzwYA)D?T~:YMj]5zZfU˫ɋZ6pǪi\`35jstcTs5Ia *ihIIw%wh{55b6;b5mniX&lqT9v^|bB9Ud|^K0WjNLI2)+_^/%&Ԝߪf~ż4h$%{ J\[dȌp7"WMZ'¬h@ZU2IFBH{OZpn1gp.n˹S9<"B`a_ntwgGq&7zsD6-` 궓1*SYG 't(fyjʝl=@"9u}5}4WQ&yG4$. KO-'Cu /]nV0CKmm5?ah|Ut]%`w847 ^$S 4cU˾.RP{{ɟ'2ʼn,PEC 5eJh_Clt7.Rߌ.y{Cq,ʙu={esPˮ(؍- $f0^/q)Q8XꢧnIj@ָ۳~9;ȜEQ( Ḥ"(GRپg"z\,z uX\HqS)&<&b+p-!\߸TU,/~!LЗV+ؐI<6syvI!j}$D/ڇ2>̲O9OUߒQW Ǹݗm :[1Sҫa5ܛSj#QsXMA5lNbzYGgĂZ دI]Tx.-gT{5\c`q.%T;Kdm̊D9d3yK&W%Źq$C3XW$cA) ZYRdVyCb%JyU,z}Y(r9҃=0WE'hɞfS;C&Ңq [Bʗs?{c2Äc8%FcRhR^ƔFpތE|} J\I 3( +d_@>3TIJa<Ȟ&8IeoSx=cH;ޔ:A8ZdnjY]>="D|3ɡÜ\udҊ@li k~Y{Ш&]ih@Nۗ3KuRys-S3DS_RCS2eh ֒v t7PsH͐*މGܤJ6U+c Z22I ᕤ$ SR ySωn4Z@w].ܠ[0Ѩ8ֽ[TS*QU| /Er&VwRMg-^RF,Ѱc -c5־mXF]>b"D/hfǩ,pq%,—:Ð=H"8h6&pD*?s2>akx1CiKJ3q&\a0tƟs 2rW5.lxc#ƪBFt WZ$Cw7{oMYh9ҩX>ݓ?gЙG$ltiZؓM'2b$g%/iKU<ޠbM-//Vs#[hOk[TCZT3,Hæjϯ"e㲹|&)g3i)@, Zvt𱾊#UU#\Ŭd-@~/q> HOLBB DΧݾB҇󩝜}5\*أqt4G{XnLh 4'rx6@pq[ɷ]L6UӜГb>dv<wbn<7[XMv7FD=Lӎ8@>L',RxLiRZ1=lX?ۍŽ$qgCBc0s.n[)9e㪵g0;Wiz{ ~gһkj΢ѓז 3 ᰸J]r`%փ'^f$:y+h:] 'On4=H'4McTcwOhY*zoj:VjXQbT=<8{|i QU{]4ߢ+ǰ4RP@KQO #AMO(qyVNM}޴k mXhoQ1/fRdΗSo܈{ uYK4hb(W4 B@pW_oZ߲v!OV[o<};Atkp3̊K9ޙޜ H0=65ƓbHl笯1=#x5 g"[E1*V`Q*Q uڕK]ƹrqya#e"< Tq-Oyoej uLJW5ly>URfFP<91K䍆\YJإxƈMl]$Yi6,tSt:M0mi9ڗA'2S¢#Y^GVN{җG-Yg9lƐ 3Idz]4mC5p ^Bt`]E8dl1ʿHU/iϩ5< ' d^Kvv䌑S)DJfsԇ3hYI7۔N9̷El ^TrX_ѷ843BB2RPo#U)Z̽Tn+0rU2-$Tcj% u7]EBo0W®~4'×"HtC J0)Ȧܫ䓒MxzhOp tìT^qx򳙔?+n$aJ,ypFH"Yzқe],pωl=oCv~_4$r L|it7>>7 Yf+\!}SAi?װ=?-%  Gqℵ+݅v sSEcoax᭲`(EԲnbW~:mK J-mƶ܍Bȁ^A4#:gsJ/1ǝX>N^{p'e [ H[A(؛2njSg^Hxkjp)U8otra{sl~Y2y+]t\% ۈ۾Wo-Tw`,68{p3G0xWE|'2F(aϩn*7?uM69 y> 29=Ԃ0<:Fe<6Ca=NE랸j=FiGLA&Ž-=UA`ԸG-+Z3Hj-%$+;X2-"p**|iE0rVq)0,ȡ|f!Ǐ0gB :=ʙoxOM EL@|UtW.cY2* ̫3. հPj%lz hѳ'܇x){͊U~\uc#%F>u)˷}'^F /234Nɩoa[+7ɎuD ._j(1^ Ю܉A}A3Ȇִۚ@~^0kѠ"ÜIL#,ȭHfc]?i.qX'bbݱwz,`Ò\REe2#gq@ v7 (OĬ&|(!zN6Sϝpc.SxQ\"X5/;p s X^⻅d(iYn}1! بpْ]Fn])0}f[/'1=LKlc#]i>ΗOY//yOLCpadO>e9MOK2P~? G\TyuQcowgUE.4A4ry )E{C%liI!ͪ'Ʊ],G[DhO¹aE+FTbyB0ni:8hOh]*:(G;'ѫ>pN [W|z8sy2^{sS4iitJP]r!؄/ZM3߂O9k39fy0/xEcgDxˢ4Ҕw/lײu mOz蕚Te|-G_Sp~ J {{mc2"]>t-݀{\xz^leHgskR%h7ƃ7쩷ÊUWG}>-3+rTsab ~Ts=V;K"Xz-Ø;It#e}mr9?ׯy\[j?b*jVu w1;{w: _z3n"y/hYgׇ: \ᕧ]>7dyHfz2j#,lbO{Bl̈́,2">+s+GK+ ~mUOy\<`[txeǶ W6#OZֺ2#-12巶5 -u /FW36u㋩;M\Xjzo[wVqt-8޴e_:$ e5nµY(n%.3^MѵjZMaw5"&mI?'{҇~ k,s2dx{CaIfX*WfP7KU2 O,?;'N3 pf" =LzӌI7^R?@`ՏVp}*Kn+qCHmPӐ D#m~{P|5~'ͽ,+?nX>D._ R,/=ғ NzQ{bÏ14,bӭuFL)_tB;xS3ؗN8Gh6#rb:(clYGcw@.BU>Քs8x?Mᥚƃ-TŪ٪L%p$#σyc}ǛrO_2ӃH0GZNbX])bS [B˩ϩJ +1ZՋJU8*v\* XgMX5Q9˯pQƻ8N3&|j HPvT:itٙ/n˟Vdre;KCFIMzw%oCbRylkpmg SwT:g/ϕژ+EVkGl pPy݌aYʉ|^Fc6aғnޏåа'pĘfxXpC9SL,NG>#bTUQ M+!w.Q*: wZ|__?o/].DWXA6#StF v30k)^9i|IMO ^J % k% eR: :Ei?1 iJK'& 4ȶ;{Ն7|I^GW޼um8Ѳ?}/ s[sxgGw1gBcNէC :c1MiUEA ~0g;D-ZRo)CnZ.ՎKRș?ݹ?7?O#Bt=kV岤o Cby)z^MKEaIf&ZbHOm3NwGBt Kձx=M ?l^ *{Bv^\c`.m e`& vF b pdzd%b^p{M_wvҧ63Uӝc ӆR6#~S:{NɚLŃiͽxd햱-yVmjs 9-3|8tّCߝ3wT68+{<t†]yNL\=/*^3Пs'G3)Cnʞ}l92ơ) 7X@0>.f\oƜ6(n4''i,6ci3!QnL |u(Ewb 9˧b ?E`?XkNc=Å=YEmS+o-_tA^~ta+㌎*>N(5_3BF~_T9qJ~E\ٶ)m}˚Ɨ䈤޼ó$PFL ]͓ah}`xO dM\X=φ[j< yGM~ݔlS3. (+6a +pXRKP-ͼ"R[YӭV[C$G#^i]ݱm4m{&1oV2L⸿0==9܁I͜0(p¯RX2E5a$NFfB$({kjj?2N^hr[yfB#吘|:x)>U5E_R͕b,ib5r CyފHWtƤME])Cd&NF%)kD\0c) Ȭ;kHG소i}+iD̟u~ J{}܍*dp!yeJhgn¡wV&1$2z;-re<$^g'UF~A+Gu?pWIө8.sdrAD3{Hb{8hi \wʭwf:8yt]Γt?fcQ:`v̕MeZ 眕9, ̀ y)N34ұ/JJq#B&[Ց(+sJ$ގTRϔ/OUaM?3Q<}@Tg4Zݏ2.s]"=mg .?Kިfp~w̔ >N*m2^8m.M?Q'QqF>hj-uA9܎sw(PƝX Tݛsl0]cz| eMFb7ؘ Ȝo!ah8ʹ Ll@#au4oFQi />? k ,mkg=ჹwHg&p /̀,AT%Q_tW&r\;֯Au-;?…{fekqz=Oi*_7X%j (e1W_jbxXL4C֎[ϛ$pQ>מPi,a!E/V-|'|)]-ta}Rrn;} !}j^ρ/RH/ @?^EwTQ]Gn^=/(e{Š;vwj'?.N8"Ke#NoɡķwX [TWj4lJGrvŬA;u-xGaFWu颔7@Vn6ZQph4ܠ4q\BbwByp`~'}q׷$Rc;$r^79msSyrXu^G$聴/ɲ6WeEau {nO ֏TaH1R                                                                                                                           snŌ %̇ Ci]n][hAqLJúm[>J(%DZ:"0ը}ys feǵn9_ЭZȽL=)eO7e?䩯[3= $=}wY}+▋53t뢅J>F:!Z V^u/ jOt`; /ɳ2zc>T =h͎h u 5:Qn9YmUM :|e:6ד{3Swk]8ޒgޗ#o\Wߒ_w]&֜2cL>1fw7[C5vq ?r7>ܙ?Zaxy0kVfp)s:z؍5:u3+؟eH!֖o[3Mdgk+tDI\gc6R/aS+/6k4S!R.n哼G\;E#?Pj`TocSJDi [P+舻!0ą}ӝLI% eL0)L=;}=mw҃PNNG0;2ƨV`4-qٌ Z=/r@ǜ GJ׉#ۙ]a߷A;݃01HMceʼN,{kIGYn_#Pv 5[smIZTxeԋl2A i=Xś ~Ͱq莰l$.7F5&x'BϏ6=#x̆nwgM3{nݏu]G)hƑ[兛e}Sb=RjŢsmٲN]M:=t`pw>zwl[+S~*>ۓ7!f>wJ0+"~k~u*4;jqrVkƃO])\MTyv[RűUi0Ex ?lό.Ats#tUO}vKF#~Đ̚Wk~8alɖ {@4Uq}4&-h0Cd6䮰@͆)M o̵ٴœMi EN֬ 6]Vܲ9/ξ{ k2H *&f2e~_K'*I U}b8){qK4| XՓe>]劧R=+6w%t[+/G;ȪtATp,Q,uV-nU\@D^DR; J憢~#0?KgJ+UP3ӛ5ٓ!j-,ǚQsUMv2V9P1_1l .dxo8P,~\BaK's* }hfV&9otxukEN( T&&`w~ ;b7\]jOICɞðM,&a-.#8U[g|k6ϝ3Z1ǾcM cz_͙f;d 'w-X./\jѮWž~hmBˇI=b.&|<2qW:i9|;OXFf]0 ,]iٗ32`N(H ]lԄ2[iH֎QaW]_pŎAY>$?XV5_k m܅=i@ˮ8Yr+b;;ѳ49,Vd&4q=W&_cM q\[|u Ծrr٤<#0|uZy` "؁Ǔs7vUyMӯh,o(. Q* ~`4n<& 3|'z3#"Ł[<0qg5s2 Q3/Ц|Uk:!n;#7;c1^J%/jtE! k Vr9:#ݜ%&KS1+ςԋgP&S/bp|<՗{ƣ_ ޻lnkKpc 6pklF"i8Q/,3)Gs$ۦIYS(}xٜOU֊3bݩ;}x^UC_rv L ۂt`kiתּP )jqr_;K2f]@U >4ȇlrC%εzKvf2݋1ŀ]nBmGT0O[3#D}ˣX]CN9 vS樜cJ9i { ĊvW !8c fH+13rv(kb=fH«_x镳x\̒|wB_4i#lGB ϋ|hԳ!~HB噎&EJSYӞKn<^ΔNļ$@[*@hR LfH]ZݑUjDr {28LLöEϳؽ0ywu֨1]b>STef4伴dR[ŠlX=]CW|[R Yicسm'uG*{<0 (/c@T&~~_UKN^e0.X3A4GD'<6vf2?fGF,bvÎX#i59$gֻ1Kȵ+&`qj!'9hJN_5ީ;τ%)ο@4 2t;;YJ#KTr.#匱baHRnб΁-x֠#p7}h)wG3LyF?@:LR /58eƄƞg{Nv!;ϗۆHoS'J7k r08X6=!σ{7ɚ*[jh)ed},…ꛁd%ų@/; МʜBמB,{GGgl˖ \2%p"Z*"rKU_NŸpuQ PBmE KpUA rF7) M^YefQxR͋. SѴHfI n#r39ՂCwŝA¡NLJVuW#eղQm7׾uboi'GBe7 d(*5V9f#6Er8RFȹ2SBW^#dޕ8xm! {'=\v[K9$+~š+PI$7 `J q}~47o9Od7˧rs/}N0/XPܧI`v .:shў,J)|Pu.wۍQyyԂF(kp"7|]Vĺb*$cX63Z$D iOBtH_~\5^%[+_()mտyG ۡ ?N|;Àyjk}|3t**_d|1 #֤ń*W9J}l_`cR<|@{sѽYDYI\͝fX荺UgrO>ܳx&c+/"gmx};! -m"ٙ/{5ya.s#"0RYX$Z$=\YozdLdGǃ<9+ z7XR2OGA>֥/MWKUqk~oRIF4aZd.dPwI)CL)*$M?B<. *0SE%zҲY(+љ`Kp[&qrI(3Mp:i Gp;8RDž \1{nùzٌwDoh@H:'eXp0582 /T*N|If~F09.#)hǟ# 7ؐm6欯Č vb!+5׾]|է -Y۟uٙLPs)%/> 5ݓ0(Y{vEbBi[6ѥ'=o:Q7ܜDikZ-[fֺL$-KtRo'%9?4InL"դf%yMKi4WgZ`x6cX&&Iy9P//Fn5%q#YnΑlsbFbkƟ](XĆSW,׃Μ\9+i)e`%_\~9ki9gV=i?zz>z\z0q7.4br&MhE&/bƒro]j.Dz\N27dN5CpfR$sKKV30SaΉ2Vik39ejꩲ1gUu r!I(ģ5.j8p.mL-%o)Mk:1WnV:tlp/J˯t|cڅr`FOCV(^Q*Y^]Fbz&9ˉ 1%OY:Æȳ`HrLU)oͱS? Z9"<+Wԫ.[)^|u\3.1xoKXd#k5 J.y`4˩ ȰMcSMAlseGp7bMK' t9kNJv3۰syLFANN2xS֞g,ݞUw1MO+7q$es yf=owVfH՟  8ϒCFuȤwH SWN` &W)5r*{ n^(Z8w Du]wwuvۻ9;wt$w󬕖 A:)g 6.ak'{ٰ`Ladɫ sjƚyg#E1Lssfpw7N*R_𧢦+VȤI,dZ'=%p{ $rQȸ]ΎX9CRP|R*69 ͵JRK) % ~Ãv`:s7ΣN@{‚r)e*d"6u&shkeR/:-y) D]00pPXUNZ1q#]t:˞QTx&q=+Y739 KiY~ ;܅h< :A{1LWANRzM&:60k<@j ~6An2)<觘UI؎cT[#9_hoˌ8rb7&wզv81#~r%''N ׯpg9%Mj|('0a,O-MO(QX+\ve6 ֊6νh'C+B&:RڞQ 0`8$G6l(3BG3:}"B=;3zyO{6Nꃕx$ mHaY̌a>&<\=PjiI~eCVI"4ˠT|JL)'ƠMLVyP@*qVËijTq󋚣(<}ʅN'-voX0x>:{b-) ܎x8'v7i3{F// -“3g,JtucaFT tVg3J>E~>-a B&q66܈"89 M" <|AN[Z͵RJbq"@쒍bSrvZrv=[\y~RO"_/%MU(GzDe&^HBȚ̑˘{Dbˢ]Qq +vBz^=zɔsYqs C;7އ(Vl43D=kljlۏ1(_%g oNp,$s*p`^l.-k:ܷ 'ws.? [6qg/Y,(|BūLZx}g ڗӗpiNPƜ ;ͭ9QI_9ҍ%Mϖ} qP#Iǃ<= YB\ֺӠ+N!.trV3!&n,L)\"2r T?AEm2M].n̸9-Le iJƾLnx~-`4 1;"X@]{>̑*wWrġA?ή v%FO^@Nþ6x߰joW[Kuaؙ:ɖzGT_f]SQѼmM؍g_{םoپt:NCY"~rUqEIQ*`,ґVϔzjFFRIBklMaIs'Nw{qH|z4O&kOAd}h6ƫjyȝ[9ެ~N55|:4Z0"9B3^ZС;'14xF$] ܙ^Jќi JD+šO)ixVFd^>0{\ӣD?ͥQG*]ca[TL} >F}KvnD1+!7)疱NZSvT)y nA<}y0+i]QΌ%\Φ*v1r-i31UH=6d`@NڇqZW)\eǤgV\Wnglc8<[Ï/nLp׆!Ըa< IL]`GD':3m2GGgZ;KݞYɼ3nMcSk9-D.T}0lXbF^8_IyމbRų8c~~&ؘ}T^JS:"xq1mix<3c6b \03WF:EDYgkp!$wY'f!c {C~˧| -cƤ|.$ryg8BxO\.WࣆӔdF@P${=֌ dF^b\ZI[%Q: 9^%(eP%wƻ-<:n ##.GZ\*\ă)K#K\_ʯbbXLcʦDbh̒:{t-/Aop nO&35'>>=9=NDtc@.MadbDa/q=䲿 Ȧ/*-11\ f7۹?x#p/YCw~\uñ'!-xM¦pOZq;'nQwFk|姽}t4c+-ksҦ /uiM񵞞YU?[F^/ţXίr:-CQGJES/cO.,sAkִ#cs(&TGqofH}ᢹ-,}9O$ -ROL(3I:oU0K!\>T3oF>r cd(gs7ޕa]јΧ} ,~hy)~=cGT YEa(ḑG Tɧ#l{ȽU²9'7IVN|nJ@V| 󷇆 Au!{$,橘EiWM̩<%GJ,머pٯLL2ot[xWSv;a|[Lċ ٽ: ,dbI9zv/ a,+9VR䗁#J91.0zœM}XB6ImOl&M_!/_b{k}ctĄ& gB?vr59?{̹_O5'j@LJ,8tJO:n40g3|D\GvhDgJկ Qf(w*xyiّcrNs`W_9FrF Qd`$G[n'e"IURGtS|mOVj*reV Xz>̱h>M`|Ap5_RW7=KOYL*~4|Hρ,ZkJ~t,. q7n02;,rVX1u˨ӫ!mPl˛n ʡ_ 9) Wp6Cխ\]7+ tNf,s+8̕ӳm*a} 3XyOG:d!oik%Oc]ci!Q Lߜ94_Vo-1)s; ;-UNx7N`I7Ga=c{"i~*k=jKeW%QٍT%l$qy D:-ωLWib$&F|uJ8Rgr)gMRrZҿb(UFFv\1Ъ[-x3PG[Nn\B\~-,愣g\_!EA嬵W2&~ +ǠMG\G&;cݽ~wa8)OuF2kQ)y؇z1n;| .%d3cXʫڡ\gTD.=ΈߴwK-gbYʸ+r+85.aK6B.3)k򹖜r˰pQt_d)尲$q2lfUO sA7 7H%=;g *^8,30+t\ݧ,ld FN*b# >=5F'L:.u2:j ?]t(5~Y0!#{Pu`~27Ź:ˣ<ͣ=<e~lDpC՞0=ܟs5atHK\ٓ)\ww˩{mԽټqH|p YCq?Ao}&YGU䁧|lZI a)|D{kN"G;̥n%q/ QW4rE˶:󸵎4Q[F5!Z 6z{YuY|-̟6)y0 '#'[6RьUK*>kثֳ^VMuf7rz"RL4VrU3 ݦcB{RxӨ-sVt^1 WxL~>Mc*q]_=W FMCO  [^Zk{-%TTMTaC/ c^=A[՜,\F,MדUIJtU&~R*2א󰪌_SluУb=SW5%MϏNb"KW }y tp,c)R %$/DDc]!{s'S¿ěO>^f/#Nx?F?;`:QPW c^qq3? SrSIxۨ(}oks[M kj㱠ǧ@KU47J c`$ owc=3 t(5nfI=:itZK^-ZFKe-|1麆+\R;9-'|sYV3=/!"0Ȁ6s\S,ܦlCTĜ3Զ M"McřB,E;EAQ% 1ha&IDDF!X6D`;̅#]9ԗ5"ϡi+)'Xtu˗RBK.00%d,&Ф6U'=2*F۴BfFGB|T|ѓa49G\a$mRԘ'JާUt["??=oZ**I5b*NWrpm$0 #niJzr{o)l(SZT}c(5.Fw%!Jf[5-/j86[*6V˨{-k[yQrXt}}RDԶiQSx#OHQpghJeBSLHƱQw*94 Ɖ20ZNQi:ٴIOה4s`|IV|tƻO1[ĨV9JHd{g/•< PqA5tn% tt4`D١ F&8f ĵS5V-~*E*$^Q.ГYG[/k1㎅ &>U˫y"D* z/]K9w3T5UROR4?2<'챙ĂYlO/;NYRIt>qnrDtt:͟O5Qx4lˁH6=E֌]Mj5𦩖fis#u\p6px|cU=H ($׈_ɲ 6hJ`;m ɿlߕ\gAG6kI砥?"#\r65:(T8ζë'ˏnD&XNv-CVa y*w<>v~!&55:kӗ*ӱ.hw1#Yy$7FzLfT$5SQN+TdrQpq*S^D4&Sy-RnNaZq6 U{x ~+49`&+0+Y]2#?Ui:Wӯ-ytlg5p0,v 5ءe -kxuVC f؟eo%_v}rU做a(h+\!/I,)N$O#K>2d~N3†q]r:o3_|–&__+ɢ T[t?Sp[݌5G:Cu\8Z;.i|QYލi5u'>!{9mn!s$":sʇ泒7mYU2%FV7#_gpe% E$.zR20>E.nLf͏d^fc/b2ߥD#&;bnSĺE$~{ܥB<Sk % Уq1[p.i}{.O6ٌrc,LNíM&fK6ϗe"%c4!G謲X>U)o[.ډs{lb?*$>^~-L\Cq=-uZ!q=EOFI 1FdkzڌsV) ;3;XX-4\a%KTdzWrDIg(%zB5Zi)Wr}w-άb.[B"ur`+=ljuAYxP%hLᗩ5yuq7imBHݑ̴2bϣ0~L`7O¤ʢfp^6g*x:uwGTb/6]̆+"Gl]ɿ+9|ȿ 3 SzBuXkDG6:>wGx֨AW84ǀEacVsͿ˕xwUԞn@{ s.̀r4DG0 c+xQDћYn+W nrY ѣ<Y۴p>fG}>18 =U.^̠Ũ$" jOWMr8^;SM2q5;vf,NʢTZOSQK_el\f{*V)|NRB~VfӷM P,PD7j [yyEؚ"k*LSkX(2L ?lRI9xn/cW\MΈBS";cd'=g fUJ>\.dhr])&groqm-Ŭܙ@7]؋W [7*8PINƁ<>H21򯥔QUeic^ =`sCU v?PUn,6|% ۑSO|]/w1/fp VM KJ.9b](NT{R?ɝ=y1?%No!\Z^~SsAF;W-4aSͷ,kസGTa\ɻ[bWbJuz8V:W*#:C`@%GWrHE=WoڣEF6`׎ZAi:^ {+rFR%ߎ]}&3Zr,2-?n+X3{ _m)IKZĶ\LֽK÷ag$ioD^[2 ca\};L&DzGet`Y ~^e_[iΚq:xz ҏE4RIYTG`jV35=Wq\\LH7jfDi2O)':77drKsK3~3{\6Hi7=9jŘ­֍2bjK47%[DLZ3C~;B]Yi\kۼrv_,jMkȢ"gpZ3K : Ƴ^-u9u*v_w7=EN?ԲJA-E17(y:,lQF|U h=XsG{@yFѵë3|&Vf1NϪ'uC_r.ZҰWU3ؿejoeVsqzv!ѿj>OvIL MOO4X7:&_7k+'zu+-_Kγ09vilPF%Wpr:SƊ I)z%yΧ 5~xd]G]M1J0rYB\X1Gpta=,h>>iu {dqm~Ih. Hi (JFz_BU1U/Qb`pә쯮f=iyUATW!8|{8Z4 L튒&rDH.5(9FweS{~ +9G2(pSNh ⯨93Zwq3IrJ`c? A"t0qmۈРµnt1/gpmtnլRIFNz\Dޒ0cBXf|Y?:~kJr+އ2 {XfRq3^ؐ\a0a/D17ԟi85C]/OT.|ԛB^guMYPovYrT uǧuau0OLa_ am*Sd짧*dJ:2eSOncdr#=tQh-]ԭ2pFDK:7p $hƾnBQc {1Hh͎ٶ%okRdv>]_>Mٻ9EdVSbyRM:}DRaz%o8nMԫ*Z.)I2JZIeZSB2zT?YˆRa 2TIMyUb+i-E{IAVJdgbI0R %שFÿD!,oY%V8D!ב-~2BmBm)ӢmI77gq`*yqV;]Lh9?#>yޤ秉bp)N - hm~_^&pn>-.GѢ -ɔǫݹla YLÓx{ v^Od.xϛDM3|?jL'EZ_:RSX2FPNcGPkJ{ΙXXܻV_uH̝[Ut/#ů m=#C&z(Ǟ:7/᪑ZGtyv2+8`dp`/L1 wEA.^m(h:mngm=_/6[),.mMx3}0T#U#`#]Q-WѢv:~ Y#gkG`e*) PmEt*ӈR|Eޗ_Z 1~ $gr4rZ9=N*~Uu3UXVM%櫒G R᳂JT[K:,J+XRMUzoRӰӥ)δv2,{.q25Q:S8jFv?V^6)XQ㎊5F6qҥKg:oiYL_H$"yhЅVNvh(0ւ;c߄2.V K2Z|^>2~6e͍ 8xe#mŎ8+G;lҔ4o;7N OeU8e1A6MˌbЬ"RUfj8LGW9+ыyCegJ z&{LdZnWc$t=3JSŝ| ӷ }D{S9ܫ'_&e+)tQp0"aD !*e0p0aiׅ#CK-xʟ ;~G$cz֮OdE>VBzXgaSr)hHFMG}ex~)E?\ʎMR^?.49uPd2חw+d6^^=5 k"rt FU\{"cm+i~]Ak9+VFLpc\䘺*1Eb <y%H"jC0~V' }ݘ[gpa~vtB >cL:+]x f֩Wur̟kH'{E \1瓛#JjWl>rW8MR|Qul+:s`@Bk'U0mҼЖeB[1cgSKWQI@wnqB2?a+Ĭ0x@-ksOʯXY̗XʃAJ=0zC*Qo*H=z+F*V(r\9P9p9SWR)eh9NsRTLqWҰc"g`U帋s WM5?W%Tl LڕsP ˱TN|_0spәfJ!+‰u`%ѽY@O$yC Sb~ioLtH%x]O[02朁ud?T3Ӯ5Xջ'1!ҕEӒWa405tl;lŒ0:r92w^[Gk@@ @/@wwwL₻wg4xpwB~WuN:U}3Tҙ~%1M}ՆƷӄœ (ok f뢥n+(iry8$=YhÉ\eE?;-3q99Q֋39٭E/o/<rRJr&qMԁCd;32kzJhbtv8?BPyAkhXlrW3{%sރB[,6CkT7oќY΢jqJ^uDHwei+ކ-̚z}xX=ōt8Ԙ<KCF X +@lft̃q <8ΖaPRvXp]$Zܧ@,*tQ[Gn?!]-;_ Q忄&1, ٱi̒ݎF 8{:20Q??.J%@1+$ȱKyQ/嘛WIZ2ZoN2nO-grVY h*!Oq nYQcx.jřvM;{ ?nz:,^FXҢD0!bɚ|iљ<^8}ŝ T4ٗPad|^dcwr }sy0;KY;=%YXQdQ瑅$ үFh P^>$Ҹ2uy̌4rT A2$vP%Nſ[-_,/71xU|ٽ nNQ2 3m ݓ»CDjFFc%dkTr4nV匝QgN9{2qUERL}E!kjg)SoƆUc1[ΎMdL,,U tl̈́M?Qwl*ɛXFbnN u מ 6&P?+  Zw֬l.bdIv{(qð|c2m#E!4,rd۳v9r24-cURf(kV)ޢן3Ua@6gLS𢵒b?%E+: )TNl<%]d[ϕR4Sd<$fvEf;f}٬Y)eQE6vbE*=詊ʴx'm1[/لʡá<9:9f38G ijABldl6ms&E vd0pBg56\<I²T@E|p<,4HMAT)?:)Q̹$#&fwrX2(U blEwMwd_?]yʞO'#AXrJnV&+y9ZŅ'崾XN߅~(dX8sP\ զ<2唽{ 5h=d=jՋgҵNYh[0rPpD()OTsLJB!kO:ǵ(k:WO1ln2!^m G[s.X4Vty?Kғ-S{7vW*&2c ]ԧ>Gy.{&stɌ{M2̌;Yޘ,P1)hZNկ ::d1/S,"f/0sdž}i"z6/"qVEHgWq[~gP&)в؇Ξkr{;y0̝Er^k$pԲ-WRN<+򺂗b7$c9>GY٭ː{ƌaYmFȃiY319-)~DA:V*W5'+Z&Srψ,sYɊW?myH9k* #]2j^+(aB q[Q@ rox'%VR+8z]ΑR+fru1#d$X˹BFm@Md0+R7X{" 5ӡfm$f\_ْqɗA8!ƾsK:YĵB%XT Hfd&gep4Iٜq𢃄3f-Dք&v_*u֙f:Sy:i[t>8drS2zlQ̔i%mJ>iԝm㈀ mԅ7i5ljVݩlM'O%w0jaָl )U[5i#z`bvP𭽂v{ܹ JBgQwQJEƠroRS2~mP`#ےblfIQ])YQ[ʽ`[DVh䧑"?ם#-.AJV#98J;Dy|>kC]B\mftr|)7ߔ7(p<-#oc Ь/֗bɍ^vb;mS8o9NU hKyo$M }ĐE?i4!I)p RH+9G+ygwL`~XNΈԂ8.o,S"BOMɷ\r)-'3taܝU7Gb,?FmX8O^^H#DZ滵#̨bc5[ +%~rg-3q̵1e@ޙ .oy1f/gx. ̑$[9[rz)t}[1-jB<5x,vp*&x3tl([{ {3̢AkC>#0kY*̵}眠v.2rs8Lik"HWǣqPA=+ ?"6T+[EJ/+9JΘR:(afYk eaz?/Mqd(͞8df#&D9gJ/7*.ұq/ g|iHTHT"-ך"6WdBcGdz>8!2C ,<%\C 7aן32_1w{Goԣi jѥ>kꃼ0e@:~Y@nOfQJ|i+Cɭd=*Nħcx"OJos׉"#wxwJ%/^r0sşvk9NYVrn\%̫Y)E" LS}SNć&4+FSET88OQQ BY#`Fzнw -|XOa`"8;2A v HbXMynGh']$OdZD&:}I \ʠgf>QI9ّⲣh̳)&x4 `ӺDaЋeQQX+> lA|]>vP0VGt~Dz1'o+\\UԢUܻYͱfƤbWwПA]L2\KɎXzm.5a ]ZΦߕiDNfL*kqnY%MRt 9$nl,$6br[3hJu~GVp2PmcijOQ65%C% ~cݔ\Vg\p.))n_u<;m{eK&dTXqҕǟ=PΕx79qʙ[гl9EeZ r71P,B&qSHc)uVIܰ*~d!1é ݒd:ƒ,JqN̲colɤ2{~WюVqv ZW:wbֵg۾,!e6-}/ܚ 5ᳪPfV%s|ֺyطLy-Jy~17-ƙԯ0;&c9tJRΌɫsPf bm:X7ԋPv/aL |^-Kx\̶"/!j.kuŠ\y9k0n7aX.kh>gͺo$ƫs:Ý{hOd$ƝI0gc6#չ;Z44`ԙ1^Gj+2)VgJHڡ`YiN)d)gvW<1V?ZI22~\!K1;}@OPFyr94m[&\l̓Nu%>],*C=|͑2g˗Y8`j> -*ab?ŢԉP`uPT{GGoMEOǚ@#+ @\0ߌyZWK&zN@F}? "h9nY+fHG3bH$ BAlNtg =o0n|8UcSQy.rtNE(V7%2¾>M!W>}0QVaOhOK!NWQ}ȅB.Sbҳf*) $H5nא 5^fVWKZ>au[jK$;%IpQ YIĞ"9 hLQ,0CoRfo-gR2n)-2h>qaw@j: )ᣴx0Yc#CaCE]:~m U`VʹF|(aie483%%Kjd蕖(,&SBPqqo];Al @Ͱ+O[kz]ؼ!|\&{UOgIR /%TwW^FbL T2it3*U lʑ3C]BĽhŧ\r y6ޅ<=7QM/z]Mo31~U0vu$E~aK/X:T8be/9kŦuޘa ^JZ,>Ģ3 U7 5 ozxI>&W5w3v-TshN}VZUц|Jߏud3|}N; Rosnuͮ/h?U.c&f欺DY$ehsK[^oZηf9zRYJ1;ճ\vpBm*&S`MjSqRwRZ9߬a-HkϾatUM`o dqh A]ۂn|w>ـܚ̃qĜm$́brKqZʨ|)i\L᧧+z) .RugpvrrNxo.O&ӹ :MAMA']:^s/2nz .SJ`L. CRPKm2n-WEN3n=ߑŞ^*]c ~,&+jүTql%+[J1'6 UBNPР#jyWtE f }Φ)cMmï4';%~&ANU9`r]ʉ? 7&Ҙgrz,C,WΡٿ z5~Bg?,Cm[ JoFiYEP ElXgG1L]ӝ}4cHv4/0EJ_ jU򼽜Rn/fjRJZLcE"wWX&Wgi&oò$l9ŭU9{92ٻb=HqPSX>n.#q/y|%b(DݺRw1ѬȻ,y0MdUJ\2t)cI{U땸=V0f?}xNn\) 2q#7Aq,=QnWkWiz.܍ab^>,#Q(49ɣ<ƸJGlTiVXӯH͒V=Fd"9^thD[$he YU1Yo۲ 4 gܶ '5(7>ˑi{:Ex퇷a윥ɍWg*TUPGv%#wc: h뷀_q]5"VۻeLQo_]_ds 3!КYiq$v#醜h}۽\/H*\ZWPvHmᑙ'v>=tjH±QzM/x2tߦ)Dm+)0Y+G4DbO\QF2BqTԋRAv)U q y S ~fi.cWd~*)Of& y?by"Kk6 ԇB_HiX.݃ -W q'k±CU BJ.1"PG˾x6Fc!yVϥH:(qOQ-P)۾.|e Aͥ;W7ChlH0)nF?/n&o-q;o|4ޮɃ Z8qz1_8+cf{ykizON\'bҙ^˧rv~6ad"aBKy!)l;S~ýV4|_ ĥ8UvE5L]PI*Fܭa<.{h{Y%${K%'Vz%7PӍ \q/n bX\!N͗p{eDm^S<*pLdJl3Xay):?۩GaKu9(I?z6.բO~"clOdxgsP1+&̷b0e1c1eQI LK9^́w2#_k"FKI' ZJp6h\v-8p\LF&BHa~INݓ;=#8}m(Z1PfwN.3{_Ik&g>DL.c:0?Ɖ{"I()Gx{tiPDA[J볪 [̤/a^vFWnqo,Rߦ[J3aAyL֞7Ѻ!#1ta:pV '|⃹WhW4q<IUWQpk2f2L$=\Yi8oX2CFwsacS‘0lM_>5:y\(Dbr!OaB?1\bWc,]N/ e ILcF7Mxr&9,'+޶ kxk8K׮b L.:m3&[fϤLN_^R:{-Qɺͥt-RrJSNFWypJPx~1DXW}p8{jrC<0k`~Te쉈oH9kHE*:ʃ}m1 )lvy&4X\a10i0?zħtZo>O eF( hHF}] | ST5~8M2܌I4IɖƔ˳ڦZLjY(w5Pl]أcZ^m'ZiIgv.ⱜM YPb<p玌 d-* +1-g2nKy~ cƘ@6}F`DAnjQځ\}/Xnss Y^=C YƤԦ`_l!9ep<`?!y\a,ֵoBZ0 ѝ79.f1 HfXBccp)AZxX1\s[CщEQc6 ,jپ%0;:sg:XGjljQ_+Ѯ gu[Ɩ\UrBVЬiUUnSJYT~P``m)JYJ3>R'|-Vdk[` sQͤ+&)A9X [ȑ8NЧyH?DzӃ_t׎~Al^NB*)`YN?r6СCb:I0D| Z}6ps85?B06ĢS½yqWLLKwM֢oyjv g*'D8P6$U(+y!>x: &N鎗&gǰORߓ#+cG)Y;PLl7kߊ/п9?m?L(:[2ԕY%q^lA&>u8Fs_%S 0db 4&ppW>S&_e㽮9\]̅\}{C%,6=-caܶ b 6R]DPYi?4֋J:.y([Y;2IO[YI}]5uiTCl./ j7|35>VjWQ 8wPj"°U\hdrzS!+xZAe,\R,.3K8qǝch`E-mIY).3A]Ar]}3]ڱ,Į7WVqchgi9 -T}?+yB2&v?.gmFyr a]Jm s⢫'E}.]dL&7$a)ee(]?Xq1O9J$-N/6vҢCZnD '-&B< nE mz'Lz.%DgK9S%Y*r|r~Xv$_{B- 7?sDџeAƔŸ9ʬ@h gs0 Ɔ!b9FxtR٦t}Ҹ.晉h\Kai7 O]BTSeJP)u}*GKYsTr,-Bҫ^ٜQciJe%aL$6"/Cͤt{So Aق?ԋu-cٔO"!Y#dpV—%yת` 7$*XD$vT_Ի's(wxט,xÑ6-<1 4;A˾׵Md~Lty#4w =\w1Оa]iGu>s٭4b~,VmxXp kڰƵA r/-eeJK2+J/z"{HF &&Qݹct2tGB*Ov @?2{/MYh©ơL)4'kO*L*i~Kd{藍r+:Z=%\%Es J_(l[Λ"k7DwKPϢKBŶX̶' 띈xވhZ7kC 'W} L~OcÑ8I,Ypͭ6"Hp~{-C5yjeT4S/WJ\9k{E, A)~q_^{aϋ!>[˘YFy fp=^h櫿{ߌ?+K0y6)oYoT0 ɴ&"|D@̨Iɨ f\ZǰO-pm4Fk2Yv&q/b5?]ÐAm5ƕi5xwSte;sq? 2gw:4Q͹ۓK3҆;w?i >ӳJE4J>NNۿ(SDb,)_" =4 ^5>}ZcHM9F.z.ΟhYBk0j E 2im2qL["r@ %L$ajkQgk vUfp,/t\.繥R'lx+g }8_hS͗URIM)3 3mU)ҭLrMt4Aqtmᘆ#YZvEֆxbߥnJjUr^)[0ӯaZfh1tz-`Qۍ5Vj[:|?WAU4, K)&J)8tK㥅(M17 3+VJYU+JVRɞ f(hUƂb&]@ǣhÝZN,><U{m~ 0fy1K&0c,v5 >2]ߦ׌{~ro^2iۍ~,ڌo 6MDŽ 6 6UW .L r 5ׅ FGÏ} TLdU1sJ2@J#rp*?>v[H!) Josq,Q/'& 5GG` خ^}Ѥ$sn-% HK8WߗŠ9;\gD;xvWIqe?ƯRfGV{ˠ¿]^*K -(!! 9Ξsfɬ &YY<\ɂjOW?+o^ɳ6||]BS@˥S.sȍHD>c͏s 'i^L"(ᇢǏʙ߬5H3L[YQX.z1h9/c^g'DY4׸a~7F=?ߵGa7$ #ع)y!knh&,$cy1gp~dJ%a`V^bȘFΏ Z*@cnTi9Ǖa}*V8Vt.ekjH0d Tb)L^)\Ģ]$oJte7m9ʐU`A[̢n&aI-TU)|Lhq%yVFť|%S4ٵ=[xK+k'RR՞^!ִ`Mk>"=7;qh3;LKs"uuY٭ѡN`d$+o1+,0RϨbiUj4G{daX+Ŝږ ll}`ȶmx.3[$*Q6#y7}0Cq5y˻.WQ`-HBވR2Y7y!/>sp9VVaEN%x~.t;c~'HЧsP>ikK)UJVDžbGxN$5qވ6W~ޝlfdt eh BlJPy?7fA\H <)DHY.b[q:7qbzOgV`W氽V/zؽZVٔXa\ws(o^J\b*}oի;kXɫcBVfoZ8X=JnwVWAKڋy!R>IGJ9WSUUb*_jZҥ pG[5]fK^2n^%s{R)eKxdRnU)1zO鄵I`{$_`̋j;;iG:-``C="0C0OEuI_sg6t5t<3v@1EU<"E1Agˈ)g3tXzf'hb$q0{!c>*Y82|.ȂbK1n\ArfMF̈́;'wplþy,>gڢՆOkR[یSD4΢N\j{J4rcӇʲ :Xfsʝ-:X^|.pr##>*ex],}H!^l5ש\<hO<;v3Z7my8E+ud;ct*&q&h"9іS\ܑRK[y=_f"O\3liq  6!'E/= A {GeD u[x1OYVwBz(.xܟsNAժ`4Be:?dDEm,ƦBiUTGd#c`cDž[RvL+g jo1:K"'q1J *'Y9vK?sJy.+#+N#@g G˸,u}Z 뗋|N Pƞ5Y_͋zyUxH@ͥ2MΗůS۫L4S4U cYmlYf3lDDb3"PA,nU:?2DBv ޾Fҽ s|9+cAƲJ#xa!wy ^SqaHlb:s'/FG+GfJL> *'qUW3el>Nߺ3QĤ%N n6T| *`'r+.q\^ŋhcihE>)Ox~d}7 Fe%jeF261 `ǞB4 ,|b|xWʋZ&ekЛ/pWb.f1E, VpJ|N7A&w'(,I~XN*eT]VEJ~}֙*V3@5UtO`S*fSjZT)kԵ?9V{ٶMUw9V=M\R'a#+JNxB"t9N>'BNXr+^ 9ٹ=jic)VdxeWc&ǘĪpf +>625ZE94Ve1B>%&%B ]sG"eh}<Ocs"ztZʂƞxBR1yԵLg],C:v;Kv8WhWQ_kL7Whx1im SڅQ×5N4ifz9%5*^o])-^IQ,d4^)dQ m ldLa!WrPFd`n_ 2/mZvb 5PA)2'g$16/])l!#].wС Q<9V(xd\ rTe%ẎBn* w<)zIlT/}SȶHòT =d6ڥ2gr:/dHIڋU.[E]NMsL.xNԋlEҹ+!h5љ y%.M'co2/y`x) ֢tDaxKWL=Cl? &U6l28+hO q-M"ekF}'$y4b+m*c2^,#c O*Q},B{\q2zU:)EnUt%*Pq% P ~~WV۪XFbV<lX%gV?v=_m)i7aJL4>{EwFGscF8Sw3}Y7=elϸ8~ᦎ&O?M ?'6cR4Me[#1ѳM ׻sv, a,!x0)~?F4噞{GVILbBVaޝx:saC:s%1;pF݉)5BӉ0H3;O dt o'<O+;q-a|I~!F3vL9OB>S:_Ux+ϟLlއV/#nG7fP/÷l9JQg 0=Gbowix]qIV0UI5Rr}_(}A~O(7{4.쇖K| WK ,m=GrI%xVmZ*1K3)?4Zev=+ɃY2+J ,Q-̚b>4Rc8_Yl6dqt۔ɹU2<,$UfϵtWZRX1wI9 i@%vWrv}~3 *&pG'ex{S*8KIC8P}ؑ%\ϋs\_H?6\GQ$DaË y|@OEkIkDɣ5LM{bJtvl$t{A4k^+cOD}_{\Օ:;K1QxG5IKaMH2f9q͎Fb0A?܏KeBj4ѣG[:k=: 9䎼?M(|<*w{DOv_kXF‡<( cpEY"YDz̛D,m&Ѵ:.o1+m%0K3B߼|x)㞒뫹4{1rVXIu GoQDΘ"D/Ըh̨Dߪbrg_JpK+ɡ7L-%F;FƉ:'ufZȩ6PRLMESOPsQ)0@Gt`_[_et?gTm_r ;Rĥ=ex b1؇7,ٳߐG19`*ݜ7ǗQD x!=z[+xme,.%p]9{߫Q-})7f"S9&Jjp F3xƇ>tǘDQs';vTf5G{QSO:>(\3̴bH53 Aח %~>}>;vVݘ?1\eJfyQX'tv t X$媟.>4ٛB'aT`_g:Ȁ |gg|cḼP,< f$ e9|b5:>()=J)n 5ߢp@|kSQuwh¨x?wd$2XKZK Jp/a>ZHe% ]_[\@*r*"q젚>RN(P0ܬ™*6T#@_*Bch--wPg'MfdTcYr7EЯJIZ}ԑMO \ި5yP6‡Rw;Z_V>F,u G T߬ `R*о@2?+#nYΕJD el+oz$9:χr,6[C ';U|)t#̆0XsǂW{]rLQ~.sbzD#~8cu،lsę3h%X0µlr `Gx2.-K2ZTruQ2p.cL*%ZSA d4:rΙ3 ڂϭɉ.wBiϤv6gIw(&3jd#ǕO}D~?8wl TBhz:+rgbog.#ݞ<[I!ڞ^ɬs oGC:xvpcuCN| Ad2/.\˥$pT N'Ef*Rw0 JO8^#rS*d踹^:וu*R[:$5ː(`mڷ=f=sd[&XM {R%9LX)X%rdr򈚙6Tji^ôUji~Ho(0yURZ1pQ{^|K[}K:$MF2/в5~/WNҊ|ʦGy|}A`m$~s*WNW;lp{f.kC|pq2&g,kб\w.zŹg&}Ie[%Za6{֙u3gS9¸Z#.6"jɌm Hg@1-n9+nǾNIL'_ujoMeD|Og0Τpܿ3/Ra>̎cm9H3+xΓgѪYb·)XE)/7̩~1Zp'{$M3rSDlSB1|}᎟چ,ǧ;Ӕӯ19f h0 .#P%.</CcYIeu^W;'pbI&˳3ܗ15B͚EL`۞ dBipTOɊ\ϲ䏓|XcǩԈ[ъzB{Ѝ\tT6oiEf]'j~ߜE7Db+Yz tq5XkN}=2>QGe+ $еwEa%۳fw6HҮ/w;T4)⼨2Ȫ 3 zׇMRx@F5Lf"^ k C5v.(˟+gewt,`1ey앰0AUzdJE8Դ826K՜nXm:Z-F#q(Fe3>=QeNgso$ˋ=(~ǫ^j\Y saz7vq)~S9V.o_vvݱP,O K#I8u#Wǂ9CKQ R*lwf/GlU>?XPhT B fa6nIS(2#5݆|D_::53Sw`zy.i&sZA(~wa k0f:h!Nb}r&28p^lT~agH&IMg?ޛݙp:?Eh6BW0Sɶ*(1+lGʎokihGo7^E5\Ӑ^JVgal.y :YŇDSbL -&u8F=[EBR2a_=Ul6S۶pBrXYÀ:PDZ`r!U./bzI$WxXJ7{ycϝT]ߙCy3 GS[J[Ӗ'8HlήAxU. W_R1咚eH󼐞h[k-ѹ mԭ _{Ƞ3>7Ư3ћϢH`|m:6fQ#c}hMNk9W*vRZO(e1~f:\sRIܑHKŭJ! R\W5iYEjr+RQr|/X7%9ɴL'nv&fs^'iXɞ&]8䄙cm߰ + ,ѫ2mrfDR8 EoGl'̐=xȎy{U̳ _/#C!#u%5㜄ϽIm nes6ɼjC=*Fގ/ն,h`@D;UL3893`OECȜ8|2? j0 pEŊZhYZ)¡EBfhBG-"37[| >ktptc EX"+.N>$:Eex /ފg`bdc߯mQ3?^bZ5/ac1-4P.%h4Q\).fY\ɻJeT"3h~sM~ p-O`<0F(WqsZUptd6V2F\Hb`@.B/Ā ;ÙkN!4XC",an9% <7Mw#~9)}լT„kØ[VY5);ۆ^ui-Z+4ϛ7͠\$3\(e^ `sqŸbf@@ϵVV%iN2VOB}q܉—.L)uC yc`.tT-4(!TvM*"h:ל>Eؘͨ[0h|s|ߑEqZY;ӯ@4־.FBEKYmD:3Xc ~/,z/яAxoy6%mMŏ7~nEr'`?=s(qKh?&^LېIC|i[k'3m8.\169ɛo >/u8'QeCoI73=%zւƇe(.udgu 4Tx5'"Sp)<*;.Z8s_ql.] 9_$Blv{9re5ߏ·T+TVT֤ri.~L{j:.ѕެ;<4;'g{qԸU9TXYvM75 W\j)2o2VI-i9@Ŏ>-eʋ|ɞLKh`BjI4a8+Ћ?|jJcJ2D?Pmj.ߎ3\5(RV.ѴDC;a R\ǯbLtQQ'>g/! Jm'AG:_p$TxRAِG#b9ߑuhg>M-\3!f2_Z;I-i.iFXOvyqtvK$-3H ugҭdvtIu~%&Aa#Haw:YVW/1#Dž#`jt}si283L[Z)iHՉ?y1+3[!eWL'q0&}2HiCEDH:Ê1ԸGO^ZR-fƻ#Ǘ'r;ը8:h;rzK>D0L4NvXگ+7xQ0Ԯu{ɘYt"%aKy*Yşb'lG:7B@b6jd n*ؾX;g=U0hJ.uϗ1|VԘd|fâ 2,xVNCy ;+bJqSelWf,r%|9%;sq<ۑϮܝOI<n(8i9=&ShZ4/5׮S>˵뚤RWHCJF=Pp޲['N oC:7c4B!Vk{r$ى.:xF9 REW a<VԫQA HhPÍ&4ϛpѐPcKPotA<*Jx[ɟgX6/sΑ}ِGƮ㘾;]CD]xm4wKNhfcRV)c|R9m/8+qɉkkdƴiVM*5Z:ɜk9$$߮Nj'ԺDV?fWvxp9/a32X*w9=YRdžڽPåZSNa9Fn2eeom +YE tдg k[e ]J NŶ Qk7xW0o3.jvna[IT8?WX[OKlA]/l>^*,rT,Vc`Yɞ~Y"Ijz;בlhY3 L-ؐW ԘԔF5|FA@Ȁv"_ۙ4ʰ>ɹc;&+q օHs!:D'a$Kpʽ&1fG `v"Ϣ $WŲe7Oq;Ճ]~?2Z&=t3H=fl&EZ5.sCBk⃍qL`L覴tP;){b{Rw'bz)2YcKZFZn|f)ߵ{Z[t_4|(b2ۖJFTRwc+]\+[KC6Wܫd_s5)+\! %4lӮc_Xnfr`nؽꛪiPEo|jV%V>Gq]5ghg{M*j㸚\ߥnUӳC%G4ӧY\IS%VZ WbctJ͋\d̓#9]]?OvAu0|6 Vm(lDc~ŽØխ7B[2kZ}(Hㅽxk.ag%/ȏeblw-WFka7+Ck:iVM"3iv x[>&Fvbe, X?KMId]~6tѪ 'Ӭ$Bvke$br.V1GȔ!_@bCy^7Wۉ8V2j,rzUW0j g|"QIRM%:jWPţg0p%jhDR8 'nhXIBp9j UPA nR1%MMJ舂sbvfޏ2)GD%lZXS[|ν.iTr\{}U^)}+WP7 _(9Yl5 񜑥ό76'rb.kūfuO̫hV= $tw1ӳ[2[rnhy`[χ~<36!\ k<`\<)a>+<-Գ2C=zqڍycU4P/34=nd,8,IDQ,y#=rqӈZ.%RFl-lȁa}z?\JYo˾\š}J1xZJ_Ĕ+YK G51J|))pPL92VSIJ*ȊPSͼ*]bWr75ǂ4Tk[f*;*KI5ihi}cwbv@8Y&깙w'y ݻ:RA*Jg5{8iy)dU)CbYY]UH#KΧ^$@s=ڮ]ބNx}7>(#ZpZ˚wb7LJfr4;0c'Iδ'' ?C,ۆǽlhݬFR-?ָذn)IN^W'R?׳ѭY]Qp܂[ R6gB2=%G &sz$C"qKķtk S8CV>c0XũEs1 #g$ ϑw,]e|n/gD5DQbKVէeYJfrTУ!3g2ޱ:'\{J:RθJz bK4>_0ʉTP]#\Wsz@%IA ~PsF%ިy[̥f Ԯ RDkg~F<l346{\ʉ֮i#5 Yt)iY8ȥԬO®sv}W0|)n<|׏%"e.47ev@g'FM#h -7h vR&&#ٜD' >#4 4p&?C<֛Ѽ++=“qOIa E2&GWy_ǙȺ: kCiYӋ0k^|23{Xo'KrY^U:];BqIwQ&}'=Aɜ.D^cI9$2t͂kr'l֥ @^^܀2)k6'TϦRq2#U4@̈́S^!j%)x y}|B1 *uj*/bSipOp2UlIk䆖vo ?<(cOkg-oO$gxV/ʦq:l*Pp*nMR:PP6O!*cCs:Fho'aw2oP$ODx\4n>CKٲ ǹ|ّKd~#Y=:7i]9S`.<7_eUyx=uȏ "~clc>l&'&nE_̚X3= ʷ.xtun7[+A }Y6.Z7F20I>le {N^Ч:qjۊo&\ɪYG/7nUKMtɁyw@J2_Ii^-#[TK2Jo?=Z-7I(y6Y'4Ybu|L/֟IO"0x=۟S?S^tkD bzI ;Os憒Z*E*ܼYn!r*b6-cR.-eH N*>hʟ=,{K鮤j3GQN4t$\B:dI;Ȧ^)>39~L?%6`dj얳s'ܩCFƤ~'TQS\54٣jryZGSC}ێ^v=`<2{9]wJ}]8/0`Y'.8C-Fr†:Ћc}'{ }y Kg1v%wIٚeqҏҡtAv4h4y" s^R[u-*5U^S7^ơ 5 eDvgq\Ke2컃f]Br|ª69m4]?/]?+nN ^ezpL&;oCiG-m73茬Y{;dۚ*ϚIv~ٝ{e|E7kFfm x"z g3:pG;;Nˆn|: :(g Bl̓BIe'3hUAJ4 ҰK_K,#m8ƯK0WO*89kφi\WC;^N>*jhXW%I&lc$0k V mL~\L0/v4mmbs]',ۥAyRiE!|ٝ͜Ǫ|\ʥubj`ٗHhFr:Mch:=rEeƹa&wν@oT}5z7⥅slb[֓}ɞF\ƒk|ӒHܻQ?lu=pdş9=YFjZ%^tR>z)1LtΖ.p_̷ubn 'q_+E2셶7O?Zu[PWy1ӑxY0ˏ38EO3CrbKd . ( /". vw=WR(YvIA3rC3`1*ҬKx|qQ$D?>Xfd,O a> ҬQǛ{mKU J:ScA*ebW+;͏1 H#WJ, EWMGYEۦγd/I{*>'ȠK,}HOF0-4G,[`i"`TWH vK޴^ = -pV3oM\y̝/޸^ dX?ϖMFSPO=}ۮ݇<9{o60ZN4nOH%]VuY7#';Pc5z?tYB87 6'KK)٣FE%ײ 'q<[FsqC$Kҭ8w"wr,ΑIGxRAi<k:Ʌy,b^,і (iX^ U2Uq`26C<ػӉ%]ӇYw1kœL( cUOycxCC:hxBϧR]&5h.+ek^=8`fdԵXh2 ^a-[p5W8@ ;)w''7/8fMGƏ/Nva5+fOfrNGk${JHX+T}HLcf`*GA]!36<#!lgwdoBiȹ2ܱH@:xqQ.J8X+[Tbi$CDŽkyxmx]j^?Ǹ`u"p<(JI7@yXURzs2o T`e1DF:P놭b-QxgFJ+xnoNS+gי2k5'6lka/lo: ןK>RHz<ͥ;v/.mv[^/hL;.mζ —YD n8#ٕ{s$65Mex_;kȶN_':r0ߜ&0 1|VB]"7cҋFj؃C`H29[eum1/L^g\*DQ2N-"K6}:,|v_}av=y؋nq~cm<싡]8M{&3[ʥAMv;6+XN >;) ~CDo=4Ds}e,7eR>ʇΔsjMs$WeU>?XܭX>l\ZÆy:K _eEٗˏJyCKv;wŖ^|ENk7^qM#:Ӹ߾ږ9l84\{ٱ,Xs iu4`14`Q}~2{w〈1ߌ~7,yjϑ%NlpRB#8ȥI>3Sd[ xw1~6ܕ V(cqSh^e[֎] alv!͈{2rx$[#_$r *6^4`r.w%#X1Ot;P/M}{+6;ؖI=د#0O!Ï&9LPB*RǛ XTD+`e8;v=÷̞YX kesD*;qnp93ϕ3ߍ3Iw]J|Puws߆sXlGW+I(TdjAyK7yMt4,ʲ]}ULNw?7{}JهmB/r#v3߫-1ș>W}u$U " 2~/iZC&O+Y_#-/El7a!lN#~8zUƎ}m({c)Pc`F Fǐ"<ÑHl팮#'bIU<Dlʎ%lۯsk缀&LUE!SY|_ojl9{(o#)v 1Vqd7J@96eytDbt L>I$: !Iy'mu`hPί|8џ9wB-i}ChLJn؛806QރI6k¿[Ln|lF:* ݙ:@e@> 3a@_P 1O6ev'6gy4ےEZٟm1~KNLs>|ܖ]9Ll o^zPec /䠻6O(I$F,8ZқoِxC=VM=ݑwqClHA|[y<7{) ۣU %Ieګ5Qntat@ t"(Kd*w'cwѼol"ϛ( H;cL캄YMkkP,u^vmFܝ -&#`1uMyiFnQsvXSʙ;9qq _'ngQFn^"+{}/E-t?c$.՜Kjzx^씅\]yQ8Þu_M4Qy)P Gl,5`p-aߑSRo}MI$h8^@K^E"љO<5S|z6[5^5\9 ᶾ8fDqW2Pγino}=٢̎C˝JhfLk58W)Z_깮秷A+]餜zƇc̤е㥦s+rKnx gO` :j[ WvlmHl3ΰfyKg7f/vq -\+:ћTm~M΁ϫޜ WgkK1glw0e˟ƸS(MfcFtՌљiAKKi}ҝˤA6^'eCW )u Ω6 sB;R'E=Ft"/ |LzmM#@u69Q0c;c0S_:;/=Ѝ;NHR57yֶ;Oz_y/.!{FJټK;lk5J?^HSZHHn],G.fWu,ޯ'/g\S(%7JnIsbp;rhiMRN7FIt JmU;.4!y9S2*n)۳r+Ka{y4׌q`x5<{u$}ZnqNGiׄҏnһW-N$nRuݥ \1}e7n)sl-UWJIVJKrWa#¦5`hCХcm,[,+j'͜F j~d7V -}[a\/ݼxAK^־$y,0`:r~-]> Cy}g:n616}`cR^RA{)mS}!y%;]O|_/UmOr.-;8gؾL-ݝ^*U=_4b퐿wbBSĬ ?!ݳbeouѷGUܕq)3Gz-96, ٧cl͏ʹ#e%.                                                                                                                          C[Gzo=T irN}?DZ2O#6>$˥_bw#R5ҔRZ{q e֑<;ʳߌ?^~JZgyVȷ=׽[fb{ MylIrebC)i彇Tndd4iޞzpű{yR6cܤa?m"Rk3c^RnaşT._㪤ZI燮v=Z[IsHoL`0e(Χ]r$KH u~IJ.J7 3 o ƴ0ܰ^eH/J32:e1TK9g:Y=_80d#Il-=۔dp$ kPAGVm؟edSƳ[O;} , Ѷgʖ l@c-O,=ݍ;t|4j[n@I/}$֏^Bw9N§qI$6u4RNH-&K>tx?މ鎌Qr߂i[k p`exODA׈ܥt#N3aۈA q>5LE,Ϗ` m<18e$hs@ˌt_{;0ҁjDϵ$lI8@v=`F@ ؓvPʲ7}P%%M;ZW7AH<C:ߍj$僷 Z#QRX*R|J.8rps+i;ԟ?j?ٔWo•j{`RW>z{z߃X+u$J:;3L~J@V~+~ Ti{ƌ!lؕiA'm/L_5&; v*Hlca %]a6Uۮ[݃aJ 5GanNzs [1^ߐ*45k5JG30Fr6|\#e=8po *l2RA)9#w0. A]=I.3q v֢Gc7?ن`w]k> wgZk{a~BJ~U%OK5)yvLjgJ0FV-nGm<,qO][ + K$N_ak?Ϋ_fOPV{;WXB(pуu6^Gը)¦1bV)\<ad0MIUmtF|:?5b=O{2c@}9M>دz"/זpҗa"!-5Qh\+ŃW}q2ʇkjMd'p(+n u\䮰E$[Vⵙ&W']dQ=ZP>b}j/ypE &x8˘w7pKju͸ޕxg2E!BrSw[qt6"[Ǣ,=#xwʟxK߭4Zk?\~ɛaW5t"Rnɽ+cz Zla孾a&^œ6.\Q<7!FaޚXrdsGSR҈ޢt 6܆a{2א)t%wvds`!{ݎ$ MN ;4ЋJV,_iIJ#xcw Yh,rf_ ΞuFňHkL[-cf -u,Ry?ƚ_ i_2;=g0튡m& !LpL&p){c݋ϗ ?|*Ԅ(3_%J >ӄg 3m|_g#M+S 1I:ԘVOWB89 }U,-l('W!#=̵8⁠pRo='I:E^S۝FXߊ<Ñ, $n95øn mGr&o$u]Gs*s{*d͏]3Ԟ=)ܖIk9!W^ĺvl,/Fs,+ߚxb/sR~tvP_ڧ3Z  -kN&9_Dm'_ra7< An%(a8VΕ Ҏb,jrp9nnQؼ+rE.*?ٛ'c}+0>G–:5%V;m06Wηqa's*93S+{ͬS~DW>;YP8smv8;M/b| LLG_D_n,Bo6wۙ5w0zIkB*ݤilYL$e|9<9S(X X[ޜi\m)\.rTTN4~ DÇ8p~L## 8H|yRU25˛vd Z &~%pIvEOc7tv1ŀC誣p{FVROG"JVڑp09yyAQ3xϦ-~T#8N|RҮSak" '~d6?_)#w"+ \>NUWRfrUX96K/p#L NUx)81G%\Q? !M7kaWHͧl }?ܶ:3r9,e´VxwajFә1)b̏` G^9Rq}fO 混uJ&]o c6gL?4]4w^"㝥EX.r({ \$+x5d0֋]M)2xқRf72̓L,bάi+?PMN,P"V>,%'xhʓeѤAfЩPݪwpU-nWx 덢wxjbPmIXW[LIR+W>wpmi՟I9t-/B^"ZOdt Dbǁ,gƅx,ĕ!6XNkRFbpkܝ /؟dN#+ad=kYȕIYdOYer^'ɋpjs?}8~у_,O.=h4R%_[>)Ytnԣno~|9ȓ.) M'jxM+!X;q.GcU͙ K*0_!lebjg>{bjͥl*ct}RRB'm$eG3Z/tD _O󻊯E&lvsZϔJt-,n(:ٛE ح$:74#urgYYμljz+&0]1]-b„X]M99/,XԚՉRM0ffR7T[ PpC=KE6ߵ =PI[ RؙM`pӓ/9+8qDVL_5c>a9S6}uYJ؊G4-avD"BM,Jl7GNP<xZO9ɵ)oqJACفׄt+B29BށjWcYo fdWdͺDJ &, MG4ѰΩX80˘[zjQә({Zɘ>TߔReK";Lhx>’QOb^ ^~6ekgg'nA69 S?:6rW%sNj7h39--Q32h tI\D bY2gd!Vr]UƆ±UpcRΕNOWU2۾xa%#sgcf̠,8wO :׉{AOXO CG$fa!Ze"&/'BE*r,g'˧9sc7#Nz1 /MYP'*5bvssɖV,L|Pu.wzMAڹ~Ԝ{n(=x" L"*$}R633D  ^@BuKI_AQb֯owx.d#7':sC[0ק3w<,Ŭ2UG1C.1‡dw[qja_J p&jbyǏ+lr\|cSƞ5b@g%;q^$q#ͨ 1-6bV$oo27/O ;TڍA8>"}0rI-FS \ͥA~E9xTpVF?TʫI3 w1,P6=i.7[c7_{bȉ^h2 C> E?-jVWyr)=%,D2躷Nٌ9#xP܃o&Ja*{!NzQ?~@ǩT~g<e|5!,5(қ8׈L o2z}q=]r HFB|ͷR9w}'ϥwl'G[ ]ݕ?P Eg:qԢdڊ{GRΔPH8nħ.\(Բ啼VHNدE֚kƙrr$> Scq8i ;VÇ%I⦦;Q>fI&ˌWi-UaN:ؔFW#Fsq0 bȋcR,A wp-ōVxB颛֒?g2pzLMOɑK>i*$D=; _͕쟔ܛ|́bFOE$sR\K/[[R29al.!OX:CJYh|29&(ɱc/qb9CW>C>3': kUAB:Đ=B tI,=gs*ΝEƋS(膁R4I bKߎN;+܍w\̔NUr@QdVtu0b.gIDrwi.$~Ɠ7?cΨI\0>QX!!;vԮ積w=]Y.D.Bc/}\qłC~`xP1-wZr*Umr Ea=eޛlb3eĪV1OPBxv*W x0Q=9e9xmT,A{dψR:6Ba$1ۄMXr;?;vbC+_߸pۙ,ܚnu#3L34{>40=ScND3G%$m(T{<< Ö %]v`\wmPzBݖH\6pv,KNǩNƴ%\M%䶜"ԎZDb웈 )  rjyPlJ^~J%kkx1#+y*zeXX41u uHuD\EW`Y!v\fD-tyyAeU!<9}Z2kU}w5]]hǡ,O`|MZBR$yLGș@ls=*%D,7$ e 6oUSGj!*݅R5h.Qg=2wsf%[y'-O /gz>ers*QXF!$2-Y"+F "=-CsYS_C%(trRxb_v8O6N:Pl4YC8҄:ЧZ8u45Mr%9ּ+e.(J{Fjx> 'ڬ8&p1>jd&3&ZEt9X #|ܔ:ԵǒKРw -N |G)N9%lTܻWJ ίexUّWjk(QMZR+Y6r <;e5)%xIDE  8.dV<Nū86(FDG|cS>'r@V\׶o\+tv,TwT6\zJE߃K;rzJ/bU,NhVϮ3$%؎y>6|ҳ|) ); kcsٞ+I-uDQÉ>a`߻F/VBæn5C"B@wvZ@Y}Ev XgLŒ%t(~AG r¶9<̃.2:YLR2f[9zWRп+j8unzubf%֨>4|O'Zp ';ӧ/y[/}bYr7kS!s0Pm7yZ*\OeṚL VfG”.PI%®ׄ}uv,i';^}Sw9# 8Egs'>cіٹ6ό2vɰrN`ƕޅ~6/0á 'B>| -Gz)\降*q+.ݜ%(xV<5YwT *ݎδ~醏 ZlƂePĘ.i 9e͘JG Vypї}x‘f} j{]W'S⃰)n͸np)c^[aon̈!\PB@;s.K̳d&XJUO[:g_ {בo 9LXeb闌'ѷ=\1T52e9IՁUCH  F{f-ꜞ;zl࿙ R:لl1h G I xC:?/c`13r9˥ ]hòXk>WSl: وz?gB6Dq,LގݶdVYg5%Q\ P*S݃Ktw b0r>3QjyxVd=u*N#G.7ܮ{7W׳Nup:ײH%* \Xto-]Vpjmi[r!#ۻZжE $ֈn% mV(ɝоȜuQA)jLq= YL?C_%zEWlNJ8 U['gM/}49Nڈ,ƴsw KEf,Ĭ2t,SӖ%teUgJ=72^)13CI}|4/ g=rNbZeq-Us\ZM%U\_,|f@ӻYU *F~L<Nel}R<ӑŌ,%yD 'dvOPZKB%ǰzhv6Z?bOϩ6ȸWYGqz r%,N]λED2aq v9i"#>oC9#&lPȚ#E|nSF2% _ XS"& QIl2֚Z>b/~CrD32uc>67=8/{Fr6ph#[M&6zkqv5lGd;U3G $$s}&;]!Ro>a1GyٌWf Y<͕=mGC^9ЀaFz= \z0uLc;m% C⩼}<N*qVYHܓDEnFק~ӛxVF>voSZ}2Yӟw ~oJ~;2ŽlTH>!r -ja[˶uUu(Va֭Ԉ\ˈ]UƧ_=Ŭ:XtFзċ~7Q۲lZ5ȑ-!3C~s')1#۽x>߀إĮ][0.e 0/ T$||(K1JX]JqeZTʍE<*uf)أ re-'I -ïbJӿeI\_VFe2)K)]Oq;Ŝ-r:p*şU̸R~v~%sjS]zqti؈FVLhDPOHb=M3Y hmcv'NM&4pu=Nv{또U|XOɫL당g/cTIU<AO:M-⢬dkH9%o9ӆ;p"t[~PnQ/[p؎?5){>͎LheP)cytȞd- C(]eNeJ{71lA]Ca-G uĵhvoIte_t+r:}&vж _ZUOV2Ͱ;5lVGnY -/QRCyO=[9#g,&/Mdԓ"Y*TRߪӊguV{,<IQT}K61<}ǂmd+d8z2N&'py1E UB|dďϣuy>ZT7 GM,"hvEon'nP//9/0r3^97*ofG{pv51+YUC: 5pqzM(C;7rV|_j~wcJnȗDqckS˧^uzSKZŠ!j~ )\++cE+ߖ[GJ9nSֆN>k^  ;lc[a6uj0v{{w1ap&ԫZ38[E-6 OXHL^,4!5\E#Jވ̯i4H_.˹;&uRlɠZ1bοjR*y 70l ,VCJ+WqNPbjz擽w*O|\9]L\)ZR%a&f-szkfI>l4X/ x\vARe(G7~tZLN bdh {oX݊KB@Iz1~~8}Y,o=_5Y>\|tz&G X M K"jpN\LnS6RT/tWΛeT[N2(hDAK~~:4*P=sHnb^='b}zƙ4+nhJyw [&vs-%ct}G2 :N2} ])r{f+Jq!*+MA…^kV7@WKjf[ա0uNV6a/N 6%ci8ZY9}Y}'I[p:ź'є&D3`'SMqH5 @EmwE]wL]=|[*Og%JB*)\TFLz8ڱx?b>:̶ga!EJx''TR)E8w+&;YąnP.v*>lLdYES,Ad:%4RIw{ZD`8dEBL_4"@"Q.B͇>:7EƈeI $s!Iw:c+Dx~w62ww&&z_UK3/-j>S=[=Lq3MÛ"ə+qyET)^$7 ?#%l@3o8g̾LhoTGImZmg YU"jwe`gjL2#E%zD| ?݋ǛRݼGrc0g6pF 8xb}_D=Z\::+ Xϻ"+SE\_˖:.눹T jnb5FO):rivȕ n𜖹]ኆ跩Rb)n:/H{/?/`E''[SBib՛ <\r'r^U @WĪ>͡z<~bok03ș9ěglʷ &MCZ5y4V(uxo7&r,7%qKXKl*rۺ{sX Ssj)rMZ2J"@3 Ҳ~11K%UнĖ#sU:Ds]t9gC1 Լڡ+ CysNMIٟa9vzI۫#}Ld9B:"X,%G\#?3D~eyЕׅ6lBV7eP{Xo{jW7`Q+BGr+G1sMO)E0 aGwWsH~@Ts$:9m˱ !uxŽɇ3;mznDX1Tb1j= # D<&ѱt~ľ)}j u0;Wj^R'71B:޶0r+DrȱE:>:(?gD.Ru"^,7y="'i!WBB0-#bn^{5LX'~)K̥Tұ-/8cdz03t`sߤ{bMS5G2x4fXcp~4d cRp~.Srz얱K9)pYLI5!4`6D˭1.qc8ggvᑠJ37 M1Ad:qN.1ZfҲ~?,UcVAr^)HV2刜=[n^,Pb'9WZ- j8$Բ#&O}9ǍNɏ͞Յ^ږ:Dn& _#ɩCJzt ;ɪ_J9=?&bN 7BID_?IG=I#n*pMNMn)wu:L:A!:i{=-՛j" FM&^1뚎qu67}Ոwkq0aViIq~ w0GjD*yLRnͧs))fŪrfDTdYOMW%8T# m2 Oi.ܾzKdW˘٬9Xr&9oHn'@֖1Ckwg3bJ6%KtZ*Gxؗѣk͛deUmP!eB5<95Ǚ]dqTl/x<`*k Ӄp^S)rhi<񈧬^*ˈPR̘Ʌ<ȃ~\@ܨɼa[dƆUl?Åд ƭɧ}ľl(.#SYvPKG:tMȀ-ޞcFFN6n&56'݈]tL?me=zdwO=o΄Do=ZdZ>9BOX5˕\rTphe"}Jd?J=EBȤn(]YTHb}:/ hQԵVRgL[JI@yطA*}X";E!G)0$v<7Cz3Z@nz gЭb$-"-ߩoTk Gt%rcD9"s&y_ɄEpQrM(㔹 m)L9|bSхK9dP❼s?{ ]M;?P&MVNpTcO.nJ/"Vɺ@ϩxYOF4h)q$?3v?ʲ Ԋ` 7cר257jxM89^_KpjcDo š +X^qbBoe1%FFs.FVx`&y85[K:F:VPZi$Gˍ*f+)be?}X">6+5V3苊T vt2:rp@ tydw ?2ʙճ_M1~KYYX9ʳSY! _NA]'ߚEЧL'7^}M){VJfOd;J:?,kffN2kELJbєB,0S7 (d-:Wٖtox73!@( zF8-Dwh^sxL8ݝiZ 4Ȏ&8hWBޝOcf]LDơ|&_dc5 ʠduP+!X}?)vشSX&6l}oղY8DdX%e2V!Hq !󸔷[Fr?T^0ӏ53ɨ&`s+Ob:,}X+ĭUدRXMc-u>wx'k]ۀ.D~3:LLzaϻk9]54f74W1ؿ5\Ǵ; u0įEFu'wU|~ET51!jVj>B\9g5Ǜ3b-pns#{8z lʋocs?FWiTGpvP;= Y46n;^ͽ0f~_bRwo*vx~kkYaSipk ZSjib>ɇu1Ln"DD>T?I΢|ki9s\H2RYO4gm' kx:A&- EgnL/./zP#2fYq$3|5ےG5$}$~LxynQ'}z !svaNmӖ٧Xuh~ G5\>FfgO9^#. 3UO_V 2yT7x2ai,8vJPWxL9gʸP_s NT=Cj9by)/-ʘX&Fzjb[g+U<ܧd,ƖjnRa@Nbs/+k#1NkmqyM8τ`36UÈ qZx]綐7܎*̯2w3:Ėt[2y_A:fg ItZ+ǎDG[ /ub+qey_~ƣe_@#Xsk$Np+~鼯\7?p!ڎ!΅+g~:zzHIFIpZ\T_ر#;m'`i6 S%&w':0*k$S YG>xLC&0E6eR-SlD'_e1juTK7.LdĽF>V].o Aҫ&~ndz+)(l1 LP1]O# _*4_XRkp8OManiի?„V ,HèȚHI.)>Rl:J9d4{RJC G}K]Bvl*"ӥ{^Pbm}`y) xS L-rt5% n4'OJfTWv\9ojq?7jߍ_8Grdž/.+\1p:C+g1 v,DY l _2h9v ,Yь'5_ i{@fs(CsG3uzO;:2n킽nT+,`K1z9BMϗ:j62whfj%$ L n ys/X#膯v%T$&O~r  ;1s.r.c~^ .%."!S("LB|zW( .<+(+B)fpc-玘u([ Cyr14Mo@*~W%(YGNR6/8ka2޾)bU˒ !C+{pJ(oM1!t-#iy]G340d8˲yT¬%4OꞖ$HZ*z8XO<çc7#S Wk:la Tvcƪ2n}.&\>TqI33I!uA8zT(_'̬>WxkX/M*؞>!^ϗ&l’@ bE]UgKQd2.!yb*U1ϣZ1CTBY^%ҋ2;q6{vuLHAb~_Bpr+b*5j.΁oT> ӹa -H8H8~ rK fE1*ALx>h.xLkŮ}'ZuV67Q760R<]{5}V,?*en +$pb3 dznMȢ}88ϗVYܛm=Xٗ1xT{wSNsck;*fZ5=5'jxQC[J.ŞLÆ /Ʊ]!Bra5d UဌҎ g*IܡLU]6$c'(o@Z @T.zI<Pm(,{THSm8whi!7V0[%,+@KZ5qcx6N>hCʱ=)qli*woFLU64V5zSujK=86I[7B◰jh?.j";ly886Gpߏaz;" WpF)2 h5$G(!57(EoPKI@dWA:VMj 󢪎J5-QbBɏ03_˨HL  vy~ BYk=sd3َ>m0uqSDG^=?8Tg|)fWBH)l&%gI6fIAξ<Ҫ!RƬBJ"1d}.VQ;>|*)AJ;)i ;JXrG;%}Z?K[]F22eDؚQcMC[<:S}a2?y(COf(jFuBԵ~|QB)ĴO~ѓ5ȕÕ{8kW hB{Nlɩl%7vcoцٹ3ڹݨTہxœ8MO8{b"l{#}ljaOX/1]gk 5 m-;Kʈs?EӒ槥F,Tz#7\K9*tP 3rDNg|y1siQN&5<; qLNrL}EPINgSqoF̳ܽr'8v<[ʋH(pgcdusR~m_fml ݞ}15?Z*)T4nfSFoB8C3mHų > ceӨ)f`S9;FjnN=Wd"fM/٢uŞʓ0RBf)N_U[f&5fnR{5șਤW= ?'f` 4lY,Q/5E~y5K%dG _g;7i"xY0!+f!p՛ :7sXsN¥{I3#%uҙoUdM &Z*Yf9HQZH;[YuOkH8;+Wlwq{J Hdy4=3:C JY}JqN_UN7Fq!p2j0xƸ`3Ш=_~>v>"\7>3`"ê!&\pݿ򬁀9}b4#bU1х=v\5#Iy?ԊK,яbChnoEÐS=xΏ|0Oqp{DG}1##x}fcP rh2_8:.u?,=\ K`\֏j{jzׄӳ+rKoJ<]5iڍwڰ3YgǑfDEDa;7}gO*G4&)r["5 /jQ1gmΉ,mr2AɜX+fO2ru.bR2ɨ3 U^dKIw4"ݦS}u|٠c^GZj=dUd X%2,bq +z^xN}G4ujP~݊0tơj8߲H?NT-H&=4$Dc:e9b+&KǓQi6m~lcgҔlNLԜT.MFh i?)&Q̓Wձe 1Fef״wX'n.EO~:t%{.4'(p*pp){~!{^Jͯ :V2Ċ^2KG}=7xH_ JT\'ݮ9 2G]:; Y;,?*/ 01RW$c^ߙpwNϝ_ʦC^soz*#S_Lc* mjS3ș8rP_ZuDƙ^O^( ]Cog=A/ 1V$ Z!8m<=oaFS"Ɏy g3Hܠ`a+=]:GTC-+ZNR㎒z֗¾y898<-i"o)H@*K!;,%UʇNO+g(%>,J2ul5KGiZƋAťjPE(Yw?2VL]N"BHs*MG(霔sNĶg!iʍqi}DZ2Ffl,$Iab k ) R& vOI-wl9Na½F<)Yd,^'@ikRJ WN뿄En'6 V8%tpiaGEZ=B}[1w :>Y})Z*DO0񴕑q3i_^ۛhע* c{$?v!МҪӀ0r#ϟxProNӜZǙ=ݨ}ׇ'Sh)旒iv" SWR̷Nƙg> ,fȮX^ xA9,y %L9/uFqmJzhf)y~,m˺ٖ7N|8OΘpnQ,L'*R-IE|-NԒSg5-STPR:-s$DK;X}@q>d^ Du;QܩˠDzU&0}m~7}pvФ&!:};pyaۂ]O®L;ǧ.I8r-w_adxin]rx%-a%*UIe+7Q XA4sF#Җ @w%g*ۣCSo/⼶{XڌN 4C˫I=*'by /s$8*8Fó.(0cO!%,w'M',yg/ilGcgV2!-V̒m*FbM8ecIT5Nʋ7zp}kV W&0׏~W1kpΓa>ʨ$A %oqh#1eܲyd} UU`X]Dkgr`at>Cf &xvTS91˳DŲNs(FBG%r@"og'+%9ήx̢NN EU7@DvEQ_׮Pгfsv-Mzog>qގ Hrux=ؼ[EbZªr^/cѡXw&C+hT+yb:n`<3?řC\ӟCeX<]c񭛅׆tD.R~nݎl'NX`:EkG#,WQr6񼳂kŬE;a՗Cc:E[~p;CŠCgfwP mӬ8=Mgf3dNʺaI~ho.e kztB=֟)x],E%2b%gdnհHg)-Ռ1I'NZJki_E 1pA\ז4q[5u{lƁdɝx2:NH7na70{!\$ĩ|0?T#gLq.̴հܠq5gD7Ze>mCKg^ cE4$*`ojߝb ܃Y8%-+qO 4y)%&1.OhG3tOMzeAl1Jǃs\˺81o/RTqJ4ChMxB·࢙DћG96 G=~W|ES9WVkqibJ#hQ+tg:靈l:5GT2a@WPk }̶^h 쨗IrRQ=,B2/72+| kmZ%ݘcLrVJTsc:u,^i8[Ji{EvCi?ĚgGc+~3c y\8f${M | '{P:Wfr*݂m{nrS)m̧jҤaffc8I233UZUfff;p{t}ϫ#d9L?x=yu1awF= `0i:2U)~#rS{nύ&cl{9Pc~Jlj$.XX)g/S-$rt=fڂvR76 44 EF؉ 6ȩ)_^Em/j"\DCk%W9 s,#3f]yrTOڗw&P̾Xtx2ԃ ^,Ûæ~sD3!AtTE0pE,AQޛH;Dy"n[# C9mdž5ؼ `0Rܣ8 &! d:RYSBOQ)?9Yխ+Sૐ\qMXpxcm^Zī6TDI:x@cرq+Ze:~`ʺ"+12 B&VǍUʊp.Fi5"o"Tř:njP[K el;W63͜ipMXl c-,ah.mŸV,2䜏#XGmWefDISʌ '2fsoA+ K!bϞ"Ծ2 isRF"h^F'ǩ|[-+.pJ2s |^̣LOc{fxHFmhܔUnA+nT 'l}13b65*ILdR- q%2,w3o9*4XbSm{,\ԅ^5mܔcſ5HVDO͛6H;@OZV[XzeuJXqt nrkuXiU}&-E {r;_q_9 _NdNe"4}bl&3 ~uK]l  -”G'?WVJ ?o Vk $ɽ2S오$SWkK?'OZzxfzN5 )!vs9'~(9`.z%,D5zNlxj'^p̯,&?qX*EA2:&R%4.ޛV:=< |7x#klsP.i !Ʒ??9,m+⥣Zg*PJ;3Oeɶ5{`Kx)eƿTic eZF͈r*3ʹYF#"wL"ЮE4nP^$l:ǍRVHʹ\xnCP = HȒ9lD8#JTO >DyxOmEs+\Yc--6VRVC%H(D#j!2gc'cikaM m_}Oƚ(ڋQb^@, "A$M9x<Ǫ?}3w~G/K ?HZl*RK?ZBAI1`GJNfS4fCA!9&"q@?־ofNWVppg4݀>j})r VqߎRO>;߫`y je(y=RNJNh)װUC 򜉑$nR;Z&gSyS-HmYH5*mwkLGSu(4Y1D2òf[Œm,c3 w> ׅ#ti2aD\aqG%`.jؗJxb׉Jd-iO?#|slH-^#9F&#rV( OʜE(_YoS >_ ̇3z.]&(<R3wfZ}!!(MYC(O&bV_VNrйY.{,G ?4QVūMPN%Yk*ZG^ѓ}t _X¤B:o}b[\vі{&ٟCH͊P 0NTZyƓ|HI5oGl\^`'. ٌ %c8T O|aeB]!- ΎhD{3ԛ}xxizߖv®h$!ChܲnUbTZɘ=+0]Ɇ)s8;oFs19Y7}o3mxQ)"@mh ī&U9ڑR{I97i#z˸J- :oue뙳WZF) c~ms~4 'e^ﲤ" 2w {qnE݀ A"*|6Mw;_9Kuud(Nc2L&kok31J\x+9_RR`I*qs (\] s8K\mҨ#d0< i̡c1K]ғ}q'Ӛ#ykYs= Ndv|ͩ4#86f;wDN4AMU䅆;jZP27T׹ΊI_ҴH̅-_>2KVEk c9 #€6&SdlKdoYunbr<&x)s"1'7ch)zIB3$,ΥZfdͫ[8hB~-T0sDypw/Fr}R k")Zb>(N &_o8 Hcٕ["-)>@, 4LR)!nV)uXYv=XՋV0&%Lth0QJJBΗr焄rzdIC?d1$6 ?nԄEsD9+7,cK*GgҲssz.gjl8ؕsDMRɄzjZ5bjhѮj7N,4}ǴSB F'xaZX[7v'xփ#}AJ$`p,Dz+&)9gv waQ̋ylL_~>X7;?!8,99> dI$&Eqi,c?k*EBt }/ѶeJvsS6x0@[/_UgT~;^=%gdx<*-pjlƲ N֞y>|eܬvr|U QCJz?sXɲթ@ 1nR U,w?EcjCO A8ɍW?FhJ=$YA5~6ZGNr?xwG출A27SS o4+_K͗_nX^z˷On+of"V;[},70}h9)h%.aI8')ߑƕ|K)္ (܁]Ig5.MsQܜƜa 40MY?0Џ*.1a01Զ=0Vj >[Ibd kHwZ\UⰵGj`rU?t5pw1+ZczMo%nJug/8Uμ%ȓ8G2ZDst9i5-LԐ>z̅y%WW3a4$U .hpxbZ3^cN*H٣!Jˉ:~hd-9haMC3QjێE*Wsw'p'!9_hNz4)4 `Txb6i R K ViB(/⺹y&1v!7,1)^JrVHƈ2rU0FPYATŘmufUB_{ ~ ^枂7ͤF,BkIv?f:O Bِh6b(dB3IL&.%>,6Jvn*&W2XJkL%ĝ-D) kut>fa%N& *8ENIbs[*{%f1Zǂᘽ Ũ^蓡dR7.#2^ x1҄VW)k20f|\[Y9U,RMl.u\FAZJ1P"㓮G $MMW5MT)G }^+_. S"q)yBFdۊП&&sG<3225_h~PTJ†"R3DJI"C* ٯ!_zc7 j+ұO -=,mߖ. ڠX>ܶb'{>\sA"&zi2Pu S-ýizf Aa͋EJ՚,;yp=däulsK2YXƙt;rxw'!?[s:a:;'f"?e,: /?:>`͌DU oKPʣi+l%FJh:oMݭl:Ƞ/ɼ󖒱dnD}C-][򵆅 :j,md$b5yT$sZ SX4օi8+By).b ;4wY%3tee9dȫ9^jF&AZřjPu*NU6*X]ϢD='*]9k;KYtN$Fn=bSȀ6֙ѽ1{ ܹg?S/O~҇ѯ^ϊR֘:I}.ȴ3> Wvw4) R`[.WUn9IqBޣY2.^_1(h ebRNe8HlJHNhgBhYً-psg7*HxPÚ?Q$M = *I2v]%Ĭ0n1E?CRsءHaiDSerU 3tlYcQ_M 40O+{9_\ylVfnR`LIDq|MT8WmP<l>L\[*XEU7=gFU0zS {ZxjzŽJc*yW*qi`Q_Vチ ^UpFGg5U*f)󆜇JxdAԸˑoć@:rxs2˃SSfggDV?~pi\f{H KzWe\]­%8*gI%_/iSdP2*]f(6IIݖrj})}G z9q_7#r7joqd??dU &RM,X:ݶ>ϩh4ɅW/m>ƍx~'_EG5tBL‰] 7V?ʫ17 ¨c1wʈ(cFH92NY-㐍rľ#[pϳ%N6$bS3ڕ-{w{̦wcQ`Wmې u;_N圏Vq :dt .g=C[#\ !] h*sf Iv#t0[[Ća֎cK$6N ;HuVBÚ,ϡ<.F?#`w ,\WȷEBM\ɬs F*p8#cPB]}֌V~ oN)u X$MG֋l &~0~BpővR.AyߚN[pŐ$%z2/˷Y%Yg9p9klT?4DJfB13~7Pc#;v1NfƷQ;aq4ӧ=bÌO Nrl#9;څyf23w&lܘtܺZ2XA?ϗq1MB" Y݂[.Y=">nUaX ~(b-LX;$["s}Ӹ{*GyO+˥L 5٤*1r9~@!<__mJXZΏjF.PcAŭJJ%-T-ZǤHh 㶫XVJ*dj͵'h x*OkSw%<]Sjdj[*۫оdJ^'Td8.D5'~UcR^.M*ؠgx=n}Tpd\5 ud2wߧ iD|=syt+QEqÉu!͚;& 4m’\h}R͸:?}^mn(/#R3U+ VƑϣpaK#:fTcUFl`wO l>=0!&9v2+]0ȋ+C%l{{wT{\9TniOD{[NrfS̷il4yWWfu93>D6~4VD.> >˗ jXF:j+$5bW*4QT!#GjG5%ej, Q{ w}Ewq:JIMVhL+cUQ Tp߅Up4&G&UrcMB RIq3,+i(vJ}FEr+XZFW\Go5Ǩ fY'NɸK>Yo }ޏnLPg;̘)x\iFC1== C3Մ^k `s8= ~y'ag|XK%XYBWivnɓEb3[X681d >߲iN'䢽lh^xZ6 Ɣ0@/ts&=抻'c^|X8RXlGJ=?)nod&oepwQ&0EDTN8cEe\(itVE`3qJːb!-KClԗ7S± aB$wjT6f*Rеm x\6AJ)+D쑒6kfq娜]*F:i96Rê?K!G3Q^~Z$%r|[3XfK|.lP3ry!@8: VjROWgSS *z^qzNJﹷ*zOQV.eAd 9s?u$2v(NJ G)qӭ_ sA]O:Ğ <9#m- 4e'o6IAvsauz™R_0q'&3\BB# G%ik) >yȑeP{[!K:alZ(r }vяcnAD69Ϙtjü O aI4y:0?h6_CϦ1坘g~c:=&̚\sY'G P^%f&ɽYLKY62xLÅXJgl5V3^MJlM?|} >`JO[ZWPހJk@$b}DhXŅUnS-رL+~䶁!ɢ+rFy IJT\CZ0e#Aǭipөu]&X26_lp4xL?_, YW4ELp}c_Wqo:9Ɵ [E ܷsȏA;Ձ!C9Ҙ{b*$R~8 Zɨg2-V찋&p|0G=re.'XBS̨+@e&n׹cޏImBӺDzD*?)dBoaFi)kE>Yl,fc=WYTOF+26)aTq1їWBx@n^*Ǘ?#X||c+N~~m%1bT+DNLatN.L 2 MJjaJE*|BeURK)er}\W+YBEP]%*& /N+E%L+,MBǰ, Ry2"IdNK݊dzG"풙71g2xi&ČJJ1}KK<Nd|ve'>Ռ{@XX9(*'~zY姳ySRš~1fܛw--ͻ6؁NVt6cGnQ>݌JyTZƙylw&l/x1;i#, 0K3[R1MApQ4Zr( siJdtEbf@rc'ڳ`p3l8yqDR9>r6 }8;>,z1ʛ>fӽ(d9gDIHx#:\&g2*ge (ϖ0[c?y+8^mYVuR#}2&j5ޖEF52/R,Yu9"O9-]S눒sJ"+1=J5F(cZJif<=w6i+Y-O i{f+RI{:ZWnG%j}^C{t Jߗ#?&z)s \JEJ,[z%Np{$zvCm=o-khvUѱiM!bCWgU AMR>&"52kաLzσAp`Øj}ٙv~-'? 2n|6L,&dDe2;H(iَfڙu=7waXcѰ'{E0==Z{z,f(܊%c*62oh"j Ll :2V;޺95\`NqX,tI,EQꆎ\cP' 'ȸ7õeqiq)5%,T"v܃ZNwܾ2n ߟN2/bk' $a:m'ћet_<$,m*sk !eR>*&PYt.O娟(#cD7dhMʱ* 5*U}YDF@ k28# {,&18Y2•d;OOj&9{2y.J"v٢ϬSA `i eK:gH9pd'HxL8<0gMglJ.DEm %PĺDdwf,( #v1ɌKj=_1y5r-](~8A#"׌Y3n:h~*[b1f/,-uv_`2$Ɉ{fȺ7ˉZƘ|O[ fW~ư0 g?ɕuf kgփ}CXv:et^6vt>['5eW9/71!k C 0Z՟N. 8bxe0#&7'}}j3h-2} ƫqMznA02`:17%S)7N eEτd|39G)4pfP/.{Ld:ҏ%XLrb[-SON!6L>4?*jJL('l W(8.'j (y6kC7gv]ۗ!FLVqtx5r-v90}:A&?pw_.S&Jpg^/byRʶ%Z{t sޖpJWJ2nT㤢Qb~WR\Ă酨+%]R~޿!<ޓ~r'2_ɮ` IKunPJwmh2&j<:ϦlȩEB 'JI)ba5CWL`ГXM65XZMGK=bYs%wihK]?0p6Fc\h{6e#=eG #&q>X]`qJ_*uDAI 4,\|~pzҥBqM׍Uo+t%x*mxfYn3H)8JITnK :mB2H8"r t.KB@dB4Lf{R7ZtoI S߅mBq }F ,󣃊)[vP~JpkC^H[sM4C}ZS[1ܾg9?;oȨr!A>J:S4+0u2tY%lTƱ2Η@Uij |?2D&vrFFuciǪ%YMk|̹} ƣyy HuíI>M#%tцb7؞I~gq{I1R [9uD>ZΊO?BΆ2f%[ǍV5~o &uYY6|%g5-Z>^]-'!^n3w.#n<(D_:$t{"tm]Y4@r\ݲ> pSƺq`*.X(%RZ)O=9) i!=%r$Ⱦ!UT͒ӯY3}H q;;P=q&^@ɥ4Lϣǥ/YSgN ?r˨/T>AK}%8d2d#3AL5m]Wdoojn )=%[AAss2ч?s cUã5ԝ̌|LJv''B8/r<9b #>0ES#\$[g&P@m{ ^eD3bfeڍ+Կֲ[X=Z1Һ$n Ew5:>X}t^x lv@#ht qNw}̀|b<$X c8%(fUs8aNin4((GRXbP&8_(jE&^+XNLEKAbϤVGE|{o-F'4nv:TaZ)^SƸ/*^+H<8?- 鰣 e(H0P*roWAƗ<%UT`pwZ6js޺Rލ QJ#3G+HHmSWw"\!ֳ0.7,< Vb]d2~ӿHVR2s% aaUrcwa2;ǍA77o0Fx4)+0W^b^ GPo\-iO-|k`N E'h^K)UbZ)#ihøtlEYFq~ E?c\ЁEؒ1 82~\$9Z54ݪtyR5W7; ^H|RR>\+XֈFؔQ/ZLԅx'QSgK8.: J *9Lp9ߧ)2Pj9_:+5*YZE-*ImW.3/~>\r+ݱK\(m14p샄 z9[Fzq` nex_GF5UxY %E&x?&GC#(M8e# ښA,ZfpvRѿEA34εZ Ԍ*$5$&j2 s55-NE(\hOgN AbE0jx./9EWZVSԹ.#E_I/%oebT= 4`Ps*`mڵBn] +(HHWȘUfh*YZA*NU0M)jZSZjW2j ɍJ^JY\B+i1WI8rRlҧg~>DJ");|i{+h_2*ﷂ*17f+S Bexuε1}Zoϳm1݂()Lא x0pCzT2Ъ=*˽*Uc4_K J2MD2X7YT)a{J.2Q l+RQ2ˈTAlQɌmӿg4.PIE9 ZQwtjjg~xt N3] a(/0b>q[^KucN?mi0ib/E'q= ZN^[] #▌H}w'm(Xu zaֈ:r@}z"X_+86aVplѷI&qMi+)c䅸SIL#JYLFoJ_dJ$HY_LWƢ4J@0Kqʾ*hqN Ol(8ӰC۵~AU"0TƣJ.J4),')&ņg*?S<ӽYX >qMkB,m8>Փ݁M8JC; e)4|\ü+F5-TSɊ ES]B.rGTdkAN=.HW sZWwC5?"r`ai!ʕK  +JnQ1 6IƏr1ΖV[c}eYuqK1VXc0F|ȖTz\Qͺp#ؑk}ɔ+f2bpUo>17Ķ'z3Y)kCY;}'up)ZU9Q0[9$'JѠ%;; [d}J1! ? Zo7STΆX%MΨ6Orvjv0[-5"CS/=@skL*ir50>而A57)KE'#ԌD˴TRa{.u ²ͮ4εQup.._H㙒čkDdP&K.9pGspZvQ;OsUrUHo;%C<ϡtu۷R)e[3_:cׁ:'T\%|]1;RLJ԰no5L5ah y3MzqRMYJmPZ #2s!Wpޓ{|=‹楜SIb*N(RV1ls]se[ލd[jX[ӃUI.zF}$TWIG ^3'k˯)X 튌VhrNU1~rYi+!Jǹb!όiLe puF8&W/ 2T2XS:s4^L=5 Ė4vK%MJJ^m9%A&atn!lSaMl{D?Ӌ;)|TNԆOurbr}5jx'zū*ﭠ@&AάOq&r&s;][Ʊ|Zx1¯b~>K#r]eɞF>DgmGZEx:1>)C/iԝcMfc(q qTڳNXDc8ǫbSON`&9H鹼/ 9ĕlF{Dr&m}(WNԩT :$m"dSʂNs`$*cd G1e.c.&4=AXp4Ňlc_4SX5kr߯Z ~WY=3Kr'b s%tZ\A59ÌEu`PDAB.w,Ƚrc_W]C6kCJBTS+YVɕ 9 e͓aXd)};U`B,'˦a.E̓ٱpS8BD/9G{H**ۣ< ZP<03E7(&g1s' dhϛυ (^8ؘByӰ o5uj%ec_ tXˣ\ԫ&W7pI懧7Ǡ`ºs7eCywa;aTUyߤ=̲;f1Tʼ%B溈>{\ث]\HB`2EaO.G3r$֎9=8Q`*J8gJ+8cHFJZ7]CqVSNFD_*$G9BCS4x=@Ep/GUl8SRU9\.}X}F17ւa37-px4Y^cfϊ4VMHvCokGg\mA#,fRC_ΊTG9؁MRN { 6Gq@ؒ(nϛH$zglw]XZx`92*O{[8e=ߎv/y0qJ"tģK`ףhTg<7cFS7L*IL5ߞqt#'^ RL5Q 'f&U/,מ"tRzɅ|g|:ڤ4yBuOtXuoxzO{J0*s jQ/xV28HE-jVTs|9d}}%H̪Խ/+erB0QƳrT7FMR *KTVpOse0c dz)4LDymf &I5,4Kip\́ j^>pk5yu58?[22=3x ܌85w 7!" .`n Sp$k>CYn&wB8Ç[6'1LD"gwp#Bߕk߰A0LEA!0g<◤v2o|%&H1oYń|ӎ-n823ы>Qwv1O"59\kK50_"mP%;%((ۘſr1I&ԛɱ>DvkvG|cZwABJ~Ɩ^<ŝI>xIY7S\}X9cT!־p%ե}rZnVMfY +,5g>mFޝmD;+\8Ϛq!y&'T_)㇘͵dZ[ٞXUTBA+U[I~*؋SMkZާ)ESɽz:"+WsS|QH=$^V:;Y"^A-٫eN+Ғ_GcK-jὋu߮fqh9_˅boREC>Ni,r}j\WQjj (ܹWVՔp5jZNWKF t/K9q>ؤr\ns;3]\G &(nhO&;/,M6Q\?Y{)RYSܐ {4\]p(ҙ AaH&$PЧ*ݤQb.H_Cq6+U]Ʋ^;QØ&ufA'9d{\U]vy>+01=:^ˬ鵢v /wnv;k2i0#3K6W 7[,<:ns]:a,InS2ʯP!TRB$rm 'DY9=g+8FK#'k T7aS5gk+^ܨ9*6OkU>-44`\Kz5z!旊 *PQ̾*kveL3DNS5>V-Os蛈b-6t7EU{%lzJq򓖇5 S3TI]| װ|ID_^Y H6go+W-rN5]/\72ixVy1ˋ#زنE!1=H؛sY0׌BHYmX8FFΚX 6JTa\9;1?EkY^>em ge`&_Mdor.&?5D<;G,׉R=N/^p̪?6JK}aU_I4[tZq/oľ׵,*.rl*Xu~1<~JL`P>IC KE< qwYA)D?Tz6YMj]54̪FWl,P1UAjzjstcDs5I *8hhQI7%w>k;55b6;b5mniX&l㨔sn=c*l]Ŗr:]+:e՜9pfeUVЯJ^9U yiHJ c"3#X܆؂\=Жi`q(./65AbP`L%z8flSU \4y85 ӧ8~* ٢9u6&e,XSNS3 %~Djr+P rq9E8IXJA<%$^b,5҇7!^pLx3h}YWemVxBsR V3YNBN6NI־eU0=Z\?8͉GYDž81_'pi{/UPd ^f-бbj)wQ j UREa_Z0Qt=MTX{i9㐘ix᪦pZjoLW^Wyt94&,~;Cs-AҺ=䬎Ua@L< _kK+iy,Ji/cH UX5']0RnF<0Fw3ok+ ,܏7{cŘư8Жs*^/.KiM8vaF/VtgMdCȑwO*MoEW=Q b#W[3ћdy<,Nrd_ Y]/{ܞeF_wcnV+9n.,7cN%Y ڼO3)jE9韇Ŧr.O֮)D"(ט@RYdisX3"nuc Q$~c[D-㶝 X(YWÐΩUtpCe5 z^ͷjq(9upPEk'1t|@V tJ3bM-VsEפ*?Rg3V˻f.1c8KÉ-vGfEaF"% q8^xEH-,t)qR|ݪoqW1Yw.>,e4yԒetΞ_7]{@69lwrZ4ekQ;@w]^0hwm Ѩ1Q;;8ף{dC_~eX$k?_B  U:9D8+;/NAR9Sx=1?fnft˿ B?VK2] .\ƞ]xL"pQ>wݙ0Feb:DiEAh-?m=in4r"'KC9K!rk穯tr)T2z1rZh{3:"h97y=7MDt OҰz:tj5ZJ#t؟O';/A]EE47,Ӗ*4*uVd/J|D#Jy*YK>{XJEWଣ-ʙͬIPڜ́h#LʮkJt]RFӰC,(w#[? umTFC>b"E/h/,pu#<ҏ:‘=("0h6Nā T~ Ǯm>m{RI Şi8ܭzc"Gcy6''9q|̆WOJ*%|g:6ҁzћ̮C|ђGa΁ ^ەF{A5>$ߌdw$*AxvtT9w:oćGѽo 4M d\ [bg>ݼ׋6,}I@VwanL0eMuk$7̚c\ϙk xOoyoVXjۇ.pBA?,RWBmXlbͮm$+z,4 (d|NGpE)&r2˩MKøZnՠNG]>+$m:±_El*Ğr4d]dkǑIJzèH̰ko޿> :tstђg+=:ţ $9v Ftg4O cv< ٌjE8`XfÊS j-:rف@L1v.Z\tta)CRk`ZSFz7qVµU]h}eH$x-֚n&0 -rb ?|8 F/5Ɠb (l'嬟)=!d- "pXE*V`U*I uږS]ƹrqy!-u"lRa=COy2$.UXd^~fWT|W#Wqr)Խ(?zē6>:70[Ji yKq^j tLJw5ly6URfFR,9c S+\Пw۱s ^AtN̛˫ś`r雃Q9N`4EwG{҇»-Yg=^l Έ/uc:Siކ kB9/YAxrppjꛕ'UyjΦm> &49{ٽڙ3&TO pS0)lKQ_["e;܉;{ 4>jcs@. btN`E%GysK8#Db.o/ _h*8R\Ş2nO9+V;rQ W%󯵔*]-)Dv 6jeM UY˜ڕ 1;9 R)¢yB0AF^0mfm*Qj]71zn?:۱۬Zǂm;)=i6Gt%.kʕ,.v`%8|3Nb{9|Ã!4zr7e-g$ ֙_@ՠRgvPM!)_'9ޕ=,intօpuطk+n#NEߑjh7VK/ R;W⡟~Ymr6.ez[ɠ]i(u9=Juvds54Z$4[#Rz/hp߃R+G2 rhmyr@?̑{5`=`.GIǦ<;ݾ3$~zS2#LͶqd'2]$A$ltZ-^pjGK.xpVcuw~+aoj*MOUOr(ٖ2qm+)8@pC6B5\xW`-:{{ .?/& MgKPƋ l4q:75Wͼ8$! TtPi] m#݇͑Lf_r _OG5 U\Vna+r](/an\\0OdLn2J\>_Ad}4бZ]MojR"ϧ)4 Nh6xV .i@>?/'hZc--0^nˤ/ЃYM)L~K}uۇQC$siƑ)Nv1j9c߾[Iow) WެI"nGbﮃZ|OB]ĕ]ݝx]=tϧ*U!Z+kV1EŊl'˶ Y؍g + gh 0>Fl&]tNey"ϱ|^ K55 tYEQeC+|#[zs8&1,ĴqFݣ(<5 5 YSFxN>vfxj pTU– kH=3YjGŌ"+d' (/}W^I _1Kɩhmg[7._]>G%Q J Ю•Apb=qmvʛ~^HҠ2ԃQ1#A,­$bW?<1.qhW|ݱr,p`bM.)wW ԏ&as8ULlM%gx'pbf-ߗ7;ɍȝ(a%{Qt4\,H5Ϸc3p YU̢EX C(g$>8 w0~?ϿVggP۪b&(0*^ =FGӴ q\K¨w&UǢ6 N 9 6ö m<↭yt4: eIaŇ'TJcmmZru +UJ|jjjQH&1P˅;l]QiQyW\{9ǭqhDeP g67K#vɝT3s2>`uOu:15e+.|N׌rݽh\uGn&E/Ad(:vdKNdoK7yub iOz:Y:Αy.2uMO~9aQA ''nwd{2Bԟh=Sm7_<9{_6B~sۛ5)ZWMRc\NaHS0>-[„Zz8:ruz\͒k- " ȓfOpfLc Rk9ϩQGezYj8vGݚ*%N2#CPbN4tO?fݍĢU OE12]+FFUXgB*Tiv<^3 |T>Q{64qbj' #j,4%1+sC+GJ+CԾm[OyugyԴґm4lˏ|hY_.jYLeCD:RցpƟ_,ԓ4``)h0%.Y5kso1fuf+OۺS^:_<8@vf(]<Z)7M+Xo*eKD_}8SI5_}^MܵJ~CuEz.qTz`?N-}idEYsVNP=+ݾSW"י[1mX(XX$<{`\~r发+ddrݥ;KCK-zw뻚mC"ylkf_fy); ;kmƛJ^b[w`;sȒLeɗ^|VNcR7q&ƜnޏeCr2"dĨYsCSFz<ٻa0WQJN-%w>*#=p `?ء|^g=oB].X+cI̖ (}XQJG8``NU/VϋRA6!͵d'{fy%ߟ*}?JRfmS˗t{)ڴddܣLʮ\ lX#9m(YK7|UD{ԱJ:1~\Xv9=vW8s+-;ߥgq;W~(ّ]Xs՜_ܰ΁4Gq)~3{+]Z$PoCnZ6ݑK\R™??9 ?Y@#"7cgq48&R8 xԙe@.MbtfL bEh&c uUt('[+xY9 .fE^FPVNEj,59Ɓmalw#^&+I7v ^#fqwmq&|=;IKW],3H $t/Gk-Ji[o idM pcr8_H,/ѧq"׳29r%=J9Y+;ʯer7~k9c67h縰"Ձ̯6L rɛ#bXP*RF,i\36èr>Uc3FW }Ф"~8Mf/.b+⇺5fyC9;\y?ߋnի2TeQe hҟEF<:`oc^>rG3:k ṽ pam?${1sƖl!C8oGP:{a38U{gN:0ΚV+my̅}^/Kآۯ F)뼘LCjNghe8}:y2`eIsf6$`BOo3NwCRL MձD=I"6(\^*{"v#8e rs7K"68{뎣)A1xalX poO3Nئ|&`d5yXTuUj2)ho݄qDܗp25<)M]f"gq?.p+#\;=n<'BOسk+s|8Wϗʗ^L2 ɑL,ᐧ2U:R!AV+H7{Qnnc)#y>˝Fc`?y#I˚Ĥ`VEP|'_:i Ǟ|zeIfv#utrg}CoCFnca:z!yPjX7¤13&n֖=Om?:/WmJۀG%9:7'=10:'Vxh.߲4BXͣk-5 nG-мnA%#֖Y|–y=exVzn1ƦS[09V85[KS^i]FP]m{0wf*+GpA8{.ph3b\ȃQD]It49jǚ+)8G1hD3ˏÝe)~;=Xp_?;;t*]_o1^OY(m%^)SV)W;[c<6wC<R;#D.}0{}Et6[4#  27d,rM;$cJQPFc8t,eTUF׌79sf|#95wn$(FtEo7.LTZǑQ]e.v܉\^}} ~Y/JYƌ/519,U'[kFɭN_p4~:1KwXqHы ʥoj_u]2ۈi˲,kM IɦPq ɗte~ˀ^ȫ[Iwr$5#X2R, &4ϞܻՕ{yMX]Ղ-{4ٳ_ f6(/?ϳrN>E ͔Ɔ!kH eǻrqMEvU"M;l&C$؁]Bb2麾Tdd37\r`Kg=䅳7{p ?;bRuVg9 yrg-;LX#慜j8EJ9Hw뷴>ylp G9:R{CQJ2J2{TE Vjސ*E gZaXnC=_{|9pZLQP}[{fȊe+\703#M*g,Qow^Z𣑼kU{cYWNE1vvEarf[1C㡉[W s^1twwnªt9 y߁#dJ65jAĴ oNpb+zhuuu}̩hAָt$mW,^w_k [.J)#H*L )  4I\+%)vSh-T., ezl151{hM;kIwDk԰nZTM0U_xo~=םy~a#mS\VP|:la?)f"                                                                                                                          ?VLo'MY,~0r"M3*\>9I?J/q; \9jyJEpq Ik)r!]eMwj)MS2zIJoT =[ajBAIU %ir彗<4>yޠ/ɾэcqyC yLwې=|lF^۔vo3Ee U-yay _/yYCt|tx E'If +dGslib||1{IX2 "cRўw(XmA.,͕zs=CeN\h' J6@lleiTg@^u;n3%4[I<܏1 >lrEKOyf8=٬1FS|ˀ~c漑ߘ6p6] =TMcߤʆ _nIgJoKr6W${w?🩴 79SyfV򬆑n-q-m9U -ugR^١+oF &Xƙ^~ fs=w7xRWߋ_ ~~Ra_fI^)NM2>%G W͸Xoޛr*9,&_ڇ,c|yƶ52_Lvg{r7G dH%ϼ(z Xc#;Gɀ{`0%Vb.U$XaHY Wjo:R%ԲVW=a,;pFv 11#&Sv`JBalj^D9q=]xە{-dB>^ܕC/" M'*p\GT[ G<̑#na@c}žst(} #83%yν2O^>:^Qxo8,M#K˖bBrr=t4_%BR;>rF* G}Ċw9L}qykoffy':YPx܅s~Xq7/>YwdOuA*x[w 옚ơvw7D*Kq%&ʇSǠ0LrS0n6U b~8.Fq=|]iTl+V8+{Wg<xZaLB=7aBC/. Gv3'6:l1 5z'#jU~т==h5wƵsN8d)vxדŭ|q&=kʃ" $aXzL-N\ (oܱ՚cWAlS;ETyl~5L+$7`7>m° A`TKdzP:V9mj>vey};r}#xR2Xu'}Yt-Z@l%90:_iBvIÙ0DKaOr' Ԙ-JM˭t rPLQ4|fǺ0cm1`-;^|/ta_3y7̞co [Oϔ ϭދdf6%JY8fl@t#W4keSS$WF8x}`56w4M+{_K6{2U2W3NUrδ57Rxep3I?^wi\IE3 fMrħ*<6h;\Y-cd3<ITnYM݆/:YAы&f\&!\W"6,VA(r\F l7S.ȩ'l b]2/FU2#΋B7s"иIFl8NhܟG3Gce*:ɒhޚ֎c9f /ңU;?9S1Ql +bDn8S*~\N$s:~ ifDz֟h= BWz(?:"e s]pT0PrbH y]?If4./ij4ߚ3 K/v`_QD2-ە/FVLPSr/Vkk3u.< k-/.N*?@bR{~c0BzȾ2gHSKԤ]F&6!^p8%):bv4{_dk}Nx(T_j/2b2shn4ve-÷N`8:˚ڱ+ brfL_&WZ̎w_\p?S`Y=?giu}Wn@BgWz2C9_fA<]siщ}5k>/?#ՄT8yv1&OFp#V8+zy>վ81ƒr=}N*^|ץA7Ĺ2 &-gj _M9ׁ~h~rVd_,ce*v"VqF⹜ ϲa<Ƈmg fp~Th"lGfaRN, xY?hה ZgyI;fSzcb߅^ nׁ/ٕǷrl8+o=5fS9[t_CG$}*zF@b6|uNBkcj'FHJ`H6{a0.չd$6js&к- u+ƅqdGqDFr'V5UNΤLU1,,qy1sOR)ƯomeSхvzp·k^&PҊgݦ4,NFg8yƛܨ7ɒ -̇aZ8mTA8 ѱH28:ⵅXQ)h$-jͮIrdjZ`tv&>4F(g~,>sqk0{|f*hōmԝj<4dJ ]gU7sȵf`'Gt}$iZV;bCJ]TtpcC -(BsNxaXӹ./HnϬTgRY4^G)gV'1e?z>꽩33wk$qC +*'t5Ғ'4xrDItBەs ^Z:ǝqa,Z`VYi?qݡƖNX 6vmJp:`lN5@zc'S,Fbm/}h%~Q((WCVeqX_HƶK(cxđ@;G@z_s)-r˶x%aށTm}q#)LG=&c+ = }B~ċXL98a2ҋ߈ޛbr/,mY:-ڰY۫!ߒMH1dc&tU9uSaX:k.!ObN'/yh;ֆƆRZ -YP|ԥꋆTר'Cؓ %ߍTb0-Y(3%|& 8YlϪx2ńy, `tDw.!Ⱪ[8 ڥ=34 䠟_px/f0wRf(k lgР!̍)K;%\ $jR~)g_1>XBlٷ&)-䥜Fj'sKUcP! @};_ STDp1#nbY <2q d9iՙ-cyڠIe\û2d:sU02@`3EY߃YT7vkJ'g;{ܜ8nB䵆8>Orj.I YܬgT0lt>M$넨4֓ϥ޼FF&_f^D&<*akCi™;9u͊-\љAn {fΉ@kjnSDBg,ǖ^x/*_B,đT C߅ϖ,z큽M>KM^6][&4;[oWk.ڢhdܝ!$20; љIʞNcpG=O44-O.brNQŴ^Dԫ^Ɵ>tc1 P=E>JqUI F6)$M,\Xii‹nɱXR.5 ]qByDfHhUpb)M8Ϙfj̽͡ŠINuPW&p||v*jB樞͵o]X\%}҉1vٓ(:J#-E.償+q1Ҩi^PBeM!I0ly_fB'^98<41 aV~,y9Ϝkаd-h4G0{\tgW9lX<-i|tPM>wۍi4ysԚަ(k}p"תE|YZ̺F*"kh.[$eʧE6ʸN)}KYBqGkISxx#np;?fMh]\Q5LRz\N'O i>NL݂L*'ԭkP}`#Ï3OSc{Y3 :K)J$wtSB)H7t[Qi/ϴHlj>Gn?Ho^j17rO(?sI}Ut]8dxy%cKes&QlLSJ+|Ƙa_mĀM6`up|N2/d@7ˀBa73kɒ6 ˒аMһZ)W.ό؍})YKnt_Wh=vHjHw3s(Bc0 GSu,a"k1d`I%5EsAHn./DVoбoexVփ-,$vSAhTsbenq>ڏI{NwOcbsÔ&=90ǽWAJ^9gS)"hwHΧ1y\Pm +y۫"pYxR4Xd- ڧH?Oͱ 1z'=̡^t }w4=pf3n=࿡!蟐;p;PdL~K@qpscb:ItQηLG6a`[sK^u +3W^~' \lX;uLP³s.AKlO%;aP2:߳xY/0w O;0b']+_5GFʬu`F')1aڟ&˦mhjf~;.l(Cj#U6cYoxkqRn\ϰ6˵9$`|*dB,Bcs2 L JՔ1(2l$7kIUPA^<IŔ,}9[VavBrX86E_95 5ʽbwHJ՛y}D+w-iKF]gy [B f0"[ۗys}i5nD?Q|Yd!7`< ţYYb>Wg%_7h$xΟu\x݌޼팺Z8}զKџP,;iLlI7ŭ6>op1yEmf}T^K)BϏ`?i2ÍY9M:&)45bR_HOb2r=õYLM_Rb t{:9.Ӕ3ztP[bYrEyWl1+Z+OX2ݞ`0,ThDZN cbIY'̼8<<1,W*siq\Q1.KQmMa_v mϩ^Tۙ8ДaMwcSwM^lU@?e6bGKW 8kAZn3*4ڰ>xFFE^QƉg݉wH P7#Hɍ⦳/Wљ{~^xƔ1Gwks~ L9MRݭ k!-+ZEq8˹ϿAp5ړΆE>la+fY)K?CJ&&Cc,xuDfW_/ ෻ }:Ӭ&}Q'o!z?kFfm4ݥskG̐z)_Ƒ~Q$J&M߲i"/"'\UUDGH0U⵳']q+`qKb|%vmH06Ie8;gk!u2Rf3> xwŪB.W3I%x889ƙ}!8>zclQB/- Cݟ/;'k5M].lݭ@uՕ*uJ][64w߸nao6g}ox<122RHw]kz_068 l-)n6RT/tC3PVl ޺s'c&zg;"E1L3 frgRMa@EM728YÉIX˓ |y@/K|A\IDsa>ȹ]ΎXCTRrRɺj69-tJRG)-c2Dl ݃Y΂ HНd1\Lʃé 1Ƕ$~ `MLEgd^l #z8Sx\08pPX/{coG7qx=㢨JZV&yxo&e>ڔlnu +_Uy1Hy%H0}l:J~'@lZ>02IwBwveh=cw`?j'SydM δs[:lv)2U{/)X!*lh]/cۍ.4ș)D=*މqi]. bgtW;~ j]RЛ>#@kܟ}8vs8"gvvpϙCA,ۻΨ̻24י!}ˎ8Q` {\j–p'L7l՚#ˠ;QĔh9,}$UFŠy*:R4TK#˔z&|`ж Zq黒lU:ۂ|QO}nOdˉT[8GuH/CVخ$"6ߓ5%l͟ùnk؇oWL5 Y j_Q΂YZ x~K,ޛx+%)E\ ұ9j dqKFIa)~52gBĬrB?ϓ=#ѥziIP r-)40kP_3c)+f%$kWՔT|HL-'ƨu'LU_ 5pN\ GYÑlzɑ>sRg8aVv;QrƑ{-17+'΁X+9#.F೰u!e#Xa"6$nRdo'a؏WQDC2ā\{zH0v#,]!iSu4P2Z)dW%Z)iJ-/j=вp+ f2+R- }`ywzzWAR.ak e)m aGLdɝPUA0µ X] t䡰0i _XzXZȅ cZ8Ňcq:$&/9}G y:8^4`pnGgj0D Q_&?dzw:ֻHګtR95S0fv j'TzPldRlլ0h.P $zq8ۓ6)%G*zw+X%ɲ#}I{J6wU?˚^|C7 ҿ=Ӗ3i 5B` `4kmu[D&ډޯqkQ\dpB]e'MdP*uY[DkφP,*D:rCD\Vvu501Zn7Tjb [bXRG<+9 ܀$yocDf.`P=ch5' e5˃9>~A 5|;4Z07"9CC3Ӿ{14xF$]˹=9bW$KBy)9R!MZ!9x5lih9%ib<|[I# t٢f]:e/o[p'-ZӬp]rn*j=5WJE2*bpBC8?1錶Vh&Ru6'Pk #ّ6cXՑԣs$s'q!ZXo{&=Ҏ]jDsf,K#x'bqr4-x7ކG*5/g j n;\%u$'O" aE>Xna L> ށ}~mkż[8k5`֭Ibt)E?`Hz^˰ZԳ^SHsGs5Q,Bjxgg!ogR♈To i ӆG,澭-cf0FLiwBx<~}1= ;+R+\h]Y>A|},achwe̘T@…D. WBo#J|-WE\"ɸ6Z58ɐS(M9#U8PbwO!^IG?\Sݝݵ⚭"Q-inI;8"Yh2Z}beqT[,m&񾲀y3 pPHp-g9eR8zU{;wE3tzT`]O@--,JpYloojE} L<[Mx)| 4eW`=d س%`1O,AhjdNH)-> vSaUGͅ#2?3:)|oʣ]MқQpx= '3o~,g43h_Pe)u^7OҺ$n+2NyS:/C2וdDqT|S,yd, zƄkVi9V-hB"> hp'ہM}63iʜu1QGi&im5I٘Z9j+.a,L+O5bhuͣw'ZW.23_cUSXg Sh;{n*g%ͯh&ޗZeo{hɟGRԿKܯc}5pҐT1sp1|9,a`d9kT`o1j%icDnpA-Wɧ%t+9]OJ8AZ4LF?}k"3vV,F Jp~|ePy32"gDo*RbXN֤2r)΍e7󁌮å(eR>RGt9Nr勔5RҿҰbNY3F͌j Abx.^:ggaW湋2#cB1}(hWN&i`┺-# Lh D0ۭbhѲEwKR>P/6&sCK-lBx?2 y<,ʧߐ|ڑǓ\YI2vDc _ft {E@Xµ/z)Q_EǃVNk$c*c2z2:Uu%leCJLeXk~Lgِvp9e!vK{j匽:3G ^*b jjm UJ//1f ="F}rro-YH<<; `w- (-/d{ 6ٕ},:C1Kq\9kǖӢʹqeLQN<+eZF2e,fz?˘PZN6,O+r-*8m-w9O*PNɾ2LQ윒 .re=PNOkTez[6*o¶MȺH5`n`*fMʅFVQ%[yed'ڧxGL4I%ߗnމi4L,%T0qZK+tiCvJMm-*xa`=U V1|i*=0"2RQUeV&D7/11,6S㵎K:,T-kvF))$fd2V,=b"}9Qo5q{<%{> cxJJ2{GMIMMJZ6_yIQ5?K+E0RRl1s^1bggqP33+=Xˀ3tWCw ocmFE)ճ] "(]\1ą~֬jf/ތwĥ9-+9<'S\^keKRF"]cRE?^DRd>]FkW>^G\N"Fsiy2?iNϩi$,K h9cE3qE#sX$"F=մ W4P͑C"u%Z!a ]%դm064#_DY(u\5 7lYɼ([U!7€jOzxYH,=-4n0i:^#RŔw ޶PpX?+XOCUSRڤugPȖad-R=L3dkxJMl60码W*XE'x/rl$#^@Lm0Kǩi[Eȝ>0衴1&; ?;6u'b1M̆"GhUɿ+9tĿM = K1B]XDOz>yJܣUU$%l}}5)bڶ%w˩RVú+\GfT#gdUE&iuJ}j300"[#& ^NbMro^*wrb IߗPα VL'"MeM5h޳*Z^z7pS]MxճO&n{Wr5JNi*v*dUt5 e=Vwln*m1qY֣/Do睘 +&Mb$fYȪCTV>Gl/CKJ/$>ksK)OF<)خI83I;sX0h2cS5?v HDZHl8$}5d%R1LO2V 2 >=$hgeAz 2=w^k(je)cj.".\B~"ad|*Ia&]W]W .۩L DvʏA|2c\TTİy1zS 4Lqqm-VL v0oM ^l"[/@U>%XȋJʴ( Ueqc 9`ǯs27}-7YnZRt܉SK֭]+o gp ְgM Ss>P(~{{|~KS\Nauf**9&7%M8tDWd"öͪYiq87/ vduA.W2ZtJ䲥 \!:h*vW׽J}\=avhS49LÐqg[t62꣆L]4v Jʹk^n*je*X4(8_*6G(L+2Z'_6.g#D0.`z-弋l/a2z(YNM}j6|=kZ "sh$-8#l]),4i?m(*8WKb{O\*^63_]Eһ.rt3pCk{ќzeE֕<uE4e1Wؐ}J3;]$\d2pE F*LFs4BT7bb*,kj"_-AG눮GGp-ch8c!rw>Z j^͵ ڼ/gbUriŌ)O8PNOrNRePi_VLh9-fGrjP 搊CU%Ɂ27ČRή s-=||= RH6.!"~6Chp 6C݋< vҵu[*xɝBi0M91 8(%IeC%F" ?Fhla[ȸ(x܋ǞHbG6"eϙʺf@hMhڽ srZ3:f,NqY%x+Kx Ȧw)m\3۳iF'Z9` ܼS@KQ4oJpfXpϣ\#E,vϡIw[oL}yٗ COZ>\nkbсxF(V13@+RL,x$]/z$&έDg!{Ml=aQ#/=N(pDY&#g;X@GvT2{9XOtԙtucyԢoŸ} /7o7 wX),.mUx|;3T#U#`#݋#:;Bw-bb{YNfYDުDا?PAj>KF/U1nagI9j-|S5?Ϫ9~MML56UttW⡧8dr)4Q Ȕ\޾ VP^ˣMt)Tq51&ñp珚$"՗O / ͬq[͂sx-yUl\M3pO7մd`/ դRT<@=p=5 L$h7cܑ ,CᚌV"Ofܖ>Ƴ\;q;+Y9;ntDpc[zt'ډA|t9M&L,õOosqS]_0ZTS3{<͖xaN*.#!,"2,6+i4@ˉez¾\Aj?T2hGGE=}&{M's:#U_ɇP}1DQ%03ϼ{ygjQa̽j˝BA- 73.gR # /֟)\/vM=Vo/3YoBdLc̚hHH/V+,r,zZCA]%mɶ-㈟ϥIٱIʫG2JcJշSEf/.#`})}6>Bj*Ӱ"Gת`I'jjjP:Uffה)Ri3H˨ nS}nJOUXId#(a^*nDG;^dXAv0 %C^5p?x0LRetB:cۚn{*so3TE˺Ӹ31IEkGw'v4n~ NpʽքuњAN`lwY[4]HDŒ,]ن &s -[`jkF ;;\Nw_'l,(# ld1_ZRTq \Ɍ:U|Yɤ&:15K~81wx]\Ř30=&[G<5O?n.fQ;֎3]:= BGppL} 1-tm=Gap{`F5sPE n>iŜ&(~w}(oBxGH,c/+oPΒGeTjR2H.cLJ3d\+G@rde.RMM1-UӸLT *8*rƼJ^J<4cBˆP)ϔ3m9Y붰Mt.Pꥌ_NDV q_NKK.m̢@%Rߜ1,U^2!zvmDo|sFn֓@ôjN3w|G= n,@V whȖmHK?'=d0Wf Qfh @Zz#Sϵ/mv7pSpκ%8mbU=]fі^“u9̜zPk48|?MbM lbˡyD?+-3㥗59}Q֊3;յ.E/oY |qJJ r&qUԁd9b1K>}{Hh fdN?5s׹g>Xnpg %sDžXdʱ V"x^W95VɏU\$#2kǒVWUŖM6t. <ɢZt84jiB/an<1|Zq6c$hzFy1/{q.˦3Yi6%d\M%%32HBZ {XygVBgɣI5E,&@ !Yr.QfNzSd~OH x!aGy μ֮ͲepX ^^"Z3+1.fU4TTQJZW0zf^ZEh} {<nk6W;NF?1[1cvL7h̀]LH1J}*BLPkD`C4N*J'=qxJVȸT'BdB@.hM8 g(|hgZbvb r :5g&{:Z*P6!9sڒRKf'Ci\Ěyj5koqDX8])Z/+!k\TQ>ן5S`q9mN˙hyk%%JWOsJ:o)r6-xPCx:;vCf7fe}بY)u0`E5݉衆e: 䥎(ƔO᾿A\\n67rK #怚<~dRVN!/0 F s>Ͷ39|˥W$tݖڄL>k\:y6x-Hcc0PH|p4<4JMA4)S0z);̾(#6fsY< cj}'yr  n+i\ŅU T5P Z_ς*>y` OmmHYr3rq=FnjyCin؟X!jt3S9e_pT,)4L4mk,J {.NXNC3rʐٿAc\hN88]jcZvz;$=޲7?q}0~q"3=qx6v0$]-g5͹ =oSN͓o $"#R*le$frAs;)%:XN)*`ȯRVY@% %/)zϥ|/U1S_)y&5a7~6O.Lݎe=97rϠ]3~.UÌf@ZqG56U|yU 1V#IYTɥC5,|PǕKTc]Fw7gbB#zgO CfåqT,R -vlGu`_KFqb,4T7' SL!"g5/ڑԉf6 ѧT˲Ŧ܌u -;a ruDTnYۇEAN &sשsD2]ˇ\0hL60 Cį9XcʞTo'{s+c*g%:dWCVN+CLVCb*Kf{>ܛ$YIMĻDF _s裔}K\S°@6r.=Q.'8Hx3)%y,N`3:-P5=Sao"Vm>/ȼǀ L>uϠķF5D4L Ka&;dE:r,I9v𼽄rn#$V%vO6Yd&3x2f]ʍ >8fqSs"'ElQh}j2*!<`wgv9!J.qeu'Zv+wٙcs0s*_;( R0לǃoj5V2$4E傒_+O55k%wB`:قc},4c^3}noIɓCѺ 1xl/X뙦ܶѠdb"rT+öc2DugX+UpgF(ʭ9I+3em{{B(n7-ZÏ:ċ+K)nw=hf6N`OR͕YT?\|#P@Sso* *Sjb3.|fwˢUq2$KO͡pKEƀrmR2~S`+l}#*! 62ZOC9E~?Oz|z3|'晰/Ɉ*{E{l7CMBő \7 M暌+O5MYFb9SON[ArB%]e8"foH}4bT BU\/uwNgp%z77j3b%pǚHUwTͱe({Gg3( ٣H~ eS/?r"]:Η!13z ?VLykUu|&_Vt";}-(Qw0ߚcOGb#ogW'шk-] AoA Gsgo<5tRn* 2WΒJk+ػY`{RtLclA;ߥз*y-813㹠Ck8F2-oy4e3Z&Mf|ywV!h'ܥת2h~'[׫H8GVVHs%DY滍;̬fS :USe-#^96Wb{%-7q?{,0s091_މ; o;9f/X2liy͖Hi6VZ`%' \HFoFz2nT oD͓OVXZ<DcS rF4ymd7: 1 e /[Y/o{(7.4!>Q 5Xve<uNӣ*X d2縉% ZJ,WRrIɉrFݒұ{) Ye f>P%}ʓCɊO"[Ev96tlgs*RY॒e,+cm)e R.Rd2.U,PʚR~ň]*b4a4QJ! iI"'J"9+ap1& Qy ^0m8/+CYkOI4X+9tHxZ4=^ [6QՊ&aNV#KAwO2*(I`BF)$lsլἻSXjyBYqa;gSN A-=)dŜ9:Yn}*o- 9&|oy)w!:J\k* j%1]]O9?*mPŀ>5l[Mۨbva*Ln:d7Ǭ}g=̽F<{lM^fϷs(I͗ٻƒvylpz_h俒؟GI_H0WIA1y%S8#98t6_h;TS.*:xq!a2Q{7#z+<>rCKX)  $" G{ `n grD4cjpestW@)n{ɘQ/J4g(X2NY((3FqnRr6g 2OHѹ[ȚN'M~EMVh'\= l % a]m2p)d*Xu,?ofM kdcK"&%Kj2PdnVLf2YjjמG^LNEA[ K5Bĝyp9aʺݰ7ɣcA mb F軧+9M:HPۭ=]jG*cϽ`.Ynt6^Z6"])>DrS'dnq;-{;ԝ&7j.z3E08wh:c,䍒b./en+Y`r"?2Y iS,%$2F/@U5ewI^AcUECɐGєߎ > x[ʠ0͈XPmhTnǣsILLfǒV$'&!׋KҴ,UR̪.>vd]x:Ք"J h9C{25cV o?>E[p|{'.DrIE7}kF'&WBwB] .bj,^WRfYjިw0sR-kkȿPiP_(0/˔G7Ps8 kQ*ұ1}/O'62W9ß%rD4Ii.hnwrr4)l>IS9BA8mѧlC6Y Sb!!O2 ujYlJg#61i`ș1 LAo;-ֻj +G90Ѓ- { bͤRz RN)et Q2F`_%4p40.$ITFFub=SLliGdVZsʍG=3׃ ,Iw昵 7_kH3QcBZ jc7J0_o݋^,;)H cNx)?2Ỳ04MyNXEv?Cφ`Fw#8I 3}&{ypvފUZ y?,f?͛y毆h%{S:/RhGnX v"ȞtʶnwKKyh]z{ZǽtidpK`˞l\%e-iH(Bܛ 5Fը;Ts#~tm]W5c)rRއx1φ~%!xn\~1iu1igW0$Tud8 3a3 j c9]E %bv" >$ZZ>ZQc7 )Sh<ØFf.\|R;I>]J6KYqR+9rbLpRDIH%]'Ⱥ&K) z|"=Lŕ8ҖalDJ g8FVvZ  l[H^ZLI_g,>i )""RP/B2MsZ&c}"YEāb Ű.hDןMo_Vgg#g2v|TƲuJ4D8^y8H3`um :k3v;p`v5*VVƣQJϟ5Yd>6nBVUp7;t 8l3@ V\wQ,&9}Uۦs-jYn :WUZ61s>m3c&Ә@[ crcm4eX[z[vǁ=+颞^TPe%];K|EiEĜm(J~Jʈ)sJhRBf(ri).% )bM.`6Cqbv4jygOLStԝ. X֗:tDQ?c܌\rg!]!mY\l(QES*evJ"˹Lɦr. Y&͹?CwgZ@vN{zwM,ІЇn󢽓ݧz|Ɨt7?IQ DCb4#Yє =ڕZNq¤+=yî̷es8ˆ3I,>V@3+MfLz2}Ǿ%6O%uB`Qp-aU#dcYW ?}i8ZUCjN"w%*ZSzfgۦ#xI\ E ?ಎ~! v7`c2g| ߶Jޙ2}QYWPRQIFJfݬ bt߅y'LX}Flw]˲+$j#Ua ,emЭ"ahkR8Wv떈 KgD,(^hzbڪn@9rbx~ RT~)+Q2>L39m-ZIԦr%6GDEFMbT&oCr%l:4x1*q\*+$ 8cC(K),7ERKՏesC8>1G1֦Q!1Ļl2]dyJȹZ)e|}U]bk?R0jR=xF9\XhFp5#p}I+UNʚyґ'_=ؗšx$rސcf1u0`EH޶e~#A.9.v"(H k?|}5AC d" FSoTal7zf,JޭO5K3;*_Vϯ-sޮ)ȢAeSyi}Ֆ3U1N{ $!g g%k2<ɜ`wobn֟rɴ.EH#vz$x1X<.fAsJR[')oP.F<|.~&%q%`o|x8ؐ@ޮ `Zs1_h=ILu _`O8#oI famӲiAΌ=Hm0c9˩<7Di٥ǐ%:vd/v ʡ{Xw澝BKPjE;9lڛpoBv_1˦:sfpf3c VEݣJLk8Á3K-_kyq$=:Oηb|[﨨%Y 3Kʼt%sgFGnŸ18Gf53aVKؐqdžM.|5 &y|NGaz>OJY^\fW,FS9_/$==Q{[G:=m.ٿu:v=u|%DYvA%\ I !Ȟn<+d )}ʐdG3+)Lħqx,CG9U i7M2;hpe)&S{&<^0mhƟڻ"O0sb1`S󉸖;Z#6[BQB&^^+,Lr/9̳xI<Y՝=- з"ziTʦͬ\xa.wOJx&aP:/2c:5"Ѹa0`\8t@%i޳9ՔE{I[mt?t{O-[}B.&Xpdf3UB;=tL$%k6ӭk*co^I/Bv£nsL^咽3SamnXźɕBzʠ.IBQ(,bWd,MbOc.SX@;Ek[Yh!/M3eyN"MIs8g ybS5¸Qrq [b$N8uyVLIF'M6E2_^55a6|wW˸բ\.E=x~iPG؉թGr6-bi`!KY2&UJܯ˹!/~r<*+̒?6mѳ<Ő),Sr{ja?B8Ћ%LzD]z.v E< +Qx|5p=OB^>TtʩDs%<43N03fun汨({?")kȉl|-| 5$8Trυ|dd6kZ-\A{C'ǰh\aq `v, Cz4WIw/.5ۓaNh'—(nLDb5+k8&zrt.r\ھԼjVc JrWitD]/ tw%*+6_ͩ6eW*_Fv WLM"eX"acMūq=ԡ'[6e(GBA+R:Qωs{:8{y5?+2XD%*UArۗa`[B'w I6[h^@ mbHLwlN7۟$0}]Z%OZP.wd<)t)dsQ Q/s#HIs(BQOe<χ7Xĩ6X6P2"bIrwd򤣂h%Lv3|ލ8iBNXBenĒMJD=h2O&R>L l{I\OY }Ϛ"$be !u)a,Ilǝ(6w ]0s3fc5# QSza?-°i^އIc񭏤QU4YMąR|Rsw#KjZ˫#uհ?B G֒_U9pw5ԪUsxfUm'E:OW J<S`qlN< _8figM<6%yxX/lkB9Њ#70Delr;;0UNISNp]'*QQc*41yL.ml&kA/'FhZ1z1pg.yQ|͗mCx9kYddql k.kRlL3|VA$1a_K>^wM OB yWeҲum-=pϡW~lB΃~90d<4^$54NF4UFe݆w ᫙- (ےR\ 0TFdq;䌼!ã~" u.~}@b}ԍK K.N5(Y~W@Oi*[0ߚW8|=}{ch}<_x,UAGHa.MYD.knys.zcy0q.7ܱŴW-qZX],%qU|.ξTrY3m(fy zM#}= e|?Fqj;Qjx3Ah1Oo瞙/w`t8S_p0.%RP.Ӝb|E<_ZrT𱼂ax|+\2I_̨)y<9ۗ! &ZH WMc_MƑ:~\h^ ;z&q)A lgHV{t񠛏 4;ƈ}H+q Vghnt0m6Hssٯg%)siw²Q=t*fdso9n&e89m<[Bv15[J5S'J+/x}\y)t§} m['j5t%ϓ5A~>~eQ(7Wb'j@Iߞ_֨WۊxuSU<8iCG^|`D&u;#>/jDpY{K=.*c.EܞYRfRr9ue(d]s+hEb&Ur_>GiWSqI4x x9#kZ`4kRKQ-rLN^b_|o'.$_$XctE< ۆ1Fdၤguk"8#_y8)H}QMld3N.dӯJq.;rw) Q**8cSkYSÜ5Ƶ*ZUk^W.[1GP?cz:\GIuYa} 'd΂!Ir#2FDwyk2,K%4.f_.[tr[HPffb{6¶2qIfp03sl$de03333333SlU*U\]R\p\4NQ! %OLFpŲ_'FQ'&I/ CbN\5^AfXNaHO3,ä -2R宺* *P-xے=g7we.~mU7w%ȶ y_ A`}z1[I[[fD :=Y9-zyZ]-zw-'O%S(CGdPp6_fPBba4 ZDeN'*DR.w2kU鸉جcZ>sz75b\d}! ױʦJ1+ᢡߑz-if *p)RN-а;_cBVbo 8X=JnwTKE<Bm\sʫ+?XMTɕUS, J*3ӟ~Y& d̼ -Jhb U%t(eg2>٦*,3/Lr䖧lb\9iGՆIĬ̸x+e_/N2;5YO2_gc1B^(6QUd("l)!lau&v1}CDL`YLϤ8n]ʱʘjB4̨PxQN!Lʌ 72WVo4bAcڽéE&gJ0s*eGlĠL9:‰h;Njw4|Wx=͗DӵIxvSZ`97iTD_ߞr9C|-FBZN,݂;]ȷq{czDI8n`p[37vLe[dfdpt>ǎHy5]Jk˧l䥹d"98 *R*6Ja #`;zg1͞"9ySRrcK죧bB1Z&TFŻ'/.湺mԜh O0G5g~5 ZC٫jlmR N~UM*vEV׷"ĭI%>*X8R|.Ȃ"K0mXN2fM#'wplþy,>gbنOkR[{*G'h=Eahfuyhͦ9K8|Y~m\Hp 2U1k_1G|qP5rY A^l5ש\<81&yv2k]ǶIa0iE.wF;{i&p&h<8ޖ]ܑRK[y=]f"O\?3lqQ  6A#E/7A yGeD1YxcOYVwB(*xܟsJA`Ba:?dTGEu,FBIeTZGd#_CDž[RvL+g jo1;K"'iu*K,#Iv}J?sMJx.+%+N%4#OiHxwOvfM쭐1QDV|#en(afvs<ќQt0_$?)T |\ Ez",(˛pڴgVH6\Bi)0:gKjawg] /F:)ZM+.f}ȁ:sٗ1Y:,/ z2/,&^=w32k uZBL^$;S%5J4:_LpW 8UT5_2LeQeq nbg;E0*"Lbu & ~t$Y!!"hX@׶47)i [)2ʈ%#cJ짩vLGbF:q|d)+}TGUVZi?J`&WdR.m3{LI,}a8\^Fe Z z*Vc\M fT\QN5'V$~]P͐/̫fjnPZAJvnSnVܴ N+r>y}VJ)=A鮣[_%Nkr7S.<$[nH[3BU܃ѤfH{{N'.5A4i/w2W# {5 FRlVQ/>:YJjox.f|!Sˁg)O {G&Px|4kWTr`WsR;# e(>:F" J-+ 'ª\rtO%n_ +GSL(' WHRp:R~h%hj Jܬ6)Y/ aBO>=sV\(㸼0)x?ъ$|}R8;؏؛.Lx;KFL)Ldl4a)cPw ]= L}Y,^1.QE'BNXr+_ d#9ٱ-jiSVdpeWC:ǔpg +N9|l,ejl-µ\9shb},KMK<{;ADȑFl1 MF\¥2Cpyr6P&]ɘRFj qDeńẞBn,= w]<)jI-lD/}SȶHݲT =d6ڥ2gR:/jeDIڊU.[%E<5,]u*eGn1۱q8WAǂJL%U,7b*"U!} r?Z\ vU".dwe8/}&öA4jFvT.Y2n}I; BEgw`<5{& of6 IhNd2vv t3PD\k [=cX{~_"c`da34bzxSF{P>7e~xX,P+Hձ޵EYBhbcb5zj}@K/-ǧ)| Eω:ԼH²N:w s;K Vq8[r(Y2Α&肜y V)9C mhqޯ#%ɿ'%|\^"PeKM4` _ARoi)[0Ĉ?$ӰЦ3-^h$PN'=;2b)yR^qW@WԳLzT|K`C9wl?'C 7TR][m"_)-"[EaCX؝| ߄QK+1iQ͍L~ģ!qdݘؖ=؅O4zIde~?-٘N!(!HT5sI[p=GmG3r wLԀshoDcа/Ea$a-V z*d݉'c:63gH2c  o]\m+=XבV.bfqXY7btceC'Ea1ę" 1*2F*c"2Tg~CKp ![*ϸ}hE?k'qtcuR0~˖ST|O s,n*kk1v瑶[UǞ`uSTI%G:EC3-{ZF٣ev&?t,[狉ZB? Veqh[9kšdq6;( p?.q\Dm{fOqry~Qx<GE n;3Nh֜?ͰQ3N:W]D+jhIx^\ގԐ\͘*~Oۼ f<  M+b_ VaZ$猧M^_ͥ݋L%g'9 TprFiPU3Zxb!+ȝYB~jKabPCG,A'yb>"]BX\Kf.Nd☐Q`>5 SҀ",XGVbFl׆7y\ۓ sXlU Xiˊ8#fyZʍ!" 6gv[݇F++^y\?üO00U̔'bg$1RV~.\C-AIt-(-$˽X%3+9]O -[\L"Ww)y E<+952.e|$kfJX`@)y"rU6;B4z)3U )ұyW C@E~8ТeMxE䭕|q[Ëo#0.Kc("i8AŠnE\=XJǭ匿WFĶRbYUzZýUܾ q3 TҹBÃь:DX%)'1j ѶvTe99hb?Y Н;/z{ٔhz= / 1+-#:RiY[K{^L;.Ly}(2yQX+tvt_sQ#媟N>4ڛBaT`_g:HI |gg|SLĭPJ-<f$ e9|b5=z>()==Š)n 5ߢ^p@|sSQk¨x?wd$ 2XKZs }Kp#ad>ZHe% ]_[\@*rB ~m4;TE |, ZHL꫑T /cZr1㖌 ^}zf1ՙ4X2en|A|g:TR磎=а驒Cܐ15 bSOJP^NSg3\ӄeXɾ Ƶ-#ХJɮ]Nͻ2>Eq%QB){I^ 2}É`ae _ HjCr,cAI1}qEfR{]k~4nf/efx$Ƭy{| Ne[d<W ͅC˘MV{D6ɗ! 0_OqGg)ͧc/%3R<]B6c.\qDvx^ča8wʥ7m5#\8?x48zWKD W=!:cV"ݼ酌QLdvhC#hsQEMpYޕF<͉y a'm3XZZr:-+2vRl&hXF |sKX^%fpu'1ؕ-< \xŸ:YXǓȒ5&VHL)Ԛ6sE }ωo't\lf i9}Ϭ0F\11яf>A4´n݆w:m y2~ E}x6]b J1 _X%#g8%2oi"R&6b~b2u.􎃑*s޲#l}?mQ!Z[w^Új\hn^}= 磑%w%3 hZ},̘SqFΩ刳MUjz9옧gDs4of-XяRַuRD粹I] Ͼo"k:.P6H|:k\b FG0d*Μ-ټNJe}pm gK;z#/CsAOMڕ֢-+qPz݄sfB r2^ 9Ԓsܞt~nͰMNuaH{&a=KڽD1ޜD%pgo}$zCO3m9/DKd#"wp&?, ^1?0gnOl:vr/~4|mk;7Vķ D0`H,rxn$µ\_JB͇gPu G<-7SUB`hT{<",8%.k^Bv뵈۪u]I\ ]4B'4'15E1C-hնmڽ+U>idO#8q+əDNBNQ3Aˆ -kJK1׏i=_􆂉 XTJ<-coI8|XBxn)O#Ag>ZhBwкZ)r~C˓s)J(?/çlxd᚛D>wެrtkX9gvo»L0- 3SN\JD$iR`O5[Y/ 4ְZ؜S&[$pjkVG>a U_)O0bGѶuȕ?sol*cp __㧶v ~}0)41LEE.C~c.z NrE itb$ D: 8$tMQ ˘fW *ض'ٳPq)U?Pb ׳,!/q*{ ZFts`Wc83E&,<[xvZxYۉG,7gQp- X g?chk͈FZ4z\O⼭OoT$z9%&Jo) t]4uFq˶ٕ #:ţ9.N>M8/-*k,co6tMũjpP{š7VP-5tbs%4,!,&}_ W(fgh ,cTܦ"r-JG(_bD6cx]t?fQ&fyqE/n*XP gP`1}<ٞXΒ:JW6TM gg)Kj͠*W }=]<ĆC-i1z2ElFx;[1SChK3G&T]AބKzt0|0%]dN*$'U`W9w pTc}EqU!o%86FqSfiɜ/A `dp c$g:LFwc#]`tGLL<ק3h`Й=ؖλzΐL>,0V`s73Bsf{+flJ^$O%*UǬ Nr +S'FۻBn¾=D On=?.>ʉ^.|]ȳZ>P3e/ d3%'tLܨ15)ni,dD}*6˩i]@Y! U먥}= vPXz+t\#x@5~_Mrv܉?&*0,=*:ƬyI6֒͟før1Bej|k+n[H *SˍJ~ʄ|8#nZ6|JXjIhDt7o 6_++i-7|xƜߏS'e"jdxbO#pq\c˷|W@JB>m9-gyGwL G?* _k? U\`CL~,(z8wuN2Vx э)r| ExhѴaEr]1?:RFMrLZtNM'nW*kקRA @%kRrdXh6~[UqY63}O%8]LvD6}d <'|dU1ܓ1x|Dxgǁq7Fҍ>kֲ\"8ó21Bzra!xߘ^3B9`)s(Y=3چ{ OKͺO*K%;˼>en%^[ׁm05OkQnb\蜟f{imhԸ"ٟlf?_y13\ecSO=?ױӭJҜd/ x|l8$`hX)rQO/8g"W-]42PK1˙}q܉—.L.qCy\>:Ri^Bօ)*"hZݔ&TkȎ͘j$>ѱO>FzT8EV籠#VJKV[[xs$$ΏV"ZF?vg?d[ٗGv < JK̶F|GVT="|G{ȟh鸌%4^LېNÃxi[k&1m.\)69o >/u8&QiCoI73=9ւe.udgy %4PFjND]xUv\p,oGxT̩ rjIj{:re5ߏ·zT#LVLĭI}\6!Gl]+=Xc)wJVy0q ?v$s-N^w qԸV9TXYvM75 W\j){2o2VL[(!s%$ S#!|Z0Wk%=S/P?[УT/!~YipW< eR 0}۔\zͨ g(Q`]i Vc(:p7-_LҹZERzn+&iWB;R \|=rTIڰ.Άį8ȡtgNG9?mhH1+yz@HʄlIKvH7G{k[LgױDB8{'P{]LBoGTG'[Ra>NX?`ZV+ ׽Ì(FKlh>b`KKv.w}Gby!C7 kʩr*kXFyJZU2JvpLLC(uM.sbX'e'ZZK0H)ss8N\u÷gq-los/D7?]ݯDG ?o닙ણuD˭(qqN Zx)4P]b ?~+iHBzyP'h,Ͻ`"|r@əFŶusNqƻB㑊6 JaGAs,ԍ}/`_OLbk\5榥v+qX`t0$ދp'} Ncզ@[Bzč qH}ŸKo:ݣXF?pH2zt:O0$1ݜQ<'2'p M9?n.l/ɏR'|*>jɿ5H\5qVs=Vծ2\se`>`FmJfCUL¦JW"敊&j"kf Pв$II/17ggk5rU ,`o/XI]΅?릿I_ }yɋA\VCQ-ۦeYoGQL)avA EKL]7>,5e @13'`ؖ..x2vj$P]F0~i~xgX٠e{'jvb+9#0PN}gK68q?Ci:E]<;sH+m=kz5m%hd%(Ne{kC'73,yNF%RԺ-a4e _wpf| cB3˜jFPЩ9#4"xM?2yOt͉½S8E?Y8E}i\KK?uf^ G}ÉÙSJwh\ǠZ0UhiYNJ:N4ְ做g5ပ B.Y{ Y$Q"^# pFZk+&_|j>Q}CW/_" sU*+.E/{K%qz9K/5#ԼxZ r5.c5m^xUAZ圙fN"yQ1vXOJ8n մ;^c:b cVlqMǟo#%^gL7F00V 3,fMbt =AWfe%,hEO +ڕ-8hPcrDהe?zٜ B`_.*ҠŃ0j,a0A;B/yq>?B8>+=bYNטG~lmѪyɘd[7"{ߎ2t~^KeӷP9r4ȅ~,$)ڙRxYʍh;hY51OU赚uK9oY ]2UV4+!X5 PWYȮD."\h{d1E{~i o!a7ں1s,v<*a3wQ*[Ž*NOa>: itݧVh5QƋee@rT3⁊Xʣ$~<Sxz$<"XÉ9ړtLm{xoC QHdyS~39̕Zy{wa[۴#D/3T &'XJ{S1![cx}'A}yP+Y \gs$s7fȥXf쉡i u.65p%M$dcxQ?pvڂhqݙS]8 M遝y}Zz+9nYƢH~VOl> EBc(/SY^™\'g^b#*8DDI8 e1DfpO XeȨfޜxE<Y$Lf,Owv]^; bL|&tR37pR 7d'66uf+7Ų[apdkߝOc("i1YYE|;.S]:,?ZB;*uEû1.QğΥܭVN6ޫ`c +\Rbt(/bv/xÚR6`O+ 3vU)R4D+u];; {%&2Wq ghl5ˈ=js} snm+K59}zQK*HqU 3˱vk}Xi8C_"ƭȧEGόM YmNvr+܊h([ Y4 g fv niuI`+|u2w86̈́tT:O"݃nK^*7z6Ŀ^&|ʌ1q18<$|*7n8FezBC ѬHpecbI5t_|)]l)M%l*އ]6uj桾QS}ęzKÿaSՒ/˜,u9 1-"r/S]JPWj|0Q&KӹfcS:o3cX8iRٿ-9gv/o\JͣżWnmvRͣ9hO'M&mO&K9{5p(v@+446 tRS흆j?";BŁ>*Z23:b,mfz?T|UέBg'4,P֤m&;m0QNȘr}o-%ְkJ,#/nnF3*'T}Odscw^;oGwg@zf$m%d3S\8d?MYaXѽT1mGXN$3B+/qe\_.>1gyiE ε K"NH^4ʳ)]d.F+aqat~{7XWىk/_Ažf"iǢs`N^SVQ(L8f! ܿXiўz@ uD.ftJFw R )cPBRF,UsᬊUū]UMH 5S*(?G&q$*;h =-uS56c9qaQв&J۟ʘ[5_*UF˵kM((ȝ|IYE8TnP?KڟٻgԻWD|z͵jlQ3d_ ۴]+7՘VawJ:;|hC: }Om6a1r= ܦtº?Fx:gпeW8ʙqh<)-q,,-Y69l!86a7<U +]h9179[]B<,%b s°ˍnL#JFGxɎâisR&;2vJ1c i-'qj<?t+g5;Y #GםTmV"Z*!D8ZR5_M-gJ>j2w,pWXEzԟ*#F%vQtp,Jȳ + jT(֊lzڞvFɊkJW|u{=*s)Κjٶ;N^35l}|(Sn~؇y+l{6$c0s%"MjOtHWPy*[E(aQ)]1p$̝+F8'TZ0}'cU4pr>_,gr5]^JvXx]\Ү׸*:?T{3+F=eZV~}AdRH6k{qhv0g:O3h/E\q(a݌u6{J N$19YPHȵn/*/bU9هZ#FQ'7&e$'Jd sWh2G1L"فNc*qTȪ6~ npDүe`VfmE/ĒWD"?596䭗 ٽ3$q{<;;DerN2O(53~9S;+fl#ۖSUdQ}E>Xf~9|K5m'T MFox40T"TIj?SF~k7QLs4T\0$UO˨ֿ׸rN&fZ Y%ܗ7rڑZK153. /Sq$nL2>RQlc GGPџ.;myx^&_Nnpefwv3\X1V[fTFsT. eo_\j+EH-nHfI I&S넊Y*nP*p.c-[ќ(c^$jӰoel߂BblXnd@\t0.,8[ -}u h4NM^Bf׎'e3yaִݟ&qZ29:f{Iˇf}XILtArho'gQ>wPnp8Oxl$Nٴy|ٙE~jY=ݖy}9c?we@`6gtyu1i`Ɍ@c.~#:Ʌs{\mIJ,fMK?ܓJmwSy$%l9yŝ>oRV3jpST׵LhF+j=zqRt0%;jA(Sk Us=Led_7E?VReA/F+A/\oG gN̗u#ؔMӰL}QӲ*ӻK f>*!ŦEӮuIʓQmNzTDАѥ!jKq)'L>k7ձ{yhh(g$rA:Fq"hd18T۪fdEN2h4K l +\7&ұ #u1C8Ǟ:?fӌ7mسmjfٟ-ߤ#V<]DAx=Ǝ\pb1GfLwNw_DQ#/Rhɽ~1ɜS=Yy?MS8݌ͬ8lcw+[khCÒK*>F)JSq,)zōKŖK=%1cr=wd|,,gptr*Z8tZ Q3`,nBhO x -fR^ninj^^4AŸ"7ŷCX1Vғ CٗѼ-¼ ^ĜD6sWkOa|Lɧ]SB\RuReJ;Ŵ׫gtQp&W1wVۏŕ6Dqt'a%pr+SH˨do6p';ވY4BvGŠj6䑛!KlGrێ/}vbpK )blN/IL?<{-ZM,dw6_kNXdbo2*M=TtWGT pX *ˎڅVtdЊڐI9gao\C)=Ź{X *cr:^TmМ5ź{pzyό9L퐂+ v0Bh7?Escy{N9ښ*՛֓C 燾x1# Uw{$9Q|{7=G6 ^ֱW|W.?Å)AXI3!^/M o}71~x]BWSVMTzIS+UtBoېMnFln`W}՗zsrGs=K&Zwޔ,Y14f+^s"߿̖ ˧Zhvmq?IL[ Aطދ~YQ1 /s7 +.JL_^ fFPN$3oiC-m7뀢Qѧ?zd{ Ug8Ό} 2K# ӎ'ՏQoƝ"'{{pe~:,X敦QЪqؚ:QzUvRu(إa{F7PwN,y~!Z1dHJZ)ǩ MdK-q9(hdnL"yYLN*SQNnrTqk!勲I^9qpŒwtN@?8?g c8kڼj Th~gR|SJhسNQW૚<$)B%jqa+LO?.p;6{42๎ {ȏiEI{1 q݆.|yˍ4Rs Đs;[sˮv 4S|~[1ŴQBq4d34\-[s37ZƢ皍Q/KOM>YNh NîdLM?.xaIPB8S4#cGC6}eWY|pRC2tw͌cX2$f&jm':!mIq1:ٔg@8֛ Lϑ}Xڗ+t7p ؈{;z.Y4ȫDg\ɹIj zu"i_`K3sn- o`^ލ}Lsɖz#čk#[=v&>Xaɂ?221Ga4&>طˁ՝ӋwB1ia/aEOy}}:H~xf<[OE:4xM4$zWC*kZvĮC/Ė~ VhpqI9xP̍ QZV?OOsu-*IϢ^ e{ k{0ZafF6JH~_ʻ̲/lgovtGg;S\&&˥ŌX^a_#׆n:!9霮RHjri0^jz)sIϷ%DM򤩅7]#WSɮU=%Ջ= }KԈDn&}U*E&P$rѱ(u-eřw)-‹G6J%1] ?nBTܰ'j;nK}A x/s-81A:,֕:K`guc h1:wbA+3Mw|#hC~&*^?z+=2'_aXx5K8ROg]A v${`Ηqc}S=XjgJKYҾa$Φn_ iEY/j:Ǩ9Øڞ:(ɣvM1M/ Fز'F\m`VXc]A_CN~ '`qML7纶SwDBh&/N{`*/bN'c]y:M),zo}bv}y؃1>cm0?⍾M( %0Gd Ŵ SqajVB/\8?{R܀=3ꮃg@SflZexS2‹'rjmc{UEz|R[Pqnc2iƯSKemK5cDfWobXڃw=l7I^'G7R[3hO>;s|>;'7SY;:TL0ȧhqc(FC,0 s&R:pz |b<6'aÈD,|T,Ho] &j|~؁כIYҟl0pӇboN!_\ZѦ9ERδb~*=C((q(S\Fbvb$2̉]g`Og8b}u>@(z)Gm?G ڠYXKϝ/d.}v7g\ FaEv~Kco ws{XSs$Iu)Vĸ 3m gN4hc·0"VFX19ƆOl.%c5T3k) =ҿ2o/솶 W e LC0l'}]6Ҳi5*Ւxs ۣ8ޛC8ݑX3mI}"53*tcgO"4C>"^3hauo}M͔9PrcPͥѵO1d@NcR?akBȽͯ,^Hgp4%[Ne@ڦ:!Č[c6eQ#Z*6u_t~^VTa(>TlR];H\\+m}"OkΉƵiH 5(Gwyθ0/(O'1 xoþiXΣLg̳fn̿Lp̈́ &\kŬHKɒ\d&SyLjҦYۻq@F;ꝠF vê"Q4n?y3X=2{ {ɃC+쩨A//v9/t]M(i"T/cPVOطݎsqFU10 <z"_ʲyk}m4}yΒ:bd#r[!f TI@9 "y"n7e-?cH%UlfO6?t6CGHZJ#G{G ԿʙI +M&+;Uݢ&nt?n$*?&-&jM[&s=;+_oqFKն4K4֒Uzxk$.s:72S7 P]>ӣ.-hX8qH7dIw%A c-n(~ڟڱ/al.'{,;Gq{01^Lq Ҍ78W1c'n6 V0fDslh$O^Ҟuq v#. VLl3}^t9cE_$;vUgt W*Q2SjJ{_s_g𳎊ګ+GO;чrno;eha(XĤg[qX c˘K ?`zH^Bxʛē+c_ś;pܓOq݊Xs6ģ3Ugyc˝P_"8{2 H3*F+y6Mϵezktpxi øv n*NE^?=嬗$w3*kV2Ɖ*D8۔nCӎ)XӌC^V!\{%zb}pv%+:;U &](n Z$iØOwi_^7Up'rEwEKn{ahԛ~׹6\@\?֋}>̓Cċ6L}iϷww]T:p=,oȳ]=B^x!Z9#c/;;M<?,^)f}hO1oQ;2 /eRru-znPesOߝʝ%W_) ?)2/vTh%.W{^m}u fR+5WmPϊLU+(5׻ta˪,{n\3PbeGшf!>n.2S.QCG,޽j*6 E]D:kwZ) h,g$G`8b27U}NoO[I$VG0үGȴ \:y¼*>-G8 !jwiNF֘VkVůK2]q6EFYه+P;PߪR tZ8KN#Cƭ4QP+ݩPɛkMEh7ynwx_/E7붛xҲco{e[WT7ݹ5+(S_--%韐ro#[o(K1j"Zs7 O%EOq٪leUC1B.I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$ICG1vr%7c(&U$itN}$?DZ Ov&[*ö5b×(ξH<2'BήS¹xi 哆]n-()3ތ?^~Jre}ʿ,Sn Q{{%I劥sO(uEC彛n0_@RptwWwnw>OlFx[1.b88*N+W6TU׮4 A{垭O&*(}rԬ٩k_V* jO7ܟ9`fqlkc.I nSDSOt0{7 ۏ7ѽbʫL o=HI~,xZՒetbFMat_co!3O*Uv4iSM,'>JV.U9^>##n)1Ԅ H؆xӵJEkB C_<ݛ6叏2zxrrBItKW3SoDqdBmZ3k@鰋q%NJk^(ZpHn!e5E@y9Ǎ꒫yA\;]4r,6rRW8 "ǀ#4 T~ m;ȅ,'GsP| '` *爂ɗt2?11PP(ܯ<@Dy#Á%mӈ9Eb>kq({p%A]d+4s-Գ҆ ܕ>xX[N|ouA|)lfl8ލPcoCGĹo:M)v7Cg8:_E7X8VxQCf*Vjbq"fWJ+>w/H7L3-i͖}מѯ5ØN<1gh#{:z#f}ޝUt ŞaWeb=qZU)et廮#8ijː}ltNί˷}s۞[ ^Y'f50R/֮Et>p"+kG 6Xkˁ43 o!^w]+MdeI{|X*vbFul ?ғ/ ݹ݊~Ǻ3\"LPZ<^QS~y,>Ŧ;(ߥKx':FTS[UKm!SyۙӜlj hp ƴvӗ. .x/v26mm33;1$.L1یm03̸SFf4G_ndu[Z-eIwC8X4P:S2TH g Ʈ3.;Pס Sd蘓@v;rVÈ9}֯=)ZܰLQ?ofy|DE۞ּiՍf$iQ5IGI΂~^\/&qdIaDObykLvV๞/: 像+Z{MPV~X)SrJ}:p'a(3^Ozʩ?/Ռǵ)'˯e߄+4X%jn|"'o{ (UR`OF(n3eX!`Do|<%5?:La[6M.'Ʊ\{W+"5f;݂ŷW2{1_ g>1pXDػso-P3Mbzk]кfw'RU/$6unQh&uRG$c܌䭰C">[\+|N)gx]Y>H['5/yrE,{?}y8ӄwp[j!\{FDF13 yoPF:RZbLfDOfHA 3i'˱w [j??ar钍FBJSwk%|st5~"[,;#xs*HJޭ4\$[\k\zɇ=DT5 "bGnɣ3z [li~NQ^%>&ܐS2'롤Ecֆ #X|dsTGRZʰޢɞ ]6X–!{4LjIEt!ڞMe9nOY {&g m:)}SZM{k"5щu޼c Yp,ta<@LutV͘THoHkf"-ulBx?ʆ_h^*;r=g~0 ne_,|C=sSDŽ /~V hѾ%WgwռJ6| 6g{^~L|y&άe˾gTHQz({MҮݰz!1 鏶0gǶr2zn H=Ek''^<N*'ROdzic ][QxXĐt8Aﲠ`wUpGy$^3;}qJՙ6ho'ʹ>/;#^sP8s!I,\"VVIP=} _=vr(|2 㯞h$lR}IF_/oG[H|_ 9Q^qp~FrfO̤n1fvdF!иUςaM\3Y*DZ)=7WUR`rgQ5's9: $&EΖ%)4LCq7wuaczb~5DJ%EƆlN7RO3Ju{GblrZ{F;E{:yȑKVeǔlHR(ܗ&Oc5ÀVuYIؚGFN4-eVd"/J7A0yZ/9YJȳ-Q6*oR# V.R-/p+ԭ(, [R08nȚ^?[ l8eQIQ1]Ұte )՞#"yJFjkxRʝ$&ThL6z8gXߣYLPY͑HkWzg3{8l@4',ygoG%c/ށK;mHW>fDa|Qsg Q&hb(i*cꓨAXe9ɬCMn&;ǣԟͮ*{qƉj7LfW .ZYal Sy[™d'1_7]ehNa{C1l^{F)qD>cb4"\tṰk%7%^LT82]V| BmKeMIT3: r,w46Gph>>|6rS#]6{w,7`~5?{Bd9Յ|vқ9W]yjƊ=Q#~1Ǟ#kOMvvc:OM6jc Ɲs7D\Wėer3Wr)a'b9XNB^1YyT.%,aJ[̣u8ɉQl\e_̬)i[%0R*|Ig$򥡌@"V"fw–IǥS{ ? 4x=?3{hMa;:u؜P#n|aMmA}:m y#PQ-p(ckGa\YC>\ma:mWTg5 f#j{ ¤lȚtCJsNk8draIFѤr@d7V׋]Rޥ~o eDn.¯k)]y.s׷<{cUĆr4ݕ]C\t1lWN-LwI-CL)^JE$綹1˅ Y𱢊C!vِfÂx3Nn5g>O}3|*Z?;ˑ:δj3)ZpF7JQF#M樻3Ǡ22 |?ʙ<Y0p}pk/":Z=F >زTÀ}c [jΆmxoZXTR९|֛+~ĚqOqdn?dY̳s.EOޏRtњ~l@lT =+-" rFvچ-k|U3g6Q*JXeÌm$F1d ڥ4/SNDt5&mqe]wa4zQ_ϠB6*jl9ز'd>!cA9'P8^0/WM:]䚭ٞjpBFt !d>HCNRߗN%F*Hc‚l}sJQtS+ӶW3ܨ"^ L.ff"yU38֓Y)Yl_Dh>{2o'{։uwm˜5_Yo 醞?!1#sAD>!Z9!ϏC+?*q8s. (i{5&Y VߗFbˍlK){\Ibi$>qD9\[ ̹!&z127.GȼuU,)#!=CALƮ"kzQĜ%ӥDV'k:N;n.K?>/zޮ3rs3y[Ɛ)k,)H8p.̉Np^;p8v5*zPM3AoŞ׌cvy.-rqG~;;0=f6acSȟ̫zFԜ%Is bg{nZ.Rሲ8w(niˤ\Š?9?LYkG oS fkdn8.\H#To{-reVLEM _\JJTTH?5L\MAE(M "ʇ`3\/i, cDЎa4O>9tdOѫ^]Q ttRNOᠹ/4 ^au""1dFpZ8~9N8JB®=-'1 뇳y nϖQs},&uyZ͉+ۄ-ap߆*6\+]-Am-81ʄFP3ȵ;dal xÜLis&t|"Jy_Β'URaVɄ ѪYP-7Bj&l:. 2mT:u 7ːFf]eirl}7`ޙШd'M^ώY0dy0FƟ{t<;D G(D)ZH ?Ns fQ\_" ~tL*)C 9RJh9ݲ)/Ra iDenSg6C,kbV=q+a9[Â*;)[V%1/m+?d ->qN[.+%s4WÉM1BWBZ?cJ; RF)v"5Y~nGTt}hJyo+4q ]K7g227M՘VALp̝#?Gaj,O l9>VtPKQ Qj5VզĄQ_Mʜ"8$?^SV? "_p5yTEs&g듵Ä3['8xXM@I 3 /+[rX#QAYY/YP0 ǚR*G!f/hT% sCirAp׎g#ٕЅ^5{j§QOUoRYƎí(ɵ)8FW2\ X=̊cdvHDFhKń}^E1,4 |ᔟW{[ zRy$)pSʆM^½{e$~* zW򽠆ZnP}iUGw0l$pȔ[vV;Ax6(GD0>G|gا|M$ A8pߤN6Z/5ZrZEҁTJk>wԿE}1 f5t SܫC+ a߳`9XKc,u8UB͋:~+xSK>弝fuNthMlYfK#-EI$/OVWeJb h]^S)eD&#e#3nQG(LI$wl6,BCdBE8۟]s]q)U惥3זO֜2CGam /;p ieN(k9+܍Y){בEتQy5a$}4ҌHDVh$^h3~,h!K-Y1Td|b2Mm(JD\P kD_Ϫ򡓌dFܻlVUZN]Eh/hٹItsq 1>Ȉ@_4[嵖\qb=YFV:6^٩ao!)+myՒ[|mr nJCwY1%U1a_WcZ1m^:c1—Cδ㍁C=V2+=UW M)P⭰yhK,MƲ@t=?\h_GWc\+KҗA:[2 (\F?t ' ,9^Cue\G=Jž>f_7J%o#zm iqR;K=-T/*ߊyKM7$KJ뇏tϾ22=t&qx ʠZd'VEJiVU- \ON-wވޟ[ j\![#YFl+Ta(S~'\9PAxךHׅ2o2cE -vS4yY~D-<0M1ilzP0bnHTO'$gV?;Ӌ)=#~q7Ѿ0WB񾗅JdM.!pVz9h( p1f)GZ@:nMS->X:9֜GL눭Sxߥ j*ySy$~˅3LT1\eqUA]mIyRbnJٔ@^Fҳgƃcѽ@~p$/9;B+N<ď+HhK 6|U5Ro'zxoaq ʹ̹0XFfvm&)-psdWOqU)d]rS#Ix>IduXWó"SVp3HHFv5 ID?DZe_|6dWE~WnfT9{2Ld N,gMb>e3uY"KVFRG&sSqu^J0NWG NPx Y73x\5roL87R/¼fP d+cU%>]p 2vb68 /aW)Ji8!G*mB?Ӭ~8{Fs!,`vw[ؘ~lu\c F][TLEa_]].Ʀ=3lb͆E9RV夎.[J)i)5,f4AGɌ\"<1sYΛXR:$IiU'\y=4ۿj@FNV5\>"|z@Fj sN1t-mjjX)bvaro/$XHPqCK=l0V-dr Wz5ƞVFp?a mnppU--C41d1<E#V$JJ69_;2Z[e%#iw&o8IQNBYF*zOkK[ص b޵!Nq{u<˵]*>ǽUcޥԊZǰDO=q#E:X Eһԛ>7}P۲Z4ȑ)%+S>Es'é#۽y>ϐ˔ةD=zXюp.cf ($$mr:}(K 6JY;c鱰 }Tی2n/g1 *9[NX;# XWD_%ѫo˒˸9eZ 2:(vl{J8WNt,T~翋1UyU|έewM=e:7ҭ}#cY1R=I56Tf5M JʛNMliz[x-(]xM~>T0LGk160Qf|9QO{ #zwz(h񦎸Kuah5*V^rV-#ds)qܶ ιT4$p/|%Fzˆuj0z{[w3n?}r6ցԫ[;x;e,2 /Tp,^,415P\E}?W̍U_5SImB54q\6sws:Y,0~]ft.uOb(KaOlCCI(5 b7sE\̲I1O[I&^wӑVOdG~ d=s# D<&ѱt~ž)}jt07Wj]R'71R:޶6r+_Wc+u|-u$nQqHĚ:t˘ףX6{p4^KLE8.W~o˴,=V!vCqWNBRI"s [^s>>~Xw`&?.g \ɠd[qk&eri-m i6)Ŧ$]Kا(-ccG=rS09j†k視P-px<LjǡC✝]Gj- T4?fnh1D9x.jVE4kزTZ yY Gɔ#r` vKd}48ɹҺTm!W3ř%q~ǁnt?O~n%0̶)_XMˆF=Ҟ8?-#FeD9iKݡ30+wM`J#b`^o:t~>uqOM:QtWĞk"Gvinv#O{@nQi^"2^˘0 jB=O5j2񢾑tcl=&\FF|ډ䄉UTi-AOCgˀZ&S J[gbΐr_դ*.=ZSGdsfs2s@\ÏE JP</B) X'#8^3 |=b۶d NMbaZ-R=.r> KUx$0[ĻL%,-_jM0OgeT{Sb!Vגr)(<96ݔ:P8G#:4L?8!N/Wk8\"@.cf ` )2䴻%# L[[ΨNŬݝ)9d`/i%zDa_NnjMUE,?ź gn&ucQIq'^?P'ft&v Fec#*'CA1c'pnpJ 'ߗo]ͶV ӃUx}D]FWYvPKG:lCLȀ-ޞkFj*mEMsD #2wQL:oTdG<Sah&2xOf|I`6T.>Τ{)'U3@IZtZSQд׊Z=tHDr D)VM< pQrMyl)oWKYBΊ8%T>eCWѸ}Q8^ԍ`z/^͛qIkZF~5GG&/ 8eDS` աM*Y^qbBoe1%FƼs!.FVx&y85[K:F;WRVe$Wˍ*f()be}X*>6+5S34 qvt2:NrjUp`)tydt 2*ի ?M ~KYYTȶ9?ƳX!?XLE]?:q Ï^PEiX*ݧ/i{C)E{ ׶Jf_d;J,n!uY3'5ã I !5)*TY B+XD$J2V2۲.MyFq&Hm@gL"O:w7cÙ}ìau 9\:2 6$x/LN*%&C*5Ք=@s'z}ROѵ L?a3qĤ&}m&UC 5-u٠ཊݯL=im㥹f&~-2.c0-E58;x !~;T+=b|y+ hP~^nOi 1>tZe" |G*?lNQ8Ւ8lHW2"L(n{!ʒg6yZ6nEXdF׍vd6Hg* 9{3UHBz6Cg(qPtwF2oI M,c2^Y(y\f9AC:53ƪIj=.4Zkc`ϕXYȂ"gɑN+gG1B ˱|PG@C;ij򶪸FTN/ j_/ys,T?b+eQ`ݾqꭜl5V*Eu&g #H^F{69JIN, {Ȱ?,p79g@)L@$暊*5]"#ν}uI<Ųq4mCV>8z\pkY;?? ݽh/c^O*{Jm1S;uWa-2;eL[DZSXf,IGmjHR1ԑy8F1 0,pXt Ai*{eD_J>hNp ,=^mC ?)\+Łҽm_׮Cʃ!?õӓ ǖhҪ46DZc)wL"0.=tt2Q(g#3/i@bM5량@2WkiwIH 64Vj蕭'Xo0~'$lunIɜd=l 2N;:Sq^j9Dv)Gs 3C{~}`ގùQ=N6wBgͷױܹGӫSiZGpv07=8,DxVl//z3;ɗuLn.\D:Eki9s\H6RY/1wm' kxe3\7PcVE\;hXg9ʁUI IQ4ң{|?V8&ټQP(]xrxh0鋿۞٧Xiu+G5Z>5SX* ֋G}]D9i2f^{ a @9?,(,MF1'~odN)L=q6씔 q frڹ+|S2|1\ND% }4ԩŶDIbW+xOY*m<ݤ¬3%(^v"Fa k4mqyT~ f\GH=X1m!)_m6f0l-+d:IV_uLAJW9̵cWK53d#X_0W~rM@_#&́_G(Ɵpw 3x_=ynt|BPK Vu5i ,|õOksQ#c²f(0JMfOq`t(^Zʉ|񈝆zMbl6˨KɥZBlD'_ e1juTKwULbĽF>^K.O,һ &~ndz+)(l1 LoP9]8GXTi qYW˶yIéȚHRJI)%>2lZShLR]"vl*bJеG9^XJo}`y SML#rt % n$ },krlL*L1ꝖwuICٺYKcq+g,lR{"Xu-~B zbOR=,](0'[2} zlή䃭78sz5u\{rw#C ;¸-XU}3p9~?W|pڜiJjS:YroJLbƩ_HVC9,O%̪]Jti`\OxDX3$31`tFTq$ z:POU7=j_( e@5Q,Hk@BѣB:afƒ_sMzV A◰o94cPs'zd Ƿyҏn:[?*71e W)'Jx] 5J^L"b.ab4/bk1ǓKXѼSe1k$a]/)Kgg ZWD_9M4(fy2K Xqw%UY=9𭓊Շ5[a ,ҦI(א,iV1POEL$h<-Nm|?԰n&10pyUj2U$S|n{JXX+Py͍ұ% ݆Ub8F2YS뀃8P1XF5̃>lya0f#8?Ċ qk|A?$L#JYIh{NMXljZH2>غޙy4~ί17AQlnKqT+biH \K^94 (ђW[طJkTe_U4X%fڛߟGϝaV3|0Ֆ²K?HN-uL\:dbc%WqO Ծd\̣z23^ԗpfm#<%|ٔɊ,eg!zBZzRsd.Om\p+6}/h=^Ԧ-? `R&",AON?{d2) {ӏZzz(%WI>>C8jFڍCB>չu"oZ‡Vx.QFVr!QKZ~73JTQSMːxLe+[8pqw(v֠<=Ӆ lԜͰъ=ئX Q.uNC)Ú#0ӹt67 dY7-d~pS4Łܙ(]݊_{WM|gswF~ÙʚIєBK*N FoN:8?~3 Y0fEjtTΎQiSOF'g%%3Jq6/V%L01GpW֩IMPM 7NVS x9*Pω:v7d{6P3I/5E~y\:L#lG,R?g;7i"xYa+cf.p՛67sYsN¥~EyK;#%3oUZM$& Ǻ*Yf9HQK;F[sXu>OkK8;+Owq{J i 0Obyt=6C X}pA?U0YN?Fs!h22ƺ ԙkbhڑ/? v AW ;n.H4iUP 8_u@`bqNc +H8~xnLtaOuVgHt{Qm^[KvgAڐ1F}pvi/twn;מnHh/N(>x8yb2@WhEKW?D=f5rvHkYxĭKuN;3Egב5vn2&4+$xr LR0U755,Eu28' )4tSJgpb1)홣nDUw¬ ODlO}/jIX7r&f;NSDw%[q/3]۶ybW=P:e_&F#rf3}Gtٕ5u'^(s]ow=n/Jc:I5;cgCHz.-$R9D(#imt079ZW|% )/g}}qspY #ۄnE0'PTE"v./?EJVJ}Y:*okzӴM჊K, TTYdqd"C[ ń?ʥّd(cUY< Q38)O$mDIG6ә&^uxea͸8~I˺%SQC=.잒[*!2r"ÓH{RٝĿN&%'vu߼ Dԍ N w'm>8!yJ9t4 N '>{Fn[߷cu9.|?J3R6ͬV2񴭑3)T/oMth]Mb`Ɛzx-4:7'$`tgwfj7եZHB;}%4𭋄f9|Oab"K|c+B3dRdY8=`Vj͔3]xXbѿ(?MLw>q{|ϏEև޿mYע{҉g;[4 ȷ%w dDnR0_7jYqMK53T)Gu.K%,x+ Qs:H܇/YPݎGtwj18>UL~irZ^FR)AI4񫖁#5,#z> ޮ#h=5-WchE$9^9K8':>^'E ]pDiYay)m1$gi.<||vH9`}:+.͘w$,I,/Kl7'!SG vs96Coe}}Sy?&v.p`L;uo \z\*m/en.7$dn?/ Y{[IuќF4:$1i:6宑+ n3#+Qbtv7l5Ϗ:.)rvDƝ3讄L( m=??g^Ta'Rď$DҊh_ng^! fkH4g%| /Fs,Ad/U${J {|o%fCpsy#hR YAu-leAJ&%= \:*.$17iۓUQ!Ec1g >,U4٭aQK -҆kS T͕"R" IxH.*`Tk h1}3 BӸ.mľ8z+9ZT^`I͜j:Jd" 2 W3P̳eUڭeDEemvfyi,w i*靗@I&bi|lk4iȉ)̍J5ɇ0u`g2"! Yᙁ$ /м]1 0˦eR+Nfpx鬛.,yoik^ą_]8W ,㓰Rx'|QVmq' ͻlYLn"j*Wʙ|At:,+Ԅsx%MkWu[Oܭ"{>Y:gx:s;p|Ӹ[~ ސAEߏgmЙQd8|݉Ş< zh0r>)P)-g -]+ah` ;ʰ68K%ƚ3Fȡ VV:oo}>݊A$sfvN&0 7W% Op){OXqHMbJo*8 kE:=NiYfAM$ 4{resW6"[ē)wq#W|x0ߋ8PE"N%| _aet U``8fsa9#ՂX,emJ8?zX+ҧq$e*HEiO+=!hZNe4BeT$PmCMs^FIkD2y6f1xi4IԶL7-fhxcsYrUm]Ƃj8NaY3b@0\43jhG"FhH6jO3hj-.MTkjBc"p]L't֖O*Vr`y%V2)l͌ƁhȎY$-+eb$I 2מ^vmBh\ڝ9vΔ #w[O58::HZ9qqɵg0Cy6y 1ӚQ?ݙQDž\cA X{֙vSյ9JdkޘE~i/sޞg,aOD%fhpy\TTߠFK]tS2j2;}ȩ4#?.kY0]N72l-`>CZcv:>Irߊz {RȆqyp-CAe2.cObFH(.]_TkxJŅ?rͬ +USs_M\1Ѿ$LKE[e7kLޏg})̂ABS^WPO{8{FZC"8'.4ǩx:l6KH^r)C{똸]^BKPՖ +;38ݞSwww׳{eg'' LX#{fYop$bh/2(j6dɬp7>)")tt ǃ+NG@Vvc?&$U\V.:(wV8eDpۀV1M$-tt'ơZUlU4|SxTX-"@Ts9|lӷXQl6_r|@eڲͧD[ȼr^XNZ8Vq&Bs)[նtfn5ؠ1t4#-,s; 4+06cpynz> uȸ呴̞t1`;JZ%v~ܞZ]ss,O$bE>DrN-%?6d-q?iD~j+wpBe*{\R=\zmU,{='FҼM7hCˤ>73^ufH`8)&늸a(&3Nf.*ur0YQrfd+Tss˹[d\~,<Isu2է>IA`=:=Y+8qFG-4UUv5 T!!fS'*8h*zYD4:ʹԞ=NXljߙ;D_ 0 ur9 J5ZjxSCC StsNXr='pn;ܡY܀ BOr&RW0+}k#ddBC(\9[; `̊dF =x~@pw+*U24Bɳ4kK)5#ʨL/JD) ܭ+gf9v%(qC)a\n.[ʆ,nOH$uOAKX<evD$eKgah"$b(fcȧB"e]X3!dl0Ƚ>_-5OM(X+ z ]jvc^;^N"/&H0a]ԙjWtz0`7)|IM2{%>qU!Xx z؂?~,I'T<+bQtav8ǟCǕGGp8'}I'l G|"6嘚W2MOJ J*SCw*Yo1skn0SU|WGGFSWBS֓]Fа=[!{28f1%;EHGXڜg@s)=Bhh}_qWA$hږӿjTwWE ?Vᦒy:W9; |K`ҷvt[jԪGN =? v 7&V1'FPt Ga)3ɰ"NjNj@ⴃ)\9O+ݶom 1=fܾ}k*?gD* oKgǩ R~V!a (ܚv9^Ɉ:eh+2[o?\Oفj<=njĕFYٟMߘ1?=k>|#x6ݺkYDptŗ"(gfj&)˙.^f qxi"=YœV0& ?%w si0QJr̓rgrzdi:C?f2( ?a4 g,0ÃJnّkŎӘۆ eKquM㖕?fj,%rt #g* T4?&%7塦bTנY'nޜE?l$<:ƴS| &xil&spk_olwM;Z4- S.agt<=KS}0Y30)w/b5,:s*xU>3ǃhKvDw~q/~|hOx0s_[V3EH>SXl˘lvg>zUa=[ܫdJzTlQNE5SUrlq]PoUT0CY?EE.(Wo6[I.ZaaH57UQ_9^ \Y! eǡL0)<`@+z`(Vur{~(aQ/o[[@{z2A URf$,,_pj8Ն#θ? c.{JP[jTSQr9#Ky3~TdP*Ck:vݑ|y,z@>.hT 9_qbUv2Pk`/AN(qk'gd,ʾxOD\sEOut;رl5Sgb!㻏[ʩc!CNNJXAb*X*V]n-8i8:Np\3(9)]Mga+ o 2Df{2xG8Ը]J+oп1_h6: ? E>BsucC>8;+B94ȟ L߈#hu-"Ty7H} c9i9]ŲdPwlΧWqȬj=e_*/Aqi:~ RC[UtV޴ʻ,w!k%a$N:"*cD =, ՟oZs/'0^4)į/$[ 5C%41AᜪHjbQZf2B- (i0,j\tOO%:+ x>97K7ŬkBEӳog:swOl FzP+V1vՇƒup $ǡ/OdaWk'Vx`9>ZdrI^Nre,ƭ~|awS5ڬY$PӾ3}'3]ϤLwr}bpNVE8EN*n)<~e!- BB7T}KlK*ogf:վ-I⽗-e\-x& TjxBd:o,PQ.R[g i'KG9-ۧ5?#ףٻ'ǣ6Xu O FN`1ɂ)?Q,1Í7zMaf*-U F;Lk_ij\U2rg~XsQbRK"gWpwU K0?ȏWG?k0%S<8T1MUBA;vgp Ӟak?nűզeY.RŒ4iz " TGI/ Dhl[gd|"v4 cNtDWup+w_1Lp9)s.kq$M\<>nqNK/ZML3SpuWzmMi`Y^m.xq}^e泚D;(t=rLΟu%1nH9 P]Ji e[S'I: m_|^ -+{9cJ ;ެ ué?*Qb-92DMcUB: KS_{ٴ!!9.ldcVyf_NsYӵlYQ_M5O+z:_T >lHFfo?-nG9-c9 0$58 b8t0ga(Un:Ύ` l+W8EWv]%CVzK^*խG=A `/*U)yM9.Ƒq&:۞Dq LqMWT;-f-g gD3®V?npYKgkH4KzץܘU8 *ꔂoTH+dLnK957Nھͥ~xnEոKB9v18/_y2Mp!/P~C.Vtה4WLqKFCh<Ԣӹ Z!r[´yVc5ڼbб{T2= ?c'謒qغ=r<ž, q!5 `-;|;{0,# >(vau(E 7J(rtx;nwL|NT);qw( ULrlvz=O5uxJLJWjVTϥ,:9d56d.$?Ev27AFrj'=԰'JV&s KUrs%*YSO`=QT]>:t-jVL"9mKKq4ĊS0ɰ"%#Zpߣ%{O5$|c3ҕͻ w{L0+~6m:y ](~2.DitT}Ƕ8,T\;Y U~I8#x(] ֡ԎesD6Fh :HyNBÚL Ϧž\.?= 7 ,X[څ 熇>^lIN2ҹԩ7+ۡ'Bbg?8.23Xu2ʤ,ă)ۘ#s,Qnl]+H^l(YYK9(vs&Kx{-'Y)4NnJ[.?An^0M¸K& I92oK:IjU} ΒtKLdG')S䰻嬶V`z(<5:p󖚓oa. u<&fO=TQOCJfW̭dbi-p@6KJx.6^AWxWA̡ 6Wpbi[E, V yg\2f42Uޡ{JTDvP+Bε)mRnJ0VaS7y.슷禫-Ebkls*ƉD¸x\:Ve'ebO~"(*0@1 O%R̋[>tQRw,ɇ2@5Xɡj/^=#s1"W|47/ZpljVkX;qfT{]@?ΠhB (݁5 Yv/p*y4ӿI63'xf5?;08 uhgu|7&Νܷve{9ЏqVHk̽!OrdK2-a(2,l-B36XٸPL AԾ4$wK`O*Nph/h~59YA:>V&0}'JЇǸM1K@*?*D\=?4{aeViEf6%K)WT]x TpNYi9۔r}1Fഊ=+2*oTt[,Rɛ*B'V%=zvUݯ}\έIu,%NO]XNp Z2h3NΟ34h">ߞ9<}He&7;rDN#qT82N s+9e@F$b}_z vc۔0~# bhmK.E<پ"1_@zpCۅ1Z6eONDN$'v=@%LeȻ<-]ɞƸ41ҟ6!qy$S|n !CFcWHq) 4V|9^ӥI.m*zļx:L3#gR:w#PwR+ÑK#:MDUO\A XKPqR&;sK\JgI`x"RjVN ~hd%gx&Ub53l{ >l/Aս{{e!r&RAMVijFT#UQAţ@TpqZ F=G'UbC=M\xZIa+i(6J}F%=s*XwZ6z GWL{o7ƨX/fI'ThOx𪄺1Yo }ΗLP'[LBBTxPFjOOkӼ`!b9\(:3\*E8^E-91_.XAU)6I:6m.;M2x:2 ZsdF KV;zGΗۖ=+/ىYn4_S&1e Љ,ƛÜ8lGGW,Tz33 }9,RW;9[:XcWR rj) ȑ١b&Z$O)fpZٰ$ؚK|x;!;2*4i?B|15HĒ>M]†Y UCJӸ|ͧI>O1H!eyRRr][tRSHG GYy@<髡K"+g2\cx6<rYōjSԣ"/G *؇|j  5VxDFdžqYeDl%l~>yhQ̄t. GJhmXʤ=y7Mbˑ:!Q;0 -ءiTYȕOgp3:;(D+ae<CԇKcC\LIy3GJ"xCϩgzZӳ}ZVT=++vWh r2.)H59b* nL߁hh*VԿ6.(Ɏmog079Lקx3Beq!t1Ncaz2XV .ȤaI:GXU@\ډڝbOؐ!ia6ƿ݈XOs?ٛC`$TYMmF0>ct#E,z)? P}AB+neR`f*#6)K[L23EJ^RBy4{Gɡ"XGFUbՓʸUTD,U,[Wap* IhrJr'"C¤|6wRoRоwl^YbƨK6 797T ,WXWk B3 >u)g{bKv_I)< D2&nyMEi=MI̝Z2prz>m%%Rӹ:V+25;ǝ*ƽp0ZG rg=awV~zDs?BR,tIKjfD!`_CoEwEdgrs<{1G:aԉN^px;6Bp?w͟{]plOl$p;*#ri0n%<.)l\Ḟw=~ō愮 G̩HR{0ނ>4\EV18*X34 xeEGص>ͧ]Y<ױvjY7 Naq_JP^jgiP:nDǎbwrwDַڮ'a0 !Z6.@@_lP6pf`ʃi%!A22##^¤~<lw{֏iz?7̎ cmn?GazqDt۽Xd`6!D̓@toɵNf4#~tϯ˟ ?1?~B==-x&kQ!勘/";)ߘܡ ̬"_v(J1Oly~hXkvoؑ3{3:p5–C6,@"0z'I-`v ׮+` g*a2[#q[1K=_ұ(JBgɳ9|\sϔ/%ߓM nW{5L9+\e(+cD7{eh]ΊJ JSuEEF@ 9=;L"!(9ҧ$";dY|-˩"˩tD,g֖A) Jgq4EesgWK9$'v02f/L uvh_Y΀˥X$ʈ}bȺʈ{Vʘ-%|G z_hre%GFTGOw-4F]Oqy\6E$>άq;w fX y]&֚Dńљ;vN?oz^f4xDŽ1 ?vhUߊS4p*>`%MjNb|fZD7 A W d&Alq dNr mP2&9ohȓur?(Uy3"sRLDr [S]DKnQ~Wim }[ȸRF1g1OB[rT4QKyއp^Z.+rr_ºL'lu;$4zǻd /ah-U -vkI4VQ7Wɷ)>i^FO.F3pzJDCM{35=Ď}z iS%t4ב uJ9*X|769Wr0 fa0ƙkg]_kw97ʝ~߼Ptf@?ٸ1bB[3+7Yf51WJqKc@C)EVg^ ]Zyϗ;δLG^|ЁZŭQ"o@W"FҚmfbJ;co-@TKD΍LH e28" $Qtw*- (Fդmf1&r< bP:_,d[n\Hϔw"MrY82hmG|:峷bx<7 66ɣin39P2h{y*noir>EFNEtd?4[f ykszoǁf{_^L0%Zua(t2ǜ.,puV$ )JtJP\:gh_"5?&S2۞$_M壸<uDn١:[p v gL>,aU%\y>Wɯ 6+!^nuF*xPpHDֲvMYޓY+,,L"y.}b7u,`"B.P%nYBuJ8 6e;TJ(}j!FE.R ~"TtH -)Ύ|jm }zds!4X"9|á9,Ï\ӧ: ~s} $Hdh}5cs/wѪ\hmݾeAa&qL333Ō1lYŒ03333f{jǩzgTjRo-I%Yzoֶƾ^cYÍaTK! 95hnM!4dNe\=yS5\Veɉ@+1Hh&i|f#( #-3 ѳ3UCukyN)y-,mXe5 N|wMM:|c8KۇϑlDht qn}ʠK|f׽`<$x1K9#%"K)f֕Kr8i.?n6w` 뎦TMd~툥'AyrA8f@ t1? 1ž wb Z_Be\37JQ`ϕޭe/|+O/Լ/e%)7]N2G/-c[d&{owe\Uʰ2lvjdl EٌtA oK\"S̓2.ٰetI(_dT^ bi&x_*WF5xQb Ņ$c0&ǂ;̷M ڱu=+ !,^0vN|`K gjo_[۩o= A5(M\^H2P~ 9+ۭp; {+=2 ov>[NX7+ qL#U'iQEI;unHd3]5r97EHs*`mڵB]r C}7KPWfjʱZVNJNS0UŦjZWFŌjnP2f ,^IY\B+iOIK9zRnүg~>Lb);h+Kiٱ|= 5D"o9boVre8{~VФV?Jri뛇Wa_js kn0 |xƋ]YϞ~枼k#5k ; VuK1Tqεв` æө_*)DiKdT-SskXwcf+箁 [lh3r~X\3z/!5z|^h[Wn_ս_ƕ+K-M}. :s{y n 3+>yyjNf!tùNyי0.:$`LFCU'՞?\,;sQJV.FkC;G8}_?^cNȉ2lf𵕡W #Ϭܟ6<<ޑVS;-c[ܶ%Q?)n} Ű^,<,(g wDǸ/|sh0Ss첂bLtJi n&RO/eYV U?~cnLpLkrWp 2&lZ~T0s/+YJttP`cVTl-}2qf5k9ǘѼε@\?OL1N\ růᄂcF8vnkl&|QK1GLe +ZhR{,- ]61ɼ11|yC‘lړVlƌOc.4&W;K3X}o >B*&Lk2,[5wAggLԲ̧\5,zPUu_D֯`Ǿ\ʞ7͙Ugow3QR)'tnZgdl1#ݶLN^-LR[^OeS<?ccq+ 0jb+Eg'By#Ne||#'mȭd͗~[FDG$u8X}+J߶7u8L0(LM#4avHҿI&q] *k䥸G~SIlJYY+sT0n],^¯"f/eqӤ|$c\e8e_8@YY2JmXZZՠ*W"I\WRTc'G6Xs/~{ /yj7{9z˒`s+NL`O@FD vCʎ~cF RX$-gH~Sؙ>eFjd6̇n0cqAl̯jrWpD/!ŹBw.uqPGZ ՘ h&f8eM4yagBkKK7f)? "˚ Ί}ft*`X2WR%rBV᪜+yTz|, qkJq\c1U,Mdx:Zt>&H$Т$&1!Sx= jˎXvGOT?ZH mBĊ [6! 8ȪTk~2vLwsr9?^ɶD@Ͷ^ٕU:v }n8+ܮ=)4\א2 neq|E+/ËJʰx.ZNPRr[)f Jq?%AlYL=).-b誤J!WzW!$T_zl`c>[|2XCySxZUnL-6pw,:n'ϖL!և=&OK$ȯnn6Ѣwy)ϝeIqT>a.)4|Ŵl'Ff6pes)֚dEq'\Lv GUgsM=!H{T grZVuC <|pV˅i!W )c ~*Iαq 6~aYƏ21ΕAby0eYuCqX~aĎPF}I`t*D(f}Gdϋu6zdpQ)9*.B˅^{`~N!ɝH:ݭ* ( I?Smx-lВ]-cK}tN<Ԙυ7ɟx`~=wJ*cc&gUtW79{X@Et75;iRC.L)Ňr|#˹=K&y%4QiTUPxPƐs%"dᝑW : Znp}rpGᠲ=/Y, KcDGRJ69i'UсWĵR~I3 i~AP>'a&:2eŖb[M/ ^m"r[09_N\>>~x}=c\B3ЧI<{ =Xd9ȅl >AO8>"e \2 z ,G`}Qk4=\Mt ZfwǗcv!|L l(礤qYN۱]3בuY+,/,}j_O ey'Jg~W_fyFq_QB9/5٭ACݴDժYUve5-AV^)(=<Ɗl6S߅6f0#8uKؒI|1v%(g¸2l{exv0ln.w')ӆ& 0Fd@5YT PJ%+Uqn0w*A^ýl5fFCn9=HؙfRu|fb)ëiTԫt2m:Ri#\(!8\`G=I|7鏄}K$/tiZ{bWg/нnǦ1q&LrG d#hwԐNc2ҵ!ya:m8eIF0Ioʩ)ehV8=>m[gf"uLr|OVѨc MĻxkl0Oeܫ k%gr9+0;xޕ=ܸсGqC6l)l)n~m=T6+>`p5' 8C_4 I\O)g | <.g!9 V\W[AU4< ae]ɂ-cJ 牙_J?3{1eW41\ϵa|>,LKJi_XRFɛKx]< ~3{ -chFd6)k)+jUH.xi9. 6 ۤg kcڳu43='%X+Տ3-+;1M8=(bӗtJ , )bv *kJyſ{ù}%[&ΩXXGie(ILRJΟ *[NE#9*hݰ YOyA2F)O(%U)|A}TR'LQI߻ %I/?" {w}*t?[(Z]6jlUJ4TyFZ*+Big9 ?j8c_j~7 6$RiDS1ab XcW|0/ƌƼ7Ͱ{D,O 0c q΍"8;a7#4rQwxx1D*\xjf;'-["9(q|i$w'=%N+O wg̷$QSJř\n;wpe%vk&! BOG:bv#Fu=6h]x,gSq4Mbq4wz}ey5FH[2H)[Tѿgَziғ؀L.wN@6'%e0{ ёԽN뽱%wTT3d T}c*mUSMl{y%+9d/GbRlx)EeYO,)$'_WIQl:'g,$pTXM g(4O}] 8>. AY@<$Ι@ô*N*:f*?oUcT͒K:>MױtO98QͫZ XZ"/q#標XFG?) ' 38>u}LPndm{`Od$OCifzr ı9=܁9Öi$-vddW;~V9ʶ艴OB?xeh8餝 ?ދla#L+[Va+s-~>nKJwϮs=ZSJx\Mt= |;LU&^HM0ZJthnkNO<)$6:jB!!E>n(y{+\͑̾pO"P 6RaZx~QMB Ùjdoլ[䲝K匜$@ܧ|5yJV/ZAIىjPԲ= ZX=R΃rK,v`p%?~4(y9cDnn {_T*LQacUB^54>YWjv1Wb59BkW4@bmXe%w('S);s1I&֛Ⱥ~Dt[v'|b Z7=7ݝHb[/UB3# H<{1CM62wଋ cM;HKU,؞Y \F(+x/aEW6")7]8MdY# #W*Yמ>^$eRv-)?e<bFն\Ǖ<3Փ\k)}qiNin;sx˃B7̾7Z,w n- NY#>MZV>bo\ԡc6 VhkS5,VFˁT-hizAu#6KOfL,ff@"Ē1!bіړh92ljgOcA?Kώ 2+ڰR%'1YRC"n6DY12D.eågϾfH;1,UG7) Jeݓ/[XoJ'kcd^L11%Wdz}=7ɛo=yΚqSs=^fn&ض_oXkLsʢl a;2ÎP(ۺwgq5X;At2$r2KY2~\[FueUBե$;Jr_5u䭭U4CRt [<qM`̥PKY8`4! << PG-6*D"ӕIHFrKl‹+f5C+cm=ڿ߸zٍ} ͖ONX׎,uFZU|krt@}X1򴘥{B(S>3L';RΥqZ} YK'd;y:G}rf yӰz^×:k몡qZZ׫m-tO ѿTNTqhNJfWq!HOS-f!2*1ְZjyvZ/ѢiSEԑ|Yª4>iyuLn\@0|5:ڃMY-V,8L<h/u ٝLF[i%^EdJg27xΘwOdz|?ƳQW b0=鬈fOR'Z2Ґf58;q"}+ccy9h%%\KppP𲏳8q}ϸGWw[tLBա8J^VZf0{P0?dY s%0&B$ !4> pgԩr:ݓSgև9dR5\T d5ut0 jaS~5{:Qqq涎Q$)ҪXhG%ߔaJ~T섊sմaسQ!rzEٲvP-򅷛V{-t\K9-sr%,g@Y߽RsaҠo(s`AjDff1v-o:f=%?&F>XUҪ9~3ѫ?׾NX|].n[cke Nf^-Աrqj)sVjj je ZM/-jH]boZN8, ^)آa:5?ah3|UdN (%&qx^$HZWҳ51*jv-5\zP-7_})le Y kF(Gn%Mtm]F_ rb8Xs^tzsh_ȍ, "f0^/q)Q8XLf;EO zugsv%z9ŋ P"nS8 ӣ ٗKeމtr璕5wgsםnخŒrFjNJ0I`6[_3o 6ofeyLa~ZLdNMlsWJV@k6D;G\‡6S[2*vAu0J1n$~e{AϕrFF^{s͔aXM5":}kHC8GQkp5ۻi[6:\QfU+:%󃫸*kR=[ˣU x> 9D B1U%aY۟#wf"][HƇ8EqnMxkDH-,L R|\+oq8~Y{R^F^F2iblΜ!d`.ٗn=G6l;pDZ4a[a(]:?]>4X7o ј2Q>:(7cm}bE(~yD>WBͅ J LU:}9L8 ƯNFR;Ear/616Ҏ7e߅<Pk$ۯYVo`<'8{ ٕĭPawb9Ti%Ap5?=h4p '܍˂9CKyr g穯tvT0vq^rZkv* u7P}X Do#znR+1S-UhaUz:tbZJ"t8Oo;֍FKÅteByk%&ǻWs;r sJB>%Hn #K9"ѕf*8g/e2Ff3QtnGS:Л6S)ip9#AGh!|e T;hMok_ t ]J]Gb"D/hf/,tq%,—:Ð=H"4h6%pD*>sOn2]メkx1SiKJ3q&\i0ts{ 7e2k\ɦF'Ft gZ$Cx;ɍ&y<4K ɟs|{LcW6b,-l^]JflNbVח茊#%*lTp 񩑊mrg4+<-fa5CTTqdQ9ܔj,'Orx>Ppw̫vKNtf˾dvΖK< [v fnAyPF\?k8op7IJ-0lӍ2{sjWuē'~Hs?^>ƌ8H6y<9׏ dNtk>瘣jeЁy~Ntq1:7:LKQlŁm(Z{Uu5k6|,}۞XgVXj BhG.O:$:"y;'sa4sl8M+ni{UpᶚzǨZEFi[J/uə6Tƕu25Vrǖ$Paÿm~ڋ-g"mꋖ6,SYS8>Juo]pg;x34*~ QLn_݌ UScRRgK4HQFA'v4. cms/ga#l7sed d`IZ#7FuEstC p c>ؓ3L?͇׳+WAh_ҷ,i %#4dEY:mJ?Nd`}ծ3Mo6&$$9u´ VׅszJݳuqᰥŴ~GOB-JM=isYg#gO R28Ƈc>@G"O v-wVh|̔ަ,qϡg.d˽t'3EJ"e]ei">o/ zX(+8ZTRnKy رjq#W'sRJ'hYɢKWG8&Ǥ.╣/Ǻ3+ }H)XLCJ()$y+d,d):ZWc;\C~ݮ0],UjGp0e{^h&eƏrfI5f^<9ƺQFc0?EHfy p2u!;GY9܅&NgU_<3.q|ʯ~)Dt$ߟԁvݎGዄcY¸qºUq7 Sc' &ˆG[e{xQC {e U O\v'n\_,wnfo3t^R@ \):s W{Ȏ8lNJ8p4R -G2 &#h%,/4.>0$n=0k8 A;NM;yj1IwG^KuOxfo#Q?bKd#+خXu4x=vC-Uu;EG?[\^,?EGKxrY6fb>&yGچ7["d0)i3wW2CkݢR2W搻! Do>Vr+p4M2)J)nsqB9Y ZP]u-1TKNL0x$qc0 OX94Ay̓n9"{7ˁxOܢ`6 7rk&}@>dL-Gz{]~ތ1K4.IDG:pBog}-݋4z6g]'xn;&̻=ckrYvy0{i}0:q3(úY9rWI,Nga%/0?><+ }#NTLe[s.8wbh0^5Is%=5Z(=#Jf " '%SS_;gCYӇۯe! ntJbMN,e -e,AՒ!T@Cr9K<%##igYF`#P|LסX,H-Ϸ3`8 XS¢;jg۫#]W|S^81Zsߞؖhn47g[WxIh<~e;֎AjUY8Bmo8HY/\ən >aXPZD1I~|JWc/:aIJ݌ÓЦ͋8Ѫet:PAA5u5(OgZ(dٴC=J b)jƛQ|I%ٟͽ:=o[8ϖ  KS9qy&Ze]Gb}I7bav;%]YSs+C^`BZMMwˋ޴I==mp<}7{7_ʐh񢹋 ;3|#ZZr`Otٞ϶p'O`ޟCmPwB|Sze,Ua׸ Ɖ vس7SJdO{\qy}%{j0?jV0NdH KbYr5>!xÂI>Ɠ1tCe^趦s8?JW/+yTW͗=[SWe$N|X:>ƒ|;XIFTEoFq雷C&R/ɭ'Ƀ5Ok^W`fZL.<(I &XZ?OS}=I=7QBKgUyPşhQŰ_n4H+~F2 &xY jv4ݪYvv,YDzw5cص/f ''|rÚ7\IXϒ`0b59v>WpmK钮X({]ګlzl8!wb~1ˇ0kSz|'ι,:G~Ժ3Xr|d"p+\-ˡE=EMp |سޔiFh-q&Ɣ_l'k+QDFcwRIϔ4CS)56:9;v~ f\ Օ{.ㄩ"&WB'UpXپYj"p-bMV)pex]T? "/'.1xfEt֛"l7%~c95jLTcU1T Tq[lL򳖬{01S{wY_9mHZ(_X,>{`\~rWVq-_9erҥCVy],6zgdv<|P55F/|mhӓ{sdMD /A=r 7rؚ1]͹k͗>i|VAc2\7' 3SN7rMt\L[*15\W}EEY|-dHrUqԿSH5xaacN$ _F=_W>o+')ΗxG1qU f˅=(äUbqQg vU2`X:.f_XZ>/A\SROeSt? 76ߚyљEQ5 ;UF^9}|IuIOkKϽʥц5ˆ )ktzWE` iʜJ'tN;#~׏1xƝ7#]۝R;2*?6Y`9&jɽ/8nJ!MǑoZ0!PIfԛor7TqO.CJ"xOȼF$̬DUXAFO&xw)zA|'IƫeK'dw?܇m^mrY @o;N^/џ-Wh"+'{\ȟ&la; : */xi<×=yŕŎT$>_q 'cRݭկ<(roeBW'/%5vv8r9΁INzD`3f`8ލSÑ+L^yq13KYZyUn3N33;{+2jǴ'\|ǂꑬ\PFѡ T>1F1O &%VX_3&{{1]0߷}^M*3Smb"Qӝl(rȾFrm " 0~/iQ6JQ퇯U6Iz?6舂ٿMzZSȅmr[*ر'ȍ!n%SEhfr2t2WZv!;jXtbb--W^$;İE9_Wy ;+Z[ɇԜΥHu#6}(š<MJ4͍3y |:VQc4-shNc)}J|H:XDN:8G ,.3NE1mPmgsUfDS6a8ޚf~#(PЧuGL8ΫzͰCjdk)dnS݌pH|̟18mA",u]df g%p} .q;6nʝepQ'5Ɲ#8Wϟ>L2 aL.吷2eh :S"!6@7U4zPi~n鳣y>G`8HϚ¤PbVEQr;_z Y1|z8 gINR͈utd} _cmkak:bz!_f\lh9Ŋ7JVWWȉ'NOMVۨ&葬gqIMn<8EZ`̤Ld}$A+y\?M0Vh':rS݊[aQ+Yoe% *KZJ(g^`LV9j[»1Yi|?m饣C94`G.>8L .6=ҙ;3[ɞ~ZĦsb 1W(.AJ:'h=>(~px MX9/yox; .4%rg'yWN! -W^f)C]V Ȭ;kFFU}{ @}6O : 6CbZM8Ge@ӌiEn$ɡqP&!dd1l;;5-qE ^gn.g'_MaQ*+%/Em} 6*O=q\nVɴ?b9p i!/8mzyΥu"[[^ 7c :s"ˋsƇ94.45rTdZUhs^3XjʐfȓxwكmgBQIF|MYBB4vq$Iv䫹ooC87CxֳcnքhI1H^ vW8VZH!ޝeUh2A^VpR~;vg bP%ZʄJˈdRW%AǙQ[en҅\V}U~I?ŬwԗӬ5Vs'c_P~0KwpHѓ eo^u2ۄViϲv,kK@"zͦpp ՟,e~O̫IOr&-X3LUf4dȞjܽمMX9]Պ\={٣-_ f4(Z*3KN)u)}m]ʥVdw㚠9T. .w&輗#Du6QZ/0se<Ͱԗ|{ W_~77v%=̞efMt_*KNBw,YM5"Ғ^bl[] !s* z?djmom׆Z#楋RzrkyaEѡ!i#i~Ź:Ůq E;AS-f,i+쯑!'ˌٛU>yCޙ&rҎ$>>cO}r{+)T2|wzRO#+ls}6(pKԺ vnƺD.۷ *T Pd]-`¿沢Կ}oQH1N]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9pbJ4]o&x"Mgl 8FEj!CI߹VʏLQVS*kdφ#{_HOZI;)"k+|3Kޤ?%7sOKuAػ+៌5A$W:tTLNqӒ'&>'@^1y׻rlW_r폦Q>nkFߖXLu[s4P|i0SjLW:].0U'T^>D=oS<)oܠ3L{|,9ȥOlwxʥ'_O/.?/6Aj% TK61lqv=I]ex,]%xy@je29lߘ3s-_3\sA@ck"rORyOF yʫVL΅TvI[OrMsWzINh/}vyu{򗢟 Mqyܞ'Yk(?ԔhM=Fy#1o]O jA}Ǽɐg%/K>^qIνY*)5(a"ikLe=+>hyȩ/3sS`3,[=i͙.hx Q>i-z]Y@pڿBs/Iӕwɻݔgzݓ%8 /)ӗF,8eh<`z@o5[Cuvv%V ;֘]T`ŜDf/Z_p:gAZ`h`v}kC7}ݛFG/Yh#7vkW0X jC?ޟ/|=_8kUۚ!Q=[>{n_II=OwJ6(Tc{| ˰4w~<7>fL5v`OM`eavL-2h}ubs& .9/Q6?^0ܼ/c>+I.-єM[-WqІ7ʶzǝ$ĵM&.?mv>gz,:sBo4Qoȕ1<͗8 \=v\`Mz>U}-hI~_tB~05Ñ y}( ;`=rM^Cp߯ۦ|򦮾z%Z}3!});ʾM9r`Sj"5qJ܏q߼7aUrZMk.kDۇAd筋|]Ij_ dGn$`p5A|8v:k }3;Ɉc4Vd>U%`Lyswjo8S#Ң/Vg:Y=l{`,;2qA 6 6SvPOEB?^8q#=x۝{{fB;> lj>ܑÙ/ u7*h\GTG:ǐ6ę(?ýc`b{‘shC'FȚמq'/Xw[(|7ӓ,mTy-yB!y~͞I[:JS%m?pkscXǣ~\]b 8Ռ ?)鰼v/3Gsr (:FչlЗl 82q?^XaJ-F,s}|J妑4#\xw1S#zӽp2YG\Iv4 Cr6wM+{`k6:UyQ2w NγcHWH%]"%'T4{{Uet }')=ϑ6X'̉O U zl~8+:,gy^rՓ U{ _tĻƋ^cKܸ򹦚K|D-CP,qf~-v\8;\%iNWi 9͉Bz44vaZ?W{07'Wz[:sCX0؀meJP|)RJE=pu'=Fc6NY,DE݁e+J em By5.Nt/ SuDewa皹ᬭ`.ur&€Y8H'E~.[E>i5g!>Lf_G3-ϝ/&6LRSrІ/ ҕK9Wg(Z]y@7JZ_M8U~R?Ƅ`4+ FYz3~xQ'S<`5IŻ MMC3HޏKa(4Jm[LųA0m 9zRoċidJLؕCJ6aXA.[jλ.4Ù}Т?^0; }qZ˓NPdLkYѹMuéo^B_#qMd;;+ 1VNec?,HFˢpLWq Ca|MϦcdcf~E<ޏQL8ȝ-V\ɠ3]x|w-Rv9DDc[6Xr5kqMq4y4O89P/:3"(LG>y9PZG;rڅ#h$eRo!`+ gE:KZJF*fW3/&g;-yFb9Wy8ћxOxb*W&]cx8E3~hJo;_Qu"P THBNZ!>}QUr')|aS wB"}p:GUP bV8uY)0@޷%&Y:ECeKUJ5磡4:MI*WS[bj?Ӡkŋ>Sm5ɞ_LFPdF6|l ŭ盇 r/%gc7~ʘ+%4[qv%6]-!ߖޒXekyKP .~QڇgΥh:a_F dg'\]#E<^ "c#ROUp 2άNez~tf!y0OkroC)+Vgf͓IZ<9b"WzH`Vx2~--p`s~8PcOl <=hzkv2'Jwb\$= S,Vb-/}'qQ8^(JOS*Vaq_Hþs8c̙`gDVK|)p%v 6>p\D̔Xd!M\X ='~9,tJQqҋ8_0s?Y1[ig;1iBɦLwK:8-ԋ/"x<cHUH+Rdfc'KY5#3/ZQq?ÙУX57(΅:P2&c C,$:҆  _vAYeEfZf4`LD<``fC.F)$R#h9)tލŚ(cs)Fnɾp51LU~/LBԒ8_^ C LC|(aB:5Vۡ$#9Qp۱L(eW6v $)_{$}K0Tʍ#%\C)l bˀ4CisC<Z -ֵ2bGҳ>e^ɟy~rk) @$E&~pYEsJ5)"uKbnִ)wՄ.3 4وCmXrgui-ϼ4Gq!#˃(,0YcѬ\I1n|ݿg_?w h$1l<ȉ:c.l~v/vEC=gi]eNFL8>4%sONmeHw eP <1{C-7f}Tdrb!slٺ$F:LPVnN&yNxtTLCD+3țgt\aP]'a G7px}8+'Ep''hJ@&4t㘖-"au|(X@m>8dg>236s3"(, gDfd#7餟NHsB06d|IG0xs9*КdI+2d2| Wms5mpe5ңJjWI53 kܨ;3X-Nc=;~%ڱ%]4 'L\O6+2Vcc.*ӓQLTV6&sq>XlslkS𦼥I4y‡h6p.b,S5>>Y.tP$҃qԿæd/~䨺#*Z+odYK-2R՚ =ʆ~4jΎm1d*LUo\8~Ɩ~]Xy;(Lz~ 7\ʍή aŻ<#a~$[Cއ!)qdN='U{ذȏ-q?`\s)X~Au٢H/f`Ehh+/GC/ٕ+_ {FN4mI SDwĢ4l`ym y͗rE?Cʡ4Zg-S= ŠB<;֗( Jv{,. L?ccw[?яv$c~JB$2ϥ?u [)3??`ybU4Фz Xu<cso\m>0NtL*n0z#|FeXʓh6 wSA5:vڐfS_Kz?mN'<2..Š6Z3CsOv qa2GǛpc\;@Wd\}79QPWd}_xs5ȋ=OV^wWEqQ>{s'm hDkOU3y-y?[GLV)=YK4_PIgTCXVҦ:,Ƿ2Kzoȥt>p lS;Mi iIz_w[SBEx$7fxAB _wSk v^uJR%iHu wwpX8, 122RIg>YpI;?>ǶpC0茾›)G#,F1e dn!H؇ >@5sMBYC̪mlߞXx\ڦemtt)Jdѿ+RpZMtE$\|0lgSn'43)S:0\ʔ "o(.(th11`Hvt.b#ԝ](pPڟx:=6Cؿm"N 2Uq4sXEIZil(tu [̟>|_T+Ex/妛 ƛOq]&yyD7/7:!$=E=0C~C/.I;~g+mA+ Z:2-`Ec8d҆ ffHF[0$̒c3'e^8ER ȎG =^M&2o fQX[5s^ڑqŵ+ zJ*~%HcRj'ULҗ{PƜ` jq^-jYѿUlzށs28w;S|։7?&ޑXk_ #8#+< m$_t^ud_B ͜¿gZuv=kZmCa tVg1J>E~>+aVTM"\"IAqvJų?oD~MxrPZa2&m 敖k%bq!@R`dG_F`.d2ReɡOڲ8C>,ܓ?M6r4g|E_NӂIr+%囚 4; |+ҒCzSr)@c/?0h3q#bmHZjƉ9)sdv8fI=ק :i 9` /vj'F׵f-[;>_Zw,XviKV+;P2f>|)A[9c HqaeH 1tܢ#Dqi8ΖAt%%/(8sWƝ>׌8^4dLNRVxh[P̌14MFk>MÁ&g lp5WG*% S95>S0aN+8g{0l`vZk8Eå*vVPK(W=9E;Lp.)$DrM\-Aʴ'}i;6wu_˜TK ѯ3V_kpzi<)^y5BSIhotgٵ~0ke ;Ns4gzrޚ.Frande3BG,!i"SPִǵ!ȹ O?O]Of\tȤLdKi8XC5mFhX_C@:#SIk1gyC9 a%5-ľuʇ# Lp^e4 Hd#҇0(=tH̑i]RnZ WKD"VbB^8/1!録el*re6$Pk ٓ6/\݁c u"c#s13F&=ʞ]sOqV,E"yѕk&byj,y7ޖ&5ojW ``j ~v\#u$u8$O"0aE>X 2l ֞}}icۓ8g=֯MbԖbju.EZ?9#Π\t ?e3ٔP^мy"{5!Ar7]b{_%^<8w=ԕ66\nI Yĝ%扷8h`1 RϺ\=hjc` {z 912ԈjC ^J~VU-)͠&܉mY͞h1ݜu⚭&Q,=haEϻMp2Yh:%dܴV?;i}ɩLa.C~/g|G)Ufu37]&˰nQ%tkD.,rd5žʂf$"Ѐr>1a]C-odSsJX5i8gMފ(/ ,Пt pcYy ͱ"VN<:I90ޛ7n4nBPZJML~d1A&cpNG;^ta;Dʻqn.'ʇ}]4=E.Lx%60㣁M]cF#^Ni k;Wj-#: tq4 &4vJ7ѱ_騾_zk=h9%U-3kPEy|9"a@T)Ռ *cV@oK1$ìӈӃ5m WcUNπRһ(0po:F1{R2kdwωўX?go&$\J*n25øψ\KJ/9iɕ\+nC]I5Qc%|dzo%_X9+(_—/R֖pX]BvJ‹8mhC3٪˧ZtksQ K%=+ J ]dMikJ|kd&m9:jkuӚr؉GdOL.43 =`n::VǦO!ZKJn/&\HdžHN B~ضMq.5 $?0hK.Osuy['Qnhj>\ ,&\ Q@ ƭ{#)\e!'BZJk%S*BbȴP$=dв&4q9f"YbLNOQ<ȳgw8Zȝh(`{ u<ZyM Kq,OƔҼfKyGr&,FFl2i*b8)u~ʙPRJ֥H+ %+9cO) O)PJ>9g(iz^E JMr(%u 4|ױWkd-Us&u5Y7#F,lQRXĞ ^7('bܷ줎W 5( t}XԸos]B9NT-!˧A>֗QQ%I wJg@+8Õ;s*vw8a?ǶaWi{ 6G'(ӃaO`,J$a1:CH uh("e5 j^N4E܇Lje5`7Tgi/2ꑝPaAwGǟ :A{L٪Lkr,0,e3R6c5%+O6kD7χne}(5Yy<]='X Rz9I>adO(]%WK) ܷc# 9^̝ o~l{E$8I6_E)\8WyUHF͟2FW?T:wOEM5Eh䥚We{m- '5#ǂB.UP~7t7(ۄ$͜˼jkWC#hWbSFb 8FO^=ZOe=m|u7\ueJxSJf+夫&g9{~.*S2'DbzGWW F̺Bǎ~!Z%])5C1q",7InĒ76$Oe ]dJd')ɬm͖^8EoZdARU0=Aif2reۿXboX$HYcgw3 70`dQ%ä2'~^{Etwk88HC1C/g yvTG՘/h(3`Qg|IBdF"h~Gڻsv?kFMR6ZX" )ldOU+zkx`ͩtgg7.ƸuysǤ3sɿҰlIRlnf{.p ڧz7z)+J ]i}% ky2l oe9yfRU{o=˹Ĵ&v:9a4\94CS,EtzLM#ay:N?)؋7vWx1ViL\ĈlV;KXd{%G m"< pAut`#KhlR_]%iI`B/,:z._Ax|(gJT-+ě|aDH'} yglwL4n0z^#J͔wJ6WrHߣXOKEc5>R٦U$PĖALח=vX8{m:zGbO=V ՙVF9aW;Y38)?* &lK8ފZqѺ?-w8(/g81[Ch-K)@pWfmdȚs*5Ln'piYVp]M^k#rR~j# tqJ^FŸ:n40DP#M>QΥ>f7a'>Nz-2%=g0mR?J$\?z1r2]|\dU4nJ|A1z9% iXYx:W> W[SN=QEGtG9\$lbg\?|.H d>`4^~KTUD~4F3x-RnZ(ՋL-8E4<ѕ|:fw L,Y]: 3?V *#`K^9cofĹ^&M 1gE:3乞1u<#3MO3痚ϻZʃ(%3j@TiiI,-N$O#K߇1d~xaǘ? YFi:aȂqVHTZu;KXӄG6C8Z3ni|SPNƎlx4?^z9mű<#c$r?m&ŕfWEQi^"'Y>!fJž)}:Fxɟof#'(68܃F^-Fbȱ2#L{i'#)[(\H"`} yI`O$J2/g(b ߤD#&+bY;H*[!ەx/~ K&[b<-|R虃,Es#X2AhY<ųJ:{X#Mӣl2Y>M n+[.ڈs{laUe$1V~/=5GD\qzZ0C✝ۈgjT^7jf\׌eZ<f7am=[hNCj4dzDMug얨#z"-Z)qTs\""/g3HN`~p-a1V ǐT z[˸íqks-y=q/iBIݑLNcN*ͣp~L@zGLb\9ȧ 5ߵžK3KCoob6\9{r^Sf9cfp6TQSd oG s5`K#Z( qVTA9qde F]Z` ΓԬ2Hi &n9nB=L]fc`bxS񯘣73%RHj.aj%#UGx,}Ƞlz}Hcq{1<(+IBN-d,Y^q+cR>r@!,CCOUFCZUI/g6 |c$!2[=Un]B)kPbo7TwVyuL*c\Ƈ撵N1V5UD9 b5UC٬E/Nszj/F6?*x5M<Z]5 ub,.#q„:0Gɔ6*`@U)Iډ7EKA$M«?VrF5׆k-YÒƳ1׵T[{b*{E9Z+h-q(jT<0>'癹Sεrjj95+߻;-*YCt ]`B37EjSA܃r~7񲙙+[ٿwb&ᗨ',Q2p(X̲,UE>%)eU=B* J3}B9JRR><-!m 7) pvh!vfp "Icuy'PcA,ml4qH$ѣt[L~K"OXRϜŇY.dc8,6`ZKa3%/H]vN #VM 222:qE\؎d̨?-^fV}4rpbvUr!CO#-Q0-~rwNsnk Ojg})rǢ/,f{7boTq,yd`(k)3%H}|_1Y5z6)26^BUxlڴ03c@l^bϔhUeѲ朖gT CJNbRm.ށzS7ɓy .,hTz^|3R}aNW%8v,G_hf]%_V⍉3>Zi`9oo_\K?\Κ ])g AY+3zStn(*'[%rB \;eNX%S1TZLb=cG-z;'혙Z<o㾂yGXJSR%GĦlp^K% $ko%sV}5(΄t3ͨMXi9-D<[Lf͗>Ntjwx)џRZNeGKoN0j~`D>[]P_,s)Xf!_SyEȠEnM~w TߙUv +$?]旎m٪FN}Ym<ӲUWʔ켋>.l_R.uv12V#j=+TPcy#:6'CRX 9ZlW(XC@CcIE6cY،ͬ;?E_p]siCǚF^Y-ݯlXȳl_%墋1ƀtGh㒞W:"t woT]=7 L'.*>UGX VY)y,%OÕ8t)RPg8?,=lTY9+=^JKq}N>\W~Qu\<'ZW q^̢r»XVC}[uDɱIX&q{"}uiGJJ6W> g%PNgqTF7g64OѝM/]Cmh=#Gq5uny/,1YҖ=5ȉ͏}<7" yc:_?E40iDLR9lw4]!TLEsӓ}y|O!_֪݅XLabXj7JcӸNG)2gR$T$g3~9oXf\L0"UC`A)y) v.SGMtP^1険^,w[c*|Wŋsi&}*(c9z|FS~O}Bf3'%cѼM*2yLʦF o7BKb`Ӝ ,kj2OY@j[O0cj9k)rwV:jNJZ/_>bc:1gɨCzr)IWjst ,2Ct_+jS2u k|+'-;=p/5gz*ht@馒4Ye_r^4ĹاdP|'1%+boxdPsƽu¦} 8y1kڶ/]*Yg̜i$ R(cCY΁a0o&_ݎ2Vr` $< }!!o|1HAQoF 2W=-{]^ԮrzʃaV_`>"% FLl}~T*H A(g_ka&%SϦb{+\4i`_z6N#kYO2=sLT3 ?ѽ0oY}(CQ!fETFq)۔m;Z liݑE6Ys4e;ӝDvnQH{5֧f O۹jfT:A2ZkIRU#k&:R&ɹVƴAr?Y°RBqx GWc{%)!Fx5-b/SrA✚?5l9:ԡ{J;]Zj>he?5+˸$x<Ǟ(bE>|E#==qC]6q֔K6"kL^˳9U0|~4Mn4gG<^&9+dKO|`>ǿyч>T"H nÄMm~?X:X.>LܞB7o\‰͚1b>я:hv]?j%oI!Žkŀ̼y\UI1LX13xm'0ymyb1LE\3#N* q${:V|<&u"]Ӑ5>Gc]½g&%ۅyM vd_'n:Dl@zrToOShV3.SA_bJR1[UT:PâRe0bW&<9cHh!8vTAə1*.45`FMjy3GEO*&RF#_=u*)Lť+c-t<ޤ~5EgJjUȝv<<{nq<KMGvV?-hpS(gC;Vk,̯`KJz/GL'#D~ !L[-\V_`wFqw86(BX9؟nɘj$id+i]K1RN"Է.<ɟkYDŽ kv nSx0,k2O^\~,jݷMXӮ9τg Û36i2k㦑>ZBzXwR`]jJhHA ?`*e&)()gRNHNzo}`5f%ԩeaSDQkO4Wעr. 5MhW1w -3z"*X)7%Uܘu(GKP TxFb*pV+ ~Ր[gpQ6Y*¢M߄] QRGk"!2̓pu_%JYXOF,gm*e]}VT)r\)0%%" sGJV7%ĜoLCCjQrLTOyjݡ2|2V3]0K6gRl7)_ū2f #~E:9Y%ıae,$MC|ɣ 4>#'XqK3y3~mv#Eox̨&n6Pˌθ2o|6Vǂ= Q,H wh؎lIs_g=bP7fơ[!p.ǓxkN^dA>ݘFա-%മuw5w~FYxG O3 zI]޼NљwY1R& SXWq1sji3C;$y6j$h T2r ͸*E60rD-6Q˄m-/rC r Z =HhH·Bѣv0|ޏy>kU:}B0>!֜_[%%BPVO\Ur?}V|2m^6 FYCΉ%ﵰE'Csf+Ң3>p>k5niB/<˿=$c}.JЪe\<bn.E]؛CWKȼFk&f1e5%2K Z]BΒOJ>ߋULm~)A"+ CL}]\x`rb}ÎLşA u{OJB\x͝ݨeఱ&9!ۯEJ!/gVa4\YUYEF5#fSxUsM>E{w4a 9TMXltΒ_ 2ucXl4+Dzoha;כcT$UD`}4N:Z'tJhxVȼTBd˜]њ_PкӟkŲI]E(zSj"pDxh2wSfk+K8Ӟo) s|gV`3GVٰn3'#0ʸR>Y)1\%J,G{isZD[+) PrP2\*((Pes}NTl9%:UI;2i4+ MOikFqAzV V!0O:S1pqqƺ9%f0tjGyNY~8lHhX͡}#$ ,&dI5ۦ=/ Mh@$ш\{T'e7Ӥ_B2bzQF\Jnp@ɛP6'&yq' (+iRͅ XÜWJZ_j>y`*OlIY q=4礣[z 5sܰ?=d=iՋCw'c KeZUSX5mӵٿZ( l:sc9:e )C&3fz}L>!s|{pt=aX/.4&zKze~j aS၉\<XuU]!zl=hS:]s|8!V/͓ (gJ R BQ\-sR2KuRU9Y_e,/e\1Q/S*'{Ŀ==W%[\BC]"i8AXo~\8?0v;Q?kt. sC_iDo22z.xWKj+*١Ϡ&a9ĞEF,KY3Z:9c-)~ĔBXl TXUӜڮL1J?[J6iOSgآ7D2.Kq3{\rs+sKhR6D+zd`d:Ό`Aٹt(y#F$jDa V+Hqfk7峩frV>QPEVA%eԽR0TQ8&WaϺfȽJ]XFG)dQpCWRHs鹌 9! ƛK*g^N"kXjgG8>>S9nFkfҞ ؓ LJCBTB%LbTJec6^d\59L*崛$^t[ 7%" kw GY9i2 5g%\ȥtx.go4Ѻ ﱹTaZ s sv :oMc[:)Le?KJ)*!b1Cb93Nӓxdĵ7/Ic'xy{7Ȇi'gy%5YWIҶJΊ,Wʸ<:Y1.38V8daGw!gK12X K테[ +٦cZ9ΕyC9+*Q$S2 ֕a Jds}S4E+mXCt:/Um3x, qi6-3IDO`8c'e|h"?$Q4)z9*aELdcz84wK_us[sbf<'KkxE1=Io6esZ&Of|E!hµ;ר0.`h~'[7+psp!m}Snw[3εhTo%gΗ7{TɋmUhPƕ;출̩xF3vd] svtG+j^t6s,$)a֜%g]DfGFy1nT,oD͓ONն8ڄ<$_gs2(rF0ot>c-˅/{yW/o{ /:eK}kx487]Ogu qF\bS1,!fCT*6῕X(mTRzIɉrFݒҩG*XavLLE>|P]ad'$#s.;Ce3 8\vm)>,Rr䗳U\r+Y%2{T,u! TʯXqݿKX]]1Nñ4JYMQ"#d#-MDig%l.D$* \HdXFeUk#)wL:vS&h@ %;}x|&x*Z1$źuNaT"_jD&,dB1W͊λ?V' {GF9+jwJ}I!;qjx.!x1xO QV[E]5OTT }+i_IjeyF؝H2lϔv-jOǜw¸g㙹Ljgmȏvdc#j|[8DSt0ej+vⱑ7j#s!cJf_V>%|"} y_NaL+!4~͢PO/N /Eq^N(M s#c~鱮8ej~„g\I7Diʢ(2Ǧ( K$#jJN\WVR+J\4O|T)C Y*at,J1w::H9fCC*ɑ1]ӏ'PéBF&q\!s sF%(ќ`81S`oLJ[Er{IT⟥D9!En'K8'65+w4YW0bh:/$-/[AZdfC4&W$X""zH_Ja~&SDCos /I .*)LFk2+RǻYqd(n!ԭ9/菼$h7  IkzK=7 aI;gµ)ko ? w|&3 &M,*ܮ܊J 6* ^K]:vwB8gm'stdzikjDN?kN;Q~ɏ}Rq㦶-Φ dk(pTgDs|LBbP o'sLJaTV&'I61 YT#yZ6SŠI..;2u[p|[g.DJIEw}F 6OB"2-R?Wan (FeK wordO-j95\(bS 4h(mƣ洷e4Q"Ա@Kc]Nl;md&D,KfgwI5*hO*lҤ]&qb!aY{R tm+d\h>i*6uҞlȪᨵ;>{1f'=X1Wn A> L3KhoόE2)Ad)nbؿ#b&zpCDc)wV^2~dc/ ahQsٿԛ 0%rpvEr@F.4Po nih8C#q+VH$zp| oa3Vp0=]3yJxaP-.)<#v9]L/!{tfu%;h5Δ{ pOV; FWP;9lGz\Z*h3ԀrՠXÍjLkֺjyзVLY=sy+~fln"wV-;b!LS΂gp`f`c-F;Y0؇{2Pv/cT*|^.2xZ%<ZFƕ|Vj sTŤ1_0O:<(8xuP&%T'whL:deɺ-~G8.Nq0Anʵ8"qelUe'c\)']gMTmkZb_'$,\e^M.mIx mDݱ?i_+ʑˡE2RP`ϗ9yZ!k/)cb?4Р`yG؅ܜ9^x5- DVބPƛ^LA;m gˊ@h!n/fhD2lP4QI^FQ0Nd[0=o1n|$ŖPy4c.sش{J"bSfYy}9?DT9g6FXhy 4+O9_]̥JzVӬ[5eaՄeȭ:2ֱ63jӬa:|aJ79v͞.n͎N)fZRyHG/qDbd'BGc9+:ӥ`#}ezrF/*hD9jwhUI,YDC|Cat&^f̀i SY艷df~Bk0n3 6G<$ _;:w ;FS i6lk:B3;z1x(cF?2 h#e@RƔ1쨌T|XL-cAhdB/*YX'CLٚy55 7W`}2w-KTp+܍ k#(JRfr!{za2]BN6"_RFmwVh]yC1~ʸtNF.rFtV:=e*DW:&(`ߞ7Z^eZd @_eGS=28;NF2`K8z[ܗ3&>_[?Fᅘm.'X= Y܀%,K~Mrȥ9<4 Ef5[u7!溰rs)'6t{0=|ytrPM۵D4koZoJhiF`@TU(_Mc!v N.bEM({[r1ۿL,sf1tdu:ES2.oIm9עۚ6Ku%*l3Wqڪͱ17f"1,[:z X?f*W>gzVa_օVqd'?4eEI7- ʷzӬDnrA+ 0?*81g82z2PRڦ%rJܩgT%k,pZk)cXGg>Ðm0aovɔt1Nz5#+EW??񌛑ֺ".,b"6˧t5pvwQT)z;˘7E}Ȉ n.QKCE6 lϐL ȎbO/?tpTRӋ"q79cYȔVfŲO C:monv3+t1iR/^vml~:Ċ)%L2 Ңm bg@_qhSa5m$>>)d}T8\wKXHpyG0YXh'LUN]_AzU AUגyg]JVӬڔs$2/w ћ8CmQ)#_C(=3ؘ43C22w&,dfA$96VVٲY7+)t$.we V%C6InHDegϒ6Qm toi) ᕍߺ'a}22 `J1O>;kmXcԗ*Y{9mRJ2ʸ^J#%"wWY,W gj iߦoCr$lݙEHNEy/?+|Ќ[,'Gz7|S |Oz79 X0m!m"Ic6km(amKG\r\8Y9 qy.Ё9jzG%NߓOO}h? ÷6g&׳ Trn-}k8]SMxR ^ ^h76_p]-^"W÷3LUʱn$ytbF-F&vf=ބ"9NY_[.8J<&U2B9y$PP.Eؼ\~cBBGy"3g_=O4ǧbp#RDS.aA%Vs9J<{*yS/]%w)_/JG/%o6_&F>|/a&m,-q#p'o}p8 .ZpUbv9wF{ŧ:x󫿘iF $a)q̨D%8T?]{fax|aBK9!% 0ޔḷ68~4㉑| :[9zur%v%uLkM ԱpM:S|nxb Ux[H0zz3\Gc ɣ2n-`-3*U]ΙSJ)̞݃X}]9g5^&d?7;HNwNA9t/Fa) 6@dC = !t13l\G&ό`aK0jUaV[ι(bUʍl?_1̏g$pW\'вGE-fy -4e=;39t< V禒VUA{U >%/\y_S+=,ճVLNfFEqnf@0 #‚a39IVG , d*~dT'3LQ{ nKtlu2yq']f82zsj߳1RQr2*'T;}iRe'7v/Mrp˷xЭ?}sXOM/9GRI d> 4`F7̙xbfy,#;畎ܲ"ǔSXۂ6kWReWms,ђ#40KR)mUNcb%+YtYRN~S9s*\'/Njmwc/nzޛz^̄5[bK&7>ti, GU8~c8Qq J6/q}Bz)^RÊx9/b+ct:V|yeBNȏ^2EpޗÙ}wK4Nbٲ:#i4_t"Dc.ӽ`M2;k1ʍQ򮥾1˽:Ɲؽev*0Pusľhժz:-^ΕT=~N1]P2nߖ1a]ԤUqc5\ y9)dz; 9*ͬ8Ca3#f;m)қ¢z5.ǿLqsY>=- [gaX̳\|hW ;$ 9/eCM*J4˸QL&3PV 3_)uE <<_aEy$N[\/hy`n9%9.d,Jy>܇@;?|܃N,dϒɔX~wI9GԪ~gacN5wPwo)ia(zo%dE`d1\qr1F_E~fޮGB[Th3X+cNsu0΄nIɷ(;_1I٘jVru_-zRyL l_ǭ9X3shf.75P˛j_j[^<uU]U4J԰ ڔSQ~9+_Y5)ksڏec\l ZQŤ(,)l H}LNpO)a+ ~g0Bذ,T Qr޺~ޕD C9vt`9C &1ZN%!k&n҃=[L&H'w'Oo6&yzn0yI(\¨|~>>}j &N펏&ı2 ORߕ##c{'T(Y`Ұ|&o%×_oyݘA~˵כb!e,WY3ܝ{Y1q>Ah̵!l&>Ց9rO%IT 0T"=1Mpbw}ط=3)/s]]m9kX^ Ǝ(cF2s'.M#eœG!NmI!AddhԔ^tl `e8|Y9 2Iw,~ Q450U |֮yS\l$զ~sYZ:^M}5jy<\^&ܱkk2Nǫ:gh;+.zȖ RP䘚y %pDvNyr$t3̺h⹱-)ëJr>H g]+ 84:cCQ|VL;%'iw!\UŏjSchے|zۇQƂihqPnjR;"\M5?Yd e3n6`-gu8]?p@c\(PcJh[%R&) C%&Db8Ş-qmŃkI]hrIՋ|ǪR&=m&ûi9~yRv<(Bk+|Z#>~.<Uoj"8ĄJw2}w&cAS# Gk\$E?:G޹%dɧ4e2/kRi4uF5]dv 1MTl/Cy5U.garj9_Fvy ^E Ԁd5NSQ]ÂP*B`iaY1~ mŐvAkyܱw D62m|]?sYvL\Znz3C^728/5,٠G5^^CI%~\Zy9a-G1O ,W. F_|8_qI 4!:-B$ƂZ?/깪B޺̼Eai2q IPB1a_?+>^wM / xW"fѲum5=xmϦ7~lFm~92d;<~nnEnk8pp:~46mx@+۱½t_TTh"#~7dxV*}8ߣ\VXfpCEoG'wG}Ÿρ̳d}Pdw)3LJ(Mߒ)ےۙL'%#mK~I(# VͫQ`aEeU4Y̻BzIӨŖ$d\QKZg gB;UuY{h. 'q=\sgsH5p( L~Wyxsa Tiuf9mـ:&a?,sq|u祒CDΚה??"/|à(?43ȟS<]7cƛ!cv瘟Y}rÙڗE,?j2 X!>:%|]ȃGY]֐J>VT'oYιz)5%1oC?Vw1dcU >\ip᫃c8q_ǟ qMe{d51p,~y: )tuf'il:/uC}XmL] yn{:hYF)ו8c@T*P~5 Q$X/aZkQek,Wgq Et\"癵R'}+g*6}8_khS˗5TM]93;5iXlp8>+ϛ#1E@E37Myc"*P͹)5LX^3S3yy:ޮc:oղWo-^p/+y`M*~ht ڊmM6ܺ)*p㴡/>Z2~"v]jDpYJ5.}%/u)7\=1eRr9$*d+hUF 1.A19V)ϸ$<UޤA5͆}%+1HdAoHe4r_c2~~?_iF7# UBTɝunyۺkµj"]S2j|LחR.吹=2<ļ,|^9\H*HFג}\׍ xσɡl EcÃH@PVErd{/&pR 9p%ȥ9%aTqvBMEGpl Yߒ0,dž`6 C(i6 l<ʈ( 䱳IB &fe_rPO EB<-{BGj&ũyV}%U`!|P*5{6ڶM3q8C803sl$d%ffN$Oa{fةo*WK.վO85et)U9*{kIVAŹ%Rꦋ4YR<ŻHٜ cJ)hPA2Η"5*r ;dyk7M3,kaUMMjgu5RV Ch6KJSȍ'zai1*kG:kߏ6Τ=Bmhކ>&]8sp B{&5c ~gsDjK#߹MibC(V]Og] V*YeBՒbf5t=GwB2hn+J}PUbNnO 7jr{7avsMEzօmOXF̚h 'Y471Aq%+:6ϘKR ObR;3iq?rǑA$ӛNtWO4#K<_LШbjf3ϙ/m9qnv,&dDRg  IpW#(nJѡmr\] ˕;*s9=vwն>-$ =s^)eM+0_Xkl9=orM)=z2W?I }w0`eO[ae+F1 m<)h'PW]bǻJT2ls%.VryK-jx&˂9mj̩G5}^TY`eB/;qkb ; X/~í~|fx(# Sf]̗cŌ;fMz~yFq'CNcMh;ƐYNÞqJ\b*%$hu enHٵSS /]$}Ąc"e؆jfԩ,!&e-TgLVJv~ Kh..{N).x@χ*J+'zTpoӱzD*_Z&R .w %< -O%mj#s6VqxJ + 7IxVc\y5 XՂTJ]]1lהۻcKX/diOjP~J˃W*~Pcmo1}$1^LPW{8X#cI<6PF5pQΗcb5U` D$T pq6R:lo!/ rVދDYYILivQiQyb n-XuC`. YVmInk/9 Yތ돟MMfP&pT]tw%#u<c_lxՙj)dhzA2)`ϨޭgZE*Qh X9!:;hQ)d45OԈ0Eێ%SM`<$D4m inZȓ)vRe,ϓKFp˕8LWsFqlT)+sDGUVVm#-fR ^-,]ۡ2.ˤ\(fB4X qK鵢D<*2$_ũiU*ɬ kO&Y__͸ ݠ2<"ܦV ݬy[_$ |ꌖ%IWwTCG~J M]/t']y6̑voQQϾ:Jjo. a!KAoL$g"Շ'R~0kW[VW8Q;3gSch>8E2i ǍBN+EqYe37!48"F3^JNS2郜r(xtOEkc5SvK1iƖCtRJ ?e&F*1qVpfgR(ԍa8ҢhSGӀxD+Me>$,6t`Lƛ2*gIYn*c #/Q v)BC˴zA FPϫcbw5)==oayRLp^2CylPg ^µCrznP[O(!POi%տ*.٧+9VUTT5ͭ+ CYULB[TE'Zps o~TqY-b 6sF_AħJݩ@x%w6YxUG!SY@`(9uo9{ =nCG8ɭ͒.SQDǶjzFM͜X^wOUf %\3*#b&9_rƟ-ȥ*,-c(Z85dFs~Y71g\Op&Z+٬̧UFQ?tMGL|KHw|C7Q/2ܠ޵4{)EuEB6sE2QqEE]Σ_e8QBu%@r] TGRN}i&m2rt*Θ9b dB*B{9l^u*F5 Bn4O]B\.r#ji.-gtd:/RɱL4 =6٧1wrkeT BڊU2ӽ (}s.egqXwe쏯ca%f*VXTfdQwޡo #D^+XX/r&dj2!Pe`5 '':r7?'qcq᭫#FK]u% '8y?jD37N$ O 7RBRxRsm^qD. ]x9Ҝ169Z3#)P>s?exZ`:0+rLӱAOGYo#EpRDz%jҰ{ގZ͐gs$-=$ux=,yU nȥo.&f Z}T"lͥSfɘ7W r+&*ZHO5>k59e:u:༞zLaE F{cB#Ga_m&N%SeɤnKƴW2#,ORN xgu> 8ٹ1J`qy1tO+{~!I_T_gpR3aOU5W+XAKwo*v^!cjpRre#*~8Cw8_+=*3#6Bm+} fGq6dȡxb^"[r0Kpb*Qilo |Z'؍aڙu35ѿyjdJÞ~uV2X'勐/b;ߘܡ)xΉ#_3}wufJ'rfC?'XkYcso8\uǷҝU cP "Ը#3 NjLT!u=,(]`*|jnG8kP;#qɛ8L4gzI+fIS1_Zٻ;b8k *"L(9YJj2R--s4c8R[RB߅ Vgsp{&maaZΩ JߑCN1xjUFrmQepp.ۅsywp>6ɸ7hA+֊RFuWn <=~6I2/ض%}-iҴ./G^=,37ZyN0c.ks&'I( p/>i1\LiH̙,&0wGS<=rbg;?v~c= f guvӿLKՒyB׽!陚[T|D 61,VB#fTbf0?1K_i/181G}oș6ZΚr**S$t35 zUff!+ɛUBŸ~0f .bdȥc@|Tj1Ix!ۦ<?%}#dzpJ8uS@i`zVl*f;= 46Vި7RLE"YdXQbfGE9/EBNV+94}H^NΣ2^-\Z 5!ikz;k\pyK۾,=bib[ʵ":}GήH_mOkY/7~>㙔;pq8[A-y(1.9U[Gk݀]0^%֤懡5 cK(h$4fMu^*OepD.=̎c΁ ROSzۉlW=]~6^bN#fS\biDԆI7,xTۋrd`)uDݬE fB疠$&]JvQwY*Wѷ[-Lw1(wUEW̑|K`Cj_-I%yYVh$Xnj>'Z01^HyTACulU:j7PѽιhNөl4ysOY0i6ΜZMQ O.3p XCa= bKf*TU2>m|L:W": E,+]uFci{щ g[50zv…V$ovj_[;^)"]F#Ic@C.8zvti5HN˔dNŷ l>]-j[^dbLmq i nMܨl:]>+óI>,[k;BЊLPN2V~h6RNO;q8ÑlsKt4*b?;EOmb:QOV-^ͧӾW#2W_][[SЕa3rN'RS4nhrWYo&j&jslX J قl~QZ~VqmV.΅NGEt/nz?~‹CKWi|(hV`cc!$,1F73fw޺ SE_1+rnՊ%:%dbj^:Fr_B'JaTd%_f9Dɉ|9`3N0GJ-=% a$|bU=z<$1뮞~tu䗨7w7\8 Dԭe-횲('>-E\Lf\BJX7EO9{qIBAWһr5}8H G%U_KæQ4KEj?X2\h -e)ΎBjmpO>=r(Ȝ, |,~r>w(CK#SBBT*AzkDrLeh}ɚ/})/񠩋9mfMne87ohnXۺzU3To 9o^\Q!6 y7ZNu!2^"c͛ɉ{o5*SƊ@Ŭ\W.泲0ly=O bU SrE!e\%Z)FQtΏq=Y8b<=2ԋGCgFΐHzJoZJ)e薗bxœR&hTF JXQ%fHu0'3č-(l:3XTNj!ЊHO~ܚD~Io&vT|'拇m8upF^{1Wd)ɟcx:F#i:Eݧ o7w"@ndTm#)" w&`ALuKFȦqjQe>ENFm͂f \=L`liهq_*ۏ BV=13Ը͢z< KJ"E=.S\;=2Y ;:8_Q?(9B@߫t| _r 윯g$vs5,h-wT$ L/ L#X_ .ȸ2'xh>DʑR6괄~RDgsE Obk:.HK6XΙ:sӂ<&a}?F1iX*ނkزǚ}ru`s`k ;{'  Cs^oM1ڕƲ3-+qXz)݄svb 1r2_0ƹԒp~1t~fse3(&e]+ڽB1E䧘rW.g|},z]W+}ƹEKby"&t!R*$ޑ1`Y# e^Vu͔4`B<2 4v܏ e8&Xyt/NOpT{1g{4n2:1icIqG+yFRyJ\Ä׼X=76hUS뚒j~3%OlN}c: nbp3[Ъm 2{W.M> L'ϐURjL]*VN'ecL_kG5YDz],k*Ea>G)7%:$!e!]ҷ+{Q!;e4\) ;Hh]- Rq 91]å)T虔m%cmɘ7 _]7ݱjO1vsȍ_=IlEu Vha<낭\K׈TvSBVPy-sx(>y265b&cp _{௶vK~ٱ2ԫLMEX. K~4 g. IE mt|³d Ew;¨=+949tmq. ɘf 3*ؾ'0vUbX9kVv样/s93jq-[PGcӹM+bKXzUۙ\l"dSx5Q`QcigFZtz^K朝U$zY%9Jn* t]14ue[VF1aێW'&FUY5bV SүQ*H$58=V a͛|SITC.T♒> ^RP~[AרB~KO% }P fgh$cTͩخbr->JE*Pbd2x} 6\ntBʽ{.l8Qrg2{ꇈ6weSx3_8Ąţroc4;dN0pgהSE=x?v2ݎ+ݙ \ڨٜ~ }k$fa+'ӳ=~ؐՂC P:_U;n'(=&:Ƽ녿Af/ޒfù|! ѥ\,d jB>*i[Dݍ*WMJ~Ȅ|8-~z|F8i2HDt? >Q_3 ++7yւ_p7:h !]gZtyrv:0 kXُXN~)|* >]T1墚ydHo{+юzٱʅܥi_`@GjqDQ nʦ$VƆ0 Ni>Oͯn*vRn:v/E1-/l⟅x 3B1/j:.ױj!S2n#V}opOK6Sh@,ʣk$_gffN1D7#7;s=GWZ_hQ. jl#p `=7 C\f+ BpwsQ;se1OzvE싌FvǍ6twsw?%SZZ*TU05 -X`=XX jގE>t5(nnisz!AE4Kx 0*pMqU9:XR+Y"M!7JO] a#df뭾uN'QOE}&S{6'lqLwo8(cBR P|#$݉i)+8 зawC j&? i!`y`#nF ДnLHK,WVEj$_L;Rˑvw2RVMJNj N ~W6QILvD5ثRseXEh5[Ui2/70c?O9#x_HVd<ú^xhuԋ3dXLf7Aʝmö@\#(##r61|2{q~5Fpτ3]Ju@)0S<[c˷N SDJqfGǤc~k_FߴcʊlHȟ95OjQn<ј_}i.e옿hg"alf\_{3'3]Cuczb= ycW f۔;X3ALkK)Cv9 uLDb>G~ܐL5}yֆE\ $nҨX¬t&gxRY4˟)^(ىrg^2>f0[ H{ex{ 秲WTE[^N4Cviėh>} v[NoW5#ZvH)fp㾕n\hx)-JxSUnnkDxZhqz:qf؟Xnao?9M+*K#eOo1%?ݮ[S̚Bi"#f:.\&y3UnKrm lc9e0NfDJV.@?LLI.)%ߐS&dPV#8ωBiE*<РCƩ9{w1Ws҅{@ES1'(Z}.%*d+ÉlncQuޯ&mK7‡'C]ɪX{|NzPړ3rQ5/_W,tWxY ͕qwi)c4)qER>2'GB?5=)e~ Wys&O[: b s ;RDb& ?~y3/hH}I NͣOo܍p zD[ ׉%hMX;8C+wH$]U Ou s6Bs] Jy'p+ZLȑKfp-&Y >hx[Xलgx9сy‡[<ŬTY"f )Ϸ#=ŕ Ůij1]Gu]vFtџWEw^</f6UiNCR-7Y#CGv [tT 7O*K1>od<EhoO@tVx^܏H;`G?<3T]O6b+۞ileTv 4b; Oܩ2OTounXcDž6\ȘBG-Ci;iOz,"3KHVztsRv>}C}сsMQ{4k{ OHXKXPKTǵI##gX0 Djo3 "H?G_?w$+'-1E!3aď#Zč_g2^٣8 Z'í<(8v= n^ a91LŴ*lk% 1l_c&jjTLj$c/xEMȘqV_ǪЌp?Ÿ ='GnZHU!U?}/~E4 ;ߏgy,Jm-,tXj57в}F1fPʓ_^Y)_%5N)1䗞Rc(GcXleeY\ܰČ۾Cy3h"V抑Eb2 uIg0_Ntᵵ-x4p!gR߃Fxo U)upKXNͩL1dDWup 4OJl YN,S0!YD.I"xQnod3F"AoizłEff+܃yr%=dң/PJ= >vОބ_ hU -Q"x9ْDb:6S$Vf{w>f$oNbL1dafa;<:ũ;wV9{}TV\$KkGRIM8cL"]:RY-6ԟ`s r! 5l(`v&T(^r#ZŎ%~VMSf)zfR[|i1g⭽Ljƥza1;JH>"5Vg%U}> )%Ylў_bZb{m>ScXͭn<c,'˳9~?JL)*|ԴVqShe2Nµ$v.gjzk)}MbY,౸f? y)(On.GEDuw0 4=S[ H8Y 66s$+j](~ؖA6=+ dDCo3 ' ae 콩̂1>-Z,clrh+_'s6uڢAM1Ovˁ-Xp̌GlpLsԱ jX,+0۝G ĩ]KXZ"f-!Tm7ZbhXzk0w[gHO( UӰg 噥l3՞(@B;@,a-Q*YeqҰn9/kgwri jkgr~`uhMΖ&E[0,P5IļҰo.5=Smݠ"8<$\Ț^,%{^ь#{ZCXmu766BɅ-YCAtq&l̮AULlH=I8GJ^?7I6t ܟi>A}*5ιNμaŞ;F/Tp0ډpc3 ͺ,řːQͨǓsyC~g0)3(ʋخ Gs +JÌ%[Uʼ ʩmy2~Nçު`IIp\W;ڵ=[2bj㸆-\߱yꩡk RMkdNDԒ R*xղr,Zo5VfjP׭q+)3cyciB8i{yxVM) n?vl2 lIJxC~}ݹ;m2{Zm(nGEx k~ g>DD3G: U'Qd{Ւk"]Ff^Oq>&`;.g^🤋OPP5ȱLUHph!i}L,c&n˕t[ـ;ų-E=ŁMpF#3?.C,GyolyTyFoqvT0/Ka]FM yŔ/aN Jz^F=dit:ߌw uJGmf G3B*}> 4ҮKy}K٭Zy4GؤMd>)xe(p&NrPGa?UdG8[EBRfTqWC^r\ 5|LozjڹZ_.dVCRÑ%ʚTйd!x Sα)cvzsC)eE﹛c=ь $Uߓ=\r4B؍׎mۑ+?|Im Y8OS=ֽht;ULӉdYh%E'45h3#awݹdI)=<U^|͆,"| h˻J`Epg\ }3fv"WufHh>㬹3UD%(yȵ/`C/u0n%+:'rZl'ШDv?->R6jsTB X}&O0=V?S&`? yh'0X>oSea)ЭK\8kfjFWU:RC͔ Oѳl0{fOkFTrN(gh}5q%jT,,ɇRF-2$kV$s4QryS{? 9r'.a|RyQ1-Uj󅛣F5,g.5ǵ{y)ѳ4^|s-E3[ W6lW+௙Z"ѭcĊOx5fY݄4$з/CQ4FU1i-~Ufn -gevG&N͖3%hsh5OEja"=LMO Ph8PNv2)㹽?L0W9Mx{}cw:11 gɛ$*祱5ƅ&\Eei6,܋&(\`|'YE f*5PVDjM~TʯU۵Kپv~5܀%fV3p1ǓBi199DGZRӛxaD Z1Mo]]nat5:Y~1;b]IJN ?vCeB?{ùcncqk9 (})nA~$nx6rqjc~CH}7=˶l3~O2f C>Q24ߪ @~`kz e^DZҥj&Ok;x jtsB_冀H cg[;q+]Eck 7/r&QQ Tj5S%zkCwj?^o4SƬeD&YDjf~f,}S4rXĉϥ&H{_hG\ 䱰Dӱ;EI\+/bb"fyDmCJi(+g̜$wfѝ:CiM7YQovyS&ْ@|{3:‘ӛ}5|urZk;ZFzbFXД<ݠ`}MT(&I$;0iT%=.JYuІ/{!8ڍܜHձ_LӪ8 U7&/`M"ye夀m v + i80;s;~ن9 t͌fj j*ȶe~GYT_RM[Itz6v1 biz* QƤJ5x y}\\ޛ (y 9*.hWƪeTWk\9'PLS3qZK{m H O{ǚoKͅ藩8i7BP}vR(Zȧ,'czk #G˳p?GǛڮ4SVE*{~ ./ڞv]~9RҌSɛӊ.>v}@ /.]xYו^P^$3$$ՋuB,7X^s8x󱖊-^hN1/ci7K26 RwA!1Y,7Hnj2 ZO d.KQ6 hmx_]E*S׶ٵIYL^5mh~dImNtY1{q>s'cP:Yϝ4c1>ӹ<cy"n6-~^_vf#pVOu^v>NrǁyΘ}迮#W_>܈̮~Drea|pnm C>$''jA8oLX2# 欟ȪNurb83Yҏya-RT71 g+I8be3[N^q'zԣՌqgZ^*oܪpɎ}-ywP8ʲԚ%C\6SmǍ9pя9TY.!xƄJ˼9ˑGlm™>,~H<6ebөG4,s_Դ,(ce)_Y§Z%ؔbڼz5n8?]y;4 c7Q54d1]-]Jˤ\vYkm7xF"w3px'&pACsI^PLjFNZ$-éj f9|N@b…yh) rQ? \944{Smc3~{ { d`,%t$ʘH9COr= ^ ;ȌӜ(j2Y -"ߏ6&#s+ioc m,ne~vǎ iKdk1U3z%T{G֡˯AwB\R(Q_RvgGkF G ZhjuCp ~bJf]ow/7x|ȏ|i:ڟIGRecr*ЙٽGrCm4#ĎT/,&TgnɮVpʣL4˦ֿPx崩 >%_m*fܗxחⳆ&;4,c4ǒ?WܸTlItH?}(؎ "T/-Qj}Ik{i%ۗGT򒃩В4S0^lmި9:&Q.DB¦a D`9 uyۿ9?5~Z0ܚy9+/V=h8̃?}QYE0+oo#ꇰb')-vץOy[yWW==9݉$mȯ֞&^Oӧxj80l/*viWoLbʷG+mN: K=JvW*zɗQlNaw)l#7C؎䀷_\)w'Rİٜ^6"yYZB>%Xlm= *N+\cɪ ^MeU|3)Z%3^{$⏨(6TggO;jZґ+O kC&տ`EysSPlrUc1m xy,GRAsvqo1{>30C F<1CquBXv̍8hjkToBjZS2О4Ō7T٧͓@VGh~Ep`&x1Zג_]]s_M}055RC%nPLXSDd~lbO ݋s |1ldLnTl׵sri9]ż}EP5O}lMKdq-wހ>dG +f j#'VﴢEaےOS;>;2ljqpBdU`fTeH=cY66>DvP4j#z2G^}Op^PܙO<[zvdq:@*͸SD`/`O 9ܼ3 ZUWR<[S'B/}PE4lhae6/\+ WvII+%]885TRL>#~%.ٍ͂?IR7013iIE}jrYNh^ NîdLM?JwnmBUq }J)ñd!>٫,K8!QL¿FˋY;f1,Bx}56ʶP8Eil3^Nw& ^\˕ W8_lĽ=yRW,ksU3n\$N=F4xj ٟltAD×ϮpC?sXVFJDD6 M ŽFD`^+Gޔj8ƇRsX ՊI8Ƌ̩@,kGX<'Iêj8SCɕvJ8͞m^ȗ\]7kࢶsZH,t/DSe4(s|fD͙IĆq(C#0n䜷"~0(Y[>=٬e,w+Ϻ**siqu՜+נ{=Y8%)3Wc]0~I"^w&1>Z[}[Fy7̆\l}K!-wqoS\p'~6qpoƖiia8h ֺn_. ]+G4.RA1YD {:ikPwr8^hy#LY0: f$>f,Ja~?`C;nDӚ\CG7VU3mx;P ޽ Y;`j9|H,bl_W8}øny ͍DɊ ÓqesauiYYİRPC- #>qvVebZsz0l(%%ic97Cvљ$:x70N~*Vw3Ҏe8a>,J#Y{|м+r@7~|%M/@1#iJ*CQ`ʖC8d̛F|I?*}3ׅzvv,a˸^tm0Ezy2)C~>t!? {it`9닱ϰUvZ+RdOEA$n{T3½jΗQC͵t-sHa\ҫt.ϕg_<ydjBuDl gQ^hk)_4}bW7[שY*ۣ0@n|;4I00"D}@K_<3Sǧ"]&ZNAC ܵ`H-;b1"Ė Vhp(qI=xP̍ QZV?OOsu-*IϢۍ e{ k{0ZafaF6BH~ʻIJ/lgovt{c;S\&&˥ŌX^a_׆:!9霮RH~jri0^jz*sIϷ%DM򤩅7]"[SɮU=%Ջ= }KDn&}U*E&P$rѵ(u-eřw)-‹G6J%1] ?nBTܰ'j;nK}A x/s-81A,օ:K`guc h>:wdAWbRnoGцnMT̽$~|+5)R}dl;Of/Rjq}Rwm'7/ؑU;_ƍNuwb%+- fGFJNk ~M'e=}HH܈3)3="5s$t1zѻZcCnrDп*+MN?mCW~Tb-w7|b=&76X6KbȷKŸ^g9e;-Ѓ>xtp\݆Ƽ)VRϋkc v{嘒ƈ|醡ŷi4~s,< #ۄҰksDoXL0i%XQ~<ϥٱO'E ܃C2qM0e'kvU7%ýȿHq6F^ .m/7\U47ɸ.ʱ z)6*֛+Om=+{MmfXEk^{]xƑ7iHf^jk`IgǴ2cBcէב`*kgQg ͜=n~CcH&a$[ZRN/sO rD5r^EhGΉ`b= @Ng>Ct|s jк6E)ev?U|lBA3,PGR6#yaN:7vwy=É`˰BKyݵ?:|eo'dcn4*hy!;<|>*K/Nٍ ܘʅ辎|48/gz\~kee^|ӸJY2yV(F]ٜϣ# 6@GvHgȟv޳aU;~q?ijm.s3 yv&E@ZwN{޶##b9 V[{J0;E;_gӮ\v1MPJ`x{ܚcv`ry$X3QǗzqhQMU7HV48'D%1`^ȦmvϣQ,+/.Ne .naZ "3Fv vij|^k oW&ʏZ>*dU1J],g0.|D#Hn>=҂\1)3'ð2u#+xpƅQ|1TF:Oi-O8Vpwe:f57{tdeBk&L01b+fEZroHZ?_'3w"^]fU6͊oUލ0W57ZPVAmq̛ꑱ[KZaOEG r}!1't|.hbODH~zqxzJƾv,<_+6b琯dחKnxD̴S)wDR]S^shhËwFЩ#:4+HbOq\xA\p#)O~ҡ^3(x˯ LZRYŋFa$mV@k9t41r σ4M ]gl0EIMIH `jG:_q}@dY5 {,nF&Nbc޲mִe";y&+;C;~Dnh] x/ zO:׆k(@\ z1sӇzRtȕ1uxц/J}gt%7 yR:E{ re3hicXaB$".a&ڇoVnC,SR&eX)Ww"߯'I Q8'){٩YJip0"bGeiVrHfߧ:Q7tP<6+8bƈB xZqՆ H`T[qkLZ̲6X_5%^zԟ/(X):m"95ŏݫm3YtZ#b^JaxFc9%?7uQs{*N<&I~J<"&~=BPp]б]ưUQVgnQ=4iQ[9[cZ w[6.͋c)e5RdoPCYp@q6~bJ1ipvO$#Cƭ4QP+ݩPh#7˛npqt-Q+r_Jnm7'e^bkʶvo3s7([k:)U.P< 0[7;Z[rK?!ݳF}G+FG^zWqb|/Eҵo^KU?/0H1˪b]$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$Icbz(!Ko>PGѕ;9F$I94V8|S6rTDwE<rvRNjM^(44T:\wk_NfS;($Sg@(}$ISұ\4]y:s'wMO=5_j2znm؈o#Eu)TP˛.O;fXK>) b:?N:<<Mql}W*w:ۓS+ĄE+ŧUiʆʣ5faTnWTikom؏(GzFye"0ɨxs fֻf9Ϡ6?E4D<7qxC!jȴvܝLP̂U-[fMg+fڴN>.4y:UyOX}3n{j`~KA!&lh@6ě&V*j\:gX?T޴ɸ.|5*2$EcE<?x-oQM6nP?S~Dbfj;dL{K}k;g++G*q0aOcȞ^w{wgs%k51yngqᦘrOD\"VUcY7ū;]dH+N2x5}3ݫzoܶ'7?pu߉Y L1ԓz3݄9A'Vr "{[ciםqDJ>YY_G:V8pt1ڨK t;Xz;[X7BM Qs-~7Ewʘ9Slx]*j+t;| 5rނb^js :ž?͉`j`СLk׏>}WpÚ'܉‰.ጴծ-.'[3Ψ a4 1vqi_MḾzT7#ρm.tv@cZ:p/vz Az&Ar 冱vüXƂ\>ӌPDx{=xԊM7b ~ޕT r&; [yq~/zwG:9197,:g<5;@ֱ惏+[Un|m_O갿^$%<ǟGJG͸}nf7qe@x`n|"'oؾNuC_ t`u`-c603sN 1w]fflChwffff?4ͧ8:rK%lukz*}3L~J@V)~+~8h}ƌAlؙiA)?)s;3m4١$6vr l;+slu7$2cG̖q9́ikX}COYRu3穎\0) mI#ط˂ݘ?[5Əmce=<1vk7^|2Xzqnme~Jbj &XIXb%8D[>Σ٦/шTÖȦ pܔͰ {W;✭yZPXhŷAJ&xG*D2›Zk:L,5`wTa1(nnm1M#1`gzn@]-r-6>,lG+ waqv`c}|~P8A;ZXvO.g lJXza(1ct-0I馤تwVN I>  nX+=b/޳ESB^دz"]zJ7זpʗa"!-5Qh^+ŃEW}u2ʇYk꺌g(4p :#n2FRV"S^KUxmfl>IVԌ3.ϬXGSXqӊ<8"sŏ>V29#)RBeXNo`O.dnÐ=VLc"-XZmG&?]3Xy^,I†=puCΆ6)x.𢽊WZH:/^OC;׬X:X3H/یTNgw?:c3шTHkDk-f -ulRy?ʚ_ i_2;r=g0͗a_LB]3SDŽ /~T ƨ Q>%iWguոSkul((Om/ bw< |2xoXˆ}?\ΨP]at-CZc- WDz6m(w]>=As6'^<N*POV^jUVYVI܄1` 9c+1n:Kec4E2&JV?3JFe ^ bHkl-p1uʣ ^&iYͩJ(/3khʏ.ljMl3gxU㸷ˈ\¢/MyҠʓ#Z4tU߭JxW~vu X]z֏6V5uɑty~y[ g yKf[yKn93E8DA@$qX]_Dz_G\o &e1n*`U= `M3aCSZRg~>~%3qO<_V)ve¥@Zfx6v׉G"}Oe_%˓F3S7uw -^l]:6oīl-囟3_NS ZH,guUvOeأrK0*Lv ~%lqW2 dl3=15Rj)>)XF% %e{3Z.tz  iZìD$UE_̕^9o&.0. x$.;r2?gSߢlT,طf^Jӭ\2^ g  [Qif6ƛ\5~+ ,$6q,'ӼFb;b$/co[GD𴕌Iո.;9LǩDo-t4pܫG|XV.Եug\'8rIi>>Ob=H&E!1T!DI &'-pwfA_.|.q͈@BU2-"*x$N:Ҏۿ9uՌИLN={Z`b sjnJ)Զ%j&FR4fI~W]PMD('R97M/{?3RPsX7? wC]w,o*{r9tljj7LaWs.ZZndtz‰d'2_']ehLa{C0b^;F()qD>eod_"B]t\̭k%;%^ wT8<]Vx \ -dg`?N$-W25g? qWy&̖s~$=ϔT 'qb9GtCl7P;^vetC84ȁ)7. g̶ ճkQݸ/B'}h\=ʊ퓩Uct([eOYno|}.#\mxU'Xr:r?W[mp&z=vn X8+~5zȠsx:OM1$ԁ2xX2k^&rmIkR}\pɍ1)Z2qC.L2dTgnfI/\uᅪ)+d"qs(e?v@\;:l帕+i|29TǝY2W7s̀EpOz\_Y_XL֯"'0S,ޟ}0rImFU_ͥAvExT`f1=F?TʫI3 o1,P1=i.#7[c7_jxbȉ^h1 C> ?-jfWyr)ݢ%,D2鼧9:# xP܃ao*aZ,{!NzQ7I~cU_ v8EF_ 'c3KbMy6B&mN6x='BEL^L.|[(#bs]K[s>̕Q3["6앣-.Jzࢳfpja2UNBngJT*"h|ħ\.\ԲURDدEΚ,3V#z&Hhy@O17 Z'8A!q+3XDVΘ>r>'otߩzCtex?/I y3{4*#9!f9(QF|N$_7Kh𫥟o+RhT K7Fflf)~F^y>+E^ʛ^\$%V{b}v>'b+dvq =/z~V LexePYlElq_{wpD3FjDBBx CG] 2^E4Rn%/M졫?4Hj3+c Q 32B~qPWf<$c >AZ,N,iɼjG֩"lU#z5D ]~H*r^bw*1TArtd苜SJj\Q𼘶⹜J)cϘ01[4E)lJFc@B:̓ys=pߵcKm}F=1zH3KѬtQᘛ6W%rq\>Iz(yqb^vB3u(1^%agdvaÎ z$7Ԓ!-H1:>ikdCoJ-{f}6ƕ_"(/dўRw>K(tv7q`1cO0a_f+PJhDf3MT5b'S??8Vb_ĹpW ъ'R𦰵4Z2Sn4ѦȾK>i =H({VN5+w ?97#DA sR\K.[W22=H6vYݐ'f,.%,Z>\qwq[vY1֗8kvᜡ+!2EM\bHJ@Şsq43ܑhڽsgC+&J.anǥ=l&bB$һƎ wW683GUP?Eƪ$t\ ni;όi@ߡ&~Ɠ7?cΈI\0>QX!!'vԭ積w=]Y.DBs/y\q~ 8kР)'k9+PTZsE5^U`=DArVIa"w2bIx_WgB4H(HXT|/`F,sjۈXxɞa}tip4b @e\56I8w.fK"(`(Jط گսMea*ᵝ °,i~5w*)hn"9cA$L< Lfr~u-g|΋2.BѮu> vVc?''2]+FB'2$ߟfW- Dɋ/"G,yډL@2rS,,6#ޔfv~av:1U1hsr$WHfsAZXɘWm}Nh8kCEtw#frwU^$eEuK{RL,9B;ȕo\L n ۑ̱G9Pʝ2,g OTTs:Q8vdMu⨜ B99!c+k@q ks1A'156všv Og˅x^n "|X?u: r2i,lO&:V :.0㸖Jt^JEZ ;p˴ߛA>8?嫥!۱j>VPOx7A8/Sc_XǠEh2Z'=sŸWmsf")9^A3\hAS=CɏE`!gUE&aS0 0ZsO챿13W]9j[Of gALٟzܟ-6?c}OA8ћ 5W13C 5}ؑ!Tu6WZn1R.6(cB@Y ׮qٰ%XJ 3Z|3ᢆ5ݙ1 /M~9KTc[Ii%V2Dg$ GdS`iKLF ܼGh/=&60-Sc ND3G%8m(P= Oc<:fiI7UAwh+T˦.ގ%rq'S1ɘBq5˾ܖSWG7e(:D-d*!wͦh@CHx1O 25G#siY;Dž$sUuS*JbF_T~,hZTg#|(↭G\VK(̮3b6 5_ GV; G)fX~nGTɴyhByoK4r ]Kt7g 2W &2#PdC6;3FyW6ڍBY@3,-YqTbccF}5f+3B@}q(C_FDC%}+yzjjT3˧m+\Z^dpd7p 6=Oh/t9}$ 1AnLN)]}vr&>\Jo)Qf"gM"& =nz-ǰH64]SS_l0A0r"'ܻ J{H^yUZq ί{A ֵݨ|G-R6 <;Uu)%xIDe  8.dvz5"WqlP͉ Poe2~1t@RܫC+ a߳ :XSc̹u8UB͋:~)xSs>Ἥ7uthmu-flYfC-]EI/OZWeJh]^c)d&!a3nRGI$wl6(BC$BE8ۏ]s]ꗅq.U惤1džOzV2E!Gam5/s3e(k:+̕X!{בEتQ~5ad}4”حfHDVh(Nh3~,K̑M$T2mP Σy9avTUC'{Ɉ,!w93S*u=([ÃXa- 6vy={_Ѳs fvkat΁>i§ȓk-xȄŗ-'bY|7kY^ 9~\\OeṚL VeG‚ߢNPIʒ΁ׄuєX3WwXB)ʹs>GpJe6 Nx aXPN^!i#TJo}|6>OE{̎ui$nw-S!9߂SK{fVK̗ݔβbJ̪Xc\*.`Ǵbt|2h{ }pJ} /e8Tq{F9Lts[aЖXeQt;~;>.g˸V-'tJ`)kFU9RʃK4[pH,:=}Lqnƕp ކK {sc 䲅ڙs^JU%`gݕo0}1`]Gex0L0KcN@Oyb!+QźV4(^[r=Iڵy#zZ#oi"&lM`q-P¾!dy1NwϹpԝ<5ܯ az^e2Dے<ƫi#73X̑`gSZ$0c7Ba (`p1OH.ѣ(AoVwS0;#7Ҿ0WB𺗉JdM*!`VsEMCzȪZ7Q Fd|}Yź_ymJS,fzlߘˢ&(Gڨo&cfF6D|{xbp %#=g6 'Žn 7VB@J~7#zHD9)r)\J| ,a].1c#1 }H6 U0c-߳*I}@dkFԪa<Ѹ8&ŒSy-T^MxH޴k[KsRN:1q?:%#3-C)u.̭(%] GlHN ڒD~qԶr*{~bRcJܵE}lYxە`Fa`FuvF8"%c' >\8NXW&]ЙK^zYR'%M.- I={b48+c?!TXijt36-P.G`ʓ&\Ho}/-f1#&WYi`lyU:O?/4ܫCkz_E3%z}1N:X΀%T)"@4ƊcؙKߔ5}ᐞ6O伡'Gyro8fˆ#z:Hy; =l7%% k$s#kZզr=M̝e V),/bt>bdS89SWFCAZz`O¢Y`m[uGy4f^ }ts*oYz=־ w#ĚPȯ$JKqO~s%E(u>'E͎+EjO5?JTq_Ep}j_t)8pRA'9Fnf b/+wOj8wPаZfUe-hY|Yʥ \0[u-Eͣh' e(ׇ1GdMv7a*'J #YƟu$FZ>_FvLLDڜ9' Kye>W6%sxDi?G9AEh?G7h%;fh,]&xҏ=Zř g_&ghB5+pv2,Ccm-27N^`rF.e,7bWH-NWѶ6#Pˀi.nj;n }U&cd, 3)fuӽYaX4SmRM* SGUZ[Nږ\jB'kĂ>p7Ò]63ILuQA)jMq9YL?C_šzWlNJF8 [';{M |8NڰlFsg)cDfrִ/S6S%deygr=7ϩ.ΫQ5CI}D4/ g=}c9UI--ֱθscj8.!Y-j.+aj rzH2ZV]LjP+cWL 't[2>N|PFz<2Na(-%!Xg$;G|ς)ڎ?bw,\d\+,c#8-WFH6JE*ݢb"tr1֝?7ah6(b͑b>*'et9ߒKHK)_ׯEd)`e1(*qڊ f$粵6a)Ķ漘rĐ! OM=% L_ ΋ޥM,V4r-f"7R[_Otw*8kiSS˦OCX ~3{!AB"?ׇpl/mcߕb_i8?f(?sO6O/Gse'[he׫ Lϝg-_^fFg( WBn0DNCQ:bI xds(c~ES/ZU2wg*s~x &87U]VML]kߛߎLq4ѺX#j \i:nֱ#y[J`5f]*YIkzu YM|;RMkYKseq-ΡEٞR23DS?w99By݋ L**LХW>><&}aB2f!i?C_JP)eSNe8_Lȣ\g1v{1=P%gHfrP "*A^}XTeX)R^D9c(Sir@c)8]|+#W9kU95kWܜJmdŸFJ$c^SYր6+4+q*o:5ïo.f㵼ޣ`\v==P01OɯL%Kg/cFhh=IG9y\s{ 4;pcdN\nt+J:%:#^>oO-ʟO`!")6{ʘ"pn&]ًCP ,b,BgC79t*<|Ԡ 8_EH̶|K%c,;)0S癘A[xZuOV1հ;l }/kPQU߭53|u6$2IS#Y*iETQߢSKgMV{,<UIQVm671<}md+bn8z1F&'p1 U"}dďͧNJ|v-N[{=m/3ȕ%kb gЛωTiK.WAJ ģެWfZܮ!xkkP{~Jqt6Ѹ0kc#g2E6s=SP(fF'^ZVO=xSG:ŠAjzɕ\+/gE9+ߖ[G8nSֆRN}rl*9BCwc[aV:VO-ʻ7Տ>CXJBլM2c'p,O`Z&E}ϚalF}.ľ+*ވ̯늩4H8_.˹;E& ~)7d= &+YP ~!w{I@]|bPǂmbjD5/{9{X~: p%*,/aTN՚j 4͆03l94ОKȣÚdr6CsBR??9ɡTzNI zd":mS8$IuM'w&7RMcg2Fw)aǵ2Z-g̊ NU1lIkM}s՘+ЧiHs4;rұ܀lZ7 F6ݨ*S} }{G%c|euTg5 R5WPɌ}x[C UÙUlVJsXDԶ0ny7  ?(fYi}Vg _$ې֒f 5ɖ28ؔT&cđ/9ҕ=^K˓P,DQ4 L%։$7)Y,Fj$a|#++h>jSij٬+\yqSI nR0KgW07G:jѶuHϬfj-*9{5tpx.#ܪ$wW9_V{D5u ¿Ee/klaª&8䭞 R.rԶp̮d~Ӝ䔖"Ax\)F&Ab<,j9U9LjʦS@KDE',zf $'3?IA[p9w"ׅc< LVIe^(`-追xB8q' qW A&$X3C>߹V6EM 3߽?k45\_"P"Q.B͇>:7cFcDު F깐cUAi"C!XfqHtdZϛo=SOf0k=iÅ9̙ܩ6N.Hrf}&?5䲎"kͪƤ 󮁆JTQĤ-9ƀ@kr]B=r1*QA7Ztԓ7EGU=O# = i묡eh8\~Z,&ήs-qI R VҠE"y|4%V+o|^%rLPcm!X^9԰ȣfqf=3CY|+nҪ K:Gě4ct(nX~Ǫ~eSѧ֥kDg V\M-VoҲQkHݥU/5p)_*9?E&U\zuA` Z,Pj4 ݯ959'E>gY|UNe< /'moTEFs|c$q,)fCW^2l ]hAyVP Wv=Cp_ݐ5G ɡDu$>"Y[Ďꡬj.4ϕ1CrӶΫ _Rw'8|i433ؖF ,5H`N%*V/77@cKGoL띢OާơP,su<߬f%j/zBz#t>mK#bM)oE()N_ՑEG!=Oa .e^|^(byx{-#2pⰻ_y-$i22Y.Q@]^: KYb&F$ly,`% ׃AKs&poǭ<˥4R?LI0&')hY>E1/c]bNON \dJb aCj(->Fsvf7 :47Pq@D溡`e4hiزTZyY Gɔ#r.grvKd}M4;ɹҲDoaW3ę%1|ǁ>nt?O~n!0Զ)U&psaxaONMzPzԇfSHOVR"e̡@;B3%}i67 :>ɺ8'&K +f5#;55rwç =cOWR]dT/߇eth'L5xQHk:1v|Wp#DU#>yrDJO]Ϡ'玎!z3 te -YZ31GoK7UԹW̊U -#s*mfss@\ÏK~z=x$3NJROg՞x NOxDh霼Dۧj>}Y1q8|g6wiKYZB0/ܟac%ʨaE̷/DeP)NUP&yrl*qHšJFIuli~Jwq>C_"ӯpRE\/dbSd5i}KFr;ʘX;S-`_ʥJvW>"þ] h4,Bl'P&.S+ϓSsؕAGF&NXͰiM.>=ANGLG3a5[ٿbƬP!8Vr%(fYȪC*pOrRHލ>ss>K ^_!s H] k%l|dUa$ʘQ T}"O]Kd(>d.&bhWxFkMO urA8T,EW;y}!UhNvDnH ,_d"~n$/3^%٦TEv/:A| Ct5~s#vMaZV!rJ7ySf"}l^2NЖr'i*6]HT)L|F7}8|o&BF!uο}o.na ^M/a 9+b Re[YHöbGRC0cPyQ;΃x5o"&2q)yejo_Up0rT^ϗ4ƈ&@C?U콞3:?ńȇ;bK~#:]53L 4pkLt\-:hG; DuHGU VRx2Q6ͦZ,R\-wt~Xʻb͜d "8!TFS îL./EKL\A f[Vi1(΄d ȽQqZѼ\zq4߻;Ӷ/?5' i-M8hWBޝOcf]TCKnM4j&?9yS@ٯTdb%phڱbNaokܲ-V2c?DcɌڅL: KBq)ocƧa"kXgQM&V{IJuX<&V[%D_&oZ}DO}5Oi5 ]f`7t&3D-DwSעsjhYjKo6hbFSk0Siw~xinb_1TKa? OjbBp9Dgj v 5D*a/KmE`m9vc"1˨(8KSra<[RF\spK^b&WS)JE j I1+8)Q!n`P !do>M5{sy6qO.H$ o«BNi&>Q7uc`+LجQw oLmWw Ο}0ŎV^C92s0ߎ&EJh_^|3ۓqZhfvfS͎gRJx#_Cq f,*6+(n{!Ғg6Q?\-mY3$IlzjGR~1GBȜq=*$"=.y ?(:;#C č7PDye$sI):+y\n Ĝa:53ƨIj=.4Xkc%`ϕXYȂ."gʑN+cGB>I2ñܩ|PGPOM;jrJ4TFOr9T2ŌQieꔰ(_K9VN@<i_}x9#JI^J69AJHJ(r˰?,pW9gR@ L@$*5"+ν}uIưq4m"Ma:8:\pk^I;?? ݽh+c^OJ{ m1S;uWa-2;L[˱SXj Fm`jR1đ8F1P:Fc@Ҏ<)0}ZL0 ,-tIdL|҅EBqkVP9y6`폥;FsD>kC%/10A4:9n  \J::V( }jb !]&nf`2W ji}I 64Tj虥'o0~',ZK35e(rTHqr~zY\L/);,m94݉BȦE|H~\}t2vrMX_S*Vђ+l9 y#ef*+0_\F*%5wIJ%t4?AJ*ạ{KxXrn+93^NS\t Hϑ3srVQ$F[r]97שF}"C PJrqEeѸD+1=D m@Kè9uscU6AI6 ct397F^Adr4ʹ0=9>$k1s>iKdS'tV|{Ý4:u]1g #xڃ 'Ecvx<ﯹ_mEo&vb'So RBp-/lj{2 nm@cZ/ޏ !rTVO1wNSaRSr'=HrT\vߵH ̙c@z>{ l=a^S/-./ẁj3 ,ZX@CJ8˘eUđ':oKը1捂F^vៗ+Eۅ9~O_ao[fRc-֥ť.8s$WOƿ}>|Y/uefȘyUd2}2RVE_bWQē9% ]DL)ٰSR&c93Tƅ ~Sp⦂ WiUOqxhUƄ295Pb%=d\>%g0Rt r ,Y ^1$\m3kL(6cCiX5@Jugň뺷vT`~ټ+й&ے'N Z|1C3]LT3:]i2v U&8ڒ~0g}3C]+5}X.R}[#w…\O}-xZ1]q%/&Pz9jH"GWS2Рs!UU\4_&MM52fcHSq!VjID&SFű2pqkqd:Z_&6&H|G" f(:π`j3}#oن<^tf2nD%S :5dmdC#dF %mǕfFp;1ʼnp+$|mn y9 ~p!m8gDMͷ(ߑ%#F9cgP.ȒyR륐6ڻl61pdrBYd#& 0:.xQv3Mg^a\yKαjzQ5LcdF{txԢ%JI:2y:++jC^5UܭWEl'3Bvmx_`EpT8ZPX*\>K%o6[ypA7|k.'፹9w7evp}d"O+md@P߉as 3N𻼔elp)aMtqE )T3 E\*4r<,ȿ? i~e;b]^r̺sL䌹=dnz[<UDPkoA>rRhg2EY붠 Me͕M3r^LֈXVQ_J0_.SH~k<hpFp96Wnq%gYN˻:_更lݬ%㱊W θ1gD&=n,lDNsFbKؓiO;KJ7{0Tɖ~L"^&p.˃+`NΜ^`M-4݀kQ06༶jzcz t^A]^|p#P2+~YgMɗ,8K"}peY5Kh&c}-} I#p Tqy&OJDbuV:>JUSq e\L,<|0BgB!xPjNYcϯ9&c?m`{{Kߜ?_>)K̉Q=Wwy͍1% ͆#b柆sEOGɴEP$s,U#Y5{R}<吱W 9_ǀk%Tfsg ,c1@Ǟ%e·D͘.~:L[ Q%^4YӇjpm󝛅-7 M}#,VbWm1{ಢ-_5$?qwL՝5͊j^ʋ9nWB3F$ * Y9R^.A8J9YJ!NOlr?$E!bN,-&bu J9G1,Ar*D0 2 u54LUs魆uVC %< OXE;DR=fA"yx"}j2cuC8n}Rx`iıL2)kHz415_˟ D̢'"&cϖ!Ci݋z2n[a]lNY;n9^M ZxzPN{%O1iawBgƒbM?V iİ~>{5}aXTz6s >".4WW:HL 3Dg:g7)8ӛErp&+zn'cb TWO%'Q΍]Jk#Dsch{BM3jOyCbQDKzZԳYxֵ{9PZasZa˜D}vnB\ӶEZġӦX2ʻ'\`s./Je[D.:=E褹j#YG0堄K 8,eB~x[J.ŞLÆ /Ʊ]u!Bʛra5d UဌҎ g*IܡLU]6$c'(o Z ݟA.cݿ&? B声R!OSEKH輱Y*9`Y'j^2rCE;3/O2:}>,B9wЋc)z4S>LތݙmhjGf<ԖF-{pm0I; v_ o(|/a~\Ł6L?E Hwذp[qlp/iþv8}EBy‘]Y.S %MQu..\4GlYuݖ#G`5rmg4q Կ7 PC0:&#:׏&3r\&,Гu=>#QhquvPik#/Ew01퓁_d7rp%;,Rp߉M17Ve4nj,+Y\밵KUǫKUHI+<-XUQF vBHE+/~yS̏*%vCan' |,cH#quMۏkq#:![kɍ~EqQGv.vn7*U=iv >Fd#N{<S=p[1`?b65ѰEʧZÍخ3^Τ%eD9_"iIfIrlhGÑjRrArDHTs兊j"i3VI4('~֚VtЇsDot8<'xB^y9v{߯-5):6zZGEY )\X)K 9(E] g2S—Mɤfz.gGdyrni6b[)"ڔ姜!zP¤!Ea4]I@ L"ya soQٟ0U ?IǓPo0]HqHpuػ*NDMKؐ 2)҈ .$zI&F[AJ*wiG rxK7ev;nI!8g:9,5'e_`LDwvc wGFf'3-tN ]M©OMÉ?yVǎg0_yEHQ wƻ1HJV !oֶ l:ws^Y59R`IE6j5cԭՁ1=sxal *MӬpB,0F-11Rw3 uviР$1c̼mz Ԩ'TI&d2H)t:57 )jp Ux/G%k9Anq?JF'j堦3ϕC橄AZl'f8b0Mp/ &te4%zs!CakIԷ3o cf䰤n:SL $ؤXV>KV,)Js)v`k6iM gg}.9 nR)!\>ə,og&CGrhA)O1])N髚C/QEyL94VQ?%(~.q5>d;5j҇bWkp,\Nv&@:rzQQMb`DIH&O* ֠ꪦz(س@6DL6n|JNdN37ru.bR2ɨfĽBɶ*hxEM˧lA ߵwZE:Je^M fl˝hΡ"ae 띍C\qe~6t[LzX"IJctfsVʽ&KǓQY6m~lcgʔ)©9\jDͰe~b4MstD1OP5sWR=c}MXv0*iƂ᝸9=Еm8ӌُSAKk9>;DUj~Wѯ&V4pY:mFVAŵ{v!]xӖ9NP5|'aΰTyx> /K]d{gszܮQ6%@tw_ZS1=x+<4pۖ1F`BǞ1lˠH|DuƑu֚#0N5A25.Z|c:ES{,U=fG¼,ևlNOإԔHc73e$nPBO&&P8G~e/dOb3KfD`Z̉7f sQ O*C^ }}Dxf:ۚ4-kEFRk5KU"vV;I+)'f|arhr$9h~&`#WdtN9'Ib[WӐXrc\s$ѳv,Ѭ/I"sXÚB|JŸT%SҰsK!][Nc1,Q׌2% ݙ윝E$h]+~MK顑Aщ]ypw&jSœ qT0_tJ(H:)#4p*E~0qU5ٗhb%HF}R= 7Ѯe%kWP;AB+ЌzҪې0r#ϟxPrNӜZי=ݨsח'Sh)i~" SOR̷Nƙe> ,fȮX^ xA8,y f%L9߅/uFmJhf)y~,>m˺fٖ7N|8@ΘhݢXOUQ[ #bZ %'GDϊkZj9%tZ*aYIwA>|ɼv8?"S#AqL`xHeFRPw) Lܭ'o_ aao ivՠAaLJ 7YKN|Jz{IC0%5 = މTJe*RVMҏ0.}v4ޭgS ҧxa"ߌ~F4ˤ]o2EOvs"8`w>CTʠm .3R vSgFWS0}EiI|f!w"o\RiMBtoAF൷]͙0v$O]b!q쯣n#[9@F=3ºJOgwJU Vna|2Mfr8$>=/ߢmB;-#8+IT&2p"fwSd g}a+<ӱ♖N|."chfY4Odtv=ux6ą%;m͋U4&~|V O?? ]qb[-@fX~=T$Ix S\~1avoLXlJ$|W%#N'yM%%l}Y&0Ƿb>CS⼶{ߊXڌNk/VCI3 *'by0/s$8*8Fó.(0cvIHٓU¦\ 3QmBÙ 65/ֿug%5Ń.ic5:p6s{]X1ȓ=|xĪaw(aFd*(4an:S8NKKGrCf vq`ͻlYDNB*W˘tAtv::;V`S- ׬J[%E|tSmJh~z>Db>Ĵ>Q4X8M .ʹZKSUPD:\I;}7eө5X^Aݯ n&dfF@V4L`GL 0ay H|I\kOTXO\4o4,;gR uznzԱxbN\\l)hrs kMḛfaw$pq!mdk7+l=kNaG;A\]Mʩv t6ُ#iftۃoP3 .KT嘊w󼋂~J7WUMF9je- )P'C 5fޮ#8N@`'ՁlXKg14_&R4/iREUAT\#grB+r^Enk5't3N)mkL4WXþYZo<~<H$Ȁ`BMaXdZ04n*}#hz.O@=)4sI;NnK QXG"N_w8Km=9=cNN"C2-.9|~ttvmyրG߅E## <֢^i'1D˻$x{s |xn8-EQ1֭ѭ.>gxh8sQ\ncu8'dY`O|6Pϕe7iGy[U[b#;Faܚ6_11={3{K ,i d<-~j Q"] )6K[%&sys(99=ӑ#hڪ MybcVw`Pq̟?4Nʘu\UllG~'1lk6V2K%9]Se,eH93TDFhXƚ .Y!۬=[1:1;Ɗ?kzw-l9ρG'Fr֏_^47?{̪İ2+=b(YYfN7jqa uݘԋWͼ?9|[<_qrH~;~6 U_ʏAlОNsx&,.(4 S2VH ο k $Mɾ63l$]Ws7+e<'ZzxdzV%q.!zS)~*9h*z9%WD %O|xjV7 8;ËgM&n\)fIRoD#iI<$/.f3+N c?')In8̞P Dy_d1fz^|Z&င}22 ې`92Wev%黻kgMX^2MFJ*JT W񼡂2vm)zx)i\ /bu &lchSٲ[\Y62)ldx.m`IbN)S ua̖$ogqU('7N"":<*/&P)5ÒyWCo)cE\yk:ݫTÂJ֨xn hDyZ=T͘ Ƙ[c5}FySם&^4t؇ѹ]0HzHrH$n|pGbL>9Ϟg'{x e܇PD`m=E'LׇoS걠xl ?(H\_k>4BSՙ~C،Éct{S;G56ՄYq8tπw2Δ O*+WOZlŴ\ōD^ױ÷EF5rs{"gb$2Ԇ=,ɚp rC-JF}]Zj/P[]o4Bb#>L>!\YI.Oe( LMɹ6S͓bMr癆uHl/ѿ&8CA5hy|CEH>(3NNi'NԘ'L &z>|/i oi+q#p'o}p$ .ɃjT^~a:7͋d/>d7;i8M$lפS\&*0ehWFz,Y8O?hP[uNH n#:s:8;>? f/d%)A`Z)05/;3ZO;2~JgThCNW]G/=LVFzo <Fiktᢣ+Cc~Ev\\DoWE!QL=U{̜e|= -7&q)lG0fXhƑY&tmNAs?/Bۑ  2|_edzFcbig{F`,ad uTkSA߻38g1;@]Zɣ_S)i`6߸rO$h[+XQg4S젒Ob޿Aۊu> >%\|ەҷgtYjآEpTʚL"ysǎnЭOs<>{f^?%t3,ܜϧ8DHƙh,/D2SgۆnH'}[R ˉr&u%VTAbWԶ}k;/Xp儊Kg`2:R~v 8lv9~!ɈjFQKv=: u*.ȣOU+1w!ZɟË́ߐ=39?=+^|%D:]6:뙼H{3Nv0:fʗBS0+C\AG T ɸQL\)s39QMoE]ڍX:tJ<]MT#;%\n|ŐV ;it D3fmIΎQmMJ{eӼ:r{Ngbl,m8ș]DM\Ʉ:jZrljh׉k~ ߮1eQ {o{=dnͮ ؟wC0ѭyP~E쌊#[i2&3E:<[%Xjn.[>ã:}yeAP6k6vp5$"88î˖qLE,O1A;:Hk0! -᷷X `fti娚USYɴ.ZW%jꬪɂ2fTUE, *N~ ޿JsG*YԔQ#4TydU\ٙ~aˡL0)]aut9U#YXљ+-#G8>m!ЃȐ23硹xQ3 ϯsis_GJe*L˹Q³yXI,3PV[07͇'40B]/9KcGxKfxEegP81 "g YEلɗὢ=' į2FYUi೩ˉrf5Cr추hn K,c`Irr' =)#jr˸pB։ZZEw1CQⵒ/;˙yBg'Y$GpϓΘ[bύI`.]1 .Ŀ1H2HRTYH,w yY,c0B*ZVtZ1@J@v|-hd?͘XsYR__+ݽ) :AtL,1""I# qH%<$L>p|&2 6J]B|4KQFG#jVQ0DR':V#iSH/\NwIo7cdT"Fc>1o1!d0iNԎ 0?zC1S)sw*0T3z<]^ɏ ]$S6[Vbgs3 ~)cExٲ -~j.mUJMXcJpYSKԯHu=E/øLg{Z/B$?FF_" -N`( J[_@bbIIO rqB—#bkGc~ =1:PQoX1[SX֝/23~4ލ] u "lr/I,j~2}Fs'Md?3h9ԍ[{p1:Xy7ް%.<4̃԰?x)/xH& +Z9½.\X(zʩ"'~>7xJ1Y`k1}1 %qK.Z+,\H8]PmGzEM'':EYndKd0NUD(ev )?1G* BqblF"M^JlU2]Vq ΅UvXM%.E?,sꅨ}_}e+$Onuklv-ʏjM.юk1*s8u}rgƗ,?(ei)S Y!aft* J4?YaL-5Zk\k5*d|$vԔT e @aO׵pSVl3:Y2,s)sR&v$M6ܸ2^S(枴}' vڮlݒƖ50ܚ\oͥ~z =Jg72?i{Phsp?9a%c PUBi1ͥY((^Z̭SD'uA-4oN>f=ÜvW0ut\t^¨;2~b,82m6cYB: K]WY&!)6,gaVƋְO![1OP 3` 2C8s2{fh& /U^жf ][N=}0O!p[K$ Ru;X;+dzz[k!HNjC:wr=W i2&*,*fQNE WPr'XƘ%z45_~T)5F|vHb xҞ:Π[%-[R_eɧc :[9<ʁ<&3cw~+ϥ Nkwp81-ʪITˡ"W#LAWёŬ\BicW5PqJG̍dEz* 'p6bb[=0avs\M&۞y4,5a0nc.EdLc.O:/1#$tdN8"^|0иLw :UdLgd31OW6ep˶$SS:\M\ɬ |F(;'c@\ ]y~ -ޞjͩSHȐ4FNr0[./n^|CC6Iل0oK.;Hl5C2N4I `G{G)^]{䬶R 5)q< zqSkMˊ]Z ^̱?y3KDwgw dsh.riz-6ZN&^Vg3}6'J0äUKX}TqgR3{~hL =s?x1)\.Røm*Sr {S-qZD-=J'Zp}G2˙? Y*X|zTNr"ZNV 6p% Fe׳hX w>)8PAP:i3NΟk$><]a&W;pVDXb{pl@CXԎK-O ö<6X>o6vl֞?ym-B 吿Bлٯ⨛ (!qw&m+ۦt&KM,vNbJX7֋=+Όײ.5x'r5'9r-x8u[6@lYBLWƥ~fO8 y.fO0Z/¹' ~EmE!*&+NW儂gJXT7BYy?BEjd^ $;ᤔ!e$G%,DZFҷV:;s{+JfK`x|"PbV2- Vss- /'SbB󅹆3 G 9pI=0 S̋b\u%,$ӛ`ZdNP6JوL|i΁,XuStn_X4 {tVzg7seTm-}hlbMKY}:~ؖrGuѯY64%)h.fG&Y%w;"wkӸ0O "+]x.i48?[GRv8%H~J1՚%AV<\ !!!Xa D mCh4wq2g2XC)c:cxZ:J)3햒2"fxp*F8h91BJFcRBԪNj+W楥.\fI,4K%T#.iGE^;NCZb,,y5-3rg'"˱/'郞S8 EX+~B9qbwSμ ~ r*CdrM+i'ql٬yIzNqᗎ8KƒvEJ*x)Er)~]¨2iGex5OwLhksM·MhT]^b~Dp.3z/LΝ+@:u5|RbnrdiEܚ9Dsy?D/n\1q5SfR~Ԕgs:wbn;w1oH$5Sy?H6] ]/0彘fzk:&걡\s'?z$ϣc1C>.bZ0iO.&r$E?+c9RLC0/f"o/ !-ݢ.r㳙܊ dƎ(./ EB84BX[E!R)1ϥ=GJYU.Hd&ER[x2ortoȧd zfӳf.M^R|Eb6֒}Eud0)acU# I BsjYlFٺh#(?ENausSh=#X.de|QK.RsM*2T.++ x\hM1CG-Zɚ*j+y]w1xuVɧN 7+bZ~>o;pW.4̳ItO }Zm'X䜖d܉ɼ1Nȣ*;Xn:ZDnagqmf;-+, 7z@MmgTp\ 1%eԳWJo-um9J|SO}l4"=,4[hē8s$w۲y0?2yk777@;b';Ct1*Iq Z%e޼ 7'd}}`|Ĝ:͍ n$⦰;ț #i"~Q\xK}UO8DsV$of[$/Ⱘ̝nΥQ8HE0Ith#)J)*B>/ "R^\ı%^[J2 l.Gd_PR 5V1گI19"%t[p]f޷,mq'1MDW2\S2v+ٹ@èR?xSP ѓFK隕Gb.T2:&>1z#ѳj)ߨ"On f jfU Wsnk;1/֨9MLO0QQZƝܨ f[_ ͎[c #EN0~Qi] CؗL7 f-#vTYʓB(:ߒ94syo`pjlci~.`^+ďLϯ35+> ܟD$Sbʶ->({| 6Q"v!YZݑұڗKa|E׵qTg%6 )Q͍ D~T"ù^Ǘ.mgq-&ϠzC7rㇹ3`Dea vlGZʡXMgKx0KK:+w) 2b'Rb0zK1e)fCOl-ÆBdݳ%ܟ@tt`CsY 2x}5R,g||Ǯ~m1v"o,%cd)‹e%TV[ JM5?qeAyHA{4Q'YH'9tٔ\73x2t}X{; 91+ [!vl%+6)/׽|Ktvc',\)?ʂRI})f ӰW^d+=E1JXYΑ2]Gc-jԑu\.~E6ߏg;əfkg΍ֽXz6t\6w^S'9iׅWF<㘐1qv(-NT'#60cж._e5{i| U&i3?٘@80')O)ȜL4Je<AD">C'4wNsd`NȻLvga<ڇ$9Mr`5SOO!&L95]8/*L/'df +8*'b )y&5e6_ӛAGLVp|Xg+v 3983w%L~"lL`˪Oy="sPDxR1[SSHs!ET+⌮dnAEh 'XBsX*\(5URnο!Ê>nrƧ]@ ^YÊewԬWLWm3h<Ɠ]*j֪<6/hiϙyR'JIJɫbA_?45M]WL`Г_IV,_RI{s=bYsroMm?%1*6Fh}Ɏ޶Vi={#e{/v'q1ٳcovZo +ksuxAQ8 ?̎6_tqp?$[ө|DqL Qw ru&p$[˭xj.1paI8NYdnM4ڍ]+҈;*rtNpCD!dB$Ict:g$V90vM[c,9ݍZ,g;S(i9}oԋ=pet-{3C*Gss^d4Ŏ%g"Z6zH)'q\>S8$C"ԍJemR 'bJX$vU/RD*vrFD}Zb>&3 =cc{K#'ss'`퐃K\K n-V1Y˞kʹ*Srj,\5IMp_>č7,{3{25םaPߴ]\=6i ٮ!bZR{ /t ~3n@Cɧ8sl#QxvF7W8jS_ԬݛĘ=靘7JH1)8۸RX#dvI%T\:Jd~$\,Gi/v11ReGP}&Q\wq֓q :i"mLE-_IMV1{ynJ>Rb=%Tt/'6/:>4Mcugi %^ 3IjC9a$)n?ٿE,u}mI=+wb.,*ţU)#z' pV)Vӷn ? HY]"fN$RߒrwG56p_^ɾCuy* ~,yrl>ЌlGJBUVDrPO8>'0n4v0յi݅=ưjGѰ?ɡd(E??^l =!,*sSrLwj"#%W7 qEKk2ݎFw]=_ȼgWD8q`m*2,¶|is埶Ww0O2u%|,9xq\T~9dk3Rօ91-yQ*=X{$%2Qk{0q{#9;O@Q3хM6Vw+V*낺{iKzӴ'mqwwwww8<@q޵;~y?}ه{&j߿J2I\O-Oi.;POZ[X]q{/gͱOa[/"h"C830m鰫%(H0T rUIF%_*i*JzS0x-zKK59oQ|A-)Fm'TJ'fe$[=cw*Ŭ^=k|,uq#rydP-`e>*g`d4,Zb)]Ja~<vθtb kƎCp7g(cd$6(0S^bAVQob5SiO5{`^4I&t4 *Y5Ù44bHO:Ŵ$M#8("XRqN|bvH[yfFa0uԿ;S-|}ntmUT+4̹[`tS[͖ NM #ZMIa,myUn3P̓h{]$#$ˇҊX`qWKӌ4)Ș&#s;ijooqǑO

3%EmW3b`}ܟCh3Cz07smQV;q6o038Dsċm#Q]O܏l-b<޹ObS꺑$׋RpK\7RqXcB{؈kIzLc)I/rEcdݑQd4wu;>͓v8z><L. R vM;oåߐs\. +y%|V8☻FrVTNLWNx)󫴐JX*t)?!WpE{q$?aqofKbEvgW`Md<*P_;7D9d_ d["tz{/J  ;oߌ 7{ԜoH96ŲK*xqI ,'2_<|'(,QYh$èROI`w9F1KOJEKl줢C-K(T.=BŁjg`9ɫިE<ܔ䁅cTEkρIdz#W{q4YMyyk42#уLrg}'S՚cecܛtR'fzo{°t,t8׮#\'ں˙1 %mWArS -2~p<|Md)ɬDXo35#v06m?(8 UV/[/)F%DB$cz2^eU@nt fmN -Ob*?r&`R$~HN+AKvwGX]ɬFx1A}_o? FRTʦh%MΩ@nrnjv0 +-+5\&CS7e<)CsgL &j*Ui5USPpHƐxqG"d╞W\&Le$RMX]r5[icN%c`F~5Ny<-'NPj,G庣.rF{ѣܙ([?^tḣ!bFҲ>O}5JכULi_J{zҞ)nytkعSEr9q1ͼr݁mGΉ/3Yś nٞ ?FSC,l,~q}bp'ᐲw5?, MeG ~#SqO)!yԴYZPYFyf ?$?KQJ4(XnSu0)rh6BqXNbI|]ħR2R(7a,Eb;WΕ:++IvDŢE=\QbcR:.ACzEx䁢Er^kGKb-iQ2JY7= <"SW:w34W+eA4F͂q$_ƹaßiA5GyLo {IAtenj;bWgӽn$WƦ2q6&DO 2e#hw̐NcǬ 6!zq+;]8eI:G3Yo˨.a(V؋=>[g+"uB}r|NUҨc5MxkbPHUb/'kgp%3Pv{=\ɞmFqc6n%b!ln~c#TW2>pp-'k?MZ6 H)〷O :!ga9 VPKA54-| 塥]…e)e 拙WB?z2uwV2\Y|~L0a'*\(I cZF%J)mRŸ7RղӖ\oK7BEgh:fxp?+O1WWy >CZn5QV#ZmD/|]eJgT_ZۊsЁ)Z*wbx+Gə.ο9B ))f5oZܿБoE_ZqU{O}! 70t;Mtf9{瓉|6`w(|X*x1z2rҏ#nm x؞+t`$?ZFӟK| `kQcD{~lzKB8ɶu ѬmOɖ "'qO +բRsӼAQ5S"آdcL$2s,Yg#HHW_Bl8~T4MjLOē͵i3IٓR^X|4qj$Nfcgɱ)ǡ2lQ$1Ik9*_nC:9dd.ur>4g?4kTJE J][F$9QJCtyy*8b%%Ořrw)I(XS}E_m=6F$ T6&rjQ^*jبhJ [V2OZf[Vqze%fUhUrAzUnZ/-%$mL$cj@a~)#yo(bԑ.bbǪ4VIPVo[;wnFcn,udrCo΋Cy̖-R7Nk7FpHIJ-H kj}UNju;iW2nNmM(9JI7 ²lM3P'LFWN8tt/f8r;j,oѺxhy(Ma|Ӎ+/u >0BߒFJԬؿߤ =7f+kJb3K߹>KYܘ@WADNS2r5S1!T`k%k PlսԜnd#l䰝IWzE9>WDNp<]GUmURT©B"5ekU4|t5#0Ⱥq/2gl8g)!2C ӧ85I^͂6y *^yeK4{R͡5k4c}k Snƍt\fncIxn&n+[&R0ڕWo2cV#s^Y!_C`6"%r8rNNۓā\L +|oYb+sxNۣbh~d-p qH=_' p1 #3$b-[f!s=~޼snK{~vNW8ϯqZSyRENt= vԉk~\ M PZRtXNkĜL ef5Liߐ_#pJ7-#.@<'\vTX`KA9MLV0NK~&F,5wj/QrVΫerFQ/Sg\%kc 㔊D5^*hjQˈW m9-exS)g!9 8|0RYϽ^̺k"fr}oy`K PӱDţ;*YOej³O{xA[)5AXgԌy⊵{RS(ٜ%9 |A 1bX׍^֣9ُ.tw\# ]ʠ>\jI*;^ȟvfgc'fSZ[.s6!|xl8Oe^8 w$A&Q ʊ>ȼpɅ!0[re2Ki u㦑  gGsO2gn {SS~r 1B9n3gԾ8Y7}t]BEj!եiwF~L{.nV<{kwZ\CvY坋>) |HR*i`(yn"fq92Si`,G?@lim]"?MC͕ThDKrƈ+RRܶ^#d,١Q[T\ n/X·||,ᢛuW:vi)\bOklC+ŗt'X]UcZZWr`@5˴U$rp^O4T|%̂ʦ0IY; 5|Ylt1oˉILXLp}/6CvٲAFѕzm\quSؒfuvјL!fQ7A hZẗOe0Nrww^cSUs4ލE4FUJb#'i4q ꃦOg+ed^HQbҪ1ۗܟEwpI`fHX4`4U 82 P56*@27!} ^NYՂϱ{W;ͪ T{q2)K  -4-^G`y& $*)8SXk&!Y>V 4Q}Vk'1,̥Kii$d-fJn}";l\-˹[8NE5_uEC Wji] wt7Qz?5DRQ ibiW|-r75Vca8/."GKG#mXEӦը#(e_:Nd9!jf+I/VW%-4H4,z">׳yXf<)PL|_5WS]ε3qCׇ?_VLHw6gzpl ۶Z0\գԱ4 gw2MlWzj^ 㜞KK)k џ %1M`j?>gr bK8!i bE&X0f0'q."}+eC!~KĽK859W qc2:ݗSgև9d25\R d5af%)U<{Y*tD%mkt 1US㐭I UUVCOJ&}SrZ}PS%g*FS掆b+GU -AE^Z4qM.٫x+4{$|TbZjFTSKFR¿y::%2++-CmyڑPA,1%WZ}Ʋ*Ve iы`S=D\kÊ!9[& F~|ˏ3%C.78ڝVt Nx;bEv+MksK{0kid3:O#t(彵k䩢ī̕Ex ;xԃE'wCX8-3V 37'#M:xܭr+h<-#X1Mu[qlPw{~v`>'bqW'?x<_)n[ckd Nf>-ұ*F85~ Ԕ:~QD\sx55C5 6S&뗖4$. -CtD oU0]Kzn>\0t3|ԕI ('sd~.<%HZWг*ivVˁ.VP}K] 쁔62ʼn,PyC 4eKh[c,t&Rߔ.xw/3V\P9;{pUKHWDzgW1/t $6v|8C\J$S^tu6`Rֹٱq=ɘIQ7(KBQ6&s_ liŽ9&\-u+6b0_ZHRMxt;aع`#p!L?T,.%LԏVHߔi)n)4)iBzO(oJ8NJ?Uf<;Z} FN$#F_\=ƕo>OYm`^u5 jE7PVҠo5i|{爂jz bG7 U3ZGUjVRSrDnk0kb&uQ㩊?{0{YCĹ QYJ@O86'g%2>5?(aBJsXZMc]+GEu,jYHzF>NgMRA-~Q+2ܗ*PT28Fc3 !ù~uaϾt9ޠŎfן#ch8!t—C~@ &eՓ<{ ݝ/m4kf8I:=m8[//l=lh~1'ʋm$.oˆ{';n[wd"g(:ILlaP3Lf\WVpë{ƍ YȀ D—#^Xv–V͠n ZeLǙ +7=*}5u捞st.לh8ĖGuTL=K,س92aGsjk$Yƛ^&DFS4\JxpBi4-E8tW쑖墷_CUe*FS*zWF 2XL5M%r7`KE(ewq 0򩚽+)?TgE&8gbHLa|lX[c$/%cz;4Vlz4Uj%|Bڦ{)O͖|l(_r6W`^|̟S86*SiRoeCqc,|лޠ˷vM7J̨YFQ"ϱwx1+3gO nsh bLL:hh'0|?V1Do3֎wtdWpb"{:#Þ' ؖ frR_kb(5@o&?\ѫ{LZ Ӵ-O{ڋb&#_Xb6:ϋ! @&xr4VugΠ 1gqm"^Dx{wԔӰ$ZEmkRQm l/gPWXɹ{RX$r҃5aO~dzr*_QZ-mvkYzM85\'KqxB^\ۢ@7gԹ]уb"Ҿۙ<&?@J{V#Ζ 4#:Omi\ϧ$]Z9"o4TՑ4[mH2Aı,a|ڎ]_ZPONgς޼>q Į-G5] ),w3(ͤQL# Ӻf2ԓ?X7 H7 DX^b[NeuN6dX3 ";ć֩~̔xA^d9'_ )c@[~nc ϰLaܓ8aj7aȸ¼ ii’S/axᝲ`(yԢnb~:ߩɯ;, e[˔>Ci6OteNh̵^,-eKN:ٲr+i1vFҫ H_FH؛2nr2gA@X+nbH1qXM)v_cptf3Z0u ]tA\#2*ۈ~PLҧVr])cb:sPF?9Ɖ 'pyc gLwbcF䂆 |x_LEȇPWjᅁHŜ9J<6čc>} " XǎuGөiLAZvwča^x`OOfV?#1= D~G?<{y+}aPGc=2R_2{u?y}_[Z7,T aI̍>X_. v,9%&Xy-n4E~| ξHJaS.E"\ mKxO>(ɞ Ptຉg1.~jl(bы qTm{x5Y:K~w}(5Աk*-.!cU69̏MH W>q0'yD^vSBU ?Em.n_,#N*a.% ),Ӓ.T@ 9,##h,jU9n'pL,4F<ȰRbr7ְg>UTE;oN^za6o οLsқ&|WCƅqby/r=LY۝!KV͚ݗiav>\7 $VyM+b@x Qvr8qN'se4z9%'f-yޑ02_g3ݘEA|}TmZD1I~|s ~v,,b_Qyߏ\Vg gQǪ&,(& >hp!p3JPAA5u5(OWZ(dٴCO hdQ(g>K~ɓt KasOuz߱ p-d.|J׬gr= 4/ǻcf¬ϰ :vfkNe_kyub mOzz>Ιyn2mofy9񢅋 ;3b#[Yr`Ou؞϶p'O`CmPsԥ})=w`&몰k\ADLk}pÅz;Yߛ}߂t 2'ec=5\Pˁ5\/Gb2Z&Sgͥ ,IBa$WF :2/t_S@ܹQZXD_x\W< 5mtcICO `hZ_ #з iLθcb ߴ!\J!aЉ ܳC ɫ]0rF#݁ Xhϰ̮<(&_?\Zhx mzr͓o{nLWlaS~>eyV10gQeL?H9[YZ7_irsd{kܼCj ׬:HM f*mH'{RQ:EqV 8SuJjR-Sj,0C0ɟvsCʞ DJ&0љXC|&,.T*x3x,WX2ej:Vkm_!1zN/OZ5o%a4bk0s|8U|G%ݰP4?w#٨pDCHc2zPz5~'ι,6G~ܦ3Drxl"t~+\+ˡE=ELp̈ |@سޔiFl#q&Ɣl/{+QDzcw:[)+]i6=JR:(kluG]#sfw@.¸Ϋ)8x SEM%㯚ŃEOϱD'}5TK1zI8[ĢW~<8Dnv8]c<8Zi7I+En*cKT%r*jLVckU9 Tq6[lL򳖬{(1swY_9mIZ(XX,>{`\~Ír7qm_yݥ;KCJzseZlK"ylkf_g); ¯'km*?_'{Lnl uP5cs3ǚ3}0S>6enNyfnޏhTbDGk lܩ͋ ]=ɋ2[rUqԿwSH=xacv$ _E=_W>o+7).xG1qutf˅=,äucqQ{ vU20o,U/t,^u.)ðOeGS?~:06ߚyўEQ5 ;UF^9m|IMIOGhI/ʥܪц5ˆ )stz7E` ˔9N.i?v!#oqϏ1x֝yNR;2*?.6Y`9&tf8n@B#ߴA?ۇaB>-̨7ߊ!7my%nlv>\D\,y1IYƍbq 8'R$Ixԕ#e@'nKb/reAJ"bh&c ucZYndϮUȫwh + 6T_&ZKlNZz-kx֓?pg("LbAtû?vc;[^A|Gxk9y-aKéqLNrbS'5i<9e_+3嚧s?k9S67h縱"݉ovL q"ŗq,c2UKo, aRm%u9cFWcѤ2~8Kf.ak/5q &k$v OϢ[j,mU~jyYegs (5e]&;{d))^œ1|J;.ttGNLJ{^$|^ *{bvce us7Kۢ68{뉳 C)A)UxaT tBoO3NԦ|&ht5Y^sRa*5Y|ѥMc ~1R}0.z(/S6-#)XS"PA&o̶|e7p'Ms;.}"#Ƹ39Ϗsz$ΝRy+3JZƠS2'aaX_d\GnYl+9ju+򭬹__e\ʙ7#Yj%o~L&7́RmIs3{h%жgsg2 "sُC\Ӓ`\!Je#YQ\I#dmǡůua+#]`f]Z.$8$v}ῄOUL{3e=T{TH[P?Z6^O,ۄR5t(OgtL 8aϫd~8.{drQl8{t =IaޅsݻGV;wΜ\/Iv03" f͍x\#>2+8g[HD,5E/se:ݲ]`ۙP&Y>&E\(!x!;Ry0 $U݈|[]ă[5aEd` f$r\/BvK#|•/~\8Fw`0"CIP&R*gP"} r#&c6{|s_?ފ+I)i^ vW8VHx]v*T4y)ܵ9ߎC\YGè{ 0] S:2U }OgmЅ7(J=~FR8H KFyzRgC1dzdY1RoZ|Af9E! 7U>~϶Žz]sb ҵZ!,ݙ<W,n*a`Z|kQ>e㟎v?ɻF?_{:w}>T;. #7ۊY/34ohTAw+4vw&=.ʔ8"KVesDMkɡkE mAOԐ9-hrSj叼oZ#֥RZ[yaE!]I˴4m\JbW8B s-f-m'쯑!'ˌY'|d3M&~Kv|w|'%C:RwR[dFCޜR}+EPجNiPjwᶨuAߐ c6S:/@y=_sm ˊÚS?Z_ˡb,                                                                                                                           נ݊MzƓY]n_[lw? .R-Ǥm钼k޵R~l:W:ZRY#{6)oRzLyHy쮲74mSzI2JT$G{? Ac{OP,?-դ4i_?ȓOm z(ژ8W]a4/ӆw#d "_̔<7N.L' owfU'7Nz.iD ߒo%oz@Oderw&HcRAƒMJIVC$n[яzI=f嬒N:H14o:9lߘ3s,[\7!DZȽJ=eO7e?)[3- $;[S B:=疧3t뢏JΘ>XdžVX<#W/{+<חQ'Fxq4gbs~GCIo o+g֦oFjYsIl{b4`Ȫ`7mhOd)q)lִf%K*Y![䪦{SnoM9N.?0S^tYTՖ7? GX;G׍hTt~!)KVy:',֙V),sm|ꭱԏnk4C\+toԛE=?,sB#'ָhRv f/K#BT心BѥfMIxtw䭼$ܳa'چY䱫ɫ5e~#:2S]ip֕?l -tUOڹxo[[rBă׀Uk]._~ɳ74I֟f͡4jʗ[FTU5=ּStp?Ʈv.jM6]6uU^|⒜sTN:Sj~;P2Nmga"iߓ#+z!|&A.g{3]Vw%ޣ,sX$[ڸҫ$Ёt:_6ד{ӯ˓w_ݒgzݗn\ Wޒ_#Yvf GԟX0=︒p;A\@EhyW+k.f .bC{ͯ^8`E3l*9]mkt#HV|v'ȍƵz. Q|*ej.۰4w~<7#>fL5vOM`eavL-2h}ds:*& .9/)Q6?;^2¼`>I.-ٌZ=/WqІ7ʶzם:$..?mv>gz,}BoԙIoȕ1<8 \=\`MZ>U}?-hI~_t B~04Ñ> u1;9&}tpo]#ogC?n~CH?NE3,/ؔ H G#_͸X߽7aMrZ]:O]YçŃmkdנ\g{v72Κ>T\`yIcGa߁]QEglҙ#l=0ےi+{1U* lu;7Ӗqiُc+C̞HO͟)Xh_C vØ%sNLjOp[T)yߗ\_̡Ģ3V'z݅L] #`fINon襪h0MZ.e((܅"5G&75ej1`r6E夒4y|)Q;e rwrԈ^MG8fΥ~h$;d}!9ЇZ |;ەr5M}bͪ(\pcs'r޴5RDUH;i]2e~^dK,'䌉? Uzb8+ځ,gy^r U{ _t»ƋޗcKܸl4򹮒C|DBP,qV~-n\Wv.\@T^YTGQE _Dy#H\;0?gʫUP3ӛؓ#j--lǁs,Zl@v2szc(A>#QyJE=pm'Fc.Ι,Vؓ1 EX;ѣ$LYY/݅akȞKCɅq,M<&Ea/[#}4[|k>C|ٙ̾#JfZ;_Mlj; '?v-X& +#'ϗPֻ$ߵf^ki}yw9xT2{V?JѬ0JԃeɊ%}F Gץ&64451 P B#0n\FQ^BNbB֎$(}lkȉe*|Op&^L%xMۍd®l l~8첥vL/Jݗ -p6W75=Ϧ iu?k7nKHnrg(cy9Ԧ2/8`Q<BPZ]ݎ[qٝ剴,(dF +, K7m|6/2^FsrM W?$aՕg$ܻQʕg5O)i2׽"i囈bBڟRW:Adh?N8Pź~4ًOcpz"4F87]&aQezX $9>09a<8˯x 쏵{l=ֈW'x!F5ErXtGYiQro,C'9D2/_;`ʈ{l0 ?v--Vl^e0~b±@n"B/W]0ʓ[}g1-''"۲)ے_FoQ|.ɱzA`R<6QƑ:ڑ. AlV0Ί4.յT6js/&gж-yFƷrc9Wy9ɛxOxj*W&U^cx8E3xJ*o;_Q5"P ZYӑFdOC|2>qs8R)oesхDtΏk>&pi'nS b3Ձ|hK#M&*KK 5̋W*x:磡4:MI WS[bj?Ӡ[ŋSm5ɞLFPdFf6i|j ŭ织 p?7fšSwʘ+%_Xqv%6,!ߖXakyKP )~QZ2oƥO9h8a_F d'\]#E\^ "}#ROU 2άNaz~vfcSCr{SgaF)LRV< L=ܚ4yzĀIEt"~8K)>e>Zq,ZVYi?qÔC=-] jmۜ*u>mrj,AX͘Ŋ۶_OpfPA$1L}p񡇙3ΰ݉̾S[m}$މt?/bq+)ٱD=f;= @Nvm#XJyq*8߈0s?Y>-ڰY~81S3dS&tU%uSq%+Sym,Wl KƯp=cHiTţ9cyrp K`uQiJX<نU;]>LN;;Ƙs^Kk)7:gB=RVw_5F=1ƞp( 'n n|GSmB 5*np4iAא_idʲq`]w؏=s=iO35dyKHmf8?H(N&o޴M^ RhfuF1T)d"`6f+\ǒSl^'gNj#.$.tJ~%z}Cw$b2*bͲ1LعŚEop/?)ȥkt7`<2|ٖ&~ՇuPf%{{tͱI-×{Rs3a7N"u0e Da^WeL|vJ0T#%CgؤĖh&(և39Z-2bGҫe^߹~rk) P$E~pUE J7)"MWmv~D\f@ʶDA1plmf)GGK*hdZB b=c\"^$wגn̘Oe;̠s1*y I]Z QM˦zqs^}N27/5Y@QOH`V#.; \iх>,E >9qfwۍy,wԖ(kp"7|]ZºRF.&G#-Rs"ٴ+e1F&d̫`rSj2֭P~+L2<AM3nbM0+~1)uci3L /z *!8E߻ vB0(q ßY9]'EHM~7-Ǯ2kQMZ\'I&ri[:_dN#K?AkJH-p֎Q7ص80-WD!zZitbx.u\x|㊺Z$}Ӧ0Ιp}18iJ3LmeH eP <1{Cm7f}Rdrb!slٺ$FLPVn&Nx40)͉,Wg7qhž:,Ne G7wpx}8+'Ep7'hJ@&4t㘦-#au|(X@m>87͠|Lg(g0͈P ³$i7\ʢ~" 8bX#KFP8'ͅLCs% ɘ%L_\IմkQWH+yQ&0aHZ^Ϭc|IZ̮PX:o/OBD1q0GJmnc"96&;p o[Žb_%ZLKTh9%]>.;FOZylJbGO9r2\qF&$#mXpې?lxAFCAPօgl݅wJ"X?7ɤp՟xʽV`8G5Q|br~C9K2ݭ[%a->pɨk _`-C&kQ*Y' 6,ͱQ>t ?GZ̆-BF[`?zØ]Y@`|#rO<ّf5^raJrX"M!JH#cv(6Y~ϥ|\bp!IKlS%޸zs=Bǽ1{≟`;L1?%uvЎ2:s]~0=x LhRE:7Nse'gh&[r/j8FÇ # 2G,yZ-4Z<{m;L mHs晍ί̎!YKtߠMړǦՔ 0Ͳ>L{w~ܓ]5jk;ȥ?hjkwna]x"xq%!!Bv۳ss###H]jK.\fDž#–0'7͆KC{KѼ?Yi (YDE~ԴY& XJmXsLu*}QO#6=nCDq!`> 5X4[Ixts$[ !K& G0Y3nV{+_1]X`Z{>ϵ~=Գ7-xox$j@1~N@ kQ\NmEL} $jyΎE7eOړrvJľ-φ?]r c=kz0/6Ltþ=ultT,(Y΢/̤ro~,X |rUǤsG"42abI?ܙэ{ZqbwlF!XhG@#ucEF;p՚ٯh7Z`=%$SK2i>M*&K=(ev5ո pPEc5?*6=OhFŸqq3Iio k(:;7Wk#>q~G,W\yQ=p >i;-1nǸz/LP OΞ0 /UƆh ףfG6"5W.) kݥYP7s!4FLA)EϢ o5E i:=1JZ#gB7ڧcb(!k58ōO&9s?S4(u9_iF%#HO3EV$$G( [&CZ8mj-lYHvv`bёќxlŔJK}hqҖQdnl0"u ZLF},lvz˘`&˹wjpU(PPKM-ʝ:kX6({ٙ؈+aqoKOR6I#kGlۏQPJ`C(ޜ %X /Ωx}3kpZ/ԝϹҺ3pg'X=jYp$J_Ļ;ek%`,fl)n٬'MK8FM_..%FӮ= a$bfѾ#\} XB]{PصuV ݩZc p$[!^e$L{:`FL癦ILFffJfM: E-؋ P%h4%wCOGC7bRe1DG´VS0a KbP\>D5c}tzΓ(]w.pXcx8ø3-W%,w0*'X}~=ޑYb&aJv$LJ0zLޛA.7:́Ӝzntl;+quMD{.82  7Ɲi1%Nye=z-s2mυQW_ JE:z4_Qrut 52:Z|[SXRCGZ90l: o)|QVN_gNGZe iA ݿf%h,rE&Qk Cٓ2#j\Ֆc49 )PΈ#̆*{Nvn'9<[. .Y=Sy_h1|:PWqyQ^R}?d;OZCD&2It% pζAm7-w{"'ĺ5 RD%4HGZ zB.tJ Z5:|j2y1jm%N$\/i٬yc7&Rҿ5oDǣ=cqZ`?Ɲd=sc Oe\_V_ iuˆ\1 _M($]}ca ]D$sX\ł:gIM@${=b7[D\b^ZF{:^*2(nIV|S՞Ӟ 9Rؖ9BsM= HqM,A$bL'a\_̯|jVj ))4\fMHނ×c4M+nO"=9'u!9{擁}.!pWЋ;w"Y+(,,lǨQ\ bw['? h(Y]~\uǩn.T-h tŮ?OZprQwu^|秣} b`+=ksӼ/ 1dZȬjS-Zx)uXIrT5k\X:^x< t:h˚pd8ى1~[+ٺHE_ w+m̅B/'+5a]HYCvEtCYfᨔ4\6ˤ=1t+ `vƘ3yR tXX%oa~D:ْ5T*yԳ0^StĄ} 9d,E)v!ƙ|1_)"(Wɧ #'*rSc]Cţ2ҙ:1|0l] ҝaq|3\)8eQgyNrϙПt'auYq "\񹴗r`o]hЗ4md ~D0:Yjn//W0Ź`2ѕM)c1O:rf 57~vjb0&Js˟ZN3h.6p贁 bbj#g79ƀh=vJW \ۡg-ǟyW::DꘝYlx0|,}O'u+F"fzS)7bX`$s&~ {sJX&J2/(yR M4o<[8a+xM) ^_PЦZȱi| 63saZ}NM>.8na"-k8D!#ꖱhIWZ$8F3Ydc>̐<2KXaaO{gUDՔSk>Ӻ› qg'*Ҟ2P\[9,nF+'ǥ۶-u27OɄȧrgڽk e'ڭb)o3i2Qs!Wy]3i"QqTnN,/oET-1)Zq<; --UΙO%I 7G2{(Dt:OEp2YݨNgwE2>+FOuzj3*#F9vLX 3;G 0󸉉glb]# ^b 䠞JQ,P>=V8V-yhÉT? op7ӑ }63Ժ)̜uQ"L&lIUչZ1lܘ⫖.zKOc&iLC2NZ(U"2S3]S˓XWSh=!{n*gMni,WL4(gU$hϩ_VC?h׻KuTݯg =tҒLѪ˙ٿ\7j2ӯw%t4ϢiDlpa5WzCEvͯԎ L$Mf-BR#vgn6]9ǡm$K E8Mg}h>Vz׽cC"7nq1Q%^ c"'-Rs}{M(`)IYsՔP-U|*%sM1n-8ֹ0d2#5"|zj"zHwAOY5:6#ZZP`{B2?ׇsj|Ŷ$ns6Cã\z ȥ9<e~lHpCӊ`P7ϹogpFgᚰWXf5= {ܝIjj- 8$ݠJ^[(!yo&o&$s!(!x 1Uaf>6,RfTu&-)'%]R7+::g[ ]^ZjC+=kѱ@RǁZ7)[ iu&I#KY* )i%(yX.נǶIrd5Va΁s[[Eh eT%cK9V1OTTS(ތv_y=}uܹ%5#tD2X0[`rΫ䆮 F?фW]32J{]4͢rH{:'V٫SU艿Dz/R|TA_oK۬c%tQդ8'wAeJĔpL} Ba ]V^rY;F豽&]ѻ<+¹ z0ƁAkz.M? CDYYiR"kZG%*>#<5|Uŕ?L_qwm | Q bl&= 1YX({-w?jI7ixԾ&&ᖤg6uAP{9ƅf,F?UEQ5 *]@R:^jEÉ? vtH7.̚oD:fѰe,]R 2ʰx(!ce iʧΚ\dqU"X" 0.( cm.gdqĜ$b%3f:;ˆ$4"f:?`}&G9;Pe+UqZ1k(Ŧ&M̛k&yt9sڣLLlc f̼7馑fď'~&z #ַ/ףn$3jiEp5:)V3xj[DZZmְBA T+m4]XaѹfBvןsK^ݪ]!tN6?"XD|Z:CnGʃ/q8!Ӯ5!T==շ=Eː=bXRy+|u̞jq[31R3B_3˨봴̕uRbnO(g2LT/30[̜gWMqjd-#5LjaRf瞑cR]XdutUGɗe*~w-Eߺpg W p ۑc\5:q_ol,ܗR)C(⍪ܶELZV"]Ƅ䤊>\: \V%2,zٜaM4=⟙4OM▥r`T}H^|o鴾»OMc܊dIBE"K+?jhYEj4YD'2ԭ+H`&e )&+_\ 8W0O9ٵy+P5+Gk"# 6ѳ ܱ2D"$#קy5O5S+ygNxjd=,Mip3(-H{,5VkdR#l՞+eLӝ'`W3^9)?"'hKt=ޜupѺv8 ׏C81[5%#בֿv{ 8+c3K1_dԘR!&4}U,-q~.&1f/ lj _ :K9%/%n s0Qio"?He-NqmL؉%=g`=MᒞOuiZ_u<T1~t\&20L&6Eb/ūLΥF|bo6k23Y$&"/řx;I$vT7«I\̱d:;F`:P1@ l"S3nG?08 =U>ytTDEh " jO.WGgqz&j"2۴d N̢dZNS\|eKd8*[&`)9dLϤHrk(x$=sᬊ*8V%jIP"j,R㐖CF&1Mg)_7&~LVJ-jZS^ʚŔ[ Tx(!jm c;X;19d.lӥ }Dm ҲY6XMP.DP+ߓSs'p=;, V5TK{b*ky~Zh-q(rx9<0>'嚹]Ƶ2k8g˙ף;MQ]tԬr])g37ElYÑ2~1񪉙w[ٿbƭ'$^Rp(P̲LUE>%)eR|*&GMJ7%>ksK~-~yR>>+&U1W)pvPwftIaUY %Qm~4␈l$.1Hz&еcĵC'cngD Ieqa&=H8P)- eRD+RFTͧUx96&ܺ"Udt:koN\7]3*1O4%26r=#\|\yq dLéΝZEG*_ߛW [78UWMA\>HұT𯵔gic8 8`  vy/@oڴbGyl^E!gJ5+KYe9-F>λ)-v{{b~ KDA~nr&q\aKqlWL]W3>\_n_T+?Tr_)c eV+3zSt(,#s2| \;evH)S5HˀQZ?[K1쓖t= v -*)7TKWh &닙K_BMɡt|Ogݻ&׍8t\+1t3S:|FTMNw:rh,EDݣ \۔2[lDUJ /ĽV6k榲fT !I!%ORRMWY!ȇz)ZA rkQ fǙQ{rZ䉞byΝٚ='о/?c=G4̎f^LaBKa6||_LdC=|̡@dc5𛚉|u>R39a3߁`}Vn),tmW2ڶjuY4BdwKbfm)SH*"븄w}]B͇j:(ӏ+WQMU>gDLb:7fh]#C>{d'Mg]ی1fb3r3Zb_u=_骧qW{yAO[-3_υY&F/[#-Y_D7c =9[%=uąXP3oxm=7 L'&o*>VSh VZ)y>gJ:Pq ?*8K/@W5ÕuVΊ4I)|%󗹸#?9~/̥$H"!&ۋX8LNh ZiOÆO::9{]^Ad/ke{[qx dCy=b/A[ tjQT9{k_Ϋ:3p&+iHz^yA>)؆^#92k8_[sg//qx]el?+l<-Ϛ'$Bd!9Ows#J2ᕂ4hnz.l1?\U&9SW; R4z:si(EL@l" .eAѡߔ9LCL_BnKZ}mFv3[̩vz1AG=Wp:or,WrL\A/r,Xn"gDCF/YNX^$tӨeЭtvț* ҽo41Z'qVgűkГR{F8  [Fyqçn .V/kVɸ!Vߖ@>%OqF DÓ&LUХΕHD_XƬhLRME:?{\4gz6N#kAOR=}M$U1' e^5𼮎 *JpTHIj(~xU\J_;z5f Vi-ػ RȦ2v>\}8;vdt{3^O)-ͪHvjqռS㴥ZjXRB*rdMD]Z9Ș_N2'I@JP-9ylS5%75ֈCegj/QSs"'BǀW:Z,+׿ijR} 5DGzk-{Yn!ccq/gr {"nېi. vTú։ۄ[P<7gD<̭3xo&o.T &,+9#DvFNɅt!-??`47^ݹXM'9b͗qܺGˑ48;l$8j6&^qx"o_lEo{PÓ~& 6=`ok@K ^u%zs$-| ፣/tLi&LH8M{Is˸2m>"㯭ef^3DOjˀ&E3\5Sm./zfSa)G&OƑ4#:OlO>+Фz*~ Xdk7Fbe P󭟆%ΐvp1EW_Gs匪-#;lYTBIS%gFPïsN\;Sj5m5by)o?TfR) |Ԫc>2jճx)&ywؽ62DLa4AbX=Y9M! UhXPeo39-+t3𶂖ůnjK37>V]i@ȸ3G^1a,&5Sx>/~=>a͍pw,W2x[u*wxωvti@& IoАii)¸z?\;'\Px߹3;U=0QSػǓv˴r_<Э B#rz}t\f eżߡ1AL&${Ldzn5Cg&[% ՕsgC.'Q!|c;g{wˤ/µcB{V;6 [nf4\$ Μ!D&,~X ,=SZ6_x{H#Vߋ߂w!oiY~5LX3R EK. VQyOEG 2K1ARvlb,A /&V(XmV^MZZ4_j 5kTChU-*RZ,WfzsV1Ow =#V$2*`pU2Mō*\Puՠ\>K!iY86ͣ )5BƀEpf'IrY$$İ&${k%k;̬QJ{%jN8v'nc>9r>n劯%ܝ8 Vbֺa9]h4mW϶!%M6) $zO^b /CtPC9vK:te z.Lȟ[n#XX`niz {{\tW'l-(c lf0_ZbUs왎>ύ_ƌ|Učf15ˀa1wySXΈ3XYW3bLݭ'nJƿ^6gR=ڞ#ԋB[p2L} =[|pΘ5qa]B + n=mƜz~w|$k@K|@`܊eO8)ac9 2IΚX 2F($x[1C!JaJ./A')-?Jn9_or S=z.{k%"Cx ,&M0SЖ%gl7>OW2f%vy*cY)İ~E.,$M|xG<hxF75ffI%gXFZ_Mll /4q+a,P{"c#XΑN]pbECْmK^N(6{0RɖA æF\\gWʛ_]&pzxj;o  k\U}W3'`UWtHM?O׿<ˋ0:?{MdS K6Fi[fb >.bvM9-XuD3&R\,=`F4583]ɑP5BE&*ѯn|,\6TK +)aTN8zTPخf՘'9Wg VOg?}-4Ȃ:GV:|YߊnIhspU0"_ڟrN+i >\F)RCsͤsq<͊9.B-d4^WPsb؈aس JZ`&wB{9!w/%=t 8tҲ X/Qҵ͊8LOi?kKfG9U44gWDEa׾B,p}=,G޽% 63R<q2$J=A,C(Mz͍X?ݒcYpbF:S〝8Ж1c ^BUʜmٺ~}]iĝ=mn4Ea}S8UsG.{X3@^Mc_Ve 0ZI!bFY95/fVh3ȞziK\C=D?^G1r/?kpmӝ6 MV{%,ր~wlINcie{>Wk<9~z!Ww87B3s..SU1$RĨJ)P9RsaYS%h5l_!? ީ"a.IJb_epTy׷ KBC@ /"D;AwmwχSuԩzyRJuzߺif&p-Կ}#dTwoɄ2FnL8(o,okzDn )6wpDXitR73kkJ9ہ[)CBg֎ug3'֨ٲa3'0oKJY N%\#j?Mg9 %N QR8p  ?_I׭=YΖse*c ̬6nҢT> >N> ٳ'԰֠x4uŘ):ȅKK㙥MBo`>CLjP\ʲ#)f$~E~6o p䢄3QGLĥgׂ465KX:0B/, Pc9,V Jyw$K%쒌RZez*+b1ߕ!nEOwd#@n)i\CU \ͼ5Ԩ \߂*=yP OH2P\=5>%z 9x=emݛCok `ZYCh:Ki\ęA.}6 F2?s1FCL?!sBH4aZTsnZ ;%֪/?tq}0~ji"3E2f]cH[$"ʌΗ,osN,ݓ $g"#R*2n]k7Hy 5Q5W׻ "&+Ul+P9.E2vKd5JIX.๔oԿ*b+E>7齰pasa,-d:퓍Րf‡4{~:38ţ9|ce'婴HOi2>MJ.'}!xoΥS.i^AL:C~qK?!QD&A"a` oes]3O jYLI1!sٞTήʤuEXҪėshηP^=d =Վhv\I,+\]UU%/D7 "CG?ˇkX+إǠiɂoyc M3Ґ3#.ZdV.Xg(YGT'd'bkBcuKrj1\w?#oJ@SgZa0ĐR>s3 {siUXkp0ᖕcoW ?h˩d.Bz  =nٽb(#FI8q A9;̎<ǖ YD%씕SJPE)XBB9;7EPdRK_"Cu# \&ה0,PFeԥ R0BJfI X'u~2Tkڴœ3C٦՝=1zޗY#Q.Bܶ m2CfnYu΄gt+vc:^DugXgMpGF(Gʭ:8}OkwF|P~ [5uhxzċ+K(nݷv7M`#SL_za?>t@[q>)a _;(h.]"lV9%c#֝Ğʐ!15#X]*eg,"ǣkd\WN%؛HYw2FT! 6*Zc9E~?Oz|}Fv36MٟdBE#X5|!hk0uA9tp0.YX"J?vY96,Z/aq6\ܛN46K2?xR 2̪> %3U7C X{-L%)8ٔ.>Cl[;;ں~6MaV,1czm*s ]7͖Z+O58hWakVSA'UPIpβ9/Ґ3:ãiPTx\]$IMجC.̡*;*Xfd#ܼ|Q$ ?9xrZQ VzX WNeU&/S:_NϛVh8QoKx,OCj#o `wg&` Z%$01L͝}=J@6\N\9K.(`߆ wTpNdKQ:ˉ⌙}tr* \1ճ 6,~}v~Rlx!#斂Jw(ZƁe|T2Ծ*hR|ZFRXυ?[-ޑHfW(ۥeQ._s`+qt1RH,R2啱]2)Y)2;Up! LqۿYU}as{F#14HCQEQ"#d!-IdI$$1.~jxY&u ۅ2uD+: XC4q3ObWqxIbۉDTtIMHjRߛ)D!65 ն LU(MW͌ۿ~KO ݶcw>>!4:%sN8QSBVIa>vam¬{!Dž%/e2/SOkM%UmEN|}] [\̂\]LBǝj,vC &Gj<Y(͍;gnЧyQs^{h ߏ Atz/|ߔmJ%#ACUEmBɐGєߎo >} x{ʠ0TGqbL, cp4nǣILLfV%b .!KR%ijR꓉.vdTۜM"`xZ獓h1z3 c}o EĎ.|Y6x?OLDyiV |bj^WRf]ʶjި0cR-jȿXȞhR_(0?˜G7-`3C+gy3b^yu8f[ϞVe1uqҎ#Aߤc<] YJnǚ}UKgˉLSŜ7J]NՐfC) )ab -%jktCܖ ' Bk1m?ѯ`HXNk e3 j c9]E g'bq2 >$Z[!Z_Qc7)Sh:ǘ&SsÅ"#b{ 򔒍6rfUȉuS0YcS%#t(#8rFtq]k'<^\m~-.oIx mq8eoWk&_jpx]6.}ޟZ"K#fH̀z1 h3]F6x~ëNHl@LJ4'^|db7>0 {V`IMtJ`8эXAQD&Fz}(=C?“Aȸшדmh \B+P^[dbK %g$}1W^DXٔ`K%Y+sxą".Ubޫݫ( "p CnՒ^V5WUs5Sˎkuueu(vuN&6&|&?E08+&1"o4Vúٻ ]G`hF/_dc`'g2vN|TƲJ49qa)("͈u>z<&ge1O.`_\LI(F1KA_%X۹e9"gD8nڍgӧTȻo9t+,Ӄ#ZB>L` e(9/qtשԷaeM }8kƵ>Xeԑ`^ns%Fd)4lFl s;6$_ os)Z@TaF u5[wW!fipdyyA[?>VU0 e۶xIRʩ t ?~! v7Y4gΠ)ɽd$;2^'ʉV̼YAk &s\4eY}g>ˮ誋Tspx-k~7/HWGVj^يǭG"vH8p>Qkx= l;{WK`.]tD0%:ig-e϶&RZհ-FZV59[]@|0G\Kg.23K™Qe$A߅²q,Zȟm~,¦MQXR~GxJİnboS4-W)q#J)kQn9;(^Q{%P.曵BΉAø? ahcHmF\g5mܘIwN>A,'a"8#>*gXeˡ<_5'_<؟š|$r vcf90beHL޴ θoFNj$.υu;R>O5\i2i#x/e0zf,Jݭ_5gK3;+_67s(Fbtx&i`Eg/ j؞zLpb;_QzO/,ڗ6X1zycOe1)bQT3Pc_e*J{ $.g g5k3<ɜ`w6lb~sɴ-EH#vZ$*|1X=.fQSJsn/w{pc3N'Gmy &x2מrt jRCZTkPE_jݩeV^?ë\ŬVMMrO3]{C,2ŵKeZQ<1[V ϭ䏷8gT1o_+>?F!rZ'0w0dGh1Bҟ>qн;'yo73R%14ܛ]8s=;2yF81PQ9mUQ2G*p=vf 7s:|I8/$GgQ…Vp$>V?&fV,CHe~i:.=3='"qun͸oy: s”]۬\cG;6Sh4=1K.~.#^pW1*zDu^9O_sM >VfAN*Ngo0q<+ GQq}mZQ0_# s} oy2ǾXw%yahzǃQTwN;_R RJd2TaUSZ8rG?yjK4XSm:0mZk0LQV C̉47nOĵ ^ _9.FNڷ,?2q9,*_RT)ҋ雓| Nc5؟UƏSøO $jFel%E>rg21i*?3Z3L<9 \MY J'nYm.ms$m-M\{j)2\yG:1i`S%7Pߺ.ŵd2~uYyebV=9Yy^xox>3֥n}l]y# J$ab(vG?($6%1y s{J->[4/ Ҕ 4gu:Kl&}pNtKsİmm,&(>1:Z'\yaaɤ!Zdtbs+*JUC]scX w{P,Z]٭gz/7E輸q~gu򑜍XX~r d): `rn˸qv gƨ Fw`Du7X;ڌSi4’:5ĽlMu{Y ĝIK!g!9x{2/sI(W؇ o~JVɸ^yXL:#wYпƌ ÛbtϢP}m"')gt<1G^lƿx,ˁ&(nrg9,ɔ~u9[̪ilC;N,o^Rn󇱔2꼔T' >0+hW Ʃa3hC{5,FPe`D8A\<Lq_#4/bM eQ:{EVEn <'g.\ jM.KFfU<+v'-(;D`zxpwUb:ޙ9h$N$%AhƧ2BΛ {}pyG s\Dx[hqfQ,)pJ(]9;2vKyYAE5j & cb-O3r X `U>F1K62;v(_ſym1S&T"$ 2@t NM'_"v&ׇ }b|Ѥ+'aJДOgH ܧ'y~wb#[{̘Ma\H6FMIXaŇ5S᝼[IKk1hn -k krF) \ȒZlhj5HfP㑵VszaN5\UMQ5j\8Q:@Y7ql+%JXY|6gLahs׃!NhcU H^%9VE]m^rM{=:q,±יWVrC.`i9{ Tc%+xL%֦2&ɥ]CfM_Ayrc!=sI wᢛ|~"g]ȿȻYLnJFv0b.)ųw!_՗)!,mߗ3H^ m#)6 ㏎Lq'Z݉\h?txpm)# s}aM2VXUʤgRex3UP"7Wʮlg͐Bυj_jMBwURaF7`v< a茋`Sp G#b=2xR s} -+%%&2|wY3Փ!OmZ&rk^KJ?WHdUxTG5qi{jevS{E<,`b$|BbS"[>Lpb)A?4h5,%xw~_(ό{$b咢G@rƄrN#/'?>y*YԢJTvb1YۓYǍR=~NLs^ Xԓr(NSugIQ /OLZg]$FnD:7Fk_1ۼ`jN FkŠ+M׭iM4ɲmˋEHXžn7鱤Wmh,#n7dxT*:bm8\^XnpC>* Ƀ 8s\:M~4 `C("y["+$Mid-!?LBөDd@f*ޱ*NG.JSf=WPծ/DnYr\YIKϢ[J8,%"듄Ǣ\dڜ = ao/?2 _4Ng᩸H,b8õz|G!Xg:,bmuzbާ3V8/ejSŒ*N={_;/,r wYrAAs<|f@j7"}(?Nq"ʞg1a=Qc3~/w`t8گ}Qê\`\Ȇp Q)t&b|E<_:rtT𡼂}ax|-|2I6@tƼ alZϐWʈz|q4gl9c,&S;kͱ :L+_p?cJ9r=|\I7FwDZ1 A'7n4%Wzqi݁^BR# NZ7 }jlz6VRO)s%$SXS9+yʏAwB'oB!|ǀWmеwʅ\cW*h$X)DY%ST{K0_(t=(^-|-:]MTr/fR#e2)-d.J|ħ-Br_$w+|ׅ.]ȓ!~<4LjL=<1aZGwK<'%cPs; /IxY\=l2lT$eBu􎒒 %1}\e̊v kj}5ܸVE+*vrVE~+g2>xLK'#8b .+ ᄜE2$INR|dR^W򭠂G+Xܱ'S<׋۫J-lkY5̘_CW***1ket*8T(øW &ob~OGtoNyLu3qoKm_gi?HԕBH/cUO W#u/H+tVBD1ܵߔ(C~MU})w}GAD97g3/zx+$(f A|&LtĻ$vIC$jpj(ecIK@JM<8K-&03#1LB°cBګg;o&t[7nGΜۦֽ83ucٓσ@ty̞/gc`[Fm<0"RҾnЮ!扙t=l4R p7%ֲnKӲ c+yա>S˙u !U|TϕiUa3WմմXÄDW!쑅 uy%\¼[X˲1mMo%deQJ;nUftOggحUJ5PMi~}9^"=¶,#fM4k,~ΘؒxgĥsSo0WW C/D+cȘL98k/k챦T iS Y2Ed8Ɣ f\n:j٧'}] Q%x/&ht1Ng NVs@`Lhu퉶87Na ?C!H2"r)3{iP$8da7P HIL@|Ve.fRLʝ\vԈqv繜^B;Rj[b^…zF?/5^J9񦔞=X <*d*iRC=aߝ iٛVG}dXيQ gi[1E &I9TU*񮒄 \ɹ\RE:5ɲj}dsj0QMUlX`Kͯ?eܚTBJأ*!C)bt\K.Vb@lzS%`W7)ZoK5ڒd({6N&vP&cxQ-d,׏yï[D ,;e+ŭb: Q5;xAEbϔZv֧ h:׾Id [Ni?9`Cv-q`N cW8U ʌn|?.MF,l`L8>chw„ Li dM-|gZG:sn;mzv7V}[/|m~Ci. Z ,3>/ۓyZ.ejYH Yԙc[pЕ[G5(al?DN珩=? 4{Z ~,uI9Sb)+e6KOO$Z'\F;'3x.X5+y4VÂS%UW5ȶP[y\5x\jFWQU\Tޤ,XGR)?sxa1%6,'gh'sZN&U8e nu GٖX/RWXgGh3hGuyh׍9kXmTDH 2FQ1{þ *axy,D!l<>?d@|{w5jW}EF3ưۃ NZ658<ɜhodz)z~,,ٲ]7.enL _| vи8?τLvΐAz1A`='Q2@ =e|9VSj֤;J 1 Ӭl4{R:0FD.c d1m%RRL*R͏bWZc$ZbF aGyuF˒J+;A顣{%r<Ȩd;p[sbmŇ[hR]PIq,Wy/<ҏҘHz)}#)(^g_l%YY}bFqiuN ۔V &3Óf">ӭ-s+8;y㨝³A)űr4"ynʴBr#5=Q\r ML#~_> /Ӕ}YNhmf)Mr(NJ)Za4WSäH% nWtLpq3> \Z|hhe2~@܇ņLx3[F,)Mdl2KƐ2v2{2^ЦA=>=.蘔s7KӰanPJER:X"#!hJȢzZZ8Kɘ".ѿ2f!ܺU~ ES.X#)J4S5&OLIgl~1Sr ]F\o2Crwr6T:CɸR#FkqDϚByMw!VxyZϧloR.mW9vIZK< Tr,SićFMɉ#\4~8\xHHﺒxټb$O̟_5O'[D'qy%B)ݻxRsm^qD. ]x9ʜ069Z1#)̞P>s0exZ`:0z(rLӱOGYO#EpRDz%jְ瀖>Z͐ws$F-=$ux==ZrG2zwLºҀϬ-}5 dxO[OY]-"lLG ,U)󖖱ЩzTprOGn{S*(O(|>+'S=?>89#Uc`ժڢ$}\ |4mqowo61_%'UحF625yzmR瓊e_2PgmK? [Ҥi]B/E_>{.:Y4kugl`.F]<=&3'?)LˍLNד2Q ^|bV/=9ܑS3Y!M|aNѣ ݟ&xz8 v.8: 0*zF|95Q}2(g@u1/%Y {+JC35㶨>0'l:+ۉ$%:2rx G}X +~bj?^b4qbL,wZշ;YPOW-椶WmmElvthHX~$-.NO TҘ6y4+{1|y1PчaoݕOÕt=7 {oj.b.h\7FAX#U2dD\GBy-,"}"YT"wR=@+bo[r2{'tV_^t_,1<٣c{5z(_CYܷH'FCr~0>4f O{ba :?O,pOD)c/$5b!!OXq[-e; l/zC PNJ1{`1?aa`^FB>:)P$L/QQd\Wtc1Lw,ȥ $hHANEd.a/Y>XۺzS3To 9o^\Q!6 y7FNu!2Y"c͛ˉ{5)SƊ@Ŭ\W.泲0clwzϵt.tJ~b`- I/r2NQ?7s~TNG홼̂0 9&^=PU<4rFjףWRL)CQ sJQR++aE7sg[x1I38p?ufC'kMFcS& '5/l}?8^fo&uT|'拇m9upF]{1{Vd)ɟc|: i:Eݷ o7w" ndTm#)" w&`ALuKFȦqjQe>ENFm͂f \3\`liهq*ۏ BV=13Ը͢z< KF"E=.S\;=2Y1 ;:8_Q?(9R@߫t| _r 윯gp^*ʄs&◄vR͑ `vG~d\\ȓir>N.nqnhPsDȃ\ȾtG& i.&OkzHV(Ø;7Ux3M?ȉ|c[;w`G2hXsyf$Q c(^W`eM(g| >妄C$D,B5tvQx/*d+e[!y %|8 !@*ܯ"!7k4E =rs̡g6ny|yIPMnrd]?k&Ԟ M]y[ߍiG1Z \lI|Bϊ.tc6-Ccɳb K.er.qk.;uuTlLv 6GZЦ51p̘9fエcgSN b[/&m^s:-Emc3B{ ɭ<̘~-8]v#h3Sk wt[2XLOm+cP7kqKPdƜd{QiuH;"Z:Wz1l]>1O=78NeOK%sdO߆c8ӊG:};mPf48䧨^}>ăƍ'frP ӽZN)q:_PSS lR$tB7ruU)W=b pk9ӼTmĦZId& 6PPM`Ex#IM ;lXLY-89g_"'' fMS}N`j]%oN6o [tC-trE"Ǘf"?2-e=S#լaF]f"{Fn_7{? +s-ۊ\{N Z\ ؃tnJ,~dؤE'sx.Koj;0 ;MĖl &1  G0>1^ג9g'k{zVIJ;]{w MG`hٖU7QbD6}xض#˾OD"ω*o1+ۘw|(Md$_UqL jBX|j9吋TxV-SEB߯,%#Uj.ǩ5";&>=f9|SsZ>}W3uϋ:69~Tz! G)U_#-rjZa^D";jOO"=C5埕:.ݔMI ac_Uޭdq=-uPɋbq[^ %? @C9"o7g*fg;MbzFXCA,NL['NX](3#ЏIFϞ*\`}l2C* z0_"m6,x܅-64 ;S'˕Յ}MUMڛؠ\ G_ζa[Y ֑ zˑ9Xq>8?ޚ.pϘ>3]Ju`)0S<[k˷N SDJqfGǤ&c~k_ܴcʊlHȟ95OjQ<_}i-e옿h̄g"lf|_{3'3]Cu㊙KO=<ӱmJҝe({ y9&qx"p1#PnH?>Ou'SiKo733%]laQ\$qȢJhСJŽp`=Y _󢩘wt+~ Ғ wt 6ly7~sgs:VseWfے!}R{E3z*d~ Lj<4T1T͋#*PacfU5 $^VrGs(eSrfX9MJ\sɑ,OMDwq#T\ (NcXBÏQXug*)AތKt0:&RbEF*Sw6您^&u'7w/z*Z֎%cʝx~>c+s2 E^9 )%N*{F:~';:07ϑ#]/S4sb|~>K$x $evr;Ac=͛C-fh3Jm=ǜM&#/SS(ɴdU?gl{2i/ @rGIO,|2)"x1&lJI;scfْ>+Sg1a:Vj#`Agg~wsP?\Er)L$ؽd8>C0㋷7I*"@{"-}М5WɿvRq"gu;_xͨz +b9~WU*t\)ޝi˥'chU (bfaM95CN5 j,W0_IyJ̬L+g96Jt^t3Q1O)}XEy_*bǷGYtjAlN屯S>~0I$uG;ޜ}.?6|y/:x(WxS_$7my@WZn70˳G2.η.!銁n4`Tb|x!> 3A1󪽈vrSyfb˩8mxw=pٞ!l*hΓ"wS el0+]Ba*p!c 5 Ky|ȋzs,irۛ.Bzĝ֋:{+j798t<{ư M帑 5;Ju\30$=5Â7]P< Ws~;71LA>1'q$]9w>nui+[o2SMh8b15H% qv.s=Zn~2sc> lNaUL¶JlP"?&jhfAY%;]}+.h@ƌRe"(Vf(U`99ZvӲ圆G 17{W_3ވ(i<ͳ` WjkyfR37(0-T,LK*ᠭuJݸ*]Cx?Ka{ӖݾzXM"f8ƛzdG4Wx1~Z$+$P}f $^[ۢiGgjrf)=8-0Pn'8c+6:spByEY2I/]0kf m%ilX 2$(Nfw[ hA[΃&ʦlVͦtD?u׹0?Ɩ#6ԾL=-OMLlc-tjiE:7ְ/g4ဵ ".E!Zsw?X"OE>xZŖZk/@|j>U}K.Ik ,l .4|FLU+B˱ zZUF)bKY|*Kᨎ:^>+榉-ɺ.%4l`l*IuIU/DŽs3E`/Wi ynԉFDZ5i[qwź8%lq'T&Ƙp2NvK+m]dq{G:8tu^קbtpt,'N)|[,"$x<(7 l)Lmލ K̷|WDR?WlμY$rh8{h-+v߁_GfTDg,v,S|:X/S?Ѐ͸|69͉vv\]bؘ6M7bvQi(V?) >MBoe6R _Zܑ&h`ňhVb;:)ez-fig"ʎ2gm1b'K=ǕnR鲱NU4mPƣETʌ/pe Y ɪm՗R./i^‚9q`JSvl`r쟕[[=çWz zvJ:DWxK9&ʯ`i{Maid^V/*hx={C)_r|Ay? eikE2FG!Z@mXiom66@щYGPмe 6fD&5&5Q;ğ!9w(k4+Vt#җ7Ci9}*% =ʹn'E$e5g Svk]zd: ,lǔ|RL=CWoǖD!8pV%^r+H8^ŧJ⪋йSYDrK8ش=*AJ\AJVкa9>ykSƕx߬bI$ϫfgo27}V}+]_;XşS4ӧ'd*^"+su7ڿ 2,ŧW!WQsx;:] Aqa A4z{&k՜tׯib_rXm5ԸqT|Ʊs O[r;%g gՉvKT&Q2qk_A]bN,WuHdL~X]YI+R~^\|6scX}& w>^/Sp/r} YH-'2XoQcQ ӫK˸pJ1-#f+\E<|:'SE=TI% (kYոJN\dx2b(ey9-ޗ[˙TA7eLVF2l^-\fP?"ΣGH6/.®m))|b_^4߬]eW?f%4[Hߒ<չeRư}lSNr AxΨkͬV46&tb.o˱7ϒoFgW'{,ϋ ~KX'u6b1p` ܦ,pw>xge3m*W|8ʑ=Mh8qr$$qmX6l&xbW_<5hSӈ[Nkl֭.}1!X^t'ejpgf>^y-:yx^-pL^M-"r\mpD6Nֽeʛn\}~ld7K|6cO\s> 6?(.c 8Z0(cA96el9SL9WYQNٝ2ð2R~TP9Q.A)S*VF<-#2&T0_%-ysq1:1.QDiDzu"SMv44XZJEOmZιL9O=9.v. ъPg+1=KĽ)T^拺kt0 s?^]͠OsK4[C†XO`S2Km>>؆x7,[1dCSFx״F=GōiQTi!mgPBhMySUwN%U=*-S#Ō;XFڵi4TpJ>]dJ2V5+&jZTqI^c:A)vVpoV^WfO9U2kz_TeȻY Laētf!'>0WoLOc]1,ˢHHJD&Ft?u)C2V.ς'{XKY^@Cf $ɶ;tftN;WhɂFx˓a4ʖt?:~nBoНKQEchŴz6Wx9 Ƥwglccr&,4z241TϪV~s.dGq$Үcº@Zt7fofT9/sTQC~fkTI[/+ +Cٽ3'D<K|wp-֏]́V,-1TPqo?WMnH记ʒql[À1Iy)"}yu+q/h;nOQi F\DS &FJ3AOKy y}|L> r+qV):s+PrV=)֠Jc*9XjzVXL} |w!g5쩷gY[:;qs6ASLOR4{6sP'?uۆP gG/tlGUE&4qSes{fc@u/hdOf,?Ѝ)D=Ai0 FS1Nk\Gָ2Η#UbƘX"t8݄£ZT+VW_GA?T6WW-kٗc˃vlj146TCr+[0Ӊ_rφq`6Ʃ/:S˃|?6 gVxgvNr0JY۹g窰CRxQq铩?}.g2., :z)IIba$As{1Vs*]yW&Ji6܎̩KrGrC,C?!4IMTTZM#^+8F4POGI׆,K!9M9+_;fጳc)?翘 VT{B~Zt1%4A(_cKh+\VӬ=/}9pчXAG&{r= Xɉ3H^Mm[1VL}.m~9+JWD?b)KBo^1V%.znJuWJi/_"4s:k3AڔQTBz^*qsԳ҅V ,}Ɩ&,4IcTNLZLrHZXD ɴ|SCbM VlbSfЧ^>`N}'phx GҠPf_nBV6!uڳ쏶 jѕ Cr Vc{W?.8{0=3g8r7s#VɴM `:f><> )a‡V2dz5p,d5ݓ,VV>RAӸ4zC˫CgJգ@v>'ۿQ 7 '6Qw&봱 {lL&]o7yxȇiKPL|é1Ws9Ȝ9妃F]=|6YlC`Ku*3ȪUo|j^*3hE|6/bB.+D~ 'or_洱^Ŧ[mƐ̏dŜl\P'/ Z`ɥR>DQZʱ\_.\*2YvFcQZ:ڷ3 `BLgswi^$TqϹb˥G Ix`NIüɘoc:oԍLI|k4afz/0s&of&دATVZ`+/f[ƢMG7aobX1ѝ6v҇?śM]@ѓ^haړǶ/Qy:/ĔN)!^Z)<)L2:jF5*]MQ۴Uy!N(lۣk'A&o$ya+]yDv$'ҶRdIP>]Yb=6|͋?n3$*J3BF\ݏ/bj (ФvgziƛQuZsVɰձPrVWrDJ&Rz{D1s[s+7Gٲ ,{aϐ~œ!߲1$49/d6{c%Ma6)zysZSUfEYc,;!g|koyfZd4 y}+c@A,. b1wVߏ)Q)}8H!h-uh>փ.ve'Yi׷q3dN NӜ=[➲laWs,%|,F` Wl!s_l- t9u&%q?@\z-& *Y!j#w~gC-XۓySXӂ65Gоa[>NNOG`r1MSۡ5eU4RƠ\)F(s ̃VeT_P7v6}um3M;< by"?ks~ WN|]yӅ7}4꿥X-"S;W~M'Tan"p&G="1uPL0=ipf^'3&3Z0Fp\4cZ9tZ((6uqZ=/w4KdS"'q>p>vJ1ރ\-"_/&xv Gq.Ԛ-]J圅A|4.aS9O+:YIpe]I,G'a?J W?7cJUl sr M(ͱY̭]gWYw1:x./btZFdXbw4(ߒLTg )WFqܥ-4b>{n`joJwyEї u(ȴ]{^&8L5wRзg-c񍈥Pv'4H!|l/}C>luo3X7hQhO}_6L3$7x܏WB9!#UOwdnUzćq#<ש1X eZ+gtv(Ia=iǛ|>d`3.;x ,wS!=Y6շJ*]s'2n"A1* L -HF% if8zgOZCrv6fG&{GRV1dbqtĢt~H@8|=2 gZμ?ʵ_ +fs. mdžЎ[ޓsɚF#…#=W>8wSE0߽tg`DZ4/LtJuWC:OÁtÚvs$/>aP>WwfnE!tȰn|H(YŴAzDz6\٪.ر5459T~!+$ . s59^bL gf(i.'ɼM'M6 eß<ᚹiN6z#)y&eqi.5h[]Ȉ:PEzz_[l[Ɋ!{Ɛ/fw+ƃ"DH^/EG GI;U.00aOz""{w2=܆e8J/'>bh勌9y?SD4#~{ݒz5o}5 q͜%_V{3`llXÚ,d4Ջux;yC>sg0[D=:qeDaV7u#+w5j4guOgƗHŷ)DfdqiC!{8_YN27lō,H|| iȱ([&ZL:/t\FtN.΢`v.E!9JիX2[c0G-cimG>``GnGS螶GW"h4TfP&ϿE qdX#wЮgCZFY30ނF,NLb{4bcUϓSrMuӼyu/e^Xȉ[ӎF_,0L5vh7ʞ}Գ7ϭ1;ȓ]o׃;g_nQff4y1SEϑ#8wǩAGo>5 0+e4\42*9׎_=o"&̓av kzOI`@_D12|[BᾉT.4 xշVKXqGUB"vOBsÑFnLu["G]_ y3̅U\]ү=h:\_:ksM_"iP&wNmʯ_EռKyabpH?fCC>wsբ+ʣQ7xܙv*n\!I NތEnRsV1BNsz ~N%}kǪQ;mi0#B\ZT `k5{B{sg?Jt9_CV|W'w$Ɂ/&8v%Ey"0!cz 훮"fJsq{Nba[| 7Vm2R1os7|JXni3n];Op!j~S~r!ݚ:}kˡlc2:p=Řϳ\c:&ynz8հerqO3嚺SX@H'LǠ?݋x3-ȮktY"lpzݣhwɋG\az]`g$~MRRj.wj1mV߷&r|vSc0Nak=xoz oY9NKxy)J戸sUF ~XQXzq=ٜ#*CbLC'آ wvE}}{cüb`JFGҟ#]xӖlmm-'jJ<{jGGΥ!lQW<]L+/}\NPgu =RiɱCx7l_uIfx1Co&Q DeQaM70&Gc8pD&OfPg!_zpq7npq{|A6au6ԣȹOZmK{_׽ڧz"NdvʏjO<1\xλ6\Iw!1(Ag 2R@_4[q&+W'qh+))^0.SݐשFpzс[u7$>яxUN)}I͠ rB2s zeDM;M/Ux=Tc #>=rFBHi/mmjqbؗζ cR# ۇ>zxqƂ7.v)j%Y+VN(ŕ>ȹ/3iWUەظbF"p Gdh*.nyp%C=+6iPPo(} hfg7j%E,?ci?!5NcLx߆,Ȋ6ekssj8Rs'&_GzRݖ$=RJ1 O;QqÉoٰV^aǁPGF0kp^˹*[}s}_ㇻ6pRFMad\7^4_%+.3-2A?l΅;M8EoDާ՗bg;%agg=+R@VPN:? sW_Z wN\p#Y3)c3Vj>Ek;4s=wt##n~9GVfn#җ~YDIrKԺΕ}m퇝Vf\mѹû~sEhvh]h#xcv#܉<ڋ)<LhŴ|s[W~5tv>g<}ՠ'|;h;Hز[H6CN|@|7{.GM77~)PBf(*+%1BYe|$D9&*TvTT#?2.vUJk=/7AwYŁdFQ+V\hdA1TCf G=h)yq`>58}YZEyۗ-EgVB5^CDk?Nzs9%?b}7u޸ϭs{:*['SίIqWGbR6"hzc67 ];ƴ;aZR/6 Q˯)E}֤7oqiK}KܸD<+7.^P{)E 2G UQ*nU(Ui9,V+_>vbox߰ˁ2ѝ"oT]Rǹs#D={'?&.-hGżk?u;K%33oҾҫzI@#:Znoʵ.I4V Xz}{d^]1 {T3G(3(W<@_ O?6IsKnhrT \WĆmx7_]+ Ħ}ϕM]Tn/\;)O?5#a壔^ʿ }$ISܵR4U9dRP ߹o ł>ŚuwGw/^ ŧIҌqn#3DvG>ךz/Y秉)}ŵL%UQ]&Z] w↸zxRӜep`fCh4n}ϱYSD9w5;PK拥JT}F>Ufr2FjG|RTu ]#dFj3h72M7m2l %rx|28kzP9>bڍRQT8iZ,XoD~,Uk1HSKl:$v;/<gDqJ6R=Dj/;/zS9v¸e?){n(fzĹftSqFtlb'21߉nZa:VD:TS.)}42/1)W_\Wu+G뉰#Ŷ9P >yn͘].N:ݶdmZ[~Pؤ!O&? b[>H GZݴu#[*V nposvbm:9뇘6ZxO6Fiz|wM~ 0jOٱ ^#"2^NjQs ."v,MOeԘ7?wI?)=A"1+i&CI4U8ٜf_2Ľ`ds!xev3[x۟Vޕ5njbʆbeb]v/Z˼!^79-8ilͰ xd n/hs˖ ~_4nb]՗iF̻@ag֎teg':*ǚ&(U i)C^u)F|0'Xǎ=tJ ibQ5 +[0X/A-Qtu˻-A7DJ\G1:M)ΰg=nHG'zk'pc[~8^s3]o[rP MK{9 k8hYvX 5ȍb=VW=|=Rj慜kSf___ }[vთIycu/3;цѽ.\`eN=0=`vDڧMښ]ᅝЙߘ髻0v8;4їmcQYFp<Ӎ!|XkG;>#I5- *n fR`iL> IS# ׄ!B3Ԛ 7]:0ƞ%iSEI#|tHd:ƤvO뼅$qgʌB Mv[%*0{&_Up[iff̖-KO333U%q[ffffffwޗNGD"*5Z)m%~s ˬяșjP>s^ש\0% kNٷ˒oܙ?ۗ#9ڟem0NKw^~zσȱn>c~&ΰfj-[YicYba.f ɘVӎۂĦa tŒW̱ {7{]lxV`6?ZYlƥwhN!dGD1҇MdF/@c9 .aii1-c/u ݷ>߂v[_#L25o':2~@n* 0~6 ~v4}^pepvRiUS_䋆z- mfu%)?杴^˘BBg,4uǣKV~H`8 l4&S {}KF8?ILbM ZNd5_j|eĆNح1̈́<MtrvT4gRUޘky9xѡE6# skndVܲ9OξG~|W5f~}w|xKm9?@B>Xe(G4c}hL J-O1Tn,Sx=";{O36,ՙ!trG#6 !{ZERU`=Cwo6Wr0jX钍FmBJ3OK|st5~"[ȁ,=#xsʟH߯4X$[/\]|ه=DTu "bGnɣ## diǕ~NQ^'>:ܐS<'Ecچ Y|d8sFPR1ޢɞ 6X–A{4LjIrm:uXZeO&|ܲ$g8nS,aəAgC1xNJTxV՚+HMt"n7o&,\ m?m&re0s`]7LĎBfy6i!|iFik9ߞsG?+7wƲe>Lt䫞9SMr)g|ɇc] / ?}+5hk3;k^:K6| 7>8m?& @1·<gVe/3<F.iScn~HK}=KhG?Uqc8,}}`É*|I@.&|<ݦܕNڿqE IXhD. j q}_ZD LPGp:CW*՜l϶&(:]́>]oˢЫff{z\eT7ɏb8_Mq<8}#y>Џt삎%" #K[Ȳ Η%SΏ\ݿ Ǯ:nΠY\LsǾl{eA1ly\w {4TcB'AE`a8ΐ1 >–Jdԍ^@n0k[3LG͐-q Wn$n\LskfWLfDN/" +_ !mQs"ĥ6~;#6+YO+b4X%e`&wZz2Z3 pN[blYBdТ_ ՅS-Uoo[W6 S,S2d|+z~$>sq?{Qa=BfyޖɫW>$2鞔˳x9& nʦ:d6#6:3_-X,JF=Ɍj<=M̞S&u1^ܩ bk ZN1ĉ١ڊv:; .4 6Ŀ|v`laXɳlI-lmB>GwF(^Ȣ8& X\S X  l񵶅65}1փ`U GlHp!|iLgz* 5& gd}ۚEnBZ > H^FP{#{oK6by(ft¾v}!Uu]'G}}yÄm=|w vHe`Fу 2G-Y]Y}n.!s*ḅK89}xlE6[P,lS'/̌b#?eVo*s}PwGh7cx֜K8}2O2VY3yÞb m~ҤkDCy4J.wr nDG㙎& 5}R% i%Wq#,)e༎ȄMҎ O;jm{9=P0N}SsW@x̽ɦL^oX}[}`dG+v3elfтܗ^bCB$) \Cpfe(C=6F8u݁%"\莾Md-̂nH!ME-}9>nUK׎^"Yf ֚ :a@Ȭ$t{bc#'2+2 I㊸#M1EЩ> DgKAbl_e0ۣhTK+!1J%@!+1*֯4 0n&=׏e%cp6#NedYT`Tr4,}mBm}z~gHQ? 7jއp7'8U9䣍&N{u((}/0kwq$ڕ';N;z%MIKަ*%7ʅh w9M,h,ҕ/DZ:_gvS~c]t30[Hc©kl r3UNZP}KJ 15c+̰TWJ+}U)lVX}GcgR <|H;sҿ]DLD}g3HXUs?b9? 1Sy%.vڐ8fjLD } &84E=g4 Txpg#+uiR53v7o?P+]F=GRsBa7>&@(g|XgA*T±1_R׋dbk#JTaіmRs6l cv¢€/}Ô\ %֌}jC%v>'"+dvQ,/ya%k'qTUQ ,Ϭ ^52ibҧo:m9RdWZ-fls%1"AcX&yt-BͯtRo''M9E?5In5P$ RB~q@zg<,c *1^zT,O4i~)nG֡"lu:x !yD J_`w+0\NJ d諂S \Q=F)Z`τp1[7 kzMɴdJFg B;ݓys=iNkGFF6z[nY91w40K3ٯ{t~#066].V`>gj0CR͆(8-'Ii2@ދZajS+ !OώIF>8yc֍$rmǿFRVWȢ=%>+C|,ۗxJݑ.NtϪ-q\m)$VߏD؅?([:pL͂$zsr>䮴ݿnضMǹAJ|pV2r4ג[iJp$sf0҃, 2pxj{\ѐRMMIJc uL_\F-tPWHQm*S͘V5ܽ^ˬc5|Lt-akIߵ*hZlۮ#~I.AL$$Y8N+dJ[L=zpZG?#YrEdJWI rdcg5=(~jΒR"B5KYmcfoOWq?<-eP UiKr'ү s",Ÿ%qt=׎){>f| oNm;\NvH'Ndh=:`wucs >:sTUʁa"\1'qDvuamÉVi7xQ֎g,ÎUw0W+7$qޓ<瞗+0hm##v@x+}䐡?g3\̾e~+#c9 |WaR j~bw R{Rٸȃp<`β sYa">74*zPM&g0'ߔ=\><=>qv`Ho)#k3mƐ=2u,I;FX;Cs|*G`qFLڮCNeC1ƣ q LޕӎE8{4qS$u$FS&_'1pٍ`6\;[d3xɳtwjUlSN\VF{kXڳ3ǓOi!B@`W#vdwx(WHV阓`3s ;2;D jhH:9y ]m ,dwjgt 5ёGa"GGq13 7JoW𦪹Vh&ߞ w[Wb{y8dEpq{ەp7ʘ;Uɜ5fpl N]k9+zc-'k(?`0d(آo͊u,kβ|#P{\¬:\JTѣL 4¼=&Mm"2r!W64{a >Š9k(&jS &kdn8U.\H#Ton{=csmVDr&rg/./f%v ~Cv*D~铫h1@ʽ"| 6e:P_7N*Bq8ӐcMOj U}E޽,gM*N-J} b\,~UYO!4iG̱Opv`eŸ\vMl8cX730mD_~vS_d$M e1+c|GoMD7̈&Lk k6fG.Qa4:\l FKǂ#M8k+Kab~͜s,9=Ė-!Rn)4mzQ|8_D oX_ *?AZ<!z+1TmUt?ZdV׃ G{N[a:J}}z2y0IiY[C&w&4*9?y= lE82(' Z.̯txY;K$ ncW[p˥;qD-N >MK fQ^_w,~tL*)ʹʿ 9Rjhmݲ dvSUYl1Q8}ٻk3 Z;17ƇUzpcl늧0HV JW%UEKN䎆:֏|0vB{zLGIQBйXs&#s$Y}3J1B=Ș;c_veHL-u -0'ъ12!zY;L8Ŋ-|ꉳ 5׋:ι X?Lb\y+aΡ~ly} ώFMR1x7'w )m}>]iM]Qm@&|њqTl.ɞek8Š\Α2{ i}8b[9Ҽȍ!\DTie\Q Ơe s*adu,pdM7j I}/ː$W͆r94L&tH4 y7DqE(U_k>XJ=s}moJ3]1(avs!ԉaZw{Gy7}b^G4E )4#n9 oXZn} dR"l2>1c6a0e*D\` k DO+󡃌=dFܳl^κN]AkijiޱeItqq 1>@_z5+ZK.2Dzt#K k8 oȜh;[MbO52)fŨ1caA_V0ImagȞXxr錞+'A}S=#8Gk(p7"ץ,sD7tqib=YFVZ6ةa!.+my͒۫|kt mJCwY敬1f_%ږcZ^9c1ܗCδ덁C%=VR+\횃*qΫ*Â(|N<9&cXwT :Þ.4厯+1%ˠ -pʆNl:MwcK%faO/3os5’wRF„!bA\RożXNUWzG:_ uω 8B8dP%2ᓥtPI hVE J0d?w4TɵB&GXV+weߣPx3n0ιră<5< ez?j)e1HNJZ`0}_BTan+`t)ҟvOI.ѣ(FV)wQ0{ G(k ma7}? ۓ kx\L_fsfQ)b>ͦCd%7R]3[|tr$95[gS)hS˵68^-ySE$~t?U?cbែǕѳ]\IT51i3ӆUH:bD5i `N_+jsS[pl-άf,{(XʇV66 o#hۉ}ͅͼҗ;XA9=IRǤ{cqRK 6{bJxaJޱ猉Y&-\J7TYZՠquM%j*kpo[Od]/β$uaQ]4 0Obt^Icj#h&OtP1oT=y܁I:( ;}6?LZdJB F~ID~ϥ`` _)Ğ>,A,XVO5RA)Bކ\lLz %0鼜%;6n$rUhZ*EɊ^[ܛ[zҙ !Y)*aشnAr xH<N$:%I]v eU Q/)l#ǏKMh{0{s6uX޷c7ҒBu<1Bሔ̱֜!#rL":b)f Yt{#.{[mEY[R6e,צtXtFr>ПIcLJlPS3;#ҁ.8Bu:MyO{r= 0ZE T3?嗕=GtdZfBu-(1x~-)J=SL(o\Xe;\Ly+9T3F'._jf u`t9"% ڋk1[N.;Qˆ{]9wbX%ٷ,EKrojh w%ܼ]g:9א*Q&][bqT&'D,-gr*ߡV?wXr:O:v$Z,zkTϕ_Cع:if*햅1wIȒx/s&}9JF/a y0]xgBGxW&3I bfi9N@>}s'Q]ѕQ~TB3C`D6z !sW3I_UęZ4+"%N*Iΰzf:NUbWy+J[j>}*b>08Yyx(8ZY_}rCm&NiuxmM(oH#ud`="LmƉ'@w?@ʼn67/Ы=6ecQ m+f_ oΕпU1m<8p5#|QF~b'u60sj"Z;m]~NS G+9󩞄uku NA9.ѦIUXmD?L%ä妕 r"[jxj7͕s͹X8c{V,ζaOf$f$#PObNb_c 6%g"_Ze_t6dWE~tWnfd+ǻ2TdrN,cM"䟳,%+#GT칩>΍tQGWq^RO!Iy?WG NPx Y7V0pl|o-Lj97jP'¼bfP od +eU>U}p)52vb68Ɨ~ -fW))CJ?!G*B?Ӭ~4{Fs!M-ɓ`vw[Kؘ~Le]c F_TDE)ca_=])¦=R0d&C9kERDZB"}E'(&9(3֚\:b.yKJ$R23uQ`1u3o_+9/Gr6``[FGdꉚ@M]b۩ZUu ."fj,cB$~8?Z}7ž,|q~c&Зl]R/nT%,^;Z:z?"\v a ML'`7u4!OF|yQJXkd$u#0 @(#8\IicPTQC#{Lefi=:۔XPϮHȖzぅɎfuX#%CCó7V@99wdShM OZLw*HO]':Z4G.^e+!Zŷ??+?' ,PW\[W9{Gy%E+xYŞ'5ܽSMJ5FzT.Mܨiac=E1ǥ}g2Y#wcRW f#A%Vݔ4{[KZհk| I\/+ce+ߕGJ9n[N}rl8J#|g;auj0j{k2gTz-RM-S&(vvȘ7ئSY"Cճx# gKdBq-\17VVd~FޔO%5r@?,2 =(dDV{XJ9IN圊$c9YLleT?1S1;lnW~!K*~QWoj4_^HC;$=N|_Ozc۲^z7f=WO[ g+)#Ͽ[8.rdݔЬfJĬ1 fûj_ȬjldZ˧dvSM|XA1sE ꦿkM m)in_!<[ӟ80!Eĥ1N8c$N|D\FJ=d-|au&uc(Ia.N$LCQ f4d@q hFzOY]+LySQlT2KW뱰CگmjбmP%άbZ 8մsx.#5ܮ wW_gx*Sq"E2镒dbO7UoMߕd_x4}X%r-_+RsJ9h` #jx?]/Ǹ~H@A=&fyXGO4N%S?72w4{NESOƫ:*EIoW%ԢzlVZ^#e^݂r.jWhO5S;W-gY2zuBhԝ]Gkzߕx[K{Pֻ9Fmy`ds\!fs#~w㼉*=)Nj81[͋})K;w)ʷ' ,X^5CgM4mZVY5Kpv{ oVlnE!!HJ*H*ݝ3tbbwwwwwwe~ywww]' g8f6ki;DA:\s9߀BOTDmp* Lӓ}@\eq[砥eh9Ba:m,,ήs}t2 i* "d5  opule2;j硾Uy|~E9t .b[:ᳲ5 4iMAZ=94Ӥ8xO7s,;E1M/7LɶLsBVdjq.TF0 >+49`&++Y]XY]_˘UPƖRڊJ6ds= t8o`C 5ޡek-#kx{NCIf؟e_wz1CKH٫c5RdB*ߧǰDMF|dp3–+ Yn2fМQ__˿"˭:׭\V7fQsBpGkS)/^2$k Q3\_Ñc3A&H.usڊc \xEI2/̊a^e1R ܈(##KD=(/(LPc=Ɣ2H;E\OmٮFyYÐKj޿Ӳ@z#sPϻ֥܊.}U=c xke=q[20E.n{Rf͟k4Α'YHKg؃jnG?we{I.$/eZR4ec2x❅E ri qbTMNE2{%*3EcaH~TOY,;}B^+n9k%ϝJQ8UDe#{D"$>\ODサhV _E|,-FJERjOGsf&z,"۷mϢxZڤz]?gC cEEl2G4$,-b@WO2牊gT{[xϷb&+)|=T:PhRJlkyJq>f0@"ӯrBBάgBT-SĎr\3cm1c:vw&e[Fƥ*R>զ=h< |Yq(uBƩ܌Pӣ[XUO&NWZvڦvL b|g59(&UI1c"h^<r1cNjwXs}%~[Ҩґ&ɥ5b߻5}W)KQX~PGz@ae؈GޞeG)7J,R^,c^27+j)rQxxI Y֭UKۦF>+lk{#%0Z "fYȪCpOOw~M>ks.KQwAօHk.\&Lgy !$4c1?QHE[Mxb) 1'cl7XNM4zvrQ8,C_{5MKxs-shJfxn#$Wd~m$'N+q^OG޾dEvHW=g fu|yt°M~`ZvF>ړ g,xPv lArN(H8Pgi2\'%Lʡ4n !ރ{ѽqi翯T&MUonQ5e^,bahլ>UC9WӸCw_Tԍqezw^ϟ’ o*#XZ2|K9.ط/Ek$ɶMYqVwܗ2 s,euv2Lt)~<Z5+#e\-:h2vѥYE)^:nU3;PET5+?R$I\yū_$'k#fqqVCb:+\¢EX&89.C9{rKGcLL?ɬI fFwh^Eg,/ ɨS<"aNG2gbZ>%bVlY ~GEG2åNk&fdq$PI:n􃹼ȓ|/1[9i{˙cVNeFq&$kDn`\"O2:7.ˁey<ݐOhxk-l.l}wB$r2\iՎ' 9쟛Gdecnoxi;Ri\okۼQ6[0ap?FbNe|b.!w yWL' :=IHӏ(+SC.V{Fud,/ıVƉ[EDY!g >}j' g]ۈ>Z+1eLyYFMDS7s:iiMj3=o7hؿ\elZyeZz2~/.]\ώ:jyzWͷ -.WKa@Ag<`-noX]-uL%"[O9_%zuUV%_Uˠw*b})a8_,1_Łn 6l+ZO[qyv69\IƳ ,jk$\<'> DI8]¡Eul75Dʱ1Xpk4-g5=zMHM, g5lqV%FO-4X欥bYyjުZ%7ߔs1}K)~!Ρ"l?H#f|ee+ Y~2z|q 9jRDu`ˈ.}q]#c"⊩^rl+8C2(pC(TD^Ss^tsO~].aȄ(6.e8f#*Q#-8up჋;y̛]Tκ-;cN=X̿ 9hKڌ'~XF-Mrk>; {p:%L7ic[~0€uvz _t(ZuFLl}?vKO2D_RʬKif$.U&na$`+uet-Via (~l(E@HW&.Q!娐@ r#p5jøٍBsv5aS>TkƇ-ٻ+ M |ʏzd:mSI۝";7+d q4#K9 *W>J-"_WbՊ(h*:bqgMѥTtR-ǿN[3PP|[Ia %cø?hWds{|ŝ4FN>CG<[=ezćk.xxƋ盽sу)<)Fح)^ NŃMʆ\t`-:w>L"|sMg{{/i3@s= xQl8Ysy&]:yF-HW{l=aA3wt,ẑ,Y@K'*8șm^$hL@f5ᱰ1捂F^vs*!}van³Ձ9볬Rwjb*Mk&)U^%{b̺*2V9>9>~ ~+YWL *[}otn#L}q6)/Όs?甜$Rj\b*x&9mə\vZaUO+Օ<ڧbl5m4<ۤƤ3~F׆SCX0 rB0^/FԿ-䌲}% ὬҡKg?iMO/>&J+Je8lxL"0zX+{)Ch-~-=fͭ1L<}Hzt0kGee 6bzR0VNoōO]AS4c*{Q-c3&ɂU\|k 4kR U`YN>N.@RbPݰ]ct=&2/-1׽)n єq)_DRD΢<'xѕ 7Ҏ }* v m7 [L63- s c>/֭>sS=1ۘb^Jx!{)I]X~$ Y1RD%TeW[PN˧2l8-{!ؔϻg({bN=$ %xWPM4L'rt CJnPT]QE ܔ\+gNcK- 70T"2bʏs*a[r&.*h!Y|h5Zd!XA ~P+׀[gda:>Jb  =k5dl`R8KEe-&v r Q՞p+w ׼,~PQ)<L8o=x4ۚv6Xӧx 5x֟۝ikфA±樖taiUKy%Lj喛;EŦ[PߗbVXag)g:ì#66GSTBUp쥆>WZeSʤF>Kn1w'yW\(g֒3O ,^a+nَw_ N8*Y-hz/.n-HG:#D?zFUKYxkjʝ͙y }RJ{>+("?ȕ%wPě%W̒gE)ڰ E, A]}&!_\1K( .ʣb |8+G X̄J#|J) pU`ҫc"g-'Ew%s SM5T, IQRƐVgbl6![λTg܆f62BƖNCB\\+gh^hA^݈P0!శ%z.f"\,ҕ<?#m6]E_dcѯU /3 k*EΪ:y00Qb(L36Q 2^2.2PÀMszRv -n$7sGQAfNUk\A^U:}Bп-d߯ߜDY}}k%ފ/&Jgb9b.y!/" F!B }RU<\s*xB!U 9R[мf.zLZ8ֈ=u2&{)kI'1kD/"S ]TTg\jVnqKJ֤6%W~ Eb%ϳTNŤZ/p^?LwBրNee2z䭑̯GR~)u2452~m!je_DSw6:;SS:5VXb N(G؊u3ckgL^?C=[;0ˉ]}э?'6{?͍?jᬚ3!=H۫A:kNUboɩ+Č4P{s:3FVh;XϞZ'cƫH~Z.~:DgE4[ӟkqïm‹_7 ͖V{+,bWUg1{XՁo5Q=v0e5-- a*e\ݮ.FBr9AȊ|VWsy$΅RfHQ+X+rɹIo6 25'XȉeL_]ĸ(BBn~9>BEVQdZ'kNIz^&j}4ݏm;NDZtj#M)G8wDcpHx=.ce)>cʘV`dB-8"gePt4'ʦNgÖ#hї0q9[_bXb6Amv  WzNK.Z0iaևBƒw-@V oȁ{mOeU-46Gyo /4WBTQ4Ob[g9ӃGzqp7ͧ'+;n7'8J԰O3^]*jo'Hstzj{BC3MECbҐHGZ4yg=݆yCFtמcyKZaoDCvnFL8̶?31֣7} x*'3RJ|"oP@PQȯlvJaő 1Yq=,e|~z2Z‘Knͥ\{R6nLņ w*Įc1˘.|Jɸ0SZFx@Y*wp&1]I,X]i37?mp?Kǡ|Z&$F.;_u /ҡ2m,gv sڗWơG"๻i]н;΄ <)ωli!O?FFu4S7ǵV w@ֽ9<HYoO7Bj@.gjK 2 ;,m%96/%Gs->gzk%K|QV.{-X:VKf+~ͭS`ッx /YG6v f[8bhxy"L*Б4y3*SB%1\FiW%z*r>$g Ulhi{\Ti["e *~*FNrf|8!q؅Y? '.z) [՛GFS/݆+’v|rotjeqWxȘPKNrDxٚ&c{cͥm%ØPLME0}QT~Fqc&3?~nܯFԱq̍B.k 2)˘ѯ2rpUr튑m|ߞ>&2ve)+(Y#걵{utk[]̀ڴeUyu+0q8"?pJAsoa֒% I_jf L0q `rI_77>=é.|7d&]عy=Pû!xJ;gL"$l\qLf7ފks_!ia3ٮ60nZ%CZԥD9+c'{sthQITԴۣ ?8F ݧIup奚l 3"WQyqg%l`(%c1ux:&p75iXIM-7NV} ۩P˯zzYZ~"+ԌVCg+";9- 9MX6X<|7`TCmyԌbId8Xu>tEY Nĩ3&9agu4/2s$[ǴCSfщQ`ꄟuy]ɚ 7>u; 1ɧT.M{=-k$ߧD*mGƓ2)ڱT$e`;s2y@bf0Z D߃ O wl̷>8!}JupiaGŧZ=B#‚[w 3>Cs)f:*Jt/YR&~1 =)c V-n%SHԝT[} ՙP1^g;^Hv(?#¹S+1cXFH2Di^E4'A) 6雎,'z>-NZ#ܴ/`"ſ <~1J8':]!E"b?3OD%cv)m$ a޲dF.lܑ>mUC+۷6}~V Ͽ> %=jpb[#/Lz!}+P Yh1q pc_0h*8]25]*fX `V.S%p'M'r(y/clM3[NF6Ƕr!%_?Wv ɏ%fs.bis*l9ԗN=i1u~T ucEoOOgHqr5T*Zvֲ0g=Mh:P '4lDKn!E7% Y96/]Ywš3b% tS(vCBաa=U R9}mg2d Huvb]Hƙ 2q}ڣˍD<.Py]%[,X~Jz h婽Y/Mɻ!汯.;,9Q,ƵNx̕ݱ8 =OGPG;\n̍,q>`f"5qGTQB\.CD8Fq,+-+j pFtQ5X,=? |͈PRfp$1 ut&G~ʧ%AIh[zCRXmvO(51tGlj oFR,<6淧ӯ ͒D `>\gqġ{|xXXX-i6 uj$9b >v ѥD!б4Z4mٳ4.peeTkZ2t33Y[<:+p\΁VΰB&jǎ$&!/b$Hx"81ˆ>8uo€h\ԓ &k+7 }9== |gZĜN˧9Rd2/Y6 9GiϧJ(M`ϑhtoq!k7+d= NaGoFT$T[{r$ɜ'1EO z3q0rc*+~LM  y]IgoZY!gJ9\:TcWVư, 7#i; LuuGOzH>0?~nam42B*i\λ2,~E."_TˣUj.U0aV \9&>zftGFZS8| -mߟ-n0Bor* sdp A1"VA K{ZIqC9'I4ǩ:n*3 } W1}0Jt."sc?a(oSh&K64>Lttʎx܈?# ?ա飾mģ2X{߱w+s%:v%Vp!F~,f8bHʘU͹E,)[%kTpwFVVѹ7ֱ;6}2F0*NJN*?h%ͬsu)`եY<ٽ"&f :1錼H%v9_'ZADU1ᘘD϶Usf0%N)S0_A "=c)] '_\Q@=$,N:ij"'lP5H!hҀYmcAT $.`b.fb6+~,TR5˫RcuYM V;#WGLKtlJ7m"6fkQ^$3x !{Q۟fI?LT[8`Uj>vOEuV9aB#巄G;BIK2Nt2ۧIՔE#r'hIs:-*1˨$R<\%Dn.O9D?+粱~v3S˘Dݪf{~yp?މL,C)dڪ)RkHaM5y.jɉIT0eՙdMd\1"ň,:gI#& 3~m}A/lmvHw6A p=&l4+ے6ʎ)\Jh[NE 5غ]EԌ.<+E4:Z rZ-:r,r'aMDz\j)#ә=aL ?e/aɰ,(&t, f8r&JQPb~C8EvT"ʲ.fȖs8qUSB94R [B *Q#ޮ/zB>& cq8Qx5teM8&>t? C.ќ8CoL+\:!;OZ[9MXo)O!,k!p [LΘcqяhpη_n&>HpX F}F|JpSME֒TN ^15k=ʴndpl?Iɰ-FH!fB][/ǣz\Hijn?UI3%dv(8d5+hYo&C\: ^s:󅩁ۄ|uB8l7൭%%./vm7<DAc/+fzLww7= (IJ|OŤ3"S#KpE[1GBo[~Ö g6,878V\9яpw;79-/UNNI9u.G5Z:ٖ ӫ87zՌ8Uwdo2sT]i#`xЉ ŭ&ڑRwI1ebTCwҵT2{qGsy']ʡFGH=7;MȘ#s /B؝_;kcOdùͦ= "xL'rܘjG[L c,>1bZ*i0)9!Q쁷35_59 $58Oח0wz6Grq޿D/1D"zB i8MxYjyb"sRǔ|ّ~ǎ9$vsRJ/@5K9}d 26WWKw:(gc9n*ߪ:'vЎb'}K<v 7v =ط3ZG^5a43<}K|a-*8|3'>j8Wh j%7?v>Bs:ƙ!ZU{/v}5d0њr|^)Oݾo+n1]pXɾ [U,ɘbc SJVHl)/ê+jhЗNC#.p1IE1FS$e|)wOJxV*C4^C#81J@'MdD>O_ߧ3w ׸|^fgb9 N7"L ɺ=١>&b{yT(FrjǛGr99]ÌH)*rG?'xbn>4`S EQq!^9Η3ӵEJv+٣uQCXXl13[<-W1o2JA.%e)bf7dJY=@{c9w2iP Xs 'GbDWX3،cd,*s9`S;VXrkJq#! 4) xgu#pjɑ\`1=E }(-=v(`E)Êx;GRj} yݎۼx,z@~A.8wA.a˴vd1 L}P>(yska,ľO8DC8̨ l3Su04%ܪ#JTp?@Az}(搾emӝ.GcԮ+&zT#4ކ~p2p&~}X%9]C4i:%lyGI^9씋o)z\NʢYބs[;o]4ub͂apb(ؾ(xƊAx~R+m<Q<9v3 O@}:zӡ>&F훖s #U}o+7Q6 Z +TlS ԄPG;5խS4r>OU '`,^"aPGؖlC/,v0dtn,)a`65 y8qVNEʥs,==ŖwxD|,@Gy5]<ՄmPL4"ZI0oD|t ۑ44"L $ Snq:KB0bMֹJ=StFH;wnjNԵ=0RJt=WNlh kHO5ʱ- \_zAdO-ZBu\SFĴ2ʻqSԴ[bVyJNcKҸ,Napㄏ;G1H5ǼO+Zx)z c(2WV rch&4c) UU9ZOh6-e)kqY2Oo;5#`<&26q=>a\p[U"2p71)eM(?r!׈™T97Hͥt$M# MC,nDp$lΏbn=C\Fr¹91|~QHX[cF?+!Ӽ2 𑖰A>Ih{0slU3SAM]IŰ3 @JB16aLFlMIJ gΥ3'kMȈ),j#^^ ׵Q28ޭLe!TD=k,-ţ"1|^0'Iq~T=pgeз!}br\K&_e:M$LWq&U,ZIzI5k8Rbgs#kt)cx$kٶ ?S5>J.nUBIHswpYKp`zdsI3`sӪYJWb}1* D;6wU%N?,r}_y%&ɹE%0nv +/v{+‡_.7ԑk3ygPoɎݓ9?^Y~{͍hVƨ0;2$|UȃGTaGG=jܿ8^يw;jR2CS;wgcU=>\?ט m4ƾ\paFu2;$r\ ي'w:EiN[oO&sE>(t;%? 9nQa2/AwFc*pY!7O Sڿ>.xZ:]މr3.z&O/0:J բDqnU2qL&,&n02KBBt۵a>͗xf#eI)'XVƆY6}:F4_+{i+_Yl)KRfofcO#qG)Q|EX0WuH4)l>ϳT[_AE-gǖ1nS&|V$JzOr#yWqc^W2^qFC% 9pG xlB08ۖoö!N\33muSU9sxъG1a_鯝&} /u7p{RC1;%eYJtr&+n`,93ʩߺb'Xbo.Eep` _b%!`I#p4۲_"x*cq(!wQ|O.KVt׌94Wp@&h: ԡe QaRFapprob-|j`W~M6#'F#Ͻ""ˊPLw UYa {Jqr?|l[D:eVlL˽.^`_ f}0#L/!~t( fMpn8Nrs; /JxI$,zܑ2MzZ 38ϡf<(PAD\dfcttuZG7i?C6Z>RG&[!Qy?b4҃0:p*2CFL$ʨ_wi }+C5 iy)gU\5OjXZ)>^9¶;u1Z갎2ӢUkh;S͵\%-J/ez",gdѥ&vwf2Ք,`mw'|5Uc[NB|Vԝ&WXᴵ~l J!~"$A*̈́"³Jh]]]eJdJ,n7wwqsf!=}l1'6I6*LXAxۺ xOLE7Ӂޜro bh ~qHz`6{zx!c/A?/!}Ԑښvgn=~C,펷e;2daiة 2>__F] =ڧ& A Rt$Cl▧"/nVĒ΅y̼ԗ1@'KTE4;EmY1ȴ[SѳzE?`39fV460č+5^$l{giï8\lIdOdGKMg3d`Lj7͢#s]Dlg&&{a> dW(Meay&fCOy1^%C5 AuA &Qr\ƄEMU>= .z>َz Gϡl/%6(3֡$P* eop6#<*eY ѹ񴹞`!e`c)ŭnM6wfa4vY͕[#.I5.XF2%ej⚩4g)y&UdSUl{Fr>l/Dٳ{{eq&LNM6*EL-CTQ#?qѼ?q`S+X9_Կf:.<-'TY&4s~u9ה>#e\FKy^ƥl30D:J4Kx 1.?=ǎV4eyRnH=# /Str5 yt2[Ypq Љ W̋sb\y`"ou ڹS!;Ry:&oPZcv+SV;;ŗۦ=3.YYȆVΌ-}c|q"K`H{B[ӹԞ#qse+_ sQ}Z떎۾L{Hi%eLIݺ-Jy kfW|$nc*9M),ŭS1;L^ē"$?KChl , ؠ`1bykÐ6"}$0"h9toCKTdf\ʊt)!$㺦YE\=VJNcb9*E!繨U7/59`W-ˊq]y;\ei67ICLd13#v>+D*YHjfei7Q:c[N-oiuzNrbァ~_LYeYƓn6M'Yܯ/ 1b?yw K;P/c8c@3B}kFXdL7?ԀjEo>jABɭ&G] gFrm”Qܾb 1M$mWbjBde|v)$[sY5 H.eB1gK^h1m2׈F4{?н\9;#©˳xYrlx>ӏ 5fJ=k&sYe>̟O %xA} x8rKtMV{1hODdS"oÙƊ,(>fDž2WNsU1qW$"/ݲ0|&MlVJl,EIОRw0g;Sګ/6)PΫ}rV_((bj&=9o/foͲ1ƔN$(ȳv$ J)r"&)ISh*"W)㨿ʃ:*tѰm5u(:L\tQ|+ص7?tz>ۗi٢oOeP@wnj)j,McYZ"Ruءr O< >9&׌fm*c8ٹ=-ll&c۩fs4^c8K(O3&,n,JIemd֔9i4.La$偅'˜D~ñ6Ƙ1<3hۙ%>z>9ՉG!I5MdU8 9JG-ߊ/7ݐ(&6ۉubj(.^N[d#R1 UXHߺٴxM|Xޫ,jPB"6U06? ( /`_!tRG"Oav1zl+DM`\F&T SSsCJbnIEB\eeU *db=Kvr_]e ^󩛌 n<ؕnY$tt/\HG49X6[3oJ"PY9bJAo2hyKC{+\mULWp_<;L|`9egX9C:ȵ %~Zv{kY旽IT-G.Qc0X`NKrs M3;[̞D]$kB@?w͟{&&FpjCT@r;< (z<.,l,9ܓwݘuř&m!GLhZHz0f:y)/,E]WL%(ſu)yKsTNy9!/Wa2R%G*/"1G1mO ̒<dyV΅*]PAcŔ=i9D)d"9CxaC-Oke-;ΊݡMZZYl*Z˨w\4lZˁ~}, 8ڵQ>-!n D[BM~ ;r\s ¯(tHaM 'atbN.<ITV$,k^NgdO\N*%*>NFE,+Z-ۖdήrA>O6{VJ RrTej٨iS{uKCjjuh"5h7}qNאu-Z;bC‘իy~6ki-sG.wfP.6!̦?<:!FZuBjM1Sc<`ǽqό'K"EVlB^в5͚/csB՚45\ z&#u~LOHG' G"ʵ8ZZk,jي9Hn3~8hC U!sg!ܲag;l?Z~ 04d:-\8=I9j0\ƠEL+!Ꙓ" .&Yk >( 6$5"6"+a8B;mA&g$KpKՕt:Kٳ4csY1ԅ؈ϋ/)\|le2ҫDQ. )"$" d<1#vKF:N$cW&+2p$A C<=ebǖrbyOD{+]igLdTEH%1>/:DŲ^ Z=&G8qo#+#Gj^SjP։\\&4KTG=N;`ٙ(%u}8Eف;Ѿ7Nb] U//s'29m<H44  C:[ױ!_K2XRqMa?%QI'm4mx>LJwL<)"6سlj_J{"OteQ:: Oc%3NM'.L1Gu4? j L\JRzˈ]!xp)a%HΓ\.%kou 4חg*/cr9\ΑG7i 0{{3>E6?f~E΢ЄBVSOc>T+ദJZ&2O_q } rQTH9_$kC8?9Y̸/a O&XaYJt>MiTD/8,uuS0LFl7;skA%46*dhWMäj[kjTpEZRrQ>o+8cB"W|h|(ǽe1%挝F:Y15fM>g 3vo'F1ɚ{ .h43վm߃} Y>=ɟADl\'B eb{5^*=UZWC[5\"DWʟ`䢟XϷH y9߁8O#Ӕ3I}91'W5)qG오Ii1ʱ&\@HkWx8p`]2gD3|i 8OGBkzp'3}ǍO+~Yx1l>Yk3\K9>39$ux}]\Xw$]ґ&k{ q0s=r?'^FDf"SBP=.CA2&}ss`r따) >z%5~ew-'R0;pElFoEs>I󙵱/|ULSQoӻ{{?VʛbΛ3OzhTKԈټeH.aF|[\)e%Z 4LR(Ix=?u.2ż~.dPzg[PP)B8L0-shO:b,lY1e ND`(C6v3t1_F8aA%)⠡zSՔ]*Qa)v&js{'&hx]$#&ˇ\ӊXŒ`qWG4k)Ȝ %+s;dzwo~ۑ =p Lv;IN#-Mi)٣f%"xSZs%)FʡsEȳ>Rb{?KQL[dgR:gq.$]#e mnCx^@ǮZ֛qdak+gR2qľYJP VsDׯ`N /qmgVxG@%l+͹R7J.s;k2Jy^[ 4$}XWrW]ȏ%/.Ĥ 49Abf5mR֖Xezgx$ `ռ\bŵLR`ZEj o(W)悵3mž[Xg7J1moK5Wed~\[;]xO ^lMB^ a+7&ɻdg. |,!Odi) Ƽqϻ}h(:rFy X0S_yaɘo)t_|vK\2wGbϴL%;yφS.(VBRdxDeIZnmTQNA2R:*LTܴ%NMڜ-hEvêG7MS(`ZLM9ʩ_c f4UM*B֨qB͍J-!Yk)˛Kh%-b"\qGKm-6)}å-ӫƫxKћQ7&K-RMJLgϏ WR\,|YXD\fā.޼].odc;zHeŚ@CBOeOl"qwc8ZWhYe Cݩ))Diˋ%4oHfý)[v1:7.lIpع4F2k rs޶0?/{'j˕&ޗN8#ijF\Vۮ.̊de'^N2#3ۀfwzH聵(\]ڏEaL_} gvNBJu&GSU'͎\ C쨜DVh.F[F:]?_]Nȉ2|d𱑡W #ϴܟ6<<ޑVb^[ ƷM=J"S4<2m=Yx:A/Yd^bq_>玩`ej&"JL¹^ʲ3a%^9VL-B3delZW0s*QJ4W`mZTl-m2rf5k9Ǹw1h^SZ܏̧^Xs8G.L7R2#ӝkZu4f}-6ɮ2^VJQS@Êl:ʩ cˬBf(齿td1N<ڗ)[φyqҒ-8Ɛ IcZcAjr늼m [?'EɋtVХVrjdrW{.=(2NZ%+ر/4M3nn͏#~(pLf!pJ+,0F9,_3sn?&u#q0x)حyH)a F܋N"OF:VN>[//#춌"kIt۱V76Emđ9p`wQrGiQX `@L6*#3 pQP+qϏJhGݕ-g *h|)w+/eѷ~1c)SEޟ&## .)yJ|>UljU `O*2IJ|rR"l|q8K_|'Sؙ6eT]7;]a1T+ؘ_̀.^"Cs ̕anKqL4sʚiplÈτjaSWnSu_P]L.k&>+Aheûa6,]Ǘ|PWW匚^ۥR{c%&!5⺭- aDcZ2_ 'Ѽ;=F5q&E09%l̘IP3;cy=/ 5K'i k #07_+2/;;3H"S%fՇ &1Mޡ2%1'5zwg7rT]hfEpIẆvc,SU|r/+& Sj7k9uBRmenSCQԓkQIb9:@Kb-.JKTw2DNJ%DS̀bl'cP}X/=E~Ě+O ʕ%[~Qs,j`lO؛OENB)!6y_\I8˾DK!K CSߨTSJI&g\5jVV.:JtQUw15wRG(#7) hIydL4DBqr5ɓ=rOdSw2XvӋv-sfe#WV4t8E;6@{?{rYMI %~eф#ߡUȓ VS 'qmZqmSpEZ51UCCez2=auN!eO7f1->\v˥d[!I%-(6 jzzK$ۂx60bˆ܉g|ѧYԗg+Y7y<66GCtol]5x1IGc7+KFvt3˝nQ4X_@%MWӰ]/,q|=JЛ`>wJeP> 6|sRRd0#{lxcO~ug|{V{ K q-|Q ^l a p6@iL ?waG$x,PÜZh9]K 5k(1.#ۭ&%H0+e3%SYƿ8tf2?.s`"O"ڶL4.æw&g1ڗ|ǕnT`be0ZXœY&뽊Jɻd^=ϭX%KWuׯ9͘>1| Sb-q;Sd$jX?BjbNAQM*Mנ^%{mhD!VBH6 |8|1vf?҂o$*_o IAtivĮt8 GH.Oed<F2f 2ҵzq+Y.DaP2(i [rjs;1U]ʶ-k+"uLr|NVѨc īxkl΃POUܫ [%gr9+P{n=]ўpc6l)BXf!|{?_T6->`p5?M4 ۮ [I' ^3{ ++X Vd2Ndr喱JBrO/%]̟R+O!P>og^&%4̯`Jf,)m%)uR ?-4vIi2u|,_gm³{υY2NǓՕt!&H||S_GA-7(l+a-W޶_bԾr3t/m9jq;1"ɕ#] ̼BwwuHdJVďF<ȑ 5"l/{8*='҈J˼ Nu\ 6@yY8O*׆ݰ*B9QŽ8rퟃo+*+aW99k$-Fׁ \k}.4 S됴QMiP0 ;+/ l2H80׹_JSI${Xq:x|a Z|\':SMz7a^mr t^RNu9# Du_H~t*2cSWu%÷{MJ|D9n(YNr9d͗anWd):hA#˦q.̗ծU4LDO9zI0/,ȡhHg 9_D`":/*Wmٞw^ 7)~IWQ8ĀQ׃yװSO5u󶎮j% T61ۧ'N *.UvMƛt8U]2u'x?w= xf8o:Dߝ&:Gx[bg)Q{듅6 dW(|X"x1x2jsҏ#%[A8e=s&II~?=)@l MEdͼ[E>N[D(~FHe]{J7>S}KYQ`u dGFGX3;σ-N|vO"&c>ɧ@Bre#ppK;a\e?yoRg~lM$yNϞ&j2<̞'7W"%u.Ǫ: Le ($XIbr~WPI"urUA|h(Ίh֨ 1Irc<6T;VsUUqS֋J3Ea+e2P:K'=)؛~zlx'IlLNjRUZJYh-U̕VZʹ3՜ZQY5ڟUvб^5`SKII4 Z1/,9+>mJHCƻ!>qk]1ctpʍ$(;7u筝Nx7rQ7{Лs0`3x%G *nވQGnE5ZO. I8$10;c1W2w~H[2mR(/893OTgmƼ2[wV ?y4Ǫyt: zw$:pϞ7h79%)s jUAm_+q_dXf[լTS%*=dC}%H*ܳ ,*%r*3Mlb@N*)_ P}([?D/+{R=bS|s"?0mho3T͒K:>OױtO9 XZ"/q#標XF{:o;)Dэ}Q\w58v}Lb_nvdmkP0?0KvbP̦^ܶ$q9Ci}ӓ*qF,؃9sR0Jl,tljb!y?E!-.L@|'f_rdXdsaLV0v]K~& jdԬ[䲭WK匚_<|5yJV/JAIىjTԢ= Z=R΃rחX*X,JLei?w;{1rݒ橂a/U<.@MRo8k=kh|Ͼ~cjso8 i`:T3JlJQ$OtSwҥ_&Sú~nDFw{v'ZW?'ݝb[OU8F3#xfvbm6Yg#Ǜ`{؁\gY=w1ǍJQV&A.lAn:8s=J2/{3%#]xoM`^;{>sJٵL\ROI7,x<Ԕm o3ng]\֜1Sdݜ?\w %fBK ^7Lk -F3n NYޯiqɇ&!؍MdwV{4UpMǏZVbo\ԡc6 VVho]5,VVˁIZz?GnTK1+ǙX,MgDVaGռ-'ba3<Ӗ-:;nkæXץNQK@C Al<72gḊYѴgOeb,Ds;۱)+9F"cJ*S|!X$SVيC|?'1§W#x|ex;Ya~57c\R}D=s4!ڦp5paM 5)&ͅ :2R6coâߝ4.cDчɐY"_͒]2+\z.EX&!A3 C%lu-SKA= Õ8ZK*j:&cs,x'TɑUe.@Gc3-jᣓ[Œdrzޞsċ}ֲ-PU8qw>8竉[REKo;TQZVtYi9CEP_+ѽ.;a {3`vGs#^=N]llql5eY ʁُz̞]h/C;pec1R:pQ!0 IL< գ_MJ9G}l9iU^oKpbhJ9 ] aԁ\=cspP\cs>J+0Y dM`p.|-AhV3@8R?F{OlOZZ\k0XlDueP(JQvM5fR4{Sh@e f&:}<^t-璱Fb/HlI9*+jr_9{iX>Zhhd~WEs>jCCO1* VIɬ*.jva,3D^E.^VbB-st-KhTSuD5E#"UǩZ0;DLC%&rnvSB4Ny }=Hoē" %ȗ}\u5ܵ/\;S?;u}9<D?dEVG"V)˃]غŒşk=VQDz QzXb+ēsY(^ZJYӥ}0[bx6J Kl''Q  Zp^?b]fc$_Edev("oRگw E=z^8(xř|TqzV>zAm4mj7r? ]i:[i+"a9ľIY2LT1TDT$B Q<}L`Ԅ`Y0ća<9UN{r,T[毋*~SafR]5b4̪B7/kؔ_nb CMը88s[ǘjBjU,擒I_GÔL-? is[rgϣB*J.AE^Z4qU,ݣx˕4{(ce|TbZͅmjFPC.-Fit&uJdfv+[ߛk6#VY}"eu$σ O{"sNs~!*o.m|_7s,Opzy*wrX1|,S:UT9KYF6VI(^߂9™F6y2y;AX[KXZAJ(HY=֋wA=^x\x7R?ߴjWZ9uLmq(QJrȉϩ2gdb`6r݇oў=yف{ŕޝ%cMwme!/q 5 jᤎ1bǩ񛯦IͶ $Sǫy!hP?P[.3QjjTC{r*Da1NYM5 ӵ ԡy &1CG]{LF'}Su%zYBxnkok5*hKe#cx U7;M0VnFyE%G9a"(k 6>g\̄mƥmqLaZDdNNtsWJZ@k"7D'(DyTV6j-;Dž>\I+宵 *]WjϭYt.*=QsDM!lnb[먽F_ͪV uJ3b--TqUפ*z>Q{G3^ˇ}f-1s8bJB)GgDg3E!H*L98VMS\׈$ca) [YәdxTqS_|qT1Ⲍ,>,e$Ќ9Ctޟ]{7mT7>Z4f[a];A?;C}1iD@q)4)+ej|vu]QoĒ1FMgjzJeƏ`)ePGX ՇT^"&U࿹93URQIVP@ģ)Z$\AXl#\iԟ\Hc\,.y2:oHxjnGL2qNTTOX /3BOH~Gt xբ~W|G`,vE#MvG?oC7W6ϕh.2h( ;D"0tppZʇ.)%6#4t ] NPd#/Bdp`1ͦNs0v; L5s{'36$;gŝVNGgIX1pPn~*e[̟lj$\}Rk7ROy4,55lfJKXn̓Lt'lv*]K/BgkEWвh1JE\5ΕnLrwQӱ UO$8$_߾Vq`ߎhЉe[:`Ц;evfXF";<{ʕݹ79q4f3mby8,s?+O7،V|nk1[;:281{=|iCwlKoCuh96D} ak.\]֗Fqitifç=EWmn4F[b'78ϋ ! @&8#Xlݜ@΅3{ҫ1AW8tm54,VQZyƣӶ 6͓3m+d o])-9oAšW0'*Y1[2OE/ڠu6,sYSRPW.8Ыԍc<Gcun2~ Ln_ SS##GU䊳4HQFN'4.Ӌ$^Z"o4TΕQ%4[mkGy, $X00;ih?ΞӼy3+|5}?Z!mK *fISX|/y+}j/qoSsB%- ї]:#XaC |2D(ו 6X^j{ ›U+w V]Nޭ]TŅ2󹛷[|:&?MEB_(>N4#+#V -Odc1K0 .кeܯ͢xh_ 5tvT^ľ {3)33cݲdɓ#hK]GHS^,j[@NfwN6dh3 "F8ȇ֩~̐x#g9o' )c [~iw# E±,qn0x0|AgxdK(^xl/1;t#U~m$+^\M7XkYA|:ӊZ#8,K ` q.kž]WNU*Uc}O Z*BNZY[thc;G8A?y8CwTc 62vf1{Osp.ʸ%:kHk8V·%[ɱzuZd.vDRiܝÇPv/a4PwѾX:5?S{ңֈ'=x#q#w=Ó♁gFHO%7 faJ_wTG}ڿ8`>N4;D0;\Xl/s#t  E>ls:ַ@kMpm]Pgo$u0) "_otyF Nd (:Zpȃϲ@EW?5yKm8"6̎=HNy6CΔCEj$>: tmJtJ\C$dH-By{]~^įKT.ID{7sש 1>BOU~ R`aeYgOwc^ȼm3"Iભ9 ,ig˅I V NtTfp^]2㑁,tS_{ o78.M#qxxj9kX35h.'nN>5 3HH,°\#y]XxPwc/}*c} ϾIpRBli⠪9WIjNˠ dX>uGc os<0{t.L? J'&p'kv0sy1o~Ƀ-\zdKt c6Fwf>lɾ46^OF\h<{Eۏy|ՆŽ[VhYu?z\[e1F!9+&zɞ^ndvGػ0/ăE|>ʃь|-y+&m(zgT; :+BXĉ h.lmMeF%݋숪̝%46rA2FݳP<.f nR2kH Ԑi+c"v~HDh6Y`l.b.ڻ=]HBn!@$@;qq8qwwqwwOչ}O׹SEPZYksN =YK,OdX><ɦJ iתmKYZFP_7I4ɇ\=+ Y>=oj3#1, ,z8fY4.yniEg}ljs^ۖͷl˅/TNt^veW|ɑ8? YJL>,[hé9g)`mfo:Ҭ>&xԺ0C^i×.w ޴ruevF ub@+,2F.۳ 7}œC`0[ԝgF~=I*웖a4 ~ە;X5}_Ct ϢH2{qy}%{0q<~q=adN0KXz-~Ò{4'b< ʼsm> 8?JW/+yT_×::>eZֱUob12u_tgic/ d,1Lx`j _uH$`TF Z`ưI ܵG+k\1vA3ݑ Ydn<(._i8RZx?OOSo-r͓{>o L.lq~[ʛA|Űw6q{8YOϽ%tV Rˈ= pb>nͱiL 4(VGX)|[|?t;M%vT@vo"e2F܈*1qI!?f_!tYd>fU"$4B3b.^ &p#qKC#ir2Oj,֟K{`hB@>Mdv eQv LZ E鱶M4\QvPUK^f/AZ8D+:%'w7/ecF?yՁfLw4w;3fd2d_݈!7` s ʍ3bt.Ʀp-xv ¯֙r^];Θ)Bi$,/.d &&n5V+E&Yonj2GN9G)sJ'sL0dwgg -i+|4=a-ѕ|Ԙk0RUXj*S0tORZgX5Q˯a8cȧNĬ$r(ړHXsT:ilٓ=4cVZke[~);vHv[ϕnawKVoʣg[  =2ۏ.V`0*^ܛ+s%o$~Wp J&CơbF _fb.mzMmpۜJ48ݲ?5q5%|Ĩ6r??t$,_!z˱h@oԧՑecv^F=_1P>_ox0.X+aC̑ ){Pi*zrQF*4.kVM%h%l,?P  .gON[AF*Øk#-/_Sk5(mw[P2ްVrP!eNo9"|2jĄrcyP_u?37xfzкӿ_j'w0r͖ -91הN_Qh^H Z#9}Y&j9 X3o3]8ԝ-5ӗ Ñp<' ibQQrgU|`p]bx`5wh;7ě?XoIH@0紇q1 t^ܹjWVPУ9lP͎1U +ae~GS^EE{moI+^ؑ֙xmޖ+ }c?"nI [yge_;*K˞2s){a8ؕ/yi<ӏǽxō%NT"I_ vdo0mƥ0g_̳}a(=vЎ&6اxG wfg\(]H6l\cR2kWJ*e{ OE M8gƝ qd\wV;՞1 95cXC4\>69c1@Ջ@rbaTP1ˆl-_}i4G24#8#ɅaĮv33= z1 pHo=?"h[Nm~&ܬvt17/S:r̤01ټdz&mZѕ?Nn?>/״oNG%9.'7B01='1frt'&ΏGX=ω< Z}ݚ::[L 4HBi;yYe̽QϡnLjYI/{e8e]Q|^I#d"&ģϜ@se>'nb_Z!,8$v}ῄNOL{=u=4JTZqhc/9PMX {,%TΤzwZ/qlX|7C=2Κm1,[ƺҼS*O : >Cb\CM2LyiNKތf@'7B Hxy*w$3†˃z-_ng'cPEaQ +$p/|xߗ2*O;q\nV?墸b9h i=b{:bi :R{v,mwe Fo]8yt_fGbڿv7˴會,( 6ȕrٓmgnVhq%hH(N-ox5cOnօdEAq #:PG5s3mgÉ,[(JuDSt33mʛUKUm {^s_?޳>櫶I)iy rt;~w0@i_fkc+k@]p"bFbFU*2Ē Xɜonqt,ʽ)LBN&eu"o$Pi>=pߎ%Q^4#[ĄʑALƸ,3ƘxϦ{37纰~j˜9ܝq^Y2+π{~osy!R1A)]q f懥Tk9j(IrِOWe[)TX\~\ԍ-sLɘc͹Y,~4 yxbTP#FA!ɋ!R_1r #U9/UeNF٫ݛݹߌgZ1PF|-7-~݄Y;M7ʆ<) Qc?I3Bzܻ}^J@KrWm{b(;Be^8s};1ޛZ *0'c/93͏-sH wF9ϺY9BtuY9c.yByGk ?_&SKʽco֧n➍΁RfJe_O_2/ ʔ5vH;_If^II.jW%Ȼ_mS4xC~Yl[L*i5g.r$]džiu jns.\şϝqbu3 @3N?; V}7ߝ祅?ȻF?^u{tyTa-kwGn^gh=07ڷQA뎊+4w'ߗ.Δ8"K֯d VDOo͡hC^^iHԘhOrsM[7kxc楋RZ@GEaDE!=I۬4}\JbW`BspqN st|I e&=A;1iry#ޙfrҎ$6۾cOCr{+)T2|wz O#[)lk}4*pKԺ oHD uI oUةHȼ9[6E@eEa-ŧ)نK-SD1^]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsnŌ %қ n7-)_ xv{'WÖcRtI^%Q~V)?2'G[#O7}!=ik.<o"GKޭBAEu~w-{_yݓ}_wUh؞#wm 9Y=AHŗFF{3 )3mQK>W#oʝ,7Ry&iX~/ߔo-oz@҉/rޢ 'JmcR~mIJC%[яzK%|߸9fr,[]79$Z*֥򞌍ŽWm׋ ˩tyЁ:pˑ2=ں+fjGG?aH4ȫtV덱gS,'/}%-YlLWA~_[ [3zbF֚YR4.]TaS]5175M-[ R~rW5oiv^n}$gHܟ]^SV Q9R1>Cx壼G\4|)9_~N ո"eH^_?s~{2Hݓp{l`G{i9XUSwҏhNEYtSeكᮭ݂ -3sȖPwʶzσ$n-&08]Hv>H`FH,}Ro4Eeoĕ<-K|nt}GGm!-Ԁ~ {>m4"k r!/ߚhH_OFv}6zx=E[9!pp=<}o˚ocn|chNU $/ܔ(JG#_ͼX=7iUr^M:_Tۗd୫'|]Ij&dn$bh |Ɋx n#ik ;Gɘ za<5W0̀luoP#ں?VC%CvH=]8oKSG[O; D@^[GpJD?/b]Ɖ^<;hQ˝N|$_N1G.݇ {t:nӶP#*W3 cIs!ߔp'}}!A؝p\}*0H"ԙ̱nh6!M~+C-_~K3R\eDof-]-W?̑B95yQ-yjr bvpr<+]):Nչ@lC؏<2Χzr?Aӆδ3c1CUoak$:by؍c .ZӾ7F`._#vK#oM<؜g͹_l-FR%oX ?~LkrGH|`@ʾ6SVm=Ig\EZ=|/'p\(Ƴ)ʋ\S:A{KZ^>d8>;0 }PQBNbBMHQ`!Έ/Ȫ'Uv?#t1cha4wemo%o7YI.;ƏSλ4Ǚz ^0'}qFˋ^hnEH6q[HGТcp^_tŅcH8ccrʈKe?Zzw(Mshs#{n.Ou~!4K8_΄+f HTS b=3!x}6ƑE:։5L)}# @{aZo\i\V/e[))lՖLɴ]/Z0ޝsDGr ^A}uծnv cU,2ZE>3hj*ox@Qu"P>Iˉ&bO;#|ZАyr')bTcS w"G,|q>k&$nSb; 5AoGCOL!:K+Mu,ˌx:a49Ci QWvfŌGi, -fǮraZp$3:7v9LcdO`(.n pOUiN+XΑՂc=?h.Qܲ"G='@F"9p`8nj 8t`_z۝g>}dܯcNI&!?BL9cg>2Ǡ@s&#oJ}Ѽ"T(Λ"g}N•_ 3U;w'u_7[9cLi9ŌnE}g'yT$OZe;gI} I<ƲfnD3G٣˰M*Ql(]ExiWGR:o>bc9yEtc`S[+}(/pi(O`Rx)%qF!Ti#l}?&U<[o?`l=hH-33%)J%eJ'3̄[+_KѩV(4$uks[%7pD@iawb9v+;r:#mKax`co79fteځ]Q!3 |#=:SN{:qE2U0 Tw.9q[4 :d={8_GS8|*piN&9Htx#KO. avHbirSw '%26c Hݘ0C.-}Ã2V>NE3UL(dŠ2lFUZNMgh)IXiahng%쪙bYr,=B "e@O1Y_:Es'o$T`d!ax5g|DY΃G&4gJz9QQ/ JN܆Dʁ'd |w&Y?\ >|.̀Hb2Cb2QLr++ݸۊSl%g=VF$-rZA}KOc3 .bqNIH ܉l8⟗_ ϥ{|b2:|َgj~՗uQj%tvͱi#WxQw#1i#X`2mП#=/+{ݔ5259c_Rn)qt}:MlfX->)c)Rn]/#PrBq Gf$4L ; .]VlVDJ^ƎE=1-_МS½N6dIhk*89oF KlP7]e{qҜxU5 HqY>lE!sP:-TLP{,?BxÜAmFc*wCwS:P]w:EԎ{~(kp"j|YVºRF*&G3R{"ٴ/E1Ʀd̯`rSƚ2֭T~-_d(x<ғ $s9{s'p$WbV]%Si^3IB+S.z0/+#Z-ݢߝ0paq'k+{`Y",pV"=ODazbpؖ1bzLրNS i<\Az=BA q(}#9N1p:`.߈¥0+ J!Z`cxق5l╪=ZuĩƔ10/a8ȋ2^2C!l?-qV׾r K,O D!KzO!-|t&KOmty}y)܆ C Y([ӑq1^w kz~ď:DzXKxr{yt 3ՈtGHn(Bf13.sY~.|[TD¦bBۖ&N% Ǽj;ՠ{KIw3pۂfs|8(ǽcXIZ~Fg T-&h mC/Ocp :>VV-q_gҴYb- :I4<O 5'8^1ơtJ#/5sF n=࿠ރ,!s/Y߇>0|?Ù`s*]sF cM6a馜o+2?.kξ!lse}AV6)ؽjsV*g🯂6f#jO'ڳlw(r8g SLKD%Gzap*Ǡ1߳sx H/N;هn}Ãڶ p5$Q]]#e83އHTfDϥ}h&VݢRC&j\bijͮ%Yt|WDY!?# k׺!u6,ɧ"v(bk"#xY1:V|W-cx5:#GhFS"z/FE /˱}_;X^"</%X:^QRKf'jqjRO:_3,CN10[V*al]ILp>0^-֓sۜQ!{_[ȶCKhv+3Bj09Ln>mP78Qo…0nhGLX Y螉Ófd0*_os>&dD+, /ܙQk}9%I,SEOf@x0ۓVXyW7m4hn4ghW#}vA eIl92Ým_}'#X59;8g01;ǴK"+'@JGZlťya(C9cGpnf$R0^%Lĵ,zf] =in(&&Az9\?¹.`r>Zhk@ &/aƒJznC:.AzTI 7aQC >6'ʱMCY}̊Ö{e&2`6s*6Qcc._S"q4`l G>.sXnsl#kS覼<] 'eJK{ȾS:'<; _#5w ٯ973!ӕ3zԠG/SXzEy'԰\E2ZŃ mYߒ',DYh\|k5*[r+C8"هs|FlTҠu4I&=#/$6>#hxG~x8#85K~Xq9 Ah/ӕͽHdg )ٛa8ālpő rJTjc-#~rߓ&M"ر- e +1`+nbMAIˋ[Vō|$.`k(|⚘q~=,8K2ݩ$k%᭫QMȯZ\3ƣVЉ8L$g%da?[z9qe9RE9OVMPEjXk/ @Cs* j߀D 淗;}:ѢfO7L=P5Sv^yC忒g{n.VH`,#.o4_15SP )+h8~EK0Mⵛ=pM,dZW3nGw$0ɟ! 7┄Ie:`@"s2Rf3 |{!t".h0Y &x&>9:ލ}8>cb]葨 'b/EeXʋl@ޛJ t15%݆;0'Zdm-sMN$jouvWs.t7Z < # /vy0VL9^qù&앃mN'8ƒ^/{3F2ƨh=corW-US5m5?;8S'srGe"%47c+YjlќWA "Ǔm2VMc-t<:?ȭΠ>ğj7O;`=X=3b;Y0ҚÄ9Ȉ]ELb4s[:KRW/*94ڝVwoeuR^n6?0lڧ|9\=%itΡh&}f_%p%4% CiE*'&b)dD&SIs1VkĮ{z?7鰷b-Z]ܭS]W UZ*;-I4xw8lzg0H%iue5=Y&a?nf<4?a2JVK'1܇˃yw:*>H&sb+{sעH#&`J}CO ?rjQ8+s{@o%ilNoMiڕ>%d3fN gǿXPnI#LJưjE?ߑܙэ{ZqBwlG!\hO`uEFcg5Xy|866tjWd q-C )%Ę4V RtJuM5C4xA 7h9M38#Qq\\'<ngΎ kGc^D/AD^TO6'/{N`r+ 1o˿&“g;8N3kḵ(̑SY15W.)_ <[P7s6F\&+EϦ`o5MW Bh:-JZE#Md|!g cb(&{ 8ŝO&5sQS4,u9_iF%#6Ho(3EVAFd|gQ# |&-GZ8mj-LKW nLo;l9 jǐ4i(|θ} l挗uh5'y.̜\xӅ*WkiD.jɡpz2'.޳Ǒ<5tĢ#xlJ+}hqҎ Qdnea#83YWƶXy9M nos^ )՜@5'Q{dқZ;uаm>0&=" 977yʏ^l;2'֍j? cQJ.19F '0_SArg+gDuq]ྍ^;ݟsugqKώ~V6 gAy)ʠOwʨJXRcsX@9 ?o:p\< ]KYҮ efѾ#\} XB{R;.!nطuV+!T-H)\B2JQ?FCu. M]≯9=Ie ijFSyà\vH#c9\iؗbtE(]><*|36ʧ㹨˕q(úD^qjo2J<2̋Q6Ĉް7|(Ŀj~?юĭXP5T݄L^ӛ}{ j\H82^T rlgģx+-3x)zj7+'*6SBCQ -V8sI졎\adK=U˩T=. |h|WARs[il aG7MdPQI01TYCiw0di? _XҺX-6ׅ1?ٗG#2$&/(8sWƝ9|,iql܉N'U =4/b&=C?cNijwz6Iګi S9-%1av+:gyeU(o7e0jy1r{ kmRm;+!+ AƸGOa *(C-j\V{8525E/ ;TѦ eNo%Ç]͑iAĆzi{ƅOVOy2N)Ovqt7ZowZ"? {Þюv;б08ђ \6:)pb2[2 ;²%ye,=z-kmυSWLJE:z4D\Qrt L_gdJ#i#ty#f43o)#!Tõ"Űӝhrt'|8CYDf>J}05#h9~V/kymG6$Mԝj끡ByMh]hϘ`< #u_{ČX)gTS8'cQvQ(6Ep/j$cuM2;8Ϟ8 QN^Gʈ]kn[4L}t>M@==zkc43CVټoP-s)\\jRy 8SI0<ᶢUҬe\ȢJwMf>f"bD-ےzlƓ1Nja{8^rg#r]ݮ؏b9ǧܽK/5c:5Vmǧc u753Ew܃1 {O'lt8&O aE>X 2l܆}z҆y'pf"L_-EPB},~Ř'At j`%V÷ݯ\D}Y_AW"Sپq/)LG{R4}'Z*R밒GjH ׸t5|etЎ-?Fq3SN\Q$tۘ '&}\/5'+妵a]H[KNE t·>T* yԳޓtĄC oXv#K 3_2c(D>PȹOFNxH^gKqbY˓TɘӡR,>*vWcSCţ222!|1l] ڝapz3gK~.g4ҩrwKCj\d/IîQM>;sopQb/ƳG#9x#( im؟SǂE7P<ASj\n /uy JMyt}qj,mjȩϡSs,mxl2̿ e5?R[Dt0ɴ8Gɇ[ƢF:_EJjrFCȴ)a=:USSNoH .cϝ]tlJ{>\Bas loMg]gu3]9>8ض-`n 'H%G>;X(8n7LQ~E˕tr)J5<&uݝ@oȦ|VDRrewiOݲx;ۦ% S_ǍQX~؞HZ)hN";=(A_8\'o^"S5pFe(3Ǯ af@3x6&1hW8VbЅZ驷ZǙuJmCAuOwD+6YN,l˶L;YC_Iğqen]\>Yy_%Ǝ.jvںX/!tt=mBapOfZt!㤅^%"385SH?M|y KWP?S)Zz䆑~DӎrYGKeMy$sXFޥ\~=m\夳g:֥=_(%sR3< +y6}Gg >.®n%LtJYtj>d֢ɤd81awncuϑ#0pQwfZv&Z$9)cx|D&D3:0,wAOY5:6#Td"„T~nD]璅]&aq: r5 VLx.gkVDʼ/W{3: ׄBF~(Clp+I4=DJd4WsߪR *TNRff|*c3Yb7ϝL'pHo]ޙ};ŒMd(/g vLr("x5rB}E_ ֍,&JyGr&(bO*/ReTJK)~S\B%,O+r%uU§N(h4>O]g \.~+9=Kɺ>ث5A *UNf{YیT#elZ#XĞr+#|w줎 nI<&?(ıcϩq 瞻Cs0J2AO(撤$3e 7~͝C8{YKRuغ=±]9&_I:Hˣxs8AXno'Ff7/Z%jER_Kߢ ʨY $UxLDm̷47&{zD|f~D㥥:#;|W8RK52y3A2:३t}XBJiz *J5(m -nKe55#Xy4&#X R9h IRzJdn1/rvs_- HBr D>6xw2$Oey\$|cù|F-ԭ"421{NE{*Bn)oF{ ůԼTʾ:֒pR:b{x,+0R9uUrCWyL`»q[۽Locf|9e$=k󩉁*o$^cRϗz^x)~C\W*Yd7+X ']l5)8+2%sbr~~s%0 o?\g֍zlI=.."IqxBzօxwӟmTi`6E}Ql |ʼns?OF oDXkU9 eO3!+cdb|C#88_B)k`IϾ<C F9^ݏZ2L+ej_dCpOѳpn k f]Brl"er.OSQjMÉ?qƑ6]:"rʦaS)X,K)!ld*⡄̕EY\O7,¸u4s#Sʨ\,z4f,2s3 =y*\K5LRl |hn9ļfR-ٽӞe|g"z }&\ 1"̦F?\[f!F\  =E褦 D͌[qxofk9Y 5/PeUqۢXi hâsA (?-uU6Bبӵm_ύEұ8 ܎'_pDC5!|%UOObͭ`Ft.Q3d'aTފxXyLԌ*uU^|R[ʙL 3UF[9YK' k1ug{#Ab.>v1jQe]Kѷ.%Ej%g#!4dƶxvhW\ׇ3͓ۢR*d(EQ۶IWJ$8xߣSE?Q@Rd.{W.s\6z!9aC94=5?h>u*]l*FӇF+i+~_4cW$140/Y^1-D?UCp55=,rP;u`dI#mMXP /3icL\H3Ut_ZUPǥy}OϮe]Y9x/Il5X2pD\y4GdKz>aڦVk5%\+>y1b"}Ld4lJ|~z9j _WYx:w Zĭ)EX'QB>ΥF|bok2+Y$aE_w)ȟJS42dp^pq*R$O^D}L_i<6RnS`Zq 5yix+b:jfw -Y]: XUU T%6R33d\w&+ӀB/vB:^ӑ{R&O3/tZƒH%j@@Tiɗ$%+%Bn"?sČg䪫BvmVk2,k7X4n Ng kh?"BpGS-~ Q= =_͙&>cau)[`?2vO +Wh<+y3KؖiZ\}Yh&nX W ~2,+ɼD~+0~,lV=WB($nlWཾj%,+F,I9<˸n9?Y;g1t|. ^eb3x5_x,R'0^21VS&3Q:LOSJzVK챖5hgU)suҳKOn4R\OqqHzL1RfBl뚑ÍS66,֣g2448LCo)!GD(YwVnk>,Բb'5Zů-$r8ݯo |<?N!0ZU*p a ~#'{8KZRw$PAx{qwO$='`Y427 :?v8t'jk5]̆+"GviVƿ8|̿g >݆JL-#l|m`FsD 4A"ӯsRKZŬl`1!*i{C*<1d=!]NߧKS+Ozw/erI"ešl_VzjwY' X.x=DVݧ1~F0cS~y&S %$yjh-fLd)roP(W/4v2X[bO+t&b\Po ekM,?h#y_;ޞkOײʨ)2U/g^r4-g@f*Q˹w Y֫e9qī&fޭ/3WDo=Rdދ9R_Dv+JAá 1˲DVn{Tp9nR$o,CY X$%k1d͓Y1I 3A8>6jckDd%vC3aDn2y=s>&ccH!/3EɆJqhYd(3p&J^^2j>"2!kSȭ[ 2[E6Ϡl\q}cUa03N3YY"#o+3U͇ t o Ĵ89!ι\ߟ)ϫЭQikc~'98 c"&/ 9 WYX`-kiy@ŠUR8:BqěI͋A,qIe~%:o򻑪 Pq>/9hƩ]3|k\&ΈppH9~e%~Q6D\odsky3qXW͔mMA;(*3p١Oֲj,N"=c'-z;#Z<VSX VZ+y>gaJ;Pq ?*+Pq_ʁj6G(YuVΊtK)|%󗹸#?52/̥$H*!.ۋX8LNX ZiO_tt4r_29" $tIO4[sx2 dCy=b/A; tjQL9{kXΫ:3p&+iHz^A:?)Ė#92k8_ېsg/$px}el?5+:-߆dz/$Bd!9Ows8E J*FK4B47=yۋgq?\U69q[; d9t"s&I"JHEr6SgbyPt7ed0bbP#/S5䗐`R/r?D[msꇽ)utԑzGO5&ϛh\0=f˿"1~:j$1%K( ~6S8;]4U cR65PuSžZ3m9f&fYTV:<<8VCtzRDY+żՑU˕TC }&).#!9oKX3~U2FՑ8PA NV_iz\QRɔh#>g5G*NNZJ w(TawXjtSM%14hJVGhŹا<%1%cWxsƽE=B'(8y9k+ڪ+Xg̜i$q"/ fa#epjhҗ>́y^8!қtŝF_ÞR[Vq`%T? }!o}1 NiiJ@3'DƇOݐ.{]_֬C5ՓC-! \oÕA|4sK&вS i|r"-Ob;8EAF:W# }c.uS3)z6Df,7sI0ҨGsתzHb&A{i"":.X(EQ!&SË- R|W ѫ1vXJSni]E6y uNhg;EvnZ0:564b`ȷsT3̨M-4גzUŒT#k":&ɹVFt9Dǟ(a)8>+籃OՔԐ{X#ffRt ]TdqFqN_6 ^hx^^K:'2fK"//ǣ0qɎ$u$C)\A)jɁۄ[P<7gD<3xo&o.T /+9#DvFNɅYt%??Gl~YҤfNerMa .yƓrWb`z+|Ə'uчT"0z n%Mmh"XiC.anbEqcΑ׏gc]\cq~5 )43wnWUfy.~j6<6ɀr WTe?ˋ T}Xʑ*fq$; ~13US^ը1捂Fvv {B߄1̯=sNcYY-"֣8wϊ4>SAb#KR1[UTOZgh;I"+zMƣrFՖTq6,*AW3#U\h9 'kn1_<g֟UL,QS3zj1`]\JKU5WʚZZxIKFj ؼ;9)^KYXe?ku&+pU$9<힬}ZxY戀oiK;TLF+gK z,G g#3E~aj75AHn4uqJ]dlPb pcŀItKT-'_aOϣY{c 'ULVN\|gB DjdXmVQ }5 ;4f~6(cD${Cύzv$ȫr/c54#/* Lys.|EuL3szкFaKݿ  fQ)s!˄1Kk.҈5-|.ZjP.Htd,~EFzmdJZP3u}m>mÅKfz+ 21쬉k+Zɺe7pg)3kUɫӸ;6k=HONcg'gwnnpLBÍm kki-}JWNG[0}PG,]قG &}jݿ˭6w,J,0t`JVYabAg:Ы3vVޔ\vG3/-ds19LGFj/cFr*cF3me0@ӌ),gĔ\`wq&֓?OSw%^v/3èxG`EpT8F^&\>[X:6#D3z`\+욹KAxea͘U r4ɒ[ :%,y,RAfr6^FRa2 /I>+B*V̐q9EeKK9CJ#-廒[b[\O5u{*9&rƼ*^Z<kݡR|R PVb`h}a vJh+3|*9Y)ıaE8,$m0B|8G<hxFpH75VffI%gBXFZ_Mll 롖i/4q/alR{c"YΉN]lp`M=CّkG^(6{2RŖAn â--8ٕW^8Zn=i!E5[Kma(Wb?.o n!<Ru'vy!ڝ@39v >?dcпe/E̮)4lDŢ,4Pș&38j 3^mY#L7Dewvq:5P/*ch!t%-> G ¬{? V 짰o?5cp3[PZGj\U/Zq@it"l\y'jżQ@Tо$ci3)dO+febNyȱst ͪ\D_zarlٰVe%W0OMJ ;Y^]!ЎJ{?J˞:rU_:iYsXOۅzl(XNfEK4%c͜L*S~ hbڰk vT}sU-ˑw/g+3Cl̯G2~)Er,-R?mOp1jLg!&uNu#k f1,81 Nvq^hK[͑1q/?*+vva }lpkjX7-4CB|p!xt7֢MBwkn=^=Ѝ[] _‡ C[7gxM퍦Mp,&g"UcY=')z䒵W;= 9u)oZVj7J 3Dĭf|1"D!F,ճ8]K^Z:%"={tY^3u.l,hIhb+aa#eKXw7+ZCփ U>'p Isv)渭j(៴"FUJY5ZJB H.΅fMHUu:iy4\NE(Ls1'F4(Bb9@IehtR\O==2tZϚ FkNNA"E|C"ݎM;F\=uQIj2ƛ{qM8>(R(x1 (g r$L1\[ޝBdDB7.O6wW;I[[Uz| 5o;vnpb8]$/DvI|<EVN|z?ʗ+͈Vr糒6!U\:\-4f5TR}TqcSyfoG( ,K`ԯq̘7!m^<A׾8m=SH\/7ʄiˡuxOEY8g_)c(c3 7by a^m:G \XKvym0Kғ-Sg7w W&'2sL]2`unѥ.=d,"tْ-01̒;@pV*2 )e"/HQ) )g˹[*zR2KuݮRW9Y_e/e\ 1/G*'{R ^HPF--R.Lzkـ7~6Y.N!Lێ彸0rΠ]W2~>Uf1ݞaAJ܏LyeY.;:9!}y-$LL^!^-S~9ltu>[(M4ΤWf ӹŐ(0kwrU{WEz6/!yv sKؑ\Ȯ.΢M4Se\i0O^?b' ͎hQ\M"'^Uu%/E7 "c>H]Tɕ#5,|Xǵ+Vg}SFdāE=Ґ}-YW2Q-TKegtڱcXs'ZS)֩95]b>.?3J@3ga0Đ2>s; ?]iUX49sGhJ9D_7 >[{(g.gS%zdTK2&()Es5}DT袤2 rY/ 2T{<{O8&LL%[lӘ+.3`"'dso ӗ0Z7v9Jfŀadl>̠zw-rTY7 /:H8!v>oMfux mSoJ/v鴜ΓU4ngan6w߉?5/x_L^xLM}(z {pQ▸3\hړ_u!;NU{n]]%ל['Cj5*RjU|WJz]Mjɸ9OD_k-̐;fg*&iv[u'te^$h$;U+ԭi]]JV,/#ΙlWΤ1l}@}'b~fqtP(ynܙcɡCNǷw)v٦WzxGx5џ6}דmqa4bQ{*5ܘI3/>6Iˉg`RvT𭽂v{Tt\l&*/IH*{6:=)CScZ.G \Ɛ/2lhϖ nkS?9b?[ʘN ~88uUEd1J~,s2;8c3ϔɳrH7V&%Tgݶ\-dt֟pI+LY!Ez\uρh6?R)E$4 å}tޑZ442yZ¹ /cX:)p>q)lrxq!N=qIhɼ0N1ty˟ YXd?!=׃mܘnV,5c↩Ttekݷ Mڌ+_58LyE9WoybN_AJb%"d8"h(CڬŨMjVrM"vOp'v72bpזG]3DYb5ʚюȏyrb gQQ,ƖF}؃/cC9f VyZ?VNek}MV' t&iī~Vj:QT`KZLGj#gOg'plnt%4(Lý #@6\N<9K.*` vVp^dP:q  ⌙ ".$| &R;)6Rv{G;%9;|L+r>o.goJ28QJ^[/Et< [-^QfwڦyQ߬ho_+q 1RI:DF,#?~XƇ&CE8jý&Y*O6fG3+ygɻTU%1e0s.{VCU3 8\.])?,J͢r嗳Cގr+%2{p! LʯXqۿKX]]1sN̗02DFFZĩ(Kb9\D$j ܰLdXFUe-")wL:S>h@ q7Ofw"Mf$tbHM(jSߗžyD%.-6LY(͢W͊λ?֧[; {:-w^81Bv)a~aѷɦBG:yR顧ĭ0*UbI*~:TǨ}kXն%*v'03K190xf'G; 3 G-Ci_:5lo4>FRO |:J:De4>%0:sØ7BuOi>҃C͐Eۡi_Y-.9"{_ş wBQoG?n[xˀƱ3SS?JI JPD969]\BVQ(GVpꦒt%v)q3*E KƉ^pP2v Lt?KsJ"Mpjmpk'W"i `мu h^J`g^Y"0ɰiiLV%D""zHDuRa0K%^HZ ՇeU x7+usneÑWSSBq6!cRA+ip`гV!,il(pA`8bw-fD0brqXW\X]A{VIjk^˾5-/yv6:& gQ~ŏg}Rs㶮f(ŊcE|gbGK"\Vз"9l~^:?(l{A`iԵ𭏸>{LGo.,϶C %CjL".Q\zЍ7"u ώ!>3t~0?,|netݧ@RO% tv2RFN)n5Aل%fbt"Os _2 Y;DFA ɝ>yUPnK քr".U2LRr~\2oVN~ӕܒ J癆N .2NSZ"ctBBP |z^t*k>VR:1Q ynx,gk%;BQ>#cXKU Gbh7=^HfzT . IvI]΢zӲ hJVJp#ʳ,4gxvM?p/Z3GaVP<'wvAYt7eԟIPDw>^f|[*6ϫM%Um!`o 3'KE}fl-empx:MvVkwq8{iliBӉm̔vt ^ 8_ "4sIܷ{xHXe̢)Gy3T. af̳F8k:cV"$e^nNx+7M |&F9?#F7sVOc('yVG\EvfR))^rvy 'ldDAѯR p:򝅌 G=QE|ϖhpd=ƚJ[۸c< NغruXT`YB{|fL.iRl&K9q%+fG 4Ky, 6ɘQF,}3b! M#j3VxSHN6FgBEG刭/qwB;J%G"уEXC15/1,_$ne*kQxNvdo!spͤG{^:ёVߘN d\:^pa 4.$m_n2M,՜"VbK+gH̀z1 x]f `[i.:1qȊ87`V{Ƌ>(z0al_(mv"{ƋnH &*)7(P ƍf^lo? S09!ry:G͊X/B)z,nl0oRJ'A:]:/F\uEi2Ny*u,#5 SKZ6fF ZUM/L&A;o8Pō])lBK 0h%NH<׈PX Vt)|C3&;9s<{tVeR96(ō >ˡp.t#&èi 3Yd=f~Ak0n3O <$,v˹MN4OGcwoa=H؄ Z]$u J9Sư2o+29K[ +9Ƀ=[J_VV~y_ #E$zjjnGxg8MAZuXکƣz+VdGo7DPhϵ2z,Ʌt z؈|1K5<\+w)u*rN.Π;hr.S#xtqF<F䨶ѩ¾/"o**폧y<}:ñ2E&3a:_,1h/E`#2o̦Fl w'.d_ks1Z XaFٙ ͚gziANZ_֥Vsbߪj&?g4cMI7 ڷ{ӬDn`Q 8.qg8{2z2PʃRڦ%rJS3բ bZ".y.o0dg:b8Pû}sx:e2{ ӤtMȚ~tѣugw\rZKٻʨM+Zx)m ]i-G^%.} E+aˉncW31̬A8s?ԟ²qX$&|QY ϐQX2~ODz~b2sh-cȖ+8sR 6[W +x`> ezN=BJft2y>thL1HҚÆ@[Gr$߶eǂ\rR8M9Q耪A5~ZǑ{:#x퇶a윭ͬ8|_wjVWTWnwU`i0_ٮ|/+[˹be*:+1LgE!d1'͜C9ܔu)yvoWUVmW[Jʿ.8FbtdaE'/ fzLpb[±{ ҟ;OXdq芽M[Fm;M)2Y+Oƍ2BROrQ*2+TKRcka*E8GBBG>\6Z3zy.cOg! ʦQ.3Q_Z_gL5L )YeͺL/c4؃۽Y? ;" ˆ8捭%%n.m/U\pgI^|鉱74N3bxWV1Ɍ`Lu-q^6#u#(ԅ =m'.[!T^Ri 8ˎ.M~ɭ<>jG#:*LЩ`z5eK wkQ/e*V3^-h3:SwU"wK&w B2(AFg.ٻ8q,N͗qg1[fV ϫŻJ3h_Ü +̟Z{Ӑu`=^&00dGj3Bҏ{}YNN_5")`\OfhM8Us=92yfs0Xê{\yM98x7[;r%&cXI21 $bK ƹM(eY0Zi+{ f$rd.yN^́V>N3HǬfn͗;21ɕa18Ϩy G;WFqc%TQzgT/KOd>Itޢ.c{ v^?+}{fm ՚ 7 ¬c¨9͌(f'[ѩ>#:H?DSC8Z>$xpg4]ŬǩX"8Mlofqu}&kàZ υaÏ 7N > G~j% ,h? 4;H>Epwy{rއ_M6MlX E~9@ӄZGmU[?F 8Z4]ŧ_Kԅ5>SMJ6R9!1XBǓ3?<+D-Gޢ ]UTά(߲JyY3!Ֆ Ywm:jqmS{&y̳diVX݃n3-KүnTΡͬ<xaOKx.aP/1cкeS0bI\T:wǚt3vO5g>Kr0ß]ŵ3?/m+V[ĤYbO@~r:Zu鮢˲ribVxqZPx=k{m\XWsp(V{mrC01kP~T76KG$jטtt^1-"W r!L\y>ӱ(S"&a@~_,|TpFpc4G\{0-^bu e76LMfgmD1_55a1bwqk1qE٥=zLjc.jmW T>AE-(gwʘР$ko9i\X'%/A#xUpuO3G35?l&% pu<ŘSXR)²cn,V֡ބ-`d2pH,yh.>a4v%Gq{2;*QQW*w#Jy68TgF3?ԃ,WcƄv|1:WqMs-.`ԗBt< 0[>ƿS\66CQY.׹,]X~wI9G̪~mgQLb4,R4XJy/uJ)ɌCshkh7 a3C5{Z@m`B87\:Bq$%ߢ4?K$uQ{rDNE!L|) W\ +ZMKF氮eɞĺw4J, aגp#x!xJ;rn",|5&D&ec]5 QC 7г}-wy> RaS[xgLʋ$mrQ.a96_ {&?m'EkvBD_ˈz^')ˑޓ+@N *bP0iX>˯w n5|0{{ZLsJvJ5 õ6 -wgށ`l bOsp;HcS-IId&a`$ڗAj$JLf\|Ө+'qJؘYn`H exHf˼xE{wBhx˜Ԕ "G FZc՗5ོ/WEsk1X[_g7>+IMy,f{-Qj6 5<YKa5oVTÍDUSQœUUA t|gy ^VP䄆%pDuNyr, ts̻h㹥-)ë?JP|aN!u^[ɏ*Pch;?e3_ {<5 EЉ5ఞ9mEpݛ~8.fl&7`#gM8]?r@\(PcJhK[%וLR%K(JLi!) p"'ZB7:4W'?/K(cz)OԥLz.%\wK9%9jr~Xv{ $_B-x ;"DPgi)dj0\ f'PL4qlByhHU&NI8הX nKyv2ZXM_"Ki*@ Y+Q;Z Жs$˙h3k<&*EM FU92&cø:cF!qx5Yn7R)}ܩwDgڄ8&#XyL3`?k>tM /Œky"dѲ8&3rG?&z1;C n݃;pbdwZymhiMnkh<}O@8q.w (Sp OɻؓNph&yS%KWuߒ)۞N'%#m{W~I"# VͫPbJre%E?yWH/iܞw29z3ci}2_y<~OhPv>LET1 ͌y,@#Xg:,u\zb޻V8/ej]Œ*N{_{"rLז~AE0ߟQ9׃h{u3a`a5db}3=VkpVQ,X[Fq#$8D~OsJyX@9U ࣪x~Sqg9|/:jJ*cކ2c'|>WGsƶ=.91{^*z%s)AGCjͫoLvGu ^4;ΈH+ydht4o6Hssտ'g-d )3pepʺQ3t*fJ7pBʌqr!Eydjg*dE O4-PWz9)f3U.Qź`9eqD/^'f@iMkRIfb5$Dm0ci<3^$$f*cY.29mt8$g[9TUdOXV f**˙YT 9lNRt˷7Od$}V Ebd~k1&46&<4.Et TR7 SKZ&pG[$ȥ9+^aVO.[ OFR sz!I\GI$uX| t6.!r+2<~TUnsi$a֊T$pkU-~NUݦ#\T^ɋÕwܪ*F!4NLhZK]:K꘿Z'!UdWi |!΍ qIQ//`$⍇;]mI8`I9m|:nF9hlT;rпǾ_H4aWp$#]ɟڛI4ϡךbHY09Q_DGn[)eI _S~R|R/D0fA$G0HJ8+;EW|ͮ]8/5";y",a0nb7]Zݏø4p}&1}#$Yn6/>qxl̜ͰŒF(_ng{wtR>b&e ic9eʉ){Qd96+Qt&])=ݓMƤ Dd8Ɔ+l $a z>[DPĐ\a6a9,ܞ˕~Y**:Va JQq/Uza-ͺz;ww wwK Q~W~y;bf3kVVIv6\(ǿa%/ Y@vA=&n&)YNn_)VbY^s:RUrեjjv"`#6WqbT*.Mg,s߫&aZL~E5X&+O9K)ۡi){v*cWk)R>e&QxSo =ؕM/{deͤA$;p2ʞS]7IX5QTǺ9u}lfxz*!N yq+B_LJ|P3eĄ]:/=sh4E1}yќ1glž'&a ?,sٙLLHg΍s\of\7 ܸot?kh0%CN[e֧a {2OåL 6 4 `[ ;|\+nQ`ȷgd+#1[#7qJc{ffrTGrF!-߾z+rOʔpBAES􍖟J3ۏzn/ѡcg=-2+x]ZԘ *ʘMϒw:nQiG[q9Y ZsB9gSqG,8U5l{5Qt[-/kX7ɵ,>YDžZN<[t q{UCZ]eIͪ]_ɢɕx$qS ^PI r3{?e4j&bB1r)d*T&%ԫ*%f/4=gLZFv~)Ki).{N.xHLJJJ{*'zsoӱ:D&e \Z.2 -w < Omj#s57Vsxj-+ 7Yx5cXY X5T*]]5qUlW۷KY/dƄh)┆89b?Ic=Dž4sF9SLpFt5pQΗcʴcd D$pq6R:l_!/ rN9ދuDYXILkQi1yj nXuC`. [VmIk/9 YVތMfP&pU ]tt%_G:k]y0o?ƿ a(>2ZX<)`t) S19[ͽ9jd+U4: OKs*/f5F&Y`L15ixf2?ѽ-s8;y#⨛³)űr4"yn{!wuӚ^S ue(. l|&/FGĨUCsdt4GΣ{Jil9AE!a54WSq#g97*h]Njv&BYȋOݸÎx.-yj >q4G2?TJ CbC7 Iy3[JլBOD=(bnO9;NЦ^==%>.h1`@f%,sۺ # 8 sҩ ylPe NµC2zoP-[ uO.%W_OY5*.٧8VTV=m}y5fմNFS\M?'Zrk-o~TsY5fJ6WpFWIħ*Fܩ`xw6YxUKaRY@`(9 =nCG8ɬix͒nS QDj~F]MZ^wOU&ލ%\"fLsTUV[2XH4-c(Z85lcr(~X71gROp%Z'٬̧UFQ?CMWL oZ'QJ%}e!ʃ,2ޫ,j-.&r‰j­+XW4UNP`<.uu`+w]IɎl^1'fOEyW͟{ffDbp;.%tXXH%*ζ+eo2G~0f0jQñ2mİ'bq$p^G$z[ϓ^LABdÛtil)JQ~bx^|9#D(gv5Z:uBѱR>(`_ (s$B!l9丟ߩ{ ޷,mL)$ұԤ;=?Y|o$H.g;1BY<(AAI/"鋒 u S ke4p}fSW(|X?=veȼ0q掦O>M"G%.\S2Kc{#1ӳM,׺8pnca,ϟ?)?~lS 4ǞXg%3EX~^Y"H81Ywg yb;/g6 pb5}Fy6!# xXw|Yؙ1Xw(B y;qc˙|D%YJ]R(8gV ~$0i<&a? u9)zc4*'l@/ 3r,i.K[1䓾G)GqMӄ\̄F wUﳚҧdw5V ~WÜb ;kY1QLϖsz⮔w# =G\#%,ٹ΀i.ˢL&3kYf.gkgË.g*&D3kKxH)3~e(msgWK94'=euJ9lUƼ,t*Sɑ[^j**0s[&uDVp_CyZ%}۶gY/hٚf*)rs!ϢYr`]s1669 M<739 \OD.G`{iLJZ`ztHKGzMs`4g!<5凙;ŏ&3dZL-'vvp=YpVd1=˩5% Vƚ2+.W$t3U#zUbfz!JțUJŸR~f 9.E (@KlA'(Ub> s&!ib=sooS8So.tn bҕl`gY1x)N %[iZt=MJxW]̟Ilh!?]̷r^%kBp^j ŬlV3LL{*'o%Z.em-u)Y^w\Z4o ʍ',܂4gN-& '+óI>,[Vk;CЈNPN2VLқ9l* ]vp#U: )?hmPBZ~vcEG]R0@V ^-ӱO2W_]_RWߝ3sN'RSڴnX)Y8BF TT*6UűDLb&HX8rhXHȯ"o<+aXf4~.G l-vWȞr7K˧i' !3~1~}/ϯ[w/fJ4RoM(=Jr*|e.)%h}9ߪQ.C)F68*JH*0X0i>VviSK'{r4f76D{a̦P{?EmbCbpհ< { _^8pL4%we[wcړ*reΙaMqXS2%S+qBtUu!W%t͡?tH>ON,'ӂ0%:4LZ`֩SH'|A`!D<7C^Ǖ:$z~ձ9\vCn E]zCsE%kŒ<[JPS J)c߶b".)X("V[=%oA} 4:.Rbg)P~)UBW7QD  ЯWSES/Y^Nt(`~dJYD*>hAG}5(21SP`lKH_*J=hbF}YӾ{L`y7R<7>*AYBɍ BV/I r-2rVPQ\DXƎRdD\GBy-,"}"YTbwRm F^-y91':k/^O(M{p\ъfǚ\=_w׎!iwf,[$a8m8~z0ӑ9hy8O i*G *a G ϐ'8gp2Edvq}}}Y{(%](gkChWqw_&PIfq!2QJ2{P ?ig^F1B>:)P$L/Qqd3\WtgLwĠ,ȥ $2z d.a/Yj>RTjzW1p/piZ rެ"ln "BD!7k{_+Sʊ@)Ŭ\W.f0#ly=ul:\U2(OVE6r9FJh)BhE9?*OxzLYfIeȆ.|θ ^?0e<2EjסWƁ eԛZvy/ˣ a'0ArWWʊj1jihT#7:X٦38p?f&k'XSx&MOp[^U,{?8^o|o6#n^D!nWv8 =+2ؔϱ 3z=MAc4׎c07 y2y%y>QbLʒ 0$&@Xǥ#fd45rd"R2fXc3u.Q!k ݴCW?GU"Z၎[uwkN*\jfQC5bt'SehVM{"܈N^4NpT`O29rvR:Pj݇p;_ʗ\=;Xgn54ޢᮗR %C`!s˙Y)W\G 9 m9-!`_!9L"掄_GE5$g%>Xƙs yL΍~0M3a և̩ͱMXe5ꚡ,Zf@vM@6H t(e%gZW6-S{2Vq)1 2_U0ԑp1t}fse3(ٲZ!l"S&pO?.g|},z]W't@碥 0ˉ<{})*"5h2YU g>VwԾ4`D'{d ޣ&i%nY0_qPy/NOh4{1g{4n*z1s#~h=#i<xakYJN4۫sMA|'5\|J1Ȍ[hߔ.C#ڂViߊ"%`LIq妄C$D."7tvQEx/*b+[!e' mk$|8 !Px\BoLWsi=?4yV*Ix1vٸY&AQ8f׫8UȺdM=4O1V \lI|\ Vѹ_6O1M%N{j95`L:Q[g6ͦp͑k k'pfp9KF 㳵@ؤXE iVUKX&Sj>&sM0Q)s)2UCN6_SB$sQaa,eA<[qrbkDNNz͚H"&Թ˽Kx<&;<Ύs~N4'Iuaj:Mb]}u |B~Ju.r<ޟ#<3YjSΦzRLsUԭg<;6=Yfz5)c,υAԍ9 ea3A?4MO~l֪Qn:tjE"Ǘf"?2-e=)"UfF}9f"}Fn_7{+p-ۊ\{N F\VtmJ,~dxBN%]du&a/cw>-]Mac6?#m G0>1ג9g'k%{zVA7w;Dߺ=ntgĐ.}g_}'#ω*o˛0+ۈiw|$M$_UrT*WBXFT|h8ᐋxƗTܖ=SEB߯**.b:T>>k0'ޜxIs/>\FYB++7cǞC77*v{펆aU:_WZZΝDd$FpWF"u,m4|a4^Y5]L甠|Ki&dJ1iNp@'6UzI\s05étM2窕s?c;21"7S\dڃF{EX3M q2Rڐ!"ƴd{Aoy.Bx$Y3~,Dօmo +P*d;9SlRg383EvH>NuǦ~]uJt1Qõ 0e͆u˞b黊iS^LpObI*TT Y8Zja;5~=l1Q۶b)YYÀ{:樦T%( r!CĭP3@ѽ P 9 ʧ%';IpqW:Q)v=6 uHg(=d.;!"']7 W'63nX\)]5lT!ݨJcJw=c}[16ji1BZ.tZJn o.H3t#]턣^q#D'3ڙv{f~Pɐ-f EH._Bt)0 )>ɩϺB/F%'^&?B>`?=.B>m #y#Iv M2Og̗hLB& q:כ~<_k^GA\n4!3bvc:<9;܍]\0BZ/VtjVgr@ _JΧJ^T1|o =hG¶lօ/=h43?5ƿSO(bruo7eS+eC&4W%w+X@Ch-;&0E :ܖpRA" b|,iqݯաHxԆqdVؾ]Cw7sjƶfd]^+~mдs Xz5!-;+|ɟ΢F,7{?<2Q_mm΍k v (x q[} 5]$2{4ԗ6J_Q6^A}oTdY:f2$g |b;8d{FXCFA,NL{'NIXȉ ](3#ЍMF^J . T>6GDU\=g_;wъ.<6fD+))xreu~_۪bAo%jgS -5{=k ekU*xpWlvĝ wnCUQdGL[Za)-_`|0lPr焣/g;<WH?ȨG~ؐL}yֆ^E\ $nQYrMIR,h?S-zepej;R]-,aABGՒVȎOc_ENͩY)΋Ý~nFch> v[F_WG4גSºz&~+#ܰ2ZJ%=".ftL?/þ$r-V9T 򧐽}loė.nM3k"V8g' Y7 8׉qeb4-Q?4'v g8~)|XfATE0eb2UF|CF,=SCYi`#h|([7<'!{x+QrMTq<*c炥 |=ϋbNޑӽ%\HK&T6W9ҽ7ذno͵~Dt[}_nK7‡t\v.gfU=>'=(]A|ߙxxcG=L*HbS9"ro1h)ey!qŅ|+dNd!j{'R3Jm FmqRį38SȫpͨD c"Ym"ϫ"L:-~}p7li.nm-Z'zrsh5aX8NI#1b()^)دz=y턼?pR:XNW4!۟ /ZZ >hx[Xऴgdw"s9Å8eO ,xYD@R.loGz+4΋j5Gu+>ˋ-fhbV:)m̌ahK4MaDŽkQ =% :χ? EToL:Gq{|6p;DDH䢙e&ʴ~}0I$uGޜ}.?6|y/:xFWxP6VMR 7'Y#}9Gv)ۖtE4=7O*K >o<Eh_OO`6#xQ܏vqގx6S=q0n{=CS>TМ'E$1'q$]1w>n+n7ԇiG>$!eGpO[E.Q>q~‡=Aܼ)qbJl먘`51jl_*3AE5uU+1m c k(xE)Iq2)c0Ux "Jp{N?C 4l9)*"+BVep}觫oD{v~ R7mY+u5&x]Ad[CR&b#ϲ֤mu}PޅS5t֝Ә3'&9h []eC"[::Ɂx]™ÙNXma:ò\D ܘ7В&6n^b":Wq qۚ1pɕ!s]P̷1̷ M `VG,ؓC9~L41S.;*2ik_!0_Of.f) ~^A#[micϬN r%? tlʓq ܌ҰssZiVEFEj.X)yD,5>6uiVj]*RiHѲ๊f #b:9-LQ d~%[OSAC+%~>N;pjsw=U ^k_-$pʢ}i| 72vSc"-^.KK`Ez2 j,oB1[21Jx녳3},r$?!a8̀dx" @kOpʬixg|ԕQĜ7ǜuD'L->3[4o1r$y`9GOG n~lf*K5{i3k߃Wߧz5nļ`l ; {T?*xR35*K\t UrёkLS{tNTCT,64b_as.}ƢaDf;Gn;~%-/]hqޓ&ӱ lKőX B P'?D{D5*B&$qe)J a`]33avLo̎c8vafa;̌yqzz}קJeY~k=o[WJMt(q+`:/H}4bBuv͖\j>46T{[ r־myAw)gw֔b=|z9?na~-)SC=iU⭥r8&3ee|]2=*R{bĂ r&a"ʲxbmW+MGU mEҏܻlj#wviflʨnuMjL꽉;H%X•rQ?Q tE89{s Oš{B CX4,vٴH%,(BXǝ?M)ٯw=F2~?7F΍yh&3rNvG$81)[;L:$".BL˾/UݔuQ~z87G%,%h87>S;U]܁d;|2^_zo+8-5x[fd?:77:Wx?H%ӡ{5)ThZF [Y Ұ)ɡ ɈȶdQLijr-]8f# (譊CdI{"6+zjħ]֢YW (?P>BJ*,~ƲMH۬H2b'cu˨1eQXoG6.2O2y:FOk9i[J]RVѴd\TEUNeQJb2B9طE]Y2;WƧ꜡EΥQx:6C߬K(mVAvS( {u0YNr*aR0K(w*RJvx)ϽLu_ǽ1d_`tI:nMᲝ>*kOM\-~-zWM$l"p:rЖ-䣖C=fԁ`.$2F٬Na u3BOk(Vv6K,ޏJ!zw+} Nd@dsx&`8Sۚbqp0Zeh]u2XI|fCS]=JAwCT:zRoM2YxTEԥj7;ƻ+I7;*e'<`[ޚlCB:1njh=[o&iZ U^rpkgX%& ;uPԟ 9TogUHxa rVe]ֳds%%<+aK ; I .!g {8qܷJ~~۰6%YB2)})Δ20V7f<''Щ2ȡ1,}@d6:e4 ֆnQ)vKre!Sho 21l|Yv1ڥ+E ϧ|o&u']7RwvuÛk=ee1gyU݁FAƮ̚j(xg%DK;J ,TV=V@bkxޜ k DT'pm"9Q#j]lJ[{ws{_waG(9 -/lT:qܿ%B1uvSx =Xq^7Yb^4YMM@se3*6 H\wol=w {O°0C[1-GUʶH*Ogp$V/[RL)ب;x jC\UKH!Эdu.vJ1M-{I9_.3] Q^DzXt3*t}T]ee$S>Na6.y^//bU̠ ̹͋I^?EAs3hӕ=?;2GO:k 4lNiAP ak/;wmҡH;lΈ`ZlƛIi##RփX9L9O_ h5=4{a l}9‰YE&\ǖs;?EGr^way ػShSq}1ѼP|:cL w79+ڎz)f{e'K:?-R6.<"YĽDH©,4w2s,7LѾ5i4&Knǜ1]@vק#ޤG?=߉L})ieEr!m2۠z\ݜdMQ ټ 8jf3([ ]gYkfX6^$ -HE0]4ۜ)YyW_ ͱ6ԫ11|u$݌i~˒1V[ٚ:en=#O72Տ/~܎3 NbDN@ob^:1} ța̧4ãXsk,`]-xV\l,Ug.Q~ {R@#1Vv#w NcBtfrg )$DWBϦgىT{dFI||ͼ c1Q_uިå!4XhG %np-"ӛ {:,dqq ˏ; {>KjKHJ lJ1t uf+LgT=rQ.sU:mٟOXy;p5,1iU72>+='ҸYEsP'3YW\ȑ.~ ճU\u(ditNCG6g}V}5Seċ*cE Cic* tXj_πZ7ݏٺ4؅}XАםUkD][r 7OknAvw ىn$wpBCS!<Ӄ~hTJx[UK._5Q](B[cwhoG^Lӷ )0h9 ԗB5!QGܡ`^v`nE(e-~ԛ%s}h̫0;vPa[D{[e_s;=,X:ДKz^#(5cd*+)`oR.CJ)C܉L@T`4w9<cLsmqMc^M`MpKf[&ӲG./@qs/O&~ м[Hމ,Fq 0/'# Htb˅2dyG*Fl iOi׈h0ž͜>ƒq4/t( '\6叴n Z'0]V|(b|;̀-հ' ]b-}?ɓOYu /ݼ+xҢc0]{0d+mh7WSx2mv 5׶ib9l ~m?Ķ3+lEqu}΅t:a}2|Sw´rF{h.xsGZf ӱ(i:Mdpq6k4rh]":XA:eXʅ;l_{ʠ*S:YέO N$]$l4oWqH2{m(nw X`'a̅ChLDɐ G25QhE8sjXo m{ӏ{kO^Z fW#u⋡G93WCo0N>Y52Ϣ(4d_#gIw3Jpc@݊mC go@ YJh4i%V÷>^OvBm_[ajM"|D<7:)_ΏYhw!-l! O V!#5`# \ i{ӈ6/syߗ~>lb3''LeߺQoY; TpK!:Mkr]o$q`&dkDżGzo-8͕g<7֏mqPX6Mݕ Lak`>UJ.MݯE("ZL(?k:bQV"(֔*G`׍3Ž LCM\,z,}Rܠ,:7VsP|B^| Z-(Co)MK}({ llktj%ʨwMQo$u İCvr<-P]%Ȳ4T+je 3Hk$#rFO6Ƭ_dy:Xln:3Q7^?"י5c "А>7Mx`_lZd˙\8$8L~&#j>+ eyk<}"y)j iGj|UBv%')|jHnEM) 7±t'G:ՄR\#[S,;cjΔHK<ģ9ΘKh'蕉TtBf'mV6ԧӏ[ )m9]//sγeu%cLm ݣBYT̚E9dΣYx:3A' S<>u)u.ix)ͽՕ xp-elث󀵺O`OS]9W͍WL1TesI'(i[Qҝ>7 u!ݍmgbC,[M@b R'8Λ> $Ng ҩj!wcXo6% h@cNm.#ej6)9#ã^|lcfA:~SqxU|\{^5KSb%ۙ<<^)蜉]2k&D}Kbh.ąio<i2! Ϝaf_;'̸Ù7HKE37x@v>$O7[!Ag--bmy^P{)5:c^pve8֌]vJ*١Ń_$3gAK/Wb:NP\Α!֌ʚ;w:B= #!&n|~hdD>^ 7ԛ=(aCZ.z^h)yVl` K`95qׯW|8Х辡M>`RZuhX?^4_! .^͹<?9ĚEDΗbG!~!f+P=6?gySF:? uG'-7N^t[1 c1F kzi=}5w-RLJ!ʐmh;یc3L^E7+G_"ih*9c:H\[!g:"p0tWt,ð_ln 꿟!ZZ~vy dYr}-m.ud8wfd07;1=.Y2 :ƅ[i/6q3G5Ey)z^ wتgРfƱ]ʰ"gd;Y\: #3uDʮgF΢gdgŬsk%⭒57oҶңrzwLl KAmP k=jnwJ.ҏ P}>Vmp`lZ9BfwI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IguÕC*o=TOջٷM6U~Vm=oo*>)bp&_<֝/ϭSKC bzJêeU.qԷ矚I_qґ6?Or{U{(Iv.W-wQ?۫ѶbCkmhDZ=ݸjӃ=2=60nq`Pp"41;Xܙi^TY9n8S noqR1 LUWWχw˕1%nm8Xo׃ʭ6m>۔c=J諌DV9R_wJށ \<_AުNb_faпCL}ݘ!'cT xXW^|osQ|)nl<ѝ-Pk._niCSƤyo[z:Ӷifp4D81rU/q1/YIH1Lَf4fEU?kڜa Nt9Y C)~I .ln;g\S6{]WloYE荫"}u8~Kۍ sFsȊ!3-Ā]ZPo5 =ѓ ݩ ndެ[ݛ){hO'֍paWG,ٳ:ˊ(U ÞoMi1tQm(|67#Hۖ^vtZ5khI_]1 k WvxFPJv͇ľDJ\9*Ez:3m̻q 98zXgpQjN8%_y1ڔib⛸`ywX/؟\nHV܌ImFx>w&?BIAs~&Zl"鮼 : v:xj6ͪA=dގXT8sW1@[1tM(ۯaDzic0[Cap=]{żUi1i% l_ˈNt] V7o!I_zU2P$ۭķRJqz_=R_+~t` s|P/3Orm1/jT}.]rUw1f PzaykZqܖs{s /?~-OA&>b>a8dδx+67HN$jX'3B]y<"I8g*g ¯PEkn6ReC%u1L)̥w OD g'饖'mz/7uGW  džhHӎ4ǰT9k X6DOFny8ڶm7FB !|}fp"O=퉻gUժ+gUPM}_yw78my 3 0~1 ~v4}U%r2V|nrx(!c A\[ ᖨwz-c|fBSw<aoducz@z|Ns*5zx_zr}-hӃX”vxz/ '_}%xhB+a.Ц'+XB ;juo̵ټœ"rֆ5iu*+nY'^g ?ӫɚG3Mx?IB;Opw% 6Dœ܈H ffrRʣHGJKlq j>q4HaF&{r%֖'ӌ*Xo7OlO;^9ӌMn|1 euf]u`s|F8gZ"yRU`=Cwo6W*r0jxыtF⓾┺g?-Dc#qX o}FdYY<qSQF+6^p,~ _av8r}XA1wx#ʌёQfrdiǕ~NQ^'>&ݐS2'Ecچ #X|tsGRZ5 !c9E":m-Z3yet&fi=UqbsaOY {&g ]:)SZM[5k"5щu޼ [p,ta<@Lηwv1w^?";F ERɛ9B0ʆߗh^*;si=~0Љ)0Y$2-ӑz4bO>ؽPrOJ1hk3;k]:65o| b :+xMYÖĸU#e#}EmF3]h:vl/' uJ#З)=[pCS@.&|"ݲQN'mGGnGaCґ(E K-H`v@3=myN-0sO d۲hn('j6YٞWlMdH gH&g{gu?.hɭh:l Զq3Tm4Sk\W{׀m9$d5Oהc4.trL$؞>?Srj0?bpħѾXJ)~{]4F^@nxֶf!Z88ʋ9<8ίH 3{ͭ]94>+_Bu/aGp ߮JBVJ龩M?VIȃǝE诞ʽVL3nF'I:[43i OűSj׿ӭ3^A'/On dVn mljmt.w7B&W|?c#,4?3%)?] g^D.@*;s|h%Jh~<גI[D.ݾl.ԧbu(oQd8UƏyI\J3FЅ!ҢE[3>KhUdpv-y81WYM6}g%6!>К`C7l{?|ج#hoNt3q7ȉf*3B40t2.L5 c"v?ϙ5IЗK~1nV6Z[eo[W)t>Yd0}B" \O^O;0uƌX5W2j/L9~&k^Lpp`{VrcHéNҧ &XK *[EhovwqfޖɫW>$0UTȲx J8& nʦ:d6#683_=Y,JF#Ɍ*uF%g`vե.b4J},;A,Z`v^菠{XqBv"N$sB5M χj4[mYw꿤Wq~G4vE(^H8& Y(d X  l񵶅65}1փ8\3l!Åp+O!=驈f0ԠS7Q^oCok1r mh54,.& zA /'.ẙɣѡ D'u`@jQ5߅x!D."K6Zc5À=uZĚFN4,eVd*sG.b* DKNm_e03ɑ7p;))W*]QYV~apևܐ6~+ -$9u*'ˢzba$oRn=[GDդjkxR$&ThL6zZ8WPߣYL`YőHkWj[{w3{8l@赖4',zT!ُ {l΃mk Y+_Jy;"0tΐ,lRf`.v+DŽ.F;w%6j&斄";cj,a ZC8Fk0R4vy!꒨o 05L-(:9ό4'sr! 8?\Fn̽h'97b/bvq,/ya%k'qtrP,Ϭ ^52bҧo:m9#촉RbwSl͕Ĉ a]Teҵ8ůtRo''M9?Hn5cP$ 2"~q@!z琐áE<,eI)1AFT,O,i~)n(@ڡl binnB ǜԭBd"pǦ ^7SVZcE⩷"n5Nx[7jxgs:7нq6+fu3v|PߑPr]ajZ 1^Q>dLIcQՍA0vxZߓz5_U3a[5ݏrg)l3Vs>a= i42gLleZ{ ax~O&hqۄyQl^&xăjD^h}WvcppLgѓރz[(\7rNQ;1O}Il4k\K#􎜢b<@GID́\DH%juA/M9 SckgmXYډ1>˅zȃ"XW!:Wã*;)[aBF_[+?T ͪsqN[+%K4‰Mn?!Bw I6s$hjn(.ng/ԾHu}dJyO+qK7g*R7-5&2#h SR2fTɗ}h? SK]bhE1j2!z6eQ&pnG Wlx25X)=ˌQ?w?=sF4oתFkj:&u?7<%IW.Iw)ke 'гA FtJ6/X< u5~l5Y̳+Gz6߫$M BGaJ1ҦTd4+28':^yPC׌B\/J:U1|c9RLb{3V֋qELFz䳦9KqYs'<'6 H`ڞ%N v߆#Ϲԅ5{jQOU%8;ٳlGZXQg9fO4ښ:͸ܷ_LTVs ?MeILbT& q( 3l>ŗGAΏ):ޞT '8r"|Jٰ;KWШ`GA%? kHQ YCNӪ. `<8uM #d#}=HL̔[vVAx6 `|Rgm2ߖ,Z· ݦ4tSb^&Uqm;J\+x,Fr8әw1p<R*иQc]s1^%yZeXE/߉7nXarѕ’ePԄ 8mè*'Vyrޏ{҉&KNt1%SC7̹aɻ X`aSbA\PU`żXAua냏dϿ23=p6qx ȠZ`#8+Ѫb] Jr0dw ޟ^; Z\[#YJ+UQ( ̽,|zOgM$jC^z7n ұou4uЉ[Y~D<0M<}_B"TW(RS?7݂GO[Q2N/pv6G(o mQ7}? SH K.!pVys`9}j( p!!Z}A-T&xׇ|, gΧts)Y|TƭjrMW!c^c6^DGCX3..)h |9=˘Ui[KuZ͇Bc>%ZvB_su3/&No,9bPjuOs1Q8b`w=nB>Pfa!d|Lь֟cc;5qʟukRDet\Ej%͓ 4UȺz^Z3g_%{7eIâl]40Obt^Ic꣜h.OtP$qo{muP:?l0}k"Lmǟ&Sr/7`>tLN< E9JaG8. Ol ÂeGv%it3 F %0% ;6n$ch&Z*ŃɊ>[ܛ[zʙS!Y*i]݂Je%pX"108ylLJZח$;4cv՗ WH? Gj`emTX޷c7ҒB}"CQ 9cC/G6߳LP1\gqUA\mIbnIؔ@^Fҽ{cѽɅ@~t$.;;*WyމW t!Жl.Ҡ){:> ;+y"ǶRÕly]ڜZW%עVMZDyr~*ߑ*ZƸ:˜8=qRk0cMo8`˩aVu y_cG;y+O$َVO*ֱ} W18\N&)Vaq̶;n293 2V;T3D.Ո|{o+/sɝ!ֱxʢzCeTp6[9&d rWXf;0 Tpbn{3w3=QMI% \B*2"B]gsUJv&݄1+y>K{-w8wTƭ>ym̧>ӝZmKaM&S_͍y0 ڰ:{uف ~q$I_9BgoE2b]- LG:sJ=!٩WO=Ox>uTkWGD* :PˎՔ."hA tXrҷQJu'w~1q,2Xٝm3HiԻI^IG0%Ĝ^a Hm,>F?D8l~UcSц-:gM7 }9AFs{).cfrִ-F9e,YIu=&dMeqnۍ: j=`$ p_-8[D9/빱9DA}3NHjzNTͿJ^H\2>VhT3ӫeRvb68Ɨ~E -aW)CJQr#֏giVh?#5ҐLqI0{f㦒r)t֏Ӵ ^ k Z9 ;#0g9iQƸEdؗpOEW(gp޴GrLd(cb('ut9SJIJ)|P̷o22sqr$e&3RتȣYx*qc ܷK"%3Z9Ӫxi[GZ}\=:Փ׷jwl=b. >?S5E]BۥZQЪFB!~?˙`qևr|z`׍B_nGxL> sKϮpu[cia7Oϛw-Y͍&&#[ia:1<EV$Hj 8/fB'I$(K#H=5E)|@jzgWd sXFBP~EZnղ#xSZP5*pYB5}Z&@ )xաbf,pa-ΥJto)YqnGRc9OO{b! cQbF;9,I-iQDlDrH!>ʰZ͆RN-r-,bB6ۋyY̆*9dgIjgz2.X\ƍeto_iR^d9wb([r@}) d\!|u c`OMi:ҶW|XIu7pG#3TlSbI@GBd'٫d\NV=H!O-P`x%wO+DTXy<{md1bArZ rJ9#]ssP%p/#|g;_-> o[3|9z?ZyBnq h$5z҄r@Ν?,2 =(DV{x= J4}s||ևQ۹dͥ׌,ק}j"1#maBNq {fs3sR\N%^FYQ*,"E ^^ue%{;$FviS7߫جi ۖFһM7J~B#{nS_@Do gp+CB5V?k7.yqN5RH\j3VĮW Lĵnԣ)OVwkVgY8&D[1HqR0+'ꉖ#_l׺x/յ2ߚȬ% BPѲA,s_UaaQ_-'(бmP;fV3K]:~~ k! l5. _56UTT%Yxg@-=MY?VӷţNۮ,>1YNiio+ P"jR,X.&'E e<4*!I 9tDݳ0,'sX+^))H&vi uSQ# at]I(s.G'U)- ,}B>5>!{9w +]͢54vD>Fd 7E>l!;.}&+5h qyD5歃 R0 3Ogı^jߍ &j!S/6qzcZ}'R'wrV"ȷ',X>5CgM4Rs-QӬ% MVrVš5ת$%[qQ£ ՜,&vLT1BE~`yU>1<\8쬒ֵt(0¥Z6'>X`:?/PlMD\[ik:jY 0G0VIF'4Mrrا(ս2얱K9+rYLI\54w`4B˭&6-nϱv`8ggF+=7NӳNd:ZqN.qZfӲ~= [1Ya9x)vDN2֞-cw,Tb9Wڔ'j8$33::|80nSO;~FZKZEn%n\?dqң^$FŽ82KpanMA;`3WzOdJr ;úwLU*RĞk"GvkavO{Fπ3PHdGeln'*5ZQ]1sʱΫ`JnVuՀW{qJӲrڈP_NʑucLfawjVytQ@{T*cVLhD6:ʠDg9*${&AX{l$ U{>:FnBql߮}:C6qnRheךt͎d}zc4UcmSi[.gi CRs9O|>+FBr@ 0EA/˱ꩤ!tVcLÌSZ~1g`9Ĕ[dնW˘ժ9XrrߒIہR-eL"|Z%m\:dho#rlK3-24+:2Xw!̈́ 39*7n^cLpϘ~AtQ(~Uĺ)h+fLBK@_#b*&{S bo+t"$5 k@M~ecɪr;<7P=qeۓ4p#݀?^U0WW0 ̀UtԌ ^`=Euo]Ac󶙞*0ݢވT'1xhQcB%{Y.Ч lhۃKP(M p3}<:{"e1~m)p.Yg1qg R !UD[Sk~m)>lI ")K0"Ni<'}xy1VONZ2ӫ['3@Ų)ZtEZW׬7 Q36!iduJys_b`[?d`uN.:?f⒎EZ|]+Vr㨊فJX9HŀQ*'M# "%ECL'-E9CGvRZEN2 )2)ʘLoPܓTWR|4S|M͢ºGpF4ԍuP$~<UD*G&+,>)|La,ZN+DDݣR)->>"QqɚII`| TFQ ,./򢁢KL^IJVmmQ Iz,=MxΕ 2X~vco~G1{d>O7ҲW;Zxp2 +[ݲ0C"OdcuN\ͧw ͳ1+o8i:QiO׶ym[i̢",1 z;  xwy"#5^u9\ú dn%i [Gb`PsQd9mE֣ ،LyYA]ES7s:kh]jSo7hbf k0z,kcI+ #o\hx&:X* DxF42i%?me|'"T[~}?V/׹Ky ~2ދs|%Rʳ%H{h]!ou&9&dpur ^E)hfSG- 0 GKX8n2QPg _tq8*V/p.HT ?BI}$n ֟Y쯬fM{kx$Mdxe m=FrdpNKڙQ޼uy4,JcdGV%@cߑϼ4'" bG2?hBak$pX/D|LJ#TS Ejcrq7aMBK ,bQ/:4:dDK@4EdAѡH'v|9>CuIP[JvKo9:v0[̩_v֩9NM} }Vtk+Tś3se+Y"g)^~"L<f0;>c9a|TPŠ;)e<9T݇RŌYD"F/aߤz'7SYT}]>p) ۥ/f}9GHRvQ[a9{9CJ%.c0t%QTWqIѿ[% OZ4s¥Un"|p8y3ڦ+Y@3zNx\KH0c8&Y}pjO$/S=}rqp} tDž&?aˎ8 l9`^hMތ 85Ǹ4+E~ԩr|ܢ`e;rh%IѴ24=9և}~ ҭUK6aDbo\AGZ_Ұ1\ U' uf_CO?6P)'$J+c5Ld()ਐH r'p ù՝~B v6e>h·--ػrM|ʏ|$vitG3^zT%[9r>Z%-T$\W`F5J(j&:RǖpgMKjR_qKP-}_^) Bx9-21^/#-[ r<`IP3 Oe<_d97ש0Z>Iib9M"(\#ɞP"چ2$e!`]xDhMhܵsqF3I:f,Nqt|%\\f3ۋ3j)hn313fNp@g7yCa4kc8;l$7j77$aD>\sų'3<͟LEwn TRp.,ljU1բza|Xm2]@;xN=-Zhg#^3qRg\ez<Wdu ثg C5  +{n(omZ/42o6)<{فas u =؀֗zpTcOSify.ckׅ.cUɘ'秙M+b|Dޗ_FO0^ /ΆRԕe4Wƙ2.4V眂7DT`ZN{Wr3SFo2&ʩX+[$JM)Y=[gT7yόg AvV ߖObԎ^Ysk N8q3P39.t~C;uGfv%)(XH~飵ܹkWvZ{`jIE0%ӧw;Ua97ɖrcoܢ^F2Usrdl6~BF,e1iuTK/ULqb | ѫ]H h>g7O.H?&WXmShkQbAx08}?WLyLa韛!MXW«v9CLH]>5$( )_Nt\BXuFaez*%ݮ>R<TȎM{VDbz.AK]_LMZ_z9uXT͔"GR2T A5UȜZ.M-42TѧJ35$")X)Z2]d 1aPG ˼\H/Ci9A $v a5]!ö6 &$,&WVΰ̭U}do㽕̬2I偅/7[ycmWW'wjg*MA`̣6t }KhB<{7r(Κ\ҕխxZ:w[m)omO@_VYQ {{&L8e,?D/=|:󸟜c/}n3jW󎁉ۣc`-bN>3XUg=#[C</\ʰ|]Ķ\Q=g;u}B{p2wL}P0zйޗ%}5na]Bm[hFz#T8?5t”Xr' %y^Ƹ,yVŸ2)iJTš"bTD$3Y42<*hr H1KOwĜoTAnr{qLy}d^ 7ydء~%e$Δ2u)Y벰Mt̑m3ͲZDy B$W1!%WDg4?QߒO죭SՕ_RřiV~V7}Bн-l߯-߂&D+Y}}% Κ/&`Bb.Y1/"V1B{\BY~hT=U4R%fd9u6?gO9wFY] r ѱg*ꚪ.Q3; Md ڜAkbfWMB凄 k5쾘UfEt>8Uw[Ɣd^]; #j||"zHyY[1mJզ (aTU!+ _X9r?k3(jDSF : k'|/z`"~-_h"t?;֣e )t+Ⱦ.,Vph'?6 |VMe /VvtcfNFq!&1RO%+A΍]Jio#Hsyi{BM3jOyCb&9QCI&i}MtȺ>BRBe0T#kÆv_._ sƥ'kusb[t%”v> >+P]&syq (UH"({?W Ω8Iqx>Jl=[O"ZH8rIBytǗy|OΡ=ipAw*|)") 3А>R2]RCeI j-ba,MzO, ̗K_.#LSxVۋ/IXj0|R7K*辱ٽ8`Zŧz\f^ 8bN [la +*z9ۃQ\y!_շ* {iFH J'{_.#ܮ[WCu(mXĈ9\ΥO \ܱʣ[|q HHU;XgR}25eˈ5]&cm(ʽoo !ZNWW1L]ѳ]2];зρxbVjO6eǘӟJ\=j=^ߪܖy4Ͷ*kRXՔN#hrߎs'ߞ=F;lPhXЉI^>hVg|)wm,zyӣ*Jn֚rl/F_BNmڕ˺׋*U_:o δaDbL. Id6NjV>bj DvU93hQ0lk^ieL]ZJyRv7WKd-6*H*j{4g%V%G4w5W^&bɋWTBZC`ϰ$uHkO.iO*sMRJB_R.RH<:dٟLyU5gqw|C𲁄3k .t3;Y[=#le-Vt.A~U323b%LAq$Uw2;}ޑ$-cMj;N*jQ|u2'p8睍IqHru`߿&ND]KȈJ6-€J.ė풖? 3UTT*0Qq6.Ϝ6:#=ttc{*ѽWͱ}ٚqV. ncj.#ȋ˚!&ߗ~6A%T曹3-T~FqK$AE~ܙ¸c(Yݚ{_MzouwF恣ڒ_,IѴ|S*w@V%ZРno߶=⁡c|١b|9bf=c,qJB+WάKJ:hObOJj*aRV!Hq7֩YITY!XMrXnLrbO uWO9}1b)1;P|r 8 rtME+M '>agU /1sǴCSf є_3~_dBYZUS걌!dVIL1NO_q^oǶAl/(K9[ƨY[&igӈBI$VȀTJthG ] YdJry\̢T>d܇LV1(c957K̾8:OEXG͋yߚќ:a (oCL5v9E/Yd=N.eOY#d{]}*=VWIW*XVPFً:gHxPΟMz^m30Ш;y8cFWG`{A0{ R=yt.pF> sI\t"}y'F Mm0eiw? K `>+S'dlRBiQ@}.7\26(XԮ+WK¹ZW|%+[^Jm!۽rqspqmi_Q䧤S k!;W29>pzz-,k-7Ku,(ֱU:Oײ6Nd*.WO*\jG%+z m2'8G4>9"#䣔qR9I"z] 7&2m"}Ś1$7!u;ѯ)4.M{=-dߧDF%:1:qT%gb;s2}HRV<2> DГ ]N wl̶>a̹IsK-~U<*x/8,gJP9=S*Vԫ^eSHԃ4;cWc1 j2A=xFq˼p8 '"Ou[Gv]oOZ_JՉٗWLCI1߻I`'Tdz;bx#0i:5{OPwGTRVX2@\74B3ܞckֵ϶!dtY_DžudQBfD>)BT-ТM-Z%T_;MMt%5Q.2 ˾d3LBܷÛn32;c@x~cfpZ.wJ KiXdrr|eEE/اYBtqjLn`'X/e0 '\ !dLs,\Cg:vY'L/(ğ![6۬(<ۧ㞋 ^VJTBD>A/\d؟$p,|6ePy(Mӹ\">'73?zk. 6N e7 9  7 -Zlv> 7-t,h¤cxr|: 2X`mwrj=%@kJa2MGbB. zsz ( )ho?tWx&v~ܶpǑecYN|>-!8”BZO.eLƼ Th/&g_D듹\Bó>9'*[ ;% ~g8~6o%4_?,zݭGEi狪<MR<{|ч(Їx~nwVEbBiId%4n C Zzk Ր2JK_ZnGi_Bhp,J '*5|S . bU/cL&oȈݧb4]QSɼ0ˁ{5#V컍a_\ʍ8rZr+̭X&h-n`P 9C<8JaSTKTm ]3\BOLZMgK+(I8=Inx&QȶFM{xNKb^D" L=,2X|>ql_I{֒SGE'8V TLlOSY7ɗ#XHӖ\5 qCKסJ'g-Nlk%]Ȩ?Oc1qσP$4-%~Z1R~,pkTրΥv[*{UŘ3HZSEɥRv=@f wN4惛8m>$SCqSiAq:LR9ܝ&%^/{A2]۽B\JXT6Bf89܂-lCsG;cG6v2!5_?HKOg8~ ϩ lr?:(9Q=̝}xϪQ⚷+aFCd*j(aq9]t4m q6P _(X1KIY$>|6S5{<ړ|\3qu Oo?WS(g2|&+b&+أavuua\2n`f("e8c|8RJ2e v"1 3`8fYkXWd3-ƴ,;ś7#CNΑ0TeMtUNkѴ ct{: ׹qؐ@!윟,Qf 1/[O<P /2gm [&_Y:+ʸZS j4@UA*ݙA-A]*JFRYMzg J1󲖅3TX|2|k H͈(C`ӉQMEf/@{RwZذ6{1Z.0){Z0Z2W/}SPe*?F W^͉jzetGJS8|+툻?Q- n8b[j* sdH A1*A ckFEBc8'N4ǩX:m:Sp_q!>>G"x%W3w0֟e}IKTK j,dO8]~)8HM%|*cUSO =S*:Wj~#io0 !Yl$s!}Y} .&W4=!Y;hhs6dev[Muf d1j])W~2@)Ӡs6?i ޚUxs Wᙧ%6KlJw m6v kȎϑ^$ x !{ǟ#8L$t7Ϊzg$2/=lwqF|6x$#~3K&ۜñNtR^ gx[>63Ɉ`¢ 7&)!g1Ȍ;Bu=aS1mu&6 xWWQEJN zWU{yHhlS$oRpꗆ ?᪥~":Չ]q!o 5ggݘk)9|GO TH;OGUPkZC~mZ="GhWɟjFԬqQwGC<0UjC>dO&^q §DRZzMΖZcn 4.3ZT_hFܿL=2߰$l5gh;3Yͨquh0:O7OXhaj,Fu1-(YK:C2wT^{=68NMfQ]P! Q\s[Bʡy'F!a>!<6X3xYCOe,iLCy4cD4Hω]q_H}C#;fy=ƃ=PêIQ8|POhť|Na^S5zf'fJ+ySIJS|P^S*/ތw|; uSB EAKqa+k:J Zś$?6 &>,7+Cxt/zsB955b0 Mr7y1ه_8by:9ń,Lq]:#UQ=hп n%-[.WRCڰz:TY:ן;ýϕGp0'mYl G|2vrL+'V%%ɡەlV9t:ӑYnjtC񦐬Cᔵ!W.84"ϚxVe#2n.WS-z˄J rzofޫVcc;LMpOSڍّ$;.s,6lcK1aH/yo }#} 9 \4c'FhZ.3?b4UMCCUXUV"[٥\ߖǦϙ|´JRCG K3-8/``hJ=!yeM$MߕmobI͘\ǂv|",zçXڝgPK)Bhd_qG!$h\A'/QꐂtdA;e O-8-`_;sz,7wlShԵ0~ L>& lkhXg*O~`Z ȍN{ͤ@.s:#8}=֢׍4f.aQVsesy]VQeOFO~^柄#`3ښSX'Y1#s&Q}ώdXG_v|0qڡrblji?om1=q8*8]ϪYt?K[g VqN! 0ܚv;nWY:eh+2[\π@\VYcX53d77EFY:n@&hʸY{?Dw"n]@,"pKܦ0xk8ݿ0s#əfc)J9 ˹YB<)8QM@VzҦaEp{]%nc.&KISRT&CL?IgLEct݊' Zd'+]0iGLvdk2V;?3͙֭8_CsLF5UJshy\ܵ%k7顦RTTklw7~wxc%$E<0~j)-ݓp8< WpB$aF?4KbO`dJaγ Ly= xK /<}&^ .q?ڂ(ՓjFF0({S"9<#n1Gx,T6(kF1&1)嗏sUX bVw+v([eb.3zTbC54XSEE8R, .VA)>?˸uKƈj%ٻUTk9Au\`9^\UA! cL2^)=<`35cX\՝ 1c8m _ɨ)TeJqJ*iX>ԍq5Gq\2s7إ2nEw>V2Ȋ&̓5VtdĵY|#Z Wq8wDjɄ\ ~=/%Ƈb~`,^KԞg| rG9ȏ+=1g6K8t+y<&߭qj?]7'3bdzNם4Y|ʹYGNi:ȨQr/XIVG} 搡kRhӝVSGc씮&f~X#4؊&p*Bg(Ӣ(װh㸳!hii 3}.W|nj pp?)}٩_R ^z)䲶~"^ϝn)^l¾qԉ[j %L0 eeJ$+?͇KC+I0J *9ӣq7iߴeX?iz7ER-T,J5x*b ỵjVC# vwt#jOST+vR0eYB3B'l32G|ҵ w d`H3ۡ6i\)\ɳu*%|u͖̳P6"C1>Jk!rf*:SeP*x0/ތA)qwgb2&ٞ:I@N  lpu!R>y>hgŝc1b+|BF>:hpԽ84?m"·/#>#fcֈcke̙l/dD?-c9)-cG`9[(*Y](|F6%/7ͯW7>oyv ܬ-QOf{E~k9d*'i+K9(;[jdYxNHanǰm$7B~ʐMKB U#}yM m"ŏ3& n4uDѱfOzꞫ$!KY59pJ+*ܻٟTAϣMk:"\\]A *Wpm5KobS쥂Ro%ǻ˘Yb.g$Urߋca.gXb͍I -G\k^rUHxe$+q[Dޫl cwVC87(di9{ԄVi8FGh1z5A/7RA-I9,i\<|(϶aQχbLJk4M`^/Kξlwq EcNx߶ΏZo.GwW mcŝCk'84LC#K υ/V(!9m>Vd2H!gu^2 DXVܥ~|뇧aOS-ڭ["@ױ+'s36Φlwr} bS8y["'M B²P!LPVʻ[Yt\x$KJzm~cYF|3g t5z.v]j(Wh+طt(OG5ddSZkGQZ»aŧºa;5'8ʃ,f[9e;IH\e*cmg{=Xv\\T2zWKX3QbBɑK"gMTpgM K0?̽W?5 ݞhbyf=ސ{&s8 }s'ʏEq<$eiAӊ))&%|-_c*1Z ^_՜mlU9ߺ55!o˜`K;]3` `ڪqcgK6=.83}^;:p\<ņk/`nE[?s҃)uHminYQW8Qݞ>Bf29͢O: ]!NX3aQUJi e[)Y^S$^= Nf/֕}ݜNcJ 4w Y'pL$wVO3z~UG:rJx4r:<.Yx$+4 *'M(OEe{MɷB hXLcm%Ĺes۫`JV:Tnz&ӣ>牺+t4Zp@ErdLk_\Ԅ03!37ÂGl-/W.u⊙ y+Nªp=2_yw "'Q*Rri'dr2lq'G :ʹ1RI[DHv1gJ62-)T {/i݋wCHn=S:a1ЏOFx)uNA\3~t>Z6}S0,CZ]NtjȨVh;Ӎ ܂ju?,莟u;?dAhة Qr>RPT_N}9=<#ހY.K'A4/wd@ʜE$l>. dcPJƲQ"H%:'qM&Ffj.sI1R/[BZɧܲu՜eS ǩ_>:l0㳖*cjVZGWP+cl!eyO0yy72{Hؚ-BJǪi㈵j <;{1sph"T5PI5{*q(iI,ӑp5ݗC̍ q1Pgg2ӃV$FՖ^}gIc%I߶tuY0{ q6CpYgM&2#i`I0\KN.Vĭ:D)'&[K)KVjgI:z{07ogJ -r؝2Z)y\q xVpoMsu8Fj}SͩjzҰjφ:^ͪh ^wa%fN+fB2JP8(%< i ᨎ+|[A VpbkKӹܷ V {gV\2n;54Uީ${KTDvR;B)Snj0V<vsՆVZd +ll9f~d"7 c:<*/ԙ'ebՏəا)M9E_ҬKxgrR}afGɹJ͍8>~5keI9^Σ~9&}և0s n,!vbC72qN1t8e¦ f4Ӧ9f'&:bЁLnYN88qʕ9|]E@?oǵG!m.3rxA9R˱\TY܁c[qKٍ+;6=w([m: A̱߃{=K$vH`O*wpX/hy%69[A:~V'.$DcܮebBVZ@PLJZ<Ѱ:SZ^LТR3aeo\@g]x oRpNiJ9cXtFޕN,4B ͋JV:pPũt $j=adb=s+pnVFK&pSs룜c0k%cydFĿwn%c6 }Y 8aAW+"]-I\5c@9F, Ŷ'jKcaxj-:1^XD\ VIqys4XQf)I{Xqϗ^C>=Peа$t{Ov aܗ0{QPqal=?WLH)M$'h2:Zt#s0ςgPYw4Pԕl'7&<aoM~*f7CO2N"9 o~ M]!šJ(̔gJY\W"z]t0f4GͦbmA 4'ovV#Fm&"$\A2nM{vb$r)#!F<&:ٸR39*TUhHlSmTMz5*ZJ|PE)xUbY^ʟ jմIS>Z/Ԝ●M*jǧU.⇃RŪ 4 sI%UؚWXv[[)KzTru`G*SQ pOО)/BJ8vteY wLLCJNΨ9= X|0,&YPC'@{bK+Ȱ}ż8'˥:ܖ*Yʊ- ];/uv /0Vfʂ5Nq6@w&Ĭwac+7җ2,A:y3p#G,sfy0e+F4>ŌsK4vFgv}:wg^6tDf;)1\\E&T 18)fpںY,؊|x3)2&4 LJHbIzÙf*Iaӻ,+s )y\>$Uy2KJ)# -ֻ+eR2zլ>`2 Z-I-vٺ _,97å\qqqǔ1 bѪJCeU|6WG zLs"JxcNL'U/~u,X\{/,dJՖ !瓻bn+`i\lbc4*͋OJC".zLhȔ9T3_ޜݭ_=,0njO'kŖἷٌ@3|a7fk e1m`bi􇄲q,b&/ kq5<[B[RøyGSRGx3FԜ~W;ra1wvI 7ͥ%V`t[ d\MHdyf RMء _D"dp %`& Gss{~6K.ˡfSfgxM[\2ӌ8=Io*Rm㤕aE4.Igx|(Mྕ]E~ ĥ ц{4fiˍ1}1IB>UԵHaM?l w³Ȇ%/7̈́23T_HsE Lile$'+"Wy|IWt7PD_#5%%Gy.bF̢1.esu1cŀ`Zp`,}3 1&FRy4ܢd["$Rɹ ɌA!aJF>[{HI)WP\X.UJ1%]*V* UWş >vU13 xӭ/ϤJG"32"ݑ$ONYt^H8eO{I /v oǽъAͮ,%q o59\=Y7JO=6UtbGH*8c>~:jI87($6^|wg94iLFxZ)7>G; ;wǑ 5юFk];i7\* ܊b\:,ΣA JJ96QOlv#u9cgQs6?9^<ƞ`/IGsU l<2ie=TN_rNok(g1N֋Q,GQ,z)I~\M4 ^oˤK HY0_J) x]PDeI1.e2+gAAe^Q瘂 Ÿ+0>*3.$#W E_;TNzHlVē=>@|A23ʓN[f[n{AM{%rJޗ!;!z8)=\ Q,K:%VH;-$:vC]u~[d;DT*LN,=ce6 dCtml3K^#΢L y!LyǃT۳q\{yL0~֎ lM _Ʋ:I&fĎF.>ʦgHv뱌?ݻ3>6ނx~.m`opf3YEbV>d;p~s '0&A̵CAwTZyb[W6 G;h&}F TwaHnG"WZ3άif afc4L<)'5^S"b9\œe({ jm&1=[ұ(NBgy|\sϔm%؛M^ nK9({*rW|&9ֵP=)N9JEWNMQ9;X5^IZI9%QPHam:GvbɃyY$e0/6D442*3pT~tM޷txb]j3kT")?ө5п:܊hmMZ)$d2,Tacj,װ^Ctޫ㏛Z|0EGEkxD 'j9K_Cy{vYt>d=5J֬P.dXMYxۄ3P?oˆ %7Lbe"w$8#)ڤE?SO{A4k^㏄τs> krhtq12oo>D&0-32bJa܍NbBRWѣlhiGLusȅf|7wD@f"ܴgWY8|nE4 [sf{5۩e`AKXNS DֽVFRՖmP=g6 1(6"#aD"fw&FsaJ(˿h&e)`݇ה`/ed)CxVcy)s+V[!'ZEo?z) (BfS+e&EdSR*\cKŮs]b4c30͡je6$bbVH\ VmP;/I3(_k,(< n%ei2˙fs-/V:`exX]QUMKC /Q7mBW~F7Ņf3֝Yg,!+M"WcBLϝh?7NJZݽ / /s&0)s 4I <bxe('$cCe:D7"~7 Nzaa&A d^r P2.yoh 锕pod&I/gQ߲'$ݑ=8 "Ń=WGUDYa6e~z!ua<SRSb`d4RΉ0Huy\.`%nv (5y"sRLDr K]DKnQT-挶ʹZ,%Mb{?1B,@Y%|/ir}Ⴔ\V2 S1gϱ;*:m@!R/@N2~tR2VA]{9]_p[9-ا k cw[*c4wo2Y6asxN9<ղE6֣$H9=#g xϡjV6SJ9[ʅb( yG]/r ]mb_)ctd9,Ezi&dd.,wg_c)ľh~.$g,zxclϠ]l6?x{dI1BJkT:̎_$v1SAnϬN6?jG3۩kl9ASOy?Mi|Qx~Z;_8Ӣ0XԬ[s[NÈYfHξnL}n 3۹iظQT'vK%T\:VdAW$\(o\gd"r|'8ɗc 'xńEfl2Avg̦SnR7չY%䝂(U󎂭JtwJЗ;  ] =ZAҡ9K{3 ~()Y$̥\a^Dȥb,KԖҿ^ 痔ٮKWB(hZE% lXJBR֖7ޙOM=_ r.RSFSKg9Or8l9|Oͥ^h>*^ q1Gp@D7;Ys?qG=ʅiw/`_VF9qoEǤ(#%puLhQ'j2jzC!:X5;JFBsA @90͊`dXyk/&3xvYx5pO9? gEΉcXyϵ ;| Hs:קqoz_pXol9G PHDM/}x:N=i$?r7CKQb.Z‰qw#,뒅#;Bj䈇%>#Ã8"T 5SrBcpR/əAAJ1P='PTqP UYn AL:j.eOE*vS1t/wRb6UbΛ1_Z>o23cIy"Mַ[{U>Rzu]31Ndmҹg Ղ<>-`uAYŜmObC)#t &2E0y;a, rPl‡kJ +fCYBEWP@!5h.jQc-v&q|vRJ/aX '93؉έ\1lS W=se=`LMC CזV ?/IM|o>cFׅ灭8pgY̨"wU [<95דQ4F,I~x =sc'"̛I8ަJ/qUbGLIiba9$ 'NЍE"L\a5ǫlaX{`";;a nS #c286(\҄Dz"6tE#9DZsS@6b4"5?s8.v{oGۮk݈wG3 0>qwwww'}Z_]z9jz뾮8g)ɯ`HoC|--б{ j+YZEm*IiW&ΙXJi*j^+۩+e\"U9ޑe&' hsɚLR^V2pk:I+iVsx9.2 G49ĸAbV5mΖmX87 egzO P^V0K~jLBxbŹLT`ZEj*o8W)梵3l\cV7x0ٍ8gL:-R1ÕE8ջr> { 6ьhɢ3I zYbrkGWq Fyj_QP٤RdZ)CI8 3JYUBUb&?"+ʷi\ ~،rM` f3J|#MA|%XE!ۊpu rͺXO2]4Թë~x#Ý4֑K4<݇ԶtgZVMnd{UT4?԰ur:9c:9Jz–:2+7A ֳGkjNYo1!q Ӧqe1\d]# K._nѪQctvbTN/L|:ASeX*X_$~;R"#cTEcρW8so+JYi44& m!݈<9=(]޽26P]. ^iRi24?xSϓr?9wfD?dZVY]Űc ZorD,sG Zw;.;]88ѣh a>U^TNj&Pl/ûp'vg|VJ`+X[Vuj`D{uTTW1KG<򸡟Ù9$bæ,増ˮ~l/$񆄾eƔbuAbQ:A<F1t HJ:wc(_S lxˏ'N3b,ȰF26)[挥a:GƋ3.\ώ)x2i"'Fc7 ec;DQ Hl(`Z%MTӰp  j,ý|;JЛ`tJeP> 6~sJRɑ$0#l|cO~sg|^ ?,y" ^lũ aIP@iLJ?ta$( X$祑{4(rI5j~UbCF[Ɨg#a>))-.i<l6Uĉ mJgfP == \!i/DlKпYD2lzgdN}]i]F+&VyQ u*-aȨjޫ0PJeKUy~0ojA^~lƌ=Gc8^9}<HNؕ&#Aߪ;ցUAZN) ڦ,96B0·dӅ b<"3M_o IAtenj;bV{ӣ$Ked<F0:eŽYmCq2VW2:]aq:G!L)eHVwk|(۷WLEil:KAB|HW>eh[ WӋ5Nj }w79$a ^3{ +o(X Vt2Ndr喱JBRE/%]YR;+1q}V(_DZ_/%4̯`ĉJf.-m$)5%a~@|(R4MJF٣ Zү3^}r+B-vBȒº,sCLg'i J:ϔ3%Hx%*nތQGnG5ZO-'2(c1O2w~C-n,N͊S&*tf+kJb3GX}2NOWANS0>r5S1TEEJ*65{9TG j/(X_a;9J,g+)* |di@9Jdy9f&DSjתh8S2T ŏ# `랔E ½qb)5LTmv5, ˖htR͡h5k4c}k oƍt\fncI 87l+]L/=3ެ/FhaGv/C4S&b7 lEK'rMNۓāQ\L +|oYb+sxn#i~Pg0l2H=_' p1 C3$b-[Vbs=޼snK{~vNW8ϯsܽZSKxRINt3~vԉII#֜>%'4:fXjk4UH0_#pJw ~^ȑ flwys.r*̃A,fƢ'TQr'Nb_R_b,5wj/QrVΫerFQ/Sg<%kc 5^*hjQO2<))g!9 8|0RYϽ^̺kr}oy`K PӱTţ;*YOe)4>Ugj1G5>Rk5PmDk%6(&S9Kr/D׋f}?7z[ĤLJNxG 5ҵ ~CO0<̥4igF:t!D5bJK+6܅sƄrgx=`H)Ơ \ !m.%˼9^0nP|}v5$} s斲{8#o[d)=p/vg4ιpk9ɺ9;~*K̄V, |oKMk -  y™z\hg`V<{kwZ\CvcX均>) |HT*i`(yn,zq92S0XM)X!G?@k.VQ*ThDKrƊ+VRܶ^%d,١Q[T\ n/Xʷ17*Y0GE7-;xI:vi)ZOkUlC+X%t'X]UcZYWq`i`O4ᆘ#7KƙOfL,v`kĂjޖۓ`1ߙ^ln eIDD7ZasiLR% Ya Al73gḊQb.Drw^cSUs4΍hEFUJBb&iq ꃦO+e$^FKQϨҪ1ۗ;wzdSnǤ0({6aѻBMKZk+CKM Hu_ڌ怍+;l7qP&} I~j7O#2.ךR$ =[ί)u䝍近U4cR2+yXOBp*֒~Z#rVbKb*9ڲܭ`j%LK~k:UG5Yܦ!x3Z\߽ : ҧs'US+… ."˥(-a+f[Yi9SEP_+ѽ.;aI1?ߺ?xb̐]\+5)L+C;Ze-:_%LISr UOd-<8wk yӱ|1گ:h碡q+W*zQK"(VqxNJfPq1PZ9CdTa/-"WKGCmXEӦSPGTQd ~:"Ru sB2R0^έnJXhjXD<148%dЙkkgv熮/G0`7[͑5lDmd\գ~ԱBdd2J;,dռ@-9Rv)Af czs+̖F6<.M*S $Mcex$.zmPa48׏X49uY[kKA-@C]َKG0ghӰ&u3(0 iߕfkBpF+"SNd0}XP?fQȚ:Gy0⃙:%˃" &$.W pgr:ݗSgև=d25]R $5)ut0 jjtDmkt 5US㐣I UUVCJR)ZPS-g*FS掆b+BΉ,oJ-AE^Z4qM|.ݫ8fJ=1@Y {*1~v5*)eFR¿y:)DMH`+zcY@6 E0b\kʡi-X}#?|Ǚ̒0C78ڝ>Vt Nx;bINR+MUJjsы{0kidcBL:Z5 ZNVTQF,"q<ȝ1^ I»]-MU,͉c h{F1W3UN\N%wq]>%qtd$?<>z+Ma/lD o+m+c\(UYO t?V5eNj_T ל:NMAPBo5TDe1 bD!:~~oWj ie@zn>\0-Ŭ.活 "H:7;65cw'S=I7 !f> iz:=ː^ ;E͏˖VܛcL_wb! ՜/8Gk46>g\̄+mRUe0mSZ "}S}'cӤ|+s26F'HDzT9V6[0:f"u1ۅ>c]IÎx/垵 *]WÈ)<7g1wQVѠӪH-9GR͎hm/zګ:YJANG,*UEϧ*~xVk_:f PLUI(1J`}6cj iP„PgkƱjc]+GEu,jYDzfNgKMRI- +2ܗjRSRNb71t(=+~{t-v4ǽyMQl/ k>gh/Ƴ;Ε h46&eLk1+ 8|ZR8ڛ_'K\-Uiauztx&8|uZJt8O/8ΕF 8ŀ4oeBw)J5*NNT/J|t%2){T<(wŬ4Ky;Z1/"9 -mNPW4BDXyQxzte(o\Jz ҰC -bwFc!+XE>$q45 !\l9Sk"gB}#ٓzY)ј}L@9SL=<9A&i7\3֓YJ5v.+dF3,GpʴqV ֜5 G ~?49bœfH[`kGL~wc'r)'qE =xo?+Bh,YM҈yQ̚rUqDM*ur.:4RO4l5#5lfJKXaLv'\v)]K/BhŬeWg h1JE\5ΕiD w UqO$8$_<( mD9TÕjܧ`LG}$yP̎GQ3/91|ËA dՓ<{Jݝ/mkf8I:=݀xy` 5'ڋm$6oˆ'Nv)ݶiT"g,:LlaP3Lf\WVpë{ƍ YȀ D—#bvSC푼* -׭9wÛʈ3pWod=4}5:FXܹwDf:kN4jǣ:*q&Ҟ0ċo9|55@, M|#x#.t xpBYi4-8P쑖bnUM U3G'T|KW3)rPbNF3F4"󗘕x TAR}W@Ka/ ^M/b)q~QFu}^mb/gYl83yآy v ed.So1SS nuZIi] faiߨ خdN~gIypFo_+: :|kN5:_$zcN2s;67lƶ͢C^ ?qsgՙa 6r_qLȞ̴I#::LGOF(v`y6nc̅+d?=[kaEiO{1XoXfũNb?ǂ>`gDaCPw y#z54!hq '³]\%Q*j[+0/ذ:mK魮`|9Ӈ˸^ƈJݓ" (3S9x&F k٭e5_bTΐ87&Ewс^nqXRss%L2*frlgV𠟚U<"W-5?(E+if8uҸȟ5̻x9"o4L)M6كum` ΰ > oǮ[P/Ngς޼> n-5]4,*g$(8VTɾREfCslڲz?$qBJ'jYb" KqYksf'W!H(TL̂K(.$y*d,dSXo$ [,L W CMv n.} KMw^c GvR _GuS;_wX,/;d);vs?}zl)9q3z;ȖqW,9dJW:b=8zˍWAyI_NIr6e .cegA@XO+nrh yXM)v_ttf3Z0u ]uA\#rڈ~P1`NҷVr_)g:sPF\?9ƉL'BH1w;GhwImбCErAÅur>/ߢLeC+5@~$qd%9J<1‡Èi}FE f뎡S='=jyÁ77rGxqÃ?=)[pf֟Ď1d&C8ٸnw4_3|_YG?ߴnBYީ&šI̍Ё>X_. v,9%Xy-n4E~t@}{(Ny8^zs%̷-_7p'{.L@т{͈*ٲE/HZfQav|Ep2̳9*%u*T#Q6LǺ*}DU9nLsF3?7!U.\\yM UhS},-kc SK FĖ(0hl0OcY5<yӑ>i9'"{O05 Z<#vq ׋9(@;ו'^{A,~4LxJĿ'z!{9u`,4ፕ3.{p ^mja¦ \чփ-͑fcƋ[cшsZgXh'3A^8_aCqoƔZGsoB2]/ˍB{xд(/"Yu(lʇh5U×uű L>eGoBެ?diƛOǖ5{wy>39o333s̱3;7L703snrLnuH=ꝙ,ٖU:/|9zr> `.#}c[g?+(W˥I8y5t ."u"uz\Ͳ/ " ȓ]fLpfNںS> xĭ|7qA95j)^K)WPI|[ )tg@ M%vR,?n 'U"q܌,*2ii?jSΛUtY͊Udܟ'so+%~W{l!ߑ&C]̑"K0f%_g{a"'mF9MJqޚ*sdDr1-ͳoe L]F *ô㾕^J||bUR=p `?ڡ|^g?BݮDWX!Ә+PV T08.+9\Eh^&x(̾RCPLmB3!גњA|(}Jeg׶GNY(_-ohj1 2)rdi䴩\`-T<(rMctjb\Dv=)x{>q~?WZwKmϼvPnV[dƩyFt7W77sy-tk5.eȏxbCK,`Mke8r| ۪]8 ${2 hbZ~2fW||Ogc﯄ ͝P#?}]Ѡ%0}*47 nCqB4җGQ8lK޺BҮ.2x{pvq?Gp+V.mrpRS.4SLp:ɑ%Tc+h5.TcX'M}(t@K涳Cqۋ<.c1KTŲ{({1 5߉N:C~o| , v$"!Yl6xmHV <~)ұq&3=Y8yr|whqE}s:'~bQhowg|{nYl;?n r-,2܎?bmƜl1*so2> o / &gv jib2M7иv}Ncy"GV83+Ł<EԵJ9&yB8MA'Y~#VO@ŢK-R ҩWhY_/S3L[,%MV"Q ?V1q8/RA~ {TiX>t zї,YrFOgCA}2Λa,[Ƣ-ѼS2VO ؾAe1#'XIu=2xnBS_3X00΍A&sd{ ݔ$(RW [XzEZ4Z/gwHI)>:oAE>kP,4pɞЉ#3+6PlCHஹ̩6GD%LbR$J~%}l"Ikx0RZ70њ4pXr72 uggƏ6&dTI6x>Ã<>ϑQ].v܉ٹܸ7 ~Y/JYƍo(539*U'[mO&^vH4~:1wYqDчՋɥ_nj7^u6׈\mˊhM xɖPnq(ɗ ˠ>t[iwq$5,IUF&i{ ͺo*nu^^36kńUoAt}뉯EwnCYR3 K핢fZSÐq_[礇Fr ]wM3t~ǔ~fr3>;d'0vɼ)vV*>0j :T$803zٛ-={ȅ_I f ϻGy<rr=rE~3;?ɟ<ؼ W[ɽ# n6&~RF6q d#%gHjwI^K_K&5{_o7& gV\neG%kT}v:j;p97%9X>_)*w;\h"&(/QIVmPGoiwS^zADSG;*ܹPS@&CNyJ>p,YMZ15G[< }{5ƺٺ!RcUQH[t~U:߾;:po;MK [W.K)GFHMI.{jZnG wϽ=4uVjtbV.5!\<%^ԗk&7 } zKi%%?,& tz-eٿg5(uOthYX+:F%f>nZT/L2!^.?~=>݊~aG|ۡ𭽪(8|2?S#5Q̱.                                                                                                                          9dbf8iRmCnu&'3+\>;I?IƯq{ |9ZyZExyKi[)r䱻˚ ^R种# H/ ?{fW(¿;I,[lTR!%Oy?C~z@^0䡼kS=y2'wG>f6SNn-{qX/Lls~Ltyj`YV'([ȍ<ϵx"o7Α]7= !z\rg\vxpC݌IR[鄔׼d%wm޺gŰ:IѽC?HsH^R$d6dr`\3YfnsA` E<>%Ͳ㧛m݋KO͙4AlxЖQrݎYU2=Һ+ƪaSr粤 ʫ/atV퍁[S.//{gg"j{#ÝLk;c%l$Ӹ%W}/%u?'Ov=Z?-5\O:I:mtCg> s 7Qb"mMqeF/  GHe{&I/1wTGm4{q;cL`{qz-آ =3sp rt*]9mFܼNt3^X cXfvì 7͔f8h v1g|EMϙv|hMRן/׌Fa>͢n~\ ䷺8ύprdE;wNQ >9wyž5bma7ݰ @j[E[d$#3|Yl%h34src:ꔩ |oRNwf`Y܋ka,apTѢ9+zvd">pta/ f>Lse_#+̲)kʄi85蓮FFok'nXtѥLHɴ]77cPqQ|ZkNwu~ |l5٬a{~wPfjHttBi :Y[hk¦Q$p$Ljp}}{)X</d@8gԛX܇. CC-ĭ7_ޛJ3RtmTܿofϔm];-?܎/8\B(DחYδOߨt^9{lƛ#}5CYwщ.vtV~iF3=yJY=^#fï,;;Yݎ2+c=m41$:{&JA'օ1s*Fו&Ŗ̿fS; c {q]8ڷӉ9oe@Z0擿Cuo4Ec+vQi ]-hۃC}O0_p1Ќe#Md,mW?1!ysY%af"~FVtkrm|~dy`eVkO)Z͡4yN[Rx7r7j_NYnLb o|څaH`4wnts~?t GT%+d6Ngz d6٫=dU< Y+5:$d0/=+(Tgjsc+=b!?Z5ʡvP1'FŒìxu/9_ˎGy?žco| [1@ϔI/df6/%C| _eֻrEK.xzjD#$*YĆ%`&2Wn+Ӛf9 eĵmA KZN&sh /xQt^G2:64Nc1j VeIhM+kGc<3FѦ̟5To&k [Š8`A;S&q\N󑘼$k~ifNJUd1j?o z ;Ů*Q6uE boAZ਩`529daDa#m$wr{.]ڝȁcHdF+_n;gM 'N,X! ՖJg)\ߵnA[icYO9pt2{RK|oΪN)yNtG7fklldb#Jf^LV"֏%0lϩe*|{˄ˡLLwˤ=1N hHc̈́};bsn\&đZ̍_]p?S*5>.tkFQW YřNOڣNd4!QW|8{"{~ty f6܊.u^ՋXAIҐuCe!M[*ϩk`M~h~rVe_,ge*v!VqNꅜ /Q<&cw pqL3踹"lS0)'oaƀ{Mᇏo4R26l]ήi(` nRvĬWЏΓ[g6UMšZ%Ӝ-98͞\C$}.F@b>|tMbkgύj'DJ@*A}d GE WJ\B$6毖L0u/Z(ƅ88S\I;ҨGM̓ӭ3Ŗ_LoB@Dfg:)|ꐨ 四pt.=JC‚̱a ∮E3^ yo[bX K <}|Bݮ0R!t?9d댷{>]y*9iMu/Ecx?J96iݓޗ:3OsgF7Q9qf$TKN1=:{l35 nW/%xixwjXȎ./q0&RfZ[[;aFZ 7ٱ)puҳ;qOQK;%x0Ώ^aHIZ33R2B̋^&9N2}@]_&XF|<@eFs03i8Ưt4E38ߏe/ԯ!&spqEd1L;{oC+eEfjǁnƓ|K6!#LjS]u[_τU߷/cyhk㜗GAC==*2oξ<Α*ᄔWV'?,[H?*X €^ix܊˂8{: _ V]yl-wgJGp>IjRɣyUxPƇYF#FA<סXØ ykv;|œkɕw676R(oo- gKܑjHuMzcx5}YPJ(NN,cǤb9];l;T[۲d洶佴a2"Yj(cԻ=<% )w݋1vx|'L M%9׃˓lp]7[C(w(kO lgШ!̍iT]%)H ͔(BSx:b|,%߱%9لs3*\yCna[+9 Ne0PWb9Ǡ2B,Gcr.#(eDUVڠ,9s`uSJX1@F~ۘl˳FLQq-#ʸ8ո*H (XLQcV,ڹkĦ>>7'κy1N.ڇKo3&I7ĵT0lt!"넨,֓/޼FF&_g^D&=.aCiʙ;9s݊m]љAn fΩ@kjoSDbg,ϖʃ^x3 *_B֭T懡BK& 4/̥6/yL]Uk*U?6l4@ޚ+h+9eAy#kRWS{3Q,4NBtf}(eGa~geL ln1Rc=FE=mP|615(bڎ,RSF`RήOlT1ӘFC~(am䏞"9i IjkV[ZFr,>V[-s VS\ N5t 5ӌcۭ9י׼2ŗi{n`uo^\#[mSq(&>va ]d`;JH!Qpb x%DZK9ib\M:u_1ÖM1, rFmN&,LㇲFRy6?]e.HS̕5/PkSHk̦ [>ׂ8n͠&͍y)Hf+{psAN3'/5,YH$S0'̞A9ЕyδI;/Έt>9p6r4_M9n}oSNOl:"./fCA cV;LPrTpx@7(eo)V)?x} oxӄA1lB3rM/fV0?Ju5~81;vR:PZb`##Oڳ@ScXSW-Ԕ%{As?N{iGiͯlȌ Hj=Ǧn?Jo_wj17=r_(si}Wt_՛8dte%ְhv :QI=6ӔmVA qfW1h ?`5{?BK=;Y{$-FCL !ϊo~lI~h&q}+1E*vcV_JVB,C-ZA{j2"4;Si,qtKD\!FY|!Y9Y0tNrse!o1: zPŅn)"mm*xa_̽/Χ8tظo|y[/Z0F-f Ws\O[ws|E1wQ#,s oݎѢcك?ZSw'{0{j9C`y5=P׮ 1(#K-[Ъ˯WPͪ_˰&{c"sNL2,qKx֜0s~ɫuIdnlӦ^A>?`QKb(\Ƈs! NNMߒsĺ7Xtl/;SxRS#@ӗX+uw+chpzzq5)eה;jVԖMޑ0qeS[cFS+ʹ'<4Z1< U*Zq{l4*$ٓ f^~LLӧA jhHZ/_]FTL0gFv%h9=+ޘj;s5GlobK#?s\͞C5;Z*Xh`ys s[PюEo74 e׎(ҕ~ΏʷNF6۔L)% cGR_bnE 8}vw_W{ZtTPج?:uiʾndN]J?L^8Kwp(u$vMUyxQ=&:Bo=9S\p/&>\ !3aב<N8<߉r0=à<HG^)j&5<֜ g;~8s7S'S7܋HϸBwyxq:|U^sz&=zSaj FVXJbWCFhΏܤEӃ7`9:[y}ёZ㎾;{F(JGqY㝸7jR_ j`s3Kȋ\ G]2w̘N]cȸH4–&S|_Tqd m9}Vd J^h{ жғ}dP{ɤqxnNʝQ-Mf%2K:t=kASLA~ 2x0%6#܉]mϤɎLט{$"+hCQPn`K{\'*pLƨZ̪}[5cYد.ky4EbWMEї5ݓ˃y:59TW+Ux%$v'2DY@rػ rp)fOb\)]P։.V# B)l}Kn#Ѷyz鐦ɬ0]t SmY;cacHaL"+Rli !ۙcģ5݊!l3]6HVW^k]8Vy3o:1(.Lk58 WZ8>ʓvv dQ|l͔J+h~ʖ Ƒ`ɕl4᜝"uD6E}<`fs^ \`{5Y{$g[ZtLװm>*P|{ٙ~؄ apkCl;S2G֍j PJdchޜ%x /Ω}y%S1-oLn\ilsջlBY``^2iU]2궔c0pטޜ ;-MJ8ZM_.6%CGѶ= adbgѾ#\= XB<\ջS+.ص풉rjd:Lu4/Wr1+tvW}Twcƭ M -HNU3-cG*b1 j>BI W5Cȵļ|=K[:_KpfUW5$ĝC=h9*'!Z]UmG!UkvYq,$lZd!& gʚ^Xɚk1wdBzRѿ=ʱk `H癦JTFVԦJfMzK E͵ǑV*/> g"r>(+xׇS4&n#-3^Uf3wFynLtU6p\J[g=kjpV,i<7)X$^ q ưQҴd\ȢՆxJwOa~{Rg$|xMېr|'>ǃ9Y^reʞ{&b7փ5Fqv Kyq"׌0Z~-;0EkԨGTr7(kGJIpH$&.}ād~ƹө5}{2 yɼ3~m"öaѾ"){kYP1QOEO0AKFw-F3/&{@Mmމd`RƱ8m:V:E ؍NaǦ ^J[cO};'<̘ W1?|y̕cx"*k罁eZV߻Ǔ+f!qb}Md~ˣ:ϕ| 3cR+ħ] XQj_M'G}l>[ a/I1/-#ѭH d({i$;!&]՞31Au!-Sz\TȃNI#hKDqci 9RY)fr~/ L2,'Fs\4{.,w2)at?Oϋatp܉^8LO7 [^9%Π\w eq؜`^2ͥ }p# x7 bq57z%܎$wf+ovW 9Q)Iin36HS1vӢ0*<" W56.I\an:7paYSVG0o$y=){V'#A-KAK;i(G{œ |XLfmO,8=NrOQrjsZǣT9AtC?)lfFôD}ɠcojy | B0'4h"鰑uXHRhuEI#,2qo fpV6%ao{TDאc%~hUſۛYMiGJ( Sq>M9$nf+'{bOiCÙ[̩e<ǟSOlb8y+N]nS$fbe># vkMb4V;g]oKb9?QC97Fg"i*d_qnH]K"G$2X=]yxAd}ΪiU3afv2`qcYF5@!=;X!dzqvyhÉΎzT?(`fp7ˑ >3iuRq'9 EKىLѵ/k'/˵$b׬&>CH(*8S}kS8C7 ,x,QJ*F),]MiLep螛KhQFFUM:gɻ΁b>s5Eucm{rhsSNZ0Z|93\ףDQͰRf.Nf9EF7Vs1|nUmG9]JA鴄s>ixESHNwdnߕ=]Dz#c8}3$rbvlNJ^UWCstNd2-.&ھ^dNsWWq'cet$eX)k󹚒JMS`~1_JZ[u1ZI(-M. Y̘6]U"H%r3v Ӳ{ʰbt-|^a>,ca[3lM47sFSV;L驉ftF#cr{=tXhul[i;DjiCɂE )>Sm璥m0$b1GKKrxz5k7jদ%&2oğsUNua!6 q7w$Mk9ܷ*dwK({m}YŠh2Dž~8t2ihZQOۆؠ4 fϩ|L{[RM"[;To"qWussE*y@RpF'~z:)%ꐖfFYu)=3ZMS?nYoKsb!ٯ ;KfRɱx.(7oE^2˧fy jF$CIb(74,݂2E,G&*#m[9-Յ: ~;(3Aw5xi-h(AwGrJ_j@}Flr6PF59 ZB'ь(at*`a_FlMyЩiRC3%[Fq+>?x: ɺ(>&pC"#dyŴrۿj)z`/򱡀'.'/ȓ+kCE=ӷʨKưrb S[P4RڷuWK) ki`ħDԙWM]M&61n :f.en2iw=#L*6nfi#1 \'vO Ty'z憎'JRR%ޖE?K85Q6s3/)S1=!D VڟkuvhtkG .L $;.؊w> we2dZdѧIm0z^8DoFd~ eV_FT3~:FƿY<>p͗f5ٟg`B1kQKIûLcBdbzn!ߣP?  kTH8WC觪<|QE=> 9ȴ΄Zk0"gc\8ڕsK}Y-Hl4iŢۼXAFi2,J\YDB692y,pgCdE.f39jNrD2q]SY#DOULfp+s0J>н]7J2OI*jTCs-~~F52f&M̛k&eT9{sƽ[LDm1fͼ7ŏ'ﶙ& #6-ףfd3hiE0w5:)V3xjKZoѰBATYJHm,Z\c}RWjZKx5w:'#iΞ9ހ [5g|Ys;m8e8q +u((*;Ff1+5#1J]Fe4[EgrXsk~b9>`zbl&x" |dzx<~;vD|N\Njۣ͓R*ň fDWLs~v"Lͳ ǎVG(YDk'V2ԭ*Hh&u&+_\ j;W0w9Yѥy{*P5-Gg"# 42汞Q ܱ6X"d#72'G)TrPJY_Ky5RڦY8~Sց=f$g˵ݑXyzﰕyUjwc԰ gVdGL$y]N4âNc.N'|Sg7qF8$何v|}lfF>)bM=1GJ]Er4đfZ1e׌-56Q'~)oq땁&*Mɻb2.0 ; ̛"#\sv-5[YU,U][aɃGe" AQT+f@^)7QU=uRe(\,ZS.sF. +!+gkncgfn&:M 21ӀB/vBψ:^ב{J&L3/tVƒ%4|ye*4WKT"KȒ!y7=ČcĪkBvVak:4= h;k4dᰅ ǪQ%> Y= 8P͉^c#qu(_Ƌ L"DhV"f=2z7$L2r+\Aj7;e,yxecgD]OٯNjdyFn1/-o^Y zbMQF2e7iEhKIjDyF t{Q3M<[Y4?Wx9: G=%W`.%i.Y٬{pE!wMqv( \_D֑`"S">Bt2t\e,2!279fߖŃ/Y<_Ns$zp/hiHӘ( L_Sڣbc-[jv0o NR瀇 l((q=mu_aqn=Hf*nI 6NdF 3r^- 3[ذX_=[\5eҽK >&FɺsJH\dM;R.~m!WęUDE|Oc_ws 8^Bsq1xU¨mKn w&wGq̛fLbz1TK==ntĨ2G = t b b]k滘 WEܴvq䴙Κm T SFB& f>y\ܣ<[FF&3<DŽuA9îUpݿ+exrWy4R|zf\5in3u00e1֩x"L ХrY*ѣU<Y{tt}Lݏl}LeSq{|\2><(#QBEN-`\D,Oӵ$d"۷nM'E)4S\:e r%rS<-C o2he*g 3YϜ|8+9N#e,~"sq B5~tnXrH}C%F8m8 O9R_bVb 6HY{`մbZ{K^W˜2atpY{0*L)CzhEQn[Bnh:}XOp6/FP3߃s'p#C- W<uLž3C0#1}B%r4ܓ(O53&vR70kH;~>|jxbO+t"rI1cHK4KL~O$IL,wpRZ0 }W OLrڧp}t2u Dc&tXߜJ*oL fTbiF73+?94Kd1 Õ΋"%a0-NR:wNsn[1NrW<1)te\=/*^_o>ߤt5Ys IJQ?6R2"%.ӦpО1y6,7s-@m޼gbO~E!gJ5+JYey-JJvbP]ΞxR+ѝ}2;)ZV iV}=>u %=]OB{E1Cv +ajG5ҕ,,2mT?¿ThUԨdvobJZ)9=Γox͈GW7ߚ $daD#7w^8?ȡY1w)pi]l'2RW@!n5v4֎%$9TJPjE`q0/FT9=+|mg43)cͨ=Mj9#Dq<_Ɖz6LdhЇqQȣRuOagSONgBa֍m2"{(jC4k$75 |-g:Mrk!ܼKX.>dm/զap75L9(γ^-u 5p_w##EN?ֳ\E5UV7S(m#x: u,Nޔv%:  ;Fj2jYtm3ưr,dY̼SNrj}]G7\y):F]tiF=ol*=g(_hf=l<,gCr~..]LǀJ=Dxs+9zbJfS-=D`7c)yġC *ވsRvQ%\ɪsrV=^J+quv)\K[~a.5tE\:/FʼnbC8CvV5lSs7tDY%rs?ض$SXh @%a_*l/^E/QB9jϠo(#zyUJd{~iLMY8چ4 =|x;# 'dD;_֬%@?f޴ BrL0& GZ#S3ᙊsBT4yӓg7 y?ƍYX ɸ)Cl\mJ9{') 9)yJuHt7ed 7lw)KMVk]JoȞzf9N:f:HNL4XWJ^.3WNE?XUl5)Z/ϋ.z8Ngq)+b-ݺͳIU \tloqV]A:F,rJh1﬽umr/4PBo_%9,m tbϔQJr(Yj蛯%Ct_jvR25JA=Y[ͱ \BJd=TQs]?(tKIP Rj9wq)+9kE qghb+>-s(ǝpm^);?> oBSvl҄[oOgjMez@\{LqMj@洖U LvCjqռW㴵fqZRi\RB*rdE]ZµD9ʈ'S% Z %rtkO<ףyw~ 6FѸze\Fr)Ԭm2j5x: -&Yw'g] esU40hX5`3˺QrGÂ*sxɈylmWA3pKAld/~u4L&4yhЅ&T#0ޚ;ø{`\Xߗ.I%yd(y4koaI'xq/Ur7ϕgGvĎw"~X;rq*-õ0nNeIX!¾T~c1LGjG.==>L"42[ǩeBRQ3?1ds}E1ufVQ]9w1Hw p9 {F]"XuV{*?Re'瘯/JٹY2ڣ3Df/㿡EX`Y55kjYHG`?2ĬS UJi\M*UYƜz1Hd%T/dSUL\""BbTs8/W"b-2ҳp7Fv(!ZYՕ?t\C.O2V8HCϙ*YwN(eE)&*yU#c^ˍȅY0>V|rsP?WXY@v ~/.ܟ=6V1wI !y*;\iT`hb /s})]҉+s!cjKXs {'t&V31PlGzvʓA<X&Lq*A5ǟH~ḛ(2&m2zY Ċ'țrO yk=4lœf;m?/ydM(ZŰA<$P8s{.YX3@^ c_VeqqJ1#M"~߽&n0拙&Z6wiZj#OmτOܓ&kr ־(]xkfŠy-lQt^8lj 4[wY7Tυf2Y*x&ӹTkY= 1RʪRJx>G4q.0kFxurHϣu,B-d95rl2N%jDV^Kr=^u4Lk=k&e;9=x t=S(j BƁLO:uĸSۃ#IiŘ2컉29XFcw3ǔ,3km1'{O2q#N!JLLv j۲uxaL\՗m'PH.eG2s8B lwQ!_k܋6Gp`ܒ{Sf}#_{"} !a(q dFxPNx_k/kAc3'E(ywKP_rn-F1h'Y:\Y\]^|*·C}Yw kz;r*>oXpZ5)j.jFBŬ?l[Ͼ:j1hg5 # sOO_T=r[L8eby#F 򤛂qkU-qAc:anI!Pz>4!i;\czĮ?=Ջ>a܋я`%AvSJ-uGb~0J!GSUH"f-~D¶sRyhPѿhv ئ/iy{wti'>laeBD+YI59C5^Ņ'4XAyj=yP*I8@ǹXj,{d)'+v5hhڛN5³}h]S69%1_pL*)YyIHEF3L)Jsq!$!9KEoQ[f)ZJ*= UƊR6<.ErvIdT )ʨ}]B%V|.o0;ڃ ' S^c`qyb=Zpy1cV< "I:gdr+rd, !kKh Xdg2|=8Ì9gSE!Tʢ,>drw: C% v7 X lRB%$O/!tv ے NܗYTxR ~4.7-=G^Ldls=͒9bۜ+i^W~g{5_^WR~ 5+8YEJ.0a W/Wg<1} *Naid1*+ۢk݂m<ވV׃R-OΤ'iDIgJ3EWOG9ӠƔ) YЂ[qNwzgfR51 pEvaa3N k@J ١LП}9~ B9o(=8nŬM+G.wo"fs{s<2ia(a~ -r*au}W*2Ҹc\θIxJ™uLys2+Sh'ZlTtO^:OVd2sҸɇy'\a1[2iJ 𘔂_PZ>dw3w9#F#-rc g'ꆾ_q!L[OuK_Y!Lݐ'BRT20+UGrQɯNt  ]rD2:l&9݆hK60ζD:<=3M;VՆA9| ݘ4*elj[}DV4.'ƙlWN1xfc|@=揲'b&[~fq(ynܞiÌS)XӍ{WW_Yo U%-E[Wxh@xSթ7%ͺ3ƱLiB*1ϓg^|HZ^J8Ӟso-إm*cՄPQ{QJ;fӤS3>Clkۛ1L[לq&Qѡ^~><v:"[05ɣ48NRckV[A'VXIβHϲ`o1VOC+L#h0'z|p"vq7$n63t.p׎G];u-w{ZaeðYȏzrB ϧQQƦF}ȃ/B9j q~,c4O.MlsU8=g3Gt:K4Ѵ!ii'K8'eLU"2y*XkOI cY+DsE2{1m2[O$S7ę6BvM%u,qij΅h)$ljZ]),9)q,~@PuJvpi!Bŧؓ:B[m‚o[v  K~^L7M%aj U*}Ut5h^Eva0I-XE-iV| SN;TyY|[8Ds2gZܙ͓Aqt=W2i-@ V-`hc^ |Q`h +pVP&:^"9n.eRdbp5$@|3'I;Hm+14l@_L`{^,0{%aN NҘJdDE6Maq&oSDhK /I`|>C=S:L\R0&>wӢ euALpMzxeLPEذXN'\7Z&tYK)8[:/L\wK0Q}#,x0}crqWqS;_YA&{VI7*S4TwfO{ HeQ<ґq>c'B\l7//Q=ݸo9/죩X,ߙ&ͥ=%%;[Ư%t'cWs)'g%|Cq,Jd/;be&ĞwJ u5|&Nx#|Uh/˳ ="Sfk;3h!ZD䕃س: pKF= t* T AWJn)Z.C,e &,1|ڛC͖:ϕ]&2 dwh.0e0Wzүwi*qasZr˘Sנ(ѽ)'Cc#γ>%T8GJ 3ewbEǮ:⦡̈bTwbۄ`5-_(28^zќǼXc8C; |2SRر(IIOLR{<9tIa$o;,\y6ɂ3;T/V@ USF~( |4|]ҟaк@lNED{e^ȷe |Vqno*)Qsknj8WCn SWVC"v?h6Es-x|˒39|&m&8c'8WF{ 8x=L!>dfD,]fvK0^Ʊ -TY/^cC D>bΛsx>'qbL'sS~Ӧ8#=K@? _?ʍ6!ڍ%q9ŷqQA@SƏ_P9͂Yģ OVk޴6)@*kZhSNr>ᄜ-# ((U}}NYѡH:UםlN9hWdcCVlyًs< ۹ruX S`YBK|&ĬTd)Yi3ΣKy,寶 6ȘQF,|3aŁ J7 j3ysSHNZa;_;4#iKD.0?b{n?cX:CIޔTZǓ x6Mc8;c$dȣ tpw,6^St@2ēUi}ޅׂs>-{rr#ƹ4/`ub1fQ/:TrMbS7sԘWѡ5<^MG D|^Cr$xs-[rȝ+h7$֩8nL"S䢲wTb =@Ծzˈٶ a JSP+d|XeCKrȸ*P:c cU00̀~5Shkڗ֫ +e7 }Gq:˓{XMd4fm|If}.Gq4S'r#!tz| :8Xݙ2R)X\b)%l̨`'fJ )0NFuqqVtq]OHE8C }:\2MI-5㉞ qȌb.sļ{K"hPYLcOK?'+ ~X(܉t"LTӱ Ч"=u6+ß&sA]5J,:iAMYޮ&m5늪iA+h?cuGjڹ]4;ۤMhI!Mĉ5f?ҖvC36'r03bQ9"s6*/g:%✸^9Fn¸;~ x1 #Rl mq!9wנ.aX$mBW֥*mC}s}&2q?rFtDOb3nGem&ͤQ`Vʹ2pn1Yʔ2YI_JN%T2 jZmY, ד<ԗw}]GB5["{ظ.B|&uy O(do<̦H(4V䋑_tTpߥXצedsEtq.Ow@ײDWZ$ęgc(0`_7/2921Xi]ƈєDpvo<],i-SQ(m|Y36ZGBx)͕['RqN!Dz&RGsvb؏+);Gۇ'6m)~MH!Z|P8w^8Tp׌G/nQS%1}t!ڮVtvV1n̝"VVr5`Ǘ)3n#p":@kkpHRr MƹErz,} iSa ک+pY6ѹ:wm9#eiD? #'qcoo4Ik9e]h$ hB]'$Lv?FPA/qY]i{f`A+ <&Ѣg82:2PʃR%ri=%WU*Hv-_l4yy˛C9 ܞIi|xg&O'Nm߉Yރ.L1g^닸"VґJbܶl..y K2J1UƼ2DFDɦr.Y>ۭ7:195;߇kzf6oO#wyٓN|H9GO/׈[ƽh fuR RbXn1?xsguYiYS7yGx=ׅoKfs'WN=gYxFgZ,Mt$?Ϭ?Y]] SB_DŽ#շywOd_3L*;WVM!J'Ϫ] ixx$'ޮҊJ2W2Vn$R=iƪx`C\'MiK1] !ʻ_^Aym'I#a V%aL|)M+;/VύŁ<ƹIiKAM1JFԍ/:4;Z rw-24]J8[UHf|0[¦9Zj<6Fg2cGG>8ߎ+f'x0L֛|4g.Ў&,ͩ[XKNg<$./ZӇU~hm)x:Cy-5cȶlÍ8|{gԄ'UᕫfȎ lTUu2-4{^Nj SIŠtw$ythA=[x9Hn_@ 9*mwWp%PEsi%U5[-Xo&x҈-Fddˉh!V)OջKع'zFġ/їKxŷiD1Ld\?i& \qb _sYoψ:O4Ǥbr3&IO<5MɌBB@k۰&Ӌ `VoVFb),2|DѳMm.}"'%73?#iij7?2Tr`lRJFA>)C*n_Y‰B:ahCrgf፝]%n.m/wGkI^|,o~i8mbxw1^M0fV8/ᚡ?jǨs߶C F/+ )XP?~bOzw} ^?g OXN d0nU!N5J\]Vt3k.ڧkR5WEjo <FYgt梃 ccAMvhTEy^%U✩f^53+twxj c$GdeEPI漝Hc04".`\6MfP;g_ :1aj Ms0XK/ `F=g0;EcO]{ջ9,NgjG`:pe>PBEg9[+5GųW*rQOtd>^tЮ.uDž덶_?+}{fcDeF {6siG1 L(l'Ѧ6÷>ֆ_ ~N8>$xp{4UŬɯX"8Mljodqem&cKCυC O > z7 h? 48ŅH?Epk閁y{r_Ͱ1Al( E~91Oӄjtԛk=RsյkZîsXxՄ?Ka*zRʱ8lv;~#K^j*VR^oY%T +gK3lNN+\33:dBmR&T;NapՒɃ2/j|m_#}=NM[y=w 0C8c#{6_%gvyB%]T+Or?nyuDiXՃM69ңwnFTv͡ٴ<p~NIx./1c#оiɸfݹt >d=Vc?ۋkO*uѕ]Hb'{F ֒XOw햔__ *֋k4Zwc#aEny=fnnC1 gaoF$fhvE? M^2{&"?~t[Xj^.D+cD:6}yeFX֍Ǐ.Ck"[qLq'ZGs%cٺ&hD)&j\xci:daSZPS_~5/T3ýeZv)jѷW뢎&kh Gq~g sYTĝRq玌sd.* XWsr+X=LgsWv0U+ l8S+ѧ;a΀6Ȣ>\/n(,9=ett%l&Scb1Csa,+ Y0<ӯ[իa\hXk'/aƛ{KXzIJ`trpu'K8حUH?dzۋ_w/BظQzѺ.oedx/xQFFh5k5|а:.g֑jW +vk5G*  &׸s7Ԅ;i(*Tqᄚm*|N :W J#cbd 9+G"y8)~ uB'v:xnjN(uru!LvƓAYExP쿺B˃bҤɧ$QRSՕPJldLG@ܖLn|- &k! Kpᢻ7%v")Ͱ{L8,m`}RKfPBA/?&I_$eA2^4EY8Z:уN~q8k\zoR~g$e XVʓ^R?m!ûɂr|XVV $4W0|B2-x 6?wXы!fT9܇g1?DTI@*đw>F$Yg餄zTf'}-E$+]dv 1v<}m%={m9t-#I"ro256" W1'IO cP3]Ƶm:\OHq* k1y|f%%԰Z-ҹ4: i5<8(:C^5739FCٗ*lPIW0 ޯKcYNXk9JqQSB5KH~8^qN 4#p)Hf^\z/tjQ&ľ%ԍ#U;iA t/Gٯ"?>9+Y@MLa%(i6m), kgz/{wSx׌=lxÙf3 雷4ؗEk̰mQIl{&Ǻc7wn'3k066yp2-Gm׌y K᫥+݋{PNEeM`&)2wvSgeDXRB_z}~%qG.wZ',ZX8ШkODMY0>CdcjxW";dK]f7IBAgP-)I[iѸ$ym-/):dĵRPByo^Po U*+i(Y̻BHӨ$d]\ȑQKZ硬 gB{w'd\AO*ps1;&ph-6j8zk jQ]]j,pƺLU,Ws_}e*E$'Ϗnk?ʏ9uhMn*xa F#v真YM}rgCƗE82MX!1:S$|YȃGYBw`U 9_#{oQSR63ir=^7õaPWβ`T<08MeGdHqe CM):=- N3t,3< vgP玴hfHsrſ3-d ,3rmetm$pK8a)EoIQ+%Y͖2,+)ToN>ݮڢLڅo2"I]6246Lyh:N +j>aN-jxjޮf̵jok׫okQC`ZB8XWIr,jHjñAl\)4,*W&e % +xo(mO1BĞrjHoG Ju@K 2sG 4LKHֈcB暫W{[S{{nNئ6ڇ-{z\WtȿVDϣ\].Ѵ[#|)}1y/#عN>'4-ZKش0Bp]Ϛpa=*MBؽ%lBI4K`ӱTFIX-]eP?.vs ]$Oc7,|Rf7TqaT%[Vu՘ Tuc3TRv|%*iQA;J&T몉1U3\tÊm\'I,9"%{bߒBJ'nU>TšJ;z5H̥bfA53E KjS]i54|HBw, ڌQgi9_~sB\kRzggkÝvv$쳢LX͕|:fNՙjI[cxπ=p?.̺Zݻѯ pDk[?.7s/.Y"eZ?arJ,a͖RʒS`HVapzGO6-fӺ;v؄lɲ@׆V+ at(oړo3s~tГz4i(uxCz1w6sL41? ' d?SH  nٔ唍/'R`9>؞22COΜ7%G 'i5*`^g_ 1 Zr-$L a\.>kdfIZ,aW6s}2z75"'cUs WQZ"5 *` Yys|]HZO̻!OR xKYlj0:btań6Ήa VEa:9 9{8o$cΎ^ B."Z_-dC! V"+'kU+15E1`k-?1nAvZCTϞzZ=`U^>T򪬒iTƗ3youDƯ  S*xsz=OU;'Yxy}kj9wkY0:*^Բlk-SXr uxPKZ԰;Au˒js娿=%m{,82MDKQ,'Ec>4(߭ϫMEhI@ {DR?U+Q% [)em%s9W2FHߝ{vh~C1f(pq38`X;VF2K41}B p{=Gm)ODg{Ns㯧/澥[79Ie_.݇q3ynX3~2B/_,E-Ht8SGM)2锊%|u(WG>Qǡw^T E3# cKVm Zi,{dzaBIiU,KBDvR7rLԟ[]Hx*A+&t#"ɈkBeZJ2B+HkQ2NsEOڥr喳YMtߡ 9wG8cnL9YPeB(2~ XðJTsѶ߲:~԰S ձrZDpI-u8TN[S+K5+fj Pu~˸1 Bf^4{'3q"͝=ts R,E֘#ۙDn#D3Y5 Dj(I8EK<ң~Q#tB^R |舶Q|"!9"' zWXt\ޑϷˊ=6D\rޓ m|0`ZϤtm t F?Ntպq'>L||Reѯ]RK{ry.ry֠4 +=~.Rq\GszB tQZD UH1Ǟv_(tb|T4ߣ~1 8-Hȩ)Rf]>#vJi\LώŴ6.q]UE IY/%frW*pQ-sظrV1ሖW#[B-xR`xӌ"ތrYZMbN,&%Qa/~++H.c2>]QRŀ5X|-֡duVU5h_'ެ!eZF|aA-n tZZUp^#tjgTqb_%V"3vQ CQ5 O-)pY_ [ }ўt('Ʀx;k}_ۊu;D*erDSsZ:bR9(3WRphVħJJwO&GAm2tȥlZ(z\Ҹ~)׃m01Bb|M=lB3Sޜ=WρOTM%>͗cx30, ;7m307L沐f2J: hrDzA1M%AZnXBOXC&j=/NأmXd!_E,ˣ͂LVitZNKߑftMY^9XLGzzTS}*P)tJ]ٕ瞰1mZ\5[CdutvBNJ9_*VUӭ)%sbI ~KS)? d"qs`EwHʭ)NlY9OD1wMz=ܙ6DNV|>J质^J)Um/awd5'jPC1ƅ&Ixx^Jxꞥ` [}8 IYV3(,9Rϓ"grFJU*8W:5kpݯ%E-(<#ce_YR)QJK mrygqAHoy iS0_2d7#>|k_$X_.:v-,g…ryTY1&J]PLg%ޯgL}PŽSU|IbS%U<+C*j7UVm!np9mK_C:FTiXГ}Găů"(ȧOHnH 0f9abG'{ٙua- 9Ll@Mb}.fy$mΎ&b.>*w8usN]ܐÛpo~s՜'4Ϟ^1d0UXU^> Y<Mx"3YO y[o6rr ƈu2! y8=XԅXth Kx3 +r$%J]2<(H'59ɒsC÷ ^܂4օbD'g!#0݄t&rQ:{q};2wCZ܃S6nm tD3:-9 [qj{^4YR\Va!io*&nUmH2b:k)$'91fT,W̪}i7QbꍖbbR,a1^2*P,tmW#zMbVz!Kɟ]F2~ns9,@GA'(Ub>,SBXKF>g㜔ap!u+ "cS9EAcX SdYڟEtAŏfɓȎ$NʒjLϗ2'e+y!Up.dpmCc9o>ri6?X'ɤ$Od/u`;o80e/˦<*ҸIdWz@9_8k{M4vw2fyyowFӮ M,=6Ԋ:[ֹ1_4wq9M"aMiA8p1'#3QNLgΛdx}jM!7%x &巜qc*ݰa}o6}2 VKoRRWr,ZKV 4xmG0Xߚvځ4WY%b*,sa:ab?swo!S8c1)tn b3l`Wy 9%+VJ%hz%򶦄9V"~Y`#C_'JʗlAKE}l +,Y?9DeWfϋxDN%#Kl][Z7Qһo.yiA>l4ys;Z%.ZCA/&0tXMq#= ΦjTQ:b,W*z %,SDSB 3# 2_ &z3l_.c@t]g{h; Q(M1ՁuveREM"g"'_X):=t2ntۃɚ֏PO]P;$d?whK 9=qUszzqĤfTLK'U1E\ /fEX#5XflD3hju~I.ДmӦr3܉r+/l &CY%wEo*YsU+t8KcK=ݳ)ϝMDg?j[q,#+~FG$Ed0OCƾ%D^RHեo$RJ/VAу*)ir\Q%V2 w9R֨LC[)}oJz%duq%Xw()HogKX7sW8_$REfKp!*IJ2gH)S>mg~f B={R)Hw ‰!l]GµϦky=Hy扊^22m }|R)sl2LFoUܚ.)+XjU6yˢ rg ">՗cCGɐ|gXX)=bq^4%:G:0u%K"'_0ak$x4֫e~C54VvE%m/Vg9-^`f?5bFԆ̃iFtm㍉$gr^dqoFLvkPtGOoH{U.p^t|—KF=kÉ8u^;1{Vf99cy2C#i95ot#PndtJyc(cz-2Y'bELmF̡yZ22DMEe!qe \3J`Wlinu; DN}ͷ2u3UղFj<"MI'"Gy#T˛Ľ!n]S\':=4UՋ,pA.(esUo5*z~yzv-бL<5 jhUo%1tSB",J֗3 R +汅 0)Gq}KiwZBa{"DgsMm O>0xRk)XΈKu3t 1ƅLɋ^`<CZ.kٺ׆Grupwd['""E}^_]):ڪ3mqZjicΤXM%Y/+YUJv<9kȠX+?e1q#&uǚNoOd 7˙E^|pn04/H4hYqLv&_ɔ\ hg m-&kG BvXā#7v5x=?-%`"Ϙ)|k{'6E1td<&y<5pj>/Dž)>N#A,<‘7{(;j?Z(.A[ZF *]SE75nѿl2$94ȇb :ة#{rI?23lfxk@>ɫ+1}z%8bMUZڼ0cڣZU3ar^em BO)! m鹭]|T1>!*)wWJhEBZ H ,WF2\&x9͞qs}ȥW|~Ep]4NY3wN8~ ٓxƖni}k't s:.Wk+ױҠAUxvF%MxCL3})l]eZ}c6;՛m2dK%:c,5&fǠk3|a{\_/rP_4??4~,SĶx^unʩށDnOyddNx?$@eGVxgcٓmΩ7\2,xΟ͸=P))>'Cc9)mtAwW&q|Y6Y+s= <ݕ2=Jźjf6co'4uSj Djr?>~sd0jlC L8Ahq{&K Y|2׮eCv}rbasܚC$7Ec#9L vi-cY kA3{-sR>RWg* еwi4Y}'$tП;XduNTȦs~ۏA|@JU%'TbD5υ5oUGS=Vʧ 8izIN-9=YMOiKX$b~W0F₰/*ZQ.)룔E*N5.m_i T0JΥbcsDg/xaÉ^>,j{8tÜve? p*kNK\{H`QzzU3ecIu'~;a$l-gr},k_i%7pH;ڌ̈́iNNJHQ(l{E~NM͝]Z%(9?0rZt4o2=Q=N-!/]`WcJrVa{YQM -3x͠d Z[3Sv&{#6Օ.fmd?W57115 A.ve\k/vF{:?WX6&Qk'de [=̉HҺ] eՑ\ʄx+gJ WmNg 9ف՝Ý=ˈڶ`/k}Nn>=&j1}f|S“s>~S1}wJZ68~Tjj! *X-lƿF2i^Bb%jtWGb#ԔUZ.FqaޑA_4d)و:g143zlþOw6}rIK*D><`] 3l̊Ʈ||@ї>go+g%XxSp+/OGsH3+pe7p3 !fbJT|\㸲ςmS0QׂRڴ3ڹVtu*RܿWEWerv& Y1,ges@m]-0OuV Y UMbK(3xp0"1K`eн\bYți0`F̛ȁSi(b =0ƶ(V{pɏ}^MCqdL.6FRFOap`O l+W]h>5j,q~F*&3/5!iEWგcE&gA{?ߴgҚ /mIv7oxR|ф慿^yi.iXh"QlzR W0BmgKFbz}e5dHY;EL{"F)>R ]r̽QI`G1ڀH-}hE"o회iXKcYz#7'g\(yƴ2`ZY&1C,%ѝ%䜟^#[J$ҝm}^ZO݂M5&/]]n*hؙ%5LZNa%/uM)UJzE3C2-h' ěp&@o&;`ݗ} w{s/w{,u݆6Dt/һ~(4Igjty1t<4'n*3fM8{n3]|YzPE2uR Fy rCF,=Xe`+h|8۶|gL1{x+I LRq<: }q+wA|9bNޖ۳%\HO!Lv[7:ѳ37ڲ8nkĆ-uEu_mO' hdž;?[t`t3w˕9e@+lyY($BDR!l_`OFx<>j3G H]~FtND?^2n,]K}C&f*硾*xxHg8$ݵRw& B&w({IQ,b'Lo <5TC/7a;[^c4vu 4=r/twPnXE\ȜFW#}h?YMhW?A3X%V僁Э޶Zξ H EGεDods8n(a\.or-$ - e;'δdMWO,g\vJW,S>Fq2~IP :&4Cfڃt#ۃĝM1A٣ŸZ/Ž2hxv? `n^ eT81JE_%vTL T0xq85v/6VPMJ̚(%mc9o ^qQJ&Rf-bL2 㔨ǩy0QRPaw [ϩy(xʺKՙ?]?akў]DCM??[|x"J} O-XiԔ6Ѱcf)Vz2Q_Qi9eӳA9W0⧎Er6R2ɟE;8Cp>ù5y&Ďț#y=HwǟIQԿB=WD<%ZhZ05jFihU˪~Z7W힊glh怍I%\#cb4r|,aDI\} Ǖ鴒4 'PU kU|@6>C 4|&x >#R]Xqq,9cKyT-/rXϺd_«26sv9M2c±&q7lFQD7''/uc!,oeC6<m_AgI 6̊uGO_ Yu*+_bY),XOZ&;bOFIMhk$B`}Ў,G_rCX=w=Lƒ&%1Uxf )\sdk$s7IH75ڽ1̵NoSYC3wbD2{]˄= x>~9gW.:+8feK:uy+v)*Z[L5/as.c䦢VwGrh++;<_f`3>9X)#q<bi=5' XkUNR1Yw*St=Sþ:϶.Ԑ\JMeiLsJ&}A_ftU ڗ``bKK)"k j.嬋wx/dw=;t.BWqS2~ӣg(h[|NOX=bQX!c2\R]91tKgK*pF ~*81_,0_š9ìGv"|;בlj'7f@sNa̞mߎMFXLOִ?I/A0-j[/􁼝Ny,Tɢpv@1aD g8]G-8A,ABu7qwww!B@ww{w<=jsj̞YHuU|G\Ԣ2I`0ixr9e Yi@'S`8g4#a$Nbl-pN+oP?mLυf!stf\\ 0qE9 `-|PƵp;ZNFqr"X̢bv!U{]^鞙B,:'9%1WU4Z%.QȟN%ܫSI*ܯ@ NT񥸒"t,dj-xY5bo f,f揩 j% *h۸強sJ|nWd̫ff{N.[ʉ9lQnUίv zu)xN™3\Z*^"kR%npe4YoBƭ̣e&Ύu"&aQ?OuJ\ {x;l~Őq;K0G:fPԙ{4׻b^5;>dG1o(d3J`ڕm"k2 <ʍ2)qь8ό\ki7YWcQ@PH+0XˇRD6+^ՌOKE)H+ۺBfz1z&Kţ:c]ۂ/CY| 3jRU\)@1ԋ)V<exˢҹ6^4*۬h$%0b*K+hqPXoG6/ NO:m:&Ok%F*c_NCr VVвdT]QIQNRK9ؿDf+O]+q6lUPez?J[Fgr֨ E<WAaoQѥG)O*K$xt%?Up@9s˘[BA׻IYNnd9ϽlU_˽^">;T=fqCo8tO7Vf&SƉMc9llϖ?MXQKXk~jt&T;)Q`Ʌ.úQ%$383{n\ .objO>bce&ttbw'2(ͳ$+DZ|`XIBOu,V뉤%&.A<g8= \,#';,U pTQ]?~?ըXnׅ&kH Ǘ7Vz^0{l PDzl8v<~Gh?N dr?>ċQ8YM`<QkQ -ӻʸxoJ1+#vjSE<~>M&SUͳJQֺ 뱕YeSQ"rZ},!;˙RAweLVgJ:V7Y~T#wge[a߾TUpuP}M*쵢& WFN>\J{Y٭e _v~ٹA.A5(YE j1J deS&ʁ6݁,nL9Z|ud7-ȇaO=\] vmoGxSOsbV6ڧq/ë˔A:LUPƶbѺe*/x:8̎z4^ܩvޚe~M1Ǘ8Kc[>nƷ7(mʞOJⱣ-]G* IOku4X6ilt&eE +r Uܗ 5/b̧dct7hE@RX)ro6 &c*7bQu풎Dt͵> 2F˔3g.e{t\Dk/&@{ % y%Nb<ߪݪLBo9Za;c\HB0M /fSpJ~j)f2z̶nN/j7˥Jt,cub*KVnTpf@UۥJx[^^ɬuAL*3MU >̊aU*:2h?QR\պq8q2 Uu*{V.O$)%ۓf_@bnR/6h_(dΝ\^LTь) aE#t5مQ?M}8ܠfKLsn/߆Ӭa[3ܵ{7K#8ś#iŴ>7y=G&d wQlsr6ty14>1TCyK5dGsDүe ZvQwfoads4QK~fk)ۮ('o׆gWΞx-Ixvr#Οwݘݑ+,+1dTTpo0uAs7VS_a@/eXjΤ<zVWetL(<:ܷozL.cRުzoU^|݋pU .V04ʩ3JN%^ud~?\gC,{_g8.ɠi:m)@'s3x*u֩R90q)܎'=xE&nrvKՕfsڲrʜѸFIۂVcr µٵ}t;Ҁ4ԍ^¸AoBeS>{k7R-Z0;++X4CzA N|1g=A@` Ve c>M;N'?w֍A~¬slԳS iQQKX_o(3 sT<@\_sLn8 .~ݞt:č{uQ);]%3}ڑ}hOFo  y؅ߞӸI%tkd)2Kyu]*xq {J>5(eg'˙1+? -r6)cm2YʽM T;ݭuUS T·4ZJqev*`N8Ƭp"7Ԋ=U_2JHUN;trئ}ʹ0i2ߤF^ݼ4b0:Ƴya<'`^u?sxx,ѨFfՑ0-knFlϠVȱ4jGr摷٪͟.w` 'qn$rSf "?ؗƣ{/N u# f%G-`ôA\9aC+ա uFk<M>Rm8zFW{Ȯ_1sJٽT]a8 >52Sm廧+gp:K>Nar~̛>pbNQvE>L*%(eI>ٛed)gIX)_Z̥IjEϲ|6/bB./Da nPg.ʏblܖX'n( Z`R>EQV\S+,[flě?$%ܛXGp!:78|4DE">XRLX,UV{TQ`ւK&[\b͸oe,ѫ7ޥYޑ\᥵;#ϖr@{?ydnDeaOc U=٩f0.gJ|]˜TYSquwߛ2{3e34 ]xCñq`++(p X"5/( ֶ㇞;-G{23ە>niJ">} DO4-ի-+(WDő1BaXQ )][ r{MKF^zbȃ(񦤝ݭy_c\|S*Ml$ש9] ٶÊ;A.ZysM:2[rO;N``5V+mh6 H ߿٭G"lr/u&L˻ k{'31[ʐeWb5;3쇒R˕]]GU+yߕO ;hb4+EA 5 gs~C:&$nV\!7Tl+ L9gm&}p{CA\=s#*Y1GFfqoC,YNjy_WY˒vuPkܞz[*ۑqZ8_uF fc3놰mz)1,|D onȮ(Zt;#GѼOxpϊ .*ܯp%sU`v0:TyMu)w  pZwV'HXHͪM;C]%E,1qOw,s7P@Ug.TIb2~ZQIJ=1f`3H4C):W1^<9W&]sU% Z zۓWdxXL+Zwu).d Q zE:8 ^pF$W׶+_wkͣb޾#þCBe9&;-iƯ! NQBy#UT Q_VD8obƴ6.TrxDEmXkybۊ͹7x3"rDOZ+"6,gy|UNŇ<"N`JdbcSQ W/Xd7.K, ,քn6Oeg&m{gRV1dbqͻt¢tyD> \8r<}2I?PW8Lu3{\XLaXыM{ن&#ʕ#[zL pIxcesuy^:JUSNE!OLdǻhjƿx Oҝik8 JVrV(H9ZfҢI'F=Յ褗*6`r.)gLVNe;wkqjw'>E2(4LBGxޮ%'Fes0<O” _LD9/, deG-;r4̍oz|zӶ +p`o~{-L7Ƚ_uշhW,yۚ12R 簡o[5~ aj7bШ]wMV)8zϜa lYg`&ZRQטÉMVC!1/_\=Zz:&loc/vrO!b{]v׌+X?v3cxě^ ~ a5,((we΍9v+ 霩UAe\+ryOCb8-CItKkm<)Mb}bG$~pьP si&eȶp/ J8_C]k4f dr0#? *E s4s}#l4 C;>DyǩrǛB+OsoƎ `Z(.CX`NsFtٟyl .ƽSi%x%D^+ơcI3VZl5A=-ώbM˯rQF{=86l0bB$*x8[h_AA qy)dԻT &bwWR^k|GQhSlK-dG q7pG3ᇼqy{͍x[w 2lϞ~v6aRGCnu+"o oݖlV3@Ӎ{r$ ZzP2 fPu IŔ%|qdH| KˣwAh<΄yL_Ӌ_-^7o;?qG7.{D+̎zgB^=CyBKUJ=I+Eύoj,F_<(lVJ_CYOmS>КL /Gx$]NkHX(. "6^Sh2ʱE+m7(7)OoQ=_&ϦXybz"wk}Պ7|Τμy4;wwi}/[rd곣;~'Ѧf:b9ꆙ4^h)m~ۊQ+, c!cV1Ҋ> &؉E\> ӓxaFzktwwx#Ñ g}7FghP,TpQGm*5QX@8^zb} DyM2K4~/eTo{Zcjk:0oRf105"]@|eG;ĵu@Tm3 ^<v bײP7TsnBU.eS&^TZq6#IxsMb?'Ю(ڎk6hv,{OMF+afѩ}6{HU'&0n v3_ -y C[Se(}\zaT_ݞnxK٣SvwxR1ՙ6@|B#In֎11B:Y}Sg@W=L˄-,Qv%anO>$pxt$}4qɎL#tm09w5,?7)Ie vj!@T'6rj+cDc6+<։۞3eCZz?Ì.nYg;`DL^3''0[*;rҟuanhG%"h8|~((PeWV2尢+ky_n_m^:WƜelFB/H~ŸKuɪ0:܃]hLJ׷<8yN>lC3F3a:1O h~krL41m;f[0r ~viY+hqfB|/R'(۹Rh/IS?_ =|)rW OwE U89FaAjW&ǚ[)hOl3 z2k73{Px؅эxɚiЅvnnj{#߂yC^|H0)GN0]B~+7T=TX{*3,knדtӆ)R*~ԿZiY1R7eJ7.7pܷ(88Ɣ5Xe´2%Grψ;mX҉/2J=9x0_[PJt"mEFE?=y=׭E6B1A] miwPR1[e4m{bNm(/M WG0kBj_l3uY¬6ʺ+lB8!%&uZqoqkR\WܺtQ[YԱ0e"`zJsq{NL-,NuNj_*67P>\pKx?=ԔʞIݣ|r[r{F{(IwT,KrSWYX_? Ăگ{#]oNi`; TϮNkY: "41?Dܙi^\M9v8 nouZiIޙ"jNW*+)WzPNw36tW~VyU" ٰ8J5irK*h"}Iͧ1usu“>ͩDmyVۂrdfc7mC?6h֙TYցb͹?A[.:gb%#+gr1ⶂ>Ì\M3Y'MTԻ..vA|1ECI5iiQctA(V׿('G}X~A9PLU*ߊrȯ%\4#b gtV +PRюs+#G^WtH Gshi娃89{~$B{:إ`Xc:v}3ԚLaYi˅z֬DޡzTS.+j޾bbV~@y?VlПJ3e>S"&ق9;Db9]+umu[GɄfy6hHstՉVNm&vtSZ3[z3߇֋.Y?M}҆'zePM-]~h֣8xk؈Sq8mϞVhziP#&M#\~D\7tm/VFi6*<7I)A"31+3CH6Sr-P3v$dD #Q,ڌa-_|f7RnG7gZ`k!!Ùy[ࢻNɞaQGmt {bq73;m.hԌN=8Nړ6"r^{wh'b{ߊ\1hQ{4R7No ŕ<ku;dɇ֖\dBp<{0E/vxQ'Љn,Ʌ >pdN7%vNBV6ڼkdGove]#{beOntҷ'y9ФGo}qzʺO#f^_6h^^M\]X6ؕOޞ<#; j6$_'gp7c\ dUN8zcvВ_uϘy ǙY# ;;)tepv+cX8P~ӆmZۦ=9] GLWqzWҮ%F$]e?CaɉLw^i;yׁqf6wY3VU86! @D*+hs|8ϚCmQ6ώ lJ4qİ;{/P[ V7-&PgMD;3!ݮ+=U} M-$ǭ7_n(g&a~4 TP:}[)4^+~R'~%_>rƟ CY§ܹ̔y1 ipr8}-,:nO9OL}fsP:{8P/DŽWL R)5v9[PnY:|gNe]W. Bv;S/d[h>t܌]/ Σjʛv 1-8z{GQ&kl1bPC,?Y KyÁiO }ސ"7a6∑!MNV_gV}T#|R#{Iwm=9Mn)Ϊ^"gn76jˌu)5Oā/m҆%|I CG cYx%{>XD0GiMEðxMAJUaE*[[1>[獩2jOIw=*Bܒ 4ڪ˪[:ٗ1|o~eɣYx? }7|nxYSǐ\Jxj<ѳ2`ƗE8`! nku33I;f133333H2,ɐ fffffffڽoNչا:Z'Kv[={xlӟ6{#'TifѼgWxd)hB4{v.1^flwY+B|NF̩Uܦ"+oEѫ>!"7{Okݵ_pea*/2DڈOUSZ>G[o'%>,3bʧˍTn4<Vt슎%"!b_̒2WP֟\Qn_cW `BNqC,&_FSrࠐq6 M Q7>7CEwK34|$ 9 ~GqV ^ٸܚYUSד(3/ĉmp"zX ׺ d$gTF Lb,O]Ϗb.n xߝtx(;rcz{㏯:+uBĸ]ky_ȳ`dO;xsqM2Z&ὕ 1%X-0P)JQe4ʇ#lrCKd/)my܂ /*݄_yL7f}/Bbܡ!q5#`Ժ3X.IOk痆_<J1jcN>nˏW"E<@6j-G"JͮŃ2>y?s!LG >i"iO%7r1,)eµHl:}VWLۈzw#!ڢ6ˁ sv vd0-m ɜ;^lԵ֌շI#;Xk)c`-iŶlXlTW|;R (HȧQC]rݑ\m8-Ȇilψ%M(%-8œ8ͭ=V@5t>c5݀=tXĚF4,cfT2j)Ǖp{vĒIGU8AI-`쏥ؕ0uw`'N|lHx%Nl,'(=9yxZHPM]eKf0N5N$j^~% =JKD šv'{渰ٞ.]kɎsE]BDo"ӛ[>*1"boby^FVPEԃà t).R*x,n&fkh܁;L8u͜КJ^#{Xbn ? joPcOLmk`+*°4L%^ZPe2UsH3q2ϼˣ6?>z@nn/ys j0kMe7 .YY1؂cA2jo<\t5-x`<՞B4P6+a2^*7,}<қ1U)Rdt\D? !^ʿY tu>Q-FPƩx,q`% +Hn-!s^Yaf艣49k?KѴW9ca"&7nC gpn>ӌ8ՂCsŝQ*/p$n`u3o^ݿRlXQ'8(͠g1/L+'unqRVyv+4R=xLMnHi@k[Wz'sE3j+hREF`?R=$ r%Z Br7|܆;Ђ01 ;+"q%Om6>P1L9l<̈_uX>fn?=_׾q }}uZ=H={(ッck'auYCվ\]qUW g0k 5!2 )l롖hԚYhM#6Zs/V_ iK<|H{s_t,!I\͝ft4 .ϥÞbں1LFV^d,ER/w{>SQfg?) sa5ɝI(>PÅ,4"Z$Y]Yod6p1ǃ:eݒ2F =JKzb4}R;ѿ621GV@MBHYW4~Ѧ;~9KƩ{WrtΔ=TJ/υ\PU-*y7PJ8.GΖ O0fc%h~@L04)':ap;=XB=\3Nl˻m{@-wi Q eƏXGr0-8S JMFOz%՛B(' [i N4`h٘n>&fL 0f)XT\_ڇ~ؚOqdneQs*%/>Azɚ~IH\433W" vArږMnnɀN|`p{mյؕ,f[oq#)2cY:Yt)A+IegGdNO-RrupeעtP_̯b/Z\s9ؼ%>!aA?Klx^B$!p\/^ѯ!6hNjdґQ l[JR$Yg(_eRTaV5_Ъ{"W2ݩdÇ3!BV~ft(F}fhӫ~*-'\`Q3غ$|b/>3kvǀQ!/ģ]hw=ezaxfȸf2S3m?%4Gp·[t=SC|FBxZm/EG3Aۡ}R?b{ai8Mg l䋯o݉Oƹskb)Y غ5M']i;:  h*ɖt/"yvh:Y7uȶonuAP}7[0dӰw,.OЖ^˭i6tTc97=b/. .p-%oY콕N)Ih?>x\zM8 Dc:*BCeB'm/RRQ1mQ6Uӵ}-_U#z\ArfN-cܽ^cr>(lV =d17e?+Fb 6UX6O1C$x&R=ǢEc͞zk|@[e)׫ v]DG];. VwIeQΌw2=q^11V*ߺrIᴘ>w.'Du,-'1#C tb}'5=(}ji6DK'o:;n.K> xn3rd3x[fU4-T/l:r.ܙNp6s<K,xd>D% ':p9M#4!ihB3;#=h~םqLQu 57U&浥B3oΨc[8B=X0|=+xcߔđM/V:΁{,LH0e?"9ϒCubPH)V(]}ZV09T{XГp:`ΒLs\Ƭ0 ,x0-J&P`0mShʃE^ӊgVE>>O_82 m#i=- {Ce]3y5KhG:F伟%1$:=~'j#c axƓxvߏn.\)¸j+iV!`mKyrx2Ӵ 7-^h2  hUů]8)Pah%z:$9\ί H ~NzMN |W.hvE{&K7CvMrQQzb"{MڇPܑ4S+N4!E\X'u[7;b @vd(籷mw#]dͩjf%Y9]8'xC'T1u8d`Ͳ5,iɒZ|-tɣGh 2\́_X:֑lȫ !D [0}uۋ͔X{Dx6HÚǽإAk3=ɛ^OceAs?P Fp8gs,e&1,H^!>Ǜh=CxפlϦtyD,eh.HR0!\fιClǦPo)l~v|8^do +X?**ͪ?Sy,'i+|aJRIާ0%}}»hd\Cl--СF׺ 6u&rv[,Wy2aX)<߁KQ?.ZW>-dkѪbIi,Mbҕ| |Cj')iBv'v&܈$`1g yvŎyAtA{ DZX x3#f`vi~>M8ɊM|ꅋ7>%K:N [_? bݐȡR1P?yx6 DƠ:!/{76'wSc։]rsv)7u{ ^Zy$FQ]$fw\Xʞ-(ͷlfMa4ڊ!:͸ܧ7^Ts ?MeILbdDӌ9QLfUh>EGN):^^T $n2"}X;[KU[;AU׬d[a?jI#YKv9ҫJ6Ǟ N8$ URSr\f[ST$UX7,'B=ځB;W<¸TIk֢.W&E$j^խeSBYRsXGYh #9ԯ0<=a@1`C13K}Y*Qw-dqŬΙ- Ǽsy;}$թ"*^EA5-+\ )‰7ݩ#C&,AR 6JQLcP?++qCǶDLW!ā9~v|ַ|îQqV۲#W^̰).tp:F i7~o$},dH +S#|Kjo zvuT]+|tv"9% ;Pgc9k`[ǵ8]-򇔹9|?`UXm*dq)gz6LcAʌ1鴦bEQ0њY.L N ՕLu)+-8sCV |ɽ[-|/Vv46o#hy }͕Vͼҏ}XA9׽IpDe>q Yz%LMӽF1nh?x! s8pĝ֬J@{S1j*pQz- բL#'hj)X+%ZGQz^Z3{o6w7%Hn´.]t]1Of ^IȘS'#Q|܆Ot=as^7|jLAT[PqPZ[0%Orq,Fk yE$~ϧh@^T)ĝP><ρ_RɼOr~T:HvːkQ"K_@S& +>ZÏf2Q20x_Zãi']05IS34 VuϯC}b&+ )v.r}q2 8j_}}yU4K3/ D_v"z/^F= ʨq9ؐ5֚rbq?.Ibrb,;nBzeK}(! Xk(ux@W8N$e~@\s 96\q 158a8 \|HŰjroF6-cA-3^{0qp0S>(+ >(9"'M\ABvm5&@Sv8ӻ(f<ӒSUUs:Dq_5y;F2eVos׼PvL&+K™P$mycdIqK|.-JI%l7c4}wS'Oyѽgze; J$Z}! lO^ tyJ9ϋin^ƨ"jz{ącl1xfk=s#Wd~Yj0Uˉ3uLcG 8 㳂;TZz%'*0իüBA׶աϫxߦ؏rEșYP)u._PۀqǵHR^Xcm#yf Dq$:J#lo\L.JNfG.Fe0*ݖR\JiY@<0K4] /VsGӇwtZN6q4OFIBHy?VXIHޝ[dDi0F(<\M޵Q<_鋫X0FaiUâ w/$0oKY -p g/)%27ȘWB_RvJJ1(; |(dbKG<*|I1l 1E3sL 9q"-~UʅzWPݬHؔՔW {ȹ{լґ=FBC/5n4n_ #9+ܗ3FşJ>[R/dzP\usWu|5u99,`rB7qH9*ج*'wɥR10T0ɝn W`etLlA1u(AC!/_glǧ?/Dy1Q[-RƊ">C_?mw[M?y$![:_Kpy R. a:ۧGן$s$?! OO-4MrӨ :g>|jk-{ܠ`= #}q 7 EJz 4[Ǔ'̑E1xί#̙8{Е] 6M)F*wDC;̪ 6=[>Oee(k?8 ] |!(0\iG92j']I`ΌrdӀzw߼itĘM2n xH \B\GTLz(yQօZ޾cֳ>RɬJiF|#*WcdJ>/-۷ X") HKw ==bbwwwwwwm|~~ٿy,&z_PD=j,MӰc_9'uY.zyݞGsVZ uIYb ^M$l~ù {ea3iC쳘&pn-i<˥ɴXX[$$V,fwKKNډsl{`%2%sְUCݑZn6qrsvfo.q:jSyCO4=lD溮gu4hjؼTMyY CɴrBǕL)r^@V \n_$nG4qfIhh"GT4zFS牏~GYX[Dj+iVߦdw G,?!4q{nbErc' _&]ʅ]c?Ï!r8x}- -Q! Zr%m*fYȪC*YWǑROO-8>sS.K^WsHc"\&HgI $ 㤁4m1+$MƢ8;I r"/sg~[Zl^.$oph`r܁S->lސO«E,SdUgUl*c|wN8F捲č1.YƫySYs_Rθ71¡U|Zpx9W-T\q+؞WNDJrYJ }Ubh&pFjQ!FߎECbMNR-bb1 "?4+cY2﷔ylͤd xDdFqx5U`]~,Ux F%;4^|pOf£LLGX#8vT2KVSDbùA$ztq$SI*3uCЃƊ|-2G%i{*m\Ѿ o8ě鑻1.K)'Gr3ǚcrq|cOd֨<ϧMxvD#\{gTUh5QG&f{Det,űFED^&gZ}n {:(\ztA\ըT߫` }m QCjVx^C{խݧ2*1᷵3עrul%'wT||Yd5QAjUi(z35VhVɳ5Dd+a-KC}D٠Ʋw;JyX%4YTϥN%)CΦRV)byCk{#Y8&'>+S(HF j JѿD)l`xF2WP_tq憚=R96)17{[qЗ:dx;*P5޹Etdz{(7f`Ҭ}ۤE oܕv)F3 tfEQ9SoǑvO'Eqhm.M RًU˭I;%c8س]fDz^BE<ߞďA؛_?Zҧ- a(n!ܘ ٥?\-60VǷAjYp7M`樒(3_ B<3b?7DɘC+'m ex :^wN YqXR̫JzIcWG Ĝiji軪 se4[S*^ϯfO@"f/r<]tz \ 0rIhά(fAFY$o'h>zKa*z3}gU fY2,ԸQiYq5Q3j3"Gyg&{x]JO%*;y_BT(`t"k1'Pc"Et_r)?m'^g#9GV3C q%^JAև%tb/V)Ӈ+P)JQŹWF\0lBM"㾑oLht .\YxFgqzwU}߻Vvs9N9CG1"/]]8?ٌoFPo`1%im튝c8mQ N4>6*8Pe~3OH?_P@q* gsgn)!@TƧzLȧ/=)Y$h~3?nSS $FѮt6Xdb˻i쳍ǿ>:WU#rf^,C+=q6JԬ{&v=\t4oE 4bZtP__FqD>}}9eGjyi漡 %R L dOW6[!5ˑ=/fq n7}Vܚ=ȗlZ͎>4ŵaܳI%mW6:ܪŨwREZZ=E-\a:98lV&RE5KhZ.)ZLW6O2d~>~ "ږ[ )ČZ(C 2RL8/l9jQqWaJؓ$ZuWWdj;W2.,2~G;=!8 #oi0 Yc >:nuoK=lS5i[ffo5d 엖ꬎ"ќ-4zeywښ__<ͷ|8;qвvL:iy%1|g <]µ>e?zθsGړg<}}iLVa&M-c2]]EƖ*<,Oc}TSyb)op̛ ;΅ܱ\8A#z6_rGMPv,+;Yp̊~%S ų7~D\[; rGϘ\ܝ%5myॐ2/Ԛ;,6u K ѷſ7Ŭ(se- 6FX[QrÏXIe^~ >MiJIaL0!.,D"^?+e|?-wi1MKXPb X@egů3 QBq@)A\~XB"̧B0Rn9x&E ])sHm)."T]ů}J%KI.fXiA K-M\Hi45B>1ŗEc4PϜؑl,C[\i|6mEorBψsel٤%W N;04ˣ>T'cG7q cOhԆaOś\%we`Gf acP/8™>XȞS i؇qgD&״te^Kެ`{iN.Ƨ0'|t,3q$v } [ǀvidphY&ϟJUv)2V2(Vy u,=`:N*#v^CBg`5ÁzѫAeT*:BIkq %\H \ e[KZ3ױc Դ.sbj[@뺹I0mxVlX-3SN\K-Y^X"rYIhWH5q|b! h-ZxkD$ƛ4+u/q{ӺfdͧwdB&wC +UPԫo g^x' a7C>-2i1X̫S+pL9-][=;V2dY4v93xd7z 95G{,&l967Gx5;ّbnH& ,D]K\$8qs(q8?moSkτo D'قу 7c,b|Ջgn @1I}"w}HOb/{ k7yq"*1|v]5{Ur<\ߩj}:Ŭ?;AK=48fd /kh9(l)Qj4iiv'xV#U? h-E -yp.;-)BLby bۥF ht>9?Cw i|/ԙJ+"1]A;,ɲ9Xmy36sT6\*$E6_4 zldV*Wr቞["+iFhB pcB MD6{{PZZR ό:Ӣ}_N: aR׽ !WKX9j0ؿʂiCơv C9O>Sa]gݗD~!4.csshZvD&i͏57w1 a좱 &.y! ӈE6ӗMinMV \nAEO[>e'2zY~<?E!; JJ~[)YK2 40򜔤2~) (iRuٜɡw.Ml/ʵy)z]X?9򥌌\>Tż\g{$ݳ__qǤĖ}UdžEp9{"K6cc#X~ӱk}t뎬M~U F8="N]ɅW)xE"W,Ph,X[Z/&/2c n; [rCvaaNv'w5\?ӛ1Qp GZtghJՏoˌ'նMDI؄T3/B6ҰA͊ZC-ҳMUƌzh RGj)KJs;]Eђ2E?$ʱXn 9IrW"U*ՄO0p\y!s)VrƜ&:mpTD&op&$_{).S28sC# ̤$71B(\` {e6;erga𢱄k*4ji+y5Yzq#󲀧l)gfNAO` );a_0P)2ck2s$_?(t\P%xd%gc^JǕ߭io%Uڡm@ "'0ܑc흈:ٵe,;FRoP6b[}C|*CjVXh>l-X q6qFc|W򪽈T=b70!e3ѓ,+'",$'KѪv$-x[:ŝA֨+f+s~>4'Yab:ۦ`(|.(fv)n@*Tؤr)ߙqJ&ۜ>l4Q,gȚ[vG][2T>zlE:'PO8֓RNh^Ov`w Vo)C5#;|10,tǭf0 t)tIE3w;Nı}&>ǭ <'U42S$ô|5(ʮM ey<>a-&?O.ZhzU85k:8"7ȅ>sv$0zr7aXM`xN<} ai4z[f-zvՓUYQM,S:93E4PL|%SwcW-CM5, z^ #h]5/Qc$E8^ K8;&M"c8žӱOD'c|1$fXgF)lRf`i + ~ [DFK݁~%T.ttk6hEs(}բ+UfN-2h}SMGk*Y2ʧ8KKDEtvea,w SE(#x$ۄ3qt|D%(:q"stP<w1Igѹ4Ħma5XJqMIR.;6* ƧSs"3mv7F:-Vyrq6(O;ϏBi:ڌohahB!$HhRBܴBTÕ/]rtNt\ɽU]E*A*.D,m1D`voMyMp/\ym>hs7O+cHhdd\iٝ,lGób+9oV}Rvgx.39oϡefn&+Zt78t )>\Wݙ$GΔ|KLRfh8P3ܕ}=x⚷)bCe*j)aA#th`q6W %帞/h!K3 a&}Kb= RgdFع1;y8[QG[!Kg'Ap%nʱGmP)C|e4yd_3 TLVP3߭1hD,sbg{4!8Mz(vp@,QDr dkwvG,"?lC ]tyى8gxfsC6./3hDAD+mQ`;V43a%+lF_ `ϧ64+zl\ vIt .beJ)&{^t.:zVbQMi_ŇU)?MӤ;chy:=*蛩 _I@9xCABVE k[qHFxHsVM8(5߱ A3rM,3-4eMkk\i*JJC j@YAġ*n ̠֔inC+ٿ_+RMD^w54Ą<"dE Xd^IdG{ZǞ-Ԧ͋z3ʞ?Adb骦BGutS_XF 1'.qbO4Y aF.:Ҝg/i1=&d='Y{ vDP2reM&I';;'ѣhf?!}O_1A̓(CH%]58Sr6^Aϣ*jWSS=tR2jҺ0;]r~\Ҳ` o6Ōؒ|Rx=2>޸5`[ua] TSGct߄Fe){'SJ[DSZTmx;m #<g/UPeJș0 .SI)jzgtrtw*:{o d^<C/ qxhw1v es0^IqB9;6I4l2c0^r.u.y)͕dgG0gpf])tLDKjgW~ϛV<|RL+rTNq.3EǮfۃ*W'XwKݻ5(*C)ݪ<3|&ǸwJR[Gn5϶c8>|It&,1f1KEمj:,.k5TqgzWQѹZ3ECIJcIW7uGr?";`)ͬ9f]#XvG]v-q*3yJfP LF;!k9F8g{`~2Q5EL8*ѳmT#0TASJz+y/aXOjz_zW.pZ %\*|b5 I<1ftX+Z4aEVN15/oL ˿J i5 TlM`wxq:iC^Ԙ{aWjOa^Ϟœiʉv%L Sa ck=ϯ;.Aτ >k. ͓ͅBǂǯ'B#I3Y3t۬4dWVOE9W*9q?|Iӣ_3ϝIbGb *!n?50g9 WEAw_uܱԞe*~Ǎ?Jn` ?x&E\_NNrS'堆t.?f ;V@k=-X|ՌT3,hٽ3Bi F?\Wfk⊄"1Wkɖv}UcH֮.$8O[~/0Go r-<7PIr S0#S(9 D.wRcIEUg*1hPw|O Ia$.mfl3.)2~ ta҉!mfLT"zD)& ~Q̋(I`4WJ`Ȗ xWs\I93ͬ*Wk}. Kn|н[O.&rbOF`Ad?'OePr*Z%Atn7!>$pp >! w>Wpp /{{Bx e{oעm=C\Hº$$;444$!n;{u9?jjwjTu*n-~ĵT~ZgAAI1gm%}'Lۏ)oR N{o8 H< k7A=++ԌCcx82cn@6Řk9 +9xGoJNWLdf>58ܫdi jy6))H-;DHUnjzoOf b'qѪ5919)Ԗ]iQzvKjVhVg}-4 Ab'_?K&HoXLss73clFaԇxp?/Lv!F<GxT7|LN"v%Ŗbג̚8CxOu2Q{1UHCU$?W`Z8r`~>?J}"OH%u6 \95th:er>/ 1#Q/8}|gf^0ȁ3ެˊ 8}TQ@:7 @|c5zf'&J|*yS J!/?kxxMIh{2VAk_ ך'L &{/u1li/$xop8,ѽ0ftx1`LRRg"2HIlUbij1A Phu'y0RڊgGŊ?Ϟ zwvdǷ%+IȉP<15b[UV1FGJ oWb6gkf0S|SGGFSWś"DP֛9A@k_#ڋ˹Tl[UiKy=[=:\5>RAX?v$v7hڝN^4B3O7w ޻8ߌn@ *|6Iw;O1Kfqsb(Xa j~ZL7oq}k>>gK* 70ЏՕ0"I-dQKs1I,pk8UIJ(B;,Ax&W.-f b:a]vL-ZTOE%ovn+l1i/crqy閣i{<.ԟ3wٳ@×hgmcօD_`&8!c7G[.>@,5s-LRʙQݬR:K$z|7aL$өK h`Z,'I Oe? ~bQ Fm~k g]ŋsJ7n:gŎmKJ'eҲ{]ӹi6d;,rcDQSe42W0]KUz^jZ,VQpV uvF^vJ67g>dnݮ 8}|DУep~h# EI G zi*2Y&݋h ˰(|<*{`&cIaѝb ?G2({84CLϖ LYBr c/ѶeLvsc6x2@S/_=gT\Q-V1\SPN,vź^PoU5T"wns ڇr.aQH1 Yέ[2VKEestj1Ru{ VPZa쑘 V( VbauW.%jOBoFO:KKr Ov+>_l9\?'N5/q+'= Iev,5ެ2ފaצeDh'_%A '/)d"L| ]n<,̾2G#9n.f,Kx~H=Ot^HLV8U{:|Vp:ɨUr/DIv~ 搡R lՕ6W1nR w=EmlCO A8ɍW;HhJ3$xK FL,vl75EYD~tPH/)(^~yĻGDKm<!D&&pB$ؾ0QLb0|rЋVy3i2{16SNXÕ}zѣ9& z6fll柿gn웅K*W&:-j6TTI%"vi孆~Rɩ*Z&нW`JVf{Nlы\3s"đ{K=`Ov&hڎ͂M՟tBz?phU'H8СT|JdL6}vbmWaY61JRrQC'_ QՄ4Q1ٹ\iגx3zߝtx37VAE!k1&NB2C|؞+l]OwFˡ<~(ͧDBMb<"P8I9Aw~ @j#n1'r#ⶌAʛnnvp;f1.&.>'y Ky@5<2` re֕3FPYN1^=*'Mg4(w0VB<%ʊHLDUFQ!$ =:dRxBgFMJ [Ixm)vv qg Qo/GyZ-XqX4#9K"#WU]1}9-=DH,cpLބbP/JP2\F^An`BFiD4=c6i=̓[|ys]5ҋz>AZy'O\s >88cx N x./xK& +?8«n^XhQ/MFv9іc v5Z>xv'!?[sZaE©:;'f"?et:M$rS0s]"8Yے$ixDmwftH -_gQ5-iMKni2|dl) 7Hh@LWŮ][ⵚj5eZj|vh7'b%YT|'sZ {Sx4ֆi8+By).b =4'J!f\˚ÒɐP,bjljDBzn_iYϫbJ}ױ0QgEBɡbΪR`~6?){/Gf2`J vyumtc^:w皟p O0?׋Y~@jr-Y%%6c%|/%@GTUcK=|9Vř u5-Ao™hO;5`b0㋫5LY ]2'Rz6ÈdǵKchAWn 3u‹{]s Oﶭij] ȯͥ\/>nw_!W&1'zf<.{])m*7DN()#մr,.-@bSz}wBW?B˪^|nNˎ:S@jIaLV%Eǀh]N`qI]N& UB: KS_9!!%>`VdEZgK7͕؊lvF.t;ānIǧD# ye0[c< ĭE1TwqfT%7Vbk^ŰՌ7EqռWsLoU1J75kY'8aYuY !9d8*65driv$I܁Nܼ!*>tpF[ut1}u;OZ®!1k,R_q}F Ɨ4S ^RS"I`TJv+:IAݖ2jLھBQ^zE!d}݀MFĸ[c1Z 餯[p9G0y0m1l\ĵ˜ ՑD`78ص9AoFi867HbtHXAγdqvx-q1"Y{HH%eB.*+^[͹Z^6~tL S?k68B˴:[kha|d%u8 EvWLS)6v'M0Ό~#6rbp3&hѮLK lܙ1Ӌ}Ou w+2si(oUp1`K :|t n)kƢg c Va6. 89{0cnM\E@>ͯ.:+2)TgG\\r}x۔U惒[K ~)]I'VfA+IZjmS䭂}LTxp2Ր!D *<-sM'ޕpt9 N۳-Sf*U#VEKT:ŧq;_Ut"zUfn=*qmRzpWs룜# 0k%s9dMğg.n:X8eAgܭIZ1=$tC:p)aKզ®M8K(bYm+8y2v)s+9e 2wg={mJ8?Ne 4ɱ~ \"r oe̗p"z^(w1:֑&sܔǓD6~4Gɮ3|ʏ1b/_,B1:Q~=]ƚb-G4#9n:Pr#IZU2i${[G~tqI*/Lյ\)J9.j{gOx1-k$Ogs!Q (3SR&;Yə&*JdX夢DͷL5D.x@pWxQݡe&BMt5kc_UUA x~*`]j~8k#Y1OԿ&!z?"Ұ{*9͡{DQϽJ]ѕl/[1*֋a!Z*+K>>ݙgChbo <2񔡌ўӮ BdrBQt0wyTpQ|Ћg|XKbVe,$˫PڴaNpn7l"in.-,Yu]dΞϷ,ik*=V\tލ-<]/k? _Ę.f&9yȁ2gscc^lX8RXlhz~ReLޮLBDTN8cυe\P+htVI` 3ѢeH~H1FÖ%!6_˛ a)QaXc0D!mGXN7IWi*e3TG)M ڶ&Rʿ>*CUo? ]U{|93fK|.lP3rB8Z5VhT䡊OW43Ni =ǣ "彎i:D_+~B bSżU '*ި[UZ.m^fKqrs?$| t(NJ ^)qѭ_ NrDr dyj[ʑG3Gٓ7ѤzPqsaU?q/3y'Lŭ+H‘zs9F|R|O2*2Jŝ󰋋@6.?9>NI\V{j)3L:bJ39]0ҋCgMDL6M"xƳAX3| 71 gV 璘v7>948*|~Kx`Q„v.$wKimXƤ=7MfT:S!o5YiX NE\_BE$e]E|x`wpqQϒ"O <83|ۗΆ.y0ͬ`]M䜻u9,,U>&FɽYLKI62xM" 鹡b f,J~&9Wr$XϬz*utMвu%5(5z=LSQ-йz>=ۗpܬЏs0;","CcǐqI,JEкń)+Né8ZQTL"d$';gmͿh4yMOU f ,3+CbŒL&8e_qo O-ȢaiCi"m|Z. ډڝH!iȽGn6ƿ<\@s??C[KPdT3XCmTE8>c^t4XB? P}q!1ZL1MӕQ|ZHT^56_1 PH"% ؗһv>^SzEb6֩*1UʸKU\LlU,Ce*"ESFoIr'g%0:'EIl&%0 _b*|ByeRK.er<|e\W)X\IP]*&J%/V𱋜-JZXț.ߕ~i-dD ϽȜD4{NlKfTॉbRIOJxCK[;x9ٙxMVʍO 4~q&4nw`<6"dyk~G577`GZ;[ٌGt3(QigZ=eO){$x\rQ0Y> Ř4(H2*G;(fo54&cX%j%[*KobG@ 38= ,&189Yҧ•d'Y),Jj&^9{2y.J"D gyנ R~f8be1tٜΙR/&Y&OetdG,[az8GћZz}0IGEkx$J%i9CA =l':p@ؑVLWSk*gd]RJ9ٳUV񣇒` Yj6e[d]Kz6O_.s Au?"}"c+XI|w^{<~,zE|XzPy`HM%F嘝3'BZ^:[+zcreGTGO7-5F]Oq\6A$7>Σqva[O aq-M,l4I\ %+w?oԔz^f0xDŽ1 7;hUߊS\4p*Dxe0&7'}}TfZDe4 ~ W Nzn~0&lĜX>NtL2s:;2(,z&$MA?NHh3Kzq D3Eg~̉vl42a)8E̷*DY-\/颖} ?n2qizuCjFۊ]**^i;guq$^*7&qvdFJX6!${ {s%` B4L%&{R7MoaI G:PߕBq }r,- j;JFn?[+po>piLlMmeWfm?/|d2IKHkCSߩd)D??̱ m "+a,S+6xL&ג[S|1=4kW de1;k3Mxby#QW%0\3km:3t ܶaf;lw{"kzPϏSpM'IͥcP=q>ʀ<݌ٺxq*ǧƳN'kǰS6rt~n%3^6phsE,i,j&)ꢠq9?2 3SK-fL{O󛧄aSBqXWteQtH,Ȣ<ܮQ; 1TLڭb79O7i,jMrz-ch(r2^s޼B x;TbDJ͛eZ·eSRVJ]ʕLq|v_`l= vN1_J]™$՗r)RJ)bNY/t'p>j1;&.q(fІN|>&=Ȑ֕2$B{e0QSgr--/h妆5"4]Wz C?I.tli7gp^;C%kM?`^1ÿ5m E?צ>5b?lqaUgE*95Ǔ40F,JƯ>mxrc''#ʛ Exަż*qU"#f8)p S̓&RfQF{.1ݰglWۏUV}*1m9kp[)rv6ibWb<Q \ܱ1϶CCS9O!"v/o)et圊YJvWn ۹,hYA-q/%TZKiw>{#Fr:x{ʐ^ӱv~E ( GKl~,`h7&au؂)5lkCf0ٳٗc) \r:SzZV2PC2J -i/,L8Z>bOȩt~jͰNsfp{Lذ%XR4~ # $pW.>J^|?{ˠ8vm7FB H!8g ݅xv[w/g=SMwuTwlsCS_Kf+7zw9߲>qb];s8&Nէ$x8sa.o-(:rhF<{a0' >Ó1 *yR.^+?(p%me>bL%;y׆.WBRxDe5InnPRNNRR:*LT¤%NMڜʡ-!oEvêG7.k MR(` ,VP'SGrQqVV2Y F%f$,k^F+IW[9RJlk ݶJD|>B" ;i+Jiٱ|s2T>1[e 2iW |O[<< }K،x\rś7=93ͅuh3'64]CO*XhH mR$yL\J +Ls;MK Qg MkXw2{8򵀝p2%s5i3rnX,Cc0njƔԣr_o,-"=^k\(5}Iٔ3=ݖi|`fhuU%̽ċ df<z`m6˭9[z(@wy ;cP3UBOe1gdp7;s6, iv:r^5zd]/5 H2|<]Es\FUx/&S)y&xhϵОs2ll ԣ$0~C>ьhɂS zQB kGdUr 5y*^S٤JdZ CqN)릕4Ō~1vO E&8SoS**9At)q4Z&fU,G v˱6)gAB*6S9=^5qbcԯ©s5~G/;i#]i&xm}Έ:.td:)/y)z)Lfy6 dJuƱyf! 7Msd3FC oԭgo'Əu{̫)8^#vKk8og,cBB{؈kIz]Oc9H+ry)cݒQd݉4wCۺnvcci_tQN>P &q))IM7 ˻ hɦ_qL.r*x)Q|V*9䈻2V<ϩƗ+|n~/Wy(U~>2R&8NW9-QTU-er4v ߪQV(8$Tcʔ 8M`s`ǩ>_,,`/qMsL-9>՝IJ[#kyQ(MaaZLfGdꫨYPov20V!?j]VaDNJ 9ՙh5–Vc,P[yMxdj#+0:%\ިŜj~z]Yt\ATgb&8ѫ)f8GQ1Y{L8.HzV GsښWw"K7|AHkZHr)r \ɴqEZFvU(㨱 n\􇳥8+sh_$3BCVll$"z ֌LS䊒lՈ7x֚_|ؗLqn6*%}>Z%f|8?ܓqXtGg/+:rS0sch9 KժȰGμoQv-^ᯅ Z.҅:lKVmw ăύ LxYg("x)r6D+hrFIyr~u{ DuWXؗj4x.Ws~O TOƭRϫPWT+r*vDN)CW_o|Wz_A ̙ՑBI#r6;8׌k?N_iGĖ.3玪؅k}͍G9v:w(Zvwq;OqgUv8@]OB-M`}NGەtV>̛WזZ{2͑ cH!\T$$4bni:kp|H'ဢ/{57Y,MeG ~RqO)%ysTXZWʬR~I=@IQ@N!}O@L*'"ttC}j/c9j'{&f1JL-c2XzËv)wfE#W7t4EcM?{rIMI %~%Â/_[w ]^wVl+µ)θ'quZm`oEjZ5ע窦c|բSRVN )a5N!ew6d15>\v˥dk!I[Pml9-HX$fiE|Ϋ͑Dl 0% K܎g|1O%/?9aWϐ{@g rxL4k a=U^r |M .862Q]Lg`0.%jLwE`]4=TCIhynmqqW^S*2p#g''J1>| n9GfdpzuhgįPSü7i_N υ#4Q0͇ܓ@ C5wihP`w Utlr֌+AǦa{$g+&"uH=2|NTӨ$9W񘫝dPKeN߭$[r)+P{ޅn=]-GsCo!b.l5ym-}_oҥ&bU^a|ߙ y+H${d=(\krzI"埦<[Feh9'T1~rYiUFrU択_J?3z2yg'P>ogNJJi_ɈcUL_\NɛΕ8 cZF%jmRʟLTղ~}ۖ\lJ OoB=Dg3=%<]Ƥ <n4RVCm \|Q{+8ɾ2SHU^+ə.qHDFRZ穄t#mE_v[qU=!M30e*-em"dŜnʋaxY:}?W_LSI$f{3hv nLaC527Zuz0& st^\A5#\n! ܩ#90ZM]ìY\Sn#*z]µ TXX$Eg3J'Kй$-t^>l*"Qi ցRO6֦QW\'1&jr<'Ǒ|ƭˑl`cFȰ%áqRnR 1I+ʉ_nZf쬤uJ7{?4kTN2TcP[A$ *CsUrSɖ =En+a_r+pUOxR74XVس0Hјxُ\乵 u#%#|Y歾JjHQoaN.״ͯj9h[M'1없e$O(e8Ax9gYϡ\hGp1#]<U+XSn$AA;oPr»uݓޜ3PA8[6I8q4_Q\!cK"3/Is w/l]xZ9a9R*Oo[(=ݸ3Ț˃ ˶7\Byԯp-qh_qfX^[qPø$Fqw,=_ΟW񽧏D%SBEDEی~idYA&h;?k 4yDuOt=uozO,{ѧ@ƝfJƵT1t(iJj4ۢbeo'*@N9+8h'̨K=+XRҼ{X\*#8PF>xVƖJDH*QTMJNyu#Ht2غ'уp/6glgJ(&2}5S(91A^ż6Sy_y%|<@Wemk5oƍbvc)N87b6NE~͕.,(gq:}KF˺3}!Zؑ AzI Ci0gxr˒qc9}ʘA9݆$-r`T::v J8֨Z'8 Hܒ4ROɼ6O7Eԁ{-qԹWo޺[S?;f&z+W9KIn %<|':ƴ8v"1x39>-7<{ҁ=8ۚS1'BvL:N4t7Ϡ@UntaV;1+'<M& +h$zRk\, ϕ BVE .xDƨY }S`dPb 9Mͫ=\TL#e8 cR"gTW*Kً0tM^*ckBJTt,U3֓i{Oٷ]oL`H`O-R5HK_*wiXEs\=÷`ttG}#^Ҿ=gG'.6l86ך4yُ:̚d]h/B;p) BYL< գMJ9G}l9IǕ^oKpbUMK9 \ aā DH;pO(9LXExdy[DŽD$`:黢cw /.wM T%m#vecַ K  -C][:b,1ʲg+_= g_/9Cb=/`i)OY_w)O"3X>ds`{ϻVpXC#'k6UCaSOfk'>ܘCT,M}ifr fZ}P栗_JJc$ c3EbZC]ԬŠj/c5TSw>,aOKD5<fV ɸMgs585 sL9/MEr=P|[W\ֵ3sMۗ#0WH*w6fyp…--Yi8iu,ի[eǥŞȚ8R.%N77l9kȻ'YҏOc٠-!&.|_@4G1bj>fFk0+#q."}+gCyr|KĽk8s'.tfճ[aWvuL(kߕfBpF+"TPVrq]˘%~%BEMDeœ4Jf0/ $p^6>'+tWF Z1KTsAɯJULSYh'$6pǪi\P*9ZN2P9% lմ`7w{5b}6;dmnY&8*eWA We JErՈuy+*Nc_) ,仧W*oU1j_vi$![1 \Λ3S"3Xܒ\=Ж7 /75`h@!n f4lCW v=.n<_7s,?NpjF:q=8#+cEp&w(rڗ`M9MP]FIm.u41c}d},{ȃE.c*9-'*x,/'rQ8 䖁ozvxWs%&sPծ27My'AU|VDJ A?2847 eW/.P#vVþj.3`%-7 {fH'@C%f IS#H-Q^uL䛘&vV;cYo9|iIIČ|o̊\0МDB;ޟ!.%{lz'fu1nzqcjSv&z9ٓt¯S87 ӳimM`:qҊ;RWl`$f4âsG[Bpۿ?Xʪ?lOAoHDL6syovN!r}i}pg@7A|eşSG9c-q% 8t;R˙cw]5#&po$ EQM~pOGV{H ۺSZj/kbe+9ZআsC"kRW%=+K |^53j1T B1%Yۏ#8#!1CFDym+(L" 0qm8:u}8ẋa˛BP5{huY涫5!#ٳ+ q";˜{FU(,(О6ᵊ5x1.kSF N!vjjB;17y=7MDpp4JRzôx&i9l5Jt؟O/9֕FK 4eBw)*JVd/Rlt_Jx*}XKO}XBbV!笝-ʙͬ xŇYϖ6'cy+jmbص ?v=q7}.Gs)=GBi!LF(Gs>V>t&0O)IyNFsA3[NڰمpE({#DV zp QoLā*?k#c >fK0x2CaCJqF.\as7erS4.lxc#ƪNc}35|Ν=JCVgCz,:K#f ;:X_IQJZ媐tbVd#G؟Q'}j&!"Gv_i#Vƾj.P> fZS{yoLh4D4'#rx6 #=)ud8ϭBwKͪit a~dvcES;0|mw3P3jHAŅruQpdǩq|iKnG!rF"㨃-2̉K81k=s}iϣCFtlK#oӃuh9>"6 YA5k.;jsMO{ڋYZ}\F=+Nw⇟Cq?DϵLqF4Vف ug1WCc6Z/w"<%>[[*JY ӶުJ6Ε1ukh 9gAܚl;x*{'"WVC_Q9N4O S{͋+2[UFQ_#1:7 ѿWBa1ۗ`;{ThHg5boy>UdS-<91K䍆*i l\ʂ8>Ӭ_0۱K ^Ej7՛3C#W 𣥁iQ0S¢#XKV{{ҟG-Yg>lv z!2GETkC5a9YAxrpplە*ϗٴ 5ݳ, לݫ8I? 6φ1D慙?L_ZyPÕ(=@x5Ŏ9El^B/*_7BR-MNu!|{F VEʩ7DΑ*|-ޠ4ϙaږ*(nJd>Z&J1:*ea|84֙]h\eGkW HdC1a\Bu!˹W)e'Ĝᮥ>6zj&VjRr@s.>u3($LQt2tb'X;H7̋`2'X ЁDmϑfD9ȇ֩~L/BϛF< es?LW;SDŽAӎ a UY8aJ7aNaya؉0aV^0md,Nb^71|vjg~6%BEl2a{{"@@3'uJog2%ǝlYrGZL}o2?}~k>Is+)kSʍrXf0uf5bz?0nUT`5LGg79U]bݮ{% TXU3prR;W106NdzO](ոK1Q̞S:TN RnꚖmj eԜ[#-hPF݇3G2LDДXSGSi̝#Pxq#Xǟ9_h d7V}]:5)=Qk.s#w<ӓ gzHM%7  vì0뱃h/>ҚMo>/OkWh"~&zǡd+Iõ>B`íYbtތ͑hF_>\]GoI) wכh:F Zxx͹jٌhMY,%xhf^$n',}Rg~e>ZʇiYPɕoUh"IxN`@|&څK\X0 4"^|e)?m.n BMT޻q[c}cܘ!2&t qbkƃKbAvpΏfUƇ)ڙ9rg F{dw& SYRcY8̛HtKN\vY[p1ڑ]M9,Ťa%+湥3Z"*$*x߮'N}Y<܆bxޟ1m C#ʉUX f?F󱂸LjAbDwQE%;ҝGu9Q{'9r[Pʪr+27Юo%*9f0螜2Y09OQÛL߅iWAEwO{ш19KymjC[[!3`K^q7~rVE3.H~`? +6+AeEL=4}ҕqMzў^ndrfGۻ07ăE|>Ŋь|%fV>X m(zgT넏; 23?OCX؉ 0,EᶺrJpCNorDYN`q Y3x`%ܩ)ZRdJt8, ǣyM[? =Bf^KhլS-%UACR lS1;XMF~Rs鮚+KX>59}fk79aQڦnY/f:Z}6}|?ϚςSs!EP]ub7E{3 Ad')v,[`ə}5m&{ӡQ}VZtdh'_3|qC A3''t$w=}ZBCjTq@I2қ' Yr=Ay˔ YudXk PșT͔I%o^KyM0:OdZTp7bnw/?f݋ĢE zG1Qh+FFmC-Ԑ/Ax]hi[# CA6}9Ɖ MCS߂FщA sBuSW.Zy__z7:o@׎yP/?|]h< J|ww! qo=@ N\=qwwwwww{US}g_Uu:kPD a|:κ՚MbNK/s&C[ʝcf5iz2oZ1=PAoC8ޓxǫYn63*YGɵ:ZM˔:I%7LP$L] }h,sd{}$ѯI0ft&?gS7 5 C&I5{)]kɈapy2׊7pӕž,Fqx([m<{_-7oFmˆ#r E3b.'XZwyomZ1%y!⚽܃ 'rh)wO>)uх&~8fdN >qz]YfoT#z8cJo6=ՕDzcw:K+\i6-JR:(klu6G]#\=:Ϋ+8x SEM%6 ٟTD'žj$p,bIV+HexS? "'+1xfE4֙ە"l79o~՜ʭ߬ӯ5ؿ!Z~2*ռpfmiS~֒㕻2/b۟3|NZ *ޠ-Q G{˒=/Bq^\_+Mj+]C4xꎸ^/l]WcRlP|X9-ۚeיu Z4Sl{-x[%QKPd4ƶPW[397:39S+hlSd1̔r\m–Hh-7;u߹IdLۿ*WnJ W6dEUA9}}r9'\a{$hZKg\H2LZW=ڵ4Uɀj:-a_h5^u.ðOeGSG D]u}uiʛrņ-81ۄ, hZH3ZL3Y}X"Ɍz|Ӗw]7ÅaAIaBcب*+E}2K$ qSW:y Mf/YX˕uqN+Wunke*ɚUɫzȭwh Gm՞\.؜u-ɫx֓?pg[^mrY1?@;?N^O~Sh"-+{\h&lil; 8 M_"y/{{x+aI}c@OƤ0{ܣ}Aݜ~ЖFإ8&%9UqzvG1G絪|%cfLtNGѫ"n3ns3;{ӝf'\|\V/PM1f1 &%Vw53b/T>>7&U /E|߇Hp[,58;+t6VD2/Пo9>@wiC)U 'hfGPn$ÐѩIiE4Zƽ)ćdǫEt\̮xB!R^0Fpi[SEvOQ}$ &k_LF >1?5d.z(/S6ͣ_]"lɧ^Lƙm ȡnNrvC\D GvqgRSʇf!;9 ѥVfQAx^08Ćc<ϚYmP!mV4O>q(G"8)Y#BXJ(J$[/3o3U/~,Ίv4]6ٞfxkMx-hC'-^JG&$2xV RU:5U-Og&+5m6豬gqIMŋ n<2+8g[KD,1E/sd:ݲ]`ۙP&Y>&E\(!x!Cv$Iv䩹ooCy[]ă[uaEd@ æ'r\/BvK#|•/~\8Fw`0"CIP&RgEOyrGJM6Ҹ=o>/Gy/Eۤ?t mz+`F‘΁ʘ h&ϧz1?f;n#jK8ԍY0#Os~wSAR/1A)}1&fT+9rH r/&a)TX1\妬~% g1ˊs3Yޝ|_SR$ٸ%%!H'S_%y}˟};ɡCΤelkU3^2óʌ& ٳW{r/ δ`l fEۮt=q3wo LyR'S kenrcc񹶮CHM Rçr&*{,K,ɝ.d3ySMnT~tcX/0cE#)ify=A(WOJ̔ԇvTL?+\%hu4w$ iHMU&l0#~לtmk)m= T;|'p%M%LL9X~m.X&$t ڝl$.,#^AV{U6otQVzApߦSG-+9]2taepYz- jjKE6'tX+zhmmM}̮lAxvmW^?w/ɷ.]ҒKU* &(JZnR(v*=( g{l67xhm;gI?\fM<`|{9:G?o(?Dn@dGtG~Y5X2嵔V*P7{u\oyg-6SZ]-j]R;7|DŻط k)T Pd^=`¿nO*rhi'.                                                                                                                          5pbZi"mC!]n_[l .RǤm钼k޵R~l:G:J\Y'{6%oRzLyH﮲7T6#T{%: q&[?Hﭼ\ΟLGy4fޢ9#y;k K?Jzax[=+f6%}}7RWɚHFeۋ*l䃡{K)޴9k>]_i>T/H3C)j媦{SnoEyM9N.?0C^xYTӖ7? GZ;G׎hTt~!)ˈptNX5?Z"Yw/L^Ӈ~b_bWlJ%:Saks ^zSohԅ XIFȟ%O, Q G7%'k}ґ>rܑ 쏓hrφ{lhZfoWmWMmʮFud]:+ $Z5r:[ʧsm7޶pV+=?t˫V?\go˓;яMCi4Ŕ/G1z[y3'~ڍ]\P 2@_eCC(jwX03׻4wD#0i"FM eœN,ykG@YA4_Q7p%;pm5i!Ta~lA'#2Kh`xGg獡,8`a0 #{_w͖>޾h:.8*Z4ȭ p)q>R%sSv$%suXЕZ>| `޹xm̷ulONvfo&W"XVǘ~Qww!M36XΑvD}6i*LvgD@,r)o؛lіqiٗc+۠NfO[', 6FЩ,s?/#SP8&pЏ1|ZvO7v^+ؠAG~ qwprhi͸ :Yk+cu1:gBw}^~L}@lO8aߴm(bDhW4YB?֛ id)6Sv4G)١1S#T˹p2XCN\IvT Cr>g]+{`k6:9QRw LrՒRDUH;i]2e _dI-' ? U zb~8+ځ,ɒqg^r rU{ _t»΋^cK\may\W&>" V!(sB h7C.̭;laC*,Fu*Y·"/eм͈H\;0cfkTQ=ӛؓ-j--lQ -6U;k]JH6F0BnR.n\he94Uw`r{2<&7Fh? w'z)?-Dfwa皻ᬥ`.u&Prah sxS?0ߗ-h^>h5!W>Lf_ÑE35ǝ&6LRSry_,Wȉk.< wZZW]0E~m~ hf%C(dyg>N#yR6{7451 P B#P;}.lRBvbB֌"(}_lkȉeՓ|؋LJ\]Y6÷Mb8G˖cT+ pftƷϡ̊_ݨ?ZR2\u[6-#o^B\Ef+8307GI&dl*.qŎl!4e/ IYHBhp2qBx\ϋ~tg "cQ9K! ˯?#Ռ-\9q6*_4̞&s+V8/fYZ5D1"Cv=O/O>n⺡2 &-gnBs;ƃSʏ0X;ƁYFDxr*n;OQu"P ZYӑFdOC|ZP9rg)|dc÷S w"}p:k>Fpi'vc b3U|hK#M&j6 +NiT:*qu/GCit,,NʣdMŌGnI4nf/LeD{~;{3^A'li]r3s$Rǟ6|:1-'HU X!1gZbl}?/el޾Ru(i\CeNI@vw_9k:oի ҷ;2-5YTѫ *̪&gWo645$gH/Xg'4S*H;ihDM1`b+=G%0MeRvs6*´' f0PgOlK<=Hozv2'j`,yZ,A|X͘E۶_OpfPA$âcv!.9C3ga},ݧ53Hq~^W0bٟ4k4}FswZ{bP@Nvm#XJ>q*8݈0s?Y>-ڰY~81S5$SwU%[::=ԋ"x"cHUHQq%ˏWM,RP E|_Lb(α#]&۳HzEi`uwqkP'eVg,1~ :Sd/-<$Ñj?#8ZM! <(a2 K ]]$Ý70v>E3QKd@&2nY#+p)'zfgCתQtG%#mdQRعhImS:~sesx5(bn->u*np4ǩ] LBkȯ4e}4e^8;ތkǞ9pᴧ\ɥm6sdus6*9Qr!XMAe0U{̗"b <:SE1zM8͖r%ٰ;zӽKtc`;-9lK-G ]H\ KzS߇0HdoUcP09Śop//5ϡkt7`<*}|ٖ&j~՛Pf%{{tͶI-×yRw3ܴa3N"u0e Da^WeL|V.}K0T#%Cgبh&WB[Lw rz儨ܧk2;*w` 9%lM1Pd7 7*ZW2I)m k[\DϦ?:^tCcV $bZ=BBKC2\_SYpd-z2'+ݓC=ܙí쯩G+e "׾ub)0xi'Aeof plPLVf/:8zt4kTyF%fk `9%2>._E~7\}-Ԍy)T :ۓg3] W "b={gj~1k6&CML ZTtmX:ŋs}2׼yiͲ<"eʯ~4w;hj-d)Cum7nKQ[s}g,ިuI k Kl|_PDbBZ*% ÜjۏEu{KIoOSq˜&9 kPIZ~g P-&h wlBH\P}jxRLfQ-spiZNOf$Pg؄Y~  Sh:tg' xaܑs8yﶍ=࿠^,%q7?PT~LAKBl>_ڬNwV%#&LZбtQη徙LGg1c 39ڰn-*ؽRj3+g߯:=fjO%رdwkr߿ ULK|H%~`*ss ßټ]'EHM~7-Ǯ2śT'I&ssh[:ȼFD(6|v6#WY07صhQaZȯBõι`B~.b",F2;9WIL (2lDL I B+ >=JxU͇ ޭrE9d`L. pj|5{E-RwHJ5}*w ݭi"ẅ́3 <ɈCmXrguI-94{Gju!#_ȃ). 0YelIQ;[>k f*sf)|Z?MN rb1^@D/>qez$Ӧu0?3X8cpҔf>GmeH )0qaEA!3?)smǿS9{9|l]@#mwxyv(+6 j|bYMMCWg7qYhž:,Je G7wpx]8+&Fp7'hJт@7t㘦-#aoy܁f|pnA_y>PaAgI8S/'r-}|J,WRzu4N&=ǯn &.h{x$Gv8&XN%_u\i4tBǦZz3Ηw}ؘЏUw@_e6@KwL8kIF^3*50! lxAFC~Pօgl݅wJ"X?7ɤp՟q+xʽ`8E5>L9ώC桜u͡WdVU&w-.cQqײZ|xT{2YЏ=q?`Òlc)XA:lVSzjQ`6m5ڊ7YǷ0"Ӎޝi^AQ>%oO=P56Z95=^s0aR k394]_15P *30j_b$"՛$2y^-ҫ{≟`;L1?%uvЎҟ:s\~0=x CjߤzYy<cso\c>0N4L*^pTFÇ " 2G,~ɱZhx(wWI5vڐf3_C&z?u^F'w'M;a)aS,y}ޙ^鉡'ty&n`THʁw#ʞq ueO7ׂUuw̝22.c۬qlKDky'Xs-3gv'8Oh c(d3,[`I3m{q%f~0R62%FҊfU4fӅT^m$n/;Q)!"y,OfdjABVS1@2+#=͛#0v} ??'9r-'Xr<߂Wv2};k6;dlrdM}⒞/h +J?"إ*j4T_󈱤mU1TƖZUTg%؏jwWNc5P}Sb:3ŠØ#8-YItB{:R٢|_Tph,o>*Ky/tg lғ*I?f7$s0U+O%}ϕD)z<B+]OW82~'EW!S4?JR-^[_"<ž-8Xb؃9IAL*QǚQ]Iu<Se +ج3śKBy2zRO>y%k$O$r7wcЈQMяɺf\*ŚPށNRd#+-)h}kn#ѺF葮}3,ЎPk+]`egLQL|i$1ژg£Z,;j@%Y2 =]y<X O 'V)gwpW؇ Mj܆ְX^n~*6၁'q~IWQǒq;)< 5$X2:8ے< Qx_vpe|ū r;jR/;[1Ūn & f{%|·dJ;38wFb6ITfhc2$ : W6ԗ䟞hvl91"?DGyѼ=J@y /Ω=y)ݓ[1x0 Ԙ﹀uϲQKώ}^ 9INw?vɨTTRb"(ZsBt:T4Prpl>e;KeG=ŽIL-G#tc q\t AnbN eh^'͠jw #TVih`x Q)YΌ[04"6E*b)eNWঘ-^*3XѝĞu&{x\(Ta] qiJA*lφhtV¶ោZg;[*?Ikaգ+kHwD{ ەޭQlGԥkGaMpn#|σiq.xZS$2бJj~UCZWc7&RViQL\lKfYchp'n(.xsXዪ,~ZC8e zM'7ci@Ru؃ۙ>yA=|0TS#//E^sl էY-NF/<4 3t᳕-+$t'ţA^o~&Nk.END]~1M4Z/&fym2A̮-S<1[pp'80d򡶒ۖ"Z^UB?/NѸL'cAteWTىCE"%3ɸRA qDJનV |}ǒ6Ǔ95&3Vo'?ڑ{0ғ5眞Eqv Kp"˜q _3SoÇ|.wb8׼R/P8pcɽ3ZSx3AtCJ'NmgwGؕMF3x΍{s&0hkVH]G:L B.{JOF6:bz|6Yx9Zn&n$?\3ũY;w(ax2;6M4iqW'zL'Cӗu#p^ƽ`?FD?w= }oV)LNΟvdY>BeԆBFS+%so BCx O\0#"mj|c d'C}~HR,KIp/&rF2 T [E@HiOzLS+iׅ|&]ZxL$e'S¸4w-բ3Om9Lgxb&Qgh&Fc\<,30:0:B(w&XN˝-'t.5 pw&Gȋ+NALmg6gz^0oFcT)dLʺC|7š̮Q ?CE4R;@M!~Gd ]lXM^H2ฅ]J 75G8גu[ƲTKv[\ڇmB"BέU|2qSOB&[$橘E=hEi< 7 \<&C;㣹><]=:1p#cގy7gM T_Ţw(' '_IXVaK/kT6;W/eo0 %q:20)=pY~//*\02o~os$1ܓ6]]d}M{ܸA}%saKǩs.01ȣF62;Yc&fAe$; xs QOH=s58Ln 8sA#qr})]1SƲ?U#8ts Ld`x>DٱϩOYB$y%O:\nCz㹝,F}qjw,ͭTDʣ\6AtC ?)laF#tD}F'>T!8~a"k9LakhIE=P슊%g>LG+YaeogDWc!^iVͅۇ6c]IQG䇩9vډ@ʱtוC-ZP`pr}dB;R+ݾ#/tCޙ+mڻ %&a kaOe[x!zr{/rIwKr+3t'SY풁O. JꝎzhL$5N_8BgoO1aGEgĹʯZk Oy>vfW7QqFBY^b:Zϙu*mAN vrAx6{cXXLJ3#Z#!w>PP=3z{<;DRpMpql{.CD 9͸ӶGz E[kom}q|BdJIk^]"395SjH?gQ<)ʝDs&Կi:]5ӠQo(#~RpI]7Ѳ[x.tqYGs=&".͗3W>|;*Guc4 (b_C6ʤ("6+M|LKdjSRQM")m ub82؃OBWo:.'0 ]cT!e@xΊ_GŅD;*XAx9DNZ|Z2HF~Rv/TvV}[g MJBh LBah>Gg3ؘ9lP!2*\,mS'35# R-/ǙHėF.[BNbL8 luY`Ao2*z=F.6PvVN*Cf?U,Q@̯ 1 7-q.Yq@?e8/iJϮrmbSi6%", {.j;J_$ecǧck?Sr\6*X7Du)ur&PuG!O&Q+UTl)bt4r(TҠ)Jn.Wa]C;/:NrNRQ:5ɓrt9$u|ѳOgb j},8tY;&FY9ԠJ3Y,&lcoL(DFf i,g!4R%$vT[cc{p7M¿śo_e#f$o" ve@6M |i =u_ N*VSEJNSͬ8'BmNĤp̏| >Xp6:ZpY7\輣 :Э$F+¹ r0>c Lk{,-?CD>YYR"kE5:?E97jy+2bިKH+W4q\!ΟΡBH#o40_:}ґf~S{1$^[h9KK1C哽:+P!j"i\PSK&4x2 Et0cW6w҉AL4iŢ~%%SeX?a4RR}m62949,eCd:䑾.F329jIzHZ% DOMtfp+J=й]7TJ5>gY%??oM3p3ZHVž}%({3Q[x73h /-lej%mbaDd"7ܗv2qhtem5kq[<tX_S>[ǹ-Z6*r! R=u'{{y#;":XX(Dv=?Tm+:4Bm΁26IħN$]m=/Gu>aQD"p[cMaXI+m(ec),'F0EjAaa /i^Gl)ϛe E%f/-}Lb#y~͌ fNV3x Y^z7QD}uX~E]__*.SCfEhQOXIy&h<:X]?cx7|&g͙Q8\)2ުnQk$e\HTOM9ٝlgQ3x:'"`XOf48_4:S[6CSNM/+jg ,}ƢꠥIZ9Qz6fl hB3R|wSJRʼ%dǧKb)EݰIW&4 L$|1Ț'2rL}Lܘfg;ψ {Ƴ`VCuĦŋ߶{T+UšJ(]3qR&:~TZ̟o={x#j4Ll?^l ̦0nW z''w2Z5⼿oO,,5gb5B̼c H*XZ|#Ǚ9B&3f|5&./┼zn6L`9W4>Q.67 >yc Gd>cޮj3 %\S??{ҷtmhLdaiLln>9Jx8gOwrVۓ Z'I|>ƪy.>gco:d33Y$֘T4f4$ؙ;i?LP^HƓdsi+Ofx~Jgi<ڞEio)F)7L-8Zr<<a=H =UEXȊ{FF,@n==(¡%.RJؚ]LsX)Y`6s3lL7P˝40䀞d`S n)yb>-_胚";x=c#OtO1#ꚐrMؚz#uj/nmj35uY{'!#8lʱATvMᓯu2vVcwTr~jKlh .usږ %mx"Z/f%0ofO) K-+& tTʯQ3k]B' L,QL? Jw>frxEπK:޾1@ L9dMbnƗR%ދ[*31ן2Մ같 Mt+rP-5(%8xh~4o&jxc$R(CJxl32Y!F|'yPᵾJ$,!*DBZl}<ͨq=2r`lNׄa[fbYm骉cDm"KeTv,awTtۣfcMG˓v-" jʃܬ+0q=Gл✝لG -ްla\M4dF<NFf67a[^ /dZ|>!rugUh-zB(rS_gVz=.*O&rVB ClczSmi, cdW`|HiLDQ3Vٴʟ?N +yT˫?#힍`={o3KZ:,ȑb ;@"y>D8# |mĪϢ{(hI k㪉qL1cW k\/!J1>-yre4_LmChfZhB LgaLoj9z+]­>yt BVV1+\-z'"kϛOiIO){&q?|klIڇx&HhH£yޛ͵aiLd-2)&(-\1nYY)& 8|Nd12hf.g>Z^;GE|f7Kd5רո R*(X; -nZA%딌h+cݞ,gKE'{%:Ӥtb;YʊÙA\ONˍN >&xK2JcoDd%ĴKڤ \[G2I|Id1T.>ʠs{ 'cYȽ:xuU4 O'u2ׇ']#Od?lFxݹƴ,%hA-fiftCDF3Nn`8 w^Y yq85Ӹ{Bs xCqjyS:bW}'&5jh0*8XGI6<-eZ%|Nozt^L~Quͻ^ oͶWzptPt'7 x3,\ae|t9Em5}WI*S˟"<طY rzvl2ꇉ J_q:/9daLb yRJ^̜a=y[bFsAŬ)bP̃\Prĵ[+ag~1Sڕ(+&c:fQ8IǪ:zձ8U \~`uomCfpPAQJ&P)MŢr.Sdj;PK&+h(do lECi<)LGqk&1jUvTBHRɓ)Ƣ҅cA`?,VF;9]KimgT #-ȟqZ.]cyޝF3huKte|oҨs2;zq2َA .;۞uT!jwQ&/5DWsAϚ&^o4N̆b0paF5 6(bMbDu|n7iz)3OO؉7[9F&10%j>WSE Vڪx>*(XɓO*6y+΁C8AÖpY*z)}*9&gr/ YTp[)IZ,('MTٯeg=Lg 2t'gbے Nb)lo}^N-T8d\-.aqKx]}=@i Mk""[+0Je'kGg Ѥ]qYG-Y:CZMd {2N t^cćs9`YHγ|؞Hc4~zP2-təBjWSZh/Mnd$FVJ6\]**9')$#9.yvHtd bf*NRkxoĞf9zf:Ik3YW͇2^-3WBE$Jx*R+IqD^E-u,}o\ "o?@Gb+aR,kl&[Y=[AVkt6Oϐ%:ڈ-杭m:6r㕊tx[r)Y3~U2V8@A/ N?]O\Dua0$P5[`{9)IJ*T!#4騠A9[*jf{UyQF~sO_E9\+H`KG`CnhNCT/wƭqMB&$s8y5{ִomJYg,e"与Q"/ za勂Ỷ #aV~};v|u['c\chFѭ0:FoN@b98җ*Iw>RmF8 ƴ7czNyu }l_U)C5ӑBl/)Y?d )|Gl 492mo9LdhWV4@O̺TL l.гۍ,L^n`nM#-.e@sצ*EO7TB6e&<ȋz.X)B1!SCӓv+ rlz ٵwZBmmȾ=jD6EMڣ(:'ӭDvnP@Gz? OhXT_oh8gI8 [h#%JjW#/:R%^+#vŢOorQŧgdъCe5\.hPp﷖M"'BOz :?KɾT 7먼VϿE'4,qY山OWfF,Q/ Zdwfۅ:S87ogD2m3x&oT .+9EvIpNŅt!=>`7 ==N67__q^DR+!2'krjLp% X.WV/D̕|t27G03wcλFr}+'9s,?mzai",õkqԮuڱ֋C. C=}{=)#x:chkӉʰ٢fw=' f&sK1&1wj-]H FcF:-t,#г(SVZLrrÏ8&ww{N*\('%4IZc0"_ !2i?o0aiµ‡7=벦5=_T/9I-kǺ C2O`(05_C\D(i`[4~ Aα b+ef)o(.c%̞/C!7>B Vձ^"GW*bEgZB+P;xz744ReK g`+1d5Puul>K)|<F?"+M-rn>ˣIfl㆗ifY3?֖1}['.E̴*8LHWs'?|U_>;stŢsK :Q;i"ήq`c{cih<ו``0MzXN/EU.4SUҘۂKaFVWe.Fvd.<_/Fav{1ʍ3{:xv ?dS$&ѫIYų'̮"45hL8EXh3 $/_ 솕q4"zgMe"bNfP ;7_*8ЁZ{/;&(  m/a?k|nH, &葕:_74>t2tٙU08W_rN,T*CRE2(A[KJ*xJ!+r]hX9"ҋec'Άb.(V^_ Ik#fyerBڨ8^DP{W[]5q|mc-DEzr5,ДdH5([8;IԨ0gmQ? S79Ebk,XդyeXϣ%[#Q *dUԯ&77*Kp^k4`XF, *w$X+.,vWFj=j# ٴl-|09؍aۆuSw~] |pL}Q4aK8Ba D#1'Ol2i~o_*"Ǿ)Aj1WZFebFE9#=šViޥU\S/E?^sS^4Xۛ[q³][M7 V{-,Tw/kB{۶cvye+T<~;TC/qo$\ 9n'RB;I'eRV P‹9RsaY%4y^"?Զ7n)IJB=M9 мESQV!Jd9u,7]@4=X3ބ RT^lcy ϚsnΕR#uһJ3G{.'/ GJrs/GIt%#Sфb{X>`]k (|Z' (jŒ"31(iIUD"cj X:sb77S%Oh6`2 BwI\HѻʇOAXbIHn6R5KK谩ٝ8ص-Td?ytzyHhƹC^ {)qlm$w/@E45êO۷^nrDAL[/׵BzH_566$;ma=)Ձ\=@wN`ǘ=\:[85ֽcX,YA~DŽ ^ ƶu~X^7/yjXeN-GBIM~k5 3 :Pߝ^HtOeU$fڧ2E?ËXwEMF[i/O[}znbȆi/gE%XIJ΋,G9|:ؤȹI z̜xeiOO)K%eq9Kb[#eKqwsTSIcz/TisU$32 7Q):kKXpsk D#!] :.M>m3{e2zc1m)[璉|$GǸ$v}Hxb:Gr7TDt$Yk ȥq H`z4=̱iholFv81ձfP6w`)YWjVb o+JNuGJnP$]Y>m<ڛoIL!WE<5>L\gr&]R6,J TC\ߎ ڄ(-2{4p! \ʯ8qݿKYSM  xAq̗(Z"# -KTY4%q&$$}aĂ7qjɫp[FS 6)r}iH3[' c|ߦd2}bImh iKeϼ4^F$w/BK!afRS]˜ =N N #δ9#pLwJ_hCXu0k^!d QMbޥ4(qWWPӾUX}TaF2f@o5Z:]%$$ٴ-kత-sbٮcc<bGA3[J1ų)K2s;s9rHiUH!CVHX11BM$,9^Bv;oaiɤXFc|ԓr[D<)TdMg%:,+悃 Ai`VR򶖱g2|OI1_̺IN$3 u XL$rd"#/%3?o,XIz8Idg[t&X}"ofM"zyRnT1s2f%_pTjпs UK݌5,a6 wZj_G\N %!ۄMK B[݂!F きދ]q! cB3'Tg_Vqau%[Y jNUS۵}|W(GWhm5'B<w*}ݹo9/JfT|=ִ*p!m yyr-f_i) Εku)+ Ȝ-G \M9 (GeḠ  N 67·n=veyj4%RS7d1w{n4AѼr0>{ֆb! Bܖy*%ý)HS2 WK1sODR+~wczoWw8ԓIZ˾~U0nKmքq"> UrVr^K.rV˙ߤR*ѻ%'C9㛔#YR\eާdDƨvEV 3kVXDI0FgF3q,q2XӗpJw @cZ 'Gdz 4X̹a#3] ?ɜ03X;C8үCU-QX#|J5Ύ|Y66a]+| )ۼ+\Ty5X¦kKͱj>j /F3/cۖᕳ0;Q:~͓AKrc'ٳJ˙G^{޴?)D* ڪlSAr>ᤜm ((U}C! XaHUŗlANL6s#9ؐ]eq[f\/&y$ӕvn~cV#g֡iiaV&IRN*ô_)3KYʭKM2fGS#e_MsiC3 Ÿ+|Md0LS#ao'Eg$m‚Č;?HE;,whG$bY`a,'yXeXg$wK&v/h@~xLe;Đ?Ӊtuqo IOy] F'Z5q)v; 9Ķ}lOF<6Wl3Ԁ άas r1KK5_yػ6j& `dҍ 8^,B(2PBJ6ʙU)'CxO̔Pe󧭘ľLwp5tM-I+34WZxN6a3S5#Kd.-Ьsq"KH(-gb?EԋPo`Uɘ6},%zJ B8$a|5 i_lg;C ` lGds,]tس0AF1BsP QNqp΄tgo3v\-G&כmdfu",_g G"7fO8;9__BAd3f M>LcCw\1i KNEjt<#jܩ%m-ki5MN &w 7N1J|\aLzda gJ%LcBX(5;ݣ# 3؜d^Ψ% ۨqqr)*"Ä 7=` u x9#Vboz } !cpAE=n-DdnH't ;rlc{bOU} S`Vr4hYj r2rRUӉU|dq Êr1yG6Hn8}pۀxy11QCV؞rw6oȾk\Yߓ3 rbr]<\+w%w(rN!zН",Kq}1l L\x6ΝBCOQ_ơSgV ZCi`$'">ŀX16~3e:?,u4bh+2doĦ&lp7>)"+ ȡV>nbVׄq5;b穜7p&f֬JǙQpKYVo:.4SsWætģo;սl)=mV,#:l˵~L!iv(7ٿ/Rd3hp 29oU$G&? gD3Fφ.z|_/>9I ܞƃED.cŜm*2 vF")hVFg)vOJֈYk2sYOy9ː2ڗwft$:v@Ԟ5}8j@.{c壷+?g1[n`_LؑŸ̑atY4)F{Y0YcH)TΕ" qk׶cnL jabO/ ?ȃ>s񢛮/IM: ù1!MeDj,k+U؜ `]r \0k o^u&;ul~ΙƩՓ1eOƹ(Y|f g`o;5IhL28.#,8'"t$ ge `5jp\5YPPu5^?1Ϯ'UǢ?5"Շ1ӂ^gѐ=s?f8vW7 "/i|&YN]%eUd5bJ+I: >+ܘwʌ5 4仦!ˮ쮏NؿBOY&z74No]G hI&4҅,PSVw%clNj?./ueJE(yVNk){1b9\(ձRlnQʹ"ڶ*<9|z9&Y=նHpPSX6v6D, $e{憱y\"$b(a}9?)R"X?!w5+gȖ+ 8sJ z7G_ j+|@k@#Tk]'\! ɥDM4Qe]_6d -=M(ODyx?{;G|Љ{F:w|]pcb~@J oQ"7cR7FSZAl6Q2܄U#5>䒓Ymˆ avg67p$i*}N`ap|Eۡ);gp3; %]ٚj"kΫfخJl԰]>k\nQS-zDj9WbLZgCw%1 I\2Ăl{fK>%ҹԛrnW0?j*bkpoYEbڄ#o&GfVtx҈mFfɸj#N%/_`ÉqO8tļ|B3h ff"kƑ0a`1`UdFT9)*  rt*U>@>soU,|ce1t6ɭZ# <uNˬBB`0j۰.˛ dvVFa1lrFӷC s2' 23?U iī7?E2Tn9%Vs%o*`F|{d ',Cv A+qڥ;+zJ Z$?6 &>,Bx fn{/pY$xN>'ft˓I,Յ`o˲)NţN9Xu0,ih ҅E htjpc s΍&?5o`]4S!woT̻h2e~5jмW&ӹ4̞7yh㛪êRͬ 5QmY)IC.\rp%h|YT-N>MsgLD_EwUdU3w5+=VȻXJ\iG qj^ȁ㢖iJ3!y噸vM޴$59ۂ340YmO={6)PBew9#+ј+y+tH' zV?תj3hO1.}{v^?+}}fcĀF]6npȶ9ML(Ҵċ-P̑!h ?ֆ\ anھq$$pg 5EӍԗ4&$]ofsu}Qkˠ χaAF#`=Ɋ[|l}?b#93 }/f"j E"\ ib-m[7Z|8ZFձ\C@-a}~lr+j|&%q=N w~{ xW1VJ]Y5f^EqF~UV;~J./`@W[Y7:dbmt{:4M?2ehֿڿ@tƗ(?Nf0`K {A!ęQ-LВ3'S*rK+^ysdY"փYݓ.-5%K/w zjF>M Y0%<0(ט(hoY2&,+ܱ!לݺ,gE;fй{Ӹc%7t"ɚcK80[2)0lQAb(Y*:-Tn{u7G~ԏwy1?PcdF-{;bw>t Y8:" GUcbX4=JF¾C)@?Oy`=W2,Ëy b(sT6WxmFx6Lȏ4 %pяO"Վq$'p59ؾ.>D16Z@\`e!:duaK;ZeQSP:Z^eG-NQ3k@6b>-aq t걜MsKX\2|~ssdﭠ&XT{[ (X;BWkW2]+QMl8C3֍2gdSMfI]&lOs|[ $|'PcR i^_8ZpsPƘG GEMo%:d܍,,GdP0OjZGm|Q: WI8U2r+)Dsz^|=q%ćb.^p̖| rGǝUrò,xNwD\rEOߍ 8ɬة23M`*㛏;M43RCFJqDGi*X6.n):9}5kX7=hBkt,#&KB0k4^cqcll{N e,Km%}|*ܤ"]&et`1S'Y8͡M'g<)0`aLݐN ;O+n^ܟ4ޕsI/#B83WQO&5ՠpFů*aޗp@s^ݮZpvQ<(0˱(}9{2vJyAAe5L,`Bi\Z?|厷ѭ[MW+`GU30^k aɖ`sm7E_}c>JS s K 6^©}NT7fcC_ᷮCry ! !a, i)lvc(s2zsPBUdb(_+i??ocx/D1GFj֫iC- 54LjZlXLaɈZk8g57~mRCm.fnjJW!)xZAe,X\,1$Su9ű0gt2,褃ז֤#wA]kArCHx3]z g,7ٜwViy)-rFN>u^[ŏjPIi=?e_z<)qR#]C v y o0~b+K`m?qPYRpH+Y.J;0VNєEЬ]0a=LgG.Nƭo#m7aMl^2U<ѐ2 >L/eb;fGBoSC0^!KCͨ4 k/ca~"3CF76]"1T'B"H) ɍ6i4IAz:KH[#Cdv v/ ߁dȆ#Sp#?U:[r3sw%]Vϑzl3]:.Sw=lkYYz\2iO KW$/սWJ\9kkKYrQQC"DrO0^bϗA̝2Ɓw]f1&Y+4`{7Wx6 7~*cա|dZH 1i*RE<XzzC*iTU?*.tBoČa M}2`tɂ1 KN̜Ʈ)hgP"ZsTR݉{#7MNy0x{G2{W[4i+yMН26:esH5TerkK9i)eX9<_F~)mě)]Q$A34ToN εC݈^lwpڕ|Sw Y?O4/ HzGZ=p R# |-VY+sw7x8)ahzX0QƺQϫ/Osg( I57U0+jz>fx[7i>g]ZJo<*A.}e. d&sib(r"I\)CR4-.O&eM%ߊ*yyZU˚yCS,:.d&x*{dbP'xtքoٶO{g>%FA f{$IÄl:Jx.#3 r09 ִG ZHT1Un[I)*fdH5_6W2su:N¾S%}-*dVѤ_R3~C-Ռ+}y͓%X;Zϲ}q$lKe*rZUsĪߋ*4xq]U:$A1:&RצCuW]Y-|HAoy5t >}B5)۝;At}oAkvm6qDמk 2;MeXk1i#lO &f2scM K]LV=\N)1QVFyTxTr ^Q =RȃJi1ٌ|î]F,5!=;y"<׊y8<0Fd,M4Y\_=^Y?ucT 8:gs]$%{07k2]'!/ ,r 2Y*pBNp)B1ZRCd8A*Yϖռ:!z5B\va%RĕpwC1P͊^EtWpjԮjv!p jh\j:ѧm=+}kiV΢Z̯{-^&f"LYTѯ@[# VK7iJ!K,kXgomk7Ykf4-Kgs&Dn˴MxR6Uhb>_J1FlZhUzl mS⎏"/mWƲޥO:}Y }Kgb=G|qTrY CjɯS|y,$&yvjµ cp$g0i~;t*F D~dNv>wd%-ؼm7wʮxy'y^L |KpFӸ8υLvƐSzN =#A"BOteV|=^̄*Vݮ! 1tӬl ?xP*ʹPF[ʏC4Qhi˺q)&PRD,V7HPqR{vvHp|&ᕳbF90EFLC*bTTYFJ2psMJx.-%+N%4# I(e|,/E<*Rɋdgj<~c%^RFkf{f*b,-lx8w&؈HF0R1H$!MLg\%Dl4nm inXӚ*l ,WJ.)#(W`?MŵcZw\1دcQ-Uy:^Z ,kj wMKxQ`p rEZ bf/$)^/LH,a\+^RA߉U6xl5դ}mFUh\#ޤ$!{fj=|a^5nU'tjZTpZ%tJUpr_9~$wPP'M15 w-+pZ'[u=ўrpF'tGښ=Y^|݌&5DۋMtbDєnlSˁ]aKdJ&6W >ӕ[VBv &DrEeә;)}y48*F=. )0(#rW@ŔjtR[wFXAsU;E($f}MIʠ|a z+BQHƻ,qV$~Lw`\YR*gPFc)]< !{!szٱmO ft6q*瑎{u([Cw5)}OnfY;Vtlar| sYY~.eZ3Z6舛TBJWCTr$[R9ZW2{m*L}hROR*Zbے 7sVWAJ߭`X%6YpMKY C'$'iYP2gt9ršv-pYQ]ɎmWHo6;M='+JD9$VuT& 1qcc.S`k1Z CCe#dS!kHСc'#ilN?^D/Nsi\SOHTJ>f<#ږl%xR(Q|vggXJ?3Cj)Jr'5^ dJ0<1|YLt=>?q [/CPOPRJ.٫Xh dc V YTOCQ*6T0+ #Y0aQTG;)qHҨ_A)2'g$1./])مl.%]&wС ^<Vy`|cxhYc2=!uu|㇐{*:sbP`!񮫌; ZCy<K-Rh,Bi-v̙΋ZY6sҾb%^VI ,]u*eG۱8WAJ%U,7b*"U!} r?Z\ vU".dNwe8/}Qao5 #;*r)$?q杋]Ppυܙ#yjLojj!$'o2wbs0ZBtRŹz4EhS" 4æki3z(Ɍ]a4\KVDž74'zX&%C㗩Ʋs]0N{h3͎=Y;LZ3>F{P60e~xX,PzȳHղ޵tEX"먹bebz}@C ǧ)| Eω:ԼH²N:wzЯo626&ѨlnɡSlfu2w7)dȓ3\TDR^*רisD~--/iuDGQ/u:^%tWLQJd:Mel>dpW<[D$ {'1O2I4,4iLKW&?Z! IǎXJG=OʋQ~T=.xx)= IdCz"ɏ*xpo t(玸v]A Z ߿+t}mU (Ed1sWr6~SӞMa0qq^ŝ1ܘΔwA<LG֍om_03.NXO" l$"MS@̥'yhNǘ9C߭3= wHmϟyŐ|= $& kWW!+_0N1C@fx:Y6RuTc|YQ,yY+QЭ*'xca9k]U$('qRZO˖\t&4&q;ky]\q~C~a,9|I&`Sp;c{_ΪIO[euW]x1ϰ0Vh`A<x!D0!9)MS9jՀ؇]1X)֤/慢1 esi4TfKun Of`dR Ȋe@RNQzǑ, -mpt>GVbJSl)3kMsdl>&ꙭ,a -0.&yY1#l@OWpc.kv; xsŕ ,d< r`A.a/os*f1c6Ych+?vaB疠 :MɖY v^W.Wү-uLs(UE+hJC "g } *)2-H9s3%,WK0 f< Nf*b,39# +ֲyW h@IB~8ТeMzE䭕Up0(Tg'!ol^̖ec $D#GƖ8KXK.ŴYW=fuv,-ul|{7"c ѕu65>caɞq4ՙs|iE1 ^ՃtZΤ{eDl+%fq ȘUŮ5^rA9K^71Q:WShx0ǃH7>$dZu#a'a}&7f˔ uƒq(I`VH^[JV]ӡ#=p)x@7 ~poQŃΙOE[Bܮ) zĂߑ6`Az.i%/Sok,t}mq!}Z*)Wѯ Qs젊Jc!gYE3 BShU*!˅RJ[Rn/z O3 ̮Τy,sK|n>?3$ԉ(o: #MO LL) /0Y 6t%4u6͵>n۝= Yʃ͉#w&JPS|K`b2]JyԼ+SdW+%??ʱ^l !7Vȍd3¼`I _MfL OՍ+7ۋhq'g53y|i#1=V޳[p*ݲؿ&x`8.l_d5۞=ie.LSs\QY G"aK F.!WX[-JE"; h/FCsp;Rm6pƚ.PN 8zCWCD W}#:eb&}\"˅ x&2}J!Hߢ&,c ɁlCܯKP-`z]q fr[McAO۵/jy_y" Q2ҭ }|b)l4XF}T)obE&9ۂ4Fe񠋘7s R[NmB!%skQHJ})Wt%t9;.Gq5tjW[ ζuPZte5d.gAF1s%眹=-ܚX{'đa=KڽD>ɜD%rw_}$zCO;dÜѠ%0ӑ\;z9uٟ,$>9pcTu>48~9tt ^#'yX]ߟ߂x a@…kLpTx2{[o2:q3{h=",8.k^Bv5۪u]A\5]B1Ȍ`טNC"ҌjۂBe LAQ&,X%2jeq򈊙6Thi^ôUi~L͸ n1yUҦ(c<>Ç%,ۖB5tvIx-,d+_.y %8 ޿@_EBoHSsy=4z^K)6Yy58d;oVrʁȜh3;7u]}WjX;0+18d/\K]P{2~W2F84ޗTʺYvh0HMX7̝.l0Mk_cņDMa0Mx:#oͷkEmj[ej$9ß𭉼ll}ƙX'̈ fE;^6&{PsQ[fΙ8AL8=S{W<ѣq _uoHKb œZ'/xz%!#pv'EU) 1|X(P:GAܛV<8ځ|N6EDqg'6?,0\Ўp或NŌr䢊|B`"2IgHX[%aI~L0- a)B&\{ "e4᧜ӿ,*fnHf7ɖ~ ,OE0můuՇpE7̇q-}i"rxRU"Zt K,-<k(ᥐr*_̲9l88?j`ӌ\f齷s$K'Tvgrx&njl<'C7 G0HW}o&"4:1yViY{jѥ8$tMq KbW5ٶ'Pq1U?_1Yq␗r8=jq-|[PGѹM01"|s<;-ȬD#^͏Bᛳ(H3?hkFZ4z]O⼭Oo$z9 o) t]4ue[VQێ_}'"΋*n13kSпQ HI䔉 T楰G}WYtjzVvr^S~GNB[G^ _Yȯ F*U\⛊fgU,esK9MG˷hd9 k8/tfLsg*^3$i$3|@hʟYq4!{˙`[CABN!xe{ʶ`{75]0=MطzӢ[ϏꯩOO ׇk6_w켆?TLË"")0y:NSZ FW ۩d(5 7-"wu5#`jJTK԰w+w$v׏YE|&y`}X')^{7ޑ'9YH؅8ę7#p45;mw2꧈6We.czqJe-cW1a(ZAK%֪N:r* W];|wZ͜ÚI䧍e>v܉?&*Y"z;\t*iI>?4l6?% Gpb$9KYNդzpn+:9cә5,˵yd ϗLbw)y^h[kzѱԵ_``G|n_g7E tm̢$FP5Nk1WJvRZO,e1~f:\sBABܑHKɭ !ϋR\WiYE*r+R2|/X7%94O'nv&fsV+iXɞ&^8䄙cm߰ + -RcKE3|X ̬X͉D86w(wwq ;qU1ϊvvE쏈Bzוcts?>'QJƶmɕ5P6q' }XKo_lYP nގ7D?剌v5(fjq93`Ojl!dNR@K^pEɊZjYRQYt8O#񩟂,)Q |OŐFٹүg,ni@!) ?ƒ3*%7܈ni=83еfW8iZ SIj,T|IoE'y"m<^މA]ނ }S33)e2^1\]UW󶨘{^1-XL{ GIJC5 >(,k9y7]]Jed327\b`#2\Jت*ϒx)[x: /tc$nGdASѬ}GvXπ˽zCɴq8zH{Ck+8ùl- *Ac8:2QRF\Hb@@.LK@.E\s Wi|exnm1G^cS pb'% $L<˼>en%^[߁mYk8?֢ݢ^q9?M~ xq?؉E?8.bn7fsO|%/3kzb~e75[9IY=ILk.!Rȃ , Hcjpj~x5=oAO "c麌)XNaL?{"7GZʜ(z”7@',1ͅ%%d]nzY%]B$]m~Y}[݄ 1FC>.* j%9#L^JA9-mU1J2M"Mh%řicwOO&:xa՛}~d7 {kϳ_Q"_;Uϭ_q,0G`.&0a:.b ċ2r#i{x(/MdkdυCpt3&G;x4 g$*G,[Me vO aEkACزi4:b$6tޭx :1p)s-/ 8^6sꮜnE/bj!Zށn=ޚpC=mb*ZbdkR4?螚Kt%+c>N*5ǎd& *^U2kSˮX"ኂKE̛'mfi9@>-eҋ5|ɞ֩LK-g"IIlApW#< eR 1~ \͠ g(Qp]i VcX:p7-_Řh\Ox}~'#JhgY{/\0j ${RAِG#b9ߑuhwg>M\3!f"_Z;I}-i.iF8OvyqtvK$-3H gҵddvtJu~%% XQwe{0;Bz/+⫗c^aԑ3tsq283LJ)iHى?y1~+2[^>C 2x!O`Lveő87҆8О3DKw4eury1*]d^&1k 3]/t^$Ck_W\[pc>K?FEm%C͋IXSNDNQy]͂5jȔ,Sz+9c Y  T`<7EGjrJ>?,U< кJ*$73,YXe_<|{yAg>oAv=BtcYcE_oAtdPF]m}1FZj[W󖞮Z5QK4ܚgG)e\;%\h]BU=S4ܠ.xC$!}<4ރxc(Z u{s>9PəFz[O幡 zQB㑊6 IaGAs,ԍ}Z쿞<ӹ%~حta5ӧQmðx/񧠗7=zG4Vm 久MxEVz4v}BsɞM'P{,kX#GpNHX&WSTu Jx3c{-mwRyͤᤝ 擏/Ӻyr #xvqE(' qeDY9̱xX!NVJq-!;];[)52NWbKM- X@&:F+% UDWS;O~ wiY_W\Ҥ /2 %1j7ggk5pUj ,do)X2 ]}M_]M+ڽh!|σ$\ṹ M/˲bގ!Z7RyJ4.E6z)O2ѣ@N̺h&Ҹ`<6al nvXs=1'Ԉyooaؖ.teY$P]F0~i~x3olP߲ý;ٕ('܃% 8~ğߎ!\4.ΝQ6޵X͚4sxS 25IO' 4 S,yNF%ZOzyK0>lbHkstlֲlyY59``B{X{X$Q$[_D1El8d CĈ5ixEJCj(мϡ[/_WD:|#< }Mp<^ZVYR]J|Jq:$?y͟m\iPjE@ΌBX :aͽX{NO pmȰ$;y[x{/%1U00q%]83gIرD# Y#wlh=WZpn:3…Xm˜ؙ7]J"di&65 -21Wsǁ#,wŒ'olpL 4hgaz*hH򴏿ŵ< d%ڣ fV:_CNb16ХDOFZW2N |5ۦ -8кQN ݡ!m4\n/^THq snT3wf1tlG!;#oe1/2Rϯ[:=Az:EYbuw@uDѱ/^G:+5\ ƲL=JtqDĦOW6ӎhro{뺱&_\ݒyL;=ӻѲu+6Ha66Ӥvύ'p(Aƃ61z }=(~F(ͺ&3Si&BÙWsψE&t"L1b>912x<e/@ψ^lFΊEXAUr~I,d Oun:׎F;& L;$]Y4m(ԢʴW&I?8ahhۢ%C;0Rk[1pdANErJ"gzu^< j.XaPb9቟o ّ1L蓁F|~6@j4Li.حqO(M¡,rLz}Ln\,23זŚzL·j(lSXfjV@Ū4V>v${b[B V7c.R[hj_qpK9B춭?V<40:f\OmL<5h"+ư!#!fd_˩XѪ ךtSUR]R+%} sr֯.Uq:g3o|/{9k :[UptY-&ӽTBN%zW:+xпe/aQ׺Q)'7nnhrƐD{3dʩ:Rۯ+Ub6}fs#t Ǹrԑ?~7cmcI{a։pnGT5z3\uʤì(zp-؊y4k0VbQc 1Ϧ u~Jh~kFΣԋ ``cn1!<ϣ"j,.bzU0lyϕu)eYF ꎙL)D/MY/$Ѯmʼ*nzo,rƦ7?FD:'fg3mW9ƅq=iǴVxza6Y,^CCl6M&8e>u!5RӔUl6-0cϏzNΊrcI}@1Ix#9yh4-pIVDl lϡlx&\:Axƅw]D*sL3!w5\uڙ}H&_V]yЍ_ޤҰQ$dkkQd)2Ky+x~~2>|WV"*N c TN~l\ƀEe0),j?S9h(fN 4Y hn+Tc9kdH)ƕ۱҅p:POG(!iF 9:VIC"=,¤)LtaJ'{IwP6HOGxlD+Bn,aA>_ve3iGzޛ:~ބ+s )_aw2🾸DvZC UqaMdE 6sb[gܻr~+#[8 K|X֟~JJo1`g)$⊹g֧ݬ:umgZJUG/D8^+R?20a®`;ݎ9*YGEWl8 f|5hxN=˘~4nIv+ѽ V{/e/gu^)C(RtOc[YBgtmR~TJ=Dש C!ݦ &?r OrliFghi0Jnttq2xכd[Cʢ"jmnTEMrkdDžJ$\\ ^@-XCzRu~q@Z= 痗9-oڲw:uڳ lѕkqf!Wz~<q'ftN/?ES'7a6-{`:y@Z3`9[Ys vvLh왻؆^vtOA>ZQ+arMG{} e^Zn$|Te.hbEz6٠`3,7F{ys6tGQO< Cy=ϏA.7Ӟh591zc<ݧ9{Z,(sbTםDVY(g"f *҆BpV.1sŷ؂k-9VcE)r^| ].ctiO~5rrgmr&5m73нI$ƷjV>wz[IrdMfzmy: s)JnJ5ZQ1,ԗ1W7ҐLK*$nCX:"9їE3-YA /hf6,9AQƯMS=O:9 ,hʪ ^i#h!}S}Дߔ==XK[%L7ՙ#VgZkzU9-5Ņ[΢JWxF~FgsTlS~%pZ4@/*^g)]7&O&} )>lA|sh:ѕNĈGF,A{,ۉ1| w'Zލ,ά)B~߽<ֆS1''KV%ϨZgŚ> YM%JjZ2uYxuXJlR~.H.K֓kOk_:*ܼD27MlL2ɰqw Y-RI}eX3C>]en(&Rq Nu2[te Znb񺤍mFSY*5G&)k^totʟ_)'Lyݘm;lF/zhS.h+.p`D+_0O{+Vbʎ&3lpk͡k=w@:y +Rf!rXǒ9%97zS0 y >XF~U._"Is`[,+LHJR<&Pm)}ʰ] z}.v"\cL%0㼱wP {|S\]€])a67f7{{NLFUr]md)"޾ɤt b]"?sxDE6:drhZtv2$z50K0u3kwYӦtlnvf;ݍIx!Y6#,zB_bn.u#GѴOO /گr#sQ`v09D}CU9w uHf:[TapVE E㬰3sO,S/5Q@Ӱ;[i8/VY[(q~f A1?D?|60gg9L$BȎ(MF/VXx0MVsf8H3i(MsYG۪BKVVdԫ`r..gLVg[Ot-qbo77?F30{+9f CޙujZ95׍|"0F nmµA(nkc:gj`9Wh2eUrHe~DO񢥥="PWa!I$n%mM*'P,rв,ubZu,abW m"[(™..,0 3&p z d-99AŵZ,ڃ;`WuQݵoX W;o(d8)3C/u"XS~*&Ͽ,W5L&c߭Tf*S[g>9yўO;1n/>xr3Xme k}:7S8nHO=@h+oX׉I7ikh03B\ZglY*:-ҎS2S8tC?K+K39[ńŔΪZHfH6DSԹu {r/c1}8nXhIS1MFp% ZHg1J2*K VKZį))G1B-WlJjѝ:FJu_HLzqFϛOh„BMjNLkI SjAsay1lثTqS;+w)4({Mo67\>GReb\h0Az|Ad nk1/]\7_p oj~Su rl Î:}l3&u0F_fc$:y81572t+Ƶ6+݂Nca0c4 qizvz1]3יp aP|wp5CǞte_sQ lh3y"y4-cx)KiŴYUbJ45"S4oX6َ?;đ3+ܹp0K} uDy2K4~-iR-s?ggĭ0w>rm{[;eI[&oZ+?sc/vapיsnBE.eS6E>^TWpoG !;@Gl% &8?2!~LMQ5'd ɱ8>'?Qx'msh<E?N4w#}iϛ.3:RփveؽO' >*-ڈ3bpX`z-R0o '^ 9Bix0-±: Y1OdD \.mN3pC}g5UPV^ִ7[%`$ Ok9|,Un`$zπe›4SzF;s#!;gu7!19k. hʗ h:wS9;%%)dfųg4^X^'Lqٛabъތ"+"[5X9Jv鿼 ㌗׸}.c{ehr-k3']y<ƏXz!s]}AӂA1݈eW2/ ܴI8Lcd`xdq%)3+Bf#QV*¥);s,'nV ux2h7=Hݏ2:s"1g ?(h ;fzG7*JEqjrߗJ bf "H ${t[ Elzw bO9w׉U[4(7&_VqgAKh:Γڡ{ lOxڏIh<"%^|z`ύd`[s+|ڱuIL97ۊU-X>Ɔ.߷q-ǟx/atвnzq;']8|؎oh 0eFQ0MǦ3(oI\)n9~ GXTgwnz+Ň@+/ok<-_ĥE>b_ʦJijI[IΰVv*߯'I*.J]ůëOI*%ډ+WAwc^`I /yk~5Yiju\K!$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$7^LeʛTçWiםl۷M4W9~WZl=oo.>$*bӗhΡP<2\ Bϭ ˄KbʓFJêeT7 OKHگwʶ _r{U&{(IwT-OP?ݫ7qŗbʻK]^==ˡ{ybGt1vmqdXϮ^KJgF^Lua=@\,n2l/Tʏ*~;ELiX7ō7sKb 9QXrӫĄ%ŧC5JS嘒^b.AVeﶧ6e@XR:* s+sS)'^V⍒O7:0iT{sIϠvU D\/ixC.jʌN\xܛ1ct8¿%OkZŠ.*th7m1z 4:dž>%jx#֞sꌾs]-[ ?JQ.QLAʰ[*z2!;o^ YQչ&,.v!tڴŤ!} 5ɵʄ☿U4.(s>qX6>ߊb5;1PK[l9*v޿ ~q&gEύJՠ6V;Dj$;OF9ʈؙؿ)VSzq0ن KƱtW2Zeυ:lHޡ:TS/+ _11HPl/u(Gȣo 8P95EOf!ggA}ذ3uց_z 4b-q_.w-G4rbˠ& Z|S/ (d67q+6Pg!o]Kmo iGGW-j1M>/OqH+VQ'0IۼI{HMy]> t/٩H7LV4jGu{;05â2LvDX t9%ǛAzˀQCxϼ&n#K\q)fk̛՝|W;šSfv eC&F†|ݏà\MnrfN3.eM7egB~b{ș59vL3GYbH&{6FWLdmE#{:ّ50xy?`GuBAcf4PeX;9Q~Îm=8]3"8+ ߃iSM#bڮkBţD'/ކ.<ĽxZ bJ;lA<Va,э*ZӦPSF(6o 'at Z9cՓ ZץZ lI:f;tBO鸅$ce=]D$ ǭ2Jqr_=SQn7\' a5?s: Y?=ܜu}!nq5i'Xqr$=mM:H9o]ۃ,>ISEi=, ?SdǖtΉ-fEd'7'R1>l3YELUD~`&͖trN c^Swi!]Vǒ\zέ$Bwu_4,},`C>w:{2p_F,׵86TEESwv fu0Wcg!XMw75i>MEnp'ՃzFxm` m?5Eq),Vw~ =Kl}>MmtS):;Z.cNDç*z,+JP8f <>OV8}"8%|n͵Uv.sj:c5&1 fOKQUs[*gNotp}ؗz"~w gl]яzڜ߫iT+^9t3k6`>oZg_[$} .k6z/ƜzT>7{w"S{4>0ʉ<cw 昡>] ؤ=m¸2Ҏ3L #}Y6( (NZeCw>nl(.8ɄS;lVHA~卒3:Fy>Dqzm۫H&]61EeI}q¯H$M~*~!N-1dITgVV> ]E_%Ew"^̕}٧AdNF*Q6G܉*x6w"3,՟ 4GW Jsd<țaD`_ז =Yv'"D~49.Rl]Y3d ChBԁ-v*m 8̌N'q옭 ,[dN9'̜UxgTT.\ke{)LIp*݌{Fw]6=2O+M;%3Ս۱`9,pu4D\KÞηqq)vk0fN }Y.op~_6GpyM+H(ͶBA?7&jW"\WX1b4l'z/~֊/g}miKy_fn}D)ؗԭ & A:&bswVtud/g5H4|ur+وd`tP~bYB|űȤ 8h|b()(U|ڞđqX'v$a$F^ڟ{,fgKl7ï r?[#M5>.dkMD^-a^8k79## I)$]̿vHƝhLp+zү2vEe,+Bu:A.&s9RDfgzҟ$S6g-̉42(۟FF_|aLi*5\Nʘd6j2yhݗvxBƷ8r%թ4.|$ڎGGӌUNΤJu<˥δܘ }}4c έ3Ǫ9Z3#|8rV)潭Q.3p&uS)vbl+W:Ÿ]pu[{1=U;yY/5<" ήNq?{ycĈAJrV<"nI& SNZGuQ4-1?*x/ ~+N] ۱M4Cެg;f_̶jCr{sBoL=RB\"Ő׃I<ONr"Si\.f- nӭoa(CA$!C%탪ya/^`)su)i|$':x!1CaLY^AsyVZTJKH? 󹤈ҶO52Юu.˝S8:΁ɖbJT33sBq=eIg|o`Ek-d+UK:s̀^3t0X!܈l[Fd>z2w/ƍwcĈM.{> gexfilqo=_ `g['s`R!i*G?'﫶L?Ό gY1QY=eφb)C2va̖d1(6pbIn" 3? \ʼnTX#^Hdb?4]FܜՖxOGaJ+ ԩd:t/i=vDNϢ ײ4 e:188EW0(p\˚᰸/[{pjv/[eW!3M0p2r<ҳ˾[YJјB_ߟX#K(H!hvƨtRAח TL[TM2:+fQŲ23JC fd%ҹO k>HǬ*M NT4q8mL{.z7Xm:α.هi0ΗXf;n zcK}+o#88U4>b/.'Dz HΥp]A`M*Zx=1ٲ Y.O8&OIA$ ^'M8"lWѿI-M%L$=.r#*&3It:ߎ|B$ 1?Rq\4qpƦN`PZbƮobS?sLӞC6bG;WSM6z)⁏EQgyĉ ;~X$G8)7Fq*9:sϋh|Cܼp&m v@!p8sι `jUҮeh-pʐ߹_/BJ"~Ujo&-Xc%)+?L x:Rqb{X`/ctU]"&7?. aO.[B'qhCc?P L:s7K3J6qhW 59:DH:BH,jE^>d ,?Zo#`o=9S\긗^Kb%VÅ@ 1>mƸSD&v~ah-0Y=@rPU'7΁?6 4`Qƽ4Ӌ q_sJ>mh[m Hu䙕3+b<9>85xlݭW3Yќ)zU{+5L'S:qo72ROO]S2-l9`gqgċoo=A`Gw3W$ݙ?.d_JT=q+j(;Y2f+99nJQA)95Ǥ}lG۱|)K[k{P0c=.j`̯qnE˘6«ĬP3$DcۊÔTwXhVH|'ӎ'|٭MG2s(8ÛY_dBn[iվT lQL H$neH.3mrJ|/r-XQU#1l?u rwC ˂_Wm`f >8UȻ5TǙ^!@]=QG )~Qq0 HYYGr-b8w=f7;\nu Qk)~,Mdiz_ů]ًE=`s#[OfҕLm:c&es&fx;D8hǎ}\>d ^ƍkN7D lD 2kV?lÙlM[pI>mLJ%T򶤚OktƲsj?I09,Qb[rL5f5ЇZWgb1BĭDu5fsaN}p|=6cΝȸfLtU.~wAgo,{NYhެ+?@o1:8ٓE8<7&rNqR5.Od`?XeyGJYq9M2ywbWڣ΁lP-%J4#iUw(Yp@";cUX~Lrss3gk+r9RE|yAi#"V]KZݩYQa3eiQDr^s􀌛_9r/82x.,vv--ob=egxp \}lZ[̽) 8&y"7#Uz3ӗ|Dm_+lW+zz߿3\+ULV׷yMhK`o`YF.MbָJ4+ad"φ=9$ުZ`<4QtϮ8R=/~7\,G]'DϚJ62$o9g7ےمO}q̟:z_'ҡHƐ HY3aX qX89)QjU%W򳌇r(LtA<-Srwhuj(#~~KχQאs+,]HՁ1Y=Y-qwsfj'4ȁ5΀oj 5r|1ۧY~\ą|4''P7 Yp؀Of"zdJeӑ,q'Zـ]qCOwj%l06Ԗ5Gj_'~H,oOp43s98w,vB3?zͅ6Bƫsd;.-S)ET^gٳ;URU\YHYa ;M]8ܧHB?_+&o5C*3+g5hzD.8`pusBȭ*GB \iZ.t)Yjh֒`$yu-C*,&,@Y2 "9lFbk{_&c NxfsnoQUj;3'Бφv\Y2 `M{pYUn Nh/wf]qWO}OƔX 3xGЪhŪѸnbCklɯd2 :nƃw<XPzf\VmŴ&%7nȬavQ֣圾$GH Z,S*VFG@\9 p%~\YcåAAle{D:uMbѽ03PF19z>ň&K$*A~Gg1 >LѥRunyxr!ٌ#& E}Q%I{CGSqώUH6nL&ѯX*C{!c/|LF::]J1viȪ <o6^eϷF,Sa%cy=cd\jUÎhJy垌@?F.1TZPLpT 7ppS!+=F5zShӀؘb19 +o]=߉l^ OimC Qҗs ADn4DCX|m4 ; 8{[}Ê16g;\wWlq1 ٚ*{d%]bM1!~uLWcFs{/}FЦ2 9 tTɈRKOki(URFEzr?w4&ZR[cY!}-k<(|d yOVP=-~I:H)8׋zʙijڼ q+ϛU݈𰤉OCf)eZ1L;,S4tNgza-6OIۛn.pfwS:+AITUY7F?SK tf s`=0h!6VĭVӦD2/Ͼ1+tԂNE8Ep4PG?ZpZ. sE,At9mU0Tӭ靤\Ku b^kg"R%+vԄvdrgҞ@NچsZո0\.GY%Y nQ8}:bӓ|(5僡%ڠ$5Z4c@z+FV\"Ms+6)':%dU62A7]};̹Ys/ޫY:eh E՚,|T*YAy9OQNTOLw+5^50{_-x7BIk|.],ܓ2Lcۆl^IRɞkZ|ʞO75Fs^l.LtCT[Qhfk촠Pr#Q&KT~/_%m^T)E$^H$>*_ZüOr~ג:aØLkQ /HhXHk#J+;VǏ&RjeR?ZsĻ579 m3[V18 b-)SID͗tGw2"8ߑs*ǩZZ̴+3/Ia9{|.Ras߉wJ`ĉDF`x;DGm~D Meb2l;C zem.'=<^kXtI´_"Wc̜tew}F$ĭܝmy~:쏈Meڴ7-r77sA2w'3tb-t̻9a?cӱ3ϠP,x?ۇwXʇran%n'7x24}~ug(Ҁ7DՔPDdݯbփ:Ls|QhdVrgYT٠[% $]Qrm{^Vu$|3 ZZJDzc s_usBhL]x;v}n3OMl6:!Ƃ=6Z|"&*=_T 0/ҽ3ҰYG)'M*yA9_I Zsj Gcc<-c G_? zOT60czbfBoZy!v*zq*idrR{PCմ)6*YԍP&c^2 #?SCl 4=S=9ъ;hi;TP=Ğ~=ةջ\z./T_xγ$ "fn. ݕȴMXG%$;*V"N)Î>ӝ4f!v/h ~stwNEqmp]vm+_\IdY`[ UT{QqVWh`A> <\kYZE bPhKeͯ~+^SM"C#ƶv64/"2ɔ^-;xuFmҙ|7Ykc "җӎ8-q6qUgEM26,j~l(nh۩Yݙ@]yŐ=RNtcT5QVH>0ei*WRWD׸&F sc=|CE'a_ L̢y?$PGkN6󺱔~8XN} ֚+8?=2߹*z~!UZtW*r11X Q]ỷpgw*WEJ'Ŝɤţ(YDj-j0v 3f}&a$=R\U6Fijq3 ˉbJr+'p+8GxݬGRNX|iVMjgTbf_Ir}C-(~ lT#SF6[ #0gj5 Wr.%(vFFCt=V3o[4~ 4`ˋ\bGd?𸤐Q EϮ$pu[if7d UM{.?vV]E-uhӔD<NףMAv%~|uB'vi%$ SesDF_)mHf5Gިx`-drU2@&)(䉣%rⲮ.bz䣼I K2mgsI\νbɢ>9YxY~oePsȬݢ[rT𿰫@#μKlrs%rBw6&௑KRLrJ{ZR(e(ډ(7g9Z]?vQSpcf}m{=݉6I{|jτ |uJR =%c ]9()U=ZJR@)V0aqC2.+*. UjM"cy*͋`pCBǢM rg$3ok)% #p7_ #R6JXNo vVBIQ% |,a2fWU.EBy|Kcgb gpVR)K}Uk0AݯkYKpSY(]:>sN='d֓7J 5/M͜iܐ7ҰAME5&j<4pNXM3J͟v*>e] dT\U (YI .+0૱t8VZWWئ愈TUpf3œ5u ǃ"Q?!# JCֹ ﵀N1ւ!=%"$"y(*m;G4 MyӏѸU2H;7>KMauh6F!/rk%5f h7%+FRIfE(a+&vCh4VVHDާz2#cE两*UN.dĞ<ԺyR L /!H- kh'`,N{́:3F@VXk;q g{Ѷyt*aBV7%!m")R<@Rzu!-8٫AQEs+f]te敐8ܐEɩ$ KCE& 9O:rHG,~)!\Ls1#WzMT3ry ާe \,E=~~*ުVaQcw5jn ` L[#7߫٤m 6ҿ7Ut[)V߷QRa8X-KȆ8dN=}uƠZJBk~KXwtWљ$cJZ/ɊtFfc;`'CB9E;)YS>pgE1<,&މf^Pdbu&bMOV0[= T&0q'fL@y893CxҷxI1 mFg XP-)\(5md =#!$.`~&b-M+'<.e^LK/~ 3281rޏS>jLJҍԜOWMZOThN!WXCk*5ݦ NPJE<_T5SY,d/׳#GT-Ayߥ5\ԭcztE:Rbtu?Fel@Sov[93m)Dchә tnOB?^lnV?N, O"Eۭ~=i`E֌9mqӤS䜛䂣C裣%(QS"\x:NVԑ^Jڨf8TEe5=7ridKrV;/ pIgr[iٻb\u֟?Ջ~ \"0:L# oEnW׹OwJ0hZƭ24H2o SLυtٓυ8O!)m\Gz4[טd%Q(E0zů|w#(VӈU6O*6G*w j5C亪#%2̈NiLst>TRFʾft4A$ߡOqt+/}LGN?̙Q5|5P8.2T~LnF &*R7>ƫ.՗vW%sG\&H͕̍^b+`_ŕ~HVHln˄\Q$}zܩm%x->1ۈ3]s.9G @./l]!^啎k,>l\^,ɢY jBiLgaIQ{e弸S]5z0?wxxmoeL(þr"sW\OɍB z uAa3B[&=z6Y uMEw]gkQ2u ((ؼDN52TFwk6f͙jvk?{˯o^ThK)g-E -^kp !PwzW~wue0`@]3g K*JM+Kz5]YJKg茑'gQɍJ+9u~+=*5=-[;=Q+ݯ-t|\dk{#s Q&(V ,]dUѡO(pOr YHOi"fy,/${1vE+b|ST]c J"*9nOش@d%DEQg:ݒad:N]xoV|c&d.>IQ'3@2? " +kQΛkK4&p,lJwx?S„YZrGKq` ~GRǥA&k&ftAA$'R]M2kcYڡ\^I#y!j3"}osL0گ縸63!IG{㲕yI4ֹp8&>tiOhfBN`GkwN&X3bk~}paX(&\"PR[f'2ͱL Ldu.S+VY!Vxe8^ g,JNSbJEO44i>?YAy:ѵuhC<Qy_K= ľ6M5W߈餦&ZnPAbWsaV:,ޫmUK= Z\)4Voj\y"&DŠj5ExZ 0y?l|m(Ց"X~}>V9/߭Ƌx Rދs|el-gV$=:r2:%Ϣ p\\X@T%,^B'gW=|b 2?ik;)9`O. H? Hn?B6Uiz>Q30m:UzmҼ »OO(wHV9'ڋb8.Ei602̓s_Td^HǷLC)KER鞈τ} ۮ|4ٙ BNyW{ 5 m(Ǽa$$iL*sɔ9t… Φ,rc:O{7 r|rȎ/eR^+xSA'sꧭu*fWp_M8Z=y`&{dE+YS ZGb fp,'K|' ԤR Sҫl'Q̲ Xfp=b| X=5zIb%g-ESEV%:ȹ]N]%w`E*1g_Yh[)Ta$Ut_k2)'0/ަkJ2(2qg)MPqiD_Sr^(Bÿ+WK3lB O2oJS18sFn"|pq8y3ھݪXNgtک% )e-ʒIl?GPo`5#y5ㆽS$]RPg}O[္s {Pp}Dя3B;/0u g/Ӽy.wמ.JNzSCy v֍i?hB%I1>64?9v~* ,Ũz }E_RɬKth#>M&n#p+f4tfcA]ˮj+ˬ oDh U\h)EAGDZ$A[hc aҜm;ZV+>liFD6-a+_ xsImHߝ.";*f]))2ƝRҺ$/o8(gV[Vp]N%e4UBQ qq}z w1O.`ȂB0q %<+ ed/P.:e˘pAF9~(r+T |Br(co]>Hd_[qEѸG+!=aDvyhBi:1xDMhڣ-s~F3I:f,NaY%i(K r.HW'glB̃1zgsc{ - lmԃpA-Ӣ-`VrY&XԘ4-䎱}9 j}LFӳK%a?T"L1S"yD e(0Ί#x KX1Л_NqTԉ/734>A3:.㉲v$ԁV8] IS"s z`;&uid?{Q-cylA*{.>5f5iɋ,Q?'i^AJbդ k{Ldjn[÷g5~n S鹿/AZzד -!wQ>C 07ҏ fV[:nnf4]$ I!-~^ ,m8S^9_MafW« 9C[\݃GSb2k"HY@RH񹄕biTZ?i)%.b ٱwϊ(VL>e>(2{~ >I֕^FJ4W7@: x!'e4)ZʜT%ڪibDd;eT+CT[R&.&h1|X""2e(mQt0>A$ "35&wfB5㖔cܼ%JOt~dK gGa@_ޏ6>LٴwBhޘNfe;=%,yc8ѳGnGHWWXO (fQ,jiaFggq><˂iy If@NN4Z-fd7?{OwFXteR540QUb5wD?*A;wZ8cpAsbfgMB凄 40.:f_kNSJ0Go=pMZ-Q1ǭKӾ (atu!+ XX994LjH׮4]1'q QreD0r54KQq靚ՓXPc y}$< KXzEPv̍n FNM ?e8wzDbph:zl%vDgAzL~cL-ұsM1Cgw<ѳ2)L B:Hɨv l2r".4W/#FI{b3vz}7h/f?_x+6{s2& iAΝ*)ex&ȸK<5Yn8ф][1u#Mhe;iSM0K< } 0޲[D.сP]ϼ"9wKeőL#zP¬e.`B~x6V‘KZlͣ8[qd9M[`c?@fVATN@ϓ Q$h\5IZL7.pHō? P+!);||fp5F`JM⼨eBE*KXT#Lά7R KU)y {oC:IX?pqKa]kpO_1 Æ+}O;>g':zٜˁ|rO6w,0/ } zHXzJX{JPOJRDyIٚ^fcGxG38L??x8E_77rA9G\r5kЩn!`>(MϷ7>Bϴ:~ sA%WW3L]ѱc2ӯDx`ZfG>c3*j2ɀ=k9^_FtցY_4զ#jSXݜ#ivߖs'_=VVFՖ,Y$OPw7WL`B wmF9xܴ{7Zn͘):ޕ{s1yV˻ax2L;MbI؆\3 ob6RQg,*+ѱ]Y7jro-3eD9WO"jHF9)2,)G͑*Vp2zF(IsSq奒9*"8AAyQvւȎC8xbÃFr:f"7e=ȻJ= ωyRB?R %aS]{fw&=*ڝ;a𲑄3k &tjb2h;YnTX-f<]˶ 9[ŭ\>ys# gl)c9JAa` ;27PM_BI7y'CRn_]! ͭ!tdOfWbY*.W풆߭*iogީmtDOq;?tsjYswXvް<;c-jqAK^e;Ga[Nθu䮋9O$/jk?ӛ|Ngs?qi7u!(v[~Fs{Eܙc)Yݎ_{X&;G-H yh澶# R}45߄V6h4jН3 sSŗq!T=0Mcx9bf=cj vVдizbW0뒂.i%8̧^cr%HUȬ#8]cMIu*lRPW͍SJ~UcBv 7Qs:r?JF&heϳΕM׶)숡9MCᄩ,YDhi)Aw՛ 5/YsN¥AzH?3X`U$'27-Dk%̶-@ѲKsh5UYX򬾄sľbloD!!\-2X6; Frha)O1k) 6ÞWhޜ/_6|ؖB5e$80؁!kGkэ믾|v KV ;n.LeՓnZH=N/t؉_}Vo"qNأ##Jӹ1ّ=q4X5fhȋ&N$u7{hdp;ؕ}TuS_gOFu4y16X^'gm5^*XtQb=tmqNdmmhhOZ1cxhCC~NJx=giw^ Zj*t!JJYXURn+el1aO?q^oǶi숦Ql.(sn9[Y[&igӈBI&ATJlXG g,a,2%< H.dy*&d2C&i̩ɱɜ¥.Mf_ViQb~/Ƨv NnpVby}ZmMGqsN-Ӷ;sq!YOSKYk~klϝBK}~s_yUf:^2[Kƒ ~oj[%VQbڽ0v;`Ȟ|\USx/(fhaze$=p w8!IDpzdxS6Gtw/ryOȀgb*38oKk ֵ#I G6zoo$"g?cAD |}gA/L&y<{NZj M~ ^m dAQ8q׬?%2h%Aw{ )a'd<< ru^48)AvE*QФqe31&a!N5xM~J:b.*sE!S q*cn \" pL˂b-[ۚ`q"#|TreJ V;(()5Sh ʉTDlZId"_!,8IKT$S11yo0וѬ/IYݚB~NŸꈹ1SSvN&}:[NqtpGur&39'oIʊST.Zѫ%_b]M6'}O }NqThxRXGhUX}0~.aqx)ΜK[]Ig+ǕWCG;=]Wa l/#SOl Qe"CfBf x1{xԕxO6{e2NBFY]/MX]JTٗWLcI1Ih'Tdz+by#0i:sq442 ע€:x*y`Գ\ 8FZOb]lJI{>!{|8(%đkMԓ/II >:NԐMRA5 >SUNWP IX%"m$!Ex^d\ @y;Qܩ CcN03ӲRx@)  LǧoY4@}j͡TJKt.Wd00 {cuW0cE~I|f!gbaP<2uMBt{AFˆn][2yXFׄBȰJܭ|{^I;*crWB^6E9)t g|^ `:r oo^cg[8Ѡ؛x S i7R)]#I\~fKrA JZX^$*mHq\:K/%ާ?-hۍUAXbQωIwD2q4tki1t2D$E&R唀 `錉`LjҰaMȠdg{ʺ><vxE Xa\em0O{OBy:֔t'`&ڕH,*:}_lSJz:nj&lW5c iM5%|"VvU&0'ߑ''`2C'd7⼶wM,u ̙'vr8Kc<_f9vA|l q±=%l:Dž q;px9'ٚV?t9lYDvBꆖ*ד :TW-vUxVq@Ch-WM5Ϡs5CDb&H5q?t-67PVҬW,ލ3ؐFET~fm܃]t4\4-RS+YP(OHya,'Z1+ͣhҕu'j$VZbo0~o(ڂn3Զ+Wjz`r:/DIcxĺ7A.e G5Ix\,E!2bOgdlUX[SֻSfJhh1DI 1}pA\&)ivwTqsPladyj68BH3gnda'0{!)X,ľo "Qt.'Y*g+g8fsa:%O8#LZ ܪ+Knr_x3*iI GYޔ(OYTq dHrlFPPԄ27Zh14E7gMtzv'.m:oFS*Q<6ַ#0p:ME d(:>\fsġ{d|dxXVvSmBhrr>GĴDEa4]d6Lɳt.˹Zck=ZG:\ѝ伟ڲ40}hVT[#Z}ĶlKMxv4 )1(i !Oĉ^6DégsiJ̵vO+ rSocZعoô,Yaש4R/6 iN6҂/1=.d ='B޳v^d O,OųwwoL¸h(1;/L׀U0ڳz߭&u3U ]ɲJ~vm)p:u C: >6Psn5UQ\n&m 'co?<7؉7n:ߪ"Tm&Tsw:uuUt֭&՜GѡB|(Z]`}\ܙ1[ } .z#'W$=Y<\BLM >@l[%g(괂ޥ h)#NfݫW#U Q#[bh򢐷 0ږIVa$NV]i2S2X73o2̊+|4ꖍwCsyU^J.+閩jy#xi[%6VqXdBnmȵ1ۊQ1F9J\ӋDߵw|7w*h52!d LK4V%'#yilE$gC;|;ڛ ob, =˛9Sd8Y3ndMgR4,ql`ðg֞'%h w%pA}zJL82PSDuO_T04% dZMveɽZɳzrT5Yq_pțER-G'!~S?4gy5W-DEGυԞm&~ǝ9<8N^p:Ifr,>)y"ULWInJQ# !DN`gF׃/zWs /0.fnƧSdDu4?AXJyoW}Cz"$'3> )/5Q1 +CqSgv7lͼ$5_UVE`^u8?b\48PJvlyÕx{*<$2w-ɳq ZQ\Bz2nشE͈:nK **w·~%eL@$>GXD++7[aʂQF0eP/[{:8GXԌ$W`^֥p`~!?JsOHuvE YRȰy4lD&S}j!/ r1#A/˴VE/Br3ȉչ>ϊI|R( qtkBˋOQ9jDͺO*͕uP_CNٟ*6օaBhwgQ@"Dts{@+)&r֜ZƘưMUPGC-zgxx+[ 9_ұ,Jf8!sN)ƽa1{ ^b] DYV.S9t</W7ÿDRg35;8Y?uv&h$ 3ʋ;BO:IA-Q䅚;*ZP0쑂7gU/iQ".ۂu.]>qR ׶%&u& iki\o*%M~0ZЍpN{ä/qvN4F's[ ez|hꝎ\,FcSv$q5]_qBv%B9>WjvwM756}>sp4}k4D 9OώSUt?d#s*N$a2ur-R,E:ZJVj>KM@\^9!xǰƔ>0#2)n㨟2/ٳHdݟ/$Ϧ"ۡLrAt EoX~.e`93ri锢fRμ,)ws\(5)8 a_6hOk4-v*d iY0Ob'Y81!#t";l۞. Mazdr&3im&Y^y*BF*Zv-] *~iXEYs4h s'}!zӮI=' *Ŭ59D7a$\z]O&pq$? gxv%; $ҙ,?^%t]ݦEbn![IR;$܏&vH֎ŏ j=p.Ogͽ)1o!xfKd$IlDŽ0=Bs=ʘq T_O0Ww ?WO5ֳ٩U^#EVrAnB~Ҡ}(g2rܺ%c%yTTei9A}c\`@9~M\Yps &GlFOX=Ć>c-Ye15=Neh_"?;ЗөɑZB{8  `goSMU%e܊I"fSO]/ 誷a|#ZWYwġjƉˊb~ۻ/x&E`~™gu B98}>s7x'x<6߭S,jB/V v(RV7)7i`)EQF{aJr?! ,]Np ]?ih: SM1ͱNnjc;khx"k~%rg]qT2lg)a%ѫs1$s>z a ~l޷KJ{F"'Ĺ L4`hGcxbm f!Tb8MXÕ}zzף9& z:4fu-7FRϥMUTͫr5x*2 QjVC*vuTjOST+sS0e=Y&A,A"7](4qW8ҭ [t$|Ȯ ̩|IɪNssQ+~Jf,6}vamwDaY.qUrYCW 1Մ5W1յVbl[EZeײ!x3Ff$޵d2/E6! ( k1&Nb%|؞/\F^Ϥwƌ <* `Pa8EBK֘8⼢Pbа)?Ew`j#FkG1'JRݑ#-c{-h`aȕ_nβ>:%[kz2SV9OCpn cx@כs`[ yu,A@4ԆbzۈYh!0H1'v%}3!oe0F;Pĝya@1u\|'6IljM<`hD!P΢E])᝼ ' #hvױjOfz꟭&9udq-8o{ٗZ:G)RtD{UTq['k3O߄ RK!c2d)ޟʃֱ‰ ?Dz`mmkc66%Nsb{UQ+G$# !MYR _qW$ӿx|/Z'2Q OIۭ&FUZ~htN{0 "5,+"884~ML/j&{Ty;e61:Ə{j-ճ>eWf+9˪$\ϩj=/t:feѮk A*.lUNET 9w*QY%W(.1Ӿ#v){@FzϚh(Bl%s\)d}9ߴ̯#D?4UN uԜ_pSoڿʷpۚ}]p͓& f55KR7]kqG3o1#Fzc?o&G_mWa՛ל(l N x4BKK|SE+?}seO)=iqB'Qr^᧭@kʙ8o5ER bkN jЩ&s;Ϡ oy0g?2-5q-KAWt:fg6ᑹHƉ)u5_өܒ[t$OB֖J.bQFRsg tM5z.t:,PQ.R_ೄ%tfݜ4dkqݓHZλ ŧ`"Gb;Uc&xaO1SpMsS˒sȒPlf쒄DFz6TixΫf*}ױ0YgBɡB2UpgU9 ω81ƽ8w\s<-S|Ļ*Q;vs8 DO3U KY~@jJB-KY#->f|t,'HGBTWcW=9Ař)ߺ 7;NWz$~ـWbb<fݖaMfpm.&q]+C:4,6Hid6Ki3c {jF>x6}&^5qռYW͈+xԳנ gЬ*^DTqNKg5J(󆌇 xE ׹˅fo Oۙa]yCU8i<@?Qnhѕd*9nǾfbz+Ugq˴ ؜R)zc3lwVQ Ȩ.0ir{9P@AIz9EaS= dD E0x `9'+"Xzcg~NSyҎi^hpʼhU{]zȴnhz(rɝDol)^}Utu+^`ХWUVIU StSI9d''w _C0C >s4/ʈ"K4Ё͝hכ[g 2c"PS#kh"Y##ۓx%3'|[<(F.-.ḻ%L~]NJ9\ƓJ*•DLTcHǵ_*^i=\4OxRͲ y4 6".M!7" &?1DK$oʤ[4,h㱶)u!e=n;[*mxԆˎ¡q)(r`svLf:8a+It(mm)ɪki̹S@Ǖe,bS=JN)\AeWrR[D΍eŐ**1pjZa=}Rxf:۞4*5QG(`!OɅ6ʛ\C.BFCb J'7鋌yޜai62u*Kptۛ=gE> JfWNEh23 #IzY^)zs'Z54EAz8[.9(v^#@&)D0oK!k}:,3+ڀ.aGW GawFXm15a*V3Fyj4-tX,M5'_[Ê]|xqLz5pߝIٛX.%`m'dpK;y&*C:Lףҳm0\ U\ڢu@ ]fY@5gUu5s=X&u٧ᦙ %&S"]2&K`NXVzD?Oz+ə#چHtpTY7bM? W?vheHQ=gs1B^EWK9ߗLNjCxoaW>Waʛ^ى4\1}qcSژ~8cϩq8~KǓ&lhNp?;?0,.p8w:|/&u-ߍ{v̜~t ź$<{N`ׅ43P\̐b@ ǵ斲;vN|m&xV6 `e#0cRz"ΩlLwOsH!/ iu%4XM:bV&.# aܾeb|vZ@P\ɞJZ>Ѱ2GZ^L֢U3q%o\@gDLCf0AO*8TBxWq,8bnjL͟woTd[ ,R| 'T==zvGV7}\*½yu,2ᑨG9G WaTKp e&ͅ'Gpn,Ǡ1g%Gh1ӈahԖզ][qwpijrE:H9Q0v96DQNsYv/ü6-rPx9и$t8`/W3K$QI[/p{/=eS9Ti_Nd'{NqeSg,4+ltDͥlYI3}χ ۇ# f~?2}N0^募Ess`8 x"4NW +XVWRzCy߃u1f ͠ju0Y "?oNdTG!D],ǥ*T^Gd'aPS Dž[Bv,I/P1SLp酘Ӵ s9 TViHiaSiDMVU.*Z|VIM^WwY%Q_1 ԴT6N͠_9>L/%T< 秊 5.ᇋ?792ij kpۜZA˯bݥ*)WJ T\b&QB?B{Z4|_q%H8fNdpu ,Oq ͦ`N~U:/L?atw|\X:7(_~)OȋB\kH mU8Q1ͳy2&hZ[kkV]nts-k:BdžNB{c@ kB_`ХbHW9ExMa`SE}뛋|͒(@۵Y]ͳyXRɋdWj{__̈́ ݠ*VU<.ܦnVż4'k9SK'/s 9VIpY'[ =g";S#'F'xG:XmLoyvêpƙBh(n]Me^?iߗpO[ʑo[4[Yܭx.f!Sµd9m5ӌ#f4۔-ÎU>醌- LU(uTWQS7UőP=詪#IvUԭӣ&ETO'Zp[ 9TO}z/Y 0`Xw6YxEƠSXD/0T1 KPg]9aKLJV8ݧ\6]:ߢ#-h2yM?_̽sI q& fB]^mrܴ2 ? Y%ܷgC(hw3Ç3f!4"zq$p coQͧ=Y&q6lj $̛+s<+HTJuyGT0sm%H62J.ȨwDA9QW~ rS] lBg l; NB %- ILRqV4bf+o((a Ԍ;&GZ9+I9&i&b.<ʣWvu8FUԐÚpo^3|haO(l2,Gg!+0V97)2VGJ//Kž%X-f͇bה,t+[Y fW JNU$Zʝ%L+_!e :ɣBǁŨ`b^B\`l+6ə/>J$>6E}VG{k/*6{#cvIdIXܥsrj,}H't+p.2N8ZI%sը:+?X[Ą3I3xٝ5nLMa,+t[&wq׎tGbW9/ >3'2)g<# H64w #JlVtji}GLVbwpHI:Ejʖ!Ԧq:S}HˢRϽQ9IJ?+vG}˙,WEO8tv_#ISYkl g)KäxXߓy\Ŕ!2"e.'y2bHk 6BVّck0|8^]rceIFQw:XyLæ9 M3{,9Ux=B.r֖S]JG)^ey[im9ZKFJV_}ba1%̷)FY#\/ } VT0힘uS0!w sEx2d-gKrYlg?:>/5ki̟G3*ݧ|$Y9zʹ|PMmZLhخ&f2j~\ÝzjiR\Ϣwd*D\Nh$u6yך.1v*賜فh8ڦΜ=bluusa~8> 4+{o|~qpRA=pPrւg-p^ Q쒈z8"|e!} R,~ Xy3a ao?/?&.0guBm5[p9/I`VD1syow .?P\Ô|nOQ?l< >P-gz;`QTf>gd$M2XKZ4.y@HQm_,c+KצmsnQ%+9v49QU F)gP S !ӵBch# wQoCwO; UgLcYz;4(U ^A޽J6?.лb1ˆds_o#ѪDjCfG? #Q~~6c!<BO83#XTRw-J51~11}&2g kD&wݓs,aj9኱XZ=_{Ǟ/şk37-/f`8|綍c6 aa;]כF0)?O/~4.!cƅ( v3V`JdgD\k:~ެ=ǒ}2=&?ڕ>ʉghR\~KHP`妠q9ecAAiJ楗2D='"DD[z)*h,x7Y.͖9tQ*2zC1JɸU2>gVf%iXI-6UB[2WT"ގ-&ݦ.P'dĘ_Ɨqymre&Н7=8@Eg1~FLϢYJ"HL !;FH`WvÞ3\ ˟)l?&wL92+hUxyo+YT\)_qlTh$=;DX҈eMh.ͨ#2̢̘ATgsTPnT|QsudϭdA)MHYN|p],!uKRy ز r}!IhW~":͍Los)T KQ)J~Q8:iX.$?ӜXl_LO%5h7!kٲ׆Fpe0sd?;SYѝ58%{! oO 8w%^Rm*G<J!A4<ґ7{Ppb4^]\R)ԻZF\JVF Tc(6kEC3kAɰUm9uW.*x6fmG2 3ui1K9y9NR6d~+ej)d\=Vɸe^+aҋ"(uQW72M :ĉ8v }3[,affffffI9=sΟzrWR[W繯[Ruqh*鹭A-:K*[\N 2t)C{F\.7ȹb!մxQ_˘r gQ1/K^{v'g~zVo#k = , INQJvh/Fy7Dv=O'Ɲf%'?Hɒc#APBI?3yx m?vżoM+FFԄm 4{7'LԲI,ۏ<T,zPeur"Wc_ϣirL>ͪȷ7?Љ3ÙQڀ)mi$^tZgd| =6~LjF`^/LR>[󩼞x2{0a.4/GD .:V魔}"^0@Bm ]DޓH+=4:VO6 @Cwʑ9p`wQrG܂cYl>TAu)gd"cWMg /e i~)w_ɢ(f2?$ʸ,SUF255|`kM8CMw*U %q} OUxj:q9A@vÉhlu-ƍ屵 n(aLag+[ŻPov20ciV?[^DFLJk;Ù+#h;ʖ,PYy-x<ÿڣR'lM,Eo^lpXi| e!zT`:l1"n 2J3K+YQYd\[؊붶^c2_ b֋cp䚸"@ 6fNwc.#pz(Ƈ%ϗ쎚ǥzZt.Ċ ҝr$U C5}%&e {~\ݙ1`gOr={-*sVt]SHX1= [ >a9QǗ5ď`\)%f՜:!Cf)\B} M~r{K:ڕĚPXʆ ?PXZG+ؿJջb.%ybSl, sh1sl"hbMٟBgrejy;op5w==- C 7{7LWWk@]nJcgkR5;Ok'GJ>dZ#( ڥ\٤Z~f}:tA4gbR؉b%9cAwSO}jGɣ3k{^soej0+z9J! \ ŬV54$嘱%nBse8#sh_&3JKvl&"z ֌LS׉7xΚ_}؟LIBn5+#S&V|0ғ :XqG{/+rk0kbh38#KݶIKoQ~^oMڰElCv}/ \xYg#x9ڤ 6FiqVA2~g%MDRXW*xPqaJq۳$`!^FJVoS{TFA #_Źo?,&\S716i̝"z6H'J˷8<όٔk y0NXeGq-g:25e ؋9ʝ9&;sqM.sԥ_rINsⵊ5SyIj8@=OBO3M`ΠrM;v(Y-\wf79-?5(::e#X#{6{SX0Uh6%f?uOAm j^ _YtƤRF6)*Xde;%b^n!zn\F +w xfQ1 s$!甫 &N [%|RIVZ 'S8&e7H gV6seESw>}@џX9ڋ؄K\M<""(v xEexwnǶ%\ӊ^LȚ{TX/m2*Vm+ z*:(8Iw ;uddΔa9V\\Rd~c6cO}{Ș푬K:}r(vq {؍@RCqȎQC` gs-& \#:MFD |pwN&]U{>I9Y^dh`pۑR[6'k :Ч(?k@ӽ{~E¸%y-ed``Bgx 7 ~{0#"<Jyibn5MJ&5_nV h۔GTPVHtJcEh*?EH6f0#(u>Kېȗ$mKѹQq6X<; k_+ܨyE0Z[RZ$e_d/_>sg%a؊~r-iή1y=:ow!)J2U`ShX˻*d~tRh/\ɦ8/.~l@zߞ$ySe.g_RvH^'^7ŽؕnâninQ2ѓq7òʁBh:ե_l9Y\6W/S>nq%?+߅} X&e0mL!b˸UE#(,_HNǚy6Η=V~mDypno%9p9=&RUN+ٰzO}0Y@]('jWGToE ~$ʙ٣d>mZL qIU1RLʂY͍zR7A8K&J9Ɨ:K|*lo~~K"GW Pg9l<󏫲3Qu%h ̫Q^M8]B%U^2ZWd\rt(h[ȕ%}PRlJѵaqMUQŴrsJʢb %U31ݪxBL#ɡqE̗îb4Lv _R-ǬoO&:؞-N1鶨s^_!kg']x)~^xpb&^G]\]RL<4Nz($,SpHl:h&sbdܭv-4X:khISz-?UYx(܈x[GO.B`oK^wlc\70fO4w}qQȦY%֜K/Ry1'c0/-%k#ejo\s9ׂrFѦ0}ؗȮb fK/lкGw>hy8#l9аQ3[Q׀u)Dd$N (cE]juJn16]Џfmw[츛;D&|%L$ \ȑgN¸DM>i ֆ2O6էS_<'1ϞM՞xN)$?=O"{oDb%uU%Ū2&KQBi$9/#~2j5vMTUլ ,IRc<6T;V(<{̶+չ\:I~ T7bC;aOPys/ ?^qJlrTPewj-k[YjkqjE-urAþFur2.&iC"5F,7 V i8E8ڐFn OAw@Xy(t" TMykhpԍ%d6朘 c}<ڲҍǂ-B94ș@p5b{:M[(-LRǍC2̜[ ?xʣL$~ՄkkCCO2LnDЬ#S'l*fŝ~+;_O>:m/*OΌS&*WN gq1>VD>]p=3hޝM7eNrJ`B%#*帯32@V%)9Rζ2X!;)F5\SņW(̫%eRhj?Ml`pRN5 ޖ(Z IP|(gw?F;ìP=|}"?P1mrJ淟[u'ձ䒆5,]J(yBֵS1 okiLÅ9J4Nsc!fD_d]قF=Wۼ1L:i)-83:c;lHfObtv!3a׭ičcy!luA:A|[$▦v* xOB)ߏ%Ʒoń yݚm1+у^^Ï_i, n7/f^5[ryoy*cK( PҥL ZOM4?Y:v0Gb%>BkT@b ~)Xek96w+%OlS6w}`Siún6x "{++Cp +ÞPNvs'hzoh!}ҍI<3;C6ߊwଳ'`{؁m n3ng]\֌Sd݊N]>\w 5Bn7Ŝ&ͅw]~L.tԳa)+u;/!;DVzc&2')H <3q ʈ4a,w2gJ =Waj&ǽK蹩ڴP좔q"/hJmj8]7 DvhyDfW:K*Qu)[|̟ₛ4[.v)^ƢOlA-6@ҋt5,ڦªDj5k?d2Ku$Us UM'jZ^Pq]|%2L&1qK3X3$w}Qjθ0}H4N}XLpc/6#vڲ`9AgGѓvT+4(nV_0$Rp(s#Ӂ>k0+=2LS9e \Avo3Ļ#fR>V5T=f?.Ay~HlEᾌ˘r§W3x|ez;}Ya^7;a\RsD7s4!ڦp5p&N)̈́t0Z9cob;ύ\L#a ^I9T)HZuQ3c Ure?-UVI͗Vֲws՜}g+ܪ"xj\߫yVӿ[-'+u-%ۥk)+`+fÔY)i3CA y+м.\;c 17߆9 յ.xI`T]\|Ro² 7+F3@k3{Zsvբ<B͞V`$wC`@1 *ojiQ8}(oˡTp\ŠkବBeZʀ8%0R+X8ĀມKH56CjA" +;!  grsl+ɃCkc=?o~?12=ii~0ɉ84(/f]Q9c,kxRB5)2<,*֘򴄥{B[ZS>3L+;yѣKju YM'!g;+y:G}qda|2_5W3EEViרw6裚F?UDRP0]Bʞ<&HDMqy'+vQ<dMRtfbaĜ3Ӊ,_ǧlԔPM >N,$iO:+£zsFqYe30o"ط V;["=ygJm\/N(3WI*5;8j)W//5l]$ť/\bݫilz(a!|cZɅmJC* V. fvMdfN+ZY]Џk;6 VXEW~Ʋ.Uh`BN,Gs>78ʝVt 7`JW[|"S VҨB;zL3c;~ү׾pe.WѰ/$tGFL½j8aeqJ+pR킌rq)㕼T((Yd(%9?"A{[(0Ps*DaZx嬤pj&Ѡy#Sż1CGM5{LY>YNy&ZBqlokUz_1_, Dh* }4/N[|\DŽCxwc g++xН"#~KBEPEd%ʈ9,Ԝ^U^z(Djͬe{5Lb_J- %v~3n":(gb3r}hzMı#I,lSLFV!NgJXTRCMwf߫UdȖG- MS6,>Ճ?ҫXxf;q?кy4ۊB5/ ~ h ǻr~kƥТ 9waoKz'NY%&_Ƞ,T30)Ä{aZj/ʫpLZvCa@G⻐/4sZS`y]h/D$n%07s}́rK. Es4gxVrYoV̞0Wv, b$,*I)Zd"Q͹/R}2 T{Jifһ.DEa%/so\M 稩K͘$^h3ILfӔUS. ~zQߑw4[Oh.o}kѪ{ݶ`Rpw#xا ckV,,P:y##f2Ixպ9~W|lij{>F1ې'+xJ43bv4Y`/:cboCwMsdϑhp1hrކ.Рw(!R8b0jS'P9yrcC[ot]=ΓrR3rN+$'G1$_p/¤y' 7W#iGz?I8l)TN3׎>ƷGN>v!acEu =xo?rCh>/auc)(8RFk{yu )'E}Fż:Ss`Q*6V2bA ,7AN y;eꥦbVP+h=FA<%j1=͋<ˍ\-HOm)]RGz#]+@z)O–]O3HΞ&ADžrMQՎE˖8Nh}񴎡e?mj_lʪnx>ۻ;!Y9yQT.尘 (5We嚕#g{3VeF.x \"3Y1k&#pD|<"Rg-Yo 0Ցý86CWX]HaoB]1Iϥ!<@`w. {Y Z⳹2>TL헾*\be!RoJFޑ񥙌l9%h5e4YĬ<E~0G! dwqMU1扒=)?UgEbqFʟE<օLXZ/ kF4:?pk(ժ NPlVx6/ AͪY^:=N$NsETdBvפ+˶tF}/*Lyʍ#< \cW+3s@ nshRøtΏ t,&2 VE{)5ӭcwqdqbB{:'˞ҁG &u Z">UMްQ5kntIfçĬz>Fc[z'78ϋ ! Ϻ@SiUp, 6EnN Bݙ=l"| ԘMV˜vi{UsᶒF*G+o'ì%4PF?e5I6R•uF5sn%9oA̚W۠wړY1e _Az5wYrU8%|2+qxB^\ڢ@27 oi4UR" Kԩ0@CfR-7Ioޔ7  I@3q$ۧŒȂWf{bVGavQGM}bvy_fg0skLOL<V?p%nVr!\cև-1`FHlqt/-썤F:xA崜S<2^U{,<}~".\3F5QO%,|DR[<ts/iJfJ`%>*t5m4ZKކ$ʃь~-f>XC( gL; :+BXĉ 0lGᶦ ʢpňNovDQN`q0^0lH5ڥRUdJ|8< ▭օt4 sV$qNg#5/v*tJVa r+Ug35?|OŎU>}I~nTB:)_+N$^#y]{Ϸ`cBxI{0ݫN,{hoR XD8򅖜=4_ ޖnxzPk>a{m5g| Guᨉ;z5>h99h#yCz"2DzA?.h}4߂&'j8Dok,jɎ[gM8^1-q ޚnXYvN3y 3G~ۺSs/-"8y' oPp]%7S1O` '}I0£@|Ѷ_ #gSrط)7čvd&?V 9PfI)?_V0Ԧwet&gd-S0I%(#C|o ޶3qKZB`Lw2Ƌ3f\:bfM͹%|D0lPט |)yх&~8fdN >qz]YfoT#z8cJ/65ՕDzcw:K+\i6-JR:(klu6G]#\5:Ϋ+8x SEM%6 ٟTD'žj$p,bIV)Hex]? "'+1xfE4֙ە"l79~՜ʭ߬/5?!Z2*ռpfmiS~֒㕻2/b۟3|NZ *ޠ-Q G{˒=/M1zٿVֻ+VdtiPimq^]ٺzgdv$I 3[nrk8_)e$* ^u8gbؐɂQmʻ~I +s@Li/Yr!e0i]EZ.j`W%r鴴}մz^ֹB'?M1u!l)c^t)0TeqzU[y%rk6-&Z<%=*rKFWK.+̵_ѧŞ/)sN.i?v&#~׏1xƝ7N}܁C7>; [pb Zr"9дf䙖1G"vԧEY1-o39؍5nӇ Ð?42/ưQ9 3*QUWPmd09w"Iģt%s_>v&_y+L=V .@u ARM U5ّ[ůc(ʫ=hG]5^c-9iɫ[W;q'϶"Lb~w׿n;)vzʣ?-ZZQD[2WИ;MvqcE t_fW"9RÒ$~:ˁ$ ZIat TGxk9y-aKéqLJrb')mz7,\cB2kUJ(eg9WEp?gʝf v`l7;Վ!N/95_Fѡ ~.cb&2}S!=LJcj_3f(1}07}nM*)__6ps_yXkpv59d_#yl" 4~/iQol4B[MJ^Zـ&iTl£# f6ER ?2\='^Sc aOC19K=ggeÖЇ;\i}ۅ9bq҉ [liž؟"ٱ8ʹpKi^ɔ|hWJld^?_;r|oӆR#N̎T;LSI0-!̣SU=F*&i:6ORD;-޹]GH+ABp`f߉Ҷ(xlлlhJw_v&;,2: Ti'}lI>T+?yM֭?T2D| ѥ c1j \:Q"1_4m NGgEْO?38>C8ݝd7툇2(Τ\?B8wr8K9*i=NT`p *M!*&yZs58CڬhOrQ9EpRdz{8'00QN^gL!_/f^,YíhG3jm8ݳ=Yeéט4ZІN[1D /3.LH6kyebŇ tkw[ȉ'NOM6Vk6m#Y֋xp֋I {.A+xl?aOVq䦺O˜Vh]"ʚKC#ޞ{+-YtžB9zc2Uލɤ~Pr:P6inz'x 0!- Ɯ鬰LH\RW&4sǴ$cDq(Gp,WH>@qqhE3;C]iNJ}yۏ=A_?;;*3]_/!3^O^ m%R*UT 9J6n/SEX k %P΄xxwZYxoWcC=2kϚe,Kƪ=дC*6O : >Cb\MM#2LxaFc Z/!'GrhkV*oR-UUWyQ}gMWlRi*<{0}NE ~|p48wqكTh R.+c)sbҏQ1( 0] R:* yOgm9Pl˖s':tdWƌ0%l FH5x6Ջq7>ۙukQ[n҅y\^}~Y/J-F/51;,դZɑGʭL]P40KvpHŠo7d-]<˄YVa,mK@"|-\/ @?0<Ο*̫IOr&-g[3\Uf4lȞjٕܽMXwcfW+zrgv؎{)ϟOxlPDf"?Γ:RX,/vϵuzFz`R(Z->ޑ{6Asd\`!77MMv~/fG'orz17'+O!o7`%'to^wq+ia(3YgUTT?g^ސ;?+gl%ם/=McC 9x|i3zddzdI1R/F|A&9eHCn}6)؟eqk[3NA-CZݙK=W,n*a`GZ|kCu2&Y\4G#y(uGYݫrO"{Hy颔_Vi^6AQtHW2m$wۯ8E+V@qh8'}E7$uRc;$rq7yĦ4|LI}i_]+ym'ɾ`yːRwWRdzCuRq)FPجNiPjwᖨuAvn]oUqߩHȼ9[6eEaMŧ)K-UH1N]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9pbZi"M!]n_SlA?xV['cRֶtI^%A~Z)?2#G[%O=7}!=im&E<{M!Iwo^_k,m ޭ0^ x _R]Jsy彏y/vk4ytw\uڐ3|bRAKRgfirх)>_6E*ʓzs& Tg=7ofʁG.xdS.=Izz``}Rk阔ߴd#fWi-FG#zIF^הo3םeM5mya/y r@/yYCl|t8 E'If+;OZӪ%~7b49}Hk'e.vŦZ3P6NJn=[E;xOϏK]ȉ.lāYr5Ϡyt|Cr4'c*y#o8&wmغdžaf6z6yԦoGc+ κ@"UsN|.7ù|I;O:rM WzINh/]wjEKOyf<ؤ9FSL|ӈj~gߘ7x ̾cޤ3 W\o)CgHoJƩ,rׯS${w?L⃦<#6dJiOo|W^9`/]`A &٢B}k}TOϝnL.OZKޭUvSuO\|N_I̴t3C;2z=9+ ą4[荏 V-Ġ|+f? 7 }A8?i--ߴFuo1d'{N n\`U ׫Q6{64G|=U)ogTgD o(Ѽ)|y'%?%ˏwv`xY7,fs:ir>|G؃o֤SЇ߂.\ F}8ۃa. ey,VI0~9K:mȇ oaWDӡ/7v!/eTעGn~oLSLNU/nse+/ id)6SvNCyR6z7451 P B#y_;}.lRBvbB֌"(}_lkȉdՓ|؋LJ\]Y6÷Mb8G˖cT+ pftƷϡW̊w_ܨ?ZR2\u[6-#o^B\Ef+8307I&dl*.qŎhɳ!4e/ IYHBhp2qBxTϋ~tg "cQ9K> /;#Ռ-/]9q6*_4̞$s+V8+fYZ5D1"Cv=O>jGuCe%MS&RK~5|w07bρaqs8ORɢƆoesDtΏ|C5e:w`s~0ÔC=-] m˜Ъ!ӂ-jA\bo4c)n~GsG{g< @QB}"R8r ƎaڅT컄3=̜ vpNdw^2n̰nC uNykLΊeV&Ҭ1_he@A]9ˁ7>h\`S*:ƩH/Ww߄%emLoц}ͺQ׍jFf '2W-ёo^|9CbB?aѬk~>QF V2l9q${q?Ҟ-U$4Y#q.`pHr^d͵rL3qz/r3#zeS/l+Y~O=(])5_9z$ǐҨy~Ͳq+Ԇli laND8r#Ff^ ~,3Fd|" |ibg(X;bCɘt- 2ٞD(Js0 /8ßWp_=:) <̔fGhј"{vxd%̌TS̽!\IDjb i-`u@ #?Q\J\"ٷ&ɷq/⥜AZ'2}qʰYsH9a#0;]vVv-s.G<*i[$Rz=@K2n+Auk1]T9w򆣡e^9~T5͔y ak"eT¼MHi+7VX۲&r<~6%KJw?8ךZ N6|=͂#[m9˕9W|8џ^΄4GldM=Ro\_)lV5y࿸ K+O:Q?".{3ke[Re863}ѣYs42-!6-_{1. q:/kIfKqFPfٞMexjM%'08P>VP}HwzҠ9Wό7v Z5~R G}= Lh$ĖU{g3mϔeL K|[ɤ|pO3 2c hiN+6cr*QCo;D[Kv6/KyvYɴA_r{ZR;71zqExRtډMtiG|ղ z.Z߉[I@ekd173[iDtb'7hmC=quQ"*L Qc9ԑ_ȓOE>Qփ%|(BY&v'"!<|W͹i!ICh!5ЇA /˱y_;X\",y$rcGeMx*'pO9az>h/Z eŦa\mQ3KiӜJ5 7&.mW3TEɺӴ47} gH͟]C)ZnӴW$,݃-99;lM3h3G;s#(, gDG{o~ݿ"8ocX=KGR8;ͅLCs% ɘ%L[TIM5kQŗ5H*{^&5L7cpܹ>D9ֳҹi_+YUÊYpb̄$9j1B/c56PUAOBG1a0GR}nc"96&9p nʛŹb_&ZLMTh9)]>.;FOZy7=AtwgGWPԤz[D'sĢ4|`yMty͗r|aءTڌ [MWLͤ2 Lڗ( Hv{,. LWj(nx'q>؎$SsOIh_2c?g~+/e0?G<L{8^,7޸|VW'~۹?LJ3`4 5aт<_yrr-{Rin&6YFbcfE鐬]צ]#NjvfK^w&;Vzbh.]w(st *>ƅ8v0r ȴD=G\C]Yۓu>|}͵ /rU!s{<أ<6+N\*Z^E*֜avٱxd &ݛ1̠ܿ0c$?] +F;%8^o$7nrk.ݞlL`Sϡ>lރS;)|jiF'[#1@8Ƃ_ve}';}1nUOC A\mˉϷढ़L_r q3tÆz߬Ds?4'hBy3Ovʺ9ը,b,i&gx>֢GqG9l ݕX yϔL"h.h0fH=-0FKlz)w V+ȶz/7hw9ֶ4`NRJA?RcM(:AѲilVU͏%;D\p)'ej͵X'MXAWr۱rh Ǩ&ǧd]nhf.bN@'~t)2tG5h]fl#|Hbz>hG(5|Օ3@&f Ai4OQØm3J-5Ғ_-ʆ잮P,CUDQXWUeZfq5nCk?n,/Fqd 7qb@8 }Xcɸv_ 5$X2:8ے< .% ƿrvӧ^v[1Ūn & f{%|·dJ;38wlBhS#Te~MyzřytZ\/'uעK)IC7eTF賣\Lݒ3Ƌ'x00$f2V:+)>T eV6I("T}/`Մrf*G!fS%Dԛ×Eӓ;u&{֟]n cPgF|Ū!ԌOWrp{x3ۑYZ&{ӗzWǰvs {|h2 IL8X"dd:fcĢY7Q ygĒ_:%nC9q^i߫9;}9]Ŷ|SGXoQ},F0mU?$:Dž wcOXon{V)ZQ*u}ys"#LppeOW6l}qrs\?;Z,> =kyI`-jq%g%H!@ $ ݴ{7w7ow0wnMeWuu5 yuN'({_z&{F]|!zc9&s fIq8ja||RTOr",?杜s$m2K &bѓq vñXn+<ăEh5ٟѼ>]@QծbiSq SɃ&`$#i|E}Tl.;?So5 M1*(Td+/=Bq ˗cuxW\uZ]/Ҕ?z(8G^=~ ,ľiТ/>ف-؋P>DøLZnY}767d(7Δljx.IK'B3x͇ԗ#'j6PVKaC=V8}ـ챁TZnfk#k)S%S=mzy`g(R?uQNjz5'9 S/C1͟VO^6};'7JQn NSA#Ow'Ie?V!jzC]1|x2(t+! Q}A2]$ƧOup6 ^T*o,28T7L@g~?e YՌk%aze*v$Jԏ0:)'aͬ<̝.|/oLc"Z֌}U(-F(r8s<3= cIPkur[%ad81uq _6,ά;&0%c?'{QF Τ/ͳTOwiW:h=)\5sI5'=9̙ҁl˒]1!\r} ގi$s/ܜ2Ή+ft Ù ]64҈V6=9fgèǯY:RRӲkf&52wb[yO1q!Z%%6bgڛÙ@{?A/(3sM41՟ 8y^oJAOng'a^mJRav zͶ*[&8P&[rRr8:)fc8{Jd)rg%r?:}jTC11k,T7r bv}lʗQ9gO";(z03vY|UGsW#+kV$y%h2Ihe]c4D廉N:2fd}׉ Xժf$A^1O=i^vg3^ډ8|<9? qDcz8v'Crԙ~>n\R9?z y0Lȍ$HΉѥ(9,:Aiؑnmwbg5ܻ8;r,A[ͅشTRW"UW=1' 9oIX/b!l+sih%{,LrXNcH=5&ӧT$JDhpdmG)nPȹuGŗ 3HT{s^S<h' (~Rl?+r0F˅#2Ә<.K}0mӝ5918\xk~VJe]$:Wގpxe lk"vȡ4CxEZ ^7_&e3:1#*:K>=VH'S t,nUgW=BChvS.w%#g@:~9yH&>exS&ҿfl0sQC8L_5q}~{C 40+OcjR W. <0n'֛y5e ;;S%70I6c(8 k^(d=I6B{[˭hPgq͈ٙO2NP~e=ʾy(MXOf[񏉁azSIUx ° Ǵl!ՊYL$~4N #*2QN of.#,ewgDWc. iRKC1qBIF!%ajΦ*u;mD ǵf(e stX;mLhF+(,>lr)mH9 G٦$^Ϣ<.(.)J({%yڑϗ|֩rħTOH96֚Hw'zPՃd%%p襌/"ߞb:#ωLij%ʎ!V|8lLv,h3G[gD0Z %3{]4'{z, oI5ZТkvcCOw>^mΞ5u) Qʦ :+EfTsr5U~ɦdYKVF˛DsF㋩{Lq_uj^+9##6PG'Nn,y(ȺFwsEO f{əѣՂ-BCAYt;E?b7cM3"גaQNJ,R1N}]-µ==Ѫå9Z *R;1UE|.%sM4Eti"(S#shd\r)J|X.^.UKSWcͤ- jlr|i%q1 [`aSb6;Gd/-̷b0 =`.[);cFo`%O*$k}8ǻM/'pKK|<ϡs\[ǖqT7e v {E?F[I'žv$5KD{-vkFKHޓɻ1ɜ&cDioN#㈖<򲰥ϵ^hk~M}W>:r`Yi'b=j[nF64Q&pƽkC{iKG= ķP:g]M}? nVot9ȐU)~)ep$5Dt?/ 6ڕ]IC'C`Fв<|PDB2M&KPor\QvN*.TrBOL"N,YReR!R*3HIJ(Lm5G)x孤Iwsf:tt FNJ"X;O\{f֋]f޷K]Ŋcg++X1lfJ0p ,N.]b6[8C'NxDl3c뱉VO70rKhoKIX%ki*?򬚌".KCK,~ˡ_c/'sSRn>d_nv/Dёq5l O w7oI2FͣrI2{*G8SjHb(1%-bjD*' &m#ōjt^;_p-3A+7sQ|Dgec#SZJFh13O"}{iol}I$),NJ_Yp6s9yme x-b5X@M- 쨥荆u}j]=q'h | m.Pmn7 X7X(da8 ^լ˜rlO 3S-4)nfI31&L_md#_(H#v|n Jg++ ۤQ%'ƪbQpFf$r|R8ǾKi( ~U{-N*tVRD\6DT1s1u$-[{EJu,ފ,<)5M"F׏x?"\G|1o%#J_qOF΁yWJp-Fk2@z֓fa,-=g=Ȃ仴%Nr u ;gyyd5G4Xϫ!mAݕp=] @tĩsfD rtI0B"GT6AFש2lKXQH&G88c}d!Z瓱6ӳ8lMvP\)mDO] gp+mJпб7 5>Z%??3Ft7p sXIR®=%, Q,x0h+le*%mbofBl&/F<v0s`4e5k~[<^4ptl(UP|>V0ek$k7Nf.FvHtYwPW/TCx)qyOMH:{uo"z]VDFº'(b[PnR4YOYCǬ>0szz+>vQwrwT͟v:MtjQOHI7yh<ZV%Ч88!vLlʤԩBҩJWpN)|#~_×'/ U.*.YA E?NK0 /9$rPs- |ifqm M],4)%+),O]tyZO)k)s)N튙u$2^7DCo2={ u%L0s#ț"DhQ[ \c^=%4:IYgXa{̇ݎ?^:rOboV剪ځ!X)Ι霐1f&@n;ju0+P3ǏB8!ەljŁ#M-S+K.'fRl&Bw񧜞%%5qaCk4g[$1w rqDwg eN^x1;YyԂ\ҳ&1RynUO&VIpg~8}O R VQQ2y(*ѫF>d?gHBnO.ff" 6yi\øY!4ڦ(;H'=o* dTx+> KI ЦF!_q.a'04dR&A.7G4>nѷL^.M}"5qyHTqyiTKss٫-]]v)X#q~tmE#~F7Rq5"HqzsP3;L2SVlr뺙̜ՈČ&/2bkdRkJ_Bb|x ˬ@_"ӯv0rLF̆E䯗@`5{J44fjK5DU2MB .ѯ^ Jt(QiL.~Xw>y99g 7;0Nyc'PǻϰkU#:՟1Ӄ-"g"ʚyt+S੥1S&Iy87Cv9xˊ.g;V '3vM>~|w㵬?eL4yd8Y1Y^'X]b*j9K۱{JQCtԬ\-a|+Dߨ)›V>+f+WEo=Zd:&>9€oxu\tr0P̲LUE>)]>GTl m/ZB:("q7)wK8;q;=pRXU±ITC8$"G.'$h*f2&cWDFHL:pJz0L'W ,G [&s}h9Es&yiZ6?\t\7y)i&+j1O4_)2FJ>FȀXS-1{9 Y#>37o)f{boPsL%9|aH)deC8߉?z0e9.6{-J<6o\F~܅SuB1=\(dB^M`:Y}V˚jzRE1T?:U<ٳދWY̼ m0_30ƿc u>_r:N)[8->%XᶘŌ|#:3\Y[ǫ !0jo䢙kDmSb)EQVLG Q4Izzֳ(U \~hķ_oi跃TQJ&P!M¾r/UtyG]5K*fuU0XļVJ :)xo>0Z5a BIӠT:FN4>x(R=Y7Od:=Tn_fT BHRɓ)Ƣ҇3Ls_.-Vʢ%&ەٝKicmgT+íh,sJNcy΃c5F2HwCھte֠#AdD(,6_=4o#,TsvLsR~3cߜҨFw/ 6d2Oֹ!WVEVK,fT2iGBIx{J*=Vf~Xcd] BnI<['Wk5)'6C*y (! T:a\Va%A3q%TnZtN7#uX̛3ؿidv0ҶJXtq36䎞ӌx\66@\^eF.(T1r+ĄFK5D`w;cx¹<59pXb4l WbRFspK^rWa\C%C!Jr~)VȂrB۪XKZbM37 Dц %m:%wb -ǚxYy[5:$R;5?yrێnB}w/WgW[Mex@8{dT IOȓz31Whf.Nf b$_bXIrrduE]ZkdDӦXt ̗TY#9=r:\򖖜CZ15Tc&#Gy ֲA$ƀ[Gz(ٓ:=WdҚE2[E^^G~%OawV1M"pEpdMf]!XhUզ!EsR~ZM327{gLNMgb^5AdgUIN;1pP>CMDј{uRJ$uaCyړk EAt<4W=n/67|(>țy!)o{ ?X%-_W֔|]Cjh1Cx7ڗug&M؜!gQ>OŽ; I9s2Kc]E_[J=Vb䩗 &T EgfL+../zfV7Rc.pV*Wj(mƵ`=+P'#ae›MC ݌mƒ+Eۄ9u~O_4o fDN9btIԭ8VU^?b#eyEd-jj4eA&2)b 1_dUdՓpO ; JUsVqz> -38C+櫆'୦W5*%crUE:\.^g)nbF=jk(8]D@|MKbCm &ߧðs vPĊo yCFQfN1AsKܢKmSGj4aMZvTjR-dm*,v_5n6Ğ"4r󈉎+_F?C 9LG-p9y 8&pw[M&\<*tGXmCh}?Z >ӅȤ9B°O%Uf׊ ![Mlz)lזԲ6]?Lb@ S 4ňK S@M' 2[Ro"wRrrqYre=!rtZ?Z^EGePSߨf t=@B n+)=bՌ]&"Bב"Խs<7wx"b*2ҋpF5Fv !؄YޝokLm/O2&3;H XwMӶa1LccU\A>w~͹?v|p@wXU@ fDx8k8eEWe !x&ܩ>PbaaɊLmZJӸ0#1Niق&_ GyC…mɐYB C;glCj_M]n'mgxvcyLsU%RQS?.rH(10TFegH2LQQ Sqc?4<\ľ%-|%ZjȵLP"g&]*mG Þ?SG=q 9Ɓ]Pldf<{1aiY{o~é#։jqg@e*-fƬmjUe^r~x׀y^8rVzRa 0 :cK 7DoI=eb ơe<ZȬJrYuDD+o4Rƚ X$z=̜g!q^ }"3jHCW~ f"Z(`a/(0 H AB#a0f^"؟:._ϗ ϒ [tUEU1ٞ'blybs{ϧȠBe?׭e,/ec)E_I9bj(~| K/_(q6{v~u &jHN+1+*DJ1y^ewU=9𭵞Շ4[`dbiRS$M׀X:oӬ 3&Qd>,G{\Yn{hdeJXJߑV敉ǣ}1?v BD;64Rݩ(qe=v<,ヱ4Cy|6Ł^ ݟ =W۱ N\?zC87;jTrPT- mOؑT^Qm GT/{?PUa+![8a5-0׍E&r+V{Ubiͭ}ČPi&&p{߬,дK,JS_Fn.~*M8Ƚ'pyϭ7 }#,P/kD[֢cveE V<~?:rgm_J*85V }.N"Sq%\J)dpC-r\#ad zQ|eK> h]jM!{Iɰq|iQLWp"7-UiYavK=ˌxW7R;ŷFV3c?@r;$"i4M>' QT:ƏuY)#hWׅc#N&WÊq :VY*pB1u=tVBʎ5EYϟ]IΜ'(u01'`sn恃hݍ˺2vewE؁G> jTw󂰨w,Xĉ}HLyJwpmқU0~Gc ϨnAu:L? ap5t{߸H|8u/MduI~4qx$ kIp}F9 |#{|@ F^T20qP==~qRS&jo脅gͨ[i7Pϳ "f\) ʙO/Bk9̯xMvGBtcO;3ܻ ,x!l'AvSJ-iM"~0Kr*凧QU@Bf.yH–3R~xh_ዅݒO|nϷ\g<7UN-T J䃣RTcw#t|دFFKLugjrwd,hͲ9Sߝ)LA47;?_#R_<7\*)G)_LT)m(eV2w.+.Zi<E;8g^ly$4 /\\=rX67CgcsiӀgm[PqN e7g׽Z!_KX57r}Fv;i7չ վ\=H]?_Pyp8jG Z2þ} b#~ n͍--̣}h.ڳ=7 ֶ͵gӟ$$楱[} 'ce2"։'dV1FƘAtщޠㅷ< ]=# eys FEy3;t VH_ZfVSu"N߻ьiن> ] zߩ"suBCM܎N|Ol69<~&];JY'APBΒl*> %4y <'!aIBB2m$$^X6,-F/9k*^d:{oGu&̜8I1ۉ1ffj6033τ9qi Ǖt9?4eeUwUwֳ\*c[j1;ڋ;ױcU@ZҲo޼zTko̢w[;<ŀv-IG2w;8TU/oRMJ|RK4PǕKHlͼo9ĉ%6̄=M̘ZP#TSe;lZmpcǚS֚^zW>7k:0Rw?pyӉ4*rx  #,f ~iVXW--a@9^9]7~9' 3 esPO0]7l$}OM^7a/ xbTN^^i ov7w#y+8E"]w 7xMuc /l&m&qΦI /i̍axQ[ãU r j>_Ps]נ9AKN7hDr zcŜF&6]1A'Y'L f?b>p Kb[ݖ39iB Ưӥc?(w#x/Y-yXhal] :դ[ͳJ_sJ D>*:FpEsْ1&4_=^ųÉ9?M5ш ihMzM{w, uF~ěy65(=a6u $?߃^|HWnoc8Y7#ѿ WS' ]()'j MPͮQOO\kNxH806;{8W!xV{SlrW"][lۻVL(m831D},, -&l53 0~})Rjl!#NJ+b96XV竒 \O(Z_e.:Ebͱngb3-2ir)qo餜I!]C&GOi 6 3Hd/ٴAɼJgtzV0i"'&rrn,01Kp G yƑlEԉUwfAZK;om/ ab!D}Vd<Nz.d6x2]v vr~0Ua5+{Tr漊*۫nZC+wc3y҇vF# 4z13ypϑg$u_Ylǩy^r] ƌoQ瓩%c=44ş##}a9tymX ?*a IA8?0OS >@bkX<70I Ku ӳÜbWF R3xP5C~+S?WI%%'^qKJLS4.X>8U=Z&'S>V㖐GMﲋ8Z)?,R Ul׷-]EP%bDFx'ゖe2d!RXH/w+}P,%rf3|8~jDHS8QYI<ۇy?#I$Y'3u<#[D*VQ;. \O)4N{-S㛌m"~oRz<^zq$ ǮY tkN:ѯIȈEy23B!a ՟bm 8) sV8Bn a^6a׭Œ ЁDŽ0}"s.PjUj|]8d >`[ZޞE t;W*s i#)@ ֭2xõXΊ@ww,xY 5>ѪZtH|'mܴ ׹01뻎a{'ywƝ(mYCLfa!e,PVɉJ238HԬWNT)G#;Te}z0S &o-ci网 [xbbt4xa$8U^̰"ڌ)M=j+yYEc\_ 1#((GJr,'&@ )wKX3Q‰A$6w! .}B1GfID Ob$D-yB1͈I+,l\vJp9Du2+%(ʹ7,M^CMy&b[|NsFTtH:K%1wVBɰK 4ta2OfLeSp> \k}N`|'X(}_*zb*έh=a )j;ղR{xq4Ϻv"`\Mt#b:y=8=եޝ'7 puy4}0_ ]kK~R>JSVƼ3ZYFBfJNde"hsF‡GcD'^fJ9y'Wbvk[nB}e[ 2;2u Xp+Q0XQt4VaȠy/":ޔa*%C+HS2懒 BH6'EhBrHX>Q+e.pgj7r8ȋcEz'~zepnS0-Ws,!u Vrv\̮32(ѻ!'}#Y2dܣdDV 1SPV:fʊa8Էe°ʧ/m G~,G%0/,8vi,>ʔ4v,JgC ƒ$SCR'*nqi<™!ÒYS]K>άpS<_=9Ի+탰Jx#|^(҄eIZN`it2gĽ $t*!ַb.SpS5` m5p#{50uB- k5](aSkkS_"0'גG7he7gv+^MuegxБMg[,3'j8[ Vt) mN>v^VX7shHuނC 8j:[6qU&${e}RoCK&v6ch͋ffIEtwc%+':b CY'YnS&TJ ֵR3VE6r>Ḝ- ((UCC.G Y1H:e0$/;Ó&dK'r%ʞv<è\NbQݹ* #B).c!Kü\d)vQY22ޫD?g;)ďGK2@e3ǕĠᘥEqw4g-ÃŌ!{t(G;<#38sqLa,_:3F V˶`3LhX&;nsлĝ1Ƃ{hoVy΢97_ Ϲdc24ɥYW4.5ȫ"4{AZ:j/2ճ:rgx+~lvliOV(\ۤ1l*:Q֚+fIS#g4A{Pv`D*|Z!ˇ *x^Ζe<TA֕BV=돛p.War#_CMY_ڬ:( u;p:_IdROWMb'l3RNq +)xD?v/;1;}=<). -JW\pi`7M ܜn4um)jk>H[\Fy!&>ӔXVnnj D uXJ9-f #y,}YrS#+|> V&r8!Yijʓ_0>E`78+CqtIfD1Ų6.cIJ:Gx*'Cr31ci6lm5^&1㘨˪L[0o9r Y(i@p.K'QU.Dv:|:A[Ϻ.]vgTWri.4XMED54 UK֛Z֕\_N &ux?לklFB|.eEL|Pd~,$6LeJxHlw@k; e\TR玊6j>OPdm'ίW~NųPd2N!Oa,ުR MxL=&d5{LfcjK9g112H<˶~ܾ6ACy#;!ޕFh>R)|#l\hQz+*eJ7lWapIU|da #U_̊-$J7^8mH}ykҗ !<xo4-cQ(q܃(v(JJݖbv+|b\DM'Vh]U})m+tNFnrft>xrU"Xf&<A 氎w|ݟ zD=\KYPg&26<M߭3.1c0p/ls9NdI8 M_B2RE~)QҳAΡԺ0@TҧHVcv>*$\V-> ?'y"kNxٟɴTaRE\jzk_/f:vE +RhY``P%?qKo&lv;>Oؑ,1au7M&-d]$*~;q:5}u%&f.g2kFMj|ddQ`(]|͔m_2f]j";.YE) , >ֳbߝOh{<7gsA+:*1g8 :2XrZ#r)}%WS1 b^N.j h,=qvLLH}i;3۰*' isՕ8}Od~zKqe!e"m\\],eKbyd8(RssM\$C>7[seSo6"."1c= KkWo:v&>t( 8ű*'(_@fH깲f,e{{j_,}N/2ϤX1MZ}ZLd?zݹ)OEuB`Qp-ae#|cWM?U5h֐}g]ŧJiYEN= U.SB NPp@s .W/KACTqȯ, &? x"'Ѿ*V1f%$TPƥ9aΪ3Fy}Ka!Kz׼] !ƷſYz6B^oRp@sYXmX(e4f[L^ى=}~<*`Vԕ+Y+9-lZ fTp%GDcEkgjiռfIt, XSlfH(V!I*dL_Hm\D@g$ %b(eC?)BY;>5y`Ȗ sJʀ z4@V j*z` Aƨ~F?L0cl=eE#{̓):>TЧ{( |Hy{hzsp41>'>Vsp=Woza&q=6c?:7Ũihd]=CMY^5oZ0w#A.9." p@=־ozvVhs!xgԜ!}s Vr5&2j~ [ "h.zK >"GVӿ3j&ԬvQ3hG2<ĵ-1u`zKosSH.gVJ.i!"֡fU241=4߰$n1ftgC&[MM{ ȝQM#,}OxTo1 O b:͓ر攘U0S?͔BxO2UYׄJ&_PQ"- V/ec_o>DzBF.gZg`066V6Zy,KڋW?!׶eM9<14c9$LW ^ x<6oZjR!iĻ?E2RN9GוϏ|ST < ~ ?s &ۅu.8ᵽ5$/M?›<F0NZ?Ɉ>7fξ-f'Տ)؈wB6uXd2ꆢz؞g ]n$Y&4UB;a,8Ձ ٽ͍!<:lSڜƷ=)HȉP<:10e۵h2yn5k| fi9oZs>U7u5߇TkyśbDPŋn\F@&.G/25EmѯD^PEUfW3{o5N3+=RAX> pVƓ4w3p!g0Tғn=YwfDӀ4A"*b|6MeP;g_eKC3qj Pf{TFŹ.bS΍ml/&2ZJ\B?J8TY>pnZľ2*&Bs*pdc `F[}g29;Y@5)"Χ Ѯtnn9}.rQ5[ӗjh@ T2?תj3h71*M덷_?+}}jkLeƎ{5siGQy} R<ؚSo4 m}n}"x9ّhœȃtN7_ұ+ sYEjX<9"8];)7$=0 c`b'Et,řndZUG?v1x$U)<Ojӥ>o\GQ{ƹ[=2ܽ]gDk >_S5>d{1U%'Q"yssX{%\.% yjwTS5*+oJ.~/d \VZ3n*=ui͕ڤT;8i8SlAjBc_?IMb."Z6/ddp7SFnϷ\>0~YYj UtKRc3?Cʽ201I bV/:6 H.|g<3Gi4*bL&C,^<`,FjǠ}Ê'cY͢" 8yr^-[2,ةkɂ=dgV :'[8_pvw,m8؅ rę*?T;&Z5UT~*\/j_N,hc3#}7}Y kv f w TΏHF2oq,bꟂ =Rqrb)^r"Jx9/mbIP52K<1'g&G!xHt#o6rexI`4φQ| %)E[3atr~jkjTn1kY}=[žh'ѿsURHΆ٥,)vQ9?+}[ƸJrvɨj+9Q VB]ELFa֌`$3VObQ].'Nu#bRUSr)q3_9\Ǔ?74RwJtVȸUX ˤ&;^lEO;eE h7$_y '/-bb0.aGc_IpMO]fχr?Vx}K6;d+x2)pjJ3⦰(N5,oRn5L:_%Cd'AE`T;apocI/YƻZX Ec A8ס\8FY4e_c0)H&}AD-Ve1o_TBu/"WZE\(⊦EX4whATo6ex%;-cLLH ر((^FC|TI<>Db _ SrЩ~ };k<&F ]Zrb6ևgslZ=Ѽpys 5kR^u+l♨&D쮢QUVܯݽk8\J'8)0YbI)ks:]^섍=zv_DŽ6]*"X5WfٷM +ū8qND*B)>llτ;< clb>R5PyJzVAMHk`.3qj@͢e(. LYv w;Z"g3F:;q=* 0|?nz$/ ɘC[ UCG>fF6P!2bU`Qʻrwd򤭂8%(0--|DnBvبaڎA*O eѦpU(DϽ^qLA=XB 6N‰=YHa4~\M) $bE9r}=L\Y6^lȝX6wS1jc$0!dfH?(}h3768lgdx'VjVkdqC-s=t\ðZH}4OaZMj8{H ~cZCmf۴JU`![(xJAc}d[X,)&}4t8͑pt2-l -wA]g^rMH|=zd,Ź9VCxQSrR *~TV*leLU@x,7R h/^1 -i!u$ ʍ ] `pOZ.2@vDE= H/A]EZL `)})92H!|q}]67ޤ&4I2bZR&TCy%*.nSJED9wQb7K/Hs>Es_Dpȟ . 6'p!If>Pϵ >G:u3bSIPLr2) ];i!䏊Tχ+DWyToU,hTM\qR||X͓RC~@C.^o9{+͛aKi/=Dkʰm1Msfl{&yc/7/l 'zw`ӃmoN!dLZ$׾9/ ^Sa+GVzN*`?d$3 DXVF kp?R:],jPhҭCb37̢,rE ɺޖ&M-2osW&J(,꾦R5wu3z%λ\%Eg TT W[B*,m1]TmIzk nx/H퍧h~ ݳpVS F;47iy6׳tl2d `=a o\D=sǮnuu~-wհ{59\}1_y%*E%7$G7{p6{칁ȩ^T: 5W MF3c~a5,A?7JYq5>JSl:H8XFo`%ԕ썬s]T򭷘Q&93nO,j0[9|qdtY7 s礳k*86\0i<:v]jS8;{L [Is p/RGU`qJjT$iLJWNɮ f(hAb&Vr_Gh6<ۯ&QI1} jY=~ 0b={1s OW0M"ε;!ʯIm.>&μ~et)j9V{2J#͹!86(P%4[!KX{KZXP{M6=Ah(^Z95 _)TRY+KA˃ ; tiQWI۰yp{y01hzHZΚ>ّ/I<|q$ܾ(& riGv{{iU-sF;pw* WcT̈☮ 3OkƵjNij޿R<@.[GS?^ci,R0!hr#E\)S4._&eu%ߊ+yyRU˪9?[R㙠/{/ПwI0&H0ω+%:f.6 c,L;ИK'3-c 9# k>͘ܞwrvknYeQ`;? S!tPA\qrzj `n)^D.>':iaφ0u)ft${Ka )qliĦ {$ERD3v8ָ ZJXUjUIjft`5_6V2su:M¡}%,+io^^0n]-qf a%/ci>MS$L[[IX=$nIv@1jrWsȺjx~YQ:$mV1:ƛRײeuS}y-ϒ4OAoi59RD!-U{vv[kzͤ%YBiǣ_Iu )LV-e !ђᬾyt]Ub7)S|EJltkS5Ǖ*$\ErdqS;uRja>c1M?,&rmkG, brVM`.5r8q $b޸arP:`ASɦ.5'Tӝ 58nlm*HYbhYMcwNʨrA oNvdi=>I䥆R [ ~_ o?aqVfcmKDPs9\դ,`k>ʝ,vIw,"vw5VJSBܟM5Ƌqb-5'Vӿ%+wWլDa:uP}QḼ֠$aY υb$(H<\U 7 ;{-54\V ٪~4|a{q-a!/4lrK&/JnPTH2Q쎔q-֩tcK8+_b M jC+-aELN۠4cП҈SFX+S}aVAQ;<=(4D+[GOޗ\Y5AjL| HvҸ$?τLzI>L I2@L=%|9VSjd͡naJ 1t\Ѭ|4{Q:pFMD]wXjbb:cӈOJ*dy:"ѿc¥)wJp~*ᥫ9bFJ&'Y uJ *'I9}K7&SMRd|$D4mhnRēR* X/#f W(qQ; v-2V3=%B%-aR ޿-,Cۡ2.ˤ\(fθ"R5Xtq*赢$R<*r%P)j`ZCƇJdUZYNkHr-a}0f B7 uO)B7b^F%'UpW):eI%u2ՠѭuPI7 sbT=OvXs#mɇ[h2cH{kšNX%/^4i?3O#&R9s%FR>oQQ~:9JjoD. e!3KoH3Z-0%הæ?3q,ՎUaJTt9Q<܉iK`䆹z|4\vx>yIW@#b4䡥rB;I=L#edtʤRVni-cU`d4ݮ -'Ea,\ǧLqG<-x& Z_~%!dg2̖Q5Krdy]F"vWso1Z,_m3SC=ѳ\-F jR{z(!>]Pm +T\cRB2M٠ia>Zkܠ3:IXJ߲*j~U]OWq8QIה 6bκj XU2mq5}h:gG5'Uj/ysgD~b؝jFTqW`WuI2!y Y(}~υSig-Ye2ќؖ_Mψ~z`dsi*̧DTgFrU$]Ff0's<>4r5^y4T0\~$K]Kg;AVD<fV4C4-EJC+ mvxB's Ot%؁E/4ΌүJѭt]0DeTzfZ ~'2t"! pT][JRTYd,dc-=W YTOKj6R2 Y(D`S_1TKD71C H3/͢4FIc3S3[P>W"6w)pLPE\h/]+T2L|t(ճfz_]U^K [(yE΃]Rb~&OGe?\4-OsZoOeC:s'eVLĜp,XWzzT!]\ɓu:~.e7p_xw:2]9*XTVլUMj3h8o +D~%C*YT/ 'dr1~}/FONSh8q nHﺑtؼbO,"?1,,L=ؙDIv|>GIhPJ7#Ujζ;eAFY~ !&^KcG6EՃ)xJ LCC*kfSJ>y4~.h<և7G=މ_8ݑu#H Id4sC/ 87;XPM ! "t+TOD=RLp u,[n/ {ht9}6GaҋOq!I9^'Òx-SyŤ,AxF427[(F2͕* Q)9SZ mkqݯ#E)<'慞J}%B+G._]N#Ke)mKW ~"ZAܴLdu`\\P ed0 c'ѽ/*/3W+*T n+qV`ڕlpn&-K_M8 `j9뇱'? b^GPOO[121L~_asfؗ #Eۛ?(r2n|V\IJ#" \|\@Vq\;];ӽ.7!'1OLhӟ=bNa+|Eo'13;49D g/.Lāw.lL[z1N,i<`UC:`=ԕoã 3.rƎ)gTgv] J ߡ(Ȅ-ĥ$NȦ1M<[OSidzb%L/S@1>Wd}\5ELz~`J1& fg Ojf9Z|ױby- _)%_ϏBG@sw{NyhU WӉ[M,f`m6r/ 3|Y[jF.1W[F&pnY]6gsvI|3X76e[ZBrQ=UAL" Sm҆UOZz5(|qw'93ɪUlc̣oKVگJS)djʴxMMond~DͶ-IӺ)^},z\thhE9!\MaNAkRKLn"דPD^B:cV/n8܉S3E!OMaA ݏ&xy:"v|t:+&f~(W9uvTпXiIzV<ފ֐L͸-*H|SB̆cc7$'F ЁvY/X[Yz1_Lr[&^gZSGƞ%r,YQsC%*u1Dոi̬ oU JISm}5ځR yt tRJ-S? 3%t۔\7x<\ bJH01S *[ϊM%xU'̢7tf?JB#H";2;;j0;_2२RV<µ>$ Q9QVO RJ`|:<ٓx5nmNB4+OZb$=辣mgWdfhK#1: U}[Xy0h5tu01b#Ƨ7'}}jk3h-r ƫDšp&lq cvF"mdɴOɺ4BȣgJ:A99L)n;ҡ{>ӟFp?2J-dWcuҒ`~ÊG8/JՅS }7 Nk(g`A\~ެ#t_%tJ Rgҧ/IGJR~Ygqw4/2"+hm/:Ɏvxrao8Cg\jEo_7YfagoQ+UK({&~ h(2;|bхP/Ӟ.O0Iw*b[{ʸ-ػJn"in8P`mI*=){ ϷWlbKXnb:KW"}bC?_a0IASHJ4!*w+2:n`rdͮfVjaK7rQQ&WBhx01BHe!$L!ށg\;80M01Dc1onc~‹C-*W>>4+{|y1ћ鳻`ۅ)OÕt9gŵIdL b.h\ /FAX#Xjb͗YDoRu~i.'q3܉2k/:l &CY)wynX}U꽞+8K gs]ݳ%ݍD:g?ukY q,ck~EG d4зMSξmD^RP%En"BM:*/FуjzIU48Z0bg__~BW7eQD  ЧG.SMc/ XQt,dB~dIUD*%u>AO} (r1FZ_`!lGp?*J=ijAYӶ{{<ޝ(@B/)*PPrЃUKdBrxx[r.GV"J*cGo2 ~~.a<F$QQ, svDL!?Ȇ侜 ՏE'%=?8vLifh,/ʿkt{m6z񐱜6?Gv Ӟ9=hy(O+PiG &a GGJ1L/xgr:E>dqX{(%)Ho7QnpLDEfq%*IJ1{@ ?ne`^f1B=Y:)P$L/QqTVte1NsĀX,ȣ $hHAbnAɗl oih,hm] =Co 9oQ\QSnL"dBD!7g{o5)SƊ VŬ\wr097zϵm:\%U1 _E՗q9VF>BM9*OxvLZf fІN|Xo e*u9CQ+Iu&[^Aˋ,9e L(痲Z̐{0y;[xc* l:YTǛ!І&HXR i yEiOu-~}bx ы?SΉ`5gE&8VaAh>` Xэ}vs'r !O&Noۆ2K"qzEYr! T`%],GP\΅q0=xmŶ}膽q*Dku8>xniX;]\-߬Jp\,Ԯ$x*rTC ֱ1ϵ#cEj%qӨ9Sq#RZMAzϗ%z֙밟aAK- h"Lg.~Ih$rL`};* ʠ"X |#lh-i r3=;~)5%t,*]!9g 锑bL d+,kE+a^[5YΑnA읈| y5~3JԮ7֕iYr tL&8vj+zU¬QKY+GZTov!xc]G;bƎwmhD+F-Qj±^}AWw_N sDXogELJΥ@;]Dns1齣];cDF!yěɽia$ȧ9ָ`M@ ~tc3c b ~\8=mSp>͜1|43,yךNW| y)qznl"n5% 4 pfKG#7mNCc: nbp3[Ъm bٽ+ &7v Jʌ9Sʩ[̉jf9iX;-Vk9Q c(^W`eM(* >C$D,"6tvQaE,*b+e[!y k$|8 1P*RgQ*Xί *Fјe짘FRXKuN]wQk SLⶑh0bp Ę9L&tíXz˩+8^%QrT)Cmӿ(jj1UQl)%}89I5kbJ^P.ԇX uX{;Dί^$&͕aE0u!6Xkd;){^ !GURu-x( >r65j&c<$@mG:|oųcSؓmW7q\0,Ο]P))>7Ccg9)-vQgV$q|i6Y+r# <ޓ1%J/U}oԻu3Űrrlÿ>~,sd jĵhA =A6hqG&M Yt27! 9y 9Dnɡj3F vaTF5֢'Z e||"i[*1U|SIHkp -۲FW6JԦ7vuw4Ꜩ2ȶrF2逌*NI͞q^k~75ZNk9䪡(+)㠠%t.bw1d#aQ@ T~UMq1^dl9U|SV7Pɣ(Pe|fbpȞΆg?y'yQܛW|PոP q ̦pʕݾJԝו6;V _"9 `GrKG([ƛ Ov8S3ΟvID+ؐ[Fed-SoXW Lo ȥvfC)DO3ҙJi+laO顩˟Il="x{|>U|sH~s`-#p+cp!cu=+^*9&P;UYo-FS[%>=ȫr$"сu5VN0c$nSvQQQRуam,J^b6(hłi-iV4]#JƀO 'JJݨ5+٤LȇIg?g&Z܎EI X|biÖ(܅^!`]pߖk)ǍrE]nL}g3+=\i=Û1Y4סbvP颊&CZx*nT y^b\ǪZR_xs[BI#%9MJyR" sm\ށG+:<Ĉ-140&ǕEn T<W]z'_5mS"cD1 Sd2)ÒXrC 5γSXĕ@kz##FLkr&Oa+El؛i)wK=if :Zs~ {*qzhNJH^E-iJ/M7dfM!t[ȷrzѲ#AGjl  Dh_ʛt+Ut,b^d$JHӈ7 LLpz/m8R)?RQ2_:-l\Ÿ^,4{P.$1a&n ܇)r;#h{h/N`یIL9WaΤveśiSɤ)T#UrYJu(.sT?mGױRt(gx5ǣ.8*B> /p>Pc2:ОE3Ev`MsYkZҡY|Nd`d0^g XU#QO|r[qc!?ZumCYXS.EDOSuMµ.U,,Pzs[Y΃R(02,3V>?l"<ZZ/{J1ۣl:5ˤ`P6ש^t^Xid|Yo>]vFtџWEw^񪽈vr~Sxfbǩ^8ocpn{=6LМE$>j;#y17tr&U8-ʅt14ч"oB; <mnM_u.6 .OJ/:rxamH6.+֣+q\Pwbt+tE4x\etx2S$'Cϴޜĉ p]$eV4߼2~4$l8'-EjWyDƳQ(sR(c6^Ήa*,{fb5i{⏉joPa@IN-+xW_241rc1S8-"Kp{Nc-ݵl9)j"-[)29^a7=;?h6,D•ZYj(ie>//(=))*dKU'8o2J9hg`o2~7.g/=ݥ R<ޟqx8eY\pSbGmߡd#{ax(VH.P2G]SW^ڡgjra;=9-0P^8c6pp øy:EAY2bȨ}jyfTJ&qfJP̢϶ $=\=K-ΰ!'MxGAHkQ+tԲF ů;si O%b71qaI9ey9 ﻣ(ԜQ\cqlF_&X~aQgiΡV͡ Eu׹2?֎#>S}݅{"KJ<h\9Z0iiE^:7ְ/g4ိ b.EZ w?X"_EޣxZŖZkq(P|5j>U}GW#Bu@Z@>BSLSxUJr,Q~y*yQqe,>oS%JpT/pږ%d_R60pv *c¾,q7mLaD6'+/ub1SX̖x dջ*a/@6 &ƚpLvkbȎHUKOFil YnR0!D-I&x0>o3F!Io֕rB-oj9eUA^4vc OJ֭(*hNH>;! BĄkvȻ4ʈ'OeH |wW^e]So pѹD&Q8Kp5}H'Kdv<#T+.&,m3y6ύ;|JӖLX7P\4 _Q[D T­.O{i~៛{Y4;2[tKtHFh5vP໓\̹9,0P%g*ĪJ~\KZ{Jh;)OU }1o +U=4K(^jk|QHP5Zd-cx)L%3%9w;t%W:4fQ(Ți4~"Ҿч!UTF4]hӠ]l 5vy7 iD4}]FgDEaotGQ++=&&8䔘1}V cOȎX6)jA8GfRݿbs"1daY`"w_j/jROt`Sp+n;?xz1yhbﮃu,AB;݈B:9q2qZ}=={s{|"Vy6 K%.|Lo[)VZz'c+h7T-+8a*e!Sx /gn@JeXĵ.%|Tɍ*gc5ܫg \v4B؋׎ە*{_> |֙ͩ.6qMYA[X=Mjv"L)Y`Ņe%'e4u20+ݻ\ $od/>fSe&>t bw'*8 .$D( P6/6sW:Uf" cs`NnKVQ햩?e!g _bNTuHdL\OYˉk?-V?HH-n>չ]!=}S/ƟiSXŸDn4v<UUe\Vǿ<, I8'O~L+"zLmpx6O06gʗC\{~l@7k~=vDH^\{! 6?*.c 8VU2rzls,e,r/cq)ae`rb]bOR TRoܾ˨TԾt*r%Ƭ2U8T34eoZ&lQĺR:,.P}}`_rο(f|!}a6wrcQv: -EU_B*fS/}";Qy}]}y}UpyqԎ5i߅Kٞ4J&:Ҷ_v?µy6'<Z5-o]]n !띬ظΘ\IJ'o8^@9~`]M͸5W5/;-ղOcB>5G8r ANggH^O  <2a;?b78 ԳIdf;٥hƎ@aK}^u#;?7'qu 6Ӳz0g/#B,yU3{ XmJvE]]̞]x%4qg7'¯ذĔB0a򤊻;]3㻙3ʁ*k9}?RsP&W +X_/u>OxYFG)t{6NS[kM*z:+ SΔ2>+卺7Rxo'ģ٥ͫ` Ėi9V[ɩrT3ʘbO9l H O"{˺h)_^nS2+Ti)E ɳLoœy2CtJ9mU&9IcܢcI0=Йrѓ:?Mw=j0~G6qp.$Ep uۆHd'쇣]Mf4Se zfkΡ`u/hdɉ,w 0؃)|B!yߍ|s D]<G1?kUP~ٟAh.?F`v#;*/s{+NL0NK:~H"!}"4Ƥ%1hyy[7uaT 'Vw&`7 ̗ܕT[ ]&^,ģ\1_{DzU̞bB6ZSrVb4v`ɻCQ=,k#Led7%?fRcQ/{FW4b9מ7z/O3Z޴avtgmآ+9V<]D!x~qGftN/_EQ'7RiɽA~t0ɼӽY}b -S0ӌ8bcw;[v]lO[X Dv}0>X 4zGaϫCˍwJգ@vρ)F[Gڨj Cq ybJfh7/7x|؏|iOp#9|9~#9F]6]lGp˓}:7ȪUR>7/FK*el^PČA\PvN23.~:'\ͪٸ(:OX΋Y˥|*0ɹ܏_n\. YNdFmP$Todb9+;edT;^[(f\J~Lԟ͇̿2F݄<. ɤѺ$,]\?- D7h9ދx;5;>5 2Қ3y9'=/V}hAヤZE0'7CX5ޓ6v{қ?MMO^laޓՏmbt#Y9ju&߰>g\ęB\Z\uJM,;Ռkgt76G56WӢ(Wa:N uet/2ͦq1Ǔ]HX5@#KN܎Þe-q?,Yc*[̰y9}vxbQ+H=\ai23†fEL 2`UX} ֞=o10+K=B}޷-v9}GVs1B;Wg.A녭3ZfQ0vDk_ 91 ٓsb7rh}}_l+ L9gM&S8-!wf|ǹN,ɉ#iҙ{pw QذǛ_SoXˊ65ui߰-wg}vecp˅]4ۗWU;m3"IŢt!肪Yѯ?zd{MKά*2KO:TřqЉ΃5?V,Vp*SϪhW[h%N4^tƞPjg]:gzK6 e23pWvIq;+.zvR:{I,~GrK\ ZY~&Yƾ\F.CRz/#ۣ[*dz c7:3Y|YNd.|p`}bzlfQk5?Gpj1M{S۩ueiR]\&%BK (Vut_`v5uids-<"jy "3?ks1 ]^osy8њRw4Ős;?Xsˮ<{kecMe(1(1lĂdubAK=3 .[aJk'-*7^aAUYCưaΨ˝͒撌שT\Ob9k]1>jn@w:oO$7ɟ9]l|`C&e!wnSFfaT7KRSJNUZYF OMO. `;7^X1T*895,ULCfOY|u 8UArW|ZǰlHLXPmm'Z!oM Ol5QnpE&wv?/V 2p Ȉ{;4ȫ$gR\ɾIZ "eQq;γ߽ I/]P[ο9,hg3U9"m~at#k[07 LwZѨ#oq5BH@{4&GP*kGX:/IŪf8[SN 4fo<޶.˱$.®5YpI9^mwx$ NveE_Ί T*91yDԺɌ vaGa&Ⱦ`E:/SX[ތ,ֆN6f{&{{RNf)6,|eZw'"șrx57$q842IW޲~\XdK3fwn- ob]ٓL{ٖFݍkýS~L qEP`e ~ݜi^oM/-XBÉ>|< ~<0͇V'!S mmcQqڧ<њ ,c#'Ò?RԏXZwpebSNŏ>FKk"Kߴ^7ñԖ8l̛f|I?|?߅Fvv,iؾl2%zaw:=2Č~փi9ހ{p(EXCn4nG]ʁj_ $M1|kF,.o*`_*˩^ƵRgxtC9W+Ọ9c?x29=Sx 7dqndQ0'oyGJTFǥUʶ e,zGxFOۍX^ۙ/?{'&<ƸYP'gׇjm"]9i8Yz|*ԢɋѷF<2Yѻ gǨve@MXb8h:$+5G+kϓCйeYCtcYчƂV/mQB|Am.@j+Mkgoު b|6fH48f CޙujR95׍|"pҙrW\7z c7ܘXF2L)gW}ku?/QS/!jO0]( \.fywjv$k+]~ #1]/>r$t1 үVsC^KE?U6*ϥ 'ן΋k^b-w;rremy^]ަƛ稶Y|\Ӝ F0H׉/s݉hmP3 65MBo*YΦ\iʼfVn0/fzh1l~L'l]994?27)IU@au+H4g6qj+Lޢ4\#z='N[ŇuEI4y$_ ]y>فg]䋡$>9v<g4v>xey4əu τaҟ& fxS.bN%֍d Ks8&%U9Lϰk!EWmmxNPwۻa59mQ4ى9{wكë__ #J yßlQ4@#i^bXփ1o{}/4jQFZN:,_w+OՃ'ZbO{=m3R~%W)HXxPџ,)p[{/F6'}9i佉;r]$quLYzj8# 65$DC=Xy]`RӒ^oٓL/CW>ݯM0WRRj`=} 01oMčh?҂ݽ?C[ Clz7 |O &8wۉU[4(7>]VqgA mCP&E?h?nqx <N{7[5ʜm-L9ޘN/~mMw{&n5Z+i6T:KŴ#Η}m퇜Qg\Uѹú~csEhnhCiF}'xcõ?(@l x1{3yRxؕ xɆ/j*'!yJm6V@S~5Z3y{Lkn_ms2\OܼtQIK)Ph\v{1HI&zi)]IY>B[.{v%I⮕I{"aMLy7C?9 ~ }˘8b^/>O숽N3L-tu R}5[P˝).LSYfeU1]cZ]3 ⦸f>z_']"TQ}zdtx;RiS2Ur=jT1Ma?֣JܴuʉU8dS Lgl0;xTk\3OM#$WK"l?Fi2#kéD~,xZӒtbVCah4nlH3iʽYƁ7b?חZsˢe G)ʢ%ß)?9]~KPf75 qsL׋S?+:ׄ.6Ç2h70]6m1no/%zxr283=r% \?#1f(Orx#!"jXzV [//ߟbY*|scR5腪 w+Q#ڥ#9aF2򠃸8fh~E$o,sE #љ3w8ƄXB#5sVq wUDX?-OL57K"B?F(Իk}fDNCsw;sP;,Dx{j痮& y:幨XsK3-iuˁ70?z36o./Y?ļ {܊M'z!ԙnz|RGj0qƨ#xځ=-E˰ZLz(FK,iS/$n抸!-7oRxo?S^D܋bvZ'2lp%;R$bxcQ4Ɯㅿf 0`;P~^3Wn.DD*qMz(\'6o #~-!tZ9aՃ| kZJA6+ې<ўuLɰBwbuq Iq#{C,N_T*˽LFpSV|ǡ/cO(r3ש\0!֤c>ʭhgy;Xu܁s^zq;/>u/Ou~uyw8oh Lbz-[XQy'RXnf%a8HD\z3'3u,Vݎۂi4[ӑ:9,b]zM'ņt[ *kqm0:ٙ}Q̲!܆ G}Xtv0^׶0Mhم.A\=g1ˇaъ7]YLl߳6AT㵁Ge/mjJ_qvdESݱ5d/F41Mok3zQ܌k݈H'fv&-HGT5czt>q4Lbj ([0{6vc٠(.ǣ |Ug굲)[ lʺ1!4*GcLijY"}eĕ7Jhe`Ion Lv(foHTci:[mά8#'>J޻5Ɲ~7:4Dpkk ]/O7TFA14Cܑ*x4Fl^]v\ꇦU:"wzuK2HK6U6wg .v"a|kzsÄάieˁ3Hx(4_SꕛV@BC4v?6߬H<QqtmfN_[pwwiohC =5] By1隃bw;9r;/XD>ݖȊr}ZDlFp&CW'pgS$":^܉])ٖMsC aWsº͎tbϨ\_Rr<7Y"8 F%l e7t PCbp2y7sC}C_M<69?$ 9V~uY#Y'J0xu:z`&H .uT7X?6?w7/<m*D/Q_?JoZI2Ѭm0I7C.pys8ݭf;]3UotMx%e,ٜanɝ~"iϥJhH~ɟ.d0WG ЖRrrP3Ix2׊If {$.ݱq lvnԥв?t(҉odEpTɝ(Wxj=-uV;8t(  <8|f>M7/1u/ 氏-ژYbNG)ZМȹH&A{_ߴicw"Cc m1k3ԏA<ҌaTZ,NDg@'\h2'4]'9鯆v̄Ѣo,ZՍ! VYޝfGNV,3>>O]Ϗb.nx7],td(;rcFlz㏟:ϫtʄq/8gȞLe\{k cJ^$f4k'qS&m[&h/F`툧(szm+?Rv2% oJy8& Φ6:d6#Ի2_#KYi,JE3ٜ* F%vd@N45)R<4},;5,Z`v^r x!;Z3WRںنAVl5-6YgFbۖ_EE̢ f G0&v \]bYMĺwEG=o`=#m)$] vxa?gDp # م 1(T&`d}1 oK=9v 1 D~#{ouşmnQhߙm{V'uh@ZQ1S{_O}2TLԗ(d|B3]QeXĔshs6; Ěm´9`n<1dݵrӰz'S2Wm,h$32֭dj\=8?)@-Zh$?Vţ9ռxP·D#gM"d8h!gZ : Vr ;xPݙwV2`^᳈El;WWLgؚxǤ6^ ( "n8oЮ)PH=eςHfGa=B/bVshIK+V/#Lbd[LF1@g>ȔN,|BO‘p|a6tMcgF,oB)m!H7OZv4FXe4bLd ZElmB'6<6r~?1p\)W)H: J}nk}$d,E[#CyC8"(I`1egW`P4t 1n&=b֏ecr>.d[VSgTrtkJm}z|sd(T~-C˹xajIF/P }:J{>˗0wv&y+/ueg\ ֒LMST%1q,1;);؜]~5niMʳ(wyvx0|Qk UgQ<Y7uA]ȝ?f֏hp#/ƉcS7夿%l)q f#fƶL3Ek5U<°4Ĭ]^Pe2sDsq*ϣ6?>zH&w@7Ǐ^||ْzc~52%hlɱL3*z$y+7|\t5=xb<Ձ}BԇP>;a^*Q 7,:҇1UrKwir)QPNrqf]*KXt}Z" zh5 U7$Qxvb% /'BZ^el D^Dy愥0a1'b8ۀɜn+Ry3(ŕQ&pHyYtjVcǴruTl,Ӟ4iCTi2*r,O&nرB} |j|kR#y]@op#]n~ 5zs\y6)B.H1&3/3`p*k^,pm)`͇r |i[3aC>ʼnLay71/sRÜ 4)x:9 eEG~ w]#m79pƃō'\pk #I1K{r}f ތ-2 K]BOߕ3m| r8ՓOc\rY7c8 Hb?_=6t3AlIAD/8#s3h kX0a]Sq ܖ_ YaHVS^BB#lzl~X VǮ-6#,r؟~m!iJĵ>lNX'at[L[)ڨGh؄?m( s倭/5ɝI(> VDBgz-n,7p]2u8ØNhJ 1n0F)=zb4}%t*c@%/l%/bn8L)a> ZHNNzp.z;R8]J+9[R%p"!|.0SwK6H`ǂsNm5[  })Lq>eIG`AlgVҢm9̀S7nGP+F=ǤVTy1G,#R9ȏa-cY% &'νC^ P-J4ў ?ڀlf9ٳz zz3o7mxօuwcj.2{=VdzaxVqqO&^cg&p`Ji&/'LIć?SaY1kٰ E:aa)}R fk qQ:90?_ z}ۉY(*,[Αsb/ı}j4v su 9 h*ɎtoG&y;h:Y7 Ďo AR}7;0 DEK'kX;'h[/N͇6}TCqL /p-%o.Y컕N)Iɜtu}.%?2 9q > U*S:i{Z+EJ\|%q%/*XZ Zƨɸ{]ά2>,|v bqS7c?'Bj ]X6O1C$x&Z=Gz`Á:~@[)VW1Fq컘 m:~I*oV -909R5G Ōq{p9!%WKY^[AbFNkzQԂ%m<-O"l,9~V| A}=9oHfdTͪiV[Bk8RRp#9SO#aڑXZb#Ʒ .yb8ёi؏I IsGWM]IlscGWrpWllz3 5-Yp[?Da {0b'Dsa 9Š2߭$[%:Tw 2:kE |e\P`7PAJVMc"/2-s$nLdôH*@vkO{3N+ٕ6sx>l~r*S(ݚnsMǒm=㐿 ; uq0jx j'+0ږK,99ҔF1L ׯYpg۳%Ԗ4n%-;|^x1]4NYJ<ߡ*jϭf)σe$PJo19VU6/9c(ݐ#3&]8P^MXJXt(s~&{ &J'81Ż('pAG>+ƦK "C^_!Aעw2Q`IϜs$Ld\*ĺ=Qޝ-AFHzXuߜۘЩLs""Es30%`c{N|݇#1E\ "|~Iִ.#;ǣXqLRSSF~3ek 28R`L F<(U5=#yv Gy 5U5NxSRn~*6H(_tc֤ 4v)] rn묉6?s;bb˖qܨ ZXf M3&rRv2ZSA1=799YLvOzY\BI!{;}PndxJųP&_SD[iM]^k@|њqHDln#8p5evc z;fW[1DX?ʊ".7㧩<9ZIzbBtc~9땺(flPicD|sǰ7G#/aHr6l*2߯ G5I?U(GQ-v2JnRSt)PWء1і8>^$tČXvV|I6 qdЧ>'D0-x`*Zj.5ZryK&K~11?tu/N P`V N9,`OWMO0 ܙS0ڒG!YeԾ3Aü* YL0жvAXV=Az4/`4_.DtJWk ee5\(&8:[:3r8lLbLRy_fhBfr8n?`Qؖ蔫P!:2ߞ6\3`m{8q. Jmpd}FpWVO ̢OYxC걨Qn}K)l*~ch0JáD;ǃ, uš)<B{1mzHȊ.#G%3Ӫuݤ /ɐ<`V˕{%y2W&vh>3ÃWZq?&ѽc[3.Y|/9 f hMf7l-1j0cт;&%2 3w+w]16< F(Ծ$ܽˡIfKr72,s[PLƉ(<1C>x,{n'g} {dt^.dN}etE 7+n[_WnS:J)ƴR.bgc)j"^&`9ܟY닁S$I<^ K%UšE-Ӓ})~NyPsLǰLG~Ns+Oݙ߁-XOMiaEvPʛsu@.4XqDXrm,;(;{{yÂVe,M W4q#ђJ[[jU!|42^z󯆌,o ]y<>3ȩ :LvZRֵQW wiÔȸV:QO\klMbPrg0r|r7{9XEHϚ(Ø.D#՗,X's :k~tV'fN3~$Lkn˴mfphܮ-2JKT m7݂G7(CVwR4;T6Ӧ8כ𽟍jĆ2ޥ4+|9ׂYbSjOsi%zרhW()w}gH~lřw|:jF|g]B9h͇ܪak8_-G r" grź" LEL*QS..7fw}5MLkI1鴦rUQ0цٮLIN *'[܌Ue+Y=ޭha7"k{Wb|RE|7Q+<Ff>LxO˝X.sƠ܂$k8b*s*8G<,}ŠB&͙^7{ǐ۔w9k{U $AtREjQ& >/cIZ ֋jl"JYK:f2}k* Jk˟&3/7b>QtHI|E%˘O܅x. O\#˂eU$GN5sx+ f%2B uKIp'TA{jLB4JFG}x6$+NcRT ƮXxXáIĖś{WRC$as(šRjL43?i RS "z/]F xʨq9nڒ5ֆ~vrf =X w6܅ȍ˾VZSY`K-[6e,fQt8tFq!(IˮlHK+۹3p 58a81ݤLFo0RyӘ?tz>3c]y 6KJX{ /{bQAlDt>}`SAG?݌KP"bX`gww [Duxr[Ȧe@,yCYӝDԶ. ,Ƽ~ptw8]Nsm4ɾDDg8,d z!b _'9(8]nGVN:xUyJ U/D+> gʗI ^P^9W8-u݅h_DX1 z½,ktdpRۥ0n2EBY7q:b<";&g^a-b_z>(CWQ|Sٳ+E$cp.#$Vۘ 895mJ)Kò$ Ә.dMv %]u5020-9ۄs> Yg*ZN֒\Ҥ1Sy|;,f\xkaO C*P͸copQ F)CΗŘ)cOQs+VgaIh?#5VLqI{s); ֏Sc0[s=\J`r2˸'pҢ+uG8o# 'dXš|iQIڨJcb[NуR}+!kM)KWLiHLQd1#5|E* B.{GjdRIl^Iz}|Y^Sςul5W+SzX#0g*!S* r.ə~FZMOCD-}V2{1!d~ԾzaǃB_fGL?01C.Ϯru[cia7}RO{-?Əf ]/ 0lChBQk'"B~b5B'6ɜ"(aPyDJz:OiQClƷ{v~0'#i2.ewˈ"㌕rR0}'=`ѱ _א3xW j$~UJ ɷ(zÄ&f* dg ߳w39yyݗ l(ٕG2=0eL(|a ޖdD-c v_˰Pکt]IׅܼPJ2bfK0[@d"wqtGSjÒsR43p~=c}걐m=Łv{|b΄ r%5 #9%H쮌 *eU=Jr_չLZQLfɪt|KI@٬G eOmW&y> mDZIuXY!Nxٛo+"| d#Żb $̍+mM<._LB>VX1w+l^l{E8q6b"Yp9UHB_* }P b*nVS$lJ )y]'2ީ%5:2(x"RUb͝ Y=uU^Ta­]yӬ;cTSuB6I%N _-'f]4{+'r]Fc5xMze%K*Y>Z J9#]ssR%r< #/g;_- Z}Ѩۂ \%Y8I-Pj7a^d>lӌ2!ټXYR"kF%*aߏ~_#7U գRG^H'EfAxq` ~PJ|J >{jIWIyq**&$g6eАu^P2d]ۛ38P|ZG;_EIsݟov՘0VK:lRӁ8ě5ÉΦS6IX$duW%=)aHznd(_U]ClNeHx>] XQS1dͣlץmj#mBNqLzdw3r S\̨e^A^Qi)H}QJ9s5*SmsHk`מNs*\oYT/}tSIUs*F 2+%JLoq^&G:R3jU5TST͌[<ۿ2Ϊf)iuf+SMh…H k(~,E6CXKD!;Ec_{.gpiiLvȡND^JJ=f@c}6uc)OenNLB~+ib(e`tˡeѯ,z2|Z qKSٯ:IX fJ ?G pyZ~٬rK%_å湟# cP, cy=}IPG)* w01kdzY^]Th@"J(`9z(kXJgy=Wj>T[%w]â4tF2%)<Y_ 2яpd?YC:rWlo+Dv$z6X aLV'$BO<͉85z֮+LÖy>鍡jHm>XOџ8I[=cE% ՈZ@#xIN4eIs\WqhM|`U%KTxU+;/_ɲ6ȸZx+-U)ɿz.a?±J*k#E.9Lj[-VTл+=Sdb Qޢ|ms'ܚV+% /<0spUDGbR4 ' 2s} $qI2GR@t<ږKnc.Zq Jy& 2Z z ,KNzq V6;! RSצJF\ax%{|}X&Ui( ,.'OX#?cރ_9GX0uUQmơlRuoU`DžF 6 i3S伺3k',؀jiHK>ySVŽ̾tu7!ĆOpt3/HH{6xά`[k1?cq|q˛Nɍi/V'+YjPOB]2,Jr#geh[7r 9|}#>Mzn70Rx8Qc wa?$iʃ*ƝjRn78q̡^"Nj7' 6\(?IJ w$өh*1xWx:ޙQCY&='OC2`33rD+eTm?o"p^ϡu>]DŽ3NK ~Ql4Tη z*,d mhyz]Qbn 6rͷxZNq>¹;ԩȻ\u m 4e,፬sSĴSʊUV%*_O oQ޾-݊HSBB$$n6k?`|߼:YkɠD=g!*$ z*AHKl?U{>>9,(پStFlL$2/u)SGhjb%9ޥӱB"{T5s+tVJ7%؍+be!g|-.RN@2ϗaWACJhdTmR53Ni.ǜS/W[9\K&eVb`1RV|KJR7)_[ƄEݝ,wKYr鴂p,c@|ڷ$ӨsBV`݅pj-722Npy|Uޓ?F3ͺo OvS^9]#FM@  .Y9#fYȪC*PGTO!} nY6ԦX{8/PLC!w 8;,);3X`J0LIM`RwBs[xBBh"ݩqĴo|"f{borJ_FU|*H4 I -PU:_6gƐ9?uӢRHٴU|S[yMrvS~ fVFmu~JVS򲙔a+ i5C>`ꅢ̕Ʊ]ʫ>,O`~RrTlߨZ.֫z~A6]*QHGjO¨wܗT2봌duNU2ZtJ䚹KZg;+YMiM%~nU2;@AÔ dq$jI[jz⸸63!IGkya/9qDtmO(fɆBK`GWN&X0z ~wb*r)ͲXxS:s)B * mg>D!b| X5Ib%gD]EV%:ʹvYN}%7w`E*1gQqz%,.RNᕩ(WINdl_X) KOM=Gה2C eQNQ)e+LR(v9D]Sr^WŹWr.e}4m(fñ]|w7~~;UǼ5lPլRI3:Np\K0c$mhLƴ$/c5r\qu AƑ'aӊ8k,9`(}!t` B?5ͤ4OEދ_7~PپyfR}0DzuvڇϚ oKR4{ҏ''[MguꯥgMޢd֥J:fDgbo\AK&:_R1L Y75 jfV_GG7Tz]Ap*.HQPQ!VIB uFs%760lɶӚ[ڰww/ e"y7z=8{VitW[3ʺ4O)iSGCȷsd3L+] - F)I.`IPJtܥe\-Κ"гRt _P_&=*A|~.출r1eE{^JZ 2Jɸ[FXbj7%y02nSRD"d,7(ˣpʏWB${2B08ßuscc6yvM6$} ɻ8;e:.i2ʹ0#ğS1s1M`$p Z#7Z] U Qcޘ"y,)[{7tgU[3p/'1{50RUŽ|үmp h?ҭߦ~n+6)t4(l hH>C+[&L@Xxprߛ-XWN 9# HhP15a$) )_Ft\BJ1U:>I)V%,[1aTۧEӧ̞_bm}`E)u帯Ѩ-U 9:97 Djr-oJi2V.Uɥvj%N8c(喿ɋHq=ZtX6%8)DV0hyr;cm283֜֕/ Ղj2BBs>/f8py4C_a'iͨs 䆔̒;L-r&镱i KIkVD[SĘ"}&PZ1eSTΕeM+B)f@sG&K4-,C9DΘ7@JUoq@J~W&(X6DFRF/8ka9R޾)bQ6Q˓4Vd "&~,MXoJ7@3u9702wKj83U4ۮMO}5?VJ2g`~̛SȢ.65!a6OĒKQٙ2 s`p6rsΜ惹{rz)nwsnD=;}?ڶjľi?\փޛ m,<ѐ/Mҙz\户֎Fv2./>, nNE@&g Kh*e= CtU8YbjL W1G Y ~i['_¾҆~mXg@BOz\ݥǷx4Zs<2;QW 'yY\DޣB"F*a")dCmS) ?ݮ6p_K/.b,ٰFe+eVrZv~%t/縓qJR1LOuq|da5-KFkt[4;L_<>bd -;k qhS8Dq([Œ7:FL1F}*yW-ҕS|n{Y !@Z黲ё[cWk&8 >';ɘ]LipJ(17 -F v01R3vz=&zZeo"d%;ېjj  ,L?8Kr qzfY ן ߶EEX5%>6le.nټB -՗gG~RSN, ;^V!"vb$2|ɏ#%q{ˇ a-/ )  "tݯ\|%Uqc2yBz/4CSb_cO#{NOfK[c<7uZmy֫+-; hw&uI,>ސ y_ªømfL>y40cC7A7i+ľ|DBn‘N}F=Y.5ipG6ߞ_zpsk~p&,K欺nΑ&4nJs6Hl-.O{8L|'A8QIh 4j"m]7(x;WƀCRvx)~OM(5~YE&NyQWNU R*0GY-2R|gm:QXoB80m9Caɕ YaFUk>e'*ٜ|?+Y10vd/͢4ޗ˘$w*dP`S[@"ʚ1f}jsGS<>rO6w_@ܻR%&N7i)/ž6u[K5-'7 ž8 xMG/?xȟ A[o5qQ Gs5kйn!0>(ƥ+y)zMXtRAJaÙ\cGdzܳa`_qè̚v-]ϊ %p%g0"K4g[EsMԽ#  =ie'VUץ%"O]əW(zI{Y Wd EuL]a}!wmLrEvia#N$o~/k q/x7eGr ]ߎ OfZc>S uƱv*Yl{#}ljfO5TWcVr|%W^)?ܛ!u.0[5Gn8I2F$EŕJf樈W3^AyQr֔F1s`Ftdnt"_w9n{R>,훋&)RX`V( ;[X坅i.OJ8;;G, RavXd0֤C KY}JP?V6fLw&n3Ķ7cp0ځ _;]\Y[[Jqpa,#xDF5kkQ${tdV*F2SgAUe@סN<_jH̎a>d3'r{ 6Cfyn=yP?&0SQPO2))f!_Ertr4קa쀷=~As0OnHX'%ͮ gUGd8j}#ɡtag8ό䡇57{DFI=)o1ș~[E*]ԠXc:itY`[[9"9f))8V$c[Ĭ饤R=IAO 9fZJy說`OYZe -]k=󴒒urV=2b_0).$(Ϋ{mؖӎ(4Φ";iUqev6)[DZp Le4FfqļzK99LI.O=KYty{L&ϤcUs'srB2pk" ٗGw(ڄqԸ'ߋ͹OŐ,?S0ctbpH/n/@~Z%{.?pop)kgSwj_R+50֒pߛtVՔX)OF3aL޻we9Mv- w0.n$u^ZA6]ÕH'-QN7+M݃ 3x@"oř e*ے8E0,90 șXsPQ_ޚ׸k)nO(mKoc%U}YPc^:B5 eɵ! gF@ޞEJmHfhs]J9:UЧw}hp,PS8W슆T Yk9+ʨ,d{.bO¸ck9&t \T|)dB%PNDO" pL˂b-[ۚE/\8>(Y2o%0mNR4zDO)"Q6$2Wůx䈌BIY$l+~V*N)ܘʼ7 lë(Kl,FҸ'zbKgT, xΖit@HQ v$u"IYtnʰ6 PK zĄKXxRI0v@0w)?zp O '{[߷{>Q̹IkS 5DVS%?W` ~hoYE5h\Mx)}H؇4+}FWHuo҂χ0a5ϟ8SrwlN)RmĖ=ѻtCKI;w:i*)[/ hxzD1fW f>In_E{"{ |7CĔg0(?4O ,'>q{rϏ֝AYv0rG}҆gȞ1E qew mR@75dgkpTP{Mtu Cy^$,d# sO2.4aTlj}) .ബ)%4\JB>+5j `75r4.j&0WPI_2ₔT`zգ$Br#w/6\p ap'Pa 1)^Ja[Q?,ˬ(:㒋 UJTE.A?\xf؟$_Ӱ.|6:eP}(-ӹ\"O'7lz3Ʒk. 6N ᛅi˄6m6 Qi;M ,v]4`[B!>eXqw%[VrVGFq=i5505P~xրV}p1c}Fntt⌇7+A|8H\'oniˋ,d%>{OaJ![*eY9kt3ELu\.HY P˙D%\ۋh?Zl׸(PVNgW>x{5Wª,B=7E[BJZV3RC?? ^jRiS(5a˕m-I 5aDby{ !e*bBim/+ʗ >\`pv{G62ITԗcVù*̮R1b5"aud8)ӔڭVd`R:u@3C5Ǡ]8+TJyHqwD0yb8_E!&<ļD=L3X|>ql_IK\RGE'D?v ԞLl_SY7ՋgcXHӦX5 zqK[zW4dЏOJGo=Nlkη%=ljX83~EZ?R/SsKTcTsV G #gKez6s*o;M)4剳8-'YCI4u`It:D=*mYB`f-X5I9.B|%+`Of Nq!3@^np<7[֊g3TH |̮$;xdt8}x-~0ԊɃӏnXmG(V pQƉkު*PЮvҲ/pBAzJԔrc,Vb$Y (ێ`6v쩌qe+7q$ҙcN><Ϡ~\MeQ4;{qufnL6Wk1ƣh`#A(oɰ":RnJa80\d3ɟyF*-n9|XŸ}clۆ4rE.wdF0nӞL'DHzAc g@J|Y'9*}9"el>!yo99׊YiIά;a՗c I | L>s<ͭt!ٿ?VJkN̜4Oc,4G%Os)s4O2 *{/n$'vȈ}8UbmOiXbNEajh(p%7N"_ *@UJ.a?frWYʼni*et |8|'䝈7qL j:bKO ̗82"3 eS0AHCb8'v4ǩXm<C0^r&Ā#jܣaOX>ړT:R23b?"?mL؁֕')]H)\|P8b|^8=9M@>)%N{% ݪpxYcdV'Xw*ݯȫC9|3|&XO͙eVGrMb2q,:@SߜFsX2 JUɹE*:.L׫fuuIVѹڴVKAIeckNwWpSgo4/Ȫ5f]'l@?^CK4gLЮAsDj_z؞/SQpnOkK?&`ѳ+8TN *xP(q8OkOt]/˸\SD煼9T@mٜM`oMwOQ4oݍf#[2)+;o)M{2X0n&3ظqʸaبWL(~1|k>W wʙ7Z[ؘ n/Ѱ+Ep)ֶ\؅^s[36);Ƌ?Gkz6B#Nq6_)oImΪg$2/=l0wsw7yRkMCo,?Gy=gߗLᗇ1'kGcۅ,<^JE;1|:_!wj}\ &^Z'DŽ#3E_6kz_d֙L[ɮ=rVsl*wM~fa7FZ#!~S?4gy5WMEIO_;ą ԝm,~Ǖ9?J^`:IrL?*y"YLWInJ&Q# a$|Et43N4}%) kQ6N<ĝB_IHp@M m}u9?jjwjTuꢛs0,'h ~МA<I;eh%3;;nVhL?3ė=xx Shz/wĮh$j`y%= dߪĨ15z;U`|u9k_7jFz76W(?6>yOBSȼ\aw^T%f 2RB[9zfjeBM@ qM3Iu\`ơ&w]׮?/c5oFQ70CB>v+ڟث%k3ݝ9>>1tz69][e\ߒ|EAi#죘sṵPr!nu sDɹL3OSo&{H͠+O=}D16 5Ua4[Ói_ɠGJP1_UuV`v,iw\5zڿ9],2TK4vH4鰨tc~^LZS(2%p/׬PcLХPΎb~IGE F'rK)f~Nriu61HC޷>{^=!nItwOFr}rk"9Z>ЏќnIM~\qgKD_͑8]mfMUt(dlbJͨbdz?^J"e5dX7ݰlx&.<[̀2b;QcMn,:WMwv0m1)ordX1vM~ט1r\"| X]7l]H!xSxNqgH|s1+aHGd U fʸ]J|).9+KƮG06в~Dq{;e*d\)wNy*{6ϟd2C62 Ïc-ʂBpd[}5vْ‰Ah!^ nZv~-:Ŏ -WT̕LQaTZ槷U3;Pv]grgA#mטvL:Ѩ_D=7g>)v;'t֋"{I#"pPsƱ#6iڟƌgYLSVD%mXMd1/EDu>pXKbfc͈nhۛ0_4FUהFI87|r Ǒ|;A T,s+'= EEN5>4aל՟G4ίHE IJ SB|Kb<17E[ȳe>l1E]Y̓<xHHAt=ôh9c!盟Աn+OŽP9I T끐CJL#exو0:;MmaM4&60 XD'*Ék,c$pgm"2eDfRЭ}!!r>) JXU7wE4__cj%&9=yJJ܅(ƙmA#ѼLfهpqЛ|`B }1ӈID˕6=*4fllӳi{gaxi *VE^t <|urȝ:jtt~;;WpNɧj*B͢.2V/zϩ@r'f+vfN:ro ~֔M]Id@3ݩ(cJ=2xP2go_FBdX7qۍg_Ct=UsOK: MLq)fTXd/ ^Nt:r}p>CU0'C(`$LӢ0) }>a3h˝蠝/?fSx!!sd,hGoP<dz; } Mg誡  NKd|-'i9Ne@v[ζ`RW o4+_K/ܜi~}{}wH2i+* ;$&tڛ=a,`P7p|U1z$pS<'Rn%f`ߕMFTnKʇ}̣׋|V /+%`M63. INcchn3a8Ga( '\J j&MkkVw8Yv<0NY>M0Pl%IQ5\̩!ék-qs%/Wޔ ֊ <[I 'NK2IKLPMȐJTR6S.r/A,Ծ4`r8,k໡!}d̅⫢Wl3MBMYhx'0^cN*Hݥ!Jˉ:~hiϗvg1&s̚2=9G@i4 N#(Obc-;qpӨ (Q,9Kcfp b)NP"F՝Ϯnnj:ܿڙ>Dg IRz엳lGF2FGj7wc)*K#q])]K,%ch)B*1 ٯ!_zc7j/ұo %,3m׆ZX>ܶdoG>\ADN jɥn!wK,?&[E mOa^ ŝ#LUwb5c?ɍԀy"ъE_l\X]L Z-(kzɩ.'i1jRf- [o|֏zhꅢDIFu8݋#txO!qDU,oKQƣۑEXDb ĴxM47Vnd2?)󕒹dlD}C- ]k 5TKu,mme6%a9y4|pZ,{v'PX քix)fȉ98OY(%2dleWxl281  Dḹ3пmJUqns+,Hs♠}nPqг+ĘMhnt Kv=65Aɝ>h\xrJQAws8%"'* ,/eՄrB,Y-5.c|/%P胇լ`SQZ|j8F͙*: 7TSNGz$|YWb| }f͚A s,nL`[4Mp7qXzYPٍ-|i'Lj7dZ{|O•զMkޢ\ jÅve,7$~Q^Y4Nݥr~-嘍q4'COiJ1l*'RARn".;>`y'j셨EeO>~7eG&xPDjEaLV%M^NZxdή YB"&vqČ/\v6}. s1_LE :*h&s5oױQw jj`h{W%'aSE&]Gu ]%k2&iS 6kBqY– gq O#po^LU]U ؚW2iMfc\/U[ɛ RM{Zw?ɬExkt}Vc]aoyG4uٿhYxڎ$ ;0-ω7_ŗ^vrΈVE;/~&sp,{rWe\Q­%8 ,ꤒ4TI$PQ{%&+BNuIەSȑx %r(]N/0"oPbM-cϱ1}(qQBf\0?k3c~$?'nPsS0Y*lj̆#g4\p1RBlB<$2M!j`2kkk87HZڍ0m)=|YegU&zGpn:GVPak*O`tv*kq>uSLZ\_Ȣ] $mJV`e55sV9 F:qHPjR2ᖕT5bi5*q*i).֓!,V®0Rk{*ǛN$EɞִzgMC5Xqٞ.88I5gDn7kW`tSZ$YS0℮3 z,J1'%sja9[m9 ƙO|YBHVi$׽0B rwM1N\Yޏ=%wbޓθB7XyXay_JB$"(Mĩf|K{OO69fsáUS>BM\s G*p<#c`bu֔~ޜhÉw a( DAl !~fAJǓvrnbG1-rbHM1=fQl"Bz=p9lT?$TJG*7Wz\uk ݻkYSO}=/ Y&U 3W{J١^R,meI1DEITtHgOVw*8{K 4cY, U ~n`K^2f;{ܜF]ŃjvnagIR>ئ2,O Lt䆇lb\9aa$fZ<*+eOL9 l)+_͓Sq tL'Zȋ~ :a2u(R)GCTmrNv/f薕@I6ˍ ۟U&V-QN aG( aLWfM^Yј Lh| 'SGcmmO~M? mĠdL9*܉h3Ǔ7<4JTȼ8MВ%TJΪT<-Spuߕpt9OӣSgJ B JlubNV~*YIn"*[].I*pkR:= qOp룂 1k#kqr~.Aǣ[8f<le3Gm1dC5˧ۂ#E41EhK4Ɔכuw0jyDZby8 Kv}*{pfhv)rXzϟ<:5'sP8QDt8`ۖ1K݃H]'p{OTϥS8X> ĉv<Χoؼywfy?ynv(+Td :/z;ad} `ȃX( WQ?MJc ƞ*cuj1_\B#~i(iGrt*V!0"Eze$ri{ZŰnt21ɨ+I(Lfvgˉ=W1I0}qP)xGM t^B^b--DXtίhڗnœ9G|3-Yy]`u ^k[5 n+B/:Yκ枌냷?MmQfLy(Bn=~\:@ ͘A,tz2'y,)=32k2 gur'Δ8|FI %ΪʓӾB&Z8 )fHZyڲ8Ԇx31:3*<LNhMIyǩ&*Mc$o4.m hfZ| TJY#%raE\ӕ`?+GP1Y˱Vd9\%k霢v+ش_%),57C\sa1$ƕ3i\K|^8, 2z^q zFJﱻ *rOyQ *B*90ǝ*>~H?2/Nj G)qӵo Nksr ']x:ԁ<>m 2ZՃ7I6bCLMXjN4i70\Lb#1%Dis)m >yɑeP{K!:I 6?%N\~Vxr"gL31ņ9ܡ1NO$mcx)<;!wq va. l,SݗK#bӥ%L|_HPBjxxVeLޝI6JcI>2~N%hΰ %8q~ Mna0 z+7bCŅC8U/{}>4֗e$/RCX_J'l6V;^MJ M?|z{ @E.:6fրdz >< xɧ5mM:Q XVpG`Wh$ ̒4< [L2Dqk>cN#dJFrC~6Gu̜&[/3i2̳DTmFBEM2XDl72mUઓc4,dp|(M⾍K<{[AS<#h8ͦ'Qi& K({ }&sm6Ƈy@wpƧ؎/0 W=dZ&e*OkƫTƥ+6! )["Rz(fudX)dQ=-M0Q\ʡoE(qr(~lI8㣩<8̈Q,|rVR*sPfUR %\*:T6M+xVM)F'Ze**ywU7!TxqZ 5/aZa!o:rg>%4Ɠ%/cp捋FK\ȿBygnw`<6" 7y|Bg<9dN5Eޝ ``,^%P!3Sa 6`g<:ٳv86a_9Կ\x539[G0җey3) [Q)rֻDIhD#;Rr.Mtqwz{^2{S8-1:Ijh,o9!-]S밒sJ"+19r5F1)4K",Bf l;t{ Lt&5ӞDba*dDLgZ"/b5>!㽊G:ˑ߿7扑) {xk$VLvQ-峐ϣw+iېƜ!IL!ofPʼnɕBÉ}p;d^w wOBs- 7V6tJӆ8uXże(-+H/pv)W)a72cH9,KǸoEj'rdc&u1yÖ)MyZ-CB`M|n%f\Rw,.`}1mPNeT;2F ~GFM&,PbY1y+MHaU&̓BrΦ! 4?̪JeUnWΏN ^Bg%f>Fe̗3&- ά~1)O6y*<k9la- Czz8 *n IZd 507gD9RrgJ_ }Ml Π\['2<ۘi~,8AoF4 XsCę1Nd\92 nG{ʧݡY 4Kp 磏D/$7LSM#6nkMfMpٱǵtB p76q)Q\@v9́S쩙$;MnF ٗyLwGtӑmq`GS9H x1k]GJ/a,#B׽QN2l.[Λ@0,mƓQ:ЮbVK&J` SkyyS#=9s)eB,FC! K0hKqYd*G Y*V [ gj~tWb)"C 훏*Nr)-󱯄gin61> c<^S"c+YQo3! 9wrKNt)-Bi:œ-&otש{6k'N-$ȏb0IL\NA=5#t[)tܤYn]òų`'I*9+Yt'ygj( g`4ƍ6`v:'Ƌ_}QvɮԳ{d·$oF7Yyf15WL6 4_x~Ks˙'-Ƒ>'_׷VI+~-߅QlELL.B4<<5ɜIbVeEh&w3d^݈?Lx@ )jlHFQk3pp7 0)a"9?ګجNUbEGوUDaVVua1ܾO\"x"tTr!F>J/É|䵲HG>x؋g, $)$uvo{GOL  GK6 ыӒ^m`*|5P@G3{5z&#R8*JrP2 D1X)c}ƻ$wQSÐs{;r#?sV^)'J:6(<_3\#:l}| hV`ߢܞc-6h{/`gՙ)ԏr9ZnIqh")S%BE|.HEɴvİo:KLy#)ao?/曱e$n86}q:/I VH",7JYuEI;%(qyGɦP߅uSԋ;ux,ڢMYك3",H!>%8vZL^-J֕ѧN)Ӻ_JExM+bE1ųKWELtZHqCZ/ gw>  |,~2<>}Kn=]BzWP罜+g+Z /0Y6B3 ڝ派ҋm)b\ޏ9{b)*P\t}zƵ YuT!B˥0=x {IAR! `2 >daCr,5c,bvIjR;=yܟk~gi̿&>\>ʼhnr%(2{M&0t!a&=dw;jϏSqC'ɄɣCK8j*PB1[/JشvxNĵSŚC,;i5~#\8͡_!G~P: +鷌x%\:@ PmiŌ)rIц"槢~Û಼ ߍ"h'Gy~6Kp*w>#b[د/sF9nXSƐQgS+y1sDX_+BҬ }|b)5B6oXH*֘.OmbV`G63 Ly57O0&t9%:XJ4/ KQR:GJ:Ez?{1iTC5ow!6 Ʋ2հTCZtej4 L(A6=9j D7&ҡ$>i{: gǷ1"GfxȌV<+-xL|=Ǻ棿<6_4ypsNȩkxd2߉ٽ< >әPvWּԑ_ȓSPuM wcXo$a^Lj2i@v"̓'QfE {.*ǫla˙.zd;94ޢDKܷ ,eS+lҤ."/G4pK>ۖ+ԄFϤNNqT`1W~|3esj>g1Oډrl3e(%T8g.~Jh뗏ET`";}^<(=XJyVRZNw>3YH 궄'鷻 5 i_14ytL21y9ώ^`CTeMeTd+•ՃX֞M.~Ga)RбӢZ˙U8rl&HcA*T{FMSkmr G3 ;X%E2b$Sͥ=E/pnLah@3ђ#Hȝ=ɼKtyLLJpAt?}0gnOl y=Mߛg sx>LõrK"0$ ><5pJ.$RŋPu =)HƿN}ž7{>@roé,\Bk&+Z2mʨuw)ۍdzGR8v8)EbhYsZiNC,uj[ 'b5s:YbQe3ne>UB,)VV1'1Aoe\%򨜫G=kEL|QҦ4/ȥߢ\>醄C$(˖4tvAx.,`+].Y{ *%|8 7_ 9!QD\h#AwV»YkN._CyʕS"c nOXԅ7]/`ZXFlIs-,7O{-?ח2RCY:Oi$|/Qú:,sK6;LHU)X7-l JV0ʔ9E$FL8g h~+\[+rn][4?hn<\b>C'3Nu%lkϛ&5/C9})C"sގgqf$nuP훮nDI8 AJpwwwCpg|ŝwwzzTΟgk{rWMM3̼%?^=(Ouq.'f%I͒k+APBY^; +wټmCkFFk?y0l4#;zd CȢ='3]){9D;Wq#e(%b6a9sX]J}S5 hUaWԪju0CB|fU{53E ~?.y2l*Xئ꿊qsցi/rxO3M,4ȽK<'76#6ƉAn͗~`v]MYa@zes絼ߠp*XѾM8L#lUB9Mf< 2G6{b$KN2f|S'sq1yj#.g7 !lOcgXk/ڀݝ2&pT^V2}ٸ{xC^8_7ghV Z9ȊBgN cFic1 ŕdNe*Dv3;Cx0 O4\6%#9=B0wy-lŵ,D(}epީoJ*$Zi߉7zlS7hO[7N Zd`W=r^kૌ cPgti~)Pɢo(fƾ2?$ʸ(SEF255~rQ]M7*U B$pcqGӈfcAבCZI .6"u!LDžK#i7Ҏvc&`TqHv@!еN4{+Ti?OPubZ Nuf7@Z2R5ful!kspY^/dg=RpkJGSk1SnLAW^6+LdK"mJ3ؘ9 ax,`t[_{6?+zNXGgB_>~JCI:Z@'a4){K6'ܳEH.Lڏ;zС^ZZgDžGbڍq,)W R?!aN(ج12+97J0l*[_UԪ$βR6tS0螚j\,=JUJ.{0))+ sarlpocC/c4gn<.t*7zr{Z7K'j;ˉϿdz1ӿ waI&9'?bčVU˃Mx`D Nl%*o?aV)6)i3"oYNvd]7xR8ͅ؉mL.{pX1j<(DŽ>ƒ©܎=/g rah{Tsb¥Bbl*Y?N54$利%mB3e8-sb0RKvn'!cjFmeDN93!| ?/FhVFtζKFF(}97‹qX@k+q[kbi;(/#JծK_+(/DG#^ ;eg7m$آM^4ҍTxQH`8W#y9 6iqZA2~{%MDRT*xPqnՏJ|a$0AUCgV(YUaE$ o\agVqTl3rOLڦM$u$ѳA:YŅy4\<.\ĽA.\w*{+1Ӊ(K\:AQ̹4)jkzlw刓b hG<^̱*L:&u@|"w;@TwqC15Ul߮g_7 öV>LHv8̧N,jb>vOuڇbw7ٔPKOÖ?ػ-y}faX=c7H#RVUҩRJ< 9%Tg]o-ݸQU뭁J' 6͢*cB<&O$Y(aOi,'0sb`(JJ'Bp]&+\X̍M= u"P >Rz\c&}rIrQx0HȊ("dp8 n0~X؏odKX5y86C߃td7']9%mgd*ޠ  {zD={4MFN:MFD3 nr{#_*UG>H9^^i} 1^95ȕs`$ߞ4=R"aLw˒_|_ /?,>*~dO&!|^⮬υRKMR5{zd9$Wv\)Z05#Xƿ9 f1[;9g[RQL])ת`Zm,fɍUԼdB7pؤR؈$.e_b_>gsg ۚ~VLܜs`r4-Gm` _oWSFQ;Rd&Xk >7U(WIWJ B3|6X~c- `[LǗK"ngĭt_ w(.McT\nM`V6JhZPȣ5XRA\Ζ$AgԷ@5ZI4lQW߯U]Б3\nV-.~*RW#fyr''JP}ySc %\ojt]\|UT`?Y؉}Б M~ͅyE?C8JI-e҈XIdqb'r2=9̛1~pHvK';3{By(!$͑s-i5gp`Gm-Tۇq&;U$c_A%Vٿ}DV9{- Hچء׉*F(5wCYp dlN/0‡(,oϑTorv!~,azKY_U|gk/Y#cp%b$1%t_REU)Du)_v\V{-Ŷ=Fnה{% UL&g:9,*5_}5S*Խ")|~.!Y|I):] Uro9EE|}4 6t WLEŜN'-Y;:s½c;߯6 w>,job楤tԠLM }x̱ayt Z_`墡& |P']K Mo=vɫ.>RA |x6֑Ӎ}qnf㱽Mó)Z9_L|ʹ^,eo?[k$WzDq.>.rb1џC(@~Du k05[yfL]+orHV]5ͯ]8ڄ=F@`:'sb@+eSSr͢Qya CnzP4tv6o|1SQ| "p%GϻK[=: cjZMxmAsCys:sJZTהBR(sRF[2YTɑRJql c\%IJR2iX,FE3 ;iߴwM^wUyU}b@h9S)f (8r=EfWɾ`_N\.}?tՍFس0Dޜ xşge\i[U3#U|Z⍡jZV֢i8?:?kw԰QZNF栗$oH$8zp.a^Iy;poa lOzabʃ4WEpN0#ilk{G7iN,"g Tˠ.؎͕?OhnѥܞHΔdt"T66ΘoI$Syn ;pi%9vk3W! =0IN܈K+Ԯ^_Fq4hn\+SJU縉6UrJwʏu&ױ䂆5,]cJ*yLͱֵW1 kiLù9J4@쏋s3AI~ȮcIz6Pe6do{H2K2bR¦ޤ޴b\XN4%oxl%qɋ1JxW¯Zw ;;GBKd3(GI/M'D8 ^l˹ s )G_)_ [O+xፇ gV'm#xrC}VRh,phu3QΓaE# =.$5vbPfgS7S䍒u\br}W/gB)edWds--kOq{Ϲ21GJq@Vq{." 4p73/c-}pZffYm˕]|Ã1S=9Mk:w}'Ls!Ԕ m[9/9>7,w nIߖ'yK P썒X铏J8 M!26D#RG%^+#DͦX)E;P\o.QPZzjhBɓRƈ)JܶV ͎ .uTZB17ə?[9w5ix]5VSZ %)EM5kKkNҰh Ռe,UבZj=R򜊫bڨO 'a^5\IRKƄ BǢ#Gv&rwae !O aǂEddOku`SYMҠ-"1ٕzDCj,2u\»Y1d1Oa*p/ڳj,8N,KVI"&Q Ks-fGGkZcǖ11%m{r'ӛo<{LCB Lbl C_Z\w jmRظoh1BL+0}nlݩ]N|N3 ϤdJ;$|y. Up_)}W!,+'ر᧪9.57fWռOYB9i._ˁj2NYab{5Xh${x)+j[ޮjf씡Jμl5 547Wө*;ZCZ#{CԜ+l%^H:/I5[DU< ߽cO:ԒZ.hJ쭕 xUh^r\.oӱJᘘ{_áhJW%0ylȎnn=l li>llƲq;KG1.#=9H{zu%zO*0;r^%(0 ѷw5Zq '"_Jq1Vy3c!JpQV2/ets!镎,lDHGS9‘a2}p Q5W3ne2$&'5 XnɀmKx~j !Ha طL[Y^i2T8jXe4ePqE怌}}e(z^ZrR4;oSiH y*f&:c"|TqTM3 17as%稹+>N_c4N 躪hb 5W臊 b Y RSS85g!2 >+b/,T4OMWC]Fա>ړQF^d +] iN|Tp١JfI'zO9-UTƫXP<{b^^YH-#ďE.\v3moܺ8W52A|ɚ̿\lOOp-V,0RKDMFsq+vQ.V x80DHiPN2T|:EĆJũi]fROfSA=E=ZKg)Qj)qpꦆѭ$R+Xh9ʹIŔ,5)1stbXn㨖rndY_vQ#򅷛Z{54\v+9)9`V% W1o^rL^*9U~EѬ%8gnI gEk+b q@G^u%z(KO@vލv_| ]U [a44O1wO` 1^ptsax̟~3ϵp 5]#G?\µ4)gcm9xHݷ>s) "?;t)M9Vh;I#YI#i_7y܇G7#t,My}y[ᱻ3: 쐁Gf zՐ;EJBn WpMphT4އ"C\-Lnϕ/iYދU4(a3 Ɉ)YG 5?^|%JQ.9eg =% |4WP$秚U$YbO jNj/\nQ4CU;bD1oP^SSYHa KfR?/^唷o_)kbh/T!v}mU\x)cj ~9w+e+adMX4U;]`$Af~5j-7N~r703eܶY\399s'"fZN#b{HIaulvh|Idm%Hȩ{jX: h?z<*u&_s/ tt'UW{S^ȹ[^eҺr/616Ҏ߄|kКrGmW,B FgW,N$Bv&s#%1w}ݝ+,[qA(#9e{\懵`•䆻}Y0>%pD)WT1/XJr%L4|+%]|*5=&3Hj&JB MT+{୘~\Mj"}xT`'b޸lib8yY\Dt9>P ]çRdau;jt֑-1+͔q^‹6̍aDBoGC:JOX}v1ǎ~76R 3z8]bX`Oab$ZoKM"slϡ1g[KaHF{oJ }M?Krѵq 41^̔ےL+wX#9>af+X>t%qc EM=y orCi*-҉{ZRRpT yq )/E}Jż:SA*6R2|A N,7^N y!;dꥦabVP+hc]5nBr*'#)ȘEHhtWH >t%u{Lƴ/nU>0?ó1<ɍ\)D_--).Tǰz*.YrGe0FFnA`7)7"$0n 'W 9Y4;t"ESM,-ƎamÆ9nzwoO.$;x(5]Dr?즸iDQ($W8}ՇoҘ3pOhl=j}Eǯ,oޮz 3MJ]r`%6T'^ fuy _$~t$U#A=<9w6eAn{x|_21_KU FJW f(qKƧf2XuJ-c)f>(C62 aH%c)o GJvwVW*Dr\VPW!z7[8y-FdF?&ShSRmS4n2z½ 7r>/$c:ð]IT:l.Ė 6f}D v1ã9ׅFQ6QW[ݮ~n,7*wy(Џrq|Bn̘AωIec:f%?#ў09gZCͩnǎq#S3:0ω>Y<4fd׎4>Z0?؀ui1m_ 8 j?Yd2gk,7 ,f6 q30xjEwo΅q8>КBCh)7s89kLߦo&ALD?vK3}s75R8F2,J+inXBeSVii#$\Z'ads9oW2Vlg-'U,SXd *^~Va%|W"Wp"4es-sƓKE-%ʸIKQ]]%2kyUK[Mn%9TfE͋,cM'VqɠVk2K$n!雍l]ʃ9!mX8w#:S^Kh?͇W#W7A򧭑/[P22wRZG]d DŽw۲rg٩;M64) &SdF:T@UaYOAxjpiDGtf՟ktss7o|qpU MhQPdGNzQ;՟Afq1G|xn0ˏŞp#Z_8{cx8eq [Xň r`t8-D}(__tQ2 q=e"_7$ݖڳحc Vp˲ MPM)D ?0]AeuQ6/}®A4'+BJtc cRJMA+[-a9Ŝ顡>%*&kWJ.;QtD} u+8*L3/Чf4Q"E$Nx\FVDėi(F~f%o's`*#(-g;~wE‘lan0t0|TaIB0AFY0mbi"ȾҲaR媗SؗmK Jmmƶ܉!h5W̔K9х\XRl؋Vsc#+h3N$ϫQTM C*XkɴYS;ǚ^ʸ9 FTR]_X\L抎&+ĺ]WEmqw )bx5>˸FU\Y{ KS:8剮4Ґ)i96a4='KY_Anm*5gU]+Rtfqwaa==&!Y]#it\(G({ `pȂX؝ջЈn-ijz6QoG^7ϫ E ^kG0qۦőĂwhGp[fc{bN[z;*|dqqwg5[槞 Sb];a}ƗU?]Y(rM&,iNV˕H=Q4<|Ή|sʙgWƋ hH/v%WL<9$M+ټOIYj!|MҖ2-rVIL)ڽ دWCM\ZfQY+sېHfWBk]uB8?.MO.k,P]B*"e5Z|U$\:c09F`1i8ųrDCq)G|v(Eofʋ!yO`4 7Rk2?WB_f4#ao<^z7cnki 4MDJ<}u="fnS'{ #R`imiL/sg^ȼm2&Yಝ dWF0`A c1Ϡ ur9+vt6^'1^eAz>lO'Q#Medž=4 1Nl=íeWfMyZ0OϬ4Q2x]5E|؝Œi,CYׇ/e!fB#NfM!8^u ]W>1=&C#R)y"K "2y_qcHT$4^TZL cs)tzs{0LhwruW`JԌ;15 (GNp'F+vy2^ Mׯ?st6vgɄ.~7pfl[oN{Zuu*b5)Fa4~(}Sc8׏xN(by}vx%W{X2~ TŻN5|9 q\3 CeΨԏ N)eosRX|pr ?U)`rL"#po/ړbK 8汷,[Γoxl)ӀjTp@Q˜u$TrAf]:X8%Lu'o# ȤlB"wNyɄbyc(ڑƣE]*oGlfsQe=t/wY/Ιe9D@e%@:i{|ׂ?GFhaWXVf [m‰]9lv^|r6דV,D`O"c=gghv܀{%5*(^KH9fťM1,A`eΉD6Nx$BuĞ/2jfUq5_IxMΗp%ZO`:% ^Wx'PfnW6OfߍbBXf4Ѷ4>Y7LL Hvӊڛ./{iBx(MB0\[oNXp}~Gژ[4/WBaL^cĂdEFx[~w&ν,:Wxܮ0"zNXxIX!\-3Y&"/7F|9Rg;Vڙ2v6% BdGTIoFر͔.ıbMK8b_Q(M0T!p#4kߐ,,.`b G~ȈJPN!$H,cO47sYJO`׏F|Fs $ڨ= cKwJv[UnamwIoȣg{ #42ˇ.a@|Uփ[9*!i#{/n:~l/t'-Q)+K7c?,fI <ҼͯUyed M1;z۠?tL4@>l@o$Aݍl0/Pkr&Di^t˼H)Kkl7jRԘGGmbE#g~dl`!<͞@WcJ2+{1ggKPE<#;]h{Ǚn sp#fϟ;DsI4[su(eY5SUC9sh2~|AڼMAi2d8B [Sl1Iq7A3.5%4tCrlH=I&.8|^.gRv#xe ?s7K#6${灓3#)A 5^yilD\ܞfv30@߯]LX_d-CÇQΧ`z4)Y e.SajK?qh ֔,v[ h(7Grf{v]EnL\?j^z34s'ӘU!/ef]M1w?C9V5o W1ÊmoRgG}*a4 Hǚa̤WERv'_ Yb^g$;Qt/b0zx>ҚS[ࡏi5\؎.[ }D <0*O2m}eRŇk~w[ 'NOV7}#Yڇ]yx֓^AJ[+y޷v< Q:pK͒۠%-ɷp{* μMQf%>êy=wE4B4{5A"ՌWdnqwo'5S;3I_˾Znb4W)M2J*I'i7>-H~sx3uY9?op . rgGyWV! %tS<|2̴SJ;~I㮔KU{΋wvzҷ?B(Mه:U3qw:#.]¹VM+2ňoh̺DZ*ސlhǁ4bͫ`J]ácd.nfn2zynJS?sY2 ޝ %Eph[,ܕIp陡tC'x@.I鴾IeQ\̊cQo SO[Mn6O$TBڽSG:2[¿ι8r]Yj['Ndzry'x8;؆DF.X]sUµ%—Ɣ2]n&L͓Шadt;Sx00D[ggMX7: <X;C 0٠hFHnO^ֆx)w#͹n%P%T3]t33m*J5{^s_?γ>+Kɩt rt3~"fW@xvŲT5i9ɗܵ9ߖC]^Kh{ ˓!_tDx<#6~|z$ٰ Pu颔4PQmV>^QrHG4i"Mpݯ8UB}pqNkCo:HFvJzIm r To!|L3Yi_moyo'ɮPyROWRlFcޜR}+RXNnTn{ᶨuAOhع f%(uǾmPwO/E<E+/+k(>O6Xn>&Y                                                                                                                          w+7.>TMvRMonp,urL^.\G&ss)Gƽ/'mM)#]T ߤ?%KE꟱WI[}V^ Œ R}rKy彷<4>y/Mɽуcse <'.sG>b>]Nn-{qP?\L3S~tTyrF|g?j{q>Ir#g-YrK$8 L^&/\.:P~;mV:&4o*YG~p`{SrVIǶޡRY9/(M3͚ON6W4dfyR3\3-X@+YŲ\ޓQvxS6C-bzq 9 -O1O;ny3VG7=T[wdCyѴ?6|7s8n(н)ϕ<ʒUlL_A~_ Z2 zlZ֘YR4.\TaS t]3[LU-Y,%\,&kMk[zAl&O5ViG>F^ߜo3EםdaZÞd_(r\.>$]Wt ;O:Ӫe~Wbt9}x[&g&X= T.ג]]I z2@חF˜đ5TlrҨarS(}iO:D=FvAYm5q֎YӚk!wם).4:o}6-y:l6=tە7\#9Fmw5n/%?ZO `L5-C~ S5 3ƬFSq;ʮ gWMl4몼/x%9V߀X+U*;"R5[>{4nu_I=OIllP+/F[91e zo;ܩej̖fE1jࢯN1X8)k6_{y;cw~ f3z-ߢ =3! vb'8mN\N|S 篇qLy7Wo+pvb[">p|4O 뇚 1yўkH ֣ƿ#`9=Ân\ⷺ?c9םΰJ#XxACynm6o[8!Ћ Y՝-аͯݰO)Uj[edcS|ԌesS_%ǥYЅ%| 'oپFzu*Uc7'p3iCZ̛+,/h@$6m8ТkztQD~2^mʹ*Lqc#kslƸNlՒqnݟcڡFfoX/ 7ӥ=CMɔz p/?mQ8sؗN|\Wv^K|4٨Aa7w0r(tuh :i[hիbʆѤ8kLO=>DClN8i.U_c lHԛXQB?yU?/ ue)&Sv2Uv^C^PH_7gҖ.ҝTIYjJhVF/זX`OOȆt^>}lyڇ}9ACBXsޙ.w?AiËO6JS=y7-*Xhop삓#-γsNېp]D)y\_ġ`>Ġ#pV'xwݙL?] b{v A̒f82 ϿЬG0aΔ90 [T㵵>[?Q?~i̞u&b[<I|/!ti3-x@r oƄ\MlN 3yo(sBAN_}fz\vJӯYϷy-oC+YěVQʍW3wr/ͨ󦭑#${'}T|{MȘOR,z-m0o.3&>7V% Gh07Kǟy5Ow+{l2;>B~zO\d~ cjqቘ Fč[U 6fPrq^v:seK0Sxi>RIsޔ(|ƍ("pnH,>29SEPNoeOD6qBe=#3T6dBG)F|Åt{FTFa6/=Vؑȵ6 A/fY9ҫ,TYl(%C9'Mw=Yƒ3fEPydM G~]6p}Cs(ȧ|Cow^zcW"05in|1f09%n/?~Lk2GP|`4_ʾ6CVךym=堉Sg\EV^Q0B)H+:9琉52T.5gmoccS[~Hǎds![ӡൣ *c 6!pCY*1b/~<F3aW6YGrv<6gS8ɻlWwiۏ3c1@bv$J=܂46mr[pJYQWpM.tNX^Ryɗ1/uGKiNm.{bf˭XHFZTọL?ʬ1\SX|q l}A厳Ika$I])u Ѭ#܅΁ד{N߇|]P㯎$o ?. Q) .Hi yXX"6ȟ9><8ς8 쇕7{]k.)ȓW8 ɱ(9:%ؘ2S>z$ҴY>[<7Ն]Ibtn6mrIʙO\B?[*pcF{wjRbsKή0z_ô{9l,]-*AP&S1u*45g;|p< 5/I6eQS:_VGgV'3e7?{ܔ~S< ?3YVO&i>J\=:%|r*u;cYmMqPƍTvĴvÝgg3Bjn+ϖ ً Xq}d\b^%;I1%;ٙHt e'AtH/{ޔ{~9)4闇( eH %J/ʎe郙ѪZt㻃-ŔFcXUWKA R *9i; ŽڭNS <٣p* gh']2Or~ fJ2Zr Czesk. Yq=8]痊.M_9r$mHnRsjy-rp8F>CĐ<5ХLÄL y5r&V{3 om)21R"oth- ,f8HܑjhH[r({r <N˝9L^ eؽ wu 3qb jmǮ} )3|-8U4 M= lHՃffbB} hfGz]Y-1t-2ّHHqߟ/9ӏWmq[3[C(NF6_fQJ͙b&<*QVkh…;-8u͚-НI~+{f o9PlLB,Z׎ބzE?:?,+Bubs p%^{`o~:kS_K> N/ht ]s ό)U_֭7dW.١h%U]dlH[APRG2(;mKН϶I#=/3{]52%y/R97q#OGI=-QIBև29h2ڎ( b + V$_fg/*5nxN7!`rJwV*52&Y {J+^tX׺ _zwG}vj+Y%n3fr 99͆C}\{ś^nLLu6 5 eUQ}ضX1~c) hIBe/fbj Vnڛb9zt k?Wq&&e`̱^3dBޓXc){'tOg௧ ?ucpz`R ֕(sm*BlJS !Q)Xl'7dsyBÊ (|IxхhYBfHZ c a4bćأ61D)\džټVʗe+.gRr*'8XMb^bh\EƼj:` ^9fq;I7M<4sWbf}5SG.g7 _g&_~A*_&U^OܵD*w~wCx܉*6*f)m|n@s>|akEs0mj26;O-7қaZ jCCaFA(vҀs8grfN4]^~cY0i>:ی-RE183p-?b%]yL }9[w(- ЧL7|]IJ4쒹.{iϠ3I!p{ߝNV_)`Cc˝L8EL;C߽<ʍ4j350ݞ%zA+<?C78!w6O 3'60)|?ř@s*cU 1uDBM9Vd28S۔}CL`6XX`*=ljMY dR% {5ޖY˄<;W$:^J/35 S;/"~eXl=(9Hf/5M7jZ3Yx5]vɬsdV/RcQٟf˥}h&v*"ZSC&ø:Ĝ gm)ɮYt|WBI1?ËЫk]H bĞVtPѽfLtlH֬PfBض4֡|c\?Z<%x;k:uǔ!{_Y/6CChV;G>c@f)s>Ioh6 V#.l^VvaZ}ϔݮ;*00?iBNSLڡNv;l3poͻO;3<@LxەY6ɛ_⨞X̢=>[$-񧉖S=iu;GrY.>SG34&LJu$υkH3"6 -3BI:װtWΞ`cşC(YƮӰW,Ӌ]99 Vb7N33G;s3)( cg=誗J1Hs12 `h|҃QIP4xqtјdA[}?2d0|WssZseңjWY3 dwgֱq|8Qtn`˪ctWd֜+3q̮Rh UA?BG2qH$Jm$E|39^-\?/̧%U+4KG.#2Y xJ|+fzsneC$)g41%\Nce_Dz*Rs)8h76UfM_s*Xdg2 ,QJcǝeǑ$+g^3fdĨ 4/W~8|q\;ѱ!Iã1É4{¿QomaT\Lۅ˙&8B=U~tnA;7<jWi`1g-4oAF;6w5|i$ۣ)Pj8s v8?ɑ%`:hn1~+O\͊wLyKSɛ; r,.`j Vں as8T\|,q>x*Yͪ=lX˖^vfi|C m(g(]R5)4p cɃ~ 3`${J߮訠Y?tDO(y;M)mPym yϭrEj|fBe-+ -nr!x$R[CLS%^xq-b˽ZvrMq}9dKf$4O/#y_[y32seC?G,/Vpax`|G`d態#m]ʉiLdbE2&{[Tr7hD kO18rq8ۏdrOOq-CU4%qB5Ğk,m޺|&3Ĭ\Jufu~jFYbs|!#]a4xkBɁFrF?X6՜R?=vb,NvF31,VTĽsg90~'s/b= ҨW)R$7 ϥZKʤC0iJ2q&Lη] *gVO֩+}Qc9ݽ28hDAOf(~ ,2V֌"fj"C=?CQ3]:ٔ#sY4vz'wvgs ”.6]ƴ9zKhs~Y݆9dώ1FWּ/ __G48p 'Yp2;k֜;dNlt`Mk|䒮#}Qoc͘j,CR{(whKJ;N ?!݌|JᎶk RiڷNtq@$܁v޷6m+6ǐo]ҵ4^9Z } ;c wug ,m()^`M`-e0bP;3|{&ˏSnazeMNo^(EBy8ijPZEܤZN .2Xfi-#?~/Fsd7sb gqxpF _>;U,qж`_ F\}dZ;-|\qɋIܨnz0c {c}iɭ|u}k[SnphS2rѹR6e~>SR21L۝LԙpDr#!$XW+(4BQ_e^qz~Gcm,.'kQŏ>Nj2*YzelFf;r7L. "9E<^ZC5JX#A>TfeD/J#NBVOdΡJ\lݒK@Y =|>4?^ߌ˄+,iMIӅO0_="-pwajg77si̹7ip) p{74O;Acqm܄޽Źji䴽%Ϟ2}E1|QFLX΂YƏfYHg2L6uPZ,n,3ngTfUPbmQ@~HX~ao_X::lׅq7ٟGCI/(8}WƝ >OT^6bHĦ^y"h~Q|< *! -$ӨBnqIɘ1't<7Z}G8o7e0lE rg k5Yå*v`#'N!C;AEBUQZyد|Hl\/ Vu L͚)T~O xн++@d 3]iuڝ.oWOe2MIovttI7:ZwvG~5q3Wc]yFtCVOp MX,w5ySmЁÛ֎g_F7߲'l$IB+2БS!ꊚf5Rd$w)M s獘b%1\õbűFܱPqa3i'8@Y˓$f! C(Q=6CuKe!eA <2}[JvNg=4֖2ٴؐvds!mQC\݊ԣ)7> ɱ?jT se3G\8{<Σ|X#~i,woS,&!ψ5?9Eħ /*EUw‹ gOr&p6 L]`+Nu0gvgdnjfc{gL9k4HCǒ:LwRO߁F6:5zk3Yx1¼jZo#N +އZ;%3X52(IyD*7fRBf(b;0fc]Hzr7,Qǃ`?w<0~F'Nk _V_D a5ˑ<1G Oă8ꤥ]>EzcI坑J ]t mrYBz& #ð}0lNc)eVČ1RH1-VNIr<]H?CS_{:R:Dqfcg)ӊx!i4'6އ\_ϨyaQơ_ g0eS| 6{ے|)/d=ߞHFj$]O$bw>.u|}'݉!\<€Ÿ3~ z WƢ,p#r_+8lmoȰq\ e/5eG]óZ|[k_Y9UePO8"Ge#%L\"m&vx?q?ڦ׈!߇ qSrofcH}ᢽ^tۀ' }=I9Q 7Hzf0[\>X?3J n)eLʺY|; cXFΧyG-ߍ ck_B`8E"w{QX%Fl8fQr"N/3.5ޒFU''ޟdGwf_p~|s%BMѓ.(Q.dϖD|y*f.oR)#~Tf Gd(~f0eB7cڗǻ{|-pa HvI-;+Dt{+A+|lGvΣ4#|yKz, Qd6G`6#d=.qc!:Kp "}87N"Z4@;#oᴺ!}'W!eqq~ |2pCd~2rkLh# 8+$]1rmOt{] - 3@Mci8g7._x0x$=O &ƣ+b8vu [4oLe)y"lXG kY(d>)6BgKh`RSqە2NVv>:q|BP|U!M 0O#C"u~ɤcj +>~4piLee*mSWⲒ$NbG9u#d)e=QzQWMMz7IEv.ڍK$`un2rRl[ nV0yc[!Ӻsb'O cT"P3x6 B^≲WC4[U@01'HU®4רD*6|C p[1UwK9wTʭf)+B>uiljlL`Tn,aMS\0MI\4/>{*d?Id[S tZo992qvW,DX9B@ <[`b}3k@x# 8EBC"n ^:%[хEwݛu\z@ *ɞEMnXg۬hJcT殏#" y$Ng ν_]>9{oAF\qʡ(!IE~6{6(d0&ƒ..62N*+QYJ(A)),#mdOa@螛Jic  }劙Fv]1]8ӁsH 뺱ݵ\~8M 79\\ gV"ѥfpYZEbK$bӋU)L@:F3{dR22aΣuϕC8 f0,Rr1Ιlcy8s/Qt8#2=RJ% &ȹ+rҒ+%בW|ތ2kGK\EIzW%ߦ+ppSPt_d-᰺-$DqjLC̜V}>bI$2f*ӳ1p)b M|^i䂘u-7Nf&Z8Y<>"|zj&~Dw@=6:=1:Z|Wp{1B*?6Dqdl|"7ŹdƇɌˣ<ќ\^I@&LhiNtY\p r8pM+D/m8` e݈|܅FGǒjܷ/xwJъzԽټ8F}(Φ hh\n偯,|gfF91w݉|D {g>'択3nzHE'Ź jbmn-u41Y̪%LkiA4LGqQ,COANM}'#鉜'ۃx`wWt`wNN#8BB&2zg WR&}l6yM?Hq"O놖bMIťܼPB#9gbǓJS#MTlibt6j?,)QRVrcZJN;*xWJJn'ROΙJSѣӅR.+~+9Sɺ>٫3AFu+UF,nADT+1̐mFV-2'7Dn1s䵉.z&ƊC#D8ZgY5b `4 'ddpIRo3b͝8wYvwpaZ?Gv⨘W'@0͎L(bQ㹽) lJ%1z~R[=ܥQGSGO,;6 ԉ.]܇FUG۶p[>[E}"w>3OgVlxHd4֠2#J=^H&&oq:DF5_J'q ƳluR饘*)yX&g|uq<[ y>t&c?itO${0O_'p[t+r8ޓt$c~b - *ZJaiv|l,dϱbdHgx gl%yL5AAɅW[hdT)cK9ZE{*n)o&g %Լec=wnHp0g3.}='gMbhbPe,]}K)ald.Uń /kx湴gwb1+ƴuy4_ l9a9A_i"q731K3 ]yJt[v4>h<B#q23e[)o+7ߙl{U-YxdaMWV[Jz*ZF& BMekM'9PG/{^MaVE=G8YrR4naݦ)~5+6.bt~*[ v O׶dmnM3p;;ovz^kHé|jkn5gQ![ Lg [Y* JV,Oʳ1HQ 9ˬj52G̜gW͸pkaDu=CjFÎYZ㞉MQK_ȶG&/UBK KJ)!k(So#8k,oG'8-9Wk=QFx|u2w9eHd4^h"~F<60|;fJD7hzWEV3wJ{%tS#&eSODx6lL8O`6_;}? ^%(V&fs39!?z:L$`1zXlj5˜4Fݼ@o HnU v[ 'P+2Z1⶯-,~5c3ͼg _t,+sn ^k@_rR3jk9)גr5Sb De3M[ƒfǒ52pztTo :<O>+H;@-`U$PPAJ }U6ny|BW.֔blIg:iY@OyjyL!~vj`m_J'IvL>ƫS8'S{?NWLn˥8Dg" >ROul2Q" 45KOQO#T_a2>UpnA9delɳR2e4Yl2sm-,MxJp^ʱRΏ3ckeȓGM,ioRw>fg9xY:޼6P cM=hus+7h?[.3!ٌן1ń򐙉UMt'r0 w+XЭgD6ExALlJ8.GӿRJ)b"=Qve!닩_²Zl%tS̖gKIy<|;Plc,zOLëIfK6ϗgavDݛFt{1ӔU{8?wkxG7M%ia:ȍs}&SLTjj0 Ef`gp52 K nز\: uy.Ӑ%/51c;dD5?K@X5[DlqfSW1xx1x/\a#Dx#c" |kĦO{/hYj[y&q(,cr{ي+q/jGJ3c1wĹ3Y:P #Y^1GofIٷN$Լ]ªJfGDVXd316s1OY  HȧSbz>.Fd mKx8{:r@!:k}mjaAȞLPQZ${kh!fRO^p^ &yd^\]kԛFTƯ-]b4}VufV4⁉['YgZ+'~ZyV]˸Ө>YVT^qJZ)O2>򳇙W -[_ WDo=RdFދ9JO@$=N+\tp(D̲lUE>)m-Gl,JBLec}-eR>>+!y )p_!v氰W&QښƱQ)TYSD$",M"T$ݒ.d6bigi1΅t(D=8t,1bFGaC%/HRQYMڈj #VM 2h22i"o|r2Tbif >88[d1Wr!ǒMDQkZwsnk jg"#Vx2B#f{boTqley|d`(1R2c$*(~͔\*dlZCymrشD`Hl^̤ż)g*5ձ欎uUCJ69bS]8AhK} XRT4TPPgF/5QyaガSƶb(\ηxk洸ae-1y%zݬ/+Eg r+.zSte(2C9 +F1'\Kdg%k+6p龁z}ґa [}gF2*Js`cT,8"uThnXfR2Ims}0'f]j%Rgf")Lċ6g t|Nט|; $LnGx2G|}"龂7>vTSIOB4. NM{?5R,3ҩ̵+2kQ -53&O)'%|ab1|66E0u =zV;B'z\|#囓O5Tt:^dUJKɳ%J8K,rQJ8#geC<>̑Ck`NCރn ԑe1$֬t"@1=͏i;wm" y#o#+ i$̕R9loAeS]O)+p5w3zX&HFOfTxMcLQ̙#!ə,EeAѡXb!̤&^j*(%/Ee ^tr?L+- s껳)rՓz@5fΙ \8=fbXFE?ZYY5R{˰ IÜDNKUneMuTo.] [Ʀ9eY"Ռ}3z6/08+ڈ@j=C8c/rwzBJ~($%Uŏ9$m)bϒQa5, V峂ӫ@G^WldJ #k z''-;Ⱥp:p5;+{@A4Z81ȿSSһc>Wqc=͢y0GlZ;k? o|i#c^ 6kro괅;M1Zde-0p%u(lM`? }##\XxڸdI'<Օ^ߝu`F@BRbcǰʌGp:g5'>|,x ;e߿q*?m1\9Gc$ݶLDcS( NLIl}~T(D22,dTgX%DFZ]41ր }[մz0RB_i&*Zz۪"ሐFCGTs)=kԈ[wwGjMeA|Lͻ0;YdT0E>P͘:W22=@۹jfR&Q-Mt^`rn[N%_(%r{`87^ّ9=N4_^&rn> /а̠>kZ YJx{ f~XNds?/͟>Q_|k*~񁆂×}yAƉΛ׻2@cX L{-l=ac_#n(pB-g[Yp@ZbN/s`u /FaBk`]=?mt;*ڼQз(.{AJY]Yka,V'`m] =VNa+du b{]JFٗEުBا"0Xͷ^"KF%Ly_!k2͓3Fagq)r%\|= ?j8~]C, NkԴ҈摏8Tbbj)Z^ӈC2*kO˚9:-<ޤV}5EKnRȝ)^5b*<>t$ԯʹ`j)eBpG*Ѱ\(f1t~[ڔuLRgm9>%K`- ; f1t0zݕJ&8ug0wgb"=X+L4Ub"t<7F2wSI{nqcW:kq~4u&*õsq%:ؖE"=>T̨#y>c 8kȰ߬v='j&g;4~Ե2lcGEn#];WS@}w[nSEo"S޹ܯ#_&~ez+q)QROafBBLD"5Slg9G&)R~,$J9uPd"9AJI XoPS 9 מjC妥 5 hlP1wKM gPJ)?ZCO7DEt #%q~*IF0BdgQ86Cv0AلSٓ>P0hL}.!P2?3Θwm3V_Fu2FKJ^U "q'#>\4(ɕ{>yq'sw;ER7eܟHD+{NQBxD vO_>9zڥX)?2'} MlKm4saJ "VYaa CN]M7})c d@ZdTsMTmeMnYB=&|g172Ui&1dL.T»fz6P0_SO%_vofEP5ޅ3m= B+p`\} >GhdpRΈiZa׬]ᕭ-6fnx]T{$ KKC>P 7Ko%2~O,ec9? 򧛜 2+d QtI"Y1RrSKQ+QF*tYcߥ4᥸䖘i#0[MnJ1L^+@:~'hYGMZqJ9(ZE8m*MׯdGŠ*a*VF?>Dv eqX0퓃ʹ!\MYZ0+yDS뜰0d?ԑBiRh0'02ړŭҾ\8P;4~GN; fo}σaPp+̪`98N-Mun4]W[{maܺ&(WWgլ.oGP%<PsGoC'&7Vrv ~?tc лY6^̩&YwfLxKDXdӍL[PF8Fz1Af*qWcq XBxQy$MNE֡};!A^m3_c` mNL~Scڅ6fY-ښGV|М@0>A1k9ޫSePQ2 Hhe Y252CƱV5.ᤗ[1O5Ѹj!$Q kŞ]h-%tjRjhN 儷SrKK0{VWSUq|icaTIrZ4.TI18-|~djU<7$!]ג] 5b#c Ѭ y20`l_e_cTwgZb\#hX˗TցL{Wda~N&y 24?J%<摽W;KW9 3Ḽ|2L&,3$]Gu;r= ]TT1ꮉLhm^a6߷ Own7$4ZqHX9J]zڋUm\&~?PVu,>'r. Ist,ᘣ*K*bUHcEϕr7] {%̞"A.j.iA_(,K ǗFΘLg)|9PIEXQ€_m3\|m`uz'[1y!Gy2bqKZy0>Ղ5Ɨ pzqM860R[*x1ҊK?bEڷ4cda2 ;זEv0{2TbUa~7y[ _O֭?zX_FN0.x AS~m ’VvX`z('n +M\0&IH4`XBju_?U+j~M!|}quә$6ΰZ GGd֓C;i.Ě^Yԟ?x~$N$&۷nUճO?U͵]Zb"BF =i='xV͈:!1T{u&IO3 Lf65joO(kt~CdjΟ-? 7>\? uٵɍoG#>ą1ʯ;=̓-} /^솔2jө%|/a3]&+AIla\a [H'iR1],B+cBSK<<_̒v%-"MlL-#fkIݡe:hEmsY1o:{ym͑|JS{(zĈ#6||7ݖŠ˅_H1p듑e\^~\0,15\k5sّ>+)‡<_~%cǙR'R>ڗEM%-˥,"Ws[8)u$oQZGƐ _U@BA^_yܲ/cio$d3C1nIWκ nUnqe.*ؚ`{}**K"vP5O[B(/LaPL IwjP=kyrFU+xCNO_Zy.z2>X8̌V.`Y\daGtKF~ď^.4*Όåޔ,UXa5ڹ2cUMv-HUw^x;duye 6w_P2At%o^Cd>8ttDcg"7nN'nUObJwvH%Ժ!l87KWdI tDΎkg2B{drAv.q~W*t=hz ?Fh c&s1x{( nB $%nCpww9wvpU[[[}glmy&tL?}_LOډt_{s;+c!g%dj!SSJ E9\bEu.b{{$*齩D2-Wkr}rg,#^Υ2j3儆(k)%yIzxƐ3s&r* MKG/wopG6s_Ps]WQ}]rF1&|9ÆK62ҥȎfpjˠNx v2-ZpրGuԺƩ wol]ѶFbϬp/ߝ[lT t'^kӛi*ҖآGKC~<0$Q9éܛ]1xۅsn8&4}ܙESo> ox.&\'e윪k+-wi׮J"f Or!rhF, %8Qw ,z9 6jI)0qa3j֪` Mb43@纳d&fз[";#-tvRftPK*/$hfKeAkJG+G 3k3X: \vb%2EΣc. IcS.dn[:nœf2?gR gʊnḬOeAd1:}0T3^ӧ=3f~!5ϓm9,3g:]4qGkjaBck Щ$et5X?0Cg4iu^ It"⚓{iz:#QIp;؋gKs>K4ssC7Qf7xޕzLN/+G0, /nP>"y(-hw|zytG"P_ue5^xÏxdՌ^LV&"3=)Lqg2$t 2Vovŋ~zfZ7‚0DŽٛa=  dC4ɗZ {kHޮۻϧM*931D}L")"l)U3 0.~] Rll!#Jr+b96XV竒 \N(\_ꇥ.b:E`1nhg`3-2h 6IǴqoi$I&]"CƓKOicÒ> 6 Id7YNILc4zV&3I'&p> }hhy%(#I$&ǓKҬ0lESƴ=욛Fԫ8cjĸ.EPH(Cx{pc0z_‡Dž'aw ZB8"tZ|Rȉ;!s+&,Ua2AMd4:*q ܡ'*b?5?5t7ojVEL);JDB<ݎ"H 2PUtޛ$ &+!)4A~M !hUhimf/:$y {ƶEQgnZh ^ˈ]ǰ=Kf;F 6a,&ktary2(Qp⺒ %5+(q8EJe2pe3-!D¾IzۘMy/d7ʭLeTu or<ڀ\N1,6ch'c,} ?+Wh +pVP.fr:yK\eD=!n1k&J87θ75Q4Wcbi, p0oY&8j%iN 'әNb$D&IKeq]REhK,ɘ`|.R:B)\T26!cԲ .jqCY{^0vI0;!l27, ׌ ]l“w .Vk }vT ol˘1^E=l] 7 V!RMMtTƞ{\ͳ8o9:x",3AnO[NvGuɟwM{\\y^2eLcMb[ŐGwb2L9VCS@, ?҈$p176g$|Gq4Zd/;d&ĝwR m5|.gIXu&__WAFSz"5uC@^h.sai4 m/ Ǟա0>6EWHǛ2:QSd7zJPr3\ArB)&Ġ“09ǽԈ|ݘÕm"#X/v{AE_FVzs)8I9f+9;B.rTʩoTd)Jnȉ~_θFe~G W'(Y)1uzC -6| Y2(8qPK8PDQ :C{*ϥ0%:Xi$d/fE+9J[l*+O$sf$;Tׂg0;L!WO@ u3F} ~J?-'0t:1^ q:Sy_)s~]ʦ^[{#{ ] 5įB1Za4Cb9]m<.+#=ӓ]h2'i(hoO*j`Pqa)aE.{ |<4_Q9܀!l1)O@S ^BR Z* }Hvgɤ\Fu|4y,Ȕ3 9zw`D{VpaĞ7-M2tJe4J_Vj&٨FΧq6eſʰo(hK1&ItFGegzx'&9ґlȮ㨭>y3j2l|#pI˰ 1qΏ?탹7ad(fQ#bb{n<?cY:ޔ݋4Zg$(Jqٶ1pbw1rqÄrFmn&zWމcה; blڜse`Kb˞\\'IM YTYx6A3\ōJجwyУN6ՌY-9sTC9V +cR *'J ܎ǍBɫar&#_pCNi_ڬ:(YI0j“*z3>E ;8+X:$k~bX1D'Gz]8ŝq8Ɠ!t̘Q4 ^oLGyLeU͋BE,l pGr8Y?珅ƒ g"B6@-g]\/1I +KFEJuOPdm'ίW~n.EEQd0N!O=c$*R MO=&d5{N1T%VHu$aP_n_Šz}ԏܑʀ}#LSQE`s)}kXr6Ge4(G[w2erR08] ]TF4U9_L-$J7^n8mH}ykܗ <xo4-cQp/ܝ")/Jr9ݖ"vl"lEN  ˺ۖs霌L-9] =V}zp"Xf&.<N4Oa_WCw?&G16P3rE ٛ@Wڈd}F`mp`q̗ k|ψáD['Qq"!$zRgCq f84攟ҧHVcv<*$U]V-> ?'y"kNxُȰPa\AlJzܮ&ƮNص__UUѲ ~ t]UAhiZCc% N.feUYsLv|#Y>-bhc뮴Ejn8HN%0Ư;ѨxntD"VbyT1b6qz_At>%ehyeH+#ZSJQ3Z*1 bVFb.VY2p{'cW=x2i":tHjêw5Uj=1/bU̦W2pqu1.e]/MѮrMᘭ$*R%J65siynŕMXߙAm9E9LEb5|{zχ.^t%?i?P+oa8wSb4:ɱ KeUv{R"3̾4sa f1^v\W.X9 _dIa"hl4a“Q w&?Y]] BG5wv\5t;dTT\{e5Y8q|J0ug\ő|=$l. D ?ಡ~ua 4dO}no~ezsL~)c^d9 v4d5`M E*(O}70cՙizNi,b@V,_ƲwIs >-aD +;uJ e2bU26!w`҈mG0ye'2%֊yq<+RZRP[dlg䴰{kʩI/JD͏"]a#g]K9SUD|0[¦c\j|6d1sGF2IR_ΘTi?%c@jCĂ@RdN&R/sD Iu))e_9SD\^yR+HTUH=Pfw|0`.$j0պcX8L1fLe'"<ԟ>CXHDq=pY;.9Ҏxb6Ox/% Y01)q)-FM'Y{(jaxӂՏps0lA\X59}X6JB'㙟1jPslk:\ώ7HtU%UxU2dUl5E`=zj E^`_ gJLYfЎ$Fy8%2K5Zmbό^4r §DR:z] &s.i! ƾ f2$094߰F$l1btgC&[NU{q ȝzw 6!n>aEG$<5tbƚQl&VpNt_{}8VMf &_P"-rV/e>c_>sn6XzF.cl|[c06 96VZx,KڋW?!׶aM7ٓ<0>| M8DjR!iī?E䯝rJR峆Gוϋ|STܻ ? !ۅbuРߥ.8ᵝ$-M̛!<n{/ x΃3INu/L|[`O"h㿓I,kC03edE=>|" I/,Lh<'tdA$9s=<8!{;֋C\xt&91oK{b]4!wc`Tj2oנUZJU1N L0oZs>U7u%߇Tyś"Sœn\Jиsk9hW \*YtA Ol0n~ѥ$;N]F \d: [.A9hϿ;9o&?@2b0(җ3ٯ粅!s85(CDM>ZŹhb]ƍmyl/)$0ZBB>J8Di qjRȾ02?tg);I:k3~W/)c `f[}f2;ڞ;kpSx,O0]>Bҍ]+ri4] oDk/UяtdU fnb&}UH"Sw m|+}}jcDeFz5sGy} P4 /4 m]0n}"XO $r0 s"#'c jn<'aW6!fPw=km[Ԧx>x& rDpvRoI8{ aFA#O,G13ɰ "NjbH*FS$y2$ְK}RޣDS:a[-aZ&.m~5;OU nETd$G ۡ\Jt?*1QI 3*+`a*)asq^iک!6WjfKSKLe{? K!|#x}7ٺkYD4;83rK8}`#T3O[cRe=/Y/Kz@ +zұY'Gp{={'nAE\O'Q! sg2Qgi:c?d2R;?1|mYуJg oِkN] "c3A>i2ad͑L-T-Lk1R٨⧇KT4A^վޜY~RxӞ}i /撚3 amnAX];;4 "1[îx'Sž)=?O_pEż61ī %?D=uci|7x0{[3CgH>Sl0Pv:lvg_>6b9y|WØ5Aپ]:f9b_tu-mV(wN; lSbn۷e${ *@ΉjnUQz .*dF6# ^}=`HsL2e$r;v$a,.ւ__Ʉ)fT³<|}i+8$ (cC ݥ2nGt@2ʊ>̓Ճ-Ymθ|cQ WI8~Dj̉\J =BLKW\C1S%_f!9ǭp͎͒,xLwD\rEO=)8Sgc*㛏[a*EUFJyH Vlu 0Rqr1ָ״کF -,ֱd^ FE#. %4үxFZD' "pKS[E3շ~ V! RϢaiȻ~N/6a8;5cH Cٱ(H^DC(>|TA\o>D`_Ls0pu5};W9&jV9{.7Q˛_J*+_fHD]5.F~o{Wq uO**+vT`JŒ>R.?G;kC;lU mYElAͶk!4% E9qNe*D)>llDŽ;N< e,?P1Py[ =}4DnPZC<%X %ʔ%#yfMC 7gٴ'恜%!).nB2B#G,Hw'N.9*XШآ Rr?n]轠3j(N3uMI0/MѾlE öEcmΙ]`YtΏ> AS@:Ǩ;ې BցI]s^/<%&ª//(9+2 MSe$3 rDXZJ? sp?S:],jP[/DOG'zoMNj>11Ѽ-IDkD ߦ B²וP!ߙ~M|k*ngf:u4)MW>[˹K&+l W[B ,m]TlIjk2n)x-Hh퍣(~ ݳ0VSaXwh2`'Jp=\gge98V:&2^|Z˹:*m j9m]&bJ%Tr8bRɡK"gMUpwu)K0jHHn +_?ڟ9ݞhbxq&W  0ڹgj+X<k?nDZ@>k 2-f}ǘ4ZMqV)" TG@ Fh\j|-f4F cn,W0LWNf!_,|6 όiµx%r5/OaH)e[N~>.xC9!\=A]:Ƣ1M#k.\*n9ȭu BA,rחrR9-<[FA)[ʉ7S'I?R>.: w#_JWM) fMHϟhRNIxkHê459LY(r %o0_Br\6;*9Rab,VN; rֽaVE־D6h7*VAeKU:Vb6x3$N@D:MӖ(,#Ð*mKg$eܾAJjVrnR2aܳZ1@kp^V5jڤ Jeh+¢VɣLݔhQ miOz'2ꍽ۶$=03ǎ[7E]ŋS6͋ rτNgGW/jhpYk=&$_2np{j v1?e5*LJSVɮY f+hAF 1v+E4Wտ$<|\٬M1َ=}9&(bɤbg~ΘMKc'^dZC=S7 ;6TV'w.,:%\-|v Z=ZFLU˩2XJ/Crv@fhç-!BjUA?e~lJ}^ðL cCڣDL@VOGvK"'b5_s{ /JxI\ˑ\g߹hUJcl-%e!JB՘=/3c*8[Mjffhp57UdF%O;VrJy<EO,d̅ q|DQHN*H"qq9~2)+VC [W򤢆UsyT:q{5իv5UMjέF}*RSAh+UpXi2fҳ>01'{ 2)oZ'ٖ^.T8:֑v 6i<-Sauyl J"$!?Sʈʕ:Nd2k2ʹ#; ɹ9~l1ko1!%l0ϧ,h3A_^xӡ?Fka2^'9b6܏WQ'uKU|!kRTٙm5tzgA ve}qHמk5dOag! Yw(uxސ30w1srL2!`1> l)tem&7mqSAzTD>/wsRFŗq@u ztSxs 'LIZ'7%DЃ }x;?~a\ %Eqၹߚǥ:ds:'I:[K$ ao&WdVC>2@䰻eT`+|56-!Ԝ[MV٬DQֵ4uP}q%QD|,%fY υ"+H8\Uj]UhobV޷X[C÷*հ5 yQ1 ,dJp@zT-U]`BpXV9O]sfw-7])`9#,ũ0k7M'r4qV Ŕk{UPԌ`ƃceJ|q2(R2;&"Pgr ˈ\ J͋25:tQ+vq+?L bK0C#Խ%dAYy0dN%2$c!m>ƒ4S4G,Ɏщ-S NtʛLc#-]p/zf}<.}$fy7,goOK*b"p,`Q;V網796|m%jրP*CP `'ؒA4m;&0'{s8v$yPXA:!V%.$TWN-R2߆J~WUPkUTD߮d[7*4P"uWag!-^C8wN*hP*yV&x2N+n9 O73^ k^e ˶w|-KN|k^CjՐ={[S*7Txj%qjnsd-*ag iZ|rx|;NE]qӞcVh$łĕ3kQc6n, N[=(Q=Gכ[oSc!4awrc1s)\ϸ;S G,#iO+gTIClkbɎ!LFx79+=s 87f3cv?<3̘MqFsٍK\vtE?|U;}#h%3ѓ}ʗ"/ya!d|chbl( U,E\r.cmr1_XBQ#N~75H`BYN8l"H GNQlM$*6UUB.;>< bz+yh⃜rR(xtOEkc5vK4-褔[ZAs5;5E+F}%M+HͦrQ8 7#pڑȥEt5#jyUtMdsj欫PQ -kЖGa3yo~pY -ְ}i.+9"S5p0,H ,BVQ$0%D?}BG6͆.SDǶjzFM]'wOU %TGed spCc.Ws[):? YOCU.Å#Y X#p ڵv!fF60o_O,)N"VerY]Hm,;&fAtXӍGʄ:sʾz&Au!Lj!kki&ߒ2 rԋ 6(Iwm)^JQ,au\%dQ=-F8Kɘ.Я:faܺma0R. i<%")ɤ45&OLdla<1MF\o2Cswr6T:KɸrGk qLϚyMw!TxyZϧ.loF.m9R4x:*٤nyMz{3;1rye"S1m*F2ӳ*c+ p-ggӱ *8XEj%5aͨb wA{|#D8q5' Z ~Wc:YoWRN7 Bßh4r+eJAÍ-uGzם n6uf<|*,gii.$"O ?JBRxRsm> D/ @=ʒ 5%Z3-)ՑSݝX7 pHf3w>P>sC?xh*+бAODƨYBhlc5w{i}@Kog-Ǧ9|]: m xm,nȧo<.&g ZstyٚOFy61o W$&ke,Gq}fކW8]X?-Ⱦ0~O>L [%!s|BӉ`{1ҽU<:9qa,~t/˟ ?1?~F7橑 {[,v9LbU/BVg$2;fq~cs='~tCՕI?ʼnHZHRTlŹN:#$dU&<-&G´|1KZ̾݅d{E_Sd`@j}PTQjohSw+r@•2.td:gE6;V5Yp5e9TfLy-J,1O𙵥of~ed"%esgW8 ' n5))ΌG+r_:qvgXZ%/ⴏM|^])KXJj*T]L c4qת9]xlե*#O?{rbjI121(WI!*O$<ϒmSs(`\0)bB:){ \4T`l=+62_W}d|BRBYD[_ԛ) d",re,|)cY*[UWJ [ە94jԐ򽒼G[Ny=['H+ioG$/>qOָ{Ο}#Yz::Ǿ"kIQDu>]WD^qWo&`?py8ړAmx(1>9U[Gkۀ]0^%dG5`[83h$ ո fMuA:OqD>=S3M`OyR~ۅ\w 3 ](Y6YfIg'5VDp^ Ŭ\\bV3BLR=UP0BR[v1 Tt(k>-ZFt/[M\onMWN-%('8QVQN{rz} j(LI6sXd&-HeADž%,+CuXF]/lYFN8D#2q76ss0Zw%n^鉓U$ C+J@<0Cy(b's$cTaO;7: >,g{_Q2~,Ө6u`j.t~Z|O}Fd.<C+fΝf?/$IO BGҬQbtcdQ̿g)@3955QSd$5ǒ\P `P|`u3mK4rq>YJدbo<+aX&RƉv? 6ؖGB~ޓx{t):( )Zydy''.x.u[ <.n@XihbpR,JLV%e {v T +iTG%K NÃq9J .{-'=f2qi4 ѝ='zgi{}= /,+:\8PЬ-DCHZbbGo]&?鋾j Wf[^Ԋ'6-dbft\sA#JNy4ڛNaf _fB|ybsNgm% c$|bU=z<"1뮞͑~t旨7w7]8(Dԭe-횲('~mCBlf\B\JX7IO9uIBAWӻJ5}8HC` G%UìJ(}5 DeV ^)42zޔqgG16H'xBy]Hf |,~Qr">w(SK#[BbT+Az kDɿ\15 es/ʇSYES7K\͚˄ LD{I Pf_zV^Σծd >Tp9 Qr9;zC^sMprfQuKf;dO{ zem1D:!Zs:*- *98L(UF̐ԷdH:L8p?uC&8-kM9ښD*~7f>յa7D/[p N]w'7Qׄ^YlJ X%=1HcQf7~i͝6<1Li?O޶ cDx:E.",;$2riBLLQ`@<:zv5n:p;tܟǫ@OzĻt{a45s|.ũsqҺxIQ4{>׎vi9VxON NqT`OAry vP:X5]8_Ɨ|;Yga-4ܢ宏2 %]92 +yb%+\F!R|V%":͌HxՔ ^ӱv! \rΔ)Ř`PdvgMDke;5YΉ을| y53JԮ76UiY tL&xfei+~URrSKYk'ov%d;c\8aƞwmi5(L3X>\ +UsWƹEKf "/L{{)l\LFhAN`JN(AC;5x37M?C8=2|cG;OPDŽ3phf<3pj/υӓ)6>ˇN'Nʉ{l(;zE:h//>Q{-jj]SAw oӻl4r$;6(7cڶع-Vݻr0mr zgH! (3yZy%8fU:Z2uGu\;a% ,^Ņ_\קݔp萄tZLF. |>Ep{+$4 t H +D.M秂FϤ\l+h㝋GA!_e2#@yzjY׎ x>udCSw֊>ky`}.IϵTYaTI*:Vk4<)rߩdRS]fԚ̔&mdhkڴq3L8Ą"'2f=& 9ł|N֦h%h2AXz]ulΩADmKEMc۫HNghmăAƃ'𼈅rvP =ZN)q:_PSS lR"tb5ru5f)[{&\:r|Tmdt%irT+Cmӿ(秄)ji1E Pl)5}99Q5kfHJ_R?.ԗǞXuXD$azVhaBmYOרtvSB̯^)[P0}83 65f.c<"PmO:6|oͳcٝcɩW?q\0lΟ]P)%97CcT rEw;¨#+94yt}i> ɘf *ؾ'95bX9kv__;r2oŵlA =I6ahsGMXt27nIcKNmWrrA"sڒKd60gLÂ)jd#EGOLT9ZEUb$䦒BGSZeՍlөMoȿY9QU-]E#fd5JgWUP4oj>irMCQ*V2|RPcZȺj)}ږPwlxv2!NKpG'!F:qTWپ]KW7&^\[~mֳFj8Guѵ"?E *ZlsrG~1{>7,N=ߑɸ%JHتbmuhM`hpD!ᇐe𧮄2s V:N#OA>II$MUMڛLAʓmǶ`(##)cT x;pHztk8ZC/PO3T|nys{=ߎ*O.ŭUJp0sӁ*[ֿBz?g̱Ga|Rw,}f_ˎLx&Ʀhe/z3=x>'sg:V`MI5bZH(rcs %<8  9TF1;NbWlHX4&[1ə4AMt d c>~vܕL*Du23Z:2j^B櫨բ9WD-/jqOSziPӿ!;4hc"ݖ]:JY7oDW"^Nˀ2Ԕ[[T1ڤ$1V ZJyg?a/6ؗH^P <*R)nyfG Wfqkq$ p@DNnLۓACCxqfLdq2Osov!+L| (&Ozd>iސS!fpVM4>Gqq fBiC*ѠCƫ9gw>W;rƍ{`IES1'(Z.d.fw9ӵ 7La˻~_g|oT~e-4>dXKt9';Ejo74&!!j^Q1)j_USMe%+x4W"XƱ%̟/mVRJ|+dNT!fLrg80\˕|Þ%S0H 4WE$3ėmACdsHŸWŘWur}z;i܆\$ZN.EOEk"ڱy ݹGb,t%t"Px}~kh hg[;_2rTWVA{'ړ#]w [̑nn|)Dy0[Je!?%n aB29>Pi:Bg"wOҋd{jϱKȋ$[ʲmXו)1[.%ܑG(,|鵼/b%n2Fr$ӌI^ĕi9:Vjd" bAgW~wuao}&^f3|aXҗÉd}=ыf:hɚl+3)֬C7ų:5ed2^:g"XNU#IoZsc?ZMmCKYXSLS}Mµ.U,,Tz ;Y΃R(12l3 N>?l<ZZ/{J((ۣ:5ˢpP. ש^t^Xiِo>]vFtџWEw^񪽈vr~^yfbϩ޸lgn{g=6\М7E$=z#y3'4q6U^8/…It34ɗ潃": !< m_n'M_u .Oj8/:qxwam)H6.+ѣ+qB0vwf4ktC4\c xa)̓a|`jWNLr8.}2j+[oI3>X~ j 6~IA\Gg*hk |b(Cy)1X 0V=URc% q_c&fڅjTX4PSA ⢌& dL;+e\Ƙ/rUhFkx8N˟R%Xa-[ix$xڶe`'`Uy ߋ>:F{GMCf_JR[3k6Z lV奼G19en)d9Ǘc^W S TA8JX:}Z>OǾ,1KcaF܈q;7̰}@ w|o͊4ԥF`f ~kk;{47jJC,v ʏ'xl˦bWK8W7Oc(#Kq{^,qW-OlB[D:b9, +Xsi%!s0bP*mm ]$]FZ75zg/ $Mέ^Qt#_Ɵ;NͩefD)pjkuָι\e\:jZ,^Rw9;]i;ٽWq:т6/50_K-:Vq|9a}] THǗp/Z*A* %]*/\GXcE:䫵ԟ\%wt5%Zvaudp+2$@1EW~*-ǒ4ת7_>XGuY)7M mYJu/.aggPI[*;&IѦI\Ftkc|R'L͍"Dzfvdls@ER5~q'7'cg0mB"{Fw&!W>[+5be"ZW7kj7q׎q4 ɕ<%{}pwј1ۿ]%BO~NcXN(Gkiy݃2#Ρ얜<&PԡmLؚv%¯'p{L74?/q ™4sdy.t6(8^dWnhٹX9ϴ CFE.تxDY}jӑaXI?%3Nǂj[냜 4P>G-pUl/fW2KٓǩY*嬫m dw;*兎BWyS2|7n3->gS[K**Bu{WD_Nk=zR A_JN̓`.at,n{]lؠ~thÑ=툳.s"'bٝ;lגS#6+-[bVjS9Mj#82j>]g7RCfFЬK#<)a(x׎=w_b1D#X0ZGb:G,_6הOV4GJ Q3BLJy fl;w<ƍn81h@濢^3E4]ޛ{YlfY-%Z:#tx^d .pn.k& >TtbB6Wxӽ\%ATJ'P۾76Bઞ%lvp5RO2 $T1^ %;/x@; Yan}i۸?w󹩁e,^N='9wW,[J;' =[^߭ ǹnӻsGVpL9ыp.u2$El6>Pӵ+^.ṞYOarJG~>tW:4fQ(Ȇ 4?{rifC̪n*#.4ipwV6{Ή 42w# 3)򦨷-mEP"trJJ!;RSlςc*``\_BhX 幘Clc:ehƧD/5':Dwho3л`+"O0WfO nW"C>JBB_9kb;+ ;XUlǓ0hl wstvpVlX5pQU sO9mrb"&Wb{#|?/osX."!{RiDZl$^<~@Lf>‹1،e<)ڂ(,)R~)J%y[ /8٦/%j%֣9J"pfcpes^lMyo7z`6ɗyǠtUnSfWqf> }.7c36u)'2813~ҹ.jN= pFbd~b6_FY,pu, hE]MsЕVxkU4S£_Jeva8v{Τ-8*T˞O˟Ɉⱳ=mKt,`Ԕ"bFr[ތex g֫8zw'[mONti͕7=޼ i2쮀cTex+#Ǿ-gV?bx&)W|2v^F .'V%v-Eqx`%mr^8ILUI3rޝ)o(}e>NXbųm2禳-&hi: )T߷s_*ۨ/| {rH\,D'Zj]r^!{>mӨ1*u.ikLf/\N/k!}9Sjϫ.yʥl/(vngXThK?7::<gͻDF5o]]n %/kYڄHFҠ@B%oG9~`u펤7̹=۝3<Q.*D߈RpNXz N~)|MąoOrL1u}'i}<ǽ`1KSsUA %?> ?ˁ=Ʉ}'Vap)~ّC^֌XE!-c\BL9qPw%}2._^Gu.}&c93Jib-*rmXٸ׈7*8g"YJGYw{ci%31ADi7gapؤl-e3,_J^7'NVgBTeA$d`2B\< ^_Ů ̺ˋ^?Ԓ0t Й?5;mTgHjDe\ mߛ{7 fP}g6Rgd1Xv`^{BX9 #|6 34q9H+ٲ/V[ɸ61kChVݓG=cCCxMj={ XmJzEM_!z'(;>cǍ@`wg"زČB0n{ns4`#U6 vbR|zLj.c㖕1נ|v|*'3TC"W0TT\I[G1P"\f?+WgW[\%QM+c 2Ci/ #u7s4Am.&q3t 5שR98)Ag"kIL<+,u!/0'4Ybq Ml&+M#uٹo=9ԈN0Ѓ"EAn|%ɟ}wNܓEU:FF BԽ'XOu a(R#1y? Iv=Mڃ~KFmȹӡRX>!3ޥ9T6W4M3.ܸʯ8'4r)yY<Õߧz`ϨĮhi{ʫzn&-?zY7XU:'K9YʣѬ8TN)[8YqИ[?+g2/ .eiKKa~$A{{1t@KfUBەf) xt O2rmhE>g\i IR4ߛANQ9&Lbd WRW}; 󸛗a8&G"x6''3rYs3`t;ateyuM;mGW_܉®ZdGqU0|qic͉qF|aEt[_> L$(T3:"zq>6bF -X7ۉq= o..au+̋VzS7"K!W8uՃoB3jqKԷ_LX;ƫt+UuRn>(:=Zq@ )\SǝC8pɟU~T̫.xņj0c}8ˉzGmk3.A(<7NS1WT-U~9+JXD/b-*\TZR_=ESݕ'{P7\~+%V]-**az/4I9Ɲum}Ɓf>,ƓIktNFL2[+5Qh8gi^I?rW玠 ,ɡG| )j68qnπCeN[٦n6,Ԋ~M;cm³Τr呯cE7o;1c w<;Zi iJ(0fhۄ|jn[+|Z1=gz9ņnNïɁj4JNo̾Z4[^D.5u߾{Z1N(\=[RU`S3.1:{{s6t^G4#0چPt z㴧>Z `NL=!iX-Ib|,#F9"JҤUf.&Py]0i N23f[a%'Yx,-:_W/4Q˥|.0ɹ>A\.-ZYdV4#FQ8$LcZfb5#$9n"&2Z==ӉduȫIQS|ͮg\řBZB\}JO{մ7+{t76G5gVݧqiQS٣k-1q7!Dƻ݉"o#F_,uV{ډLb񦤥e UORV$_6-nU 5b1[p'č\_wu\b\V `_V,׵f ǚCם{π>e,qsVB,i–[MALf2@sIߙ`CaJG4+S=kT}w+N9UK1wB;Vd:}4퍝 JI8fs~]z3'n̡ŹBnW+Z^Arά)L/HH ރ*C{<ڏATdm&'2aܽ~Dfn| V>vfNkZVףMV|ڙN_ xɖWΌq+~1aۆ0f[E5BhKmu7U㶢wkUΙ!+S, Y͗V SNhƱ"? Po&h!P˙td|GRo/b^ycOLf8{0p'h;OKf2P~? d#{mԀ*cGwg9.hdaͅx :Rp{壷?vJFbU.Gs WZ`` T$8(UZy:X^F [QH: X΅;l[iyn%Nl֧h)Rhk5BvɅDa|:;&̳0ׁIy&b+ʞ9A/ SIQqhƲf:Ѝ=_ 3gurC]o(6NA 7ǩԎy9ln|Mrg+YÎѽlp.;R{~b@sz XC4xP2늰^ =pÞj;XՍU~qa0Ic Y\^_H2.TsG3JiMRl ҆\ s?nD4x pZtM:/[AqZE|W.0M3&t zK ds,99V%,օKbW Qձo@ ]z2?d()+0m7'X#~&&ι,~T{)}؍p~X\TD Y7M>;uўO1z/5>zr3KXae4k}4+ 7$ ~Ms 7=}IDС=);=B\glY95Ҏ=ݹe!p-*v er #? )U s̨#7@wD:^V76Ƀ3J "M8n˜gI#z1Ŧ<RY̩J0ZՋxJ sPRXtgRW(=^ss'֙0k4!&t0[ K:eT Ѷy)l׭T !&7wT.1#K[dCmw)-{6a{ݡs,"[qG;|9{Lx[P Kckӑ6cB[cnu;FbߦP<ñ[I#CN‘Lat 32,]'ɋɀnWqQZ#: wZ3X}IX_Z_:WX6F]-2{A"څrQ ^L%(E8LxQܝ.6|>۠3˕|(M'9 "a4XSj\ʨ%yrzC*촟5yvʉ"K牰Ջث6d=O&p['ަ;p smsܚ#_>;9kpbͫq36C8I5̣ǏfqgCLX#7M %G8rf;"|c:>'3e͐ZD,DK}]X9^vBl5_k8bhΙWCtCo`P-VnG?8bIT/7ikjgA1/gpP ءiKiM'h䕉bx!m(9;Y54vhU9f>Hϟ|;dA`-3,-h]5cm";rǢv0jq=-W2}B&eo9JoJk;tΐϚ=sYhKj%mHjAY ț=Ԓ1)x0,±2Y>/JhdrID$tDGueD{?h $)Ucyw,Y+Y .kíަ<2uSƚq5DYq0z\gތaBr>څ To@4kUHnt!ј7XR;MLdհ_˞^ĺNb8WbCؘ2`qE$:L@{F bՔ.z;Yp.V/b*Na|{>{ڛ) Q+JAjUkDۊ>|oEI+x3q9mCD&I%2k܉`ƢSCpsʷ W*òVF?dۼc^*{vP8(_ޓT}nD6"/z+V:e;;N$ry+mֺ$ՏXF!s彆QAYan Ј-oY$~&T,$0x&}vAb-H9 opfʗ'* (:ÉAQ<}@T+tG]Xι֑og@ oZǹ?f?Ď3DD:JisR'K xQj0VLpAiJ9܇AMJ6s;b;~ޜ`CPvnZ]O/;Lp%Gz9ړ{ VS4_3Ѽ}EK(-О7n&VxVs>nmC&nڌ0Px>͕[|cu6h/rGD7̞csz5O;iz*?^/Iji3LO1:0!kGFs'⊋_3nO{|pgNs:j;}Ӛ- HmʹV,oT/66al{##!fx}ˋmjý:?S62maнWbnBo21@H<2]!g_,xkk3 S.֟ : U9&颕vaAbM-7;RёrWf*_#:3-S_9/<]ϕ9Ł@+n3/Eȳ"in1rtqZ#H:E\\hnV֏ءD'I}nIMeJc;mEf ѽKp^燈g:A~) E;IϊU^bkJ;J[%gFMqozME'gUku>5rMT]V4R)p\nqPl}ڪmQf2'ʬʉWUFOmb83dxFc.I毊`+&mvn ?Ĕ׍ў O˩D-yV݊VrfFmh5hC믑l`3i>YbչΜ?׋ښ;fbeU!ϕŇ Sf62$qC[ֈ~(Zׅl LJ!S4[}^6ORq 5Cƙ鈊g j@o/}yBm~]L^[|U\q%f7̕[.|W5̚Sfv aC'&LDؼz|ٛ=wC\MEnw揆f]ɚ=aʜ΄qc}u3+s8nP^քo@1峵asDGU ՙs~L穕_ype5}wC|5"ʹojRO[O>l$%JWbg3ēv)6j":| kH ebnZ =:ԁ\?͙ dj`K1Na־}e⢧ Oz. SG]WTFw|7g%־uېvɝ9FCIw$o+Z8kBV\o]N Oc.]4֎4Q7}Reo- Õ<H/z9qȚͬywfl2F )͏Y#^# WG9 1PO ͝1ɞ ~T JC lI@Zfd8t1`(f$;6PNh7+"=y<f *JT"=3H6r̘{R@- 阥ZTtһto'#o{aKf-uGK-xIXNpt`!MiJmA ~C`τ%dn,nv'>1MEnp{:Fxn` m?Z]8^%(6vWwuy ً:t"fտ[ǝM EbϢ3 M=lp'ri[bzէSsW=r;%-1$&ƕIb5?ʝcbKE>Πڸ>Ii?^w VؓۆlYڛ7zlZaΦԯNY:WS5 Eyu΋/E߿r5f =x՗SxccN=c*_s;i#t(ʉ<v>4GNFIEa\nǓi&tΆ>,ͷcx-oCV2c;_X=*Ydy>XO[ VjS=TU5 .GwZ"U`!NZ>1䯮8۩%:>,dY3U=Uޯ4,d|yx2W:^e^ u4c1lj Tll@3Efz5vZse?ݭGd4u_ g(Ϲ oN(n}m[j]ӯ%Zԋӛ7Mz [a500[MKK(h6gs`^7(HTXmt0ޥ*>hfJ+Ӈ7<5 WB'[[e%=]w&uj*tM(TO'eR( 5?+4ضc,幓?h:3;滆h|˜6ʉL5Sw|1}BrïX+b+f $v^#e}~;7qxb{\O'?+>v)p;ӛ$GJrsjYz=+>Ʊ~[4?~ ‰I-=b/ x:MP;qE,#D.Omٙ3;S٠_0;u -\l1-4su`qaWӱŸh~Ŏ>$>Xz# ֘d 5@ˮ qV$ĶrB3?,D*+vC/]oF{DaxNX}u6Fl}!u٤`t8]ChlJV.8lF͋u]сOw\R)^]UT!$$ݺqڐ$_=:7gs/v1z(_9*0uuÿ_J/(̤nhֶfZ$!Z8<҇9A<8ɯh s[Z0z*#zm|VT(1 _DCh&(JBv1tT əR'm_={jL;NG ,Iif ^T4gߧ0} ݵ;3^F'On dWn[&ʒ\f-.֏ H\m 33#$DKYхg-ԁ\?LR)ޟL&o/Z1 zaoeR;8.=΍4CZE9-H G*1/ ܉vR7a#IbqPB"dQcό?b'3Et:NȅѢEs>kآVlHSv#eC 5W$8 6};mZdCtl ؝Bv̓Y#GX9ʄ5|I# Kt:ɸEMd3(Ov< άɣdK} yKցxnucH%UwY~e&'kьʿ)w >ܘ*]F2a 3έ7Ţ)Y2=S<${l/޺1X/3p)6bBUe<ʗ]#pvSke);mui7Ul2ήI~?YȀ!HRV> fi|L6JGQt 1?lx2~NMذ]4,^DvpՅ.wi!Up=[f3ykWQ~g4wE3mQ0n}p#.bLQoc;Hb~clpfy)x>2v)^nDZ{?Hdv!C ; {#YCvm/.!89fsA7QoqmW9qɛ,OŌ߶7?lyr]ѮNEc^0e[[tOۧ1 iãᘟO|F 3* iڜA~<z=TՌl BS''̍b'?V6sPODv*S͗pT&޺ZҊK/eu-S GŃHfg F3F u du'lk'vp|a6tMcgF,o(m!H7OZv4FXe4bLd ZElmB'6<6r~?1J?KBHU'>>%d,E[#CyC"(I`1egW`PNy:g7q֏ecq>.d[VSgTrtkJm}z|sdhT~-ʹxajIF/P }:J{>˗0wv&y+/ueg\ ֒LMSEM3q"1;);؜]~5ni Y;_-FK=_SU*VZLBh_;ܒ'ˢ]%C{=n„Ɯcl'sG[rx#sx0J͠WwFd6#eѹE[EխS|_բ.O{< B.3{ e'Sɨ8ʉγ<9c Y[ʶa̓}薈p7b8iJOУN :Ǖg"cB9 Ne :&:|(7y1FU>6]$ 7qsO2;/5Y@Hc̬[Fȯδw&Nx1Rdva$<:f}OCNJ'o6X _21}"OqHAGb*^JWAJ +:e.cJqH5I q7 0#ܸa^̬~[5]~rуIr_Wl$UUAK-jŐlNX'at[L[ VDBgv-n,7p]2u8Ø!NhJ 1nI~eex 3}j1PLf P 1n8La_ ZHNNzp.z;Rx߻ڕ$WsR%p"|.*̭kT%@ چIX`ΩtK2Aa<3"Sfhtl vf+-Zaܖ 8u-vmуLjuN~8L嘧3Ģ>"Ci8?XoPj2z˘/>E0 UނLnXY:р akm31И=`YmJ#g/W f ccŲ=B1狙]GK|m 8*yhgV&Eaq[Ƌ76Ĩk;Y)vNRTIJu!RWiƦNɂҟZh#(t{/B_!l_ĵ^$fry1O?sRC%/FmVyUKc@* /5[syrAVqtoB(&N ʱP]"ZLM& rYӊjl7 ыRZuOJ-|g~S"lgNׁ"g6r+5+BGOo/ֺw B4z_Efފ C441#:ī~8lL|:=M66].jϔA|8Pѹ ;Q3l0h'g |/l*Cs1I8N|RY̢9'FBۗL ojK8tsmg"\4Ƴed]rgqD~vSddM i9)W|nMB7ˆ߹LcɌ6q߆8}H`/.' *ma%KVPMy5V3p!2vXZS 혜?ȪNeΎl[nH~`B.Z_CͦXw%<&9?x=ʼnlɇ9N(|Ln7߉.W՚1 ;<5P7Ql}S8>2)K*͕tP\Pw48ɕU(r`x8;Ӡ5Zzx%mlt. ,K]tM/=cڔ2)^[9ZL+ 4  bADUͳ;U8k=a7q,\˜Zrk-GbӋtEwaߚfN4E˖366m51qnG,Wy2X+<ߑˌQ?.T9c2 *e'5DS3ÛSYŤ+lL iܓ@{qcZ&ʙfQ)x6$kgW쩜L7\ /$&Lw>r-6'{)gXʼnOqؗXdz_'U)_ʰHY3!XY/qH(Qe9s2)@d4['b+.Q "?An}έ4.t5 [ >h8E"~őek8š|;αe=οFӌ}zsxNeqTvD$FNda=?1!`1?uœJ]G641E"9c˛꣑ӽ(r6l*2߯ G5I?U(GQ-v2$7k)c +_ИhFs/R-1c!'JY;U`]>tuEd(~GQ82OSjgԓRXזj<0y {.?Tw5-9cc%EwDtcg P`avڧBLcs &'C)z m#!lĴYeԾ3Aü* YL0жvXV=z4/`p/Lyuty%Wԫ5Ҳa.lsUh?-q96Me1&)輯d<~>xui70blKty~UP[Log}.Hvňc6ގ=WՍ Mq{68>ZN#h'Q~Nf'C̉j CDw!`XƍaՉ]7d% 䔋pn614NDP.N KB}]qh Fw:ϥ^L%dŔңiUl^źnR{pӗd<`V˕{%y2W&vh>3Ãć+kt،1-G,_]h34&3Wg hiDj0cт;&?PSRȻv.OO9(s% /*^$\3K8q7*,s[PLƉh<1C>x,{n'g} {dt^.dN}ctE 7+n[_WnS:J)ƴR.bgc)j"^&`9ܟY닁SI<Q %\풇*5P˴$uq__m+1;&bZ#?hgww`l +2ASSgX#.\]; MVcK%ve`oOsSxY׍ =Y܅07sy#!Q4]_B&!isҷ+.с}Jv ݸ Yܝ^JSA^o ~6xRFD\^ zfQ5NB>ͥ}Y]{[xa@+g"Y]w q6:Vpvr|T5E4Ξt;uE ccUң]JܘEq40y%)3ӚUI>jDDg2e?'C9-AߜGt0?-wbr {[ሩDG| + 6gzb~CNoSq䬩U[bUUJZ=E '伌'ehj)X/%F*óhe/m꘳[ɲ$eQZ~M:ŮX'}c$IdL 9 .ioaK'̌pl;q/ 5s'&p}*Yaa"L֖?Mf ^n h} 鐒 (݋J>11 \Ɵ`GD50˪IƏj_7:Wt{r}12`=Jd uKIp'TA{jѬki$;ޏlnI)W&L bRT ƮXxJpH,$b%w&ޕ0/IwxJq<2!hS<1~tZjڞA$\š(U6Xw`ғu"1 Q[pώ_l>ųILn_1gs]AܸkE5޲eS;˂ymMnCj4љ| ?:c; `{ZXcQ^f\B_z/LRO晛0e`Q)Z\9[+r9 V)mΖ"7Kq-J)JMBE509kza}v?#]N %h k.x!/\4v #uDQWqh&e5}SΓ$s+̝u[rλVD|3Φ(OgX &?t͸a|!2֎vƬqwEWYpǣ UP*,IɽUٴ %o' fv|!N+丫4Q%Uo ٽ%i ^B(gLKBO:Uc&‘͍(jG2e%os0vN6+"H$xcd\ klS-Rv1P~}79ѩ3w2哅L~F`cJYڄ~/z2ܜMtw~otgTQ5|=1v(CWQ|Sٳ+E"cp.#J8ѭ13Vqrf%kڔ"Kò$ 1AL z.B]2L"y?_GKN6q p`3s~t-'lk~.CiRye(rAQZjjS T21{f3XyQPo1CSArT'ŜJգY@R5ڏFzv0Su\0}ʞ.9x\J("cb!\wE+J,WpAwug:W)i=[,#0g*b!S* r.ə~FZM *dZdbBEZq}¼71_(۲c9/E(kvY;n+麰J \nj l/w)% ̖]B;#TEГwtU n,[JNҽ'+WA2T\9](ߕ'K=J ݽto5йMcX1J“s{3+TlSb m_OG(y`)d2U06WpL~=R0XG ei}Aofh.M|+ KR}s_NYS8zq=7wNdeѴ[XzUL-:u8G M~>ȫ_Tfg'pgS,jY^Z7$u4Q8RѭрPU Z:c!{O \D΄ r)9%H쮌 *eU=Jrڿ!s$OZÒU4JI@٬G eOm4W&y> mDZIuXY!Nxٛo+"뼄{)[hq !JWJ_2|KyP-_LB>VX1w+<*|q|cgrV1ҢZ.AUVaSj@cW|"ᡴR75}"ZNHY##f'"%^*^jܐSQE*Up\4:(oizRI2W˙G Yqo9_ .ӱ&Ws%V|WArn}%[U䮹T9~UhZ}Ѩۂ \%YI-Qj7a^d>lӌĥ2!ټXYR"kF%: ߟ&|!7Jy+0F|=oHG#t^pÔ <1ѫVGo &+,(|C->Ւ~o TUL>')I΂m2vI9!%ࡖeȺ7g yqyPG;_E2-H紻?1a6ti9qf7kGiM6Hꦯ$?]Tzj \Q^= h&fٜː|>yb \GK$bG$*C'N$f:?R*Qyfs+ R/%or(j0+T psԑ= r{QUUa߲:^ֱ馒'6VU}{;eVJ ޒLt fhm!k 0neUR66|!V0m[$k7Ѵ͏ )9$dYP@Y[4' )z;&;1qa׫ DԵԣ)oV kgq,IL-I(oR$3FƬ:cѸ:VVe==;O󾹬K|k^B y@Ezy~U۾rNc-c3k!C߯s-u?mmqݕ|]Zş5n'*HJ̢ ƕe;*t6cU3\XN/-osz[Wy@Bk ż*$1Wt.fT)B?^HBD)UyLϥ}p'C9t?ˢ_YLMexP qKSٯ:IX ۷fJ ?pyZ~٬rK%_å湟# cP, cy=}IPG)* wik\3zx=sw5RգqWJ+IOஉb!x(!\?" Pn-_S5%%,1OYp|bPǖ~=d#ĭϚ_#w_6٭BT٫9QmGmEPdepDW91XOu傩:=v1χC81[͇)GV`oOX}kjD-BT$'P ղAƹ .ث8~ZJNR媒%*ĝ dY qd|`* _Vx=F $g̵_.9Lj[-VT0+=Sdb Qޢ|ms' *FmVEMj 9n{r*Glb#]Z ͓QJwY9>?$ )Kx:Jd| m˥qFf)Rj-gޤ`= $h/?OܼFF4%~±*[Jّ*UT!S/w|)g>;! RSצJF\aD%{|}X&Ui(Q ,.'OC0xW#,({6] L)?#Sqт&C9̚# 1ࠚGZ!O^-aG0pf_ [sbCQ|q&@/w9qĞ ^t'3+ؖڴzԱ8{MFƴh vgG,5Gӧ w yr^%\ȟfZkyF|!'ccSύT 6(]$mQRyPGK%#' \+r.4,͛+Z,bW Q#l =Au;.C!+ q[WL}b"fhbqO>,5A̠bjwW92Sz5bLNNfaz23cE5[ٿOb֨SzKrY!ЧlhC.4A-q3}\[Bew,q>g2yg& %UI7K(;Ē/}8zEoS`TyO" |g&.>ɠo|N6+ge~W۲7 U;  rE)VMrR"tPpMܾQ]*I萊Zd}t|rpb[5I竹  G?L6R8T".P3(S*0oN[?2)>Xrw|iguc(v >`|U+M;=Λ,7ռO8pE0GԹͶKx=52j PWM ]Y@bGc|Pp {׻zK&&2e 9*oT-xP] Թ:Rl*٢9#aSW ƿs Vgt|+x4k:\-:hO=;*YIIUnU2;HAC dq$j2 N-@Dݣ%8vR0[||V"Q`pn05sY3& R*L,p./򠱼K5V9Fگ縸63!YG[9㳔yQ 9sxϏ~tm/fMdG7N&ZaPJ?8Y͋H9ԯ3X3(^yN=?nl),ӵm^X-L7`(?`Iuc&!x>aOdt£1"YRG*V{ƱuLQfbܬzoҢ »zLh2^KtFwb k2N zz=ymN<땈,T̋)q((a]ܒD~ۅQF<;A.^šĶc0M46D6`B"g~9oE~_A(&5B˛D9>9d%si <)LNjf9FM:T$Wu9iVŧ*,fϕy둈YۮE>ϔY~B\d2;!c|TED;} gl=IbuL,"KYk@ꉮWM0(9k!rw**Q7e\2/s,R_]~e!cط>J8Nt9JDu&c2#JH^Bm6qtM #?PJeb}X>2.bo9R?;(ڦ!N41_6+8Xe3OS@  grw^ia Dt_&{\篽)],d~տf,.! Y7k ߖh&ҾG$hqr {T&XB~ZzV)}K.Uбt5$*?{:Z7j1w-P3`z9 tĊ>cC7hxeB+) 9*$29}\ b Wb (aQ hŇZ {w@&i;_ןDp&ٜ*s"Fږ164${|;GA8ô2pآmrZ-)ib [ӊAJ>Р Q-m_^(-'\xm21^(%=K 2JxGFXb[jw%>pP){Sd\w 5\EjG%Xު+"//9/߉ #cN#[J@'BmB(ď3m&cLYʙ ^QdtSse\A,XcΔ1XZ8;rA6-Ӳ#ّa)Vptxb}O5gۻ;͞_?*w~k$Fc0aSޤŢ-ոab0QY*R yN56mdv4yIQd-噸v~h1wnץ:u7@d t ޫc #NK7JBq?{R f&ŜUv\|Kl$5 ,'iQN bݴrzMӰ:Jo*\s_'GZL΢<'yދS 72  -w 7 [ 63-e s >/6W>sS=9;_?BVTd1+šG哜'#6J|.a%X*ak2Ji bzvl*ݳB"ݯEf+g}}7>պ2mΓxWqL /grYSU}T )2Oす7: ӯv[iWgrGtJ'l0 ^(:h-8]nŀR?m;"זŦD@(diM;6x%Mڻ-6wZBޖ>ܕL8c<xOϨ\d ܭ&gNe.d\n-gu}Bgp2gL}?vнޗ%}5vaW.gmVyц9AMGp޻)t܈\Xr'Iży^ƄF,yV̟қ51L*dTp!yW>P ~YRJ( )ʣR 9vGTʸ#|r taЯc"g/%Mw2\D90CI%+p,,#EVK9(ZXo*kwo 6"fy2MY"I,"Uc/͉D6֒?eX\%UZoN&'u/gf OsƩXrdƅ9=zgu%~Ag6xjMb5݌(h+[:2sj.壥;zsz9 nw34ab=~m[V5`?\? 5q ^ Wt.7>G8u`&KpK6igP4g♄i&e} Cu4IbjLr>U ։^fh [TNUrU׿Pʭ/E䞛lN0$) =r? G %Y ȭoa߰VچmXЊXE##puW#!ZYL)aT9a\ċBSħBr W2b`zM 9TDM"N9J iS7 uB,J kĞ]PQJxHh)Ew1떈~_LP2;+d*C).΁=>B5㗔aآm$N_4~`%ϳPUcP+8m$iى]N Û1Ԭl%ou c~?zW눞J J%>=E,7`ZɉpXcOƱZ}KV)OS8P:aVg㚏AI-y3c9ob&v /?$W L{r+ m\iӸyc[-?^U ?#[3ӑϝ}ѕ?&.{#f G(V͉$<}+G5Ê4d9j%_9XcMWYNiSΝ:Vױ·NõYfqFJQs}I>4I ek$k_@ˊX]QąNE(r|nUE2"DVMdjNZ,MXLn? ORx>Ǣx)s#pA}Q޼iTwg1֯oO !S U`GtzV*(ȴ Z0NB;1lyw'3k:DHe<.6wO#kMg]>I+z|okv#gQM3AXܙ{HFspp~Y 9ן ޵EI CY5c>o1˪Y>,Gyo gG~,c @gO{bvcOb?_x 6{q26 hAΝ*)ex$ʸK\5mYn\5{OhpFŰ)j^ pH=^%ޱ*Rkh'tNQJ)!^&tM-m6t*t@2c00!㛠8є][3MWhm3ȩFg` 6T&XSxۅ4>P@[6?i82<0kY.zp䒄[s:4/sM b aۭFKX\eK0S5|< Y w($9SN,6s3w—Kt_(/#\~<#Qn$,LH[M8wjh!=+ݷF\|%9HCyJF/O4/¡S1j"'rc[ 39ԶBke\yПSN&$0!mI>ݐ ªCeƁL6y,`Xsd eMvچa&ov_`p$bs C54rԣvI~m1=7 x|p%KV]F3m7W%gZ=M/OX9pR96[1OpF!2  4jo]7(x7GFCRv(q_ʹjzM*5󢶖 y-U`R09HiXʬ ϛOc{;dO'c_ C6b-gSeZseWXm,7D^/r8Ǔ|(b׀S.30 0|>) 9τu&Zͅ*39\z%>4=%,!Ŭ}V½%L'Mm)R=l(a{sͥme™XB]Y}??cx8qI[_W7vAGruFsB|QLoo*x%z]:~-g bj]ѱS =1$c\jK~Vcøb=Jj1Ʊ[{FsԽ# 9iu'VU֦&h~߆|s&>V+-XЁ=:/r#$ 8 zG 8Uԓ5پ؃8ڢ';ח*o3Vb9i&cSfy6*V>`VAnrfQc3rke/-%FYv7GC.˰X5Gn8Y2FV$UŕJUDE#hh fg2vS@M4kVIh ̺kz1D F(`֑/MIu*lRPW͍SJUcBn 6Uk:Vkf u5QSYN͢[TBvĒ_;fآOpT,"de [I-bFa,֜piH&Tgq: SL $Xb0`6(Zsiw6Ͷ` sxV_b_`,oH!!\.3Y. [LFpha O2[ v &ӎWCMiތ/_:|ؖ5eTuda=֎Bײ;_}>v>"\4եדa\(=/t؊_uVoBqNأ#3qJӸ1Ł=V4X51hNċF#J`xno01v yc'4guc'%LAu4y1.8^,=&6O/Y4&=yPZBܪ K'ǾӅ|?3GܨCtD418{{R92$@"3eu U,AFǞu:ҷ8'r4Ʌ4usr*gG&sb1<&ξYSK8'rVr*5Tsm$Q]C6 ghw^ Zjʵt!JYXURn+U\ayܔq^o϶Hwиaél-Og̠tϦ1 IM"ilN瞡f0]Ӡ<и Yx" -\FXF)$8秫?W[IO*E-!$>(&U0n%6J c FGW檚x{A0{G+ď+[6&uo=I~4'&ܙtŋҩ>{ރ@O8TӘLi[2\buz0=IJ+{9s[/F;sfR]0/p}@3N͊CXrm0CY6J >dn2ݥ$nS9 )_M\ +NV//ƺ9؋98 ӎAt R3sQ񵀝+ N'19Ŝ,c}ExfEZuFƋQɥ**QF(XmOxLiTFBBgHs1.Iy(d霔sNĶ>HC)Ҙ6 x]Úq$71u;Э)t.M{2=5 +gD:$69TLbw&;Lgڛ$g$йAC۔_-aUoaI&xs~ "9*Z|JK:)#4s*,E~YMɜKim7=:U0K9+ .緻zubEJ&H^Gޤ`RE4ɯb0 E l,~,,͞oٳډFw=yj;h)v'Q`_nM$E|%a >Y(!1!!C{PKL=3EA/#˔MQr&s'%Xk=ǒum-g8Y'xև hYOqOyPJ&% 4h8ySCVWI954LUQ;CA2L²/YL2e-a}xy10~FGq^#%2*=Juh>e%K-ɠ(]NO4 7UhԸ;qU3TE@d,-#>DIIKY=R=a4B(&q'AԮJQ*FRVCP-zF vcS3YF4BE>iI_ze؟D$ұ.|:eRy(-2\B>O 7 N[5~W1'By eB6פ][1e8[b~dqw[VpFGFq=y%Ul5-Gd(B/m+ ZHI;1ےљ3hL0|m抗=/Ƴ쳍|iPEA.eTʼrH+"{_Ӊեp9?&g%|-D},^d/$wJ`*^\Mprx+lNh ?3:AY:9=>\: .'g iەUQAXb87&D[LJZV3BC >jRhK5˕m3̬
^=`V07[EF4v3U*Q컍4Zʱ{\rfṶH*X cn$gh-<:FJS5H h\BNQhf 8>恴j P>)xz=Inx(&[D4Dc"1o&g06>틦S㚎$״t|/Ҧs!3NLjNsx~iQ,}lgis^߽8ܥ-Rx/|I(Sۚ}I2xZYAIZ0@~,Ss s*q|[IO-ܿU=Ub܈$R)OvJ9D 'shdEV񪉣vq:^KR#3([J0`a+X5vA2]۽%pgb6 qsx'#lEk{>BZ ?:k-Ww%ї%&xǰx~ gS=/ǰׁV׼M17*.URK]5k 1qҢCpBzJԔzcE,V "$fпtwufO΍)É 9k gp5͟Ew(,܋O}"LGRN& ߒaEmH2y`35LS+%?1 ,sxq`Tgax.XAƉtGpу9~yt,qg(FBO'r@"$;9ήٸN k%c4B)슲Y;1XBހBf̵0BA|cCnHϓ&罱Ailޝ曅d-nh1x= Cubh[G%؇VҲ~TLZ9U1Ld/ɛEf=n9JX"}j2 \$NŇI\a&=I׍O0әAFJNj*Pu |r,6/]XwŠF1zv&0 1{XtCB͡(iƜ :3sҙx2;9.q y:KM8xœPMFJ2KP[9[,֖*&T$橝~ZSwCc9Ew׵Qj:mb[*,r,NK{Z8m%k5 s:5SR:˚a7m4G<"Üq?ǠqDž,c oV{ZŽ03#ӹv)77&cw st'@+TgCP1+ Uqx\ǔޠ|8{`l;%UdbvSaL%Z9mJ0ٚx3*N>3P7>Xuc}~cF)/[J;/QZĵt9Ky7= +<g/~SJͣUJ.1qV!M\9$*ft8|'䝈?1 i2"k/Ÿ82<{SS[`FO gs(AÀ H8')4ǩite4F ]W3}DJt"s0wH֟f}AitTC *,`W=~eq>UA|=g&#iֺMGEZVfud9M{Q},RdZȘu\]llTDY(3lkWX3D{iq^acmW Ep-ֶI\؅^s[3: ;Ɗ?GkzvNJc?BNWGy6iQ-oq 304dUz"2YĞVDt6ϻS;c1®/Vy<#͏%iu6KӰGq5# wXR¢I7ߵ)!{1;BM=nSy׭uf:ۭdUTQ<'o_StV = Y$7rtZ!~69KA3qWs\dYw} \G٦nȃgl**R\ttԭ`m%:)JC朴cY -Kk%L90o0{4bf?,k1:G⍋Z㊄}2HݘdkiEn$9OGA/2W52 c50PI-2掐3sk2"]bRV`Р <%l<公 ,dCBpyKHҺq无[X2 N.#cK(KfGap*E#0v"f]JE%52P`9cE\^c zUӡf,4PSF5wKYR.˄=zs)7zS5j e 8Tߏi4͟q/ kH8Oçq7G8j_^E¡}.\ɳ?NfBA\gCÁI2.fyE?l7d'JrB8Y7 ~)Ԙ]Y2M96φ1?/O}fpn&*vLJ ٮa%[0l.6f*E^`GLΖ3RY*r 1ϝ"x:Ҳ֮6 W4Ѣ̛*6mQc_mw^NCE ֯@FH ˚ <|eIfK[3z C$oKIsOMKLE_>.Y@BP"ahp|*rPVH҆)ۇe$/}Z0D<}E(N !pf>|:G gf6S`bijw8KrՑؙMkhWE9m~l Z&՜2#[ 9֕89s{B?8[}xr49ُK;X2Vaf9UdߝIgLFޥff6&g9 9]r=SQτatG1ܼ dTkKYVlqԡ*· rޣ}QG( gNݴPw3;aNKz-2pJ:.e1oމ& *Ld\=cԦ\u0g #ű&2XScc~237 iSJ!a& 4̜qc'mSff]]fffƻi㞹;i%k)e>˶GZlj)8v^7K?c^Pq: $|}13 8"ýG/16z,6;R9t</W{7þƲR2;8EBzڝ.dPK)Bid_{qWC&l_* fkxRC]5(XI*뷪 Q`W20qm:muoO̵MYh:k]E)GDb0֙FAx08t3a?9aQ@")<OUk&qk&v%fAn>qyM.!DFDܮ2,:15OuBq"%:9ѧt"6$?fIH/*xRݦ 2g6goM5g԰lCp5u8UE*(B;"!D"%#gk!3xj*ڮC;QKqr-fjf`? 0;vL䴏1y͍L3CMM7ٳPdݏ$ϦBe^ŝPB&;#:m4o|̿3rPs4i阢ayYrҩ@\`;[|i0N㢹#.6FQB)RX0Oݓb)ËY `8n2!6R#Ur$;cmێ ukauuff lR9ȃQ=MLjZZjsjfURNX=frraѣ>ϘvI1``d߽7f>%/&|ΛmEQ#&hhΌL),5.6s *L8^ A3GvTO~vGP -t|XhOxxy3}_"[V'a!i ¨k?NvcLnKc6y3zj`;[ݫfj,}QN,,{rla]`U -T&w~J*X?Eaܖ۷"o,-? dh 7*Wj@~\)cpqO3&Ndx=|``kz1gtr{Ӗ1G ՑzNMEExwq'Q~'N UU/Wp; MUn<2ޚ]-ǂ(C(Kd Ri?0ϤoP9_Ark/gLg&7od_RO$U u]0=b0mpt|sN;(Wq?LEnr)P!C%KWܦ;mE7NNDŽ]'L1Vض?c[zsH|΅3DR-aq .8i*suN"BnUVQR&ҳR d\qE/e q Qdž}HDe$2X2I/F~4W1,w.|h#hO&¼(kgIlZ>ƕ\ݧG;=DŽAO*}f6Y_鹼yU8}a"]a`5_ZRI.-uZQ@UqVjt)Rr,z v8q+Q;SYdHOfscQd>hU 'Ί9Щ2䟓Y?M_uǝ!lXK}Tw%155S3͵blZFZeη|;HgtrʗBN (k1&nkR>n|.#ndɏйrV=y\pZZDRK8⼢b);Eׇ`j#FmK1'rSOr߭@~G9OZ(LPQl2J/ޚivcs1lt_K5Sʉj g0qi8FWȽ LCc(fsbwط=s)/ \]I2(<0tZE.8';Ilj-f?`ȆhDhtWͤymqq3&%hVuױjϓ=WMrt-rktzU㴥WGjg_jDz`j_ڟ*UQݽulRILT]Ȑ-s<lc]P"E_;$iXigS:c=#qA|lE;UAn 5\ghqR0zƵx/ȧZՉAIMmh,w%(Ƌ >^ bHJGv-w} 'E2[i IdZR 1Q,jƛKdOgfH"(^0"Ã/niόz&<֍E ">`9 z&'F ƉTHV$A1&[\Y瓨=ɏ&N?("!w`΄b},Tɣ1ˆ61L\l RI 1g24(kM2, [bl/GuZ-]YqXQK+8MAqbpG:{ 5cS1Xs ǠAdS?!C"CȄ>IMx9ڈ62)xܣJϻ2nFZёPe_*,%k:En9ױ=Cջ|cž.|Iz3ƛ%ٛGB5Ng8~Ysǁ#w_l}F/60́4Ǔ{`S&߹/Ei^ں§*hB諠A O[x2kq kؓ=j˥vkE ,PTcWM'wN `}e['kxW2?t`l#s#M5)ߒ۹tŬ$ꗦOJ֖r.cQAR3%Jt+yBuu(hXѠZg B9-i(:7?ػ'c6"YDvOFOfqxè8Q !Í7zMb"gxp`$lp6j7TMNs^5wV臎:N>/՝*]zD%wWs).az16AKe+Xҳ!olcaDdc_r8TNy1bĸgtO }H5LTQSɞJi8^9߻ ɐ v.Xd|80嫻 CMi0ܓ\;Dl 6l;wZ6_9C+;Ww o4F r9=' /Sn6Y N}Dzx{YWq[9UxeO*E$ Jrd0i_{QE/E81ՓjRsod3Y'DpL bp%9$Xpne&)_ b։^̸ˣC/1iylqDib/S- N` ;h$tO}5cHϗ~UCfbq K\foShJ)B) |mL$0\WuH"Yl:ʳl܈4.J8hl?y2/>-.'P!uߋ*yt6[~J !B 7NcTJeJ4KTwrWW1yk gs77wve)=l6ⷧ[K62l(L4AAu/5"8NLE\@N\B7fI4TQjA_Xg}Ͱv>f^2)Y}KdXtThf{Qe m}=՘-{Kw661ڵ#K/ m! tPNN\(%+袗#cK" pX$ ~B5rW6.XůhƃBַnh&,$e91ks872V$\00+P/1c,X+{"Z*Dn#gz] jyմ4X1*X(-.*jSI++-fAψ$(Àb9⽤ib,dn,ObD7s;8dWIy ZrXauXAb- aU55Mj8PZCj˪yCj&KtWbK|)eޑƚa3){vuW mXeçD^qguARh仦억lV:851(:Ӝ6d4fߕae L)UAW9񱥬\FyW4WqR[H̍e` }ɸJ̩):)XMȶlniuaS?F&5x g̤(ؚ]xkȥs`WW $SoD)]cȘL98kOk&4T^2E8Δ9 fn:3cujGU(~83$C:gB˿DoO9s2bt`B/%>ܟ:\c zUbW% u<&dO=@΃*LM,V"rJS4(<>IIaW]xWE*6WqbiPCXP͹Ul+fom ?Bf d|wUrk'S&] %KhNXVzD?6Ox+ɉ%ʚ lIwT=SY7 lu?>u6kuHY=A><= b_Ag/jVΥ'M0A9GlqWL;6™sci?׋2 |7z2c5$QD[e֧a{2OΥ 96  `[! ;|l+noȷg` VF`:!IqrlPH)=;RˠZ^ͧ}>Vd#O|s}dBە􍂟ԌK(JCE1j-Shc5Lئb;%7+MR!V<̤J-9Jų +-gi5s{WbݫfQ m5Tfj$հT j8nQѳ;5ۭ粤 fUxױhD ?UpdaajLkVɜ Ѩ|{vNmc??p1; iC K|st3X։mOFnydD3k}^oj,u9NxV(d`{9G>S#U\E;=Ec^^w_57ƩY/dIOўU)?clb?c==Dž4sF9<6pFHok"ya/ 3>8 8FJ<,~:l_!/ rN%^DZlniΏ9",s :ZYt]΁/hk.9 YV^M킨X¸0.n&G}ȑ WŇqY6"ei-do.Y4SJ){wt6fqoa6aK!&/]ka5JSS9;L4/IjRLQcI-vrw`LD$6?"v151H%>͒]Ά WI!yb!Ҥ'5 ܾʼr1IMiWoR-Tl೷yV uXU}B8E2Br#5~\ry&?FGŔ/k KAFpWE=ۗpڬoOUs0,@° ),IGZ/0D(s+΄#Kd4fIhdjgH6:OOUI^%Sf¬l&;_q[nZe,ȡqi##i2lY)<:ڵp"r0F60o/RO0R',VdQ*O %!,o=^ gnB})n$xXŤuLmtU &+:i|Ow\67(["R-JPzrz6el]˜bb/2*ܺU?EQ.!)NaA0jL ؼ|bftߤB*BGdl^YiJ1/7J,WR_kJ J3J>u`{,e2v`W9QiI!2Si.ۓd)<+1' i/.U,񤗖Zkqְ3W}qf»J\XD =kF鉼Gf_CG  ~:vX_/W-g1m5Jq%N yI~f4iFvT.YZ)7?'p᭫#K])JnOtd<1{* =ulR7<:*?܎e( àǥem+ag,yq+^d2#b`M09 A2mt>*DX^%z[,5ϓ^9ń A鸏Dd͛9ti)J)*yE.-h2f-9.)m袂:GWBq5V1_A=RJ%B&tټ)MoY)ے0Ĩ$Ұ33?^|o$]Jv.0*k+(PI+$K)*G\-SZ#qV`:7h-\G *z8L2jšG~8U#w",b!._+=:™6Bqӌ#E;N6|Qm=v/v٘N!0!HT7sq=pG2zPvJڈh_DSи{zDaa-||E oǓ9ә;<鵱 e dݝZm'=<0 k1lB Gx4l:crgUcgFc9܅o#" 1,JƎd 2J.u%,P.0@Rf /U ?♰Ł}_K|$n±^ obz*I#fIs1_ڊٿ'=bH9k &|bLpk?~*GvWΨ2oʩ-컂U4*S{E߅Vgqh{9bꌐ;?3bcxJ. Y"|5e85.A_Y*'gL9e˘U-[%oUQ󳗊P+9w_VH] T9ttGiO$L$>6Eo|ZG;+/6{SƬ2ɲs9+a -/E:[/xSje5GOOw-ُ*y5W + 7AT>Nqu7LEK3.Ňٝ;~N?/fz_~i}19~wGЦ5,2ؒ:(S[ұ!_u{1Y} U"aMa~(rP0'-O)ʜMɺ,CTb=@iw4rep_*݃QGk#Yydij3bm1`;,N^&߰Q]O6CR5S+Xi+8 f)yEkɚ[8?6e7Vepld!#0ˁ~E6aHiۛ1NTțyE :J:b<-aNkKJέJfh_;}19~1ZF2)_3-H}L +%XnZ'\P1M^i#K^`n5o+ۨ|wΡU0Obɛx͂-HqB/B yr1S6P Fï:j%0BUB'KEv,_2f:~YRpw hlO}?1V6qDG[˙ 懲Lv7>r! 3ozj[;3ud"qH(1)EV Dt;Ǿ:ySmC'ꔴE߆A݉)j[^ΤO:hD#p=Z¹Yt-fS13rqdֱ_,u-doc)x?2$ԋ(_U >(AIr6?){eb F0dojj_ִ>&,uקɥPZA -؟cBJ\5D̈`QUI6%kVܶ$FO_Qt_9?,nDmVɏV1u$Ƭܻv| N/,Z}Dᰱ6?l= PHtm/};4xB|:H년c$ k3V`LdgE\olA_oocI\*|2=F?ʕ>ʉg`bȉHPb馤 D+3P1/qEB?:%P$L/QqD3\Wtg1th,ȡ $)`ɸ]ÆdV9M_Ne %l>MBΛ3WTBލn]TcHy1J޷JS )Ŭ\gf0 c,y=u0.t%>Tʠζ*$REI:EÜH;Q3e'?!qpƚxX0JXW.cX\{%e40Poj%ZZ_dj5 L$:|rլЋVHL5vs+O&I|94C]/E<6XkbMs*3a3vHH{9ͤ.ꛍl ыVl8 c5gE:}95Q4Is#wv܅9HȓӨCDeIǬj?aFLϢiJ"30KB !swd-vӎ] _)l?&wL) (iUxyYT\9,*phPǹh݉;TPԀehVM{"̘̤^TsL`O~2EYkR>Dy5_rT윯ddvsYZN-rz^*3A$t/V*~s:sAʕ!<1"~(`C[)mH[/ާlnf}G/ SF5 PİK6Pߚ|s\&b}?&G|1asj-hg5Vlkùf(9՟} R~ tR߭p\IS{2F$5r-,̨ iud~p`@%]0b3\8ҁIly׊o(h"M8ާ?>I.GsOsE6XO'rELB%? vd0߳bRFvנdVB7`›}iN8tt4^#'ilj܏ aX&PDWo.Fi8v{n*zsD}‘>(Gpy.q% 믥%76/ε:3ȵ7SlRKehsmڷб==sI5mXϜN8rU9LXU@MiKe.2f;٨SꝜTSpX9cPp/ YּVy \^'ߔpօtZH&. |nTעBvKiRʽZvжZw Q,ƴr.MgMp9 ?fnzny|yA@M$7j7NYߚ ?gCsW6tܜ>?amϵ.R@KW+\M3xSLIѲw_sةd]'jLænX9‚vma\ /1!j)s Aт|NҮh%tsYlQ箦GD^4O[^q&5Em_clfE3=MIIF[=y dc/L]K;EnG vn\N宙;t(Ha^|=JAapwksK@%iI; %\ fEH{\]tcOWbYwX0ݲ9%dM6s: v<ێa&-hnYqO^C>ƒ!1jƂ z2,#0RL9sDA e)8r|E&B-dHܖN/aiu|T}sMG0qc 6%D$hVUElE1?%L,qv9;lʰ$eA\cmu] ąwww'8wڻ!.;]vu'!S3?Ο̙fNzuѫ~]ի*DY+XƾF*zWgd[K'%."kI>ڶYs'KtПGr`Cz*^%l4cNh,3Y[vMis98kॸGIL#n zX\c%M/W2N%=Ye_’㡔Q29qJiuN OeU*LjwhhVB_DZ\TNA)L{p6=7湾z\E6ӃeI)!̂t8M`a1<2u'dW0,TLr5k3xNfp>؀J60{ 9+*9>a3ľJwNp{ڌ؉'i>ey4ڟTw6뾔0OUv/4X)|E>#{a6L1 N!.r=7y$\Ēk66~,cİ`_4'żGrO46OgS6Æ&sZnKڛE1ɏ쎜̇eh$uF //p&Fd_*7v bVˣZ^Lcä|C Ov bMglΞd+{exgZp`z3­'GjκM1,G*]P 2>"ngR Y'L:.&NgwTIZf64/ɢප*ʥ8DY1S%3az)zhYQ9>H"{gKp CGmQDHb"zYI@񢇉9/V̘xJYl3a_nb??lRBd<εI`>zs~uܰFY>A͉t(fwJ>-cr|-Зғ {-lԚ]]u.n:d<Ԕ@g›OB0λ-T')JA3Jz/󳗌={,m$&jƽThcӤEޏ*|eܚ-*t]b6%Ï)8(eX* *8"d♖\j&:e&cyR ȊN41t6#? <t#WRXnCYLuCU5];1G1A&qa6Ù=ֽ\~ʮYTz^ar*Sv׃vLv9{(_[JzVu+kQlogʎ|FV_3u',~wL XoY| (To? ɢfG;:X=OErڪp3*8wRYwѳ5wFPKO oӽk08sh6(2k:ٜML6ldz\srةC_ML.PV3 9,W[#A~2ҸybJ`?rĶ.cQA oġOh7I`˜=dBqvHxrٟ>%wX%eS &a/%shC?ж•LLJ+[`+QUdS߹܋ZaՂ(wZOтk^+L_ه0( )=dg5!Zw*~ my;Cj^1,J@ A9LY~/8H^0'|4q|K׿R [f<%f+zX7#4.QMq7N"jrnXTؓ/E# gM xӌ[]HǪb< iLOnV0"#YNalj \0d}&]0Xɸ <{֑Kn/ ˱d^,JzVq` 2ӈa;Dž+|hƭafD|H2='4fMaH>@_Y!|Ǿ/.q^%#U1sio9Wh\&#ԗQoES'SY _c/wSg$4"l+ V]ji!?!)ds'c}cˑ69Jg2gHEP=IbEd4цk p7 xU$w+bK/rη}xV;%s$ ׵'ecWcdW$5#TZJENɢ$0E\Ӆpt2r`\ r0+h'Ybu&vlaŞZ r$Vgb]oK0{_Üx ep.nK+&cpqJ) M>q~Ȱ/cU#kʵ _Wx+2Ji@m%حK,lA6,* Ui1=l8 9OB/UcSѾdtZeS843)$_!r3 d/ ~,ܭ ]:ׂx۸Sf疖*˕22ǻ):wؾԫZ,4ݬ1njޖKifs!=gFΔL@/ LCo\63zOw3qۑa)֜7KO&=dFfoXK8WGp&5^8/RD*1ɗ(G%>Dtk0[CynH;t} O/ <GJ/D/-_;q1{ Yߎ-DtJn ++ѠQqݼ!AoQ,$N&o)| q&K˟; cM|iQ{L1=x.|;yx9b (cj>q~Iy?{Cu9íwH}eד3>HʠMR$$*%89q/sP+ü]m\bM?_ʢ2 *M1j=/OIJS6_ *>COӀo> M 8[}yVJ[V*P7Q#\jhf^y5j~+1AZ{-лč TмXVȅ2%aPSl;#ӝ[ƲPMU8DH-GR+K} ;6=bՇ=.@3]Ӕ@cbAiYAb K/j4C˲%j9`We}[5o𦚦MbnS)niN87l ݷLĶ7'/0L #V%s'X>_M 6$q 9'pt5H\b΄vq"%>7,r4'mѴKD'0>e 7΃9f=b)kf!!bw5^u~k;NpgOq=4SyTIt6xv$/їBy#8>#7<{A9ӖS'ㄦB:_LKl;NpާKNϫ\tf6{Z92 'B {"M[ *l,zRkZ*ϕ BV% .xL9 }-P`"-dPb 9%U\T\<#e<(cB'Vg ͓Y1rIl^.ekBJlUt)Q3VSio MO[Z{k0Zbا|W}MPjj^Oc)dN9ɔle Ѭs!"Ճ^Y]K8i\ԛb y# 6{m5 ] s新k8ߣ>5G^8,h)}Xsog:tc4w8;sc9chՒN] ]v UfBk B?t!i]jSUmAˀWϜhpǙ,s]bĀ]\[ \Zg7F13gzSub]tFOl 1VsA&?8зw%p0+/opV{2C A-pRU6+FS*9̌r{ 2$f0c(aOm\b1*4+s*0tWH]ՊO1; - mk0،{愅j!Kǻc_߆ί"Y<*)eWehWVe5+%I.6~4S$mVL'qO*+"|ޝIIH^=d}sa,_Yde/$wR6 yrak~RyXz4+=ͺ+{l!vA5LMBBTPVrq]˘)~%BDExe"kGɓA4bP.Syqal]cNVz=$GVe*[%I*&W5FCjkxb j)j:<2T l-oiREbE6j}T0髂L0ཊ>[W2zvԬkvmq2ݫ_d%UXsg%Y"_xhĺ2DdSV(h@@E*T> gݛmӘ5YYliAT^?.Xa/5gX .=iιFܯ}.nWS OsjV);r=(#oI0CvH;h]͍KT]Jq]S-CϝhbmBOn; cxgU5rZOVX^FLJ#q-CO!k1erSm%:cL,pK/a*ʈˮӎ2nc$d 6p͛oɎxɞ {~]}%w{./9rjUѢǪ]QŶrJ5S\Pb]fJ#Ud԰x1KmDdZLTIEV4LԌ$捙*>h+sz2=k7HbtjɣҶU+cmEj.iZWrվ2rbvRFƊ,Xyc5SRJi[C,7*fm)1=s| K,9tu}7>tr-s"4%;y I,Bȑ()ob#3̖wbVsFLj:W[65cWS=H3&z i~z}ʐ島$v썦/-,3ǘtzC4K+8>sT܌rh.X{ vKw6.{KYOr,aڦYHڦ$NLtK5NDl ' N~ "ĉs,]cƁӑ0&f"0L.$|f{~"'~CkK͝|%mDRwYȉ*{Ģ X=yn gU3蝆^e0/ET3Cdm_ Y y2!D:sžq$X׊(eQr.$-#H'\E 9w~A%)s2P)d*"XQJ3#3 #é{`=zC/hŖ\ǏwѴjŶ`zt A_9A28O4++aZׇd?r&~?GUMyo_*i"YRyVĚ2VrXMJb5~Z>5QW洚54l#lb*Ya v#LwʙKC_BhĬag754Tj69*ʻU1i+(C؟R#mzAy"Ga>#Aj.P6ZS{H6'`v4xç<\e8ͯbBvSŚt-zdgE3]COk95$ cO@JcC:_uTx>!VǟF.rFBtd=9Οl"{y@r1_sUJW΃cJq[&r2XtB5ͣ)f)^(s62ap9)mяU餢LAXIW8=+L>;O:4-Xlәio\NqU122h]C)܈{5XiA>RɽJwB'nK>֔1I%ªY/~ȉ}N4k06>mϾ7ޮef<_JawP*αW0{bx҅3ܸXg1C&scx0"{vN 3fX-Gm\‘9@ ;1Ky#GIz1hDsZ?Yd6OJLSޝ$fV p1̂V,9ё゙H }~RMӣ p lsLଷ}ْ8#aY,KcJRQ@͒(%umԠzJ觪d|GH^Ȧ )$s˭g5Ū*9^d_y{ԇ}cIqȦ aTN̬䞞|-<&G-ϧY,3¨؆~||ȼKX1GƓ*<kӰIv'f[ J9џ3[4#:s+^KjX0݋׳C+Wӷ7[PF3<%wZ2χN]6gDžZA2s]vu`՟ Fs;sIA*Ƿ0圻p ^Jt`YC8O5?Q2y[K$\9+a>y$Yk% ?6"/fкН.D ,u!?G,gT+qQB>R opny g0oTT&BNrVDkZS}6^5Iܖ]ɷjDe*U!VrgޛqNH*[_2T7{)fAXв{R}TE)nZZWafN%f3c *{4,>X<sޢ+iPʴ 6}jJ,V'+z2Y]װY8BB?iROz^0YFba?$-<_& W|<7~.Ve &b]a&y KM=QㄷNcArI4WSQrvɲ"[kx}w<(`Z32GupJ?'0mXoJZMm-o2}~[+h!kSʍ2Y3}v 5F_3~QTT֖c% '7ꇄC nnWPN*4And TUŸvI4v98q#;rqc {[et iٮPzN͹u2޿+FoQG{0>/7'qdM)Ku9u4+x0r(;ʖ{%F6 0l\OCo^|gkÏ/npZ7,D33aS}j,'u%d7z3a-D9]J`J\]KAɌp[Ji>6%;&L` ȻHjΙYl-X,e6j˧>$l #\r`a/nEA6 G-Ws(fCRnB99% 'bxC|Y&k8S!3tD8]fCQ? +0Z2&!)㿙}]ID,sf~; t0UJm="305|uBg#n,gp~? fcGo7k18=*׵ehQs/O:eMhj˥${e"TĐAnV0{iIPa#e˩Bvx(6i@$7m|w(6N2)#,ӦE Zok+خRc~M4]5;Vrz${'rS,#3(2бI݊p]v#luX5oK.}M׌BE0_qdWEy1Пd;џ:XdCFp6zیNYu$gXnP%T.J޼d/*?UGW* n2) Ɂ=,kƗ̹V<dY8cixs.Cבĸçh,#>K7M0^33ڜc1hH:Gƅ;0,MÉ,? >|X,\"Ydݟ~4cSOWu{k ^;SNæ>xMrW[r'ДW Ezr/hAD?LpGҔ3A][(޶g9a2i=mܨR{f᜸= W*ʮhUf2R&mibk|hoGhg5gS|ٷ9 ĎMVD:Wg!=vi1?^1غt`y9OSJxO"0-9BteA-'by,!4!A`'̹l0˾2uSګ`f06!da82VFG)?њ] ?i,$q!/9?6拮KƌJxೳ9v$d7g\Yh*ѣs&2dK_ӝz?]H7cƉf3"ڗAYw e{kJ19D߳<&%9qJ(3WdfY"A;J1͛ !k${"X`MkaOFj V[+.嫷3 |+0楂2~(D!M9`w#fՇFGRy~kb_h/pЗ\hFtC%.|Tq@Fɢ +nt]>E*;^B┶½%x?M]6g︷D22!g`[v6CW"SwG0?=x0O~k3$ne( tfgGJ-(1V_fy2^H*[VW:ބqr# ^!!>V3ucʒt꼊[RqU׫)dKf_ˏ_l#~z'ޟ.Wy*r1?#h?B1*0n-[G*iW^N+ e#.d45:]Won%!57N\q%n w'u{}NSTjɬ59W*Tu2A;k C(Y1ڳ>M.~$;L^/c:ys]ۍVR;0=)o}65s|1Xp;"߬c3)gff}ODST[2 o28ؕ͵ӛB;6}'hlVA gV,`D^ Q%\4Z4{ʫM>d/d֙YD.TRZ;nUVE*^P[ϐRg]$5^. qXe I΃}|qc[;&iabW~l;!vz?+[\l*+'oŒli9#g=y f"9PUoA-}cmOw $Sؽ/x^N>fx09z Mű=NLNtdcG(Mpz7l_cbri*,cg#9IJ6q [r$Ȟ]s\YH[;CXbA9+i%Ck"U fg=@x]v jT6i9ɗܶ9ϖC]^Kh{ ˒>tDx^ߏ#S6~|)NaK;;|U4 11̷QlƵ`'i~W À ^o|Oxp)lHcEX64Smiq\fTp[9)>Rsrm;l02Jɕɼ\t}?zܝ‹L}^Ilk*mQs#Zړm:7 cv'/g8\ jٷ-5ޛdNrAs҂坣}/;=:ʊ>rjrҰ˵; ۉY/74oꨠU[K[&ݓί̔S/?,K/e3DNkhMNm@Ԉ9U-iwr3NUK;s"8C RjR*v⃺Ici>-c wLw{^W'5K6Pf>wƊY                                                                                                                          ďӛKIGWMz&?eS~to>*Eom'Ou.UCrU:٣hyÞ6RԎ羻Z RdJ}3H8#iKX. A5&(gH[#\5Io6ޗW~nȿ~ξ\q鏆a>vE-# oɇͧI:1 W|n8SjT[6].>?U'DBW5o8EEb/yIrCէw Yr$/{e&_N-.?h 6Aj#5"DEmQVP)GҬɦf&'3dfyRk7\ HjY& ;}..Oyنi1=8h:LWі' 7ttwhlΝL!=1toEs;j JwKJ{apS=Kf1!}o$[5'6T;=FW#Siy |8/K >Iy5 ZӚ}+.fSoO5bLkNmy!OyOycH~>(]St ;OZSj>Wr[r6M"W]lKLH@gLWv%tw'En/ :s#5)?ИɗQC?2S(}nW:D=Zz^}MXu5q;-J5ɫ5c>C\o;0;R\hxƅ_%Zɤgr:]‡+wMW^tVk{=!t˫Wߺ^?go󣎬;ޏMh<ՄO7 >DُVP8ڬ9FStp; /Ѭ+n?cerRQJ{{] g*Wx.'?"A.6gz_:=ԅԗIx'6uAԟat|Z6Hӯɓw_/ސgzޕc"-/+!ݗo,9iİ }dtDkFBr?[˝[[azibP%syȋU>h~;KؗkPڎV۠7rO䣽Q rDW83XC(هkmOw汝py=sNX+5*ڛ"R5w?Ȼ5oȵJ=IR{;$ j1E>4h(͝E oSn{3@ݝP[lo[>zh)p(j .:#97 'emAKw[e~kr])Z7? ׺68u@76q?1Juse,ymK.IAcPB{uz+RðggNp?F7{ Z0b{oPށCtqۧÛbKoV}qgO_ 4rKWR~R-sGyx/Xj48)?5Bxn|ekX˛d㍳;V|YAZ_$Dg' `+zSy9e>{~vitښ+1ʖȏùB).lWohH'*Z1[e[ʶf;Kc8Up:7g9}RO@?B:*C<Nj|yćUlp.7N np O&zs[c.uBO/^ߣ1}Q2_Mtׇ1ˮA40 QEB`cG2 ]hlE*}\V]-čW>IRLyH<>_fϤ͝[-VĞO9%Ѭ _.Ylyr 贬{w3EqR,3-)>JYȇm?3larVoν(7gA)7+sha(≂> .8h?]4[9t =~ĵN SN :HgU'ל ㏫As.!Y#[eR`M[>yx+(XLOu^Yg2k6e\g|4ڳ6܄ YvÞg8Ng}pz[Bj/sS DDzӷ!<[ۗfU=7N]U! .Hiry,Ōs pPG~oT̮1^g˟)$s|툥T΍*dZ6\]Za4Nck t4f!M3oqTFC$p{%UԾ#3^t n0N obl .ub87x}M,M GRT5#A$]6# % ЁkΌ A47w]K'E*RFdJ O&gqߦyJƗxFƔpXo88xlJgR$UJd"y8% ݈/:zs_ͬ@"{NX}Q+h@~\9V6j¿I;|d=f8eUo~W dfX1R0֪޵!;*BCax0G$ HFm̩Uy)Ƥqh["Mٓ>Sm9ɎN^LU %uGf&|hq !㫻5q75h} TiVH }fəXfy6 섾7w0N[+ykWbpvu0S! b 4 >r8Vt2/Ic6fQ]2/* ӫΛݼ̀C{ܔ>SƆ{<3G7B;Kwқ֞^fTl6-o(=ɵ)F3zgp;H# s;1+ǰhOkc{ԉ {'Hf |*%zvceȥb:^Śeb?7dH̋f4X̩9UX c{zQ Pn3z4yXCrj̩ٽ 5y0b.@RMB3%֬LE/frG72ĈZ)_KV(Xp%|֔4ѥPvAY!9z39L϶ Osٵ õ 1qb heν !3!-+;U4 M= lHffbBb<5Xw,11]8 g=;W5 ‿?rޏGWlq[=:+ ]ĄŴ5jM͗p'Zz3Z#}Qvs q 2򾄍q*UfU5-&m~/]Yae qZVdzuh.xZNr<+$4elS5!g9p s/{3p=8ÍߪɾZR_[)[oV.q)y$=LXoF6 WAgc,GS%g+ilRJ |;1èT&ۙ("|3(]kN@z`U/kZl6H`V/-]hc,Iˡ|p`]ۏY ?{Ć>f/XєO㲲_̬bʖ}/ǥLz /HJ눻:Hnv91=VՆa]F"-߃Ss(Ç?d͸(s6`w?MU!cÿ?C{/~qJ̀>v0c)_O:g@.](&˪o, fѷ}:c]1v'3VeQقjhY[hC17 vCpKe?gkѽyĖ\ϭVMX⏦]2jwͽp: s;?Rwnl1Ԋ gG/ {Dy!] T&|M1L;TD^edOi?#rpcHb(a_et*/Gf} XBp ZW̡;Ac[Z8뗰nO)z_3IE6޴nzl?.zt'fHyW_ JH?-`F0竱Cu-oTKh<ew$UˑVجCD>P NX2 ~C#J9C8͛NXnAÆX=uଊ)'7Ͷ, Z9^Rq!G|-L(N$؆ . >eShaL GW|[8wOS2e5`aN]+1er2ѫCo3x[ fmH&/"f%9Prўyh׬^bA)G6yѵ/=E˚~ÉWcgj}Gfl"56}iI+͸dL%k$>BkʾxW3-ysQSiRď".@",fb(F13=1L B[Mk6r;&u$ D@o六E)/*~W5_&<ϥPÆ:^1YM:p9ǛMc^ bVWѻjL2ِFìYrguI8QByǼ~4Kjwv&)#Ƀ)>a)`,wMY9b:W'O?wi8:l8-F^Pz.&m붗c0! aXy;1 (sm7>Q5?vWpL1&غ؟nLtVl#:43 fR#Y~.4XGNha:,Je5vsh]+&E;G(B&4r娦 ?#`qa¶t|_nOm85ˠÏr6ڝNUݡQoMDe{4prk}0qR NHեO3ybΎXfc'{pD݁}=74挅&yͩl˂*枯;Q- e3No3+ncI~vH͋溋WɅ;,ΔϏ@k0bpn-B82^]E*B[U3!cqK?o8OQu?X;nYc|,+deZf[&ZroCF0*|| bw <\Ł7^yH jlVCJ;X^4C}uUD3` m:f-vr9AEx$RSCLS%^xq-"˝puq}9dKf'%N֩{Og8\g~)Oe0;K~<DX,Z&4Fe|>+E`d態#l]ciL^d"DZJX7geX҃hy_ޓ*3+m16&Պ';>1;R$-M}6O'JOtzg3kgxOmn9'ߺsfuA2Gsccm#0+vWq%ąEVx.fo`&MIk5·Py09Ϟ!~,U[Sj2BJ&t8N#+!}$XW)(4CA_e\vj~Gcu,.&QeƏ>Nj_2YW~ [pz#7L. 1֊YA[WCkf,6Xˎ2n*&fV/Ԉ=^6Dx\A,Bbu*ed|9靪YƯլPKQ:/ɋ(}0dDOVLJkn[~`‚\AP?Wr%t=:MalD#Xt'k]N3Un<Z\jlNԤ硇[RpIKwwt&} G͠(k_RnT<x.{"IJbTPD8Z)?a?GeX̨Y?{ o3B=` %H`[iw '~~;{ܚʪjH ~<@2Mp{'a쐱<ʝ5n|uU63dr5;K I¥D {ƠtNfC !Qjz,K#Z\W{gv.-iJwVqՅdd_ʿg xе+At3\i~ڝZoVOujMIov wt7۱zWwEq5t3b\yF7ctEסs mh/s5i{ӖFC֚_G7߳&lՔ6D'2БS%`Zh"g̤2pVa#!L"ƲN4UqQ$Ӄhs7{8 @UDf12c=ӂOAi9g{~v?k{Df$M.TjaӄҴW/ޱ!T}Nʾ$]R-S8g:G'%E0^o$~6cOi0.UA}4>4L4ZB#h/fׇuNc#8d͇ܶhnze-^H_2/bD>.kb<;C(w t̨#JiM7$5~\HمAQnNёCjO2#7.=>,{(\ɇFeؚ؟ȇB{> sQW{s͗Jr"w܋JgnLp&8Fp:q]`+Nm gu{fЅG1q5֯Mb"ZSW"U7=1' ;oI b!l+skh5wY!,6yW%"D}cd+>)澳 af\Em'Bq<xܓ~cay*eB:*w9+fp!Kd~ϣj/T| S0c\ 3 &e Y5Np0${}h76cJGSwAu$/ѣL7}LǿdhOC2`*yĩQ+X_BM&^Es !-=KS19Vyz+`:7%l菠[j[ _ L|4hCLd|6O; s֘9ɷ&qVHj#9\*:?hm`v wNJSq=_ܸrQt?1h>)c)nQ9h ibړ'QP%Yb7rn&G%p(l[ޖݺ;y(c8q<#wFsxy>}?JpZ$eKYǦ`% QW)Y7zU]Ṱ r"+?.< /ReRʡR*R0\^LF,O-r8_15N'} LRQ眚nՔ.r_t>PL/kg`,v XqbeeW+f"Š8Xm3r=)%n#b#o)ˣ%4 ?+y/N&t^v{ZB\6D\1s1%t"ɣV zGJMlވ,,y*kF%6n"?Ey7jy+2Do%LK3J_$;bטΊm #L3YX(=>IhyOGZw Ʃ3ld6Z{^P:Ί38(8YM jjt_i}s'R@z0q<9tkG=:Zl)c^I }"e [z$d,bB6ٜlC<x!c" \KmMd;04η=w*2IjMt~.A\B v(<W?R-9/yk62פñdž"-̛k%eh pƭb6[galE+c 閙ůO-am+: 3nZnD&fޢkPam8SݬecJ (*)ۢYi2hâsݿ h?#CyfB³_݃K-h-O&qZ:7_pd-b%bPʟ!LSX8er<}Nx%=ʓVHݭ(FzJy45F)*1'0{M m&f3nMl`h-[j1S7s􃙉TcW-5Quutע%nq1u yXjMpduG|~ݰݸrǏbpRJ}d(EUۼ ׊K$xINN HʥՀ<~e\r: 0Mz?Y4LKTq`4xN ^M8~1XDlVIHdr~𳽖k9rXZx̒Y74-%/+-OMt_ZO){)󺕐%m]A x hIb5O e⮃ ƛa=%4:KYʳ bxQ0[3?{DZ`Vo|Cuľ_{TS#CR8]28!?*0ՉSi!vraT7pfn /6qzc+Po[ 'Lwydcm_ ߞXYz~5#gb7,e$,-1p c-^kY3_r%uTH&zZ(sj&Fm\la3 cIϚ7HK"#\6r6=jX%)ήMqC 2 VFPq E(+]v<+`h"nO.nf &fKӹP)q>ejK< ;H'#? 2sz*MƓFD453x-^RnTdZq hyfQo*fL(Y] XU^K\ƹt%F3X)Yop6F C,iu;~id~=! ӌ.0JE^-_鍚F";2ĒDr=cߏt1#Ꚑb}Ě:÷ uBj.nC*35Y{a9d!THSu2vT`/Wpp~jC|x5.sځ x@qD˵JbbeZ>FV$ZIg#8zJR#gp"O-2lށVž)}ff{[ɛgf/yl13砙7MlL,J9Tfc?q?oi&y! +G!ZV2sϵ ldX\ʫaYHq]|%D6%6+beW$~{ܣ|Qa$؅Ih[-94Gra:~),eLzOūa:fk/a*]4 ?X4 x&LO+?*VK jwIZG\C1Rq5*(qz8$Yx')J +IV6;uLÁfjcjbf31cd2iyX tkb%^PϾF5\nm!WęUDE|OHғ IF7;!<࿩NS7ֲ0'r+y37#6 %eTR7FͰ.Eq "7 d@gY ց$gwQK'l*rd6lq;8Æ2*L+ 3acM0 &>yDܣ%%}"|$Z$VlUTt^Ldfͳ1wRXB# >ϥ\v TVnLqΟ2ǔی,ZYw72瑎gԔ{mNR4O|s@%,]KkCef]l ٦62㤉o|mD ?E_dp Yl]%TJbb3usC"NJ.ѿ^ NtXHәCd)+e|}89w 7R:2T|&𿡎izF}jcf0{8;Eç{Y1IZ3eR'kI17|z#ڳ=f1k (O>u~ew@M4}h8mX7OVٸeƉ_6W,a^/W %ܿZ¸Vn,Ӹ)mfu]+חe}%LXi HX:.h94Q̲,UE>)?:@AJu$x>ksKGK&eyR>=DCʝ)`l TVR96" pjDd%ĵs[OAYxѿ)X'*LeN£,:pJzM4aVOA]JT>&Jdr #VMi"2*o\RMVbiFG++?98Kd1FJ}Ő1,tV9rgqy2'K>ߨd5 Y&%Jr(I^YQR2%*H~P&o*ikq7N Fr+5LԱ>DϚz^Tg->0}R%ɛ|y9"KS_WI~L% qLiKZ†4R)e; }7Ko_dck?כfcM^ (:`ظ`䢙kDm[ŽBSږ,`=t'YGO!zO_[T50ೞt#LTv =^j8+?m4THW˔<fQ5AD~Ff)`3UBMʡtL@ '3r"/çT[eq4:E}B:qCP)%bQLl9 ~[GJ/ītMc)%1-e2exTH 2"k,^jbbR2K)pL\LH2Ѝ\=D%8Vcێ[1xf._RvJaG_N82pG~bD]Pg%s(hd'gXL~N=,w%؊v %?]ujաj,$xzf3I$8}L›{rS鑆 63D5F֗.f*{'uTNf&7gqZm #5>w~l!讙J',4g]ۊ9>3qFeFޤH0лȥp3po`#LcdJNj>WQY8 V:x,U.b|RW8_,1_ǁ6GXuFibRZrG~J6Wc\K%CJr~)E^ ۩YDK}Zlm37 DFI'q]"?bغ$XhF-ϛ_r*PJE%} Qb ΠG/-f3u:y#ciOPGY9f te/,-'fYbf1l~O9SoYH%1="VJR. ~P2-ou鿄<Ք?&5FNXIGl\4T"s&uK"ZHAr&SgzPt6YIr0W)ZMVsu<\cfw3#Ŝldz3] 5usj+Cdt ,H̢m, yIl1et HEC u<}nM5DR W¦%Y4ł}3678+ډHJ_9c/rwTˍW*},~bRE1g(Y%cHUt A ד!U ۇ$ewǬZ%+HM.jk8QJjP`"vmz 18Tlǵ$'qy,qtOƑt?Jգnx6Nؤw^1fp}w[u)h~ɝfŽ)2JbqtQ(K2~_7 .s1m#]h8ZA{<͕?s`F?_BRSTɝyTˈ[0:d9Z>~,x;U?1(=}Q\=5O:oeSuN l}~'+iL۲1뢍$gTd`SZeL&_41ƈ }+#tFM\Jaxe!2ċjSC!iCGr9=݅Rm;\}mijD6E0UMڣ:g;S-Ev/gCQ'4(g"-@9jf6A \RoI15)wi1ג^+#6K@JHe*x3 ŷ֊Cew5kPp"'@~z}Pqg1{i^Oŵzwհ"//ǫp ?S';QxpY$U'P(aWo C)wW˂rsxy%liYJ3JAw4bf/մu0Qɼ4yA}wWU@݁? 1\`5STHW:0nZ`&O^'RÙv-]Fn1p׬E̴TaDѷ?L#w.%|hۖtNػLJ1}8$bh.< ;!L27e&¿Yl,5mXhdbQyD'eL)m| 3N9RAB7y׎ ׳ f8(l0"o !:yЯ`0ai5|ÿ7ji=z-^/+Ǵ0;xN!mB qľTDW豒,gG&(*GʎMR^{jyV.;"{yRՑgx(CvIDZ'uǷMPppĚgj8Rr}z )q~3b֟u7QodqO;J&4Q&ޫ'0T# ڛ-4>aaY36f󴣒q4`ʙWBMO9넹 Y_ZS-B}^Ćva_W[r?J`s@.-N^즔[2Pоer~0K:OGSH"f-}X3RhX} Լ:/VT$F䃣RTc7#Yu?FVK,);t'-[K;2a4$6#t1'sGzDs"O~-/ ˑlgJxKݩ]JJV+M穯Y0=f={;˖]d؜wnA}}]K4IρHƒ8~'| ?Ճp)wwCQсQS}ʾ ܝoυc:xu/kq#j?7􈰽+66ځ_.<<ؗ዇9>vyl=1Լ4kqs~, Nۼ": Ԋ4HZE8do :A:54H_ZVб`1q^7Sgp:e+5UevߎfL:A~\0NUrsWz=N\Htpc/c̏|L.S)&eai# Ksx?,r3蜄id^6(!cІ<ί̧W5 \n.YԷ2ն%`%SnAy5Y.jٚd{m.:ՠhTDP=('=>W'3|l'0؇}9p%gмna>ߡ̧/ltL la1L^4Mc~ď.4 W弞,UT!UڡoRIT/ U%4R`Zuβ__ȧyow RNzISMYLȦ\fbYH#\*|qvY7PȝwIB{[~h4Tˈ{ & &= aW@2/:},3̐64M 640IڔO{N۔NcjwvJ,[hfyn{傀;{؝]hbJW^T6+qfz"lZx a8%x48]>F J~u*hwYXNX7[bۦkMv4 suz]WCjR"eȢ6ے&4[=?s,>K4ss!C6Sf7yޕ~sLNkl24f6#^<ij|EQ4 >Ky0XG0{ܽȺ)=?N/OlsE85w7i/gy%ҵא]Yw.GOT>'rfB<׉3'DZSSDRfJoRUIBF-onW!]s*>mTRW%YQK[]D`1nhg`3V3h0tNǬaoi$I&]"CœKwic’>6@ Id7YNIJc4W&3q'&p. hhz)(#o-Fl0_{q%鏄^{ k k ]B]S9x2hUwѢgTnΜW?WE=56kxUɸr'=6:io{S'oKoY7ܝ:Gl,Ń{4H\$)3ւ ;N͟%}>Ό(f85O~>jY9jI`L?"M.)ș#O׆ |ۈnf9=P:a9R9؛Auc)@WƠIq@:U?#A{*߾n,gq5V2\yuJ.)9R[Rt,gypB-1KϕNNb /J?kEd.S!%0/\/V@6q{TQ.Zdw2.],X )m.eO)%D'aQ' gQ -g,eќı}ӓHu_1y$/+YkOI,c3X<~Hw"Dk$Ll}Џ%iVvM&1mO**z6Kbl"+$lsSXb{BY/CB;gS-N !trN mm nfn- 8&|oiw!FJܵ;VGXR槓eE*ǔăH6kĪ8.nI܆XjgcwȘg,zY%Y{H^XR؟]@kI_Hn{$ǜp&䕐I@ d|ǐi,4.sF?_oŽ cڠ?7cyv4uΌeΣٞG sޝq#cfJ0F5*GYTJf (j8q]IFWi"2d L²Xj*aDm!| VH&D2RhO& SeE M,"ZIأ&@J ,- lA`fo)yXh'-f ':&z@ lt, &9,aٞNܷ/ 4=Id:dSt&Xy,oI"$2$."c%dJ09TLw.S1@.j~C^{^0zI0?!l27,t ׌ :m“w .k L~vaT Olʘ1NE=l] 7 U!Z=|s/xYp6&R<vwTywڏ4tł%YL|=64+p!e yytu-fOi)ϔke)4dΒ`#Msi}F‡|GE'NfJ9'V׮bvk[.Beay5h<9;R37d1u;FIpbFш{XI`Bh^d}t)zJx) pSd%7/!t2tb)O <>ͥZfXndoq'x;ܓz}"=]MAXƱ,ԍ1[r13RN]" LQCNr6(COT8GJ#e7lNV2ǎfXԷeB§/n CAOg~hU6xDSYr.)ѩXJd%8$%~1N=IC`4ĦD2gMbl7N䏇3&`rʈSszuf)#}V o? %q|{[,Gj {?{ $._Bbb| (2?Uq^6+PVckwoh9WKn-SWVKbv?x.r,ytӊv8|m&`/x\VFk'9x&/O!!eD.w]V gwK6<] ^Ja G}M+dl|ErCNńf<=}O!h=J X{7&ƝCp=qѴI 3$o:ݒX1ܙ^{ެ?7+@*K?Zh}k9Ɗp\ΖJK*áaHt^ŗlAhN`Kv=G5NG$X1\q5ز'-hGBV'rV1bb*9Wq#*:4ݪѱ2Ndg5U,5W0Ȃ7̍^MNic2Y"u5Vpuac}F̱#/f)gx |Z!ˇr-yVƖ<XNV=돛p$&yx[3f}h꠰XdBQ":y?mmXQ ͅ8nȭܸ"N"#bm ,?d9 ƺ(xlhd\ح d:YF0Ї+mpާǥ-042sLvZ{yZ,#uI)|~-!"rP+B9-fQ"q }XzsӬ8WY d%K yO|b͸_]n ®.c頗Į b6amluw TOf0DtX{r2=Md1QU(f2> e8A63|ҟnd? "+: u l i؀uLqư'),%*iСJip7լ+G*ZQEUL '~<ۯ9QΝb&J ɂ$ΔJl0ǔ jn綴+BXUTֶj>Wt]'ίW~^.EEsPd2!#L$#zNXU1>_qzLȰ?j- wHrs8X "}B2ץp2mC|}m3Q_rG ޙ6fR(|#ll9hQz"eJlSax|dQir1q[6 Iդpz-I6"gQPAF؁.rw6ȡ+tY^%)rbr: Q ۔s霌̞r!zЭ"z7t)A11¿, L]x:Ɲi,ӋzA_cW?&G1.tS3bE ٛ@gZd}F`c0`qܗ kzáD;'Rq!$zR{Cv 842_Vc۶<*$U]V-9 68'{"oF#yяȰTa\AlJc_+fvE4|Ux_C0[WDyU={ZCc- N.feUpLv|1#X>-bhm뮴Ejn 8XNv\#-4Lk]el3W͐c#'}8btYl2S(a$|Ŕm_sf]l$oBgdTnoFRAʧ]hk7gqa"+ :*h1g8r:2H2-r)%WpNKq+o\1y냹 ؞ Xi}ygO&Nm>ߑIYѝFB'0 \YؿԢV}3Jfܶ..e 2I1U2DETɦr. Y!ۭ:295;Ğ^,]s[~,p |hEI'7kD- nJ G:9ʎcoXVb{&9}=.4r;&˼yΛץ9ǀ+'bˁ3),:VD|&+S?n|bk B;^0{|Rp2`BҖԞNc*Wjɺ\ʼn3dSJ~b]K|3G?05F"ՆӒgR=s Ļ9ͽ3AdoP{$k(Tո75kH: >KݘwœUg9!H[ޥ͘V(D47PBN2H.᫒ t#l:+uӇ8;k|ƹKiKAM1JVeԍ/:+e4;R rwi[dh;r : aMr1!~ KGaԖl `06I@"F9j/$R+Rx[\rl@H9W+SЭC5Z*Z{$g_!2A\H Fh$\8/[|z0EϛQB@F^/q8C?ktAωosxŋ})^\I!ؗh>r:ɺXdOSW eƛԭ~$%DžӞ[P*]6P?ǂ!<ؕ1x[Czv&a4_{3Ɯbsq`0j2B0^j2#4x0I/]Ϊvؿ<~g"†y"_XoU?u2VIFLx3x,KӫڃW?,еeM7=0>| M68lTjR!iī?E䯝rJR峆Gוˋ⽼?SW#ݻ ] ? &!ۅbuߥNޡk{kH Zś$?6&>,7+Bx|?Fn{/ x΃3INu/f𫗘D 'c#^YԄ`nha;F}$tE@X8zXyNH udg{pC gsw7=Li}b(MOQq5]dޮgi5*j_Š;l0K:+>MWEk(u Nt9GWYšlwi[ŠZB!]+ri4 k\5O_ɻ+zSɂ\^̠]LE7~?W֘>ˌ;h LY(ӏ#[h60h5^0oi Y '% ڇ-G;O>I?*"%1슎'_2Hy}r{˰ /TuSB2/jhUY1ԅyzݵ<5P~sG4fɜHů់*=y%%>?'tx>ؗ G“nsXى;\ϓqnKUS>>=;]Frdy|rFfRTe($+AΟ |( VС7#ܭ'M{cMzLiQjj=+wd4n™P"̢(hq]Ot~i 3]+l4EUD_>S} ۵_YȅBhY<45y؏FJbA|RX8:x_(#UJ$+>͇KtC Ih:$*9 = WkQtjYͭX3sill;yYD(bvhܠ& S2zJlJR_KFXwo&sh)O ,99/KBS%]daGYFG;/NH7!c\x˰Έe~v G/abHdpe?\|t2nVz^2XFr?JywWRQU €_K˗_nyߘs&OvJF=v Ty0o_737-Cv0m_׼& 8%d2AYHXl,fN$[2wrC>0e~kJ8`('i+8[ɨdYxi^wcج-P> eĆVzӺ.68lcdx'i𯍦1PKj"긔UG}1ռ:R{o-X/hy<<*^$Y˵UDVQݻ+6]C ]|=d<_)(VrJ%r$@N{q$ K,ᵩ9+?GIP/\^b~$+K][Ll ;+{]S1=jBk4\]M%\Ƅ4 }T>ʗ.(O Gwd9hdIs#\?ێ] rz7 R%.PhHZLj])İp4IKY.L;0f)5Q`&zǙNg[#}\EڐoBqؾ(+JySgRr,e43YPCȪ ?< =?$DɒPs4d e ,cFUGGC$&#" Kdq6Y|i $M&od8j$|>\.z ~`aJb*XfJٖʒ.|k\tŽ}|;wݖ]hțp`#iM) ͏q^>gv1g3֝[}y`0&^tXqww\%)881i9f_(xJLU__YQLrt>Id2H!g ^Y`k)Km02 G:\NXvpCQ ΃a縓sԗn/|pND$EN*)<~ʟ2 " Τk [Syw;7өqiIZΥ_R6Ɉo@\Aes _ݰj(WPgo,MbK[uIkaGooMGk]?F߁0u&* F~76z<9tY-j=X˄5Xŋ[k8^KߵܱƲK mjqYP̈́]U,^JN>g_Ww^*9tI䬩 .ey |_E3.38M#o;̤oA=`hd=S=VS\`&Fq+ư bGJpI g/@k}AaojuRqFʷ^bFMMc0̢ X0ՈWbr2C܌2ےQp( 1/SVOáDn) 0llBGo`ȾH5:Wwc`'Z[6Y3y ЉS26>a{@:pK r\b0ZN?(ϖbXvK9rJrd1߈wB_B|nL+v:P]J;ެ Ki:1nQt2UaőX/An rd'>ww.=+%xgb􎒲%jWr1VˬZkq3*yڡ,VEϥǘ,g5%d.$>Fv2WAʀ9 Ix]ɷ" jXԪ'լJuxQ+nzT¾2u!-OU\\Ih#UpXY2gҽ.ygcbAgXP{sww\pfuW9IpZVcұ}l J>"%!?Sʈʕ*Nd2k2lj˹#; ȹ9l1ko1!%lȧ׸,췤h3@^xӾF~2^'L9a>̏WQ'U=ڳTs7lӓgoчH~ fl)|]˹%xōtJTΈI%ɇN=qp^">!ĥԑM~6EOI86"t0[ ]PJƲY"1$Z’쪗м.qٴ۟˥\g*!ab>a 2*xRCjft@%_6jJWNCK +0PE ZƮ&֬abv5^Gd ӗ1V"7VijtO [R_D$59*9dr쿤UK})U} 39t^kwflz.F[% E3MN=zYҠg&%9u &2']YydN%Obַt>F#ZifhX1=_hN=fi+o2}N9Nܷrۃ G)BG2o9HPQߞ,r)U")DTԎ^X򵥨YC"wUb {ǖ~8,'y>;ñ#yϣhe,RKXӻN %,[Ə*&,TaA? ~)]IVeV2CUDTP`?*1DA {C iYsRARɳ29;q] &贊:UP5h^Vlk5װT j8^Dղ'5ߣrn[Uᾡ%S+qSs#0j^Ah d>SHVDB_ovOyXӳ.$^3veipW.m}dDm^on.O={#U+ Iʑ˥pe>c2O%G+pB7=Y,KQlƏSY|z$nZ mhkW{9`';V0KH (83)ƎM9TnMdk8`Ln3nl]B+i=C?/CAKy$<ۛQ|,rB7?<&ƶP%MSh,|>.g2&զ>%5bwJ|7xX!?U\wa ?IV.VZ.<&bP i.vjuFKZTr MbG*nLVA pO8-R/"% yCK[_B`ׁ16eA>f!xROcօBz 5k  Xlr5t~y%v\ju02ou;z1swZetB~[S;sV3Ft5^ /ي^̆vLj쉇/ dry0+EͰD̑cqu` SY*ڋ뙅b-}038Ĥ'1̌133 ,Yhd™0L8f 33vV߳UVZV]i"3%#)˦427!Ofbq 1 JKF\ů2Crr6R*GɤJk O+ D6oBn5ⴞ=F\Λr%ny!md\63)ͤӊ,Z = 69e1jD R:U}iW-ҥ5/YQ2fV⢎z\c_YѾrU* x@Af#xdnKǤ_: ]6Đ~}10ٹ*{oQu9tO$wq)iU ^gxJU3A N%1.װko+~Qg2koڇ|w&#&^,yMyt}d}r2?Wsk|g0M8~F2'?'uıro&/s)$ T:`nQHxj&qYlo"bzKZ7g8Nd4ٝޥ 5 4'w<12i@v>/Z Y,Bvoa |%=(.{1m'Nuc Wo9]0 B"_Dp=ыZ/V7uj#::H2ތb*LB>GŵzXT%UNlqf}{RR?#qiIl=EI!O 0P̲b>ow1ٻ]qQ)֖b%2L(9];O*h2N--ʴcdJ[HRAh߄ \\ y0""Ү.fGUgr=+?V@\~t޷|x^\%=/̺r5Q3v?26p$csg8p,'[8q [boqNSE Yΐj3>`uoiH{f߆k棱s0%-Յ1h't]bV$^` So%IY+E4{ r~TI] Wop35Z5g m򷶜9GQvZN#%)%. GD3[J^L2v`~,^ QЭj(xki5ݪ7HVM*^ίS\: &7'm7k=OܚvFi\' ƨYcˮ FQU|s+MhZZU՞iJChHv!x #m3;_7t=vH$l[g:ftץ dw.Ops]&e5oYOa݌$ GjH=Vxh Q4s_I&ʁ8w|"ܕ9.bbd|_Q9ŀ=]JG =[sf䮹.<#CSГQ'qvsRNoU81 2/r^r!J*Z.Tmcj.(0(xvDN >U`:'j3˰4ji!EJR{[o/ )z0 !x- u; jEFwy`<45S1W9WVu[5w^I "wn:Ti\e'>qYp%"p,_]?;2Ng Nʼn\hlܦΞ=o~u#-+>d> 4+{o |~1Rџs{dL\KzɏzgL,Nb.h\ -f{3"}>,7W45:LYdiSB]vA`㿢7TGNϕz\%~ѳ9w==s)ϝD=j[q,#[~ő$9Ed0ׁOCξme\RXeoZ*/AуjIU49 V(2X~kBW 7dQJ  0O%R73«O]J8\%|ϕ J1{6?V;9be2d-/TWxݒWc/3aE'6R6?~R-T*j"ֲ/)J W3M⪸S(eʉP/(&El[$y1Dz6Oe^dX;gEQl)x1}'9gu/^M,K}pHaZ }'Z^PTtǑ/Yg<٤9m$eP2B3 H7cY<)@$TOQYl _g3){Fb^-B߿U )RrM)e\N#^)Qv.xqSai 3lC7>d/F0BzZTrӪЭ*y8 L,5UN̈4bXOL38p/`I_FLq;֙#=`M#s ?=T?8ͺ}lh9c˥=lÉ8uh];1W)-cՖy2C& i9%ٽw@lFA"䉩僼x11=\*J"ff+FɧyfqUȳEXfNEmǢ!& \=J`W6l8u&ۏ BN}=ͷұ୆u3xզF% I'"gE#4gC<6NtzhL.31ݳ8]\Q?(9FɫP| \gt;*R:ʄc&⧄NRW0 2 +屵HGH9^ʆ2ڝndp[“e ޭ\𚮥et S0⒰ snEX!Ƥ$p&Cܱ?dͬ%0t[سbHΒlegCdhΫ UNNLZćd LY-eVrqⰚ9.Z6hVK-3vTEJX(取Rڔ3xi1{^qC¡Cbږsk) :(RKFU2к3%|8 %X*ܯ2!7fk4M =rs}(O>E|~Kج8\rgͫ5sa@{8ĉ -=xؓZkN"X.1w|RkгҨ5xwEhsyCL3}y=uRN]8w\Uϊ-rȆͱ6thfpf V"C2a< =Ţ|^ޡhڛehnvef;ֈhe 31\$Yυ[XCrV-dP'Qp,g1PCUlo \D9|~Mځ lΆǬ؝gɩ8I\2\Ο=P !-;;Ct6MEwè+S9<ܕtCy!ʰU lߓInytݜo1Ƶ|;uoV:q`3nC Lel9ո}]V?XXRJQ+`rN*5OqʛL>E'P̗WPd̃U0ġ, 2h;gFa0/8q<lp[E2ťrS͎jQ&סpe@;`CA%W'0NVBLhg.t(;LF|h%vXR)hխEs0*6)A6:.V!|jY UFU+ղR{`ak:L檝?0:mbX'iSbыcg09Vt6d!Ò9w5%o|dzBݲZ>f 7s#tuhXu !{*d{Õ|KΙBNv bugxGOr=23[oѵ>D75^ט>J naI>.9-ݳ2F*xMzUpC#d8%k4VeYK,h?jtWO=#\4Te*o 2LEJ Gn( cH1 =~QĘ7ŕGZJ؃w4ܝWptt*9''َLXłQ^̥:Zͫз֬O#kF0]֙'6t"֔챔y '@Չ[)GE}*DFNtyw{faX-BҪt4/!TH!ԙVʀe4ܨ5)ۤLȇB &s(%1JCVln%  ,0f{?dzG OWY_)0~\:~>co% NiHBxّvsǺ;g{ W&7փ22R_m|bE5 ʐ!=Zk7۳G7>ɐؔOD>ٔOE Q{Tڥdi#-tRrx(lx#B1jбzW2aZ=oJ{>S3hB<ѳ^!c3Ms-d"1)Ua4ˑ|wt%.\5.p;sc??CR7/ .vA豴0v+rUZ%y'G3M8N9۷kP:F7yWǎh;:ΑōlPͰ֝s]tCWWQKM ~Y گ1f϶"'%EyD76d I[Ucmu  .ݕ($|2[,~55FF`i>1Q?#q&*.h U.1U_ݟ'v@Wtn< 7FL -)iTςmU(Erڴ40ڵζZt2uj2f)Ou>WpvɻX!ڸ\c@.E$^b\(.FFE تOy9[x<8O1$3B:7c t@?'Lb~,j?'qTڥ4g"}Lt8l >922FOgp0O(rlwEh}!k44?XI* KE\ %i/ҸDt&g2Y2'i6(}ɕr7ʞ{0 >V60Wzetg QkDfE[ӴnpSvkً4{Nׁ%|%-;ud$~_+6F4+GJERtHErD9By0Ng?eٗDAp% e-^{jOJ7~Maq0Gp$1MsDT^0~X(Tt8m2{ ˜w]!CԎ-$CTs=-UFgq\\:8} c4RŐje[5N\u,/GyR zqr YDC6. v<5ͳD>YZ*ؖ>w -G%ӗՉNb mgW֐A5Ϗ@tK5+Y&2@B?R32ZǕY|ǞY%4.P0H34%Ѹ#̏1oEST*L¯SŪ2i.nm-]/z|c(dڨN,s@Lng' ]g ^(ٯz#E?p :UVW#G?վ|Ё?HlʉщߕЮ/rH/w C2<#fOS _?I#nED_vYq vM#+ӻCx&8Ձ,b*'e<͎\[Vtc#hY$'2?߂R(㳟IX̦1t cR J &MWRHi;Stو@<co}&_2|Xҏ^d{3KfuВVeS|{Yy^" caύg\LD}*ƌ:nE)Rݕ *Fؔ1jJ!4\X\% &2 Qb e6g@)}Ũy*bQTׇytkC|N[1龸^i%sG'^}&_/7n~':tc3O熁: ˵ܘl`O% UV[o_AVn4Vwr_x%>4S='F񲳈\vsAV<5qTC\70vW|p^)h·"/R{Qϓ0/eW".޸,΅it802ŏ_" a0FBz‹KB[]}ɿ9r2't$qc +jvUf!ahE߹0n CnxLLIV}0C>ӗKE7:&5Cfڃ,#ۃē2I٣ Z(ó8$v=0n\` 991Ju_Ԙ+A8XCB*~[~MTж(E3JY$1DL+h 4rS˖s +eoK)Zccx-ڽh)tO%\婍[&Z(ӊr^ӣ`^i[*=YWYA{To*F[ &\: ^1/g8|&2?ʌ1x3p$aБY2:iK)7 G̝Whn8čzXIFcoN TàyȎMn;OHn~Q(GւxNz^>rs|s"%9's-I7n PK²(|M PgS@,zK06&'҄6]<u_6W3iT"8PExZŖZEHkq*D|3|DF~C ,j%f >#S[Xt J%Vu-)QuxZ ږw] *hٹ:6Uˤ f biEGԞ Ssc'G+{z5$oh:K8ˋV&prLv[kā]LUk|[atpn[#iUH .aDH=_' r6ݜqH+kV1+cw%޼v~k왝A+p_)ZrwWyB':OSDe?/ Fs.=}1ܜIJ{ߞ~vg 'a/dMffM85=b`?Eό~$0_L&,ZJxQb*6ۗ >LXlǘD.u$:Lhw<ٙy8FCEg[,=O{9?EOA kh|Lv aSg#\N]!'U|b|.4 )t *~]Ao  iȟZ$Z ՒUAZ)iTB:Z>OaUj/,$WOqBsdvVnF%.a5T?y09!:fMҐ`zO -)-gܕ ]I*H=ٗ=E\v5՘׮i؋cb|7Ző٘i.llŒc=6PʈȾd1e\Xy]sz!ϬJYc$&zѧ'TX86D(0nj!XɐD[2r-ލ}k5aN:]쫌{pNNi{\yZbl>0ה{wag SZ4ڴ/&잜ϯ?U ZEJ 6 ]63>s$$>0.ci0!q03:tLZ333q 1&qffܡfv:Sկ_wކRYVUsZ*)z)m"ʩ15J0h^)MoB]n#wsg%?bߪ|PrTpY7sw)'쵢 UK<[K~پNAU)YUqmF1+% Lߕ+ztkL1Eh 4_]?#h:w33suߏu8y <ɧO|?ƉYYo5@vbl7SZ ej ܬ=0 eLL˦^'ee,ϚE1Q\jS͘;δ[,֯)Ѹbe3R2s B͡Bʢ̀2CGbVrrkg:[5%p To^gUDdQ)ñ V{d) Jɶ-e"ґ<e+e[);JH -%g9 {ꖠ8sܿJu?m\ RҶR;)+hXƻ3e S獙cqt"jp K&R9?.Yd5GSa%]TFz})g_2ο,b<&uAFwsm^vz]vC ؛E mٞnUζ(*Ogr۬ԖE3,k2L)ة3xI1IT/U#E9TJ׾֩i%4Rp \`JRV7.bdE15bэreuFw(ˣ~*I~[λe^^~uALdRFZ.Yۓs0k}R,P/U'PkճGt尨Ұ=Aqn_//bS΅EuMrq+*k~$uaуNCh6[R#w{Q6alMC>4YzT?3,ٙL3"x3!qdB7~uv`?91)g HcW*J=JX}Ț=})8ƕ(ޚ@ڵ1[D<> u7*o`m*ievzm {v왈גTxog47bv׍y bͲb A\AIvnS'4rCo=UV t`r_~ jeo!+JWo|vv|0|h.4-gܛiD, V+K[=ks8*Awn9.3(ʨѿ N%^ʄudj?\gC,{_gX.IAl^Y G;OfTj.WS%%s`c0K{ˆG ėn0fcK=vRpL ݏbnp,1ޢzh1~̀ݞ;č{vn)3]Ò>H[<'j7Cg g^s')yԫD<Ț9Y¡m,a]r^WꔰճeOr.EۧK0( Vp/%mƓx*ETzS hWƇ%4TB㱥gF + mWtė$LOzN4⵳ؼ}ʸ0q2_ZTM0:Ƴya<'1ti=g]fPC[o{u3#F mrUL9,ΜUStbQتY-٪y)>ʼnmO‘u؇y{v`&M$mI^lF7=h4ZO8bcWڌࠗ-_xN<:Q 8_̽ x0f&gT~.kBѷٓ}O+ޜIgTX`/ᖒè%|3.[zV8u_BT,BHyiNp;vE#W''7= # iݼ},f:8;Up_):eLiG+c"I֔3;{#q9YL똌 ~Q1G/fqI0ˏ ǀKiCMII :vshOffRÍz^ۗwv1eOe`0Kɫk8I6vyg}P˕]]ˤ+R{D9ݿqa!=/sU_Hӱ:q-I( ߮kU?2:k"{NLfe6-pCO\`[Y9Yg8wo3(#t81k?QҶ82+ݗ{h=^H"xȚ]>6ZyZ:Qgk^e92VY>n̚!lA( m7#o}Zc^s_QуU]Tݝ_4K?nDQ걺S1-p$;W׺=A’E9ܬ*ZT(k#~se''b`Y|9zsoɋi8Չ"؅]gFPZኞ3]lc"C恖|ʨ-A$RY\BdWݿuK\OLVah\f3ݪdυ9Qlzu^u-%Hgs J.Q2j:Vt J_Cx7wЁھnAځ}ɪʏK1<ήF}xGB˞O<\ˁ:^vtżД/4R9uIaMׅʰ۾ZR{4F)ڍ_mUYֵN[ TSv sd~zlN3]S .[fB }G/2' n~eư~ΨƉ qNT2.'15.5FI5UQHE.6<4!c·ٰès ]21ǣu.I*(XAч yej͌T6a ֎+Ѥ {/P#?r}c4? ./7VZ]6珉]N4 0V|(b;`͈t$ذʞԛͧ:l?i!.4ٝOvnӼ6;OYȖktq3{E6dFaɕ~xm$ ?4#^dNO1~ O(7,<1Ks@6+ P>>MPM2h\?rXK ItSe\SʼwThOn}h"]̷KN `L x1k)M31yay/ <"lYؑan fq/I;ڛm]XȄSkf(xA~?U߆^m3TM2[ VY3R΄k( ~M#'e@5vԝJu56$nް\՛R=Q8t}/ujC+K28ϑE,E1sr}Ș#l4 C'6D=^Ǫ7V ΃3ތI M(.CX`N#Fqٖ\P^ĩb< Zŋb" bjI3V%l5B-mΎ`M:˯rQF{=83ԓ`фEYw_E璅#Ň/D~ŧբ1D]K{<_/.wcMeU.QF[&jŽ0ԑsoƽ 52mB*<.AP=;8eĶL1,W D,ߦS4?Gaڝו#yж&xqC.$H,I[aXR_NDhL(X*^jy;]i}ٛ'z!4\A\.%S@"Z,_ _d3FcŃh'ϐv>eMX 9δNh'(L&Ґk5UpS.Rt7Wl7+̔ӛT!}dΗɵ)RNOD]";33o:6ՎhoKmż֦_dĉyz4XmR#CJK#ו5k И7xh_Zlϙ\8"̠aj9McyKmx)j<ְ8Mxbϛ?H^̲vlwÛsOV>onQ߶"޶VĮB~e:-OM+r9&8^1j58q;=ؑH>:1tPP-TnGm*5Q+X@8^z`y Ò6Olx+#/L7wV;ZQkw0j&ɖDzpb YUs\xv!3k`cu'Kl-e͞xڐ>ځtd^ϤPL*mc 9L|OJjpN ǒYoMr9}uۨpfQ.Y<`,OzĤqf>|)kGON+3#9 ~yM%Zm_%+IZb:ug[ m`-ܷf5Ay—ScX.yy~6~) IZ s.;ݱ%ZVvf63s{?`g v- eolv0Ms(=B5A,Š=tx7,?<` u5G?֞^?s<- 38Gc{Co"qy3vshDg!_^{ririG0{d']1e=l0RB9ʠ ǓT'mV<։۞'Ngz[ǵEq x?.NdóĶ@DLR^3'3[ ;EsŸuan-JpA} g 6VHVW'c1}huϣ >JJK0t ~0m1"9QA{Gu6I|?80t85Jo.4ޛxK4'nx`ISW0UUi'˷:ӗ̰,5w@JĎ5\V\l6"/z+Vg;N$:sy3mֻ$هYFvAs潆QYhcf +Ѐc-o qƏdQL$d3x}w{Q枌ײ'”U8U3GneDD<}GD+;GTʹLhȎf=oO4Zq&?]3EE:EJiSB'q>XC/ft FiJy٥/Ah:WlO=9w۞5ɯ3^F\VqwAsu;5CQWP4_17}AS0<Ж7,eƶ&Wsl/Lp7p_I5j-bOw3ٰqZ+9ҞaN䎰e!\^ āۆ^O%I-}фՕ:GXc~h4(*(4 eWV2尪#k_n>_m^:WƜefF/H|–m\2ƃD0:܃hÇ׷<8yN>lC3F3a&0O jkqVaMt1ofgfwkoCWzEx)*Y`>pe\[Agz"xtWt(ÐN_i$꽟!Zaov d[sO{ >]̂1Z͌!vat]G&\f+;=tᥝ9sҞ_f[iQ9RAx)Z>+.:w~=?_Sť?LEb؝JSILTt*?'IV>}w)^+^+#?&^h-Ԉ{_)b$&]*&2<ߜjV_b}KMV0\q W:5VWFp]_ASӏս1ED?Hoz^Y3ELti.T㻈4ŨAuٹ;*7^/I ;?T=WN6ram{Z<*P>p8~ Ծ&f>x+5WPpChh ILj4^@;צEu7Rض0I*@e~-\6bՑ^$VCFm6U\*5Rj$rIjDH8?L?SG xzK1o*zqOV,:~PپVR*3k{6*m;++W{}1rp[ֺ$'u°wmSsح]J9GeUƑcqrnmYK5\]$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IsjF2cR혇Z2z7Ixrg[cJ&c"6~ c":1T8'6dwbm=3>cNEQպ..vdKh> ̸A4ڴ٨| _E#^,S]Ҽ5nB}[t,߉Ybu_K[l>,v> <}~FgE1 J倗V=Dj 3_ 513Dc+"o#,&we@̳stKņ1ƴ`bg26ߙnݩҖ Yo۟CL+\Vj޾bBX+_kPvGߊp0\=S3%bPܵ3'k(ZCߵb]GZQ*oXg_:t8؎OWhjDoG'Ś ٕ5>pXW^|o}Q|)nl<э?4}凖z=Z_ ފu>UijP ķbbq_x%r+G Ի mji*Sr;>P}(b^>Rړf:D3,h͆h#%"\ҍ|Dų(37c'~=h~Bmq]LٸGrU\%f97Օx-nW*a)ʹ#fxv&dA=;vDbGo.\82 {nu/z3#G\X7̍_>l,V1(7{5FL5261?nLnLJNH>3-K!Loߟ?⢻N34]a͏: j65lKm;ԥnC%v:]*kOvg48pVLjy޺.}+rŬ] F0i FIi^o26+ޚы+Cyp #%Yrm qC( aD@'''&r#[8; =?Zq@]VݕuU:]YK߮@Y,)ܩfxMSx顼;wX8~X2-,4IZ,3łPwnm=f`:amL<͵Ci@l_16HTlͳ}:e{-s*jr]:ޙķ}4&̚KfN}avPԴAif~$իv# 2%o;<29U#F2H~4P:Y[4Il}StY 2U̩K)<;Nz5Eg*8 Q4Phf\uѥSs<J%% #KdHg\+у%|(sbskeNjui *z \UV%S4ٺoLe)[*=_#t)sK6Sw.nYg_{.KV7pʔC xa5+| Qy*1}]:jG lC!\eÓFtɂQ^,ɷx-oazaf}WvL0/سS|fH^~孒=zM}OrUwd6M&tlujɋde8S(&=kjDYkgqDV^ ESo%j[ ;/][RLFxI2s]3(Z|У,Z]\KX^X{S+*7rFIAֶfl7Ƽ+֤Oޜs0Rn4 Y2hҰ`yśv˖,. Nt<dZ% >\mAb#xF'^d*X`Mluaۈ,7ßsb>$OHMŖsBÛ$MCk~]6G円Ew3y\ȦD:sGmaZ #LYa -hN~\QgW7mvXBB =; cF4cX9„5|I# Mt:ɸENd3(Ov< άɣdK} yKցxnucH%Uw4:Ƒ'LOS8!9Rכ.|:21 6=OU\e¸f[oE_SȳddO{xypI2^.u cJ^$f4k'qS&m[&h/F`툧(szm+?Rv2% o$ϝ`-ah /M9Yj )m]PlC Cn{mg,{Fbۖ_EE̢ f G0&v \]bY/&b;7vڑ6 t.S|d;R܈3"8Brw*F0>ۆBDԆDL^F"ʽӈωK6fy(faΓ|O4 -Wvu()z=Ѝy>E *&KZZZc~>S.xT~1ڜA~<z=043֍ON>r9OL*Yw=4lTU / ̩Lu+YyWam.G,=PVp<E$UhN5/m&G=ȃY=g:Zh3-Qw9xɝkzH&w@7Ǐ^||ْzc S͒KL4X=EZ•ڛMgn.w:њvUyOu`0#!X S/rh 7,:҇1U@ uK4ˈ(('``9C8.Y^ rm>Q-FK=_SU*VZLB(_;ܒ'ˢ]%M{=n„Ɯcl'sG[rx#sx0J͠WwFd6#eѹE[EխS|_բ.O{</3{ e'Sɨp8ʉγ<9c Y[ʶa̓}薈p7b8iJO0N :Ǖg"c9` Ne :&:|(7yFU>6]$ 7qsO2;/5Y@Hc̬`[Fȯδw&Nx1Rdva<lNX'at[L[cGwzbMgM`6ZNv3kF, A${t)jc:9+ n{q:ދ/Wp1qW.ٹj^bP ?Ƌlթx^UB!p\o^\Я!6hǛ:ɤSBūr,>Tn5FHg¢\}-ᴢMBAVt-Ybߔ[)ukzMlJF d`:L㣧7zk]Xwׁ; y!"HoE?ƏgeaU?f |m^>&hb8rr._gJ >qdzϊ \ˆe(ҙx6s{Od3k*CsѷI8N|RY̢9'FBۗL ojK͘'PBfW;Mf̐> E9?) Vǩ(pΆ&PhkysUQc\.&G2Bdoʣdz|b/bέTu `9i1c}\NbyRVE`r:^F=`t["A7Ke{mp`UHf_wypE %32x[f4=Tol:q>܅@ΔH6>;sv$XȆ-|9=KNtr>G2>iCƕDSvEzܘѕc&:83L5HkKFgO\PS iG8¼'Z2|`đMGo䫝xf=Va$C= j\oa@9f1(w+VɴU(]CZQ0_ T{ظȋq>hL ᵌYa~7&UaZ$N` ;5Ќ||9<~qubp/[v3FzZqDCz@e]3<$yѺ^/R0a 'p":=6+ +xt1TW{j &qtsϯ^J5EMEҋ Vbxڄ `L1#80Q\[`ó^xͳtsj1IQ<'B5tƎ?VL.ά{ ,FPW#vl?S@9֚VXd3 v}evD&hs6jvjWX'pQ+4Yɔծ{3Lcf9po'vR_OKMs'̬9@GqeăooݹFP{YźR洗%9.]䜊^N)UJ:+%shÊu,kɲZ|-B~„YtɣGh2B͑_X:֑lȫM!Dn ;'0DtۋVÔX{Dh6HdC֍-ttslKYr_woֶ8FK1k>% HdY!-dTwJ4}U<:zUXhNekpO9rŸ@gwT3'.!VUeKY$GcbA͞)xrM{6njgˀ <C6O>>l~r*S(ݚnsMǒm=㐿 ; uq0jx j'+0ږK,99ҔF1L ׯYpg۳%Ԗ4n%-;|^x1]4NYJ<ߡ*jϭf)σe$PJo19VU6/9c(ݐ#3&]8P^MXJXt(s~&{ &J'81Ż('lt. ,K]tM/=cڔ2)^[9ZĔc1iDYͳ;U8k=a7q,\˜Zrk-GbӋtE7Ɖ KoM@3l'"eK0.WΚhSO C9#+lǍ0Ȍe( QWE]mEOϜ1d˵JhMmǤ Tf1J>~>)f4B$v6܈$@91gȏMxvŞAtA{ *zS˵RJt'菈Sh*bl}wrv5Y[xW}VK"\/j:Ka1&33+ź#!3#? X,gr~\&ȍAu"B_nmNlorsn7u{ Zy$Fk!--.,[֔v-'q0]mf\ӛ/ct*+pߔ$ju&12v" q Ӎ9QDWh>ŗGA):^T 4%DaS9wq~I?97OA՜ЬbGa5?jI!YKNӥW@oO\bD[6@&gxӕj 9Qbک[ST$կ0,'C;ƑyOϫ}PONKa][T.j1﹀R\j䌍L+"bb~5^ȏ%SBYʂYsXGh 3+8ܯ0ŘT͆hBfr8n?`Qؖ蔫0!:2ߞ6\3`m{8q. Jmpd}FpWVO ̢OYxC걨Qn}K)l*~ch0JáD^ANtK 6=JȊ.#G%3Ӫuݤ /(y$cF9+JNeLL?|dygӳ)WZq?&ѽc[3.Y|/9 f hMf7l-1j0cт;&PSRȻv.OOyZKf_T{%ܽˡIfKr72,s[PLƉ(<1C>x,{n'g} {dt^.dN}etE 7+n[_WnS:J)ƴR.bgc)j"^&`9ܟY닁S$I<^ %\풇*akiI|'<9VcXwLDL#?'Vd,ꧦϰi;FJ](^͹v I 8!!0\KN=ޞxްj"m'KS+Mvi5a`4Mj ^ol!=˛gCiWOLj:r]u-d)]d0%):2?w,Z|1[SX&}5}( yw{Q9=>&0H ˃:ɜ³Κn_].̫ Ee2-tm&>+}LRHۧ!$M`э+ПUh@h \%=j*ѥˍY]GMSZ2s a:\՟FL!}+Ss:GiSݭp|n*KЕ׬ErV4EK= 1>͇"c>ZѪ^r/˜1(ືʜJt7K 2is( ^16eGΚz^Ⱥ5 ho)FmP].TeѣZ r˘xRZ2<ۨRҦ95,DrXwڤS~27fJDƤ0c邚t艬 3v|0{Qɧ2f8w!;C`Y?SMF#n/Co6FDGL nI= D*(x X ?P}-ҁdz=-I;ʄӘ>yCëk%aA5x84XI8]Iw%5=KV1R*̫D?s)h:-5Em em*;ɡ:ǘ-Ycm8gG/g6$&/J9.x#7.ZkMe-lٔ ^Eѭ[<нŅ@~t&.'";.TI#eTIָ&1š1ݤLFo0RyӘ?tz>3c]y 6HX{ /{bQAlDt>}`SAG?݌KP"bX`gww [Dsxr[%,MˀXx`fמL˸yρJHUR[p TȢ&zE,=gZ}*'ЩS5)P;iQXb&O:~$SYb[=w~elh,Nrߎ7FVOX̕v,ߟh1O*eQ%!w㝃:y1+=x+_>Y.K $;*V|6ig!GdN"jRYegT pc^z?B8;.¹6tNd_v}3E_I(b _'9(8]nGVN:xUyJ U/D+> gʗI ^P^9W8-u݅h_DX1 z½,ktdpRۥ0n2EBY7q:b<";&g^a-b_z>(CWQ|Sٳ+E$cp.#J8ѭ13Vqrf%kڔ"Kò$ Ә.tMv %]}5020!-9ۄs> % [Á%2Tѵ% I 1Sy|;,f\xkaO C*P͸copQ F)CΗŘ)cOQs+VgaIh?#5VLqI{s); ֏Sc0[s=\S eYEd:qOEWJPu0x&C kE%i*Zm9EJMB֚RU2Ґ"N档bFj>[e4H#U,^6Զɤfe!w+QK{%e*Qe B{u#O= Ա\E:NIb! >?S=RIv)4H32jelWT;Dg%"J0 @}<)R7 >j%`)DžyGryv%K}H #!CxJ4=sau0~4ch(|agdSFd$ݏZ?\r0L`\1BN)=yb:>umF CYkd {XBqE+97l`p%Oz(PcN# !g"SI!0&oQ(-? mYMT%%~O HZ v_^3޲RWgWlhg0-:ZRD쾖aS+6 +yex̨`RxAZl%3BU = aPZA^,KƲJY9/+p;q-L@%]UޮӅ.+]yRSd0;NVa1c($,YQ]=70B6+؝nQq䍒B';!^csX #>qPj֗qIL_&j4?i K$.w1U5~ssdN]Ť;aU2i{/7}#~iSb<] ͝MeQ#f{ Fs hݐ̞Q.C:hJrXrNFzίCxv>|RBؿcQ=m_[8.T~XLA[PrQF>rJNIi0"+cCJ_բ@c/a\&-If(DdU:>j*P6QC'S~nCk4H6VRogH^?x&ۊ:/alJp0Z\Bƕ׶&RTK(8eG>Vt1 7|"_G8oL\8[BN*FZTB%h** }P b*nVS$ܔRJ_WƻOdܽSK )ktdDQDīPK ;z6(W vu˜fO%T-Y_O*vRp_j91{|[9PN2:kr5++YbUwn. NWUU'wͥJ0TnOBND{-?kEbn 6syd$ BiCp(1z1oM3$hfF`gIP?~?F|7Jy+0F|=oHG#ta\1(ΟƁybV+=zC*9{LV(YP$Z}%]%Rǩ'|NSdr@CJy!C-ːu)"oo@)iUD|J ~#ƄZڄ?aCę%ެNu6KhT"DvQ %t{$&sE1zE*<esO.CRb䝊Q/$sm=gds.nSn4z;e#K]bFu,c ͭd*[uW1JY))TbzK29ґJx(UKR]1 jfûZ]qtV-g7KXN4[B̶nF6?.tйfBQDms!94inOSlM?w .M">-w"c®W9։k] ]GSެpưq,IL-̉IoR:MgYxҿIquzzw}sY-P)ּf- f KK%}h-CZ@);f0KC}%G?(_K[Z~]wTjwWui [CiRU0,Qǚwx)m|۝"]K(//mU!yZLXs 6JMB4%?MyJcR}.r8Q&F͡\ʢgj*ç4ip ^Ihq.O@/UbZ.X~)~kޡE7.:vUo K8>3wW#U=Ǫ|z/ z+XD? *r^#Vݢ*ծaZ:US2Z /~lGSOv[82M!+6n^͉l;=m,Z0&+%BO<͉85z֮+LÖy>鍡jHm>XOџ8ߕ0`۽ |{RǒX3lV#jm'9чjӬ% 2MVp^š5uRu-W+QU$LxNA [n HIesitKrV\9]ᒜ3dҺo5+K8 u]`w/`E(z'[Phv(,\l';5/ִbJ,aUx֯' pt&<-Y@<te0Sx#O9̐ڏDwѶ\'HiT\`j,HwLVC7m>e8`&)0,X&El.y>7y:52-yU:܈o`@Q%T {@%I[TTRȉJiy y.c{ EJ"KUr?$#*+ nP+bݎ" 3PBb%Ĩڡ- 8#l,^,MI"c㰹Hq*4l0di~>{S]U4 3[ϝRf[)b[UCriFga 4aB=g$%zx:6[uMIOm%gca`f?ɑߑenkt]DŽ3NK ~Ql4Tη z*,t mhyz]Qbn 6rͷxx-RE;ԩȻ\u m 4e,፬BsSĴSʊUV%*_O O)}&x.!6b\ Z(ѴBV^6Zfqc:C&R"}YLޘɉ,LOy1c;e>;ωV$6#bK RB]9L^a[|s O%|)`t)B?x65t%L+V%gITA_ӯ6shz-Uӫ(&= QE*\W!%ݕ~P.Y3/F } Ǝ,wrK0&al֝u+'p=y$SvI\ogV-uj 631NM}xHEM EJ_!cb$<\Gao|XƖf\]c̪_tiKX4^-nܻv潩eԪXv@A߇Jn ~P  W]zeRZω$/Bwf3|a>cIy8{oG[q I;Aj 4qڻi$=O][gϷ,4-UZלUh+=d-&kWx&jIO *drq(YA[;%yy}1usNVDn''2L?lJ噸m/⇝kRMFT";c-g fE12>]cɗEǧr8s;c2 ӦTcދ}Q)}RTe BCn>(h<ͅx5ϏkUJnռWKULxaۥuj~f Έp***pG}I%߈NhJVTZ%EgѨJ먺mA{V#ՔTQ%+Y9LɐqJM#5z*F}Q&=oP"U)M!^j9 Gp`i)O'JwLOJߓD[άxlϢTʺIxtF,& x5Up4~"eTƦ/<^|pO,N-DXݣ8vR0K|~"QQ)h:k$f\4A A$RSC23#Ѓ&B-׻6*<`8u$萹U01[i'r3ǛNdJω|?-*m>D!?Qv[Na2cl/%=[d<-gI,W1 <\7)F}"CPQ2qEe118G+1=aDu iDKCiȺ91~мg;$ak:7jywu&rg0ii%i K r.Ƞo g,T̃zk̇s{< lcȝoc VWi쨱`o.\o1y,ɼ{{wtg}-K0>-nr[oArיͻZέbKj-s W-"xI#O\S_:K{^۔ocڽjBG Œ 39ˆ„O%kvh#^vWa@JMO֮G) yL2bVYR)'vOJɰ*W)nߊ+dǦB>-8>8}Pd|oKY+cFooɹ\Np]%R;hySJ+dҔ\jfQ Q} c9NRnJqX$%,Lbò<7'8"¢4E(m#):O ^׉!o;jl /ĻĎ3q0!(Qg+wM ӷְQ%r5ﯠin4v&v_l9&pӌ/v+)ǃ!4KBϑG,l T?goh݉y/1&*o$jH5B'KVIBd^]f{`Pf5M|^.fE+˭q8c"zvXQv3XMg^a>v3HƱ*hp%3TN%7GL |ߝ]~cgp=:>DW0hܹr;cms6Q֜֕/ ՂjRYBYB{ k].7yކA͐Wp޻utܐ]X|'I%~V^𻼔fel+aMLj\D$gq5ҠrCʹ",ݑbao9wĜoDN9.2sL䌹^yd)ڡ~CdԖ2}Y봠 Met͑MF,Kfq+h/!!WD`T_zLd)c 4?#Xǚs +3x3S+YNûZډ+غYCc%iq*cq&|= aN,bK^r&`OhԊO,I]+se0Gf QQ-87݅+|`^8Fi9wG7>0im[W5b\փޛ m*<ѐ/M҅zᄯ֎eFv2./~,% nAEt/S >Mʪx# A"hL U1<|k8ZY-di [XAM ,U׿Pƭ䝛u&NMRHSz}|J- 3#3 ޑ['_¾҆mX`@BOz\ݥǷxql=T[k CZeo94H׾t]1'i ArjeD025MԴHUq魚ՓVC y%< K8yPv̉~ FyCR;э1FX!7=)?0NPu_?UJWI*LZcb/bfN#T¦ֳd˘tveqXiCixkM[s-i8Ahڐa]/¢$3E"^6F`Ӷ7;-|NȽLx-B(bƪ1-70da/kŲ&-?-D(p[B\_}}v$3N~U8}oXpNwoBy^6gsVvuaf/NB ˹S_> D7v)f`1kPFgT EC 0 ܓU"%IMI+hMH{h=FɳĦJv`C/BMYk9~'D3vnʹ6]q2"b>Ay&7bcV@ѭBbn@ PSϼ"9tOcG3K q9\ֳp/]#$ښGay|Ƿ]:7 $,^u2!B[raj2*p@JiO93$P0鲒L9u[$cgo+9ϗ82?P^GݿxFQXr p|(K轱Yj8`X':^an&Bh3 ?Lp`^'m}]ĕF&qnլB瞻k*UD~qKWrp r튎Rqߖ?Q5[JJ`Ei8G=x=~)Щ{GezNKaMKFۍ}+ D-, ~S̋:%@6c;n'{뼘 C$8 zz~F*I޼^Hrl?_AnmٓK{ۏ@/Zc9i'cӊ)dy퍸6v*V>`VI^ fV[-gr<_RF>y(ro4o ]6IaPI=jPqse'BI+/樈T3^AiQv֔F1s`FtS6:u2ɻJ=i ωyEL@R -acLgv}#K 9+E g2U—MͤlfSaO;lgdy.s84[|{eOSƘrL?&h7i;2 &yuUu)M$4yG}Roz\].X˭Q|:dz*Uj.$T߭+io55gj٩]4Ln#;80žu,u;`V7w/[c=6V!.lcȋȚzl_lvH0m˜vߟyFMfϯ&ȗ;90IG1m;ՂT;c+S~>2%UGS nioCF=8acY2]}@@> #ph$f`S;&Fog͛WTEM3/)^$|4{*W)Y ޟBB< 3Y. kLƚrhA)O1[) *ӖÌi΄-W_!Пm|7,cе>ūF0Ud> :E97XG8OёVI8%^iܘbǞx ȀcRg^'|uCv cx2Lq2?1Γ4gurq:<'e3S ۅRC|5C,׽1tq7l9ayr|tkY#ye%.ĭox:9.LNEvY:gaU7GoI?N܇T-H&=4$Dc:e#8b^F:d1]˓|&ɥI,pgNϝ/ʦIn{< S]Lc2 msŢnF CAg9(Z/oMkZa@Rh[oIU@3N͂yCY|mC6H MU"ֹ c3KI ga  Nj h]pw4k-gbE+, $1'c1+9& \T|)dB q,Cn #n`'^iYe~mE/Rx>(YR_%')$>)+J;i}$9~&? Gd|tN9'Ib[_ҐtJCs$1q*cXc/I"YݚBJŸTꉹ.SӰpJ!][Ni\"iqnOMtvgstN"9+΍֦j Dؗ N w6 Fڞ 8%wN8wZ`蔐tRXGhU}`~I(>ٗToM%1nUG_b3C\xXb_ iz3Bca`os̶ֵdYm8E01\lnMJkql V\3UE uP.R K?g`$!RbIŝqȠ3D*?KiZow:>~0XSF.:UM @d,%#>DIIX=J=a4B(&q;mJa*RVCҏP.2+iCǩ,FUx"L|F4ˤE.o2EO|s"v`q>C2>Aז\dHJ'&َ_N[Œ5Wq'BE B6AF起] b?#Xpõt]ɖ_dU޴f`wU( Fxű>hg7Itt挧/+!|8L|'_n5YJ|=4*"Q?B{[*eY9WH+&gӉեp g%| -B},^d/${J`*^\GdFѺd{׿ ߬ƽftDa僲"ur{|(0Ar3nWVEaJ94(ZVrhQ:NnǨXDhh)OMJ'&-|S - fU:xUd_r^Frs4;}1OΥ۷ P^.gV9uKEa- #cg]IVrj%ҩS?i "YʧpF3('^$& |tk4X:'pbP2svLp"wS1d g}tVc.I5-y\D|.1'9Wm4M;cgiS^Ʌ_8ܥ-+2'aNP޷'5dD ,\ " HZLR/UsKfWSTsV G #gKez怹Pf ηm{'shdEZGvq 'Iτ)J[▹"7s$Y9Eͳj]Ppcvg 3M'0=H8̄&xm$+>NR!-/7Z]IqeH}x<-~0܊)ӏXkNJQ,?'yoT2BBAjW0IK˦* g i)QS[<d[)d1lvfMaS^y.s@ j? s9Q_ͤ\)n*LdΣ%êrKe(Xj+'g[btMŁS) h2ck'Wzᢣs%dzXDDZ4d'Q3 KāDNW"KV%r(;]spy9&)IƲJm+ʂJ` h7;q¸n O+pC7~4=Oc6,"~!CKXVΫe_zTsIմjXÇ5<0 `YZg皸L-g67PҢo^M!\ݩ|mړ d= D=9h RS/˕|$G/C'<-'Z1+Mi…u',r cWag+ƔinՍ+ +z`q:/$Nd͂Iwrd]8$ t0 SEeÍd/p3r2Y`) UT$扭Z WCc9Ew׵aj:mbW2km;+`q$e<18wO9‰|XA!^J2I)-|85H?TgLq.4W\pgD71Za!wc1ٓcXɑpMm$O9)Aۅ">lYxlHՈ4vK(5#iYCYNGt[$mnG0x4tz<\fsdR*p7-eA<ư[?1'|vj?*=m?hkLhИm, .Vse6UiU<53w3X[6F5j|ft+vÝhf$'--aԣ"$Hx 82ӒЁ8iжiQҏ9(B]U \X4uH-j*uj>.u%o0X1Dŏ S&wO|']J^X{jw ;g8Yҹ6S low`sc!T%nj)8(1%u7%>rzx)NRG=Tj%?.kX0CV7RFoc>iC'_ޚ->b(Jqz`^* Nˆqs-]NeRގ*eO"lK(5YA_yJɅ?2gLΕJr:8᭢_AwJgzNމC͔)_JY?##7q5fp80 .O@=)K;NMۖXͣ1t E0gmX:w! 8Km:=9F%cJNS/e:^Pq`!3")A$䧍1m +uSs.UV.:(1>/TۈVu0m£nUt[CLѱkV㥕WRtvu>yq9s\nf6l:Cw EhȲ4FfA)*9PEŕq|aVWG*~dlMxn5t4С,[:twX?h >ua|VAz֥zyd`8Z'4gTv hV |Ҏ:]sƇS]Q11m^rZVЯTBˈ9k*Hg8T"=/͡zmD~dEh65-Ӛ2#Miz݋c`"ƭ+ʯ2(c^1Mg\^UJOW`SJ4Lb 몸[dBnms.ӚM1^>Z\ Eߵu(Άyw*wR+Lm@^$/g{}d~ysrhL}6K׸'FޒO+NO3a w%pAzrJL82㎰`扠'iNuKfv 5ٕxD[UCjN"O%_Rt"L&$ӊIΩj3"͌{p!ougqwN ΆAӏJޤHq!U[uH;89+}}Җg(7>f,fB }Sw2!YaB,Mƙ>R_ы.~3H 0`e:NQH1Wc€HrvGa/1Wo52 Cb5Ԍ̂cwٌN5c@s:N%!tm0iMim/AU^ʅC\xܓ؛ƛ1,' jM$}dֆPϒe~ט9 * fȃc*fueePn65px:>μ~<ލ軵.۬Gp3/p 0C5gM&u8=fYԫ8PJvly4Yd"GZ#kxEsK*-Kȼb5sv4VTZoJЋ@(XHXLKsR6cڔڗ$pߨ.m#F&<1&:.7}g&|G[lE*2:CfNRO| Nɉ5c%-EZ^QDo/fBN$ !ӱOB^wΥ't&ۗyCXHh?,{nTVMsy.rbөYͮ2DOqYh4FÛ_2p`Z6 BPbahp<"rPVH҆)GŁv_.- G"HHcM |Ք":X'm:>钜qm$&x-~hiѹBi 5V̿08֕8)s{B?$[}x|O4=ٟK:X:Vab>5ܝAg ΩK5}`,.LÏγzU۷U *J=?zq͛aIf~mvXΝg J꽯+Y{pc? &7-8݄Nch{~8cyӜ^ M99~K)hzͺwb0hP&2z^.d zÆ}jcڙ2ÅQX`UO2ZVаO+r>^wdZȆ9-$$'򳄋%Xr$)K{L%#cI=! 2gxy|'{0GOli:Wr_bi}͋Ik=$ڨ0l =Qyy u MK>N%/Xg:9ݖ*5TGM&`ֱ![>.gPxkǏ՝b< |GFa4Z aJVWPLƠZiʤ>-H7oX5ȊcXi:]^yha_v'rQ-5gER; ߯*pI$.%*cC%niCCeG܎.ilgQGM+Ioň|c wI$~Ƣn$ % Ro!S%a+13w9?!.pkۦOcFWm`ob O$E2ym`?s4|q:f2T"'IJz?r%+jՕA^6'L)'UO6FЦCz}p,Q|ƅDP-ߡ 6Xi yN"l*X{) ޡR Y%DK/o]蒞ID%%rbMٶ ّh^Ec8~TM+ >Fy01JY bR2^=8*z=mWq|fq,ͽ3ѿsyc%s+qXELÆAj :ȝZjityWAJvvd5S>( uU2eE]e^*pϩ@q'f+v&N;r ~ΘQM]Id@P1=(Zbw(#rE!I/Np/!c ^*;VɯuBRFs1I4[ ^A$ܳxr}p>CU0'frI5Iose!YaR>nx>72hcX1al4J/ޚazc-!ttos4ґjof cPrqWHEGL+1 L6B]dtLet~0;;qll-pf= g(kBºAtU͠iM0{p^ёQ83X9Szj")K95d8p=p6˪p\ūxuճ7"=W?3uDةTu1[&WJ y篔Pq9K'K8/-bx`@_Gceu C|74$NoxIbA|MڞmIHCIU6׹W/ c+bI4WWpb:RRքhvkQ{T2|XL9`bMC ў\Z [EE7q'1P8R =)4dLD$ RҘ@XJ-$1>ws'+G11u!wѹi1)pxQJr@ƨg2U0VBYATovaEOw&=~.G3[d`McAQO[RaMh(èEa<42((d֚jçbNaH`6eP;/W3YJ,ğ+D) ޫt>f!%,1TpC"<^x9z8eP,qJ=$Z_sqKM^L~̪fՙfSw,gVsUȮb*=_*'AI32tl]IeIj.nQFMdSUwY“E/py]~Dj^Dr0Q9$v! [fcL=WԺ$&܋,uEt+fIL%p$'|9T.d}Yߵ̫#H˂T4YJޖt̄#{r}[kƯ'wxǒx݃uf957S'kF-Kӳfn1=Gxs><*GWwzo0Vbɋȯ#gX4DS^H|SE+}qaw1+h/#z˩.'i7j1X`g)3`/>}6GfhꅢLTĹM:LsKDOb: ,/erB̊Y-5.|/%PjVi0UGM*l[5ge|"t `v=v"Wup?fo _ݬ`M KڹDz 'z/oeݸҗ~/̠qoqCVaIs۶um>5@_Am8Aow?QvrMbM;umĢ-gm)ld>3eM,EDKKJy"ܯ潨c"UÔWAA3X_O-h:J"L܊ +7_bb׊N˥]1 lr04]29)XV:{-־DWS=ҷ=th]L(.? *3śyXP2%zr<7`&!la~&," Ŵ QQM1mִϪ`8yy *ޮb*u$Z^crHO;SzqMG]sO[J@o<X:ˡS O¨>c΋S4'蕦vq9r^To㉶ɳyVÌ3UO*9Uz!z&֣9穦}u*Zf2%嘵-\B0fqcb{1β%Nޖq$vCp ̺֎gSd6ɠ_8'aM6FbKdf)&ik ^ Y˘V[!Z^5X {uL ,h68Js :[WRJ^3bMf:1] ZOT1d0V27%hWIҸXD:V^C~e:U#n6fYXV3ҲF/fWNeUprlяjH1mݒνSy=|_ͣ]ugQ!Iy~1|A)a9?=OG++1QfO+XcG-ZDihUwJnSBib ZsB9ge )39=l>U1ox5ҭTb*$Vd59.Uֳ+ݥ粤&xӱp ?)8@AhZV0{? iDx=x|;ςs樷-m&y޻82EDYځOFn~dD3k}^ol(y)>NF-8V,/`@[?SF{JƃWP"d{Gcº{0u3\hbo3DaxReLcaޞD.sCEY_ 3^0>8DHgq*F;Wpl(1:"G习U -p|>g 0I0)\ flqXx!P8Z Wof#5V`/wSfzTaTEou8X#~RB]U /¼*ݬG`ʐ*XTpج:NrD:#cqꤖ}w96Whn φ;0*і'-8֔(CfzV3Ton-6=o󄥦:EGzsZ s$6s^g$b(ϛKQlSK,[ YY]|Fa)uJ% ӄV'9}"U'R~0kWTzW(sP;=gaH>8"Bt%=ªq\ry s'/GĔ+K J΅$^)1ew>MS|(N%Ȅǭ;-c9r&`Tč%4VDrf:څ,Xǧ܌ ~{,F<914E"od#CfgR̖R9+eR6H12^Ď={0{|OKJ^U򂜉Y2 < &eAEܶxxeq_6;fL SJvK錜}NP1]SI/n}!zfSYkM+YGUKOd=b=}hTռ3=-ٶD&-g:>U2ɂr* $ ̒4yB*$n1l $kǭiB+_ JFsc[~5=#& &NSdi2ijDTmBBe] 3X$l>4uY*p4,d}$M⁍K<~ ƽ]sG"e><&4IԢ@Kʞ8k\j[. !DF>؝%;)cKSWn+Ix2q?Sڄ2M5IJu~*RŰ-T@}i)ke>YG:2zVelU˜bb.п2fAܺe~ER6h")N~~:m'3jL2Qn,1S MJZߤCp}!r ٴi%Ք2bt9~rn^"ה|r{O|`[, yۥ;/ɦż4Jw2Yɴ[BSsZoKb] s&V&Ŝ/W*zUHǓZiaGqf XPDrs=G鉸Ю|_(q%'rt б¯_.Z2&d* >y})Ŷ!i42Rn~Nc_[ ׅ ܞ#ybT5gj: CoF$n0nv fP2ζ#~OGn9dJ} k8G14jXοN*2Pg6_}4tʃEvnڑwH$G`dR!j: gpnvf0‡i,˛AaV݋HOUJB#XّbsBeU2z;8XHMi9OH8^'y5XIvlb|4Fg 2͖l:5bs~|!s.*#=˘6e8#'rjVw^I %|X`:fI"dVYI縷Noi"[1ȨI$b!K%zF<3:;옯肆*k~(G~LR yu?kZnul?+t:6h)G`}mzhhv jjٰ;}ECQJLT>kE$GGq}fSW0Y7-q-~R'E]͗obɤlⓉ0Ma[1ҽU4:sֈsPkgϐܟ?D{=-D& kQ-勐/w;ԎiߐƜaIL!3SՉ)UBÉH:dp wOCq= J7V6tjÜ6">żYј &W_JR]W|5nB;Pat,G7۳qK|ȑ8IM [N3l1~,n*Kk1v璺[)GpuSM,ƸA ;s92 U&52||BT\QwªLnK=sH !hv6ip5TIgfu*K2pt~vLx]z3koP|)2lutٔUR?(&E&tb@5-5]R nGni):=8-ډ*n I^d-zkp"oL!ljrFʕv9~biFf^ l2Je%ˈf"IxVͥ|@y 09+?fnPBTj)[fCSL{11%zW)m)ZȸR gg#ɹK QUK9_&k|]C87Cr ŬKDbGF/y SټKͰrj7({Eߝi2S="hJW|3gssR8?\ed)2q9T̏뇆&zJ :rfҷM Ϥ$UɹPU̢4ͣRC1*X7^t wmpĞ/EqP QSފ~L._gZmck$'lD?6>irAfKV3pO7Z&'}J/@(Z?+cRe6ӘA;|[hd*.yZ/[k97:ŬzˊL w+d^܈?LxP )jlHư;g; >4*NaR~,@AEr~vPaYImG_믤gоW#W]][a3ZS[Օ3r?$'9Z7v)pl!2 ߬MfuJ˸P"tUϏb2"terFG}3m15bQ6d!_,q)`OC)xb1<4JLm(tY|v_G 9,SE1O#Eڴ8F^W|$tʢd:kDoK-2ˑO磰ƴhr5(2gMr}q~0>4d 2@=Q5=hyOs\Pi2aG, #[/JE; .`sJ}9%mQ@r})t)0Ey;{1y9ƣ7;q0=h{4-/dhL{%es57PgJeZZ^`j4 QB~txY3*ܘbJLpq N x0tZ؊f(=~0ZfHPfbOuM>1]4Ep N̩xd2^iMtAt8 SonDVA(Ʉ(m#D),wh0 WXj#e890MLYO/:]Xw`p{6gM[>t;$пKc@I-JĻ}WΚ2\f^9碐&u%vS}Q=ʖ6k]\:6v{ԇfT.05zu:p:7B[8#KxWw}]+q=K󔬝$vN9[hY]RJs&◄v~H_Ex_repO q|h>G>䳾V%l7S2#b.C!xMǂb1 (&N9\&8/ 1Xa:cuȌ,sZŚ3h%X0µlrcG8 J)?_WN4qe%*(/gJ7\F˱&J% 2gSЗ􏲠3kFlr cG3 ;Z%ELDn1zr^8wzN0O4hIy8#rgBOg2/=yd5;\е==N rba̙ }'LMt#9O5scu}_ ~D00'g}$ClajEF *ow_0 ([|Z8`[KɊVrc q2j]+!C9]~3NlN]c: iJѐf /kA-(phY\R bk$fL#kb,9lƯ̧ZQ%*2f9ؠ❌dTsh9FKȿ^Ĥ,mO\,eI7%:$!e]ЯB?^IiBʽwкJw b!7si=?h,m%hIx162q˳t#pHa;WrJ~Vd뛺+df1Z m2|eZ:pXPnγb ?K԰=Ky:R]k*M&sMi c9ؘȩ"&3f]Ǔ?sE[Zsڢ)oesr M8ݗ h׷@ tJ6 ]mĜ v<3!9u(Mnu灨; ̜ӵ-pj7f93F|v wMٮsC뇏y2 Q2r7Z_)IMd̙tǑR'sAB_PKGU_FGK d&9ޕb\4Zg9QkknL+@x6 CԢ⠟"|ىG3+O0y &Dc-dӇtJS06S eKnR,0msz KRĨ1߇n1&8ܺ3BtEm_uU I4,bÏ" E1?%tO(aV9ۭ0(e~6~,pp1zexq'O=I~0;:rۑ&"W~}F|JDY`:/%cm ^ռ0[G=Zfc}}8M3s]Nl"Dp _SfC:|oγcSٝaʩWc=]X. Kr ύ`.).87Ʀ 2M[4P vT. җgG:6lܓ255_ [Ķ=HP+vMj`eZɓ^,˶d`ĵֶF&ٕhNHcq Of9dv"//**]ۍ+qB @Cp2Ne]g\w}`cGQyQTEKUL]E }+gy38U*@(qJiuVU&tZkhFRGqU\XAA>9L}Ӥ6>y~|/\C6ÓEE=N!!̒cȮt8me1<6mUT2,L)H2k2yMWfr!*62{-˫8>ažJo ̥iK-8Yfǘ6wh]]`RChUƌIna_ };cZ8߳]Qxt"-ǰ(.Ċʝt(UG]|l&c0)sv\ݙ['9tEpqvc,{yO5O+MW?BS)'Top 4V)-ѕl_A26tU2(,=JɾU*.{P+ ޠO61EϱAz*5gDW8s{+SKg$F|87“:XqL_Vv j`z`_FMa_)+D_ ;fgWڳY{dpWlJSuG!a]MwdQ#kں}b > f MHl6sXg K|(tٻ-y)~bah*=b{J)[ecmU .ݤTe]oͲݰQVtB'4Τ2}B\,&,'v4:y2O2_naPTL0]"+˝Yĕ MG"bfh/g/* >)aO(8^VI]2 `xӑ=2[6's :ЧH=G={~؂_|ߤ! -?$<d|^>䮼2KC {i|bfۤdv| mS4LeEh6.Bәo.QʰYqU"/9ݼGʨ -xj,cn9H..cQܩ#? |+跢~%&ʙY$M<#*\&RN.lJY͍_=]y><8K'oJǕ2 |(|O~?x=\ `gﮓ6W~UoVѝu.g ;yxALFmI%We.f\2t oSW΁12ln]-r >i,ZrEERϗbnWń v2K 04ʇg2_ZBr6V0%Ԙqo慅|}4 V9 t!uWDEEJ ;:s½c;߯6 w>,i\sSKeJnkS#d ̣5\h_C-ZnVww5oy%>47v#yY`tiud%9p;>Yo/`ӰLvvk·%x1m'0/-%+#ajo\s1ǂ FLu`g/] a͖0lpHmů9Ҙ=oO ";%qBUrvjPժf^ʐHw š7ݩzLlq2zW~;7>KH>ӗS-ݥ­,f~|nlFI^D=VX=R@2EϞ0n^pK+99RU_2h`I ^=NNB0o"%ggmW+.Er"Εϕ&PQHX5"{W䈧+x$m]spܓ4`Ca`ES/ ?rg*l MlPi7,k[QZĊ|jAj>?5."iC"Ɓ4/3¡nV+4}qg,MIe#x3G_ VqUv2ʌا /*PJ%2ek?Mgd5K(I%J.VQFIr>Γ|W@~E Cy`܋M(iS@cb~QAR-K.h8]j9@e][5yu Mh97GŜR2yqql,D6NE~Օ-({$quKIK:7ž҈`Vaʗ$й4M3Hiq:iB nC4{;0 a] juKln akT lO"ni'd Υa`@Xb|KUD8] k7oܭZඟ=hΓ+$w͔VEh `7G0`pMuOjlPodq8ХΟo&R[NS$wdP j@\ՁN̾0P*6TbJx%;~^E3%gQn2^,1zqzU)XP.+9Ǖd'X\NsI5$vOW5U21W.rdlXY,惡|@nwb \9%JrF")b_Լ\|kS؇J.Z+]m n3v]\֜1SpnI.i;3۟f:sZSU-AӀOipۅ6,8axt9`gJ $i~$/Xy1ׯ"fv("obY=w+zig~GX8Ƀ=ͺ{l!uA!8HM"WX⼖11K*6}6UI>s$!)X,ćq<9QI;2-T:coX%X_EX jNlʯGkL0S*reLKIr5JڪiAį |R3%SÀw*jlqL*T\ف㨒qn%*$E2\:+󅗫F{ -C\Kw8)r-KdPy<Tqnl{ ¿y:&23;--ǕxڅP!,n+mxcY@5 i0"w[09gqzzy}ݰoǏ|?Yəe ǵ0r'] o_Tµ47.ccM%sy>o|L=2@߂;ut.uVi=I#y9#q_ 7 xԇG7#zHZbVxD1qK=ə"#>N˹&MS94*uh!wF{Gq"Wuʗ4gJw2NU,ܣZVƈor'[)*^3A꞊*v))RSjDLCÉ-u߶PYE5LwgՌ( U>5u $$muYFYj&ZB5Rְ /L>XE/nl@c%NS#J-I^tH Sb{ 5=α&,҉WKe̍Xvbf7Et$!l#GЎw'}K|ߊ.rڭFLlZ7;61cg'Sh~z}ʑ~.`MlCW7?.XZq{1}W |̗T"3Pql|iܿͥh\c8b&\lǙԍh2ɜr.M kmSAZ MP3g[֌YG˜X ;bɅc]IöΔrZJ^'9sMfZΝ54қ{Z _>"'琊~CkK%mE:*VUP'74Ze^z(H]̬a[ Lab_) %v8<;f&2>gt_ƄP)>+#i7u=,WEgtE.D\s__2N/"DO%K:71t}~ѫxCvԽUhУkqZ~x1ǹrMYy)S䳳s,ox=GQOFDS|.1S^R"u{^cRj/ʪ8wk9LZN><ìu7!O瞽 G߸d?9Y\Htck1>T"Sͧ'gby;*4֑%x-f9c'ErFd3A^!tӷ݉!XZO}v Ǎ~W6h.2p(;G@O9er$Xʇ/%6C"g:CޡHF{o±Dԛ8~ ȣk<Ђx3%c=!%ى8cBz|$ZŠMdrS6-bhSBGj#v;7y+ɕfuVp" ,}hH]BlFbV7䔒C%JmTjp򱉒~24+< gf(TXrlegk>Cά^Y tFd ;VUQѭMZNE=:t$Be<2 st6d{bq-E1iEܭC)#<͓X>2j/y^_v3hVOwkPv#>[.Hʈux<ߐ_ "F8QʭWaD ' a-q:3:1g):IXeF[a+޹ۃ {=HlƲ,gM ERܗ:ݔ7 )1ҎrʑW֍!+2<}FL]ך7yJrvt.h<̖yTL=K $S0ԋC9x)e[ƫ~&Dj\JvҲy,>q-} DnEE*5++ 1G|MW1▜OMd9((XGSd(62ap)kяTLAXɗ8?-\>{/:4yƙV,2Ɍt*@lѪY9 d4ئqdr\8ifaRhФخc$q|32u㷯o9w>lKgEVuȃGcߞ~petw6'FٌEXBbs `bFt+>v㈃-]:܉81{=|i#Fv@ïh=Q!6hak.\WK.FbYD'U[3X`SKZ-'yq.AYH4͈*8z"x3'323>FmlB&+Nga4g8wSEi5|n+ǼPJ?Uɘ6BʥuRF6Upv% @n?m?ɯxV.{b/ڠg vjXrY8<%'2*pxB^\٢=@R7 o9ԻQ"ԩUSQ%#5䊽49WMEf8Ҵȟϒ{1 kqżxb%FbM:)Į5 m! BY7`5 nDGv|jū}4c!=#V.>-X$NެsKTu|mw' Wuff a^ 8p~l$%ӟc>ssY.`+Q2{Gk?EbysBq<+#;o[Hw懱mSQRϛ< esO»Sߑ FE‘,an0d0|TaI0AFI0m,1ohW!.Y_3];J}&Y_,Tvkf/SN'H"S.uhg.sfI-.Zrɖدp4{qI/426\.gefN@X+ozX (uPEU]v_bttf;3H2ԅ v]%5u)hA4~s+ٹ.없. ws" =Y8v\2.l(pf1{Ns}U-Ϊ9Vƻ%-HPF߃\dw)cN 'a;GpFٱn?sHneGtmޙOS1z;ܑ̍^x\`OgZ' #6-LD G'<"yaH7o?pOm~w~sQrvBYf٩'%[qWF aO;9ܺsti(AkpeݿPoO$0)sb\F9e̳-7I“]g' "኱d3~*6/f qHCx% lV:SNo%Uh)emc%V]TJr7$9=՛.~pa݃`ΏOdӓLy2(K.~Kq\%YrZPMU  \1>Jče`0=c|R2F{ /q8ğ.n^Ȭ<^}}Ј{]|Ů^į8K(?sO{n;uqtD#^8_a}q? +c\4J2F!9㿙=!}xL-,wa^͋x Rd6>XC( gt焏; :+OBXȉkی0lEᶦrJpŰ:'7;,wiI0MMXq,2 M fTT-)j2ml>YĎw kc< ↭t4 +8p+OIm mZruVҹNam*5kDøj.Q}U +E1_mp@@>1<*!.%w&{#;fϷ`/L׻ N,{ho&(3Lq|'QǓ -9}P_ ޖnxjP+^a4g*+\aSw޶K/UйprbNGrӿ1>;ư{AV E|zfݡ 6Ȱi\axLsÉzlYߓ_:kQ2R.oROE*(\FzDFriS4Kӧ* Owq"c!sc-+mMfgD6Fː~Ms&5v%i8RajgMBPAƦXfs9m1A(U\"r>뀉yM%;8K8P͑r"tU0{pF/39FhS"|{sFjψ><8@NV(Y]|Z 8~:WJR)_}S;^/]G i2.qH{`V>4?sXY~b1YC?>up%rA iЖE2aP1u$ g nBvAJ n{ I w\4ZΟ*7v5ۤebɄwK܁ml# 2ۛNɘCt\{x+P9 i4Ѕ.Xǔٖ|x!oӪilU_8ax4Ǒat2&d܎XsCd~H|.anJ|eZI|Bb{6Y,zAN.|c_g?OB].DG1vu4%T>ĸnQJ)zyr:Pp XN8C$>"h >!&-ɞ=R|\qfm[ KcziQk4wG$GPbiiS$c̦gpQ.9IJG>v"=%o|~χyԻ3)Psp#fϟ;DP$-ʹhK۬iСS94Y?Nt ަ $DG2-қ ƶJFGb&fi9')gZcxBb^ssq{$Ӈ~?"'?۠%v2muY| ֥ #2fP*1M4[ƐgŴۚOFٗ~KFrv]Dqv1%ח ~d`Ξɤ2z)3*0K/lA|Se1V\`Ŝv(ny6'Ӹe ch?qƉL. !zU$., ~6~@KñE(Ƭ g#91r&`!_FEI/.Q|QjZGZ~pxa9}s>/1i}x>ɕg2yadM eu =X5ρ<G,ѺfIGVYגC8z Uz^) 3i#|k8飭M4`KO 'xk<{1oV:+-0ݗ|9̅I-0) h/'RR>11g4NnB,ھpgFrjF@^,<߂察z 팃bKxDʹSI;~I/Ii{LƋwvzҷ?B(M:U3iW:\x.\My+Yb@<~7[rY_iǏɭ&7\S"y!ו/vῼǩ͖48os.gw9ZWVa։㙞\I5<ba8!QKVG=y\mgq7e@&1(.7mp~:IhVq13JI:VİT ֟<5W쬩'FWGK>?vf](4Meq]]nmwrw?ќKAp %$.b,zƞaZ[wϔ(=NhV#U<~Q}8(.3T :uP C>Lk|W{3[3aXjsat96RL!\RpB>[ u{/#Q%])J$RVAgn\8ɆmA?6 NT.fk:jK<Ʉ|u-u2WxPn̬<}]kI޾H?Ĭw fTK9bhIr̈́ 򙠎Ogfi5*\V.|CVJЍ-sɘcYv,Ʋ>4 11wQlƵ`#cBAAlj A'R_0r#U)/QmJޣݛݹߌ[1PZ h&?{wfKyᬽcB9yRߓ +vjSsq_[᧥Er2f"{.Kf]}eS˼.ufW><ޓ2~Tbd w .:2 xŇ-=ߕc]H F)ϺY:Btu9cNyB 5/tŵr;g_k/T" sDLI}XT_J2J2M(G&_n'zYN֘C e[cTiK?|:r=VLSP{pb2ze Hp_|Q3vw,Y᜴GyuGy?ݫroN"w4wNb {7:ۺbs ]=KWeiV{%Wq+"`DKBЧWcl:mj(5fnU+]\3cwǪQv-t[a||)-iTݣʬ}eDOq6eb8"š! o3StIKImrr4o|t3Y}/ɶ<䶷Xdgu{+)T:|wz O[)h[}4*3=KԺ R;;lغ۸ط j*vHȼo9v_%E!Mŧc)ۆUaD1V]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAs.Ō қQF)4r&7eW~r:l9*Eok/H_w.U#yrԪ:٣yғR.k)|{Icߤ?5KE꟱Go7Jޥ03ϽCA>K2|sOwIu)-dWM{oy͓U_2zhsAO\t1||ZpŗFFL{e3)Bş+*țFM%tosY9IsAg0l["Ve;clvW¨r;rMbW]lKLH@g:̨Wn%=zȓ"w7d/9s#k5)?Єs)j_rA|Cr4+g"~#o;ξXfwٶۚ#Ukrٹ;,NTq6-y:lg=t˕7\#9Fmw5n/?9Z`pL3MC~)њ}#1kTN3j#P3*If_u%(,SϒZ R;nXH?U+>h)/ʳrzoKęvahs!=q^c{HDڹROȠ0:DcH)wʻȗ]oʳ<ɱׯE+NJnʯ绡l {NZ91|3ÿ/Q[:n+O?r6V^CoDb_\nƱk@*L )-ݚ7/9|q+Tc| eH`L3rPNwg;塶L+2 (}ds0T\u` RFDr Nמxh؝$:Ƴw &hC~[m~kr])j?7?+׺8s@76=A3:c͕~3y]YƖ\>ӱQ|C} 1yўH ֧ڿß`9=n ⷆ?ΰJYtACynmo[8!Ћ Y՝=-дύݰOIUjᛟ䅛ec| sS_%ǥ+uX%Z| 'oپFz *Tc7i'p#iCZ̛,/p@$6mjh5V:h["?rhA/ fJCU¿5棜hNlՖqnݟڡNfoX/T}Ԟdbj> a/EW;ÕGܸ_;-6*tsCa}4NDSurǬ/0tGWm $,pA.*s//\n!3npHqOOb2e-o4 7{&o"nJ1@ԥ|́͋fU`ru5ϛdKΛ&7i>ŭK šst+gvc^|P:85BN.6f(cϴ '6jÈYj,6ˎh_nK֧l5u]:(̾L4MFR+]9BS*{[&6tne#oiHxGZ1!/c5vѼnQ},iۓ@ï\=S9Kaў7XnL{lJ/{)43ǹ^ OZdPIA[?vϾiʳ[ݔΡq~rzOr˧ Y.$:sC23yrR+{:)ܙk˜8Xt~$O9ǟW]B%G&.A襪pZ!e8x+ܙbu47a_꼶lOF ,߄h?g] -=/qE;gK]y8˂wK '!#̘ܚkiI%qVr\87*娉!*۹0L3X=]+okm}K2;Pʡ~Vl4UFE+̙7fȹHFH##$'}R|{UJAKf'+|-m0o.3&=7V% Gh(7K'{Ow+{Wo2;>\~:O\ dbe51ib7+lm͠:syK0Syi>RIó+|(("pnH,><UEPNmcwD6qBe=3dm:5΅ڍ!zfSx '|݅tFTDa6/ =VؑN^k,ZUQl(!B9'- v=Eƒ3fGP4 sɚAdN҇vQlۑGmyf*C6@_:״,8dyI-qd|dl C:tbnDu~5N 逖#MmؔmVF/z٣|*ѡQN Rc>Qac5ËkΌ Aޑo-0'N4.ͥa)lÕL4M/Z0֕)^%G/<z]H;V)*< 8E>3hj*o@u堿[IӁ&E`w;:!XOR詢Ư'Fod3EDyx֗WC5Ma=]z;PgF Z)1%gY`l }_o-aUή2,F`&Fqcńە0y4a{#v.XyQ|Hf6ۏ<|YI^ևm(cJϴGZd&O`r 3C\v9s{\8.gst4ݡΎXzv1#zbyZ4^S,fb-/r^7#0{qjU{}|J8w$ד;?bjv 3ϴk2àtH/{ޔyq)E4闋h"eH %r.ʎe郙٪{[t㻃:-Ք\cZN1abw[BaV⒟Oa>C=* l͎>܏fU#-JhƆ3ΓX'r)TjA D=!҇5 sD~FU8V؞^.یM_9r8m IiRù5<_98A3g1dO (4!4SBbͪ ţLF[[ M=ZkBR6/&10( #N4GoӲ>3>Y.2{`5'+vkZVZHTF:`hI`@*0+k4{3'f)z͕%l"L)-L!ى$q/C~*iJFItxl#sw. bvH +J<'K.w,kKNem{Zkz+b^%r?ELX^J+t t)7&a+lQ[ \W1ڦ)e,- 2n [Q1umRǻ DCyƹ)8=3MY߃MXTkF{ݝ9aJ/9dN,olR-'H.CeoK;}8/>f@8њ|YO1Q1rZF.mɫlLO\=Gu PwӁ"g`p@?vT&+љYfY!FR3/W?[kOlKg)%D{vx3` sjmE &5̨6Pd;WjZU1Y1){J+]pX׺_:wCcN)j+[%.3r 939͆}\wٛ^nLJs6M6 %̾Ȗ"ױmbc) hIB%/ |p GWn:b9r+8[IReKqF2![I>W\|,̔)P :׃]W ŸB8fza 늕6f!l})cύ!棵>EZl'7DszBӊ D f;0 ?2߅9f鑴G\֍N12Wbpnj%pgZ/KKYWTƘ_%h1U*}'q$6ET(иU_5YWκʯe8Ʊatލo' 8O}M nDTM7!q.F;łWhY[`C17c` v_Bpd gkѳEĖYi\OVKXꏦ] zw-t: s;?Rwml})Ԋnj"Fy!q] 4&~CB*O("2'Kx6X+z'Frcy1n0zQwEh/ۢb6ܶ6UUWbpҏp:Ľ|*jX][Zu3Irda'(&p<:8>R~h7VxШ'V87Zv{d~?ِ#> d}4؆ U >gS`ǴLO7|[ɔ8p/S1e5`aN]1er*1kKoأDk-Kw.olsʒxяC(hOϴ`6 Ne\4 =; b #Iܗ7eīs}Gfn"-6}mIQ/dJ#[$?B[k~D+C̙xƖ=ٹ84)gxzrk.s9а'umJQvLlO$2Z@q"+s͖\?^MvǤ΀İaѐMdQJ WN 旪ɨ)&>EkpX+!?/iT.xSف{lkArӊ*2zW>k]x5+Yn- 'u(|?Ϗ} ^;D6epsyȞ:ŗ?-gx4;GR+1@J 9tn>mP'g8Ո/[Շ]ADcr &fs: +o'F0!vSL3ܛcnH{o\ͱ/qTM*:Sɹ$-񧉶04&LNs$υkiEl.{tYilZ߉9P(]9iïXRЋ]9Wb7N33GٙIx1RWӳ>=7誟F1Hs12 `h|MP4w{q+МlA~dL`ҹRf,Z:ZGU=dYZf1x\p9o-Z]Ò9Xs|̤$:h1RO#560~*p)'Ah/ә=HpXfS'?xpD݁=,04挅&y-l[k}_w4 ~{4z?OgagV2% ^' ?&r婓 wY.b_`vfib¹4 (DN_m]İ~9c<*.u\>9<GDbL6˖^vfi|Ku(g(=ʴk:Q`~ KfNU> L@~{ҷ-:*(n򆩑 uؼ4rPymLy͗r?9_?MTBemW[BrCHƇH Iv[ EL]05֏n8&r.ȖD3NJh]_3:dyV_avڗxz/XUaLlVM :.ua_(ǏdƈXq7r$*{hQ8z|Q%<81^ V꽩2Nck\xj-#Dꐤ]znЦɉ^#.XlyͲ:D;7~̃n8v =riiKƋ:S/s{<.#]a4xkBɁF}rF1b`lx9%~;bµ,rOVF2١-2o*aҞ4n 3_0͓CQQrhԫջ2* ϥ9ɓ`F}2&Lɳ]~*gVO֩3y}Q8ս28`DAOfh~ ,RVV&fZ",c9s-F{]qчg1;u{)Aͽfif/ONAN)]l ѿ9rShs~Z݆:9dώ#\߫Pc~\ik#ZCۆ,8oK[UkT_'6G:05 YrQhc+xSPŒ'9PmUƼTky>z"ǡuLҏjFd5ȗ7Oa9X=;1ܒUoz]d@MX *>?Rx-ũlU~.\98ƕ̲woeeuR:^o6?lܧꏼ9I\L4kPq >g`7WERƖ iAJ&`߀()bD<&UEs\Jzg%JYlӋgz=QПݴٳ {+3/1)]/bY[>}r(ZR2-}Ӽ4w'i0.C 7KqgZ:o?'`}5 P&іv~\1mm֮Œ>o4n8=$܁vݳmˍQkHZ G?p>ܙ9;eF^hM`-e0bP;3}yJGFPfa~eMNo^(EBY8#*85tj\&cqu\ײox^Zn|Ѕj6>\9vXc(:eϵv[Pə\vJE$Ea7ч\T׽1[nF~rOr+'5_]Zm!ܔQ^g2?)f[ Rwu:.\O!d_ U,>MoTtZF1|˅ĽjTx[F%K =61a NocfW^<)E'>[CZo`1~dO8Y8ыrS9},'U0`?xp&RM@Y*=|>4?񷜑^׌ ˄3+,aLIӃO0_=B-pwajg5<ߑ7se7ip) p{7?!ˏʜg8K.uXtИ%g(A1+M2bb!,45o`.Nup ecUJl`7Vp{[9U3kۧcl/{a)QGՎͪe۱TD؃ώh8g"7ݗ?<)dJXcV6.W)Ǜb }*h/wtG} ǵq[L[zI|){Y_=+;et*^|QJLT%ƏaYH3D8>>lT5DYXoL!6:ζi$.~LA^5,&s΁XMpEcWÜJ'ŒhXM.Jq< 9ĞsVlNXȮˮ\IV;=M.S⋼䣜'phF[Ya;WdPV]ѡ53Peǘ &eVT=ã>6Dx\A,@bw.eT|9靫YͦoլXKQ:,ɋ)}8&t$@̨I; ܶ9Y7ѥ>.AKzҩM0%Y|7kc[Nsn2yZ\fJ$XIC䅙V"O/MX!!3><2L-4! LU־\ɻ9ˁixd'}Dr'6W,uhlh5ޛߦlǽMda1[N`Rvӌ*XHN|dHe0{1;ĉ_mʁS="0ZZFu--bjvL/\KlqpM`Ku Fz%n5%\ib3I2[ySZ e~zAn^,Z#[B Ze#j)ZǙ)oLԛrĀYrUƔ]n͕X[:0=6e[mm w$j %)fk3*]Зg_|םou:a2:QIkZ.Mr}w PA$E:$$g2sew.w{=c9&8}s] &r֚L@wߊٟa6´\O,bKj,KľME2=(wùwޏTe1< Ld֚X#)3cZYi1p43v/^σgso"|)Дɥœj9Y-+,Mh7.M e;6OIٛn1KW*:er LDT;R덑f) ޥ*=׃8ׅF8|4ӢE?͡zmĭPȽZƋy'`Fy{΅OGX:df1:^Y5RLX'aȇ!tIgG48ME}]13ȸRE vN^WRgv&r`eTrtǐ>LJ{&rrt8kړA~܉jWpV,{(\ɇFe8B> uQ/D*uÔ.ܘBJq4x1j81^tţ8,:AiؑnmwBg7ɼqvx[BX&kYL]T],~ǜd$켁' gb'NkXcݧ\&ލfPRdz8m:~J:E> Maۆ ^IW|=:xcC}7≠ެO2xm&'}Ta糁[!4*w:+f0!Kd~ϣj/T| S0c\ # &E Y5Np0${|p8769` źF&ߛ>r24Ӑ&;1_ޕS>4>է!q.MJF<jp1mF{c})瘇J< ^0 De#Ӓ 9tefF`?IO:C _ndu`w~zD.Mo"F+C~ z˕QFFm76fl菠[j[s_l2̦xr[nƯT nQ9qi voNwJbQa 3xO'%!FipDW:rs?-xv|WF?~.`TܲҨaTrfcJ3-u>P䊊;%JdG9u3Yyd,fݑQ[I]|z4HI/pw?$*]'ه)Ps6Mֶ]73ܕc:35չsb'Ѷa )ۑ~OG{jFDS]VS8X|̳9 Rls@u5j+MɼXMe\^D]RrQwK򩵣TNc{5d 7G3pΩ(xR}_H]k^,2)Fڭ3T{LV9;ѫV"b% ʓ7uU|i$fFա\%lF2pzyC#Ͷ_ 2с ^hg(UKe欋%< EOeݑ]]?;}oגÇʯ9 ?q,l;U=kR8qǐ*v2N+\,23U"G9,+]$MoicM3u}᪅zp}ۉb>r#E2wq`i|'='d?7`vqq= Q-a ݢY;ZÀ`3u/bA6ݎ*xt4)¹LkrR™4*=b֢I$f۞]퇳( fpԙxIEdsJx]1~̡kxXNk1]+Iq!cd#ep)kRAEZGߧ)qtSR@ηoR9ӥyx!F2ДŌiyl1Q.:J\,mӪ0-+ R-/ǚIWX̗&.PJ^c [laSZ]#2gX1̈́0d-1`7Dw䇊ۊR>&a5%%{P>Kbҹg.x- dK8*DZAW G3ׅ=BԢТN}GQ҉'wt4ͦHy߻kFKHٓ1)%sD#ioN'6ZʧZ6f͚vϝΤGwv:HXOv83-#[(kgI}]tT^A̵=ڥ#怞 $ꐜI3VK}e nVouȐU%~)fr$-Dd[/6ڕ]Cĉ#CQ")\:6G\.QHRܿ*p[AwRQwQ1.ȉ|`b:od2ZdKEΖ*N{K!+HK0y12J^}O MMt)KZy<&#?]e{%ܷɒ9[;r20%!C~niQ1®M`ǫP&o/"x첐J'cļ|*r,9K"1U$,= lԈ*]܇-&*u<Ǣ6q{y2KM"w>7[gVlox{DFdbk*_D=f&msz֫s4vOcctKҊ1SDycy:_AtYh"nfI3q&L_md#(H#|n JQ*zWL&%wsb-%g9k^jTO(c7 e;  k Un`E$ Q$W k a IhK^xi+7">Kʚ&lHO~Zފ#u i 6zZIa2bP"90_BjZ 71bdo&3 Ŝ'=-͂q x&YՀb=Ğ3UN!{L/1NV}D2so"ӾsKD=.pSO,QDΦV=)FX,WRBH&:M# +8|S6':*.X2`F6J&} +qɿSqIRlomp :TF1Ri-jy'0[&N&>6ia\+)CJصS6nɂ^ c+Zke_%~}j {n[wQmL(F13FobF?=;j-Fk f;= &-JT:_@R5'sk0!;$:Ps<"+:wi*!<[Ӕ}=;uQ&w'ݎG>Yٓ`l1s_jƭ e| -g@f~03񾞪^zE]w*.ScZԓ-."!4 K NѼ:Wqzk .ײy@J r1ZzW/c:ə&ri?;sY55>NB To3z'sX3Ӧnr* ˦p]IU}KMsxH_p6$T\$}9 E?NK σ9$rPs-c ifIm M,8mhaΧZ&:|qRսy]KOv6*E]IWf4 $}1'F2qB]0zQ&}P^B5XWOI- NR:A$gV=g8o5ܕ84{qaybv`Ȁ1T sV'dGMLu&T7k]\ٕݨȋ aJ!o ĒN M-+K/'fR&B񻜞%5qaCk4gk$1p >  DQ\-䇚ɻbq;YyԂXҳ&1RyfUO&KgƁ~wxZj+#(" QYxw0|'aV}UQ||]|Z|~t.TeO6qrZm:*NlϟF=C9P=&sI GRhHzDjJ<ښCiO)F(q6L-8Z|<3` p"hb=ËDhh$}n&*/ʁ%~.R:J؜kx󬌷X8Bk!41jۍzid>=! [ם*_+a=Z> 5 Ev+d5&%E{d0>bF0kBv ?= h»Vf͑D 㠝G*P#OJ^1W~WkëQtӎ]ːw#XPgVf5)6>$J=e-sR~]{ E KI ЦFs.i:&2t<dR!nY˂יWt>l,^,KT:ks*Ӑ&1q&LW+?*RSFn j{IZG\1Rq5"Hqz8(Yx')J +IV6uLfjc1̦&/6bejyH t5DT] D/Ygo=#.7V+Y*J"'$RDqp G?T Fg) Cjk3R}*k)fh\Z Dtc8@Ӌ}{p2ͳak@2ʿb6\9m}w8tʝVzva}E&H}&FFVӄ]E<^"ђW≠ϱXP€k\*! f<9^B2+U]j!s43i&&20NbʔpWIT̊TC sS:-~dS*󞉳@_GEt{Ra>IZ.hrvrmH6*fqf:mME&}fYݐɉ;),JOsc.e~*+7$P( ScJmFM,E,U+RK wH3jʽV6Xg)RȋٯXg58tawP236KlUq7q>@"ӯv6rLOFͬr KYs@.T͞ nRbb3rC֮"J.ѯ^ tPHә]d)+f|}89w 7R:Sg}c㪂>PǻthU#:՟13B-" Tkӭ$o-MČ2Iʃy)Ƶ$ ěVqC=ljkkXӁZ3݈̘5W{:bF&<4s[}6V(V|ޛ+\+wl\ϲQQk/+0c w3ӆKt_-a+DiT”6~u𺮕JU[ٿb&4h$,р ](fYȪCGTlPm/ZB:L~:AF<) n,G!Nw gz0nG6 gI*lLq87N@"}DNA)v``-3yo z|HS2yi\xEǶNR3@ϲ&2)U)82)\Lnad"I~:VdMw7Wk^JɊZS";`eg3f f>^)r<&2`c0őT""VH n?2OFDz^Ԝ!ˤdI.%8( 3RJF%Y|~s=kۄ;P%^7|-t?Ʃ:$P<(b¾"^Pp:օY}Vϋjz%vl> w tžTIfz_^ΟU_l`#5S~A clSVF7a,R:,gᴸ`nm1l|-:3l+UDglAW\4smJ^hcJRe6BL\?gv$=sik+2r֓n$[%G3 *U'#?&5hQԬbvW%r𗴐r~ }*%PcFL)>tq|Fi|{t T~Gx41[|}N" <5sf’HKL4>v}ȟZ)خ=\J}%Ȅw|n벑7" *3r)\Pȭ<㻳Ut:Nd*KpZScq1O>;X[q/c; "UuF4I)|-Wx#?%+1.̥ g%XJ9?V”"l+bam,h^-6&̙"sh$6~1lYa$QfWe/g jQl {kX3^k&JKhLNF^n#1iDA5SoFfS|/&ph]5d j1+:%.p$3{aZΙ>;B mOtDZ)KY3J{ Bdyי'TS;1Z[aMJ$#&1JjqHsiDLDL"1omd naB?3RdR%/xd̮Ff9uf2rHYeZ0ݗg9"1~$Y( F68{C 5ΎR6T}K~z:t3] g*fY 48j'FG#)} Z猃b9ۢj-7^hTT/sP˻bČ)/*X%'hn{ }j6D%)۔t+>fU G(^Ajr1uR|HáNWRs-ht_sNomŹܫG<%= c vsx5ہPuóau&m$8y5ҸoJYFVN0vLV0BYd)u{8w(i˝J<F{5ݭIoÅ:'9x%T/}!^15HܙA(6 }f02'T/{:TC5/.Z7&AS<-FcBith[ކ5Jv2Ӧil̺hI=+əF6XTV&/rY0Sfl1"H%-$ m^Y7񢚁jtH8"RwZ8{ u\oG7>;av{ޕǻٳ-RȦ v \{]LvqwUb0LL vq5MYGx=)״/)f9.-ZkdP&:x }H `C= LC--bk/D{]Mfg5eI0*(fOT\c^Hog_ e\yyy|<^S2Q5³o "=u톰#ԭB6 Mi6$k ^+8?1lr&u*\EFB= wٰCzT|--j9~CKL-Ϋ54Ҋᱏ84f|J:j\Մ\GW<ثcl=&lSrpwz2a })rҚh~=壘NzJxU?ĉrw,(7ʙ Wt\:|WJ/ffXM˴&27"Ə<>rƻ:yw ar ".V)\>{Cշ6oWBx_!=iemX~0vôjH(%ml)"d(82AW9Ro y9u@dBAt( %*k\Yς:&9~V-ןi /Gr unoT3gk n)=ZCPO57'XMT#rԽs4/QD0Td85Ev Aaڅ]ޓojLm-&P2&;h XwMӷ&u1NG*^W W"a'C?\,>{q'Df=x0ۉf8ѵx"ax:P a薴aʆsjc\`M]nGmgBxvc(xTŨ,yJIfbvS&^FR2 /K>+B*^V̐qeJ10# Tp쇔 +_ŜTK uRqTy]d^FmG Ñ?=v&%ΙPnfƇͽ= \toά 潣ڎTD]32F3ƬmjUe^rnx³8bN_>xlvcyw7~vN,;h%l:I+)hf]Zy:Lb(at= S'zNC8nD3f1BY S t/w@\PhGjD ZYv? ƬB`q=?קUH}ؓ*zdy0̎6}n6c <" r>D(x(Eѯe,/ecrV֗sKʨ_ߐ"ҋeW$Ά5b.N ui%fyE Z8#ݫ 8ֳf \]Mq`J IO |a$p.@D_ V?zv`)7\-h$pn@w6Ԩ͵ 0q^8Pa2=GZPyFvwto8zɟ2| [_1)_hj?z~4CӐ86JDX5'e*:撵G{#}&*F;UbӊG5i&gMLm +ZYli_3Yrg= z-"4ޚ\Zn? vl~4([~PX1ﵰBMm[-R~ȝ})8r_8@F{%ϥϹ;msRP$\J-bpJ Y()ĹG¬Z NG> h]jM{Iɴ9LNj#3Ern9@E\C sZ)Znį.1zzvWPЩQiXHq76MDB"JvE{S4\ߩj}fŬ?nȞ*6gLhLsOGO`T# ڛ,4:aaY3f 󴃒Ui"zA37烈 r s'Fe}tksu=33\zڙ~]f(M8Qd7ߒQ}vD(@YV8<yL!L! [H'ab/QwK-zY_:/זT$F䃣RTc7#Yt߯FFK,)ugZrwd,lpܝfl̝!/-zω<7X&.G)۟MT+m(ev2w.c+.Zi<D;8>d ,Fp/es,tՃsQޥ9kӶ-Ӹ '=}KeV(V ͥ_@hh@݁ Au;GtCo(WO(wbn{.T'վ^K~ױOa[Q}Wl=dyxEGV]s6yl=1Լ4kq s~,Lۼ": Њ4ȴ837.p:t<A5ۃt|k$hcHc(of@*Ku8>=JˬWj.V3&y$͘mupas,67\.<<\Dwc/c̏|O.S)*eaiC Ksx?,r3𜄴2NDHN6(!c<ί̧W5 \n;6YԷ2٦%`%Sn~y5Yjْd[m.:hTDP=('=>W'3ll' ؇}9^UAhf0jooWPS—W6^?:؏V|0}ˇʘ`&W/[4wGӵX}{+ ;9 p9"KU4bGU/X~ӴUR4]u;MYUZiY ]$"lj˟~ȞNǶNh,Yƭi _Ꮋ3Sn n{[ێ/ *sRކmQ3r5c-9R ;4#exy<ӕѱH5ho 9޸ٓPDҫJh:Al?e߿O/(,;).y"N2ħXM])2>Tlun&!;酌'*60pLMD)T{ʁd였@0UObڢ`ݘݘ@^PR>@R#yT#Ak<GWKy4F8~WJ9lEho)e(aaX=߃c=IΜrN2ח'۲=5i''E=7bTL'Z5{w@ d gN 0S:=EIEX86 Ss{'Ci?w A/amڊM3~<AxB ;SZ9 >+߽ә}fdDO'qvᝓv){omN)mJi4sIli033lj1;)339enSfy?VZV߮Z5GTNrzmPpJkm<]J~Rpyqqog#![2rk 6Qfy>F%;p-vC; Qon]0>ȣx8")|yyD8Gm#\sg6xylۈnSN?O.oyU8=w,Q6ĕBG``$ bNXΞs l~S{넍LBC#9y1`9uchcU-g/ &_[QAJ -\^L0=U7avŌl*4L<;$3ʊ`Nϟe7}}6ٝ]Vȡ#jB2Udw$p1iC0OH62l"g?3b^!SZsjn#\K9>,cplkN;su Xzu1){=/IȈ{dFw(bR&1WMk?%';[;>tvamŒ{~Dž }.TgOU`Qj ~hlW=+T$%@E3W6yq3ZǦykF>}yđXW6bs_ͤ,يͭط֞wfd/=?DbNġʁZH Om ޛ'06e#',R[!5&>NY)g 0Œ3Ph8%?p6ǂ^_fl8نd9dFeGd87J "'f `-'oT$Ѱꪊ9 ʨ? B-c&#$K?^}SoqIVøGm N$Q"'bd-exՐmgJs%.vJŌrR2XA;[X򳌘9~'e+f8 '@;&.: bd%5$!! [ bKdq%T4ɬ:L7S$,Fi k40s %L;ɡniTJgT.i(X[sݲ?S{~n7)T L|Y4:)n6. R ͖ :l"Rv n  ЎY6y|<^qx)c5]VNWi),*lZlvUmLa^o;o86`ȷN^W@}9wg-'ܬxQ2,cG7ŒOgb2l9VE[@L ?҉&r)/g%|<##rs ?%vx_ w/˻I]YA D˾91\|F S(Jr6^'ք1-(x/Bޒf UQdb"#t1x|)OM ч|>ˣJY#.l Gy'‹:O2+U4]l4 ˱GŹ 13WR&0 }9a(YOR*ګbDΰEtJ 4]PVALIpgq;2aN ӗJ q,''0?,J8Ni,9ʤ4v.NgS f$SCRR',Nqi:فⲃ0k&Xtf L;mʋ5cُ=:_ӈ>7‡ 8_!XJi DTBbb} *r%W>4utVɽzGU$Sx=l1n@M\k߲LIqn8z=mn1Ëݦl8W&ԄYrKV8:;s{$L^αJ-R]'ΤcuKJ<Du~[qx 'CMp:V<;N"xt; 2wWmIKLJ~.cbh͋FMNAtv1b59r+BYc$E!ncX*LF>J70^M >ᄂU()US]! XHe08/œsg1ҙY\Ş G9xzs%ًYwíØR`%V٥4s.x\1X a7˰QxrsH2l$eQTaWsF\GLSbr_2.H~8zix9ϟN!ųH~Gv4dS#ؾbXljg^?X&C)ٜtg&"N\e,6Vy.e( ät n#ς flZwgzOf<ސ0I.b KM qfJ6o=T^lW;Wd~_+t`k9*dJZ­E:.R omҘ;-41lA}/ Urf(@ɧr|(GѬwel=Qd]-`I8^84Sl:aCSzWOE/Z>$:t} 3ys̼lNbҟ{;6;vGr1}<O2% 9\OLB2p<J[!M!ba[t{<E]VgrĪ,bZĢz9L`oD+X+=p%L4ӱ2bcw0.d:3{Nfkn[5lg1.+3H<A~ܹ>7yڡޑ&2zU+~#\\9ɩIf&cR'9QcrSI|bQ)rX1~{ I t?4;ԋz1f7NtRxi}EN\M)ӊRWľNR,'I(2AѷSpeԔвduWp]LуnOKnSZ̤܍g<(Ţ?9b]_>8wgbt0DUVR}tN8NEk[$vf q?g-ظ7 =K1\Ir{<Ʊ9#KH[/*)8|0*xPkEicDcu|"]!.Ѐ'2)یOL.ey,/oŨY?ȼޕQ¾ ɓ0#{J94z֌9Rr/ e * &eĈ~Xջ~h9R)f32;Kz)-Pvdr*z?hվ-ǶMr Vgv倻)-Q},4b?W1мw&_)ٞ˥5Ÿ͖cvINtf˙?^K( \_" 8ss-W7_m{&`$yӋżkiϏND<$p/ݼi?MȿKP֤18-9G02/wyȍUnX6`r^!sҙmU1DT/A)ߧƜO3 g5$陰Z,<&->\,=JZ{͜3윦$=:=W*9yVG >%j9-SBrNPrDJWN_/k:A]d58vWJq9NQ訥L[Av R%4.?ü>;<)|0WMH0A̔݌k(-m̔ !ƷɿY&F5oGK g1tu a.pfʌ흇2qU;2">K~).S1*Rf سڱTes5GKDW0e}RVѬq!_#̖xVHY#eSl63v&ri[uH{q⇠N),ً2{"-s4*c#JTO Dyx֍Imes˙$\ѷVIzZ|M4,jr JPdF}7k˅}p1ifOɢti ck$CF{q:J9>AvY ^ _CvLȔJ|u ܩA%LjiT˯sTOlqr k\5ߙpOL&m?kr̝ԛzn\DjBn(زMv+*uģQ4 Ab'`KO%7,o)[ޔ6q7HpS8z뿳?C',{bLxT&o5q Lb:ՓQ[% Cjΐ!<ȧ9'iȊ5Vċjj_*>խq|%|~2VC#N<Q̥y>wϦD3'wcFC!BP@س6ۇb6_VMr&Эe-/{"'1r癆 HOQkl yˤp΂_D´BzaPCrf4䵣-$/M?›.3L8ZۇAX?46:CDmFŦm IW:%T;ú{Vf< "Lwټ/Q~1WMȸQ,C Qk1J\x'9_R(Hd$a~p9I*dVB06i42W{4'sD RWe֗-Imzfgw]7Oq?SVRҾvçHvP0s5<{!x- ZUub$fҿ iQ$~eWnJ_ٛks"nIaQahT3~Iz %ܛBhY[ F$)A^ nn$~$&pG,mD/ChEٹʺlly}ǁ> 3 ^ \}8[nN c`bP$ERL,1Nd5g?|l#(|9Oۡomp=2S U1dN5_ejV.-}]+qH9ETb$ljǹGBFL5:,wꨘ\Aqf7X0xnlP=30"-'dL~&ٌ=?}+ |'D&6ٺټLG3ָ2lk=b1C0_Si* 2d*syٜ(K®o+yѶQ 'Fr{<]{aIE<ORE ;%\ԇ>Y|Y 3 cNZj" xrAm{25{m\ȁ@ڴ{g:uqmw:َK\;G2)V^KUvZ/USPfnW{pjgAx7]zM>x[f>ϭuY{cg uo TΏHF2I,c꓂^ރy?Et[&eDj~><.kX&ycIh֏͏ hmbϧ1L0(N{,ijmme|6c\UAO!ږ nej嫧*F^bg5V0W56?TrQ%.RXƹ%, )Na?˹sG*r̨ZvpSA5x7Qrew!2=~1edIL kYwkƳ'W  Kzau Db/>L:KKr ~,r`O#pǾ2FM6zrٞǵBAh mkD1":gÈk #csoC1df.Onkp) ݹ_Rfu/bD!WRcm$='=Rt3o㩗OxL$21 "16 cHdǢ;5BO! dXj$egkjG{\Mz:4v\lٹ4gԠ[ϕ-T.#]ҕ6S\i%Z"TPo4dOJN7VPi{%!.JVu+D9D/qԑ|#,sLu4blDnlef;6 Ek8y^eD.D) >lػxƦ|( Zjڨ!s2ZyInFr_Kh5! \f4 ^Xqj^p&Oh{m agٌN{oO xǐPZM4q1ĸGqW$1B1z?i2z6k 3~6YF2PNr?xwO쮜A2TS Ԙk_K/19y~˷O4n+hf*8_ɼ,Hn6 0_h-S)hHc%aFK87.)ؙƵ|KW-᠉u ^,}#KgeyMeK(n1q7E/ #LB֏`6ʇAi?';ENA@M E ձF'=Hrv-鎵*Ujk-Ƿn 2v=,h3}'LyB[2m?xHzXѝ%ah-=ȳXP*efS( B&$ =dRxRٺlFdqi:sS1)2B4;Q๮nGԬ:@rC'zU"X@|NJeHQc$rB2WƱ.7t#JP2f0.#"*C؈~ My5΀)kj2qf%#sYql<n˅j3YU\s% E6(i']ǏvYjI Psi6j"Z(WǏ1^]E_He J_oKBaBdE&:MaRIXDrRjGJI7H$yj#8]-r5׼` WTT4SJ4t̔_cRש=GI|kɁ|F>Dϲdϡa뚤2x{ ?x;FI͋;DJqD۵u {C>8iؘ͆҅\XƙU:r<& _irw*|SwE9EX^JR׀$!q;._/,^D8]РS7LY8==G} fKcx[27 TMݙg# 0RBJ4ɦۭ jhX;o)ʹKf9 ͕_(5u(ѰHAb>{[DGY[ݖS* 9r#it"_Cy,%@Ajj0F˾H-_5|o=Č7 o6U4ǔ/x6L8+1u 9F;n\@ ʶnoC ? v&ާڞ!ЎyoY~}vdq}~fsǘ?(t?y_!RN0ɟ2TH5)EKKu*ؔ>x=h@w;+MU?>~7ULݨҹ#0Ї}DÒK@4&0OԀ8$Ve"{J xD=C>RsةhaiTsdrN)XFƙlYSqZ1hJVQfrq 汵2[1]Ku2$qWik46QHjCp^g`23qm]L`սt_Ʉؚ͕U1y5 kk\ͫU8TfCUv[|mXCz3*yV B?V8K_<^\ EоvYiIm[,X;alžc5Hg.{ޜYe.Áfz>(u7pgr ˱: yjJƧbL%3)iFNM1v*Ecqy4Sm|Y1(u'w1F`DG>cNaXDfUE7 5N$u-kslNm>fMGlAW\Gy7纣M΍BL©ݿKUkҿ11{b[Y̐r*eL&Zaxy;hE?@!- e[;jw(<p1<ѝ ģi.IKmqt7^wL': 3:^̡rUQ"X7~[ z:mF n6?݄-9'[vNYbq`Omۓ ]tXN\Vq e .g؄濌C8.Bz3BEA8ƜEOIv#"|(=[[va֏ck$6KgP%쮓Ф619>-r$ejJf_P7Ny8(f:#^)9ՁSuu D$GDʶˁl &a0~]BspővZ.Ay,ؖpM,IJ$e_WfZ/ +rؽ1rڨx\a}xS`m fu8GUShG˪=Zxu\z4q݇T_.Edbi#hh;Hx!!AIלz[IJ VRw+kVUQEU쯭{_*f"L\-Mhvx4E;R5Q5쉔s=QTBƱ5U|~>ߕ= rx ~V!n&oJԆOǓIB=~X+b6AY5ZOeCQ_UEd%XڥK| ;XͥZoL_{;3S0&_B .Yp|Pjۚzgs؃'9;>n!և2K\y7Q̺-Xؐ/'r:e3)#6#iu-Av4XI&V'.%+} 㡚q |PqgRoShL,?TZ] *5P쭒LT<8hIO"SJT*)8ѾJx[H˓;)8υ~,N{7ܬIZ5}&bKC:sia̶fK4_&ž-:G(Y ޏnsbgZ!!t Oh6}ctuyAĿBa9څ|x:+Rn.ev}gA$rٓ<~..FI:r:RD2&!!TA;w[p/oqk±0E!mGX4OWi*e3JG.)- ١VF]23O@c=g,2:I#zqT ~}U,X\Ũ.,bҭ[7}S^PUJݕԨ[IIw׍ٸl|Ysޞ̜gLfte#W$D539PnͶVf5,Ȯ*."]g,뤤^c:z PⱡX x;nNioCtsyfio-9\78i+lMY,ЈIo"H ^MǥO[UwC69KJpIMH6-?+~ܸNXf%5Wy>gQؽ2Oon:k2Q^!]MgEitTfa)} ߿IJ1/b:'%Eh {jj ٢Bc55Y7=SÑZffV5ӫҶyj1VbTKZe|U,.uﵜzZK}X^*XÈ;&40lb& sU %'~3 N~NLCN4@tD*ps{~6?+.MV=tB+jbf= yT+߮ǻJ'9 ig}(0 1 v݉61cLh߭io KRU'-c;\&X0!,IH K^ggN}_ɐ[p&ϘȧJ4)\rKD4Uo])-^HQ*c^#dQ-mldlYIWPC\Hn]8?ِ"ePKoJ'ggd3Cl!#G.WСJQb9[V+xd|c4Fxw7!yqnzvR 󦛜RV sx2:8daeͅvG]?)guyi.k)*^Sti5{UޥJU{T}8t.gJ&Wӹ+I-kY7]fur?A\ɢjvGT:^UYfΛĕ7, ZĎ4iCA|U2n~JP/7L{!EEOn[e(<~k~߳PwR[+IEL-b)=LT,y>Nb}r2?Ws{L7f2M~F1'ȝ?Ʒgjń0;s/NX"nI{lZu!dK&]\9:uca,ϯ)!߿hsfOxҙ$`A/|)dw¦o^1gNąlN '1D(^ϓ?n$TÚ\Kpa'_GeZƛQ[ =*sT\aE PrHEp =OaVWDRsts>n21{ĶSYTt0 ,k.s[1GLUr])BM/ü#]]-Ղ2LKo:VM0"0M`m>ͷsȈ."rn!mjsZ+*dp#-E%g11+ "я-e<[!|7 ⻍e-2fJuEt˝]L#%)%* c-A#cH%/6|gK;kgn|˟WBT-tj ^Z8az&GbzZҾUQ𰒗+hcD)~&^> I~<:/o<Ѿ ϤXG 8Wfr=%>ُsk~qrh KpD 3 MC'0dxm(b&d$cCh2XO7L׈5Lhͣ?A5>oh[ h%UH,w(>Tv'6ߋCD;CN0bdې4 ɞl);b<ϦO32OU:fJOJ=t$nB#I1\ɆՁc3l8^]f"cJw;\\/dBd}$&qc)(.tn JUldWEe$)V*[i4O#MR->1G3*凗Nrd\P'hI*.ȓJ# Ř'nm4y.ET غumge)< i:l4ys7ڳ=YS<88h0_Jf$ZF%V{*%0B5B'8c6ct&C FgSK/1CKwsn3>z7)_C1t4D\цo \o3yMy .mH&>)%W Dtk3 }uDr'NQ$eLg^òПf4ѨlIn|:m1cI?"[QdV4jRE%!tM1ܛylt']pH5}6 XߗmR?:jt 0`Mitӄܵ7DWc5vgܹg=.;DSZ3uX'99/J9BN %T*>YT5<;*%&Jc{FeؘKX h&%g)˽JXm7͗0H,ffR'qc6^@b~ܓ긛cSu^FRtu K_BAYij=`ƁfKF7Oip<3ilbh=WUy{w+eQIZv?ݯWҵw>8&jd&%0xYBqû>dvX[Pg'v-s;w^>ۓiyyO9 /:R 0XЬ%+EHYfbg_펋S7lP=smv_$ß21^:Nr5DBˤFj܁s܉ gT>ΓB΄2q&Of~tEMFZOBT;Wpy#߅߂t姨/w7E^<$Xԣu$7GR\RBK0YF9{YbAזҷ*5멸DCH; #U脂 #(b`C5 DdU ^%42zߔqgg)u6J'xB^\Le< |,~^J>u*k =WBQRn װ屒ɹ!c2: &k>AT ܗ6֗u{9+1$lUDaf5WU'ԭb֛J>Ur%Qj;GAK(c8%5|*!Ι[I@I=9qEjRG}]k~"yEU~ 뇫:hsBQݩ|O>q> ~DžyÌ-Npï$EO|B'-s%3b.HXI[-CJ(Fc{p2˺Xy<^-ќx42CͤKˌT#:c = 7 !žlnm} m}*q觨lF3VugѻDN.*N %h~IQɧ2roQ< nih*hM} K VB۔1_Tʔ+'ǩ.1O-C$Z*WJ*L1Wa_͜|,%&b^-B߿T *RrU) e\I-^F)Qv>꓾xu Vس4v"ƅC 3ܟ"JfFΰZ Tpмz+ѭJyLIZ%a; .*gUa3#hhd3o:R¹9x?MgI=MtG֛;!=hі DUK~ז]>ַGd!1F_;1{V9-U6z2"i>%=_;lBA$䉅->iɨntMm.i%t33TX#43@"l2'6 `ѠDsu.Cq!+{ߜʹ^L Lv;Qh 4f@[ǂOW5_W{= 4O@ѝODW4w}:7txhJ3j8z]8S\1?(5Jɫ0jtbB9 Zh`5,jV-wU LO ¤͓ `nge\Rc;9Q2Zrme9#!a`)s#ᎄ'G^ΥetW0첰s.EX)Ƽ$GH^O7oNlMDk78wDX$r(ҝ,/3]ky5g>8v4oFut ,8>kʉ/܏b$,C yj*µ"z^JG%gl)nY$^+o:P~ `t~3hd%^kYNA7jWS纒Nyiv3c[$ե)]6G1#ԭhӾnٝl[4͏dL\#e^r9u 8yD7-uzeZ-3~LøEJ7X(eEs)JBϸ)a K龭M]|D)KJ#jVIhIBۙ *WN5\,xMJ^By >/b>?%|Vn!7ZoN׺yy^i?Z;'811O|Rk0ʤavFcEhryCLquR.]wݙUǖ)&qĞ-3i22smEMb؝f"o~~#?33=VDNAtd%Ay.dYa55l]ȦaHl]ĜB }Uy +c̗3u9=O۲'φ/3)q,Օ8h<\8?1GwS4,Ww6wƹ 6vIWjVrby =g}!ɰfg +ر7ٓhc\=_A,tTf\ՊzBwȇ"^MT=S!?Ţd^'vk>Rqǔ5 e|0]>19?UƇW*R %7Dtغ=k&)]Au>O>Y8/N%rlœ|3l1I&H┵Ṱ;r:ZaO =GXTI?/+{\))+f> KR_SʏR(gh(cTak=ZP%g(RbtrR~Kt6> dQ?83_ @5ӛ2/Vod !ʖc5 ;ci|YHqcx`o,.34H*vU|%h;3s9 6T0{+6Wºry3F8jd'r$&#y4C?0cQ[hswfɪ¤زf> :2 Ief j.'vaj\QaV[ƫel*$ &h7юki˂1LI'43寫L`xZ٘I0yFyM(J`ʅ{`5* Umn.9g' 9َ5ӝvӰNi_D{|z\p}Cz)Y1% '|vwʈ:78qLVMnSV39ږkSFt2%i(W ,=J˾:^R1_eHhOK-չ mҭ Y{hPglLH'WIEq tlΧRǚmZVSt@esk)B'=/TLʠej ;\D:iLŠ-4εqv0 vYSDW5)Gy2~(N0&p~n}1ƑcF= gb󤬊+PƁxvl ݓ=ݏ键c ,h7%3}:8m{>Neq{/G2ez]P,YԨjϙm}Иw{Q ŢTjb0K3YB6h_cUkB[W%, ߅$_%D\O,ayu0yzLJ!4;9'-t$]‡dxDY8oޝ2WV5rgeCO>>`hX c "g/&58y[P.('_;BWv.<0fl+")E$<ςmS(Eb=鮧|bD뤥bYJ/.k]r8y'YlؘEM\.mss/"I1-+ŢRօlU['m!<NȧXLy1[3 p@6<g>,j;as$ڤ^h&ye 1+"x6^? 48@Skhڮ$C: 1m S?((`[G2,9oʍ eַ@vB":i\"юb\3y >,d{|NkeϽ\N T+fQtd2 የיy3WD p_shQ;1sޖK:2lid bLup9kV[ʂvi4K(Vgd@P8EQ͢mDoM[D.)Ӌ;x(ZWFי**C'FJHQ;!8ҡU-f{3ʟV֎:G3iqW02ѝٕEnvNwcĬVi*#/JvG>Οvn5҈I̞iiw sg^{&ޱ_/7|~':tfByPSjuH7ZnN02ǯJ r.-'[W#7qI+继2w#"&4p0{I(b7]l~s6흦s$CpY)\̙Lg3Sh7i@z-'siSDVov4R`bG%W7@鞱;";$rTJ]t:[K\ɞwnnϠ([Dk츝k,>ƒ}*AL)V叢[&Eʚ!3AQmAͦi "R<v]UH\`F~O87/G2vK99B]ouX*Q8TCB*~[nF֍Rк $Y#IY$1D1+V j9ey OQ; qoP?A4HӘ x%^V|Zh r敖ZAͩ N,ߪr9[V2직R$P6!8AgE\hKFMbét$ v3Xu0ƺ4\r# !pD-=y y62i<#驩rBY6/8 $M|HiE9NN$w$p f K1Fx'W¯GGr-*t l1cY' f@Υ[1Xb|*&l \ /=R'f'x'W  Ub(hЅc`ςy%<1y oX>'s[s2hBBcQ]~wa3Yh֥J4`?Om*=l2(#C 7j9Ӽ99E2\`!Z_jeRAu?2lkh2fs4 Y#7_ÚE*Sy\KvE4)c{9{\3(hakZH;&_jfg*˂ՇYC-9Oɹ0@#A Zihx\asG+Nߨ9'|bj~nzOc@z.z 'Iu0{sJ0q3N?yuY#ŠE4Z.5oSN.WNLO5r⣁C̙cx *ntFO =TIR)G4 -r劻%vJ\3?t |ɎSƓMY^-,0B8iuulMݓL[ťެ̺q̶&b̌e=_n;sfDZ(&&HIw Iܝʈ("%Ɔ6hn/c} 3AؿžX\L~J xvi SZg[?~MJwN=~6I;tٚi8Fńߗja]HRbyO0wf"5bwPŇRU|, eZ\91't" 1=a2kZ]::hU1G*TPB-S#C-up1rꦑ1u$ 6hY䨧 )_5*@:*}6;l674;p G%M[p%[>A"l%u9pf (S[Ä:ma_!/MS.IpV6%WUj'diۊ ZɃ$OBH{2sOXsvx ߎ\<LiǏ|?YYRuzh8W{׎Nc숯?vQQthl,"Ӷ r}wb}__"D@ ww]]Aw?ϋjΜg#ק*EHuͤoxfO =ҥ wj|$oͳYFcKxTK)) v/7Ư 7:(vKd/q[Ɏist*`"F.nƩƺlPrكϟ lͣO6ێHƋ+_#8Ro{.Qy!ÞW1Qe,]*YQex/#Ǯ-gV?FLSve0.%=ԟ?\N:K[RJmr^ؗډL]I3rޝ)g@:o(}e>NhucY6Mv45X^Jۅ۹/mTL>O=9n., юRKQ.wB9bH!{6mS1*u.ikDd޼փ_PxqԎW՝iKٞ4Jɑq;Ҫ_vµyaŻDŅb˦ꬮij_ÇNV_c̎$Oq%Q7k9z72%/鬩϶q⼩g룹Ju#DZGnOp.c䷛X\hFJ *?S7J?7rs,Fr45U4#t} W;~YmI;iȗ #Mng udd[ӣ9x:慤,fQ ]=ywN^ۗLV8'L~3P]NbkrnZ=+rmXո%T7*8w"ӡ.J3'm3kY%3@"\ջgaHZ2Y-e3<_J&H}_רwBVea$&cw2B\ ^_b[΅BfExuEJI(:QWϘ9YH4mT'j%#mߋ{wgS}#g8d18v ^)yOԄ8&M$+0i,MGHȪC6~KndGsxүf`UQfmeX%s4QM~fkmT[( kٽ3$q{,;bлDr^2*Of0sN#wW8P[e G-Ȥ<yVhg?ϧR~2ÆcZD# ƾJJj3`V~11xo'ģ癥ͩ` ŔY95WSɩrTbZK9{m H O{Ú4hC? //hI Be>UZJ>e<6q{$4/P.nbN[asCR ӱ>@FvJw=j3>G6rۥp.$Fp [@dg쇢]Mft3}e4secơQ`u.oɉ/,w 0؃j)|B=!])>Ih ?;myt^&|XNnuefqvD;pnǴ(V&lkȝ'R#ͪG뫏fwǨgnsW#up1L=NT=cC7`, }qpU=W {@̬@ YD,цRv8xWN)[8YμIh̫`߬2}4~ dA*RYfIr^̬NhwPv|YJA4SFnfkĒܙ0kvU#~d qZ2{tE}T΅ <UN<楡lp H>iV6:jV|$pG?+Y=ݖ6}ɝt|ޘG=` X׉ InfW-?*_>8D!wXև Q]jAoLZ2#欟ȪwNuvF6ubgy|]Auv+97"K!%Wl9u՝>oR3jqSԳLh;Fu*UuRn>(:Yyi5Ktv ơl_-Ud{]rܑӝ9QMehZErmM3tOVO>L7Ss+XږZ3Ӗ.< Cusj~-TQ|Уx`բ ;R%v-Y);okMţ%-Y:]pˍ8:_$6f/g8=ЬmF3FDv2j8/MQe梡;jͳZyELPȥuhkpv.1u؜-9ʯRwy;*XrOQer<)qT"K*ڠDOhF1v4nd{7P m|(#ݧe1ZB4ixWaCP3_&sJxX} ֞10*S]T}wRrzb4,#v%.̓ōIR70Q3h۹$%kkrEY$͘1Na{_U0с Xs#$}Z6 J= Կ#8F=˩Tɚ4*Y.gGj "j%jqQ+úO?.h;znd ->"jx "3Mf# o\^Coki8#zKQ^Mo1om"E?,LL[8.%gE{U;x70AI~&F8/eg;q4ܝ!>,J#Y}|Т+r@w~z-M/P5#mFj 7ñԖ8lƮ|M?w XÖ1p8;R{~|d 3X8:qgݡ$aQ;!G`P·vTinΟNH -Be9q=V$6!\ktϕg_<Fnj7r].zZ = t1rBl`EEM&& Z1JQʪkP?unn[V$~o+[PSÓN,dӬXL4{B{Qˇڎ FܜLYmOa\]cSLS> _)-|uсCwm0PQHptByzxSh̀<8@Rڄ+4l0K+YocKH!UŜJ+Ӱ%X(!Z0!Qj`].2&pVWJEcǓ3Cܑƌ+MMHt_-zwp\pphJ^*toM;K){L61X>KbebL&l;C:۝ e!<::s^#c)TXB-z9ߞ٦LhkTStPmZs$FEYĻyA(<τ)%EBV V߮=x%ڇ֗}x+̏zoJn =CQJ]J݅H+E΍J _<)lavrO AYWP>ΔўB ozD=Nm_ . 7\S5? |etBEo:nc\9JzW|'3eZD,DS}]>,Hoh_ &5i1V@48OwR= ܀h/]|Z῵6d-$eN!3_9JOS)hAY).1;9\gÃ&@Og8bξz /T mF6 ~Rfz?ڠYPGϙ/.f.}vt0g\ aE'vh7b;;x=K)9;Q5+|h8! Ь*Sy?ڸ9LVLaSlɘy :׎zj Gcb<(fB&eo8B/Jk;x΀ ׊=sX`CJlszaY Ǩ)kG/N1 #998_K(wy鿌ߋoW+Q嘵bEa wl}U1JGS#v޷a5;A8ҏSbY. x~6~E@Z uN{ݱ##ZaVss?dG`v. cznv2Ms);J,Қ=tx?l>hu- ΁Q?s-4؆)Oc1{K_x3v}h,Dw!?_{qi/sqi{zd!]5c=n0€"׮&<2auƙr"-f8KNXr=Ɵ3o2!)wB$'mߪl{w:ik`- AmIxL`_^aĺbaWK2LgݕxFqE!L ;zJWF,PK+ESJxXf}枪OL{3e#R~%W)_{xh[ї-)ps/7'M9G ZLY|j(5 ֟5$D#=X~C`RݒռhLC{>]0VRRj`}}31oL~x ;ڑ!;) VpA $^*g'3$̬XVu~ nzɹ/3y'Jl811HSZ͈.}m:Ukݘ?݁k+{L{VlҤ@l{{Y,85 CKXKeXrfHbDa$y!6C;nް"k9[XQ͙과1P_"8ʛLH6 Ͱ'zWx>ͅ[.|kˆh- ;7܎sz5O;kn{)^?=嬗$'TWQJLD1Ѽ8یnӎ)Xӌê^N})\-zf}pn%+9; &}(r=Ǐ$QtOɋnxta[ޘ3j)4!~\dHVCٻO{p/ԧMobLh۞6,??;4żX8s[{\| /R)-=NLuVڗ)/ :<&+էCiw*/cQtc zO&dž:Pсrbj+:1 S_+/]υ8ŞKn&53/Eը"qn1jBtq:#H6E\Lt)lۡ?l +eu-z^휤SYZ1Z1Y5R'd@kqFO۷&Q75`g>-ql}?#NTw:;EbܢݴJrLIרbL1Uv?Qr%nevīX$#ɱ'16j[Οmbb-1很qUd:(gv廞V2e k>1fWgB[>cOmo|o/.vmbxkWW s:rĕCCNʱ@"{[mΛ:ńV9בNV͎ޚm"Wʹ1ݎ|mΕV;Ո0$!J(^,>LOv>T<إTۤ ,?_Ck(lR[na|iND^S[*p ̴ӧ/*.zX;CB85ÀvjXьD5C]*6]RP3RfG5[ׅoSn bH7 ¸)7/Zjr>g|{Y67". zэr&; [{qa/yoG;;17A,:o5G: ZǕX[ľoՕUJ)Mׯ[Q3V_9|=R?jŜ)'*f7quxwvNl_'Џ|ͮX@ɖك[MyF VD0[պ/ZhSW۲k!8=z0muGfW 3Gے_ߑl5ʱ5؇(O0[靉lem+zeSvƻ56&u'2=xf˧pvG3rT:=d^.XOtdp.7EW7 TS`5Q&NlF@[Bq*qXʧ<Ԍ{u~1iw[;3rr=z-L:@9/|Sӝ:ڛ R Cxg(`4Jbj-YQy'Xjf%a<@x\z3'u,VÎ[yjӑZ9̻b]TbóB:e {- *kq]0: ̷ّQ̰!܆ GeAXv0Դ`Mhf~իv[_c2o'<6AU㵁Ge. mjuup8;hC6d/Le]Rtl?w5kFw ?zT,2qǣq~#m1LoH99G٧8~*-;%i.Kj8:?F. nw'R_f+6T4iui *{ Td#55 زŏyzQFesRFV2=V޲9Oξ|O˝V<9 0pWNᎷ]QŒ܈H#zf&,ʣHGT9cztk8&A{4[re-O%Fzd@xw^ӔMn|1 e_p`1&b6m2[%gU`iezl |($)Fc q·H$N|&~uV[m,8#终>JU6w$^ĵ̅N};$f*A4Cԑ[*6y4Gә"3;-츲ŏVq2Cq 97T P#mC͸n,9ڍ_Iν9.{Sn0-Z1h1а`Y=%ql̏= µMt<[%>VXeIR1xF']bJXhCufl'3sb>LHMŎC͛i$O C~]6Gpx历e(v޶qu`}6%+3PIP=-| ؿ+'d'lkb}W4~tӯf 9XYR)^^Wzȗ ~@2nz_e8b{N3=x.<1vcs>%3b".D_]\*i+9?&i4۔_6R1 &c;0XǽZf 腇g8M猢*>)43JI} 7wu#6gƫ mÓ[]g5md䛓hr?!7f4e;~y0z/v*ޭPwwWZJ wwwwwIp1Sww/uw}{}~owuZUƌ{aʹ&5< Fc;Dx/b[`4Eb&NV>e2ZLU>lFk-Vx1s)׶,^%e NX JͣWS5 opg76&k 3ޅ XGD/McQf#i.d~!2ao# sߖּ-ug`&6$Gl.$b2P $'.ẙ)Ѿ3懍:O=Q\]c&laWi4d3/9026^Ĭfт^bKX mo_*D03=1Z6L`KS;D`] =г ( k;3b}JiK?y{/Gxr5*q f'#fӢb+c>污3Tq\LJX# ;(.!cv,E2©T1Dw(,;r?˸ItY?]M\:WmQMa)]ӱtc ́ãxBjR z-n^2uq2"W ݀)8W0ߣX̘AXQn[yw {9Oص4gl%m涿*Q`I<[tqhJPẼà Z.x,N&fhҁ;L8}͜2ÕGV݄~޲X۞0ׄ):N[2vyCT f#_Xp*]MFUt͑;VȺ/@MT}+3@DD=7{.g~5?wR`9.>nϋ4-!D&{||ʇ9xaƊ<@#f0_~ w]m7sڝō'\pk "A1 {pR>ydoJť9>|2C :zSR4 RUrhX9)cWW {<^FOm*im]d~1mtYFiD #Ӟ]^WUAεD]!TC`O0o-;9cXV]8Ƈ {S=4ƙG̑r6܇Ќ-6OWc ߾:#=ĉA⇑Oi3b:筡Z_. 8V+3K5_mxŀ5l5PK4j,4Fˈ͖lxc؅"b9Sѯm:DL$}g3:< .ϥbں1lV^8p˽|ߙfLB=B]oMQ l|ĤH)a?cT%`g |YoACS/#zSE2T2z #acD}g9Ycb#E>+ ^ڗ>\/k>51ڒe{YbD)34n0%k%qT"5r*ϬL^52[ⶸѻ'n:m9Vdk2cI <˺iˢKi_N"w(>;B'sJN!Em,WG8gI Wv/N{1z .fc"%1;C͋yY̞b*x1mӰ<ϫXSy]_}1?ٚk3zxcBG0tJxU ߭rb3YXˢ%VTcV5^Ҫ{"W2ݑn> L!t+e?31.}fjѫn-'R`Qؾ,|b\/>3vGQ!/D}]d|0GLc9L,϶M<˧$M gyNnLMć?SaY1kٰ mE:an)=R{fVX6)еg/>u'#> \ΉQT*Y#]co4hpuVmj,<r'FU-^4_E47"3t'8n49:ݑܸן#X !n$a,xװw,)Oж^+i6tT!c9?#bc_\Jhõt9gV:&Gsap҃l1`x {ݸU4T&t">/)]+)Ə+}QRfh2FMrfd9fSg%g)1>US u\uƲ)"5ߌ2Ѕ'(308p>Ys*m-O{.z1l4`_ƗNlERybpLoy\ẂE̹ʷl2:g8-f؝ Q,"0\ 3?L@'6vXӐ,nC9h|clS? ByCwdFOu*جfZőWG·;x{gGbiޓ‡ۃ(D.a7~$&1$͞m\H4qfWﺳ9Ε]8na\rDԼTjtfmm5 v*Yoswڳ7 MMIytBڑgvvg`F=?)ΈDž6CBovBTSe t׊ȸv_ޛEloAse eĪ1BBR ǰ#X My؋qS]O|<ח?. eCnF[aJ6п?PYt ;Op1N;F.nhW9:L‰?H`t"gfe>ue.'j"B7nq>5K{RzrϒX= N3:=~&j!k ap֓xvߏn.\-8)U4D:n8Xҁ^|8bkN&0CQ?Tai9If<37fWfN$nS~NFMN |w.jvEk&7mvOrQQbČ"{MVC!|iH'?.l|]jG;Dº;yk[ vDW2ae'XwZʜ2d8'ùSqB<%X _#vqdCYΈem5Y6` {0fm.%i$ 1Wsׄ0ִNud&[.&jS< Ȗf0 Ѹ"_{0e'5Q,v 4Yu"qMzf:3ys;imRlܗĝ~盕 W\ZOE C%KV4ٟ<r4zs0M_!sѣ.Ϛ^,%d6W֫;Sy{YŚ.5SΩ!2# U Bngs6?GHUUD4Ēeɹ#ا8[;xsmg"\412`2.@938wG[Gc2&+cil>c&n\&`DkDl9gB? p0COO[& N4D!,E :k?ləvl 9;ri-/<.' ,ma%KVg_MY5V3p2vXZ@S 혜?ȪNe'Nxt[n@)`BS8P^M0_BXt(s~&{ &JGo86('MDM֭% No6vL 2Sqc:2v4SHќLM5D3؈Ӹ;c_vaHL-u_`obEhzhVӢĄLڜ"4d<'Vgd5T AY~R޴qr/sj9z@ͯM/92G.,j)Mh| gyp:\}:+M<( ܎Xe7jðRx3x3D_]u==sx_/*e'5DS3ÛSYŤ+lNҌ iܓ@`zr#&ĘW ,z?6 ";*=#58 M-J):Ӎ?"O| g둽ӄ[˧^h{SWC`Y,]2xp/eJ$ŬH`f 88̌D(`9qYsN "7։=|ŻA9KAr5#ǹԁ$xM#1\3impqv`{,ߖsl=Aoj+h7r|1Xq\ą&|4''Q=YxXOn"z0cRE,< * ~L洿ovh9t+!ҷ ʹ+HQ͹yRf; QTK Z*w؟.e|Bz[4&ڰ{B79Ǔ.TKLh`+Nj7"~aQ=Q?|ox^z@[ R&rQ;R%gwd_yNWB~,}2R̒8:FT0il^~ՄyyXYsAjư+TծW83l #iQwͶ_E[>b_C4p2>PdiFVsVh,⽃6Ǣ6n NDK,O"\SiƎq * yq"Y}Sڽy.-b(!+Lb*uRܫ+d$䑌Zd+9;12Ύ~8mE9FGϦ$\YkɥæJn bG8tg`0XL6ޠOe6XĘ#E KeBMMf,V.cT=x<- F(̾J{!CGpɈU06 nd+X$EQ#/|XLNz:>] 1֮ɜ Tܘ`o^m÷zW ݦttRf.eI-\jSRDErIb\hu}H͓(& 8UK%UžE-ӂ})~NyPs,MưL~~Nnod,&ϰi[FJ)^Ź:vIg-9!&0\KN]ޞfx0j%"mG KM-u vib`@&5]K76yՀQE+ǻ&59UA R®T{u-d)]$pmw ٟQ; r-)Q,V>׊UnFOCp=SxYyhP@m+dNYgM^7¯`sgB]hُFvL ]gkJ"c,8Gi{-dt2fUpwz)Es8OeS8my) ؝Fl ]JA9p͇{}PE!V8F4QR'zvrm.dׇi|_,xgΧtw9F|XʹZRHאCQ8y Veg@*ZBWI ft)rc}QCvk*W'!I=~ QZ47Krʂ07pa5gܻMђ0>,BdejNjȈzf|>j{\i̛ /heN藛s˜d LdNX&:瀻ХTXrXߴ8kcrz0gMy `ݚ6UײQ-9eL<)CsZ2<ڨRҺ95,DrXwڤS^27fJDƤ0b=錚6t艬 f#18P#/?wd6 7LZɔ{Qɧ2f8w!;C<`Y?SM|G#N/o6BDGL nI= ND((x X ?P}-ҁdz-H;„iLjجضcs E<D$^ع%+})uBUcYƟ9n'ןNKMP38tY ,Nzr(N1|(#;":jCXkNˉ'x6틱:l ȕ>XQY`C-6e,צQtр8tFq!(Hmχ.lHs 96\q 58a83wF>Vbl9R kdeO #C)MΧϰ*+Q)âMD- lXFaaXG7տχUX {7iKLmڃ"Ay7oW9@qiJ{K1B YLHgln pDMʅ#%N'!K=PlIS'vٍd< :`ƯZMVm3wI K|.-ZI4c$zwS'O{ѽgze; J$Z= O^ teJߜEt7~otcT?591?E.oˑA|H_5Y9+"O)0W+9Qɷ LuW*9Sry5QƠ -XE fņETAQhg1ڡB%o5vc8п?h3ƖKyvۇa UhOJfÀ4"h.+ (l.y" CiʢFw1}s/geirsG%݆:,,>IDm[*lJn̋@GGwT8׆"EeG':QʼndKMЋ> +FurjUJqJjuԭӷ']U01C.Ϯru7[cha7}RO{.?>Ff ]/ `:ф>IV$ODz5F~b5¬'ɜ"0aPyDJz:OiQCl =[B?rla4Ih]2"8c)禽mLI5wqD52!4 UCZz*!dաRd">0a-ɣr)߻I<<Ëy[6]Jҥ{5~~в&}cPE1Yr0V_hQ2l7vZFWua7/ ^R6HK-8avFX+2K+ޫe)XVIv6-[NVr'e˹*ەsP…_1z+Y;Oʗ|{jf{js:Աbl%C%+1@fVަ`x۾-*QBd'd٫`l+z`'08[2;;%ſI%4yڮR.K]}U:eMa,~ɡ_v9yE1)XU-:u8G E>_ZTfg'&EsgS,>jYzVZ7$uP8Rѭހ$XTn׆)䷋g?U+ps}&tЖ#\/Q0SR РRWk(أk-J:IK4i5,Yw *yPxF|/" ҆MTśO_I`"KG $q)ɧ $)DQcE!s7]3m#[S?+7w Zʸ8 *T{ 7ռawwBmc<),T1RN熬*JUaµ]2Y=wƨAɧ4}KnVדJܗ)8ZN9*hVNe9F|5Nj\JXV]˹}vlUsF]ssR%r? #O|c;_-^ Z=Ѩۜ \%Y8I-PjZ7a^dlӌ2!ټXYR"kF%*aݏ|?_R ̯_ϛH#]/WK'EAxq` ~@J|J 9{jIWIyq**&$g6eАu^P2d]ۛ38P<#ԝCIs͏o3va=9rfkaM6H&$=]Tzj \Qn= h&ٜː|;>yb \GK۴$bG$*C'N$f:?R"Qyfs+ R/oo%or(j0-T 0sԑ= r{U8Uaײ:^Ա馒'6VU}{;eJ ܒLt fLW)ZBRMaP53n ]-.8:ll,BL!f[k7Ҵ͗ (9$tYP@QHa-=[ӏ}w@8KOKg;Du"ZWBWo51{KyR,w sb[1+'눑!WzZzIx7r BnKh`֒zhY`9ϯPbWΉ2cf 4dWrup_`uGeܮ&w%_Vgx 5J qe LY?VӳSinl>RByy1o _bjb,JUJnǠicUbsiÉ20~hOW=SSBT뤡Nc3{%Eb<)٬rK%_å湯# cP, #y=}IPG)* w1mdzY=р8VE+%$|QM'rtQpXEW ܕ\ϐz}JUV Щgg}/eD_Ҟz܁hg]QwkUjNdۑjYc*1Y(:~x*hFĩq ?v]`N6t`No Vmb?đmۓ:daQo`o;ɉ>Tßf,iqn v*%_')rUɿJ˄ׯdY qd|`* _Vx=F s$g̵_.9Lj[-VT]gxcم vfR Vҩw2x(oQfB^&O_nbnV}e ‹&~ G=9\hK6.n|-vI(H,̇hI\d%~lO-aGPpb_ sbCQ|qOw9~Ď t'3+ؖZL=X_Gܽz|mr#cZ4pwճ@ɣJף]G0;>z sYuUl)kyF|'ccSύT m,Q1AןTEIA-(pʙ786p^o$J/ +]*(GCBX9-,&:LR✤Y:בTfs)驥lp,,`"9;r,myQ"%ݣDTL%\szɂZvSjUͥ>ev9Kbڌ/{\qO>,%A̠bjwWu92Sz5bLNNfaz22)aÝqXOģ>8 ɣuOG"&$3Ӹ(QĜT)x@-K(K{[KaJ^]ݼ>aJ^y )VM <%|ኰIWQ%d)fcg%A|29v|\Ĺբ0%ss[Kp;~#h|![|c'U(gCrDBF Y|F[/1s(}οiEpKq϶x+2fE| jY}RBG}0>Tbﭿ껾zN݅ m;E,nEKq[prUξs[WFbgΝ'w<3] 9JoT_ WcUٟUr+I2GGMBwܗT14buv5U1Nt*I%՗4\-:hjvUѷ*8`V"_+G*>Q$IT\y]K/ UDR%:N<2/Q)}4J.cb,-r+ǫ-ˑ+gYCJP1w>+ I<7uЎe]qx4U`~"Ō>MHb`h"?Qr *q&"kūs?'_ɴ BLWbŦ²߮msK'uf(CEV~B: =}PR>&~Db]u9%J`hN8J8qTf,VRXMK͟Tu_Cӓt[)v%jtLWfb_k?力EWVWj= o6}ؿU\YAJީmN5뵫Jtq ;&)]_3T8^Q6YIT*.Lx{㚫flr~y9D! 2c" ޥ\Tel.8%9+esp+n`l1ʙEF}26|Q[ٛJ "sKX2ģKb*}) bRZ,.aN╡D?GA辎פlTX Kt_M-)Gה0C1 q4QFrK9<@ʙ%:PL2ʐɉBI05sd_es](6. xz#9uN-!YxBOqkڥkXg*9SCqF"/SBl-⮖O3q41ЂXϠE2A@4'VnZ3?' D_e{7|h^ݹAh0[SL̞O_SH(kgi3Ú&?Fµ>|V1hK_'f~=9·=n:-/ }k)}s3/Uѵ}%q*6I&vJUrEЦTl S!kKES!5$JP 8RKm%tʑQ!vLSJ.Ck˶:oО[:ww? "z7Z<8橤tO1֢)th&]RJ.J9#_V )l':RsgM!aÊ[%:|F/Y1[S2>?Rz[FaR:ecl[Nj RJIy[FXd%*W:x8IRnSxD$,)"#q̋W|{C5a- y?t'qck6uNI6ד7ywu&r^Zūs>j Eu ui r#y0[o pn2S~OPuwdj(Zأ;l xډm2|"[?kvv;6+>ܨL譱I_M]}X/ʝuJK|;tZ;M kQ.Oŵk]M~^%sTqDJ^ mJd c*ThD&yolyڏoӾ 7Ҏ C Mv ]7 [7u и9ܥO%Uvn:#^vWCRm_֮Hi#q|>yRf%~%lmPFr:=)!ͼ%|+B3 x"*AZ_M,/auen4k`~[%>Dn$gLe6TPn#2)moAUR*S\b Rs}/nQ9!!-|d`MX DFzip +&6t`ۖ"|:ۆ ̯'L j ` ]SKZ>O7Ӯ7MSx`ōDwCVdц`= ̿@7Vq(h)ݍ9]aʐRG;6ׂJ>cg/˒x쥐2Pk.3;B)ա-\.fE3-,8g zZ6PzӏMe^A6E3TʱJlXuMq+GL5Qj"|ߝ]^5X[J>DT0t2;am3XHՓ/ ݅ɜՂrRYBYB{ Ik]&N7::yށ(g+\'cF9Nvż~VV)󻬄Vl)fMd!1,$Jg BFRPFYPWRYt:RRl-㎘-hY,I21wp9)"W-Id fPkWAReKӹuXP٦RzfM!YD.K$ B1.WD6ctoxS߈Z,LC:-*VSnN5~vf4#ئvlU3]Op8`覜iJ'rSKo*Wxc(1s^f5-sJ9[i v@M0 gW;QuNH`jj SC jT`DRn}."\N^40L'A x=*f6+<5GP<÷ &O}t:O(葍Ko(q4&tx> EV:v%W1'xQ\H?䅌Zģ>,P\B'CstB:4OB^TŘaسJ[W4w)qd-fy ]qG99YdG*/P1eqmAxk\$z[4kz_<>tbd*m»k yhKGr)P7RɼZq{j^FHS[PO+baLiF[bcNf|DV{䀹8P:`Ȓm0fF{?I6CWhbԢB57<`qɇJ!ifwԊ뭙nOghOatQ MN~E,fWd79*_9{ZZ3ſS㱧;*Yta4S^r; ED &Ѻ Mxs&CoZ_3#:`lVkt@Muc+||Bݗ_Miԥ\N0-$sao>3Q1s=lZe\ ek$\@je'))% ݊A2j02-TIVr魊S5SC1$< IhnM0jQ>Ó|ԛ). Iw+*,UUHL*2酕\SĨeG + i(w9=2~]vVޚHf\oEzZ6ed ;LpN8#N 3߿r?=HFj|[&< k.|l{kŲQm?-@(p[F\_=;Γ 2kLe8ӕ<(t<V+{:n'O:eidB[\UBCl亩{BI3JFMSiCbU$)AEq6+|M4Ѡ;^%KDz 4taC/BMϙk9>'˴D+vnOL8Уp§a:x"'%ciO"o@1CE-gn!l {HEayL?(al?\ -% sd.-)"Lb zaѫy%|p,%\c]E9SWFL9;X_V.BdٜDL*A|G1zˇMa,-e/ 5fTsP5k5z5\|RIKt[͡G"3iQ?nA;m-r͎-l]NM:_Ov)q$G~'|!reUFr9ː>j (aIظ7isFdzS % 2VqTg]%*9'2ԉrHSb2g&rb1<&ںKH;WN2,9Xcm/$QUM6525; +*4& XO9Wsk):E؄qsSCyuc,۲qIY_wBy,21o-η RϦ! I <)lJLsOWL2$9< H-:fY m3|ATf7N$NIR'/3>tMAO0sWmi6Yv`tcXH?n$~ {.?pop)sgSslg_R+6fEJ^4KC ~o*F4\{!y֓9ִNPy'ڡ14xiT=p z#I{kk"C9=wW<(%;9"gފ3Oy1:E 9i0R;$i ;73k"5bAkO(M[o}_ʈc^:L5S`gL@T49$Zp34D]N U_8(FzEWJߑӪ)0+`[bNĠkWsM$yi䋹(Rx&mχbNPξO" RsT" [ۚA+\X>(]Ro09NO9+*#jj!dHs*C{pyȥrNg I`Hh^UE6_xgngk h) i$4vOO!wil9JLi,INg b^'Gf)P` WM뿄E'>mOOs;':-sTYtJK8)u#v*E\Kw\$22RxVRnU}fe>rY5Բy ^Ck3F ڴom6 {>{,xĉ876asLEbY]wXLh:_JӉxؗ[DKIIY X]ѼFAҵF{ u>]l3#p_xXb__$ oj#~mc!ucouƶdY/,CQ;D0>,"nA9aWTɛj8K*XqMt% 4,Eq~K%,fsOw/iؘx>I'紴AŴVB9>+1W5 T,&z>*d#UX*SIʢ_Rbctc%BR37/11\p aṗӰi2z]Jf[a$ ?4H\휃 n2[Š)|3] KR8819H?Hb[,uKP=ۦq"IGHwnX2淄5AW'BEˆԹ BAF¸ޟ]uf;_()4t]ŖU_QIF{VEgjөcwZ+`yQvq1cf"wu䌻7+A|8Hl7on:a͋),d.>{yGAr=K]^ܳ2~(KeS%8 2ɴ<+Sp!c"{90#S{gq}GNB=2LH EE08xr)08r1ngV4$9(bVvUj RkAtL B CJ^u ߗ kSơn[j{j U1u$R)ab1lx|mǩZ6Vc=pD{2t" ✷2CNٔ<;L"t6ʅP ?kL$ޛ<QKPs& w@:Nd +:|j͋ٿQr r:QVqڶTe8N(45qV.L{JV9qч_:ˏ),专_صA*sv)`l)M";q+-)=ʱ*co9< F˨f_n=8t:!螋<= M@.b8q0ъ=NwhED'"wbh@.0/y;;_,YϡTvme-(lYxVqZLc SZ+1% )l&^ ޺i4fͧ=d+}iya'o)&nf^*ar ƣeRHޕv]nݖ}I܋O&2ݑF#cp*T|Y'Jm"l>Qs]׊XiAN;a՗㙰+-K~FDk^\yHXqs3Eӹ~W%pfv*'jH=''Nø1'z 7qXUdrHߪbeԬwTbY$GHOԔ Rnb{8(S`\h\cȐZfq=HPndaQ /*تozזT.c,c8fsa RrFtQI/-y=!)I EQ[f:S(L ̖8ΉxڍNa$эXC>qĦfm$#q9mtư14Kן-xŹu)H*Hq5*aA\,G[;.%|6*܈< B iЀ4.Vqe4hW,õSG:֖̠5X^C5k$a"nRƛm*Ą<"ʋɼ8$nKnFDeDִ)Sk2g%Cj8= -*:FjF9qq))qGeƨ 5x;TfQB1?c/+x=#Na`s%sl*Wft*{c*'2qo#}f=hDBU杜s2Sp]ʃR%PF_VZ#;m@!Փ')绐RsSXppzScn3=ʛiʳoc_3$p`p,nq];_,3ÉF4㵓tRqF¾ ^Ìp0Wm΃BݽHpOA/2[oR5ã'^,w7?fA$If\&[gNSH1N 4cY ,5gΪǂRrB8Y4 |!؂Y=Y4-82OG1/k O>wF[6dhn&ZwLM5Q5T3`{%kb8!sy7j)y=u-`UnnOa+E&(]?r͜G$ֶJ6mQ1?jhU9ݴ RÐ؋ofx҄&7b8.a,ߧ7܊R+ 8NSлzSpbMQd% R^>M68*~-d">QHo-bȒO"ʣYsO~iz݅ޓaHHS'wf}}Ye:+cp\H !ItkB+L?rUrYhPA͛_2Vs`6M5m bˤUPB@"app<4|PVHҁiGɎNoB.% GHp SlFGE5`c5jzջrF"K\r$td0s_+B.qgibPWFȩf֞j\V2h1`Ûmytg7 ~Ų)FLi`Ŏ-|u&3/x%2gܺ>bO>XBe%z-tUW '*:V3?UuAtN.eɻL]+}`B&.JLB5&u)G9 (oGjfo3d(O7!jfE1" I<GM[q֍O )aAN3oruM!1HC#3- \o|X;nA(qA(hp&1Ndن8ݏ.f)\Oa&=SCŴN3ٷ=zvł| #B,c^-;N㐚^%Tf$IcK<(e29]4(UcUfU(b4ofŽ93ܖ#`Vig2]0YEYV$z[L '赱Htbbn^(!Ngl4scHzk)+qϮ`PE LJey]NmQ5ܔ!ifl@ 3s8c;NڦL233334hqF+Y[xg]k=Nv,!,KŅ t蔊YMZs=!Bnټxɐ  ? PX͇jLo9`6eG gfӼ{3ei: {/`D\AS2XGCӣ®Y^/r-PpNì -ڵ®vΉ~_D Dc!D~}4F:{ޞ9o>i$ݚG&.AqYǎDBbkӞg1_Okmp b^gg5R b>5#Mol(Fh5WS&yU"8F)>JcLj45fC72~:W*nv+Dl&;T3R˵*̯MFZtUbnU RSCEk>J Tį; ?59ӌƳ[<.>j5Gl :s9i(Ѣ8ECiK_FljQ}>$c0.'+w("Ix5+:ѫ q[[n`cuxىJ6ž|W:S=a,Pn4 ځp|U1y&pc<'R)%fB&l2ڧw[:W?S=_Vb !5 +Z46NNbs-Y> Ci8dtVOqu{pȊ1^ٞ43Y9 j$)K9d8Ws=h6}e8m*;؛RZ}+ɟ\z< \SA *;Wp->bBl+jvV0g~ d Y Fp<ȏg` I$c.^}_%v`IlR%,&u.GF՛e},usRIr«XVct8Z)9PJx/ϧZ 73P_JP|)ĖcJG0*Q a}h&F.JDz6f)鸘r͵KcL(K`v1 )VT9>utJǬ:_c?j /%oK: En9׶5浢ܿ;wcxNJxݓz9%7S'텬F-Go1-ys?<*Ggz_-Vaɯ %g&7@s=^H|SD+}ueO1]+i TP']A6%}o(ӕa$jRf. {o|{u%1AZrт E'k>jۑޱxɝNa7yGh"sg0-U+IFWTߥoGa9HG)M6U(ۜ9t̀DjOJ2.cAAb#*~!vM=7//GTGMſ+<ݦ$6h߼]e0?`yP/?)?!95%EyiBo,>LLFLF6Q8nlLofrǩUJF`= x.h_Ww^9xI*,ey1f3B*]t bVu0-9m+ZXҵV/X)50l7nDd7_r8eP bFqˠX1J xp\(-~9Z*9; 5=o#@1U->\1fWw՛}`.'b1;mmҸv.n‰hcll;w2_8C=ȵ;ѳuKy=5ܚ/Qf6Qqv=Gh{KY[1[9+O 6htI)7O 0*/j(ye>0'&zRBjMatVK";*A1l⭒9"dmc YLZ1։SW{&&5!m\bZƋm8#Z).scX6~)NeܘV%8,o˩hH6f*,'\A -E#KQT$ @iDơzG8atE*'^C~+7Em i;X߃_Si0ٝׯlKi8sԠ"sE׋Ӊb.[tfJQ ?"kks_~Dves/]F\ 2*匝,FA[%9 };diS?6}7-ޢ"?K΋{=o:#y02 (0uP2Ц"Uc8-_y8"]ܾ(1J;. ]HF^G9H;jdajǕcX,tm)}B ܸ-|xU o<_:ɡs~c Oˆ>cʋS4'鑦fq 9=^C-ydElW3}L*c%˜+Y@ g(?hiyW{kurPC [˰С:٭ܙfM L)f9Չ~4q&yt {mtĚ+t.H xה]9%rU/SَэidCV^Oe] mVKxJbʉ)e&e*\)瘚2F3pN Hy+Ŝܖ̭BWImzߘm\8.l}ǒDduXEr3io.6'wyҹԪ3߮;{ }pYhg5Xu )/̃"Djeʏ챤 bS67˘OEZ e#4(TL=$`r&/tLhq֜8gNz =EAH|)MA3`JǓnr!nR1~sjH]1ݧ1; +w^%Uʟt8pl|8Zq TTqn9zqV9'ޔӭ;? mTE;1u'[)VLQ\\TDDI\u1`2]q*s+@*:4ҀJ}`kQ%{0QI6 ]`%c鹻W˭ ʷy8QR ZvigG_c C;iO:[ߖ{NFc0赃7ecE5{sҖ^ެ"Uek}xz*ND yq_I{6})O>\IrBަtmVaڛY ԛ$tܼhѱ^eL;?jbo7  e!~C eg;Vołzƴy1q>6'LX?ΔƟA9ö8|vfP+&i̹y^L[m=6݇oH㵉xv)e=+Rrz ߭Y6՝ȳu[CI8oᘎ gƒ0[c5o$`¶.IOީ<eP>M>Z˳(,!Iy~1|A*a?h9OG5PT1U&O3磎tbUw*nQFyD-PqNLɱV2/20{%-fϽJ B JlMbNVq+YIn"*[].K*poT:= H('%( `Z_G`-)sz{o2}X }.è-ў6$/g9G&h6a"Eze$ i{Zưnt21h*I(L] /CfV -ɍpo464 B:1e ,j:uБ W Ň1Y:,ϲtz427߽y,.N=w32wk2 r1'Δ8|GI@r Ω SۮB&x"CS4^v,bN LpFG`#))ZQ<)8(ߥiR'йuMM xR.*)rD>˸zTA5#]YΊT>⹠U-R48`gMK]Bv|.nS=ĸ2, $t]9=kҰW8Hgc1XWAϛt=.z AXIwW2wA%C 07+ؠbF%,+xIxL1lVT='8KGO^] RK9ZF.}Kp^+4Hj{NCqҕgChǓnmƌ(cfVUmo-6;ofZEpZ s$6sNg$b ϛKQnS[<[ YQ}|Fa)vN˔'9m'Px|0sg[TW(sP3=gaH>82Bt#5~&ʪ\rysǧ/zGĔ+k K$T^)-{ɘ;)l>F|֝3JМaGK0v.Fo+"93,S7na{,F<9i"Zw2!{3XI3)ofK2)MyJUt-bǞb䘿T T 5RCXyA,9FH{*PRƲ"n[c24Su'IH3a,y9U*R:`s/5dL+>]f7PQsM-+^k@5`myyނO4 b*0pf{ l[i3*=a*z dUZ# %$; 6OP.&\?Ads& mYThMk4hߚ_ψ~0d=}L4/UfPF' df19 ~]&V%n:>0? IuRY Tȃdl^OG',d,K9-%>9x^#W&bN8Z\+5+_I7uq.gGyia;-c/Tb`# D5Ph_E[*  ~9zvY嗫3XSb;3o?6h CNω4|\xWٴ|8O̞Bs?5"M '⛅'19!͂|Tٖzԟw}qE3 ,Є^̨ӼAawa9B -8 W'zHrʦưs]0Nyh c՞S]X;zd0DjW>DM~tijtk}jDzf͠kQ) ֻTEhu{)&V-,],n2vQαBzo W|UZ11T=OĪVeӧw>2qodӡA̝#^ y[PQ1%.cښ2Z]TP㰊*"_0>r F2.4K"G3 l{tLT&5Dba*T+-sYŎ匾PN5uJJ?8&x)]s HRJ*(yI?k:nl?+tz*7i.| D+Y9GW8XdžUS7Տsq.][DsGF3r vHׂTshoxCPDb$a>^Y"yHm iB`4 ;;3N{y:.bVqiTG]\r ߆Eҫõeq%*u.tLRFW<1n{Xė٘cdİd zl)!([bow.x]rqW0E|bLp}&? Verp[:PY7hڜFkRRc+C>f tbt$uM"չɬ I<;3Yq\OH(TЏŦ0.%kuv*G:mS򠰑7?)~4#,τn9 iւ?̰4WoNsZuT d94XVD d\ t7@aXَ'!ޑCh!0ЮibVK&Z,ݳ#0 8),FGr6PKŅ*dB`Ж$ed*C\\JBV(ə!̰sE.HM{LA'|+y.s#tKFgE "FMiJrۺ|dDg#A'z ;Cy3`KSh$1)~@˜dͤLtOL?3$ra,=E0Ti>61#.l 9a5a d,>$.0y *IZXr|a)o> 0חXQTY/У\,dM6SLy,ޞ<'qO[%Zʖ%(/&ӣf+ᔮ>jbqJW̑\ӵyօI!h)__͐L}1kD&1CL{ZDR(lޥam5U[wl5/ҍ',܂gN-b?O.2`:jGG9mM&t+&0MIV,[]ʙŘHX(rhOBx G ,SPE1O䣨E8zGƃ.fړխ bܸޟ9gb)*Q|}zƵZΣdQV-SʟUјo !'i,s;I涄zM!ߊۖdc ˢדڊ+8Kce6h(nͺ'ʹkq5ܷH`˩<[1?mFCp~R1}>\XBa&g2qZٲmZQ4ނD&pGo.}}(z]WsG sE*hO'rDB%?3ϳbRz v[dT@79s{`k=ivc8xd$^6܏a&f󬗄Wsz1\8=Sp:IH>HaWE2c#>(SwY%h7QZ ZԌpBSaPc5a-Z75];sI=> 䨳2*e!SR#erA;9Wɩ<2F/!z_q> r(='ݔp萄tR@. |h^ . )KhNBJ ߅/|BߐZƥɂ,|.;',ZM-'/ 1ݗ}F^)#kX1oۺnoKXk$EO*0-[bYmK,!7(_R7.yԋX h;8HƯSoIe CWhnk\Mdv-Bg멸dYl6x/5ifW9jLs|eԬe<;6fz5IѣkpU8n#wMDQę4 h֬^nuby<ǗdZۀYLMl/%j)''Q1evOr9f9RF,VBo"_*Bw,.4ʽ _Q% /qA8ϒ2QV\OR68UT4D^(g_ ‹W@ш,Ʀţ}FMc쑩LĻ({n,b;F9t _)pa4vvX՞V [tN098333333 'x¸؛ٙR% ~{ߧ0n,Mq[E4E 2g ;Ҧl5 &`+3 9J\`kUjȰb_i%΄pڌ8 F|Oy3}'g;?\jMz/$n-SdE u bYM Kd߮&UeWzi=1k:[q֖yqЏclXb;]{{`RChUƌIna_ };c[8߳]Qxt"-ǰ0.Ċʝt(UG]|l&c0)sv\ݙ['9tEpqvc,{yO5O+MW?BS)'Top HX!. FW2}j U{BkF.(%V|[!Ce$T0P1}ʰX̽d .BW<,&̟}]y\UL-=w6s絾GjˑϿ'Eא:x(i1lJ]UN`l`31Љ]҄T{ #@։ }j#S9$5=/y K0-*|1R Xt"O+jnqXRl7K^.ÙRB9pk4ϓ!^6bal50sHS%٬xΚ}ؗLqn4)%S>g$F|87w~/+rk0krch=0/#Jզ˰[Qv^ᯄZECϽh2+?6%SuG!a]MwdQ#kں}b > f MHl6s?Yg K|(ػ-y)~bah*=b{J)[ecmU .ݤTe]oͲݰQVtB'4Τ2}B\,&,'v4:y2O2_naPTL0]"+˝Yĕ MG"bdh/g/* >)aO(c~OfyDrW^B ٥Q4D>SmRYkRB{23%#SYƿ8tf2?;g`RDm :*0.Ǧ_&gaaK/>ҶҍXxQ u*)aQTdU߹ aU w5eVKtPەz);dGD5}%Fo ~-mkx3]j^F 9BY0Ng~6ٟD~p%,hƷ\MdryqTƼ2%rV\KNe)7Ѽ2B9[͂t-gUe|'zN~)ʔQ|X̏+3C50))q~#V3cI9%s8[ʫ\'#̏QHhMSTj&QY)_U`v/uKg(4*,lX/<[YTX݉.tNv ?` ySC-4\outm-D.pE轕THg_ژۊ}Ё )}U~+ՙy.?9B+I)aR _Adq"G3<8ċqpvK#+3{Bx(&8Ձs%h1b't\q&׆ܰB9Vŝ8r㟃o~VTٯ}W99k$s uC0Wg`h_D5#TZŜMiP0 +χ1 g$M)cR_b|!% OǑ/ LYuJޯ*Tݥ`~wM9 ib-$QŌ\N!m Ե90VM}íE<*d5)\)cQU1!*y#ͦa.̗îb8LI25f?e[ya!_MBUEC=]~"mQg?oCN9\pM#K3j0o`ꩢtC aFZfH;cC'v אvE8]rt'JׇF<›yn$: B;ʹ xN7uSwGs' lΎQbDb/dr徥ۺDp{$7lpZ"{.XU~ ?}5@l M-n]VZx~q8V~ӣ3[Qǀun"S'JYQ%gUk d{DX3;UO-N|O"&c>ɇ@Bzr Qս0,ڣԓM(+`ȳ*pkg`9S OfHKl`c%'Gʰ+á`)6J) V᥌/TPH &RrvVѶqrZ4)'\ +1\^ X U!|%zJx*뼂GbOVO(\ÅTGM6D V4%@mYx)W+yfF@D5Vy3FCe s+jPU˴SXQY-59h۠_'3eU$mH(e8 j`0.c^) y;`obȑYt *iJ)7 Gԝv(n:čzXIFcoΈ Tؖn?O(nѥܞ@$;ӯkӱtܜ0ےDqN)Ur->nlͥ!²m)xM P$d "8/ZM9r#j<կѸxrY(MOO$iQKb|B5(r?_DE6l݉B7ϣ>SBU1S3mhUo77jT˒ Z>Nײt8357kYVͤb^x]C&ZQ1Lt^%`w\ }_uf I\{=R{&fzWY[w1L:i)7-1Iϩ6$L'i;řV^VƑF*? .a$▦z" xO\c(Ko _]G+Ax 捻5[ cVyr%C}֠Rê(-pXƓα顴I# ܶ9.%6tdQjkiBk԰@b-~PEk6+'OtSҽ&Siún6h"{++уpt+CPVOs'Mjh|gh!{ԍQI<5;C6ߊളMs ٟplK,I)IYޅ !ypeRiÌ Ƶ1.T݃W&fz$eRv.{Tߧe3jBi5g8YSw4Buj1o9* 9Oipۅ6,8axt9`gJ%Ƴm/{p'Ëo{ L CB LmZ C^_wOPo0o6\lxFj7}6lT<.q@k-DF!왌ٿb7O%Eo]9gwu)²2v\jhrUTR+@\5h!d Z&0WVqB5aN9W)!~f:6W[{' Zj ]Ò޵dprwڞ/5u԰5Pjp@ j8_dΞ%nI Y.5\Ci[ Qag %AzRrWT}Ys9uH2-c"go!Jz=Îmlqllʲd~ǥݧ?3{ZSu"=v!zOl 0R8p^!0 xҷwr ;Boum9Ӑv!8*Q1 ]az \;TpN7&<͊bOC5MCԘжA-ojm{ ~4F!JҺ*5Pɹ@ =xh8KbX䳡^jVbB Os5t#f[ GhPdTe-ZN|p!*f*H4q5qj>^9+MZ<)edЙˮƵ {qU '&+2r$b;<8l_[,Ya8փhs?,շ7[m%E8ܲ5KЙ=osƐ'|dzQ[BL@cy?ib9&H&N#yup|}1}-gCys|MĽG8r[sO8S]?jO7῍\iEXng SZFmvoĺ&kޫbcgQs1:GI0M29˂XLH|8/nt#BmѫS0n+FUUt8Z?̦Zz{ϴ 3Uj!G˩ZƶT*'PdvL'5S25 xVǔM5ŚxK܏*GV/OjZ$ål1_xjĺ2Tet>/W⾔JWSK綪_v/7 k1 \Ι3k"3XҒ~\9Ёש]’ϻ7 `X@< &XE/nl@c%NS#H-I^tH Sb{ ͵ &kT&NB)G5 &}O ]`iF]%e+6c0_Rlc&qF4¢sGԷBpݛ?X~ g S7 7&sw˹4uN!rCiA8G30ʛRg϶wOYGX ;2 \IöΔrZJ^'9sMfZΝ54?W}DN!ֲJڋn%-uTj#'^N oh8;b&P瑒߻43L#w_4BR6ggXz >,)ϣ8 gݧ0\:c2IʪCyeK㫽(Jܭ" 0i]8p62>–߄<ޟgК2mW$!kس+ q;¸F*, О2޿M׭aNp=9al_OIQB Q\<#-|>nε~>oSF L%vFjjT  żT*"|dTb8GCF'YLMZMEZ %r:O~J\@{fq!-jJf.Rll5Jx|XG}^DV)猝ʙ xŇMߖv'`yjAv1?ކ4oBlh.2p(;G@O:cr$XkCwmstKIPj4B-l9ن.Pw(҇!fp`>c0}w9 Zoss'36$;gVHDkAX1WWpO 7?i-65>.o:H`n?u=~%ҬΊS̨&׎>N-fuCMN)9TF%k{hxq-('CsJͼZӰj6R1lA5 %,7^v& q;ꥡBgkDVа*i5ZI\ݪ4TD٣OOG(TƓ>-|1Ga_i#AƾGj.R>Z)[T<$1;ͳ<ɉ.H_ʭ2UeW ;ftGV e׋dg3-;2b]/70sjHFAŅrUQpjB>%N'F!>ExZ<V5ok6qe;7z{paXEļ@*R'E7FTBQ[X9r7C޺1d!]f4✧3{)Z&_Inޮzx8liϒ1vmLš@-U|r5Ij. rQ{plYi<8e"_sJƆWJqKΧ&rXvBͣ)doy|0ߔ5PWG*vwRWX S[.zً/_H9 9\T͞R1_78͆خebFN斤JYI"HSd}#,⥃u5ЉvrEEil,2̂K(.$e9w,`)ZZSafN0c,5*4-^85y4)zp9k-36+wXJ0dAUu}!љ=̰!aPzhKuԴ}d ;jMРYΝV2\dܺ_F\?9ΉL+BqaC)3sut|2o3 fyǛ f Sl]|ƇU?]X(p:KΙӥY-n4Õ~t@=?<ωzs1϶$B Ov+F~FJzؼOH^j!av|Ep2̳ZAL:WQ棥|\ZvQ)+sݐfD7!5.\º7IdӓLy2(K.~Kq\%YrZPMU  \1:Jče`0=c|R2F{1/q8ğ.n^Ȭ<^}}А{]|Ů^įq*$P"~ͯvy>s+>/{'N1֧1Ο8x& aPVh]:U6 !=0fF u#38ޅy!4/ (VfK`>=30ѵ>|sFg>6,*`~? a#'m3ˆ]ۚr?)J숲ܝ%45bA2F?,fȠ* 6)S Sɴd;%pE4E$0~Xxt,$H(>I~LJLtlSx V\2τ{~Y7։e8De):x|%skMXpP] j%43+,~۞&0 W#Ǻpԝm<`F2t-XӑA趚@"C>ggXv܀{yz8|<ڊ!hoLެ;A6+1hڛn8Qo-u=95S01-/.F)T\ԪzeLdA$6EZ8}$z'):Ӛ(:fH sӋJUU~%6_TdmT,x]ILSC2ҋ]XН/?}7V1<$YcmBhxAבz ÷xRC>I7m0^3 }3ƜlĉĵNpdX,2KRFW:$M OZy7oU+|Yл9UK!aS_~<6Rfy60e"* zk^:bK7䳅?'xпʔCo3%.YS5 iF"oZ0ߜ_㘸][w՞xnţYoMwCgU3tk*Zժb|[ Z_/ƅa%^%l?n 'U"qҹUH]R @9)XqNN9+-cR$> JbPb3ۂ7-LRo"84̵T9חf~4[y#|o_{5 ,6,OQ8;[7fe׹6Q$N9fGz|ɓBpi|r1Nd`=ܜ|L7:ٲ֘ivh#l1 ج+k3P +IǓ2g,SV;lzR :562calqdot.Reą!"áѤQ"3y !'2^I[W`2#1l4F?%Ra?WoÃd5 ݑ70&йRJFH#t__ؾPwME(!쁽r$[d$U&Z+Jxcח~|J3Ҡ-Ee c6H8(sㅠ31r0\O)-$Mn+]Krih^;sUnjI=|Œ ۲xFe71B38ZV&ws|/A-:h ;9\fI)7-2 !oӪilU_8a1gH0F:\BnGK| !2ua g >{0J Sc2M$W!}S=p `?1Vܮw3'!.x" 9DZ79B +1j-[G*iGJ<9V(8,ՋrF!xJf}v4fd폪>!ƨ-ɞ=R|\rfm[ Kc{iQk4wG$GPbiiS$c̦gpQ.9IJG>v"=%o|~χy?A P焏E9?ț/=Ip>48=L^dy_Ư?o7FkvcWK+єOsy:vcqΕĜx5Y{ڔHK a5vkOΩX?.d2j>Dԋ 5澆):ǒ\O/)[cyMH e 7FVYȹ6ɴzN;ٜ~h RX>0aћA,~1_iǎʭ*7\S,{.ڡ+OyRǚ-nt\jran,w52=8ϓy,plCX}-KxL -igʢAKLmk12]o&TY-,A".et;R7(D[r\|k],ȝF|p438!usA!a'#Ds{,v:`zci{kn]޾cx ݡRyjꤵT_=Q1>hb+P9''HH?(2]lPlvaϙsslonP.NCIඅ̱J_FFK,S(BqI8<"9i\fOQ [:ȃƿ`m Bc9-.6!tH5x:ݓ|ĺ-qRWxPf̬\}^mIrCC%~b R4 11̷QlՒ`bBA'R_0jT)/~QeJnޣƝ=לuZSc_,}Ӆa[}:bSBcV| K\ 2Qc;7гu^[ƅrRmτ,{-KVog|dSayUMTw%Γc"~TbTKw/82 _{Ň_<ϕ\H z)OI:\|mi9cNy~3[W=>ӍX}o֥nbH G)sBe d'%zdJwH;_J&W^J J5ZKM]/7)Û]I,k*liGη']ۊi jnuN,__qdU N>o{/m;L9N]^_~ǩ/[*'hݻ0=tBAæWGtR uVe=L9ra!Y|)&rzD"$-}{7Ŧ;٦1RSVIh;-T0CtN_r[gu 祴ARUJI3i^ř- wޛLxQ[+59COj'Goj!IJwO5ݓv<)ٶi~ 'r~)e;Jf6]'' ڷ@$zwJRss7E ?!3͆MP}۠bߊ̫#oS^TT|<6Pj`wfٶ                                                                                                                          Cv)ff-^0<\1 ˷~o hVGg#RtI^9^~R)?4'GY%O=7y.=ng*E}@y'4uU{_%,P<.AoNT,>%զ]5o6C+?Ƙk=9s]a8OpiϘ[!rN?z#̒<5ΐMʷfZ}S'7,7Qy*jH~'ߐ-z@±}ɥre7'J#R^$hmvvmy"Y"i~4O#ivJ؋}LSRL 昛6Oj} ?[ U,Kde/1=7 &+K ;qÞ2=ڦ&jaG?NeKwɍ^+atQ냡o,X4O^p򻒾T0XϒYLH_ߓUOU 5ygǸ`7m0oŚd)a'):jZbs`3yڍ rU #%yITӖ7;'ǚ;nji=Wtv)誢0r5;Z"YuϏ!$o,rŶ؄4 tÌ ֎gW|zRFy Rg5sd&e/o\>46XM+0X/5KCMC+5[w[7y$j]M^M^5;zہB.)۶O&?Ù.|AGg:tukJhicMwjysy8?̺c٤9fLtÐj~s_˯Zb4UZHLeٗ=~G+.7JV7$Ԏ9)AS={Mw9yVvouɴ8ǎ_2. Nk9*xh^{TJ FwhaS#{?h |3ma +'Ft`#sf#j~+6Ug-o>siZ ӋCY|(C,{ߝȃ^2A'Y^k FD cyWhvȐ{%2teW}'r3T1[FXk}3·K8:R)R!^Cy[\8C'?q_jsoц ՘~"t~4-")ӌ\x7̃ Vw,Ԗi2pgzoM6GXy_22bpR{Dƚ f$ѹ }ZR߲-2w! vl'8cNn\i| qywW+pufk["pl4OG9.]'{"-X*x6m~4 `^Ϲ ~i͡~ Vx\³Xl3 |;p.n{uxҁ^liͪ/`}Nк%n|/KMǝ#f/^r"9.*_Ú.,C?ٝmeӠ\uv+ד3lOβX Fbמ݇6MOY{%!p^Pa>U%Xc>Ɖn]wbsY u2 =rzi 'wd13ԜZLݡO@rC:6C< }yćUlp.7N nwPO&ys[cFC ;GFt/(|T'GT{ED1ngw\ 9@zT|&@"ؑ|4YB!?ƫ wd)&SvLW{KRu n5G ˉ^܋S#H2-cLpb==86Z&x9$-X+0Cjߝٻ%IGhzѬĊyqP/.x:҄E#̖M&Dn̴ Α&|0d_6l{B}4pD_AyK:0&K8W8dfu/m-ފMqm`As~DQt=barVoɽ=([@7#+sha4ꉂ>.8̌ats:~N pujҲYUg2JuA%1[rpv F/U CiZ)#8L[e;0 RH6.f>Z7ɡvP iԞ&lȲ8I|!taσYu ćG9 ig\}Mlv* ygç(ĹQ^`]]4uch5KINYErL$Ϲ͜ySztf3}dtT2*Az#B x/E7Wn h?`gYz*9cWSUpx=nN,nv 0Sz(]nާjYsxzb G;! \fI`ݸQ`ow%4b363>ci24>M‡h^bt\ο94u  d kTQ7؝-v mPmψ(Iێ2MpfCc^_s"]bnQ"[&BݞLs'yM C~U{.n. UX> ]i劓;ɚKSəp(ë9ɻhN‡vQlݞK$%0-cll4K5:!_ ?zwDs|R{Po@ʺ2SNuIɜMVA0C)x wvᇌ)u2Tȃ\YV>0r(}adH&$<-KXLqp?~6{~_V={~ԝcTҏТ8&bdތ&QYNN TMbs*? KmDϮhzÑ-,(% VtN46+!r "XхΗ@Dd\J_NǼ؁;Ï8쇕7SmȠܮ)NS?S#[IV=g}=e4Ύ-dz96\ݨlLK"cҐ;ͬ1/sF%m4mش8-Qd|dno C;vfDэ1Ar逖#ٰ1˂[/z|,ѡFQYN Rc!1a-C ǚgLʠa;g%Lꉓ"lu)%ux p'S2͸oӛ6FT\*#̒k-i6 ꄾ7w0N6[ˋxkWbX)vu #Ӹ! "♡Y72~*[5!?g3t4dPkGLg,=Ioz{{v5#j8nfyZ$^|XE67#0$-$84geM.yyD1K٣ʰN(gƱlȽ;81_5\.gi|8j=ꏕy"s{%kc@S|[;}/ZXxq0'ggTx(E1BH~KG\Ų])ͪx0gy2C>hBl]"牁%&fJSY3!xʛ)HxcK}QKW(4 uo{K)mi0BnGsf:vd3uF& ?a̻dž>.Gĉ>0;,QK ېܖ*q`( M= lHŽf>Eɣy !_ue2hJ 9p,td{V"")m~> ?]mPn *C(2U֚4I#$:>硹;S1;nRM1wrs.v$K6g'%^()ۓd6jy?! 1u!L)&ګv#JyԿk2k/*Unx0!ܗ1`"eTڬQ͋HiKWVXٰ;r%{-sJ{/֓]2ߊZ 2l)g=ÜC[m8ׅy2ُƤ4odoM#R_O])[oV)q*IA+8/z1g=e[GPe͐h8•}TAę 0!-0ǎ{{0* v:OcAϥ,H绲FSfй<킿r/HWč/UcHkHo`;ޕ2> \ImZ[?Kyr}~ 05X6k2Wpw@7Zr3GY4=3Á8f1lCaq|c,^yI k Kl\fN߱$gַW1ʹJX\sk2Ph;IM<I4w(.)ŬJn2z_$_L9i|\A{-qW&-2'Fu`Ǫ0= 9{%RQ=8"0 3|0Es2}Z#269O-k}{0m70 ˧ n|=nyꜱx=,~[V~cV):3%h^~2cU7[RZk|q1fF[ sz8= s#l z >)~VWs%i…9]HK\Jĝ(]Gt"@$1#P◆=Qu`B0tbu?QS1+d+4"{ǻ(8Q\_V̸VJ2|=mF! +mp%JTL蔏~15o^hM&䂧xqbaM{{d%iy*_)ܲ&!y;W]-jxRL.sƠޑ4-GHf$S'XZvܒ\;‡Qotr4grzKl-zA=ߋ]58&s6O %>(|ũ, L[727cڈ2&]9ߖd2e@8Kǔlsf, Qk>6զ,W^2nu{+b{+peɮ`aR)dNi.n!LfXfgQ,t$i[_2ܿGi<ЉfÙm1܋˻_. Wߩ"ײn{Gs* +o'F7!c)&OPy{f7G;3<@L_{ӕ6ɛ㨜Tȟ9xIl]O3m7yf+6%s|4&LNsd 1Ћ,']`%NӚC3\ŋ[9.#sharDӆ87a[q|-6oZdG.&33633)( cM74z}AQD[6pn}ۋsm̘\d ڍ#cjΖ0cQ%6бu-_ =YK0Ӡa}Gx9o-+XCÒ9[sl̤$:h1BO#560ዂ*;yC9ШW^&1cV+F* oO>N&xp5{49'yus4FW3ٮMR:l,fҞ4n3_I(r )>_ 4]TbamF c򤡘U%|{?v|N SriYœAx.oWN(x [hefP>UcXN_/w{W\Yṛ+N>lL`S٤lٛzC3#w`S`|FbaJWC/1(ڜ9a==Gٳ=w*TûP.` VfrzŚ3l9ωMLnM\s/yw4r^WqATYU1בm2UM4Lz.~bLu[|vsCdn5!- Z;>V# DG2{ (-E?ƹ2VCX4K^0VjLG|W_L m'="mC/&nkCn%(Zٔ~ǤOX5$0JGu5`z<;0m} 9GU;ajbu^/Tzwml1ܙȔ宺ߗkj)ǂ~t=]˃mJXfU厾i^|_4%{L-7CRr{*whKRS'kNA@>&rKG5ks/kwEkg: {N, 3wzwD2cRG30G;\!gwEe&0͎V21ھ% &_r'~[16nk^ fAR[O݊ɔ+S8uZB6!{ITfhm2ۋ_2*Q9&nMv~x30вD:dpjuiWÀ(bQ g2+'zQAvV*gդr({!Og3{ 19 7OA/{ӗ3wSt9M8ܒFй֔?=8Ué)wr`;y=ׁ9ZƜy=FA#.ξg=6dw-xt5ep sD t;jIFLl9z[_F}ؒff-c2[OX_n@Ex(I.WQ*4Uצ͸gQ/#6z˷?1h:zm{ {1qR).5~KCh3'dc &?vc1}p`8[ߥ0|O*=YDgweSWÜč 'Œh\M.Hq8QJ.WhZCjťt5A,qcuo(z\,BJm%͊ˎDK`ʜ.5sIPkA:O/+k>\ 9Ğ5V dNaXȮK\ w{9ƛF\Xqgy9e/d[+7[#)Bp.TaCf,6Hˎq2n LtT{N}myGG&ZѢK cHRɬ*6~bM rY'.Q?IyQO6ęE{ ܶ:7uGA\Zm˅|s`7k:'N8WЯȝ*l :͔FKI":Q>dޒ[ OH?}Tߩ\U}\}xh[hC}wJ}6JE(vl&1/+XVBѺΛ_dƇL$˰Y4]utQ f;/f8q-7W:e'fhRf]*Z4kТKi&#Ao0u:EDW}b.wEB׌Y zRocl-LB C=i‡ 7/48Ė%P؂Y>w WqzJ0;;Lm9Zl@,FvcV\r-obW 璭6ζƄpq5v3BAn tf 1~>Id{g3AV QWÚ&uL)HIDA_+g0$9=E͔ucG*/D1. #sƋ}TΈ2^}3C`oT 葭ϓڼ?sc+iE#^NB9vx|ۦ@l݈yc͇Cts=}k[)Xϕ5].U̟6p ~*BPK{ (oNn DRPfnmwww67v6~y~>]k͚5{f8vLgݕ43k4v$w%e\ӂC\5*Obs'n\9g,.#|X+~oԳ)<CH>,0z,֎@>8a38|R!^/'RyW+p{cދQ?K*Q 2 \toלd$yoaúDn-Ħu1E.RvӱSzӻjf,ca5-0~4+>\3%3+w(IeX2;6JDzHbѠ|b>r8n =yȈAs;Sa_V*Eۉ1ˇ qo!Tj$}.-xSr]}T4YBOz& !Ð#}PlL%)eVD4H -VJQhz`,]I=C[s:bEqbc) x.8i-'2ևiZ̯:E8Ff1v'[NM$,d~8'Π'\ Enhynucs+By4[Z3T.0Ӛx;>#h.y o~­/c[`KaojK~O6vZCoD(C?5|XF7R 6@&F2b~h8ȷ&fPJ12l,§Pɯ#J*q6;qM}| m916zq~gڹ1965M rz\<5M?/uIό$f8Gk.g2Z)m>lIY(/bh Pv°4mzll?Dǹ݁u~~W*NXK)AF|'Y|Ԍk{ we,EIq'ɝY&_)"(ܹs>zR%7olbI*O B<Ռp ů4&|wĀ~;~\)eR}ENН70E "jİ`.[b$E~ַ]9sp/<|S'4hȻ d ~LMa膉R-xyߟա|( Ĕk &=Ȑ>sgxPzWJ?xrcZ(BP&iHO #O9|Hg#73wsL~kiFn4ռ%z rq8ōkNSCAATuXɜ'2q|ľQ=9(d; ?/(yjdvgcQi{Y1I ȩ8>u &p"N_bh(ePfedP)_ө"RO5_%gB/F235,^euG*]SRuQ u?gn/3ŬtҰ7Rs*Vc!hV+.O1BEF֑b "TOUt7D&gP2yZwN-ٽ 7N&sex E(ۻr/T{IUy |69v$I}q:쉧lK/6fQoyRy ǥm= Y㞉-hQ;vԙ@5OjNɢK|M EkO.LYC,n!®-7| lnKS ;d`q-po=g+Iߚ.4Qk D&8<͢:l) S G9cwƧc$7wώ秾Ҩ#p~Ʊ!AUq&է`@NBzl:8e׮XdFg)YWlJV$lTyh3~Q{n.MUfc|t/G /"e2=0.:Nz9z\÷G~Zfjy^Y/ao,B_^OdlWM8n,d[8*mMSBBY?VÓ턛>!jq]h~#(BDy'MRihnd!!R)F+ښevL2CaH:8aǾf 𩎕Zgd=p'3)Ƒ%R*7z΍2pF:(oh[*<;ы66{L9cb# Ŭ:R$ O"Fwi/*eH+s+38E(ċ#x{ucOP0qxwEsdE}?Jp^,ek!'fh QW9)X?.J/.Υ""3~f1v;(P_"gH{UCT%gxQ1 "+PrIKbjVw|1圛j(8/ҿ_r_J/%W>bo7]VbgaUW v&"M[jP¬b3Yִ̱7&NvJϛFf-O}xxnSB30^I\aq.OkK+⪤%<4!ҷ9;q:rOP Ƿuธa7&`0Mρ(_`}c{sA6J'~~UKWu*K#1V$",V Ԋ*]܇$V8n̍)Hl5܈KqZeZ#PbA__%FzѭLLڦDmfwY2Ne6ek,M-TAɓ9 B;mORfK $O~M" yQJ}"=AJ2M"O0.Sm=Q4 \$WC$oq" N6cؼ|N-DS /_ɹUň@*>TzGMx1h(z-[G) 鉱3R.7j 5q[oŲL3ְpA<.*XZ&>iVd&b<<9@>@5M |a-=uNh RɲQJV+&b{Nj95V6s3?y''Eb~@g?Ä;~ ]KBh2(*b=$z d{hIE%Mc]hNۇHƊs?WF oE`卪x+=S,pNdS(aZ aZ#[02l`~F Ĝ'if k݌a~x&X]|C=5L(f}r`|^*0YE15*jt_YLN֑hEۃ=9lG=:: lDtK!6]  8F62if< CKس3V73efV0qA61pi%kbaD>D^w x0dx#3hU@o5ڪU3x鰽hT|*N!v{47Of`/CvDt9wPyDVv\Kx9jzpemHHM9zUDaDJ3X{7ۢ}> ġH^O)Gd 1zLPBԂj /4ڠIͲYkskAb sYE0Sjd9oqu5z0驧C?PGu/"n8NM^%_AHw b]EPZ'sh Kɍk8} .7xHJ |rZ2F!:W/c:=]$Fz@.wfZ} )3n Ngg&OOTx^t]O~S2YqPyh,DyZi=E^&5͌Y))YHnbo:VBx|t2O)%Hd2^h"~F֖:}G3%7q+"DA{[% T\e~%uȺHY³Fbxa0[ԟ.X87M:v_/ǽW RCJ8v霒5 0͙3p65sid7tvN /6qvSw`=SK'R;w2Z5⶿o]1q@d9L*03o9wJ\gX3GYh׾F0qEj&@m"^|~-Zs絑̔ 5{LVvc8LyԬ.)ήMqC r VEPI2qy(*ѻV>/_gç߹Њܝ\z)M2DM6h9}3T%q>YaZLMkQ&ґTLbgtxơ)7[M<]i=jd{6ܱWlZq.4hxb;POJ=UEXFF,@n=ݍ(¡%~.‚RJؚcx-79L[C!f02j; ~i`=9%L3:(q}>Ev'duJ"K ҏa ?3|ČpaBVk : o= ~RǶf ^kX"ÆsƃcC§e^F}Xݖ^ #z2$=:6%ԛYl0s3JG&X`%8 ~U*LZY$Bˇ[hX]OݯEjb&mo ,=A¦)&2񦩕 %T"ǖL|L4'L$m5 t@²l$Uy\H 9wǡL_$-crX:SjƇm<ɋi4v:11a:T)幹o%]-Xq~PW͎]Ғ0OO| Tdv]q 9R\^VsvvgI&*4PzBb-."s4hjX22K 6ujQB!_KQ5#?dDM?K@h5W[@LqfRG!R>#jک& g0RVb(pzn%wb14A5LC1ˡv axpv?2h*xOvˊIL̘IROa0n\ &q$NXԙFddƮ˧b}VufV2챉-Z)!GQJG$x>{K>FKV|z^Dp"$RpO>veG:ƚ‰ITZsx$"G/M },.th 2h4H4FHғL:pR:O4byVG~}%KT1dN$rj #6Mh2 2i.oLRҌTbif' >84[d1UZ>}O!c"7c^Iii?)ιmE\:YȪ] Z}-?J_OU߉}Ij2 Q"{#GK8\MLGГ/*бUHۼ{ UqBnQZw/2L t6׭ abG\wPrč;+agv(ʬyLǜ0-EtKRVh# #-@Bk#E 553}$&TMex,O9 ]L:9z:'/ 4 [*1͵_Swtx`ݼKXRɓ)ơEA`WSS#e2#;v?P qC63aԾfF8#D8^lDo7o]Ъn?\3Ҩs2;r*ىF8j_Dt]|s&_dU|mP30|`֬ڼKX!>xsf` #%YդL:(ŷ<(M1UiHCDN?6DE%U!SOۆLY$֫39y[N\5zQ<1RKs7Q唙f-k[0E`gNg3~ PU/e+9= gcVC8L" o r6¶5J*H瞎/3 x]5&MO|eTxkd\Z;\MEѫcD6XXJ+զZK)`o9pXblTbmRZrK^raXC}!KrqB(d9U,l~ }.Ĺ[z "sxD9>~Sض4EXd F%ϛ_鿄 ʗZSKH\^WI:8PZB-&u1OKtkOP'쁜y3T]x-#%`p ]L#s [i=wl" y3_"#i9bIo ASJ&;%*c:ֲR.IC)l<]*J9%-$#9!y} =$:[+,$īd Ay$)صLZi69bNp10yY$7u f/CbՙP(fVu(|G4Z븠~Źدg\n&=M+]87PwóqM&n$8y5{ִomJٰJN2vB*(CYlGu@l8o+J\F{5 :IoÅiZ'9spD$T>(}!16HܛA(5cF02&T/:RC5/)0g&A|OSBSirdކr5 w1Ѯi러̾lY I6TF&pU0Q lb@sס*ZfI`!^oYѿ2gE =mUhpLHp!l ׁBCvcN[Uh ٷ=RȦ v x2.dL+1U>P:V02=@۹jfR6^V-t$`ꋎr1vVKPJHU9S35w4шCew9j/QWM"'ROz ~:l?(yس}jnmQy{E']լqUqqx39YQ4³ GR-k2: 'Biۅ:S4/ogE2m3yotL,"d Sc8L:t֙<7x~8# ~wS GcW}Kkԯc87`0|77 a>KC|d{n %?&vtѷ`~.x67=` l`}ks򍾼s'fK4kmlЏbRCz͹rS.]oF$ͳrCea׺^,l=@FEgal M./z64P񉖣cT!hV*rƵbvޕ거qM&Ϻ%;y [2 sd*QjrG\r+O'M>kl{b2U̾&26~jаf2Z-b 1+ޔ<9CɈo 8v/U`U\y 'oiy^1_#?;_JV7XLՊײvk3=uԨl?#=c#_S._g#ppn(E ^ռ# u} +b痰U)+y&ޕ䋉Y"0  GQxWG2lTR `e R_V…_pƞt_73xWq2r=iЍZ.o5X'7rzh<.ړVSRSvM0ZRGЮ}mIطׇ]1c8RX3K~]Q[Tr#dmb~VFʹO4? >fBp2&__V>l)'oqk_Džn kw zlKYg7s4O藿\q,u[ž~uY̖/ ‹ lI-kC1g]0@M|D)ph`[%U4GAc~-GRޔ(ZD.Ŝ9$2{Et,Jk-J7ZUzz&9 7iC妥 5nhhP1wKˍ g@w)=^C0O'DET cEi~2C0Gh*C #&芞zS[dQY$7aeEp̿ʘ3rY6ZZUJ:Fq<y4vp8ˍC==a'._&C&9Npىn !4I|Wȇ?@V5柪/qCaKXKW& "|fV2vٶ#/ŷB(X Lr+qw5ǟD՞Vfڔq,4kwc_#bI1񶠄Agrǚ@| <ؿ . r+ZG}ɗ1TZAupiA2tЦ\OK ݳv 6׶}֐aQuW8B`m*\mG!}Yz7czdTbTQ䬋X&cP 3e\-FDbdrNhŠqW]1k.PKa]9c~W"Q-2l1;ul̾0`P+ܪ`;,GýU40f}#kFƟkw#t…tXMݾ|Iɍ=i7݂Y)˒$s Yy!sib}#Yx62D)il37z&NC8nHs&6LY'3αzz4POE䟟w@\X@JD-6? ̍Bm㙓Oa_[~nH, %^[]J\]hzo:il<,)'fO9'{,V)#VFEu׶:1bKt'YB&Eρqm&Qd|q"]8S{IZt-zq⑁MJw*ak FZXP&V~-eLӤ ~?ސ"dNldn JwQpǡLƓt'bOFTxؓθ:؝A#h0 {Vun_(ḣ t¡J{a8֊7 uvգ}͒?UmAM_ ɖ_ǍhmÂ>%z}ɴ7!1lO T(aܩHӸ9}jl$ȱo3X#^<<ʨݯLH3U?od^3w[X`3ػTUtig" Qw'VKu†/ ~l"hYhⰰrkaQ/Y;+nZRaޙ{QRy4sN KsqINE<%JJ!Cʤ&%ds 'Ki$8ɻMJP.3m!uo"%RELY+gdqyދHQ€_Mu\~c`8u~/'K!Dbcy$;MAȫU%Y#}i7w\V\;5+%MRB%,ZWD ޓD %x|_՝:h0-~E7Ʈr{5:kh]P }Z]%-HB$;1aBލƒ7G ǐ>^\UjyV;"{Rw)'P1ckOh=9ˏo' Ђ 1Yʛ [&p*>ؾp:5jnr=Wb֟w7o`I=U;*FQFڧ#0^OjH-f2 U[xIAY2`*WBOyO 2ړٽ [cG^L c_W0J`K@,Icm)qwd<(Cwʊ/$eDtVAєB2{#OFB^.|ZS|RMXȒ6E.SD>8 E@řZ}39X*4d֒S˘+:gipOƢ٬7ǽ2sK.ЬdAwY\hѻNƟOAXbIh~6R5ˇK谩98hWʥ,Tl?y >hhC#{ilm$WO@E45ۦO۷^ӮH΁/mӗ‡!_SX3WrFpp}GN0a\?BwؿщџPuptPG|^6~}C ; r~i˭m% _2ǗYsÑFPg=s{$Ic}e,׹)Xn̷g"#yAq1&zl]ఞ7hy%8OM*viv@iXRf'yQ.5Zҗiq|{ٯTT_bU;11aIB{Ybją.]utճʼn^+(_~M!&s?88'O|r(bw7)%HKYMg?A$6q*B¨ FIFq-6rqUGy~p!I^Xv,+Vo9NUd P-SkuAѸEPYA͠P_^=!,@`jzUZ&E=B>)̧/~p쳙 \=RƂG~橴?n 2=]iʼn=\.=)YCȥblK诐r65 9^PB>odU|0ۧ}}r<,V=˳LJ?HJ2lfP #ș4((aw@wM@ jG'1}q0oMfL 6B(Nѵ@RN#@.x akϊ>CW#Jy2J+~Jde#Xio)eg(ۥqX"=6M=I N6]ߏQŖtϛ0jJ{F cGn&Pę`:n^x5"$",a[I̋hXeɨÑmBϽB?Yǿu7 aK!{iϏG(-QUmĈw Y-;ꋵU0##B(}:sKƕt]fpjL:D?ZZec[M- dWl)*𸢡7YYOHe7O=uҽMDwl6P9O=D~}^NnZ3|^sG/Kx$tEj[XkHNbet\}jJג:B-4L N߫!-Q2\e\iSCTQo~7v!D8 hĠMMw,fP;D~ěy69(=a6u $?߃^|HW`5sh4"۔ &[^Nˮqȁ6n|D}?=q;!̋g8M^.>^YMrYt^t5lpVd+P&. IuJEQ-&lUӥ5RWIBF-mW1Cs*>oTR7%Q_]/%**(c&ݎ1l ~g͛djA hś)~o餜I!}&GWi<“!6N cm2Hd/4AɼNgtjS09Yą4 LdF =#B+Ľ~$g/[0uY~`v^ۍA>w-| Qzp~v3|2 '2 < .XF|wbj9rCX.ΜW0GE=57kxU˸r'=hx͉yHR%7K}ٝ]Vȡ5O~>jY2v8iR;,M șOO〘G|~c@4T 3{NPTmC~ 6C;Їug)Gb;_%WF ~3v Ӥ :hH>o26V .OA~KJN3+.aY>;\}p~ }_GJZ[BYy.Th);(K%KT,(TM\߶tMCὌ ,! RxqX[i)3 |IJ#UKY"#"-ODy g%l(d$ݒf̼ kZGKǟL*D6VSDZ7SDަx H}tLٓƮD'!#ݡ \55n ۝n{nFlGP;0YTSB(GvO 'u.{Vvۄ߶ 7B>q̽N{c%J"cʙ6FE=l]ɹ6i%NQݮ=mts/#xֱm}GjY.?1ʤ4v,Jgc &$SCN%Y:Xy"3e'~;O'X4f 2ǡnU[BފKt,C>LC_ }P Xm˟l[JTvZm Gڭcj(P6Lcv\+ݴ .Aq8zm.וQ.c'4N˓ojLQiLhO*RgT:qc%aU{Ӌ|EKRlYg Ʌ8nȭݹb"#pm ,?d9 F*xlxcd^ؽ :XE2ȗ+mq٧ϥ-4r XZ]} oZ$#mqE|y'[WJbYE,5` Mx4Fi1Xɐ02ŒbϧYP'#+ a_R8,ByRW{$vPue01G[dvOQ,k'h^}Ny=7C9*FCfh<ӏe E(ٸrftI w RxUBdçadDE`ew&d:5{NbcjK9lf1.2H<˶A~ܾ6 7y!ёrv6AQ`Vٸ QnQTUʤN2It%'*~QjST|5/f̫ tp1i/6!4߽4UBVđNr6ر+)tZ^ƛqT$ ƹ؋|1Kv Q٥9Yw3(S[˓Cҩ1wGa՘3(4s(xooN(@lEEqfo"i!ΓI8CC~ ?6mCB6EOql8nƆHW*Kurȧ5<XRqʐ>Xի'ZQ\u]XppJ:1m u{<.&JK%qt#akq_?U MѲJ~|]1UtjM.u 7Upv +¹ɖ-$ral3@ [_wմh򊙿MEr.c 踭aJ} Dc9ݝ \YQG9\}WAR$O*rGͯ ,pZ{9K+|^̣LNXƱOǻ=3x2~In̮w3UWj#/үFS¦4w crqu d\;]ɮ 捗ᜣ$:J%J6՗snÕM=W۞-9I|."1Zs#= KsWoO#L|hS#oQwSc?")q NcUN<{;Q" 3̺a44pe+<0]>\7-YX9ߎdIeb4)6Y1p~ŭ8>\<]Z uBGշ_wV^5ctv*Ȭ%DVG*Nђωxel8]\6ov8}w:u9?P[ljY>;L* :ENrM% +zSC Ҹtߝ',Xuf y^S1` Ka1KϼQ]Ҙ)ABǒ om(t+K e1tU vawb҄m2qe;2"ކ><1RVPSdTg4{k9c+ΨJd9!]i'ge*Y"G%aӱGs#xE~ZWu~œK ?Lzl*&~]oNSIћ`Jr06v#A.9." {@=~hzNOVq1'g4ߘ}>s Vr.URO;4ݯbQ-Mjeכ(y=՜)U3Nf;LwI\ liϊ3G5k8>'ڦr6oU0ݭr&JbhT[ MCC؊7CSZ aBF7fx/Gǐ)c K8[ż|LSM$v%"k !̞jƐ !<ȧzתɊ5V * BU$P}fZ 97 Z"z~gu!Ö3d~30ٍ\z{6?%XFW=3i~ Agǚlr{b׋[}Y9%O8T d0)n-hy)>.OլB\w%5E?;b +iy_& {t: LC %AKC6tx؛l<BBxoW~ 89;b0r9ON!%ՇO׽1b{IK8IV<&=1 %9T3֌8Hm00y`2ږulɎ (on ta\>`/m8BN^I5Ctdݮ{Y5ktvbj6ϡnF-߻ET Z~ ԒI1UtETtW.8<:䈽S@%Zf-4xWk9{80Ham9 t<7牼eBE IW:%;úsVv< "Lwٴ7Q~~!Q,4c9zfj R+s1 \x;%_S1/Ld$a~pw|'1aZ4̭­]w 9t<e__ޗ- Iezj#w]8ڟ.dhҾ;^qWS$h:BI9jTWE F3 ^ |8n^0ȓ"w:}L2I檓Z`g2r|'I0oknp=0lf{ a>V.-}qPb*Gg1\ODjsT{% [.% y-;TN$JFb? <'6 iO}rZqehg2'P?in兂@F<^ l]Dl^ &hi+\%s1R˜rfe'T)IR )_\l'a7[h(##=R0ɤSR {R3}x4Q kƜU,y Ʒd+!siF콞ܲ `wnw*ٖ#];Gr(V^KUf_jZ/QQXbNzW{prAh7]zM>d׾&>ϬY[c{ u|h THF2oq,b꓂ =Rq?tSʽ&XGr^><*kX&vycAh֍ώ hm"{81LЋi[r-Yٺ&iXG).j &bm~dgSC5QSW^5#W3ݳeRfz^#E-*Em sJYRr|UpsVQQZl5\Pn"& eX=;4aʀ xsVgQMO.'췎7`+ӉE^}JMVɥ< 73j™xݗKEc+F0HO':%K} W^uthVͭ93shf.7FJUTͯm%+l♨"vWR44bw*N5VTTgT,)er{N| ы5v K=0n ۢ#Qe[ƪ?YMtHJ$Nps9~Nd80Lqy61K伽6 i̩V^Z\eηa|;B7Y4A%!I1.n"2C #WlFH7wǍQIyWARTS Ԑ/11ɏ~˷K4f#oz*dPm a_7r`۾yM4G$D`%ؓEzHlʥ|הrHNZ9/Vs@!w?.%ʲ2LeD$IJ]Ø(#ѕ!g0SC FٟUὼ c `v D ղzF:UY˥Zj0oՑ(`}+Ly\G2l?yӠ;,Xx=ďg<BiTI#1ƶQB*$Pp.&ɤf鄄3uٌZt禢w5Em%)2";*PV㹶nUZ~"BCbTVBNr<~ħ1E0k.=E/"Ulz[k {$unPϻw75_hi P\J†b{Q;tD?n\lofsǾN5jb-|.ξTrY]]ƢL3]C=~ `Nm CrjX'޵Nxo`x==?F~yӁLxύxV(`Q%NI>(#@#A*1ZH Ԝ\=Č _wocU>\ʉ r7L+F4}@.L`tvtLZ]}ٖ'10М3ƛv.P'D){;U}>7F_ˁ8Y\oo_!_{v'0{eY_qk)#4[l9FeT`!lY7O ~/tx}\3~)ǧ&tb+Z7 =( aMh?Ѱ4FM+ 5 "U$irPbK0 ab#Qбvhs8RqZ,^N+urֽaF%E־D:2}T:\R ylFfoRhLIDq|uT8Vmx<l>̳L\Z6XIM/-W1aS6&Ռ~Vd5jbyQWqc_5M:3xVŁJBQ(K?7eKgnլpf.#tLC}HSuWjj*i7]õ"- 0Pʹ<ֆ2LB-7 LK Xi6L綷+.s檱!EkOkl=6Yqp%ƀ BSPP@IDIi/d2k2lgWp7WΛ; ;ɹ9ށl1.{o 9l,ǘloEgMޏ#DO")vb?'Dڗ@fB(wF?CXo4Mt6cT?^/Ԍ~ % (>*d"T4165=۰T"6֞lӝ_g;a`ًE=iOΗ> fv*͠O[Diŧ_AϭH^-S=2awp(m()̹GU,v2YGRbXG/%ڑĭbV ~_;Lp]lF9G?fYD0k#X;4gt` ې+opn ՕC! e 1 aj-~5ClFRS|L8ޘYH ,nU**ƪ)u^89 O(瀘g/3'k0z#i>"P^ dK@01 s5,TM66D1k>JnU]*3%l-'~Y\ Ny^D_ZɇcjCT\shZh1Y)Ԝ|O +wkj1ѫ߼ewTb,e_|)տ k CsXAs kCc*bVU\ު_ ]f_5u߫^\;T3-bX.rZpHzST-SYH hJH8V/VO廰;láT-MSZ?Ix\>Ig_+ubҵO]L|*(2Tӱ O#J[r쿸y9KCUc 3t\kzgxj[%KEsMJ}:{[Q,x?g5YPt "3O t@w;v5֧㋉JxҀƴfgF$9avaMIyn]y8:swO-[?-'ګvbwCrdKiRJ 2PBp`ńV ڎoDq 0 8>G0oce̎^M\e@>26+3)Rg6Pª\r]x8/e?@G%*)1VO52c%UFVRp@kDHCzqTPT\x_ʣ ,GD5{u &gp 踜WUxlвxx5?9HNH &d0PƟ3E4n.߾<}(^Ǣn81Ow&ՊkQSz, v1[<(U=GכoKeBtrS %c(ZY;e[J*'yO6gۧT6IK[bŎLND@R69=.Lr3Uq2S9ɆgN~f?<6f ;[a1*6􋤙NͪL8*C8^~z$-r|9[U 1N.sqډ$V0 bƩTo8 K|UÌ<- u6q<jR>hyQC&uO&A{QE]XPͤxlP\UGLn4tuGvʉgzvM`Bp>s}p%kv[KM7ִ&c<}-J8W"g$`4[ːC4ۊX-۸X. dBSK~b1mnD#&iͼ*O a^4y6,?h6_}ϧa^΄ߴĻ)ANeїm0r21s*y)S>حb+݀rL"SZT\nÙ *uqw'8Db+I]㸻.62s{ŹxU|RZ^{%c]Z,cUtWO}Mw(ϥrI$7pٙKy@@EMCN'(0?SHz·}yl"⩌seTϑBf+f~2wګDC M{&< >0r5X0[$pWy􏁤,-+#rb13 ׷IJȱ(b&'%Esjn$yb*ʫoBo{Q5>XC*Wu56`&55|E,.u5~ZC}5X^ۖJ2Vak8]M_Sa&aȄL (JNL]%B̠`;'=nrG_'d"T9ձ-?%&MV?=t+B+Ҫc22X_Wj݀WOrPpaP}P 1vv܈2ѣ͹h߭h? Kg\hY+-C;E |X˃`3K^gkA]e_Ȑ_0&הȧH4)\Ѝr4KL7(Ewm)^HQR\::zV#5lbRI"UG,Wq(ex7#Hԗ[&dRٌ-.X frA)[ȑKU&tR.XΖ ^Wfh-z)3nȺF]3M&^5򱋁-T"RjbaOFe<(Lڭ̢sZ`s'V>/-Ĝr)Xȗ&zzW#]Zu:~%A*2qO8˘𶂃Ut,JR*֍!N rYwq7„OWsUg%yg3L +yB18FM)/"RƍO4~8G 98k&̓ 4OpOgQE0!, rld#qاDwLIX-XN/-{ 9}bҗxJR8Y'WRy=YqíS\A9xC4 Ԩf2̗"g T8SCz-m8'%=)`$'x T./;)A$WdnOǢW: ].9[b$a t7kQ9c/ģJZ'O'{q)i_ldprU2AT%Wo ]qG igvQ cg:Mkɺ>T}w!4L Y*Ct=d}r2?Wsktg0M8~F2'Ѝ?ƵeZ0;s/_".H׻lVu!ᩙdK*k\86m,~t/˯ 1߿6扙 {[Od;paSf;/~Qv @՝3 y[?w6sr#FqSA?/I/ fMCw&8c?ԃ4WfDcT0T59j]7¢2(9&`*0a ;<ۜkLFNb,, y:WLb5󹵘{#J)BIWb@RDQo꘧䛞UMMl=o"JAF:2X`nQED-UM\"qE2{V6+V@\~t޷|x^\] zhHƌlbtْǹ2W%dz:-4a@GYnԣ{8v^*\UCeJ%&n df_f%gz5(7p-rAWj1Ú5!<;˵%ihۤ*oleÃoYVM[/ݕ_rCI݀L<9[04oIuT}>H2H'ќ9Ɏ¹Ϸt_μLGf`[_)\OE-G`YLJZpXsWzLqaw!|7 仍7ʇ4-J,qAtӍ]2>uO#%)%, ?-"H%/&|'K;j``n|9˟WBT%t* VZXaz&GFbFҾUR𰂗)g)W&^> H<:O/<Ҷo4ϦXG 8Udr-%tهsqrh 3MP 1U}Gy3h=xu0b3g5'}}j3x-t kDš (tQldnv m7i.|(gzI;FooTxG1'Fh?lHdEL-1;cӂާ.c@=t28=[uuRa9n 4WXR),qa1v} AYb<swo ĸEIY  : jU\I$sު8So 7[aQ5J~s,R~x*X(4K/y} < 0Sĭ-`WFϥ}h=[w1 t({!-ZFt?MXv,|fGTw,',Ǘ8INE^N{rz} j(ΘM6Xl6meIřJޑpZ uXyfi{ɍN sOw&kƎ=0z 5( HƱվ6ٔ6>iYrq˙FVFmoZfL wr/n@-UkJr f:/~9Kp.Ops}&GaoYOQ݌$iWyz(( ,h̓aso=p$DGs\Ͷ~1LOO3mV# t~m:O}F䮽.<C+f0>+&q 'BGڬi8+`395T5PYbd 'R5\T `R옜Η|`+NY5Ubc!aB((,,eoCx4_iHi ۽B7`{mRqWʞs'O+\ISR MOB8^ȳ=0G1)t ]<3?ARn*J&ީ vG9ܹ5~<;_kP/K*O>=8.JD& %0D8YCpͻ^dv)$Ls& ?J)mhyу>lR?Mk|Qx~My|ȯfvo-]8!B2s;{3cnW0q_Uc2׆.mqGY+%ұBpUE+:h_&5Rߗ|FtV&AX緟|6 6y7\)/ lR;ՒxVW;FD.|#x@W\~zsgAQCyEZBܮ)K{Ȟqq$5eqN%/ eU,t}uY)[)з Kr^R5 N*W0Vr5ȿ+V#dzZyC흥( }zPr1y3h,y1+KԡC.%,]\ ubKS{=)ecɹ.c6*&kΖ^̇6ڛum+1d{I VڀJ"U? m+,r jW2M*S(eʉ(('El{$yA1IJ:OJo2lBQ)x1=95/^Mj/O}pV$X16=&t_PTtg_"8ρyܳK/CraPǁ;bW{ɧ 0L'+c%)4CB6V.}Jm/zC;zH2:ax4Q+ȿQ|4"zͤ(q#6Ո' 3wt3 G8{OD67O6<>u;Sm窮,z7E)/)61$*>itSKcAojWVgS'伍R^/99Ȅ>>fyB6o$'RŷnSqeU2vY:;Bleq6#g&)j+0!t*=f@s-Jɬ/r.2NQ0 NyLZaҘ fN|X ?`: Z9Cbu,(E9u&W_YIKSʙ&0A BwTTTƪ1CfSڛ#KI0H3%u2oXo-GVMD@xk;-U.p_[vXf6K#zقSq4uMY`NT(0dw>mxrc'`͛H4\RVM13Cu\&0bN>3ӈ@-&ss H$41WXB8Ǟa{ci{ɴp:dqՈqo6#zղ~:p|$|"rQC ٱ1ϷCsEz-^ө9%cq]#T UFCAF.ĮF6X6_ˢ:nqOMJ[p].T< vTtQƕA<))KZFB":W<nKxYI= t,U.LmK]ďb,JXp bGlU`Gd;s`^GVuY-Ꝃ|  tjWk*jY 4L&D=Ne$*}Y\y %᜝ t*÷1.\lĮ;{bV(ΰD>\y/+]sWDfE"& ;sYWJAs1Yc]cDG!pɽi~$qhGL<{y~'s/.C .䩹 W~)@.B)cގxL$Oغf=e']Ѭ BKE8%_2 QZT$w2S˷.ܲ9΍4)iA-(ummmv5})LTȄ5RfLY.VSG5qձJO:1kǵ]Bz]RV4ҢK+ӲJH%χ⿤2qw$))!R~(ߔɂP詔Km%TCm|**\f~3^L+:7 'llɛ^ٲ6h'`J-/#p'E #*ZO ~nT3Z\*?4ߟ^+ٻ\ϑ/҇c}ǍY0$nٱ%֎6a, ZfA.3Ϛg^bQk\ hS[4Ͳ?4 Jl&\ulř!lOy4`hfdmSօ*-%xʝ1Պ{:];of48⇨n}ىF3N%1Y 9#05V{u=Sqz^PW l:m)H9{K† ˳Ĕ-a=b hk9~r εW1u 9Ml`v+!{ZvN`g)cQ"[qsc[TNOzͺXb:Ëpj] <'7vC8vh"7_R13ӃakE0 HטLvmPB,- t$>˖E)k_Ȱ1V8|8Q=?p8&%b#8 3h}n qjtrt Ew:¬3իR9 KR_]ʏ*F5\SEC4hJ|?*p~9viڀN# DXUT7O|N̏WQb̓1̑ljvg¡tv<}7Edfo%;*Y>JOL^Ӎ8Jl^N ['0FfBBhDa;|p% V XZ.dͽuk0+A6<S E$%YZ $MjF(y X%h:m&rq1,ItF" t8ymad_ c$7߳?#x,Y7nCBÜg_;[pP&d[TVgosskmXӞm0ٕ]: iO&Etэ'DקʚucXҥ{<97 S&yLIPOTxc4S Y8JŨZa?-Al)gVRbl-QGG ]bd2#t[-CIZzHWݍd (뤧?Ѕ[ݨ{r{j;n6(;2?$Gwim|=>:gG4?qHAЦx`z.Eu4Ƭf(h-Mz+зnH#kFڅgzu&ϩwn"%#Qz&Pݎ[)E=DN紱)zg{faXՠЭ6Yp._Cw!Qv2|TP3 RURw4l|a2!Jp^@'!E,ajep+Q]&XcŎ;3s<[z8 z#(S? $D+tg:|97ԋ6$ѫ8cuuo6S(ccFgtt_g75wXZOGd7=;'xn ֈJT~rDjnV ydAIg WYMǐ#\W(9gqO,,sO U( q~nWf;\9:mGҼ;u/ xUy .X`b>IŖfl q0?`܌-߽ȏq3bQ ?'*E9cyp-Z)@ε`{E( |ȱ81B:{qa#fxw$g{p=z XrU`M:~7}5։~ǎ Ȕ[ԜJp(sc{r*\5ωq-#Z_$[ݦW_?4Zq"X4fSalv|W/=#)sg H=݌D<ճ*e(!{JqoX*+Cxcژf} `׹X*J=I% 59'Ȱɒ9LCaLJOn|2od0٥\1섎'덎%_z]+7sHd 4 5k^3,_ѻp:--9=5Hؙ'#&-'ڼrZƀ~n1,hF`ZBhqv:IV!8,\` =QT ǗKbv4Js`]w#15֗!tETF4s|Qy!xX3EDjm l5q`ܼxōz=]0~hb4>ꑅd y.{&Gll2K ܰO<:Q{*0^ɸL ֙ܕX2ϛ9}[ABW%HN۲fݢ9=YLiqvep5Y>-4 LѰR/XR2NVp2VJIRJ0_Ȝ BJH>bڟ+B-(P@cJf.!~_T^Dď0F| $y ]S)sΣv# ^buO)E킷yrQTph[Eӗ<j21tvv2?+rC P+#-%' Q9kb'a Ff$3̝H#+37UkzVd# aQgwƳ!AxEǾJ)-$L{˄ I|G`'&{=DD.-Z rmޭzKCn"u3øϨzUBr1D.R;QТ;p䮌V3Nɰ-šr/%nkZrYfq TX;*TJro2@UՂ|U䢙U.2 QRV?)ź,A8)bbzyq1g8oOv>Lt}_w~$!b,ԞZC&/qc9<4Up|PoquiWLLq1p 2{x-q8"{R'|Hƒxު|pޕ?#\wrG 6IȲ#{i=k\Q܅&v#^$a\ {D)+yô6<lI5\J<[WWfteҮ[QNRl%jn;怨Eŋ'.ԹJ,#x>{7t.q@>& >TL|B6W|\#A\JP^k{!#hpȻT*xh[DŽF{ehi$T5&RwWIN Ǫ9Xp2v02s!2DC+#meOMM*cir95;j pl z}2相HeU_\_,2^/CRbA`8i>SGܕrL/Ĝ84Eq\'W{ tp*s?Ύ"왾َ %˓&kX?9=95sڌyځ]qa։"_#o=+ٱRہ]QJĴmCH\r Vb?1-7SSĢc)@єuPPbr$W%>>=Y W5c̟g5':Y) 8J^,<opb͕zE,=Oȹ0HA XiBZas{=#|^S~5ST }Fh8ĕFZ)uݭMyg?uHu#t 2RՄD#g =C7 uZC)fDN&cQ:rqnq.;7&b?,h,FƻI$Ncex$ym`!4y7mY89*t28k]y;;q;w@k}RǬqȯ /w Zag]?ih]L=9_ ֵ,wl zlf(Ys.?H=A|a,\Dž~S }RNjj-CZ.s鼎u&IcYeyM*2<51RoTOb EZ}ВUO*3}\g:FꆁfC9"|Qu:~ftoiV[)VhirOE?2߼6=#k!YR¿uu:)ʦS*ŕmxځPہ,>y7Z|aJy - nĨ'!z ='k8*gp.l?w6*,)Cs-$#=mK1TvtHrIXNFR6Iixʿp 'P(Խ's'cxc'e GCďJb giK%={Y"*6/:8O=] bח'Q $w]o&ˍ<]ֈy}ڟkK8]jδlO Hvlc8wTi[/::<˰qBVeuWWBZ'+֯1fHW8(9z3%鬩]q✩f룹Je#DZGѠ22E\ 1 o78 +-誜8SLГ+H1ϱm\FM}CH}7˲l3~O2f C>Uiou[}rPGF~*=e^HZbеz9:'qgd}DjsD+SϑbF,kITu*Vz)M{y%/V2m3zNzt(R~̉~SZV~ &013H-Wu`I_T<͠lrs ssP$5Sj,l4tNdRhC!׊K=_lK=_۹<H) e'3']`ZCMVԟĻxACpdСMyq|L}s>Gݜ,Vīax<4%c;?b7 u≚3d; YuІ]/{!8ڍhOь]L? U7&o`M*2)`p:];qJ{q= N_ai) c򄊻f3g4rGU֌rd2?~zLjc_˘_ou>YF;It~66"U0T"VTI~VuocbޔOG3KћS  )grjhWSɤrTbZM9{l H OÚ4hC? //HIBe9UZJ>e,6[q{$4-`.nbNYasCR}?ӵ>@F]vJw=j3^G6tp'FP [@d'쇢SC}ft3}e4secQ`u/o,w 0؃j)|B!yߍ|c4GEs k27UjYpcqmQLc1*;hwڙw]Hfӹ<G+h=g\=EM=k=̈́mZRUKƭQ?.Q%27f f-q?/:ۗj x50Z_ bl7z;R ]8sڇe4Ǧ t.ѽ {/e/ge^)Y̽#|M,b>)&ŦWIʓ)M(V.þU r>,cg24J^JägF>cO33o D6LGwh'qa&rH^PD jGNZ$-ǩz1f|N@b…yq4ݔ9XS?揱ԭ1Qpe=hvӆ[uѭՆe[ݴ9V<]DAx~Őc̘̝8͉Vn*C*-{hk29z6S0݌ͭ8lcwk[jq;f/f-]yNݙ$uȫс|æ^Oӧxj80APT^?DMUۏJShD]$ankl89ȕSHK\7~؝g*o,Ow!}#aE4͐%mǗ>lntϕpw| ! e8)G_'{/ա[̡Rk`*,Xj7WrSeRL%U2V{&ݽ??â^xp`=;z١Q`EKGtW@ &6N~!K?IS\+i r&ͧn2*ΚbރNQ{\f|cƠlvLAȕ?tѨC燰4eXAS`oZͦP}]{~{d3(^}o$>o3vd"^˒_Z⾲e1Z^\aif†.f]EAL 2`rA=cCaJ_:TqyzݮcbSmߖkH=ݰؾ2։- /l9dzo(J2b͹Y 9]'p@-r]RIUy٧9o20Ýxؿﱜm?Q͒?<˝ӗD b.o~ V/TJ}qK:_oʦޜlYfB:u0qeVǩ*W'~.堠y1rs0IT2jfm;}ohWv)P(䕣>!xKLtH6>N:͂,*~OzgN)Qrj:Ul" ]KB6ߑ~fIAyƏ<F}xÍ x@^D-c_oZ;aQdFtzd\!7vrc-?~- gDs=CKT9Ɲ_eUIk%qe(?'1ļ$udA3=3F .YnJ '-*7 fDfݬќV'1% )Os$Wb|%_mw:lM 67ɟ>`Ƒ& eAwnShfaT; JRSJNVZYFueag2KSiORӝ/,iRw{Brt gdshs*&!cأ, QL¿V9ˋX+,BX}56ʷPkQwZ r ߡ3zx C:r+Wr%Õqo{/ӣ Ӛ&yL+=IDnQ7?*:'yٛm.hPhR_{/|1l9XDjˠдБ jdM9 av+vMy?kl(R(a29#hĵ#~,ޤ`U=]ۮpXMGyDI vaa&>oE@:,QX[1Yalys&-糹^)J'2$bq;t)txL`\M9b,=2 W޲>_`K3s@C[Ѐ 轼M-:׆z3\%8Z K1+Cr֊Fy<UoDl@ 5N$f[X;0/z}/B{`;ѥW0'y1͞pfQSgqqJw}v*< 59T!+,Nn;`&[JsG wJgfm/lYȦ6ꇳpq tZ `Š Ó$8(՚y:PȐQH: Pl]Ɋia}W ;͏Qh%)ikǛ!|Lp?nU 1(8e m= о$c#'?ćE~$_1>h򅦜ߝ^ wS'ǃrC]k(4NA 7ñԖ8d̛Ʈ|I?w Xݖ1p8.S:}̓C~d@3X8:vg$aQ;!G`PvTanK?! R1!K )Sr(Zz)Il0!\ҫtϕg_<Fn7zQ@-ۊ\ɏ4ra/8̈́Ce6Tv[{v˾UÕ&B|#f;S\fWM*X73F3UJY:SPzO\pf<9]e\-rzK!f,ߖ#5ɓftp_m3%Ջ }9MT rI&?eQ^4oWŠ3$=.fZ,xØ.ȟw7 S&ް'j;nK}Ax/s-81NŵZ,֕KbguS-x:&wbA0W`RoOFnML{I:W `Nxj%sq& 8,aV.z/}8 ƅyux]hM?@Rڄ34l0KYocKH!_=9Va _J|^B"~OIa,C(rT-]eCᬮTw.50"d([Kze~sѶ91t^*r1;w({Tvܖmhc|jKŘ^MVw8e;->xtt\FƼ)R]Eȱ [jr`=Mֈ|醡۴jaHlWyЀSr8:v,Wts;uA$I|vd@|J˳S)HQxcSJ0^ݛs_~\w{=K/X+̏xoJn =CQJSJ]H+yώJ Ɵ=)laNrO AYW]P>ΔљB ozwߑD=Nm_ . 7\U5?ɘs|etBEo:nc\9*5yQ"K籰ٛ+d]&pGޤs# s{̊_>;s|>Ϳ'7s@#KgG#ۍ{0 7yd_KRen&hȤQ6Ck5M}fK"myw1j><ҰX}Mx?IYҟl0pӇ ov:KiQU1m h[HʜB^V+fGZsX&!;Sr(S\ʇcvb82ΆMlp"ݽ20_z)]m*7A3_8͌l`ΐ Ê6xKco ws{XSc8I3`LSvXƷ+@k9Ϝh㍆ƅo eE6br ]dKl7kѹv RS8ryq12af.+?mI:xQZdzܩg_VRZ0/;w`aIuyӨLfI{, عWLHLj-lCB_v⤻;Yq_0#cޏ3= }Dy2Ke^|ӸZy%,Ǭ+ kP'f舊9 P:Ȏ l=^Uc/we=-1%r;gg藚ȹQĬ P7>찧m;b[8em &Vp%ϟ9'۫ci[1uNBi.eR:ޞ|X]$_Gm>q9_2 ~eQ՝0:ix4ObKB'~/{fѮU6Q(u2N0WMx[#;Ugvimj9Wa|K{b,.0nɁj^h4I&[=.shI+\))Q0>RӘ7i&tr?ӣ.4*YK Y]!hbMsN1rb#ewGm8-"-/Ux3@s5>?vfYކF̌ɓDGn~ą_8:v&l?+:'ؾc>htd_X):eTW(}:4VoSbljϋjnoFtˠQ%֍ Dۋ 1YI:eL%w po{xP3$ u/!ce,McK#]ś9pܓOq݊T5ģ3gyc6̗;Dq7?왐l@aOVil 7]>ז Znw&o3 ڵj(uR~zʽ^RߥP]cxX)3ƈF& o3n DS޻|TY|CJTyf}pv%+9; &](ǁXOaT';Ӭ/nzr'9tȖ挚k(M0a˟8RP6MÆ)oӛ&eOY ۣM1x)'$d,qJK*SݕrKŔΕ㺶6O+3E aPZ1"X{7]&t Cαڟ~p ܅ڇ=)<ʨNhԗ|{ {w~s}'>yhfհI}Uɭo]mw$?Ʊ&*OvJ-GMćEl%GDٵbJap9VlByP yHo6=&_JĽ߾,T(ޭ22=CISjirn,q_޻I 'Ě/}-Gwu}wuv6ft1R ՗3 Ž"T1?@ܞaS*?.NT)GtڊYW-I*_ۭGY٩k/b 4&0`f =$gwjEG\'qxC!jĴ܃]N&kn,䦳3m[FA+ ]G<%{#V¹i=,X2O,},Y9r/xӉTdF$llKZ=uM_0mآTld\?>ʈUɵʸ_].jWf7KEqX2NVoEb5[#6v^3yh @R9D j(;_qF4sąEc"o#,'ue, w4C&"26υn<ŽlXgMZH#'_Rie>~b|(_jSt1Gވ?B]31#r<3;{(^Mz8ܱf'ZS=(kX: u9ȞWijL[oO'ņ ٕ5>`X[N|o}A|)ll8ލ?RkoCK=Uc7Q]Mڡ3-ïb›1l/qH+bTV55N۸AHMy>h;O \LKk_;tʊ t>i91 4CYM˝xM&&o%v".;3]WDXMNW)nIS[ΰcc{u&t~=DbW;1)zvU/z0!]Y;/.tbU-Pܛ]ߚM#t_w=+&|$Tρݾtjv4hyoÏvx|ߓvNl[']:Ӂ-1LyF VD0[պ/ZPW۲s!8=z0muGfW 3Gے_ߑTttLCRsNԎDl6Ѳ Iҟ);ql:Zk;;h#aٟM*]{/'qG2}_82hP \ثw_u?TO߆eJ}G8+{[H7V$$evN[,Q/3iKKv5G7M[0n^k|BWvONO9:-Vvc. ޿vgPn]G/֝ Y(:녙k9^Gzd;Gjjwm}_VLMeS?+;xK w$"̃(qK 1sRQ:]b?_OT;1ee33=.6<-4Sײ{+| 2m;zZfΫh Ǣ(t=G`B.4w#5g5f@#>Z+Kz͑ {l^? ,?l,{ghU+˽řŦݧ.?!{qgр.S7wg]YftT"w<a7 lցt(Oe'ž-–C%~|N GSX;…NdU_ʝ|lņ}٭ۃAqZ7{7"R㈞{4>0ґ<w ਁ5v#GD6茦zP.4cdHo7ۼ<7uvخ=MdgP֌yV83or{(i).QrFP^ V\}t^ҿΗNR-~l4}DħwMM|W7+lYoEv`yi=E=Qޭ2P@­%e.tÞ!D0kDEcRGnрMg̴j찰?zXx u_ő+gR77$GcWۆqXrs_Iν9 *4`N}s[:b\cfaSR{J66Au{ 6쁫x&÷)$Jk7}Xʒx'b浞?:=0fŢц9?uMewfg9`_ł]}H<=fb9H6dL PnGx #Ws >L}3hqIqxkx|[,#|()Wg (Z7!8UjƐsğ%5|yP(UnFc/pd8?#9p3gSk7Y1XZ:-&z.B4v,4¥";#:;sc21OMyec9*Ü`2f8 5zܭe^xxt(':?&cfY<ޏ!TwWxٚmx| w vYƆlNΥf/n+Σ b?bcC~"/Nn 淊"so͵;ƦPKI$s(6yyނ&0 x.e}.q}c8ǝ+\d46$~btx6G}(}t%X2;{F?',h4tfє86p$|_}:יC^a'mkjeZq2|8{-+I'"t>)c T {k)<YlYʯ1KӇځ<͉X_?t$SBuޯFYqeKM\Rۿu4XNGYdSi5FS?[\2՜],ej4)|4Oezx>6#) [7'3>^rChUvóaX gǬpgN ppMek~,sPrq%qoH<?* <'!7;`gi9VUy҇>fNI'EcxYy^˔ nh&ۉ*cCLqfv,6aQ˒X(SLɑ!Lʲ(kg*wsq_. bB+<7F)Qw2KaDB]'4bG'#N}UZ>4+yMaKT̿ɈŁ"+ʋnA(6X3%~>ցL8F{C[|la I]y6֭k3033:$e!3333';}ߗ}5FVZs>J~clpfy)x>2v^nDZ{?LdV ;{#^Cvmc/. Ay89pA7 Q(nqmW9qɛ,Kߺ'?l5yr]IѦNe/c^0ek7[tOۦ/%DQ"VIq,( lj#*("Cr1lgP򹚙}adn|r(bSkc3DOD7uZYtqgNe[Ŋ5 k{vQ$~8RniǣQlPLF5fAZga{ԓq0s"#Lg2 J7ATg]^rj:Ίb}]m'.bFv&mMzcRuV~^boV0x7Si3ilW"zǞQ̹~L]gh}{Κ bf;shIK+V-#ԖU)L5pï"mZ%25)םX,EPZ99qĽ ?||z#;yr 5#5*#qf'cЬ.bk:?᱑ KT1e\χq$D^Op2 YSJr \U(82x3ovSļ0:S>,AJ*2c&z ީGѬ0b0nqԥX斁?}MIOolͳfbkЗ>)֩٘?m'O_|gR`úD۸h9uqך\N&oӕ&f77Ś8 lʃNE7& Y;_=y;4q|.AUBt|m0W8r)Y3QVir-[Jt]-SL<К2$"o31k3XB͜:Ŝoܰ+?dӫ]"j;{G!>\lsт^ df%kk&[r,ˌ"|-IYfy N1M h/S(H}(RKePB]R:L*r" +_rάMcIqOtd?4Rm4fԿU1N4d.艢(k=eU1U;m9&k=2}qt%82# Hup_gTɶ<6&$ݼ,:w`bcyyuPb4nCITi1"tLO&lر"~$|%֦/FX`!"=ލN8z{m)轓vLG| ՘gά7~X=_:ɤ dC5* (ucn 7GSbU$1‡e nܜS̾q,E$6ff-uPg8z'lTzNu3DOps1$LQFr< xVփ/IB@ T¶{)-KS$W$pUG3j( i9˝ h.v蜭gcܱ n( xsk/]0;#y9Ř.&4=(3S,Lq>eIGo`AgVҬm9ĀS7[n{_ _X+܆=DsRa*<#aiJOp4>S|IH/Img:uCBphϒ iv[ oԜ Y5Vk|WЛ6~jSK.?2/aVY<].ya-K6I`È$j1.?3x$ WgNV^̷ u&Fs2SDb$G@k[27Nee~;al,(9T\i7ؽ(.T+ }#<5-g1{NvchNT*h Hu}%fK7.t C&a Rl[jjd8_K9vL^ѢkWKL)d+Us:1fhӣn*'YB`3ٶ4vA|foZ?"` k:~ǀ/D#Ɍ.4{=A-4gY&ƵE=upՏmȁ)Βߡ/[{pjv[W>MJLp- r,R3;[L@Wח"X#Kr(OAv+'3NmJmoP](eڢ*lҹ_I1y\E%ZJ#c<. grK X+V7X3fc}"T+g;Yfcj3+OPK`JQ"4p*|F(T.%RZ*֨1x}'\?! o7͌w ݾs^ 3V:qQܡ4>b.'F )d$efSp8l O-X<͖slD FSV'm͝FzHLVҿI MdZǓW'Gș:gG.AGhދl̗ۂ)G.c?v8c'2(݁n\I2uaW'Mz)ލI]9i!\1qtiבuSh/44ٹ=4aPցg-Áw|0K J,oIΏণ7UNb{8)2"oLN`VUM @^?:1-#n9[EjʾgqIʜQE{o5]!B pA3MxxI֕c<W8jj< 38s9r/❅kMʋ Vbxڄ`IL680A[`ó^ {ͳtq*1HQU'B5tƎ?ViQgV½Ӄ BW#v|G9ZVXd3 v}eVǏcω٠ƩaD]cXnEhbFS^_3Wc<8:Z3^I}I>>/MH7d[YǕu皟y)\Dqq>ZWp71U_QMj֞2l9'qT Nɩ>V]])m@5fik-"'LAKZ-3hIJzO;}. A4Oh?rk+M tw7u#uKzVyxs;m2:mڗ̝p-7R_ӦҬ#;ZOZ5 1_ wէ.߆,%xV7i;S{YNUAi'u Bn`K?I9D6đmŹ4#ا>8tssf"\؏Mco.P5M8vE{g/6 g$M n9)WFtnMD7ˆyLe 6q߆E8}O@<p^^vi˥?nʉ#^Y"d,8؊3fKM |7d;|^x1M NUۢ*?ߡjΩ)C$oWZZn1V]V/j9cՐ#34Lzl2b+1a梅,JbUN>uBcw,{NYhZfńPo188ɓEz7sN15>Oa?hd~2@@DE9ǕC>qJ\hW#I`l3DE}y>͞Zj%z-\G]Uyqctks7d<*bܮʕl,dx4si OѤ6G 7Jq(`T}Z$]b-d3ZN. 9)ےⴡ|ȝ Z]7K]n?bldKi7k&76&t(c쩈=&5!SfV1c=rw0Y".1dkĉG Ѫ,?M)ÿ2Yy)ElY)x#$Z]CݩQQa-3iQ$)r^8z@ͯ2[naߚfN0E˖366m51qn{Wx<p(QWEmjDOϜ1`WkjY;Ķ 4e3J~>)ft"$~6a܈"@U0N3~M=U隙ZUFƵ2Jcr'SY1 adovSo\u|+%g:VrO >JgMѣHKn aۇdbg#{ghx.8apus'kϭJ{iZ _.Dt1*hg yU C\*(&$ZY:3 9lBbLRky_&C JXfrnoQTh0:2ߞ6\3U`M{8q. JHwd]qWO}O[xChŪиnb}Kɭd*~qh?*D]3<A[1SNj*fW{5kH)!r9/)}$g-JAvLJ?zdyg}g(a3~Ltk6{<&^s}(vUҘ\o0R[,c͉G#EHeš:DѥBunxxjA#/I}QrB&˫Nlݨt"_WYna 'i+@ǀ_ q*&uu$uZblR8=?33О߬ʖon|]».-BjSc\jU͎24DżrMr?]iq(*, x(&08H)BϏ C#˒E)yNi@SLG,G~'fVd.ʹi;K](Y͹vIvXqBC!,6za(+E2 N ;+VZ8Xhe-"k.1*ѐ -j; ^Ol!#=ۛghSO,j:rv㥄_d)kɩ+VFE:r?w"ZB [RY!}5(\D ywVxQ5-> :p)Kau5gxp+ǓU]s3WEeZ6D+$]4tNgz`t%:OCIٛn?(рvFЪ$񽟃Ćrޥ<3|9ׂYjSZOh-zbViSf)w}g(~lřw|:jFg]8hÇܪk-8_-򇄹 tg]b]8vm&d1UtdzR.7f{]<;גiIʾ5p \ǟ֡NLu׫-9 CWV ߳zŽ[1/|oD26oVLtt͍M|ҟ;|\A׽-H爩$G|J+ 6gz`>EnOSq䬩Ձ]4TY*M P%*9/gI9ZɈl&ZUK:f﫡ߖ|FC0)mX߅kAk)lې+I2qbp4 oaK'̈pl9q/ 6s'&t}*Qg[0Qpzk4#_rQFb}Md~/_m^T)_H0>"y_ZͼOr~֐:!Ð뛌kQ.H[\Os=J +9Vˏ&\K$9 ~ggSKO2~jۦ!6dpD v-8̯SCR1''7eq}q 9PC]y5hg^.A S4 z]F xƈ:vnڒ=چ~vDrf .MfR;C=r㲯Tw˖9x. Y4]$`/ݫ\dGgz:+>z"R6.m?7iGĦ-ڏE80r7sA"w1tR }lGdkk SнWJ(s|kRZ-YL)o֕ZRCU>RN`ak3%7.,asV:~0 FlKPk6!/\4v u$Qg1ԪLիE !u'#W 3*1wdS5'a̎Q.אZL~*i'q>CCdYNQHaXG6-χXw%7rhG Oړ C*AE97oW9PqW9*{sUT GJAc47xܢœe?)s-~눭;慱kU*^B&o#+']JX/`S_4'(PL/l f3:4dBfi^I؊`> 9ϛiΈj{ԕ0xVK=sWfqYj1%Y)B%O)5V8AɷJXT)Iv8j(g@5ڕr2tb"j06h\Xvmn2OIl6:!ʌ=V8YDTcX:A'k}4<>rҨw[YP(W!&q4:ӂ:/1D^p3+ 5"/,xMS'㘔$TM= \σjz_N1 ̲'n3),JI.j[1q-ӓ6x̡vd)9*)lzfX3XȺY~/A~fqbn2G # #ٞv̉![Nu$esy!ź>/0xthxmJź:-)p[= PHE|ͧ;IhlMc]6(\ˍ: ɹD$g8"d zQgo*VsSQrZY:^#Lzux񤳚sUfmk_*Wr@T,2_^mW9ȂɶvV4/"<^5;xuFimRz7Yk <ܛ8q6qUgѯp-b_v>CWQBfѶSmٳ3"s`5J9ѥQ3VsrF[!Gd01ALJzNB_ rL"y?_GKN6q)Fr`5Up~2rQrqn93S5?oŌdu ~}h%jss,Ӌ<]9nH{M+ZZ?>XtMG#$SFd8]Z7 <q

0,\3LA)yf˔:>uuf-]CsX+o`NGri,yWaʉ"猕 P2m'ݔhbѾa5_`Z"aUŷhUC~[ZOu)d ]¿w8y"x͗s t045ٕGr=0ɡL(|obϿح`JJn^(#q9+'e?G"pv) S\OBUҵG%KS+.m8mVKJڝN|%%{9PEsht ?׿.gJ"Wf/rTfkijc:,Fձ|tU0@fT٪d|5Sx۶jQRd'٫dt kzd'1<[Ӻr;=9ɨ$$ xڦŒ2.˸]}u;Y֋C칹c'/bSopU2i{薡/7#~iSb,\ ÝqjdS#f{)Fs iِž- G2vʌrY|Nʸ.WO>|VLq ٶ-S(hiWJ,&}&dT\*KA)) FRwoPRX%g+㔌ۣ"` Z) }QBmz%&UZ *+8#9yT8~Shf}шm-ۂ t_%y̓Qi?D!\h>lՊĥ*AZ9XYr{G9: ߏt@ȍR ?.7 3. _rO" ͂ \1ѫRGoJ&)U/|{dd[K5$5qJV0]R}^Pr䝊ߛ˲3E8P"#5ԝ]i9cgpݟovך0z6tXi8qf7GiC6Pꦯ$?MTfZ)]Z^^1ݫ i:f9Ǡ.ETZO9ˠd↥"󃅜'Y$vf?Q*F\̈^I9U\^i)K{!G[Z̊|6\͜u5kO\^M&5.{7?ulJI UGX5#FI@8/U  e*EEj( a-<墜3e$eCc-dE*[#Y1[XCB9E!IS>Pg``Y2 L(vD]L =fխ@D`}6HcnaNLBv+ 11rfo:DcXQSOt_+gXP%f.Jf KKh)GZG)g2s*~P_Fkgu?mms[VC*.Zk R$%fa%csH`{:xyoʖ˷95 9<} ѵV߷%b,KQF^π)ٙʤ|&68`tɥ\cl14(%iMGd,ۣ3}%cEa,~9|!_C ṟ#'g@U,ꨦcE=5I]_Gj wֱkdf99ր8NM+5T$~Q]ɪ' QrDMg ImrIײlng"n43z')-HaPy"mG'Scghk%4\!0qJy&erZ je,CAN9ch*E>7y62UŜ:ll^,ɠIjⱹDqtl4bIA{eS]f;<<]öR&+ŶrtsU\Gɍ i*z :.*zul뚊*JɌ>J-T`9]HiR2\CikTK\5w!̗2.*~قfjl hě?O|]9?դ:o?T sC=Dz4oN~ lPqēlO"C16gP l3#ѫ(-O?xegg@3(e7\8rHzno:ncMnWb[{%ݕ|Gx޶1WT؏Sa7KIQW@z< zrx\pvujo8fFw%ZrF^SGofU&bZ)c* rt5O/ aT<@ᇯ q+`<)AD1yT\XlN`$J7I8q;)0s||gL'|CrluKg.橄/eI ɐR)gsk0^AHgXjO*&c~CdTO2IX}j4F5iq_IJ fWyd*μj緦םxQ"֣x%(IcR ^-OkY#Ul +G:L°j1:qc4yxG.J fH,⑉ :8 я&3 Se2Y\x͈!bNt4@%R%(\ū+t+<)\O&M0"Iaතﶵ\7_#:?%u,?#oV@Ǿ0'<7^N tnK|G<1Os¨;/x{wœodo8"nJȌs!Ivg~KGЋ& X/ظdעm9)x)`rz9װ<2V}5VH?GZ͗J7Z%g/.+(mW?T4׀o=*T|:գ(#ݢYNi'7[[cZȟkUhֳW2_=sŤ*2;iz)vD̐Zd c{+Qpr| aB:]K5,*oTIРeT`R9TĴG&CjwYbfފ2BRր< ־OŻM<#ow^2{b285i|{v,AH#8e|UVQqm<' q%BN-hp Npwk qwwwwww'r{e`hjZ9|efNk&DHrBuQ+B0h_Z2[k8.>řTEQRJ&g+8-@(^sxL3mƃQϓ tL0c+fz֧1|3.&LR|7"OdcM Hdu.S+YTzߊiشSXVkܲ松6f8?DaA}B`*!xoczĽ "XWSA &$x>VRs'xd%]V]&?5ڢϻk9TSZ_Û *+ ~fVR w*~kxSz~-]\Îj GxrWLNWTMQdxAg<9l)g'=7:r2ꕂ{Q 4UJxw\/ 2H)!o;hOƆ/Jh8{S^AdoiӍ$}c)cƇѼMx[hpzsUQGcSgm 6kh;P79a=KQ M;ud<5X5HdbgMD]IV׺ȸOe ,;Jx_BEԬ,bV |JSoxg*1U*5)'^JR%R|(!1;)Xa)K9ӯVJ]Nt9QW(_q+ghKbmeLGPC:04ۂ@N1gpcw[;W-TLvjY2(kLA~;=i 8Xg#@ a /gpwn0ک H4%/ItFsڞJÞl}7 w>u5Ҿ4$J?{c˪"hhBMK*65驢\JT- (_W楶 :)ਐH t!p r%J!Bve7h-ػ/RM\}4wpcYKS :4P!l) Hy-vQ Y\F%wIcK%j#߬JP-e9K)-#Lx)r1^ -[)<-cI,W2<Zd)7)hF}"CREARqEeQQ8G+!=Lp<#uz9%nк.s~Fo}:S3YZͫs>f(Eu 3Ns~}1`"$&H!';X1ph<ȡ0ڵp@8;f<t3d0Ev 8<לpFmE7|SÅ[cЗF :obՌf@;[WԮ b0VD;k) AjM49;Ey<׮w5U̙S*ܪx)7Xdͪm'TU&5 Eg^EUt,U`AG29 W҃$YKp'?ʁDŽ77 n{iۅ/ mV s>݂=؂NqTe~kW]0mC齁0<-nq[ȝhF27ͻzϭaKZ,S W "xiH'W\c:?v Zv,Od} ˇy!F1|]6 jȚ[?a}({araE-641)Z(I6޹Ov8`J"ػDž-0ʜdcWYs#PI#TV Z VrrdlF#YZUcTYIX5{Sŭj(WK5_@ Є0&/m7F1ap^aNFaaFBXaTRaҧ’yo Gau ^\_ /+!kOITD4|)ZIR6('aOJI(g)ߊь(dǦB>-8~8}Pd3`KY]Uz)͚)VP]%sA T]& :*BJUK*(#NP;cX UZb*FdynV1NPd!u`?IlHXCGmI-§mx zްJƜ5udncj9>PN}9=y4FhD~G Xs>nM⚇ _l98V8Pp/ibf̈́ӕf .%q4ݑy/1dzhT;k|qIBCdsHALN&h.,WLkbnJM^`~4y)^(RChRÏ;LXE=\gQT)D k0uqCd%Cvȝ+c9Ư0A4nٞ=s_ M8*]-(-.n%L%8[yppFUKhIxÝ؊ {={|S2Z3DcoSgXii KIkUD[Wĸ"}&PZ>eS\ΕGeypg!GXݿs-Kd8KX13 U8s K ~&Y:LJu});qP 0TF ޾) eIdưBd`ۇf,CXJ7@3e)7H12w83UԼۮAW'{դ?VJ2f`żS;aahO-ĜԷt3.l0&|"e29‡nk4sیFw{ڎjƾi,7345Dx>)_ҙF\Ɩeҟ./,% Ne`&eYMKZjUFZIE,PS;TÙͫad &q$Jj5g5!ta%u+1TbA\B>w.goXLBW#1%>>G 넙M T/aH|@/,!Z%zd#O!2ywK:2סŬP)t?[DyKҋ63q6{v~uJ!%,o\*} 9$'w=Rp]z+X}XE*&/.Gm ]:H8X~BK4fMGYv\ޗQLMDWv;!4k|(?RS %kXQW'~o1JhԹV\N0/(B$sao3 P 0{=DZclo k$THZU1'ɩ ]Arꊥ02n-TIQr魊S4UC y%< M!mpjS1݋|ԇɮ2 I $t-դj,UUHl5휫7`Ѷ}عT)h)E3+ɶ7W̦*v*YTqh5y%UlWT2 =1[qO+oIQbz畲ȽjRt(#OB8rCOru2NJpi.JPPdzavr-He܏гƄ7@o0v h{nt"^w9{R9"嗋Fh5Rx̽I/aWH<>c9MʍCBˡ ub:ԄjNj-+zIt3uTШ)؎qxgGG1wN"a83}TV=/:a>mK9<ɖNF<=ɬB~'1ޜ6?!~3p"0f [?~Fqw$AE>ܙՁID=髿?mSߙܝ*zy2#cR}4-_ݩhhѬ77`/sq}YǢ}9fbf=c*vVҺu-!5D[U2i%ӤS%L*dR.UAuJoRXōS ~Ua)rRsU,p?RF'e3ϕMOwDSPlk[RU3 X,Q|ӑPu՛ ?7YsN¥hIfI4's-N{7Iy> \fY )ZobOƹ1;Fh^;;o0\6M j5auxrtlkYy;e%Ĭtu;ٙ$3yaɍDGb:7'# +_nPWҸH‹jkسmUY`[G"Z9f))c8V$ZcSiJN3g"ǩVζ x簾`OYez|W{Pi%dQ* blC)⼺1m98툢ElZ/c.9]ƄYX4[&igӈ€I$EȰTLltGL 'a}\cs$,vXϤKM'srR2pG"MCٗG/(:q԰'ߋn͹v4Nð,;S0[^k24/7gb0?-;gjX8[FXFv);5凋V)WK:Fװsg/j!A%7Ur[5RbڽPv;eҸ~wekZx'(ڼfaBhdt + [ QaN;+M݃N 0tP"oř E*ے8Ypӂ38 ;w3k5a?k)nO?(M[oc95_cެ:B53 ga gB`,%5 $Yr3,DUA VO8(FzEWJݑӪɕe0/d{.6bN°K VpM)(Rx%PNGHξO" RsLb [ۚA+B8>(MRp9mNO+U*'zJ!dH"sQ*G{PȥiqNȶg" TIdp^UG._$dng1Uk i) Rh$tvOK1wl9F Nĩiuə`Lb_'OfP WMN뿄E'mOOs;':-DpTYtJO<)u#v*EZK{\$30R&UZӮve%Ary =;ױy-+^K~Yh3V ׅڴ,h]6 }>I{,yęxw6cc*LAj6Y]XNǧ:]JBD+o}%kgB{X.8wCh4/(!]yVnRq}SYLeTBD.%\xf؟$_Ӱ%|6fP{(mӹ\"O'-7_N[Œ5W 'BE ӥBAFص^]uj7#PH)#5t]͖՜_QEF{VM'Z똡3mW`\6yG  m,)4Wp&>6rӆYB?4+$A;”B:yge^QAbrHpItU2 RhyV§"TDr&QaNy2WNl?G7B=2뙎OEexxq'zL(0x!r5nVM,49(VvQj V2AПjnG_@ g POTj. "7[Ī"o&u"oȈz~4Ϯ(?2/Rw9!/#-^]ľH'RX[5)E/1Fɜ+Df-%qeh eg=&TPn5+$ (kg8F1O5a7dHN}'Py7Qt'G[[#QGD0C;=Z'}7c Ogb\f% SI .i\ΣC"nB+Nqxفͳq,HƼX5 r{G*2'aNP޿'dhFdt̜ " CˈVLM)ߗ kqxSƱ[j{UǤ3HZSGɥ2v=r83fNS8l x,kIx;]9؊.W'eT51\hʹ]L,e\0*+OrdD29oeF0sm,xvzMHlVa>YvӘAFu.#hÏaMBtr:[Vqa w gq[Q VVڶTe8N(U;sɗ_2˟~,⸳7_Oĭ*lr+v-pLM";q#-)+ .g_+< Ȩ\^1q=9tY蝋"#M`4b9q0bЊ =Aw EF'2wbiHT.0/x;; _ ,Y4vme&-)jyxVYNet3Z+$.BwvroT  ZpEߟA#cPjT|Y'Jm"l>Qs=9׊YiIά;a՗k-+QHk\yHXqo #ՀyW%rfvv'nD&'ހ!C9'r77pXMd~rتbeԬwRbU$WOOՔTnb{8$S`̀i\Q\덣ɔZЋfq;DpGnda;3{!*XTAu1_?%nRzՕ\!c!$c8fsaU TrFtiO=x=>I CQޔH[GvߜJ7mf aˊ0`CFs^FI_xby6Q:gX't}<\dsĦy{|AӢحL(r|>[/1DwBe%F^hx]Fi:kʹZmAUC:ޙAλ-A3:\Gr`y--2IlF}VgG (ạ"$IS!q`9!qז[Ӧdsl(LL] ^X4th ת.u*>.U9#o1xz3dLSu1~L@> L$ /V{ŽA`F֘4"T<[rL`^ AoGz&ꙹ6ӳ^;9d;%yOFoO9u,uP[љjNT㲚3hd|(e`?GFtop09`?((/"4{hLKwhL#w EgY:w :2\Mq{,s6a sG{Jt_tBfxGǃU6N;v0+{ck.V.:(1 {qk8s\uv++ȉaY3͢t`M/Z[ƒQPʼ -Teq5\9ߨ0iXE*|J*:WSj!2d$ !Yt<sM*~8}냦Y>_K1>MȾ1OcOH) G*MkR_:e. 䶕7cb=BRd?-g@RgJ9k*WőZq+uEz^țCݖI~C=i5=mS[2 iyݓc!P"&+ʯ2F(cV1-ze#ȭ\^U ze1)cXnyjbc*XƆJ,Rȭm\؝s3>%;&?Gkz֎B?F Oڏ $l0h[/oI3`UZ3XȞN HOlwqw'x>- UBzOᗇ!'W gYpF͋wr8tB;<|^'DŽ#3+ kZ_7gLȮ=:rrl \^] fb7f+!~S?U4gyWEI?[:B$2q #/($CIS\L]EOT'ep7OZ ~&τ׌H1Bm⮆;=a2#T/h-n}y,74\|V8=yU Ư!{wO]ȋE[ETͰh5ϵ4wk9eȒq-ZJ"wW;*1٬cgkKnV6/"V!>\ä'$=9kSd|#CIYlBDr \dRuOdt0+HD-qz>sTtnP4Jh]ﱊA%BM{BብBS~ԍʂpل6eb8#`zt`~@(iDqT,|9y$!^7>8sh3/{?{Cy ep3>"@ڭɤ 0gz 3gcA)9!, }Px|lA ͖NH#=';׌[r7 Ss~:rZ k追 LJl1C9.Q'?̚2k9NѿBzSpbM%9Ub% ER_6U6e8*B~-bR">QDo+fB N" aʧy!s2O~izݕ^bHxSϼᎬ o/}Xe+Lbq\D !qtmJ+!L;Ó zWqY%hPA͛_2Qs`6M5m cNBn?$O8``M(]+ {$]xlćEK bÑp"y<'{:fJ #o>eUi|i.:hZ&m>鞔a}Fx.hiBC 煌v̿0^n6B ʹ=ϭ<>'sZȏ%]p(C|+12 :rΠ[ ϩs-`,.LÏn~5ۿ5XˍTJ==E؈$1>O\;E4\,JfpFʢj3Y{jpRŸ%SGnqHv)}sc$]M)vf;1Gn, p }.qO:z1Dbʐvwf̤X`IpJq5uǩp=n[[ 5cQ$D|poB0q {dT>2h$d1[N S9|""waoBU+CR=[ZB=z]KT3u"h̀7^9}J[6g*)AOTtf>蠺.eIL]WєKM]ەum L\* bus(MSϞ`s5 pߎ`0j`Jp.̊fx`")Ӓy-ڶo#"K‚|f\Bbys׉އ{`[=?*8%6"12 s0\QDL<c9Qdۅ4͟뮁f` (\OSfLzfS=݇;3ٷf|1'2Hyu8]KCj{R="!D"'S0']u֠lT'US]MԠ  {O(ZڂdZ՟IsG}&f^gY`ӟoA$ȦbѭK{a8#ܝ#e#B5)˒ NEv4>,G!tͥ= lu h6%,WS+;ϲ)~ˎ'a[4Dp;dڰc-wۓҙ}9!m+ܱ f%om6Ձ+O))Z*Lhh}\\kjVo˷65_0+uZ)B?ZvIiMomӀš]}z82u,mD:`x.gg\Ө+Jgt_dcܫ{ŅPX?mØlVo?*X\AU0|bj]*yn.& q;#%g(2~ra,XƍeG9 sEܪ6 *QdA= 9KU/эc+g|T%o M:0щHn0"ͣ)]@4Y<'x6[B*$"@x|+`o)nF\(A¾VN"jy)՗ 7B. tJgD"81qaT/D~$WQ,w?.xB2LHy/#keItJ.Z5ХQ7hݰ[=43gSnᕁ˛)WW=&z6(૓DQC;-٩T|\WW59ȲAD/rԉ<G/qo=ۘ0qJ6lea9OCC W%qdD,@9u~3ʼnwxƆe|,FCyG-DҨ).24rsa @=KM >[sbND]61w*cu N+G_E{x8ϟ~y441xFAAq}>v+A62|tKm95?򵷂g8}r4QS`W7_~5f?[CO[Qަi&1y#=˼'C\;os^MG<:Ƒs"M/1ݬ,4:01we>i\O|GbOPFɋ2f1*E6>R8'; lj-0f? cH %aiB9鬞A`E)cི=#&"pV 5ճj uq'+1 u"wѹi9)pxQB HΈgrr*dH@0DuM|\T>glÛ&҃F, BkMv?:ZR.dp4ZD1y@rQҳI3K&.OŜ>͠,5Hfn*Cf7F;W) ktt[fs> FVW(R| [陑gr$qqkmʈh aп ,hc]x’z*QAfw{Ͽ8u%O{3u7Y_ 4/b]tɾ@OI-5ZvGjl2VIi |Μ {@EVjj_WtSMePi7 [sҩnʵs t;F&;_K sd[ܸܗ~/̠qoqC$\ُ[xjM>CWA8^8nW?QVRb̎;9$[Ϻ7XI}rgdN(+%%KKy"ؔnܯ潨c"ӗ=ÌvWAA3XO.(FJsJt] pg11Č[/fL]Ц9.n+y樤\sJ־U^&>z.gE7=:2 \&P$rR7Gc*3:0 6OYx&͊h1SMe=gG3zc9f {VxYtWTv]CVqJ՞Eff2U:B1Rͣ,Tha12hH*7~;pڎ$ k2׉[7_ŗY^2ƋvtΈE;?~F\98 t_k7s{|1NK>e 2 *FvT^d+!tҶ%p$NB~ ~5qD!S<4w'v=חLa@D*zSƐӖUe1x ϱ4l0:0J ι!r9wX4jzNSwĎߢDS#r&6GDW& ƨ}dĖ˰)<@r:9h${o/ f|*e[uU$giytaxF%B`ڔs4x5#Ұ'YbnK8S厔Io$x[J~1b㜘UYC.EH藑LO1,X[4?|i55UC-mhܫgJ=_7hXʹtԾ`` }":9$)b&-Mg$n,O`x7r;h ^Ct~zT"n2&XT2ܪ/jWN %\=9AZ yI_~ D%59Feڞš!T'آhOੴ|?|:bM{:oqhg$vLkʮVxݪYթ,4OJpV]Oa] mVSxJbʉ.af)*\}L ]>g87$( aqjKDy[AoRqgXLʝ,Wqry;\j5j0)B7#UܟAXB=.Q:p⍆nݴةŧGi`oJ8UΞbn/$+1sXZsQ!T$sـw(gr],+p+8m쩪G_,te^-&ٮ2vNH|M%E+YҏO=1乳3vʚqmdZ7qckX6VTú'ujO"RU֛bFQ#ۗC ϕZ\ڬ]37I1=byќcSژvSfGx0ӣf#iP&+ޏ&ʞX N(ڜ0a8Sh`ىAI.weFz'o{2i+ܷ` ocp%ѥB{CX<9L] ]Y؉壛q[݉\5<{6Z0&<Iȱ?fRF*Ƚp%=AK;'TSy&Sry4ʘ۽-^V"VeKT&'+qPɉt z]d.%5*kEkIJBr0#s99]@F)8b|ne3Gm1hCTVXۜ#E4>!hGf5wyhh)ޱ\Or*hR)a>5t(ch],OAll>?81F9v40ЇND R =']uײ),ΜĉObiOhWvf쭑b(t"O*Lhh1e^(˱`fwc|\('p \zo$ ✐/jh\"ZƲMb:U+_ NL& 8fqmfŪB[u|mEߖv[rAzw7dtm6`Ɣ_/tBA+\x0OgoƼ bٰp>\Xl|h:ReLޭL\DTN8;c%B5*S])˅L4$YSi-=mYbÃ%~ƙa g0\ pMFq$T~}6C¶KiO45Iez<,ϖKJڰB늱!Q;Ԍtrl}D!GsA>Z:%q[yJ6/-w1c!R.KQL՘|bK<,BqtzgUƒGe|^8 *zޤqPzV ᄏy +r_Y3+8`YΓNcA`r9O_:~ꌜ%튩RRt[ӺEPc:.<[lpk3fF3GݝШZ$PYX/3z/4ܛגW*&u9s%y|RZg/bjn-`qG vq\B')ycOSZ,@ T@3Νm[]!MʹD H6M#s` ӕvLf džsYeL̾S:?.<4/f:_Uȣ{%%c<'P* ?-g9ÎR&cTȍ4.$)# ݢ`.SWn~{ E<)h ZW!{I3)oH)r)LyHU|v-dǞ"䘿T T %BCXuAL9F H{*P\Bn[a24Su2'IrI5f,U*:`K/1R뙮)◞9]f7P^s-˩Zg@5`eyyނO4 bJ0pf{ T/YO c@H9wnXT+tBk@29||*mYX`Mk4⑜hߚ_ψ~ 7d=~J0/Ud_J'tfd2) ~].6%:> % <{kHًԂ=\HSi?]BؓKpd>d"-VTE4~&GQ tgg|XR&VRՕ<k=ΟɭBDE:/o)dȆd`_RBϚy4yGɁ",#UTDl$[WBWbQP {#F%\Y)E)frf>HI-pT`|.-]NW:1,O2k 5߅Si:)nVeAo;`gY4)N"26˓i,pND6%3wR*kdD |ZK0~[9y<馣N`|Nvd/ǝe{eJ 0f *ik_Q7܏s"[Ϯ=+rё>~Vkq[{0OՃӠqd@Ǿ.-u! q=ށ+($kqlB'<9,?܎f mŨ%2ζ#e~OF~f&:dF m8G4hο:5C)#,Hh4;G81ց=_8՞uáHI4qCtܜ<`ևiV,ϝAALf`OUX"krR%2(e~9= ,0z5Ƨ\$qMjr[}zgr1.Mj*n#gfkd2HʼRJJu9 QQȒ2-a9(\AE5=" ce|XQ>%K(ɔ/[g&ނ'3Me $mKG#~'P<L{$tRc4PXC)c'5'/%[bP ϳuLz)=_ wq[gY;SQOswַ6OCp%5 a n0ka[X:eH6ݭŤ虂լ_a+ jY訥zNs䖎ߵLMPs['ih9{t& 3l'wpȑ*;VlS[*gQ-\˻r(m[,{O//\2pv(qdgz~M!SfDwj'bLTdvl⏪TϺA4j\—/G^y?Y4{uGocU".kIbmp"Y1Ɍz|!~p/&qɑ\@8ԁnS쩚$;aFѣ ٗf&LsGtˑmqhGuaU9xqjӴڮ_e'ɉ{V4.f$"=bj 3?bJŸ'eJ6u=^R|,~1m oUJ֨RDee̪\I2b񳛚Vr(9$yh!$O}%vnqqtK. mbC mFi=lgk/'11k C0ZԵXP㟮"Bl$WyMATF=t*&i3&rlqfNJ,R2&9oiēus?< eDSuSnhn;!>h݂PtEͮkYy/)efDOut3[l8iNhMxÂG5=8/jJʘ<@A]M$.Wr,\A9SdMׇ0Zה5ptMoˮ,L|NpG,fsQ}&b<soO.8cէ|+dL)abvhp/39+O39ᬦAw"s$)Ayt)duJ)eR Zʓ=%(`q_̺)9:ALvE=!J[v1䶂JS͚x'[M\ʓonAT'N-dO.0`:jDiCC[S ݄u=9ݪKfLO_֩\(bM/_cVickV#Q(Nj~/2=|lхS'ՖN-fן;n4OG|Ў-Q gF†1!˃638\N*&qndFY.!$V0I:7lѻw (de&P /ݩb;g;>To(NR~,QHI ~ScEEMG%_+V9MgжGV_]S!3ZRSݙp?s$'%Nm1QR^糿IŔ5*fdd\(:G x}lr#>]™EHX8 2iGЯ|䳧Bxu%8nVDb $KSJiU2zPx!^ 5/hv (Q)eBbh.M)wSc{'I8*i(c].sYz'ijӻZ "~)s} HbH]5`s/4üЕٌVW{u0ay+7Q47yxO,%:/IϸZ]4kGa{O)RR ~~n&Gy-tP¦ܟEn$9l?+n[r#%xv_ /^Oj+{plh2ъQfGu]=_}זA?kӹoϴ5x4 Oc6[!#TYՍF0x~>u&z$y!q@ ڌuTYƳ#ߓ"׷kŰC6Jt~U]opH7~XҨ3HLlNũtUs+QEW 5RS(S٭E-D]5eEgE 'Nd˂,n~MB*KGƐnVϧ(xWy"z=w HG*%Rl< |)b쐲OE+ӱlv_`l}#1f!FS-gsY>Iu\)Bu):;.Gqw9`+fy!\]3EǎRz^Wm4sy9(EQ l&)בJ4% QY {FZTmv 3 ;Z-\DN zr ;=R&n'P\HF{8-rg|wg2.=d63Lе='|b!̝CLIƴ##>OUqcM]_ ~x0D3'g$M׋ ~)oa#p#]I׊䷻/v%eF1-˳)e92j\+&])]J~3e#)Д8tԘAM*kFwhy\R`[DgL#sB ,ƭʣRY,al+hNΌr**v ɻ^ė,kG-a7%:$!y>ӧB?|IRʽвBw ?"!7ri=? i,%Ix1V2p˳4+qHa;Wr>֤+1R m2|yF::qo׆F)5MO1 %hXGǞ }b"w1&qȂaj c*M8Ą)"&1j"]Ǒ7k Z:soe9e\AlQKx^4[ ^p:9Eۺ b;ǚ2F@Yn隖8Fzۑp>;fl׻"bs( E7:[_)NI`ԙ4bI5sAB_`+uo :M +2iŴ*&c׾S;-3-޷V 6iBcZ~tag V,8M,Xvq=rNV!Uɘ /U ݤH`|6m &)ˤo&\p= rm1S+ K,Qy!RM/)kl*bM)ܒS:[qr5k c/qŋ{圚)s)]GY1 B:_*JX'~y>?3DIْ'T] U4D^ go1 OLƦơ]z MgiLĻi({'%,rF8t )-wftovvљX՞וV=pZFvq 䯦4u,@:7~xmwb7m.dC?4-+`H_i"[{:si ͆ZldI; ia<ʁ_-vA#녙S1%5B 568% n߇ynJC;I1TDV]M ]K06zI>\2hcgU++~fX#2oO'9nba F2>&6$!Ac8wEΌl:PH,v~I,fL -|ŝ™-|w0G2)]!<./{vK;̌'8Lcl]َ10333:LoG>p?{T-dSﵮVĞR!8'#d+iHG욱Wz­DžkKjΚ 1,Ǘ=U<;w9d|xQEP)ϤxPaIÉcr n)D/%eTC2`Frb$U,5,0YA\dJTqCHZzbݿH/DW3ƞo\|ħ(MW2`\r`̟̆93Opao0&i_fˎ υ4Q_273#'/}jfРX"XU6)Ye1)u)C2\ʃaXņK]tCcݏXj5I }(K$ʦ7.úOf2ʇʾ>|B W^3ړ2M(-&bČ"KȽ` άL_) –uל>fLИsZ`j4M>ѹ_T.*Ԭ[ }'# u@5oQ#yRiH!VgI2 l|0vzSk߶D11EppvK%33{y$"h=uHlEd4ކkVs7 XU$w+bKd_6>yY^bē҉M# Ix_{&jt *qNQ3T\)Y+bHpNdR-UX|%I$k@.),]+aM̿_»kM՝z{τ_ByϨ* 1D̸N*˝8|eXו1Īakʵ ^Wp+2Ji;Om%ߥKїc6/oir(`neM'Jږ1%HR x":-)Ч. 9㙊yk2vtmgv^o~ Y<ׂx۰Su떖n*K22˻I4wжԫZ,4ި1njޖS 3@³6xQ`GgJuhus7.;;ޙmg vkΛł')O=߃˼LJlծܴ q = {R7~ZCDgY9ց4KW1[oIEhSEQǀvl $C"'RN KXΌ Bς)JBZd;O1d}83YἿIݵ0_7GG%BR\Gg*j2<&'[#0؜Z Na[}9&ARlR !Q+ʉ[nZ捤dﬤuJ7{ť25*#\) *0RAD *]d9yJ*9dyŞ")gnؖR* ==M=և(+p?7I"S #'s/sϫqENKRe3b 9ml=_. wb28K߹*N4U/g࠭R*.`rJ}bqy*tGW-3TXıJɛ"4.\)tK @^EVdStMLxymf kX|A˧iZ,R1UzX-k[xC oiH˹*f7$lc3^d\i<۶/&f}0dY [2zĪLmh:q'ɷ,0I˩vkڑȞ D5K|nX`#uHN0[#iN`:fa?d"KRp"8 \)CO12 YKx⭛u[ ef;-;pn|;A #컒p?m2%ni'#ƚ`SkOya{ T£F%(y/byg#n;q-9K4/[6Ӷg(G9Sy^=5 ] fs8#19G^8,h)VYs3n1f;ƜѓpjNN.;b38f:KjcEmAs9Q3[3%OʍibA+rSN9GLT7HΒ: DꨔYkD1te2tEVۺHI~ZeO#muV1U|1;4=$g;-_f9a}- Wqy"SJ5[kш]|^N[X9\aU5Lb7hXCsjA_RN+b"e Y b cͼGv A2{ωllgwa~? Gޝm۰uSؒfuzΐ! Bl,ѳTQΈ"Oe`,Dqٲ)9J<RNb"RX8%|9~SVɒ|;;ѥMgT15qlyM[7zxp&q A?ga۩BuKJ+nZbMf U_<یf jE;+?˚"R\FF?|9Sћ'wmg{U RK|_*X[k#itMÇ %lvSp9ZCjȵ0_Vq\aN9CV*!nf7UGG k S5dpR_{bmREMyq'5l s}jj_nj)'[8gk]\Ms5o:VSRFdUZh9]I`_)9+о*l٧b1{5@tN@}Ҿ=Ŏ.] dq.lb$#K.am51Ⱥ|a_tFwl 0Rs^&?8лg%p +/otm8ݐ6+=.fE8*PS*9̴r{ 0 FєV7l ", \LV$O|Y{1XFeh]‹f 7U ~G53q s už _E2oi&k JiQųRʮUXK*XmVJ"s]2iHxV0R[54|~ 3 x;X1;ll IN$|bOjLkh]4Rz?DRR@%\ZM4|) 1ӏ_䋡jVBg9:5TKg>YBOK-'>ix4Hͬ`3 $ȸ]'X5 sTlLzɥ!d+.K/-I@*76fsx3[6[0qu,ٻ'Seq8¢]љ}/n}ƐwOƱl/ƱA[L%]c0.ݩ,D;)K0^=dmSga$_YbXe_HnJ6o u yrak~byGYz0+: {j&vFULUBBTXu-#%SJ6Cᕉ:S$O(>ɓB4OADžanvy>QA2,P ,Qq鼒_oX&Hsh'$6P]ߣմ{e U[ZN29% lԴ 囂Lj>S2r6,km8*eWA >KزPsG%Ybtшuy+gn'c[) (仇W*mU1r_vmTNط"93O#s3BY܂>\=Ў7:b9?#?B^XӪŸM, "wg s6~`¦qqŮ/>d>'g2c.׃B9ҍ]K:0 ^>XFFݡkhjTʆRm<5߃8܉Fy< xֺӱ0wV]%De$\d4}2m`/&q\b˺*Y;ቫ#F& ""{*:l/<6NIЈH~byܼF~6q?ٳn#1Ч/WFsi{/VPϥt-'Vb ײ"ZXT9zNNxͩT<ԨbHY4;&^d=MH5R+j^:߬aIuU)"oLWA[S^O$Kvn.WSoD-՘OUQFCqӰI>޺h8u9^T@etRZў5 LbR*sh1/2Lw*kɲbJ3䜱Es³0ϸ` ͉XZХMpv!ǚs Gz{9i1 <BÎQ̗0?NcFZzUlmr94! !Lf6b'gB¼3pz RV1zc<DS)޻x|gC5ƃ k5rKLJ5(,+h7Ҵqf 7V6EP ~Ngn_u}w~'Ф֒G(*ǖ9ʷd?r&~?&K#"n/Y4mÌ&<+bU}N)9T%kixyg?-)+CsJ܂հaj6P1x~,3~V;~ rf[!4"+hE?U.UjD27###(HAPpsi/ae|l'cc5j(tq3-M.^E. (fiX6K1.v[Ns+Dj=`A ]ۃ' =OnA !~Jo:r;m矑9W!V4Mc| azɊ]XϞ\NBW>t#x;272e>Ԋ즼e@,zԆw \aH 8#7̞a|tpy'% M|őmpHc( փ Л ^dUiuO8>tD=]9w̥֟4o"{y@R/|UѱR͊ %e -Q%T -s#9 ,Ki&誦QdYy _Jbh(fc;-SP$Nʨ)ΓvMDq GEtz[3|L.B٢Q22˨MCØI܈{5uXi^>R=rwB&fS>֔ѯQ%ªY+DN^'Ań6?>mޠ3K7wdHٚ|+yC8.^\ ӧqociPŘvt̍@tƏc~89ͨfɧvS8rGf-c2xnȰN`v-Sh!m_р7~1µ>UYf2'%wtYQ |fA%__Ov8^khD(,b18Ƭ8mHn$NHX/6K}sTS(Jɗr̋i<:J裪d\SJVʰ N)$˭g5Oz2JZ䉘 ׫yEC_Q)V4Wɉr&S'Wd6hӻĕ#><l,`Խb" ءS%=䈽T9kEyFuиЏs1+qļ0#i: dwb֌"u3Bi 3~ y?=;>tnVkǼ^ /- I6,dv货)8&ԒuAȞeg.V7LğI9*uҤ ׄIg݅g;ˢnB|ە*ϕٴMSpM kA@앰{=GyP=ŗM$gaQGxa0Ӈp!Rfh|Ą'&,vA?G.gTW0 |¥* ]̷<`Uz.bOEO96mXȏ-)'ᇒ|WYBWD*d]#8/䕽7cߑUva`+R)PDS`U@@2UJYQ&SݴاzI:ͬ1Tќ7{]cGr`RtDԃ?X;W g2'4#2GsJ'0mX>j^[p%e<VP/B&֦AeHg@k eT .dUT֖c5 '7꧄Ƀ .nVPF\*0NC/rb;W)Pơ6g' c ( j\ʅ%(b"nՖeZCY5gxPܜ04,) [ƃa(?ǜ4+vҡv^b.u%g'Ӄ czM!' 'fccJGwTyϛ=K7w7GkUo"z&z:$KI] ͵ެL`1[Z`tΜN%rlpp/o.7쉠d:pNכJi:6%[x {8$\5r,5PWŦuE,xH S/O6nžr&̐SI*J Ѳ+ߪ.,!cE69~"ڙY0& l| 1^|e ?Em.Ο ,SN~jjY7CT儝K%|SF]h8ر6oʹDZ\~^Nov#1{35楾3-0ꉵ̒/כY )iO[xGɘ;^Ex. 'pxq<2D/~cẈ_ਫ਼dXahr$XvX`>W榋w5m -vbc΃| b?aXxk(ڙٜrgtF{:~*̎GkA/mO%^+-9reG=4 Ql=(=fG +y\ w5-U1`m%a|ܝ))ŭW6t0Y pe&*RN/a% )a,֐&@2K,#i4pA?"L^aHdL aS1ͺ~eŪxؙ )vYSCh7indxzPzӇ&׍%mAI4:ŋ~qG9i&@~%2tO+~3BtGF6R}A82Ԏ 䬳b-:N̯QACBH=ɫ^q̮F.GY4;1ѼMĶnSy`Sµ&v'.+x߾ӸTǾv,je9ެ#`L jTF<ȥvX1*{Y3h vv]i$Džb)xRzі4t[,a~(_0G/%,cѽR~/ms1Vjf_! Z t1t{dc. i\x5=tJskf 8ߘזLNm g<˜ Q]L-{Łfc\ƓcVcZGXj"p鏝'NWYW5Bˊ?M=AH w3]#+鯜فv vi?D@#^lʛi-^Yͧ\'t:m| `>v6Ch3ۢbq]]g%8dp#~PѸ8Ʊ\O¨G&GE PF3wa56R6,dx5bñ(Dr|wڛ`x ˓B9p;2I u1pe9zWбVAm*5H؏j.U}e1˧F27ÿYD_neHdB:6ɼ[n#(,Q5oK.~IB`\qdWFybŒ@2O{-Fp=Z?U[M ޵QQE6u]+v% N3GGt g-QАAφ3s4;nn<;?>li@3^/Jt 4X?7ˆU1 CIϏYpe}*.jTq#_IǠRҚ' Xr=^zˌN Yu$u3x,.k>_%T,ǓJ޼d*>UmkUSAdL'3p'w;_2^[DO$eጶκ`d߆>1hK ,էūBKa@&z3ڜȑ5 w`p-Yh2:$I ֝ Yh~ i~ǦeKm {;7ͷ33;b;?Ex Do~`{cc8w*M9n#?XE\a2:LOm3{ )ѵqJzܛsv >9[ACT]WѢF_%eO ڏ> n(aJdwcƭt~B?b~(Cߺ`99OC=Jxɬ!rcx:߲K\LÐ ̶0ړSyXϒ}hD3dh Z ɩϽ6#KЮoɟ߅9WOZ5F8~b_O׋%Oc A%<ٜۗ0ƶk9=W8ڰƘtk%l1i ؤ+{|Q' cǒ<{4W9dZ$Rrډ56"cNlv`o@2@Cá{ҨA><\T*YJ'H4̢!P>#掷R;NY3CERHaDt`Ry9DW6/^g! iαHݱScU/ 8ViE_h/p\XoFt&.|wa0 3W |) |X) F'-%<`dlz{$/rfG 5p,/;pW?чƃ9[N&s|.C 8Р3;8\jA),:!ShhYӖVz3Ę3Mpr0^&!>VϼPR1iQ:_ѷSc>2O G1's6Ma,|N?.|e_/'>H3,G3cylǰYt*C>Ɨ. 95B|n߆歚՘=*y^)ɖ-n\+qX%I_o%9yęWepKNj&%Þ ͎MQ{w޾s]zмݿKmǜ)N"NdfcDoxMa6.h%y콞zZ47 et-qf™K=x0?\#?O;~3ox؝%`J?r)*U^E69UHɜ-u9re*ce~ZS)wCqUqXǛ+x2‡3|S FV |%7=:oc_+=YZi]Uye׋ ۈݬ0c͘ut~HW޼6CnMM~lf<Iݗ^^lR_Oq'n ?j0̹~ׅ uǍ_џE%5ri=貥Ԉ'G͙Iw *83͉Qx`:؟ߙ~6Ī.e)Źgqa\,+B8Ɠhyב.9avʞmVXeδ{:aZVѷu^nS)SR>)Gu&˜7'>e$AbI&'[cL7(h+"FShq<ϒ LgXJoUݞqw Ĉۚwww$D $e wn]::V9TTV-1JvF2 ҏ̽mLF~D pԉw ޘjρmK /&qD"8U^X1<ȊCH#-0Ȓ9P"uN$ޥr[.)H#yx,rWZAx~d0G r!0nFҳ ܵvg]'7}oC6㱰%WnXhxcY%6HWiW}Wo<㏟m߯<'vlIǀE9:&p)}10:G<VhT>_$cCXBwVγ熚OB 4Yoaővkݕ,:n˵`Nʥ0UWL &o_n`ijb˷2дvGǾ̛ DK>\̤VrBQ()%2#&J8:4Ġl?vb+$ oLAޡEqP ]|w3ԅ؟R22ubUr<kKm{a!ҞQKE:vcąq^D䏓x:Y{Ƅ  `2mȏ]Rz\\k9x4̥NUFG׌y sz|[7nOzfi+\,i4mh*w931'|PwC[bcӎUn1O8D}.ڡ-_yRƚ.nt\Jrݵ,w1D#3=4σx,0l#Yw,XmKĥE%–΄92nX*t0Y-QQ13JI,ݠJe m|Imsl84>4B0nY2;%S3$X#8eN\ێDktŧ;0ۑq? ߝ)cLP Htnxm#3b/ڝrs'frZ#Mo)Z;L+f (e-0_XjarHMWϛ$4\vh81KvXqPŠ埮j^[{ys,8;˖]YʛU8$6[BVd_2!-Ɨ*t wt$5is-IS&&a{ -{ɝ;݆IbA ʷo-߇ϲn>'ZD !񹶞OK2݇r -Yv[&ɭΐl4&$ԁk\zBRs"T$/:03_{ٛ_=߅cI z OI<\r=팜y F6té5Vrȡu)ۥ觅Og'P,>'/H Ҏ՗IGE~RFrXyMrȦ]WelR/ JsՁ mH״dZڛx1Ce#˗3/sXϘS5ӁqdN߿7wo_v:vkUѭkwZ=&w^W7߻ѸCoS[2t~ezwaYx)!bz[&84ź;ٺ1RSVIH{t-U2cO,tN_! /H^UE% fD}[;&(4*}67䵯Njrt^.7%R2%ӗn!'xSi%%?R(.oNRʶ-l*ߙN_IXj&ef>oZB#N46^&?m;ݮ)R)2[M[wIQtH]X?nCقuڊ)f"                                                                                                                          !~ ݥ2NHzs_a8ybLWnAƱ NRG钼sֹJ~hVrߒ͐c S|n2KjD[6C.>?M2 XB[5c"1gD|#|CzK;[S/ 4L(J-KVQ,DEk?ј!Ro+/+M2M[NI6[8xVYbk&+\bQ& ;~..O}ٞ}8hYYZLWņ'mIӖv̬Cն1q_~$4u:[;XnΝN}1pk΂EH U *-y/+MCt,ޘH\%O$)]/1Jw:V&(){֬p^ˏ}k,V\T=/2ݘ W-ty-/o7rYeC{eX3risE7Jo )z ;/ZS>B e9}d{l'd66%Ƥz5fP6ǂ^}]YA+y0HLJ&K8́Nh9rŔKؠA2 }nW:i®@WMrj#'a~?lNL;uzKRtgkF0w~(?Fp7Һ^Kmsvo3@|s6xʞliŪ/nh@]@OM+(1NM6#f^(r"9,*_Ś,CcɍmeE@%D7'aKzQy9e1z?{d4=mE5ֆZymBκlWkbY#m\M9*jdFzhNacݚ1ČLݡ {|:6}Nj|xȇUlww.WV -n0'yq[eh.uDG'4Q.OCceZGT֯"Eۑ#z.na@c}ܞ.sux} #2;3%* p//Zn!3n^HqWG3eE 7{&o&jR>H%v|zā/!ϋbe@$puϚdkΛ'5AiûWK1 sNt g VSopͽ.}2bA̶cZ#FݐcFgO[b|~,Zx c=Vn &"FAw'm c464+J-w peOLOWǷf6Ll7h bcME6惿e_wGc' QjQ],׃[C}O/a\=cGbi ʳܐξQӄrzr' Zx! ۠DsS3zuriP .+{<)ԕkK9XħhǓƪxt9Ww 6>ْ FKk:)#x0m7#Ss bAULE*jsj%ڭ#*=׌%z$gj75a%웟DTK W7r&7YdtwZٱt-n$A0|0feՁ>!ay aU.8j(XS)42;^5c q%3޴d|ZokuCV%XR#g#+YܭrwGo;-i 3u.< ^ZW[4M~̅>noe>a0;ґ3wgyG cc;/T۞4v0_j2'~vVݝ|oiNiLkXУc%[ش+y8,gFg\vdh?8MP} I}8u{vi g6܈mAKFr*VAM31+ 5Jbχ&f Ϋ0Sf~dO-h88ܚY\lɾz{6x{M -#c40JïY䄎c~T/T\u"7/fRE{y-`Z7\R+cs)#Y?Ǜ+=i}>5A _ȉ.N%q'V 5NΤHU*< ay85 ]^ asO&--nO";NF>^QטyrG)tTg× 77B;Mp8CU/~S `z(4Y1&R*u&&[1FQj#F/T8"qe7Giv4,dNʧtM1%̧I{Ys-?=(vd:R)Q9c1 [)W7+>Rv=#vz+@Ն Y!1g֚c]/.flVֶ2l(F`&wR!Qvńٖ?y,CkNxaX^ }=YSKuX$rNJf:/dCK}rFc @=X?3#4KOVa=&;77|+24y[w;ʺ<3DIéORuDuݍVnucG?SGv6͑ى Hq<~+G(s(WC2WSJa/8h`^vd\`QH ;L9`2k?3͐q~@O;^y1R Rh6 籜3LAzCyB@]姥-KӇ2M7{5]3k yFbĞ ^~3gKW{{dd7~E~A-Ĺy*{TA9V8nKG櫆Rϕ8 cx\4KR~1b 3Z7r+EK+/ԉl| X~w=({ߜ)㧊_:|8 InV̓5l$Ou(U7&$SBbʿU^LJ ;ۊkB#RvҖf}1P( %vGozG6Sgmb)u9lΓ`Zd]/ s>ЏKyj4Bٯv#Xs-5G-&coM2wꮇ[''){? '8+kdj8sX2.B?Ib6cTp<c]p SJ,2n^+'z\A*(Ԛ A6J} k#.E6U(&C,/]Xai nɱXZdzuS{qBD.SLpv138՚wً}>LJVu6"%̾f=ܾH0Rc 'sQu4F +\01925* ?[I3R'd?fro)2^N]A>Ԅv|W :ם'U žB}g+sm*-Yd˻ {5?2))@c]cRжc4 ^乺%~dc *f JgZmp☝Gfd8X7۝rif殷)K_Ո>/)emQ?Kό6)?ȁ,QJ2Wq``(go9k+pM& ox݄A0dB nqY/fU1uK R&qbw~OJBꈽ:n1v092=5=VŚ a=BMi8#Ω:S͇n>ҌY5?j_ޑMֽ^8%odHcoz XP~ Da Y;:Kq,ʢj) D)Lٜ6Y3 Z#ol?cCw2'+tһ)#I vRՏ[- 4ud.ͣ"Zy3t"fHn,KR_uK%zEWįQvFޟ CT&~ȥK!EWc$K2${>'*8Ή4/+ff]Fr=mF؍%]PKXȼqL<')Ek&߼:֕4iS{62V6F{ 1T\df}K@mp2S?XdMU >e1(i˙\O|[ɔa8wO-3aXonV]+u1ar2\7XK Kv6?xz9et˻a\wj뇦0a~ꡅ͋F1؄S|ʁMhC|Ѱbqj:LY-Ƅ/5-2 CDz\dy3l(Cz\f36ۃm1E+b}Bv#elc1@)F*IL`zP/Mߔfs//'a\OBHڍE4PJ Uv fɨ)&.y񹔓kP+& ?+y.g{Qɞw{1kNrےN*2:W9KS h:ڊ,7tv0[6޾̟K{>vcm'"o04Ŏ4\xC\. "lzbBñtxR1>L _R+b 4~ʝ"*d t`tD#UťX_VfކZUC0rU\Y^5}(lĜ&K)AU=sbMHVΚ=]=9kŁga%*jhTWB D3|(7b9UDCc۞KȡZa;F5P/zc̥LcG aT62ҝs7m/6&z0;G?P .U#Θߊ*~S_㬸FfEAOQډc݉H P7WGqٗ.QORFݝҹ۱l%4YW=dI~TM|ide!d6nZ&GsӲK'[}x[{yt(<"J.1`Mz'r-X޴L4 vmώ#w7fJ}YC9xV-qjVu@]= {_}p ؔz,ȱ̵hRpsz?Z%G?*Ql;~Fa:iga=T0ޣ 67G0P0ʌyhf=ڱ}!.T1}a\e!+0ㅍ@rgp#"r݊F_-3FݱTz|WTCe ՠ[ӰzRMꉘ|-|K߫ɩ`K5b̍Du1eAc!pt>7c֝ȸ~OtEr` m=o*K6ϴgldң*Q&=d8<7$rVqR驑Mه\&}ro<r9h J)WoLM;+8ϝ}"֯iqZd-(J+QcuF@dS,1jƼ*w>="5,_E3u<(EѶlVU}%=@ yKTWFS}[U)XՂA_e\vjA(]r1: }U2J㒰$]vT~1csz-9\xw}?R@B]+v jŬ0f)Q'adgp8VM` \qL6z$Z{7hy/9#~~ Oǘ3-n]LHՁC0[5B_qwsf*'5s홣ait9qg?c9wל ~\:}m$hGIPLcdXti0&MWA2_1Kh rYJL@6Tpkk9wV3kۯcl_÷:R)^GzeqTȝOkٳ'"6ӇԔXԔc6PfhCd p2Ι>8/D-Mڴ^}ŹR54[|Nzg 'T&C'|^JLTKpeip"m無w" oL6v`"4Q,50kn cTgS_x9,hP'8rґP#Wy?ğR,/N2j5$Ҵnlq.&(yM K]y݋"9hFKH5迭bi =L#[9j]+G4EBW5nO3hlǹZK^6Nr`et`LuEuάU과7h`J%IYq[g}VᬼEk,6XÖ F$ gF?LU9~ք#cxZ;Ӳk)9qwbVf5Vs-E븿)}Pht{^4иm93V4X8ʠ@'ď˫mxЂotiMlH.I,Ƶ\R4fצh=D%C[RPI :W&]7 p bؼbR/WpN)qp*Y=܎$e%K\k1WDֱX{Q˄L 2(fl:N!yW=]fTb<85aAL~`GJ{L0l2ʭjYe^ǨZ.f2ɅpOzP si~*R _LpT5WZS•(V(4˶&cQ/7kpv{_xɂNhbCylN,t`HE+|93%y܍&6+',:F,ۊ+16g+;\G68lͥIԎe$Ʉt7A}~6e7t+e:tD^N-k3p"y'2p~YSxTjTX5S}-= \dYOWP5#~I*{ hF=ßq9^3['4y9~wXoV>u#ÒF>I.i'2?s$ͰLyмN*[l0;=}Y9Ƴ+=9JjG-x!cqmS6nDa :~X޵Ɣ uhjZ\)O˥۳X\|`F$%=8= ?*ٱKs6 ;ۚYÉoAՊ>6cc渣+T~v\_XR7'1ܹGHlJSxW%۠k4o@nz+&V\"MzWlROtKK﫴r'ǩCڛݾaμ[Μ6`֬JFoSUIA;[z4u&V#4vS ͒wI\Ǜc(rO8xQJv$ >qr[!X^Qo߶݅ݭ>PA$E钒fnx}ֻ\ In(yvec/fllqhǠkSO$6vo}ūțսy>xM=գ=yhWx`h&p_y#Ǫ~2l~c`mt662iFW11󀆪gTv}ޅJ~RU%)hӱ'4Ca.T[W&`f"}ᢃ'6t_'zcI>Q(7kGʺL+Mb>~|2wz.\+8]&2'P f(ΥI;-? cP)'2֍n%BWp“Υda3.4dߖf'Œf< #ܘf7$橘E;h\EtbYA4\8"C;cpsx[ztgmvHy.z7Ʈ)fNڲ.oGb81eބUf\6EKPҵw;sh) e޻P02G膈R5sxuod /f <8bJe9ѽaMTVe2f*yc9/rtwuOEpd4'uŃ|$Yt o z)c _g992qvW-Uc@ Oy1ĺfU3Q땁1FB~Tb:\JJ7 g /I,h3GxΈ z %3{BBO `p-7lH51; ⵛmjgM= &ظ([gӱ6 |lEfTqr5U~ɦdYKVNA7ѓ!b{[wD]q_uj~k9|h7QGNv?n,E-)wqUG =&G-əѽ-2_ˇbz fXx;L|NkB_LjkMf.DR(?a;d/? eOi3KPs:m\›!ox6mψ_[ƇEELq)"c9i"j#>oc{K9LʚE|dj'%?R8*(xXR2qH]DB 85<LEKȩWe9HLjf&.^1&73ˍ\ݯ&VL8 4V6;Gd/DϷ7=`.#[(;NKbO%*$k}8ǻM7?8l7៳ym\[ϖرT&D܁Wg ׅ=B:в/# ǽ3aO;R('C|IЫkFIHޓɻɜB}^`J#㈆VVkŚ_~ߍNKwv:HX_z"93-w[)koi#]C8RA^̵! ޥ%ꀎ MwPl3^<ߖis(g!٫ +SR.8m7ڲkWv% |4'~G$R&ylrD5>Iq&kcYIܺPD9cG#eTl)bt0b* -*~bssJNPʷ'܍+p3=ku\W9[y٣3^]Bm-bADx {KQlfV#+ٝ\»V69CNyHlc뱑֢O3rxHhwKI%sT~-˜rVښSfYD7h#F6zFʽ3ŀCc߆h~COcZTd ۤbNQŬ8'wFeNp̏1X{Zp^;D购2v;ӥ$ù b0 D{;:/r-KDYYyR"kFyJ]? F7jx'2x+oU%L=B_qOF3>$$LYmw; aF& 5hbAu#ͬ^-9#z4ay1C]w@*"WQS&ۂ4NN$ZGOKOw7̒ A,jח^"ՇT6AFT6%d(d&G#8$6c}d!څ瓱6ӳ8lIf`Ty*ۊ'$4"V?ec {!S-9;nSn+T? /uxg20ǨeDO ͸;Bv)ᔗ[Dm2̘&N*[&Xžt}[u#&L msMGWGo{FM~^E=Gg8IÆRSne 1[#Yq2;p/CsD{xË́A;k;ZDк(i^Pxm#l`ʟAL1{")>>q v,E%3k-H-,T[)Ju:Hy4)J1%0kU3FfM g( Zj>Cˬz>0qtTaW-zVm?j wӠ!zQ1Yt yjO#3Cgr_NoZJ)PNONB&\+D')ct"SE?OBDggsmͦF4NEFӨ2E2iJ)-Met% .4‡/wkSJ5Rv-!S<>[U$f2^P7H#_#<=G3$3q#"DQ% T\e^%:KY `ha {2xv;e̞4Y7=Cw_!('ZGsPl39!?"Dn?֐JqaxWlwV?/7pzC+a՟'R'2Z6⺷O-,dbȚJ4B̼m ?t,)s cZcY_z|%?zkGϭ7FF)s1l"Fǭ\lQ33cI;@K"#\6pVUYY$C]gś^hO"vdb oPDϚzkr77 =Jk<0XQ9TjG/9ƅ9"zfէjƷL|#)TxƁ)7O9Ly5Ss"vy5Rn+p2L-8r546>oYG\zס✝ɄWr,ްla\M4oZ<#hfd"6/cVCCj^4|XMp%k(%QsW:7P4J&r~%SYT+G\ 7V*s0v%~q"z82$oOdZmѣU ͡PG'2 4Ӌme}'\ZNE tȑXʡУt˨(2AL12}:Y! 8Id1w45TNp /g`c-Ψ(F 󝤨IZT~4 Ţ<ơJu,3bV'|cnO3ě%2j'tUlTDz)k VDM*R[_̔ m#clg}DS1]:и4Iq,e,֝J7'FrG& ^7;= unCjaש~nxx%R\+ne$xih*fL$)&W.0loX\[_ԞJxdƬɧ}>b{}eVuf0+v}-]#[/@HZ.h88Q̲LUE>)]-(&GAJu%x>sS>KFI^s|~QD`"$RI8+;oN8)plXE$ns[OX'u|"ÍIfLL:pR:N4bNG~=%JP>&dJ$r #Mh< m2~j*otRҌTbizG +80Sd1G ӕ|z͍"}"7b^N4ܖ"./dŎ8Z}M_JLUދ}Aj2 I";åGJ8Xɗ $~P*mZCxntܸ`wܕSuC1>\(d¾B^M`ZX}VZ*zReTOb&xgMd[2)+ֳm(?V)L|䀅Q--Lu.GR7sZ܇K0Yp[B+߈DW+sKxJ&ZyUG %M\%:hXi[JGt R4I^:z ұh \~h~_toeRYb&QS!M>r/UtyGUt ]KLJfuU0PļVJ :)xo>0z5ǡĄ* ՏD^EiT:EcB|p{M`)bQL,WgiʚA1$05y2eXpFiå㩡hKSlR+ᘸAęj!y9:N<6<9Vs8{ѴOXf ,?RvJf{N$a#ޓ-Of_Dd|w&_d🜉|uP+aؙ7`C+Vl!,tm[<ة7 ӪpbKbFU)Kp)$똄pz[LjZ?3A"VXW)yϖA^n7@LN*TUYh V8*y>JF.b~VOw8_,1Oj6+YyFbRFsK^rW/Kð B.`y' 1VȂ~rB۩DCm37DF ;$]R#R>/B>)5H>裨4v[*ѱK81˚&quFϦyFgJkt2[:8-x=[t\mk%>u狾bz1g(Y)cP59t[5HmLRMA{cVSsd~$SqYgNt1R2Mث:28{to˵űaKt;Lx4AȤ>1s}W[u)6[i~&BmSrta0$y0O%^e#B\oFG% 0A#Lvʜ?̏}y*I16HܙF6 CF #3&LΧ/.{8\C5ͳaB,.\7&F1|Iq)lp q4>4-Ld:h[V4PVf^Ҵ  &vC Y,SH6Duhe@ifY}?V̈́yY]yZ$Rޟބl\.ǶЀuٺ݆~sjT-,/vGq9]j)s"(~RGrFRDZa&5Ըn0VG5 6UNK Q崵?NBRH~.J>?WS|KC!jJ1^vSY5k rx棒݋3U͍u:*sgP}5ձe62.,6ς~%ǰ;+x`i8U&`?|,4M*nۈ9)|?-zئdnΛ3xwe&'3zWgM|%cY%g1g3a͡9=Xgdz+A5ir$1#\ɱOQ'Vm p`߱m[v8`[10S&g7e:3lP^O'l(.<+n 5Dhd8lRQK~7ɊI jYf6.Ȟ"4pNz ʘ]F_} YbS% p9y 8&po;&\<*tGXChjA\azBBdORa’3kyoauS^|/r0-kykbH !@M\D(ph`K9%T4z YΑ |a%eF)o(RDŜ: 2{Et(r-JƯWSuL.rt-}-?Z^UKejPb 5t`_)=Z]7'HED #Ezyn2#㉊oH/p  !R=&y6 ,%3Hn:1C4ה1mKkZgXg-3*ii9Fɛ`ȗQCOWtXt8aJ;g #ZNG2'-`k9BOח&t2R ?n[B&|f16# J0y:JnCn C+[LŒP*FpUK~|Ah.N] $g ~^,F0 ^#윱SIxcc R U}kQr >ilq-3%#JUΚX e2(,|+1(B(Ô\~X_αR.b_H1n*-|%j5LRS"g"]JDٟ#z_ ZP3U8CAgǂb62W72f,iCY!İ~ycY|YtA, MB }$x,Pȍj.O2N[YȻm&_ld$WN{3gHG)5,l16 őj?Sg>q"9ډV(6y1P^L _&pvgVїFsj=U;hWmBQ Qk?\.1'\xާ2^~v)ʃ@+\e;//Y!}K8s4-BfU8]Ū{Fz&Zx62D")nt}3J98jڈdXh=v /ssg@94ړV6#G:afƒ_sCzq◰ 4uP&zdƷMxړ&G<.'1 YKq"ȠBe?ۭmd,i ec)EhPIO96bj$A|| K/Oq6{vu Ink1+*DZ1O-yt^W59𭍎Շ 4_``b%iڠ1t&,4+IT/7xHvΔf{\Y{h`eKXB敉ǣKxU!SGTO{TJ0R<<(GxX6ai09CxžJŁ؃aF2N?$t'^S t[p\;6Ԭ͵0qN8Pa4aGZReFN;:({?PUٰl-|Zߗ ]ŖNgM<{hͦqtOhV͞ĜȥN9dQc@"#E}A*1W^F>ebFIF&6s{,,4ӬK ,? ]Tx!Nq}UtB˟[;6 ?l/;(,FXPv/kL;6cvuEKV(U0vb9w~Wsb4e]Ҏ-zR j,vbQۻi;fezb֟u3?z{#sOG)r#u6i|Ƴ&TmLYGwYy":߁35f_6 s&Ff~ksu}#ږ=l0.t3A6\ZH Rboɨ_Nn3_I˰,?<2sCWFB_,ޖ|Zs|Mͥ;9sEpiULy D>8/EY_Z|79Pˇ*m5dԒ]K:R4#cAlIqwo1LA4;;?]#R_yZiy4xHh>!{cP ݞ-kW^_ª3=MH;O(q7p3ߏdҍ/*|Q=;^Zsɰ:8>"l+l5 7t̖Gz3tP]td5GoFmudӟ$$֥1[c+'tche2"֊#F-RMm]ࠞ7hy%0OM*h~@B?~kXBFfyQUZҗhq|GUT[bU: }7ѭ2GaqB;Xdjȹ]qxղi=;PO9>"Rg~rIPήRI6$2H $goILƉ0 #IBB5e XyΧ_>ym|%IH|'!m Yr[r>UpJ*W"OŖLꈯO>7I(DVFEu5v~?bxh2C1o WÛ*8Y+mw 1W{a2RQQ%Ld3[|ygpͦ(s ШvUpf.vTd rƖ1/] nJ =OԌU呖եsF"^Xѕxٳ {nr+uJ6 7hE %+l@]E3o i8,|lS5tґ 3rDO1MKth'qƞvӃzsxw Tm$XB_)VݫM5)jt&!f1 tϧUi,=~ 2ͳ&BB^(Z) 1qYTݕL4Ρ,c[.gfs3.~y//edz{If^4򻾕Rvz$=v,9ă>n.7;[cvllC`i-KlzYՙf=aؤfQ:.Y &OӧQ3詛s(^Bwø|!Y:UPm,Y:k`ךk/? v AW oΏCń)!Ӯ %?" d>BVz:&>Ε݉#j8]b`:ԕrpϗeTsat00ţuGI'wơ?ĭ <']<'2S,#M $$pdLkzFP\֋c*5jcZWS;j˽_5уiމη[#Uυqn }{$sww{0yRL|ˀ2= /ѮֱmfᔙҦI6i 6Mff8q8fq6eff8m0?FFzo^i4Xhl{kIٮۗJ> IubLeQVRfzi2zO)e8TBN-%\TmW1Csj>oTR7SK1\]/Ŵ*:(c"1l agMeboR8efy F3%[:)gRzĀ Yψdv|HxtWh %w-Ӣ?Qߺq~v|2 '2 < X|wjr*TNZΜW0GM= 7kyZȹr'=vc8\ShAӝoy˷œm0MSX6͙yvHR7KnL;2܇y#z|2Ud'p1)uC0OH62d_"g==b_!)a[_-Lwy9AQ-]H18:է2,2KΐLI .\aS,%nc9hWG?*ר(Koh޶ɚbV5+17I]WpuI䉹(Ϯ'eBND" TqX͂5mKW8Tź˹U29kd9]JLFX !YY 'b8+g{g$#5d潎gH(^VD&_8e~WڵB$ꉹ:=LOm*[(84AΤ=i욛Nx2b0QU/a fa 5O N5>%rDhBXWhaMXm0mn!1x)H 5Uᡯ YǓ.~`J_.Z:IϊF4-eG')bфq^ԄfyuiڒF0qT=v ֕M%Xu)KKS+$,0 as[L{#0nŘ8czÄITqI4^D|{4dkEE^_r#L+VGF2*#&@ wY3F‰A$6tţ6 !}CGID JbЅ$K#ȼegD5,l\wJp=M2+%(,MQd-M̶!eO SerKS*4F$Jy79\?[nUk S^,N%[ y5eBvZsu7)=? ϷaD G\>ʘ:JM=l]Z 7 :V"M{Z!^}[Ck#򭦒ف3=P_ ibxp 77+LfG Ѱ&'ѽ=;St5]t"\K (ƈHܜsN ov,֯m;Mwtݨ,f!Le.wI&vP^:vHߚP}Yx_!oiGa*g)I2R1JB8'&CrHX>Q%ebb'wr׋#Ez'~ },nS0Ws,!Mr,ߨ8;X!rQSP*F7|(gd2  @>)iЬp)Lyz4p[{j0GaVPҿǷ^5͠i3őJhTLo>VE|[gVb.[+{Cϑzv8z /-fS ],07ךG7mh0˧|_Oy(Mb3O 76aܒNn s Dʨ5)h%au{ |Ḃ-CU()]Sm!G XHd08;ɓzsf0ҙ/]Ş G:xCxs9ًEYsWaLr)vR8`<,Dv0FƱeXt+ej@ J1TcPAr*~9.o)1sg/yA=EZ$jHwGs@ ~E8Ng$Y9fܙz5ٲ'-ץdϧ~`!Kx9ZCPwj%\+* A*%2ͳjry̟+qgli8Ş^CQ5Kec "s-cVsYo&`c#t }fjS %(B׏(>-Kyַ+2 sGj10gZX٪ʃgpYȅ8]e<`s"۱>Έ?ø8 c9pܔ,QZb.狐OrҶ)Yְ  i$x*䱥*Z{MY vq]JJu$ }}\MI/䱱; Eq9@@K{eڕϡErRhYyy|=%$[d@Xf0L Gɰ j;,9I6|ɫALpB0%2'|uaTl_@ ơ&:hm̮b7em\4zuT8OfGD`P{}d<]e1їՙ*f2eNS}#$N)d!\JO*\8MTLhȘuqͣh&LsF]7ahgSɘTS&~7B7 Gͼ}$8vۙdI OƲmM#>Iސ6(~l`-MPC=Xq6~Gݨ@[~r1ev R{19]ɤ _TJ$u9_--$j\]5nσEdZZA\nu-vjvU%|Sy*XWDye0]^K}x+9}\`eG a\˯bj4iyE&"Tǩs62:-]&vvm3s džQ|x&dY`q\؍ ۄ,e=ŹUO0w\ٳ"VRSyfdOik#$޿#gtNQܜ6 \YQ1ׇ=B}eE2(OrGï-+.pZݬ2zsQ/|^̣LNXűOǻ=y2v -趴Jnƪw7U7#RsW1#)fSD;Qrr..lW9qQ*Wd|nlʦnif .Ebߵ|'"zϗn޴GڙЪZwX(SǪxvlEgyۗC;L* ~:EA2m+|SKJ ҸtsOX$&$\1!YSt1y#ػ!F☛Z_҇WqkbB)<:f6dA-yQ2VR]bDgM4{k5˩(Jd "]a`9,IBG)aӱ4T؇нc( |Hyhzsp4Ob t3y՛}A^I\MEjG4: vd9+2m#jV?i-sa퇦htgUכr(yb~H 鿭.ۧr='`TJ)CJ([p#+_ř cVj#.tMjG>;17u¹9V]WywZ.kh$ ֩84Zb~h2`Ys/HbưA‘;`4:~1Q b(cm'#,)YK:1{9.#_!+Rh-/I~rV, OʜE._YoS ;_ LFc~#nMO<3='vaZ!O!(? YCXO{{~/+'EIJc9BF b<=RzkTj$MUxS_TSA?j|躊|PfB aGGCw`p|aJvs0 3vі{6ٟCHPެ0Ng/Lf'çXw7=qߤ`'n WbibےaK}$E<_X0|P_uNH m͂ڱtd{'Zzrcgpw77#ivb ߗvƮh !'BhĬznWѵ5:::VN,P;]bp?ߤcڨJ:_ӡ|[Dy WM sĵ#rn-0G*- iUc^.ӵ;RȻAX?48ڟEx2"S4d3w {pKA"*|6Mo;_iekS:2fb -XtT?Z\W)ƶ|6~T, &I%nH.$/aE> Q}GE/1̥M g&;:ÿfZscg2%;ED'zsDmO0^m<ݹ+rI j O_jȿ%+xSZv;B |[pYlҷfXfܺ,Ka:gA|DՄ_ׇӠ9El 0AP N{ݤ /P;'x|y=V׍Ktl!4C\f_lly}ہ^ 5^ \z}[nL S`bP$ERt,1řdUg?vl(<9On6V\Mb{aF_[ŠYz>'XEzvAfQ12x%Wn+fr1(ܡbbřW0G@5U\Q9A_DN{̀+ HG?2Iw`./l<5ڟT vBeN0AN[nʐ-tŗbF V03K<Iϐq/R:gs, AEtɅtY&h8YJJBΗrgrzei#>f1 6:k,y+b8k%s#iJ\{ӹe h}vY9hld_jZZ5rZ5sh׋k'} vx>c9Ǥ'yiZX[/v'X6>WB%$`X,Dz+&^)襩9ʬ癘SYD;%kTMD1/M3 dbɟ1DdlߟƘ-r|8HOxX2s<[$0U(>ŅP_mǐl`߾zkZ}eܪ u{9վ*NT!%}9Oɲթ~^Ǹ)]&UO2Fhd3 94d$7_rLє~{x xO FL,v<[-mo/e_=;[ʌ\(^ʢyD[7o]( qQ2e%e].rs%z v9p3ӥ't`P/3ӱn(Zĉst,#bU!ωaGFߙ06.&c }TwWK !M՘;Ku0+-V2oGW j49^8*sC$3a]"F%mUHf;rEft:xswX:iM|?bj$/d!=M ÿ"#ޏ{qH31Xcqm16PrbI dwmUݕW\V|ٍ9~|DBi&3e}՞ʢM! FP c79&-{]9^Vl{Hi\O}(H^Ŋ2(e1ly6^ƩlȝX6Ks1tc$04!d f?|hV~H6jP;S|L@_ke<*c3r|+/ @*cb:'¤υI/Oن7]YfғA~ ?ձL Rh6bʐ(dBsI7K&.O'$fX@S77,j-ML%Qϵt9fa%N *8MNIbsG*z5" _QO1#qaa@߆FIh1N]+2(} GgF\rfcN5˯&[6[p> FV)R JIM%AZ\ܦf '>E/r_s8)yBFgے_&&sWCᳱ?81缾IoVs.b67PujNm~cvUE:N>/;/U$rD%wW$~fnbSੁ6֙wѳ^?Y-hs_`?^s81)'آQ\bi2A§9ɀ}3i} Dvmhf] r`;.NWSn6i BǾXbǽr/帍 -CuTR[ITP'Mztռڽ>.ZU3:^qٍ*;R  }XO/(:DJsELvU:I\&,7H@{9%!%>`ڠfKLAC=_W g5K7-؊\ q8=h39[ GR` 0?ykbZJm֬Ϫh8ռ_sLoW1jnZͷQOpF%/*9PSA5*e)禜GJxlA #M:ہ$q LuMWT-f}]F1aUf3>kʌ2va J=ǡXR<5Iz%cUpPkiSo%I;WѸ< JT_Bn]l@<ޑ=%R,U<)oIm:Sf S'Фp+uh1\{DXQرBiB8p`=ZTuM6#'&AtT̽2b+˘RN SdtQ8d {/o-bf|"2/E]$,cKGwZ`L8۝1*2u2Ѿ25ݣ9#_x8: Ν$ܾ(& YGv{qG7ytI&eb6􎊲Pa,[ʹ ^gi=BܸTO[Jo<\ytMgl'd…|DSͧ(O.蓪nq9r}^C- xRQŪ1I 9q%2&@BTb:#o9#zx&g!g/_Q!{؀-ي}9gvg˞:#, 쎿m[r)aiб >VR\_Ag W¼Q|l'BHB|`ɜٴ0gØ0_Ց-nX${Ka &ҺqliĦ ]dQ;*Ǡ,%$p]!P2k3j8?WMta~}t|ݨeڗ u8.ZZZV`6\WEAbw>nx,ͧ~ҙs++X'-(l܆:j;!kVpX+tX F|.͕s feՍ9PZM͞*˪xCr%FKuji>BCjsR\k2 ٳ3BxIKkGRe:iޚF*k>"tou8' tה=m<)̸U_gufCQhhMpV_Oa<گ*a:%?"|]ʚ-e(9zEq'+ H?yѬGC_-Ԏ$nڠXNabs97"\1=#f]lEμǥ!k(WW"co.,x qpZl4vXU9K@`鶦Ț@Aԧ;[i_άWS>ZM\ (p8'chB=ֈ֗ oOdi18Ia䥆R [ ~_ ?aqjKDPsV9\է2C }rŕ;Y쬖,Bzvw56*>`B/%cܟAL"Q ziY[W/YS%n SKթR,m$ aY; υ"%(I<㪓*=XJj/Vry~tn2~U~d{Qj1QEz]`%踻_-5*NRTMTG #\K6qr gK_wew7(`ƃmΩp;&~8lPǪϿN k:5UPV f֓cF|tq2t*ɇR2+?!2H9VgrǐT\䏩?T4eUy+x`JdXNɍJt&*djM'h x礒Zge -+gi5zWulWj۫Ѿb*$TT59nUDճ'ߣr^%3VA:\5"!jLU9\\c9Ұ|{v m{6 ;x˗,7UE FM4%2dZ_E2nM>{v4Ny͒X#)΅D5*TAJ5Zj枹sM;M3y:&HZw¥%onOmK~!ŬweCKwڏf(1<:0h3$wHWܝ<*#\FVbze?>RN.dn]e^$rٝ<~-*FIZr:RD2$!)TAw[`/o'qsc±0F!mGXN7Mwi*g3BGN) ޮFFê;*G乨U/?-ݒ9`w-q]Bsv|.nP3ry!@8gf#5jzGWaXEot8EX'~R b[EU/‚*&ܬKd*NI7j٬):N]_$YK;P/c唸19bs,䧜yf`[ƑvfG2W՛Ӵz 찺L_n^<ʓג_.!#%rJv=2J%]򰋋@6-?9I\ǛAVz L:bBmWɁ=!7nZ"φ$g|p ,ދۅVxBf3k&sYe̟L94<*|A}KxhQ¤v)$GJiӯ){1lét.G&nጌ1 +б Jh4*hp3&;c8IF;aUIKXOgcF+1Tl6e472k 齱.OID5Y*4T]g*9g=:'TM%5ze)e~B§][7f(3? [O⒩4E3=eDʦC+Jmvd"'Fp4@ Xٌ΂^dJЭ|}8kLL'Z÷M)d9F"TRѫf/(Xl&dc-=V YTOKj6V2Z r1},[Wb/ cOE71R(r/ͣ,Fb2sSRP26w+pLPe\h/]ͫydla4Qa` #Qu f໐{yyzPb'󶳜K ry:2AYenE6Mz{&7) x5N 2ڊUxe4KjxҽBǯ&ȽF qǤ ؟RI4,$Yi;#w:r癴wQ7…OODq "jXV/j'bUW%!~}PPPLA3h8xeHzv]ټr8Ob5YYwoi-bbƏn*Ԝm-a_2qxq7+䍴"XEZ15)<̰aWL %ӨU*pu: O%EW$Od~]ՙS\X?zd0DN3O>$Pʹ9 eaU0!( E^MBulfS1jG:.XTݞvU˱rzoì/"rN2z[23g`_'݋ӻiyVshD!oѱQ!sLe̟'CUy9K*R0CH549c:/u@y / 8VSg UDD P{< 7_g-q=3o&9$?K󷻁 +sFWQ}Р;&xXJH"zV򼸚Iki5 w涸gv]Ì5~~GۧԯzjO'rL\Wq}Xȇ.}7_Ǡ)9|HIתnJX&(fضL}fGޅ74{Qy]Cv/S ,""-xl7sq Z%q GaԼA҉neu=7&?qyj:=5 & k&H!+_$v*9&ߘ˼!M&o4\wqg)B8ϝ }ݨ@"fLpdOc|M4oV7tj3vC<6,(3oW1ftKS!u,[`*hfG*RZ;# pň7l=M͸"'ajM|i-frv"2-Z! 5Pr5T<"eZ=Z*4cx#J#[IRAX߅ pp{>ENjF,1W[Fny 7svd >䙎 _aJ/b[ܪ*&L:js#}N㟬jNuk`oZ~WrcчիCx~6kө-s.˻JдUیGi~.h^3e(sTz}u䦐u^@v~E϶-zcxIӺD}9X*Pg5ؿіNs#w)t[ܒ,EebS™TQ#G`{)LNZHsW[0]!MaDKq vtz[>f(ouvTodiI{V|ފאL-*Os",a44WMЁvY7DYz14HLarO&YOVS_rlFYQ[C%ӫT ], E5Ԫ5CxlϮ w?rE91ebj,$@I *O}%<ϕuS1kQb^%uS@8raz ܤg;z-p 467aVy8Xb⼞9 ,{QKQЭj#x[Y5c9GUWIe=['H+uo@d=qozz.}bXv:etZ_SURc5ێ޴3'7g=f4^Lh,C0Zw7POW 6e|vs競6":cZ$ -F;.-QI\Tc6YjFse쏢V -3Sc )W%t ,?Yt,gǗndwRu~i!CЂ'q3ڕJ;_:l &#Y%I `EnXsՀ꽁+ Ik`s xKԋ"/u"ڲvMYЃv'Ari.O} n}$,#𧜽^RHեejZM:*/FjzJU48^N]9Cm(fW_G9}2֨LCK=nʸZ$>(aw);rewJ'N\)AǀJkDrŘbH}ɚFg 𡩇mbmۮ9^b^ )=Y@G؛UÄU{Vi%U\AVɎ^2~Sd\4Gx-XX<- o2m8̞vĨ㉚ݗ/^Oj/KspX]V'Yu[@T|w _#]uܷM/fp~>f=dw{v! 8?OlLY)$J¾b*XX[+r.eq-Yw(k{, < rr$l'G 8o4_"̣ A3 kK3`e1=3:3nF*[.^SխE-D])๲ ߏ&2ԝٲ;$\-e9VAɗ| oih,hm] =] ZǛB[)'*zFu(C&Key@9IJRs{+;e a]̪Ua5r\}S1K\B߃*+9ۢ2.' _Q G\p;̤,q nG!Gۣ V^#gpV{WIUVTbTJL(5Wr3"o^\S?Leq?OpC{֍s@c & $ 5/拪Wy?8~o;~k5%Co^DD>F^{1W)=cVt:G#i:9]wnHa/Dk}y6ᝓ<*K fF+F-qV:UsDXeMBmI% \=T`׶l9=ɾ,;Iho5 ޥc; 릪园z|%"B"z7W]w$і+DdX\ 3CsgyaӞ?7E>LA;XWFas1ٽ]нDD2y{4#o&t#>Osj!( If״,$Oظv]Q BG8(_ ؠEVMkJR:h,zUBnޜ4tԔAnA-(smM.\2`P_ S(61az9*TpⰚٮZ6hNK-3vTØJ˱|YRZoI {^yS¡Cb[ek} :(2[FU2м3$|8 5D*ܯs4\,xr=rs,o^%|yGx\k5^>Op3z6 K1}R$N >ײJj:cRů *FX짘F{3*N5{8,15M&qԖqi cgq$Xp 蹖#jvOϊEl<`jcbfiOɴ1F8/}V;Q?58j,FSS5 ǒgsu37E3|Dgdh êE0̴i_OB:I_Ģ{2ԬajrC4zpn}0ȵ{u +9Y8ZUSHW8#%JY|7mO~mw ra Silg,sLCJbGF6֢'Bq-sSd||"m[*W$BޕHSa[e.lѱM/5ྺ=DdwNTrKPՈ#HFYl/#㪊jpU{šM'SZyh6RgJz;R9շ_Ƣb~JiBߟVJ\SUM3j4 dl9U |G+Q\9R(Y4j%? NE܏WQb̓U1̡V[XstK$mFc_73fmq_M2Eer[͎jQ&7a>pc ;TΆJ$oy9['2h+̈́օ.\D3|0'V DZ)hͽekSnZb^{YQSF}X Y$Er[A*FLWzi= 4MƭQ(m&pޞy#pǨItJf" pI8 me] c4?y4cX;v*mC _;Z`"R!dͻr&)>MAJ#$!'=U[{b tܞ&Ut)gDէҒbYܹ/<=w5֓T ~˧JdQ5jk 75BT2FOCP7[FșٺX+ŋUe=a vPXzV|[*Wj+pRroC!K%<:i,&"Rx\UnԈ=wσMT9gg qG Abz.)Ŵ)^Z̥:ͭз֬O'{jh 1Lߎtv"9#Px"PՎ۩GEe+DN涱rg{fAx-V C[Ҭl/#TDʙ>ӤnF'^&%?dB>ZHG!F<\k`;Q'XbՖC%-?)z8z$SZ $D+L$:}/gx16=h=ӏjš1(E/M6xGל&Q.jҕM!^'3Sy$54:|5صKɒzZ1Aϸzm xsFg>}(G, &QcBZRSOɠ |F9 bd㝑W*'e<-*KtB/| ,x -(Źp sݙ()tj <ЕrQ(a^ݓzJ+C2E#YvݛĶn+{QCbCU^`}R z0gwBVtʎ<0fl "M)ĬI{$qeMA_۪fao%zZ452MO{;-GшAK:53VFe jz frs$S_8c1 La؅ n~SǏ8KK=YغeIJiz@q(W{s5VC%qdx!#d ;AiT.AY\u""hh|Uyf-_nqQ7_$YRVϜ @3kjئ$]ډbZI(u/dk:", K8o1 evuWBH^4>h{1əi#-㆜*y'GQ nn K>v=VAUx|݄\;z$MŜSNb'IA.bʟ+35=(PGX"C:34^p$y4 ]ӨpΧv# _aq傷YNsAThhkzѓDFch:dyr''Xt*Xx~~kt*hg_;_2b U^A'Jq"-n*g%qpa&.+vHW> S ͼ+f҈X?Ir2=91~P:Nw wPCHZѹ$tve=yvc_RQEwq$12 2zP_̰ $raSpY`ipq&cqM3DgDJ-$!,ο]x>8>(Zqcd>#?S,"n{-uyVWeSrgCW:ߝȼ/]vFtWEw^2WCxS_ڎ~HgeZn72۷G* η k# 7qN72t'/u",`o ij/bGW=hdB_ksT]_62bW4}^AYl%hΗ%"oRx3m#2a*WL#aj\9r!w2&'ӼWt_GIPl]0Mnc*twMi8B[Q{хsMS{4z9"Ld$IXQf]kTD+#OC-MBo"?Œs2Av$('-Ӷ1FL~mxcHkxK:"9 <{ wA]dxU̮G|Kޜɺ)rN UaCS-5C۠D!1IKǩ_v}F ,er⢌& dL=+e\/r̒ThFix8VX={-d尗-4<,>KcmN37ͱ4ٞ1&3hK9/`R܃Nhn:ZYEf}N TK߹.؞Me;/(n>QGNr=%YݑI4swbsO{[o˥VS·&assu-_ 60rv9 dyd*9c¹,qnnLšĵ6? .ud,o@Vo] _pC{IgzrӚ8yby'qx IZĈwp! ~׭Ws8/Q14+Lcp&48?ދ8aH 'wc-qԺwxRJwOr] bGQo3G¢Dt&?1ys*C#8:=׽ƱpO"АŦr62Y򕆛Zv.~NG3-gPѱn *^,U1baZuhXP6jiIԱV v}rY*8RŎ}* XY" ~JciP;y3B0c99KJjB5b#m~P[ vP'#٘ͭy"b~ 1ubX۝9هt1'nS!ƀ'}C0ޚʓ!kEJƞub)' dM4a-82q?DK,ؖ (a E>?_}a"ם\܍-e4eƞZw HWX3K/2{˄=)S%V_RC檿q%I v2褜_UWNߨ \5>M#1z~Z8Q*S`iTCq*i8ؼ= ةf* 5@zylsS#A+XҭN7p:I<' [^ߵyFn5ЫSGUTqL%qK*vu $F6>@3)[!ṞuJ:=w7x++V1Hvp3#t- `s%O1\;{)55)M4׻`/xD"O1=o# r(񥴗=)&&-Ę}JgJ^c·2̉FRٟ(ā^a2HL\ćDrv'0zMf˭0[ٌO_j/jRWBphO<=Gڏ{h1k+6Y"zte٬+2ZӕJdWTAK嬱򸔥EyBiR>3Lþ<, /H6b1oi-tMuz'eSo=<F %*ޱ J ]ºiF2p١:fՐ8Q.>Y)ӳ|I^$kHǞb.cfN U{Cwm2=ؘɡɮllCsݏ{Sڔb4 .,b .%e1qF,p=ܞcyxWq\<bb1~RIYEX1j0M5ivk ]워N%bG9r5ng,OvXb9e?`6 =.D-j"Lա8HEF3Uf+1WΆ0wajy'!4H*BTBh|/XȨrLPCjhTsZ~b#X+0Wy +9E#yfd]kNFN4205A- !;TgNG&GM=%G#wJE*\kAнaF. [.'cX}%}5raKgWv!/MCg-3H5IdfN8+Z]ؓ+:a6Xc2snue - jȧ!Dy =9-93g,}7Mb; )'81S\ *z!b4&8aEn; h<^ʆ )/y9~3ğ+_c8ܸ=nd3%UֱpY#d:d:U#֜.^3= |tR#痁$,+OCd=/\tmQ?@U?#;gH3t7d>]$02%o390 ^R-bM (c;?j9(/n @}-N#ĸGJtx#okk:۹of3%6:&<$i^$b{G03 },q}?+:;K\J$lz+iM%N kk;Ȫ"cd( 'F1P~)bMTݟ6ܞ=D|,Qqtbӹ#K8`+@W хVodţU:ifCZ &cC21$RMߊhB_SIKT}|~ +-{r"_W{պ{09 * {}%s st6猺 [ي6gsE>ũ;n͙{g<..V.G7 &q5xQKnYޥE&e hRY4 GeYVMpM^r)eʡrhͤO2Up*>_bVrַ+%zz%g\{g]%U3M%oV0uF()`4ݕYۇ By?/-=ͤ\ss ᤙ 4Q#e*,k; NfSlSaJC+}y>C'VΚzZ꛲0gӧ.<6Zvn_L@]-A8Bo0gHglCu\"-r:]]x=#WVx=4'SדGq eӧDg%2l29Mg"qCvyi c5r 2NaڦP:6Q/o ̚Wy_tIE\_\;Yj̠?$: 'Fx'1'yŎUe朗$2JTqok4ZõN2%ę?V)&i%d)ga?|rz8Τ^F% dD-"y3LeoS VHW /b%c+X#pTJ9XIvh)]'cA>{"_;}KboSٰ"6=豽 GF/4[ܧ JtͳTo%R&y&CJJ9mSs<MfXMi55(L~=ܪ*]9&uTK`@'1j=θr?iYo_Lɟ#ۆn*SB gDmq%痣_6rF,-">5F;9I9R2 /TvJv}3cZN~"%ƕ[POGTĐ<'N}$iS Vp!k&3\gaԺ]^t[0=E<G)_D7$cK9KRe8>cfrzЩ8—cy<7ɐ\WflIKKhZ[IY\IǷ4)"K2D`ֺ82"!Z&s6Nn<:ҲF?-xӎfts Vޕgc.r㡟73>wfhOf\4GqoTƳ֝IjN6Ʒ=G:p,e=RmyvN4;J2=Bۉi^Z]4-oLk@G&I$7.tQvUMcq6U7z8~81H,Pveҧ #ZS@dW%t!goӴ >/E,T:0K3KV+ԭ|8c_%k}1]j ^|îJV^V1tS򱻟H<\bMY;縐qěd?뙌M~Ӻdc=;"%LU-O甲i>e'Ckfi<.a|ʼbbdzC2։nDmK6=$+'oc鯖.2ט*[`(W IDVN@jޤu趧CSz-ɵ(y:]{ YdsSmk;3}IQf(4_Ҭ3nҙӒr:­SEV/^ zFgd~(T,+g;NuzILe8O"xL4ߛ3LD-cy~<}o'1:Q˸; bnpf$NI -I+&ZQĞeV=$+Ȱ`IWu?W䞩޾fT f]h/R%p4\VvđItZ=m-2$ZdžM{|Y%ȅ:4CUW>GφfݨORuk;=ĈN?!zyT}U)'? yݎnׅ`ܭ~$fwi1+cVɏrl:oXJ򽷣Q͑[ay#ɝM\X̼۬o2eȅgeH ,b1O&g6͟.]|N~" Q|qtsGz$bJиQJS3f 2|=;yr3/{S0pE!۔VS*rNU^UΰMgaw*+gO \8ĺxaMp8FxXfP<7rXX3OYGtdi&+]Sª=t2e0:%ho4èؑF+SLw9QPb½]CyJl[sU+^fr&c vCdRCsɩaXxZv!K ]3t(vf/f}ފYaˆݜySN `t(bXX=N!\;A܌xlD2;Sδxİso;X2U|pdQV\RvW}EU:ҩ#jND*|_@jB\X<#8<> Ƀ 6$;J9+4C|+E7# KxiaǯݨWw5Fl5i?ܜi=΅<6Η)״(~ ǥ[M/[[6Jm &t?M+ nzaՔ^m B GnR['jD@$:/ݼfѩW2fn+3=?XЁx`Ѹlȣ1Xx0m(\QD(  IAÇ*`vZ v֑l3\2Í&:l66!7#$ hM9hOMQFmyVCnWlΉ`[/F7Xxn~fdD*R*ݭy&\I2OXŽڱx6w%% .|FS)fyF^r`#Fz2QϏ*_ߟ~tΚe:8C_I.o6/S.4+xUZରgM\yΝ/)޸^DEnvp`.{exd4ty>t{mmu8݈^{=t(%X(@E FJ559OC }%om&-+BU\P506qsik$ү0w"L9Ȍ?xRA灩Kn D,q7hSƤNn4݌z&KXU(g`^9̗\h¡7#'@noY%en[1WFqLg@kW*q[0ݜ Ψ5Ϭ`O9Cy$5K@D/&81{dn %e㒹·)?4>CӪCKԣgKIy\et,ao9Ƚ&wD}we7̩H*O9ɸyсTC/lz3uM?xqz Ygm}zs&ˆzl(c#a|GR g H\/55b|:)/1 ̅Pr~Cw0<oT`lGK QͺHaʑ l1dtb2N9*sb[F?pN4-~% VLW)6.KˈZ'M mvX6gSSx8ӽޜS'g72xÛ'&l4hy4,Oe$J?8/} _/g_6F8^/+آab;+߮mΖsO&t f8ʽEwۚDNo2/A5d|;9kNVwnL6<D)E_[ H Z#gjgs3,ì)|FgP!&.bdg"ؖatȻ^e?+sQ_ i;0R6 0l[B4SR-@`)un cٛFha`&hYntt)IHJt{I[ڵid(sBer[)-姷6O/S`_*?Q9I~,F_d]/:3oי6Զ,:nÑ1ʛNfeXdHPղi`QCcX׃PKXcT1%oSs;ʜ8ڃ b:>'in˸D+0X] %VŏGjt&q?=vvOV#[\ܨX/f[2:X[Fq݋I[XKRKT>ԕVGV1yiI&;w7/uٙBBoL$[#_$rIV.4UEVW*-["\h݆e"+fc^xi'h#+m)Om]bt1O!f(C\ mnC57* >6OaV{[bO,[зE<&qt{p~T)5/u$q;>E>(Z8|Έ;߆XdGZsqd`SE}.`ҍ\Fg3w{6= ,cR|_:'0?vxk )OOr{pqK^3™of쐫RRE׭" c\qT"L)YO(-nāl5Q !mN#㪌Co4b@/ cQV0br2G.-?3te"q'iW9m0OLy;=Yv%~I 2â |;y{hHQJ׺ɀqo9nhlq?C g(C1?;5E8gS1+ Yc1/Hti31pG sGl?(X+k:emAB*f|~ |CQA@:F`ew?Ƙu!<DHn0 PC6h"ɼQU7Wj2wfyj䴅JG1ut'L.s] #c;"Kk Fa'>`Kp{d`?Ԕ28qЊ#Eu TuH GH͛QqқOq݆8Kj[JXs'ܟ Ke#YFA&rqٳe-k8։w`t]]S|t4pPwo1Ai YMGefR覩RRiEGnxaw~y: zST4+ַ;ЌsYљ-=iR]l()6ky'x&x3w 7'/zuҕÇI|mɤELfMycTc~Mn*[δBc f|k {XV; iM\#}2O.uJf>zXAצ1aoVxGPEujc*zk^26F]<;mwn,ü?~;Z0_:;/=ʍ;N knkz,y! uY)yi2MGR )oR!Ғ?[w#eev>LyM|=A>V"U'+}%7JnIulT7J(iRV3oxmq0"+Tmj6$i3\F٭q5.{֯ues;l皑##N?vfn?;K˗56L.5޽($ɦn/ōiݍ&3>z1:lQ6yو=3/lH&>X/?*^I& ӆáWOfXv|/Y5OތEŭiZdiv)|[uB_y|b yIbѲ:QFUNeje{|2m#9CO=w>0xAq\X\7T`]Jݮ& (OϏQT[{HCo{HG~[&jpx%lF7twFe_!ez]%ֺ 7yDksm?}λeK|d)B#y_e)t<c-:6e $AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/oo`ants-1.9.2+svn680.dfsg/Examples/Data/r64slice.nii000066400000000000000000010005401147325206600212430ustar00rootroot00000000000000\r ????C???n+1A/=BdhBGpB=sBъBBHMBҏBGB^H_BAD2@?@oBIBeB|B" C CC5CmCtCCUC Cg5BwB>b_@zLBB"B%CC0CU1Cq3C7Cc)6C6C4Ch4C6CW6C)CCfB_|B=%>6?Vy?ƍv?6??>Y ?A^;A.b?=2]>ߪ<,T@DBB\BB'Cu!C;#C/!CH*CP3C$ 5Cr/5C9Cdq@s:As6B;ғBBB֢B$BC,7C 65C:C@ACANCUCYTCyNC|fMCUNC5QMCGHC' DC (BC^?C_CD?C8CxO&C C!B!@iB k(C;BC29C#~BCJ9C?CLCYC|TC!QCQVCGCS:C@03C/C(CG#C%CA$C>$CS=3Cf-Cɼ.CE2C&3Cc3C?-C6L%C!CqClB&B/B BoizBgB8A YA佸?\^AZBBC@"C'CЈCy~B! C367CkC=C'JCu2C'0CDACWC3YCQVC:WCDCS>1C'CN"CC3CC7 CsC$CCJ $C;%C."C+"C#CgCM C> C%BFBBBAC3BCGB B$h?@{AC2C,=C@HC'=C"C\!C3C;KC޾LC>C2C:i9CrBCD%1CD3 CGC2l(Cm?CKCmECs(C{Cf.C BCFCC9C-C XCBrSB$B9 BX-C9C8CNNCVC$&KCxIC-HC(NC1TC\CD]CoVCxGCXa7C,Cd)CM,C'CDBCjB}lBCbBB uBCmC[oBw3B~%BCNC%Cu#C(C3,C9'C!C] CI CB3ANAAmBCi$C˲6Cn?CɆ?CEC NC 8C.$C\C7C+Ca#:Cg%CC BTBMBBBnXBxbCgCBBA0B2C! CcCrUCs!Cpy(CY.CDO)C )C0C&C8Cc-BjBuA@>BBC9C:;CHCMMCNCVRCd`,C|5CoxCsECtIPC[Ca^CH\CZVC.NCRC}ZC)\C^CVCIJC NC+FC*6CC\BBB3CCI"C9C C"BaBB CCCCnC؀#Cc.C).Ce2CA7C*C3-CzCϜBlBhABB1B.8BϼCP C(C}6CQECrOC!QCPC=Cr*%C˜C9uC.CC}C C3$CMCBBHB:CmCZBCMC)CC)Ct1C8C,AC5C*Cd>CC6BzFBS A:CKCtOCpOCBC+CRCJC+C=C9UOCWC%WCPC0OCUCVOCJsJCIEC/;C(CP/C;C CحCqq#C -C+C6CCB:B9CW6CCPC CCrR$Cb1Cv9CZGCdACI'CGCĊCCB>B%e8B"AAo$ZBהB3<C CCRCC&CʿCC &$C133CþJC(bNCQCuJC2CCCF@,C@CQCaYC]TCIMCXLCMCDC:CƗ7C i5C24C~'ClBBzC #CN'>CvFCgLC LCRC[CWCUC/]C2`C`C^CÉ]C^C_C,i_CLCE=C)C5C>CC'C0C .C<%ClwCnCV|CCECCC C C-C4.CF8CEC@CB(C)C3C CCB=BAABZB i C#CKCMCCCC#CGC CyE-CQECΝNCQC|NC-C%C:CsO9C8C8C+;=C,HC?PCU XC]C,`CbC]CYCD^CMaC_CjVC3JC:C-C (C3~-C8#3C3C!0CT#C5 CύCzC%Cb$CwCvC!v CCa)CQ:CLGC=CZJ,CZE$Ck]#C%C(C!C'B6BWACBlB{CCCC!"CM!CgC C CC)"C/)C:CKCMCPCGICϰ5Ct/Cf?CSJCTCwYCOCYCCu9CԨ)C&C CCHCCÐBfB7BBC_.C)Ck$C!CG#C4CHC WCT]C_C_C#[C VCXC_C0^C(YC(XCiPCBC9C#:C>C4Cs%C+>Cq6Cp C.CW<1C+C-$CN"C'u%CL5CICSC0OCICJCICx=C-C'CEsC?B#?mDA{B0B7CGCkC 3CCnC`"CJ&C9C$CC bCVCCt%C0CoCC MCSCTC}QCSOCKXNCPCRCMC,@C!'-CvqCCCbC` CpBgBFB@B/KB֮BJ"C,7C9Ci6C^i6C/=CkHC(OCRQCNCGCC@C8CC`MC:UCLYCG\Cc_XCSC:VCiTCeXC#tWC@NMC1CCo2C%CqCaEC3#Co_2C<9CZ5CP1C9p0Cx2Ct?CbOCSCmRC"OC.KCK@C!"7C,C&CCB@B)BGA"BfBN&CRCCsDCVCCCjCI$CM'Cb'CCCCK&C#t.C'BC'|OCPC!SCѥSCNCºKCOOCJC[T?C.C(CTnBYBlCC=BBBBdB?aBnCm-C*9CxGAC~DCB8DCGGCNCSOCtFCǨ;C_*C5Z'C$:C;DCtPCy]CCYCSZRCӥOCRCSOC/VCZCXRCISKCک6C!C5CC+CW6C>CʎFTC>MC9C'$C>C]3C((C;&5C?CECLClPVC\CE[CRZCUSCs9C^!C<Ce8C2C C/CaB_(CAC4CnBB}@`BB CCE"CCC4C9{CCXCfC&C)CW1!CCCCR7"C)C'PCIC RCSCRC4\Ckp]CPWC`MYCaC[[C)a@C+$CQeCsF C.C$DCrTCVCC]C4kbC:]C+XbC|KC6(CVCLC9BB_BC/C9C0C-C;(C CC+CrCFCӺBȿBDBBUBBCfCCP)Ca;C2HC+TC0OC PQC]XCI4YCYC)YCZCUCGICi,3C+Cj2C=:CJCgYCuZCA`C`CZ(]C*WC6C$C CBOBBBpCU/CO;CkCCHC>C3C(C;Cr28B?->@rB9RCBCt#C"-CC;CF+C/Cr(CӷCClCC*CW,C6,C7!CWCCI*&C*0CDCHJPCTC{RCQCSCMSKCBC>)8Cj-.CH51Cg C|% CC_ CECICfC+C1C‚2C2CJCCCCK%C)cCBBB9'BB.BTC]CbC!C|.C>CHCbTCWLNCUCraVCKRC x]C]CcC״IC}KCACz/C[2(Cm#CC=BSA*AnOBC-CJ"C%CCwPCv(Cc.Cj-C̎ CCQ0C]Cx&C)CKK$C CCGC9)C֥6CECRCgVCSCD4OCCOC;*FC6C*@'CIC)$CC*B|Cx C6C#C8%CP(C R5C }9C6C)C CCD/C"CXCBB}BPBCCp]'C)C97CEC,JCrUC-wQCWC'XC(SCD0[CXCZCXCH\UCR{[CBUCRC?\Cd_C0aCZ`C]Ci]COC&1C?$C8C1B'BC-(C/C]>C.ECKC[\IC_CfNCPCVCUCNCr]MC0AC70CIC;C;KBt0BB;pCs&CA,Cf3C0C1Cj8C(p;Cv3C+C CWQC1C|$CC8Cn5CCCCCeC]#C81C2C@C>LC!OCZCUC%/VC6ZC$TC`UCmVCO`C u[CCVCcSC SCYCCZC`C`CKZCgXCWCCCa$C5C*CWBgC"&C*C=CEHCMCOC,HCDCo};C.}8CH'C*IB9AiBB5Cq8&C=C C ChMCCJ(CO'C8r2C &CCT CCSCݢ#CE"C5@&C/C% >CkJCHCOCI NC2\NCSCwDKCJHCCC8CZ0CF*CMCU+CC*C:CGC>C9Cn9CM2Cc5C)#7C3)C5 C3CEL/C *CޙC4C^cC=+CZS C"%C .C 0C<=CݻACCCRVC^C?`C[CVCLCOCTC^C}bC_CДUCB{PCȧSCYCq\C ^Cw%_CW[CNCk8C]!C Cu6 C$C)C=.Ckc7C:C>C$FC~2ICRLCPPCMCJCݦHCbCC7C+CMBpApB[CoCC_#CCCCpCCTy.C?-Ca7Cht*COCA C CaC3'C.C|=CCFECJCVZCUC-MCPCRCPCzfHC@DC=BC=CH)4Cx/C&C:C9#C)3C$n@C&HC.=C6Cn5C-C:95CK:C g/CWC#PCs,C"-C7?%CeC>C~y!C)Ch*C/C5C72GC_ICFC OC\CshaC RC JCvAEC!HCNSCM]C$^CM\CXC \TC0UC'ZC9ZC-7[C`^Cf6^CLRC7C"CkC= C֙Cʡ%C2C=/C0C9CC9CQCDCCC8Cn6CS8C`4CZF>C;CJ3CD;"ClC,C/Cv+C(CX'C&Cu)C2,C{3C>CKC HCYFC:LCGXC,A\CB{LCCCH:C_ICC+zPCoTCYC h]C|[CWCYCG[CrxYCwXCYCZ_Cv(\CBC(CWC&CC#C.C)C?,CL]4C4C@;5C=CECFCFClHC,DC|4C+CoJCL;ByA#BBnCC,CgC3C3CPBC\&C0C@Cc9C'CC|TCq)C:C0NCePCKCexTCaXCYC\eWCFVCgOCgICDCC 4CH0CD8C6AC8DC3BC{C5C#CƇCK.C1CѮ0C2C3C4C@1CU5CC@CHChpICACحDC LCsUCXUCHMCrEC]J:CǦ@CxGCHC|@PCUYCXCd\CK^C]YCWC XC^WC[C^[CcPC:Cu*C$C6!C$Cx*C *Ct`+C-C3.C.CT3C8CzQ8CH-9C;=C!?C"?7C7$CMC_(C3C7C :C*CyCC;C}3C-C8"C~B/B$MI@rB2C@hCCMHCCCq=@Cw[BCRLC TCTC"RCTCXRCUKCQCUCW"ICTJCEC/Cz'C Cn"C 1C>C=AC@CEC eAC=RAC3CCG>C?C&:C2C8C9C>6Cw%C[= C TC2C)6C7C;k;Cg@CtBC8ICuKCDACe;C:C@CYECdKCICGAC7?C\BAC>C7C;CKCӵRC.VCbCigCg`C[CZC۪XCXC*fVCSVCd[C)]CDSCs]GCAC6C2C]/C)C%Cذ&C(CB(Ct,C61C2C7C<;Ca_9C 3C-C CBA͔@B)BLB[B8 CCCp"CCCɱC}'Cw@6C CCNCQCseRC2TC SC$XC]C&XCWCRC PC`EWCRURCGCHC ACDE+CCRCntC5*C?:C@CQAC?C]MC)I@CFCWIC@Cp9C=CECNECɖ?C;CD5CA/C/2C55C6CAC>CNC/TCqWC\CքdCeC%bC\C<XCѨWC[YCPXC<[C_C_C|ZC VCLClDC=CŸ5C.C<*C*)CCZ'CFF*Ck*Co#'C-Cb7Cn;CO5C*ClJ)CCxB;"@9xBS BCCBC Cb(CD%C}#C&C?)C/0C9t:CCCNCSC:XCZCSCVCq_CjqZCrRC9-PCXC\CҴTC JCLFC?CJ,C4CC CH!C]1C9C{B;Cd:C:C#,8CI6C;}7C.C(4(C(C:(C-/Ce03C$CUB4BC C`0Cx7C6C9CRBCިACMMC9 >C8C,CCB`0BºBxCvC C#C#CCQfCCH CCvCt&C{c+C-C7C2C?C NCrUC̟UCBYCp]CYC"=TC"TCZCD\C=RCSCLCNECdACc 7CL-Cn"-C,C#C CJCC6CZfCsC`SC CC`6C'CþC+C+0C`!C=C:[B.C CSCxC@)C8CfhBCAC-:C(8CC5C(CCB]C C? C=C*~CgCt"C#0ClECUCXC#`C>"dC)XCyPCVCYCUC'CKCMCAPCHCEC5BCsx>C'Cϓ:C1C"CDCYCkmC5i"Cq CCMjCCV.C+CP!C`C,CGgCFBWC"CMC;gC C BCC+C/C>i0CCYBB[) C@)&C;.CIBCC};CgCx\C:C1Ce(Cӛ&CFJ"Cm0CB.B,wCo"C6#)C+z:C"DCNCOZC=WMC+;9C-C$C9CC;TCC- C:C"C'C̄4C#\GC~[PCdzWCTCQUCLUC8\C\CMOCyKC:?UCY_CSbC^CYD`C]C _CaCbCbCR_CdXCАQCHCl=C@2CC,C>y)C@*C)C('COr(CK(Cj,CV5'C:(CJCC_ CcBZ"AbBBC#Ci2ClBCACC5GCGVC.gVC6QCHC B3B# CsCCm(C3;CrHC:WC#VCILCPQCVCn[CUCFCEC{TC^`C݉eC7.`C\Ca`CNhCq\bCa\CXC{MC;C 2Cs)C!C-%C "&C C5Cl#C"C$C CACCC@C\BRB~PCR%C;CB5B A~B]CXCF)Cc9C ACJ;CH5C8C]h=C^GCCXC@XC1JC}:C:CO$=C;C6@C|JC,SCXCJCLCKCSCXCVC8C&Cw+C+C†1C3C4C9C/C#C:[C PBBC+)Cvx#C-CI`+C'CB1-ClCxBpAB:GB+BY CBF%C8"C@+C;C,HCXCN!WCjPC'XC@WCXCsPCf8C}'9CURCbN`C8jCieC aC`CbCfCTCCC\d5Cb%C"CF\$C$W!CC.C{ CCrCrCVC|C CsBL@BZBLCgC"v%C=^.CsM(CB2>~0B8B7C#Cư5C@C 8C 3C90*C#C'C\+CAC~MCMCPCVC@VCTCSCOC!MC|XC`Ct/cCΏYC!TCO^CNUCfJCKCSCUVC6UC oKCS.CcCG"C"C7,Crm/C+C}3C5C'6C;CA5CS%CUCCLCd%CN2C$C%CCB.BٮC'C1!C5Cs2Cȵ*C7+CbCBrBfCaCG`CWC_CMC32C~&CCC~CoC44 CKCC׷CCCqCH7CCCRJB} C%C"]CNCx&CY.CC\ B>jAR7BwC`&CX'C]3C:C3CH +C4$COCC.C#C1C1Cc4C@CLCLRCbXCRCKC\KC{UCpkYCYC7lRC3YCC/]C{NCNCw LCvQCVCPC6C%C|< C)C!C-C>/C*C'C'$C'CЂCX CbC,^BC_CR"C+4+C+C};"CoPCB5B1@C!CkC8?C1C)Cr "CE C?CU CBBjC%C-CE8C*6ICRCUEYCVC'[Cʑ\C>TCcUC#*CB'YCOC'^CøcC_CZCI\C *XCtVCzQCn3CDC;C15C C>CP#C#C&CG.C +C%Ck'C$C'C (C>C_$C"%(C$C)0C'C(CCBAAB%C*C]/C0C;0C1/Cl CiC#CBRCKm$C[!C!CZ3*C;1C;C1 HC~NCaRCEOCsTCtvVCSC=RCu]C[CLCSC(NC2OCxeXCMCT)C"C(CC^%C%Ck"C CCCCCnBgB CC\P#C"Cj$C-C/CECC1BBd$B"C["CNCCO1C#CͥCC+C,CC$CtC5'Cn".C XICjhNCSCXWC6UCn;XC'^CСZC ECdC BCVECdaCbC`C+YCWCc`CTC[C|tEC6'C C^(C&C@(Cto.Cg3C\;4C 3C$9C%=C8CA3C0Cd0C]&C/C2C9CSNBC"C$#Co!C}BA=AB!C%C6/C) -CU#CA#CRCCC~,BXBQ^C0CC_mCpCU"C^.C>CPC~RCr_WCUCTC'SCoVCYCvSCJQC8PCӗTC]$YCACm$CCq~C6CWC<C4CCڃCPkCCW5Cc CbCCʵ(Cct!C@$4CMAC5C[CcC[9B*B?B;(C8h-CT=C0-C;C*CCs(C@,Ct$CkCC$C/CpPCBUC4VCiPCpePCOTC1'\C1VC CBBB=C_Cg_COaC]CXC0aC+XCHSbC|ZCNIC4C|2CjP4CWX4C6C2CCܟICJC QCIRZCZUC.QCICkGC}qDCVWLC OCSHCIC57&C CCBe BTbBaC{C&C#C4CfCCC\`CřCYC9 CC;C4COCC)Cy*CX7C(CCR#C}C|CvFC C'C +Ca'C\=CHC1CuCCBm^BBd&CE3Cj6Ckx'CCy'C%#C&C.CW-C CW C5}"C>0C8RC¯]CMWCIQCk,OCTCy]C?ICLBBNB\BU;CRZCFqZC_C@!_CWC\C\C_`C_C3[C)OCJCSC]ChS_C'aC:a_CP[CYCQM\CdXC\XCVC VCeWCVCRCHBC.m?C+CN#CkQ$C0Ce>BLZ@-AzAKB=C<CC'CyCOSCC*CqCa]C+CCCC@SCCGCnmCC&C9C%OCEUCE\CWCWCAo\CJTCPCTCyPC]HC.Cs;C#,Cr(Cxj.CACZC[CYXWCbWCńRCWC \C[*C޲BGB2Bw+B~>CwWCVYC`C_CFWC;ZC_Cɭ\CXCa[CTCUUCa_C%dC?aCK_C^0]CUYCUC/PCICICHCXrGCJCKCH)JCBC@C`5C(C}.$COC2iBACA!qBϖB>BCa C]CmCCC-DChCC~CV3%C%C!C[2CC$CZ CLC!CI/CICRCxVCOYC^]CUCvKC9DCaRC}OC=AC>Cp^3C?%C CK&CCXC$$$Cs0C6C52C(CX<CjC*Cm!C%C9C(KIC!@C0.CC}C5B}~BBC1.Ce8C#0CCU C*CI8CYICMCGCBCGCbZC]CYC[CeYC+QCUCLC| C/BrzBB+B/1>CWC]CbC\C;UC<WCM\CBbXCWCXrZC&TCXC\C`WC?[YCiYC\QC:KC3FC=C>j7C%4C(3C5C( 8Ce9Cv?CDDCe;HCACl.C%C^CC}?C:C+1C)CH+C8+C,C5CCCCCa4CsZ%CCfCrCCpk(C?CQC9CCe-C=CCּBKB1B/CJA*C;8CH8C%,Cg3C4BCHCgMC~|SCſUCXCZC:`CdZCZCQ_CVCeQCj:NCR**C"BuxB~BBM[B;CUC܊aC ^C3WC,XCZCXCYCZXCjsVCT[CbC\C)ZCTC}CCM7C`-Ch)Cj)C5%Cd#CzZ'C')C%CwG+C`~2C:CqAC-4CT*C$C@BHBj@"$BBDBVBCE C8C+CaQCCeCCTCzZC*C5"C1P(Cga1C2C,3C!-C'C:#CyC6C4C\ICN RCSCNCSCZC:YCc&CCCC8>C ACWFC;Ch2C]6C9C\?CFIC$RCoIC35C'#CɺC CC Cq+CπAC SC>C,CFC`CgB&VBtBBBT9CNUC8ZC8`C˛bC]Cn[C"]C[Cq[CXCWC,XC[L_C}[CQCDCR4C?n%C\ CDCC.Ck CC>C{C:5C%%CJ,C/6CH3Cُ-Cl$CCBY A BgB C C CC C^C2CSCCKC%CE*C}+C1Cq7Cp:C?C(=C6C;f0Cv)Ce,C?C/OCSVCWCQCRCaZCkYC۠#CUC+C">C@GCRCFC=%=CLBCHCQPC,VCѵWC?zNC`C#8aCf\^C0]C="[CƊXCGZC]XCSCnRCSC|JC=C0Ci%C CSC?OC7 C1CC, C(pC# CCC#$C *C')C˖)CY$CCBvBw@BsCCBC C C C#CCQCq C_@(C=0C@6CU36CY-:C2@CaBCfFCKCJC;oDC0=>C?CMCjVC;YCYCzWC<1TCVCtVC#CJ#BtC2,C;KCҧUCNC6aHCeJCfRCUYC4ZC~YCSC\JC7CT$C "C?'Cf0CQCECCC CCPC?YCdVCYCP2\COVC:UC0CBoBfBWlB7hB0+B.BOWC٤UCG^ZCZCͣUCy|OC'GC:C0Ch@)C%HCCWiBBw C C/ CH C] C CMC&yC C*T$C}#CCIC. Ca)B=)A~BCNC*CC< C C(CcC|!C$C^*C0C94C?Cv@CEC`KC+LCNCSCgTC%TCQC/FQCˑWCZC[CxWCtRCWQCVCXC7%C(eCqB<CCBlBA?pB~B}z{BoBCסECE^CkHaCY_C[WXC)TC0VCUCVCBZC[CWWCLCI8C+Cc'C,#C~CCHBBC"C:CNCnCyCC.C.Cm C "CXCdCueCe:BASBCCCCgACCCb*!C 3(C.CO6CV:CIBC0+NCLCEOCkEUCWUCmTCSCSUCWWCWWCYCYCWC;qXCTCcNC/SC \C ZC%CvB8=BB~d"CMCSCQCpMCLC0OC(UCVCZXCJZCjXCL^C]Ch]CaCn;`CC$C"CBR(C1V7C:CR>CHCXQCcPZCYCPUCWCNZCLCCB BTىB B}BhBB[COC.^C!`C]C6AXC0SCPCe%RC oRCTCTWC MC:C"+C{P$CC CAC}CaB}BCayECYKC>NC%SCwYCyWCaVC CUCGSC2CBR}B`BԡBBBiB#hXB Bc9$CVC_Cx`C`CQ]CJWCbOCGTCPC2PCpPCq8C #C)CNC CJsCiCn CBdvB&zC7CCCC_"CgC/CCOCOx CFCBABBKC0 CR%CMf CCNCgRCs?ZCXC6RCAyTC\XC\XCjMCBCNm>C1C+C#C\BBZBBʬB3B;rBC+C=HCNCjNCOTC0WCtRC4QCYCWCSC|QCdHCu^ ChBɆB١BTBԎBۚdBFtB B8C]C^CDbCdC%2aCYCxQC1]]CWCOCIFC&CyCC CIC#CcCdC3C B B;C 2CqCCCFCm:C)C(BBS BSA3EACSB C0#CX%Ca-C"*C!"CCtCX-C1ACJCGCRCTCWCUCswXCz[CkYCvOXCWCZCYCUCQWCYC YCXCIcUCVCj]CsXC\RCWCCIB? B"BzloB`BBCC2DCtLCQC_SCTCgQXC%\CZXClRCOCOCKFCO7Cfr1C?Y*Cl)C$C  CB%C~ZCCC>*Cd>CNC\\C ^CVCSSWCXCb[QCnMC15VCuOXC{QCwbNCk7CB8BQRB-BNaB؝BBwB CGMC}_C|]Cѡ^C2bC]CJ[CNhVC=<]CZCVC@CC%;"C#C\9C YCC$C C! CCB2|COCW C֌C2CCatC^ CBhAA:ABC5"C('C_1C0C&,C;,C3C&ACLCt7SCKC1mOCcQCrVVCRCyMCNC/QCOC>PC>TC SCQCUC|ZCq[C]XC'WC8YC=[C< VCvHTCSCC1 B8GB0BēB "B*wBC2C&3C634C:7CkICHJC@MChOCNC RCaVCH6]C[G^Co#VCRCtVUCONCLC>SCVCyPCNCx'CBGBByBoBQ:BXBcB9.C[VC.XC\CO%^C_C AlqBOC\CY$CQ0CG*ACetGCMCRCRNC_IC\CCl9C2C1,CP/CV.C7C@a8C:CECfMCԅUCUCNTCLUCbUCpWC/VCSCSCԠ\C[COC1`WC aMCB鶥BPBMBH9BURB-BBG C&CCA[[CWCTCkTCXC\CVUC?SCOCN,TCةZC7!WC;WCXC/!PC4NCRCMDTC;RCIUCZC]CYCRCCRC^LCNCqNC[rMCTMPC OCǪOCC(C5CBX{B&BC~7C/C$,Cu#C*C?+C|3Cv7C7C{>C^EGCJCKCSCYCZCcFZCR}XCTC$;TCQ[CUC"OCUCkUCNkCsB BBTBlB B@BHJB1CH=CZCXCZQCUQC?VCǛMCRCWCjZCJWCqO^C"ZC1KCQCTC QCBSC?RCRQCvZC۾[CXCDVCAWCTC]TCSC)TCTCPC}?CCI4C Cs#BBg BFBuB\B8CZC(_C8aCHj[C^C߽aC=IaC̬XCMC[C\CUCzUCSPC[LC~TC NCNCfBC&CHVCC&%CRd#CEu!Ci$Ck!CBCC͇C1CCBB=1BQ3BҜ@ZBBC)C1C6Ci.HCFC?C8C?7C5C1C&CM-C&C@-C(-CF,C0X0C+.Ck3C&e8CJ6CU7C>@CpyJCNSC=UC( WCUCqSC;YCSCL}UC\OCtXCy!CBBBjB>BBHBSB_BB@C@\CSC?|NCIPCTxQC; WC%TC^COC[C#[C\OC9UC(WCSC(TC'WCxVCo[CP*WCYC^C\C TCtYCuWCX[CUC'HCP,CC.!C+CDqCCB9NBsB!B7CUgCϴ_CbC;5]C0\C]C`C_CPCyVC__CH6PCqTC$^C6@WCjYC-XCRCLC; 3C$C"C C2C0!C CvCvGC7CCC(Cm'CH&CsC}B>B#A72BaCC= C9 &C5CP4C-C^+CoW%C1'C++C*CU,C(c*CCq-C`^,C*C8+C~'C%CC:!"C|#C]#C,CZC`C\C\C\C(1TCFCK*C;Cpv7CWC[CzRC3WC<]CׂZC^Cj[C@HCi:C3C82C F8CCKACiFC6KC1OCYRCSWCMCy;C>-C"CCgC*CCq1#C &CDQ4CAC=Cw6C.C*CCC, C3*C-C[{3C>C?C5@CKGC(NC%]TCѪOC,CC(h'C[*C)C'C(Cq.C-Co)C.C4C 5C21C[?3C>C=KCd>MCHC_JCFC,BCUCCvBC%CCECELBCI9C.C+Ct'C#-C_CHCmBA}@BBeC/ CpCtCoC CCCkCC@sC/C#Ch$CQ&CJ.C~,C,C#-Cf.C5C 9C7C:C=?C=C!9CNCC 3Cp&C0CwChBBBԈBCdBBB&B[B4BpBlQBRHB|VBH^BChFC&C\-C"U(C20C7C-;C>C>CaACHCm1MCcNCNC!NCXESCXCUXC1UC$WCpXChUCE|XC^ VC,PCQQC-eJCHCC&Co>C BC2DDCECmDCFC EC>C<:C=C!DCIC;SC~[CYx^C-^C UCSCFYC\C\CAVC)TCPC]BC7C0C(Cv'C+C 2C?@Cp6C5C>.CG$C'7CA C% BB(cBY$A(BB%\B¼?;?TNACB@BIC??$C7-CI-C1,Cv2CZ8Ct=C4@C>DCoECFC2QKCLJCICoJC|MC)1TCDXCYCWCxUCRCTC_TCUPCNCKC//JCDCC?CaFCHDCECCCe @Cn@C?C0KACP GC΂OC RCBWCӪYCE\C`CWCqVCL]CM[C6ZC~XCxVCeUCOCLGC+?C8C19CfCp@CFDCJCNCSCVCYCXCZC6`CXC>8SCC@\C \CuVC1%[C,YCWjSCܢUCԭRCIC`AC6@CRCC CC7@C1>C!;CE8Cd:C3Cߢ0C81C +C},C-Cdz*Cq{C깸B֣B\CBTB9nB@k CaC;$C.C1C04C[8C69C=CDC xBCC4DCAHCECqIECJCCMCJOCVPC~TCoUCoUCRCNdLC&FCe;C~3CT2CCR8CW4C0C 'C#C #CC'C CaC;C,CCuCCpUBAB"BBB"b CLCT C"Bd6BABuC+C1,C8-Cb5CL;C4CGQ.C%1CW4C8:C*@CECGCGECBCmAC5ACHCKKCyNCxUCXC',YCvYXC%XCYC#[CZC1YCUCQYCyvYCXC`C>[CxPCQCQCdKCmGCEC5 DCBCBCZACZ?C x?C>^=C3C 0C61C,C/-C91C `2C"CBBj?B BA BC!C?(C3/CJ2CG6C8#8CaZ7C;CyAC 2AC%{CCFHC>ICňFCfrLC5PC[OCOCGMUCWVC VCQCCCqb4C&C C C^-C:CFCNC:QRCbNCLCNC$PCDZGCDm@C6>CV5C/Cd.Cd".C*C7!CgC2CQC CCfCBlB BB"Bk CxC"CBDB@C;B? BC.Cm1C]4C:C)ACTACC!>C *?Ck@C,VBCiEC *KCȽGCW>CBCCoHCJCQC;VCUXC5]C`CBp^CA6XCUC>ZCZC WCgrZC ]C[C}YCAo]C}_CUCyNCOC@OCKC҂JCaJCECÐBC?Ckf>CBC+CC>C :C84CP0C.CH.C;/C3C&CpCBPBrVBZC"CC)C2C4C17C!a:C$8C]:Cu=C @CCC@ICMHCPFCtvHCcKC*QCTC8VCXCXCWPCG;Cu0'CcCC'C!&Cl3CuBNko@AkBB@CC-C&/C92C4CY?CICLQNC4JCGCsHC%vJCNCOC֕DCJCPCRCUCP\C?_Cm_C]_CIXCS\SCrRCSXC8[CsWCD2SC ZC^CZCJ[CZCLQC_MC5LC1RCiLCWHCJCIC,DC('?C=CBC.CCU=C ;C2C.CL1C0/CmG.C1C>$C,CBU*B\BT$C5&C.C7C/C-C;6CR8C6C8C=C&C=C&@C- ?Cym7C4C`3Cu-C)Cr.Cy(C#Cy$CC*C^3C=C CCBFyCB9z@AlBB}CB&C'CZ+CQ.CH9CJCTC~NC!KCONCNClQC>UC,LCFRC GZCXCYC{]Cs\CIYC;?TC2NC@QCSCLWCWYClWChQCWCIZCWCeVC ]CI%ZChPCKCUC RCLClNCLCHC6 DC ?C?CAC;:CW8C4Cz/CM1C.CZ_+CC2C}&Cx{ CڟB_aA+B C(C2)C*C2CX/CG*CX1C5CL54CL=Cfz;C5CH>C\ECFC_HCOCTCFQCGTCYC@VCPC#D=Cj)'CC C7CuC@/CJ$C4*C<:C9C ;C J@C`>Ck=C5:C9Co4C{4CN:CACCC]=C->C;Cw9C)4C7CC3Co1C)C?$C2T"CNC4C3>CC2'B}?Ba]@uA\oBB*CmC6Cl#C*C@h5C3HCTC=SCOCQC(SCWC[C'WC}SXCP[C YC[C"*YCf\SCePClKC@HCxLCSQCSC VCSC<KCKCHC+NC(PC}=WCXClPCDrKCVCdTCQC+MCKCLCDC>ACBC'@C:7Ct8C9CY12CZD0C-'.C}\,C$1C.&C-"CCB@1GBBeFCQ'C'C%CW*Ct1Cs.C`0C!4C5CdBCS:C :CjDCGCIECG GC LCLCOCPC'SCm{TCSCU&?C'CtCCBlCyCsC&Cy1C$/Ch(4C 5:C}_9CH4C.2C-C#C<&C>1Cp7CW=C>C59C8C@C8C8CZ>CHB;Cp.C7O2CV+C CA#C"CnKC~B0B^@x B݀BABC8Ce$5C6C3C>^0C+CCY.C3CX,CC$CBP^@u;B4BCy0*C'C'C )CѾ*C0CS0C .2C=x8C>3CY=C?Cx@CDCGCܗBCTCCWECHCKLCLCCLCzLCPCdEC +C|C4C7CdBBC1C"C#Cv+C1/Cv.CL-C1Cq&CCCՃ"Cr,C50C5C_0C^F3C.;Cǔ5C{;C ;CTd0CY(C+C.C)CP'C CCMB[B@"?B[BhB C6CCE~C*C6C&ECNCMCmRC-PCTC@VCSSCWC˝ZCWCKWC~@OCCC"?C9C;CDC&KCuQCVC TCI17C CQ$CFd$C'Cr@C&PC@WCYCvZSC5VCTCě[CTCLCYICAC:CA@CO=C;Cm2C3C@5C/C})C-C%3CM?-CCЇ'Cg CUBlA)BCd&C(C.V-C\b-C(C:*C5h5Cp/:CG1C>C9CI=C)FC;n@CCCDC?C]FCxGC FCXNCyPCHCuHHCOCbxLCM.CCCF C݆BBBcB CCCd/CL3C|,C-C*`*C$CoBC2CCCf6&CŠ+C .CE0CUL2C#G=C?1Cb!C0!Ca#CX.C*CC˘CYCBBz-AXBCJ C4C%C;o#C$C-C:CJC UPCPCBUC!OC7TCnYCXCbNCzLC'CC<CCiGC:C~o/C[J5CBCKC TCVCZLC&+C4CgEC>KC#QCSCQCMUC&ZC;TC*LC1C+.@CT9C-3C"O;C˂0Cmn)C:CGKCXQCdYC^UCYDC:C;C8CB'C%CdK'CJCt$ZCiOC&NCNC8UCC(YC*@OCHMNCKCECcIC.GCuJCEUCNC:C,CW7C?W/CoC12!C#CBB5CxCB7BZB~@SsB(CAC,CV"7C=.C 2C>CMClPC5PC2TCLCBCG;C7CF 2C.Cs:7C*Cb&C6(C(CA4C4FCQC]VC_TCJCB;C4CH6Cw CPBcC#C!,CTCCPCSC}LCMCʼZC9WCNCQC{PCIClIC HCuECHgHCNFC>ACZ5C6C#5CR-C)C/C+C-C#$C *CC`C +C1*CK0CgA/C'C.C65C';CB GC5kCCDC>CBC̮ECCCCDC1C<\0C)C%C "C;CTBsMBmBB Bt@VBCCb)CQ;C9C;cDCALCNCXFC-zKCSCoQC%MCNCYKCGC GC$GCECECGCPYCC75C>C9?C/CE/C' 4C L,Cq.Cy.C4C.C-Cd/C_.C5C5C3C/4C!5C9C:Ch;C&@CKACACC+FC9rBC#FCGoMC#YLCwIC%;HC+NChMC?HC{ACCHC}CC]9C[P.CI'*CC[C2C@mCCB̀BmcA>BҰBI CCCCX7Cnc!C $C)]$C%CuB&C*C U1C(CR"CG$C9CfB ByBB*BBCC.CPDCHC]DC#DCTICCC9C2C+C$C| CwCxC$CCZCR)C5C9CXEC=UCf8YC}?LC:CR7C$i7CB-C(C+B CC $CU7C#ECRCNC AC0IC XRCQC*RCFRC LCk KCkLCIC:CC>BC*GCkICMS@C7ZDC%C??C6C1Cw6C4C0C 1C(C2CCC CdC6"CA,C 8C@CZCCNCWCC7C 5C?4C:5CkQ.C*,CJ1Cr/C#-C'1C^3CY6C]8C'=9Cz7C:C;C9v=C­BC>C4+>CGCZ?C\@CTKC-LCvFC@CYCCb1GCLCsOCDC=CLq@C̭C1Cn#Co,CEC<4CBB)mB-Bv_CfCYCCdCطB~VB"CɱC CwhC?C:#CCCCB QB\B<Cx !Cbd/C\7C1CO)C2'Cst*Cɣ$C7Cg%Cϊ C;CWKCg#C9;!C%,C3C3CZ{>CZJC!`NChSCOCFCwCCDwECL>CC_S8C7C]CR;CCBCGC1KCEC7DCFCMC=QC+ECw@C@C"0=CD@C2FCFCaDCrBCog>C459Ck,C2%CvCr.C\CmB-BCC=C C C&C/BeBBB$B_BBCC5ECbBѶBIZBG@BB!C&C-CfG1C)Ci#CQ#C CCW C C CH $C,C$+C)C0C=Cs*DCGC#>NCDOC;NCGCQ >Cp6CC&C6CBUB=&CCC4'CkDCPCECoACr>BC&ACNCSSCFNCPJC1MC\SC^LQCߌKCLHCFCECECõ?CHv@CEC :C7C"PCBCICNCFJCECJCxQCJC>Cx5?CXy?C*h?C7DC-FCyEC>Cy7C`1CE45C1C;'CCpCuMCBkCC%|CCb`C_nCC CBGBABXBBBoB BHB!ABB Bt,AʓB!mC Cس'C+.C(C#CF"C5QCc6BUB. C&Ci 3Cy8C8CR;CECCKCOCcLCVLCIC!sFC?C@9Cj/C v CBBB>B.[ C^~CFECl-CFCnNC@C͕>C$@Cf$CI@C$?CA>CSBCICOC]fOCJCHCNCrQCxHC =C+?C@C@CCC'AFCjQACH4C3)C!CA%C;&C!CCCuC>C CuC|ZCҢC\EC3CCNCjCxB(cBB B;BBBxBBɱBqc@^BCeLC Co,C7s+C'C#&CbCKaBCWC.C9:C7E=C2s;C˔=C]CCGCGFC]ECCCDCC@CECLCRCtMCh{IC!8JCMCQC]%KC77BCx?CQ?CQDCFCd0HC5BCz-CG,CzC[6CUCcYCCeFCCB, CѯCFt#C(C#CCC2C;CdCq2B0HBBTBmXCP C4BWBuqBA#B,|CpeC)CJ,CX*CPT#C1 CESC?aC9n"Cw.C-8C5C 2C5Cd;C@Cb>C:C;6Cu2C^g0Cy.CM'C CsBBw CźC C@!C#C=+C4?CqTCh)RCqDGCACpDC2pDCGCbLC?4KCrMC)OCG2SCh,UC6OC;|KCVGC4"ECBC.=Cfl=CACCC}ZAC?k;C66C5C_5Ci5Cy+C/Cd&C?.C00C\M5Cm7CN9C:C9C=CH@C5>Cݺ>C8C+:C -CQC`%C7 ,C /C%2C6C9Ct3Cu;6Cu+=C;Cĭ;Ck>CS=C`GC'>NC&TCTWCm:PCRCӜXCgTCݻFCBCBC)CC:HCeEC̵ACdHC?qEC-C`QCk"COCtCC@ C$BBBCC'C6C,CCGCRW Cm C CY CCuCCgCCD~C: CBfB6kA@B=xB¬BCC &CГ$CiCvCC%C (*C;j)C#CCr C/B7CC>CCnCnCC C'BBBb CC:g!C#C(C;/Cx>CGACEC:UCfZCZLC'CCFCICH+C{C#"C(C.C3C"m;C=:Cj-CkY3CC>C؋BCBC\MCыRCRC1TC&oQCJSCeVCXMCy@C:~BCCCZAC@CcAC6ACNLC}ICS7C$CZCCoCC\CBZBjBCy C-/CC9C#0Cb&C#C C'F CC C&C<CRCZC[C CUCTCxBNdBsAiBKB;CC}!CaCRCCK&C+'C$Cl C/BIByBBdBC JCB[C;CϳB BC0Ch0"CN%Cx+C%5CTCoUCORYCLCOBC07AC=Cs*>C BCCCb@C BCFBCT>C:C7Cl(C C$!C(C[Z.CsO=C2Ck5C;C>CnBCtHCFCJCupQCQC4SC/8QCTC* TCFC\V;C5AC9EC-@C;CI?Cp?CLC2IC>C5CDCdU CCEC CCz|BB;}CoC1C?Cl6CKC7CDCj CmCCCCeCOLCCCCC#>BbBsAiBVBOC|CpCCC7"C&C$"C*C-BBcvCHCCVCCB8_B:rBBCTBBXCq C'C/C5C=C{@C@CGC;IC9PCnPCKCF$FCvECuAICpBCGC*TC\C3YC-WC VC8YC"ZCĄJCCCc%BC@=C%BCCC$>C.;C6>CێACCC;C80C&CdC"CN*COU/Cdn?CFCBC&C>C>CB2CC.C?BC%=C%C1CCLCs2CڙCzCuC$@CChYCm~C(CPCBUBKsA,0BqB[ C6CdC#C$C"CP#CCC C&CCy!C3)C%C C<CHB ZBC7SCRCCC(C2Cg4C}7Cp6C5Cn@CUFCIMRCpSCƓMCDCCCGCu@C]ECASC1^C[CxYCbaYC[C@YCA:PCfJCBC/TBC]HC]FC:C&8Cۨ@CACIC"r?C/C:&CQ!Cf%C!,C-C]:C C7>C(;C%?CoMCpKC2:CSrBCBCj,C?2CYCCFCCB} CnCU/CrAChAC0C!C~CeCCHC}C[2CjCCδC~C۾CxC²BIWAHAnBB: CC'CM#CV"CLC_C;CCCD C#C+Ciw-C%CE9COC&CB C C\CqC~C Cю(CK1'C*C+C(C:CqECSC}QCQNCOWFC_"HCLC\DCcW@CyICSZCYCgXCiXCTCpbYCXCMCBCKCEGC- @C>NCC#m9C;C|ECOCDCrt3C,CȨ&C[)C;.3C/C}:C;C$ :C =Cc5C*?C?CAC/7DCHCTCLCKVC QCkGLC+PJCiEC?6C4C:C/;C$B`- C_C8)C2Cf8C1(C tCG7C CȜCtCCC CIB4 C6 CCOB" @A8C@CtJUCg[CYC>YCũWC^Cr[CPC JC}LC,BCJd?CxAC";C9CXGC/RCU/EC4C>o1CJ(Cy%C,:C(H7C7C5<>CP7CQ*4C3CC-=C=C$?CA>C)HC5(KC CCICt@C-C.=&C-0C=CC+Ck_B-1 C 4CeCy4CR?CGS?C7C)CɓCE%CCoe CPB6QCF B BR+BoBhΧB&A\ԲABB9BxCV(CQrCԽBC]C#UCJ(C#C-$C]CnCiC')BmC C{C%CE!CCCCrwC +C:%CMC҄C-C+C{BCTPC DC+JCDCwFCCNQCECZ>CxL?C%NC/?\C ]C`ZCXC\C ^Cu[CRCGCjECAC6C5M@Cr6CCCSCDCHy6C\5CU(C!.C)C9C9D9C}:C7C0t-Cl4CAC$ ICCMC.IC7GCMCPCOCYLCM,UC9GC4C/C"3CO9C>CIACNCEFC,|DCyCC-1Co&CN*%CC`eC\CCBeICC7CL %C[.9CGCC>ECJ=5Cl(CbCCkC̪C# CFB)BB BaA#@h@\ A$BGB}BvBsBpCCțC-GCeC!C=C5BBKBqCC/CX%Cp%C:C&kBz/B!CC5 CVc C "C|C -C ;C5C^=CL-%C@C0XC]%C3CBbBBCtCC'CvC&1C^ByBTBSlC6CCmeC#C$ClC-BB#CCHC!CC"$C9CfECfCsRCVBC0ECFC3AC`ACKaNCGCECNC XC^VXCQCWC7]CYCF[CI]CPC!DCaYC(ECM7C!CxCC|C4CUJCPLCGCרJCJC6ZKCXZCWQCKCU/UC>OC OC6RCMC@=CeD4C4C6C l:CcC!C<CECgCCU CPPC:ICqBBFBhBZCC$Cln7CY?CBCxAC 3C0-CH'C!C3C&CC #C}۴B >nAhPBYpBQyBBC CBB|BTgBB:C CT!C&CE'CCBsB)TB CC"C "C8"C22C9C?CYC-SCBCAC%ZJC> CCACC2NCF)ACDC;Cb-C"C.%C $C BB{?OAi0B9m4BBP~BBMBqBCC5$%Cˆ.C .C2C&CCBÿB=aBC>C"C{"C()CQ4C|1C@CIXC NCDC'DCn*>C28C DC0HC|JWCUWCA^CO>[C\VCWC4OCIGCTFCKCgEC>+CC3Cvs C 5C9@C%CtCH/CfCv^=CNTCRCJCzPCVCLSC'TCWCTCVCXJC3C-Cg/C9Cd;>Cd$:C݋=C>C9ClEC]kJC:4C;R C;C_ CBpBvB/WCCuNC CECȦC" CD CLCA(CCIC3WC[C"[C!XC&XC!cCTbCWCdWCBbC ZCIC/CX CRBCC?C OC QCvRCJ!C^B3?BB#C9C=ICRCWCVCPCSPCVCYCoTCHC,r:C5C5C6C+4C~3C}9C:CACzIC@C6>C*CCCCJ C$VB$EB CClC&,C,9C^5C3p-C+/Cb1CȤ6C?C8CB,CS CCCXCDCk@ CC<ClCݾB/`j@BqBn0 CbCDC5CPb CqCxC'C#CL('C.C`)C#CCMBNB6wCڈClCCv$C|71CGu5Cq2C:CK??CsAC)PC1SCaKACN5CQ;CACACCCAC=C-2C,DC/DC6ECGC_LFC~.@C2C*"C< CC>CnCICDcCƵCsL CMBoDBpABC|C=C8l!CȏC" CCG C&Cz'CQ#Cg$CCCBvhBB"BB8N C+\CCǟCZC$C@LC_C_/C8C@CB+SCOCq@C?CCC?DC@C5CGCGC;HCLJCKCIFCt9C-C&CC?CxCB8BUBBxEBQA#ǯB,C$ C_,%CK&C9"CCqC=w C&CCChC#BBQl CWC]g C Cb CrC^CdC2CC C\C>9)C2C5CEB笂B$BC-CM%C4C̢HCTXC(|XChLCOC WC QCzGC?C26C 3C{7Cyl7C`5C&4C6Cr?CUMCZLCBQAΗAgBk3C!CK)C+CJ!*C%C)%C1 Cr ComC>]CZC< CFCPC5CCCC9C~#CTC6 CCB C:"C1CAC+MCQC~uGCo@Cg>C?BCMBC;C6CI7C&,C&CBy{B|B^BTpC#Cw$C>01CBCLC4NCJC9SRCBXCo`UCJC;CO4CjJ3C1CP;2C5C5C5CCCqOCwHC@C[;C ;Cb>C5C)C$Cp!CCxCBu֒APBCy#CA.C0Cޏ0C)CCH)Cj#C?!CCHC/C CPCjC #C#C CU$CH&C[Y C5CgC1=BB8gCC,C!$AC"GCaOCJC_>C=C9?C?C;CL6Cd8C?CBECOQC^Cw&^CYt]C'dC,cC-[CQC6BCԜ1CҫCSB&B-BrBBC/2CM)CdBcBBBC%Cz(C%2C $C{,C8ACAC3Cf)C#C"C!e%C*#CC+C:g3Cs6Cr5C2C+C:CStCzyBA3HBCH$C-CB3C 4CC7*C#.C@+Cg(C)CU#C_"C%'C_'C^'C@*C-'C`'C,C#3-Ck)CpJ#CC<C< CcCCK(C,U>CECdMC+MCR>CCz&CaCWCCiCCCC]%Ci-CL2CaB-CC*CbB4ApqBG C="C'C2C:5C`p.CB4C`2Ci4CC,=C0#=Cz8C4C:CAC GC RC|_C>_CnB`CXaC`CYC3@CUZ4C5Ci0C)CBeB@B=C\3CCBQzBB֍C%(C?!C &C.C1CPn4C!HC<2KCJCUC pVCO[RCHC9C13C7C`o3CW~.CQ5CaDCUPC\HC)8CBq$CCCaCB;[B CZCxCV'C3CpAC@GCd=C(C CJCƝCCCE CbCbC7 C%CA%CCC2Bi@ aBC<CѠ"CR+C{i0CI1C5CAi6C:?CRMC DC9CCjFCECYqDCXaCC,8CLJ8C'77Cq/)C"CCrC:CkCϬC"C,C2;C\ICTNCOSCMHC MBC@CB?CF-;C&6Cg:CQ?CEC!RCY^CdCRbCJ^CC'6CG7C1C-C/:CJTGC$KCIC8C_!CDC CCB. CwCvC4#C/C8CCC ECACߥ:Ca3Ce,CS)C#CC& CCMC_CCxhCɅCCyBBC&BCCPDCsXJCVMC0~GCyAC7CR&C!CCB9L C#C!C CXL/C}CFCMC,VC!aCigC²`CSC.d@Cp]7C/C-p8C6C]A+C(CCBfBC?CCBBeجBCA#Cn)Cl>'CNR%Cݸ,C;2C:C 4C:CcUC5\CVCBPCGC;C0q7C3Cd2CFCOCrICߐFC 9C&Cq!CC+C?CXCCC&C1C7C=eFC@GIC6tCCzDC@DC'?C7'@C*9C$C!CcgCbC' CdCbC[CcCwRBߚABNBAgC2C!CO&C!C(CW+C$CG-C۬.C .)C1C=Cs>CGCC4BC$8C[)C$\$CCF C CCΐC$C>/CBCh=CzFC+XCVCBKC8@C>;C9C:C DC&RCЗWC&ZC jhCIHhCWCDDC+7C8CK0C6Cz4C2CL*CC C .BBՐ CCECtCBBBa C*CfU*Cu$C,C3C 40Cc4C 0C.CqOC_C)XCXCjPC>Cۋ7Cd:C';CbGCrSCJCCNCIH]C\Cj]CeCR\CKCӏ;C9Cʁ9C-C1>/C_S4C>4C-CECBfBCHC CYҧBPBBbCj%C"CjH%C+C:.C/Cz/C,1Cv3,CCCWCGVC[CuUCDCU;C@CECJC[TCICc7C;(CCCV.C}CY CS|C C C<C= C=0CZ9CKCiPCJBCIr-C1$C%C3%CQ!C"'CG%C3CCCeCC>BA*@ȃA?AB7BB&BB0B1 CaCMdCQCCCCC$CF)CP0C)C'%C$C#CMConCtPCy!Cy%Cd9C7GCGCQCG[CfRCkDCp:C=C]=GC.VCK]CS\C7V`C\CJCV5HCo?C8C6CG/CT.C7C6b2C*CCBbĒBCJCaCVB]fBćBi_BBOCCi5%CT#C~#C0 +Cx(Ce0C.-C16CKHCfSCZCXCMCFC DCKCS(PCMCh3@Cwy2C "C:C p C CwCCCU CDCC1C+CV|7CHC4MC@CQ$CQCjCBCCn CC`CXC C[C HBŃB@3A9AAsBgB CCC: CC CCCCw C!CZo!C^)C`3)C&CICUCCx#Cmq"C,CCCBC/MCN]CZCRPCDCDCPC) ]Czv]C"[CK\C݇QCAC OBC?CH5Cv.C=2C2C=29CK/C$CB BSBC8OCIC3MCDC@C8C37Cb3C.C1Cku3C-C*CCBC@CCCHCHCJCuGCg=CA2C&+C>!CkCBCCCνBNκBaBxCC$C;F.Cb'Cl#C'C)C#CDsCCC]C1C$CW9C7C#+CaCvCCCeC,Cչ#Cү.C>;CGCKQCXChb^C%dC cC$\CBZCxXCGC?C=C(8C3C0C *C.C#-Co'C&<C/BGؠBCg;CMC!HCdDC.CBBzBjoB*BC,o%Cۋ!C(C@)C#+CN0C 90C3C=:CƴDCjRC UCaPClPCvSCOC?C,C2"CCTCBB^ B?dCXCcCĊ!C0CC5Ci0Cb0Cp-CS)C+C8CaDC:C2+C!CCCLCI{CFC8~CC&(C4Ci>CGCFTC]C `C cC&^C6hXCNC)I?Cw8Cx7C%4C9-C)Cd<'C%C+C)C.)B3BɌB:CQC^NC=GCKtKC4SCWACC9BrB|_BBCU#C3(C,CL+C"}2C,CN[,C6CPAC NC51RCk3PCJUCaVCMC[x7CB #CGC[CBB)RBCwCf"CNC!CȜ*C/C4CE;C?C1ECIC JCHChICWIC&GDC9C)CqmCjV!CdCCBYAtBpCCQ)C32C|9CKFCCKCICFC(FCACACyJCMCLC^CC1C|&C6~$CQCCuzCPC`!C&C%C+Cu4CVOCk^CbC@8dC̑dCYC?EC'7C3C>0Cm>.C.CA1C0C;M%C C0gB> C>C\CaCaCcC6aCg_C bC=adCt(bC;XC=C> CHBTBsBj+BѪCR#C)C\&C'Cl2C؈CCSC=WC,VCzXC5WCMCR5CyCx ClRBIP C~CC9C'CC71CC?CC CU C@CCɈ!CC C@%C+Cѳ2C;C^3CS'C$CRCB0@BO CC+!C2CM"BCyFCFC0@Cp\:C;C 8C{[/Cl+C3C:CEP7C86C2;Ckj9CX.C#CC~C CNC<{"Cv$C#C .CHC1?\CcCUxcCdC_CvKC8C8Y2C.CB+C[,C4v5C-CCPB4CKCdCW2`C2^CzaCcCrHcC<_CxaC~eCbC bC`COC!CB%BBiϬBGBC'Ca3C:@CKCSCmWCCܣ>Cj;=C|7Cf0C1C/C#CuC$C+C(C (Cܘ/CA2CZ2+C C!CCߔC7Bc CiCh)'C/C~(ECYCdC;fC2JgCXC6TCOCϠ8CҁCzCCC8(C/C'0C(COCC"CցCg B2BBBBuBA`C C7aC@CCNj C{)C CVC"C\.B҂?AvYBrC C,C%Q4CE5Cܜ2CA1C\/CO-Ca)CV&CNHCCC PCR#CGC"CT$C CI`CC,BB1BŻCC %CG86C HCZC/eCeC7gCDhC(`CVCdHC78C,C3ClvB!;Bo /CF[CeCVbCcCgCrfCcCdaCy]^C^]CZk\C,^C_C^CW`CbC[^C-\`CLC<CBzB+|BziBq4CIlOC%VCYC[C7\C;[CܱVCvSCFCx0Cs&C9!CϚ&C5CBCw5?Ci2Cg+Ce"CC4QCC C/ C3CrCbB*BԣB^ABըC3 CCC#C\uC^CI`BBmABL\C#C/+Cf1C8.C*C$CP!C COC&%C CTCBBڱBrBlBvCHCC CpCBB]C7 CCS+C_DCkRC[CF4aC#`CdCvfCcC aCWC8CC#B|uBO3CdCAhCcC`CydCdeiCzfCccCbCF_CY\CvZC_C\cCAaCybCJ:dC7`CIgCfhkCHTC(CBBC8Bc/CEMC gWC+YCu\Ce]CvD[CnYCHZCTCCC5C.C1C5:CGC\GCZ@C>Co6C.Cu%C*"CCC=!CC&CCɮ CKCBBCv C9ZCtCCgC B)B.B.CC3#CM&C#CC C(CC CC.aCCa CL@ COC~CG{CCt CCCcx"CiCCHC3%C.U:C3SC\Cf=_C~`CaCSfCfCbCQ\C 2PCC*CZB B::CeC&sjCgCeCaCaCZfC=C˶CCvB-B˺`B˧AAdSBBv CHCYSC CCDPB*BkCڽCOjCu&C,C,C3..CQ-CuK(C&,C-++CV*C,.C=W5C1C^/CH*C8G(C8C7OC^CaCdC5gC_~eCR(gC%dC_CXC[OC\NCUC[/_CaC@bCUjCjcC A^C]CQ_CebCcCmdCoBeCdCaCx]C^Cq_Cs_C_C\aC \C%XC^CbC7&gC)'eC_CO1[CEPC0"VC \C8VC#_C7bCeC,cCYCUXC[UCXSCCCC@C"CCACf$HChHC'@C*8C+;CjIC-VCbXbCsndCkcCeC+HcC|=fCMYcC`Cl]C>\CcC+dCnSdCr.fCdCKnlCbCXbC`C EYCI`C}eC TeC9eCQheCicCW\CaCSgCq+`CZCyaC#[C?\C]CyeChC`C?4aCdC[CJYC:\C\GYC$]C`C `C])\CWC\C~XCltWCSCPCMCeNC!PCcPCROCUMCTCLCKCtQC[GOCdMCwOC)LCLC^4IC"AC>C1Cخ/C&CCpCٳCA'BiB C_%C#(C%CpC CDC#C,C7CEC}KCPCڝUCFVCOUCvXCWCgUC!1XCNCSCRCҸJC1sKCMC=tVCL[CscC}dC;dCeCdCgC|bC^C_CbCkC,gCf dC2fCnfCiCAfClCiCZCcCqhC{ fC~\CVZCJcC r_C1tcC(jCeaC '^Ct`C%\CeC3cClCeC<^CAcC=cC`C `CF]C\C\]C\CP]Cv]CZCBxYCNZCXCRCOCOC4TCJTCfNCWjOC|OCxWCPCICYKCECz=Ca5C40Ct4C3C&/Cj5CkW6C>5CK&C "CJCNvMBBC?Cà C,r6C1C]+C?2CG/CE6CCCQCYCVC XC(^Cz_C]C=bCa^CK_Cn`C'UCYC WCPFQCCUCyVCAYC[CeCbCdC gCWkfCdhCgbC^C^CC|cC:WnCmCT bC6bCnfC\gCjCAnCkCHeCmcC&XCKCY 7C5CdC dCC]CkdCeChCY`C0aC_bC!R_CZCne_C(`C]C]CZ!]C>]C_C^CXC+[CXC(WCQC;sOCaUUCp*SC~|NCEUCwhQCQCKCȞ CCC?UCC/NCeCC7HC9GC70KCuSCKzXC[C _ZCg{XCo{\C^Cv.\Cb`Ce`CbCaC3^CZC/`C\CfXC^Cӎ]C`n[CJdC6dCqeCIfCbgCɈhC9eC AdCgaCeCr?nC?.qCMjCITiCdCfCvpCgiC+^CU\CvJC)<*C:_CYCCDsC'C.C9CxECUCv^C\C#`C>dCU`C(_CG|gCaC)_CXCpZC4dCgaC@]C\CddZC ^C_C1[ZCYCCVCՑZCTCg$NCKQC@PCJITCiZCQCCCn5C (CA!CCCC\CCLCƛCCfCCCC! CgWCVC WCXC8YCVC UCTCHCQACP63CfV)C'C'^$C#5!C,NCL"CM&C'Cz"C{CCBBg@jCAC4$!C&C#5C_>CbN7C)Cl,C"CC`TCIoCCCBC&CR/CqCg'C!EC\C<`CHZCǑ[Cg\C bCaaCKCSOC)7SCLCIRClu_C[C\C/^CM_Cf]CDZC%[C]C|]C^C[C۬YC~XCTC WCHXCTCSCrSCXCkYCVC"RC]SCJC=@C9C;6C5C)4C?:CPP=Cp:C#j+C5 CVC COB@*B%C̄.CK!*C1C5Co#C Ck CC~C# C#CsCC<C C#CrN2CIC=[C"]C;4\C{\CP_C,`C_C7bC"cCp}gChCfCgCgC=beCdCgCiClCeecCgCmC^]dCaC [CQCH9MC8C2#CC=C3B͔B[ChMXC0}TCYVCuaTC'TCAOCHCICHCACC,AC;Co-C#C_CCmB_@dB} C6-C%Ck+C0C`!CCC4vC4$C*CX.C B+C7'C +C.Cq'3CAC]TC\Cs]CaC(fC\dC@^CP_CaCiaCncCdcCncC@eC]5hCWgCHdCFfChCڈlCdCaCcCbC=bCYCqXC5eXC/BD8B)CxCeC"C|wCxCd C$Cp#Ce1C~DC.RC%XClWC-[C]CVdCbCt\CGe\Cե\C^/]C^ZCGWCV]C1DbC^C&fXCVC]YC5YC8SC:RCvRCPCSCUCWCP>UCLCCCB7C5(*C%CQ "CAC#CC;f>YEB"CV!CCaC'C\C-%C(CP1C7C6%9C~%9C8C?CDEC JCrVC\C}"\C&]C2ngCilChCgeC`eC3bC_C `CKbCaCdC9fCeCeCiCihCUdCcCG:cCcCW cCF`CPXCa-VCUCCCj)C2CC4 CB ABCtCrCؿC;C[C*C$CɌCCM!0C*DC{QCbVC][Cc\C,^C?s]C{^C~aC}_Cx[CVCAZC]C̾TC}OCΉLCKCOCDHC`C}AC!?C\{@CGCNCEPCZKC[=CS-CCUCCZCC6&CηA˂>BBVB$oB}CC!C<-C!G7CI@CECHCICJxLC#VCg\C]C4aC8aC%D^C]CZIgCAfmC fCWF^C[C_]C^`CjRcC:dC1aCeCfCcCyeCCiCiCbCkbCbC^VYCJC5:C2C6Cf>CAC6C(CgCfCCBD CI]CCCCQC4CC CFC`CC]N0CDCDUC=\C\C[C[C)_CY_CZCXCE[CwZC-NCAC-m9CZ1C.Cű2C6,C#C|'C%j(Cg"Ck$CO)1CZC`HCJPCpdTC&VC]F^CaC_C_CfJ`C|hbCaCJ`C dC:aC6nVC]VC}_CcC˪dCAcCk|aCJdCdCOcC$dCcC}eCcCaC+\CrFC+.,CCCC $CA6C:CCo-C!Cr(C CјBB:C\3CCҭCC1KCua CJ C CMCCC/9Ce$VC,]C4]CZC{GXC]C\CXCXCPZC JC74C.Ca&CSCQCCvC%CM:CtMCCCaC C2*Ck>8CzEC3|FC-CCC^C޾BlA[@*B8C)CÔ*C.-C7Ci,FC(MCyOCLCC-NCoQC7LCݦLCmVC\C^C]Cj]C/`CK_CigCEiCdC eaCbzaCr`CyaC*cCeCaiCgCFeCseC\COC7Cf"C#yCNC"C1C4%C 0C w*C"!CcC3 CuBBėC- CrCNCCsC$CCCa C;C?CZZ;C7g7C2Cn5C<2CF0CY;C-#BCLC[_UC:[CmaCdC̑iC~dCz8aC5H_CR[Cq-\CE`CGcCZ[dC-iC6hClbCQvbCnVC`DC,CC^Cx COUC?C4vC:$C&$C" C C[CBoB$BWC C C C$uCy C C CC!CDECXCbVCDPYCg)\C.ZCYCXCUCMVCMCc/CRC:C>\CuCCg;C!jC?OCC̈CBvC\;CSY C*Ci CuCCZ%C!2C-*CdC]CB瀋Aʚ@I`BBKBкC*+Cd,C-C.C -C)C"&C6#C$C#C<CO$C,Cl9CKC+ZC^CO^CD_C{`C bC6]CATC""YC0]CZ.`CaCa2dC"eC%uaCbCWCICn0CECIC>4CaBW&CQCnCC!CcC} CKB4BRBC`{ C%bC1Cp C"8 CiCCCn4/C{%QCYCAXC^YCZC{IXCJWCWCQC1OCJCWu3C=CCEChCC>CDCRCcCCjCNCfCȧC6JBC|&CCC!C^CC-B+3K@g B BBzCC.&C~%C56 CgCCPeCCfCUCTCCS+C~`7C6FCOC/KC1FC~>KCKXCiaCb\C̓VCYCb[C.]_CU!cC6bC#aC^dCnMbCUCnLC7CRdCmC, CBSBCCeC C.&Cd*CeBLmB BMCOC߻CCbC{ CC]lC0(CWACUCXCYC-YXCWCXC^ZC5UCtSC'QVC;NC8C9+CطCpUCoCCC%!ClCB#CaCBi(BC4CQCC#!C2*0C%9C!CCEC;C`'KC2$PC\WC)]CjWCVC*\CVCRmTCOCZ(GC9C%CC^C}C C|aCCB/CCCr C#CCZCCMfCB*JB{@I@$BBBR4 C4CxC3C|C|4CC`Ct(CkK/C^"-C&CQ"C]C4CC /COC-RCrPCRCvUCTCVC_ZC?[C<]C;cCaCs\CƋ^CSCvGC5C^+CC?!CC5$C(CL\!Cܯ#CWC:B CcCCCz*CY7C>CB.C@)C'C_)C^ LCRC9]COZCRC϶VCg[C(RCEC]s=C2@Cb:Cx&C}C9 C CCC38CBeC C|C CaCCC]CCB1B\@;@A_BB%CC'CC CL C C/,C0C/)CC#CCSCB%CNBCUXCuRCkHCBCbFC0PCUC5YC?[CZCeaChdC)aCC `4C-C91CukCC݈UCנZC0 XC*WC[C_Cb^Cf]COWCPTC+`\CaqWCWCO#SCc=CmC!C C*CBKiBVBCeCVyCCAC%C1C CK CB|+CZLCȣOCުMC*PCƲOC6UCCAC C^C7CCv-C.C?\$C;CaCCRC"LC[C(D(C,Cc$Co"CZY!C{9CCH:C$BIBGS@I@B~B-BC{ C./ CC CsC`!CHCCz#Cs8CNDC1Cw*C7CG/C$/CD-C/C6C.CRG$C"CyC#DCCe]C!BB*$Ar@H_@7AchBBScC CbC$CBkCZC.C;,CK>Cd1C5Cw7C AC9Cj$CNCLCCiCCGBgBgAg@TʿAHBBBVC^ CgC|CC#C8C:BC5CNC.8CC8C!C!CCC C'C?C; WC]C>XCTZCa_CdC`C$\C_C"VCxMC^HC DC$v>C{5Cn)C;!CaCx CC9CVEC^W)Cr3CV:Co@CCCJCQCFQCUC.XCeVCVCfVCJCb1C C,CCCZC)C $C8*CQ1C6C.09C\>Cw4Co"CeLC;[C9C\BoB5AI AB@@A' bByӸBBEC# CCC&C#?CWaBC2CCCCCfCC҆CkCZ!C4~C:%Cҷ!(CC CCGCC~ C.&C%)C&C"CCCC$C9B*?A4OBB/B :CJC`E,C>4CE-C{%CCgCJuC%YCHCrC CKCC-C[CCi@Co'CCC C2#C"6C%QCݫ[C(RCp[?CR6C@-4C`1C2Cg,C 4#C[CBCUCu,C+gCYC3C)Cl2C4C9CHEAC]CeMCKC @C9C9/C"C=pCCKBOt C\CCпCCPCCBCCΡB#BuABBBr C!C-C2C:+CJ CC͹ CACCC CdCl!CC/C?C3C%%C~ CnCCyCX"C8C'NCPCzCC7CC/Cm-CH-C.+C"C?k CBӽBCnCC7C$CI)C0C9CCV/C/C H/CW$C'4!ClCĦBB? CCC/ CBBdb"AX?Bग़B4BB BNBhBCCCCC$Cm'C$.C߉.CY!CPCCd2CC C(x ClCC))CBC{GC8C.*CiCfC%c C.BƷBBB3 C~C %C,C6C7@C;sFCtBCS[@C.C!C6_*C@;CgnCC};Ch(Cp`&Ct*CN$CU CC#B/BABiBEnBmB[@A1BlBF CACCAC۶"C!C%C&CVC C[C0C|-CgC,C CCnC}%C\E6CI?Cy2C;'CCo_ C B0GB\BqB CpmC%CY1Cw?CCDCZ?C2C-CS'Cxx#C'CJ4C@5C3j-CiC_IC!C21 COCC~BdӥBOBdBjB@9n?A*BRBC(CNCPCCЏCgCC/C3?CSbCJC>WCAC)CeCdC-CK<Cک.C{3C3Cx CnZCFhCBfzBնBCCq#C2C^?C;K:Cľ)C!CC"C!CH#CQ+C5$CjC_CdCOCȥC C BCB5B@TGA'BKBWCCMC҉ C] ClCC1dCq C< CCxC5 CCC{ Ce CaCҵCEC(%CG3Cp$CѷC:. C^BB B,Cm$!CD"C-CU/C$CCCCCCC!CCRC!C1C3CB1BB:!Bd@zFbAB'BBBB9BBNC= CxCț CCk(C CK) C{ C&]C=C]CCJCC)C=#CCC(BWOBpBiCC6<"C~(CD#CxC!|C&C7C[ CiD CCQC!C CŇB'ÔBj yBd:B-AxAΒ@ ^=ѻA]B A B/-B!B!BBC C1 CCVCCC C\C$CC*CJ'!C@ CD CkBtBBaBfBGB3CC1U C .Ct CBHBj;BB B%CXB8NB 3BB}A BDBѨBDBK!BCCCNC C4CC5CCuC!CYC CB1B A~BӛCoC8CB{B >- AwBV`B$B)At APBlOB.BBqCj CC{CK C CC# CC?B;B B~5AK"BrBBB6z`B Akl=HIA BBB{B[B%BC)Cd]C;gBwB6uByB/AAzABհ@JAB,`BsyBˎBF`B VBL@uc0E8+%CH2{`" X\P4lMmk\-Zhnܥ)q,nPډW>)\m8.%#> W)ƛ'Cp*oX(c7+[t-uhp,M/xx>_¨N/-^Zɞk=/*# `& "BY?ɍmP9߭: uPQv{dCh04J :o ƛ?I y Ǥ|Ym=wY7 2'&8z/NB4g8 xCFc̟j0`|B O^ܔ|tSx$_p(!Q .$U=+p-1lhohf[*EFgt a:!- C&Ug~QV8 ^C0R+s45m|m*}eS蕩 fmB1(H| Ag Eq004àע AIHK@[.8[z2? lX?jufs/eBE*h9Z;`_bu嶐3k3K XwCD̓p5gGn8a|'6w-ި6:p7틄-/\alqTv `Mbڷ0x)xtb6r);_B,qG' bCrA4/ )A۳ayzr3`.q^ccW~G[G|R PRkP(\ {Y~Av ǰ)9Zvͽh@G e5N^:JΨ2ଚ;j  ?nD@Ek-,o y0*,kI5r] C>7GÂ>8وFK{L7L=o?{Dz $*-\4'Nꨣl5P;Rx7/~ûm[B+p3]hTAߜqCV 5pΤ#AزDtᮣۄ_N{;xߐ6ģYapJ(Vu蒗Sqw.LǁQPP@V(6^"x/ 3Pz'LJ=4r? /r eC vy2W~\ad0ze ^ޅo>zRX5잖cY=   A qW)N@PLr.}?= I6>O&~A}xOnutbr~_>GRQ*//RQY !g >T]P(▻9W*WiD\V?[Qg}'wQZy0 'CD4޳IG?bL|.@v ܕvov3@+ C+݅ C`~ɀs 48$ù$?`X'?ҀB\Xnpq@ؑZ2AH,a#:]A=}&p+v.%,;FӀ' ~ >Pp7u>ZT{;80m^/bPB xl%TibPFc {]:p8[-%E|tB&pa cnP3CaZphk,TDR6F@2X^Rһ*C|{?,>}x33PO91\5i !'(ACW0d(9dXns E8}gmэԷ֘ 4Sl Ty 0c!zUx7f_-\/,@d=p]7$<`Λ-`6 *A;7<w?ܺ5Xu!kwZf R^l^ӂ+ `Fu:FP*<c< jCaxˌf01{:Eo86KT/ 'B/GLjO[i;pb`QLP D?K'R<<`>eq Z[Y*?>wԼDwv<7t0ǣRZlӱyr7>c5/prR/O i1KAܓ.|+;RQF<_L T|z+H!ÎFp0te`Sz/N}F2f7q0@.glpɋGȔ<2%`M2iuKLfg{6 6Djb`H(v0 ko\K ObG#4dp]]ТY t-[V[C[k!G_ưZ<W˧p1n)p7sualYMBs\xw }; 55^v~s*H ھ=/yB[A*(ˡtâI`Lw᠎.^_`柆XL-mJ\MeIxG _+"h4=c l_bq'\V cy,,ǣ7'zX|ᏳCg@]k(2*diBC)N]lٖ`C]R[.7e]Qp)cЈSؗ%pX>NvdB (Zȍ'cA$BgdL[ s.bk=ZX_G%HT3F d '{0>Dn| 0Qyr ѝtkC80湞e>y 6̴N涫i?t> >C+f?h&XK&2E݃8yo, JQVi!XQXvEHGʳVR[Fs+S j;H (w#^]sefѥ" L6ʫ'lE_-W[ o@k/Ρۜ/0gDQ幸4 ;$ %eLA1$i1@6()[(g,zw/Mpf V-ap.9  pŋo\:<u}tlSah=6gq:l9M^/y6kEWenuӋϣ@|YcҴqcšW<Ս*4f6((M=OݛJN^": Q-8E2ZN!O iXK2֊kЬp$XЩiK_.@̕B*9OOh~2¤Ѻ- 3EtM*ua~izQ툿0Që.\Ԃp}YR (|ÿir@ a *0/æլe™&x9ezf1/߯aQ>+Gzo`<قEuP޲xcf?UAk̾~GQs-sGR Q6מH7>38R=* 9KUb-66OWFsmW(ڃg\ڃOY y Xߒ4K3V/+( dJ|&#e7l~b`F9s$U|'683U4|z 쫻֕`|T!7WؠN)z(|1L!5\1xþenrK)w +P.0Kb/=Is2: ۊlwGpd*5g2 4{3@(~y؈)TggC4(<ߨ(_D3%u\=4m&=ՎJ XT0)0W -q~2: Dg( ”My!ap~ ":phk<,h`ڎ' Z;غ&Oi k!ˈ?pmޚZz~#,A)"N{xP#ķ-1|` y(s\t"}}\x[5I.L)֯E_C%[=V8`y>S RxFɐ9k@W6Ӭ4'nF2O~M22_$#U=2#Kf/RXLXu)v#k7D6Q ^]Z7XKZ) 4n .pa;Y $B`~Z;tϋuX ֪XЛv}c-r'X$e(Rx}jIp%8el7J 9?C:1 #M3o6 I6Aj| ,(Ëw~q|fsϋۍj 3 'q0ʀ) U#yp]'ؾ&5W+a[=?z$tb^ׇMî{98x0BހzM:źqxbV+#`obbE'<>Bu&^3}gbSO{|4 Ke>ʨt*=|(5!yL)Fl3a{>:$9F4aoJ!>tsYɆ̕k~=%aw<=ϲk5MI'|Lf߱JpK}A">CP&v D{>?*C7ft07g^P g3X$BWS-HOBևnÙ7% =P* \`Fl["1q+茒ǖ%8'ጠ3E Ɔ0 6|E҇{$Ζ=_))^С{yfhVG߸[:j7I =e_B`Sv1Xs17Mp8rw|OlI6kKaZmV7 Qrح x<`-z[>̙nkK1+v|6e?'Y5Y/8pd0-_;r`  9Gqsn4Ӆ_pS8gT!Z@,T]?GܾgijS%eZp5.\gJۊC4ν墿pp]>阡 i_&8M=7i꯱; eH!f%Pݍ{&q̧'qp'>LGGH/ʃ^OfX5vCDs y[|5x|?]y 3@MO)ؖtB^O2lOVy`p9[[b z4$ .%  =HFۨhyb5 m^% j 2K?a R%z;o`CXx֦2,7Z!+LeN1nRbcs-'Pm' w-ESjǁJx'?8{A5L_qӋ009/`Y,> &(bǏhl\8 35 l^L?LFċ}N[U*kfMo-yb&tٹ %_Z@T>qsBvqM} ڳ{bdK5E_DeD$>K/X45>rj)0 Au>!*^gy.TVP-!+96؜3 ܮUڱf?/͂uJ!ȬyTxKB:HeNt<&})1*ۯÌ 9N} " }Ɍn:s|2˲MDn1Ie1[C M(2x|cz(A6dDn!NTs qhS_yޤtkMh#S;r'(>AKbnQq.P}hBrxH,G i] | #e!hl,nb.e<9IT\SӝH_ł&<] WO:NY;~9Ʒ`,,c| xNC3?rx61op(F~m%PB)h̜Í0 pxpbaD:pk)ec{heHD2%P-aʾ֦iS!w)a/ ^<~ːx_^.&2.&7x~^)WFq[t}o馏 5Gnn\eBt o&\ 0;tD%[GJ} '6n-Pn4D}Kc8epf96n_0ظ"qLi\,b?s=oqZ7.\|AV+/5e?W8UT&3]E8ҟ ЛcDG* f(pyIUҶ!s:, @-/X&[M_(oErbr3|"dnKJZ,Y\DS: (Vߜce)Jq$yc,3WV8w b.kx=Z*%LZ5 k*RεW>d Tu~nD晴R-:lNQ)wN| j:,V(d&Il 4aa3>@9Rn!i'D Zw/K(j_.oTt8gt<6Bh= G%s&s1O9Dז.T܄ٛ095AZu 9yDs.0.~Ee@~"njpA#ܟ.a?_迭"Kӟ- CCQEAZË.PFz^y6m:)??@]ipd:;ճonC<,`9:&,*vrc; _!du<ϊ[sȕ)_ v,&*wQHj(Gl4h^ȑc Y%MSf9ERt+pU $W Te-,Ln5%]S݉u}Is5egh]=:$D1Ail18C6* d/q|XW9 8Ip~j|x->qƾ!y/4-hL`Lܙyґ$ ͡)GR"S~i_~WQGyD$h~ G":UE&N"t]~ywSؐm,Ȧrh2}Pهx0m)Kv/MNWSΤ{HyU=3.8 t%ŔiQϏN ]F߄} X2g2w@7 ݰf^)+SJ?En zE$֜Շd"t[EEAxe*%SLԸ cыze{P/qhI~6~Ɖ<'eTTlCb[R΋2lY_5b 7`NDΧ% T步ʭI_k'Rm.:|&DR۴_r7%,2ac lxK`~J82? `[y 3 ؽtg(8*e菔IVgA)ܮɃAPy ɂ- KP{yt`.5'$hNe.K1^[X嬨原a,6|#rkiM5-pJSc"{QZ&ٟIޝ+$#KvP ,W%3t"v5a++L-~xr%F^z i:,ET]Mr/?P>{p{#9@ŇQr6!zp_ǎ`QLI?qa2}5VP)̹ۍml;k81LlAnu؞jLį+K.] ϋX/veW#?_+$v8 #sٰk3)9Վĝ\Hy'nbW&\RHhz_EjT|#P<5't=?|T).)=F~XKR#ɵlgg AX7-ӧ={qQ|ϜCߖof䂥eXQ9gyz7L?)ٷI)EWk߉f;k~G}Ea,G/s!Yڰ$=RLea5_3V3nWXP A?b}|ћO_M ; pU\`Xǘ4 n  +.~9#t|,7.;,XL4%~BI9 kK?=A1=c?m[C%VP?<)Rbf Zxi;uMӦ]gK|^4"}GBC#s*tˋ-V'gS2d޷ mwr%ϴBޤ+뉓Kp*uRӍ9̗qgRL'|OM_x~ VV}ہGp"(vGhl$G+ۈjӛ *3lk=ZS`b(3wz>JCq]ltMa?߸}Gdࠜ%u ajo*(ۙX&t./M֝6\GSIC;PדdfED7B>C#쇋u1>_n?c|Zy9MϾ\9t]j>$0V'^, f(Yo:>HT7;쮏ux˜*SG_} ueCn?<о8]D+Hc=/w@#yHg ecNIjTŲXo-[@h/}q98ߔ&o%L#\r QY xL.(Q[cEu͗~3.|Q/lTD0 6sRRO%I>t/㲛ԐvP!K:Mc,i-{fJV_Uz*ͷtۮt} ؐ>wZ(o'<|h,Lzn+z+ԩqoG%v1-<;NIX(. h_u1M=pXvGC{Kpk fܣF,P^ *"-Ü;jJWÄGԦэT>>n دGoP ހe.]xd/<>C (Oq}̢m+xR0sB;x(dn-B\;sA2a,Xho|c$^k}zoO lzщ7Ij~:'=pj/J*[3|@9 !BO[ns ZS᳙NFQ&5 '36I:跦C۠4 e`}j߂ }"NüUJǿ`6ZR OVMv?qRc< f.e\^dtq57d6$ dBCE{o4O{O*I&n?z㜧?us?D:`CLuZsY+ HZL0t`rݦ;g1< øHT񾘦l$v)g%#T}A֕X gBPKK۔Uz=#l($Ew/|0)o/g|д 1%8>*rp)>6ؤ&-U4Z*EB"|B%5ގqgHxx mk1>;#;)D,B=וDvVa,mQB==t_b}E1Dgi~zHp6H{ oQt\O$fqf4ṷ'|Ά8/ӏ=ÔOsy#hQznh߆_"5?%Ec0; ˇC%OtuA\⋛\l| Tk GB?Ssփ 9gJIXB}>czz㋷?'9cǃߚ!)9^Ӑ7ۺYǴ҈پ&dhCUз :2MF 6)+x~$La)m6-;Q"yĠm?V`7]8w=v9k2X56HSoO󵞘><qotzjh>xIfQXnyRlLjG=xx)Db4}hZ)0S}lCferap>i#0; Wjt: eqj3@$UX?6+BY=!,8;G xH! &ǠisƆK؊8 =4zUR!O)"4QYa }ohd4%Y"]TFZ˩$"^B녋sq{1?. q,X3 :{=Q(:c+fNgX터8-UjD_>c2L{!4<+hg )qU^C 4xP9&£t_Up(G$R(D׸!WTk;gL+|῟a^C_%Q◑:gn.ΘU(=i0]HخuM;."?i <:QO:EW]F[w4}3وܫ˩SƮs)v! ,[ W.4Gث (#\ٰq sF`+A1D֭#ww~*6fL,zE=G™X'>np^8.vgA„4x uժG_x!Wq@K%-oG̷`5*fx@\ 3=UD5.XK"i`${4M*ﺬEtImT%]Kjy=jM'*]Iori:9 IwCʹb/ĥL| d[GxYn/8xgx4Q0$_;zW(7ò8'"0*9W= p>-: yQ uR6z5!~~`oRٞtI'#5r [[\vX dӭSgsϵ5i{[vSupa߬wf܌WE|4˃pw<! Zc1V-Z&jkn>wMjsT4QYv,ʊBnьiœ}4Z.k70ր_U1Fmԅaz:=M7qyaӃvX `X2L)y[.Ž.~| *ᤄ:M>؎\Gqy0Dr)B=d=vU KfTz8俦Q _(EQe ؁Έ2u#y]xNkdY [x'78E 1GGѰ';% a2;Pxi'@^+)8(T]ng-H@!jf]#F}n@&oS k87a_0Cض=Rߊ5o)&+F[2qoIspBeY#v 1}C%, Kn>~,yN=ul"텪L,s>eTUSN\!9D\|p6v+ ,] beC jc$9t `db1T-osBAB>~>٨#h'R>(Kⵁ Ǎ`I1l"F[TcGK)ً!%8'˸7bj_`eڇ3gko|Ť)>Q?a8~.k@jOA%|ܿ0Y4 Q0 z0ëzwyhf6gg% 3/߯$n64f?"q!T沔س&ܞ?!#'tS_s4"XĿ:xkb4ySI{d ;CBjImPvCj(J yY9F;,\ت'YW&f8A 7C6?5 qՁ ahlU@qmQ3 o+8s.yaꍂ1&7.~پ!جDZ1e| :}Fz!q:2p*yD<)sְ!<¢/ʠ>Nc/u{iT,hD k+bxɢ&1-7!Fo7 O_~9M!&X^ięPJHhEq='4 S2B0lD-tt7^x D vMNEu>COEމ~5|[VxWk G B?\U1ŻQ^n5 9oZ``wV$I9[)fjbLً +^s+Я?b[;:= ;M:2fZ)]OSbl9>ۙCV}|\!o=4➜kۍ)(?:a69̳Fp,f:܉p-HW}Vja^7qF (Ai!.D=_Я%YX+ט8N;b^u9?#&\S ]]wָIGDg8YMU/P&?~8u%Ӭ4D'"'7I5O?M=!vPW*HE4s_=]wsѤ劈![a|~ifvDoQK C^\ g֧P@{+esa^^0ֺ&bd76 ZSSQ9 Ҩv !ي* ͤ'H9{| Q0)145QZտ:k睊K6:,Km}󼔖8M'C>dQ7u>0skreYldza0-W\جŷ'] owMFm* |0a#> &v3tH"&WfH:9 YJH6Kdk`'M<'ᑽ:B5g^8X)[1&=1ȹXqo̯UP:DtbP}0|- Mq>Xej=&N\Ejھ5tOGC0bU,}; z!M$[{+%+tL>eĥho$ly$THϝȢ_)hί'_74 ^p{&],ŷZܤ/- y0w5v25#Ż̦q?#(wB0n{NZH2PgݞA!a@[C oC.DfC*`n!q)A&N)6T40ќ9!6h#$-}ŝQeioqY=,U=n;KVPZ7qnwُCfeo0K4=ݴ;ԓ>EMyOq93`J%itH-w.ݾ0U^JK'Wp۔ID4wQſ:|^GӖ&,A6 -83M{WE$OFr?ĸDl D]9dskn65ܪ>5/t.{aa(U!K7FibV9d䥍QW^0Cgf"n6Y9 C(1暸smVf&t p| {! 9ȏ//qD?͑N%KÌZxzCat#"U!ۡt;g#2))v-}\L]gA` P⯑,ZKhReJN+Ȥ[֯'_4 v9yM-|rHװY$%wa,끢F\] ]oJ^R1S!+6GS "?4K{ƺ#h){٘g[W-QjU%։7Cͺ3z*1L+![k;LTѭbo\~ݎي= ? ;uaC6QIoyH)Ɔho ݪ$)+ALNg /zsa a]ّs`s<\~>vwApSVG7tbPjd[>^ OR'W姑ޒG%ۻַXZTJTGNJ ͘kR5=H*kJ{(vH oMenu0:0w2Tc+^g?f͐Urјx"1 ~X*unhhxd A搞C!FUNhԍCTy.ۊIʐSưEsZJs]T2`'wÒx6VFzP᫊b&02w^Щ}*sC,O?pJxM߆B/Ŏ%<>b<ݩހl~a_!(y.8ޣqV- 1u(hd~~!IN'Y~TUJ; :'\oԒFN'ݗh#YY0{pp#xʻXc!K*3ꇵ< VL*| |בQG!8r5Ϡ-l";2 ca`(@9p:b;9e-;oz~K]|u)c/x W9O= )ቼ>yc#Kp@ݹÈ:mu@jO,r. XBj:jjؼ,9k|ToHt^Lw\UTU5*؁ߵsKo$@Ω-4l}:C^ 6+9WG!?uԷӌ9TׇšiL]ZMUnT3&"[]H?n%RږHr}\ {kMj!w4qΌٽEx?436>H$2B#a;#Yo tU8EZs)g]30e9оh 'ʷ,  sAe !KWd (AonOBz/ ChY s~U`H'`KaJ.r}8V3k4&DoųJڈ+ח XLq,|'9E>Ӑ.y#M'3LL8f.FAWvl "Q2{TA$mfA:󪄞Ҧr|\L/tRAbYťiwDgRۡ$ZאD_ʴSTSݖ&lh9%]4md*Ҵ䶙3Ii2CˇJ,$}]%lYd)MX5[)8j1聦\?z'l a>m!3Oᓿ=~ D< Lً$پ,-rb 936hA>|^{"@*Fi+i*<~/ Y y1YwA`;*7#t6>2iL E.e>k&c|udFOFƎx/l]K52FŒ3 Mdrsij_ ^N?9]_RHmZ74=J3)o|cEq+ hش"x#h62$]}\#3Xʒ2Q!̣A_BV$& =G`P02uf :YO֚1/vXXm| WM c'EH3K;ߑ+ p\sЇ=QvE~ o- *4 ss<&x>݃9lӌ`ru>2ܗT肛;ilCd,!o̦0jajz~+5îhJxrӽ ԣAbhtWi|J$ofZRErOq/huCy!u${'^+@U^dNntv9z!јzv9iMzMki؛EEk2+1c2Ak=6a:_+q_|o:@(m>AL?)|eo!py L9`yG>z;@`a\ wbMHPUb(䬍ڗ޵ cҥ߻f=f/(P]6ίO`U/Yk4o>/Lc2T% ڒE.mtrC$=K_h/%򽙴W#YD'2"RΥcZȥN71 {/Pr!Rfpt#gݸu*%pÓD݇}KwsF^UhRl>6a(g\wu<g'4ju04c?\ <^bnꁣ!"䊢l/D\wv|n;ó=JuzξJȚJ2K1@lD *0]s9TA4NbM+qsK~CSSdE#;W50&(.*TSgEqO:9Ї 4(ͽH ,o.8z@fnA%6Jw֊<whPn3tvqr ]I>'˔Pt5irϠbV1fM4딫!UԜ3CG[q0.{HR!JV \sAlvBeQ:V##gt:ߍυ $˔uPڼ 3v"Dz!2oZ1{7)aZw. X{]W#kRh1l0B”liV:#s/屪+ Bk)^WRn:'G:6(Lig̻'[XvEbgjzW\ŷa0E`SD$_CP 4ƶ%6%<(|KgR,Voq 8=x' (2&X[w |V=WZkYϤP=V(6(gӼX=;P|l{i*={?gqQp{ 2ޞaoMû{I_H|z{]J~hF3.ζ(r& T3-E~TDݾdU_@ߔP}Mп: .oo$a4v~_?=\FwS,JbWjhxm/cgR4zO3k`g]dMF^MlK=>IPp~/>1S+vcE8cXFkFg_|%O,gބih>koڇ3:2c'P۱Kr^T}_BhXR4@Q}T˾>:.e`J2#>>K-b#qH, {E34FY啑c͜F{dіIZ(۶ O()U+IqTVOsb+)ɤ[/)mO/OGy뷔gf=9[7Rib5m@HbQ8Rd]LlxDP!l\V1 NMq|\>x!o<:`*DbS]D{ LDC"YK_<^E[0`Lxz†2 _p#ԑR?$un{HM.trcyf2"vQ6Dؔlp2d'I[*5f䐇y)BZ\wͣ-f}f}D|zqvnn$?/nfD5sȏr>-tM-8$Ql Í4k^B(,Em Y~Uhӣo8 Yv#gRXΦK(A֜wBx* J5P&mfP 3ǑԷL SLsOҸIӝ1H'FlZMYu>fJbPse2(ݷGo[Iu :}E3,و aE̤&ۚ_ض-'Zy$}T&u<.B7=hz h,!tq%jɓ!e)̒*:3Ylj_?ȣƅF ~$6+g#O_7-hx*򬋴I1 X s nG a e72 9,( S/b{ 'Z]NFWn*uF◚AGA]Ɔ 5V䬾͕;F(7߇QvːX}w- n1a P8i3!y /ǦYXSq. ?2!jWIT1eme1987x$TPgG m H"3I\Cc*8[: m`RrxMͷZ&'_dpr·U_3"Wih׋HZ< GZ4Kϕ,>!dlxz Jvg3THw*3kEz,3 ؖlTa%d3']#䥣! ƛz:_z`)wL3:#ГAZ*|ux>RE%sw#w(!y$}9b=9Y<~baG>/`gJ~f cYlD*flleX,M>QCl<#8ԯ>\3!yb/Rm)mO?cII^}8,*Q#A(ō ƶ]G6 MvW9y< SNІRb(,h4Chz_07"9STЌtnE)TѰibJJI ({^N.b9=jR.Ԋ ,$bxsn峫߃1 r>ñ{03@?xc" J`mJs7/oqh5ûo#V@Dos`$7ek>Ӻu`3-Rw1`/&$&^&gǔٳLޘ|K5H*y Q=TIhp*TN~id*Yqtb>[Sd7b 4?TiiYLTle BܣRs!gDY9qwyfҭogheu~4œފ3-|^gUY{1KEOځ0|*fOg(5vc .s  ?T>,(iqLӪઉ$>A]b#F0x %gzڻǙDl$,i~wdSx/3L,l`B;&g,英ȯR]Nv5B|4^".jNN3=~d.BӚ{Ժtl{$tELΣ5~$q 5ZS!/,U4P-H*+ƃDsfE_-r#9)"2r_Pǧmkܫ():6g7e:}V$}e,];0NN sg?gcE6w70Rz,ٮ,ƳX0Rp_{*ȸOO1]1v״4A[C>b7oډ7b&6K03In udxbw هe,;[-lJR?=ɌF6 o|Kur:WA5 T{*Iz{cɫԠµ0z*TCהD˫iDusj VHs'E㻢s:lͽI`yn wd&˦V4@̦]ܟkxegBzz::rȡ/bˡ}8%YA?/cĜzbVNd+= |&',N̞b̢7*utD6ɲLNJyolSK#It7a<!2c!S -u} bkNT'ym4%)FRH}gBv$$eg6ho M"ZM}ϫu>xn V9?_c`(ESiU/2Bx\ @4^7fBDwP}q~;&9cҬ͐y?/5bx>5&j!TGY:O;ܢG hj9=^BKeѳd'IJR1߅>WЯM>!yB|j[Gc~{eg54E[ n &ݓw~`LYC}2SD/q9~7Ey)UӰ^&)4qD=NU e"i *={oon}Wu G6dޱ tQmmyK0f)z}\ L< C"ҹ Y8:?\cd_'Pc,|p0=e|<=c \>N¤%JRex^;GYBDOe!5y=&\Nӓgȴ46ȣMσH=m-.4O99֓U4-2ȃNVIILѱE)S9r=ށ yE(JxVH[ MW=$sвF`t=&G'93as9_8៣yHKn:jRD +МHy^Tfؾiԩ,]2dL"ieTS&43L*}t.:z#pKj x]OhC/~MyF RSh}zFFR0u(dї;E!MJjpݮERk?'_ dvSmrsy:3>5>^(V T߯;{0ڬ!bycfمU_#1yNūQiqz8z|J-]qw6,lCiZRtIx_ZuޒGЦ,9G:AtjoKsq>sM~A4cN1Eh%oiSt·~gGE)#Α):}4eǑ{2 -s*Ǐ cw=XKB>$=ESc& dj؞EV odW 6鋖N6g&5l4IrC;h=R_z~̚S/An uXj;<31/qc>{ _s`Ю8-68uUF=#Je~Aچ&i)%ZL 8P[a8t\og[>.ܗ7]+C| 17j`]}<}1ph`mw&PKx]HƺaagX?{4.T^Ŷ=o{^RCGȾk2G9kZޖEhT0^I)^`KI5R]HަfiᘾOY7#a}-~GqkB @4iO x[;}{n` 'BPR_ ZU"gӰM@M=綳TNnwC"Wy4i7 {Nd_nsbs}([ۇhسxy(y5dH ΝR2-k72鷩oz`(x_ r"{@u *YeV7CSI@}Sk"=2{iߘϋu"^CΓ@ -#h菀>*8nyG'Ojmm:ha ^D[(fzB.Tۜ;b[*t]s&Ÿ2ȑrmOAB77os1:wT\iTO={"Z,GBE.x]×8"5uV0Y ʝ;-J9<lÿG't'PC)% bxvķ1iyʽNMB߳ds~s=d,*rvQ|֍>!ò?M-D>s'X>ZiW*]> HG X|t7Td:=\Y )>x|WjVCU:aDZ^r- zV/ìeƢu_4WG^Z ϕqcɭHCUJ< ?RwP«v9XT"D]WL~Du8CvaZƘ$dv$XyRdl:[_?|9 24X[mCޕd5~<,| 9ҫ'Huu 5NbOQD+O0p<}Pd21ApU/Йit#E67+ TjXy3,&47,Cer.9P1gw@Cx_~nuJ#CqxQ·Z^=Y8z>̋00ۿ"J8Bdjxe VC~+H%J.j| %c$!]#eӛG.UK9ݕf,3]K)A7_rZ_%mB,\JzVHU;k%H^9EVe1⽎ǑҞz<1~$XglyI4:UdO~"gTSu299,}0/ʰRMP} rz v NquWks1zظV^nmqäF}=jۧRL.+? k_~]oO}6篏wl^wVB{sO{=\bmnk5(;wt/Kwg˳7dP)w־F>$zBSSێS =}jO &ݖ^_&>"{],_tk\Am8AA*rRi3q?9K]R }hW-DI=چzj(yp)MO:mw&=Rkk.U];| pxi;8|fG<5E!-C}ǡq8;NZ34ϐLozS޴$~t:65jN^$m6 MH.w\Iuq2!'O+^"2B"'7\ V=LItX+[%KI9EkQZx@$}H!|zPnu!O y^*zD '*F2΀FF{#%㆜efMQ6Ȋ{g @8wc(f)߳]mPZ(j3׹7\''mu\&5]؝nIȹtu;_. NCYkK'&?k[ 29LxpLcG ˫zӨB?]y TY %J LOCE:$Д2CORtj }{F!doPe QICLF'שaoU*Z9,+Pڑr vkr li.uPEP懨׶RG4i=J#bUw-xMG/RHl ]K\!&Y_k 2~tvQ7(:"yqT5ψݠKϋ]qIoĈt,ҍI"띠Ke*TN=u'2Om.18 Xm}0Ou+0jW!SG(TeO-/~Dfk@zc?D]v+&`LNx`¸Or5VjsG<ŽBv>?=84U^v;[7zuXYEvTWL8M]Nқq9)urfK_*hrj6uް$dѧ9@&[=ughհ*49$Ua0LZ`{CL VdYBτu&u-4/]8M3_b. q؋y8g =o{bL_7vcC}l?~]M-B@V;:/Rs5%Ê,S?#M .Ҿ)pNp8~!5_dTt7ԍ*ӝ 4"hmz6RN}8]x@KH~?+U=Z.Š-]WRr:0n H:]MTBwZ~AfiԠ#ɡߚiIRzFaa"GQf`-R Dݔc(~E8p^{R[/y KJBok] >I/tdSYNsW4i.Fpr΀\l=F#|P|M :ԯ"(Unǹe<.^!&/c\F]6˩Ǧr5J6л)<É'[peD'}F,K%Q^B>;N 89Ri /+D_ҜccPͳu4}}Vܹ=xt jQY%x7`,>6G [0t85GȀ:(Ɯcx|`HF ѐ^|w;C'8Cd)4G|a5Q4wM#5̤ld EKQ" O=%Rug 4X>1JZd*h`D:mNqG$$zsL_Qf ) 4gLj\ܴ+Ome' N~"7x³M:rT:~prmz`n|^71- wes45- v~\ݧO0ٚpuh^Fʧ9>IFyeG6Gؽ0zz ʚ/>и5 td:^oѡﴜ¿CPӄrMп{I|U5-6cZt>TKO?>A4/)jS :\ t,ȥ!ETESKrqZGA"dZz<-` K$9s7m] BI6CYKH%vde8{zVr|H?ĈI=b):"TEgZ-}^SZ]6:AEX";7Иܣ߱bаT5">Od/8˩ !|T䬭VybԊ"? x,-VZZޚ<@Ѐq&q_gv M &ˋe˟#o`Mi)V 񩡻g 9.f>Yczluo*}od{6ƥs|SwJT*9m2=oI򺒍<@1^x2̏H/*^IqtAǗMQLD WK'搮U*ZڧuXܗfHf7)]m @Yg+W˂sV>'ԦyhڣM_6 ?GSl;7P9I 1;Tq?H-WF9{Bfx.,e`1UHԑy"[\"ûc3z$V`}kWoEط=jr+ 1ÄE|j>k?_禯bwkZQԑsZn6 1y-/Wo=ì9ē;=7Ǚȇ[ SԿu󻲺4dשG)k!Ŭ@R;!b\!ݣj tt :VR )O-~v u[]KhGPmM>+J&v@J"&wLz]E+,&Hot/ /Dt)͸)mCb4.܅Œႝ:``|H 8{fv`ݓR?!ԸO(KLp#?5xu0V|=%3ܺo#/|& ?u9s2Ok9r2sos8d [q(Ք4dW,jZK7_4O6vxEdSO9|Zz*eA4:%oZSL%M`Pv;5UxڼYLïiܬnHW G7~X3Dvy1G 6y.XTc[:"0¤ x}knUiu4,.zZTku#?R6F^ptHreV7f[,ړ-`%f6Ws|j8z~8%$"% 5}eŢD'n3g'}id2&Lf7{4eg!8֖KU,|n8>)ǞR4%xC=u ?в9"G4$%DO(jH ͠&p/'4A ;%b(a&X6myn#Zꌶ$/m"C9t Ԙq؀{uP6:b_hM#,^2~`c3`O/q9>Ӄ'VMjű\52Lx!a Si/-穗{%Ň]m =g]c2 5u(~LAQPD74Ћ_ DnE̚TBτ&iЄK_)w ,!N3$¿,|@c]ID ;`x(ɺ#=tX@Sa.?JE&B!`sHEBv㕻U3v`ai ]zwl67lc27Nxi.|&`et]ћUTϐ9Ip wٗŶEvgkESn5y?Cqћ xj1ݣ?ZZkޓѬkxǓuL 08}@k?h^[4,۪wȴVwF&e̽?bZH}c%zfOF-:؟J˶P54~%Ғ~HV3fh]1Hp$]Bqk7_h^"0EDww4/X0٨~\&q\8 2BlcN7#o+:M+`> ౓g\^˘ykrׄAf0S0Y7)$x YkQKڟvBR)L_g{aPݡE;-zO)mJ}zk%dl*'.}N ΩCjP8o&~ ')UgTŨ؍.r&tuAZO h5Ŭ@Ȗlƪ༏`gc _лa1&:-Ā?}E v$[#v a5.XLI׍s,oK2~ݟw V7Pԃ=>\_y@loq8W&q}SQi?aėW HK2Yyg N|Nw녩 `$p)/R'[ ?06ef:+8WuJ+ aƱ==VLw+q؞ s8: BӓC'ٽ*wcat(2EF;(Kd( ݧ-Ϩ>a.|OKK &wqfϠw}`}ȹB_e>w~cI v2?̋"6exx~Ή*h*# 9 cܘW܁@-Q[4qiYj7TbqO&fUB޺pfY'?ٳ~2ooW5\i|ɩ07 7weFRs>MWDߡՏẼ7W:"B^>矋1p὿I5]p(yk :6ߣJE/#>4[g7%yaNLr_+Vk\Yf _7teql=֍OQb>>vC@1פr&Dh ra{&.+;C#5 au;SxXl-軴[|&PT{\t~X @O1CPYek񭡣Lɖc٣yzxb<QНlFVtD^? ΨK0n6fS½v{6g \;6ڎy|/:by5lf=IC;si2!/ou\4h컘Wn&? ;UtȤo` ߥ@r=z]cWBVޕjFS=jvC`e`Q0xDv7 }kxm6}=u?_\X`?/Rϕ0/+Mf]?b+_3d78 V*ippl] 'fE~l \P O4K$O&%Ѻ>4B&BnN$&*ACRM9t)Ad, ;$LsY5RkULl #Z6pUw1SW{@$bk˧P]!BHF4ҁ)W`SLJZyGtlkK7te8 ԋ#`v8!z<m^ԝ|~lY8E0 N뷲yGu8diV>'0>^esz׉˯clrӜdm\, oQ(IKm;6RE+" G>( ݬ [}Z^=?_VX B_z=4G&ZVKaad]#ǴPKPO,mx'@@/xKӟ.Fc)|,W H(=0.Gѵ"wo!嗲CpTi;t4gz4z׭+?}.2.z/LGlWc6|c V}yg*[>m:w%7^,ڙ+ k66H!8s7SGo&tcʔ{2莾 3c,znů9ŃSx3|upѩѹl"+ ZÞiak@6fz*=)4KaPe;v:'xh[<ŷ?;_Pv=˩V& C\*>)M>|P,ajoܧhZ ^[Xv'rogfcPS"z/R7|2j/T\Kse=/^{=EG6c%-ߊbA{Z+` VbG-~v[!q@H:`˜;p>*GBym୺|qpޒkцywN}_ٳL__޼0qbְ+[ww^2_ Ǟ\hzmm&z:'6OE`ܚu3Gaӊ뉘jX2r!O; iooLT6_nu>␑r8bWOHh2r5 l|Gś 4Y6z, 1}s֮ Р{ s~w@3ui׀5lH,x&Ϗ8QYR@w = nUcE!-vkE;{8-GyHQgXr3܊W'tn~ m ;#zX >&sǎbæWU0I| Es3mP=&O*H ssoEڼYOy| ǚQћ_cYBf {GAAҙ^7~[f+)=/o [ 7ቲh{x4'}q{ vpwE!yPˆ{;mG4: 4m"hOoD<&[礉TJc6DVKaɗ41*IK2VoMk}->yhNx&n^ ^io{D9O[_,kMOjsZj?[;/"Fd}{LEyZsC_u.щ8~}xlS-s s=~kV:W3fS1 {e,J~ĢlcXxd;`#eXt%BX6c<[8JͨC~}LʲB#-v:86i7c9g9TDBiqV!igXbDi8$TYc$$}]b Әp>Î<#`\+D1(|n(f帷`CY?yNuxrkl˰+sW,i)&ﷃ2*p7X }C .܋`n ΞY^IF3c^e<{B:]Nxˆ A~ |Sa)].Vc"mwq),eŎ1afe^VЭ99HRD< L}GWܧK[_Lcnkx,&ui |+ĆJ25t6dK3eK{دKevp7B|B/G}iA|5#z" ',Fv5,cnW|` Bf'Zw#Hq&ߓF;"_YQKUoMX)C4E..Ȍv6ֆjq:+uz>~#oIvy*Ux>g 6TzYOM$X՞X9F_"F36`w%N^_jPW~-7)eh**LXM7X K4._11gDѲDB *v h|?EټGeDg@tG8+`rXљH'?}J0'IH>8_ tKV#8.ԢUp֙ dݦؠ剞QH((=St02F1y^&c ?D4a *pd1lmfx_tTc+\S9"{dދS:lաVSFNo(j 6ϐ{Y+a:~lGt)U<ƆTƚGQ4_s~gY(Y~J0Uܳm=ަ6^3_>]bº)bŢeN |uttv+ e ؏mblPx5;0k|<4p=8~~qq7k`xȞ4N7;9QDFiv\2 ec<03^3\A"p5t 3!4!gU8k@w^xVtDO쎦tؐٷc.1>eYJhĢo'KYQI);4yJdG Y,Vz8/C^>kv/jm%F]Tn2ngM GMؓLca0o K6ZL<NlFJWO[H ݲlm!*)i ],8Ja!ӱ+WK703 LN:!-u_Lp:w51U* D )CU "M&I`Zց%"18b.E yVguJq ֤dKWD$_|'m V%#^[ K٤:a;mQ=0$ElYx&Ύ*d]O~/^Eg6cXlք\)o[Z=,%z}=H_lM3Sx ߸m1DIroinZ?OSw5vF>"0&>]˯EvHFik+敼SqJ"^.`88}jRh`1Կ!uv:&Y8%3*.`h_ARb)ܛsVoM¡.HgՋ FZ%Bc@ o,6Q8?KثT%|ƞb|q_E3Nj7S%8&=;) Y8@؟!KӋSJlQ99'NO(N#ML_#$XRuϞ.g\ )p2ȀH_ V^*,-=3 ViMC\Do:l勹/ Bؕ9C$K In>^t,aݯn~6{AF%%oъ)Tg{e 3+q6|>u|(_Yχbf(2vsTh/D~9vC'v5[mzIɻKhcKxkIeu,G'iOMIί:Q&gȥx36RCɩiwۙEs7zgES>m"lt ypxM8U/SՑ*Af,6啸*8\^^g<=,4&E ?!SEθZqr ]ތ#3k7D憡%u..Sbr}j>[bz7vJ`8ME^΅36Glsz(C+P q :˞$ ߥfʓXd0J,1e;{hGyeHm29Eo/4QqZ \Fb>W#a'gu441<aԕ ݚeX<Ԅ?mlR/q}ło+tP9aTUG ڝO鈄Ĺo]R^~˹1apUImM/ΐz{*%;k@{"f̑8mJGl6|YucVq[ oacIou(t-kjxR.lZVX"K3m$}O!v[;7˿k9Hྫǖ{]leu|7҅LF<7sH9ړ며_኉73z5yOL[9#T"Hq4G[%fXd6ft&Ϭ0sJZsݬFf+DtF.E;YYq,m5ؙ bowAW*Dvku|Bqk-Z;Y3g+U4\Ӗ qGr uYMd!򜒍 z&P::k  S5ގ2~ޚY ?T΂й-Hd:IHr5h1&9.r'ǘHlN7hO'n6J=am>Ay~7D쫚*{R~0l5 a(ƱO>ue+gߠ$%`"_$Iy ߤc(O4j ӓV8#Vy"?޳ɲ^dG ّ \d,}tBZ*.-g'؁>J&{}.ү߯# =,,rRRb*ř殝Th`d&˰9lD%B6i$ 87}aH{<1\ OXٱ8,}>*°v:?6ps"3|6\0C 7 z. BxHa63YU8to_g1azޯ"O=6@Fw+cdH㖤^Wě ȼ0W 5s (ߝ̛_ t(HbK՘i (8E&Ǩ\ jfWٛ x*u Ӳ]x[C]/h{ fVF/b$[+[[hXK=V aū}xQ؀mSai^ιKF;2s!)=,Кm}c0 Blpgݮ"s @t ^&™xT,^g؀AOuhEj!X9 )<],S:/NíT_NW}8 'Ύ4'p}Rt1eȞpX5 Rp>(e^()ǃ0a5^ٖbX],3eyK1HKTJ/g?2Tb񔲋^uZx|PyD{8Cj#@X~L*8i#$fnkoYf=(I,׊ oYb8\l-(#I8D0.L} o΄,Zgo|9s^Q<U/Qvm>adHz%C4 ba9I9walnG$N F?8f`5YA3 ۼ |Ame:9YK q~[9G`%Xyh)̵qMwL[5v;dLE6Ӆvؿu̞"b8N/~RLVz B,$ ,n2Now c" X2x?YA76bLqf#tKq28Lu0^$*iO؈#q f~nvsBBnдC\gv [c=*\L-14R:=Uܳ?k):KHM~.'@vϞёǴ;2#bCxrVR(;gs]j cAaX\ (dr Gۅ\77[iC74-8NJ+?͵Ck%EC=cOq 5}S.a14?SXK=Xj?/s=jNCԋ@a!?(|HĒY= Ob:g; ƸkOXsgW #X#4asޔ-ud- 6ŨV`~ƀ3Ũ4]E>-_6M4/.oŗ{o;3w^*|yf5c{'oˋKX.i]3- 6F8+v_җ^ 6D`D>a[ gG`jVHDQ$>&wg'SqO?[c h&t+bx}4}Nn]Ʃ`[9}AWC3S1(LBz>rA>3 ; 3fgs]R s&2흋oo t 9r' a l0K7aiD(59y7p:p4- 9JwҠsvP$UNOiuvu|AsO]I/SwC*춛r_5}1.abl?+lޯ+syʆDl.t [ Br3ẋ3aဋϝaix_V6 T0E);AB suAVލ\}q\_x~<t p"&¡DWd8s5mQu$Or1 !S#P fFi& -P אP67e&J|W_`VZL\p:JytM'TC9ιEj/H+Zi_^V9ńUH>N]}t=SC8j|bf2dôTυ{ڇ Z~aAZ#N ȱW5 O!: =n+q))BIX' 32o<pD [c1د7ŪdM޿fNzAkj<2qĘz}k/^YsVn(/’"Z$;}zህQ՛q!\=ƮY.D>f?8QOU3 ,Yz|ľ0} .fl׳WB#sStrU̠[gɅ]#8q= ]Y3<.E}^3]$EC!vQ(qƚN+Wjro D3wB!-9hWK(>G2?>,Fc|JP!71S'̎lULT˜@rp8C-D?8NJY NSR֮$$FE \&IgƷ(>ZO|'N>etpx+C=roTӼϤ7 bS Ru1+I7E) Sm[Mpnd zcʦA$TKi CgGch>VLՑg &rG| :قU8SRti4l+1llWCcآ˳G7  P J3vv_$G/{jA'F8O㩵obGҔ=oY8:< 5/470?ݤA\q-r_C6R2QI:d |'0~}!6rnm}i=Dftлba]P lKiz} ڒp[lNxeM#XO7e:Hs lvHY TTbT MP^ &έ@pfDoʼnkұi&=, ZXкgQfk<8$!PUSg &"b1* namO=i,f,_ҳ} [wS\(@S-A_/aUD1>ZYE?^OGO"5{Al#zTJQH::tr7_U݅3܇[rd.DvvQFn6P**N=e΄bX|9kﲖ?ȶͳpb$ToZoK`<241gDrx ,%t:g:-4ZMm#T)@G0Ud;^X~J46ښ(ߢ:I i_)U0@=LEhCj I[f f]6'u1~r㥞x*"kVۏ9}Is"e{2R~ &3Ib#0x {0&A I좋h!pBO]/bi)!vZ_|<\K2jWUTÕ]d絇&RP8w;ש躑z(G޲ű50$Y0M[?*QYZbTڈqLGW"B=(p6L7_Ӑ{n}l:|VzX>/G=JV1e$5p/lTX[{S- )ؒsژygsVei&xl/5WԔY D5;]Pkp/-GJĉ/²]tJmd+A7CM TmˎH~2J r :9,OOYK'븇FBۗA=LIZqfrtJcO @] lYI SjR9Nҫpy<:7"~4d.'K0hY6?\ }F aZ}elK%Q5GO*3qxR&b3M,F#3@k'atG%/mAMSE |g Θ 㛗t3qm4Ἦbu ʟǜ3΄=.!p/! aBCӯD!c*aJNX|^ESoqM*t*i=TSCF";T?OX+d4M$,2.\ qgLZϞҝdz7ӄHF}c/.},q0] egC^\3&/&h;+wXB4 U]L/6gD }ApKL|}"P4lgb TAd)`mX(`OI 8݌WhގsQZk&b4zAܷU0b&2"V[,49wL"d[:&7({42A>4濍d3l ,]")[.KeS٭qtu.RV?x^F6rXw?WVw[?nRIBֽSr`&>rXYjz|Nܚq*{m 8N|1Ag7!Ff=;g?`C'k'Y;t:^欖U8"sb^>xuL12qiF]) 8}J +ƀHr5EP%gc*2vhǪst`[>_A?ccɥa>қJ•qjIJȢI>kI%֕МKK"z$Ԓhc9[axӷJ>AM{KI nLmkVde^1_nlH_my;`as 1% qZؔ_}$gzPH\5mLRs# 7 SEj+0$' n8$aNjs& *ͦ Z x0F-0lx^0xH#Ilwxq{4N7JxDJ"lt(oއC*9 ^f!;P^Zc1&PUKeYzyw'㲷Tz$Wp&. $,Ghvy.d@ѭ6Ϻ-Es{*ı1/u^n`e) NpF@6) aXpWe[0+gBp^<r; =4$'D"m:U硝Bh:{3o&d2ߛ+0=7\q>Eϭ;`fςۨ3tǷx a f0OVOCr Է%aӪt,џf+[ Cn MQJŸ= juI~cZ޺OTRP•"y; S` <'coI(Iv> dm ,cP);6d c/vЕ3;hzDggmhQ*UВPS:ZK[IVru ŤnthΫ5d|lюԴ.C-]7|5fQ(ǖ; x6A5~@3>!hJPbW;a :ryM$/ܻjBv85i)"av*=b/y.B| ?yQQC Liıfe9N%:*^ȵ=h#рrRjnk''P޿YW]geGK%VӫZ;B X>ϲx=I`+4sTDXO8Ew ܧCu'wj9lB\"{{!C uפ3՘r _Cp; oC$x)DAklSr\U|'a̵qP<+  b}&=lFt)q~G T}_ gğ$?ޏ;I:n)*%TGS%HjHm \{og1b~l{~]*}p:O*b J3f2u&M,߉c5sبB6ZYk=D%Radݑy$y"(Ԝ>G+P0ܦ ۓyf跛 700 nÓ S m'"Y뤐_ K!t-uYdJB h 2r$p-;S'SUGȒcI-i^MJbdYgYYrK{j1?N%l'W@?Л=td#:cwv޿Om"xz#*lDCz5}NEgƗk烔mIn )߰e-!::dc:)$8Wd{<ZڶT7c57 <)USܠehޥXt7v|c h N@Izsf7$LE!(sM}'c x&bYlTIvhtXtnkf6!1BU WӖ^X=JܧBqjo?-$PMMG{=D5{x {xT I;Ց$wbNͧ7N6l {)*'q:]ϐdpl+O7?ט>`+t؞ 0oJnATvRJʬL_/л4D'woU|ET,FX-EHwwww("Xy|q?<9gf{>3g*H]<{&s0w.4vDLV$kbTZnsyD nИ y Ӌt lhnaW?A.h=q]މ[ާ'p]r{GV⏾rciښ9`lmټe?Į13,e?6W9R yuK^<1ŧ: 佡|*O9w9EkįҔ8|"7Mbϊ|-JA!Gw˷hO}V蠃8ҞgN7]~utx [{Y ==_<_႖ <)O#zBe?7s!B׽0~ۊ!{"u&&wҹ8|өBif*ڡϤDh_m$ξ&:L?:xt0&!nQN:!l*9ՄSli9-|K2; <빍VfevZ16D/bkX}%OEBb_J9i [,QVrfYx!Lr$o:fGi*F"E0"&41߆v 1ǵ7ٻ^?xhq[sBEED/31'@)Lœ F-}{r#qTLqS5cD<|9?9*Cxs8d@E%Lt"uA`hwaz p'fl3d+J,Wo@Yb,uF4rAWޤlܔhY!џ5WWԧ}!h͇ آM#5ӁGq7(Rh3Fô@d C\?ƥX6ڜG[s.hYd5ua3ܵ@UgqUy\e>E]PC@R/6( y :==V@U6 I~[EK72" 9pktj?E_.lCkב!_k0V$q+hgga_uF=d@E3xlJseI)u,-Flљ ʱt'VzZjlyA6ﵲ?:7Ÿ 0w Aa!7.qkn2> HHFdR9c3 OU艩SRdXDjӔUyC=—LGk-r#Mh:w K{ˬY\1='^vJϑ$/0"¡[Ú $`<9r$oSC9}SkOBJ31k\<3=Cr+ ԑ"YQ''*  E-̻Da7O:NvMբw}z!|`".ɦ8u${x/@LrrS,H -E#*~Ch#4fnŷMuMNƓ=JIáG,]![M i @g;NŠ^Xރ~A\<LJU_PvLV0Ŕ&ޟB%ӶQ[qE? @'"9oʸFϸ^cP>R>04Y$aM€IX$ pw Fa2GLF~X78 __p ?AnkuV<0^si;E;:W'|)/b}`}z׹Ri|1X2Ba4ȪPR.~\,Bee<6rk|`^<ӳ eEZh5<=V*DdAhIsy>OWVa##O:)8+b K(u09 !tJ. [FSB2wt4'4wln:?2¿SIDFtŰZ ["|Ӄ+ymkP1F<YK} ΨGAO-6X:b|W傻5YKPPzPbH{byq+_xؔmT޴&_ۨ "5%-B;'ou޹&CZ*uZ4#%&m?>BElk3Ę~>KU Nŋȭȝn?Sa8747[.>{E֍ɨI CȠC1%zY!,93.\W\xirICb< Ăx3c12g.#5bfw±^=exR]7Ml}2r!ӥ sЮcױQ7bڗ_MB(jL}D?m4cyӘ5N$5,ZӹhI͜~@ ;v$[R. &tSm$4ʻ{PM7 NmS]TuD|DNUkȣ*2c`ΤCsg,ۊɑ 0bw,T.WFY8Vh2,Bl"|z>7Яne1qJI &%alpxӭ-앋'3CѧSV ηv~y(9;p?ÐB[.ha\lԮO ]EfFwxQ2Bb7Fb sD4T#.B)?Ikih:JYu>^B8})t3 ޴o-ա9H2=I4%Q8li!. դa{ouāY&E8VϠ!A"kx`.W E`uo#`o.?$?=P̟u ]bs.08b|T.CdlsIlL@up :uQ Jy9s3=3 ceZ15!/UDC@=g= wkp. dyY&sB&JX @4VY2 ǂc4`E.,+Md=ʮ?ݟf7#1dڥ< 2Ms\<>r-g WJL+i*j:zr%>nS([PQZW䐯x ٹ"c?38ø%yC;=Ҝg fPz |P8"{"V7$C{_AdHDMU͈&ׂ!~a39S3d3C`L3Җ<_Ʊzkl[ Q0χ|e #ht^S,ͫjfΣ•kh =) {wYցybf hEzs*2a-@wQU9W/׳ѐa$@nҭu<)tk *zir\*\d;#AQ9(% |-"戹5x/D,slm tart݄U/2 Fw"ꔒ,chLlw@xOį P t;!-0Q~t|SViX!UUL=}=->o;XYNT! ZxWf݇VWmt6&pN<ѹ+gOb?^OH6O fONL/ұ)4@يdvދ 0.nD0}iԣV|lMW}OН~Yd=ZݦٮIe5zӚp}I?! :y2@rLqIX ӌ" % /@YSpS*wůvm6@1 ˸Lr(|KLбC~-hD곘 ~ åX|B_lv,.JNb{D_CA³R嗌׭\r4Tuc9\{\qx;%nN˴,)RN"ٴ5kME$:ql#Y+؈7 :YO bFO]Tt^S:"[A} k9v-؝RF?,)+2z 7= a">1(R'uXܬ 8diÐ.?~X>n}]z;]Dv>GF5\\w;5ή.H7ܨ@jNYXp3U:.\0F[R2l(>b_*ɒCxT"g˳ 0]@ntqVLQюL%zlJBQHV]i2ij}ZB6 If&Tyz-@gV/*"iW?%25N jw`M2tq0qqϋh z[|Bpy #)-ʉ2Oth?vEè:$NvG7;t6FgT}YrO>l}Eۆ x?%f?3W0N{gE>XغbJ vq^<~ӏ۟!$ɸی8aNB~?qK Vq#TGYq&<㹋,yL-ƃ$zt}' ?*Nѩܹ:FJ[$ EV=sMGm;UїŸ3cB^Q#yFrˤ{աލlɢx vlF SyH'q27qy SgyսG/S`UVQw` VaXXp1b~$Xt |h~nqEw`2Q}{džI͒Qi*ߧcbb ] X YrDzٺiFK6РU6>6{w&iD}t_6iEZtܗQMYNkH<)MGq;m* w,mאB,-,xݒҷ o糛r^u3h[O8bVaІDtJķ@@iB4駣w}x5@z/NT ݂tvݧ%ܡ[iͻVl9ix t~1V\ף7Gd^w/|px@^oL\.ifNxy ~U-_u Q_߿q#CpyZgMq.$w?WO t6w?=dL1d\vӐ)azPr;rS2qNB?ӠԹ؝"iXZٵrftCmH?*G81uP ;XGOBho:(CWؓT7z>OK+^ b^coGTdfcK|Tb1W6+l<:ǫ+-_tca޶AMXZ2K, CKV)EudP{1DFR~ E"f,X. 3GC+4@;] }ЍtwaHEM褗aO2>ڎ;_RgQMזN6k$ܩЈzuZI|uH4}E V*FmJGS:šμB3lcJҍnh_k)~3Q`le]7ECן0aBWh^IO& e.74WM]්),%aZkL$~ḽͯ`ɫPԿEB8zAחzӤmu(?/rQj¡҈-VPx 7o>e]<}n"vQξ| Y5(MqAd6;˦2wЪVd  AW5|mI39EUx9UӦ)dMGm阚 ld .y= ҁehhqoNzOC^Q"ϛtܽr*EfH9eFЅWn4M%6Ӻ9>aЕzj->C<4NoIwƪ]Weο5Bo· (ƵfEwS 7% # V'cr ?GЮihmNXꃰO0*_Ga:޹ {WQ]:_T5tP҇D$v +D6rþ|N3#Z4$eMQ]q{£D:ٖKd3Nf3?jjW Z_:֟N4K/^'ƽ&k'|@{7E?ӏgtg0/9uOW9T0^(T@{A' xdABm2IqMX܉eono2,+tx/?킼(Q(9UZa* E9tk0`3V~D338-U l͠:8@d8)AԿܚ$ƌǥa0%:-Z:M ƎL?Aا 8\Ձb*Ѓ& ݔ;wiO= ·$DG~f_2ӺK 2]N5!aeĄѾWлSGVw @[bLF<`:Ȼ#-|Զ ؝/4Յ43;wmJ'^jTp3gzxiI9L24DNkScl(KK4~R8kQ#\s#Gz=-dݏJ|}6|+QJn/\Ji4v=$!D } hƯL?ioD''e+h5י}|`ajOB"C=6κPL#1df0TKEANaÜ2|:(7OpKZvDT_ Yk9 ZdE:\R0nQ\}ֽRh65f27Wh-=Б:scf{B-Gpߎ 5J[oӾ"/3VEu34l*L+3rhr8X&::EtRAyaxuLnJϱn;HVxx MN|HK_}%^Z*\3,f$B>SN} )xc:݁O,cTE=s!*SD9#Ź9IH_/"c> ?΀rEvzgT8woY0Ҋh;\8~MyQ0jGp{0̿QZX̀c[Bb!Q/O=iY*R0?). Ye9_hg:n9Q,ܯH.?ԍ8#J%&7MWɬkuH# xt+9d-Ҷ΢:4;ʏ9؈Js>My(j^vHuG>PCu7orX66e8\gRTDyD&z*ϡ&H*K@pXZ9aij-Gy?.=>eEL&CX2vB<?tBл >OpE"; .8/]g@VU__vnBw"߿>xݵd~UO9љSW}q#:"a t@b{!a ~HߑZdIAh9VWq>s^jE#,!9q0,ވ?^6r-aJ2AꏳȐOͨd5H!K${](1'6!a] {!Z}De41* != kM%mw*jޕ˕(Gw:ԿS3*PWϾ4U22-1:DU5'{`-m^Z3W ګGi i&lFԦ#:&< YH"%RγyߦS9d0zstq%4ܢHDZ O[>d>aq8F>)ľ.x3-~|mKiRnefY\Q—}q2&'Qp^>Ɛ B2 =8byҥ5tPmqJAԺ*ɯ"wTZdAܙȼcugfS}ο;ބ)J]ǂxY5|tz$Ie#M4x@ݼ+D;` K{:jЙ|wTH-4).#4o.=I~=n@-MRcqB8Ɣ/ t/ D >qeaW@ 4!Rqh>a^ԃ0* +d)/]k/Fcb [cOd {]þhD=NHhcG`xCٳަ4ZWR2'_0ec vNkQW(YZa,EWDaX5BS3hKB"hw!}byhUX802?RrҬ{;6W?70YMGF]^OʓZMRf"*2_Q:͓2@,{|4;$|$O>bߣ!rOK ?"&C-~S E!mdCNO,,<]xD >ϽDVM>)<zU%+W *+p'}mh RJѹ5*W[!~#Z| >r2%QIYe.ݨM歍^Z=ۊtYk#b%P#W{LGߤOجu&+6j>%'IPc=鱀plw8(uI<.9P!c>ƀFiw6j$3z/)Ï㿗:q3ڴb9Z4(nB]e:j+(R#l G9S9Uz4fyJd-+&|h$KGsϽa{fȨ8Y_[Z1tSlz-\ԟƸ)g+(2HLAG`h~>wCv0M#4f|S #)t4y6Yd\H-SzRw-rh3F4x2gGDn`kkˍlsa7/4crMПͥCjP*Еȅ6?w)ho"d<ϟ<}ʱ¸Ql%lIh8-khhS\քXZq]#UF)p|5%VAoZ9Z˭|]'ct6ee,0@ xcl<c,lGVZh9Wc\,&Å.M))]AMl> ~HBö07_ AzCf tDzBxLYB.t)|N F,)9VJulŬ0,6&c`5xT h>:o bg@.j;fDX/{`pC4vaKYߡ{Oj&t;  ڙ}ɢI(v)Y6.ś!.K>D񂩔FxBO;3uF9٭.=_u56yI xMޭ~fqbŶv{:njS 8,TxFY{D,ĹtDzՙ΂)_CGT£dsRqthsDg60 Ko7/x{)M6}+.ݒU>msreLK7r|N6#fsh?z es|a1{5{kwbjKV ʩ'n1 ȯ/5-'S;HGr' r&!͵IC2Ϝpً',?>{#CXBi.icov!Enۯ/I7G KOƵ5;sD;: y)1E%t"{\_]ZbqP7~^ՏhId/O.uIMB'|Th].0w6zRXםmtO(r\a/3c_,5f;yVgD3 qx7y^l=iYm*^gsed37g/J'e9wur&~5V>7xT=} B{ҭv:4S{{^aO~zԁY6SV!s2_N7TdNOģI靌o`"xZ_e|FK'Wлf״p:aP ,폑#xOcMPOkYZ_~hs2?c{dX._(|:ᒉ;*+үCg2],~.A1Qjt2GPfPUP1fe-d]gؐal3x2Wr!ޤ4mğr?;*7V/ms =jqYR|)ɘcfm8s|=_?Zb89R36Ӈj+wbmz*m[jYEC,~䇞V0-y`^%r2:\5b =DRhMAں4}'Ucu>*]lb)gse}5o$.͙)+r5[*t$_i4mud682ZyBR+.+ӟglÄR(>[9}]NxJb":&ߡV>g8(/HО|E_h 또B4+ ] zI/ǃbpfĂƵ- ERe:s}8Je޹j("%{KK(+;%*IFC{G"E~O?zqsu_ystc翽hr]a\;1r$2T >sټ F.18i=O ȿV1Z(aF QX`/?eZOgl`$OOQRVjc)}l;CןX_Iؙ941",hWqس~vy-'vp43_z3i=ȗ>*YQD}uv(.b͑y ~[o vHi]6qw9TET"ĶVk-gnD+]xI٘#07ۊ7[^42F҃H}R $=g!T_#qk.DsP^.% p>4Aa ,xc20dhkH(9Cd*)o:7~} cK3&ב@vV@.[mʢ>m*~Q#g>p*4x=Wby:w$i;?\7]\NdSV'*TvKةsei5FK;jc: navgkKw5±16 =]\Ên1S:= I: i~I[v V*a:gx87cYH0I {'lO+,wJ7q'_o/)mnN!qCt[V`Ho=)Y"zܝM<^g>az5kSg54iO AZNYb!(2׬[{5;a<` ţ)Ƙ|fݲ^濼ȎgNgEt6FVүMu6I)j dТ<qb?;6 f>6e(s4N kU﯍_r<3ITU¶!x1Ţv?{aʨYv.Q+w" 3M0 de$/*Oܣݮz|,y[hn)F92ǗYڿbm_$ƥQg/;QW~/ɋaA=/SCtK%,*"$.7saTȱi~b^MLhgdrhZctgfi]%;Cw > El˓;Bbg!{!8/OP5=:!rB?qF!.B$tQLCEhV d2qDFRF 5Y1TV>Ьߛ1;C'W[UZ%=c,M/ƌZz_ h߯;}Uk&KlW[&U(>pZa4<ѨcYX"mHIE\\ +Dx{ x[0>ivt2SWqz4$a Q' %^UhLd'E 7ݹ/_;و>Zz{4n,H5ز6^ǒLqj ^$ Yvf8ذw H*t{6dEPE>IfǁhYqޯWj*ΣjIRheI3`tFAedtrl̻By1K ͆¡غ(3"w/ciV>ͯ WE`gfd'MfF])GBz\tgn^G+ &"kk> 2$d#LWTQwRwжRQqX7Cc}_@[f/i;$oeG(ץOzN!OeV=tV 4=:nEcBNZ,D#`B͂ej}^0y: *1-+T^%GiH_$9%+g>?BBOY$^WȹP][v}MQk&o*[Y}ZCpk2Di".v|=Դxj[*Fr3f-xp5z+Z6(%r89F?( ԟL0 ҄ >&-"] b"; + =j%V&ehtp >{KJu?ה8]4}_VHu#k/!r;dDO?gr3XG7iOdתhe:Z |/.ޜFJ[]g)44O{L瞞(*G,9"UYlny}?Ss8|c[YT$&`?4B /SR1Bڇ̃\8xa&O,xiz6s-/H c9mb@\ @w6{bi1#IC8cRkVƯ1bTx,|dw\k)| ()(X$J.ѯsW$iӬot5#?QGo}e{!S,66 WTʱ>u(.,5h5̇E늨UZielڬ}_e)N6[U˸VqNͥUְFڪ0c7R~mϦ+Ѣ,e:^ߢoH[[Lb[s8)FPGptg`](-mFQH^1%):js5Bsx@?ݡOQm94&G]y򀿇B}j~V)ev+q-ĬcXTνS䍖̄66k %8a@]I}V 1xߖ WK+nû=P8mhLX64F^/qrEٗLY+۪ Vc7QΒL^QJiL/3B,y\_|2/.{T4Y=dG)wY+]mߒK\UdC&';AK]8NG\ J K\1/2 u$g\hwrېDnVqt[IHT\A a}-g낸WMJ/Jhտ=Sj sr.: B:F X5u7L2HDz>xmTKZm1Ԗ }Ua ].ЁODQؓ1(1iatF A<S}ߘ>a E?Ӗ_lӋ>ZJ`) kb][؎%pSG!ofvjvo:ߤ4K((9}bEnr,%-K[FzrҮljgvR),AcΎLzC(JTuN?whI55SB.%n*ÁM&=g&[v*[0=w𱸞rg _g&x &bً(M^?BVzh=-~Ptxh֛I ~Z^7‡QaIJ=#it aUb%~3mƹ8dR C๲=gũ3<RcTn+35Y ;`^q4lxM'Ki€92Uxͻj2括h3|NNCS~ۓE9t҉ݲFZb:K82 (J pw= a&h٥à},'hd/^R׸t?vvu=0d'kd?/L KT]GQ)WOEo >IP>g~FXD^~1M͕l>3O-ulI*rwD nu9!>C+0E~uq]2=, X9\{X)S'q_D0:'Bv3x]N; =yM#x8K56"M?$ d Mx-uWrQ&½%Va}>n6DݡU4'x@056Px3f(;5k} l>8 iZQ>l xaO*|n2gtqG<:VƌԮ]T$dS*H}v!WGEGal:Y8( ƛRyd!Jƣ `/ GCA&{#/k}z6n\Y{9`Ņ)X"{lGz3/d1 2@A^x^6#z˜ʓlg6v0>o_ثkٙ(>nB=׏Ѽs?ɲ4RzN?Dc3bJ:I6KUd -\;kͶU2>Ht3f8l-jz #Lx /\i^ aP}=5}*^bRe1#TXxco'dcq怏ks)qiXG810٩? 8}م]J BW(./aЧdwbJz獃3#ܑE>Fa>}g'U?򺟂 @Hmѡ~<޾Ձr$H }i` mHs|8F;~$sRKs[56VT1PJC{S)]"E8 U/%kؐe̙Y+IHWXrZ>nP@lEJ*E5Y(/cC0yoZJ5qZpz1cݱ"o;t97~lRqHdT!$o/܊EGpu-ƎBk{hL0 Ewȇ!R\(kp7ڦ vfh8sẀ<)uzpf*oXw(U=TC=J?s}kJ| եh1ڋ14bEzSM/ȹ< pJc `\ 1Fm0 mcPRk VXzw .yrp U^f1#[~6]ʮƲаGU9r`[+iC ڲ惔{(߾!hUY;$YubQR<5 <0{8;3Ջ,gS|ũ,3Ps /XGq9s*T&MEE\wReO1%;MNq5ZaPha1 ž4>{(tO7^%f -Y 4l>{'q Xp.'(+{dg%"g7js?j&Qt|sVGģR4H. |'h~<=:Kc?G1{].p \-0h>1ߪ`]rF }kMy0+Ǟm8YWS%苫carxxmijy+!R<む(r3Avv}LFzw7vܝjuXWlVC nClV4ldZpr~SaBр'0e:(mx25%/H9“rٴ8ܻ ;*+UdE33rz&b/ q!sІ@3RXj]0=TX4F`0br2W+[YuǶ! C@qwpG3#,nܚ)t;Ԋc\NwCU1N2HŒPXcg#stP>3P/}==w.`z$ ݃y3$ZшhR'[C7 V =ғ4H#EuI{}N/Z>v'ިsswؿolZ뙱m|#-զg1o*ޏ0w}Q{x~sP.&Lg.8^K[>քߞ8znΜ*¢κS1u=s6PN PlG~, Oëܻ D ~(|ݏ45ί'q4 =vݬ e pK >m.<2C=p|NDn`%+ڟx;ٜdj ~qAOгtr~HA)ϣާ"H*R;rBfVRӴaZ34eʤ]uH#aSbV\2OLT,m^0{ -?MiӐg!u 7Mx3l2Ɩ`3Ey0\=3s4Faz+?Yőo,z6u1pHbemYk ]Q|Ŏk<,lJ <[/O9ŤBPiTՉ=4o}wHS<yqP~,F;are0 ]1wfN Bv# 6p*jǮ6x.TYC3'ҐbJUa/^sv{wt-!bh\<b4H)'J(QjQIX@O.q-Hrp"QFL)^F.f>[pt<|H}f\+XI'En?%"5k0{\qi ZMR?dx㳩 S7bZ-170q>h f_…Q q.Rt@C_chI-pF6tEvK;S-ncffYvZos|,&I:sчl cZ./8p27خEB[1v,"gG4LwVj?+ю*j.;ܫ&RqO8rne4(H٧HxtKVr^Ljs_*U;)߱?[Pc~W򼳛&\*L}2;&6TD&ɢ76Y'! f/DM(ŰqǍHz<E;D%crXiZǢcYlT J4r c5.Yj6P|g{20([OMXtRKU+?VL ;׉ו u›ZCӌ| L¼!L E9 N %qSEO0F3vNz1q&~I^w?&>p>Cq5z.=?Iv Mm{D9Y|ޠ8|SNe F;;)%e?%Hi<cIr:?N!!>HLT:򨱐Fs&RdpVӅKu n"V:"mTI\G&6'@ rV?{ph*O??8[-SۋlZmp¬ k7u戨9> S3 L§#3pUXg 3tW$~Je͢8{2[5Ozq/ m]U_/Љ4Y5UҢWhU9.UPO74R(< zv=;FZwё (4EZ5IEnii:f>û"7T7Xr;:(?wz"X! 笕2HSn5!3W"Fv >0o_ /pL,|0uQI~i-ѰBcP*58㘣Elx^s` vgQ+DŽ #eclX".ð:sKZ=z4M8b WKd3dU,Pi p>IO*4G&)$1>BsfVRrӑ֋vߦуөiAZo7[O(Z ܂PQu/ ]UsiV*4S-Y{ 4pކ]sQұk*,6 36A, cE$֟P-<1!8c-ozO2Zx#EgH<4.ae@H -a2ӑ?p0-1c1nwY#!^urQpg:}惓c&~WƔp`1vx*a%gnKIdpyV0J;6 HI;]Bb')"ݡD3}>O2BG)upX}b iL?@O'רnvU8 :9LrK mqndqv1"0;G5Ŷkx.\4nix"#bN#C"n`PFzG./Ńrola{X)iA S0P7hc{)Lrc6t)8s@hĉn%L'@5qF(_ aߧ_MI?cٿwmp#rdQuByim4}ZL/Dr\jXJ~Tǡqsiy6J m*JV&NT]l(Moス/BS T)a7G.GT{B3씍PˁY(?oL?rXsR*f C=I$B!B,,6O"=,{l>Y8I#YB ro{>& <ֺ`>o,̫ࡵ-jd] P;Œ|8 RLu ݡ$/$[ed޻NLoNкױkz6}͡ï_kQ&{ZGyb)Z9AEgh :8%-*Li\% 2B3E_|1}ZU&`-&m޿[ I {5Qc)sdOUk],'Ҹ?5PsbE࢜CLeБXEp"`D"n}8i5jTkRlҾeGK$b تϹaK/s^~Lט4dc/6尠"{Ƽ]/RW^Ǩ5k7KJ^A.pH+*}k`Xʢ4N y PAÀL#0ׁ;nYê}'O|#$â!e^1y7V)lV&hug׫h~}(EE` @Hr$vYTTi@0X W8ۧ#; rͶAM8m As `ws$D@s1>yWs$ a~8MiK~e]W~6^]an4<)ߝ/+WqV4s1wPU W,Lb:2uxkzPF*gw@rDq~XOm-N:!x<2C[! qUP-,]e6@n!!{U@Sf/R8J§xe{32F:R΀rh"!h {u,s@5{EaYs^~C|<뙛C)QK^ܢE7tZ1%;_,?E6Z"SO yd-7)`66E2MwhS |_^2N?z[½hӹy8q^[=bjH؇3#F#Vk[`AR̶ut$:#Z y|Yncs4  B!i, T'` Io+%Ü!(#G2XzW~^KN &(P7#m =ʡr^dČWתh6|%0Rq``b6 x*I)D$2!{%hKKK{=KKJ%{=S?W8:븤߆rZ%a=,*SHnDtXrL;pi%ƿ:Cy4A[ 99޸Z _oJ:-sıMX9S:p iBPEd(CV5X6Jγ>p3Relk6~$x͛'[`k%^d%7를fHfYXhO9l=\tXxi~} e?쳼3GJKj9JK-Ox51f Y);7Hs.84kޮ cw[#HVS("Qϓ6_ߧbwmGm?Q Y$FZTC_pl_ܩP۞D|3;xt8j¯(}Y;B0` =>;L4ܸϥCjAg)/t9d!/vжRJ$zG}0~y?ys;-oZTYzޑB6;3d{A3<Ëzy99^\'3rCivUVy>ߍv2r|xcoֱb)}Cm`y/iFtxi3>d~)ҝ\) gT`a4HlL5ҏ2m 蕀!޷pS'AJPvGw<h@r |(CB?eA0B}KzDiI.pYrBE0$uBqp[<`{i`SL6"|^:TKwhҞ&n3! x{&8pHgЙyzk,Z(%'1]3e`J|JOb=yffYKv}/[=^U/c)\߃^ n U:WIY I5D_KOߍFJ*i[.h>ﮠ{n8rw'); |N)1T=A03_CQudd.G6:|S]-k_d*$_6Q`U#CdIY%Xe ߘ tWIҸ>AAU3OWZ{%WTbN+ 7.Ø7oԌ9VOڧk舊:cxb$>x<\9oY5 e,^巄 SЉGRKukܔO! i ENlZ\t@` u!GoZ¥B_sN+woŠ oRbRE2ϳWIRsKUÀʳg}&`)|+ٲl33d1]*>Oujw =hr1~c4v^' $ޑY |̺ H9#KԮ[?$F`Mܣӱ[ E 4 cZM:"j0!dL9/wUmE[t 6oqkbxw 4=\́jcOhlFu O.{33O9ӄ G+=A[h|6Yxj5~4?iO'#lpא_ nYKyP&%NUEP[ymhg8lT7,:p]؋4NNvQɵ7W xB> )G%%qntTu]ɽ-*"DŽy&,e+`萍^u^eJAxk+|*B8gy)KF2 M;~ْGA OٹȚZYh6EEqޖ~|yԫ|ŌhrNYƩMx[uo or斊!Æ I] y9w1Xsϫ4s.|OQ49)L~M ɾ#Mc.ׂx/Xԟx"/AҡFg>7En:〈 п.5 [fu@CG?Unvr{TQش%r8 ?!9 -XW-pP%Q!^h]}KW:b3pTV"q5sr ,:X m(׻s۷h&Ʉ]rMvN8E,L; `K z~ZǓ6\kks0;'^Vyɨ\ޛOt_Sy ~֯RG2؇7Np+)s}?lȮ5xuRg~ZRq3yF' P,o *P#;.N߽Ѫ~]-:ywbs)ak hLu єVuh7jJNG /߾íRl.cp4C[|6UM ~r^(jJ?98mڕ5Rh];R~ Hs^?W&hըlq= Mʯ]Gw~N{__k1Gc܍復 cr eۅ;HgiE0xwx_:zԖt/M}qЭKzKjP5A4}ioP>tT 8 q&Qސѭ@Y7勲=ChO0tѧkf >*I?/K Zl O4^]` yk#~X#0>u6q =zEbM\+3.Rťl=Y&aYuWOڡ8]{dK\6v,_a&_8??k(ʞf&.ɫLt鑔"0/;p.aTmP*DE8tSdP<-:bӤ*t=ۯ53X#[rQl*;o?#n%X݋F>Ҵu)K}*uOPP4ayٶn ty ]_Jb6ӝ֑eү%_a7TbcІtڊO8ߚ)pyrYd 0m%|жB[5#C >D9*ꗂڏq^pf $s`w얅8"m]_K@ tR˅ePh7;~겙S .禵41ǭ$}":Ѻ(kVO:"CivlʑU9v7c9k:_s5B,k&O*rƆn\7?ãfޛ5+u,wQxq4MC5U} <4­w+Iz&_tG}n>43bYS1tϥ a{*&?XxZ>1etL^,F*J<ݟҍ^誒#K6)A?b)\Oy35:>B,^ Q C31 p`2V:Ű^XՋr]' }7?,=K)t: ״!׍+:c4U Ic\w Gbt\hl,w w˖q㽁Ñ zlIXSLw pIdnOvxE$94!U0I ޙHނ^l$ʏZOp;>8&tF VЃ@ˋ"w}jD`Y;qkNϋxⴑGōi0exz>ɆPP"Hzj@K vr(ZޕgѼۨnR;G4< rq"c; iӄkwBią?Iƶ!x?-6!)x(27EF:{_HQ?w|:UZw>LEȨ:8cݓ8$jQ}rCKYhYK85%X<z+Łm~+~sY +8fpիy ܮAdԬ)O]\A%й1G:5 C}.[܂W-^ vEz8愋R]ԄJdz%ΣUbX>7҉f?4%8]"~vETM,1K ^='`zF`<~T q(x-8pZƆ7W<ֳЩzCmeۘ= j$d>E^S}< w>q\ֈp|Ty.[h?v~@d?=O#ݔ;G. ea*>;\ZfMoKmD9aYz{Փ6Cqр]UGB5o[T }ϻӣ<7k‹V$8!q#/R븶Qxaxlnw 1D3 zq zEޢ(lmn O!p(=lop4v}3J)CbC* c}Q]Ö>_Rփkxqy)%sb!-F9 bPYɐh=1/ZQὲNY ݼ7H[DFj\(("uk2ŠM"x\v+uǪ5$B7t u1݅!6T}$vv`{R$gCGjFӋ59{LohoZ<ޙ,uԤsQ>)xQosFh/RY/pF~C%6VEa<H+KH=hV'Q5=S ېUtoZy<IO-nRdʜ4ȈQ;.>^B wpœo[anDN7;>x+|cnu _8"T4ݿ{AcjX$BƼ84# c[,u"V"jWC)υ^8OKʅq;lKe׼hf4<]8\+0@:2cIG'KWS^'S3Q~d4WU!!Af Ѵxf TS0:aΞmxV./PqPWS:0nՏ;\bN~z<-彣1 r!aˏCP^@Z.Xz) o9Zcb rE/)'}J& ?~r#JXaڻht[ aQ.vx. 4m%L~]uamvo0kv Ad5I 儣[9]'fzYd~\+K1~ g jdajȜIh(ea[1 )[Rq4+eDt7زe(Gѓ_SdBmdN _SM\)_"54\<] &^nJ!]Y6S|iAU[ =~Xx O>nE#4\Bp߾FW[ !c##>C/Bdl W"~coJcbY,pLyWdXLqa[O|"~!x߃.SUw.Ɗн%'%qQMq~XAYMHLW9f *2Pړ\z 44 gz|ӏK_t7r]hѳ`Z%;lA6jOF~۟)%4#u\Lޓ)cLspG7l~R-5Y5 %iWF),VLh 8=[iPe)˚{-L=3FXV!o_R{G"xau3:jpQ6 RສS_8>. #hHM$6U O& ^UVB}J77Wҝ4 sN!Ŵ7uP^M59l7Vu=QpZg{f;:>z)pƆs+m{9Vw?[L#sxeP^ɯ.ͽHcc'),Tr+GgTl\Oq% f,G2sEqgF,O@ J/84~^~]MZ_#`4NE~"}6wE:vK8XH EmCr_Ex)s-9iz&(z/ܪ7Zxg5{c~ƤymEn;H ȯ1]H7[2OvnHǒ:FD>ǫG@#^5 1]q5 0e8^EN\ceSlGN,Vp.+r-< a/֊$D6Jðn}\Tv]lp{LYނ?gCp{PQw گqs~miEee6tm"&B|Ŝm|B!Սokk{.aM8G߀ݖ cV=Ř#Vpߑc)UTBzaInmAF[!oFU~Ж'}%8oXГ tZo_J⥼^ic;JӡFJSH3Gnb D _g^_=#*x/m P'xᓩ:o%,Lo :ccǼR +FhS(IX1uػpp*~#,qy|Nc"|>@.WhV8&^Ci ]is r7$x(o7t.;SBؕ꫓ zR'kntus3^!M0 Ah {0J,xGai,T(B?&.wJD Fl;OaITOJ¤5h: OL!ѰsNQ~ "gA? ~7:9nm1 kb-8M4b]"h'i3'iQDR>1e᳙Kژgpcf'SB?E|)k\@lIߛLWZr)J4s~n4#jzhױ>w&kfR@ H_vY4ɳ1u7؍Vnʡ%$XwP/慖ݨF^N BYvzXxXB1P'$7pګ'k7 uWs:]t%',O5 <6ܒNx$rÿ?d4Spg"6(#Pz@bTF7>hF7Ȝ}ܫW1%Xph%~ףg~81yŜ2s ݻ;R17UֽsդDRmȸɳ1zNƔZ1pTB&$]MhYΔV*̊.4{(=9_@+f7ey>&b,&f\xwO3+NР_C)$GBAApX7]3C*և #[]aq{G h> %Lse2ި.Ĥ'oazٷnK h6t=!";g7 (wv/Ed.,C ?^QWu"$Ch, /2៵yP4nȔsJiPb>m;L7Ql|FoVWviA"Wc?]HgS霑}鎍:‡6drJGD>:PҲyF׎ԓo)=D*4ڻzng UU3i8e2H)Cs'Dgu,7½-Rqo!v`t[l䍵bzpEo)*B~hޑӧ#L{r'=;#W习/Σ2ݧ'项+6]IK:^[8Qe)J"Gmg>" 4|Z#IREoIG}쩧7N25ƒUԶ(u]~v/ʹ[yA o˲qgS YZ0.M` W)/pL? ( !jWSq[L{n="y'AAlU2E ,"/kbLVs:\GH/x3G}?\OﰛNpq^ݖ5 } #i@z;\?OG7\Hien~0BGdqk u!Nq܃đW-a/QnjʸTIoɃzrwt,No ݞH'Է|3̦U.!`FN2"Y.˜7s#xb j /Y3EuU`D84tT6Lt \g/^  ѽ@9!VD:v^iI&wWX .xl' 8ݮcJEf Cs%ۘ(t(ChR*M_77Hbv_d߃bTbւ ~ZuO )!Ʌ)sʟl)ħ-J"rGܰN'}߃RH:ÏVl q(zYmT~1u~iVhǚ* %vQ\-v? [yq"Hb\^$i>*#U FBJZ=2.K+)4qg.ɛp$6GӐw '"W12_ Tdc$9%9e+Zf>݊+-KeSݧ냠p,ж3X4"tѷ& ~_gŝbm'vycL#Yl{}+nyX3& Eqoj֣)k(e3W*ߴ9Aq";~P/"F-[.ƣhN|zXsHu2Н>/s0-qPz'm. )s5lWm+{rI\/뮮taYCZ M,+hPS@ai|(7fjʲ<9k'ėZ6ި«Z(`:L1x%x$.(֣c\2B'a$6ġTlC< ^//=/}׷'S c 3({p|Y%v+ὓ%"~F (Dbz-::~Z +UQtoFJb:ӵ/oimKHʟut)A+H_Ca'z+A8=qg}\LtND90SŊ{{Cۯ89yW"rgg#įͶ@H Injg}UiHOO!(~,~s*o^}^%_xFx#7wh0I)"h䰎lR>֦*JgSe&rE&d6n J ƅk*~\{0G4vc5rr<t'~k5_]BwjS~~V_&wFUi|BS]M-T}Z A&/Ѳ^}eRYJƹV89jH=%\kc^KagsL–Iװ+v)֔e/t b$z$Y˳_d6r@]"PZL)/eNޏJ@]>&|?ufLKʬf26_>Y7x.GU:`}xZ2ۏiKf󻓣98Ҍ[G^C,u3=y5y~o?:6˃;pDiW?^uuyAqg|aϻFp4{OuءT\8ULO@:% Pt$ل: F&#} 7IXL=c@nnqCH#x/==\CatE 9X:S^Ow[>k/ q4) dO҂ )0d1yyiAQ"3^"͍60%._~Z{=5L<7 4NR]521TqN[mSOfnT.+Q or."pn=HDkbH<06`I>K9#v_p.ƪݹ,뙽xCE xp>}_OU*Ijڳ+?n5#8sfM7!ik9.Ҩ?$k6VRi%Is{ʸuPxpZ bC *-_DW!*A lYNi]yQC>NNY?2%NwǨ(R_FO!؅+8wW- ~%,Wvj%[T/}Vm3)̭&4 ReR DLƀ=k.R8 M׏=]`F8&U1C:j $&jD(80FC*QCotȩz!IW~p ֢O D e @L2e{W.j D*zZ>2\|_GMælVFq92rx HIjoVt*F5|ɳЇd̎bHiaK UU ooG1_L:ly6}-+E=mLޜV)+=嗦| ۗ$; o([)"iex*@ =Tp:1X^Artr@EЮx`Oj0 UE:j +?!eo`yKjst0̏6kps> 04tސ+BYͯq5EZHmWmʜ܁9Hqql23=p< l3dSKh%2*~u{ [3YqBnX^S{ToG4_sx4YST}.%K^-qy*5Cp{@i܏tJܩ/k a\W1z ^~8oU;! QxM6 *#LJQ9XF,)ưM'zYxy"6AIѥq/x{$ëz[xmn³_s9I)u2zKU#e($u\qnZl?QYS%Uy_e^Ka2/mԋ%6;ŕfk2of_-f9|6+ng3W\x)kR/=c>י7|~OQ%)g;kx Ϲ\w0M }$YҌウIoxdgYN2>,ι&"]u _te&yY4>_c8)\䠿 sǀ]琩n%Bag]!8 x@5@E瓆p7\~ĞhNDZ QoSp{,OI ѫV1s˕)=jNλ̴N)JN]ٶ2Nup7G7TQwQ,貇ϭ=xw/7 @A:a+|?ʿ+@#K]>|rr}iU[m)ξGٽޕ'Wm%I8= pR ꉕ<.vK c__\l%*9< bƢNUx3^N0Me(?ZɨJH(<TbL%b ^@p%:qFcHgm.\Y9HdZqAVFڣ]݇Zke9;KJTRZ)Tϕ&)Ide=HIIHJCFBe ;+OO>u]ss {~@uhht2"kckLqq*z#M8yK\ ok\1vWNX>aca܉uGPy!<mX4&-ΣëٟɣwLfB"f3T{atղM%tj)Sj' OmGitZqRoLt|Sr==,I$Ft|K%Շ4J 'yxfT WQe{<+p/+8^3^zO9Kw -[L;)SXٕ-jxz֕3<"s$1CoMѤ8>nH,&S`{,T9nl Z6F 8`˳z<8oXc H4`gNò `/*&a<^-b&´}b#"Hl-J]e*唺F-H'H" &%mVPM%㍜EaܛF*jM3mZ1-w,G RBV4 $pu>lTDu"6čDMTCSqх^>\F⊍#<WA г h;!GBK]5k8l 1*/`"9eV?XP? /[#&NG&MCG"~S@ #{^c[Yet.nCL 琺obtd"iMmUyn"*qVጱYy&D?7h=;in;A2R3 3-[_d1A_;!쳝6r?ɡ\$L 2z{3iզ"WRgT0BIإf?Km>5`) 7J=Q%z8q/мs</M{;+69 >Hꌷvu0ar~.]cᶕ'LyuT C/ܺ=k2ñqDpNY#`ƬbwL~-|x~sRu~~9hCuyte y~[-meB?CGhܟ=._y =X{"p{=,̡)>|l ߞK X !NYɐ虁u!fzHgq1ؚ5G<`x6 AUxJJ؊ko6J0% 5,1 l\mlh^`-A-d-.т~L=M4N̷kz,D?kbrf;=ZSoSCgYZQA޷Ȁ3x(dZ_"6m jYgߠGqkIާ)% C{iz!eۨ)#/V.N=w)DFs-{ omqp!ߎ®xt.|~Ƕ}v?/{0~w4̡=/ئSY&g%lF/ZhCq>%Eҫ9T'#|!iB2+B+nP, OSIN1\Fy+g\Ia7C-,>J7>:LndQCkM(>ukB?*Njش{>o{;xkXSuz\7q8g %8B;' ؿG9V`B ^s Vw=wu c|/C## mЪCۭ-a/Rq2ּCV"쳡7yG6mwŴZhx<kYt͢mm,gPez-)?ʡN)6;igTv[6 )Sτ2z3l*r ]O+ܿkTuԊbޓ $W߃}hUxp'?"矡yPR +r Y} }5Csoq-+1,X [$+{(ʠc04QCЀ*ϧ1a0!a4ŜF(5>e2Xg4mv˶hM8Plp o{|2 i^\O38ޡ'T-*VU B"^=$=gŐRRt.x[kv#:r:ԧ\+HegR{$l}lJۏlN(1 ;6|D[iiVDgT|6WѹJxts X[yVs xkQQ5z҇B/46(BVWVt+O)X?_G)p4`PR;8s]6?wBXt曗#lt-| ެB6ZnqXzVg'[8uQtܐ)C{3鈖:{7wb۫.\]4Y+=VHԉu:( 4>ϧ79+ܡQ tHe!K?cc],BSxO cDL@MNjL816gLq KAE06$}hU2חK!a. OkL#%13wR\k8}zI"SP'!(OV>&e &ǵJ Yr4qw0b{xj6 (,ߋAEq- U" c JL0 1: |O=RY[J^A efE}lǔ.ݻNen̊LzԓJG^EU7F+'I[SmPJZD:aC͚cdcJSa6,[עu^";j['[a<eeQ ԠeŊ6TV%Տܷ~JNJoOg zrͷ(u(Miۥ rgd!ΓP{ 4|{-MEWqV( rC1$'y2] ^2>݅d7iaQ<:.>EIYcJU pi(rncJRBHLO ޲&81ʣ lgΐZ!qdr2JS~֛_@/KTDL9θB",sz]^i.?Yhf=$z{q_8_E c_ķYT8|[`yx vy`)I/oi9{Mc_aC Lo~Gq6wh}f;Qe;%EAPsO˱Wo0D݋VS߄D.J" ܫOӴ%QU^)嘴PPp5f*iϚ.I2SKa]ņXMf#VطI7PP  4Dkvkwf7-Zj6'<Ͳi5cFs(MU@m OֿULEy d+K!JDxhb̿{$ 胧{faڵ0u *GՉHNv " O_&uV KRbRebZpLmٟOF5%ŔqhV4R@"^4aϐT m$o|Tvۘң6T@ֽOm.Eُ0_pt0W_cw.fmWFg%-fxX2W،/&% kc-9Gߥ":)fvB` ,u%0e6\4`V6&cU IYN|{rG*Ecˬq@ZZoi+yh2Dk$4 +*] GN vUıCy ϪB]/#b?#>OKz/9v(Nf]&{)lj :MrdYR*SvG:1?ZrauD` ([w'ynݟv/XkOr{ Ci?v>J5GەѸS&?9)nX۠U;A#{P/ Ao íRHtYg$e^ρT_O vhS+m +?YYIME*}c[YB2go{gA81ߵ:n?.̃ΐAhxKͺ/hSeQL&Q!fc2BJ皊U(>t3Q&9̸M4(Lj4CsDVcIWNgux3g,zIeQdaAYGoá]$ +٘qKj Xb[cZg,!4aIc,2H~;Z(=\ͮx 3{m/dд &INJDwlA<=W>&&Zqܰd l wnw1Α_y6 ë hg! cVNH_7߾o΀(`سl4uu!1eqh2| v_KCV5s΁wt>%9`yWvU~>|M/ҴէyE/:jdw9#$M;ސJY&gTAmri=rV-A FIC,֙cH Ő^2ׅ~tBn#qx/κ.( @'6Zb+ngP2 1SEu'٫oLiw ~fW`Xol~#…O5+xdu/rmaa6?{[8Ĭ;'07mΈK5s.tMk:|>Mf=Öӵhݔݸ9u#0'-539>0mT/[skf;ӝ%Ude׸ 7ʎԼ(GhFdb+:X{1w$k`*nGbqXL|C~,$1YWV+sBK30l}g+}D[vj+G&)#~gX;ȤD& oy+慠<~2kb <zsx 4\6ad\Aɑ-gX"-ˤ0Ai]aG;`1#d'AKR dK8'[\OLe3syƽ L'-|>_Њ?ǝA ùN OwVM1 A=nX9~~(>Yb\na\m2μS~kGF@nn*ai \YeYf@$]]ov2 ;8WնxigfO_}ԤLrP4mX>@Y뿉*ඟ r& Y4.,ĉ>\^s++buέXl^@ǬLZ$Xs'{a'BpX".-yy(u΂4{a)E Iב味d}a6(\*_ 9gCҜrqH.ܮ()Omg8K.k1/|"gCU)PY'#j$Ӕ17)/P~ ,Gf0愿gqw7fin>aj:?ex<vv^ +^؏,QB<Bj`xf3zi[FCɆ_g nRJ19s1@]y&ooN}{~n5Xr8Nz<zcy8hV\;>K?ό>G:Xo h7F+M<Sȹ5G?o y|;v]4l\&fi6*aޑ5%\5t a؅Y{k8>p9K\Rf^;Ұ3{MS^n~dc IdO&y1USW]lH;fs^1| 8f AQ'`3#Q<^vu7HdX-+01D-)b0` J47)K?u ;x=Y[ tK3 x{xsm9I;RX_:Caw4ͲoFp~3?J_Y&²ɽr[:>,]_ݯ=4^\Jz`2gQfVи ;nr a+Qq_47p7s 3™zG kt Us8Ą{6Mİʷe;}d$`6UOz0BWbXOgYD^’6?dڙyO"-+$G4sa0w0,YԂI)ceDkhAܖP) b.<L)֡Oq !^( GXFs08:6Mcg`B `B K?1Ӄ`,KIζPb=s֎g Nbk8> rYOLc|k8L?ca୆Š+fxW#t8z!!g@2Cox95+z ?wDl/׳ kg0!K(nn$&V\O^!l1g~H)OJxߤUk=Hܢ+V/ml͘1ޓ*fA^ XrLp`l7Ølk Â_~sa3 bg8,AXk_Ap:vą3ڊ>6F Z0catRd9Er &g|nsYn's{Sk*YiXb}VZ6;˴7`5]lܬ3COZ#g ΩX>ݺ'Xh폍qaNj)(>ajٹ~lj7 0d{PFS+IHf9Z$̮mV`=˽}TcGIªF**,<vS!YZx6ǡ/ 6nJ4twEa8lͦޯ OAw/ e8ϱZH =v QƟ@ȑY®aS`A0l.0/%ȳi3Sk]qv[mSulaK/fk`2[108XqfY4u5Ms6S y:< c 陋hcIؓkv=`)լ?S+ۡ\8gI[JB12*Dq:/́rm:f"j.r~̦ u#Jc/D""a?CDG]sFr|XH5vWa WW> |0\uHY "hsǨ)!y^f'&!:g}nk8- Eb3Vj-)J$ H|yXs?zw »q@h@"\,c$oҸ;P>k<0"hBw*>feTV硿y mt(һ؟kg`s;#S\̠jNh,m72il.)(ާbwc 7JҞP5ObGٻ#Ē 9 틕Nk̒.W϶}uv&6R\[MB34>Mucj7=:tsGM>{2=Fo,Ǔ4U.eo9a5 CY܄Fsϳ軗C82 \S.FDx ӵ9SAW`e_TJv(: D[@nXκ)+ɘ\֥T':dFxp洀$,3 _ci~B֖=\yVDL{@J\o-0k5`]|'C,;41] %4H=gǯdxkŴ,Owv\z/DdY!t2鉞a'i~ƔyH6iؽ0 FlCOq[[Ocr4q39=t)h,υH3b ĥ-8/OqmȂHGgCh1icHM ?$.pJ,ngr3 q(=j.ܰEL'adb*T!{^7d0Z+ sP&{b>k4ʈ.E/I*0)y+EVKjW@aD1YXWE,֢}xT$Mfm!|dded4^{%Pd( ٳ{9s><\ܛo㙹xqN'b_$^EզBvK~Ep_6I"z7$w}ںjDʘ$T ,>pSf7h8!/.7xɚ"D6>}I襂릲1m]j{fx;'\ÚÅ׫ _,X7k?L$Lo]:/5J* %5o@vP6CI򼆿>; M_4Pd`7 ~wQpKw٫Fwug)$) rsF|1k4q^9c&DT' {uCHT#p4^{ T?A#.E\(|B;'yu]-*Mf'D^\]Wns֊-Xa/ލ˟*m=N'ǿ~ŝgz j؞y{⽢V\Utv4`͡6-h&+U2[Ni)-BCWZO஬uYk[;W2dݓ;JY.]NoƳȽ$uqN֌QSFGڭIZ J3x_L/+P\LC59RZho]yު|th#&#{J4`^k(ܿG'oL'Gcgp7YAk w7W5d%=[q!=5z񝐱|#ÄGo*46MH},ו5|nˮ_9"՞T\_V,#`M~?1HnoQY\/X\Ky7x4.N9L;8,ዓ^m9e#od-u4N|ҽ;w6*2;<7p9%Syuc_|cV YIƒl9<>6ȹiu _yOr'PN n?v\E7Gl oM!KаHxs-T\BLfRwiWu^`IO[pbI5Gbt-B׻ΈɖjU@7 (}k1ԓ%-3|j8WY#nGN]֖=xm"q{xFUnv pq??:&CX*蠮_j&`tIMddtw8RJFk1w7Z $0FY?;~`^Xƒ0oCPgpAd,Wt1UD˳,?,3#`ꟄwnFQc7aU-XW?~V.q(бT:*,<ɿ; Oat=NB;~DB2ވO ?^9[GgX/˗\ES^>.Ϳc:qơQ,;r:f`P}l4<^g39__n⾞,JXaT>~D HVwBVdWiF:O?Ic^گǯiCZmr蕼rNv@.Ӫ皡vڔ!# iU҇o+t;Α^WO !0T#ؑsv'ZI"jcM B fάء 3EIEQK &ϸutY!$^x5l^?pn~ӕG672zZϋ8>9^л~ T7WX^f> ǣx ãI_J!=뚐6t3-,kýE&rv8!3s񹟜Ek/cF}8lJXXL/_53&y%u9dnk6p".bu'({4c78J'Py=X'?}$فw̼vq|s\~Fa,%ڹ:cjZxUPX2e8Ӆ">6-W+(ҬUnO&͔;C%G\ף^#ȏJﺞWE' mSw6͡4-9C]5RwN%%aBQ #p3*B0e"Q/Fxv.oaew^4gkJ:~? W߳0C<ͱx`vGUj|3 0|}dawS%n-ɻslVdł/6{KS?|aXq7Ѽuou莽y{W->h~|‡47I<(݀_(,^<#m||W~o~iz+&v:a9e{ӝɲ]yڽT{/6ٿd]eLH:NQ(lAMػ+KR*rBC:p'SCO iZyS.lB** 6Qe.@1|'8[pC(hc:la@gЛp$ÜMUlWx /E@Q 6-gtf]V56 mJ?}~G2>ɑXwn:um$9*jGdиФf!LW?)/}ꑆ ]w|_To.$E\)tINlH?<=0G(\.m> Ȟ{3`$c㙅2abݫKQc&A-N.O{ZbK^qm_œix4Ъz!sQq-kOg O^s~S瓎}/ZV ;]I'[y@R~= E `QpkM.eV G>Rm2B%#+vu?@oh. WZ<1jI3GP);P҂ĀpG[U'RxO.P6_%S!e>h\ʁ5N|LX,js ۦ_ŧ9Lцk"Z|"?$??G+-VTalcv]/;;zNSYy^̯ve8KC- $8պ/۽3 -7q#"n< qMɘ/|vt<=a؛۾Fb! 31~¿жJEOV,KŝoW40/ŒH[WQh o, j< ipRpp㦾Ѭb<_?O*>F=?ZNsV~;Ks{4weev{y7=p'M3+_o;Wչ2p9erGX+:p),U =otŃP*YMLXu ZF(mi?rg.+^A7`^3[bA*@xlUMEzIl҄GNzY0zZ:ܓW؉%pbBd"nT1(yR1,ѷ.gP#݉.MGWgLuV_ecޱ4yĞ_@CZ4,vթ;!bqȭ+:ͅ>L=sh&K9k%hq~c@nA{ |'ՁxņIC"rq({^Of32t|ٓ"cca=}XBe(nV'}Ae[Rcv|]c|W/D{b%}nGkH 20{:F  O AԠP{9`$˩j& \o ʬжAenYm}H*߿#+ 7yBM"r>'ct4Ny\B)zMnlSuy  <>ቩ"D`eBh\>(>NEWp='53Uw\2L̨کmk[ $GBF'+QeҀa+o⇴}}k޺s_yͺO#'S~013Ә% 9VѴ4_#t†䩵4n]җ~24d 31jH6 ա5|q=>GSKE'N4:Qw>Ǖ\Ցh7{ 3Yy;KQfX^ 5?s%MĆX)S 7eb!7Fhz\+c0Ԉ ߼M( WU掞ɶ tP1nY=k#/A/P<=r0ƏxHk'|Z|_*>ƒNIQHj$Y[Q* JϼN^ ˳₊6T&jƟ 67:ѧ 7Z(n;(x~*P_f4n94 a/Gs>,VZRF)/z/28#s?"qz}b`( hEB>kQ=\Di\G|?4 C%=w\ j^D=M"bpo>Ud"]; rCD j8wX5޹1uV)V p,$1fq%l~ t=PZ)Lяܳa[˿cC9zq҂Gt!S| >F)NtU:8N:z⏛RWVpL?ŚQT|D[)É[3,*PunAA"|SvW[mbekEn?ބN FLM1ܾkRE]N{DgoČQqޙ я067a&kFp!>ZbnM/!0Ũ-@ltn+.qh2mtSE͠l IG V!x$VWb^Ědk7vW{ E `mTgҹ$E.>amZՍ 3E~Mx1V5+ib%R<{ZTze.%J%Ed~h(;6bzQ竡ȋǦ "BR)Å6x 鰭 $F 0*guR29q q.DtMߪ8daϹv]jvVbTAԍA5 L[s:/`zb/hĉɨsK~G_`g<ϋ O 朏 2/b9 ^4ƻSX0?:/0.)KS s'zk5qdq'A 渁4bzm!}<hj绗VMJ(rGJJ/;QI"#w tz܂ZsP7Id gHMGQz8 7prKrwgbb`;t[}Om} 7"vlJ.B/L떭h ʼn28[AeQ.BmxLhR'@)<\[g, gT%}$1Wkxt7`سx48 % r5FI?|āMWg4 ow/E˟N]{|Քe%>PA=HY 0MHM&i 7K2NjZRMțNdߟϖ"3)dnG: y-9.Er&P}lmn "w=y9Eltt!0ij$] jP/xgXd~FlG9-lӧ&4ۂQǛv%(9Ñ:& .tq" }uCTᕞ}!#0?o<5+a拌/.m`L߾jy/{ c!՚޳4,q&#H <b;WeXLDۼw]^~wf1$$V K붫P\jMf'MN xB?ۃooł; A<^NH?34z>wxn,[+ gCGqd(]iBgҟ*C*+;Fr\\|Ay'd\۾'cVopp *%c_^C~~at\Yn?^ɷ,1w-ZPY&8HpXV KC׎ٸ,qcC>/P~AT.#rt9ټXsdkbyoAߞȾv!ھb̡{ P3G?,[VͣCI_W&cО48ɣV^c0[̟Yr"39}3Vxa^Fu~Ud8 }1q-4NGt9')q}r(^\EE&^BQ-Yw*]/w\I>O1 k*spsd[/%%0ra4LՂͧм8+q}#JXLAzIJ`sOdV(Ƅc}wlp$?Lq&'Gar=&jBecLe~ϵ`,'{S/w,zq.֙k\8+)g5| >GSf7݊g-`K N~4x(y;-FCLWA/)>v >N!+Y&n_.;x)o:qOVXGa_%. mOoSĨ^7y\APn£tg[p_mx7a+BhqhwEKQ`v}0?mUrQcu"ρ_[̈́l{Uy^86 '?{^LD}>FS0q\C7Af x b Ok2D٘V,|UMؿ)C"b ZZnFի&jvF֎򰢯"U7oMde;gja vhʹW&@zQh.[LGwe_5V23{g $ͻ$^D79_Й#y>V<\y 4nj-t8/NY`/7-"A݂q) [C`XIYoDȴ?U<[)S{m}jh8v]ۮ~Z!LTc,6hemw N!an.>X7S/j>Ox¦nX5Jn1Cs~ ^XCn@y<foQ)K~N/)Ka"/[0@h7͙JEmL=HyUд4/|ԁepv,oWR''ܠy4+먷V5@oxv>n͆/lAK\ 1јG 7S&& w-mas.%L#^ ?q7Vx|:eho? fPU,,^'*8#Y1_ &W=W)S7ܿzc JYL +vW jMܿ"_Da1.}$\D/&מԸw~ʓwᮟV휁֖m%_>%4Qs>"GRFE:"ufBvQCha,~$ݣh%CbAH[6E&ȧ—+ȶ?*ٔB[{lyd7Jx*4Ms)h{pNsdVDXt 8G(f d<]$_# f@h`4qYX"_^}7YX3KUsرwDse[)O1>o~0Dol?6t)bq*mMZ6fi|s꙰Fx_IݛX lN|iTxoSoBi8h8RO''SZ CHq uNnXRȢ;έnC#_Y(x]o7nwzpAh҃_vÃ8guDްdn$H N (+s(=BpuP{$#! y>k+<9Ci8`oS`m/C菳6:Y0JC'NB1&vbGD#[2ykC{(Mvyw.7bzI2*Ɖ;r(e,$ZYC3hBk1NJHOۃfVH[Odч%xaBG-YKo3& 5fA>SɏtE9]оJ?ߤP*{H~jX= ʷxy>i%"6i~2C_GBlOƌzL @y7:@^µo1( 7?a}*$'En͆4 H2à 2e:^!&r,D٦XQbC4I0GF'ӈ}NOr-1.q2G)Af%Ӡ\ۺUNi{k's\,WzOyyZ-~NG*-ȡIMꛥ*Xm8#Hc3k?9+pHN3f^Pz y{xйTz/>69'gЌ41=#ySuZֹ){s"/vh\y~v0yF49lý~`$L ?LM"xSg"K,OL񴒹曂WYd<5l?{U| w?\! jYPu}ݔ)0)t&/6 ΀x)JKgW֕(Ė.+e2<8b3?Dna'elN+jNmҚ;iDyv4,RJ7#ׁU;/iOUw=|k\'^"|GG /Cp۵c!x5}з4UhEz~)Vxo*NLk+,_l_?hz;|XBI)rJvGU"Fakk 'dc&7},=0;2kUGua(ѷH.6bO_2,gwK0D}t~Ftl8c*ܟWo/f1:diNJ[q7~~ƺ6 ozL$N+!}&wJW uv Lfq'*ZFoNZБB:4ꥧ dGJ"J՗x=#p2uu8 l&akp@Su8]+ ms]>zU"!ˆl#8i^CS_!Np R n' :=sod׉Σ z P V8T*D+֕TMeü$Yx$2^bqP#o?5%2CdqfeT"X*H3w7W9Nǽ$3ǩkNr>&&#2>!iz !`"Q1f&̢bhKL)Kў\:\=#BZaeUn%.3g^xC>+BfMlMFFJ{: NƧh h75+/m?ʺb3ZG|~^TC Ezc_\85wn34FHkJLg {wQ^cQSUOo_E9 W,Vu;mB7ht@:K_tv2TYNsLǣpdNͣItԡ46S񼣢L!}\ Nm O.?I>]/<>Opն9a#C okۋ]yy>;XZrXs*0"mYDt!^CTpIh)?5F]0Ecu )7ٯl=d|D\c2y* $=Th,;bWfWE"rN>Ur7T]5p(Ukc6|R4-!8<}Σ+YhÙsЦZj AZ-վJoZ:OՓ;ꐯ=>E\H4M D~ ?7@|67XZ -`=SŽz(Ox3E~O)4D}87MC-/Ω/oȚ?Mm8s4` x[:=i# >m7%eˠfXS7"JF4b H'C2H+ΥWkюhЛ?ۅ\ƢЀwDKoD^B\x~]j_G`<OYׁh"m;*k &8KVlW2sOsӜ~&'9Z&{ gչ)Zf{ohQFY, B 8KlaF734GYaÒ}a5I q6p?V=Q'^E+_@\_̰Ӵ荎5JUϫ%B6sIKpa7>{c%ǑYEq/_Vv2HO;M|ykz-<^9y'ƸU^ 1a<jG}\6qDvlve!Xaۣ`>"fvÕT쌦-ؐ=?C}&V^ 9I`߽~vi ja ZSo<7M';8!<}}6h68-e7}q$#>Pĸ )= 5LxO tƿ]#~TQ͚f RVH;V5Zˇ{q7N^q(' pG垁Q0s5T;?m"q>Hz"Fhiv?ߔ8hGa]pܲO@fz46&iCj|;MVB珯#+hi=έQw DN(89//SrRl ~vL#`bhP9T\H}},=ܡ]kddY#ׂ7ΘbYN+<,.nںq-vqE]_yANP(Sޚ"_ v[ ?~OCxhWz'"`WǷ. G\ Wae4o෵Z ƌ3 kۦ#.9W~X( G̘ 8f; yUO ENxX ]B ~eԢ?᳃u(t{e="*h6Yˣ}z/2z |vL˺#sOnS:ڮ$Rj,kxCKs? 6<ȥ9v%&߲ǞhKAxqM#K*T)[I`rHK SüMDÛ!_&R;=Kl|p+ džc [zB텯;c,N?DpK_xGe8_SU):} aH--G~7{.)lCufKì>#-'ɴTn#%j\UJKk2v=D:ug7Ŷ$R}#PzZzMd((V@h9,ruUH=q'v7|9T(e 3mЕ(Kؓ kTe$J"l6MLbODԫ*^6:AonV)/|S^&2 [}cQ(Mda,v0t솹FaP9cUn(iߗXAÀA']Al;0~!0N[bM/jdNa%V-U3:7nƩR%Oha*5,4&von|k3gQTu1*:9x*$͘M4A2|zJO4VZy̳%׃\39ٚPx`h181 yHx!4/ ߭Cz<$(Ϝ0=.OA-ܾ ԄI*C^.& ^MC*qt0D SG:YcrIcOSC\PY3k,1}9%ƕp<]: F_Zlڐ |/ф(+x[=7~yŸ`#ww:d2 $;gw!]xlNv tt&*}բEm~kRifr6l\@mT;gG?11Cnyĥ11z໓_B{gq&^>E[/qԻOk#mhdO0;gP V\ "[PSڸaұJJ:|ՆFe,“)atMps7Z 신̓0x#i'^1C6z) zȂa .:1՛[F$<6Td'˽,bУ7h~}.goa}V೫;9Wk9JGAtQ:#>&<訃] ,]Gm7i H1)Q"Xe^._ZWZJmN&kkgzqc-eVQ͍\Khg G xBznIlΓu$MuEPizyZu& +|xvo/HOk`%~Sǎ;a$j#N,GV뇈`|m>BROE7%uC\n jUi]X%yИh0gfb@n&=LܶA+c}Q-!2:\+H톁=( =ݵOŷ<' $QcG RS!Yצ8#}Sv={~ommvFj~Z=Fi e8R`5lSؼNKſGG3U1l~C{bT xGa /"Ο\5cZKaD _YNฯ"fuD)40asr:ާۓ4}YY|BPI+Hp46Y\ AEۖ԰Y TGW:$v^<$w' EUC*#P}צ><暃bHW/ l+Wi^h# O]p.~mTVZhՆB&a&`>kc8Du;ab.;!+Mt*tdqLE =U?DyjR+Qx\ :X}dU`[hݝn(suJ smw‰m.ɱm>Yq\oyD#`N \!7Wu_yFM+٥^]jyi_|9%tHGWJXfXfҚN-F"^A2O:y/Ku[#2N=a'x-.klobLDڥY!众̄P{Ψ˗3\*68}^iUUAj`Ld_Mk¼3b`'UTA 82zһCY*=z` m+39]SI;KTTǗJXK&s qXs, tY3FH G~c0ʯ(}FᷩA5x|i*=j;s2 ays?_S_N&몎S'%З=o^=GgS{g(^y%A뮹8"O5N"^t>kyT/ťX%A}#^* \OYce1bn2QNoP-y?\->hvs$MIG|Ydlc{`imt@D]9'4Ho ZilP`%g/HO3&k-RCr]$+|B~㍡w-?Nx Xe`<+knx\}Oue#E<%KH{|X G3|! l/Hz2"G.Ci:yI4;5~%k_xvI]& aǕ9GJ}.gO7ŗ2C ?vA6"dغ fBQPG~+}p7OO%{b#>z!5Bt [Kt.W[ | ]p>fAXKl 0V+^}OC> ni#JQ;|G;Lӏ = tmTЍs}C:/QM^1/VsӫXK7[n%SWtP!LJ[gVОRNY߱ƽl)oh՝t sQwV5Ш|XE#7'qAAsWen83+d[s}S`+H#؜ ) 3}Prua0Z,h ;↊ϒ;( 1Ӫ۱nP WEwTpLÔ`U+j»}V⌡ awbV 4Ƿ%ް "/qK N%ʼ+oUSмdrng81WoۈD;ɉ ugڐz^VAS<'t Gi:7= EF#JhTމx%3BwtFA{t;lJ;\߫Uxʫ]>sdPҳgm>aJmߛ7/O`O ! =baQv>&'%&a줭t%?꠱ =ga6Y+2X䌰!&X=u}[?sHQþ7nxHg&N>rI_%ŤE]}TY:w|5nh}H+[ʑM:R^GVlĮ:c-{G'Uu|T,y\6QJhWM2WFҳwyv(Aw5ޕNK/S$UjfzVE) ZEs?E]J%QWc4Gs}X&Rބg<J7Jc#דWOWp1KqmJJ u2`W@0iMX[fF՜?"WB{,j!gS:y:'no޴\vY0/mYGKas>?*'v4I{r}u!Ev>%raQǞUtA[VO)c+vlhbRԦb+ ~w^U6>I Ȅ-${qk O ;}1M&Bod+@ ~{‡^rx8$mU})KXvS n΍ex1Z']ԑrvW/B[9"N0FTr>Q#2KaDc?#dE4_~28Hml9d!qV ~0Iv#֭ h?.wMGZ=-e;p~=k.ԐSun2 .Vݣ#(6;-GMGi'rKAyM(b|*mMqϠcCovS0Y(@Ԟf5Iq7-к.(u#(s'md(ELcU|CalD'c -Ŋ&Y2j|<ߏӛpm%7HF'nSgvЪzkt)gXԵG^h, =y}}/'縑Hh6=OcwXOGb#uw7o}E)t;<MFTGa{1r]ME~-<2& )cwwMZ*h%N-?N`e :A< ፙ!udYSKf6|Cg b[rw{o<Ya9,45K:EW)HW kG NC{ OZQ; "; SYb>#ω <$Xm#XY34R0d|u__Kg]xܧ$W°VzyϘ|rC gGhOO _uAi5ЙA@2R[DyZ˩}VQXNx;.7flB}jq{tP9 |xt׊6I0v]O[к=4:1zYB=NOS]'z m"Xp Hxs=1ȩЙ%'y SR+8v`/<^w*;`n 8߫!ِ94`qE>'96-oeox|Ozco{t_${+ 49їyywɠu4+0^-$ydްVђ[+haю{s=ҢJO|Rǃrv#ly{+_qd3MݍzgDJ3JB3 ?r#i!R5040u t\Euuǧ^tw9B3Vp t-v6ҍkT;s=,\]KPS,(l" Nt6>'>'#Eoϑ\ g}ۄ pN{ȉ\?վӜ|Q(zS/H{塘| Bs-b=ip iƑ8λ[Z81?|{ _s*|st|Q 'j .-ׅ3ǕGGbzJ&Lc(2 }{@q`5Y*{ .W10hJ {֐6 BT%=|2 >CQ}R~9 Z}oCƇ $)Q,ڿ'ǽ[hWUzJLDNe3=40*~/72O7屮MguE`i#tBLݧsu^a -W+׼> /g1?"|9*``Oa$WlAJ%L/㐪zPscϾa])[h]&~4ϲ8a’o^*8#Mi7P>/j Sco 4QJE; !ط&'[}M9c, ghy+DuO 0$؂MF:X}:Bz^Ĺ޳i?ǪصV_Ԯ}lѪY0hPfGJr#?E?is7vS[O7ޛ]ϟG X=|a"s!|?\;'cIE"R7ӣ.xl p+r&Jy"Tp,,=WvHd/_Yj-c7GՀˬ 9]TRLgW|$d,5_+tԡyk gvK\.VsX@K!\ 2)7rYӳE\w@QT."`40`lO-Gk]MYmmݟI.(n g;q}wQ ;@Ν ɓ*J(}~OW:*bO&^1ǤBk" sJu{SL 7G=c)4. K@3O).2@l!֬5<_Vƃ\D_W[ zXe*VtU(7<񷼿=f(a$^ ԤϬMIS3[9^ϟ s54züig8&w+ZXI\뎦s;mEAވ Jhϯ{s7~!ia}9rtm-tc6_Fi k}t%?tϧJ4"- *&]$r{|)K&`em[6b kX=^[1Yc`]/1“.堧 =?B!h.jo6Č Z<,Ys$[x!+$4o 9y>sEZw MD=J ,|A竈eg$ަptaUm]FJDBTPVt̩""6v7&"%ݝҍ]~s< 9k9x^'2iܒ!X>=Ƕ[}<{w>q#lQd\uPOz& Rp|ccƱrm78#\_Nh˄61u%p{;oyMsT6ejxs47(KM{E{ž,ͽ$TqayѸXٞ X}/S{8S'|h {KgroxCLyS|W_ѻye(ۛ|7sh4>L[u/ʻoKq2h5o%OcwS:6(/O "|OvP~=<[$CKTZ)LKk5=GOx]э;%yqP<>4 &>l3Yx 4-uЏ7G#?`Ge3FPO4;zieO#8ZчP8DK6R,Mc-a:]0:3 .tIv/Fٚt1 vMggyOcC<)׭-k"Nfgȇb7oTfl+5]{w5ؼڤӚN=% >ۮc=;9M-${]k`Ah^~Z[Owӟ8~2I=hrj,Y4GQ|iO^ߙ/Eo5~\ӞvE?mO-q|u Zu({gi"vPֿ]ǩT4k [W6(:ۚ+ tkDV‹vM_XȀӵ[WM9E]pO59Y/ *rJ;j? ,!ܾg'~m<ߧ0fD?޵#|aaـۧr—~;ً<,zh~ωECtli9φ]2er*OU䵗^Ã|b:ד=;7ÕkZRZrEN`9bl6Tq xӶ^4C1nh/l^+G +߹ǻ'`\jOSQ%Uxy^exh-tHy]:-jqXZfBc([!Md{.Y ڸp06oU$|bLmvz&(:Cư0.d8\XƹFyܢ2@=|LFˉR򆾖u$fG | >f̞W[ѸAlFKt7~k8_=;_̯}1Nz4h0@R'M2m9XU`*T:+J1\!'cRv-|:~ă4}+~i3t3<c(!\9kHްe4Ο)r9'Lcxo;FC MW)!;7qpA3'͟"\(׶FM|}Z|~{?ѯ*WI+r<@eY.>3{tyNQ*ϖ,Ɋ) fϻTvp=N*2.7cnKiwvsL+(7_r1=qc b12Dd =) В5ZP ]k!^l CtyjlL }yKC<2wIZ ^[._sNo"LKe-J%l`c)v&_[yẮE`n&Ưx_[K #2,ۯ=:$/_ UFz&?'m ==0-A ̚F9ڵ~4F D[[Q?4C/},@+xBڋ*c(S.ԋ}4>XaZkOrQ/?ʱv;{>"o_ѣ6H^5#p] :sp5!N~|;'MۘK%gˤÙמǔս)͉'TK q!NK`i4oM "x0nb[&kM\5\ηV>Bv~vg.4))e~BIG1;p?t7e?/>wپ#?PC}%yB>i{μԘfTo=x_J{.cτWp3NDkݿPO9~7c2wayRjYPftDrUp~#c]̥86H%2w*'Ǫ?=ȿ^*~o8782rw~1^؎d»bo]ܞ{@#]ZtZ[v5ƒ^/ .f(]gAtDD=j$A5^uXWB#'x1 qX]:.́-3Ÿ"r>+6௛D6-ebOODvIvvVfE??5 Yj:Yq@K7NuC:F_Iwdn=ufqàrᣓ9XG&"Re~T`$<7hJqYRUYJ m6><qRo}x=8%o|CtWf`n/ՙvI2i GVQ? @sFHK]D]ՍXDrH `{zEA&DvI?4g%t6>!s2.{d8yո&"QD{[nY"#-#uY3N]i\3fYo(w[5Jde~i[xIw>=[Ϯƺ\{;@{YO/)!c* ].rkʼY$O2 &4M_q'|Ao英/R;<;yX56(AuFQEy>45~љr\^;R\[({8 2o55]["q(M0 n%`kQqF9IIʑ7i}r AUh،)R0*[E1ߒyn/^Z+8+܊л`?,@ xˋԭċs`ێ\Pm'3Xxdc5|UP=f7TέBOB|{$Nw?yR|1D> 9>GO^vdA 4` {wu+jR D>ϔGwZ'ja]yҊ&_4C&Yq JqvЋAa='5YU DF@zl,5!P`/釶B3GvM(fNu&erx+J\{<-6 $>zzF<8yܓg\euGWveA9q$XbΕ/IwzzC7V\tg N)ig8-6Wy<<}>ׁKMP](^ق#[nW-}#~"u Xv 5o9KE6h0wf8=~7 Yo-d:$ϵP}0}sY WD4wC@,RdС,> yPHC}x Wz:[d +pu`SʯIaD:'<~<}&R7mw6cSYo?lkٱhᡃ9sgD^n_VYaʺ#>k0/wƂ"}nP`R,_oGUd|sJ/-S՗~Era"=pVT1K 7A?8W>ەX:mhg5:=Ux,uRΨ\A5e?P`w*YƓH3uK%=/Dn.φ/g Fw{w %d3vh1ͰYAI36~Sh4OYギ\hٟudc,ݱC-6"J'(6{_Ġ 8TgSO9(,8(3q:4 K4a0ʲY ƾ-80ߍ_J@nS큙퐅?_CKuS˩f2`SշC'pm6S೷;B0r܄ϙC9z13\ǁ59yp֬Rn~!H?'ߑOE_we# 69㥇Z=u<׽]!}1p*lƞѤ*Z_f zz6|er1I!b?U3qRsYTyՊ³ͨaL(7nxۚ'Y:oA:Cp\o6{%jXUVMu'2UO`ڋ C})>iB5v%b>¾LH,GG0.a6h\l,cYAeRР0l|EF=<֌ .; (lhC.x[丛"'}REI @T)8=Ûw33٥ِq|څ۫Hؑ2ϷpV]4-+5};Of.C~w(5.8-;Hx6x߻(PPlnϱ=Py]:bW0~xMgVCu'^Q´T-XaSЩ7E4O~3wsMM؉n*ߓyyswkC%1*EP:]Dr*6GUnIY: a8D 0S:+Z{sKEF v+k\悑َJEwpXXYy </x̚M15 m:qO9]9KG50Ir\K#k#ü T^ݞ~:(zWCr-qCwNfZs2s]{nqq0epեy$Co=> [;Gg$} hp1(@Nxt6Uգ90@CdT5_{&ڧa:,t<*G_qOì:m7]hɬ!0{'dP P_jB b1'4N? Kʓj0S7AUeX7 ]b_dcȱ#;?u{L6Fw틣paf f>Xa韋To/?ZR 'gQFB;e$dڱN0 dӏK8Wv"]܇GxNGddǶȸ9c^oLi_[IzmJ^ٓgd#xE]ya7bi,T}q85:a%AӟΔ&s\]X=O1s$g")Se2ʽtlxk6><Fa|.)Ʈ cv wH NG!F'. iG>O/cos`0WH .܂zda؀RT/ 彭p?*c7Ws-;ߒQV%)LM]EBjg R^,9[TphC=c,#YuxEo4,[?tN ']kybZ݉wbfyn]dN|hZ-8ԝ#tf i^)DWc:\@Ŗ}uգfMN/~ߠ7GNu}JF-E$m h[+;b \(r%, ,`40ŻNpݛghxqL<\Ob(hʓnw=:Rj~93\g\^yn_ }(8 s5|;KS0M$^0ŝH4}mewѷ<}Q]cD{KIKڜm`T^B 67ճZ) ڐ꿁c1w &e@51SuM-_W˂87 dl&d{~Iuҵ@ןC`j7>< ud{ع=y hn +enkhrSbDPw;q\7EV:Յ{p*X{*j15nFLDzށ5%|kO2"ڭ nL}фt:k_/i,*y/Cє6 PT?1O#ʳ^#RE-lGUuVxrmä2*9-%p]dVmx1ŅX?>Vr(zڕm?|۲ 2\FUN"gt w(CIX$dN319! ]KQWM2 i "*ԼJ]hi5)N4s+p4|6hQ~k;WN2prVX%Öm!RNo`UD :u-SNsHF+fDyуVE,w'L겴 ^ä ?Dฉ3v`(LvEYh~?a̜ $1CnyFYv~ nrf"bU5a%BH<_tt;߾?ED&mzU'tx7dΘ{Z:zu r'n#F1@~/ڃ28|pJD ]קbʏHo?F7MI݇Zm]s_t#Dfϧv49nFm[pO5_aCsḋ9f_+G}}"5[E;v' tdrC]Gr ɦ_ҟ)m@\3SWwy$8MGmP Ѐ!sDGPhN@ݷ:ـIBH ;b1!A(=׏f R{@j`BNCq3`4IE ve $4`mxy0}(2 Q'§$^WdU?ntOCx~qD#~5~%,=/9?K-K4.{!]?RR @*%3^NByZ?io|A"kwJcT5L$c4#M&A|;NvM[5v L9^]vе T4vz QIOXca }3S\QXE Mw@~`DW,pɂo@x'powzֽ>ؐ-2Q\ +1+<\1 .. nhVS7`Mp:Å;1E_bM2nDa˺]Gsi7?hFuRnm(tI/݊% zKi"́z]OIO^Nsh0QvjFp@oLgNhTVяIg>E{iuzL%c8~<:>lv7Ä_*,{.; #"ghku'IVRDvN&G&lԏB[*쏤f!cV{b\<'(:h]i0.{㒾;W\l(cQOBvm ˑƫs7ϵ~j=ۑOzV(@~Y|%xWNhx*=֏?. ق\ e(_w-Cwg 5;R7[rv(!̒r>ߵ'Ya-l@JscozЁm:UmHK-0 /M|##@ 1jk!aU5p7áET9rMHNE\(*P\dox7!rV:[>Gzݯ~W ˇj E~m qjor&tHh$eD\(;IQ璄Yɰ~YrF~,-ǂXrlA\x_'c,94t,zp嚀RԶ?kx<^&wG4-{h;/B݀u 4El~h_H - cMӟZRn_;a(jcTg,ϛۑ8ٷLhu8r&[p_f|W:s} ?%f"aK!B J[XI9aSuM{Gj;_xl UHL$аʪm|^-H'J0kw #X|CcUۚdO*ޫoM3JO:]|jtIuOó"WJ>gEz؍G_(q]Œ2 \+P(خEx]6 Z_ M:ܳ>#d^8/鴇e*CNa&S%6G|) [x9Z!: `_^ Fl =?!S2dﮋhxœ"`gؼ3O2yqp'n㋅&N+ eE4hX"C^Z|9@8`8vCJ _cs?`4wYOao8yƒHw`ҰD綣k!tK<65[gv̜"oM%:Jga;otEz~|3K$|GȢ(d@ ou)Z,m1[?\,hg|ݰƖ/kW|l~𨈂D7rR6,gv蘓o"=Y ]>6 lӸ")x=FW3jj) ]1!ׇIjO"$bWc ~Z{^IX*N<ƔS5vΘGd4ȫE qF09 *I"rex~E؄k3t`=zݛۅ"C40g2 W0" F԰ҀVEAm8yl8OE͟úN" WM^[Cv" KֺO48*׊BIdS9/ejL]l#($2D?Uը`i=.4-|< N"W!ͽ}̥^S.N}4Ky%DnTCNnA22zFy϶C2. 'U^SaYp왁1pc-\5H0C KEZMɹ= m5AYu'95qDq(_h"Y /XǸ9\ HC\0ಱ"!(Zh7BɰbQw1,eOcp ph|™\,FF ;RŗF:}aoxJK E#QhNSW"zw={4 &EiJKiP7)҃R ~m00/ˢ~)XJ<腮:9ރ=tk!<@WjIN}@nh,OI?4Ge u[pan% &+t, ܄ nq:Nw%#%6TkO|.%CVKJpǛ@, sGR+Gbt04Q0=Ew~liLvF4iuI=GkұYJj4_=L 9/GVk)|D}$HifYXW2vҤh~\r2[2rs^һgxsfJLsi"#f`Gߥ8 Pd|+"4a[[ac'\/eA |}jDƪ([!j zY|1k ܴq +&/bD nнv$,Ve[Ȩ09)ѥB+p7a >\i[]$=\$g>owjjjJ^En SZj?ȡ:y3ԔTÂr|-[L+n_byQm9)}y2uAGQhEψ0sFg U0:irF".?2U?zp*Tb` Y/4o$,hұѢvʱ![|>A?Kw,\quv C\r`.w[h| /^gbD 8'~L4f  ue! )"O&6m-F C"1>Ouh~w+v3d#YN˪i\i)S| th.I}ԣmȂ CoO!/P(c C<,)ƣ$t Ù|[(ٗsx2-&j ?YcHw R vY,[zKW{sk|8v]+hؙ_Fd>Ӟ#[}}>~ϫZ𦵻hNqw3Oy_/xaTYtISt&֌y'$(xLqro(4uadl.rG))=2Wby5{Oj8qkv.~8d}Uo*aеHhcK@vAq(+2p,g+1~Ъ8M)šyXz1PR ZXwՄ E4$?Uz">n"wʩYI_O{_u3CNm\`M<̉A=sO"t 3,rrk[瀇 -r.]:.Hs^ǯ[ fEvL7§ Ϫ7aN3>Ƽ4%ciP{ZM) )s2r=NNl|ϒ풦vM-r9*fWtΙ lZr- vZHYP`5~շ?YǗ.Ey:rϩli#{+jc [=ť&~3`A-=yҙxM=SoBuSF9f(NuK99*MxjOw!70 |oDPjU%KGKzmψ"Z"9I6\NЩJ~Ƿ "rYWoJB/z`HFSȿ"`ϴ$twc<`OY9Zk4k 6TFj wT=d &P@ ȎOdʽJu9ٝyRZ:vgCd$b>HBtx !3M+iW}Wva$;cO e]HJ?RR(E[:vvŴh_$Lю1to wǧ?0Urǵ9 c$0W7PdᙉxsAyW|K\kU*UEr="<<@Gd3 ;AZ&apK/,uFXnE屸v(Ar\JHIښYSaWjEyA~q2 i;hcvOSof-lEXzxi$M%Cd!" #(1CM|lqsGwiKu|ҋx0='XU3SHq84nEw{7(j3g -E.>t'MkQyyBؖ`t .m\,K2ӂ?=pbK$nc팔T$w쾋Se [] }8$d<e*9SqI>m\B?YL-k6?EXs@f q9]xFNW7`,:z?1LȜ+2ZducF$f}ъ}lOxDћV]g?c#]0'ƞjK"w$V.ILʇd>f {DWGi(_pңѩC')aO]AeG9#],niV:1߼JwH5?JL<&Uq=)$JK+yVޤGHMn\Zs:Eb)bל'M$^zVÙ^*l wdXj]oiPmC31u;'}TSM{ˉ,r'F?^vS_R痃>ОD%CMΧ_\M)U}?/Vb4h&S믊MӨk)ZU6!QO\c 6=_f9',8?ڻ.4a^\w3=',*1XήavYϧK,M( Uk y>}nS@'[^=ll 6t&(֞{(۴͒u)wZAxƼ`#9V|Dt̶g,ok3㎺7}L/7>[)6v_kqr_IYnf' p{ײ-kx5s4:"x\}9|F鿞o^ڛPB*IfQJvmt/F&gޣQ f7Y]yǫ9U`vFIް*Ƹ9@#5I統nB'ԋ,gZw{?5]lZsS0E6nbwx촷D J1fY3U: @K*& a/͞$Cj(B-&wz?_si:N~qڦc }{ֿcM"ICz#Q; t*c6$]|AlB&s6oG,x-\tPg?lմ&]a#XX( kkK3W- L RhE=RdYtE2{x{j}<I{4ͭzcz**שeowN"z7,*eHӳ9vTw:zB)^{ik,G׶Pت>&S'S!~+M`䱬r8ZBm &<oBb8E+RdqAu{TMXϳ-dg}35!`oKo؀kSob ><_Jn23`Y}#敂htO'ܑцaqՏ-`Ńpiv>c;@i:g:lˎ@6t̮Ҭyv*e^[S^aZpQ iC5-Fs[fXO޴p8Ko* -+(v;Ϯ{HN\2MSs;x;8PTOK5~ҐL&δY/& p{y@Wl|Ɔ\|> ˒h ""o9WF}kl%' ]jzm!+tLf2a_+j{UjZ۱v,'oz᮰/>0EQSenT3JY)-EGRbI2^Kܳ x=F4SaϿfhu ( =?'б|zr.&Lwݻsz)NPTfj5 {0=zBg ioG*QevW1ՑszKmcQu9I6yKsZ%qggmY5\}P6r.#9@yO6D{ Bf'!Cu< {`1rd-~ /[_K{*hkz_]d증ޓJ_P^V-P?'S$*?xR/1{挙Ʊ\/h``|OT_zR%EvUP"MP&FXRPig|88i4 tNwb{e`.H0'ľpwu;bN a}Xچ!hn+F@x-@[vCgn` rp0d3ym-;[G SK;zM:( o{̛lIs{3@ϫ$ܷ˩R7U_,-.'s?ӸoRy3u7kXΦ/YCw-[=~ [akvvqFcmq1ZO] º)Mʆ;'s<tTH?o_\y~ ڭ/ yiV8q.}ŕk X >18K [,xf0 @ ~;g \8bW/4AR͋owdYt=*n:ݲ.m>- ^Tae*Mq+taq 7ġ L&Goq,^YXix~g ?Ӗ%؛5 dkYAm 𙽱¦C8R+H{$ $PBGi>neD:ͳ3P5 uZP8Q!z!7۠ zچ"D|r_E{{~8׿o#:ͅܓ LKɯ>49O*v6^ MӠeE~({^k&VxȜ3P=I3iu+}jlub.[ @=CL,Xq$PZĽU%p[o/jilf5>.xO &6p)*;JG:ԅ5-4Gj:VilP P1rzL$aXr3?1z8hOgZEz+p^6k Ju18y,HeTNdqsNCwn)n=MeCu6yfR͈ṵ?wɣORxvZ&eu{]`l|V>{Yt֥ާ}ejQ% 1#9z-ÚSk`Uhj( [&LYYnǾ (':)# "xb*>r~9l`mup-#2OIx5K bm$,ut%̝ V<]8ʠ+9| $fT%xUz"z{c=w@NGa=Q뇰 Wnh8ْJ~$Y2R P#LۢJkܸbS`텂,BsbY(5ݎs^j7EIQy}RIzsxB͞"`* SOy4dk%gKѴ^Knё x,#)"}:?Y,&stf_~e.Rn9Fw$ps8]Ga#xXl"^*a>C$g#7sM9 G5b,v(`TTTc-ʰrys'a8!:xkǧG.s8hnlv*n <0QWuT*xSg؃j&"4 0":Z=E!oN$%  ʤ64|&ݴ0 heo>YNלJ>qʹOQ9 YC/[Zh.k7 "p~ ,?e8^U&'O{Jq\hsgAqh˜Yaa haϩӒQaaߋWZB`aےY(rRT8==<(ލr¶<{~nLtge;{(x=N{z0{؛}Dts)&zÂHnWv#k!y\Z ^(8m "V9/^`XHdUʅܕ[lAVt*in :^B2KH潸BBaYIyYs0ɸ1_hQRm"l&5~WP쮨69u0YV:D&6_`muʣ[r>0{%-0ح1m i|9jc8wKSLcBs9 J9!ڸ{! QqD;Op<>0a0jAjO԰!W4[3do??qpK K(X%a>π%t98Ij[W{09}Ɛ]9Emd1ަ%Sjtϭ//Ce5jg^"' t5@%G)tN ə6aGfRwA0>ߒd򉢈;9[${.ޜf̤fq,ZV 6rYh1d ,ӆ[23>$b3WVdXZ Nǣ.E6& C"$xsLM[jI|qп^ʷXa [IAe [.60q007ħ-Viv84D.sx0g޸at`Ky)s` tsJv"*} ]3dD,kIw,u=Z9G+ӷ9_Mw*Ibag|z e=>M<2i^׭:%'ĔIgwHk;__=ǕcwKUD}z1NǝAs}8[C2ۄmCG2gײEG5QPTcnt| "Mw{9"tt?6H$iLȀ?XTe*8e{IJJ"H_jF!a(զC_ ';"^W"9L3?pG<@0_=` Z% c62Y3$wQeQ|Dߤ%8z9}nOKyӸ&}j\n'ȳmiSgUVSgL`w*0r,uD0A1} }axgZbrB{9"A 7v ,G8޳ui]0_~zaA4b ZOjV;ntq`\z~ј:eVJh-A'kE ] ~gQ8Kc9=19k/Nm@},ʞ!~%0_Bi%vߦ&jߜeGKp53-ظٍkioavK&9F7ƉSG.ӫ,2Wu>(c9gŹgeϢ94}[0Nm+f㱻$gS,DQbzKCB~fW~3 P2kg8 ]Q,V?L@@mxf$P[EѰkh䌷/=\87F۳2'J2B0Nڅ%<;4G<_LT! ib #15Ԓ:ߍg2>v欱q2 g|řƴ 6bkڹ ^>b*E=0 ":JsPecoI7ysw_ֆ*j}F5J`ujWh^,s{F:ݬelo)E<`~kbChI"A /9鍆5er?3yi ˾GvenB48; Qg8=:8 |2BӇq %_X~3fa~x]DQʲh]q(qQX0%Lp#, C Ƙ lEXg$ |q.E*paNEaB.@d;#o\ajrlw ZoxVi5;f>a\n(p/e=9%lc&0u֞MG[/QH{~ӧB*`A>iV2^md`_nSla16ϳNk+1OA nv}rJpl]kaPȾ?es ݠ_uTA.ʾoϖ%>aUF4oKH^ Y! ц<*̠j6l4?kϺ8h>R2.;y2uT=auCxVaaR~;XB(f/Ϝ 0`M&{З +dZig&FL&>iՒ,rn"-xC꿖nl_^r/8KPF7>0mrr=1y+nq!P^0uߞ(\,ѝJX㥀`i45v<|9;Zx's I+dD7LtHSƥ0N0 b!u 0# 30n F>@ Ag]:Zf6X0@j$ i8 ;[1إO,I#9SjL!UW0[B&gze3NM6>")l~H=Czؼoߦ$vZ׷Lq :.5;S9Kߠ3'cЧdD,] |P=A>=[bX^ Tդ>}9tBC#FG L1 @K1 ?]4A}wrG@kPH<@G!fkR-mcР1>X0е6'8πp+ñɘJ2k*q+Ci/vl_sq<3X9Gprd8X.c.5x~cgWrƵ 2 #F g]; Ij[oq\_Q4&M|*x_Ts^O'Y} rI~asR: K# x{סy1|hoE'|'CIp /@ibu{g`4kȯl5Plp wl\$?(BD:e8z'w#tף1ac;;4%:; .Ko}OOEV,Cvub۸܂%Xݽ ]ik;zkҐqgK'4b0ZJD6mlRr9AJR0e 6SdE^'ɔΟCz;#) MqE}."츤*;_m [g=^9CPO/v=\D RV%1^WuYAx~XXD#AxLKzXj Y WxU аD! r{QݎA-[4?b=QS*?QޜJc0Y '&Z#m6F0:#8s saʄΧdERoXnRDΧ/%S2;}&뾤Ͽ%T.8Nn_oAZO7Pu=Y6 fRUkg,) CR2,A&c,VlF6gd9$|0ĝ88uzkK)G _,+tf-lc:ܵwY΍0V{؁clY/0.@k0EMFuXy1Сh9KNຳ*CL1S1~>\vA(> W563*X|RՎpd>.Ap\/?);3y L3G=I ʩ]筜ϑXjo޽)x}%ןzZFYu>Vخ$s3ùgaQ6hBj"S+Lg5mw)g{5iSήo읂 j?VG`:o:i࿻) ibR4>YC"pz lAr/RO,)I. 4gr)"Ə݋ k߳ʴOl! /Up!S"˸esJ0?&s^Y+#d)WRHb{[ؕk~H[f]M۔ѥkx?9,m, J$ õ/a%O.%g?L/wXoT!}FxD1j°LX1`^NES0VP1t®{kn "Y״2fHALk!HA):ziL %֓q[i?fY<g!rN`ֶFjWC˫ hF?8p8Dд-HZn #5= QP ?+7en4!hjM{z+[8"5ͱ橆T{G#IrN adl[z'XG+ש7-(ėIcvn/+W!Dϔl,,AjP3;4jFKf\Ơ#g1n5,C`T.xbkyе(fU8Vg#yIo#iThy1 ݀[s1Yc~{y&4e0*"U=sohއ)z#~nI˃q'3NA'Xl?)@[uz[r9v}!xB=lWO1eংc9;j yy?SI ً[pq6ւ}L2AVZg%[3A<]]¨}-~˦6)a?ɻJa[e']&5X)CKXѽ6f+)u$hi-XnIm|4:8-v踋_ ,5tz٧J0;g$iKq,3 63`Ox9(lN&3ٓBo[OfcŸw_w7h$SFq֗GS!v8z?9k3Oa:0;}E!WyOmfvo- rX.!#c8Z%`x[+l(|3Q]7MА_~'1sgX0TsaАH A=BS0 X9x8hV,l;Jؠ$JgO_9ld}{i%=kYYYξNyx;͵zz5ܻ]Y? j3LxNx½ٜ-{edLeppLs;t ;<p͙-nab2]3⎝'~p[H ;Gm &[[> G-B0r96ݟL\'k΍~h&Atu%q1ƘG=LIxu}/=dz 7Y[8&f֢ /5k>7gJbbMfs@u<^ B|SՏ` 운 B a[2j&:+5g[4#ڢ\E Y?̽ d[WPLJr#Jz$ƅVk0jd^̻n|VLfAh{q[U~x p_k0Ϭg)nLĎPvg(eurx$dSd:oɣw`3,@_0nY0IUę\UI_Ǻj "'S{ԝr?a[gPjx4pkjr:IiSGo!]]3 )R c1ZjH{4T(qHCkϧvvV=gϏT,5ˆ63kqnP$xyYl4w*V? -wT HY 6(6 uCTp>o^'[ٔ>#z]JU3"z2F[HE/ L>u{J~'?jiGm Yqiʥ6% h]l csب[!oO b\ ΅%10*׃ ~V5J!(u7jEYbXLsC9w{-u&f$$Jpnn6c8y1|X } a,f,#a3WURxo&/wJȽSEx; #q HA33ZŖ+#5911®' ϽpjZ8ӨבL&I1ߋ1sᨸ[\I!A5?S<{WN{JE !($+|B^zM-*ОڥDRd=MHQݜrιy|$U]Hʀlw+-8I}t*KZ ioSH#s&KV"eP~;iݺ֍/D a9+Р w.VC,ͅ\d,@"'=q'-facCAwP6Cnؤ~H Ie kAr<ɯt}b|B ?$ 0"Wάo:y4F Z?VYnƔxWƼbN]@}0ս,IRTYsCv5.jwˤ?yf{ŎOҤ4.c2@~ݤϳע=IV|CúRcJE&7jXN7-(ܘq+ߖC{A[GQ|Sr5eU%S7w$Ĩ2α6QȣOӨot 6hfcOBO>⅞p{wDA5P[<EvAvH\TJGbl ͸|R}9LHciv&-{{L,+DP=!Q\y)Xߣ+_ԑ׭WBl| GZo=IJZ➔sҙD3 'н#haZ:ϊN2*}'^T(40P`A f{cޚ F ˒0?HcT'w$dB{Ot\GZŇ/Z\Դ˘\=h4(=8N~4NƤ2u?umC+5\oP.w*(ozi )B牚 oD4%dۗB k1}9V.`NNßp`^!v6`Fj{=niAȒҀ}3Tl+ v~oqMr.Rpˎ=ʶ/S{zU6c֟V'Ҝ}髉%xMceFڔJAgtBn(ygڒNJt[~/>@ '4{p5~!g4@3J%ӊpq4$HI>=C)F74I)=J4ѣ>QP!֬Ik HS>QjLqtg%$]5־g< 3"#I(' XM}ǘѕ3iB9.B]D?Bi-)GMS͆T9p 6ʵmIC?Tr(ĘeRN }*n x_jxU :g)Q'-煜}fȭV{r]=,)L:`vny_m-}I7i^'ҊQcҢgߊiJDjE]׏z:ԋ~f?F&tx~!Di0 %dX,>wTH(2t{>żJ1#駮7֞CSit;ׄ*]%3o/yaY}x5y)y?);%ZI U"}7zv)~Tc8q":p^{0c}R[Kǽ>ZXqs8iIj]X]709}AKSѸw J;OeD-)qh] EH*AbI&G!bzoABŚ58淵4'yFQÆt֒6dl2uXCi!Ty"{~2:T OWk CZ(%RhST%.t_ %{ RM#}ejpd0EhE* 3(\hOz2-b6M>D^RdK %(0Oȑ{SQZt:Yc.G5iy4S!ci~P_9XWwbq&i,"ஓypH S,H״,y5jD_\mk*Σ#һ#a rqAq) VEXR\IV{K#*DX<F]-ih:zaHCKh#Cյi{?VUi 毄/Y$v%oqB)x#n> YR`ҺMWj'ž VryRU\]JXʐe%~ ЉU<| b J_ۃט19P'VBQ?M ѡ?iIWxJV> ƙ Hp-W++krC^~Cb1.k7"?gF#Q U-*.P'z: 0^qBhD5jGRd^cF;?Ґ䳺U U*S'zиYtf-NwȐ[25|[],f¾d:eW *ſwï/|X*OW9j[UV`&OU;r  pm;_@*,ol E-hSe wޞȱ/r/8܇\ T/\ƱfM*Ͻ^AyQ1Yگ| I}ә4{}v!Oiay0üLYNH'#5I_+y>*kh)r1"_E%Ŀ6'm-sQw),TS2W-njɇ|JpXHbӌ6bpmcN;Q6m;`M B3# C,\[U8}hsu2b30p͆k5Uc}ŗ qϳ}Lk n r"pD8͞ʑb"[OіiLPZMR7#IدƳU+uiWhP<9YqJF겖W'U~>?S64x:)s:^HGt'Ҭ%hۿDǵIOvX;IK1JR: Ҭ6 b{GènU4;u+۪'ݨ: y"i~*R$ebg8t;[5 AZI;cpt9=E2<zW6y|91 .QIG,;BrZև *A/Z24o Iy&-Gѵcrtw3U&k~I#cߨ8y>QPxs&~ ĥcd091}%0C/A gwftێlل?5f>F]!շZNZRo:fmܽ$Xzބ3hݒNCF-բIy}{eIwͩ0f|*z`IBv,/ rq4}&r}w[5hO,kPmZȘ4Wz Jicn FKB']%΂ncC.{#_ qpj{;d#_f%@mINuǀ2q;FajL0^\{o0f%NG WDn k*QW}5 \}P5_BV+q2:B'Ssvu>I.AUwA4p}G2A:TlFg cI2ڙmF#(RrWکOτm;ґ:4DÐ"-cAvhD>tdQ<,fJ3JBK[DƼV3عELu~婥UJ3kfm/J|h/1\aWrz$y]%v'&+Yk>w4>-Jۀl*aߖ sK0NIQ1Ê> ܙwΫn4zM? l.7.ĜG^m87Mjbhc9R-kFce-l"6gsf֏T1 ~ (|'M!ΜHta>D{嗈*ItG#)8YW5 ܇R)KRtg1tIRY J&%RY%-7M3%hL]'LP„x,1ϋ?%hTp.<&1m@{'-&%X葕ӡQwg'h\OT׈/LF'߅UzrNvKмWCź{X4 a:w.>f2q~ ΥSsJzՃӎ*+T?:Qn/<;^Qd_L=+2*Cf4כmN9@'ڠoA[Lhtx&~rL$(/qR"1-")ZhHӫgb{ѥV&UEYՎ5t垽}X݃tMlsc"ZcSqioϧІ]9zXsyGAظ4=5?. cCanm][Jp>{ OZ3.( .`'GGab@ZZe;3ʪ~JX_dCEdyoP<9{uT8jX쓈q05# `[w=E)*d9-RӦ ?N 5#mEqmab }MV!@cފ/bQP5$jBXqM,]Mt[O7P4"MHr4o[\1#_ zZSyzT`X.ɘuqdDЧSDAoa{1g\@r sO4" l})|wVCrlH]6Dug_mͨC_u Ճ^TžxcaTsɌ*6+rDmct}% G6hVx*=JاIRJ>ktXB$~I$=QZDAYZm/ErĮwKLCr)C%& 90w>H1B yS]$c997n*}c R7G'x~+{iF_KF]s;3ѾI)ǿ}ueǼ{a8/yߙ7Q29W{gsOr/yWSׇߢSݢA3*Q/t-m8MHzc7NOKK~Si^_Jb1Nn1aM}?49;!D_k0'x'B?C$/qp>Fl~q4~$sLEqxx8r,AGtAH;IT41=Z Y87kr% Áؤy !\pyl]=b_S[<g20#C!az4]݈1YdZ6FgG x݉1(ni&b2 ̢B1Q7 ߅$pj{1x@ gAU7^DRdnN{QmĽ`@')bɘ9dɘxә6)zYԿ{+ HnZHO+xd&-~Ww:,ADgB]UDFt&%LI􃊭Ex)GEit;t2܇[1lt˰rd釻'ӾV[3$XmljXb3Yg֠(tXQ3ᢒe{UjlŶ4~^..݂xO/H]S2&t -6nCV3WT%Br#u cjb1k3"ѯ6j =Dj^_$6R ezӈN he5nvd {VڡDC;b >Dm/.>F4SvOĈ?t/+YhHЦ$:֡5xT~g ,-F CdJ)4/H ?^ qc30bu?erχ@vn4SWC6'Ot[y#Q>_6aҲ4,D0)ޏ~ABY =/zsWx*z1v&!dҺaPI c1t4y +$I EZX^E8j?!mcgn⺵/uD$ҡ62ݝ6S?c[ ՆS_Zz|.G~~Yһ.X"{S]l[sIz/y+v$~3icW֓T5z5xw^G RD$#7m(`0(zʂ]f4 .!6ϗu Lt] FW¡枎50B}Ia[>.<10. XĄ*~OA|8Oqzc9  @cRsTmOaMO?xnpg WJX x]9hNfshXGyp=\O86ŠS=#YAhQQhZuxI"Jn-w>_l[mbqbIty!5XJ0`_6RP(kR\gD'LgҢFzX#>*?DX|[_bR@6/wF{@E̒=I&1UG0% 0] ́di$jcۚ\ƚ2H>H;V/>/uiV6@",l]9Hzq(95Ƽ:7J(g8D4ڧaZ.D䘥8maEsK` foT~00S)$FӣrIՆ87}mxKx0JTv\簠X>|'҅ ȭf)e>KڍmďqbS0;^Z" ɐ}Yq}8\%&=!JꎳŚ®p8`O\N5 )UT+f` 0tnK]~MAŸ5CYGdx4 uܐgVxh{$U_$ĩ+YhwuhP 0G=ӌъȯBəcY] 왗q%7cKpah`oeYx\OfqDU~'{Snep4'7!S:+=pB`w927pz`M8ё-c`e P5sF$~\;(%Иw5FŨ uЭg`mϫfl gxw?9OG&&ϵiHnW{0r= ,9#T((Nj^t!JL_[ kwpgTI!_?pc{ ԕ;lz'3FkĞ5L<5_I#37LΠvn=o1M8W?q5gʾœM ?$+J /ҭ}p8+Ӱ)3z2QO5SpBʴ}}CMaU~ǾVc`y8rȞxt1DfbgsDp}ƾnh2/ Dp`o@N piט㴬8CE(cs/W#:)Lj[bB aXRU,Gnx㶘%!9 R'iPpI\lH_f9VBjR;@ǵR7[a3/N0řxcCfcGD{!$ Qs&jEYuz"K"9)y=оzޔ}|$i݂EDkbЙ$]—lq iXⓆgZdQx9Y|;DlB;f44qj7Yc, @`L,Rl{ 6Ux .FbNX֑ueNd ~mF@8nƔ" *`ξu όF}9Zh`$;wϐ*xKQ1d}9  tIC^AJY+E͓xz.byfB G9+ ]Y?chh`)C5֢W(R4J?ФAW" NT~ߣ<=و禉+E bZ8d't IEb]EPpJTo9eAђmy3?v۫`[Iw"Z~aXjfo8m(j7' !2&C@X!~ Ld{'lм?Xc>E!?#!_ýY8ʡ:KTſQ>=y2kT]I1?S4r6o),MqW7:32g:tZZ a5y /oČ:򁾐x7 M`Xt[wn/H(+L /5v;bkk>NvINx6(@̓5-*CK{0˹C0 8SwtJb8Eh޾y :DކU$6.=IS_I—bݘ~pƚ>U'P+vIN?g?t-ĕ/qun[lkb _ڐ"YrH/XFIUqp/;[`:uj ܻG؋aHN'@z_L`våo)5;=JٽKC"RY`eݿ%ƺ\OAsOWnr:./KF"kM:vwm) y0M1$UfZFv?\37{ŷY}p#,:$<[N(4ї4m 5<N)O.09,(2-p}VX~ch ~=;46 3q6%X7&5TpMt\j8@~"xps-[qsD c!QAТ06ASie> SKؠ\'saMgK< B:~.cm:t31/X1qk>].@*{b_Ơ0xeUoXbNaWF|k!o읗=e0"+r ~)+ߢ g@XӋ8^E4,6Ln1Py^sW{pf f\KAcY$Y&;R$X}/Ǩȭ@0la~f0X/6N2dnjXλNjaLD„DdCR4Ǵ2^۝e2ʋX0zuV =XKݹ Ҧ)2ڂ=o ZD"> q5FYش'2y'\ƶjF/'±J/> 'gV91grrR58ᣎ7Ǽ{azg zX}V6]q,' L~c+Ạ?HnN[7ֱ,gF0{x\^./ @_Ȕ>p0۞Êz)qIPE8K;xH#Oom溞b{{{L YXsgrC'hoh4;hJI20'#6YwDqWaIj،c8.%Hy R!-+!vJ&"##;DD*EƷ޿C?@U vh $1L XTPrz-W6-7XBo<o3"V${"Ƥ<6Rvϱ(,@>^F%`WM*d/EKRTFu(u9-!9_*9;$=o?^'wLQ,[˽:;x-7fj9N{Sx@Ϯ7s6^$9H~j 砾]Y<21a!:7`Pq{>vf-o>|5p{Cs2*ϼe b J*/KX2tv:@73t\Tۈ/ vrB\wC oahef5/0CsZsоs:&/g1ȧߥG](ϻT8y_I[8AXTC*Ye85[2"c>}w}Qr<{Den*9]DssWY\9%@?Is-kIٸ2iox++"< fq<-E~)W gM8d-H(,rI mc_`sQ!b0Ej#CraG;7*!;;dţx o_e9 20QTāzTn.Z3ƣ K 8}U09h8's+vXB۩2<W}x$UcZ2v@6HfQg\H!%|$U5TrM:N4Ӝ:>KHyCz,EZJ4>FJy^Jy')~Zܖ0:nU59fTQE|Tk38A2y}O$ߎ{x\S),i4ULp ?n:陁9pm[l㼁+s55 syItwhfFb;y9kXBBjXBZ~?ζnügձ5Vg _:͎ jG*~ۯb8Wz!Y`/S qX3lu3t9ku(cz9{8FZ<$X<:=bmVt/7QLG-j~z<_͵g?,4yrN񹼗>圹 #vAz)yi9R(%AuRεQgvIs6 ]n8k)R8`abbǞ3cVFFWsU x+6 4]p.b*ݞQ#x>ŏ#$,] M}MG6Si/~jz0nJJA7Y22+l~qQPW>  je!,.1:BXdf o Q4Gdz<e_E-QAG9ƹu.==|\$OJ (bO)i;,Ol\Gu 83T4u, \ӹ }DF#u~I]6m_}\Y$f\j8@cQrk *&ӎ1\اW!H<֩ Qi wf76׍a]m8–b( [bYJUޟDˌF3C0\3W6q*N tο M,%d͉`%RzҔ@Ƶpf :^@gVҧj@([1JKY<~ONUg1= ?Gnrn8@&PUj6C$qѝ}4|߾/l]{^f% OϚalSn&6F8ZǖљTvϬvǣ9.MQ㵚kh&CX</#p"W;ih ue9O0ofp+zɊFb{ qZqibP n\SO1-kn$1t4i%-ﭗhFb9'#k)Z!s.νN=(RWpjWY6]♵5cN <碑G|e1}Sy;kΑ~'?7shgEhD*33_:/ݍruJ)-=GWfNnVҡr\eglIpOn>\Oӫmw#O26%g2ZIRуyw(rsYrV<ͳQ)[lS8}{ *c*Ϸ>7rb{Re}P@PŷR )1=e`>0R(>}4 NF86F93WG왆5BqnM`1pl*ic^5ӯr>KeIt-¾Y[򲤠h-'( F~'Ձ.nem%Lh[1 ?AcR9GћaxWQkR$,"'\Rt?Bei }ܳ9sUJ[ iȻJOhҺΒPEJtlQ68J9>4GrJ9Ct9W3l%^,Ld:h[z6|:k=ky 4Ga4 DBTqTT8CgXWvY16J !zm6'bS1nL VeCh)w4ףu;~o&8Oo;5A׬$.n5vϦk,t+-TæB>X#BQi=^@i>_Ja,#<'5++Y sZ^!mOG:7S=m*"+ܓ+iI+zU]@s6^ P9FBl:3.|}.9҉W7(x " Gea åTq#{g{I-LEmT,s9mJ`\ ZUq# n&f2 !2b Mp{ 8a5N[ Lg׭DTdn}|r8AC 3 zAR[}aĶ,f>NX}io=4=blļ\r=@בʧBzTT@g5Iy+j> x_t4/f.ٹ^KžrTPH'hpӿSÒ[ AVyðN!+,1|6ìf| &m#g%[B,'t)J4qU}珻WW9W7ٞR5Oߎ<fBNzv.eghA'kwŌ{ `ҸfLu$3=xPSmI>܈sGƱ SoGR{7OlƋ'y9FNу$v=H6 H9HTsILq֮LK}<_m<') DRvë|O;Ʒ@t+hW_ D2b[f4LW7m;Hl<a0!α蔌vC̼SЫӤVLH:vy6L?@1]q5qdBy$>\<9ͨԾݲyf*OQЧ^ӃVEX#%9'>cv_co^fg22o.V}2;1;V0+VV0F}G[F˲|QUo"UA u7~ط#Lx^}wY ēCxӺ~"2+AJ\x7jfo*b0 glj<+BsIt42 ˿ޢň[ PsQ?O؆BU#,Zk}Eܧk_S `,)F| S8=dG?T=E&A89JKy>8Gƶu.4_Cͺ93}J<6l &zRy\ z!&+605[x(3u}f'2AL>m'F F}/6ĈfdkL"x8; 0hT46PkxgTc!Mu:3Q8`nTvhu29)} pn}RF 'G?8/a;l K~['. yNgE_8kʰDzbǰBn 6] TPd'K`) E *a=ǘ^ic0|L |{.KLKmZνy"N, !חCVu Y0, GJd꬇SFAM}`7d'\^뙏HQlz&xS9cb[+)$yHgSm 'LE}YyN23f*D˰Zƅ^>acX V[tT7+vD^[G,:K\a#8{|Eol2Z_8cYbV'K l+Su<6@%XsŒ4E:mp;S|TAf1>c5`4gh)+p8g@*c 0o;?l/LʀJ(}o*9O(m"xlҺǗIo\PLcǓ4g-c,8v .Ri_KޝVg'v*D=;l;31:Bj?,~Σg%;31hH `~eab`WU^')x; 3![ Yա1qҘ2\Qrũr9cqs-SPnC/Gx@mnGy<  ,C!:XXEq%=Tİ*̲D >MBZ%B6 { ,5ml/4{\5}\@udUNC쥧f[Dox/UJѧKtaDIM>54xٻSgS==PW^P;TYJ~! p> U ޚ\|tِm'+~|Ձk SZM9JT!(S sy̼x>G+aP&sd"w L dm^31|χa+FWOޢDHNTE.ʌGI=a pӆ-c!_f¡`[09| nA]'LP֩le f_ Ss-Sq'S4>f;%' bi`}}t~y y@NZ=~lW9WTBY˞M7p}҃ [8KPZ.վck %m %y~9٩C똰q#z3xBd)x3S6 _J{&Fnz oݾ$RMm=<ϵX7fQ4r_Ng?kn|Ѯ9p5<;k}UO ۳ caHFetFC*GwiX}Wz"ο3~3?0Ƭ9{2&es4Ig)~RmٸS԰`(TG:b÷*G 6P|1ݰ7B_`7˷bhAxV]9r˹?,@<=serCYj7\\7ىypY@7kO&:=iAZ'hp9*Rq5MzCZ_jh^?ճ ױ~cQp6r.A.,T]W\q)Ņ=NZٹ~+ckp5ÂvXuΊg";27˽aޔgɑ< EI6/a pqA+9q]yaO`@n7Ka+YQ"c* )]$>ž*e=G ZL/s4.ɡtz1< x/HNEt A7 ; ɷJdpžp*+Ba*Zaٚl}c/ﰌ#N 'զf!QM͹ix>_"#^Kjij^2med~ob; ~$z>Hƨ/Yn(B~bsD㧘({R6Vzar=ܸ'뚰gjӠd$)o9g` \ZgVb3'DvǽnWHB$CLꄦf34Ⓡ)"Vlgwt, QpQ@o9h 0v >{E s A*xזvm3P}?WmGƝi:sq$k .†kp! lެ-,/mfcvA1+#9j,c4Rjt U@ ]d7y tzqC.qn} }f9нtxIn. E.O%&&Ǚ-3G[< Ru9udK9luh :=2_CGg`r$UA|I0:91}b\D{@><[n5q4 -8C(#VCIZd-n&9bW#LNJ|SAwWhςX^؏R᥻zqTcrlSgy?p)Gݥ[VAێI0xvD*)V xF/Qp\3{9=)Zsǹ_f/(eE漝Akhfc+JHET H’-fX"OQsp^q꜈?P3ϟ!3eV~geBpΗ;+Ark3-ﰄbkۇ`jJME]o@9!"d0c?y̶Q,hNq;,M> {Tp44l*K}͎&J16 ]Ex)3&y#105X`܍73՘MPD|Kb)Ȳ{?xzCMbxgFITLcOTD#m#E4/ZEs6 MB'!\g´}N;V%N&|͂$ܰz[e(.тYv2 ~,?CW$0c!HG{hYBa|tYq?Ͷx.aK<Nĺۆj cA,a|~> cSL<3RȹWCkS㾈]Ž~1a3p)*P{n Tw?SO;_,l?T] *̸NnBHgLfkF bꨝ̓y'yô{Mٗh6,YhV]{yy*Y7a4ǣ3Q]&&/a4dkp C}x0Di0?Xϗ x/, A63b=[ ,CWSTĂp>WuR[̫-`玿qJ8[]1MC ts%ƜxrO;+>%mvy\=8}6`cZ%l,tw--J.`p(Ue K8+4{)]H;A7uP;gӴ޴.Zso1maOѧKT k$dg0ώ<*uX_LW3]pT
"א!Y)[Ϯ++0/++N(*0 3~Zz{pn1dd2YNM]d1.ҨTzf=,KEVȞ^*%Z}~=BuѢ;ϙ_"$r/༨S Į"ݜ+&rjeҎ_p!_6<5NuT<ა,(Gocc1:2V;P,:1A e,(0#oo<{5;Kt8 "XqVz5{$Tڍι9'b< iʜCm^zh!5<-Bs3\̿0 ! *M#uc6z찒?+U_C\$(kkOīn?@ONvt \O{iI 5k%P1ڼ|2hԨTDo/9:~XsyĖN =`TNZ m:31Rb׌5FDπ闽F2T,kHxg,+a;@MѾEmTj/ƏЎXZNhʀ_Tb&P F(އ3.*YŪ8/=q{(qX3 mۧ\Թl>?fc-8-$|7ŏ>Xr+^Ƭ;XզF=Ѯ3L*bi Ub?^|ng)XC%4ӿut_p!k&. u9JqK=cI\mB)r-e; g#]hўsg" o7:h& b"!~=hǃ/Ͻ2 fڹ,3 Yo=F(9ή-u1K}װ.Z{*/Sd%Z5("7R6PCdM  RălA݈jd:ܝZv&\0:UK /gͻq$׺ۗUjyI.yX@/`ǖAP.p &ߴgHLRDV#12QKD`(]'yz JTI2APz¦f_4_00 ,ko|!#M⮌!D=U l?'$QX{7gue5799Y1N Q+mf+^O Y+ dG3^́_U"!UԚAl` vy~XtVrl|Nߎ&iˋT(B'F!C*{>TҰ5$WEՔ3M6ho>q N Ӛ ͺԘyWs(z\#[pkhrNNCg:Gx|FB7`n$Q2_32w,jOǾ۪*e|xq $Ēk!'}w }!KW0g|з͘lIȜ 4*-賹2|#]jjhBI)4RydGe44ԊgiG-Ϊș>b7gSFGh^Fl}mYH-z)54aMޝdB-E;_I4\]Au o 6|oL;#)0<ٲpZ3w> ~ T1BEʖ8uYX=v(3]]rG]=\T'L2>":x;́kZl AEY=,=ދ`/CI[ ;2kl?rm/b5Q8?Ua< jb`2nXzb(,vN 拤J Dz#/PTD^d8Γ]~zzQg,'OKϻ=9I:3\=)Ό4"&*2B`qo5…8wsf0坣燐#kr,]ËࢴKb1ZNnl bOf˹Z|WEs=3O*%CFkCN9vD0mfהCn2b,=,h-k3[19_Y=7R"$9yBMo:\/FlpTF@3V͆N UlF85ui=RdtkaYϽJkrP͍;\g(%f%˭_S40EPaH)6X[ATwvdAZ,Rfѷo֭-g)?y&~b ^QB-7(!?,(cuՍ3-dtjzcǡ^1WUDD +xn_N$S&"ס{p/!xm="۳ܫqs;Y8P܏-=>(#A[I+zRXݯ\Ù$Qpƿu?3Xy6ݶrt_0]lIy?@jU!nd&a1M;;q?>_S9VȱG jJk/6 07/Xo.+U_Xl_ [qIG F2N퀣d\=\:?Hv[>+(ǻ/Ju .Ie=lQ?9|蕁 ^3C7cW#'p_YMyv=-Hw gmܡc{ca꿄 ,r0>EAZ'hAhp&QԲ.jl4ȅ^8GRuw[TE^:1)).o)Z2(אΔ[fo^s".mU}k6_]؊pc@3I3O_FZ:3UPvZ3ݑG{҉$C?5%#R$ڹo@Z''J>S.f5gR)G/F7ls$vVMm>wc|l8'3 *t;CIK '/bvc$?'I$2g!{RXS/%eL_r}3l;D9G̅9,TkCLAxxZ{ g\u>_Ta3[ dDI\y?J#r(֬w$y\}Pם2?U|*̓/Pq\W48ksg)N㤙Ț3r7Og]3f@WImgi/52N#ȇeУkeAoq}*TnE:b)[+Huf ק).̧b_5]W Ხ&?nm,#ZhkhE;~:ō9+ f"Og`cG"`D';e$ f Z3N 3Zq7̔EzQQȳU5fPŝǤx\->y~kg1VX}N(.69q|&eMC@0lvRI ez̽[ zDPş!Pәpy0k8cv>3)9tp~\a97`Mtq-an d& M{i܌"GvCzDl=gp(}{q8+yn/w`ޕGQ@ z%"LJ?/8ޜ8&ێ8TIsIK43OP?qa/;XXaB,ַ MkXw*s xah /ueb8=MIFjH㐫*?&x ߍ'w,i9Inε@x.Dܿ2G ̡41\5cG4C}xEK{=Iqe u(s RP}r:jϹ޽|LOd yp. 0KmYR1zyW9p1.54O}H l ʌ JQ| VU >G!f("eZ1EJ1ivf%<ミ-n \8DT>PU@fm <3}1][yRSmők,aYԡ,?.bUޟCSyEYʼn$6?Vsg&/CyfRc(^ C6n4dwb0bpmH ,:[GigG֕ GUd5&*Qn߹2:<*&WZշ.\ޡ&~MMseܔGUqoW ?m+UWyNË1|v%LWU\+q+gEuPP\}d2"8XºRw(qQ,~ɽy cXw/(כ`TNFr xmO@*Yν_&yH?Hݕs{y~5&pP<}&L7GUĹ7z؄/(̢&Y+kiCw9NF%ck$O^mg,KeІ;{t"G 5COri'Ԣ9ǽ*5Cvan;Xgom$H1@~ S4U xh9୸Y捑WxD7Y5E>2X:X1is =sW7\Ȫ 3j9?'ӕg_4 󡇋> U윗웡$KcsrsD9I^gW8Iqr]ە<3;w%ԞjA<#nw#<~,X^1OdڿctQrbkaS:[,÷s 7WA/~Ƨ U1,,sxXs>^JaK<ro$:G?q!l'ޟ쫫(Z9M XO:(< ݬ%P_q׊C:vI ^nb׿,8p ^\ E`e/5r=SC ] gb+a6, =az"I2.`ofdx3 *jcit=#%]hDY-&,\ k>P^AsÆ{$~ v+ŏ,F*1cܱie< /s4Ch5b75C0{$?U(ΖB h \{IުP &YQI̕y;dt-0߰/s& -pz3DxVyw67s&3\.9kL1 +k~QΨe:v>~OZIM'ٻٽaVú,/ΡE"H&~6?ßєiJr5SsI&2 K1h7Assҫ/԰3>i.Ϣfb{jmaӲDZ[a%Ƚ˾02_<Ӛvq}SÂJ,}Qi)hX995 ?Mk8 /VeFL*8,g:JnW.ƮX O"(>EdĒ}s7%Y_X9 L|"Oؕ-:Bn@=B؛ŵqv='4ZRWM&a{e7qu)W~g~WCg<,1ys3JlpyN՞'Ot+^ ۈMSf3oiTIwOԹa4Sf#%ZAdby쥾rplF}C)WږzX<-Y0ȍggS׽sbc ,Oœ >!F`y ~ܑB&94P8~HBy6vdUDٓ_:3Fl|UU2SE0ñI = {h=$_ }M_f >G$hr_o"] z~"Ug*;ʹ$x+pѸQ*ݾ៘;1pYtQġz0NdгH -8,+^F"iMkw|WJH$c,~Wvqo u6=?3bbT#=gm`Fl, hbG `cpsTTbBgV)oE`4hRh<L>9uea,:L{`70=;z(фST2t`gԾ3ccx!$`?&p-O%ۧ4G\k(8 =;xynު:SJQuh{[G*S.MoF*ҳgUu]?k uo+k"&ҏLǞ`ժxowX2vXwfx=Fa|l$˰B!!, s&޸͐ݾ-Y,} nC3&B$D(/Ky[!Z QU Ğa9d?\Q*W?3I|U@6yp٭qE߂ h\<6qz'+hV>5JȱU蹓sJ]y$1@:vOM] hMJP=G#90Fn/);~7ϲVńIe F4{Mڼ$"@'{c3w ui{&)x%J/3%P[pjI7BkϥCqgaE`Lטa#8.\БծnIW"vNF4 j#!@L|vv\2E[# /bM%oSZj d '1'l_=E|_6C\OsؼdޚCR/ ˃~M7J ō?),X7ۅƖldM?;shlQnO42O0uliJD [f  㴊ɛA(zA('2tARСOac,ߘ[14c(n|>?oչx~XAj8 lOl]0r>4a{yΝ-Ϸ9gn iҞs񫓏GRaB=N>+ ma:XV(@ ce9Nb?Mcl<׃S,wjiCv5 a>0S3uQυb2%~|H~RL$TFSvW=Bif Mݥ%s7{Z$H GT85oy}{JU5dSK/bvK߹hyD`vdaU7l= Yvr<1w ČZUu` ?7Fخƭ|.LUL+%d8NƺKs$Fd9'cX2'Aghl46a~?zr{x#G`8v4K?H7"hэ |\vN( ݕ@eSʞH鈧[ le!}lM)Jw_{ƛʅ1d#JrvSP45jF&]L>M 9EhjX#:>ǓI}|,5[/+bȭitqf1՗f0o0a]i;U Q&gyN x܎Qh?sl # \}uR5;q4^ yƌ>`&beRɯY~0YU&i'{-/6@Sj+8Ƒů-%#YJKuv <_fat.b(^v2q*F_DӢ5ԼL{Iv&HzQL0/Mcaw:/b"H`>x$feed7Ŏ~l0H _ZF/n!Zީs]D]1 /OB8F#%?mlzS?u(͍.Zgc;}a8h.(/hIl+[fW}$?=b Fow _kj< *GM0;ބalP*&,dZj|1ToB&% H$Wi`*H+ܥJmG1.t z(jt,'L?!M+O}D}f.嚓'M>ToHl.i?c5!¶m&+NZ<9ɬ ɧ\Sz v%=þRDX2gD ҆+YB\_:Xcw»Z=䡯5Iଷ2l,O\#hLDY7*ՙT8rF-CcjkU`֨hsnr.c^!}CW9zC<;"2GR={ʇ|vRe?DOܥfڗB|H޽>aM]DBK7[ޛ:7dεZQ7wT #0P|(G!-fz'n \'7Y"</3;Ug=ξ"uȮ}dճ~[Yh76u~)ޏ O{*Xy&4w 5vH z4EɫI_لG4Z5,^%R~ܞ*2"*'P"48.ܒlY.KٜN5`l.F$Lc&/q!<3a%Md+ovQuĘMXX[fSv'UuF0WI:9f7.g?6 +8 -PibWEd=Nq4qs8x̔Lad /YodT1- QZN;ݦt; ڵ3g.t5itp`E b&O1E-t2 Xy%o@v.=?s9te?װ# Y{GDi]I]/_i&ϸ+uwBM㤔0eǏ)F?eb9{KJXg1o-b؍0|&drb"{hL;DوVlڮ]LVV5Ɩ#pߍ=&Jly kɤ.vF /ubi QEs7 WZ29V`~ήj(_Q 7.-ԡo ҍd@k|7\!-UO$POiVzEҷw{9uʷR V6fw,X4b ]`ـ)&}]^bPۺ3,j6LP}.odHMz6A|+rUU*ץ^ &?[y+ΕAg*tڈ.{\mK똂URcٛHSAlu}{ݯ3]Ee; Gu/(P9KWҨ| |_eMg'C\@wNC'zSN2Ȳ" L26<<ʋH*eM>ڧ9%aᜧt΂~)Ol7a&l;l)+$-EG8)wc٠nЙ( ]a!o?b~ϛX?s5psfBkYi9>EAg1(hbWp=Z !90>:!c?Z{?bBB1ޱœL jp{&=&X QgOzy;2y4=_Ͷe3ײnL Ni: '92ЙGM(5NԷNI>:M24U->KwcIddרt3*ZъF4k7=GҦ\k\@Ī)`D(\ :Go+ש9nF$ |#NiMܫ_g}jL׃V8=.qNFE YN` ل41ߋ=+]*yT"JgZ)3<@-ɇYi&OF|;'kqخO,?m!|/GƑwK.ÞsƬfMC!\EU^]ƞΖTjAgWAA8WJk(Peez;Exѳ ӎ 4G2-=wHŁJ C9ә/3 ɧ:mH!ux2cXSLJڹ3$?SsqYӼ!qtm2 Lu\O36sY]xq>iS$bn[EVȍw2,Nqe]E2}\&N붏b>uvj1:acCwg&V/;h8e.7ID4Zorr@2ڙWЇ6ab)~Uc&2Mu.ڀe{hyԞ>|JSs]!ߡd2*h%݈COH1YGIlM 94ݣ- %4z1E?ͥ;LnT78 s73,A9bȦՎDߏؾʾvr^}!{/%zI3ɢ]Ȩ[?\r}iOI"} :ѐTVC7ߊEgTє]<ӆܣ,P;:%/[ؑzJ %k67Gߒ|8 }z_rmAʟƸВ:l ;B4y 5Vzӗ:,":bZU4ۑbaO9qv]$*kJ%49t;)1XQď2S+>T>ēKʍg`oG/dsv74IPz7k)I-5J7?KZ8яXEn(:YBetSLcENW_$sʤ QHJ<{uoAyL:Y͉!O?\C9؛ȇ,ݦVNcڔfsd:rΥ;B4:N6TuKC3ưoy& ` lxJRBi&Z{6# '&&TFKBqݾOGGgP nσy&uy\:>E,Shl2uhit)%Yua4a5$dAuh\>e)*49}k'Ple~ %ܻ}aN:~2X[5{u;_NZK8DŽyR`@+ ~}0r[Т\19[KgoFeα9;l&du(`eiu8{jK_Æsov<.tQqA~*&$=c>4ý9s[,X/Ya'L}=t3ř0ϝB;0r0xMgٓgױQvZqz,oz&+̞y}~^r?3Ѓ^&C4cT$]OSD iR]} \Е8h`=:#` 9ȇ%8fTI! dx!s;G<lѭ>#/b΃PA,$Җi3f\}AeZǪޯJSXZ65 gu<>6`* 2k!y^8-ۀ!ol6OgE*JV̏4[ArhOҭB^iOӽ(]nN% M jŗ{_oghۇHZ%Yn|މ avݠV h;S#\N6ӺrkV ;S\9{ɣ$Q̡7Z[^p-lXk FGsZxMccdY҉K'kBEDy`k޳,BC7pZ::}"3ˑ}rlex=zNJ]Zg7eղ#'mM8i @.fb^?g{ƿUds#HxQؾ빲)N׌ϡC"J^ң*kWVKBW ӅޙISL:>ϡF|=O| I~/Xϲ">ŕĵGg*~LLm&>43i> {x΁*Sʐ<_~s:F3,H*3yud΃| #v9PoB LY>יg JzESiK%zfN#Q2k^IN4\ؐ֘dxk=^H IˎJ呬H&ѸI.Lwp6J& Ntqֿ_H xai(:N3(qj' +'8V@u2ht)O9*ǵH#Y e%ţrj~v ir_B9K)pRȳ~<.Yozf\OT|jϜTSq^L$0'VFQp*~dG4ҖnzdN(;64ya s<,}N$sbs Dq(͖6/@'?$96L#+dMNi(OZ‹;5VglSL.;IІn3ZAt3MB+\jz[g+%-gKWqiDI2K!KPi%h(DBlٲ{w?tyzY/H\(yкWʆ(Ο(ڔ7)-&l.wl. R|":bϒY}hO>24{G Kh!DJG>现Zv*O,Wq`*|ZIc7q{VϩTf :iUqؕQsJ"\޴shUFAr7?6%^=r?I70?Cu13o%l[7Y889&4ϖ=k*]!_L}KWRKos_;*=BZx;8fL5jIc$[vgJdB5(=[-lD G/aШ/69 6=o~Of,{N}˨B<~mWie?J[K5_~z3_Jk  9Jw;LN!92ndh )}W&R@fdzVF欫_"#_-WB!ګq Y!|BIy69) Ѥx:b:@작yM2CQ#G!r2nD3*g$.ngWQ8=4V%/:>2O%qs{URNN6}^u\RB$bl}gB>}d7'Vu%M[sZ*rKY8IQ&Vfѝt}Q#lZ1(#\SN3~RF0d9s&;=O#CT:  ٴ' \oֲFQ7 N&Lˋ}<. kq*~HwoM:]TB]S1xH!YB;;Z(O2kg/~B9Nx |s9?7P&fi 6b!=t, WVf2biPH6 N Nm&˲pZZO:qu: i~ F{G:NŬ#72nڋBm %&kfQAÓh*he\zI罤 \;DitU5v1&ҜGcAe.]LmX5{Yߒ8ڝ[Ek]I]@[FdJlkkEԽD#礊a\2_Ծ^xO<ZNa*gċ46I(7 ]%Z*fJq" iivqv@5 zoz&#Էј4BӖH-n pOVsx oϺe^XqcN8clxs5]ϕ1=Zli#j융bȇ-b_W+1wŧEP@B[#~L,7+tu9s6Sn;.`O8R]SNGbH>Exp -~C CeJ.3 5iH&N;SYG׳3I9EJJpFQvv Y'S"<{;:6P8720--"}ۺ|oQDоN9à Ecg. 7X< F*ubiwfMvf.ȝw[LvX8<,my'"E|]1_32_%68?֖ы_EtcR(mmx.Oġ[X,^OWk|iN]!'H}yz1ZC!m,{%H=͖-˞&ӭG8/7ii>CCLOѾ?z>qx1?/F&n;NA%*U>8,c{+E__U _c ¹yEH^_M㏈ųP7b.8㗍tByb|0;#]7]c9?dros2ve+U;BMԌN(M#د3FPuB19^1 M]N5q>Lf]ya\B7w9,YЩx)WTHc0ɼ)ai䵪_0{|b8UC+c\&ӣK. r|ܟ|'NNv+Y;U$uj`:ÏSiB*>v=3h*U%2K1wAi=?M/F=g gvO*k=fEkDB>|Z\yfq(c7]9"apQܙ =nSpY 6;a=}-wkj1+PhX=^N]YC@z֙=oWmzx\ނzl @j 6cܵb hQᴻ)fyt:άVq 'w౹6f''!H)6߼H.wALCm^z#9Z8yJLV$"Mɍq&׋8p( !.hj)2^ȈyEΚ ZB6+nG b0 ʘmi3mOpd+T#l|1Ebp=EٷYª[3:-ꀹ{`A8>]+{( hZ߾Օh\wvwuWwDߪaZS`38=aFRd^6ڏvd~O LFЮ[BK1I62'ѯd3d9{X[FQԶ+htb%ׯj-gvaxFc8Ժ9tGѽ/%qTĵj' *]IŮG_!C{'zRK ]`5 =fL:ؼ$s]Ek?Бp3ݔd08;BZ"&ǓLz$K[lۺP]2,ܯowfxK>{(Wz9R]tk{]a9n_ *8ul,fjci:mcP~;= EMcT˖B(O>uᢨ 3px4C4(bg* b. z;F?^,h^R1Z h⁙w#_(޴@ti,rhM)b04R.=钽$(]g^޳'-epݶiքF1טSH9kR,3x");y B?d5c9{$NpjFRdV? n~D\6 AX[h8h^0:si2{irQayU#r\8 DUfqz s7KbV;BTUzS:@ ^ÅUևp{PzM5XmJa|8PMߓZ =UO+"ə|)jhGi y;ٿiKt25؃K?j#Zۚ3`*T _ tU'Ӹ.VQq$v@6U+m/]<G,@L2d'g2T1%ѥ)kj2y⧒ tއx t\7.5=ZŌ4zb"Yn&$v&_ȓ|G1Nȵ*5._Tϟ8ތbA[BݩNyTݻeHeyoӺyz<ʓ){U4m@Tr Flj p=e-?E*ov#,mѮ2 ՠ3z2z :ph 3Dϑ~T|}acf 8yj&!߲DU$R\rU]p_^ȴ[Bk޾F>#˝)a$NyktrR;?6HE%"2Z{œnUR`II_bvlie#߳=i uf'ۊ4/DC @ue?Deyź3RhΥ4(5L+4R>fGv>lR"ުO ~S>oVccw'DՀIѨUń9 `do¥ ` f vgm= ۇ"a8n>66ű q6zt H xl`XX7h܁c}zbb -Ib ]mo(T<%`«v|eD\ǯvS;-g:5]>H%m9y6!u\Oѫ_q+7Zmε.J+>d1_AQhaZ-"a\Hmk7yT5Ž[(h~g L1L|OkU £/s?:w^Z0 Iҹv QXAvN}w2zFl(+`Nl7}6,vc)~ 1h:L[GmJ:z;s.Qn ֘*Cd֎gǝ#&!k X5c!#R0Lb4vDYS9N-/VU]@i$<.{PRI']i t2*Zt+]úNuͷpp~||>fHց|_,xyVIDO6nMAm%11C@a{cs[*V;2+M۱| `9'Xk CY8<6p_k${lFBz _Gіz 0ܬϖ~;A*b6t `t ];}th7JN&g%.wLDMfmjfz] ZE§u)<6Q3]?9sM:FH|k%%.b}?J2׶G´lr5|M/wVGʣ1c"\Pl'G#DCax|Zka\d0-HY9a4`E3M_\o? aoD zCM,ΖAYn8k{˼Yd"&蚠1]ec iDf-HZ܇L;ҟME%=Lmbꠚ@2_nΡ% @M!<+5s$02{!3QtZ)VUQ(X \Cѐ^5qf}M7+%WxcXD3DW9wʓb`S.`?GOچ{UYkm m'D؎'8 e6b AnLgh5 P+W߼O3U4K Jgv.śwǝ01#Ii|56Ҵ䱹<֞Qi/*G(69LzƲv]pQXf? R4:_Btc d-jbWW"ߔeup8EoϝH}d Ь [>> '7؁]}+<Δ8_hÞkd><`>4p,ȞW.GJ{_Dڅ}7!i'_(?Tije"g3'`jgNE 㫝8'ף.h8rH`$/</֮n(zɬ[FKhx2 _E>pl`,bv4ϒoN!4Pҽ4mqm idu}처4zb$֋}YM*Nӣ5yoIp=GIO9u,FGT ^( FL5 լmu/~}~K t(gcQo/FXo WuU0Zfrb7clGEț|޶(p ;|qf\pGe{G h\* gta}hblѷ6h`_;3\&Ur-^h=voʥhӬg:wEهz Z% Τen䚓'l+!tpvu-IqssY#.~\^>ΟXO' 7.Aq=&ON̼2Cb]1)_֖~" Ж90H|/A>k"d]D·3 `~h ͕= ۜp9Z/+0|*ab7YhW?O>d;,NBiz(l!eAS?mcحXk39qf:-C Lg_է8_vcGL,^dRKhe!9b2,NjVUT?PETQ& cffH?\85Ct9f_f5{r>0F޵%XY8k<"b΁> K͜}4ʆmh|96 ?dWr%̶T&֭d싓;`L']m=#t-eFBkh ӏutk'^1_aߐEo/*Nof]&gCd~8)]GIYuM W#5k4 6=Euvd]1CJiQ^Ճ#ވ|:ݨ1~kˎ/9X\޿n;d'i#qGe \h@i.&ñ83 \5Pp[DZle!w\8к3JLq;ƪڧ/r*Aޠj!c*Fe8~p\ zMW54uɽleFqkktf8#ſa-ض;!~Jێ*h,NyY_\4`b_Z#u͎_Sz s<31~Q9['C&ftztV:} J38;$LvȕTPC37})yIx ݲgaM$ΛZկx\hx15w0wY]̿ӴQ^ѮƄ9˜yVb.3<>MgaЩ5'1좁%?,)ƽeY7p^g"<;_U@˥v,j s0GB-Z7$ vGpK /Cc9vGtlu/tն&n0>yM>,͏ǩ/-0֎:}nuzތ}Sit|ĭH9u7Dyw (V3<‹G!,eƤ75ڮ1,˻G[Sp q|I\JCab5QxOJx?2GWȱ;|4y@оQl*.oF˴o "O>Þ`/+g ( v0Ik"z,בXV1z/1Ω\0C;=ro1 ex t_ynd=cğ'q*ĵ !鬡.NϷ"3=3&}]DI;u8ɿN_Qn9:j^j)^=^\ 4KIXW 9/Hnz@3d7~B>y5wghG*OSL,vG=_ieTBXh) ¥oSPxe1 'tOs3ǴysQl6wtĄW0'|#jƩBo,̾`<9WWdp&v$ߌbq?viX3-K&ubfX_&Ҷ}x Û13??N}(HZC!YGIZh§bz1u* Q>D%e)BTrJ(ޠ?g8<-";<;ľi !E5?樾 #px۪i7'N>5FYwkfe.z |c{chg2m:>3 }L6OU!{FayWq1Aw#ٯ% !}ll;k\<탁֘'7Wpn౎7b؃DJѽZ7MC>6 <LPz@){=D9^34ඵ NRZe?Jo{&j ; M%4VϮd&1 LpKLơ07f̂~hg:YUZxT`& ${ɲ…`ݓ۪ڹKc\XWȞaQȖ}!`z?k4xvM͋dMXkY~Y'cIh:;;.)VpmY(܄+#P˞mol PaUznV^nJn$fZv]2K4 c5TJhvuzA*}ډ;# r*̢߅J~(]OsYic8su Tm|fk_&ߙ_S{Q>+VH7 ,ks=C7a &TW2Ε~u[m[+W\N-.'0m38.00Wc۽'=2M|W|mj>NK$l*mPɔ\T7aW|X0[tbsCtr Åebۃ^Nvb&/JۤS*v";tYFb]c+aDy1I*{4Q4!2sD3<}p4?!%sXٽܸN6H-2Gvԋ@av fW\i7J\~Y/#|D̶=m=]Y e|4 WC pp|S}e:>C:f2vVx'k1ZWayp^k6#gMTN:b)[G{r#&5`t?\0/bCCиt3Bķ GحP,ܜ"mkИs^2pJjo$DNW9]4o/ᔧytn {s6ҏX:Dھ94uaZAšqo,8,rCZ;urW2|j5L~w;G=ދ5Kprm8d:ck#څ,.K v1&V5#cO|ȁh*q1ػV &@@wK ]c$D[/3> A}xlԂt;l|':; ;AF.R4fHl8N'vؾOWae8A yv1MQr&MhXkq->~-t (}:3md`p +u(d;h&k(]{pO;E ϩnvI@޽2hw$c:-iHangM ά Dcz8)Q],~}w3g:pΣc#\^㎬V+s]75G# \_%]`!MP6ğ>lwd"uc)ϯ? heM_Tx&h/IG= l^A~x஡)gLWRїt0m 뱗ݳv}w盱HuQ~t3o;w䀓 =bִA}v]U~Бoit{Xq z0̍SozSf?uijPzI6u/_MKPœ0lgU(<{ZYUG.'#aUR pjbhm 6`}u\i\6C-?P>c]K;D}G<6"Ig,~ ۊPꌚl+,[tݦa;C]2'ɊxpHKwD =L BP^9;9 qgfmJ-av6XS #vCJ\DļZOW8ΊD0ѭZ1,ݝcL!epЭ:drqJ?o*'ߊlv} #Z}r*.Զ(.kchx{EIw(ǓhP8n ?Nn-ud|R:uJ1Gu"X*rWs,_}Lz"iQ,dzR2S 3 h*2z F.zҍkS .uEm#.jptF/(.CɿcXGN0OE¹12d. D!KغOs⒬:Bx"Oسݓe՟Tq}rcpaP'(|L1ﺈ7gAj9,\Oan{O*SkJ>kchYo}>Uy@<&:6yF"RZZPD҅W3:U#%7uwWo@,c=UBx5٠ƌЏuUq-!73J]fPNJ2j[l  :m\4AQL*Ra9~^.^2uUtfPQ =™Rfyn>As} >x76PEex :eF8#? ʠp}_ԖCO?6Ey9%)t&RfNT^$n~g&L"{Re6-!ylg| \Z@;kty: Sʏx#s)*4Ֆ NWD@DG9VBѫH˚evjP<=ӻ;Ao;k4ظ?kCO6ágҝ,嘩;aȭ7tj) ~;C&[9B8hH<Ꮸc^r-bBfpSh Qj}pjt/'5oF'>^Bc/ w.6yk?^})ɎШ.~W/BQ뿉yQo6ugO_HK3ޚ\s.Y/@!גHSJ4}X(,^SMho̭59 J/!6&Fn.zbU|1f>Ƽa{Q0RKkaf,Pc_499܎[ԉY}nz(6U ^øP~ѐoDXC!wu,zffw(rӆjl$.˃;2]nX8lWHAn-v|YB08Xh+Vá'r[42ؤn9)E\,XKhʎBQ}(YM>K(:1Quq0_1CYȩ~cJTXyvPVh7q.EzOU&f8PDE5mE6S(X*vWл Et#(a}* No'$Z鿅5\V]ApxV/`w#gF C0眼cO*6-DSrlhE9~-6!YE$N2:IF 2J⩾4u CLq9 n?0`^g܏7 A]cD a {T;;Mq(^ŕ wk9;pNQ}doeB&ajҕ&%6_-zpuWń`C{]_nը'uԴILHwI^._%YKGSh~c}*6}m$,:2t]c]G2LZ먄qSk9e[~BʩGaU93HmEX`u<QV"#8WAB{vM27F) ۝yR#!qxt5XbmPwE51Ow0#RX?X$ EhZA`!?.;l[ x0e=r5#V,K[~H>`^mU|Db"Y%T92>̞ϑY-}M9I͈nMNpmxٯ@8~g^\Sp,ڃS1n,qvi}4`t&AOTw Ma(8J8p=..᫢(3qeWN!Jc4܆Adh O/#ϪrlQi`ME*~"5>0՝LJM"e\qT}t@3f; +o[ZZ lYc*X MaLLMŠ8tm:"-xsHhX K54(2b^  8EA깤{F֠:|ǥ4~Xt}:t [BߵհnE'']M1h"\i7z l# h[ Ze&a([$"t47a8Safy8~̸:%Bk#Uy`elk*ƃ/28HC:PQH ԝ1(H|tx,z^yr,u[`ӹ'ƵFdW.pb pZOqKRĿp7U0h)j9l.kySʞ5ǷXo&)3=\w&K#y%)]@}??dEw¨VBsmdҐE[Q31kd4YxbYQ$k nGVU+w9έET2Tu[k} %'\9g+DjWlN:s6Bǎ_m8x)SOG]8W~j`(}6p6<BE ƚI8:94./9cF)$yN2HJ-I]Vx =p/mʽz+2ٳ_}Xq!om_1+W@3цߑmM`G1R/-sLo55I'CXS%Xc Omc=:(}G }upbk͹G@`Ԗ̃<|0!}YW9|{irRayf~j7 ;>?ITDCyEwh^ M)$W?sP88Գc[u4(AWCzzވ_ [jg`B+΃6M!p,=jT0Z-K0rQ7 Uې¼8\ Ikh$qO= $Tp \x)~#t|0,YX93u( 4Qľ#a R(QOإ E' -9 ƀ.ҝ.39x FwP8={{bdi0gj,jP8׮58gCX[u [Rt}F۔~$ic.|H1QM\Hց%6sΐeSWs^so|`j%lsSUaA4C4V8O'' m5̆$~BHh(7 b,&- ?,A|tz? 咑;ņgO?HO,F*Xr?NĜ6Zyhu\>+ Y_ef:>y[3GOˆU$oxuG^;hgsZ VjAY(z~6&Ry*/o4哑}(zC /vroSgzEקmMʠ4նdPħ՛͓]T{T9i.TdSqLڏTg@gy}KwI٤5_=N2\p=ve0:h*8x9$)JeQ\D > s?ZC$1 H9  V݆ZVA g,ÚO۬VvGsI"< fY^sď#j.^?+q Oó)8Nx1AJBM&/3s7RB$>kzSv)CyȿDK.9z3)3a":oMOK 9^%ҵK2-6aopvS`̖aL1 ϙ p1s1繩 lT i10 $nH#A'sEsI+8eG2p3 Y$_xp| ?wi/u_f^<'1mo2j㤙RKCst׬̎#10Xcy( }6k6c&JG`pܰw5) .H!o֏ߋYZNz#"ZIăp,- 'e%4df4Sˍ!B~^|˩a+G2˾1Vmfii81&r%5ET$}$p$="gxJ=Sׄ aAjO}++::(,9ǽ:0,Ps(ޕ}գ` S %~h4{Eڬ uo.עrYW)`d 6~}{ כ(]9f9ѩx;6$'إTNA6۩_x5>G^5qRK^=S}tҮM4˩wmb-ޘL33;jYLGLbzsmU\b73Na6#"@+6yTFlARlt&"4&#tp[cЫ+13qy_j#R"voB0hK{]u #aۗZ;"40kFqlJƕk@s*Z\xǾJcЅ9Zlf*#bry抨M2hpp7.xKv*sq).'gbg6(7:O~GΑdU)? Hk]"Pҷc3s3唽Q]|g`IF/dm@op.␾k{4ڎݮGC: 76@ x3#ձc t>vYaZYa6l_kWٹ0֠pEU*b z~Ic>r `NV9׉\(JuN38'0_|t< ǰ\;lg fom'K+&.A /4A޾0Aei?;Q_%T`Z"3[c*ԹUG!؋z Ae(97j_>[[ Ů3,G ńVd;xA$2N NF:M(ze_6z\M&+z},8x)C۾o3h봋SMn!iL++"}Vw2G+Mvw JUey`1v1n'.9vi\ hᘊ W~ORDѲJ4T6^ 0K8x҃~2lcpZ<)eg8`l!pCG邘"TLjys/- oCI:|!..""*u?ٓ<YsN}dMN_AT:eirZճy%oYzM_I kDGtHbbٶS>[nZkCM/s/Nwg?[ gW#H&6Zdp-Usfqˁ//>@nWp֗o Q {Ta! 8`Xi-1eW0kqx#a3S5t8L$"P$!p]b`)$лP ;$ϖzN KX$}(/ns %.#54ҦIa!= 3pR`-De|H9Ly+6n"nMAS.ԨC5V_j\Y=5C +IN,%m[\>ϧow?ݺ׫-,"bɵ8^&u\K} LU=˘l`USX۽c5w ~ 1}b~G֘!UQ)a>ڃ(B|K%FEB7z 0i؎'Bs ,iX!9Kb"ؘ0K'";ov%h-qNsvp#_'!? 6V $--?}Ekpi:yt@&tE?3mxtaB;h-RTL'Eh< T*Z|3hώ$ZWMׁnӀ14S&nL]tji׮T|%-]AhY8x7㶈fOfAERk-Xcy9^7ZE-HFeo/l}46 *]y4xȈAEX8E ev3wk%t|bօdifQۻ`b"qؔ a&^SK X^;渚ƈc** 8eK)a9͇pG4XhL[r=Fw#?b0G.JmA\# a`ի$)CLPGE< 2EU} q҇Cd|8ƵRT)0}l{k&t-dkJjUYHRC[FUJrq G[*MeҍmIfpYo3ptӿ[2y, )qj s!G_zGYb&_)=;>\t.[Eg;[!4l|6LīкץW+S<$!s\c5`oI84 (h往ߘp30%Ó2~hGH+76W1T]eʭL { eqG KDQlA|DyWEun7K7@~k&Gh1:NWj)èHJM`Śls>{}Nj@"|/{Q-2|?7{$~o KxrVN? 4inqprl&1rv6PYlʲLrc6tsL};އmeax:7r3㼪}G!=O;b 뉪q\y( ]:8,ai,9~2ߣ2+afȶ݊(E` _lJO~AK\?`^8, ) 蹋ò]r~dYb g@G@p%~CشE,K;k.(]*]-&ќ@Q}<,,+jFJY8́,,U{^Tc45֦:ZLk֭UF럓xIjHbTb ߿> nz$\b,ZXeBx#R 5I eК|UEU:xoQxM//?N La 6MǗTg 5mx#X|21p.GZRx?@5j_O?__zB+Uآ%p7G\ CvHPC .,:ߚ¶k`i rlux'0v~6 ߝ{ql*FXB`RzfX(<o8Zo_Sc1H-0iTWb7feHBĩPdvxrɶ sNQtGm'q^$."Iڡ%D.I_ipa[oө7rl]k^,#D|?;<Ş>kF\Q S!{\6o w NjIHz=]DEgy}Dщ5LQ;}$Sb/0v|,߰>Tk`g\:1\rE1/tJ5ΰFҝoJhZK UEޱv6zñbQ~YS!-o@3e\ Yp,|8-\ɺЗV-lGhEG6%ZlӃq ܆xfH-Q,ľ>މ$K^.^-X \?ŻS)&)ܥ? tB?' e>MЅX "WL|#5R.ɹ\N8NQ8So6E' Ob7CGUYG3}GF`.a8tMky<p^e):L8r[dFR;ckv=<~3)!W<[^f4ߘ=˪vg M>pyԻQfmBFbٴ]ut͢mEBPcF~ЃtEkۂ]dפzW *ӑsE7 f'P2oҎalq ie{0rƴ8)_Gv13UGcS"ؑfXjli \kbۿJxad אsVw/p[d(T쏂PyH/Sǣ6* ZI}@'_%FRNFCU/OM]G ]7OQ`[hewq ~"(4?/o%G9siùBä؊Y fZ9ޕp:=eFbmr?'4I6Ou vM"?E69r% ipr +v\ tvΪbMU\ZY?Cd(jc}{i>ggQ=1t`,\}zch7PAq-]o&Jb̡a]GWl|$: iy5tsM6$ :D9'r+KͿ?{I(jItZ3;J[3MʏN4V?Q;% ϿJ?R(lk<}ZZMG򩯟87MSގrI. 3V7y2c4QJ=u5ňI Cyv]>ث4Q!z8,k8YCqւ[v]JHzw@;&3:}$ g&`jSk '+^2&qϴ]<{ʎ\cd+A.ԟDsp0z -2 ^=&/s"Ve^pkNA1IO%xrO l5|HON+2I<jINȝF,%iIh>39I7f8ypYP@z'RHʓiL$;o uyG^4k =ސF*9^ԸG.6l'eXUp{g G&{+v48[([<1-I`&fr[bس,Z>3 },l4;M'B,OȠ޺m\m4SƢnY =~CTڟ]}Xȷtji`a)+"͹N[haяlp vo'ilgSwۏpڄww%ŴU1h\` m .z/O"r伺 );-}i:<PΠZ{YZЂ\bOq%}KZfaSWijzqVX4OwӔKBi\h/F,K,qqP*aC;7h y^$FhQ8_YR*Tr*ƻf1e=yr]6{}Tx\\ϱJ /~Jv}XmbC,$!b۶ٸoKIInʖ =C6],Mtgґ=tg>ٍM T>Jh헸~!vo("!hq{JK_zwGѠ '˒d>~Ȗeo+m 6X"cVR>}]LI%;ENmv\ ]bh 3ep94&g{Q}+ /e4毦Y2T vNOfSKwʱĒpjDM\FQE.OܚEgѯs%CY ]!_U=O_N)GsJzF 9,•8ҡdl:;v&՜"g>'*JzL9d=K$-I҆`[u&~,fϡ!jYy`HY8c#]|Tq5e:;߱]'q7=^]{js-e*pdf>aDSk(!?IFcR0U]qú؋_ʈNz=>r/Or@:kilQ=z٢ G8$t By=|7]uĽm,9qFϹfҒMIA:nVPSd<ݬ,gI2:Ddڑ?;=3[/ OqN-h\Q]Ta M{q|ޗ, jY oq-Xꗵ;LkQk W9s1l+yD*-V tԹp<[Ksx5HZbrw=S@.),"T[xMeӍߧ+ѫ[@Q~jun xYIon]ڇ./+Ǚ.5 sD88zC?62 ϦI\Cr\*8UA/iz[)eٴR ]ɵnؕNn""SdumPx>KJc?cb哃iҕL]<-Y;m5N@ѯksM/EjiQHTFL\JwO0#XH6_1SpigV{2+taJ5M度~6P0Kt8Ʈ?:06 3ajؠeAá5H/Fz!z@grWO(%{R\]Ztѓ\PK8=u)2cN!N5=Js}bw9DG=z} u[WӈWIy VЅSu4r` 5IO#kBF3[i\G!KNt9J.2LfZkoI1OԲŸݠ֏\SPJ'r2ﳞwލ 2z*!THCzС[aS${t`;eۚޑRs2#%JthA‘-I"o(db=?b1@0ֳn{*B/c%z@S;C+w~s8dlk,}Nӌ.F'4}6RYN}K{52cۻ)dgYI&5VWϙ'H}W+%nOf,)Π/d)CRs@0 O2̛ׯ+mSla4kl }|7 ]tz ]_o*U&a[iƈ8*Iwrl)EeX$*\uU*GI6{8OSg6}BeF7l_YAzk6BU89F8~3|䍘4ۋg m{c,SϬ 3^[&ddc71C7يc9r0{"U/R4WaQX `5DG>,iEb]mKɕT=4ܹFIeq-ȁi^jH*rOǫHdbsƮ Ӑ|q $NhXCIz:"9u ՝%i^$<,'ikm ݫRIkW o>-/kBc.g8ȍ!ч挍!_rFyln֓E]jh%fQd*zGwq!_Oδ)/ Ɯ/WṙЯTz}r]=7ZR%?H[:-ɥy1//УDI]LDNDhb6D-D,BDwQD?D#;DC- Dio D:D.Dq-DCxBBcB+BBB\BBmBBBBU'BB5BXB6#Bp=BBBBaB8B=BvBWdB+B4Be;B:B BABBJBɉB~B;BTBդBPBdB]BCB1`ants-1.9.2+svn680.dfsg/Examples/ExtractSliceFromImage.cxx000077500000000000000000000036111147325206600231470ustar00rootroot00000000000000#include #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkExtractImageFilter.h" template int ExtractSliceFromImage( int argc, char *argv[] ) { typedef float PixelType; typedef itk::Image ImageType; typedef itk::Image SliceType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->Update(); typename ImageType::RegionType region; typename ImageType::RegionType::SizeType size = reader->GetOutput()->GetLargestPossibleRegion().GetSize(); size[atoi( argv[4] )] = 0; typename ImageType::IndexType index; index.Fill( 0 ); index[atoi( argv[4] )] = atoi( argv[5] ); region.SetIndex( index ); region.SetSize( size ); typedef itk::ExtractImageFilter ExtracterType; typename ExtracterType::Pointer extracter = ExtracterType::New(); extracter->SetInput( reader->GetOutput() ); extracter->SetExtractionRegion( region ); extracter->Update(); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[3] ); writer->SetInput( extracter->GetOutput() ); writer->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc != 6 ) { std::cout << "Usage: " << argv[0] << " imageDimension inputImage outputSlice direction(e.g. 0, 1, 2) slice_number" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: ExtractSliceFromImage<2>( argc, argv ); break; case 3: ExtractSliceFromImage<3>( argc, argv ); break; case 4: ExtractSliceFromImage<4>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/GetMeshAndTopology.cxx000066400000000000000000000273221147325206600225040ustar00rootroot00000000000000 #include #include #include #include "itkImage.h" #include "itkBinaryThresholdImageFilter.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkMesh.h" #include "itkSphereMeshSource.h" #include "itkBinaryMask3DMeshSource.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "vtkPolyData.h" #include "vtkPolyDataConnectivityFilter.h" #include "vtkExtractEdges.h" #include "vtkPolyDataReader.h" // #include "itkFEMConformalMap.h" // #include "itkFEMDiscConformalMap.h" #include "BinaryImageToMeshFilter.h" #include "vtkCallbackCommand.h" #include "vtkPointPicker.h" #include "vtkCellPicker.h" #include "vtkPolyDataWriter.h" #include "vtkPolyDataReader.h" #include "ReadWriteImage.h" #include "itkRescaleIntensityImageFilter.h" #include "vtkDelaunay2D.h" #include "vtkFloatArray.h" #include #include #include "vtkVolume16Reader.h" #include "vtkImageReader2.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkOutlineFilter.h" #include "vtkCamera.h" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkPolyVertex.h" #include "vtkPointData.h" #include "vtkExtractEdges.h" #include "vtkPolyDataNormals.h" #include "vtkMarchingCubes.h" #include "vtkImageGaussianSmooth.h" #include "vtkDecimatePro.h" #include "vtkContourFilter.h" #include "vtkPolyDataConnectivityFilter.h" //#include "vtkKitwareContourFilter.h" #include "vtkSmoothPolyDataFilter.h" #include "vtkSTLWriter.h" #include "vtkUnstructuredGridToPolyDataFilter.h" #include "itkSurfaceImageCurvature.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkPointSet.h" template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType bkg, typename TImage::PixelType foreground, typename TImage::PixelType replaceval, typename TImage::Pointer input) { typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); float low=bkg; float high=foreground; if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } float ComputeGenus(vtkPolyData* pd1) { vtkExtractEdges* edgeex=vtkExtractEdges::New(); edgeex->SetInput(pd1); edgeex->Update(); vtkPolyData* edg1=edgeex->GetOutput(); vtkIdType nedg=edg1->GetNumberOfCells(); vtkIdType vers = pd1->GetNumberOfPoints(); int nfac = pd1->GetNumberOfPolys(); float g = 0.5 * (2.0 - vers + nedg - nfac); std::cout << " Genus " << g << std::endl; std::cout << " face " << nfac << " edg " << nedg << " vert " << vers << std::endl; return g; } float vtkComputeTopology(vtkPolyData* pd) { // Marching cubes // std::cout << " Marching Cubes "; // vtkMarchingCubes *marchingCubes = vtkMarchingCubes::New(); // vtkContourFilter *marchingCubes = vtkContourFilter::New(); // vtkKitwareContourFilter *marchingCubes = vtkKitwareContourFilter::New(); // marchingCubes->SetInput((vtkDataSet*) vds); // marchingCubes->SetValue(0, hithresh); // int nc; // std::cout << " Input # conts "; std::cin >> nc; // marchingCubes->SetNumberOfContours(2); // marchingCubes->SetComputeScalars(false); // marchingCubes->SetComputeGradients(false); // marchingCubes->SetComputeNormals(false); vtkPolyDataConnectivityFilter* con = vtkPolyDataConnectivityFilter::New(); con->SetExtractionModeToLargestRegion(); // con->SetInput(marchingCubes->GetOutput()); con->SetInput(pd); con->Update(); float g = ComputeGenus(con->GetOutput()); return g; // vtkUnstructuredGridToPolyDataFilter* gp = vtkUnstructuredGridToPolyDataFilter::New(); // gp->SetInput(con->GetOutput()); // marchingCubes->Delete(); int inputNumberOfPoints = con->GetOutput()->GetNumberOfPoints(); int inputNumberOfPolys = con->GetOutput()->GetNumberOfPolys(); vtkPolyDataConnectivityFilter *polyDataConnectivityFilter = vtkPolyDataConnectivityFilter::New(); polyDataConnectivityFilter->SetInput( con->GetOutput() ); polyDataConnectivityFilter->SetExtractionModeToAllRegions(); polyDataConnectivityFilter->SetExtractionModeToLargestRegion(); polyDataConnectivityFilter->Update(); int connectivityNumberOfExtractedRegions = polyDataConnectivityFilter-> GetNumberOfExtractedRegions(); polyDataConnectivityFilter->Delete(); vtkExtractEdges *extractEdges = vtkExtractEdges::New(); extractEdges->SetInput( con->GetOutput() ); extractEdges->Update(); int extractNumberOfLines = extractEdges->GetOutput()->GetNumberOfLines(); extractEdges->Delete(); int EulerCharacteristic = inputNumberOfPoints - extractNumberOfLines + inputNumberOfPolys; double genus = 0.5 * ( 2 * connectivityNumberOfExtractedRegions - EulerCharacteristic ); std::cout << "EulerCharacteristic " << EulerCharacteristic << std::endl; std::cout << "genus " << genus << std::endl; return genus; } template void GetValueMesh(typename TImage::Pointer image, typename TImage::Pointer image2, std::string outfn, const char* paramname, float scaledata, float aaParm ) { // std::cout << " parname " << std::string(paramname) << std::endl; typedef TImage ImageType; typedef ImageType itype; typedef vtkPolyData MeshType; typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(0.8); filter->SetMaximumError(.01f); filter->SetUseImageSpacingOn(); filter->SetInput(image); filter->Update(); typedef BinaryImageToMeshFilter FilterType; typename FilterType::Pointer fltMesh = FilterType::New(); fltMesh->SetInput( image ); fltMesh->SetAntiAliasMaxRMSError( aaParm ); // to do nothing, set negative fltMesh->SetSmoothingIterations( 0 ); fltMesh->Update(); vtkPolyData* vtkmesh =fltMesh->GetMesh(); // assign scalars to the original surface mesh // Display((vtkUnstructuredGrid*)vtkmesh); vtkSmartPointer smoother = vtkSmartPointer::New(); smoother->SetInput(vtkmesh); smoother->SetNumberOfIterations(25); smoother->BoundarySmoothingOff(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(120.0); smoother->SetPassBand(.01); smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOn(); smoother->Update(); vtkmesh=smoother->GetOutput(); std::cout << " Genus " << vtkComputeTopology(vtkmesh) << std::endl; typename itype::SpacingType spacing=image->GetSpacing(); vtkPoints* vtkpoints =vtkmesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); float mx=0,mn=9.e9,meank=0; for(int i =0; i < numPoints; i++) { typename ImageType::IndexType index; typename ImageType::PointType point; for (int j=0;j<3;j++) point[j]=(vtkpoints->GetPoint(i)[j]); image2->TransformPhysicalPointToIndex(point,index); float temp=image2->GetPixel(index); if (fabs(temp)>mx) mx=fabs(temp); if (fabs(temp) 0) mn=fabs(temp); meank+=fabs(temp); } std::cout <<" max kap " << mx <<" mn k " << mn << std::endl; meank/=numPoints; // mx=1.3; // mx=2.0; vtkFloatArray* param; //while (!done) { param= vtkFloatArray::New(); param->SetName(paramname); float dif=(mx-mn)*scaledata; float mx2=meank+dif; float mn2=meank-dif; dif=mx2-mn2; for(int i =0; i < numPoints; i++) { typename ImageType::IndexType index; typename ImageType::PointType point; for (int j=0;j<3;j++) point[j]=(vtkpoints->GetPoint(i)[j]); image2->TransformPhysicalPointToIndex(point,index); float temp=image2->GetPixel(index); // param->InsertNextValue(temp); // float temp=surfk->CurvatureAtIndex(index); if (i % 1000 == 0) std::cout << " kappa " << temp << std::endl; //=fabs(manifoldIntegrator->GetGraphNode(i)->GetTotalCost()); temp=fabs(temp); float vvv=(temp-mn2)*255./dif; /* if (vvv > 128) { float dif=255-vvv; vvv = 128 - dif; } else { float dif=128-vvv; vvv = 128 + dif; }*/ param->InsertNextValue(vvv); } vtkmesh->GetPointData()->SetScalars(param); // Display((vtkUnstructuredGrid*)vtkmesh); // std::cout<<"DOne? "; std::cin >> done; } std::cout <<" done with mesh map "; vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetInput(vtkmesh); std::cout << " writing " << outfn << std::endl; // outnm="C:\\temp\\mesh.vtk"; writer->SetFileName(outfn.c_str()); writer->SetFileTypeToBinary(); writer->Update(); std::cout << " done writing "; return; } template float GetImageTopology(typename TImage::Pointer image) { typedef TImage ImageType; typedef vtkPolyData MeshType; double aaParm = 0.024; typedef BinaryImageToMeshFilter FilterType; typename FilterType::Pointer fltMesh = FilterType::New(); fltMesh->SetInput(image); fltMesh->SetAntiAliasMaxRMSError(aaParm); fltMesh->SetAntiAliasMaxRMSError( -1000.0 ); // to do nothing fltMesh->Update(); vtkPolyData* vtkmesh =fltMesh->GetMesh(); // assign scalars to the original surface mesh // Display((vtkUnstructuredGrid*)vtkmesh); float genus = vtkComputeTopology(vtkmesh); std::cout << " Genus " << genus << std::endl; return genus; } int main(int argc, char *argv[]) { if (argc < 2) { std::cout << argv[0] << " binaryimage valueimage out paramname ValueScale AntiaAliasParm=0.001" << std::endl; std::cout << " outputs vtk version of input image -- assumes object is defined by non-zero values " << std::endl; std::cout << " mesh is colored by the value of the image voxel " << std::endl; std::cout << " the AA-Param could cause topo problems but makes nicer meshes " << std::endl; std::cout << " ValueScale controls contrast in image appearance - lower increaseses -- should be <= 1 " << std::endl; exit(0); } // Define the dimension of the images const unsigned int Dimension = 3; typedef float PixelType; // Declare the types of the output images typedef itk::Image ImageType; typedef itk::Image Image2DType; // Declare the type of the index,size and region to initialize images typedef itk::Index IndexType; typedef itk::Size SizeType; typedef itk::ImageRegion RegionType; typedef itk::ImageRegionIterator IteratorType; // Declare the type of the Mesh std::string outfn=std::string(argv[3]); ImageType::Pointer image2; ImageType::Pointer image; ReadImage(image,argv[1]); ReadImage(image2,argv[2]); ImageType::DirectionType fmat=image->GetDirection(); fmat.SetIdentity(); image->SetDirection(fmat); image2->SetDirection(fmat); // Save the mesh float aaParm = 0.03; const char* paramname=std::string("f(x)").c_str(); if (argc > 4) paramname =(argv[4]); float scaledata=0.5; if (argc > 5) scaledata=atof(argv[5]); if (argc > 6) aaParm=atof(argv[6]); std::cout << "aaParm " << aaParm<(image,image2,outfn,paramname,scaledata, aaParm); // GetImageTopology(image); return 0; } ants-1.9.2+svn680.dfsg/Examples/ImageCompare.cxx000066400000000000000000000177441147325206600213300ustar00rootroot00000000000000#include "itkWin32Header.h" #include #include #include "itkNumericTraits.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkExtractImageFilter.h" #include "itkDifferenceImageFilter.h" using namespace std; #define ITK_TEST_DIMENSION_MAX 6 int RegressionTestImage (const char *, const char *, int, bool); int main(int argc, char **argv) { if(argc < 3) { cerr << "Usage:" << endl; cerr << "testImage, baselineImage1, [baselineImage2, baselineImage3, ...]" << endl; cerr << "Note that if you supply more than one baselineImage, this test will pass if any" << endl; cerr << "of them match the testImage" << endl; return -1; } int bestBaselineStatus = 2001; int bestBaseline = 2; try { if(argc == 3) { bestBaselineStatus = RegressionTestImage(argv[1], argv[2], 0, false); } else { int currentStatus = 2001; for(int i=2;i ImageType; typedef itk::Image OutputType; typedef itk::Image DiffOutputType; typedef itk::ImageFileReader ReaderType; // Read the baseline file ReaderType::Pointer baselineReader = ReaderType::New(); baselineReader->SetFileName(baselineImageFilename); try { baselineReader->UpdateLargestPossibleRegion(); } catch (itk::ExceptionObject& e) { std::cerr << "Exception detected while reading " << baselineImageFilename << " : " << e.GetDescription(); return 1000; } // Read the file generated by the test ReaderType::Pointer testReader = ReaderType::New(); testReader->SetFileName(testImageFilename); try { testReader->UpdateLargestPossibleRegion(); } catch (itk::ExceptionObject& e) { std::cerr << "Exception detected while reading " << testImageFilename << " : " << e.GetDescription() << std::endl; return 1000; } // The sizes of the baseline and test image must match ImageType::SizeType baselineSize; baselineSize = baselineReader->GetOutput()->GetLargestPossibleRegion().GetSize(); ImageType::SizeType testSize; testSize = testReader->GetOutput()->GetLargestPossibleRegion().GetSize(); if (baselineSize != testSize) { std::cerr << "The size of the Baseline image and Test image do not match!" << std::endl; std::cerr << "Baseline image: " << baselineImageFilename << " has size " << baselineSize << std::endl; std::cerr << "Test image: " << testImageFilename << " has size " << testSize << std::endl; return 1; } // Now compare the two images typedef itk::DifferenceImageFilter DiffType; DiffType::Pointer diff = DiffType::New(); diff->SetValidInput(baselineReader->GetOutput()); diff->SetTestInput(testReader->GetOutput()); diff->SetDifferenceThreshold(2.0); diff->UpdateLargestPossibleRegion(); double status = diff->GetTotalDifference(); if (reportErrors) { typedef itk::RescaleIntensityImageFilter RescaleType; typedef itk::ExtractImageFilter ExtractType; typedef itk::ImageFileWriter WriterType; typedef itk::ImageRegion RegionType; OutputType::IndexType index; index.Fill(0); OutputType::SizeType size; size.Fill(0); RescaleType::Pointer rescale = RescaleType::New(); rescale->SetOutputMinimum(itk::NumericTraits::NonpositiveMin()); rescale->SetOutputMaximum(itk::NumericTraits::max()); rescale->SetInput(diff->GetOutput()); rescale->UpdateLargestPossibleRegion(); RegionType region; region.SetIndex(index); size = rescale->GetOutput()->GetLargestPossibleRegion().GetSize(); for (unsigned int i = 2; i < ITK_TEST_DIMENSION_MAX; i++) { size[i] = 0; } region.SetSize(size); ExtractType::Pointer extract = ExtractType::New(); extract->SetInput(rescale->GetOutput()); extract->SetExtractionRegion(region); WriterType::Pointer writer = WriterType::New(); writer->SetInput(extract->GetOutput()); if(differences) { // if there are discrepencies, create an diff image std::cout << ""; std::cout << status; std::cout << "" << std::endl; ::itk::OStringStream diffName; diffName << testImageFilename << ".diff.png"; try { rescale->SetInput(diff->GetOutput()); rescale->Update(); } catch (...) { std::cerr << "Error during rescale of " << diffName.str() << std::endl; } writer->SetFileName(diffName.str().c_str()); try { writer->Update(); } catch (...) { std::cerr << "Error during write of " << diffName.str() << std::endl; } std::cout << ""; std::cout << diffName.str(); std::cout << "" << std::endl; } ::itk::OStringStream baseName; baseName << testImageFilename << ".base.png"; try { rescale->SetInput(baselineReader->GetOutput()); rescale->Update(); } catch (...) { std::cerr << "Error during rescale of " << baseName.str() << std::endl; } try { writer->SetFileName(baseName.str().c_str()); writer->Update(); } catch (...) { std::cerr << "Error during write of " << baseName.str() << std::endl; } std::cout << ""; std::cout << baseName.str(); std::cout << "" << std::endl; ::itk::OStringStream testName; testName << testImageFilename << ".test.png"; try { rescale->SetInput(testReader->GetOutput()); rescale->Update(); } catch (...) { std::cerr << "Error during rescale of " << testName.str() << std::endl; } try { writer->SetFileName(testName.str().c_str()); writer->Update(); } catch (...) { std::cerr << "Error during write of " << testName.str() << std::endl; } std::cout << ""; std::cout << testName.str(); std::cout << "" << std::endl; } return (status != 0) ? 1 : 0; } ants-1.9.2+svn680.dfsg/Examples/ImageMath.cxx000066400000000000000000007430711147325206600206320ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RSfile: ImageMath.cxx,v $ Language: C++ Date: $Date: 2009/06/02 21:51:08 $ Version: $Revision: 1.103 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include // Here I'm using a map but you could choose even other containers #include #include #include #include #include "itkTDistribution.h" #include "itkTimeProbe.h" #include "itkMedianImageFilter.h" #include "itkVariableSizeMatrix.h" #include "itkVectorImageFileReader.h" #include "itkVector.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkHessianRecursiveGaussianImageFilter.h" #include "itkLaplacianRecursiveGaussianImageFilter.h" #include "itkBilateralImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkDanielssonDistanceMapImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkLabeledPointSetFileReader.h" #include "itkLabeledPointSetFileWriter.h" //#include "itkBinaryMorphologicalClosingImageFilter.h" //#include "itkBinaryMorphologicalOpeningImageFilter.h" #include "itkGrayscaleErodeImageFilter.h" #include "itkGrayscaleDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkGradientMagnitudeRecursiveGaussianImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkGradientAnisotropicDiffusionImageFilter.h" #include "itkBayesianClassifierImageFilter.h" #include "itkGradientAnisotropicDiffusionImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkBayesianClassifierInitializationImageFilter.h" #include "itkScalarImageKmeansImageFilter.h" #include "itkRelabelComponentImageFilter.h" #include "itkTranslationTransform.h" #include "itkImageMomentsCalculator.h" #include "itkBinaryThresholdImageFilter.h" #include "ReadWriteImage.h" #include "itkBSplineControlPointImageFilter.h" #include "itkExpImageFilter.h" #include "itkOtsuThresholdImageFilter.h" #include "itkShrinkImageFilter.h" #include "itkKdTree.h" #include "itkKdTreeBasedKmeansEstimator.h" #include "itkWeightedCentroidKdTreeGenerator.h" #include "../Temporary/itkFastMarchingImageFilter.h" // #include "itkMinimumDecisionRule.h" // #include "itkEuclideanDistance.h" // #include "itkSampleClassifier.h" #include "itkCastImageFilter.h" // #include "itkScalarImageToListAdaptor.h" #include "itkConnectedComponentImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkHistogramMatchingImageFilter.h" #include "itkLabelStatisticsImageFilter.h" #include "itkExtractImageFilter.h" #include "itkMRIBiasFieldCorrectionFilter.h" #include "itkImage.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkGaussianImageSource.h" #include "itkMultivariateLegendrePolynomial.h" #include "itkCompositeValleyFunction.h" #include "itkNormalVariateGenerator.h" #include "itkArray.h" #include "itkImageFileWriter.h" #include "itkSphereSpatialFunction.h" #include "itkLabelContourImageFilter.h" #include "itkMaskImageFilter.h" // #include "itkDecisionRuleBase.h" // #include "itkMinimumDecisionRule.h" // #include "itkImageClassifierBase.h" // #include "itkWellComposedImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkImageKmeansModelEstimator.h" #include "itkDistanceToCentroidMembershipFunction.h" #include "itkMRFImageFilter.h" #include "itkImageClassifierBase.h" #include "itkImageGaussianModelEstimator.h" // #include "itkMahalanobisDistanceMembershipFunction.h" // #include "itkMinimumDecisionRule.h" #include "itkSize.h" #include "itkImage.h" #include "itkVector.h" #include "vnl/vnl_matrix_fixed.h" #include "itkImageRegionIterator.h" #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodIterator.h" #include "itkNeighborhoodAlgorithm.h" #include "itkNeighborhood.h" #include "itkRGBPixel.h" #include "ReadWriteImage.h" #include "TensorFunctions.h" std::string ANTSGetFilePrefix(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } // if (extension==".txt") return AFFINE_FILE; // else return DEFORMATION_FILE; } // else{ // return INVALID_FILE; //} return filepre; } template int GetLargestComponent(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2=""; unsigned long smallest=50; if (argc > argct) { smallest=atoi(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename readertype::Pointer reader1 = readertype::New(); reader1->SetFileName(fn1.c_str()); reader1->UpdateLargestPossibleRegion(); try { image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } // compute the voxel volume typename ImageType::SpacingType spacing=image1->GetSpacing(); float volumeelement=1.0; for (unsigned int i=0; i labelimagetype; typedef itk::Image labelimagetype; typedef ImageType InternalImageType; typedef ImageType OutputImageType; typedef itk::BinaryThresholdImageFilter< InternalImageType, labelimagetype > ThresholdFilterType; typedef itk::ConnectedComponentImageFilter< labelimagetype, labelimagetype > FilterType; typedef itk::RelabelComponentImageFilter< labelimagetype, ImageType > RelabelType; typename ThresholdFilterType::Pointer threshold = ThresholdFilterType::New(); typename FilterType::Pointer filter = FilterType::New(); typename RelabelType::Pointer relabel = RelabelType::New(); // InternalPixelType threshold_low, threshold_hi; threshold->SetInput (image1); threshold->SetInsideValue(1); threshold->SetOutsideValue(0); threshold->SetLowerThreshold(0.25); threshold->SetUpperThreshold(1.e9); threshold->Update(); filter->SetInput (threshold->GetOutput()); filter->SetFullyConnected( 0 ); filter->Update(); relabel->SetInput( filter->GetOutput() ); relabel->SetMinimumObjectSize( smallest ); // relabel->SetUseHistograms(true); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } // WriteImage(relabel->GetOutput(),outname.c_str()); // return 0; typename ImageType::Pointer Clusters=MakeNewImage(relabel->GetOutput(),0); //typename ImageType::Pointer Clusters=relabel->GetOutput(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); float maximum=relabel->GetNumberOfObjects(); std::cout <<" # ob " << maximum << std::endl; float maxtstat=0; std::vector histogram((int)maximum+1); std::vector clustersum((int)maximum+1); for (int i=0; i<=maximum; i++) { histogram[i]=0; clustersum[i]=0; } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { float vox=image1->GetPixel(vfIter.GetIndex()); histogram[(unsigned int)vfIter.Get()]=histogram[(unsigned int)vfIter.Get()]+1; clustersum[(unsigned int)vfIter.Get()]+=vox; if (vox > maxtstat) maxtstat=vox; } } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { Clusters->SetPixel( vfIter.GetIndex(), histogram[(unsigned int)vfIter.Get()] ); // if ( Clusters->GetPixel( vfIter.GetIndex() ) > maximgval ) // maximgval=Clusters->GetPixel( vfIter.GetIndex()); } else Clusters->SetPixel(vfIter.GetIndex(),0); } float maximgval=0; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) > maximgval ) maximgval=Clusters->GetPixel( vfIter.GetIndex()); std::cout << " max float size " << (maximgval*volumeelement) << " long-size: " << (unsigned long) (maximgval*volumeelement) << std::endl; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) if ( Clusters->GetPixel( vfIter.GetIndex() ) >= maximgval ) image1->SetPixel( vfIter.GetIndex(), 1); else image1->SetPixel( vfIter.GetIndex(), 0); if (outname.length() > 3) WriteImage(image1,outname.c_str()); return 0; } template int ExtractSlice(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; unsigned int slice = atoi(argv[argct]); argct++; std::cout << " Extract slice " << slice << " from dimension" << ImageDimension << std::endl; typename ImageType::Pointer image1 = NULL; typename OutImageType::Pointer outimage = NULL; typedef itk::ExtractImageFilter ExtractFilterType; typedef itk::ImageRegionIteratorWithIndex ImageIt; typedef itk::ImageRegionIteratorWithIndex SliceIt; if (fn1.length() > 3) ReadImage(image1, fn1.c_str()); else return 1; unsigned int timedims=image1->GetLargestPossibleRegion().GetSize()[ImageDimension-1]; if ( slice >= timedims ) { std::cout << " max slice number is " << timedims << std::endl; return 1; } typename ImageType::RegionType extractRegion = image1->GetLargestPossibleRegion(); extractRegion.SetSize(ImageDimension-1, 0); extractRegion.SetIndex(ImageDimension-1, slice ); typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New(); extractFilter->SetInput( image1 ); extractFilter->SetExtractionRegion( extractRegion ); extractFilter->Update(); outimage=extractFilter->GetOutput(); /* typename ImageType::SpacingType qspc=warpthisimage->GetSpacing(); typename ImageType::PointType qorg=warpthisimage->GetOrigin(); typename ImageType::DirectionType qdir=warpthisimage->GetDirection(); qdir.Fill(0); for (unsigned int qq=0; qqGetDirection()[qq][pp]; } qspc[qq]=img_mov->GetSpacing()[qq]; qorg[qq]=img_mov->GetOrigin()[qq]; } warpthisimage->SetSpacing(qspc); warpthisimage->SetOrigin(qorg); warpthisimage->SetDirection(qdir); */ if (outname.length() > 3) WriteImage(outimage,outname.c_str()); else return 1; return 0; } template int ThresholdAtMean(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float percentofmean=1.0; if (argc > argct) { percentofmean=atof(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename readertype::Pointer reader1 = readertype::New(); reader1->SetFileName(fn1.c_str()); reader1->UpdateLargestPossibleRegion(); try { image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } typedef itk::ImageRegionIteratorWithIndex Iterator; double mean=0,max=-1.e9,min=1.e9; unsigned long ct = 0; Iterator vfIter2( image1, image1->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { double val=vfIter2.Get(); mean+=val; if (val >max) max=val; else if (val < min) min=val; ct++; } if (ct > 0) mean/= (float)ct; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; typename ThresholdFilterType::Pointer threshold = ThresholdFilterType::New(); threshold->SetInput (image1); threshold->SetInsideValue(1); threshold->SetOutsideValue(0); threshold->SetLowerThreshold(mean*percentofmean); threshold->SetUpperThreshold(max); threshold->Update(); WriteImage(threshold->GetOutput(),outname.c_str()); return 0; } template int FlattenImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float percentofmax=1.0; if (argc > argct) { percentofmax=atof(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename readertype::Pointer reader1 = readertype::New(); reader1->SetFileName(fn1.c_str()); reader1->UpdateLargestPossibleRegion(); try { image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } typedef itk::ImageRegionIteratorWithIndex Iterator; double mean=0,max=-1.e9,min=1.e9; unsigned long ct = 0; Iterator vfIter2( image1, image1->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { double val=vfIter2.Get(); mean+=val; if (val >max) max=val; else if (val < min) min=val; ct++; } if (ct > 0) mean/= (float)ct; typename ImageType::Pointer out=MakeNewImage(image1,0); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { double val=vfIter2.Get(); if (val > max*percentofmax) val=(max*percentofmax); out->SetPixel(vfIter2.GetIndex(),val); ct++; } std::cout << " Flattening to : " << percentofmax << std::endl; WriteImage(out,outname.c_str()); return 0; } template int TruncateImageIntensity( unsigned int argc, char *argv[] ) { typedef int PixelType; typedef float RealType; // usage ImageMath 3 out.nii.gz TrunateImageIntensity InImage.nii.gz FractionLo(e.g.0.025) FractionHi(e.g.0.975) Bins Mask if (argc < 4 ) { std::cout <<" need more args -- see usage " << std::endl << " ImageMath 3 outimage.nii.gz TruncateImageIntensity inputImage {lowerQuantile=0.025} {upperQuantile=0.975} {numberOfBins=65} {binary-maskImage} " << std::endl; exit(0); } unsigned int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1=std::string(argv[argct]); argct++; float lo = 0.025; if ( argc > argct ) lo=atof(argv[argct]); argct++; float hi = 0.975; if ( argc > argct ) hi=atof(argv[argct]); else hi=1.0-lo ; argct++; unsigned int numberOfBins = 64; if ( argc > argct ) numberOfBins=atoi(argv[argct]); argct++; // std::cout << " bin " << numberOfBins << " lo " << lo << " Hi " << hi << std::endl; typedef itk::Image ImageType; typedef itk::Image RealImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer imageReader = ReaderType::New(); imageReader->SetFileName( fn1.c_str() ); imageReader->Update(); typename ImageType::Pointer mask=NULL; /* if ( argc > argct ) { mask = ImageType::New(); try { typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer labelImageReader = ReaderType::New(); labelImageReader->SetFileName( argv[argct] ); labelImageReader->Update(); mask = labelImageReader->GetOutput(); } catch(...) { std::cout << " can't read mask " << std::endl; mask=NULL; }; } */ // std::cout << " Mask " << std::endl; if( !mask ) { mask = ImageType::New(); mask->SetOrigin( imageReader->GetOutput()->GetOrigin() ); mask->SetSpacing( imageReader->GetOutput()->GetSpacing() ); mask->SetRegions( imageReader->GetOutput()->GetLargestPossibleRegion() ); mask->SetDirection( imageReader->GetOutput()->GetDirection() ); mask->Allocate(); mask->FillBuffer( itk::NumericTraits::One ); } // std::cout << " iterate " << std::endl; itk::ImageRegionIterator ItI( imageReader->GetOutput(), imageReader->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItM( mask, mask->GetLargestPossibleRegion() ); RealType maxValue = itk::NumericTraits::NonpositiveMin(); RealType minValue = itk::NumericTraits::max(); ItM.GoToBegin(); for (ItI.GoToBegin(); !ItI.IsAtEnd(); ++ItI ) { // std::cout << " ind " << ItI.GetIndex() << std::endl; if ( ItI.Get() > 0 && ItM.Get() >= 0.5 ) { if ( ItI.Get() < minValue ) { minValue = ItI.Get(); } else if ( ItI.Get() > maxValue ) { maxValue = ItI.Get(); } ItM.Set( itk::NumericTraits::One ); } else { ItM.Set( itk::NumericTraits::Zero ); } if( vnl_math_isnan( ItI.Get() ) || vnl_math_isinf( ItI.Get() ) ) { ItM.Set( itk::NumericTraits::Zero ); } ++ItM; } // std::cout << " label " << std::endl; typedef itk::LabelStatisticsImageFilter HistogramGeneratorType; typename HistogramGeneratorType::Pointer stats = HistogramGeneratorType::New(); stats->SetInput( imageReader->GetOutput() ); stats->SetLabelInput( mask ); stats->SetUseHistograms( true ); stats->SetHistogramParameters( numberOfBins, minValue, maxValue ); stats->Update(); // std::cout << " labeld " << std::endl; typedef typename HistogramGeneratorType::HistogramType HistogramType; const HistogramType *histogram = stats->GetHistogram( 1 ); double lowerQuantile = histogram->Quantile( 0, lo ); double upperQuantile = histogram->Quantile( 0, hi ); std::cout << "Lower quantile: " << lowerQuantile << std::endl; std::cout << "Upper quantile: " << upperQuantile << std::endl; for ( ItI.GoToBegin(); !ItI.IsAtEnd(); ++ItI ) { if ( ItI.Get() < lowerQuantile ) { ItI.Set( lowerQuantile ); } if ( ItI.Get() > upperQuantile ) { ItI.Set( upperQuantile ); } } typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[2] ); writer->SetInput( imageReader->GetOutput() ); writer->Update(); return EXIT_SUCCESS; } template int TileImages(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; unsigned int nx = atoi(argv[argct]); argct++; unsigned int numberofimages=0; typename ImageType::Pointer averageimage = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::SizeType size; double meanval=1; size.Fill(0); unsigned int bigimage=0; for (unsigned int j=argct; j< argc; j++) { numberofimages++; // Get the image dimension std::string fn = std::string(argv[j]); typename itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); for (unsigned int i=0; iGetNumberOfDimensions(); i++) { if ( imageIO->GetDimensions(i) > size[i] ) { size[i]=imageIO->GetDimensions(i); bigimage=j; std::cout << " bigimage " << j << " size " << size << std::endl; } } } ReadImage(image2,argv[bigimage]); std:: cout << " largest image " << size << std::endl; /** declare the tiled image */ unsigned int xsize=size[0]; unsigned int ysize=size[1]; typename ImageType::SizeType tilesize; unsigned int ny=(unsigned int)((float)numberofimages/(float)nx+0.5); if ( nx*ny < numberofimages) ny++; std::cout << " nx " << nx << " ny " << ny << std::endl; tilesize[0]=xsize*nx; tilesize[1]=ysize*ny; typename ImageType::RegionType region; region.SetSize( tilesize ); bool normalizei=false; typename ImageType::Pointer tiledimage=ImageType::New(); tiledimage->SetLargestPossibleRegion( region ); tiledimage->SetBufferedRegion( region ); tiledimage->SetSpacing( image2->GetSpacing() ); tiledimage->SetDirection( image2->GetDirection() ); tiledimage->SetOrigin( image2->GetOrigin() ); tiledimage->Allocate(); unsigned int imagecount=0,imagexct=0,imageyct=0; for (unsigned int j=argct; j< argc; j++) { // Get the image dimension std::string fn = std::string(argv[j]); ReadImage(image2,fn.c_str()); unsigned long ct = 0; if (normalizei) { meanval = 0.0; Iterator vfIter2( image2, image2->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { meanval+=vfIter2.Get(); ct++; } if (ct > 0) meanval /= (float)ct; if (meanval <= 0) meanval=1.0; } imagexct=imagecount % nx; imageyct=imagecount/nx; std::cout << "doing " << fn << " " << imagecount << " x " << imagexct << " y " << imageyct << std::endl; imagecount++; Iterator vfIter( image2, image2->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { typename ImageType::IndexType locind=vfIter.GetIndex(); typename ImageType::IndexType globind; globind[0]=size[0]*imagexct+locind[0]; globind[1]=size[1]*imageyct+locind[1]; double val = vfIter.Get()/meanval; tiledimage->SetPixel(globind, val ); } } WriteImage(tiledimage,outname.c_str()); return 0; typedef itk::Image ByteImageType; typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 255 ); rescaler->SetInput( tiledimage ); std::cout << " writing output "; typedef itk::ImageFileWriter writertype; typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( rescaler->GetOutput() ); writer->Update(); return 0; } template int ConvertLandmarkFile(unsigned int argc, char *argv[]) { unsigned int argct=2; if (argc < 5 ) { std::cout <<" need more args -- see usage " << std::endl; exit(0); } std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string infn=std::string(argv[argct]); argct++; float pointp=1; typedef itk::PointSet PointSetType; typedef itk::LabeledPointSetFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( infn.c_str() ); reader->SetRandomPercentage( 1 ); if ( pointp > 0 && pointp < 1 ) { reader->SetRandomPercentage( pointp ); } reader->Update(); std::cout << "Number of labels: " << reader->GetNumberOfLabels() << std::endl; std::cout << "Labels: "; for ( unsigned int i = 0; i < reader->GetNumberOfLabels(); i++ ) { std::cout << reader->GetLabelSet()->operator[](i) << " "; } std::cout << std::endl; typedef itk::LabeledPointSetFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( outname.c_str() ); writer->SetInput( reader->GetOutput() ); writer->Update(); return 0; } template int TriPlanarView(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image MatrixImageType; typedef itk::ImageFileReader readertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; unsigned int argct=2; if (argc < 5 ) { std::cout <<" need more args -- see usage " << std::endl; exit(0); } std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string maskfn=std::string(argv[argct]); argct++; std::cout << " file name " << maskfn << std::endl; typename ImageType::Pointer mask = NULL; typename readertype::Pointer reader2 = readertype::New(); reader2->SetFileName(maskfn.c_str()); try { reader2->UpdateLargestPossibleRegion(); } catch(...) { std::cout << " Error reading " << maskfn << std::endl; } mask=reader2->GetOutput(); //ReadImage(mask,maskfn.c_str()); // WriteImage(mask,"temp.nii"); float clamppercent1 = 0.1; if (argc > argct) clamppercent1=atof(argv[argct]); argct++; if (clamppercent1 > 1) clamppercent1=1; float clamppercent2=0.1; if (argc > argct) clamppercent2=atof(argv[argct]); argct++; if (clamppercent2 > 1) clamppercent2=1; typename ImageType::SizeType size=mask->GetLargestPossibleRegion().GetSize(); unsigned int xslice = size[0]/2; if (argc > argct) xslice=atoi(argv[argct]); argct++; unsigned int yslice = size[1]/2; if (argc > argct) yslice=atoi(argv[argct]); argct++; unsigned int zslice = size[2]/2; if (argc > argct) zslice=atoi(argv[argct]); argct++; typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 255 ); rescaler->SetInput( mask ); rescaler->Update(); mask=rescaler->GetOutput(); // typedef itk::IntensityWindowingImageFilter wFilterType; // typename wFilterType::Pointer wer = wFilterType::New(); //wer->SetInput(mask); /** declare the tiled image */ unsigned long xsize=size[0]; unsigned long ysize=size[1]; unsigned long zsize=size[2]; typename MatrixImageType::SizeType ztilesize; ztilesize[0]=xsize; ztilesize[1]=ysize; typename MatrixImageType::SizeType ytilesize; ytilesize[0]=xsize; ytilesize[1]=zsize; typename MatrixImageType::SizeType xtilesize; xtilesize[0]=ysize; xtilesize[1]=zsize; typename MatrixImageType::SizeType tilesize; tilesize[0]=xtilesize[0]+ytilesize[0]+ztilesize[0]; tilesize[1]=xtilesize[1]; if ( ytilesize[1] > tilesize[1] ) tilesize[1]=ytilesize[1]; if ( ztilesize[1] > tilesize[1] ) tilesize[1]=ztilesize[1]; std::cout << " allocate matrix " << tilesize << std::endl; typename MatrixImageType::RegionType region; region.SetSize( tilesize ); typename MatrixImageType::Pointer matimage=MatrixImageType::New(); matimage->SetLargestPossibleRegion( region ); matimage->SetBufferedRegion( region ); typename MatrixImageType::DirectionType mdir; mdir.Fill(0); mdir[0][0]=1; mdir[1][1]=1; typename MatrixImageType::SpacingType mspc; mspc.Fill(1); typename MatrixImageType::PointType morg; morg.Fill(0); matimage->SetSpacing( mspc ); matimage->SetDirection(mdir); matimage->SetOrigin( morg ); matimage->Allocate(); unsigned int lowgetridof=(unsigned int) (clamppercent1*256); unsigned int higetridof=(unsigned int) (256 - clamppercent2*256); // std::cout << " get rid of " << getridof << std::endl; matimage->FillBuffer(lowgetridof); // now loop over each slice and put the pixels in the right place in matimage typename MatrixImageType::IndexType index2d; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( mask, mask->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { double val1=vfIter2.Get(); if ( val1 > higetridof ) vfIter2.Set(higetridof ); if ( val1 < lowgetridof ) vfIter2.Set(lowgetridof ); // first do z-slice if ( vfIter2.GetIndex()[2] == (long) zslice) { double val=vfIter2.Get(); typename ImageType::IndexType index=vfIter2.GetIndex(); index2d[0]=index[0]+xtilesize[0]+ytilesize[0]; index2d[1]=index[1]; index2d[1]=tilesize[1]-index2d[1]-1; matimage->SetPixel(index2d,val); } if ( vfIter2.GetIndex()[1] == (long)yslice) { double val=vfIter2.Get(); typename ImageType::IndexType index=vfIter2.GetIndex(); index2d[0]=index[0]+xtilesize[0]; index2d[1]=index[2]; index2d[1]=tilesize[1]-index2d[1]-1; matimage->SetPixel(index2d,val); } if ( vfIter2.GetIndex()[0] == (long)xslice) { double val=vfIter2.Get(); typename ImageType::IndexType index=vfIter2.GetIndex(); index2d[0]=index[1]; index2d[1]=index[2]; index2d[1]=tilesize[1]-index2d[1]-1; matimage->SetPixel(index2d,val); } } typedef itk::Image ByteImageType; typedef itk::RescaleIntensityImageFilter RescaleFilterType2; typename RescaleFilterType2::Pointer rescaler2 = RescaleFilterType2::New(); rescaler2->SetOutputMinimum( 0 ); rescaler2->SetOutputMaximum( 255 ); rescaler2->SetInput( matimage ); rescaler2->Update(); std::cout << " writing output "; typedef itk::ImageFileWriter writertype; typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( rescaler2->GetOutput() ); writer->Update(); return 0; } template int ConvertVectorToImage(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image MatrixImageType; typedef itk::ImageFileReader readertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::ImageRegionIteratorWithIndex vIterator; int argct=2; if (argc < 5 ) { std::cout <<" need more args -- see usage " << std::endl; exit(0); } std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string maskfn=std::string(argv[argct]); argct++; std::string vecfn=std::string(argv[argct]); argct++; typename ImageType::Pointer mask = NULL; ReadImage(mask,maskfn.c_str()); typename MatrixImageType::Pointer vecimg = NULL; ReadImage(vecimg,vecfn.c_str()); unsigned long voxct=0,mct=0; Iterator mIter( mask,mask->GetLargestPossibleRegion() ); for( mIter.GoToBegin(); !mIter.IsAtEnd(); ++mIter ) if (mIter.Get() >= 0.5) mct++; vIterator vIter(vecimg,vecimg->GetLargestPossibleRegion() ); for( vIter.GoToBegin(); !vIter.IsAtEnd(); ++vIter ) voxct++; std::cout << " vct " << voxct << " mct " << mct << std::endl; typename ImageType::Pointer outimage = NULL; ReadImage(outimage,maskfn.c_str()); outimage->FillBuffer(0); vIter.GoToBegin(); for( mIter.GoToBegin(); !mIter.IsAtEnd(); ++mIter ) if (mIter.Get() >= 0.5) { outimage->SetPixel(mIter.GetIndex(),vIter.Get()); ++vIter; } WriteImage(outimage,outname.c_str()); return 0; } template int CorruptImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float noiselevel=1.0; if (argc > argct) { noiselevel=atof(argv[argct]); argct++; } float smoothlevel=1.0; if (argc > argct) { smoothlevel=atof(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename readertype::Pointer reader1 = readertype::New(); reader1->SetFileName(fn1.c_str()); reader1->UpdateLargestPossibleRegion(); try { image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator iter( image1, image1->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { double r = ( (double)rand() / ((double)(RAND_MAX) +(double)(1)) )-0.5; iter.Set(iter.Get()+r*noiselevel); } if (smoothlevel > 0) { { typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(smoothlevel); filter->SetUseImageSpacingOff(); filter->SetMaximumError(.01f); filter->SetInput(image1); filter->Update(); image1=filter->GetOutput(); } } WriteImage(image1,outname.c_str()); return 0; } template int Where(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float value=atof(argv[argct]); argct++; std::string fn2 = ""; if (argc > argct) {fn2=std::string(argv[argct]); argct++; } float tol=0.0; if (argc > argct) { tol=atof(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; if (fn1.length() > 3) ReadImage(image1, fn1.c_str()); if (fn2.length() > 3) ReadImage(image2, fn2.c_str()); unsigned long ct=0; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator iter( image1, image1->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { if (!image2) { if ( fabs(iter.Get() - value) < tol ) { std::cout << iter.GetIndex() << std::endl; ct++; } } else if (image2->GetPixel(iter.GetIndex()) > 0 && fabs(iter.Get() - value) < tol ) { std::cout << iter.GetIndex() << std::endl; ct++; } } std::cout << ct << " voxels have the value " << value << std::endl; return 0; } template int SetOrGetPixel(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float value=atof(argv[argct]); std::string Get=std::string(argv[argct]); argct++; float indx=atof(argv[argct]); argct++; float indy=0; if (ImageDimension >= 2) { indy=atof(argv[argct]); argct++ ;} float indz=0; if (ImageDimension >= 3) { indz=atof(argv[argct]); argct++ ;} bool usephyspace=false; if (argc > argct ) { usephyspace=atoi(argv[argct]); argct++; } bool get=false; if (strcmp(Get.c_str(),"Get") == 0) get=true; typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; if (fn1.length() > 3) { ReadImage(image1, fn1.c_str()); ReadImage(image2, fn1.c_str()); } if (!image1) {std::cout <<" no image ! " << std::endl; exit(0);} typename ImageType::IndexType index; index.Fill(0); if (usephyspace==false) { index[0]=(long int)indx; index[1]=(long int)indy; if ( ImageDimension == 3) index[2]=(long int)indz; } else { typename ImageType::PointType porig; porig[0]=indx; porig[1]=indy; if (ImageDimension==3) porig[2]=indz; image1->TransformPhysicalPointToIndex(porig, index); } std::cout << " use phy " << usephyspace << " " << indx << " " << indy << " " << indz << std::endl; std::cout << " Ind " << index << std::endl; bool isinside=true; for (unsigned int i=0; i image1->GetLargestPossibleRegion().GetSize()[i]-1 ) isinside=false; } if ( isinside == true ) { if ( get ) { std::cout <<" GetValue at " << index << " is " << image1->GetPixel(index) << std::endl; } else { std::cout <<" SetValue at " << index << " value " << value << " replaces " << image1->GetPixel(index) << std::endl; image2->SetPixel(index,value); WriteImage(image2,outname.c_str()); } } else std::cout <<" not in image " << index << std::endl; return 0; } template int HistogramMatching(int argc, char * argv[]) { typedef float PixelType; typedef itk::Image ImageType; typedef itk::HistogramMatchingImageFilter MatchingFilterType; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = std::string(argv[argct]); argct++; long bins = 255; if (argc > argct) bins =atoi(argv[argct]); argct++; long points = 64; if (argc > argct) points =atoi(argv[argct]); argct++; typename ImageType::Pointer source; ReadImage(source,fn1.c_str()); typename ImageType::Pointer reference; ReadImage(reference,fn2.c_str()); typename MatchingFilterType::Pointer match = MatchingFilterType::New(); match->SetSourceImage(source); match->SetReferenceImage(reference); match->SetNumberOfHistogramLevels(bins); match->SetNumberOfMatchPoints(points); match->Update(); WriteImage(match->GetOutput(), outname.c_str()); return 0; } template int PadImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float padvalue=atof(argv[argct]); argct++; std::string fn2 = ""; if (argc > argct) fn2=std::string(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; if (fn1.length() > 3) ReadImage(image1, fn1.c_str()); typename ImageType::PointType origin=image1->GetOrigin(); typename ImageType::PointType origin2=image1->GetOrigin(); typename ImageType::SizeType size=image1->GetLargestPossibleRegion().GetSize(); typename ImageType::SizeType newsize=image1->GetLargestPossibleRegion().GetSize(); typename ImageType::RegionType newregion; // determine new image size for (unsigned int i=0; iGetLargestPossibleRegion().GetIndex()); typename ImageType::Pointer padimage = ImageType::New(); padimage->SetSpacing(image1->GetSpacing()); padimage->SetOrigin(origin2); padimage->SetDirection(image1->GetDirection()); padimage->SetRegions(newregion ); padimage->Allocate(); padimage->FillBuffer( 0 ); typename ImageType::IndexType index; typename ImageType::IndexType index2; if (padvalue > 0) { index.Fill(0); index2.Fill((unsigned int)fabs(padvalue)); } else { index2.Fill(0); index.Fill((unsigned int)fabs(padvalue)); } typename ImageType::PointType point1,pointpad; image1->TransformIndexToPhysicalPoint(index, point1); padimage->TransformIndexToPhysicalPoint(index2, pointpad); std::cout << " pre " << point1 << " pad " << pointpad << std::endl; for (unsigned int i=0; iSetOrigin(origin2); Iterator iter( image1, image1->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { typename ImageType::IndexType oindex=iter.GetIndex(); typename ImageType::IndexType padindex=iter.GetIndex(); bool isinside=true; for (unsigned int i=0; i newsize[i]-1 ) isinside=false; // if (shifted < 0) shifted=0; //padindex[i]= } if (isinside) { for (unsigned int i=0; iSetPixel(padindex,iter.Get()); } } WriteImage(padimage,outname.c_str()); return 0; } template int StackImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if (argc > argct) fn2=std::string(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; if (fn1.length() > 3) ReadImage(image1, fn1.c_str()); typename ImageType::Pointer image2 = NULL; if (fn2.length() > 3) ReadImage(image2, fn2.c_str()); typename ImageType::PointType origin=image1->GetOrigin(); typename ImageType::PointType origin2=image1->GetOrigin(); typename ImageType::SizeType size=image1->GetLargestPossibleRegion().GetSize(); typename ImageType::SizeType newsize=image1->GetLargestPossibleRegion().GetSize(); typename ImageType::RegionType newregion; // determine new image size newsize[ImageDimension-1]=(unsigned int)newsize[ImageDimension-1]+image2->GetLargestPossibleRegion().GetSize()[ImageDimension-1]; std::cout << " oldsize " << size << " newsize " << newsize << std::endl; newregion.SetSize(newsize); newregion.SetIndex(image1->GetLargestPossibleRegion().GetIndex()); typename ImageType::Pointer padimage = ImageType::New(); padimage->SetSpacing(image1->GetSpacing()); padimage->SetOrigin(origin2); padimage->SetDirection(image1->GetDirection()); padimage->SetRegions(newregion ); padimage->Allocate(); padimage->FillBuffer( 0 ); typename ImageType::IndexType index; index.Fill(0); typename ImageType::IndexType index2; index2.Fill(0); typename ImageType::PointType point1,pointpad; image1->TransformIndexToPhysicalPoint(index, point1); padimage->TransformIndexToPhysicalPoint(index2, pointpad); // std::cout << " pre " << point1 << " pad " << pointpad << std::endl; for (unsigned int i=0; iSetOrigin(origin2); float padvalue=image1->GetLargestPossibleRegion().GetSize()[ImageDimension-1]; Iterator iter( padimage, padimage->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { typename ImageType::IndexType oindex=iter.GetIndex(); typename ImageType::IndexType padindex=iter.GetIndex(); bool isinside=false; if ( oindex[ImageDimension-1] >= padvalue ) isinside=true; if (isinside) { float shifted=((float)oindex[ImageDimension-1]-padvalue); padindex[ImageDimension-1]=(unsigned int)shifted; padimage->SetPixel(oindex,image2->GetPixel(padindex)); } else padimage->SetPixel(oindex,image1->GetPixel(oindex)); } WriteImage(padimage,outname.c_str()); return 0; } template int MakeImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; unsigned int sizevalx = atoi(argv[argct]); argct++; unsigned int sizevaly=0; if (argc >argct) { sizevaly=atoi(argv[argct]); argct++; } unsigned int sizevalz=0; if (argc >argct && ImageDimension == 3) { sizevalz=atoi(argv[argct]); argct++; } typename ImageType::SizeType size; size[0]=sizevalx; size[1]=sizevaly; if ( ImageDimension == 3) size[2]=sizevalz; typename ImageType::RegionType newregion; std::cout << " size " << size << std::endl; newregion.SetSize(size); typename ImageType::Pointer padimage = ImageType::New(); typename ImageType::SpacingType spacing; spacing.Fill(1); typename ImageType::PointType origin; origin.Fill(0); padimage->SetSpacing(spacing); padimage->SetOrigin(origin); padimage->SetRegions(newregion ); padimage->Allocate(); padimage->FillBuffer( 0 ); WriteImage(padimage,outname.c_str()); return 0; } template typename TImage::Pointer LabelSurface(typename TImage::Pointer input, typename TImage::Pointer input2 ) { std::cout << " Label Surf " << std::endl; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typename ImageType::Pointer Image = ImageType::New(); Image->SetLargestPossibleRegion(input->GetLargestPossibleRegion() ); Image->SetBufferedRegion(input->GetLargestPossibleRegion()); Image->Allocate(); Image->SetSpacing(input->GetSpacing()); Image->SetOrigin(input->GetOrigin()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); while (!GHood.IsAtEnd()) { typename TImage::PixelType p = GHood.GetCenterPixel(); typename TImage::IndexType ind = GHood.GetIndex(); typename TImage::IndexType ind2; if ( p >= 0.5 ) { bool atedge=false; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0.0; for (int j=0; jGetPixel(ind2) >= 0.5 ) secondval=true; if (GHood.GetPixel(i) < 0.5 && dist < 2. && secondval ) { atedge=true; } } if (atedge && p >= 0.5) Image->SetPixel(ind,1); else Image->SetPixel(ind,0); } ++GHood; } return Image; } template int FitSphere(int argc, char *argv[]) { /* typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if (argc > argct) fn2=std::string(argv[argct]); argct++; float MaxRad=5; if (argc > argct) MaxRad = atof(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer radimage = NULL; typename ImageType::Pointer radimage2 = NULL; typename ImageType::Pointer priorimage = NULL; typename ImageType::Pointer wmimage = NULL; if (fn2.length() > 3) ReadImage(wmimage, fn2.c_str()); std::cout <<" read " << fn1 << " MXR " << MaxRad << std::endl; ReadImage(image1, fn1.c_str()); ReadImage(radimage, fn1.c_str()); ReadImage(radimage2, fn1.c_str()); ReadImage(priorimage, fn1.c_str()); radimage->FillBuffer(0); radimage2->FillBuffer(0); priorimage->FillBuffer(0); typename ImageType::SpacingType spacing=image1->GetSpacing(); typename ImageType::Pointer surf = LabelSurface(image1,wmimage); typedef itk::LinearInterpolateImageFunction ScalarInterpolatorType; typename ScalarInterpolatorType::Pointer ginterp = ScalarInterpolatorType::New(); ginterp->SetInputImage(image1); typename ScalarInterpolatorType::ContinuousIndexType Y1; typename ScalarInterpolatorType::ContinuousIndexType Y2; typename ScalarInterpolatorType::ContinuousIndexType GMx; typename ScalarInterpolatorType::ContinuousIndexType WMx; typename ScalarInterpolatorType::Pointer winterp=NULL; if (wmimage) { winterp=ScalarInterpolatorType::New(); winterp->SetInputImage(wmimage); } // float x=0,y=0,z=0; // float xc=0,yc=0,zc=0; float globalbestrad=0; typename ImageType::IndexType bestind; bestind.Fill(0); typename ImageType::IndexType ind2; ind2.Fill(0); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator iter( image1, image1->GetLargestPossibleRegion() ); std::cout <<" Begin " << std::endl; unsigned long npx=0; // float pi=3.141; unsigned long numpx=image1->GetBufferedRegion().GetNumberOfPixels(); //unsigned int prog=0; // float gmtotal,wmtotal,gvol,wvol,warea,garea; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { npx++; typename ImageType::IndexType ind=iter.GetIndex(); // float val=surf->GetPixel(ind);//iter.Get(); // float minrad=1.e9; */ /* if (val > 0.5 && fabs((float)ind[2]-80.) < 6 ) { //float bestrad=0; //parameterize sphere at this index float epspi=pi*0.1; float epsrad=0.2; gvol=0;wvol=0;warea=0;garea=0; float svol=0;//4./3.*pi*MaxRad*MaxRad*MaxRad; // float sarea=0;//4.*pi*MaxRad*MaxRad; //float bestvol=0; // float wdiff=0; // for (float theta=0; theta<=pi; theta+=epspi) float theta=0; gmtotal=0; wmtotal=0; float glength=0,wlength=0; while ( theta < pi ) { garea=0;warea=0; float psi=0; while ( psi < pi ) { glength=0;wlength=0; float rr=0; bool raddone=false; GMx.Fill(0); WMx.Fill(0); while ( rr <= MaxRad && !raddone) { // integrate the wm/gm probability along this radius, at these angles Y1[0]=(float)ind[0]/spacing[0]+rr*cos(psi)*sin(theta); Y1[1]=(float)ind[1]/spacing[1]+rr*sin(psi)*sin(theta); Y1[2]=(float)ind[2]/spacing[2]+rr*cos(theta); Y2[0]=(float)ind[0]/spacing[0]+rr*cos(psi+pi)*sin(theta); Y2[1]=(float)ind[1]/spacing[1]+rr*sin(psi+pi)*sin(theta); Y2[2]=(float)ind[2]/spacing[2]+rr*cos(theta); float gval1 = ginterp->EvaluateAtContinuousIndex( Y1 ); float gval2 = ginterp->EvaluateAtContinuousIndex( Y2 ); float wval1=0,wval2=0; if (wmimage) wval1 = winterp->EvaluateAtContinuousIndex( Y1 ); if (wmimage) wval2 = winterp->EvaluateAtContinuousIndex( Y2 ); glength+=(gval1+gval2)*epsrad*2; wlength+=(wval2+wval2)*epsrad*2; gmtotal+=(gval1+gval2); wmtotal+=(wval1+wval2); for (unsigned int dd=0; dd 0) gwrat=garea/warea; if (wvol > 0) gvrat=gvol/wvol; priorimage->SetPixel(ind,gmtotal/(wmtotal+gmtotal)); radimage->SetPixel(ind,cmdist); } */ /* // radimage2->SetPixel(ind,gvrat); if (image1->GetPixel(ind) >= 0.5) { bool okfit=true; float dorad=1; float bestrad=1; while (okfit && dorad <= MaxRad ) { typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad,rad2; rad2.Fill(0); for (unsigned int j=0; jGetLargestPossibleRegion()); GHood.SetLocation(ind); typename ImageType::PixelType p = GHood.GetCenterPixel(); unsigned int goodct=0; unsigned int possct=0; if ( p > 0 && radimage->GetPixel(ind) <= 0 ) { for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=sqrt(((float)ind2[0]-(float)ind[0])*((float)ind2[0]-(float)ind[0])+ ((float)ind2[1]-(float)ind[1])*((float)ind2[1]-(float)ind[1])+ ((float)ind2[2]-(float)ind[2])*((float)ind2[2]-(float)ind[2])); if ( GHood.GetPixel(i) == p && dist <= tardist) { goodct++; possct++; } else if ( dist <= tardist ) possct++; // std::cout << " Ind " << ind << " : " << bestrad << " tardist " << tardist << " gct " << goodct <<" pos " << possct << " dist " << dist << " ind2 " << ind2 << std::endl; } if (goodct==possct) { bestrad=dorad; radimage->SetPixel(ind,bestrad*(-1.0)); } else { okfit=false; radimage->SetPixel(ind,radimage->GetPixel(ind)*(-1.0)); } } dorad=dorad+1; } if (bestrad >= globalbestrad) { globalbestrad=bestrad; bestind=ind; } if (npx % 10000 == 0) { std::cout <<" prog " << (float)npx/(float)numpx << std::endl; // WriteImage(radimage,outname.c_str()); // WriteImage(radimage2,(std::string("Sphere")+outname).c_str()); //WriteImage(priorimage,(std::string("Prior")+outname).c_str()); } } } for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { float val=iter.Get(); typename ImageType::IndexType ind=iter.GetIndex(); if (val > 0) { unsigned int dorad=(unsigned int)fabs(radimage->GetPixel(ind)); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetLargestPossibleRegion()); GHood.SetLocation(ind); typename ImageType::PixelType p = GHood.GetCenterPixel(); for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=sqrt(((float)ind2[0]-(float)ind[0])*((float)ind2[0]-(float)ind[0])+ ((float)ind2[1]-(float)ind[1])*((float)ind2[1]-(float)ind[1])+ ((float)ind2[2]-(float)ind[2])*((float)ind2[2]-(float)ind[2])); if ( GHood.GetPixel(i) == p && dist <= tardist && diameter > priorimage->GetPixel(ind2)) { priorimage->SetPixel(ind2,diameter); } } } } // now, make rad image std::cout << " Best " << bestind << " gbr " << globalbestrad << std::endl; typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetLargestPossibleRegion()); GHood.SetLocation(bestind); typename ImageType::PixelType p = GHood.GetCenterPixel(); for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0; dist+=sqrt((float)(ind2[0]-(float)bestind[0])*(float)(ind2[0]-(float)bestind[0])+ (float)(ind2[1]-(float)bestind[1])*(float)(ind2[1]-(float)bestind[1])+ (float)(ind2[2]-(float)bestind[2])*(float)(ind2[2]-(float)bestind[2])); if ( dist <= (globalbestrad*sqrt((double)2))) { radimage2->SetPixel(ind2,p); } } // WriteImage(radimage,outname.c_str()); WriteImage(radimage2,outname.c_str()); //WriteImage(priorimage,(std::string("Prior")+outname).c_str()); */ return 0; } template int ImageMath(int argc, char *argv[]) { typedef float PixelType; // const unsigned int ImageDimension = AvantsImageDimension; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2=""; if (argc > argct) { fn2=std::string(argv[argct]); } typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::Pointer varimage = NULL; typename readertype::Pointer reader2 = readertype::New(); typename readertype::Pointer reader1 = readertype::New(); reader2->SetFileName(fn2.c_str()); bool isfloat=false; try { reader2->UpdateLargestPossibleRegion(); } catch(...) { std::cout << " Error reading " << fn2 << " as a file -- will treat " << argv[argct] << " as a float value " << std::endl; isfloat=true; } float floatval=1.0; if (isfloat) floatval=atof(argv[argct]); else image2 = reader2->GetOutput(); reader1->SetFileName(fn1.c_str()); try { reader1->UpdateLargestPossibleRegion(); image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } varimage=ImageType::New(); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( image1->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(image1->GetSpacing()); varimage->SetOrigin(image1->GetOrigin()); varimage->SetDirection(image1->GetDirection()); if (strcmp(operation.c_str(),"mresample") == 0 && !isfloat ) { typename ImageType::SpacingType spc=image2->GetSpacing(); typedef itk::TranslationTransform< double, ImageDimension> TransformType0; typename TransformType0::Pointer m_Transform0=TransformType0::New(); typename TransformType0::ParametersType trans=m_Transform0->GetParameters(); for( unsigned int i=0; iGetSpacing()[i]*image1->GetLargestPossibleRegion().GetSize()[i]/image2->GetLargestPossibleRegion().GetSize()[i]; } image2->SetSpacing(spc); image2->SetOrigin(image1->GetOrigin()); image2->SetDirection(image1->GetDirection()); m_Transform0->SetParameters(trans); std::cout <<" trans " << m_Transform0->GetParameters() << " Nspc " << image2->GetSpacing() << std::endl; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleFilterType; typename ResampleFilterType::Pointer resample = ResampleFilterType::New(); resample->SetTransform( m_Transform0 ); resample->SetInput( image2 ); resample->SetSize( image1->GetLargestPossibleRegion().GetSize() ); resample->SetOutputOrigin( image1->GetOrigin() ); resample->SetOutputSpacing( image1->GetSpacing() ); typename ImageType::IndexType zeroind; zeroind.Fill(0); resample->SetDefaultPixelValue( image1->GetPixel(zeroind) ); resample->UpdateLargestPossibleRegion(); image2=resample->GetOutput(); WriteImage(image2,outname.c_str()); return 0; } float volumeelement=1.0; for (unsigned int i=0; iGetSpacing()[i]; float result=0; Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType ind=vfIter2.GetIndex(); float pix2; if (isfloat) pix2= floatval; else pix2=image2->GetPixel(ind); float pix1 = image1->GetPixel(ind); if (strcmp(operation.c_str(),"m") == 0) result=pix1*pix2; else if (strcmp(operation.c_str(),"+") == 0) result=pix1+pix2; else if (strcmp(operation.c_str(),"-") == 0) result=pix1-pix2; else if (strcmp(operation.c_str(),"/") == 0) { if (pix2 > 0) result=pix1/pix2; } else if (strcmp(operation.c_str(),"^") == 0) { result=pow(pix1,pix2); } else if (strcmp(operation.c_str(),"exp") == 0) { result=exp(pix1*pix2); } else if (strcmp(operation.c_str(),"abs") == 0) { result=fabs(pix1); } else if (strcmp(operation.c_str(),"addtozero") == 0 && pix1 == 0) { result=pix1+pix2; } else if (strcmp(operation.c_str(),"addtozero") == 0 && pix1 != 0) { result=pix1; } else if (strcmp(operation.c_str(),"overadd") == 0 && pix2 != 0) { result=pix2; } else if (strcmp(operation.c_str(),"overadd") == 0 ) { result=pix1; } else if (strcmp(operation.c_str(),"Decision") == 0 ) { result=1./(1.+exp(-1.0*( pix1-0.25)/pix2));} else if (strcmp(operation.c_str(),"total") == 0 ) { result+=pix1*pix2 ;} vfIter2.Set(result); } if (strcmp(operation.c_str(),"total") == 0 ) std::cout << "total: " << result << " total-volume: " << result*volumeelement << std::endl; else std::cout << "operation " << operation << std::endl; if ( outname.length() > 3 ) WriteImage(varimage,outname.c_str()); return 0; } template int TensorFunctions(int argc, char *argv[]) { typedef float PixelType; // typedef itk::Vector TensorType; typedef itk::SymmetricSecondRankTensor< float, 3 > TensorType; typedef typename itk::RGBPixel RGBType; typedef itk::Image TensorImageType; typedef typename TensorImageType::IndexType IndexType; typedef itk::Image ImageType; typedef itk::Image ColorImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef itk::ImageFileWriter ColorWriterType; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::Vector VectorType; typedef itk::Image VectorImageType; typedef itk::ImageRegionIteratorWithIndex vecIterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; unsigned int whichvec=ImageDimension-1; if (argc > argct) { whichvec=atoi(argv[argct]); } argct++; std::cout << " whichvec " << whichvec << std::endl; typename TensorImageType::Pointer timage = NULL; // input tensor image typename ImageType::Pointer vimage = NULL; // output scalar image typename ColorImageType::Pointer cimage = NULL; // output color image typename VectorImageType::Pointer vecimage = NULL; // output vector image ReadTensorImage(timage,fn1.c_str(),false); if (strcmp(operation.c_str(), "TensorIOTest") == 0) { std::cout <<" test function for tensor I/O " << std::endl; WriteTensorImage(timage, outname.c_str() ,false); return 0; } std::cout << " imagedir " << timage->GetDirection() << std::endl; if (strcmp(operation.c_str(), "TensorColor") == 0) { cimage = ColorImageType::New(); cimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); cimage->SetBufferedRegion( timage->GetLargestPossibleRegion() ); cimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); cimage->Allocate(); cimage->SetSpacing(timage->GetSpacing()); cimage->SetOrigin(timage->GetOrigin()); cimage->SetDirection(timage->GetDirection()); } else if (strcmp(operation.c_str(), "TensorToVector") == 0) { vecimage = VectorImageType::New(); vecimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); vecimage->SetBufferedRegion( timage->GetLargestPossibleRegion() ); vecimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); vecimage->Allocate(); vecimage->SetSpacing(timage->GetSpacing()); vecimage->SetOrigin(timage->GetOrigin()); vecimage->SetDirection(timage->GetDirection()); VectorType zero; zero.Fill(0); vecimage->FillBuffer(zero); } else { vimage=ImageType::New(); vimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); vimage->SetBufferedRegion( timage->GetLargestPossibleRegion() ); vimage->SetLargestPossibleRegion( timage->GetLargestPossibleRegion() ); vimage->Allocate(); vimage->SetSpacing(timage->GetSpacing()); vimage->SetOrigin(timage->GetOrigin()); vimage->SetDirection(timage->GetDirection()); } Iterator tIter(timage, timage->GetLargestPossibleRegion() ); for( tIter.GoToBegin(); !tIter.IsAtEnd(); ++tIter ) { IndexType ind=tIter.GetIndex(); float result=0; if (strcmp(operation.c_str(),"TensorFA") == 0) { result=GetTensorFA(tIter.Value()); if (vnl_math_isnan(result)) result=0; vimage->SetPixel(ind,result); } else if (strcmp(operation.c_str(),"TensorMeanDiffusion") == 0) { result=GetTensorADC(tIter.Value(),0); if (vnl_math_isnan(result)) result=0; vimage->SetPixel(ind,result); } else if (strcmp(operation.c_str(),"TensorColor") == 0) { RGBType rgb = GetTensorRGB(tIter.Value()); cimage->SetPixel(ind,rgb); } else if (strcmp(operation.c_str(),"TensorToVector") == 0) { VectorType vv = GetTensorPrincipalEigenvector(tIter.Value(),whichvec); vecimage->SetPixel(ind,vv); } else if (strcmp(operation.c_str(),"TensorToVectorComponent") == 0) { if ( whichvec <= 2 ){ VectorType vv = GetTensorPrincipalEigenvector(tIter.Value(),whichvec); vimage->SetPixel(ind,vv[whichvec]); } else if ( whichvec > 2 && whichvec < 9){ vimage->SetPixel(ind,tIter.Value()[whichvec]); } } } if (strcmp(operation.c_str(), "TensorColor") == 0) { typename ColorWriterType::Pointer cwrite = ColorWriterType::New(); cwrite->SetInput(cimage); cwrite->SetFileName(outname.c_str()); cwrite->Update(); } else if (strcmp(operation.c_str(), "TensorToVector") == 0) { WriteImage(vecimage,outname.c_str()); } else { WriteImage(vimage,outname.c_str()); } return 0; } template int CompareHeadersAndImages(int argc, char *argv[]) { typedef float PixelType; // const unsigned int ImageDimension = AvantsImageDimension; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2=""; if (argc > argct) { fn2=std::string(argv[argct]); } typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; typename readertype::Pointer reader2 = readertype::New(); typename readertype::Pointer reader1 = readertype::New(); reader2->SetFileName(fn2.c_str()); bool isfloat=false; try { reader2->UpdateLargestPossibleRegion(); } catch(...) { std::cout << " Error reading " << fn2 << std::endl; isfloat=true; } float floatval=1.0; if (isfloat) floatval=atof(argv[argct]); else image2 = reader2->GetOutput(); reader1->SetFileName(fn1.c_str()); try { reader1->UpdateLargestPossibleRegion(); image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } // compute error in spacing, in orientation and in offset unsigned int failure=0; float sperr=0,merr=0,operr=0,orsignerr=0; typename ImageType::SpacingType sp1,sp2; sp1=image1->GetSpacing(); sp2=image2->GetSpacing(); for (unsigned int i=0;iGetOrigin(); op2=image2->GetOrigin(); for (unsigned int i=0;i 0 && op2[i] <= 0) orsignerr+=1; else if ( op1[i] < 0 && op2[i] >= 0) orsignerr+=1; } std::cout << " OriginError: " << sqrt(operr) << std::endl; std::cout << " OriginSignError: " << orsignerr << std::endl; for (unsigned int i=0;iGetDirection()[i][j]-image2->GetDirection()[i][j]; merr+=temp*temp; } std::cout << " OrientError: " << sqrt(merr) << std::endl; bool samesize=true; for (unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i] != image2->GetLargestPossibleRegion().GetSize()[i] ) samesize=false; if (samesize ) { // run a quick registration if (false){ typedef typename itk::ImageMomentsCalculator< ImageType > ImageCalculatorType; typename ImageCalculatorType::Pointer calculator = ImageCalculatorType::New(); calculator->SetImage( image1 ); typename ImageCalculatorType::VectorType fixed_center; fixed_center.Fill(0); typename ImageCalculatorType::VectorType moving_center; moving_center.Fill(0); try { calculator->Compute(); fixed_center = calculator->GetCenterOfGravity(); calculator->SetImage( image2 ); try { calculator->Compute(); moving_center = calculator->GetCenterOfGravity(); } catch(...) { std::cout << " zero image2 error "; fixed_center.Fill(0); } } catch(...) { std::cout << " zero image1 error "; } typedef itk::TranslationTransform< double, ImageDimension> TransformType0; typename TransformType0::Pointer m_Transform0=TransformType0::New(); typename TransformType0::ParametersType trans=m_Transform0->GetParameters(); for( unsigned int i=0; iSetParameters(trans); std::cout <<" trans " << m_Transform0->GetParameters() << std::endl; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleFilterType; typename ResampleFilterType::Pointer resample = ResampleFilterType::New(); resample->SetTransform( m_Transform0 ); resample->SetInput( image2 ); resample->SetSize( image1->GetLargestPossibleRegion().GetSize() ); resample->SetOutputOrigin( image1->GetOrigin() ); resample->SetOutputSpacing( image1->GetSpacing() ); typename ImageType::IndexType zeroind; zeroind.Fill(0); resample->SetDefaultPixelValue( image1->GetPixel(zeroind) ); resample->UpdateLargestPossibleRegion(); typename ImageType::Pointer varimage=resample->GetOutput(); } float i1norm=0,i2norm=0,i1i2norm=0; //i3norm=0,i1i3norm=0; unsigned long ct1=1,ct2=1,ct12=1; //ct3=1,ct13=1; Iterator vfIter2( image1, image1->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType ind=vfIter2.GetIndex(); float pix2; if (isfloat) pix2= floatval; else pix2=image2->GetPixel(ind); if ( vnl_math_isnan(pix2) || vnl_math_isinf(pix2) ) { pix2=0; image2->SetPixel(ind,0);} // float pix3=varimage->GetPixel(ind); float pix1 = image1->GetPixel(ind); if (pix1 > 0 ) { i1norm+=fabs(pix1); ct1++; } if (pix2 > 0 ) { i2norm+=fabs(pix2); ct2++; } //if (pix3 > 0 ) { i3norm+=fabs(pix3); ct3++; } } float mean1=i1norm/ct1; if (mean1 == 0) mean1=1; float mean2=i2norm/ct2; if (mean2 == 0) mean2=1; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType ind=vfIter2.GetIndex(); float pix2; if (isfloat) pix2= floatval; else pix2=image2->GetPixel(ind)/mean2; // float pix3=vfIter2.Get()/mean2; float pix1 = image1->GetPixel(ind)/mean1; if ( pix1 > 0 || pix2 > 0) { i1i2norm+=fabs(pix1-pix2); ct12++; } // if ( pix1 > 0 || pix3 > 0) //{ // i1i3norm+=fabs(pix1-pix3); // ct13++; //} } float idice0 = 1.0 - 2.0*i1i2norm/ct12 / ( i1norm/ct1 + i2norm / ct2 ); // float idice1 = 1.0 - 2.0*i1i3norm/ct13 / ( i1norm/ct1 + i3norm / ct3 ); std::cout << " DiceImageDifference: " << idice0 << " IntensityDifference: " << i1i2norm << std::endl; //std::cout << " CenterOfMassTransImageDifference: " << idice1 << " and " << i1i3norm << std::endl; } typename ImageType::PointType fixedorig=image2->GetOrigin(); if ( orsignerr > 0 ) { failure=1; // now fix the error for (unsigned int i=0;i 0 && op2[i] < 0 ) || (op1[i] < 0 && op2[i] > 0) ) fixedorig[i]*=(-1.0); else if ( (op1[i] > 0 && op2[i] == 0 ) || (op1[i] < 0 && op2[i] == 0) ) fixedorig[i]=image1->GetOrigin()[i]; } } image2->SetOrigin(fixedorig); // if ( sqrt(operr) > 100) failure= if (sqrt(merr) >= 0.7 && failure==0 ) failure=2; if (sqrt(merr) >= 0.7 && failure != 0 ) failure=3; if (failure > 1) { image2->SetDirection(image1->GetDirection()); } // write repaired images typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( image2 ); writer->Write(); std::cout << " FailureState: " << failure << " for " << fn2 << std::endl; return failure; } template typename TImage::Pointer BinaryThreshold(typename TImage::PixelType low, typename TImage::PixelType high,typename TImage::PixelType replaceval, typename TImage::Pointer input) { //std::cout << " Binary Thresh " << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } // template // typename TImage::Pointer // SegmentKMeans(typename TImage::Pointer image , unsigned int nclasses) // { // // typedef TImage ImageType; // typedef typename TImage::PixelType PixelType; // enum { ImageDimension = ImageType::ImageDimension }; // typedef itk::ImageRegionIteratorWithIndex Iterator; // // typedef itk::Statistics::ScalarImageToListAdaptor< ImageType > AdaptorType; // // typename AdaptorType::Pointer adaptor = AdaptorType::New(); // // adaptor->SetImage( image ); // // // Define the Measurement vector type from the AdaptorType // typedef typename AdaptorType::MeasurementVectorType MeasurementVectorType; // // // Create the K-d tree structure // typedef itk::Statistics::WeightedCentroidKdTreeGenerator< // AdaptorType > // TreeGeneratorType; // // typename TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New(); // // treeGenerator->SetSample( adaptor ); // treeGenerator->SetBucketSize( 16 ); // treeGenerator->Update(); // // typedef typename TreeGeneratorType::KdTreeType TreeType; // typedef itk::Statistics::KdTreeBasedKmeansEstimator EstimatorType; // // typename EstimatorType::Pointer estimator = EstimatorType::New(); // // typename EstimatorType::ParametersType initialMeans( nclasses ); // // Iterator vfIter2( image, image->GetLargestPossibleRegion() ); // double mx =-1.e12, mn=1.e12; // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // double px = vfIter2.Get(); // if (px > mx) mx=px; // else if (px < mn) mn=px; // } // float range=(mx-mn); // // float bins=1.0/((float)nclasses+1.); // for (unsigned int i=0; iSetParameters( initialMeans ); // // estimator->SetKdTree( treeGenerator->GetOutput() ); // estimator->SetMaximumIteration( 200 ); // estimator->SetCentroidPositionChangesThreshold(0.0); // estimator->StartOptimization(); // // typename EstimatorType::ParametersType estimatedMeans = estimator->GetParameters(); // // // typename ImageType::Pointer varimage=ImageType::New(); // varimage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // varimage->SetBufferedRegion( image->GetLargestPossibleRegion() ); // varimage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // varimage->Allocate(); // varimage->SetSpacing(image->GetSpacing()); // varimage->SetOrigin(image->GetOrigin()); // varimage->SetDirection(image->GetDirection()); // // // float var=sqrt(range); // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // double px = vfIter2.Get(); // unsigned int best=0; // float mindist=1.e9; // for ( unsigned int i = 0 ; i < nclasses ; ++i ) // { // float dist=fabs(px-estimatedMeans[i]); // if (dist < mindist) { mindist=dist; best=i; } // //vec[i]=exp(-1.0*dist*dist/var); // } // varimage->SetPixel(vfIter2.GetIndex(),best+1); // // vecimage->SetPixel(vfIter2.GetIndex(),vec); // } // // return varimage; // // // } template typename TImage::Pointer Morphological( typename TImage::Pointer input,float rad, unsigned int option, float dilateval) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::PixelType PixelType; if (option == 0) std::cout << " binary eroding the image " << std::endl; else if (option == 1) std::cout << " binary dilating the image " << std::endl; else if (option == 2) std::cout << " binary opening the image " << std::endl; else if (option == 3) std::cout << " binary closing the image " << std::endl; else if (option == 4) std::cout << " grayscale eroding the image " << std::endl; else if (option == 5) std::cout << " grayscale dilating the image " << std::endl; else if (option == 6) std::cout << " grayscale opening the image " << std::endl; else if (option == 7) std::cout << " grayscale closing the image " << std::endl; typedef itk::BinaryBallStructuringElement< PixelType, ImageDimension > StructuringElementType; // Software Guide : BeginCodeSnippet typedef itk::BinaryErodeImageFilter< TImage, TImage, StructuringElementType > ErodeFilterType; typedef itk::BinaryDilateImageFilter< TImage, TImage, StructuringElementType > DilateFilterType; //typedef itk::BinaryMorphologicalOpeningImageFilter< // TImage, // TImage, // StructuringElementType > OpeningFilterType; //typedef itk::BinaryMorphologicalClosingImageFilter< // TImage, // TImage, // StructuringElementType > ClosingFilterType; typedef itk::GrayscaleErodeImageFilter< TImage, TImage, StructuringElementType > GrayscaleErodeFilterType; typedef itk::GrayscaleDilateImageFilter< TImage, TImage, StructuringElementType > GrayscaleDilateFilterType; typename ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); //typename OpeningFilterType::Pointer binaryOpen = OpeningFilterType::New(); //typename ClosingFilterType::Pointer binaryClose = ClosingFilterType::New(); typename GrayscaleErodeFilterType::Pointer grayscaleErode = GrayscaleErodeFilterType::New(); typename GrayscaleDilateFilterType::Pointer grayscaleDilate = GrayscaleDilateFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius((unsigned long) rad ); // 3x3x3 structuring element structuringElement.CreateStructuringElement(); binaryErode->SetKernel( structuringElement ); binaryDilate->SetKernel( structuringElement ); //binaryOpen->SetKernal( structuringElement ); //binaryClose->SetKernel( structuringElement ); grayscaleErode->SetKernel( structuringElement ); grayscaleDilate->SetKernel( structuringElement ); // It is necessary to define what could be considered objects on the binary // images. This is specified with the methods \code{SetErodeValue()} and // \code{SetDilateValue()}. The value passed to these methods will be // considered the value over which the dilation and erosion rules will apply binaryErode->SetErodeValue( 1 ); binaryDilate->SetDilateValue( 1 ); typename TImage::Pointer temp; if (option == 1) { std::cout << " Dilate " << rad << std::endl; binaryDilate->SetInput( input ); binaryDilate->Update(); temp = binaryDilate->GetOutput(); } else if (option == 0) { std::cout << " Erode " << rad << std::endl; binaryErode->SetInput( input );//binaryDilate->GetOutput() ); binaryErode->Update(); temp = binaryErode->GetOutput(); } else if (option == 2) { // dilate(erode(img)) std::cout << " Binary Open " << rad << std::endl; //binaryOpen->SetInput( input );//binaryDilate->GetOutput() ); //binaryOpen->Update(); binaryErode->SetInput( input ); binaryDilate->SetInput( binaryErode->GetOutput() ); binaryDilate->Update(); temp = binaryDilate->GetOutput(); } else if (option == 3) { std::cout << " Binary Close " << rad << std::endl; //binaryClose->SetInput( input );//binaryDilate->GetOutput() ); //binaryClose->Update(); binaryDilate->SetInput( input ); binaryErode->SetInput( binaryDilate->GetOutput() ); binaryErode->Update(); temp = binaryErode->GetOutput(); } else if (option == 4) { std::cout << " Grayscale Erode " << rad << std::endl; grayscaleErode->SetInput( input );//binaryDilate->GetOutput() ); grayscaleErode->Update(); temp = binaryErode->GetOutput(); } else if (option == 5) { std::cout << " Grayscale Dilate " << rad << std::endl; grayscaleDilate->SetInput( input );//binaryDilate->GetOutput() ); grayscaleDilate->Update(); temp = binaryDilate->GetOutput(); } else if (option == 6) { std::cout << " Grayscale Open " << rad << std::endl; grayscaleErode->SetInput( input );//binaryDilate->GetOutput() ); grayscaleErode->Update(); grayscaleDilate->SetInput( grayscaleErode->GetOutput() ); grayscaleDilate->Update(); temp = grayscaleDilate->GetOutput(); } else if (option == 7) { std::cout << " Grayscale Close " << rad << std::endl; grayscaleDilate->SetInput( input );//binaryDilate->GetOutput() ); grayscaleDilate->Update(); grayscaleErode->SetInput( grayscaleDilate->GetOutput() ); grayscaleErode->Update(); temp = grayscaleErode->GetOutput(); } if (option == 0 ) { // FIXME - replace with threshold filter? typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; ImageIteratorType o_iter( temp, temp->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { if (o_iter.Get() > 0.5 && input->GetPixel(o_iter.GetIndex()) > 0.5) o_iter.Set(1); else o_iter.Set(0); ++o_iter; } } return temp; } // template // typename TImage::Pointer // BayesianSegmentation(typename TImage::Pointer image , unsigned int nclasses, std::string priorfn , unsigned int nsmooth = 2 ) // { // // typedef TImage ImageType; // typedef typename TImage::PixelType PixelType; // enum { ImageDimension = ImageType::ImageDimension }; // typedef itk::ImageRegionIteratorWithIndex Iterator; // // // const unsigned int ImageDimension = AvantsImageDimension; // typedef itk::Vector VectorType; // typedef itk::Image FieldType; // typedef itk::ImageFileReader readertype; // typedef itk::ImageFileWriter writertype; // typedef typename ImageType::IndexType IndexType; // typedef typename ImageType::SizeType SizeType; // typedef typename ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; // typedef itk::ImageRegionIteratorWithIndex Iterator; // // // // typedef itk::Statistics::ScalarImageToListAdaptor< ImageType > AdaptorType; // typename AdaptorType::Pointer adaptor = AdaptorType::New(); // adaptor->SetImage( image ); // // Define the Measurement vector type from the AdaptorType // typedef typename AdaptorType::MeasurementVectorType MeasurementVectorType; // // Create the K-d tree structure // typedef itk::Statistics::WeightedCentroidKdTreeGenerator< // AdaptorType > // TreeGeneratorType; // typename TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New(); // treeGenerator->SetSample( adaptor ); // treeGenerator->SetBucketSize( 16 ); // treeGenerator->Update(); // typedef typename TreeGeneratorType::KdTreeType TreeType; // typedef itk::Statistics::KdTreeBasedKmeansEstimator EstimatorType; // typename EstimatorType::Pointer estimator = EstimatorType::New(); // typename EstimatorType::ParametersType initialMeans( nclasses ); // Iterator vfIter2( image, image->GetLargestPossibleRegion() ); // double mx =-1.e12, mn=1.e12; // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // double px = vfIter2.Get(); // if (px > mx) mx=px; // else if (px < mn) mn=px; // } // float range=(mx-mn); // float bins=1.0/((float)nclasses+1.); // for (unsigned int i=0; iSetParameters( initialMeans ); // estimator->SetKdTree( treeGenerator->GetOutput() ); // estimator->SetMaximumIteration( 200 ); // estimator->SetCentroidPositionChangesThreshold(0.0); // estimator->StartOptimization(); // typename EstimatorType::ParametersType estimatedMeans = estimator->GetParameters(); // // typename ImageType::Pointer varimage=ImageType::New(); // varimage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // varimage->SetBufferedRegion( image->GetLargestPossibleRegion() ); // varimage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // varimage->SetSpacing(image->GetSpacing()); // varimage->SetOrigin(image->GetOrigin()); // varimage->SetDirection(image->GetDirection()); // varimage->Allocate(); // // std::vector estimatedVar(nclasses,0); // std::vector estimatedCounts(nclasses,0); // // // float var=sqrt(range); // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // double px = vfIter2.Get(); // unsigned int best=0; // float mindist=1.e9; // for ( unsigned int i = 0 ; i < nclasses ; ++i ) // { // float dist=fabs(px-estimatedMeans[i]); // if (dist < mindist) { mindist=dist; best=i; } // //vec[i]=exp(-1.0*dist*dist/var); // } // varimage->SetPixel(vfIter2.GetIndex(),best); // } // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // double px = vfIter2.Get(); // unsigned int i = (unsigned int) varimage->GetPixel(vfIter2.GetIndex()); // estimatedCounts[i]=estimatedCounts[i]+1; // float dist=(px -estimatedMeans[i]); // estimatedVar[i]+=dist*dist; // } // // for (unsigned int i=0; i 0) estimatedVar[i]=(estimatedVar[i])/ct; // else estimatedVar[i]=0; // std::cout << " Sample SD Ests " << sqrt(estimatedVar[i]) << " Mean " << estimatedMeans[i] << std::endl; // } // // typedef float InputPixelType; // typedef itk::VectorImage< InputPixelType, ImageDimension > InputImageType; // typedef float LabelType; // typedef float PriorType; // typedef float PosteriorType; // typedef itk::BayesianClassifierImageFilter< // InputImageType,LabelType, // PosteriorType,PriorType > ClassifierFilterType; // // typename InputImageType::Pointer vecImage = InputImageType::New(); // typedef typename InputImageType::PixelType VecPixelType; // vecImage->SetSpacing(image->GetSpacing()); // vecImage->SetOrigin(image->GetOrigin()); // vecImage->SetRegions( image->GetLargestPossibleRegion() ); // vecImage->SetVectorLength(nclasses); // vecImage->Allocate(); // VecPixelType vvv(nclasses); // vvv.Fill(0); // vecImage->FillBuffer(vvv); // // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { // double px = vfIter2.Get(); // VecPixelType probs(nclasses); // float total=0; // for (unsigned int i=0; i0) probs[i]/=total; // } // vecImage->SetPixel( vfIter2.GetIndex(), probs); // } // // typename ClassifierFilterType::Pointer filter = ClassifierFilterType::New(); // // // typedef itk::ImageFileReader< InputImageType > ReaderType; // typename ReaderType::Pointer reader = ReaderType::New(); // typename InputImageType::Pointer priors=NULL; // // if (priorfn.length() > 3 ) // { // std::cout << " Setting Priors " << priorfn << std::endl; // bool geometric=false; // if ( strcmp(priorfn.c_str(),"Geometric") == 0) geometric=true; // if (geometric) // { // std::cout <<" Using a geometric thickness prior to aid cortical segmentation " << std::endl; // typename ImageType::Pointer outbrainmask = BinaryThreshold(0,nclasses-3,1,varimage); // typename ImageType::Pointer inwmask = BinaryThreshold(nclasses-1,nclasses,1,varimage); // typename ImageType::Pointer outwmask = BinaryThreshold(0,nclasses-2,1,varimage); // typedef itk::DanielssonDistanceMapImageFilter FilterType; // typename FilterType::Pointer distmap = FilterType::New(); // distmap->InputIsBinaryOn(); // distmap->SetUseImageSpacing(true); // distmap->SetInput(outbrainmask); // distmap->Update(); // typename ImageType::Pointer distcortex=distmap->GetOutput(); // // typename FilterType::Pointer distmap2 = FilterType::New(); // distmap2->InputIsBinaryOn(); // distmap2->SetUseImageSpacing(true); // distmap2->SetInput(inwmask); // distmap2->Update(); // typename ImageType::Pointer distwm=distmap2->GetOutput(); // // typedef itk::LaplacianRecursiveGaussianImageFilter dgf; // typename dgf::Pointer lfilter = dgf::New(); // lfilter->SetSigma(1.3); // lfilter->SetInput(distwm); // lfilter->Update(); // typename ImageType::Pointer image2=lfilter->GetOutput(); // typedef itk::RescaleIntensityImageFilter RescaleFilterType; // typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); // rescaler->SetOutputMinimum( 0 ); // rescaler->SetOutputMaximum( 1 ); // rescaler->SetInput( image2 ); // rescaler->Update(); // typename ImageType::Pointer sulci= rescaler->GetOutput(); // // priors= InputImageType::New(); // typedef typename InputImageType::PixelType VecPixelType; // priors->SetSpacing(image->GetSpacing()); // priors->SetOrigin(image->GetOrigin()); // priors->SetDirection(image->GetDirection()); // priors->SetRegions( image->GetLargestPossibleRegion() ); // priors->SetVectorLength(nclasses); // priors->Allocate(); // std::cout <<" Allocated " << std::endl; // // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // // std::cout <<" ind " <GetPixel( vfIter2.GetIndex()); // // float inw = inwmask->GetPixel( vfIter2.GetIndex()); // float distance = distcortex->GetPixel( vfIter2.GetIndex()); // float wdistance = distwm->GetPixel( vfIter2.GetIndex()); // VecPixelType probs(nclasses); // probs.Fill(1.0/(float)nclasses); // VecPixelType posteriors=vecImage->GetPixel(vfIter2.GetIndex()); // if (nclasses > 2) // { // float dvar=2; // float basedist=4; // float distmag=basedist-distance; // // if (distmag > 0) distmag=0; // distmag*=distmag; // float gdistprob=1.0-exp(-1.0*distmag/dvar); // // float wdistprob=1.0/(1.0+exp(-1.0*distance/5)); // // float wdistmag=basedist-wdistance; // if (wdistmag > 0) wdistmag=0; // wdistmag*=wdistmag; // float gdistprob2=exp(-1.0*wdistmag/dvar); // // float sulcprob=sulci->GetPixel( vfIter2.GetIndex()); // float sdiff=(0.25-sulcprob); // if (sdiff > 0) sdiff=0; // sdiff*=sdiff; // sulcprob=exp(-1.0*sdiff/0.5); // // std::cout << " Sulc " << sulcprob << std::endl; // // bool test = (outbrain < 1 && inw > 1); // if ( true ) // { // for (unsigned int i=0; i 0) probs[i]=sulcprob; // } // } // else // { // for (unsigned int i=0; i0) probs[i]/=prtotal; else probs[i]=1.0/(float)nclasses; // if (pototal>0) posteriors[i]/=pototal; else posteriors[i]=1.0/(float)nclasses; // } // priors->SetPixel( vfIter2.GetIndex(), probs); // vecImage->SetPixel( vfIter2.GetIndex(), posteriors); // } // std::cout << " ok " << std::endl; // // // } // else // { // reader->SetFileName( priorfn.c_str() ); // reader->Update(); // priors=reader->GetOutput(); // // for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) // { // VecPixelType posteriors=vecImage->GetPixel(vfIter2.GetIndex()); // VecPixelType probs=priors->GetPixel(vfIter2.GetIndex()); // for (unsigned int i=0; i0) probs[i]/=prtotal; else probs[i]=1.0/(float)nclasses; // if (pototal>0) posteriors[i]/=pototal; else posteriors[i]=1.0/(float)nclasses; // } // vecImage->SetPixel( vfIter2.GetIndex(), posteriors); // } // } // // if (priors) filter->SetInput( 1, priors ); // Bug -- // // classification filter does not actually use priors // } else std::cout << " No Priors " << std::endl; // // filter->SetInput( vecImage ); // // // if( nsmooth >= 1 ) // { // std::cout << " Smoothing Iterations: " << nsmooth << std::endl; // filter->SetNumberOfSmoothingIterations( nsmooth ); // typedef typename ClassifierFilterType::ExtractedComponentImageType ExtractedComponentImageType; // typedef itk::DiscreteGaussianImageFilter< // ExtractedComponentImageType, ExtractedComponentImageType > SmoothingFilterType; // typedef itk::BilateralImageFilter< // ExtractedComponentImageType, ExtractedComponentImageType > SmoothingFilterType2; // typename SmoothingFilterType::Pointer smoother = SmoothingFilterType::New(); // smoother->SetVariance(1.0); // smoother->SetUseImageSpacingOff(); // //smoother->SetDomainSigma(1); // //smoother->SetRangeSigma(1); // filter->SetSmoothingFilter( smoother ); // } // // // SET FILTER'S PRIOR PARAMETERS // // do nothing here to default to uniform priors // // otherwise set the priors to some user provided values // // // // // Setup writer.. Rescale the label map to the dynamic range of the // // datatype and write it // // // filter->Update(); // // return filter->GetOutput(); // // } template int NegativeImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2=""; if (argc > argct) { fn2=std::string(argv[argct]); } typename ImageType::Pointer image1 = NULL; typename readertype::Pointer reader1 = readertype::New(); reader1->SetFileName(fn1.c_str()); reader1->UpdateLargestPossibleRegion(); try { image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } Iterator vfIter2( image1, image1->GetLargestPossibleRegion() ); double mx =-1.e12, mn=1.e12; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { double px = vfIter2.Get(); if (px > mx) mx=px; else if (px < mn) mn=px; } if (mx == mn) { mx=1; mn=0; } for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType ind=vfIter2.GetIndex(); double pix = image1->GetPixel(ind); pix = (pix - mn)/(mx-mn); pix = (1.0 - pix)*(mx-mn); vfIter2.Set(pix); } typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( image1 ); writer->Write(); return 0; } // template // typename TImage::Pointer // //void // SegmentMRF(typename TImage::Pointer image , // typename TImage::Pointer labelimage, unsigned int nclasses, float smf, unsigned int maxits) // { // // typedef TImage ImageType; // typedef typename TImage::PixelType PixelType; // enum { ImageDimension = ImageType::ImageDimension }; // enum { Dimension = ImageType::ImageDimension }; // // // // const unsigned int NUMBANDS=1; // typedef itk::Image,ImageDimension> VecImageType; // typedef typename VecImageType::PixelType VecPixelType; // // /** copy the input image into this vector image. stupid. */ // // typename VecImageType::Pointer vecImage = VecImageType::New(); // vecImage->SetSpacing(image->GetSpacing()); // vecImage->SetOrigin(image->GetOrigin()); // vecImage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // vecImage->SetBufferedRegion( image->GetLargestPossibleRegion() ); // vecImage->Allocate(); // VecPixelType vvv; // vvv.Fill(0); // vecImage->FillBuffer(vvv); // // // setup the iterators // // typedef VecImageType::PixelType::VectorType VecPixelType; // // enum { VecImageDimension = VecImageType::ImageDimension }; // typedef itk::ImageRegionIterator< VecImageType > VecIterator; // // VecIterator outIt( vecImage, vecImage->GetBufferedRegion() ); // for (outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt) // { // vvv[0]=image->GetPixel(outIt.GetIndex()); // outIt.Set(vvv); // } // // // namespace stat = itk::Statistics; // typedef itk::Image ClassImageType; // typedef stat::MahalanobisDistanceMembershipFunction< VecPixelType > // MembershipFunctionType ; // typedef typename MembershipFunctionType::Pointer MembershipFunctionPointer ; // typedef std::vector< MembershipFunctionPointer > MembershipFunctionPointerVector; // // typedef itk::ImageGaussianModelEstimator // ImageGaussianModelEstimatorType; // // typename ImageGaussianModelEstimatorType::Pointer applyEstimateModel = // ImageGaussianModelEstimatorType::New(); // /* // typedef itk::Statistics::WeightedCentroidKdTreeGenerator< // AdaptorType > // TreeGeneratorType; // typedef typename TreeGeneratorType::KdTreeType TreeType; // typedef itk::Statistics::KdTreeBasedKmeansEstimator EstimatorType; // // */ // applyEstimateModel->SetNumberOfModels(nclasses); // applyEstimateModel->SetInputImage(vecImage); // applyEstimateModel->SetTrainingImage(labelimage); // // //Run the gaussian classifier algorithm // applyEstimateModel->Update(); // applyEstimateModel->Print(std::cout); // // MembershipFunctionPointerVector membershipFunctions = // applyEstimateModel->GetMembershipFunctions(); // // //---------------------------------------------------------------------- // //Set the decision rule // //---------------------------------------------------------------------- // typedef typename itk::DecisionRuleBase::Pointer DecisionRuleBasePointer; // // typedef itk::MinimumDecisionRule DecisionRuleType; // typename DecisionRuleType::Pointer // myDecisionRule = DecisionRuleType::New(); // // //---------------------------------------------------------------------- // // Set the classifier to be used and assigne the parameters for the // // supervised classifier algorithm except the input image which is // // grabbed from the MRF application pipeline. // //---------------------------------------------------------------------- // //--------------------------------------------------------------------- // typedef PixelType MeasurementVectorType; // // typedef itk::ImageClassifierBase< VecImageType, // ClassImageType > ClassifierType; // // typedef typename itk::ClassifierBase::Pointer // ClassifierBasePointer; // // typedef typename ClassifierType::Pointer ClassifierPointer; // ClassifierPointer myClassifier = ClassifierType::New(); // // Set the Classifier parameters // myClassifier->SetNumberOfClasses(nclasses); // // // Set the decison rule // myClassifier-> // SetDecisionRule((DecisionRuleBasePointer) myDecisionRule ); // // //Add the membership functions // double meanDistance=0; // for( unsigned int i=0; iAddMembershipFunction( membershipFunctions[i] ); // meanDistance+=membershipFunctions[i]->GetMean()[0]; // } // meanDistance/=(float)nclasses; // std::cout << " mean dist " << meanDistance << std::endl; // // // //---------------------------------------------------------------------- // // Set the MRF labeller and populate the parameters // //---------------------------------------------------------------------- // // //Set the MRF labeller // typedef itk::MRFImageFilter MRFImageFilterType; // typename MRFImageFilterType::Pointer applyMRFImageFilter = MRFImageFilterType::New(); // // // Set the MRF labeller parameters // applyMRFImageFilter->SetNumberOfClasses( nclasses ); // applyMRFImageFilter->SetMaximumNumberOfIterations( maxits ); // applyMRFImageFilter->SetErrorTolerance( 1.e-4 ); // applyMRFImageFilter->SetSmoothingFactor( smf ); // applyMRFImageFilter->SetInput(vecImage); // applyMRFImageFilter->SetClassifier( myClassifier ); // // //For setting up a square/cubic or hypercubic neighborhood // applyMRFImageFilter->SetNeighborhoodRadius( 1 ); // std::vector weights = // applyMRFImageFilter->GetMRFNeighborhoodWeight(); // std::vector testNewNeighborhoodWeight( weights.size(), 1); // double totalWeight = 0; // for(std::vector< double >::const_iterator wcIt = weights.begin(); // wcIt != weights.end(); ++wcIt ) // { // totalWeight += *wcIt; // } // unsigned int jj = 0; // for(std::vector< double >::iterator wIt = weights.begin(); // wIt != weights.end(); wIt++ ) // { // testNewNeighborhoodWeight[jj] = static_cast< double > ( (*wIt) * meanDistance / (2 * totalWeight)); // // std::cout << " ow " << weights[jj] << " nw " << testNewNeighborhoodWeight[jj] << std::endl; // jj++; // } // // // applyMRFImageFilter->SetMRFNeighborhoodWeight( testNewNeighborhoodWeight ); // // applyMRFImageFilter->SetMRFNeighborhoodWeight( weights ); // // //Kick off the MRF labeller function // applyMRFImageFilter->Update(); // // applyMRFImageFilter->Print(std::cout); // std::cout << "Number of Iterations : " << applyMRFImageFilter->GetNumberOfIterations() // << std::endl; // std::cout << "Stop condition: (1) Maximum number of iterations (2) Error tolerance: " // << applyMRFImageFilter->GetStopCondition() << std::endl; // // typename ClassImageType::Pointer outClassImage = applyMRFImageFilter->GetOutput(); // // //Testing of different parameter access functions in the filter // std::cout << "The number of classes labelled was: " << // applyMRFImageFilter->GetNumberOfClasses() << std::endl; // std::cout << "The maximum number of iterations were: " << // applyMRFImageFilter->GetMaximumNumberOfIterations() << std::endl; // std::cout << "The error tolerace threshold was: " << // applyMRFImageFilter->GetErrorTolerance() << std::endl; // std::cout << "The smoothing MRF parameter used was: " << // applyMRFImageFilter->GetSmoothingFactor() << std::endl; // std::cout << "The MRF neighborhood weights are: " << std::endl; // // // return outClassImage; // // } template typename TImage::Pointer //void itkMRIBiasFieldCorrectionFilter(typename TImage::Pointer image , typename TImage::Pointer labelimage, unsigned int sd=2) { std::cout << "doing Bias corr " << std::endl; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; // bool SaveImages = false; // WriteImage(image,"temp1.nii"); // WriteImage(labelimage,"temp2.nii"); // class statistics for two classes: a bright sphere and background // 3 or 1 classes ? SD //unsigned int numclasses=1; unsigned int numclasses=4; itk::Array classMeans(numclasses); itk::Array classSigmas(numclasses); itk::Array classCounts(numclasses); classMeans.Fill(0.0); classSigmas.Fill(0.0); classCounts.Fill(0); //******** get output mask from image SD typename ImageType::Pointer outputmask = BinaryThreshold(0.1,1.e9,1,image); //******** get output mask from image SD // WriteImage(mask,"outMK1.nii"); // SD play with mask to see if we can move the artifact line // mask=MorphologicalErosion(1.5, mask); //mask=MorphologicalErosion(3.5, mask); //WriteImage(mask,"outMK2.nii"); ImageIteratorType o_iter( labelimage,labelimage->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { unsigned int label = (unsigned int) o_iter.Get(); float pix = image->GetPixel(o_iter.GetIndex()); // uncomment for using one tissue class only for input mask SD /* if ( mask->GetPixel(o_iter.GetIndex()) == 1 ) { label=label-1; unsigned int ind=0; classCounts[ind] +=1; float n = classCounts[ind]; classMeans[ind] = (n-1.0)/( n )* classMeans[ind] + 1.0 / n * pix; double sqrdf = ( pix - classMeans[ind])*( pix - classMeans[ind]); if (n > 1)classSigmas[ind]= (n-1)/n * classSigmas[ind] + 1.0 / (n-1) * sqrdf; } */ // uncomment for using 3 tissue classes SD if ( outputmask->GetPixel(o_iter.GetIndex()) == 1 ) { //label=label-1; classCounts[label] +=1; float n = classCounts[label]; classMeans[label] = (n-1.0)/( n )* classMeans[label] + 1.0 / n * pix; double sqrdf = ( pix - classMeans[label])*( pix - classMeans[label]); if (n > 1)classSigmas[label]= (n-1)/n * classSigmas[label] + 1.0 / (n-1) * sqrdf; } ++o_iter ; } for (unsigned int k=0; k < numclasses; k++) { classSigmas[k]=sqrt(classSigmas[k]); std::cout << " Initial Means pre-bias " << classMeans[k] << " sig " << classSigmas[k] << std::endl; } // creats a normal random variate generator //itk::Statistics::NormalVariateGenerator::Pointer randomGenerator = // itk::Statistics::NormalVariateGenerator::New() ; // creates a bias correction filter and run it. typedef itk::MRIBiasFieldCorrectionFilter FilterType; std::cout << "before new filter" << std::endl; typename FilterType::Pointer filter = FilterType::New() ; std::cout << "after new filter" << std::endl; // typename FilterType::BiasFieldType::CoefficientArrayType filter->SetInput( image.GetPointer() ) ; //filter->SetInput( image ) ; filter->IsBiasFieldMultiplicative( true ) ; // correct with multiplicative bias unsigned int biasDegree=4; filter->SetBiasFieldDegree( biasDegree ) ; // default value = 3 filter->SetTissueClassStatistics( classMeans, classSigmas ) ; //filter->SetOptimizerGrowthFactor( 1.01 ) ; // default value //filter->SetOptimizerInitialRadius( 0.02 ) ; // default value // SD debug don't do interslice correction //filter->SetUsingInterSliceIntensityCorrection( true ) ; // default value filter->SetUsingInterSliceIntensityCorrection( false ) ; // default value filter->SetVolumeCorrectionMaximumIteration( 200) ; // default value = 100 filter->SetInterSliceCorrectionMaximumIteration( 100 ) ; // default value = 100 filter->SetUsingSlabIdentification( false ) ; // default value = false //filter->SetSlabBackgroundMinimumThreshold( 0 ) ; // default value //filter->SetSlabNumberOfSamples( 10 ) ; // default value //filter->SetSlabTolerance(0.0) ; // default value filter->SetSlicingDirection(sd) ; // default value filter->SetUsingBiasFieldCorrection( true ) ; // default value filter->SetGeneratingOutput( true ) ; // default value filter->SetInputMask( outputmask ) ; //******** Try different output mask SD // filter->SetOutputMask( labelimage ) ; filter->SetOutputMask( outputmask ) ; // filter->SetDebug( true ); // WriteImage(mask,"mask.nii"); // WriteImage(outputmask,"outputmask.nii"); // WriteImage(image,"image.nii"); // WriteImage(labelimage,"labelimage.nii"); //******** Try different output mask SD // default schedule is 2 2 2 - 1 1 1, let's change this bool setnewsched=false; if (setnewsched) { unsigned int nlev=1; typename FilterType::ScheduleType schedule ( nlev, ImageDimension) ; schedule.Fill( 4 ); // for (unsigned int jj=0; jjSetNumberOfLevels( nlev ) ; // Important to set this first, otherwise the filter rejects the new schedule filter->SetSchedule( schedule ) ; } // filter->SetInitialBiasFieldCoefficients(initCoefficients); filter->SetVolumeCorrectionMaximumIteration( 200 ) ; // default value = 100 filter->SetInterSliceCorrectionMaximumIteration( 100 ) ; // default value = 100 //filter->SetOptimizerInitialRadius( 0.02 ) ; // default value //timing long int t1 = time(NULL); filter->Update() ; long int t2 = time(NULL); std::cout << "Run time (in s)" << t2-t1 << std::endl ; return filter->GetOutput(); } // template // typename TImage::Pointer // //void // SegmentMRFKM(typename TImage::Pointer image , // typename TImage::Pointer labelimage, unsigned int nclasses, float smf, unsigned int maxit) // { // // typedef TImage ImageType; // typedef typename TImage::PixelType PixelType; // enum { ImageDimension = ImageType::ImageDimension }; // enum { Dimension = ImageType::ImageDimension }; // // // // const unsigned int NUMBANDS=1; // typedef itk::Image,ImageDimension> VecImageType; // typedef typename VecImageType::PixelType VecPixelType; // // /** copy the input image into this vector image. stupid. */ // // typename VecImageType::Pointer vecImage = VecImageType::New(); // vecImage->SetSpacing(image->GetSpacing()); // vecImage->SetOrigin(image->GetOrigin()); // vecImage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); // vecImage->SetBufferedRegion( image->GetLargestPossibleRegion() ); // vecImage->Allocate(); // VecPixelType vvv; // vvv.Fill(0); // vecImage->FillBuffer(vvv); // // // setup the iterators // // typedef VecImageType::PixelType::VectorType VecPixelType; // // enum { VecImageDimension = VecImageType::ImageDimension }; // typedef itk::ImageRegionIterator< VecImageType > VecIterator; // // VecIterator outIt( vecImage, vecImage->GetBufferedRegion() ); // for (outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt) // { // vvv[0]=image->GetPixel(outIt.GetIndex()); // outIt.Set(vvv); // } // // // namespace stat = itk::Statistics; // // typedef itk::Image ClassImageType; // // // //---------------------------------------------------------------------- // //Set membership function (Using the statistics objects) // //---------------------------------------------------------------------- // // typedef itk::Statistics::DistanceToCentroidMembershipFunction< VecPixelType > // MembershipFunctionType ; // // typedef typename MembershipFunctionType::Pointer MembershipFunctionPointer ; // // typedef std::vector< MembershipFunctionPointer > // MembershipFunctionPointerVector; // // //---------------------------------------------------------------------- // //Set the image model estimator // //---------------------------------------------------------------------- // typedef itk::ImageKmeansModelEstimator< VecImageType, // MembershipFunctionType> ImageKmeansModelEstimatorType; // // typename ImageKmeansModelEstimatorType::Pointer // applyKmeansModelEstimator = ImageKmeansModelEstimatorType::New(); // // //---------------------------------------------------------------------- // //Set the parameters of the clusterer // //---------------------------------------------------------------------- // // std::cout << "Starting to build the K-means model ....." << std::endl; // // applyKmeansModelEstimator->SetInputImage( vecImage ); // applyKmeansModelEstimator->SetNumberOfModels(nclasses); // applyKmeansModelEstimator->SetThreshold(0.0001); // applyKmeansModelEstimator->Update(); // // MembershipFunctionPointerVector membershipFunctions = // applyKmeansModelEstimator->GetMembershipFunctions(); // // typedef std::vector TempVectorType; // typedef TempVectorType::iterator TempVectorIterator; // TempVectorIterator start, end; // // std::vector kmeansResultForClass(membershipFunctions.size()); // // // std::cout << "Result of K-Means clustering" << std::endl; // // double meanDistance=0; // for(unsigned int classIndex=0; classIndex < membershipFunctions.size(); // classIndex++ ) // { // kmeansResultForClass[classIndex] = // (double) (membershipFunctions[classIndex]->GetCentroid())[0]; // meanDistance+=kmeansResultForClass[classIndex];//membershipFunctions[i]->GetMean()[0]; // } // meanDistance/=(float)nclasses; // std::cout << " mean dist " << meanDistance << std::endl; // // // start = kmeansResultForClass.begin(); // end = kmeansResultForClass.end(); // // std::sort( start, end ); // // vnl_vector temp = membershipFunctions[0]->GetCentroid(); // for(unsigned int classIndex=0; classIndex < membershipFunctions.size(); // classIndex++ ) // { // temp[0] = (double) kmeansResultForClass[classIndex]; // membershipFunctions[classIndex]->SetCentroid(temp); // } // // for(unsigned int classIndex=0; classIndex < membershipFunctions.size(); // classIndex++ ) // { // std::cout << (membershipFunctions[classIndex]->GetCentroid())[0] << std::endl; // } // // //---------------------------------------------------------------------- // //Set the decision rule // //---------------------------------------------------------------------- // typedef itk::DecisionRuleBase::Pointer DecisionRuleBasePointer; // // typedef itk::MinimumDecisionRule DecisionRuleType; // DecisionRuleType::Pointer // classifierDecisionRule = DecisionRuleType::New(); // // //------------------------------------------------------ // //Instantiate the classifier model (as the input image is in right format) // //------------------------------------------------------ // // //Assign a class label image type // // typedef itk::Image ClassImageType; // // typedef itk::ImageClassifierBase< VecImageType,ClassImageType > // SupervisedClassifierType; // // typename SupervisedClassifierType::Pointer // classifierPointer = SupervisedClassifierType::New(); // // // //------------------------------------------------------ // // Set the Classifier parameters // //------------------------------------------------------ // classifierPointer->SetNumberOfClasses( nclasses ); // classifierPointer->SetInputImage( vecImage ); // // // Set the decison rule // classifierPointer-> // SetDecisionRule( (DecisionRuleBasePointer) classifierDecisionRule ); // // MembershipFunctionPointer membershipFunction; // //------------------------------------------------------ // //Set the classifier membership functions // //------------------------------------------------------ // for( unsigned int i=0; iAddMembershipFunction( membershipFunctions[i] ); // } // // //Do the classification // //Run the kmeans classifier algorithm // classifierPointer->Update(); // // //Get the classified image // typedef typename ClassImageType::Pointer ClassifiedImagePointer; // ClassifiedImagePointer outClassImage = // classifierPointer->GetClassifiedImage(); // // //------------------------------------------------------ // //Mask the output of the classifier // //------------------------------------------------------ // // // Declare the type for the MaskInput filter // // typedef itk::MaskImageFilter< ClassImageType, // ClassImageType, // ClassImageType > MaskFilterType; // // typedef typename ClassImageType::Pointer MaskedOutputImagePointer; // typedef typename MaskFilterType::Pointer MaskFilterTypePointer; // // // Create an ADD Filter // MaskFilterTypePointer maskfilter = MaskFilterType::New(); // // // Connect the input images // maskfilter->SetInput1( outClassImage ); // maskfilter->SetInput2( labelimage ); // // // Execute the filter // maskfilter->Update(); // // // Get the Smart Pointer to the Filter Output // MaskedOutputImagePointer maskedOutputImage = maskfilter->GetOutput(); // // // this->SetClassifiedImage( maskedOutputImage ); // // //------------------------------------------------------ // //Set the MRF labeller and populate the parameters // //------------------------------------------------------ // //Set the MRF labeller // typedef itk::MRFImageFilter // MRFFilterType; // // typename MRFFilterType::Pointer applyMRFFilter = MRFFilterType::New(); // // // Set the MRF labeller parameters // applyMRFFilter->SetNumberOfClasses(nclasses); // unsigned int m_MaximumNumberOfIterations=maxit; // applyMRFFilter->SetMaximumNumberOfIterations(m_MaximumNumberOfIterations); // float m_ErrorTolerance=1.e-5; // applyMRFFilter->SetErrorTolerance(m_ErrorTolerance); // float m_SmoothingFactor=smf; // applyMRFFilter->SetSmoothingFactor( m_SmoothingFactor ); // // //For setting up a square/cubic or hypercubic neighborhood // applyMRFFilter->SetNeighborhoodRadius( 1 ); // std::vector weights = // applyMRFFilter->GetMRFNeighborhoodWeight(); // std::vector testNewNeighborhoodWeight( weights.size(), 1); // double totalWeight = 0; // for(std::vector< double >::const_iterator wcIt = weights.begin(); // wcIt != weights.end(); ++wcIt ) // { // totalWeight += *wcIt; // } // unsigned int jj = 0; // for(std::vector< double >::iterator wIt = weights.begin(); // wIt != weights.end(); wIt++ ) // { // testNewNeighborhoodWeight[jj] = static_cast< double > ( (*wIt) * meanDistance / (2 * totalWeight)); // //std::cout << " ow " << weights[jj] << " nw " << testNewNeighborhoodWeight[jj] << std::endl; // jj++; // } // // applyMRFFilter->SetMRFNeighborhoodWeight( testNewNeighborhoodWeight ); // // applyMRFFilter->SetInput(vecImage); // applyMRFFilter->SetClassifier( classifierPointer ); // // //Kick off the MRF labeller function // applyMRFFilter->Update(); // // applyMRFFilter->Print(std::cout); // outClassImage = applyMRFFilter->GetOutput(); // // //------------------------------------------------------ // //Mask the output of the classifier // //------------------------------------------------------ // // // Declare the type for the MaskInput filter // // // Create an ADD Filter // MaskFilterTypePointer maskfilter2 = MaskFilterType::New(); // // // Connect the input images // maskfilter2->SetInput1( outClassImage ); // maskfilter2->SetInput2( labelimage ); // // // Execute the filter // maskfilter2->Update(); // // // Get the Smart Pointer to the Filter Output // maskedOutputImage = maskfilter2->GetOutput(); // // // this->SetClassifiedImage( maskedOutputImage ); // // return outClassImage;//maskedOutputImage; // // } template int SmoothImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sigma = 1.0; if (argc > argct) sigma=atof(argv[argct]); typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer varimage = NULL; ReadImage(image1, fn1.c_str()); typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sigma*sigma); bool usespacing=true; if (!usespacing) filter->SetUseImageSpacingOff(); else filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image1); filter->Update(); varimage=filter->GetOutput(); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( varimage ); writer->Write(); return 0; } template int MorphImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sigma = 1.0; if (argc > argct) sigma=atof(argv[argct]); unsigned int morphopt=1; if ( strcmp(operation.c_str(),"ME") == 0) morphopt=0; else if ( strcmp(operation.c_str(),"MO") == 0) morphopt=2; else if ( strcmp(operation.c_str(),"MC") == 0) morphopt=3; else if ( strcmp(operation.c_str(),"GE") == 0) morphopt=4; else if ( strcmp(operation.c_str(),"GD") == 0) morphopt=5; else if ( strcmp(operation.c_str(),"GO") == 0) morphopt=6; else if ( strcmp(operation.c_str(),"GC") == 0) morphopt=7; typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); // SRD set dilatevalue float dilateval = 1.0; // if (argc > argct + 1) dilateval=atof(argv[argct+1]); image1=Morphological(image1, sigma, morphopt , dilateval); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( image1 ); writer->Write(); return 0; } template int FastMarchingSegmentation( unsigned int argc, char *argv[] ) { typedef float InternalPixelType; typedef itk::Image InternalImageType; typedef itk::Image ImageType; typedef unsigned char OutputPixelType; typedef itk::Image OutputImageType; unsigned int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; float stoppingValue=100.0; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } else { std::cout << " not enough parameters -- need label image " << std::endl; return 0; } if ( argc > argct) { stoppingValue=atof(argv[argct]); argct++; } typename ImageType::Pointer speedimage = NULL; ReadImage(speedimage, fn1.c_str()); typename ImageType::Pointer labimage = NULL; ReadImage(labimage, fn2.c_str()); typename ImageType::Pointer fastimage = NULL; ReadImage(fastimage, fn1.c_str()); typename ImageType::Pointer outlabimage = NULL; ReadImage(outlabimage, fn2.c_str()); /* typedef itk::WellComposedImageFilter WCFilterType; typename WCFilterType::Pointer filter3D = WCFilterType::New(); filter3D->SetInput( labimage ); filter3D->SetTotalNumberOfLabels( 1 ); filter3D->Update(); labimage=filter3D->GetOutput(); WriteImage(labimage,"temp.nii.gz"); */ typedef itk::FastMarchingImageFilter FastMarchingFilterType; typename FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New(); fastMarching->SetInput( speedimage ); typedef typename FastMarchingFilterType::NodeContainer NodeContainer; typedef typename FastMarchingFilterType::NodeType NodeType; // typedef typename FastMarchingFilterType::LabelImageType LabelImageType; typedef ImageType LabelImageType; typedef itk::LabelContourImageFilter ContourFilterType; typename ContourFilterType::Pointer contour = ContourFilterType::New(); contour->SetInput( labimage ); contour->FullyConnectedOff(); contour->SetBackgroundValue( itk::NumericTraits::Zero ); contour->Update(); // WriteImage(contour->GetOutput(),"temp2.nii.gz"); typename NodeContainer::Pointer alivePoints = NodeContainer::New(); alivePoints->Initialize(); unsigned long aliveCount = 0; typename NodeContainer::Pointer trialPoints = NodeContainer::New(); trialPoints->Initialize(); unsigned long trialCount = 0; itk::ImageRegionIteratorWithIndex ItL( labimage , labimage->GetLargestPossibleRegion() ); itk::ImageRegionIteratorWithIndex ItC( contour->GetOutput(), contour->GetOutput()->GetLargestPossibleRegion() ); for( ItL.GoToBegin(), ItC.GoToBegin(); !ItL.IsAtEnd(); ++ItL, ++ItC ) { if( ItC.Get() != itk::NumericTraits::Zero ) { typename LabelImageType::IndexType position = ItC.GetIndex(); NodeType node; const double value = 0.0; node.SetValue( value ); node.SetIndex( position ); trialPoints->InsertElement( trialCount++, node ); } if( ItL.Get() != itk::NumericTraits::Zero ) { typename LabelImageType::IndexType position = ItL.GetIndex(); NodeType node; const double value = 0.0; node.SetValue( value ); node.SetIndex( position ); alivePoints->InsertElement( aliveCount++, node ); } } fastMarching->SetTrialPoints( trialPoints ); fastMarching->SetAlivePoints( alivePoints ); fastMarching->SetStoppingValue( stoppingValue ); fastMarching->SetTopologyCheck( FastMarchingFilterType::None ); if( argc > 7 && atoi( argv[7] ) == 1 ) { std::cout << "Strict." << std::endl; fastMarching->SetTopologyCheck( FastMarchingFilterType::Strict ); } if( argc > 7 && atoi( argv[7] ) == 2 ) { std::cout << "No handles." << std::endl; fastMarching->SetTopologyCheck( FastMarchingFilterType::NoHandles ); } try { fastMarching->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception caught !" << std::endl; std::cerr << excep << std::endl; } typedef itk::BinaryThresholdImageFilter ThresholdingFilterType; typename ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New(); thresholder->SetLowerThreshold( 0.0 ); thresholder->SetUpperThreshold( stoppingValue ); thresholder->SetOutsideValue( 0 ); thresholder->SetInsideValue( 1 ); thresholder->SetInput( fastMarching->GetOutput() ); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( thresholder->GetOutput() ); writer->SetFileName( outname.c_str() ); writer->Update(); return 0; } template int PropagateLabelsThroughMask(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; float thresh=0.5; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; float stopval=100.0; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } else { std::cout << " not enough parameters -- need label image " << std::endl; return 0; } if ( argc > argct) { stopval=atof(argv[argct]); argct++; } typename ImageType::Pointer speedimage = NULL; ReadImage(speedimage, fn1.c_str()); typename ImageType::Pointer labimage = NULL; ReadImage(labimage, fn2.c_str()); typename ImageType::Pointer fastimage = NULL; ReadImage(fastimage, fn1.c_str()); typename ImageType::Pointer outlabimage = NULL; ReadImage(outlabimage, fn2.c_str()); fastimage->FillBuffer(1.e9); // compute max label double maxlabel=0; Iterator vfIter2( labimage, labimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { bool isinside=true; double speedval=speedimage->GetPixel(vfIter2.GetIndex()); double labval=labimage->GetPixel(vfIter2.GetIndex()); if ( speedval < thresh ) isinside=false; if (isinside ) { if ( labval > maxlabel ) maxlabel=labval; } } for (unsigned int lab=1; lab<=(unsigned int)maxlabel; lab++) { typedef itk::FastMarchingImageFilter< ImageType, ImageType > FastMarchingFilterType; typename FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New(); fastMarching->SetInput( speedimage ); fastMarching->SetTopologyCheck( FastMarchingFilterType::None ); typedef typename FastMarchingFilterType::NodeContainer NodeContainer; typedef typename FastMarchingFilterType::NodeType NodeType; typename NodeContainer::Pointer seeds = NodeContainer::New(); seeds->Initialize(); unsigned long ct=0; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { bool isinside=true; double speedval=speedimage->GetPixel(vfIter2.GetIndex()); double labval=labimage->GetPixel(vfIter2.GetIndex()); if ( speedval < thresh ) isinside=false; if (isinside && (unsigned int) labval == lab ) { NodeType node; const double seedValue = 0.0; node.SetValue( seedValue ); node.SetIndex( vfIter2.GetIndex() ); seeds->InsertElement( ct, node ); ct++; } } fastMarching->SetTrialPoints( seeds ); fastMarching->SetStoppingValue( stopval ); fastMarching->Update(); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { bool isinside=true; double speedval=speedimage->GetPixel(vfIter2.GetIndex()); double labval=labimage->GetPixel(vfIter2.GetIndex()); if ( speedval < thresh ) isinside=false; if (isinside && labval == 0 ) { double fmarrivaltime=fastMarching->GetOutput()->GetPixel( vfIter2.GetIndex() ); double mmm= fastimage->GetPixel(vfIter2.GetIndex()); if ( fmarrivaltime < mmm ) { fastimage->SetPixel(vfIter2.GetIndex() , fmarrivaltime ); outlabimage->SetPixel(vfIter2.GetIndex() , lab ); } } else if (!isinside) outlabimage->SetPixel(vfIter2.GetIndex() , 0 ); } } std::string::size_type idx; idx = outname.find_first_of('.'); std::string tempname = outname.substr(0,idx); std::string extension = outname.substr(idx,outname.length()); std::string kname=tempname+std::string("_speed")+extension; WriteImage(fastimage,kname.c_str()); WriteImage(outlabimage,outname.c_str()); return 0; } template int DistanceMap(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sigma = 1.0; if (argc > argct) sigma=atof(argv[argct]); typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typedef itk::DanielssonDistanceMapImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->InputIsBinaryOff(); filter->SetUseImageSpacing(true); filter->SetInput(image1); filter->Update(); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( filter->GetOutput() ); writer->Write(); return 0; } template int FillHoles(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image LabelImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::CastImageFilter CastFilterType; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float holeparam = 2.0; if (argc > argct) holeparam=atof(argv[argct]); typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typename ImageType::Pointer imageout = NULL; ReadImage(imageout, fn1.c_str()); image1 = BinaryThreshold(0.5,1.e9,1,image1); typedef itk::DanielssonDistanceMapImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->InputIsBinaryOff(); filter->SetUseImageSpacing(false); filter->SetInput(image1); filter->Update(); // algorithm : // 1. get distance map of object // 2. threshold // 3. label connected components // 4. label surface // 5. if everywhere on surface is next to object then it's a hole // 6. make sure it's not the background typedef itk::Image labelimagetype; typename ImageType::Pointer dist = filter->GetOutput(); typename ImageType::Pointer regions = BinaryThreshold(0.001,1.e9,1,dist); typedef itk::ConnectedComponentImageFilter< labelimagetype, labelimagetype > ccFilterType; typedef itk::RelabelComponentImageFilter< labelimagetype, ImageType > RelabelType; typename RelabelType::Pointer relabel = RelabelType::New(); typename ccFilterType::Pointer ccfilter = ccFilterType::New(); typename CastFilterType::Pointer castRegions = CastFilterType::New(); castRegions->SetInput( regions ); ccfilter->SetInput(castRegions->GetOutput()); ccfilter->SetFullyConnected( 0 ); ccfilter->Update(); relabel->SetInput( ccfilter->GetOutput() ); relabel->SetMinimumObjectSize( 0 ); // relabel->SetUseHistograms(true); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } // WriteImage(relabel->GetOutput(),"test.nii"); if (holeparam == 2) { std::cout <<" Filling all holes "<< std::endl; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 1 ) imageout->SetPixel(vfIter.GetIndex(),1); } WriteImage(imageout,outname.c_str()); return 0; } typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetOutput(),relabel->GetOutput()->GetLargestPossibleRegion()); float maximum=relabel->GetNumberOfObjects(); //now we have the exact number of objects labeled independently for (unsigned int lab=2; lab<=maximum; lab++) { float erat=2; if (holeparam <= 1 ) { GHood.GoToBegin(); unsigned long objectedge=0; unsigned long backgroundedge=0; unsigned long totaledge=0; unsigned long volume=0; while (!GHood.IsAtEnd()) { typename ImageType::PixelType p = GHood.GetCenterPixel(); typename ImageType::IndexType ind = GHood.GetIndex(); typename ImageType::IndexType ind2; if ( p == lab ) { volume++; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0.0; for (unsigned int j=0; jGetPixel(ind2); if (val2 >= 0.5 && GHood.GetPixel(i) != lab ) { objectedge++; totaledge++; } else if (val2 < 0.5 && GHood.GetPixel(i) != lab ) { backgroundedge++; totaledge++; } } } ++GHood; } float vrat=(float)totaledge/(float)volume; erat=(float)objectedge/(float)totaledge; std::cout <<" Lab " << lab << " volume " << volume << " v-rat " << vrat << " edge " << erat << std::endl; } if (erat > holeparam)// fill the hole { std::cout <<" Filling " << lab << " of " << maximum << std::endl; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() == lab ) imageout->SetPixel(vfIter.GetIndex(),1); } } } WriteImage(imageout,outname.c_str()); return 0; } template int NormalizeImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float option = 0; if (argc > argct) option=atof(argv[argct]); typename ImageType::Pointer image = NULL; ReadImage(image, fn1.c_str()); float max=0; float min=1.e9; float mean = 0.0; unsigned long ct = 0; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator iter( image, image->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { float pix=iter.Get(); // if (option == 0) if (pix < 0) pix=0; mean+=pix; ct++; if (pix > max ) max=pix; if (pix < min) min=pix; } mean/=(float)ct; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { float pix=iter.Get(); if (option == 0) { pix= (pix - min)/(max-min); iter.Set(pix); } else iter.Set(pix/mean); } typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( image ); writer->Write(); return 0; } template int PrintHeader(int argc, char *argv[]) { typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(fn1.c_str()); reader->Update(); std::cout << " Spacing " << reader->GetOutput()->GetSpacing() << std::endl; std::cout << " Origin " << reader->GetOutput()->GetOrigin() << std::endl; std::cout << " Direction " << std::endl << reader->GetOutput()->GetDirection() << std::endl; std::cout << " Size " << std::endl << reader->GetOutput()->GetLargestPossibleRegion().GetSize() << std::endl; return 1; } template int GradientImage( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sig = 1; if (argc > argct) sig=atof(argv[argct]); argct++; if (sig <= 0) sig=0.5; bool normalize=false; if (argc > argct) normalize=atoi(argv[argct]); typename ImageType::Pointer image = NULL; typename ImageType::Pointer image2 = NULL; ReadImage(image, fn1.c_str()); typedef itk::GradientMagnitudeRecursiveGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetSigma(sig); filter->SetInput(image); filter->Update(); image2=filter->GetOutput(); if ( !normalize ) { WriteImage( image2,outname.c_str()); return 0; } typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 1 ); rescaler->SetInput( image2 ); WriteImage( rescaler->GetOutput() ,outname.c_str()); return 0; } template int LaplacianImage( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sig = 1; if (argc > argct) sig=atof(argv[argct]); if (sig <= 0) sig=0.5; bool normalize=false; if (argc > argct) normalize=atoi(argv[argct]); typename ImageType::Pointer image = NULL; typename ImageType::Pointer image2 = NULL; ReadImage(image, fn1.c_str()); typedef itk::LaplacianRecursiveGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetSigma(sig); filter->SetInput(image); filter->Update(); image2=filter->GetOutput(); if ( !normalize ) { WriteImage( image2,outname.c_str()); return 0; } typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 1 ); rescaler->SetInput( image2 ); WriteImage( rescaler->GetOutput() ,outname.c_str()); return 0; } template void RemoveLabelInterfaces(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; typename ImageType::Pointer input = NULL; ReadImage(input , fn1.c_str()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); // std::cout << " foreg " << (int) foreground; while (!GHood.IsAtEnd()) { typename ImageType::PixelType p = GHood.GetCenterPixel(); typename ImageType::IndexType ind = GHood.GetIndex(); typename ImageType::IndexType ind2; if ( p > 0 ) { bool atedge=false; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); if (GHood.GetPixel(i) > 0 && GHood.GetPixel(i) != p ) { atedge=true; } } if (atedge) input->SetPixel(ind,0); } ++GHood; } WriteImage(input,outname.c_str()); return; } template void EnumerateLabelInterfaces(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string outname2 = ""; if (argc > argct) outname2=std::string(argv[argct]); argct++; float nfrac = 0.1; if (argc > argct) nfrac=atof(argv[argct]); argct++; typename ImageType::Pointer input = NULL; ReadImage(input , fn1.c_str()); typename ImageType::Pointer output = NULL; ReadImage(output , fn1.c_str()); output->FillBuffer(0); typename ImageType::Pointer colored = NULL; ReadImage(colored , fn1.c_str()); colored->FillBuffer(0); unsigned int max=0; Iterator o_iter( input,input->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { unsigned int label = (unsigned int) o_iter.Get(); if ( label > max ) max=label; ++o_iter; } std::cout << " Max Label " << max << std::endl; typedef itk::Image myInterfaceImageType; typename myInterfaceImageType::SizeType size; size[0]=max+1; size[1]=max+1; typename myInterfaceImageType::RegionType region; typename myInterfaceImageType::SpacingType spacing; spacing.Fill(1); typename myInterfaceImageType::PointType origin; origin.Fill(max/2); region.SetSize(size); typename myInterfaceImageType::Pointer faceimage = myInterfaceImageType::New(); faceimage->SetSpacing(spacing); faceimage->SetOrigin(origin); faceimage->SetRegions(region ); faceimage->Allocate(); faceimage->FillBuffer( 0 ); typename myInterfaceImageType::Pointer colorimage = myInterfaceImageType::New(); colorimage->SetSpacing(spacing); colorimage->SetOrigin(origin); colorimage->SetRegions(region ); colorimage->Allocate(); colorimage->FillBuffer( 0 ); typedef itk::ImageRegionIteratorWithIndex FIterator; // we can use this to compute a 4-coloring of the brain typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); // std::cout << " foreg " << (int) foreground; while (!GHood.IsAtEnd()) { typename ImageType::PixelType p = GHood.GetCenterPixel(); typename ImageType::IndexType ind = GHood.GetIndex(); typename ImageType::IndexType ind2; if ( p > 0 ) { bool atedge=false; unsigned long linearinda=0,linearindb=0,linearind=0; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); if (GHood.GetPixel(i) > 0 && GHood.GetPixel(i) != p ) { atedge=true; typename myInterfaceImageType::IndexType inda,indb; inda[0]=(long int)p; inda[1]=(long int)GHood.GetPixel(i); indb[1]=(long int)p; indb[0]=(long int)GHood.GetPixel(i); faceimage->SetPixel(inda,faceimage->GetPixel(inda)+1); faceimage->SetPixel(indb,faceimage->GetPixel(indb)+1); linearinda=inda[1]*size[0]+inda[0]; linearindb=indb[1]*size[0]+indb[0]; if (linearinda < linearindb) linearind=linearinda; else linearind=linearindb; } } if (atedge) output->SetPixel(ind,linearind); } ++GHood; } // first normalize the interfaces typename myInterfaceImageType::IndexType find; typename myInterfaceImageType::IndexType find2; find2.Fill(0); for (unsigned int j=0; j<=max; j++) { find[0]=j; float total=0; for (unsigned int i=0; i<=max; i++) { find[1]=i; total+= faceimage->GetPixel(find) ; // if ( faceimage->GetPixel(find) > 50 ) //std::cout << i <<" :: " << faceimage->GetPixel(find) << std::endl; } std::cout << " total interfaces for label : " << j << " are " << total << std::endl; for (unsigned int i=0; i<=max; i++) { find[1]=i; if (total > 0) faceimage->SetPixel(find,faceimage->GetPixel(find)/total); if ( faceimage->GetPixel(find) > 0.01 ) std::cout << i <<" :: " << faceimage->GetPixel(find) << std::endl; } } // colors 1 , 2 , 3 , 4 // set all to color 1. typedef std::vector ColorSetType; colorimage->FillBuffer(0); // for (unsigned int j=1; j<=max; j++) for (unsigned int j=max; j>=1; j--) { ColorSetType myColorSet1; ColorSetType myColorSet2; ColorSetType myColorSet3; ColorSetType myColorSet4; ColorSetType myColorSet5; find[0]=j; // list all indices that have an interface with j // for (unsigned int i=1; i<=max; i++) for (unsigned int i=max; i>=1; i--) { if ( i != j) { find[1]=i; find2[0]=i; unsigned int color=(unsigned int) colorimage->GetPixel(find2); if ( faceimage->GetPixel(find) > nfrac ) // then color { if ( color == 1) myColorSet1.push_back( (unsigned int) i ); if ( color == 2) myColorSet2.push_back( (unsigned int) i ); if ( color == 3) myColorSet3.push_back( (unsigned int) i ); if ( color == 4) myColorSet4.push_back( (unsigned int) i ); if ( color == 5) myColorSet5.push_back( (unsigned int) i ); // now you know all of j's neighbors and their colors } } } //we have to recolor j so that his color is different //than any in the label set unsigned int okcolor=6; find[0]=j; find[1]=0; if( myColorSet1.empty() ) okcolor=1; else if( myColorSet2.empty() ) okcolor=2; else if( myColorSet3.empty() ) okcolor=3; else if( myColorSet4.empty() ) okcolor=4; else if( myColorSet5.empty() ) okcolor=5; colorimage->SetPixel(find,okcolor); std::cout <<" Label " << j << " color " << okcolor << std::endl; } o_iter.GoToBegin() ; colored->FillBuffer(0); while ( !o_iter.IsAtEnd() ) { unsigned int label = (unsigned int) o_iter.Get(); if (label > 0) { find[0]=label; find[1]=0; unsigned int color=(unsigned int)colorimage->GetPixel(find); colored->SetPixel(o_iter.GetIndex(),color); } ++o_iter; } WriteImage(output,outname.c_str()); WriteImage(faceimage,(std::string("face")+outname).c_str()); if (outname2.length() > 3) WriteImage(colored,outname2.c_str()); return; } template int CountVoxelDifference( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } std::string maskfn = ""; if ( argc > argct) { maskfn=std::string(argv[argct]); argct++; } typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::Pointer mask = NULL; ReadImage(image1, fn1.c_str()); ReadImage(image2, fn2.c_str()); ReadImage(mask, maskfn.c_str()); unsigned long maskct=0; float err=0,poserr=0,negerr=0; Iterator It ( mask,mask->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( It.Get() > 0 ) { float p1=image1->GetPixel(It.GetIndex()); float p2=image2->GetPixel(It.GetIndex()); float locerr=p1-p2; err+=fabs(locerr); if (locerr > 0) poserr+=locerr; if (locerr < 0) negerr+=locerr; maskct++; } } if (maskct ==0) maskct=1; std::ofstream logfile; logfile.open(outname.c_str() ); if (logfile.good() ) { logfile << " Err " << " : " << err << " %ER " << " : " << err/(maskct)*100. << " NER " << " : " << negerr/maskct*100.0 < int DiceAndMinDistSum( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } std::string outdistfn = ""; if ( argc > argct) { outdistfn=std::string(argv[argct]); argct++; } std::string diceimagename=ANTSGetFilePrefix(outname.c_str())+std::string("dice.nii.gz"); std::string mdsimagename=ANTSGetFilePrefix(outname.c_str())+std::string("mds.nii.gz"); typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::Pointer outdist = NULL; ReadImage(image1, fn1.c_str()); if ( fn2.length() > 3) ReadImage(image2, fn2.c_str()); if ( outdistfn.length() > 3) { ReadImage(outdist, fn1.c_str()); outdist->FillBuffer(0); } // 1: for each label, and each image, compute the distance map // 2: sum min-dist(i) over every point in each image // 3: take average over all points typedef float PixelType; typedef std::vector LabelSetType; LabelSetType myLabelSet1; { /** count the labels in the image */ Iterator It ( image1,image1->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( fabs(label) > 0 ) { if( find( myLabelSet1.begin(), myLabelSet1.end(), label ) == myLabelSet1.end() ) { myLabelSet1.push_back( label ); } } }} LabelSetType myLabelSet2; unsigned int labct=0; { Iterator It ( image2,image2->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( fabs(label) > 0 ) { if( find( myLabelSet2.begin(), myLabelSet2.end(), label ) == myLabelSet2.end() && find( myLabelSet1.begin(), myLabelSet1.end(), label ) != myLabelSet1.end() ) { myLabelSet2.push_back( label ); labct++; } } }} vnl_vector distances(labct,0.0); vnl_vector dicevals(labct,0.0); vnl_vector rovals(labct,0.0); vnl_vector tpvals(labct,0.0); vnl_vector tpvals2(labct,0.0); /** now we have the common labels */ std::ofstream logfile; logfile.open(outname.c_str() ); labct=0; typename LabelSetType::const_iterator it; for( it = myLabelSet2.begin(); it != myLabelSet2.end(); ++it ) { typename ImageType::Pointer mask1 = BinaryThreshold(*it,*it,1,image1); typename ImageType::Pointer surf = NULL; typename ImageType::Pointer d1 = NULL; typename ImageType::Pointer d2 = NULL; float count1=0;// count vox in label 1 float count2=0;// count vox in label 2 float counti=0;// count vox intersection in label 1 and label 2 float countu=0;// count vox union label 1 and label 2 float surfdist=0,surfct=0; // float truepos=0; if (outdist) { surf=LabelSurface(mask1,mask1); // WriteImage(surf,outdistfn.c_str()); //exit(0); typedef itk::DanielssonDistanceMapImageFilter FilterType; typename FilterType::Pointer dfilter1 = FilterType::New(); dfilter1->InputIsBinaryOn(); dfilter1->SetUseImageSpacing(true); dfilter1->SetInput(mask1); typename ImageType::Pointer mask2 = BinaryThreshold(*it,*it,1,image2); typename FilterType::Pointer dfilter2 = FilterType::New(); dfilter2->InputIsBinaryOn(); dfilter2->SetUseImageSpacing(true); dfilter2->SetInput(mask2); dfilter1->Update(); d1=dfilter1->GetOutput(); dfilter2->Update(); d2=dfilter2->GetOutput(); } float dist1=0; float dist2=0; Iterator It2 ( image2,image2->GetLargestPossibleRegion() ); for( It2.GoToBegin(); !It2.IsAtEnd(); ++It2 ) { if (It2.Get() == *it || image1->GetPixel(It2.GetIndex()) == *it) countu++; if (It2.Get() == *it && image1->GetPixel(It2.GetIndex()) == *it) counti++; if (It2.Get() == *it) { count2++; if (d1) dist2+=d1->GetPixel(It2.GetIndex()); } if ( image1->GetPixel(It2.GetIndex()) == *it) { count1++; if (d2) dist1+=d2->GetPixel(It2.GetIndex()); } if (outdist) if ( surf->GetPixel(It2.GetIndex()) > 0 ) { float sdist=d2->GetPixel(It2.GetIndex()); outdist->SetPixel(It2.GetIndex(),sdist); surfdist+=sdist; surfct+=1; } } // std::cout << " sdist " << surfdist << " sct " << surfct << std::endl if (outdist) WriteImage(outdist,outdistfn.c_str()); if (count2+count1 > 0) { distances[labct]+=(dist2+dist1)/(count2+count1); dicevals[labct]=2.0*counti/(count2+count1); rovals[labct]=counti/(countu); tpvals[labct]=counti/count1; tpvals2[labct]=counti/count2; } labct++; } labct=0; float sum=0,sumdice=0,sumro=0; // std::sort(myLabelSet2.begin(),myLabelSet2.end()); unsigned long labelcount=0; for( it = myLabelSet2.begin(); it != myLabelSet2.end(); ++it ) labelcount++; float temp=sqrt((float)labelcount); unsigned int squareimagesize=(unsigned int)(temp+1); typedef itk::Image TwoDImageType; typename TwoDImageType::RegionType newregion; typename TwoDImageType::SizeType size; size[0]=size[1]=squareimagesize; newregion.SetSize(size); typename TwoDImageType::Pointer squareimage = TwoDImageType::New(); typename TwoDImageType::SpacingType spacingb; spacingb.Fill(1); typename TwoDImageType::PointType origin; origin.Fill(0); squareimage->SetSpacing(spacingb); squareimage->SetOrigin(origin); squareimage->SetRegions(newregion ); squareimage->Allocate(); squareimage->FillBuffer( 0 ); typename TwoDImageType::Pointer squareimage2 = TwoDImageType::New(); squareimage2->SetSpacing(spacingb); squareimage2->SetOrigin(origin); squareimage2->SetRegions(newregion ); squareimage2->Allocate(); squareimage2->FillBuffer( 0 ); labelcount=0; for( it = myLabelSet2.begin(); it != myLabelSet2.end(); ++it ) { if (logfile.good() ) { if (outdist) logfile <<" Label " << *it << " MD " << distances[labct] << " DICE " << dicevals[labct] << std::endl; else logfile <<" Label " << *it << " DICE " << dicevals[labct] << " RO " << rovals[labct] << " TP1 " << tpvals[labct] << " TP2 " << tpvals2[labct] << std::endl; } sum+=distances[labct]; sumdice+=dicevals[labct]; sumro+=rovals[labct]; // square image squareimage->GetBufferPointer()[labct]=distances[labct]; squareimage2->GetBufferPointer()[labct]= dicevals[labct]; labct++; } if (labct ==0) labct=1; if (logfile.good() ) { if (outdist) logfile <<" AvgMinDist " << " : " << sum/(float)labct << " AvgDice " << " : " << sumdice/(float)labct << " AvgRO " << " : " << sumro/(float)labct << std::endl; else logfile << " AvgDice " << " : " << sumdice/(float)labct << std::endl; } WriteImage(squareimage,mdsimagename.c_str()); WriteImage(squareimage2,diceimagename.c_str()); return 0; } template int Lipschitz( int argc, char *argv[] ) { std::cout << " Compute Lipschitz continuity of the mapping " << std::endl; typedef float RealType; typedef itk::Image RealImageType; typedef itk::Vector VectorType; typedef itk::Image VectorImageType; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string vecname = std::string(argv[argct]); argct++; /** * Read in vector field */ typedef itk::VectorImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( vecname.c_str() ); reader->SetUseAvantsNamingConvention( true ); reader->Update(); typename VectorImageType::Pointer vecimage=reader->GetOutput(); typename RealImageType::Pointer lipcon = RealImageType::New(); lipcon->SetOrigin( vecimage->GetOrigin() ); lipcon->SetSpacing( vecimage->GetSpacing() ); lipcon->SetRegions( vecimage->GetLargestPossibleRegion() ); lipcon->SetDirection( vecimage->GetDirection()); lipcon->Allocate(); lipcon->FillBuffer(0); itk::TimeProbe timer; timer.Start(); /** global Lipschitz points */ typename VectorImageType::PointType gx; gx.Fill(0); typename VectorImageType::PointType gxt; gxt.Fill(0); typename VectorImageType::PointType gy; gy.Fill(0); typename VectorImageType::PointType gyt; gyt.Fill(0); typename VectorImageType::PointType lx; lx.Fill(0); typename VectorImageType::PointType lxt; lxt.Fill(0); typename VectorImageType::PointType ly; ly.Fill(0); typename VectorImageType::PointType lyt; lyt.Fill(0); float globalmaxval=0; unsigned long ct1=0; // unsigned long numpx=vecimage->GetBufferedRegion().GetNumberOfPixels(); Iterator It1 ( vecimage,vecimage->GetLargestPossibleRegion() ); for( It1.GoToBegin(); !It1.IsAtEnd(); ++It1 ) { ct1++; typename VectorImageType::PointType x; typename VectorImageType::PointType xt; vecimage->TransformIndexToPhysicalPoint( It1.GetIndex(), x); typename VectorImageType::PixelType vecx=It1.Get(); for (unsigned int i=0; iGetLargestPossibleRegion() ); for( It2.GoToBegin(); !It2.IsAtEnd(); ++It2 ) { ct2++; if (ct2 != ct1) { typename VectorImageType::PointType y; typename VectorImageType::PointType yt; vecimage->TransformIndexToPhysicalPoint( It2.GetIndex(), y); typename VectorImageType::PixelType vecy=It2.Get(); float numer=0; float denom=0; for (unsigned int i=0; i localmaxval) { lx=x; ly=y; lxt=xt; lyt=yt; localmaxval=localval; } } } if (localmaxval > globalmaxval) { gx=lx; gy=ly; gxt=lxt; gyt=lyt; globalmaxval = localmaxval; } lipcon->SetPixel(It1.GetIndex(),localmaxval); // if (ct1 % 1000 == 0) std::cout << " Progress : " << (float ) ct1 / (float) numpx *100.0 << " val " << localmaxval << std::endl; } std::cout << " Lipschitz continuity related to: " << globalmaxval << std::endl; std::cout << " Tx : " << gxt << " Ty: " << gyt << std::endl; std::cout << " x : " << gx << " y: " << gy << std::endl; timer.Stop(); // std::cout << "Elapsed time: " << timer.GetMeanTime() << std::endl; typedef itk::ImageFileWriter RealImageWriterType; typename RealImageWriterType::Pointer realwriter = RealImageWriterType::New(); realwriter->SetFileName( outname.c_str() ); realwriter->SetInput( lipcon ); realwriter->Update(); return 0; } template int InvId( int argc, char *argv[] ) { std::cout << " Compute phi( phi^{-1}(x)) " << std::endl; typedef float RealType; typedef itk::Image RealImageType; typedef itk::Vector VectorType; typedef itk::Image VectorImageType; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string vecname1 = std::string(argv[argct]); argct++; std::string vecname2 = std::string(argv[argct]); argct++; /** * Read in vector field */ typedef itk::VectorImageFileReader ReaderType; typename ReaderType::Pointer reader1 = ReaderType::New(); reader1->SetFileName( vecname1.c_str() ); reader1->SetUseAvantsNamingConvention( true ); reader1->Update(); typename VectorImageType::Pointer vecimage1=reader1->GetOutput(); typename ReaderType::Pointer reader2 = ReaderType::New(); reader2->SetFileName( vecname2.c_str() ); reader2->SetUseAvantsNamingConvention( true ); reader2->Update(); typename VectorImageType::Pointer vecimage2=reader2->GetOutput(); typename RealImageType::Pointer invid = RealImageType::New(); invid->SetOrigin( vecimage1->GetOrigin() ); invid->SetSpacing( vecimage1->GetSpacing() ); invid->SetRegions( vecimage1->GetLargestPossibleRegion() ); invid->SetDirection( vecimage1->GetDirection()); invid->Allocate(); invid->FillBuffer(0); itk::TimeProbe timer; timer.Start(); typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); vinterp->SetInputImage(vecimage2); /** global Lipschitz points */ typename VectorImageType::PointType gx; gx.Fill(0); float globalmaxval=0; Iterator It1 ( vecimage1,vecimage1->GetLargestPossibleRegion() ); for( It1.GoToBegin(); !It1.IsAtEnd(); ++It1 ) { typename VectorImageType::PointType x; typename DefaultInterpolatorType::PointType xt,yt; vecimage1->TransformIndexToPhysicalPoint( It1.GetIndex(), x); typename VectorImageType::PixelType vecx=It1.Get(); for (unsigned int i=0; iIsInsideBuffer(xt)) disp = vinterp->Evaluate(xt); else disp.Fill(0); for (unsigned int jj=0; jj globalmaxval) { globalmaxval=error; gx=x; } invid->SetPixel(It1.GetIndex(),error); } std::cout << " Max error " << globalmaxval << " at " << gx << std::endl; timer.Stop(); // std::cout << "Elapsed time: " << timer.GetMeanTime() << std::endl; typedef itk::ImageFileWriter RealImageWriterType; typename RealImageWriterType::Pointer realwriter = RealImageWriterType::New(); realwriter->SetFileName( outname.c_str() ); realwriter->SetInput( invid ); realwriter->Update(); return 0; } template int LabelStats( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string imagename=ANTSGetFilePrefix(outname.c_str())+std::string(".nii.gz"); std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } typename ImageType::Pointer image = NULL; typename ImageType::Pointer valimage = NULL; ReadImage(image, fn1.c_str()); if ( fn2.length() > 3) ReadImage(valimage, fn2.c_str()); typedef float PixelType; typedef std::vector LabelSetType; LabelSetType myLabelSet; /** count the labels in the image */ Iterator It ( image,image->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( fabs(label) > 0 ) { if( find( myLabelSet.begin(), myLabelSet.end(), label ) == myLabelSet.end() ) { myLabelSet.push_back( label ); } } } // compute the voxel volume typename ImageType::SpacingType spacing=image->GetSpacing(); float volumeelement=1.0; for (unsigned int i=0; i TwoDImageType; typename TwoDImageType::RegionType newregion; typename TwoDImageType::SizeType size; size[0]=size[1]=squareimagesize; newregion.SetSize(size); typename TwoDImageType::Pointer squareimage = TwoDImageType::New(); typename TwoDImageType::SpacingType spacingb; spacingb.Fill(1); typename TwoDImageType::PointType origin; origin.Fill(0); squareimage->SetSpacing(spacingb); squareimage->SetOrigin(origin); squareimage->SetRegions(newregion ); squareimage->Allocate(); squareimage->FillBuffer( 0 ); labelcount=0; for( it = myLabelSet.begin(); it != myLabelSet.end(); ++it ) { float currentlabel= *it ; float totalvolume=0; float totalmass=0; float totalct=0; typename ImageType::PointType myCenterOfMass; myCenterOfMass.Fill(0); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( label == currentlabel ) { totalvolume+=volumeelement; totalct+=1; if ( valimage) totalmass+=valimage->GetPixel(It.GetIndex()); // compute center of mass typename ImageType::PointType point; image->TransformIndexToPhysicalPoint(It.GetIndex(), point); for (unsigned int i=0; i 500 && totalmass/totalct > 1/500 ) { { std::cout << " Volume Of Label " << *it << " is " << totalvolume << " Avg-Location " << myCenterOfMass <<" mass is " << totalmass << " average-val is " << totalmass/totalct << std::endl; // std::cout << *it << " " << totalvolume << " & " << totalmass/totalct << " \ " << std::endl; } // square image squareimage->GetBufferPointer()[labelcount]=totalmass/totalct; labelcount++; } logfile.close(); WriteImage(squareimage,imagename.c_str()); return 0; } //int is the key, string the return value std::map RoiList(std::string file) { unsigned int wordindex=1; std::string tempstring=""; std::map RoiList; char str[2000]; std::fstream file_op(file.c_str(),std::ios::in); while(file_op >> str) { tempstring=std::string(str); RoiList[wordindex]=tempstring; wordindex++; std::cout << tempstring << std::endl; } return RoiList; //returns the maximum index } // now words can be accessed like this WordList[n]; where 'n' is the index template int ROIStatistics( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; // first create a label image => ROI value map std::map cortroimap; cortroimap[1]=std::string("L. Occipital Lobe"); cortroimap[2]=std::string("R. Occipital Lobe"); cortroimap[3]=std::string("L. Cingulate Gyrus"); cortroimap[4]=std::string("R. Cingulate Gyrus"); cortroimap[5]=std::string("L. Insula"); cortroimap[1]=std::string("CSF"); cortroimap[2]=std::string("CGM"); cortroimap[3]=std::string("WM"); cortroimap[4]=std::string("DGM"); cortroimap[5]=std::string("Cerebellum"); cortroimap[6]=std::string("R. Insula"); cortroimap[7]=std::string("L. Temporal Pole"); cortroimap[8]=std::string("R. Temporal Pole"); cortroimap[9]=std::string("L. Sup. Temp. Gyrus"); cortroimap[10]=std::string("R. Sup. Temp. Gyrus "); cortroimap[11]=std::string("L. Infero. Temp. Gyrus"); cortroimap[12]=std::string("R. Infero. Temp. Gyrus"); cortroimap[13]=std::string("L. Parahippocampal Gyrus"); cortroimap[14]=std::string("R. Parahippocampal Gyrus"); cortroimap[15]=std::string("L. Frontal Pole"); cortroimap[16]=std::string("R. Frontal Pole"); cortroimap[17]=std::string("L. Sup. Frontal Gyrus"); cortroimap[18]=std::string("R. Sup. Frontal Gyrus"); cortroimap[19]=std::string("L. Mid. Frontal Gyrus"); cortroimap[20]=std::string("R. Mid. Frontal Gyrus"); cortroimap[21]=std::string("L. Inf. Frontal Gyrus"); cortroimap[22]=std::string("R. Inf. Frontal Gyrus"); cortroimap[23]=std::string("L. Orbital Frontal Gyrus"); cortroimap[24]=std::string("R. Orbital Frontal Gyrus"); cortroimap[25]=std::string("L. Precentral Gyrus"); cortroimap[26]=std::string("R. Precentral Gyrus"); cortroimap[27]=std::string("L. Sup. Parietal Lobe"); cortroimap[28]=std::string("R. Sup. Parietal Lobe"); cortroimap[29]=std::string("L. Inf. Parietal Lobe"); cortroimap[30]=std::string("R. Inf. Parietal Lobe"); cortroimap[31]=std::string("L. Postcentral Gyrus"); cortroimap[32]=std::string("R. Postcentral Gyrus"); cortroimap[33]=std::string("L. Hipp. Head"); cortroimap[34]=std::string("R. Hipp Head"); cortroimap[35]=std::string("L. Hipp Midbody"); cortroimap[36]=std::string("R. Hipp Midbody"); cortroimap[37]=std::string("L. Hipp Tail"); cortroimap[38]=std::string("R. Hipp Tail"); cortroimap[39]=std::string("L. Caudate"); cortroimap[40]=std::string("R. Caudate"); cortroimap[41]=std::string("L. Putamen"); cortroimap[42]=std::string("R. Putamen"); cortroimap[43]=std::string("L. Thalamus"); cortroimap[44]=std::string("R. Thalamus"); cortroimap[45]=std::string("White Matter"); std::map wmroimap; wmroimap[1]=std::string("R. corticospinal Tract"); wmroimap[2]=std::string("R. inferior fronto-occipital fasciculus"); wmroimap[3]=std::string("R. inferior longitudinal fasciculus"); wmroimap[4]=std::string("R. superior longitudinal fasciculus"); wmroimap[5]=std::string("R. uncinate fasciculus"); wmroimap[6]=std::string("L. corticospinal Tract"); wmroimap[7]=std::string("L. inferior fronto-occipital fasciculus"); wmroimap[8]=std::string("L. inferior longitudinal fasciculus"); wmroimap[9]=std::string("L. superior longitudinal fasciculus"); wmroimap[10]=std::string("L. uncinate fasciculus"); wmroimap[11]=std::string("Anterior corpus callosum"); wmroimap[12]=std::string("Posterior corpus callosum"); wmroimap[13]=std::string("Mid-body corpus callosum"); // if(grade_list.find("Tim") == grade_list.end()) { std::cout<<"Tim is not in the map!"<second int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string imagename=ANTSGetFilePrefix(outname.c_str())+std::string(".nii.gz"); std::string operation = std::string(argv[argct]); argct++; std::string fn0 = std::string(argv[argct]); argct++; std::cout <<" fn0 " << fn0 << std::endl; std::map roimap=RoiList(fn0); std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = ""; if ( argc > argct) { fn2=std::string(argv[argct]); argct++; } std::string fn3 = ""; if ( argc > argct) { fn3=std::string(argv[argct]); argct++; } std::string fn4 = ""; if ( argc > argct) { fn4=std::string(argv[argct]); argct++; } std::string fn5 = ""; if ( argc > argct) { fn5=std::string(argv[argct]); argct++; } typename ImageType::Pointer image = NULL; typename ImageType::Pointer valimage = NULL; typename ImageType::Pointer valimage3 = NULL; typename ImageType::Pointer valimage4 = NULL; typename ImageType::Pointer valimage5 = NULL; ReadImage(image, fn1.c_str()); if ( fn2.length() > 3) ReadImage(valimage, fn2.c_str()); if ( fn3.length() > 3) ReadImage(valimage3, fn3.c_str()); if ( fn4.length() > 3) ReadImage(valimage4, fn4.c_str()); if ( fn5.length() > 3) ReadImage(valimage5, fn5.c_str()); typedef float PixelType; typedef std::vector LabelSetType; LabelSetType myLabelSet; /** count the labels in the image */ unsigned long maxlab=0; Iterator It ( image,image->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( fabs(label) > 0 ) { if( find( myLabelSet.begin(), myLabelSet.end(), label ) == myLabelSet.end() ) { myLabelSet.push_back( label ); } if (label > maxlab) maxlab=(unsigned long)label; } } // maxlab=32; // for cortical analysis // compute the voxel volume typename ImageType::SpacingType spacing=image->GetSpacing(); float volumeelement=1.0; for (unsigned int i=0; i pvals(maxlab+1,1.0); vnl_vector pvals3(maxlab+1,1.0); vnl_vector pvals4(maxlab+1,1.0); vnl_vector pvals5(maxlab+1,1.0); vnl_vector clusters(maxlab+1,0.0); vnl_vector masses(maxlab+1,0.0); typename ImageType::PointType mycomlist[33]; std::cout <<" csv b " << std::endl; std::ofstream logfile; logfile.open(outname.c_str() ); std::sort(myLabelSet.begin(),myLabelSet.end()); typename LabelSetType::const_iterator it; unsigned long labelcount=0; for( it = myLabelSet.begin(); it != myLabelSet.end(); ++it ) labelcount++; float temp=sqrt((float)labelcount); unsigned int squareimagesize=(unsigned int)(temp+1); typedef itk::Image TwoDImageType; typename TwoDImageType::RegionType newregion; typename TwoDImageType::SizeType size; size[0]=size[1]=squareimagesize; newregion.SetSize(size); typename TwoDImageType::Pointer squareimage = TwoDImageType::New(); typename TwoDImageType::SpacingType spacingb; spacingb.Fill(1); typename TwoDImageType::PointType origin; origin.Fill(0); squareimage->SetSpacing(spacingb); squareimage->SetOrigin(origin); squareimage->SetRegions(newregion ); squareimage->Allocate(); squareimage->FillBuffer( 0 ); labelcount=0; typename ImageType::PointType myCenterOfMass; myCenterOfMass.Fill(0); for (unsigned int i=0; i<=maxlab; i++) mycomlist[i]=myCenterOfMass; for( it = myLabelSet.begin(); it != myLabelSet.end(); ++it ) { float currentlabel= *it ; float totalvolume=0; float totalmass=0; float totalct=0; float maxoneminuspval=0.0; float maxoneminuspval3=0.0; float maxoneminuspval4=0.0; float maxoneminuspval5=0.0; myCenterOfMass.Fill(0); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( label == currentlabel ) { totalvolume+=volumeelement; totalct+=1; float vv=valimage->GetPixel(It.GetIndex()); if ( valimage) totalmass+=vv; if ( vv > maxoneminuspval) maxoneminuspval=vv; if ( valimage3 ){ vv=valimage3->GetPixel(It.GetIndex()); if ( fabs(vv) > fabs(maxoneminuspval3)) maxoneminuspval3=vv; } if ( valimage4 ){ vv=valimage4->GetPixel(It.GetIndex()); if ( vv > maxoneminuspval4) maxoneminuspval4=vv; } if ( valimage5 ){ vv=valimage5->GetPixel(It.GetIndex()); if ( vv > maxoneminuspval5) maxoneminuspval5=vv; } // compute center of mass typename ImageType::PointType point; image->TransformIndexToPhysicalPoint(It.GetIndex(), point); for (unsigned int i=0; iGetBufferPointer()[labelcount]=totalmass/totalct; labelcount++; } bool iswm=false; // if (maxlab > 13 ) iswm=false; // unsigned int roi=(unsigned int) *it; for (unsigned int roi=1; roi <=maxlab ; roi++) { if (roi < maxlab ) logfile << roimap.find(roi)->second << ","; else logfile << roimap.find(roi)->second << ","; //<< std::endl; } for (unsigned int roi=maxlab+1; roi <=maxlab*2 ; roi++) { if (roi < maxlab*2 ) logfile << roimap.find(roi-maxlab)->second+std::string("mass") << ","; else logfile << roimap.find(roi-maxlab)->second+std::string("mass") << std::endl; } for (unsigned int roi=1; roi <=maxlab ; roi++) { if (roi < maxlab ) logfile << clusters[roi] << ","; else logfile << clusters[roi] << ","; //<< std::endl; } for (unsigned int roi=maxlab+1; roi <=maxlab*2 ; roi++) { if (roi < maxlab*2 ) logfile << masses[roi-maxlab] << ","; else logfile << masses[roi-maxlab] << std::endl; } logfile.close(); return 0; for (unsigned int roi=1; roi <=maxlab ; roi++) { //unsigned int resol=5000; //unsigned int intpvalue=resol*totalmass/totalct; // float pvalue=1.0-(float)intpvalue/(float)resol;// average pvalue myCenterOfMass=mycomlist[roi]; if( roimap.find(roi) != roimap.end() && iswm ) std::cout << roimap.find(roi)->second << " & " << clusters[roi] << " , " << pvals[roi] << " & xy & yz \\ " << std::endl; else if( roimap.find(roi) != roimap.end() && ! iswm ) std::cout << roimap.find(roi)->second << " & " << clusters[roi] << " , " << pvals[roi] << " & " << pvals3[roi] << " & " << pvals4[roi] << " & " << (float)((int)(myCenterOfMass[0]*10))/10. << " " << (float)((int)(myCenterOfMass[1]*10))/10. << " " << (float)((int)(myCenterOfMass[2]*10))/10. << " \\ " << std::endl; } // WriteImage(squareimage,imagename.c_str()); return 0; } template int ByteImage( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; float sig = 1; if (argc > argct) sig=atof(argv[argct]); if (sig <= 0) sig=0.5; typename ImageType::Pointer image = NULL; typename ByteImageType::Pointer image2 = NULL; ReadImage(image, fn1.c_str()); typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 255 ); rescaler->SetInput( image ); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(outname.c_str()); writer->SetInput( rescaler->GetOutput() ); writer->Update(); return 0; } template int PValueImage( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; unsigned int dof = 1; if (argc > argct) dof=atoi(argv[argct]); argct++; typename ImageType::Pointer image = NULL; ReadImage(image, fn1.c_str()); std::cout <<" read Image" << fn1 << " dof " << dof << std::endl; typedef itk::Statistics::TDistribution DistributionType; typename DistributionType::Pointer distributionFunction = DistributionType::New(); distributionFunction->SetDegreesOfFreedom( dof ); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( image, image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { float val=image->GetPixel(vfIter.GetIndex()); if ( ! vnl_math_isnan(val) && ! vnl_math_isinf(val) ) { if ( fabs( val ) > 0 ) { float pval=0; if (val >= 1) pval = 1.0-distributionFunction->EvaluateCDF( val , dof ); else if (val < 1) pval = distributionFunction->EvaluateCDF( val , dof ); image->SetPixel(vfIter.GetIndex() , pval ); } } else image->SetPixel(vfIter.GetIndex() , 0); } WriteImage(image,outname.c_str()); return 0; } template int ConvertImageSetToMatrix(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image MatrixImageType; typedef itk::ImageFileReader readertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; if (argc < 5 ) { std::cout <<" need more args -- see usage " << std::endl; exit(0); } std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; unsigned int rowcoloption = atoi(argv[argct]); argct++; std::string maskfn=std::string(argv[argct]); argct++; unsigned int numberofimages=0; typename ImageType::Pointer mask = NULL; ReadImage(mask,maskfn.c_str()); unsigned long voxct=0; Iterator mIter( mask,mask->GetLargestPossibleRegion() ); for( mIter.GoToBegin(); !mIter.IsAtEnd(); ++mIter ) if (mIter.Get() >= 0.5) voxct++; typename ImageType::Pointer image2 = NULL; typename ImageType::SizeType size; size.Fill(0); unsigned int bigimage=0; for (unsigned int j=argct; j< argc; j++) { numberofimages++; // Get the image dimension std::string fn = std::string(argv[j]); typename itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); for (unsigned int i=0; iGetNumberOfDimensions(); i++) { if ( imageIO->GetDimensions(i) > size[i] ) { size[i]=imageIO->GetDimensions(i); bigimage=j; std::cout << " bigimage " << j << " size " << size << std::endl; } } } std:: cout << " largest image " << size << " num images " << numberofimages << " voxct " << voxct << std::endl; /** declare the tiled image */ unsigned long xx=0,yy=0; if (rowcoloption==0) { std::cout << " row option " << std::endl; xx=voxct; yy=numberofimages; } if (rowcoloption==1) { std::cout << " col option " << std::endl; yy=voxct; xx=numberofimages; } unsigned long xsize=xx; unsigned long ysize=yy; typename MatrixImageType::SizeType tilesize; tilesize[0]=xsize; tilesize[1]=ysize; std::cout << " allocate matrix " << tilesize << std::endl; typename MatrixImageType::RegionType region; region.SetSize( tilesize ); typename MatrixImageType::Pointer matimage=MatrixImageType::New(); matimage->SetLargestPossibleRegion( region ); matimage->SetBufferedRegion( region ); typename MatrixImageType::DirectionType mdir; mdir.Fill(0); mdir[0][0]=1; mdir[1][1]=1; typename MatrixImageType::SpacingType mspc; mspc.Fill(1); typename MatrixImageType::PointType morg; morg.Fill(0); matimage->SetSpacing( mspc ); matimage->SetDirection(mdir); matimage->SetOrigin( morg ); matimage->Allocate(); unsigned int imagecount=0; for (unsigned int j=argct; j< argc; j++) { std::string fn = std::string(argv[j]); ReadImage(image2,fn.c_str()); std::cout << " image " << j << " is " << fn << std::endl; unsigned long xx=0,yy=0,tvoxct=0; if (rowcoloption==0) { yy=imagecount; } if (rowcoloption==1) { xx=imagecount; } typename MatrixImageType::IndexType mind; for( mIter.GoToBegin(); !mIter.IsAtEnd(); ++mIter ) { if (mIter.Get() >= 0.5) { if (rowcoloption==0) { xx=tvoxct; } if (rowcoloption==1) { yy=tvoxct; } mind[0]=xx; mind[1]=yy; // std::cout << " Mind " << mind << std::endl; matimage->SetPixel(mind,image2->GetPixel(mIter.GetIndex())); tvoxct++; } } imagecount++; } std::cout << " mat size " << matimage->GetLargestPossibleRegion().GetSize() << std::endl; WriteImage(matimage,outname.c_str()); return 0; } template int ConvertImageToFile( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2=""; if (argc > argct) fn2=std::string(argv[argct]); argct++; typename ImageType::Pointer image = NULL; ReadImage(image, fn1.c_str()); typename ImageType::Pointer mask = NULL; if (fn2.length() > 3) ReadImage(mask, fn2.c_str()); std::cout <<" read Image" << fn1 << " mask? " << fn2 << std::endl; std::ofstream logfile; logfile.open(outname.c_str() ); if (logfile.good()) { typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( image, image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { bool getval=true; if ( mask->GetPixel(vfIter.GetIndex()) < 0.5) getval=false; if (getval) { float val=image->GetPixel(vfIter.GetIndex()); logfile << " " << val ; } } logfile << std::endl; } logfile.close(); return 0; } template int CorrelationUpdate( int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::Image ByteImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; int argct=2; std::string outname=std::string(argv[argct]); argct++; std::string operation = std::string(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 =""; if (argc > argct) { fn2=std::string(argv[argct]); argct++; }else { std::cout <<" Not enough inputs "<< std::endl; return 1; } unsigned int radius=2; if (argc > argct) radius=atoi(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typename ImageType::Pointer imageout = NULL; ReadImage(imageout, fn1.c_str()); imageout->FillBuffer(0); typename ImageType::Pointer image2 = NULL; ReadImage(image2, fn2.c_str()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (unsigned int j=0; jGetLargestPossibleRegion()); float Gsz=(float)GHood.Size(); GHood.GoToBegin(); while (!GHood.IsAtEnd()) { typename ImageType::IndexType ind = GHood.GetIndex(); bool isinside=true; for (unsigned int j=0; j image1->GetLargestPossibleRegion().GetSize()[j]-radius-1 ) isinside=false; } if (isinside) { if ( image1->GetPixel(ind) > 0 || image2->GetPixel(ind) > 0) { typename ImageType::IndexType ind2; // compute mean difference float diff=0.0; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); diff+=(image1->GetPixel(ind2)-image2->GetPixel(ind2)); } diff/=Gsz; float upd=(image1->GetPixel(ind)-image2->GetPixel(ind))-diff; imageout->SetPixel(ind,upd); } } ++GHood; } WriteImage(imageout,outname.c_str()); return 0; } int main(int argc, char *argv[]) { if ( argc < 5 ) { std::cout << "Usage: "<< std::endl; std::cout << argv[0] << " ImageDimension OutputImage.ext Operator Image1.ext Image2.extOrFloat " << std::endl; std::cout <<" some options output text files " << std::endl; std::cout << " The last two arguments can be an image or float value " << std::endl; std::cout << " Valid Operators : \n m (multiply) , \n + (add) , \n - (subtract) , \n / (divide) , \n ^ (power) , \n exp -- take exponent exp(imagevalue*value) \n addtozero \n overadd \n abs \n total -- sums up values in an image or in image1*image2 (img2 is the probability mask) \n Decision -- computes result=1./(1.+exp(-1.0*( pix1-0.25)/pix2)) " << std::endl; std::cout << " Neg (Produce Image Negative ) , \n G Image1.ext s (Smooth with Gaussian of sigma = s ) " << std::endl; std::cout << " MD Image1.ext s ( Morphological Dilation with radius s ) , \n \n ME Image1.ext s ( Morphological Erosion with radius s ) , \n \n MO Image1.ext s ( Morphological Opening with radius s ) \n \n MC Image1.ext ( Morphological Closing with radius s ) \n \n GD Image1.ext s ( Grayscale Dilation with radius s ) , \n \n GE Image1.ext s ( Grayscale Erosion with radius s ) , \n \n GO Image1.ext s ( Grayscale Opening with radius s ) \n \n GC Image1.ext ( Grayscale Closing with radius s ) \n" << std::endl; std::cout << " D (DistanceTransform) , \n \n Segment Image1.ext N-Classes LocalityVsGlobalityWeight-In-ZeroToOneRange OptionalPriorImages ( Segment an Image with option of Priors , weight 1 => maximally local/prior-based ) \n " << std::endl; std::cout << " Grad Image.ext S ( Gradient magnitude with sigma s -- if normalize, then output in range [0, 1] ) , \n " << std::endl; std::cout << " Laplacian Image.ext S normalize? ( laplacian computed with sigma s -- if normalize, then output in range [0, 1] ) , \n " << std::endl; std::cout << " Normalize image.ext opt ( Normalize to [0,1] option instead divides by average value ) \n " << std::endl; std::cout << " PH (Print Header) , \n Byte ( Convert to Byte image in [0,255] ) \n " << std::endl; std::cout << " LabelStats labelimage.ext valueimage.nii ( compute volumes / masses of objects in a label image -- write to text file ) \n" << std::endl; std::cout << " ROIStatistics LabelNames.txt labelimage.ext valueimage.nii ( see the code ) \n" << std::endl; std::cout << " DiceAndMinDistSum LabelImage1.ext LabelImage2.ext OptionalDistImage -- outputs DiceAndMinDistSum and Dice Overlap to text log file + optional distance image \n " << std::endl; std::cout << " Lipschitz VectorFieldName -- prints to cout & writes to image \n " << std::endl; std::cout << " InvId VectorFieldName VectorFieldName -- prints to cout & writes to image \n " << std::endl; std::cout << " GetLargestComponent InputImage {MinObjectSize} -- get largest object in image \n " << std::endl; std::cout << " ThresholdAtMean Image %ofMean \n " << std::endl; std::cout << " FlattenImage Image %ofMax -- replaces values greater than %ofMax*Max to the value %ofMax*Max \n " << std::endl; std::cout << " stack Image1.nii.gz Image2.nii.gz --- will put these 2 images in the same volume " << std::endl; std::cout << " CorruptImage Image NoiseLevel Smoothing " << std::endl; std::cout << " TileImages NumColumns ImageList* " << std::endl; std::cout << " RemoveLabelInterfaces ImageIn " << std::endl; std::cout << " EnumerateLabelInterfaces ImageIn ColoredImageOutname NeighborFractionToIgnore " << std::endl; std::cout << " FitSphere GM-ImageIn {WM-Image} {MaxRad-Default=5}" << std::endl; std::cout << " HistogramMatch SourceImage ReferenceImage {NumberBins-Default=255} {NumberPoints-Default=64}" << std::endl; std::cout << " PadImage ImageIn Pad-Number ( if Pad-Number is negative, de-Padding occurs ) " << std::endl; std::cout << " Where Image ValueToLookFor maskImage-option tolerance --- the where function from IDL " << std::endl; std::cout << " TensorFA DTImage " << std::endl; std::cout << " TensorColor DTImage --- produces RGB values identifying principal directions " << std::endl; std::cout << " TensorToVector DTImage WhichVec --- produces vector field identifying one of the principal directions, 2 = largest eigenvalue " << std::endl; std::cout << " TensorToVectorComponent DTImage WhichVec --- 0 => 2 produces component of the principal vector field , i.e. largest eigenvalue. 3 = 8 => gets values from the tensor " << std::endl; std::cout << " TensorIOTest DTImage --- will write the DT image back out ... tests I/O processes for consistency. " << std::endl; std::cout << " MakeImage SizeX SizeY {SizeZ} " << std::endl; std::cout << " SetOrGetPixel ImageIn Get/Set-Value IndexX IndexY {IndexZ} -- for example \n ImageMath 2 outimage.nii SetOrGetPixel Image Get 24 34 -- gets the value at 24, 34 \n ImageMath 2 outimage.nii SetOrGetPixel Image 1.e9 24 34 -- this sets 1.e9 as the value at 23 34 " << std::endl << " you can also pass a boolean at the end to force the physical space to be used " << std::endl; std::cout << " TensorMeanDiffusion DTImage " << std::endl; std::cout << " CompareHeadersAndImages Image1 Image2 --- tries to find and fix header error! output is the repaired image with new header. never use this if you trust your header information. " << std::endl; std::cout << " CountVoxelDifference Image1 Image2 Mask --- the where function from IDL " << std::endl; std::cout << " stack image1 image2 --- stack image2 onto image1 " << std::endl; std::cout << " CorrelationUpdate Image1 Image2 RegionRadius --- in voxels , Compute update that makes Image2 more like Image1 " << std::endl; std::cout << " ConvertImageToFile imagevalues.nii {Optional-ImageMask.nii} -- will write voxel values to a file " << std::endl; std::cout << " PValueImage TValueImage dof " << std::endl; std::cout << " ConvertToGaussian TValueImage sigma-float " << std::endl; std::cout << " ConvertImageSetToMatrix rowcoloption Mask.nii *images.nii -- each row/column contains image content extracted from mask applied to images in *img.nii " << std::endl; std::cout << " ConvertVectorToImage Mask.nii vector.nii -- the vector contains image content extracted from a mask - here we return the vector to its spatial origins as image content " << std::endl; std::cout << " TriPlanarView ImageIn.nii.gz PercentageToClampLowIntensity PercentageToClampHiIntensity x-slice y-slice z-slice " << std::endl; std::cout << " TruncateImageIntensity inputImage {lowerQuantile=0.05} {upperQuantile=0.95} {numberOfBins=65} {binary-maskImage} " << std::endl; std::cout << " FillHoles Image parameter : parameter = ratio of edge at object to edge at background = 1 is a definite hole bounded by object only, 0.99 is close -- default of parameter > 1 will fill all holes " << std::endl; std::cout << " PropagateLabelsThroughMask speed/binaryimagemask.nii.gz initiallabelimage.nii.gz Optional-Stopping-Value -- final output is the propagated label image " << std::endl << " optional stopping value -- higher values allow more distant propagation " << std::endl; std::cout << " FastMarchingSegmentation speed/binaryimagemask.nii.gz initiallabelimage.nii.gz Optional-Stopping-Value -- final output is the propagated label image " << std::endl << " optional stopping value -- higher values allow more distant propagation " << std::endl; std::cout << " ExtractSlice volume.nii.gz slicetoextract --- will extract slice number from last dimension of volume (2,3,4) dimensions " << std::endl; std::cout << " ConvertLandmarkFile InFile.txt ---- will convert landmark file between formats. see ants.pdf for description of formats. e.g. ImageMath 3 outfile.vtk ConvertLandmarkFile infile.txt " << std::endl; return 1; } std::string operation=std::string(argv[3]); switch ( atoi(argv[1]) ) { case 2: if (strcmp(operation.c_str(),"m") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"mresample") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"+") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"-") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"/") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"^") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"exp") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"abs") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"addtozero") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"overadd") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"total") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"Decision") == 0) ImageMath<2>(argc,argv); else if (strcmp(operation.c_str(),"Neg") == 0) NegativeImage<2>(argc,argv); else if (strcmp(operation.c_str(),"G") == 0) SmoothImage<2>(argc,argv); else if (strcmp(operation.c_str(),"MD") == 0 || strcmp(operation.c_str(),"ME") == 0) MorphImage<2>(argc,argv); else if (strcmp(operation.c_str(),"MO") == 0 || strcmp(operation.c_str(),"MC") == 0) MorphImage<2>(argc,argv); else if (strcmp(operation.c_str(),"GD") == 0 || strcmp(operation.c_str(),"GE") == 0) MorphImage<2>(argc,argv); else if (strcmp(operation.c_str(),"GO") == 0 || strcmp(operation.c_str(),"GC") == 0) MorphImage<2>(argc,argv); else if (strcmp(operation.c_str(),"D") == 0 ) DistanceMap<2>(argc,argv); else if (strcmp(operation.c_str(),"Normalize") == 0 ) NormalizeImage<2>(argc,argv); else if (strcmp(operation.c_str(),"Grad") == 0 ) GradientImage<2>(argc,argv); else if (strcmp(operation.c_str(),"Laplacian") == 0 ) LaplacianImage<2>(argc,argv); else if (strcmp(operation.c_str(),"PH") == 0 ) PrintHeader<2>(argc,argv); else if (strcmp(operation.c_str(),"Byte") == 0 ) ByteImage<2>(argc,argv); else if (strcmp(operation.c_str(),"LabelStats") == 0 ) LabelStats<2>(argc,argv); else if (strcmp(operation.c_str(),"ROIStatistics") == 0 ) ROIStatistics<2>(argc,argv); else if (strcmp(operation.c_str(),"DiceAndMinDistSum") == 0 ) DiceAndMinDistSum<2>(argc,argv); else if (strcmp(operation.c_str(),"Lipschitz") == 0 ) Lipschitz<2>(argc,argv); else if (strcmp(operation.c_str(),"InvId") == 0 ) InvId<2>(argc,argv); else if (strcmp(operation.c_str(),"GetLargestComponent") == 0 ) GetLargestComponent<2>(argc,argv); else if (strcmp(operation.c_str(),"ThresholdAtMean") == 0 ) ThresholdAtMean<2>(argc,argv); else if (strcmp(operation.c_str(),"FlattenImage") == 0 ) FlattenImage<2>(argc,argv); else if (strcmp(operation.c_str(),"CorruptImage") == 0 ) CorruptImage<2>(argc,argv); else if (strcmp(operation.c_str(),"TileImages") == 0 ) TileImages<2>(argc,argv); else if (strcmp(operation.c_str(),"Where") == 0 ) Where<2>(argc,argv); else if (strcmp(operation.c_str(),"FillHoles") == 0 ) FillHoles<2>(argc,argv); else if (strcmp(operation.c_str(),"HistogramMatch") == 0) HistogramMatching<2>(argc,argv); else if (strcmp(operation.c_str(),"PadImage") == 0 ) PadImage<2>(argc,argv); else if (strcmp(operation.c_str(),"SetOrGetPixel") == 0 ) SetOrGetPixel<2>(argc,argv); else if (strcmp(operation.c_str(),"MakeImage") == 0 ) MakeImage<2>(argc,argv); else if (strcmp(operation.c_str(),"stack") == 0 ) StackImage<2>(argc,argv); else if (strcmp(operation.c_str(),"CompareHeadersAndImages") == 0 ) CompareHeadersAndImages<2>(argc,argv); else if (strcmp(operation.c_str(),"CountVoxelDifference") == 0 ) CountVoxelDifference<2>(argc,argv); // else if (strcmp(operation.c_str(),"AddToZero") == 0 ) AddToZero<2>(argc,argv); else if (strcmp(operation.c_str(),"RemoveLabelInterfaces") == 0 ) RemoveLabelInterfaces<2>(argc,argv); else if (strcmp(operation.c_str(),"EnumerateLabelInterfaces") == 0 ) EnumerateLabelInterfaces<2>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageToFile") == 0 ) ConvertImageToFile<2>(argc,argv); else if (strcmp(operation.c_str(),"PValueImage") == 0 ) PValueImage<2>(argc,argv); else if (strcmp(operation.c_str(),"CorrelationUpdate") == 0 ) CorrelationUpdate<2>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageSetToMatrix") == 0 ) ConvertImageSetToMatrix<2>(argc,argv); else if (strcmp(operation.c_str(),"ConvertVectorToImage") == 0 ) ConvertVectorToImage<2>(argc,argv); else if (strcmp(operation.c_str(),"PropagateLabelsThroughMask") == 0 ) PropagateLabelsThroughMask<2>(argc,argv); else if (strcmp(operation.c_str(),"FastMarchingSegmentation") == 0 ) FastMarchingSegmentation<2>(argc,argv); else if (strcmp(operation.c_str(),"TruncateImageIntensity") == 0 ) TruncateImageIntensity<2>(argc,argv); else if (strcmp(operation.c_str(),"ExtractSlice") == 0) ExtractSlice<2>(argc,argv); // else if (strcmp(operation.c_str(),"ConvertLandmarkFile") == 0) ConvertLandmarkFile<2>(argc,argv); else std::cout << " cannot find operation : " << operation << std::endl; break; case 3: if (strcmp(operation.c_str(),"m") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"mresample") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"+") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"-") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"/") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"^") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"exp") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"abs") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"addtozero") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"overadd") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"total") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"Decision") == 0) ImageMath<3>(argc,argv); else if (strcmp(operation.c_str(),"Neg") == 0) NegativeImage<3>(argc,argv); else if (strcmp(operation.c_str(),"G") == 0) SmoothImage<3>(argc,argv); else if (strcmp(operation.c_str(),"MD") == 0 || strcmp(operation.c_str(),"ME") == 0) MorphImage<3>(argc,argv); else if (strcmp(operation.c_str(),"MO") == 0 || strcmp(operation.c_str(),"MC") == 0) MorphImage<3>(argc,argv); else if (strcmp(operation.c_str(),"GD") == 0 || strcmp(operation.c_str(),"GE") == 0) MorphImage<3>(argc,argv); else if (strcmp(operation.c_str(),"GO") == 0 || strcmp(operation.c_str(),"GC") == 0) MorphImage<3>(argc,argv); else if (strcmp(operation.c_str(),"D") == 0 ) DistanceMap<3>(argc,argv); else if (strcmp(operation.c_str(),"Normalize") == 0 ) NormalizeImage<3>(argc,argv); else if (strcmp(operation.c_str(),"Grad") == 0 ) GradientImage<3>(argc,argv); else if (strcmp(operation.c_str(),"Laplacian") == 0 ) LaplacianImage<3>(argc,argv); else if (strcmp(operation.c_str(),"PH") == 0 ) PrintHeader<3>(argc,argv); else if (strcmp(operation.c_str(),"Byte") == 0 ) ByteImage<3>(argc,argv); else if (strcmp(operation.c_str(),"LabelStats") == 0 ) LabelStats<3>(argc,argv); else if (strcmp(operation.c_str(),"ROIStatistics") == 0 ) ROIStatistics<3>(argc,argv); else if (strcmp(operation.c_str(),"DiceAndMinDistSum") == 0 ) DiceAndMinDistSum<3>(argc,argv); else if (strcmp(operation.c_str(),"Lipschitz") == 0 ) Lipschitz<3>(argc,argv); else if (strcmp(operation.c_str(),"InvId") == 0 ) InvId<3>(argc,argv); else if (strcmp(operation.c_str(),"GetLargestComponent") == 0 ) GetLargestComponent<3>(argc,argv); else if (strcmp(operation.c_str(),"ThresholdAtMean") == 0 ) ThresholdAtMean<3>(argc,argv); else if (strcmp(operation.c_str(),"FlattenImage") == 0 ) FlattenImage<3>(argc,argv); else if (strcmp(operation.c_str(),"CorruptImage") == 0 ) CorruptImage<3>(argc,argv); else if (strcmp(operation.c_str(),"RemoveLabelInterfaces") == 0 ) RemoveLabelInterfaces<3>(argc,argv); else if (strcmp(operation.c_str(),"EnumerateLabelInterfaces") == 0 ) EnumerateLabelInterfaces<3>(argc,argv); else if (strcmp(operation.c_str(),"FitSphere") == 0 ) FitSphere<3>(argc,argv); else if (strcmp(operation.c_str(),"Where") == 0 ) Where<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorFA") == 0 ) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorIOTest") == 0 ) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorMeanDiffusion") == 0 ) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorColor") == 0) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorToVector") == 0) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"TensorToVectorComponent") == 0) TensorFunctions<3>(argc,argv); else if (strcmp(operation.c_str(),"FillHoles") == 0 ) FillHoles<3>(argc,argv); else if (strcmp(operation.c_str(),"HistogramMatch") == 0) HistogramMatching<3>(argc,argv); else if (strcmp(operation.c_str(),"PadImage") == 0 ) PadImage<3>(argc,argv); else if (strcmp(operation.c_str(),"SetOrGetPixel") == 0 ) SetOrGetPixel<3>(argc,argv); else if (strcmp(operation.c_str(),"MakeImage") == 0 ) MakeImage<3>(argc,argv); else if (strcmp(operation.c_str(),"stack") == 0 ) StackImage<3>(argc,argv); else if (strcmp(operation.c_str(),"CompareHeadersAndImages") == 0 ) CompareHeadersAndImages<3>(argc,argv); else if (strcmp(operation.c_str(),"CountVoxelDifference") == 0 ) CountVoxelDifference<3>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageToFile") == 0 ) ConvertImageToFile<3>(argc,argv); else if (strcmp(operation.c_str(),"PValueImage") == 0 ) PValueImage<3>(argc,argv); else if (strcmp(operation.c_str(),"CorrelationUpdate") == 0 ) CorrelationUpdate<3>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageSetToMatrix") == 0 ) ConvertImageSetToMatrix<3>(argc,argv); else if (strcmp(operation.c_str(),"ConvertVectorToImage") == 0 ) ConvertVectorToImage<3>(argc,argv); else if (strcmp(operation.c_str(),"PropagateLabelsThroughMask") == 0 ) PropagateLabelsThroughMask<3>(argc,argv); else if (strcmp(operation.c_str(),"FastMarchingSegmentation") == 0 ) FastMarchingSegmentation<3>(argc,argv); else if (strcmp(operation.c_str(),"TriPlanarView") == 0 ) TriPlanarView<3>(argc,argv); else if (strcmp(operation.c_str(),"TruncateImageIntensity") == 0 ) TruncateImageIntensity<3>(argc,argv); else if (strcmp(operation.c_str(),"ExtractSlice") == 0) ExtractSlice<3>(argc,argv); else if (strcmp(operation.c_str(),"ConvertLandmarkFile") == 0) ConvertLandmarkFile<3>(argc,argv); else std::cout << " cannot find operation : " << operation << std::endl; break; case 4: if (strcmp(operation.c_str(),"m") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"mresample") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"+") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"-") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"/") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"^") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"exp") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"abs") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"addtozero") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"overadd") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"total") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"Decision") == 0) ImageMath<4>(argc,argv); else if (strcmp(operation.c_str(),"Neg") == 0) NegativeImage<4>(argc,argv); else if (strcmp(operation.c_str(),"G") == 0) SmoothImage<4>(argc,argv); else if (strcmp(operation.c_str(),"MD") == 0 || strcmp(operation.c_str(),"ME") == 0) MorphImage<4>(argc,argv); else if (strcmp(operation.c_str(),"MO") == 0 || strcmp(operation.c_str(),"MC") == 0) MorphImage<4>(argc,argv); else if (strcmp(operation.c_str(),"GD") == 0 || strcmp(operation.c_str(),"GE") == 0) MorphImage<4>(argc,argv); else if (strcmp(operation.c_str(),"GO") == 0 || strcmp(operation.c_str(),"GC") == 0) MorphImage<4>(argc,argv); else if (strcmp(operation.c_str(),"D") == 0 ) DistanceMap<4>(argc,argv); else if (strcmp(operation.c_str(),"Normalize") == 0 ) NormalizeImage<4>(argc,argv); else if (strcmp(operation.c_str(),"Grad") == 0 ) GradientImage<4>(argc,argv); else if (strcmp(operation.c_str(),"Laplacian") == 0 ) LaplacianImage<4>(argc,argv); else if (strcmp(operation.c_str(),"PH") == 0 ) PrintHeader<4>(argc,argv); else if (strcmp(operation.c_str(),"Byte") == 0 ) ByteImage<4>(argc,argv); else if (strcmp(operation.c_str(),"LabelStats") == 0 ) LabelStats<4>(argc,argv); else if (strcmp(operation.c_str(),"ROIStatistics") == 0 ) ROIStatistics<4>(argc,argv); else if (strcmp(operation.c_str(),"DiceAndMinDistSum") == 0 ) DiceAndMinDistSum<4>(argc,argv); else if (strcmp(operation.c_str(),"Lipschitz") == 0 ) Lipschitz<4>(argc,argv); else if (strcmp(operation.c_str(),"InvId") == 0 ) InvId<4>(argc,argv); else if (strcmp(operation.c_str(),"GetLargestComponent") == 0 ) GetLargestComponent<4>(argc,argv); else if (strcmp(operation.c_str(),"ThresholdAtMean") == 0 ) ThresholdAtMean<4>(argc,argv); else if (strcmp(operation.c_str(),"FlattenImage") == 0 ) FlattenImage<4>(argc,argv); else if (strcmp(operation.c_str(),"CorruptImage") == 0 ) CorruptImage<4>(argc,argv); else if (strcmp(operation.c_str(),"RemoveLabelInterfaces") == 0 ) RemoveLabelInterfaces<4>(argc,argv); else if (strcmp(operation.c_str(),"EnumerateLabelInterfaces") == 0 ) EnumerateLabelInterfaces<4>(argc,argv); else if (strcmp(operation.c_str(),"FitSphere") == 0 ) FitSphere<4>(argc,argv); else if (strcmp(operation.c_str(),"Where") == 0 ) Where<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorFA") == 0 ) TensorFunctions<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorIOTest") == 0 ) TensorFunctions<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorMeanDiffusion") == 0 ) TensorFunctions<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorColor") == 0) TensorFunctions<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorToVector") == 0) TensorFunctions<4>(argc,argv); // else if (strcmp(operation.c_str(),"TensorToVectorComponent") == 0) TensorFunctions<4>(argc,argv); else if (strcmp(operation.c_str(),"FillHoles") == 0 ) FillHoles<4>(argc,argv); else if (strcmp(operation.c_str(),"HistogramMatch") == 0) HistogramMatching<4>(argc,argv); else if (strcmp(operation.c_str(),"PadImage") == 0 ) PadImage<4>(argc,argv); // else if (strcmp(operation.c_str(),"SetOrGetPixel") == 0 ) SetOrGetPixel<4>(argc,argv); else if (strcmp(operation.c_str(),"MakeImage") == 0 ) MakeImage<4>(argc,argv); else if (strcmp(operation.c_str(),"stack") == 0 ) StackImage<4>(argc,argv); else if (strcmp(operation.c_str(),"CompareHeadersAndImages") == 0 ) CompareHeadersAndImages<4>(argc,argv); else if (strcmp(operation.c_str(),"CountVoxelDifference") == 0 ) CountVoxelDifference<4>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageToFile") == 0 ) ConvertImageToFile<4>(argc,argv); else if (strcmp(operation.c_str(),"PValueImage") == 0 ) PValueImage<4>(argc,argv); else if (strcmp(operation.c_str(),"CorrelationUpdate") == 0 ) CorrelationUpdate<4>(argc,argv); else if (strcmp(operation.c_str(),"ConvertImageSetToMatrix") == 0 ) ConvertImageSetToMatrix<4>(argc,argv); else if (strcmp(operation.c_str(),"ConvertVectorToImage") == 0 ) ConvertVectorToImage<4>(argc,argv); else if (strcmp(operation.c_str(),"PropagateLabelsThroughMask") == 0 ) PropagateLabelsThroughMask<4>(argc,argv); else if (strcmp(operation.c_str(),"FastMarchingSegmentation") == 0 ) FastMarchingSegmentation<4>(argc,argv); else if (strcmp(operation.c_str(),"TriPlanarView") == 0 ) TriPlanarView<4>(argc,argv); else if (strcmp(operation.c_str(),"TruncateImageIntensity") == 0 ) TruncateImageIntensity<4>(argc,argv); else if (strcmp(operation.c_str(),"ExtractSlice") == 0) ExtractSlice<4>(argc,argv); else if (strcmp(operation.c_str(),"ConvertLandmarkFile") == 0) ConvertLandmarkFile<4>(argc,argv); else std::cout << " cannot find operation : " << operation << std::endl; break; default: std::cerr << " Dimension Not supported " << atoi(argv[1]) << std::endl; exit( 1 ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ImageSetStatistics.cxx000066400000000000000000000632521147325206600225430ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ImageSetStatistics.cxx,v $ Language: C++ Date: $Date: 2009/05/15 13:23:53 $ Version: $Revision: 1.2 $ Copriyght (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "ReadWriteImage.h" //#include "DoSomethingToImage.cxx" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkHistogramMatchingImageFilter.h" #include "itkMinimumMaximumImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkRelabelComponentImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkLabelStatisticsImageFilter.h" #include "itkNeighborhoodIterator.h" // RecursiveAverageImages img1 img2 weight // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. //Note: could easily add variance computation //http://people.revoledu.com/kardi/tutorial/RecursiveStatistic/Time-Variance.htm #include "itkDiscreteGaussianImageFilter.h" template void ReadImage(itk::SmartPointer &target, const char *file, bool copy) { // std::cout << " reading b " << std::string(file) << std::endl; typedef itk::ImageFileReader readertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(file); reader->Update(); if (!copy) target=(reader->GetOutput() ); else { typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( target, target->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { vfIter2.Set( reader->GetOutput()->GetPixel(vfIter2.GetIndex() )); } } } double TProb(double t, int df) { if (t == 0) return 0; double a = 0.36338023; double w = atan(t / sqrt((double)df)); double s = sin(w); double c = cos(w); double t1, t2; int j1, j2, k2; if (df % 2 == 0) // even { t1 = s; if (df == 2) // special case df=2 return (0.5 * (1 + t1)); t2 = s; j1 = -1; j2 = 0; k2 = (df - 2) / 2; } else { t1 = w; if (df == 1) // special case df=1 return 1 - (0.5 * (1 + (t1 * (1 - a)))); t2 = s * c; t1 = t1 + t2; if (df == 3) // special case df=3 return 1 - (0.5 * (1 + (t1 * (1 - a)))); j1 = 0; j2 = 1; k2 = (df - 3)/2; } for (int i=1; i >= k2; i++) { j1 = j1 + 2; j2 = j2 + 2; t2 = t2 * c * c * j1/j2; t1 = t1 + t2; } return 1 - (0.5 * (1 + (t1 * (1 - a * (df % 2))))); } template typename TImage::Pointer SmoothImage(typename TImage::Pointer image, float sig) { typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); return filter->GetOutput(); } template //typename TInputImage::Pointer void HistogramMatch(typename TInputImage::Pointer m_InputFixedImage, typename TInputImage::Pointer m_InputMovingImage)// typename TInputImage::Pointer m_OutputMovingImage ) { std::cout << " MATCHING INTENSITIES " << std::endl; typedef itk::HistogramMatchingImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( m_InputMovingImage ); filter->SetReferenceImage( m_InputFixedImage ); filter->SetNumberOfHistogramLevels( 256 ); filter->SetNumberOfMatchPoints( 10 ); filter->ThresholdAtMeanIntensityOn(); filter->ThresholdAtMeanIntensityOff(); filter->Update(); typename TInputImage::Pointer img = filter->GetOutput(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( img, img->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { m_InputMovingImage->SetPixel(vfIter.GetIndex(), vfIter.Get() ); } return; } template void LocalMean(typename TImage::Pointer image, unsigned int nhood, typename TImage::Pointer meanimage ) { typename TImage::Pointer localmean=MakeNewImage(image,0); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator outIter(image, image->GetLargestPossibleRegion() ); typename TImage::SizeType imagesize=image->GetLargestPossibleRegion().GetSize(); const unsigned int ImageDimension = 3; typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for( unsigned int j = 0; j < ImageDimension; j++ ) rad[j] = nhood; for( outIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter ) { itk::NeighborhoodIterator hoodIt( rad,image ,image->GetLargestPossibleRegion()); typename TImage::IndexType oindex = outIter.GetIndex(); hoodIt.SetLocation(oindex); double fixedMean=0; //double movingMean=0; unsigned int indct; unsigned int hoodlen=hoodIt.Size(); //unsigned int inct=0; bool takesample = true; //double sumj=0; //double sumi=0; if (takesample) { //double sumj=0; double sumi=0; unsigned int cter=0; for(indct=0; indct static_cast(imagesize[dd]-1) ) inimage=false; } if (inimage) { sumi+=image->GetPixel(index); cter++; } } if (cter > 0) fixedMean=sumi/(float)cter; } float val = image->GetPixel(oindex) - fixedMean; meanimage->SetPixel( oindex, meanimage->GetPixel(oindex) +fixedMean); localmean->SetPixel( oindex, val ); } typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( image, image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { vfIter.Set( localmean->GetPixel( vfIter.GetIndex() )); } return;// localmean; } template //std::vector float GetClusterStat(typename TImage::Pointer image, float Tthreshold, unsigned int minSize, unsigned int whichstat, std::string outfn, bool TRUTH) { typedef float InternalPixelType; typedef TImage InternalImageType; typedef TImage OutputImageType; typedef itk::BinaryThresholdImageFilter< InternalImageType, InternalImageType > ThresholdFilterType; typedef itk::ConnectedComponentImageFilter< InternalImageType, OutputImageType > FilterType; typedef itk::RelabelComponentImageFilter< OutputImageType, OutputImageType > RelabelType; typename ThresholdFilterType::Pointer threshold = ThresholdFilterType::New(); typename FilterType::Pointer filter = FilterType::New(); typename RelabelType::Pointer relabel = RelabelType::New(); InternalPixelType threshold_low, threshold_hi; threshold_low = Tthreshold; threshold_hi = 1.e9; threshold->SetInput (image); threshold->SetInsideValue(itk::NumericTraits::One); threshold->SetOutsideValue(itk::NumericTraits::Zero); threshold->SetLowerThreshold(threshold_low); threshold->SetUpperThreshold(threshold_hi); threshold->Update(); filter->SetInput (threshold->GetOutput()); // if (argc > 5) { int fullyConnected = 1;//atoi( argv[5] ); filter->SetFullyConnected( fullyConnected ); } relabel->SetInput( filter->GetOutput() ); relabel->SetMinimumObjectSize( minSize ); // relabel->SetUseHistograms(true); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } typename TImage::Pointer Clusters=MakeNewImage(relabel->GetOutput(),0); //typename TImage::Pointer Clusters=relabel->GetOutput(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( relabel->GetOutput(), relabel->GetOutput()->GetLargestPossibleRegion() ); /* typename itk::LabelStatisticsImageFilter::Pointer labstat= itk::LabelStatisticsImageFilter::New(); labstat->SetInput(image); labstat->SetLabelImage(Clusters); labstat->SetUseHistograms(true); labstat->Update(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( Clusters, Clusters->GetLargestPossibleRegion() ); float maximum=0; // Relabel the Clusters image with the right statistic for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (relabel->GetOutput()->GetPixel(vfIter.GetIndex()) > 0 ) { float pix = relabel->GetOutput()->GetPixel(vfIter.GetIndex()); float val; if (whichstat == 0) val=pix; else if (whichstat == 1) val = labstat->GetSum(pix); else if (whichstat == 2) val = labstat->GetMean(pix); else if (whichstat == 3) val = labstat->GetMaximum(pix); if (val > maximum) maximum=val; vfIter.Set(val); } } */ float maximum=relabel->GetNumberOfObjects(); float maxtstat=0; std::vector histogram((int)maximum+1); std::vector clustersum((int)maximum+1); for (int i=0; i<=maximum; i++) { histogram[i]=0; clustersum[i]=0; } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { float vox=image->GetPixel(vfIter.GetIndex()); histogram[(unsigned int)vfIter.Get()]=histogram[(unsigned int)vfIter.Get()]+1; clustersum[(unsigned int)vfIter.Get()]+=vox; if (vox > maxtstat) maxtstat=vox; } } for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (vfIter.Get() > 0 ) { if (whichstat == 0) //size { Clusters->SetPixel( vfIter.GetIndex(), histogram[(unsigned int)vfIter.Get()] ); } if (whichstat == 1) //sum { Clusters->SetPixel( vfIter.GetIndex(), clustersum[(unsigned int)vfIter.Get()] ); } if (whichstat == 2) //mean { Clusters->SetPixel( vfIter.GetIndex(), clustersum[(unsigned int)vfIter.Get()]/(float)histogram[(unsigned int)vfIter.Get()] ); } if (whichstat == 3) //max { Clusters->SetPixel( vfIter.GetIndex(), histogram[(unsigned int)vfIter.Get()] ); } } else Clusters->SetPixel(vfIter.GetIndex(),0); } // for (int i=0; i<=maximum; i++) // std::cout << " label " << i << " ct is: " << histogram[i] << std::endl; if (TRUTH) { typedef itk::ImageFileWriter writertype; typename writertype::Pointer writer = writertype::New(); writer->SetFileName( (outfn+std::string("Clusters.nii")).c_str()); writer->SetInput( Clusters ); writer->Write(); } if (whichstat == 0) return histogram[1]; else if (whichstat == 1) { float mx=0; for (int i=1; i<=maximum; i++) if (clustersum[i] > mx) mx=clustersum[i]; return mx; } else if (whichstat == 2) { float mx=0; for (int i=1; i<=maximum; i++) if (clustersum[i]/(float)histogram[i] > mx) mx=clustersum[i]/(float)histogram[i]*1000.0; return mx; } else if (whichstat == 3) return maxtstat*1000.0; else return histogram[1]; } float median(std::vector vec) { typedef std::vector::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) return 0; // throw domain_error("median of an empty vector"); sort(vec.begin(),vec.end()); vec_sz mid = size/2; return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; } float npdf(std::vector vec, bool opt, float www) { typedef std::vector::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) return 0; // throw domain_error("median of an empty vector"); float mean=0,var=0; float max=-1.e9,min=1.e9; for (unsigned int i=0; i max) max=val; else if (val < min) min=val; float n = (float) (i+1); float wt1 = 1.0/(float)n; float wt2 = 1.0-wt1; mean = mean*wt2+val*wt1; if ( i > 0) { float wt3 = 1.0/( (float) n - 1.0 ); var = var*wt2 + ( val - mean )*( val - mean)*wt3; } } if (var == 0) return mean; // else std::cout << " Mean " << mean << " var " << var << std::endl; // eval parzen probability std::vector prob(size); float maxprob=0; // float maxprobval=0; float weightedmean=0; float weighttotal=0; unsigned int maxprobind=0; // float sample=0.0; float width; if (www > 0 ) width = www; else width = sqrt(var)/2.0; // std::cout << " using width " << width << std::endl; // float N=(float)size; for (unsigned int j=0; j maxprob){ maxprob=total; maxprobind=j; } weightedmean+=sample*total; weighttotal+=total; // for (unsigned int i=0; i vec) { typedef std::vector::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) return 0; // throw domain_error("median of an empty vector"); sort(vec.begin(),vec.end()); vec_sz mid = size/2; float lo=mid-(0.1*size+1); float hi=mid+(0.1*size+1); lo=0; hi=size; float ct=hi-lo; float total=0; for (unsigned int i=(unsigned int)lo; i vec) { typedef std::vector::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) return 0; float max=-1.e9; for (unsigned int i=0; i max) max=val; } return max; } float myantssimilaritymaxlabel(std::vector labelvec, std::vector similarityvec, bool opt) { typedef std::vector::size_type vec_sz; vec_sz size = labelvec.size(); if (size == 0) return 0; unsigned int max=0; float maxsim=-1.e9; float totalsim=0; float estapp=0; for (unsigned int i=0; i maxsim) { maxsim=simval; max=i; } // std::cout << " simval " << simval << " i " << i << " appval " << appval << " maxsim " << maxsim << " max " << max << std::endl; } // std::cout <<" estapp " << estapp << " max " << max << std::endl; //return estapp; if ( opt == true ) return labelvec[max]; else return max; } template int ImageSetStatistics(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; unsigned int mch=0; int argct=2; std::string fn1 = std::string(argv[argct]); argct++; std::string outfn = std::string(argv[argct]);argct++; unsigned int whichstat = atoi(argv[argct]);argct++; std::string roifn=""; if (argc > argct){ roifn=std::string(argv[argct]); argct++; } std::string simimagelist=std::string(""); if (argc > argct){ simimagelist=std::string(argv[argct]); argct++; } float www = 0; // if (argc > argct) { www=atof(argv[argct]);argct++;} // unsigned int mchmax= 0; // if (argc > argct) { mchmax=atoi(argv[argct]); argct++;} unsigned int localmeanrad= 0; // if (argc > argct) { localmeanrad=atoi(argv[argct]);argct++;} // std::cout <<" roifn " << roifn << " fn1 " << fn1 << " whichstat " << whichstat << std::endl; typename ImageType::Pointer outimage = NULL; typename ImageType::Pointer ROIimg = NULL; if (roifn.length() > 4) { std::cout <<" reading roi image " << roifn << std::endl; typename readertype::Pointer reader2 = readertype::New(); reader2->SetFileName(roifn.c_str()); reader2->UpdateLargestPossibleRegion(); try { ROIimg = reader2->GetOutput(); } catch(...) { ROIimg=NULL; std::cout << " Error reading ROI image " << std::endl; // return 0; } } // now do the recursive average const unsigned int maxChar = 512; char lineBuffer[maxChar]; char filenm[maxChar]; unsigned int filecount1=0; { std::ifstream inputStreamA( fn1.c_str(), std::ios::in ); if ( !inputStreamA.is_open() ) { std::cout << "Can't open parameter file: " << fn1 << std::endl; return -1; } while ( !inputStreamA.eof() ) { inputStreamA.getline( lineBuffer, maxChar, '\n' ); if ( sscanf( lineBuffer, "%s ",filenm) != 1 ) { // std::cout << "Done. read " << lineBuffer << " n " << ct1 << " files " << std::endl; //std::cout << std::endl; continue; } else { filecount1++; } } inputStreamA.close(); } std::cout << " NFiles1 " << filecount1 << std::endl; unsigned int filecount2=0; if ( simimagelist.length() > 2 && ( whichstat == 5 || whichstat == 6 ) ) { std::ifstream inputStreamA( simimagelist.c_str(), std::ios::in ); if ( !inputStreamA.is_open() ) { std::cout << "Can't open parameter file: " << fn1 << std::endl; return -1; } while ( !inputStreamA.eof() ) { inputStreamA.getline( lineBuffer, maxChar, '\n' ); if ( sscanf( lineBuffer, "%s ",filenm) != 1 ) { // std::cout << "Done. read " << lineBuffer << " n " << ct1 << " files " << std::endl; //std::cout << std::endl; continue; } else { filecount2++; } } inputStreamA.close(); if ( filecount1 != filecount2 ) { std::cout << " the number of similarity images does not match the number of label images --- thus, we have to get out of here !! i.e. something's wrong. " << std::endl; return 1; } } // fi simimagelist std::cout << " NFiles2 " << filecount2 << std::endl; typename ImageType::Pointer meanimage; std::vector imagestack; imagestack.resize(filecount1); // imagestack.fill(NULL); std::vector filenames(filecount1); typename ImageType::Pointer StatImage; unsigned int ct = 0; std::ifstream inputStreamA( fn1.c_str(), std::ios::in ); if ( !inputStreamA.is_open() ) { std::cout << "Can't open parameter file: " << fn1 << std::endl; return -1; } while ( !inputStreamA.eof() ) { inputStreamA.getline( lineBuffer, maxChar, '\n' ); if ( sscanf( lineBuffer, "%s ",filenm) != 1 ) { // std::cout << "Done. read " << lineBuffer << " n " << ct1 << " files " << std::endl; //std::cout << std::endl; continue; } else { filenames[ct]=std::string(filenm); ReadImage(imagestack[ct] , filenm ,false); if (ct ==0) meanimage=MakeNewImage(imagestack[ct],0); if (localmeanrad > 0) LocalMean(imagestack[ct],localmeanrad,meanimage); std::cout << " done reading " << (float) ct / (float ) filecount1 << std::endl; ct++; } } inputStreamA.close(); // read similarity images, if needed std::vector simimagestack; simimagestack.resize(filecount2); std::vector simfilenames(filecount2); ct = 0; if ( simimagelist.length() > 2 && ( whichstat == 5 || whichstat == 6 ) ) { std::ifstream inputStreamA( simimagelist.c_str(), std::ios::in ); if ( !inputStreamA.is_open() ) { std::cout << "Can't open parameter file: " << fn1 << std::endl; return -1; } while ( !inputStreamA.eof() ) { inputStreamA.getline( lineBuffer, maxChar, '\n' ); if ( sscanf( lineBuffer, "%s ",filenm) != 1 ) { continue; } else { simfilenames[ct]=std::string(filenm); ReadImage(simimagestack[ct] , filenm ,false); ct++; } } inputStreamA.close(); } // fi read similarity images ReadImage( StatImage , filenames[0].c_str() , false); Iterator vfIter(StatImage , StatImage->GetLargestPossibleRegion() ); std::vector voxels(filecount1); std::vector similarities(filecount2); unsigned long nvox=1; for (unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i]; ct=0; unsigned long prog = nvox/15; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { if (ct % prog == 0) std::cout << " % " << (float) ct / (float) nvox << std::endl; ct++; IndexType ind=vfIter.GetIndex(); unsigned int maxval=0; bool takesample=true; if ( ROIimg ) { if ( ROIimg->GetPixel(ind) < 0.5 ) takesample=false; else maxval=(unsigned int)(ROIimg->GetPixel(ind)-1); } if ( takesample ) { if (mch == 0) meanimage->SetPixel(ind, meanimage->GetPixel(ind)/filecount1 ); for (unsigned int j=0; jGetPixel(ind); } for (unsigned int j=0; jGetPixel(ind); } float stat = 0; switch( whichstat ) { case 1: stat=npdf(voxels,true,www); if (ct == 1) std::cout << "the max prob appearance \n"; break; case 2: stat=npdf(voxels,false,www); if (ct == 1) std::cout << "the probabilistically weighted appearance " << www << " \n"; break; case 3: stat=trimmean(voxels); if (ct == 1) std::cout << "the trimmed mean appearance \n"; break; case 4: stat=myantsmax(voxels); if (ct == 1) std::cout << "the maximum appearance \n"; break; case 5: stat=myantssimilaritymaxlabel(voxels,similarities,true); if (ct == 1) std::cout << "the maximum similarity-based label \n"; break; case 6: stat=myantssimilaritymaxlabel(voxels,similarities,false); if (ct == 1) std::cout << "which image provides the maximum similarity-based label \n"; break; case 7: stat=voxels[maxval]; if (ct == 1) std::cout << "which image provides the maximum similarity-based label \n"; break; default: stat=median(voxels); if (ct == 1) std::cout << "the median appearance \n"; break; } float sval=stat; if ( localmeanrad > 0 ) sval+= meanimage->GetPixel(ind); StatImage->SetPixel(ind, sval); } else StatImage->SetPixel(ind, 0); } WriteImage(StatImage, outfn.c_str() ); std::cout << " Done " << std::endl; return 0; } int main( int argc, char * argv[] ) { if ( argc < 4 ) { std::cout << "Usage: "<< std::endl; std::cout << argv[0] << " ImageDimension controlslist.txt outimage.nii whichstat {roi.nii} {imagelist2forsimilarityweightedstats.txt}" << std::endl; std::cout << " whichstat = 0: median, 1: max prob appearance , 2: weighted mean appearance , 3: trimmed mean , 4 : max value , option 5 : similarity-weighted (must pass imagelist2 as well) else median , option 6 : same as similarity-weighted option 5 but the label corresponds to the image that provides the best local match ... useful if you want to MRF smooth these indices , option 7 : similar to 5 but expects the max-value to be stored in the ROI image and uses it to get the intensity ... " << std::endl; std::cout << " example: ImageSetStatistics 3 imagelist.txt maxvalueimage.nii.gz 4 " << std::endl; std::cout << " similarity weighted --- pass in a list of similarity images here which will be used to select the best label --- thus, number of similarity images must match the number of label images . " << std::endl; return 1; } // Get the image dimension switch ( atoi(argv[1])) { case 2: ImageSetStatistics<2>(argc,argv); break; case 3: ImageSetStatistics<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/KellySlater.cxx000066400000000000000000001236621147325206600212270ustar00rootroot00000000000000//#include "DoSomethingToImage.cxx" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "vnl/algo/vnl_determinant.h" #include "itkWarpImageFilter.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkDeformationFieldFromMultiTransformFilter.h" #include "itkImageFileWriter.h" #include "itkANTSImageRegistrationOptimizer.h" #include "vnl/algo/vnl_determinant.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkBinaryThresholdImageFilter.h" #include "itkCovariantVector.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "ReadWriteImage.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkCentralDifferenceImageFunction.h" #include "itkSurfaceCurvatureBase.h" #include "itkSurfaceImageCurvature.h" template typename TImage::Pointer GetVectorComponent(typename TField::Pointer field, unsigned int index) { // Initialize the Moving to the displacement field typedef TField FieldType; typedef TImage ImageType; typename ImageType::Pointer sfield=ImageType::New(); sfield->SetSpacing( field->GetSpacing() ); sfield->SetOrigin( field->GetOrigin() ); sfield->SetDirection( field->GetDirection() ); sfield->SetLargestPossibleRegion(field->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(field->GetRequestedRegion() ); sfield->SetBufferedRegion( field->GetBufferedRegion() ); sfield->Allocate(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( field, field->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TField::PixelType v1=vfIter.Get(); sfield->SetPixel(vfIter.GetIndex(),v1[index]); } return sfield; } template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType low, typename TImage::PixelType high, typename TImage::PixelType replaceval, typename TImage::Pointer input) { //std::cout << " Binary Thresh " << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } template typename TImage::Pointer MaurerDistanceMap( typename TImage::PixelType pixlo, typename TImage::PixelType pixhi, typename TImage::Pointer input) { //std::cout << " DDMap " << std::endl; typedef TImage ImageType; typedef itk::SignedMaurerDistanceMapImageFilter< ImageType, ImageType > FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetSquaredDistance(false); // filter->InputIsBinaryOn(); filter->SetUseImageSpacing(true); filter->SetBackgroundValue(0); filter->SetInput(BinaryThreshold(pixlo,pixhi,pixhi,input)); filter->Update(); // WriteImage(filter->GetOutput(),"temp1.nii"); return filter->GetOutput(); } template typename TImage::Pointer SmoothImage(typename TImage::Pointer image, float sig) { // find min value typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter(image,image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TImage::PixelType v1=vfIter.Get(); if (vnl_math_isnan(v1)) vfIter.Set(0); } typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); typename TImage::Pointer out= filter->GetOutput(); return out; } template void SmoothDeformation(typename TImage::Pointer vectorimage, float sig) { enum { ImageDimension = TImage::ImageDimension }; typedef itk::Vector VectorType; typedef itk::Image ImageType; typename ImageType::Pointer subimgx=GetVectorComponent(vectorimage,0); subimgx=SmoothImage(subimgx,sig); typename ImageType::Pointer subimgy=GetVectorComponent(vectorimage,1); subimgy=SmoothImage(subimgy,sig); typename ImageType::Pointer subimgz=GetVectorComponent(vectorimage,2); subimgz=SmoothImage(subimgz,sig); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( vectorimage, vectorimage->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { VectorType vec; vec[0]=subimgx->GetPixel(Iterator.GetIndex()); vec[1]=subimgy->GetPixel(Iterator.GetIndex()); vec[2]=subimgz->GetPixel(Iterator.GetIndex()); Iterator.Set(vec); ++Iterator; } return; } template typename TImage::Pointer ComputeJacobian(TDeformationField* field ) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; // unsigned int row=0; //unsigned int col=0; typedef itk::Image FloatImageType; typename FloatImageType::RegionType m_JacobianRegion; typename TImage::SizeType s= field->GetLargestPossibleRegion().GetSize(); typename TImage::SpacingType sp= field->GetSpacing(); typename FloatImageType::Pointer m_FloatImage=NULL; m_FloatImage = FloatImageType::New(); m_FloatImage->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); m_FloatImage->SetBufferedRegion( field->GetLargestPossibleRegion().GetSize() ); m_FloatImage->SetSpacing(field->GetSpacing()); m_FloatImage->SetDirection( field->GetDirection() ); m_FloatImage->SetOrigin(field->GetOrigin()); m_FloatImage->Allocate(); m_FloatImage->FillBuffer(0); typename FloatImageType::SizeType m_FieldSize = field->GetLargestPossibleRegion().GetSize(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator wimIter( m_FloatImage, m_FloatImage->GetLargestPossibleRegion() ); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) wimIter.Set(1.0); typedef vnl_matrix MatrixType; MatrixType jMatrix,idMatrix,avgMatrix; jMatrix.set_size(ImageDimension,ImageDimension); avgMatrix.set_size(ImageDimension,ImageDimension); avgMatrix.fill(0); itk::ImageRegionIteratorWithIndex m_FieldIter( field, field->GetLargestPossibleRegion() ); typename TImage::IndexType rindex; typename TImage::IndexType ddrindex; typename TImage::IndexType ddlindex; typename TImage::IndexType difIndex[ImageDimension][2]; double det=0.0; unsigned int posoff=1; float difspace=1.0; float space=1.0; if (posoff == 0) difspace=1.0; typedef itk::Vector VectorType; typedef itk::Image FieldType; typename FieldType::PixelType dPix; typename FieldType::PixelType lpix; typename FieldType::PixelType llpix; typename FieldType::PixelType rpix; typename FieldType::PixelType rrpix; typename FieldType::PixelType cpix; float volumeelt=1.0; for (int j=0;jGetPixel(rindex); for(unsigned int row=0; row< ImageDimension;row++) { difIndex[row][0]=rindex; difIndex[row][1]=rindex; ddrindex=rindex; ddlindex=rindex; if ((int) rindex[row] < (int)(m_FieldSize[row]-2) ) { difIndex[row][0][row]=rindex[row]+posoff; ddrindex[row]=rindex[row]+posoff*2; } if (rindex[row] > 1 ) { difIndex[row][1][row]=rindex[row]-1; ddlindex[row]=rindex[row]-2; } float h=0.5; space=1.0; // should use image spacing here? rpix = field->GetPixel(difIndex[row][1]); rpix = rpix*h+cpix*(1.-h); lpix = field->GetPixel(difIndex[row][0]); lpix = lpix*h+cpix*(1.-h); // dPix = ( rpix - lpix)*(1.0)/(2.0); rrpix = field->GetPixel(ddrindex); rrpix = rrpix*h+rpix*(1.-h); llpix = field->GetPixel(ddlindex); llpix = llpix*h+lpix*(1.-h); dPix=( lpix*(-8.0) + rpix*8.0 - rrpix + llpix )*(-1.0)*space/(12.0); //4th order centered difference //dPix=( lpix - rpix )*(1.0)*space/(2.0*h); //4th order centered difference for(unsigned int col=0; col< ImageDimension;col++){ float val; if (row == col) val=dPix[col]/sp[col]+1.0; else val = dPix[col]/sp[col]; // std::cout << " row " << row << " col " << col << " val " << val << std::endl; jMatrix.put(col,row,val); avgMatrix.put(col,row,avgMatrix.get(col,row)+val); } } //the determinant of the jacobian matrix // std::cout << " get det " << std::endl; det = vnl_determinant(jMatrix); // float prodval = m_FloatImage->GetPixel(rindex); if (det < 0.0) det = 0; m_FloatImage->SetPixel(rindex, det ); //totaljac+=det; }//oktosample if } return m_FloatImage; } template typename TImage::Pointer LabelSurface(typename TImage::PixelType foreground, typename TImage::PixelType newval, typename TImage::Pointer input, float distthresh ) { std::cout << " Label Surf " << std::endl; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typename ImageType::Pointer Image = ImageType::New(); Image->SetLargestPossibleRegion(input->GetLargestPossibleRegion() ); Image->SetBufferedRegion(input->GetLargestPossibleRegion()); Image->Allocate(); Image->SetSpacing(input->GetSpacing()); Image->SetOrigin(input->GetOrigin()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); // std::cout << " foreg " << (int) foreground; while (!GHood.IsAtEnd()) { typename TImage::PixelType p = GHood.GetCenterPixel(); typename TImage::IndexType ind = GHood.GetIndex(); typename TImage::IndexType ind2; if ( p == foreground ) { bool atedge=false; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0.0; for (int j=0; jSetPixel(ind,newval); else Image->SetPixel(ind,0); } ++GHood; } return Image; } template typename TImage::Pointer SpeedPrior(typename TImage::Pointer image1 , typename TImage::Pointer wmimage, typename TImage::Pointer surf ) { typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::SurfaceImageCurvature ParamType; typename ParamType::Pointer Parameterizer=ParamType::New(); float sig=1.5; Parameterizer->SetInput(wmimage); Parameterizer->SetNeighborhoodRadius( 1. ); Parameterizer->SetSigma(sig); Parameterizer->SetUseLabel(false); Parameterizer->SetUseGeodesicNeighborhood(false); float sign=1.0; Parameterizer->SetkSign(sign); Parameterizer->SetThreshold(0); Parameterizer->ComputeFrameOverDomain( 3 ); typename ImageType::Pointer outimage=Parameterizer->GetFunctionImage(); float max=0; float min=1.e9; float mean = 0.0; unsigned long ct = 0; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator iter( outimage, outimage->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { float pix=iter.Get(); mean+=pix; ct++; if (pix > max ) max=pix; if (pix < min) min=pix; } mean/=(float)ct; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { float pix=iter.Get(); pix= (pix - min)/(max-min); iter.Set(pix); } return outimage; } template typename TImage::Pointer Morphological( typename TImage::Pointer input,float rad, bool option) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::PixelType PixelType; if (!option) std::cout << " eroding the image " << std::endl; else std::cout << " dilating the image " << std::endl; typedef itk::BinaryBallStructuringElement< PixelType, ImageDimension > StructuringElementType; // Software Guide : BeginCodeSnippet typedef itk::BinaryErodeImageFilter< TImage, TImage, StructuringElementType > ErodeFilterType; typedef itk::BinaryDilateImageFilter< TImage, TImage, StructuringElementType > DilateFilterType; typename ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius((unsigned long) rad ); // 3x3x3 structuring element structuringElement.CreateStructuringElement(); binaryErode->SetKernel( structuringElement ); binaryDilate->SetKernel( structuringElement ); // It is necessary to define what could be considered objects on the binary // images. This is specified with the methods \code{SetErodeValue()} and // \code{SetDilateValue()}. The value passed to these methods will be // considered the value over which the dilation and erosion rules will apply binaryErode->SetErodeValue( 1 ); binaryDilate->SetDilateValue( 1 ); typename TImage::Pointer temp; if (option) { binaryDilate->SetInput( input ); binaryDilate->Update(); temp = binaryDilate->GetOutput(); } else { binaryErode->SetInput( input );//binaryDilate->GetOutput() ); binaryErode->Update(); temp = binaryErode->GetOutput(); typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; ImageIteratorType o_iter( temp, temp->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { if (o_iter.Get() > 0.5 && input->GetPixel(o_iter.GetIndex()) > 0.5) o_iter.Set(1); else o_iter.Set(0); ++o_iter; } } return temp; } template typename TField::Pointer LaplacianGrad(typename TImage::Pointer wm,typename TImage::Pointer gm, float sig) { typedef typename TImage::IndexType IndexType; IndexType ind; typedef TImage ImageType; typedef TField GradientImageType; typedef itk::GradientRecursiveGaussianImageFilter< ImageType,GradientImageType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; typename TField::Pointer sfield=TField::New(); sfield->SetSpacing( wm->GetSpacing() ); sfield->SetOrigin( wm->GetOrigin() ); sfield->SetDirection( wm->GetDirection() ); sfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(wm->GetRequestedRegion() ); sfield->SetBufferedRegion( wm->GetBufferedRegion() ); sfield->Allocate(); typename TImage::Pointer laplacian=SmoothImage(wm,3); laplacian->FillBuffer(0); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( wm, wm->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); //initialize L(wm)=1, L(gm)=0.5, else 0 while( !Iterator.IsAtEnd() ) { ind=Iterator.GetIndex(); if (wm->GetPixel(ind) ) laplacian->SetPixel(ind,1); else if (gm->GetPixel(ind) && wm->GetPixel(ind) == 0 ) laplacian->SetPixel(ind,0.); else laplacian->SetPixel(ind,0.); ++Iterator; } //smooth and then reset the values for(unsigned int iterations=0; iterations<100; iterations++) { laplacian=SmoothImage(laplacian,sqrt(sig)); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { ind=Iterator.GetIndex(); if (wm->GetPixel(ind) ) laplacian->SetPixel(ind,1); else if (gm->GetPixel(ind) ==0 && wm->GetPixel(ind) == 0 ) laplacian->SetPixel(ind,0.); ++Iterator; } } GradientImageFilterPointer filter=GradientImageFilterType::New(); filter->SetInput( laplacian ); filter->SetSigma(sig); filter->Update(); return filter->GetOutput(); } template typename TField::Pointer ExpDiffMap(typename TField::Pointer velofield, typename TImage::Pointer wm, float sign, unsigned int numtimepoints ) { typedef TImage ImageType; typedef TField DeformationFieldType; typename TField::PixelType zero,disp; enum { ImageDimension = TImage::ImageDimension }; disp.Fill(0); zero.Fill(0); typename DeformationFieldType::Pointer incrfield=DeformationFieldType::New(); incrfield->SetSpacing( velofield->GetSpacing() ); incrfield->SetOrigin( velofield->GetOrigin() ); incrfield->SetDirection( velofield->GetDirection() ); incrfield->SetLargestPossibleRegion(velofield->GetLargestPossibleRegion() ); incrfield->SetRequestedRegion(velofield->GetRequestedRegion() ); incrfield->SetBufferedRegion( velofield->GetBufferedRegion() ); incrfield->Allocate(); incrfield->FillBuffer(zero); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( wm, wm->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { incrfield->SetPixel(Iterator.GetIndex(),velofield->GetPixel(Iterator.GetIndex())*sign); ++Iterator; } // generate phi typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef itk::DeformationFieldFromMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetOutputSize(velofield->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(velofield->GetSpacing()); warper->SetOutputOrigin(velofield->GetOrigin()); warper->SetOutputDirection(velofield->GetDirection()); warper->DetermineFirstDeformNoInterp(); unsigned int ttiter=0; while( ttiter < numtimepoints ) // 10 time integration points { ttiter++; warper->PushBackDeformationFieldTransform(incrfield); } warper->Update(); return warper->GetOutput(); } template typename TField::Pointer DiReCTCompose(typename TField::Pointer velofield, typename TField::Pointer diffmap ) { typedef TImage ImageType; typedef TField DeformationFieldType; typename TField::PixelType zero,disp; enum { ImageDimension = TImage::ImageDimension }; disp.Fill(0); zero.Fill(0); typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef itk::DeformationFieldFromMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetOutputSize(velofield->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(velofield->GetSpacing()); warper->SetOutputOrigin(velofield->GetOrigin()); warper->SetOutputDirection(velofield->GetDirection()); warper->DetermineFirstDeformNoInterp(); warper->PushBackDeformationFieldTransform(diffmap); warper->PushBackDeformationFieldTransform(velofield); warper->Update(); return warper->GetOutput(); } template int LaplacianThicknessExpDiff2(int argc, char *argv[]) { int argct=2; std::string segfn = std::string(argv[argct]); argct++; std::string wfn = std::string(argv[argct]); argct++; std::string gfn = std::string(argv[argct]); argct++; std::string outname = std::string(argv[argct]); argct++; unsigned int numtimepoints=10; float gradstep=(float)(-1.0)*0.5;//(ImageDimension-1); if (argc > argct) gradstep=atof(argv[argct])*(-1.0); gradstep*=1.0/(float)numtimepoints*10; argct++; unsigned int alltheits=50; if (argc > argct) alltheits=atoi(argv[argct]); argct++; float thickprior=6.0; if (argc > argct ) thickprior=atof(argv[argct]); argct++; bool useCurvaturePrior=false; if (argc > argct) useCurvaturePrior=atoi(argv[argct]); argct++; float smoothingsigma=1.5; if (argc > argct ) smoothingsigma=atof(argv[argct]); argct++; bool useEuclidean=true; if (argc > argct) useEuclidean=atoi(argv[argct]); argct++; std::cout <<" smooth " << smoothingsigma << " thp " << thickprior << " gs " << gradstep << std::endl; typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::Image tvt; typedef itk::ANTSImageRegistrationOptimizer ROType; typename ROType::Pointer m_MFR=ROType::New(); typename ImageType::Pointer segmentationimage; ReadImage(segmentationimage,segfn.c_str()); typename ImageType::Pointer wm; ReadImage(wm,wfn.c_str()); typename ImageType::DirectionType omat=wm->GetDirection(); typename ImageType::DirectionType fmat=wm->GetDirection(); fmat.SetIdentity(); std::cout <<" Setting Identity Direction " << fmat << std::endl; wm->SetDirection(fmat); typename ImageType::Pointer totalimage; ReadImage(totalimage,wfn.c_str()); totalimage->SetDirection(fmat); typename ImageType::Pointer hitimage; ReadImage(hitimage,wfn.c_str()); hitimage->SetDirection(fmat); typename ImageType::Pointer gm; ReadImage(gm,gfn.c_str()); gm->SetDirection(fmat); wm->SetDirection(fmat); segmentationimage->SetDirection(fmat); SpacingType spacing=wm->GetSpacing(); typename DeformationFieldType::Pointer lapgrad; typename ImageType::Pointer gmb=BinaryThreshold(2,2,1,segmentationimage); // fixme typename ImageType::Pointer wmb=BinaryThreshold(3,3,1,segmentationimage); // fixme typename ImageType::Pointer laplacian= SmoothImage(wm,smoothingsigma); lapgrad=LaplacianGrad(wmb,gmb,1); typename DeformationFieldType::Pointer corrfield=DeformationFieldType::New(); corrfield->SetSpacing( wm->GetSpacing() ); corrfield->SetOrigin( wm->GetOrigin() ); corrfield->SetDirection( wm->GetDirection() ); corrfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); corrfield->SetRequestedRegion(wm->GetRequestedRegion() ); corrfield->SetBufferedRegion( wm->GetBufferedRegion() ); corrfield->Allocate(); VectorType zero; zero.Fill(0); corrfield->FillBuffer(zero); typename DeformationFieldType::Pointer incrfield=DeformationFieldType::New(); incrfield->SetSpacing( wm->GetSpacing() ); incrfield->SetOrigin( wm->GetOrigin() ); incrfield->SetDirection( wm->GetDirection() ); incrfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); incrfield->SetRequestedRegion(wm->GetRequestedRegion() ); incrfield->SetBufferedRegion( wm->GetBufferedRegion() ); incrfield->Allocate(); incrfield->FillBuffer(zero); typename DeformationFieldType::Pointer invfield=DeformationFieldType::New(); invfield->SetSpacing( wm->GetSpacing() ); invfield->SetOrigin( wm->GetOrigin() ); invfield->SetDirection( wm->GetDirection() ); invfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); invfield->SetRequestedRegion(wm->GetRequestedRegion() ); invfield->SetBufferedRegion( wm->GetBufferedRegion() ); invfield->Allocate(); invfield->FillBuffer(zero); typename DeformationFieldType::Pointer incrinvfield=DeformationFieldType::New(); incrinvfield->SetSpacing( wm->GetSpacing() ); incrinvfield->SetOrigin( wm->GetOrigin() ); incrinvfield->SetDirection( wm->GetDirection() ); incrinvfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); incrinvfield->SetRequestedRegion(wm->GetRequestedRegion() ); incrinvfield->SetBufferedRegion( wm->GetBufferedRegion() ); incrinvfield->Allocate(); incrinvfield->FillBuffer(zero); typename DeformationFieldType::Pointer velofield=DeformationFieldType::New(); velofield->SetSpacing( wm->GetSpacing() ); velofield->SetOrigin( wm->GetOrigin() ); velofield->SetDirection( wm->GetDirection() ); velofield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); velofield->SetRequestedRegion(wm->GetRequestedRegion() ); velofield->SetBufferedRegion( wm->GetBufferedRegion() ); velofield->Allocate(); velofield->FillBuffer(zero); // LabelSurface(typename TImage::PixelType foreground, // typename TImage::PixelType newval, typename TImage::Pointer input, float distthresh ) float distthresh = 1.1; typename ImageType::Pointer wmgrow = Morphological(wmb,1,true); typename ImageType::Pointer bsurf = LabelSurface(1,1,wmgrow , distthresh); // or wmb ? typename ImageType::Pointer speedprior=NULL; if ( useCurvaturePrior ) speedprior=SpeedPrior(gm,wm,bsurf); //WriteImage(bsurf,"surf.hdr"); // typename DoubleImageType::Pointer distfromboundary = // typename ImageType::Pointer surf=MaurerDistanceMap(0.5,1.e9,bsurf); //surf= SmoothImage(surf,3); typename ImageType::Pointer finalthickimage=BinaryThreshold(3,3,1,segmentationimage); // fixme //typename ImageType::Pointer gmsurf = LabelSurface(1,1,gmb, distthresh); // gmsurf=MaurerDistanceMap(0.5,1.e9,gmsurf); // gmsurf= SmoothImage(gmsurf,3); typename ImageType::SizeType s= wm->GetLargestPossibleRegion().GetSize(); typename DeformationFieldType::IndexType velind; velind.Fill(0); typedef DeformationFieldType TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType2; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); vinterp->SetInputImage(lapgrad); typedef itk::LinearInterpolateImageFunction ScalarInterpolatorType; typename ScalarInterpolatorType::Pointer ginterp = ScalarInterpolatorType::New(); typename ScalarInterpolatorType::Pointer winterp = ScalarInterpolatorType::New(); winterp->SetInputImage(wm); ginterp->SetInputImage(gm); DPointType pointIn1; DPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType vcontind; DPointType pointIn3; typename ImageType::Pointer surfdef; typedef itk::ImageRegionIteratorWithIndex IteratorType; typedef itk::ImageRegionIteratorWithIndex VIteratorType; VIteratorType VIterator( lapgrad, lapgrad->GetLargestPossibleRegion().GetSize() ); VIterator.GoToBegin(); while( !VIterator.IsAtEnd() ) { VectorType vec=VIterator.Get(); float mag=0; for (unsigned dd=0; dd 0) vec=vec/mag; VIterator.Set( (vec)*gradstep); ++VIterator; } // m_MFR->SmoothDeformationFieldGauss(lapgrad,1.7); std::cout << " Scaling done " << std::endl; // float thislength=0; unsigned long ct = 1; bool timedone = false; typename ImageType::Pointer thickimage=laplacian; VectorType disp; VectorType incdisp; disp.Fill(0.0); incdisp.Fill(0.0); IteratorType Iterator( wm, wm->GetLargestPossibleRegion().GetSize() ); timedone=false; float totalerr=1.e8, lasterr=1.e10; unsigned its=0; wmgrow->FillBuffer(0); float dmag=0; float thicknesserror=0; unsigned long thickerrct=0; unsigned int badct=0; float thickoffset=0; bool checknans=true; while ( its < alltheits && badct < 4) { its++; if (totalerr > lasterr) { badct++; std::cout << " badct " << badct << std::endl; } else badct=0; lasterr=totalerr; // Optimization Error initialized for this iteration totalerr=0; ct=0; incrfield->FillBuffer(zero); incrfield->FillBuffer(zero); incrinvfield->FillBuffer(zero); // generate phi corrfield->FillBuffer(zero); invfield->FillBuffer(zero); unsigned int ttiter=0; thickimage->FillBuffer(0); hitimage->FillBuffer(0); totalimage->FillBuffer(0); thicknesserror=0; thickerrct=1; bool debug=false; bool spatprior=false; typename ImageType::Pointer priorim=NULL; if (speedprior){ spatprior=true; priorim=speedprior; } typename ImageType::Pointer wpriorim=NULL; float origthickprior=thickprior; while( ttiter < numtimepoints ) // N time integration points { // m_MFR->Compose(incrinvfield,invfield,NULL); m_MFR->ComposeDiffs(invfield,incrinvfield,invfield,1); if (debug) std::cout <<" exp " << std::endl; // Integrate the negative velocity field to generate diffeomorphism corrfield step 3(a) // ExpDiffMap( velofield, corrfield, wm, -1, numtimepoints-ttiter); corrfield=ExpDiffMap( velofield, wm, -1, numtimepoints-ttiter); // why integrate velofield, but only compose incrinvfield ??? // technically, we should warp the gm image by corrfield but this can be avoided if (debug) std::cout <<" gmdef " << std::endl; typename ImageType::Pointer gmdef =m_MFR->WarpImageBackward(gm,corrfield); totalerr=0; typename ImageType::Pointer surfdef=m_MFR->WarpImageBackward(wm,invfield); if (debug) std::cout <<" thkdef " << std::endl; typename ImageType::Pointer thkdef =m_MFR->WarpImageBackward(thickimage,invfield); if (debug) std::cout <<" thindef " << std::endl; typename ImageType::Pointer thindef =m_MFR->WarpImageBackward(bsurf,invfield); if (spatprior) wpriorim=m_MFR->WarpImageBackward(priorim,invfield); typedef DeformationFieldType GradientImageType; typedef itk::GradientRecursiveGaussianImageFilter< ImageType,GradientImageType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; GradientImageFilterPointer gfilter=GradientImageFilterType::New(); gfilter->SetInput( surfdef ); gfilter->SetSigma( smoothingsigma ); gfilter->Update(); typename DeformationFieldType::Pointer lapgrad2=gfilter->GetOutput(); GradientImageFilterPointer gfilter2=GradientImageFilterType::New(); gfilter2->SetInput( gm ); gfilter2->SetSigma( smoothingsigma ); gfilter2->Update(); typename DeformationFieldType::Pointer lapgrad3=gfilter2->GetOutput(); typename ImageType::Pointer lapjac=ComputeJacobian(invfield); IteratorType xxIterator( lapjac, lapjac->GetLargestPossibleRegion().GetSize() ); xxIterator.GoToBegin(); float maxlapgrad2mag=0; while( !xxIterator.IsAtEnd() ) { typename ImageType::IndexType speedindex=xxIterator.GetIndex(); if ( segmentationimage->GetPixel(speedindex) == 2 ) // fixme { // float thkval=thkdef->GetPixel(speedindex); float thkval=finalthickimage->GetPixel(speedindex); float prior=1; if (spatprior){ float prval=wpriorim->GetPixel(speedindex); float partialvol=surfdef->GetPixel(speedindex) ; if ( partialvol >= 0.1 ) prior=prval/partialvol;//7;//0.5*origthickprior;// prval; if (prior > 10 ) prior=10; /** Potential cause of problem 1 -- this line added */ } //else thickprior = origthickprior; //} else thickprior=origthickprior; VectorType wgradval=lapgrad2->GetPixel(speedindex);//velofield->GetPixel(speedindex);// // VectorType ggradval=lapgrad3->GetPixel(speedindex); double dp=0; double gmag=0,wmag=0; for (unsigned kq=0;kqSetPixel(speedindex,wgradval); wmag=0; } // if (gmag > 0 && wmag > 0) // { // for (unsigned kq=0;kqSetPixel(speedindex,dp); double fval=(thickprior-thkval); double sigmoidf=1; // double sigmoidf=1.0- thkval/thickprior; if (fval >=0) sigmoidf=1.0/(1.0+exp((-1.0)*fval*0.01)); if (fval < 0) sigmoidf=-1.0*(1.0-thickprior/thkval); // else sigmoidf=1.0- thkval/thickprior; float thkscale=thickprior/thkval; if (thkscale < 0.99) thkscale=0.99;//*+thkscale*0.1; if (fval < 0 ) velofield->SetPixel(speedindex,velofield->GetPixel(speedindex)*thkscale); float dd=surfdef->GetPixel(speedindex) - gmdef->GetPixel(speedindex); // float gmd=gmdef->GetPixel(speedindex); totalerr+=fabs(dd); if ( segmentationimage->GetPixel(speedindex) != 2 /* && bsurf->GetPixel(speedindex) < 0.5 */ ) dd=0; // fixme float stopval=gm->GetPixel(speedindex); // if (wm->GetPixel(speedindex) > stopval) stopval=1; float jwt=xxIterator.Get(); if (jwt < 1) jwt=1; else jwt=1.0/xxIterator.Get(); // dd*=stopval*jwt*thindef->GetPixel(speedindex)*sigmoidf*gradstep*dp*gmd*jwt; dd*=stopval*sigmoidf*gradstep*jwt*prior;// speed function here IMPORTANT!! if (checknans) if ( vnl_math_isnan(dd) || vnl_math_isinf(dd) ) dd=0; if ( wmag*dd > 1 ) dd=stopval*(surfdef->GetPixel(speedindex) - gmdef->GetPixel(speedindex))*gradstep; lapjac->SetPixel(speedindex, dd); // std::cout <<" dd " << dd << " prior " << prior << " wmag " << wmag << std::endl; if ( wmag*dd > maxlapgrad2mag ) maxlapgrad2mag=wmag*dd; } else lapjac->SetPixel(speedindex, 0); ++xxIterator; } if ( maxlapgrad2mag < 1.e-4) maxlapgrad2mag=1.e9; lapjac=SmoothImage(lapjac,1); // if (ImageDimension==2) WriteJpg(surfdef,"surfdef.jpg"); //if (ImageDimension==2) WriteJpg(thindef,"thindef.jpg"); //if (ImageDimension==2) WriteJpg(gmdef,"gmdef.jpg"); //if (ImageDimension==2) WriteJpg(lapjac,"diff.jpg"); //if (ImageDimension==2) WriteJpg(wpriorim,"prior.jpg"); //if (ImageDimension==2) WriteJpg(thkdef,"thick2.jpg"); // if (ImageDimension==2) WriteJpg(tempim,"dotp.jpg"); //exit(0); /* Now that we have the gradient image, we need to visit each voxel and compute objective function */ // std::cout << " maxlapgrad2mag " << maxlapgrad2mag << std::endl; Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { velind=Iterator.GetIndex(); // float currentthickvalue=finalthickimage->GetPixel(velind); VectorType wgradval=lapgrad2->GetPixel(velind); //*5.0/(maxlapgrad2mag*(float)numtimepoints); disp=wgradval*lapjac->GetPixel(velind); incrfield->SetPixel(velind,incrfield->GetPixel(velind)+disp); if (ttiter == 0)// make euclidean distance image { dmag=0; disp=corrfield->GetPixel(velind); for (unsigned int jj=0; jjGetPixel(velind); if (checknans) { if ( vnl_math_isnan(dmag) || vnl_math_isinf(dmag) ) dmag=0; if ( vnl_math_isnan(bval) || vnl_math_isinf(bval) ) bval=0; } /** Change 2-26-2010 = incoporate gm prob in length ... */ dmag=sqrt(dmag)*bval*gm->GetPixel(velind); thickimage->SetPixel(velind,dmag); totalimage->SetPixel(velind,dmag); hitimage->SetPixel(velind,bval); } else if ( segmentationimage->GetPixel(velind) == 2 ) // fixme { float thkval=thkdef->GetPixel(velind); float putval=thindef->GetPixel(velind); // float getval=hitimage->GetPixel(velind); hitimage->SetPixel(velind,hitimage->GetPixel(velind)+putval); totalimage->SetPixel(velind,totalimage->GetPixel(velind)+thkval); } // std::cout << "disp " << incrfield->GetPixel(velind) << " hit " << hitimage->GetPixel(velind) << " thk " << totalimage->GetPixel(velind) << std::endl; ++Iterator; } // if (ttiter ==0) { //WriteImage(totalimage,"Ztotalimage.nii.gz"); //WriteImage(hitimage,"Zhitimage.nii.gz"); //WriteImage(lapjac,"Zlapjac.nii.gz"); } Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { incrinvfield->SetPixel(Iterator.GetIndex(),velofield->GetPixel(Iterator.GetIndex())); ++Iterator; } ttiter++; } Iterator.GoToBegin(); float maxth=0; while( !Iterator.IsAtEnd() ) { velind=Iterator.GetIndex(); // increment velocity field at every voxel v = v + u, step 4 velofield->SetPixel(Iterator.GetIndex(),velofield->GetPixel(Iterator.GetIndex()) + incrfield->GetPixel(Iterator.GetIndex()) ); float hitval=hitimage->GetPixel(velind); float thkval=0; if ( hitval >= 0.001 ) /** potential source of problem 2 -- this value could be smaller ... */ thkval=totalimage->GetPixel(velind)/hitval - thickoffset; if (thkval < 0) thkval=0; finalthickimage->SetPixel(velind ,thkval); if (thkval > maxth) maxth=thkval; ++Iterator; } if (debug) std::cout << " now smooth " << std::endl; m_MFR->SmoothDeformationFieldGauss(velofield,smoothingsigma); // std::string velofieldname = outname + "velofield"; //WriteDisplacementField(velofield,velofieldname.c_str()); //std::string incrfieldname = outname + "incrfield"; //WriteDisplacementField(incrfield,incrfieldname.c_str()); //std::string tname = outname + "dork1.nii.gz"; //WriteImage(hitimage,tname.c_str()); //tname = outname + "dork2.nii.gz"; //WriteImage(totalimage,tname.c_str()); if (thickerrct == 0) thickerrct=1; std::cout << " error " << totalerr << " at it " << its << " th-err " << thicknesserror/(float)thickerrct << " max thick " << maxth << std::endl; // std::string sulcthickname =outname + "sulcthick.nii"; // if (ImageDimension==2) WriteJpg(finalthickimage,"thick.jpg"); // std::string velofieldname = outname + "velofield"; //WriteDisplacementField(velofield,velofieldname.c_str()); if (debug)std::cout << "outside it " << its << std::endl; //std::cin.get(); } finalthickimage->SetDirection(omat); WriteImage(finalthickimage,outname.c_str()); finalthickimage->SetDirection(fmat); return 0; thickimage->FillBuffer(0); typename ImageType::Pointer thkdef =m_MFR->WarpImageBackward(finalthickimage,invfield); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { float tt1=finalthickimage->GetPixel(Iterator.GetIndex()); float tt=thkdef->GetPixel(Iterator.GetIndex()); if (tt1 > tt) tt=tt1; thickimage->SetPixel(Iterator.GetIndex(),tt); ++Iterator; } std::string thickname = outname; thickimage->SetDirection(omat); WriteImage(thickimage,thickname.c_str()); return 0; } int main(int argc, char *argv[]) { if ( argc < 6) { std::cout << "Usage: " << argv[0] << " ImageDimension Segmentation.nii.gz WMProb.nii.gz GMProb.nii.gz Out.nii {GradStep-1-2D,2-3D} {#Its-~50} {ThickPriorValue-6} {Bool-use-curvature-prior} {smoothing} {BoolUseEuclidean?}" << std::endl; std::cout << " this is a kind of binary image registration thing with diffeomorphisms " << std::endl; std::cout << " Segmentation.nii.gz -- should contain the value 3 where WM exists and the value 2 where GM exists " << std::endl; return 1; } unsigned int dim = atoi(argv[1]); std::cout << " dim " << dim << std::endl; switch ( dim ) { case 2: LaplacianThicknessExpDiff2<2>(argc,argv); break; case 3: LaplacianThicknessExpDiff2<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return EXIT_SUCCESS; return 1; } ants-1.9.2+svn680.dfsg/Examples/LabelClustersUniquely.cxx000066400000000000000000000106431147325206600232660ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: LabelClustersUniquely.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkDiscreteGaussianImageFilter.h" // RecursiveAverageImages img1 img2 weightonimg2 outputname // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. #include #include #include #include "vnl/vnl_vector.h" #include "itkMinimumMaximumImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkRelabelComponentImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkLabelStatisticsImageFilter.h" #include "itkCastImageFilter.h" #include "ReadWriteImage.h" template int LabelUniquely(int argc, char *argv[]) { typedef float PixelType; // const unsigned int ImageDimension = AvantsImageDimension; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; // typedef itk::ImageRegionIteratorWithIndex Iterator; typedef float InternalPixelType; typedef int ULPixelType; typedef itk::Image labelimagetype; typedef itk::CastImageFilter CastFilterType; typedef ImageType InternalImageType; typedef ImageType OutputImageType; typedef itk::ConnectedComponentImageFilter< labelimagetype, labelimagetype > FilterType; typedef itk::RelabelComponentImageFilter< labelimagetype, labelimagetype > RelabelType; // want the average value in each cluster as defined by the mask and the value thresh and the clust thresh std::string fn1 = std::string(argv[1]); std::string fn2 = std::string(argv[2]); float clusterthresh = atof(argv[3]); typename ImageType::Pointer image1 = NULL; ReadImage(image1,fn1.c_str()); // typename typename FilterType::Pointer filter = FilterType::New(); //typename typename RelabelType::Pointer relabel = RelabelType::New(); typename CastFilterType::Pointer castInput = CastFilterType::New(); castInput->SetInput(image1); filter->SetInput( castInput->GetOutput() ); int fullyConnected = 0;//atoi( argv[5] ); filter->SetFullyConnected( fullyConnected ); relabel->SetInput( filter->GetOutput() ); relabel->SetMinimumObjectSize( (unsigned int) clusterthresh ); try { relabel->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Relabel: exception caught !" << std::endl; std::cerr << excep << std::endl; } // float maximum=relabel->GetNumberOfObjects(); WriteImage( relabel->GetOutput() , argv[2]); return 0; } int main(int argc, char *argv[]) { if ( argc < 3) { std::cout << "Usage: "<< std::endl; std::cout << argv[0] << " ImageDimension clustersin.hdr labeledclustersout.hdr sizethresh " << std::endl; return 1; } switch ( atoi(argv[1])) { case 2: LabelUniquely<2>(argc,argv+1); break; case 3: LabelUniquely<3>(argc,argv+1); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/LabelOverlapMeasures.cxx000066400000000000000000000161151147325206600230430ustar00rootroot00000000000000#include "itkBinaryThresholdImageFilter.h" #include "itkHausdorffDistanceImageFilter.h" #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkLabelOverlapMeasuresImageFilter.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include #include template int LabelOverlapMeasures( int argc, char * argv[] ) { typedef unsigned int PixelType; typedef itk::Image ImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader1 = ReaderType::New(); reader1->SetFileName( argv[2] ); typename ReaderType::Pointer reader2 = ReaderType::New(); reader2->SetFileName( argv[3] ); typedef itk::LabelOverlapMeasuresImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetSourceImage( reader1->GetOutput() ); filter->SetTargetImage( reader2->GetOutput() ); filter->Update(); std::cout << " " << "************ All Labels *************" << std::endl; std::cout << std::setw( 10 ) << " " << std::setw( 17 ) << "Total" << std::setw( 17 ) << "Union (jaccard)" << std::setw( 17 ) << "Mean (dice)" << std::setw( 17 ) << "Volume sim." << std::setw( 17 ) << "False negative" << std::setw( 17 ) << "False positive" << std::endl; std::cout << std::setw( 10 ) << " "; std::cout << std::setw( 17 ) << filter->GetTotalOverlap(); std::cout << std::setw( 17 ) << filter->GetUnionOverlap(); std::cout << std::setw( 17 ) << filter->GetMeanOverlap(); std::cout << std::setw( 17 ) << filter->GetVolumeSimilarity(); std::cout << std::setw( 17 ) << filter->GetFalseNegativeError(); std::cout << std::setw( 17 ) << filter->GetFalsePositiveError(); std::cout << std::endl; std::cout << " " << "************ Individual Labels *************" << std::endl; std::cout << std::setw( 10 ) << "Label" << std::setw( 17 ) << "Target" << std::setw( 17 ) << "Union (jaccard)" << std::setw( 17 ) << "Mean (dice)" << std::setw( 17 ) << "Volume sim." << std::setw( 17 ) << "False negative" << std::setw( 17 ) << "False positive" << std::setw( 17 ) << "Hausdorff" << std::setw( 17 ) << "Avg. Hausdorff" << std::setw( 17 ) << "Min. dist. sum" << std::endl; typename FilterType::MapType labelMap = filter->GetLabelSetMeasures(); typename FilterType::MapType::const_iterator it; for( it = labelMap.begin(); it != labelMap.end(); ++it ) { if( (*it).first == 0 ) { continue; } int label = (*it).first; std::cout << std::setw( 10 ) << label; std::cout << std::setw( 17 ) << filter->GetTargetOverlap( label ); std::cout << std::setw( 17 ) << filter->GetUnionOverlap( label ); std::cout << std::setw( 17 ) << filter->GetMeanOverlap( label ); std::cout << std::setw( 17 ) << filter->GetVolumeSimilarity( label ); std::cout << std::setw( 17 ) << filter->GetFalseNegativeError( label ); std::cout << std::setw( 17 ) << filter->GetFalsePositiveError( label ); /** * Calculate distance-related measures which, perhaps, aren't considered * "label overlap measures" in a precise sense but are still used to determine * segmentation/registration accuracy. These measurements include * 1. Hausdorff distance * 2. Min distance sum */ typedef itk::BinaryThresholdImageFilter ThresholderType; typename ThresholderType::Pointer source = ThresholderType::New(); source->SetInput( filter->GetSourceImage() ); source->SetLowerThreshold( label ); source->SetUpperThreshold( label ); source->SetInsideValue( static_cast( 1 ) ); source->SetOutsideValue( static_cast( 0 ) ); source->Update(); typename ThresholderType::Pointer target = ThresholderType::New(); target->SetInput( filter->GetTargetImage() ); target->SetLowerThreshold( label ); target->SetUpperThreshold( label ); target->SetInsideValue( static_cast( 1 ) ); target->SetOutsideValue( static_cast( 0 ) ); target->Update(); // Calculate Hausdorff distances typedef itk::HausdorffDistanceImageFilter HausdorffType; typename HausdorffType::Pointer hausdorff = HausdorffType::New(); hausdorff->SetInput1( source->GetOutput() ); hausdorff->SetInput2( target->GetOutput() ); hausdorff->Update(); std::cout << std::setw( 17 ) << hausdorff->GetHausdorffDistance(); std::cout << std::setw( 17 ) << hausdorff->GetAverageHausdorffDistance(); // Calculate min sum distance typedef itk::SignedMaurerDistanceMapImageFilter DistancerType; typename DistancerType::Pointer sourceDistance = DistancerType::New(); sourceDistance->SetInput( source->GetOutput() ); sourceDistance->SetSquaredDistance( false ); sourceDistance->SetUseImageSpacing( true ); sourceDistance->SetInsideIsPositive( false ); sourceDistance->Update(); typename DistancerType::Pointer targetDistance = DistancerType::New(); targetDistance->SetInput( target->GetOutput() ); targetDistance->SetSquaredDistance( false ); targetDistance->SetUseImageSpacing( true ); targetDistance->SetInsideIsPositive( false ); targetDistance->Update(); float distanceToSource = 0.0; float NS = 0.0; float distanceToTarget = 0.0; float NT = 0.0; itk::ImageRegionIteratorWithIndex ItS( sourceDistance->GetOutput(), sourceDistance->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIteratorWithIndex ItT( targetDistance->GetOutput(), targetDistance->GetOutput()->GetLargestPossibleRegion() ); for( ItS.GoToBegin(), ItT.GoToBegin(); !ItS.IsAtEnd(); ++ItS, ++ItT ) { // on the boundary or inside the source object? if( ItS.Get() <= 0.0 ) { // outside the target object? if( ItT.Get() > 0.0 ) { distanceToTarget += ItT.Get(); NS += 1.0; } } // on the boundary or inside the target object? if( ItT.Get() <= 0.0 ) { // outside the source object? if( ItS.Get() > 0.0 ) { distanceToSource += ItS.Get(); NT += 1.0; } } } float minDistanceSum = ( distanceToSource + distanceToTarget ) / ( NS + NT ); std::cout << std::setw( 17 ) << minDistanceSum; std::cout << std::endl; } return EXIT_SUCCESS; } int main( int argc, char *argv[] ) { if( argc < 4 ) { std::cerr << "Usage: " << argv[0] << " imageDimension sourceImage " << "targetImage" << std::endl; return EXIT_FAILURE; } switch( atoi( argv[1] ) ) { case 2: LabelOverlapMeasures<2>( argc, argv ); break; case 3: LabelOverlapMeasures<3>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/LaplacianThickness.cxx000066400000000000000000000727221147325206600225340ustar00rootroot00000000000000 //#include "DoSomethingToImage.cxx" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "vnl/algo/vnl_determinant.h" #include "itkWarpImageFilter.h" #include "itkImageFileWriter.h" #include "itkRescaleIntensityImageFilter.h" #include "vnl/algo/vnl_determinant.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkBinaryThresholdImageFilter.h" #include "itkDanielssonDistanceMapImageFilter.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "itkLaplacianRecursiveGaussianImageFilter.h" #include "ReadWriteImage.h" #include "itkGradientRecursiveGaussianImageFilter.h" template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType low, typename TImage::PixelType high, typename TImage::PixelType replaceval, typename TImage::Pointer input) { //std::cout << " Binary Thresh " << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; inputThresholder->SetLowerThreshold((PixelType) low ); inputThresholder->SetUpperThreshold((PixelType) high); inputThresholder->Update(); return inputThresholder->GetOutput(); } template typename TImage::Pointer GetVectorComponent(typename TField::Pointer field, unsigned int index) { // Initialize the Moving to the displacement field typedef TField FieldType; typedef TImage ImageType; typename ImageType::Pointer sfield=ImageType::New(); sfield->SetSpacing( field->GetSpacing() ); sfield->SetOrigin( field->GetOrigin() ); sfield->SetDirection( field->GetDirection() ); sfield->SetLargestPossibleRegion(field->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(field->GetRequestedRegion() ); sfield->SetBufferedRegion( field->GetBufferedRegion() ); sfield->Allocate(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( field, field->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TField::PixelType v1=vfIter.Get(); sfield->SetPixel(vfIter.GetIndex(),v1[index]); } return sfield; } template typename TImage::Pointer SmoothImage(typename TImage::Pointer image, float sig) { // find min value typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter(image,image->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { typename TImage::PixelType v1=vfIter.Get(); if (vnl_math_isnan(v1)) vfIter.Set(0); } typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); typename TImage::Pointer out= filter->GetOutput(); return out; } template void SmoothDeformation(typename TImage::Pointer vectorimage, float sig) { typedef itk::Vector VectorType; typedef itk::Image ImageType; typename ImageType::Pointer subimgx=GetVectorComponent(vectorimage,0); subimgx=SmoothImage(subimgx,sig); typename ImageType::Pointer subimgy=GetVectorComponent(vectorimage,1); subimgy=SmoothImage(subimgy,sig); typename ImageType::Pointer subimgz=GetVectorComponent(vectorimage,2); subimgz=SmoothImage(subimgz,sig); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( vectorimage, vectorimage->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { VectorType vec; vec[0]=subimgx->GetPixel(Iterator.GetIndex()); vec[1]=subimgy->GetPixel(Iterator.GetIndex()); vec[2]=subimgz->GetPixel(Iterator.GetIndex()); Iterator.Set(vec); ++Iterator; } return; } template typename TImage::Pointer LabelSurface(typename TImage::PixelType foreground, typename TImage::PixelType newval, typename TImage::Pointer input, float distthresh ) { std::cout << " Label Surf " << std::endl; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typename ImageType::Pointer Image = ImageType::New(); Image->SetLargestPossibleRegion(input->GetLargestPossibleRegion() ); Image->SetBufferedRegion(input->GetLargestPossibleRegion()); Image->Allocate(); Image->SetSpacing(input->GetSpacing()); Image->SetOrigin(input->GetOrigin()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); // std::cout << " foreg " << (int) foreground; while (!GHood.IsAtEnd()) { typename TImage::PixelType p = GHood.GetCenterPixel(); typename TImage::IndexType ind = GHood.GetIndex(); typename TImage::IndexType ind2; if ( p == foreground ) { bool atedge=false; for (unsigned int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0.0; for (int j=0; jSetPixel(ind,newval); else Image->SetPixel(ind,0); } ++GHood; } return Image; } template typename TImage::Pointer Morphological( typename TImage::Pointer input,float rad, bool option) { typedef TImage ImageType; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::PixelType PixelType; if (!option) std::cout << " eroding the image " << std::endl; else std::cout << " dilating the image " << std::endl; typedef itk::BinaryBallStructuringElement< PixelType, ImageDimension > StructuringElementType; // Software Guide : BeginCodeSnippet typedef itk::BinaryErodeImageFilter< TImage, TImage, StructuringElementType > ErodeFilterType; typedef itk::BinaryDilateImageFilter< TImage, TImage, StructuringElementType > DilateFilterType; typename ErodeFilterType::Pointer binaryErode = ErodeFilterType::New(); typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New(); StructuringElementType structuringElement; structuringElement.SetRadius((unsigned long) rad ); // 3x3x3 structuring element structuringElement.CreateStructuringElement(); binaryErode->SetKernel( structuringElement ); binaryDilate->SetKernel( structuringElement ); // It is necessary to define what could be considered objects on the binary // images. This is specified with the methods \code{SetErodeValue()} and // \code{SetDilateValue()}. The value passed to these methods will be // considered the value over which the dilation and erosion rules will apply binaryErode->SetErodeValue( 1 ); binaryDilate->SetDilateValue( 1 ); typename TImage::Pointer temp; if (option) { binaryDilate->SetInput( input ); binaryDilate->Update(); temp = binaryDilate->GetOutput(); } else { binaryErode->SetInput( input );//binaryDilate->GetOutput() ); binaryErode->Update(); temp = binaryErode->GetOutput(); typedef itk::ImageRegionIteratorWithIndex< ImageType > ImageIteratorType ; ImageIteratorType o_iter( temp, temp->GetLargestPossibleRegion() ); o_iter.GoToBegin() ; while ( !o_iter.IsAtEnd() ) { if (o_iter.Get() > 0.5 && input->GetPixel(o_iter.GetIndex()) > 0.5) o_iter.Set(1); else o_iter.Set(0); ++o_iter; } } return temp; } template typename TField::Pointer LaplacianGrad(typename TImage::Pointer wm,typename TImage::Pointer gm, float sig , unsigned int numits, float tolerance) { typedef typename TImage::IndexType IndexType; IndexType ind; typedef TImage ImageType; typedef TField GradientImageType; typedef itk::GradientRecursiveGaussianImageFilter< ImageType,GradientImageType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; typename TField::Pointer sfield=TField::New(); sfield->SetSpacing( wm->GetSpacing() ); sfield->SetOrigin( wm->GetOrigin() ); sfield->SetDirection( wm->GetDirection() ); sfield->SetLargestPossibleRegion(wm->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(wm->GetRequestedRegion() ); sfield->SetBufferedRegion( wm->GetBufferedRegion() ); sfield->Allocate(); typename TImage::Pointer laplacian=SmoothImage(wm,1); laplacian->FillBuffer(0); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( wm, wm->GetLargestPossibleRegion().GetSize() ); Iterator.GoToBegin(); //initialize L(wm)=1, L(gm)=0.5, else 0 while( !Iterator.IsAtEnd() ) { ind=Iterator.GetIndex(); if (wm->GetPixel(ind) >= 0.5 ) laplacian->SetPixel(ind,1); else if (gm->GetPixel(ind) >= 0.5 && wm->GetPixel(ind) < 0.5 ) laplacian->SetPixel(ind,2.); else laplacian->SetPixel(ind,2.); ++Iterator; } //smooth and then reset the values float meanvalue=0,lastmean=1; unsigned int iterations=0; while ( fabs(meanvalue-lastmean) > tolerance && iterations < numits) { iterations++; std::cout << " % " << (float) iterations/(float)(numits+1) << " delta-mean " << fabs(meanvalue-lastmean) << std::endl; laplacian=SmoothImage(laplacian,sqrt(sig)); Iterator.GoToBegin(); unsigned int ct=0; lastmean=meanvalue; while( !Iterator.IsAtEnd() ) { ind=Iterator.GetIndex(); if (wm->GetPixel(ind) >= 0.5 ) laplacian->SetPixel(ind,1); else if (gm->GetPixel(ind) < 0.5 && wm->GetPixel(ind) < 0.5 ) laplacian->SetPixel(ind,2.); else { meanvalue+=laplacian->GetPixel(ind); ct++;} ++Iterator; } meanvalue/=(float)ct; } /// WriteImage(laplacian, "laplacian.hdr"); GradientImageFilterPointer filter=GradientImageFilterType::New(); filter->SetInput( laplacian ); filter->SetSigma(sig*0.5); filter->Update(); return filter->GetOutput(); } template float IntegrateLength( typename TImage::Pointer gmsurf, typename TImage::Pointer thickimage, typename TImage::IndexType velind, typename TField::Pointer lapgrad, float itime, float starttime, float finishtime, bool timedone, float deltaTime, typename TInterp::Pointer vinterp, typename TInterp2::Pointer sinterp, unsigned int task, bool propagate,bool domeasure, unsigned int m_NumberOfTimePoints, typename TImage::SpacingType spacing, float vecsign, float timesign, float gradsign, unsigned int ct, typename TImage::Pointer wm, typename TImage::Pointer gm, float priorthickval , typename TImage::Pointer smooththick , bool printprobability, typename TImage::Pointer sulci ) { typedef TField TimeVaryingVelocityFieldType; typedef typename TField::PixelType VectorType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename TField::IndexType DIndexType; typedef typename TField::PointType DPointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; VectorType zero; zero.Fill(0); VectorType disp; disp.Fill(0); ct=0; DPointType pointIn1; DPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType vcontind; DPointType pointIn3; enum { ImageDimension = TImage::ImageDimension }; typedef typename TImage::IndexType IndexType; float startprob=gm->GetPixel(velind); if (sulci) startprob=sulci->GetPixel(velind); bool printout=false; if ( gmsurf->GetPixel(velind) > 0) printout=true; IndexType index; for (unsigned int jj=0; jjGetSpacing()[jj]; } if (task ==0) { propagate=false; } else propagate=true; itime=starttime; timedone=false; float totalmag=0; if ( domeasure ) { while ( !timedone ) { float scale = 1;//*m_DT[timeind]/m_DS[timeind]; // std::cout << " scale " << scale << std::endl; double itimetn1 = itime - timesign*deltaTime*scale; double itimetn1h = itime - timesign*deltaTime*0.5*scale; if (itimetn1h < 0 ) itimetn1h=0; if (itimetn1h > m_NumberOfTimePoints-1 ) itimetn1h=m_NumberOfTimePoints-1; if (itimetn1 < 0 ) itimetn1=0; if (itimetn1 > m_NumberOfTimePoints-1 ) itimetn1=m_NumberOfTimePoints-1; // first get current position of particle IndexType index; for (unsigned int jj=0; jjGetSpacing()[jj]; } // std::cout << " ind " << index << std::endl; // now index the time varying field at that position. typename DefaultInterpolatorType::OutputType f1; f1.Fill(0); typename DefaultInterpolatorType::OutputType f2; f2.Fill(0); typename DefaultInterpolatorType::OutputType f3; f3.Fill(0); typename DefaultInterpolatorType::OutputType f4; f4.Fill(0); typename DefaultInterpolatorType::ContinuousIndexType Y1; typename DefaultInterpolatorType::ContinuousIndexType Y2; typename DefaultInterpolatorType::ContinuousIndexType Y3; typename DefaultInterpolatorType::ContinuousIndexType Y4; for (unsigned int jj=0; jjGetSpacing()[jj]; Y1[jj]=vcontind[jj]; Y2[jj]=vcontind[jj]; Y3[jj]=vcontind[jj]; Y4[jj]=vcontind[jj]; } //Y1[ImageDimension]=itimetn1; //Y2[ImageDimension]=itimetn1h; //Y3[ImageDimension]=itimetn1h; // Y4[ImageDimension]=itime; f1 = vinterp->EvaluateAtContinuousIndex( Y1 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f2 = vinterp->EvaluateAtContinuousIndex( Y2 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f3 = vinterp->EvaluateAtContinuousIndex( Y3 ); for (unsigned int jj=0; jj lapgrad->GetLargestPossibleRegion().GetSize()[jj] -2 ) isinside=false; if (isinside) f4 = vinterp->EvaluateAtContinuousIndex( Y4 ); for (unsigned int jj=0; jjGetPixel(myind) < 0.5 && wm->GetPixel(myind) < 0.5 || wm->GetPixel(myind) >= 0.5 && gm->GetPixel(myind) < 0.5 || mag < 1.e-1*deltaTime) { timedone=true; } if ( gm->GetPixel(myind) < 0.5 ) { timedone=true; } if ( ct > 2.0/deltaTime ) { timedone=true;} if ( totalmag > priorthickval ) timedone=true; if (smooththick) if ( (totalmag - smooththick->GetPixel(velind)) > 1 ) timedone=true; if (printprobability) std::cout << " ind " << Y1 << " prob " << sinterp->EvaluateAtContinuousIndex(Y1) << " t " << itime << std::endl; } } return totalmag; } template int LaplacianThickness(int argc, char *argv[]) { float gradstep= -50.0;//atof(argv[3])*(-1.0); unsigned int nsmooth=2; float smoothparam=1; float priorthickval=500; double dT=0.01; std::string wfn = std::string(argv[1]); std::string gfn = std::string(argv[2]); int argct=3; std::string outname=std::string(argv[argct]); argct++; if (argc > argct) smoothparam=atof(argv[argct]); argct++; if (argc > argct) priorthickval=atof(argv[argct]); argct++; if (argc > argct) dT=atof(argv[argct]); argct++; float dosulc=0; if (argc > argct ) dosulc=atof(argv[argct]); argct++; unsigned int totalits=500; float tolerance=0.001; if (argc > argct ) tolerance=atof(argv[argct]); argct++; std::cout << " using tolerance " << tolerance << std::endl; typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::Image tvt; // typename tvt::Pointer gWarp; //ReadImage( gWarp, ifn.c_str() ); typename ImageType::Pointer thickimage; ReadImage(thickimage,wfn.c_str()); thickimage->FillBuffer(0); typename ImageType::Pointer thickimage2; ReadImage(thickimage2,wfn.c_str()); thickimage2->FillBuffer(0); typename ImageType::Pointer wm; ReadImage(wm,wfn.c_str()); typename ImageType::Pointer gm; ReadImage(gm,gfn.c_str()); SpacingType spacing=wm->GetSpacing(); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( wm, wm->GetLargestPossibleRegion().GetSize() ); typename ImageType::Pointer wmb=BinaryThreshold(0.5,1.e9,1,wm); typename DeformationFieldType::Pointer lapgrad=NULL; typename DeformationFieldType::Pointer lapgrad2=NULL; typename ImageType::Pointer gmb=BinaryThreshold(0.5,1.e9,1,gm); /** get sulcal priors */ typename ImageType::Pointer sulci=NULL; if (dosulc > 0 ){ std::cout <<" using sulcal prior " << std::endl; typedef itk::DanielssonDistanceMapImageFilter FilterType; typename FilterType::Pointer distmap = FilterType::New(); distmap->InputIsBinaryOn(); distmap->SetUseImageSpacing(true); distmap->SetInput(wmb); distmap->Update(); typename ImageType::Pointer distwm=distmap->GetOutput(); typedef itk::LaplacianRecursiveGaussianImageFilter dgf; typename dgf::Pointer lfilter = dgf::New(); lfilter->SetSigma(smoothparam); lfilter->SetInput(distwm); lfilter->Update(); typename ImageType::Pointer image2=lfilter->GetOutput(); typedef itk::RescaleIntensityImageFilter RescaleFilterType; typename RescaleFilterType::Pointer rescaler = RescaleFilterType::New(); rescaler->SetOutputMinimum( 0 ); rescaler->SetOutputMaximum( 1 ); rescaler->SetInput( image2 ); rescaler->Update(); sulci= rescaler->GetOutput(); WriteImage(sulci,"sulci.nii"); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { // std::cout << " a good value for use sulcus prior is 0.002 -- in a function : 1/(1.+exp(-0.1*(sulcprob-0.275)/use-sulcus-prior)) " << std::endl; // float gmprob=gm->GetPixel(Iterator.GetIndex()); if (gmprob == 0) gmprob=0.05; float sprob=sulci->GetPixel(Iterator.GetIndex()); sprob=1/(1.+exp(-0.1*(sprob-0.5)/dosulc)); sulci->SetPixel(Iterator.GetIndex(),sprob ); // if (gmprob > 0) std::cout << " gmp " << gmprob << std::endl; ++Iterator; } std::cout << " modified gm prior by sulcus prior " << std::endl; WriteImage(sulci,"sulcigm.nii"); typedef itk::GradientRecursiveGaussianImageFilter< ImageType,DeformationFieldType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; GradientImageFilterPointer filter=GradientImageFilterType::New(); filter->SetInput( distwm ); filter->SetSigma(smoothparam); filter->Update(); lapgrad2 = filter->GetOutput(); // return 0; /** sulc priors done */ } lapgrad=LaplacianGrad(wmb,gmb,smoothparam,totalits,tolerance); // LabelSurface(typename TImage::PixelType foreground, // typename TImage::PixelType newval, typename TImage::Pointer input, float distthresh ) float distthresh = 1.9; typename ImageType::Pointer wmgrow = Morphological(wmb,1,true); typename ImageType::Pointer surf = LabelSurface(1,1,wmgrow, distthresh); typename ImageType::Pointer gmsurf = LabelSurface(1,1,gmb, distthresh); // now integrate // double timezero=0; //1 typename ImageType::SizeType s= wm->GetLargestPossibleRegion().GetSize(); double timeone=1;//(s[ImageDimension]-1-timezero); // unsigned int m_NumberOfTimePoints = s[ImageDimension]; float starttime=timezero;//timezero; float finishtime=timeone;//s[ImageDimension]-1;//timeone; //std::cout << " MUCKING WITH START FINISH TIME " << finishtime << std::endl; typename DeformationFieldType::IndexType velind; typename ImageType::Pointer smooththick=NULL; float timesign=1.0; if (starttime > finishtime ) timesign= -1.0; unsigned int m_NumberOfTimePoints=2; typedef DeformationFieldType TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType2; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); typedef itk::LinearInterpolateImageFunction ScalarInterpolatorType; typename ScalarInterpolatorType::Pointer sinterp = ScalarInterpolatorType::New(); sinterp->SetInputImage(gm); if (sulci) sinterp->SetInputImage(sulci); VectorType zero; zero.Fill(0); DPointType pointIn1; DPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType vcontind; DPointType pointIn3; typedef itk::ImageRegionIteratorWithIndex VIteratorType; VIteratorType VIterator( lapgrad, lapgrad->GetLargestPossibleRegion().GetSize() ); VIterator.GoToBegin(); while( !VIterator.IsAtEnd() ) { VectorType vec=VIterator.Get(); float mag=0; for (unsigned int qq=0; qq 0) vec=vec/mag; VIterator.Set(vec*gradstep); if (lapgrad2) { vec=lapgrad2->GetPixel(VIterator.GetIndex()); mag=0; for (unsigned int qq=0; qq 0) vec=vec/mag; lapgrad2->SetPixel(VIterator.GetIndex(), vec*gradstep); } ++VIterator; } bool propagate=false; for (unsigned int smoothit=0; smoothitGetPixel(velind) << " gm " << gm->GetPixel(velind) << std::endl; // if (surf->GetPixel(velind) != 0) printprobability=true; if ( gm->GetPixel(velind) > 0.25 )//&& wmb->GetPixel(velind) < 1 ) { cter++; domeasure=true; } vinterp->SetInputImage(lapgrad); gradsign=-1.0; vecsign=-1.0; float len1=IntegrateLength (gmsurf, thickimage, velind, lapgrad, itime, starttime, finishtime, timedone, deltaTime, vinterp, sinterp,task,propagate,domeasure,m_NumberOfTimePoints,spacing,vecsign, gradsign, timesign, ct, wm,gm, priorthickval , smooththick , printprobability , sulci ); gradsign=1.0; vecsign=1; float len2=IntegrateLength (gmsurf, thickimage, velind, lapgrad, itime, starttime, finishtime, timedone, deltaTime, vinterp, sinterp,task,propagate,domeasure,m_NumberOfTimePoints,spacing,vecsign, gradsign, timesign, ct,wm,gm , priorthickval-len1 , smooththick , printprobability , sulci ); float len3=1.e9,len4=1.e9; if (lapgrad2) { vinterp->SetInputImage(lapgrad2); gradsign=-1.0; vecsign=-1.0; len3=IntegrateLength (gmsurf, thickimage, velind, lapgrad2, itime, starttime, finishtime, timedone, deltaTime, vinterp, sinterp,task,propagate,domeasure,m_NumberOfTimePoints,spacing,vecsign, gradsign, timesign, ct, wm,gm, priorthickval , smooththick , printprobability , sulci ); gradsign=1.0; vecsign=1; len4=IntegrateLength (gmsurf, thickimage, velind, lapgrad2, itime, starttime, finishtime, timedone, deltaTime, vinterp, sinterp,task,propagate,domeasure,m_NumberOfTimePoints,spacing,vecsign, gradsign, timesign, ct,wm,gm , priorthickval-len3, smooththick , printprobability , sulci ); } float totalength=len1+len2; // if (totalength > 5 && totalength < 8) std::cout<< " t1 " << len3+len4 << " t2 " << len1+len2 << std::endl; if (len3+len4 < totalength) totalength=len3+len4; if (smoothit==0) { if ( thickimage2->GetPixel(velind) == 0 ) { thickimage2->SetPixel(velind,totalength); } else if ( (totalength) > 0 && thickimage2->GetPixel(velind) < (totalength) ) { thickimage2->SetPixel(velind,totalength); } } if ( smoothit > 0 && smooththick ) { thickimage2->SetPixel(velind, (totalength)*0.5 + smooththick->GetPixel(velind)*0.5 ); } if (domeasure && (totalength)> 0 && cter % 10000 == 0) std::cout << " len1 " << len1 << " len2 " << len2 << " ind " << velind << std::endl; } ++Iterator; } smooththick=SmoothImage(thickimage2,1.0); // set non-gm voxels to zero IteratorType gIterator( gm, gm->GetLargestPossibleRegion().GetSize() ); gIterator.GoToBegin(); while( !gIterator.IsAtEnd() ) { if (gm->GetPixel(gIterator.GetIndex()) < 0.25 ) thickimage2->SetPixel(gIterator.GetIndex(),0); ++gIterator; } std::cout << " writing " << outname << std::endl; WriteImage(thickimage2,outname.c_str()); } // WriteImage(thickimage,"turd.hdr"); return 0; } int main(int argc, char *argv[]) { if ( argc < 4) { std::cout << "Usage: " << argv[0] << " WM.nii GM.nii Out.nii {smoothparam=3} {priorthickval=5} {dT=0.01} use-sulcus-prior optional-laplacian-tolerance=0.001" << std::endl; std::cout << " a good value for use sulcus prior is 0.15 -- in a function : 1/(1.+exp(-0.1*(laplacian-img-value-sulcprob)/0.01)) " << std::endl; return 1; } std::string ifn = std::string(argv[1]); // std::cout << " image " << ifn << std::endl; // Get the image dimension itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(ifn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(ifn.c_str()); imageIO->ReadImageInformation(); unsigned int dim = imageIO->GetNumberOfDimensions(); // std::cout << " dim " << dim << std::endl; switch ( dim ) { case 2: LaplacianThickness<2>(argc,argv); break; case 3: LaplacianThickness<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return EXIT_SUCCESS; return 1; } ants-1.9.2+svn680.dfsg/Examples/MeasureImageSimilarity.cxx000066400000000000000000000226071147325206600234040ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: MeasureImageSimilarity.cxx,v $ Language: C++ Date: $Date: 2009/01/05 20:09:47 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "ReadWriteImage.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkAvantsMutualInformationRegistrationFunction.h" #include "itkSpatialMutualInformationRegistrationFunction.h" #include "itkProbabilisticRegistrationFunction.h" #include "itkCrossCorrelationRegistrationFunction.h" // #include "itkLandmarkCrossCorrelationRegistrationFunction.h" template int MeasureImageSimilarity(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::Image JointHistType; typedef itk::ImageFileWriter jhwritertype; // get command line params unsigned int argct=2; unsigned int whichmetric = atoi(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = std::string(argv[argct]); argct++; std::string logfilename=""; if (argc > argct) logfilename = std::string(argv[argct]); argct++; std::string imgfilename=""; if (argc > argct) imgfilename = std::string(argv[argct]); argct++; double targetvalue=0; if (argc > argct) targetvalue = atof(argv[argct]); argct++; double epsilontolerance=1.e20; if (argc > argct) epsilontolerance = atof(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typename ImageType::Pointer image2 = NULL; ReadImage(image2, fn2.c_str()); /* typedef itk::ImageRegionIteratorWithIndex VIterator; typename FieldType::Pointer field=FieldType::New(); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->SetBufferedRegion( image1->GetLargestPossibleRegion() ); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->Allocate(); field->SetSpacing(image1->GetSpacing()); field->SetOrigin(image1->GetOrigin()); VectorType zero; zero.Fill(0); VIterator vfIter2( field, field->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType index=vfIter2.GetIndex(); vfIter2.Set(zero); } */ typename ImageType::Pointer metricimg=ImageType::New(); metricimg->SetRegions( image1->GetLargestPossibleRegion() ); metricimg->Allocate(); metricimg->SetSpacing(image1->GetSpacing()); metricimg->SetOrigin(image1->GetOrigin()); metricimg->SetDirection(image1->GetDirection()); Iterator iter( metricimg, metricimg->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) iter.Set(0); typedef ImageType FixedImageType; typedef ImageType MovingImageType; typedef FieldType DeformationFieldType; // Choose the similarity metric typedef itk::AvantsMutualInformationRegistrationFunction MIMetricType; typedef itk::SpatialMutualInformationRegistrationFunction SMIMetricType; typedef itk::CrossCorrelationRegistrationFunction CCMetricType; //typedef itk::LandmarkCrossCorrelationRegistrationFunction MetricType; //typename typename MIMetricType::Pointer mimet=MIMetricType::New(); typename SMIMetricType::Pointer smimet=SMIMetricType::New(); typename CCMetricType::Pointer ccmet=CCMetricType::New(); // int nbins=32; typename CCMetricType::RadiusType hradius; typename CCMetricType::RadiusType ccradius; ccradius.Fill(4); typename MIMetricType::RadiusType miradius; miradius.Fill(0); // mimet->SetDeformationField(field); mimet->SetFixedImage(image1); mimet->SetMovingImage(image2); mimet->SetRadius(miradius); mimet->SetGradientStep(1.e2); mimet->SetNormalizeGradient(false); // ccmet->SetDeformationField(field); ccmet->SetFixedImage(image1); ccmet->SetMovingImage(image2); ccmet->SetRadius(ccradius); ccmet->SetGradientStep(1.e2); ccmet->SetNormalizeGradient(false); double metricvalue=0; std::string metricname=""; if (whichmetric == 0) { hradius=miradius; unsigned long ct = 0; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { IndexType index=iter.GetIndex(); double fval=image1->GetPixel(index); double mval=image2->GetPixel(index); metricvalue+=fabs(fval-mval); metricimg->SetPixel(index,fabs(fval-mval)); ct++; } metricvalue/=(float)ct; metricname="MSQ "; } else if (whichmetric == 1 ) // imagedifference { hradius=ccradius; metricname="CC "; std::cout << metricname << std::endl; ccmet->InitializeIteration(); metricimg=ccmet->MakeImage(); metricvalue=ccmet->ComputeCrossCorrelation()*(1.0); } else if (whichmetric == 2 ) { hradius=miradius; mimet->InitializeIteration(); metricvalue=mimet->ComputeMutualInformation(); metricname="MI "; } else if (whichmetric == 3 ) { hradius=miradius; smimet->InitializeIteration(); metricvalue=smimet->ComputeSpatialMutualInformation(); metricname="SMI "; } std::cout << fn1 << " : " << fn2 << " => " << metricname << metricvalue << std::endl; if (logfilename.length() > 3 ){ std::ofstream logfile; logfile.open(logfilename.c_str(), std::ofstream::app); if (logfile.good()) { logfile << fn1 << " : " << fn2 << " => " << metricname << metricvalue << std::endl; } else std::cout << " cant open file "; logfile.close(); } if (imgfilename.length() > 3 ){ std::cout << "Only Implemented for MSQ and CC " << std::endl; typedef itk::ImageFileWriter writertype; typename writertype::Pointer w= writertype::New(); w->SetInput(metricimg); w->SetFileName(imgfilename.c_str()); w->Write(); // met->WriteImages(); /* typename MetricType::NeighborhoodType asamIt( hradius, field,field->GetLargestPossibleRegion()); unsigned long ct = 0; double totval = 0; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType index=vfIter2.GetIndex(); double val=0; asamIt.SetLocation(index); // met->ComputeUpdate( asamIt, gd); met->ComputeMetricAtPairB(index, zero); metricimg->SetPixel(index, val); //if (ct % 10000 == 0) // std::cout << val << " index " << index << std::endl; // asamIt.SetLocation(index); // totval+=met->localProbabilistic; ct++; } std::cout << " AvantsMI : " << totval/(double)ct << " E " << met->GetEnergy() << std::endl; std::cout << " write begin " << std::endl; std::cout << " write end " << std::endl; */ } double diff = ((double)metricvalue - (double) targetvalue); std::cout << " targetvalue " << targetvalue << " metricvalue " << metricvalue << " diff " << diff << " toler " << epsilontolerance << std::endl; if ( diff < epsilontolerance) return EXIT_SUCCESS; else return EXIT_FAILURE; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Basic useage ex: " << std::endl; std::cout << argv[0] << " ImageDimension whichmetric image1.ext image2.ext {logfile} {outimage.ext} {target-value} {epsilon-tolerance}" << std::endl; std::cout << " outimage (Not Implemented for MI yet) and logfile are optional " << std::endl; std::cout <<" target-value and epsilon-tolerance set goals for the metric value -- if the metric value is within epsilon-tolerance of the target-value, then the test succeeds " << std::endl; std::cout << " Metric 0 - MeanSquareDifference, 1 - Cross-Correlation, 2-Mutual Information , 3-SMI " << std::endl; return 1; } int metricsuccess=EXIT_FAILURE; // Get the image dimension switch( atoi(argv[1])) { case 2: metricsuccess=MeasureImageSimilarity<2>(argc,argv); break; case 3: metricsuccess=MeasureImageSimilarity<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } std::cout << " Failure? " << metricsuccess << std::endl; return metricsuccess; } ants-1.9.2+svn680.dfsg/Examples/MeasureMinMaxMean.cxx000066400000000000000000000105451147325206600223030ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: MeasureMinMaxMean.cxx,v $ Language: C++ Date: $Date: 2008/12/16 17:56:34 $ Version: $Revision: 1.20 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ //#include "DoSomethingToImage.cxx" // RecursiveAverageImages img1 img2 weight // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. //Note: could easily add variance computation //http://people.revoledu.com/kardi/tutorial/RecursiveStatistic/Time-Variance.htm #include "ReadWriteImage.h" template int MeasureMinMaxMean(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; typename ImageType::Pointer image = NULL; typename ImageType::Pointer mask = NULL; // typename ImageType::SizeType size; double mean=0,max=-1.e9,min=1.e9; unsigned long ct = 0; ReadImage(image,argv[2]); bool takeabsval=false; if ( argc > 4 ) takeabsval=atoi(argv[4]); if ( argc > 5 ) { ReadImage(mask,argv[5]);} Iterator vfIter2( image, image->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { bool isinside=true; if (mask) if (mask->GetPixel(vfIter2.GetIndex()) < 0.5) isinside=false; if (isinside) { double val=vfIter2.Get(); if (takeabsval) val=fabs(val); mean+=val; if (val >max) max=val; else if (val < min) min=val; ct++; } } if (ct > 0) mean/= (float)ct; float variance=0; for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { bool isinside=true; if (mask) if (mask->GetPixel(vfIter2.GetIndex()) < 0.5) isinside=false; if (isinside) { double val=vfIter2.Get(); if (takeabsval) val=fabs(val); variance+=vnl_math_sqr(val-mean); } } if (ct > 0) variance/= (float)ct; std::cout << argv[2] <<" Max : " << max << " Min : " << min << " Mean : " << mean << " Var : " << variance << " SD : " << sqrt(variance) << std::endl; if (argc > 3){ std::ofstream logfile; logfile.open(argv[3], std::ofstream::app); if (logfile.good()) { logfile << argv[2] << " Max : " << max << " Min : " << min << " Mean : " << mean << std::endl; } else std::cout << " cant open file " << argv[3] << std::endl; logfile.close(); } return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Basic useage ex: " << std::endl; std::cout << argv[0] << " ImageDimension image.nii {log.txt} {take-absolute-value} {mask-name} " << std::endl; std::cout << " log.txt is optional - take-abs-val reports min-max-mean of abs val image " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: MeasureMinMaxMean<2>(argc,argv); break; case 3: MeasureMinMaxMean<3>(argc,argv); break; case 4: MeasureMinMaxMean<4>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/MemoryTest.cxx000066400000000000000000000151651147325206600211020ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: MemoryTest.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "ReadWriteImage.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkAvantsMutualInformationRegistrationFunction.h" #include "itkProbabilisticRegistrationFunction.h" #include "itkCrossCorrelationRegistrationFunction.h" // #include "itkLandmarkCrossCorrelationRegistrationFunction.h" template int MemoryTest(unsigned int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::ImageRegionIteratorWithIndex Iterator; typedef itk::Image JointHistType; typedef itk::ImageFileWriter jhwritertype; // get command line params unsigned int argct=2; unsigned int whichmetric = atoi(argv[argct]); argct++; std::string fn1 = std::string(argv[argct]); argct++; std::string fn2 = std::string(argv[argct]); argct++; unsigned int numberoffields=11; if (argc > argct) numberoffields=atoi(argv[argct]); argct++; typename ImageType::Pointer image1 = NULL; ReadImage(image1, fn1.c_str()); typename ImageType::Pointer image2 = NULL; ReadImage(image2, fn2.c_str()); typedef itk::ImageRegionIteratorWithIndex VIterator; std::vector fieldvec; for (unsigned int i=0; i < numberoffields; i++) { std::cout <<" NFields " << i << " of " << numberoffields << std::endl; typename FieldType::Pointer field=FieldType::New(); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->SetBufferedRegion( image1->GetLargestPossibleRegion() ); field->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); field->Allocate(); field->SetSpacing(image1->GetSpacing()); field->SetOrigin(image1->GetOrigin()); VectorType zero; zero.Fill(0); VIterator vfIter2( field, field->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType index=vfIter2.GetIndex(); vfIter2.Set(zero); } fieldvec.push_back(field); } typename ImageType::Pointer metricimg=ImageType::New(); metricimg->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); metricimg->SetBufferedRegion( image1->GetLargestPossibleRegion() ); metricimg->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); metricimg->Allocate(); metricimg->SetSpacing(image1->GetSpacing()); metricimg->SetOrigin(image1->GetOrigin()); Iterator iter( metricimg, metricimg->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) iter.Set(0); typedef ImageType FixedImageType; typedef ImageType MovingImageType; typedef FieldType DeformationFieldType; // Choose the similarity metric typedef itk::AvantsMutualInformationRegistrationFunction MIMetricType; typedef itk::CrossCorrelationRegistrationFunction CCMetricType; //typedef itk::LandmarkCrossCorrelationRegistrationFunction MetricType; //typename typename MIMetricType::Pointer mimet=MIMetricType::New(); typename CCMetricType::Pointer ccmet=CCMetricType::New(); // int nbins=32; typename CCMetricType::RadiusType hradius; typename CCMetricType::RadiusType ccradius; ccradius.Fill(4); typename MIMetricType::RadiusType miradius; miradius.Fill(0); // mimet->SetDeformationField(field); mimet->SetFixedImage(image1); mimet->SetMovingImage(image2); mimet->SetRadius(miradius); mimet->SetGradientStep(1.e2); mimet->SetNormalizeGradient(false); // ccmet->SetDeformationField(field); ccmet->SetFixedImage(image1); ccmet->SetMovingImage(image2); ccmet->SetRadius(ccradius); ccmet->SetGradientStep(1.e2); ccmet->SetNormalizeGradient(false); double metricvalue=0; std::string metricname=""; if (whichmetric == 0) { hradius=miradius; unsigned long ct = 0; for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { IndexType index=iter.GetIndex(); double fval=image1->GetPixel(index); double mval=image2->GetPixel(index); metricvalue+=fabs(fval-mval); ct++; } metricvalue/=(float)ct; metricname="MSQ "; } else if (whichmetric == 1 ) // imagedifference { hradius=ccradius; ccmet->InitializeIteration(); metricvalue=ccmet->ComputeCrossCorrelation(); metricname="CC "; } else { hradius=miradius; mimet->InitializeIteration(); metricvalue=mimet->ComputeMutualInformation(); metricname="MI "; } return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Basic useage ex: " << std::endl; std::cout << argv[0] << " ImageDimension whichmetric image1.ext image2.ext NumberOfFieldsToAllocate " << std::endl; std::cout << " outimage and logfile are optional " << std::endl; std::cout << " Metric 0 - MeanSquareDifference, 1 - Cross-Correlation, 2-Mutual Information " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: MemoryTest<2>(argc,argv); break; case 3: MemoryTest<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/MultiplyImages.cxx000066400000000000000000000111371147325206600217320ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: MultiplyImages.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkDiscreteGaussianImageFilter.h" // RecursiveAverageImages img1 img2 weightonimg2 outputname // We divide the 2nd input image by its mean and add it to the first // input image with weight 1/n. //The output overwrites the 1st img with the sum. #include "ReadWriteImage.h" template int MultiplyImages(int argc, char *argv[]) { typedef float PixelType; // const unsigned int ImageDimension = AvantsImageDimension; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; std::string fn1 = std::string(argv[2]); std::string fn2 = std::string(argv[3]); std::string outname=std::string(argv[4]); typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer image2 = NULL; typename ImageType::Pointer varimage = NULL; typename readertype::Pointer reader2 = readertype::New(); typename readertype::Pointer reader1 = readertype::New(); reader2->SetFileName(fn2.c_str()); bool isfloat=false; try { reader2->UpdateLargestPossibleRegion(); } catch(...) { std::cout << " Rather than opening " << fn2 << " as an image file, this program has decided, in its great wisdom, to consider it to be a floating point numerical value, and has acted accordingly -- i.e. read this as a number. " << std::endl; isfloat=true; } float floatval=1.0; if (isfloat) floatval=atof(argv[3]); else image2 = reader2->GetOutput(); reader1->SetFileName(fn1.c_str()); try { reader1->UpdateLargestPossibleRegion(); image1 = reader1->GetOutput(); } catch(...) { std::cout << " read 1 error "; } varimage=ImageType::New(); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( image1->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(image1->GetSpacing()); varimage->SetOrigin(image1->GetOrigin()); varimage->SetDirection(image1->GetDirection()); Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { IndexType ind=vfIter2.GetIndex(); float pix2; if (isfloat) pix2= floatval; else pix2=image2->GetPixel(ind); float pix1 = image1->GetPixel(ind); //std::cout << " p1 " << pix1 << " p2 " << pix2 << std::endl; float div=pix1*pix2; vfIter2.Set(div); } typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[4]); writer->SetInput( varimage ); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 4 ) { std::cout << "Usage: "<< std::endl; std::cout << argv[0] << " ImageDimension img1.nii img2.nii product.nii {smoothing}" << std::endl; return 1; } switch ( atoi(argv[1]) ) { case 2: MultiplyImages<2>(argc,argv); break; case 3: MultiplyImages<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/N3BiasFieldCorrection.cxx000066400000000000000000000157671147325206600230550ustar00rootroot00000000000000#include "itkBSplineControlPointImageFilter.h" #include "itkExpImageFilter.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkN3MRIBiasFieldCorrectionImageFilter.h" #include "itkOtsuThresholdImageFilter.h" #include "itkShrinkImageFilter.h" template class CommandIterationUpdate : public itk::Command { public: typedef CommandIterationUpdate Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; itkNewMacro( Self ); protected: CommandIterationUpdate() {}; public: void Execute(itk::Object *caller, const itk::EventObject & event) { Execute( (const itk::Object *) caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { const TFilter * filter = dynamic_cast< const TFilter * >( object ); if( typeid( event ) != typeid( itk::IterationEvent ) ) { return; } std::cout << "Iteration " << filter->GetElapsedIterations() << " (of " << filter->GetMaximumNumberOfIterations() << "). "; std::cout << " Current convergence value = " << filter->GetCurrentConvergenceMeasurement() << " (threshold = " << filter->GetConvergenceThreshold() << ")" << std::endl; } }; template int N3BiasFieldCorrection( int argc, char *argv[] ) { typedef float RealType; typedef itk::Image ImageType; typedef itk::Image MaskImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->Update(); typedef itk::ShrinkImageFilter ShrinkerType; typename ShrinkerType::Pointer shrinker = ShrinkerType::New(); shrinker->SetInput( reader->GetOutput() ); shrinker->SetShrinkFactors( 1 ); typename MaskImageType::Pointer maskImage = NULL; if( argc > 5 ) { typedef itk::ImageFileReader MaskReaderType; typename MaskReaderType::Pointer maskreader = MaskReaderType::New(); maskreader->SetFileName( argv[5] ); try { maskreader->Update(); maskImage = maskreader->GetOutput(); } catch(...) { std::cout << "Mask file not read. Generating mask file using otsu" << " thresholding." << std::endl; } } if( !maskImage ) { typedef itk::OtsuThresholdImageFilter ThresholderType; typename ThresholderType::Pointer otsu = ThresholderType::New(); otsu->SetInput( reader->GetOutput() ); otsu->SetNumberOfHistogramBins( 200 ); otsu->SetInsideValue( 0 ); otsu->SetOutsideValue( 1 ); otsu->Update(); maskImage = otsu->GetOutput(); } typedef itk::ShrinkImageFilter MaskShrinkerType; typename MaskShrinkerType::Pointer maskshrinker = MaskShrinkerType::New(); maskshrinker->SetInput( maskImage ); maskshrinker->SetShrinkFactors( 1 ); if( argc > 4 ) { shrinker->SetShrinkFactors( atoi( argv[4] ) ); maskshrinker->SetShrinkFactors( atoi( argv[4] ) ); } shrinker->Update(); maskshrinker->Update(); typedef itk::N3MRIBiasFieldCorrectionImageFilter CorrecterType; typename CorrecterType::Pointer correcter = CorrecterType::New(); correcter->SetInput( shrinker->GetOutput() ); correcter->SetMaskImage( maskshrinker->GetOutput() ); if( argc > 6 ) { correcter->SetMaximumNumberOfIterations( atoi( argv[6] ) ); } if( argc > 7 ) { correcter->SetNumberOfFittingLevels( atoi( argv[7] ) ); } typedef CommandIterationUpdate CommandType; typename CommandType::Pointer observer = CommandType::New(); correcter->AddObserver( itk::IterationEvent(), observer ); try { correcter->Update(); } catch(...) { std::cerr << "Exception caught." << std::endl; return EXIT_FAILURE; } // correcter->Print( std::cout, 3 ); /** * Reconstruct the bias field at full image resolution. Divide * the original input image by the bias field to get the final * corrected image. */ typedef itk::BSplineControlPointImageFilter BSplinerType; typename BSplinerType::Pointer bspliner = BSplinerType::New(); bspliner->SetInput( correcter->GetLogBiasFieldControlPointLattice() ); bspliner->SetSplineOrder( correcter->GetSplineOrder() ); bspliner->SetSize( reader->GetOutput()->GetLargestPossibleRegion().GetSize() ); bspliner->SetOrigin( reader->GetOutput()->GetOrigin() ); bspliner->SetDirection( reader->GetOutput()->GetDirection() ); bspliner->SetSpacing( reader->GetOutput()->GetSpacing() ); bspliner->Update(); typename ImageType::Pointer logField = ImageType::New(); logField->SetOrigin( bspliner->GetOutput()->GetOrigin() ); logField->SetSpacing( bspliner->GetOutput()->GetSpacing() ); logField->SetRegions( bspliner->GetOutput()->GetLargestPossibleRegion().GetSize() ); logField->SetDirection( bspliner->GetOutput()->GetDirection() ); logField->Allocate(); itk::ImageRegionIterator ItB( bspliner->GetOutput(), bspliner->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItF( logField, logField->GetLargestPossibleRegion() ); for( ItB.GoToBegin(), ItF.GoToBegin(); !ItB.IsAtEnd(); ++ItB, ++ItF ) { ItF.Set( ItB.Get()[0] ); } typedef itk::ExpImageFilter ExpFilterType; typename ExpFilterType::Pointer expFilter = ExpFilterType::New(); expFilter->SetInput( logField ); expFilter->Update(); typedef itk::DivideImageFilter DividerType; typename DividerType::Pointer divider = DividerType::New(); divider->SetInput1( reader->GetOutput() ); divider->SetInput2( expFilter->GetOutput() ); divider->Update(); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[3] ); writer->SetInput( divider->GetOutput() ); writer->Update(); if( argc > 8 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[8] ); writer->SetInput( expFilter->GetOutput() ); writer->Update(); } return EXIT_SUCCESS; } int main( int argc, char *argv[] ) { if ( argc < 4 ) { std::cerr << "Usage: " << argv[0] << " imageDimension inputImage " << "outputImage [shrinkFactor] [maskImage] [numberOfIterations] " << "[numberOfFittingLevels] [outputBiasField] " << std::endl; exit( EXIT_FAILURE ); } switch( atoi( argv[1] ) ) { case 2: N3BiasFieldCorrection<2>( argc, argv ); break; case 3: N3BiasFieldCorrection<3>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/N4BiasFieldCorrection.cxx000066400000000000000000000664641147325206600230560ustar00rootroot00000000000000#include "itkBSplineControlPointImageFilter.h" #include "antsCommandLineParser.h" #include "itkConstantPadImageFilter.h" #include "itkExpImageFilter.h" #include "itkExtractImageFilter.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkN4MRIBiasFieldCorrectionImageFilter.h" #include "itkOtsuThresholdImageFilter.h" #include "itkShrinkImageFilter.h" #include "itkTimeProbe.h" #include #include #include template class CommandIterationUpdate : public itk::Command { public: typedef CommandIterationUpdate Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; itkNewMacro( Self ); protected: CommandIterationUpdate() {}; public: void Execute(itk::Object *caller, const itk::EventObject & event) { Execute( (const itk::Object *) caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { const TFilter * filter = dynamic_cast< const TFilter * >( object ); if( typeid( event ) != typeid( itk::IterationEvent ) ) { return; } if( filter->GetElapsedIterations() == 1 ) { std::cout << "Current level = " << filter->GetCurrentLevel() + 1 << std::endl; } std::cout << " Iteration " << filter->GetElapsedIterations() << " (of " << filter->GetMaximumNumberOfIterations()[filter->GetCurrentLevel()] << "). "; std::cout << " Current convergence value = " << filter->GetCurrentConvergenceMeasurement() << " (threshold = " << filter->GetConvergenceThreshold() << ")" << std::endl; } }; template int N4( itk::ants::CommandLineParser *parser ) { typedef float RealType; typedef itk::Image ImageType; typename ImageType::Pointer inputImage = NULL; typedef itk::Image MaskImageType; typename MaskImageType::Pointer maskImage = NULL; typedef itk::N4MRIBiasFieldCorrectionImageFilter CorrecterType; typename CorrecterType::Pointer correcter = CorrecterType::New(); typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); typename itk::ants::CommandLineParser::OptionType::Pointer inputImageOption = parser->GetOption( "input-image" ); if( inputImageOption ) { std::string inputFile = inputImageOption->GetValue(); reader->SetFileName( inputFile.c_str() ); reader->Update(); inputImage = reader->GetOutput(); } else { std::cerr << "Input image not specified." << std::endl; return EXIT_FAILURE; } /** * handle the mask image */ typename itk::ants::CommandLineParser::OptionType::Pointer maskImageOption = parser->GetOption( "mask-image" ); if( maskImageOption && maskImageOption->GetNumberOfValues() ) { std::string inputFile = maskImageOption->GetValue(); typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer maskreader = ReaderType::New(); maskreader->SetFileName( inputFile.c_str() ); try { maskreader->Update(); maskImage = maskreader->GetOutput(); } catch(...) {} } if( !maskImage ) { std::cout << "Mask not read. Creating Otsu mask." << std::endl; typedef itk::OtsuThresholdImageFilter ThresholderType; typename ThresholderType::Pointer otsu = ThresholderType::New(); otsu->SetInput( inputImage ); otsu->SetNumberOfHistogramBins( 200 ); otsu->SetInsideValue( 0 ); otsu->SetOutsideValue( 1 ); otsu->Update(); maskImage = otsu->GetOutput(); } typename ImageType::Pointer weightImage = NULL; typename itk::ants::CommandLineParser::OptionType::Pointer weightImageOption = parser->GetOption( "weight-image" ); if( weightImageOption && weightImageOption->GetNumberOfValues() ) { std::string inputFile = weightImageOption->GetValue(); typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer weightreader = ReaderType::New(); weightreader->SetFileName( inputFile.c_str() ); weightreader->Update(); weightImage = weightreader->GetOutput(); } /** * convergence options */ typename itk::ants::CommandLineParser::OptionType::Pointer convergenceOption = parser->GetOption( "convergence" ); if( convergenceOption ) { if( convergenceOption->GetNumberOfParameters() > 0 ) { std::vector numIters = parser->ConvertVector( convergenceOption->GetParameter( 0 ) ); typename CorrecterType::VariableSizeArrayType maximumNumberOfIterations( numIters.size() ); for( unsigned int d = 0; d < numIters.size(); d++ ) { maximumNumberOfIterations[d] = numIters[d]; } correcter->SetMaximumNumberOfIterations( maximumNumberOfIterations ); typename CorrecterType::ArrayType numberOfFittingLevels; numberOfFittingLevels.Fill( numIters.size() ); correcter->SetNumberOfFittingLevels( numberOfFittingLevels ); } if( convergenceOption->GetNumberOfParameters() > 1 ) { correcter->SetConvergenceThreshold( parser->Convert( convergenceOption->GetParameter( 1 ) ) ); } } /** * B-spline options -- we place this here to take care of the case where * the user wants to specify things in terms of the spline distance. */ bool useSplineDistance = false; typename ImageType::IndexType inputImageIndex = inputImage->GetLargestPossibleRegion().GetIndex(); typename ImageType::SizeType inputImageSize = inputImage->GetLargestPossibleRegion().GetSize(); typename ImageType::IndexType maskImageIndex = maskImage->GetLargestPossibleRegion().GetIndex(); typename ImageType::SizeType maskImageSize = maskImage->GetLargestPossibleRegion().GetSize(); typename ImageType::PointType newOrigin = inputImage->GetOrigin(); typename itk::ants::CommandLineParser::OptionType::Pointer bsplineOption = parser->GetOption( "bspline-fitting" ); if( bsplineOption ) { if( bsplineOption->GetNumberOfParameters() > 1 ) { correcter->SetSplineOrder( parser->Convert( bsplineOption->GetParameter( 1 ) ) ); } if( bsplineOption->GetNumberOfParameters() > 2 ) { correcter->SetSigmoidNormalizedAlpha( parser->Convert( bsplineOption->GetParameter( 2 ) ) ); } if( bsplineOption->GetNumberOfParameters() > 3 ) { correcter->SetSigmoidNormalizedBeta( parser->Convert( bsplineOption->GetParameter( 3 ) ) ); } if( bsplineOption->GetNumberOfParameters() > 0 ) { std::vector array = parser->ConvertVector( bsplineOption->GetParameter( 0 ) ); typename CorrecterType::ArrayType numberOfControlPoints; if( array.size() == 1 ) { // the user wants to specify things in terms of spline distance. // 1. need to pad the images to get as close to possible to the // requested domain size. useSplineDistance = true; float splineDistance = array[0]; unsigned long lowerBound[ImageDimension]; unsigned long upperBound[ImageDimension]; for( unsigned int d = 0; d < ImageDimension; d++ ) { float domain = static_cast( inputImage-> GetLargestPossibleRegion().GetSize()[d] - 1 ) * inputImage->GetSpacing()[d]; unsigned int numberOfSpans = static_cast( vcl_ceil( domain / splineDistance ) ); unsigned long extraPadding = static_cast( ( numberOfSpans * splineDistance - domain ) / inputImage->GetSpacing()[d] + 0.5 ); lowerBound[d] = static_cast( 0.5 * extraPadding ); upperBound[d] = extraPadding - lowerBound[d]; newOrigin[d] -= ( static_cast( lowerBound[d] ) * inputImage->GetSpacing()[d] ); numberOfControlPoints[d] = numberOfSpans + correcter->GetSplineOrder(); } typedef itk::ConstantPadImageFilter PadderType; typename PadderType::Pointer padder = PadderType::New(); padder->SetInput( inputImage ); padder->SetPadLowerBound( lowerBound ); padder->SetPadUpperBound( upperBound ); padder->SetConstant( 0 ); padder->Update(); inputImage = padder->GetOutput(); typedef itk::ConstantPadImageFilter MaskPadderType; typename MaskPadderType::Pointer maskPadder = MaskPadderType::New(); maskPadder->SetInput( maskImage ); maskPadder->SetPadLowerBound( lowerBound ); maskPadder->SetPadUpperBound( upperBound ); maskPadder->SetConstant( 0 ); maskPadder->Update(); maskImage = maskPadder->GetOutput(); if( weightImage ) { typename PadderType::Pointer weightPadder = PadderType::New(); weightPadder->SetInput( weightImage ); weightPadder->SetPadLowerBound( lowerBound ); weightPadder->SetPadUpperBound( upperBound ); weightPadder->SetConstant( 0 ); weightPadder->Update(); weightImage = weightPadder->GetOutput(); } } else if( array.size() == ImageDimension ) { for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfControlPoints[d] = static_cast( array[d] ) + correcter->GetSplineOrder(); } } else { std::cerr << "Incorrect mesh resolution" << std::endl; return EXIT_FAILURE; } correcter->SetNumberOfControlPoints( numberOfControlPoints ); } } typedef itk::ShrinkImageFilter ShrinkerType; typename ShrinkerType::Pointer shrinker = ShrinkerType::New(); shrinker->SetInput( inputImage ); shrinker->SetShrinkFactors( 1 ); typedef itk::ShrinkImageFilter MaskShrinkerType; typename MaskShrinkerType::Pointer maskshrinker = MaskShrinkerType::New(); maskshrinker->SetInput( maskImage ); maskshrinker->SetShrinkFactors( 1 ); typename itk::ants::CommandLineParser::OptionType::Pointer shrinkFactorOption = parser->GetOption( "shrink-factor" ); int shrinkFactor = 4; if( shrinkFactorOption ) { shrinkFactor = parser->Convert( shrinkFactorOption->GetValue() ); } shrinker->SetShrinkFactors( shrinkFactor ); maskshrinker->SetShrinkFactors( shrinkFactor ); shrinker->Update(); maskshrinker->Update(); itk::TimeProbe timer; timer.Start(); correcter->SetInput( shrinker->GetOutput() ); correcter->SetMaskImage( maskshrinker->GetOutput() ); if( weightImage ) { typedef itk::ShrinkImageFilter WeightShrinkerType; typename WeightShrinkerType::Pointer weightshrinker = WeightShrinkerType::New(); weightshrinker->SetInput( weightImage ); weightshrinker->SetShrinkFactors( 1 ); if( shrinkFactorOption ) { int shrinkFactor = parser->Convert( shrinkFactorOption->GetValue() ); weightshrinker->SetShrinkFactors( shrinkFactor ); } weightshrinker->Update(); correcter->SetConfidenceImage( weightshrinker->GetOutput() ); } typedef CommandIterationUpdate CommandType; typename CommandType::Pointer observer = CommandType::New(); correcter->AddObserver( itk::IterationEvent(), observer ); /** * histogram sharpening options */ typename itk::ants::CommandLineParser::OptionType::Pointer histOption = parser->GetOption( "histogram-sharpening" ); if( histOption ) { if( histOption->GetNumberOfParameters() > 0 ) { correcter->SetBiasFieldFullWidthAtHalfMaximum( parser->Convert( histOption->GetParameter( 0 ) ) ); } if( histOption->GetNumberOfParameters() > 1 ) { correcter->SetWeinerFilterNoise( parser->Convert( histOption->GetParameter( 1 ) ) ); } if( histOption->GetNumberOfParameters() > 2 ) { correcter->SetNumberOfHistogramBins( parser->Convert( histOption->GetParameter( 2 ) ) ); } } try { correcter->Update(); } catch(...) { std::cerr << "Exception caught." << std::endl; return EXIT_FAILURE; } correcter->Print( std::cout, 3 ); timer.Stop(); std::cout << "Elapsed time: " << timer.GetMeanTime() << std::endl; /** * output */ typename itk::ants::CommandLineParser::OptionType::Pointer outputOption = parser->GetOption( "output" ); if( outputOption ) { /** * Reconstruct the bias field at full image resolution. Divide * the original input image by the bias field to get the final * corrected image. */ typedef itk::BSplineControlPointImageFilter BSplinerType; typename BSplinerType::Pointer bspliner = BSplinerType::New(); bspliner->SetInput( correcter->GetLogBiasFieldControlPointLattice() ); bspliner->SetSplineOrder( correcter->GetSplineOrder() ); bspliner->SetSize( inputImage->GetLargestPossibleRegion().GetSize() ); bspliner->SetOrigin( newOrigin ); bspliner->SetDirection( inputImage->GetDirection() ); bspliner->SetSpacing( inputImage->GetSpacing() ); bspliner->Update(); typename ImageType::Pointer logField = ImageType::New(); logField->SetOrigin( inputImage->GetOrigin() ); logField->SetSpacing( inputImage->GetSpacing() ); logField->SetRegions( inputImage->GetLargestPossibleRegion() ); logField->SetDirection( inputImage->GetDirection() ); logField->Allocate(); itk::ImageRegionIterator ItB( bspliner->GetOutput(), bspliner->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIterator ItF( logField, logField->GetLargestPossibleRegion() ); for( ItB.GoToBegin(), ItF.GoToBegin(); !ItB.IsAtEnd(); ++ItB, ++ItF ) { ItF.Set( ItB.Get()[0] ); } typedef itk::ExpImageFilter ExpFilterType; typename ExpFilterType::Pointer expFilter = ExpFilterType::New(); expFilter->SetInput( logField ); expFilter->Update(); typedef itk::DivideImageFilter DividerType; typename DividerType::Pointer divider = DividerType::New(); divider->SetInput1( inputImage ); divider->SetInput2( expFilter->GetOutput() ); divider->Update(); if( weightImage && ( maskImageOption && maskImageOption->GetNumberOfValues() > 0 ) ) { itk::ImageRegionIteratorWithIndex ItD( divider->GetOutput(), divider->GetOutput()->GetLargestPossibleRegion() ); for( ItD.GoToBegin(); !ItD.IsAtEnd(); ++ItD ) { if( maskImage->GetPixel( ItD.GetIndex() ) != correcter->GetMaskLabel() ) { ItD.Set( inputImage->GetPixel( ItD.GetIndex() ) ); } } } typename ImageType::RegionType inputRegion; inputRegion.SetIndex( inputImageIndex ); inputRegion.SetSize( inputImageSize ); typedef itk::ExtractImageFilter CropperType; typename CropperType::Pointer cropper = CropperType::New(); cropper->SetInput( divider->GetOutput() ); cropper->SetExtractionRegion( inputRegion ); cropper->Update(); typename CropperType::Pointer biasFieldCropper = CropperType::New(); biasFieldCropper->SetInput( expFilter->GetOutput() ); biasFieldCropper->SetExtractionRegion( inputRegion ); biasFieldCropper->Update(); if( outputOption->GetNumberOfParameters() == 0 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( cropper->GetOutput() ); writer->SetFileName( ( outputOption->GetValue() ).c_str() ); writer->Update(); } if( outputOption->GetNumberOfParameters() > 0 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetInput( cropper->GetOutput() ); writer->SetFileName( ( outputOption->GetParameter( 0 ) ).c_str() ); writer->Update(); } if( outputOption->GetNumberOfParameters() > 1 ) { typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( ( outputOption->GetParameter( 1 ) ).c_str() ); writer->SetInput( biasFieldCropper->GetOutput() ); writer->Update(); } } return EXIT_SUCCESS; } void InitializeCommandLineOptions( itk::ants::CommandLineParser *parser ) { typedef itk::ants::CommandLineParser::OptionType OptionType; { std::string description = std::string( "This option forces the image to be treated as a specified-" ) + std::string( "dimensional image. If not specified, N4 tries to " ) + std::string( "infer the dimensionality from the input image." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "image-dimensionality" ); option->SetShortName( 'd' ); option->SetUsageOption( 0, "2/3/4" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "A scalar image is expected as input for bias correction. " ) + std::string( "Since N4 log transforms the intensities, negative values " ) + std::string( "or values close to zero should be processed prior to " ) + std::string( "correction." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "input-image" ); option->SetShortName( 'i' ); option->SetUsageOption( 0, "inputImageFilename" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "If a mask image is specified, the final bias correction is " ) + std::string( "only performed in the mask region. If a weight image is not " ) + std::string( "specified, only intensity values inside the masked region are " ) + std::string( "used during the execution of the algorithm. If a weight " ) + std::string( "image is specified, only the non-zero weights are used in the " ) + std::string( "execution of the algorithm although the mask region defines " ) + std::string( "where bias correction is performed in the final output. " ) + std::string( "Otherwise bias correction occurs over the entire image domain. " ) + std::string( "See also the option description for the weight image." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "mask-image" ); option->SetShortName( 'x' ); option->SetUsageOption( 0, "maskImageFilename" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The weight image allows the user to perform a relative " ) + std::string( "weighting of specific voxels during the B-spline fitting. " ) + std::string( "For example, some studies have shown that N3 performed on " ) + std::string( "white matter segmentations improves performance. If one " ) + std::string( "has a spatial probability map of the white matter, one can " ) + std::string( "use this map to weight the b-spline fitting towards those " ) + std::string( "voxels which are more probabilistically classified as white " ) + std::string( "matter. See also the option description for the mask image." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "weight-image" ); option->SetUsageOption( 0, "weightImageFilename" ); option->SetShortName( 'w' ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Running N4 on large images can be time consuming. " ) + std::string( "To lessen computation time, the input image can be resampled. " ) + std::string( "The shrink factor, specified as a single integer, describes " ) + std::string( "this resampling. Shrink factors <= 4 are commonly used." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "shrink-factor" ); option->SetShortName( 's' ); option->SetUsageOption( 0, "1/2/3/4/..." ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Convergence is determined by calculating the coefficient of " ) + std::string( "variation between subsequent iterations. When this value " ) + std::string( "is less than the specified threshold " ) + std::string( "from the previous iteration or the maximum number of " ) + std::string( "iterations is exceeded the program terminates. Multiple " ) + std::string( "resolutions can be specified by using 'x' between the number " ) + std::string( "of iterations at each resolution, e.g. 100x50x50." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "convergence" ); option->SetShortName( 'c' ); option->SetUsageOption( 0, "[,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "These options describe the b-spline fitting parameters. " ) + std::string( "The initial b-spline mesh at the coarsest resolution is " ) + std::string( "specified either as the number of elements in each dimension, " ) + std::string( "e.g. 2x2x3 for 3-D images, or it can be specified as a " ) + std::string( "single scalar parameter which describes the isotropic sizing " ) + std::string( "of the mesh elements. The latter option is typically preferred. " ) + std::string( "For each subsequent level, the spline distance decreases in " ) + std::string( "half, or equivalently, the number of mesh elements doubles " ) + std::string( "Cubic splines (order = 3) are typically used. The final " ) + std::string( "two parameters are experimental and really do not need to " ) + std::string( "be used for good performance." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "bspline-fitting" ); option->SetShortName( 'b' ); option->SetUsageOption( 0, "[splineDistance,,,]" ); option->SetUsageOption( 1, "[initialMeshResolution,,,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "These options describe the histogram sharpening parameters, " ) + std::string( "i.e. the deconvolution step parameters described in the " ) + std::string( "original N3 algorithm. The default values have been shown " ) + std::string( "to work fairly well." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "histogram-sharpening" ); option->SetShortName( 't' ); option->SetUsageOption( 0, "[,,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "The output consists of the bias corrected version of the " ) + std::string( "input image. Optionally, one can also output the estimated " ) + std::string( "bias field." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "output" ); option->SetShortName( 'o' ); option->SetUsageOption( 0, "[correctedImage,]" ); option->SetDescription( description ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu (short version)." ); OptionType::Pointer option = OptionType::New(); option->SetShortName( 'h' ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } { std::string description = std::string( "Print the help menu." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "help" ); option->SetDescription( description ); option->AddValue( std::string( "0" ) ); parser->AddOption( option ); } } int main( int argc, char *argv[] ) { itk::ants::CommandLineParser::Pointer parser = itk::ants::CommandLineParser::New(); parser->SetCommand( argv[0] ); std::string commandDescription = std::string( "N4 is a variant of the popular N3 (nonparameteric nonuniform " ) + std::string( "normalization) retrospective bias correction algorithm. Based " ) + std::string( "on the assumption that the corruption of the low frequency bias " ) + std::string( "field can be modeled as a convolution of the intensity histogram " ) + std::string( "by a Gaussian, the basic algorithmic protocol is to iterate " ) + std::string( "between deconvolving the intensity histogram by a Gaussian, " ) + std::string( "remapping the intensities, and then spatially smoothing this " ) + std::string( "result by a B-spline modeling of the bias field itself. " ) + std::string( "The modifications from and improvements obtained over " ) + std::string( "the original N3 algorithm are described in the following paper: " ) + std::string( "N. Tustison et al., N4ITK: Improved N3 Bias Correction, " ) + std::string( "IEEE Transactions on Medical Imaging, 29(6):1310-1320, June 2010." ); parser->SetCommandDescription( commandDescription ); InitializeCommandLineOptions( parser ); parser->Parse( argc, argv ); if( argc < 2 || parser->Convert( parser->GetOption( "help" )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, false ); exit( EXIT_FAILURE ); } else if( parser->Convert( parser->GetOption( 'h' )->GetValue() ) ) { parser->PrintMenu( std::cout, 5, true ); exit( EXIT_FAILURE ); } // Get dimensionality unsigned int dimension = 3; itk::ants::CommandLineParser::OptionType::Pointer dimOption = parser->GetOption( "image-dimensionality" ); if( dimOption && dimOption->GetNumberOfValues() > 0 ) { dimension = parser->Convert( dimOption->GetValue() ); } else { // Read in the first intensity image to get the image dimension. std::string filename; itk::ants::CommandLineParser::OptionType::Pointer imageOption = parser->GetOption( "input-image" ); if( imageOption && imageOption->GetNumberOfValues() > 0 ) { if( imageOption->GetNumberOfParameters( 0 ) > 0 ) { filename = imageOption->GetParameter( 0, 0 ); } else { filename = imageOption->GetValue( 0 ); } } else { std::cerr << "No input images were specified. Specify an input image" << " with the -i option" << std::endl; return( EXIT_FAILURE ); } itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( filename.c_str(), itk::ImageIOFactory::ReadMode ); dimension = imageIO->GetNumberOfDimensions(); } std::cout << std::endl << "Running N4 for " << dimension << "-dimensional images." << std::endl << std::endl; switch( dimension ) { case 2: N4<2>( parser ); break; case 3: N4<3>( parser ); break; case 4: N4<4>( parser ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/PermuteFlipImageOrientationAxes.cxx000066400000000000000000000107021147325206600252160ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: PermuteFlipImageOrientationAxes.cxx,v $ Language: C++ Date: $Date: 2009/01/30 16:40:33 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkImage.h" #include "itkConstantPadImageFilter.h" #include "itkIdentityTransform.h" #include "itkLinearInterpolateImageFunction.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkPermuteAxesImageFilter.h" #include "itkFlipImageFilter.h" #include "ReadWriteImage.h" template int PermuteFlipImageOrientationAxes( int argc, char * argv[] ) { typedef float InputPixelType; typedef float InternalPixelType; typedef float OutputPixelType; typedef itk::Image< InputPixelType, Dimension > InputImageType; typedef itk::Image< InternalPixelType, Dimension > InternalImageType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typename InputImageType::Pointer inputImage = NULL; ReadImage(inputImage,argv[1]); typename InputImageType::SpacingType inputSpacing = inputImage->GetSpacing(); // Create a filter typedef OutputImageType ShortImage; typename itk::PermuteAxesImageFilter< ShortImage >::Pointer permute; permute = itk::PermuteAxesImageFilter< ShortImage >::New(); permute->SetInput( inputImage ); unsigned int upperFactors[Dimension]; unsigned int lowerFactors[Dimension]; bool flipaboutorigin=false; if (Dimension == 2) { if (argc > 3) upperFactors[0] = atoi(argv[3]); if (argc > 4) upperFactors[1] = atoi(argv[4]); if (argc > 5) lowerFactors[0] = atoi(argv[5]); if (argc > 6) lowerFactors[1] = atoi(argv[6]); if (argc > 7) flipaboutorigin=atoi(argv[7]); } else if (Dimension == 3) { if (argc > 3) upperFactors[0] = atoi(argv[3]); if (argc > 4) upperFactors[1] = atoi(argv[4]); if (argc > 5 ) upperFactors[2] = atoi(argv[5]); if (argc > 6) lowerFactors[0] = atoi(argv[6]); if (argc > 7) lowerFactors[1] = atoi(argv[7]); if (argc > 8 ) lowerFactors[2] = atoi(argv[8]); if (argc > 9) flipaboutorigin=atoi(argv[9]); } permute->SetOrder( upperFactors ); permute->Update(); typedef itk::FlipImageFilter FlipType; typename FlipType::FlipAxesArrayType flip; for (unsigned int i=0; iSetFlipAboutOrigin(flipaboutorigin); flipper->SetFlipAxes(flip); flipper->SetInput( permute->GetOutput()); flipper->Update(); typename InputImageType::Pointer image = flipper->GetOutput(); WriteImage(image,argv[2]); return 0; } int main(int argc, char *argv[]) { if( argc < 3 ) { std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " ImageDimension inputImageFile outputImageFile xperm yperm {zperm} xflip yflip {zflip} {FlipAboutOrigin}" << std::endl; std::cout << " for 3D: " << argv[0] << " 3 in.nii out.nii 2 0 1 1 1 1 \n would map z=>x, x=>y, y=>z and flip each " << std::endl; std::cout << " for 2D: " << argv[0] << " 2 in.nii out.nii 1 0 1 0 \n would map x=>y, y=>x and flip x " << std::endl; std::cout << std::endl; std::cout << " 0 1 2 for permute factors gives no axis permutation " << std::endl; std::cout << " 1 2 0 maps y to x, z to y and x to z " << std::endl; std::cout <<" the flip values are boolean - 0 1 0 would flip the y-axis only " << std::endl; std::cout << std::endl << " The FlipAboutOrigin boolean lets you flip about the coordinate set in the origin " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: PermuteFlipImageOrientationAxes<2>(argc-1,argv+1); break; case 3: PermuteFlipImageOrientationAxes<3>(argc-1,argv+1); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/PrintHeader.cxx000066400000000000000000000317341147325206600211770ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: PrintHeader.cxx,v $ Language: C++ Date: $Date: 2009/01/05 20:09:47 $ Version: $Revision: 1.4 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" #include "itkMetaDataDictionary.h" #include "itkMetaDataObject.h" #include "itkSpatialOrientation.h" using namespace std; /** below code from Paul Yushkevich's c3d */ template bool try_print_metadata(itk::MetaDataDictionary &mdd, std::string key) { AnyType value=0; if(itk::ExposeMetaData(mdd, key, value)) { cout << " " << key << " = " << value << endl; return true; } else return false; } string get_rai_code(itk::SpatialOrientation::ValidCoordinateOrientationFlags code) { std::map m_CodeToString; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP] = "RIP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIP] = "LIP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RSP] = "RSP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LSP] = "LSP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIA] = "RIA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LIA] = "LIA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RSA] = "RSA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LSA] = "LSA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRP] = "IRP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ILP] = "ILP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SRP] = "SRP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SLP] = "SLP"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IRA] = "IRA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ILA] = "ILA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SRA] = "SRA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SLA] = "SLA"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RPI] = "RPI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LPI] = "LPI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAI] = "RAI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LAI] = "LAI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RPS] = "RPS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LPS] = "LPS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RAS] = "RAS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_LAS] = "LAS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PRI] = "PRI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PLI] = "PLI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ARI] = "ARI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ALI] = "ALI"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PRS] = "PRS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PLS] = "PLS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ARS] = "ARS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ALS] = "ALS"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IPR] = "IPR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SPR] = "SPR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IAR] = "IAR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SAR] = "SAR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IPL] = "IPL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SPL] = "SPL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_IAL] = "IAL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_SAL] = "SAL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PIR] = "PIR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PSR] = "PSR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIR] = "AIR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ASR] = "ASR"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PIL] = "PIL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_PSL] = "PSL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_AIL] = "AIL"; m_CodeToString[itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_ASL] = "ASL"; return m_CodeToString[code]; } template int PrintHeader(int argc, char *argv[]) { typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); std::cout << " Spacing " << reader->GetOutput()->GetSpacing() << std::endl; std::cout << " Origin " << reader->GetOutput()->GetOrigin() << std::endl; std::cout << " Direction " << std::endl << reader->GetOutput()->GetDirection() << std::endl; if ( ImageDimension == 1 ) std::cout << " Size : " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0] << " " << std::endl; else if ( ImageDimension == 2 ) std::cout << " Size : " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0] << " " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] << " " << std::endl; else if ( ImageDimension == 3 ) std::cout << " Size : " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0] << " " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] << " " << " " << reader->GetOutput()->GetLargestPossibleRegion().GetSize()[2] << std::endl; else std::cout << " Size : " << reader->GetOutput()->GetLargestPossibleRegion().GetSize() << std::endl; // std::cout << " Orientation " << reader->GetOutput()->GetOrientation() << std::endl; unsigned int VDim=ImageDimension; // Get the input image typename ImageType::Pointer image = reader->GetOutput(); // Compute the bounding box vnl_vector bb0, bb1, ospm; bb0.set_size(VDim); bb1.set_size(VDim); ospm.set_size(VDim); for(size_t i = 0; i < VDim; i++) { bb0[i] = image->GetOrigin()[i]; bb1[i] = bb0[i] + image->GetSpacing()[i] * image->GetBufferedRegion().GetSize()[i]; ospm[i] = -image->GetOrigin()[i] / image->GetSpacing()[i]; } // Compute the intensity range of the image size_t n = image->GetBufferedRegion().GetNumberOfPixels(); float *vox = image->GetBufferPointer(); double iMax = vox[0], iMin = vox[0], iMean = vox[0]; for(size_t i = 1; i < n; i++) { iMax = (iMax > vox[i]) ? iMax : vox[i]; iMin = (iMin < vox[i]) ? iMin : vox[i]; iMean += vox[i]; } iMean /= n; // Short or long? bool full=true; if(!full) { cout << " dim = " << image->GetBufferedRegion().GetSize() << "; "; cout << " bb = {[" << bb0 << "], [" << bb1 << "]}; "; cout << " vox = " << image->GetSpacing() << "; "; cout << " range = [" << iMin << ", " << iMax << "]; "; cout << endl; } else { cout << endl; cout << " Image Dimensions : " << image->GetBufferedRegion().GetSize() << endl; cout << " Bounding Box : " << "{[" << bb0 << "], [" << bb1 << "]}" << endl; cout << " Voxel Spacing : " << image->GetSpacing() << endl; cout << " Intensity Range : [" << iMin << ", " << iMax << "]" << endl; cout << " Mean Intensity : " << iMean << endl; cout << " Direction Cos Mtx. : " << endl; std::cout << image->GetDirection().GetVnlMatrix() << std::endl; // Print NIFTI s-form matrix (check against freesurfer's MRIinfo) cout << " Voxel->RAS x-form : " << endl; // image->GetVoxelSpaceToRASPhysicalSpaceMatrix().GetVnlMatrix(); // std::cout << image->GetVoxelSpaceToRASPhysicalSpaceMatrix().GetVnlMatrix() << std::endl; // // Print metadata cout << " Image Metadata: " << endl; itk::MetaDataDictionary &mdd = image->GetMetaDataDictionary(); itk::MetaDataDictionary::ConstIterator itMeta; for(itMeta = mdd.Begin(); itMeta != mdd.End(); ++itMeta) { // Get the metadata as a generic object string key = itMeta->first, v_string; itk::SpatialOrientation::ValidCoordinateOrientationFlags v_oflags; if(itk::ExposeMetaData(mdd, key, v_string)) { // For some weird reason, some of the strings returned by this method // contain '\0' characters. We will replace them by spaces std::ostringstream sout(""); for(unsigned int i=0;i= ' ') sout << v_string[i]; v_string = sout.str(); // Make sure the value has more than blanks if(v_string.find_first_not_of(" ") != v_string.npos) cout << " " << key << " = " << v_string << endl; } else if(itk::ExposeMetaData(mdd, key, v_oflags)) { cout << " " << key << " = " << get_rai_code(v_oflags) << endl; } else { bool rc = false; if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) rc |= try_print_metadata(mdd, key); if(!rc) { cout << " " << key << " of unsupported type " << itMeta->second->GetMetaDataObjectTypeName() << endl; } } } } return 1; } bool FileExists(string strFilename) { struct stat stFileInfo; bool blnReturn; int intStat; // Attempt to get the file attributes intStat = stat(strFilename.c_str(),&stFileInfo); if(intStat == 0) { // We were able to get the file attributes // so the file obviously exists. blnReturn = true; } else { // We were not able to get the file attributes. // This may mean that we don't have permission to // access the folder which contains this file. If you // need to do that level of checking, lookup the // return values of stat which will give you // more details on why stat failed. blnReturn = false; } return(blnReturn); } int main(int argc, char *argv[]) { if ( argc < 2 || ((argc == 2) && strcmp(argv[1], "--help") == 0)) { std::cout << "Usage: " << argv[0] << " image.ext " << std::endl; return 1; } // Get the image dimension std::string fn = std::string(argv[1]); if ( ! FileExists(fn) ) { std::cout << " file " << fn << " does not exist . " << std::endl; return 1; } itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); try { imageIO->ReadImageInformation(); } catch ( ... ) { std::cout << " cant read " << fn << std::endl; return 1 ; } switch ( imageIO->GetNumberOfDimensions() ) { case 2: PrintHeader<2>(argc,argv); break; case 3: PrintHeader<3>(argc,argv); break; case 4: PrintHeader<4>(argc,argv); break; default: std::cerr << "Unsupported dimension " << imageIO->GetNumberOfDimensions() << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ReorientTensorImage.cxx000066400000000000000000000517501147325206600227170ustar00rootroot00000000000000/*=========================================================================1 Program: Advanced Normalization Tools Module: $RCSfile: ReorientTensorImage.cxx,v $ Language: C++ Date: $Date: 2009/03/17 18:55:26 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "ReadWriteImage.h" #include "TensorFunctions.h" #include "itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.h" #include "itkVectorImageFileReader.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkVectorResampleImageFilter.h" #include "itkWarpTensorImageMultiTransformFilter.h" #include "itkTransformFileReader.h" #include "itkTransformFactory.h" #include "itkVectorNearestNeighborInterpolateImageFunction.h" typedef enum{INVALID_FILE=1, AFFINE_FILE, DEFORMATION_FILE, IMAGE_AFFINE_HEADER, IDENTITY_TRANSFORM} TRAN_FILE_TYPE; typedef struct{ std::string filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; typedef struct{ bool use_NN_interpolator; bool use_TightestBoundingBox; char * reference_image_filename; bool use_RotationHeader; } MISC_OPT; void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue); void DisplayOpt(const TRAN_OPT &opt); TRAN_FILE_TYPE CheckFileType(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } if (extension==".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else{ return INVALID_FILE; } return AFFINE_FILE; } void FilePartsWithgz(const std::string &filename, std::string &path, std::string &name, std::string &ext){ std::string extension; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); if (pos != std::string::npos){ extension = std::string( filepre, pos, filepre.length()-1 ) + ".gz"; filepre = std::string(filepre, 0, pos); } } } else { extension = std::string(""); } ext = extension; pos = filepre.rfind('/'); if ( pos != std::string::npos ){ path = std::string(filepre, 0, pos+1); name = std::string(filepre, pos+1, filepre.length()-1); } else { path = std::string(""); name = filepre; } // std::cout << "filename: " << filename << std::endl // << "path: " << path << std::endl // << "name: " << name << std::endl // << "ext: " << ext << std::endl; } bool CheckFileExistence(const char *str){ std::ifstream myfile(str); bool b = myfile.is_open(); myfile.close(); return b; } void SetAffineInvFlag(TRAN_OPT &opt, bool &set_current_affine_inv){ opt.do_affine_inv = set_current_affine_inv; if (set_current_affine_inv) set_current_affine_inv = false; } bool ParseInput(int argc, char **argv, char *&moving_image_filename, char *&output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ opt_queue.clear(); opt_queue.reserve(argc-2); misc_opt.reference_image_filename = NULL; misc_opt.use_NN_interpolator = false; misc_opt.use_TightestBoundingBox = false; misc_opt.use_RotationHeader = false; moving_image_filename = argv[0]; output_image_filename = argv[1]; int ind = 2; bool set_current_affine_inv = false; while(ind < argc){ if (strcmp(argv[ind], "--use-NN")==0) { misc_opt.use_NN_interpolator = true; } else if (strcmp(argv[ind], "-R")==0) { ind++; if(ind >= argc) return false; misc_opt.reference_image_filename = argv[ind]; } else if ((strcmp(argv[ind], "--tightest-bounding-box")==0) && (strcmp(argv[ind], "-R")!=0) ) { misc_opt.use_TightestBoundingBox = true; } else if (strcmp(argv[ind], "--reslice-by-header")==0) { misc_opt.use_RotationHeader = true; TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.do_affine_inv = false; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--Id")==0) { TRAN_OPT opt; opt.filename = "--Id"; opt.do_affine_inv = false; opt.file_type = IDENTITY_TRANSFORM; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--moving-image-header")==0 || strcmp(argv[ind], "-mh") ==0){ TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = moving_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--reference-image-header")==0 || strcmp(argv[ind], "-rh") ==0){ if (misc_opt.reference_image_filename==NULL){ std::cout << "reference image filename is not given yet. Specify it with -R before --reference-image-header / -rh." << std::endl; return false; } TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = misc_opt.reference_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "-i")==0) { set_current_affine_inv = true; } else if (strcmp(argv[ind], "--ANTS-prefix")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("Warp")+ext; x_deform_name = path+name+std::string("Warpxvec")+ext; if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } } else if (strcmp(argv[ind], "--ANTS-prefix-invert")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = true; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("InverseWarp.nii.gz"); x_deform_name = path+name+std::string("InverseWarpxvec.nii.gz"); if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } } else{ TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; if (opt.file_type == AFFINE_FILE) SetAffineInvFlag(opt, set_current_affine_inv); else if (opt.file_type == DEFORMATION_FILE && set_current_affine_inv){ std::cout << "Ignore inversion of non-affine file type! " << std::endl; std::cout << "opt.do_affine_inv:" << opt.do_affine_inv << std::endl; } opt_queue.push_back(opt); DisplayOpt(opt); } ind++; } if (misc_opt.use_RotationHeader) { // if (misc_opt.reference_image_filename) { // opt_queue[0].filename = misc_opt.reference_image_filename; // } else { opt_queue[0].filename = "--Id"; opt_queue[0].file_type = IDENTITY_TRANSFORM; opt_queue[0].do_affine_inv = false; // } // TRAN_OPT opt; // opt.file_type = IMAGE_AFFINE_HEADER; // opt.filename = moving_image_filename; // opt.do_affine_inv = true; // opt_queue.push_back(opt); // // std::cout << "Use Rotation Header!" << std::endl; } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue){ const int kQueueSize = opt_queue.size(); for(int i=0; i void GetIdentityTransform(AffineTransformPointer &aff){ typedef typename AffineTransformPointer::ObjectType AffineTransform; aff = AffineTransform::New(); aff->SetIdentity(); } template void GetAffineTransformFromImage(const ImageTypePointer& img, AffineTransformPointer &aff){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename ImageType::DirectionType DirectionType; typedef typename ImageType::PointType PointType; typedef typename ImageType::SpacingType SpacingType; typedef typename AffineTransformPointer::ObjectType::TranslationType VectorType; DirectionType direction = img->GetDirection(); SpacingType spacing = img->GetSpacing(); VectorType translation; // translation.Fill(0); for(unsigned int i=0; iGetOrigin()[i]; aff->SetMatrix(direction); // aff->SetCenter(pt); PointType pt; pt.Fill(0); aff->SetOffset(translation); aff->SetCenter(pt); std::cout << "aff from image:" << aff << std::endl; } template void GetLaregstSizeAfterWarp(WarperPointerType &warper, ImagePointerType &img, SizeType &largest_size, PointType &origin_warped){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::GetImageDimension(); // typedef typename ImageType::PointType PointType; typedef typename std::vector PointList; typedef typename ImageType::IndexType IndexType; // PointList pts_orig; PointList pts_warped; typename ImageType::SizeType imgsz; imgsz = img->GetLargestPossibleRegion().GetSize(); typename ImageType::SpacingType spacing; spacing = img->GetSpacing(); pts_warped.clear(); if (ImageDimension == 3){ for(int i=0; i<8; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; ind[2]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=0; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=0; break; case 4: ind[0]=0; ind[1]=0; ind[2]=imgsz[2]-1; break; case 5: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=imgsz[2]-1; break; case 6: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; case 7: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else if (ImageDimension == 2) { for(int i=0; i<4; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else { std::cout << "could not determine the dimension after warping for non 2D/3D volumes" << std::endl; exit(-1); } PointType pt_min, pt_max; pt_min = pts_warped[0]; pt_max = pts_warped[0]; for(unsigned int k=0; kpts_warped[k][i])?(pt_max[i]):(pts_warped[k][i]); } } for(int i=0; i void ReorientTensorImage(char *moving_image_filename, char *output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ typedef itk::SymmetricSecondRankTensor< float, 3 > TensorType; typedef itk::SymmetricSecondRankTensor< float, 3 > PixelType; typedef itk::Image TensorImageType; typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; typename TensorImageType::Pointer img_mov; ReadTensorImage(img_mov,moving_image_filename,true); typename ImageType::Pointer img_ref; typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (misc_opt.reference_image_filename){ reader_img_ref->SetFileName(misc_opt.reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } // else // img_ref = NULL; typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; typename DeformationFieldType::Pointer field; unsigned int transcount=0; const int kOptQueueSize = opt_queue.size(); for(int i=0; iSetFileName( opt.filename ); field_reader->Update(); field = field_reader->GetOutput(); transcount++; break; } default: std::cout << "Unknown file type!" << std::endl; } } // warper->PrintTransformList(); typedef itk::PreservationOfPrincipalDirectionTensorReorientationImageFilter ReorientType; typename ReorientType::Pointer reo = ReorientType::New(); reo->SetDeformationField( field ); reo->SetInput( img_mov ); reo->Update(); typename TensorImageType::Pointer img_output = reo->GetOutput(); WriteTensorImage(img_output, output_image_filename,true); } int main(int argc, char *argv[]) { std::cout << " Does not take into account reorientation needed when orientations change only in the header!! " << std::endl; std::cout << " consider the same DT image in 2 different orientations under an applied identity transform. " << std::endl; std::cout << " the components will not be rotated correctly, but should be, b/c the header rotation is not accounted for in the reorientation filter." << std::endl; std::cout << " this is a bug we need to fix." << std::endl; std::cout << " ... " << std::endl; if ( argc < 4 ) { std::cout << "Usage: " << argv[0] << " dimension infile.nii outfile.nii warp.nii " << std::endl; return 1; } TRAN_OPT_QUEUE opt_queue; char *moving_image_filename = NULL; char *output_image_filename = NULL; MISC_OPT misc_opt; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc-2, argv+2, moving_image_filename, output_image_filename, opt_queue, misc_opt); if (is_parsing_ok){ std::cout << "moving_image_filename: " << moving_image_filename << std::endl; std::cout << "output_image_filename: " << output_image_filename << std::endl; std::cout << "reference_image_filename: "; if (misc_opt.reference_image_filename) std::cout << misc_opt.reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim){ case 2:{ //WarpImageMultiTransform<2>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } case 3:{ ReorientTensorImage<3>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } } } else{ std::cout << "Input error!" << std::endl; } exit(0); //ReorientTensorImage<3>(argc,argv); // WarpImageForward(argc,argv); return 0; } ants-1.9.2+svn680.dfsg/Examples/ResampleImage.cxx000077500000000000000000000233511147325206600215040ustar00rootroot00000000000000#include #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkResampleImageFilter.h" #include "itkConstantBoundaryCondition.h" #include "itkIdentityTransform.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkGaussianInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkWindowedSincInterpolateImageFunction.h" #include #include template TValue Convert( std::string optionString ) { TValue value; std::istringstream iss( optionString ); iss >> value; return value; } template std::vector ConvertVector( std::string optionString ) { std::vector values; std::string::size_type crosspos = optionString.find( 'x', 0 ); if ( crosspos == std::string::npos ) { values.push_back( Convert( optionString ) ); } else { std::string element = optionString.substr( 0, crosspos ) ; TValue value; std::istringstream iss( element ); iss >> value; values.push_back( value ); while ( crosspos != std::string::npos ) { std::string::size_type crossposfrom = crosspos; crosspos = optionString.find( 'x', crossposfrom + 1 ); if ( crosspos == std::string::npos ) { element = optionString.substr( crossposfrom + 1, optionString.length() ); } else { element = optionString.substr( crossposfrom + 1, crosspos ) ; } std::istringstream iss( element ); iss >> value; values.push_back( value ); } } return values; } template int ResampleImage( int argc, char *argv[] ) { typedef double RealType; typedef double PixelType; typedef itk::Image ImageType; typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[2] ); reader->Update(); typedef itk::IdentityTransform TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); typedef itk::LinearInterpolateImageFunction LinearInterpolatorType; typename LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); interpolator->SetInputImage( reader->GetOutput() ); typedef itk::NearestNeighborInterpolateImageFunction NearestNeighborInterpolatorType; typename NearestNeighborInterpolatorType::Pointer nn_interpolator = NearestNeighborInterpolatorType::New(); nn_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::BSplineInterpolateImageFunction BSplineInterpolatorType; typename BSplineInterpolatorType::Pointer bs_interpolator = BSplineInterpolatorType::New(); bs_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::GaussianInterpolateImageFunction GaussianInterpolatorType; typename GaussianInterpolatorType::Pointer g_interpolator = GaussianInterpolatorType::New(); g_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::WindowedSincInterpolateImageFunction HammingInterpolatorType; typename HammingInterpolatorType::Pointer sh_interpolator = HammingInterpolatorType::New(); sh_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::WindowedSincInterpolateImageFunction > Sinc1InterpolatorType; typename Sinc1InterpolatorType::Pointer sc_interpolator = Sinc1InterpolatorType::New(); sc_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::WindowedSincInterpolateImageFunction > Sinc2InterpolatorType; typename Sinc2InterpolatorType::Pointer sw_interpolator = Sinc2InterpolatorType::New(); sw_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::WindowedSincInterpolateImageFunction > Sinc3InterpolatorType; typename Sinc3InterpolatorType::Pointer sl_interpolator = Sinc3InterpolatorType::New(); sl_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::WindowedSincInterpolateImageFunction > Sinc4InterpolatorType; typename Sinc3InterpolatorType::Pointer sb_interpolator = Sinc3InterpolatorType::New(); sb_interpolator->SetInputImage( reader->GetOutput() ); typedef itk::ResampleImageFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); typename ResamplerType::SpacingType spacing; typename ResamplerType::SizeType size; std::vector sp = ConvertVector( std::string( argv[4] ) ); if( argc <= 5 || atoi( argv[5] ) == 0 ) { if ( sp.size() == 1 ) { spacing.Fill( sp[0] ); } else if ( sp.size() == ImageDimension ) { for ( unsigned int d = 0; d < ImageDimension; d++ ) { spacing[d] = sp[d]; } } else { std::cerr << "Invalid spacing." << std::endl; } for ( unsigned int i = 0; i < ImageDimension; i++ ) { RealType spacing_old = reader->GetOutput()->GetSpacing()[i]; RealType size_old = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i]; size[i] = static_cast( ( spacing_old * size_old ) / spacing[i] + 0.5 ); } } else { if ( sp.size() == 1 ) { size.Fill( static_cast( sp[0] ) ); } else if ( sp.size() == ImageDimension ) { for ( unsigned int d = 0; d < ImageDimension; d++ ) { size[d] = static_cast( sp[d] ); } } else { std::cerr << "Invalid size." << std::endl; } for ( unsigned int i = 0; i < ImageDimension; i++ ) { RealType spacing_old = reader->GetOutput()->GetSpacing()[i]; RealType size_old = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[i]; spacing[i] = spacing_old * static_cast( size_old - 1.0 ) / static_cast( size[i] - 1.0 ); } } char arg7 = '\0'; if( argc > 7 ) { arg7 = *argv[7]; } resampler->SetTransform( transform ); resampler->SetInterpolator( interpolator ); if( argc > 6 && atoi( argv[6] ) ) { switch( atoi( argv[6] ) ) { case 0: default: resampler->SetInterpolator( interpolator ); break; case 1: resampler->SetInterpolator( nn_interpolator ); break; case 2: { double sigma[ImageDimension]; for( unsigned int d = 0; d < ImageDimension; d++ ) { sigma[d] = reader->GetOutput()->GetSpacing()[d]; } double alpha = 1.0; if( argc > 7 ) { std::vector sg = ConvertVector( std::string( argv[7] ) ); for( unsigned int d = 0; d < ImageDimension; d++ ) { sigma[d] = sg[d]; } } if( argc > 8 ) { alpha = static_cast( atof( argv[8] ) ); } g_interpolator->SetParameters( sigma, alpha ); resampler->SetInterpolator( g_interpolator ); } break; case 3: { switch( arg7 ) { case 'h': default: resampler->SetInterpolator( sh_interpolator ); break; case 'c': resampler->SetInterpolator( sc_interpolator ); break; case 'l': resampler->SetInterpolator( sl_interpolator ); break; case 'w': resampler->SetInterpolator( sw_interpolator ); break; case 'b': resampler->SetInterpolator( sb_interpolator ); break; } } case 4: { if( argc > 7 && atoi( argv[7] ) >= 0 && atoi( argv[7] ) <= 5 ) { bs_interpolator->SetSplineOrder( atoi( argv[7] ) ); } else { bs_interpolator->SetSplineOrder( 3 ); } resampler->SetInterpolator( bs_interpolator ); break; } } } resampler->SetInput( reader->GetOutput() ); resampler->SetOutputSpacing( spacing ); resampler->SetOutputOrigin( reader->GetOutput()->GetOrigin() ); resampler->SetSize( size ); resampler->SetOutputDirection( reader->GetOutput()->GetDirection() ); resampler->Update(); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[3] ); writer->SetInput( resampler->GetOutput() ); writer->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc < 5 ) { std::cout << "Usage: " << argv[0] << " imageDimension inputImage " << "outputImage MxNxO [size=1,spacing=0] [interpolate type]" << std::endl; std::cout << " Interpolation type: " << std::endl; std::cout << " 0. linear (default)" << std::endl; std::cout << " 1. nn " << std::endl; std::cout << " 2. gaussian [sigma=imageSpacing] [alpha=1.0]" << std::endl; std::cout << " 3. windowedSinc [type = 'c'osine, 'w'elch, 'b'lackman, 'l'anczos, 'h'amming]" << std::endl; std::cout << " 4. B-Spline [order=3]" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: ResampleImage<2>( argc, argv ); break; case 3: ResampleImage<3>( argc, argv ); break; case 4: ResampleImage<4>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/ResampleImageBySpacing.cxx000066400000000000000000000256401147325206600233040ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ResampleImageBySpacing.cxx,v $ Language: C++ Date: $Date: 2009/03/31 21:22:00 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkResampleImageFilter.h" #include "itkIdentityTransform.h" #include "itkLinearInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkIntensityWindowingImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" template typename TImage::Pointer SmoothImage(typename TImage::Pointer image, float sig) { typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(sig); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(image); filter->Update(); return filter->GetOutput(); } int main( int argc, char * argv[] ) { if( argc < 5 ) { std::cerr << "Usage: " << std::endl; std::cerr << argv[0] << " ImageDimension inputImageFile outputImageFile outxspc outyspc {outzspacing} {dosmooth?} {addvox} {nn-interp?}" << std::endl; std::cout <<" addvox pads each dimension by addvox " << std::endl; std::cerr << " " << std::endl; // std::cout << " interp 0 = linear, 1 = nn " << std::endl; return 1; } unsigned int Dimension = atoi(argv[1]); if (Dimension == 2) { typedef float InputPixelType; typedef float InternalPixelType; typedef float OutputPixelType; typedef itk::Image< InputPixelType, 2 > InputImageType; typedef itk::Image< InternalPixelType, 2 > InternalImageType; typedef itk::Image< OutputPixelType, 2 > OutputImageType; typedef itk::ImageFileReader< InputImageType > ReaderType; typedef itk::ImageFileWriter< OutputImageType > WriterType; ReaderType::Pointer reader = ReaderType::New(); WriterType::Pointer writer = WriterType::New(); reader->SetFileName( argv[2] ); writer->SetFileName( argv[3] ); try { reader->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception caught!" << std::endl; std::cerr << excep << std::endl; } InputImageType::ConstPointer inputImage = reader->GetOutput(); const InputImageType::SpacingType& inputSpacing = inputImage->GetSpacing(); OutputImageType::SpacingType spacing; for (int i=0; i<2; i++) spacing[i]=inputSpacing[i]; std::cout << " spacing " << spacing << " dim " << 2 << std::endl; bool dosmooth=1; if (argc > 4) spacing[0] = atof(argv[4]); if (argc > 5) spacing[1] = atof(argv[5]); if (argc > 6) dosmooth = atoi(argv[6]); int addvox=0; if (argc > 7) addvox = atoi(argv[7]); bool nn=false; if (argc > 8) nn = atoi(argv[7]); std::cout << " spacing2 " << spacing << std::endl; InternalImageType::ConstPointer smoothedImage = reader->GetOutput(); if( dosmooth ) { for (int sm=0; sm<2; sm++) { typedef itk::RecursiveGaussianImageFilter< OutputImageType, OutputImageType > GaussianFilterType; GaussianFilterType::Pointer smootherX = GaussianFilterType::New(); smootherX->SetInput( smoothedImage ); float sig = 0; sig = atof(argv[4+sm])/inputSpacing[sm]-1.0; std::cout << " smoothing by : " << sig << " dir " << sm << std::endl; smootherX->SetSigma( sig ); smootherX->SetDirection( sm ); smootherX->SetNormalizeAcrossScale( false ); if (sig > 0 && dosmooth) { try { smootherX->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception catched !" << std::endl; std::cerr << excep << std::endl; } smoothedImage = smootherX->GetOutput(); } } } // InternalImageType::ConstPointer smoothedImage = smootherY->GetOutput(); // InternalImageType::ConstPointer smoothedImage = reader->GetOutput(); //smoothedImage =SmoothImage(reader->GetOutput() , ); typedef itk::ResampleImageFilter< InternalImageType, OutputImageType > ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); typedef itk::IdentityTransform< double, 2 > TransformType; typedef itk::LinearInterpolateImageFunction< InternalImageType, double > InterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< InternalImageType, double > InterpolatorType2; InterpolatorType::Pointer interpolator = InterpolatorType::New(); InterpolatorType2::Pointer interpolator2 = InterpolatorType2::New(); resampler->SetInterpolator( interpolator ); if (nn == 1 ) resampler->SetInterpolator( interpolator2 ); InternalImageType::IndexType ind; ind.Fill(1); resampler->SetDefaultPixelValue( inputImage->GetPixel(ind) ); // zero regions without source std::cout << " out space " << spacing << std::endl; resampler->SetOutputSpacing( spacing ); // Use the same origin resampler->SetOutputOrigin( inputImage->GetOrigin() ); // Use the same origin resampler->SetOutputDirection( inputImage->GetDirection() ); InputImageType::SizeType inputSize = inputImage->GetLargestPossibleRegion().GetSize(); typedef InputImageType::SizeType::SizeValueType SizeValueType; InputImageType::SizeType size; for (int i=0; i<2; i++) size[i] = static_cast(inputSize[i] * inputSpacing[i] / spacing[i]+addvox); std::cout << " output size " << size << " spc " << spacing << std::endl; resampler->SetSize( size ); resampler->SetInput( smoothedImage ); writer->SetInput( resampler->GetOutput() ); TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); resampler->SetTransform( transform ); try { writer->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception catched !" << std::endl; std::cerr << excep << std::endl; } } if (Dimension == 3) { typedef float InputPixelType; typedef float InternalPixelType; typedef float OutputPixelType; typedef itk::Image< InputPixelType, 3 > InputImageType; typedef itk::Image< InternalPixelType, 3 > InternalImageType; typedef itk::Image< OutputPixelType, 3 > OutputImageType; typedef itk::ImageFileReader< InputImageType > ReaderType; typedef itk::ImageFileWriter< OutputImageType > WriterType; ReaderType::Pointer reader = ReaderType::New(); WriterType::Pointer writer = WriterType::New(); reader->SetFileName( argv[2] ); writer->SetFileName( argv[3] ); try { reader->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception caught!" << std::endl; std::cerr << excep << std::endl; } InputImageType::ConstPointer inputImage = reader->GetOutput(); const InputImageType::SpacingType& inputSpacing = inputImage->GetSpacing(); OutputImageType::SpacingType spacing; for (int i=0; i<3; i++) spacing[i]=inputSpacing[i]; std::cout << " spacing " << spacing << " dim " << 3 << std::endl; bool dosmooth=1; if (argc > 4) spacing[0] = atof(argv[4]); if (argc > 5) spacing[1] = atof(argv[5]); if (argc > 6) spacing[2] = atof(argv[6]); if (argc > 7) dosmooth = atoi(argv[7]); int addvox=0; if (argc > 8) addvox = atoi(argv[8]); bool nn=false; if (argc > 9) nn = atoi(argv[9]); std::cout << " spacing2 " << spacing << std::endl; InternalImageType::ConstPointer smoothedImage = reader->GetOutput(); if( dosmooth ) { for (int sm=0; sm<3; sm++) { typedef itk::RecursiveGaussianImageFilter< OutputImageType, OutputImageType > GaussianFilterType; GaussianFilterType::Pointer smootherX = GaussianFilterType::New(); smootherX->SetInput( smoothedImage ); float sig = 0; sig = atof(argv[4+sm])/inputSpacing[sm]-1.0; std::cout << " smoothing by : " << sig << " dir " << sm << std::endl; smootherX->SetSigma( sig ); smootherX->SetDirection( sm ); smootherX->SetNormalizeAcrossScale( false ); if (sig > 0 && dosmooth) { try { smootherX->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception catched !" << std::endl; std::cerr << excep << std::endl; } smoothedImage = smootherX->GetOutput(); } } } // InternalImageType::ConstPointer smoothedImage = smootherY->GetOutput(); // InternalImageType::ConstPointer smoothedImage = reader->GetOutput(); //smoothedImage =SmoothImage(reader->GetOutput() , ); typedef itk::ResampleImageFilter< InternalImageType, OutputImageType > ResampleFilterType; ResampleFilterType::Pointer resampler = ResampleFilterType::New(); typedef itk::IdentityTransform< double, 3 > TransformType; typedef itk::LinearInterpolateImageFunction< InternalImageType, double > InterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< InternalImageType, double > InterpolatorType2; InterpolatorType::Pointer interpolator = InterpolatorType::New(); InterpolatorType2::Pointer interpolator2 = InterpolatorType2::New(); resampler->SetInterpolator( interpolator ); if (nn == 1 ) resampler->SetInterpolator( interpolator2 ); InternalImageType::IndexType ind; ind.Fill(1); resampler->SetDefaultPixelValue( inputImage->GetPixel(ind) ); // zero regions without source std::cout << " out space " << spacing << std::endl; resampler->SetOutputSpacing( spacing ); // Use the same origin resampler->SetOutputOrigin( inputImage->GetOrigin() ); // Use the same origin resampler->SetOutputDirection( inputImage->GetDirection() ); InputImageType::SizeType inputSize = inputImage->GetLargestPossibleRegion().GetSize(); typedef InputImageType::SizeType::SizeValueType SizeValueType; InputImageType::SizeType size; for (int i=0; i<3; i++) size[i] = static_cast(inputSize[i] * inputSpacing[i] / spacing[i]+addvox); std::cout << " output size " << size << " spc " << spacing << std::endl; resampler->SetSize( size ); resampler->SetInput( smoothedImage ); writer->SetInput( resampler->GetOutput() ); TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); resampler->SetTransform( transform ); try { writer->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << "Exception catched !" << std::endl; std::cerr << excep << std::endl; } } return 0; } ants-1.9.2+svn680.dfsg/Examples/ResetDirection.cxx000066400000000000000000000067351147325206600217200ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ResetDirection.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.3 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" // #include "../itkAvants.DefineDimension" template int ResetDirection(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " infile.nii outfile.nii " << std::endl; return 1; } typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); typename OutImageType::Pointer outim = reader->GetOutput(); typename OutImageType::DirectionType direction=outim->GetDirection(); //direction->SetIdentity(); direction.Fill(0); for (unsigned int i=0;i Iterator; typename ImageType::Pointer varimage=ImageType::New(); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( outim->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(outim->GetSpacing()); varimage->SetOrigin(outim->GetOrigin()); varimage->SetDirection( direction ); Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) vfIter2.Set(outim->GetPixel(vfIter2.GetIndex())); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput( varimage ); writer->Update(); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " infile.nii outfile.nii " << std::endl; return 1; } // Get the image dimension std::string fn = std::string(argv[1]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO( fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); switch ( imageIO->GetNumberOfDimensions() ) { case 2: ResetDirection<2>(argc,argv); break; case 3: ResetDirection<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/SetDirectionByMatrix.cxx000066400000000000000000000076161147325206600230500ustar00rootroot00000000000000/* * ResetDirection2.cxx * * Created on: Nov 14, 2008 * Author: songgang */ /*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ResetDirection2.cxx,v $ Language: C++ Date: $Date: 2008/11/14 20:47:46 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" // #include "../itkAvants.DefineDimension" template int ResetDirection(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " infile.nii outfile.nii direction matrix in a row " << std::endl; return 1; } typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); typename OutImageType::Pointer outim = reader->GetOutput(); typename OutImageType::DirectionType direction=outim->GetDirection(); //direction->SetIdentity(); // direction.Fill(0); // for (unsigned int i=0;iSetFileName(fn.c_str()); imageIO->ReadImageInformation(); switch ( imageIO->GetNumberOfDimensions() ) { case 2: ResetDirection<2>(argc,argv); break; case 3: ResetDirection<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/SetOrigin.cxx000066400000000000000000000065611147325206600206750ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: SetOrigin.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.19 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" template int SetOrigin(int argc, char *argv[]) { typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); typename OutImageType::Pointer outim = reader->GetOutput(); typename OutImageType::PointType orig = outim->GetOrigin(); std::cout << " Old Orig " << outim->GetOrigin(); if (argc > 3) orig[0]=atof(argv[3]); if (argc > 4) orig[1]=atof(argv[4]); if (argc > 5) orig[2]=atof(argv[5]); std::cout <<" New Orig " << orig << std::endl; outim->SetOrigin(orig); typedef itk::ImageRegionIteratorWithIndex Iterator; typename ImageType::Pointer varimage=ImageType::New(); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( outim->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(outim->GetSpacing()); varimage->SetOrigin(orig); varimage->SetDirection( outim->GetDirection()); Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) vfIter2.Set(outim->GetPixel(vfIter2.GetIndex())); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput( varimage ); writer->Update(); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " Dimension infile.hdr outfile.nii OriginX OriginY {OriginZ} " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: SetOrigin<2>(argc-1,argv+1); break; case 3: SetOrigin<3>(argc-1,argv+1); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/SetSpacing.cxx000066400000000000000000000064121147325206600210250ustar00rootroot00000000000000/* * SetSpacing.cxx * * Created on: Mar 5, 2009 * Author: songgang */ /*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: SetSpacing.cxx,v $ Language: C++ Date: $Date: 2009/03/06 03:57:48 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include #include #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkCastImageFilter.h" #include "itkRescaleIntensityImageFilter.h" template int SetSpacing(int argc, char *argv[]) { typedef float outPixelType; typedef float floatPixelType; typedef float inPixelType; typedef itk::Image ImageType; typedef itk::Image IntermediateType; typedef itk::Image OutImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(argv[1]); reader->Update(); typename OutImageType::Pointer outim = reader->GetOutput(); typename OutImageType::SpacingType spacing = outim->GetSpacing(); std::cout << " Old Spacing " << outim->GetSpacing(); if (argc > 3) spacing[0]=atof(argv[3]); if (argc > 4) spacing[1]=atof(argv[4]); if (argc > 5) spacing[2]=atof(argv[5]); std::cout <<" New Spacing " << spacing << std::endl; typedef itk::ImageRegionIteratorWithIndex Iterator; typename ImageType::Pointer varimage=ImageType::New(); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( outim->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( outim->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(spacing); varimage->SetOrigin(outim->GetOrigin()); varimage->SetDirection( outim->GetDirection()); Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) vfIter2.Set(outim->GetPixel(vfIter2.GetIndex())); typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[2]); writer->SetInput( varimage ); writer->Update(); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 3 ) { std::cout << "Usage: " << argv[0] << " Dimension infile.hdr outfile.nii SpacingX SpacingY {SpacingZ} " << std::endl; return 1; } // Get the image dimension switch( atoi(argv[1])) { case 2: SetSpacing<2>(argc-1,argv+1); break; case 3: SetSpacing<3>(argc-1,argv+1); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/SmoothImage.cxx000066400000000000000000000070121147325206600211760ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: SmoothImage.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "itkMedianImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" #include "ReadWriteImage.h" template int SmoothImage(int argc, char *argv[]) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef itk::AffineTransform AffineTransformType; typedef itk::LinearInterpolateImageFunction InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::ImageRegionIteratorWithIndex Iterator; std::string fn1 = std::string(argv[2]); float sigma=atof(argv[3]); typename ImageType::Pointer image1 = NULL; typename ImageType::Pointer varimage = NULL; ReadImage(image1, argv[2]); typedef itk::DiscreteGaussianImageFilter dgf; typedef itk::MedianImageFilter medf; typename dgf::Pointer filter = dgf::New(); typename medf::Pointer filter2 = medf::New(); bool usespacing=false; if (argc > 5) usespacing=atoi(argv[5]); bool usemedian=false; if (argc > 6) usemedian=atoi(argv[6]); if (!usespacing) filter->SetUseImageSpacingOff(); else filter->SetUseImageSpacingOn(); if ( !usemedian) { filter->SetVariance(sigma*sigma); filter->SetMaximumError(.01f); filter->SetInput(image1); filter->Update(); varimage=filter->GetOutput(); } else { typename ImageType::SizeType rad; rad.Fill((long unsigned int) sigma); filter2->SetRadius(rad); filter2->SetInput(image1); filter2->Update(); varimage=filter2->GetOutput(); } typename writertype::Pointer writer = writertype::New(); writer->SetFileName(argv[4]); writer->SetInput( varimage ); writer->Write(); return 0; } int main(int argc, char *argv[]) { if ( argc < 4 ) { std::cout << "Usage: "<< std::endl; std::cout << argv[0] << " ImageDimension image.ext smoothingsigma outimage.ext {sigma-is-in-spacing-coordinates-0/1} {medianfilter-0/1}" << std::endl; std::cout <<" if median, then sigma means radius of filtering " << std::endl; return 1; } switch ( atoi(argv[1]) ) { case 2: SmoothImage<2>(argc,argv); break; case 3: SmoothImage<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/StackSlices.cxx000066400000000000000000000161451147325206600212010ustar00rootroot00000000000000/*========================================================================= Program: ITK General Module: $RCSfile: StackSlices.cxx,v $ Language: C++ Date: $Date: 2009/04/02 19:55:26 $ Version: $Revision: 1.22 $ Author: Jeffrey T. Duda (jtduda@seas.upenn.edu) Institution: PICSL This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkExtractImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "ReadWriteImage.h" /* FlipScalarVolume * This program takes a volume and flips it along the * indicated axes */ int main( int argc, char *argv[] ) { // Pixel and Image typedefs typedef float PixelType; typedef itk::Image ImageType; typedef itk::Image SliceType; typedef itk::ImageFileReader ReaderType; typedef itk::ImageFileWriter WriterType; typedef itk::ExtractImageFilter ExtractFilterType; typedef itk::ImageRegionIteratorWithIndex ImageIt; typedef itk::ImageRegionIteratorWithIndex SliceIt; // Check for valid input paramters if (argc < 5) { std::cout << "Usage: " << argv[0] << " outputvolume x y z inputvolumes" << std::endl; return 1; } char * stackName = argv[1]; int dimVars[3]; dimVars[0] = atoi(argv[2]); dimVars[1] = atoi(argv[3]); dimVars[2] = atoi(argv[4]); int dim = -1; int slice = -1; // which dim to extract slice from for (unsigned int i=0; i<3; i++) { if (dimVars[i] > -1) { if ( (dim > -1) || (slice > -1) ) { std::cerr << "Can only choose slice from 1 dimension" << std::endl; return EXIT_FAILURE; } dim = i; slice = dimVars[i]; } } unsigned long nSlices = argc-5; //std::cout << nSlices << std::endl; ReaderType::Pointer firstReader = ReaderType::New(); firstReader->SetFileName( argv[5] ); firstReader->Update(); std::cout <<" Slice 0 :: " << std::string(argv[5]) << std::endl; ImageType::Pointer stack = ImageType::New(); ImageType::RegionType region = firstReader->GetOutput()->GetLargestPossibleRegion(); region.SetSize(dim, nSlices); stack->SetRegions(region); stack->Allocate(); SliceType::SizeType size; size.Fill(0); SliceType::IndexType index2d; if (dim == 0){ size[0]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1]; size[1]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[2]; } if (dim == 1){ size[0]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0]; size[1]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[2]; } if (dim == 2){ size[0]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0]; size[1]=firstReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1]; } SliceType::Pointer stack2 = SliceType::New(); SliceType::RegionType region2; region2.SetSize(size); stack2->SetRegions(region2); stack2->Allocate(); // std::cout << region << std::endl; ImageType::RegionType extractRegion = stack->GetLargestPossibleRegion(); extractRegion.SetSize(dim, 0); extractRegion.SetIndex(dim, slice); ExtractFilterType::Pointer extractFilter = ExtractFilterType::New(); extractFilter->SetInput( firstReader->GetOutput() ); extractFilter->SetExtractionRegion( extractRegion ); extractFilter->Update(); SliceIt it1(extractFilter->GetOutput(), extractFilter->GetOutput()->GetLargestPossibleRegion()); float mean = 0.0, ct=1; while (!it1.IsAtEnd()) { float val=it1.Value(); if (val > 0) { mean+=it1.Value(); ct++; } ++it1; } mean/=ct; std::cout << " Mean " << mean << std::endl; mean=1; it1.GoToBegin(); while (!it1.IsAtEnd()) { ImageType::IndexType index; index.Fill(0); if (dim == 0) { index[0] = 0; index[1] = it1.GetIndex()[0]; index[2] = it1.GetIndex()[1]; } if (dim == 1) { index[0] = it1.GetIndex()[0]; index[1] = 0; index[2] = it1.GetIndex()[1]; } if (dim == 2) { index[0] = it1.GetIndex()[0]; index[1] = it1.GetIndex()[1]; index[2] = 0; } index2d[0]=it1.GetIndex()[0]; index2d[1]=it1.GetIndex()[1]; stack->SetPixel(index, it1.Value()/mean); stack2->SetPixel(index2d,it1.Value()/mean); ++it1; } if (nSlices == 1 ) { std::cout << " write slice " << std::endl; WriteImage(stack2,stackName); return 0; } //std::cout << "Stacking." << std::flush; for (unsigned int i=1; iSetFileName( argv[5+i] ); reader->Update(); std::cout <<" Slice "<< i << " :: " << std::string(argv[5+i]) << std::endl; // std::cout << reader->GetOutput()->GetLargestPossibleRegion().GetSize() << std::endl; ExtractFilterType::Pointer extract = ExtractFilterType::New(); extract->SetInput( reader->GetOutput() ); extract->SetExtractionRegion( extractRegion ); extract->Update(); SliceIt it(extract->GetOutput(), extract->GetOutput()->GetLargestPossibleRegion()); float mean = 0.0, ct=1; while (!it.IsAtEnd()) { mean+=it.Value(); ct++; ++it; } mean/=ct; std::cout << " Mean " << mean << std::endl; mean=1; it.GoToBegin(); while (!it.IsAtEnd()) { ImageType::IndexType index; index.Fill(0); if (dim == 0) { index[0] = i; index[1] = it.GetIndex()[0]; index[2] = it.GetIndex()[1]; } if (dim == 1) { index[0] = it.GetIndex()[0]; index[1] = i; index[2] = it.GetIndex()[1]; } if (dim == 2) { index[0] = it.GetIndex()[0]; index[1] = it.GetIndex()[1]; index[2] = i; } stack->SetPixel(index, it.Value()/mean); ++it; } //std::cout << i << "." << std::flush; } //std::cout << "Done" << std::endl; WriterType::Pointer writer = WriterType::New(); writer->SetFileName( stackName ); writer->SetInput( stack ); writer->Update(); // Input parameters // char * inputName = argv[1]; // unsigned int flip_x = atoi( argv[2] ); // unsigned int flip_y = atoi( argv[3] ); // unsigned int flip_z = atoi( argv[4] ); // char * outputName = argv[5]; // ReaderType::Pointer reader = ReaderType::New(); // reader->SetFileName( inputName ); // reader->Update(); // // flip in desired directions for correct display // FlipFilterType::Pointer flip = FlipFilterType::New(); // FlipFilterType::FlipAxesArrayType flipOver; // flipOver[0] = flip_x; // flipOver[1] = flip_y; // flipOver[2] = flip_z; // flip->SetInput( reader->GetOutput() ); // flip->SetFlipAxes( flipOver ); // flip->Update(); // // write output // WriterType::Pointer writer = WriterType::New(); // writer->SetInput( flip->GetOutput() ); // writer->SetFileName( outputName ); // writer->Update(); return 0; } ants-1.9.2+svn680.dfsg/Examples/StudentsTestOnImages.cxx000066400000000000000000000353071147325206600230660ustar00rootroot00000000000000 #include #include #include #include #include #include #include #include #include #include #include #include "ReadWriteImage.h" //#include "itkSampleFalseDiscoveryRateCorrectionFilter.h" #include #include #include #include #include "itkTDistribution.h" #include "vnl/vnl_math.h" #include "vnl/vnl_erf.h" // for computing F distribution extern "C" double dbetai_(double *x, double *pin, double *qin); extern "C" double dgamma_(double *x); typedef struct { double statVal; int index; } StatElement; int smallerStatElem(StatElement * elem1, StatElement * elem2) // comparison function for sorting { if (elem1->statVal > elem2->statVal) return 1; else if (elem1->statVal < elem2->statVal) return -1; else return 0; } template void ReadImage(itk::SmartPointer &target, const char *file, bool copy) { // std::cout << " reading b " << std::string(file) << std::endl; typedef itk::ImageFileReader readertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(file); reader->Update(); if (!copy) target=(reader->GetOutput() ); else { typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( target, target->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { vfIter2.Set( reader->GetOutput()->GetPixel(vfIter2.GetIndex() )); } } } #define GROUPALABEL 0 #define GROUPBLABEL 1 typedef struct { int randNum; int index; } PermElement; void generatePerm(int length, int * genPerm); // generate a permutation of numbers from 0 to length-1 void generatePermGroup(int * groupID, int lengthGroupA, int lengthGroupB, int * genGroupID); // generate a permutation of group assignments int smallerPermElem(PermElement * elem1, PermElement * elem2); static int first = 0; void generatePermGroup(int * groupID, int lengthGroupA, int lengthGroupB, int * genGroupID) // generate a permutation of group assignments { int numSubjects = lengthGroupA + lengthGroupB; if (!first) { first = 1; srand(time(NULL)); //cout << "generatePermGroup called" << endl; } int * newPerm = new int [numSubjects]; generatePerm(numSubjects, newPerm); for (int i=0; irandNum > elem2->randNum) return 1; else if (elem1->randNum < elem2->randNum) return -1; else return 0; } double computeQuantile(int numObs, double * stat, double quantile) // computes the value in the provided statistic for the given quantile value // // numObs = Number of Observations // stat = double array[numObs ] contains the test statisticss { static int first = 0; if (!first) { first = 1; srand(time(NULL)); } StatElement * sortStat= new StatElement[numObs]; for (int perm = 0; perm < numObs; perm++) { sortStat[perm].statVal = stat[perm]; sortStat[perm].index = perm; } // sort, smallest first qsort(sortStat, numObs, sizeof(StatElement), (int (*) (const void *, const void *)) smallerStatElem); // index at value double quantindex = (double) numObs * quantile; if (quantile == 1.0 ) quantindex = numObs; double retval = stat[sortStat[(int) quantindex].index]; delete sortStat; return retval; } void computePermStatPval(int numFeatures, int numPerms, double * permStat, double * permStatPval) // computes the Pval for all permutation statistics // the p-val is computed as the percentual ordered rank over all permutations // // numFeatures = Number of scalar features per Subject // numPerms = Number of Permutations // permStat = double array[numPerms * numFeatures] contains the test statistics // permStatPval = double array [numPerms * numFeatures] returns the p-val of the statistics { static int first = 0; if (!first) { first = 1; srand(time(NULL)); } int feat; int perm; StatElement * sortPermStat= new StatElement[numPerms]; for (feat = 0; feat < numFeatures; feat++) { for (perm = 0; perm < numPerms; perm++) { sortPermStat[perm].statVal = permStat[perm * numFeatures + feat]; sortPermStat[perm].index = perm; } // sort, smallest first qsort(sortPermStat, numPerms, sizeof(StatElement), (int (*) (const void *, const void *)) smallerStatElem); double prevPval = 0; double curPval = 0; for (perm = 0 ; perm < numPerms; perm++) { // percentual rank 0..1 -> cumulative probability -> p-val double nextPval = 1.0 - (double) (perm+1) / (double) numPerms; int curIndex = sortPermStat[perm].index; if ((perm == 0) || (sortPermStat[perm].statVal != sortPermStat[perm-1].statVal)) { // current value is different from previous value (or first value), // thus step up p-value prevPval = curPval; curPval = nextPval; } permStatPval[curIndex * numFeatures + feat] = curPval; } } delete sortPermStat; } double decode_ieee_single( unsigned char *v, int natural_order) { unsigned char *data = v; int s, e; unsigned long src; long f; double value = 0.0; if (natural_order) { src = ((unsigned long)data[0] << 24) | ((unsigned long)data[1] << 16) | ((unsigned long)data[2] << 8) | ((unsigned long)data[3]); } else { src = ((unsigned long)data[3] << 24) | ((unsigned long)data[2] << 16) | ((unsigned long)data[1] << 8) | ((unsigned long)data[0]); } s = (src & 0x80000000UL) >> 31; e = (src & 0x7F800000UL) >> 23; f = (src & 0x007FFFFFUL); if (e == 255 && f != 0) { /* NaN (Not a Number) */ value = DBL_MAX; } else if (e == 255 && f == 0 && s == 1) { /* Negative infinity */ value = -DBL_MAX; } else if (e == 255 && f == 0 && s == 0) { /* Positive infinity */ value = DBL_MAX; } else if (e > 0 && e < 255) { /* Normal number */ f += 0x00800000UL; if (s) f = -f; value = ldexp(f, e - 150); } else if (e == 0 && f != 0) { /* Denormal number */ if (s) f = -f; value = ldexp(f, -149); } else if (e == 0 && f == 0 && s == 1) { /* Negative zero */ value = 0; } else if (e == 0 && f == 0 && s == 0) { /* Positive zero */ value = 0; } else { /* Never happens */ printf("s = %d, e = %d, f = %lu\n", s, e, f); assert(!"Woops, unhandled case in decode_ieee_single()"); } return value; } double factorial( double x) { if ( x <= 1) return 1; double fac=x; double n=fac-1; while ( n >= 1) { fac*=n; n=n-1; } return fac; } double betadist( double a , double b ) { double numer = factorial( a -1)*factorial(b-1); double denom =factorial( a+b-1); return (numer/denom); } double TTest(int numSubjects, int* groupLabel, double * featureValue ) { int numSubjA = 0; int numSubjB = 0; double meanA=0,meanB=0; // unsigned int GROUPALABEL=0; //unsigned int GROUPBLABEL=1; for (int subj = 0; subj < numSubjects; subj++) { if (groupLabel[subj] == GROUPALABEL) { numSubjA++; meanA += featureValue[subj]; } else if (groupLabel[subj] == GROUPBLABEL) { numSubjB++; meanB += featureValue[subj]; } else { std::cerr << " group label " << groupLabel[subj] << " does not exist" << std::endl; } } meanA/=(float)numSubjA; meanB/=(float)numSubjB; double varA=0,varB=0; for (int subj = 0; subj < numSubjects; subj++) { if (groupLabel[subj] == GROUPALABEL) { varA += (featureValue[subj] - meanA)*(featureValue[subj] - meanA); } else if (groupLabel[subj] == GROUPBLABEL) { varB += (featureValue[subj] - meanB)*(featureValue[subj] - meanB); } } float n1 = (float) numSubjA; float n2 = (float) numSubjB; varA/=(n1); // use n1 -1 for unbiased estimator, here assume normal distribution varB/=(n2); // use n2 - 1 " ... " // float sdA=sqrt(varA); // float sdB=sqrt(varB); // float df = n1 + n2 - 2; // unequal vars float denom = varA/n1 + varB/n2; // for equal vars // float var = ( (n1-1.)*newvar1 + (n2-1.)*newvar2 ) / df; // denom = var*(1.0/n1+1.0/n2); double tt=0; if ( denom > 0) tt = (meanA - meanB)/sqrt(denom); return tt; } template int StudentsTestOnImages(int argc, char *argv[]) { typedef float PixelType; typedef itk::Image ImageType; typename ImageType::Pointer mask=NULL; // ReadImage(mask, argv[1], false); unsigned int numSubjectsA=atoi(argv[3]); unsigned int numSubjectsB=atoi(argv[4]); unsigned int numSubjects= numSubjectsA+numSubjectsB; std::string outname=std::string(argv[2]); unsigned int numvals=numSubjects; int* groupLabel = new int [numSubjects]; for (unsigned int i=0; i < numSubjectsA; i++) groupLabel[i]=0; for (unsigned int i=numSubjectsA; i < numSubjects; i++) groupLabel[i]=1; double* feature = new double [numvals]; for (unsigned int i=0; i < numvals; i++) feature[i]=0; std::cout << " Numvals " << numvals << std::endl; // Get the image dimension std::string fn = std::string(argv[5]); itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(fn.c_str(), itk::ImageIOFactory::ReadMode); imageIO->SetFileName(fn.c_str()); imageIO->ReadImageInformation(); typename ImageType::SizeType size; typename ImageType::SpacingType spacing; typename ImageType::PointType origin; typename ImageType::DirectionType direction; std::vector axis; for(unsigned int i=0; iGetDimensions(i); // if (size[i] != mask->GetLargestPossibleRegion().GetSize()[i]) // { // std::cout << " mask not same size as data !! " << std::endl; // exit(0); //} spacing[i] = imageIO->GetSpacing(i); origin[i] = imageIO->GetOrigin(i); axis= imageIO->GetDirection(i); for (unsigned j=0; jGetNumberOfDimensions()) { direction[j][i] = axis[j]; } else { direction[j][i] = 0.0; } } } std::cout << " size " << size << std::endl; typename ImageType::RegionType region; region.SetSize(size ); typename ImageType::Pointer StatImage=ImageType::New(); StatImage->SetSpacing( spacing ); StatImage->SetOrigin( origin ); StatImage->SetLargestPossibleRegion(region ); StatImage->SetRequestedRegion( region ); StatImage->SetBufferedRegion( region ); StatImage->Allocate(); StatImage->FillBuffer(0); typename ImageType::Pointer PImage=ImageType::New(); PImage->SetSpacing( spacing ); PImage->SetOrigin( origin ); PImage->SetLargestPossibleRegion(region ); PImage->SetRequestedRegion( region ); PImage->SetBufferedRegion( region ); PImage->Allocate(); PImage->FillBuffer(0); // unsigned int sizeofpixel=sizeof(PixelType); std::vector imagestack; imagestack.resize(numvals); for (unsigned int j=0; j(imagestack[j] , ifn.c_str() ,false); } typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter(PImage , PImage->GetLargestPossibleRegion() ); unsigned long nvox=1; for (unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i]; unsigned long ct=0; unsigned long prog = nvox/20; std::cout << " NVals " << numvals << " NSub " << numSubjects << std::endl; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { typename ImageType::IndexType index=vfIter.GetIndex(); for (unsigned int subj=0; subjGetPixel(index); } if (ct % prog == 0) std::cout << " % " << (float) ct / (float) nvox << std::endl; double stat=0; // if (mask->GetPixel(index) >= 0.5) if (true) stat=TTest(numSubjects,groupLabel,feature); ct++; StatImage->SetPixel( index , stat); } typedef itk::Statistics::TDistribution DistributionType; typename DistributionType::Pointer distributionFunction = DistributionType::New(); // unsigned long dof=numSubjects-2; WriteImage(StatImage,outname.c_str()); std::string soutname=std::string("PVAL")+outname; //WriteImage(PImage,soutname.c_str()); return 1; } int main(int argc, char *argv[]) { std::cout << " df P = 0.05 P = 0.01 P = 0.001 " << std::endl; std::cout <<" 1 12.71 63.66 636.61 " << std::endl; std::cout << " 2 4.30 9.92 31.60 " << std::endl; std::cout << " 3 3.18 5.84 12.92" << std::endl; std::cout << " 4 2.78 4.60 8.61" << std::endl; std::cout << " 5 2.57 4.03 6.87" << std::endl; std::cout << " 6 2.45 3.71 5.96" << std::endl; std::cout << " 7 2.36 3.50 5.41" << std::endl; std::cout << " 8 2.31 3.36 5.04" << std::endl; std::cout << " 9 2.26 3.25 4.78" << std::endl; std::cout << " 10 2.23 3.17 4.59" << std::endl; std::cout << " 15 2.13 2.95 4.07" << std::endl; std::cout << " 20 2.09 2.85 3.85" << std::endl; std::cout << " 30 2.04 2.75 3.65" << std::endl; std::cout << " 50 2.01 2.68 3.50" << std::endl; std::cout << " 100 1.98 2.63 3.39 " << std::endl; if ( argc < 6 ) { std::cout << "Usage: " << argv[0] << " ImageDimension OutName NGroup1 NGroup2 ControlV1* SubjectV1* " << std::endl; std::cout << " Assume all images the same size " << std::endl; std::cout <<" Writes out an F-Statistic image " << std::endl; std::cout << " \n example call \n \n "; std::cout << argv[0] << " 2 TEST.nii.gz 4 8 FawtJandADCcon/*SUB.nii FawtJandADCsub/*SUB.nii \n "; return 1; } switch ( atoi(argv[1]) ) { case 2: StudentsTestOnImages<2>(argc,argv); break; case 3: StudentsTestOnImages<3>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/SurfaceBasedSmoothing.cxx000066400000000000000000000056741147325206600232150ustar00rootroot00000000000000 #include "itkBinaryThresholdImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkBinaryErodeImageFilter.h" #include "itkBinaryDilateImageFilter.h" #include "itkBinaryBallStructuringElement.h" #include "ReadWriteImage.h" #include "itkSurfaceImageCurvature.h" int main(int argc, char *argv[]) { if (argc < 3) { std::cout << " usage : " << argv[0] << " ImageToSmooth sigma SurfaceImage outname {numrepeatsofsmoothing}" << std::endl; std::cout << " We assume the SurfaceImage has a label == 1 that defines the surface " << std::endl; std::cout << " sigma defines the geodesic n-hood radius --- numrepeats allows one to use " << std::endl; std::cout << " a small geodesic n-hood repeatedly applied many times -- faster computation, same effect " << std::endl; return 0; } typedef itk::Image ImageType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::Image floatImageType; typedef itk::SurfaceImageCurvature ParamType; ParamType::Pointer Parameterizer=ParamType::New(); typedef itk::ImageFileReader< ImageType > ReaderType; typedef ImageType::PixelType PixType; // std::string fn="C://Data//brain15labelimage.img"; std::string ext=".nii"; float opt = 0; float sig=1.0; // float thresh=0.0; if (argc > 2) sig = atof( argv[2]); unsigned int numrepeats=0; if (argc > 5) numrepeats=atoi(argv[5]); ImageType::Pointer input; ReadImage(input, argv[1]); ImageType::Pointer surflabel; ReadImage(surflabel,argv[3]); Parameterizer->SetInput(surflabel); Parameterizer->SetFunctionImage(input); Parameterizer->SetNeighborhoodRadius( sig ); if (sig <= 0) sig=1.0; std::cout << " sigma " << sig << " thresh " << opt << std::endl; Parameterizer->SetSigma(sig); Parameterizer->SetUseGeodesicNeighborhood(true); Parameterizer->SetUseLabel(true); Parameterizer->SetThreshold(0.5); // Parameterizer->ComputeSurfaceArea(); // Parameterizer->IntegrateFunctionOverSurface(); Parameterizer->SetNeighborhoodRadius( sig ); std::cout <<" begin integration NOW " << std::endl; Parameterizer->IntegrateFunctionOverSurface(true); for (unsigned int i=0; iIntegrateFunctionOverSurface(true); std::cout <<" end integration " << std::endl; // Parameterizer->PostProcessGeometry(); // double mn=0.0; ImageType::Pointer output=NULL; floatImageType::Pointer smooth=NULL; smooth=Parameterizer->GetFunctionImage(); std::string fnname = std::string(argv[1]).substr(0,std::string(argv[1]).length()-4); std::string ofn = std::string(argv[4]); std::cout << " writing result " << ofn << std::endl; //writer->SetFileName(ofn.c_str()); // writer->SetInput( smooth ); WriteImage(smooth,ofn.c_str()); std::cout << " done writing "; return 1; } ants-1.9.2+svn680.dfsg/Examples/SurfaceCurvature.cxx000066400000000000000000000111461147325206600222560ustar00rootroot00000000000000 //#include "curvatureapp.h" #include "itkSurfaceCurvatureBase.h" #include "itkSurfaceImageCurvature.h" #include "ReadWriteImage.h" /* void test1() { typedef itk::SurfaceCurvatureBase ParamType; ParamType::Pointer Parameterizer=ParamType::New(); // Parameterizer->TestEstimateTangentPlane(p); Parameterizer->FindNeighborhood(); // Parameterizer->WeightedEstimateTangentPlane( Parameterizer->GetOrigin() ); Parameterizer->EstimateTangentPlane( Parameterizer->GetAveragePoint()); Parameterizer->PrintFrame(); // Parameterizer->SetOrigin(Parameterizer->GetAveragePoint()); for(int i=0; i<3; i++){ Parameterizer->ComputeWeightsAndDirectionalKappaAndAngles (Parameterizer->GetOrigin()); Parameterizer->ComputeFrame(Parameterizer->GetOrigin()); Parameterizer->EstimateCurvature(); Parameterizer->PrintFrame(); } Parameterizer->ComputeJoshiFrame(Parameterizer->GetOrigin()); Parameterizer->PrintFrame(); std::cout << " err 1 " << Parameterizer->ErrorEstimate(Parameterizer->GetOrigin()) << " err 2 " << Parameterizer->ErrorEstimate(Parameterizer->GetOrigin(),-1) << std::endl; } */ int main(int argc, char *argv[]) { if (argc < 3) { std::cout << " usage : SurfaceCurvature FileNameIn FileNameOut sigma option " << std::endl; std::cout << " e.g : SurfaceCurvature BrainIn.nii BrainOut.nii 3 0 " << std::endl; std::cout << " option 0 means just compute mean curvature from intensity " << std::endl; std::cout << " option 5 means characterize surface from intensity " << std::endl; return 0; } typedef itk::Image ImageType; typedef itk::Image floatImageType; enum { ImageDimension = ImageType::ImageDimension }; typedef itk::SurfaceImageCurvature ParamType; ParamType::Pointer Parameterizer=ParamType::New(); typedef ImageType::PixelType PixType; int opt = 0; float sig=1.0; if (argc > 3) sig = atof( argv[3]); std::cout << " sigma " << sig << std::endl; if (argc > 4) opt = (int) atoi(argv[4]); if ( opt < 0) { std::cout << " error " << std::endl; return 0; } ImageType::Pointer input; ReadImage(input,argv[1]); std::cout << " done reading " << std::string(argv[1]) << std::endl; // float ballradius = 2.0; // if (argc >= 6) ballradius = (float) atof(argv[5]); // if (ballradius > 0 && thresh > 0) input = SegmentImage(input, thresh, ballradius); Parameterizer->SetInput(input); // Parameterizer->ProcessLabelImage(); Parameterizer->SetNeighborhoodRadius( 1. ); // std::cout << " set sig " ; std::cin >> sig; if (sig <= 0.5) sig=1.66; std::cout << " sigma " << sig << " option " << opt << std::endl; Parameterizer->SetSigma(sig); if (opt == 1) { Parameterizer->SetUseLabel(true); Parameterizer->SetUseGeodesicNeighborhood(false); } else { Parameterizer->SetUseLabel(false); Parameterizer->SetUseGeodesicNeighborhood(false); float sign=1.0; if (opt == 3) sign=-1.0; std::cout << " setting outward direction as " << sign; Parameterizer->SetkSign(sign); Parameterizer->SetThreshold(0); } // Parameterizer->ComputeSurfaceArea(); // Parameterizer->IntegrateFunctionOverSurface(); // Parameterizer->IntegrateFunctionOverSurface(true); std::cout << " computing frame " << std::endl; if (opt != 5) Parameterizer->ComputeFrameOverDomain( 3 ); else Parameterizer->ComputeFrameOverDomain( opt ); // Parameterizer->SetNeighborhoodRadius( 2 ); // Parameterizer->LevelSetMeanCurvature(); // Parameterizer->SetNeighborhoodRadius( 2.9 ); // Parameterizer->IntegrateFunctionOverSurface(false); // Parameterizer->SetNeighborhoodRadius( 1.5 ); // Parameterizer->IntegrateFunctionOverSurface(true); // for (int i=0; i<1; i++) Parameterizer->PostProcessGeometry(); ImageType::Pointer output=NULL; // Parameterizer->GetFunctionImage()->SetSpacing( input->GetSpacing() ); // Parameterizer->GetFunctionImage()->SetDirection( input->GetDirection() ); // Parameterizer->GetFunctionImage()->SetOrigin( input->GetOrigin() ); // smooth->SetSpacing(reader->GetOutput()->GetSpacing()); // SmoothImage(Parameterizer->GetFunctionImage(),smooth,3); // NormalizeImage(smooth,output,mn); // NormalizeImage(Parameterizer->GetFunctionImage(),output,mn); WriteImage(Parameterizer->GetFunctionImage() , argv[2]); std::cout << " done writing "; return 1; } ants-1.9.2+svn680.dfsg/Examples/TensorDerivedImage.cxx000066400000000000000000000136021147325206600225040ustar00rootroot00000000000000/*========================================================================= Program: ITK General Module: $RCSfile: TensorDerivedImage.cxx,v $ Language: C++ Date: $Date: 2009/03/17 18:58:59 $ Version: $Revision: 1.2 $ Author: Jeffrey T. Duda (jtduda@seas.upenn.edu) Institution: PICSL This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include #include "itkImage.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" //#include "itkDiffusionTensor3D.h" #include "itkVector.h" //#include "itkTensorFractionalAnisotropyImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include #include "TensorFunctions.h" #include "ReadWriteImage.h" #include "itkRGBPixel.h" int main( int argc, char *argv[] ) { // Pixel and Image typedefs typedef float PixelType; typedef itk::Image ScalarImageType; typedef itk::ImageFileWriter WriterType; //typedef itk::Vector TensorType; typedef itk::SymmetricSecondRankTensor< float, 3 > TensorType; typedef itk::Image TensorImageType; typedef itk::ImageFileReader ReaderType; typedef itk::RGBPixel< float > ColorPixelType; typedef itk::Image ColorImageType; typedef itk::ImageFileWriter ColorWriterType; // Check for valid input paramters if (argc < 3) { std::cout << "Usage: " << argv[0] << " tensorvolume outputvolume outputtype" << std::endl; return 1; } // Input parameters char * inputName = argv[1]; char * outputName = argv[2]; std::string outType = argv[3]; TensorImageType::Pointer dtimg; ReadTensorImage(dtimg, inputName, false); std::cout << "tensor_image: " << inputName << std::endl; std::cout << "output_image: " << outputName << std::endl; ScalarImageType::Pointer outImage; ColorImageType::Pointer colorImage; if (outType == "DEC") { colorImage = ColorImageType::New(); colorImage->SetRegions(dtimg->GetLargestPossibleRegion() ); colorImage->SetSpacing(dtimg->GetSpacing()); colorImage->SetOrigin(dtimg->GetOrigin()); colorImage->SetDirection(dtimg->GetDirection()); colorImage->Allocate(); } else { outImage = ScalarImageType::New(); outImage->SetRegions(dtimg->GetLargestPossibleRegion() ); outImage->SetSpacing(dtimg->GetSpacing()); outImage->SetOrigin(dtimg->GetOrigin()); outImage->SetDirection(dtimg->GetDirection()); outImage->Allocate(); } itk::ImageRegionIteratorWithIndex inputIt(dtimg, dtimg->GetLargestPossibleRegion()); if ( (outType == "XX") || (outType == "xx") ) outType = "0"; if ( (outType == "XY") || (outType == "YX") || (outType == "xy") || (outType == "yx") ) outType = "1"; if ( (outType == "XZ") || (outType == "ZX") || (outType == "xz") || (outType == "zx") ) outType = "2"; if ( (outType == "YY") || (outType == "yy") ) outType = "3"; if ( (outType == "YZ") || (outType == "ZY") || (outType == "yz") || (outType == "zy") ) outType = "4"; if ( (outType == "ZZ") || (outType == "zz") ) outType = "5"; std::cout << "Calculating output..." << std::flush; while (!inputIt.IsAtEnd()) { if ((outType == "0") || (outType == "1") || (outType == "2") || (outType == "3") || (outType == "4") || (outType == "5")) { int idx = atoi(outType.c_str()); outImage->SetPixel(inputIt.GetIndex(),inputIt.Value()[idx]); } else if ((outType == "TR") || (outType == "MD")) { ScalarImageType::PixelType tr; tr = inputIt.Value()[0] + inputIt.Value()[2] + inputIt.Value()[5]; if (tr < 0) tr = 0; if (tr != tr) tr = 0; if (outType == "TR") { outImage->SetPixel(inputIt.GetIndex(),tr); } else { outImage->SetPixel(inputIt.GetIndex(),tr/3.0); } } else if (outType == "V") { //unsigned int invalids = 0; bool success=true; TensorType t = TensorLogAndExp(inputIt.Value(), true, success); int current=1; if (!success) current=0; outImage->SetPixel(inputIt.GetIndex(),current); //std::cout << "Found " << invalids << " invalid tensors" << std::endl; } else if (outType == "FA") { float fa = GetTensorFA(inputIt.Value()); outImage->SetPixel(inputIt.GetIndex(),fa); } else if (outType == "DEC") { colorImage->SetPixel(inputIt.GetIndex(), GetTensorRGB(inputIt.Value())); ++inputIt; } } std::cout << "Done. " << std::endl; if (outType == "DEC") { std::cout << "output origin: " << colorImage->GetOrigin() << std::endl; std::cout << "output size: " << colorImage->GetLargestPossibleRegion().GetSize() << std::endl; std::cout << "output spacing: " << colorImage->GetSpacing() << std::endl; std::cout << "output direction: " << colorImage->GetDirection() << std::endl; } else { std::cout << "output origin: " << outImage->GetOrigin() << std::endl; std::cout << "output size: " << outImage->GetLargestPossibleRegion().GetSize() << std::endl; std::cout << "output spacing: " << outImage->GetSpacing() << std::endl; std::cout << "output direction: " << outImage->GetDirection() << std::endl; } if (outType == "DEC") { ColorWriterType::Pointer writer = ColorWriterType::New(); writer->SetInput( colorImage ); writer->SetFileName( outputName ); writer->Update(); } else { WriterType::Pointer writer = WriterType::New(); writer->SetInput( outImage ); writer->SetFileName( outputName ); writer->Update(); } return 0; } ants-1.9.2+svn680.dfsg/Examples/ThresholdImage.cxx000066400000000000000000000206271147325206600216700ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: ThresholdImage.cxx,v $ Language: C++ Date: $Date: 2009/01/27 23:45:44 $ Version: $Revision: 1.20 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // Software Guide : BeginLatex // // This example illustrates how to deform an image using a BSplineTransform. // // \index{BSplineDeformableTransform} // // Software Guide : EndLatex #include #include #include // Software Guide : BeginCodeSnippet #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkNeighborhoodIterator.h" #include "itkImage.h" #include "itkResampleImageFilter.h" #include "itkLinearInterpolateImageFunction.h" #include "itkBSplineDeformableTransform.h" #include "itkExtractImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkDanielssonDistanceMapImageFilter.h" #include "itkMultiplyImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkOtsuMultipleThresholdsImageFilter.h" #include template typename TImage::Pointer MultiplyImage(typename TImage::Pointer image1, typename TImage::Pointer image2) { std::cout << " Multiply " << std::endl; // Begin Multiply Images typedef TImage tImageType; // output will be the speed image for FMM typedef itk::MultiplyImageFilter MultFilterType; typename MultFilterType::Pointer filter = MultFilterType::New(); filter->SetInput1( image1 ); filter->SetInput2( image2 ); filter->Update(); return filter->GetOutput(); // this is the speed image // write a function to threshold the speedimage so // if the dist is g.t. D then speed = 1 } template typename TImage::Pointer BinaryThreshold( typename TImage::PixelType low, typename TImage::PixelType high, typename TImage::PixelType replaceval, typename TImage::Pointer input) { std::cout << " Binary Thresh " << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::BinaryThresholdImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); if (high < low) high=255; float eps=1.e-6*low; inputThresholder->SetLowerThreshold((PixelType) low-eps ); inputThresholder->SetUpperThreshold((PixelType) high+eps); inputThresholder->Update(); return inputThresholder->GetOutput(); } template typename TImage::Pointer LabelSurface(typename TImage::PixelType foreground, typename TImage::PixelType newval, typename TImage::Pointer input) { std::cout << " Label Surf " << std::endl; typedef TImage ImageType; enum { ImageDimension = ImageType::ImageDimension }; typename ImageType::Pointer Image = ImageType::New(); Image->SetLargestPossibleRegion(input->GetLargestPossibleRegion() ); Image->SetBufferedRegion(input->GetLargestPossibleRegion()); Image->Allocate(); Image->SetSpacing(input->GetSpacing()); Image->SetOrigin(input->GetOrigin()); typedef itk::NeighborhoodIterator iteratorType; typename iteratorType::RadiusType rad; for (int j=0; jGetLargestPossibleRegion()); GHood.GoToBegin(); // std::cout << " foreg " << (int) foreground; while (!GHood.IsAtEnd()) { typename TImage::PixelType p = GHood.GetCenterPixel(); typename TImage::IndexType ind = GHood.GetIndex(); typename TImage::IndexType ind2; if ( p == foreground ) { bool atedge=false; for (int i = 0; i < GHood.Size(); i++) { ind2=GHood.GetIndex(i); float dist=0.0; for (int j=0; jSetPixel(ind,newval); else if ( p == foreground) Image->SetPixel(ind,0); } ++GHood; } return Image; } template typename TImage::Pointer DanielssonDistanceMap( typename TImage::PixelType pixlo, typename TImage::PixelType pixhi, typename TImage::Pointer input) { std::cout << " DDMap " << std::endl; typedef TImage ImageType; typedef itk::DanielssonDistanceMapImageFilter< ImageType, ImageType > FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->InputIsBinaryOn(); filter->SetUseImageSpacing(true); filter->SetInput(BinaryThreshold(pixlo,pixhi,pixhi,input)); filter->Update(); // std::string fn="C:\\Data\\temp.img"; // WriteImage(filter->GetOutput(),fn.c_str()); // fn="C:\\Data\\temp2.img"; // WriteImage(filter->GetVoronoiMap(),fn.c_str()); return filter->GetOutput(); } template typename TImage::Pointer OtsuThreshold( int NumberOfThresholds, typename TImage::Pointer input) { std::cout << " Otsu Thresh with " << NumberOfThresholds << " thresholds" << std::endl; typedef typename TImage::PixelType PixelType; // Begin Threshold Image typedef itk::OtsuMultipleThresholdsImageFilter InputThresholderType; typename InputThresholderType::Pointer inputThresholder = InputThresholderType::New(); inputThresholder->SetInput( input ); /* inputThresholder->SetInsideValue( replaceval ); int outval=0; if ((float) replaceval == (float) -1) outval=1; inputThresholder->SetOutsideValue( outval ); */ inputThresholder->SetNumberOfThresholds ( NumberOfThresholds ); inputThresholder->Update(); return inputThresholder->GetOutput(); } template int ThresholdImage( int argc, char * argv[] ) { // const unsigned int InImageDimension = AvantsImageDimension; typedef float PixelType; typedef itk::Image< PixelType, InImageDimension > FixedImageType; typedef itk::ImageFileReader< FixedImageType > FixedReaderType; typename FixedReaderType::Pointer fixedReader = FixedReaderType::New(); fixedReader->SetFileName( argv[2] ); typedef itk::ImageFileWriter< FixedImageType > MovingWriterType; typename MovingWriterType::Pointer movingWriter = MovingWriterType::New(); typename MovingWriterType::Pointer movingWriter2 = MovingWriterType::New(); movingWriter->SetFileName( argv[3] ); try { fixedReader->Update(); } catch( itk::ExceptionObject & excp ) { std::cerr << "Exception thrown " << std::endl; std::cerr << excp << std::endl; return EXIT_FAILURE; } // Label the surface of the image typename FixedImageType::Pointer thresh; std::string threshtype=std::string(argv[4]); if (strcmp(threshtype.c_str(),"Otsu") == 0 ) { thresh = OtsuThreshold(atoi(argv[5]),fixedReader->GetOutput()); } else thresh = BinaryThreshold(atof(argv[4]),atof(argv[5]),1.,fixedReader->GetOutput()); movingWriter->SetInput(thresh); movingWriter->Write( ); return EXIT_SUCCESS; } int main( int argc, char * argv[] ) { if( argc < 3 ) { std::cerr << "Usage: " << argv[0]; std::cerr << " ImageDimension ImageIn.ext outImage.ext threshlo threshhi " << std::endl; std::cerr << " ImageDimension ImageIn.ext outImage.ext Otsu NumberofThresholds " << std::endl; std::cout << " Inclusive thresholds " << std::endl; return 1; } // Get the image dimension switch ( atoi(argv[1])) { case 2: ThresholdImage<2>(argc,argv); break; case 3: ThresholdImage<3>(argc,argv); break; case 4: ThresholdImage<4>(argc,argv); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } return 0; } ants-1.9.2+svn680.dfsg/Examples/TileImages.cxx000077500000000000000000000056071147325206600210200ustar00rootroot00000000000000#include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkTileImageFilter.h" #include #include template TValue Convert( std::string optionString ) { TValue value; std::istringstream iss( optionString ); iss >> value; return value; } template std::vector ConvertVector( std::string optionString ) { std::vector values; std::string::size_type crosspos = optionString.find( 'x', 0 ); if ( crosspos == std::string::npos ) { values.push_back( Convert( optionString ) ); } else { std::string element = optionString.substr( 0, crosspos ) ; TValue value; std::istringstream iss( element ); iss >> value; values.push_back( value ); while ( crosspos != std::string::npos ) { std::string::size_type crossposfrom = crosspos; crosspos = optionString.find( 'x', crossposfrom + 1 ); if ( crosspos == std::string::npos ) { element = optionString.substr( crossposfrom + 1, optionString.length() ); } else { element = optionString.substr( crossposfrom + 1, crosspos ) ; } std::istringstream iss( element ); iss >> value; values.push_back( value ); } } return values; } template int TileImages( unsigned int argc, char *argv[] ) { typedef float PixelType; typedef itk::Image ImageType; typedef itk::TileImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); typename FilterType::LayoutArrayType array; std::vector layout = ConvertVector( std::string( argv[3] ) ); for ( unsigned int d = 0; d < ImageDimension; d++ ) { array[d] = layout[d]; } filter->SetLayout( array ); for ( unsigned int n = 4; n < argc; n++ ) { typedef itk::ImageFileReader ReaderType; typename ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[n] ); reader->Update(); filter->SetInput( n-4, reader->GetOutput() ); } filter->Update(); typedef itk::ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( argv[2] ); writer->SetInput( filter->GetOutput() ); writer->Update(); return 0; } int main( int argc, char *argv[] ) { if ( argc < 4 ) { std::cout << argv[0] << " imageDimension outputImage layout inputImage1 ... inputImageN" << std::endl; exit( 1 ); } switch( atoi( argv[1] ) ) { case 2: TileImages<2>( argc, argv ); break; case 3: TileImages<3>( argc, argv ); break; case 4: TileImages<4>( argc, argv ); break; default: std::cerr << "Unsupported dimension" << std::endl; exit( EXIT_FAILURE ); } } ants-1.9.2+svn680.dfsg/Examples/WarpImageMultiTransform.cxx000066400000000000000000001027501147325206600235520ustar00rootroot00000000000000#include #include #include "itkImageFileReader.h" #include "itkVector.h" #include "itkVectorImageFileReader.h" #include "itkImageFileWriter.h" #include "itkMatrixOffsetTransformBase.h" #include "itkTransformFactory.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkTransformFileReader.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" typedef enum{INVALID_FILE=1, AFFINE_FILE, DEFORMATION_FILE, IMAGE_AFFINE_HEADER, IDENTITY_TRANSFORM} TRAN_FILE_TYPE; typedef struct{ // char *filename; std::string filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; // void SetValue(char *filename, TRAN_FILE_TYPE file_type, bool do_affine_inv){ // this.filename = filename; // this.file_type = file_type; // this.do_affine_inv = do_affine_inv; // }; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; typedef struct{ bool use_NN_interpolator; bool use_BSpline_interpolator; bool use_TightestBoundingBox; char * reference_image_filename; bool use_RotationHeader; } MISC_OPT; void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue); void DisplayOpt(const TRAN_OPT &opt); TRAN_FILE_TYPE CheckFileType(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } if (extension==".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else{ return INVALID_FILE; } return AFFINE_FILE; } bool IsInverseDeformation(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "Inverse" ); if ( pos == std::string::npos ) return false; else return true; } void FilePartsWithgz(const std::string &filename, std::string &path, std::string &name, std::string &ext){ std::string extension; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); if (pos != std::string::npos){ extension = std::string( filepre, pos, filepre.length()-1 ) + ".gz"; filepre = std::string(filepre, 0, pos); } } } else { extension = std::string(""); } ext = extension; pos = filepre.rfind('/'); if ( pos != std::string::npos ){ path = std::string(filepre, 0, pos+1); name = std::string(filepre, pos+1, filepre.length()-1); } else { path = std::string(""); name = filepre; } // std::cout << "filename: " << filename << std::endl // << "path: " << path << std::endl // << "name: " << name << std::endl // << "ext: " << ext << std::endl; } bool CheckFileExistence(const char *str){ std::ifstream myfile(str); bool b = myfile.is_open(); myfile.close(); return b; } void SetAffineInvFlag(TRAN_OPT &opt, bool &set_current_affine_inv){ opt.do_affine_inv = set_current_affine_inv; if (set_current_affine_inv) set_current_affine_inv = false; } bool ParseInput(int argc, char **argv, char *&moving_image_filename, char *&output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ opt_queue.clear(); opt_queue.reserve(argc-2); misc_opt.reference_image_filename = NULL; misc_opt.use_BSpline_interpolator = false; misc_opt.use_TightestBoundingBox = false; misc_opt.use_RotationHeader = false; misc_opt.use_NN_interpolator=false; misc_opt.use_BSpline_interpolator=false; moving_image_filename = argv[0]; output_image_filename = argv[1]; int ind = 2; bool set_current_affine_inv = false; while(ind < argc){ if (strcmp(argv[ind], "--use-NN")==0) { misc_opt.use_NN_interpolator = true; } else if (strcmp(argv[ind], "--use-BSpline")==0) { misc_opt.use_BSpline_interpolator = true; } else if (strcmp(argv[ind], "-R")==0) { ind++; if(ind >= argc) return false; misc_opt.reference_image_filename = argv[ind]; } else if ((strcmp(argv[ind], "--tightest-bounding-box")==0) && (strcmp(argv[ind], "-R")!=0) ) { misc_opt.use_TightestBoundingBox = true; } else if (strcmp(argv[ind], "--reslice-by-header")==0) { misc_opt.use_RotationHeader = true; TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.do_affine_inv = false; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--Id")==0) { TRAN_OPT opt; opt.filename = "--Id"; opt.do_affine_inv = false; opt.file_type = IDENTITY_TRANSFORM; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--moving-image-header")==0 || strcmp(argv[ind], "-mh") ==0){ TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = moving_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--reference-image-header")==0 || strcmp(argv[ind], "-rh") ==0){ if (misc_opt.reference_image_filename==NULL){ std::cout << "reference image filename is not given yet. Specify it with -R before --reference-image-header / -rh." << std::endl; return false; } TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = misc_opt.reference_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "-i")==0) { set_current_affine_inv = true; } else if (strcmp(argv[ind], "--ANTS-prefix")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("Warp")+ext; x_deform_name = path+name+std::string("Warpxvec")+ext; if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } } else if (strcmp(argv[ind], "--ANTS-prefix-invert")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = true; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("InverseWarp.nii.gz"); x_deform_name = path+name+std::string("InverseWarpxvec.nii.gz"); if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } } else{ TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; if (opt.file_type == AFFINE_FILE) SetAffineInvFlag(opt, set_current_affine_inv); else if (opt.file_type == DEFORMATION_FILE && set_current_affine_inv){ std::cout << "Ignore inversion of non-affine file type! " << std::endl; std::cout << "opt.do_affine_inv:" << opt.do_affine_inv << std::endl; } opt_queue.push_back(opt); DisplayOpt(opt); } ind++; } if (misc_opt.use_RotationHeader) { // if (misc_opt.reference_image_filename) { // opt_queue[0].filename = misc_opt.reference_image_filename; // } else { opt_queue[0].filename = "--Id"; opt_queue[0].file_type = IDENTITY_TRANSFORM; opt_queue[0].do_affine_inv = false; // } // TRAN_OPT opt; // opt.file_type = IMAGE_AFFINE_HEADER; // opt.filename = moving_image_filename; // opt.do_affine_inv = true; // opt_queue.push_back(opt); // // std::cout << "Use Rotation Header!" << std::endl; } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue){ const int kQueueSize = opt_queue.size(); for(int i=0; i void GetIdentityTransform(AffineTransformPointer &aff){ typedef typename AffineTransformPointer::ObjectType AffineTransform; aff = AffineTransform::New(); aff->SetIdentity(); } template void GetAffineTransformFromImage(const ImageTypePointer& img, AffineTransformPointer &aff){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename ImageType::DirectionType DirectionType; typedef typename ImageType::PointType PointType; typedef typename ImageType::SpacingType SpacingType; typedef typename AffineTransformPointer::ObjectType::TranslationType VectorType; DirectionType direction = img->GetDirection(); SpacingType spacing = img->GetSpacing(); VectorType translation; // translation.Fill(0); for(unsigned int i=0; iGetOrigin()[i]; aff->SetMatrix(direction); // aff->SetCenter(pt); PointType pt; pt.Fill(0); aff->SetOffset(translation); aff->SetCenter(pt); std::cout << "aff from image:" << aff << std::endl; } template void GetLaregstSizeAfterWarp(WarperPointerType &warper, ImagePointerType &img, SizeType &largest_size, PointType &origin_warped){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::GetImageDimension(); // typedef typename ImageType::PointType PointType; typedef typename std::vector PointList; typedef typename ImageType::IndexType IndexType; // PointList pts_orig; PointList pts_warped; typename ImageType::SizeType imgsz; imgsz = img->GetLargestPossibleRegion().GetSize(); typename ImageType::SpacingType spacing; spacing = img->GetSpacing(); pts_warped.clear(); if (ImageDimension == 3){ for(int i=0; i<8; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; ind[2]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=0; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=0; break; case 4: ind[0]=0; ind[1]=0; ind[2]=imgsz[2]-1; break; case 5: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=imgsz[2]-1; break; case 6: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; case 7: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else if (ImageDimension == 2) { for(int i=0; i<4; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else { std::cout << "could not determine the dimension after warping for non 2D/3D volumes" << std::endl; exit(-1); } PointType pt_min, pt_max; pt_min = pts_warped[0]; pt_max = pts_warped[0]; for(unsigned int k=0; kpts_warped[k][i])?(pt_max[i]):(pts_warped[k][i]); } } for(int i=0; i void WarpImageMultiTransform(char *moving_image_filename, char *output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); reader_img->SetFileName(moving_image_filename); reader_img->Update(); typename ImageType::Pointer img_mov = ImageType::New(); img_mov = reader_img->GetOutput(); typename ImageType::Pointer img_ref; // = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (misc_opt.reference_image_filename){ reader_img_ref->SetFileName(misc_opt.reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } // else // img_ref = NULL; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(img_mov); warper->SetEdgePaddingValue( 0); if (misc_opt.use_NN_interpolator){ typedef typename itk::NearestNeighborInterpolateImageFunction NNInterpolateType; typename NNInterpolateType::Pointer interpolator_NN = NNInterpolateType::New(); std::cout << "User nearest neighbor interpolation (was Haha) " << std::endl; warper->SetInterpolator(interpolator_NN); } else if (misc_opt.use_BSpline_interpolator){ typedef typename itk::BSplineInterpolateImageFunction BSInterpolateType; typename BSInterpolateType::Pointer interpolator_BS = BSInterpolateType::New(); interpolator_BS->SetSplineOrder(3); std::cout << "User B-spline interpolation " << std::endl; warper->SetInterpolator(interpolator_BS); } else { typedef typename itk::LinearInterpolateImageFunction LinInterpolateType; typename LinInterpolateType::Pointer interpolator_LN = LinInterpolateType::New(); std::cout << "User Linear interpolation " << std::endl; warper->SetInterpolator(interpolator_LN); } typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; bool takeaffinv=false; unsigned int transcount=0; const int kOptQueueSize = opt_queue.size(); for(int i=0; iSetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast< AffineTransformType* > ((tran_reader->GetTransformList())->front().GetPointer()); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; takeaffinv=true; } // std::cout <<" aff " << transcount << std::endl; warper->PushBackAffineTransform(aff); if (transcount==0){ warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(img_mov->GetOrigin()); warper->SetOutputDirection(img_mov->GetDirection()); } transcount++; break; } case IDENTITY_TRANSFORM:{ typename AffineTransformType::Pointer aff; GetIdentityTransform(aff); // std::cout << " aff id" << transcount << std::endl; warper->PushBackAffineTransform(aff); transcount++; break; } case IMAGE_AFFINE_HEADER:{ typename AffineTransformType::Pointer aff = AffineTransformType::New(); typename ImageType::Pointer img_affine = ImageType::New(); typename ImageFileReaderType::Pointer reader_image_affine = ImageFileReaderType::New(); reader_image_affine->SetFileName(opt.filename); reader_image_affine->Update(); img_affine = reader_image_affine->GetOutput(); GetAffineTransformFromImage(img_affine, aff); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; takeaffinv=true; } // std::cout <<" aff from image header " << transcount << std::endl; warper->PushBackAffineTransform(aff); // if (transcount==0){ // warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); // warper->SetOutputSpacing(img_mov->GetSpacing()); // warper->SetOutputOrigin(img_mov->GetOrigin()); // warper->SetOutputDirection(img_mov->GetDirection()); // } transcount++; break; } case DEFORMATION_FILE:{ typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName( opt.filename ); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); warper->PushBackDeformationFieldTransform(field); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->SetOutputOrigin(field->GetOrigin()); warper->SetOutputSpacing(field->GetSpacing()); warper->SetOutputDirection(field->GetDirection()); transcount++; break; } default: std::cout << "Unknown file type!" << std::endl; } } //std::cout << " transcount " << transcount << std::endl; warper->PrintTransformList(); if ( transcount == 2 ) { std::cout << " We check the syntax of your call .... " << std::endl; const TRAN_OPT &opt1 = opt_queue[0]; const TRAN_OPT &opt2 = opt_queue[1]; if ( opt1.file_type == AFFINE_FILE && opt2.file_type == DEFORMATION_FILE ) { bool defisinv=IsInverseDeformation(opt2.filename.c_str()); if ( ! takeaffinv ) { std::cout << " Your 1st parameter should be an inverse affine map and the 2nd an InverseWarp --- exiting without applying warp. Check that , if using an inverse affine map, you pass the -i option before the Affine.txt." << std::endl; return ; } if ( ! defisinv ) { std::cout << " Your 2nd parameter should be an InverseWarp when your 1st parameter is an inverse affine map --- exiting without applying warp. " << std::endl; return ; } } if ( opt2.file_type == AFFINE_FILE && opt1.file_type == DEFORMATION_FILE ) { bool defisinv=IsInverseDeformation(opt1.filename.c_str()); if ( defisinv ) { std::cout << " Your 1st parameter should be a Warp (not Inverse) when your 2nd parameter is an affine map --- exiting without applying warp. " << std::endl; return ; } if ( takeaffinv ) { std::cout << " Your 2nd parameter should be a regular affine map (not inverted) if the 1st is a Warp --- exiting without applying warp. " << std::endl; return ; } } std::cout <<" syntax probably ok. " << std::endl; } else { std::cout << " You are doing something more complex -- we wont check syntax in this case " << std::endl; } if (img_ref.IsNotNull()){ warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); } else { if (misc_opt.use_TightestBoundingBox == true){ // compute the desired spacking after inputting all the transform files using the typename ImageType::SizeType largest_size; typename ImageType::PointType origin_warped; GetLaregstSizeAfterWarp(warper, img_mov, largest_size, origin_warped); warper->SetOutputSize(largest_size); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(origin_warped); typename ImageType::DirectionType d; d.SetIdentity(); warper->SetOutputDirection(d); } } std::cout << "output origin: " << warper->GetOutputOrigin() << std::endl; std::cout << "output size: " << warper->GetOutputSize() << std::endl; std::cout << "output spacing: " << warper->GetOutputSpacing() << std::endl; std::cout << "output direction: " << warper->GetOutputDirection() << std::endl; // warper->PrintTransformList(); warper->DetermineFirstDeformNoInterp(); warper->Update(); // { // typename ImageType::IndexType ind_orig, ind_warped; // ind_orig[0] = 128; // ind_orig[1] = 128; // ind_orig[2] = 16; // typename ImageType::PointType pt_orig, pt_warped; // warper->GetOutput()->TransformIndexToPhysicalPoint(ind_orig, pt_orig); // warper->MultiTransformSinglePoint(pt_orig, pt_warped); // img_mov->TransformPhysicalPointToIndex(pt_warped, ind_warped); // std::cout << "Transform output index " << ind_orig << "("<GetOutputSize()[i] * 0.5; // } // warper->MultiTransformSinglePoint(pt_in, pt_out); // std::cout << "pt_in=" << pt_in << " pt_out=" <GetOutput(); typedef itk::ImageFileWriter ImageFileWriterType; typename ImageFileWriterType::Pointer writer_img = ImageFileWriterType::New(); if (img_ref) img_output->SetDirection(img_ref->GetDirection()); writer_img->SetFileName(output_image_filename); writer_img->SetInput(img_output); writer_img->Update(); } int main(int argc, char **argv){ if (argc<=3) { std::cout << " \n " << std::endl; std::cout << "Usage: \n " << std::endl; // std::cout << argv[0] << " ImageDimension moving_image output_image [-R reference_image | --tightest-bounding-box] (--reslice-by-header) [--use-NN]" //<< "[--ANTS-prefix prefix-name | --ANTS-prefix-invert prefix-name] {[deformation_field | [-i] InverseAffineTransform.txt | --Id | [-i] --moving-image-header / -mh | [-i] --reference-image-header / -rh]} \n" << std::endl; std::cout << argv[0] << " ImageDimension moving_image output_image -R reference_image --use-NN SeriesOfTransformations--(See Below) " << std::endl; std::cout <<" SeriesOfTransformations --- " << argv[0] << " can apply, via concatenation, an unlimited number of transformations to your data ." << std::endl; std::cout << " Thus, SeriesOfTransformations may be an Affine transform followed by a warp another affine and then another warp. " << std::endl; std::cout << " Inverse affine transformations are invoked by calling -i MyAffine.txt " << std::endl; std::cout << " InverseWarps are invoked by passing the InverseWarp.nii.gz filename (see below for a note about this). " << std::endl; std::cout << std::endl; std::cout << " Example 1: Mapping a warped image into the reference_image domain by applying abcdWarpxvec.nii.gz/abcdWarpyvec.nii.gz/abcdWarpzvec.nii.gz and then abcdAffine.txt\n" << std::endl; std::cout << argv[0] << " 3 moving_image output_image -R reference_image abcdWarp.nii.gz abcdAffine.txt\n" << std::endl; std::cout << " Example 2: To map the fixed/reference_image warped into the moving_image domain by applying the inversion of abcdAffine.txt and then abcdInverseWarpxvec.nii.gz/abcdInverseWarpyvec.nii.gz/abcdInverseWarpzvec.nii.gz .\n" << std::endl; std::cout << argv[0] << " 3 reference_image output_image -R moving_image -i abcdAffine.txt abcdInverseWarp.nii.gz \n \n" << std::endl; std::cout <<" Note that the inverse maps (Ex. 2) are passed to this program in the reverse order of the forward maps (Ex. 1). " << std::endl; std::cout <<" This makes sense, geometrically ... see ANTS.pdf for visualization of this syntax." << std::endl; std::cout << std::endl; std::cout << " Compulsory arguments:\n " << std::endl; std::cout << " ImageDimension: 2 or 3 (for 2 or 3 Dimensional registration)\n " << std::endl; std::cout << " moving_image: the image to apply the transformation to\n " << std::endl; std::cout << " output_image: the resulting image\n \n " << std::endl; std::cout << " Optional arguments:\n " << std::endl; std::cout << " -R: reference_image space that you wish to warp INTO." << std::endl; std::cout << " --tightest-bounding-box: Computes the tightest bounding box using all the affine transformations. It will be overrided by -R reference_image if given." << std::endl; std::cout << " --reslice-by-header: equivalient to -i -mh, or -fh -i -mh if used together with -R. It uses the orientation matrix and origin encoded in the image file header. " << std::endl; std::cout << " It can be used together with -R. This is typically not used together with any other transforms.\n " << std::endl; std::cout << " --use-NN: Use Nearest Neighbor Interpolation. \n " << std::endl; std::cout << " --use-BSpline: Use 3rd order B-Spline Interpolation. \n " << std::endl; // std::cout << " --ANTS-prefix prefix-name: followed by a deformation field filename. \n " << std::endl; // std::cout << " --ANTS-prefix-invert: . \n" << std::endl; std::cout << " -i: will use the inversion of the following affine transform. \n " << std::endl; // std::cout << " --Id: use an identity transform. \n " << std::endl; // std::cout << " --moving-image-header or -mh: will use the orientation header of the moving image file. This is typically not used with --reslice-by-header.\n " << std::endl; // std::cout << " --reference-image-header or -rh: use the orientation matrix and origin encoded in the image file header. It can be used together with -R.\n " << std::endl; std::cout << " \n " << std::endl; // std::cout << " For ANTS users:" << std::endl; std::cout << " Other Example Usages:" << std::endl; std::cout << " Reslice the image: WarpImageMultiTransform 3 Imov.nii.gz Iout.nii.gz --tightest-bounding-box --reslice-by-header" << std::endl; std::cout << " Reslice the image to a reference image: WarpImageMultiTransform 3 Imov.nii.gz Iout.nii.gz -R Iref.nii.gz --tightest-bounding-box --reslice-by-header\n" << std::endl; std::cout << " Important Notes: " << std::endl; std::cout << " Prefixname \"abcd\" without any extension will use \".nii.gz\" by default" << std::endl; std::cout << " The abcdWarp and abcdInverseWarp do not exist. They are formed on the basis of abcd(Inverse)Warpxvec/yvec/zvec.nii.gz when calling " << argv[0] <<", yet you have to use them as if they exist." << std::endl; exit(0); } TRAN_OPT_QUEUE opt_queue; char *moving_image_filename = NULL; char *output_image_filename = NULL; MISC_OPT misc_opt; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc-2, argv+2, moving_image_filename, output_image_filename, opt_queue, misc_opt); if (is_parsing_ok){ std::cout << "moving_image_filename: " << moving_image_filename << std::endl; std::cout << "output_image_filename: " << output_image_filename << std::endl; std::cout << "reference_image_filename: "; if (misc_opt.reference_image_filename) std::cout << misc_opt.reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim){ case 2:{ WarpImageMultiTransform<2>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } case 3:{ WarpImageMultiTransform<3>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } } } else{ std::cout << "Input error!" << std::endl; } exit(0); } ants-1.9.2+svn680.dfsg/Examples/WarpTensorImageMultiTransform.cxx000066400000000000000000000722011147325206600247420ustar00rootroot00000000000000#include #include #include "itkImageFileReader.h" #include "itkVector.h" #include "itkVariableLengthVector.h" #include "itkVectorImageFileReader.h" #include "itkImageFileWriter.h" #include "itkMatrixOffsetTransformBase.h" #include "itkTransformFactory.h" #include "itkWarpTensorImageMultiTransformFilter.h" #include "itkTransformFileReader.h" #include "itkVectorNearestNeighborInterpolateImageFunction.h" #include "ReadWriteImage.h" #include "itkWarpImageMultiTransformFilter.h" typedef enum{INVALID_FILE=1, AFFINE_FILE, DEFORMATION_FILE, IMAGE_AFFINE_HEADER, IDENTITY_TRANSFORM} TRAN_FILE_TYPE; typedef struct{ // char *filename; std::string filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; // void SetValue(char *filename, TRAN_FILE_TYPE file_type, bool do_affine_inv){ // this.filename = filename; // this.file_type = file_type; // this.do_affine_inv = do_affine_inv; // }; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; typedef struct{ bool use_NN_interpolator; bool use_TightestBoundingBox; char * reference_image_filename; bool use_RotationHeader; } MISC_OPT; void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue); void DisplayOpt(const TRAN_OPT &opt); TRAN_FILE_TYPE CheckFileType(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } if (extension==".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else{ return INVALID_FILE; } return AFFINE_FILE; } void FilePartsWithgz(const std::string &filename, std::string &path, std::string &name, std::string &ext){ std::string extension; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); if (pos != std::string::npos){ extension = std::string( filepre, pos, filepre.length()-1 ) + ".gz"; filepre = std::string(filepre, 0, pos); } } } else { extension = std::string(""); } ext = extension; pos = filepre.rfind('/'); if ( pos != std::string::npos ){ path = std::string(filepre, 0, pos+1); name = std::string(filepre, pos+1, filepre.length()-1); } else { path = std::string(""); name = filepre; } // std::cout << "filename: " << filename << std::endl // << "path: " << path << std::endl // << "name: " << name << std::endl // << "ext: " << ext << std::endl; } bool CheckFileExistence(const char *str){ std::ifstream myfile(str); bool b = myfile.is_open(); myfile.close(); return b; } void SetAffineInvFlag(TRAN_OPT &opt, bool &set_current_affine_inv){ opt.do_affine_inv = set_current_affine_inv; if (set_current_affine_inv) set_current_affine_inv = false; } bool ParseInput(int argc, char **argv, char *&moving_image_filename, char *&output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ opt_queue.clear(); opt_queue.reserve(argc-2); misc_opt.reference_image_filename = NULL; misc_opt.use_NN_interpolator = false; misc_opt.use_TightestBoundingBox = false; misc_opt.use_RotationHeader = false; moving_image_filename = argv[0]; output_image_filename = argv[1]; int ind = 2; bool set_current_affine_inv = false; while(ind < argc){ if (strcmp(argv[ind], "--use-NN")==0) { misc_opt.use_NN_interpolator = true; } else if (strcmp(argv[ind], "-R")==0) { ind++; if(ind >= argc) return false; misc_opt.reference_image_filename = argv[ind]; } else if ((strcmp(argv[ind], "--tightest-bounding-box")==0) && (strcmp(argv[ind], "-R")!=0) ) { misc_opt.use_TightestBoundingBox = true; } else if (strcmp(argv[ind], "--reslice-by-header")==0) { misc_opt.use_RotationHeader = true; TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.do_affine_inv = false; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--Id")==0) { TRAN_OPT opt; opt.filename = "--Id"; opt.do_affine_inv = false; opt.file_type = IDENTITY_TRANSFORM; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--moving-image-header")==0 || strcmp(argv[ind], "-mh") ==0){ TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = moving_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--reference-image-header")==0 || strcmp(argv[ind], "-rh") ==0){ if (misc_opt.reference_image_filename==NULL){ std::cout << "reference image filename is not given yet. Specify it with -R before --reference-image-header / -rh." << std::endl; return false; } TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = misc_opt.reference_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "-i")==0) { set_current_affine_inv = true; } else if (strcmp(argv[ind], "--ANTS-prefix")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("Warp")+ext; x_deform_name = path+name+std::string("Warpxvec")+ext; if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } } else if (strcmp(argv[ind], "--ANTS-prefix-invert")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = true; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("InverseWarp.nii.gz"); x_deform_name = path+name+std::string("InverseWarpxvec.nii.gz"); if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } } else{ TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; if (opt.file_type == AFFINE_FILE) SetAffineInvFlag(opt, set_current_affine_inv); else if (opt.file_type == DEFORMATION_FILE && set_current_affine_inv){ std::cout << "Ignore inversion of non-affine file type! " << std::endl; std::cout << "opt.do_affine_inv:" << opt.do_affine_inv << std::endl; } opt_queue.push_back(opt); DisplayOpt(opt); } ind++; } if (misc_opt.use_RotationHeader) { // if (misc_opt.reference_image_filename) { // opt_queue[0].filename = misc_opt.reference_image_filename; // } else { opt_queue[0].filename = "--Id"; opt_queue[0].file_type = IDENTITY_TRANSFORM; opt_queue[0].do_affine_inv = false; // } // TRAN_OPT opt; // opt.file_type = IMAGE_AFFINE_HEADER; // opt.filename = moving_image_filename; // opt.do_affine_inv = true; // opt_queue.push_back(opt); // // std::cout << "Use Rotation Header!" << std::endl; } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue){ const int kQueueSize = opt_queue.size(); for(int i=0; i void GetIdentityTransform(AffineTransformPointer &aff){ typedef typename AffineTransformPointer::ObjectType AffineTransform; aff = AffineTransform::New(); aff->SetIdentity(); } template void GetAffineTransformFromImage(const ImageTypePointer& img, AffineTransformPointer &aff){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename ImageType::DirectionType DirectionType; typedef typename ImageType::PointType PointType; typedef typename ImageType::SpacingType SpacingType; typedef typename AffineTransformPointer::ObjectType::TranslationType VectorType; DirectionType direction = img->GetDirection(); SpacingType spacing = img->GetSpacing(); VectorType translation; // translation.Fill(0); for(unsigned int i=0; iGetOrigin()[i]; aff->SetMatrix(direction); // aff->SetCenter(pt); PointType pt; pt.Fill(0); aff->SetOffset(translation); aff->SetCenter(pt); std::cout << "aff from image:" << aff << std::endl; } template void GetLaregstSizeAfterWarp(WarperPointerType &warper, ImagePointerType &img, SizeType &largest_size, PointType &origin_warped){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::GetImageDimension(); // typedef typename ImageType::PointType PointType; typedef typename std::vector PointList; typedef typename ImageType::IndexType IndexType; // PointList pts_orig; PointList pts_warped; typename ImageType::SizeType imgsz; imgsz = img->GetLargestPossibleRegion().GetSize(); typename ImageType::SpacingType spacing; spacing = img->GetSpacing(); pts_warped.clear(); if (ImageDimension == 3){ for(int i=0; i<8; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; ind[2]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=0; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=0; break; case 4: ind[0]=0; ind[1]=0; ind[2]=imgsz[2]-1; break; case 5: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=imgsz[2]-1; break; case 6: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; case 7: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else if (ImageDimension == 2) { for(int i=0; i<4; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else { std::cout << "could not determine the dimension after warping for non 2D/3D volumes" << std::endl; exit(-1); } PointType pt_min, pt_max; pt_min = pts_warped[0]; pt_max = pts_warped[0]; for(unsigned int k=0; kpts_warped[k][i])?(pt_max[i]):(pts_warped[k][i]); } } for(int i=0; i void WarpImageMultiTransform(char *moving_image_filename, char *output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ //typedef itk::Vector PixelType; typedef itk::SymmetricSecondRankTensor< float, 3 > PixelType; typedef itk::Image TensorImageType; typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; //typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); //reader_img->SetFileName(moving_image_filename); //reader_img->Update(); //typename ImageType::Pointer img_mov = ImageType::New(); //img_mov = reader_img->GetOutput(); typename TensorImageType::Pointer img_mov; ReadTensorImage(img_mov,moving_image_filename,true); typename ImageType::Pointer img_ref; // = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (misc_opt.reference_image_filename){ reader_img_ref->SetFileName(misc_opt.reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } typename TensorImageType::Pointer img_output = TensorImageType::New(); img_output->SetLargestPossibleRegion( img_ref->GetLargestPossibleRegion() ); img_output->SetBufferedRegion( img_ref->GetLargestPossibleRegion() ); img_output->SetLargestPossibleRegion( img_ref->GetLargestPossibleRegion() ); img_output->Allocate(); img_output->SetSpacing(img_ref->GetSpacing()); img_output->SetOrigin(img_ref->GetOrigin()); img_output->SetDirection(img_ref->GetDirection()); // else // img_ref = NULL; for (unsigned int tensdim=0; tensdim < 6; tensdim++) { typedef itk::VectorIndexSelectionCastImageFilter IndexSelectCasterType; typename IndexSelectCasterType::Pointer fieldCaster = IndexSelectCasterType::New(); fieldCaster->SetInput( img_mov ); fieldCaster->SetIndex( tensdim ); fieldCaster->Update(); typename ImageType::Pointer tenscomponent=fieldCaster->GetOutput(); tenscomponent->SetSpacing(img_mov->GetSpacing()); tenscomponent->SetOrigin(img_mov->GetOrigin()); tenscomponent->SetDirection(img_mov->GetDirection()); typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(tenscomponent); // PixelType nullPix; // nullPix.Fill(0); warper->SetEdgePaddingValue(0); if (misc_opt.use_NN_interpolator){ typedef typename itk::NearestNeighborInterpolateImageFunction NNInterpolateType; typename NNInterpolateType::Pointer interpolator_NN = NNInterpolateType::New(); std::cout << "Haha" << std::endl; warper->SetInterpolator(interpolator_NN); } typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; unsigned int transcount=0; const int kOptQueueSize = opt_queue.size(); for(int i=0; iSetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast< AffineTransformType* > ((tran_reader->GetTransformList())->front().GetPointer()); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff " << transcount << std::endl; warper->PushBackAffineTransform(aff); if (transcount==0){ warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(img_mov->GetOrigin()); warper->SetOutputDirection(img_mov->GetDirection()); } transcount++; break; } case IDENTITY_TRANSFORM:{ typename AffineTransformType::Pointer aff; GetIdentityTransform(aff); // std::cout << " aff id" << transcount << std::endl; warper->PushBackAffineTransform(aff); transcount++; break; } case IMAGE_AFFINE_HEADER:{ typename AffineTransformType::Pointer aff = AffineTransformType::New(); typename ImageType::Pointer img_affine = ImageType::New(); typename ImageFileReaderType::Pointer reader_image_affine = ImageFileReaderType::New(); reader_image_affine->SetFileName(opt.filename); reader_image_affine->Update(); img_affine = reader_image_affine->GetOutput(); GetAffineTransformFromImage(img_affine, aff); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff from image header " << transcount << std::endl; warper->PushBackAffineTransform(aff); // if (transcount==0){ // warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); // warper->SetOutputSpacing(img_mov->GetSpacing()); // warper->SetOutputOrigin(img_mov->GetOrigin()); // warper->SetOutputDirection(img_mov->GetDirection()); // } transcount++; break; } case DEFORMATION_FILE:{ typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName( opt.filename ); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); warper->PushBackDeformationFieldTransform(field); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->SetOutputOrigin(field->GetOrigin()); warper->SetOutputSpacing(field->GetSpacing()); warper->SetOutputDirection(field->GetDirection()); transcount++; break; } default: std::cout << "Unknown file type!" << std::endl; } } // warper->PrintTransformList(); if (img_ref.IsNotNull()){ warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); } else { if (misc_opt.use_TightestBoundingBox == true){ // compute the desired spacking after inputting all the transform files using the typename ImageType::SizeType largest_size; typename ImageType::PointType origin_warped; GetLaregstSizeAfterWarp(warper, img_mov, largest_size, origin_warped); warper->SetOutputSize(largest_size); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(origin_warped); typename ImageType::DirectionType d; d.SetIdentity(); warper->SetOutputDirection(d); } } //std::cout << "output origin: " << warper->GetOutputOrigin() << std::endl; //std::cout << "output size: " << warper->GetOutputSize() << std::endl; //std::cout << "output spacing: " << warper->GetOutputSpacing() << std::endl; // std::cout << "output direction: " << warper->GetOutputDirection() << std::endl; // warper->PrintTransformList(); warper->DetermineFirstDeformNoInterp(); warper->Update(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( img_output, img_output->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { PixelType tens=vfIter2.Get(); tens[tensdim]=warper->GetOutput()->GetPixel(vfIter2.GetIndex()); vfIter2.Set(tens); } } WriteTensorImage(img_output, output_image_filename,true); } int main(int argc, char **argv){ if (argc<=3){ std::cout << "WarpImageMultiTransform ImageDimension moving_image output_image [-R reference_image | --tightest-bounding-box] (--reslice-by-header) [--use-NN (use Nearest Neighbor Interpolator)]" << "[--ANTS-prefix prefix-name | --ANTS-prefix-invert prefix-name] {[deformation_field | [-i] affine_transform_txt | --Id | [-i] --moving-image-header / -mh | [-i] --reference-image-header / -rh]}" << std::endl << "Example:" << std::endl << "Reslice the image: WarpImageMultiTransform 3 Imov.nii Iout.nii --tightest-bounding-box --reslice-by-header" << std::endl << "Reslice the image to a reference image: WarpImageMultiTransform 3 Imov.nii Iout.nii -R Iref.nii --tightest-bounding-box --reslice-by-header" << std::endl << "Note:" << std::endl << "-i will use the inversion of the following affine transform." << std::endl << "--tightest-bounding-box will be overrided by -R reference_image if given. It computes the tightest bounding box using all the affine transformations." << std::endl << "--Id uses the identity transform." << std::endl << "--moving-image-header or -mh in short will use the orientation header of the moving image file. This is typically not used with --reslice-by-header." << std::endl << "--reference-image-header or -rh in short will use the orientation header of the fixed image file. This is typically not used with --reslice-by-header." << std::endl << "--reslice-by-header uses the orientation matrix and origin encoded in the image file header. It can be used together with -R. " << "This is typically not used together with any other transforms. " << "--reslice-by-header is equvalient to -i -mh, or -fh -i -mh if used together with -R. " << std::endl; std::cout << std::endl << "For ANTS users:" << std::endl << "To use with the deformation field and the affine transform files generated from ANTS:" << std::endl << "--ANTS-prefix prefix-name" << std::endl << "--ANTS-prefix-invert prefix-name" << std::endl << "Example:" << std::endl << "3 moving_image output_image -R reference_image --ANTS-prefix abcd.nii.gz" << std::endl << "Applies abcdWarpxvec.nii.gz/abcdWarpyvec.nii.gz/abcdWarpzvec.nii.gz and then abcdAffine.txt. Use this with ANTS to get the moving_image warped into the reference_image domain. " << std::endl << "3 reference_image output_image -R moving_image --ANTS-prefix-invert abcd.nii.gz --ANTS-invert" << std::endl << "Applies the inversion of abcdAffine.txt and then abcdInverseWarpxvec.nii.gz/abcdInverseWarpyvec.nii.gz/abcdInverseWarpzvec.nii.gz. Use this with ANTS to get the reference_image warped into the moving_image domain. " << std::endl << "Note: " << std::endl << "prefix name \"abcd\" without any extension will use \".nii.gz\" by default" << std::endl; exit(0); } TRAN_OPT_QUEUE opt_queue; char *moving_image_filename = NULL; char *output_image_filename = NULL; MISC_OPT misc_opt; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc-2, argv+2, moving_image_filename, output_image_filename, opt_queue, misc_opt); if (is_parsing_ok){ std::cout << "moving_image_filename: " << moving_image_filename << std::endl; std::cout << "output_image_filename: " << output_image_filename << std::endl; std::cout << "reference_image_filename: "; if (misc_opt.reference_image_filename) std::cout << misc_opt.reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim){ case 2:{ WarpImageMultiTransform<2>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } case 3:{ WarpImageMultiTransform<3>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } } } else{ std::cout << "Input error!" << std::endl; } exit(0); } ants-1.9.2+svn680.dfsg/Examples/WarpTimeSeriesImageMultiTransform.cxx000066400000000000000000001163071147325206600255470ustar00rootroot00000000000000#include #include #include "itkImageFileReader.h" #include "itkVector.h" #include "itkVariableLengthVector.h" #include "itkVectorImageFileReader.h" #include "itkImageFileWriter.h" #include "itkMatrixOffsetTransformBase.h" #include "itkTransformFactory.h" #include "itkTransformFileReader.h" #include "itkVectorNearestNeighborInterpolateImageFunction.h" #include "ReadWriteImage.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkExtractImageFilter.h" typedef enum{INVALID_FILE=1, AFFINE_FILE, DEFORMATION_FILE, IMAGE_AFFINE_HEADER, IDENTITY_TRANSFORM} TRAN_FILE_TYPE; typedef struct{ // char *filename; std::string filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; // void SetValue(char *filename, TRAN_FILE_TYPE file_type, bool do_affine_inv){ // this.filename = filename; // this.file_type = file_type; // this.do_affine_inv = do_affine_inv; // }; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; typedef struct{ bool use_NN_interpolator; bool use_TightestBoundingBox; char * reference_image_filename; bool use_RotationHeader; } MISC_OPT; void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue); void DisplayOpt(const TRAN_OPT &opt); TRAN_FILE_TYPE CheckFileType(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } if (extension==".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else{ return INVALID_FILE; } return AFFINE_FILE; } void FilePartsWithgz(const std::string &filename, std::string &path, std::string &name, std::string &ext){ std::string extension; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); if (pos != std::string::npos){ extension = std::string( filepre, pos, filepre.length()-1 ) + ".gz"; filepre = std::string(filepre, 0, pos); } } } else { extension = std::string(""); } ext = extension; pos = filepre.rfind('/'); if ( pos != std::string::npos ){ path = std::string(filepre, 0, pos+1); name = std::string(filepre, pos+1, filepre.length()-1); } else { path = std::string(""); name = filepre; } // std::cout << "filename: " << filename << std::endl // << "path: " << path << std::endl // << "name: " << name << std::endl // << "ext: " << ext << std::endl; } bool CheckFileExistence(const char *str){ std::ifstream myfile(str); bool b = myfile.is_open(); myfile.close(); return b; } void SetAffineInvFlag(TRAN_OPT &opt, bool &set_current_affine_inv){ opt.do_affine_inv = set_current_affine_inv; if (set_current_affine_inv) set_current_affine_inv = false; } bool ParseInput(int argc, char **argv, char *&moving_image_filename, char *&output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ opt_queue.clear(); opt_queue.reserve(argc-2); misc_opt.reference_image_filename = NULL; misc_opt.use_NN_interpolator = false; misc_opt.use_TightestBoundingBox = false; misc_opt.use_RotationHeader = false; moving_image_filename = argv[0]; output_image_filename = argv[1]; int ind = 2; bool set_current_affine_inv = false; while(ind < argc){ if (strcmp(argv[ind], "--use-NN")==0) { misc_opt.use_NN_interpolator = true; } else if (strcmp(argv[ind], "-R")==0) { ind++; if(ind >= argc) return false; misc_opt.reference_image_filename = argv[ind]; } else if ((strcmp(argv[ind], "--tightest-bounding-box")==0) && (strcmp(argv[ind], "-R")!=0) ) { misc_opt.use_TightestBoundingBox = true; } else if (strcmp(argv[ind], "--reslice-by-header")==0) { misc_opt.use_RotationHeader = true; TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.do_affine_inv = false; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--Id")==0) { TRAN_OPT opt; opt.filename = "--Id"; opt.do_affine_inv = false; opt.file_type = IDENTITY_TRANSFORM; opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--moving-image-header")==0 || strcmp(argv[ind], "-mh") ==0){ TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = moving_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "--reference-image-header")==0 || strcmp(argv[ind], "-rh") ==0){ if (misc_opt.reference_image_filename==NULL){ std::cout << "reference image filename is not given yet. Specify it with -R before --reference-image-header / -rh." << std::endl; return false; } TRAN_OPT opt; opt.file_type = IMAGE_AFFINE_HEADER; opt.filename = misc_opt.reference_image_filename; // opt.do_affine_inv = false; SetAffineInvFlag(opt, set_current_affine_inv); opt_queue.push_back(opt); } else if (strcmp(argv[ind], "-i")==0) { set_current_affine_inv = true; } else if (strcmp(argv[ind], "--ANTS-prefix")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("Warp")+ext; x_deform_name = path+name+std::string("Warpxvec")+ext; if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } } else if (strcmp(argv[ind], "--ANTS-prefix-invert")==0){ ind++; std::string prefix = argv[ind]; std::string path, name, ext; FilePartsWithgz(prefix, path, name, ext); if (ext=="") ext=".nii.gz"; std::string affine_file_name; affine_file_name = path+name+std::string("Affine.txt"); if (CheckFileExistence(affine_file_name.c_str())){ TRAN_OPT opt; opt.filename = affine_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = true; opt_queue.push_back(opt); std::cout << "found affine file: " << opt.filename << std::endl; DisplayOpt(opt); } std::string deform_file_name, x_deform_name; deform_file_name = path+name+std::string("InverseWarp.nii.gz"); x_deform_name = path+name+std::string("InverseWarpxvec.nii.gz"); if (CheckFileExistence(x_deform_name.c_str())){ TRAN_OPT opt; opt.filename = deform_file_name.c_str(); opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; opt_queue.push_back(opt); std::cout << "found deformation file: " << opt.filename << std::endl; DisplayOpt(opt); } } else{ TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename.c_str()); opt.do_affine_inv = false; if (opt.file_type == AFFINE_FILE) SetAffineInvFlag(opt, set_current_affine_inv); else if (opt.file_type == DEFORMATION_FILE && set_current_affine_inv){ std::cout << "Ignore inversion of non-affine file type! " << std::endl; std::cout << "opt.do_affine_inv:" << opt.do_affine_inv << std::endl; } opt_queue.push_back(opt); DisplayOpt(opt); } ind++; } if (misc_opt.use_RotationHeader) { // if (misc_opt.reference_image_filename) { // opt_queue[0].filename = misc_opt.reference_image_filename; // } else { opt_queue[0].filename = "--Id"; opt_queue[0].file_type = IDENTITY_TRANSFORM; opt_queue[0].do_affine_inv = false; // } // TRAN_OPT opt; // opt.file_type = IMAGE_AFFINE_HEADER; // opt.filename = moving_image_filename; // opt.do_affine_inv = true; // opt_queue.push_back(opt); // // std::cout << "Use Rotation Header!" << std::endl; } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue){ const int kQueueSize = opt_queue.size(); for(int i=0; i void GetIdentityTransform(AffineTransformPointer &aff){ typedef typename AffineTransformPointer::ObjectType AffineTransform; aff = AffineTransform::New(); aff->SetIdentity(); } template void GetAffineTransformFromImage(const ImageTypePointer& img, AffineTransformPointer &aff){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename ImageType::DirectionType DirectionType; typedef typename ImageType::PointType PointType; typedef typename ImageType::SpacingType SpacingType; typedef typename AffineTransformPointer::ObjectType::TranslationType VectorType; DirectionType direction = img->GetDirection(); SpacingType spacing = img->GetSpacing(); VectorType translation; // translation.Fill(0); for(unsigned int i=0; iGetOrigin()[i]; aff->SetMatrix(direction); // aff->SetCenter(pt); PointType pt; pt.Fill(0); aff->SetOffset(translation); aff->SetCenter(pt); std::cout << "aff from image:" << aff << std::endl; } template void GetLaregstSizeAfterWarp(WarperPointerType &warper, ImagePointerType &img, SizeType &largest_size, PointType &origin_warped){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::GetImageDimension(); // typedef typename ImageType::PointType PointType; typedef typename std::vector PointList; typedef typename ImageType::IndexType IndexType; // PointList pts_orig; PointList pts_warped; typename ImageType::SizeType imgsz; imgsz = img->GetLargestPossibleRegion().GetSize(); typename ImageType::SpacingType spacing; spacing = img->GetSpacing(); pts_warped.clear(); if (ImageDimension == 3){ for(int i=0; i<8; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; ind[2]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=0; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=0; break; case 4: ind[0]=0; ind[1]=0; ind[2]=imgsz[2]-1; break; case 5: ind[0]=imgsz[0]-1; ind[1]=0; ind[2]=imgsz[2]-1; break; case 6: ind[0]=0; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; case 7: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; ind[2]=imgsz[2]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else if (ImageDimension == 2) { for(int i=0; i<4; i++){ IndexType ind; switch (i){ case 0: ind[0]=0; ind[1]=0; break; case 1: ind[0]=imgsz[0]-1; ind[1]=0; break; case 2: ind[0]=0; ind[1]=imgsz[1]-1; break; case 3: ind[0]=imgsz[0]-1; ind[1]=imgsz[1]-1; break; } PointType pt_orig, pt_warped; img->TransformIndexToPhysicalPoint(ind, pt_orig); if (warper->MultiInverseAffineOnlySinglePoint(pt_orig, pt_warped)==false){ std::cout << "ERROR: outside of numeric boundary with affine transform." << std::endl; exit(-1); } pts_warped.push_back(pt_warped); std::cout << '[' << i << ']' << ind << ',' << pt_orig << "->" << pt_warped << std::endl; } } else { std::cout << "could not determine the dimension after warping for non 2D/3D volumes" << std::endl; exit(-1); } PointType pt_min, pt_max; pt_min = pts_warped[0]; pt_max = pts_warped[0]; for(unsigned int k=0; kpts_warped[k][i])?(pt_max[i]):(pts_warped[k][i]); } } for(int i=0; i void WarpImageMultiTransformFourD(char *moving_image_filename, char *output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt) { typedef itk::Image VectorImageType; // 4D contains functional image typedef itk::Image ImageType; // 3D image domain -R option typedef itk::Vector VectorType; // 3D warp typedef itk::Image DeformationFieldType; // 3D Field typedef itk::MatrixOffsetTransformBase< double, ImageDimension-1, ImageDimension-1> AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; //typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); //reader_img->SetFileName(moving_image_filename); //reader_img->Update(); //typename ImageType::Pointer img_mov = ImageType::New(); //img_mov = reader_img->GetOutput(); typename VectorImageType::Pointer img_mov; ReadImage(img_mov,moving_image_filename); std::cout << " Four-D image size: " << img_mov->GetLargestPossibleRegion().GetSize() << std::endl; typename ImageType::Pointer img_ref; // = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (misc_opt.reference_image_filename){ reader_img_ref->SetFileName(misc_opt.reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } typedef itk::ExtractImageFilter ExtractFilterType; typedef itk::ImageRegionIteratorWithIndex ImageIt; typedef itk::ImageRegionIteratorWithIndex SliceIt; // allocate output image typename VectorImageType::Pointer transformedvecimage = VectorImageType::New(); typename VectorImageType::RegionType region =img_mov->GetLargestPossibleRegion(); for (unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i] ); } transformedvecimage->SetRegions(region); // transformedvecimage->SetDirection( transformedvecimage->Allocate(); typename VectorImageType::DirectionType direction=transformedvecimage->GetDirection(); direction.Fill(0); typename VectorImageType::PointType origin=transformedvecimage->GetOrigin(); typename VectorImageType::SpacingType spc=transformedvecimage->GetSpacing(); for (unsigned int i=0; iGetDirection()[i][j]; } spc[i]=img_ref->GetSpacing()[i]; origin[i]=img_ref->GetOrigin()[i]; } direction[ImageDimension-1][ImageDimension-1]=1; origin[ImageDimension-1]=img_mov->GetOrigin()[ImageDimension-1]; spc[ImageDimension-1]=img_mov->GetSpacing()[ImageDimension-1]; transformedvecimage->SetDirection(direction); transformedvecimage->SetSpacing(spc); transformedvecimage->SetOrigin(origin); std::cout << " 4D-In-Spc " << img_mov->GetSpacing() << std::endl; std::cout << " 4D-In-Org " << img_mov->GetOrigin() << std::endl; std::cout << " 4D-In-Size " << img_mov->GetLargestPossibleRegion().GetSize() << std::endl; std::cout << " 4D-In-Dir " << img_mov->GetDirection() << std::endl; std::cout << " ...... " << std::endl; std::cout << " 4D-Out-Spc " << transformedvecimage->GetSpacing() << std::endl; std::cout << " 4D-Out-Org " << transformedvecimage->GetOrigin() << std::endl; std::cout << " 4D-Out-Size " << transformedvecimage->GetLargestPossibleRegion().GetSize() << std::endl; std::cout << " 4D-Out-Dir " << transformedvecimage->GetDirection() << std::endl; unsigned int timedims=img_mov->GetLargestPossibleRegion().GetSize()[ImageDimension-1]; for (unsigned int timedim=0; timedim < timedims ; timedim++ ) { typename WarperType::Pointer warper = WarperType::New(); warper->SetEdgePaddingValue(0); if (misc_opt.use_NN_interpolator){ typedef typename itk::NearestNeighborInterpolateImageFunction NNInterpolateType; typename NNInterpolateType::Pointer interpolator_NN = NNInterpolateType::New(); std::cout << " Use Nearest Neighbor interpolation " << std::endl; warper->SetInterpolator(interpolator_NN); } typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; unsigned int transcount=0; const int kOptQueueSize = opt_queue.size(); for(int i=0; iSetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast< AffineTransformType* > ((tran_reader->GetTransformList())->front().GetPointer()); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff " << transcount << std::endl; warper->PushBackAffineTransform(aff); if (transcount==0){ warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); } transcount++; break; } case IDENTITY_TRANSFORM:{ typename AffineTransformType::Pointer aff; GetIdentityTransform(aff); // std::cout << " aff id" << transcount << std::endl; warper->PushBackAffineTransform(aff); transcount++; break; } case IMAGE_AFFINE_HEADER:{ typename AffineTransformType::Pointer aff = AffineTransformType::New(); typename ImageType::Pointer img_affine = ImageType::New(); typename ImageFileReaderType::Pointer reader_image_affine = ImageFileReaderType::New(); reader_image_affine->SetFileName(opt.filename); reader_image_affine->Update(); img_affine = reader_image_affine->GetOutput(); GetAffineTransformFromImage(img_affine, aff); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff from image header " << transcount << std::endl; warper->PushBackAffineTransform(aff); // if (transcount==0){ // warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); // warper->SetOutputSpacing(img_mov->GetSpacing()); // warper->SetOutputOrigin(img_mov->GetOrigin()); // warper->SetOutputDirection(img_mov->GetDirection()); // } transcount++; break; } case DEFORMATION_FILE:{ typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName( opt.filename ); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); warper->PushBackDeformationFieldTransform(field); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->SetOutputOrigin(field->GetOrigin()); warper->SetOutputSpacing(field->GetSpacing()); warper->SetOutputDirection(field->GetDirection()); transcount++; break; } default: std::cout << "Unknown file type!" << std::endl; } } // warper->PrintTransformList(); if (img_ref.IsNotNull()){ warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); } else { if (misc_opt.use_TightestBoundingBox == true){ // compute the desired spacking after inputting all the transform files using the std::cout << " not implemented " << std::endl; /* typename ImageType::SizeType largest_size; typename ImageType::PointType origin_warped; GetLaregstSizeAfterWarp(warper, warpthisimage , largest_size, origin_warped); warper->SetOutputSize(largest_size); warper->SetOutputSpacing(warpthisimage->GetSpacing()); warper->SetOutputOrigin(origin_warped); typename ImageType::DirectionType d; d.SetIdentity(); warper->SetOutputDirection(d);*/ } } if ( timedim % vnl_math_max(timedims / 10, static_cast(1)) == 0 ) std::cout << (float) timedim/(float)timedims*100 << " % done ... " << std::flush; // << std::endl; typename VectorImageType::RegionType extractRegion = img_mov->GetLargestPossibleRegion(); extractRegion.SetSize(ImageDimension-1, 0); extractRegion.SetIndex(ImageDimension-1, timedim ); typename ExtractFilterType::Pointer extractFilter = ExtractFilterType::New(); extractFilter->SetInput( img_mov ); extractFilter->SetExtractionRegion( extractRegion ); extractFilter->Update(); typename ImageType::Pointer warpthisimage=extractFilter->GetOutput(); typename ImageType::SpacingType qspc=warpthisimage->GetSpacing(); typename ImageType::PointType qorg=warpthisimage->GetOrigin(); typename ImageType::DirectionType qdir=warpthisimage->GetDirection(); qdir.Fill(0); for (unsigned int qq=0; qqGetDirection()[qq][pp]; } qspc[qq]=img_mov->GetSpacing()[qq]; qorg[qq]=img_mov->GetOrigin()[qq]; } warpthisimage->SetSpacing(qspc); warpthisimage->SetOrigin(qorg); warpthisimage->SetDirection(qdir); warper->SetInput( warpthisimage ); warper->DetermineFirstDeformNoInterp(); warper->Update(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( warper->GetOutput(), warper->GetOutput()->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { typename ImageType::PixelType fval=vfIter2.Get(); typename VectorImageType::IndexType ind; for (unsigned int xx=0; xxSetPixel(ind,fval); // if ( ind[0] == 53 && ind[1] == 19 && ind[2] == 30 ) std::cout << " fval " << fval << " td " << timedim << std::endl; } if (timedim == 0) std::cout << warper->GetOutput()->GetDirection() << std::endl; } std::cout << " 100 % complete " << std::endl; WriteImage( transformedvecimage , output_image_filename); } template void WarpImageMultiTransform(char *moving_image_filename, char *output_image_filename, TRAN_OPT_QUEUE &opt_queue, MISC_OPT &misc_opt){ typedef itk::VectorImage VectorImageType; typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; //typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); //reader_img->SetFileName(moving_image_filename); //reader_img->Update(); //typename ImageType::Pointer img_mov = ImageType::New(); //img_mov = reader_img->GetOutput(); typename VectorImageType::Pointer img_mov; typename itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(moving_image_filename, itk::ImageIOFactory::ReadMode); imageIO->SetFileName(moving_image_filename); imageIO->ReadImageInformation(); // std::cout << " Dimension " << imageIO->GetNumberOfDimensions() << " Components " <GetNumberOfComponents() << std::endl; unsigned int veclength=imageIO->GetNumberOfComponents(); std::cout <<" read veclength as:: " << veclength << std::endl; ReadImage(img_mov,moving_image_filename); typename ImageType::Pointer img_ref; // = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (misc_opt.reference_image_filename){ reader_img_ref->SetFileName(misc_opt.reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } typename VectorImageType::Pointer img_output = VectorImageType::New(); img_output->SetNumberOfComponentsPerPixel(veclength); img_output->SetLargestPossibleRegion( img_ref->GetLargestPossibleRegion() ); img_output->SetBufferedRegion( img_ref->GetLargestPossibleRegion() ); img_output->SetLargestPossibleRegion( img_ref->GetLargestPossibleRegion() ); img_output->Allocate(); img_output->SetSpacing(img_ref->GetSpacing()); img_output->SetOrigin(img_ref->GetOrigin()); img_output->SetDirection(img_ref->GetDirection()); typename ImageType::IndexType index; index.Fill(0); typename VectorImageType::PixelType vec=img_mov->GetPixel(index); vec.Fill(0); img_output->FillBuffer( vec ); for (unsigned int tensdim=0; tensdim < veclength; tensdim++) { typedef itk::VectorIndexSelectionCastImageFilter IndexSelectCasterType; typename IndexSelectCasterType::Pointer fieldCaster = IndexSelectCasterType::New(); fieldCaster->SetInput( img_mov ); fieldCaster->SetIndex( tensdim ); fieldCaster->Update(); typename ImageType::Pointer tenscomponent=fieldCaster->GetOutput(); tenscomponent->SetSpacing(img_mov->GetSpacing()); tenscomponent->SetOrigin(img_mov->GetOrigin()); tenscomponent->SetDirection(img_mov->GetDirection()); typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(tenscomponent); // PixelType nullPix; // nullPix.Fill(0); warper->SetEdgePaddingValue(0); if (misc_opt.use_NN_interpolator){ typedef typename itk::NearestNeighborInterpolateImageFunction NNInterpolateType; typename NNInterpolateType::Pointer interpolator_NN = NNInterpolateType::New(); std::cout << "Haha" << std::endl; warper->SetInterpolator(interpolator_NN); } typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; unsigned int transcount=0; const int kOptQueueSize = opt_queue.size(); for(int i=0; iSetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast< AffineTransformType* > ((tran_reader->GetTransformList())->front().GetPointer()); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff " << transcount << std::endl; warper->PushBackAffineTransform(aff); if (transcount==0){ warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(img_mov->GetOrigin()); warper->SetOutputDirection(img_mov->GetDirection()); } transcount++; break; } case IDENTITY_TRANSFORM:{ typename AffineTransformType::Pointer aff; GetIdentityTransform(aff); // std::cout << " aff id" << transcount << std::endl; warper->PushBackAffineTransform(aff); transcount++; break; } case IMAGE_AFFINE_HEADER:{ typename AffineTransformType::Pointer aff = AffineTransformType::New(); typename ImageType::Pointer img_affine = ImageType::New(); typename ImageFileReaderType::Pointer reader_image_affine = ImageFileReaderType::New(); reader_image_affine->SetFileName(opt.filename); reader_image_affine->Update(); img_affine = reader_image_affine->GetOutput(); GetAffineTransformFromImage(img_affine, aff); if (opt.do_affine_inv) { typename AffineTransformType::Pointer aff_inv = AffineTransformType::New(); aff->GetInverse(aff_inv); aff = aff_inv; } // std::cout <<" aff from image header " << transcount << std::endl; warper->PushBackAffineTransform(aff); // if (transcount==0){ // warper->SetOutputSize(img_mov->GetLargestPossibleRegion().GetSize()); // warper->SetOutputSpacing(img_mov->GetSpacing()); // warper->SetOutputOrigin(img_mov->GetOrigin()); // warper->SetOutputDirection(img_mov->GetDirection()); // } transcount++; break; } case DEFORMATION_FILE:{ typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName( opt.filename ); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); warper->PushBackDeformationFieldTransform(field); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->SetOutputOrigin(field->GetOrigin()); warper->SetOutputSpacing(field->GetSpacing()); warper->SetOutputDirection(field->GetDirection()); transcount++; break; } default: std::cout << "Unknown file type!" << std::endl; } } // warper->PrintTransformList(); if (img_ref.IsNotNull()){ warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); } else { if (misc_opt.use_TightestBoundingBox == true){ // compute the desired spacking after inputting all the transform files using the typename ImageType::SizeType largest_size; typename ImageType::PointType origin_warped; GetLaregstSizeAfterWarp(warper, img_mov, largest_size, origin_warped); warper->SetOutputSize(largest_size); warper->SetOutputSpacing(img_mov->GetSpacing()); warper->SetOutputOrigin(origin_warped); typename ImageType::DirectionType d; d.SetIdentity(); warper->SetOutputDirection(d); } } warper->DetermineFirstDeformNoInterp(); warper->Update(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter2( img_output, img_output->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { typename VectorImageType::PixelType tens=vfIter2.Get(); tens[tensdim]=warper->GetOutput()->GetPixel(vfIter2.GetIndex()); vfIter2.Set(tens); } } WriteImage(img_output, output_image_filename); } int main(int argc, char **argv){ if (argc<=3){ std::cout << argv[0] << " ImageDimension moving_image output_image -R fixed_image MyWarp.nii.gz MyAffine.txt --use-NN (Nearest Neighbor Interpolator option) " << std::endl; std::cout << argv[0] << " ImageDimension fixed_image output_image -R moving_image -i MyAffine.txt MyInverseWarp.nii.gz --use-NN (Nearest Neighbor Interpolator option ) " << std::endl; std::cout << " you can also string together series of mappings --- e.g.: MyAffine.txt MySecondAffine.txt MyWarp.nii.gz MySecondWarp.nii.gz -i MyInverseAffine.txt --- this can be an arbitrarily long series. " << std::endl; std::cout << " For this program, your moving_image will be either a 3-D image with vector voxels or a 4D image with scalar voxels. " << std::endl; std::cout << " You must define whether the image is 3/4D via the first parameter to the program " << std::endl; std::cout << " Output will be of the same type as input, but will be resampled to the domain size defined by the -R image ... " << std::endl; std::cout <<" See WarpImageMultiTransform for more detailed usage " << std::endl; exit(0); } TRAN_OPT_QUEUE opt_queue; char *moving_image_filename = NULL; char *output_image_filename = NULL; MISC_OPT misc_opt; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc-2, argv+2, moving_image_filename, output_image_filename, opt_queue, misc_opt); if (is_parsing_ok){ std::cout << "moving_image_filename: " << moving_image_filename << std::endl; std::cout << "output_image_filename: " << output_image_filename << std::endl; std::cout << "reference_image_filename: "; if (misc_opt.reference_image_filename) std::cout << misc_opt.reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim){ case 2:{ WarpImageMultiTransform<2>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } case 3:{ WarpImageMultiTransform<3>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } case 4:{ WarpImageMultiTransformFourD<4>(moving_image_filename, output_image_filename, opt_queue, misc_opt); break; } } } else{ std::cout << "Input error!" << std::endl; } exit(0); } ants-1.9.2+svn680.dfsg/Examples/WarpVTKPolyDataMultiTransform.cxx000066400000000000000000000525231147325206600246340ustar00rootroot00000000000000#include #include #include #include "itkImageFileReader.h" #include "itkVector.h" #include "itkVectorImageFileReader.h" #include "itkVectorImageFileWriter.h" #include "itkImageFileWriter.h" #include "itkMatrixOffsetTransformBase.h" #include "itkTransformFactory.h" #include "vtkPolyDataReader.h" //#include "itkWarpImageMultiTransformFilter.h" #include "itkDeformationFieldFromMultiTransformFilter.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" #include "itkLabeledPointSetFileReader.h" #include "itkLabeledPointSetFileWriter.h" #include "itkMesh.h" #include #include #include #include #include #include #include typedef enum { INVALID_FILE = 1, AFFINE_FILE, DEFORMATION_FILE } TRAN_FILE_TYPE; typedef struct { char * filename; TRAN_FILE_TYPE file_type; bool do_affine_inv; } TRAN_OPT; typedef std::vector TRAN_OPT_QUEUE; template typename TImage::PointType TransformPoint(TDeformationField* field, typename TImage::PointType point ) { enum { ImageDimension = TImage::ImageDimension }; typename TImage::PointType newpoint; newpoint.Fill(0); for (unsigned int row=0; rowGetDirection()[row][col]; return newpoint; } vnl_matrix_fixed ConstructNiftiSform( vnl_matrix m_dir, vnl_vector v_origin, vnl_vector v_spacing) { // Set the NIFTI/RAS transform vnl_matrix m_ras_matrix; vnl_diag_matrix m_scale, m_lps_to_ras; vnl_vector v_ras_offset; // Compute the matrix m_scale.set(v_spacing); m_lps_to_ras.set(vnl_vector(3, 1.0)); m_lps_to_ras[0] = -1; m_lps_to_ras[1] = -1; m_ras_matrix = m_lps_to_ras * m_dir * m_scale; // Compute the vector v_ras_offset = m_lps_to_ras * v_origin; // Create the larger matrix vnl_vector vcol(4, 1.0); vcol.update(v_ras_offset); vnl_matrix_fixed m_sform; m_sform.set_identity(); m_sform.update(m_ras_matrix); m_sform.set_column(3, vcol); return m_sform; } vnl_matrix_fixed ConstructVTKtoNiftiTransform( vnl_matrix m_dir, vnl_vector v_origin, vnl_vector v_spacing) { vnl_matrix_fixed vox2nii = ConstructNiftiSform(m_dir, v_origin, v_spacing); vnl_matrix_fixed vtk2vox; vtk2vox.set_identity(); for(size_t i = 0; i < 3; i++) { vtk2vox(i,i) = 1.0 / v_spacing[i]; vtk2vox(i,3) = - v_origin[i] / v_spacing[i]; } return vox2nii * vtk2vox; } TRAN_FILE_TYPE CheckFileType(char *str) { std::string filename = str; std::string::size_type pos = filename.rfind("."); std::string filepre = std::string(filename, 0, pos); if (pos != std::string::npos) { std::string extension = std::string(filename, pos, filename.length() - 1); if (extension == std::string(".gz")) { pos = filepre.rfind("."); extension = std::string(filepre, pos, filepre.length() - 1); } if (extension == ".txt") return AFFINE_FILE; else return DEFORMATION_FILE; } else { return INVALID_FILE; } return AFFINE_FILE; } bool ParseInput(int argc, char **argv, char *&input_vtk_filename, char *&output_vtk_filename, char *&reference_image_filename, TRAN_OPT_QUEUE &opt_queue) { opt_queue.clear(); opt_queue.reserve(argc - 2); input_vtk_filename = argv[0]; output_vtk_filename = argv[1]; reference_image_filename = NULL; int ind = 2; while (ind < argc) { if (strcmp(argv[ind], "-R") == 0) { ind++; if (ind >= argc) return false; reference_image_filename = argv[ind]; } else if (strcmp(argv[ind], "-i") == 0) { ind++; if (ind >= argc) return false; TRAN_OPT opt; opt.filename = argv[ind]; if (CheckFileType(opt.filename) != AFFINE_FILE) { std::cout << "file: " << opt.filename << " is not an affine .txt file. Invalid to use '-i' " << std::endl; return false; } opt.file_type = AFFINE_FILE; opt.do_affine_inv = true; opt_queue.push_back(opt); } else { TRAN_OPT opt; opt.filename = argv[ind]; opt.file_type = CheckFileType(opt.filename); opt.do_affine_inv = false; opt_queue.push_back(opt); } ind++; } // if (reference_image_filename == NULL) { // std::cout << "the reference image file (-R) must be given!!!" // << std::endl; // return false; // } return true; } void DisplayOptQueue(const TRAN_OPT_QUEUE &opt_queue) { const int kQueueSize = opt_queue.size(); for (int i = 0; i < kQueueSize; i++) { std::cout << "[" << i << "/" << kQueueSize << "]: "; switch (opt_queue[i].file_type) { case AFFINE_FILE: std::cout << "AFFINE"; if (opt_queue[i].do_affine_inv) std::cout << "-INV"; break; case DEFORMATION_FILE: std::cout << "FIELD"; break; default: std::cout << "Invalid Format!!!"; break; } std::cout << ": " << opt_queue[i].filename << std::endl; } } template void WarpLabeledPointSetFileMultiTransform(char *input_vtk_filename, char *output_vtk_filename, char *reference_image_filename, TRAN_OPT_QUEUE &opt_queue) { typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase AffineTransformType; // typedef itk::WarpImageMultiTransformFilter WarperType; typedef itk::DeformationFieldFromMultiTransformFilter WarperType; typedef itk::LinearInterpolateImageFunction FuncType; itk::TransformFactory::RegisterTransform(); typedef itk::ImageFileReader ImageFileReaderType; typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); typename ImageType::Pointer img_ref = ImageType::New(); typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); if (reference_image_filename) { reader_img_ref->SetFileName(reference_image_filename); reader_img_ref->Update(); img_ref = reader_img_ref->GetOutput(); } else { std::cout << "the reference image file (-R) must be given!!!" << std::endl; return; } typename WarperType::Pointer warper = WarperType::New(); // warper->SetInput(img_mov); // warper->SetEdgePaddingValue( 0); VectorType pad; pad.Fill(0); // warper->SetEdgePaddingValue(pad); typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; const int kOptQueueSize = opt_queue.size(); for (int i = 0; i < kOptQueueSize; i++) { const TRAN_OPT &opt = opt_queue[i]; switch (opt_queue[i].file_type) { case AFFINE_FILE: { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast ((tran_reader->GetTransformList())->front().GetPointer()); if (opt_queue[i].do_affine_inv) { aff->GetInverse(aff); } // std::cout << aff << std::endl; warper->PushBackAffineTransform(aff); break; } case DEFORMATION_FILE: { typename FieldReaderType::Pointer field_reader = FieldReaderType::New(); field_reader->SetFileName(opt.filename); field_reader->Update(); typename DeformationFieldType::Pointer field = field_reader->GetOutput(); // std::cout << field << std::endl; warper->PushBackDeformationFieldTransform(field); break; } default: std::cout << "Unknown file type!" << std::endl; } } warper->SetOutputSize(img_ref->GetLargestPossibleRegion().GetSize()); warper->SetOutputSpacing(img_ref->GetSpacing()); warper->SetOutputOrigin(img_ref->GetOrigin()); warper->SetOutputDirection(img_ref->GetDirection()); std::cout << "output size: " << warper->GetOutputSize() << std::endl; std::cout << "output spacing: " << warper->GetOutputSpacing() << std::endl; // warper->PrintTransformList(); warper->DetermineFirstDeformNoInterp(); warper->Update(); typename DeformationFieldType::Pointer field_output = DeformationFieldType::New(); field_output = warper->GetOutput(); /** * Code to read the mesh */ typename ImageType::PointType point; typename ImageType::PointType warpedPoint; typedef itk::Mesh MeshType; // typedef itk::LabeledPointSetFileReader VTKReaderType; vtkPolyDataReader *vtkreader = vtkPolyDataReader::New(); vtkreader->SetFileName( input_vtk_filename ); vtkreader->Update(); vtkPolyData *mesh = vtkreader->GetOutput(); /* typename VTKReaderType::Pointer vtkreader = VTKReaderType::New(); vtkreader->SetFileName( input_vtk_filename ); vtkreader->Update(); typename MeshType::PointsContainerIterator It = vtkreader->GetOutput()->GetPoints()->Begin(); while( It != vtkreader->GetOutput()->GetPoints()->End() ) { point.CastFrom( It.Value() ); */ vnl_matrix_fixed ijk2ras, vtk2ras, lps2ras; vtk2ras = ConstructVTKtoNiftiTransform( field_output->GetDirection().GetVnlMatrix(), field_output->GetOrigin().GetVnlVector(), field_output->GetSpacing().GetVnlVector()); ijk2ras.set_identity(); vtk2ras.set_identity(); lps2ras.set_identity(); lps2ras(0,0) = -1; lps2ras(1,1) = -1; // Set up the transforms ijk2ras = ConstructNiftiSform( field_output->GetDirection().GetVnlMatrix(), field_output->GetOrigin().GetVnlVector(), field_output->GetSpacing().GetVnlVector()); vtk2ras = ConstructVTKtoNiftiTransform( field_output->GetDirection().GetVnlMatrix(), field_output->GetOrigin().GetVnlVector(), field_output->GetSpacing().GetVnlVector()); vnl_matrix_fixed ras2ijk = vnl_inverse(ijk2ras); vnl_matrix_fixed ras2vtk = vnl_inverse(vtk2ras); vnl_matrix_fixed ras2lps = vnl_inverse(lps2ras); // Update the coordinates for(int k = 0; k < mesh->GetNumberOfPoints(); k++) { // Get the point (in whatever format that it's stored) vnl_vector_fixed x_mesh, x_ras, x_ijk, v_warp, v_ras; vnl_vector_fixed y_ras, y_mesh; x_mesh[0] = mesh->GetPoint(k)[0]; x_mesh[1] = mesh->GetPoint(k)[1]; x_mesh[2] = mesh->GetPoint(k)[2]; x_mesh[3] = 1.0; // Map the point into RAS coordinates // if(parm.mesh_coord == RAS) x_ras = x_mesh; // else if(parm.mesh_coord == LPS) x_ras = lps2ras * x_mesh; // else if(parm.mesh_coord == IJKOS) x_ras = vtk2ras * x_mesh; // else x_ras = ijk2ras * x_mesh; // Map the point to IJK coordinates (continuous index) x_ijk = ras2ijk * x_ras; typename FuncType::ContinuousIndexType ind; ind[0]=x_ijk[0]; ind[1]=x_ijk[1]; ind[2]=x_ijk[2]; field_output->TransformContinuousIndexToPhysicalPoint(ind, point); // std::cout << " point " << point << std::endl; // std::cout << " point-t " << point << std::endl; bool isInside = warper->MultiTransformSinglePoint( point, warpedPoint ); // if ( isInside ) std::cout << " point-w " << warpedPoint << std::endl; if( isInside ) { typename MeshType::PointType newPoint; newPoint.CastFrom( warpedPoint ); // vtkreader->GetOutput()->SetPoint( It.Index(), newPoint ); if ( ImageDimension == 3 ) { mesh->GetPoints()->SetPoint(k, warpedPoint[0], warpedPoint[1], warpedPoint[2]); } } // ++It; } std::string fn=std::string(output_vtk_filename); if(fn.rfind(".vtk") == fn.length() - 4) { vtkPolyDataWriter *writer = vtkPolyDataWriter::New(); writer->SetFileName(output_vtk_filename); writer->SetInput(mesh); writer->Update(); } /* typedef itk::LabeledPointSetFileWriter VTKWriterType; typename VTKWriterType::Pointer vtkwriter = VTKWriterType::New(); vtkwriter->SetFileName( output_vtk_filename ); vtkwriter->SetInput( vtkreader->GetOutput() ); vtkwriter->SetMultiComponentScalars( vtkreader->GetMultiComponentScalars() ); vtkwriter->SetLines( vtkreader->GetLines() ); vtkwriter->Update(); */ // std::string filePrefix = output_vtk_filename; // std::string::size_type pos = filePrefix.rfind("."); // std::string extension = std::string(filePrefix, pos, filePrefix.length() // - 1); // filePrefix = std::string(filePrefix, 0, pos); // // std::cout << "output extension is: " << extension << std::endl; // // if (extension != std::string(".mha")) { // typedef itk::VectorImageFileWriter // WriterType; // typename WriterType::Pointer writer = WriterType::New(); // writer->SetFileName(output_vtk_filename); // writer->SetUseAvantsNamingConvention(true); // writer->SetInput(field_output); // writer->Update(); // } else { // typedef itk::ImageFileWriter WriterType; // typename WriterType::Pointer writer = WriterType::New(); // writer->SetFileName(output_vtk_filename); // writer->SetInput(field_output); // writer->Update(); // } } template void ComposeMultiAffine(char *input_affine_txt, char *output_affine_txt, char *reference_affine_txt, TRAN_OPT_QUEUE &opt_queue) { typedef itk::Image ImageType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef itk::WarpImageMultiTransformFilter WarperType; // typedef itk::DeformationFieldFromMultiTransformFilter WarperType; itk::TransformFactory::RegisterTransform(); // typedef itk::ImageFileReader ImageFileReaderType; // typename ImageFileReaderType::Pointer reader_img = ImageFileReaderType::New(); // typename ImageType::Pointer img_ref = ImageType::New(); // typename ImageFileReaderType::Pointer reader_img_ref = ImageFileReaderType::New(); typename WarperType::Pointer warper = WarperType::New(); // warper->SetInput(img_mov); // warper->SetEdgePaddingValue( 0); VectorType pad; pad.Fill(0); // warper->SetEdgePaddingValue(pad); typedef itk::TransformFileReader TranReaderType; typedef itk::VectorImageFileReader FieldReaderType; int cnt_affine = 0; const int kOptQueueSize = opt_queue.size(); for (int i = 0; i < kOptQueueSize; i++) { const TRAN_OPT &opt = opt_queue[i]; switch (opt_queue[i].file_type) { case AFFINE_FILE: { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(opt.filename); tran_reader->Update(); typename AffineTransformType::Pointer aff = dynamic_cast ( (tran_reader->GetTransformList())->front().GetPointer()); if (opt_queue[i].do_affine_inv) { aff->GetInverse(aff); } // std::cout << aff << std::endl; warper->PushBackAffineTransform(aff); cnt_affine++; break; } case DEFORMATION_FILE: { std::cout << "Compose affine only files: ignore " << opt.filename << std::endl; break; } default: std::cout << "Unknown file type!" << std::endl; } } typedef typename AffineTransformType::CenterType PointType; PointType aff_center; typename AffineTransformType::Pointer aff_ref_tmp; if (reference_affine_txt) { typename TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(reference_affine_txt); tran_reader->Update(); aff_ref_tmp = dynamic_cast ((tran_reader->GetTransformList())->front().GetPointer()); } else { if (cnt_affine > 0) { std::cout << "the reference affine file for center is selected as the first affine!" << std::endl; aff_ref_tmp = ((warper->GetTransformList()).begin())->second.aex.aff; } else { std::cout << "No affine input is given. nothing to do ......" << std::endl; return; } } aff_center = aff_ref_tmp->GetCenter(); std::cout << "new center is : " << aff_center << std::endl; // warper->PrintTransformList(); // typename AffineTransformType::Pointer aff_output = warper->ComposeAffineOnlySequence(aff_center); typename AffineTransformType::Pointer aff_output = AffineTransformType::New(); warper->ComposeAffineOnlySequence(aff_center, aff_output); typedef itk::TransformFileWriter TranWriterType; typename TranWriterType::Pointer tran_writer = TranWriterType::New(); tran_writer->SetFileName(output_affine_txt); tran_writer->SetInput(aff_output); tran_writer->Update(); std::cout << "wrote file to : " << output_affine_txt << std::endl; } int main(int argc, char **argv) { if ( argc <= 4 ) { std::cout << "WarpLabeledPointSetFileMultiTransform ImageDimension inputVTKFile " << "outputVTKFile [-R reference_image] " << "{[deformation_field | [-i] affine_transform_txt ]}" << std::endl; exit(0); } TRAN_OPT_QUEUE opt_queue; // char *moving_image_filename = NULL; char *input_vtk_filename = NULL; char *output_vtk_filename = NULL; char *reference_image_filename = NULL; bool is_parsing_ok = false; int kImageDim = atoi(argv[1]); is_parsing_ok = ParseInput(argc - 2, argv + 2, input_vtk_filename, output_vtk_filename, reference_image_filename, opt_queue); if (is_parsing_ok) { switch (CheckFileType(output_vtk_filename)) { case DEFORMATION_FILE: { if (reference_image_filename == NULL) { std::cout << "the reference image file (-R) must be given!!!" << std::endl; return false; } std::cout << "output_vtk_filename: " << output_vtk_filename << std::endl; std::cout << "reference_image_filename: "; if (reference_image_filename) std::cout << reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim) { case 2: { WarpLabeledPointSetFileMultiTransform<2> (input_vtk_filename, output_vtk_filename, reference_image_filename, opt_queue); break; } case 3: { WarpLabeledPointSetFileMultiTransform<3> (input_vtk_filename, output_vtk_filename, reference_image_filename, opt_queue); break; } } break; } case AFFINE_FILE: { std::cout << "output_affine_txt: " << output_vtk_filename << std::endl; std::cout << "reference_affine_txt: "; if (reference_image_filename) std::cout << reference_image_filename << std::endl; else std::cout << "NULL" << std::endl; DisplayOptQueue(opt_queue); switch (kImageDim) { case 2: { ComposeMultiAffine<2>(input_vtk_filename, output_vtk_filename, reference_image_filename, opt_queue); break; } case 3: { ComposeMultiAffine<3> (input_vtk_filename, output_vtk_filename, reference_image_filename, opt_queue); break; } } break; } default: std::cout << "Unknow output file format: " << output_vtk_filename << std::endl; break; } } else { std::cout << "Input error!" << std::endl; } exit(0); } ants-1.9.2+svn680.dfsg/Examples/itkCommandLineParserTest.cxx000066400000000000000000000042661147325206600237050ustar00rootroot00000000000000 #include "itkPICSLAdvancedNormalizationToolKit.h" #include "itkCommandLineParser.h" int main( int argc, char *argv[] ) { typedef itk::PICSLAdvancedNormalizationToolKit<3> RegistrationType; RegistrationType::Pointer registration = RegistrationType::New(); registration->ParseCommandLine( argc, argv ); typedef itk::CommandLineParser ParserType; ParserType::Pointer parser = ParserType::New(); typedef ParserType::OptionType OptionType; OptionType::Pointer fileOption = OptionType::New(); fileOption->SetShortName( 'f' ); fileOption->SetLongName( "file" ); fileOption->SetDescription( "The fixed image file used in the image registration algorithm." ); parser->AddOption( fileOption ); typedef ParserType::OptionType OptionType; OptionType::Pointer metricOption = OptionType::New(); metricOption->SetShortName( 'm' ); metricOption->SetLongName( "metric" ); metricOption->SetDescription( "The metric used by the image registration algorithm." ); parser->AddOption( metricOption ); typedef ParserType::OptionType OptionType; OptionType::Pointer verbosityOption = OptionType::New(); verbosityOption->SetLongName( "verbosity" ); verbosityOption->SetDescription( "Mundi vult decipi. " ); parser->AddOption( verbosityOption ); typedef ParserType::OptionType OptionType; OptionType::Pointer dirOption = OptionType::New(); dirOption->SetLongName( "directionality" ); // dirOption->SetShortName( 'd' ); dirOption->SetDescription( "Mundi vult decipi. " ); parser->AddOption( dirOption ); parser->Parse( argc, argv ); if ( !parser->GetOption( "directionality" ) ) { std::cout << "N ULL" << std::endl; } else { for ( unsigned int j = 0; j < 3; j++ ) { std::cout << parser->ConvertVector( parser->GetOption( "directionality" )->GetValue( 0 ) )[j] << " x "; } } parser->PrintMenu( std::cout, 7 ); // std::cout << std::endl << std::endl << "--------------------------------------------" // << std::endl << std::endl; // parser->Print( std::cout << 7 ); return 0; }; ants-1.9.2+svn680.dfsg/ImageRegistration/000077500000000000000000000000001147325206600200755ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/ImageRegistration/ANTS_affine_registration.h000066400000000000000000001567561147325206600251410ustar00rootroot00000000000000#ifndef ANTS_AFFINE_REGISTRATION_H_ #define ANTS_AFFINE_REGISTRATION_H_ #include #include #include #include "itkImage.h" #include "itkPoint.h" #include "itkCastImageFilter.h" #include "itkImageMaskSpatialObject.h" #include "itkCenteredEuler3DTransform.h" #include "itkRegularStepGradientDescentOptimizer.h" #include "itkGradientDescentOptimizer.h" #include "itkCenteredTransformInitializer.h" #include "itkMattesMutualInformationImageToImageMetric.h" #include "itkMultiResolutionImageRegistrationMethod.h" #include "itkLinearInterpolateImageFunction.h" #include "itkANTSAffine3DTransform.h" #include "itkCenteredRigid2DTransform.h" #include "itkANTSCenteredAffine2DTransform.h" #include "itkTransformFactory.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkResampleImageFilter.h" #include "itkLinearInterpolateImageFunction.h" #include "itkWarpImageFilter.h" #include "itkWarpImageWAffineFilter.h" template void read_transform_file(StringType filename, CastTransformPointerType &transform); template void write_transform_file(TransformPointerType &transform, StringType str); template void compute_single_affine_transform_3d(ImagePointerType I_fixed, ImagePointerType I_moving, MaskImagePointerType mask_fixed, TransformPointerType &transform, TransformPointerType &transform_initial); template void compute_single_affine_transform_2d(ImagePointerType I_fixed, ImagePointerType I_moving, MaskImagePointerType mask_fixed, TransformPointerType &transform, TransformPointerType &transform_initial); template void compute_single_affine_transform(ImagePointerType fixedImage, ImagePointerType movingImage, MaskImagePointerType maskImage, TransformPointerType &transform, TransformPointerType &transform_initial); //void compute_single_affine_transform_2d(itk::Image::Pointer I_fixed, // itk::Image::Pointer I_moving, // itk::Image::Pointer mask_fixed, // itk::CenteredAffine2DTransform::Pointer &transform); template void create_deformation_field_byref(const DeformationFieldPointerType &ref, DeformationFieldPointerType &field); // this is obsolet, use itkWarpImageWAffineFilter template void compose_affine_with_field(const TransformPointerType &aff, const DeformationFieldPointerType &field, DeformationFieldPointerType &field_output); template void warp_image_field(const ImagePointerType &img_input, const DeformationFieldPointerType &field, ImagePointerType &img_output); template void warp_image_field_waffine(const ImagePointerType &img_input, const TransformPointerType &aff, const DeformationFieldPointerType &field, ImagePointerType &img_output); template void affine_image(const ImageTypePointer &input_image, const TransformTypePointer &transform, const RefImageTypePointer &ref_image, ImageTypePointer &img_aff ); template void write_transform_file(TransformPointerType &transform, StringType filename){ itk::TransformFileWriter::Pointer transform_writer; transform_writer = itk::TransformFileWriter::New(); transform_writer->SetFileName(filename); transform_writer->SetInput(transform); try{ transform_writer->Update(); } catch( itk::ExceptionObject &err){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl <<"Exception in writing tranform file: " << std::endl << filename << std::endl; return; } return; } template void read_transform_file(StringType filename, CastTransformPointerType &transform){ typedef typename CastTransformPointerType::ObjectType CastTransformType; // const unsigned int InputSpaceDimension = CastTransformType::InputSpaceDimension; // const unsigned int OutputSpaceDimension = CastTransformType::OutputSpaceDimension; itk::TransformFactory::RegisterTransform(); itk::TransformFactory >::RegisterTransform(); typedef typename itk::TransformFileReader TranReaderType; TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(filename); try{ tran_reader->Update(); } catch( itk::ExceptionObject &err) { std::cerr << err << std::endl; std::cerr << "Exception caught in reading tran para file: " << filename << std::endl; return; } transform = dynamic_cast< CastTransformType* >((tran_reader->GetTransformList())->front().GetPointer()); return; } template void convert_affine_para_to_deformation_field(TransformPointerType &transform, DeformationFieldType &def){ return; } template class SEARCH_POINT_TYPE { public: ParaType para0; // seed parameter ParaType para1; // local optimal parameter itk::Point center; // transformation center double rval; // registered value unsigned int index; // the index in the list, //for sorting int number_of_iteration; // the number of iteration used for gradient descent }; template void generate_search_seed_3d(SEARCH_LIST &search_list, ParaType &ret); template void generate_search_seed_2d(SEARCH_LIST &search_list, ParaType &ret); template void get_best_search_point(SEARCH_LIST &search_list, SEARCH_POINT &spt); template void add_search_point(SEARCH_LIST &search_list, SEARCH_POINT spt); // use moment of the image initializer to get cx and cy only template bool register_image_cxyz(ImagePointerType fixed_image, ImagePointerType moving_image, ParaType ¶1, double &rval); // use an optional mask for the fixed image template bool register_image_affine3d_mres_mask(ImagePointerType fixed_image, ImagePointerType moving_image, ImageMaskSpatialObjectPointerType mask_fixed_object, ParaType para0, itk::Point center, int number_of_iteration, int MI_bins, int MI_samples, ParaType ¶1, double &rval); template bool register_image_affine2d_mres_mask(ImagePointerType fixed_image, ImagePointerType moving_image, ImageMaskSpatialObjectPointerType mask_fixed_object, ParaType para0, itk::Point center, int number_of_iteration, int MI_bins, int MI_samples, ParaType ¶1, double &rval); template double get_cost_value_mmi(ImagePointerType fixedImage, ImagePointerType movingImage, ParaType para, PointType center, TransformTypePointer null_transform); template bool compare_search_point(const SEARCH_POINT& lhs, const SEARCH_POINT& rhs){ return lhs.rval < rhs.rval; } template void compute_single_affine_transform_3d(ImagePointerType I_fixed, ImagePointerType I_moving, MaskImagePointerType mask_fixed, TransformPointerType &transform, TransformPointerType &transform_initial){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::ImageDimension; typedef typename ImageType::IOPixelType PixelType; typedef typename MaskImagePointerType::ObjectType MaskImageType; typedef typename MaskImageType::IOPixelType MaskPixelType; typedef typename TransformPointerType::ObjectType TransformType; typedef typename TransformType::ParametersType ParaType; // option parameters int number_of_seeds = 0; int number_of_iteration = 10000; int MI_bins = 32; int MI_samples = 6000; unsigned int time_seed = (unsigned int) time(NULL) ; srand(time_seed); //TODO: need to fix here bool b_use_mask = 0; //(mask_fixed == NULL); std::cout<<"number_of_seeds: " << number_of_seeds << std::endl; std::cout<<"rand_time_seed: " << time_seed << std::endl; std::cout<<"number_of_iteration: " << number_of_iteration << std::endl; std::cout<<"MI_bins: " << MI_bins << std::endl; std::cout<<"MI_samples: " << MI_samples < SEARCH_POINT; typedef std::vector SEARCH_LIST; SEARCH_LIST search_list; // typedef itk::ImageMaskSpatialObject ImageMaskSpatialObject; typedef itk::ImageMaskSpatialObject ImageMaskSpatialObject; typename ImageMaskSpatialObject::Pointer mask_fixed_object = 0; if (b_use_mask){ typedef itk::Image CharMaskImageType; typedef itk::CastImageFilter CastFilterType; typename CastFilterType::Pointer cast_filter = CastFilterType::New(); cast_filter->SetInput(mask_fixed); cast_filter->Update(); typename CharMaskImageType::Pointer mask_fixed_char = cast_filter->GetOutput(); mask_fixed_object = ImageMaskSpatialObject::New(); mask_fixed_object->SetImage(mask_fixed_char); } typename ImageType::PointType origin; origin.Fill(0); I_moving->SetOrigin(origin); I_fixed->SetOrigin(origin); typename TransformType::Pointer trans = TransformType::New(); ParaType para0(trans->GetNumberOfParameters()), para1(trans->GetNumberOfParameters()); double rval; SEARCH_POINT spt; typedef itk::CenteredEuler3DTransform TransformType_Euler3D; ParaType para_cxy(TransformType_Euler3D::New()->GetNumberOfParameters()); // translated from pre registration // find initial center bool is_ok = false; itk::Point center; if (transform_initial.IsNull()){ is_ok = register_image_cxyz(I_fixed, I_moving, para_cxy, rval); if (!is_ok){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl <<"initial affine registeration falied" << std::endl; exit(-1); } center[0] = para_cxy[3]; center[1] = para_cxy[4]; center[2] = para_cxy[5]; } else { center[0] = transform_initial->GetCenter()[0]; center[1] = transform_initial->GetCenter()[1]; center[2] = transform_initial->GetCenter()[2]; } std::cout << std::endl; for (int n = 0; (number_of_seeds > 0) ? (n < number_of_seeds) : (n <= number_of_seeds) ; n++){ if (n==0){ if (transform_initial.IsNull()) { para0[0] = 0.0; para0[1] = 0.0; para0[2] = 0.0; para0[3] = 1.0; para0[4] = 1.0; para0[5] = 1.0; para0[6] = 1.0; para0[7] = 0.0; para0[8] = 0.0; para0[9] = 0.0; para0[10] = 0.0; para0[11] = 0.0; para0[12] = 0.0; } else { // use input as intial for(unsigned int i=0; iGetParameters().Size(); i++){ para0[i] = transform_initial->GetParameters()[i]; } } } else{ generate_search_seed_3d(search_list, para0); } // main registration using affine transform is_ok = register_image_affine3d_mres_mask(I_fixed, I_moving, mask_fixed_object, para0, center, number_of_iteration, MI_bins, MI_samples, para1, rval); if (!is_ok){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl << "affine registration failed!" << std::endl << "use the initial parameters" << std::endl; // return -1; } spt.para0 = para0; spt.para1 = para1; spt.center = center; spt.rval = rval; spt.index= n; spt.number_of_iteration = number_of_iteration; std::cout << "para0: " << para0 << std::endl; std::cout << "para1: " << para1 << std::endl; std::cout << "center: " << center << std::endl; std::cout << "rval: " << rval << std::endl; std::cout << "add the search result to the list ... seed [" << n << "]" << std::endl << std::endl; add_search_point(search_list, spt); } get_best_search_point(search_list, spt); std::cout<< std::endl << "History: " << std::endl; for(int ii = 0; ii < search_list.size(); ii++){ std::cout << "[" << ii << "]: " << search_list[ii].rval << std::endl; std::cout << "center: " << search_list[ii].center << std::endl; std::cout << "para0: " << search_list[ii].para0 << std::endl; std::cout << "para1: " << search_list[ii].para1 << std::endl; } typename TransformType::Pointer transform_final = TransformType::New(); transform_final->SetParameters(spt.para1); transform_final->SetCenter(center); std::cout << "final transform parameters = " << transform_final->GetParameters() << std::endl; transform = transform_final; } double myrand(double l, double u) { // std::cout<<"in myrand" << std::endl; double r = l + (u-l)*rand()/(RAND_MAX+1.0); return r; // std::cout<<"out myrand" << std::endl; } template double dist2_search_point(ParaType para0, ParaType para1) { // use theta / scale / skew to compare two nodes double d2 = 0; // double scale[4] = {1.0, 1.0, 1.0, 1.0}; for (int ii = 0; ii<12; ii++){ double a = para0[ii]-para1[ii]; d2 += a * a; // * scale[ii]; } return d2; } template void generate_search_seed_3d(SEARCH_LIST &search_list, ParaType ¶){ bool b_found = 0; double s1, s2, s3, k1, k2, k3 = 0; double a=0; // rotation alpha double u=0, v=0, w=0; // rotation axis // ParaType para(13); const double scale_upper = 1.5; const double scale_lower = 1 / 1.5; const double skew_lower = -1.0; const double skew_upper = 1.0; const double dist2_thres = 0.3; const double mypi = 3.1415926536; const double rot_angle_upper = mypi * (0.5); const double rot_angle_lower = mypi * (-0.5); unsigned int iteration = 0; unsigned int maxiteration = 50; while(b_found==0 && iteration < maxiteration ){ iteration++; s1 = myrand(scale_lower, scale_upper); s2 = myrand(scale_lower, scale_upper); s3 = myrand(scale_lower, scale_upper); k1 = myrand(skew_lower, skew_upper); k2 = myrand(skew_lower, skew_upper); k3 = myrand(skew_lower, skew_upper); a = myrand(rot_angle_lower, rot_angle_upper); u = myrand(-1, 1); v = myrand(-1, 1); w = myrand(-1, 1); double n1 = 1.0/sqrt(u*u + v*v + w*w); double sin_half_a = sin(a*0.5); para.Fill(0.0); para[0] = sin_half_a * u * n1; para[1] = sin_half_a * v * n1; para[2] = sin_half_a * w * n1; para[3] = cos(a*0.5); para[4] = s1; para[5] = s2; para[6] = s3; para[7] = k1; para[8] = k2; para[9] = k3; // std::cout << "test rand: " << para << " iteration " << iteration << std::endl; // search nearby search points bool bfar = 1; for (int i=0; (bfar) & (i dist2_thres) & (d1 > dist2_thres); } b_found = bfar; // std::cout << "b_found = " << b_found << " bfar = " << bfar << std::endl; } // ret = para; } template void generate_search_seed_2d(SEARCH_LIST &search_list, ParaType ¶){ bool b_found = 0; double r1, s1, s2, k = 0; const double pi = 3.1415927; const double theta_upper = pi / 4 ; const double theta_lower = -pi / 4; const double scale_upper = 1.5; const double scale_lower = 1 / 1.5; const double skew_lower = -1.0; const double skew_upper = 1.0; const double dist2_thres = 0.1; unsigned int iteration = 0; unsigned int maxiteration = 50; while(b_found==0 && iteration < maxiteration ){ // for(;~b_found; ){ // std::cout << "b_found = " << b_found << std::endl; iteration++; r1 = myrand(theta_lower, theta_upper); s1 = myrand(scale_lower, scale_upper); s2 = myrand(scale_lower, scale_upper); k = myrand(skew_lower, skew_upper); para.Fill(0.0); para[0] = r1; para[1] = s1; para[2] = s2; para[3] = k; // // std::cout << "test rand: " << para << " iteration " << iteration << std::endl; // search nearby search points bool bfar = 1; for (int i=0; (bfar) & (i dist2_thres) & (d1 > dist2_thres); } b_found = bfar; // std::cout << "b_found = " << b_found << " bfar = " << bfar << std::endl; } } template void get_best_search_point(SEARCH_LIST &search_list, SEARCH_POINT &spt){ std::sort(search_list.begin(), search_list.end(), compare_search_point); spt = search_list[0]; } template void add_search_point(SEARCH_LIST &search_list, SEARCH_POINT spt){ search_list.push_back(spt); } template double get_cost_value_mmi(ImagePointerType fixedImage, ImagePointerType movingImage, ParaType para, PointType center, TransformTypePointer null_transform){ typedef typename ImagePointerType::ObjectType ImageType; typedef typename TransformTypePointer::ObjectType TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetCenter(center); // transform->SetParameters(para); typedef typename itk::MattesMutualInformationImageToImageMetric mattesMutualInfoMetricType; typename mattesMutualInfoMetricType::Pointer mattesMutualInfo=mattesMutualInfoMetricType::New(); typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator=InterpolatorType::New(); interpolator->SetInputImage(movingImage); mattesMutualInfo->SetFixedImage(fixedImage); mattesMutualInfo->SetMovingImage(movingImage); mattesMutualInfo->SetFixedImageRegion(fixedImage->GetBufferedRegion()); // mattesMutualInfo->SetMovingImage(outputImage); mattesMutualInfo->SetTransform(transform); mattesMutualInfo->SetInterpolator(interpolator); mattesMutualInfo->SetNumberOfHistogramBins( 32 ); mattesMutualInfo->SetNumberOfSpatialSamples( 5000 ); mattesMutualInfo->SetTransformParameters(para); mattesMutualInfo->Initialize(); double rval = 0; try{ rval = mattesMutualInfo->GetValue(para); } catch (itk::ExceptionObject &err){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl << "Exception caught in computing mattesMutualInfo after registration" << std::endl << "Maybe: Too many samples map outside moving image buffer" << std::endl << "Set the cost value = 0 (max for MutualInfo) " << std::endl; rval = 0; } // test the cost before registration transform->SetIdentity(); transform->SetCenter(center); ParaType para0 = transform->GetParameters(); mattesMutualInfo->SetTransformParameters(para0); mattesMutualInfo->Initialize(); double rval0 = 0; try{ rval0 = mattesMutualInfo->GetValue(para0); } catch(itk::ExceptionObject &err) { std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl << "Exception caught in computing mattesMutualInfo before registration" << std::endl << "Maybe: Too many samples map outside moving image buffer" << std::endl << "Set the cost value = 0 (max for MutualInfo) " << std::endl; rval0 = 0; } std::cout << "in cost: before register: cost = " << rval0 << std::endl; std::cout << "in cost: after register: cost = " << rval << std::endl; return rval; } template bool register_image_cxy(ImagePointerType fixed_image, ImagePointerType moving_image, ParaType ¶1, double &rval){ // for 3d image use CenteredRigid2DTransform typedef itk::RegularStepGradientDescentOptimizer OptimizerType; typedef itk::CenteredRigid2DTransform TransformType_Rigid2D; typedef typename ImagePointerType::ObjectType ImageType; typename TransformType_Rigid2D::Pointer transform = TransformType_Rigid2D::New(); typedef itk::CenteredTransformInitializer< TransformType_Rigid2D, ImageType, ImageType > TransformInitializerType; typename TransformInitializerType::Pointer initializer = TransformInitializerType::New(); try { transform->SetIdentity(); initializer->SetTransform( transform ); initializer->SetFixedImage( fixed_image ); initializer->SetMovingImage( moving_image ); initializer->MomentsOn(); initializer->InitializeTransform(); transform->SetAngle( 0.0 ); } catch (itk::ExceptionObject &err) { std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!1" << std::endl << "Exception in InitializeTransform" << std::endl; return false; } para1 = transform->GetParameters(); std::cout << "finish initialize cx/cy/cz ..." << std::endl; std::cout << "cx/cy parameters (Euler3D): " << para1 << std::endl; return true; } template bool register_image_cxyz(ImagePointerType fixed_image, ImagePointerType moving_image, ParaType ¶1, double &rval){ // for 3d image use CenteredRigid2DTransform typedef itk::RegularStepGradientDescentOptimizer OptimizerType; typedef itk::CenteredEuler3DTransform TransformType_Euler3D; typedef typename ImagePointerType::ObjectType ImageType; TransformType_Euler3D::Pointer transform = TransformType_Euler3D::New(); typedef itk::CenteredTransformInitializer< TransformType_Euler3D, ImageType, ImageType > TransformInitializerType; typename TransformInitializerType::Pointer initializer = TransformInitializerType::New(); try { transform->SetIdentity(); initializer->SetTransform( transform ); initializer->SetFixedImage( fixed_image ); initializer->SetMovingImage( moving_image ); initializer->MomentsOn(); initializer->InitializeTransform(); } catch (itk::ExceptionObject &err) { std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!1" << std::endl << "Exception in InitializeTransform" << std::endl; return false; } para1 = transform->GetParameters(); std::cout << "finish initialize cx/cy/cz ..." << std::endl; std::cout << "cx/cy parameters (Euler3D): " << para1 << std::endl; return true; } template bool register_image_affine3d_mres_mask(ImagePointerType fixed_image, ImagePointerType moving_image, ImageMaskSpatialObjectPointerType mask_fixed_object, ParaType para0, itk::Point center, int number_of_iteration, int MI_bins, int MI_samples, ParaType ¶1, double &rval){ typedef typename ImagePointerType::ObjectType ImageType; typedef itk::RegularStepGradientDescentOptimizer OptimizerType; typedef itk::MattesMutualInformationImageToImageMetric< ImageType, ImageType> MetricType; typedef typename ImagePointerType::ObjectType ImageType; typename MetricType::Pointer metric = MetricType::New(); // for mattesMutualInfo metric->SetNumberOfHistogramBins( MI_bins ); /** 32 BA */ metric->SetNumberOfSpatialSamples( MI_samples );/** 6000 BA */ if (mask_fixed_object){ metric->SetFixedImageMask(mask_fixed_object); std::cout << mask_fixed_object << std::endl; std::cout << mask_fixed_object->GetImage() << std::endl; } // typedef TransformType_Rigid2D TransformType_Pre; typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::MultiResolutionImageRegistrationMethod RegistrationType; typedef itk::MultiResolutionPyramidImageFilter fPyramidType; typename fPyramidType::Pointer fixedImagePyramid = fPyramidType::New(); typename fPyramidType::Pointer movingImagePyramid = fPyramidType::New(); typename ImageType::PointType origin; origin.Fill(0); moving_image->SetOrigin(origin); fixed_image->SetOrigin(origin); typename OptimizerType::Pointer optimizer = OptimizerType::New(); typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); typename RegistrationType::Pointer registration = RegistrationType::New(); typedef OptimizerType::ScalesType OptimizerScalesType; /*******************************************/ /* translate to para0 here */ std::cout << "pre registration para :" << para0 << std::endl; typedef itk::ANTSAffine3DTransform TransformType_ANTSAffine3D; typename TransformType_ANTSAffine3D::Pointer transform_a = TransformType_ANTSAffine3D::New(); transform_a->SetCenter(center); std::cout<<"initial center: " << transform_a->GetCenter() << std::endl; // typedef OptimizerType::ScalesType OptimizerScalesType; OptimizerScalesType optimizerScales_a( transform_a->GetNumberOfParameters() ); const double translationScale = 1.0/1.e4; /** BA */// /1.e6; // 1.e6; //1.e6; //1.0 / 1000.0; optimizerScales_a[0] = 1.0; // quaternion optimizerScales_a[1] = 1.0; // quaternion optimizerScales_a[2] = 1.0; // quaternion optimizerScales_a[3] = 1.0; // quaternion optimizerScales_a[4] = 1.0; // s1 optimizerScales_a[5] = 1.0; // s2 optimizerScales_a[6] = 1.0; // s3 optimizerScales_a[7] = 1.0; // k1 optimizerScales_a[8] = 1.0; // k2 optimizerScales_a[9] = 1.0; // k3 optimizerScales_a[10] = translationScale; optimizerScales_a[11] = translationScale; optimizerScales_a[12] = translationScale; optimizer->SetScales( optimizerScales_a ); optimizer->SetMaximumStepLength(0.1); optimizer->SetMinimumStepLength( 1.e-5 ); // optimizer->SetNumberOfIterations( 1000 ); // optimizer->SetNumberOfIterations( 500 ); optimizer->SetNumberOfIterations(number_of_iteration); // (500); /** BA */ optimizer->MinimizeOn(); // Create the Command observer and register it with the optimizer. // // CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); // optimizer->AddObserver( itk::IterationEvent(), observer ); registration = RegistrationType::New(); registration->SetNumberOfLevels(3); registration->SetFixedImagePyramid( fixedImagePyramid ); registration->SetMovingImagePyramid( movingImagePyramid ); registration->SetMetric( metric ); registration->SetOptimizer( optimizer ); registration->SetInterpolator( interpolator ); registration->SetFixedImage( fixed_image ); registration->SetMovingImage( moving_image ); registration->SetFixedImageRegion( fixed_image->GetLargestPossibleRegion() ); registration->SetTransform( transform_a ); // reset the parameter // registration->SetInitialTransformParameters(para_pre ); registration->SetInitialTransformParameters(para0 ); std::cout << "reset initial transform parameters" << std::endl; std::cout << "para_pre: " << para0 << std::endl; // std::cout << "transform_a: " << transform_a << std::endl; rval = get_cost_value_mmi(fixed_image, moving_image, para0, center, transform_a); std::cout << "init measure value: rval = " << rval << std::endl; // rval = optimizer->GetValue(para0); // rval = metric->GetValue(para0); bool bsuc = 1; try { registration->StartRegistration(); } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; bsuc = 0; // exit(-1); } if (bsuc){ // OptimizerType::ParametersType // finalParameters = registration->GetLastTransformParameters(); para1 = registration->GetLastTransformParameters(); // para1 = finalParameters; // rval = optimizer->GetValue(para1); // rval = metric->GetValue(para1); // rval = registration->GetMetric()->GetValue(para1); rval = get_cost_value_mmi(fixed_image, moving_image, para1, center, transform_a); // double rval2 = optimizer->GetValue(); // std::cout << "measure value: rval2 = " << rval2 << std::endl; } else{ // register failed para1 = para0; // registration->GetLastTransformParameters(); rval = get_cost_value_mmi(fixed_image, moving_image, para1, center, transform_a); } std::cout << "final affine3d registration para :" << para1 << std::endl; std::cout << "use iteration: " << optimizer->GetNumberOfIterations() << std::endl; std::cout << "measure value: rval = " << rval << std::endl; std::cout << "finish register..." << std::endl; return bsuc; } template bool register_image_affine2d_mres_mask(ImagePointerType fixed_image, ImagePointerType moving_image, ImageMaskSpatialObjectPointerType mask_fixed_object, ParaType para0, itk::Point center, int number_of_iteration, int MI_bins, int MI_samples, ParaType ¶1, double &rval){ typedef typename ImagePointerType::ObjectType ImageType; typedef itk::RegularStepGradientDescentOptimizer OptimizerType; typedef itk::MattesMutualInformationImageToImageMetric< ImageType, ImageType> MetricType; typedef typename ImagePointerType::ObjectType ImageType; typename MetricType::Pointer metric = MetricType::New(); // for mattesMutualInfo metric->SetNumberOfHistogramBins( MI_bins ); /** 32 BA */ metric->SetNumberOfSpatialSamples( MI_samples );/** 6000 BA */ if (mask_fixed_object){ metric->SetFixedImageMask(mask_fixed_object); std::cout << mask_fixed_object << std::endl; std::cout << mask_fixed_object->GetImage() << std::endl; } // typedef TransformType_Rigid2D TransformType_Pre; typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::MultiResolutionImageRegistrationMethod RegistrationType; typedef itk::MultiResolutionPyramidImageFilter fPyramidType; typename fPyramidType::Pointer fixedImagePyramid = fPyramidType::New(); typename fPyramidType::Pointer movingImagePyramid = fPyramidType::New(); typename ImageType::PointType origin; origin.Fill(0); moving_image->SetOrigin(origin); fixed_image->SetOrigin(origin); typename OptimizerType::Pointer optimizer = OptimizerType::New(); typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); typename RegistrationType::Pointer registration = RegistrationType::New(); typedef OptimizerType::ScalesType OptimizerScalesType; /*******************************************/ /* translate to para0 here */ std::cout << "pre registration para :" << para0 << std::endl; // typedef itk::CenteredAffine2DTransform TransformType; // typedef itk::CenteredAffine2DTransform TransformType_GSAffine2D; // typename TransformType_GSAffine2D::Pointer transform_a = TransformType_GSAffine2D::New(); typedef itk::ANTSCenteredAffine2DTransform TransformType_ANTSAffine2D; typename TransformType_ANTSAffine2D::Pointer transform_a = TransformType_ANTSAffine2D::New(); // transform_a->SetCenter(center); // std::cout<<"initial center: " << transform_a->GetCenter() << std::endl; OptimizerScalesType optimizerScales_a( transform_a->GetNumberOfParameters() ); const double translationScale = 1.0 / 1000.0; optimizerScales_a[0] = 1.0; optimizerScales_a[1] = 1.0; optimizerScales_a[2] = 1.0; optimizerScales_a[3] = 1.0; optimizerScales_a[4] = translationScale; optimizerScales_a[5] = translationScale; optimizerScales_a[6] = translationScale; optimizerScales_a[7] = translationScale; optimizer->SetScales( optimizerScales_a ); optimizer->SetMaximumStepLength( 0.1 ); optimizer->SetMinimumStepLength( 0.01 ); optimizer->SetNumberOfIterations( number_of_iteration ); optimizer->MinimizeOn(); // Create the Command observer and register it with the optimizer. // // CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); // optimizer->AddObserver( itk::IterationEvent(), observer ); registration = RegistrationType::New(); registration->SetNumberOfLevels(3); registration->SetFixedImagePyramid( fixedImagePyramid ); registration->SetMovingImagePyramid( movingImagePyramid ); registration->SetMetric( metric ); registration->SetOptimizer( optimizer ); registration->SetInterpolator( interpolator ); registration->SetFixedImage( fixed_image ); registration->SetMovingImage( moving_image ); registration->SetFixedImageRegion( fixed_image->GetLargestPossibleRegion() ); registration->SetTransform( transform_a ); // reset the parameter // registration->SetInitialTransformParameters(para_pre ); registration->SetInitialTransformParameters(para0 ); std::cout << "reset initial transform parameters" << std::endl; std::cout << "para_pre: " << para0 << std::endl; // std::cout << "transform_a: " << transform_a << std::endl; rval = get_cost_value_mmi(fixed_image, moving_image, para0, center, transform_a); std::cout << "init measure value: rval = " << rval << std::endl; // rval = optimizer->GetValue(para0); // rval = metric->GetValue(para0); bool bsuc = 1; try { registration->StartRegistration(); } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; bsuc = 0; // exit(-1); } if (bsuc){ // OptimizerType::ParametersType // finalParameters = registration->GetLastTransformParameters(); para1 = registration->GetLastTransformParameters(); // para1 = finalParameters; // rval = optimizer->GetValue(para1); // rval = metric->GetValue(para1); // rval = registration->GetMetric()->GetValue(para1); rval = get_cost_value_mmi(fixed_image, moving_image, para1, center, transform_a); // double rval2 = optimizer->GetValue(); // std::cout << "measure value: rval2 = " << rval2 << std::endl; } else{ // register failed para1 = para0; // registration->GetLastTransformParameters(); rval = get_cost_value_mmi(fixed_image, moving_image, para1, center, transform_a); } std::cout << "final affine2d registration para :" << para1 << std::endl; std::cout << "use iteration: " << optimizer->GetNumberOfIterations() << std::endl; std::cout << "measure value: rval = " << rval << std::endl; std::cout << "finish register..." << std::endl; return bsuc; } // template // void compute_single_affine_transform_2d(ImagePointerType I_fixed, ImagePointerType I_moving, MaskImagePointerType mask_fixed, TransformPointerType &transform){ template void compute_single_affine_transform_2d(ImagePointerType I_fixed, ImagePointerType I_moving, MaskImagePointerType mask_fixed, TransformPointerType &transform, TransformPointerType &transform_initial){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::ImageDimension; typedef typename ImageType::IOPixelType PixelType; typedef typename MaskImagePointerType::ObjectType MaskImageType; typedef typename MaskImageType::IOPixelType MaskPixelType; typedef typename TransformPointerType::ObjectType TransformType; typedef typename TransformType::ParametersType ParaType; // option parameters int number_of_seeds = 0; int number_of_iteration = 500; int MI_bins = 32; int MI_samples = 6000; unsigned int time_seed = (unsigned int) time(NULL) ; srand(time_seed); //TODO: need to fix here bool b_use_mask = 0; //(mask_fixed == NULL); std::cout<<"number_of_seeds: " << number_of_seeds << std::endl; std::cout<<"rand_time_seed: " << time_seed << std::endl; std::cout<<"number_of_iteration: " << number_of_iteration << std::endl; std::cout<<"MI_bins: " << MI_bins << std::endl; std::cout<<"MI_samples: " << MI_samples < SEARCH_POINT; typedef std::vector SEARCH_LIST; SEARCH_LIST search_list; // typedef itk::ImageMaskSpatialObject ImageMaskSpatialObject; typedef typename itk::ImageMaskSpatialObject ImageMaskSpatialObject; typename ImageMaskSpatialObject::Pointer mask_fixed_object = 0; if (b_use_mask){ typedef typename itk::Image CharMaskImageType; typedef typename itk::CastImageFilter CastFilterType; typename CastFilterType::Pointer cast_filter = CastFilterType::New(); cast_filter->SetInput(mask_fixed); cast_filter->Update(); typename CharMaskImageType::Pointer mask_fixed_char = cast_filter->GetOutput(); mask_fixed_object = ImageMaskSpatialObject::New(); mask_fixed_object->SetImage(mask_fixed_char); } typename ImageType::PointType origin; origin.Fill(0); I_moving->SetOrigin(origin); I_fixed->SetOrigin(origin); typename TransformType::Pointer trans = TransformType::New(); ParaType para0(trans->GetNumberOfParameters()), para1(trans->GetNumberOfParameters()); double rval; SEARCH_POINT spt; typedef typename itk::CenteredRigid2DTransform TransformType_Rigid2D; ParaType para_cxy(TransformType_Rigid2D::New()->GetNumberOfParameters()); // translated from pre registration // find initial center bool is_ok = false; itk::Point center; if (transform_initial.IsNull()){ // if (1) { is_ok = register_image_cxy(I_fixed, I_moving, para_cxy, rval); if (!is_ok){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl <<"initial affine registeration falied" << std::endl; exit(-1); } center[0] = para_cxy[1]; center[1] = para_cxy[2]; std::cout << "is_ok=" << is_ok << "para_cxy:" << para_cxy << std::endl; } else { center[0] = transform_initial->GetCenter()[0]; center[1] = transform_initial->GetCenter()[1]; std::cout << "input transform: " << transform_initial << std::endl; } std::cout << "initial center: (" << center[0] << "," << center[1] << ")" << std::endl; for (int n = 0; (number_of_seeds > 0) ? (n < number_of_seeds) : (n <= number_of_seeds) ; n++){ if (n==0){ // if (1) { if (transform_initial.IsNull()){ para0[0] = 0; // para1[0]; // theta para0[1] = 1.0; //s1 para0[2] = 1.0; //s2 para0[3] = 0.0; //k para0[4] = center[0]; // para1[1]; //c1 para0[5] = center[1]; // para1[2]; //c2 para0[6] = para_cxy[3]; // 0;//para1[3]; //t1 para0[7] = para_cxy[4]; //0; //para1[4]; //t2 std::cout << "ABC: " << std::endl; } else { for(unsigned int i=0; iGetParameters().Size(); i++){ para0[i] = transform_initial->GetParameters()[i]; } std::cout << "DEF: " << std::endl; } } else{ generate_search_seed_2d(search_list, para0); } // main registration using affine transform is_ok = register_image_affine2d_mres_mask(I_fixed, I_moving, mask_fixed_object, para0, center, number_of_iteration, MI_bins, MI_samples, para1, rval); if (!is_ok){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl << "affine registration failed!" << std::endl << "use the initial parameters" << std::endl; // return -1; } spt.para0 = para0; spt.para1 = para1; spt.center = center; spt.rval = rval; spt.index= n; spt.number_of_iteration = number_of_iteration; std::cout << "para0: " << para0 << std::endl; std::cout << "para1: " << para1 << std::endl; std::cout << "center: " << center << std::endl; std::cout << "rval: " << rval << std::endl; std::cout << "add the search result to the list ... seed [" << n << "]" << std::endl << std::endl; add_search_point(search_list, spt); } get_best_search_point(search_list, spt); std::cout<< std::endl << "History: " << std::endl; for(int ii = 0; ii < search_list.size(); ii++){ std::cout << "[" << ii << "]: " << search_list[ii].rval << std::endl; std::cout << "center: " << search_list[ii].center << std::endl; std::cout << "para0: " << search_list[ii].para0 << std::endl; std::cout << "para1: " << search_list[ii].para1 << std::endl; } typename TransformType::Pointer transform_final = TransformType::New(); transform_final->SetParameters(spt.para1); transform_final->SetCenter(center); std::cout << "final transform parameters = " << transform_final->GetParameters() << std::endl; transform = transform_final; } template void compute_single_affine_transform(ImagePointerType fixedImage, ImagePointerType movingImage, MaskImagePointerType maskImage, TransformPointerType &transform, TransformPointerType &transform_initial){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::ImageDimension; typedef typename ImageType::IOPixelType PixelType; typedef typename MaskImagePointerType::ObjectType MaskImageType; typedef typename MaskImageType::IOPixelType MaskPixelType; typedef typename TransformPointerType::ObjectType TransformType; std::cout << "transform_initial: IsNotNull():" << transform_initial.IsNotNull() << std::endl; if (ImageDimension==2) { typedef itk::ANTSCenteredAffine2DTransform RunningAffineTransformType; RunningAffineTransformType::Pointer transform_running = RunningAffineTransformType::New(); RunningAffineTransformType::Pointer transform_running_initial; // = RunningAffineTransformType::New(); std::cout << "1: transform_running_initial: IsNotNull():" << transform_running_initial.IsNotNull() << std::endl; if (transform_initial.IsNotNull()) { transform_running_initial->SetCenter(*(reinterpret_cast (const_cast (&(transform_initial->GetCenter()))))); transform_running_initial->SetMatrix(*(reinterpret_cast (const_cast (&(transform_initial->GetMatrix()))))); transform_running_initial->SetTranslation(*(reinterpret_cast (const_cast (&(transform_initial->GetTranslation()))))); } // Use type casting typedef typename itk::Image::Pointer R_ImagePointerType; R_ImagePointerType & R_fixedImage = reinterpret_cast (fixedImage); R_ImagePointerType & R_movingImage = reinterpret_cast (movingImage); R_ImagePointerType & R_maskImage = reinterpret_cast (maskImage); std::cout << "2: transform_running_initial: IsNotNull():" << transform_running_initial.IsNotNull() << std::endl; compute_single_affine_transform_2d(R_fixedImage, R_movingImage, R_maskImage, transform_running, transform_running_initial); //TODO: transform->SetCenter(*(reinterpret_cast (const_cast (&(transform_running->GetCenter()))))); transform->SetTranslation(*(reinterpret_cast (const_cast (&(transform_running->GetTranslation()))))); transform->SetMatrix(*(reinterpret_cast (const_cast (&(transform_running->GetMatrix()))))); // transform->SetFixedParameters(transform_running->GetFixedParameters()); // transform->SetParameters(transform_running->GetParameters()); } else if (ImageDimension==3){ typedef itk::ANTSAffine3DTransform RunningAffineTransformType; RunningAffineTransformType::Pointer transform_running = RunningAffineTransformType::New(); RunningAffineTransformType::Pointer transform_running_initial = RunningAffineTransformType::New();; // compute_single_affine_transform_3d(fixedImage, movingImage, maskImage, transform_running); if (transform_initial.IsNotNull()) { transform_running_initial->SetCenter(*(reinterpret_cast (const_cast (&(transform_initial->GetCenter()))))); transform_running_initial->SetMatrix(*(reinterpret_cast (const_cast (&(transform_initial->GetMatrix()))))); transform_running_initial->SetTranslation(*(reinterpret_cast (const_cast (&(transform_initial->GetTranslation()))))); } // Use type casting typedef typename itk::Image::Pointer R_ImagePointerType; R_ImagePointerType & R_fixedImage = reinterpret_cast (fixedImage); R_ImagePointerType & R_movingImage = reinterpret_cast (movingImage); R_ImagePointerType & R_maskImage = reinterpret_cast (maskImage); compute_single_affine_transform_3d(R_fixedImage, R_movingImage, R_maskImage, transform_running, transform_running_initial); //TODO: transform->SetCenter(*(reinterpret_cast (const_cast (&(transform_running->GetCenter()))))); transform->SetTranslation(*(reinterpret_cast (const_cast (&(transform_running->GetTranslation()))))); transform->SetMatrix(*(reinterpret_cast (const_cast (&(transform_running->GetMatrix()))))); // transform->SetFixedParameters(transform_running->GetFixedParameters()); // transform->SetParameters(transform_running->GetParameters()); } else { std::cout << "Unsupported, not 2D/ 3D" << std::endl; return; } } template void create_deformation_field_byref(const DeformationFieldPointerType &ref, DeformationFieldPointerType &field){ typedef typename DeformationFieldPointerType::ObjectType DeformationFieldType; // field = DeformationFieldType::New(); typename DeformationFieldType::RegionType region; region.SetSize(ref->GetLargestPossibleRegion().GetSize() ); region.SetIndex(ref->GetLargestPossibleRegion().GetIndex() ); field->SetRegions( region ); field->SetSpacing(ref->GetSpacing()); field->SetOrigin(ref->GetOrigin() ); field->Allocate(); } // compose affine transform (in a matrix format A: (Ax+b)) with a deformation field F: // the new field is: F_new (x) = F ( A (x) ) // output should be allocated outside template void compose_affine_with_field(const TransformPointerType &aff, const DeformationFieldPointerType &field, DeformationFieldPointerType &field_output){ typedef typename DeformationFieldPointerType::ObjectType DeformationFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef typename DeformationFieldType::IndexType IndexType; typedef typename DeformationFieldType::PointType PointType; typedef typename DeformationFieldType::PixelType VectorType; const unsigned int ImageDimension = DeformationFieldType::ImageDimension; // PointType zeroorigin; // zeroorigin.Fill(0); // field->SetOrigin(zeroorigin); // field_output->SetOrigin(zeroorigin); PointType pointIn1; PointType pointIn2; PointType pointIn3; // iterate through field_output finding the points that it maps to via field. // then take the difference from the original point and put it in the output field. // std::cout << " begin iteration " << std::endl; FieldIterator iter_field(field, field->GetLargestPossibleRegion()); // std::cout << field_output->GetLargestPossibleRegion() << std::endl; int cnt = 0; for(iter_field.GoToBegin(); !iter_field.IsAtEnd(); ++iter_field) { IndexType index = iter_field.GetIndex(); field_output->TransformIndexToPhysicalPoint( index, pointIn1 ); VectorType disp=iter_field.Get(); for (int jj=0; jjTransformPoint(pointIn2); VectorType out; for (int jj=0; jjSetPixel(iter_field.GetIndex(), out); } // std::cout << " end iteration " << std::endl; } // this is obsolet, use itkWarpImageWAffineFilter template void warp_image_field(const ImagePointerType &img_input, const DeformationFieldPointerType &field, ImagePointerType &img_output){ typedef typename ImagePointerType::ObjectType ImageType; typedef typename DeformationFieldPointerType::ObjectType DeformationFieldType; typedef typename itk::WarpImageFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(img_input); warper->SetDeformationField(field); warper->SetEdgePaddingValue( 0); warper->SetOutputSpacing(field->GetSpacing() ); warper->SetOutputOrigin( field->GetOrigin() ); warper->Update(); img_output=warper->GetOutput(); } template void affine_image(const ImageTypePointer &input_image, const TransformPointerType &transform, const RefImageTypePointer &ref_image, ImageTypePointer &img_aff ){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename TransformPointerType::ObjectType TransformType; // apply the transform typedef itk::ResampleImageFilter< ImageType, ImageType> ResampleFilterType; typename ResampleFilterType::Pointer resampler = ResampleFilterType::New(); typedef itk::LinearInterpolateImageFunction< ImageType, double> InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); resampler->SetInterpolator( interpolator ); resampler->SetInput( input_image ); resampler->SetSize( ref_image->GetLargestPossibleRegion().GetSize() ); resampler->SetOutputOrigin( ref_image->GetOrigin() ); resampler->SetOutputSpacing( ref_image->GetSpacing() ); resampler->SetDefaultPixelValue( 0 ); resampler->SetTransform( transform ); resampler->Update(); img_aff = resampler->GetOutput(); } template void warp_image_field_waffine(const ImagePointerType &img_input, const TransformPointerType &aff, const DeformationFieldPointerType &field, ImagePointerType &img_output){ // TODO: add a new WarpImageFilter to support affine as an input // temporary solution: typedef typename DeformationFieldPointerType::ObjectType DeformationFieldType; typename DeformationFieldType::Pointer field_comp = DeformationFieldType::New(); // create_deformation_field_byref(field, field_comp); // compose_affine_with_field(aff, field, field_comp); // warp_image_field(img_input, field_comp, img_output); typedef typename TransformPointerType::ObjectType TransformType; typedef typename ImagePointerType::ObjectType ImageType; typedef itk::WarpImageWAffineFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(img_input); warper->SetDeformationField(field); warper->SetAffineTransform(aff); warper->SetEdgePaddingValue( 0); warper->SetOutputSpacing(field->GetSpacing() ); warper->SetOutputOrigin( field->GetOrigin() ); warper->SetOutputSize(field->GetLargestPossibleRegion().GetSize()); warper->Update(); img_output=warper->GetOutput(); return; } //TODO: use my own code to implement all the optimization codes #endif /*ANTS_AFFINE_REGISTRATION_H_*/ ants-1.9.2+svn680.dfsg/ImageRegistration/ANTS_affine_registration2.h000066400000000000000000001562111147325206600252050ustar00rootroot00000000000000#ifndef ANTS_AFFINE_REGISTRATION2_H_ #define ANTS_AFFINE_REGISTRATION2_H_ #include #include #include #include "itkImage.h" #include "itkPoint.h" #include "itkCastImageFilter.h" #include "itkImageMaskSpatialObject.h" #include "itkCenteredEuler3DTransform.h" #include "itkRegularStepGradientDescentOptimizer.h" #include "itkGradientDescentOptimizer.h" #include "itkCenteredTransformInitializer.h" #include "itkMattesMutualInformationImageToImageMetric.h" #include "itkCorrelationCoefficientHistogramImageToImageMetric.h" #include "itkMultiResolutionImageRegistrationMethod.h" #include "itkLinearInterpolateImageFunction.h" #include "itkANTSAffine3DTransform.h" #include "itkCenteredRigid2DTransform.h" #include "itkANTSCenteredAffine2DTransform.h" #include "itkTransformFactory.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkResampleImageFilter.h" #include "itkLinearInterpolateImageFunction.h" #include "itkWarpImageFilter.h" #include "itkWarpImageWAffineFilter.h" #include "itkImageMomentsCalculator.h" #include #include "ReadWriteImage.h" #include "itkMeanSquaresImageToImageMetric.h" #include "itkGradientDifferenceImageToImageMetric.h" #include "itkNormalizedCorrelationImageToImageMetric.h" typedef enum{AffineWithMutualInformation=1, AffineWithMeanSquareDifference , AffineWithHistogramCorrelation, AffineWithNormalizedCorrelation , AffineWithGradientDifference } AffineMetricType; template class OptAffine{ public: typedef TAffineTransformPointer AffineTransformPointerType; typedef TMaskImagePointer MaskImagePointerType; typedef typename AffineTransformPointerType::ObjectType AffineTransformType; OptAffine(){ MI_bins = 32; MI_samples = 6000; number_of_seeds = 0; time_seed = (unsigned int) time(NULL) ; number_of_levels = 3; number_of_iteration_list.resize(number_of_levels); for(int i = 0; i number_of_iteration_list; std::vector gradient_scales; AffineMetricType metric_type; bool is_rigid; double maximum_step_length; double relaxation_factor; double minimum_step_length; double translation_scales; bool use_rotation_header; bool ignore_void_orgin; }; template std::ostream& operator<< (std::ostream& os, const OptAffine& p) { typedef OptAffine OptAffineType; os << "OptAffine: "; os << "metric_type="; switch(p.metric_type){ case AffineWithMutualInformation: os << "AffineWithMutualInformation" << std::endl; break; case AffineWithMeanSquareDifference: os << "AffineWithMeanSquareDifference" << std::endl; break; case AffineWithHistogramCorrelation: os << "AffineWithHistogramCorrelation" << std::endl; break; case AffineWithNormalizedCorrelation: os << "AffineWithNormalizedCorrelation" << std::endl; break; case AffineWithGradientDifference: os << "AffineWithGradientDifference" << std::endl; break; } os << "MI_bins="<< p.MI_bins << " " << "MI_samples=" << p.MI_samples << std::endl; os << "number_of_seeds="< 0) os << p.number_of_iteration_list[p.number_of_iteration_list.size()-1]; os << "]" << std::endl; os << "graident_scales="<<"["; for(unsigned int i=0; i 0) os << p.gradient_scales[p.gradient_scales.size()-1]; os << "]" << std::endl; os << "is_rigid = " << p.is_rigid << std::endl; os << "mask null: " << p.mask_fixed.IsNull() << std::endl; os << "maximum_step_length="< void ReadAffineTransformFile(StringType filename, CastTransformPointerType &transform){ typedef typename CastTransformPointerType::ObjectType CastTransformType; // const unsigned int InputSpaceDimension = CastTransformType::InputSpaceDimension; // const unsigned int OutputSpaceDimension = CastTransformType::OutputSpaceDimension; itk::TransformFactory::RegisterTransform(); itk::TransformFactory >::RegisterTransform(); typedef typename itk::TransformFileReader TranReaderType; TranReaderType::Pointer tran_reader = TranReaderType::New(); tran_reader->SetFileName(filename); try{ tran_reader->Update(); } catch( itk::ExceptionObject &err) { std::cerr << err << std::endl; std::cerr << "Exception caught in reading tran para file: " << filename << std::endl; return; } transform = dynamic_cast< CastTransformType* >((tran_reader->GetTransformList())->front().GetPointer()); return; } template void InitializeAffineOptmizationParameters(OptAffine &opt, double translationScale){ const int kImageDim = OptAffine::MaskImagePointerType::ObjectType::ImageDimension; switch(kImageDim){ case 2:{ // const double translationScale = 1.0 / 1000.0; opt.gradient_scales[0] = 1.0; opt.gradient_scales[1] = 1.0; opt.gradient_scales[2] = 1.0; opt.gradient_scales[3] = 1.0; opt.gradient_scales[4] = translationScale; opt.gradient_scales[5] = translationScale; opt.gradient_scales[6] = translationScale; opt.gradient_scales[7] = translationScale; } break; case 3:{ // const double translationScale = 1.0/1.e4; opt.gradient_scales[0] = 1.0; // quaternion opt.gradient_scales[1] = 1.0; // quaternion opt.gradient_scales[2] = 1.0; // quaternion opt.gradient_scales[3] = 1.0; // quaternion opt.gradient_scales[4] = 1.0; // s1 opt.gradient_scales[5] = 1.0; // s2 opt.gradient_scales[6] = 1.0; // s3 opt.gradient_scales[7] = 1.0; // k1 opt.gradient_scales[8] = 1.0; // k2 opt.gradient_scales[9] = 1.0; // k3 opt.gradient_scales[10] = translationScale; opt.gradient_scales[11] = translationScale; opt.gradient_scales[12] = translationScale; } break; } std::cout << opt; } template class RunningAffineCache{ public: typedef TImagePyramid ImagePyramidType; typedef typename ImagePyramidType::value_type ImagePointerType; typedef typename ImagePointerType::ObjectType ImageType; typedef TMetricPointerType MetricPointerType; typedef typename MetricPointerType::ObjectType MetricType; typedef TInterpolatorPointerType InterpolatorPointerType; typedef typename InterpolatorPointerType::ObjectType InterpolatorType; typedef TMaskObjectPointerType MaskObjectPointerType; RunningAffineCache(){ }; ~RunningAffineCache(){ }; TMaskObjectPointerType mask_fixed_object; TImagePyramid fixed_image_pyramid; TImagePyramid moving_image_pyramid; TMetricPointerType metric; TMetricPointerType invmetric; TInterpolatorPointerType interpolator; }; template void ComputeSingleAffineTransform(ImagePointerType fixedImage, ImagePointerType movingImage, OptAffineType &opt, TransformPointerType &transform); template void ComputeSingleAffineTransform2D3D(ImagePointerType I_fixed, ImagePointerType I_moving, OptAffineType &opt, TransformPointerType &transform); //////////////////////////////////////////////////////////////////////// template inline void PreConversionInAffine(ImagePointerType &fixedImage, RunningImagePointerType& R_fixedImage, ImagePointerType &movingImage, RunningImagePointerType& R_movingImage, OptAffineType &opt, RunningOptAffineType &R_opt){ typedef typename OptAffineType::AffineTransformPointerType::ObjectType AffineTransformType; typedef typename RunningOptAffineType::AffineTransformPointerType::ObjectType RunningAffineTransformType; if (opt.use_rotation_header){ std::cout << "===================>initialize from rotation header ... " << std::endl; // use the rotation header to initialize the affine: inv(Tm) * Tf typename AffineTransformType::Pointer aff_Im = AffineTransformType::New(); GetAffineTransformFromImage(movingImage, aff_Im); typename AffineTransformType::Pointer aff_If = AffineTransformType::New(); GetAffineTransformFromImage(fixedImage, aff_If); typename AffineTransformType::Pointer aff_combined = AffineTransformType::New(); aff_combined->SetFixedParameters(aff_If->GetFixedParameters()); aff_combined->SetParameters(aff_If->GetParameters()); typename AffineTransformType::Pointer aff_Im_inv = AffineTransformType::New(); aff_Im->GetInverse(aff_Im_inv); aff_combined->Compose(aff_Im_inv, 0); opt.transform_initial = aff_combined; // std::cout << "aff_If: " << aff_If << std::endl; // std::cout << "aff_Im: " << aff_Im << std::endl; // std::cout << "aff_combined: " << aff_combined << std::endl; } if (!opt.use_rotation_header && opt.ignore_void_orgin){ std::cout << "===================> ignore void origins which are too far away to be possible alignments: use 0 instead." << std::endl; typename AffineTransformType::Pointer aff_Im = AffineTransformType::New(); GetAffineTransformFromImage(movingImage, aff_Im); typename AffineTransformType::Pointer aff_If = AffineTransformType::New(); GetAffineTransformFromImage(fixedImage, aff_If); bool b_far_origin_without_rotation=false; // bool b_far_origin_without_rotation = HaveFarOriginWithoutRotation(aff_If, aff_Im); if (b_far_origin_without_rotation){ typename AffineTransformType::Pointer aff_combined = AffineTransformType::New(); aff_combined->SetFixedParameters(aff_If->GetFixedParameters()); aff_combined->SetParameters(aff_If->GetParameters()); typename AffineTransformType::Pointer aff_Im_inv = AffineTransformType::New(); aff_Im->GetInverse(aff_Im_inv); aff_combined->Compose(aff_Im_inv, 0); opt.transform_initial = aff_combined; } } if (opt.transform_initial.IsNotNull()) { R_opt.transform_initial = RunningAffineTransformType::New(); R_opt.transform_initial->SetCenter(*(reinterpret_cast (const_cast (&(opt.transform_initial->GetCenter()))))); R_opt.transform_initial->SetMatrix(*(reinterpret_cast (const_cast (&(opt.transform_initial->GetMatrix()))))); R_opt.transform_initial->SetTranslation(*(reinterpret_cast (const_cast (&(opt.transform_initial->GetTranslation()))))); } // std::cout << "R_opt.transform_initial" << R_opt.transform_initial << std::endl; if (opt.mask_fixed.IsNotNull()){ R_opt.mask_fixed = RunningOptAffineType::MaskImagePointerType::ObjectType::New(); R_opt.mask_fixed = reinterpret_cast (opt.mask_fixed); // have to set " -fno-strict-aliasing " in gcc to remove the following compilation warning: // warning: dereferencing type-punned pointer will break strict-aliasing rules } R_fixedImage = reinterpret_cast (fixedImage); R_movingImage = reinterpret_cast (movingImage); R_opt.MI_bins = opt.MI_bins; R_opt.MI_samples = opt.MI_samples; R_opt.number_of_seeds = opt.number_of_seeds; R_opt.time_seed = opt.time_seed; R_opt.number_of_levels = opt.number_of_levels; R_opt.number_of_iteration_list = opt.number_of_iteration_list; // R_opt.gradient_scales = opt.gradient_scales; // does not need, will assign value later. R_opt.metric_type = opt.metric_type; R_opt.is_rigid = opt.is_rigid; R_opt.maximum_step_length = opt.maximum_step_length ; R_opt.relaxation_factor = opt.relaxation_factor ; R_opt.minimum_step_length = opt.minimum_step_length ; R_opt.translation_scales = opt.translation_scales ; R_opt.use_rotation_header = opt.use_rotation_header; R_opt.ignore_void_orgin = opt.ignore_void_orgin; } //////////////////////////////////////////////////////////////////////// template inline void PostConversionInAffine(RunningAffineTransformPointerType& transform_running, AffineTransformPointerType &transform){ typedef typename RunningAffineTransformPointerType::ObjectType RunningAffineTransformType; typedef typename AffineTransformPointerType::ObjectType AffineTransformType; transform->SetCenter(*(reinterpret_cast (const_cast (&(transform_running->GetCenter()))))); transform->SetTranslation(*(reinterpret_cast (const_cast (&(transform_running->GetTranslation()))))); transform->SetMatrix(*(reinterpret_cast (const_cast (&(transform_running->GetMatrix()))))); // std::cout << "transform_running" << transform_running << std::endl; // std::cout << "transform" << transform << std::endl; } /////////////////////////////////////////////////////////////////////////// // the initial transform maybe any derivative class type from MatrixOffsetTransformBase, // it will be automatically converted to the my 2D/3D affine type template void ComputeSingleAffineTransform(ImagePointerType fixedImage, ImagePointerType movingImage, OptAffineType &opt, TransformPointerType &transform){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::ImageDimension; typedef typename ImageType::IOPixelType PixelType; std::cout << "transform_initial: IsNotNull():" << opt.transform_initial.IsNotNull() << std::endl; if (ImageDimension==2) { typedef itk::ANTSCenteredAffine2DTransform::Pointer RunningAffineTransformPointerType; const unsigned int RunningImageDimension = 2; typedef typename itk::Image::Pointer RunningImagePointerType; typedef OptAffine RunningOptAffineType; RunningImagePointerType R_fixedImage, R_movingImage; RunningOptAffineType R_opt; RunningAffineTransformPointerType transform_running; PreConversionInAffine(fixedImage, R_fixedImage, movingImage, R_movingImage, opt, R_opt); ComputeSingleAffineTransform2D3D(R_fixedImage, R_movingImage, R_opt, transform_running); PostConversionInAffine(transform_running, transform); } else if (ImageDimension==3){ typedef itk::ANTSAffine3DTransform::Pointer RunningAffineTransformPointerType; const unsigned int RunningImageDimension = 3; typedef typename itk::Image::Pointer RunningImagePointerType; typedef OptAffine RunningOptAffineType; RunningImagePointerType R_fixedImage, R_movingImage; RunningOptAffineType R_opt; RunningAffineTransformPointerType transform_running; PreConversionInAffine(fixedImage, R_fixedImage, movingImage, R_movingImage, opt, R_opt); ComputeSingleAffineTransform2D3D(R_fixedImage, R_movingImage, R_opt, transform_running); PostConversionInAffine(transform_running, transform); } else { std::cout << "Unsupported, not 2D/ 3D" << std::endl; return; } } /////////////////////////////////////////////////////////////////////////////// template void InitialzeImageMask(MaskImagePointerType &mask_fixed, ImageMaskSpatialObjectPointerType &mask_fixed_object){ if (mask_fixed.IsNull()) return; const unsigned int ImageDimension = MaskImagePointerType::ObjectType::ImageDimension; typedef typename MaskImagePointerType::ObjectType MaskImageType; typedef typename ImageMaskSpatialObjectPointerType::ObjectType ImageMaskSpatialObjectType; typedef itk::Image CharMaskImageType; typedef itk::CastImageFilter CastFilterType; typename CastFilterType::Pointer cast_filter = CastFilterType::New(); cast_filter->SetInput(mask_fixed); cast_filter->Update(); typename CharMaskImageType::Pointer mask_fixed_char = cast_filter->GetOutput(); mask_fixed_object = ImageMaskSpatialObjectType::New(); mask_fixed_object->SetImage(mask_fixed_char); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// template void ComputeInitialPosition(ImagePointerType &I_fixed, ImagePointerType &I_moving, PointType ¢er, VectorType &translation_vec){ typedef typename ImagePointerType::ObjectType ImageType; typedef typename itk::ImageMomentsCalculator< ImageType > ImageCalculatorType; const unsigned int ImageDimension = ImageType::ImageDimension; typename ImageCalculatorType::Pointer calculator = ImageCalculatorType::New(); calculator->SetImage( I_fixed ); calculator->Compute(); typename ImageCalculatorType::VectorType fixed_center = calculator->GetCenterOfGravity(); calculator->SetImage( I_moving ); calculator->Compute(); typename ImageCalculatorType::VectorType moving_center = calculator->GetCenterOfGravity(); for( unsigned int i=0; i void InjectInitialPara(PointType ¢er, VectorType &translation_vec, TransformPointerType &transform){ typedef typename TransformPointerType::ObjectType::ParametersType ParaType; ParaType para0(TransformPointerType::ObjectType::ParametersDimension); switch((unsigned int) PointType::PointDimension){ case 2: para0[0] = 0; // para1[0]; // theta para0[1] = 1.0; //s1 para0[2] = 1.0; //s2 para0[3] = 0.0; //k para0[4] = center[0]; // para1[1]; //c1 para0[5] = center[1]; // para1[2]; //c2 para0[6] = translation_vec[0]; // 0;//para1[3]; //t1 para0[7] = translation_vec[1]; //0; //para1[4]; //t2 transform->SetParameters(para0); transform->SetCenter(center); break; case 3: para0[0] = 0.0; para0[1] = 0.0; para0[2] = 0.0; para0[3] = 1.0; para0[4] = 1.0; para0[5] = 1.0; para0[6] = 1.0; para0[7] = 0.0; para0[8] = 0.0; para0[9] = 0.0; para0[10] = translation_vec[0]; para0[11] = translation_vec[1]; para0[12] = translation_vec[2]; //para0[10] = 0.0; para0[11] = 0.0; para0[12] = 0.0; transform->SetParameters(para0); transform->SetCenter(center); break; } } ////////////////////////////////////////////////////////////////////////////////////////// template double TestCostValueMMI(ImagePointerType fixedImage, ImagePointerType movingImage, ParaType para, PointType center, TransformTypePointer null_transform){ typedef typename ImagePointerType::ObjectType ImageType; typedef typename TransformTypePointer::ObjectType TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetCenter(center); // transform->SetParameters(para); typedef typename itk::MattesMutualInformationImageToImageMetric mattesMutualInfoMetricType; typename mattesMutualInfoMetricType::Pointer mattesMutualInfo=mattesMutualInfoMetricType::New(); typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator=InterpolatorType::New(); interpolator->SetInputImage(movingImage); mattesMutualInfo->SetFixedImage(fixedImage); mattesMutualInfo->SetMovingImage(movingImage); mattesMutualInfo->SetFixedImageRegion(fixedImage->GetBufferedRegion()); mattesMutualInfo->SetTransform(transform); mattesMutualInfo->SetInterpolator(interpolator); mattesMutualInfo->SetNumberOfHistogramBins( 32 ); mattesMutualInfo->SetNumberOfSpatialSamples( 5000 ); mattesMutualInfo->SetTransformParameters(para); mattesMutualInfo->Initialize(); double rval = 0; try{ rval = mattesMutualInfo->GetValue(para); } catch (itk::ExceptionObject &err){ std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl << "Exception caught in computing mattesMutualInfo after registration" << std::endl << "Maybe: Too many samples map outside moving image buffer" << std::endl << "Set the cost value = 0 (max for MutualInfo) " << std::endl; rval = 0; } return rval; } template void InitializeRunningAffineCache(ImagePointerType &fixed_image, ImagePointerType &moving_image, OptAffineType &opt, RunningAffineCacheType &running_cache){ typedef typename ImagePointerType::ObjectType ImageType; // typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef typename RunningAffineCacheType::InterpolatorType InterpolatorType; typedef typename RunningAffineCacheType::MetricType MetricType; // typedef itk::MattesMutualInformationImageToImageMetric MetricType; BuildImagePyramid(fixed_image, opt.number_of_levels, running_cache.fixed_image_pyramid); BuildImagePyramid(moving_image, opt.number_of_levels, running_cache.moving_image_pyramid); InitialzeImageMask(opt.mask_fixed, running_cache.mask_fixed_object); running_cache.interpolator = InterpolatorType::New(); running_cache.metric = MetricType::New(); running_cache.invmetric = MetricType::New(); } template void GetAffineTransformFromImage(const ImageTypePointer& img, AffineTransformPointer &aff){ typedef typename ImageTypePointer::ObjectType ImageType; typedef typename ImageType::DirectionType DirectionType; typedef typename ImageType::PointType PointType; typedef typename ImageType::SpacingType SpacingType; typedef typename AffineTransformPointer::ObjectType::TranslationType VectorType; DirectionType direction = img->GetDirection(); PointType pt = img->GetOrigin(); SpacingType spacing = img->GetSpacing(); VectorType translation; translation.Fill(0); aff->SetMatrix(direction); aff->SetCenter(pt); aff->SetTranslation(translation); } template void InitializeAffineTransform(ImagePointerType &fixed_image, ImagePointerType &moving_image, OptAffineType& opt){ typedef typename OptAffineType::AffineTransformType TransformType; typedef typename TransformType::ParametersType ParaType; typedef typename TransformType::InputPointType PointType; typedef typename TransformType::OutputVectorType VectorType; std::cout << "opt.transform_initial.IsNull(): " << opt.transform_initial.IsNull() << std::endl; std::cout << " opt.use_rotation_header: " << opt.use_rotation_header << std::endl; std::cout << " opt.ignore_void_orgin: " << opt.ignore_void_orgin << std::endl; if (opt.transform_initial.IsNull()){ PointType center; VectorType translation_vec; ComputeInitialPosition(fixed_image, moving_image, center, translation_vec); opt.transform_initial = TransformType::New(); InjectInitialPara(center, translation_vec, opt.transform_initial); } } template ImagePointer ShrinkImageToScale(ImagePointer image , float scalingFactor ) { typedef float RealType; typedef typename ImagePointer::ObjectType ImageType; typename ImageType::SpacingType inputSpacing = image->GetSpacing(); typename ImageType::RegionType::SizeType inputSize = image->GetRequestedRegion().GetSize(); typename ImageType::SpacingType outputSpacing; typename ImageType::RegionType::SizeType outputSize; typedef itk::ResampleImageFilter ResampleFilterType; typename ResampleFilterType::Pointer resampler = ResampleFilterType::New(); RealType minimumSpacing = inputSpacing.GetVnlVector().min_value(); // RealType maximumSpacing = inputSpacing.GetVnlVector().max_value(); ImagePointer current_image = image; for ( unsigned int d = 0; d < ImageType::ImageDimension; d++ ) { RealType scaling = vnl_math_min( scalingFactor * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); typedef itk::RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( current_image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); smoother->SetSigma( 0.25 * ( outputSpacing[d] / inputSpacing[d] ) ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); current_image = smoother->GetOutput(); } } resampler->SetInput(current_image ); resampler->SetSize(outputSize); resampler->SetOutputSpacing(outputSpacing); resampler->SetOutputOrigin(image->GetOrigin()); resampler->SetOutputDirection(image->GetDirection()); resampler->Update(); image = resampler->GetOutput(); // std::cout << "DEBUG: " << outputSize << std::endl; return image; } template void BuildImagePyramid(const ImagePointerType &image, int number_of_levels, ImagePyramidType &image_pyramid){ image_pyramid.resize(number_of_levels); image_pyramid[number_of_levels-1] = image; double scale_factor = 2; for(int i = 0; i < number_of_levels-1; i++){ image_pyramid[number_of_levels-2-i] = ShrinkImageToScale(image, scale_factor); scale_factor *= 2; } // for(int i=0; i < number_of_levels; i++) // std::cout << "level " << i << ": size: " << image_pyramid[i]->GetLargestPossibleRegion().GetSize() << std::endl; } template ParaType NormalizeGradientForRigidTransform(ParaType &original_gradient, int kImageDim){ ParaType new_gradient(original_gradient.Size()); new_gradient = original_gradient; switch(kImageDim){ case 2: //theta, s1, s2, k for(int j=1; j<=3; j++) new_gradient[j] = 0.; break; case 3: // q1,q2,q3,q4,s1,s2,s3,k1,k2,k3 for(int j=4; j<=9; j++) new_gradient[j] = 0.; break; } return new_gradient; } /////////////////////////////////////////////////////////////////////////////// //template template bool SymmRegisterImageAffineMutualInformationMultiResolution(RunningAffineCacheType &running_cache, OptAffine &opt, ParaType ¶_final){ typedef typename RunningAffineCacheType::ImagePyramidType ImagePyramidType; typedef typename RunningAffineCacheType::ImagePointerType ImagePointerType; typedef typename ImagePointerType::ObjectType ImageType; typedef typename RunningAffineCacheType::MetricType MetricType; typedef typename RunningAffineCacheType::InterpolatorType InterpolatorType; typedef typename OptAffine::AffineTransformType TransformType; typedef typename RunningAffineCacheType::MaskObjectPointerType MaskObjectPointerType; const unsigned int kImageDim = ImageType::ImageDimension; ImagePyramidType& fixed_image_pyramid = running_cache.fixed_image_pyramid; ImagePyramidType& moving_image_pyramid = running_cache.moving_image_pyramid; MaskObjectPointerType& mask_fixed_object = running_cache.mask_fixed_object; int number_of_levels = opt.number_of_levels; std::vector& number_of_iteration_list = opt.number_of_iteration_list; std::vector& gradient_scales = opt.gradient_scales; bool is_rigid = opt.is_rigid; // use my own's registration routine of image pyramid and gradient descent , only use ITK's implementation of mutual information // try to use my own transform class together with image pyramid when transform are required (not much for MI though) typename TransformType::Pointer transform = TransformType::New(); typename TransformType::Pointer invtransform = TransformType::New(); typename InterpolatorType::Pointer& interpolator = running_cache.interpolator; typename InterpolatorType::Pointer invinterpolator = InterpolatorType::New(); typename MetricType::Pointer& metric = running_cache.metric; typename MetricType::Pointer& invmetric = running_cache.invmetric; const int kParaDim = TransformType::ParametersDimension; ParaType current_para(kParaDim); current_para = opt.transform_initial->GetParameters(); double maximum_step_length = opt.maximum_step_length; double relaxation_factor = opt.relaxation_factor; double minimum_step_length = opt.minimum_step_length; double current_step_length; for(int i = 0; i < number_of_levels; i++){ transform->SetParameters(current_para); transform->SetCenter(opt.transform_initial->GetCenter()); ImagePointerType fixed_image = fixed_image_pyramid[i]; ImagePointerType moving_image = moving_image_pyramid[i]; int number_of_iteration_current_level = number_of_iteration_list[i]; interpolator->SetInputImage( moving_image ); metric->SetMovingImage( moving_image ); metric->SetFixedImage( fixed_image ); metric->SetTransform( transform ); metric->SetInterpolator( interpolator ); metric->SetFixedImageRegion(fixed_image->GetLargestPossibleRegion()); if (mask_fixed_object.IsNotNull()) metric->SetFixedImageMask(mask_fixed_object); metric->Initialize(); ParaType last_gradient(kParaDim); ParaType invlast_gradient(kParaDim); for(int j=0; j < kParaDim; j++) { last_gradient[j] = 0; invlast_gradient[j] = 0; } current_step_length = maximum_step_length; bool is_converged = false; int used_iterations = 0; for(used_iterations=0; used_iterations < number_of_iteration_current_level; used_iterations++){ transform->GetInverse(invtransform); invinterpolator->SetInputImage( fixed_image ); invmetric->SetMovingImage( fixed_image ); invmetric->SetFixedImage( moving_image ); invmetric->SetTransform( invtransform ); invmetric->SetInterpolator( invinterpolator ); invmetric->SetFixedImageRegion(moving_image->GetLargestPossibleRegion()); invmetric->Initialize(); ParaType original_gradient(kParaDim); ParaType current_gradient(kParaDim); ParaType invoriginal_gradient(kParaDim); ParaType invcurrent_gradient(kParaDim); double value,invvalue; try{ metric->GetValueAndDerivative(current_para, value, original_gradient); invmetric->GetValueAndDerivative( invtransform->GetParameters() , invvalue, invoriginal_gradient); } catch(itk::ExceptionObject & err){ std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; return false; break; } // use the similar routine as RegularStepGradientDescentBaseOptimizer::AdvanceOneStep // to use oscillation as the minimization convergence // notice this is always a minimization procedure if (is_rigid) { original_gradient = NormalizeGradientForRigidTransform(original_gradient, kImageDim); invoriginal_gradient = NormalizeGradientForRigidTransform(invoriginal_gradient, kImageDim); } for(int j=0; jGetRequestedRegion().GetSize() << "-mov" << moving_image->GetRequestedRegion().GetSize(); std::cout << ", affine para: " << current_para << std::endl; if (is_converged) std::cout << " reach oscillation, current step: " << current_step_length << "<" << minimum_step_length << std::endl; else std::cout << " does not reach oscillation, current step: " << current_step_length << ">" << minimum_step_length << std::endl; } para_final = current_para; return true; } /////////////////////////////////////////////////////////////////////////////// //template template bool RegisterImageAffineMutualInformationMultiResolution(RunningAffineCacheType &running_cache, OptAffine &opt, ParaType ¶_final){ typedef typename RunningAffineCacheType::ImagePyramidType ImagePyramidType; typedef typename RunningAffineCacheType::ImagePointerType ImagePointerType; typedef typename ImagePointerType::ObjectType ImageType; typedef typename RunningAffineCacheType::MetricType MetricType; typedef typename RunningAffineCacheType::InterpolatorType InterpolatorType; typedef typename OptAffine::AffineTransformType TransformType; typedef typename RunningAffineCacheType::MaskObjectPointerType MaskObjectPointerType; const unsigned int kImageDim = ImageType::ImageDimension; ImagePyramidType& fixed_image_pyramid = running_cache.fixed_image_pyramid; ImagePyramidType& moving_image_pyramid = running_cache.moving_image_pyramid; MaskObjectPointerType& mask_fixed_object = running_cache.mask_fixed_object; int number_of_levels = opt.number_of_levels; std::vector& number_of_iteration_list = opt.number_of_iteration_list; std::vector& gradient_scales = opt.gradient_scales; bool is_rigid = opt.is_rigid; // use my own's registration routine of image pyramid and gradient descent , only use ITK's implementation of mutual information // try to use my own transform class together with image pyramid when transform are required (not much for MI though) typename TransformType::Pointer transform = TransformType::New(); typename InterpolatorType::Pointer& interpolator = running_cache.interpolator; typename MetricType::Pointer& metric = running_cache.metric; const int kParaDim = TransformType::ParametersDimension; ParaType current_para(kParaDim); current_para = opt.transform_initial->GetParameters(); double maximum_step_length = opt.maximum_step_length; double relaxation_factor = opt.relaxation_factor; double minimum_step_length = opt.minimum_step_length; double current_step_length; double value=0; for(int i = 0; i < number_of_levels; i++){ transform->SetParameters(current_para); transform->SetCenter(opt.transform_initial->GetCenter()); ImagePointerType fixed_image = fixed_image_pyramid[i]; ImagePointerType moving_image = moving_image_pyramid[i]; int number_of_iteration_current_level = number_of_iteration_list[i]; interpolator->SetInputImage( moving_image ); metric->SetMovingImage( moving_image ); metric->SetFixedImage( fixed_image ); metric->SetTransform( transform ); metric->SetInterpolator( interpolator ); metric->SetFixedImageRegion(fixed_image->GetLargestPossibleRegion()); if (mask_fixed_object.IsNotNull()) metric->SetFixedImageMask(mask_fixed_object); metric->Initialize(); ParaType last_gradient(kParaDim); ParaType invlast_gradient(kParaDim); for(int j=0; j < kParaDim; j++) { last_gradient[j] = 0; invlast_gradient[j] = 0; } current_step_length = maximum_step_length; bool is_converged = false; int used_iterations = 0; for(used_iterations=0; used_iterations < number_of_iteration_current_level; used_iterations++){ ParaType original_gradient(kParaDim); ParaType current_gradient(kParaDim); value=0; try{ metric->GetValueAndDerivative(current_para, value, original_gradient); } catch(itk::ExceptionObject & err){ std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; return false; break; } // use the similar routine as RegularStepGradientDescentBaseOptimizer::AdvanceOneStep // to use oscillation as the minimization convergence // notice this is always a minimization procedure if (is_rigid) { original_gradient = NormalizeGradientForRigidTransform(original_gradient, kImageDim); } for(int j=0; jGetRequestedRegion().GetSize() << "-mov" << moving_image->GetRequestedRegion().GetSize(); std::cout << ", affine para: " << current_para << std::endl; if (is_converged) std::cout << " reach oscillation, current step: " << current_step_length << "<" << minimum_step_length << std::endl; else std::cout << " does not reach oscillation, current step: " << current_step_length << ">" << minimum_step_length << std::endl; } double value1=value; if ( ! mask_fixed_object.IsNotNull()) { typename TransformType::Pointer transform2 = TransformType::New(); ParaType current_para2(kParaDim); current_para2 = opt.transform_initial->GetParameters(); maximum_step_length = opt.maximum_step_length; relaxation_factor = opt.relaxation_factor; minimum_step_length = opt.minimum_step_length; value=0; for(int i = 0; i < number_of_levels; i++){ transform2->SetParameters(current_para2); transform2->SetCenter(opt.transform_initial->GetCenter()); /** see below -- we switch fixed and moving!! */ ImagePointerType fixed_image = moving_image_pyramid[i]; ImagePointerType moving_image = fixed_image_pyramid[i]; int number_of_iteration_current_level = number_of_iteration_list[i]; interpolator->SetInputImage( moving_image ); metric->SetMovingImage( moving_image ); metric->SetFixedImage( fixed_image ); metric->SetTransform( transform2 ); metric->SetInterpolator( interpolator ); metric->SetFixedImageRegion(fixed_image->GetLargestPossibleRegion()); /** FIXME --- need a moving mask ... */ // if (mask_fixed_object.IsNotNull()) metric->SetFixedImageMask(mask_fixed_object); metric->Initialize(); ParaType last_gradient(kParaDim); for(int j=0; j < kParaDim; j++) { last_gradient[j] = 0; } current_step_length = maximum_step_length; bool is_converged = false; int used_iterations = 0; for(used_iterations=0; used_iterations < number_of_iteration_current_level; used_iterations++){ ParaType original_gradient(kParaDim); ParaType current_gradient(kParaDim); value=0; try{ metric->GetValueAndDerivative(current_para2, value, original_gradient); } catch(itk::ExceptionObject & err){ std::cerr << "ExceptionObject caught !" << std::endl; std::cerr << err << std::endl; return false; break; } // use the similar routine as RegularStepGradientDescentBaseOptimizer::AdvanceOneStep // to use oscillation as the minimization convergence // notice this is always a minimization procedure if (is_rigid) { original_gradient = NormalizeGradientForRigidTransform(original_gradient, kImageDim); } for(int j=0; jGetRequestedRegion().GetSize() << "-mov" << moving_image->GetRequestedRegion().GetSize(); std::cout << ", affine para: " << current_para2 << std::endl; if (is_converged) std::cout << " reach oscillation, current step: " << current_step_length << "<" << minimum_step_length << std::endl; else std::cout << " does not reach oscillation, current step: " << current_step_length << ">" << minimum_step_length << std::endl; } std::cout << " v1 " << value1 << " v2 " << value << std::endl; if ( value < value1 ) { std::cout << " last params " << transform->GetParameters() << std::endl; std::cout << " my params " << transform2->GetParameters() << std::endl; transform2->GetInverse(transform); std::cout << " new params " << transform->GetParameters() << std::endl; para_final = transform->GetParameters(); return true; } } para_final = current_para; std::cout << "final " << para_final << std::endl; return true; } /////////////////////////////////////////////////////////////////////////////// template void ComputeSingleAffineTransform2D3D(ImagePointerType fixed_image, ImagePointerType moving_image, OptAffineType &opt, TransformPointerType &transform){ typedef typename ImagePointerType::ObjectType ImageType; const int ImageDimension = ImageType::ImageDimension; typedef std::vector ImagePyramidType; typedef itk::ImageMaskSpatialObject ImageMaskSpatialObjectType; typedef typename ImageMaskSpatialObjectType::Pointer MaskObjectPointerType; typedef itk::LinearInterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointerType; typedef typename TransformPointerType::ObjectType TransformType; typedef typename TransformType::ParametersType ParaType; InitializeAffineOptmizationParameters(opt, opt.translation_scales); // std::cout << "DEBUG: opt.gradient_scales.size() = " << opt.gradient_scales.size() << std::endl; InitializeAffineTransform(fixed_image, moving_image, opt); std::cout << "input affine center: " << opt.transform_initial->GetCenter() << std::endl; std::cout << "input affine para: " << opt.transform_initial->GetParameters() << std::endl; transform = TransformType::New(); ParaType para_final(TransformType::ParametersDimension); switch (opt.metric_type){ case AffineWithMeanSquareDifference:{ typedef itk::MeanSquaresImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointerType; typedef RunningAffineCache RunningAffineCacheType; RunningAffineCacheType running_cache; InitializeRunningAffineCache(fixed_image, moving_image, opt, running_cache); RegisterImageAffineMutualInformationMultiResolution(running_cache, opt, para_final); } break; case AffineWithHistogramCorrelation:{ typedef itk::CorrelationCoefficientHistogramImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointerType; typedef RunningAffineCache RunningAffineCacheType; RunningAffineCacheType running_cache; InitializeRunningAffineCache(fixed_image, moving_image, opt, running_cache); unsigned int nBins = 32; typename MetricType::HistogramType::SizeType histSize; histSize[0] = nBins; histSize[1] = nBins; running_cache.metric->SetHistogramSize(histSize); RegisterImageAffineMutualInformationMultiResolution(running_cache, opt, para_final); } break; case AffineWithNormalizedCorrelation:{ typedef itk::NormalizedCorrelationImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointerType; typedef RunningAffineCache RunningAffineCacheType; RunningAffineCacheType running_cache; InitializeRunningAffineCache(fixed_image, moving_image, opt, running_cache); RegisterImageAffineMutualInformationMultiResolution(running_cache, opt, para_final); } break; case AffineWithGradientDifference:{ typedef itk::GradientDifferenceImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointerType; typedef RunningAffineCache RunningAffineCacheType; RunningAffineCacheType running_cache; InitializeRunningAffineCache(fixed_image, moving_image, opt, running_cache); RegisterImageAffineMutualInformationMultiResolution(running_cache, opt, para_final); } break; case AffineWithMutualInformation: { typedef itk::MattesMutualInformationImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointerType; typedef RunningAffineCache RunningAffineCacheType; RunningAffineCacheType running_cache; InitializeRunningAffineCache(fixed_image, moving_image, opt, running_cache); running_cache.metric->SetNumberOfHistogramBins( opt.MI_bins ); running_cache.metric->SetNumberOfSpatialSamples( opt.MI_samples ); RegisterImageAffineMutualInformationMultiResolution(running_cache, opt, para_final); } break; default: break; } bool noaffine=true; for(int i = 0; i 0) noaffine=false; if (noaffine) for (int i=TransformType::ParametersDimension-ImageDimension; iSetParameters(para_final); transform->SetCenter(opt.transform_initial->GetCenter()); double rval_init = TestCostValueMMI(fixed_image, moving_image, opt.transform_initial->GetParameters(), opt.transform_initial->GetCenter(), transform); // std::cerr << "ABCDABCD: " << transform << std::endl; double rval_final = TestCostValueMMI(fixed_image, moving_image, para_final, opt.transform_initial->GetCenter(), transform); std::cout << "outputput affine center: " << transform->GetCenter() << std::endl; std::cout << "output affine para: " << transform->GetParameters() << std::endl; std::cout << "initial measure value (MMI): rval = " << rval_init << std::endl; std::cout << "final measure value (MMI): rval = " << rval_final << std::endl; std::cout << "finish affine registeration..." << std::endl; }; #endif /*ANTS_AFFINE_REGISTRATION2_H_*/ ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSAffine3DTransform.h000066400000000000000000000133521147325206600247230ustar00rootroot00000000000000#ifndef __itkANTSAffine3DTransform_h #define __itkANTSAffine3DTransform_h #include #include "itkRigid3DTransform.h" #include "vnl/vnl_quaternion.h" namespace itk { /** \brief ANTSAffine3DTransform of a vector space (e.g. space coordinates). * * This transform applies a rotation and translation to the space * * \ingroup Transforms */ template < class TScalarType=double > // Data type for scalars (float or double) class ITK_EXPORT ANTSAffine3DTransform : public MatrixOffsetTransformBase< TScalarType, 3, 3> // public Rigid3DTransform< TScalarType > { public: /** Standard class typedefs. */ typedef ANTSAffine3DTransform Self; // typedef Rigid3DTransform< TScalarType > Superclass; typedef MatrixOffsetTransformBase< TScalarType, 3, 3 > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** New macro for creation of through a Smart Pointer */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ // itkTypeMacro( ANTSAffine3DTransform, Rigid3DTransform ); itkTypeMacro( ANTSAffine3DTransform, MatrixOffsetTransformBase ); /** Dimension of parameters */ itkStaticConstMacro(InputSpaceDimension, unsigned int, 3); itkStaticConstMacro(OutputSpaceDimension, unsigned int, 3); itkStaticConstMacro(SpaceDimension, unsigned int, 3); itkStaticConstMacro(ParametersDimension, unsigned int, 13); /** Parameters Type */ typedef typename Superclass::ParametersType ParametersType; typedef typename Superclass::JacobianType JacobianType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::InputPointType InputPointType; typedef typename Superclass::OutputPointType OutputPointType; typedef typename Superclass::InputVectorType InputVectorType; typedef typename Superclass::OutputVectorType OutputVectorType; typedef typename Superclass::InputVnlVectorType InputVnlVectorType; typedef typename Superclass::OutputVnlVectorType OutputVnlVectorType; typedef typename Superclass::InputCovariantVectorType InputCovariantVectorType; typedef typename Superclass::OutputCovariantVectorType OutputCovariantVectorType; typedef typename Superclass::MatrixType MatrixType; typedef typename Superclass::InverseMatrixType InverseMatrixType; typedef typename Superclass::CenterType CenterType; typedef typename Superclass::OffsetType OffsetType; typedef typename Superclass::TranslationType TranslationType; /** VnlQuaternion type. */ typedef vnl_quaternion VnlQuaternionType; /** Compute the Jacobian Matrix of the transformation at one point */ /** Set the rotation of the rigid transform. * This method sets the rotation of a ANTSAffine3DTransform to a * value specified by the user. */ void SetRotation(const VnlQuaternionType &rotation); void SetS1(const TScalarType S1); void SetS2(const TScalarType S2); void SetS3(const TScalarType S3); void SetK1(const TScalarType K1); void SetK2(const TScalarType K2); void SetK3(const TScalarType K3); /** Get the rotation from an ANTSAffine3DTransform. * This method returns the value of the rotation of the * ANTSAffine3DTransform. **/ const VnlQuaternionType & GetRotation(void) const { return m_Rotation; } MatrixType ComputeMyRotationMatrix(); itkGetConstReferenceMacro( S1, TScalarType ); itkGetConstReferenceMacro( S2, TScalarType ); itkGetConstReferenceMacro( S3, TScalarType ); itkGetConstReferenceMacro( K1, TScalarType ); itkGetConstReferenceMacro( K2, TScalarType ); itkGetConstReferenceMacro( K3, TScalarType ); /** Set the parameters to the IdentityTransform */ virtual void SetIdentity(void); /** Set the transformation from a container of parameters. * This is typically used by optimizers. * There are 7 parameters. The first four represents the * quaternion and the last three represents the * offset. */ void SetParameters( const ParametersType & parameters ); const ParametersType & GetParameters() const; /** Compute the Jacobian of the transformation. * This method computes the Jacobian matrix of the transformation. * given point or vector, returning the transformed point or * vector. The rank of the Jacobian will also indicate if the transform * is invertible at this point. */ const JacobianType & GetJacobian(const InputPointType &point ) const; protected: /* ANTSAffine3DTransform(const MatrixType &matrix, */ /* const OutputVectorType &offset); */ ANTSAffine3DTransform(unsigned int outputDims, unsigned int paramDims); ANTSAffine3DTransform(); ~ANTSAffine3DTransform(){}; virtual void ComputeMatrix(); virtual void ComputeMatrixParameters(); void SetVarRotation(const VnlQuaternionType & rotation) { m_Rotation = rotation; }; // const InverseMatrixType & GetInverseMatrix( void ) const; void PrintSelf(std::ostream &os, Indent indent) const; private: ANTSAffine3DTransform(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Rotation of the transformation. */ VnlQuaternionType m_Rotation; /** added affine parameters **/ TScalarType m_S1; TScalarType m_S2; TScalarType m_S3; TScalarType m_K1; TScalarType m_K2; TScalarType m_K3; }; //class ANTSAffine3DTransform } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkANTSAffine3DTransform.txx" #endif #endif /* __itkANTSAffine3DTransform_h */ ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSAffine3DTransform.txx000066400000000000000000000370571147325206600253270ustar00rootroot00000000000000#ifndef _itkANTSAffine3DTransform_txx #define _itkANTSAffine3DTransform_txx #include "itkANTSAffine3DTransform.h" #include "vnl/algo/vnl_qr.h" namespace itk { // Constructor with default arguments template ANTSAffine3DTransform ::ANTSAffine3DTransform() : Superclass(SpaceDimension, ParametersDimension) { m_Rotation = VnlQuaternionType(0,0,0,1); // axis * vcl_sin(t/2), vcl_cos(t/2) m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_S3 = NumericTraits< TScalarType >::One; m_K1 = NumericTraits< TScalarType >::Zero; m_K2 = NumericTraits< TScalarType >::Zero; m_K3 = NumericTraits< TScalarType >::Zero; } // Constructor with default arguments template ANTSAffine3DTransform:: ANTSAffine3DTransform( unsigned int outputSpaceDimension, unsigned int parametersDimension ) : Superclass(outputSpaceDimension, parametersDimension) { m_Rotation = VnlQuaternionType(0,0,0,1); // axis * vcl_sin(t/2), vcl_cos(t/2) m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_S3 = NumericTraits< TScalarType >::One; m_K1 = NumericTraits< TScalarType >::Zero; m_K2 = NumericTraits< TScalarType >::Zero; m_K3 = NumericTraits< TScalarType >::Zero; } // // Constructor with explicit arguments // template // ANTSAffine3DTransform:: // ANTSAffine3DTransform( const MatrixType & matrix, // const OutputVectorType & offset ) : // Superclass(matrix, offset) // { // this->ComputeMatrixParameters(); // } // Print self template void ANTSAffine3DTransform:: PrintSelf(std::ostream &os, Indent indent ) const { Superclass::PrintSelf(os,indent); os << indent << "Rotation: " << m_Rotation << std::endl; os << indent << "S1, S2, S3: " << m_S1 <<", "< void ANTSAffine3DTransform:: SetRotation(const VnlQuaternionType &rotation ) { m_Rotation = rotation; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetS1(const TScalarType S1) { m_S1 = S1; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetS2(const TScalarType S2) { m_S2 = S2; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetS3(const TScalarType S3) { m_S3 = S3; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetK1(const TScalarType K1) { m_K1 = K1; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetK2(const TScalarType K2) { m_K2 = K2; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } template void ANTSAffine3DTransform:: SetK3(const TScalarType K3) { m_K3 = K3; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); return; } // Set the parameters in order to fit an Identity transform template void ANTSAffine3DTransform:: SetIdentity( void ) { m_Rotation = VnlQuaternionType(0,0,0,1); m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_S3 = NumericTraits< TScalarType >::One; m_K1 = NumericTraits< TScalarType >::Zero; m_K2 = NumericTraits< TScalarType >::Zero; m_K3 = NumericTraits< TScalarType >::Zero; this->Superclass::SetIdentity(); } // Set Parameters template void ANTSAffine3DTransform ::SetParameters( const ParametersType & parameters ) { OutputVectorType translation; // Transfer the quaternion part unsigned int par = 0; for(unsigned int j=0; j < 4; j++) { m_Rotation[j] = parameters[par]; ++par; } m_S1 = parameters[par++]; m_S2 = parameters[par++]; m_S3 = parameters[par++]; m_K1 = parameters[par++]; m_K2 = parameters[par++]; m_K3 = parameters[par++]; this->ComputeMatrix(); // Transfer the constant part for(unsigned int i=0; i < SpaceDimension; i++) { translation[i] = parameters[par]; ++par; } this->SetVarTranslation( translation ); this->ComputeOffset(); // Modified is always called since we just have a pointer to the // parameters and cannot know if the parameters have changed. this->Modified(); } // Set Parameters template const typename ANTSAffine3DTransform::ParametersType & ANTSAffine3DTransform ::GetParameters() const { VnlQuaternionType quaternion = this->GetRotation(); OutputVectorType translation = this->GetTranslation(); // Transfer the quaternion part unsigned int par = 0; for(unsigned int j=0; j < 4; j++) { this->m_Parameters[par] = quaternion[j]; ++par; } this->m_Parameters[par++] = m_S1; this->m_Parameters[par++] = m_S2; this->m_Parameters[par++] = m_S3; this->m_Parameters[par++] = m_K1; this->m_Parameters[par++] = m_K2; this->m_Parameters[par++] = m_K3; // Transfer the constant part for(unsigned int i=0; i < SpaceDimension; i++) { this->m_Parameters[par] = translation[i]; ++par; } return this->m_Parameters; } // Get parameters template const typename ANTSAffine3DTransform::JacobianType & ANTSAffine3DTransform:: GetJacobian( const InputPointType & p ) const { this->m_Jacobian.Fill(0.0); TScalarType c1 = this->GetCenter()[0]; TScalarType c2 = this->GetCenter()[1]; TScalarType c3 = this->GetCenter()[2]; TScalarType s1 = this->m_S1; TScalarType s2 = this->m_S2; TScalarType s3 = this->m_S3; TScalarType k1 = this->m_K1; TScalarType k2 = this->m_K2; TScalarType k3 = this->m_K3; TScalarType x1 = p[0]; TScalarType x2 = p[1]; TScalarType x3 = p[2]; // z1,z2,z3 is the S*K*point p TScalarType w1 = (x1-c1)+k1*(x2-c2)+k2*(x3-c3); TScalarType w2 = (x2-c2)+k3*(x3-c2); TScalarType w3 = (x3-c3); TScalarType z1 = s1*w1; TScalarType z2 = s2*w2; TScalarType z3 = s3*w3; // compute Jacobian with respect to quaternion parameters this->m_Jacobian[0][0] = 2.0 * ( m_Rotation.x() * z1 + m_Rotation.y() * z2 + m_Rotation.z() * z3 ); this->m_Jacobian[0][1] = 2.0 * (- m_Rotation.y() * z1 + m_Rotation.x() * z2 + m_Rotation.r() * z3 ); this->m_Jacobian[0][2] = 2.0 * (- m_Rotation.z() * z1 - m_Rotation.r() * z2 + m_Rotation.x() * z3 ); this->m_Jacobian[0][3] = - 2.0 * (- m_Rotation.r() * z1 + m_Rotation.z() * z2 - m_Rotation.y() * z3 ); this->m_Jacobian[1][0] = - this->m_Jacobian[0][1]; this->m_Jacobian[1][1] = this->m_Jacobian[0][0]; this->m_Jacobian[1][2] = this->m_Jacobian[0][3]; this->m_Jacobian[1][3] = - this->m_Jacobian[0][2]; this->m_Jacobian[2][0] = - this->m_Jacobian[0][2]; this->m_Jacobian[2][1] = - this->m_Jacobian[0][3]; this->m_Jacobian[2][2] = this->m_Jacobian[0][0]; this->m_Jacobian[2][3] = this->m_Jacobian[0][1]; // get rotation matrix first // this is done to compensate for the transposed representation // between VNL and ITK VnlQuaternionType conjugateRotation = m_Rotation.conjugate(); MatrixType newMatrix; newMatrix = conjugateRotation.rotation_matrix_transpose(); TScalarType r11 = newMatrix[0][0]; TScalarType r12 = newMatrix[0][1]; TScalarType r13 = newMatrix[0][2]; TScalarType r21 = newMatrix[1][0]; TScalarType r22 = newMatrix[1][1]; TScalarType r23 = newMatrix[1][2]; TScalarType r31 = newMatrix[2][0]; TScalarType r32 = newMatrix[2][1]; TScalarType r33 = newMatrix[2][2]; // compute Jacobian wrt S1/S2/S3 this->m_Jacobian[0][4] = r11 * w1; this->m_Jacobian[0][5] = r12 * w2; this->m_Jacobian[0][6] = r13 * w3; this->m_Jacobian[1][4] = r21 * w1; this->m_Jacobian[1][5] = r22 * w2; this->m_Jacobian[1][6] = r23 * w3; this->m_Jacobian[2][4] = r31 * w1; this->m_Jacobian[2][5] = r32 * w2; this->m_Jacobian[2][6] = r33 * w3; // compute Jacobian wrt K1/K2/K3 this->m_Jacobian[0][7] = r11 * s1 * (x2-c2); this->m_Jacobian[0][8] = r11 * s1 * (x3-c3); this->m_Jacobian[0][9] = r12 * s2 * (x3-c3); this->m_Jacobian[1][7] = r21 * s1 * (x2-c2); this->m_Jacobian[1][8] = r21 * s1 * (x3-c3); this->m_Jacobian[1][9] = r22 * s2 * (x3-c3); this->m_Jacobian[2][7] = r31 * s1 * (x2-c2); this->m_Jacobian[2][8] = r31 * s1 * (x3-c3); this->m_Jacobian[2][9] = r32 * s2 * (x3-c3); // for test purpose // FORCE ONLY DO DERIVATIVE ON S // for(int ii=0; ii <3; ii++){ // for(int jj=0; jj<=9;jj++){ // this->m_Jacobian[ii][jj] = 0.0; // } // } // this->m_Jacobian[0][4] = r11 * w1; // this->m_Jacobian[1][4] = r21 * w1; // this->m_Jacobian[2][4] = r31 * w1; // compute derivatives for the translation part unsigned int blockOffset = 10; for(unsigned int dim=0; dim < SpaceDimension; dim++ ) { this->m_Jacobian[ dim ][ blockOffset + dim ] = 1.0; } return this->m_Jacobian; // // compute derivatives with respect to rotation // this->m_Jacobian.Fill(0.0); // const TScalarType x = p[0] - this->GetCenter()[0]; // const TScalarType y = p[1] - this->GetCenter()[1]; // const TScalarType z = p[2] - this->GetCenter()[2]; // // compute Jacobian with respect to quaternion parameters // this->m_Jacobian[0][0] = 2.0 * ( m_Rotation.x() * x + m_Rotation.y() * y // + m_Rotation.z() * z ); // this->m_Jacobian[0][1] = 2.0 * (- m_Rotation.y() * x + m_Rotation.x() * y // + m_Rotation.r() * z ); // this->m_Jacobian[0][2] = 2.0 * (- m_Rotation.z() * x - m_Rotation.r() * y // + m_Rotation.x() * z ); // this->m_Jacobian[0][3] = - 2.0 * (- m_Rotation.r() * x + m_Rotation.z() * y // - m_Rotation.y() * z ); // this->m_Jacobian[1][0] = - this->m_Jacobian[0][1]; // this->m_Jacobian[1][1] = this->m_Jacobian[0][0]; // this->m_Jacobian[1][2] = this->m_Jacobian[0][3]; // this->m_Jacobian[1][3] = - this->m_Jacobian[0][2]; // this->m_Jacobian[2][0] = - this->m_Jacobian[0][2]; // this->m_Jacobian[2][1] = - this->m_Jacobian[0][3]; // this->m_Jacobian[2][2] = this->m_Jacobian[0][0]; // this->m_Jacobian[2][3] = this->m_Jacobian[0][1]; // // compute derivatives for the translation part // unsigned int blockOffset = 4; // for(unsigned int dim=0; dim < SpaceDimension; dim++ ) // { // this->m_Jacobian[ dim ][ blockOffset + dim ] = 1.0; // } // return this->m_Jacobian; } // template // const typename ANTSAffine3DTransform< TScalarType >::InverseMatrixType & // ANTSAffine3DTransform:: // GetInverseMatrix() const // { // // If the transform has been modified we recompute the inverse // if(this->InverseMatrixIsOld()) // { // InverseMatrixType newMatrix; // VnlQuaternionType conjugateRotation = m_Rotation.conjugate(); // VnlQuaternionType inverseRotation = conjugateRotation.inverse(); // newMatrix = inverseRotation.rotation_matrix_transpose(); // this->SetVarInverseMatrix(newMatrix); // } // return this->GetVarInverseMatrix(); // } template typename ANTSAffine3DTransform::MatrixType ANTSAffine3DTransform:: ComputeMyRotationMatrix() { VnlQuaternionType conjugateRotation = m_Rotation.conjugate(); // this is done to compensate for the transposed representation // between VNL and ITK MatrixType R; R = conjugateRotation.rotation_matrix_transpose(); return R; } template void ANTSAffine3DTransform:: ComputeMatrix() { VnlQuaternionType conjugateRotation = m_Rotation.conjugate(); // this is done to compensate for the transposed representation // between VNL and ITK MatrixType R; R = conjugateRotation.rotation_matrix_transpose(); MatrixType S; S.Fill(NumericTraits< TScalarType >::Zero); S[0][0] = this->m_S1; S[1][1] = this->m_S2; S[2][2] = this->m_S3; MatrixType K; K.Fill(NumericTraits< TScalarType >::Zero); K[0][0] = NumericTraits< TScalarType >::One; K[0][1] = this->m_K1; K[0][2] = this->m_K2; K[1][1] = NumericTraits< TScalarType >::One; K[1][2] = this->m_K3; K[2][2] = NumericTraits< TScalarType >::One; MatrixType newMatrix; newMatrix = R * S * K; this->SetVarMatrix(newMatrix); } template void ANTSAffine3DTransform:: ComputeMatrixParameters() { // VnlQuaternionType quat(this->GetMatrix().GetVnlMatrix()); // m_Rotation = quat; // std::cout << "compute para: to be done!" << std::endl; // InternalMatrixType A, Q, R; typedef vnl_matrix TMatrix; TMatrix A,Q,R; A = this->GetMatrix().GetVnlMatrix(); vnl_qr myqr(A); R = myqr.Q(); // Q() is the rotation Q = myqr.R(); // R() is the upper triangluar // this is not necessary, for the mirror case // the scale factor could not negative // normalize Q // TMatrix dq(3,3,0); // for(unsigned i=0;i<3;i++){ // dq(i,i) = (Q(i,i)>=0)? 1 : -1; // } // R = R * dq; // Q = dq * Q; double tr = 1 + R(0,0)+R(1,1)+R(2,2); double s,r,u,v,w; if (tr > 0){ s = 0.5 / sqrt(tr); r = 0.25 / s; u = (R(2,1)-R(1,2))*s; v = (R(0,2)-R(2,0))*s; w = (R(1,0)-R(0,1))*s; } else if (R(0,0)>R(1,1) && R(0,0)>R(2,2)) { s = 2 * sqrt(1 + R(0,0) - R(1,1) - R(2,2)); u = 0.25 * s; v = (R(0,1)+R(1,0)) / s; w = (R(0,2)+R(2,0)) / s; r = (R(1,2)-R(2,1)) / s; } else if (R(0,0)>R(1,1)) { s = 2 * sqrt(1 + R(1,1) - R(0,0) - R(2,2)); u = (R(0,1)+R(1,0)) / s; v = 0.25 * s; w = (R(1,2)+R(2,1)) / s; r = (R(0,2)-R(2,0)) / s; } else { s = 2 * sqrt(1 + R(2,2) - R(0,0) - R(1,1)); u = (R(0,2)+R(2,0)) / s; v = (R(1,2)+R(2,1)) / s; w = 0.25 * s; r = (R(0,1)-R(1,0)) / s; } m_Rotation = VnlQuaternionType(u,v,w,r); m_S1 = Q(0,0); m_S2 = Q(1,1); m_S3 = Q(2,2); m_K1 = Q(0,1) / Q(0,0); m_K2 = Q(0,2) / Q(0,0); m_K3 = Q(1,2) / Q(1,1); // std::cout << "before: this->GetMatrix(): " << this->GetMatrix(); this->ComputeMatrix(); // std::cout << "after: this->GetMatrix(): " << this->GetMatrix(); // std::cout << "A=" << A << std::endl; // std::cout << "Q=" << Q << std::endl; // std::cout << "R=" << R << std::endl; // std::cout << "dq=" << dq << std::endl; } } // namespace #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSCenteredAffine2DTransform.h000066400000000000000000000202261147325206600263720ustar00rootroot00000000000000#ifndef __itkANTSCenteredAffine2DTransform_h #define __itkANTSCenteredAffine2DTransform_h #include #include "itkMatrixOffsetTransformBase.h" #include "itkExceptionObject.h" namespace itk { template < class TScalarType=double > // Data type for scalars (float or double) //class ITK_EXPORT Rigid2DTransform : class ITK_EXPORT ANTSCenteredAffine2DTransform: public MatrixOffsetTransformBase< TScalarType, 2, 2> // Dimensions of input and output spaces { public: /** Standard class typedefs. */ // typedef Rigid2DTransform Self; typedef ANTSCenteredAffine2DTransform Self; typedef MatrixOffsetTransformBase< TScalarType, 2, 2 > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ // itkTypeMacro( Rigid2DTransform, MatrixOffsetTransformBase ); itkTypeMacro( ANTSCenteredAffine2DTransform, MatrixOffsetTransformBase ); /** New macro for creation of through a Smart Pointer */ itkNewMacro( Self ); /** Dimension of the space. */ itkStaticConstMacro(InputSpaceDimension, unsigned int, 2); itkStaticConstMacro(OutputSpaceDimension, unsigned int, 2); // itkStaticConstMacro(ParametersDimension, unsigned int, 3); itkStaticConstMacro(ParametersDimension, unsigned int, 8); /** Scalar type. */ typedef typename Superclass::ScalarType ScalarType; /** Parameters type. */ typedef typename Superclass::ParametersType ParametersType; /** Jacobian type. */ typedef typename Superclass::JacobianType JacobianType; /// Standard matrix type for this class typedef typename Superclass::MatrixType MatrixType; /// Standard vector type for this class typedef typename Superclass::OffsetType OffsetType; /// Standard vector type for this class typedef typename Superclass::InputVectorType InputVectorType; typedef typename Superclass::OutputVectorType OutputVectorType; /// Standard covariant vector type for this class typedef typename Superclass::InputCovariantVectorType InputCovariantVectorType; typedef typename Superclass::OutputCovariantVectorType OutputCovariantVectorType; /// Standard vnl_vector type for this class typedef typename Superclass::InputVnlVectorType InputVnlVectorType; typedef typename Superclass::OutputVnlVectorType OutputVnlVectorType; /// Standard coordinate point type for this class typedef typename Superclass::InputPointType InputPointType; typedef typename Superclass::OutputPointType OutputPointType; /** * Set the rotation Matrix of a Rigid2D Transform * * This method sets the 2x2 matrix representing the rotation * in the transform. The Matrix is expected to be orthogonal * with a certain tolerance. * * \warning This method will throw an exception is the matrix * provided as argument is not orthogonal. * * \sa MatrixOffsetTransformBase::SetMatrix() **/ // virtual void SetMatrix( const MatrixType & matrix ); /** * Set/Get the rotation matrix. These methods are old and are * retained for backward compatibility. Instead, use SetMatrix() * GetMatrix(). **/ // virtual void SetRotationMatrix(const MatrixType &matrix) // { this->SetMatrix( matrix ); } // const MatrixType & GetRotationMatrix() const // { return this->GetMatrix(); } /** * Compose the transformation with a translation * * This method modifies self to include a translation of the * origin. The translation is precomposed with self if pre is * true, and postcomposed otherwise. **/ // void Translate(const OffsetType &offset, bool pre=false); /** * Back transform by an rigid transformation. * * The BackTransform() methods are slated to be removed from ITK. * Instead, please use GetInverse() or CloneInverseTo() to generate * an inverse transform and then perform the transform using that * inverted transform. **/ inline InputPointType BackTransform(const OutputPointType &point ) const; inline InputVectorType BackTransform(const OutputVectorType &vector) const; inline InputVnlVectorType BackTransform(const OutputVnlVectorType &vector) const; inline InputCovariantVectorType BackTransform( const OutputCovariantVectorType &vector) const; /** Set/Get the angle of rotation in radians */ void SetAngle(TScalarType angle); void SetS1(TScalarType S1); void SetS2(TScalarType S2); void SetK(TScalarType K); itkGetConstReferenceMacro( Angle, TScalarType ); itkGetConstReferenceMacro( S1, TScalarType ); itkGetConstReferenceMacro( S2, TScalarType ); itkGetConstReferenceMacro( K, TScalarType ); /** Set the angle of rotation in degrees. */ void SetAngleInDegrees(TScalarType angle); /** Set/Get the angle of rotation in radians. These methods * are old and are retained for backward compatibility. * Instead, use SetAngle() and GetAngle(). */ // void SetRotation(TScalarType angle) // { this->SetAngle(angle); } // virtual const TScalarType & GetRotation() const // { return m_Angle; } /** Set the transformation from a container of parameters * This is typically used by optimizers. * There are 3 parameters. The first one represents the * angle of rotation in radians and the last two represents the translation. * The center of rotation is fixed. * * \sa Transform::SetParameters() * \sa Transform::SetFixedParameters() */ void SetParameters( const ParametersType & parameters ); /** Get the parameters that uniquely define the transform * This is typically used by optimizers. * There are 3 parameters. The first one represents the * angle or rotation in radians and the last two represents the translation. * The center of rotation is fixed. * * \sa Transform::GetParameters() * \sa Transform::GetFixedParameters() */ const ParametersType & GetParameters( void ) const; /** This method computes the Jacobian matrix of the transformation * at a given input point. * * \sa Transform::GetJacobian() */ const JacobianType & GetJacobian(const InputPointType &point ) const; /** * This method creates and returns a new ANTSCenteredAffine2DTransform object * which is the inverse of self. **/ // void CloneInverseTo( Pointer & newinverse ) const; /** * This method creates and returns a new ANTSCenteredAffine2DTransform object * which has the same parameters. **/ void CloneTo( Pointer & clone ) const; /** Reset the parameters to create and identity transform. */ virtual void SetIdentity(void); protected: // Rigid2DTransform(); ANTSCenteredAffine2DTransform(); // Rigid2DTransform( unsigned int outputSpaceDimension, // unsigned int parametersDimension); ANTSCenteredAffine2DTransform( unsigned int outputSpaceDimension, unsigned int parametersDimension); // ~Rigid2DTransform(); ~ANTSCenteredAffine2DTransform(); /** * Print contents of an ANTSCenteredAffine2DTransform **/ void PrintSelf(std::ostream &os, Indent indent) const; /** Compute the matrix from angle. This is used in Set methods * to update the underlying matrix whenever a transform parameter * is changed. */ virtual void ComputeMatrix(void); /** Compute the angle from the matrix. This is used to compute * transform parameters from a given matrix. This is used in * MatrixOffsetTransformBase::Compose() and * MatrixOffsetTransformBase::GetInverse(). */ virtual void ComputeMatrixParameters(void); /** Update angle without recomputation of other internal variables. */ void SetVarAngle( TScalarType angle ) { m_Angle = angle; } void SetVarS1( TScalarType S1) { m_S1 = S1; } void SetVarS2( TScalarType S2) { m_S2 = S2; } void SetVarK( TScalarType K) { m_K = K; } private: ANTSCenteredAffine2DTransform(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented TScalarType m_Angle; TScalarType m_S1; TScalarType m_S2; TScalarType m_K; }; //class ANTSCenteredAffine2DTransform } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkANTSCenteredAffine2DTransform.txx" #endif #endif /* __itkANTSCenteredAffine2DTransform_h */ ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSCenteredAffine2DTransform.txx000066400000000000000000000327251147325206600267750ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSCenteredAffine2DTransform.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkANTSCenteredAffine2DTransform_txx #define _itkANTSCenteredAffine2DTransform_txx // #include "itkRigid2DTransform.h" #include "itkANTSCenteredAffine2DTransform.h" #include "vnl/algo/vnl_qr.h" namespace itk { // Constructor with default arguments // template // ANTSCenteredAffine2DTransform:: // ANTSCenteredAffine2DTransform(): // Superclass(OutputSpaceDimension, ParametersDimension) // { // m_Angle = NumericTraits< TScalarType >::Zero; // } template ANTSCenteredAffine2DTransform:: ANTSCenteredAffine2DTransform(): Superclass(OutputSpaceDimension, ParametersDimension) { m_Angle = NumericTraits< TScalarType >::Zero; m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_K = NumericTraits< TScalarType >::Zero; } // Constructor with arguments template ANTSCenteredAffine2DTransform:: ANTSCenteredAffine2DTransform( unsigned int spaceDimension, unsigned int parametersDimension): Superclass(spaceDimension,parametersDimension) { m_Angle = NumericTraits< TScalarType >::Zero; m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_K = NumericTraits< TScalarType >::Zero; } // Destructor template ANTSCenteredAffine2DTransform:: ~ANTSCenteredAffine2DTransform() { } // Print self template void ANTSCenteredAffine2DTransform:: PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "Angle = " << m_Angle << std::endl; os << indent << "S1 = " << m_S1 << std::endl; os << indent << "S2 = " << m_S2 << std::endl; os << indent << "K = " << m_K << std::endl; // os << indent << "S2 = " << m_ << std::endl; } // Set the rotation matrix // template // void // ANTSCenteredAffine2DTransform:: // SetMatrix(const MatrixType & matrix ) // { // itkDebugMacro("setting m_Matrix to " << matrix ); // // The matrix must be orthogonal otherwise it is not // // representing a valid rotaion in 2D space // typename MatrixType::InternalMatrixType test = // matrix.GetVnlMatrix() * matrix.GetTranspose(); // const double tolerance = 1e-10; // if( !test.is_identity( tolerance ) ) // { // itk::ExceptionObject ex(__FILE__,__LINE__,"Attempt to set a Non-Orthogonal matrix",ITK_LOCATION); // throw ex; // } // this->SetVarMatrix( matrix ); // this->ComputeOffset(); // this->ComputeMatrixParameters(); // this->Modified(); // } /** Compute the Angle from the Rotation Matrix */ template void ANTSCenteredAffine2DTransform ::ComputeMatrixParameters( void ) { typedef vnl_matrix TMatrix; TMatrix A,Q,R; A = this->GetMatrix().GetVnlMatrix(); vnl_qr myqr(A); R = myqr.Q(); // Q() is the rotation Q = myqr.R(); // R() is the upper triangluar TMatrix dq(2,2,0); for(unsigned i=0;i<2;i++){ dq(i,i) = (Q(i,i)>=0)? 1 : -1; } R = R * dq; Q = dq * Q; // std::cout << "A=" << A << std::endl; // std::cout << "Q=" << Q << std::endl; // std::cout << "R=" << R << std::endl; // std::cout << "dq=" << dq << std::endl; m_Angle = vcl_acos(R[0][0]); if(this->GetMatrix()[1][0]<0.0) { m_Angle = -m_Angle; } m_S1 = Q[0][0]; m_S2 = Q[1][1]; m_K = Q[0][1] / Q[0][0]; this->ComputeMatrix(); if(this->GetMatrix()[1][0]-sin(m_Angle) > 0.000001) { itkWarningMacro("Bad Rotation Matrix " << this->GetMatrix() ); } } // // Compose with a translation // template // void // ANTSCenteredAffine2DTransform:: // Translate(const OffsetType &offset, bool) // { // OutputVectorType newOffset = this->GetOffset(); // newOffset += offset; // this->SetOffset(newOffset); // } // Create and return an inverse transformation // template // void // ANTSCenteredAffine2DTransform:: // CloneInverseTo( Pointer & result ) const // { // result = New(); // result->SetCenter( this->GetCenter() ); // inverse have the same center // result->SetAngle( -this->GetAngle() ); // result->SetTranslation( -( this->GetInverseMatrix() * this->GetTranslation() ) ); // } // Create and return a clone of the transformation template void ANTSCenteredAffine2DTransform:: CloneTo( Pointer & result ) const { result = New(); result->SetCenter( this->GetCenter() ); result->SetAngle( this->GetAngle() ); result->SetS1( this->GetS1() ); result->SetS2( this->GetS2() ); result->SetK( this->GetK() ); result->SetTranslation( this->GetTranslation() ); } // Reset the transform to an identity transform template void ANTSCenteredAffine2DTransform< TScalarType >:: SetIdentity( void ) { this->Superclass::SetIdentity(); m_Angle = NumericTraits< TScalarType >::Zero; m_S1 = NumericTraits< TScalarType >::One; m_S2 = NumericTraits< TScalarType >::One; m_K = NumericTraits< TScalarType >::Zero; } // Set the angle of rotation template void ANTSCenteredAffine2DTransform ::SetAngle(TScalarType angle) { m_Angle = angle; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); } template void ANTSCenteredAffine2DTransform ::SetS1(TScalarType S1) { m_S1 = S1; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); } template void ANTSCenteredAffine2DTransform ::SetS2(TScalarType S2) { m_S2 = S2; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); } template void ANTSCenteredAffine2DTransform ::SetK(TScalarType K) { m_K = K; this->ComputeMatrix(); this->ComputeOffset(); this->Modified(); } // Set the angle of rotation template void ANTSCenteredAffine2DTransform ::SetAngleInDegrees(TScalarType angle) { const TScalarType angleInRadians = angle * vcl_atan(1.0) / 45.0; this->SetAngle( angleInRadians ); } // Compute the matrix from the angle template void ANTSCenteredAffine2DTransform ::ComputeMatrix( void ) { const double ca = vcl_cos(m_Angle ); const double sa = vcl_sin(m_Angle ); const double s1 = m_S1; const double s2 = m_S2; const double k = m_K; MatrixType rotationMatrix; rotationMatrix[0][0]= ca; rotationMatrix[0][1]=-sa; rotationMatrix[1][0]= sa; rotationMatrix[1][1]= ca; MatrixType scaleMatrix; scaleMatrix[0][0]= s1; scaleMatrix[0][1]=0; scaleMatrix[1][0]= 0; scaleMatrix[1][1]= s2; MatrixType shearMatrix; shearMatrix[0][0]= 1; shearMatrix[0][1]=k; shearMatrix[1][0]= 0; shearMatrix[1][1]= 1; MatrixType varMatrix; varMatrix = rotationMatrix * scaleMatrix * shearMatrix; this->SetVarMatrix( varMatrix ); } // Set Parameters template void ANTSCenteredAffine2DTransform:: SetParameters( const ParametersType & parameters ) { itkDebugMacro( << "Setting parameters " << parameters ); // Set angle/s1/s2/k this->SetVarAngle( parameters[0] ); this->SetVarS1( parameters[1] ); this->SetVarS2( parameters[2] ); this->SetVarK( parameters[3] ); // Set the center InputPointType center; for(unsigned int i=0; i < OutputSpaceDimension; i++) { center[i] = parameters[i+4]; } this->SetVarCenter( center ); // Set translation OutputVectorType translation; for(unsigned int i=0; i < OutputSpaceDimension; i++) { translation[i] = parameters[i+6]; } this->SetVarTranslation( translation ); // Update matrix and offset this->ComputeMatrix(); this->ComputeOffset(); // Modified is always called since we just have a pointer to the // parameters and cannot know if the parameters have changed. this->Modified(); itkDebugMacro(<<"After setting parameters "); } // Get Parameters template const typename ANTSCenteredAffine2DTransform::ParametersType & ANTSCenteredAffine2DTransform:: GetParameters( void ) const { itkDebugMacro( << "Getting parameters "); // Get the angle/s1/s2/k this->m_Parameters[0] = this->GetAngle(); this->m_Parameters[1] = this->GetS1(); this->m_Parameters[2] = this->GetS2(); this->m_Parameters[3] = this->GetK(); // Get the center for(unsigned int i=0; i < OutputSpaceDimension; i++) { this->m_Parameters[i+4] = this->GetCenter()[i]; } // Get the translation for(unsigned int i=0; i < OutputSpaceDimension; i++) { this->m_Parameters[i+6] = this->GetTranslation()[i]; } itkDebugMacro(<<"After getting parameters " << this->m_Parameters ); return this->m_Parameters; } // Compute transformation Jacobian template const typename ANTSCenteredAffine2DTransform::JacobianType & ANTSCenteredAffine2DTransform:: GetJacobian( const InputPointType & p ) const { const double ca = vcl_cos(this->GetAngle() ); const double sa = vcl_sin(this->GetAngle() ); const double s1 = m_S1; const double s2 = m_S2; const double k = m_K; this->m_Jacobian.Fill(0.0); const double cx = this->GetCenter()[0]; const double cy = this->GetCenter()[1]; // derivatives with respect to the angle // this->m_Jacobian[0][0] = -sa * ( p[0] - cx ) - ca * ( p[1] - cy ); // this->m_Jacobian[1][0] = ca * ( p[0] - cx ) - sa * ( p[1] - cy ); double pxoff = (p[0]-cx)+k*(p[1]-cy); double pyoff = p[1]-cy; // wrt. theta this->m_Jacobian[0][0] = s1*( pxoff )*(-sa) + s2*( pyoff )*(-ca); this->m_Jacobian[1][0] = s1*( pxoff )*(ca) + s2*( pyoff )*(-sa); // wrt. s1/s2 this->m_Jacobian[0][1] = ca * pxoff; this->m_Jacobian[0][2] = -sa * pyoff; this->m_Jacobian[1][1] = sa * pxoff; this->m_Jacobian[1][2] = ca * pyoff; // wrt. k this->m_Jacobian[0][3] = ca * s1 * pyoff; this->m_Jacobian[1][3] = sa * s1 * pyoff; // wrt. cx/cy this->m_Jacobian[0][4] = - s1*ca + 1.0; this->m_Jacobian[0][5] = -(k*s1*ca - s2*sa); this->m_Jacobian[1][4] = - s1*sa; this->m_Jacobian[1][5] = -(k*s1*sa + s2*ca) + 1.0; // wrt. t1/t2 this->m_Jacobian[0][6] = 1.0; this->m_Jacobian[1][7] = 1.0; // compute derivatives for the translation part // unsigned int blockOffset = 1; // for(unsigned int dim=0; dim < OutputSpaceDimension; dim++ ) // { // this->m_Jacobian[ dim ][ blockOffset + dim ] = 1.0; // } return this->m_Jacobian; } // Back transform a point template typename ANTSCenteredAffine2DTransform::InputPointType ANTSCenteredAffine2DTransform:: BackTransform(const OutputPointType &point) const { itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK. Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform."); return this->GetInverseMatrix() * (point - this->GetOffset()); } // Back transform a vector template typename ANTSCenteredAffine2DTransform::InputVectorType ANTSCenteredAffine2DTransform:: BackTransform(const OutputVectorType &vect ) const { itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK. Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform."); return this->GetInverseMatrix() * vect; } // Back transform a vnl_vector template typename ANTSCenteredAffine2DTransform::InputVnlVectorType ANTSCenteredAffine2DTransform:: BackTransform(const OutputVnlVectorType &vect ) const { itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK. Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform."); return this->GetInverseMatrix() * vect; } // Back Transform a CovariantVector template typename ANTSCenteredAffine2DTransform::InputCovariantVectorType ANTSCenteredAffine2DTransform:: BackTransform(const OutputCovariantVectorType &vect) const { itkWarningMacro(<<"BackTransform(): This method is slated to be removed from ITK. Instead, please use GetInverse() to generate an inverse transform and then perform the transform using that inverted transform."); return this->GetMatrix() * vect; } } // namespace #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSImageRegistrationOptimizer.cxx000066400000000000000000003272211147325206600273460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSImageRegistrationOptimizer.cxx,v $ Language: C++ Date: $Date: 2009/04/22 01:00:16 $ Version: $Revision: 1.47 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkANTSImageRegistrationOptimizer_txx_ #define _itkANTSImageRegistrationOptimizer_txx_ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include "itkVectorParameterizedNeighborhoodOperatorImageFilter.h" #include "itkANTSImageRegistrationOptimizer.h" #include "itkIdentityTransform.h" #include "itkLinearInterpolateImageFunction.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkVectorGaussianInterpolateImageFunction.h" #include "itkResampleImageFilter.h" #include "itkVectorNeighborhoodOperatorImageFilter.h" #include "vnl/vnl_math.h" #include "ANTS_affine_registration2.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkVectorImageFileWriter.h" namespace itk { template ANTSImageRegistrationOptimizer ::ANTSImageRegistrationOptimizer() { this->m_DeformationField=NULL; this->m_InverseDeformationField=NULL; this->m_AffineTransform=NULL; itk::TransformFactory::RegisterTransform(); itk::TransformFactory >::RegisterTransform(); itk::TransformFactory >::RegisterTransform(); this->m_FixedPointSet=NULL; this->m_MovingPointSet=NULL; this->m_UseMulti=true; this->m_UseROI=false; this->m_MaskImage=NULL; this->m_ScaleFactor=1.0; this->m_Debug=false; this->m_SyNF=NULL; this->m_SyNFInv=NULL; this->m_SyNM=NULL; this->m_SyNMInv=NULL; this->m_Parser=NULL; this->m_GaussianTruncation=256; this->m_TimeVaryingVelocity=NULL; this->m_LastTimeVaryingVelocity=NULL; this->m_LastTimeVaryingUpdate=NULL; this->m_DeltaTime=0.1; this->m_SyNType=0; this->m_UseNN=false; this->m_UseBSplineInterpolation=false; this->m_VelocityFieldInterpolator=VelocityFieldInterpolatorType::New(); this->m_HitImage=NULL; this->m_ThickImage=NULL; this->m_SyNFullTime=0; } template typename ANTSImageRegistrationOptimizer::ImagePointer ANTSImageRegistrationOptimizer ::SubsampleImage( ImagePointer image, RealType scalingFactor , typename ImageType::PointType outputOrigin, typename ImageType::DirectionType outputDirection , AffineTransformPointer aff ) { typename ImageType::SpacingType inputSpacing = image->GetSpacing(); typename ImageType::RegionType::SizeType inputSize = image->GetRequestedRegion().GetSize(); typename ImageType::SpacingType outputSpacing=this->m_CurrentDomainSpacing; typename ImageType::RegionType::SizeType outputSize=this->m_CurrentDomainSize; // RealType minimumSpacing = inputSpacing.GetVnlVector().min_value(); // RealType maximumSpacing = inputSpacing.GetVnlVector().max_value(); typedef ResampleImageFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); typedef LinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetInputImage( image ); resampler->SetInterpolator( interpolator ); typedef itk::IdentityTransform< double, TDimension > TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); resampler->SetTransform( transform ); if ( aff ) { // std::cout << " Setting Aff to " << this->m_AffineTransform << std::endl; resampler->SetTransform( aff ); } resampler->SetInput( image ); resampler->SetOutputSpacing( outputSpacing ); resampler->SetOutputOrigin( outputOrigin ); resampler->SetOutputDirection( outputDirection ); resampler->SetSize( outputSize ); resampler->Update(); ImagePointer outimage = resampler->GetOutput(); if (this->m_UseROI ) { outimage=this->MakeSubImage(outimage); // WriteImage(outimage,"temps.hdr"); // warp with affine & deformable } return outimage; } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::CopyDeformationField( DeformationFieldPointer input ) { DeformationFieldPointer output=DeformationFieldType::New(); output->SetSpacing( input->GetSpacing() ); output->SetOrigin( input->GetOrigin() ); output->SetDirection( input->GetDirection() ); output->SetLargestPossibleRegion(input->GetLargestPossibleRegion() ); output->SetRequestedRegion(input->GetLargestPossibleRegion() ); output->SetBufferedRegion( input->GetLargestPossibleRegion() ); output->Allocate(); typedef ImageRegionIterator Iterator; Iterator inIter( input, input->GetBufferedRegion() ); Iterator outIter( output, output->GetBufferedRegion() ); inIter.GoToBegin(); outIter.GoToBegin(); for( ; !inIter.IsAtEnd(); ++inIter, ++outIter ) { outIter.Set( inIter.Get() ); } output->SetSpacing( input->GetSpacing()); output->SetOrigin(input->GetOrigin()); return output; } template void ANTSImageRegistrationOptimizer ::SmoothDeformationFieldGauss(DeformationFieldPointer field, float sig, bool useparamimage, unsigned int lodim) { if (this->m_Debug ) std::cout << " enter gauss smooth " << sig << std::endl; if (sig <= 0) return; if (!field) { std::cout << " No Field in gauss Smoother " << std::endl; return; } DeformationFieldPointer tempField=DeformationFieldType::New(); tempField->SetSpacing( field->GetSpacing() ); tempField->SetOrigin( field->GetOrigin() ); tempField->SetDirection( field->GetDirection() ); tempField->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); tempField->SetRequestedRegion( field->GetRequestedRegion() ); tempField->SetBufferedRegion( field->GetBufferedRegion() ); tempField->Allocate(); typedef typename DeformationFieldType::PixelType VectorType; typedef typename VectorType::ValueType ScalarType; typedef GaussianOperator OperatorType; // typedef VectorNeighborhoodOperatorImageFilter< DeformationFieldType, DeformationFieldType> SmootherType; typedef VectorParameterizedNeighborhoodOperatorImageFilter< DeformationFieldType, DeformationFieldType, ImageType> SmootherType; OperatorType * oper = new OperatorType; typename SmootherType::Pointer smoother = SmootherType::New(); typedef typename DeformationFieldType::PixelContainerPointer PixelContainerPointer; PixelContainerPointer swapPtr; // graft the output field onto the mini-pipeline smoother->GraftOutput( tempField ); typename ImageType::SpacingType spacing=field->GetSpacing(); for( unsigned int j = 0; j < lodim; j++ ) { // smooth along this dimension oper->SetDirection( j ); float sigt=sig; oper->SetVariance( sigt ); oper->SetMaximumError(0.001 ); oper->SetMaximumKernelWidth( (unsigned int) this->m_GaussianTruncation ); oper->CreateDirectional(); // todo: make sure we only smooth within the buffered region smoother->SetOperator( *oper ); smoother->SetInput( field ); smoother->Update(); if ( j < lodim - 1 ) { // swap the containers swapPtr = smoother->GetOutput()->GetPixelContainer(); smoother->GraftOutput( field ); field->SetPixelContainer( swapPtr ); smoother->Modified(); } } // graft the output back to this filter tempField->SetPixelContainer( field->GetPixelContainer() ); //make sure boundary does not move float weight=1.0; if (sig < 0.5) weight=1.0-1.0*(sig/0.5); float weight2=1.0-weight; typedef itk::ImageRegionIteratorWithIndex Iterator; typename DeformationFieldType::SizeType size = field->GetLargestPossibleRegion().GetSize(); Iterator outIter( field, field->GetLargestPossibleRegion() ); for( outIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter ) { bool onboundary=false; typename DeformationFieldType::IndexType index= outIter.GetIndex(); for (int i=0;i= static_cast( size[i] )-1 ) onboundary=true; } if (onboundary) { VectorType vec; vec.Fill(0.0); outIter.Set(vec); } else { //field=this->CopyDeformationField( VectorType svec=smoother->GetOutput()->GetPixel(index); outIter.Set( svec*weight+outIter.Get()*weight2); } } if (this->m_Debug ) std::cout << " done gauss smooth " << std::endl; delete oper; } template void ANTSImageRegistrationOptimizer ::SmoothVelocityGauss(TimeVaryingVelocityFieldPointer field, float sig , unsigned int lodim) { if (sig <= 0) return; if (!field) { std::cout << " No Field in gauss Smoother " << std::endl; return; } TimeVaryingVelocityFieldPointer tempField=TimeVaryingVelocityFieldType::New(); tempField->SetSpacing( field->GetSpacing() ); tempField->SetOrigin( field->GetOrigin() ); tempField->SetDirection( field->GetDirection() ); tempField->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); tempField->SetRequestedRegion( field->GetRequestedRegion() ); tempField->SetBufferedRegion( field->GetBufferedRegion() ); tempField->Allocate(); typedef typename TimeVaryingVelocityFieldType::PixelType VectorType; typedef typename VectorType::ValueType ScalarType; typedef GaussianOperator OperatorType; typedef VectorNeighborhoodOperatorImageFilter SmootherType; OperatorType * oper = new OperatorType; typename SmootherType::Pointer smoother = SmootherType::New(); typedef typename TimeVaryingVelocityFieldType::PixelContainerPointer PixelContainerPointer; PixelContainerPointer swapPtr; // graft the output field onto the mini-pipeline smoother->GraftOutput( tempField ); for( unsigned int j = 0; j < lodim; j++ ) { // smooth along this dimension oper->SetDirection( j ); oper->SetVariance( sig ); oper->SetMaximumError(0.001 ); oper->SetMaximumKernelWidth( (unsigned int) this->m_GaussianTruncation ); oper->CreateDirectional(); // todo: make sure we only smooth within the buffered region smoother->SetOperator( *oper ); smoother->SetInput( field ); smoother->Update(); if ( j < lodim - 1 ) { // swap the containers swapPtr = smoother->GetOutput()->GetPixelContainer(); smoother->GraftOutput( field ); field->SetPixelContainer( swapPtr ); smoother->Modified(); } } // graft the output back to this filter tempField->SetPixelContainer( field->GetPixelContainer() ); //make sure boundary does not move float weight=1.0; if (sig < 0.5) weight=1.0-1.0*(sig/0.5); float weight2=1.0-weight; typedef itk::ImageRegionIteratorWithIndex Iterator; typename TimeVaryingVelocityFieldType::SizeType size = field->GetLargestPossibleRegion().GetSize(); Iterator outIter( field, field->GetLargestPossibleRegion() ); for( outIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter ) { bool onboundary=false; typename TimeVaryingVelocityFieldType::IndexType index= outIter.GetIndex(); for (int i=0;i= static_cast( size[i] )-1 ) onboundary=true; } if (onboundary) { VectorType vec; vec.Fill(0.0); outIter.Set(vec); } else { //field=this->CopyDeformationField( VectorType svec=smoother->GetOutput()->GetPixel(index); outIter.Set( svec*weight+outIter.Get()*weight2); } } if (this->m_Debug ) std::cout << " done gauss smooth " << std::endl; delete oper; } template void ANTSImageRegistrationOptimizer ::SmoothDeformationFieldBSpline( DeformationFieldPointer field, ArrayType meshsize, unsigned int splineorder, unsigned int numberoflevels ) { if (this->m_Debug ) std::cout << " enter bspline smooth " << std::endl; if (!field) { std::cout << " No Field in bspline Smoother " << std::endl; return; } if ( splineorder <= 0 ) { return; } typename BSplineFilterType::ArrayType numberofcontrolpoints; for ( unsigned int d = 0; d < ImageDimension; d++ ) { if ( meshsize[d] <= 0 ) { return; } numberofcontrolpoints[d] = static_cast( meshsize[d] ) + splineorder; } VectorType zeroVector; zeroVector.Fill( 0.0 ); // typedef VectorImageFileWriter // DeformationFieldWriterType; // typename DeformationFieldWriterType::Pointer writer = DeformationFieldWriterType::New(); // writer->SetInput( field ); // writer->SetFileName( "field.nii.gz" ); // writer->Update(); // exit( 0 ); typename ImageType::DirectionType originalDirection = field->GetDirection(); typename ImageType::DirectionType identityDirection; identityDirection.SetIdentity(); field->SetDirection( identityDirection ); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetInput( field ); bspliner->SetNumberOfLevels( numberoflevels ); bspliner->SetSplineOrder( splineorder ); bspliner->SetNumberOfControlPoints( numberofcontrolpoints ); bspliner->SetIgnorePixelValue( zeroVector ); bspliner->Update(); field->SetDirection( originalDirection ); //make sure boundary does not move typedef itk::ImageRegionIteratorWithIndex Iterator; typename DeformationFieldType::SizeType size = field->GetLargestPossibleRegion().GetSize(); Iterator bIter( bspliner->GetOutput(), bspliner->GetOutput()->GetLargestPossibleRegion() ); Iterator outIter( field, field->GetLargestPossibleRegion() ); for( outIter.GoToBegin(), bIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter, ++bIter ) { // bool onboundary=false; // typename DeformationFieldType::IndexType index = outIter.GetIndex(); // for( int i = 0; i < ImageDimension; i++ ) // { // if ( index[i] < 1 || index[i] >= static_cast( size[i] )-1 ) // onboundary = true; // } // if (onboundary) // { // VectorType vec; // vec.Fill(0.0); // outIter.Set(vec); // } // else // { outIter.Set( bIter.Get() ); // } } if (this->m_Debug ) std::cout << " done bspline smooth " << std::endl; } template void ANTSImageRegistrationOptimizer ::ComposeDiffs(DeformationFieldPointer fieldtowarpby, DeformationFieldPointer field, DeformationFieldPointer fieldout, float timesign) { typedef Point VPointType; // field->SetSpacing( fieldtowarpby->GetSpacing() ); // field->SetOrigin( fieldtowarpby->GetOrigin() ); // field->SetDirection( fieldtowarpby->GetDirection() ); if (!fieldout) { fieldout=DeformationFieldType::New(); fieldout->SetSpacing( fieldtowarpby->GetSpacing() ); fieldout->SetOrigin( fieldtowarpby->GetOrigin() ); fieldout->SetDirection( fieldtowarpby->GetDirection() ); fieldout->SetLargestPossibleRegion(fieldtowarpby->GetLargestPossibleRegion() ); fieldout->SetRequestedRegion( fieldtowarpby->GetLargestPossibleRegion() ); fieldout->SetBufferedRegion( fieldtowarpby->GetLargestPossibleRegion() ); fieldout->Allocate(); VectorType zero; zero.Fill(0); fieldout->FillBuffer(zero); } typedef typename DeformationFieldType::PixelType VectorType; typedef itk::WarpImageFilter WarperType; typedef DeformationFieldType FieldType; enum { ImageDimension = FieldType::ImageDimension }; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef ImageType FloatImageType; typedef itk::ImageFileWriter writertype; typename ImageType::SpacingType oldspace = field->GetSpacing(); typename ImageType::SpacingType newspace = fieldtowarpby->GetSpacing(); typedef typename DeformationFieldType::IndexType IndexType; typedef typename DeformationFieldType::PointType PointType; typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef itk::VectorGaussianInterpolateImageFunction DefaultInterpolatorType2; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); vinterp->SetInputImage(field); // vinterp->SetParameters(NULL,1); VPointType pointIn1; VPointType pointIn2; typename DefaultInterpolatorType::ContinuousIndexType contind; // married to pointIn2 VPointType pointIn3; unsigned int ct=0; // iterate through fieldtowarpby finding the points that it maps to via field. // then take the difference from the original point and put it in the output field. // std::cout << " begin iteration " << std::endl; FieldIterator m_FieldIter( fieldtowarpby, fieldtowarpby->GetLargestPossibleRegion()); for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { IndexType index = m_FieldIter.GetIndex(); bool dosample = true; // if (sub && m_FloatImage->GetPixel(index) < 0.5) dosample=false; if (dosample) { fieldtowarpby->TransformIndexToPhysicalPoint( index, pointIn1 ); VectorType disp=m_FieldIter.Get(); for (int jj=0; jjIsInsideBuffer(pointIn2)) disp2 = vinterp->Evaluate( pointIn2 ); else disp2.Fill(0); for (int jj=0; jjSetPixel(m_FieldIter.GetIndex(),out); ct++; }//endif }//end iteration } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::IntegrateConstantVelocity(DeformationFieldPointer totalField, unsigned int ntimesteps, float timestep) { VectorType zero; zero.Fill(0); DeformationFieldPointer diffmap=DeformationFieldType::New(); diffmap->SetSpacing( totalField->GetSpacing() ); diffmap->SetOrigin( totalField->GetOrigin() ); diffmap->SetDirection( totalField->GetDirection() ); diffmap->SetLargestPossibleRegion(totalField->GetLargestPossibleRegion() ); diffmap->SetRequestedRegion( totalField->GetLargestPossibleRegion() ); diffmap->SetBufferedRegion( totalField->GetLargestPossibleRegion() ); diffmap->Allocate(); diffmap->FillBuffer(zero); for (unsigned int nts=0; ntsComposeDiffs(diffmap,totalField,diffmap, timestep); } return diffmap; } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::ComputeUpdateField(DeformationFieldPointer fixedwarp, DeformationFieldPointer movingwarp , PointSetPointer fpoints, PointSetPointer wpoints, DeformationFieldPointer totalUpdateInvField, bool updateenergy) { ImagePointer mask=NULL; if ( movingwarp && this->m_MaskImage && !this->m_ComputeThickness ) mask= this->WarpMultiTransform( this->m_MaskImage, this->m_MaskImage, NULL, movingwarp, false , this->m_FixedImageAffineTransform ); else if (this->m_MaskImage && !this->m_ComputeThickness ) mask=this->SubsampleImage( this->m_MaskImage, this->m_ScaleFactor , this->m_MaskImage->GetOrigin() , this->m_MaskImage->GetDirection() , NULL); if ( !fixedwarp) {std::cout<< " NO F WARP " << std::endl; fixedwarp=this->m_DeformationField; } //if ( !movingwarp) std::cout<< " NO M WARP " << std::endl; /// std::cout << " get upd field " << std::endl; typename ImageType::SpacingType spacing=fixedwarp->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer updateField=NULL,totalUpdateField=NULL,updateFieldInv=NULL; totalUpdateField=DeformationFieldType::New(); totalUpdateField->SetSpacing( fixedwarp->GetSpacing() ); totalUpdateField->SetOrigin( fixedwarp->GetOrigin() ); totalUpdateField->SetDirection( fixedwarp->GetDirection() ); totalUpdateField->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->Allocate(); totalUpdateField->FillBuffer(zero); // bool hadpointsetmetric=false; RealType sumWeights = 0.0; for( unsigned int n = 0; n < this->m_SimilarityMetrics.size(); n++ ) { sumWeights += this->m_SimilarityMetrics[n]->GetWeightScalar(); } sumWeights=1; for ( unsigned int metricCount = 0; metricCount < this->m_SimilarityMetrics.size(); metricCount++ ) { bool ispointsetmetric=false; /** build an update field */ if ( this->m_SimilarityMetrics.size() == 1 ) { updateField=totalUpdateField; if (totalUpdateInvField) updateFieldInv=totalUpdateInvField; } else { updateField=DeformationFieldType::New(); updateField->SetSpacing( fixedwarp->GetSpacing() ); updateField->SetOrigin( fixedwarp->GetOrigin() ); updateField->SetDirection( fixedwarp->GetDirection() ); updateField->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); updateField->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); updateField->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); updateField->Allocate(); updateField->FillBuffer(zero); if (totalUpdateInvField){ updateFieldInv=DeformationFieldType::New(); updateFieldInv->SetSpacing( fixedwarp->GetSpacing() ); updateFieldInv->SetOrigin( fixedwarp->GetOrigin() ); updateFieldInv->SetDirection( fixedwarp->GetDirection() ); updateFieldInv->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->Allocate(); updateFieldInv->FillBuffer(zero); } } /** get the update */ typedef DeformationFieldType DeformationFieldType; typedef typename FiniteDifferenceFunctionType::NeighborhoodType NeighborhoodIteratorType; typedef ImageRegionIterator UpdateIteratorType; // TimeStepType timeStep; void *globalData; // std::cout << " B " << std::endl; AffineTransformPointer faffinverse=NULL; if (this->m_FixedImageAffineTransform ){ faffinverse=AffineTransformType::New(); this->m_FixedImageAffineTransform->GetInverse(faffinverse); } AffineTransformPointer affinverse=NULL; if (this->m_AffineTransform ){ affinverse=AffineTransformType::New(); this->m_AffineTransform->GetInverse(affinverse); } // for each metric, warp the assoc. Images /** We loop Over This To Do MultiVariate */ /** FIXME really should pass an image list and then warp each one in turn then expand the update field to fit size of total deformation */ ImagePointer wmimage=NULL; if ( fixedwarp) wmimage= this->WarpMultiTransform( this->m_SmoothFixedImages[metricCount],this->m_SmoothMovingImages[metricCount], this->m_AffineTransform, fixedwarp, false , NULL ); else wmimage=this->SubsampleImage( this->m_SmoothMovingImages[metricCount] , this->m_ScaleFactor , this->m_SmoothMovingImages[metricCount]->GetOrigin() , this->m_SmoothMovingImages[metricCount]->GetDirection() , NULL); // std::cout << " C " << std::endl; ImagePointer wfimage=NULL; if ( movingwarp) wfimage= this->WarpMultiTransform( this->m_SmoothFixedImages[metricCount], this->m_SmoothFixedImages[metricCount], NULL, movingwarp, false , this->m_FixedImageAffineTransform ); else wfimage=this->SubsampleImage( this->m_SmoothFixedImages[metricCount] , this->m_ScaleFactor , this->m_SmoothFixedImages[metricCount]->GetOrigin() , this->m_SmoothFixedImages[metricCount]->GetDirection() , NULL); /* if (this->m_TimeVaryingVelocity && ! this->m_MaskImage ) { std::string outname=this->localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("thick.nii.gz"); /// WriteImage(wmimage,outname.c_str()); outname=this->localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("thick2.nii.gz"); WriteImage(wfimage,outname.c_str()); } */ // std::string outname=this->localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("temp.nii.gz"); // WriteImage(wmimage,outname.c_str()); // std::string outname2=this->localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("temp2.nii.gz"); // WriteImage(wfimage,outname2.c_str()); /** MV Loop END -- Would have to collect update fields then add them * together somehow -- Would also have to eliminate the similarity * metric loop within ComputeUpdateField */ // Get the FiniteDifferenceFunction to use in calculations. MetricBaseTypePointer df = this->m_SimilarityMetrics[metricCount]->GetMetric(); df->SetFixedImage(wfimage); df->SetMovingImage(wmimage); if (df->ThisIsAPointSetMetric()) ispointsetmetric=true; if (fpoints && ispointsetmetric ) df->SetFixedPointSet(fpoints); else if (ispointsetmetric ) std::cout << "NO POINTS!! " << std::endl; if (wpoints && ispointsetmetric ) df->SetMovingPointSet(wpoints); else if (ispointsetmetric ) std::cout << "NO POINTS!! " << std::endl; typename ImageType::SizeType radius = df->GetRadius(); df->InitializeIteration(); typename DeformationFieldType::Pointer output = updateField; typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator FaceCalculatorType; typedef typename FaceCalculatorType::FaceListType FaceListType; FaceCalculatorType faceCalculator; FaceListType faceList = faceCalculator(updateField, updateField->GetLargestPossibleRegion(), radius); typename FaceListType::iterator fIt = faceList.begin(); globalData = df->GetGlobalDataPointer(); // Process the non-boundary region. NeighborhoodIteratorType nD(radius, updateField, *fIt); UpdateIteratorType nU(updateField, *fIt); nD.GoToBegin(); nU.GoToBegin(); while( !nD.IsAtEnd() ) { bool oktosample=true; float maskprob=1.0; if (mask) { maskprob=mask->GetPixel( nD.GetIndex() ); if (maskprob > 1.0) maskprob=1.0; if ( maskprob < 0.1) oktosample=false; } if ( oktosample ) { VectorType temp=df->ComputeUpdate(nD, globalData)*maskprob; nU.Value() += temp; if (totalUpdateInvField) { typename ImageType::IndexType index=nD.GetIndex(); temp = df->ComputeUpdateInv(nD, globalData)*maskprob+updateFieldInv->GetPixel(index); updateFieldInv->SetPixel(index,temp); }// else nU.Value() -= df->ComputeUpdateInv(nD, globalData)*maskprob; ++nD; ++nU; } else { ++nD; ++nU; } } // begin restriction of deformation field bool restrict=false; for (unsigned int jj=0; jjm_RestrictDeformation.size(); jj++ ) { float temp=this->m_RestrictDeformation[jj]; if ( fabs( temp - 1 ) > 1.e-5 ) restrict=true; } if (restrict && this->m_RestrictDeformation.size() == ImageDimension ) { nU.GoToBegin(); while( !nU.IsAtEnd() ) { for (unsigned int jj=0; jjm_RestrictDeformation.size(); jj++ ) { typename ImageType::IndexType index=nU.GetIndex(); VectorType temp = updateField->GetPixel(index); temp[jj]*=this->m_RestrictDeformation[jj]; updateField->SetPixel(index,temp); if (updateFieldInv ) { temp = updateFieldInv->GetPixel(index); temp[jj]*=this->m_RestrictDeformation[jj]; updateFieldInv->SetPixel(index,temp); } } ++nU; } } // end restrict deformation field if (updateenergy){ this->m_LastEnergy[metricCount]=this->m_Energy[metricCount]; this->m_Energy[metricCount]=df->GetEnergy();// *this->m_SimilarityMetrics[metricCount]->GetWeightScalar()/sumWeights; } // smooth the fields //if (!ispointsetmetric || ImageDimension == 2 ){ this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); ///} /* else // use another strategy -- exact lm? / something like Laplacian { float tmag=0; for (unsigned int ff=0; ff<5; ff++) { tmag=0; this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); nD.GoToBegin(); nU.GoToBegin(); while( !nD.IsAtEnd() ) { typename ImageType::IndexType index=nD.GetIndex(); bool oktosample=true; float maskprob=1.0; if (mask) { maskprob=mask->GetPixel( nD.GetIndex() ); if (maskprob > 1.0) maskprob=1.0; if ( maskprob < 0.1) oktosample=false; } VectorType F1; F1.Fill(0); VectorType F2; F2.Fill(0); if ( oktosample ) { F1 = df->ComputeUpdate(nD, globalData)*maskprob; if (totalUpdateInvField) { F2 = df->ComputeUpdateInv(nD, globalData)*maskprob; } ++nD; ++nU; } else { ++nD; ++nU; } // compute mags of F1 and F2 -- if large enough, reset them float f1mag=0,f2mag=0,umag=0; for (unsigned int dim=0; dimGetPixel(index)[dim]/spacing[dim]*updateField->GetPixel(index)[dim]/spacing[dim]; } f1mag=sqrt(f1mag); f2mag=sqrt(f2mag); umag=sqrt(umag); if ( f1mag > 0.05 ) updateField->SetPixel(index,F1); if ( f2mag > 0.05 ) updateFieldInv->SetPixel(index,F2); tmag+=umag; } // std::cout << " total mag " << tmag << std::endl; } //smooth the total field this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); } */ //normalize update field then add to total field typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(totalUpdateField,totalUpdateField->GetLargestPossibleRegion() ); float mag=0.0; float max=0.0; unsigned long ct=0; float total=0; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateField->GetPixel(index); mag=0; for (unsigned int jj=0; jj 0. ) std::cout << " mag " << mag << " max " << max << " vec " << vec << std::endl; if (mag > max) max=mag; ct++; total+=mag; // std::cout << " mag " << mag << std::endl; } if (this->m_Debug) std::cout << "PRE MAX " << max << std::endl; float max2=0; if (max <= 0) max=1; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateField->GetPixel(index); vec=vec/max; mag=0; for (unsigned int jj=0; jj max2 ) max2=mag; // if (mag > 0.95) std::cout << " mag " << mag << " max " << max << " vec " << vec << " ind " << index << std::endl; /** FIXME need weights between metrics */ RealType normalizedWeight = this->m_SimilarityMetrics[metricCount]->GetWeightScalar() / sumWeights; // RealType weight = this->m_SimilarityMetrics[metricCount]->GetWeightImage()->GetPixel( diter.GetIndex() ); if (ispointsetmetric ) { VectorType intensityupdate=dIter.Get(); VectorType lmupdate=vec; float lmag=0; for (unsigned int li=0; li 1) modi=0; else modi=1.0-lmag; float iwt=1*modi; float lmwt=normalizedWeight; VectorType totalv=intensityupdate*iwt+lmupdate*lmwt; dIter.Set(totalv); } else dIter.Set(dIter.Get()+vec*normalizedWeight); } if (totalUpdateInvField){ Iterator dIter(totalUpdateInvField,totalUpdateInvField->GetLargestPossibleRegion() ); float mag=0.0; float max=0.0; unsigned long ct=0; float total=0; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateFieldInv->GetPixel(index); mag=0; for (unsigned int jj=0; jj 0. ) std::cout << " mag " << mag << " max " << max << " vec " << vec << std::endl; if (mag > max) max=mag; ct++; total+=mag; // std::cout << " mag " << mag << std::endl; } if (this->m_Debug) std::cout << "PRE MAX " << max << std::endl; float max2=0; if (max <= 0) max=1; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateFieldInv->GetPixel(index); vec=vec/max; mag=0; for (unsigned int jj=0; jj max2 ) max2=mag; // if (mag > 0.95) std::cout << " mag " << mag << " max " << max << " vec " << vec << " ind " << index << std::endl; /** FIXME need weights between metrics */ RealType normalizedWeight = this->m_SimilarityMetrics[metricCount]->GetWeightScalar() / sumWeights; // RealType weight = this->m_SimilarityMetrics[metricCount]->GetWeightImage()->GetPixel( diter.GetIndex() ); if (ispointsetmetric ) { VectorType intensityupdate=dIter.Get(); VectorType lmupdate=vec; float lmag=0; for (unsigned int li=0; li 1) modi=0; else modi=1.0-lmag; float iwt=1*modi; float lmwt=normalizedWeight; VectorType totalv=intensityupdate*iwt+lmupdate*lmwt; dIter.Set(totalv); } else dIter.Set(dIter.Get()+vec*normalizedWeight); } } if (this->m_Debug) std::cout << "PO MAX " << max2 << " sz" << totalUpdateField->GetLargestPossibleRegion().GetSize() << std::endl; } // this->SmoothDeformationField( totalUpdateField,true); // if (totalUpdateInvField) this->SmoothDeformationField( totalUpdateInvField,true); return totalUpdateField; } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::ComputeUpdateFieldAlternatingMin(DeformationFieldPointer fixedwarp, DeformationFieldPointer movingwarp , PointSetPointer fpoints, PointSetPointer wpoints, DeformationFieldPointer totalUpdateInvField, bool updateenergy) { ImagePointer mask=NULL; if ( movingwarp && this->m_MaskImage) mask= this->WarpMultiTransform( this->m_MaskImage, this->m_MaskImage, NULL, movingwarp, false , this->m_FixedImageAffineTransform ); else if (this->m_MaskImage) mask=this->SubsampleImage( this->m_MaskImage, this->m_ScaleFactor , this->m_MaskImage->GetOrigin() , this->m_MaskImage->GetDirection() , NULL); if ( !fixedwarp) {std::cout<< " NO F WARP " << std::endl; fixedwarp=this->m_DeformationField; } //if ( !movingwarp) std::cout<< " NO M WARP " << std::endl; /// std::cout << " get upd field " << std::endl; typename ImageType::SpacingType spacing=fixedwarp->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer updateField=NULL,totalUpdateField=NULL,updateFieldInv=NULL; totalUpdateField=DeformationFieldType::New(); totalUpdateField->SetSpacing( fixedwarp->GetSpacing() ); totalUpdateField->SetOrigin( fixedwarp->GetOrigin() ); totalUpdateField->SetDirection( fixedwarp->GetDirection() ); totalUpdateField->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); totalUpdateField->Allocate(); totalUpdateField->FillBuffer(zero); //bool hadpointsetmetric=false; RealType sumWeights = 0.0; for( unsigned int n = 0; n < this->m_SimilarityMetrics.size(); n++ ) { sumWeights += this->m_SimilarityMetrics[n]->GetWeightScalar(); } sumWeights=1; // for ( unsigned int metricCount = 0; metricCount < this->m_SimilarityMetrics.size(); metricCount++ ) //{ //MetricBaseTypePointer df = this->m_SimilarityMetrics[metricCount]->GetMetric(); // if (df->ThisIsAPointSetMetric()) hadpointsetmetric=true; //} //for ( unsigned int metricCount = 0; metricCount < this->m_SimilarityMetrics.size(); metricCount++ ) unsigned int metricCount= this->m_CurrentIteration % this->m_SimilarityMetrics.size(); { bool ispointsetmetric=false; /** build an update field */ if ( true )// this->m_SimilarityMetrics.size() == 1 ) { updateField=totalUpdateField; if (totalUpdateInvField) updateFieldInv=totalUpdateInvField; } else { updateField=DeformationFieldType::New(); updateField->SetSpacing( fixedwarp->GetSpacing() ); updateField->SetOrigin( fixedwarp->GetOrigin() ); updateField->SetDirection( fixedwarp->GetDirection() ); updateField->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); updateField->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); updateField->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); updateField->Allocate(); updateField->FillBuffer(zero); if (totalUpdateInvField){ updateFieldInv=DeformationFieldType::New(); updateFieldInv->SetSpacing( fixedwarp->GetSpacing() ); updateFieldInv->SetOrigin( fixedwarp->GetOrigin() ); updateFieldInv->SetDirection( fixedwarp->GetDirection() ); updateFieldInv->SetLargestPossibleRegion(fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->SetRequestedRegion( fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->SetBufferedRegion( fixedwarp->GetLargestPossibleRegion() ); updateFieldInv->Allocate(); updateFieldInv->FillBuffer(zero); } } /** get the update */ typedef DeformationFieldType DeformationFieldType; typedef typename FiniteDifferenceFunctionType::NeighborhoodType NeighborhoodIteratorType; typedef ImageRegionIterator UpdateIteratorType; // TimeStepType timeStep; void *globalData; // std::cout << " B " << std::endl; // for each metric, warp the assoc. Images /** We loop Over This To Do MultiVariate */ /** FIXME really should pass an image list and then warp each one in turn then expand the update field to fit size of total deformation */ ImagePointer wmimage=NULL; if ( fixedwarp) wmimage= this->WarpMultiTransform( this->m_SmoothFixedImages[metricCount],this->m_SmoothMovingImages[metricCount], this->m_AffineTransform, fixedwarp, false , this->m_FixedImageAffineTransform ); else wmimage=this->SubsampleImage( this->m_SmoothMovingImages[metricCount] , this->m_ScaleFactor , this->m_SmoothMovingImages[metricCount]->GetOrigin() , this->m_SmoothMovingImages[metricCount]->GetDirection() , NULL); // std::cout << " C " << std::endl; ImagePointer wfimage=NULL; if ( movingwarp) wfimage= this->WarpMultiTransform( this->m_SmoothFixedImages[metricCount], this->m_SmoothFixedImages[metricCount], NULL, movingwarp, false , this->m_FixedImageAffineTransform ); else wfimage=this->SubsampleImage( this->m_SmoothFixedImages[metricCount] , this->m_ScaleFactor , this->m_SmoothFixedImages[metricCount]->GetOrigin() , this->m_SmoothFixedImages[metricCount]->GetDirection() , NULL); // std::cout << " D " << std::endl; /** MV Loop END -- Would have to collect update fields then add them * together somehow -- Would also have to eliminate the similarity * metric loop within ComputeUpdateField */ // Get the FiniteDifferenceFunction to use in calculations. MetricBaseTypePointer df = this->m_SimilarityMetrics[metricCount]->GetMetric(); df->SetFixedImage(wfimage); df->SetMovingImage(wmimage); if (df->ThisIsAPointSetMetric()) ispointsetmetric=true; if (fpoints && ispointsetmetric ) df->SetFixedPointSet(fpoints); else if (ispointsetmetric ) std::cout << "NO POINTS!! " << std::endl; if (wpoints && ispointsetmetric ) df->SetMovingPointSet(wpoints); else if (ispointsetmetric ) std::cout << "NO POINTS!! " << std::endl; typename ImageType::SizeType radius = df->GetRadius(); df->InitializeIteration(); typename DeformationFieldType::Pointer output = updateField; typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator FaceCalculatorType; typedef typename FaceCalculatorType::FaceListType FaceListType; FaceCalculatorType faceCalculator; FaceListType faceList = faceCalculator(updateField, updateField->GetLargestPossibleRegion(), radius); typename FaceListType::iterator fIt = faceList.begin(); globalData = df->GetGlobalDataPointer(); // Process the non-boundary region. NeighborhoodIteratorType nD(radius, updateField, *fIt); UpdateIteratorType nU(updateField, *fIt); nD.GoToBegin(); nU.GoToBegin(); while( !nD.IsAtEnd() ) { bool oktosample=true; float maskprob=1.0; if (mask) { maskprob=mask->GetPixel( nD.GetIndex() ); if (maskprob > 1.0) maskprob=1.0; if ( maskprob < 0.1) oktosample=false; } if ( oktosample ) { nU.Value() += df->ComputeUpdate(nD, globalData)*maskprob; if (totalUpdateInvField) { typename ImageType::IndexType index=nD.GetIndex(); VectorType temp = df->ComputeUpdateInv(nD, globalData)*maskprob; updateFieldInv->SetPixel(index,temp); } //else nU.Value() -= df->ComputeUpdateInv(nD, globalData)*maskprob; ++nD; ++nU; } else { ++nD; ++nU; } } if (updateenergy){ this->m_LastEnergy[metricCount]=this->m_Energy[metricCount]; this->m_Energy[metricCount]=df->GetEnergy();//*this->m_SimilarityMetrics[metricCount]->GetWeightScalar()/sumWeights; } // smooth the fields // if (!ispointsetmetric || ImageDimension == 2 ){ this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); // } /* else // use another strategy -- exact lm? / something like Laplacian { float tmag=0; for (unsigned int ff=0; ff<5; ff++) { tmag=0; this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); nD.GoToBegin(); nU.GoToBegin(); while( !nD.IsAtEnd() ) { typename ImageType::IndexType index=nD.GetIndex(); bool oktosample=true; float maskprob=1.0; if (mask) { maskprob=mask->GetPixel( nD.GetIndex() ); if (maskprob > 1.0) maskprob=1.0; if ( maskprob < 0.1) oktosample=false; } VectorType F1; F1.Fill(0); VectorType F2; F2.Fill(0); if ( oktosample ) { F1 = df->ComputeUpdate(nD, globalData)*maskprob; if (totalUpdateInvField) { F2 = df->ComputeUpdateInv(nD, globalData)*maskprob; } ++nD; ++nU; } else { ++nD; ++nU; } // compute mags of F1 and F2 -- if large enough, reset them float f1mag=0,f2mag=0,umag=0; for (unsigned int dim=0; dimGetPixel(index)[dim]/spacing[dim]*updateField->GetPixel(index)[dim]/spacing[dim]; } f1mag=sqrt(f1mag); f2mag=sqrt(f2mag); umag=sqrt(umag); if ( f1mag > 0.05 ) updateField->SetPixel(index,F1); if ( f2mag > 0.05 ) updateFieldInv->SetPixel(index,F2); tmag+=umag; } // std::cout << " total mag " << tmag << std::endl; } //smooth the total field this->SmoothDeformationField(updateField,true); if (updateFieldInv) this->SmoothDeformationField(updateFieldInv,true); } */ //normalize update field then add to total field typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(totalUpdateField,totalUpdateField->GetLargestPossibleRegion() ); float mag=0.0; float max=0.0; unsigned long ct=0; float total=0; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateField->GetPixel(index); mag=0; for (unsigned int jj=0; jj 0. ) std::cout << " mag " << mag << " max " << max << " vec " << vec << std::endl; if (mag > max) max=mag; ct++; total+=mag; // std::cout << " mag " << mag << std::endl; } if (this->m_Debug) std::cout << "PRE MAX " << max << std::endl; float max2=0; if (max <= 0) max=1; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateField->GetPixel(index); vec=vec/max; mag=0; for (unsigned int jj=0; jj max2 ) max2=mag; // if (mag > 0.95) std::cout << " mag " << mag << " max " << max << " vec " << vec << " ind " << index << std::endl; /** FIXME need weights between metrics */ RealType normalizedWeight = this->m_SimilarityMetrics[metricCount]->GetWeightScalar() / sumWeights; /* RealType weight = this->m_SimilarityMetrics[metricCount]->GetWeightImage()->GetPixel( diter.GetIndex() ); if (ispointsetmetric ) { VectorType intensityupdate=dIter.Get(); VectorType lmupdate=vec; float lmag=0; for (unsigned int li=0; li 1) modi=0; else modi=1.0-lmag; float iwt=1*modi; float lmwt=normalizedWeight; VectorType totalv=intensityupdate*iwt+lmupdate*lmwt; dIter.Set(totalv); } else */ dIter.Set(dIter.Get()+vec*normalizedWeight); } if (totalUpdateInvField){ Iterator dIter(totalUpdateInvField,totalUpdateInvField->GetLargestPossibleRegion() ); float mag=0.0; float max=0.0; unsigned long ct=0; float total=0; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateFieldInv->GetPixel(index); mag=0; for (unsigned int jj=0; jj 0. ) std::cout << " mag " << mag << " max " << max << " vec " << vec << std::endl; if (mag > max) max=mag; ct++; total+=mag; // std::cout << " mag " << mag << std::endl; } if (this->m_Debug) std::cout << "PRE MAX " << max << std::endl; float max2=0; if (max <= 0) max=1; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateFieldInv->GetPixel(index); vec=vec/max; mag=0; for (unsigned int jj=0; jj max2 ) max2=mag; // if (mag > 0.95) std::cout << " mag " << mag << " max " << max << " vec " << vec << " ind " << index << std::endl; /** FIXME need weights between metrics */ RealType normalizedWeight = this->m_SimilarityMetrics[metricCount]->GetWeightScalar() / sumWeights; // RealType weight = this->m_SimilarityMetrics[metricCount]->GetWeightImage()->GetPixel( diter.GetIndex() ); /* if (ispointsetmetric ) { VectorType intensityupdate=dIter.Get(); VectorType lmupdate=vec; float lmag=0; for (unsigned int li=0; li 1) modi=0; else modi=1.0-lmag; float iwt=1*modi; float lmwt=normalizedWeight; VectorType totalv=intensityupdate*iwt+lmupdate*lmwt; dIter.Set(totalv); } else */ dIter.Set(dIter.Get()+vec*normalizedWeight); } } if (this->m_Debug) std::cout << "PO MAX " << max2 << " sz" << totalUpdateField->GetLargestPossibleRegion().GetSize() << std::endl; } // this->SmoothDeformationField( totalUpdateField,true); // if (totalUpdateInvField) this->SmoothDeformationField( totalUpdateInvField,true); return totalUpdateField; } template void ANTSImageRegistrationOptimizer ::DiffeomorphicExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { // this function computes a velocity field that --- when composed with itself --- optimizes the registration solution. // it's very different than the Exp approach used by DiffeomorphicDemons which just composes small deformation over time. // DiffDem cannot reconstruct the path between images without recomputing the registration. // DiffDem also cannot create an inverse mapping. /** FIXME really should pass an image list and then warp each one in turn then expand the update field to fit size of total deformation */ typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField=NULL; DeformationFieldPointer totalField=this->m_DeformationField; /** generate phi and phi gradient */ DeformationFieldPointer diffmap=DeformationFieldType::New(); diffmap->SetSpacing( totalField->GetSpacing() ); diffmap->SetOrigin( totalField->GetOrigin() ); diffmap->SetDirection( totalField->GetDirection() ); diffmap->SetLargestPossibleRegion(totalField->GetLargestPossibleRegion() ); diffmap->SetRequestedRegion( totalField->GetLargestPossibleRegion() ); diffmap->SetBufferedRegion( totalField->GetLargestPossibleRegion() ); diffmap->Allocate(); DeformationFieldPointer invdiffmap=DeformationFieldType::New(); invdiffmap->SetSpacing( totalField->GetSpacing() ); invdiffmap->SetOrigin( totalField->GetOrigin() ); invdiffmap->SetDirection( totalField->GetDirection() ); invdiffmap->SetLargestPossibleRegion(totalField->GetLargestPossibleRegion() ); invdiffmap->SetRequestedRegion( totalField->GetLargestPossibleRegion() ); invdiffmap->SetBufferedRegion( totalField->GetLargestPossibleRegion() ); invdiffmap->Allocate(); // float timestep=1.0/(float)this->m_NTimeSteps; // for (unsigned int nts=0; nts<=this->m_NTimeSteps; nts+=this->m_NTimeSteps) unsigned int nts=(unsigned int)this->m_NTimeSteps; { diffmap->FillBuffer(zero); invdiffmap->FillBuffer(zero); DeformationFieldPointer diffmap = this->IntegrateConstantVelocity(totalField, nts, 1); //DeformationFieldPointer invdiffmap = this->IntegrateConstantVelocity(totalField,(unsigned int)( this->m_NTimeSteps)-nts, (-1.)); ImagePointer wfimage,wmimage; PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; if ( mpoints ) {// need full inverse map DeformationFieldPointer tinvdiffmap = this->IntegrateConstantVelocity(totalField, nts, (-1.)); wmpoints = this->WarpMultiTransform(fixedImage,movingImage, mpoints , aff , tinvdiffmap , true , this->m_FixedImageAffineTransform ); } DeformationFieldPointer updateField=this->ComputeUpdateField( diffmap, NULL, fpoints, wmpoints); // updateField = this->IntegrateConstantVelocity( updateField, nts, timestep); float maxl= this->MeasureDeformation(updateField); if (maxl <= 0) maxl=1; typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(updateField,updateField->GetLargestPossibleRegion() ); for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) dIter.Set( dIter.Get()*this->m_GradstepAltered/maxl); this->ComposeDiffs(updateField,totalField,totalField,1); /* float maxl= this->MeasureDeformation(updateField); if (maxl <= 0) maxl=1; typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(updateField,updateField->GetLargestPossibleRegion() ); for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { dIter.Set( dIter.Get()*this->m_GradstepAltered/this->m_NTimeSteps ); totalField->SetPixel(dIter.GetIndex(), dIter.Get() + totalField->GetPixel(dIter.GetIndex()) ); } */ } this->SmoothDeformationField(totalField,false); return; } template void ANTSImageRegistrationOptimizer ::GreedyExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { // similar approach to christensen 96 and diffeomorphic demons typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField=NULL; // we compose the update with this field. DeformationFieldPointer totalField=this->m_DeformationField; float timestep=1.0/(float)this->m_NTimeSteps; unsigned int nts=(unsigned int)this->m_NTimeSteps; ImagePointer wfimage,wmimage; PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; DeformationFieldPointer updateField=this->ComputeUpdateField( totalField, NULL, fpoints, wmpoints); updateField = this->IntegrateConstantVelocity( updateField, nts, timestep); float maxl= this->MeasureDeformation(updateField); if (maxl <= 0) maxl=1; typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(updateField,updateField->GetLargestPossibleRegion() ); for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) dIter.Set( dIter.Get()*this->m_GradstepAltered/maxl ); this->ComposeDiffs(updateField,totalField,totalField,1); // maxl= this->MeasureDeformation(totalField); // std::cout << " maxl " << maxl << " gsa " << this->m_GradstepAltered << std::endl; // totalField=this->CopyDeformationField(totalUpdateField); this->SmoothDeformationField(totalField,false); return; } //added by songgang template typename ANTSImageRegistrationOptimizer::AffineTransformPointer ANTSImageRegistrationOptimizer::AffineOptimization(OptAffineType &affine_opt) { // typedef itk::Image TempImageType; // typename TempImageType::Pointer fixedImage = TempImageType::New(); // typename TempImageType::Pointer movingImage = TempImageType::New(); ImagePointer fixedImage; ImagePointer movingImage; /** FIXME -- here we assume the metrics all have the same image */ fixedImage = this->m_SimilarityMetrics[0]->GetFixedImage(); movingImage = this->m_SimilarityMetrics[0]->GetMovingImage(); //TODO: get mask image pointer / type for mask image if (this->m_MaskImage) affine_opt.mask_fixed = this->m_MaskImage; // AffineTransformPointer &transform_init = affine_opt.transform_initial; // ImagePointer &maskImage = affine_opt.mask_fixed; AffineTransformPointer transform = AffineTransformType::New(); // std::cout << "In AffineOptimization: transform_init.IsNotNull()=" << transform_init.IsNotNull() << std::endl; // compute_single_affine_transform(fixedImage, movingImage, maskImage, transform, transform_init); // OptAffine opt; ComputeSingleAffineTransform(fixedImage, movingImage, affine_opt, transform); return transform; } template void ANTSImageRegistrationOptimizer ::SyNRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField,totalUpdateInvField=DeformationFieldType::New(); totalUpdateInvField->SetSpacing( this->m_DeformationField->GetSpacing() ); totalUpdateInvField->SetOrigin( this->m_DeformationField->GetOrigin() ); totalUpdateInvField->SetDirection( this->m_DeformationField->GetDirection() ); totalUpdateInvField->SetLargestPossibleRegion(this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->Allocate(); totalUpdateInvField->FillBuffer(zero); if (!this->m_SyNF) { std::cout <<" Allocating " << std::endl; this->m_SyNF=this->CopyDeformationField(totalUpdateInvField); this->m_SyNFInv=this->CopyDeformationField(this->m_SyNF); this->m_SyNM=this->CopyDeformationField(totalUpdateInvField); this->m_SyNMInv=this->CopyDeformationField(this->m_SyNF); //this->m_Debug=true; if (this->m_Debug) std::cout << " SyNFInv" << this->m_SyNFInv->GetLargestPossibleRegion().GetSize() << std::endl; if (this->m_Debug) std::cout << " t updIf " << totalUpdateInvField->GetLargestPossibleRegion().GetSize() << std::endl; if (this->m_Debug) std::cout << " synf " << this->m_SyNF->GetLargestPossibleRegion().GetSize() << std::endl; //this->m_Debug=false; std::cout <<" Allocating Done " << std::endl; } if (!this->m_SyNF) { std::cout<<" F'D UP " << std::endl;} PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; AffineTransformPointer affinverse=NULL; if (aff){ affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } if ( mpoints ) { wmpoints = this->WarpMultiTransform(fixedImage,movingImage, mpoints , aff , this->m_SyNM , true , this->m_FixedImageAffineTransform ); } if ( fpoints ) {// need full inverse map wfpoints = this->WarpMultiTransform(fixedImage,fixedImage, fpoints , NULL , this->m_SyNF , false , this->m_FixedImageAffineTransform ); } //syncom totalUpdateField=this->ComputeUpdateField(this->m_SyNMInv, this->m_SyNFInv, wfpoints, wmpoints,totalUpdateInvField); this->ComposeDiffs(this->m_SyNF,totalUpdateField,this->m_SyNF,this->m_GradstepAltered); this->ComposeDiffs(this->m_SyNM,totalUpdateInvField,this->m_SyNM,this->m_GradstepAltered); if ( this->m_TotalSmoothingparam > 0 || this->m_TotalSmoothingMeshSize[0] > 0 ) { this->SmoothDeformationField( this->m_SyNF,false); this->SmoothDeformationField( this->m_SyNM,false); } this->InvertField(this->m_SyNF,this->m_SyNFInv); this->InvertField(this->m_SyNM,this->m_SyNMInv); this->InvertField(this->m_SyNFInv,this->m_SyNF); this->InvertField(this->m_SyNMInv,this->m_SyNM); // std::cout << " F " << this->MeasureDeformation(this->m_SyNF) << " F1 " << this->MeasureDeformation(this->m_SyNFInv) << std::endl; // std::cout << " M " << this->MeasureDeformation(this->m_SyNM) << " M1 " << this->MeasureDeformation(this->m_SyNMInv) << std::endl; return; } template void ANTSImageRegistrationOptimizer ::SyNExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { std::cout << " SyNEX" ; typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField,totalUpdateInvField=DeformationFieldType::New(); totalUpdateInvField->SetSpacing( this->m_DeformationField->GetSpacing() ); totalUpdateInvField->SetOrigin( this->m_DeformationField->GetOrigin() ); totalUpdateInvField->SetDirection( this->m_DeformationField->GetDirection() ); totalUpdateInvField->SetLargestPossibleRegion(this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->Allocate(); totalUpdateInvField->FillBuffer(zero); if (!this->m_SyNF) { std::cout <<" Allocating " << std::endl; this->m_SyNF=this->CopyDeformationField(totalUpdateInvField); this->m_SyNFInv=this->CopyDeformationField(this->m_SyNF); this->m_SyNM=this->CopyDeformationField(totalUpdateInvField); this->m_SyNMInv=this->CopyDeformationField(this->m_SyNF); std::cout <<" Allocating Done " << std::endl; } if (!this->m_SyNF) { std::cout<<" F'D UP " << std::endl;} ImagePointer wfimage,wmimage; PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; AffineTransformPointer affinverse=NULL; //here, SyNF holds the moving velocity field, SyNM holds the fixed //velocity field and we integrate both to generate the inv/fwd fields float timestep=1.0/(float)this->m_NTimeSteps; unsigned int nts=this->m_NTimeSteps; DeformationFieldPointer fdiffmap = this->IntegrateConstantVelocity(this->m_SyNF, nts, 1); this->m_SyNFInv = this->IntegrateConstantVelocity(this->m_SyNF, nts, (-1.)); DeformationFieldPointer mdiffmap = this->IntegrateConstantVelocity(this->m_SyNM, nts, 1); this->m_SyNMInv = this->IntegrateConstantVelocity(this->m_SyNM, nts, (-1.)); if (aff){ affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } if ( mpoints ) { wmpoints = this->WarpMultiTransform(fixedImage,movingImage, mpoints , aff , this->m_SyNM , true , this->m_FixedImageAffineTransform ); } if ( fpoints ) {// need full inverse map wfpoints = this->WarpMultiTransform(fixedImage,fixedImage, fpoints , NULL , this->m_SyNF , false , this->m_FixedImageAffineTransform ); } totalUpdateField=this->ComputeUpdateField( this->m_SyNMInv , this->m_SyNFInv , wfpoints, wmpoints,totalUpdateInvField); //then addd typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(this->m_SyNF,this->m_SyNF->GetLargestPossibleRegion() ); float max=0,max2=0; for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vecf=totalUpdateField->GetPixel(index); VectorType vecm=totalUpdateInvField->GetPixel(index); dIter.Set(dIter.Get()+vecf*this->m_GradstepAltered); this->m_SyNM->SetPixel( index, this->m_SyNM->GetPixel( index )+vecm*this->m_GradstepAltered); // min field difference => geodesic => DV/dt=0 float geowt1=0.99; float geowt2=1.0-geowt1; VectorType synmv=this->m_SyNM->GetPixel( index ); VectorType synfv =this->m_SyNF->GetPixel( index ); this->m_SyNM->SetPixel( index, synmv*geowt1-synfv*geowt2); this->m_SyNF->SetPixel( index, synfv*geowt1-synmv*geowt2); } if (this->m_TotalSmoothingparam > 0 || this->m_TotalSmoothingMeshSize[0] > 0 ) { this->SmoothDeformationField( this->m_SyNF,false); this->SmoothDeformationField( this->m_SyNM,false); } // std::cout << " TUF " << this->MeasureDeformation(this->m_SyNF) << " TUM " << this->MeasureDeformation(this->m_SyNM) << std::endl; return; } template void ANTSImageRegistrationOptimizer ::UpdateTimeVaryingVelocityFieldWithSyNFandSyNM( ) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef TimeVaryingVelocityFieldType tvt; bool generatetvfield=false; if (!this->m_TimeVaryingVelocity) generatetvfield=true; else { for (int jj=0; jjm_CurrentDomainSize[jj] != this->m_TimeVaryingVelocity->GetLargestPossibleRegion().GetSize()[jj]) generatetvfield=true; } VectorType zero; zero.Fill(0); if (generatetvfield) { typename tvt::RegionType gregion; typename tvt::SizeType gsize; typename tvt::SpacingType gspace; typename tvt::PointType gorigin; gorigin.Fill(0); for (unsigned int dim=0; dimm_CurrentDomainSize[dim]; gspace[dim]=this->m_CurrentDomainSpacing[dim]; gorigin[dim]=this->m_CurrentDomainOrigin[dim]; } gsize[TDimension]=2;//this->m_NTimeSteps; gspace[TDimension]=1; gregion.SetSize(gsize); /** The TV Field has the direction of the sub-image -- the time domain has identity transform */ typename tvt::DirectionType iddir; iddir.Fill(0); iddir[ImageDimension][ImageDimension]=1; for (unsigned int i=0; iGetDeformationField()->GetDirection()[i][j]; this->m_TimeVaryingVelocity=tvt::New(); this->m_TimeVaryingVelocity->SetSpacing( gspace ); this->m_TimeVaryingVelocity->SetOrigin( gorigin ); this->m_TimeVaryingVelocity->SetDirection( iddir ); this->m_TimeVaryingVelocity->SetLargestPossibleRegion(gregion); this->m_TimeVaryingVelocity->SetRequestedRegion( gregion); this->m_TimeVaryingVelocity->SetBufferedRegion( gregion ); this->m_TimeVaryingVelocity->Allocate(); this->m_TimeVaryingVelocity->FillBuffer(zero); } typedef tvt TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; TVFieldIterator m_FieldIter( this->m_TimeVaryingVelocity,this->m_TimeVaryingVelocity->GetLargestPossibleRegion()); for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { typename tvt::IndexType velind=m_FieldIter.GetIndex(); IndexType ind; for (unsigned int j=0; jm_SyNF->GetPixel(ind); m_FieldIter.Set(vel); } else if (velind[ImageDimension]==1) { VectorType vel=this->m_SyNM->GetPixel(ind)*(-1.0); m_FieldIter.Set(vel); } } // std::cout <<" ALlocated TV F "<< std::endl; } template void ANTSImageRegistrationOptimizer ::CopyOrAddToVelocityField( TimeVaryingVelocityFieldPointer velocity, DeformationFieldPointer update1, DeformationFieldPointer update2 , float timept) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef TimeVaryingVelocityFieldType tvt; VectorType zero; typedef tvt TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; int tpupdate=(unsigned int) (((float)this->m_NTimeSteps-1.0)*timept+0.5); //std::cout <<" add to " << tpupdate << std::endl; float tmag=0; TVFieldIterator m_FieldIter(velocity, velocity->GetLargestPossibleRegion()); for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { typename tvt::IndexType velind=m_FieldIter.GetIndex(); IndexType ind; for (unsigned int j=0; jGetPixel(ind); float mag=0; for (unsigned int jj=0; jjGetPixel(ind)*(-1); m_FieldIter.Set(vel+m_FieldIter.Get() ); } } // std::cout << " tmag " << tmag << std::endl; } template void ANTSImageRegistrationOptimizer ::SyNTVRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField,totalUpdateInvField=DeformationFieldType::New(); totalUpdateInvField->SetSpacing( this->m_DeformationField->GetSpacing() ); totalUpdateInvField->SetOrigin( this->m_DeformationField->GetOrigin() ); totalUpdateInvField->SetDirection( this->m_DeformationField->GetDirection() ); totalUpdateInvField->SetLargestPossibleRegion(this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->Allocate(); totalUpdateInvField->FillBuffer(zero); if (!this->m_SyNF) { std::cout <<" Allocating " << std::endl; this->m_SyNF=this->CopyDeformationField(totalUpdateInvField); this->m_SyNFInv=this->CopyDeformationField(this->m_SyNF); this->m_SyNM=this->CopyDeformationField(totalUpdateInvField); this->m_SyNMInv=this->CopyDeformationField(this->m_SyNF); std::cout <<" Allocating Done " << std::endl; } if (!this->m_SyNF) { std::cout<<" F'D UP " << std::endl;} ImagePointer wfimage,wmimage; PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; AffineTransformPointer affinverse=NULL; typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(this->m_SyNF,this->m_SyNF->GetLargestPossibleRegion() ); //here, SyNF holds the moving velocity field, SyNM holds the fixed //velocity field and we integrate both to generate the inv/fwd fields typename JacobianFunctionType::Pointer jfunction = JacobianFunctionType::New(); float lot=0,hit=0.5; float lot2=1.0; this->UpdateTimeVaryingVelocityFieldWithSyNFandSyNM( );// sets tvt to SyNF and SyNM -- works only for 2 time points! this->m_SyNFInv = this->IntegrateVelocity(hit,lot); this->m_SyNMInv = this->IntegrateVelocity(hit,lot2); if (aff){ affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } if ( mpoints ) { /**FIXME -- NEED INTEGRATION FOR POINTS ONLY -- warp landmarks for * tv-field */ // std::cout <<" aff " << std::endl; /** NOte, totalUpdateInvField is filled with zeroes! -- we only want affine mapping */ wmpoints = this->WarpMultiTransform(fixedImage,movingImage, mpoints , aff , totalUpdateInvField , true, NULL ); DeformationFieldPointer mdiffmap = this->IntegrateLandmarkSetVelocity(lot2,hit,wmpoints,movingImage); wmpoints = this->WarpMultiTransform(fixedImage,movingImage, wmpoints , NULL , mdiffmap , true , NULL ); } if ( fpoints ) {// need full inverse map wfpoints = this->WarpMultiTransform(fixedImage,movingImage, fpoints , NULL , totalUpdateInvField , true, this->m_FixedImageAffineTransform ); DeformationFieldPointer fdiffmap = this->IntegrateLandmarkSetVelocity(lot,hit,wfpoints,fixedImage); wfpoints = this->WarpMultiTransform(fixedImage,fixedImage, wfpoints , NULL , fdiffmap , false , NULL ); } totalUpdateField=this->ComputeUpdateField( this->m_SyNMInv, this->m_SyNFInv , wfpoints, wmpoints,totalUpdateInvField,true); for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vecf=totalUpdateField->GetPixel(index)*1; VectorType vecm=totalUpdateInvField->GetPixel(index); // update time components 1 & 2 this->m_SyNF->SetPixel( index, this->m_SyNF->GetPixel( index )+vecf*this->m_GradstepAltered); this->m_SyNM->SetPixel( index, this->m_SyNM->GetPixel( index )+vecm*this->m_GradstepAltered); // min field difference => geodesic => DV/dt=0 float geowt1=0.95; float geowt2=1.0-geowt1; VectorType synmv=this->m_SyNM->GetPixel( index ); VectorType synfv =this->m_SyNF->GetPixel( index ); this->m_SyNM->SetPixel( index, synmv*geowt1-synfv*geowt2); this->m_SyNF->SetPixel( index, synfv*geowt1-synmv*geowt2); } if ( this->m_TotalSmoothingparam > 0 || this->m_TotalSmoothingMeshSize[0] > 0 ) { //smooth time components separately this->SmoothDeformationField( this->m_SyNF,false); this->SmoothDeformationField( this->m_SyNM,false); } return; } template void ANTSImageRegistrationOptimizer ::DiReCTUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints, PointSetPointer mpoints) { typedef TimeVaryingVelocityFieldType tvt; TimeVaryingVelocityFieldPointer velocityUpdate=NULL; typename ImageType::SpacingType spacing=fixedImage->GetSpacing(); VectorType zero; zero.Fill(0); DeformationFieldPointer totalUpdateField,totalUpdateInvField=DeformationFieldType::New(); totalUpdateInvField->SetSpacing( this->m_DeformationField->GetSpacing() ); totalUpdateInvField->SetOrigin( this->m_DeformationField->GetOrigin() ); totalUpdateInvField->SetDirection( this->m_DeformationField->GetDirection() ); totalUpdateInvField->SetLargestPossibleRegion(this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); totalUpdateInvField->Allocate(); totalUpdateInvField->FillBuffer(zero); unsigned long numpx=this->m_DeformationField->GetBufferedRegion().GetNumberOfPixels(); bool generatetvfield=false; bool enlargefield=false; if (!this->m_TimeVaryingVelocity) generatetvfield=true; else { for (int jj=0; jjm_CurrentDomainSize[jj] != this->m_TimeVaryingVelocity->GetLargestPossibleRegion().GetSize()[jj]) enlargefield=true; } velocityUpdate=tvt::New(); typename tvt::RegionType gregion; typename tvt::SizeType gsize; typename tvt::SpacingType gspace; typename tvt::PointType gorigin; gorigin.Fill(0); for (unsigned int dim=0; dimm_CurrentDomainSize[dim]; gspace[dim]=this->m_CurrentDomainSpacing[dim]; gorigin[dim]=this->m_CurrentDomainOrigin[dim]; } if ( this->m_NTimeSteps < 2 ) this->m_NTimeSteps=2; gsize[TDimension]=(unsigned long) this->m_NTimeSteps; float hitstep=1.0/((float)this->m_NTimeSteps-1); gspace[TDimension]=1; gregion.SetSize(gsize); velocityUpdate->SetSpacing( gspace ); velocityUpdate->SetOrigin( gorigin ); /** The TV Field has the direction of the sub-image -- the time domain has identity transform */ typename tvt::DirectionType iddir; iddir.Fill(0); iddir[ImageDimension][ImageDimension]=1; for (unsigned int i=0; iGetDeformationField()->GetDirection()[i][j]; velocityUpdate->SetDirection( iddir ); velocityUpdate->SetLargestPossibleRegion(gregion); velocityUpdate->SetRequestedRegion( gregion); velocityUpdate->SetBufferedRegion( gregion ); velocityUpdate->Allocate(); velocityUpdate->FillBuffer(zero); if (generatetvfield) { this->m_TimeVaryingVelocity=tvt::New(); this->m_TimeVaryingVelocity->SetSpacing( gspace ); this->m_TimeVaryingVelocity->SetOrigin( gorigin ); this->m_TimeVaryingVelocity->SetDirection( iddir ); this->m_TimeVaryingVelocity->SetLargestPossibleRegion(gregion); this->m_TimeVaryingVelocity->SetRequestedRegion( gregion); this->m_TimeVaryingVelocity->SetBufferedRegion( gregion ); this->m_TimeVaryingVelocity->Allocate(); this->m_TimeVaryingVelocity->FillBuffer(zero); /* this->m_LastTimeVaryingVelocity=tvt::New(); this->m_LastTimeVaryingVelocity->SetSpacing( gspace ); this->m_LastTimeVaryingVelocity->SetOrigin( gorigin ); this->m_LastTimeVaryingVelocity->SetDirection( iddir ); this->m_LastTimeVaryingVelocity->SetLargestPossibleRegion(gregion); this->m_LastTimeVaryingVelocity->SetRequestedRegion( gregion); this->m_LastTimeVaryingVelocity->SetBufferedRegion( gregion ); this->m_LastTimeVaryingVelocity->Allocate(); this->m_LastTimeVaryingVelocity->FillBuffer(zero); */ this->m_LastTimeVaryingUpdate=tvt::New(); this->m_LastTimeVaryingUpdate->SetSpacing( gspace ); this->m_LastTimeVaryingUpdate->SetOrigin( gorigin ); this->m_LastTimeVaryingUpdate->SetDirection( iddir ); this->m_LastTimeVaryingUpdate->SetLargestPossibleRegion(gregion); this->m_LastTimeVaryingUpdate->SetRequestedRegion( gregion); this->m_LastTimeVaryingUpdate->SetBufferedRegion( gregion ); this->m_LastTimeVaryingUpdate->Allocate(); this->m_LastTimeVaryingUpdate->FillBuffer(zero); } else if ( enlargefield ){ this->m_TimeVaryingVelocity=this->ExpandVelocity(); this->m_TimeVaryingVelocity->SetSpacing(gspace); this->m_TimeVaryingVelocity->SetOrigin(gorigin); /* this->m_LastTimeVaryingVelocity=tvt::New(); this->m_LastTimeVaryingVelocity->SetSpacing( gspace ); this->m_LastTimeVaryingVelocity->SetOrigin( gorigin ); this->m_LastTimeVaryingVelocity->SetDirection( iddir ); this->m_LastTimeVaryingVelocity->SetLargestPossibleRegion(gregion); this->m_LastTimeVaryingVelocity->SetRequestedRegion( gregion); this->m_LastTimeVaryingVelocity->SetBufferedRegion( gregion ); this->m_LastTimeVaryingVelocity->Allocate(); this->m_LastTimeVaryingVelocity->FillBuffer(zero);*/ this->m_LastTimeVaryingUpdate=tvt::New(); this->m_LastTimeVaryingUpdate->SetSpacing( gspace ); this->m_LastTimeVaryingUpdate->SetOrigin( gorigin ); this->m_LastTimeVaryingUpdate->SetDirection( iddir ); this->m_LastTimeVaryingUpdate->SetLargestPossibleRegion(gregion); this->m_LastTimeVaryingUpdate->SetRequestedRegion( gregion); this->m_LastTimeVaryingUpdate->SetBufferedRegion( gregion ); this->m_LastTimeVaryingUpdate->Allocate(); this->m_LastTimeVaryingUpdate->FillBuffer(zero); } if (!this->m_SyNF) { std::cout <<" Allocating " << std::endl; this->m_SyNF=this->CopyDeformationField(totalUpdateInvField); this->m_SyNFInv=this->CopyDeformationField(this->m_SyNF); this->m_SyNM=this->CopyDeformationField(totalUpdateInvField); this->m_SyNMInv=this->CopyDeformationField(this->m_SyNF); std::cout <<" Allocating Done " << std::endl; } if (!this->m_SyNF) { std::cout<<" F'D UP " << std::endl;} ImagePointer wfimage,wmimage; PointSetPointer wfpoints=NULL,wmpoints=NULL; AffineTransformPointer aff =this->m_AffineTransform; AffineTransformPointer affinverse=NULL; typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(this->m_SyNF,this->m_SyNF->GetLargestPossibleRegion() ); //here, SyNF holds the moving velocity field, SyNM holds the fixed //velocity field and we integrate both to generate the inv/fwd fields typename JacobianFunctionType::Pointer jfunction = JacobianFunctionType::New(); float lot=0, lot2=1.0; unsigned int fct=100; for (float hit=0; hit<=1; hit=hit+hitstep) { this->m_SyNFInv = this->IntegrateVelocity(hit,lot); this->m_SyNMInv = this->IntegrateVelocity(hit,lot2); if ( false && this->m_CurrentIteration == 1 && this->m_SyNFInv ) { typedef itk::VectorImageFileWriter DeformationFieldWriterType; typename DeformationFieldWriterType::Pointer writer = DeformationFieldWriterType::New(); std::ostringstream osstream; osstream << fct; fct++; std::string fnm = std::string("field1")+osstream.str()+std::string("warp.nii.gz"); std::string fnm2 = std::string("field2")+osstream.str()+std::string("warp.nii.gz"); writer->SetUseAvantsNamingConvention( true ); writer->SetInput( this->m_SyNFInv ); writer->SetFileName( fnm.c_str() ); std::cout << " write " << fnm << std::endl; writer->Update(); // writer->SetInput( this->m_SyNMInv ); // writer->SetFileName( fnm2.c_str() ); // writer->Update(); } if (aff){ affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } if ( mpoints ) { /**FIXME -- NEED INTEGRATION FOR POINTS ONLY -- warp landmarks for * tv-field */ // std::cout <<" aff " << std::endl; /** NOte, totalUpdateInvField is filled with zeroes! -- we only want affine mapping */ wmpoints = this->WarpMultiTransform(fixedImage,movingImage, mpoints , aff , totalUpdateInvField , true, NULL ); DeformationFieldPointer mdiffmap = this->IntegrateLandmarkSetVelocity(lot2,hit,wmpoints,movingImage); wmpoints = this->WarpMultiTransform(fixedImage,movingImage, wmpoints , NULL , mdiffmap , true , NULL ); } if ( fpoints ) {// need full inverse map wfpoints = this->WarpMultiTransform(fixedImage,movingImage, fpoints , NULL , totalUpdateInvField , true, this->m_FixedImageAffineTransform ); DeformationFieldPointer fdiffmap = this->IntegrateLandmarkSetVelocity(lot,hit,wfpoints,fixedImage); wfpoints = this->WarpMultiTransform(fixedImage,fixedImage, wfpoints , NULL , fdiffmap , false , NULL ); } totalUpdateField=this->ComputeUpdateField( this->m_SyNMInv, this->m_SyNFInv , wfpoints, wmpoints,totalUpdateInvField,true); if ( this->m_SyNFullTime == 2 ) totalUpdateInvField=NULL; this->CopyOrAddToVelocityField( velocityUpdate, totalUpdateField , totalUpdateInvField, hit ); } // http://en.wikipedia.org/wiki/Conjugate_gradient_method // below is r_k+1 this->SmoothVelocityGauss( velocityUpdate , this->m_GradSmoothingparam , ImageDimension ); // update total velocity with v-update float tmag=0; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; TVFieldIterator m_FieldIter( this->m_TimeVaryingVelocity,this->m_TimeVaryingVelocity->GetLargestPossibleRegion()); for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { float A=1; float alpha=0,alpha1=0,alpha2=0,beta=0,beta1=0,beta2=0; VectorType vec1=velocityUpdate->GetPixel(m_FieldIter.GetIndex()); // r_k+1 VectorType vec2=vec1;//this->m_LastTimeVaryingVelocity->GetPixel(m_FieldIter.GetIndex()); // r_k VectorType upd=this->m_LastTimeVaryingUpdate->GetPixel(m_FieldIter.GetIndex()); // p_k for (unsigned int ii=0; ii 0 ) alpha=alpha1/(A*alpha2+0.001); if (beta2 > 0 ) beta=beta1/(beta2+0.001); if (beta > 1) beta=1; if (alpha > 1) alpha=1; // std::cout <<" beta " << beta << " alpha " << alpha << " it " << this->m_CurrentIteration << std::endl; VectorType newupd=(vec1); if ( this->m_CurrentIteration > 2) { newupd=(vec1+upd)*0.5; } VectorType newsoln=m_FieldIter.Get()+ this->m_GradstepAltered*newupd; m_FieldIter.Set( newsoln ); // VectorType vec2u=vec2 - alpha*A*upd; // this->m_LastTimeVaryingVelocity->SetPixel(m_FieldIter.GetIndex(), vec1 ); this->m_LastTimeVaryingUpdate->SetPixel(m_FieldIter.GetIndex(), newupd); float mag=0; VectorType vv=m_FieldIter.Get(); for (unsigned int jj=0; jjm_NTimeSteps*(float)numpx); std::cout << " DiffLength " << tmag << std::endl; if ( this->m_TotalSmoothingparam > 0 || this->m_TotalSmoothingMeshSize[0] > 0 ) { this->SmoothVelocityGauss( this->m_TimeVaryingVelocity , this->m_TotalSmoothingparam , ImageDimension ); // this->SmoothDeformationField( this->m_SyNF,false); // this->SmoothDeformationField( this->m_SyNM,false); } return; } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::IntegrateVelocity(float starttimein, float finishtimein ) { ImagePointer mask=NULL; if ( this->m_SyNMInv && this->m_MaskImage) mask= this->WarpMultiTransform( this->m_MaskImage, this->m_MaskImage, NULL, this->m_SyNMInv, false , this->m_FixedImageAffineTransform ); else if (this->m_MaskImage) mask=this->SubsampleImage( this->m_MaskImage, this->m_ScaleFactor , this->m_MaskImage->GetOrigin() , this->m_MaskImage->GetDirection() , NULL); // std::cout << " st " << starttimein << " ft " << finishtimein << std::endl; typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef TimeVaryingVelocityFieldType tvt; bool dothick=false; if ( finishtimein > starttimein && this->m_ComputeThickness ) dothick=true; if ( dothick && this->m_CurrentIteration > 2 ) { this->m_ThickImage=ImageType::New(); this->m_ThickImage->SetSpacing( this->m_SyNF->GetSpacing() ); this->m_ThickImage->SetOrigin( this->m_SyNF->GetOrigin() ); this->m_ThickImage->SetDirection( this->m_SyNF->GetDirection() ); this->m_ThickImage->SetLargestPossibleRegion(this->m_SyNF->GetLargestPossibleRegion() ); this->m_ThickImage->SetRequestedRegion( this->m_SyNF->GetLargestPossibleRegion() ); this->m_ThickImage->SetBufferedRegion( this->m_SyNF->GetLargestPossibleRegion() ); this->m_ThickImage->Allocate(); this->m_ThickImage->FillBuffer(0); this->m_HitImage=ImageType::New(); this->m_HitImage->SetSpacing( this->m_SyNF->GetSpacing() ); this->m_HitImage->SetOrigin( this->m_SyNF->GetOrigin() ); this->m_HitImage->SetDirection( this->m_SyNF->GetDirection() ); this->m_HitImage->SetLargestPossibleRegion(this->m_SyNF->GetLargestPossibleRegion() ); this->m_HitImage->SetRequestedRegion( this->m_SyNF->GetLargestPossibleRegion() ); this->m_HitImage->SetBufferedRegion( this->m_SyNF->GetLargestPossibleRegion() ); this->m_HitImage->Allocate(); this->m_HitImage->FillBuffer(0); } else { this->m_HitImage=NULL; this->m_ThickImage=NULL; } DeformationFieldPointer intfield=DeformationFieldType::New(); intfield->SetSpacing( this->m_CurrentDomainSpacing ); intfield->SetOrigin( this->m_DeformationField->GetOrigin() ); intfield->SetDirection( this->m_DeformationField->GetDirection() ); intfield->SetLargestPossibleRegion( this->m_DeformationField->GetLargestPossibleRegion()); intfield->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion()); intfield->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); intfield->Allocate(); VectorType zero; zero.Fill(0); intfield->FillBuffer(zero); if (starttimein == finishtimein) return intfield; if (!this->m_TimeVaryingVelocity) { std::cout << " No TV Field " << std::endl; return intfield; } this->m_VelocityFieldInterpolator->SetInputImage(this->m_TimeVaryingVelocity); typedef tvt TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; if (starttimein < 0) starttimein=0; if (starttimein > 1) starttimein=1; if (finishtimein < 0) finishtimein=0; if (finishtimein > 1) finishtimein=1; float timesign=1.0; if (starttimein > finishtimein ) timesign= -1.0; FieldIterator m_FieldIter(this->GetDeformationField(), this->GetDeformationField()->GetLargestPossibleRegion()); // std::cout << " Start Int " << starttimein << std::endl; if ( mask && !this->m_ComputeThickness ) { for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { IndexType velind=m_FieldIter.GetIndex(); VectorType disp; if (mask->GetPixel(velind) > 0.05 ) disp=this->IntegratePointVelocity(starttimein, finishtimein , velind)*mask->GetPixel(velind); else disp.Fill(0); intfield->SetPixel(velind,disp); } } else { for( m_FieldIter.GoToBegin(); !m_FieldIter.IsAtEnd(); ++m_FieldIter ) { IndexType velind=m_FieldIter.GetIndex(); VectorType disp=this->IntegratePointVelocity(starttimein, finishtimein , velind); intfield->SetPixel(velind,disp); } } if (this->m_ThickImage && this->m_MaskImage ){ std::string outname=this->localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("thick.nii.gz"); std::cout << " write " << outname << std::endl; WriteImage(this->m_ThickImage,outname.c_str()); } return intfield; } template typename ANTSImageRegistrationOptimizer::DeformationFieldPointer ANTSImageRegistrationOptimizer ::IntegrateLandmarkSetVelocity(float starttimein, float finishtimein, typename ANTSImageRegistrationOptimizer::PointSetPointer mypoints , typename ANTSImageRegistrationOptimizer::ImagePointer refimage ) { typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef TimeVaryingVelocityFieldType tvt; DeformationFieldPointer intfield=DeformationFieldType::New(); intfield->SetSpacing( this->m_CurrentDomainSpacing ); intfield->SetOrigin( this->m_DeformationField->GetOrigin() ); intfield->SetDirection( this->m_DeformationField->GetDirection() ); intfield->SetLargestPossibleRegion( this->m_DeformationField->GetLargestPossibleRegion()); intfield->SetRequestedRegion( this->m_DeformationField->GetLargestPossibleRegion()); intfield->SetBufferedRegion( this->m_DeformationField->GetLargestPossibleRegion() ); intfield->Allocate(); VectorType zero; zero.Fill(0); intfield->FillBuffer(zero); if (starttimein == finishtimein) return intfield; if (!this->m_TimeVaryingVelocity) { std::cout << " No TV Field " << std::endl; return intfield; } this->m_VelocityFieldInterpolator->SetInputImage(this->m_TimeVaryingVelocity); typedef tvt TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; if (starttimein < 0) starttimein=0; if (starttimein > 1) starttimein=1; if (finishtimein < 0) finishtimein=0; if (finishtimein > 1) finishtimein=1; float timesign=1.0; if (starttimein > finishtimein ) timesign= -1.0; unsigned long sz1 = mypoints->GetNumberOfPoints(); for (unsigned long ii=0; iiGetPoint(ii,&point); //std::cout <<" get point index " << point << std::endl; ImagePointType pt,wpt; for (unsigned int jj=0; jjTransformPhysicalPointToIndex( pt, velind ); //std::cout <<" inside? " << bisinside << std::endl; if (bisinside) { // std::cout << "integrate " << std::endl; VectorType disp=this->IntegratePointVelocity(starttimein, finishtimein , velind); // std::cout << "put inside " << std::endl; intfield->SetPixel(velind,disp); } } return intfield; } template typename ANTSImageRegistrationOptimizer::VectorType ANTSImageRegistrationOptimizer ::IntegratePointVelocity(float starttimein, float finishtimein , IndexType velind) { typedef Point xPointType; this->m_Debug=false; // std::cout <<"Enter IP "<< std::endl; typedef typename VelocityFieldInterpolatorType::OutputType InterpPointType; typedef float PixelType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef itk::Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::SpacingType SpacingType; typedef TimeVaryingVelocityFieldType tvt; VectorType zero; zero.Fill(0); if (starttimein == finishtimein) return zero; typedef tvt TimeVaryingVelocityFieldType; typedef itk::ImageRegionIteratorWithIndex FieldIterator; typedef itk::ImageRegionIteratorWithIndex TVFieldIterator; typedef typename DeformationFieldType::IndexType DIndexType; typedef typename DeformationFieldType::PointType DPointType; typedef typename TimeVaryingVelocityFieldType::IndexType VIndexType; typedef typename TimeVaryingVelocityFieldType::PointType VPointType; this->m_VelocityFieldInterpolator->SetInputImage(this->m_TimeVaryingVelocity); double dT=this->m_DeltaTime; unsigned int m_NumberOfTimePoints = this->m_TimeVaryingVelocity->GetLargestPossibleRegion().GetSize()[TDimension]; if (starttimein < 0) starttimein=0; if (starttimein > 1) starttimein=1; if (finishtimein < 0) finishtimein=0; if (finishtimein > 1) finishtimein=1; float timesign=1.0; if (starttimein > finishtimein ) timesign= -1.0; VectorType velo; velo.Fill(0); xPointType pointIn1; xPointType pointIn2; xPointType pointIn3; typename VelocityFieldInterpolatorType::ContinuousIndexType vcontind; float itime = starttimein; unsigned long ct = 0; float inverr=0; float thislength=0,euclideandist=0; bool timedone = false; inverr=1110; VectorType disp; double deltaTime=dT,vecsign=1.0; SpacingType spacing= this->m_DeformationField->GetSpacing(); if (starttimein > finishtimein ) vecsign=-1.0; VIndexType vind; vind.Fill(0); for (unsigned int jj=0; jjm_TimeVaryingVelocity->TransformIndexToPhysicalPoint( vind, pointIn1); // time is in [0,1] pointIn1[TDimension]= starttimein*(m_NumberOfTimePoints-1); bool isinside=true; xPointType Y1x; xPointType Y2x; xPointType Y3x; xPointType Y4x; // set up parameters for start of integration disp.Fill(0.0); timedone=false; itime = starttimein; ct = 0; while ( !timedone ) { double itimetn1 = itime - timesign*deltaTime; double itimetn1h = itime - timesign*deltaTime*0.5; if (itimetn1h < 0 ) itimetn1h=0; if (itimetn1h > 1 ) itimetn1h=1; if (itimetn1 < 0 ) itimetn1=0; if (itimetn1 > 1 ) itimetn1=1; float totalmag=0; // first get current position of particle typename VelocityFieldInterpolatorType::OutputType f1; f1.Fill(0); typename VelocityFieldInterpolatorType::OutputType f2; f2.Fill(0); typename VelocityFieldInterpolatorType::OutputType f3; f3.Fill(0); typename VelocityFieldInterpolatorType::OutputType f4; f4.Fill(0); for (unsigned int jj=0; jjm_Debug) std::cout << " p2 " << pointIn2<< std::endl; Y1x[TDimension]=itimetn1*(float)(m_NumberOfTimePoints-1); Y2x[TDimension]=itimetn1h*(float)(m_NumberOfTimePoints-1); Y3x[TDimension]=itimetn1h*(float)(m_NumberOfTimePoints-1); Y4x[TDimension]=itime*(float)(m_NumberOfTimePoints-1); if (this->m_Debug) std::cout << " p2 " << pointIn2<< " y1 " << Y1x[TDimension] << " y4 " << Y4x[TDimension] << std::endl; if ( this->m_VelocityFieldInterpolator->IsInsideBuffer(Y1x) ) { f1 = this->m_VelocityFieldInterpolator->Evaluate( Y1x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y2x) ) { f2 = this->m_VelocityFieldInterpolator->Evaluate( Y2x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y3x) ) { f3 = this->m_VelocityFieldInterpolator->Evaluate( Y3x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y4x) ) { f4 = this->m_VelocityFieldInterpolator->Evaluate( Y4x ); } for (unsigned int jj=0; jj finishtimein) { if (itime <= finishtimein ) timedone=true; } else if (thislength == 0) timedone=true; else { if (itime >= finishtimein ) timedone=true; } } // now we have the thickness value stored in thislength if ( this->m_ThickImage && this->m_HitImage){ // set up parameters for start of integration velo.Fill(0); itime = starttimein; timedone = false; vind.Fill(0); for (unsigned int jj=0; jjm_TimeVaryingVelocity->TransformIndexToPhysicalPoint( vind, pointIn1); // time is in [0,1] pointIn1[TDimension]= starttimein*(m_NumberOfTimePoints-1); // set up parameters for start of integration disp.Fill(0.0); timedone=false; itime = starttimein; ct = 0; while ( !timedone ) { double itimetn1 = itime - timesign*deltaTime; double itimetn1h = itime - timesign*deltaTime*0.5; if (itimetn1h < 0 ) itimetn1h=0; if (itimetn1h > 1 ) itimetn1h=1; if (itimetn1 < 0 ) itimetn1=0; if (itimetn1 > 1 ) itimetn1=1; // float totalmag=0; // first get current position of particle typename VelocityFieldInterpolatorType::OutputType f1; f1.Fill(0); typename VelocityFieldInterpolatorType::OutputType f2; f2.Fill(0); typename VelocityFieldInterpolatorType::OutputType f3; f3.Fill(0); typename VelocityFieldInterpolatorType::OutputType f4; f4.Fill(0); for (unsigned int jj=0; jjm_Debug) std::cout << " p2 " << pointIn2<< std::endl; Y1x[TDimension]=itimetn1*(float)(m_NumberOfTimePoints-1); Y2x[TDimension]=itimetn1h*(float)(m_NumberOfTimePoints-1); Y3x[TDimension]=itimetn1h*(float)(m_NumberOfTimePoints-1); Y4x[TDimension]=itime*(float)(m_NumberOfTimePoints-1); if (this->m_Debug) std::cout << " p2 " << pointIn2<< " y1 " << Y1x[TDimension] << " y4 " << Y4x[TDimension] << std::endl; if ( this->m_VelocityFieldInterpolator->IsInsideBuffer(Y1x) ) { f1 = this->m_VelocityFieldInterpolator->Evaluate( Y1x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y2x) ) { f2 = this->m_VelocityFieldInterpolator->Evaluate( Y2x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y3x) ) { f3 = this->m_VelocityFieldInterpolator->Evaluate( Y3x ); for (unsigned int jj=0; jjm_VelocityFieldInterpolator->IsInsideBuffer(Y4x) ) { f4 = this->m_VelocityFieldInterpolator->Evaluate( Y4x ); } for (unsigned int jj=0; jj finishtimein) { if (itime <= finishtimein ) timedone=true; } else { if (itime >= finishtimein ) timedone=true; } // bool isingray=true; if ( this->m_MaskImage ) { if ( this->m_MaskImage->GetPixel(velind) ) { VIndexType thind2; IndexType thind; bool isin=this->m_TimeVaryingVelocity->TransformPhysicalPointToIndex( pointIn3, thind2 ); for (unsigned int ij=0; ijm_HitImage->GetPixel(thind); unsigned long newct=lastct+1; float oldthick=this->m_ThickImage->GetPixel(thind); float newthick=(float)lastct/(float)newct*oldthick+1.0/(float)newct*euclideandist; this->m_HitImage->SetPixel( thind, newct ); this->m_ThickImage->SetPixel(thind, newthick ); } else std::cout << " thind " << thind << " edist " << euclideandist << " p3 " << pointIn3 << " p1 " << pointIn1 << std::endl; // this->m_ThickImage->SetPixel(thind, thislength ); } } } } // if (!isinside) { std::cout << " velind " << velind << " not inside " << Y1 << std::endl; } if (this->m_Debug) std::cout << " Length " << thislength << std::endl; this->m_Debug=false; return disp; } /** * Standard "PrintSelf" method */ template void ANTSImageRegistrationOptimizer ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSImageRegistrationOptimizer.h000066400000000000000000002204411147325206600267670ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSImageRegistrationOptimizer.h,v $ Language: C++ Date: $Date: 2009/04/22 01:00:17 $ Version: $Revision: 1.44 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkANTSImageRegistrationOptimizer_h #define __itkANTSImageRegistrationOptimizer_h #include "itkObject.h" #include "itkObjectFactory.h" #include "itkVectorGaussianInterpolateImageFunction.h" #include "antsCommandLineParser.h" #include "itkShiftScaleImageFilter.h" #include "itkMinimumMaximumImageFilter.h" #include "itkImage.h" #include "itkMacro.h" #include "ReadWriteImage.h" #include "itkCenteredEuler3DTransform.h" #include "itkQuaternionRigidTransform.h" #include "itkANTSAffine3DTransform.h" #include "itkANTSCenteredAffine2DTransform.h" #include "itkCenteredTransformInitializer.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" #include "itkFiniteDifferenceFunction.h" #include "itkFixedArray.h" #include "itkANTSSimilarityMetric.h" #include "itkVectorExpandImageFilter.h" //#include "itkNeighbohoodAlgorithm.h" #include "itkPDEDeformableRegistrationFilter.h" #include "itkWarpImageFilter.h" #include "itkWarpImageMultiTransformFilter.h" #include "itkDeformationFieldFromMultiTransformFilter.h" #include "itkWarpImageWAffineFilter.h" #include "itkPointSet.h" #include "itkVector.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkGeneralToBSplineDeformationFieldFilter.h" #include "ANTS_affine_registration2.h" #include "itkVectorFieldGradientImageFunction.h" #include "itkBSplineInterpolateImageFunction.h" namespace itk { template class ITK_EXPORT ANTSImageRegistrationOptimizer : public Object { public: /** Standard class typedefs. */ typedef ANTSImageRegistrationOptimizer Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ANTSImageRegistrationOptimizer, Object ); itkStaticConstMacro( Dimension, unsigned int, TDimension ); itkStaticConstMacro( ImageDimension, unsigned int, TDimension ); typedef TReal RealType; typedef Image ImageType; typedef typename ImageType::Pointer ImagePointer; typedef itk::MatrixOffsetTransformBase< double, ImageDimension, ImageDimension > TransformType; /** Point Types for landmarks and labeled point-sets */ typedef itk::ANTSLabeledPointSet LabeledPointSetType; typedef typename LabeledPointSetType::Pointer LabeledPointSetPointer; typedef typename LabeledPointSetType::PointSetType PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef typename ImageType::PointType ImagePointType; typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef typename AffineTransformType::Pointer AffineTransformPointer; typedef OptAffine OptAffineType; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef itk::Image TimeVaryingVelocityFieldType; typedef typename TimeVaryingVelocityFieldType::Pointer TimeVaryingVelocityFieldPointer; typedef itk::VectorLinearInterpolateImageFunction VelocityFieldInterpolatorType; typedef itk::VectorGaussianInterpolateImageFunction VelocityFieldInterpolatorType2; typedef typename DeformationFieldType::IndexType IndexType; typedef ants::CommandLineParser ParserType; typedef typename ParserType::OptionType OptionType; typedef GeneralToBSplineDeformationFieldFilter BSplineFilterType; typedef FixedArray ArrayType; /** Typedefs for similarity metrics */ typedef ANTSSimilarityMetric SimilarityMetricType; typedef typename SimilarityMetricType::Pointer SimilarityMetricPointer; typedef std::vector SimilarityMetricListType; /** FiniteDifferenceFunction type. */ typedef FiniteDifferenceFunction FiniteDifferenceFunctionType; typedef typename FiniteDifferenceFunctionType::TimeStepType TimeStepType; typedef typename FiniteDifferenceFunctionType::Pointer FiniteDifferenceFunctionPointer; typedef AvantsPDEDeformableRegistrationFunction MetricBaseType; typedef typename MetricBaseType::Pointer MetricBaseTypePointer; /* Jacobian and other calculations */ typedef itk::VectorFieldGradientImageFunction JacobianFunctionType; /** Set functions */ void SetAffineTransform(AffineTransformPointer A) {this->m_AffineTransform=A;} void SetDeformationField(DeformationFieldPointer A) {this->m_DeformationField=A;} void SetInverseDeformationField(DeformationFieldPointer A) {this->m_InverseDeformationField=A;} void SetMaskImage( ImagePointer m) { this->m_MaskImage=m; } void SetFixedImageAffineTransform(AffineTransformPointer A) {this->m_FixedImageAffineTransform=A;} AffineTransformPointer GetFixedImageAffineTransform() {return this->m_FixedImageAffineTransform;} /** Get functions */ AffineTransformPointer GetAffineTransform() {return this->m_AffineTransform;} DeformationFieldPointer GetDeformationField( ) {return this->m_DeformationField;} DeformationFieldPointer GetInverseDeformationField() {return this->m_InverseDeformationField;} /** Initialize all parameters */ void SetNumberOfLevels(unsigned int i) {this->m_NumberOfLevels=i;} void SetParser( typename ParserType::Pointer P ) {this->m_Parser=P;} /** Basic operations */ DeformationFieldPointer CopyDeformationField( DeformationFieldPointer input ); std::string localANTSGetFilePrefix(const char *str){ std::string filename = str; std::string::size_type pos = filename.rfind( "." ); std::string filepre = std::string( filename, 0, pos ); if ( pos != std::string::npos ){ std::string extension = std::string( filename, pos, filename.length()-1); if (extension==std::string(".gz")){ pos = filepre.rfind( "." ); extension = std::string( filepre, pos, filepre.length()-1 ); } // if (extension==".txt") return AFFINE_FILE; // else return DEFORMATION_FILE; } // else{ // return INVALID_FILE; //} return filepre; } void SmoothDeformationField(DeformationFieldPointer field, bool TrueEqualsGradElseTotal ) { typename ParserType::OptionType::Pointer regularizationOption = this->m_Parser->GetOption( "regularization" ); if ( ( regularizationOption->GetValue() ).find( "DMFFD" ) != std::string::npos ) { if( ( !TrueEqualsGradElseTotal && this->m_TotalSmoothingparam == 0.0 ) || ( TrueEqualsGradElseTotal && this->m_GradSmoothingparam == 0.0 ) ) { return; } ArrayType meshSize; unsigned int splineOrder = this->m_BSplineFieldOrder; float bsplineKernelVariance = static_cast( splineOrder + 1 ) / 12.0; unsigned int numberOfLevels = 1; if( TrueEqualsGradElseTotal ) { if( this->m_GradSmoothingparam < 0.0 ) { meshSize = this->m_GradSmoothingMeshSize; for( unsigned int d = 0; d < ImageDimension; d++ ) { meshSize[d] *= static_cast( vcl_pow( 2.0, static_cast( this->m_CurrentLevel ) ) ); } } else { float spanLength = vcl_sqrt( this->m_GradSmoothingparam / bsplineKernelVariance ); for( unsigned int d = 0; d < ImageDimension; d++ ) { meshSize[d] = static_cast( field->GetLargestPossibleRegion().GetSize()[d] / spanLength + 0.5 ); } } this->SmoothDeformationFieldBSpline( field, meshSize, splineOrder, numberOfLevels ); } else { if( this->m_TotalSmoothingparam < 0.0 ) { meshSize = this->m_TotalSmoothingMeshSize; for( unsigned int d = 0; d < ImageDimension; d++ ) { meshSize[d] *= static_cast( vcl_pow( 2.0, static_cast( this->m_CurrentLevel ) ) ); } } else { float spanLength = vcl_sqrt( this->m_TotalSmoothingparam / bsplineKernelVariance ); for( unsigned int d = 0; d < ImageDimension; d++ ) { meshSize[d] = static_cast( field->GetLargestPossibleRegion().GetSize()[d] / spanLength + 0.5 ); } } RealType maxMagnitude = 0.0; ImageRegionIterator It( field, field->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { RealType magnitude = ( It.Get() ).GetNorm(); if( magnitude > maxMagnitude ) { maxMagnitude = magnitude; } } this->SmoothDeformationFieldBSpline( field, meshSize, splineOrder, numberOfLevels ); if( maxMagnitude > 0.0 ) { for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { It.Set( It.Get() / maxMagnitude ); } } } } else // Gaussian { float sig=0; if (TrueEqualsGradElseTotal) sig=this->m_GradSmoothingparam; else sig=this->m_TotalSmoothingparam; this->SmoothDeformationFieldGauss(field,sig); } } void SmoothDeformationFieldGauss(DeformationFieldPointer field = NULL, float sig=0.0, bool useparamimage=false, unsigned int lodim=ImageDimension); // float = smoothingparam, int = maxdim to smooth void SmoothVelocityGauss(TimeVaryingVelocityFieldPointer field,float,unsigned int); void SmoothDeformationFieldBSpline(DeformationFieldPointer field, ArrayType meshSize, unsigned int splineorder, unsigned int numberoflevels ); DeformationFieldPointer ComputeUpdateFieldAlternatingMin(DeformationFieldPointer fixedwarp, DeformationFieldPointer movingwarp, PointSetPointer fpoints=NULL, PointSetPointer wpoints=NULL,DeformationFieldPointer updateFieldInv=NULL, bool updateenergy=true); DeformationFieldPointer ComputeUpdateField(DeformationFieldPointer fixedwarp, DeformationFieldPointer movingwarp, PointSetPointer fpoints=NULL, PointSetPointer wpoints=NULL,DeformationFieldPointer updateFieldInv=NULL, bool updateenergy=true); TimeVaryingVelocityFieldPointer ExpandVelocity( ) { float expandFactors[ImageDimension+1]; expandFactors[ImageDimension]=1; m_Debug=false; for( int idim = 0; idim < ImageDimension; idim++ ) { expandFactors[idim] = (float)this->m_CurrentDomainSize[idim]/(float) this->m_TimeVaryingVelocity->GetLargestPossibleRegion().GetSize()[idim]; if( expandFactors[idim] < 1 ) expandFactors[idim] = 1; if (this->m_Debug) std::cout << " ExpFac " << expandFactors[idim] << " curdsz " << this->m_CurrentDomainSize[idim] << std::endl; } VectorType pad; pad.Fill(0); typedef VectorExpandImageFilter ExpanderType; typename ExpanderType::Pointer m_FieldExpander = ExpanderType::New(); m_FieldExpander->SetInput(this->m_TimeVaryingVelocity); m_FieldExpander->SetExpandFactors( expandFactors ); // m_FieldExpander->SetEdgePaddingValue( pad ); m_FieldExpander->UpdateLargestPossibleRegion(); return m_FieldExpander->GetOutput(); } DeformationFieldPointer ExpandField(DeformationFieldPointer field, typename ImageType::SpacingType targetSpacing) { // this->m_Debug=true; float expandFactors[ImageDimension]; for( int idim = 0; idim < ImageDimension; idim++ ) { expandFactors[idim] = (float)this->m_CurrentDomainSize[idim]/(float)field->GetLargestPossibleRegion().GetSize()[idim]; if( expandFactors[idim] < 1 ) expandFactors[idim] = 1; // if (this->m_Debug) std::cout << " ExpFac " << expandFactors[idim] << " curdsz " << this->m_CurrentDomainSize[idim] << std::endl; } VectorType pad; pad.Fill(0); typedef VectorExpandImageFilter ExpanderType; typename ExpanderType::Pointer m_FieldExpander = ExpanderType::New(); m_FieldExpander->SetInput(field); m_FieldExpander->SetExpandFactors( expandFactors ); // use default // m_FieldExpander->SetEdgePaddingValue( pad ); m_FieldExpander->UpdateLargestPossibleRegion(); typename DeformationFieldType::Pointer fieldout=m_FieldExpander->GetOutput(); fieldout->SetSpacing(targetSpacing); fieldout->SetOrigin(field->GetOrigin()); if (this->m_Debug) std::cout << " Field size " << fieldout->GetLargestPossibleRegion().GetSize() << std::endl; //this->m_Debug=false; return fieldout; } ImagePointer GetVectorComponent(DeformationFieldPointer field, unsigned int index) { // Initialize the Moving to the displacement field typedef DeformationFieldType FieldType; typename ImageType::Pointer sfield=ImageType::New(); sfield->SetSpacing( field->GetSpacing() ); sfield->SetOrigin( field->GetOrigin() ); sfield->SetDirection( field->GetDirection() ); sfield->SetLargestPossibleRegion(field->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(field->GetRequestedRegion() ); sfield->SetBufferedRegion( field->GetBufferedRegion() ); sfield->Allocate(); typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator vfIter( field, field->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { VectorType v1=vfIter.Get(); sfield->SetPixel(vfIter.GetIndex(),v1[index]); } return sfield; } ImagePointer SubsampleImage( ImagePointer, RealType , typename ImageType::PointType outputOrigin, typename ImageType::DirectionType outputDirection, AffineTransformPointer aff = NULL); DeformationFieldPointer SubsampleField( DeformationFieldPointer field, typename ImageType::SizeType targetSize, typename ImageType::SpacingType targetSpacing ) { std::cout << "FIXME -- NOT DONE CORRECTLY " << std::endl; std::cout << "FIXME -- NOT DONE CORRECTLY " << std::endl; std::cout << "FIXME -- NOT DONE CORRECTLY " << std::endl; std::cout << "FIXME -- NOT DONE CORRECTLY " << std::endl; std::cout << " SUBSAM FIELD SUBSAM FIELD SUBSAM FIELD " << std::endl; typename DeformationFieldType::Pointer sfield=DeformationFieldType::New(); for (unsigned int i=0; i < ImageDimension; i++) { typename ImageType::Pointer precomp=this->GetVectorComponent(field,i); typename ImageType::Pointer comp=this->SubsampleImage(precomp,targetSize,targetSpacing); if ( i==0 ) { sfield->SetSpacing( comp->GetSpacing() ); sfield->SetOrigin( comp->GetOrigin() ); sfield->SetDirection( comp->GetDirection() ); sfield->SetLargestPossibleRegion(comp->GetLargestPossibleRegion() ); sfield->SetRequestedRegion(comp->GetRequestedRegion() ); sfield->SetBufferedRegion( comp->GetBufferedRegion() ); sfield->Allocate(); } typedef itk::ImageRegionIteratorWithIndex Iterator; typedef typename DeformationFieldType::PixelType VectorType; VectorType v1; VectorType zero; zero.Fill(0.0); Iterator vfIter( sfield, sfield->GetLargestPossibleRegion() ); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter) { v1=vfIter.Get(); v1[i]=comp->GetPixel(vfIter.GetIndex()); vfIter.Set(v1); } } return sfield; } PointSetPointer WarpMultiTransform(ImagePointer referenceimage, ImagePointer movingImage, PointSetPointer movingpoints, AffineTransformPointer aff , DeformationFieldPointer totalField, bool doinverse , AffineTransformPointer fixedaff ) { if (!movingpoints) { std::cout << " NULL POINTS " << std::endl; return NULL; } AffineTransformPointer affinverse=NULL; if (aff) { affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } AffineTransformPointer fixedaffinverse=NULL; if (fixedaff) { fixedaffinverse=AffineTransformType::New(); fixedaff->GetInverse(fixedaffinverse); } typedef itk::WarpImageMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(movingImage); warper->SetEdgePaddingValue( 0); warper->SetSmoothScale(1); if (!doinverse) { if (totalField) warper->PushBackDeformationFieldTransform(totalField); if (fixedaff) warper->PushBackAffineTransform(fixedaff); else if (aff) warper->PushBackAffineTransform(aff); } else { if (aff) warper->PushBackAffineTransform( affinverse ); else if (fixedaff) warper->PushBackAffineTransform(fixedaffinverse); if (totalField) warper->PushBackDeformationFieldTransform(totalField); } warper->SetOutputOrigin(referenceimage->GetOrigin()); typename ImageType::SizeType size=referenceimage->GetLargestPossibleRegion().GetSize(); if (totalField) size=totalField->GetLargestPossibleRegion().GetSize(); warper->SetOutputSize(size); typename ImageType::SpacingType spacing=referenceimage->GetSpacing(); if (totalField) spacing=totalField->GetSpacing(); warper->SetOutputSpacing(spacing); warper->SetOutputDirection(referenceimage->GetDirection()); totalField->SetOrigin(referenceimage->GetOrigin() ); totalField->SetDirection(referenceimage->GetDirection() ); // warper->Update(); // std::cout << " updated in point warp " << std::endl; PointSetPointer outputMesh = PointSetType::New(); unsigned long count = 0; unsigned long sz1 = movingpoints->GetNumberOfPoints(); if (this->m_Debug) std::cout << " BEFORE # points " << sz1 << std::endl; for (unsigned long ii=0; iiGetPoint(ii,&point); movingpoints->GetPointData(ii,&label); // convert pointtype to imagepointtype ImagePointType pt,wpt; for (unsigned int jj=0; jjMultiTransformSinglePoint(pt,wpt); if (bisinside) { for (unsigned int jj=0; jjSetPointData( count, label ); outputMesh->SetPoint( count, wpoint ); // if (ii % 100 == 0) std::cout << " pt " << pt << " wpt " << wpt << std::endl; count++; } } if (this->m_Debug) std::cout << " AFTER # points " << count << std::endl; // if (count != sz1 ) std::cout << " WARNING: POINTS ARE MAPPING OUT OF IMAGE DOMAIN " << 1.0 - (float) count/(float)(sz1+1) << std::endl; return outputMesh; } ImagePointer WarpMultiTransform( ImagePointer referenceimage, ImagePointer movingImage, AffineTransformPointer aff , DeformationFieldPointer totalField, bool doinverse , AffineTransformPointer fixedaff ) { typedef typename ImageType::DirectionType DirectionType; DirectionType rdirection=referenceimage->GetDirection(); DirectionType mdirection=movingImage->GetDirection(); AffineTransformPointer affinverse=NULL; if (aff) { affinverse=AffineTransformType::New(); aff->GetInverse(affinverse); } AffineTransformPointer fixedaffinverse=NULL; if (fixedaff) { fixedaffinverse=AffineTransformType::New(); fixedaff->GetInverse(fixedaffinverse); } DirectionType iddir; iddir.Fill(0); for (unsigned int i=0;i InterpolatorType1; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; typedef itk::BSplineInterpolateImageFunction InterpolatorType3; typename InterpolatorType1::Pointer interp1 = InterpolatorType1::New(); typename InterpolatorType2::Pointer interpnn = InterpolatorType2::New(); typename InterpolatorType3::Pointer interpcu = InterpolatorType3::New(); this->m_UseMulti=true; if (!this->m_UseMulti){ ImagePointer wmimage = this->SubsampleImage(movingImage , this->m_ScaleFactor , movingImage->GetOrigin() , movingImage->GetDirection() , aff ); typedef itk::WarpImageFilter WarperType; typename WarperType::Pointer warper; warper = WarperType::New(); warper->SetInput( wmimage); warper->SetDeformationField(totalField); warper->SetOutputSpacing(totalField->GetSpacing()); warper->SetOutputOrigin(totalField->GetOrigin()); warper->SetInterpolator(interp1); if (this->m_UseNN) warper->SetInterpolator(interpnn); if (this->m_UseBSplineInterpolation) warper->SetInterpolator(interpcu); // warper->SetOutputSize(this->m_CurrentDomainSize); // warper->SetEdgePaddingValue( 0 ); warper->Update(); return warper->GetOutput(); } typedef itk::WarpImageMultiTransformFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); warper->SetInput(movingImage); warper->SetEdgePaddingValue( 0); warper->SetSmoothScale(1); warper->SetInterpolator(interp1); if (this->m_UseNN) warper->SetInterpolator(interpnn); if (!doinverse) { if (totalField) warper->PushBackDeformationFieldTransform(totalField); if (fixedaff) warper->PushBackAffineTransform(fixedaff); else if (aff) warper->PushBackAffineTransform(aff); } else { if (aff) warper->PushBackAffineTransform( affinverse ); else if (fixedaff) warper->PushBackAffineTransform(fixedaffinverse); if (totalField) warper->PushBackDeformationFieldTransform(totalField); } warper->SetOutputOrigin(referenceimage->GetOrigin()); typename ImageType::SizeType size=referenceimage->GetLargestPossibleRegion().GetSize(); if (totalField) size=totalField->GetLargestPossibleRegion().GetSize(); warper->SetOutputSize(size); typename ImageType::SpacingType spacing=referenceimage->GetSpacing(); if (totalField) spacing=totalField->GetSpacing(); warper->SetOutputSpacing(spacing); warper->SetOutputDirection(referenceimage->GetDirection()); totalField->SetOrigin(referenceimage->GetOrigin() ); totalField->SetDirection(referenceimage->GetDirection() ); warper->Update(); if (this->m_Debug){ std::cout << " updated ok -- warped image output size " << warper->GetOutput()->GetLargestPossibleRegion().GetSize() << " requested size " << totalField->GetLargestPossibleRegion().GetSize() << std::endl; } typename ImageType::Pointer outimg=warper->GetOutput(); return outimg; } ImagePointer SmoothImageToScale(ImagePointer image , float scalingFactor ) { typename ImageType::SpacingType inputSpacing = image->GetSpacing(); typename ImageType::RegionType::SizeType inputSize = image->GetRequestedRegion().GetSize(); typename ImageType::SpacingType outputSpacing; typename ImageType::RegionType::SizeType outputSize; RealType minimumSpacing = inputSpacing.GetVnlVector().min_value(); // RealType maximumSpacing = inputSpacing.GetVnlVector().max_value(); for ( unsigned int d = 0; d < Dimension; d++ ) { RealType scaling = vnl_math_min( scalingFactor * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); typedef RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); float sig = (outputSpacing[d]/inputSpacing[d]-1.0)*0.2;///(float)ImageDimension; smoother->SetSigma(sig ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); image = smoother->GetOutput(); } } image=this->NormalizeImage(image); return image; } typename ANTSImageRegistrationOptimizer::DeformationFieldPointer IntegrateConstantVelocity(DeformationFieldPointer totalField, unsigned int ntimesteps, float timeweight); /** Base optimization functions */ // AffineTransformPointer AffineOptimization(AffineTransformPointer &aff_init, OptAffine &affine_opt); // {return NULL;} AffineTransformPointer AffineOptimization(OptAffineType &affine_opt); // {return NULL;} std::string GetTransformationModel( ) { return this->m_TransformationModel; } void SetTransformationModel( std::string s) { this->m_TransformationModel=s; std::cout << " Requested Transformation Model: " << this->m_TransformationModel << " : Using " << std::endl; if ( this->m_TransformationModel == std::string("Elast") ) { std::cout << "Elastic model for transformation. " << std::endl; } else if ( this->m_TransformationModel == std::string("SyN") ) { std::cout << "SyN diffeomorphic model for transformation. " << std::endl; } else if ( this->m_TransformationModel == std::string("GreedyExp") ) { std::cout << "Greedy Exp Diff model for transformation. Similar to Diffeomorphic Demons. Params same as Exp model. " << std::endl; this->m_TransformationModel=std::string("GreedyExp"); } else { std::cout << "Exp Diff model for transformation. " << std::endl; this->m_TransformationModel=std::string("Exp"); } } void SetUpParameters() { /** Univariate Deformable Mapping */ // set up parameters for deformation restriction std::string temp=this->m_Parser->GetOption( "Restrict-Deformation" )->GetValue(); this->m_RestrictDeformation = this->m_Parser->template ConvertVector(temp); if ( this->m_RestrictDeformation.size() != ImageDimension ) { std::cout <<" You input a vector of size : " << this->m_RestrictDeformation.size() << " for --Restrict-Deformation. The vector length does not match the image dimension. Ignoring. " << std::endl; for (unsigned int jj=0; jjm_RestrictDeformation.size(); jj++ ) this->m_RestrictDeformation[jj]=0; } // set up max iterations per level temp=this->m_Parser->GetOption( "number-of-iterations" )->GetValue(); this->m_Iterations = this->m_Parser->template ConvertVector(temp); this->SetNumberOfLevels(this->m_Iterations.size()); this->m_UseROI=false; if ( typename OptionType::Pointer option = this->m_Parser->GetOption( "roi" ) ) { temp=this->m_Parser->GetOption( "roi" )->GetValue(); this->m_RoiNumbers = this->m_Parser->template ConvertVector(temp); if ( temp.length() > 3 ) this->m_UseROI=true; } typename ParserType::OptionType::Pointer oOption = this->m_Parser->GetOption( "output-naming" ); this->m_OutputNamingConvention=oOption->GetValue(); typename ParserType::OptionType::Pointer thicknessOption = this->m_Parser->GetOption( "geodesic" ); if( thicknessOption->GetValue() == "true" || thicknessOption->GetValue() == "1" ) { this->m_ComputeThickness=1; this->m_SyNFullTime=2; }// asymm forces else if( thicknessOption->GetValue() == "2" ) { this->m_ComputeThickness=1; this->m_SyNFullTime=1; } // symmetric forces else this->m_ComputeThickness=0; // not full time varying stuff /** * Get transformation model and associated parameters */ typename ParserType::OptionType::Pointer transformOption = this->m_Parser->GetOption( "transformation-model" ); this->SetTransformationModel( transformOption->GetValue() ); if ( transformOption->GetNumberOfParameters() >= 1 ) { std::string parameter = transformOption->GetParameter( 0, 0 ); float temp=this->m_Parser->template Convert( parameter ); this->m_Gradstep = temp; this->m_GradstepAltered = temp; } else { this->m_Gradstep=0.5; this->m_GradstepAltered=0.5; } if ( transformOption->GetNumberOfParameters() >= 2 ) { std::string parameter = transformOption->GetParameter( 0, 1 ); this->m_NTimeSteps = this->m_Parser->template Convert( parameter ); } else this->m_NTimeSteps=1; if ( transformOption->GetNumberOfParameters() >= 3 ) { std::string parameter = transformOption->GetParameter( 0, 2 ); this->m_DeltaTime = this->m_Parser->template Convert( parameter ); if (this->m_DeltaTime > 1) this->m_DeltaTime=1; if (this->m_DeltaTime <= 0) this->m_DeltaTime=0.001; std::cout <<" set DT " << this->m_DeltaTime << std::endl; this->m_SyNType=1; } else this->m_DeltaTime=0.1; // if ( transformOption->GetNumberOfParameters() >= 3 ) // { // std::string parameter = transformOption->GetParameter( 0, 2 ); // this->m_SymmetryType // = this->m_Parser->template Convert( parameter ); // } /** * Get regularization and associated parameters */ this->m_GradSmoothingparam = -1; this->m_TotalSmoothingparam = -1; this->m_GradSmoothingMeshSize.Fill( 0 ); this->m_TotalSmoothingMeshSize.Fill( 0 ); typename ParserType::OptionType::Pointer regularizationOption = this->m_Parser->GetOption( "regularization" ); if( regularizationOption->GetValue() == "Gauss" ) { if ( regularizationOption->GetNumberOfParameters() >= 1 ) { std::string parameter = regularizationOption->GetParameter( 0, 0 ); this->m_GradSmoothingparam = this->m_Parser->template Convert( parameter ); } else this->m_GradSmoothingparam=3; if ( regularizationOption->GetNumberOfParameters() >= 2 ) { std::string parameter = regularizationOption->GetParameter( 0, 1 ); this->m_TotalSmoothingparam = this->m_Parser->template Convert( parameter ); } else this->m_TotalSmoothingparam=0.5; if ( regularizationOption->GetNumberOfParameters() >= 3 ) { std::string parameter = regularizationOption->GetParameter( 0, 2 ); this->m_GaussianTruncation = this->m_Parser->template Convert( parameter ); } else this->m_GaussianTruncation = 256; std::cout <<" Grad Step " << this->m_Gradstep << " total-smoothing " << this->m_TotalSmoothingparam << " gradient-smoothing " << this->m_GradSmoothingparam << std::endl; } else if( ( regularizationOption->GetValue() ).find( "DMFFD" ) != std::string::npos ) { if ( regularizationOption->GetNumberOfParameters() >= 1 ) { std::string parameter = regularizationOption->GetParameter( 0, 0 ); if( parameter.find( "x" ) != std::string::npos ) { std::vector gradMeshSize = this->m_Parser->template ConvertVector( parameter ); for( unsigned int d = 0; d < ImageDimension; d++ ) { this->m_GradSmoothingMeshSize[d] = gradMeshSize[d]; } } else { this->m_GradSmoothingparam = this->m_Parser->template Convert( parameter ); } } else { this->m_GradSmoothingparam = 3.0; } if ( regularizationOption->GetNumberOfParameters() >= 2 ) { std::string parameter = regularizationOption->GetParameter( 0, 1 ); if( parameter.find( "x" ) != std::string::npos ) { std::vector totalMeshSize = this->m_Parser->template ConvertVector( parameter ); for( unsigned int d = 0; d < ImageDimension; d++ ) { this->m_TotalSmoothingMeshSize[d] = totalMeshSize[d]; } } else { this->m_TotalSmoothingparam = this->m_Parser->template Convert( parameter ); } } else { this->m_TotalSmoothingparam=0.5; } if ( regularizationOption->GetNumberOfParameters() >= 3 ) { std::string parameter = regularizationOption->GetParameter( 0, 2 ); this->m_BSplineFieldOrder = this->m_Parser->template Convert( parameter ); } else this->m_BSplineFieldOrder = 3; std::cout <<" Grad Step " << this->m_Gradstep << " total-smoothing " << this->m_TotalSmoothingparam << " gradient-smoothing " << this->m_GradSmoothingparam << " bspline-field-order " << this->m_BSplineFieldOrder << std::endl; } else { this->m_GradSmoothingparam=3; this->m_TotalSmoothingparam=0.5; std::cout <<" Default Regularization is Gaussian smoothing with : " << this->m_GradSmoothingparam << " & " << this->m_TotalSmoothingparam << std::endl; // itkExceptionMacro( "Invalid regularization: " << regularizationOption->GetValue() ); } } void ComputeMultiResolutionParameters(ImagePointer fixedImage ) { VectorType zero; zero.Fill(0); /** Compute scale factors */ this->m_FullDomainSpacing = fixedImage->GetSpacing(); this->m_FullDomainSize = fixedImage->GetRequestedRegion().GetSize(); this->m_CurrentDomainSpacing = fixedImage->GetSpacing(); this->m_CurrentDomainSize = fixedImage->GetRequestedRegion().GetSize(); this->m_CurrentDomainDirection=fixedImage->GetDirection(); this->m_FullDomainOrigin.Fill(0); this->m_CurrentDomainOrigin.Fill(0); /** alter the input size based on information gained from the ROI information - if available */ if (this->m_UseROI) { for (unsigned int ii=0; iim_FullDomainSize[ii]= (typename ImageType::SizeType::SizeValueType) this->m_RoiNumbers[ii+ImageDimension]; this->m_FullDomainOrigin[ii]=this->m_RoiNumbers[ii]; } std::cout << " ROI #s : size " << this->m_FullDomainSize << " orig " << this->m_FullDomainOrigin << std::endl; } RealType minimumSpacing = this->m_FullDomainSpacing.GetVnlVector().min_value(); // RealType maximumSpacing = this->m_FullDomainSpacing.GetVnlVector().max_value(); for ( unsigned int d = 0; d < Dimension; d++ ) { RealType scaling = vnl_math_min( this->m_ScaleFactor * minimumSpacing / this->m_FullDomainSpacing[d], static_cast( this->m_FullDomainSize[d] ) / 32.0 ); if (scaling < 1) scaling=1; this->m_CurrentDomainSpacing[d] = this->m_FullDomainSpacing[d] * scaling; this->m_CurrentDomainSize[d] = static_cast( this->m_FullDomainSpacing[d] *static_cast( this->m_FullDomainSize[d] ) / this->m_CurrentDomainSpacing[d] + 0.5 ); this->m_CurrentDomainOrigin[d] = static_cast( this->m_FullDomainSpacing[d] *static_cast( this->m_FullDomainOrigin[d] ) / this->m_CurrentDomainSpacing[d] + 0.5 ); } // this->m_Debug=true; if (this->m_Debug) std::cout << " outsize " << this->m_CurrentDomainSize << " curspc " << this->m_CurrentDomainSpacing << " fullspc " << this->m_FullDomainSpacing << " fullsz " << this->m_FullDomainSize << std::endl; // this->m_Debug=false; if (!this->m_DeformationField) {/*FIXME -- need initial deformation strategy */ this->m_DeformationField=DeformationFieldType::New(); this->m_DeformationField->SetSpacing( this->m_CurrentDomainSpacing); this->m_DeformationField->SetOrigin( fixedImage->GetOrigin() ); this->m_DeformationField->SetDirection( fixedImage->GetDirection() ); typename ImageType::RegionType region; region.SetSize( this->m_CurrentDomainSize); this->m_DeformationField->SetLargestPossibleRegion(region); this->m_DeformationField->SetRequestedRegion(region); this->m_DeformationField->SetBufferedRegion(region); this->m_DeformationField->Allocate(); this->m_DeformationField->FillBuffer(zero); std::cout << " allocated def field " << this->m_DeformationField->GetDirection() << std::endl; //exit(0); } else { this->m_DeformationField=this->ExpandField(this->m_DeformationField,this->m_CurrentDomainSpacing); if ( this->m_TimeVaryingVelocity ) this->ExpandVelocity(); } } ImagePointer NormalizeImage( ImagePointer image) { typedef itk::MinimumMaximumImageFilter MinMaxFilterType; typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New(); minMaxFilter->SetInput( image ); minMaxFilter->Update(); double min = minMaxFilter->GetMinimum(); double shift = -1.0 * static_cast( min ); double scale = static_cast( minMaxFilter->GetMaximum() ); scale += shift; scale = 1.0 / scale; typedef itk::ShiftScaleImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( image ); filter->SetShift( shift ); filter->SetScale( scale ); filter->Update(); return filter->GetOutput(); } void DeformableOptimization() { DeformationFieldPointer updateField = NULL; this->SetUpParameters(); typename ImageType::SpacingType spacing; VectorType zero; zero.Fill(0); std::cout << " setting N-TimeSteps = " << this->m_NTimeSteps << " trunc " << this->m_GaussianTruncation << std::endl; unsigned int maxits=0; for ( unsigned int currentLevel = 0; currentLevel < this->m_NumberOfLevels; currentLevel++ ) if ( this->m_Iterations[currentLevel] > maxits) maxits=this->m_Iterations[currentLevel]; if (maxits == 0) { this->m_DeformationField=NULL; this->m_InverseDeformationField=NULL; // this->ComputeMultiResolutionParameters(this->m_SimilarityMetrics[0]->GetFixedImage()); return; } /* this is a hack to force univariate mappings in the future, we will re-cast this framework s.t. multivariate images can be used */ unsigned int numberOfMetrics=this->m_SimilarityMetrics.size(); for ( unsigned int metricCount = 1; metricCount < numberOfMetrics; metricCount++) { this->m_SimilarityMetrics[metricCount]->GetFixedImage( )->SetOrigin( this->m_SimilarityMetrics[0]->GetFixedImage()->GetOrigin()); this->m_SimilarityMetrics[metricCount]->GetFixedImage( )->SetDirection( this->m_SimilarityMetrics[0]->GetFixedImage()->GetDirection()); this->m_SimilarityMetrics[metricCount]->GetMovingImage( )->SetOrigin( this->m_SimilarityMetrics[0]->GetMovingImage()->GetOrigin()); this->m_SimilarityMetrics[metricCount]->GetMovingImage( )->SetDirection( this->m_SimilarityMetrics[0]->GetMovingImage()->GetDirection()); } /* here, we assign all point set pointers to any single non-null point-set pointer */ for (unsigned int metricCount=0; metricCount < numberOfMetrics; metricCount++) { for (unsigned int metricCount2=0; metricCount2 < numberOfMetrics; metricCount2++) { if (this->m_SimilarityMetrics[metricCount]->GetFixedPointSet()) this->m_SimilarityMetrics[metricCount2]->SetFixedPointSet(this->m_SimilarityMetrics[metricCount]->GetFixedPointSet()); if (this->m_SimilarityMetrics[metricCount]->GetMovingPointSet()) this->m_SimilarityMetrics[metricCount2]->SetMovingPointSet(this->m_SimilarityMetrics[metricCount]->GetMovingPointSet()); } } this->m_SmoothFixedImages.resize(numberOfMetrics,NULL); this->m_SmoothMovingImages.resize(numberOfMetrics,NULL); for ( unsigned int currentLevel = 0; currentLevel < this->m_NumberOfLevels; currentLevel++ ) { this->m_CurrentLevel = currentLevel; typedef Vector ProfilePointDataType; typedef Image CurveType; typedef PointSet EnergyProfileType; typedef typename EnergyProfileType::PointType ProfilePointType; std::vector energyProfiles; energyProfiles.resize( numberOfMetrics ); for( unsigned int qq = 0; qq < numberOfMetrics; qq++ ) { energyProfiles[qq] = EnergyProfileType::New(); energyProfiles[qq]->Initialize(); } ImagePointer fixedImage; ImagePointer movingImage; this->m_GradstepAltered=this->m_Gradstep; this->m_ScaleFactor = pow( 2.0, (int)static_cast( this->m_NumberOfLevels-currentLevel-1 ) ); std::cout << " this->m_ScaleFactor " << this->m_ScaleFactor << " nlev " << this->m_NumberOfLevels << " curl " << currentLevel << std::endl; /** FIXME -- here we assume the metrics all have the same image */ fixedImage = this->m_SimilarityMetrics[0]->GetFixedImage(); movingImage = this->m_SimilarityMetrics[0]->GetMovingImage(); spacing=fixedImage->GetSpacing(); this->ComputeMultiResolutionParameters(fixedImage); std::cout << " Its at this level " << this->m_Iterations[currentLevel] << std::endl; /* generate smoothed images for all metrics */ for ( unsigned int metricCount=0; metricCount < numberOfMetrics; metricCount++) { this->m_SmoothFixedImages[metricCount] = this->SmoothImageToScale(this->m_SimilarityMetrics[metricCount]->GetFixedImage(), this->m_ScaleFactor); this->m_SmoothMovingImages[metricCount] = this->SmoothImageToScale(this->m_SimilarityMetrics[metricCount]->GetMovingImage(), this->m_ScaleFactor); } fixedImage=this->m_SmoothFixedImages[0]; movingImage=this->m_SmoothMovingImages[0]; unsigned int nmet=this->m_SimilarityMetrics.size(); this->m_LastEnergy.resize(nmet,1.e12); this->m_Energy.resize(nmet,1.e9); this->m_EnergyBad.resize(nmet,0); bool converged=false; this->m_CurrentIteration=0; if (this->GetTransformationModel() != std::string("SyN")) this->m_FixedImageAffineTransform=NULL; while (!converged) { for (unsigned int metricCount=0; metricCount < numberOfMetrics; metricCount++) this->m_SimilarityMetrics[metricCount]->GetMetric()->SetIterations(this->m_CurrentIteration); if ( this->GetTransformationModel() == std::string("Elast")) { if (this->m_Iterations[currentLevel] > 0) this->ElasticRegistrationUpdate(fixedImage, movingImage); } else if (this->GetTransformationModel() == std::string("SyN")) { if ( currentLevel > 0 ) { this->m_SyNF=this->ExpandField(this->m_SyNF,this->m_CurrentDomainSpacing); this->m_SyNFInv=this->ExpandField(this->m_SyNFInv,this->m_CurrentDomainSpacing); this->m_SyNM=this->ExpandField(this->m_SyNM,this->m_CurrentDomainSpacing); this->m_SyNMInv=this->ExpandField(this->m_SyNMInv,this->m_CurrentDomainSpacing); } if(this->m_Iterations[currentLevel] > 0) { if (this->m_SyNType && this->m_ComputeThickness ) this->DiReCTUpdate(fixedImage, movingImage, this->m_SimilarityMetrics[0]->GetFixedPointSet(), this->m_SimilarityMetrics[0]->GetMovingPointSet() ); else if (this->m_SyNType) this->SyNTVRegistrationUpdate(fixedImage, movingImage, this->m_SimilarityMetrics[0]->GetFixedPointSet(), this->m_SimilarityMetrics[0]->GetMovingPointSet() ); else this->SyNRegistrationUpdate(fixedImage, movingImage, this->m_SimilarityMetrics[0]->GetFixedPointSet(), this->m_SimilarityMetrics[0]->GetMovingPointSet() ); } else if (this->m_SyNType) this->UpdateTimeVaryingVelocityFieldWithSyNFandSyNM( ); // this->CopyOrAddToVelocityField( this->m_SyNF, 0 , false); } else if (this->GetTransformationModel() == std::string("Exp")) { if(this->m_Iterations[currentLevel] > 0) { this->DiffeomorphicExpRegistrationUpdate(fixedImage, movingImage,this->m_SimilarityMetrics[0]->GetFixedPointSet(), this->m_SimilarityMetrics[0]->GetMovingPointSet() ); } } else if (this->GetTransformationModel() == std::string("GreedyExp")) { if(this->m_Iterations[currentLevel] > 0) { this->GreedyExpRegistrationUpdate(fixedImage, movingImage,this->m_SimilarityMetrics[0]->GetFixedPointSet(), this->m_SimilarityMetrics[0]->GetMovingPointSet() ); } } this->m_CurrentIteration++; /** * This is where we track the energy profile to check for convergence. */ for( unsigned int qq = 0; qq < numberOfMetrics; qq++ ) { ProfilePointType point; point[0] = this->m_CurrentIteration-1; ProfilePointDataType energy; energy[0] = this->m_Energy[qq]; energyProfiles[qq]->SetPoint( this->m_CurrentIteration-1, point ); energyProfiles[qq]->SetPointData( this->m_CurrentIteration-1, energy ); } /** * If there are a sufficent number of iterations, fit a quadratic * single B-spline span to the number of energy profile points * in the first metric. To test convergence, evaluate the derivative * at the end of the profile to determine if >= 0. To change to a * window of the energy profile, simply change the origin (assuming that * the desired window will start at the user-specified origin and * end at the current iteration). */ unsigned int domtar=12; if( this->m_CurrentIteration > domtar ) { typedef BSplineScatteredDataPointSetToImageFilter BSplinerType; typename BSplinerType::Pointer bspliner = BSplinerType::New(); typename CurveType::PointType origin; unsigned int domainorigin=0; unsigned int domainsize=this->m_CurrentIteration - domainorigin; if ( this->m_CurrentIteration > domtar ) { domainsize=domtar; domainorigin=this->m_CurrentIteration-domainsize; } origin.Fill( domainorigin ); typename CurveType::SizeType size; size.Fill( domainsize ); typename CurveType::SpacingType spacing; spacing.Fill( 1 ); typename EnergyProfileType::Pointer energyProfileWindow = EnergyProfileType::New(); energyProfileWindow->Initialize(); unsigned int windowBegin = static_cast( origin[0] ); float totale=0; for( unsigned int qq = windowBegin; qq < this->m_CurrentIteration; qq++ ) { ProfilePointType point; point[0] = qq; ProfilePointDataType energy; energy.Fill( 0 ); energyProfiles[0]->GetPointData( qq, &energy ); totale+=energy[0]; energyProfileWindow->SetPoint( qq-windowBegin, point ); energyProfileWindow->SetPointData( qq-windowBegin, energy ); } // std::cout <<" totale " << totale << std::endl; if (totale > 0) totale*=(-1.0); for( unsigned int qq = windowBegin; qq < this->m_CurrentIteration; qq++ ) { ProfilePointDataType energy; energy.Fill(0); energyProfiles[0]->GetPointData( qq, &energy ); energyProfileWindow->SetPointData( qq-windowBegin, energy/totale); } bspliner->SetInput( energyProfileWindow ); bspliner->SetOrigin( origin ); bspliner->SetSpacing( spacing ); bspliner->SetSize( size ); bspliner->SetNumberOfLevels( 1 ); unsigned int order=1; bspliner->SetSplineOrder( order ); typename BSplinerType::ArrayType ncps; ncps.Fill( order+1); // single span, order = 2 bspliner->SetNumberOfControlPoints( ncps ); bspliner->Update(); ProfilePointType endPoint; endPoint[0] = static_cast( this->m_CurrentIteration-domainsize*0.5 ); typename BSplinerType::GradientType gradient; gradient.Fill(0); bspliner->EvaluateGradientAtPoint( endPoint, gradient ); this->m_ESlope=gradient[0][0] ; if ( this->m_ESlope < 0.0001 && this->m_CurrentIteration > domtar) converged=true; std::cout << " E-Slope " << this->m_ESlope;//<< std::endl; } for ( unsigned int qq=0; qq < this->m_Energy.size(); qq++ ) { if ( qq==0 ) std::cout << " iteration " << this->m_CurrentIteration; std::cout << " energy " << qq << " : " << this->m_Energy[qq];// << " Last " << this->m_LastEnergy[qq]; if (this->m_LastEnergy[qq] < this->m_Energy[qq]) { this->m_EnergyBad[qq]++; } } unsigned int numbade=0; for (unsigned int qq=0; qqm_Energy.size(); qq++) if (this->m_CurrentIteration <= 1) this->m_EnergyBad[qq] = 0; else if ( this->m_EnergyBad[qq] > 1 ) numbade += this->m_EnergyBad[qq]; //if ( this->m_EnergyBad[0] > 2) // { // this->m_GradstepAltered*=0.8; // std::cout <<" reducing gradstep " << this->m_GradstepAltered; // this->m_EnergyBad[this->m_Energy.size()-1]=0; // } std::cout << std::endl; if (this->m_CurrentIteration >= this->m_Iterations[currentLevel] )converged = true; // || this->m_EnergyBad[0] >= 6 ) // if ( converged && this->m_CurrentIteration >= this->m_Iterations[currentLevel] ) std::cout <<" tired convergence: reached max iterations " << std::endl; else if (converged) { std::cout << " Converged due to oscillation in optimization "; for (unsigned int qq=0; qqm_Energy.size(); qq++) std::cout<< " metric " << qq << " bad " << this->m_EnergyBad[qq] << " " ; std::cout <GetTransformationModel() == std::string("SyN")) { // float timestep=1.0/(float)this->m_NTimeSteps; // unsigned int nts=this->m_NTimeSteps; if (this->m_SyNType) { // this->m_SyNFInv = this->IntegrateConstantVelocity(this->m_SyNF, nts, timestep*(-1.)); // this->m_SyNMInv = this->IntegrateConstantVelocity(this->m_SyNM, nts, timestep*(-1.)); // this->m_SyNF= this->IntegrateConstantVelocity(this->m_SyNF, nts, timestep); // this->m_SyNM= this->IntegrateConstantVelocity(this->m_SyNM, // nts, timestep); // DeformationFieldPointer fdiffmap = this->IntegrateVelocity(0,0.5); // this->m_SyNFInv = this->IntegrateVelocity(0.5,0); // DeformationFieldPointer mdiffmap = this->IntegrateVelocity(0.5,1); // this->m_SyNMInv = this->IntegrateVelocity(1,0.5); // this->m_SyNM=this->CopyDeformationField(mdiffmap); // this->m_SyNF=this->CopyDeformationField(fdiffmap); this->m_DeformationField = this->IntegrateVelocity(0,1); // ImagePointer wmimage= this->WarpMultiTransform( this->m_SmoothFixedImages[0],this->m_SmoothMovingImages[0], this->m_AffineTransform, this->m_DeformationField, false , this->m_ScaleFactor ); this->m_InverseDeformationField=this->IntegrateVelocity(1,0); } else { this->m_InverseDeformationField=this->CopyDeformationField( this->m_SyNM); this->ComposeDiffs(this->m_SyNF,this->m_SyNMInv,this->m_DeformationField,1); this->ComposeDiffs(this->m_SyNM,this->m_SyNFInv,this->m_InverseDeformationField,1); } } else if (this->GetTransformationModel() == std::string("Exp")) { DeformationFieldPointer diffmap = this->IntegrateConstantVelocity( this->m_DeformationField, (unsigned int)this->m_NTimeSteps , 1 ); // 1.0/ (float)this->m_NTimeSteps); DeformationFieldPointer invdiffmap = this->IntegrateConstantVelocity(this->m_DeformationField,(unsigned int) this->m_NTimeSteps, -1 ); // -1.0/(float)this->m_NTimeSteps); this->m_InverseDeformationField=invdiffmap; this->m_DeformationField=diffmap; AffineTransformPointer invaff =NULL; if (this->m_AffineTransform) { invaff=AffineTransformType::New(); this->m_AffineTransform->GetInverse(invaff); if (this->m_Debug) std::cout << " ??????invaff " << this->m_AffineTransform << std::endl << std::endl; if (this->m_Debug) std::cout << " invaff?????? " << invaff << std::endl << std::endl; } } else if (this->GetTransformationModel() == std::string("GreedyExp")) { DeformationFieldPointer diffmap = this->m_DeformationField; this->m_InverseDeformationField=NULL; this->m_DeformationField=diffmap; AffineTransformPointer invaff =NULL; if (this->m_AffineTransform) { invaff=AffineTransformType::New(); this->m_AffineTransform->GetInverse(invaff); if (this->m_Debug) std::cout << " ??????invaff " << this->m_AffineTransform << std::endl << std::endl; if (this->m_Debug) std::cout << " invaff?????? " << invaff << std::endl << std::endl; } } this->m_DeformationField->SetOrigin( this->m_SimilarityMetrics[0]->GetFixedImage()->GetOrigin() ); this->m_DeformationField->SetDirection( this->m_SimilarityMetrics[0]->GetFixedImage()->GetDirection() ); if (this->m_InverseDeformationField) { this->m_InverseDeformationField->SetOrigin( this->m_SimilarityMetrics[0]->GetFixedImage()->GetOrigin() ); this->m_InverseDeformationField->SetDirection( this->m_SimilarityMetrics[0]->GetFixedImage()->GetDirection() ); } if ( this->m_TimeVaryingVelocity ) { std::string outname=localANTSGetFilePrefix(this->m_OutputNamingConvention.c_str())+std::string("velocity.mhd"); typename itk::ImageFileWriter::Pointer writer = itk::ImageFileWriter::New(); writer->SetFileName(outname.c_str()); writer->SetInput( this->m_TimeVaryingVelocity); writer->UpdateLargestPossibleRegion(); // writer->Write(); std::cout << " write tv field " << outname << std::endl; // WriteImage( this->m_TimeVaryingVelocity , outname.c_str()); } } void DiffeomorphicExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage,PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); void GreedyExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage,PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); void SyNRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); void SyNExpRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); void SyNTVRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); void DiReCTUpdate(ImagePointer fixedImage, ImagePointer movingImage, PointSetPointer fpoints=NULL, PointSetPointer mpoints=NULL); /** allows one to copy or add a field to a time index within the velocity * field */ void UpdateTimeVaryingVelocityFieldWithSyNFandSyNM( ); void CopyOrAddToVelocityField( TimeVaryingVelocityFieldPointer velocity, DeformationFieldPointer update1, DeformationFieldPointer update2 , float timept); //void CopyOrAddToVelocityField( DeformationFieldPointer update, unsigned int timeindex, bool CopyIsTrueOtherwiseAdd); void ElasticRegistrationUpdate(ImagePointer fixedImage, ImagePointer movingImage) { typename ImageType::SpacingType spacing; VectorType zero; zero.Fill(0); DeformationFieldPointer updateField; updateField=this->ComputeUpdateField(this->m_DeformationField,NULL,NULL,NULL,NULL); typedef ImageRegionIteratorWithIndex Iterator; Iterator dIter(this->m_DeformationField,this->m_DeformationField->GetLargestPossibleRegion() ); for( dIter.GoToBegin(); !dIter.IsAtEnd(); ++dIter ) { typename ImageType::IndexType index=dIter.GetIndex(); VectorType vec=updateField->GetPixel(index); dIter.Set(dIter.Get()+vec*this->m_Gradstep); } if (this->m_Debug) { std::cout << " updated elast " << " up-sz " << updateField->GetLargestPossibleRegion() << std::endl; std::cout << " t-sz " << this->m_DeformationField->GetLargestPossibleRegion() << std::endl; } this->SmoothDeformationField(this->m_DeformationField, false); return; } ImagePointer WarpImageBackward( ImagePointer image, DeformationFieldPointer field ) { typedef WarpImageFilter WarperType; typename WarperType::Pointer warper = WarperType::New(); typedef NearestNeighborInterpolateImageFunction InterpolatorType; warper->SetInput(image); warper->SetDeformationField( field ); warper->SetEdgePaddingValue( 0); warper->SetOutputSpacing(field->GetSpacing() ); warper->SetOutputOrigin( field->GetOrigin() ); warper->Update(); return warper->GetOutput(); } void ComposeDiffs(DeformationFieldPointer fieldtowarpby, DeformationFieldPointer field, DeformationFieldPointer fieldout, float sign); void SetSimilarityMetrics( SimilarityMetricListType S ) {this->m_SimilarityMetrics=S;} void SetFixedPointSet( PointSetPointer p ) { this->m_FixedPointSet=p; } void SetMovingPointSet( PointSetPointer p ) { this->m_MovingPointSet=p; } void SetDeltaTime( float t) {this->m_DeltaTime=t; } float InvertField(DeformationFieldPointer field, DeformationFieldPointer inverseField, float weight=1.0, float toler=0.1, int maxiter=20, bool print = false) { float mytoler=toler; unsigned int mymaxiter=maxiter; typename ParserType::OptionType::Pointer thicknessOption = this->m_Parser->GetOption( "go-faster" ); if( thicknessOption->GetValue() == "true" || thicknessOption->GetValue() == "1" ) { mytoler=0.5; maxiter=12; } VectorType zero; zero.Fill(0); // if (this->GetElapsedIterations() < 2 ) maxiter=10; ImagePointer floatImage = ImageType::New(); floatImage->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); floatImage->SetBufferedRegion( field->GetLargestPossibleRegion().GetSize() ); floatImage->SetSpacing(field->GetSpacing()); floatImage->SetOrigin(field->GetOrigin()); floatImage->SetDirection(field->GetDirection()); floatImage->Allocate(); typedef typename DeformationFieldType::PixelType VectorType; typedef typename DeformationFieldType::IndexType IndexType; typedef typename VectorType::ValueType ScalarType; typedef ImageRegionIteratorWithIndex Iterator; DeformationFieldPointer lagrangianInitCond=DeformationFieldType::New(); lagrangianInitCond->SetSpacing( field->GetSpacing() ); lagrangianInitCond->SetOrigin( field->GetOrigin() ); lagrangianInitCond->SetDirection( field->GetDirection() ); lagrangianInitCond->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); lagrangianInitCond->SetRequestedRegion(field->GetRequestedRegion() ); lagrangianInitCond->SetBufferedRegion( field->GetLargestPossibleRegion() ); lagrangianInitCond->Allocate(); DeformationFieldPointer eulerianInitCond=DeformationFieldType::New(); eulerianInitCond->SetSpacing( field->GetSpacing() ); eulerianInitCond->SetOrigin( field->GetOrigin() ); eulerianInitCond->SetDirection( field->GetDirection() ); eulerianInitCond->SetLargestPossibleRegion( field->GetLargestPossibleRegion() ); eulerianInitCond->SetRequestedRegion(field->GetRequestedRegion() ); eulerianInitCond->SetBufferedRegion( field->GetLargestPossibleRegion() ); eulerianInitCond->Allocate(); typedef typename DeformationFieldType::SizeType SizeType; SizeType size=field->GetLargestPossibleRegion().GetSize(); typename ImageType::SpacingType spacing = field->GetSpacing(); float subpix=0.0; unsigned long npix=1; for (int j=0; jGetLargestPossibleRegion().GetSize()[j]; } subpix=pow((float)ImageDimension,(float)ImageDimension)*0.5; float max=0; Iterator iter( field, field->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { IndexType index=iter.GetIndex(); VectorType vec1=iter.Get(); VectorType newvec=vec1*weight; lagrangianInitCond->SetPixel(index,newvec); float mag=0; for (unsigned int jj=0; jj max) max=mag; } eulerianInitCond->FillBuffer(zero); float scale=(1.)/max; if (scale > 1.) scale=1.0; // float initscale=scale; Iterator vfIter( inverseField, inverseField->GetLargestPossibleRegion() ); // int num=10; // for (int its=0; its subpix && meandif > subpix*0.1 && badct < 2 )//&& ct < 20 && denergy > 0) // float length=0.0; float stepl=2.; float lastdifmag=0; float epsilon = (float)size[0]/256; if (epsilon > 1) epsilon = 1; while ( difmag > mytoler && ct < mymaxiter && meandif > 0.001) { denergy=laste-difmag;//meandif; denergy2=laste-meandif; laste=difmag;//meandif; meandif=0.0; //this field says what position the eulerian field should contain in the E domain this->ComposeDiffs(inverseField,lagrangianInitCond, eulerianInitCond, 1); difmag=0.0; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { IndexType index=vfIter.GetIndex(); VectorType update=eulerianInitCond->GetPixel(index); float mag=0; for (int j=0; j difmag) {difmag=mag; } // if (mag < 1.e-2) update.Fill(0); eulerianInitCond->SetPixel(index,update); floatImage->SetPixel(index,mag); } meandif/=(float)npix; if (ct == 0) epsilon = 0.75; else epsilon=0.5; stepl=difmag*epsilon; for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { float val = floatImage->GetPixel(vfIter.GetIndex()); VectorType update=eulerianInitCond->GetPixel(vfIter.GetIndex()); if (val > stepl) update = update * (stepl/val); VectorType upd=vfIter.Get()+update * (epsilon); vfIter.Set(upd); } ct++; lastdifmag=difmag; } // std::cout <<" difmag " << difmag << ": its " << ct << std::endl; return difmag; } void SetUseNearestNeighborInterpolation( bool useNN) { this->m_UseNN=useNN; } void SetUseBSplineInterpolation( bool useNN) { this->m_UseBSplineInterpolation=useNN; } protected: DeformationFieldPointer IntegrateVelocity(float,float); DeformationFieldPointer IntegrateLandmarkSetVelocity(float,float, PointSetPointer movingpoints, ImagePointer referenceimage ); VectorType IntegratePointVelocity(float starttimein, float finishtimein , IndexType startPoint); ImagePointer MakeSubImage( ImagePointer bigimage) { typedef itk::ImageRegionIteratorWithIndex Iterator; ImagePointer varimage=ImageType::New(); typename ImageType::RegionType region; typename ImageType::SizeType size=bigimage->GetLargestPossibleRegion().GetSize(); region.SetSize( this->m_CurrentDomainSize); typename ImageType::IndexType index; index.Fill(0); region.SetIndex(index); varimage->SetRegions( region ); varimage->SetSpacing(this->m_CurrentDomainSpacing); varimage->SetOrigin(bigimage->GetOrigin()); varimage->SetDirection(bigimage->GetDirection()); varimage->Allocate(); varimage->FillBuffer(0); typename ImageType::IndexType cornerind; cornerind.Fill(0); for (unsigned int ii=0; iim_CurrentDomainOrigin[ii]-(float)this->m_CurrentDomainSize[ii]/2; if (diff < 0) diff=0; cornerind[ii]=(unsigned long) diff; } // std::cout << " corner index " << cornerind << std::endl; Iterator vfIter2( bigimage, bigimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { typename ImageType::IndexType origindex=vfIter2.GetIndex(); typename ImageType::IndexType index=vfIter2.GetIndex(); bool oktosample=true; for (unsigned int ii=0; iim_CurrentDomainOrigin[ii]); // float diff = // index[ii]=origindex[ii]-cornerind[ii]; if ( fabs(centerbasedcoord) > (this->m_CurrentDomainSize[ii]/2-1)) oktosample=false; } if (oktosample) { // std::cout << " index " << index << " origindex " << origindex << " ok? " << oktosample << std::endl; varimage->SetPixel(index,bigimage->GetPixel(origindex)); } } //std::cout << " sizes " << varimage->GetLargestPossibleRegion().GetSize() << " bigimage " << bigimage->GetLargestPossibleRegion().GetSize() << std::endl; return varimage; } float MeasureDeformation(DeformationFieldPointer field, int option=0) { typedef typename DeformationFieldType::PixelType VectorType; typedef typename DeformationFieldType::IndexType IndexType; typedef typename DeformationFieldType::SizeType SizeType; typedef typename VectorType::ValueType ScalarType; typedef ImageRegionIteratorWithIndex Iterator; // all we have to do here is add the local field to the global field. Iterator vfIter( field, field->GetLargestPossibleRegion() ); SizeType size=field->GetLargestPossibleRegion().GetSize(); unsigned long ct=1; double totalmag=0; float maxstep=0; // this->m_EuclideanNorm=0; typename ImageType::SpacingType myspacing = field->GetSpacing(); for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter ) { IndexType index=vfIter.GetIndex(); IndexType rindex=vfIter.GetIndex(); IndexType lindex=vfIter.GetIndex(); VectorType update=vfIter.Get(); float mag=0.0; float stepl=0.0; for (int i=0;i2) lindex[i]=lindex[i]-1; VectorType rupdate=field->GetPixel(rindex); VectorType lupdate=field->GetPixel(lindex); VectorType dif=rupdate-lupdate; for (int tt=0; tt maxstep) maxstep=stepl; ct++; totalmag+=mag; // this->m_EuclideanNorm+=stepl; } //this->m_EuclideanNorm/=ct; //this->m_ElasticPathLength = totalmag/ct; //this->m_LinftyNorm = maxstep; // std::cout << " Elast path length " << this->m_ElasticPathLength << " L inf norm " << this->m_LinftyNorm << std::endl; //if (this->m_ElasticPathLength >= this->m_ArcLengthGoal) // if (maxstep >= this->m_ArcLengthGoal) { // this->StopRegistration(); // scale the field to the right length // float scale=this->m_ArcLengthGoal/this->m_ElasticPathLength; // for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter )vfIter.Set(vfIter.Get()*scale); } //if (this->m_LinftyNorm <= 0) this->m_LinftyNorm=1; //if (this->m_ElasticPathLength <= 0) this->m_ElasticPathLength=0; //if (this->m_EuclideanNorm <= 0) this->m_EuclideanNorm=0; //if (option==0) return this->m_ElasticPathLength; //else if (option==2) return this->m_EuclideanNorm; // else return maxstep; } ANTSImageRegistrationOptimizer(); virtual ~ANTSImageRegistrationOptimizer() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: ANTSImageRegistrationOptimizer( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented typename VelocityFieldInterpolatorType::Pointer m_VelocityFieldInterpolator; typename ImageType::SizeType m_CurrentDomainSize; typename ImageType::PointType m_CurrentDomainOrigin; typename ImageType::SpacingType m_CurrentDomainSpacing; typename ImageType::DirectionType m_CurrentDomainDirection; typename ImageType::SizeType m_FullDomainSize; typename ImageType::PointType m_FullDomainOrigin; typename ImageType::SpacingType m_FullDomainSpacing; AffineTransformPointer m_AffineTransform; AffineTransformPointer m_FixedImageAffineTransform; DeformationFieldPointer m_DeformationField; DeformationFieldPointer m_InverseDeformationField; std::vector m_GradientDescentParameters; std::vector m_MetricScalarWeights; std::vector m_SmoothFixedImages; std::vector m_SmoothMovingImages; bool m_Debug; unsigned int m_NumberOfLevels; typename ParserType::Pointer m_Parser; SimilarityMetricListType m_SimilarityMetrics; ImagePointer m_MaskImage; float m_ScaleFactor; bool m_UseMulti; bool m_UseROI; bool m_UseNN; bool m_UseBSplineInterpolation; unsigned int m_CurrentIteration; unsigned int m_CurrentLevel; std::string m_TransformationModel; std::string m_OutputNamingConvention; PointSetPointer m_FixedPointSet; PointSetPointer m_MovingPointSet; std::vector m_Iterations; std::vector m_RestrictDeformation; std::vector m_RoiNumbers; float m_GradSmoothingparam; float m_TotalSmoothingparam; float m_Gradstep; float m_GradstepAltered; float m_NTimeSteps; float m_GaussianTruncation; float m_DeltaTime; float m_ESlope; /** energy stuff */ std::vector m_Energy; std::vector m_LastEnergy; std::vector m_EnergyBad; /** for SyN only */ DeformationFieldPointer m_SyNF; DeformationFieldPointer m_SyNFInv; DeformationFieldPointer m_SyNM; DeformationFieldPointer m_SyNMInv; TimeVaryingVelocityFieldPointer m_TimeVaryingVelocity; TimeVaryingVelocityFieldPointer m_LastTimeVaryingVelocity; TimeVaryingVelocityFieldPointer m_LastTimeVaryingUpdate; unsigned int m_SyNType; /** for BSpline stuff */ unsigned int m_BSplineFieldOrder; ArrayType m_GradSmoothingMeshSize; ArrayType m_TotalSmoothingMeshSize; /** For thickness calculation */ ImagePointer m_HitImage; ImagePointer m_ThickImage; unsigned int m_ComputeThickness; unsigned int m_SyNFullTime; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkANTSImageRegistrationOptimizer.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSImageTransformation.cxx000066400000000000000000000125641147325206600260000ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSImageTransformation.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkANTSImageTransformation_txx_ #define _itkANTSImageTransformation_txx_ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include "ANTS_affine_registration2.h" #include "itkANTSImageTransformation.h" #include "itkIdentityTransform.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkLinearInterpolateImageFunction.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkResampleImageFilter.h" #include "itkVectorImageFileWriter.h" #include "vnl/vnl_math.h" namespace itk { template ANTSImageTransformation ::ANTSImageTransformation() { this->m_DeformationField=NULL; this->m_InverseDeformationField=NULL; this->m_AffineTransform=NULL; this->m_WriteComponentImages = false; m_DeformationRegionOfInterestSize.Fill(0); m_DeformationRegionSpacing.Fill(1); m_DeformationRegionOfInterestCenter.Fill(0); } template void ANTSImageTransformation ::Compose() { } template void ANTSImageTransformation ::Write() { std::cout <<" begin writing " << m_NamingConvention << std::endl; std::string filePrefix = this->m_NamingConvention; std::string::size_type pos = filePrefix.rfind( "." ); std::string extension; std::string gzExtension( "" ); if ( pos != std::string::npos && std::string( filePrefix, pos, pos+2 ) != std::string( "./" ) ) { filePrefix = std::string( filePrefix, 0, pos ); extension = std::string( this->m_NamingConvention, pos, this->m_NamingConvention.length()-1 ); if ( extension == std::string( ".gz" ) ) { gzExtension = std::string( ".gz" ); pos = filePrefix.rfind( "." ); extension = std::string( filePrefix, pos, filePrefix.length()-1 ); filePrefix = std::string( filePrefix, 0, pos ); } } else { extension = std::string( ".nii.gz" ); } //Added by songgang if (this->m_AffineTransform) { std::cout << " writing " << filePrefix << " affine " << std::endl; std::string filename = filePrefix + std::string( "Affine.txt" ); WriteAffineTransformFile(this->m_AffineTransform, filename); } if ( this->m_DeformationField ) { std::cout <<" writing " << filePrefix << " def " << std::endl; if ( extension != std::string( ".mha" ) ) { std::string filename = filePrefix + std::string( "Warp" ) + extension + gzExtension; typedef VectorImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); std::cout << "filename " << filename << std::endl; writer->SetFileName( filename ); writer->SetUseAvantsNamingConvention( true ); writer->SetInput( this->m_DeformationField ); writer->Update(); } else { std::string filename = filePrefix + std::string( "Warp.mha" ); typedef ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( filename ); writer->SetInput( this->m_DeformationField ); writer->Update(); } } if ( this->m_InverseDeformationField ) { if ( extension != std::string( ".mha" ) ) { std::string filename = filePrefix + std::string( "InverseWarp" ) + extension + gzExtension; typedef VectorImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( filename ); writer->SetUseAvantsNamingConvention( true ); writer->SetInput( this->m_InverseDeformationField ); writer->Update(); } else { std::string filename = filePrefix + std::string( "InverseWarp.mha" ); typedef ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( filename ); writer->SetInput( this->m_InverseDeformationField ); writer->Update(); } } } /** * Standard "PrintSelf" method */ template void ANTSImageTransformation ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSImageTransformation.h000066400000000000000000000146441147325206600254260ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSImageTransformation.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkANTSImageTransformation_h #define __itkANTSImageTransformation_h #include "itkObject.h" #include "itkObjectFactory.h" #include "antsCommandLineParser.h" #include "itkImage.h" #include "itkMacro.h" #include "itkCenteredEuler3DTransform.h" #include "itkQuaternionRigidTransform.h" #include "itkANTSCenteredAffine2DTransform.h" #include "itkANTSAffine3DTransform.h" // #include "itkCenteredRigid2DTransform.h" #include "itkCenteredTransformInitializer.h" #include "itkTransformFileReader.h" #include "itkTransformFileWriter.h" namespace itk { template class ITK_EXPORT ANTSImageTransformation : public Object { public: /** Standard class typedefs. */ typedef ANTSImageTransformation Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ANTSImageTransformation, Object ); itkStaticConstMacro( Dimension, unsigned int, TDimension ); itkStaticConstMacro( ImageDimension, unsigned int, TDimension ); typedef TReal RealType; typedef Image ImageType; /** declare transformation types */ typedef itk::MatrixOffsetTransformBase AffineTransformType; typedef typename AffineTransformType::Pointer AffineTransformPointer; typedef itk::Vector VectorType; typedef itk::Image DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::RegionType DeformationRegionOfInterestType; typedef typename DeformationFieldType::SizeType DeformationRegionOfInterestSizeType; typedef typename DeformationFieldType::PointType DeformationRegionOfInterestCenterType; typedef typename ants::CommandLineParser ParserType; typedef typename ParserType::OptionType OptionType; /** Set functions */ void SetDeformationRegionOfInterest( DeformationRegionOfInterestCenterType DRC, DeformationRegionOfInterestSizeType DRS , typename DeformationFieldType::SpacingType DRSp) { m_DeformationRegionOfInterestCenter=DRC; m_DeformationRegionOfInterestSize=DRS; m_DeformationRegionSpacing=DRSp; } void SetAffineTransform(AffineTransformPointer A) {this->m_AffineTransform=A;} void SetDeformationField(DeformationFieldPointer A) {this->m_DeformationField=A;} void SetInverseDeformationField(DeformationFieldPointer A) {this->m_InverseDeformationField=A;} void SetNamingConvention(std::string name) { this->m_NamingConvention=name; } /** Get functions */ AffineTransformPointer GetAffineTransform() { return this->m_AffineTransform; } DeformationFieldPointer GetDeformationField( ) { return this->m_DeformationField; } DeformationFieldPointer GetInverseDeformationField() { return this->m_InverseDeformationField; } void SetFixedImageAffineTransform(AffineTransformPointer A) {this->m_FixedImageAffineTransform=A;} AffineTransformPointer GetFixedImageAffineTransform() {return this->m_FixedImageAffineTransform;} /** Initialize the mapping */ void InitializeTransform() { if (!this->m_AffineTransform) { this->m_AffineTransform=AffineTransformType::New(); this->m_AffineTransform->SetIdentity(); } // deformation fields too if (!this->m_DeformationField) { VectorType zero; zero.Fill(0); this->m_DeformationField=DeformationFieldType::New(); /* m_DeformationRegionOfInterest.SetSize( m_DeformationRegionOfInterestSize ); this->m_DeformationField->SetSpacing( m_DeformationRegionSpacing ); this->m_DeformationField->SetOrigin( m_DeformationRegionOfInterestCenter ); this->m_DeformationField->SetLargestPossibleRegion( m_DeformationRegionOfInterest ); this->m_DeformationField->SetRequestedRegion( m_DeformationRegionOfInterest ); this->m_DeformationField->SetBufferedRegion( m_DeformationRegionOfInterest ); this->m_DeformationField->Allocate(); this->m_DeformationField->FillBuffer(zero); */ } } /** Write the transformations out */ void Write(); /** Concatenate all transformations */ void Compose(); /** Concatenate all transformations in inverse direction */ void ComposeInverse(); itkSetMacro( WriteComponentImages, bool ); itkGetMacro( WriteComponentImages, bool ); itkBooleanMacro( WriteComponentImages ); protected: ANTSImageTransformation(); virtual ~ANTSImageTransformation() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: ANTSImageTransformation( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented AffineTransformPointer m_AffineTransform; AffineTransformPointer m_FixedImageAffineTransform; DeformationFieldPointer m_DeformationField; DeformationRegionOfInterestType m_DeformationRegionOfInterest; DeformationRegionOfInterestCenterType m_DeformationRegionOfInterestCenter; DeformationRegionOfInterestSizeType m_DeformationRegionOfInterestSize; typename DeformationFieldType::SpacingType m_DeformationRegionSpacing; DeformationFieldPointer m_InverseDeformationField; std::string m_NamingConvention; bool m_WriteComponentImages; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkANTSImageTransformation.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSLabeledPointSet.h000066400000000000000000000064231147325206600244670ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSLabeledPointSet.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkANTSLabeledPointSet_h #define __itkANTSLabeledPointSet_h #include "itkObject.h" #include "itkObjectFactory.h" #include "itkMacro.h" #include "itkVector.h" #include "itkPointSet.h" namespace itk { template class ITK_EXPORT ANTSLabeledPointSet : public Object { public: /** Standard class typedefs. */ typedef ANTSLabeledPointSet Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ANTSLabeledPointSet, Object ); itkStaticConstMacro( Dimension, unsigned int, TDimension ); typedef float RealType; typedef Image ImageType; typedef typename ImageType::Pointer ImagePointer; typedef Vector VectorType; typedef Image DeformationFieldType; /** Point Types for landmarks and labeled point-sets */ typedef long PointDataVectorType; typedef itk::PointSet PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef typename ImageType::PointType ImagePointType; itkSetMacro( PointSet, PointSetPointer ); itkGetConstMacro( PointSet, PointSetPointer ); PointType GetPoint( unsigned long ii) { PointType point; this->m_PointSet->GetPoint(ii,&point); return point; } PointDataType GetPointData( unsigned long ii) { PointDataType data; this->m_PointSet->GetPointData(ii,&data); return data; } void SetPoint( unsigned long ii , PointType point ) { this->m_PointSet->SetPoint(ii,point); } void SetPointData( unsigned long ii , PointDataType label ) { this->m_PointSet->SetPointData(ii,label); } void SetPointAndData( unsigned long ii , PointType point , PointDataType label ) { this->m_PointSet->SetPoint(ii,point); this->m_PointSet->SetPointData(ii,label); } private: PointSetPointer m_PointSet; }; } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkANTSSimilarityMetric.h000066400000000000000000000105321147325206600247370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkANTSSimilarityMetric.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkANTSSimilarityMetric_h #define __itkANTSSimilarityMetric_h #include "itkObject.h" #include "itkObjectFactory.h" #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkMacro.h" #include "itkVector.h" #include "itkANTSLabeledPointSet.h" namespace itk { template class ITK_EXPORT ANTSSimilarityMetric : public Object { public: /** Standard class typedefs. */ typedef ANTSSimilarityMetric Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ANTSSimilarityMetric, Object ); itkStaticConstMacro( Dimension, unsigned int, TDimension ); typedef TReal RealType; typedef Image ImageType; typedef typename ImageType::Pointer ImagePointer; typedef Vector VectorType; typedef Image DeformationFieldType; /** Point Types for landmarks and labeled point-sets */ typedef itk::ANTSLabeledPointSet LabeledPointSetType; typedef typename LabeledPointSetType::Pointer LabeledPointSetPointer; typedef typename LabeledPointSetType::PointSetType PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef typename ImageType::PointType ImagePointType; /** Typedefs for similarity metrics */ typedef AvantsPDEDeformableRegistrationFunction MetricType; typedef typename MetricType::Pointer MetricPointer; typedef typename MetricType::RadiusType RadiusType; itkSetMacro( FixedImage, ImagePointer ); itkGetConstMacro( FixedImage, ImagePointer ); itkSetMacro( MovingImage, ImagePointer ); itkGetConstMacro( MovingImage, ImagePointer ); itkSetMacro( FixedPointSet, PointSetPointer ); itkGetConstMacro( FixedPointSet, PointSetPointer ); itkSetMacro( MovingPointSet, PointSetPointer ); itkGetConstMacro( MovingPointSet, PointSetPointer ); itkSetMacro( WeightImage, ImagePointer ); itkGetConstMacro( WeightImage, ImagePointer ); itkSetClampMacro( WeightScalar, RealType, 0.0, NumericTraits::max() ); itkGetConstMacro( WeightScalar, RealType ); itkSetObjectMacro( Metric, MetricType ); itkGetObjectMacro( Metric, MetricType ); itkSetMacro( MaximizeMetric, bool ); itkGetConstMacro( MaximizeMetric, bool ); itkBooleanMacro( MaximizeMetric ); private: MetricPointer m_Metric; bool m_MaximizeMetric; ImagePointer m_FixedImage; ImagePointer m_MovingImage; PointSetPointer m_FixedPointSet; PointSetPointer m_MovingPointSet; ImagePointer m_WeightImage; RealType m_WeightScalar; }; } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkAvantsMutualInformationRegistrationFunction.cxx000066400000000000000000000523041147325206600322700ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAvantsMutualInformationRegistrationFunction.cxx,v $ Language: C++ Date: $Date: 2009/01/08 15:14:48 $ Version: $Revision: 1.21 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkAvantsMutualInformationRegistrationFunction_txx #define _itkAvantsMutualInformationRegistrationFunction_txx #include "itkAvantsMutualInformationRegistrationFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkCovariantVector.h" #include "itkImageRandomConstIteratorWithIndex.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionIterator.h" #include "itkImageIterator.h" #include "vnl/vnl_math.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkBSplineDeformableTransform.h" #include "itkImageRegionConstIteratorWithIndex.h" namespace itk { /** * Constructor */ template < class TFixedImage, class TMovingImage , class TDeformationField > AvantsMutualInformationRegistrationFunction ::AvantsMutualInformationRegistrationFunction() { this-> Superclass::m_NormalizeGradient=true; this->m_NumberOfSpatialSamples = 5000; this->m_NumberOfHistogramBins = 50; // this->SetComputeGradient(false); // don't use the default gradient for no // Initialize PDFs to NULL m_JointPDF = NULL; m_OpticalFlow=false; typename TransformType::Pointer transformer = TransformType::New(); this->SetTransform(transformer); typename BSplineInterpolatorType::Pointer interpolator = BSplineInterpolatorType::New(); this->SetInterpolator (interpolator); m_FixedImageMask=NULL; m_MovingImageMask=NULL; // Initialize memory m_MovingImageNormalizedMin = 0.0; m_FixedImageNormalizedMin = 0.0; m_MovingImageTrueMin = 0.0; m_MovingImageTrueMax = 0.0; m_FixedImageBinSize = 0.0; m_MovingImageBinSize = 0.0; m_CubicBSplineDerivativeKernel = NULL; m_BSplineInterpolator = NULL; m_DerivativeCalculator = NULL; m_NumParametersPerDim = 0; m_NumBSplineWeights = 0; m_BSplineTransform = NULL; m_NumberOfParameters = ImageDimension; m_FixedImageGradientCalculator = GradientCalculatorType::New(); m_MovingImageGradientCalculator = GradientCalculatorType::New(); this->m_Padding=2; typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); typename DefaultInterpolatorType::Pointer interp2 = DefaultInterpolatorType::New(); m_MovingImageInterpolator = static_cast( interp.GetPointer() ); m_FixedImageInterpolator = static_cast( interp2.GetPointer() ); m_Interpolator = static_cast( interp.GetPointer() ); this->m_RobustnessParameter=-1.e19; } /** * Print out internal information about this class */ template < class TFixedImage, class TMovingImage , class TDeformationField> void AvantsMutualInformationRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "NumberOfSpatialSamples: "; os << m_NumberOfSpatialSamples << std::endl; os << indent << "NumberOfHistogramBins: "; os << m_NumberOfHistogramBins << std::endl; // Debugging information os << indent << "NumberOfParameters: "; os << m_NumberOfParameters << std::endl; os << indent << "FixedImageNormalizedMin: "; os << m_FixedImageNormalizedMin << std::endl; os << indent << "MovingImageNormalizedMin: "; os << m_MovingImageNormalizedMin << std::endl; os << indent << "MovingImageTrueMin: "; os << m_MovingImageTrueMin << std::endl; os << indent << "MovingImageTrueMax: "; os << m_MovingImageTrueMax << std::endl; os << indent << "FixedImageBinSize: "; os << m_FixedImageBinSize << std::endl; os << indent << "MovingImageBinSize: "; os << m_MovingImageBinSize << std::endl; os << indent << "InterpolatorIsBSpline: "; os << m_InterpolatorIsBSpline << std::endl; os << indent << "TransformIsBSpline: "; os << m_TransformIsBSpline << std::endl; } /** * Initialize */ template void AvantsMutualInformationRegistrationFunction ::InitializeIteration() { m_CubicBSplineKernel = CubicBSplineFunctionType::New(); m_CubicBSplineDerivativeKernel = CubicBSplineDerivativeFunctionType::New(); this->m_Energy=0; pdfinterpolator = pdfintType::New(); dpdfinterpolator = dpdfintType::New(); pdfinterpolator2 = pdfintType2::New(); pdfinterpolator3 = pdfintType2::New(); m_DerivativeCalculator = DerivativeFunctionType::New(); // this->ComputeMetricImage(); // bool makenewimage=false; typedef ImageRegionIteratorWithIndex ittype; TFixedImage* img =const_cast(this->m_FixedImage.GetPointer()); typename TFixedImage::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); /* if (!this->m_MetricImage )makenewimage=true; else if (imagesize[0] != this->m_MetricImage->GetLargestPossibleRegion().GetSize()[0]) makenewimage = true; else this->m_MetricImage->FillBuffer(0); if (makenewimage) { this->m_MetricImage = TFixedImage::New(); this->m_MetricImage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); this->m_MetricImage->SetBufferedRegion(img->GetLargestPossibleRegion()); this->m_MetricImage->SetSpacing(img->GetSpacing()); this->m_MetricImage->SetOrigin(img->GetOrigin()); this->m_MetricImage->Allocate(); ittype it(this->m_MetricImage,this->m_MetricImage->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) it.Set(0); } */ m_FixedImageGradientCalculator->SetInputImage( this->m_FixedImage ); m_MovingImageGradientCalculator->SetInputImage( this->m_MovingImage ); m_FixedImageInterpolator->SetInputImage( this->m_FixedImage ); m_Interpolator->SetInputImage( this->m_MovingImage ); m_FixedImageSpacing = this->m_FixedImage->GetSpacing(); m_FixedImageOrigin = this->m_FixedImage->GetOrigin(); m_Normalizer = 0.0; m_NumberOfSpatialSamples = 1; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; m_NumberOfSpatialSamples *= this->m_FixedImage->GetLargestPossibleRegion().GetSize()[k]; } m_Normalizer /= static_cast( ImageDimension ); /** * Compute binsize for the histograms. * * The binsize for the image intensities needs to be adjusted so that * we can avoid dealing with boundary conditions using the cubic * spline as the Parzen window. We do this by increasing the size * of the bins so that the joint histogram becomes "padded" at the * borders. Because we are changing the binsize, * we also need to shift the minimum by the padded amount in order to * avoid minimum values filling in our padded region. * * Note that there can still be non-zero bin values in the padded region, * it's just that these bins will never be a central bin for the Parzen * window. * double fixedImageMax = 1.0; double fixedImageMin = 0.0; double movingImageMax = 1.0; double movingImageMin = 0.0; m_MovingImageTrueMin = movingImageMin; m_MovingImageTrueMax = movingImageMax; */ double movingImageMin = NumericTraits::max(); double movingImageMax = NumericTraits::NonpositiveMin(); double fixedImageMin = NumericTraits::max(); double fixedImageMax = NumericTraits::NonpositiveMin(); typedef ImageRegionConstIterator MovingIteratorType; MovingIteratorType movingImageIterator( this->m_MovingImage, this->m_MovingImage->GetBufferedRegion() ); for ( movingImageIterator.GoToBegin(); !movingImageIterator.IsAtEnd(); ++movingImageIterator) { bool takesample = true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( movingImageIterator.GetIndex() ) < 1.e-6 ) takesample=false; if (takesample) { double sample = static_cast( movingImageIterator.Get() ); double fsample = static_cast( this->m_FixedImage->GetPixel( movingImageIterator.GetIndex() )); if ( sample < movingImageMin ) { movingImageMin = sample; } if ( sample > movingImageMax ) { movingImageMax = sample; } if ( fsample < fixedImageMin ) { fixedImageMin = fsample; } if ( fsample > fixedImageMax ) { fixedImageMax = fsample; } } } this->m_MovingImageTrueMax=movingImageMax; this->m_FixedImageTrueMax=fixedImageMax; this->m_MovingImageTrueMin=movingImageMin; this->m_FixedImageTrueMin=fixedImageMin; fixedImageMax=1.*( fixedImageMax - fixedImageMin )+fixedImageMin; movingImageMax=1.*( movingImageMax - movingImageMin )+movingImageMin; m_FixedImageBinSize = ( fixedImageMax - fixedImageMin ) / static_cast( m_NumberOfHistogramBins - 2 * this->m_Padding ); m_FixedImageNormalizedMin = fixedImageMin / m_FixedImageBinSize - static_cast( this->m_Padding ); m_MovingImageBinSize = ( movingImageMax - movingImageMin ) / static_cast( m_NumberOfHistogramBins - 2 * this->m_Padding ); m_MovingImageNormalizedMin = movingImageMin / m_MovingImageBinSize - static_cast( this->m_Padding ); m_FixedImageMarginalPDF = MarginalPDFType::New(); m_MovingImageMarginalPDF = MarginalPDFType::New(); typename MarginalPDFType::RegionType mPDFRegion; typename MarginalPDFType::SizeType mPDFSize; typename MarginalPDFType::IndexType mPDFIndex; typename MarginalPDFType::SpacingType mPDFspacing; mPDFspacing.Fill(1); mPDFIndex.Fill( 0 ); mPDFSize.Fill( m_NumberOfHistogramBins ); mPDFRegion.SetIndex( mPDFIndex ); mPDFRegion.SetSize( mPDFSize ); m_FixedImageMarginalPDF->SetRegions( mPDFRegion ); m_FixedImageMarginalPDF->Allocate(); m_FixedImageMarginalPDF->SetSpacing(mPDFspacing); m_MovingImageMarginalPDF->SetRegions( mPDFRegion ); m_MovingImageMarginalPDF->Allocate(); m_MovingImageMarginalPDF->SetSpacing(mPDFspacing); /** * Allocate memory for the joint PDF and joint PDF derivatives. * The joint PDF and joint PDF derivatives are store as itk::Image. */ m_JointPDF = JointPDFType::New(); // Instantiate a region, index, size JointPDFRegionType jointPDFRegion; JointPDFIndexType jointPDFIndex; JointPDFSizeType jointPDFSize; // For the joint PDF define a region starting from {0,0} // with size {m_NumberOfHistogramBins, m_NumberOfHistogramBins}. // The dimension represents fixed image parzen window index // and moving image parzen window index, respectively. jointPDFIndex.Fill( 0 ); jointPDFSize.Fill( m_NumberOfHistogramBins ); jointPDFRegion.SetIndex( jointPDFIndex ); jointPDFRegion.SetSize( jointPDFSize ); // Set the regions and allocate m_JointPDF->SetRegions( jointPDFRegion ); m_JointPDF->Allocate(); m_JointHist = JointPDFType::New(); m_JointHist->SetRegions(jointPDFRegion ); m_JointHist->Allocate(); // For the derivatives of the joint PDF define a region starting from {0,0,0} // with size {m_NumberOfParameters,m_NumberOfHistogramBins, // m_NumberOfHistogramBins}. The dimension represents transform parameters, // fixed image parzen window index and moving image parzen window index, // respectively. typename JointPDFType::SpacingType jspacing; jspacing.Fill(1); this->m_JointHist->SetSpacing(jspacing); this->m_JointPDF->SetSpacing(jspacing); m_NormalizeMetric=1.0; for (int i=0; im_FixedImage->GetLargestPossibleRegion().GetSize()[i]; this->GetProbabilities(); this->ComputeMutualInformation(); pdfinterpolator->SetInputImage(m_JointPDF); pdfinterpolator2->SetInputImage(m_FixedImageMarginalPDF); pdfinterpolator3->SetInputImage(m_MovingImageMarginalPDF); pdfinterpolator->SetSplineOrder(3); pdfinterpolator2->SetSplineOrder(3); pdfinterpolator3->SetSplineOrder(3); } /** * Get the both Value and Derivative Measure */ template < class TFixedImage, class TMovingImage , class TDeformationField> void AvantsMutualInformationRegistrationFunction ::GetProbabilities() { typedef ImageRegionConstIteratorWithIndex RandomIterator; RandomIterator randIter( this->m_FixedImage, this->m_FixedImage->GetLargestPossibleRegion() ); for ( unsigned int j = 0; j < m_NumberOfHistogramBins; j++ ) { MarginalPDFIndexType mind; mind[0]=j; m_FixedImageMarginalPDF->SetPixel(mind,0); m_MovingImageMarginalPDF->SetPixel(mind,0); } // Reset the joint pdfs to zero m_JointPDF->FillBuffer( 0.0 ); m_JointHist->FillBuffer( 0.0 ); unsigned long nSamples=0; RandomIterator iter( this->m_FixedImage, this->m_FixedImage->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { bool takesample=true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( iter.GetIndex() ) < 1.e-6 ) takesample=false; if (takesample) { // Get sampled index FixedImageIndexType index = iter.GetIndex(); typename FixedImageType::SizeType imagesize=this->m_FixedImage->GetLargestPossibleRegion().GetSize(); /* bool inimage=true; for (unsigned int dd=0; dd= static_cast(imagesize[dd]-1) ) inimage=false; } */ double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( index ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( index ) ); unsigned int movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); unsigned int fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); // std::cout << " fiv " << fixedImageValue << " fip " << fixedImageParzenWindowIndex << " miv " << movingImageValue << " mip " << movingImageParzenWindowIndex << std::endl; JointPDFValueType *pdfPtr = m_JointPDF->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); int pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); ++nSamples; } } /** * Normalize the PDFs, compute moving image marginal PDF * */ typedef ImageRegionIterator JointPDFIteratorType; JointPDFIteratorType jointPDFIterator ( m_JointPDF, m_JointPDF->GetBufferedRegion() ); // Compute joint PDF normalization factor (to ensure joint PDF sum adds to 1.0) double jointPDFSum = 0.0; float max = 0; float max2 = 0; float max3 = 0; float max4 = 0; jointPDFIterator.GoToBegin(); while( !jointPDFIterator.IsAtEnd() ) { float temp = jointPDFIterator.Get(); m_JointHist->SetPixel(jointPDFIterator.GetIndex(),temp); if (temp > max) max = temp; if (temp > max2 && temp < max) max2=temp; if (temp > max3 && temp < max2) max3=temp; if (temp > max4 && temp < max3) max4=temp; ++jointPDFIterator; } jointPDFIterator.GoToBegin(); while( !jointPDFIterator.IsAtEnd() ) { float temp = jointPDFIterator.Get(); jointPDFIterator.Set(temp); jointPDFSum += temp; ++jointPDFIterator; } //std::cout << " Joint PDF Summation? " << jointPDFSum << std::endl; // of derivatives if ( jointPDFSum == 0.0 ) { itkExceptionMacro( "Joint PDF summed to zero" ); } // Normalize the PDF bins jointPDFIterator.GoToEnd(); while( !jointPDFIterator.IsAtBegin() ) { --jointPDFIterator; jointPDFIterator.Value() /= static_cast( jointPDFSum ); } bool smoothjh=true; if (smoothjh) { typedef DiscreteGaussianImageFilter dgtype; typename dgtype::Pointer dg=dgtype::New(); dg->SetInput(this->m_JointPDF); dg->SetVariance(1.); dg->SetUseImageSpacingOff(); dg->SetMaximumError(.01f); dg->Update(); this->m_JointPDF=dg->GetOutput(); } // Compute moving image marginal PDF by summing over fixed image bins. typedef ImageLinearIteratorWithIndex JointPDFLinearIterator; JointPDFLinearIterator linearIter( m_JointPDF, m_JointPDF->GetBufferedRegion() ); linearIter.SetDirection( 0 ); linearIter.GoToBegin(); unsigned int fixedIndex = 0; while( !linearIter.IsAtEnd() ) { double sum = 0.0; while( !linearIter.IsAtEndOfLine() ) { sum += linearIter.Get(); ++linearIter; } MarginalPDFIndexType mind; mind[0]=fixedIndex; m_FixedImageMarginalPDF->SetPixel(mind,static_cast(sum)); linearIter.NextLine(); ++fixedIndex; } linearIter.SetDirection( 1 ); linearIter.GoToBegin(); unsigned int movingIndex = 0; while( !linearIter.IsAtEnd() ) { double sum = 0.0; while( !linearIter.IsAtEndOfLine() ) { sum += linearIter.Get(); ++linearIter; } MarginalPDFIndexType mind; mind[0]=movingIndex; m_MovingImageMarginalPDF->SetPixel(mind,static_cast(sum)); linearIter.NextLine(); ++movingIndex; } } /** * Get the both Value and Derivative Measure */ template < class TFixedImage, class TMovingImage , class TDeformationField> double AvantsMutualInformationRegistrationFunction ::GetValueAndDerivative(IndexType oindex, MeasureType& valuei, DerivativeType& derivative1,DerivativeType& derivative2) { double value=0; DerivativeType zero(ImageDimension); zero.Fill(0); double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( oindex ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( oindex ) ); double movingImageParzenWindowContIndex=this->FitContIndexInBins( movingImageValue ); double fixedImageParzenWindowContIndex=this->FitContIndexInBins( fixedImageValue ); double dJPDF=0,dFmPDF=0,jointPDFValue=0,fixedImagePDFValue=0; { typename pdfintType::ContinuousIndexType pdfind; pdfind[1]= fixedImageParzenWindowContIndex; pdfind[0]= movingImageParzenWindowContIndex; jointPDFValue=pdfinterpolator->EvaluateAtContinuousIndex(pdfind); dJPDF = (1.0)*(pdfinterpolator->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; } { typename pdfintType2::ContinuousIndexType mind; mind[0]=fixedImageParzenWindowContIndex; fixedImagePDFValue = pdfinterpolator2->EvaluateAtContinuousIndex(mind); dFmPDF = (pdfinterpolator2->EvaluateDerivativeAtContinuousIndex(mind))[0]; } double term1=0,term2=0,eps=1.e-12; if( jointPDFValue > eps && (fixedImagePDFValue) > 0) { term1 = dJPDF/jointPDFValue; term2 = dFmPDF/fixedImagePDFValue; value = (term1*(-1.0)+term2); } // end if-block to check non-zero bin contribution else value = 0; return value; } template < class TFixedImage, class TMovingImage , class TDeformationField> double AvantsMutualInformationRegistrationFunction ::GetValueAndDerivativeInv(IndexType oindex, MeasureType& valuei, DerivativeType& derivative1,DerivativeType& derivative2) { double value=0; DerivativeType zero(ImageDimension); zero.Fill(0); double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( oindex ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( oindex ) ); double movingImageParzenWindowContIndex=this->FitContIndexInBins( movingImageValue ); double fixedImageParzenWindowContIndex=this->FitContIndexInBins( fixedImageValue ); double dJPDF=0,dMmPDF=0,jointPDFValue=0,movingImagePDFValue=0; { typename pdfintType::ContinuousIndexType pdfind; pdfind[1]= fixedImageParzenWindowContIndex; pdfind[0]= movingImageParzenWindowContIndex; jointPDFValue=pdfinterpolator->EvaluateAtContinuousIndex(pdfind); dJPDF = (1.0)*(pdfinterpolator->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; } { typename pdfintType2::ContinuousIndexType mind; mind[0]=movingImageParzenWindowContIndex; movingImagePDFValue = pdfinterpolator3->EvaluateAtContinuousIndex(mind); dMmPDF = (pdfinterpolator3->EvaluateDerivativeAtContinuousIndex(mind))[0]; } double term1=0,term2=0,eps=1.e-12; if( jointPDFValue > eps && (movingImagePDFValue) > 0 ) { term1 = dJPDF/jointPDFValue; term2 = dMmPDF/movingImagePDFValue; value = (term1*(-1.0)+term2); } // end if-block to check non-zero bin contribution else value = 0; // double pmr=jointPDFValue; // double pmt=jointPDFValue; // double Fx=log( ( pmr / pr ) / ( pmt / pt ) ); return value; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkAvantsMutualInformationRegistrationFunction.h000066400000000000000000000645001147325206600317160ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAvantsMutualInformationRegistrationFunction.h,v $ Language: C++ Date: $Date: 2009/01/08 15:14:48 $ Version: $Revision: 1.20 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAvantsMutualInformationRegistrationFunction_h #define __itkAvantsMutualInformationRegistrationFunction_h #include "itkImageFileWriter.h" #include "itkImageToImageMetric.h" #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkCovariantVector.h" #include "itkPoint.h" #include "itkIndex.h" #include "itkBSplineKernelFunction.h" #include "itkBSplineDerivativeKernelFunction.h" #include "itkCentralDifferenceImageFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkBSplineDeformableTransform.h" #include "itkTranslationTransform.h" #include "itkArray2D.h" #include "itkImageBase.h" #include "itkTransform.h" #include "itkInterpolateImageFunction.h" #include "itkSingleValuedCostFunction.h" #include "itkExceptionObject.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkSpatialObject.h" #include "itkConstNeighborhoodIterator.h" namespace itk { /** \class AvantsMutualInformationRegistrationFunction * \brief Computes the mutual information between two images to be * registered using the method of Avants et al. * * AvantsMutualInformationRegistrationFunction computes the mutual * information between a fixed and moving image to be registered. * * This class is templated over the FixedImage type and the MovingImage * type. * * The fixed and moving images are set via methods SetFixedImage() and * SetMovingImage(). This metric makes use of user specified Transform and * Interpolator. The Transform is used to map points from the fixed image to * the moving image domain. The Interpolator is used to evaluate the image * intensity at user specified geometric points in the moving image. * The Transform and Interpolator are set via methods SetTransform() and * SetInterpolator(). * * If a BSplineInterpolationFunction is used, this class obtain * image derivatives from the BSpline interpolator. Otherwise, * image derivatives are computed using central differencing. * * \warning This metric assumes that the moving image has already been * connected to the interpolator outside of this class. * * The method GetValue() computes of the mutual information * while method GetValueAndDerivative() computes * both the mutual information and its derivatives with respect to the * transform parameters. * * The calculations are based on the method of Avants et al [1,2] * where the probability density distribution are estimated using * Parzen histograms. Since the fixed image PDF does not contribute * to the derivatives, it does not need to be smooth. Hence, * a zero order (box car) BSpline kernel is used * for the fixed image intensity PDF. On the other hand, to ensure * smoothness a third order BSpline kernel is used for the * moving image intensity PDF. * * On Initialize(), the FixedImage is uniformly sampled within * the FixedImageRegion. The number of samples used can be set * via SetNumberOfSpatialSamples(). Typically, the number of * spatial samples used should increase with the image size. * * During each call of GetValue(), GetDerivatives(), * GetValueAndDerivatives(), marginal and joint intensity PDF's * values are estimated at discrete position or bins. * The number of bins used can be set via SetNumberOfHistogramBins(). * To handle data with arbitray magnitude and dynamic range, * the image intensity is scale such that any contribution to the * histogram will fall into a valid bin. * * One the PDF's have been contructed, the mutual information * is obtained by doubling summing over the discrete PDF values. * * * Notes: * 1. This class returns the negative mutual information value. * 2. This class in not thread safe due the private data structures * used to the store the sampled points and the marginal and joint pdfs. * * References: * [1] "Nonrigid multimodality image registration" * D. Avants, D. R. Haynor, H. Vesselle, T. Lewellen and W. Eubank * Medical Imaging 2001: Image Processing, 2001, pp. 1609-1620. * [2] "PET-CT Image Registration in the Chest Using Free-form Deformations" * D. Avants, D. R. Haynor, H. Vesselle, T. Lewellen and W. Eubank * IEEE Transactions in Medical Imaging. Vol.22, No.1, January 2003. pp.120-128. * [3] "Optimization of Mutual Information for MultiResolution Image * Registration" * P. Thevenaz and M. Unser * IEEE Transactions in Image Processing, 9(12) December 2000. * * \ingroup RegistrationMetrics * \ingroup ThreadUnSafe */ template class ITK_EXPORT AvantsMutualInformationRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage , TDeformationField> { public: /** Standard class typedefs. */ typedef AvantsMutualInformationRegistrationFunction Self; typedef AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( AvantsMutualInformationRegistrationFunction, AvantsPDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; typedef typename FixedImageType::SpacingType SpacingType; /** Deformation field type. */ typedef typename Superclass::VectorType VectorType; typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Interpolator type. */ typedef double CoordRepType; typedef // // LinearInterpolateImageFunction BSplineInterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef typename InterpolatorType::PointType PointType; typedef InterpolatorType DefaultInterpolatorType; // typedef LinearInterpolateImageFunction //DefaultInterpolatorType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** Gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Set the moving image interpolator. */ void SetMovingImageInterpolator( InterpolatorType * ptr ) { m_MovingImageInterpolator = ptr; } /** Get the moving image interpolator. */ InterpolatorType * GetMovingImageInterpolator(void) { return m_MovingImageInterpolator; } /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void *itkNotUsed(GlobalData)) const { return 1; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); // global->m_SumOfSquaredDifference = 0.0; /// global->m_NumberOfPixelsProcessed = 0L; // global->m_SumOfSquaredChange = 0; return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const { delete (GlobalDataStruct *) GlobalData; } /** Set the object's state before each iteration. */ virtual void InitializeIteration(); typedef double CoordinateRepresentationType; /** Types inherited from Superclass. */ typedef TranslationTransform TransformType; typedef ImageToImageMetric< TFixedImage, TMovingImage > Metricclass; typedef typename TransformType::Pointer TransformPointer; typedef typename Metricclass::TransformJacobianType TransformJacobianType; // typedef typename Metricclass::InterpolatorType InterpolatorType; typedef typename Metricclass::MeasureType MeasureType; typedef typename Metricclass::DerivativeType DerivativeType; typedef typename TransformType::ParametersType ParametersType; typedef typename Metricclass::FixedImageConstPointer FixedImageConstPointer; typedef typename Metricclass::MovingImageConstPointer MovingImageCosntPointer; // typedef typename TransformType::CoordinateRepresentationType CoordinateRepresentationType; /** Index and Point typedef support. */ typedef typename FixedImageType::IndexType FixedImageIndexType; typedef typename FixedImageIndexType::IndexValueType FixedImageIndexValueType; typedef typename MovingImageType::IndexType MovingImageIndexType; typedef typename TransformType::InputPointType FixedImagePointType; typedef typename TransformType::OutputPointType MovingImagePointType; /** The marginal PDFs are stored as std::vector. */ typedef float PDFValueType; // typedef std::vector MarginalPDFType; typedef Image MarginalPDFType; typedef typename MarginalPDFType::IndexType MarginalPDFIndexType; /** Typedef for the joint PDF and PDF derivatives are stored as ITK Images. */ typedef Image JointPDFType; typedef Image JointPDFDerivativesType; typedef JointPDFType::IndexType JointPDFIndexType; typedef JointPDFType::PixelType JointPDFValueType; typedef JointPDFType::RegionType JointPDFRegionType; typedef JointPDFType::SizeType JointPDFSizeType; typedef JointPDFDerivativesType::IndexType JointPDFDerivativesIndexType; typedef JointPDFDerivativesType::PixelType JointPDFDerivativesValueType; typedef JointPDFDerivativesType::RegionType JointPDFDerivativesRegionType; typedef JointPDFDerivativesType::SizeType JointPDFDerivativesSizeType; /** Get the value and derivatives for single valued optimizers. */ double GetValueAndDerivative( IndexType index, MeasureType& Value, DerivativeType& Derivative1 , DerivativeType& Derivative2 ) ; /** Get the value and derivatives for single valued optimizers. */ double GetValueAndDerivativeInv( IndexType index, MeasureType& Value, DerivativeType& Derivative1 , DerivativeType& Derivative2 ) ; /** Number of spatial samples to used to compute metric */ // itkSetClampMacro( NumberOfSpatialSamples, unsigned long, // 1, NumericTraits::max() ); //itkGetConstReferenceMacro( NumberOfSpatialSamples, unsigned long); /** Number of bins to used in the histogram. Typical value is 50. */ // itkSetClampMacro( NumberOfHistogramBins, unsigned long, // 1, NumericTraits::max() ); // itkGetConstReferenceMacro( NumberOfHistogramBins, unsigned long); void SetNumberOfHistogramBins(unsigned long nhb) { m_NumberOfHistogramBins=nhb+2*this->m_Padding;} unsigned long GetNumberOfHistogramBins() {return m_NumberOfHistogramBins;} void SetTransform(TransformPointer t){m_Transform=t;} TransformPointer GetTransform(){return m_Transform;} void SetInterpolator(InterpolatorPointer t){m_Interpolator=t;} InterpolatorPointer GetInterpolator(){ return m_Interpolator; } void GetProbabilities(); double ComputeMutualInformation() { /** Ray Razlighi changes : May 3, 2010: improves convergence. 1- The padding is lowered to 2. 2- The MI energy is changed to actual MI, please note the value of this MI is in the range of [0 min(H(x),H(y))]. in case you need it to be normalized. 3- The Natural logarithm is changed to log2. 4- In the ComputeMutualInformation() the iterator range has been changed to cover the entire PDF. 5- In the FitIndexInBins() the truncation by floor has been modified to round. 6- The normalization is done based on NomberOfHistogramBins-1 instead of NomberOfHistogramBins. */ float px,py,pxy; double mival = 0; double mi; unsigned long ct = 0; typename JointPDFType::IndexType index; for (unsigned int ii=0; iiGetPixel(mind); for (unsigned int jj=0; jjGetPixel(mind); float denom = px*py; index[0]=ii; index[1]=jj; //pxy=m_JointPDF->GetPixel(index); JointPDFValueType *pdfPtr = m_JointPDF->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ); // Move the pointer to the first affected bin int pdfMovingIndex = static_cast( jj ); pdfPtr += pdfMovingIndex; pxy=*(pdfPtr); mi=0; if (fabs(denom) > 0 ) { if (pxy/denom > 0) { //true mi mi = pxy*log(pxy/denom); //test mi //mi = 1.0 + log(pxy/denom); ct++; } } mival += mi; } // std::cout << " II " << ii << " JJ " << ii << " pxy " << pxy << " px " << px << std::endl; } this->m_Energy = -1.0*mival/log(2); return this->m_Energy; } virtual VectorType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(this->Superclass::m_FixedImage.GetPointer()); if (!img) return update; typename FixedImageType::SpacingType spacing=img->GetSpacing(); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); for (unsigned int dd=0; dd= static_cast(imagesize[dd]-1) ) return update; } CovariantVectorType fixedGradient; double loce=0.0; ParametersType fdvec1(ImageDimension); ParametersType fdvec2(ImageDimension); fdvec1.Fill(0); fdvec2.Fill(0); fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( oindex ); double nccm1=0; loce=this->GetValueAndDerivativeInv(oindex,nccm1,fdvec1,fdvec2); float eps=10; if ( loce > eps ) loce=eps; if ( loce < eps*(-1.0) ) loce=eps*(-1.0); for (int imd=0; imdm_MetricImage) this->m_MetricImage->SetPixel(oindex,loce); return update; } /* Normalizing the image to the range of [0 1] */ double GetMovingParzenTerm( double intensity ) { double windowTerm = static_cast( intensity ) - this->m_MovingImageTrueMin; windowTerm = windowTerm / ( this->m_MovingImageTrueMax - this->m_MovingImageTrueMin ) ; return windowTerm ; } double GetFixedParzenTerm( double intensity ) { double windowTerm = static_cast( intensity ) - this->m_FixedImageTrueMin; windowTerm = windowTerm / ( this->m_FixedImageTrueMax - this->m_FixedImageTrueMin ) ; return windowTerm ; } /* find the image index in the number of histogram bins */ unsigned int FitIndexInBins( double windowTerm ) { unsigned int movingImageParzenWindowIndex = static_cast( this->m_Padding + round( windowTerm * (float)(this->m_NumberOfHistogramBins - 1 - this->m_Padding))) ; // Make sure the extreme values are in valid bins if ( movingImageParzenWindowIndex < this->m_Padding ) { movingImageParzenWindowIndex = this->m_Padding -1 ; } else if ( movingImageParzenWindowIndex > (m_NumberOfHistogramBins - this->m_Padding ) ) { movingImageParzenWindowIndex = m_NumberOfHistogramBins - this->m_Padding - 1; } return movingImageParzenWindowIndex; } double FitContIndexInBins( double windowTerm ) { return ( (double) this->m_Padding + windowTerm*(float)(this->m_NumberOfHistogramBins-this->m_Padding)); } virtual VectorType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(this->Superclass::m_MovingImage.GetPointer()); if (!img) return update; typename FixedImageType::SpacingType spacing=img->GetSpacing(); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); for (unsigned int dd=0; dd= static_cast(imagesize[dd]-1) ) return update; } CovariantVectorType movingGradient; double loce=0.0; ParametersType fdvec1(ImageDimension); ParametersType fdvec2(ImageDimension); fdvec1.Fill(0); fdvec2.Fill(0); movingGradient = m_MovingImageGradientCalculator->EvaluateAtIndex( oindex ); double nccm1=0; loce=this->GetValueAndDerivative(oindex,nccm1,fdvec1,fdvec2); float eps=10; if ( loce > eps ) loce=eps; if ( loce < eps*(-1.0) ) loce=eps*(-1.0); for (int imd=0; imdm_MetricImage) { typedef ImageFileWriter writertype; typename writertype::Pointer w= writertype::New(); w->SetInput( this->m_MetricImage); w->SetFileName("ZZmetric.nii.gz"); w->Write(); } } void SetOpticalFlow(bool b){ m_OpticalFlow = b; } typename JointPDFType::Pointer GetJointPDF() { return m_JointPDF; } typename JointPDFType::Pointer GetJointHist() { return m_JointHist; } void SetFixedImageMask( FixedImageType* img) {m_FixedImageMask=img; } /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * iterators for the fixed image. */ struct GlobalDataStruct { FixedImageNeighborhoodIteratorType m_FixedImageIterator; }; /** The fixed image marginal PDF. */ mutable MarginalPDFType::Pointer m_FixedImageMarginalPDF; /** The moving image marginal PDF. */ mutable MarginalPDFType::Pointer m_MovingImageMarginalPDF; /** The joint PDF and PDF derivatives. */ typename JointPDFType::Pointer m_JointPDF; unsigned long m_NumberOfSpatialSamples; unsigned long m_NumberOfParameters; /** Variables to define the marginal and joint histograms. */ unsigned long m_NumberOfHistogramBins; double m_MovingImageNormalizedMin; double m_FixedImageNormalizedMin; double m_MovingImageTrueMin; double m_MovingImageTrueMax; double m_FixedImageTrueMin; double m_FixedImageTrueMax; double m_FixedImageBinSize; double m_MovingImageBinSize; protected: AvantsMutualInformationRegistrationFunction(); virtual ~AvantsMutualInformationRegistrationFunction() {}; void PrintSelf(std::ostream& os, Indent indent) const; private: AvantsMutualInformationRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typename JointPDFType::Pointer m_JointHist; typename JointPDFDerivativesType::Pointer m_JointPDFDerivatives; /** Typedefs for BSpline kernel and derivative functions. */ typedef BSplineKernelFunction<3> CubicBSplineFunctionType; typedef BSplineDerivativeKernelFunction<3> CubicBSplineDerivativeFunctionType; /** Cubic BSpline kernel for computing Parzen histograms. */ typename CubicBSplineFunctionType::Pointer m_CubicBSplineKernel; typename CubicBSplineDerivativeFunctionType::Pointer m_CubicBSplineDerivativeKernel; /** * Types and variables related to image derivative calculations. * If a BSplineInterpolationFunction is used, this class obtain * image derivatives from the BSpline interpolator. Otherwise, * image derivatives are computed using central differencing. */ typedef CovariantVector< double, itkGetStaticConstMacro(ImageDimension) > ImageDerivativesType; /** Boolean to indicate if the interpolator BSpline. */ bool m_InterpolatorIsBSpline; // boolean to determine if we use mono-modality assumption bool m_OpticalFlow; /** Typedefs for using BSpline interpolator. */ typedef BSplineInterpolateImageFunction BSplineInterpolatorType; /** Pointer to BSplineInterpolator. */ typename BSplineInterpolatorType::Pointer m_BSplineInterpolator; /** Typedefs for using central difference calculator. */ typedef CentralDifferenceImageFunction DerivativeFunctionType; /** Pointer to central difference calculator. */ typename DerivativeFunctionType::Pointer m_DerivativeCalculator; /** * Types and variables related to BSpline deformable transforms. * If the transform is of type third order BSplineDeformableTransform, * then we can speed up the metric derivative calculation by * only inspecting the parameters within the support region * of a mapped point. */ /** Boolean to indicate if the transform is BSpline deformable. */ bool m_TransformIsBSpline; /** The number of BSpline parameters per image dimension. */ long m_NumParametersPerDim; /** * The number of BSpline transform weights is the number of * of parameter in the support region (per dimension ). */ unsigned long m_NumBSplineWeights; /** * Enum of the deformabtion field spline order. */ enum { DeformationSplineOrder = 3 }; /** * Typedefs for the BSplineDeformableTransform. */ typedef BSplineDeformableTransform< CoordinateRepresentationType, ::itk::GetImageDimension::ImageDimension, DeformationSplineOrder> BSplineTransformType; typedef typename BSplineTransformType::WeightsType BSplineTransformWeightsType; typedef typename BSplineTransformType::ParameterIndexArrayType BSplineTransformIndexArrayType; /** * Variables used when transform is of type BSpline deformable. */ typename BSplineTransformType::Pointer m_BSplineTransform; /** * Cache pre-transformed points, weights, indices and * within support region flag. */ typedef typename BSplineTransformWeightsType::ValueType WeightsValueType; typedef Array2D BSplineTransformWeightsArrayType; typedef typename BSplineTransformIndexArrayType::ValueType IndexValueType; typedef Array2D BSplineTransformIndicesArrayType; typedef std::vector MovingImagePointArrayType; typedef std::vector BooleanArrayType; BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray; BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray; MovingImagePointArrayType m_PreTransformPointsArray; BooleanArrayType m_WithinSupportRegionArray; typename TFixedImage::SpacingType m_FixedImageSpacing; typename TFixedImage::PointType m_FixedImageOrigin; typedef FixedArray::ImageDimension> ParametersOffsetType; ParametersOffsetType m_ParametersOffset; mutable TransformPointer m_Transform; InterpolatorPointer m_Interpolator; InterpolatorPointer m_FixedImageInterpolator; InterpolatorPointer m_MovingImageInterpolator; GradientCalculatorPointer m_FixedImageGradientCalculator; GradientCalculatorPointer m_MovingImageGradientCalculator; FixedImagePointer m_FixedImageMask; MovingImagePointer m_MovingImageMask; double m_NormalizeMetric; float m_Normalizer; typedef BSplineInterpolateImageFunction pdfintType; typename pdfintType::Pointer pdfinterpolator; typedef BSplineInterpolateImageFunction dpdfintType; typename dpdfintType::Pointer dpdfinterpolator; typedef BSplineInterpolateImageFunction pdfintType2; typename pdfintType2::Pointer pdfinterpolator2; typename pdfintType2::Pointer pdfinterpolator3; unsigned int m_Padding; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkAvantsMutualInformationRegistrationFunction.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkAvantsPDEDeformableRegistrationFunction.h000066400000000000000000000250271147325206600306330ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAvantsPDEDeformableRegistrationFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkAvantsPDEDeformableRegistrationFunction_h_ #define _itkAvantsPDEDeformableRegistrationFunction_h_ #include "itkPDEDeformableRegistrationFunction.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkPointSet.h" namespace itk { /** \class AvantsPDEDeformableRegistrationFunction * * This is an abstract base class for all PDE functions which drives a * deformable registration algorithm. It is used by * PDEDeformationRegistrationFilter subclasses to compute the * output deformation field which will map a moving image onto * a fixed image. * * This class is templated over the fixed image type, moving image type * and the deformation field type. * * \sa AvantsPDEDeformableRegistrationFilter * \ingroup PDEDeformableRegistrationFunctions */ template class ITK_EXPORT AvantsPDEDeformableRegistrationFunction : public PDEDeformableRegistrationFunction { public: /** Standard class typedefs. */ typedef AvantsPDEDeformableRegistrationFunction Self; typedef PDEDeformableRegistrationFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods) */ itkTypeMacro( AvantsPDEDeformableRegistrationFunction, PDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef TMovingImage MovingImageType; typedef typename MovingImageType::ConstPointer MovingImagePointer; typedef typename TMovingImage::IndexType IndexType; enum { ImageDimension = MovingImageType::ImageDimension }; /** FixedImage image type. */ typedef TFixedImage FixedImageType; typedef typename FixedImageType::ConstPointer FixedImagePointer; typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; /** Deformation field type. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldTypePointer; typedef typename TDeformationField::PixelType VectorType; /** PointSet Types */ typedef itk::PointSet PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef Image MetricImageType; typedef typename Image::Pointer MetricImagePointer; /** Set the moving image. */ void SetMovingImage( const MovingImageType * ptr ) { Superclass::m_MovingImage = ptr; } /** Get the moving image. */ MovingImageType * GetMovingImage(void) { return const_cast(Superclass::m_MovingImage.GetPointer()); } /** Set the fixed image. */ void SetFixedImage( const FixedImageType * ptr ) { Superclass::m_FixedImage = ptr; } /** Get the fixed image. */ FixedImageType * GetFixedImage(void) { return const_cast(Superclass::m_FixedImage.GetPointer()); } /** Set the fixed image. */ void SetDeformationField( DeformationFieldTypePointer ptr ) { Superclass::m_DeformationField = ptr; } /** Get the fixed image. */ DeformationFieldTypePointer GetDeformationField(void) { return Superclass::m_DeformationField; } void SetEnergy( double e) { this->m_Energy=0.0;} double GetEnergy( ) { return this->m_Energy;} void SetGradientStep( double e) { this->m_GradientStep = e;} void SetMaxAllowedStep( double e) { this->m_MaxAllowedStep = e;} double GetGradientStep( ) { return this->m_GradientStep ;} void SetNormalizeGradient( bool e) { this->m_NormalizeGradient=e;} bool GetNormalizeGradient( ) { return this->m_NormalizeGradient;} /* * allows one to compute the metric everywhere */ void ComputeMetricImage() { bool makenewimage=false; typedef ImageRegionIteratorWithIndex ittype; FixedImageType* img =const_cast(this->m_FixedImage.GetPointer()); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); if (!m_MetricImage )makenewimage=true; else if (imagesize[0] != m_MetricImage->GetLargestPossibleRegion().GetSize()[0]) makenewimage = true; if (makenewimage) { m_MetricImage = MetricImageType::New(); m_MetricImage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); m_MetricImage->SetBufferedRegion(img->GetLargestPossibleRegion()); m_MetricImage->SetSpacing(img->GetSpacing()); m_MetricImage->SetOrigin(img->GetOrigin()); m_MetricImage->Allocate(); ittype it(m_MetricImage,m_MetricImage->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) it.Set(0); } return; } virtual double ComputeMetricAtPair(IndexType fixedindex, typename TDeformationField::PixelType vec) { return 0.0; } virtual VectorType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { bool m_Use1SidedDiff=false; VectorType update; update.Fill(0.0); typename FixedImageType::SpacingType spacing=this->GetFixedImage()->GetSpacing(); IndexType oindex = neighborhood.GetIndex(); typename TDeformationField::PixelType vec = this->m_DeformationField->GetPixel(oindex); float loce=0.0; double nccp1,nccm1; if(m_Use1SidedDiff) nccp1=this->ComputeMetricAtPair(oindex,vec); for (int imd=0; imdm_DeformationField->GetPixel(oindex); typename TDeformationField::PixelType fdvec2 = this->m_DeformationField->GetPixel(oindex); float step=0.1*spacing[imd]; fdvec1[imd]=vec[imd]+step; if (!m_Use1SidedDiff) nccp1=this->ComputeMetricAtPair(oindex,fdvec1); fdvec2[imd]=vec[imd]-step; nccm1=this->ComputeMetricAtPair(oindex,fdvec2); update[imd]=nccp1-nccm1; loce+=(nccp1+nccm1); } loce/=(2.0*(float)ImageDimension);//this->ComputeMetricAtPair(oindex,vec); this->m_Energy+=loce; if (m_MetricImage) m_MetricImage->SetPixel(oindex,loce); return update*this->m_GradientStep; } virtual VectorType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { bool m_Use1SidedDiff=false; VectorType update; update.Fill(0.0); typename FixedImageType::SpacingType spacing=this->GetFixedImage()->GetSpacing(); IndexType oindex = neighborhood.GetIndex(); typename TDeformationField::PixelType vec = this->m_DeformationField->GetPixel(oindex); float loce=0.0; double nccp1,nccm1; if(m_Use1SidedDiff) nccp1=this->ComputeMetricAtPair(oindex,vec); for (int imd=0; imdm_DeformationField->GetPixel(oindex); typename TDeformationField::PixelType fdvec2 = this->m_DeformationField->GetPixel(oindex); float step=0.1*spacing[imd]; fdvec1[imd]=vec[imd]+step; if (!m_Use1SidedDiff) nccp1=this->ComputeMetricAtPair(oindex,fdvec1); fdvec2[imd]=vec[imd]-step; nccm1=this->ComputeMetricAtPair(oindex,fdvec2); update[imd]=nccp1-nccm1; loce+=(nccp1+nccm1); } loce/=(2.0*(float)ImageDimension);//this->ComputeMetricAtPair(oindex,vec); this->m_Energy+=loce; if (m_MetricImage) m_MetricImage->SetPixel(oindex,loce); // float mag=0; // for (int imd=0; imd 1) update.Fill(0.0); // //std::cout << " update " << update << " ind " << oindex << std::endl; return update*this->m_GradientStep; } void SetIterations( unsigned int i ) { this->m_Iterations=i; } /** this parameter is used to set a minimum value for the metric -- a minimum value that is treated as " close enough" -- */ void SetRobustnessParameter( float i ) { this->m_RobustnessParameter=i; } void SetFixedPointSet( PointSetPointer p ) { this->m_FixedPointSet=p; } void SetMovingPointSet( PointSetPointer p ) { this->m_MovingPointSet=p; } bool ThisIsAPointSetMetric() { return this->m_IsPointSetMetric; } protected: AvantsPDEDeformableRegistrationFunction() { this->m_MovingImage = NULL; m_MetricImage = NULL; this->m_FixedImage = NULL; this->m_DeformationField = NULL; this->m_Energy = 0.0; m_BestEnergy = 0.0; this->m_NormalizeGradient = true; this->m_GradientStep = 1.0; m_AverageStepMag=0; m_MaxStepMag=0; m_AvgCt=0; m_Iterations=0; this->m_FixedPointSet=NULL; this->m_MovingPointSet=NULL; this->m_IsPointSetMetric=false; this->m_RobustnessParameter=-1.e12; } ~AvantsPDEDeformableRegistrationFunction() {} void PrintSelf(std::ostream& os, Indent indent) const { this->PrintSelf(os, indent); }; mutable double m_BestEnergy; mutable double m_LastLastEnergy; mutable double m_MaxAllowedStep; mutable double m_AverageStepMag; mutable unsigned long m_AvgCt; mutable unsigned long m_Iterations; mutable double m_MaxStepMag; PointSetPointer m_FixedPointSet; PointSetPointer m_MovingPointSet; bool m_IsPointSetMetric; MetricImagePointer m_MetricImage; float m_RobustnessParameter; private: AvantsPDEDeformableRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkCrossCorrelationRegistrationFunction.cxx000066400000000000000000000365041147325206600307350ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCrossCorrelationRegistrationFunction.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkCrossCorrelationRegistrationFunction_txx_ #define _itkCrossCorrelationRegistrationFunction_txx_ #include "itkCrossCorrelationRegistrationFunction.h" #include "itkExceptionObject.h" #include "vnl/vnl_math.h" #include "itkImageFileWriter.h" #include "itkImageLinearConstIteratorWithIndex.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkMeanImageFilter.h" #include "itkMedianImageFilter.h" #include "itkImageFileWriter.h" #include namespace itk { /* * Default constructor */ template CrossCorrelationRegistrationFunction ::CrossCorrelationRegistrationFunction() { m_AvgMag=0; m_Iteration=0; RadiusType r; unsigned int j; for( j = 0; j < ImageDimension; j++ ) { r[j] = 2; } this->SetRadius(r); this->m_Energy = 0.0; m_TimeStep = 1.0; m_DenominatorThreshold = 1e-9; m_IntensityDifferenceThreshold = 0.001; Superclass::m_MovingImage = NULL; m_MetricGradientImage = NULL; Superclass::m_FixedImage = NULL; m_FixedImageSpacing.Fill( 1.0 ); m_FixedImageOrigin.Fill( 0.0 ); m_FixedImageGradientCalculator = GradientCalculatorType::New(); binaryimage=NULL; m_FullyRobust=false; m_MovingImageGradientCalculator = GradientCalculatorType::New(); typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_MovingImageInterpolator = static_cast( interp.GetPointer() ); for (int i=0; i<5; i++) finitediffimages[i]=NULL; m_NumberOfHistogramBins=32; m_FixedImageMask=NULL; m_MovingImageMask=NULL; } /* * Standard "PrintSelf" method. */ template void CrossCorrelationRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); /* os << indent << "MovingImageIterpolator: "; os << m_MovingImageInterpolator.GetPointer() << std::endl; os << indent << "FixedImageGradientCalculator: "; os << m_FixedImageGradientCalculator.GetPointer() << std::endl; os << indent << "DenominatorThreshold: "; os << m_DenominatorThreshold << std::endl; os << indent << "IntensityDifferenceThreshold: "; os << m_IntensityDifferenceThreshold << std::endl; */ } /* * Set the function state values before each iteration */ template void CrossCorrelationRegistrationFunction ::InitializeIteration() { typedef ImageRegionIteratorWithIndex ittype; if( !Superclass::m_MovingImage || !Superclass::m_FixedImage || !m_MovingImageInterpolator ) { itkExceptionMacro( << "MovingImage, FixedImage and/or Interpolator not set" ); throw ExceptionObject(__FILE__,__LINE__); } // cache fixed image information m_FixedImageSpacing = Superclass::m_FixedImage->GetSpacing(); m_FixedImageOrigin = Superclass::m_FixedImage->GetOrigin(); // setup gradient calculator m_FixedImageGradientCalculator->SetInputImage( Superclass::m_FixedImage ); m_MovingImageGradientCalculator->SetInputImage( Superclass::m_MovingImage ); // setup moving image interpolator m_MovingImageInterpolator->SetInputImage( Superclass::m_MovingImage ); unsigned long numpix=1; for (int i=0; iGetLargestPossibleRegion().GetSize()[i]; m_MetricTotal=0.0; this->m_Energy=0.0; typedef itk::DiscreteGaussianImageFilter dgf1; // typedef itk::DiscreteGaussianImageFilter dgf; typedef itk::MeanImageFilter dgf; typedef itk::MedianImageFilter dgf2; // compute the normalizer m_Normalizer = 0.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; } m_Normalizer /= static_cast( ImageDimension ); typename FixedImageType::SpacingType spacing=this->GetFixedImage()->GetSpacing(); bool makeimg=false; if ( m_Iteration==0 ) makeimg=true; else if (!finitediffimages[0] ) makeimg=true; else { for (unsigned int dd=0; ddGetLargestPossibleRegion().GetSize()[dd] != this->GetFixedImage()->GetLargestPossibleRegion().GetSize()[dd] ) makeimg=true; } } if (makeimg) { finitediffimages[0]=this->MakeImage(); finitediffimages[1]=this->MakeImage(); finitediffimages[2]=this->MakeImage(); finitediffimages[3]=this->MakeImage(); finitediffimages[4]=this->MakeImage(); } //float sig=15.; RadiusType r; for( int j = 0; j < ImageDimension; j++ ) r[j] = this->GetRadius()[j]; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator tIter(this->GetFixedImage(),this->GetFixedImage()->GetLargestPossibleRegion() ); typename FixedImageType::SizeType imagesize=this->GetFixedImage()->GetLargestPossibleRegion().GetSize(); // compute local means // typedef itk::ImageRegionIteratorWithIndex Iterator; // // The following change was made to speed up the correlation calculation. // typedef std::deque SumQueueType; SumQueueType Qsuma2; SumQueueType Qsumb2; SumQueueType Qsuma; SumQueueType Qsumb; SumQueueType Qsumab; SumQueueType Qcount; ImageLinearConstIteratorWithIndex outIter( this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); outIter.SetDirection( 0 ); outIter.GoToBegin(); while( !outIter.IsAtEnd() ) { // Push the zeros onto the stack that are outsized the image boundary at // the beginning of the line. Qsuma2 = SumQueueType( r[0], 0.0 ); Qsumb2 = SumQueueType( r[0], 0.0 ); Qsuma = SumQueueType( r[0], 0.0 ); Qsumb = SumQueueType( r[0], 0.0 ); Qsumab = SumQueueType( r[0], 0.0 ); Qcount = SumQueueType( r[0], 0.0 ); NeighborhoodIterator hoodIt( this->GetRadius(), this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); IndexType oindex = outIter.GetIndex(); hoodIt.SetLocation( oindex ); unsigned int hoodlen = hoodIt.Size(); // Now add the rest of the values from each hyperplane for( unsigned int i = r[0]; i < ( 2*r[0] + 1 ); i++ ) { float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; for( unsigned int indct = i; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->GetFixedImage()->GetPixel( index ); float b = this->GetMovingImage()->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } while( !outIter.IsAtEndOfLine() ) { // Test to see if there are any voxels we need to handle in the current // window. float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; typename SumQueueType::iterator itcount = Qcount.begin(); while( itcount != Qcount.end() ) { count += *itcount; ++itcount; } // If there are values, we need to calculate the different quantities if( count > 0 ) { typename SumQueueType::iterator ita2 = Qsuma2.begin(); typename SumQueueType::iterator itb2 = Qsumb2.begin(); typename SumQueueType::iterator ita = Qsuma.begin(); typename SumQueueType::iterator itb = Qsumb.begin(); typename SumQueueType::iterator itab = Qsumab.begin(); while( ita2 != Qsuma2.end() ) { suma2 += *ita2; sumb2 += *itb2; suma += *ita; sumb += *itb; sumab += *itab; ++ita2; ++itb2; ++ita; ++itb; ++itab; } float fixedMean = suma / count; float movingMean = sumb / count; float sff = suma2 - fixedMean*suma - fixedMean*suma + count*fixedMean*fixedMean; float smm = sumb2 - movingMean*sumb - movingMean*sumb + count*movingMean*movingMean; float sfm = sumab - movingMean*suma - fixedMean*sumb + count*movingMean*fixedMean; IndexType oindex = outIter.GetIndex(); float val = this->GetFixedImage()->GetPixel( oindex ) - fixedMean; this->finitediffimages[0]->SetPixel( oindex, val ); val = this->GetMovingImage()->GetPixel( oindex ) - movingMean; this->finitediffimages[1]->SetPixel( oindex, val ); this->finitediffimages[2]->SetPixel( oindex, sfm );//A this->finitediffimages[3]->SetPixel( oindex, sff );//B this->finitediffimages[4]->SetPixel( oindex, smm );//C } // Increment the iterator and check to see if we're at the end of the // line. If so, go to the next line. Otherwise, add the // the values for the next hyperplane. ++outIter; if( !outIter.IsAtEndOfLine() ) { hoodIt.SetLocation( outIter.GetIndex() ); suma2 = 0.0; sumb2 = 0.0; suma = 0.0; sumb = 0.0; sumab = 0.0; count = 0.0; for( unsigned int indct = 2*r[0]; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->GetFixedImage()->GetPixel( index ); float b = this->GetMovingImage()->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } Qsuma2.pop_front(); Qsumb2.pop_front(); Qsuma.pop_front(); Qsumb.pop_front(); Qsumab.pop_front(); Qcount.pop_front(); } outIter.NextLine(); } //m_FixedImageGradientCalculator->SetInputImage(finitediffimages[0]); m_MaxMag=0.0; m_MinMag=9.e9; m_AvgMag=0.0; m_Iteration++; } /* * Compute the ncc metric everywhere */ template typename TDeformationField::PixelType CrossCorrelationRegistrationFunction ::ComputeMetricAtPairB(IndexType oindex, typename TDeformationField::PixelType vec) { typename TDeformationField::PixelType deriv; deriv.Fill(0.0); double sff=0.0; double smm=0.0; double sfm=0.0; // double fixedValue; // double movingValue; sff=0.0; smm=0.0; sfm=0.0; PointType mappedPoint; CovariantVectorType gradI,gradJ; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( oindex ) < 0.25 ) return deriv; sfm=finitediffimages[2]->GetPixel(oindex); sff=finitediffimages[3]->GetPixel(oindex); smm=finitediffimages[4]->GetPixel(oindex); if ( sff == 0.0 || smm == 0.0) return deriv; this->localCrossCorrelation=0; if (sff*smm > 1.e-5) this->localCrossCorrelation = sfm*sfm / ( sff * smm ); IndexType index=oindex;//hoodIt.GetIndex(indct); gradI = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); // gradJ = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); float Ji=finitediffimages[1]->GetPixel(index); float Ii=finitediffimages[0]->GetPixel(index); m_TEMP=2.0*sfm/(sff*smm)*( Ji - sfm/sff*Ii ); for (int qq=0; qqlocalCrossCorrelation*(-1.0) < this->m_RobustnessParameter) deriv.Fill(0); // if ( this->localCrossCorrelation*(-1.0) < this->m_RobustnessParameter) { // std::cout << " localC " << this->localCrossCorrelation << std::endl; } if ( this->localCrossCorrelation < 1 ) this->m_Energy-=this->localCrossCorrelation; return deriv;//localCrossCorrelation; } /* * Compute the ncc metric everywhere */ template typename TDeformationField::PixelType CrossCorrelationRegistrationFunction ::ComputeMetricAtPairC(IndexType oindex, typename TDeformationField::PixelType vec) { typename TDeformationField::PixelType deriv; deriv.Fill(0.0); double sff=0.0; double smm=0.0; double sfm=0.0; // double fixedValue; // double movingValue; sff=0.0; smm=0.0; sfm=0.0; PointType mappedPoint; CovariantVectorType gradI,gradJ; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( oindex ) < 0.25 ) return deriv; sfm=finitediffimages[2]->GetPixel(oindex); sff=finitediffimages[3]->GetPixel(oindex); smm=finitediffimages[4]->GetPixel(oindex); if ( sff == 0.0 || smm == 0.0) return deriv; IndexType index=oindex;//hoodIt.GetIndex(indct); if (sff == 0.0) sff=1.0; if (smm == 0.0) smm=1.0; ///gradI = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); gradJ = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); float Ji=finitediffimages[1]->GetPixel(index); float Ii=finitediffimages[0]->GetPixel(index); for (int qq=0; qqlocalCrossCorrelation = sfm*sfm / ( sff * smm ); else if (sff == 0.0 && smm == 0) this->localCrossCorrelation = 1.0; else this->localCrossCorrelation = 1.0; // if ( this->localCrossCorrelation*(-1.0) < this->m_RobustnessParameter) deriv.Fill(0); return deriv;//localCrossCorrelation; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkCrossCorrelationRegistrationFunction.h000066400000000000000000000347511147325206600303640ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCrossCorrelationRegistrationFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkCrossCorrelationRegistrationFunction_h_ #define _itkCrossCorrelationRegistrationFunction_h_ #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkPoint.h" #include "itkCovariantVector.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkCentralDifferenceImageFunction.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkAvantsMutualInformationRegistrationFunction.h" namespace itk { /** * \class CrossCorrelationRegistrationFunction * * This class encapsulate the PDE which drives the demons registration * algorithm. It is used by CrossCorrelationRegistrationFilter to compute the * output deformation field which will map a moving image onto a * a fixed image. * * Non-integer moving image values are obtained by using * interpolation. The default interpolator is of type * LinearInterpolateImageFunction. The user may set other * interpolators via method SetMovingImageInterpolator. Note that the input * interpolator must derive from baseclass InterpolateImageFunction. * * This class is templated over the fixed image type, moving image type, * and the deformation field type. * * \warning This filter assumes that the fixed image type, moving image type * and deformation field type all have the same number of dimensions. * * \sa CrossCorrelationRegistrationFilter * \ingroup FiniteDifferenceFunctions */ template class ITK_EXPORT CrossCorrelationRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField> { public: /** Standard class typedefs. */ typedef CrossCorrelationRegistrationFunction Self; typedef AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( CrossCorrelationRegistrationFunction, AvantsPDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::MetricImageType MetricImageType; typedef typename Superclass::MetricImageType::Pointer MetricImagePointer; typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; /** Deformation field type. */ typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; typedef typename TDeformationField::PixelType VectorType; typedef CovariantVector GradientPixelType; typedef Image GradientImageType; typedef SmartPointer GradientImagePointer; typedef GradientRecursiveGaussianImageFilter< MetricImageType,GradientImageType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; typedef Image BinaryImageType; typedef typename BinaryImageType::Pointer BinaryImagePointer; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; // typedef typename Superclass::NeighborhoodType BoundaryNeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Interpolator type. */ typedef double CoordRepType; typedef InterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef typename InterpolatorType::PointType PointType; typedef LinearInterpolateImageFunction DefaultInterpolatorType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** Gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Set the moving image interpolator. */ void SetMovingImageInterpolator( InterpolatorType * ptr ) { m_MovingImageInterpolator = ptr; } /** Get the moving image interpolator. */ InterpolatorType * GetMovingImageInterpolator(void) { return m_MovingImageInterpolator; } typename TDeformationField::PixelType ComputeMetricAtPairB(IndexType fixedindex, typename TDeformationField::PixelType vec ); typename TDeformationField::PixelType ComputeMetricAtPairC(IndexType fixedindex, typename TDeformationField::PixelType vec ); /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void *GlobalData) const { return m_TimeStep; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const { delete (GlobalDataStruct *) GlobalData; } /** Set the object's state before each iteration. */ virtual void InitializeIteration(); double ComputeCrossCorrelation() { if (finitediffimages[0]) { double totalcc=0; unsigned long ct=0; typedef ImageRegionIteratorWithIndex ittype; ittype it(this->finitediffimages[0],this->finitediffimages[0]->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) { IndexType oindex=it.GetIndex(); double sfm=finitediffimages[2]->GetPixel(oindex); double sff=finitediffimages[3]->GetPixel(oindex); double smm=finitediffimages[4]->GetPixel(oindex); double cc=0; if ( fabs(sff*smm) > 0) { cc+=sfm*sfm/(sff*smm); ct++; } if ( this->m_MetricImage) { this->m_MetricImage->SetPixel(oindex,cc); //if ( fabs(cc) > 0) // std::cout << " set cc " << cc << std::endl; } totalcc+=cc; } this->m_Energy=totalcc/(float)ct*(-1.0); return this->m_Energy; } else return 0; } virtual VectorType OpticalFlowUpdate(const NeighborhoodType &neighborhood) { // Get fixed image related information IndexType index=neighborhood.GetIndex(); typename TDeformationField::PixelType vec = Superclass::m_DeformationField->GetPixel(index); VectorType update; update.Fill(0.0); double fixedValue; CovariantVectorType fixedGradient; double fixedGradientSquaredMagnitude = 0; fixedValue = (double) Superclass::Superclass::m_FixedImage->GetPixel( index ); fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); for( unsigned int j = 0; j < ImageDimension; j++ ) { fixedGradientSquaredMagnitude += vnl_math_sqr( fixedGradient[j] ); } double movingValue; int j; PointType mappedPoint; for( j = 0; j < ImageDimension; j++ ) { mappedPoint[j] = double( index[j] ) * m_FixedImageSpacing[j] + m_FixedImageOrigin[j]; mappedPoint[j] += vec[j]; } if( m_MovingImageInterpolator->IsInsideBuffer( mappedPoint ) ) { movingValue = m_MovingImageInterpolator->Evaluate( mappedPoint ); } else { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } double speedValue = fixedValue - movingValue; if (fabs(speedValue) < this->m_RobustnessParameter) speedValue=0; double denominator = vnl_math_sqr( speedValue ) / m_Normalizer + fixedGradientSquaredMagnitude; double m_DenominatorThreshold = 1e-9; double m_IntensityDifferenceThreshold = 0.001; if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold || denominator < m_DenominatorThreshold ) { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } for( j = 0; j < ImageDimension; j++ ) { update[j] = speedValue * fixedGradient[j] / denominator; } return update; } void SetFixedImageMask( MetricImageType* img) {m_FixedImageMask=img; } virtual VectorType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); if (!img) return update; update=this->ComputeMetricAtPairB(oindex,update); return update; } virtual VectorType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); if (!img) return update; update=this->ComputeMetricAtPairC(oindex,update); return update; } void SetFullyRobust(bool b){m_FullyRobust=b;} void GetProbabilities(); double localCrossCorrelation; float m_TEMP; MetricImagePointer MakeImage() { typedef ImageRegionIteratorWithIndex ittype; typedef ImageRegionIteratorWithIndex ittype2; FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); this->m_MetricImage = MetricImageType::New(); this->m_MetricImage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); this->m_MetricImage->SetBufferedRegion(img->GetLargestPossibleRegion()); this->m_MetricImage->SetSpacing(img->GetSpacing()); this->m_MetricImage->SetOrigin(img->GetOrigin()); this->m_MetricImage->SetDirection(img->GetDirection()); this->m_MetricImage->Allocate(); this->m_MetricImage->FillBuffer(0); bool makebinimg=false; if (makebinimg) { m_Iteration=0; binaryimage = BinaryImageType::New(); binaryimage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); binaryimage->SetBufferedRegion(img->GetLargestPossibleRegion()); binaryimage->SetSpacing(img->GetSpacing()); binaryimage->SetOrigin(img->GetOrigin()); binaryimage->Allocate(); ittype2 it(binaryimage,binaryimage->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) it.Set(1); } return this->m_MetricImage; } protected: CrossCorrelationRegistrationFunction(); ~CrossCorrelationRegistrationFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * iterators for the fixed image. */ struct GlobalDataStruct { FixedImageNeighborhoodIteratorType m_FixedImageIterator; }; private: CrossCorrelationRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Cache fixed image information. */ typename TFixedImage::SpacingType m_FixedImageSpacing; typename TFixedImage::PointType m_FixedImageOrigin; /** Function to compute derivatives of the fixed image. */ GradientCalculatorPointer m_FixedImageGradientCalculator; GradientCalculatorPointer m_MovingImageGradientCalculator; /** Function to interpolate the moving image. */ InterpolatorPointer m_MovingImageInterpolator; /** The global timestep. */ TimeStepType m_TimeStep; /** Threshold below which the denominator term is considered zero. */ double m_DenominatorThreshold; /** Threshold below which two intensity value are assumed to match. */ double m_IntensityDifferenceThreshold; mutable double m_MetricTotal; mutable float m_MinMag; mutable float m_MaxMag; mutable float m_AvgMag; mutable float m_Thresh; GradientImagePointer m_MetricGradientImage; MetricImagePointer finitediffimages[5]; BinaryImagePointer binaryimage; MetricImagePointer m_FixedImageMask; MetricImagePointer m_MovingImageMask; typedef itk::AvantsMutualInformationRegistrationFunction MetricType2; typename MetricType2::Pointer m_MIFunct; unsigned int m_NumberOfHistogramBins; bool m_FullyRobust; unsigned int m_Iteration; float m_Normalizer; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkCrossCorrelationRegistrationFunction.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkExpectationBasedPointSetRegistrationFunction.h000066400000000000000000000320401147325206600317660ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkExpectationBasedPointSetRegistrationFunction.h,v $ Language: C++ Date: $Date: 2009/02/11 02:37:46 $ Version: $Revision: 1.21 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkExpectationBasedPointSetRegistrationFunction_h_ #define _itkExpectationBasedPointSetRegistrationFunction_h_ #include "itkPointSetFunction.h" #include "itkGaussianProbabilityDensityFunction.h" #include "itkKdTreeGenerator.h" #include "itkListSample.h" #include "itkMatrix.h" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkMeshSource.h" #include "itkPointSet.h" #include "itkVector.h" #include "itkWeightedCentroidKdTreeGenerator.h" #include "itkPDEDeformableRegistrationFunction.h" #include "itkPoint.h" #include "itkCovariantVector.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkCentralDifferenceImageFunction.h" namespace itk { /** * \class ExpectationBasedPointSetRegistrationFunction * * This class encapsulate the PDE which drives the demons registration * algorithm. It is used by ExpectationBasedPointSetRegistrationFilter to compute the * output deformation field which will map a moving image onto a * a fixed image. * * Non-integer moving image values are obtained by using * interpolation. The default interpolator is of type * LinearInterpolateImageFunction. The user may set other * interpolators via method SetMovingImageInterpolator. Note that the input * interpolator must derive from baseclass InterpolateImageFunction. * * This class is templated over the fixed image type, moving image type, * and the deformation field type. * * \warning This filter assumes that the fixed image type, moving image type * and deformation field type all have the same number of dimensions. * * \sa ExpectationBasedPointSetRegistrationFilter * \ingroup FiniteDifferenceFunctions */ template class ITK_EXPORT ExpectationBasedPointSetRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField> { public: /** Standard class typedefs. */ typedef ExpectationBasedPointSetRegistrationFunction Self; typedef PDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( ExpectationBasedPointSetRegistrationFunction, PDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::PointType ImagePointType; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; typedef typename FixedImageType::SpacingType SpacingType; /** Deformation field type. */ typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; typedef typename DeformationFieldType::PixelType VectorType; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); itkStaticConstMacro(MeasurementDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** PointSet Types */ typedef TPointSet PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef std::vector LabelSetType; // typedef long PointDataType; typedef Vector MeasurementVectorType; typedef typename Statistics::ListSample SampleType; typedef typename Statistics::WeightedCentroidKdTreeGenerator TreeGeneratorType; typedef typename TreeGeneratorType::KdTreeType:: InstanceIdentifierVectorType NeighborhoodIdentifierType; /** Bspline stuff */ typedef PointSet BSplinePointSetType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::WeightsContainerType BSplineWeightsType; typedef typename BSplineFilterType::PointDataImageType ControlPointLatticeType; typedef typename BSplineFilterType::ArrayType ArrayType; /** Other typedef */ typedef float RealType; typedef float OutputType; typedef typename Statistics ::MersenneTwisterRandomVariateGenerator RandomizerType; typedef typename Statistics ::GaussianProbabilityDensityFunction GaussianType; /** Fixed image gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Moving image gradient calculator type. */ typedef CentralDifferenceImageFunction MovingImageGradientCalculatorType; typedef typename MovingImageGradientCalculatorType::Pointer MovingImageGradientCalculatorPointer; /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void * itkNotUsed(GlobalData)) const { return m_TimeStep; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); global->m_SumOfSquaredDifference = 0.0; global->m_NumberOfPixelsProcessed = 0L; global->m_SumOfSquaredChange = 0; return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const; void ExpectationLandmarkField(float weight, bool whichdirection); void FastExpectationLandmarkField(float weight, bool whichdirection, long whichlabel, bool dobsp); /** Set the object's state before each iteration. */ virtual void InitializeIteration(); /** This method is called by a finite difference solver image filter at * each pixel that does not lie on a data set boundary */ virtual PixelType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)); virtual PixelType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)); /** Get the metric value. The metric value is the mean square difference * in intensity between the fixed image and transforming moving image * computed over the the overlapping region between the two images. */ virtual double GetMetric() const { return m_Metric; } /** Get the rms change in deformation field. */ virtual double GetRMSChange() const { return m_RMSChange; } /** Set/Get the threshold below which the absolute difference of * intensity yields a match. When the intensities match between a * moving and fixed image pixel, the update vector (for that * iteration) will be the zero vector. Default is 0.001. */ virtual void SetEuclideanDistanceThreshold(double); virtual double GetEuclideanDistanceThreshold() const; void SetFixedPointSetSigma ( float f ) { this->m_FixedPointSetSigma=f; } float GetFixedPointSetSigma ( ) { return this->m_FixedPointSetSigma; } void SetMovingPointSetSigma ( float f ) { this->m_MovingPointSetSigma=f; } float GetMovingPointSetSigma ( ) { return this->m_MovingPointSetSigma; } void SetKNeighborhood( unsigned int n ) { this->m_KNeighborhood = n; } unsigned int GetKNeighborhood() { return this->m_KNeighborhood; } void SetUseSymmetricMatching(unsigned int b) { this->m_UseSymmetricMatching=b; } protected: ExpectationBasedPointSetRegistrationFunction(); ~ExpectationBasedPointSetRegistrationFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * information for computing the metric. */ struct GlobalDataStruct { double m_SumOfSquaredDifference; unsigned long m_NumberOfPixelsProcessed; double m_SumOfSquaredChange; }; void SetUpKDTrees(long whichlabel); private: ExpectationBasedPointSetRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Cache fixed image information. */ SpacingType m_FixedImageSpacing; ImagePointType m_FixedImageOrigin; double m_Normalizer; /** Function to compute derivatives of the fixed image. */ GradientCalculatorPointer m_FixedImageGradientCalculator; /** Function to compute derivatives of the moving image. */ MovingImageGradientCalculatorPointer m_MovingImageGradientCalculator; bool m_UseMovingImageGradient; /** The global timestep. */ TimeStepType m_TimeStep; /** Threshold below which the denominator term is considered zero. */ double m_DenominatorThreshold; /** Threshold below which two intensity value are assumed to match. */ double m_EuclideanDistanceThreshold; /** The metric value is the mean square difference in intensity between * the fixed image and transforming moving image computed over the * the overlapping region between the two images. */ mutable double m_Metric; mutable double m_SumOfSquaredDifference; mutable unsigned long m_NumberOfPixelsProcessed; mutable double m_RMSChange; mutable double m_SumOfSquaredChange; /** Mutex lock to protect modification to metric. */ mutable SimpleFastMutexLock m_MetricCalculationLock; DeformationFieldTypePointer m_DerivativeFixedField; DeformationFieldTypePointer m_DerivativeMovingField; float m_FixedPointSetSigma; float m_MovingPointSetSigma; float m_LandmarkEnergy; unsigned int m_KNeighborhood; unsigned int m_BucketSize; RealType m_Sigma; typename TreeGeneratorType::Pointer m_FixedKdTreeGenerator; typename SampleType::Pointer m_FixedSamplePoints; typename TreeGeneratorType::Pointer m_MovingKdTreeGenerator; typename SampleType::Pointer m_MovingSamplePoints; typename RandomizerType::Pointer m_Randomizer; bool m_Normalize; LabelSetType m_LabelSet; unsigned int m_UseSymmetricMatching; typename BSplinePointSetType::Pointer m_bpoints; typename BSplineWeightsType::Pointer m_bweights; unsigned int m_bcount; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkExpectationBasedPointSetRegistrationFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkExpectationBasedPointSetRegistrationFunction.txx000066400000000000000000000604211147325206600323660ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkExpectationBasedPointSetRegistrationFunction.txx,v $ Language: C++ Date: $Date: 2009/03/09 17:03:46 $ Version: $Revision: 1.25 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkExpectationBasedPointSetRegistrationFunction_txx_ #define _itkExpectationBasedPointSetRegistrationFunction_txx_ #include "itkExpectationBasedPointSetRegistrationFunction.h" #include "itkExceptionObject.h" #include "vnl/vnl_math.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkPointSet.h" namespace itk { /* * Default constructor */ template ExpectationBasedPointSetRegistrationFunction ::ExpectationBasedPointSetRegistrationFunction() { RadiusType r; unsigned int j; for( j = 0; j < ImageDimension; j++ ) { r[j] = 0; } this->SetRadius(r); m_TimeStep = 1.0; m_DenominatorThreshold = 1e-9; m_EuclideanDistanceThreshold =0.01; this->SetMovingImage(NULL); this->SetFixedImage(NULL); m_FixedImageSpacing.Fill( 1.0 ); m_FixedImageOrigin.Fill( 0.0 ); m_Normalizer = 1.0; m_FixedImageGradientCalculator = GradientCalculatorType::New(); m_Metric = NumericTraits::max(); m_SumOfSquaredDifference = 0.0; m_NumberOfPixelsProcessed = 0L; m_RMSChange = NumericTraits::max(); m_SumOfSquaredChange = 0.0; this->m_KNeighborhood=100; m_MovingImageGradientCalculator = MovingImageGradientCalculatorType::New(); m_UseMovingImageGradient = false; this->m_FixedPointSet=NULL; this->m_MovingPointSet=NULL; this->m_DerivativeFixedField=NULL; this->m_DerivativeMovingField=NULL; this->m_IsPointSetMetric=true; this->m_UseSymmetricMatching=100000; this->m_Iterations=0; } /* * Standard "PrintSelf" method. */ template void ExpectationBasedPointSetRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); } /** * */ template void ExpectationBasedPointSetRegistrationFunction ::SetEuclideanDistanceThreshold(double threshold) { m_EuclideanDistanceThreshold = threshold; } /** * */ template double ExpectationBasedPointSetRegistrationFunction ::GetEuclideanDistanceThreshold() const { return m_EuclideanDistanceThreshold; } /* * Set the function state values before each iteration */ template void ExpectationBasedPointSetRegistrationFunction ::ExpectationLandmarkField(float weight, bool whichdirection) { typedef ImageRegionIteratorWithIndex Iterator; SpacingType spacing = this->GetFixedImage()->GetSpacing(); unsigned long sz1=this->m_FixedPointSet->GetNumberOfPoints(); unsigned long sz2=this->m_MovingPointSet->GetNumberOfPoints(); if (!whichdirection) { sz2=this->m_FixedPointSet->GetNumberOfPoints(); sz1=this->m_MovingPointSet->GetNumberOfPoints(); } typedef vnl_matrix MatrixType; MatrixType EucDist(sz1,sz2); EucDist.fill(0); MatrixType fixedlms(sz1,ImageDimension); MatrixType movinglms(sz2,ImageDimension); fixedlms.fill(0); movinglms.fill(0); if ( sz1 <= 0 || sz2 <= 0 ) { return; } DeformationFieldTypePointer lmField=this->m_DerivativeFixedField; if (!whichdirection) lmField=this->m_DerivativeMovingField; float inweight=weight; this->m_LandmarkEnergy=0.0; float max=0; unsigned long bestindex=0; std::cout << " sz1 " << sz1 << " sz2 "<m_FixedPointSet->GetPoint(ii,&fixedpoint); else this->m_MovingPointSet->GetPoint(ii,&fixedpoint); if (whichdirection) this->m_FixedPointSet->GetPointData(ii,&fixedlabel); else this->m_MovingPointSet->GetPointData(ii,&fixedlabel); float min = 1.e9; ImagePointType fpt; IndexType oindex; for (int j=0; jGetFixedImage()->TransformPhysicalPointToIndex(fpt,oindex); if (!convok) std::cout <<" fpt " << fpt << std::endl; // if whichdirection is true, then the fixed direction, else moving for (unsigned long jj=0; jjm_MovingPointSet->GetPoint(jj,&movingpoint); else this->m_FixedPointSet->GetPoint(jj,&movingpoint); ImagePointType mpt; for (int j=0; jGetMovingImage()->TransformPhysicalPointToIndex(mpt,movingindex); double prob=0; if (convok) { float mag=0.0; VectorType force; for (int j=0; jm_FixedPointSetSigma; if (!whichdirection) sigma=this->m_MovingPointSetSigma; prob=exp(-1.0*mag/sigma); PointDataType movinglabel=0; if (whichdirection) this->m_MovingPointSet->GetPointData(jj,&movinglabel); else this->m_FixedPointSet->GetPointData(jj,&movinglabel); // if (ii == 2 && jj==2) std::cout << "prob " << prob << " sigma " << sigma << " " << mag << " fl " << fixedlabel << " ml " << movinglabel << std::endl; if ( fixedlabel != movinglabel) prob=0; // || fixedlabel !=4) prob=0; mag=sqrt(mag); } EucDist(ii,jj)=prob; } if (min < 1.e5) this->m_LandmarkEnergy+=min; } MatrixType sinkhorn=EucDist; for (unsigned int iter=0; iter<1; iter++) { for (unsigned int jj=0; jjm_FixedPointSet->GetPoint(ii,&fixedpoint); else this->m_MovingPointSet->GetPoint(ii,&fixedpoint); if (whichdirection) this->m_FixedPointSet->GetPointData(ii,&fixedlabel); else this->m_MovingPointSet->GetPointData(ii,&fixedlabel); ImagePointType mpt; ImagePointType fpt; for (int j=0; jGetFixedImage()->TransformPhysicalPointToIndex(fpt,fixedindex); if (convok) { float mag=0.0; VectorType force; for (int j=0; j 50) { float tot=0; for (int k=0; k < sz2; k++) { tot+=sinkhorn(ii,k); } std::cout << "TOT " << tot << std::endl; force.Fill(0); mag=0; } */ if (mag > maxerr) maxerr=mag; energy+=mag; std::cout <<" ii " << ii << " force " << force << " mag " << mag << " mpt " << mpt << " fpt " << fixedpoint << " nrg " << energy /(float)ii << std::endl; lmField->SetPixel(fixedindex,force+lmField->GetPixel(fixedindex)); } // lmField->SetPixel(fixedindex,sforce); } // std::cout << " max " << maxerr << std::endl; this->m_LandmarkEnergy=energy/(float)sz1; this->m_Energy=this->m_LandmarkEnergy; } /* * Set the function state values before each iteration */ template void ExpectationBasedPointSetRegistrationFunction ::InitializeIteration() { // std::cout << " INIT ITER " << std::endl; if( !this->GetMovingImage() || !this->GetFixedImage() ) { itkExceptionMacro( << "MovingImage, FixedImage not set" ); } // cache fixed image information m_FixedImageSpacing = this->GetFixedImage()->GetSpacing(); m_FixedImageOrigin = this->GetFixedImage()->GetOrigin(); // compute the normalizer m_Normalizer = 0.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; } m_Normalizer /= static_cast( ImageDimension ); // setup gradient calculator m_FixedImageGradientCalculator->SetInputImage( this->GetFixedImage() ); m_MovingImageGradientCalculator->SetInputImage( this->GetMovingImage() ); // initialize metric computation variables m_SumOfSquaredDifference = 0.0; m_NumberOfPixelsProcessed = 0L; m_SumOfSquaredChange = 0.0; typename DeformationFieldType::PixelType zero; zero.Fill(0); this->m_DerivativeFixedField=DeformationFieldType::New(); this->m_DerivativeFixedField->SetSpacing( this->GetFixedImage()->GetSpacing() ); this->m_DerivativeFixedField->SetOrigin( this->GetFixedImage()->GetOrigin() ); this->m_DerivativeFixedField->SetLargestPossibleRegion(this->GetFixedImage()->GetLargestPossibleRegion() ); this->m_DerivativeFixedField->SetRequestedRegion(this->GetFixedImage()->GetLargestPossibleRegion() ); this->m_DerivativeFixedField->SetBufferedRegion( this->GetFixedImage()->GetLargestPossibleRegion() ); this->m_DerivativeFixedField->Allocate(); this->m_DerivativeMovingField=DeformationFieldType::New(); this->m_DerivativeMovingField->SetSpacing( this->GetMovingImage()->GetSpacing() ); this->m_DerivativeMovingField->SetOrigin( this->GetMovingImage()->GetOrigin() ); this->m_DerivativeMovingField->SetLargestPossibleRegion(this->GetMovingImage()->GetLargestPossibleRegion() ); this->m_DerivativeMovingField->SetRequestedRegion(this->GetMovingImage()->GetLargestPossibleRegion() ); this->m_DerivativeMovingField->SetBufferedRegion( this->GetMovingImage()->GetLargestPossibleRegion() ); this->m_DerivativeMovingField->Allocate(); this->m_DerivativeMovingField->FillBuffer(zero); this->m_DerivativeFixedField->FillBuffer(zero); //acquire labels if (this->m_LabelSet.size() < 1) { this->m_LabelSet.clear(); unsigned long sz1=this->m_FixedPointSet->GetNumberOfPoints(); std::cout << " NPTS " << sz1 << std::endl; for (unsigned long ii=0; iim_FixedPointSet->GetPoint(ii,&fixedpoint); this->m_FixedPointSet->GetPointData(ii,&label); if ( label > 0 ) { if ( find( this->m_LabelSet.begin(), this->m_LabelSet.end(), label ) == this->m_LabelSet.end() ) { this->m_LabelSet.push_back( label ); } } } } else { std::cout << " #of Label Values to match " << this->m_LabelSet.size() << std::endl; } this->m_bpoints = BSplinePointSetType::New(); this->m_bpoints->Initialize(); this->m_bweights = BSplineWeightsType::New(); this->m_bweights->Initialize(); this->m_bcount=0; unsigned int lct=0; typename LabelSetType::const_iterator it; for ( it = this->m_LabelSet.begin(); it != this->m_LabelSet.end(); ++it ) { lct++; PointDataType label=(PointDataType)*it; // std::cout << " doing label " << label << std::endl; this->SetUpKDTrees(label); bool dobsp=false; // if (lct == this->m_LabelSet.size() ) dobsp=true; this->FastExpectationLandmarkField(1.0,true,label,dobsp); this->FastExpectationLandmarkField(1.0,false,label,dobsp); } // follow up with BSpline if dospb is true . } /* * Compute update at a specify neighbourhood */ template typename ExpectationBasedPointSetRegistrationFunction ::PixelType ExpectationBasedPointSetRegistrationFunction ::ComputeUpdate(const NeighborhoodType &it, void * gd, const FloatOffsetType& itkNotUsed(offset)) { IndexType index = it.GetIndex(); PixelType update = this->m_DerivativeFixedField->GetPixel(index); if (this->m_Iterations > this->m_UseSymmetricMatching) update.Fill(0); return update; } /* * Compute update at a specify neighbourhood */ template typename ExpectationBasedPointSetRegistrationFunction ::PixelType ExpectationBasedPointSetRegistrationFunction ::ComputeUpdateInv(const NeighborhoodType &it, void * gd, const FloatOffsetType& itkNotUsed(offset)) { IndexType index = it.GetIndex(); return this->m_DerivativeMovingField->GetPixel(index); } /* * Update the metric and release the per-thread-global data. */ template void ExpectationBasedPointSetRegistrationFunction ::ReleaseGlobalDataPointer( void *gd ) const { GlobalDataStruct * globalData = (GlobalDataStruct *) gd; m_MetricCalculationLock.Lock(); m_SumOfSquaredDifference += globalData->m_SumOfSquaredDifference; m_NumberOfPixelsProcessed += globalData->m_NumberOfPixelsProcessed; m_SumOfSquaredChange += globalData->m_SumOfSquaredChange; if ( m_NumberOfPixelsProcessed ) { m_Metric = m_SumOfSquaredDifference / static_cast( m_NumberOfPixelsProcessed ); m_RMSChange = vcl_sqrt( m_SumOfSquaredChange / static_cast( m_NumberOfPixelsProcessed ) ); } m_MetricCalculationLock.Unlock(); delete globalData; } /* * Set the function state values before each iteration */ template void ExpectationBasedPointSetRegistrationFunction::SetUpKDTrees(long whichlabel) { // convert this->m_FixedPointSet to a sample type this->m_FixedSamplePoints = SampleType::New(); this->m_FixedSamplePoints->SetMeasurementVectorSize( MeasurementDimension ); MeasurementVectorType mv; unsigned int bucketsize=4; unsigned int npts= this->m_FixedPointSet->GetNumberOfPoints(); // std::cout << " NP MOV " << npts << std::endl; for ( unsigned int i = 0; i < npts; i++ ) { PointType fixedpoint; this->m_FixedPointSet->GetPoint(i,&fixedpoint); PointDataType fixedlabel=0; this->m_FixedPointSet->GetPointData(i,&fixedlabel); for ( unsigned int d = 0; d < ImageDimension; d++ ) { mv[d] = fixedpoint[d]; } //mv[ImageDimension]=(float) fixedlabel*1.e6; if (fixedlabel == whichlabel) this->m_FixedSamplePoints->PushBack( mv ); } this->m_FixedKdTreeGenerator = TreeGeneratorType::New(); this->m_FixedKdTreeGenerator->SetSample( this->m_FixedSamplePoints ); this->m_FixedKdTreeGenerator->SetBucketSize( bucketsize ); this->m_FixedKdTreeGenerator->Update(); this->m_MovingSamplePoints = SampleType::New(); this->m_MovingSamplePoints->SetMeasurementVectorSize( ImageDimension ); npts= this->m_MovingPointSet->GetNumberOfPoints(); // std::cout << " NP MOV " << npts << std::endl; for ( unsigned int i = 0; i < npts; i++ ) { PointType movingpoint; this->m_MovingPointSet->GetPoint(i,&movingpoint); PointDataType movinglabel=0; this->m_MovingPointSet->GetPointData(i,&movinglabel); for ( unsigned int d = 0; d < ImageDimension; d++ ) { mv[d] = movingpoint[d]; } //mv[ImageDimension]=(float) movinglabel*1.e6; if (movinglabel == whichlabel) this->m_MovingSamplePoints->PushBack( mv ); } this->m_MovingKdTreeGenerator = TreeGeneratorType::New(); this->m_MovingKdTreeGenerator->SetSample( this->m_MovingSamplePoints ); this->m_MovingKdTreeGenerator->SetBucketSize( bucketsize ); this->m_MovingKdTreeGenerator->Update(); } /* * Set the function state values before each iteration */ template void ExpectationBasedPointSetRegistrationFunction ::FastExpectationLandmarkField(float weight, bool whichdirection, long whichlabel, bool dobspline) { /** * BSpline typedefs */ /** Typedefs for B-spline filter */ unsigned int m_SplineOrder=3; unsigned int m_NumberOfBLevels=5; ArrayType m_MeshResolution; m_MeshResolution.Fill(1); unsigned int PointDimension=ImageDimension; typedef ImageRegionIteratorWithIndex Iterator; SpacingType spacing = this->GetFixedImage()->GetSpacing(); typename TreeGeneratorType::Pointer fkdtree; typename TreeGeneratorType::Pointer mkdtree; if (whichdirection) { mkdtree=this->m_MovingKdTreeGenerator; fkdtree=this->m_FixedKdTreeGenerator; }else{ fkdtree=this->m_MovingKdTreeGenerator; mkdtree=this->m_FixedKdTreeGenerator; } unsigned long sz1=fkdtree->GetOutput()->Size(); unsigned long sz2=mkdtree->GetOutput()->Size(); // std::cout << " s1 " << sz1 << " s2 " << sz2 << std::endl; if ( sz1 <= 0 || sz2 <= 0 ) { return; } DeformationFieldTypePointer lmField=this->m_DerivativeFixedField; if (!whichdirection) lmField=this->m_DerivativeMovingField; unsigned int KNeighbors=this->m_KNeighborhood; if (KNeighbors > sz2) KNeighbors=sz2; float inweight=weight; this->m_LandmarkEnergy=0.0; // float max=0; vnl_vector probabilities(KNeighbors); probabilities.fill(0); float energy=0,maxerr=0; for (unsigned long ii=0; iiGetOutput()->GetMeasurementVector(ii); ImagePointType mpt; mpt.Fill(0); ImagePointType fpt; fpt.Fill(0); for (int j=0; jGetFixedImage()->TransformPhysicalPointToIndex(fpt,fixedindex); // std::cout << " Orig " << this->GetFixedImage()->GetOrigin() << " ind " << fixedindex << " pt " << fpt << std::endl; if (convok) { float mag=0.0; VectorType force; force.Fill(0); typename TreeGeneratorType::KdTreeType::InstanceIdentifierVectorType neighbors; mkdtree->GetOutput()->Search( fixedpoint, static_cast( KNeighbors ), neighbors ); double probtotal=0.0; for (unsigned int dd=0; ddGetOutput()->GetMeasurementVector(wpt); float mag=0; for (unsigned int qq=0; qqm_FixedPointSetSigma; if (!whichdirection) sigma=this->m_MovingPointSetSigma; double prob=exp(-1.0*mag/sigma); probtotal+=prob; probabilities(dd)=prob; } if (probtotal > 0) for (unsigned int dd=0; ddGetOutput()->GetMeasurementVector(wpt); double pp=probabilities(dd)/probtotal; if (pp > 0)for (int j=0; j 1.e-3) std::cout << " prob " << pp << " mpt " << mpt << " dd " << dd <<" wpt " << wpt << " movinpoint " << movingpoint << " ptot " << probtotal << std::endl; } typename BSplinePointSetType::PointType bpoint; for (int j=0; jm_bpoints->SetPoint( this->m_bcount, bpoint ); this->m_bpoints->SetPointData( this->m_bcount, distance ); float bwt=1; this->m_bweights->InsertElement( this->m_bcount, static_cast( bwt ) ); this->m_bcount++; mag=sqrt(mag); if (mag > maxerr) maxerr=mag; energy+=mag; lmField->SetPixel(fixedindex,force+lmField->GetPixel(fixedindex)); } } // std::cout << " max " << maxerr << std::endl; this->m_LandmarkEnergy=energy/(float)sz1; this->m_Energy=this->m_LandmarkEnergy; if (dobspline) { /** * Calculate derivative field with respect to the moving points */ { //std::cout << " start bsp " << std::endl; typename BSplineFilterType::ArrayType nlevels; typename BSplineFilterType::ArrayType ncps; nlevels.Fill( m_NumberOfBLevels ); for( unsigned int d = 0; d < PointDimension; d++ ) { ncps[d] = m_MeshResolution[d] +m_SplineOrder; } typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetInput( this->m_bpoints ); bspliner->SetOrigin( this->GetMovingImage()->GetOrigin() ); bspliner->SetSpacing( this->GetMovingImage()->GetSpacing() ); bspliner->SetSize( this->GetMovingImage()->GetLargestPossibleRegion().GetSize() ); bspliner->SetNumberOfLevels( nlevels ); bspliner->SetSplineOrder( m_SplineOrder ); bspliner->SetNumberOfControlPoints( ncps ); bspliner->SetGenerateOutputImage( true ); bspliner->SetPointWeights( this->m_bweights ); bspliner->Update(); lmField = bspliner->GetOutput(); /** * Now calculate the distances after matching. ItM = this->m_MovingPointSet->GetPoints()->Begin(); ItMD = this->m_MovingPointSet->GetPointData()->Begin(); ItF = this->m_FixedPointSet->GetPoints()->Begin(); ItFD = this->m_FixedPointSet->GetPointData()->Begin(); typename BSplineWeightsType::ConstIterator ItW = weights->Begin(); while( ItM != this->m_MovingPointSet->GetPoints()->End() && ItF != this->m_FixedPointSet->GetPoints()->End() ) { typename BSplinePointSetType::PixelType vector; bspliner->EvaluateAtPoint( ItM.Value(), vector ); RealType distance = 0.0; for( unsigned int d = 0; d < PointDimension; d++ ) { distance += vnl_math_sqr( ItM.Value()[d] + vector[d] - ItF.Value()[d] ); } this->m_Energy += ItW.Value() * vcl_sqrt( distance ); ++ItF; ++ItFD; ++ItM; ++ItMD; ++ItW; } */ } } } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.h000066400000000000000000000207001147325206600322750ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkJensenHavrdaCharvatTsallisLabeledPointSetMetric_h #define _itkJensenHavrdaCharvatTsallisLabeledPointSetMetric_h #include "itkPointSetToPointSetMetric.h" #include "itkIdentityTransform.h" namespace itk { /** \class JensenHavrdaCharvatTsallisLabeledPointSetMetric * * * This class is templated over the fixed point-set type, moving * point-set type. * */ template class ITK_EXPORT JensenHavrdaCharvatTsallisLabeledPointSetMetric : public PointSetToPointSetMetric { public: /** Standard class typedefs. */ typedef JensenHavrdaCharvatTsallisLabeledPointSetMetric Self; typedef PointSetToPointSetMetric Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods) */ itkTypeMacro( JensenHavrdaCharvatTsallisLabeledPointSetMetric, PointSetToLabelPointSetMetric ); itkStaticConstMacro( PointDimension, unsigned int, TPointSet::PointDimension ); /** Types transferred from the base class */ typedef typename Superclass::TransformType TransformType; typedef typename Superclass::TransformPointer TransformPointer; typedef typename Superclass::TransformParametersType TransformParametersType; typedef typename Superclass::TransformJacobianType TransformJacobianType; typedef typename Superclass::MeasureType MeasureType; typedef typename Superclass::DerivativeType DerivativeType; typedef TPointSet PointSetType; typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PixelType; /** * Other typedefs */ typedef double RealType; typedef IdentityTransform DefaultTransformType; typedef std::vector LabelSetType; /** * Public function definitions */ itkSetConstObjectMacro( FixedPointSet, PointSetType ); itkGetConstObjectMacro( FixedPointSet, PointSetType ); itkSetConstObjectMacro( MovingPointSet, PointSetType ); itkGetConstObjectMacro( MovingPointSet, PointSetType ); itkSetObjectMacro( Transform, TransformType ); itkGetObjectMacro( Transform, TransformType ); /** * The only transform type used is Identity */ unsigned int GetNumberOfParameters( void ) const { return m_Transform->GetNumberOfParameters(); } /** Initialize the Metric by making sure that all the components * are present and plugged together correctly */ virtual void Initialize( void ) throw ( ExceptionObject ); /** Get the number of values */ unsigned int GetNumberOfValues() const; /** Get the derivatives of the match measure. */ void GetDerivative( const TransformParametersType & parameters, DerivativeType & Derivative ) const; /** Get the value for single valued optimizers. */ MeasureType GetValue( const TransformParametersType & parameters ) const; /** Get value and derivatives for multiple valued optimizers. */ void GetValueAndDerivative( const TransformParametersType & parameters, MeasureType& Value, DerivativeType& Derivative ) const; itkSetClampMacro( Alpha, RealType, 1.0, 2.0 ); itkGetConstMacro( Alpha, RealType ); itkSetMacro( UseRegularizationTerm, bool ); itkGetConstMacro( UseRegularizationTerm, bool ); itkBooleanMacro( UseRegularizationTerm ); itkSetMacro( UseWithRespectToTheMovingPointSet, bool ); itkGetConstMacro( UseWithRespectToTheMovingPointSet, bool ); itkBooleanMacro( UseWithRespectToTheMovingPointSet ); itkSetMacro( MovingPointSetSigma, RealType ); itkGetConstMacro( MovingPointSetSigma, RealType ); itkSetMacro( MovingEvaluationKNeighborhood, unsigned int ); itkGetConstMacro( MovingEvaluationKNeighborhood, unsigned int ); itkSetMacro( FixedPointSetSigma, RealType ); itkGetConstMacro( FixedPointSetSigma, RealType ); itkSetMacro( FixedEvaluationKNeighborhood, unsigned int ); itkGetConstMacro( FixedEvaluationKNeighborhood, unsigned int ); itkSetMacro( UseInputAsSamples, bool ); itkGetConstMacro( UseInputAsSamples, bool ); itkBooleanMacro( UseInputAsSamples ); /** * If this->m_UseInputAsSamples = true, the following * two variables are not used. */ itkSetMacro( NumberOfMovingSamples, unsigned long ); itkGetConstMacro( NumberOfMovingSamples, unsigned long ); itkSetMacro( NumberOfFixedSamples, unsigned long ); itkGetConstMacro( NumberOfFixedSamples, unsigned long ); itkSetMacro( UseAnisotropicCovariances, bool ); itkGetConstMacro( UseAnisotropicCovariances, bool ); itkBooleanMacro( UseAnisotropicCovariances ); /** * If this->m_UseAnisotropicCovariances = false, the * following four variables are not used. */ itkSetMacro( FixedCovarianceKNeighborhood, unsigned int ); itkGetConstMacro( FixedCovarianceKNeighborhood, unsigned int ); itkSetMacro( FixedKernelSigma, RealType ); itkGetConstMacro( FixedKernelSigma, RealType ); itkSetMacro( MovingCovarianceKNeighborhood, unsigned int ); itkGetConstMacro( MovingCovarianceKNeighborhood, unsigned int ); itkSetMacro( MovingKernelSigma, RealType ); itkGetConstMacro( MovingKernelSigma, RealType ); void SetFixedLabelSet( LabelSetType labels ) { typename LabelSetType::const_iterator iter; for ( iter = labels.begin(); iter != labels.end(); ++iter ) { this->m_FixedLabelSet.push_back( *iter ); } this->Modified(); } LabelSetType* GetFixedLabelSet() { return &this->m_FixedLabelSet; } void SetMovingLabelSet( LabelSetType labels ) { typename LabelSetType::const_iterator iter; for ( iter = labels.begin(); iter != labels.end(); ++iter ) { this->m_MovingLabelSet.push_back( *iter ); } this->Modified(); } LabelSetType* GetMovingLabelSet() { return &this->m_MovingLabelSet; } protected: JensenHavrdaCharvatTsallisLabeledPointSetMetric(); ~JensenHavrdaCharvatTsallisLabeledPointSetMetric() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: JensenHavrdaCharvatTsallisLabeledPointSetMetric(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented bool m_UseRegularizationTerm; bool m_UseInputAsSamples; bool m_UseAnisotropicCovariances; bool m_UseWithRespectToTheMovingPointSet; RealType m_MovingPointSetSigma; RealType m_MovingKernelSigma; unsigned int m_MovingCovarianceKNeighborhood; unsigned int m_MovingEvaluationKNeighborhood; unsigned long m_NumberOfMovingSamples; RealType m_FixedPointSetSigma; RealType m_FixedKernelSigma; unsigned int m_FixedCovarianceKNeighborhood; unsigned int m_FixedEvaluationKNeighborhood; unsigned long m_NumberOfFixedSamples; RealType m_Alpha; TransformPointer m_Transform; LabelSetType m_FixedLabelSet; LabelSetType m_MovingLabelSet; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.txx000066400000000000000000000451531147325206600327020ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkJensenHavrdaCharvatTsallisLabeledPointSetMetric_txx #define _itkJensenHavrdaCharvatTsallisLabeledPointSetMetric_txx #include "itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.h" #include "itkJensenHavrdaCharvatTsallisPointSetMetric.h" namespace itk { template JensenHavrdaCharvatTsallisLabeledPointSetMetric ::JensenHavrdaCharvatTsallisLabeledPointSetMetric() { this->m_UseRegularizationTerm = false; this->m_UseInputAsSamples = true; this->m_UseAnisotropicCovariances = false; this->m_NumberOfFixedSamples = 100; this->m_FixedPointSetSigma = 1.0; this->m_FixedKernelSigma = 10.0; this->m_FixedCovarianceKNeighborhood = 5; this->m_FixedEvaluationKNeighborhood = 50; this->m_NumberOfMovingSamples = 100; this->m_MovingPointSetSigma = 1.0; this->m_MovingKernelSigma = 10.0; this->m_MovingCovarianceKNeighborhood = 5; this->m_MovingEvaluationKNeighborhood = 50; this->m_Alpha = 2.0; this->m_UseWithRespectToTheMovingPointSet = true; typename DefaultTransformType::Pointer transform = DefaultTransformType::New(); transform->SetIdentity(); Superclass::SetTransform( transform ); } /** Initialize the metric */ template void JensenHavrdaCharvatTsallisLabeledPointSetMetric ::Initialize( void ) throw ( ExceptionObject ) { Superclass::Initialize(); if ( this->m_FixedLabelSet.size() <= 0 && this->m_FixedPointSet->GetNumberOfPoints() > 0 ) { typename PointSetType::PointDataContainerIterator It = this->m_FixedPointSet->GetPointData()->Begin(); while ( It != this->m_FixedPointSet->GetPointData()->End() ) { if ( find( this->m_FixedLabelSet.begin(), this->m_FixedLabelSet.end(), It.Value() ) == this->m_FixedLabelSet.end() ) { this->m_FixedLabelSet.push_back( It.Value() ); } ++It; } } if ( this->m_MovingLabelSet.size() <= 0 && this->m_MovingPointSet->GetNumberOfPoints() > 0 ) { typename PointSetType::PointDataContainerIterator It = this->m_MovingPointSet->GetPointData()->Begin(); while ( It != this->m_MovingPointSet->GetPointData()->End() ) { if ( find( this->m_MovingLabelSet.begin(), this->m_MovingLabelSet.end(), It.Value() ) == this->m_MovingLabelSet.end() ) { this->m_MovingLabelSet.push_back( It.Value() ); } ++It; } } } /** Return the number of values, i.e the number of points in the moving set */ template unsigned int JensenHavrdaCharvatTsallisLabeledPointSetMetric ::GetNumberOfValues() const { if ( this->m_UseWithRespectToTheMovingPointSet ) { if ( this->m_MovingPointSet ) { return this->m_MovingPointSet->GetPoints()->Size(); } } else { if ( this->m_FixedPointSet ) { return this->m_FixedPointSet->GetPoints()->Size(); } } return 0; } /** Get the match Measure */ template typename JensenHavrdaCharvatTsallisLabeledPointSetMetric::MeasureType JensenHavrdaCharvatTsallisLabeledPointSetMetric ::GetValue( const TransformParametersType & parameters ) const { MeasureType measure; measure.SetSize( 1 ); measure.Fill( 0 ); typename LabelSetType::const_iterator iter; for ( iter = this->m_FixedLabelSet.begin(); iter != this->m_FixedLabelSet.end(); ++iter ) { PixelType currentLabel = *iter; /** * check to see if the moving label set contains the same label */ if ( find( this->m_MovingLabelSet.begin(), this->m_MovingLabelSet.end(), currentLabel ) == this->m_MovingLabelSet.end() ) { continue; } /** * Collect all the fixed and moving points with the currentLabel */ typename PointSetType::Pointer fixedLabelPoints = PointSetType::New(); fixedLabelPoints->Initialize(); unsigned long fixedCount = 0; typename PointSetType::PointsContainerConstIterator ItF = this->m_FixedPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItFD = this->m_FixedPointSet->GetPointData()->Begin(); while ( ItF != this->m_FixedPointSet->GetPoints()->End() ) { if ( ItFD.Value() == currentLabel ) { fixedLabelPoints->SetPoint( fixedCount++, ItF.Value() ); } ++ItF; ++ItFD; } typename PointSetType::Pointer movingLabelPoints = PointSetType::New(); movingLabelPoints->Initialize(); unsigned long movingCount = 0; typename PointSetType::PointsContainerConstIterator ItM = this->m_MovingPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItMD = this->m_MovingPointSet->GetPointData()->Begin(); while ( ItM != this->m_MovingPointSet->GetPoints()->End() ) { if ( ItMD.Value() == currentLabel ) { movingLabelPoints->SetPoint( movingCount++, ItM.Value() ); } ++ItM; ++ItMD; } /** * Invoke the single label JensenTsallis measure */ typedef JensenHavrdaCharvatTsallisPointSetMetric MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetFixedPointSet( fixedLabelPoints ); metric->SetNumberOfFixedSamples( this->m_NumberOfFixedSamples ); metric->SetFixedPointSetSigma( this->m_FixedPointSetSigma ); metric->SetFixedKernelSigma( this->m_FixedKernelSigma ); metric->SetFixedCovarianceKNeighborhood( this->m_FixedCovarianceKNeighborhood ); metric->SetFixedEvaluationKNeighborhood( this->m_FixedEvaluationKNeighborhood ); metric->SetMovingPointSet( movingLabelPoints ); metric->SetNumberOfMovingSamples( this->m_NumberOfMovingSamples ); metric->SetMovingPointSetSigma( this->m_MovingPointSetSigma ); metric->SetMovingKernelSigma( this->m_MovingKernelSigma ); metric->SetMovingCovarianceKNeighborhood( this->m_MovingCovarianceKNeighborhood ); metric->SetMovingEvaluationKNeighborhood( this->m_MovingEvaluationKNeighborhood ); metric->SetUseRegularizationTerm( this->m_UseRegularizationTerm ); metric->SetUseInputAsSamples( this->m_UseInputAsSamples ); metric->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); metric->SetUseWithRespectToTheMovingPointSet( this->m_UseWithRespectToTheMovingPointSet ); metric->SetAlpha( this->m_Alpha ); metric->Initialize(); MeasureType value = metric->GetValue( parameters ); measure[0] += value[0]; } return measure; } /** Get the Derivative Measure */ template void JensenHavrdaCharvatTsallisLabeledPointSetMetric ::GetDerivative( const TransformParametersType & parameters, DerivativeType & derivative ) const { unsigned long numberOfDerivatives = this->m_FixedPointSet->GetNumberOfPoints(); if ( this->m_UseWithRespectToTheMovingPointSet ) { numberOfDerivatives = this->m_MovingPointSet->GetNumberOfPoints(); } derivative.SetSize( numberOfDerivatives, PointDimension ); derivative.Fill( 0 ); typename LabelSetType::const_iterator iter; for ( iter = this->m_FixedLabelSet.begin(); iter != this->m_FixedLabelSet.end(); ++iter ) { PixelType currentLabel = *iter; /** * check to see if the moving label set contains the same label */ if ( find( this->m_MovingLabelSet.begin(), this->m_MovingLabelSet.end(), currentLabel ) == this->m_MovingLabelSet.end() ) { continue; } /** * Collect all the fixed and moving points with the currentLabel */ typename PointSetType::Pointer fixedLabelPoints = PointSetType::New(); fixedLabelPoints->Initialize(); unsigned long fixedCount = 0; std::vector fixedIndices; fixedIndices.clear(); typename PointSetType::PointsContainerConstIterator ItF = this->m_FixedPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItFD = this->m_FixedPointSet->GetPointData()->Begin(); while ( ItF != this->m_FixedPointSet->GetPoints()->End() ) { if ( ItFD.Value() == currentLabel ) { fixedLabelPoints->SetPoint( fixedCount++, ItF.Value() ); fixedIndices.push_back( ItF.Index() ); } ++ItF; ++ItFD; } typename PointSetType::Pointer movingLabelPoints = PointSetType::New(); movingLabelPoints->Initialize(); unsigned long movingCount = 0; std::vector movingIndices; movingIndices.clear(); typename PointSetType::PointsContainerConstIterator ItM = this->m_MovingPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItMD = this->m_MovingPointSet->GetPointData()->Begin(); while ( ItM != this->m_MovingPointSet->GetPoints()->End() ) { if ( ItMD.Value() == currentLabel ) { movingLabelPoints->SetPoint( movingCount++, ItM.Value() ); movingIndices.push_back( ItM.Index() ); } ++ItM; ++ItMD; } /** * Invoke the single label JensenTsallis measure */ typedef JensenHavrdaCharvatTsallisPointSetMetric MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetFixedPointSet( fixedLabelPoints ); metric->SetNumberOfFixedSamples( this->m_NumberOfFixedSamples ); metric->SetFixedPointSetSigma( this->m_FixedPointSetSigma ); metric->SetFixedKernelSigma( this->m_FixedKernelSigma ); metric->SetFixedCovarianceKNeighborhood( this->m_FixedCovarianceKNeighborhood ); metric->SetFixedEvaluationKNeighborhood( this->m_FixedEvaluationKNeighborhood ); metric->SetMovingPointSet( movingLabelPoints ); metric->SetNumberOfMovingSamples( this->m_NumberOfMovingSamples ); metric->SetMovingPointSetSigma( this->m_MovingPointSetSigma ); metric->SetMovingKernelSigma( this->m_MovingKernelSigma ); metric->SetMovingCovarianceKNeighborhood( this->m_MovingCovarianceKNeighborhood ); metric->SetMovingEvaluationKNeighborhood( this->m_MovingEvaluationKNeighborhood ); metric->SetUseRegularizationTerm( this->m_UseRegularizationTerm ); metric->SetUseInputAsSamples( this->m_UseInputAsSamples ); metric->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); metric->SetUseWithRespectToTheMovingPointSet( this->m_UseWithRespectToTheMovingPointSet ); metric->SetAlpha( this->m_Alpha ); metric->Initialize(); DerivativeType labelDerivative; metric->GetDerivative( parameters, labelDerivative ); RealType avgNorm = 0.0; for ( unsigned int i = 0; i < metric->GetNumberOfValues(); i++ ) { RealType norm = 0.0; for ( unsigned int j = 0; j < PointDimension; j++ ) { norm += ( labelDerivative(i, j) * labelDerivative(i, j) ); } avgNorm += vcl_sqrt( norm ); } avgNorm /= static_cast( metric->GetNumberOfValues() ); labelDerivative /= avgNorm; if ( this->m_UseWithRespectToTheMovingPointSet ) { std::vector::const_iterator it; unsigned long index = 0; for ( it = movingIndices.begin(); it != movingIndices.end(); ++it ) { for ( unsigned int d = 0; d < PointDimension; d++ ) { derivative( *it, d ) = labelDerivative( index, d ); } index++; } } else { std::vector::const_iterator it; unsigned long index = 0; for ( it = fixedIndices.begin(); it != fixedIndices.end(); ++it ) { for ( unsigned int d = 0; d < PointDimension; d++ ) { derivative( *it, d ) = labelDerivative( index, d ); } index++; } } } } /** Get both the match Measure and theDerivative Measure */ template void JensenHavrdaCharvatTsallisLabeledPointSetMetric ::GetValueAndDerivative( const TransformParametersType & parameters, MeasureType & value, DerivativeType & derivative ) const { unsigned long numberOfDerivatives = this->m_FixedPointSet->GetNumberOfPoints(); if ( this->m_UseWithRespectToTheMovingPointSet ) { numberOfDerivatives = this->m_MovingPointSet->GetNumberOfPoints(); } derivative.SetSize( numberOfDerivatives, PointDimension ); derivative.Fill( 0 ); value.SetSize( 1 ); value.Fill( 0 ); typename LabelSetType::const_iterator iter; for ( iter = this->m_FixedLabelSet.begin(); iter != this->m_FixedLabelSet.end(); ++iter ) { PixelType currentLabel = *iter; /** * check to see if the moving label set contains the same label */ if ( find( this->m_MovingLabelSet.begin(), this->m_MovingLabelSet.end(), currentLabel ) == this->m_MovingLabelSet.end() ) { continue; } /** * Collect all the fixed and moving points with the currentLabel */ typename PointSetType::Pointer fixedLabelPoints = PointSetType::New(); fixedLabelPoints->Initialize(); unsigned long fixedCount = 0; std::vector fixedIndices; fixedIndices.clear(); typename PointSetType::PointsContainerConstIterator ItF = this->m_FixedPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItFD = this->m_FixedPointSet->GetPointData()->Begin(); while ( ItF != this->m_FixedPointSet->GetPoints()->End() ) { if ( ItFD.Value() == currentLabel ) { fixedLabelPoints->SetPoint( fixedCount++, ItF.Value() ); fixedIndices.push_back( ItF.Index() ); } ++ItF; ++ItFD; } typename PointSetType::Pointer movingLabelPoints = PointSetType::New(); movingLabelPoints->Initialize(); unsigned long movingCount = 0; std::vector movingIndices; movingIndices.clear(); typename PointSetType::PointsContainerConstIterator ItM = this->m_MovingPointSet->GetPoints()->Begin(); typename PointSetType::PointDataContainerIterator ItMD = this->m_MovingPointSet->GetPointData()->Begin(); while ( ItM != this->m_MovingPointSet->GetPoints()->End() ) { if ( ItMD.Value() == currentLabel ) { movingLabelPoints->SetPoint( movingCount++, ItM.Value() ); movingIndices.push_back( ItM.Index() ); } ++ItM; ++ItMD; } /** * Invoke the single label JensenTsallis measure */ typedef JensenHavrdaCharvatTsallisPointSetMetric MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetFixedPointSet( fixedLabelPoints ); metric->SetNumberOfFixedSamples( this->m_NumberOfFixedSamples ); metric->SetFixedPointSetSigma( this->m_FixedPointSetSigma ); metric->SetFixedKernelSigma( this->m_FixedKernelSigma ); metric->SetFixedCovarianceKNeighborhood( this->m_FixedCovarianceKNeighborhood ); metric->SetFixedEvaluationKNeighborhood( this->m_FixedEvaluationKNeighborhood ); metric->SetMovingPointSet( movingLabelPoints ); metric->SetNumberOfMovingSamples( this->m_NumberOfMovingSamples ); metric->SetMovingPointSetSigma( this->m_MovingPointSetSigma ); metric->SetMovingKernelSigma( this->m_MovingKernelSigma ); metric->SetMovingCovarianceKNeighborhood( this->m_MovingCovarianceKNeighborhood ); metric->SetMovingEvaluationKNeighborhood( this->m_MovingEvaluationKNeighborhood ); metric->SetUseRegularizationTerm( this->m_UseRegularizationTerm ); metric->SetUseInputAsSamples( this->m_UseInputAsSamples ); metric->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); metric->SetUseWithRespectToTheMovingPointSet( this->m_UseWithRespectToTheMovingPointSet ); metric->SetAlpha( this->m_Alpha ); metric->Initialize(); DerivativeType labelDerivative; MeasureType labelValue; metric->GetValueAndDerivative( parameters, labelValue, labelDerivative ); value[0] += labelValue[0]; RealType avgNorm = 0.0; for ( unsigned int i = 0; i < metric->GetNumberOfValues(); i++ ) { RealType norm = 0.0; for ( unsigned int j = 0; j < PointDimension; j++ ) { norm += ( labelDerivative(i, j) * labelDerivative(i, j) ); } avgNorm += vcl_sqrt( norm ); } avgNorm /= static_cast( metric->GetNumberOfValues() ); labelDerivative /= avgNorm; if ( this->m_UseWithRespectToTheMovingPointSet ) { std::vector::const_iterator it; unsigned long index = 0; for ( it = movingIndices.begin(); it != movingIndices.end(); ++it ) { for ( unsigned int d = 0; d < PointDimension; d++ ) { derivative( *it, d ) = labelDerivative( index, d ); } index++; } } else { std::vector::const_iterator it; unsigned long index = 0; for ( it = fixedIndices.begin(); it != fixedIndices.end(); ++it ) { for ( unsigned int d = 0; d < PointDimension; d++ ) { derivative( *it, d ) = labelDerivative( index, d ); } index++; } } } } template void JensenHavrdaCharvatTsallisLabeledPointSetMetric ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Use with respect to the moving point set: " << this->m_UseWithRespectToTheMovingPointSet << std::endl; os << indent << "Use regularization term: " << this->m_UseRegularizationTerm << std::endl; if ( !this->m_UseInputAsSamples ) { os << indent << "Number of fixed samples: " << this->m_NumberOfFixedSamples << std::endl; os << indent << "Number of moving samples: " << this->m_NumberOfMovingSamples << std::endl; } os << indent << "Alpha: " << this->m_Alpha << std::endl; os << indent << "Fixed sigma: " << this->m_FixedPointSetSigma << std::endl; os << indent << "Moving sigma: " << this->m_MovingPointSetSigma << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenHavrdaCharvatTsallisPointSetMetric.h000066400000000000000000000176601147325206600310370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenHavrdaCharvatTsallisPointSetMetric.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkJensenHavrdaCharvatTsallisPointSetMetric_h #define __itkJensenHavrdaCharvatTsallisPointSetMetric_h #include "itkPointSetToPointSetMetric.h" #include "itkIdentityTransform.h" #include "itkManifoldParzenWindowsPointSetFunction.h" namespace itk { /** \class JensenHavrdaCharvatTsallisPointSetMetric * * * * */ template class ITK_EXPORT JensenHavrdaCharvatTsallisPointSetMetric : public PointSetToPointSetMetric { public: /** Standard class typedefs. */ typedef JensenHavrdaCharvatTsallisPointSetMetric Self; typedef PointSetToPointSetMetric Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods) */ itkTypeMacro( JensenHavrdaCharvatTsallisPointSetMetric, PointSetToPointSetMetric ); itkStaticConstMacro( PointDimension, unsigned int, TPointSet::PointDimension ); /** Types transferred from the base class */ typedef typename Superclass::TransformType TransformType; typedef typename Superclass::TransformPointer TransformPointer; typedef typename Superclass::TransformParametersType TransformParametersType; typedef typename Superclass::TransformJacobianType TransformJacobianType; typedef typename Superclass::MeasureType MeasureType; typedef typename Superclass::DerivativeType DerivativeType; typedef TPointSet PointSetType; typedef typename PointSetType::Pointer PointSetPointer; typedef typename PointSetType::PointType PointType; /** * Other typedefs */ typedef double RealType; typedef ManifoldParzenWindowsPointSetFunction DensityFunctionType; typedef typename DensityFunctionType::GaussianType GaussianType; typedef IdentityTransform DefaultTransformType; /** * Public function definitions */ itkSetConstObjectMacro( FixedPointSet, PointSetType ); itkGetConstObjectMacro( FixedPointSet, PointSetType ); itkSetConstObjectMacro( MovingPointSet, PointSetType ); itkGetConstObjectMacro( MovingPointSet, PointSetType ); itkSetObjectMacro( Transform, TransformType ); itkGetObjectMacro( Transform, TransformType ); /** * The only transform type used is Identity */ unsigned int GetNumberOfParameters( void ) const { return m_Transform->GetNumberOfParameters(); } /** Initialize the Metric by making sure that all the components * are present and plugged together correctly */ virtual void Initialize( void ) throw ( ExceptionObject ); /** Get the number of values */ unsigned int GetNumberOfValues() const; /** Get the derivatives of the match measure. */ void GetDerivative( const TransformParametersType & parameters, DerivativeType & Derivative ) const; /** Get the value for single valued optimizers. */ MeasureType GetValue( const TransformParametersType & parameters ) const; /** Get value and derivatives for multiple valued optimizers. */ void GetValueAndDerivative( const TransformParametersType & parameters, MeasureType& Value, DerivativeType& Derivative ) const; itkSetClampMacro( Alpha, RealType, 1.0, 2.0 ); itkGetConstMacro( Alpha, RealType ); itkSetMacro( UseRegularizationTerm, bool ); itkGetConstMacro( UseRegularizationTerm, bool ); itkBooleanMacro( UseRegularizationTerm ); itkSetMacro( UseWithRespectToTheMovingPointSet, bool ); itkGetConstMacro( UseWithRespectToTheMovingPointSet, bool ); itkBooleanMacro( UseWithRespectToTheMovingPointSet ); itkSetMacro( MovingPointSetSigma, RealType ); itkGetConstMacro( MovingPointSetSigma, RealType ); itkSetMacro( MovingEvaluationKNeighborhood, unsigned int ); itkGetConstMacro( MovingEvaluationKNeighborhood, unsigned int ); itkSetMacro( FixedPointSetSigma, RealType ); itkGetConstMacro( FixedPointSetSigma, RealType ); itkSetMacro( FixedEvaluationKNeighborhood, unsigned int ); itkGetConstMacro( FixedEvaluationKNeighborhood, unsigned int ); itkSetMacro( UseInputAsSamples, bool ); itkGetConstMacro( UseInputAsSamples, bool ); itkBooleanMacro( UseInputAsSamples ); /** * If this->m_UseInputAsSamples = true, the following * two variables are not used. */ itkSetMacro( NumberOfMovingSamples, unsigned long ); itkGetConstMacro( NumberOfMovingSamples, unsigned long ); itkSetMacro( NumberOfFixedSamples, unsigned long ); itkGetConstMacro( NumberOfFixedSamples, unsigned long ); itkSetMacro( UseAnisotropicCovariances, bool ); itkGetConstMacro( UseAnisotropicCovariances, bool ); itkBooleanMacro( UseAnisotropicCovariances ); /** * If this->m_UseAnisotropicCovariances = false, the * following four variables are not used. */ itkSetMacro( FixedCovarianceKNeighborhood, unsigned int ); itkGetConstMacro( FixedCovarianceKNeighborhood, unsigned int ); itkSetMacro( FixedKernelSigma, RealType ); itkGetConstMacro( FixedKernelSigma, RealType ); itkSetMacro( MovingCovarianceKNeighborhood, unsigned int ); itkGetConstMacro( MovingCovarianceKNeighborhood, unsigned int ); itkSetMacro( MovingKernelSigma, RealType ); itkGetConstMacro( MovingKernelSigma, RealType ); protected: JensenHavrdaCharvatTsallisPointSetMetric(); ~JensenHavrdaCharvatTsallisPointSetMetric() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: //purposely not implemented JensenHavrdaCharvatTsallisPointSetMetric(const Self&); void operator=(const Self&); bool m_UseRegularizationTerm; bool m_UseInputAsSamples; bool m_UseAnisotropicCovariances; bool m_UseWithRespectToTheMovingPointSet; typename DensityFunctionType::Pointer m_MovingDensityFunction; PointSetPointer m_MovingSamplePoints; RealType m_MovingPointSetSigma; RealType m_MovingKernelSigma; unsigned int m_MovingCovarianceKNeighborhood; unsigned int m_MovingEvaluationKNeighborhood; unsigned long m_NumberOfMovingSamples; typename DensityFunctionType::Pointer m_FixedDensityFunction; PointSetPointer m_FixedSamplePoints; RealType m_FixedPointSetSigma; RealType m_FixedKernelSigma; unsigned int m_FixedCovarianceKNeighborhood; unsigned int m_FixedEvaluationKNeighborhood; unsigned long m_NumberOfFixedSamples; RealType m_Alpha; TransformPointer m_Transform; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkJensenHavrdaCharvatTsallisPointSetMetric.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenHavrdaCharvatTsallisPointSetMetric.txx000066400000000000000000000616121147325206600314270ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenHavrdaCharvatTsallisPointSetMetric.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkJensenHavrdaCharvatTsallisPointSetMetric_txx #define __itkJensenHavrdaCharvatTsallisPointSetMetric_txx #include "itkJensenHavrdaCharvatTsallisPointSetMetric.h" namespace itk { template JensenHavrdaCharvatTsallisPointSetMetric ::JensenHavrdaCharvatTsallisPointSetMetric() { this->m_UseRegularizationTerm = false; this->m_UseInputAsSamples = true; this->m_UseAnisotropicCovariances = false; this->m_NumberOfFixedSamples = 100; this->m_FixedPointSetSigma = 1.0; this->m_FixedKernelSigma = 10.0; this->m_FixedCovarianceKNeighborhood = 5; this->m_FixedEvaluationKNeighborhood = 50; this->m_NumberOfMovingSamples = 100; this->m_MovingPointSetSigma = 1.0; this->m_MovingKernelSigma = 10.0; this->m_MovingCovarianceKNeighborhood = 5; this->m_MovingEvaluationKNeighborhood = 50; this->m_Alpha = 2.0; this->m_UseWithRespectToTheMovingPointSet = true; typename DefaultTransformType::Pointer transform = DefaultTransformType::New(); transform->SetIdentity(); Superclass::SetTransform( transform ); } /** Initialize the metric */ template void JensenHavrdaCharvatTsallisPointSetMetric ::Initialize( void ) throw ( ExceptionObject ) { Superclass::Initialize(); /** * Initialize the fixed points */ this->m_FixedDensityFunction = DensityFunctionType::New(); this->m_FixedDensityFunction->SetBucketSize( 4 ); this->m_FixedDensityFunction->SetKernelSigma( this->m_FixedKernelSigma ); this->m_FixedDensityFunction->SetRegularizationSigma( this->m_FixedPointSetSigma ); this->m_FixedDensityFunction->SetNormalize( true ); this->m_FixedDensityFunction->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); this->m_FixedDensityFunction->SetCovarianceKNeighborhood( this->m_FixedCovarianceKNeighborhood ); this->m_FixedDensityFunction->SetEvaluationKNeighborhood( this->m_FixedEvaluationKNeighborhood ); this->m_FixedDensityFunction->SetInputPointSet( this->m_FixedPointSet ); if( !this->m_UseInputAsSamples ) { this->m_FixedSamplePoints = PointSetType::New(); this->m_FixedSamplePoints->Initialize(); for( unsigned long i = 0; i < this->m_NumberOfFixedSamples; i++ ) { this->m_FixedSamplePoints->SetPoint( i, this->m_FixedDensityFunction->GenerateRandomSample() ); } } /** * Initialize the moving points */ this->m_MovingDensityFunction = DensityFunctionType::New(); this->m_MovingDensityFunction->SetBucketSize( 4 ); this->m_MovingDensityFunction->SetKernelSigma( this->m_MovingKernelSigma ); this->m_MovingDensityFunction->SetRegularizationSigma( this->m_MovingPointSetSigma ); this->m_MovingDensityFunction->SetNormalize( true ); this->m_MovingDensityFunction->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); this->m_MovingDensityFunction->SetCovarianceKNeighborhood( this->m_MovingCovarianceKNeighborhood ); this->m_MovingDensityFunction->SetEvaluationKNeighborhood( this->m_MovingEvaluationKNeighborhood ); this->m_MovingDensityFunction->SetInputPointSet( this->m_MovingPointSet ); if( !this->m_UseInputAsSamples ) { this->m_MovingSamplePoints = PointSetType::New(); this->m_MovingSamplePoints->Initialize(); for( unsigned long i = 0; i < this->m_NumberOfMovingSamples; i++ ) { this->m_MovingSamplePoints->SetPoint( i, this->m_MovingDensityFunction->GenerateRandomSample() ); } } } /** Return the number of values, i.e the number of points in the moving set */ template unsigned int JensenHavrdaCharvatTsallisPointSetMetric ::GetNumberOfValues() const { if( this->m_UseWithRespectToTheMovingPointSet ) { if( this->m_MovingPointSet ) { return this->m_MovingPointSet->GetPoints()->Size(); } } else { if( this->m_FixedPointSet ) { return this->m_FixedPointSet->GetPoints()->Size(); } } return 0; } /** Get the match Measure */ template typename JensenHavrdaCharvatTsallisPointSetMetric ::MeasureType JensenHavrdaCharvatTsallisPointSetMetric ::GetValue( const TransformParametersType & parameters ) const { /** * Only identity transform is valid */ // this->SetTransformParameters( parameters ); PointSetPointer points[2]; PointSetPointer samples[2]; typename DensityFunctionType::Pointer densityFunctions[2]; if( this->m_UseWithRespectToTheMovingPointSet ) { points[0] = const_cast( static_cast( this->m_FixedPointSet ) ); points[1] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[0] = points[0]; samples[1] = points[1]; } else { samples[0] = this->m_FixedSamplePoints; samples[1] = this->m_MovingSamplePoints; } densityFunctions[0] = this->m_FixedDensityFunction; densityFunctions[1] = this->m_MovingDensityFunction; } else { points[1] = const_cast( static_cast( this->m_FixedPointSet ) ); points[0] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[1] = points[1]; samples[0] = points[0]; } else { samples[1] = this->m_FixedSamplePoints; samples[0] = this->m_MovingSamplePoints; } densityFunctions[1] = this->m_FixedDensityFunction; densityFunctions[0] = this->m_MovingDensityFunction; } RealType totalNumberOfPoints = static_cast( points[0]->GetNumberOfPoints() ) + static_cast( points[1]->GetNumberOfPoints() ); RealType totalNumberOfSamples = static_cast( samples[0]->GetNumberOfPoints() ) + static_cast( samples[1]->GetNumberOfPoints() ); MeasureType measure; measure.SetSize( 1 ); measure.Fill( 0 ); RealType energyTerm1 = 0.0; RealType energyTerm2 = 0.0; /** * first term */ RealType prefactor = -1.0 / totalNumberOfSamples; if( this->m_Alpha != 1.0 ) { prefactor /= ( this->m_Alpha - 1.0 ); } typename PointSetType::PointsContainerConstIterator It = samples[0]->GetPoints()->Begin(); while( It != samples[0]->GetPoints()->End() ) { PointType samplePoint = It.Value(); RealType probabilityStar = densityFunctions[0]->Evaluate( samplePoint ) * static_cast( points[0]->GetNumberOfPoints() ) + densityFunctions[1]->Evaluate( samplePoint ) * static_cast( points[1]->GetNumberOfPoints() ); probabilityStar /= totalNumberOfPoints; if( probabilityStar == 0 ) { ++It; continue; } if( this->m_Alpha == 1.0 ) { energyTerm1 += ( prefactor * vcl_log( probabilityStar ) / vnl_math::ln2 ); } else { energyTerm1 += ( prefactor * vcl_pow( probabilityStar, static_cast( this->m_Alpha - 1.0 ) ) ); } ++It; } /** * second term, i.e. regularization term */ if( this->m_UseRegularizationTerm ) { RealType prefactor2 = -static_cast( points[1]->GetNumberOfPoints() ) / ( totalNumberOfPoints * static_cast( samples[1]->GetNumberOfPoints() ) ); if( this->m_Alpha != 1.0 ) { prefactor2 /= ( this->m_Alpha - 1.0 ); } typename PointSetType::PointsContainerConstIterator It = samples[1]->GetPoints()->Begin(); while( It != samples[1]->GetPoints()->End() ) { PointType samplePoint = It.Value(); RealType probability = densityFunctions[1]->Evaluate( samplePoint ); if( probability == 0 ) { ++It; continue; } if( this->m_Alpha == 1.0 ) { energyTerm2 += ( prefactor2 * vcl_log( probability ) / vnl_math::ln2 ); } else { energyTerm2 += ( prefactor2 * vcl_pow( probability, static_cast( this->m_Alpha - 1.0 ) ) ); } ++It; } } measure[0] = energyTerm1 - energyTerm2; return measure; } /** Get the Derivative Measure */ template void JensenHavrdaCharvatTsallisPointSetMetric ::GetDerivative( const TransformParametersType & parameters, DerivativeType & derivative ) const { /** * Only identity transform is valid */ // this->SetTransformParameters( parameters ); PointSetPointer points[2]; PointSetPointer samples[2]; typename DensityFunctionType::Pointer densityFunctions[2]; unsigned int kNeighborhood; if( this->m_UseWithRespectToTheMovingPointSet ) { points[0] = const_cast( static_cast( this->m_FixedPointSet ) ); points[1] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[0] = points[0]; samples[1] = points[1]; } else { samples[0] = this->m_FixedSamplePoints; samples[1] = this->m_MovingSamplePoints; } densityFunctions[0] = this->m_FixedDensityFunction; densityFunctions[1] = this->m_MovingDensityFunction; kNeighborhood = this->m_MovingEvaluationKNeighborhood; } else { points[1] = const_cast( static_cast( this->m_FixedPointSet ) ); points[0] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[1] = points[1]; samples[0] = points[0]; } else { samples[1] = this->m_FixedSamplePoints; samples[0] = this->m_MovingSamplePoints; } densityFunctions[1] = this->m_FixedDensityFunction; densityFunctions[0] = this->m_MovingDensityFunction; kNeighborhood = this->m_FixedEvaluationKNeighborhood; } RealType totalNumberOfPoints = static_cast( points[0]->GetNumberOfPoints() ) + static_cast( points[1]->GetNumberOfPoints() ); RealType totalNumberOfSamples = static_cast( samples[0]->GetNumberOfPoints() ) + static_cast( samples[1]->GetNumberOfPoints() ); derivative.SetSize( points[1]->GetPoints()->Size(), PointDimension ); derivative.Fill( 0 ); /** * first term */ RealType prefactor = 1.0 / ( totalNumberOfSamples * totalNumberOfPoints ); typename PointSetType::PointsContainerConstIterator It = samples[0]->GetPoints()->Begin(); while( It != samples[0]->GetPoints()->End() ) { PointType fixedSamplePoint = It.Value(); RealType probabilityStar = densityFunctions[0]->Evaluate( fixedSamplePoint ) * static_cast( points[0]->GetNumberOfPoints() ) + densityFunctions[1]->Evaluate( fixedSamplePoint ) * static_cast( points[1]->GetNumberOfPoints() ); probabilityStar /= totalNumberOfPoints; if( probabilityStar == 0 ) { ++It; continue; } RealType probabilityStarFactor = vcl_pow( probabilityStar, static_cast( 2.0 - this->m_Alpha ) ); typename GaussianType::MeasurementVectorType sampleMeasurement; for( unsigned int d = 0; d < PointDimension; d++ ) { sampleMeasurement[d] = fixedSamplePoint[d]; } typename DensityFunctionType::NeighborhoodIdentifierType neighbors = densityFunctions[1]->GetNeighborhoodIdentifiers( sampleMeasurement, kNeighborhood ); for( unsigned int n = 0; n < neighbors.size(); n++ ) { RealType gaussian = densityFunctions[1]-> GetGaussian( neighbors[n] )->Evaluate( sampleMeasurement ); if( gaussian == 0 ) { continue; } typename GaussianType::MeanType mean = densityFunctions[1]->GetGaussian( neighbors[n] )->GetMean(); for( unsigned int d = 0; d < PointDimension; d++ ) { mean[d] -= fixedSamplePoint[d]; } if( this->m_UseAnisotropicCovariances ) { typename GaussianType::MatrixType Ci = densityFunctions[1]->GetGaussian( neighbors[n] ) ->GetInverseCovariance(); mean = Ci * mean; } else { mean /= vnl_math_sqr( densityFunctions[1]->GetGaussian( neighbors[n] )->GetSigma() ); } mean *= ( prefactor * gaussian / probabilityStarFactor ); for( unsigned int d = 0; d < PointDimension; d++ ) { derivative(neighbors[n], d) += mean[d]; } } ++It; } /** * second term, i.e. regularization term */ if( this->m_UseRegularizationTerm ) { RealType prefactor2 = -1.0 / ( static_cast( samples[1]->GetNumberOfPoints() ) * totalNumberOfPoints ); typename PointSetType::PointsContainerConstIterator It = samples[1]->GetPoints()->Begin(); while( It != samples[1]->GetPoints()->End() ) { PointType movingSamplePoint = It.Value(); RealType probability = densityFunctions[1]->Evaluate( movingSamplePoint ); if( probability == 0 ) { ++It; continue; } RealType probabilityFactor = vcl_pow( probability, static_cast( 2.0 - this->m_Alpha ) ); probabilityFactor *= ( samples[1]->GetNumberOfPoints() / totalNumberOfSamples ); typename GaussianType::MeasurementVectorType sampleMeasurement; for( unsigned int d = 0; d < PointDimension; d++ ) { sampleMeasurement[d] = movingSamplePoint[d]; } typename DensityFunctionType::NeighborhoodIdentifierType neighbors = densityFunctions[1]->GetNeighborhoodIdentifiers( sampleMeasurement, kNeighborhood ); for( unsigned int i = 0; i < neighbors.size(); i++ ) { RealType gaussian = densityFunctions[1]-> GetGaussian( neighbors[i] )->Evaluate( sampleMeasurement ); if( gaussian == 0 ) { continue; } typename GaussianType::MeanType mean = densityFunctions[1]->GetGaussian( neighbors[i] )->GetMean(); for( unsigned int d = 0; d < PointDimension; d++ ) { mean[d] -= movingSamplePoint[d]; } if( this->m_UseAnisotropicCovariances ) { typename GaussianType::MatrixType Ci = densityFunctions[1]->GetGaussian( neighbors[i] ) ->GetInverseCovariance(); mean = Ci * mean; } else { mean /= vnl_math_sqr( densityFunctions[1]->GetGaussian( neighbors[i] )->GetSigma() ); } mean *= ( prefactor2 * gaussian / probabilityFactor ); for( unsigned int d = 0; d < PointDimension; d++ ) { derivative(neighbors[i], d) += mean[d]; } } ++It; } } } /** Get both the match Measure and theDerivative Measure */ template void JensenHavrdaCharvatTsallisPointSetMetric ::GetValueAndDerivative( const TransformParametersType & parameters, MeasureType & value, DerivativeType & derivative ) const { /** * Only identity transform is valid */ // this->SetTransformParameters( parameters ); PointSetPointer points[2]; PointSetPointer samples[2]; typename DensityFunctionType::Pointer densityFunctions[2]; unsigned int kNeighborhood; if( this->m_UseWithRespectToTheMovingPointSet ) { points[0] = const_cast( static_cast( this->m_FixedPointSet ) ); points[1] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[0] = points[0]; samples[1] = points[1]; } else { samples[0] = this->m_FixedSamplePoints; samples[1] = this->m_MovingSamplePoints; } densityFunctions[0] = this->m_FixedDensityFunction; densityFunctions[1] = this->m_MovingDensityFunction; kNeighborhood = this->m_MovingEvaluationKNeighborhood; } else { points[1] = const_cast( static_cast( this->m_FixedPointSet ) ); points[0] = const_cast( static_cast( this->m_MovingPointSet ) ); if( this->m_UseInputAsSamples ) { samples[1] = points[1]; samples[0] = points[0]; } else { samples[1] = this->m_FixedSamplePoints; samples[0] = this->m_MovingSamplePoints; } densityFunctions[1] = this->m_FixedDensityFunction; densityFunctions[0] = this->m_MovingDensityFunction; kNeighborhood = this->m_FixedEvaluationKNeighborhood; } RealType totalNumberOfPoints = static_cast( points[0]->GetNumberOfPoints() ) + static_cast( points[1]->GetNumberOfPoints() ); RealType totalNumberOfSamples = static_cast( samples[0]->GetNumberOfPoints() ) + static_cast( samples[1]->GetNumberOfPoints() ); derivative.SetSize( points[1]->GetPoints()->Size(), PointDimension ); derivative.Fill( 0 ); value.SetSize( 1 ); value.Fill( 0 ); /** * first term */ RealType energyTerm1 = 0.0; RealType energyTerm2 = 0.0; RealType prefactor[2]; prefactor[0] = -1.0 / totalNumberOfSamples; if( this->m_Alpha != 1.0 ) { prefactor[0] /= ( this->m_Alpha - 1.0 ); } prefactor[1] = 1.0 / ( totalNumberOfSamples * totalNumberOfPoints ); typename PointSetType::PointsContainerConstIterator It = samples[0]->GetPoints()->Begin(); while( It != samples[0]->GetPoints()->End() ) { PointType fixedSamplePoint = It.Value(); RealType probabilityStar = densityFunctions[0]->Evaluate( fixedSamplePoint ) * static_cast( points[0]->GetNumberOfPoints() ) + densityFunctions[1]->Evaluate( fixedSamplePoint ) * static_cast( points[1]->GetNumberOfPoints() ); probabilityStar /= totalNumberOfPoints; if( probabilityStar == 0 ) { ++It; continue; } if( this->m_Alpha == 1.0 ) { energyTerm1 += ( prefactor[0] * vcl_log( probabilityStar ) / vnl_math::ln2 ); } else { energyTerm1 += ( prefactor[0] * vcl_pow( probabilityStar, static_cast( this->m_Alpha - 1.0 ) ) ); } RealType probabilityStarFactor = vcl_pow( probabilityStar, static_cast( 2.0 - this->m_Alpha ) ); typename GaussianType::MeasurementVectorType sampleMeasurement; for( unsigned int d = 0; d < PointDimension; d++ ) { sampleMeasurement[d] = fixedSamplePoint[d]; } typename DensityFunctionType::NeighborhoodIdentifierType neighbors = densityFunctions[1]->GetNeighborhoodIdentifiers( sampleMeasurement, kNeighborhood ); for( unsigned int n = 0; n < neighbors.size(); n++ ) { RealType gaussian = densityFunctions[1]-> GetGaussian( neighbors[n] )->Evaluate( sampleMeasurement ); if( gaussian == 0 ) { continue; } typename GaussianType::MeanType mean = densityFunctions[1]->GetGaussian( neighbors[n] )->GetMean(); for( unsigned int d = 0; d < PointDimension; d++ ) { mean[d] -= fixedSamplePoint[d]; } if( this->m_UseAnisotropicCovariances ) { typename GaussianType::MatrixType Ci = densityFunctions[1]->GetGaussian( neighbors[n] ) ->GetInverseCovariance(); mean = Ci * mean; } else { mean /= vnl_math_sqr( densityFunctions[1]->GetGaussian( neighbors[n] )->GetSigma() ); } mean *= ( prefactor[1] * gaussian / probabilityStarFactor ); for( unsigned int d = 0; d < PointDimension; d++ ) { derivative(neighbors[n], d) += mean[d]; } } ++It; } /** * second term, i.e. regularization term */ if( this->m_UseRegularizationTerm ) { RealType prefactor2[2]; prefactor2[0] = -static_cast( points[1]->GetNumberOfPoints() ) / ( totalNumberOfPoints * static_cast( samples[1]->GetNumberOfPoints() ) ); prefactor2[1] = -1.0 / ( static_cast( samples[1]->GetNumberOfPoints() ) * totalNumberOfPoints ); if( this->m_Alpha != 1.0 ) { prefactor2[0] /= ( this->m_Alpha - 1.0 ); } typename PointSetType::PointsContainerConstIterator It = samples[1]->GetPoints()->Begin(); while( It != samples[1]->GetPoints()->End() ) { PointType movingSamplePoint = It.Value(); RealType probability = densityFunctions[1]->Evaluate( movingSamplePoint ); if( probability == 0 ) { ++It; continue; } if( this->m_Alpha == 1.0 ) { energyTerm2 += ( prefactor2[0] * vcl_log( probability ) / vnl_math::ln2 ); } else { energyTerm2 += ( prefactor2[0] * vcl_pow( probability, static_cast( this->m_Alpha - 1.0 ) ) ); } RealType probabilityFactor = vcl_pow( probability, static_cast( 2.0 - this->m_Alpha ) ); probabilityFactor *= ( samples[1]->GetNumberOfPoints() / totalNumberOfSamples ); typename GaussianType::MeasurementVectorType sampleMeasurement; for( unsigned int d = 0; d < PointDimension; d++ ) { sampleMeasurement[d] = movingSamplePoint[d]; } typename DensityFunctionType::NeighborhoodIdentifierType neighbors = densityFunctions[1]->GetNeighborhoodIdentifiers( sampleMeasurement, kNeighborhood ); for( unsigned int i = 0; i < neighbors.size(); i++ ) { RealType gaussian = densityFunctions[1]-> GetGaussian( neighbors[i] )->Evaluate( sampleMeasurement ); if( gaussian == 0 ) { continue; } typename GaussianType::MeanType mean = densityFunctions[1]->GetGaussian( neighbors[i] )->GetMean(); for( unsigned int d = 0; d < PointDimension; d++ ) { mean[d] -= movingSamplePoint[d]; } if( this->m_UseAnisotropicCovariances ) { typename GaussianType::MatrixType Ci = densityFunctions[1]->GetGaussian( neighbors[i] ) ->GetInverseCovariance(); mean = Ci * mean; } else { mean /= vnl_math_sqr( densityFunctions[1]->GetGaussian( neighbors[i] )->GetSigma() ); } mean *= ( prefactor2[1] * gaussian / probabilityFactor ); for( unsigned int d = 0; d < PointDimension; d++ ) { derivative(neighbors[i], d) += mean[d]; } } ++It; } } value[0] = energyTerm1 - energyTerm2; } template void JensenHavrdaCharvatTsallisPointSetMetric ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf( os, indent ); os << indent << "Use with respect to the moving point set: " << this->m_UseWithRespectToTheMovingPointSet << std::endl; os << indent << "Use regularization term: " << this->m_UseRegularizationTerm << std::endl; os << indent << "Alpha: " << this->m_Alpha << std::endl; os << indent << "Fixed sigma: " << this->m_FixedPointSetSigma << std::endl; os << indent << "Moving sigma: " << this->m_MovingPointSetSigma << std::endl; if( !this->m_UseInputAsSamples ) { os << indent << "Number of fixed samples: " << this->m_NumberOfFixedSamples << std::endl; os << indent << "Number of moving samples: " << this->m_NumberOfMovingSamples << std::endl; } else { os << indent << "Use input points as samples." << std::endl; } if( this->m_UseAnisotropicCovariances ) { os << indent << "Fixed kernel sigma: " << this->m_FixedKernelSigma << std::endl; os << indent << "Moving kernel sigma: " << this->m_MovingKernelSigma << std::endl; os << indent << "Fixed covariance k-neighborhood: " << this->m_FixedCovarianceKNeighborhood << std::endl; os << indent << "Moving covariance k-neighborhood: " << this->m_MovingCovarianceKNeighborhood << std::endl; } else { os << indent << "Isotropic covariances are used." << std::endl; } } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenTsallisBSplineRegistrationFunction.h000066400000000000000000000247761147325206600311320ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenTsallisBSplineRegistrationFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkJensenTsallisBSplineRegistrationFunction_h_ #define _itkJensenTsallisBSplineRegistrationFunction_h_ #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkJensenHavrdaCharvatTsallisLabeledPointSetMetric.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkPointSet.h" namespace itk { /** * \class JensenTsallisBSplineRegistrationFunction * \ingroup FiniteDifferenceFunctions */ template class ITK_EXPORT JensenTsallisBSplineRegistrationFunction : public AvantsPDEDeformableRegistrationFunction { public: /** Standard class typedefs. */ typedef JensenTsallisBSplineRegistrationFunction Self; typedef AvantsPDEDeformableRegistrationFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods) */ itkTypeMacro( JensenTsallisBSplineRegistrationFunction, AvantsPDEDeformableRegistrationFunction ); /** * Inherit some enums from the superclass. */ itkStaticConstMacro( ImageDimension, unsigned int, Superclass::ImageDimension); itkStaticConstMacro( PointDimension, unsigned int, TFixedPointSet::PointDimension ); typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; typedef JensenHavrdaCharvatTsallisLabeledPointSetMetric PointSetMetricType; typedef typename PointSetMetricType::RealType RealType; /** * Moving typedefs */ typedef TMovingImage MovingImageType; typedef TMovingPointSet MovingPointSetType; typedef typename MovingImageType::Pointer MovingImagePointer; typedef typename MovingPointSetType::Pointer MovingPointSetPointer; /** * Fixed typedefs */ typedef TFixedImage FixedImageType; typedef TFixedPointSet FixedPointSetType; typedef typename FixedImageType::Pointer FixedImagePointer; typedef typename FixedPointSetType::Pointer FixedPointSetPointer; /** * Deformation field typedefs */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType VectorType; /** * BSpline typedefs */ /** Typedefs for B-spline filter */ typedef PointSet BSplinePointSetType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::WeightsContainerType BSplineWeightsType; typedef typename BSplineFilterType::PointDataImageType ControlPointLatticeType; typedef typename BSplineFilterType::ArrayType ArrayType; void SetAlpha( RealType r ) { this->m_Alpha = r; } RealType GetAlpha() { return this->m_Alpha; } void SetUseRegularizationTerm( bool b ) { this->m_UseRegularizationTerm = b; } RealType GetUseRegularizationTerm() { return this->m_UseRegularizationTerm; } void SetUseInputAsSamples( bool b ) { this->m_UseInputAsSamples = b; } RealType GetUseInputAsSamples() { return this->m_UseInputAsSamples; } void SetUseAnisotropicCovariances( bool b ) { this->m_UseAnisotropicCovariances = b; } RealType GetUseAnisotropicCovariances() { return this->m_UseAnisotropicCovariances; } void SetFixedPointSetSigma( RealType r ) { this->m_FixedPointSetSigma = r; } RealType GetFixedPointSetSigma() { return this->m_FixedPointSetSigma; } void SetFixedKernelSigma( RealType r ) { this->m_FixedKernelSigma = r; } RealType GetFixedKernelSigma() { return this->m_FixedKernelSigma; } void SetFixedEvaluationKNeighborhood( unsigned int r ) { this->m_FixedEvaluationKNeighborhood = r; } unsigned int GetFixedEvaluationKNeighborhood() { return this->m_FixedEvaluationKNeighborhood; } void SetFixedCovarianceKNeighborhood( unsigned int r ) { this->m_FixedCovarianceKNeighborhood = r; } unsigned int GetFixedCovarianceKNeighborhood() { return this->m_FixedCovarianceKNeighborhood; } void SetNumberOfFixedSamples( unsigned long r ) { this->m_NumberOfFixedSamples = r; } unsigned long GetNumberOfFixedSamples() { return this->m_NumberOfFixedSamples; } void SetMovingPointSetSigma( RealType r ) { this->m_MovingPointSetSigma = r; } RealType GetMovingPointSetSigma() { return this->m_MovingPointSetSigma; } void SetMovingKernelSigma( RealType r ) { this->m_MovingKernelSigma = r; } RealType GetMovingKernelSigma() { return this->m_MovingKernelSigma; } void SetMovingEvaluationKNeighborhood( unsigned int r ) { this->m_MovingEvaluationKNeighborhood = r; } unsigned int GetMovingEvaluationKNeighborhood() { return this->m_MovingEvaluationKNeighborhood; } void SetMovingCovarianceKNeighborhood( unsigned int r ) { this->m_MovingCovarianceKNeighborhood = r; } unsigned int GetMovingCovarianceKNeighborhood() { return this->m_MovingCovarianceKNeighborhood; } void SetNumberOfMovingSamples( unsigned long r ) { this->m_NumberOfMovingSamples = r; } unsigned long GetNumberOfMovingSamples() { return this->m_NumberOfMovingSamples; } void SetMeshResolution( ArrayType a ) { this->m_MeshResolution = a; } ArrayType GetMeshResolution() { return this->m_MeshResolution; } void SetNumberOfLevels( unsigned int r ) { this->m_NumberOfLevels = r; } unsigned int GetNumberOfLevels() { return this->m_NumberOfLevels; } void SetSplineOrder( unsigned int r ) { this->m_SplineOrder = r; } unsigned int GetSplineOrder() { return this->m_SplineOrder; } /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void *itkNotUsed(GlobalData)) const { return m_TimeStep; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const { delete (GlobalDataStruct *) GlobalData; } /** Set the object's state before each iteration. */ virtual void InitializeIteration(); virtual VectorType ComputeUpdate( const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType( 0.0 ) ); virtual VectorType ComputeUpdateInv( const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType( 0.0 ) ); protected: JensenTsallisBSplineRegistrationFunction(); ~JensenTsallisBSplineRegistrationFunction() {} /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * iterators for the fixed image. */ struct GlobalDataStruct { FixedImageNeighborhoodIteratorType m_FixedImageIterator; }; void PrintSelf(std::ostream& os, Indent indent) const; private: // typename ControlPointLatticeType::Pointer m_FixedControlPointLattice; // typename ControlPointLatticeType::Pointer m_MovingControlPointLattice; /** The global timestep. */ TimeStepType m_TimeStep; /** * point-set related variables */ bool m_UseRegularizationTerm; bool m_UseInputAsSamples; bool m_UseAnisotropicCovariances; typename DeformationFieldType::Pointer m_DerivativeFixedField; typename DeformationFieldType::Pointer m_DerivativeMovingField; RealType m_FixedPointSetSigma; RealType m_FixedKernelSigma; unsigned int m_FixedEvaluationKNeighborhood; unsigned int m_FixedCovarianceKNeighborhood; unsigned long m_NumberOfFixedSamples; RealType m_MovingPointSetSigma; RealType m_MovingKernelSigma; unsigned int m_MovingEvaluationKNeighborhood; unsigned int m_MovingCovarianceKNeighborhood; unsigned long m_NumberOfMovingSamples; RealType m_Alpha; /** * Bspline related variables */ unsigned int m_SplineOrder; unsigned int m_NumberOfLevels; ArrayType m_MeshResolution; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkJensenTsallisBSplineRegistrationFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkJensenTsallisBSplineRegistrationFunction.txx000066400000000000000000000413401147325206600315100ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJensenTsallisBSplineRegistrationFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkJensenTsallisBSplineRegistrationFunction_txx_ #define _itkJensenTsallisBSplineRegistrationFunction_txx_ #include "itkJensenTsallisBSplineRegistrationFunction.h" #include "itkImageLinearConstIteratorWithIndex.h" //#include "itkBSplineControlPointImageFilter.h" namespace itk { template JensenTsallisBSplineRegistrationFunction ::JensenTsallisBSplineRegistrationFunction() { this->m_UseRegularizationTerm = false; this->m_UseInputAsSamples = true; this->m_UseAnisotropicCovariances = false; this->m_NumberOfFixedSamples = 100; this->m_FixedPointSetSigma = 1.0; this->m_FixedKernelSigma = 0.0; this->m_FixedEvaluationKNeighborhood = 50; this->m_NumberOfMovingSamples = 100; this->m_MovingPointSetSigma = 1.0; this->m_MovingKernelSigma = 0.0; this->m_MovingEvaluationKNeighborhood = 50; unsigned int covarianceKNeighborhood = static_cast( vcl_pow( 3.0, static_cast( ImageDimension ) ) ) - 1; this->m_FixedCovarianceKNeighborhood = covarianceKNeighborhood; this->m_MovingCovarianceKNeighborhood = covarianceKNeighborhood; this->m_Alpha = 2.0; // this->m_FixedControlPointLattice = NULL; // this->m_MovingControlPointLattice = NULL; this->m_DerivativeFixedField = NULL; this->m_DerivativeMovingField = NULL; this->m_IsPointSetMetric=true; this->m_SplineOrder = 3; this->m_NumberOfLevels = 1; this->m_MeshResolution.Fill( 1 ); } template void JensenTsallisBSplineRegistrationFunction ::InitializeIteration( void ) { if( this->m_FixedKernelSigma == 0 ) { double maxFixedSpacing = 0.0; for( unsigned int d = 0; d < ImageDimension; d++ ) { if( this->GetFixedImage()->GetSpacing()[d] ) { maxFixedSpacing = this->GetFixedImage()->GetSpacing()[d]; } } this->m_FixedKernelSigma = 2.0 * maxFixedSpacing; } if( this->m_MovingKernelSigma == 0 ) { double maxMovingSpacing = 0.0; for( unsigned int d = 0; d < ImageDimension; d++ ) { if( this->GetMovingImage()->GetSpacing()[d] ) { maxMovingSpacing = this->GetMovingImage()->GetSpacing()[d]; } } this->m_MovingKernelSigma = 2.0 * maxMovingSpacing; } typename PointSetMetricType::Pointer pointSetMetric = PointSetMetricType::New(); pointSetMetric->SetFixedPointSet( this->m_FixedPointSet ); pointSetMetric->SetMovingPointSet( this->m_MovingPointSet ); pointSetMetric->SetUseRegularizationTerm( this->m_UseRegularizationTerm ); pointSetMetric->SetUseInputAsSamples( this->m_UseInputAsSamples ); pointSetMetric->SetUseAnisotropicCovariances( this->m_UseAnisotropicCovariances ); pointSetMetric->SetNumberOfFixedSamples( this->m_NumberOfFixedSamples ); pointSetMetric->SetFixedPointSetSigma( this->m_FixedPointSetSigma ); pointSetMetric->SetFixedKernelSigma( this->m_FixedKernelSigma ); pointSetMetric->SetFixedCovarianceKNeighborhood( this->m_FixedCovarianceKNeighborhood ); pointSetMetric->SetFixedEvaluationKNeighborhood( this->m_FixedEvaluationKNeighborhood ); pointSetMetric->SetNumberOfMovingSamples( this->m_NumberOfMovingSamples ); pointSetMetric->SetMovingPointSetSigma( this->m_MovingPointSetSigma ); pointSetMetric->SetMovingKernelSigma( this->m_MovingKernelSigma ); pointSetMetric->SetMovingCovarianceKNeighborhood( this->m_MovingCovarianceKNeighborhood ); pointSetMetric->SetMovingEvaluationKNeighborhood( this->m_MovingEvaluationKNeighborhood ); pointSetMetric->SetAlpha( this->m_Alpha ); pointSetMetric->Initialize(); typename PointSetMetricType::DefaultTransformType::ParametersType parameters; parameters.Fill( 0.0 ); /** * Calculate with respect to the moving point set */ pointSetMetric->SetUseWithRespectToTheMovingPointSet( true ); typename PointSetMetricType::DerivativeType movingGradient; typename PointSetMetricType::MeasureType movingMeasure; pointSetMetric->GetValueAndDerivative( parameters, movingMeasure, movingGradient ); this->m_Energy += movingMeasure[0]; typename BSplinePointSetType::Pointer movingGradientPoints = BSplinePointSetType::New(); movingGradientPoints->Initialize(); typename BSplineWeightsType::Pointer movingWeights = BSplineWeightsType::New(); movingWeights->Initialize(); unsigned long count = 0; for( unsigned int n = 0; n < pointSetMetric->GetNumberOfValues(); n++ ) { typename MovingPointSetType::PointType point; this->m_MovingPointSet->GetPoint( n, &point ); typename BSplinePointSetType::PointType bsplinePoint; VectorType gradient; bsplinePoint.CastFrom( point ); bool isInside = true; for( unsigned int d = 0; d < PointDimension; d++ ) { if( bsplinePoint[d] <= this->GetMovingImage()->GetOrigin()[d] || bsplinePoint[d] >= this->GetMovingImage()->GetOrigin()[d] + ( this->GetMovingImage()->GetLargestPossibleRegion().GetSize()[d] - 1 ) * this->GetMovingImage()->GetSpacing()[d] ) { isInside = false; break; } } if( isInside ) { for( unsigned int d = 0; d < PointDimension; d++ ) { gradient[d] = movingGradient(n, d); } movingGradientPoints->SetPoint( count, bsplinePoint ); movingGradientPoints->SetPointData( count, gradient ); movingWeights->InsertElement( count, 1.0 ); count++; } } VectorType zeroVector; zeroVector.Fill( 0.0 ); ImageLinearConstIteratorWithIndex ItM( this->GetMovingImage(), this->GetMovingImage()->GetLargestPossibleRegion() ); for( unsigned int d = 0; d < PointDimension; d++ ) { ItM.SetDirection( d ); ItM.GoToBegin(); while( !ItM.IsAtEnd() ) { typename MovingImageType::PointType point; typename BSplinePointSetType::PointType bsplinePoint; ItM.GoToBeginOfLine(); this->GetMovingImage()->TransformIndexToPhysicalPoint( ItM.GetIndex(), point ); bsplinePoint.CastFrom( point ); movingGradientPoints->SetPoint( count, bsplinePoint ); movingGradientPoints->SetPointData( count, zeroVector ); count++; ItM.GoToEndOfLine(); --ItM; this->GetMovingImage()->TransformIndexToPhysicalPoint( ItM.GetIndex(), point ); bsplinePoint.CastFrom( point ); movingGradientPoints->SetPoint( count, bsplinePoint ); movingGradientPoints->SetPointData( count, zeroVector ); movingWeights->InsertElement( count, 1000.0 ); count++; ItM.NextLine(); } } ArrayType numberOfMovingControlPoints; for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfMovingControlPoints[d] = this->m_SplineOrder + static_cast( vcl_floor( 0.5 + static_cast( this->GetMovingImage()->GetLargestPossibleRegion().GetSize()[d] ) / static_cast( this->m_MeshResolution[d] ) ) ); } typename BSplineFilterType::Pointer movingBSpliner = BSplineFilterType::New(); movingBSpliner->SetInput( movingGradientPoints ); movingBSpliner->SetPointWeights( movingWeights.GetPointer() ); movingBSpliner->SetOrigin( this->GetMovingImage()->GetOrigin() ); movingBSpliner->SetSpacing( this->GetMovingImage()->GetSpacing() ); movingBSpliner->SetSize( this->GetMovingImage()->GetLargestPossibleRegion().GetSize() ); movingBSpliner->SetNumberOfLevels( this->m_NumberOfLevels ); movingBSpliner->SetSplineOrder( this->m_SplineOrder ); movingBSpliner->SetNumberOfControlPoints( numberOfMovingControlPoints ); movingBSpliner->SetGenerateOutputImage( true ); movingBSpliner->Update(); this->m_DerivativeMovingField = movingBSpliner->GetOutput(); // this->m_MovingControlPointLattice = movingBSpliner->GetPhiLattice(); /** * Calculate with respect to the fixed point set */ pointSetMetric->SetUseWithRespectToTheMovingPointSet( false ); typename PointSetMetricType::DerivativeType fixedGradient; typename PointSetMetricType::MeasureType fixedMeasure; pointSetMetric->GetValueAndDerivative( parameters, fixedMeasure, fixedGradient ); this->m_Energy += fixedMeasure[0]; typename BSplinePointSetType::Pointer fixedGradientPoints = BSplinePointSetType::New(); fixedGradientPoints->Initialize(); typename BSplineWeightsType::Pointer fixedWeights = BSplineWeightsType::New(); fixedWeights->Initialize(); count = 0; for( unsigned int n = 0; n < pointSetMetric->GetNumberOfValues(); n++ ) { typename FixedPointSetType::PointType point; this->m_FixedPointSet->GetPoint( n, &point ); typename BSplinePointSetType::PointType bsplinePoint; VectorType gradient; bsplinePoint.CastFrom( point ); bool isInside = true; for( unsigned int d = 0; d < PointDimension; d++ ) { if( bsplinePoint[d] <= this->GetFixedImage()->GetOrigin()[d] || bsplinePoint[d] >= this->GetFixedImage()->GetOrigin()[d] + ( this->GetFixedImage()->GetLargestPossibleRegion().GetSize()[d] - 1 ) * this->GetFixedImage()->GetSpacing()[d] ) { isInside = false; break; } } if( isInside ) { for( unsigned int d = 0; d < PointDimension; d++ ) { gradient[d] = fixedGradient(n, d); } fixedGradientPoints->SetPoint( count, bsplinePoint ); fixedGradientPoints->SetPointData( count, gradient ); fixedWeights->InsertElement( count, 1.0 ); count++; } } ImageLinearConstIteratorWithIndex ItF( this->GetFixedImage(), this->GetFixedImage()->GetLargestPossibleRegion() ); for( unsigned int d = 0; d < PointDimension; d++ ) { ItF.SetDirection( d ); ItF.GoToBegin(); while( !ItF.IsAtEnd() ) { typename FixedImageType::PointType point; typename BSplinePointSetType::PointType bsplinePoint; ItF.GoToBeginOfLine(); this->GetFixedImage()->TransformIndexToPhysicalPoint( ItF.GetIndex(), point ); bsplinePoint.CastFrom( point ); fixedGradientPoints->SetPoint( count, bsplinePoint ); fixedGradientPoints->SetPointData( count, zeroVector ); fixedWeights->InsertElement( count, 1.0 ); count++; ItF.GoToEndOfLine(); --ItF; this->GetFixedImage()->TransformIndexToPhysicalPoint( ItF.GetIndex(), point ); bsplinePoint.CastFrom( point ); fixedGradientPoints->SetPoint( count, bsplinePoint ); fixedGradientPoints->SetPointData( count, zeroVector ); fixedWeights->InsertElement( count, 1000.0 ); count++; ItF.NextLine(); } } ArrayType numberOfFixedControlPoints; for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfFixedControlPoints[d] = this->m_SplineOrder + static_cast( vcl_floor( 0.5 + static_cast( this->GetFixedImage()->GetLargestPossibleRegion().GetSize()[d] ) / static_cast( this->m_MeshResolution[d] ) ) ); } typename BSplineFilterType::Pointer fixedBSpliner = BSplineFilterType::New(); fixedBSpliner->SetInput( fixedGradientPoints ); fixedBSpliner->SetPointWeights( fixedWeights.GetPointer() ); fixedBSpliner->SetOrigin( this->GetFixedImage()->GetOrigin() ); fixedBSpliner->SetSpacing( this->GetFixedImage()->GetSpacing() ); fixedBSpliner->SetSize( this->GetFixedImage()->GetLargestPossibleRegion().GetSize() ); fixedBSpliner->SetNumberOfLevels( this->m_NumberOfLevels ); fixedBSpliner->SetSplineOrder( this->m_SplineOrder ); fixedBSpliner->SetNumberOfControlPoints( numberOfFixedControlPoints ); fixedBSpliner->SetGenerateOutputImage( true ); fixedBSpliner->Update(); this->m_DerivativeFixedField = fixedBSpliner->GetOutput(); // this->m_FixedControlPointLattice = fixedBSpliner->GetPhiLattice(); } template typename JensenTsallisBSplineRegistrationFunction::VectorType JensenTsallisBSplineRegistrationFunction ::ComputeUpdate( const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset ) { if( this->m_DerivativeFixedField ) { return -this->m_DerivativeFixedField->GetPixel( neighborhood.GetIndex() ); } else { itkExceptionMacro( "Initialize() has not been called." ); } /* typedef BSplineControlPointImageFilter BSplineControlPointImageFilterType; typename BSplineControlPointImageFilterType::Pointer movingBSpliner = BSplineControlPointImageFilterType::New(); movingBSpliner->SetInput( this->m_MovingControlPointLattice ); movingBSpliner->SetOrigin( this->GetMovingImage()->GetOrigin() ); movingBSpliner->SetSpacing( this->GetMovingImage()->GetSpacing() ); movingBSpliner->SetSize( this->GetMovingImage()->GetLargestPossibleRegion().GetSize() ); movingBSpliner->SetSplineOrder( this->m_SplineOrder ); VectorType gradient; movingBSpliner->EvaluateAtIndex( neighborhood.GetIndex(), gradient ); return gradient; */ } template typename JensenTsallisBSplineRegistrationFunction::VectorType JensenTsallisBSplineRegistrationFunction ::ComputeUpdateInv( const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset ) { if( this->m_DerivativeMovingField ) { return -this->m_DerivativeMovingField->GetPixel( neighborhood.GetIndex() ); } else { itkExceptionMacro( "Initialize() has not been called." ); } /* typedef BSplineControlPointImageFilter BSplineControlPointImageFilterType; typename BSplineControlPointImageFilterType::Pointer fixedBSpliner = BSplineControlPointImageFilterType::New(); fixedBSpliner->SetInput( this->m_FixedControlPointLattice ); fixedBSpliner->SetOrigin( this->GetFixedImage()->GetOrigin() ); fixedBSpliner->SetSpacing( this->GetFixedImage()->GetSpacing() ); fixedBSpliner->SetSize( this->GetFixedImage()->GetLargestPossibleRegion().GetSize() ); fixedBSpliner->SetSplineOrder( this->m_SplineOrder ); VectorType gradient; fixedBSpliner->EvaluateAtIndex( neighborhood.GetIndex(), gradient ); return gradient; */ } template void JensenTsallisBSplineRegistrationFunction ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf( os, indent ); os << indent << "Use regularization term: " << this->m_UseRegularizationTerm << std::endl; if( !this->m_UseInputAsSamples ) { os << indent << "Number of fixed samples: " << this->m_NumberOfFixedSamples << std::endl; os << indent << "Number of moving samples: " << this->m_NumberOfMovingSamples << std::endl; } os << indent << "Alpha: " << this->m_Alpha << std::endl; os << indent << "Fixed sigma: " << this->m_FixedPointSetSigma << std::endl; os << indent << "Moving sigma: " << this->m_MovingPointSetSigma << std::endl; os << indent << "Spline order: " << this->m_SplineOrder << std::endl; os << indent << "Number of levels: " << this->m_NumberOfLevels << std::endl; os << indent << "Number of control points: " << this->m_MeshResolution << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkPICSLAdvancedNormalizationToolKit.h000066400000000000000000000120121147325206600273270ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPICSLAdvancedNormalizationToolKit.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkPICSLAdvancedNormalizationToolKit_h #define __itkPICSLAdvancedNormalizationToolKit_h #include "itkObject.h" #include "itkObjectFactory.h" #include "itkANTSImageTransformation.h" #include "itkANTSImageRegistrationOptimizer.h" #include "itkANTSSimilarityMetric.h" #include "antsCommandLineParser.h" #include "itkImage.h" #include "itkMacro.h" #include "itkANTSLabeledPointSet.h" namespace itk { template class ITK_EXPORT PICSLAdvancedNormalizationToolKit : public Object { public: /** Standard class typedefs. */ typedef PICSLAdvancedNormalizationToolKit Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( PICSLAdvancedNormalizationToolKit, Object ); itkStaticConstMacro( Dimension, unsigned int, TDimension ); typedef TReal RealType; typedef Image ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::PixelType PixelType; typedef itk::ANTSImageTransformation TransformationModelType; typedef typename TransformationModelType::Pointer TransformationModelPointer; typedef itk::ANTSImageRegistrationOptimizer RegistrationOptimizerType; typedef typename RegistrationOptimizerType::Pointer RegistrationOptimizerPointer; typedef typename TransformationModelType::DeformationFieldType DeformationFieldType; typedef typename TransformationModelType::AffineTransformType AffineTransformType; typedef typename RegistrationOptimizerType::OptAffineType OptAffineType; /** Point Set Type */ typedef itk::ANTSLabeledPointSet LabeledPointSetType; typedef typename LabeledPointSetType::Pointer LabeledPointSetPointer; typedef typename LabeledPointSetType::PointSetType PointSetType; /** Typedefs for similarity metrics */ typedef ANTSSimilarityMetric SimilarityMetricType; typedef typename SimilarityMetricType::Pointer SimilarityMetricPointer; typedef std::vector SimilarityMetricListType; typedef typename SimilarityMetricType::MetricType MetricBaseType; typedef ants::CommandLineParser ParserType; typedef typename ParserType::OptionType OptionType; void ParseCommandLine( int argc, char **argv ); TransformationModelPointer GetTransformationModel( ) { return this->m_TransformationModel; } RegistrationOptimizerPointer SetRegistrationOptimizer( ) { return this->m_RegistrationOptimizer; } void SetTransformationModel( TransformationModelPointer T ) {this->m_TransformationModel=T; } void SetRegistrationOptimizer( RegistrationOptimizerPointer T ) {this->m_RegistrationOptimizer=T; } void InitializeTransformAndOptimizer(); void RunRegistration(); protected: PICSLAdvancedNormalizationToolKit(); virtual ~PICSLAdvancedNormalizationToolKit() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: PICSLAdvancedNormalizationToolKit( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented ImagePointer SubsampleImage( ImagePointer, RealType ); ImagePointer PreprocessImage( ImagePointer ); ImagePointer ReplaceProblematicPixelValues( ImagePointer, PixelType ); void InitializeCommandLineOptions(); void ReadImagesAndMetrics(); typename ParserType::Pointer m_Parser; TransformationModelPointer m_TransformationModel; RegistrationOptimizerPointer m_RegistrationOptimizer; SimilarityMetricListType m_SimilarityMetrics; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkPICSLAdvancedNormalizationToolKit.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkPICSLAdvancedNormalizationToolKit.txx000066400000000000000000001536641147325206600277460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPICSLAdvancedNormalizationToolKit.txx,v $ Language: C++ Date: $Date: 2009/03/08 19:51:49 $ Version: $Revision: 1.22 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkPICSLAdvancedNormalizationToolKit_txx_ #define _itkPICSLAdvancedNormalizationToolKit_txx_ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include "itkPICSLAdvancedNormalizationToolKit.h" #include "itkHistogramMatchingImageFilter.h" #include "itkSpatialMutualInformationRegistrationFunction.h" #include "itkIdentityTransform.h" #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkLabeledPointSetFileReader.h" #include "itkLinearInterpolateImageFunction.h" #include "itkRecursiveGaussianImageFilter.h" #include "itkResampleImageFilter.h" // Image similarity metrics #include "itkAvantsMutualInformationRegistrationFunction.h" #include "itkSyNDemonsRegistrationFunction.h" #include "itkProbabilisticRegistrationFunction.h" #include "itkCrossCorrelationRegistrationFunction.h" #include "itkExpectationBasedPointSetRegistrationFunction.h" //#include "itkRobustDemonsRegistrationFunction.h" //#include "itkRobustOpticalFlow.h" //#include "itkSectionMutualInformationRegistrationFunction.h" #include "itkJensenTsallisBSplineRegistrationFunction.h" #include "vnl/vnl_math.h" #include "ANTS_affine_registration2.h" namespace itk { template PICSLAdvancedNormalizationToolKit ::PICSLAdvancedNormalizationToolKit() { this->InitializeCommandLineOptions(); } template void PICSLAdvancedNormalizationToolKit ::ParseCommandLine( int argc, char **argv ) { this->m_Parser->Parse( argc, argv ); typename ParserType::OptionListType unknownOptions = this->m_Parser->GetUnknownOptions(); if( unknownOptions.size() ) { std::cout << std::endl << "WARNING: Unknown options" << std::endl; typename ParserType::OptionListType::const_iterator its; for( its = unknownOptions.begin(); its != unknownOptions.end(); its++ ) { if( (*its)->GetShortName() != '\0' ) { std::cout << " " << '-' << (*its)->GetShortName() << std::endl; } else { std::cout << " " << "--" << (*its)->GetLongName() << std::endl; } } std::cout << std::endl; } std::string printhelp_long = this->m_Parser->GetOption( "help" )->GetValue(); unsigned int help_long = this->m_Parser->template Convert( printhelp_long ); if ( help_long ) { this->m_Parser->PrintMenu( std::cout, 7, false ); exit( 0 ); } std::string printhelp_short = this->m_Parser->GetOption( 'h' )->GetValue(); unsigned int help_short = this->m_Parser->template Convert( printhelp_short ); if ( help_short ) { this->m_Parser->PrintMenu( std::cout, 7, true ); exit( 0 ); } } template void PICSLAdvancedNormalizationToolKit ::InitializeTransformAndOptimizer() { if (!this->m_TransformationModel) { this->m_TransformationModel=TransformationModelType::New(); } if (!this->m_RegistrationOptimizer) { this->m_RegistrationOptimizer=RegistrationOptimizerType::New(); } std::string temp = this->m_Parser->GetOption( "output-naming" )->GetValue(); this->m_TransformationModel->SetNamingConvention( temp ); this->m_TransformationModel->InitializeTransform(); this->m_RegistrationOptimizer->SetParser( this->m_Parser ); this->m_RegistrationOptimizer->SetSimilarityMetrics( this->m_SimilarityMetrics ); } template void PICSLAdvancedNormalizationToolKit ::RunRegistration() { /** parse the command line and get input objects */ this->ReadImagesAndMetrics(); // exit(0); /** initializes the transformation model and the optimizer */ this->InitializeTransformAndOptimizer(); /** Get the mask if there is one */ if ( typename OptionType::Pointer option = this->m_Parser->GetOption( "mask-image" ) ) { typedef ImageFileReader ReaderType; std::string maskfn = this->m_Parser->GetOption( "mask-image" )->GetValue(); if (maskfn.length() > 4) { typename ReaderType::Pointer maskImageFileReader = ReaderType::New(); maskImageFileReader->SetFileName( maskfn.c_str() ); maskImageFileReader->Update(); ImagePointer maskImage = this->PreprocessImage( maskImageFileReader->GetOutput() ); this->m_RegistrationOptimizer->SetMaskImage(maskImage); } } typename TransformationModelType::AffineTransformPointer aff_init, aff, fixed_aff_init; //added by songgang // try initialize the affine transform typename OptionType::ValueType initial_affine_filename = this->m_Parser->GetOption( "initial-affine" )->GetValue(); if ( initial_affine_filename != "" ){ std::cout << "Loading affine registration from: " << initial_affine_filename << std::endl; aff_init = TransformationModelType::AffineTransformType::New(); ReadAffineTransformFile(initial_affine_filename, aff_init); } else{ std::cout << "Use identity affine transform as initial affine para." << std::endl; std::cout << "aff_init.IsNull()==" << aff_init.IsNull() << std::endl; } typename OptionType::ValueType fixed_initial_affine_filename = this->m_Parser->GetOption( "fixed-image-initial-affine" )->GetValue(); if ( fixed_initial_affine_filename != "" ){ std::cout << "Loading affine registration from: " << fixed_initial_affine_filename << std::endl; fixed_aff_init = TransformationModelType::AffineTransformType::New(); ReadAffineTransformFile(fixed_initial_affine_filename, fixed_aff_init); std::cout << " FIXME! currently, if one passes a fixed initial affine mapping, then NO affine mapping will be performed subsequently! " << std::endl; } else{ std::cout << "Use identity affine transform as initial fixed affine para." << std::endl; std::cout << "fixed_aff_init.IsNull()==" << fixed_aff_init.IsNull() << std::endl; } bool useNN = this->m_Parser->template Convert( this->m_Parser->GetOption( "use-NN" )->GetValue() ); if ( useNN) this->m_RegistrationOptimizer->SetUseNearestNeighborInterpolation(true); else this->m_RegistrationOptimizer->SetUseNearestNeighborInterpolation(false); typename OptionType::ValueType continue_affine = this->m_Parser->GetOption( "continue-affine" )->GetValue(); if ( fixed_initial_affine_filename != "" ) continue_affine=std::string("false"); if ( continue_affine == "true" ){ std::cout << "Continue affine registration from the input" << std::endl; //<< aff_init << std::endl; OptAffineType affine_opt; //InitializeAffineOption() { affine_opt.transform_initial = aff_init; std::string temp=this->m_Parser->GetOption( "number-of-affine-iterations" )->GetValue(); affine_opt.number_of_iteration_list = this->m_Parser->template ConvertVector(temp); affine_opt.number_of_levels = affine_opt.number_of_iteration_list.size(); temp=this->m_Parser->GetOption( "affine-metric-type" )->GetValue(); if (temp == "MI") affine_opt.metric_type = AffineWithMutualInformation; if (temp == "MSQ") affine_opt.metric_type = AffineWithMeanSquareDifference; if (temp == "CCH") affine_opt.metric_type = AffineWithHistogramCorrelation; if (temp == "CC") affine_opt.metric_type = AffineWithNormalizedCorrelation; if (temp == "GD") affine_opt.metric_type = AffineWithGradientDifference; temp=this->m_Parser->GetOption( "MI-option" )->GetValue(); std::vector mi_option = this->m_Parser->template ConvertVector(temp); affine_opt.MI_bins = mi_option[0]; affine_opt.MI_samples = mi_option[1]; temp=this->m_Parser->GetOption( "rigid-affine" )->GetValue(); std::string temp2=this->m_Parser->GetOption( "do-rigid" )->GetValue(); affine_opt.is_rigid = ( ( temp=="true" ) || ( temp2=="true" ) || ( temp == "1" ) || ( temp2 == "1" ) ); temp=this->m_Parser->GetOption( "affine-gradient-descent-option" )->GetValue(); std::vector gradient_option = this->m_Parser->template ConvertVector(temp); affine_opt.maximum_step_length = gradient_option[0]; affine_opt.relaxation_factor = gradient_option[1]; affine_opt.minimum_step_length = gradient_option[2]; affine_opt.translation_scales = gradient_option[3]; // std::cout << affine_opt; temp=this->m_Parser->GetOption( "use-rotation-header" )->GetValue(); affine_opt.use_rotation_header = (temp=="true"); std::cout << "affine_opt.use_rotation_header = " << affine_opt.use_rotation_header << std::endl; temp=this->m_Parser->GetOption( "ignore-void-origin")->GetValue(); affine_opt.ignore_void_orgin = (temp=="true"); std::cout << "affine_opt.ignore_void_orgin = " << affine_opt.ignore_void_orgin << std::endl; } aff = this->m_RegistrationOptimizer->AffineOptimization(affine_opt); } else{ std::cout << "Use fixed initial affine para." << std::endl; if (aff_init.IsNull()){ aff_init = TransformationModelType::AffineTransformType::New(); aff_init->SetIdentity(); } if (fixed_aff_init.IsNull()){ fixed_aff_init = TransformationModelType::AffineTransformType::New(); fixed_aff_init->SetIdentity(); } aff = aff_init; } // std::cout << aff << std::endl; this->m_TransformationModel->SetAffineTransform(aff); this->m_TransformationModel->SetFixedImageAffineTransform(fixed_aff_init); this->m_RegistrationOptimizer->SetAffineTransform(aff); this->m_RegistrationOptimizer->SetFixedImageAffineTransform( this->m_TransformationModel->GetFixedImageAffineTransform()); /** Second, optimize Diff */ this->m_RegistrationOptimizer->DeformableOptimization(); std::cout << " Registration Done " << std::endl; this->m_TransformationModel->SetDeformationField(this->m_RegistrationOptimizer->GetDeformationField()); this->m_TransformationModel->SetInverseDeformationField(this->m_RegistrationOptimizer->GetInverseDeformationField()); } template typename PICSLAdvancedNormalizationToolKit::ImagePointer PICSLAdvancedNormalizationToolKit ::PreprocessImage( ImagePointer image ) { image = this->ReplaceProblematicPixelValues( image, 0 ); return image; } template typename PICSLAdvancedNormalizationToolKit::ImagePointer PICSLAdvancedNormalizationToolKit ::ReplaceProblematicPixelValues( ImagePointer image, PixelType value = 0 ) { ImageRegionIterator It( image, image->GetRequestedRegion() ); for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType pixel = It.Get(); if ( vnl_math_isinf( pixel ) || vnl_math_isnan( pixel ) ) { It.Set( value ); } } typedef itk::MinimumMaximumImageFilter MinMaxFilterType; typename MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New(); minMaxFilter->SetInput( image ); minMaxFilter->Update(); double min = minMaxFilter->GetMinimum(); double shift = -1.0 * static_cast( min ); double scale = static_cast( minMaxFilter->GetMaximum() ); scale += shift; scale = 1.0 / scale; typedef itk::ShiftScaleImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( image ); filter->SetShift( shift ); filter->SetScale( scale ); filter->Update(); return filter->GetOutput(); } /** * Standard "PrintSelf" method */ template void PICSLAdvancedNormalizationToolKit ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } template void PICSLAdvancedNormalizationToolKit ::ReadImagesAndMetrics() { /** * Read in all images and preprocess them before * storing them in their corresponding image lists. */ this->m_SimilarityMetrics.clear(); typedef ImageFileReader ReaderType; bool useHistMatch = this->m_Parser->template Convert( this->m_Parser->GetOption( "use-Histogram-Matching" )->GetValue() ); /** * Read the metrics and image files */ if ( typename OptionType::Pointer option = this->m_Parser->GetOption( "image-metric" ) ) { std::cout <<" values " << option->GetNumberOfValues() << std::endl; for ( unsigned int i = 0; i < option->GetNumberOfValues(); i++ ) { SimilarityMetricPointer similarityMetric = SimilarityMetricType::New(); RealType similarityMetricScalarWeight = 1.0; similarityMetric->SetWeightScalar( similarityMetricScalarWeight ); unsigned int parameterCount = 0; typename ReaderType::Pointer fixedImageFileReader = ReaderType::New(); fixedImageFileReader->SetFileName( option->GetParameter( i, parameterCount ) ); fixedImageFileReader->Update(); ImagePointer fixedImage = this->PreprocessImage( fixedImageFileReader->GetOutput() ); similarityMetric->SetFixedImage( fixedImage ); parameterCount++; std::cout << " Fixed image file: " << fixedImageFileReader->GetFileName() << std::endl; typename ReaderType::Pointer movingImageFileReader = ReaderType::New(); movingImageFileReader->SetFileName( option->GetParameter( i, parameterCount ) ); movingImageFileReader->Update(); ImagePointer movingImage = this->PreprocessImage( movingImageFileReader->GetOutput() ); similarityMetric->SetMovingImage( movingImage ); typename SimilarityMetricType::RadiusType radius; radius.Fill( 0 ); parameterCount++; std::cout << " Moving image file: " << movingImageFileReader->GetFileName() << std::endl; /** * Check if similarity metric is image based or point-set based. * Image metrics: * > mean-squares/MeanSquares/MSQ * > mutual-information/MutualInformation/MI * > cross-correlation/CrossCorrelation/CC * > probabilistic/Probabilistic/PR * * Point-set metrics: * > point-set-expectation/PointSetExpectation/PSE * > jensen-tsallis-bspline/JensenTsallisBSpline/JTB * */ bool isMetricPointSetBased = false; typename OptionType::ValueType whichMetric = option->GetValue( i ); if ( whichMetric == "point-set-expectation" || whichMetric == "PointSetExpectation" || whichMetric == "PSE" || whichMetric == "jensen-tsallis-bspline" || whichMetric == "JensenTsallisBSpline" || whichMetric == "JTB" ) { isMetricPointSetBased = true; } if ( isMetricPointSetBased ) { std::cout << "Metric " << i << ": " << " Point-set " << whichMetric << " n-params " << option->GetNumberOfParameters( i ) << std::endl; /** * Read in the point-set metric parameters */ typedef LabeledPointSetFileReader PointSetReaderType; typename PointSetReaderType::Pointer fixedPointSetReader = PointSetReaderType::New(); fixedPointSetReader->SetFileName( option->GetParameter( i, parameterCount ) ); parameterCount++; typename PointSetReaderType::Pointer movingPointSetReader = PointSetReaderType::New(); movingPointSetReader->SetFileName( option->GetParameter( i, parameterCount ) ); parameterCount++; if ( option->GetNumberOfParameters( i ) > parameterCount ) { similarityMetricScalarWeight = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } similarityMetric->SetWeightScalar( similarityMetricScalarWeight ); std::cout << " similarity metric weight: " << similarityMetricScalarWeight << std::endl; float pointSetPercent=0.5; float pointSetSigma = 5.0; bool extractBoundaryPointsOnly = false; unsigned int kNeighborhood = 50; if ( option->GetNumberOfParameters( i ) > parameterCount ) { pointSetPercent = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { pointSetSigma = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { extractBoundaryPointsOnly = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { kNeighborhood = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } std::cout << " point-set sigma = " << pointSetSigma << std::endl; std::cout << " percentage of points = " << pointSetPercent << std::endl; std::cout << " k-neighborhood = " << kNeighborhood << std::endl; if( extractBoundaryPointsOnly ) { std::cout << " use only boundary points. " << pointSetPercent << std::endl; } fixedPointSetReader->SetRandomPercentage( pointSetPercent ); fixedPointSetReader->SetExtractBoundaryPoints( extractBoundaryPointsOnly ); fixedPointSetReader->Update(); std::cout << " Fixed point-set file: " << fixedPointSetReader->GetFileName() << std::endl; std::cout << " Number of fixed labels: " << fixedPointSetReader->GetLabelSet()->size() << std::endl; std::cout << " Distinct fixed labels: "; for ( unsigned int n = 0; n < fixedPointSetReader->GetLabelSet()->size(); n++ ) { std::cout << fixedPointSetReader->GetLabelSet()->operator[]( n ) << " "; } std::cout << std::endl; movingPointSetReader->SetRandomPercentage( pointSetPercent ); movingPointSetReader->SetExtractBoundaryPoints( extractBoundaryPointsOnly ); movingPointSetReader->Update(); movingPointSetReader->SetRandomPercentage( pointSetPercent ); movingPointSetReader->SetExtractBoundaryPoints( extractBoundaryPointsOnly ); movingPointSetReader->Update(); std::cout << " Moving point-set file: " << movingPointSetReader->GetFileName() << std::endl; std::cout << " Number of moving labels: " << movingPointSetReader->GetLabelSet()->size() << std::endl; std::cout << " Distinct moving labels: "; for ( unsigned int n = 0; n < movingPointSetReader->GetLabelSet()->size(); n++ ) { std::cout << movingPointSetReader->GetLabelSet()->operator[]( n ) << " "; } std::cout << std::endl; if ( whichMetric == "point-set-expectation" || whichMetric == "PointSetExpectation" || whichMetric == "PSE" ) { typedef itk::ExpectationBasedPointSetRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetRadius( radius ); metric->SetFixedPointSet( fixedPointSetReader->GetOutput() ); metric->SetMovingPointSet( movingPointSetReader->GetOutput() ); metric->SetFixedPointSetSigma( pointSetSigma ); metric->SetMovingPointSetSigma( pointSetSigma ); metric->SetKNeighborhood( kNeighborhood ); if ( option->GetNumberOfParameters( i ) > parameterCount ) { unsigned int pm = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); metric->SetUseSymmetricMatching( pm ); std::cout << " Symmetric match iterations -- going Asymmeric for the rest " << pm << std::endl; parameterCount++; } similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); similarityMetric->SetFixedPointSet( fixedPointSetReader->GetOutput() ); similarityMetric->SetMovingPointSet(movingPointSetReader->GetOutput() ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else if ( whichMetric == "jensen-tsallis-bspline" || whichMetric == "JensenTsallisBSpline" || whichMetric == "JTB" ) { typedef itk::JensenTsallisBSplineRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetRadius( radius ); metric->SetFixedPointSet( fixedPointSetReader->GetOutput() ); metric->SetMovingPointSet( movingPointSetReader->GetOutput() ); metric->SetFixedPointSetSigma( pointSetSigma ); metric->SetMovingPointSetSigma( pointSetSigma ); metric->SetFixedEvaluationKNeighborhood( kNeighborhood ); metric->SetMovingEvaluationKNeighborhood( kNeighborhood ); if ( option->GetNumberOfParameters( i ) > parameterCount ) { metric->SetAlpha( this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { typename RegistrationOptimizerType::ArrayType meshResolution; std::vector resolution = this->m_Parser->template ConvertVector( option->GetParameter( i, parameterCount ) ); if ( resolution.size() != TDimension ) { itkExceptionMacro( "Mesh resolution does not match image dimension." ); } for ( unsigned int d = 0; d < TDimension; d++ ) { meshResolution[d] = resolution[d]; } metric->SetMeshResolution( meshResolution ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { metric->SetSplineOrder( this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { metric->SetNumberOfLevels( this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ) ); parameterCount++; } if ( option->GetNumberOfParameters( i ) > parameterCount ) { metric->SetUseAnisotropicCovariances( this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ) ); parameterCount++; } std::cout << " B-spline parameters " << std::endl; std::cout << " mesh resolution: " << metric->GetMeshResolution() << std::endl; std::cout << " spline order: " << metric->GetSplineOrder() << std::endl; std::cout << " number of levels: " << metric->GetNumberOfLevels() << std::endl; std::cout << " Alpha: " << metric->GetAlpha() << std::endl; if ( metric->GetUseAnisotropicCovariances() ) { std::cout << " using anisotropic covariances." << std::endl; } similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); similarityMetric->SetFixedPointSet( fixedPointSetReader->GetOutput() ); similarityMetric->SetMovingPointSet( movingPointSetReader->GetOutput() ); this->m_SimilarityMetrics.push_back( similarityMetric ); } } else // similarity metric is image-based { std::cout << "Metric " << i << ": " << " Not a Point-set" << std::endl; std::cout << " Fixed image file: " << fixedImageFileReader->GetFileName() << std::endl; std::cout << " Moving image file: " << movingImageFileReader->GetFileName() << std::endl; similarityMetric->SetFixedPointSet( NULL); similarityMetric->SetMovingPointSet( NULL ); if ( option->GetNumberOfParameters( i ) > parameterCount ) { similarityMetricScalarWeight = this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); parameterCount++; } similarityMetric->SetWeightScalar( similarityMetricScalarWeight ); std::cout << " similarity metric weight: " << similarityMetricScalarWeight << std::endl; typename SimilarityMetricType::RadiusType radius; radius.Fill( 0 ); if ( option->GetNumberOfParameters( i ) > parameterCount ) { std::vector rad = this->m_Parser->template ConvertVector( option->GetParameter( i, parameterCount ) ); if( rad.size() == 1 ) { radius.Fill( rad[0] ); } else if( rad.size() == TDimension ) { for( unsigned int n = 0; n < TDimension; n++ ) { radius[n] = rad[n]; } } else { std::cerr << "Badly formed radius specification" << std::endl; exit( 0 ); } parameterCount++; } std::cout << " Radius: " << radius << std::endl; float extraparam= -1.e12; if ( option->GetNumberOfParameters( i ) > parameterCount ) { extraparam=this->m_Parser->template Convert( option->GetParameter( i, parameterCount ) ); std::cout <<" Setting Extra Param to : " << extraparam << " often used as a robustness parameter for longitudinal studies " << std::endl; parameterCount++; } std::cout << " Radius: " << radius << std::endl; unsigned int numberOfHistogramBins = 64; if ( Dimension == 2 ) { numberOfHistogramBins = 32; } if ( whichMetric == "mean-squares" || whichMetric == "MeanSquares" || whichMetric == "MSQ" ) { typedef itk::HistogramMatchingImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(movingImage ); filter->SetReferenceImage(fixedImage); filter->SetNumberOfHistogramLevels( 256 ); filter->SetNumberOfMatchPoints( 12 ); filter->ThresholdAtMeanIntensityOn(); // filter->ThresholdAtMeanIntensityOff(); if (useHistMatch){ filter->Update(); std::cout << " use Histogram Matching " << std::endl; movingImage=filter->GetOutput(); movingImage = this->PreprocessImage(movingImage); similarityMetric->SetMovingImage( movingImage );} typedef SyNDemonsRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); if ( radius[0] > 0) metric->SetUseMovingImageGradient( true ); metric->SetIntensityDifferenceThreshold( extraparam ); metric->SetRobustnessParameter( extraparam ); // metric->SetRobust( true ); // metric->SetSymmetric( false ); /// metric->SetNormalizeGradient( false ); metric->SetRadius( radius ); similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else if ( whichMetric == "mutual-information" || whichMetric == "MutualInformation" || whichMetric == "MI" ) { typedef itk::AvantsMutualInformationRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetNumberOfHistogramBins( numberOfHistogramBins ); metric->SetNormalizeGradient( false ); metric->SetRobustnessParameter( extraparam ); unsigned int histbins=radius[0]; if (histbins < 8) histbins=8; metric->SetNumberOfHistogramBins(histbins); radius.Fill(0); metric->SetRadius( radius ); similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else if ( whichMetric == "spatial-mutual-information" || whichMetric == "SpatialMutualInformation" || whichMetric == "SMI" ) { typedef itk::SpatialMutualInformationRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetNumberOfHistogramBins( numberOfHistogramBins ); metric->SetNormalizeGradient( false ); metric->SetRobustnessParameter( extraparam ); unsigned int histbins=radius[0]; if (histbins < 8) histbins=8; metric->SetNumberOfHistogramBins(histbins); radius.Fill(0); metric->SetRadius( radius ); similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else if ( whichMetric == "cross-correlation" || whichMetric == "CrossCorrelation" || whichMetric == "CC" ) { typedef itk::HistogramMatchingImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(movingImage ); filter->SetReferenceImage(fixedImage); filter->SetNumberOfHistogramLevels( 256 ); filter->SetNumberOfMatchPoints( 12 ); filter->ThresholdAtMeanIntensityOn(); // filter->ThresholdAtMeanIntensityOff(); if (useHistMatch){ filter->Update(); std::cout << " use Histogram Matching " << std::endl; movingImage=filter->GetOutput(); movingImage = this->PreprocessImage(movingImage); similarityMetric->SetMovingImage( movingImage );} typedef itk::CrossCorrelationRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetNormalizeGradient( false ); metric->SetRadius( radius ); metric->SetRobustnessParameter( extraparam ); similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else if ( whichMetric == "probabilistic" || whichMetric == "Probabilistic" || whichMetric == "PR" ) { typedef itk::HistogramMatchingImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput(movingImage ); filter->SetReferenceImage(fixedImage); filter->SetNumberOfHistogramLevels( 256 ); filter->SetNumberOfMatchPoints( 12 ); filter->ThresholdAtMeanIntensityOn(); // filter->ThresholdAtMeanIntensityOff(); if (useHistMatch){ filter->Update(); std::cout << " use Histogram Matching " << std::endl; movingImage=filter->GetOutput(); movingImage = this->PreprocessImage(movingImage); similarityMetric->SetMovingImage( movingImage );} typedef itk::ProbabilisticRegistrationFunction MetricType; typename MetricType::Pointer metric = MetricType::New(); metric->SetNormalizeGradient( false ); metric->SetRadius( radius ); metric->SetRobustnessParameter( extraparam ); similarityMetric->SetMetric( metric ); similarityMetric->SetMaximizeMetric( true ); this->m_SimilarityMetrics.push_back( similarityMetric ); } else { itkWarningMacro( "Could not decipher image metric choice: " << whichMetric ); } } } } else { itkExceptionMacro( "No image metric specified on the command line." ); } } template void PICSLAdvancedNormalizationToolKit ::InitializeCommandLineOptions() { this->m_Parser = ParserType::New(); // this->m_Parser->SetCommandDescription( " PICSL Advanced Image Normalization Toolkit" ); if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "weight-image" ); option->SetShortName( 'w' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (true) { std::string description = std::string( "this mask -- defined in the 'fixed' image space defines " ) + std::string( "the region of interest over which the registration is " ) + std::string( "computed ==> above 0.1 means inside mask ==> continuous " ) + std::string( "values in range [0.1,1.0] effect optimization like a " ) + std::string( "probability. ==> values > 1 are treated as = 1.0 " ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "mask-image" ); option->SetShortName( 'x' ); // option->SetDescription( "this mask -- defined in the 'fixed' image space defines the region of interest over which the registration is computed ==> above 0.1 means inside mask \n\t\t==> continuous values in range [0.1 , 1.0] effect optimization like a probability. \n\t\t==> values > 1 are treated as = 1.0 " ); option->SetDescription( description ); option->SetUsageOption( 0, "maskFileName" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "mask-threshold" ); option->SetShortName( 'M' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "image-metric" ); option->SetShortName( 'm' ); std::string newLineTabs( "\n\t\t" ); std::string intensityBasedDescription( "Intensity-Based Metrics: " ); std::string intensityBasedOptions( "[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]" ); std::string ccDescription( "CC/cross-correlation/CrossCorrelation" ); std::string miDescription( "MI/mutual-information/MutualInformation" ); std::string smiDescription( "SMI/spatial-mutual-information/SpatialMutualInformation" ); std::string prDescription( "PR/probabilistic/Probabilistic" ); std::string msqDescription( "MSQ/mean-squares/MeanSquares -- radius > 0 uses moving image gradient in metric deriv." ); intensityBasedDescription += ( newLineTabs + ccDescription + intensityBasedOptions + newLineTabs + miDescription + intensityBasedOptions + newLineTabs + smiDescription + intensityBasedOptions + newLineTabs + prDescription + intensityBasedOptions + newLineTabs + msqDescription + intensityBasedOptions ); std::string pointBasedDescription( "\n\t Point-Set-Based Metrics: " ); std::string pointBasedOptions = std::string( "[fixedImage,movingImage,fixedPoints,movingPoints" ) + std::string( ",weight,pointSetPercentage,pointSetSigma,boundaryPointsOnly" ) + std::string( ",kNeighborhood" ); std::string pseDescription( "PSE/point-set-expectation/PointSetExpectation" ); std::string pseOptions(", PartialMatchingIterations=100000] \n the partial matching option assumes the complete labeling is in the first set of label parameters ... more iterations leads to more symmetry in the matching - 0 iterations means full asymmetry " ); std::string jtbDescription( "JTB/jensen-tsallis-bspline/JensenTsallisBSpline" ); std::string jtbOptions = std::string( ",alpha,meshResolution,splineOrder,numberOfLevels" ) + std::string( ",useAnisotropicCovariances]" ); pointBasedDescription += ( newLineTabs + pseDescription + pointBasedOptions + pseOptions + newLineTabs + jtbDescription + pointBasedOptions + jtbOptions ); std::string description = intensityBasedDescription + pointBasedDescription; option->SetDescription( description ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "output-naming" ); option->SetShortName( 'o' ); option->SetDescription( "The name for the output - a prefix or a name+type : e.g. -o OUT or -o OUT.nii or -o OUT.mha " ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "roi" ); option->SetLongName( "R" ); option->SetDescription( "TODO/FIXME: the --R sets an ROI option -- it passes a vector of parameters that sets the center and bounding box \n of the region of interest for a sub-field registration. e.g. in 3D the option setting \n -r 10x12x15x50x50x25 \n sets up a bounding box of size 50,50,25 with origin at 10,12,15 in voxel (should this be physical?) coordinates. " ); std::string roidefault=std::string("0"); /** set up a default parameter */ option->AddValue(roidefault); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "number-of-levels" ); option->SetShortName( 'n' ); option->SetDescription( "number of levels in multi-resolution optimization -- an integer :: 3 is a common choice " ); std::string nlevdefault=std::string("3"); /** set up a default parameter */ option->AddValue(nlevdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "number-of-iterations" ); option->SetShortName( 'i' ); option->SetDescription( "number of iterations per level -- a 'vector' e.g. : 100x100x20 " ); std::string nitdefault=std::string("10x10x5"); /** set up a default parameter */ option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "Restrict-Deformation" ); option->SetDescription( "restrict the gradient that drives the deformation by scalar factors along specified dimensions -- a float 'vector' of length ImageDimension to multiply against the similarity metric's gradient values --- e.g. in 3D : 0.1x1x0 --- will set the z gradient to zero and scale the x gradient by 0.1 and y by 1 (no change). Thus, you get a 2.5-Dimensional registration as there is still 3D continuity in the mapping. " ); std::string nitdefault; if (TDimension == 2) nitdefault=std::string("1x1"); if (TDimension == 3) nitdefault=std::string("1x1x1"); /** set up a default parameter */ option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "number-to-interpolate" ); option->SetShortName( 'b' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-converge-criteria" ); option->SetShortName( 'a' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "thickness-limit" ); option->SetShortName( 'T' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "prior-image-list" ); option->SetShortName( 'P' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-laplacian" ); option->SetShortName( 'i' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (false) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-histogram-matching" ); option->SetShortName( 'e' ); option->SetDescription( "blah-blah" ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "verbose" ); option->SetShortName( 'v' ); option->SetDescription( " verbose output " ); this->m_Parser->AddOption( option ); } if( true ) { std::string description = std::string( "Print the help menu (short version)." ); OptionType::Pointer option = OptionType::New(); option->SetShortName( 'h' ); option->SetDescription( description ); std::string zero = std::string( "0" ); option->AddValue( zero ); this->m_Parser->AddOption( option ); } if( true ) { std::string description = std::string( "Print the help menu." ); OptionType::Pointer option = OptionType::New(); option->SetLongName( "help" ); option->SetDescription( description ); std::string zero = std::string( "0" ); option->AddValue( zero ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "transformation-model" ); option->SetShortName( 't' ); option->SetDescription( "TRANSFORMATION[gradient-step-length,number-of-time-steps,DeltaTime,symmetry-type].\n\t Choose one of the following TRANSFORMATIONS:\n\t\tDiff = diffeomorphic\n\t\tElast = Elastic\n\t\tExp = exponential diff\n\t\t Greedy Exp = greedy exponential diff, like diffeomorphic demons. same parameters. \n\t\tSyN -- symmetric normalization \n \n DeltaTime is the integration time-discretization step - sub-voxel - n-time steps currently fixed at 2 " ); std::string nitdefault=std::string("SyN[0.5]"); /** set up a default parameter */ option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } // if (true) // { // OptionType::Pointer option = OptionType::New(); // option->SetLongName( "def-field-sigma" ); // option->SetShortName( 's' ); // option->SetDescription( "smoothing of deformation field " ); // // this->m_Parser->AddOption( option ); // } // // if (true) // { // OptionType::Pointer option = OptionType::New(); // option->SetLongName( "gradient-field-sigma" ); // option->SetShortName( 'g' ); // option->SetDescription( "this smooths the gradient update field" ); // option->AddValue("0.0"); // this->m_Parser->AddOption( option ); // } // // if (true) // { // OptionType::Pointer option = OptionType::New(); // option->SetLongName( "gradient-step-length" ); // option->SetShortName( 'l' ); // option->SetDescription( "gradient descent parameter - a float :: e.g. 1.0 " ); // option->AddValue("1.0"); // this->m_Parser->AddOption( option ); // } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "regularization" ); option->SetShortName( 'r' ); option->SetDescription( "REGULARIZATION[gradient-field-sigma,def-field-sigma,truncation].\n\t Choose one of the following REGULARIZATIONS:\n\t\tGauss = gaussian\n\t\tDMFFD = directly manipulated free form deformation" ); std::string nitdefault=std::string("Gauss[3,0.5]"); /** set up a default parameter */ option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } //added by songgang if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "initial-affine" ); option->SetShortName( 'a' ); option->SetDescription( "use the input file as the initial affine parameter" ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "fixed-image-initial-affine" ); option->SetShortName( 'F' ); option->SetDescription( "use the input file as the initial affine parameter for the fixed image " ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "geodesic" ); option->SetShortName( 'T' ); option->SetDescription( " = 0 / 1 / 2, 0 = not time-dependent, 1 = asymmetric , 2 = symmetric "); // compute the Euclidean length of the diffeomorphism and write to an image -- OutputNamethick.nii.gz -- This is a Beta version of thickness computation -- Not Full-Blown DiReCT , Das, 2009, Neuroimage --- syn with time is the only model that can be used with this option " ); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "go-faster" ); option->SetShortName( 'G' ); option->SetDescription( " true / false -- if true, SyN is faster but loses some accuracy wrt inverse-identity constraint, see Avants MIA 2008."); std::string nitdefault=std::string("false"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } //added by songgang if (true){ OptionType::Pointer option = OptionType::New(); option->SetLongName( "continue-affine"); option->SetDescription( "true (default) | false, do (not) perform affine given the initial affine parameters"); std::string nitdefault=std::string("true"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } //added by songgang if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "number-of-affine-iterations" ); option->SetDescription( "number of iterations per level -- a 'vector' e.g. : 100x100x20 " ); std::string nitdefault=std::string("10000x10000x10000"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-NN" ); option->SetDescription( "use nearest neighbor interpolation " ); std::string nitdefault=std::string("0"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-Histogram-Matching" ); option->SetDescription( "use histogram matching of moving to fixed image " ); std::string nitdefault=std::string("0"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "affine-metric-type" ); option->SetDescription( "MI: mutual information (default), MSQ: mean square error, CC: Normalized correlation, CCH: Histogram-based correlation coefficient (not recommended), GD: gradient difference (not recommended) " ); std::string nitdefault=std::string("MI"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "MI-option" ); option->SetDescription( "option of mutual information: MI_bins x MI_samples (default: 32x32000)" ); switch(TDimension){ case 2: option->AddValue(std::string("32x5000")); break; case 3: option->AddValue(std::string("32x32000")); break; } //std::string nitdefault=std::string("32x8000"); // option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "rigid-affine" ); option->SetDescription( "use rigid transformation : true / false(default)" ); std::string nitdefault=std::string("false"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "do-rigid" ); option->SetDescription( "use rigid transformation : true / false(default)" ); std::string nitdefault=std::string("false"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "affine-gradient-descent-option" ); option->SetDescription( "option of gradient descent in affine transformation: maximum_step_length x relaxation_factor x minimum_step_length x translation_scales "); std::string nitdefault=std::string("0.1x0.5x1.e-4x1.e-4"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "use-rotation-header" ); option->SetDescription( "use rotation matrix in image headers: true (default) / false" ); std::string nitdefault=std::string("false"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } if (true) { OptionType::Pointer option = OptionType::New(); option->SetLongName( "ignore-void-origin" ); option->SetDescription( "ignore the apparently unmatched origins (when use-rotation-header is false and the rotation matrix is identity: true (default) / false" ); std::string nitdefault=std::string("false"); option->AddValue(nitdefault); this->m_Parser->AddOption( option ); } } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkProbabilisticRegistrationFunction.cxx000066400000000000000000000670621147325206600302330ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkProbabilisticRegistrationFunction.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkProbabilisticRegistrationFunction_txx_ #define _itkProbabilisticRegistrationFunction_txx_ #include "itkProbabilisticRegistrationFunction.h" #include "itkExceptionObject.h" #include "vnl/vnl_math.h" #include "itkImageFileWriter.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkMeanImageFilter.h" #include "itkMedianImageFilter.h" #include "itkImageFileWriter.h" #include namespace itk { /* * Default constructor */ template ProbabilisticRegistrationFunction ::ProbabilisticRegistrationFunction() { m_AvgMag=0; m_Iteration=0; RadiusType r; unsigned int j; for( j = 0; j < ImageDimension; j++ ) { r[j] = 2; } this->SetRadius(r); this->m_Energy = 0.0; m_TimeStep = 1.0; m_DenominatorThreshold = 1e-9; m_IntensityDifferenceThreshold = 0.001; Superclass::m_MovingImage = NULL; m_MetricGradientImage = NULL; Superclass::m_FixedImage = NULL; m_FixedImageSpacing.Fill( 1.0 ); m_FixedImageOrigin.Fill( 0.0 ); m_FixedImageGradientCalculator = GradientCalculatorType::New(); binaryimage=NULL; m_FullyRobust=false; m_MovingImageGradientCalculator = GradientCalculatorType::New(); typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_MovingImageInterpolator = static_cast( interp.GetPointer() ); for (int i=0; i<5; i++) finitediffimages[i]=NULL; m_NumberOfHistogramBins=32; m_FixedImageMask=NULL; m_MovingImageMask=NULL; } /* * Standard "PrintSelf" method. */ template void ProbabilisticRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); /* os << indent << "MovingImageIterpolator: "; os << m_MovingImageInterpolator.GetPointer() << std::endl; os << indent << "FixedImageGradientCalculator: "; os << m_FixedImageGradientCalculator.GetPointer() << std::endl; os << indent << "DenominatorThreshold: "; os << m_DenominatorThreshold << std::endl; os << indent << "IntensityDifferenceThreshold: "; os << m_IntensityDifferenceThreshold << std::endl; */ } /* * Set the function state values before each iteration */ template void ProbabilisticRegistrationFunction ::InitializeIteration() { typedef ImageRegionIteratorWithIndex ittype; if( !Superclass::m_MovingImage || !Superclass::m_FixedImage || !m_MovingImageInterpolator ) { itkExceptionMacro( << "MovingImage, FixedImage and/or Interpolator not set" ); throw ExceptionObject(__FILE__,__LINE__); } // cache fixed image information m_FixedImageSpacing = Superclass::m_FixedImage->GetSpacing(); m_FixedImageOrigin = Superclass::m_FixedImage->GetOrigin(); // setup gradient calculator m_FixedImageGradientCalculator->SetInputImage( Superclass::m_FixedImage ); m_MovingImageGradientCalculator->SetInputImage( Superclass::m_MovingImage ); // setup moving image interpolator m_MovingImageInterpolator->SetInputImage( Superclass::m_MovingImage ); unsigned long numpix=1; for (int i=0; iGetLargestPossibleRegion().GetSize()[i]; m_MetricTotal=0.0; this->m_Energy=0.0; typedef itk::DiscreteGaussianImageFilter dgf1; // typedef itk::DiscreteGaussianImageFilter dgf; typedef itk::MeanImageFilter dgf; typedef itk::MedianImageFilter dgf2; // compute the normalizer m_Normalizer = 0.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; } m_Normalizer /= static_cast( ImageDimension ); typename FixedImageType::SpacingType spacing=this->GetFixedImage()->GetSpacing(); bool makeimg=false; if ( m_Iteration==0 ) makeimg=true; else if (!finitediffimages[0] ) makeimg=true; else { for (unsigned int dd=0; ddGetLargestPossibleRegion().GetSize()[dd] != this->GetFixedImage()->GetLargestPossibleRegion().GetSize()[dd] ) makeimg=true; } } if (makeimg) { finitediffimages[0]=this->MakeImage(); finitediffimages[1]=this->MakeImage(); finitediffimages[2]=this->MakeImage(); finitediffimages[3]=this->MakeImage(); finitediffimages[4]=this->MakeImage(); } //float sig=15.; RadiusType r; for( int j = 0; j < ImageDimension; j++ ) r[j] = this->GetRadius()[j]; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator tIter(this->GetFixedImage(),this->GetFixedImage()->GetLargestPossibleRegion() ); typename FixedImageType::SizeType imagesize=this->GetFixedImage()->GetLargestPossibleRegion().GetSize(); // compute local means // typedef itk::ImageRegionIteratorWithIndex Iterator; // // The following change was made to speed up the correlation calculation. // // first round { typedef std::deque SumQueueType; SumQueueType Qsuma2; SumQueueType Qsumb2; SumQueueType Qsuma; SumQueueType Qsumb; SumQueueType Qsumab; SumQueueType Qcount; ImageLinearConstIteratorWithIndex outIter( this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); outIter.SetDirection( 0 ); outIter.GoToBegin(); while( !outIter.IsAtEnd() ) { // Push the zeros onto the stack that are outsized the image boundary at // the beginning of the line. Qsuma2 = SumQueueType( r[0], 0.0 ); Qsumb2 = SumQueueType( r[0], 0.0 ); Qsuma = SumQueueType( r[0], 0.0 ); Qsumb = SumQueueType( r[0], 0.0 ); Qsumab = SumQueueType( r[0], 0.0 ); Qcount = SumQueueType( r[0], 0.0 ); NeighborhoodIterator hoodIt( this->GetRadius(), this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); IndexType oindex = outIter.GetIndex(); hoodIt.SetLocation( oindex ); unsigned int hoodlen = hoodIt.Size(); // Now add the rest of the values from each hyperplane for( unsigned int i = r[0]; i < ( 2*r[0] + 1 ); i++ ) { float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; for( unsigned int indct = i; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->GetFixedImage()->GetPixel( index ); float b = this->GetMovingImage()->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } while( !outIter.IsAtEndOfLine() ) { // Test to see if there are any voxels we need to handle in the current // window. float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; typename SumQueueType::iterator itcount = Qcount.begin(); while( itcount != Qcount.end() ) { count += *itcount; ++itcount; } // If there are values, we need to calculate the different quantities if( count > 0 ) { typename SumQueueType::iterator ita2 = Qsuma2.begin(); typename SumQueueType::iterator itb2 = Qsumb2.begin(); typename SumQueueType::iterator ita = Qsuma.begin(); typename SumQueueType::iterator itb = Qsumb.begin(); typename SumQueueType::iterator itab = Qsumab.begin(); while( ita2 != Qsuma2.end() ) { suma2 += *ita2; sumb2 += *itb2; suma += *ita; sumb += *itb; sumab += *itab; ++ita2; ++itb2; ++ita; ++itb; ++itab; } float fixedMean = suma / count; float movingMean = sumb / count; float sff = suma2 - fixedMean*suma - fixedMean*suma + count*fixedMean*fixedMean; float smm = sumb2 - movingMean*sumb - movingMean*sumb + count*movingMean*movingMean; float sfm = sumab - movingMean*suma - fixedMean*sumb + count*movingMean*fixedMean; IndexType oindex = outIter.GetIndex(); float val = this->GetFixedImage()->GetPixel( oindex ) - fixedMean; this->finitediffimages[0]->SetPixel( oindex, val ); val = this->GetMovingImage()->GetPixel( oindex ) - movingMean; this->finitediffimages[1]->SetPixel( oindex, val ); this->finitediffimages[2]->SetPixel( oindex, sfm );//A this->finitediffimages[3]->SetPixel( oindex, sff );//B this->finitediffimages[4]->SetPixel( oindex, smm );//C } // Increment the iterator and check to see if we're at the end of the // line. If so, go to the next line. Otherwise, add the // the values for the next hyperplane. ++outIter; if( !outIter.IsAtEndOfLine() ) { hoodIt.SetLocation( outIter.GetIndex() ); suma2 = 0.0; sumb2 = 0.0; suma = 0.0; sumb = 0.0; sumab = 0.0; count = 0.0; for( unsigned int indct = 2*r[0]; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->GetFixedImage()->GetPixel( index ); float b = this->GetMovingImage()->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } Qsuma2.pop_front(); Qsumb2.pop_front(); Qsuma.pop_front(); Qsumb.pop_front(); Qsumab.pop_front(); Qcount.pop_front(); } outIter.NextLine(); } } // second round { typedef std::deque SumQueueType; SumQueueType Qsuma2; SumQueueType Qsumb2; SumQueueType Qsuma; SumQueueType Qsumb; SumQueueType Qsumab; SumQueueType Qcount; ImageLinearConstIteratorWithIndex outIter( this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); outIter.SetDirection( 0 ); outIter.GoToBegin(); while( !outIter.IsAtEnd() ) { // Push the zeros onto the stack that are outsized the image boundary at // the beginning of the line. Qsuma2 = SumQueueType( r[0], 0.0 ); Qsumb2 = SumQueueType( r[0], 0.0 ); Qsuma = SumQueueType( r[0], 0.0 ); Qsumb = SumQueueType( r[0], 0.0 ); Qsumab = SumQueueType( r[0], 0.0 ); Qcount = SumQueueType( r[0], 0.0 ); NeighborhoodIterator hoodIt( this->GetRadius(), this->finitediffimages[0], this->finitediffimages[0]->GetLargestPossibleRegion() ); IndexType oindex = outIter.GetIndex(); hoodIt.SetLocation( oindex ); unsigned int hoodlen = hoodIt.Size(); // Now add the rest of the values from each hyperplane for( unsigned int i = r[0]; i < ( 2*r[0] + 1 ); i++ ) { float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; for( unsigned int indct = i; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->finitediffimages[0]->GetPixel( index ); float b = this->finitediffimages[1]->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } while( !outIter.IsAtEndOfLine() ) { // Test to see if there are any voxels we need to handle in the current // window. float suma2 = 0.0; float sumb2 = 0.0; float suma = 0.0; float sumb = 0.0; float sumab = 0.0; float count = 0.0; typename SumQueueType::iterator itcount = Qcount.begin(); while( itcount != Qcount.end() ) { count += *itcount; ++itcount; } // If there are values, we need to calculate the different quantities if( count > 0 ) { typename SumQueueType::iterator ita2 = Qsuma2.begin(); typename SumQueueType::iterator itb2 = Qsumb2.begin(); typename SumQueueType::iterator ita = Qsuma.begin(); typename SumQueueType::iterator itb = Qsumb.begin(); typename SumQueueType::iterator itab = Qsumab.begin(); while( ita2 != Qsuma2.end() ) { suma2 += *ita2; sumb2 += *itb2; suma += *ita; sumb += *itb; sumab += *itab; ++ita2; ++itb2; ++ita; ++itb; ++itab; } float fixedMean = suma / count; float movingMean = sumb / count; float sff = suma2 - fixedMean*suma - fixedMean*suma + count*fixedMean*fixedMean; float smm = sumb2 - movingMean*sumb - movingMean*sumb + count*movingMean*movingMean; float sfm = sumab - movingMean*suma - fixedMean*sumb + count*movingMean*fixedMean; IndexType oindex = outIter.GetIndex(); // float val = this->GetFixedImage()->GetPixel( oindex ) - fixedMean; // this->finitediffimages[0]->SetPixel( oindex, val ); // val = this->GetMovingImage()->GetPixel( oindex ) - movingMean; // this->finitediffimages[1]->SetPixel( oindex, val ); this->finitediffimages[2]->SetPixel( oindex, sfm );//A this->finitediffimages[3]->SetPixel( oindex, sff );//B this->finitediffimages[4]->SetPixel( oindex, smm );//C } // Increment the iterator and check to see if we're at the end of the // line. If so, go to the next line. Otherwise, add the // the values for the next hyperplane. ++outIter; if( !outIter.IsAtEndOfLine() ) { hoodIt.SetLocation( outIter.GetIndex() ); suma2 = 0.0; sumb2 = 0.0; suma = 0.0; sumb = 0.0; sumab = 0.0; count = 0.0; for( unsigned int indct = 2*r[0]; indct < hoodlen; indct += ( 2*r[0] + 1 ) ) { bool isInBounds = true; hoodIt.GetPixel( indct, isInBounds ); IndexType index = hoodIt.GetIndex( indct ); if ( !isInBounds || ( this->m_FixedImageMask && this->m_FixedImageMask->GetPixel( index ) < 0.25 ) ) { continue; } float a = this->finitediffimages[0]->GetPixel( index ); float b = this->finitediffimages[1]->GetPixel( index ); suma2 += a*a; sumb2 += b*b; suma += a; sumb += b; sumab += a*b; count += 1.0; } Qsuma2.push_back( suma2 ); Qsumb2.push_back( sumb2 ); Qsuma.push_back( suma ); Qsumb.push_back( sumb ); Qsumab.push_back( sumab ); Qcount.push_back( count ); } Qsuma2.pop_front(); Qsumb2.pop_front(); Qsuma.pop_front(); Qsumb.pop_front(); Qsumab.pop_front(); Qcount.pop_front(); } outIter.NextLine(); } } m_MaxMag=0.0; m_MinMag=9.e9; m_AvgMag=0.0; m_Iteration++; } /* * Set the function state values before each iteration */ template void ProbabilisticRegistrationFunction ::InitializeIterationOld() { typedef ImageRegionIteratorWithIndex ittype; if( !Superclass::m_MovingImage || !Superclass::m_FixedImage || !m_MovingImageInterpolator ) { itkExceptionMacro( << "MovingImage, FixedImage and/or Interpolator not set" ); throw ExceptionObject(__FILE__,__LINE__); } // cache fixed image information m_FixedImageSpacing = Superclass::m_FixedImage->GetSpacing(); m_FixedImageOrigin = Superclass::m_FixedImage->GetOrigin(); // setup gradient calculator m_FixedImageGradientCalculator->SetInputImage( Superclass::m_FixedImage ); m_MovingImageGradientCalculator->SetInputImage( Superclass::m_MovingImage ); // setup moving image interpolator m_MovingImageInterpolator->SetInputImage( Superclass::m_MovingImage ); unsigned long numpix=1; for (int i=0; iGetLargestPossibleRegion().GetSize()[i]; m_MetricTotal=0.0; this->m_Energy=0.0; typedef itk::DiscreteGaussianImageFilter dgf1; // typedef itk::DiscreteGaussianImageFilter dgf; typedef itk::MeanImageFilter dgf; typedef itk::MedianImageFilter dgf2; // compute the normalizer m_Normalizer = 0.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; } m_Normalizer /= static_cast( ImageDimension ); typename FixedImageType::SpacingType spacing=this->GetFixedImage()->GetSpacing(); bool makeimg=false; if ( m_Iteration==0 ) makeimg=true; else if (!finitediffimages[0] ) makeimg=true; else { for (unsigned int dd=0; ddGetLargestPossibleRegion().GetSize()[dd] != this->GetFixedImage()->GetLargestPossibleRegion().GetSize()[dd] ) makeimg=true; } } if (makeimg) { finitediffimages[0]=this->MakeImage(); finitediffimages[1]=this->MakeImage(); finitediffimages[2]=this->MakeImage(); finitediffimages[3]=this->MakeImage(); finitediffimages[4]=this->MakeImage(); } //float sig=15.; RadiusType r; for( int j = 0; j < ImageDimension; j++ ) r[j] = this->GetRadius()[j]; typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator tIter(this->GetFixedImage(),this->GetFixedImage()->GetLargestPossibleRegion() ); typename FixedImageType::SizeType imagesize=this->GetFixedImage()->GetLargestPossibleRegion().GetSize(); // compute local means // typedef itk::ImageRegionIteratorWithIndex Iterator; Iterator outIter(this->finitediffimages[0],this->finitediffimages[0]->GetLargestPossibleRegion() ); for( outIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter ) { bool takesample = true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( outIter.GetIndex() ) < 0.25 ) takesample=false; if (takesample) { NeighborhoodIterator hoodIt( this->GetRadius() ,this->finitediffimages[0] , this->finitediffimages[0]->GetLargestPossibleRegion()); IndexType oindex = outIter.GetIndex(); hoodIt.SetLocation(oindex); double fixedMean=0; double movingMean=0; PointType mappedPoint; unsigned int indct; unsigned int hoodlen=hoodIt.Size(); // unsigned int inct=0; double sumj=0,sumi=0; unsigned int cter=0; for(indct=0; indct static_cast(imagesize[dd]-1) ) inimage=false; } if (inimage && this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( index ) < 0.25 ) inimage=false; if (inimage) { sumj+=this->GetMovingImage()->GetPixel(index); sumi+=this->GetFixedImage()->GetPixel(index); cter++; } } if (cter > 0) movingMean=sumj/(float)cter; if (cter > 0) fixedMean=sumi/(float)cter; float val = this->GetFixedImage()->GetPixel(oindex) - fixedMean; this->finitediffimages[0]->SetPixel( oindex, val ); val = this->GetMovingImage()->GetPixel(oindex) - movingMean; this->finitediffimages[1]->SetPixel( oindex, val ); } } for( outIter.GoToBegin(); !outIter.IsAtEnd(); ++outIter ) { IndexType oindex = outIter.GetIndex(); bool takesample = true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( oindex ) < 0.25 ) takesample=false; if (takesample) { NeighborhoodIterator hoodIt( this->GetRadius() ,this->finitediffimages[0] , this->finitediffimages[0]->GetLargestPossibleRegion()); hoodIt.SetLocation(oindex); double sff=0.0; double smm=0.0; double sfm=0.0; PointType mappedPoint; unsigned int indct; unsigned int hoodlen=hoodIt.Size(); // unsigned int inct=0; for(indct=0; indct static_cast(imagesize[dd]-1) ) inimage=false; } if (inimage && this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( index ) < 0.25 ) inimage=false; if (inimage) { double fixedValue =(double)this->finitediffimages[0]->GetPixel( index ); double movingValue=(double)this->finitediffimages[1]->GetPixel( index ); // double ofixedValue =(double)this->GetFixedImage()->GetPixel( index ); // double omovingValue=(double)this->GetMovingImage()->GetPixel( index ); sff+=fixedValue*fixedValue; smm+=movingValue*movingValue; sfm+=fixedValue*movingValue; } } this->finitediffimages[2]->SetPixel( oindex, sfm );//A this->finitediffimages[3]->SetPixel( oindex, sff );//B this->finitediffimages[4]->SetPixel( oindex, smm );//C // this->finitediffimages[5]->SetPixel( oindex , sumi);//B*C // this->finitediffimages[6]->SetPixel( oindex , sumj);//B*C } } //m_FixedImageGradientCalculator->SetInputImage(finitediffimages[0]); m_MaxMag=0.0; m_MinMag=9.e9; m_AvgMag=0.0; m_Iteration++; } /* * Compute the ncc metric everywhere */ template typename TDeformationField::PixelType ProbabilisticRegistrationFunction ::ComputeMetricAtPairB(IndexType oindex, typename TDeformationField::PixelType vec) { typename TDeformationField::PixelType deriv; deriv.Fill(0.0); double sff=0.0; double smm=0.0; double sfm=0.0; // double fixedValue; // double movingValue; sff=0.0; smm=0.0; sfm=0.0; PointType mappedPoint; CovariantVectorType gradI,gradJ; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( oindex ) < 0.25 ) return deriv; sfm=finitediffimages[2]->GetPixel(oindex); sff=finitediffimages[3]->GetPixel(oindex); smm=finitediffimages[4]->GetPixel(oindex); if ( sff == 0.0 || smm == 0.0) return deriv; IndexType index=oindex;//hoodIt.GetIndex(indct); // bool inimage=true; if (sff == 0.0) sff=1.0; if (smm == 0.0) smm=1.0; gradI = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); // gradJ = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); float Ji=finitediffimages[1]->GetPixel(index); float Ii=finitediffimages[0]->GetPixel(index); m_TEMP=2.0*sfm/(sff*smm)*( Ji - sfm/sff*Ii ); for (int qq=0; qqm_RobustnessParameter) deriv.Fill(0); // if ( localProbabilistic*(-1.0) < this->m_RobustnessParameter) { // std::cout << " localC " << localProbabilistic << std::endl; } this->m_Energy-=localProbabilistic; return deriv;//localProbabilistic; } /* * Compute the ncc metric everywhere */ template typename TDeformationField::PixelType ProbabilisticRegistrationFunction ::ComputeMetricAtPairC(IndexType oindex, typename TDeformationField::PixelType vec) { typename TDeformationField::PixelType deriv; deriv.Fill(0.0); double sff=0.0; double smm=0.0; double sfm=0.0; // double fixedValue; // double movingValue; sff=0.0; smm=0.0; sfm=0.0; PointType mappedPoint; CovariantVectorType gradI,gradJ; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( oindex ) < 0.25 ) return deriv; sfm=finitediffimages[2]->GetPixel(oindex); sff=finitediffimages[3]->GetPixel(oindex); smm=finitediffimages[4]->GetPixel(oindex); if ( sff == 0.0 || smm == 0.0) return deriv; IndexType index=oindex;//hoodIt.GetIndex(indct); if (sff == 0.0) sff=1.0; if (smm == 0.0) smm=1.0; ///gradI = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); gradJ = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); float Ji=finitediffimages[1]->GetPixel(index); float Ii=finitediffimages[0]->GetPixel(index); for (int qq=0; qqm_RobustnessParameter) deriv.Fill(0); return deriv;//localProbabilistic; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkProbabilisticRegistrationFunction.h000066400000000000000000000344641147325206600276600ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkProbabilisticRegistrationFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkProbabilisticRegistrationFunction_h_ #define _itkProbabilisticRegistrationFunction_h_ #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkPoint.h" #include "itkCovariantVector.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkCentralDifferenceImageFunction.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkAvantsMutualInformationRegistrationFunction.h" namespace itk { /** * \class ProbabilisticRegistrationFunction * * This class encapsulate the PDE which drives the demons registration * algorithm. It is used by ProbabilisticRegistrationFilter to compute the * output deformation field which will map a moving image onto a * a fixed image. * * Non-integer moving image values are obtained by using * interpolation. The default interpolator is of type * LinearInterpolateImageFunction. The user may set other * interpolators via method SetMovingImageInterpolator. Note that the input * interpolator must derive from baseclass InterpolateImageFunction. * * This class is templated over the fixed image type, moving image type, * and the deformation field type. * * \warning This filter assumes that the fixed image type, moving image type * and deformation field type all have the same number of dimensions. * * \sa ProbabilisticRegistrationFilter * \ingroup FiniteDifferenceFunctions */ template class ITK_EXPORT ProbabilisticRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField> { public: /** Standard class typedefs. */ typedef ProbabilisticRegistrationFunction Self; typedef AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( ProbabilisticRegistrationFunction, AvantsPDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::MetricImageType MetricImageType; typedef typename Superclass::MetricImageType::Pointer MetricImagePointer; typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; /** Deformation field type. */ typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; typedef typename TDeformationField::PixelType VectorType; typedef CovariantVector GradientPixelType; typedef Image GradientImageType; typedef SmartPointer GradientImagePointer; typedef GradientRecursiveGaussianImageFilter< MetricImageType,GradientImageType > GradientImageFilterType; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; typedef Image BinaryImageType; typedef typename BinaryImageType::Pointer BinaryImagePointer; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; // typedef typename Superclass::NeighborhoodType BoundaryNeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Interpolator type. */ typedef double CoordRepType; typedef InterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef typename InterpolatorType::PointType PointType; typedef LinearInterpolateImageFunction DefaultInterpolatorType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** Gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Set the moving image interpolator. */ void SetMovingImageInterpolator( InterpolatorType * ptr ) { m_MovingImageInterpolator = ptr; } /** Get the moving image interpolator. */ InterpolatorType * GetMovingImageInterpolator(void) { return m_MovingImageInterpolator; } typename TDeformationField::PixelType ComputeMetricAtPairB(IndexType fixedindex, typename TDeformationField::PixelType vec ); typename TDeformationField::PixelType ComputeMetricAtPairC(IndexType fixedindex, typename TDeformationField::PixelType vec ); /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void *GlobalData) const { return m_TimeStep; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const { delete (GlobalDataStruct *) GlobalData; } /** Set the object's state before each iteration. */ virtual void InitializeIteration(); /** Set the object's state before each iteration. */ void InitializeIterationOld(); double ComputeCrossCorrelation() { if (finitediffimages[0]) { double totalcc=0; unsigned long ct=0; typedef ImageRegionIteratorWithIndex ittype; ittype it(this->finitediffimages[0],this->finitediffimages[0]->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) { IndexType oindex=it.GetIndex(); double sfm=finitediffimages[2]->GetPixel(oindex); double sff=finitediffimages[3]->GetPixel(oindex); double smm=finitediffimages[4]->GetPixel(oindex); double cc=0; if ( fabs(sff*smm) > 0) { cc+=sfm*sfm/(sff*smm); ct++; } totalcc+=cc; } this->m_Energy=totalcc/(float)ct*(-1.0); return this->m_Energy; } else return 0; } virtual VectorType OpticalFlowUpdate(const NeighborhoodType &neighborhood) { // Get fixed image related information IndexType index=neighborhood.GetIndex(); typename TDeformationField::PixelType vec = Superclass::m_DeformationField->GetPixel(index); VectorType update; update.Fill(0.0); double fixedValue; CovariantVectorType fixedGradient; double fixedGradientSquaredMagnitude = 0; fixedValue = (double) Superclass::Superclass::m_FixedImage->GetPixel( index ); fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); for( unsigned int j = 0; j < ImageDimension; j++ ) { fixedGradientSquaredMagnitude += vnl_math_sqr( fixedGradient[j] ); } double movingValue; int j; PointType mappedPoint; for( j = 0; j < ImageDimension; j++ ) { mappedPoint[j] = double( index[j] ) * m_FixedImageSpacing[j] + m_FixedImageOrigin[j]; mappedPoint[j] += vec[j]; } if( m_MovingImageInterpolator->IsInsideBuffer( mappedPoint ) ) { movingValue = m_MovingImageInterpolator->Evaluate( mappedPoint ); } else { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } double speedValue = fixedValue - movingValue; if (fabs(speedValue) < this->m_RobustnessParameter) speedValue=0; double denominator = vnl_math_sqr( speedValue ) / m_Normalizer + fixedGradientSquaredMagnitude; double m_DenominatorThreshold = 1e-9; double m_IntensityDifferenceThreshold = 0.001; if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold || denominator < m_DenominatorThreshold ) { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } for( j = 0; j < ImageDimension; j++ ) { update[j] = speedValue * fixedGradient[j] / denominator; } return update; } void SetFixedImageMask( MetricImageType* img) {m_FixedImageMask=img; } virtual VectorType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); if (!img) return update; update=this->ComputeMetricAtPairB(oindex,update); return update; } virtual VectorType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); if (!img) return update; update=this->ComputeMetricAtPairC(oindex,update); return update; } void SetFullyRobust(bool b){m_FullyRobust=b;} void GetProbabilities(); double localProbabilistic; float m_TEMP; protected: ProbabilisticRegistrationFunction(); ~ProbabilisticRegistrationFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * iterators for the fixed image. */ struct GlobalDataStruct { FixedImageNeighborhoodIteratorType m_FixedImageIterator; }; MetricImagePointer MakeImage() { typedef ImageRegionIteratorWithIndex ittype; typedef ImageRegionIteratorWithIndex ittype2; FixedImageType* img =const_cast(Superclass::m_FixedImage.GetPointer()); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); this->m_MetricImage = MetricImageType::New(); this->m_MetricImage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); this->m_MetricImage->SetBufferedRegion(img->GetLargestPossibleRegion()); this->m_MetricImage->SetSpacing(img->GetSpacing()); this->m_MetricImage->SetOrigin(img->GetOrigin()); this->m_MetricImage->Allocate(); this->m_MetricImage->FillBuffer(0); bool makebinimg=false; if (makebinimg) { m_Iteration=0; binaryimage = BinaryImageType::New(); binaryimage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); binaryimage->SetBufferedRegion(img->GetLargestPossibleRegion()); binaryimage->SetSpacing(img->GetSpacing()); binaryimage->SetOrigin(img->GetOrigin()); binaryimage->Allocate(); ittype2 it(binaryimage,binaryimage->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) it.Set(1); } return this->m_MetricImage; } private: ProbabilisticRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Cache fixed image information. */ typename TFixedImage::SpacingType m_FixedImageSpacing; typename TFixedImage::PointType m_FixedImageOrigin; /** Function to compute derivatives of the fixed image. */ GradientCalculatorPointer m_FixedImageGradientCalculator; GradientCalculatorPointer m_MovingImageGradientCalculator; /** Function to interpolate the moving image. */ InterpolatorPointer m_MovingImageInterpolator; /** The global timestep. */ TimeStepType m_TimeStep; /** Threshold below which the denominator term is considered zero. */ double m_DenominatorThreshold; /** Threshold below which two intensity value are assumed to match. */ double m_IntensityDifferenceThreshold; mutable double m_MetricTotal; mutable float m_MinMag; mutable float m_MaxMag; mutable float m_AvgMag; mutable float m_Thresh; GradientImagePointer m_MetricGradientImage; MetricImagePointer finitediffimages[5]; BinaryImagePointer binaryimage; MetricImagePointer m_FixedImageMask; MetricImagePointer m_MovingImageMask; typedef itk::AvantsMutualInformationRegistrationFunction MetricType2; typename MetricType2::Pointer m_MIFunct; unsigned int m_NumberOfHistogramBins; bool m_FullyRobust; unsigned int m_Iteration; float m_Normalizer; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkProbabilisticRegistrationFunction.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkSpatialMutualInformationRegistrationFunction.cxx000077500000000000000000001037451147325206600324420ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkSpatialMutualInformationRegistrationFunction.cxx,v $ Language: C++ Date: $Date: 2009/01/08 15:14:48 $ Version: $Revision: 1.21 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkSpatialMutualInformationRegistrationFunction_txx #define _itkSpatialMutualInformationRegistrationFunction_txx #include "itkSpatialMutualInformationRegistrationFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkCovariantVector.h" #include "itkImageRandomConstIteratorWithIndex.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionIterator.h" #include "itkImageIterator.h" #include "vnl/vnl_math.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkBSplineDeformableTransform.h" #include "itkImageRegionConstIteratorWithIndex.h" namespace itk { /** * Constructor */ template < class TFixedImage, class TMovingImage , class TDeformationField > SpatialMutualInformationRegistrationFunction ::SpatialMutualInformationRegistrationFunction() { this-> Superclass::m_NormalizeGradient=true; this->m_NumberOfSpatialSamples = 5000; this->m_NumberOfHistogramBins = 50; // this->SetComputeGradient(false); // don't use the default gradient for now this->m_InterpolatorIsBSpline = false; this->m_TransformIsBSpline = false; // Initialize PDFs to NULL m_JointPDF = NULL; m_OpticalFlow=false; typename TransformType::Pointer transformer = TransformType::New(); this->SetTransform(transformer); typename BSplineInterpolatorType::Pointer interpolator = BSplineInterpolatorType::New(); this->SetInterpolator (interpolator); m_FixedImageMask=NULL; m_MovingImageMask=NULL; // Initialize memory m_MovingImageNormalizedMin = 0.0; m_FixedImageNormalizedMin = 0.0; m_MovingImageTrueMin = 0.0; m_MovingImageTrueMax = 0.0; m_FixedImageBinSize = 0.0; m_MovingImageBinSize = 0.0; m_BSplineInterpolator = NULL; m_NumParametersPerDim = 0; m_NumBSplineWeights = 0; m_BSplineTransform = NULL; m_NumberOfParameters = ImageDimension; m_FixedImageGradientCalculator = GradientCalculatorType::New(); m_MovingImageGradientCalculator = GradientCalculatorType::New(); this->m_Padding=0; typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); typename DefaultInterpolatorType::Pointer interp2 = DefaultInterpolatorType::New(); m_MovingImageInterpolator = static_cast( interp.GetPointer() ); m_FixedImageInterpolator = static_cast( interp2.GetPointer() ); m_Interpolator = static_cast( interp.GetPointer() ); this->m_RobustnessParameter=-1.e19; } /** * Print out internal information about this class */ template < class TFixedImage, class TMovingImage , class TDeformationField> void SpatialMutualInformationRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "NumberOfSpatialSamples: "; os << m_NumberOfSpatialSamples << std::endl; os << indent << "NumberOfHistogramBins: "; os << m_NumberOfHistogramBins << std::endl; // Debugging information os << indent << "NumberOfParameters: "; os << m_NumberOfParameters << std::endl; os << indent << "FixedImageNormalizedMin: "; os << m_FixedImageNormalizedMin << std::endl; os << indent << "MovingImageNormalizedMin: "; os << m_MovingImageNormalizedMin << std::endl; os << indent << "MovingImageTrueMin: "; os << m_MovingImageTrueMin << std::endl; os << indent << "MovingImageTrueMax: "; os << m_MovingImageTrueMax << std::endl; os << indent << "FixedImageBinSize: "; os << m_FixedImageBinSize << std::endl; os << indent << "MovingImageBinSize: "; os << m_MovingImageBinSize << std::endl; os << indent << "InterpolatorIsBSpline: "; os << m_InterpolatorIsBSpline << std::endl; os << indent << "TransformIsBSpline: "; os << m_TransformIsBSpline << std::endl; } /** * Initialize */ template void SpatialMutualInformationRegistrationFunction ::InitializeIteration() { m_CubicBSplineKernel = CubicBSplineFunctionType::New(); this->m_Energy=0; this->pdfinterpolator = pdfintType::New(); this->pdfinterpolatorXuY = pdfintType::New(); this->pdfinterpolatorXYu = pdfintType::New(); this->pdfinterpolatorXlY = pdfintType::New(); this->pdfinterpolatorXYl = pdfintType::New(); this->pdfinterpolatorXuYl = pdfintType::New(); this->pdfinterpolatorXlYu = pdfintType::New(); this->pdfinterpolatorXuYr = pdfintType::New(); this->pdfinterpolatorXrYu = pdfintType::New(); pdfinterpolator2 = pdfintType2::New(); pdfinterpolator3 = pdfintType2::New(); // this->ComputeMetricImage(); // std::cout << " A " << std::endl; // bool makenewimage=false; typedef ImageRegionIteratorWithIndex ittype; TFixedImage* img =const_cast(this->m_FixedImage.GetPointer()); typename TFixedImage::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); // std::cout << " B " << std::endl; /* if (!this->m_MetricImage )makenewimage=true; else if (imagesize[0] != this->m_MetricImage->GetLargestPossibleRegion().GetSize()[0]) makenewimage = true; else this->m_MetricImage->FillBuffer(0); if (makenewimage) { this->m_MetricImage = TFixedImage::New(); this->m_MetricImage->SetLargestPossibleRegion(img->GetLargestPossibleRegion() ); this->m_MetricImage->SetBufferedRegion(img->GetLargestPossibleRegion()); this->m_MetricImage->SetSpacing(img->GetSpacing()); this->m_MetricImage->SetOrigin(img->GetOrigin()); this->m_MetricImage->Allocate(); ittype it(this->m_MetricImage,this->m_MetricImage->GetLargestPossibleRegion().GetSize()); for( it.GoToBegin(); !it.IsAtEnd(); ++it ) it.Set(0); } */ m_FixedImageGradientCalculator->SetInputImage( this->m_FixedImage ); m_MovingImageGradientCalculator->SetInputImage( this->m_MovingImage ); m_FixedImageInterpolator->SetInputImage( this->m_FixedImage ); m_Interpolator->SetInputImage( this->m_MovingImage ); m_FixedImageSpacing = this->m_FixedImage->GetSpacing(); m_FixedImageOrigin = this->m_FixedImage->GetOrigin(); m_Normalizer = 0.0; m_NumberOfSpatialSamples = 1; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; m_NumberOfSpatialSamples *= this->m_FixedImage->GetLargestPossibleRegion().GetSize()[k]; } m_Normalizer /= static_cast( ImageDimension ); /** * Compute binsize for the histograms. * * The binsize for the image intensities needs to be adjusted so that * we can avoid dealing with boundary conditions using the cubic * spline as the Parzen window. We do this by increasing the size * of the bins so that the joint histogram becomes "padded" at the * borders. Because we are changing the binsize, * we also need to shift the minimum by the padded amount in order to * avoid minimum values filling in our padded region. * * Note that there can still be non-zero bin values in the padded region, * it's just that these bins will never be a central bin for the Parzen * window. * double fixedImageMax = 1.0; double fixedImageMin = 0.0; double movingImageMax = 1.0; double movingImageMin = 0.0; m_MovingImageTrueMin = movingImageMin; m_MovingImageTrueMax = movingImageMax; */ double movingImageMin = NumericTraits::max(); double movingImageMax = NumericTraits::NonpositiveMin(); double fixedImageMin = NumericTraits::max(); double fixedImageMax = NumericTraits::NonpositiveMin(); typedef ImageRegionConstIterator MovingIteratorType; MovingIteratorType movingImageIterator( this->m_MovingImage, this->m_MovingImage->GetBufferedRegion() ); for ( movingImageIterator.GoToBegin(); !movingImageIterator.IsAtEnd(); ++movingImageIterator) { bool takesample = true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( movingImageIterator.GetIndex() ) < 1.e-6 ) takesample=false; if (takesample) { double sample = static_cast( movingImageIterator.Get() ); double fsample = static_cast( this->m_FixedImage->GetPixel( movingImageIterator.GetIndex() )); if ( sample < movingImageMin ) { movingImageMin = sample; } if ( sample > movingImageMax ) { movingImageMax = sample; } if ( fsample < fixedImageMin ) { fixedImageMin = fsample; } if ( fsample > fixedImageMax ) { fixedImageMax = fsample; } } } this->m_MovingImageTrueMax=movingImageMax; this->m_FixedImageTrueMax=fixedImageMax; this->m_MovingImageTrueMin=movingImageMin; this->m_FixedImageTrueMin=fixedImageMin; fixedImageMax=1.*( fixedImageMax - fixedImageMin )+fixedImageMin; movingImageMax=1.*( movingImageMax - movingImageMin )+movingImageMin; m_FixedImageBinSize = ( fixedImageMax - fixedImageMin ) / static_cast( m_NumberOfHistogramBins - 2 * this->m_Padding ); m_FixedImageNormalizedMin = fixedImageMin / m_FixedImageBinSize - static_cast( this->m_Padding ); m_MovingImageBinSize = ( movingImageMax - movingImageMin ) / static_cast( m_NumberOfHistogramBins - 2 * this->m_Padding ); m_MovingImageNormalizedMin = movingImageMin / m_MovingImageBinSize - static_cast( this->m_Padding ); m_FixedImageMarginalPDF = MarginalPDFType::New(); m_MovingImageMarginalPDF = MarginalPDFType::New(); typename MarginalPDFType::RegionType mPDFRegion; typename MarginalPDFType::SizeType mPDFSize; typename MarginalPDFType::IndexType mPDFIndex; typename MarginalPDFType::SpacingType mPDFspacing; mPDFspacing.Fill(1); mPDFIndex.Fill( 0 ); mPDFSize.Fill( m_NumberOfHistogramBins ); mPDFRegion.SetIndex( mPDFIndex ); mPDFRegion.SetSize( mPDFSize ); m_FixedImageMarginalPDF->SetRegions( mPDFRegion ); m_FixedImageMarginalPDF->Allocate(); m_FixedImageMarginalPDF->SetSpacing(mPDFspacing); m_MovingImageMarginalPDF->SetRegions( mPDFRegion ); m_MovingImageMarginalPDF->Allocate(); m_MovingImageMarginalPDF->SetSpacing(mPDFspacing); // std::cout << " C " << std::endl; /** * Allocate memory for the joint PDF and joint PDF derivatives. * The joint PDF and joint PDF derivatives are store as itk::Image. */ this->m_JointPDF = JointPDFType::New(); this->m_JointPDFXuY = JointPDFType::New(); this->m_JointPDFXYu = JointPDFType::New(); this->m_JointPDFXlY = JointPDFType::New(); this->m_JointPDFXYl = JointPDFType::New(); this->m_JointPDFXuYl = JointPDFType::New(); this->m_JointPDFXlYu = JointPDFType::New(); this->m_JointPDFXrYu = JointPDFType::New(); this->m_JointPDFXuYr = JointPDFType::New(); // std::cout << " D " << std::endl; // Instantiate a region, index, size JointPDFRegionType jointPDFRegion; JointPDFIndexType jointPDFIndex; JointPDFSizeType jointPDFSize; typename JointPDFType::SpacingType jspacing; jspacing.Fill(1); // For the joint PDF define a region starting from {0,0} // with size {m_NumberOfHistogramBins, m_NumberOfHistogramBins}. // The dimension represents fixed image parzen window index // and moving image parzen window index, respectively. jointPDFIndex.Fill( 0 ); jointPDFSize.Fill( m_NumberOfHistogramBins ); jointPDFRegion.SetIndex( jointPDFIndex ); jointPDFRegion.SetSize( jointPDFSize ); m_JointHist = JointPDFType::New(); m_JointHist->SetRegions(jointPDFRegion ); m_JointHist->Allocate(); this->m_JointHist->SetSpacing(jspacing); // Set the regions and allocate this->m_JointPDF->SetRegions( jointPDFRegion ); this->m_JointPDF->Allocate(); this->m_JointPDF->SetSpacing(jspacing); this->m_JointPDFXYu->SetRegions( jointPDFRegion ); this->m_JointPDFXYu->Allocate(); this->m_JointPDFXYu->SetSpacing(jspacing); this->m_JointPDFXuY->SetRegions( jointPDFRegion ); this->m_JointPDFXuY->Allocate(); this->m_JointPDFXuY->SetSpacing(jspacing); this->m_JointPDFXlY->SetRegions( jointPDFRegion ); this->m_JointPDFXlY->Allocate(); this->m_JointPDFXlY->SetSpacing(jspacing); this->m_JointPDFXYl->SetRegions( jointPDFRegion ); this->m_JointPDFXYl->Allocate(); this->m_JointPDFXYl->SetSpacing(jspacing); // this->m_JointPDFXlYu->SetRegions( jointPDFRegion ); this->m_JointPDFXlYu->Allocate(); this->m_JointPDFXlYu->SetSpacing(jspacing); this->m_JointPDFXuYl->SetRegions( jointPDFRegion ); this->m_JointPDFXuYl->Allocate(); this->m_JointPDFXuYl->SetSpacing(jspacing); this->m_JointPDFXrYu->SetRegions( jointPDFRegion ); this->m_JointPDFXrYu->Allocate(); this->m_JointPDFXrYu->SetSpacing(jspacing); this->m_JointPDFXuYr->SetRegions( jointPDFRegion ); this->m_JointPDFXuYr->Allocate(); this->m_JointPDFXuYr->SetSpacing(jspacing); // std::cout << " E " << std::endl; m_NormalizeMetric=1.0; for (int i=0; im_FixedImage->GetLargestPossibleRegion().GetSize()[i]; // std::cout << " F " << std::endl; pdfinterpolator->SetInputImage(m_JointPDF); pdfinterpolator->SetSplineOrder(3); this->pdfinterpolatorXuY->SetInputImage(this->m_JointPDFXuY); this->pdfinterpolatorXYu->SetInputImage(this->m_JointPDFXYu); this->pdfinterpolatorXlY->SetInputImage(this->m_JointPDFXlY); this->pdfinterpolatorXYl->SetInputImage(this->m_JointPDFXYl); this->pdfinterpolatorXuYl->SetInputImage(this->m_JointPDFXuYl); this->pdfinterpolatorXlYu->SetInputImage(this->m_JointPDFXlYu); this->pdfinterpolatorXuYr->SetInputImage(this->m_JointPDFXuYr); this->pdfinterpolatorXrYu->SetInputImage(this->m_JointPDFXrYu); this->pdfinterpolatorXuY->SetSplineOrder(3); this->pdfinterpolatorXYu->SetSplineOrder(3); this->pdfinterpolatorXlY->SetSplineOrder(3); this->pdfinterpolatorXYl->SetSplineOrder(3); this->pdfinterpolatorXuYl->SetSplineOrder(3); this->pdfinterpolatorXlYu->SetSplineOrder(3); this->pdfinterpolatorXuYr->SetSplineOrder(3); this->pdfinterpolatorXrYu->SetSplineOrder(3); pdfinterpolator2->SetInputImage(m_FixedImageMarginalPDF); pdfinterpolator3->SetInputImage(m_MovingImageMarginalPDF); pdfinterpolator2->SetSplineOrder(3); pdfinterpolator3->SetSplineOrder(3); // std::cout << " Ga " << std::endl; this->GetProbabilities(); // std::cout << " G " << std::endl; this->ComputeSpatialMutualInformation(); // std::cout << " H " << std::endl; } /** * Get the both Value and Derivative Measure */ template < class TFixedImage, class TMovingImage , class TDeformationField> void SpatialMutualInformationRegistrationFunction ::GetProbabilities() { typedef ImageRegionConstIteratorWithIndex RandomIterator; RandomIterator randIter( this->m_FixedImage, this->m_FixedImage->GetLargestPossibleRegion() ); for ( unsigned int j = 0; j < m_NumberOfHistogramBins; j++ ) { MarginalPDFIndexType mind; mind[0]=j; m_FixedImageMarginalPDF->SetPixel(mind,0); m_MovingImageMarginalPDF->SetPixel(mind,0); } // Reset the joint pdfs to zero m_JointPDF->FillBuffer( 0.0 ); m_JointPDFXuY->FillBuffer( 0.0 ); m_JointPDFXYu->FillBuffer( 0.0 ); m_JointPDFXlY->FillBuffer( 0.0 ); m_JointPDFXYl->FillBuffer( 0.0 ); m_JointPDFXuYl->FillBuffer( 0.0 ); m_JointPDFXlYu->FillBuffer( 0.0 ); m_JointPDFXrYu->FillBuffer( 0.0 ); m_JointPDFXuYr->FillBuffer( 0.0 ); m_JointHist->FillBuffer( 0.0 ); unsigned long nSamples=0; RandomIterator iter( this->m_FixedImage, this->m_FixedImage->GetLargestPossibleRegion() ); for( iter.GoToBegin(); !iter.IsAtEnd(); ++iter ) { bool takesample=true; if (this->m_FixedImageMask) if (this->m_FixedImageMask->GetPixel( iter.GetIndex() ) < 1.e-6 ) takesample=false; if (takesample) { // Get sampled index FixedImageIndexType index = iter.GetIndex(); FixedImageIndexType IndexU = index; FixedImageIndexType IndexL = index; FixedImageIndexType IndexR = index; // check the neighboring voxel to be in the image typename FixedImageType::SizeType imagesize=this->m_FixedImage->GetLargestPossibleRegion().GetSize(); bool inimage=true; for (unsigned int dd=0; dd static_cast(imagesize[dd]-2) ) inimage=false; } // std::cout << " Image size? " << imagesize << std::endl; if (inimage) { IndexU[0] = index[0] - 1; IndexL[1] = index[1] - 1; IndexR[1] = index[1] + 1; double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( index ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( index ) ); unsigned int movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); unsigned int fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); JointPDFValueType *pdfPtr = m_JointPDF->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); int pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( index ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexU ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXuY->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexU ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( index ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXYu->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( index ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexL ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXlY->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexL ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( index ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXYl->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexL ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexU ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXuYl->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexU ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexL ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXlYu->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexU ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexR ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXrYu->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( IndexR ) ); fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( IndexU ) ); movingImageParzenWindowIndex=this->FitIndexInBins( movingImageValue ); fixedImageParzenWindowIndex=this->FitIndexInBins( fixedImageValue ); pdfPtr = m_JointPDFXuYr->GetBufferPointer() + ( fixedImageParzenWindowIndex* m_NumberOfHistogramBins ); pdfMovingIndex = static_cast( movingImageParzenWindowIndex ); pdfPtr += pdfMovingIndex; *(pdfPtr) += static_cast( 1 ); ++nSamples; } } } // std::cout << " Image Rotation Number " << nSamples << std::endl; /** * Normalize the PDFs, compute moving image marginal PDF * */ typedef ImageRegionIterator JointPDFIteratorType; JointPDFIteratorType jointPDFIterator ( m_JointPDF, m_JointPDF->GetBufferedRegion() ); JointPDFIteratorType jointPDFXuYIterator ( m_JointPDFXuY, m_JointPDFXuY->GetBufferedRegion() ); JointPDFIteratorType jointPDFXYuIterator ( m_JointPDFXYu, m_JointPDFXYu->GetBufferedRegion() ); JointPDFIteratorType jointPDFXlYIterator ( m_JointPDFXlY, m_JointPDFXlY->GetBufferedRegion() ); JointPDFIteratorType jointPDFXYlIterator ( m_JointPDFXYl, m_JointPDFXYl->GetBufferedRegion() ); JointPDFIteratorType jointPDFXuYlIterator ( m_JointPDFXuYl, m_JointPDFXuYl->GetBufferedRegion() ); JointPDFIteratorType jointPDFXlYuIterator ( m_JointPDFXlYu, m_JointPDFXlYu->GetBufferedRegion() ); JointPDFIteratorType jointPDFXrYuIterator ( m_JointPDFXrYu, m_JointPDFXrYu->GetBufferedRegion() ); JointPDFIteratorType jointPDFXuYrIterator ( m_JointPDFXuYr, m_JointPDFXuYr->GetBufferedRegion() ); // Compute joint PDF normalization factor (to ensure joint PDF sum adds to 1.0) double jointPDFSum = 0.0; jointPDFIterator.GoToBegin(); while( !jointPDFIterator.IsAtEnd() ) { float temp = jointPDFIterator.Get(); // jointPDFIterator.Set(temp); jointPDFSum += temp; ++jointPDFIterator; } // std::cout << " Joint PDF Summation? " << jointPDFSum << std::endl; // of derivatives if ( jointPDFSum == 0.0 ) { itkExceptionMacro( "Joint PDF summed to zero" ); } // Normalize the PDF bins jointPDFIterator.GoToEnd(); jointPDFXuYIterator.GoToEnd(); jointPDFXYuIterator.GoToEnd(); jointPDFXlYIterator.GoToEnd(); jointPDFXYlIterator.GoToEnd(); jointPDFXuYlIterator.GoToEnd(); jointPDFXlYuIterator.GoToEnd(); jointPDFXrYuIterator.GoToEnd(); jointPDFXuYrIterator.GoToEnd(); while( !jointPDFIterator.IsAtBegin() ) { --jointPDFIterator; --jointPDFXuYIterator; --jointPDFXYuIterator; --jointPDFXlYIterator; --jointPDFXYlIterator; --jointPDFXuYlIterator; --jointPDFXlYuIterator; --jointPDFXrYuIterator; --jointPDFXuYrIterator; jointPDFIterator.Value() /= static_cast( jointPDFSum ); jointPDFXuYIterator.Value() /= static_cast( jointPDFSum ); jointPDFXYuIterator.Value() /= static_cast( jointPDFSum ); jointPDFXlYIterator.Value() /= static_cast( jointPDFSum ); jointPDFXYlIterator.Value() /= static_cast( jointPDFSum ); jointPDFXuYlIterator.Value() /= static_cast( jointPDFSum ); jointPDFXlYuIterator.Value() /= static_cast( jointPDFSum ); jointPDFXrYuIterator.Value() /= static_cast( jointPDFSum ); jointPDFXuYrIterator.Value() /= static_cast( jointPDFSum ); } bool smoothjh=false; if (smoothjh) { typedef DiscreteGaussianImageFilter dgtype; typename dgtype::Pointer dg=dgtype::New(); dg->SetInput(this->m_JointPDF); dg->SetVariance(1.); dg->SetUseImageSpacingOff(); dg->SetMaximumError(.01f); dg->Update(); this->m_JointPDF=dg->GetOutput(); } // Compute moving image marginal PDF by summing over fixed image bins. typedef ImageLinearIteratorWithIndex JointPDFLinearIterator; JointPDFLinearIterator linearIter( m_JointPDF, m_JointPDF->GetBufferedRegion() ); linearIter.SetDirection( 0 ); linearIter.GoToBegin(); unsigned int fixedIndex = 0; while( !linearIter.IsAtEnd() ) { double sum = 0.0; while( !linearIter.IsAtEndOfLine() ) { sum += linearIter.Get(); ++linearIter; } MarginalPDFIndexType mind; mind[0]=fixedIndex; m_FixedImageMarginalPDF->SetPixel(mind,static_cast(sum)); linearIter.NextLine(); ++fixedIndex; } linearIter.SetDirection( 1 ); linearIter.GoToBegin(); unsigned int movingIndex = 0; while( !linearIter.IsAtEnd() ) { double sum = 0.0; while( !linearIter.IsAtEndOfLine() ) { sum += linearIter.Get(); ++linearIter; } MarginalPDFIndexType mind; mind[0]=movingIndex; m_MovingImageMarginalPDF->SetPixel(mind,static_cast(sum)); linearIter.NextLine(); ++movingIndex; } } /** * Get the both Value and Derivative Measure */ template < class TFixedImage, class TMovingImage , class TDeformationField> double SpatialMutualInformationRegistrationFunction ::GetValueAndDerivative(IndexType oindex, MeasureType& valuei, DerivativeType& derivative1,DerivativeType& derivative2) { double value=0; DerivativeType zero(ImageDimension); zero.Fill(0); double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( oindex ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( oindex ) ); double movingImageParzenWindowContIndex=this->FitContIndexInBins( movingImageValue ); double fixedImageParzenWindowContIndex=this->FitContIndexInBins( fixedImageValue ); double dJPDF=0,jointPDFValue=0; double jointPDFValueXuY = 0, dJPDFXuY = 0, jointPDFValueXYu = 0, dJPDFXYu = 0, jointPDFValueXlY = 0, dJPDFXlY = 0, jointPDFValueXYl = 0; double dJPDFXYl = 0, jointPDFValueXuYl = 0, dJPDFXuYl = 0, jointPDFValueXlYu = 0, dJPDFXlYu = 0, jointPDFValueXuYr = 0, dJPDFXuYr = 0, jointPDFValueXrYu = 0, dJPDFXrYu = 0; { /** take derivative of joint pdf with respect to the b-spline */ typename pdfintType::ContinuousIndexType pdfind; pdfind[1]= fixedImageParzenWindowContIndex; pdfind[0]= movingImageParzenWindowContIndex; jointPDFValue = pdfinterpolator->EvaluateAtContinuousIndex(pdfind); dJPDF = (1.0)*(pdfinterpolator->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXuY = pdfinterpolatorXuY->EvaluateAtContinuousIndex(pdfind); dJPDFXuY = (1.0)*(pdfinterpolatorXuY->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXYu = pdfinterpolatorXYu->EvaluateAtContinuousIndex(pdfind); dJPDFXYu = (1.0)*(pdfinterpolatorXYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXlY = pdfinterpolatorXlY->EvaluateAtContinuousIndex(pdfind); dJPDFXlY = (1.0)*(pdfinterpolatorXlY->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXYl = pdfinterpolatorXYl->EvaluateAtContinuousIndex(pdfind); dJPDFXYl = (1.0)*(pdfinterpolatorXYl->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXuYl = pdfinterpolatorXuYl->EvaluateAtContinuousIndex(pdfind); dJPDFXuYl = (1.0)*(pdfinterpolatorXuYl->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXlYu = pdfinterpolatorXlYu->EvaluateAtContinuousIndex(pdfind); dJPDFXlYu = (1.0)*(pdfinterpolatorXlYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXuYr = pdfinterpolatorXuYr->EvaluateAtContinuousIndex(pdfind); dJPDFXuYr = (1.0)*(pdfinterpolatorXuYr->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; jointPDFValueXrYu = pdfinterpolatorXrYu->EvaluateAtContinuousIndex(pdfind); dJPDFXrYu = (1.0)*(pdfinterpolatorXrYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[1]; } double eps=1.e-12; if( jointPDFValue > eps && jointPDFValueXuY > eps && jointPDFValueXYu > eps && jointPDFValueXlY > eps && jointPDFValueXYl > eps && jointPDFValueXuYl > eps && jointPDFValueXlYu > eps && jointPDFValueXrYu > eps && jointPDFValueXuYr > eps) { value = 4 * dJPDF / jointPDFValue + dJPDFXuYl / jointPDFValueXuYl + dJPDFXlYu / jointPDFValueXlYu + dJPDFXuYr / jointPDFValueXuYr + dJPDFXrYu / jointPDFValueXrYu - 2 * dJPDFXYu / jointPDFValueXYu - 2 * dJPDFXuY / jointPDFValueXuY - 2 * dJPDFXYl / jointPDFValueXYl - 2 * dJPDFXlY / jointPDFValueXlY; } // end if-block to check non-zero bin contribution else value = 0; return (value/4)*(-1); } template < class TFixedImage, class TMovingImage , class TDeformationField> double SpatialMutualInformationRegistrationFunction ::GetValueAndDerivativeInv(IndexType oindex, MeasureType& valuei, DerivativeType& derivative1,DerivativeType& derivative2) { double value=0; DerivativeType zero(ImageDimension); zero.Fill(0); double movingImageValue = this->GetMovingParzenTerm( this->m_MovingImage->GetPixel( oindex ) ); double fixedImageValue = this->GetFixedParzenTerm( this->m_FixedImage->GetPixel( oindex ) ); double movingImageParzenWindowContIndex=this->FitContIndexInBins( movingImageValue ); double fixedImageParzenWindowContIndex=this->FitContIndexInBins( fixedImageValue ); double dJPDF=0,jointPDFValue=0; double jointPDFValueXuY = 0, dJPDFXuY = 0, jointPDFValueXYu = 0, dJPDFXYu = 0, jointPDFValueXlY = 0, dJPDFXlY = 0, jointPDFValueXYl = 0; double dJPDFXYl = 0, jointPDFValueXuYl = 0, dJPDFXuYl = 0, jointPDFValueXlYu = 0, dJPDFXlYu = 0, jointPDFValueXuYr = 0, dJPDFXuYr = 0, jointPDFValueXrYu = 0, dJPDFXrYu = 0; { /** take derivative of joint pdf with respect to the b-spline */ typename pdfintType::ContinuousIndexType pdfind; pdfind[1]= fixedImageParzenWindowContIndex; pdfind[0]= movingImageParzenWindowContIndex; jointPDFValue = pdfinterpolator->EvaluateAtContinuousIndex(pdfind); dJPDF = (1.0)*(pdfinterpolator->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXuY = pdfinterpolatorXuY->EvaluateAtContinuousIndex(pdfind); dJPDFXuY = (1.0)*(pdfinterpolatorXuY->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXYu = pdfinterpolatorXYu->EvaluateAtContinuousIndex(pdfind); dJPDFXYu = (1.0)*(pdfinterpolatorXYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXlY = pdfinterpolatorXlY->EvaluateAtContinuousIndex(pdfind); dJPDFXlY = (1.0)*(pdfinterpolatorXlY->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXYl = pdfinterpolatorXYl->EvaluateAtContinuousIndex(pdfind); dJPDFXYl = (1.0)*(pdfinterpolatorXYl->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXuYl = pdfinterpolatorXuYl->EvaluateAtContinuousIndex(pdfind); dJPDFXuYl = (1.0)*(pdfinterpolatorXuYl->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXlYu = pdfinterpolatorXlYu->EvaluateAtContinuousIndex(pdfind); dJPDFXlYu = (1.0)*(pdfinterpolatorXlYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXuYr = pdfinterpolatorXuYr->EvaluateAtContinuousIndex(pdfind); dJPDFXuYr = (1.0)*(pdfinterpolatorXuYr->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; jointPDFValueXrYu = pdfinterpolatorXrYu->EvaluateAtContinuousIndex(pdfind); dJPDFXrYu = (1.0)*(pdfinterpolatorXrYu->EvaluateDerivativeAtContinuousIndex( pdfind ))[0]; } double eps=1.e-12; if( jointPDFValue > eps && jointPDFValueXuY > eps && jointPDFValueXYu > eps && jointPDFValueXlY > eps && jointPDFValueXYl > eps && jointPDFValueXuYl > eps && jointPDFValueXlYu > eps && jointPDFValueXrYu > eps && jointPDFValueXuYr > eps) { value = 4 * dJPDF / jointPDFValue + dJPDFXuYl / jointPDFValueXuYl + dJPDFXlYu / jointPDFValueXlYu + dJPDFXuYr / jointPDFValueXuYr + dJPDFXrYu / jointPDFValueXrYu - 2 * dJPDFXYu / jointPDFValueXYu - 2 * dJPDFXuY / jointPDFValueXuY - 2 * dJPDFXYl / jointPDFValueXYl - 2 * dJPDFXlY / jointPDFValueXlY; } // end if-block to check non-zero bin contribution else value = 0; // return 0; return (value/4)*(0); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkSpatialMutualInformationRegistrationFunction.h000077500000000000000000000727721147325206600320740ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkSpatialMutualInformationRegistrationFunction.h,v $ Language: C++ Date: $Date: 2009/01/08 15:14:48 $ Version: $Revision: 1.20 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkSpatialMutualInformationRegistrationFunction_h #define __itkSpatialMutualInformationRegistrationFunction_h #include "itkImageFileWriter.h" #include "itkImageToImageMetric.h" #include "itkAvantsPDEDeformableRegistrationFunction.h" #include "itkCovariantVector.h" #include "itkPoint.h" #include "itkIndex.h" #include "itkBSplineKernelFunction.h" #include "itkBSplineDerivativeKernelFunction.h" #include "itkCentralDifferenceImageFunction.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkBSplineDeformableTransform.h" #include "itkTranslationTransform.h" #include "itkArray2D.h" #include "itkImageBase.h" #include "itkTransform.h" #include "itkInterpolateImageFunction.h" #include "itkSingleValuedCostFunction.h" #include "itkExceptionObject.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkSpatialObject.h" #include "itkConstNeighborhoodIterator.h" namespace itk { /** \class SpatialMutualInformationRegistrationFunction * \brief Computes the mutual information between two images to be * registered using the method of Spatial et al. * * SpatialMutualInformationRegistrationFunction computes the mutual * information between a fixed and moving image to be registered. * * This class is templated over the FixedImage type and the MovingImage * type. * * The fixed and moving images are set via methods SetFixedImage() and * SetMovingImage(). This metric makes use of user specified Transform and * Interpolator. The Transform is used to map points from the fixed image to * the moving image domain. The Interpolator is used to evaluate the image * intensity at user specified geometric points in the moving image. * The Transform and Interpolator are set via methods SetTransform() and * SetInterpolator(). * * If a BSplineInterpolationFunction is used, this class obtain * image derivatives from the BSpline interpolator. Otherwise, * image derivatives are computed using central differencing. * * \warning This metric assumes that the moving image has already been * connected to the interpolator outside of this class. * * The method GetValue() computes of the mutual information * while method GetValueAndDerivative() computes * both the mutual information and its derivatives with respect to the * transform parameters. * * The calculations are based on the method of Spatial et al [1,2] * where the probability density distribution are estimated using * Parzen histograms. Since the fixed image PDF does not contribute * to the derivatives, it does not need to be smooth. Hence, * a zero order (box car) BSpline kernel is used * for the fixed image intensity PDF. On the other hand, to ensure * smoothness a third order BSpline kernel is used for the * moving image intensity PDF. * * On Initialize(), the FixedImage is uniformly sampled within * the FixedImageRegion. The number of samples used can be set * via SetNumberOfSpatialSamples(). Typically, the number of * spatial samples used should increase with the image size. * * During each call of GetValue(), GetDerivatives(), * GetValueAndDerivatives(), marginal and joint intensity PDF's * values are estimated at discrete position or bins. * The number of bins used can be set via SetNumberOfHistogramBins(). * To handle data with arbitray magnitude and dynamic range, * the image intensity is scale such that any contribution to the * histogram will fall into a valid bin. * * One the PDF's have been contructed, the mutual information * is obtained by doubling summing over the discrete PDF values. * * * Notes: * 1. This class returns the negative mutual information value. * 2. This class in not thread safe due the private data structures * used to the store the sampled points and the marginal and joint pdfs. * * References: * [1] "Nonrigid multimodality image registration" * D. Spatial, D. R. Haynor, H. Vesselle, T. Lewellen and W. Eubank * Medical Imaging 2001: Image Processing, 2001, pp. 1609-1620. * [2] "PET-CT Image Registration in the Chest Using Free-form Deformations" * D. Spatial, D. R. Haynor, H. Vesselle, T. Lewellen and W. Eubank * IEEE Transactions in Medical Imaging. Vol.22, No.1, January 2003. pp.120-128. * [3] "Optimization of Mutual Information for MultiResolution Image * Registration" * P. Thevenaz and M. Unser * IEEE Transactions in Image Processing, 9(12) December 2000. * * \ingroup RegistrationMetrics * \ingroup ThreadUnSafe */ template class ITK_EXPORT SpatialMutualInformationRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage , TDeformationField> { public: /** Standard class typedefs. */ typedef SpatialMutualInformationRegistrationFunction Self; typedef AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( SpatialMutualInformationRegistrationFunction, AvantsPDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; typedef typename FixedImageType::SpacingType SpacingType; /** Deformation field type. */ typedef typename Superclass::VectorType VectorType; typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Interpolator type. */ typedef double CoordRepType; typedef // // LinearInterpolateImageFunction BSplineInterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef typename InterpolatorType::PointType PointType; typedef InterpolatorType DefaultInterpolatorType; // typedef LinearInterpolateImageFunction //DefaultInterpolatorType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** Gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Set the moving image interpolator. */ void SetMovingImageInterpolator( InterpolatorType * ptr ) { m_MovingImageInterpolator = ptr; } /** Get the moving image interpolator. */ InterpolatorType * GetMovingImageInterpolator(void) { return m_MovingImageInterpolator; } /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void *itkNotUsed(GlobalData)) const { return 1; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); // global->m_SumOfSquaredDifference = 0.0; /// global->m_NumberOfPixelsProcessed = 0L; // global->m_SumOfSquaredChange = 0; return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const { delete (GlobalDataStruct *) GlobalData; } /** Set the object's state before each iteration. */ virtual void InitializeIteration(); typedef double CoordinateRepresentationType; /** Types inherited from Superclass. */ typedef TranslationTransform TransformType; typedef ImageToImageMetric< TFixedImage, TMovingImage > Metricclass; typedef typename TransformType::Pointer TransformPointer; typedef typename Metricclass::TransformJacobianType TransformJacobianType; // typedef typename Metricclass::InterpolatorType InterpolatorType; typedef typename Metricclass::MeasureType MeasureType; typedef typename Metricclass::DerivativeType DerivativeType; typedef typename TransformType::ParametersType ParametersType; typedef typename Metricclass::FixedImageConstPointer FixedImageConstPointer; typedef typename Metricclass::MovingImageConstPointer MovingImageCosntPointer; // typedef typename TransformType::CoordinateRepresentationType CoordinateRepresentationType; /** Index and Point typedef support. */ typedef typename FixedImageType::IndexType FixedImageIndexType; typedef typename FixedImageIndexType::IndexValueType FixedImageIndexValueType; typedef typename MovingImageType::IndexType MovingImageIndexType; typedef typename TransformType::InputPointType FixedImagePointType; typedef typename TransformType::OutputPointType MovingImagePointType; /** The marginal PDFs are stored as std::vector. */ typedef float PDFValueType; // typedef std::vector MarginalPDFType; typedef Image MarginalPDFType; typedef typename MarginalPDFType::IndexType MarginalPDFIndexType; /** Typedef for the joint PDF and PDF derivatives are stored as ITK Images. */ typedef Image JointPDFType; typedef Image JointPDFDerivativesType; typedef JointPDFType::IndexType JointPDFIndexType; typedef JointPDFType::PixelType JointPDFValueType; typedef JointPDFType::RegionType JointPDFRegionType; typedef JointPDFType::SizeType JointPDFSizeType; typedef JointPDFDerivativesType::IndexType JointPDFDerivativesIndexType; typedef JointPDFDerivativesType::PixelType JointPDFDerivativesValueType; typedef JointPDFDerivativesType::RegionType JointPDFDerivativesRegionType; typedef JointPDFDerivativesType::SizeType JointPDFDerivativesSizeType; /** Get the value and derivatives for single valued optimizers. */ double GetValueAndDerivative( IndexType index, MeasureType& Value, DerivativeType& Derivative1 , DerivativeType& Derivative2 ) ; /** Get the value and derivatives for single valued optimizers. */ double GetValueAndDerivativeInv( IndexType index, MeasureType& Value, DerivativeType& Derivative1 , DerivativeType& Derivative2 ) ; /** Number of spatial samples to used to compute metric */ // itkSetClampMacro( NumberOfSpatialSamples, unsigned long, // 1, NumericTraits::max() ); //itkGetConstReferenceMacro( NumberOfSpatialSamples, unsigned long); /** Number of bins to used in the histogram. Typical value is 50. */ // itkSetClampMacro( NumberOfHistogramBins, unsigned long, // 1, NumericTraits::max() ); // itkGetConstReferenceMacro( NumberOfHistogramBins, unsigned long); void SetNumberOfHistogramBins(unsigned long nhb) { m_NumberOfHistogramBins=nhb+2*this->m_Padding;} unsigned long GetNumberOfHistogramBins() {return m_NumberOfHistogramBins;} void SetTransform(TransformPointer t){m_Transform=t;} TransformPointer GetTransform(){return m_Transform;} void SetInterpolator(InterpolatorPointer t){m_Interpolator=t;} InterpolatorPointer GetInterpolator(){ return m_Interpolator; } void GetProbabilities(); double ComputeMutualInformation() { // typedef ImageRegionIterator JointPDFIteratorType; // JointPDFIteratorType jointPDFIterator ( m_JointPDF, m_JointPDF->GetBufferedRegion() ); float px,py,pxy; double mival = 0; double mi; unsigned long ct = 0; typename JointPDFType::IndexType index; // for (unsigned int ii=this->m_Padding+1; iim_Padding-2; ii++) for (unsigned int ii=0; iiGetPixel(mind); // for (unsigned int jj=this->m_Padding+1; jjm_Padding-2; jj++) for (unsigned int jj=0; jjGetPixel(mind); float denom = px*py; index[0]=ii; index[1]=jj; //pxy=m_JointPDF->GetPixel(index); JointPDFValueType *pdfPtr = m_JointPDF->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ); // Move the pointer to the first affected bin int pdfMovingIndex = static_cast( jj ); pdfPtr += pdfMovingIndex; pxy=*(pdfPtr); mi=0; if (fabs(denom) > 0 ) { if (pxy/denom > 0) { //true mi mi = pxy*log(pxy/denom); //test mi //mi = 1.0 + log(pxy/denom); ct++; } } mival += mi; } // std::cout << " II " << ii << " JJ " << ii << " pxy " << pxy << " px " << px << std::endl; } this->m_Energy = (-1.0) * mival/log(2); return this->m_Energy; } double ComputeSpatialMutualInformation() { float pxy; double SMI = 0; double JointEntropy = 0, JointEntropyXuY = 0, JointEntropyXYu = 0, JointEntropyXlY = 0, JointEntropyXYl = 0; double JointEntropyXuYl = 0, JointEntropyXlYu = 0, JointEntropyXrYu = 0, JointEntropyXuYr = 0; for (unsigned int ii=0; ii( jj ); JointPDFValueType *pdfPtr = m_JointPDF->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropy -= pxy * log(pxy); pdfPtr = m_JointPDFXuY->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXuY -= pxy * log(pxy); pdfPtr = m_JointPDFXYu->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXYu -= pxy * log(pxy); pdfPtr = m_JointPDFXlY->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXlY -= pxy * log(pxy); pdfPtr = m_JointPDFXYl->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXYl -= pxy * log(pxy); pdfPtr = m_JointPDFXuYl->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXuYl -= pxy * log(pxy); pdfPtr = m_JointPDFXlYu->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXlYu -= pxy * log(pxy); pdfPtr = m_JointPDFXrYu->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXrYu -= pxy * log(pxy); pdfPtr = m_JointPDFXuYr->GetBufferPointer() + ( ii* m_NumberOfHistogramBins ) + pdfMovingIndex; pxy=*(pdfPtr); if (fabs(pxy) > 0 ) JointEntropyXuYr -= pxy * log(pxy); } } SMI = (0.5) * (JointEntropyXuY + JointEntropyXYu + JointEntropyXlY + JointEntropyXYl) - (0.25) * (4 * JointEntropy + JointEntropyXuYr + JointEntropyXrYu + JointEntropyXlYu + JointEntropyXuYl); // std::cout << " JE " << JointEntropy << " JEXuY " << JointEntropyXuY << " JEXYu " << JointEntropyXYu << " JEXuYr " << JointEntropyXuYr << std::endl; this->m_Energy = (-1.0) * fabs(SMI/log(2)); return this->m_Energy; } virtual VectorType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(this->Superclass::m_FixedImage.GetPointer()); if (!img) return update; typename FixedImageType::SpacingType spacing=img->GetSpacing(); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); for (unsigned int dd=0; dd= static_cast(imagesize[dd]-1) ) return update; } CovariantVectorType fixedGradient; double loce=0.0; ParametersType fdvec1(ImageDimension); ParametersType fdvec2(ImageDimension); fdvec1.Fill(0); fdvec2.Fill(0); fixedGradient = m_FixedImageGradientCalculator->EvaluateAtIndex( oindex ); double nccm1=0; loce=this->GetValueAndDerivativeInv(oindex,nccm1,fdvec1,fdvec2); float eps=10; if ( loce > eps ) loce=eps; if ( loce < eps*(-1.0) ) loce=eps*(-1.0); for (int imd=0; imdm_MetricImage) this->m_MetricImage->SetPixel(oindex,loce); return update; } /* Normalizing the image to the range of [0 1] */ double GetMovingParzenTerm( double intensity ) { double windowTerm = static_cast( intensity ) - this->m_MovingImageTrueMin; windowTerm = windowTerm / ( this->m_MovingImageTrueMax - this->m_MovingImageTrueMin ) ; return windowTerm ; } double GetFixedParzenTerm( double intensity ) { double windowTerm = static_cast( intensity ) - this->m_FixedImageTrueMin; windowTerm = windowTerm / ( this->m_FixedImageTrueMax - this->m_FixedImageTrueMin ) ; return windowTerm ; } /* find the image index in the number of histogram bins */ unsigned int FitIndexInBins( double windowTerm ) { unsigned int movingImageParzenWindowIndex = static_cast( this->m_Padding + round( windowTerm * (float)(this->m_NumberOfHistogramBins - 1 - this->m_Padding))) ; // Make sure the extreme values are in valid bins if ( movingImageParzenWindowIndex < this->m_Padding ) { movingImageParzenWindowIndex = this->m_Padding -1 ; } else if ( movingImageParzenWindowIndex > (m_NumberOfHistogramBins - this->m_Padding ) ) { movingImageParzenWindowIndex = m_NumberOfHistogramBins - this->m_Padding - 1; } return movingImageParzenWindowIndex; } double FitContIndexInBins( double windowTerm ) { return ( (double) this->m_Padding + windowTerm*(float)(this->m_NumberOfHistogramBins-this->m_Padding)); } virtual VectorType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)) { VectorType update; update.Fill(0.0); IndexType oindex = neighborhood.GetIndex(); FixedImageType* img =const_cast(this->Superclass::m_MovingImage.GetPointer()); if (!img) return update; typename FixedImageType::SpacingType spacing=img->GetSpacing(); typename FixedImageType::SizeType imagesize=img->GetLargestPossibleRegion().GetSize(); for (unsigned int dd=0; dd= static_cast(imagesize[dd]-1) ) return update; } CovariantVectorType movingGradient; double loce=0.0; ParametersType fdvec1(ImageDimension); ParametersType fdvec2(ImageDimension); fdvec1.Fill(0); fdvec2.Fill(0); movingGradient = m_MovingImageGradientCalculator->EvaluateAtIndex( oindex ); double nccm1=0; loce=this->GetValueAndDerivative(oindex,nccm1,fdvec1,fdvec2); float eps=10; if ( loce > eps ) loce=eps; if ( loce < eps*(-1.0) ) loce=eps*(-1.0); for (int imd=0; imdm_MetricImage) { typedef ImageFileWriter writertype; typename writertype::Pointer w= writertype::New(); w->SetInput( this->m_MetricImage); w->SetFileName("ZZmetric.nii.gz"); w->Write(); } } void SetOpticalFlow(bool b){ m_OpticalFlow = b; } typename JointPDFType::Pointer GetJointPDF() { return m_JointPDF; } typename JointPDFType::Pointer GetJointHist() { return m_JointHist; } void SetFixedImageMask( FixedImageType* img) {m_FixedImageMask=img; } /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * iterators for the fixed image. */ struct GlobalDataStruct { FixedImageNeighborhoodIteratorType m_FixedImageIterator; }; /** The fixed image marginal PDF. */ mutable MarginalPDFType::Pointer m_FixedImageMarginalPDF; /** The moving image marginal PDF. */ mutable MarginalPDFType::Pointer m_MovingImageMarginalPDF; /** The joint PDF and PDF derivatives. */ typename JointPDFType::Pointer m_JointPDF; unsigned long m_NumberOfSpatialSamples; unsigned long m_NumberOfParameters; /** Variables to define the marginal and joint histograms. */ unsigned long m_NumberOfHistogramBins; double m_MovingImageNormalizedMin; double m_FixedImageNormalizedMin; double m_MovingImageTrueMin; double m_MovingImageTrueMax; double m_FixedImageTrueMin; double m_FixedImageTrueMax; double m_FixedImageBinSize; double m_MovingImageBinSize; protected: SpatialMutualInformationRegistrationFunction(); virtual ~SpatialMutualInformationRegistrationFunction() {}; void PrintSelf(std::ostream& os, Indent indent) const; private: SpatialMutualInformationRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typename JointPDFType::Pointer m_JointHist; typename JointPDFDerivativesType::Pointer m_JointPDFDerivatives; typedef BSplineInterpolateImageFunction pdfintType; typename pdfintType::Pointer pdfinterpolator; // typename JointPDFType::Pointer m_JointEntropy; typename JointPDFType::Pointer m_JointPDFXuY; typename JointPDFType::Pointer m_JointPDFXYu; typename JointPDFType::Pointer m_JointPDFXlY; typename JointPDFType::Pointer m_JointPDFXYl; typename JointPDFType::Pointer m_JointPDFXuYl; typename JointPDFType::Pointer m_JointPDFXlYu; typename JointPDFType::Pointer m_JointPDFXrYu; typename JointPDFType::Pointer m_JointPDFXuYr; typename pdfintType::Pointer pdfinterpolatorXuY; typename pdfintType::Pointer pdfinterpolatorXYu; typename pdfintType::Pointer pdfinterpolatorXlY; typename pdfintType::Pointer pdfinterpolatorXYl; typename pdfintType::Pointer pdfinterpolatorXuYl; typename pdfintType::Pointer pdfinterpolatorXlYu; typename pdfintType::Pointer pdfinterpolatorXuYr; typename pdfintType::Pointer pdfinterpolatorXrYu; /** Typedefs for BSpline kernel and derivative functions. */ typedef BSplineKernelFunction<3> CubicBSplineFunctionType; typedef BSplineDerivativeKernelFunction<3> CubicBSplineDerivativeFunctionType; /** Cubic BSpline kernel for computing Parzen histograms. */ typename CubicBSplineFunctionType::Pointer m_CubicBSplineKernel; typename CubicBSplineDerivativeFunctionType::Pointer m_CubicBSplineDerivativeKernel; /** * Types and variables related to image derivative calculations. * If a BSplineInterpolationFunction is used, this class obtain * image derivatives from the BSpline interpolator. Otherwise, * image derivatives are computed using central differencing. */ typedef CovariantVector< double, itkGetStaticConstMacro(ImageDimension) > ImageDerivativesType; /** Boolean to indicate if the interpolator BSpline. */ bool m_InterpolatorIsBSpline; // boolean to determine if we use mono-modality assumption bool m_OpticalFlow; /** Typedefs for using BSpline interpolator. */ typedef BSplineInterpolateImageFunction BSplineInterpolatorType; /** Pointer to BSplineInterpolator. */ typename BSplineInterpolatorType::Pointer m_BSplineInterpolator; /** Typedefs for using central difference calculator. */ typedef CentralDifferenceImageFunction DerivativeFunctionType; /** Pointer to central difference calculator. */ typename DerivativeFunctionType::Pointer m_DerivativeCalculator; /** * Types and variables related to BSpline deformable transforms. * If the transform is of type third order BSplineDeformableTransform, * then we can speed up the metric derivative calculation by * only inspecting the parameters within the support region * of a mapped point. */ /** Boolean to indicate if the transform is BSpline deformable. */ bool m_TransformIsBSpline; /** The number of BSpline parameters per image dimension. */ long m_NumParametersPerDim; /** * The number of BSpline transform weights is the number of * of parameter in the support region (per dimension ). */ unsigned long m_NumBSplineWeights; /** * Enum of the deformabtion field spline order. */ enum { DeformationSplineOrder = 3 }; /** * Typedefs for the BSplineDeformableTransform. */ typedef BSplineDeformableTransform< CoordinateRepresentationType, ::itk::GetImageDimension::ImageDimension, DeformationSplineOrder> BSplineTransformType; typedef typename BSplineTransformType::WeightsType BSplineTransformWeightsType; typedef typename BSplineTransformType::ParameterIndexArrayType BSplineTransformIndexArrayType; /** * Variables used when transform is of type BSpline deformable. */ typename BSplineTransformType::Pointer m_BSplineTransform; /** * Cache pre-transformed points, weights, indices and * within support region flag. */ typedef typename BSplineTransformWeightsType::ValueType WeightsValueType; typedef Array2D BSplineTransformWeightsArrayType; typedef typename BSplineTransformIndexArrayType::ValueType IndexValueType; typedef Array2D BSplineTransformIndicesArrayType; typedef std::vector MovingImagePointArrayType; typedef std::vector BooleanArrayType; BSplineTransformWeightsArrayType m_BSplineTransformWeightsArray; BSplineTransformIndicesArrayType m_BSplineTransformIndicesArray; MovingImagePointArrayType m_PreTransformPointsArray; BooleanArrayType m_WithinSupportRegionArray; typename TFixedImage::SpacingType m_FixedImageSpacing; typename TFixedImage::PointType m_FixedImageOrigin; typedef FixedArray::ImageDimension> ParametersOffsetType; ParametersOffsetType m_ParametersOffset; mutable TransformPointer m_Transform; InterpolatorPointer m_Interpolator; InterpolatorPointer m_FixedImageInterpolator; InterpolatorPointer m_MovingImageInterpolator; GradientCalculatorPointer m_FixedImageGradientCalculator; GradientCalculatorPointer m_MovingImageGradientCalculator; FixedImagePointer m_FixedImageMask; MovingImagePointer m_MovingImageMask; double m_NormalizeMetric; float m_Normalizer; // typedef BSplineInterpolateImageFunction dpdfintType; // typename dpdfintType::Pointer dpdfinterpolator; typedef BSplineInterpolateImageFunction pdfintType2; typename pdfintType2::Pointer pdfinterpolator2; typename pdfintType2::Pointer pdfinterpolator3; unsigned int m_Padding; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSpatialMutualInformationRegistrationFunction.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkSyNDemonsRegistrationFunction.cxx000066400000000000000000000270111147325206600273120ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSyNDemonsRegistrationFunction.cxx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkSyNDemonsRegistrationFunction_txx_ #define _itkSyNDemonsRegistrationFunction_txx_ #include "itkSyNDemonsRegistrationFunction.h" #include "itkExceptionObject.h" #include "vnl/vnl_math.h" namespace itk { /* * Default constructor */ template SyNDemonsRegistrationFunction ::SyNDemonsRegistrationFunction() { RadiusType r; unsigned int j; for( j = 0; j < ImageDimension; j++ ) { r[j] = 0; } this->SetRadius(r); m_TimeStep = 1.0; m_DenominatorThreshold = 1e-9; m_IntensityDifferenceThreshold =0.001; this->SetMovingImage(NULL); this->SetFixedImage(NULL); m_FixedImageSpacing.Fill( 1.0 ); m_FixedImageOrigin.Fill( 0.0 ); m_Normalizer = 1.0; m_FixedImageGradientCalculator = GradientCalculatorType::New(); typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_MovingImageInterpolator = static_cast( interp.GetPointer() ); m_Metric = NumericTraits::max(); m_SumOfSquaredDifference = 0.0; m_NumberOfPixelsProcessed = 0L; m_RMSChange = NumericTraits::max(); m_SumOfSquaredChange = 0.0; m_MovingImageGradientCalculator = MovingImageGradientCalculatorType::New(); m_UseMovingImageGradient = false; } /* * Standard "PrintSelf" method. */ template void SyNDemonsRegistrationFunction ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "MovingImageIterpolator: "; os << m_MovingImageInterpolator.GetPointer() << std::endl; os << indent << "FixedImageGradientCalculator: "; os << m_FixedImageGradientCalculator.GetPointer() << std::endl; os << indent << "DenominatorThreshold: "; os << m_DenominatorThreshold << std::endl; os << indent << "IntensityDifferenceThreshold: "; os << m_IntensityDifferenceThreshold << std::endl; os << indent << "UseMovingImageGradient: "; os << m_UseMovingImageGradient << std::endl; os << indent << "Metric: "; os << m_Metric << std::endl; os << indent << "SumOfSquaredDifference: "; os << m_SumOfSquaredDifference << std::endl; os << indent << "NumberOfPixelsProcessed: "; os << m_NumberOfPixelsProcessed << std::endl; os << indent << "RMSChange: "; os << m_RMSChange << std::endl; os << indent << "SumOfSquaredChange: "; os << m_SumOfSquaredChange << std::endl; } /** * */ template void SyNDemonsRegistrationFunction ::SetIntensityDifferenceThreshold(double threshold) { m_IntensityDifferenceThreshold = threshold; } /** * */ template double SyNDemonsRegistrationFunction ::GetIntensityDifferenceThreshold() const { return m_IntensityDifferenceThreshold; } /* * Set the function state values before each iteration */ template void SyNDemonsRegistrationFunction ::InitializeIteration() { // std::cout << " INIT ITER " << std::endl; if( !this->GetMovingImage() || !this->GetFixedImage() || !m_MovingImageInterpolator ) { itkExceptionMacro( << "MovingImage, FixedImage and/or Interpolator not set" ); } // cache fixed image information m_FixedImageSpacing = this->GetFixedImage()->GetSpacing(); m_FixedImageOrigin = this->GetFixedImage()->GetOrigin(); // compute the normalizer m_Normalizer = 0.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { m_Normalizer += m_FixedImageSpacing[k] * m_FixedImageSpacing[k]; } m_Normalizer /= static_cast( ImageDimension ); this->m_Energy=0; // setup gradient calculator m_FixedImageGradientCalculator->SetInputImage( this->GetFixedImage() ); m_MovingImageGradientCalculator->SetInputImage( this->GetMovingImage() ); // setup moving image interpolator m_MovingImageInterpolator->SetInputImage( this->GetMovingImage() ); // initialize metric computation variables m_SumOfSquaredDifference = 0.0; m_NumberOfPixelsProcessed = 0L; m_SumOfSquaredChange = 0.0; } /* * Compute update at a specify neighbourhood */ template typename SyNDemonsRegistrationFunction ::PixelType SyNDemonsRegistrationFunction ::ComputeUpdate(const NeighborhoodType &it, void * gd, const FloatOffsetType& itkNotUsed(offset)) { PixelType update; unsigned int j; IndexType index = it.GetIndex(); // Get fixed image related information double fixedValue; CovariantVectorType gradient; CovariantVectorType mgradient; double gradientSquaredMagnitude = 0; // Note: no need to check the index is within // fixed image buffer. This is done by the external filter. fixedValue = (double) this->GetFixedImage()->GetPixel( index ); double movingValue = (double)this->GetMovingImage()->GetPixel( index ); // if (fixedValue > 0)std::cout << " fxv " << fixedValue << " movingValue " << movingValue << std::endl; gradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); mgradient = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); for( j = 0; j < ImageDimension; j++ ) { if ( this->m_UseMovingImageGradient) gradient[j]=gradient[j]+mgradient[j]; gradientSquaredMagnitude += vnl_math_sqr( gradient[j] ); } /** * Compute Update. * In the original equation the denominator is defined as (g-f)^2 + grad_mag^2. * However there is a mismatch in units between the two terms. * The units for the second term is intensity^2/mm^2 while the * units for the first term is intensity^2. This mismatch is particularly * problematic when the fixed image does not have unit spacing. * In this implemenation, we normalize the first term by a factor K, * such that denominator = (g-f)^2/K + grad_mag^2 * where K = mean square spacing to compensate for the mismatch in units. */ double speedValue = fixedValue - movingValue; if ( fabs(speedValue) < this->m_RobustnessParameter) speedValue=0; // update the metric GlobalDataStruct *globalData = (GlobalDataStruct *)gd; if ( globalData ) { globalData->m_SumOfSquaredDifference += vnl_math_sqr( speedValue ); globalData->m_NumberOfPixelsProcessed += 1; } double denominator = vnl_math_sqr( speedValue ) / m_Normalizer + gradientSquaredMagnitude; this->m_Energy+=speedValue*speedValue; if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold || denominator < m_DenominatorThreshold ) { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } for( j = 0; j < ImageDimension; j++ ) { update[j] = speedValue * gradient[j] / denominator; if ( globalData ) { globalData->m_SumOfSquaredChange += vnl_math_sqr( update[j] ); } } return update; } /* * Compute update at a specify neighbourhood */ template typename SyNDemonsRegistrationFunction ::PixelType SyNDemonsRegistrationFunction ::ComputeUpdateInv(const NeighborhoodType &it, void * gd, const FloatOffsetType& itkNotUsed(offset)) { PixelType update; unsigned int j; IndexType index = it.GetIndex(); // Get fixed image related information double fixedValue; CovariantVectorType gradient; double gradientSquaredMagnitude = 0; // Note: no need to check the index is within // fixed image buffer. This is done by the external filter. fixedValue = (double) this->GetFixedImage()->GetPixel( index ); double movingValue = (double)this->GetMovingImage()->GetPixel( index ); // if (fixedValue > 0)std::cout << " fxv " << fixedValue << " movingValue " << movingValue << std::endl; // gradient = m_FixedImageGradientCalculator->EvaluateAtIndex( index ); gradient = m_MovingImageGradientCalculator->EvaluateAtIndex( index ); for( j = 0; j < ImageDimension; j++ ) { gradientSquaredMagnitude += vnl_math_sqr( gradient[j] ); } /** * Compute Update. * In the original equation the denominator is defined as (g-f)^2 + grad_mag^2. * However there is a mismatch in units between the two terms. * The units for the second term is intensity^2/mm^2 while the * units for the first term is intensity^2. This mismatch is particularly * problematic when the fixed image does not have unit spacing. * In this implemenation, we normalize the first term by a factor K, * such that denominator = (g-f)^2/K + grad_mag^2 * where K = mean square spacing to compensate for the mismatch in units. */ double speedValue = movingValue - fixedValue; if ( fabs(speedValue) < this->m_RobustnessParameter) speedValue=0; // update the metric GlobalDataStruct *globalData = (GlobalDataStruct *)gd; if ( globalData ) { globalData->m_SumOfSquaredDifference += vnl_math_sqr( speedValue ); globalData->m_NumberOfPixelsProcessed += 1; } double denominator = vnl_math_sqr( speedValue ) / m_Normalizer + gradientSquaredMagnitude; if ( vnl_math_abs(speedValue) < m_IntensityDifferenceThreshold || denominator < m_DenominatorThreshold ) { for( j = 0; j < ImageDimension; j++ ) { update[j] = 0.0; } return update; } for( j = 0; j < ImageDimension; j++ ) { update[j] = speedValue * gradient[j] / denominator; if ( globalData ) { globalData->m_SumOfSquaredChange += vnl_math_sqr( update[j] ); } } return update; } /* * Update the metric and release the per-thread-global data. */ template void SyNDemonsRegistrationFunction ::ReleaseGlobalDataPointer( void *gd ) const { GlobalDataStruct * globalData = (GlobalDataStruct *) gd; m_MetricCalculationLock.Lock(); m_SumOfSquaredDifference += globalData->m_SumOfSquaredDifference; m_NumberOfPixelsProcessed += globalData->m_NumberOfPixelsProcessed; m_SumOfSquaredChange += globalData->m_SumOfSquaredChange; if ( m_NumberOfPixelsProcessed ) { m_Metric = m_SumOfSquaredDifference / static_cast( m_NumberOfPixelsProcessed ); m_RMSChange = vcl_sqrt( m_SumOfSquaredChange / static_cast( m_NumberOfPixelsProcessed ) ); } m_MetricCalculationLock.Unlock(); delete globalData; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkSyNDemonsRegistrationFunction.h000066400000000000000000000237151147325206600267460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSyNDemonsRegistrationFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkSyNDemonsRegistrationFunction_h_ #define _itkSyNDemonsRegistrationFunction_h_ #include "itkPDEDeformableRegistrationFunction.h" #include "itkPoint.h" #include "itkCovariantVector.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkCentralDifferenceImageFunction.h" namespace itk { /** * \class SyNDemonsRegistrationFunction * * This class encapsulate the PDE which drives the demons registration * algorithm. It is used by SyNDemonsRegistrationFilter to compute the * output deformation field which will map a moving image onto a * a fixed image. * * Non-integer moving image values are obtained by using * interpolation. The default interpolator is of type * LinearInterpolateImageFunction. The user may set other * interpolators via method SetMovingImageInterpolator. Note that the input * interpolator must derive from baseclass InterpolateImageFunction. * * This class is templated over the fixed image type, moving image type, * and the deformation field type. * * \warning This filter assumes that the fixed image type, moving image type * and deformation field type all have the same number of dimensions. * * \sa SyNDemonsRegistrationFilter * \ingroup FiniteDifferenceFunctions */ template class ITK_EXPORT SyNDemonsRegistrationFunction : public AvantsPDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField> { public: /** Standard class typedefs. */ typedef SyNDemonsRegistrationFunction Self; typedef PDEDeformableRegistrationFunction< TFixedImage, TMovingImage, TDeformationField > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( SyNDemonsRegistrationFunction, PDEDeformableRegistrationFunction ); /** MovingImage image type. */ typedef typename Superclass::MovingImageType MovingImageType; typedef typename Superclass::MovingImagePointer MovingImagePointer; /** FixedImage image type. */ typedef typename Superclass::FixedImageType FixedImageType; typedef typename Superclass::FixedImagePointer FixedImagePointer; typedef typename FixedImageType::IndexType IndexType; typedef typename FixedImageType::SizeType SizeType; typedef typename FixedImageType::SpacingType SpacingType; /** Deformation field type. */ typedef typename Superclass::DeformationFieldType DeformationFieldType; typedef typename Superclass::DeformationFieldTypePointer DeformationFieldTypePointer; /** Inherit some enums from the superclass. */ itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension); /** Inherit some enums from the superclass. */ typedef typename Superclass::PixelType PixelType; typedef typename Superclass::RadiusType RadiusType; typedef typename Superclass::NeighborhoodType NeighborhoodType; typedef typename Superclass::FloatOffsetType FloatOffsetType; typedef typename Superclass::TimeStepType TimeStepType; /** Interpolator type. */ typedef double CoordRepType; typedef InterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef typename InterpolatorType::PointType PointType; typedef LinearInterpolateImageFunction DefaultInterpolatorType; /** Covariant vector type. */ typedef CovariantVector CovariantVectorType; /** Fixed image gradient calculator type. */ typedef CentralDifferenceImageFunction GradientCalculatorType; typedef typename GradientCalculatorType::Pointer GradientCalculatorPointer; /** Moving image gradient calculator type. */ typedef CentralDifferenceImageFunction MovingImageGradientCalculatorType; typedef typename MovingImageGradientCalculatorType::Pointer MovingImageGradientCalculatorPointer; /** Set the moving image interpolator. */ void SetMovingImageInterpolator( InterpolatorType * ptr ) { m_MovingImageInterpolator = ptr; } /** Get the moving image interpolator. */ InterpolatorType * GetMovingImageInterpolator(void) { return m_MovingImageInterpolator; } /** This class uses a constant timestep of 1. */ virtual TimeStepType ComputeGlobalTimeStep(void * itkNotUsed(GlobalData)) const { return m_TimeStep; } /** Return a pointer to a global data structure that is passed to * this object from the solver at each calculation. */ virtual void *GetGlobalDataPointer() const { GlobalDataStruct *global = new GlobalDataStruct(); global->m_SumOfSquaredDifference = 0.0; global->m_NumberOfPixelsProcessed = 0L; global->m_SumOfSquaredChange = 0; return global; } /** Release memory for global data structure. */ virtual void ReleaseGlobalDataPointer( void *GlobalData ) const; /** Set the object's state before each iteration. */ virtual void InitializeIteration(); /** This method is called by a finite difference solver image filter at * each pixel that does not lie on a data set boundary */ virtual PixelType ComputeUpdate(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)); virtual PixelType ComputeUpdateInv(const NeighborhoodType &neighborhood, void *globalData, const FloatOffsetType &offset = FloatOffsetType(0.0)); /** Get the metric value. The metric value is the mean square difference * in intensity between the fixed image and transforming moving image * computed over the the overlapping region between the two images. */ virtual double GetMetric() const { return m_Metric; } /** Get the rms change in deformation field. */ virtual double GetRMSChange() const { return m_RMSChange; } /** Select if the fixed image or moving image gradient is used for * the computating the demon forces. The fixed image gradient is used * by default. */ virtual void SetUseMovingImageGradient( bool flag ) { m_UseMovingImageGradient = flag; } virtual bool GetUseMovingImageGradient() const { return m_UseMovingImageGradient; } /** Set/Get the threshold below which the absolute difference of * intensity yields a match. When the intensities match between a * moving and fixed image pixel, the update vector (for that * iteration) will be the zero vector. Default is 0.001. */ virtual void SetIntensityDifferenceThreshold(double); virtual double GetIntensityDifferenceThreshold() const; protected: SyNDemonsRegistrationFunction(); ~SyNDemonsRegistrationFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** FixedImage image neighborhood iterator type. */ typedef ConstNeighborhoodIterator FixedImageNeighborhoodIteratorType; /** A global data type for this class of equation. Used to store * information for computing the metric. */ struct GlobalDataStruct { double m_SumOfSquaredDifference; unsigned long m_NumberOfPixelsProcessed; double m_SumOfSquaredChange; }; private: SyNDemonsRegistrationFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Cache fixed image information. */ SpacingType m_FixedImageSpacing; PointType m_FixedImageOrigin; double m_Normalizer; /** Function to compute derivatives of the fixed image. */ GradientCalculatorPointer m_FixedImageGradientCalculator; /** Function to compute derivatives of the moving image. */ MovingImageGradientCalculatorPointer m_MovingImageGradientCalculator; bool m_UseMovingImageGradient; /** Function to interpolate the moving image. */ InterpolatorPointer m_MovingImageInterpolator; /** The global timestep. */ TimeStepType m_TimeStep; /** Threshold below which the denominator term is considered zero. */ double m_DenominatorThreshold; /** Threshold below which two intensity value are assumed to match. */ double m_IntensityDifferenceThreshold; /** The metric value is the mean square difference in intensity between * the fixed image and transforming moving image computed over the * the overlapping region between the two images. */ mutable double m_Metric; mutable double m_SumOfSquaredDifference; mutable unsigned long m_NumberOfPixelsProcessed; mutable double m_RMSChange; mutable double m_SumOfSquaredChange; /** Mutex lock to protect modification to metric. */ mutable SimpleFastMutexLock m_MetricCalculationLock; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSyNDemonsRegistrationFunction.cxx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkVectorParameterizedNeighborhoodOperatorImageFilter.h000066400000000000000000000157241147325206600331230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorParameterizedNeighborhoodOperatorImageFilter.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVectorParameterizedNeighborhoodOperatorImageFilter_h #define __itkVectorParameterizedNeighborhoodOperatorImageFilter_h #include "itkImageToImageFilter.h" #include "itkNeighborhoodOperator.h" #include "itkImage.h" #include "itkImageBoundaryCondition.h" #include "itkGaussianOperator.h" namespace itk { /** \class VectorParameterizedNeighborhoodOperatorImageFilter * \brief Applies a single scalar NeighborhoodOperator to an * itk::Vector image region. * * This filter calculates successive inner products between a single * NeighborhoodOperator and a NeighborhoodIterator, which is swept * across every pixel in an image region. For operators that are * symmetric across their axes, the result is a fast convolution * with the image region. Apply the mirror()'d operator for * non-symmetric NeighborhoodOperators. * * This filter assumes that the input and output images have * pixels which are itk::Vectors of the same vector dimension. * The input NeighbourhoodOperator must have a scalar type * that matches the ValueType of vector pixels. * * To apply a scalar NeighborhoodOperator to a scalar image * use NeighborhoodOperatorImageFilter instead. * * \ingroup ImageFilters * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * \sa NeighborhoodOperatorImageFilter */ template class ITK_EXPORT VectorParameterizedNeighborhoodOperatorImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Standard class typedefs. */ typedef VectorParameterizedNeighborhoodOperatorImageFilter Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro(VectorParameterizedNeighborhoodOperatorImageFilter, ImageToImageFilter); /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef typename TInputImage::Pointer InputImagePointer; typedef typename TOutputImage::Pointer OutputImagePointer; typedef typename TOutputImage::PixelType OutputPixelType; typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::InternalPixelType InputInternalPixelType; typedef typename OutputPixelType::ValueType ScalarValueType; typedef TParamImage ParameterImageType; typedef typename TParamImage::Pointer ParameterImagePointer; typedef typename TParamImage::PixelType ParameterImageTypePixelType; /** Determine image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); /** Image typedef support */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; /** Typedef for generic boundary condition pointer */ typedef ImageBoundaryCondition * ImageBoundaryConditionPointerType; /** Superclass typedefs. */ typedef typename Superclass::OutputImageRegionType OutputImageRegionType; typedef itk::GaussianOperator OperatorType; // Neighborhood /** Sets the operator that is used to filter the image. Note * that the operator is stored as an internal COPY (it * is not part of the pipeline). */ void SetOperator(OperatorType &p) { m_Operator = p; this->Modified(); } /** Allows a user to override the internal boundary condition. Care should be * be taken to ensure that the overriding boundary condition is a persistent * object during the time it is referenced. The overriding condition * can be of a different type than the default type as long as it is * a subclass of ImageBoundaryCondition. */ void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i) { m_BoundsCondition = i; } /** VectorParameterizedNeighborhoodOperatorImageFilter needs a larger input requested * region than the output requested region. As such, * VectorParameterizedNeighborhoodOperatorImageFilter needs to provide an implementation for * GenerateInputRequestedRegion() in order to inform the pipeline * execution model. * * \sa ProcessObject::GenerateInputRequestedRegion() */ virtual void GenerateInputRequestedRegion() throw (InvalidRequestedRegionError); void SetParameterImage( ParameterImagePointer I) { m_ParameterImage = I; } protected: VectorParameterizedNeighborhoodOperatorImageFilter() { m_ParameterImage = NULL; } virtual ~VectorParameterizedNeighborhoodOperatorImageFilter() {} /** VectorParameterizedNeighborhoodOperatorImageFilter can be implemented as a * multithreaded filter. Therefore, this implementation provides a * ThreadedGenerateData() routine which is called for each * processing thread. The output image data is allocated * automatically by the superclass prior to calling * ThreadedGenerateData(). ThreadedGenerateData can only write to * the portion of the output image specified by the parameter * "outputRegionForThread" * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); void PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); } private: VectorParameterizedNeighborhoodOperatorImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented /** Pointer to the internal operator used to filter the image. */ OperatorType m_Operator; /** Pointer to a persistent boundary condition object used * for the image iterator. */ ImageBoundaryConditionPointerType m_BoundsCondition; ParameterImagePointer m_ParameterImage; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkVectorParameterizedNeighborhoodOperatorImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageRegistration/itkVectorParameterizedNeighborhoodOperatorImageFilter.txx000066400000000000000000000130301147325206600335030ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorParameterizedNeighborhoodOperatorImageFilter.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkVectorParameterizedNeighborhoodOperatorImageFilter_txx #define _itkVectorParameterizedNeighborhoodOperatorImageFilter_txx #include "itkVectorParameterizedNeighborhoodOperatorImageFilter.h" #include "itkNeighborhoodAlgorithm.h" #include "itkVectorNeighborhoodInnerProduct.h" #include "itkImageRegionIterator.h" #include "itkConstNeighborhoodIterator.h" #include "itkProgressReporter.h" namespace itk { template void VectorParameterizedNeighborhoodOperatorImageFilter ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError) { // call the superclass' implementation of this method. this should // copy the output requested region to the input requested region Superclass::GenerateInputRequestedRegion(); // get pointers to the input and output InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if ( !inputPtr ) { return; } // get a copy of the input requested region (should equal the output // requested region) typename TInputImage::RegionType inputRequestedRegion; inputRequestedRegion = inputPtr->GetRequestedRegion(); // pad the input requested region by the operator radius inputRequestedRegion.PadByRadius( m_Operator.GetRadius() ); // crop the input requested region at the input's largest possible region if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) { inputPtr->SetRequestedRegion( inputRequestedRegion ); return; } else { // Couldn't crop the region (requested region is outside the largest // possible region). Throw an exception. // store what we tried to request (prior to trying to crop) inputPtr->SetRequestedRegion( inputRequestedRegion ); // build an exception InvalidRequestedRegionError e(__FILE__, __LINE__); OStringStream msg; msg << static_cast(this->GetNameOfClass()) << "::GenerateInputRequestedRegion()"; e.SetLocation(msg.str().c_str()); e.SetDescription("Requested region is (at least partially) outside the largest possible region."); e.SetDataObject(inputPtr); throw e; } } template< class TInputImage, class TOutputImage, class TParamImage> void VectorParameterizedNeighborhoodOperatorImageFilter ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId) { typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator BFC; typedef typename BFC::FaceListType FaceListType; VectorNeighborhoodInnerProduct smartInnerProduct; BFC faceCalculator; FaceListType faceList; // Allocate output OutputImageType *output = this->GetOutput(); const InputImageType *input = this->GetInput(); // Break the input into a series of regions. The first region is free // of boundary conditions, the rest with boundary conditions. Note, // we pass in the input image and the OUTPUT requested region. We are // only concerned with centering the neighborhood operator at the // pixels that correspond to output pixels. faceList = faceCalculator(input, outputRegionForThread, m_Operator.GetRadius()); typename FaceListType::iterator fit; // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); ImageRegionIteratorWithIndex it; // Process non-boundary region and then each of the boundary faces. // These are N-d regions which border the edge of the buffer. ConstNeighborhoodIterator bit; for (fit=faceList.begin(); fit != faceList.end(); ++fit) { bit = ConstNeighborhoodIterator(m_Operator.GetRadius(), input, *fit); it = ImageRegionIteratorWithIndex(output, *fit); bit.GoToBegin(); while ( ! bit.IsAtEnd() ) { if (m_ParameterImage) { // float max=1.45; float param = m_ParameterImage->GetPixel(it.GetIndex()); // if (param > 0.5 || param < 2.0 ) param = 0.0; // if (param < 1./max && param > 0 ) param = 1./max; // if (param > max && param > 0 ) param = max; // if (param < 1.0 && param > 0) param=1.0/param; // std::cout << " param " << param ; if (param <= 0) it.Value() = input->GetPixel(it.GetIndex()); else { m_Operator.SetVariance( param ); m_Operator.CreateDirectional(); it.Value() = smartInnerProduct(bit, m_Operator); } } else it.Value() = smartInnerProduct(bit, m_Operator); ++bit; ++it; progress.CompletedPixel(); } } } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/000077500000000000000000000000001147325206600200605ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/ImageSegmentation/antsAtroposSegmentationImageFilter.h000066400000000000000000000377411147325206600272510ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsAtroposSegmentationImageFilter.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsAtroposSegmentationImageFilter_h #define __antsAtroposSegmentationImageFilter_h #include "itkImageToImageFilter.h" #include "antsListSampleFunction.h" #include "antsListSampleToListSampleFilter.h" #include "itkArray.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkFixedArray.h" #include "itkListSample.h" #include "itkPointSet.h" #include "itkVector.h" #include #include #include #include namespace itk { namespace ants { /** \class AtroposSegmentationImageFilter * \brief Atropos: A Priori Classification with Registration Initialized * Template Assistance * * This filter provides an Expectation-Maximization framework for statistical * segmentation where the intensity profile of each class is modeled as a * mixture model and spatial smoothness is enforced by an MRF prior. * * Initial labeling can be performed by otsu thresholding, kmeans clustering, * a set of user-specified prior probability images, or a prior label image. * If specified, the latter two initialization options are also used as * priors in the MRF update step. * * The assumed labeling is such that classes are assigned consecutive * indices 1, 2, 3, etc. Label 0 is reserved for the background when a * mask is specified. * */ template::ImageDimension>, class TClassifiedImage = TMaskImage> class ITK_EXPORT AtroposSegmentationImageFilter : public ImageToImageFilter { public: /** Standard class typdedefs. */ typedef AtroposSegmentationImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( AtroposSegmentationImageFilter, ImageToImageFilter ); /** Dimension of the images. */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro( ClassifiedImageDimension, unsigned int, TClassifiedImage::ImageDimension ); itkStaticConstMacro( MaskImageDimension, unsigned int, TMaskImage::ImageDimension ); /** Typedef support of input types. */ typedef TInputImage ImageType; typedef typename ImageType::PixelType PixelType; typedef TMaskImage MaskImageType; typedef typename MaskImageType::PixelType MaskLabelType; typedef TClassifiedImage ClassifiedImageType; typedef typename ClassifiedImageType::PixelType LabelType; /** Some convenient typedefs. */ typedef float RealType; typedef Image RealImageType; typedef FixedArray ArrayType; typedef PointSet SparseImageType; /** Mixture model component typedefs */ typedef Array MeasurementVectorType; typedef typename itk::Statistics::ListSample SampleType; typedef SmartPointer SamplePointer; typedef ants::Statistics::ListSampleFunction LikelihoodFunctionType; typedef typename LikelihoodFunctionType::Pointer LikelihoodFunctionPointer; typedef typename LikelihoodFunctionType:: WeightArrayType WeightArrayType; /** Outlier handling typedefs */ typedef ants::Statistics:: ListSampleToListSampleFilter OutlierHandlingFilterType; /** B-spline fitting typedefs */ typedef Vector ScalarType; typedef Image ScalarImageType; typedef PointSet PointSetType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::PointDataImageType ControlPointLatticeType; typedef std::vector ControlPointLatticeContainerType; /** Initialization typedefs */ enum InitializationStrategyType { Random, KMeans, Otsu, PriorProbabilityImages, PriorLabelImage }; typedef std::pair LabelParametersType; typedef std::map LabelParameterMapType; typedef Array ParametersType; enum PosteriorProbabilityFormulationType { Socrates, Plato, Aristotle /*, Zeno, Diogenes, Thales, Democritus*/ }; /** ivars Set/Get functionality */ itkSetClampMacro( NumberOfClasses, unsigned int, 2, NumericTraits::max() ); itkGetConstMacro( NumberOfClasses, unsigned int ); itkSetMacro( MaximumNumberOfIterations, unsigned int ); itkGetConstMacro( MaximumNumberOfIterations, unsigned int ); itkSetMacro( ConvergenceThreshold, RealType ); itkGetConstMacro( ConvergenceThreshold, RealType ); itkGetConstMacro( CurrentConvergenceMeasurement, RealType ); itkGetConstMacro( ElapsedIterations, unsigned int ); itkSetMacro( MRFSmoothingFactor, RealType ); itkGetConstMacro( MRFSmoothingFactor, RealType ); itkSetMacro( MRFRadius, ArrayType ); itkGetConstMacro( MRFRadius, ArrayType ); itkSetMacro( InitializationStrategy, InitializationStrategyType ); itkGetConstMacro( InitializationStrategy, InitializationStrategyType ); itkSetMacro( InitialKMeansParameters, ParametersType ); itkGetConstMacro( InitialKMeansParameters, ParametersType ); itkSetMacro( PosteriorProbabilityFormulation, PosteriorProbabilityFormulationType ); itkGetConstMacro( PosteriorProbabilityFormulation, PosteriorProbabilityFormulationType ); itkSetMacro( UseMixtureModelProportions, bool ); itkGetConstMacro( UseMixtureModelProportions, bool ); itkSetMacro( SplineOrder, unsigned int ); itkGetConstMacro( SplineOrder, unsigned int ); itkSetMacro( NumberOfLevels, ArrayType ); itkGetConstMacro( NumberOfLevels, ArrayType ); itkSetMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( NumberOfIntensityImages, unsigned int ); itkSetMacro( MinimizeMemoryUsage, bool ); itkGetConstMacro( MinimizeMemoryUsage, bool ); itkBooleanMacro( MinimizeMemoryUsage ); void SetMaskImage( const MaskImageType * mask ); const MaskImageType * GetMaskImage() const; itkSetClampMacro( PriorProbabilityWeight, RealType, 0.0, 1.0 ); itkGetConstMacro( PriorProbabilityWeight, RealType ); itkSetClampMacro( ProbabilityThreshold, RealType, 0.0, 1.0 ); itkGetConstMacro( ProbabilityThreshold, RealType ); void SetAdaptiveSmoothingWeight( unsigned int idx, RealType weight ) { RealType clampedWeight = vnl_math_min( NumericTraits::One, vnl_math_max( NumericTraits::Zero, weight ) ); /** * Clamp values between 0 and 1. Also, index [0] corresponds to the * input image and [1]...[n], correspond to the auxiliary images. */ if( idx >= this->m_AdaptiveSmoothingWeights.size() ) { this->m_AdaptiveSmoothingWeights.resize( idx + 1 ); this->m_AdaptiveSmoothingWeights[idx] = clampedWeight; this->Modified(); } if( this->m_AdaptiveSmoothingWeights[idx] != weight ) { this->m_AdaptiveSmoothingWeights[idx] = clampedWeight; this->Modified(); } } RealType GetAdaptiveSmoothingWeight( unsigned int idx ) { /** * [0] corresponds to the input image and [1]...[n], correspond to * the auxiliary images. */ if( idx < this->m_AdaptiveSmoothingWeights.size() ) { return this->m_AdaptiveSmoothingWeights[idx]; } else { return 0; } } void SetPriorLabelParameterMap( LabelParameterMapType m ) { this->m_PriorLabelParameterMap = m; this->Modified(); } void GetPriorLabelParameterMap() { return this->m_PriorLabelParameterMap; } /** * Prior probability images (numbered between 1,...,numberOfClasses) */ void SetPriorProbabilityImage( unsigned int whichClass, RealImageType * prior ); typename RealImageType::Pointer GetPriorProbabilityImage( unsigned int whichClass ) const; void SetPriorLabelImage( const ClassifiedImageType * prior ); const ClassifiedImageType * GetPriorLabelImage() const; /** * Auxiliary images (numbered between 1,...,n) */ void SetIntensityImage( unsigned int which, const ImageType * image ); const ImageType * GetIntensityImage( unsigned int which ) const; /** * Euclidean distance uses Maurer to calculate the distance transform image. * Otherwise use the fast marching filter. The former option is faster but it * for non-Euclidean shapes (such as the cortex), it might be more accurate * to use the latter option. */ itkSetMacro( UseEuclideanDistanceForPriorLabels, bool ); itkGetConstMacro( UseEuclideanDistanceForPriorLabels, bool ); itkBooleanMacro( UseEuclideanDistanceForPriorLabels ); itkSetObjectMacro( OutlierHandlingFilter, OutlierHandlingFilterType ); itkGetObjectMacro( OutlierHandlingFilter, OutlierHandlingFilterType ); void SetLikelihoodFunction( unsigned int n, LikelihoodFunctionType *prob ) { if( n < this->m_MixtureModelComponents.size() && this->m_MixtureModelComponents[n] != prob ) { this->m_MixtureModelComponents[n] = prob; this->Modified(); } else if( n >= this->m_MixtureModelComponents.size() ) { this->m_MixtureModelComponents.resize( n + 1 ); this->m_MixtureModelComponents[n] = prob; this->Modified(); } } LikelihoodFunctionType * GetLikelihoodFunction( unsigned int n ) { if( n < this->m_MixtureModelComponents.size() ) { return this->m_MixtureModelComponents[n].GetPointer(); } else { return NULL; } } /** * Function to facilitate looking at the likelihood image. * Not used internally. */ typename RealImageType::Pointer GetLikelihoodImage( unsigned int ); RealType CalculateLocalPosteriorProbability( RealType, RealType, RealType, RealType, RealType ); typename RealImageType::Pointer GetPosteriorProbabilityImage( unsigned int ); typename RealImageType::Pointer GetSmoothIntensityImageFromPriorImage( unsigned int, unsigned int ); typename RealImageType::Pointer GetDistancePriorProbabilityImage( unsigned int ); typename SampleType::Pointer GetScalarSamples(); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro( SameDimensionCheck1, ( Concept::SameDimension ) ); itkConceptMacro( SameDimensionCheck2, ( Concept::SameDimension ) ); /** End concept checking */ #endif protected: AtroposSegmentationImageFilter(); ~AtroposSegmentationImageFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: AtroposSegmentationImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented void GenerateInitialClassLabeling(); void GenerateInitialClassLabelingWithOtsuThresholding(); void GenerateInitialClassLabelingWithKMeansClustering(); void GenerateInitialClassLabelingWithPriorProbabilityImages(); RealType UpdateClassLabeling(); unsigned int m_NumberOfClasses; unsigned int m_NumberOfIntensityImages; unsigned int m_ElapsedIterations; unsigned int m_MaximumNumberOfIterations; RealType m_CurrentConvergenceMeasurement; RealType m_ConvergenceThreshold; MaskLabelType m_MaskLabel; std::vector m_MixtureModelComponents; Array m_MixtureModelProportions; InitializationStrategyType m_InitializationStrategy; ParametersType m_InitialKMeansParameters; PosteriorProbabilityFormulationType m_PosteriorProbabilityFormulation; bool m_UseMixtureModelProportions; typename OutlierHandlingFilterType::Pointer m_OutlierHandlingFilter; ArrayType m_MRFRadius; RealType m_MRFSmoothingFactor; std::vector m_AdaptiveSmoothingWeights; RealType m_PriorProbabilityWeight; LabelParameterMapType m_PriorLabelParameterMap; RealType m_ProbabilityThreshold; std::vector m_PriorProbabilityImages; std::vector m_PriorProbabilitySparseImages; unsigned int m_SplineOrder; ArrayType m_NumberOfLevels; ArrayType m_NumberOfControlPoints; std::vector m_ControlPointLattices; typename RealImageType::Pointer m_SumDistancePriorProbabilityImage; typename RealImageType::Pointer m_SumPosteriorProbabilityImage; bool m_MinimizeMemoryUsage; bool m_UseEuclideanDistanceForPriorLabels; std::vector m_DistancePriorProbabilityImages; std::vector m_PosteriorProbabilityImages; inline typename RealImageType::IndexType NumberToIndex( unsigned long number, const typename RealImageType::SizeType size ) const { typename RealImageType::IndexType k; k[0] = 1; for ( unsigned int i = 1; i < ImageDimension; i++ ) { k[i] = size[i-1]*k[i-1]; } typename RealImageType::IndexType index; for ( unsigned int i = 0; i < ImageDimension; i++ ) { index[ImageDimension-i-1] = static_cast( number/k[ImageDimension-i-1] ); number %= k[ImageDimension-i-1]; } return index; } inline unsigned long IndexToNumber( typename RealImageType::IndexType k, const typename RealImageType::SizeType size ) const { unsigned long number = k[0]; for ( unsigned int i = 1; i < ImageDimension; i++ ) { unsigned long s = 1; for( unsigned int j = 0; j < i; j++ ) { s *= size[j]; } number += s*k[i]; } return number; } }; } // namespace ants } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsAtroposSegmentationImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsAtroposSegmentationImageFilter.txx000066400000000000000000003130471147325206600276410ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: antsAtroposSegmentationImageFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsAtroposSegmentationImageFilter_txx #define __antsAtroposSegmentationImageFilter_txx #include "antsAtroposSegmentationImageFilter.h" #include "antsGaussianListSampleFunction.h" #include "itkAddImageFilter.h" #include "itkAddConstantToImageFilter.h" #include "itkBinaryContourImageFilter.h" #include "itkBinaryThresholdImageFilter.h" #include "itkBSplineControlPointImageFilter.h" #include "itkCastImageFilter.h" #include "itkConstNeighborhoodIterator.h" #include "itkDistanceToCentroidMembershipFunction.h" #include "itkFastMarchingImageFilter.h" #include "itkImageDuplicator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkIterationReporter.h" #include "itkKdTreeBasedKmeansEstimator.h" #include "itkLabelStatisticsImageFilter.h" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkMinimumDecisionRule2.h" #include "itkOtsuMultipleThresholdsCalculator.h" #include "itkSampleClassifierFilter.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkTimeProbe.h" #include "itkVariableSizeMatrix.h" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkWeightedCentroidKdTreeGenerator.h" #include "vnl/vnl_vector.h" namespace itk { namespace ants { template AtroposSegmentationImageFilter ::AtroposSegmentationImageFilter() { this->ProcessObject::SetNumberOfRequiredInputs( 1 ); this->m_NumberOfIntensityImages = 1; this->m_NumberOfClasses = 3; this->m_MaximumNumberOfIterations = 5; this->m_ElapsedIterations = 0; this->m_ConvergenceThreshold = 0.001; this->m_MaskLabel = NumericTraits::One; this->m_InitializationStrategy = KMeans; this->m_InitialKMeansParameters.SetSize( 0 ); this->m_PosteriorProbabilityFormulation = Socrates; this->m_UseMixtureModelProportions = true; this->m_PriorProbabilityWeight = 0.0; this->m_AdaptiveSmoothingWeights.clear(); this->m_PriorLabelParameterMap.clear(); this->m_ProbabilityThreshold = 0.0; this->m_PriorProbabilityImages.clear(); this->m_PriorProbabilitySparseImages.clear(); this->m_MRFSmoothingFactor = 0.3; this->m_MRFRadius.Fill( 1 ); this->m_SplineOrder = 3; this->m_NumberOfLevels.Fill( 6 ); this->m_NumberOfControlPoints.Fill( this->m_SplineOrder + 1 ); this->m_MinimizeMemoryUsage = false; this->m_UseEuclideanDistanceForPriorLabels = false; this->m_PosteriorProbabilityImages.clear(); this->m_DistancePriorProbabilityImages.clear(); this->m_OutlierHandlingFilter = NULL; } template AtroposSegmentationImageFilter ::~AtroposSegmentationImageFilter() { } template void AtroposSegmentationImageFilter ::SetMaskImage( const MaskImageType * mask ) { this->SetNthInput( 1, const_cast( mask ) ); } template const typename AtroposSegmentationImageFilter ::MaskImageType * AtroposSegmentationImageFilter ::GetMaskImage() const { const MaskImageType * maskImage = dynamic_cast( this->ProcessObject::GetInput( 1 ) ); return maskImage; } template void AtroposSegmentationImageFilter ::SetPriorLabelImage( const ClassifiedImageType * prior ) { this->SetNthInput( 2, const_cast( prior ) ); } template const typename AtroposSegmentationImageFilter ::ClassifiedImageType * AtroposSegmentationImageFilter ::GetPriorLabelImage() const { const ClassifiedImageType * prior = dynamic_cast( this->ProcessObject::GetInput( 2 ) ); return prior; } template void AtroposSegmentationImageFilter ::SetPriorProbabilityImage( unsigned int whichClass, RealImageType * priorImage ) { if( whichClass < 1 || whichClass > this->m_NumberOfClasses ) { itkExceptionMacro( "The requested prior probability image = " << whichClass << " should be in the range [1, " << this->m_NumberOfClasses << "]" ); } if( this->m_MinimizeMemoryUsage ) { // To make matters simpler, we force the index to be zero // for each priorImage image. typename RealImageType::IndexType startIndex = priorImage->GetRequestedRegion().GetIndex(); typename SparseImageType::Pointer sparsePriorImage = SparseImageType::New(); sparsePriorImage->Initialize(); unsigned long count = 0; ImageRegionConstIteratorWithIndex It( priorImage, priorImage->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( It.Get() > this->m_ProbabilityThreshold ) { typename RealImageType::IndexType index = It.GetIndex(); for( unsigned int d = 0; d < ImageDimension; d++ ) { index[d] -= startIndex[d]; } unsigned long number = this->IndexToNumber( index, priorImage->GetRequestedRegion().GetSize() ); typename SparseImageType::PointType imageNumberIndex; imageNumberIndex[0] = number; sparsePriorImage->SetPoint( count, imageNumberIndex ); sparsePriorImage->SetPointData( count, It.Get() ); count++; } } if( this->m_PriorProbabilitySparseImages.size() < whichClass ) { this->m_PriorProbabilitySparseImages.resize( whichClass ); } this->m_PriorProbabilitySparseImages[whichClass-1] = sparsePriorImage; } else { if( this->m_PriorProbabilityImages.size() < whichClass ) { this->m_PriorProbabilityImages.resize( whichClass ); } this->m_PriorProbabilityImages[whichClass-1] = priorImage; } } template typename AtroposSegmentationImageFilter ::RealImageType::Pointer AtroposSegmentationImageFilter ::GetPriorProbabilityImage( unsigned int whichClass ) const { if( whichClass < 1 || whichClass > this->m_NumberOfClasses ) { itkExceptionMacro( "The requested prior probability image = " << whichClass << " should be in the range [1, " << this->m_NumberOfClasses << "]" ); } if( this->m_InitializationStrategy != PriorProbabilityImages ) { return NULL; } if( ( this->m_MinimizeMemoryUsage && this->m_PriorProbabilitySparseImages.size() != this->m_NumberOfClasses ) || ( !this->m_MinimizeMemoryUsage && this->m_PriorProbabilityImages.size() != this->m_NumberOfClasses ) ) { itkExceptionMacro( "The number of prior probability images does not " << "equal the number of classes." ); } if( this->m_MinimizeMemoryUsage ) { // To make matters simpler, we forced the prior probability images // to all have indices of zeros. typename RealImageType::RegionType region; region.SetSize( this->GetIntensityImage( 0 )->GetRequestedRegion().GetSize() ); typename RealImageType::RegionType::IndexType index; for( unsigned int d = 0; d < ImageDimension; d++ ) { index[d] = 0; } region.SetIndex( index ); typename RealImageType::Pointer priorImage = RealImageType::New(); priorImage->SetRegions( region ); priorImage->SetOrigin( this->GetIntensityImage( 0 )->GetOrigin() ); priorImage->SetDirection( this->GetIntensityImage( 0 )->GetDirection() ); priorImage->SetSpacing( this->GetIntensityImage( 0 )->GetSpacing() ); priorImage->Allocate(); priorImage->FillBuffer( 0 ); typename SparseImageType::Pointer sparsePriorImage = this->m_PriorProbabilitySparseImages[whichClass-1]; typename SparseImageType::PointsContainer::ConstIterator It = sparsePriorImage->GetPoints()->Begin(); typename SparseImageType::PointDataContainer::ConstIterator ItD = sparsePriorImage->GetPointData()->Begin(); while( It != sparsePriorImage->GetPoints()->End() ) { unsigned long number = static_cast( It.Value()[0] ); typename RealImageType::IndexType index = this->NumberToIndex( number, priorImage->GetRequestedRegion().GetSize() ); priorImage->SetPixel( index, ItD.Value() ); ++It; ++ItD; } return priorImage; } else { return this->m_PriorProbabilityImages[whichClass-1]; } } template void AtroposSegmentationImageFilter ::SetIntensityImage( unsigned int which, const ImageType * image ) { if( which == 0 ) { this->SetInput( image ); } if( which > this->m_NumberOfIntensityImages - 1 ) { this->m_NumberOfIntensityImages = which + 1; } this->SetNthInput( 2 + this->m_NumberOfClasses + which, const_cast( image ) ); } template const typename AtroposSegmentationImageFilter ::ImageType * AtroposSegmentationImageFilter ::GetIntensityImage( unsigned int which ) const { const ImageType *image; if( which == 0 ) { image = dynamic_cast( this->ProcessObject::GetInput( 0 ) ); } else if( which > 0 && which <= this->m_NumberOfIntensityImages ) { image = dynamic_cast( this->ProcessObject::GetInput( 2 + this->m_NumberOfClasses + which ) ); } else { itkExceptionMacro( "Image " << which << " is outside the range " << "[1+m_NumberOfClasses...1+m_NumberOfClasses+m_NumberOfIntensityImages]." ) } return image; } template void AtroposSegmentationImageFilter ::GenerateData() { /** * Assign Gaussian likelihood functions if mixture model components are absent */ typedef ants::Statistics::GaussianListSampleFunction LikelihoodType; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { if( !this->GetLikelihoodFunction( n ) ) { typename LikelihoodType::Pointer gaussianLikelihood = LikelihoodType::New(); this->SetLikelihoodFunction( n, gaussianLikelihood ); } } /** * Initialize the class labeling and the likelihood parameters */ this->GenerateInitialClassLabeling(); /** * Iterate until convergence or iterative exhaustion. */ IterationReporter reporter( this, 0, 1 ); bool isConverged = false; RealType probabilityNew = 0.0; RealType probabilityOld = NumericTraits::NonpositiveMin(); unsigned int iteration = 0; while( !isConverged && iteration++ < this->m_MaximumNumberOfIterations ) { /** * Clear the current posterior probability images to force * recalculation of the posterior probability images. */ this->m_PosteriorProbabilityImages.clear(); TimeProbe timer; timer.Start(); probabilityNew = this->UpdateClassLabeling(); timer.Stop(); this->m_CurrentConvergenceMeasurement = probabilityNew - probabilityOld; if( this->m_CurrentConvergenceMeasurement < this->m_ConvergenceThreshold ) { isConverged = true; } probabilityOld = probabilityNew; itkDebugMacro( "Iteration: " << probabilityNew ); this->m_ElapsedIterations++; reporter.CompletedStep(); } } template void AtroposSegmentationImageFilter ::GenerateInitialClassLabeling() { this->AllocateOutputs(); this->GetOutput()->FillBuffer( NumericTraits::Zero ); switch( this->m_InitializationStrategy ) { case Random: { typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType; typename GeneratorType::Pointer generator = GeneratorType::New(); ImageRegionIterator It( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { LabelType label = generator->GetIntegerVariate( this->m_NumberOfClasses - 1 ) + 1; It.Set( label ); } break; } case KMeans: default: { this->GenerateInitialClassLabelingWithKMeansClustering(); break; } case Otsu: { this->GenerateInitialClassLabelingWithOtsuThresholding(); break; } case PriorProbabilityImages: { this->GenerateInitialClassLabelingWithPriorProbabilityImages(); break; } case PriorLabelImage: { typedef ImageDuplicator DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage( this->GetPriorLabelImage() ); duplicator->Update(); this->SetNthOutput( 0, duplicator->GetOutput() ); break; } } /** * Calculate the initial parameters of the mixture model from the * initial labeling, i.e. the proportion, mean, and covariance for each label. */ this->m_MixtureModelProportions.SetSize( this->m_NumberOfClasses ); unsigned int totalSampleSize = 0; std::vector samples; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename SampleType::Pointer sample = SampleType::New(); sample->SetMeasurementVectorSize( this->m_NumberOfIntensityImages ); samples.push_back( sample ); } /** * Accumulate the sample array for all labels. Also accumulate the * prior probability weights, if applicable. */ ImageRegionIteratorWithIndex ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( ItO.GoToBegin(); !ItO.IsAtEnd(); ++ItO ) { LabelType label = ItO.Get(); if( label == 0 ) { continue; } typename SampleType::MeasurementVectorType measurement; ::itk::Statistics::MeasurementVectorTraits::SetLength( measurement, this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { measurement[i] = this->GetIntensityImage( i )->GetPixel( ItO.GetIndex() ); } samples[label-1]->PushBack( measurement ); } /** * Create the weight array now that we know the sample sizes. */ Array count( this->m_NumberOfClasses ); count.Fill( 0 ); std::vector weights; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { totalSampleSize += samples[n]->Size(); WeightArrayType weightArray( samples[n]->Size() ); weightArray.Fill( 1.0 ); weights.push_back( weightArray ); } if( this->m_InitializationStrategy == PriorProbabilityImages ) { for( ItO.GoToBegin(); !ItO.IsAtEnd(); ++ItO ) { LabelType label = ItO.Get(); if( label == 0 ) { continue; } typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( label ); weights[label-1].SetElement( count[label-1]++, priorProbabilityImage->GetPixel( ItO.GetIndex() ) ); } } for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { this->m_MixtureModelComponents[n]->SetWeights( &weights[n] ); this->m_MixtureModelComponents[n]->SetInputListSample( samples[n] ); if( this->m_UseMixtureModelProportions ) { this->m_MixtureModelProportions[n] = static_cast( samples[n]->Size() ) / static_cast( totalSampleSize ); } else { this->m_MixtureModelProportions[n] = 1.0 / static_cast( this->m_NumberOfClasses ); } this->m_MixtureModelComponents[n]->ClearInputListSample(); } for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { ControlPointLatticeContainerType container; this->m_ControlPointLattices.push_back( container ); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { this->m_ControlPointLattices[i].push_back( NULL ); } } } template void AtroposSegmentationImageFilter ::GenerateInitialClassLabelingWithPriorProbabilityImages() { // We first normalize prior probability images by keeping track of // 1. the sum of the prior probabilities at each pixel // 2. the max prior probability value // 3. which prior probability image corresponds to the max prior value typename RealImageType::Pointer sumPriorProbabilityImage = RealImageType::New(); sumPriorProbabilityImage->SetOrigin( this->GetInput()->GetOrigin() ); sumPriorProbabilityImage->SetSpacing( this->GetInput()->GetSpacing() ); sumPriorProbabilityImage->SetRegions( this->GetInput()->GetRequestedRegion() ); sumPriorProbabilityImage->SetDirection( this->GetInput()->GetDirection() ); sumPriorProbabilityImage->Allocate(); sumPriorProbabilityImage->FillBuffer( 0 ); typename RealImageType::Pointer maxPriorProbabilityImage = RealImageType::New(); maxPriorProbabilityImage->SetOrigin( this->GetInput()->GetOrigin() ); maxPriorProbabilityImage->SetSpacing( this->GetInput()->GetSpacing() ); maxPriorProbabilityImage->SetRegions( this->GetInput()->GetRequestedRegion() ); maxPriorProbabilityImage->SetDirection( this->GetInput()->GetDirection() ); maxPriorProbabilityImage->Allocate(); maxPriorProbabilityImage->FillBuffer( 0 ); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( n + 1 ); typedef AddImageFilter AdderType; typename AdderType::Pointer adder = AdderType::New(); adder->SetInput1( sumPriorProbabilityImage ); adder->SetInput2( priorProbabilityImage ); adder->Update(); sumPriorProbabilityImage = adder->GetOutput(); ImageRegionIteratorWithIndex ItP( priorProbabilityImage, priorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItM( maxPriorProbabilityImage, maxPriorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); ItP.GoToBegin(); ItM.GoToBegin(); ItO.GoToBegin(); while( !ItP.IsAtEnd() ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItP.GetIndex() ) == this->m_MaskLabel ) { if( ItP.Get() > ItM.Get() ) { ItM.Set( ItP.Get() ); ItO.Set( n + 1 ); } else if( ItP.Get() == ItM.Get() ) { if( n == 0 ) { ItO.Set( 1 ); } else // if maximum probabilities are the same, randomly select one { typedef itk::Statistics::MersenneTwisterRandomVariateGenerator GeneratorType; typename GeneratorType::Pointer generator = GeneratorType::New(); if( generator->GetIntegerVariate( 1 ) ) { ItO.Set( n + 1 ); } } } } ++ItP; ++ItM; ++ItO; } } // Now we can normalize each prior probability image by dividing by the sum for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( n + 1 ); ImageRegionIteratorWithIndex ItP( priorProbabilityImage, priorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItS( sumPriorProbabilityImage, sumPriorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItM( maxPriorProbabilityImage, maxPriorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); ItP.GoToBegin(); ItS.GoToBegin(); ItM.GoToBegin(); ItO.GoToBegin(); while( !ItP.IsAtEnd() ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItP.GetIndex() ) == this->m_MaskLabel ) { if( ItM.Get() <= this->m_ProbabilityThreshold || ItS.Get() == 0.0 ) { ItO.Set( NumericTraits::Zero ); ItP.Set( NumericTraits::Zero ); } else { ItP.Set( ItP.Get() / ItS.Get() ); } } ++ItP; ++ItS; ++ItM; ++ItO; } this->SetPriorProbabilityImage( n + 1, priorProbabilityImage ); } /** * Set the initial output to be the prior label image. This way we can * propogate the segmentation solution to regions of non-zero probability * but where the mask exists. */ typedef ImageDuplicator DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage( this->GetOutput() ); duplicator->Update(); this->SetPriorLabelImage( duplicator->GetOutput() ); } template void AtroposSegmentationImageFilter ::GenerateInitialClassLabelingWithOtsuThresholding() { RealType maxValue = NumericTraits::min(); RealType minValue = NumericTraits::max(); ImageRegionConstIteratorWithIndex ItI( this->GetInput(), this->GetInput()->GetRequestedRegion() ); for( ItI.GoToBegin(); !ItI.IsAtEnd(); ++ItI ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) { if ( ItI.Get() < minValue ) { minValue = ItI.Get(); } else if ( ItI.Get() > maxValue ) { maxValue = ItI.Get(); } } } typedef LabelStatisticsImageFilter StatsType; typename StatsType::Pointer stats = StatsType::New(); stats->SetInput( this->GetInput() ); if( this->GetMaskImage() ) { stats->SetLabelInput( const_cast( this->GetMaskImage() ) ); } else { typename MaskImageType::Pointer maskImage = MaskImageType::New(); maskImage->SetOrigin( this->GetOutput()->GetOrigin() ); maskImage->SetSpacing( this->GetOutput()->GetSpacing() ); maskImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); maskImage->SetDirection( this->GetOutput()->GetDirection() ); maskImage->Allocate(); maskImage->FillBuffer( this->m_MaskLabel ); stats->SetLabelInput( maskImage ); } stats->UseHistogramsOn(); stats->SetHistogramParameters( 200, minValue, maxValue ); stats->Update(); typedef OtsuMultipleThresholdsCalculator OtsuType; typename OtsuType::Pointer otsu = OtsuType::New(); otsu->SetInputHistogram( stats->GetHistogram( this->m_MaskLabel ) ); otsu->SetNumberOfThresholds( this->m_NumberOfClasses - 1 ); otsu->Update(); typename OtsuType::OutputType thresholds = otsu->GetOutput(); ImageRegionIterator ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( ItI.GoToBegin(), ItO.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItO ) { LabelType label = NumericTraits::Zero; if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) { if( ItI.Get() < thresholds[0] ) { label = NumericTraits::One; } else { bool thresholdFound = false; for ( unsigned int i = 1; i < thresholds.size(); i++ ) { if( ItI.Get() >= thresholds[i-1] && ItI.Get() <= thresholds[i] ) { label = static_cast( i+1 ); thresholdFound = true; break; } } if( !thresholdFound ) { label = static_cast( thresholds.size() + 1 ); } } } ItO.Set( label ); } } template void AtroposSegmentationImageFilter ::GenerateInitialClassLabelingWithKMeansClustering() { /** * We first perform kmeans on the first image and use the results to * seed the second run of kmeans using all the images. */ typedef LabelStatisticsImageFilter StatsType; typename StatsType::Pointer stats = StatsType::New(); stats->SetInput( this->GetInput() ); if( this->GetMaskImage() ) { stats->SetLabelInput( const_cast( this->GetMaskImage() ) ); } else { typename MaskImageType::Pointer maskImage = MaskImageType::New(); maskImage->SetOrigin( this->GetOutput()->GetOrigin() ); maskImage->SetSpacing( this->GetOutput()->GetSpacing() ); maskImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); maskImage->SetDirection( this->GetOutput()->GetDirection() ); maskImage->Allocate(); maskImage->FillBuffer( this->m_MaskLabel ); stats->SetLabelInput( maskImage ); } stats->UseHistogramsOff(); stats->Update(); RealType minValue = stats->GetMinimum( this->m_MaskLabel ); RealType maxValue = stats->GetMaximum( this->m_MaskLabel ); /** * The code below can be replaced by itkListSampleToImageFilter when we * migrate over to the Statistics classes current in the Review/ directory. */ typename SampleType::Pointer sample = SampleType::New(); sample->SetMeasurementVectorSize( 1 ); ImageRegionConstIteratorWithIndex ItI( this->GetInput(), this->GetInput()->GetRequestedRegion() ); for( ItI.GoToBegin(); !ItI.IsAtEnd(); ++ItI ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) { typename SampleType::MeasurementVectorType measurement; measurement.SetSize( 1 ); measurement[0] = ItI.Get(); sample->PushBack( measurement ); } } typedef itk::Statistics::WeightedCentroidKdTreeGenerator TreeGeneratorType; typename TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New(); treeGenerator->SetSample( sample ); treeGenerator->SetBucketSize( 16 ); treeGenerator->Update(); typedef typename TreeGeneratorType::KdTreeType TreeType; typedef itk::Statistics::KdTreeBasedKmeansEstimator EstimatorType; typename EstimatorType::Pointer estimator = EstimatorType::New(); estimator->SetKdTree( treeGenerator->GetOutput() ); estimator->SetMaximumIteration( 200 ); estimator->SetCentroidPositionChangesThreshold( 0.0 ); typedef typename EstimatorType::ParametersType ParametersType; ParametersType initialMeans( this->m_NumberOfClasses ); /** * If the initial KMeans parameters are not set, guess initial class means by * dividing the dynamic range of the first image into equal intervals. */ if( this->m_InitialKMeansParameters.Size() == this->m_NumberOfClasses ) { for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { initialMeans[n] = this->m_InitialKMeansParameters[n]; } } else { for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { initialMeans[n] = minValue + ( maxValue - minValue ) * ( static_cast( n ) + 0.5 ) / static_cast( this->m_NumberOfClasses ); } } estimator->SetParameters( initialMeans ); estimator->StartOptimization(); /** * Classify the samples */ typedef itk::Statistics::MinimumDecisionRule2 DecisionRuleType; typename DecisionRuleType::Pointer decisionRule = DecisionRuleType::New(); typedef itk::Statistics::SampleClassifierFilter ClassifierType; typename ClassifierType::Pointer classifier = ClassifierType::New(); classifier->SetDecisionRule( decisionRule ); classifier->SetInput( sample ); classifier->SetNumberOfClasses( this->m_NumberOfClasses ); typename ClassifierType::ClassLabelVectorObjectType::Pointer classLabels = ClassifierType::ClassLabelVectorObjectType::New(); classifier->SetClassLabels( classLabels ); typename ClassifierType::ClassLabelVectorType &classLabelVector = classLabels->Get(); /** * Order the cluster means so that the lowest mean of the input image * corresponds to label '1', the second lowest to label '2', etc. */ std::vector estimatorParameters; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { estimatorParameters.push_back( estimator->GetParameters()[n] ); } std::sort( estimatorParameters.begin(), estimatorParameters.end() ); typedef itk::Statistics::DistanceToCentroidMembershipFunction MembershipFunctionType; typename ClassifierType::MembershipFunctionVectorObjectType::Pointer membershipFunctions = ClassifierType::MembershipFunctionVectorObjectType::New(); typename ClassifierType::MembershipFunctionVectorType &membershipFunctionsVector = membershipFunctions->Get(); classifier->SetMembershipFunctions( membershipFunctions ); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename MembershipFunctionType::Pointer membershipFunction = MembershipFunctionType::New(); membershipFunction->SetMeasurementVectorSize( sample->GetMeasurementVectorSize() ); typename MembershipFunctionType::CentroidType centroid; ::itk::Statistics::MeasurementVectorTraits::SetLength( centroid, sample->GetMeasurementVectorSize() ); centroid[0] = estimatorParameters[n]; membershipFunction->SetCentroid( centroid ); membershipFunctionsVector.push_back( membershipFunction.GetPointer() ); classLabelVector.push_back( static_cast( n + 1 ) ); } classifier->Update(); /** * Classify the voxels */ typedef typename ClassifierType::MembershipSampleType ClassifierOutputType; typedef typename ClassifierOutputType::ConstIterator LabelIterator; ImageRegionIteratorWithIndex ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); ItO.GoToBegin(); LabelIterator it = classifier->GetOutput()->Begin(); while( it != classifier->GetOutput()->End() ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { ItO.Set( it.GetClassLabel() ); ++it; } else { ItO.Set( NumericTraits::Zero ); } ++ItO; } /** * If there are more than one intensity images, use the results from the first * kmeans grouping to seed a second invoking of the algorithm using both * the input image and the auxiliary images. */ if( this->m_NumberOfIntensityImages > 1 ) { VariableSizeMatrix classMeanValues; classMeanValues.SetSize( this->m_NumberOfIntensityImages, this->m_NumberOfClasses ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { typedef LabelStatisticsImageFilter StatsType; typename StatsType::Pointer stats = StatsType::New(); stats->SetInput( this->GetIntensityImage( i ) ); stats->SetLabelInput( this->GetOutput() ); stats->UseHistogramsOff(); stats->Update(); for( unsigned int j = 0; j < this->m_NumberOfClasses; j++ ) { classMeanValues( i, j ) = stats->GetMean( j + 1 ); } } typedef itk::Statistics::WeightedCentroidKdTreeGenerator TreeGeneratorType; typedef typename TreeGeneratorType::KdTreeType TreeType; typedef itk::Statistics::KdTreeBasedKmeansEstimator EstimatorType; typedef typename EstimatorType::ParametersType ParametersType; typename EstimatorType::Pointer estimator = EstimatorType::New(); ParametersType initialMeans( this->m_NumberOfClasses * ( this->m_NumberOfIntensityImages ) ); initialMeans.Fill( 0.0 ); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { initialMeans[this->m_NumberOfIntensityImages * n + i] = classMeanValues( i, n ); } } typename SampleType::Pointer sample = SampleType::New(); sample->SetMeasurementVectorSize( this->m_NumberOfIntensityImages ); for( ItO.GoToBegin(); !ItO.IsAtEnd(); ++ItO ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { typename SampleType::MeasurementVectorType measurement; measurement.SetSize( this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { measurement[i] = this->GetIntensityImage( i )->GetPixel( ItO.GetIndex() ); } sample->PushBack( measurement ); } } typename TreeGeneratorType::Pointer treeGenerator = TreeGeneratorType::New(); treeGenerator->SetSample( sample ); treeGenerator->SetBucketSize( 16 ); treeGenerator->Update(); estimator->SetParameters( initialMeans ); estimator->SetKdTree( treeGenerator->GetOutput() ); estimator->SetMaximumIteration( 200 ); estimator->SetCentroidPositionChangesThreshold( 0.0 ); estimator->StartOptimization(); /** * Classify the samples */ typedef itk::Statistics::MinimumDecisionRule2 DecisionRuleType; typename DecisionRuleType::Pointer decisionRule = DecisionRuleType::New(); typedef itk::Statistics::SampleClassifierFilter ClassifierType; typename ClassifierType::Pointer classifier = ClassifierType::New(); classifier->SetDecisionRule( decisionRule ); classifier->SetInput( sample ); classifier->SetNumberOfClasses( this->m_NumberOfClasses ); typename ClassifierType::ClassLabelVectorObjectType::Pointer classLabels = ClassifierType::ClassLabelVectorObjectType::New(); classifier->SetClassLabels( classLabels ); typename ClassifierType::ClassLabelVectorType &classLabelVector = classLabels->Get(); /** * Order the cluster means so that the lowest mean of the input image * corresponds to label '1', the second lowest to label '2', etc. */ std::vector estimatorParameters; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { estimatorParameters.push_back( estimator->GetParameters()[n] ); } std::sort( estimatorParameters.begin(), estimatorParameters.end() ); typedef itk::Statistics::DistanceToCentroidMembershipFunction MembershipFunctionType; typename ClassifierType::MembershipFunctionVectorObjectType::Pointer membershipFunctions = ClassifierType::MembershipFunctionVectorObjectType::New(); typename ClassifierType::MembershipFunctionVectorType &membershipFunctionsVector = membershipFunctions->Get(); classifier->SetMembershipFunctions( membershipFunctions ); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename MembershipFunctionType::Pointer membershipFunction = MembershipFunctionType::New(); membershipFunction->SetMeasurementVectorSize( sample->GetMeasurementVectorSize() ); typename MembershipFunctionType::CentroidType centroid; ::itk::Statistics::MeasurementVectorTraits::SetLength( centroid, sample->GetMeasurementVectorSize() ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { centroid[i] = estimator->GetParameters()[ ( this->m_NumberOfIntensityImages ) * n + i]; } membershipFunction->SetCentroid( centroid ); membershipFunctionsVector.push_back( membershipFunction.GetPointer() ); classLabelVector.push_back( static_cast( n + 1 ) ); } classifier->Update(); /** * Classify the voxels */ typedef typename ClassifierType::MembershipSampleType ClassifierOutputType; typedef typename ClassifierOutputType::ConstIterator LabelIterator; ItO.GoToBegin(); LabelIterator it = classifier->GetOutput()->Begin(); while( it != classifier->GetOutput()->End() ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { ItO.Set( it.GetClassLabel() ); ++it; } else { ItO.Set( NumericTraits::Zero ); } ++ItO; } } } template typename AtroposSegmentationImageFilter ::RealType AtroposSegmentationImageFilter ::UpdateClassLabeling() { typename RealImageType::Pointer maxPosteriorProbabilityImage = RealImageType::New(); maxPosteriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); maxPosteriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); maxPosteriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); maxPosteriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); maxPosteriorProbabilityImage->Allocate(); maxPosteriorProbabilityImage->FillBuffer( NumericTraits::Zero ); typename ClassifiedImageType::Pointer maxLabels = ClassifiedImageType::New(); maxLabels->SetRegions( this->GetOutput()->GetRequestedRegion() ); maxLabels->SetOrigin( this->GetOutput()->GetOrigin() ); maxLabels->SetSpacing( this->GetOutput()->GetSpacing() ); maxLabels->SetDirection( this->GetOutput()->GetDirection() ); maxLabels->Allocate(); maxLabels->FillBuffer( NumericTraits::Zero ); typename RealImageType::Pointer weightedPriorProbabilityImage = RealImageType::New(); weightedPriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); weightedPriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); weightedPriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); weightedPriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); weightedPriorProbabilityImage->Allocate(); weightedPriorProbabilityImage->FillBuffer( NumericTraits::Zero ); Array sumPosteriors( this->m_NumberOfClasses ); sumPosteriors.Fill( 0.0 ); typename SampleType::Pointer sample = SampleType::New(); sample = this->GetScalarSamples(); unsigned long totalSampleSize = sample->Size(); for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { typename RealImageType::Pointer posteriorProbabilityImage = this->GetPosteriorProbabilityImage( n + 1 ); ImageRegionIteratorWithIndex ItO( maxLabels, maxLabels->GetRequestedRegion() ); ImageRegionConstIterator ItP( posteriorProbabilityImage, posteriorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItM( maxPosteriorProbabilityImage, maxPosteriorProbabilityImage->GetRequestedRegion() ); WeightArrayType weights( totalSampleSize ); unsigned long count = 0; ItP.GoToBegin(); ItM.GoToBegin(); ItO.GoToBegin(); while( !ItP.IsAtEnd() ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { RealType posteriorProbability = ItP.Get(); weights.SetElement( count++, posteriorProbability ); if( posteriorProbability > this->m_ProbabilityThreshold && posteriorProbability >= ItM.Get() ) { ItM.Set( posteriorProbability ); ItO.Set( static_cast( n + 1 ) ); } sumPosteriors[n] += posteriorProbability; } ++ItP; ++ItM; ++ItO; } this->m_MixtureModelComponents[n]->SetWeights( &weights ); this->m_MixtureModelComponents[n]->SetInputListSample( sample ); this->m_MixtureModelComponents[n]->ClearInputListSample(); if( this->m_UseMixtureModelProportions ) { /** * Perform the following calculation as a preprocessing step to update the * class proportions. */ typename RealImageType::Pointer distancePriorProbabilityImage = this->GetDistancePriorProbabilityImage( n + 1 ); typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( n + 1 ); ImageRegionIteratorWithIndex ItW( weightedPriorProbabilityImage, weightedPriorProbabilityImage->GetRequestedRegion() ); for( ItW.GoToBegin(); !ItW.IsAtEnd(); ++ItW ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItW.GetIndex() ) == this->m_MaskLabel ) { RealType priorProbability = 0.0; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItW.GetIndex() ); } if( priorProbability <= this->m_ProbabilityThreshold && distancePriorProbabilityImage ) { priorProbability = distancePriorProbabilityImage->GetPixel( ItW.GetIndex() ); } } else { priorProbability = 1.0; } ItW.Set( ItW.Get() + this->m_MixtureModelProportions[n] * priorProbability ); } } } } this->SetNthOutput( 0, maxLabels ); if( this->m_UseMixtureModelProportions ) { /** * Update the class proportions */ for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { RealType denominator = 0.0; typename RealImageType::Pointer distancePriorProbabilityImage = this->GetDistancePriorProbabilityImage( n + 1 ); typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( n + 1 ); ImageRegionIteratorWithIndex ItW( weightedPriorProbabilityImage, weightedPriorProbabilityImage->GetRequestedRegion() ); for( ItW.GoToBegin(); !ItW.IsAtEnd(); ++ItW ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItW.GetIndex() ) == this->m_MaskLabel ) { RealType priorProbability = 0.0; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItW.GetIndex() ); } if( priorProbability <= this->m_ProbabilityThreshold && distancePriorProbabilityImage ) { priorProbability = distancePriorProbabilityImage->GetPixel( ItW.GetIndex() ); } } else { priorProbability = 1.0; } if( ItW.Get() > 0.0 ) { denominator += ( priorProbability / ItW.Get() ); } } } if( denominator > 0.0 ) { this->m_MixtureModelProportions[n] = sumPosteriors[n] / denominator; } else { this->m_MixtureModelProportions[n] = 0.0; } } } /** * Calculate the maximum posterior probability sum over the region of * interest. This quantity should increase at each iteration. */ RealType maxPosteriorSum = 0.0; ImageRegionIteratorWithIndex ItM( maxPosteriorProbabilityImage, maxPosteriorProbabilityImage->GetRequestedRegion() ); for( ItM.GoToBegin(); !ItM.IsAtEnd(); ++ItM ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItM.GetIndex() ) == this->m_MaskLabel ) { maxPosteriorSum += ItM.Get(); } } return maxPosteriorSum / static_cast( totalSampleSize ); } template typename AtroposSegmentationImageFilter ::SamplePointer AtroposSegmentationImageFilter ::GetScalarSamples() { /** * This function returns a set of samples for each class such that each * measurement vector of the returned SampleType corresponds to a single * voxel across the set of auxiliary and input images. */ std::vector samples; /** * Accumulate the samples in individual SampleTypes. This allows us to * "filter" the samples of each auxiliary/input image. This filtering * could including outlier winsorization, log transformation, and/or * converting vector/tensor auxiliary images to scalar data for * modeling. */ for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { typename SampleType::Pointer sample = SampleType::New(); sample->SetMeasurementVectorSize( 1 ); samples.push_back( sample ); } ImageRegionIteratorWithIndex ItO( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( ItO.GoToBegin(); !ItO.IsAtEnd(); ++ItO ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { typename SampleType::MeasurementVectorType measurement; ::itk::Statistics::MeasurementVectorTraits::SetLength( measurement, 1 ); measurement.SetSize( 1 ); measurement[0] = this->GetIntensityImage( i )->GetPixel( ItO.GetIndex() ); samples[i]->PushBack( measurement ); } } } /** * Simultaneously filter the samples and accumulate for return. */ typename SampleType::Pointer scalarSamples = SampleType::New(); scalarSamples->SetMeasurementVectorSize( this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { typename SampleType::Pointer univariateSamples = SampleType::New(); univariateSamples->SetMeasurementVectorSize( 1 ); if( this->m_OutlierHandlingFilter ) { this->m_OutlierHandlingFilter->SetInput( samples[i] ); this->m_OutlierHandlingFilter->Update(); univariateSamples = this->m_OutlierHandlingFilter->GetOutput(); } else { univariateSamples = samples[i]; } if( i == 0 ) { typename SampleType::ConstIterator It = univariateSamples->Begin(); while( It != univariateSamples->End() ) { typename SampleType::MeasurementVectorType measurement; measurement.SetSize( this->m_NumberOfIntensityImages ); ::itk::Statistics::MeasurementVectorTraits::SetLength( measurement, this->m_NumberOfIntensityImages ); measurement[0] = It.GetMeasurementVector()[0]; scalarSamples->PushBack( measurement ); ++It; } } else { typename SampleType::Iterator ItS = scalarSamples->Begin(); typename SampleType::ConstIterator It = univariateSamples->Begin(); while( ItS != scalarSamples->End() ) { scalarSamples->SetMeasurement( ItS.GetInstanceIdentifier(), i, It.GetMeasurementVector()[0] ); ++It; ++ItS; } } } return scalarSamples; } template typename AtroposSegmentationImageFilter ::RealType AtroposSegmentationImageFilter ::CalculateLocalPosteriorProbability( RealType mixtureModelProportion, RealType spatialPriorProbability, RealType distancePriorProbability, RealType mrfPriorProbability, RealType likelihood ) { RealType posteriorProbability = 0.0; switch( this->m_PosteriorProbabilityFormulation ) { case Socrates: default: { posteriorProbability = vcl_pow( static_cast( spatialPriorProbability ), static_cast( this->m_PriorProbabilityWeight ) ) * vcl_pow( static_cast( likelihood * mrfPriorProbability ), static_cast( 1.0 - this->m_PriorProbabilityWeight ) ); break; } case Plato: { posteriorProbability = 1.0; break; } case Aristotle: { posteriorProbability = 1.0; break; } // case Zeno: // { // posteriorProbability = 1.0; // break; // } // case Diogenes: // { // posteriorProbability = 1.0; // break; // } // case Thales: // { // posteriorProbability = 1.0; // break; // } // case Democritus: // { // posteriorProbability = 1.0; // break; // } } return posteriorProbability; } template typename AtroposSegmentationImageFilter ::RealImageType::Pointer AtroposSegmentationImageFilter ::GetPosteriorProbabilityImage( unsigned int whichClass ) { if( whichClass > this->m_NumberOfClasses ) { itkExceptionMacro( "Requested class is greater than the number of classes." ); } /** * If memory minimization is turned off and if the posterior probability * images have already been calculated, simply return the probability * image for the requested class. Otherwise, calculate the probability * image. */ if( whichClass <= this->m_PosteriorProbabilityImages.size() ) { return this->m_PosteriorProbabilityImages[whichClass-1]; } else { /** * Here we assume that the calling function is invoked in order such * that GetPosteriorProbabilityImage( 1 ) is called before * GetPosteriorProbabilityImage( 2 ), etc. As such, when this part of * the code is reached and the class requested is '1', we assume that * the sum of the posterior probability images needs to be calculated * for normalization purposes. This sum is then saved for subsequent calls. */ typename RealImageType::Pointer posteriorProbabilityImage = RealImageType::New(); posteriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); posteriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); posteriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); posteriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); posteriorProbabilityImage->Allocate(); posteriorProbabilityImage->FillBuffer( 0 ); /** * Calculate the sum of the probability images. Also, store the * posterior probability images if m_MinimizeMemoryUsage == false. */ if( whichClass == 1 ) { this->m_SumPosteriorProbabilityImage = RealImageType::New(); this->m_SumPosteriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); this->m_SumPosteriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); this->m_SumPosteriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); this->m_SumPosteriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); this->m_SumPosteriorProbabilityImage->Allocate(); this->m_SumPosteriorProbabilityImage->FillBuffer( 0 ); typename RealImageType::Pointer sumPriorProbabilityImage = NULL; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { sumPriorProbabilityImage = RealImageType::New(); sumPriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); sumPriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); sumPriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); sumPriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); sumPriorProbabilityImage->Allocate(); sumPriorProbabilityImage->FillBuffer( 0 ); for( unsigned int c = 0; c < this->m_NumberOfClasses; c++ ) { typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( c + 1 ); ImageRegionIteratorWithIndex ItS( sumPriorProbabilityImage, sumPriorProbabilityImage->GetLargestPossibleRegion() ); for( ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItS ) { RealType priorProbability = 0.0; if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItS.GetIndex() ); } ItS.Set( ItS.Get() + this->m_MixtureModelProportions[c] * priorProbability ); } } } for( unsigned int c = 0; c < this->m_NumberOfClasses; c++ ) { std::vector smoothImages; if( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) { for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { if( this->m_AdaptiveSmoothingWeights.size() > i && this->m_AdaptiveSmoothingWeights[i] > 0.0 ) { smoothImages.push_back( this->GetSmoothIntensityImageFromPriorImage( i, c + 1 ) ); } else { smoothImages.push_back( NULL ); } } } typename RealImageType::Pointer distancePriorProbabilityImage = this->GetDistancePriorProbabilityImage( c + 1 ); typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( c + 1 ); typename NeighborhoodIterator::RadiusType radius; unsigned int neighborhoodSize = 1; for( unsigned int d = 0; d < ImageDimension; d++ ) { neighborhoodSize *= ( 2 * this->m_MRFRadius[d] + 1 ); radius[d] = this->m_MRFRadius[d]; } ConstNeighborhoodIterator ItO( radius, this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); ImageRegionIterator ItS( this->m_SumPosteriorProbabilityImage, this->m_SumPosteriorProbabilityImage->GetRequestedRegion() ); for( ItO.GoToBegin(), ItS.GoToBegin(); !ItO.IsAtEnd(); ++ItO, ++ItS ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { /** * Perform mrf prior calculation */ RealType mrfPriorProbability = 1.0; if( this->m_MRFSmoothingFactor > 0.0 && neighborhoodSize > 1 ) { Array weightedNumberOfClassNeighbors; weightedNumberOfClassNeighbors.SetSize( this->m_NumberOfClasses ); weightedNumberOfClassNeighbors.Fill( 0.0 ); for( unsigned int n = 0; n < neighborhoodSize; n++ ) { if( n == static_cast( 0.5 * neighborhoodSize ) ) { continue; } bool isInBounds = false; LabelType label = ItO.GetPixel( n, isInBounds ); if( !isInBounds || label == 0 ) { continue; } typename ClassifiedImageType::OffsetType offset = ItO.GetOffset( n ); double distance = 0.0; for( unsigned int d = 0; d < ImageDimension; d++ ) { distance += vnl_math_sqr( offset[d] * this->GetOutput()->GetSpacing()[d] ); } distance = vcl_sqrt( distance ); weightedNumberOfClassNeighbors[label-1] += ( 1.0 / distance ); } RealType numerator = vcl_exp( this->m_MRFSmoothingFactor * weightedNumberOfClassNeighbors[c] ); RealType denominator = 0.0; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { denominator += vcl_exp( this->m_MRFSmoothingFactor * weightedNumberOfClassNeighbors[n] ); } if( denominator > 0.0 ) { mrfPriorProbability = numerator / denominator; } } /** * Perform prior calculation using both the mixing proportions * and template-based prior images (if available) */ RealType priorProbability = 0.0; RealType distancePriorProbability = 0.0; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { if( distancePriorProbabilityImage ) { distancePriorProbability = distancePriorProbabilityImage->GetPixel( ItO.GetIndex() ); } if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItO.GetIndex() ); } RealType sumPriorProbability = sumPriorProbabilityImage->GetPixel( ItO.GetIndex() ); if( priorProbability > this->m_ProbabilityThreshold ) { priorProbability *= ( this->m_MixtureModelProportions[c] / sumPriorProbability ); } else if( sumPriorProbability <= this->m_ProbabilityThreshold && distancePriorProbabilityImage ) { priorProbability = distancePriorProbability; } } MeasurementVectorType measurement; measurement.SetSize( this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { measurement[i] = this->GetIntensityImage( i )->GetPixel( ItO.GetIndex() ); if( ( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) && smoothImages[i] ) { measurement[i] = ( 1.0 - this->m_AdaptiveSmoothingWeights[i] ) * measurement[i] + this->m_AdaptiveSmoothingWeights[i] * smoothImages[i]->GetPixel( ItO.GetIndex() ); } } /** * Calculate likelihood probability from the model */ RealType likelihood = this->m_MixtureModelComponents[c]->Evaluate( measurement ); /** * Calculate the local posterior probability. Given that the * algorithm is meant to maximize the posterior probability of the * labeling configuration, this is the critical energy minimization * equation. */ RealType posteriorProbability = CalculateLocalPosteriorProbability( this->m_MixtureModelProportions[c], priorProbability, distancePriorProbability, mrfPriorProbability, likelihood ); if( vnl_math_isnan( posteriorProbability ) || vnl_math_isinf( posteriorProbability ) ) { posteriorProbability = 0.0; } if( ( c == 0 ) || !this->m_MinimizeMemoryUsage ) { posteriorProbabilityImage->SetPixel( ItO.GetIndex(), posteriorProbability ); } /** * Calculate a running total of the posterior probabilities. */ ItS.Set( ItS.Get() + posteriorProbability ); } } if( !this->m_MinimizeMemoryUsage ) { typedef ImageDuplicator DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage( posteriorProbabilityImage ); duplicator->Update(); this->m_PosteriorProbabilityImages.push_back( duplicator->GetOutput() ); } } /** * Normalize the posterior probability image(s). */ ImageRegionIterator ItS( this->m_SumPosteriorProbabilityImage, this->m_SumPosteriorProbabilityImage->GetRequestedRegion() ); if( this->m_MinimizeMemoryUsage ) { ImageRegionIterator ItP( posteriorProbabilityImage, posteriorProbabilityImage->GetRequestedRegion() ); for( ItP.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItP, ++ItS ) { if( ItS.Get() > 0 ) { ItP.Set( ItP.Get() / ItS.Get() ); } } return posteriorProbabilityImage; } else { for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { ImageRegionIterator ItP( this->m_PosteriorProbabilityImages[n], this->m_PosteriorProbabilityImages[n]->GetRequestedRegion() ); for( ItP.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItP, ++ItS ) { if( ItS.Get() > 0 ) { ItP.Set( ItP.Get() / ItS.Get() ); } } } return this->m_PosteriorProbabilityImages[0]; } } else // whichClass > 1 { typename RealImageType::Pointer sumPriorProbabilityImage = NULL; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { sumPriorProbabilityImage = RealImageType::New(); sumPriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); sumPriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); sumPriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); sumPriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); sumPriorProbabilityImage->Allocate(); sumPriorProbabilityImage->FillBuffer( 0 ); for( unsigned int c = 0; c < this->m_NumberOfClasses; c++ ) { typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( c + 1 ); ImageRegionIteratorWithIndex ItS( sumPriorProbabilityImage, sumPriorProbabilityImage->GetLargestPossibleRegion() ); for( ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItS ) { RealType priorProbability = 0.0; if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItS.GetIndex() ); } ItS.Set( ItS.Get() + this->m_MixtureModelProportions[c] * priorProbability ); } } } std::vector smoothImages; if( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) { for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { if( this->m_AdaptiveSmoothingWeights.size() > i && this->m_AdaptiveSmoothingWeights[i] > 0.0 ) { smoothImages.push_back( this->GetSmoothIntensityImageFromPriorImage( i, whichClass ) ); } else { smoothImages.push_back( NULL ); } } } typename RealImageType::Pointer distancePriorProbabilityImage = this->GetDistancePriorProbabilityImage( whichClass ); typename RealImageType::Pointer priorProbabilityImage = this->GetPriorProbabilityImage( whichClass ); typename NeighborhoodIterator::RadiusType radius; unsigned int neighborhoodSize = 1; for( unsigned int d = 0; d < ImageDimension; d++ ) { neighborhoodSize *= ( 2 * this->m_MRFRadius[d] + 1 ); radius[d] = this->m_MRFRadius[d]; } ConstNeighborhoodIterator ItO( radius, this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( ItO.GoToBegin(); !ItO.IsAtEnd(); ++ItO ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItO.GetIndex() ) == this->m_MaskLabel ) { /** * Perform mrf prior calculation */ RealType mrfPriorProbability = 1.0; if( this->m_MRFSmoothingFactor > 0.0 && neighborhoodSize > 1 ) { Array weightedNumberOfClassNeighbors; weightedNumberOfClassNeighbors.SetSize( this->m_NumberOfClasses ); weightedNumberOfClassNeighbors.Fill( 0.0 ); for( unsigned int n = 0; n < neighborhoodSize; n++ ) { if( n == static_cast( 0.5 * neighborhoodSize ) ) { continue; } bool isInBounds = false; LabelType label = ItO.GetPixel( n, isInBounds ); if( !isInBounds || label == 0 ) { continue; } typename ClassifiedImageType::OffsetType offset = ItO.GetOffset( n ); double distance = 0.0; for( unsigned int d = 0; d < ImageDimension; d++ ) { distance += vnl_math_sqr( offset[d] * this->GetOutput()->GetSpacing()[d] ); } distance = vcl_sqrt( distance ); weightedNumberOfClassNeighbors[label-1] += ( 1.0 / distance ); } RealType numerator = vcl_exp( this->m_MRFSmoothingFactor * weightedNumberOfClassNeighbors[whichClass-1] ); RealType denominator = 0.0; for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { denominator += vcl_exp( this->m_MRFSmoothingFactor * weightedNumberOfClassNeighbors[n] ); } mrfPriorProbability = numerator / denominator; if( vnl_math_isinf( mrfPriorProbability ) || vnl_math_isnan( mrfPriorProbability ) ) { mrfPriorProbability = 1.0; } } /** * Perform prior calculation using both the mixing proportions * and template-based prior images (if available) */ RealType priorProbability = 0.0; RealType distancePriorProbability = 0.0; if( this->m_InitializationStrategy == PriorLabelImage || this->m_InitializationStrategy == PriorProbabilityImages ) { if( distancePriorProbabilityImage ) { distancePriorProbability = distancePriorProbabilityImage->GetPixel( ItO.GetIndex() ); } if( priorProbabilityImage ) { priorProbability = priorProbabilityImage->GetPixel( ItO.GetIndex() ); } RealType sumPriorProbability = sumPriorProbabilityImage->GetPixel( ItO.GetIndex() ); if( priorProbability > this->m_ProbabilityThreshold ) { priorProbability *= ( this->m_MixtureModelProportions[whichClass-1] / sumPriorProbability ); } else if( sumPriorProbability <= this->m_ProbabilityThreshold && distancePriorProbabilityImage ) { priorProbability = distancePriorProbability; } } MeasurementVectorType measurement; measurement.SetSize( this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { measurement[i] = this->GetIntensityImage( i )->GetPixel( ItO.GetIndex() ); if( ( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) && smoothImages[i] ) { measurement[i] = ( 1.0 - this->m_AdaptiveSmoothingWeights[i] ) * measurement[i] + this->m_AdaptiveSmoothingWeights[i] * smoothImages[i]->GetPixel( ItO.GetIndex() ); } } /** * Calculate likelihood probability from the model */ RealType likelihood = this->m_MixtureModelComponents[whichClass-1]->Evaluate( measurement ); /** * Calculate the local posterior probability. Given that the * algorithm is meant to maximize the posterior probability of the * labeling configuration, this is the critical energy minimization * equation. */ RealType posteriorProbability = CalculateLocalPosteriorProbability( this->m_MixtureModelProportions[whichClass-1], priorProbability, distancePriorProbability, mrfPriorProbability, likelihood ); if( vnl_math_isnan( posteriorProbability ) || vnl_math_isinf( posteriorProbability ) ) { posteriorProbability = 0.0; } posteriorProbabilityImage->SetPixel( ItO.GetIndex(), posteriorProbability ); } } /** * Normalize the posterior probability image(s). */ ImageRegionIterator ItS( this->m_SumPosteriorProbabilityImage, this->m_SumPosteriorProbabilityImage->GetRequestedRegion() ); ImageRegionIterator ItP( posteriorProbabilityImage, posteriorProbabilityImage->GetRequestedRegion() ); for( ItP.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItP, ++ItS ) { if( ItS.Get() > 0 ) { ItP.Set( ItP.Get() / ItS.Get() ); } } return posteriorProbabilityImage; } } } template typename AtroposSegmentationImageFilter ::RealImageType::Pointer AtroposSegmentationImageFilter ::GetDistancePriorProbabilityImage( unsigned int whichClass ) { if( this->m_InitializationStrategy != PriorLabelImage && this->m_InitializationStrategy != PriorProbabilityImages ) { return NULL; } if( whichClass > this->m_NumberOfClasses ) { itkExceptionMacro( "Requested class is greater than the number of classes." ); } /** * If memory minimization is turned off and if the distance prior probability * images have already been calculated, simply return the probability * image for the requested class. Otherwise, calculate the probability * image. */ if( whichClass <= this->m_DistancePriorProbabilityImages.size() ) { return this->m_DistancePriorProbabilityImages[whichClass-1]; } else { /** * Here we assume that the calling function is invoked in order such * that GetDistancePriorImage( 1 ) is called before * GetDistancePriorImage( 2 ), etc. As such, when this part of * the code is reached and the class requested is '1', we assume that * the sum of the distance prior probability images needs to be calculated * for normalization purposes. This sum is then saved for subsequent calls. */ typename RealImageType::Pointer distancePriorProbabilityImage = NULL; /** * Calculate the sum of the distance probability images. Also, store the * distance probability images if m_MinimizeMemoryUsage == false. */ if( whichClass == 1 ) { this->m_SumDistancePriorProbabilityImage = RealImageType::New(); this->m_SumDistancePriorProbabilityImage->SetRegions( this->GetOutput()->GetRequestedRegion() ); this->m_SumDistancePriorProbabilityImage->SetOrigin( this->GetOutput()->GetOrigin() ); this->m_SumDistancePriorProbabilityImage->SetSpacing( this->GetOutput()->GetSpacing() ); this->m_SumDistancePriorProbabilityImage->SetDirection( this->GetOutput()->GetDirection() ); this->m_SumDistancePriorProbabilityImage->Allocate(); this->m_SumDistancePriorProbabilityImage->FillBuffer( 0 ); for( unsigned int c = 0; c < this->m_NumberOfClasses; c++ ) { typedef BinaryThresholdImageFilter ThresholderType; typename ThresholderType::Pointer thresholder = ThresholderType::New(); if( this->m_InitializationStrategy == PriorLabelImage ) { thresholder->SetInput( const_cast( this->GetPriorLabelImage() ) ); } else { thresholder->SetInput( this->GetOutput() ); } thresholder->SetInsideValue( 1 ); thresholder->SetOutsideValue( 0 ); thresholder->SetLowerThreshold( static_cast( c + 1 ) ); thresholder->SetUpperThreshold( static_cast( c + 1 ) ); thresholder->Update(); typename RealImageType::Pointer distanceImage = RealImageType::New(); if( this->m_UseEuclideanDistanceForPriorLabels ) { typedef SignedMaurerDistanceMapImageFilter DistancerType; typename DistancerType::Pointer distancer = DistancerType::New(); distancer->SetInput( thresholder->GetOutput() ); distancer->SetSquaredDistance( false ); distancer->SetUseImageSpacing( true ); distancer->SetInsideIsPositive( false ); distancer->Update(); distanceImage = distancer->GetOutput(); } else { typedef BinaryContourImageFilter ContourFilterType; typename ContourFilterType::Pointer contour = ContourFilterType::New(); contour->SetInput( thresholder->GetOutput() ); contour->FullyConnectedOff(); contour->SetBackgroundValue( 0 ); contour->SetForegroundValue( 1 ); contour->Update(); typedef FastMarchingImageFilter FastMarchingFilterType; typename FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New(); typedef CastImageFilter CasterType; typename CasterType::Pointer caster = CasterType::New(); if( this->GetMaskImage() ) { caster->SetInput( const_cast( this->GetMaskImage() ) ); caster->Update(); fastMarching->SetInput( caster->GetOutput() ); } else { fastMarching->SetSpeedConstant( 1.0 ); fastMarching->SetOverrideOutputInformation( true ); fastMarching->SetOutputOrigin( this->GetOutput()->GetOrigin() ); fastMarching->SetOutputSpacing( this->GetOutput()->GetSpacing() ); fastMarching->SetOutputRegion( this->GetOutput()->GetRequestedRegion() ); fastMarching->SetOutputDirection( this->GetOutput()->GetDirection() ); } typedef typename FastMarchingFilterType::NodeContainer NodeContainer; typedef typename FastMarchingFilterType::NodeType NodeType; typename NodeContainer::Pointer trialPoints = NodeContainer::New(); trialPoints->Initialize(); unsigned long trialCount = 0; ImageRegionIteratorWithIndex ItC( contour->GetOutput(), contour->GetOutput()->GetRequestedRegion() ); for( ItC.GoToBegin(); !ItC.IsAtEnd(); ++ItC ) { if( ItC.Get() == contour->GetForegroundValue() ) { NodeType node; node.SetValue( 0.0 ); node.SetIndex( ItC.GetIndex() ); trialPoints->InsertElement( trialCount++, node ); } } fastMarching->SetTrialPoints( trialPoints ); fastMarching->SetStoppingValue( NumericTraits::max() ); // fastMarching->SetTopologyCheck( FastMarchingFilterType::None ); fastMarching->Update(); ImageRegionIterator ItT( thresholder->GetOutput(), thresholder->GetOutput()->GetRequestedRegion() ); ImageRegionIterator ItF( fastMarching->GetOutput(), fastMarching->GetOutput()->GetRequestedRegion() ); for( ItT.GoToBegin(), ItF.GoToBegin(); !ItT.IsAtEnd(); ++ItT, ++ItF ) { if( ItT.Get() == 1 ) { ItF.Set( -ItF.Get() ); } } distanceImage = fastMarching->GetOutput(); } RealType maximumInteriorDistance = 0.0; ImageRegionIterator ItD( distanceImage, distanceImage->GetRequestedRegion() ); for( ItD.GoToBegin(); !ItD.IsAtEnd(); ++ItD ) { if( ItD.Get() < 0 && maximumInteriorDistance < vnl_math_abs( ItD.Get() ) ) { maximumInteriorDistance = vnl_math_abs( ItD.Get() ); } } RealType labelLambda = 0.0; RealType labelBoundaryProbability = 1.0; typename LabelParameterMapType::iterator it = this->m_PriorLabelParameterMap.find( c + 1 ); if( it != this->m_PriorLabelParameterMap.end() ) { labelLambda = ( it->second ).first; labelBoundaryProbability = ( it->second ).second; } for( ItD.GoToBegin(); !ItD.IsAtEnd(); ++ItD ) { if( labelLambda == 0 ) { if( ItD.Get() <= 0 ) { ItD.Set( labelBoundaryProbability ); } else { ItD.Set( 0.0 ); } } else if( ItD.Get() >= 0 ) { ItD.Set( labelBoundaryProbability * vcl_exp( -labelLambda * ItD.Get() ) ); } else if( ItD.Get() < 0 ) { ItD.Set( 1.0 - ( 1.0 - labelBoundaryProbability ) * ( maximumInteriorDistance - vnl_math_abs( ItD.Get() ) ) / ( maximumInteriorDistance ) ); } } typedef AddImageFilter AdderType; typename AdderType::Pointer adder = AdderType::New(); adder->SetInput1( this->m_SumDistancePriorProbabilityImage ); adder->SetInput2( distanceImage ); adder->Update(); this->m_SumDistancePriorProbabilityImage = adder->GetOutput(); if( ( c == 0 ) && this->m_MinimizeMemoryUsage ) { distancePriorProbabilityImage = distanceImage; } if( !this->m_MinimizeMemoryUsage ) { this->m_DistancePriorProbabilityImages.push_back( distanceImage ); } } /** * Normalize the distance prior probability image(s). */ ImageRegionIterator ItS( this->m_SumDistancePriorProbabilityImage, this->m_SumDistancePriorProbabilityImage->GetRequestedRegion() ); if( this->m_MinimizeMemoryUsage ) { ImageRegionIteratorWithIndex ItD( distancePriorProbabilityImage, distancePriorProbabilityImage->GetRequestedRegion() ); for( ItD.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItD, ++ItS ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItD.GetIndex() ) == this->m_MaskLabel ) { if( ItS.Get() <= this->m_ProbabilityThreshold ) { ItD.Set( NumericTraits::Zero ); } else { ItD.Set( ItD.Get() / ItS.Get() ); } } } return distancePriorProbabilityImage; } else { for( unsigned int c = 0; c < this->m_NumberOfClasses; c++ ) { ImageRegionIteratorWithIndex ItD( this->m_DistancePriorProbabilityImages[c], this->m_DistancePriorProbabilityImages[c]->GetRequestedRegion() ); for( ItD.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItD, ++ItS ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItD.GetIndex() ) == this->m_MaskLabel ) { if( ItS.Get() <= this->m_ProbabilityThreshold ) { ItD.Set( NumericTraits::Zero ); } else { ItD.Set( ItD.Get() / ItS.Get() ); } } } } return this->m_DistancePriorProbabilityImages[0]; } } else // whichClass > 1 { typedef BinaryThresholdImageFilter ThresholderType; typename ThresholderType::Pointer thresholder = ThresholderType::New(); if( this->m_InitializationStrategy == PriorLabelImage ) { thresholder->SetInput( const_cast( this->GetPriorLabelImage() ) ); } else { thresholder->SetInput( this->GetOutput() ); } thresholder->SetInsideValue( 1 ); thresholder->SetOutsideValue( 0 ); thresholder->SetLowerThreshold( static_cast( whichClass ) ); thresholder->SetUpperThreshold( static_cast( whichClass ) ); thresholder->Update(); typename RealImageType::Pointer distanceImage = RealImageType::New(); if( this->m_UseEuclideanDistanceForPriorLabels ) { typedef SignedMaurerDistanceMapImageFilter DistancerType; typename DistancerType::Pointer distancer = DistancerType::New(); distancer->SetInput( thresholder->GetOutput() ); distancer->SetSquaredDistance( false ); distancer->SetUseImageSpacing( true ); distancer->SetInsideIsPositive( false ); distancer->Update(); distanceImage = distancer->GetOutput(); } else { typedef BinaryContourImageFilter ContourFilterType; typename ContourFilterType::Pointer contour = ContourFilterType::New(); contour->SetInput( thresholder->GetOutput() ); contour->FullyConnectedOff(); contour->SetBackgroundValue( 0 ); contour->SetForegroundValue( 1 ); contour->Update(); typedef FastMarchingImageFilter FastMarchingFilterType; typename FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New(); typedef CastImageFilter CasterType; typename CasterType::Pointer caster = CasterType::New(); if( this->GetMaskImage() ) { caster->SetInput( const_cast( this->GetMaskImage() ) ); caster->Update(); fastMarching->SetInput( caster->GetOutput() ); } else { fastMarching->SetSpeedConstant( 1.0 ); fastMarching->SetOverrideOutputInformation( true ); fastMarching->SetOutputOrigin( this->GetOutput()->GetOrigin() ); fastMarching->SetOutputSpacing( this->GetOutput()->GetSpacing() ); fastMarching->SetOutputRegion( this->GetOutput()->GetRequestedRegion() ); fastMarching->SetOutputDirection( this->GetOutput()->GetDirection() ); } typedef typename FastMarchingFilterType::NodeContainer NodeContainer; typedef typename FastMarchingFilterType::NodeType NodeType; typename NodeContainer::Pointer trialPoints = NodeContainer::New(); trialPoints->Initialize(); unsigned long trialCount = 0; ImageRegionIteratorWithIndex ItC( contour->GetOutput(), contour->GetOutput()->GetRequestedRegion() ); for( ItC.GoToBegin(); !ItC.IsAtEnd(); ++ItC ) { if( ItC.Get() == contour->GetForegroundValue() ) { NodeType node; node.SetValue( 0.0 ); node.SetIndex( ItC.GetIndex() ); trialPoints->InsertElement( trialCount++, node ); } } fastMarching->SetTrialPoints( trialPoints ); fastMarching->SetStoppingValue( NumericTraits::max() ); // fastMarching->SetTopologyCheck( FastMarchingFilterType::None ); fastMarching->Update(); ImageRegionIterator ItT( thresholder->GetOutput(), thresholder->GetOutput()->GetRequestedRegion() ); ImageRegionIterator ItF( fastMarching->GetOutput(), fastMarching->GetOutput()->GetRequestedRegion() ); for( ItT.GoToBegin(), ItF.GoToBegin(); !ItT.IsAtEnd(); ++ItT, ++ItF ) { if( ItT.Get() == 1 ) { ItF.Set( -ItF.Get() ); } } distanceImage = fastMarching->GetOutput(); } distancePriorProbabilityImage = distanceImage; RealType maximumInteriorDistance = 0.0; ImageRegionIterator ItD( distancePriorProbabilityImage, distancePriorProbabilityImage->GetRequestedRegion() ); for( ItD.GoToBegin(); !ItD.IsAtEnd(); ++ItD ) { if( ItD.Get() < 0 && maximumInteriorDistance < vnl_math_abs( ItD.Get() ) ) { maximumInteriorDistance = vnl_math_abs( ItD.Get() ); } } RealType labelLambda = 0.0; RealType labelBoundaryProbability = 1.0; typename LabelParameterMapType::iterator it = this->m_PriorLabelParameterMap.find( whichClass ); if( it != this->m_PriorLabelParameterMap.end() ) { labelLambda = ( it->second ).first; labelBoundaryProbability = ( it->second ).second; } for( ItD.GoToBegin(); !ItD.IsAtEnd(); ++ItD ) { if( labelLambda == 0 ) { if( ItD.Get() <= 0 ) { ItD.Set( labelBoundaryProbability ); } else { ItD.Set( 0.0 ); } } else if( ItD.Get() >= 0 ) { ItD.Set( labelBoundaryProbability * vcl_exp( -labelLambda * ItD.Get() ) ); } else if( ItD.Get() < 0 ) { ItD.Set( 1.0 - ( 1.0 - labelBoundaryProbability ) * ( maximumInteriorDistance - vnl_math_abs( ItD.Get() ) ) / ( maximumInteriorDistance ) ); } } /** * Normalize the distance prior probability image(s). */ ImageRegionIterator ItS( this->m_SumDistancePriorProbabilityImage, this->m_SumDistancePriorProbabilityImage->GetRequestedRegion() ); for( ItD.GoToBegin(), ItS.GoToBegin(); !ItS.IsAtEnd(); ++ItD, ++ItS ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItD.GetIndex() ) == this->m_MaskLabel ) { if( ItS.Get() <= this->m_ProbabilityThreshold ) { ItD.Set( NumericTraits::Zero ); } else { ItD.Set( ItD.Get() / ItS.Get() ); } } } return distancePriorProbabilityImage; } } } template typename AtroposSegmentationImageFilter ::RealImageType::Pointer AtroposSegmentationImageFilter ::GetSmoothIntensityImageFromPriorImage( unsigned int whichImage, unsigned int whichClass ) { typename ScalarImageType::Pointer bsplineImage; if( this->m_ControlPointLattices[whichImage][whichClass-1].GetPointer() != NULL ) { typedef BSplineControlPointImageFilter BSplineReconstructorType; typename BSplineReconstructorType::Pointer bspliner = BSplineReconstructorType::New(); bspliner->SetInput( this->m_ControlPointLattices[whichImage][whichClass-1] ); bspliner->SetSize( this->GetInput()->GetRequestedRegion().GetSize() ); bspliner->SetSpacing( this->GetInput()->GetSpacing() ); bspliner->SetOrigin( this->GetInput()->GetOrigin() ); bspliner->SetDirection( this->GetInput()->GetDirection() ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->Update(); bsplineImage = bspliner->GetOutput(); } else { typename PointSetType::Pointer points = PointSetType::New(); points->Initialize(); typedef typename BSplineFilterType::WeightsContainerType WeightsType; typename WeightsType::Pointer weights = WeightsType::New(); weights->Initialize(); typename RealImageType::Pointer probabilityImage; if( this->m_InitializationStrategy == PriorProbabilityImages ) { probabilityImage = this->GetPriorProbabilityImage( whichClass ); } else { typedef BinaryThresholdImageFilter ThresholderType; typename ThresholderType::Pointer thresholder = ThresholderType::New(); thresholder->SetInput( const_cast( this->GetPriorLabelImage() ) ); thresholder->SetInsideValue( 1 ); thresholder->SetOutsideValue( 0 ); thresholder->SetLowerThreshold( static_cast( whichClass ) ); thresholder->SetUpperThreshold( static_cast( whichClass ) ); thresholder->Update(); probabilityImage = thresholder->GetOutput(); } typename RealImageType::DirectionType originalDirection = probabilityImage->GetDirection(); typename RealImageType::DirectionType identity; identity.SetIdentity(); probabilityImage->SetDirection( identity ); unsigned long count = 0; ImageRegionIteratorWithIndex ItP( probabilityImage, probabilityImage->GetBufferedRegion() ); for( ItP.GoToBegin(); !ItP.IsAtEnd(); ++ItP ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItP.GetIndex() ) == this->m_MaskLabel ) { if( ItP.Get() >= 0.5 ) { typename RealImageType::PointType imagePoint; probabilityImage->TransformIndexToPhysicalPoint( ItP.GetIndex(), imagePoint ); typename PointSetType::PointType bsplinePoint; bsplinePoint.CastFrom( imagePoint ); ScalarType intensity; intensity[0] = this->GetIntensityImage( whichImage )->GetPixel( ItP.GetIndex() ); points->SetPoint( count, bsplinePoint ); points->SetPointData( count, intensity ); weights->InsertElement( count, ItP.Get() ); count++; } } } probabilityImage->SetDirection( originalDirection ); typename BSplineFilterType::ArrayType numberOfControlPoints; typename BSplineFilterType::ArrayType numberOfLevels; for( unsigned int d = 0; d < ImageDimension; d++ ) { numberOfControlPoints[d] = this->m_NumberOfControlPoints[d]; numberOfLevels[d] = this->m_NumberOfLevels[d]; } typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetInput( points ); bspliner->SetPointWeights( weights ); bspliner->SetNumberOfLevels( numberOfLevels ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetNumberOfControlPoints( numberOfControlPoints ); bspliner->SetSize( this->GetOutput()->GetLargestPossibleRegion().GetSize() ); bspliner->SetOrigin( this->GetOutput()->GetOrigin() ); bspliner->SetDirection( this->GetOutput()->GetDirection() ); bspliner->SetSpacing( this->GetOutput()->GetSpacing() ); bspliner->SetGenerateOutputImage( true ); bspliner->Update(); bsplineImage = bspliner->GetOutput(); this->m_ControlPointLattices[whichImage][whichClass-1] = bspliner->GetPhiLattice(); } typedef VectorIndexSelectionCastImageFilter CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput( bsplineImage ); caster->SetIndex( 0 ); caster->Update(); return caster->GetOutput(); } template typename AtroposSegmentationImageFilter ::RealImageType::Pointer AtroposSegmentationImageFilter ::GetLikelihoodImage( unsigned int whichClass ) { typename RealImageType::Pointer likelihoodImage = RealImageType::New(); likelihoodImage->SetSpacing( this->GetInput()->GetSpacing() ); likelihoodImage->SetOrigin( this->GetInput()->GetOrigin() ); likelihoodImage->SetDirection( this->GetInput()->GetDirection() ); likelihoodImage->SetRegions( this->GetInput()->GetRequestedRegion() ); likelihoodImage->Allocate(); likelihoodImage->FillBuffer( 0 ); std::vector smoothImages; if( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) { for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { if( this->m_AdaptiveSmoothingWeights.size() > i && this->m_AdaptiveSmoothingWeights[i] > 0.0 ) { smoothImages.push_back( this->GetSmoothIntensityImageFromPriorImage( i, whichClass ) ); } else { smoothImages.push_back( NULL ); } } } ImageRegionIteratorWithIndex It( likelihoodImage, likelihoodImage->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) { MeasurementVectorType measurement; measurement.SetSize( this->m_NumberOfIntensityImages ); for( unsigned int i = 0; i < this->m_NumberOfIntensityImages; i++ ) { measurement[i] = this->GetIntensityImage( i )->GetPixel( It.GetIndex() ); if( ( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) && smoothImages[i] ) { measurement[i] = ( 1.0 - this->m_AdaptiveSmoothingWeights[i] ) * measurement[i] + this->m_AdaptiveSmoothingWeights[i] * smoothImages[i]->GetPixel( It.GetIndex() ); } } RealType likelihood = this->m_MixtureModelComponents[whichClass-1]->Evaluate( measurement ); It.Set( likelihood ); } } return likelihoodImage; } template void AtroposSegmentationImageFilter ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf( os, indent ); os << indent << "Maximum number of iterations: " << this->m_MaximumNumberOfIterations << std::endl; os << indent << "Convergence threshold: " << this->m_ConvergenceThreshold << std::endl; os << indent << "Mask label: " << static_cast::PrintType> ( this->m_MaskLabel ) << std::endl; os << indent << "Number of classes: " << this->m_NumberOfClasses << std::endl; os << indent << "Minimize memory usage:"; if( this->m_MinimizeMemoryUsage ) { os << " true"; if( this->m_MinimizeMemoryUsage && this->m_InitializationStrategy == PriorProbabilityImages ) { os << " (prior probability threshold = " << this->m_ProbabilityThreshold << ")" << std::endl; } os << std::endl; } else { os << " false" << std::endl; } os << indent << "Initialization strategy: "; switch( this->m_InitializationStrategy ) { case Random: { os << "Random" << std::endl; break; } case KMeans: { os << "K means clustering" << std::endl; break; } case Otsu: { os << "Otsu thresholding" << std::endl; break; } case PriorProbabilityImages: { os << "Prior probability images" << std::endl; os << indent << " Use Euclidean distance for prior labels:"; if( this->m_UseEuclideanDistanceForPriorLabels ) { os << " true" << std::endl; } else { os << " false" << std::endl; } if( this->m_PriorLabelParameterMap.size() > 0 ) { os << indent << " Specified prior label parameters:" << std::endl; typename LabelParameterMapType::const_iterator it; for( it = this->m_PriorLabelParameterMap.begin(); it != this->m_PriorLabelParameterMap.end(); ++it ) { RealType label = it->first; RealType lambda = ( it->second ).first; RealType boundaryProbability = ( it->second ).second; os << indent << " Class " << label << ": lambda = " << lambda << ", boundary probability = " << boundaryProbability << std::endl; } } break; } case PriorLabelImage: { os << "Prior label image" << std::endl; os << indent << " Use Euclidean distance for prior labels:"; if( this->m_UseEuclideanDistanceForPriorLabels ) { os << " true" << std::endl; } else { os << " false" << std::endl; } os << indent << " Specified prior label parameters:" << std::endl; typename LabelParameterMapType::const_iterator it; for( it = this->m_PriorLabelParameterMap.begin(); it != this->m_PriorLabelParameterMap.end(); ++it ) { RealType label = it->first; RealType lambda = ( it->second ).first; RealType boundaryProbability = ( it->second ).second; os << indent << " Class " << label << ": lambda = " << lambda << ", boundary probability = " << boundaryProbability << std::endl; } break; } } os << indent << "Posterior probability formulation: "; switch( this->m_PosteriorProbabilityFormulation ) { case Socrates: { os << "Socrates" << std::endl; break; } case Plato: { os << "Plato" << std::endl; break; } case Aristotle: { os << "Aristotle" << std::endl; break; } // case Zeno: // { // os << "Zeno" << std::endl; // break; // } // case Diogenes: // { // os << "Diogenes" << std::endl; // break; // } // case Thales: // { // os << "Thales" << std::endl; // break; // } // case Democritus: // { // os << "Democritus" << std::endl; // break; // } } os << indent << "MRF parameters" << std::endl; os << indent << " MRF smoothing factor: " << this->m_MRFSmoothingFactor << std::endl; os << indent << " MRF radius: " << this->m_MRFRadius << std::endl; if( this->m_OutlierHandlingFilter ) { os << indent << "Outlier handling " << std::endl; this->m_OutlierHandlingFilter->Print( os, indent.GetNextIndent() ); } else { os << indent << "No outlier handling." << std::endl; } if( ( this->m_InitializationStrategy == PriorProbabilityImages || this->m_InitializationStrategy == PriorLabelImage ) && this->m_AdaptiveSmoothingWeights.size() > 0 ) { os << indent << "Adaptive smoothing weights: ["; for( unsigned int i = 0; i < this->m_AdaptiveSmoothingWeights.size()-1; i++ ) { os << this->m_AdaptiveSmoothingWeights[i] << ", "; } os << this->m_AdaptiveSmoothingWeights[ this->m_AdaptiveSmoothingWeights.size() - 1] << "]" << std::endl; os << indent << "BSpline smoothing" << std::endl; os << indent << " Spline order: " << this->m_SplineOrder << std::endl; os << indent << " Number of levels: " << this->m_NumberOfLevels << std::endl; os << indent << " Number of initial control points: " << this->m_NumberOfControlPoints << std::endl; } for( unsigned int n = 0; n < this->m_NumberOfClasses; n++ ) { if( this->m_MixtureModelProportions.size() > n ) { os << indent << "Class " << n + 1 << ": proportion = " << this->m_MixtureModelProportions[n] << std::endl; } if( this->m_MixtureModelComponents.size() > n ) { this->m_MixtureModelComponents[n]->Print( os, indent.GetNextIndent() ); } } } } // namespace ants } // namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsBoxPlotQuantileListSampleFilter.h000066400000000000000000000100021147325206600273460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsBoxPlotQuantileListSampleFilter.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsBoxPlotQuantileListSampleFilter_h #define __antsBoxPlotQuantileListSampleFilter_h #include "antsListSampleToListSampleFilter.h" #include namespace itk { namespace ants { namespace Statistics { /** \class BoxPlotQuantileListSampleFilter * \brief Base class of filters intended to generate scalar samples from * intensity samples. * */ template class ITK_EXPORT BoxPlotQuantileListSampleFilter : public ListSampleToListSampleFilter { public: /** * Standard class typedefs. */ typedef BoxPlotQuantileListSampleFilter Self; typedef ListSampleToListSampleFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Standard macros */ itkTypeMacro( BoxPlotQuantileListSampleFilter, ListSampleToScalarListSampleFilter ); /** * Method for creation through the object factory. */ itkNewMacro( Self ); /** * Conveneient typedefs */ typedef double RealType; typedef TScalarListSample ScalarListSampleType; typedef typename ScalarListSampleType ::MeasurementVectorType MeasurementVectorType; typedef typename ScalarListSampleType ::InstanceIdentifier InstanceIdentifierType; typedef std::vector InstanceIdentifierContainerType; enum OutlierHandlingType { None, Trim, Winsorize }; itkSetMacro( OutlierHandling, OutlierHandlingType ); itkGetConstMacro( OutlierHandling, OutlierHandlingType ); itkSetMacro( WhiskerScalingFactor, RealType ); itkGetConstMacro( WhiskerScalingFactor, RealType ); itkSetClampMacro( UpperPercentile, RealType, 0, 1 ); itkGetConstMacro( UpperPercentile, RealType ); itkSetClampMacro( LowerPercentile, RealType, 0, 1 ); itkGetConstMacro( LowerPercentile, RealType ); InstanceIdentifierContainerType GetOutlierInstanceIdentifiers() { return this->m_OutlierInstanceIdentifiers; } // itkGetConstMacro( Outliers, InstanceIdentifierContainerType ); protected: BoxPlotQuantileListSampleFilter(); virtual ~BoxPlotQuantileListSampleFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; virtual void GenerateData(); private: BoxPlotQuantileListSampleFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented InstanceIdentifierType FindMaximumNonOutlierDeviationValue( RealType, RealType ); bool IsMeasurementAnOutlier( RealType, RealType, RealType, unsigned long ); OutlierHandlingType m_OutlierHandling; InstanceIdentifierContainerType m_OutlierInstanceIdentifiers; RealType m_WhiskerScalingFactor; RealType m_LowerPercentile; RealType m_UpperPercentile; }; // end of class } // end of namespace Statistics } // end of namespace ants4443 } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsBoxPlotQuantileListSampleFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsBoxPlotQuantileListSampleFilter.txx000066400000000000000000000141161147325206600277540ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsBoxPlotQuantileListSampleFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsBoxPlotQuantileListSampleFilter_txx #define __antsBoxPlotQuantileListSampleFilter_txx #include "antsBoxPlotQuantileListSampleFilter.h" #include "itkDenseFrequencyContainer2.h" #include "itkHistogram.h" #include "itkSampleToHistogramFilter.h" namespace itk { namespace ants { namespace Statistics { template BoxPlotQuantileListSampleFilter ::BoxPlotQuantileListSampleFilter() { this->AllocateOutput(); this->GetOutput()->SetMeasurementVectorSize( 1 ); this->m_OutlierHandling = Winsorize; this->m_WhiskerScalingFactor = 1.5; this->m_LowerPercentile = 0.25; this->m_UpperPercentile = 0.75; } template BoxPlotQuantileListSampleFilter ::~BoxPlotQuantileListSampleFilter() { } template void BoxPlotQuantileListSampleFilter ::GenerateData() { if( this->GetInput()->GetMeasurementVectorSize() != 1 ) { itkExceptionMacro( "The input sample must be univariate." ); } if( this->m_LowerPercentile >= this->m_UpperPercentile ) { itkExceptionMacro( "Lower percentile must be less than upper percentile." ); } const unsigned int scalarMeasurementVectorSize = this->GetInput()->GetMeasurementVectorSize(); this->GetOutput()->SetMeasurementVectorSize( scalarMeasurementVectorSize ); /** * Initialize the histogram in preparation */ typedef itk::Statistics:: Histogram HistogramType; typedef itk::Statistics:: SampleToHistogramFilter SampleFilterType; typename SampleFilterType::HistogramSizeType histogramSize( 1 ); histogramSize.Fill( 200 ); typename SampleFilterType::Pointer sampleFilter = SampleFilterType::New(); sampleFilter->SetInput( this->GetInput() ); sampleFilter->SetHistogramSize( histogramSize ); sampleFilter->Update(); RealType lowerQuantile = sampleFilter->GetOutput()-> Quantile( 0, this->m_LowerPercentile ); RealType upperQuantile = sampleFilter->GetOutput()-> Quantile( 0, this->m_UpperPercentile ); RealType upperBound = upperQuantile + this->m_WhiskerScalingFactor * ( upperQuantile - lowerQuantile ); RealType lowerBound = lowerQuantile - this->m_WhiskerScalingFactor * ( upperQuantile - lowerQuantile ); typename ScalarListSampleType::ConstIterator It = this->GetInput()->Begin(); It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); typename ScalarListSampleType::MeasurementVectorType outputMeasurement; outputMeasurement.SetSize( scalarMeasurementVectorSize ); if( inputMeasurement[0] < lowerBound || inputMeasurement[0] > upperBound ) { this->m_OutlierInstanceIdentifiers.push_back( It.GetInstanceIdentifier() ); if( this->m_OutlierHandling == None ) { outputMeasurement[0] = inputMeasurement[0]; this->GetOutput()->PushBack( outputMeasurement ); } // else trim from the output } else { outputMeasurement[0] = inputMeasurement[0]; this->GetOutput()->PushBack( outputMeasurement ); } ++It; } if( this->m_OutlierHandling == Winsorize ) { /** Retabulate the histogram with the outliers removed */ typename SampleFilterType::Pointer sampleFilter2 = SampleFilterType::New(); sampleFilter2->SetInput( this->GetOutput() ); sampleFilter2->SetHistogramSize( histogramSize ); sampleFilter2->Update(); RealType lowerQuantile2 = sampleFilter2->GetOutput()-> Quantile( 0, this->m_LowerPercentile ); RealType upperQuantile2 = sampleFilter2->GetOutput()-> Quantile( 0, this->m_UpperPercentile ); RealType upperBound2 = upperQuantile2 + this->m_WhiskerScalingFactor * ( upperQuantile2 - lowerQuantile2 ); RealType lowerBound2 = lowerQuantile2 - this->m_WhiskerScalingFactor * ( upperQuantile2 - lowerQuantile2 ); this->GetOutput()->Clear(); It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); typename ScalarListSampleType::MeasurementVectorType outputMeasurement; outputMeasurement.SetSize( scalarMeasurementVectorSize ); outputMeasurement[0] = inputMeasurement[0]; if( inputMeasurement[0] < lowerBound ) { outputMeasurement[0] = lowerBound2; } else if( inputMeasurement[0] > upperBound ) { outputMeasurement[0] = upperBound2; } this->GetOutput()->PushBack( outputMeasurement ); ++It; } } } template void BoxPlotQuantileListSampleFilter ::PrintSelf( std::ostream& os, Indent indent ) const { os << indent << "Percentile Bounds: [" << this->m_LowerPercentile << ", " << this->m_UpperPercentile << "]" << std::endl; os << indent << "Whisker scaling factor: " << this->m_WhiskerScalingFactor << std::endl; os << indent << "Outlier handling: "; if( this->m_OutlierHandling == None ) { os << "None" << std::endl; } if( this->m_OutlierHandling == Trim ) { os << "Trim" << std::endl; } if( this->m_OutlierHandling == Winsorize ) { os << "Winsorize" << std::endl; } } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsGaussianListSampleFunction.h000066400000000000000000000060531147325206600264010ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsGaussianListSampleFunction.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsGaussianListSampleFunction_h #define __antsGaussianListSampleFunction_h #include "antsListSampleFunction.h" #include "itkGaussianMembershipFunction.h" namespace itk { namespace ants { namespace Statistics { /** \class GaussianListSampleFunction.h * \brief point set filter. */ template class ITK_EXPORT GaussianListSampleFunction : public ListSampleFunction { public: typedef GaussianListSampleFunction Self; typedef ListSampleFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( GaussianListSampleFunction, ListSampleFunction ); typedef typename Superclass::InputListSampleType InputListSampleType; typedef typename Superclass::InputMeasurementVectorType InputMeasurementVectorType; typedef typename Superclass::InputMeasurementType InputMeasurementType; /** List sample typedef support. */ typedef TListSample ListSampleType; /** Gaussian typedefs */ typedef typename itk::Statistics::GaussianMembershipFunction GaussianType; /** Other typedef */ typedef TOutput RealType; typedef TOutput OutputType; /** Helper functions */ virtual void SetInputListSample( const InputListSampleType * ptr ); virtual TOutput Evaluate( const InputMeasurementVectorType& measurement ) const; protected: GaussianListSampleFunction(); virtual ~GaussianListSampleFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: //purposely not implemented GaussianListSampleFunction( const Self& ); void operator=( const Self& ); typename GaussianType::Pointer m_Gaussian; }; } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsGaussianListSampleFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsGaussianListSampleFunction.txx000066400000000000000000000113361147325206600267750ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsGaussianListSampleFunction.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsGaussianListSampleFunction_txx #define __antsGaussianListSampleFunction_txx #include "antsGaussianListSampleFunction.h" #include "itkCovarianceSampleFilter.h" #include "itkMeanSampleFilter.h" #include "itkWeightedCovarianceSampleFilter.h" #include "itkWeightedMeanSampleFilter.h" namespace itk { namespace ants { namespace Statistics { template GaussianListSampleFunction ::GaussianListSampleFunction() { this->m_Gaussian = GaussianType::New(); } template GaussianListSampleFunction ::~GaussianListSampleFunction() { } template void GaussianListSampleFunction ::SetInputListSample( const InputListSampleType * ptr ) { this->m_ListSample = ptr; if( !this->m_ListSample ) { return; } if( this->m_ListSample->Size() > 1 ) { if( this->m_Weights.Size() == this->m_ListSample->Size() ) { typedef typename itk::Statistics:: WeightedCovarianceSampleFilter CovarianceCalculatorType; typename CovarianceCalculatorType::Pointer covarianceCalculator = CovarianceCalculatorType::New(); covarianceCalculator->SetWeights( this->m_Weights ); covarianceCalculator->SetInput( this->m_ListSample ); covarianceCalculator->Update(); typename GaussianType::MeanType mean; ::itk::Statistics::MeasurementVectorTraits::SetLength( mean, this->m_ListSample->GetMeasurementVectorSize() ); for( unsigned int d = 0; d < this->m_ListSample->GetMeasurementVectorSize(); d++ ) { mean[d] = covarianceCalculator->GetMean()[d]; } this->m_Gaussian->SetMean( mean ); this->m_Gaussian->SetCovariance( covarianceCalculator->GetCovarianceMatrix() ); } else { typedef itk::Statistics::CovarianceSampleFilter CovarianceCalculatorType; typename CovarianceCalculatorType::Pointer covarianceCalculator = CovarianceCalculatorType::New(); covarianceCalculator->SetInput( this->m_ListSample ); covarianceCalculator->Update(); typename GaussianType::MeanType mean; ::itk::Statistics::MeasurementVectorTraits::SetLength( mean, this->m_ListSample->GetMeasurementVectorSize() ); for( unsigned int d = 0; d < this->m_ListSample->GetMeasurementVectorSize(); d++ ) { mean[d] = covarianceCalculator->GetMean()[d]; } this->m_Gaussian->SetMean( mean ); this->m_Gaussian->SetCovariance( covarianceCalculator->GetCovarianceMatrix() ); } } else { itkWarningMacro( "The input list sample has <= 1 element." << "Function evaluations will be equal to 0." ); } } template TOutput GaussianListSampleFunction ::Evaluate( const InputMeasurementVectorType &measurement ) const { try { return this->m_Gaussian->Evaluate( measurement ); } catch(...) { return 0.0; } } /** * Standard "PrintSelf" method */ template void GaussianListSampleFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "mean = " << this->m_Gaussian->GetMean() << ", "; typename GaussianType::CovarianceType covariance = this->m_Gaussian->GetCovariance(); os << "covariance = ["; for( unsigned int r = 0; r < covariance.Rows(); r++ ) { for( unsigned int c = 0; c < covariance.Cols() - 1; c++ ) { os << covariance( r, c ) << ", "; } if( r == covariance.Rows() - 1 ) { os << covariance( r, covariance.Cols() - 1 ) << "]" << std::endl; } else { os << covariance( r, covariance.Cols() - 1 ) << "; "; } } } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsGrubbsRosnerListSampleFilter.h000066400000000000000000000074351147325206600267110ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsGrubbsRosnerListSampleFilter.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsGrubbsRosnerListSampleFilter_h #define __antsGrubbsRosnerListSampleFilter_h #include "antsListSampleToListSampleFilter.h" #include namespace itk { namespace ants { namespace Statistics { /** \class GrubbsRosnerListSampleFilter * \brief Base class of filters intended to generate scalar samples from * intensity samples. * */ template class ITK_EXPORT GrubbsRosnerListSampleFilter : public ListSampleToListSampleFilter { public: /** * Standard class typedefs. */ typedef GrubbsRosnerListSampleFilter Self; typedef ListSampleToListSampleFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Standard macros */ itkTypeMacro( GrubbsRosnerListSampleFilter, ListSampleToScalarListSampleFilter ); /** * Method for creation through the object factory. */ itkNewMacro( Self ); /** * Conveneient typedefs */ typedef double RealType; typedef TScalarListSample ScalarListSampleType; typedef typename ScalarListSampleType ::MeasurementVectorType MeasurementVectorType; typedef typename ScalarListSampleType ::InstanceIdentifier InstanceIdentifierType; typedef std::vector InstanceIdentifierContainerType; enum OutlierHandlingType { None, Trim, Winsorize }; itkSetMacro( OutlierHandling, OutlierHandlingType ); itkGetConstMacro( OutlierHandling, OutlierHandlingType ); itkSetMacro( WinsorizingLevel, RealType ); itkGetConstMacro( WinsorizingLevel, RealType ); itkSetMacro( SignificanceLevel, RealType ); itkGetConstMacro( SignificanceLevel, RealType ); InstanceIdentifierContainerType GetOutlierInstanceIdentifiers() { return this->m_OutlierInstanceIdentifiers; } // itkGetConstMacro( Outliers, InstanceIdentifierContainerType ); protected: GrubbsRosnerListSampleFilter(); virtual ~GrubbsRosnerListSampleFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; virtual void GenerateData(); private: GrubbsRosnerListSampleFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented InstanceIdentifierType FindMaximumNonOutlierDeviationValue( RealType, RealType ); bool IsMeasurementAnOutlier( RealType, RealType, RealType, unsigned long ); OutlierHandlingType m_OutlierHandling; RealType m_WinsorizingLevel; InstanceIdentifierContainerType m_OutlierInstanceIdentifiers; RealType m_SignificanceLevel; }; // end of class } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsGrubbsRosnerListSampleFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsGrubbsRosnerListSampleFilter.txx000066400000000000000000000210111147325206600272670ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsGrubbsRosnerListSampleFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsGrubbsRosnerListSampleFilter_txx #define __antsGrubbsRosnerListSampleFilter_txx #include "antsGrubbsRosnerListSampleFilter.h" #include "itkTDistribution.h" namespace itk { namespace ants { namespace Statistics { template GrubbsRosnerListSampleFilter ::GrubbsRosnerListSampleFilter() { this->AllocateOutput(); this->GetOutput()->SetMeasurementVectorSize( 1 ); this->m_OutlierHandling = Winsorize; this->m_WinsorizingLevel = 0.10; this->m_SignificanceLevel = 0.05; } template GrubbsRosnerListSampleFilter ::~GrubbsRosnerListSampleFilter() { } template void GrubbsRosnerListSampleFilter ::GenerateData() { if( this->GetInput()->GetMeasurementVectorSize() != 1 ) { itkExceptionMacro( "The input sample must be univariate." ); } const unsigned int scalarMeasurementVectorSize = this->GetOutput()->GetMeasurementVectorSize(); this->GetOutput()->SetMeasurementVectorSize( scalarMeasurementVectorSize ); /** * A common hueristic is that Grubbs-Rosner outlier removal does not work for * sample sizes less than or equal to 6. */ if( this->GetInput()->Size() <= 6 ) { typename ScalarListSampleType::ConstIterator It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); MeasurementVectorType outputMeasurement; outputMeasurement.SetSize( scalarMeasurementVectorSize ); for( unsigned int d = 0; d < scalarMeasurementVectorSize; d++ ) { outputMeasurement[d] = inputMeasurement[d]; } this->GetOutput()->PushBack( outputMeasurement ); ++It; } return; } /** * Otherwise, iterate through the input list, removing t */ RealType mean = 0.0; RealType variance = 0.0; RealType count = 0.0; typename ScalarListSampleType::ConstIterator It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); count += 1.0; variance += ( count - 1.0 ) * vnl_math_sqr( inputMeasurement[0] - mean ) / count; mean = mean + ( inputMeasurement[0] - mean ) / count; ++It; } variance /= ( count - 1.0 ); bool outlierFound = true; this->m_OutlierInstanceIdentifiers.clear(); while( outlierFound == true && ( this->GetInput()->Size() - this->m_OutlierInstanceIdentifiers.size() > 6 ) ) { outlierFound = false; InstanceIdentifierType id = this->FindMaximumNonOutlierDeviationValue( mean, variance ); if( this->GetInput()->GetFrequency( id ) > 0 ) { MeasurementVectorType measurement = this->GetInput()->GetMeasurementVector( id ); outlierFound = this->IsMeasurementAnOutlier( measurement[0], mean, variance, this->GetInput()->Size() - this->m_OutlierInstanceIdentifiers.size() ); if( outlierFound ) { /** Retabulate the variance and mean by removing the previous estimate */ RealType count = this->GetInput()->Size() - this->m_OutlierInstanceIdentifiers.size(); mean = ( mean * count - measurement[0] ) / ( count - 1.0 ); variance = ( count - 1.0 ) * variance - ( count - 1.0 ) * vnl_math_sqr( measurement[0] - mean ) / count; variance /= ( count - 2.0 ); this->m_OutlierInstanceIdentifiers.push_back( id ); } } } RealType lowerWinsorBound = 0.0; RealType upperWinsorBound = 0.0; if( this->m_OutlierHandling == Winsorize ) { typename itk::Statistics::TDistribution::Pointer tdistribution = itk::Statistics::TDistribution::New(); RealType t = tdistribution->EvaluateInverseCDF( 1.0 - 0.5 * this->m_WinsorizingLevel, this->GetInput()->Size() - this->m_OutlierInstanceIdentifiers.size() ); lowerWinsorBound = mean - t * vcl_sqrt( variance ); upperWinsorBound = mean + t * vcl_sqrt( variance ); } It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); MeasurementVectorType outputMeasurement; outputMeasurement.SetSize( scalarMeasurementVectorSize ); if( this->m_OutlierHandling == None || std::find( this->m_OutlierInstanceIdentifiers.begin(), this->m_OutlierInstanceIdentifiers.end(), It.GetInstanceIdentifier() ) == this->m_OutlierInstanceIdentifiers.end() ) { outputMeasurement[0] = inputMeasurement[0]; this->GetOutput()->PushBack( outputMeasurement ); } else if( this->m_OutlierHandling == Winsorize ) { if( inputMeasurement[0] < lowerWinsorBound ) { outputMeasurement[0] = lowerWinsorBound; } else { outputMeasurement[0] = upperWinsorBound; } this->GetOutput()->PushBack( outputMeasurement ); } ++It; } } template typename GrubbsRosnerListSampleFilter ::InstanceIdentifierType GrubbsRosnerListSampleFilter ::FindMaximumNonOutlierDeviationValue( RealType mean, RealType variance ) { RealType maximumDeviation = 0.0; InstanceIdentifierType maximumID = NumericTraits::max(); typename ScalarListSampleType::ConstIterator It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { MeasurementVectorType inputMeasurement = It.GetMeasurementVector(); InstanceIdentifierType inputID = It.GetInstanceIdentifier(); if( std::find( this->m_OutlierInstanceIdentifiers.begin(), this->m_OutlierInstanceIdentifiers.end(), inputID ) == this->m_OutlierInstanceIdentifiers.end() ) { if( vnl_math_abs( inputMeasurement[0] - mean ) > maximumDeviation ) { maximumDeviation = vnl_math_abs( inputMeasurement[0] - mean ); maximumID = inputID; } } ++It; } return maximumID; } template bool GrubbsRosnerListSampleFilter ::IsMeasurementAnOutlier( RealType x, RealType mean, RealType variance, unsigned long N ) { /** * The Grubb critical two-sided value is defined to be * (N-1)/sqrt(N)*sqrt( t*t / (N-2+t*t) ) where t is at the * (alpha / (2N)) signficance level with N-2 degrees of freedom. */ RealType sig = this->m_SignificanceLevel / ( 2.0 * static_cast( N ) ); typename itk::Statistics::TDistribution::Pointer tdistribution = itk::Statistics::TDistribution::New(); RealType t = tdistribution->EvaluateInverseCDF( 1.0 - sig, N - 2 ); RealType nu = static_cast( N - 1 ); RealType g = nu / vcl_sqrt( nu + 1.0 ) * vcl_sqrt( t*t / ( nu - 1 + t*t ) ); return g < ( vnl_math_abs( x - mean ) / vcl_sqrt( variance ) ); } template void GrubbsRosnerListSampleFilter ::PrintSelf( std::ostream& os, Indent indent ) const { os << indent << "Significance level: " << this->m_SignificanceLevel << std::endl; os << indent << "Outlier handling: "; if( this->m_OutlierHandling == None ) { os << "None" << std::endl; } if( this->m_OutlierHandling == Trim ) { os << "Trim" << std::endl; } if( this->m_OutlierHandling == Winsorize ) { os << "Winsorize"; os << " (level = " << this->m_WinsorizingLevel << ")" << std::endl; } if( this->m_OutlierInstanceIdentifiers.size() > 0 ) { os << indent << "Outlier Identifiers: " << std::endl; for( unsigned int d = 0; d < this->m_OutlierInstanceIdentifiers.size(); d++ ) { os << indent << " " << this->m_OutlierInstanceIdentifiers[d] << std::endl; } } else { os << indent << "There are no outliers." << std::endl; } } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsHistogramParzenWindowsListSampleFunction.h000066400000000000000000000066531147325206600313250ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsHistogramParzenWindowsListSampleFunction.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsHistogramParzenWindowsListSampleFunction_h #define __antsHistogramParzenWindowsListSampleFunction_h #include "antsListSampleFunction.h" #include "itkImage.h" namespace itk { namespace ants { namespace Statistics { /** \class HistogramParzenWindowsListSampleFunction.h * \brief point set filter. */ template class ITK_EXPORT HistogramParzenWindowsListSampleFunction : public ListSampleFunction { public: typedef HistogramParzenWindowsListSampleFunction Self; typedef ListSampleFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( HistogramParzenWindowsListSampleFunction, ListSampleFunction ); typedef typename Superclass::InputListSampleType InputListSampleType; typedef typename Superclass::InputMeasurementVectorType InputMeasurementVectorType; typedef typename Superclass::InputMeasurementType InputMeasurementType; /** List sample typedef support. */ typedef TListSample ListSampleType; /** Other typedef */ typedef TOutput RealType; typedef TOutput OutputType; typedef Image HistogramImageType; /** Helper functions */ itkSetMacro( Sigma, RealType ); itkGetConstMacro( Sigma, RealType ); itkSetMacro( NumberOfHistogramBins, unsigned int ); itkGetConstMacro( NumberOfHistogramBins, unsigned int ); virtual void SetInputListSample( const InputListSampleType * ptr ); virtual TOutput Evaluate( const InputMeasurementVectorType& measurement ) const; protected: HistogramParzenWindowsListSampleFunction(); virtual ~HistogramParzenWindowsListSampleFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: //purposely not implemented HistogramParzenWindowsListSampleFunction( const Self& ); void operator=( const Self& ); unsigned int m_NumberOfHistogramBins; RealType m_Sigma; std::vector m_HistogramImages; }; } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsHistogramParzenWindowsListSampleFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsHistogramParzenWindowsListSampleFunction.txx000066400000000000000000000172311147325206600317130ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsHistogramParzenWindowsListSampleFunction.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsHistogramParzenWindowsListSampleFunction_txx #define __antsHistogramParzenWindowsListSampleFunction_txx #include "antsHistogramParzenWindowsListSampleFunction.h" #include "itkArray.h" #include "itkBSplineInterpolateImageFunction.h" #include "itkContinuousIndex.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkDivideByConstantImageFilter.h" #include "itkStatisticsImageFilter.h" namespace itk { namespace ants { namespace Statistics { template HistogramParzenWindowsListSampleFunction ::HistogramParzenWindowsListSampleFunction() { this->m_NumberOfHistogramBins = 32; this->m_Sigma = 1.0; } template HistogramParzenWindowsListSampleFunction ::~HistogramParzenWindowsListSampleFunction() { } template void HistogramParzenWindowsListSampleFunction ::SetInputListSample( const InputListSampleType * ptr ) { this->m_ListSample = ptr; if( !this->m_ListSample ) { return; } if( this->m_ListSample->Size() <= 1 ) { itkWarningMacro( "The input list sample has <= 1 element." << "Function evaluations will be equal to 0." ); return; } const unsigned int Dimension = this->m_ListSample->GetMeasurementVectorSize(); /** * Find the min/max values to define the histogram domain */ Array minValues( Dimension ); minValues.Fill( NumericTraits::max() ); Array maxValues( Dimension ); maxValues.Fill( NumericTraits::NonpositiveMin() ); typename InputListSampleType::ConstIterator It = this->m_ListSample->Begin(); while( It != this->m_ListSample->End() ) { InputMeasurementVectorType inputMeasurement = It.GetMeasurementVector(); for( unsigned int d = 0; d < Dimension; d++ ) { if( inputMeasurement[d] < minValues[d] ) { minValues[d] = inputMeasurement[d]; } if( inputMeasurement[d] > maxValues[d] ) { maxValues[d] = inputMeasurement[d]; } } ++It; } this->m_HistogramImages.clear(); for( unsigned int d = 0; d < Dimension; d++ ) { this->m_HistogramImages.push_back( HistogramImageType::New() ); typename HistogramImageType::SpacingType spacing; spacing[0] = ( maxValues[d] - minValues[d] ) / static_cast( this->m_NumberOfHistogramBins - 1 ); typename HistogramImageType::PointType origin; origin[0] = minValues[d] - 3.0 * ( this->m_Sigma * spacing[0] ); typename HistogramImageType::SizeType size; size[0] = static_cast( vcl_ceil( ( maxValues[d] + 3.0 * ( this->m_Sigma * spacing[0] ) - ( minValues[d] - 3.0 * ( this->m_Sigma * spacing[0] ) ) ) / spacing[0] ) ); this->m_HistogramImages[d]->SetOrigin( origin ); this->m_HistogramImages[d]->SetSpacing( spacing ); this->m_HistogramImages[d]->SetRegions( size ); this->m_HistogramImages[d]->Allocate(); this->m_HistogramImages[d]->FillBuffer( 0 ); } unsigned long count = 0; It = this->m_ListSample->Begin(); while( It != this->m_ListSample->End() ) { InputMeasurementVectorType inputMeasurement = It.GetMeasurementVector(); RealType newWeight = 1.0; if( this->m_Weights.Size() == this->m_ListSample->Size() ) { newWeight = this->m_Weights[count]; } for( unsigned int d = 0; d < Dimension; d++ ) { typename HistogramImageType::PointType point; point[0] = inputMeasurement[d]; ContinuousIndex cidx; this->m_HistogramImages[d]->TransformPhysicalPointToContinuousIndex( point, cidx ); typename HistogramImageType::IndexType idx; idx[0] = static_cast( vcl_floor( cidx[0] ) ); if( this->m_HistogramImages[d]->GetLargestPossibleRegion().IsInside( idx ) ) { RealType oldWeight = this->m_HistogramImages[d]->GetPixel( idx ); this->m_HistogramImages[d]->SetPixel( idx, ( 1.0 - ( cidx[0] - idx[0] ) ) * newWeight + oldWeight ); } idx[0]++; if( this->m_HistogramImages[d]->GetLargestPossibleRegion().IsInside( idx ) ) { RealType oldWeight = this->m_HistogramImages[d]->GetPixel( idx ); this->m_HistogramImages[d]->SetPixel( idx, ( 1.0 - ( idx[0] - cidx[0] ) ) * newWeight + oldWeight ); } } ++count; ++It; } for( unsigned int d = 0; d < Dimension; d++ ) { typedef DiscreteGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer gaussian = GaussianFilterType::New(); gaussian->SetInput( this->m_HistogramImages[d] ); gaussian->SetVariance( this->m_Sigma * this->m_Sigma ); gaussian->SetMaximumError( 0.01 ); gaussian->SetUseImageSpacing( false ); gaussian->Update(); typedef StatisticsImageFilter StatsFilterType; typename StatsFilterType::Pointer stats = StatsFilterType::New(); stats->SetInput( gaussian->GetOutput() ); stats->Update(); typedef DivideByConstantImageFilter DividerType; typename DividerType::Pointer divider = DividerType::New(); divider->SetInput( gaussian->GetOutput() ); divider->SetConstant( stats->GetSum() ); divider->Update(); this->m_HistogramImages[d] = divider->GetOutput(); } } template TOutput HistogramParzenWindowsListSampleFunction ::Evaluate( const InputMeasurementVectorType &measurement ) const { try { typedef BSplineInterpolateImageFunction InterpolatorType; RealType probability = 1.0; for( unsigned int d = 0; d < this->m_HistogramImages.size(); d++ ) { typename HistogramImageType::PointType point; point[0] = measurement[d]; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetSplineOrder( 3 ); interpolator->SetInputImage( this->m_HistogramImages[d] ); if( interpolator->IsInsideBuffer( point ) ) { probability *= interpolator->Evaluate( point ); } else { return 0; } } return probability; } catch(...) { return 0; } } /** * Standard "PrintSelf" method */ template void HistogramParzenWindowsListSampleFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "Sigma: " << this->m_Sigma << std::endl; os << indent << "Number of histogram bins: " << this->m_NumberOfHistogramBins << std::endl; } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsListSampleFunction.h000066400000000000000000000107141147325206600247050ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsListSampleFunction.h,v $ Language: C++ Date: $Date: 2008/10/18 00:20:04 $ Version: $Revision: 1.1.1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsListSampleFunction_h #define __antsListSampleFunction_h #include "itkFunctionBase.h" #include "itkArray.h" namespace itk { namespace ants { namespace Statistics { /** \class ListSampleFunction * \brief Evaluates a function of an image at specified position. * * ListSampleFunction is a baseclass for all objects that evaluates * a function of a list sample at a measurement * This class is templated over the input list type, the type * of the function output and the coordinate representation type * (e.g. float or double). * * The input list sample is set via method SetInputListSample(). * The methods Evaluate() evaluates the function at a measurement vector. * * \ingroup ListSampleFunctions */ template class ITK_EXPORT ListSampleFunction : public FunctionBase { public: /** Standard class typedefs. */ typedef ListSampleFunction Self; typedef FunctionBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( ListSampleFunction, FunctionBase ); /** InputListSampleType typedef support. */ typedef TInputListSample InputListSampleType; /** Array typedef for weights */ typedef Array WeightArrayType; /** InputPixel typedef support */ typedef typename InputListSampleType::MeasurementVectorType InputMeasurementVectorType; typedef typename InputListSampleType::MeasurementType InputMeasurementType; /** OutputType typedef support. */ typedef TOutput OutputType; /** CoordRepType typedef support. */ typedef TCoordRep CoordRepType; /** Set the input point set. * \warning this method caches BufferedRegion information. * If the BufferedRegion has changed, user must call * SetInputListSample again to update cached values. */ virtual void SetInputListSample( const InputListSampleType * ptr ); /** Get the input image. */ const InputListSampleType * GetInputListSample() const { return m_ListSample.GetPointer(); } /** Clear the input list sample to free memory */ virtual void ClearInputListSample() { this->SetInputListSample( NULL ); } /** Sets the weights using an array */ virtual void SetWeights( WeightArrayType* array ); /** Gets the weights array */ WeightArrayType* GetWeights(); /** Evaluate the function at specified Point position. * Subclasses must provide this method. */ virtual TOutput Evaluate( const InputMeasurementVectorType& measurement ) const = 0; protected: ListSampleFunction(); ~ListSampleFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** Const pointer to the input image. */ typename InputListSampleType::ConstPointer m_ListSample; WeightArrayType m_Weights; private: ListSampleFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end of namespace Statistics } // end of namespace ants } // end of namespace itk // Define instantiation macro for this template. #define ITK_TEMPLATE_ListSampleFunction(_, EXPORT, x, y) namespace itk { \ _(3(class EXPORT ListSampleFunction< ITK_TEMPLATE_3 x >)) \ namespace Templates { typedef ListSampleFunction< ITK_TEMPLATE_3 x > ListSampleFunction##y; } \ } #if ITK_TEMPLATE_EXPLICIT # include "Templates/antsListSampleFunction+-.h" #endif #if ITK_TEMPLATE_TXX # include "antsListSampleFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsListSampleFunction.txx000066400000000000000000000043301147325206600252760ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsListSampleFunction.txx,v $ Language: C++ Date: $Date: 2008/10/18 00:20:04 $ Version: $Revision: 1.1.1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsListSampleFunction_txx #define __antsListSampleFunction_txx #include "antsListSampleFunction.h" namespace itk { namespace ants { namespace Statistics { /** * Constructor */ template ListSampleFunction ::ListSampleFunction() { this->m_ListSample = NULL; } /** * Standard "PrintSelf" method */ template void ListSampleFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "InputListSample: " << m_ListSample.GetPointer() << std::endl; } template void ListSampleFunction ::SetWeights( WeightArrayType* array ) { this->m_Weights = *array; this->Modified(); } template typename ListSampleFunction::WeightArrayType* ListSampleFunction ::GetWeights() { return &this->m_Weights; } /** * Initialize by setting the input point set */ template void ListSampleFunction ::SetInputListSample( const InputListSampleType * ptr ) { // set the input image m_ListSample = ptr; } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsListSampleToListSampleFilter.h000066400000000000000000000055751147325206600266570ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsListSampleToListSampleFilter.h,v $ Language: C++ Date: $$ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsListSampleToListSampleFilter_h #define __antsListSampleToListSampleFilter_h #include "itkProcessObject.h" namespace itk { namespace ants { namespace Statistics { /** \class ListSampleToListSampleFilter * \brief Base class for filters that take a list sample as an input and output * another list sample. * * ListSampleToListSampleFilter is the base class for all process objects that output * list sample data, and require list sample data as input. Specifically, this class * defines the SetInput() method for defining the input to a filter. * * \ingroup ListSampleFilters * */ template class ITK_EXPORT ListSampleToListSampleFilter : public ProcessObject { public: /** Standard class typedefs. */ typedef ListSampleToListSampleFilter Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( ListSampleToListSampleFilter, ProcessObject ); /** Some convenient typedefs. */ typedef TInputListSample InputListSampleType; typedef TOutputListSample OutputListSampleType; /** Set the list sample input of this object. */ void SetInput( const InputListSampleType *input ); /** Get the list sample input of this object. */ InputListSampleType * GetInput(); /** Get the list sample output of this object. */ OutputListSampleType * GetOutput(); virtual void Update() { this->GenerateData(); } protected: ListSampleToListSampleFilter(); ~ListSampleToListSampleFilter() {}; virtual void GenerateData() = 0; void AllocateOutput(); private: ListSampleToListSampleFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented // typename InputListSampleType::ConstPointer m_InputListSample; // typename OutputListSampleType::Pointer m_OutputListSample; }; } // end namespace Statistics } // end namespace ants } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsListSampleToListSampleFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsListSampleToListSampleFilter.txx000066400000000000000000000060311147325206600272370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsListSampleToListSampleFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkListSampleToListSampleFilter_txx #define _itkListSampleToListSampleFilter_txx #include "antsListSampleToListSampleFilter.h" namespace itk { namespace ants { namespace Statistics { /** * */ template ListSampleToListSampleFilter ::ListSampleToListSampleFilter() { // Modify superclass default values, can be overridden by subclasses this->SetNumberOfRequiredInputs( 1 ); this->SetNumberOfRequiredOutputs( 1 ); } template void ListSampleToListSampleFilter ::SetInput( const TInputListSample *input ) { // this->m_InputListSample = const_cast( input ); this->ProcessObject::SetNthInput( 0, reinterpret_cast( const_cast( input ) ) ); } template void ListSampleToListSampleFilter ::AllocateOutput() { typename DataObject::Pointer obj = reinterpret_cast(TOutputListSample::New().GetPointer()); // typename TOutputListSample::Pointer output // = reinterpret_cast(obj.GetPointer()); this->ProcessObject::SetNumberOfRequiredOutputs( 1 ); this->ProcessObject::SetNthOutput( 0, obj.GetPointer() ); // this->m_OutputListSample = OutputListSampleType::New(); } /** * */ template typename ListSampleToListSampleFilter::InputListSampleType * ListSampleToListSampleFilter ::GetInput() { return reinterpret_cast( this->ProcessObject::GetInput( 0 ) ); } template typename ListSampleToListSampleFilter::OutputListSampleType * ListSampleToListSampleFilter ::GetOutput() { if (this->GetNumberOfOutputs() < 1) { return 0; } // we assume that the first output is of the templated type return reinterpret_cast( this->ProcessObject::GetOutput( 0 ) ); // return this->m_OutputListSample.GetPointer(); } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsLogEuclideanGaussianListSampleFunction.h000066400000000000000000000065241147325206600306600ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsLogEuclideanGaussianListSampleFunction.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsLogEuclideanGaussianListSampleFunction_h #define __antsLogEuclideanGaussianListSampleFunction_h #include "antsListSampleFunction.h" #include "itkVariableSizeMatrix.h" namespace itk { namespace ants { namespace Statistics { /** \class LogEuclideanGaussianListSampleFunction.h * \brief */ template class ITK_EXPORT LogEuclideanGaussianListSampleFunction : public ListSampleFunction { public: typedef LogEuclideanGaussianListSampleFunction Self; typedef ListSampleFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( LogEuclideanGaussianListSampleFunction, ListSampleFunction ); typedef typename Superclass::InputListSampleType InputListSampleType; typedef typename Superclass::InputMeasurementVectorType InputMeasurementVectorType; typedef typename Superclass::InputMeasurementType InputMeasurementType; /** List sample typedef support. */ typedef TListSample ListSampleType; /** Other typedef */ typedef TOutput RealType; typedef TOutput OutputType; typedef VariableSizeMatrix TensorType; /** Helper functions */ virtual void SetInputListSample( const InputListSampleType * ptr ); virtual TOutput Evaluate( const InputMeasurementVectorType& measurement ) const; protected: LogEuclideanGaussianListSampleFunction(); virtual ~LogEuclideanGaussianListSampleFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); TensorType LogTensorTransform( const TensorType & ) const; TensorType ExpTensorTransform( const TensorType & ) const; RealType CalculateTensorDistance( const TensorType &, const TensorType & ) const; TensorType m_MeanTensor; RealType m_Dispersion; private: //purposely not implemented LogEuclideanGaussianListSampleFunction( const Self& ); void operator=( const Self& ); }; } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsLogEuclideanGaussianListSampleFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsLogEuclideanGaussianListSampleFunction.txx000066400000000000000000000172511147325206600312530ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsLogEuclideanGaussianListSampleFunction.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsLogEuclideanGaussianListSampleFunction_txx #define __antsLogEuclideanGaussianListSampleFunction_txx #include "antsLogEuclideanGaussianListSampleFunction.h" #include "itkDecomposeTensorFunction.h" #include "vnl/vnl_trace.h" namespace itk { namespace ants { namespace Statistics { template LogEuclideanGaussianListSampleFunction ::LogEuclideanGaussianListSampleFunction() { } template LogEuclideanGaussianListSampleFunction ::~LogEuclideanGaussianListSampleFunction() { } template void LogEuclideanGaussianListSampleFunction ::SetInputListSample( const InputListSampleType * ptr ) { this->m_ListSample = ptr; if( !this->m_ListSample ) { return; } if( this->m_ListSample->Size() > 1 ) { RealType L = static_cast( this->m_ListSample->GetMeasurementVectorSize() ); unsigned int D = static_cast( 0.5 * ( -1 + vcl_sqrt( 1.0 + 8.0 * L ) ) ); this->m_MeanTensor.SetSize( D, D ); this->m_MeanTensor.Fill( 0.0 ); unsigned long N = 0; RealType totalWeight = 0.0; typename InputListSampleType::ConstIterator It = this->m_ListSample->Begin(); while( It != this->m_ListSample->End() ) { InputMeasurementVectorType measurement = It.GetMeasurementVector(); TensorType T( D, D ); unsigned int index = 0; for( unsigned int i = 0; i < D; i++ ) { for( unsigned int j = i; j < D; j++ ) { T( i, j ) = measurement( index++ ); T( j, i ) = T( i, j ); } } T = this->LogTensorTransform( T ); RealType weight = 1.0; if( this->m_Weights.Size() == this->m_ListSample->Size() ) { weight = this->m_Weights[N++]; } totalWeight += weight; this->m_MeanTensor += ( T * weight ); ++It; } if( totalWeight > 0.0 ) { this->m_MeanTensor /= totalWeight; } this->m_MeanTensor = this->ExpTensorTransform( this->m_MeanTensor ); /** * Now calculate the dispersion (i.e. variance) */ this->m_Dispersion = 0.0; N = 0; It = this->m_ListSample->Begin(); while( It != this->m_ListSample->End() ) { InputMeasurementVectorType measurement = It.GetMeasurementVector(); TensorType T( D, D ); unsigned int index = 0; for( unsigned int i = 0; i < D; i++ ) { for( unsigned int j = i; j < D; j++ ) { T( i, j ) = measurement( index++ ); T( j, i ) = T( i, j ); } } RealType distance = this->CalculateTensorDistance( T, this->m_MeanTensor ); RealType weight = 1.0; if( this->m_Weights.Size() == this->m_ListSample->Size() ) { weight = this->m_Weights[N++]; } this->m_Dispersion += ( weight * vnl_math_sqr( distance ) ); ++It; } this->m_Dispersion /= static_cast( N ); } else { itkWarningMacro( "The input list sample has <= 1 element." << "Function evaluations will be equal to 0." ); } } template typename LogEuclideanGaussianListSampleFunction ::TensorType LogEuclideanGaussianListSampleFunction ::LogTensorTransform( const TensorType &T ) const { TensorType V; TensorType W; TensorType Tc = T; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( Tc, W, V ); for( unsigned int i = 0; i < W.Rows(); i++ ) { if( W( i, i ) > 0.0 ) { W( i, i ) = vcl_log( W( i, i ) ); } else { W( i, i ) = 0.0; } } W *= V.GetTranspose(); TensorType logT = V * W; return logT; } template typename LogEuclideanGaussianListSampleFunction ::TensorType LogEuclideanGaussianListSampleFunction ::ExpTensorTransform( const TensorType &T ) const { TensorType V; TensorType W; TensorType Tc = T; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( Tc, W, V ); for( unsigned int i = 0; i < W.Rows(); i++ ) { W( i, i ) = vcl_exp( W( i, i ) ); } W *= V.GetTranspose(); TensorType expT = V * W; return expT; } template typename LogEuclideanGaussianListSampleFunction ::RealType LogEuclideanGaussianListSampleFunction ::CalculateTensorDistance( const TensorType &S, const TensorType &T ) const { TensorType logS = this->LogTensorTransform( S ); TensorType logT = this->LogTensorTransform( T ); TensorType diff = logS - logT; TensorType diffSq = diff * diff; RealType distance = vcl_sqrt( vnl_trace( ( diffSq ).GetVnlMatrix() ) ); // RealType distance = ( ( logS - logT ).GetVnlMatrix() ).frobenius_norm(); return distance; } template TOutput LogEuclideanGaussianListSampleFunction ::Evaluate( const InputMeasurementVectorType &measurement ) const { unsigned int D = this->m_MeanTensor.Rows(); TensorType T( D, D ); unsigned int index = 0; for( unsigned int i = 0; i < D; i++ ) { for( unsigned int j = i; j < D; j++ ) { T( i, j ) = measurement( index++ ); T( j, i ) = T( i, j ); } } RealType distance = this->CalculateTensorDistance( T, this->m_MeanTensor ); RealType preFactor = 1.0 / ( vcl_sqrt( 2.0 * vnl_math::pi * this->m_Dispersion ) ); RealType probability = preFactor * vcl_exp( -0.5 * vnl_math_sqr( distance ) / this->m_Dispersion ); return probability; } /** * Standard "PrintSelf" method */ template void LogEuclideanGaussianListSampleFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "Mean tensor = ["; for( unsigned int r = 0; r < this->m_MeanTensor.Rows(); r++ ) { for( unsigned int c = 0; c < this->m_MeanTensor.Cols() - 1; c++ ) { os << this->m_MeanTensor( r, c ) << ", "; } if( r == this->m_MeanTensor.Rows() - 1 ) { os << this->m_MeanTensor( r, this->m_MeanTensor.Cols() - 1 ) << "], "; } else { os << this->m_MeanTensor( r, this->m_MeanTensor.Cols() - 1 ) << "; "; } } os << "Dispersion (variance) = " << this->m_Dispersion << std::endl; } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsManifoldParzenWindowsListSampleFunction.h000066400000000000000000000110011147325206600311000ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsManifoldParzenWindowsListSampleFunction.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsManifoldParzenWindowsListSampleFunction_h #define __antsManifoldParzenWindowsListSampleFunction_h #include "antsListSampleFunction.h" #include "itkGaussianMembershipFunction.h" #include "itkWeightedCentroidKdTreeGenerator.h" #include namespace itk { namespace ants { namespace Statistics { /** \class ManifoldParzenWindowsListSampleFunction.h * \brief point set filter. */ template class ITK_EXPORT ManifoldParzenWindowsListSampleFunction : public ListSampleFunction { public: typedef ManifoldParzenWindowsListSampleFunction Self; typedef ListSampleFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ManifoldParzenWindowsListSampleFunction, ListSampleFunction ); typedef typename Superclass::InputListSampleType InputListSampleType; typedef typename Superclass::InputMeasurementVectorType InputMeasurementVectorType; typedef typename Superclass::InputMeasurementType InputMeasurementType; /** List sample typedef support. */ typedef TListSample ListSampleType; /** Kd tree typedefs */ typedef typename itk::Statistics:: WeightedCentroidKdTreeGenerator TreeGeneratorType; typedef typename TreeGeneratorType::KdTreeType KdTreeType; typedef typename KdTreeType ::InstanceIdentifierVectorType NeighborhoodIdentifierType; /** Other typedef */ typedef TOutput RealType; typedef TOutput OutputType; typedef typename itk::Statistics::GaussianMembershipFunction GaussianType; typedef std::vector GaussianContainerType; typedef typename GaussianType::CovarianceType CovarianceMatrixType; /** Helper functions */ itkSetMacro( EvaluationKNeighborhood, unsigned int ); itkGetConstMacro( EvaluationKNeighborhood, unsigned int ); itkSetMacro( RegularizationSigma, RealType ); itkGetConstMacro( RegularizationSigma, RealType ); itkSetMacro( CovarianceKNeighborhood, unsigned int ); itkGetConstMacro( CovarianceKNeighborhood, unsigned int ); itkSetMacro( KernelSigma, RealType ); itkGetConstMacro( KernelSigma, RealType ); virtual void SetInputListSample( const InputListSampleType * ptr ); virtual TOutput Evaluate( const InputMeasurementVectorType& measurement ) const; protected: ManifoldParzenWindowsListSampleFunction(); virtual ~ManifoldParzenWindowsListSampleFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: //purposely not implemented ManifoldParzenWindowsListSampleFunction( const Self& ); void operator=( const Self& ); unsigned int m_CovarianceKNeighborhood; unsigned int m_EvaluationKNeighborhood; RealType m_RegularizationSigma; RealType m_KernelSigma; RealType m_NormalizationFactor; typename TreeGeneratorType::Pointer m_KdTreeGenerator; GaussianContainerType m_Gaussians; }; } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsManifoldParzenWindowsListSampleFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsManifoldParzenWindowsListSampleFunction.txx000066400000000000000000000170351147325206600315110ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsManifoldParzenWindowsListSampleFunction.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsManifoldParzenWindowsListSampleFunction_txx #define __antsManifoldParzenWindowsListSampleFunction_txx #include "antsManifoldParzenWindowsListSampleFunction.h" namespace itk { namespace ants { namespace Statistics { template ManifoldParzenWindowsListSampleFunction ::ManifoldParzenWindowsListSampleFunction() { this->m_KdTreeGenerator = NULL; this->m_EvaluationKNeighborhood = 50; this->m_RegularizationSigma = 1.0; this->m_CovarianceKNeighborhood = 0; this->m_KernelSigma = 0.0; } template ManifoldParzenWindowsListSampleFunction ::~ManifoldParzenWindowsListSampleFunction() { } template void ManifoldParzenWindowsListSampleFunction ::SetInputListSample( const InputListSampleType * ptr ) { this->m_ListSample = ptr; if( !this->m_ListSample ) { return; } if( this->m_ListSample->Size() <= 1 ) { itkWarningMacro( "The input list sample has <= 1 element." << "Function evaluations will be equal to 0." ); return; } /** * Generate KdTree and create set of gaussians from input point set */ this->m_KdTreeGenerator = TreeGeneratorType::New(); this->m_KdTreeGenerator->SetSample( const_cast( this->m_ListSample.GetPointer() ) ); this->m_KdTreeGenerator->SetBucketSize( 16 ); this->m_KdTreeGenerator->Update(); /** * Calculate covariance matrices */ this->m_Gaussians.resize( this->m_ListSample->Size() ); const unsigned int Dimension = this->m_ListSample->GetMeasurementVectorSize(); unsigned long count = 0; typename InputListSampleType::ConstIterator It = this->m_ListSample->Begin(); while( It != this->m_ListSample->End() ) { InputMeasurementVectorType inputMeasurement = It.GetMeasurementVector(); typename GaussianType::MeanType mean( Dimension ); for( unsigned int d = 0; d < Dimension; d++ ) { mean[d] = inputMeasurement[d]; } this->m_Gaussians[count] = GaussianType::New(); this->m_Gaussians[count]->SetMean( mean ); if( this->m_CovarianceKNeighborhood > 0 ) { /** Temporarily set the covariance */ CovarianceMatrixType Cov( Dimension, Dimension ); Cov.SetIdentity(); Cov *= this->m_KernelSigma; this->m_Gaussians[count]->SetCovariance( Cov ); Cov.Fill( 0 ); typename TreeGeneratorType::KdTreeType ::InstanceIdentifierVectorType neighbors; unsigned int numberOfNeighbors = vnl_math_min( this->m_CovarianceKNeighborhood, static_cast( this->m_ListSample->Size() ) ); this->m_KdTreeGenerator->GetOutput()->Search( inputMeasurement, numberOfNeighbors, neighbors ); RealType denominator = 0.0; for( unsigned int j = 0; j < numberOfNeighbors; j++ ) { if( neighbors[j] != count && neighbors[j] < this->m_ListSample->Size() ) { InputMeasurementVectorType neighbor = this->m_KdTreeGenerator->GetOutput()->GetMeasurementVector( neighbors[j] ); RealType kernelValue = this->m_Gaussians[count]->Evaluate( neighbor ); if( this->m_Weights.Size() == this->m_Gaussians.size() ) { kernelValue *= this->m_Weights[count]; } denominator += kernelValue; if( kernelValue > 0.0 ) { for( unsigned int m = 0; m < Dimension; m++ ) { for( unsigned int n = m; n < Dimension; n++ ) { RealType covariance = kernelValue * ( neighbor[m] - inputMeasurement[m] ) * ( neighbor[n] - inputMeasurement[n] ); Cov( m, n ) += covariance; Cov( n, m ) += covariance; } } } } } if( denominator > 0.0 ) { Cov /= denominator; } for( unsigned int m = 0; m < Dimension; m++ ) { Cov( m, m ) += ( this->m_RegularizationSigma * this->m_RegularizationSigma ); } this->m_Gaussians[count]->SetCovariance( Cov ); } else { CovarianceMatrixType Cov( Dimension, Dimension ); Cov.SetIdentity(); Cov *= this->m_RegularizationSigma; this->m_Gaussians[count]->SetCovariance( Cov ); } ++It; ++count; } /** * Calculate normalization factor */ this->m_NormalizationFactor = 0.0; for( unsigned int i = 0; i < this->m_Gaussians.size(); i++ ) { if( this->m_Weights.Size() == this->m_Gaussians.size() ) { this->m_NormalizationFactor += this->m_Weights[i]; } else { this->m_NormalizationFactor += 1.0; } } } template TOutput ManifoldParzenWindowsListSampleFunction ::Evaluate( const InputMeasurementVectorType &measurement ) const { try { unsigned int numberOfNeighbors = vnl_math_min( this->m_EvaluationKNeighborhood, static_cast( this->m_Gaussians.size() ) ); OutputType sum = 0.0; if( numberOfNeighbors == this->m_Gaussians.size() ) { for( unsigned int j = 0; j < this->m_Gaussians.size(); j++ ) { sum += static_cast( this->m_Gaussians[j]->Evaluate( measurement ) ); } } else { typename TreeGeneratorType::KdTreeType ::InstanceIdentifierVectorType neighbors; this->m_KdTreeGenerator->GetOutput()->Search( measurement, numberOfNeighbors, neighbors ); for( unsigned int j = 0; j < numberOfNeighbors; j++ ) { sum += static_cast( this->m_Gaussians[neighbors[j]]->Evaluate( measurement ) ); } } return static_cast( sum / this->m_NormalizationFactor ); } catch(...) { return 0; } } /** * Standard "PrintSelf" method */ template void ManifoldParzenWindowsListSampleFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "Regularization sigma: " << this->m_RegularizationSigma << std::endl; os << indent << "Evaluation K neighborhood: " << this->m_EvaluationKNeighborhood << std::endl; if( this->m_CovarianceKNeighborhood > 0 ) { os << indent << "Covariance K neighborhood: " << this->m_CovarianceKNeighborhood << std::endl; os << indent << "Kernel sigma: " << this->m_KernelSigma << std::endl; } } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsPassThroughListSampleFilter.h000066400000000000000000000050151147325206600265330ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsPassThroughListSampleFilter.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsPassThroughListSampleFilter_h #define __antsPassThroughListSampleFilter_h #include "antsListSampleToListSampleFilter.h" namespace itk { namespace ants { namespace Statistics { /** \class PassThroughListSampleFilter * \brief Simple class which pass the input to the output. * */ template class ITK_EXPORT PassThroughListSampleFilter : public ListSampleToListSampleFilter { public: /** * Standard class typedefs. */ typedef PassThroughListSampleFilter Self; typedef ListSampleToListSampleFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Standard macros */ itkTypeMacro( PassThroughListSampleFilter, ListSampleToScalarListSampleFilter ); /** * Method for creation through the object factory. */ itkNewMacro( Self ); /** * Conveneient typedefs */ typedef TListSample ListSampleType; typedef ListSampleType InputType; typedef typename ListSampleType::MeasurementVectorType MeasurementVectorType; typedef typename ListSampleType::MeasurementType MeasurementType; protected: PassThroughListSampleFilter(); virtual ~PassThroughListSampleFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; virtual void GenerateData(); private: PassThroughListSampleFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented }; // end of class } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "antsPassThroughListSampleFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/ImageSegmentation/antsPassThroughListSampleFilter.txx000066400000000000000000000036441147325206600271350ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsPassThroughListSampleFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsPassThroughListSampleFilter_txx #define __antsPassThroughListSampleFilter_txx #include "antsPassThroughListSampleFilter.h" namespace itk { namespace ants { namespace Statistics { template PassThroughListSampleFilter ::PassThroughListSampleFilter() { this->AllocateOutput(); this->GetOutput()->SetMeasurementVectorSize( this->GetInput()->GetMeasurementVectorSize() ); } template PassThroughListSampleFilter ::~PassThroughListSampleFilter() { } template void PassThroughListSampleFilter ::GenerateData() { const unsigned int measurementVectorSize = this->GetOutput()->GetMeasurementVectorSize(); /** * Simply pass the input to the output. */ typename ListSampleType::ConstIterator It = this->GetInput()->Begin(); while( It != this->GetInput()->End() ) { this->GetOutput()->PushBack( It.GetMeasurementVector() ); ++It; } } template void PassThroughListSampleFilter ::PrintSelf( std::ostream& os, Indent indent ) const { this->Superclass::PrintSelf( os, indent ); } } // end of namespace Statistics } // end of namespace ants } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/README.txt000066400000000000000000000143441147325206600161640ustar00rootroot00000000000000Release 1.9.2 --- svn release 674++ Homepage: http://www.picsl.upenn.edu/ANTS/ Introduction -- ANTS is a tool for computational neuroanatomy based on medical images. ANTS reads any image type that can be read by ITK (www.itk.org), that is, jpg, tiff, hdr, nii, nii.gz, mha/d and more image types as well. For the most part, ANTS will output float images which you can convert to other types with the ANTS ConvertImagePixelType tool. ImageMath has a bunch of basic utilities such as multiplication, inversion and many more advanced tools such as computation of the Lipschitz norm of a deformation field. ANTS programs may be called from the command line on almost any platform .... you can compile the code yourself or use the precompiled binaries for Windows (Vista), OSX (Darwin) or linux (32 bit or 64 bit). Download the binaries that are correct for you. If you are a naive user (not from a medical imaging background) then you might still find the tools here useful. Many of the operations available, for instance, in PhotoShop are available in ANTS and many more are available as well. For instance, ANTS tools may be useful in face mapping / morphing and also in generating animations from two different images, for instance, interpolating between frames in a movie. But, mainly, ANTS is useful for brain mapping, segmentation, measuring cortical thickness and in generating automated or semi-automated labeling of three-dimensional imagery (e.g. labeling hippocampus or cortical regions or lobes of the lung). Many prior-based segmentation possibilities are available in the Atropos tool, including three tissue segmentation, structure-specific segmentation and brain extracton. The ants.pdf file has more details and examples. New Stuff 1.9.2 : New atropos interface + ROIStatistics in ImageMath New Stuff 1.9.1 : Atropos refactored , vtk dependencies allowed , additional tools for surface-based mapping (not much tested), augmented warping for vtk files Must compile ITK with USE_REVIEW_STATISTICS ON if you want Atropos functionality Should compile ITK with USE_REVIEW ON Should compile ITK with USE_OPTIMIZED_REGISTRATION ON Should have ITK v 3.20 or greater. New Stuff 1.9 : Atropos revisions + various utilities. New Stuff 1.8 : Sped up CC metric -- comparable to PR but faster. Fixed the MI metric -- fast and functional. WarpTimeSeries --- for deforming 4D or vector images. New Stuff 1.7 : Now using SymmetricSecondOrderPixelType -- fixes some DT bugs with Nifti I/O etc. This means our nii tensors have SYMMATRIX as intent (as with standard) Update in parameters for convergence and inversion -- aids performance. TensorToVector coloring --- also preliminary integration of vector field Speed up number one for the CC metric (number two coming later). Atropos ! new tool for segmentation. Nick's N4 bias correction tool (publication on the way). Updates to buildtemplateparallel that allow parallel use on multicore machines. Various utilities and a few improvements in usage. New Stuff 1.6 : Check DT tensor ordering in DTI Read/Write HistogramMatching in ImageMath ConvertImagePixelType utility Affine averaging in buildtemplateparallel Updated time-dependent diffeomorphic mapping (option --geodesic 1 / 2 ). Updated with a greedy exponential mapping diffeomorphic approach akin to DiffeomorphicDemons. Bug fix in checking ANTS convergence. Other miscellaneous including minor Apocrita changes and allowing spaces in command line interface. # directory guide: Documentation -- pdf / tex describing ANTS Examples -- the executable programs and test data in Examples/Data Scripts -- user-friendly scripts for template building and running studies Utilities --- basic utilities ImageRegistration -- base code for ImageRegistration Temporary -- where temporary code lives Tensor -- base code for diffusion tensor operations Use cmake (cmake.org) to set up compilation. To build ANTS, do the following: 1. get ANTS svn checkout https://advants.svn.sourceforge.net/svnroot/advants ANTS 2. get itk : cvs -d :pserver:anoncvs@www.itk.org:/cvsroot/Insight co Insight 3. compile itk and ANTS -- link ANTS to itk build directory ccmake ANTS/Examples/ 4. call ctest in the compile directory and verify that the tests pass 5. in general, to perform a mapping : # include the mask, if desired. mask is inclusive. ANTS 3 -m PR[tp22_s1.nii,template.nii.gz,1,4] -i 50x20x10 -o tp22map -t SyN[0.25] -x mask.nii.gz -r Gauss[3,0] # The ANTS executable reflects the variational optimization problem # which balances regularization of the transformation model's parameters # and the quality of matchins as driven by a similarity (or data) term # # explanation : -m PR -- the similarity metric => PR[fixed.nii,moving,nii,weight,metric-radius] # : -i 50x20 -- the number of iterations and number of resolution levels # : -o tp22map -- the output naming convention (can add an extension) # : -t SyN/Elast/Exp/Syn[time] --- transformation model # : -r Gauss/Bspline -- the regularization models # Gauss[gradient-regularize,deformation-regularize] # : -x mask -- an inclusive mask -- dictates what information to use in registration # -- defined in the fixed domain but works on both domains # : -m other metrics : PSE MSQ MI etc -- some are label-image (or point-set) metrics # and some are intensity metrics # # Call ANTS with no params to get detailed help # # warp the tp22 to template image WarpImageMultiTransform 3 tp22_s1.nii tp22totemplate.nii -R template.nii.gz -i tp22mapAffine.txt tp22mapInverseWarp.nii # warp the template image to tp22 -- note reversal of order from above WarpImageMultiTransform 3 template.nii.gz templatetotp22.nii -R tp22_s1.nii tp22mapWarp.nii tp22mapAffine.txt # or call ants.sh for a standard approach. # # use CreateJacobianDeterminantImage to get log-Jacobian (volumetric change) images # and programs StudentsTestOnImages or GLM to peform a statistical study # one might also use SurfaceCurvature to do a curvature study # or LaplacianThickness to do a thickness study # ants-1.9.2+svn680.dfsg/Scripts/000077500000000000000000000000001147325206600161075ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Scripts/ANTSAverage2DAffine.sh000077500000000000000000000043411147325206600220070ustar00rootroot00000000000000#!/bin/sh NUMPARAM=$# if [ $NUMPARAM -lt 2 ] ; then echo " Usage " echo " $0 OUTNameAffine.txt *Affine.txt " echo " assumes close to idetity affine transforms " exit fi OUTNM=$1 shift 1 FLIST=$* NFILES=0 PARAM1=0 PARAM2=0 PARAM3=0 PARAM4=0 PARAM5=0 PARAM6=0 PARAM7=0 PARAM8=0 LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM1=` awk -v a=$PARAM1 -v b=$x 'BEGIN{print (a + b)}' ` ; let NFILES=$NFILES+1 ; done PARAM1=` awk -v a=$PARAM1 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM2=` awk -v a=$PARAM2 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM2=` awk -v a=$PARAM2 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM3=` awk -v a=$PARAM3 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM3=` awk -v a=$PARAM3 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 5 ` for x in $LL ; do PARAM4=` awk -v a=$PARAM4 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM4=` awk -v a=$PARAM4 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 6 ` for x in $LL ; do PARAM5=` awk -v a=$PARAM5 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM5=` awk -v a=$PARAM5 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 7 ` for x in $LL ; do PARAM6=` awk -v a=$PARAM6 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM6=` awk -v a=$PARAM6 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM7=` awk -v a=$PARAM7 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM7=` awk -v a=$PARAM7 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM8=` awk -v a=$PARAM8 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM8=` awk -v a=$PARAM8 -v b=$NFILES 'BEGIN{print (a / b)}' ` echo "#Insight Transform File V1.0 " > $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_2_2 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 " >> $OUTNM echo "FixedParameters: $PARAM7 $PARAM8 " >> $OUTNM exit ants-1.9.2+svn680.dfsg/Scripts/ANTSAverage3DAffine.sh000077500000000000000000000075421147325206600220160ustar00rootroot00000000000000#!/bin/sh NUMPARAM=$# if [ $NUMPARAM -lt 2 ] ; then echo " Usage " echo " $0 OUTNameAffine.txt *Affine.txt " echo " assumes close to idetity affine transforms " exit fi OUTNM=$1 shift 1 FLIST=$* NFILES=0 PARAM1=0 PARAM2=0 PARAM3=0 PARAM4=0 PARAM5=0 PARAM6=0 PARAM7=0 PARAM8=0 PARAM9=0 PARAM10=0 PARAM11=0 PARAM12=0 PARAM13=0 PARAM14=0 PARAM15=0 LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM1=` awk -v a=$PARAM1 -v b=$x 'BEGIN{print (a + b)}' ` ; let NFILES=$NFILES+1 ; done PARAM1=` awk -v a=$PARAM1 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM2=` awk -v a=$PARAM2 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM2=` awk -v a=$PARAM2 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM3=` awk -v a=$PARAM3 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM3=` awk -v a=$PARAM3 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 5 ` for x in $LL ; do PARAM4=` awk -v a=$PARAM4 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM4=` awk -v a=$PARAM4 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 6 ` for x in $LL ; do PARAM5=` awk -v a=$PARAM5 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM5=` awk -v a=$PARAM5 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 7 ` for x in $LL ; do PARAM6=` awk -v a=$PARAM6 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM6=` awk -v a=$PARAM6 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 8 ` for x in $LL ; do PARAM7=` awk -v a=$PARAM7 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM7=` awk -v a=$PARAM7 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 9 ` for x in $LL ; do PARAM8=` awk -v a=$PARAM8 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM8=` awk -v a=$PARAM8 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 10 ` for x in $LL ; do PARAM9=` awk -v a=$PARAM9 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM9=` awk -v a=$PARAM9 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 11 ` for x in $LL ; do PARAM10=` awk -v a=$PARAM10 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM10=` awk -v a=$PARAM10 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 12 ` for x in $LL ; do PARAM11=` awk -v a=$PARAM11 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM11=` awk -v a=$PARAM11 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 13 ` for x in $LL ; do PARAM12=` awk -v a=$PARAM12 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM12=` awk -v a=$PARAM12 -v b=$NFILES 'BEGIN{print (a / b)}' ` # translation params below LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM13=` awk -v a=$PARAM13 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM13=` awk -v a=$PARAM13 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM14=` awk -v a=$PARAM14 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM14=` awk -v a=$PARAM14 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM15=` awk -v a=$PARAM15 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM15=` awk -v a=$PARAM15 -v b=$NFILES 'BEGIN{print (a / b)}' ` echo "#Insight Transform File V1.0 " > $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_3_3 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 $PARAM7 $PARAM8 $PARAM9 $PARAM10 $PARAM11 $PARAM12 " >> $OUTNM echo "FixedParameters: $PARAM13 $PARAM14 $PARAM15 " >> $OUTNM exit ants-1.9.2+svn680.dfsg/Scripts/ANTSpexec.sh000077500000000000000000000104361147325206600202440ustar00rootroot00000000000000#!/bin/bash VERSION="0.0.1" function Usage { cat <&2 fi while getopts j:rh OPT; do # "j:" waits for an argument "h" doesnt case $OPT in h) Help ;; j) MAX_NPROC=$OPTARG ;; r) REPLACE_CMD=1 ;; \?) Usage >&2 ;; esac done # Main program echo Using max $MAX_NPROC parallel threads if [ $MAX_NPROC -eq 1 ] ; then echo " Dont use pexec to run 1 process at a time. " echo " In this case, just run in series. " exit fi shift `expr $OPTIND - 1` # shift input args, ignore processed args COMMAND=$1 shift # keep list of started processes echo "#!/bin/bash" >> ${here}/killme.sh chmod +x ${here}/killme.sh for INS in $* # for the rest of the arguments do # DEFINE COMMAND if [ $REPLACE_CMD -eq 1 ]; then CMD=${COMMAND//"*"/$INS} else CMD="$COMMAND $INS" #append args fi echo "Running $CMD" eval "$CMD &" # DEFINE COMMAND END PID=$! echo "kill $PID" >> ${here}/killme.sh queue $PID osmac=0 osmac="` uname -a | grep Darwin `" oslin=0 oslin="`uname -a | grep Linux`" if [ ${#osmac} -ne 0 ] then while [ $NUM -ge $MAX_NPROC ]; do checkqueuemac sleep 0.5 done elif [ ${#oslin} -ne 0 ] then while [ $NUM -ge $MAX_NPROC ]; do checkqueuelinux sleep 0.5 done fi done wait # wait for all processes to finish before exit rm ${here}/killme.sh exit 0 ants-1.9.2+svn680.dfsg/Scripts/ants.sh000077500000000000000000000117161147325206600174210ustar00rootroot00000000000000#!/bin/bash NUMPARAMS=$# MAXITERATIONS=30x90x20 export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} # EDIT THIS if [ $NUMPARAMS -lt 3 ] then echo " USAGE :: " echo " sh ants.sh ImageDimension fixed.ext moving.ext OPTIONAL-OUTPREFIX OPTIONAL-max-iterations OPTIONAL-Labels-In-Fixed-Image-Space-To-Deform-To-Moving-Image Option-DoANTSQC " echo " be sure to set ANTSPATH environment variable " echo " Max-Iterations in form : JxKxL where " echo " J = max iterations at coarsest resolution (here, reduce by power of 2^2) " echo " K = middle resolution iterations ( here, reduce by power of 2 ) " echo " L = fine resolution iterations ( here, full resolution ) -- this level takes much more time per iteration " echo " an extra Ix before JxKxL would add another level " echo " Default ierations is $MAXITERATIONS -- you can often get away with fewer for many apps " echo " Other parameters are updates of the defaults used in the A. Klein evaluation paper in Neuroimage, 2009 " exit fi #ANTSPATH=YOURANTSPATH if [ ${#ANTSPATH} -le 0 ] then echo " Please set ANTSPATH=LocationOfYourAntsBinaries " echo " Either set this in your profile or directly, here in the script. " echo " For example : " echo " ANTSPATH=/home/yourname/bin/ants/ " exit else echo " ANTSPATH is $ANTSPATH " fi #initialization, here, is unbiased DIM=$1 if [ ${#DIM} -gt 1 ] then echo " Problem with specified ImageDimension => User Specified Value = $DIM " exit fi FIXED=$2 if [ ${#FIXED} -lt 1 -o ! -f $FIXED ] then echo " Problem with specified Fixed Image => User Specified Value = $FIXED " exit fi MOVING=$3 if [ ${#MOVING} -lt 1 -o ! -f $MOVING ] then echo " Problem with specified Moving Image => User Specified Value = $MOVING " exit fi OUTPUTNAME=` echo $MOVING | cut -d '.' -f 1 ` if [ $NUMPARAMS -gt 4 ] then MAXITERATIONS=$5 fi LABELIMAGE=0 if [ $NUMPARAMS -gt 5 ] then LABELIMAGE=$6 fi DoANTSQC=0 if [ $NUMPARAMS -gt 6 ] then DoANTSQC=$7 fi if [ $NUMPARAMS -gt 3 ] then OUTPUTNAME=${4} fi # Mapping Parameters TRANSFORMATION=SyN[0.25] ITERATLEVEL=(`echo $MAXITERATIONS | tr 'x' ' '`) NUMLEVELS=${#ITERATLEVEL[@]} echo $NUMLEVELS REGULARIZATION=Gauss[3,0] METRIC=CC[ METRICPARAMS=1,4] # echo " $METRICPARAMS & $METRIC " # exit echo " ANTSPATH is $ANTSPATH " echo " Mapping Parameters :: " echo " Transformation is: $TRANSFORMATION " echo " MaxIterations : $MAXITERATIONS " echo " Number Of MultiResolution Levels $NUMLEVELS " echo " Regularization : $REGULARIZATION " echo " Metric : ${METRIC} " echo " OutputName : $OUTPUTNAME " echo " " echo " if the files and parameters are all ok then uncomment the exit call below this line " echo " " #exit if [[ ! -s ${OUTPUTNAME}repaired.nii.gz ]] ; then ${ANTSPATH}N3BiasFieldCorrection $DIM $MOVING ${OUTPUTNAME}repaired.nii.gz 4 fi exe=" ${ANTSPATH}ANTS $DIM -m ${METRIC}${FIXED},${OUTPUTNAME}repaired.nii.gz,${METRICPARAMS} -t $TRANSFORMATION -r $REGULARIZATION -o ${OUTPUTNAME} -i $MAXITERATIONS --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 " echo " $exe " $exe #below, some affine options #--MI-option 16x8000 #-a InitAffine.txt --continue-affine 0 ${ANTSPATH}WarpImageMultiTransform $DIM ${OUTPUTNAME}repaired.nii.gz ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} if [ ${#LABELIMAGE} -gt 3 ] then ${ANTSPATH}WarpImageMultiTransform $DIM $LABELIMAGE ${OUTPUTNAME}labeled.nii.gz -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz -R ${MOVING} --use-NN fi exit if [ $DoANTSQC -eq 1 ] ; then # measure image similarity for SIM in 0 1 2 ; do ${ANTSPATH}MeasureImageSimilarity $DIM $SIM $FIXED ${OUTPUTNAME}deformed.nii.gz done # measure dice overlap and mds ${ANTSPATH}ThresholdImage $DIM $FIXED ${OUTPUTNAME}fixthresh.nii.gz Otsu 4 ${ANTSPATH}ThresholdImage $DIM $MOVING ${OUTPUTNAME}movthresh.nii.gz Otsu 4 ${ANTSPATH}WarpImageMultiTransform $DIM ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}defthresh.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} --use-NN ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}dicestats.txt DiceAndMinDistSum ${OUTPUTNAME}fixthresh.nii.gz ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}mindistsum.nii.gz # labelstats for jacobian wrt segmenation # below, to compose # ${ANTSPATH}ComposeMultiTransform $DIM ${OUTPUTNAME}CompWarp.nii.gz -R $FIXED ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt # ${ANTSPATH}CreateJacobianDeterminantImage $DIM ${OUTPUTNAME}CompWarp.nii.gz ${OUTPUTNAME}jacobian.nii.gz 0 # ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}movlabstat.txt LabelStats ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}movthresh.nii.gz # ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}jaclabstat.txt LabelStats ${OUTPUTNAME}defthresh.nii.gz ${OUTPUTNAME}jacobian.nii.gz # we compare the output of these last two lines: # the Volume of the movlabstat computation vs. the mass of the jaclabstat fi ants-1.9.2+svn680.dfsg/Scripts/antsIntroduction.sh000077500000000000000000000615071147325206600220260ustar00rootroot00000000000000#!/bin/bash VERSION="0.0.7" # Uncomment the line below in case you have not set the ANTSPATH variable in your environment. export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} function Usage { cat <&2 elif [ $nargs -lt 6 ] then Usage >&2 fi # reading command line arguments while getopts "d:f:r:i:h:o:m:n:l:q:s:t:" OPT do case $OPT in h) #help echo "$Help" exit 0 ;; d) #dimensions DIM=$OPTARG ;; f) #ignore header warnings IGNORE_HDR_WARNING=$OPTARG ;; i) #input or moving image MOVING=$OPTARG OUTPUTNAME=` echo $MOVING | cut -d '.' -f 1 ` ;; l) #use label image LABELIMAGE=$OPTARG ;; m) #max iterations other than default MAXITERATIONS=$OPTARG ;; n) #apply bias field correction N3CORRECT=$OPTARG ;; o) #output name prefix OUTPUTNAME=$OPTARG ;; q) #perform quality check after running ANTS DoANTSQC=$OPTARG ;; r) #ref image FIXED=$OPTARG ;; s) #similarity model METRICTYPE=$OPTARG ;; t) #transformation model TRANSFORMATIONTYPE=$OPTARG ;; \?) # getopts issues an error message echo "$USAGE" >&2 exit 1 ;; esac done #ANTSPATH=YOURANTSPATH if [ ${#ANTSPATH} -le 0 ] then setPath >&2 fi # test input parameter before starting if [ ${#DIM} -gt 1 ] then echo "Problem with specified ImageDimension => User Specified Value = $DIM" exit fi if [ ${#FIXED} -lt 1 -o ! -f $FIXED ] then echo "Problem with specified Fixed Image => User Specified Value = $FIXED" exit fi if [ ${#MOVING} -lt 1 -o ! -f $MOVING ] then echo "Problem with specified Moving Image => User Specified Value = $MOVING" exit fi # check the image headers echo "input files: checking" compareheaders=`${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}repaired.nii.gz CompareHeadersAndImages $FIXED $MOVING | grep FailureState | cut -d ' ' -f 4 ` if [ $compareheaders -ne 0 ] then dataCheck if [ $IGNORE_HDR_WARNING -eq 0 ] then exit 1 fi else echo "input files: check passed" fi ITERATLEVEL=(`echo $MAXITERATIONS | tr 'x' ' '`) NUMLEVELS=${#ITERATLEVEL[@]} # Transformation model if [ "${TRANSFORMATIONTYPE}" == "RI" ] then RIGID=1 RIGIDTRANSF=" --do-rigid: true " elif [ "${TRANSFORMATIONTYPE}" == "RA" ] then RIGID=1 RIGIDTRANSF=" --rigid-affine true " elif [ "${TRANSFORMATIONTYPE}" == "EL" ] then # Mapping Parameters TRANSFORMATION=Elast[1] REGULARIZATION=Gauss[3,0.5] # Gauss[3,x] is usually the best option. x is usually 0 for SyN --- if you want to reduce flexibility/increase mapping smoothness, the set x > 0. # We did a large scale evaluation of SyN gradient parameters in normal brains and found 0.25 => 0.5 to perform best when # combined with default Gauss[3,0] regularization. You would increase the gradient step in some cases, though, to make # the registration converge faster --- though oscillations occur if the step is too high and other instability might happen too. elif [ "${TRANSFORMATIONTYPE}" == "S2" ] then # Mapping Parameters for the LDDMM style SyN --- the params are SyN[GradientStepLength,NTimeDiscretizationPoints,IntegrationTimeStep] # increasing IntegrationTimeStep increases accuracy in the diffeomorphism integration and takes more computation time. # NTimeDiscretizationPoints is set to 2 here TRANSFORMATION=SyN[1,2,0.05] REGULARIZATION=Gauss[3,0.] elif [ "${TRANSFORMATIONTYPE}" == "SY" ] then # Mapping Parameters for the LDDMM style SyN --- the params are SyN[GradientStepLength,NTimeDiscretizationPoints,IntegrationTimeStep] # increasing IntegrationTimeStep increases accuracy in the diffeomorphism integration and takes more computation time. # NTimeDiscretizationPoints is the number of spatial indices in the time dimension (the 4th dim when doing 3D registration) # increasing NTimeDiscretizationPoints increases flexibility and takes more computation time. # the --geodesic option enables either 1 asymmetric gradient estimation or 2 symmetric gradient estimation (the default here ) TRANSFORMATION=" SyN[1,2,0.05] --geodesic 2 " REGULARIZATION=Gauss[3,0.] elif [ "${TRANSFORMATIONTYPE}" == "LDDMM" ] then # Mapping Parameters for the LDDMM style SyN --- the params are SyN[GradientStepLength,NTimeDiscretizationPoints,IntegrationTimeStep] # increasing IntegrationTimeStep increases accuracy in the diffeomorphism integration and takes more computation time. # NTimeDiscretizationPoints is the number of spatial indices in the time dimension (the 4th dim when doing 3D registration) # increasing NTimeDiscretizationPoints increases flexibility and takes more computation time. # the --geodesic option enables either 1 asymmetric gradient estimation or 2 symmetric gradient estimation (the default here ) TRANSFORMATION=" SyN[1,2,0.05] --geodesic 1 " REGULARIZATION=Gauss[3,0.] elif [ "${TRANSFORMATIONTYPE}" == "GR" ] then # Mapping Parameters for the greedy gradient descent (fast) version of SyN -- only needs GradientStepLength TRANSFORMATION=SyN[0.25] REGULARIZATION=Gauss[3,0] elif [ "${TRANSFORMATIONTYPE}" == "EX" ] then # Mapping Parameters TRANSFORMATION=Exp[0.5,10] REGULARIZATION=Gauss[3,0.5] elif [ "${TRANSFORMATIONTYPE}" == "DD" ] then # Mapping Parameters for diffemorphic demons style optimization Exp[GradientStepLength,NTimePointsInIntegration] # NTimePointsInIntegration controls the number of compositions in the transformation update , see the DD paper TRANSFORMATION=GreedyExp[0.5,10] REGULARIZATION=Gauss[3,0.5] else echo "Invalid transformation metric. Use RI, RA, EL, SY, S2, GR , DD or EX or type sh $0 -h." exit 1 fi # Similarity Measures if [ "${METRICTYPE}" == "PR" ] then # Mapping Parameters METRIC=PR[ METRICPARAMS=1,4] elif [ "${METRICTYPE}" == "CC" ] then # Mapping Parameters METRIC=CC[ METRICPARAMS=1,5] elif [ "${METRICTYPE}" == "MI" ] then # Mapping Parameters METRIC=MI[ METRICPARAMS=1,32] elif [ "${METRICTYPE}" == "MSQ" ] then # Mapping Parameters METRIC=MSQ[ METRICPARAMS=1,0] else echo "Invalid similarity metric. Use CC, MI, MSQ or PR or type sh $0 -h." exit 1 fi # main script reportMappingParameters # write config file MOVINGBASE=` echo ${MOVING} | cut -d '.' -f 1 ` if [ -f ${MOVINGBASE}.cfg ] ; then rm -f ${MOVINGBASE}.cfg fi echo "REGDIR=${currentdir}" >> ${MOVINGBASE}.cfg echo "DIM=$DIM" >> ${MOVINGBASE}.cfg echo "FIXED=$FIXED" >> ${MOVINGBASE}.cfg echo "MOVING=$MOVING" >> ${MOVINGBASE}.cfg echo "LABELIMAGE=$LABELIMAGE" >> ${MOVINGBASE}.cfg echo "N3CORRECT=$N3CORRECT" >> ${MOVINGBASE}.cfg echo "DoANTSQC=$DoANTSQC" >> ${MOVINGBASE}.cfg echo "METRICTYPE=$METRICTYPE" >> ${MOVINGBASE}.cfg echo "TRANSFORMATIONTYPE=$TRANSFORMATIONTYPE" >> ${MOVINGBASE}.cfg echo "REGULARIZATION=$REGULARIZATION" >> ${MOVINGBASE}.cfg echo "MAXITERATIONS=$MAXITERATIONS" >> ${MOVINGBASE}.cfg echo "NUMLEVELS=$NUMLEVELS" >> ${MOVINGBASE}.cfg echo "OUTPUTNAME=$OUTPUTNAME" >> ${MOVINGBASE}.cfg if [ ${N3CORRECT} -eq 0 ] && [ ${RIGID} -eq 0 ] then # Apply ANTS mapping command without N3BiasFieldCorrection exe="${ANTSPATH}ANTS $DIM -m ${METRIC}${FIXED},${MOVING},${METRICPARAMS} -t $TRANSFORMATION -r $REGULARIZATION -o ${OUTPUTNAME} -i $MAXITERATIONS --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 " echo echo "--------------------------------------------------------------------------------------" echo "ANTS command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execants=$exe" >> ${MOVINGBASE}.cfg # Apply forward transformation to MOVING echo echo "--------------------------------------------------------------------------------------" echo "Applying forward transformation to ${MOVING}" echo "--------------------------------------------------------------------------------------" ${ANTSPATH}WarpImageMultiTransform $DIM ${MOVING} ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} echo "warpfw=${ANTSPATH}WarpImageMultiTransform $DIM ${MOVING} ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED}" >> ${MOVINGBASE}.cfg # Apply inverse transformation to FIXED if [ "${TRANSFORMATIONTYPE}" == "EL" ] then echo echo "--------------------------------------------------------------------------------------" echo "Applying inverse transformation to ${FIXED} is not possible for elastic registration." echo "--------------------------------------------------------------------------------------" else echo echo "--------------------------------------------------------------------------------------" echo "Applying inverse transformation to ${FIXED}" echo "--------------------------------------------------------------------------------------" FIXEDBASE=` echo ${FIXED} | cut -d '.' -f 1 ` ${ANTSPATH}WarpImageMultiTransform $DIM ${FIXED} ${FIXEDBASE}_InverseWarp.nii.gz -R ${MOVING} -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz echo "warpinv=${ANTSPATH}WarpImageMultiTransform $DIM ${FIXED} ${FIXEDBASE}_InverseWarp.nii.gz -R ${MOVING} -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz" >> ${MOVINGBASE}.cfg fi elif [ ${N3CORRECT} -eq 1 ] && [ ${RIGID} -eq 0 ] then # Apply N3BiasFieldCorrection exe="${ANTSPATH}N3BiasFieldCorrection $DIM $MOVING ${OUTPUTNAME}.nii.gz 4" echo echo "--------------------------------------------------------------------------------------" echo "N3BiasFieldCorrection command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execN3=$exe" >> ${MOVINGBASE}.cfg # Apply ANTS mapping command on N3 corrected image exe="${ANTSPATH}ANTS $DIM -m ${METRIC}${FIXED},${OUTPUTNAME}.nii.gz,${METRICPARAMS} -t $TRANSFORMATION -r $REGULARIZATION -o ${OUTPUTNAME} -i $MAXITERATIONS --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 " echo echo "--------------------------------------------------------------------------------------" echo "ANTS command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execants=$exe" >> ${MOVINGBASE}.cfg # Apply forward transformation to MOVING echo echo "--------------------------------------------------------------------------------------" echo "Applying forward transformation to ${MOVING}" echo "--------------------------------------------------------------------------------------" ${ANTSPATH}WarpImageMultiTransform $DIM ${OUTPUTNAME}.nii.gz ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} echo "warpfw=${ANTSPATH}WarpImageMultiTransform $DIM ${OUTPUTNAME}.nii.gz ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED}" >> ${MOVINGBASE}.cfg # Apply inverse transformation to FIXED if [ "${TRANSFORMATIONTYPE}" == "EL" ] then echo echo "--------------------------------------------------------------------------------------" echo "Applying inverse transformation to ${FIXED} is not possible for elastic registration." echo "--------------------------------------------------------------------------------------" else echo echo "--------------------------------------------------------------------------------------" echo "Applying inverse transformation to ${FIXED}" echo "--------------------------------------------------------------------------------------" FIXEDBASE=` echo ${FIXED} | cut -d '.' -f 1 ` ${ANTSPATH}WarpImageMultiTransform $DIM ${FIXED} ${FIXEDBASE}_InverseWarp.nii.gz -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz -R ${OUTPUTNAME}.nii.gz echo "warpinv=${ANTSPATH}WarpImageMultiTransform $DIM ${FIXED} ${FIXEDBASE}_InverseWarp.nii.gz -R ${OUTPUTNAME}.nii.gz -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz" >> ${MOVINGBASE}.cfg fi elif [ ${N3CORRECT} -eq 0 ] && [ ${RIGID} -eq 1 ] then exe=" ${ANTSPATH}ANTS $DIM -m MI[${FIXED},${MOVING},1,32] -o ${OUTPUTNAME}.nii.gz -i 0 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 ${RIGIDTRANSF} " echo echo "--------------------------------------------------------------------------------------" echo "ANTS command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execants=$exe" >> ${MOVINGBASE}.cfg # Apply forward transformation to MOVING echo echo "--------------------------------------------------------------------------------------" echo "Applying rigid transformation to ${MOVING}" echo "--------------------------------------------------------------------------------------" ${ANTSPATH}WarpImageMultiTransform $DIM ${MOVING} ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} elif [ ${N3CORRECT} -eq 1 ] && [ ${RIGID} -eq 1 ] then # Apply N3BiasFieldCorrection exe="${ANTSPATH}N3BiasFieldCorrection $DIM $MOVING ${OUTPUTNAME}.nii.gz 4" echo echo "--------------------------------------------------------------------------------------" echo "N3BiasFieldCorrection command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execN3=$exe" >> ${MOVINGBASE}.cfg exe=" ${ANTSPATH}ANTS $DIM -m MI[${FIXED},${MOVING},1,32] -o ${OUTPUTNAME}.nii.gz -i 0 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 --MI-option 32x16000 ${RIGIDTRANSF} " echo echo "--------------------------------------------------------------------------------------" echo "ANTS command:" echo "$exe " echo "--------------------------------------------------------------------------------------" $exe echo "execants=$exe" >> ${MOVINGBASE}.cfg # Apply forward transformation to MOVING echo echo "--------------------------------------------------------------------------------------" echo "Applying rigid transformation to ${MOVING}" echo "--------------------------------------------------------------------------------------" ${ANTSPATH}WarpImageMultiTransform $DIM ${MOVING} ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} fi # Apply transformation on labeled image? if [ ${#LABELIMAGE} -gt 3 ] then ${ANTSPATH}WarpImageMultiTransform $DIM $LABELIMAGE ${OUTPUTNAME}labeled.nii.gz -i ${OUTPUTNAME}Affine.txt ${OUTPUTNAME}InverseWarp.nii.gz -R ${MOVING} --use-NN fi if [ $DoANTSQC -eq 1 ] then # measure image similarity - 0 = intensity difference, 1 = correlation , 2 = mutual information for SIM in 0 1 2 ; do ${ANTSPATH}MeasureImageSimilarity $DIM $SIM $FIXED ${OUTPUTNAME}deformed.nii.gz done # the lines below measure dice overlap and min-dist-sum from the approximately segmented brain (3 tissues and background) ${ANTSPATH}ThresholdImage $DIM $FIXED ${OUTPUTNAME}fixthresh.nii.gz Otsu 4 ${ANTSPATH}ThresholdImage $DIM $MOVING ${OUTPUTNAME}movthresh.nii.gz Otsu 4 ${ANTSPATH}WarpImageMultiTransform $DIM ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}defthresh.nii.gz ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} --use-NN ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}dicestats.txt DiceAndMinDistSum ${OUTPUTNAME}fixthresh.nii.gz ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}mindistsum.nii.gz # below not used unless you want to compare segmentation volumes to those estimated by the jacobian # labelstats for jacobian wrt segmenation below, to compose # ${ANTSPATH}ComposeMultiTransform $DIM ${OUTPUTNAME}CompWarp.nii.gz -R $FIXED ${OUTPUTNAME}Warp.nii.gz ${OUTPUTNAME}Affine.txt # ${ANTSPATH}CreateJacobianDeterminantImage $DIM ${OUTPUTNAME}CompWarp.nii.gz ${OUTPUTNAME}jacobian.nii.gz 0 # ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}movlabstat.txt LabelStats ${OUTPUTNAME}movthresh.nii.gz ${OUTPUTNAME}movthresh.nii.gz # ${ANTSPATH}ImageMath $DIM ${OUTPUTNAME}jaclabstat.txt LabelStats ${OUTPUTNAME}defthresh.nii.gz ${OUTPUTNAME}jacobian.nii.gz # we compare the output of these last two lines: # the Volume of the movlabstat computation vs. the mass of the jaclabstat fi time_end=`date +%s` time_elapsed=$((time_end - time_start)) echo " ">> ${MOVINGBASE}.cfg echo " Script executed in $time_elapsed seconds" >> ${MOVINGBASE}.cfg echo " $(( time_elapsed / 3600 ))h $(( time_elapsed %3600 / 60 ))m $(( time_elapsed % 60 ))s" >> ${MOVINGBASE}.cfg exit ants-1.9.2+svn680.dfsg/Scripts/antsaffine.sh000077500000000000000000000035031147325206600205650ustar00rootroot00000000000000#!/bin/sh export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} NUMPARAMS=$# if [ $NUMPARAMS -lt 3 ] then echo " USAGE :: " echo " sh ants.sh ImageDimension fixed.ext moving.ext OPTIONAL-OUTPREFIX PURELY-RIGID " echo " be sure to set ANTSPATH environment variable " echo " affine only registration " exit fi #ANTSPATH=YOURANTSPATH if [ ${#ANTSPATH} -le 0 ] then echo " Please set ANTSPATH=LocationOfYourAntsBinaries " echo " Either set this in your profile or directly, here in the script. " echo " For example : " echo $ANTSPATH echo " ANTSPATH=/home/yourname/bin/ants/ " exit else echo " ANTSPATH is $ANTSPATH " fi #initialization, here, is unbiased DIM=$1 if [ ${#DIM} -gt 1 ] then echo " Problem with specified ImageDimension => User Specified Value = $DIM " exit fi FIXED=$2 if [ ${#FIXED} -lt 1 -o ! -f $FIXED ] then echo " Problem with specified Fixed Image => User Specified Value = $FIXED " exit fi MOVING=$3 if [ ${#MOVING} -lt 1 -o ! -f $MOVING ] then echo " Problem with specified Moving Image => User Specified Value = $MOVING " exit fi OUTPUTNAME=` echo $MOVING | cut -d '.' -f 1 ` if [ $NUMPARAMS -gt 3 ] then OUTPUTNAME=${4} fi RIGID=" --rigid-affine false " if [ $NUMPARAMS -gt 4 ] then RIGID=" --rigid-affine true --affine-gradient-descent-option 0.5x0.95x1.e-4x1.e-4 " fi echo " Will this mapping be purely rigid? $RIGID " echo " ANTSPATH is $ANTSPATH " #below, some affine options #--MI-option 16x8000 #-a InitAffine.txt --continue-affine 0 exe=" ${ANTSPATH}ANTS $DIM -m MI[${FIXED},${MOVING},1,32] -o ${OUTPUTNAME} -i 0 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 $RIGID " echo " $exe " $exe ${ANTSPATH}WarpImageMultiTransform $DIM $MOVING ${OUTPUTNAME}deformed.nii.gz ${OUTPUTNAME}Affine.txt -R ${FIXED} ants-1.9.2+svn680.dfsg/Scripts/antsbashstats.sh000077500000000000000000000077021147325206600213360ustar00rootroot00000000000000#!/bin/bash # sttdev.sh: Standard Deviation # Original version obtained from: http://tldp.org/LDP/abs/html/contributed-scripts.html#STDDEV # 2009-03-09: Panagiotis Kritikakos # Function stat_median() added for calculating the median value # of the data set # ------------------------------------------------------------ # The Standard Deviation indicates how consistent a set of data is. # It shows to what extent the individual data points deviate from the #+ arithmetic mean, i.e., how much they "bounce around" (or cluster). # It is essentially the average deviation-distance of the #+ data points from the mean. # =========================================================== # # To calculate the Standard Deviation: # # 1 Find the arithmetic mean (average) of all the data points. # 2 Subtract each data point from the arithmetic mean, # and square that difference. # 3 Add all of the individual difference-squares in # 2. # 4 Divide the sum in # 3 by the number of data points. # This is known as the "variance." # 5 The square root of # 4 gives the Standard Deviation. # =========================================================== # count=0 # Number of data points; global. SC=9 # Scale to be used by bc. Nine decimal places. E_DATAFILE=90 # Data file error. # ----------------- Set data file --------------------- if [ ! -z "$1" ] # Specify filename as cmd-line arg? then datafile="$1" # ASCII text file, else #+ one (numerical) data point per line! datafile=sample.dat fi # See example data file, below. if [ ! -e "$datafile" ] then echo "\""$datafile"\" does not exist!" echo " Usage : " echo " sh $0 textdatafile.txt " exit $E_DATAFILE fi # ----------------------------------------------------- arith_mean () { local rt=0 # Running total. local am=0 # Arithmetic mean. local ct=0 # Number of data points. while read value # Read one data point at a time. do echo $value rt=$(echo "scale=$SC; $rt + $value" | bc) (( ct++ )) done am=$(echo "scale=$SC; $rt / $ct" | bc) echo $am; return $ct # This function "returns" TWO values! # Caution: This little trick will not work if $ct > 255! # To handle a larger number of data points, #+ simply comment out the "return $ct" above. } <"$datafile" # Feed in data file. sd () { mean1=$1 # Arithmetic mean (passed to function). n=$2 # How many data points. sum2=0 # Sum of squared differences ("variance"). avg2=0 # Average of $sum2. sdev=0 # Standard Deviation. while read value # Read one line at a time. do diff=$(echo "scale=$SC; $mean1 - $value" | bc) # Difference between arith. mean and data point. dif2=$(echo "scale=$SC; $diff * $diff" | bc) # Squared. sum2=$(echo "scale=$SC; $sum2 + $dif2" | bc) # Sum of squares. done avg2=$(echo "scale=$SC; $sum2 / $n" | bc) # Avg. of sum of squares. sdev=$(echo "scale=$SC; sqrt($avg2)" | bc) # Square root = echo $sdev # Standard Deviation. } <"$datafile" # Rewinds data file. stat_median() { NUMS=(`sort -n $1`) TOTALNUMS=${#NUMS[*]} MOD=$(($TOTALNUMS % 2)) if [ $MOD -eq 0 ]; then ARRAYMIDDLE=$(echo "($TOTALNUMS / 2)-1" | bc) ARRAYNEXTMIDDLE=$(($ARRAYMIDDLE + 1)) MEDIAN=$(echo "scale=$SC; ((${NUMS[$ARRAYMIDDLE]})+(${NUMS[$ARRAYNEXTMIDDLE]})) / 2" | bc) elif [ $MOD -eq 1 ]; then ARRAYMIDDLE=$(echo "($TOTALNUMS / 2)" | bc) MEDIAN=${NUMS[$ARRAYMIDDLE]} fi echo $MEDIAN } # ======================================================= # mean=$(arith_mean); count=$? # Two returns from function! std_dev=$(sd $mean $count) median=$(stat_median $1) echo " Mean : $mean SD: $std_dev " #echo #echo "Number of data points in \""$datafile"\" = $count" #echo "Arithmetic mean (average) = $mean" #echo "Standard Deviation = $std_dev" #echo "Median number (middle) = $median" #echo # ======================================================= # exit ants-1.9.2+svn680.dfsg/Scripts/antsdeformationmag.sh000077500000000000000000000037441147325206600223400ustar00rootroot00000000000000#!/bin/bash NUMPARAMS=$# if [ $NUMPARAMS -lt 4 ] then echo " USAGE :: " echo " $0 inWarp WhichTypeOfMagnitude outputmagnitudeimage.nii ANTSPATH " echo " WhichTypeOfMagnitude == Laplacian Grad Euclidean " echo " the numbers that come out of this depend on some itk filters being dimensionally correct and consistent. " echo " this may not be the case -- however, relative values should be ok , e.g comparing Grad values to Grad values etc " exit fi inwarp=$1 whichmag=$2 magimage=$3 ANTSPATH=$4 dimarr=(`${ANTSPATH}PrintHeader ${inwarp}xvec.nii.gz | grep Spacing | grep , | wc `) DIM=${dimarr[0]} let DIM=${DIM}+1 # multiply some image of the right size by 0 to make the initial magnitude image ${ANTSPATH}ImageMath $DIM $magimage m ${inwarp}xvec.nii.gz 0 ${ANTSPATH}ImageMath $DIM ${magimage}temp.nii.gz m ${inwarp}xvec.nii.gz 0 ok=0 for x in x y z do if [ -s ${inwarp}${x}vec.nii.gz ] then # compute the magnitude of the x-component deformation if [ $whichmag == Laplacian ] then echo " Laplacian $x " ok=1 ${ANTSPATH}ImageMath $DIM ${magimage}temp.nii.gz Laplacian ${inwarp}${x}vec.nii.gz 1.0 0 elif [ $whichmag == Grad ] then echo " Grad $x " ok=1 ${ANTSPATH}ImageMath $DIM ${magimage}temp.nii.gz Grad ${inwarp}${x}vec.nii.gz 1.0 0 #ImageMath $DIM temp.nii.gz m temp.nii.gz temp.nii.gz elif [ $whichmag == Euclidean ] then echo " Euclidean $x " ok=1 ${ANTSPATH}ImageMath $DIM ${magimage}temp.nii.gz m ${inwarp}${x}vec.nii.gz ${inwarp}${x}vec.nii.gz fi # add the xvec magnitude to the magimage ${ANTSPATH}ImageMath $DIM $magimage + $magimage ${magimage}temp.nii.gz fi # ifz done #loop if [ $ok -eq 1 ] then # take the square root ${ANTSPATH}ImageMath $DIM $magimage ^ $magimage 0.5 ${ANTSPATH}MeasureMinMaxMean $DIM $magimage #thus, #magimage=sqrt( x*x + y*y + z*z ) else echo " User Requested deformation measure :: $whichmag " echo " that is not available -- user needs to choose another type of deformation measure " fi rm -f ${magimage}temp.nii.gz ants-1.9.2+svn680.dfsg/Scripts/antsqsub.sh000077500000000000000000000017771147325206600203220ustar00rootroot00000000000000#!/bin/bash #$ -S /bin/bash dir=$1 cmd=$2 para=$3 naming=$4 fixname=$5 movingname=$6 echo $6 opta=$7 echo $7 optb=$8 echo $8 optc=$9 echo $9 optd=${10} echo ${10} opte=${11} echo ${11} optf=${12} echo ${12} optg=${13} echo ${13} opth=${14} echo ${14} opti=${15} echo ${15} optj=${16} echo ${16} optk=${17} echo ${17} optl=${18} echo ${18} optm=${19} echo ${19} optn=${20} echo ${20} opto=${21} echo ${21} optp=${22} echo ${22} optq=${23} echo ${23} optr=${24} echo ${24} opts=${25} echo ${25} optt=${26} echo ${26} echo " dir " echo $1 cd $1 echo $cmd $para $naming $fixname $movingname $opta $optb $optc $optd $opte $optf $optg $opth $opti $optj $optk $optl $optm $optn $opto $optp $optq $optr $opts $optt $cmd $para $naming $fixname $movingname $opta $optb $optc $optd $opte $optf $optg $opth $opti $optj $optk $optl $optm $optn $opto $optp $optq $optr $opts $optt ${27} ${28} ${29} ${30} ${31} ${32} ${33} ${34} ${35} ${36} ${37} ${38} ${39} ${40} ${41} ${42} ${43} ${44} ${45} ${46} ${47} ${48} ${49} cd - ants-1.9.2+svn680.dfsg/Scripts/antswithdt.sh000077500000000000000000000106661147325206600206500ustar00rootroot00000000000000#!/bin/bash NUMPARAMS=$# MAXITERATIONS=30x90x20 export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} if [ $NUMPARAMS -lt 3 ] then echo " USAGE :: " echo " sh ants.sh ImageDimension fixed.ext moving.ext Subject/Moving-DT-To-Deform-To-Fixed-Image OPTIONAL-Subject/Moving-BZero-To-DistortionCorrect-To-Moving-T1-Image " echo " be sure to set ANTSPATH environment variable " echo " Max-Iterations in form : JxKxL where " echo " J = max iterations at coarsest resolution (here, reduce by power of 2^2) " echo " K = middle resolution iterations ( here, reduce by power of 2 ) " echo " L = fine resolution iterations ( here, full resolution ) -- this level takes much more time per iteration " echo " an extra Ix before JxKxL would add another level " echo " Default ierations is $MAXITERATIONS -- you can often get away with fewer for many apps " echo " Other parameters are defaults used in the A. Klein evaluation paper in Neuroimage, 2009 " echo " " echo " The DT component is distortion corrected to the T1 image either by the B-Zero Image / Average-DWI Image " echo " or whatever is passed as the last parameter --- Alternatively, we compute the FA from the DTI and then " echo" distortion correct to it. One should test the validity of this approach on your data before widely applying ." echo " We use the cross-correlation to perform the distortion correction. " echo " Some parameter tuning may be required, depending on the distortions present in your acquisition. " exit fi #initialization, here, is unbiased DIM=$1 if [ ${#DIM} -gt 1 ] then echo " Problem with specified ImageDimension => User Specified Value = $DIM " exit fi FIXED=$2 if [ ${#FIXED} -lt 1 -o ! -f $FIXED ] then echo " Problem with specified Fixed Image => User Specified Value = $FIXED " exit fi MOVING=$3 if [ ${#MOVING} -lt 1 -o ! -f $MOVING ] then echo " Problem with specified Moving Image => User Specified Value = $MOVING " exit fi OUTPUTNAME=${MOVING%.*.*} if [ ${#OUTPUTNAME} -eq ${#MOVING} ] then OUTPUTNAME=${MOVING%.*} fi MOVINGDT=0 if [ $NUMPARAMS -gt 3 ] then MOVINGDT=$4 if [ ! -f $MOVINGDT ] then echo " THIS DTI DOES NOT EXIST : $MOVINGDT " MOVINGDT="" fi fi MOVINGBZ=0 if [ $NUMPARAMS -gt 4 ] then MOVINGBZ=$5 if [ ! -f $MOVINGBZ ] then echo " THIS BZero DOES NOT EXIST : $MOVINGBZ " MOVINGBZ=0 fi fi if [ ${#MOVINGDT} -gt 3 ] then echo " The BZero DOES NOT EXIST : Using FA Instead!!" ${ANTSPATH}ImageMath 3 ${OUTPUTNAME}_fa.nii TensorFA $MOVINGDT MOVINGBZ=${OUTPUTNAME}_fa.nii fi # Mapping Parameters TRANSFORMATION=SyN[0.25] ITERATLEVEL=(`echo $MAXITERATIONS | tr 'x' ' '`) NUMLEVELS=${#ITERATLEVEL[@]} echo $NUMLEVELS REGULARIZATION=Gauss[3,0] METRIC=PR[ METRICPARAMS=1,2] #echo " $METRICPARAMS & $METRIC " #exit #ANTSPATH=/mnt/aibs1/avants/bin/ants/ #ANTSPATH=YOURANTSPATH echo " ANTSPATH $ANTSPATH " echo " Mapping Parameters :: " echo " Transformation is: $TRANSFORMATION " echo " MaxIterations : $MAXITERATIONS " echo " Number Of MultiResolution Levels $NUMLEVELS " echo " Regularization : $REGULARIZATION " echo " Metric : ${METRIC} " echo " OutputName : $OUTPUTNAME " echo " " echo " if the files and parameters are all ok then uncomment the exit call below this line " echo " " #exit # first, do distortion correction of MOVINGDT to MOVING # use the B0 image ${ANTSPATH}ANTS 3 -m PR[${MOVINGBZ},${MOVING},1,2] -o ${OUTPUTNAME}distcorr -r Gauss[3,0] -t SyN[0.25] -i 25x20x0 --do-rigid 1 ${ANTSPATH}WarpImageMultiTransform 3 $MOVING ${OUTPUTNAME}distcorr.nii ${OUTPUTNAME}distcorrWarp.nii ${OUTPUTNAME}distcorrAffine.txt -R $MOVINGBZ #exit if [[ ! -s ${OUTPUTNAME}Affine.txt ]] ; then sh ${ANTSPATH}/ants.sh $DIM $FIXED $MOVING ${OUTPUTNAME} fi if [[ -s ${MOVINGDT} ]] && [[ -s ${OUTPUTNAME}Affine.txt ]] ; then DTDEF=${OUTPUTNAME}DTdeformed.nii FIXEDSUB=${OUTPUTNAME}fixedsub.nii ${ANTSPATH}ResampleImageBySpacing 3 $FIXED $FIXEDSUB 2 2 2 echo " Warp DT " ${ANTSPATH}WarpTensorImageMultiTransform $DIM $MOVINGDT $DTDEF ${OUTPUTNAME}Warp.nii ${OUTPUTNAME}Affine.txt -i ${OUTPUTNAME}distcorrAffine.txt ${OUTPUTNAME}distcorrInverseWarp.nii -R $FIXEDSUB COMPWARP=${OUTPUTNAME}DTwarp.nii ${ANTSPATH}ComposeMultiTransform $DIM $COMPWARP -R ${FIXEDSUB} ${OUTPUTNAME}Warp.nii ${OUTPUTNAME}Affine.txt -i ${OUTPUTNAME}distcorrAffine.txt ${OUTPUTNAME}distcorrInverseWarp.nii ${ANTSPATH}ReorientTensorImage 3 $DTDEF $DTDEF $COMPWARP fi exit ants-1.9.2+svn680.dfsg/Scripts/buildtemplateparallel.sh000077500000000000000000001155001147325206600230200ustar00rootroot00000000000000#!/bin/bash VERSION="0.0.13" # trap keyboard interrupt (control-c) trap control_c SIGINT # Uncomment the line below in case you have not set the ANTSPATH variable in your environment. export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} #assuming .nii.gz as default file type. This is the case for ANTS 1.7 and up function Usage { cat < Example Case: echo " bash $0 -d 3 -m 30x50x20 -t GR -s CC -c 1 -o MY -z InitialTemplate.nii.gz *RF*T1x.nii.gz " echo " in this case you use 30x50x20 iterations per registration " echo " 4 iterations over template creation (that is the default) " echo " with Greedy-SyN and CC metrics to guide the mapping. " echo " Output is prepended with MY and the initial template is InitialTemplate.nii.gz (optional). " echo " the -c option is set to 1 which will try to use SGE to distribute the computation. " echo " if you do not have SGE, use -c 0 or -c 2 --- read the help." Compulsory arguments (minimal command line requires SGE cluster, otherwise use -c & -j options): -d: ImageDimension: 2 or 3 (for 2 or 3 dimensional registration of single volume) ImageDimension: 4 (for 3 dimensional registration of time-series; requires FSL) -o: OUTPREFIX; A prefix that is prepended to all output files. List of images in the current directory, eg *_t1.nii.gz. Should be at the end of the command. NB: All images to be added to the template should be in the same directory, and this script should be invoked from that directory. Optional arguments: -c: Control for parallel computation (default 1) -- 0 == run serially, 1 == SGE qsub, 2 == use PEXEC (localhost) -g: Gradient step size (default 0.25) -- smaller in magnitude results in more cautious steps -i: Iteration limit (default 4) -- iterations of the template construction (Iteration limit)*NumImages registrations. -j: Number of cpu cores to use (default: 2; -- requires "-c 2" -m: Max-iterations in each registration -n: N3BiasFieldCorrection of moving image (default 1) -- 0 == off, 1 == on -r: Do rigid-body registration of inputs before creating template (default 0) -- 0 == off 1 == on. Only useful when you do not have an initial template -s: Type of similarity metric used for registration. -t: Type of transformation model used for registration. -z: Use this this volume as the target of all inputs. When not used, the script will create an unbiased starting point by averaging all inputs. Use the full path! -------------------------------------------------------------------------------------- ANTS was created by: -------------------------------------------------------------------------------------- Brian B. Avants, Nick Tustison and Gang Song Penn Image Computing And Science Laboratory University of Pennsylvania -------------------------------------------------------------------------------------- script adapted by N.M. van Strien, http://www.mri-tutorial.com | NTNU MR-Center -------------------------------------------------------------------------------------- USAGE exit 1 } function Help { cat < Compulsory arguments (minimal command line requires SGE cluster, otherwise use -c & -j options):: -d: ImageDimension: 2 or 3 (for 2 or 3 dimensional registration of single volume) ImageDimension: 4 (for 3 dimensional registration of time-series; requires FSL) -o: OUTPREFIX; A prefix that is prepended to all output files. List of images in the current directory, eg *_t1.nii.gz. Should be at the end of the command. NB: All files to be added to the template should be in the same directory. Optional arguments: -c: Control for parallel computation --- if set to zero, run serially, if set to 2 , use PEXEC (localhost), if set to 1 , use SGE qsub. -g: Gradient step size; smaller in magnitude results in more cautious steps (default 0.25) -i: Iteration limit (default = 4) for template construction. requires 4*NumImages registrations. -j: Number of cpu cores to use (default: 2; --- set -c option to 2 to use this . The optimal number of cpu cores to use for template generation depends on the availability of cores, the amount of free working memory (RAM) and the resolution of the data. High resolution datasets typically require more RAM during processing. Running out of RAM during a calculation will slow down all processing on your computer. -m: Max-iterations Max-Iterations in form: JxKxL where J = max iterations at coarsest resolution (here, reduce by power of 2^2) K = middle resolution iterations (here,reduce by power of 2) L = fine resolution iterations (here, full resolution) !!this level takes much more time per iteration!! Adding an extra value before JxKxL (i.e. resulting in IxJxKxL) would add another iteration level. -n: N3BiasFieldCorrection of moving image ( 0 = off; 1 = on (default) ) -r: Do rigid-body registration of inputs before creating template (default 0) -- 0 == off 1 == on. Only useful when you do not have an initial template In case a template is specified (-z option), all inputs are registered to that template. If no template is specified, the inputs will be registered to the averaged input. -s: Type of similarity metric used for registration. For intramodal image registration, use: CC = cross-correlation MI = mutual information PR = probability mapping (default) MSQ = mean square difference For intermodal image registration, use: MI = mutual information PR = probability mapping (default) -t: Type of transformation model used for registration. For elastic image registration, use: EL = elastic transformation model (less deformation possible) For diffeomorphic image registration, use: SY = SyN with time (default) with arbitrary number of time points in time discretization S2 = SyN with time optimized specifically for 2 time points in the time discretization GR = Greedy SyN EX = Exponential DD = Diffeomorphic Demons style exponential mapping -z: Use this this volume as the target of all inputs. When not used, the script will create an unbiased starting point by averaging all inputs. Use the full path! Requirements: This scripts relies on the following scripts in your $ANTSPATH directory. The script will terminate prematurely if these files are not present or are not executable. - antsIntroduction.sh - pexec.sh - waitForSGEQJobs.pl (only for use with Sun Grid Engine) For 4D template building FSL is also needed -------------------------------------------------------------------------------------- Get the latest ANTS version at: -------------------------------------------------------------------------------------- http://sourceforge.net/projects/advants/ -------------------------------------------------------------------------------------- Read the ANTS documentation at: -------------------------------------------------------------------------------------- http://picsl.upenn.edu/ANTS/ -------------------------------------------------------------------------------------- ANTS was created by: -------------------------------------------------------------------------------------- Brian B. Avants, Nick Tustison and Gang Song Penn Image Computing And Science Laboratory University of Pennsylvania -------------------------------------------------------------------------------------- script adapted by N.M. van Strien, http://www.mri-tutorial.com | NTNU MR-Center -------------------------------------------------------------------------------------- HELP exit 1 } function setPath { cat < $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_2_2 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 " >> $OUTNM echo "FixedParameters: $PARAM7 $PARAM8 " >> $OUTNM } function ANTSAverage3DAffine { OUTNM=${templatename}Affine.txt FLIST=${outputname}*Affine.txt NFILES=0 PARAM1=0 PARAM2=0 PARAM3=0 PARAM4=0 PARAM5=0 PARAM6=0 PARAM7=0 PARAM8=0 PARAM9=0 PARAM10=0 PARAM11=0 PARAM12=0 PARAM13=0 PARAM14=0 PARAM15=0 LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM1=` awk -v a=$PARAM1 -v b=$x 'BEGIN{print (a + b)}' ` ; let NFILES=$NFILES+1 ; done PARAM1=` awk -v a=$PARAM1 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM2=` awk -v a=$PARAM2 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM2=` awk -v a=$PARAM2 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM3=` awk -v a=$PARAM3 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM3=` awk -v a=$PARAM3 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 5 ` for x in $LL ; do PARAM4=` awk -v a=$PARAM4 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM4=` awk -v a=$PARAM4 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 6 ` for x in $LL ; do PARAM5=` awk -v a=$PARAM5 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM5=` awk -v a=$PARAM5 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 7 ` for x in $LL ; do PARAM6=` awk -v a=$PARAM6 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM6=` awk -v a=$PARAM6 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 8 ` for x in $LL ; do PARAM7=` awk -v a=$PARAM7 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM7=` awk -v a=$PARAM7 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 9 ` for x in $LL ; do PARAM8=` awk -v a=$PARAM8 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM8=` awk -v a=$PARAM8 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 10 ` for x in $LL ; do PARAM9=` awk -v a=$PARAM9 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM9=` awk -v a=$PARAM9 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 11 ` for x in $LL ; do PARAM10=` awk -v a=$PARAM10 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM10=0 # ` awk -v a=$PARAM10 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 12 ` for x in $LL ; do PARAM11=` awk -v a=$PARAM11 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM11=0 # ` awk -v a=$PARAM11 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 13 ` for x in $LL ; do PARAM12=` awk -v a=$PARAM12 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM12=0 # ` awk -v a=$PARAM12 -v b=$NFILES 'BEGIN{print (a / b)}' ` # origin params below LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM13=` awk -v a=$PARAM13 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM13=` awk -v a=$PARAM13 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM14=` awk -v a=$PARAM14 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM14=` awk -v a=$PARAM14 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM15=` awk -v a=$PARAM15 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM15=` awk -v a=$PARAM15 -v b=$NFILES 'BEGIN{print (a / b)}' ` echo "# Insight Transform File V1.0 " > $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_3_3 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 $PARAM7 $PARAM8 $PARAM9 $PARAM10 $PARAM11 $PARAM12 " >> $OUTNM echo "FixedParameters: $PARAM13 $PARAM14 $PARAM15 " >> $OUTNM } function jobfnamepadding { files=`ls job*.sh` BASENAME1=`echo $files[1] | cut -d 'b' -f 1` for file in ${files} do if [ "${#file}" -eq "9" ] then BASENAME2=`echo $file | cut -d 'b' -f 2 ` mv "$file" "${BASENAME1}b_000${BASENAME2}" elif [ "${#file}" -eq "10" ] then BASENAME2=`echo $file | cut -d 'b' -f 2 ` mv "$file" "${BASENAME1}b_00${BASENAME2}" elif [ "${#file}" -eq "11" ] then BASENAME2=`echo $file | cut -d 'b' -f 2 ` mv "$file" "${BASENAME1}b_0${BASENAME2}" fi done } cleanup() # example cleanup function { cd ${currentdir}/ echo -en "\n*** Performing cleanup, please wait ***\n" # 1st attempt to kill all remaining processes # put all related processes in array runningANTSpids=( `ps -C ANTS -C N3BiasFieldCorrection -C fslsplit | awk '{ printf "%s\n", $1 ; }'` ) # debug only #echo list 1: ${runningANTSpids[@]} # kill these processes, skip the first since it is text and not a PID for ((i = 1; i < ${#runningANTSpids[@]} ; i++)) do echo "killing: ${runningANTSpids[${i}]}" kill ${runningANTSpids[${i}]} done return $? } control_c() # run if user hits control-c { echo -en "\n*** User pressed CTRL + C ***\n" cleanup exit $? echo -en "\n*** Script cancelled by user ***\n" } #initializing variables with global scope time_start=`date +%s` currentdir=`pwd` nargs=$# MAXITERATIONS=30x90x20 LABELIMAGE=0 # initialize optional parameter METRICTYPE=CC # initialize optional parameter TRANSFORMATIONTYPE="GR" # initialize optional parameter N3CORRECT=1 # initialize optional parameter DOQSUB=1 # By default, buildtemplateparallel tries to do things in parallel GRADIENTSTEP=0.25 # Gradient step size, smaller in magnitude means more smaller (more cautious) steps ITERATIONLIMIT=4 CORES=2 TDIM=0 RIGID=0 RIGIDTYPE=" --do-rigid" # set to an empty string to use affine initialization range=0 REGTEMPLATE=target cpu_count=`cat /proc/cpuinfo | grep processor | wc -l` ##Getting system info from linux can be done with these variables. # RAM=`cat /proc/meminfo | sed -n -e '/MemTotal/p' | awk '{ printf "%s %s\n", $2, $3 ; }' | cut -d " " -f 1` # RAMfree=`cat /proc/meminfo | sed -n -e '/MemFree/p' | awk '{ printf "%s %s\n", $2, $3 ; }' | cut -d " " -f 1` # cpu_free_ram=$((${RAMfree}/${cpu_count})) # Provide output for Help if [ "$1" == "-h" ] then Help >&2 fi OUTPUTNAME=antsBTP # reading command line arguments while getopts "c:d:g:i:j:h:m:n:o:s:r:t:z:" OPT do case $OPT in h) #help echo "$USAGE" exit 0 ;; c) #use SGE cluster DOQSUB=$OPTARG if [[ ${#DOQSUB} -gt 2 ]] ; then echo " DOQSUB must be an integer value (0=serial, 1=SGE qsub, 2=try pexec ) you passed -c $DOQSUB " exit 1 fi ;; d) #dimensions DIM=$OPTARG if [[ ${DIM} -eq 4 ]] ; then DIM=3 TDIM=4 fi ;; g) #gradient stepsize (default = 0.25) GRADIENTSTEP=$OPTARG ;; i) #iteration limit (default = 3) ITERATIONLIMIT=$OPTARG ;; j) #number of cpu cores to use (default = 2) CORES=$OPTARG ;; m) #max iterations other than default MAXITERATIONS=$OPTARG ;; n) #apply bias field correction N3CORRECT=$OPTARG ;; o) #output name prefix OUTPUTNAME=$OPTARG TEMPLATENAME=${OUTPUTNAME}template TEMPLATE=${TEMPLATENAME}.nii.gz ;; s) #similarity model METRICTYPE=$OPTARG ;; r) #start with rigid-body registration RIGID=$OPTARG ;; t) #transformation model TRANSFORMATIONTYPE=$OPTARG ;; z) #initialization template REGTEMPLATE=$OPTARG ;; \?) # getopts issues an error message echo "$USAGE" >&2 exit 1 ;; esac done if [ $DOQSUB -eq 1 ] ; then qq=`which qsub` if [ ${#qq} -lt 1 ] ; then echo do you have qsub? if not, then choose another c option ... if so, then check where the qsub alias points ... exit fi fi # Provide different output for Usage and Help if [ ${TDIM} -eq 4 ] && [ $nargs -lt 5 ] then Usage >&2 elif [ ${TDIM} -eq 4 ] && [ $nargs -eq 5 ] then echo "" # This option is required to run 4D template creation on SGE with a minimal command line elif [ $nargs -lt 6 ] then Usage >&2 fi #ANTSPATH=YOURANTSPATH if [ ${#ANTSPATH} -le 0 ] then setPath >&2 fi # Creating the file list of images to make a template from. # Shiftsize is calculated because a variable amount of arguments can be used on the command line. # The shiftsize variable will give the correct number of arguments to skip. Issuing shift $shiftsize will # result in skipping that number of arguments on the command line, so that only the input images remain. shiftsize=$(($OPTIND - 1)) shift $shiftsize # The invocation of $* will now read all remaining arguments into the variable IMAGESETVARIABLE IMAGESETVARIABLE=$* NINFILES=$(($nargs - $shiftsize)) #test if FSL is available in case of 4D, exit if not if [ ${TDIM} -eq 4 ] && [ ${#FSLDIR} -le 0 ] then setFSLPath >&2 fi if [ ${NINFILES} -eq 0 ] then echo "Please provide at least 2 filenames for the template." echo "Use `basename $0` -h for help" exit 1 elif [[ ${NINFILES} -eq 1 ]] && [[ -s ${FSLDIR}/bin/fslnvols ]] then range=`fslnvols ${IMAGESETVARIABLE}` if [ ${range} -eq 1 ] && [ ${TDIM} -ne 4 ] then echo "Please provide at least 2 filenames for the template." echo "Use `basename $0` -h for help" exit 1 elif [ ${range} -gt 1 ] && [ ${TDIM} -ne 4 ] then echo "This is a multivolume file. Use -d 4" echo "Use `basename $0` -h for help" exit 1 elif [ ${range} -gt 1 ] && [ ${TDIM} -eq 4 ] then echo "--------------------------------------------------------------------------------------" echo " Creating template of 4D input. " echo "--------------------------------------------------------------------------------------" #splitting volume #setting up working dirs mkdir tmp mkdir tmp/selection #split the 4D file into 3D elements cp ${IMAGESETVARIABLE} tmp/ cd tmp/ fslsplit ${IMAGESETVARIABLE} rm -f ${IMAGESETVARIABLE} # selecting 16 volumes randomly from the timeseries for averaging, placing them in tmp/selection. folder for ((i = 0; i < 16 ; i++)) do number=$RANDOM let "number %= $range" if [ ${number} -lt 10 ] then cp vol000${number}.nii.gz selection/ elif [ ${number} -ge 10 ] && [ ${number} -lt 100 ] then cp vol00${number}.nii.gz selection/ elif [ ${number} -ge 100 ] && [ ${number} -lt 1000 ] then cp vol0${number}.nii.gz selection/ fi done # set filelist variable cd selection/ IMAGESETVARIABLE=`ls *.nii.gz` fi fi # System specific queue options, eg "-q name" to submit to a specific queue # It can be set to an empty string if you do not need any special cluster options QSUBOPTS="" # EDIT THIS # Test availability of helper scripts. # No need to test this more than once. Can reside outside of the main loop. ANTSSCRIPTNAME=${ANTSPATH}antsIntroduction.sh PEXEC=${ANTSPATH}ANTSpexec.sh SGE=${ANTSPATH}waitForSGEQJobs.pl for FLE in $ANTSSCRIPTNAME $PEXEC $SGE do if [ ! -x $FLE ] ; then echo echo "--------------------------------------------------------------------------------------" echo " FILE $FLE DOES NOT EXIST -- OR -- IS NOT EXECUTABLE !!! $0 will terminate." echo "--------------------------------------------------------------------------------------" echo " if the file is not executable, please change its permissions. " exit 1 fi done # exit # check for an initial template image and perform rigid body registration if requested if [ ! -s $REGTEMPLATE ] then echo echo "--------------------------------------------------------------------------------------" echo " No initial template exists. Creating a population average image from the inputs." echo "--------------------------------------------------------------------------------------" ${ANTSPATH}AverageImages $DIM $TEMPLATE 1 $IMAGESETVARIABLE else echo echo "--------------------------------------------------------------------------------------" echo " Initial template found. This will be used for guiding the registration. use : $REGTEMPLATE and $TEMPLATE " echo "--------------------------------------------------------------------------------------" # now move the initial registration template to OUTPUTNAME, otherwise this input gets overwritten. cp ${REGTEMPLATE} ${TEMPLATE} fi if [ ! -s $TEMPLATE ] ; then echo Your template : $TEMPLATE was not created. This indicates trouble! You may want to check correctness of your input parameters. exiting. exit fi # remove old job bash scripts rm -f job*.sh if [ "$RIGID" -eq 1 ] ; then count=0 jobIDs="" RIGID_IMAGESET="" for IMG in $IMAGESETVARIABLE do RIGID_IMAGESET="$RIGID_IMAGESET rigid_${IMG}" BASENAME=` echo ${IMG} | cut -d '.' -f 1 ` exe=" ${ANTSPATH}ANTS $DIM -m MI[${TEMPLATE},${IMG},1,32] -o rigid_${IMG} -i 0 --use-Histogram-Matching --number-of-affine-iterations 10000x10000x10000x10000x10000 $RIGIDTYPE" exe2="${ANTSPATH}WarpImageMultiTransform $DIM ${IMG} rigid_${IMG} rigid_${BASENAME}Affine.txt -R ${TEMPLATE}" pexe=" $exe >> job_${count}_metriclog.txt " qscript="job_${count}_qsub.sh" echo "$exe" > $qscript echo "$exe2" >> $qscript if [ $DOQSUB -eq 1 ] ; then id=`qsub -cwd -S /bin/bash -N antsBuildTemplate_rigid -v ANTSPATH=$ANTSPATH $QSUBOPTS $qscript | awk '{print $3}'` jobIDs="$jobIDs $id" sleep 0.5 elif [ $DOQSUB -eq 2 ] ; then # Send pexe and exe2 to same job file so that they execute in series echo $pexe >> job${count}_r.sh echo $exe2 >> job${count}_r.sh elif [ $DOQSUB -eq 0 ] ; then # execute jobs in series $exe $exe2 fi ((count++)) done if [ $DOQSUB -eq 1 ]; then # Run jobs on SGE and wait to finish echo echo "--------------------------------------------------------------------------------------" echo " Starting ANTS rigid registration on cluster. Submitted $count jobs " echo "--------------------------------------------------------------------------------------" # now wait for the jobs to finish. Rigid registration is quick, so poll queue every 60 seconds ${ANTSPATH}waitForSGEQJobs.pl 1 60 $jobIDs # Returns 1 if there are errors if [ ! $? -eq 0 ]; then echo "qsub submission failed - jobs went into error state" exit 1; fi fi # Run jobs on localhost and wait to finish if [ $DOQSUB -eq 2 ]; then echo echo "--------------------------------------------------------------------------------------" echo " Starting ANTS rigid registration on max ${CORES} cpucores. " echo " Progress can be viewed in job*_metriclog.txt" echo "--------------------------------------------------------------------------------------" jobfnamepadding #adds leading zeros to the jobnames, so they are carried out chronologically chmod +x job*.sh $PEXEC -j ${CORES} "sh" job*.sh fi # Update template ${ANTSPATH}AverageImages $DIM $TEMPLATE 1 $RIGID_IMAGESET # cleanup and save output in seperate folder mkdir rigid mv *.cfg rigid_*.nii.gz *Affine.txt rigid/ # backup logs if [ $DOQSUB -eq 1 ]; then mv antsBuildTemplate_rigid* rigid/ # Remove qsub scripts rm -f job_${count}_qsub.sh elif [ $DOQSUB -eq 2 ]; then mv job*.txt rigid/ fi fi # endif RIGID # Begin Main Loop ITERATLEVEL=(` echo $MAXITERATIONS | tr 'x' ' ' `) NUMLEVELS=${#ITERATLEVEL[@]} # debugging only #echo $ITERATLEVEL #echo $NUMLEVELS #echo ${ITERATIONLIMIT} echo "--------------------------------------------------------------------------------------" echo " Start to build template: ${TEMPLATE}" echo "--------------------------------------------------------------------------------------" reportMappingParameters i=0 while [ $i -lt ${ITERATIONLIMIT} ] do itdisplay=$((i+1)) rm -f ${OUTPUTNAME}*Warp*.nii* rm -f job*.sh # Used to save time by only running coarse registration for the first couple of iterations # But with decent initialization, this is probably not worthwhile. # If you uncomment this, replace MAXITERATIONS with ITERATIONS in the call to ants below # # # For the first couple of iterations, use high-level registration only # # eg if MAXITERATIONS=30x90x20, then for iteration 0, do 30x0x0 # # for iteration 1 do 30x90x0, then do 30x90x20 on subsequent iterations # if [ $i -gt $((NUMLEVELS - 1)) ] # then # ITERATIONS=$MAXITERATIONS # else # # ITERATIONS=${ITERATLEVEL[0]} # # for (( n = 1 ; n < ${NUMLEVELS}; n++ )) # do # ITERATIONS=${ITERATIONS}x$((${ITERATLEVEL[n]} * $((n <= i)) )) # done # fi # Job IDs of jobs submitted to queue in loop below jobIDs="" # Reinitialize count to 0 count=0 # Submit registration of each input to volume template to SGE or run locally. for IMG in $IMAGESETVARIABLE do # 1 determine working dir dir=`pwd` # 2 determine new filename POO=${OUTPUTNAME}${IMG} # 3 Make variable OUTFILENAME and remove anything behind . ; for example .nii.gz.gz OUTFN=${POO%.*.*} # 4 Test if outputfilename has only a single extention and remove that if [ ${#OUTFN} -eq ${#POO} ] then OUTFN=${OUTPUTNAME}${IMG%.*} fi # 5 prepare registration command exe="${ANTSSCRIPTNAME} -d ${DIM} -r ${dir}/${TEMPLATE} -i ${dir}/${IMG} -o ${dir}/${OUTFN} -m ${MAXITERATIONS} -n ${N3CORRECT} -s ${METRICTYPE} -t ${TRANSFORMATIONTYPE} " pexe=" $exe >> job_${count}_${i}_metriclog.txt " # 6 submit to SGE or else run locally if [ $DOQSUB -eq 1 ]; then id=`qsub -cwd -N antsBuildTemplate_deformable_${i} -S /bin/bash -v ANTSPATH=$ANTSPATH $QSUBOPTS $exe | awk '{print $3}'` jobIDs="$jobIDs $id" sleep 0.5 elif [ $DOQSUB -eq 2 ] ; then echo $pexe echo $pexe >> job${count}_${i}.sh elif [ $DOQSUB -eq 0 ] ; then bash $exe fi # counter updated, but not directly used in this loop count=`expr $count + 1`; # echo " submitting job number $count " # for debugging only done # SGE wait for script to finish if [ $DOQSUB -eq 1 ]; then echo echo "--------------------------------------------------------------------------------------" echo " Starting ANTS registration on SGE cluster. Iteration: $itdisplay of $ITERATIONLIMIT" echo "--------------------------------------------------------------------------------------" # now wait for the stuff to finish - this will take a while so poll queue every 10 mins ${ANTSPATH}waitForSGEQJobs.pl 1 600 $jobIDs if [ ! $? -eq 0 ]; then echo "qsub submission failed - jobs went into error state" exit 1; fi fi # Run jobs on localhost and wait to finish if [ $DOQSUB -eq 2 ]; then echo echo "--------------------------------------------------------------------------------------" echo " Starting ANTS registration on max ${CORES} cpucores. Iteration: $itdisplay of $ITERATIONLIMIT" echo " Progress can be viewed in job*_${i}_metriclog.txt" echo "--------------------------------------------------------------------------------------" jobfnamepadding #adds leading zeros to the jobnames, so they are carried out chronologically chmod +x job*.sh $PEXEC -j ${CORES} sh job*.sh fi shapeupdatetotemplate ${DIM} ${TEMPLATE} ${TEMPLATENAME} ${OUTPUTNAME} ${GRADIENTSTEP} if [ $DIM -eq 2 ] then ${ANTSPATH}MeasureMinMaxMean $DIM ${TEMPLATENAME}warpxvec.nii.gz ${TEMPLATENAME}warpxlog.txt 1 ${ANTSPATH}MeasureMinMaxMean $DIM ${TEMPLATENAME}warpyvec.nii.gz ${TEMPLATENAME}warpylog.txt 1 elif [ $DIM -eq 3 ] then ${ANTSPATH}MeasureMinMaxMean $DIM ${TEMPLATENAME}warpxvec.nii.gz ${TEMPLATENAME}warpxlog.txt 1 ${ANTSPATH}MeasureMinMaxMean $DIM ${TEMPLATENAME}warpyvec.nii.gz ${TEMPLATENAME}warpylog.txt 1 ${ANTSPATH}MeasureMinMaxMean $DIM ${TEMPLATENAME}warpzvec.nii.gz ${TEMPLATENAME}warpzlog.txt 1 fi echo echo "--------------------------------------------------------------------------------------" echo " Backing up results from iteration $itdisplay" echo "--------------------------------------------------------------------------------------" mkdir ${TRANSFORMATIONTYPE}_iteration_${i} cp ${TEMPLATENAME}warp*log.txt *.cfg *${OUTPUTNAME}*.nii.gz ${TRANSFORMATIONTYPE}_iteration_${i}/ # backup logs if [ $DOQSUB -eq 1 ]; then mv antsBuildTemplate_deformable_* ${TRANSFORMATIONTYPE}_iteration_${i} elif [ $DOQSUB -eq 2 ]; then mv job*.txt ${TRANSFORMATIONTYPE}_iteration_${i} fi ((i++)) done # end main loop rm -f job*.sh #cleanup of 4D files if [ "${range}" -gt 1 ] && [ "${TDIM}" -eq 4 ] then mv ${currentdir}/tmp/selection/${TEMPLATE} ${currentdir}/ cd ${currentdir} rm -rf ${currentdir}/tmp/ fi time_end=`date +%s` time_elapsed=$((time_end - time_start)) echo echo "--------------------------------------------------------------------------------------" echo " Done creating: ${TEMPLATE}" echo " Script executed in $time_elapsed seconds" echo " $(( time_elapsed / 3600 ))h $(( time_elapsed %3600 / 60 ))m $(( time_elapsed % 60 ))s" echo "--------------------------------------------------------------------------------------" exit 0 ants-1.9.2+svn680.dfsg/Scripts/geodesicinterpolation.sh000077500000000000000000000155441147325206600230510ustar00rootroot00000000000000#!/bin/bash NUMPARAMS=$# if [ $NUMPARAMS -lt 2 ] then echo " USAGE :: " echo " sh geodesicinterpolation.sh image1 image2 N-interpolation-points N-step-size Use-Affine-Initialization? Mask-Image Auxiliary-Template " echo " N-interpolation-points -- if you choose 10 points and step-size of 1 then you will get 8 interpolated/morphed images -- end-points are the original images " echo " if you choose 10 points and step-size of 2 then you will get 4 interpolated/morphed images -- end-points are the original images " echo " if you use affine initialization - sometimes it could cause unpleasantness, if the affine mapping is large -- sometimes it may be needed, though " echo " the mask image restricts matching to an ROI " echo " The Auxiliary-Template is another image through which the morph images (image1 and image2) are mapped -- this often helps, if the auxiliary template is an average face image " echo " Be sure to set the ANTSPATH path variable " echo " " echo " You may need to tune the ANTS parameters coded within this script for your application " exit fi # should we use the generative model to find landmarks then # drive individual mappings by the LMs? TEMPLATE=$1 TARGET=$2 NUMSTEPS=10 STEP=1 OUTNAME=ANTSMORPH if [ $NUMPARAMS -gt 2 ] then NUMSTEPS=$3 fi if [ $NUMPARAMS -gt 3 ] then STEP=$4 fi USEAFF=0 if [ $NUMPARAMS -gt 4 ] then USEAFF=$5 fi MASK=0 if [ $NUMPARAMS -gt 5 ] then MASK=$6 fi TEMPLATEB=0 if [ $NUMPARAMS -gt 6 ] then TEMPLATEB=$7 fi echo " Morphing in total $NUMSTEPS time-points by $STEP steps -- end-points are original images " echo " Use-Affine ? $USEAFF " echo " templateB $TEMPLATEB " for (( n = 0 ; n <= ${NUMSTEPS}; n=n+${STEP} )) do BLENDINGA=$(echo "scale=2; ${n}/${NUMSTEPS}" | bc ) BLENDINGB=$(echo "scale=2; 1-$BLENDINGA" | bc ) BLENDNAME=$(echo "scale=2; 100*$BLENDINGA" | bc ) echo " Blending values: $BLENDINGA and $BLENDINGB" done ITS=100x100x10 TRAN=SyN[0.5] REG=Gauss[3,1] RADIUS=6 if [ $NUMPARAMS -le 5 ] then if [ $USEAFF -eq 0 ] then ${ANTSPATH}ANTS 2 -m PR[$TEMPLATE,$TARGET,1,${RADIUS}] -t $TRAN -r $REG -o $OUTNAME -i $ITS --number-of-affine-iterations 0 -x $MASK fi if [ $USEAFF -ne 0 ] then ${ANTSPATH}ANTS 2 -m PR[$TEMPLATE,$TARGET,1,${RADIUS}] -t $TRAN -r $REG -o $OUTNAME -i $ITS -x $MASK #--MI-option 16x2000 fi ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}Warp.nii -R $TEMPLATE ${OUTNAME}Warp.nii ${OUTNAME}Affine.txt ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}InverseWarp.nii -R $TARGET -i ${OUTNAME}Affine.txt ${OUTNAME}InverseWarp.nii fi if [ $NUMPARAMS -gt 5 ] then if [ $USEAFF -eq 0 ] then #echo " Pseudo-Morphing " #echo " method 1 " ${ANTSPATH}ANTS 2 -m PR[$TEMPLATEB,$TARGET,1,${RADIUS}] -t $TRAN -r $REG -o ${OUTNAME}B -i $ITS --number-of-affine-iterations 0 -x $MASK ${ANTSPATH}ANTS 2 -m PR[$TEMPLATE,$TEMPLATEB,1,${RADIUS}] -t $TRAN -r $REG -o ${OUTNAME}A -i $ITS --number-of-affine-iterations 0 -x $MASK ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}AWarp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}AAffine.txt ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}AInverseWarp.nii -R $TEMPLATEB -i ${OUTNAME}AAffine.txt ${OUTNAME}AInverseWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}BWarp.nii -R $TEMPLATEB ${OUTNAME}BWarp.nii ${OUTNAME}BAffine.txt ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}BInverseWarp.nii -R $TARGET -i ${OUTNAME}BAffine.txt ${OUTNAME}BInverseWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}Warp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}BWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}InverseWarp.nii -R $TARGET ${OUTNAME}BInverseWarp.nii ${OUTNAME}AInverseWarp.nii # #echo " method 2 " #${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}Warp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}AAffine.txt ${OUTNAME}BWarp.nii ${OUTNAME}BAffine.txt #${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}InverseWarp.nii -R $TARGET -i ${OUTNAME}BAffine.txt ${OUTNAME}BInverseWarp.nii -i ${OUTNAME}AAffine.txt ${OUTNAME}AInverseWarp.nii # fi if [ $USEAFF -ne 0 ] then #echo " Pseudo-Morphing " #echo " method 1 " ${ANTSPATH}ANTS 2 -m PR[$TEMPLATEB,$TARGET,1,${RADIUS}] -t $TRAN -r $REG -o ${OUTNAME}B -i $ITS -x $MASK ${ANTSPATH}ANTS 2 -m PR[$TEMPLATE,$TEMPLATEB,1,${RADIUS}] -t $TRAN -r $REG -o ${OUTNAME}A -i $ITS -x $MASK ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}AWarp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}AAffine.txt ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}AInverseWarp.nii -R $TEMPLATEB -i ${OUTNAME}AAffine.txt ${OUTNAME}AInverseWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}BWarp.nii -R $TEMPLATEB ${OUTNAME}BWarp.nii ${OUTNAME}BAffine.txt ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}BInverseWarp.nii -R $TARGET -i ${OUTNAME}BAffine.txt ${OUTNAME}BInverseWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}Warp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}BWarp.nii ${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}InverseWarp.nii -R $TARGET ${OUTNAME}BInverseWarp.nii ${OUTNAME}AInverseWarp.nii # #echo " method 2 " #${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}Warp.nii -R $TEMPLATE ${OUTNAME}AWarp.nii ${OUTNAME}AAffine.txt ${OUTNAME}BWarp.nii ${OUTNAME}BAffine.txt #${ANTSPATH}ComposeMultiTransform 2 ${OUTNAME}InverseWarp.nii -R $TARGET -i ${OUTNAME}BAffine.txt ${OUTNAME}BInverseWarp.nii -i ${OUTNAME}AAffine.txt ${OUTNAME}AInverseWarp.nii # fi fi for (( n = 0 ; n <= ${NUMSTEPS}; n=n+${STEP} )) do BLENDINGA=$(echo "scale=2; ${n}/${NUMSTEPS}" | bc ) BLENDINGB=$(echo "scale=2; 1-$BLENDINGA" | bc ) BLENDNAME=$(echo "scale=2; 100*$BLENDINGA" | bc ) echo " Blending values: $BLENDINGA and $BLENDINGB" BASEA=${TEMPLATE%.*} BASEB=${TARGET%.*} ${ANTSPATH}MultiplyImages 2 ${OUTNAME}InverseWarpxvec.nii $BLENDINGA SM${OUTNAME}InverseWarpxvec.nii ${ANTSPATH}MultiplyImages 2 ${OUTNAME}InverseWarpyvec.nii $BLENDINGA SM${OUTNAME}InverseWarpyvec.nii ${ANTSPATH}MultiplyImages 2 ${OUTNAME}Warpxvec.nii $BLENDINGB SM${OUTNAME}Warpxvec.nii ${ANTSPATH}MultiplyImages 2 ${OUTNAME}Warpyvec.nii $BLENDINGB SM${OUTNAME}Warpyvec.nii ${ANTSPATH}WarpImageMultiTransform 2 $TARGET temp.nii SM${OUTNAME}Warp.nii -R $TEMPLATE ${ANTSPATH}ImageMath 2 temp.nii Normalize temp.nii 1 ${ANTSPATH}ImageMath 2 temp.nii m temp.nii 1. #$BLENDINGA ${ANTSPATH}WarpImageMultiTransform 2 $TEMPLATE temp2.nii SM${OUTNAME}InverseWarp.nii -R $TEMPLATE ${ANTSPATH}ImageMath 2 temp2.nii Normalize temp2.nii 1 ${ANTSPATH}ImageMath 2 temp2.nii m temp2.nii 0 #$BLENDINGB echo " ImageMath 2 ${BASEA}${BASEB}${BLENDNAME}morph.nii + temp2.nii temp.nii " ${ANTSPATH}ImageMath 2 ${BASEA}${BASEB}${BLENDNAME}morph.nii + temp2.nii temp.nii ${ANTSPATH}ConvertToJpg ${BASEA}${BASEB}${BLENDNAME}morph.nii ${BASEA}${BASEB}${BLENDNAME}morph.jpg rm -f ${BASEA}${BASEB}${BLENDNAME}morph.nii done rm -f ${OUTNAME}* SM${OUTNAME}* exit ants-1.9.2+svn680.dfsg/Scripts/guidedregistration.sh000077500000000000000000000040371147325206600223460ustar00rootroot00000000000000#!/bin/sh if [ $# -lt 7 ] then echo " USAGE \n sh command.sh fixed.nii fixedhipp.nii moving.nii movinghipp.nii outputname iterations DIM " echo " the template = fixed.nii , the individual = moving.nii " echo " iterations should be of the form 100x100x10 " exit fi FIX=$1 FIXH=$2 MOV=$3 MOVH=$4 OUT=$5 ITS=$6 DIM=$7 #ANTSPATH='/Users/stnava/Code/bin/ants/' if [ ${#FIX} -lt 1 -o ! -f $FIX ] then echo " Problem with specified Fixed Image => User Specified Value = $FIX " exit fi if [ ${#MOV} -lt 1 -o ! -f $MOV ] then echo " Problem with specified Moving Image => User Specified Value = $MOV " exit fi if [ ${#FIXH} -lt 1 -o ! -f $FIXH ] then echo " Problem with specified Fixed Label Image => User Specified Value = $FIXH " exit fi if [ ${#MOVH} -lt 1 -o ! -f $MOVH ] then echo " Problem with specified Moving Label Image => User Specified Value = $MOVH " exit fi # == Important Parameters Begin == LMWT=$9 # weight on landmarks INTWT=$8 # weight on intensity -- twice the landmarks # PSE/point-set-expectation/PointSetExpectation[fixedImage,movingImage,fixedPoints,movingPoints,weight,pointSetPercentage,pointSetSigma,boundaryPointsOnly,kNeighborhood, PartialMatchingIterations=100000] # the partial matching option assumes the complete labeling is in the first set of label parameters ... # more iterations leads to more symmetry in the matching - 0 iterations means full asymmetry PCT=0.1 # percent of labeled voxels to use PARZ=100 # PARZEN sigma LM=PSE[${FIX},${MOV},$FIXH,$MOVH,${LMWT},${PCT},${PARZ},0,25,100] INTENSITY=PR[$FIX,${MOV},${INTWT},4] # == Important Parameters end? == ${ANTSPATH}ANTS $DIM -o $OUT -i $ITS -t SyN[0.25] -r Gauss[3,0] -m $INTENSITY -m $LM ${ANTSPATH}WarpImageMultiTransform $DIM $MOV ${OUT}toTemplate.nii ${OUT}Warp.nii ${OUT}Affine.txt -R $FIX ${ANTSPATH}WarpImageMultiTransform $DIM $FIX ${OUT}toMov.nii -i ${OUT}Affine.txt ${OUT}InverseWarp.nii -R $MOV ${ANTSPATH}WarpImageMultiTransform $DIM $FIXH ${OUT}hipp.nii -i ${OUT}Affine.txt ${OUT}InverseWarp.nii -R $MOV --UseNN ants-1.9.2+svn680.dfsg/Scripts/landmarkmatch.sh000077500000000000000000000051031147325206600212530ustar00rootroot00000000000000#!/bin/sh if [ $# -lt 6 ] then echo " USAGE \n sh $0 fixed.nii fixedhipp.nii moving.nii movinghipp.nii ITERATIONS LandmarkWeight " echo " you should set LandmarkWeight yourself --- the intensity weight is 1. so the landmark weight should be in that range (e.g. 0.5 => 1 ) " echo " the usage indicates .nii but you can use whatever image type you like (as long as itk can read it). also, the fixedhipp.nii can contain either the full hippocampus or the landmarks for the hippocampus --- this would be your template. the moving.nii can contain either one as well. if the moving contains the landmarks and the fixed contains the full hippocampus, then this is known as "partial matching" as in Pluta, et al Hippocampus 2009. " exit fi #ANTSPATH="/mnt/aibs1/avants/bin/ants/" ITS=$5 LMWT=$6 INTWT=1 FIX=$1 FIXH=$2 MOV=$3 MOVH=$4 OUT=${MOV%.*} NN=${#OUT} MM=${#MOV} let DD=MM-NN if [ $DD -eq 3 ] then OUT=${MOV%.*.*} fi OUT2=${FIX%.*} NN=${#OUT2} MM=${#FIX} let DD=MM-NN if [ $DD -eq 3 ] then OUT2=${FIX%.*.*} fi dothis=0 if [ $dothis -eq 1 ] then # here, we select a subset of the labeled regions FIXHMOD=${OUT2}locmod.nii.gz MOVHMOD=${OUT}locmod.nii.gz for i in $MOVH do PRE=$OUT TOUT=${PRE}locmod.nii.gz echo " DOING $TOUT " ${ANTSPATH}ThresholdImage 3 $i ${PRE}tempb.nii.gz 30.5 32.5 ${ANTSPATH}MultiplyImages 3 $i ${PRE}tempb.nii.gz $TOUT ${ANTSPATH}ThresholdImage 3 $i ${PRE}tempb.nii.gz 20.5 22.5 ${ANTSPATH}MultiplyImages 3 $i ${PRE}tempb.nii.gz ${PRE}tempb.nii ${ANTSPATH}ImageMath 3 $TOUT + $TOUT ${PRE}tempb.nii.gz ${ANTSPATH}ThresholdImage 3 $i ${PRE}tempb.nii.gz 8.5 10.5 ${ANTSPATH}MultiplyImages 3 $i ${PRE}tempb.nii.gz ${PRE}tempb.nii.gz ${ANTSPATH}ImageMath 3 $TOUT + $TOUT ${PRE}tempb.nii.gz done else FIXHMOD=$FIXH MOVHMOD=$MOVH fi KNN=10 PERCENTtoUSE=0.5 PARZSIG=10 LM=PSE[${FIX},${MOV},${FIXHMOD},${MOVHMOD},${LMWT},${PERCENTtoUSE},${PARZSIG},0,${KNN}] echo $LM if [ $# -gt 6 ] then OUT=$7 fi STEPL=0.25 INTENSITY=PR[$FIX,${MOV},${INTWT},4] if [ $LMWT -le 0 ] then exe="${ANTSPATH}ANTS 3 -o $OUT -i $ITS -t SyN[${STEPL}] -r Gauss[3,0] -m $INTENSITY " else exe="${ANTSPATH}ANTS 3 -o $OUT -i $ITS -t SyN[${STEPL}] -r Gauss[3,0] -m $LM -m $INTENSITY " fi echo " $exe " $exe ${ANTSPATH}WarpImageMultiTransform 3 $MOV ${OUT}deformed.nii.gz ${OUT}Warp.nii.gz ${OUT}Affine.txt -R $FIX ${ANTSPATH}WarpImageMultiTransform 3 $MOVH ${OUT}label.nii.gz ${OUT}Warp.nii.gz ${OUT}Affine.txt -R $FIX --use-NN ${ANTSPATH}WarpImageMultiTransform 3 $FIXH ${OUT}labelinv.nii.gz -i ${OUT}Affine.txt ${OUT}InverseWarp.nii.gz -R $MOV --use-NN ants-1.9.2+svn680.dfsg/Scripts/lohmann.sh000077500000000000000000000056331147325206600201110ustar00rootroot00000000000000#!/bin/sh NUMPARAMS=$# MAXITERATIONS=30x90x20 if [ $NUMPARAMS -lt 2 ] then echo " USAGE :: " echo " sh $0 ImageDimension image.ext " echo " be sure to set ANTSPATH environment variable " exit fi ANTSPATH=/mnt/aibs1/avants/bin/ants/ if [ ${#ANTSPATH} -le 0 ] then echo " Please set ANTSPATH=LocationOfYourAntsBinaries " echo " Either set this in your profile or directly, here in the script. " echo " For example : " echo " ANTSPATH=/home/yourname/bin/ants/ " exit else echo " ANTSPATH is $ANTSPATH " fi #initialization, here, is unbiased DIM=$1 if [ ${#DIM} -gt 1 ] then echo " Problem with specified ImageDimension => User Specified Value = $DIM " exit fi FIXED=$2 if [ ${#FIXED} -lt 1 -o ! -f $FIXED ] then echo " Problem with specified Fixed Image => User Specified Value = $FIXED " exit fi OUTPUTNAME=` echo $FIXED | cut -d '.' -f 1 ` if [[ ! -s ${OUTPUTNAME}repaired.nii.gz ]] ; then ${ANTSPATH}N3BiasFieldCorrection $DIM $FIXED ${OUTPUTNAME}repaired.nii.gz 4 fi ${ANTSPATH}ThresholdImage $DIM ${OUTPUTNAME}repaired.nii.gz ${OUTPUTNAME}mask.nii.gz 0.1 99999 WM=${OUTPUTNAME}seg.nii.gz if [[ ! -s $WM ]] ; then ${ANTSPATH}Apocrita $DIM -x ${OUTPUTNAME}mask.nii.gz -m [0.5,1,0,0] -o [${OUTPUTNAME}seg.nii.gz] -i Otsu[${OUTPUTNAME}repaired.nii.gz,3] -h 0 ${ANTSPATH}ThresholdImage $DIM $WM $WM 3 3 ${ANTSPATH}ImageMath $DIM $WM GetLargestComponent $WM fi OUT=${OUTPUTNAME} if [[ ! -s ${OUT}max.nii.gz ]] ; then # the closing operation - arachnoid surface ${ANTSPATH}ImageMath 3 ${OUT}max.nii.gz MD $WM 15 ${ANTSPATH}ImageMath 3 ${OUT}max.nii.gz ME ${OUT}max.nii.gz 15 # unfolded or lissencephalic surface # we would prefer to do this in a topology preserving way ${ANTSPATH}ImageMath 3 ${OUT}min.nii.gz ME $WM 5 ${ANTSPATH}ImageMath 3 ${OUT}min.nii.gz MD ${OUT}min.nii.gz 5 # distance transform from arachnoid surface to inside of brain # perhaps should be a geodesic distance transform ${ANTSPATH}ImageMath 3 ${OUT}max.nii.gz Neg ${OUT}max.nii ${ANTSPATH}ImageMath 3 ${OUT}dist.nii.gz D ${OUT}max.nii fi # multiply the distance transform by the "unfolded" surface # this gives the "feature" surface/image that could be input # to an image registration similarity metric ${ANTSPATH}ImageMath 3 ${OUT}lohmann.nii.gz m ${OUT}dist.nii.gz ${OUT}min.nii.gz # surface stuff for visualization ${ANTSPATH}ImageMath 3 ${OUT}surf.nii.gz ME ${OUT}min.nii.gz 2 ${ANTSPATH}ImageMath 3 ${OUT}surf.nii.gz - ${OUT}min.nii.gz ${OUT}surf.nii.gz ${ANTSPATH}ImageMath 3 ${OUT}maxvals.nii.gz m ${OUT}lohmann.nii.gz ${OUT}surf.nii.gz # find sulci using curvature of the WM/lohmann surface ${ANTSPATH}SurfaceCurvature ${OUT}lohmann.nii.gz ${OUT}lohmannk.nii.gz 1.5 ${ANTSPATH}ThresholdImage 3 ${OUT}lohmann.nii.gz ${OUT}lohmann.nii.gz 0.001 9999 ${ANTSPATH}ImageMath 3 ${OUT}lohmannk.nii.gz Normalize ${OUT}lohmannk.nii.gz ${ANTSPATH}ImageMath 3 ${OUT}lohmannk.nii.gz m ${OUT}lohmannk.nii.gz ${OUT}lohmann.nii.gz exit ants-1.9.2+svn680.dfsg/Scripts/optimalsmooth.sh000077500000000000000000000006111147325206600213430ustar00rootroot00000000000000#!/bin/sh echo " sh $0 outputprefix " if [ $# -lt 1 ] ; then exit fi export ANTSPATH=${ANTSPATH:="$HOME/bin/ants/"} SUB=$1 TH=${SUB}thicknorm.nii.gz JA=${SUB}logjacobian.nii MK=${SUB}mask.nii.gz OUTT=${SUB}smooththick.nii.gz OUTJ=${SUB}smoothjac.nii.gz REPS=5 ${ANTSPATH}SurfaceBasedSmoothing $TH 1.5 $MK $OUTT $REPS ${ANTSPATH}SurfaceBasedSmoothing $JA 1.5 $MK $OUTJ $REPS ants-1.9.2+svn680.dfsg/Scripts/phantomstudy.sh000077500000000000000000000027351147325206600212140ustar00rootroot00000000000000#!/bin/sh ANTSPATH="/Users/stnava/Code/bin/ants/" #initialization, here, is unbiased count=0 for x in phantomAwmgm.jpg phantomBwmgm.jpg phantomCwmgm.jpg phantomDwmgm.jpg phantomEwmgm.jpg phantomFwmgm.jpg phantomGwmgm.jpg phantomHwmgm.jpg do count=`expr $count + 1` # Increment the counter echo " count is $count and file is $x " ${ANTSPATH}ANTS 2 -m PR[phantomtemplate.jpg,$x,1,4] -i 20x161x161x161 -o TEST{$count} -t SyN[2] -r Gauss[3,0.] # # -t SyN[1,2,0.05] -r Gauss[3,0.25] ${ANTSPATH}WarpImageMultiTransform 2 $x TEST{$count}registered.nii TEST{$count}Warp.nii TEST{$count}Affine.txt done # to look at the stack of results, do this: ${ANTSPATH}StackSlices volo.hdr -1 -1 0 *$1 ${ANTSPATH}StackSlices volr.hdr -1 -1 0 *registered.nii count=0 for x in phantomAwmgm.jpg phantomBwmgm.jpg phantomCwmgm.jpg phantomDwmgm.jpg phantomEwmgm.jpg phantomFwmgm.jpg phantomGwmgm.jpg phantomHwmgm.jpg do count=`expr $count + 1` # Increment the counter echo " count is $count and file is $x " echo " CreateJacobianDeterminantImage 2 TEST{$count}Warp.nii TEST{$count}logjac.nii 1 " ${ANTSPATH}CreateJacobianDeterminantImage 2 TEST{$count}Warp.nii TEST{$count}logjac.nii 1 # ${ANTSPATH}SmoothImage 2 TEST{$count}logjac.nii 1 TEST{$count}logjac.nii done ${ANTSPATH}ThresholdImage 2 phantomtemplate.jpg mask.nii 100 200 # use the GLM with mask ${ANTSPATH}GLM 2 mask.nii designmat.txt contrast.txt Result.nii 1000 TEST*logjac.nii ants-1.9.2+svn680.dfsg/Scripts/registerimages.pl000077500000000000000000000033441147325206600214650ustar00rootroot00000000000000#!/usr/bin/perl -w use File::Basename; if ($#ARGV >= 0) { $who = join(' ', $ARGV[0]); } if ($#ARGV >= 1) { $template = join(' ', $ARGV[1]); } if ($#ARGV >= 2) { $params = join(' ', $ARGV[2]); } else { $params=0; } if ($#ARGV >= 3) { $outnaming = join(' ', $ARGV[3]); } else { $outnaming=0; } if ($#ARGV >= 4) { $metric= join(' ', $ARGV[4]); } else { $metric="PR[".$template; } if ($#ARGV >= 5) { $metricpar= join(' ', $ARGV[5]); } else { $metricpar=",1,4]"; } opendir(DIR, $who); @filelist = glob("$who"); # @filelist2 = glob("$who2"); $ct=100; print " Expecting Normalization params ".$params." \n \n \n doing \n $who \n "; $dir = `pwd`; $dir=substr($dir,0,length($dir)-1)."/"; $pathpre=""; $qsname="superfresh.sh"; foreach $name (@filelist) { $pre=$outnaming.$name; $pre=~s/\.[^.]*$//; print $pre." \n "; $prog=$params; $exe=$prog." -m ".$metric.",".$name.",".$metricpar." -o ".$pre." \n "; $exe2 = "/mnt/pkg/sge-root/bin/lx24-x86/qsub -q mac ".$qsname." ".$dir." ".$exe." "; print $exe."\n"; system $exe2; # USE qstat TO VERIFY THE JOB IS SUBMITTED $ct=$ct+1; } print " DONE WITH LOOP \n "; $user=`whoami`; chomp($user); print " you are ".$user." = surf-king "; $atcfn=0; if ($atcfn) { $waitcmd="vq -s | grep ".$user; } else { $waitcmd=" qstat -u ".$user." | grep ".substr($qsname,0,4); } $continuewaiting=1; if ($continuewaiting) { system "sleep 40"; } # Now Wait for the jobs to complete while($continuewaiting) { system $waitcmd; $output = `$waitcmd`; if ( $output eq "" ) { $continuewaiting=0; print "Jobs all finished!\n"; } else { print " wait ";system "sleep 30"; } } closedir(DIR); ants-1.9.2+svn680.dfsg/Scripts/runprogramonimageset.pl000077500000000000000000000012541147325206600227210ustar00rootroot00000000000000#!/usr/bin/perl -w if ($#ARGV >= 0) { $who = join(' ', $ARGV[0]); } opendir(DIR, $who); @filelist = glob("$who"); # @filelist2 = glob("$who2"); $ct=0; $dir = `pwd`; $dir=substr($dir,0,length($dir)-1)."/"; $pathpre="/mnt/aibs1/avants/bin/ants/"; foreach $name (@filelist) { $exe = $pathpre."ANTS 3 -m PR[templatecontrol.nii,".$name.",1,2] -o ".$name." -t SyN[3] -r Gauss[2,0] -i 100x100x30 "; $exe2 = "/mnt/pkg/sge-root/bin/lx24-x86/qsub -q mac /mnt/data1/avants/Data/code/qsub3.sh ".$dir." ".$exe." "; print "$exe\n"; system $exe2; # USE qstat TO VERIFY THE JOB IS SUBMITTED $ct=$ct+1; } closedir(DIR); ants-1.9.2+svn680.dfsg/Scripts/shapeupdatetotemplate.sh000077500000000000000000000274331147325206600230610ustar00rootroot00000000000000#!/bin/bash function shapeupdatetotemplate { # local declaration of values dim=${DIM} template=${TEMPLATE} templatename=${TEMPLATENAME} outputname=${OUTPUTNAME} gradientstep=-${GRADIENTSTEP} # debug only # echo $dim # echo ${template} # echo ${templatename} # echo ${outputname} # echo ${outputname}*formed.nii* # echo ${gradientstep} # We find the average warp to the template and apply its inverse to the template image # This keeps the template shape stable over multiple iterations of template building echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 1" echo "--------------------------------------------------------------------------------------" ${ANTSPATH}AverageImages $dim ${template} 1 ${outputname}*formed.nii.gz echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 2" echo "--------------------------------------------------------------------------------------" if [ $dim -eq 2 ] then ${ANTSPATH}AverageImages $dim ${templatename}warpxvec.nii.gz 0 `ls ${outputname}*Warpxvec.nii.gz | grep -v "InverseWarpxvec"` ${ANTSPATH}AverageImages $dim ${templatename}warpyvec.nii.gz 0 `ls ${outputname}*Warpyvec.nii.gz | grep -v "InverseWarpyvec"` elif [ $dim -eq 3 ] then ${ANTSPATH}AverageImages $dim ${templatename}warpxvec.nii.gz 0 `ls ${outputname}*Warpxvec.nii.gz | grep -v "InverseWarpxvec"` ${ANTSPATH}AverageImages $dim ${templatename}warpyvec.nii.gz 0 `ls ${outputname}*Warpyvec.nii.gz | grep -v "InverseWarpyvec"` ${ANTSPATH}AverageImages $dim ${templatename}warpzvec.nii.gz 0 `ls ${outputname}*Warpzvec.nii.gz | grep -v "InverseWarpzvec"` fi echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 3" echo "--------------------------------------------------------------------------------------" if [ $dim -eq 2 ] then ${ANTSPATH}MultiplyImages $dim ${templatename}warpxvec.nii.gz ${gradientstep} ${templatename}warpxvec.nii.gz ${ANTSPATH}MultiplyImages $dim ${templatename}warpyvec.nii.gz ${gradientstep} ${templatename}warpyvec.nii.gz elif [ $dim -eq 3 ] then ${ANTSPATH}MultiplyImages $dim ${templatename}warpxvec.nii.gz ${gradientstep} ${templatename}warpxvec.nii.gz ${ANTSPATH}MultiplyImages $dim ${templatename}warpyvec.nii.gz ${gradientstep} ${templatename}warpyvec.nii.gz ${ANTSPATH}MultiplyImages $dim ${templatename}warpzvec.nii.gz ${gradientstep} ${templatename}warpzvec.nii.gz fi echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 4" echo "--------------------------------------------------------------------------------------" rm -f ${templatename}Affine.txt echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 5" echo "--------------------------------------------------------------------------------------" # Averaging and inversion code if [ ${dim} -eq 2 ] then ANTSAverage2DAffine ${templatename}Affine.txt ${outputname}*Affine.txt ${ANTSPATH}WarpImageMultiTransform ${dim} ${templatename}warpxvec.nii.gz ${templatename}warpxvec.nii.gz -i ${templatename}Affine.txt -R ${template} ${ANTSPATH}WarpImageMultiTransform ${dim} ${templatename}warpyvec.nii.gz ${templatename}warpyvec.nii.gz -i ${templatename}Affine.txt -R ${template} ${ANTSPATH}WarpImageMultiTransform ${dim} ${template} ${template} -i ${templatename}Affine.txt ${templatename}warp.nii.gz ${templatename}warp.nii.gz ${templatename}warp.nii.gz ${templatename}warp.nii.gz -R ${template} elif [ ${dim} -eq 3 ] then ANTSAverage3DAffine ${templatename}Affine.txt ${outputname}*Affine.txt ${ANTSPATH}WarpImageMultiTransform ${dim} ${templatename}warpxvec.nii.gz ${templatename}warpxvec.nii.gz -i ${templatename}Affine.txt -R ${template} ${ANTSPATH}WarpImageMultiTransform ${dim} ${templatename}warpyvec.nii.gz ${templatename}warpyvec.nii.gz -i ${templatename}Affine.txt -R ${template} ${ANTSPATH}WarpImageMultiTransform ${dim} ${templatename}warpzvec.nii.gz ${templatename}warpzvec.nii.gz -i ${templatename}Affine.txt -R ${template} ${ANTSPATH}WarpImageMultiTransform ${dim} ${template} ${template} -i ${templatename}Affine.txt ${templatename}warp.nii.gz ${templatename}warp.nii.gz ${templatename}warp.nii.gz ${templatename}warp.nii.gz -R ${template} fi echo echo "--------------------------------------------------------------------------------------" echo " shapeupdatetotemplate 6" echo "--------------------------------------------------------------------------------------" if [ ${dim} -eq 2 ] then ${ANTSPATH}MeasureMinMaxMean ${dim} ${templatename}warpxvec.nii.gz ${templatename}warpxlog.txt 1 ${ANTSPATH}MeasureMinMaxMean ${dim} ${templatename}warpyvec.nii.gz ${templatename}warpylog.txt 1 elif [ ${dim} -eq 3 ] then ${ANTSPATH}MeasureMinMaxMean ${dim} ${templatename}warpxvec.nii.gz ${templatename}warpxlog.txt 1 ${ANTSPATH}MeasureMinMaxMean ${dim} ${templatename}warpyvec.nii.gz ${templatename}warpylog.txt 1 ${ANTSPATH}MeasureMinMaxMean ${dim} ${templatename}warpzvec.nii.gz ${templatename}warpzlog.txt 1 fi } function ANTSAverage2DAffine { OUTNM=${templatename}Affine.txt FLIST=${outputname}*Affine.txt NFILES=0 PARAM1=0 PARAM2=0 PARAM3=0 PARAM4=0 PARAM5=0 PARAM6=0 PARAM7=0 PARAM8=0 LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM1=` awk -v a=$PARAM1 -v b=$x 'BEGIN{print (a + b)}' ` ; let NFILES=$NFILES+1 ; done PARAM1=` awk -v a=$PARAM1 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM2=` awk -v a=$PARAM2 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM2=` awk -v a=$PARAM2 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM3=` awk -v a=$PARAM3 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM3=` awk -v a=$PARAM3 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 5 ` for x in $LL ; do PARAM4=` awk -v a=$PARAM4 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM4=` awk -v a=$PARAM4 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 6 ` for x in $LL ; do PARAM5=` awk -v a=$PARAM5 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM5=0 # ` awk -v a=$PARAM5 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 7 ` for x in $LL ; do PARAM6=` awk -v a=$PARAM6 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM6=0 # ` awk -v a=$PARAM6 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM7=` awk -v a=$PARAM7 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM7=` awk -v a=$PARAM7 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM8=` awk -v a=$PARAM8 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM8=` awk -v a=$PARAM8 -v b=$NFILES 'BEGIN{print (a / b)}' ` echo "# Insight Transform File V1.0 " > $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_2_2 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 " >> $OUTNM echo "FixedParameters: $PARAM7 $PARAM8 " >> $OUTNM } function ANTSAverage3DAffine { OUTNM=${templatename}Affine.txt FLIST=${outputname}*Affine.txt NFILES=0 PARAM1=0 PARAM2=0 PARAM3=0 PARAM4=0 PARAM5=0 PARAM6=0 PARAM7=0 PARAM8=0 PARAM9=0 PARAM10=0 PARAM11=0 PARAM12=0 PARAM13=0 PARAM14=0 PARAM15=0 LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM1=` awk -v a=$PARAM1 -v b=$x 'BEGIN{print (a + b)}' ` ; let NFILES=$NFILES+1 ; done PARAM1=` awk -v a=$PARAM1 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM2=` awk -v a=$PARAM2 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM2=` awk -v a=$PARAM2 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM3=` awk -v a=$PARAM3 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM3=` awk -v a=$PARAM3 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 5 ` for x in $LL ; do PARAM4=` awk -v a=$PARAM4 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM4=` awk -v a=$PARAM4 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 6 ` for x in $LL ; do PARAM5=` awk -v a=$PARAM5 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM5=` awk -v a=$PARAM5 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 7 ` for x in $LL ; do PARAM6=` awk -v a=$PARAM6 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM6=` awk -v a=$PARAM6 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 8 ` for x in $LL ; do PARAM7=` awk -v a=$PARAM7 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM7=` awk -v a=$PARAM7 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 9 ` for x in $LL ; do PARAM8=` awk -v a=$PARAM8 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM8=` awk -v a=$PARAM8 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 10 ` for x in $LL ; do PARAM9=` awk -v a=$PARAM9 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM9=` awk -v a=$PARAM9 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 11 ` for x in $LL ; do PARAM10=` awk -v a=$PARAM10 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM10=0 # ` awk -v a=$PARAM10 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 12 ` for x in $LL ; do PARAM11=` awk -v a=$PARAM11 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM11=0 # ` awk -v a=$PARAM11 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` head -n 4 $FLIST | grep Paramet | cut -d ' ' -f 13 ` for x in $LL ; do PARAM12=` awk -v a=$PARAM12 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM12=0 # ` awk -v a=$PARAM12 -v b=$NFILES 'BEGIN{print (a / b)}' ` # origin params below LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 2 ` for x in $LL ; do PARAM13=` awk -v a=$PARAM13 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM13=` awk -v a=$PARAM13 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 3 ` for x in $LL ; do PARAM14=` awk -v a=$PARAM14 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM14=` awk -v a=$PARAM14 -v b=$NFILES 'BEGIN{print (a / b)}' ` LL=` cat $FLIST | grep FixedParamet | cut -d ' ' -f 4 ` for x in $LL ; do PARAM15=` awk -v a=$PARAM15 -v b=$x 'BEGIN{print (a + b)}' ` ; done PARAM15=` awk -v a=$PARAM15 -v b=$NFILES 'BEGIN{print (a / b)}' ` echo "# Insight Transform File V1.0 " > $OUTNM echo "# Transform 0 " >> $OUTNM echo "Transform: MatrixOffsetTransformBase_double_3_3 " >> $OUTNM echo "Parameters: $PARAM1 $PARAM2 $PARAM3 $PARAM4 $PARAM5 $PARAM6 $PARAM7 $PARAM8 $PARAM9 $PARAM10 $PARAM11 $PARAM12 " >> $OUTNM echo "FixedParameters: $PARAM13 $PARAM14 $PARAM15 " >> $OUTNM } DIM=3 TEMPLATE=t2template.nii.gz TEMPLATENAME=t2template OUTPUTNAME=t2 GRADIENTSTEP=0.1 shapeupdatetotemplate ${DIM} ${TEMPLATE} ${TEMPLATENAME} ${OUTPUTNAME} ${GRADIENTSTEP} ants-1.9.2+svn680.dfsg/Scripts/submitexperimentalbuild.sh000077500000000000000000000005211147325206600234050ustar00rootroot00000000000000#!/bin/sh # request Bourne shell as shell for job ctest -D ExperimentalStart ctest -D ExperimentalUpdate ctest -D ExperimentalConfigure ctest -D ExperimentalBuild ctest -D ExperimentalSubmit ctest -D ExperimentalTest #ctest -D ExperimentalCoverage ctest -D ExperimentalSubmit #ctest -D ExperimentalMemCheck #ctest -D ExperimentalSubmit ants-1.9.2+svn680.dfsg/Scripts/sygnccavg.sh000077500000000000000000000010141147325206600204260ustar00rootroot00000000000000#!/bin/sh TNAME=$1 GRADSTEP=$2 shift 2 FLIST2=$* ImageMath 2 $TNAME Normalize $TNAME for x in $(seq 1 5 ) ; do for y in $FLIST2 ; do ImageMath 2 turdx${y} Normalize $y ImageMath 2 turdx${y} CorrelationUpdate $TNAME turdx${y} 4 # MeasureImageSimilarity 2 1 $y $TNAME SmoothImage 2 turdx${y} 0.5 turdx${y} # MeasureMinMaxMean 2 turdx$y done AverageImages 2 turdu.nii.gz 0 turdx** MultiplyImages 2 turdu.nii.gz $GRADSTEP turdu.nii.gz ImageMath 2 $TNAME + $TNAME turdu.nii.gz done ants-1.9.2+svn680.dfsg/Scripts/thickstudy.sh000077500000000000000000000017471147325206600206520ustar00rootroot00000000000000#!/bin/sh count=0 for x in phantomA phantomB phantomC phantomD phantomE phantomF phantomG phantomH do count=`expr $count + 1` # Increment the counter echo " $x " echo " LaplacianThickness ${x}wm.hdr ${x}gm.hdr 15 TEST{$count}thick.hdr 1 0.5 " ThresholdImage 2 ${x}wmgm.jpg ${x}wm.nii 245 290 ThresholdImage 2 ${x}wmgm.jpg ${x}gm.nii 111 133 LaplacianThickness ${x}wm.nii ${x}gm.nii 15 TEST{$count}thick.hdr 5 3 WarpImageMultiTransform 2 TEST{$count}thick.hdr TEST{$count}thickreg.hdr TEST{$count}Warp.nii TEST{$count}Affine.txt # SmoothImage 2 TEST{$count}thickreg.hdr 1 TEST{$count}thickreg.hdr done StudentsTestOnImages 2 THICK2.hdr 4 4 ~/Code/bin/ants/GLM 2 mask.nii designmat.txt contrastvec.txt temp.hdr 1000 TEST{1}thickreg.hdr TEST{2}thickreg.hdr TEST{3}thickreg.hdr TEST{4}thickreg.hdr TEST{5}thickreg.hdr TEST{6}thickreg.hdr TEST{7}thickreg.hdr TEST{8}thickreg.hdr MultiplyImages 2 THICK2.hdr phantomtemplate.jpg THICK2.hdr ants-1.9.2+svn680.dfsg/Scripts/waitForSGEQJobs.pl000077500000000000000000000062731147325206600213700ustar00rootroot00000000000000#!/usr/bin/perl -w use strict; # Usage: waitForSGEQJobs.pl [job IDs] # # # Takes as args a string of qsub job IDs and periodically monitors them. Once they all finish, it returns 0 # # If any of the jobs go into error state, an error is printed to stderr and the program waits for the non-error # jobs to finish, then returns 1 # # Usual qstat format - check this at run time # job-ID prior name user state submit/start at queue slots ja-task-ID # First thing to do is parse our input my ($verbose, $delay, @jobIDs) = @ARGV; # Check for user stupidity if ($delay < 10) { print STDERR "Sleep period is too short, will poll queue once every 10 seconds\n"; $delay = 10; } elsif ($delay > 3600) { print STDERR "Sleep period is too long, will poll queue once every 60 minutes\n"; $delay = 3600; } print " Waiting for " . scalar(@jobIDs) . " jobs: @jobIDs\n"; my $user=`whoami`; my $qstatOutput = `qstat -u $user`; if (!scalar(@jobIDs) || !$qstatOutput) { # Nothing to do exit 0; } my @qstatLines = split("\n", $qstatOutput); my @header = split('\s+', trim($qstatLines[0])); # Position in qstat output of tokens we want my $jobID_Pos = -1; my $statePos = -1; foreach my $i (0..$#header) { if ($header[$i] eq "job-ID") { $jobID_Pos = $i; } elsif ($header[$i] eq "state") { $statePos = $i; } } # If we can't parse the job IDs, something is very wrong if ($jobID_Pos < 0 || $statePos < 0) { die "Cannot find job-ID and state field in qstat output, cannot monitor jobs\n"; } # Now check on all of our jobs my $jobsIncomplete = 1; # Set to 1 for any job in an error state my $haveErrors = 0; while ($jobsIncomplete) { # Jobs that are still showing up in qstat $jobsIncomplete = 0; foreach my $job (@jobIDs) { # iterate over all user jobs in the queue qstatLine: foreach my $line (@qstatLines) { # trim string for trailing white space so that the tokens are in the correct sequence # We are being paranoid by matching tokens to job-IDs this way. Less elegant than a # match but also less chance of a false-positive match my @tokens = split('\s+', trim($line)); if ( $tokens[$jobID_Pos] eq $job) { # Check status if ($tokens[$statePos] =~ m/E/) { $haveErrors = 1; } else { $jobsIncomplete = $jobsIncomplete + 1; } if ($verbose) { print " Job $job is in state $tokens[$statePos]\n"; } } last qstatLine if ( $tokens[$jobID_Pos] eq $job ); } } if ($jobsIncomplete) { if ($verbose) { my $timestamp = `date`; chomp $timestamp; print " ($timestamp) Still waiting for $jobsIncomplete jobs\n\n"; } # Use of backticks rather than system permits a ctrl+c to work `sleep $delay`; $qstatOutput = `qstat -u $user`; @qstatLines = split("\n", $qstatOutput); } } if ($haveErrors) { print " No more jobs to run - some jobs had errors\n\n"; exit 1; } else { print " No more jobs in queue\n\n"; exit 0; } sub trim { my ($string) = @_; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } ants-1.9.2+svn680.dfsg/Scripts/warpimages.pl000077500000000000000000000030131147325206600206030ustar00rootroot00000000000000#!/usr/bin/perl -w if ($#ARGV >= 0) { $who = join(' ', $ARGV[0]); } if ($#ARGV >= 1) { $template = join(' ', $ARGV[1]); } if ($#ARGV >= 2) { $dim = join(' ', $ARGV[2]); } else { $dim=0; } if ($#ARGV >= 3) { $outnaming = join(' ', $ARGV[3]); } else { $outnaming=""; } opendir(DIR, $who); @filelist = glob("$who"); # @filelist2 = glob("$who2"); $ct=0; print " EXPECTING IMAGE DIMENSION ".$dim." \n \n \n "; $dir = `pwd`; $dir=substr($dir,0,length($dir)-1)."/"; $pathpre="/mnt/aibs1/avants/bin/ants/"; $qsname="superfresh.sh"; foreach $name (@filelist) { $pre=$outnaming.$name; $pre=~s/\.[^.]*$//; print $pre." \n "; $prog=$pathpre."WarpImageMultiTransform ".$dim; $exe=$prog." ".$name." ".$pre."deformed.nii ".$pre."Warp.nii ".$pre."Affine.txt -R ".$template; $exe2 = "/mnt/pkg/sge-root/bin/lx24-x86/qsub -q mac ".$qsname." ".$dir." ".$exe." "; print $exe."\n"; system $exe2; # USE qstat TO VERIFY THE JOB IS SUBMITTED $ct=$ct+1; } $user=`whoami`; chomp($user); print " you are ".$user." = a jingle-jangle-jungle "; $atcfn=0; if ($atcfn) { $waitcmd="vq -s | grep ".$user; } else { $waitcmd=" qstat -u ".$user." | grep ".substr($qsname,0,4); } $continuewaiting=1; if ($continuewaiting) { system "sleep 40"; } while($continuewaiting) { system $waitcmd; $output = `$waitcmd`; if ( $output eq "" ) { $continuewaiting=0; print "Jobs all finished!\n"; } else { print " wait ";system "sleep 30"; } } closedir(DIR); ants-1.9.2+svn680.dfsg/Scripts/weightedaverage.pl000077500000000000000000000021421147325206600216010ustar00rootroot00000000000000#!/usr/bin/perl -w if ($#ARGV >= 0) { $who = join(' ', $ARGV[0]); } if ($#ARGV >= 1) { $imagedimension = join(' ', $ARGV[1]); } if ($#ARGV >= 2) { $outputname = join(' ', $ARGV[2]); } if ($#ARGV < 2) { print " usage: \n perl weightedaverage.pl *files.jpg imagedimension weight1 ... weightN \n "; exit(1); } opendir(DIR, $who); @filelist = glob("$who"); $basect=3; $ct=$basect; $dir = `pwd`; $dir=substr($dir,0,length($dir)-1)."/"; foreach $name (@filelist) { $weight=0; if ($#ARGV >= $ct) { $weight = join(' ', $ARGV[$ct]); } print " count ".$ct." & w= ".$weight." \n "; $tempname=" temp.nii "; $exe = " ImageMath ".$imagedimension." ".$tempname." m ".$name." ".$weight." \n "; system $exe; $exe = " ImageMath ".$imagedimension." ".$outputname." + ".$tempname." ".$outputname." \n "; if ($ct > $basect ) { system $exe; } else { $exe=" ImageMath ".$imagedimension." ".$outputname." m ".$name." ".$weight." \n "; print " YEE \n"; system $exe; } $ct=$ct+1; } closedir(DIR); ants-1.9.2+svn680.dfsg/Scripts/weightedaverage.sh000077500000000000000000000015651147325206600216100ustar00rootroot00000000000000#!/bin/sh echo "Usage: \n sh weightedaverage.sh \"Faces*tiff\" \n " count=9 for x in `ls -tr $1 ` do count=`expr $count + 1` # Increment the counter echo " count is $count and file is $x at it $i " ANTS 2 -m PR[template.nii,$x,1,8,-0.9] -t SyN[3] -r Gauss[3,1.5] -o ROBU{$count} -i 22x21x10 --MI-option 16x8000 #-a InitAffine.txt --continue-affine 0 WarpImageMultiTransform 2 $x ROBU{$count}{$i}registered.nii ROBU{$count}Warp.nii ROBU{$count}Affine.txt ComposeMultiTransform 2 ROBU{$count}Warp.nii -R template.nii ROBU{$count}Warp.nii ROBU{$count}Affine.txt ComposeMaps 2 ROBU{$count}Warp.nii ROBU{$count}Affine.txt ROBU{$count}Warp.nii 2 ConvertToJpg ROBU{$count}{$i}registered.nii ROBU{$count}{$i}registered.jpg MeasureImageSimilarity 2 2 template.nii ROBU{$count}{$i}registered.nii metriclog.txt done # end loop ants-1.9.2+svn680.dfsg/Temporary/000077500000000000000000000000001147325206600164425ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Temporary/itkAddConstantToImageFilter.h000066400000000000000000000105121147325206600241400ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAddConstantToImageFilter.h,v $ Language: C++ Date: $Date: 2009-02-24 19:03:14 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAddConstantToImageFilter_h #define __itkAddConstantToImageFilter_h #include "itkUnaryFunctorImageFilter.h" #include "itkNumericTraits.h" namespace itk { /** \class AddConstantToImageFilter * * \brief Add a constant to all input pixels. * * This filter is templated over the input image type * and the output image type. * * \author Tom Vercauteren, INRIA & Mauna Kea Technologies * * Based on filters from the Insight Journal paper: * http://hdl.handle.net/1926/510 * * \ingroup IntensityImageFilters Multithreaded * \sa UnaryFunctorImageFilter */ namespace Functor { template< class TInput, class TConstant, class TOutput> class AddConstantTo { public: AddConstantTo() : m_Constant(NumericTraits::One) {}; ~AddConstantTo() {}; bool operator!=( const AddConstantTo & other ) const { return !(*this == other); } bool operator==( const AddConstantTo & other ) const { return other.m_Constant == m_Constant; } inline TOutput operator()( const TInput & A ) const { // Because the user has to specify the constant we don't // check if the cte is not 0; return static_cast( A + m_Constant ); } void SetConstant(TConstant ct) {this->m_Constant = ct; } const TConstant & GetConstant() const { return m_Constant; } TConstant m_Constant; }; } template class ITK_EXPORT AddConstantToImageFilter : public UnaryFunctorImageFilter > { public: /** Standard class typedefs. */ typedef AddConstantToImageFilter Self; typedef UnaryFunctorImageFilter< TInputImage,TOutputImage, Functor::AddConstantTo< typename TInputImage::PixelType, TConstant, typename TOutputImage::PixelType> > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(AddConstantToImageFilter, UnaryFunctorImageFilter); /** Set the constant that will be used to multiply all the image * pixels */ void SetConstant(TConstant ct) { if( ct != this->GetFunctor().GetConstant() ) { this->GetFunctor().SetConstant(ct); this->Modified(); } } const TConstant & GetConstant() const { return this->GetFunctor().GetConstant(); } #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(InputConvertibleToOutputCheck, (Concept::Convertible)); itkConceptMacro(Input1Input2OutputAddOperatorCheck, (Concept::AdditiveOperators)); /** End concept checking */ #endif protected: AddConstantToImageFilter() {}; virtual ~AddConstantToImageFilter() {}; void PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Constant: " << static_cast::PrintType>(this->GetConstant()) << std::endl; } private: AddConstantToImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkAutumnColormapFunctor.h000066400000000000000000000045221147325206600236350ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAutumnColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.3 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAutumnColormapFunctor_h #define __itkAutumnColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class AutumnColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT AutumnColormapFunctor : public ColormapFunctor { public: typedef AutumnColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: AutumnColormapFunctor() {}; ~AutumnColormapFunctor() {}; private: AutumnColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkAutumnColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkAutumnColormapFunctor.txx000066400000000000000000000030641147325206600242310ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkAutumnColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkAutumnColormapFunctor_txx #define __itkAutumnColormapFunctor_txx #include "itkAutumnColormapFunctor.h" namespace itk { namespace Functor { template typename AutumnColormapFunctor::RGBPixelType AutumnColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = 1.0; RealType green = value; RealType blue = 0.0; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkBinaryContourImageFilter.h000066400000000000000000000155171147325206600242430ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBinaryContourImageFilter.h,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBinaryContourImageFilter_h #define __itkBinaryContourImageFilter_h #include "itkInPlaceImageFilter.h" #include "itkImage.h" #include "itkConceptChecking.h" #include #include #include "itkProgressReporter.h" #include "itkBarrier.h" namespace itk { /** * \class BinaryContourImageFilter * \brief Give the pixels on the border of an object. * * BinaryContourImageFilter labels the pixels on the borders * of the objects in a binary image. * * \sa ImageToImageFilter */ template class ITK_EXPORT BinaryContourImageFilter : public InPlaceImageFilter< TInputImage, TOutputImage > { public: /** * Standard "Self" & Superclass typedef. */ typedef BinaryContourImageFilter Self; typedef InPlaceImageFilter< TInputImage, TOutputImage > Superclass; /** * Types from the Superclass */ typedef typename Superclass::InputImagePointer InputImagePointer; /** * Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef typename TOutputImage::PixelType OutputPixelType; typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::InternalPixelType InputInternalPixelType; itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); /** * Image typedef support */ typedef TInputImage InputImageType; typedef typename TInputImage::IndexType IndexType; typedef typename TInputImage::SizeType SizeType; typedef typename TInputImage::OffsetType OffsetType; typedef typename TInputImage::PixelType InputImagePixelType; typedef TOutputImage OutputImageType; typedef typename TOutputImage::RegionType RegionType; typedef typename TOutputImage::IndexType OutputIndexType; typedef typename TOutputImage::SizeType OutputSizeType; typedef typename TOutputImage::OffsetType OutputOffsetType; typedef typename TOutputImage::PixelType OutputImagePixelType; typedef std::list ListType; /** * Smart pointer typedef support */ typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Run-time type information (and related methods) */ itkTypeMacro(BinaryContourImageFilter, ImageToImageFilter); /** * Method for creation through the object factory. */ itkNewMacro(Self); /** * Set/Get whether the connected components are defined strictly by * face connectivity or by face+edge+vertex connectivity. Default is * FullyConnectedOff. For objects that are 1 pixel wide, use * FullyConnectedOn. */ itkSetMacro(FullyConnected, bool); itkGetConstReferenceMacro(FullyConnected, bool); itkBooleanMacro(FullyConnected); // Concept checking -- input and output dimensions must be the same itkConceptMacro(SameDimension, (Concept::SameDimension)); /** */ itkSetMacro(BackgroundValue, OutputImagePixelType); itkGetMacro(BackgroundValue, OutputImagePixelType); /** */ itkSetMacro(ForegroundValue, InputImagePixelType); itkGetMacro(ForegroundValue, InputImagePixelType); protected: BinaryContourImageFilter() { m_FullyConnected = false; m_ForegroundValue = NumericTraits< InputImagePixelType >::max(); m_BackgroundValue = NumericTraits< OutputImagePixelType >::Zero; m_NumberOfThreads = 0; this->SetInPlace( false ); } virtual ~BinaryContourImageFilter() {} BinaryContourImageFilter(const Self&) {} void PrintSelf(std::ostream& os, Indent indent) const; /** * Standard pipeline methods. */ void BeforeThreadedGenerateData (); void AfterThreadedGenerateData (); void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId); /** BinaryContourImageFilter needs the entire input. Therefore * it must provide an implementation GenerateInputRequestedRegion(). * \sa ProcessObject::GenerateInputRequestedRegion(). */ void GenerateInputRequestedRegion(); /** BinaryContourImageFilter will produce all of the output. * Therefore it must provide an implementation of * EnlargeOutputRequestedRegion(). * \sa ProcessObject::EnlargeOutputRequestedRegion() */ void EnlargeOutputRequestedRegion(DataObject *itkNotUsed(output)); private: InputImagePixelType m_ForegroundValue; OutputImagePixelType m_BackgroundValue; bool m_FullyConnected; // some additional types typedef typename TOutputImage::RegionType::SizeType OutSizeType; // types to support the run length encoding of lines class runLength { public: // run length information - may be a more type safe way of doing this long int length; typename InputImageType::IndexType where; // Index of the start of the run }; typedef std::vector lineEncoding; // the map storing lines typedef std::vector LineMapType; typedef std::vector OffsetVec; // the types to support union-find operations typedef std::vector UnionFindType; bool CheckNeighbors(const OutputIndexType &A, const OutputIndexType &B); void CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour); void SetupLineOffsets(OffsetVec &LineOffsets); void Wait() { if( m_NumberOfThreads > 1 ) { m_Barrier->Wait(); } } typename Barrier::Pointer m_Barrier; LineMapType m_ForegroundLineMap; LineMapType m_BackgroundLineMap; long m_NumberOfThreads; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkBinaryContourImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkBinaryContourImageFilter.txx000066400000000000000000000361131147325206600246320ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBinaryContourImageFilter.txx,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBinaryContourImageFilter_txx #define __itkBinaryContourImageFilter_txx #include "itkBinaryContourImageFilter.h" #include "itkNumericTraits.h" // don't think we need the indexed version as we only compute the // index at the start of each run, but there isn't a choice #include "itkImageLinearConstIteratorWithIndex.h" #include "itkImageLinearIteratorWithIndex.h" #include "itkConstShapedNeighborhoodIterator.h" #include "itkImageRegionIterator.h" #include "itkMaskImageFilter.h" #include "itkConnectedComponentAlgorithm.h" namespace itk { template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // We need all the input. InputImagePointer input = const_cast(this->GetInput()); if( !input ) { return; } input->SetRequestedRegion( input->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::EnlargeOutputRequestedRegion(DataObject *) { this->GetOutput() ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::BeforeThreadedGenerateData() { typename TOutputImage::Pointer output = this->GetOutput(); typename TInputImage::ConstPointer input = this->GetInput(); long nbOfThreads = this->GetNumberOfThreads(); if( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() != 0 ) { nbOfThreads = vnl_math_min( this->GetNumberOfThreads(), itk::MultiThreader::GetGlobalMaximumNumberOfThreads() ); } // number of threads can be constrained by the region size, so call the SplitRequestedRegion // to get the real number of threads which will be used typename TOutputImage::RegionType splitRegion; // dummy region - just to call the following method nbOfThreads = this->SplitRequestedRegion(0, nbOfThreads, splitRegion); // std::cout << "nbOfThreads: " << nbOfThreads << std::endl; m_Barrier = Barrier::New(); m_Barrier->Initialize( nbOfThreads ); long pixelcount = output->GetRequestedRegion().GetNumberOfPixels(); long xsize = output->GetRequestedRegion().GetSize()[0]; long linecount = pixelcount/xsize; m_ForegroundLineMap.clear(); m_ForegroundLineMap.resize( linecount ); m_BackgroundLineMap.clear(); m_BackgroundLineMap.resize( linecount ); m_NumberOfThreads = nbOfThreads; } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::ThreadedGenerateData(const RegionType& outputRegionForThread, int threadId) { typename TOutputImage::Pointer output = this->GetOutput(); typename TInputImage::ConstPointer input = this->GetInput(); // create a line iterator typedef itk::ImageLinearConstIteratorWithIndex InputLineIteratorType; InputLineIteratorType inLineIt(input, outputRegionForThread); inLineIt.SetDirection(0); typedef itk::ImageLinearIteratorWithIndex OutputLineIteratorType; OutputLineIteratorType outLineIt(output, outputRegionForThread); outLineIt.SetDirection(0); // set the progress reporter to deal with the number of lines long pixelcountForThread = outputRegionForThread.GetNumberOfPixels(); long xsizeForThread = outputRegionForThread.GetSize()[0]; long linecountForThread = pixelcountForThread/xsizeForThread; ProgressReporter progress(this, threadId, linecountForThread * 2); // find the split axis IndexType outputRegionIdx = output->GetRequestedRegion().GetIndex(); IndexType outputRegionForThreadIdx = outputRegionForThread.GetIndex(); unsigned int splitAxis = 0; for( unsigned int i=0; iGetRequestedRegion().GetSize(); outputRegionSize[splitAxis] = outputRegionForThreadIdx[splitAxis] - outputRegionIdx[splitAxis]; long firstLineIdForThread = RegionType( outputRegionIdx, outputRegionSize ).GetNumberOfPixels() / xsizeForThread; long lineId = firstLineIdForThread; OffsetVec LineOffsets; SetupLineOffsets(LineOffsets); outLineIt.GoToBegin(); for( inLineIt.GoToBegin(); !inLineIt.IsAtEnd(); inLineIt.NextLine(), outLineIt.NextLine() ) { inLineIt.GoToBeginOfLine(); outLineIt.GoToBeginOfLine(); lineEncoding fgLine; lineEncoding bgLine; while (! inLineIt.IsAtEndOfLine()) { InputPixelType PVal = inLineIt.Get(); //std::cout << inLineIt.GetIndex() << std::endl; if (PVal == m_ForegroundValue) { // We've hit the start of a run runLength thisRun; long length=0; IndexType thisIndex; thisIndex = inLineIt.GetIndex(); //std::cout << thisIndex << std::endl; outLineIt.Set( m_BackgroundValue ); ++length; ++inLineIt; ++outLineIt; while( !inLineIt.IsAtEndOfLine() && inLineIt.Get() == m_ForegroundValue ) { outLineIt.Set( m_BackgroundValue ); ++length; ++inLineIt; ++outLineIt; } // create the run length object to go in the vector thisRun.length=length; thisRun.where = thisIndex; fgLine.push_back(thisRun); // std::cout << "fg " << thisIndex << " " << length << std::endl; } else { // We've hit the start of a run runLength thisRun; long length=0; IndexType thisIndex; thisIndex = inLineIt.GetIndex(); //std::cout << thisIndex << std::endl; outLineIt.Set( PVal ); ++length; ++inLineIt; ++outLineIt; while( !inLineIt.IsAtEndOfLine() && inLineIt.Get() != m_ForegroundValue ) { outLineIt.Set( inLineIt.Get() ); ++length; ++inLineIt; ++outLineIt; } // create the run length object to go in the vector thisRun.length=length; thisRun.where = thisIndex; bgLine.push_back(thisRun); // std::cout << "bg " << thisIndex << " " << length << std::endl; } } // std::cout << std::endl; m_ForegroundLineMap[lineId] = fgLine; m_BackgroundLineMap[lineId] = bgLine; lineId++; progress.CompletedPixel(); } // wait for the other threads to complete that part this->Wait(); // now process the map and make appropriate entries in an equivalence // table // assert( linecount == m_ForegroundLineMap.size() ); long pixelcount = output->GetRequestedRegion().GetNumberOfPixels(); long xsize = output->GetRequestedRegion().GetSize()[0]; long linecount = pixelcount/xsize; long lastLineIdForThread = linecount; if( threadId != m_NumberOfThreads - 1 ) { lastLineIdForThread = firstLineIdForThread + RegionType( outputRegionIdx, outputRegionForThread.GetSize() ).GetNumberOfPixels() / xsizeForThread; } for(long ThisIdx = firstLineIdForThread; ThisIdx < lastLineIdForThread; ++ThisIdx) { if( !m_ForegroundLineMap[ThisIdx].empty() ) { for (OffsetVec::const_iterator I = LineOffsets.begin(); I != LineOffsets.end(); ++I) { long NeighIdx = ThisIdx + (*I); // check if the neighbor is in the map if ( NeighIdx >= 0 && NeighIdx < linecount && !m_BackgroundLineMap[NeighIdx].empty() ) { // Now check whether they are really neighbors bool areNeighbors = CheckNeighbors(m_ForegroundLineMap[ThisIdx][0].where, m_BackgroundLineMap[NeighIdx][0].where); if (areNeighbors) { // Compare the two lines CompareLines(m_ForegroundLineMap[ThisIdx], m_BackgroundLineMap[NeighIdx]); } } } } progress.CompletedPixel(); } } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::AfterThreadedGenerateData() { m_Barrier = NULL; m_ForegroundLineMap.clear(); m_BackgroundLineMap.clear(); } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::SetupLineOffsets(OffsetVec &LineOffsets) { // Create a neighborhood so that we can generate a table of offsets // to "previous" line indexes // We are going to mis-use the neighborhood iterators to compute the // offset for us. All this messing around produces an array of // offsets that will be used to index the map typename TOutputImage::Pointer output = this->GetOutput(); typedef Image PretendImageType; typedef typename PretendImageType::RegionType::SizeType PretendSizeType; typedef typename PretendImageType::RegionType::IndexType PretendIndexType; typedef ConstShapedNeighborhoodIterator LineNeighborhoodType; typename PretendImageType::Pointer fakeImage; fakeImage = PretendImageType::New(); typename PretendImageType::RegionType LineRegion; //LineRegion = PretendImageType::RegionType::New(); OutSizeType OutSize = output->GetRequestedRegion().GetSize(); PretendSizeType PretendSize; // The first dimension has been collapsed for (unsigned int i = 0; iSetRegions( LineRegion ); PretendSizeType kernelRadius; kernelRadius.Fill(1); LineNeighborhoodType lnit(kernelRadius, fakeImage, LineRegion); setConnectivity( &lnit, m_FullyConnected ); typename LineNeighborhoodType::IndexListType ActiveIndexes; ActiveIndexes = lnit.GetActiveIndexList(); typename LineNeighborhoodType::IndexListType::const_iterator LI; PretendIndexType idx = LineRegion.GetIndex(); long offset = fakeImage->ComputeOffset( idx ); for (LI=ActiveIndexes.begin(); LI != ActiveIndexes.end(); LI++) { LineOffsets.push_back( fakeImage->ComputeOffset( idx + lnit.GetOffset( *LI ) ) - offset ); } LineOffsets.push_back( 0 ); // LineOffsets is the thing we wanted. } template< class TInputImage, class TOutputImage> bool BinaryContourImageFilter< TInputImage, TOutputImage> ::CheckNeighbors(const OutputIndexType &A, const OutputIndexType &B) { // this checks whether the line encodings are really neighbors. The // first dimension gets ignored because the encodings are along that // axis OutputOffsetType Off = A - B; for (unsigned i = 1; i < OutputImageDimension; i++) { if (abs(Off[i]) > 1) { return(false); } } return(true); } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour) { bool sameLine = true; OutputOffsetType Off = current[0].where - Neighbour[0].where; for (unsigned i = 1; i < OutputImageDimension; i++) { if (Off[i] != 0) { sameLine = false; } } long offset = 0; if (m_FullyConnected || sameLine) { offset = 1; } // std::cout << "offset: " << offset << std::endl; typename TOutputImage::Pointer output = this->GetOutput(); typename lineEncoding::const_iterator nIt, mIt; typename lineEncoding::iterator cIt; mIt = Neighbour.begin(); // out marker iterator for (cIt = current.begin();cIt != current.end();++cIt) { //runLength cL = *cIt; long cStart = cIt->where[0]; // the start x position long cLast = cStart + cIt->length - 1; bool lineCompleted = false; for (nIt=mIt; nIt != Neighbour.end() && !lineCompleted; ++nIt) { //runLength nL = *nIt; long nStart = nIt->where[0]; long nLast = nStart + nIt->length - 1; // there are a few ways that neighbouring lines might overlap // neighbor S------------------E // current S------------------------E //------------- // neighbor S------------------E // current S----------------E //------------- // neighbor S------------------E // current S------------------E //------------- // neighbor S------------------E // current S-------E //------------- long ss1 = nStart - offset; // long ss2 = nStart + offset; // long ee1 = nLast - offset; long ee2 = nLast + offset; bool eq = false; long oStart = 0; long oLast = 0; // the logic here can probably be improved a lot if ((ss1 >= cStart) && (ee2 <= cLast)) { // case 1 // std::cout << "case 1" << std::endl; eq = true; oStart = ss1; oLast = ee2; } else if ((ss1 <= cStart) && (ee2 >= cLast)) { // case 4 // std::cout << "case 4" << std::endl; eq = true; oStart = cStart; oLast = cLast; } else if ((ss1 <= cLast) && (ee2 >= cLast)) { // case 2 // std::cout << "case 2" << std::endl; eq = true; oStart = ss1; oLast = cLast; } else if ((ss1 <= cStart) && (ee2 >= cStart)) { // case 3 // std::cout << "case 3" << std::endl; eq = true; oStart = cStart; oLast = ee2; } if (eq) { // std::cout << oStart << " " << oLast << std::endl; assert( oStart <= oLast ); IndexType idx = cIt->where; for( int x=oStart; x<=oLast; x++ ) { // std::cout << idx << std::endl; idx[0] = x; output->SetPixel( idx, m_ForegroundValue ); } if( oStart == cStart && oLast == cLast ) { lineCompleted = true; } } } } } template< class TInputImage, class TOutputImage> void BinaryContourImageFilter< TInputImage, TOutputImage> ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "FullyConnected: " << m_FullyConnected << std::endl; os << indent << "ForegroundValue: " << static_cast::PrintType>(m_ForegroundValue) << std::endl; os << indent << "BackgroundValue: " << static_cast::PrintType>(m_BackgroundValue) << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkBlueColormapFunctor.h000066400000000000000000000045031147325206600232520ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBlueColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:08:09 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBlueColormapFunctor_h #define __itkBlueColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class BlueColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT BlueColormapFunctor : public ColormapFunctor { public: typedef BlueColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: BlueColormapFunctor() {}; ~BlueColormapFunctor() {}; private: BlueColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkBlueColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkBlueColormapFunctor.txx000066400000000000000000000026511147325206600236500ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBlueColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBlueColormapFunctor_txx #define __itkBlueColormapFunctor_txx #include "itkBlueColormapFunctor.h" namespace itk { namespace Functor { template typename BlueColormapFunctor::RGBPixelType BlueColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = 0; pixel[1] = 0; pixel[2] = this->RescaleRGBComponentValue( value ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkColormapFunctor.h000066400000000000000000000121051147325206600224370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-21 20:16:56 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkColormapFunctor_h #define __itkColormapFunctor_h #include "itkLightObject.h" #include "itkNumericTraits.h" #include "itkRGBPixel.h" namespace itk { namespace Functor { /** * \class ColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT ColormapFunctor : public Object { public: typedef ColormapFunctor Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(ColormapFunctor, Object); typedef TRGBPixel RGBPixelType; typedef typename TRGBPixel::ComponentType RGBComponentType; typedef TScalar ScalarType; typedef typename NumericTraits::RealType RealType; itkSetMacro( MinimumRGBComponentValue, RGBComponentType ); itkGetConstMacro( MinimumRGBComponentValue, RGBComponentType ); itkSetMacro( MaximumRGBComponentValue, RGBComponentType ); itkGetConstMacro( MaximumRGBComponentValue, RGBComponentType ); itkSetMacro( MinimumInputValue, ScalarType ); itkGetConstMacro( MinimumInputValue, ScalarType ); itkSetMacro( MaximumInputValue, ScalarType ); itkGetConstMacro( MaximumInputValue, ScalarType ); virtual bool operator!=( const ColormapFunctor & ) const { return false; } virtual bool operator==( const ColormapFunctor & other ) const { return !(*this != other); } virtual RGBPixelType operator()( const ScalarType & ) const = 0; protected: ColormapFunctor() { this->m_MinimumInputValue = NumericTraits::min(); this->m_MaximumInputValue = NumericTraits::max(); this->m_MinimumRGBComponentValue = NumericTraits::min(); this->m_MaximumRGBComponentValue = NumericTraits::max(); } ~ColormapFunctor() {}; /** * Map [min, max] input values to [0, 1]. */ RealType RescaleInputValue( ScalarType v ) const { RealType d = static_cast( this->m_MaximumInputValue - this->m_MinimumInputValue ); RealType value = ( static_cast( v ) - static_cast( this->m_MinimumInputValue ) ) / d; value = vnl_math_max( 0.0, value ); value = vnl_math_min( 1.0, value ); return value; } /** * Map [0, 1] value to [min, max] rgb component values. */ RGBComponentType RescaleRGBComponentValue( RealType v ) const { RealType d = static_cast( m_MaximumRGBComponentValue - m_MinimumRGBComponentValue ); const RGBComponentType rescaled = static_cast( d * v ) + this->m_MinimumRGBComponentValue; return rescaled; } void PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Minimum RGB Component Value: " << static_cast::PrintType>( this->GetMinimumRGBComponentValue()) << std::endl; os << indent << "Maximum RGB Component Value: " << static_cast::PrintType>( this->GetMaximumRGBComponentValue()) << std::endl; os << indent << "Minimum Input Value: " << static_cast::PrintType>( this->GetMinimumInputValue()) << std::endl; os << indent << "Maximum Input Value: " << static_cast::PrintType>( this->GetMaximumInputValue()) << std::endl; } private: ColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented ScalarType m_MinimumInputValue; ScalarType m_MaximumInputValue; RGBComponentType m_MinimumRGBComponentValue; RGBComponentType m_MaximumRGBComponentValue; }; } // end namespace functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkContourDirectedMeanDistanceImageFilter.h000066400000000000000000000146371147325206600270200ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkContourDirectedMeanDistanceImageFilter.h,v $ Language: C++ Date: $Date: 2009-04-25 12:27:20 $ Version: $Revision: 1.7 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkContourDirectedMeanDistanceImageFilter_h #define __itkContourDirectedMeanDistanceImageFilter_h #include "itkImageToImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" #include "itkImage.h" namespace itk { /** \class ContourDirectedMeanDistanceImageFilter * \brief Computes the directed Mean distance between the boundaries of * non-zero pixel regions of two images. * * ContourDirectedMeanDistanceImageFilter computes the distance between the set * non-zero pixels of two images using the following formula: * \f[ h(A,B) = \mathrm{mean}_{a \in A} \min_{b \in B} \| a - b\| \f] * where \f$A\f$ and \f$B\f$ are respectively the set of non-zero pixels * in the first and second input images. It identifies the point \f$ a \in A \f$ * that is farthest from any point of \f$B\f$ and measures the distance from \f$a\f$ * to the nearest neighbor in \f$B\f$. Note that this function is not * is not symmetric and hence is not a true distance. * * In particular, this filter uses the SignedDanielssonDistanceMapImageFilter inside * to compute distance map from all non-zero pixels in the second image. It * then computes the mean distance (in pixels) within the boundary pixels of * non-zero regions in the first image. * * Use MeanDistanceImageFilter to compute the full Mean distance. * * This filter requires the largest possible region of the first image and the * same corresponding region in the second image. It behaves as filter with * two input and one output. Thus it can be inserted in a pipeline with other * filters. The filter passes the first input through unmodified. * * This filter is templated over the two input image type. It assume * both image have the same number of dimensions. * * \sa SignedDanielssonDistanceMapImageFilter * \sa MeanDistanceImageFilter * * \ingroup MultiThreaded * * \author Teo Popa, ISIS Center, Georgetown University * */ template class ITK_EXPORT ContourDirectedMeanDistanceImageFilter : public ImageToImageFilter { public: /** Standard Self typedef */ typedef ContourDirectedMeanDistanceImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(ContourDirectedMeanDistanceImageFilter, ImageToImageFilter); /** Image related typedefs. */ typedef TInputImage1 InputImage1Type; typedef TInputImage2 InputImage2Type; typedef typename TInputImage1::Pointer InputImage1Pointer; typedef typename TInputImage2::Pointer InputImage2Pointer; typedef typename TInputImage1::ConstPointer InputImage1ConstPointer; typedef typename TInputImage2::ConstPointer InputImage2ConstPointer; typedef typename TInputImage1::RegionType RegionType; typedef typename TInputImage1::SizeType SizeType; typedef typename TInputImage1::IndexType IndexType; typedef typename TInputImage1::PixelType InputImage1PixelType; typedef typename TInputImage2::PixelType InputImage2PixelType; /** Image related typedefs. */ itkStaticConstMacro(ImageDimension, unsigned int, TInputImage1::ImageDimension); /** Type to use form computations. */ typedef typename NumericTraits::RealType RealType; /** Set the first input. */ void SetInput1( const InputImage1Type * image ) { this->SetInput( image ); } /** Set the second input. */ void SetInput2( const InputImage2Type * image ); /** Get the first input. */ const InputImage1Type * GetInput1(void) { return this->GetInput(); } /** Get the second input. */ const InputImage2Type * GetInput2(void); /** Return the computed directed Mean distance. */ itkGetConstMacro(ContourDirectedMeanDistance,RealType); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif protected: ContourDirectedMeanDistanceImageFilter(); ~ContourDirectedMeanDistanceImageFilter(){}; void PrintSelf(std::ostream& os, Indent indent) const; /** Pass the input through unmodified. Do this by Grafting in the AllocateOutputs method. */ void AllocateOutputs(); /** Initialize some accumulators before the threads run. */ void BeforeThreadedGenerateData (); /** Do final mean and variance computation from data accumulated in threads. */ void AfterThreadedGenerateData (); /** Multi-thread version GenerateData. */ void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId); // Override since the filter needs all the data for the algorithm void GenerateInputRequestedRegion(); // Override since the filter produces all of its output void EnlargeOutputRequestedRegion(DataObject *data); private: ContourDirectedMeanDistanceImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typedef Image DistanceMapType; typename DistanceMapType::Pointer m_DistanceMap; Array m_MeanDistance; Array m_Count; RealType m_ContourDirectedMeanDistance; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkContourDirectedMeanDistanceImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkContourDirectedMeanDistanceImageFilter.txx000066400000000000000000000171341147325206600274070ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkContourDirectedMeanDistanceImageFilter.txx,v $ Language: C++ Date: $Date: 2008-10-13 18:54:27 $ Version: $Revision: 1.9 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkContourDirectedMeanDistanceImageFilter_txx #define __itkContourDirectedMeanDistanceImageFilter_txx #include "itkContourDirectedMeanDistanceImageFilter.h" #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkNeighborhoodAlgorithm.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkOffset.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkNumericTraits.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkProgressReporter.h" namespace itk { template ContourDirectedMeanDistanceImageFilter ::ContourDirectedMeanDistanceImageFilter(): m_MeanDistance(1),m_Count(1) { // this filter requires two input images this->SetNumberOfRequiredInputs( 2 ); m_DistanceMap = NULL; m_ContourDirectedMeanDistance = NumericTraits::Zero; } template void ContourDirectedMeanDistanceImageFilter ::SetInput2( const TInputImage2 * image ) { this->SetNthInput(1, const_cast( image ) ); } template const typename ContourDirectedMeanDistanceImageFilter ::InputImage2Type * ContourDirectedMeanDistanceImageFilter ::GetInput2() { return static_cast< const TInputImage2 * > (this->ProcessObject::GetInput(1)); } template void ContourDirectedMeanDistanceImageFilter ::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); // this filter requires: // - the largeset possible region of the first image // - the corresponding region of the second image if ( this->GetInput1() ) { InputImage1Pointer image1 = const_cast< InputImage1Type * >( this->GetInput1() ); image1->SetRequestedRegionToLargestPossibleRegion(); if ( this->GetInput2() ) { InputImage2Pointer image2 = const_cast< InputImage2Type * >( this->GetInput2() ); image2->SetRequestedRegion( this->GetInput1()->GetRequestedRegion() ); } } } template void ContourDirectedMeanDistanceImageFilter ::EnlargeOutputRequestedRegion(DataObject *data) { Superclass::EnlargeOutputRequestedRegion(data); data->SetRequestedRegionToLargestPossibleRegion(); } template void ContourDirectedMeanDistanceImageFilter ::AllocateOutputs() { // Pass the first input through as the output InputImage1Pointer image = const_cast< TInputImage1 * >( this->GetInput1() ); this->GraftOutput( image ); } template void ContourDirectedMeanDistanceImageFilter ::BeforeThreadedGenerateData() { int numberOfThreads = this->GetNumberOfThreads(); // Resize the thread temporaries m_MeanDistance.SetSize(numberOfThreads); m_Count.SetSize(numberOfThreads); // Initialize the temporaries m_MeanDistance.Fill(NumericTraits::Zero); m_Count.Fill(0); // Compute SignedMaurer distance from non-zero pixels in the second image typedef SignedMaurerDistanceMapImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( this->GetInput2() ); filter->Update(); m_DistanceMap = filter->GetOutput(); } template void ContourDirectedMeanDistanceImageFilter ::AfterThreadedGenerateData() { int i; int numberOfThreads = this->GetNumberOfThreads(); // find mean over all threads int count = 0; RealType sum = NumericTraits::Zero; for( i = 0; i < numberOfThreads; i++) { sum += m_MeanDistance[i]; count += m_Count[i]; } if (count != 0) { m_ContourDirectedMeanDistance= sum/static_cast(count); } else { m_ContourDirectedMeanDistance = NumericTraits::Zero; } } template void ContourDirectedMeanDistanceImageFilter ::ThreadedGenerateData(const RegionType& outputRegionForThread, int threadId) { unsigned int i; ZeroFluxNeumannBoundaryCondition nbc; ConstNeighborhoodIterator bit; typename InputImage1Type::ConstPointer input = this->GetInput(); // Find the data-set boundary "faces" typedef typename InputImage1Type::SizeType InputSizeType; InputSizeType radius; radius.Fill(1); typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType faceList; NeighborhoodAlgorithm::ImageBoundaryFacesCalculator bC; faceList = bC(input, outputRegionForThread, radius); typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType::iterator fit; typedef typename InputImage1Type::PixelType InputPixelType; // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // Process each of the boundary faces. These are N-d regions which border // the edge of the buffer. for (fit=faceList.begin(); fit != faceList.end(); ++fit) { ImageRegionConstIterator it2 (m_DistanceMap, *fit); bit = ConstNeighborhoodIterator(radius, input, *fit); unsigned int neighborhoodSize = bit.Size(); bit.OverrideBoundaryCondition(&nbc); bit.GoToBegin(); bool bIsOnContour; while ( ! bit.IsAtEnd() ) { // first test // if current pixel is not on, let's continue if( bit.GetCenterPixel() != NumericTraits< InputPixelType >::Zero ) { bIsOnContour = false; for (i = 0; i < neighborhoodSize; ++i) { // second test if at least one neighbour pixel is off // the center pixel belongs to contour if( bit.GetPixel(i) == NumericTraits< InputPixelType >::Zero ) { bIsOnContour = true; break; } } // set pixel center pixel value whether it is or not on contour if( bIsOnContour ) { const RealType value = it2.Get(); m_MeanDistance[threadId] += vnl_math_abs( value ); m_Count[threadId]++; } } ++bit; ++it2; progress.CompletedPixel(); } } } template void ContourDirectedMeanDistanceImageFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "ContourDirectedMeanDistance: " << m_ContourDirectedMeanDistance << std::endl; } }// end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkCoolColormapFunctor.h000066400000000000000000000045071147325206600232630ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCoolColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:08:09 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCoolColormapFunctor_h #define __itkCoolColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class CoolColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT CoolColormapFunctor : public ColormapFunctor { public: typedef CoolColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: CoolColormapFunctor() {}; ~CoolColormapFunctor() {}; private: CoolColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkCoolColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkCoolColormapFunctor.txx000066400000000000000000000030601147325206600236500ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCoolColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCoolColormapFunctor_txx #define __itkCoolColormapFunctor_txx #include "itkCoolColormapFunctor.h" namespace itk { namespace Functor { template typename CoolColormapFunctor::RGBPixelType CoolColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = value; RealType green = 1.0 - value; RealType blue = 1.0; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkCopperColormapFunctor.h000066400000000000000000000045301147325206600236130ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCopperColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:08:09 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCopperColormapFunctor_h #define __itkCopperColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class CopperColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT CopperColormapFunctor : public ColormapFunctor { public: typedef CopperColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: CopperColormapFunctor() {}; ~CopperColormapFunctor() {}; private: CopperColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkCopperColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkCopperColormapFunctor.txx000066400000000000000000000032421147325206600242060ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCopperColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCopperColormapFunctor_txx #define __itkCopperColormapFunctor_txx #include "itkCopperColormapFunctor.h" namespace itk { namespace Functor { template typename CopperColormapFunctor::RGBPixelType CopperColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color map. RealType red = 1.2 * value; red = vnl_math_min( 1.0, red ); RealType green = 0.8 * value; RealType blue = 0.5 * value; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkCustomColormapFunctor.h000066400000000000000000000057401147325206600236410ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCustomColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCustomColormapFunctor_h #define __itkCustomColormapFunctor_h #include "itkColormapFunctor.h" #include namespace itk { namespace Functor { /** * \class CustomColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT CustomColormapFunctor : public ColormapFunctor { public: typedef CustomColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; typedef std::vector ChannelType; virtual RGBPixelType operator()( const TScalar & ) const; void SetRedChannel( ChannelType red ) { m_RedChannel = red; } ChannelType GetRedChannel() const { return m_RedChannel; } void SetGreenChannel( ChannelType green ) { m_GreenChannel = green; } ChannelType GetGreenChannel() const { return m_GreenChannel; } void SetBlueChannel( ChannelType blue ) { m_BlueChannel = blue; } ChannelType GetBlueChannel() const { return m_BlueChannel; } protected: CustomColormapFunctor() {}; ~CustomColormapFunctor() {}; private: CustomColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented ChannelType m_RedChannel; ChannelType m_GreenChannel; ChannelType m_BlueChannel; }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkCustomColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkCustomColormapFunctor.txx000066400000000000000000000062661147325206600242410ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCustomColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCustomColormapFunctor_txx #define __itkCustomColormapFunctor_txx #include "itkCustomColormapFunctor.h" namespace itk { namespace Functor { template typename CustomColormapFunctor::RGBPixelType CustomColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = 0.0; if ( this->m_RedChannel.size() == 1 || value == 0.0 ) { red = this->m_RedChannel[0]; } else if ( this->m_RedChannel.size() > 1 ) { RealType size = static_cast( this->m_RedChannel.size() ); RealType index = vcl_ceil( value * ( size - 1.0 ) ); RealType p1 = this->m_RedChannel[static_cast( index )]; RealType m1 = this->m_RedChannel[static_cast( index-1 )]; RealType d = p1 - m1; red = d * ( size - 1.0 ) * ( value - ( index - 1.0 )/( size - 1.0 ) ) + m1; } RealType green = 0.0; if ( this->m_GreenChannel.size() == 1 || value == 0.0 ) { green = this->m_GreenChannel[0]; } else if ( this->m_GreenChannel.size() > 1 ) { RealType size = static_cast( this->m_GreenChannel.size() ); RealType index = vcl_ceil( value * ( size - 1.0 ) ); RealType p1 = this->m_GreenChannel[static_cast( index )]; RealType m1 = this->m_GreenChannel[static_cast( index-1 )]; RealType d = p1 - m1; green = d * ( size - 1.0 ) * ( value - ( index - 1.0 )/( size - 1.0 ) ) + m1; } RealType blue = 0.0; if ( this->m_BlueChannel.size() == 1 || value == 0.0 ) { blue = this->m_BlueChannel[0]; } else if ( this->m_BlueChannel.size() > 1 ) { RealType size = static_cast( this->m_BlueChannel.size() ); RealType index = vcl_ceil( value * ( size - 1.0 ) ); RealType p1 = this->m_BlueChannel[static_cast( index )]; RealType m1 = this->m_BlueChannel[static_cast( index-1 )]; RealType d = p1 - m1; blue = d * ( size - 1.0 ) * ( value - ( index - 1.0 )/( size - 1.0 ) ) + m1; } // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkDensityFunction.h000066400000000000000000000043671147325206600224620ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkDensityFunction.h,v $ Language: C++ Date: $Date: 2009-03-04 15:23:46 $ Version: $Revision: 1.11 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDensityFunction_h #define __itkDensityFunction_h #include "itkMembershipFunctionBase.h" #include "itkMeasurementVectorTraits.h" namespace itk { namespace Statistics { /** \class DensityFunction * \brief DensityFunction class defines common interfaces for * density functions. * * The Evaluate method returns density value for the input measurement vector. * The length of the measurement vector must be set using * \c SetMeasurementVectorSize() before using the class. */ template< class TMeasurementVector > class ITK_EXPORT DensityFunction : public MembershipFunctionBase< TMeasurementVector > { public: /** Standard class typedefs */ typedef DensityFunction Self; typedef MembershipFunctionBase< TMeasurementVector > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Strandard macros */ itkTypeMacro(DensityFunction, MembershipFunctionBase); /** Length of each measurement vector */ typedef unsigned int MeasurementVectorSizeType; /** Method to get probability of an instance. The return value is the * value of the density function, not probability. */ virtual double Evaluate(const TMeasurementVector &measurement) const = 0; protected: DensityFunction() {} virtual ~DensityFunction() {} void PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); } private: }; // end of class } // end of namespace Statistics } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkDijkstrasAlgorithm.cxx000077500000000000000000000200071147325206600235050ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit (ITK) Module: $RCSfile: itkDijkstrasAlgorithm.cxx,v $ Language: C++ Date: $Date: 2008/06/05 18:39:14 $ Version: $Revision: 1.8 $ =========================================================================*/ #ifndef _itkDijkstrasAlgorithm_cxx_ #define _itkDijkstrasAlgorithm_cxx_ #include "itkDijkstrasAlgorithm.h" namespace itk { template DijkstrasAlgorithm::DijkstrasAlgorithm() { m_Graph = GraphType::New(); m_QS = DijkstrasAlgorithmQueue::New(); m_MaxCost=vnl_huge_val(m_MaxCost); // not defined for unsigned char this->m_TotalCost=0; }; template void DijkstrasAlgorithm::SetGraphSize(GraphSizeType Sz) { for (int i=0; i < GraphDimension; i++) { m_GraphSize[i]=Sz[i]; } } template void DijkstrasAlgorithm::InitializeGraph() { bool InBorder=false; m_GraphRegion.SetSize( m_GraphSize ); m_Graph->SetLargestPossibleRegion( m_GraphRegion ); m_Graph->SetRequestedRegion( m_GraphRegion ); m_Graph->SetBufferedRegion( m_GraphRegion ); m_Graph->Allocate(); GraphIteratorType GraphIterator( m_Graph, m_GraphRegion ); GraphIterator.GoToBegin(); NodeLocationType loc; while( !GraphIterator.IsAtEnd() ) { typename GraphSearchNode::Pointer G=NULL; GraphIterator.Set(G); ++GraphIterator; /* m_GraphIndex = GraphIterator.GetIndex(); //std::cout << " allocating " << m_GraphIndex << std::endl; ///GraphSearchNode::Pointer G= G=TGraphSearchNode::New(); G->SetUnVisited(); G->SetTotalCost(m_MaxCost); for (int i=0; iSetLocation(loc); G->SetPredecessor(NULL); m_Graph->SetPixel(m_GraphIndex,G);*/ m_Graph->SetPixel( GraphIterator.GetIndex(),NULL); // USE IF POINTER IMAGE defines visited } m_SearchFinished=false; } template void DijkstrasAlgorithm::InitializeQueue() { int n = m_QS->m_SourceNodes.size(); GraphIteratorType GraphIterator( m_Graph, m_GraphRegion ); m_GraphSize=m_Graph->GetLargestPossibleRegion().GetSize(); GraphIterator.GoToBegin(); m_GraphIndex = GraphIterator.GetIndex(); NodeLocationType loc; // make sure the graph contains the right pointers for (int i=0; i::Pointer G = m_QS->m_SourceNodes[i]; G->SetPredecessor(G); m_QS->m_Q.push(G); loc=G->GetLocation(); for (int d=0;dSetPixel(m_GraphIndex,G); } for (int i=0; im_SinkNodes.size(); i++) { typename GraphSearchNode::Pointer G = m_QS->m_SinkNodes[i]; G->SetPredecessor(NULL); loc=G->GetLocation(); for (int d=0;dSetPixel(m_GraphIndex,G); } m_SearchFinished=false; if (m_EdgeTemplate.empty()) InitializeEdgeTemplate(); } template void DijkstrasAlgorithm::InitializeEdgeTemplate (vector < unsigned int > UserEdgeTemplate,unsigned int R) { for (int i=0; i void DijkstrasAlgorithm::InitializeEdgeTemplate() { int MaxIndex=1; for (int i=0; i typename DijkstrasAlgorithm:: PixelType DijkstrasAlgorithm::LocalCost() { return 1.0; // manhattan distance }; template bool DijkstrasAlgorithm::TerminationCondition() { if (!m_QS->m_SinkNodes.empty()) { if (m_NeighborNode == m_QS->m_SinkNodes[0] && !m_SearchFinished ) { m_SearchFinished=true; m_NeighborNode->SetPredecessor(m_CurrentNode); } } else m_SearchFinished=true; return m_SearchFinished; } template void DijkstrasAlgorithm::SearchEdgeSet() { //std::cout << " SES 0 " << std::endl; int i=0,j=0; GraphNeighborhoodIteratorType GHood(m_Radius, m_Graph,m_Graph->GetRequestedRegion()); GraphNeighborhoodIndexType GNI; //std::cout << " SES 1 " << std::endl; for (i=0; i < GraphDimension; i++) { //std::cout << " SES 2 " << std::endl; GNI[i]=(long)(m_CurrentNode->GetLocation()[i]+0.5); } //std::cout << " SES 3 " << std::endl; GHood.SetLocation(GNI); bool inimage=true; for (unsigned int dd=0; dd (unsigned long)(m_GraphSize[dd]-2)) return; } for (i = 0; i < m_EdgeTemplate.size(); i++) { //std::cout << " SES 4 " << std::endl; //std::cout << " ET " << m_EdgeTemplate[i] << " RAD " << m_Radius << " ind " << GHood.GetIndex(m_EdgeTemplate[i]) << std::endl; if (!GHood.GetPixel(m_EdgeTemplate[i])) //std::cout << " OK " << std::endl; ///else { // std::cout << " NOT OK " <SetUnVisited(); G->SetTotalCost(m_MaxCost); NodeLocationType loc; for (int i=0; iSetLocation(loc); G->SetPredecessor(m_CurrentNode); m_Graph->SetPixel(ind,G); } m_NeighborNode=GHood.GetPixel(m_EdgeTemplate[i]); //std::cout << "DA i " << i << " position " << m_NeighborNode->GetLocation() << endl; this->TerminationCondition(); if (!m_SearchFinished && m_CurrentNode != m_NeighborNode && !m_NeighborNode->GetDelivered()) { m_NewCost = m_CurrentCost + LocalCost(); CheckNodeStatus(); } } } template void DijkstrasAlgorithm::CheckNodeStatus() // checks a graph neighbor's status { if (!m_NeighborNode->GetVisited() ) { // set the cost and put into the queue m_NeighborNode->SetTotalCost(m_NewCost); m_NeighborNode->SetPredecessor(m_CurrentNode); m_NeighborNode->SetVisited(); m_QS->m_Q.push(m_NeighborNode); } else if (m_NewCost < m_NeighborNode->GetTotalCost() ) { m_NeighborNode->SetTotalCost(m_NewCost); m_NeighborNode->SetPredecessor(m_CurrentNode); m_QS->m_Q.push(m_NeighborNode); } } template void DijkstrasAlgorithm::FindPath() { if (m_QS->m_SourceNodes.empty()) { std::cout << "ERROR !! DID NOT SET SOURCE!!\n"; return; } //std::cout << "DA start find path " << " Q size " << m_QS->m_Q.size() << " \n"; while ( !m_SearchFinished && !m_QS->m_Q.empty() ) { m_CurrentNode=m_QS->m_Q.top(); m_CurrentCost=m_CurrentNode->GetTotalCost(); m_QS->m_Q.pop(); if (!m_CurrentNode->GetDelivered()) { m_QS->IncrementTimer(); //std::cout << " searching " << m_CurrentNode->GetLocation() << " \n"; this->SearchEdgeSet(); this->m_TotalCost+=m_CurrentNode->GetTotalCost(); //if ( (m_CurrentNode->GetTimer() % 1.e5 ) == 0) // std::cout << " searched " << m_CurrentNode->GetTimer() << " \n"; } m_CurrentNode->SetDelivered(); } // end of while m_NumberSearched = (unsigned long) m_QS->GetTimer(); std::cout << "Done with find path " << " Q size " << m_QS->m_Q.size() << " num searched " << m_NumberSearched << " \n"; return; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkDijkstrasAlgorithm.h000077500000000000000000000435401147325206600231410ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit (ITK) Module: $RCSfile: itkDijkstrasAlgorithm.h,v $ Language: C++ Date: $Date: 2008/06/05 18:39:14 $ Version: $Revision: 1.8 $ Copyright (c) 2001 Insight Consortium All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the Insight Consortium, nor the names of any consortium members, nor of any contributors, may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _itkDijkstrasAlgorithm_h_ #define _itkDijkstrasAlgorithm_h_ #include #include #include #include #include #include #include #include "vnl/vnl_math.h" //#include "vnl/vnl_matrix_fixed.h" //#include "vnl/vnl_vector_fixed.h" #include "itkImage.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNeighborhoodIterator.h" #include "itkVector.h" using namespace std; namespace itk { /** The GraphSearchNode class defines a general shortest path graph node. * The algorithm requires * the node to have a pointer to itself and entry for the cumulative cost. * We also define an index to its location and a couple of booleans * for keeping track of the graph node's state. * We assume the connectivity between nodes is defined externally. * The class will also be useful for minimum spanning trees and * other graph search algorithms. Connectivity is defined externally. * May be worthwhile to implement arbitrary connectivity e.g. for random graphs. * One way to do this is to include a list of pointers which define * the neighbors of this node, similar to how the predecessor is defined. */ template class GraphSearchNode : public itk::LightObject { public: /* Standard typedefs.*/ typedef GraphSearchNode Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkTypeMacro(GraphSearchNode,LightObject); itkNewMacro(Self); /** Method for creation through the object factory. */ enum StateType {UnVisitedState, VisitedState, DeliveredState, UnVisitableState }; enum{GraphDimension=NGraphDimension}; typedef TPixelType PixelType; /** defines the cost data type */ typedef TCoordRep CoordRep; /** defines the location data type */ typedef itk::Vector NodeLocationType; // typedef typename itk::Image::IndexType NodeLocationType; typedef vector < Pointer > NodeListType; // typedef itk::Image::IndexType NodeLocationType; inline void SetLocation(NodeLocationType loc) { m_Location=loc; } inline NodeLocationType GetLocation() { return m_Location; } inline void SetTotalCost(TPixelType cost) { m_TotalCost=cost; } inline void SetValue(TPixelType cost,int which=0) { if (which <= 0) m_Value1=cost; if (which == 1) m_Value2=cost; if (which == 2) m_Value3=cost; if (which >= 3) m_Value4=cost; } inline TPixelType GetValue(int which=0) { if (which <= 0) return m_Value1; if (which == 1) return m_Value2; if (which == 2) return m_Value3; if (which >= 3) return m_Value4; return m_Value1; } inline void SetUnVisited() { m_State=UnVisitedState; } inline void SetUnVisitable() { m_State=UnVisitableState; } inline void SetVisited() { m_State=VisitedState; } inline void SetDelivered() { m_State=DeliveredState; } inline bool IsInQueue() { if ( m_State == VisitedState ) return true; else return false; } inline bool WasVisited() { if ( m_State == VisitedState ) return true; else if ( m_State == DeliveredState ) return true; else return false; } inline TPixelType GetTotalCost() { return m_TotalCost; } inline void SetPredecessor(Pointer address) { m_PredecessorAddress=address; } inline Pointer GetPredecessor() { return m_PredecessorAddress; } inline void SetAncestor(Pointer address) { m_AncestorAddress=address; } inline Pointer GetAncestor() { return m_AncestorAddress; } inline bool GetUnVisited() { if (m_State==UnVisitedState) return true; else return false; } inline bool GetUnVisitable() { if (m_State==UnVisitableState) return true; else return false; } inline bool GetVisited() { if (m_State==VisitedState) return true; else return false; } inline bool GetDelivered() { if (m_State==DeliveredState) return true; else return false; } inline void SetState(StateType S) { m_State=S; } inline StateType GetState() { return m_State; } inline void SetIdentity(unsigned int i) { m_Identity=i; } inline unsigned int GetIdentity() { return m_Identity; } inline int GetNumberOfNeighbors() { return m_Neighbors.size(); } inline Pointer GetNeighbor(int i) { return m_Neighbors[i]; } void SetNeighborSize(int i){m_Neighbors.resize(i);} NodeListType m_Neighbors; unsigned short m_NumberOfNeighbors; unsigned int m_Identity; protected: GraphSearchNode() { m_TotalCost=0.0; m_Value1=0.0; m_Value2=0.0; m_Value3=0.0; m_Value4=0.0; m_PredecessorAddress=NULL; m_AncestorAddress=NULL; m_State=UnVisitedState; m_NumberOfNeighbors=0; m_Identity=0; } ~GraphSearchNode(){} private: TPixelType m_TotalCost; /** keeps track of the minimum accumulated cost. */ TPixelType m_Value1; /** keeps track of the minimum accumulated cost. */ TPixelType m_Value2; /** keeps track of the minimum accumulated cost. */ TPixelType m_Value3; /** keeps track of the minimum accumulated cost. */ TPixelType m_Value4; /** keeps track of the minimum accumulated cost. */ StateType m_State; NodeLocationType m_Location; /** provides the location in the graph. */ Pointer m_PredecessorAddress;/** provides the best predecessor address */ Pointer m_AncestorAddress;/** provides the best predecessor address */ GraphSearchNode(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; // Forward declaration of DijkstrasAlgorithm so it can be declared a friend template class DijkstrasAlgorithm; template class DijkstrasAlgorithmQueue : public itk::LightObject /** \class DijkstrasAlgorithmQueue the class containing the priority queue and associated data. */ { private: template class GraphSearchNodePriority /* defines the comparison operator for the prioritiy queue */ { public: bool operator() ( typename G::Pointer N1, typename G::Pointer N2) { return N1->GetTotalCost() > N2->GetTotalCost(); } }; public: /* Standard typedefs.*/ typedef DijkstrasAlgorithmQueue Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkTypeMacro(DijkstrasAlgorithmQueue,LightObject); itkNewMacro(Self); /** Method for creation through the object factory. */ typedef typename TGraphSearchNode::Pointer TGraphSearchNodePointer; typedef typename TGraphSearchNode::PixelType PixelType; /** pixel type for the cost */ typedef typename TGraphSearchNode::CoordRep CoordRep; /** type for coordinates */ typedef typename std::priority_queue< typename TGraphSearchNode::Pointer,std::vector< typename TGraphSearchNode::Pointer>, GraphSearchNodePriority >QType; /** the queue we are using */ typedef vector < typename TGraphSearchNode::Pointer > NodeListType; inline QType GetQ() { return m_Q; } void AddToPath(TGraphSearchNodePointer G) { this->m_Path.push_back(G); } inline NodeListType GetPath() { return m_Path; } void EmptyPath() { m_Path.clear(); } inline NodeListType GetSourceNodes() { return m_SourceNodes; } inline NodeListType GetSinkNodes() { return m_SinkNodes; } inline void IncrementTimer() { m_timer++;} inline long GetTimer() { return m_timer; } inline void EmptyQ() { while (!m_Q.empty()) m_Q.pop(); m_timer=0; m_SourceNodes.clear(); m_SinkNodes.clear(); } NodeListType m_SinkNodes; NodeListType m_SourceNodes; QType m_Q; NodeListType m_Path; protected: friend class DijkstrasAlgorithm; // so it can access this data easily DijkstrasAlgorithmQueue() { m_timer=0; } ~DijkstrasAlgorithmQueue() {} private: unsigned long m_timer; DijkstrasAlgorithmQueue(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; /** * \class DijkstrasAlgorithm * \brief General shortest path / greedy dynamic programming solver. * * This class uses Dijkstra's algorithm to solve the shortest path problem. * We use the stl priority queue which is not optimal for this problem, but which * works o.k. It's implemented to be used for general regularly connected * graphs with fixed costs, or for the variational solution of an integral * curve matching energy. * Note: we assume all edge weights are positive. * The class is implemented as a an abstract base class, with virtual functions for * LocalCost, SearchEdgeSet and FindPath. LocalCost must be implemented by derived classes. * The connectivity of the graph defined * here is always regular and is controlled by a set of neighborhood indices. * the default is a radius 1 neighborhood with all entries used. However, the * user may also supply her own regular connectivity by selecting the size of * the neighborhood and a subset of the indices which define the edges. If * the GraphSearchNode contains its edges, they may be used with minor modification * to the function SearchEdgeSet. * Another improvement would be to make the LocalCost function a pointer * to a function which could be set. */ template class DijkstrasAlgorithm : public itk::LightObject { public: typedef DijkstrasAlgorithm Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkTypeMacro(DijkstrasAlgorithm,LightObject); itkNewMacro(Self); // Computation Data typedef TGraphSearchNode SearchNode; /** dimension of the graph */ typedef typename SearchNode::Pointer SearchNodePointer; enum{GraphDimension=SearchNode::GraphDimension}; /** dimension of the graph */ typedef typename SearchNode::PixelType PixelType; /** pixel type for the cost */ typedef typename SearchNode::CoordRep CoordRep; /** coordinate type */ typedef Image GraphType; typedef typename GraphType::SizeType GraphSizeType; typedef ImageRegionIteratorWithIndex GraphIteratorType; typedef typename GraphType::RegionType GraphRegionType; typedef typename DijkstrasAlgorithmQueue::Pointer QType; typedef typename DijkstrasAlgorithmQueue::NodeListType NodeListType; typedef itk::NeighborhoodIterator GraphNeighborhoodIteratorType; typedef typename GraphNeighborhoodIteratorType::IndexType GraphNeighborhoodIndexType; typedef typename GraphNeighborhoodIteratorType::RadiusType RadiusType; typedef typename TGraphSearchNode::NodeLocationType NodeLocationType; typedef typename GraphType::IndexType IndexType; // FUNCTIONS void InitializeGraph(); /** initializes all graph values appropriately */ void InitializeQueue(); /** initializes all queue values appropriately call AFTER source and sink are set*/ void InitializeEdgeTemplate(); /** helper function initializes edge set appropriately */ void InitializeEdgeTemplate(vector < unsigned int >,unsigned int); /** user supplied edge template */ void SetGraphSize(typename GraphType::SizeType Sz); /** the rectangular size of the graph */ inline void EmptyQ() { m_QS->EmptyQ(); this->m_TotalCost=0; } /* adds a source to the source set */ void SetSource(typename TGraphSearchNode::Pointer G) { m_QS->m_SourceNodes.push_back(G); for (int i=0; iGetLocation()[i]+0.5); // std::cout << " mgi " << m_GraphIndex[i]; } m_Graph->SetPixel(m_GraphIndex,G); }; typename TGraphSearchNode::Pointer GetGraphNode( IndexType index) { // std::cout << " get node " << index << std::endl; return m_Graph->GetPixel(index); }; // adds a sink to the sink set void SetSink(typename TGraphSearchNode::Pointer G) { m_QS->m_SinkNodes.push_back(G); } // Backtracks from the given node to its source node; void BackTrack(typename TGraphSearchNode::Pointer SinkNode) { m_QS->m_Path.clear(); typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetPredecessor(); if (!P || !G) return; float highcost=G->GetValue(); if (G->GetTotalCost() > P->GetValue()) { P->SetAncestor(G); P->SetValue(G->GetTotalCost()); highcost=G->GetTotalCost(); } while(P && G != P) { m_QS->m_Path.push_back(G); G=P; P=G->GetPredecessor(); if (P->GetValue() < highcost) { P->SetValue(highcost); P->SetAncestor(G); } } if (!P) cout << " null pred "; //else cout << " pred == self \n"; return; } // Inverse of backtrack - from the given node to its sink node; void ForwardTrack(typename TGraphSearchNode::Pointer SinkNode) { typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetAncestor(); while(P && G != P && G) { if (P->GetValue() > G->GetValue()) G->SetValue(P->GetValue()); if (G->GetValue() > P->GetValue()) P->SetValue(G->GetValue()); G=P; P=G->GetAncestor(); } return; } virtual bool TerminationCondition(); /** decides when the algorithm stops */ virtual void SearchEdgeSet(); /** loops over the neighbors in the graph */ void CheckNodeStatus(); /** checks if the node has been explored already, its cost, etc. */ virtual PixelType LocalCost(); /* computes the local cost */ /* alternatively, we could pass the function as a template parameter or set a function pointer. the latter method is used in dijkstrasegment. */ virtual void FindPath(); /* runs the algorithm */ inline unsigned int GetPathSize() { return m_QS->m_Path.size(); } inline typename TGraphSearchNode::Pointer GetPathAtIndex(unsigned int i) { return m_QS->m_Path[i]; } inline typename TGraphSearchNode::Pointer GetNeighborNode() { return m_NeighborNode; } inline typename TGraphSearchNode::Pointer GetCurrentNode() { return m_CurrentNode; } void SetMaxCost(PixelType m){ m_MaxCost=m;} double GetTotalCost() { return m_TotalCost; } void SetSearchFinished(bool m){ m_SearchFinished=m;} /** sets the boolean that indicates if the algorithm is done */ protected: QType m_QS; vector < unsigned int > m_EdgeTemplate;/** defines neighborhood connectivity */ RadiusType m_Radius; /** used by the neighborhood iterator */ typename TGraphSearchNode::Pointer m_PredecessorNode; /** holds the predecessor node */ typename TGraphSearchNode::Pointer m_CurrentNode; /** holds the current node */ typename TGraphSearchNode::Pointer m_NeighborNode; /** holds the current neighbor node */ typename GraphType::Pointer m_Graph; /** holds all the graph information */ GraphRegionType m_GraphRegion; GraphSizeType m_GraphSize; /** rectangular size of graph */ typename GraphType::IndexType m_GraphIndex; bool m_SearchFinished; PixelType m_NewCost; PixelType m_CurrentCost; PixelType m_MaxCost; // This creates an insurmountable barrier unless all costs are max double m_TotalCost; unsigned long m_NumberSearched; DijkstrasAlgorithm(); ~DijkstrasAlgorithm(){}; private: DijkstrasAlgorithm(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkDijkstrasAlgorithm.cxx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkDirectedHausdorffDistanceImageFilter.h000066400000000000000000000147251147325206600265050ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDirectedHausdorffDistanceImageFilter.h,v $ Language: C++ Date: $Date: 2009-04-25 12:27:21 $ Version: $Revision: 1.11 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDirectedHausdorffDistanceImageFilter_h #define __itkDirectedHausdorffDistanceImageFilter_h #include "itkImageToImageFilter.h" #include "itkNumericTraits.h" #include "itkArray.h" #include "itkImage.h" namespace itk { /** \class DirectedHausdorffDistanceImageFilter * \brief Computes the directed Hausdorff distance between the set of * non-zero pixels of two images. * * DirectedHausdorffDistanceImageFilter computes the distance between the set * non-zero pixels of two images using the following formula: * \f[ h(A,B) = \max_{a \in A} \min_{b \in B} \| a - b\| \f] * where \f$A\f$ and \f$B\f$ are respectively the set of non-zero pixels * in the first and second input images. It identifies the point \f$ a \in A \f$ * that is farthest from any point of \f$B\f$ and measures the distance from \f$a\f$ * to the nearest neighbor in \f$B\f$. Note that this function is not * is not symmetric and hence is not a true distance. * * In particular, this filter uses the DanielssonDistanceMapImageFilter inside to * compute distance map from all non-zero pixels in the second image. It then * find the largest distance (in pixels) within the set of all non-zero pixels in the first * image. * * Use HausdorffDistanceImageFilter to compute the full Hausdorff distance. * * This filter requires the largest possible region of the first image * and the same corresponding region in the second image. * It behaves as filter with * two input and one output. Thus it can be inserted in a pipeline with * other filters. The filter passes the first input through unmodified. * * This filter is templated over the two input image type. It assume * both image have the same number of dimensions. * * \sa DanielssonDistanceMapImageFilter * \sa HausdorffDistanceImageFilter * * \ingroup MultiThreaded */ template class ITK_EXPORT DirectedHausdorffDistanceImageFilter : public ImageToImageFilter { public: /** Standard Self typedef */ typedef DirectedHausdorffDistanceImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(DirectedHausdorffDistanceImageFilter, ImageToImageFilter); /** Image related typedefs. */ typedef TInputImage1 InputImage1Type; typedef TInputImage2 InputImage2Type; typedef typename TInputImage1::Pointer InputImage1Pointer; typedef typename TInputImage2::Pointer InputImage2Pointer; typedef typename TInputImage1::ConstPointer InputImage1ConstPointer; typedef typename TInputImage2::ConstPointer InputImage2ConstPointer; typedef typename TInputImage1::RegionType RegionType; typedef typename TInputImage1::SizeType SizeType; typedef typename TInputImage1::IndexType IndexType; typedef typename TInputImage1::PixelType InputImage1PixelType; typedef typename TInputImage2::PixelType InputImage2PixelType; /** Image related typedefs. */ itkStaticConstMacro(ImageDimension, unsigned int, TInputImage1::ImageDimension); /** Type to use form computations. */ typedef typename NumericTraits::RealType RealType; /** Set the first input. */ void SetInput1( const InputImage1Type * image ) { this->SetInput( image ); } /** Set the second input. */ void SetInput2( const InputImage2Type * image ); /** Get the first input. */ const InputImage1Type * GetInput1(void) { return this->GetInput(); } /** Get the second input. */ const InputImage2Type * GetInput2(void); /** Return the computed directed Hausdorff distance. */ itkGetConstMacro(DirectedHausdorffDistance,RealType); itkGetConstMacro(AverageHausdorffDistance,RealType); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif protected: DirectedHausdorffDistanceImageFilter(); ~DirectedHausdorffDistanceImageFilter(){}; void PrintSelf(std::ostream& os, Indent indent) const; /** Pass the input through unmodified. Do this by Grafting in the * AllocateOutputs method. */ void AllocateOutputs(); /** Initialize some accumulators before the threads run. */ void BeforeThreadedGenerateData (); /** Do final mean and variance computation from data accumulated in threads. */ void AfterThreadedGenerateData (); /** Multi-thread version GenerateData. */ void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId); // Override since the filter needs all the data for the algorithm void GenerateInputRequestedRegion(); // Override since the filter produces all of its output void EnlargeOutputRequestedRegion(DataObject *data); private: DirectedHausdorffDistanceImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typedef Image DistanceMapType; typename DistanceMapType::Pointer m_DistanceMap; Array m_MaxDistance; Array m_PixelCount; Array m_Sum; RealType m_DirectedHausdorffDistance; RealType m_AverageHausdorffDistance; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkDirectedHausdorffDistanceImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkDirectedHausdorffDistanceImageFilter.txx000066400000000000000000000143151147325206600270740ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDirectedHausdorffDistanceImageFilter.txx,v $ Language: C++ Date: $Date: 2008-10-14 19:20:33 $ Version: $Revision: 1.14 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDirectedHausdorffDistanceImageFilter_txx #define __itkDirectedHausdorffDistanceImageFilter_txx #include "itkDirectedHausdorffDistanceImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkNumericTraits.h" #include "itkSignedMaurerDistanceMapImageFilter.h" #include "itkProgressReporter.h" namespace itk { template DirectedHausdorffDistanceImageFilter ::DirectedHausdorffDistanceImageFilter(): m_MaxDistance(1) { // this filter requires two input images this->SetNumberOfRequiredInputs( 2 ); m_DistanceMap = NULL; m_DirectedHausdorffDistance = NumericTraits::Zero; m_AverageHausdorffDistance = NumericTraits::Zero; } template void DirectedHausdorffDistanceImageFilter ::SetInput2( const TInputImage2 * image ) { this->SetNthInput(1, const_cast( image ) ); } template const typename DirectedHausdorffDistanceImageFilter ::InputImage2Type * DirectedHausdorffDistanceImageFilter ::GetInput2() { return static_cast< const TInputImage2 * > (this->ProcessObject::GetInput(1)); } template void DirectedHausdorffDistanceImageFilter ::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); // this filter requires: // - the largeset possible region of the first image // - the corresponding region of the second image if ( this->GetInput1() ) { InputImage1Pointer image1 = const_cast< InputImage1Type * >( this->GetInput1() ); image1->SetRequestedRegionToLargestPossibleRegion(); if ( this->GetInput2() ) { InputImage2Pointer image2 = const_cast< InputImage2Type * >( this->GetInput2() ); image2->SetRequestedRegion( this->GetInput1()->GetRequestedRegion() ); } } } template void DirectedHausdorffDistanceImageFilter ::EnlargeOutputRequestedRegion(DataObject *data) { Superclass::EnlargeOutputRequestedRegion(data); data->SetRequestedRegionToLargestPossibleRegion(); } template void DirectedHausdorffDistanceImageFilter ::AllocateOutputs() { // Pass the first input through as the output InputImage1Pointer image = const_cast< TInputImage1 * >( this->GetInput1() ); this->GraftOutput( image ); } template void DirectedHausdorffDistanceImageFilter ::BeforeThreadedGenerateData() { int numberOfThreads = this->GetNumberOfThreads(); // Resize the thread temporaries m_MaxDistance.SetSize(numberOfThreads); m_PixelCount.SetSize(numberOfThreads); m_Sum.SetSize(numberOfThreads); // Initialize the temporaries m_MaxDistance.Fill(NumericTraits::Zero); m_PixelCount.Fill(0); m_Sum.Fill(NumericTraits::Zero); // Compute distance map from non-zero pixels in the second image typedef itk::SignedMaurerDistanceMapImageFilter FilterType; typename FilterType::Pointer filter = FilterType::New(); filter->SetInput( this->GetInput2() ); filter->SetUseImageSpacing( false ); filter->Update(); m_DistanceMap = filter->GetOutput(); } template void DirectedHausdorffDistanceImageFilter ::AfterThreadedGenerateData() { int i; int numberOfThreads = this->GetNumberOfThreads(); m_DirectedHausdorffDistance = NumericTraits::Zero; RealType sum = NumericTraits::Zero; unsigned int pixelcount = 0; // find max over all threads for( i = 0; i < numberOfThreads; i++) { if ( m_MaxDistance[i] > m_DirectedHausdorffDistance ) { m_DirectedHausdorffDistance = m_MaxDistance[i]; } pixelcount += m_PixelCount[i]; sum += m_Sum[i]; } m_AverageHausdorffDistance = sum / (RealType) pixelcount; // clean up m_DistanceMap = NULL; } template void DirectedHausdorffDistanceImageFilter ::ThreadedGenerateData(const RegionType& regionForThread, int threadId) { ImageRegionConstIterator it1 (this->GetInput1(), regionForThread); ImageRegionConstIterator it2 (m_DistanceMap, regionForThread); // support progress methods/callbacks ProgressReporter progress(this, threadId, regionForThread.GetNumberOfPixels()); // do the work while (!it1.IsAtEnd()) { if( it1.Get() != NumericTraits::Zero ) { if ( it2.Get() > m_MaxDistance[threadId] ) { m_MaxDistance[threadId] = it2.Get(); } m_PixelCount[threadId]++; m_Sum[threadId] += it2.Get(); } ++it1; ++it2; progress.CompletedPixel(); } } template void DirectedHausdorffDistanceImageFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "DirectedHausdorffDistance: " << m_DirectedHausdorffDistance << std::endl; os << indent << "AverageHausdorffDistance: " << m_AverageHausdorffDistance << std::endl; } }// end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkDivideByConstantImageFilter.h000066400000000000000000000113411147325206600246450ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDivideByConstantImageFilter.h,v $ Language: C++ Date: $Date: 2009-02-24 19:03:15 $ Version: $Revision: 1.4 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDivideByConstantImageFilter_h #define __itkDivideByConstantImageFilter_h #include "itkUnaryFunctorImageFilter.h" #include "itkNumericTraits.h" namespace itk { /** \class DivideByConstantImageFilter * * \brief Divide input pixels by a constant. * * This filter is templated over the input image type * and the output image type. * * \author Tom Vercauteren, INRIA & Mauna Kea Technologies * * This implementation was taken from the Insight Journal paper: * http://hdl.handle.net/1926/510 * * \ingroup IntensityImageFilters Multithreaded * \sa UnaryFunctorImageFilter */ namespace Functor { template< class TInput, class TConstant, class TOutput> class DivideByConstant { public: DivideByConstant() : m_Constant(NumericTraits::One) {}; ~DivideByConstant() {}; bool operator!=( const DivideByConstant & other ) const { return !(*this == other); } bool operator==( const DivideByConstant & other ) const { return other.m_Constant == m_Constant; } inline TOutput operator()( const TInput & A ) const { // Because the user has to specify the constant we don't // check if the constant is not too small (i.e. almost equal to zero); return static_cast( A / m_Constant ); } void SetConstant(TConstant ct) { if( ct == NumericTraits::Zero ) { itkGenericExceptionMacro( <<"The constant value used as denominator should not be set to zero"); } this->m_Constant = ct; } const TConstant & GetConstant() const { return m_Constant; } TConstant m_Constant; }; } template class ITK_EXPORT DivideByConstantImageFilter : public UnaryFunctorImageFilter > { public: /** Standard class typedefs. */ typedef DivideByConstantImageFilter Self; typedef UnaryFunctorImageFilter< TInputImage,TOutputImage, Functor::DivideByConstant< typename TInputImage::PixelType, TConstant, typename TOutputImage::PixelType> > Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(DivideByConstantImageFilter, UnaryFunctorImageFilter); /** Set the constant value that will be used for dividing all the image * pixels */ void SetConstant(TConstant ct) { if( ct != this->GetFunctor().GetConstant() ) { this->GetFunctor().SetConstant(ct); this->Modified(); } } const TConstant & GetConstant() const { return this->GetFunctor().GetConstant(); } #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(InputConvertibleToOutputCheck, (Concept::Convertible)); // The following concept check doesn't seem to work with vector immages //itkConceptMacro(Input1Input2OutputDivisionOperatorsCheck, // (Concept::DivisionOperators)); /** End concept checking */ #endif protected: DivideByConstantImageFilter() {}; virtual ~DivideByConstantImageFilter() {}; void PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Constant: " << static_cast::PrintType>(this->GetConstant()) << std::endl; } private: DivideByConstantImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkFEMConformalMap.cxx000066400000000000000000001053701147325206600226120ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMConformalMap.cxx,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for detailm_Solver. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _FEMConformalMap_txx #define _FEMConformalMap_txx #include "vtkFeatureEdges.h" #include "vtkPointLocator.h" #include "vtkCellLocator.h" #include "vtkTriangleFilter.h" #include "vtkCleanPolyData.h" #include "vtkPolyDataConnectivityFilter.h" #include #include #include #include #include #include #include "itkFEMConformalMap.h" #include "itkFEMLoadNode.h" namespace itk { vtkPolyData* vtkGenSmoothMesh(vtkPolyData* vds) { float fai=45; vtkSmoothPolyDataFilter *polySmoother = vtkSmoothPolyDataFilter::New(); // polySmoother->SetInput(decimator->GetOutput()); polySmoother->SetInput(vds); polySmoother->SetNumberOfIterations(100); polySmoother->SetRelaxationFactor(0.01); polySmoother->SetFeatureAngle(fai); polySmoother->FeatureEdgeSmoothingOff(); polySmoother->BoundarySmoothingOff(); polySmoother->Update(); return polySmoother->GetOutput(); } template FEMConformalMap ::FEMConformalMap() { m_Sigma=2.0e-4; m_ParameterFileName = ""; m_NorthPole=0; m_SouthPole=1; m_VtkSurfaceMesh=NULL; m_Pi= 3.14159265358979323846; m_ReadFromFile=true; m_Debug=false; m_FindingRealSolution=true; m_SurfaceMesh=NULL; m_Image=NULL; m_SphereImage=NULL; for (int i=0; i<7; i++) m_PoleElementsGN[i]=0; } template bool FEMConformalMap ::GenerateSystemFromVtkSurfaceMesh() { if (!m_VtkSurfaceMesh) { std::cout << " NO MESH"; return false;} std::cout << " Generate system from surface mesh " << std::endl; vtkTriangleFilter* fltTriangle = vtkTriangleFilter::New(); fltTriangle->SetInput(m_VtkSurfaceMesh); cout << " converting mesh to triangles " << endl; fltTriangle->Update(); // Clean the data vtkCleanPolyData* fltCleaner = vtkCleanPolyData::New(); fltCleaner->SetInput(fltTriangle->GetOutput()); fltCleaner->SetTolerance(0); fltCleaner->ConvertPolysToLinesOn(); cout << " cleaning up triangle mesh " << endl; fltCleaner->Update(); // Go through and delete the cells that are of the wrong type vtkPolyData* clean= fltCleaner->GetOutput(); for(vtkIdType i = clean->GetNumberOfCells();i > 0;i--) { if(clean->GetCellType(i-1) != VTK_TRIANGLE) clean->DeleteCell(i-1); } clean->BuildCells(); m_VtkSurfaceMesh=clean; // create a material // Choose the material properties typename MaterialType::Pointer m; m=MaterialType::New(); m->GN=0; // Global number of the material /// m->E=m_Sigma; // Young modulus -- used in the membrane /// m->A=0.0; // Crossection area /// m->h=0.0; // Crossection area /// m->I=0.0; // Moment of inertia /// m->nu=0.; //.0; // poissons -- DONT CHOOSE 1.0!!/// m->RhoC=0.0; // Create the element type ElementType::Pointer e1=ElementType::New(); e1->m_mat=dynamic_cast( m ); vtkPoints* vtkpoints = m_VtkSurfaceMesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); int foundnum=0; int boundsz=0; for(int i =0; i < numPoints; i++) { double* pt = vtkpoints->GetPoint(i); typename NodeType::Pointer n; n=new NodeType(pt[0],pt[1],pt[2]); n->GN=i; m_Solver.node.push_back(itk::fem::FEMP(n)); foundnum++; } std::cout << " foundnum " << foundnum << std::endl; typename NodeType::Pointer* narr = new NodeType::Pointer[numPoints]; for(int i =0; i < numPoints; i++) { narr[i]=m_Solver.node.Find( i ); } vtkCellArray* vtkcells = m_VtkSurfaceMesh->GetPolys(); vtkIdType npts; vtkIdType* pts; unsigned long i = 0; unsigned long toti = vtkcells->GetNumberOfCells(); unsigned long rate = toti/50; // std::cout << " progress "; std::cout << " DONE: NUMBER OF CELLS start " << toti << std::endl; for(vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); ) { bool eltok=true; ElementType::Pointer e; e=dynamic_cast(e1->Clone()); e->SetNode(2,narr[pts[0]]); e->SetNode(1,narr[pts[1]]); e->SetNode(0,narr[pts[2]]); e->GN=i; m_Solver.el.push_back(itk::fem::FEMP(e)); i++; } std::cout << " DONE: NUMBER OF CELLS " << i << std::endl; return true; } template bool FEMConformalMap ::GenerateSystemFromSurfaceMesh() { if (!m_SurfaceMesh) return false; // create a material // Choose the material properties typename MaterialType::Pointer m; m=MaterialType::New(); m->GN=0; // Global number of the material /// m->E=m_Sigma; // Young modulus -- used in the membrane /// m->A=0.0; // Crossection area /// m->h=0.0; // Crossection area /// m->I=0.0; // Moment of inertia /// m->nu=0.; //.0; // poissons -- DONT CHOOSE 1.0!!/// m->RhoC=0.0; // 3.e-4 prolly good // std::cout << " input E "; std::cin >> m->E; // Create the element type ElementType::Pointer e1=ElementType::New(); e1->m_mat=dynamic_cast( m ); PointType* pt_ptr; PointType pt; pt_ptr = &pt; for(int i=0; iGetNumberOfPoints(); i++) { m_SurfaceMesh->GetPoint(i, pt_ptr); if (m_Debug) std::cout << "Point: " << i << " coords " << pt[0] << ", " << pt[1] << ", "<< pt[2] << std::endl; // turn the point into a node { // Create nodes typename NodeType::Pointer n; n=new NodeType(pt[0],pt[1],pt[2]); n->GN=i; m_Solver.node.push_back(itk::fem::FEMP(n)); } } InputCellsContainerPointer cellList = m_SurfaceMesh->GetCells(); InputCellsContainerIterator cells = cellList->Begin(); for(int i=0; iGetNumberOfCells(); i++) { const unsigned long *tp; typename SurfaceType::CellType * cellPtr = cells.Value(); tp = cellPtr->GetPointIds(); if (m_Debug) std::cout << " pt 1 id " << tp[0] << " pt 2 id " << tp[1] <<" pt 3 id " << tp[2] << std::endl; cells++; // turn the cell into an element { // Create elements ElementType::Pointer e; e=dynamic_cast(e1->Clone()); e->SetNode(0,m_Solver.node.Find( tp[0] )); e->SetNode(1,m_Solver.node.Find( tp[1] )); e->SetNode(2,m_Solver.node.Find( tp[2] )); e->GN=i; m_Solver.el.push_back(itk::fem::FEMP(e)); } } return true; } template void FEMConformalMap ::MapImageToSphere(TImage* img, float rad ) { typename ImageType::SizeType imageSize=img->GetLargestPossibleRegion().GetSize(); vnl_vector Pos; // solution at the point vnl_vector Sol; // solution at the local point vnl_vector Gpt; // global position given by local point Sol.set_size(ImageDimension); Gpt.set_size(ImageDimension); Pos.set_size(ImageDimension); VectorType disp; disp.set_size(3); disp.fill(0.0); float solval,posval; float WIDTH = rad*2.1; float HEIGHT = rad*2.1; float DEPTH = rad*2.1; float frad=(float)rad; int i, j, k; typename ImageType::SizeType size; size[0] = WIDTH; size[1] = HEIGHT; size[2] = DEPTH; typename ImageType::IndexType start; start.Fill(0); typename ImageType::RegionType region; region.SetSize( size ); region.SetIndex( start ); m_SphereImage = ImageType::New(); m_SphereImage->SetRegions( region ); m_SphereImage->Allocate(); int center=(int)WIDTH/2; typename ImageType::PixelType backgroundValue=0; itk::ImageRegionIteratorWithIndex it( m_SphereImage, region ); it.GoToBegin(); typename ImageType::IndexType rindex = it.GetIndex(); typename ImageType::IndexType sindex = it.GetIndex(); while( !it.IsAtEnd() ) { rindex=it.GetIndex(); float dist=0; for (int ii=0; ii < ImageDimension; ii++) dist+=(float)(rindex[ii]-center)*(float)(rindex[ii]-center); dist = sqrt(dist); if ( dist > rad) it.Set( backgroundValue ); else it.Set( 1 ); ++it; } PointType* pt_ptr; PointType pt; pt_ptr = &pt; bool inimage; for( itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); elt!=m_Solver.el.end(); elt++) { unsigned int Nnodes= (*elt)->GetNumberOfNodes(); inimage=true; for (unsigned int nd=0; nd< Nnodes; nd++) { for(unsigned int f=0; fGetNumberOfDegreesOfFreedomPerNode() == 3) { Sol[f]= m_Solver.GetLinearSystemWrapper()->GetSolutionValue( (*elt)->GetNode(nd)->GetDegreeOfFreedom(f) , 0); x=(*elt)->GetNode(nd)->GetCoordinates()[f]; } else { Sol[f]= (*elt)->GetNode(nd)->GetCoordinates()(f); m_SurfaceMesh->GetPoint((*elt)->GetNode(nd)->GN, pt_ptr); x=pt[f]; } // get img index long int temp; if (x !=0) temp=(long int) ((x)+0.5); else temp=0;// round rindex[f]=temp; // get sphr index disp[f] =(float) ((float)center)+rad*Sol[f]; x=disp[f]; if (x !=0) temp=(long int) ((x)+0.5); else temp=0;// round sindex[f]=temp; } if (inimage ) m_SphereImage->SetPixel(sindex, img->GetPixel(rindex) + 1.0);//*100. +110.0); } } // end of elt array loop } template void FEMConformalMap ::MapCheckerboardToImage( float increment ) { typedef float Float; if (increment < 0) increment=0; if (increment > 1) increment=1; float phiinc=m_Pi*increment; float thetainc=m_Pi*increment; vnl_vector Sol; // solution at the local point typename ImageType::SpacingType spacing=m_Image->GetSpacing(); typename ImageType::SizeType imageSize=m_Image->GetLargestPossibleRegion().GetSize(); std::cout << " size " << imageSize << std::endl; VectorType disp; disp.set_size(3); disp.fill(0.0); // Float solval,posval; bool inimage; float phi; float theta; float s; float t; float gridval; ImageRegionIteratorWithIndex wimIter( m_Image, m_Image->GetLargestPossibleRegion() ); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) wimIter.Set(0.0); typename ImageType::IndexType rindex = wimIter.GetIndex(); Sol.set_size(ImageDimension); PointType* pt_ptr; PointType pt; pt_ptr = &pt; for( itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); elt!=m_Solver.el.end(); elt++) { unsigned int Nnodes= (*elt)->GetNumberOfNodes(); inimage=true; for (unsigned int nd=0; nd< Nnodes; nd++) { for(unsigned int f=0; fGetNode(nd)->GetCoordinates()(f); m_SurfaceMesh->GetPoint((*elt)->GetNode(nd)->GN, pt_ptr); x=pt[f]; long int temp; if (x !=0) temp=(long int) ((x)+0.5); else temp=0;// round rindex[f]=temp/spacing[f]; disp[f] =(Float) 1.0*Sol[f]; if ( temp < 0 || temp > (long int) imageSize[f]-1) inimage=false; } // convert the cartesian coordinates to theta and phi spherical coords phi=acos(Sol[2]); theta = acos(Sol[0]/sin(phi)); s=phi/phiinc; t=theta/thetainc; gridval; if ( ( ((int)t) + ((int)s)) % 2 == 0) gridval = 100; else gridval=200; if (inimage ) m_Image->SetPixel(rindex, gridval);//*100. +110.0); } } // end of elt array loop } template void FEMConformalMap ::MapStereographicCoordinatesToImage(int cdim) { typedef float Float; Float rstep,sstep,tstep; vnl_vector Pos; // solution at the point vnl_vector Sol; // solution at the local point vnl_vector Gpt; // global position given by local point typename ImageType::SpacingType spacing=m_Image->GetSpacing(); typename ImageType::SizeType imageSize=m_Image->GetLargestPossibleRegion().GetSize(); VectorType disp; disp.set_size(3); disp.fill(0.0); Float solval,posval; bool inimage; ImageRegionIteratorWithIndex wimIter( m_Image, m_Image->GetLargestPossibleRegion() ); wimIter.GoToBegin(); for( ; !wimIter.IsAtEnd(); ++wimIter ) wimIter.Set(0.0); typename ImageType::IndexType rindex = wimIter.GetIndex(); Sol.set_size(ImageDimension); Gpt.set_size(ImageDimension); Pos.set_size(ImageDimension); PointType* pt_ptr; PointType pt; pt_ptr = &pt; for( itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); elt!=m_Solver.el.end(); elt++) { unsigned int Nnodes= (*elt)->GetNumberOfNodes(); inimage=true; for (unsigned int nd=0; nd< Nnodes; nd++) { for(unsigned int f=0; fGetNumberOfDegreesOfFreedomPerNode() == 3) { Sol[f]= m_Solver.GetLinearSystemWrapper()->GetSolutionValue( (*elt)->GetNode(nd)->GetDegreeOfFreedom(f) , 0); x=(*elt)->GetNode(nd)->GetCoordinates()[f]; } else { Sol[f]= (*elt)->GetNode(nd)->GetCoordinates()(f); m_SurfaceMesh->GetPoint((*elt)->GetNode(nd)->GN, pt_ptr); x=pt[f]; } long int temp; if (x !=0) temp=(long int) ((x)+0.5); else temp=0;// round rindex[f]=temp/spacing[f]; disp[f] =(Float) 1.0*Sol[f]; if ( temp < 0 || temp > (long int) imageSize[f]-1) inimage=false; } if (inimage ) m_Image->SetPixel(rindex, disp[cdim]+2.0);//*100. +110.0); } } // end of elt array loop } template void FEMConformalMap ::FindPoles(int dim) { // find node with min x coord and its elt -> use as north pole (apply forces there) // find node with max x coord and its elt -> use as south pole (fix solution to zero) if (dim < 0) return; vnl_vector minx(3,9.e9); vnl_vector maxx(3,0.0); itk::fem::Element::VectorType minv; itk::fem::Element::VectorType maxv; unsigned int dofsperelt; itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); unsigned int Nnodes= (*elt)->GetNumberOfNodes(); dofsperelt=(*elt)->GetNumberOfDegreesOfFreedomPerNode()*Nnodes; for( ; elt!=m_Solver.el.end(); elt++) { for (unsigned int nd=0; nd< Nnodes; nd++) { for (unsigned int dd=0; dd< ImageDimension; dd++) { float x=((*elt)->GetNode(nd)->GetCoordinates()[dd]); if (x <= minx[dd]) { // std::cout << " x " << x << " minx " << minx << std::endl; m_PoleElementsGN[dd*2]=(*elt)->GN; minv=(*elt)->GetNode(nd)->GetCoordinates(); minx[dd]=x; } else if (x >= maxx[dd]) { // std::cout << " x " << x << " maxx " << maxx << std::endl; m_PoleElementsGN[dd*2+1]=(*elt)->GN; maxv=(*elt)->GetNode(nd)->GetCoordinates(); maxx[dd]=x; } } } } for (int jj=0; jj<3; jj++){ std::cout << " Element " << m_PoleElementsGN[jj*2] << " is north " << jj << std::endl; std::cout << " Element " << m_PoleElementsGN[jj*2+1] << " is south " << jj << std::endl; } } template void FEMConformalMap ::FixPoles(int dim) { // if (dim > 3 || dim < -3 || dim == 0 ) return; if (dim == m_NorthPole) return; unsigned int dofsperelt; itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); unsigned int Nnodes= (*elt)->GetNumberOfNodes(); unsigned int dofs=(*elt)->GetNumberOfDegreesOfFreedomPerNode(); dofsperelt=dofs*Nnodes; { float fixval; itk::fem::LoadBC::Pointer l1; itk::fem::LoadBC::Pointer l2; itk::fem::LoadBC::Pointer l3; itk::fem::LoadBC::Pointer l4; itk::fem::LoadBC::Pointer l5; // itk::fem::LoadBC::Pointer l6; int absdim=abs(dim); float oc=2.0; std::cout << " Fixing BC " << absdim << std::endl; switch (absdim) { case 0: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[0]]; l1->m_dof=i; l1->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l1) );} break; case 1: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[1]]; l1->m_dof=i; l1->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l1) );} break; case 2: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[2]]; l2->m_dof=i; l2->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l2) );} break; case 3: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[3]]; l3->m_dof=i; l3->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l3) );} break; case 4: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[4]]; l4->m_dof=i; l4->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l4) );} break; case 5: for (int i=0; im_element=m_Solver.el[m_PoleElementsGN[5]]; l5->m_dof=i; l5->m_value=vnl_vector(1,fixval); m_Solver.load.push_back( itk::fem::FEMP(&*l5) );} break; } } } template void FEMConformalMap ::ApplyRealForces(int dim) { int ct=0; if (dim > 6) dim=6; // loop over all elements, applying forces to the nodes 0 and 1 (real forces are zero on the 3rd node) // for( ::itk::fem::Solver::ElementArray::iterator e = m_Solver.el.begin(); e!=m_Solver.el.end(); e++) { itk::fem::Element::Pointer e = m_Solver.el[m_PoleElementsGN[dim]]; int na=0; int nb=1; int nc=2; { VectorType A=(e)->GetNode(na)->GetCoordinates(); VectorType B=(e)->GetNode(nb)->GetCoordinates(); VectorType C=(e)->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType AC =A-C; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=AC.magnitude(); if (bamag > cbmag && bamag > acmag) { na=0; nb=1; nc=2; } if (cbmag > bamag && cbmag > acmag) { na=1; nb=2; nc=0; } if (acmag > bamag && acmag > cbmag) { na=2; nb=0; nc=1; } } VectorType A=(e)->GetNode(na)->GetCoordinates(); VectorType B=(e)->GetNode(nb)->GetCoordinates(); VectorType C=(e)->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=CA.magnitude(); float theta=(CA[0]*BA[0]+CA[1]*BA[1]+CA[2]*BA[2])/bamag*bamag; if (theta > 1) std::cout << " theta " << theta << std::endl; VectorType E = A+BA*theta; VectorType CE =C-E; float cemag=CE.magnitude(); float mag=bamag; // load node 0 { itk::fem::LoadNode::Pointer load=itk::fem::LoadNode::New(); load->m_pt=na; load->F.set_size(3); load->F.fill(-1.0/bamag); load->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*load) ); } // load node 1 { itk::fem::LoadNode::Pointer load=itk::fem::LoadNode::New(); load->m_pt=nb; load->F.set_size(3); load->F.fill(1.0/bamag); load->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*load) ); } ct++; if (ct > 0) return; } } template void FEMConformalMap ::ApplyImaginaryForces(int dim) { unsigned int ct=0; if (dim > 6) dim=6; // loop over all elements, applying forces to the nodes 0 and 1 (real forces are zero on the 3rd node) // for( ::itk::fem::Solver::ElementArray::iterator e = m_Solver.el.begin(); e!=m_Solver.el.end(); e++) { itk::fem::Element::Pointer e = m_Solver.el[m_PoleElementsGN[dim]]; /* VectorType A=(e)->GetNode(0)->GetCoordinates(); VectorType B=(e)->GetNode(1)->GetCoordinates(); VectorType C=(e)->GetNode(2)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; float bamag=BA.magnitude(); float theta=(CA[0]*BA[0]+CA[1]*BA[1]+CA[2]*BA[2])/bamag*bamag; if (theta > 1) std::cout << " theta " << theta << std::endl; VectorType E = A+BA*theta; VectorType CE =C-E; float cemag=CE.magnitude(); */ int na=0; int nb=1; int nc=2; { VectorType A=(e)->GetNode(na)->GetCoordinates(); VectorType B=(e)->GetNode(nb)->GetCoordinates(); VectorType C=(e)->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType AC =A-C; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=AC.magnitude(); if (bamag > cbmag && bamag > acmag) { na=0; nb=1; nc=2; } if (cbmag > bamag && cbmag > acmag) { na=1; nb=2; nc=0; } if (acmag > bamag && acmag > cbmag) { na=2; nb=0; nc=1; } } VectorType A=(e)->GetNode(na)->GetCoordinates(); VectorType B=(e)->GetNode(nb)->GetCoordinates(); VectorType C=(e)->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=CA.magnitude(); float theta=(CA[0]*BA[0]+CA[1]*BA[1]+CA[2]*BA[2])/bamag*bamag; if (theta > 1 || theta < 0) { // std::cout << " ERROR : theta from non-acute angle " << theta << std::endl; // throw; // return; } VectorType E = A+BA*theta; VectorType CE =C-E; float cemag=CE.magnitude(); // load node 0 { itk::fem::LoadNode::Pointer load=itk::fem::LoadNode::New(); load->m_pt=na; load->F.set_size(3); load->F.fill((1.0-theta)/cemag); load->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*load) ); } // load node 1 { itk::fem::LoadNode::Pointer load=itk::fem::LoadNode::New(); load->m_pt=nb; load->F.set_size(3); load->F.fill((theta)/cemag); load->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*load) ); } // load node 2 { itk::fem::LoadNode::Pointer load=itk::fem::LoadNode::New(); load->m_pt=nc; load->F.set_size(3); load->F.fill(-1.0/cemag); load->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*load) ); } ct++; if (ct > 0) return; } } template void FEMConformalMap ::ComputeStereographicCoordinates() { std::cout << " coords on unit sphere : " << std::endl; float radsq; // radius squared float c1,c2,c3; // stereographic coordinates unsigned int ngfn=0,dof; // ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { dof=(*n)->GetDegreeOfFreedom(0); float x=m_RealSolution[dof]; float y=m_ImagSolution[dof]; radsq=x*x+y*y; c1=2.0*x/(1.0+radsq); c2=2.0*y/(1.0+radsq); c3=2.0*radsq/(1.0+radsq)-1.0; // std::cout << c1 << " " << c2 << " " << c3 << " mag " << sqrt(c1*c1+c2*c2+c3*c3) << std::endl; VectorType coord=(*n)->GetCoordinates(); coord[0]=c1; coord[1]=c2; coord[2]=c3; /// (*n)->SetCoordinates(coord); } std::cout << " coords on unit sphere done " << std::endl; } template void FEMConformalMap ::ConformalMap() { m_Solver.load.clear(); m_Solver.node.clear(); m_Solver.el.clear(); /** * Open the file and assign it to stream object f */ if (m_ReadFromFile) { const char* filename=m_ParameterFileName.c_str(); std::cout<<"Reading FEM problem from file: "<GenerateSystemFromVtkSurfaceMesh(); } // else this->GenerateSystemFromSurfaceMesh(); int dir=m_NorthPole; // std::cout << " input dir to fix "; std::cin >> dir; this->FindPoles(dir); if (m_NorthPole != m_SouthPole) this->FixPoles(m_SouthPole); // for (int oo=0; oo<6; oo++) // this->FixPoles(oo); /** * Assign a unique id (global freedom number - GFN) * to every degree of freedom (DOF) in a system. */ m_Solver.GenerateGFN(); m_ImagSolution.set_size(m_Solver.GetNumberOfDegreesOfFreedom()); m_RealSolution.set_size(m_Solver.GetNumberOfDegreesOfFreedom()); m_RealSolution.fill(0); m_ImagSolution.fill(0); if (m_Debug) { for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { std::cout<<"Node#: "<<(*n)->GN<<": "; std::cout << " coord " << (*n)->GetCoordinates() << std::endl; } for( ::itk::fem::Solver::ElementArray::iterator n = m_Solver.el.begin(); n!=m_Solver.el.end(); n++) { std::cout<<"Elt#: "<<(*n)->GN<<": has " << (*n)->GetNumberOfNodes() << " nodes "; for (int i=0; i<(*n)->GetNumberOfNodes(); i++) std::cout << " coord " << (*n)->GetNode(i)->GetCoordinates() << std::endl; } } unsigned int maxits=m_Solver.GetNumberOfDegreesOfFreedom(); // should be > twice ndofs //if (m_Debug) std::cout << " ndof " << maxits << std::endl; itpackWrapper.SetMaximumNumberIterations(maxits*4); itpackWrapper.SetTolerance(1.e-5); itpackWrapper.JacobianConjugateGradient(); itpackWrapper.SetMaximumNonZeroValuesInMatrix(maxits*100); m_Solver.SetLinearSystemWrapper(&itpackWrapper); /** * Assemble the master stiffness matrix. In order to do this * the GFN's should already be assigned to every DOF. */ std::cout << " assemble k " << std::endl; m_Solver.AssembleK(); std::cout << " assemble k done " << std::endl; if (m_Debug) { for (int i=0; iGetMatrixValue(i,j); if ( i != j) sum+=val; // if (val != 0) std::cout << " entry i,j " << i << " , " << j << " = " << m_Solver.GetLinearSystemWrapper()->GetMatrixValue(i,j)<GN<<": "; if (m_Debug) std::cout << " coord " << (*n)->GetCoordinates() << std::endl; // For each DOF in the node... */ for( unsigned int d=0, dof; (dof=(*n)->GetDegreeOfFreedom(d))!=::itk::fem::Element::InvalidDegreeOfFreedomID; d++ ) { if (m_Debug) std::cout< void FEMConformalMap ::BuildOutputMeshes(typename TImage::Pointer image) { // Get the number of points in the mesh int numPoints = m_Solver.node.size(); // Create vtk polydata vtkPolyData* polydata1 = vtkPolyData::New(); vtkPolyData* polydata2 = vtkPolyData::New(); // Create the vtkPoints object and set the number of points vtkPoints* vpoints1 = vtkPoints::New(); vtkPoints* vpoints2 = vtkPoints::New(); vpoints1->SetNumberOfPoints(numPoints); vpoints2->SetNumberOfPoints(numPoints); vtkFloatArray* param = vtkFloatArray::New(); param->SetName("angle"); std::cout <<" start pts "; int idx=0; vtkDataArray* scs=NULL; if (m_VtkSurfaceMesh) { vtkPointData *pd=m_VtkSurfaceMesh->GetPointData(); scs = pd->GetScalars(); } typename TImage::SpacingType spacing = image->GetSpacing(); for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { // extrinisic coords VectorType loc = (*n)->GetCoordinates(); // spherical coords unsigned int dof=(*n)->GetDegreeOfFreedom(0); float x=m_RealSolution[dof]; float y=m_ImagSolution[dof]; float radsq=x*x+y*y; float c1=2.0*x/(1.0+radsq); float c2=2.0*y/(1.0+radsq); float c3=2.0*radsq/(1.0+radsq)-1.0; if (idx % 1000 == 0) std::cout << c1 << " " << c2 << " " << c3 << " mag " << sqrt(c1*c1+c2*c2+c3*c3) << std::endl; // float pt1[3]; pt1[0]=c1; pt1[1]=c2; pt1[2]=c3; float pt2[3]; pt2[0]=loc[0]; pt2[1]=loc[1]; pt2[2]=loc[2]; vpoints1->SetPoint(idx,pt1); vpoints2->SetPoint(idx,pt2); typename TImage::IndexType index; index[0]=(long int) loc[0]/spacing[0]; index[1]=(long int) loc[1]/spacing[1]; index[2]=(long int) loc[2]/spacing[2]; float temp; if (m_VtkSurfaceMesh) temp = scs->GetTuple1(idx); else temp = (float) image->GetPixel(index); param->InsertNextValue(temp); (*n)->GN=idx; idx++; } std::cout << " done with pts " << std::endl; vtkCellArray* tris1 = vtkCellArray::New(); vtkCellArray* tris2 = vtkCellArray::New(); std::cout << " start with tris " << std::endl; for( ::itk::fem::Solver::ElementArray::iterator n = m_Solver.el.begin(); n!=m_Solver.el.end(); n++) { tris1->InsertNextCell(3); tris2->InsertNextCell(3); for (int i=0; i<(*n)->GetNumberOfNodes(); i++) { tris1->InsertCellPoint((*n)->GetNode(i)->GN); tris2->InsertCellPoint((*n)->GetNode(i)->GN); } } std::cout << " done with tris " << std::endl; // Assign points and cells polydata1->SetPoints(vpoints1); polydata2->SetPoints(vpoints2); polydata1->SetPolys(tris1); polydata2->SetPolys(tris2); polydata1->GetPointData()->SetScalars(param); polydata2->GetPointData()->SetScalars(param); // vtkDelaunay2D* delny1=vtkDelaunay2D::New(); // delny1->SetInput(polydata1); //m_ExtractedSurfaceMesh=delny1->GetOutput();//polydata1;// m_ExtractedSurfaceMesh=vtkGenSmoothMesh(polydata1); // vtkDelaunay2D* delny2=vtkDelaunay2D::New(); // delny2->SetInput(polydata2); // m_DiskSurfaceMesh=delny2->GetOutput(); if (!m_VtkSurfaceMesh) m_VtkSurfaceMesh=vtkGenSmoothMesh(polydata2);//polydata2; return; } } // namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkFEMConformalMap.h000077500000000000000000000153001147325206600222330ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMConformalMap.h,v $ Language: C++ Date: $Date: 2006/10/13 19:20:46 $ Version: $Revision: 1.2 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _FEMConformalMap_h #define _FEMConformalMap_h #include #include #include #include "vtkDataSetWriter.h" #include "vtkDataSetMapper.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkActor.h" #include "vtkRenderWindowInteractor.h" #include "vtkDataSetReader.h" #include "vtkUnstructuredGrid.h" #include "vtkDataSet.h" #include "vtkCellArray.h" #include "vtkVolume16Reader.h" #include "vtkImageReader2.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkOutlineFilter.h" #include "vtkCamera.h" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkPolyVertex.h" #include "vtkPointData.h" #include "vtkExtractEdges.h" #include "vtkPolyDataNormals.h" #include "vtkMarchingCubes.h" #include "vtkImageGaussianSmooth.h" #include "vtkDecimatePro.h" #include "vtkContourFilter.h" #include "vtkPolyDataConnectivityFilter.h" //#include "vtkKitwareContourFilter.h" #include "vtkSmoothPolyDataFilter.h" #include "vtkSTLWriter.h" #include "vtkUnstructuredGridToPolyDataFilter.h" //#include "itkImageToVTKImageFilter.h" #include "vtkDelaunay2D.h" #include "vtkFloatArray.h" #include "itkObject.h" #include "itkProcessObject.h" #include "itkVectorContainer.h" #include "itkCastImageFilter.h" #include "itkFEM.h" #include "itkFEMLinearSystemWrapperItpack.h" #include "itkFEMElement3DC0LinearTriangularLaplaceBeltrami.h" #include "itkFEMElement3DC0LinearTriangularMembrane.h" namespace itk { /** \class FEMConformalMap * Angenent, Haker conformal mapping algorithm using FEM. * * \note The origin of a neighborhood is always taken to be * the first point entered into and the * last point stored in the list. */ template < typename TSurface, typename TImage, unsigned int TDimension=3 > class FEMConformalMap : public ProcessObject { public: /** Standard class typedefs. */ typedef FEMConformalMap Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(FEMConformalMap,ProcessObject); /** Method for creation through the object factory. */ itkNewMacro(Self); /** Surface (mesh) types. */ typedef TImage ImageType; typedef typename TImage::Pointer ImageTypePointer; /** Surface (mesh) types. */ typedef TSurface SurfaceType; typedef typename SurfaceType::Pointer SurfaceTypePointer; typedef typename SurfaceType::PointType PointType; typedef typename SurfaceType::CellsContainerPointer InputCellsContainerPointer; typedef typename SurfaceType::CellsContainer::Iterator InputCellsContainerIterator; /** Image dimension. */ // itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension); itkStaticConstMacro(ImageDimension, unsigned int, TDimension); itkStaticConstMacro(SurfaceDimension, unsigned int, TDimension); typedef double RealType; typedef vnl_vector VectorType; typedef vnl_vector_fixed FixedVectorType; typedef vnl_matrix MatrixType; /** FEM types */ typedef itk::fem::MaterialLinearElasticity MaterialType; typedef itk::fem::Node NodeType; typedef itk::fem::LoadNode LoadType; typedef itk::fem::Element3DC0LinearTriangularLaplaceBeltrami ElementType; typedef itk::fem::Element3DC0LinearTriangularMembrane ElementType1; /** Set input parameter file */ itkSetStringMacro( ParameterFileName ); /** Set input parameter file */ itkGetStringMacro( ParameterFileName ); itkGetMacro(Sigma, RealType); itkSetMacro(Sigma, RealType); itkGetMacro(SurfaceMesh, SurfaceTypePointer); itkSetMacro(SurfaceMesh, SurfaceTypePointer); itkGetMacro(Image, ImageTypePointer); itkSetMacro(Image, ImageTypePointer); itkGetMacro(SphereImage, ImageTypePointer); itkSetMacro(SphereImage, ImageTypePointer); itkSetMacro(SouthPole, int); void SetNorthPole(int p) { if (p % 2 == 0 ) { m_NorthPole=p; m_SouthPole=p+1; } else { m_NorthPole=p-1; m_SouthPole=p-1; } } void SetDebug(bool b) {m_Debug=b;} void SetReadFromFile(bool b) {m_ReadFromFile=b;} void FindPoles(int dim); void FixPoles(int dim); void ConformalParameterize(); void ConformalMap(); void ComputeStereographicCoordinates(); void MapStereographicCoordinatesToImage(int dim); void MapImageToSphere(ImageType* img, float rad ); void MapCheckerboardToImage(float increment); void BuildOutputMeshes(typename TImage::Pointer image); vtkPolyData* m_ExtractedSurfaceMesh; vtkPolyData* m_VtkSurfaceMesh; protected: bool GenerateSystemFromSurfaceMesh(); bool GenerateSystemFromVtkSurfaceMesh(); void ApplyRealForces(int dim); void ApplyImaginaryForces(int dim); FEMConformalMap(); virtual ~FEMConformalMap(){}; private: RealType m_Sigma; RealType m_Pi; std::string m_ParameterFileName; int m_NorthPole; int m_SouthPole; itk::fem::Solver m_Solver; bool m_ReadFromFile; bool m_Debug; bool m_FindingRealSolution; VectorType m_RealSolution; VectorType m_ImagSolution; ImageTypePointer m_Image; ImageTypePointer m_SphereImage; SurfaceTypePointer m_SurfaceMesh; itk::fem::LinearSystemWrapperItpack itpackWrapper; unsigned long m_PoleElementsGN[7]; }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkFEMConformalMap.cxx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkFEMDiscConformalMap.cxx000066400000000000000000001504341147325206600234160ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMDiscConformalMap.cxx,v $ Language: C++ Date: $Date: 2007/08/07 15:30:39 $ Version: $Revision: 1.3 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for detailm_Solver. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _FEMDiscConformalMap_txx #define _FEMDiscConformalMap_txx #include #include #include #include #include #include #include "vtkDelaunay2D.h" #include "vtkSelectPolyData.h" #include "vtkFloatArray.h" #include "itkDiscreteGaussianImageFilter.h" #include "itkFEMDiscConformalMap.h" #include "itkFEMLoadNode.h" #include "itkSurfaceMeshCurvature.h" #include "vtkClipPolyData.h" #include "vtkContourFilter.h" #include "vtkSmartPointer.h" namespace itk { template FEMDiscConformalMap ::FEMDiscConformalMap() { m_Sigma=2.0e-4; m_ParameterFileName = ""; m_NorthPole=0; m_SourceNodeNumber=1; this->m_DistanceCostWeight=1; this->m_LabelCostWeight=0; m_Pi= 3.14159265358979323846; m_ReadFromFile=false; m_Debug=false; m_FindingRealSolution=true; this->m_SurfaceMesh=NULL; for (int i=0; i<7; i++) m_PoleElementsGN[i]=0; this->m_MapToCircle=true; this->m_MapToSquare=false; this->m_ParamWhileSearching=true; m_Smooth=2.0; this->m_Label_to_Flatten=0; this->m_FlatImage = NULL; manifoldIntegrator=ManifoldIntegratorType::New(); } template bool FEMDiscConformalMap ::InBorder(typename FEMDiscConformalMap::GraphSearchNodePointer g) { if ( this->m_HelpFindLoop[ g->GetIdentity() ] > 0 ) return true; else return false; float dist=g->GetTotalCost(); if (dist > m_MaxCost && dist < m_MaxCost + 1.0) return true; return false; } template bool FEMDiscConformalMap ::InDisc(typename FEMDiscConformalMap::GraphSearchNodePointer g) { // if ( this->m_HelpFindLoop[ g->GetIdentity() ] != 0 ) return true; // else return false; // if ( g->WasVisited() ) return true; float d=g->GetTotalCost(); for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { if ( d <= this->m_DiscBoundaryList[i]->GetTotalCost() ) return true; } return false; if (g->GetPredecessor()) return true; else return false; } template void FEMDiscConformalMap ::FindSource(IndexType index) { vtkPoints* vtkpoints = this->m_SurfaceMesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); float mindist= 1.e9; for(int i =0; i < numPoints; i++) { double* pt = vtkpoints->GetPoint(i); float dist = 0.0; for (int j=0;j void FEMDiscConformalMap ::FindMeanSourceInLabel(unsigned int label ) { vtkPoints* vtkpoints = this->m_SurfaceMesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); float mindist= 1.e9; float meanx=0.,meany=0,meanz=0; unsigned long ct=0; vtkDataArray* labels=this->m_SurfaceMesh->GetPointData()->GetArray("Label"); vtkDataArray* features=NULL; if ( this->m_SurfaceFeatureMesh ) if ( this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature") ) features=this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature"); else features=labels; if ( !labels ) { std::cout << " cant get Labels --- need an array named Label in the mesh ... " << std::endl; exit(1); } else std::cout << " got Labels " << std::endl; for(int i =0; i < numPoints; i++) { double* pt = vtkpoints->GetPoint(i); manifoldIntegrator->GetGraphNode(i)->SetValue(labels->GetTuple1(i),3); // std::cout << " label " << labels->GetTuple1(i) << " & " << label <GetTuple1(i) - label ) < 0.5 ) { // std::cout << " choose " << labels->GetTuple1(i) << " & " << label << std::endl; meanx+=pt[0]; meany+=pt[1]; meanz+=pt[2]; ct++; // i=numPoints+1; } else { // ct+=0; manifoldIntegrator->GetGraphNode(i)->SetUnVisitable(); } } meanx/=(float)ct; meany/=(float)ct; meanz/=(float)ct; for(int i =0; i < numPoints; i++) { double* pt = vtkpoints->GetPoint(i); float dist = 0.0; dist+=(pt[0]-meanx)*(pt[0]-meanx); dist+=(pt[1]-meany)*(pt[1]-meany); dist+=(pt[2]-meanz)*(pt[2]-meanz); dist=sqrt(dist); if (dist < mindist && fabs( label - labels->GetTuple1(i) ) < 0.5 ) { mindist=dist; m_SourceNodeNumber = i; // std::cout << " label " << label << " chose " << labels->GetTuple1(i) << std::endl; } } if ( this->FindLoopAroundNode( this->m_SourceNodeNumber ) == 2 ) { std::cout << " found loop " << std::endl; } if ( ct > 0 ) std::cout << meanx << " " << meany << " " << meanz << std::endl; else { std::cout << " no label " << label << " exiting " << std::endl; exit(1); } } template float FEMDiscConformalMap ::AssessNodeDistanceCost( unsigned int nodeid ) { return manifoldIntegrator->GetGraphNode(nodeid)->GetTotalCost(); /* diff=G1->GetLocation()-G3->GetLocation(); tangentlength=0; for (unsigned int d=0; dGetLocation()-G3->GetLocation(); tangentlength=0; for (unsigned int d=0; d float FEMDiscConformalMap ::GetBoundaryParameterForSquare( unsigned int nodeid, unsigned int whichParam ) { // compute loop length and check validity float tangentlength=0,totallength=0,nodeparam=0,x=0,y=0; typename GraphSearchNodeType::NodeLocationType diff; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); diff=this->m_DiscBoundaryList[i]->GetLocation()-this->m_DiscBoundaryList[nxt]->GetLocation(); if ( this->m_DiscBoundaryList[i]->GetIdentity() == nodeid ) nodeparam=totallength; tangentlength=0; for (unsigned int d=0; d 1 */ } else if ( arclength <= 0.5 ) { x=(0.5-arclength)/0.25; /* 0 => 1 */ y=1; } else if ( arclength <= 0.75 ) { x=1; y=(0.75-arclength)/0.25; /* 1 => 0 */ } else if ( arclength <= 1 ) { x=(1-arclength)/0.25; /* 1 => 0 */ y=0; } // std::cout <<" x " << x << " y " << y << " al " << arclength << std::endl; if ( whichParam == 0 ) return x; else if ( whichParam == 1 ) return y; else return arclength; } template float FEMDiscConformalMap ::GetBoundaryParameterForCircle( unsigned int nodeid, unsigned int whichParam ) { // compute loop length and check validity float tangentlength=0,totallength=0,nodeparam=0; typename GraphSearchNodeType::NodeLocationType diff; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); diff=this->m_DiscBoundaryList[i]->GetLocation()-this->m_DiscBoundaryList[nxt]->GetLocation(); if ( this->m_DiscBoundaryList[i]->GetIdentity() == nodeid ) nodeparam=totallength; tangentlength=0; for (unsigned int d=0; d unsigned int FEMDiscConformalMap ::AddVertexToLoop( ) { // compute loop length and check validity float tangentlength=0,totallength=0; bool isvalid=true; typename GraphSearchNodeType::NodeLocationType diff; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); // std::cout << " this->m_DiscBoundaryList[i]->GetLocation() " << this->m_DiscBoundaryList[i]->GetLocation() << std::endl; diff=this->m_DiscBoundaryList[i]->GetLocation()-this->m_DiscBoundaryList[nxt]->GetLocation(); tangentlength=0; for (unsigned int d=0; dm_DiscBoundaryList[i]->m_NumberOfNeighbors; n++ ) { if ( this->m_DiscBoundaryList[i]->m_Neighbors[n] == this->m_DiscBoundaryList[nxt] ) isvalid=true; } } std::cout << " length " << totallength << " valid? " << isvalid << " entries " << this->m_DiscBoundaryList.size() << " gsz " << this->m_HelpFindLoop.size() << std::endl; /** now find a node with HelpFindLoop value == 0 that minimally changes the length ... and that has a root neighbor and next neighbor consistent with the original edge */ unsigned int newnodeid=0; unsigned int nodeparam=0; // the position in the curve parameter float newedgelength=1.e9; // minimize this GraphSearchNodePointer G1,G2,G3,BestG=NULL; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); G1=this->m_DiscBoundaryList[i]; G2=this->m_DiscBoundaryList[nxt]; G3=NULL; /** 3 conditions : (1) HelpFindLoop == 0 (2) am neighbor of curnode (3) am neighbor of next node (4) minlength */ for ( unsigned int n=0; n < G1->m_NumberOfNeighbors; n++ ) { for ( unsigned int m=0; m < G2->m_NumberOfNeighbors; m++ ) { long hfl=abs(this->m_HelpFindLoop[G1->m_Neighbors[n]->GetIdentity()]); hfl+=abs(this->m_HelpFindLoop[G2->m_Neighbors[m]->GetIdentity()]); if ( G1->m_Neighbors[n] == G2->m_Neighbors[m] && hfl == 0 ){ G3=G1->m_Neighbors[n]; n=G1->m_NumberOfNeighbors; m=G2->m_NumberOfNeighbors; float elementlength=this->AssessNodeDistanceCost( G3->GetIdentity() ); if ( elementlength < newedgelength ) { newedgelength=elementlength; BestG=G3; newnodeid=G3->GetIdentity(); nodeparam=i; } } } } } if ( !BestG ) { std::cout << " does not exist " << std::endl; return false; } if ( this->m_HelpFindLoop[ BestG->GetIdentity() ] != 0 ) { std::cout << " already done " << std::endl; return false; } std::vector neighborlist; long paramct=0; totallength=0; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { paramct++; neighborlist.push_back( this->m_DiscBoundaryList[i] ); this->m_HelpFindLoop[this->m_DiscBoundaryList[i]->GetIdentity()]=paramct; if ( i == nodeparam ) { paramct++; neighborlist.push_back( BestG ); this->m_HelpFindLoop[BestG->GetIdentity()]=paramct; } } // std::cout << " len1 " << this->m_DiscBoundaryList.size() << " len2 " << neighborlist.size() << std::endl; this->SetDiscBoundaryList( neighborlist ); // this->m_DiscBoundaryList.assign(neighborlist.begin(),neighborlist.end()); /* for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); diff=this->m_DiscBoundaryList[i]->GetLocation()-this->m_DiscBoundaryList[nxt]->GetLocation(); tangentlength=0; for (unsigned int d=0; dm_DiscBoundaryList.size(); i++) { paramct++; neighborlist.push_back( this->m_DiscBoundaryList[i] ); this->m_HelpFindLoop[ this->m_DiscBoundaryList[i]->GetIdentity() ]=paramct; if ( this->m_DiscBoundaryList[i]->GetIdentity() == newnodeid ) { // find the parameter of any of this fellows neighors ... // if it's greater than i+1 then skip ahead long bestparam= this->m_HelpFindLoop[ this->m_DiscBoundaryList[i]->GetIdentity()] +1; for ( unsigned int n=0; n < this->m_DiscBoundaryList[i]->m_NumberOfNeighbors; n++ ) { if ( this->m_HelpFindLoop[ this->m_DiscBoundaryList[i]->m_Neighbors[n]->GetIdentity()] > bestparam ) { bestparam=this->m_HelpFindLoop[ this->m_DiscBoundaryList[i]->m_Neighbors[n]->GetIdentity()]; BestG=this->m_DiscBoundaryList[i]->m_Neighbors[n]; } } // neighborlist.push_back( BestG ); for ( unsigned int j=i+1; j<(unsigned int) bestparam-1; j++) this->m_HelpFindLoop[ this->m_DiscBoundaryList[j]->GetIdentity() ]=-1; i=(unsigned int) (bestparam-2); } } this->SetDiscBoundaryList( neighborlist ); // this->m_DiscBoundaryList.assign(neighborlist.begin(),neighborlist.end()); float newtotallength=0; for (unsigned int i=0; im_DiscBoundaryList.size(); i++) { unsigned int nxt=( ( i+1 ) % this->m_DiscBoundaryList.size() ); diff=this->m_DiscBoundaryList[i]->GetLocation()-this->m_DiscBoundaryList[nxt]->GetLocation(); tangentlength=0; for (unsigned int d=0; dm_DiscBoundaryList.size(); i++) { for (unsigned int j=0; jm_DiscBoundaryList.size(); j++) { if ( i != j && this->m_DiscBoundaryList[i]->GetIdentity() == this->m_DiscBoundaryList[j]->GetIdentity() ) isvalid=false; } } for ( unsigned long g = 0 ; g < this->m_HelpFindLoop.size(); g ++ ) { if ( this->m_HelpFindLoop[g] != 0 ) this->m_HelpFindLoop[g]=-1; } for ( unsigned int j = 0 ; j < this->m_DiscBoundaryList.size(); j ++ ) { m_HelpFindLoop[this->m_DiscBoundaryList[j]->GetIdentity()]=j+1; } unsigned long MAXLIST=200; if ( this->m_DiscBoundaryList.size() > MAXLIST ) { std::cout << this->m_RootNode->GetLocation() < unsigned int FEMDiscConformalMap ::FindLoopAroundNode( unsigned int j_in ) { vtkDataArray* labels=this->m_SurfaceMesh->GetPointData()->GetArray("Label"); vtkDataArray* features=NULL; if ( this->m_SurfaceFeatureMesh ) if ( this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature") ) features=this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature"); else features=labels; this->m_DiscBoundaryList.clear(); unsigned int gsz=manifoldIntegrator->GetGraphSize(); // get distance from this node to all others // now measure the length distortion of the given solution this->m_RootNode=manifoldIntegrator->GetGraphNode(j_in); for (int i=0; iGetGraphSize(); i++) { manifoldIntegrator->GetGraphNode(i)->SetTotalCost(vnl_huge_val(manifoldIntegrator->GetMaxCost())); manifoldIntegrator->GetGraphNode(i)->SetUnVisited(); manifoldIntegrator->GetGraphNode(i)->SetValue(0.0,1); manifoldIntegrator->GetGraphNode(i)->SetValue(0.0,2); float labval=labels->GetTuple1(i); manifoldIntegrator->GetGraphNode(i)->SetValue(labval,3); manifoldIntegrator->GetGraphNode(i)->SetPredecessor(NULL); } manifoldIntegrator->EmptyQ(); manifoldIntegrator->SetSearchFinished( false ); manifoldIntegrator->SetSource(this->m_RootNode); manifoldIntegrator->InitializeQueue(); manifoldIntegrator->SetParamWhileSearching( this->m_ParamWhileSearching ); manifoldIntegrator->SetWeights(this->m_MaxCost,this->m_DistanceCostWeight,this->m_LabelCostWeight); manifoldIntegrator->PrintWeights(); manifoldIntegrator->FindPath(); /** at this point, we should have extracted the disc now we want to find a boundary point and an instant parameterization via FEM */ this->SetDiscBoundaryList( manifoldIntegrator->m_BoundaryList ); // this->m_DiscBoundaryList.assign(manifoldIntegrator->m_BoundaryList.begin(), // manifoldIntegrator->m_BoundaryList.end()); this->m_HelpFindLoop.clear(); this->m_HelpFindLoop.resize(gsz, 0); this->m_HelpFindLoop[j_in]=-1; unsigned int furthestnode=0; float maxdist=0; GraphSearchNodePointer farnode1=NULL; for ( unsigned int j = 0 ; j < this->m_DiscBoundaryList.size(); j ++ ) { if ( this->m_DiscBoundaryList[j]->GetTotalCost() > maxdist ) { maxdist= this->m_DiscBoundaryList[j]->GetTotalCost(); furthestnode=this->m_DiscBoundaryList[j]->GetIdentity(); farnode1=this->m_DiscBoundaryList[j]; } m_HelpFindLoop[this->m_DiscBoundaryList[j]->GetIdentity()]=j+1; } if ( this->m_ParamWhileSearching ) return 2; // butt ManifoldIntegratorTypePointer discParameterizer=ManifoldIntegratorType::New(); discParameterizer->SetSurfaceMesh(this->m_SurfaceMesh); discParameterizer->InitializeGraph3(); discParameterizer->SetMaxCost(1.e9); std::cout << " dcz "<< discParameterizer->GetGraphSize() << std::endl; for (int i=0; iGetGraphSize(); i++) { discParameterizer->GetGraphNode(i)->SetTotalCost(vnl_huge_val(discParameterizer->GetMaxCost())); discParameterizer->GetGraphNode(i)->SetUnVisitable(); if ( this->m_HelpFindLoop[i] > 0 ) discParameterizer->GetGraphNode(i)->SetUnVisited(); discParameterizer->GetGraphNode(i)->SetValue(0.0,1); discParameterizer->GetGraphNode(i)->SetValue(0.0,2); discParameterizer->GetGraphNode(i)->SetPredecessor(NULL); } discParameterizer->EmptyQ(); discParameterizer->SetSearchFinished( false ); discParameterizer->SetSource(discParameterizer->GetGraphNode(furthestnode)); discParameterizer->InitializeQueue(); discParameterizer->SetWeights(1.e9,1,0); discParameterizer->FindPath(); float temp=0; GraphSearchNodePointer farnode2=NULL; unsigned int vct=0; for (int i=0; iGetGraphSize(); i++) { if ( discParameterizer->GetGraphNode(i)->WasVisited() ) { float t=discParameterizer->GetGraphNode(i)->GetTotalCost() ; if ( t > temp ) { temp=t; farnode2=discParameterizer->GetGraphNode(i); } vct++; //std::cout << " dist " << t << " vct " << vct << std::endl; } } discParameterizer->BackTrack(farnode2); // butt2 ManifoldIntegratorTypePointer lastlooper=ManifoldIntegratorType::New(); lastlooper->SetSurfaceMesh(this->m_SurfaceMesh); lastlooper->InitializeGraph3(); lastlooper->SetMaxCost(1.e9); // std::cout << " dcz "<< lastlooper->GetGraphSize() << std::endl; for (int i=0; iGetGraphSize(); i++) { lastlooper->GetGraphNode(i)->SetTotalCost(vnl_huge_val(lastlooper->GetMaxCost())); lastlooper->GetGraphNode(i)->SetUnVisitable(); if ( this->m_HelpFindLoop[i] > 0 ) lastlooper->GetGraphNode(i)->SetUnVisited(); lastlooper->GetGraphNode(i)->SetValue(0.0,1); lastlooper->GetGraphNode(i)->SetValue(0.0,2); lastlooper->GetGraphNode(i)->SetPredecessor(NULL); } lastlooper->EmptyQ(); lastlooper->SetSearchFinished( false ); for ( unsigned int pp=0; ppGetPathSize(); pp++) { unsigned int id=discParameterizer->GetPathAtIndex(pp)->GetIdentity(); lastlooper->SetSource( lastlooper->GetGraphNode(id) ); } lastlooper->InitializeQueue(); lastlooper->SetWeights(1.e9,1,0); lastlooper->FindPath(); GraphSearchNodePointer farnode3=NULL; vct=0; temp=0; for (int i=0; iGetGraphSize(); i++) { if ( lastlooper->GetGraphNode(i)->WasVisited() ) { float t=lastlooper->GetGraphNode(i)->GetTotalCost() ; if ( t > temp ) { temp=t; farnode3=lastlooper->GetGraphNode(i); } vct++; // std::cout << " dist " << t << " vct " << vct << std::endl; } } // exit(1); // finally reuse lastlooper with farnode3 as root ... for (int i=0; iGetGraphSize(); i++) { lastlooper->GetGraphNode(i)->SetTotalCost(vnl_huge_val(lastlooper->GetMaxCost())); lastlooper->GetGraphNode(i)->SetUnVisitable(); if ( this->m_HelpFindLoop[i] > 0 ) lastlooper->GetGraphNode(i)->SetUnVisited(); lastlooper->GetGraphNode(i)->SetValue(0.0,1); lastlooper->GetGraphNode(i)->SetValue(0.0,2); lastlooper->GetGraphNode(i)->SetPredecessor(NULL); } lastlooper->EmptyQ(); lastlooper->SetSearchFinished( false ); lastlooper->SetSource( lastlooper->GetGraphNode(farnode3->GetIdentity()) ); lastlooper->InitializeQueue(); lastlooper->SetWeights(1.e9,1,0); lastlooper->FindPath(); // now assemble the parameterization... // this->m_DiscBoundaryList.clear(); // add both the above to the list // std::cout << " part 1 " << std::endl; for ( unsigned int i = 0; i< discParameterizer->GetPathSize(); i++) { unsigned int id=discParameterizer->GetPathAtIndex(i)->GetIdentity(); // std::cout << manifoldIntegrator->GetGraphNode(id)->GetLocation() << std::endl; this->m_DiscBoundaryList.push_back( manifoldIntegrator->GetGraphNode(id) ); } // std::cout << " part 2 " << std::endl; lastlooper->BackTrack( lastlooper->GetGraphNode( farnode1->GetIdentity() ) ); for ( unsigned int i = 0; i< lastlooper->GetPathSize(); i++) { unsigned int id=lastlooper->GetPathAtIndex(i)->GetIdentity(); // std::cout << manifoldIntegrator->GetGraphNode(id)->GetLocation() << std::endl; this->m_DiscBoundaryList.push_back( manifoldIntegrator->GetGraphNode(id) ); } // std::cout << farnode1->GetLocation() << std::endl; // std::cout << farnode2->GetLocation() << std::endl; // std::cout << farnode3->GetLocation() << std::endl; // std::cout << " another idea --- get two points far apart then solve a minimization problem across the graph that gives the average value in 0 => 1 ... " << std::endl; // std::cout << " path 1 sz " << discParameterizer->GetPathSize() << std::endl; // finally do but add in reverse order // std::cout << " part 3 " <GetIdentity() << " and " << farnode1->GetIdentity() << std::endl; lastlooper->EmptyPath(); lastlooper->BackTrack( lastlooper->GetGraphNode( farnode2->GetIdentity()) ); for ( unsigned int i = lastlooper->GetPathSize()-1; i > 0 ; i--) { unsigned int id=lastlooper->GetPathAtIndex(i)->GetIdentity(); // std::cout << manifoldIntegrator->GetGraphNode(id)->GetLocation() << std::endl; this->m_DiscBoundaryList.push_back( manifoldIntegrator->GetGraphNode(id) ); } std::cout<< " Almost ... " << std::endl; this->m_HelpFindLoop.clear(); this->m_HelpFindLoop.resize(gsz, 0); for ( unsigned int j = 0 ; j < this->m_DiscBoundaryList.size(); j ++ ) { m_HelpFindLoop[this->m_DiscBoundaryList[j]->GetIdentity()]=j+1; } std::cout<< " Achievement!! " << std::endl; return 2; } template void FEMDiscConformalMap ::LocateAndParameterizeDiscBoundary( unsigned int label , bool CheckCost ) { float effectivemaxcost=0; this->m_DiscBoundaryList.clear(); unsigned int gsz=manifoldIntegrator->GetGraphSize(); std::vector alreadyfound(gsz, false); this->m_DiscBoundarySorter.clear(); this->m_DiscBoundarySorter.resize(gsz,0); for ( unsigned int j=0; jGetGraphNode(j) ) { float cost=manifoldIntegrator->GetGraphNode(j)->GetTotalCost(); if ( ! CheckCost ) cost=0; if ( fabs( manifoldIntegrator->GetGraphNode(j)->GetValue(3) - label ) < 0.5 && cost <= this->m_MaxCost ) { for (unsigned int i = 0; i < manifoldIntegrator->GetGraphNode(j)->m_NumberOfNeighbors; i++) { if ( fabs( manifoldIntegrator->GetGraphNode(j)->m_Neighbors[i]->GetValue(3) - label ) > 0.5 ) { // CurrentNode is in the boundary inb=1; } } // neighborhood if ( inb > 0 ) { // std::cout << " Node is in boundary " << std::endl; inb=0; for (unsigned int i = 0; i < manifoldIntegrator->GetGraphNode(j)->m_NumberOfNeighbors; i++) { if ( fabs( manifoldIntegrator->GetGraphNode(j)->m_Neighbors[i]->GetValue(3) - label ) < 0.5 && cost <= this->m_MaxCost ) { // CurrentNode is in the boundary inb+=1; } } // neighborhood if ( inb >= 2 && alreadyfound[j] == false ) { // need at least two neighbors with same label alreadyfound[j]=true; this->m_DiscBoundaryList.push_back(manifoldIntegrator->GetGraphNode(j)); if ( cost > effectivemaxcost ) effectivemaxcost=cost; } } } // less than max cost } // if node exists } // gsz std::cout << " Boundary has " << this->m_DiscBoundaryList.size() << " elements with eff. max cost " << effectivemaxcost << std::endl; if ( CheckCost ) { // very inefficient way to parameterize boundary .... unsigned int bsz=this->m_DiscBoundaryList.size(); std::vector alreadyfound(bsz, false); this->m_DiscBoundarySorter.resize(bsz,0); unsigned int boundcount=0; unsigned int rootind=0,lastroot=0; this->m_DiscBoundarySorter[rootind]=boundcount; alreadyfound[rootind]=true; bool paramdone=false; while ( ! paramdone ) { std::cout << " start param " << bsz << std::endl; if ( bsz == 0 ) exit(0); for (unsigned int myi = 0; myi < bsz ; myi++) { if ( this->m_DiscBoundaryList[myi] != this->m_DiscBoundaryList[rootind] ) { std::cout <<" myi " << myi << " root " << rootind << " bc " << boundcount << std::endl; for (unsigned int n = 0; n < this->m_DiscBoundaryList[rootind]->m_NumberOfNeighbors; n++) { if ( this->m_DiscBoundaryList[myi] == this->m_DiscBoundaryList[rootind]->m_Neighbors[n] && !alreadyfound[myi] ) { // its in the bndry // check that it's not an isolated bastard bool oknode=true; if ( oknode ) { boundcount++; alreadyfound[myi]=true; this->m_DiscBoundarySorter[myi]=boundcount; n=this->m_DiscBoundaryList[rootind]->m_NumberOfNeighbors+1; std::cout <<" cur " << this->m_DiscBoundaryList[rootind]->GetLocation() << " next " << this->m_DiscBoundaryList[myi]->GetLocation() << " boundcount " << boundcount << " of " << bsz << " curroot " << rootind << std::endl; lastroot=rootind; rootind=myi; myi=bsz; } } // is in boundary } // neighborhood loop } // not currootnode if ( boundcount >= bsz-1 ) paramdone=true; else if ( myi == (bsz-1) ) { boundcount--; rootind=lastroot; this->m_DiscBoundarySorter[rootind]=-1; std::cout <<" failure " << std::endl; exit(0); } } // all boundary nodes } // while // exit(0); }// param boundary if } template void FEMDiscConformalMap ::ExtractSurfaceDisc(unsigned int label) { std::cout << " set surface mesh " << std::endl; manifoldIntegrator->SetSurfaceMesh(this->m_SurfaceMesh); std::cout << " begin initializing graph " << std::endl; manifoldIntegrator->InitializeGraph3(); this->m_SurfaceMesh=manifoldIntegrator->GetSurfaceMesh(); // float frac=0; // IndexType index; if ( this->m_Label_to_Flatten == 0 ) { std::cout <<" enter LabelToExtract "; std::cin >> m_Label_to_Flatten; float mc=0; std::cout << " Enter max cost "; std::cin >> mc; m_MaxCost=mc; } manifoldIntegrator->SetMaxCost(this->m_MaxCost); this->FindMeanSourceInLabel( this->m_Label_to_Flatten ); // this->LocateAndParameterizeDiscBoundary( m_Label_to_Flatten , false ); // this->LocateAndParameterizeDiscBoundary( m_Label_to_Flatten , true ); // std::cout << " findpath in extractsurfacedisk done "; // assign scalars to the original surface mesh // typedef itk::SurfaceMeshCurvature surfktype; // typename surfktype::Pointer surfk=surfktype::New(); vtkPoints* vtkpoints = this->m_SurfaceMesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); vtkFloatArray* param = vtkFloatArray::New(); param->SetName("angle"); for(int i =0; i < numPoints; i++) { float temp=fabs(manifoldIntegrator->GetGraphNode(i)->GetTotalCost()); if (temp > m_MaxCost) temp=m_MaxCost; param->InsertNextValue(temp*255./m_MaxCost); } std::cout << " extractsurfacedisk done "; // m_SurfaceMesh->GetPointData()->SetScalars(param); } template bool FEMDiscConformalMap ::GenerateSystemFromSurfaceMesh() { if (!this->m_SurfaceMesh) { std::cout << " NO MESH"; return false;} std::cout << " Generate system from surface mesh " << std::endl; m_Smooth=m_Sigma; // create a material // Choose the material properties typename MaterialType::Pointer m; m=MaterialType::New(); m->GN=0; // Global number of the material /// m->E=4.0; // Young modulus -- used in the membrane /// m->A=0.0; // Crossection area /// m->h=0.0; // Crossection area /// m->I=0.0; // Moment of inertia /// m->nu=0.; //.0; // poissons -- DONT CHOOSE 1.0!!/// m->RhoC=0.0; // Create the element type ElementType::Pointer e1=ElementType::New(); e1->m_mat=dynamic_cast( m ); vtkPoints* vtkpoints = this->m_SurfaceMesh->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); int foundnum=0; int boundsz=0; for(int i =0; i < numPoints; i++) { double* pt = vtkpoints->GetPoint(i); typename NodeType::Pointer n; n=new NodeType(pt[0],pt[1],pt[2]); if (this->InDisc(manifoldIntegrator->GetGraphNode(i))) { n->GN=i; m_Solver.node.push_back(itk::fem::FEMP(n)); foundnum++; } if (this->InBorder(manifoldIntegrator->GetGraphNode(i))) boundsz++; } typename NodeType::Pointer* narr = new NodeType::Pointer[numPoints]; for(int i =0; i < numPoints; i++) { if (this->InDisc(manifoldIntegrator->GetGraphNode(i)) || this->InBorder(manifoldIntegrator->GetGraphNode(i))) { narr[i]=m_Solver.node.Find( i ); } } std::cout << " Found " << foundnum << " nodes " << std::endl; std::cout << " bound " << boundsz << std::endl; vtkCellArray* vtkcells = this->m_SurfaceMesh->GetPolys(); vtkIdType npts; vtkIdType* pts; unsigned long i = 0; // unsigned long toti = vtkcells->GetNumberOfCells(); // unsigned long rate = toti/50; // std::cout << " progress "; for(vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); ) { // if ( i % rate == 0 && i > rate ) std::cout << " " << (float) i / (float) toti << " "; // turn the cell into an element // std::cout << " points ids a " << pts[0] << " b " << pts[1] << " c " << pts[2] << std::endl; bool eltok=true; ElementType::Pointer e; e=dynamic_cast(e1->Clone()); if (this->InDisc(manifoldIntegrator->GetGraphNode(pts[0]))) e->SetNode(2,narr[pts[0]]); // e->SetNode(2,m_Solver.node.Find( pts[0] )); else eltok=false; if (this->InDisc(manifoldIntegrator->GetGraphNode(pts[1]))) e->SetNode(1,narr[pts[1]]); // e->SetNode(1,m_Solver.node.Find( pts[1] )); else eltok=false; if (this->InDisc(manifoldIntegrator->GetGraphNode(pts[2]))) e->SetNode(0,narr[pts[2]]); // e->SetNode(0,m_Solver.node.Find( pts[2] )); else eltok=false; if (eltok) { e->GN=i; m_Solver.el.push_back(itk::fem::FEMP(e)); i++; }//else std::cout <<" cannot find elt " << std::endl; } std::cout << " DONE: NUMBER OF CELLS " << i << std::endl; return true; } template void FEMDiscConformalMap ::FixBoundaryPoints(unsigned int option) { // if (dim > 3 || dim < -3 || dim == 0 ) return; unsigned int dofsperelt; itk::fem::Element::ArrayType::iterator elt=m_Solver.el.begin(); unsigned int Nnodes= (*elt)->GetNumberOfNodes(); unsigned int dofs=(*elt)->GetNumberOfDegreesOfFreedomPerNode(); dofsperelt=dofs*Nnodes; int fixct=0; int eltct=0; while(elt!=m_Solver.el.end()) { for (unsigned int i=0; iGetNode(i)->GN; // if( manifoldIntegrator->GetGraphNode(nodeid)->GetTotalCost() > 222 ) if( this->InBorder(manifoldIntegrator->GetGraphNode(nodeid)) ) { itk::fem::LoadBC::Pointer l1; l1=itk::fem::LoadBC::New(); l1->m_element=(*elt); l1->m_dof=i; l1->m_value=vnl_vector(1,0.0); // for exp float fixvalue=0.0; if ( this->m_MapToCircle) fixvalue=this->GetBoundaryParameterForCircle(nodeid,option); else fixvalue=this->GetBoundaryParameterForSquare(nodeid,option); l1->m_value=vnl_vector(1,fixvalue); // for direct rad m_Solver.load.push_back( itk::fem::FEMP(&*l1) ); /* itk::fem::LoadNode::Pointer ln1=itk::fem::LoadNode::New(); ln1->m_pt=0; ln1->F.set_size(1); ln1->F.fill(fixvalue); ln1->m_element=(*elt); m_Solver.load.push_back( itk::fem::FEMP(&*ln1) ); itk::fem::LoadNode::Pointer ln2=itk::fem::LoadNode::New(); ln2->m_pt=1; ln2->F.set_size(1); ln2->F.fill(fixvalue); ln2->m_element=(*elt); m_Solver.load.push_back( itk::fem::FEMP(&*ln2) ); itk::fem::LoadNode::Pointer ln3=itk::fem::LoadNode::New(); ln3->m_pt=2; ln3->F.set_size(1); ln3->F.fill(fixvalue); ln3->m_element=(*elt); m_Solver.load.push_back( itk::fem::FEMP(&*ln3) ); */ if (i==0) fixct++; // std::cout << " bord coord "<< manifoldIntegrator->GetGraphNode(nodeid)->GetLocation() << std::endl; } } elt++; eltct++; } std::cout << " Fixed elt number " << fixct << " of " << eltct << std::endl; } template void FEMDiscConformalMap ::ApplyRealForces() { /* itk::fem::Element::Pointer e = m_Solver.el[m_PoleElementsGN[0]]; // load node 0 { itk::fem::LoadNode::Pointer ln1=itk::fem::LoadNode::New(); ln1->m_pt=0; ln1->F.set_size(1); ln1->F.fill(-4.0*m_Pi); ln1->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*ln1) ); itk::fem::LoadNode::Pointer ln2=itk::fem::LoadNode::New(); ln2->m_pt=1; ln2->F.set_size(1); ln2->F.fill(-4.0*m_Pi); ln2->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*ln2) ); itk::fem::LoadNode::Pointer ln3=itk::fem::LoadNode::New(); ln3->m_pt=2; ln3->F.set_size(1); ln3->F.fill(-4.0*m_Pi); ln3->m_element=(e); m_Solver.load.push_back( itk::fem::FEMP(&*ln3) ); } */ } template void FEMDiscConformalMap ::ApplyImaginaryForces() { itk::fem::Element::Pointer e = m_Solver.el[m_PoleElementsGN[0]]; itk::fem::LoadBC::Pointer l1; l1=itk::fem::LoadBC::New(); l1->m_element=(e); l1->m_dof=0; l1->m_value=vnl_vector(1,-1./3.);// for exp m_Solver.load.push_back( itk::fem::FEMP(&*l1) ); itk::fem::LoadBC::Pointer l2; l2=itk::fem::LoadBC::New(); l2->m_element=(e); l2->m_dof=1; l2->m_value=vnl_vector(1,-1./3.);// for exp m_Solver.load.push_back( itk::fem::FEMP(&*l2) ); itk::fem::LoadBC::Pointer l3; l3=itk::fem::LoadBC::New(); l3->m_element=(e); l3->m_dof=2; l3->m_value=vnl_vector(1,2./3.);// for exp m_Solver.load.push_back( itk::fem::FEMP(&*l3) ); } template void FEMDiscConformalMap::MakeFlatImage() { // first declare the flat image typename FlatImageType::RegionType region; typename FlatImageType::SizeType size; int sz=256; size[0]=sz; size[1]=sz; region.SetSize( size ); m_FlatImage = FlatImageType::New(); m_FlatImage->SetRegions( region ); m_FlatImage->Allocate(); typename FlatImageType::IndexType index; std::cout << " Making flat image " << std::endl; int maxits=100; for ( int its =0; its <= maxits; its++) { for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { float temp=255.0 - manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(3); // curvature // float temp=255.0*manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(2); // extrinsic dist index[0]=(long int)(0.5+( 1.0+manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(0) )*(float)(sz-1)/2.); index[1]=(long int)(0.5+( 1.0+manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(1) )*(float)(sz-1)/2.); //std::cout << " ind " << index << std::endl; m_FlatImage->SetPixel(index, temp); } typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(1.0); filter->SetUseImageSpacingOff(); filter->SetMaximumError(.01f); filter->SetInput(m_FlatImage); filter->Update(); m_FlatImage=filter->GetOutput(); if ( its < maxits) { int center=(int)sz/2; itk::ImageRegionIteratorWithIndex it( m_FlatImage, region ); it.GoToBegin(); typename FlatImageType::IndexType index; while( !it.IsAtEnd() ) { index=it.GetIndex(); float x=(float)index[0]-(float)sz/2.0; float y=(float)index[1]-(float)sz/2.0; float dist=sqrt(x*x+y*y); // std::cout << "center " << center << " index " << index << "dist " << dist ; if ( dist > center ) it.Set( 0.0 ); ++it; } } } } template void FEMDiscConformalMap::BuildOutputMeshes(float tval) { std::cout << " build output mesh " << std::endl; typedef GraphSearchNodeType::NodeLocationType loctype; // Get the number of points in the mesh int numPoints = m_Solver.node.size(); vtkDataArray* labels=this->m_SurfaceMesh->GetPointData()->GetArray("Label"); vtkDataArray* features=NULL; if ( this->m_SurfaceFeatureMesh ) if ( this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature") ) features=this->m_SurfaceFeatureMesh->GetPointData()->GetArray("Feature"); else features=labels; else features=labels; // Create vtk polydata vtkPolyData* polydata1 = vtkPolyData::New(); vtkPolyData* polydata2 = vtkPolyData::New(); // Create the vtkPoints object and set the number of points vtkPoints* vpoints1 = vtkPoints::New(); vtkPoints* vpoints2 = vtkPoints::New(); vpoints1->SetNumberOfPoints(numPoints); vpoints2->SetNumberOfPoints(numPoints); std::cout <<" start pts "; int idx=0; vtkFloatArray* param = vtkFloatArray::New(); param->SetName("feature"); vtkFloatArray* paramAngle = vtkFloatArray::New(); paramAngle->SetName("angle"); vtkFloatArray* paramDistance = vtkFloatArray::New(); paramDistance->SetName("distance"); vtkIdTypeArray* paramPoints = vtkIdTypeArray::New(); paramPoints->SetName("points"); for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { loctype loc = manifoldIntegrator->GetGraphNode((*n)->GN)->GetLocation(); float pt1[3]; pt1[0]=loc[0]; pt1[1]=loc[1]; pt1[2]=loc[2]; float pt2[3]; pt2[0]=manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(0)*100.* (1.0 - tval) + tval * loc[0]; pt2[1]=manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(1)*100.* (1.0 - tval) + tval * loc[1]; pt2[2]=1. * (1.0 - tval) + tval * loc[2]; vpoints1->SetPoint(idx,pt1); vpoints2->SetPoint(idx,pt2); // temp=m_RealSolution[(*n)->GN]*255.0; // temp=( (unsigned int) this->InBorder(manifoldIntegrator->GetGraphNode((*n)->GN)) )*255; float temp=manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(3); // for curvature temp=features->GetTuple1((*n)->GN); // float temp=manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(1)*255; // for curvature float temp2=manifoldIntegrator->GetGraphNode((*n)->GN)->GetValue(0)*255;// for length param->InsertNextValue(temp); paramDistance->InsertNextValue(temp2); paramPoints->InsertNextValue((*n)->GN); paramAngle->InsertNextValue(temp); // curvature // param->InsertNextValue(temp*255./m_MaxCost); (*n)->GN=idx; idx++; } std::cout << " done with pts " << std::endl; vtkCellArray* tris1 = vtkCellArray::New(); vtkCellArray* tris2 = vtkCellArray::New(); std::cout << " start with tris " << std::endl; for( ::itk::fem::Solver::ElementArray::iterator n = m_Solver.el.begin(); n!=m_Solver.el.end(); n++) { tris1->InsertNextCell(3); tris2->InsertNextCell(3); for (unsigned int i=0; i<(*n)->GetNumberOfNodes(); i++) { tris1->InsertCellPoint((*n)->GetNode(i)->GN); tris2->InsertCellPoint((*n)->GetNode(i)->GN); } } std::cout << " done with tris " << std::endl; // Assign points and cells polydata1->SetPoints(vpoints1); polydata2->SetPoints(vpoints2); polydata1->SetPolys(tris1); polydata2->SetPolys(tris2); polydata1->GetPointData()->SetScalars(param); polydata2->GetPointData()->SetScalars(param); polydata1->GetPointData()->AddArray(paramAngle); polydata2->GetPointData()->AddArray(paramAngle); polydata1->GetPointData()->AddArray(paramDistance); polydata2->GetPointData()->AddArray(paramDistance); polydata1->GetPointData()->AddArray(paramPoints); polydata2->GetPointData()->AddArray(paramPoints); m_ExtractedSurfaceMesh=polydata1;// vtkDelaunay2D* delny2=vtkDelaunay2D::New(); delny2->SetInput(polydata2); m_DiskSurfaceMesh=delny2->GetOutput(); //m_DiskSurfaceMesh=polydata2; return; } template void FEMDiscConformalMap ::ConformalMap() { m_Solver.load.clear(); m_Solver.node.clear(); m_Solver.el.clear(); /** * Open the file and assign it to stream object f */ if (m_ReadFromFile) { const char* filename=m_ParameterFileName.c_str(); std::cout<<"Reading FEM problem from file: "<GenerateSystemFromSurfaceMesh()); else return; /** * Assign a unique id (global freedom number - GFN) * to every degree of freedom (DOF) in a system. */ m_Solver.GenerateGFN(); m_ImagSolution.set_size(m_Solver.GetNumberOfDegreesOfFreedom()); m_RealSolution.set_size(m_Solver.GetNumberOfDegreesOfFreedom()); m_Radius.set_size(m_Solver.GetNumberOfDegreesOfFreedom()); m_RealSolution.fill(0); m_ImagSolution.fill(0); m_Radius.fill(0); m_Debug=false; if (m_Debug) { for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { std::cout<<"Node#: "<<(*n)->GN<<": "; std::cout << " coord " << (*n)->GetCoordinates() << " coord2 " << manifoldIntegrator->GetGraphNode((*n)->GN)->GetLocation() << std::endl; } for( ::itk::fem::Solver::ElementArray::iterator n = m_Solver.el.begin(); n!=m_Solver.el.end(); n++) { std::cout<<"Elt#: "<<(*n)->GN<<": has " << (*n)->GetNumberOfNodes() << " nodes "; for (unsigned int i=0; i<(*n)->GetNumberOfNodes(); i++) std::cout << " coord " << (*n)->GetNode(i)->GetCoordinates() << std::endl; } } unsigned int maxits=m_Solver.GetNumberOfDegreesOfFreedom(); // should be > twice ndofs //if (m_Debug) std::cout << " ndof " << maxits << std::endl; itpackWrapper.SetMaximumNumberIterations(maxits*5); itpackWrapper.SetTolerance(1.e-4); itpackWrapper.SuccessiveOverrelaxation(); // itpackWrapper.JacobianConjugateGradient(); itpackWrapper.SetMaximumNonZeroValuesInMatrix(maxits*50); m_Solver.SetLinearSystemWrapper(&itpackWrapper); this->FixBoundaryPoints(0); m_Solver.AssembleK(); m_Solver.DecomposeK(); // this->ApplyRealForces(); std::cout << " appl force "; m_Solver.AssembleF(); // for (int i=0; iGetDegreeOfFreedom(d))!=::itk::fem::Element::InvalidDegreeOfFreedomID; d++ ) { m_RealSolution[dof]=m_Solver.GetSolution(dof); // if ( ct % 10 == 0) std::cout << " mrdof " << m_RealSolution[dof] << " dof " << dof << std::endl; } ct++; } this->ConformalMap2(); // this->ConformalMap3(); this->ConjugateHarmonic(); } template void FEMDiscConformalMap ::ConformalMap2() { m_Solver.load.clear(); this->FixBoundaryPoints(1); m_Solver.AssembleK(); // need to reassemble b/c LoadBC's affect K m_Solver.AssembleF(); m_Solver.Solve(); m_Solver.UpdateDisplacements();// copies solution to nodes unsigned long ct = 0; for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { for( unsigned int d=0, dof; (dof=(*n)->GetDegreeOfFreedom(d))!=::itk::fem::Element::InvalidDegreeOfFreedomID; d++ ) { m_ImagSolution[dof]=m_Solver.GetSolution(dof); // if (ct % 10 == 0) std::cout << " midof " << m_ImagSolution[dof] << " dof " << dof << std::endl; } ct++; } } template void FEMDiscConformalMap ::MeasureLengthDistortion() { // now measure the length distortion of the given solution manifoldIntegrator->EmptyQ(); manifoldIntegrator->SetSearchFinished( false ); for (int i=0; iGetGraphSize(); i++) { manifoldIntegrator->GetGraphNode(i)->SetTotalCost(vnl_huge_val(manifoldIntegrator->GetMaxCost())); manifoldIntegrator->GetGraphNode(i)->SetUnVisited(); manifoldIntegrator->GetGraphNode(i)->SetValue(0.0,1); manifoldIntegrator->GetGraphNode(i)->SetValue(0.0,2); manifoldIntegrator->GetGraphNode(i)->SetPredecessor(NULL); } manifoldIntegrator->SetSource(manifoldIntegrator->GetGraphNode(this->m_SourceNodeNumber)); manifoldIntegrator->InitializeQueue(); float mchere = 1.2; manifoldIntegrator->SetMaxCost(mchere); manifoldIntegrator->SetWeights(this->m_MaxCost,this->m_DistanceCostWeight,this->m_LabelCostWeight); manifoldIntegrator->FindPath(); // backtrack everywhere to set up forweard tracking float maxmanifolddist=0; float meanmanifolddist=0; float distDistortion=0; unsigned int ct = 0; for (int i=0; iGetGraphSize(); i++) { if (manifoldIntegrator->GetGraphNode(i)) if (manifoldIntegrator->GetGraphNode(i)->GetTotalCost() <= manifoldIntegrator->GetMaxCost() ) { float ttt=manifoldIntegrator->GetGraphNode(i)->GetValue(2); meanmanifolddist+=ttt; if ( ttt > maxmanifolddist) maxmanifolddist=ttt; ct++; } } meanmanifolddist/=(float)ct; ct=0; for (int i=0; iGetGraphSize(); i++) { float manifolddist; float rad; if (manifoldIntegrator->GetGraphNode(i)) if (manifoldIntegrator->GetGraphNode(i)->GetTotalCost() < manifoldIntegrator->GetMaxCost()) { rad=manifoldIntegrator->GetGraphNode(i)->GetValue(0); manifolddist=manifoldIntegrator->GetGraphNode(i)->GetValue(2)/maxmanifolddist; manifoldIntegrator->GetGraphNode(i)->SetValue(manifolddist,2); distDistortion+=fabs(rad-manifolddist); ct++; } } std::cout << " distDistortion/ct " << distDistortion/(float)ct << " maxmfd " << maxmanifolddist <GetOutput(); float total=0.0; for (int i=0; im_SurfaceMesh->GetPoints()->GetNumberOfPoints(); i++) { float length1=0; float length2=0; float pt1[3]; for (int ne=0; neGetGraphNode(i)->GetNumberOfNeighbors(); ne++) { } } */ } template void FEMDiscConformalMap ::ConjugateHarmonic() { std::cout << " Conformal coordinates " << std::endl; unsigned long ct = 0; for( ::itk::fem::Solver::NodeArray::iterator n = m_Solver.node.begin(); n!=m_Solver.node.end(); n++) { ct++; unsigned long dof=(*n)->GetDegreeOfFreedom(0); if ( dof < m_RealSolution.size() ) { // std::cout << " dof " << dof << std::endl; float U = m_RealSolution[dof]; // std::cout << " U " << U << std::endl; float V = m_ImagSolution[dof]; // std::cout << " V " << V << " ngn " << (*n)->GN << std::endl; manifoldIntegrator->GetGraphNode( (*n)->GN )->SetValue(U,0); manifoldIntegrator->GetGraphNode( (*n)->GN )->SetValue(V,1); // if (ct % 100 == 0) std::cout << " U " << U<< " V " << V << std::endl; } } // this->MakeFlatImage(); this->BuildOutputMeshes(); return; } } // namespace itk /* vtkSelectPolyData *loop = vtkSelectPolyData::New(); loop->SetInput(this->m_SurfaceMesh); // put points inside ... vtkPoints* points = vtkPoints::New(); points->SetNumberOfPoints( this->m_DiscBoundaryList.size()); unsigned int idx=0; for ( unsigned int j = 0 ; j < this->m_DiscBoundaryList.size(); j ++ ) { float pt1[3]; typename GraphSearchNodeType::NodeLocationType loc=this->m_DiscBoundaryList[j]->GetLocation(); pt1[0]=loc[0]; pt1[1]=loc[1]; pt1[2]=loc[2]; // unsigned int idx=this->m_DiscBoundaryList[j]->GetIdentity(); points->SetPoint(idx,pt); idx++; } loop->GenerateSelectionScalarsOff(); loop->SetSelectionModeToClosestPointRegion(); //negative scalars inside loop->SetSelectionModeToSmallestRegion(); //negative scalars inside loop->SetLoop(points); loop->Modified(); vtkClipPolyData *clip = vtkClipPolyData::New(); //clips out positive region clip->SetInput(loop->GetOutput()); vtkPolyDataMapper *clipMapper = vtkPolyDataMapper::New(); clipMapper->SetInput(clip->GetOutput()); vtkActor *clipActor = vtkActor::New(); clipActor->SetMapper(clipMapper); clipActor->AddPosition(1, 0, 0); // clipActor->GetProperty()->SetColor(0, 0, 1); //Set colour blue vtkRenderer *ren1 = vtkRenderer::New(); vtkRenderWindow* renWin = vtkRenderWindow::New(); renWin->AddRenderer(ren1); vtkRenderWindowInteractor* inter = vtkRenderWindowInteractor::New(); inter->SetRenderWindow(renWin); ren1->SetViewport(0.0, 0.0, 1.0, 1.0); ren1->AddActor(clipActor); renWin->Render(); inter->Start(); ren1->Delete(); renWin->Delete(); points-> Delete(); loop->Delete(); clip->Delete(); clipMapper->Delete(); clipActor->Delete(); */ #endif ants-1.9.2+svn680.dfsg/Temporary/itkFEMDiscConformalMap.h000077500000000000000000000220161147325206600230400ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMDiscConformalMap.h,v $ Language: C++ Date: $Date: 2006/10/13 19:20:46 $ Version: $Revision: 1.2 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _FEMDiscConformalMap_h #define _FEMDiscConformalMap_h #include #include #include #include "vtkDataSetWriter.h" #include "vtkDataSetMapper.h" #include "vtkRenderer.h" #include "vtkRenderWindow.h" #include "vtkActor.h" #include "vtkRenderWindowInteractor.h" #include "vtkDataSetReader.h" #include "vtkUnstructuredGrid.h" #include "vtkDataSet.h" #include "vtkCellArray.h" #include "vtkVolume16Reader.h" #include "vtkImageReader2.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkOutlineFilter.h" #include "vtkCamera.h" #include "vtkProperty.h" #include "vtkPolyData.h" #include "vtkPolyVertex.h" #include "vtkPointData.h" #include "vtkExtractEdges.h" #include "vtkPolyDataNormals.h" #include "vtkMarchingCubes.h" #include "vtkImageGaussianSmooth.h" #include "vtkDecimatePro.h" #include "vtkContourFilter.h" #include "vtkPolyDataConnectivityFilter.h" //#include "vtkKitwareContourFilter.h" #include "vtkSmoothPolyDataFilter.h" #include "vtkSTLWriter.h" #include "vtkUnstructuredGridToPolyDataFilter.h" //#include "itkImageToVTKImageFilter.h" #include "itkDijkstrasAlgorithm.h" #include "itkManifoldIntegrationAlgorithm.h" //#include "itkTriangulatedDijkstrasAlgorithm.h" #include "itkObject.h" #include "itkProcessObject.h" #include "itkVectorContainer.h" #include "itkCastImageFilter.h" #include "itkFEM.h" #include "itkFEMLinearSystemWrapperItpack.h" #include "itkMesh.h" namespace itk { /** \class FEMDiscConformalMap * Avants Epstein conformal mapping algorithm using FEM. * * \note The origin of a neighborhood is always taken to be * the first point entered into and the * last point stored in the list. */ template < typename TSurface, typename TImage, unsigned int TDimension=3 > class FEMDiscConformalMap : public ProcessObject { public: /** Standard class typedefs. */ typedef FEMDiscConformalMap Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(FEMDiscConformalMap,ProcessObject); /** Method for creation through the object factory. */ itkNewMacro(Self); /** Surface (mesh) types. */ typedef TImage ImageType; typedef typename TImage::Pointer ImageTypePointer; typedef typename TImage::IndexType IndexType; /** Surface (mesh) types. */ typedef TSurface SurfaceType; typedef SurfaceType* SurfaceTypePointer; // typedef typename SurfaceType::PointType PointType; // typedef typename SurfaceType::CellsContainerPointer InputCellsContainerPointer; // typedef typename SurfaceType::CellsContainer::Iterator InputCellsContainerIterator; /** Image dimension. */ // itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension); itkStaticConstMacro(ImageDimension, unsigned int, TDimension); itkStaticConstMacro(SurfaceDimension, unsigned int, TDimension); typedef float RealType; typedef vnl_vector VectorType; typedef vnl_vector_fixed FixedVectorType; typedef vnl_matrix MatrixType; typedef Image FlatImageType; typedef typename FlatImageType::Pointer FlatImageTypePointer; typedef GraphSearchNode GraphSearchNodeType; typedef typename GraphSearchNodeType::Pointer GraphSearchNodePointer; typedef typename GraphSearchNodeType::NodeLocationType NodeLocationType; typedef ManifoldIntegrationAlgorithm ManifoldIntegratorType; // typedef TriangulatedDijkstrasAlgorithm ManifoldIntegratorType; typedef typename ManifoldIntegratorType::Pointer ManifoldIntegratorTypePointer; /** FEM types */ typedef itk::fem::MaterialLinearElasticity MaterialType; typedef itk::fem::Node NodeType; typedef itk::fem::LoadNode LoadType; typedef itk::fem::Element3DC0LinearTriangularLaplaceBeltrami ElementType; typedef itk::fem::Element3DC0LinearTriangularMembrane ElementType1; /** Set input parameter file */ itkSetStringMacro( ParameterFileName ); /** Set input parameter file */ itkGetStringMacro( ParameterFileName ); itkGetMacro(Sigma, RealType); itkSetMacro(Sigma, RealType); itkGetMacro(SurfaceMesh, SurfaceTypePointer); itkSetMacro(SurfaceMesh, SurfaceTypePointer); itkGetMacro(SurfaceFeatureMesh, SurfaceTypePointer); itkSetMacro(SurfaceFeatureMesh, SurfaceTypePointer); void SetDebug(bool b) {m_Debug=b;} void SetReadFromFile(bool b) {m_ReadFromFile=b;} float AssessNodeDistanceCost( unsigned int ); float GetBoundaryParameterForSquare(unsigned int, unsigned int); float GetBoundaryParameterForCircle(unsigned int, unsigned int); unsigned int FindLoopAroundNode( unsigned int j ); unsigned int AddVertexToLoop(); void LocateAndParameterizeDiscBoundary(unsigned int,bool) ; void FixBoundaryPoints( unsigned int option ); void ConformalMap(); void ConformalMap2(); void ConjugateHarmonic(); bool InBorder(GraphSearchNodePointer); bool InDisc(GraphSearchNodePointer); void ExtractSurfaceDisc( unsigned int label = 0 ); void BuildOutputMeshes(float tval = 0.0); SurfaceTypePointer m_ExtractedSurfaceMesh; SurfaceTypePointer m_DiskSurfaceMesh; void SetSmooth(float i){ m_Smooth=i;} void MeasureLengthDistortion(); void SetParamWhileSearching( bool b ) { this->m_ParamWhileSearching=b; } void FindSource(IndexType); void FindMeanSourceInLabel(unsigned int); void MakeFlatImage(); FlatImageTypePointer m_FlatImage; inline void SetLabelToFlatten( unsigned int b ) { this->m_Label_to_Flatten=b; } inline void SetMaxCost( float f ) { this->m_MaxCost=f; } inline void SetDistanceCostWeight(float d) { this->m_DistanceCostWeight=d; } inline void SetLabelCostWeight(float d) { this->m_LabelCostWeight=d; } inline void SetMapToSquare( ) { this->m_MapToSquare=true; this->m_MapToCircle=false; } inline void SetMapToCircle( ) { this->m_MapToSquare=false; this->m_MapToCircle=true; } inline void SetDiscBoundaryList( std::vector b ) { this->m_DiscBoundaryList.assign(b.begin(),b.end()); }; protected: bool GenerateSystemFromSurfaceMesh(); void ApplyRealForces(); void ApplyImaginaryForces(); FEMDiscConformalMap(); virtual ~FEMDiscConformalMap(){}; private: std::vector m_DiscBoundaryList; // contains ids of nodes at boundary std::vector m_HelpFindLoop; // 0 = not found, 2 = already done , 1 = in loop std::vector m_DiscBoundarySorter; // contains ids of nodes at boundary std::vector m_DiscBoundaryParameter; // contains ids of nodes at boundary RealType m_Sigma; RealType m_Pi; std::string m_ParameterFileName; int m_NorthPole; int m_SourceNodeNumber; float m_DistanceCostWeight; float m_LabelCostWeight; itk::fem::Solver m_Solver; bool m_ReadFromFile; bool m_Debug; bool m_FindingRealSolution; bool m_MapToCircle; bool m_MapToSquare; bool m_ParamWhileSearching; VectorType m_RealSolution; VectorType m_ImagSolution; VectorType m_Radius; SurfaceTypePointer m_SurfaceMesh; SurfaceTypePointer m_SurfaceFeatureMesh; float m_MaxCost; itk::fem::LinearSystemWrapperItpack itpackWrapper; unsigned long m_PoleElementsGN[7]; ManifoldIntegratorTypePointer manifoldIntegrator; float m_Smooth; unsigned int m_Label_to_Flatten; GraphSearchNodePointer m_RootNode; }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkFEMDiscConformalMap.cxx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DC0LinearTriangular.cxx000066400000000000000000000231671147325206600253660ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DC0LinearTriangular.cxx,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include "itkFEMElement3DC0LinearTriangular.h" #include "vnl/vnl_math.h" #include "vnl/algo/vnl_svd.h" #include "vnl/algo/vnl_qr.h" namespace itk { namespace fem { const Element3DC0LinearTriangular::Float Element3DC0LinearTriangular ::trigGaussRuleInfo[6][7][4] = { { // order=0, never used { 0.0 } }, { // order=1 //<-------------------------- point ---------------------------> <-------weight-----> { 0.33333333333333333, 0.33333333333333333, 0.33333333333333333, 1.00000000000000000} }, { // order=2 { 0.66666666666666667, 0.16666666666666667, 0.16666666666666667, 0.33333333333333333}, { 0.16666666666666667, 0.66666666666666667, 0.16666666666666667, 0.33333333333333333}, { 0.16666666666666667, 0.16666666666666667, 0.66666666666666667, 0.33333333333333333} }, { // order=3, p=-3 in the book { 0.00000000000000000, 0.50000000000000000, 0.50000000000000000, 0.33333333333333333}, { 0.50000000000000000, 0.00000000000000000, 0.50000000000000000, 0.33333333333333333}, { 0.50000000000000000, 0.50000000000000000, 0.00000000000000000, 0.33333333333333333} }, { // order=4, p=6 in the book { 0.10810301816807023, 0.44594849091596489, 0.44594849091596489, 0.22338158967801147}, { 0.44594849091596489, 0.10810301816807023, 0.44594849091596489, 0.22338158967801147}, { 0.44594849091596489, 0.44594849091596489, 0.10810301816807023, 0.22338158967801147}, { 0.81684757298045851, 0.09157621350977074, 0.09157621350977074, 0.10995174365532187}, { 0.09157621350977074, 0.81684757298045851, 0.09157621350977074, 0.10995174365532187}, { 0.09157621350977074, 0.09157621350977074, 0.81684757298045851, 0.10995174365532187} }, { // order=5, p=7 in the book { 0.33333333333333333, 0.33333333333333333, 0.33333333333333333, 0.22500000000000000}, { 0.79742698535308732, 0.10128650732345634, 0.10128650732345634, 0.12593918054482715}, { 0.10128650732345634, 0.79742698535308732, 0.10128650732345634, 0.12593918054482715}, { 0.10128650732345634, 0.10128650732345634, 0.79742698535308732, 0.12593918054482715}, { 0.05971587178976982, 0.47014206410511509, 0.47014206410511509, 0.13239415278850618}, { 0.47014206410511509, 0.05971587178976982, 0.47014206410511509, 0.13239415278850618}, { 0.47014206410511509, 0.47014206410511509, 0.05971587178976982, 0.13239415278850618} } }; const unsigned int Element3DC0LinearTriangular ::Nip[6]= { 0,1,3,3,6,7 }; void Element3DC0LinearTriangular ::GetIntegrationPointAndWeight(unsigned int i, VectorType& pt, Float& w, unsigned int order) const { // FIXME: range checking // default integration order if (order==0 || order>5) { order=DefaultIntegrationOrder; } pt.set_size(3); /* * We provide implementation for 5 different integration rules * as defined in chapter 24 - Implementation of Iso-P Truangular * Elements, of http://titan.colorado.edu/courses.d/IFEM.d/. * * Note that the order parameter here does not correspond to the * actual order of integration, but rather the degree of polynomials * that are exactly integrated. In addition, there are two integration * rules for polynomials of 2nd degree. In order to allow using both of * them, we assign the index number 3 to the second one. Note that this * does not mean that the rule is capable of integrating the polynomials * of 3rd degree. It's just an index of a rule. */ pt.copy_in(trigGaussRuleInfo[order][i]); // We scale the weight by 0.5, to take into account // the factor that must be applied when integrating. w=0.5*trigGaussRuleInfo[order][i][3]; } unsigned int Element3DC0LinearTriangular ::GetNumberOfIntegrationPoints(unsigned int order) const { // FIXME: range checking // default integration order if (order==0) { order=DefaultIntegrationOrder; } return Nip[order]; } Element3DC0LinearTriangular::VectorType Element3DC0LinearTriangular ::ShapeFunctions( const VectorType& pt ) const { // Linear triangular element has 3 shape functions VectorType shapeF(3); // Shape functions are equal to coordinates shapeF=pt; return shapeF; } void Element3DC0LinearTriangular ::ShapeFunctionDerivatives( const VectorType&, MatrixType& shapeD ) const { // Matrix of shape functions derivatives is an // identity matrix for linear triangular element. shapeD.set_size(3,3); shapeD.fill(0.0); shapeD[0][0]=1.0; shapeD[1][1]=1.0; shapeD[2][2]=1.0; } bool Element3DC0LinearTriangular ::GetLocalFromGlobalCoordinates( const VectorType& globalPt , VectorType& localPt) const { Float x, x1, x2, x3, y, y1, y2, y3, z, z1, z2, z3, A; localPt.set_size(3); x=globalPt[0]; y=globalPt[1]; z=globalPt[2]; x1 = this->m_node[0]->GetCoordinates()[0]; y1 = this->m_node[0]->GetCoordinates()[1]; x2 = this->m_node[1]->GetCoordinates()[0]; y2 = this->m_node[1]->GetCoordinates()[1]; x3 = this->m_node[2]->GetCoordinates()[0]; y3 = this->m_node[2]->GetCoordinates()[1]; z1 = this->m_node[0]->GetCoordinates()[2]; z2 = this->m_node[1]->GetCoordinates()[2]; z3 = this->m_node[2]->GetCoordinates()[2]; //FIXME! A=x1*y2 - x2*y1 + x3*y1 - x1*y3 + x2*y3 - x3*y2; // localPt[0]=((y2 - y3)*x + (x3 - x2)*y + x2*y3 - x3*y2)/A; // localPt[1]=((y3 - y1)*x + (x1 - x3)*y + x3*y1 - x1*y3)/A; // localPt[2]=((y1 - y2)*x + (x2 - x1)*y + x1*y2 - x2*y1)/A; if (localPt[0] < 0.0 || localPt[0] > 1.0 || localPt[1] < 0.0 || localPt[1] > 1.0 || localPt[2] < 0.0 || localPt[2] > 1.0 ) { return false; } else { return true; } } Element3DC0LinearTriangular::Float Element3DC0LinearTriangular ::JacobianDeterminant( const VectorType& pt, const MatrixType* pJ ) const { // use heron's formula int na=0; int nb=1; int nc=2; VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float L1=CB.magnitude(); float L2=CA.magnitude(); float L3=BA.magnitude(); float s=(L1+L2+L3)*.5; Float det = sqrt( s*(s-L1)*(s-L2)*(s-L3) ); /* // use the formula for tri pqr, area is mag( vec(pq) cross vec(pr) ) VectorType a=this->GetNode(2)->GetCoordinates()-this->GetNode(0)->GetCoordinates(); VectorType b=this->GetNode(1)->GetCoordinates()-this->GetNode(0)->GetCoordinates(); VectorType c; c.set_size(3); c[0] = a[1] * b[2] - a[2] * b[1]; c[1] = a[2] * b[0] - a[0] * b[2]; c[2] = a[0] * b[1] - a[1] * b[0]; Float det=0.5*c.magnitude(); */ // std::cout << " area " << det << std::endl; return det; } void Element3DC0LinearTriangular ::JacobianInverse( const VectorType& pt, MatrixType& invJ, const MatrixType* pJ ) const { MatrixType* pJlocal=0; // If Jacobian was not provided, we // need to compute it here if(pJ==0) { pJlocal=new MatrixType(); this->Jacobian( pt, *pJlocal ); pJ=pJlocal; } // invJ=vnl_svd_inverse(*pJ); invJ=vnl_qr(*pJ).inverse(); /* // Note that inverse of Jacobian is not quadratic matrix MatrixType invJ2; invJ2.set_size(3,3); invJ2.fill(0); Float idet=1.0/this->JacobianDeterminant( pt, pJ ); invJ2[0][0]=idet*((*pJ)[1][1]-(*pJ)[2][1]); invJ2[0][1]=idet*((*pJ)[2][1]-(*pJ)[0][1]); invJ2[0][2]=idet*((*pJ)[0][1]-(*pJ)[1][1]); invJ2[1][0]=idet*((*pJ)[2][0]-(*pJ)[1][0]); invJ2[1][1]=idet*((*pJ)[0][0]-(*pJ)[2][0]); invJ2[1][2]=idet*((*pJ)[1][0]-(*pJ)[0][0]); std::cout << " pJ " << std::endl; std::cout << (*pJ) << std::endl; std::cout << " invJ " << std::endl; std::cout << (invJ) << std::endl; std::cout << " invJ2 " << std::endl; std::cout << (invJ2) << std::endl;*/ delete pJlocal; } /* * Draw the element on device context pDC. */ #ifdef FEM_BUILD_VISUALIZATION void Element3DC0LinearTriangular ::Draw(CDC* pDC, Solution::ConstPointer sol) const { int x1=m_node[0]->GetCoordinates()[0]*DC_Scale; int y1=m_node[0]->GetCoordinates()[1]*DC_Scale; int x2=m_node[1]->GetCoordinates()[0]*DC_Scale; int y2=m_node[1]->GetCoordinates()[1]*DC_Scale; int x3=m_node[2]->GetCoordinates()[0]*DC_Scale; int y3=m_node[2]->GetCoordinates()[1]*DC_Scale; x1+=sol->GetSolutionValue(this->m_node[0]->GetDegreeOfFreedom(0))*DC_Scale; y1+=sol->GetSolutionValue(this->m_node[0]->GetDegreeOfFreedom(1))*DC_Scale; x2+=sol->GetSolutionValue(this->m_node[1]->GetDegreeOfFreedom(0))*DC_Scale; y2+=sol->GetSolutionValue(this->m_node[1]->GetDegreeOfFreedom(1))*DC_Scale; x3+=sol->GetSolutionValue(this->m_node[2]->GetDegreeOfFreedom(0))*DC_Scale; y3+=sol->GetSolutionValue(this->m_node[2]->GetDegreeOfFreedom(1))*DC_Scale; pDC->MoveTo(x1,y1); pDC->LineTo(x2,y2); pDC->LineTo(x3,y3); pDC->LineTo(x1,y1); } #endif }} // end namespace itk::fem ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DC0LinearTriangular.h000077500000000000000000000052161147325206600250110ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DC0LinearTriangular.h,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFEMElement3DC0LinearTriangular_h #define __itkFEMElement3DC0LinearTriangular_h #include "itkFEMElementStd.h" namespace itk { namespace fem { /** * \class Element3DC0LinearTriangular * \brief 3-noded, linear, C0 continuous finite element in 2D space. */ class Element3DC0LinearTriangular : public ElementStd<3,3> { typedef ElementStd<3,3> TemplatedParentClass; FEM_ABSTRACT_CLASS( Element3DC0LinearTriangular, TemplatedParentClass ) public: ////////////////////////////////////////////////////////////////////////// /* * Methods related to numeric integration */ enum { DefaultIntegrationOrder = 1 }; virtual void GetIntegrationPointAndWeight(unsigned int i, VectorType& pt, Float& w, unsigned int order) const; virtual unsigned int GetNumberOfIntegrationPoints(unsigned int order) const; ////////////////////////////////////////////////////////////////////////// /* * Methods related to the geometry of an element */ virtual VectorType ShapeFunctions( const VectorType& pt ) const; virtual void ShapeFunctionDerivatives( const VectorType& pt, MatrixType& shapeD ) const; // FIXME: Write a proper implementation virtual bool GetLocalFromGlobalCoordinates( const VectorType& globalPt , VectorType& localPt) const; virtual Float JacobianDeterminant( const VectorType& pt, const MatrixType* pJ = 0 ) const; virtual void JacobianInverse( const VectorType& pt, MatrixType& invJ, const MatrixType* pJ = 0 ) const; /** * Draw the element on the specified device context */ #ifdef FEM_BUILD_VISUALIZATION void Draw(CDC* pDC, Solution::ConstPointer sol) const; #endif /** * Constants for integration rules. */ static const Float trigGaussRuleInfo[6][7][4]; /** * Array that holds number of integration point for each order * of numerical integration. */ static const unsigned int Nip[6]; }; }} // end namespace itk::fem #endif // #ifndef __itkFEMElement3DC0LinearTriangular_h ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DC0LinearTriangularLaplaceBeltrami.cxx000066400000000000000000000170401147325206600303210ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DC0LinearTriangularLaplaceBeltrami.cxx,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include #include "itkFEMElement3DC0LinearTriangularLaplaceBeltrami.h" namespace itk { namespace fem { Element3DC0LinearTriangularLaplaceBeltrami ::Element3DC0LinearTriangularLaplaceBeltrami() : Superclass() {} Element3DC0LinearTriangularLaplaceBeltrami ::Element3DC0LinearTriangularLaplaceBeltrami( NodeIDType n1_, NodeIDType n2_, NodeIDType n3_, Material::ConstPointer m_) : Superclass() { // Set the geometrical points this->SetNode( 0, n1_ ); this->SetNode( 1, n2_ ); this->SetNode( 2, n3_ ); /* * Initialize the pointer to material object and check that * we were given the pointer to the right class. * If the material class was incorrect an exception is thrown. */ if( (m_mat=dynamic_cast(&*m_)) == 0 ) { throw FEMExceptionWrongClass(__FILE__,__LINE__,"Element3DC0LinearTriangularLaplaceBeltrami::Element3DC0LinearTriangularLaplaceBeltrami()"); } } void Element3DC0LinearTriangularLaplaceBeltrami::GetStiffnessMatrix(MatrixType& Ke) const { MatrixType cot,D,BB; this->GetMaterialMatrix( D ); // //std::cout<< " Nip " << Nip << " w " << w << std::endl; this->GetMaterialMatrix(D); cot.set_size(3,3); cot.fill(0.); int na=0; int nb=1; int nc=2; VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float L1=CB.magnitude(); float L2=CA.magnitude(); float L3=BA.magnitude(); float s=(L1+L2+L3)*.5; Float Area = sqrt( s*(s-L1)*(s-L2)*(s-L3) ); cot[0][0]=(2.0*L1*L1)*D[0][0]; cot[1][1]=(2.0*L2*L2)*D[0][0]; cot[2][2]=(2.0*L3*L3)*D[0][0]; cot[0][1]=(L3*L3-L1*L1-L2*L2)*D[0][0]; cot[0][2]=(L2*L2-L1*L1-L3*L3)*D[0][0]; cot[1][2]=(L1*L1-L3*L3-L2*L2)*D[0][0]; cot[1][0]=(L3*L3-L1*L1-L2*L2)*D[0][0]; cot[2][0]=(L2*L2-L1*L1-L3*L3)*D[0][0]; cot[2][1]=(L1*L1-L3*L3-L2*L2)*D[0][0]; cot=cot*1.0/(8.0*Area); /* if ( this->GetNode(0)->GetDegreeOfFreedom(0)==53 || this->GetNode(1)->GetDegreeOfFreedom(0)==53 || this->GetNode(2)->GetDegreeOfFreedom(0)==53 ) { std::cout << " cot " << this->GetNode(0)->GetDegreeOfFreedom(0) << " " <GetNode(1)->GetDegreeOfFreedom(0) << " " <GetNode(2)->GetDegreeOfFreedom(0) <GetMaterialMatrix( D ); VectorType ip; Float w; MatrixType J; MatrixType shapeDgl; MatrixType shapeD; // //std::cout<< " Nip " << Nip << " w " << w << std::endl; this->GetMaterialMatrix(D); cot.set_size(3,3); cot.fill(0.); int na=0; int nb=1; int nc=2; { VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType AC =A-C; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=AC.magnitude(); if (bamag > cbmag && bamag > acmag) { na=0; nb=1; nc=2; } if (cbmag > bamag && cbmag > acmag) { na=1; nb=2; nc=0; } if (acmag > bamag && acmag > cbmag) { na=2; nb=0; nc=1; } } VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=CA.magnitude(); float t=(CA[0]*BA[0]+CA[1]*BA[1]+CA[2]*BA[2])/bamag*bamag; VectorType E = A+BA*t; VectorType CE =C-E; VectorType BE =B-E; VectorType AE =A-E; float cemag=CE.magnitude(); float bemag=CE.magnitude(); float aemag=AE.magnitude(); float h1; if (acmag > aemag) h1=acmag; else h1=aemag; float theta1=asin(cemag/h1); float h2; if (cbmag > bemag) h2=cbmag; else h2=bemag; float theta2=asin(cemag/h2); float theta3=acos(-1.0)-theta1-theta2; float cottheta1=cemag/aemag; // if (aemag == 0) cottheta1=1.0/tan(3.14159/2.0); float cottheta2=cemag/bemag; float cottheta3=1.0/tan(theta3); // if (fabs(cottheta1-1) < 1.e-6 && fabs(cottheta2-1) < 1.e-6) cottheta3=1.0; // std::cout <<" ct0 " << cottheta1 <<" ct1 " << cottheta2 <<" ct2 " << cottheta3 << std::endl; cot[na][na]=(cottheta3+cottheta2)*D[0][0]; cot[nb][nb]=(cottheta3+cottheta1)*D[0][0]; cot[nc][nc]=(cottheta1+cottheta2)*D[0][0]; cot[na][na]=-cottheta3*D[0][0]; cot[na][nc]=-cottheta2*D[0][0]; cot[nb][nc]=-cottheta1*D[0][0]; cot[nc][nb]=cot[nb][nc]*D[0][0]; cot[nc][na]=cot[na][nc]*D[0][0]; cot[nb][na]=cot[na][nb]*D[0][0]; cot=cot*0.5; Ke=cot; if ( this->GetNode(0)->GetDegreeOfFreedom(0)==909 || this->GetNode(1)->GetDegreeOfFreedom(0)==909 || this->GetNode(2)->GetDegreeOfFreedom(0)==909 ) { std::cout << " cot " << std::endl; std::cout << cot < { FEM_CLASS(Element3DC0LinearTriangularLaplaceBeltrami,Element3DMembrane1DOF) public: HANDLE_ELEMENT_LOADS(); /** * Default constructor only clears the internal storage */ Element3DC0LinearTriangularLaplaceBeltrami(); /** * Construct an element by specifying pointers to * 3 points and a material. */ Element3DC0LinearTriangularLaplaceBeltrami( NodeIDType n1_, NodeIDType n2_, NodeIDType n3_, Material::ConstPointer p_ ); virtual unsigned int GetNumberOfDegreesOfFreedomPerNode( void ) const { return 1; } virtual void GetStiffnessMatrix( MatrixType& Ke ) const; // void Read( std::istream&, void* info ); }; // class Element3DC0LinearTriangularLaplaceBeltrami FEM_CLASS_INIT(Element3DC0LinearTriangularLaplaceBeltrami) }} // end namespace itk::fem #endif // #ifndef __itkFEMElement3DC0LinearTriangularLaplaceBeltrami_h ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DC0LinearTriangularMembrane.cxx000066400000000000000000000102551147325206600270270ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DC0LinearTriangularMembrane.cxx,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ // disable debug warnings in MS compiler #ifdef _MSC_VER #pragma warning(disable: 4786) #endif #include #include "itkFEMElement3DC0LinearTriangularMembrane.h" namespace itk { namespace fem { Element3DC0LinearTriangularMembrane ::Element3DC0LinearTriangularMembrane() : Superclass() {} Element3DC0LinearTriangularMembrane ::Element3DC0LinearTriangularMembrane( NodeIDType n1_, NodeIDType n2_, NodeIDType n3_, Material::ConstPointer m_) : Superclass() { // Set the geometrical points this->SetNode( 0, n1_ ); this->SetNode( 1, n2_ ); this->SetNode( 2, n3_ ); /* * Initialize the pointer to material object and check that * we were given the pointer to the right class. * If the material class was incorrect an exception is thrown. */ if( (m_mat=dynamic_cast(&*m_)) == 0 ) { throw FEMExceptionWrongClass(__FILE__,__LINE__,"Element3DC0LinearTriangularMembrane::Element3DC0LinearTriangularMembrane()"); } } /* void Element3DC0LinearTriangularMembrane::GetStiffnessMatrix(MatrixType& Ke) const { MatrixType D; unsigned int Nip=this->GetNumberOfIntegrationPoints(0); VectorType ip; Float w; this->GetIntegrationPointAndWeight(0,ip,w,0); // //std::cout<< " Nip " << Nip << " w " << w << std::endl; this->GetMaterialMatrix(D); Ke.set_size(3,3); int na=0; int nb=1; int nc=2; { VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType AC =A-C; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=AC.magnitude(); if (bamag > cbmag && bamag > acmag) { na=0; nb=1; nc=2; } if (cbmag > bamag && cbmag > acmag) { na=1; nb=2; nc=0; } if (acmag > bamag && acmag > cbmag) { na=2; nb=0; nc=1; } } VectorType A=this->GetNode(na)->GetCoordinates(); VectorType B=this->GetNode(nb)->GetCoordinates(); VectorType C=this->GetNode(nc)->GetCoordinates(); VectorType BA =B-A; VectorType CA =C-A; VectorType CB =C-B; float bamag=BA.magnitude(); float cbmag=CB.magnitude(); float acmag=CA.magnitude(); float t=(CA[0]*BA[0]+CA[1]*BA[1]+CA[2]*BA[2])/bamag*bamag; VectorType E = A+BA*t; VectorType CE =C-E; VectorType BE =B-E; VectorType AE =A-E; float cemag=CE.magnitude(); float bemag=CE.magnitude(); float aemag=AE.magnitude(); float h1; if (acmag > aemag) h1=acmag; else h1=aemag; float theta1=asin(cemag/h1); float h2; if (cbmag > bemag) h2=cbmag; else h2=bemag; float theta2=asin(cemag/h2); float theta3=acos(-1.0)-theta1-theta2; float cottheta1=atan(theta1); float cottheta2=atan(theta2); float cottheta3=atan(theta3); Ke[0][0]=(cottheta3+cottheta2)*D[0][0]; Ke[1][1]=(cottheta3+cottheta1)*D[0][0]; Ke[2][2]=(cottheta1+cottheta2)*D[0][0]; Ke[0][1]=-cottheta3*D[0][0]; Ke[0][2]=-cottheta2*D[0][0]; Ke[1][2]=-cottheta1*D[0][0]; Ke[2][1]=Ke[1][2]*D[0][0]; Ke[2][0]=Ke[0][2]*D[0][0]; Ke[1][0]=Ke[0][1]*D[0][0]; // std::cout << " lapl belt " << std::endl; // std::cout << Ke << std::endl; } */ FEM_CLASS_REGISTER(Element3DC0LinearTriangularMembrane) }} // end namespace itk::fem ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DC0LinearTriangularMembrane.h000077500000000000000000000042421147325206600264560ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DC0LinearTriangularMembrane.h,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFEMElement3DC0LinearTriangularMembrane_h #define __itkFEMElement3DC0LinearTriangularMembrane_h #include "itkFEMElement3DC0LinearTriangular.h" #include "itkFEMElement3DMembrane.h" #include "itkFEMElement3DMembrane1DOF.h" namespace itk { namespace fem { /** * \class Element3DC0LinearTriangularMembrane * \brief 3-noded finite element class in 3D space for surface membrane problem. * * This element is combined from Element3DC0LinearTriangular and Element3DMembrane. */ class Element3DC0LinearTriangularMembrane : public Element3DMembrane { FEM_CLASS(Element3DC0LinearTriangularMembrane,Element3DMembrane) public: HANDLE_ELEMENT_LOADS(); /** * Default constructor only clears the internal storage */ Element3DC0LinearTriangularMembrane(); /** * Construct an element by specifying pointers to * 3 points and a material. */ Element3DC0LinearTriangularMembrane( NodeIDType n1_, NodeIDType n2_, NodeIDType n3_, Material::ConstPointer p_ ); // virtual unsigned int GetNumberOfDegreesOfFreedomPerNode( void ) const // { return 1; } // virtual void GetStiffnessMatrix( MatrixType& Ke ) const; // void Read( std::istream&, void* info ); }; // class Element3DC0LinearTriangularMembrane FEM_CLASS_INIT(Element3DC0LinearTriangularMembrane) }} // end namespace itk::fem #endif // #ifndef __itkFEMElement3DC0LinearTriangularMembrane_h ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DMembrane1DOF.h000066400000000000000000000072651147325206600235260ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DMembrane1DOF.h,v $ Language: C++ Date: $Date: 2005/11/08 15:34:16 $ Version: $Revision: 1.1.1.1 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFEMElement3DMembrane1DOF_h #define __itkFEMElement3DMembrane1DOF_h #include "itkFEMElementBase.h" #include "itkFEMMaterialLinearElasticity.h" namespace itk { namespace fem { /** * \class Element3DMembrane1DOF * \brief Class that is used to define a membrane energy problem in 3D space. * * This class only defines the physics of the problem. Use his class together * with element classes that specify the geometry to fully define the element. * * You can specify one template parameter: * * TBaseClass - Class from which Element3DMembrane1DOF is derived. TBaseClass must * be derived from the Element base class. This enables you * to use this class at any level of element definition. * If not specified, it defaults to the Element base class. */ template class Element3DMembrane1DOF : public TBaseClass { FEM_ABSTRACT_CLASS(Element3DMembrane1DOF,TBaseClass) public: // Repeat the required typedefs and enums from parent class typedef typename Superclass::Float Float; typedef typename Superclass::MatrixType MatrixType; typedef typename Superclass::VectorType VectorType; /** * Read data for this class from input stream */ virtual void Read( std::istream&, void* info ); /** * Write this class to output stream */ virtual void Write( std::ostream& f ) const; /** * Default constructor only clears the internal storage */ Element3DMembrane1DOF(); ////////////////////////////////////////////////////////////////////////// /* * Methods related to the physics of the problem. */ /** * Compute the B matrix. */ virtual void GetStrainDisplacementMatrix(MatrixType& B, const MatrixType& shapeDgl) const; /** * Compute the D matrix. */ virtual void GetMaterialMatrix(MatrixType& D) const; /** * Compute the mass matrix specific for 3D membrane problems. */ void GetMassMatrix(MatrixType& Me) const; /** * 3D membrane elements have 3 DOFs per node. */ virtual unsigned int GetNumberOfDegreesOfFreedomPerNode( void ) const { return 3; } virtual void GetStiffnessMatrix( MatrixType& Ke ) const; public: /** * Pointer to material properties of the element */ MaterialLinearElasticity::ConstPointer m_mat; virtual Material::ConstPointer GetMaterial(void) const { return m_mat; } virtual void SetMaterial(Material::ConstPointer mat_ ) { m_mat=dynamic_cast(&*mat_); } }; // class Element3DMembrane1DOF #ifdef _MSC_VER // Declare a static dummy function to prevent a MSVC 6.0 SP5 from crashing. // I have no idea why things don't work when this is not declared, but it // looks like this declaration makes compiler forget about some of the // troubles it has with templates. static void Dummy( void ); #endif // #ifdef _MSC_VER }} // end namespace itk::fem #ifndef ITK_MANUAL_INSTANTIATION #include "itkFEMElement3DMembrane1DOF.txx" #endif #endif // #ifndef __itkFEMElement3DMembrane1DOF_h ants-1.9.2+svn680.dfsg/Temporary/itkFEMElement3DMembrane1DOF.txx000066400000000000000000000100551147325206600241110ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkFEMElement3DMembrane1DOF.txx,v $ Language: C++ Date: $Date: 2006/10/16 16:30:27 $ Version: $Revision: 1.2 $ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFEMElement3DMembrane1DOF_txx #define __itkFEMElement3DMembrane1DOF_txx #include "itkFEMElement3DMembrane1DOF.h" namespace itk { namespace fem { template Element3DMembrane1DOF ::Element3DMembrane1DOF() : Superclass(), m_mat(0) {} ////////////////////////////////////////////////////////////////////////// /* * Methods related to the physics of the problem. */ template void Element3DMembrane1DOF ::GetStrainDisplacementMatrix(MatrixType& B, const MatrixType& shapeDgl) const { } template void Element3DMembrane1DOF ::GetMassMatrix(MatrixType& Me) const { // Call the parent's get matrix function Superclass::GetMassMatrix(Me); // Since parent class doesn't have the material properties, // we need to adjust Me matrix here for the density of the element. Me=Me*m_mat->RhoC; } template void Element3DMembrane1DOF ::GetMaterialMatrix(MatrixType& D) const { unsigned int d=3; D.set_size(d,d); D.fill(0.0); // This is the main difference from the linear elasticity problem. /* Material properties matrix. Simpler than linear elasticity. */ Float disot = m_mat->E; for (unsigned int i=0; i void Element3DMembrane1DOF::GetStiffnessMatrix(MatrixType& Ke) const { Superclass::GetStiffnessMatrix(Ke); } template void Element3DMembrane1DOF ::Read( std::istream& f, void* info ) { int n; /* * Convert the info pointer to a usable objects */ ReadInfoType::MaterialArrayPointer mats=static_cast(info)->m_mat; /* first call the parent's read function */ Superclass::Read(f,info); try { /* * Read and set the material pointer */ FEMLightObject::SkipWhiteSpace(f); f>>n; if(!f) goto out; m_mat=dynamic_cast( &*mats->Find(n)); } catch ( FEMExceptionObjectNotFound e ) { throw FEMExceptionObjectNotFound(__FILE__,__LINE__,"Element3DMembrane1DOF::Read()",e.m_baseClassName,e.m_GN); } // Check if the material object was of correct class if(!m_mat) { throw FEMExceptionWrongClass(__FILE__,__LINE__,"Element3DMembrane1DOF::Read()"); } out: if( !f ) { throw FEMExceptionIO(__FILE__,__LINE__,"Element3DMembrane1DOF::Read()","Error reading FEM element!"); } } /* * Write the element to the output stream. */ template void Element3DMembrane1DOF ::Write( std::ostream& f ) const { // First call the parent's write function Superclass::Write(f); /* * then write the actual data (material number) * We also add some comments in the output file */ f<<"\t"<GN<<"\t% MaterialLinearElasticity ID\n"; // check for errors if (!f) { throw FEMExceptionIO(__FILE__,__LINE__,"Element3DMembrane1DOF::Write()","Error writing FEM element!"); } } #ifdef _MSC_VER // Declare a static dummy function to prevent a MSVC 6.0 SP5 from crashing. // I have no idea why things don't work when this is not declared, but it // looks like this declaration makes compiler forget about some of the // troubles it has with templates. static void Dummy( void ); #endif // #ifdef _MSC_VER }} // end namespace itk::fem #endif // #ifndef __itkFEMElement3DMembrane1DOF_txx ants-1.9.2+svn680.dfsg/Temporary/itkFastMarchingImageFilter.h000066400000000000000000000422401147325206600240040ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkFastMarchingImageFilter.h,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFastMarchingImageFilter_h #define __itkFastMarchingImageFilter_h #include "itkArray.h" #include "itkImageToImageFilter.h" #include "itkIndex.h" #include "itkLevelSet.h" #include "itkNeighborhoodIterator.h" #include "vnl/vnl_math.h" #include #include namespace itk { /** \class FastMarchingImageFilter * \brief Solve an Eikonal equation using Fast Marching * * Fast marching solves an Eikonal equation where the speed is always * non-negative and depends on the position only. Starting from an * initial position on the front, fast marching systematically moves the * front forward one grid point at a time. * * Updates are preformed using an entropy satisfy scheme where only * "upwind" neighborhoods are used. This implementation of Fast Marching * uses a std::priority_queue to locate the next proper grid position to * update. * * Fast Marching sweeps through N grid points in (N log N) steps to obtain * the arrival time value as the front propagates through the grid. * * Implementation of this class is based on Chapter 8 of * "Level Set Methods and Fast Marching Methods", J.A. Sethian, * Cambridge Press, Second edition, 1999. * * This class is templated over the level set image type and the speed * image type. The initial front is specified by two containers: one * containing the known points and one containing the trial * points. Alive points are those that are already part of the * object, and trial points are considered for inclusion. * In order for the filter to evolve, at least some trial * points must be specified. These can for instance be specified as the layer of * pixels around the alive points. * The speed function can be specified as a speed image or a * speed constant. The speed image is set using the method * SetInput(). If the speed image is NULL, a constant speed function * is used and is specified using method the SetSpeedConstant(). * * If the speed function is constant and of value one, fast marching results * in an approximate distance function from the initial alive points. * FastMarchingImageFilter is used in the ReinitializeLevelSetImageFilter * object to create a signed distance function from the zero level set. * * The algorithm can be terminated early by setting an appropriate stopping * value. The algorithm terminates when the current arrival time being * processed is greater than the stopping value. * * There are two ways to specify the output image information * ( LargestPossibleRegion, Spacing, Origin): (a) it is copied directly from * the input speed image or (b) it is specified by the user. Default values * are used if the user does not specify all the information. * * The output information is computed as follows. * If the speed image is NULL or if the OverrideOutputInformation is set to * true, the output information is set from user specified parameters. These * parameters can be specified using methods SetOutputRegion(), SetOutputSpacing(), SetOutputDirection(), * and SetOutputOrigin(). Else if the speed image is not NULL, the output information * is copied from the input speed image. * * Possible Improvements: * In the current implemenation, std::priority_queue only allows * taking nodes out from the front and putting nodes in from the back. * To update a value already on the heap, a new node is added to the heap. * The defunct old node is left on the heap. When it is removed from the * top, it will be recognized as invalid and not used. * Future implementations can implement the heap in a different way * allowing the values to be updated. This will generally require * some sift-up and sift-down functions and * an image of back-pointers going from the image to heap in order * to locate the node which is to be updated. * * \sa LevelSetTypeDefault * \ingroup LevelSetSegmentation */ template < class TLevelSet, class TSpeedImage = Image::ImageDimension> > class ITK_EXPORT FastMarchingImageFilter : public ImageToImageFilter { public: /** Standard class typdedefs. */ typedef FastMarchingImageFilter Self; typedef ImageSource Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(FastMarchingImageFilter, ImageSource); /** Typedef support of level set method types. */ typedef LevelSetTypeDefault LevelSetType; typedef typename LevelSetType::LevelSetImageType LevelSetImageType; typedef typename LevelSetType::LevelSetPointer LevelSetPointer; typedef typename LevelSetType::PixelType PixelType; typedef typename LevelSetType::NodeType NodeType; typedef typename LevelSetType::NodeContainer NodeContainer; typedef typename LevelSetType::NodeContainerPointer NodeContainerPointer; typedef typename LevelSetImageType::SizeType OutputSizeType; typedef typename LevelSetImageType::RegionType OutputRegionType; typedef typename LevelSetImageType::SpacingType OutputSpacingType; typedef typename LevelSetImageType::DirectionType OutputDirectionType; typedef typename LevelSetImageType::PointType OutputPointType; class AxisNodeType : public NodeType { public: int GetAxis() const { return m_Axis; } void SetAxis( int axis ) { m_Axis = axis; } const AxisNodeType & operator=(const NodeType & node) { this->NodeType::operator=(node); return *this; } private: int m_Axis; }; /** SpeedImage typedef support. */ typedef TSpeedImage SpeedImageType; /** SpeedImagePointer typedef support. */ typedef typename SpeedImageType::Pointer SpeedImagePointer; typedef typename SpeedImageType::ConstPointer SpeedImageConstPointer; /** Dimension of the level set and the speed image. */ itkStaticConstMacro(SetDimension, unsigned int, LevelSetType::SetDimension); itkStaticConstMacro(SpeedImageDimension, unsigned int, SpeedImageType::ImageDimension); /** Index typedef support. */ typedef Index IndexType; /** Enum of Fast Marching algorithm point types. FarPoints represent far * away points; TrialPoints represent points within a narrowband of the * propagating front; and AlivePoints represent points which have already * been processed. Topology points were trial points but their inclusion * would have violated topology checks. */ enum LabelType { FarPoint, AlivePoint, TrialPoint, InitialTrialPoint, TopologyPoint }; /** LabelImage typedef support. */ typedef Image LabelImageType; typedef NeighborhoodIterator NeighborhoodIteratorType; /** LabelImagePointer typedef support. */ typedef typename LabelImageType::Pointer LabelImagePointer; /** ConnectedComponentImage typedef support. */ typedef Image ConnectedComponentImageType; /** ConnectedComponentImagePointer typedef support. */ typedef typename ConnectedComponentImageType::Pointer ConnectedComponentImagePointer; /** Set the container of Alive Points representing the initial front. * Alive points are represented as a VectorContainer of LevelSetNodes. */ void SetAlivePoints( NodeContainer * points ) { m_AlivePoints = points; this->Modified(); } /** Get the container of Alive Points representing the initial front. */ NodeContainerPointer GetAlivePoints( ) { return m_AlivePoints; } /** Set the container of Trial Points representing the initial front. * Trial points are represented as a VectorContainer of LevelSetNodes. */ void SetTrialPoints( NodeContainer * points ) { m_TrialPoints = points; this->Modified(); } /** Get the container of Trial Points representing the initial front. */ NodeContainerPointer GetTrialPoints( ) { return m_TrialPoints; } /** Get the point type label image. */ LabelImagePointer GetLabelImage() const { return m_LabelImage; } /** Get the point type label image. */ ConnectedComponentImagePointer GetConnectedComponentImage() const { return m_ConnectedComponentImage; } /** Set the Speed Constant. If the Speed Image is NULL, * the SpeedConstant value is used for the whole level set. * By default, the SpeedConstant is set to 1.0. */ void SetSpeedConstant( double value ) { m_SpeedConstant = value; m_InverseSpeed = -1.0 * vnl_math_sqr( 1.0 / m_SpeedConstant ); this->Modified(); } /** Get the Speed Constant. */ itkGetConstReferenceMacro( SpeedConstant, double ); /** Set/Get the Normalization Factor for the Speed Image. The values in the Speed Image is divided by this factor. This allows the use of images with integer pixel types to represent the speed. */ itkSetMacro( NormalizationFactor, double ); itkGetConstMacro( NormalizationFactor, double ); /** Set the Fast Marching algorithm Stopping Value. The Fast Marching * algorithm is terminated when the value of the smallest trial point * is greater than the stopping value. */ itkSetMacro( StoppingValue, double ); /** Get the Fast Marching algorithm Stopping Value. */ itkGetConstReferenceMacro( StoppingValue, double ); /** Set the Collect Points flag. Instrument the algorithm to collect * a container of all nodes which it has visited. Useful for * creating Narrowbands for level set algorithms that supports * narrow banding. */ itkSetMacro( CollectPoints, bool ); /** Get thConste Collect Points flag. */ itkGetConstReferenceMacro( CollectPoints, bool ); itkBooleanMacro( CollectPoints ); enum TopologyCheckType { None, NoHandles, Strict }; /** Set/Get boolean macro indicating whether the user wants to check topology. */ itkSetMacro( TopologyCheck, TopologyCheckType ); itkGetConstReferenceMacro( TopologyCheck, TopologyCheckType ); /** Get the container of Processed Points. If the CollectPoints flag * is set, the algorithm collects a container of all processed nodes. * This is useful for defining creating Narrowbands for level * set algorithms that supports narrow banding. */ NodeContainerPointer GetProcessedPoints() const { return m_ProcessedPoints; } /** The output largeset possible, spacing and origin is computed as follows. * If the speed image is NULL or if the OverrideOutputInformation is true, * the output information is set from user specified parameters. These * parameters can be specified using methods SetOutputRegion(), SetOutputSpacing(), SetOutputDirection(), * and SetOutputOrigin(). Else if the speed image is not NULL, the output information * is copied from the input speed image. */ virtual void SetOutputSize( const OutputSizeType& size ) { m_OutputRegion = size; } virtual OutputSizeType GetOutputSize() const { return m_OutputRegion.GetSize(); } itkSetMacro( OutputRegion, OutputRegionType ); itkGetConstReferenceMacro( OutputRegion, OutputRegionType ); itkSetMacro( OutputSpacing, OutputSpacingType ); itkGetConstReferenceMacro( OutputSpacing, OutputSpacingType ); itkSetMacro( OutputDirection, OutputDirectionType ); itkGetConstReferenceMacro( OutputDirection, OutputDirectionType ); itkSetMacro( OutputOrigin, OutputPointType ); itkGetConstReferenceMacro( OutputOrigin, OutputPointType ); itkSetMacro( OverrideOutputInformation, bool ); itkGetConstReferenceMacro( OverrideOutputInformation, bool ); itkBooleanMacro( OverrideOutputInformation ); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(SameDimensionCheck, (Concept::SameDimension)); itkConceptMacro(SpeedConvertibleToDoubleCheck, (Concept::Convertible)); itkConceptMacro(DoubleConvertibleToLevelSetCheck, (Concept::Convertible)); itkConceptMacro(LevelSetOStreamWritableCheck, (Concept::OStreamWritable)); /** End concept checking */ #endif protected: FastMarchingImageFilter(); ~FastMarchingImageFilter(){}; void PrintSelf( std::ostream& os, Indent indent ) const; virtual void Initialize( LevelSetImageType * ); virtual void UpdateNeighbors( const IndexType& index, const SpeedImageType *, LevelSetImageType * ); virtual double UpdateValue( const IndexType& index, const SpeedImageType *, LevelSetImageType * ); const AxisNodeType& GetNodeUsedInCalculation(unsigned int idx) const { return m_NodesUsed[idx]; } void GenerateData(); /** Generate the output image meta information. */ virtual void GenerateOutputInformation(); virtual void EnlargeOutputRequestedRegion(DataObject *output); /** Get Large Value. This value is used to represent the concept of infinity for the time assigned to pixels that have not been visited. This value is set by default to half the max() of the pixel type used to represent the time-crossing map. */ itkGetConstReferenceMacro( LargeValue, PixelType ); OutputRegionType m_BufferedRegion; typedef typename LevelSetImageType::IndexType LevelSetIndexType; LevelSetIndexType m_StartIndex; LevelSetIndexType m_LastIndex; itkGetConstReferenceMacro( StartIndex, LevelSetIndexType ); itkGetConstReferenceMacro( LastIndex, LevelSetIndexType ); private: FastMarchingImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented NodeContainerPointer m_AlivePoints; NodeContainerPointer m_TrialPoints; LabelImagePointer m_LabelImage; ConnectedComponentImagePointer m_ConnectedComponentImage; double m_SpeedConstant; double m_InverseSpeed; double m_StoppingValue; bool m_CollectPoints; NodeContainerPointer m_ProcessedPoints; OutputRegionType m_OutputRegion; OutputPointType m_OutputOrigin; OutputSpacingType m_OutputSpacing; OutputDirectionType m_OutputDirection; bool m_OverrideOutputInformation; typename LevelSetImageType::PixelType m_LargeValue; AxisNodeType m_NodesUsed[SetDimension]; /** Trial points are stored in a min-heap. This allow efficient access * to the trial point with minimum value which is the next grid point * the algorithm processes. */ typedef std::vector HeapContainer; typedef std::greater NodeComparer; typedef std::priority_queue< AxisNodeType, HeapContainer, NodeComparer > HeapType; HeapType m_TrialHeap; double m_NormalizationFactor; /** * Functions and variables to check for topology changes (2D/3D only). */ TopologyCheckType m_TopologyCheck; // Functions/data for the 2-D case void InitializeIndices2D(); bool IsChangeWellComposed2D( IndexType ); bool IsCriticalC1Configuration2D( Array ); bool IsCriticalC2Configuration2D( Array ); bool IsCriticalC3Configuration2D( Array ); bool IsCriticalC4Configuration2D( Array ); bool IsSpecialCaseOfC4Configuration2D( PixelType, IndexType, IndexType, IndexType ); Array m_RotationIndices[4]; Array m_ReflectionIndices[2]; // Functions/data for the 3-D case void InitializeIndices3D(); bool IsCriticalC1Configuration3D( Array ); unsigned int IsCriticalC2Configuration3D( Array ); bool IsChangeWellComposed3D( IndexType ); Array m_C1Indices[12]; Array m_C2Indices[8]; // Functions for both 2D/3D cases bool DoesVoxelChangeViolateWellComposedness( IndexType ); bool DoesVoxelChangeViolateStrictTopology( IndexType ); }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkFastMarchingImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkFastMarchingImageFilter.txx000066400000000000000000001007201147325206600243760ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkFastMarchingImageFilter.txx,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkFastMarchingImageFilter_txx #define __itkFastMarchingImageFilter_txx #include "itkFastMarchingImageFilter.h" #include "itkConnectedComponentImageFilter.h" #include "itkImageRegionIterator.h" #include "itkNumericTraits.h" #include "itkRelabelComponentImageFilter.h" #include "vnl/vnl_math.h" #include namespace itk { template FastMarchingImageFilter ::FastMarchingImageFilter() : m_TrialHeap( ) { this->ProcessObject::SetNumberOfRequiredInputs(0); OutputSizeType outputSize; outputSize.Fill( 16 ); typename LevelSetImageType::IndexType outputIndex; outputIndex.Fill( 0 ); this->m_OutputRegion.SetSize( outputSize ); this->m_OutputRegion.SetIndex( outputIndex ); this->m_OutputOrigin.Fill( 0.0 ); this->m_OutputSpacing.Fill( 1.0 ); this->m_OutputDirection.SetIdentity(); this->m_OverrideOutputInformation = false; this->m_AlivePoints = NULL; this->m_TrialPoints = NULL; this->m_ProcessedPoints = NULL; this->m_SpeedConstant = 1.0; this->m_InverseSpeed = -1.0; this->m_LabelImage = LabelImageType::New(); this->m_LargeValue = static_cast( NumericTraits::max() / 2.0 ); this->m_StoppingValue = static_cast( this->m_LargeValue ); this->m_CollectPoints = false; this->m_NormalizationFactor = 1.0; this->m_TopologyCheck = None; } template void FastMarchingImageFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "Alive points: " << this->m_AlivePoints.GetPointer() << std::endl; os << indent << "Trial points: " << this->m_TrialPoints.GetPointer() << std::endl; os << indent << "Speed constant: " << this->m_SpeedConstant << std::endl; os << indent << "Stopping value: " << this->m_StoppingValue << std::endl; os << indent << "Large Value: " << static_cast::PrintType>( this->m_LargeValue ) << std::endl; os << indent << "Normalization Factor: " << this->m_NormalizationFactor << std::endl; os << indent << "Topology check: "; switch( this->m_TopologyCheck ) { case None: { os << "None" << std::endl; } case NoHandles: { os << "No handles" << std::endl; } case Strict: { os << "Strict" << std::endl; } } os << indent << "Collect points: " << this->m_CollectPoints << std::endl; os << indent << "OverrideOutputInformation: "; os << this->m_OverrideOutputInformation << std::endl; os << indent << "OutputRegion: " << this->m_OutputRegion << std::endl; os << indent << "OutputOrigin: " << this->m_OutputOrigin << std::endl; os << indent << "OutputSpacing: " << this->m_OutputSpacing << std::endl; os << indent << "OutputDirection: " << this->m_OutputDirection << std::endl; } template void FastMarchingImageFilter ::GenerateOutputInformation() { // copy output information from input image Superclass::GenerateOutputInformation(); // use user-specified output information if ( this->GetInput() == NULL || this->m_OverrideOutputInformation ) { LevelSetPointer output = this->GetOutput(); output->SetLargestPossibleRegion( this->m_OutputRegion ); output->SetOrigin( this->m_OutputOrigin ); output->SetSpacing( this->m_OutputSpacing ); output->SetDirection( this->m_OutputDirection ); } } template void FastMarchingImageFilter ::EnlargeOutputRequestedRegion( DataObject *output ) { // enlarge the requested region of the output // to the whole data set TLevelSet * imgData; imgData = dynamic_cast( output ); if ( imgData ) { imgData->SetRequestedRegionToLargestPossibleRegion(); } else { // Pointer could not be cast to TLevelSet * itkWarningMacro(<< "itk::FastMarchingImageFilter" << "::EnlargeOutputRequestedRegion cannot cast " << typeid(output).name() << " to " << typeid(TLevelSet*).name() ); } } template void FastMarchingImageFilter ::Initialize( LevelSetImageType * output ) { // allocate memory for the output buffer output->SetBufferedRegion( output->GetRequestedRegion() ); output->Allocate(); // cache some buffered region information this->m_BufferedRegion = output->GetBufferedRegion(); this->m_StartIndex = this->m_BufferedRegion.GetIndex(); this->m_LastIndex = this->m_StartIndex + this->m_BufferedRegion.GetSize(); typename LevelSetImageType::OffsetType offset; offset.Fill( 1 ); this->m_LastIndex -= offset; // allocate memory for the LabelImage this->m_LabelImage->CopyInformation( output ); this->m_LabelImage->SetBufferedRegion( output->GetBufferedRegion() ); this->m_LabelImage->Allocate(); // Checking for handles only requires an image to keep track of // connected components. if( this->m_TopologyCheck == NoHandles ) { this->m_ConnectedComponentImage = ConnectedComponentImageType::New(); this->m_ConnectedComponentImage->SetOrigin( output->GetOrigin() ); this->m_ConnectedComponentImage->SetSpacing( output->GetSpacing() ); this->m_ConnectedComponentImage->SetRegions( output->GetBufferedRegion() ); this->m_ConnectedComponentImage->SetDirection( output->GetDirection() ); this->m_ConnectedComponentImage->Allocate(); this->m_ConnectedComponentImage->FillBuffer( 0 ); } // set all output value to infinity typedef ImageRegionIterator OutputIterator; OutputIterator outIt ( output, output->GetBufferedRegion() ); PixelType outputPixel; outputPixel = this->m_LargeValue; for ( outIt.GoToBegin(); !outIt.IsAtEnd(); ++outIt ) { outIt.Set( outputPixel ); } // set all points type to FarPoint typedef ImageRegionIterator< LabelImageType > LabelIterator; LabelIterator typeIt( this->m_LabelImage, this->m_LabelImage->GetBufferedRegion() ); for ( typeIt.GoToBegin(); !typeIt.IsAtEnd(); ++typeIt ) { typeIt.Set( FarPoint ); } // process input alive points AxisNodeType node; if ( this->m_AlivePoints ) { typename NodeContainer::ConstIterator pointsIter = this->m_AlivePoints->Begin(); typename NodeContainer::ConstIterator pointsEnd = this->m_AlivePoints->End(); for (; pointsIter != pointsEnd; ++pointsIter ) { // get node from alive points container node = pointsIter.Value(); // check if node index is within the output level set if ( !this->m_BufferedRegion.IsInside( node.GetIndex() ) ) { continue; } // make this an alive point this->m_LabelImage->SetPixel( node.GetIndex(), AlivePoint ); // if( this->m_TopologyCheck == NoHandles ) { this->m_ConnectedComponentImage->SetPixel( node.GetIndex(), NumericTraits::One ); } outputPixel = node.GetValue(); output->SetPixel( node.GetIndex(), outputPixel ); } } if( this->m_TopologyCheck == NoHandles ) { // Now create the connected component image and relabel such that labels // are 1, 2, 3, ... typedef ConnectedComponentImageFilter ConnectedComponentFilterType; typename ConnectedComponentFilterType::Pointer connecter = ConnectedComponentFilterType::New(); connecter->SetInput( this->m_ConnectedComponentImage ); typedef RelabelComponentImageFilter RelabelerType; typename RelabelerType::Pointer relabeler = RelabelerType::New(); relabeler->SetInput( connecter->GetOutput() ); relabeler->Update(); this->m_ConnectedComponentImage = relabeler->GetOutput(); } // make sure the heap is empty while ( !this->m_TrialHeap.empty() ) { this->m_TrialHeap.pop(); } // process the input trial points if ( this->m_TrialPoints ) { typename NodeContainer::ConstIterator pointsIter = this->m_TrialPoints->Begin(); typename NodeContainer::ConstIterator pointsEnd = this->m_TrialPoints->End(); for (; pointsIter != pointsEnd; ++pointsIter ) { // get node from trial points container node = pointsIter.Value(); // check if node index is within the output level set if ( !this->m_BufferedRegion.IsInside( node.GetIndex() ) ) { continue; } #ifdef ITK_USE_DEPRECATED_FAST_MARCHING // make this a trial point m_LabelImage->SetPixel( node.GetIndex(), TrialPoint ); #else // make this an initial trial point m_LabelImage->SetPixel( node.GetIndex(), InitialTrialPoint ); #endif outputPixel = node.GetValue(); output->SetPixel( node.GetIndex(), outputPixel ); this->m_TrialHeap.push( node ); } } // initialize indices if this->m_TopologyCheck is activated if( this->m_TopologyCheck != None ) { if( SetDimension == 2 ) { this->InitializeIndices2D(); } else if( SetDimension == 3 ) { this->InitializeIndices3D(); } else { itkExceptionMacro( "Topology checking is only valid for level set dimensions of 2 and 3" ); } } } template void FastMarchingImageFilter ::GenerateData() { LevelSetPointer output = this->GetOutput(); SpeedImageConstPointer speedImage = this->GetInput(); this->Initialize( output ); if ( this->m_CollectPoints ) { this->m_ProcessedPoints = NodeContainer::New(); } // process points on the heap AxisNodeType node; double currentValue; double oldProgress = 0; this->UpdateProgress( 0.0 ); // Send first progress event while ( !this->m_TrialHeap.empty() ) { // get the node with the smallest value node = this->m_TrialHeap.top(); this->m_TrialHeap.pop(); // does this node contain the current value ? currentValue = (double) output->GetPixel( node.GetIndex() ); if ( node.GetValue() != currentValue ) { continue; } // is this node already alive ? #ifdef ITK_USE_DEPRECATED_FAST_MARCHING if ( m_LabelImage->GetPixel( node.GetIndex() ) != TrialPoint ) #else if ( m_LabelImage->GetPixel( node.GetIndex() ) == AlivePoint ) #endif { continue; } if( this->m_TopologyCheck != None ) { bool wellComposednessViolation = this->DoesVoxelChangeViolateWellComposedness( node.GetIndex() ); bool strictTopologyViolation = this->DoesVoxelChangeViolateStrictTopology( node.GetIndex() ); if( this->m_TopologyCheck == Strict && ( wellComposednessViolation || strictTopologyViolation ) ) { output->SetPixel( node.GetIndex(), -0.00000001 ); this->m_LabelImage->SetPixel( node.GetIndex(), TopologyPoint ); continue; } if( this->m_TopologyCheck == NoHandles ) { if( wellComposednessViolation ) { output->SetPixel( node.GetIndex(), -0.00000001 ); this->m_LabelImage->SetPixel( node.GetIndex(), TopologyPoint ); continue; } if( strictTopologyViolation ) { // check for handles typename NeighborhoodIteratorType::RadiusType radius; radius.Fill( 1 ); NeighborhoodIteratorType ItL( radius, this->m_LabelImage, this->m_LabelImage->GetBufferedRegion() ); ItL.SetLocation( node.GetIndex() ); NeighborhoodIterator ItC( radius, this->m_ConnectedComponentImage, this->m_ConnectedComponentImage->GetBufferedRegion() ); ItC.SetLocation( node.GetIndex() ); typename ConnectedComponentImageType::PixelType minLabel = NumericTraits::Zero; typename ConnectedComponentImageType::PixelType otherLabel = NumericTraits::Zero; bool doesChangeCreateHandle = false; for( unsigned int d = 0; d < SetDimension; d++ ) { if( ItL.GetNext( d ) == AlivePoint && ItL.GetPrevious( d ) == AlivePoint ) { if( ItC.GetNext( d ) == ItC.GetPrevious( d ) ) { doesChangeCreateHandle = true; } else { minLabel = vnl_math_min( ItC.GetNext( d ), ItC.GetPrevious( d ) ); otherLabel = vnl_math_max( ItC.GetNext( d ), ItC.GetPrevious( d ) ); } break; } } if( doesChangeCreateHandle ) { output->SetPixel( node.GetIndex(), -0.0001 ); this->m_LabelImage->SetPixel( node.GetIndex(), TopologyPoint ); continue; } else { for( ItC.GoToBegin(); !ItC.IsAtEnd(); ++ItC ) { if( ItC.GetCenterPixel() == otherLabel ) { ItC.SetCenterPixel( minLabel ); } } } } } } if ( currentValue > this->m_StoppingValue ) { break; } if ( this->m_CollectPoints ) { this->m_ProcessedPoints->InsertElement( this->m_ProcessedPoints->Size(), node ); } // set this node as alive this->m_LabelImage->SetPixel( node.GetIndex(), AlivePoint ); // for topology handle checks, we need to update the connected // component image at the current node with the appropriate label. if( this->m_TopologyCheck == NoHandles ) { typename ConnectedComponentImageType::PixelType neighborhoodLabel = NumericTraits::Zero; typename NeighborhoodIteratorType::RadiusType radius; radius.Fill( 1 ); NeighborhoodIterator ItC( radius, this->m_ConnectedComponentImage, this->m_ConnectedComponentImage->GetBufferedRegion() ); ItC.SetLocation( node.GetIndex() ); for( unsigned int n = 0; n < ItC.Size(); n++ ) { if( n == static_cast( 0.5 * ItC.Size() ) ) { continue; } typename ConnectedComponentImageType::PixelType c = ItC.GetPixel( n ); if( c > 0 ) { neighborhoodLabel = c; break; } } if( neighborhoodLabel > 0 ) { ItC.SetCenterPixel( neighborhoodLabel ); } } // update its neighbors this->UpdateNeighbors( node.GetIndex(), speedImage, output ); // Send events every certain number of points. const double newProgress = currentValue / this->m_StoppingValue; if( newProgress - oldProgress > 0.01 ) // update every 1% { this->UpdateProgress( newProgress ); oldProgress = newProgress; if( this->GetAbortGenerateData() ) { this->InvokeEvent( AbortEvent() ); this->ResetPipeline(); ProcessAborted e(__FILE__,__LINE__); e.SetDescription("Process aborted."); e.SetLocation(ITK_LOCATION); throw e; } } } } template void FastMarchingImageFilter ::UpdateNeighbors( const IndexType& index, const SpeedImageType * speedImage, LevelSetImageType * output ) { IndexType neighIndex = index; for ( unsigned int j = 0; j < SetDimension; j++ ) { // update left neighbor if( index[j] > this->m_StartIndex[j] ) { neighIndex[j] = index[j] - 1; } #ifdef ITK_USE_DEPRECATED_FAST_MARCHING if ( m_LabelImage->GetPixel( neighIndex ) != AlivePoint ) #else unsigned char label = m_LabelImage->GetPixel( neighIndex ); if ( label != AlivePoint && label != InitialTrialPoint ) #endif { this->UpdateValue( neighIndex, speedImage, output ); } // update right neighbor if ( index[j] < this->m_LastIndex[j] ) { neighIndex[j] = index[j] + 1; } #ifdef ITK_USE_DEPRECATED_FAST_MARCHING if ( m_LabelImage->GetPixel( neighIndex ) != AlivePoint ) #else label = m_LabelImage->GetPixel( neighIndex ); if ( label != AlivePoint && label != InitialTrialPoint ) #endif { this->UpdateValue( neighIndex, speedImage, output ); } //reset neighIndex neighIndex[j] = index[j]; } } template double FastMarchingImageFilter ::UpdateValue( const IndexType& index, const SpeedImageType * speedImage, LevelSetImageType * output ) { IndexType neighIndex = index; typename TLevelSet::PixelType neighValue; PixelType outputPixel; AxisNodeType node; for ( unsigned int j = 0; j < SetDimension; j++ ) { node.SetValue( this->m_LargeValue ); // find smallest valued neighbor in this dimension for( int s = -1; s < 2; s = s + 2 ) { neighIndex[j] = index[j] + s; if( neighIndex[j] > this->m_LastIndex[j] || neighIndex[j] < this->m_StartIndex[j] ) { continue; } if ( this->m_LabelImage->GetPixel( neighIndex ) == AlivePoint ) { outputPixel = output->GetPixel( neighIndex ); neighValue = outputPixel; if( node.GetValue() > neighValue ) { node.SetValue( neighValue ); node.SetIndex( neighIndex ); } } } // put the minimum neighbor onto the heap this->m_NodesUsed[j] = node; this->m_NodesUsed[j].SetAxis(j); // reset neighIndex neighIndex[j] = index[j]; } // sort the local list std::sort( this->m_NodesUsed, this->m_NodesUsed + SetDimension ); // solve quadratic equation double aa, bb, cc; double solution = this->m_LargeValue; aa = 0.0; bb = 0.0; if ( speedImage ) { typedef typename SpeedImageType::PixelType SpeedPixelType; cc = (double) speedImage->GetPixel( index ) / this->m_NormalizationFactor; cc = -1.0 * vnl_math_sqr( 1.0 / cc ); } else { cc = this->m_InverseSpeed; } OutputSpacingType spacing = this->GetOutput()->GetSpacing(); double discrim; for ( unsigned int j = 0; j < SetDimension; j++ ) { node = this->m_NodesUsed[j]; if ( solution >= node.GetValue() ) { const int axis = node.GetAxis(); const double spaceFactor = vnl_math_sqr( 1.0 / spacing[axis] ); const double value = double(node.GetValue()); aa += spaceFactor; bb += value * spaceFactor; cc += vnl_math_sqr( value ) * spaceFactor; discrim = vnl_math_sqr( bb ) - aa * cc; if ( discrim < 0.0 ) { // Discriminant of quadratic eqn. is negative ExceptionObject err(__FILE__, __LINE__); err.SetLocation( ITK_LOCATION ); err.SetDescription( "Discriminant of quadratic equation is negative" ); throw err; } solution = ( vcl_sqrt( discrim ) + bb ) / aa; } else { break; } } if ( solution < this->m_LargeValue ) { // write solution to this->m_OutputLevelSet outputPixel = static_cast( solution ); output->SetPixel( index, outputPixel ); // insert point into trial heap this->m_LabelImage->SetPixel( index, TrialPoint ); node.SetValue( static_cast( solution ) ); node.SetIndex( index ); this->m_TrialHeap.push( node ); } return solution; } /** * Topology check functions */ template bool FastMarchingImageFilter ::DoesVoxelChangeViolateWellComposedness( IndexType idx ) { bool isChangeWellComposed = false; if( SetDimension == 2 ) { isChangeWellComposed = this->IsChangeWellComposed2D( idx ); } else // SetDimension == 3 { isChangeWellComposed = this->IsChangeWellComposed3D( idx ); } return !isChangeWellComposed; } template bool FastMarchingImageFilter ::DoesVoxelChangeViolateStrictTopology( IndexType idx ) { typename NeighborhoodIteratorType::RadiusType radius; radius.Fill( 1 ); NeighborhoodIteratorType It( radius, this->m_LabelImage, this->m_LabelImage->GetBufferedRegion() ); It.SetLocation( idx ); unsigned int numberOfCriticalC3Configurations = 0; unsigned int numberOfFaces = 0; for( unsigned int d = 0; d < SetDimension; d++ ) { if( It.GetNext( d ) == AlivePoint ) { numberOfFaces++; } if( It.GetPrevious( d ) == AlivePoint ) { numberOfFaces++; } if( It.GetNext( d ) == AlivePoint && It.GetPrevious( d ) == AlivePoint ) { numberOfCriticalC3Configurations++; } } if( numberOfCriticalC3Configurations > 0 && numberOfFaces % 2 == 0 && numberOfCriticalC3Configurations * 2 == numberOfFaces ) { return true; } return false; } template bool FastMarchingImageFilter ::IsChangeWellComposed2D( IndexType idx ) { typename NeighborhoodIteratorType::RadiusType radius; radius.Fill( 1 ); NeighborhoodIteratorType It( radius, this->m_LabelImage, this->m_LabelImage->GetBufferedRegion() ); It.SetLocation( idx ); Array neighborhoodPixels( 9 ); // Check for critical configurations: 4 90-degree rotations for ( unsigned int i = 0; i < 4; i++ ) { for ( unsigned int j = 0; j < 9; j++ ) { neighborhoodPixels[j] = ( It.GetPixel( this->m_RotationIndices[i][j] ) != AlivePoint ); if( this->m_RotationIndices[i][j] == 4 ) { neighborhoodPixels[j] = !neighborhoodPixels[j]; } } if( this->IsCriticalC1Configuration2D( neighborhoodPixels ) || this->IsCriticalC2Configuration2D( neighborhoodPixels ) || this->IsCriticalC3Configuration2D( neighborhoodPixels ) || this->IsCriticalC4Configuration2D( neighborhoodPixels ) ) { return false; } } // Check for critical configurations: 2 reflections // Note that the reflections for the C1 and C2 cases // are covered by the rotation cases above (except // in the case of FullInvariance == false. for ( unsigned int i = 0; i < 2; i++ ) { for ( unsigned int j = 0; j < 9; j++ ) { neighborhoodPixels[j] = ( It.GetPixel( this->m_ReflectionIndices[i][j] ) != AlivePoint ); if( this->m_ReflectionIndices[i][j] == 4 ) { neighborhoodPixels[j] = !neighborhoodPixels[j]; } } // if( !this->m_FullInvariance // && ( this->IsCriticalC1Configuration2D( neighborhoodPixels ) // || this->IsCriticalC2Configuration2D( neighborhoodPixels ) ) ) // { // return false; // } if( this->IsCriticalC3Configuration2D( neighborhoodPixels ) || this->IsCriticalC4Configuration2D( neighborhoodPixels ) ) { return false; } } return true; } template bool FastMarchingImageFilter ::IsCriticalC1Configuration2D( Array neighborhood ) { return ( !neighborhood[0] && neighborhood[1] && neighborhood[3] && !neighborhood[4] && !neighborhood[8] ); } template bool FastMarchingImageFilter ::IsCriticalC2Configuration2D( Array neighborhood ) { return ( !neighborhood[0] && neighborhood[1] && neighborhood[3] && !neighborhood[4] && neighborhood[8] && ( neighborhood[5] || neighborhood[7] ) ); } template bool FastMarchingImageFilter ::IsCriticalC3Configuration2D( Array neighborhood ) { return ( !neighborhood[0] && neighborhood[1] && neighborhood[3] && !neighborhood[4] && !neighborhood[5] && neighborhood[6] && !neighborhood[7] && neighborhood[8] ); } template bool FastMarchingImageFilter ::IsCriticalC4Configuration2D( Array neighborhood ) { return ( !neighborhood[0] && neighborhood[1] && neighborhood[3] && !neighborhood[4] && !neighborhood[5] && !neighborhood[6] && !neighborhood[7] && neighborhood[8] ); } template void FastMarchingImageFilter ::InitializeIndices2D() { this->m_RotationIndices[0].SetSize( 9 ); this->m_RotationIndices[1].SetSize( 9 ); this->m_RotationIndices[2].SetSize( 9 ); this->m_RotationIndices[3].SetSize( 9 ); this->m_RotationIndices[0][0] = 0; this->m_RotationIndices[0][1] = 1; this->m_RotationIndices[0][2] = 2; this->m_RotationIndices[0][3] = 3; this->m_RotationIndices[0][4] = 4; this->m_RotationIndices[0][5] = 5; this->m_RotationIndices[0][6] = 6; this->m_RotationIndices[0][7] = 7; this->m_RotationIndices[0][8] = 8; this->m_RotationIndices[1][0] = 2; this->m_RotationIndices[1][1] = 5; this->m_RotationIndices[1][2] = 8; this->m_RotationIndices[1][3] = 1; this->m_RotationIndices[1][4] = 4; this->m_RotationIndices[1][5] = 7; this->m_RotationIndices[1][6] = 0; this->m_RotationIndices[1][7] = 3; this->m_RotationIndices[1][8] = 6; this->m_RotationIndices[2][0] = 8; this->m_RotationIndices[2][1] = 7; this->m_RotationIndices[2][2] = 6; this->m_RotationIndices[2][3] = 5; this->m_RotationIndices[2][4] = 4; this->m_RotationIndices[2][5] = 3; this->m_RotationIndices[2][6] = 2; this->m_RotationIndices[2][7] = 1; this->m_RotationIndices[2][8] = 0; this->m_RotationIndices[3][0] = 6; this->m_RotationIndices[3][1] = 3; this->m_RotationIndices[3][2] = 0; this->m_RotationIndices[3][3] = 7; this->m_RotationIndices[3][4] = 4; this->m_RotationIndices[3][5] = 1; this->m_RotationIndices[3][6] = 8; this->m_RotationIndices[3][7] = 5; this->m_RotationIndices[3][8] = 2; this->m_ReflectionIndices[0].SetSize( 9 ); this->m_ReflectionIndices[1].SetSize( 9 ); this->m_ReflectionIndices[0][0] = 6; this->m_ReflectionIndices[0][1] = 7; this->m_ReflectionIndices[0][2] = 8; this->m_ReflectionIndices[0][3] = 3; this->m_ReflectionIndices[0][4] = 4; this->m_ReflectionIndices[0][5] = 5; this->m_ReflectionIndices[0][6] = 0; this->m_ReflectionIndices[0][7] = 1; this->m_ReflectionIndices[0][8] = 2; this->m_ReflectionIndices[1][0] = 2; this->m_ReflectionIndices[1][1] = 1; this->m_ReflectionIndices[1][2] = 0; this->m_ReflectionIndices[1][3] = 5; this->m_ReflectionIndices[1][4] = 4; this->m_ReflectionIndices[1][5] = 3; this->m_ReflectionIndices[1][6] = 8; this->m_ReflectionIndices[1][7] = 7; this->m_ReflectionIndices[1][8] = 6; } template bool FastMarchingImageFilter ::IsChangeWellComposed3D( IndexType idx ) { Array neighborhoodPixels( 8 ); typename NeighborhoodIteratorType::RadiusType radius; radius.Fill( 1 ); NeighborhoodIteratorType It( radius, this->m_LabelImage, this->m_LabelImage->GetRequestedRegion() ); It.SetLocation( idx ); // Check for C1 critical configurations for ( unsigned int i = 0; i < 12; i++ ) { for ( unsigned int j = 0; j < 4; j++ ) { neighborhoodPixels[j] = ( It.GetPixel( this->m_C1Indices[i][j] ) == AlivePoint ); if( this->m_C1Indices[i][j] == 13 ) { neighborhoodPixels[j] = !neighborhoodPixels[j]; } } if( this->IsCriticalC1Configuration3D( neighborhoodPixels ) ) { return false; } } // Check for C2 critical configurations for ( unsigned int i = 0; i < 8; i++ ) { for ( unsigned int j = 0; j < 8; j++ ) { neighborhoodPixels[j] = ( It.GetPixel( this->m_C2Indices[i][j] ) == AlivePoint ); if( this->m_C2Indices[i][j] == 13 ) { neighborhoodPixels[j] = !neighborhoodPixels[j]; } } if( this->IsCriticalC2Configuration3D( neighborhoodPixels ) ) { return false; } } return true; } template bool FastMarchingImageFilter ::IsCriticalC1Configuration3D( Array neighborhood ) { return ( ( neighborhood[0] && neighborhood[1] && !neighborhood[2] && !neighborhood[3] ) || ( !neighborhood[0] && !neighborhood[1] && neighborhood[2] && neighborhood[3] ) ); } template unsigned int FastMarchingImageFilter ::IsCriticalC2Configuration3D( Array neighborhood ) { // Check if Type 1 or Type 2 for ( unsigned int i = 0; i < 4; i++ ) { bool isC2 = false; if( neighborhood[2*i] == neighborhood[2*i+1] ) { isC2 = true; for ( unsigned int j = 0; j < 8; j++ ) { if( neighborhood[j] == neighborhood[2*i] && j != 2*i && j != 2*i+1 ) { isC2 = false; } } } if( isC2 ) { if( neighborhood[2*i] ) { return 1; } else { return 2; } } } return 0; } template void FastMarchingImageFilter ::InitializeIndices3D() { for ( unsigned int i = 0; i < 12; i++ ) { this->m_C1Indices[i].SetSize( 4 ); } for ( unsigned int i = 0; i < 8; i++ ) { this->m_C2Indices[i].SetSize( 8 ); } this->m_C1Indices[0][0] = 1; this->m_C1Indices[0][1] = 13; this->m_C1Indices[0][2] = 4; this->m_C1Indices[0][3] = 10; this->m_C1Indices[1][0] = 9; this->m_C1Indices[1][1] = 13; this->m_C1Indices[1][2] = 10; this->m_C1Indices[1][3] = 12; this->m_C1Indices[2][0] = 3; this->m_C1Indices[2][1] = 13; this->m_C1Indices[2][2] = 4; this->m_C1Indices[2][3] = 12; this->m_C1Indices[3][0] = 4; this->m_C1Indices[3][1] = 14; this->m_C1Indices[3][2] = 5; this->m_C1Indices[3][3] = 13; this->m_C1Indices[4][0] = 12; this->m_C1Indices[4][1] = 22; this->m_C1Indices[4][2] = 13; this->m_C1Indices[4][3] = 21; this->m_C1Indices[5][0] = 13; this->m_C1Indices[5][1] = 23; this->m_C1Indices[5][2] = 14; this->m_C1Indices[5][3] = 22; this->m_C1Indices[6][0] = 4; this->m_C1Indices[6][1] = 16; this->m_C1Indices[6][2] = 7; this->m_C1Indices[6][3] = 13; this->m_C1Indices[7][0] = 13; this->m_C1Indices[7][1] = 25; this->m_C1Indices[7][2] = 16; this->m_C1Indices[7][3] = 22; this->m_C1Indices[8][0] = 10; this->m_C1Indices[8][1] = 22; this->m_C1Indices[8][2] = 13; this->m_C1Indices[8][3] = 19; this->m_C1Indices[9][0] = 12; this->m_C1Indices[9][1] = 16; this->m_C1Indices[9][2] = 13; this->m_C1Indices[9][3] = 15; this->m_C1Indices[10][0] = 13; this->m_C1Indices[10][1] = 17; this->m_C1Indices[10][2] = 14; this->m_C1Indices[10][3] = 16; this->m_C1Indices[11][0] = 10; this->m_C1Indices[11][1] = 14; this->m_C1Indices[11][2] = 11; this->m_C1Indices[11][3] = 13; this->m_C2Indices[0][0] = 0; this->m_C2Indices[0][1] = 13; this->m_C2Indices[0][2] = 1; this->m_C2Indices[0][3] = 12; this->m_C2Indices[0][4] = 3; this->m_C2Indices[0][5] = 10; this->m_C2Indices[0][6] = 4; this->m_C2Indices[0][7] = 9; this->m_C2Indices[4][0] = 9; this->m_C2Indices[4][1] = 22; this->m_C2Indices[4][2] = 10; this->m_C2Indices[4][3] = 21; this->m_C2Indices[4][4] = 12; this->m_C2Indices[4][5] = 19; this->m_C2Indices[4][6] = 13; this->m_C2Indices[4][7] = 18; for ( unsigned int i = 1; i < 4; i++ ) { int addend; if( i == 2 ) { addend = 2; } else { addend = 1; } for ( unsigned int j = 0; j < 8; j++ ) { this->m_C2Indices[i ][j] = this->m_C2Indices[i-1][j] + addend; this->m_C2Indices[i+4][j] = this->m_C2Indices[i+3][j] + addend; } } } } // namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkGreenColormapFunctor.h000066400000000000000000000045141147325206600234250ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGreenColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:08:09 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGreenColormapFunctor_h #define __itkGreenColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class GreenColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT GreenColormapFunctor : public ColormapFunctor { public: typedef GreenColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: GreenColormapFunctor() {}; ~GreenColormapFunctor() {}; private: GreenColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkGreenColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkGreenColormapFunctor.txx000066400000000000000000000026571147325206600240270ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGreenColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGreenColormapFunctor_txx #define __itkGreenColormapFunctor_txx #include "itkGreenColormapFunctor.h" namespace itk { namespace Functor { template typename GreenColormapFunctor::RGBPixelType GreenColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = 0; pixel[1] = this->RescaleRGBComponentValue( value ); pixel[2] = 0; return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkGreyColormapFunctor.h000066400000000000000000000045031147325206600232710ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGreyColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGreyColormapFunctor_h #define __itkGreyColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class GreyColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT GreyColormapFunctor : public ColormapFunctor { public: typedef GreyColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: GreyColormapFunctor() {}; ~GreyColormapFunctor() {}; private: GreyColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkGreyColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkGreyColormapFunctor.txx000066400000000000000000000026671147325206600236760ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGreyColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGreyColormapFunctor_txx #define __itkGreyColormapFunctor_txx #include "itkGreyColormapFunctor.h" namespace itk { namespace Functor { template typename GreyColormapFunctor::RGBPixelType GreyColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( value ); pixel[1] = pixel[0]; pixel[2] = pixel[0]; return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkHSVColormapFunctor.h000066400000000000000000000044721147325206600230300ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkHSVColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkHSVColormapFunctor_h #define __itkHSVColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class HSVColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT HSVColormapFunctor : public ColormapFunctor { public: typedef HSVColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: HSVColormapFunctor() {}; ~HSVColormapFunctor() {}; private: HSVColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkHSVColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkHSVColormapFunctor.txx000066400000000000000000000036521147325206600234230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkHSVColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkHSVColormapFunctor_txx #define __itkHSVColormapFunctor_txx #include "itkHSVColormapFunctor.h" namespace itk { namespace Functor { template typename HSVColormapFunctor::RGBPixelType HSVColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. // Apply the color mapping. RealType red = vnl_math_abs( 5.0 * ( value - 0.5 ) ) - 5.0/6.0; red = vnl_math_min( red, 1.0 ); red = vnl_math_max( 0.0, red ); RealType green = -vnl_math_abs( 5.0 * ( value - 11.0/30.0 ) ) + 11.0/6.0; green = vnl_math_min( green, 1.0 ); green = vnl_math_max( 0.0, green ); RealType blue = -vnl_math_abs( 5.0 * ( value - 19.0/30.0 ) ) + 11.0/6.0; blue = vnl_math_min( blue, 1.0 ); blue = vnl_math_max( 0.0, blue ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkHotColormapFunctor.h000066400000000000000000000044721147325206600231220ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkHotColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkHotColormapFunctor_h #define __itkHotColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class HotColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT HotColormapFunctor : public ColormapFunctor { public: typedef HotColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: HotColormapFunctor() {}; ~HotColormapFunctor() {}; private: HotColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkHotColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkHotColormapFunctor.txx000066400000000000000000000034741147325206600235170ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkHotColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkHotColormapFunctor_txx #define __itkHotColormapFunctor_txx #include "itkHotColormapFunctor.h" namespace itk { namespace Functor { template typename HotColormapFunctor::RGBPixelType HotColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = 63.0/26.0 * value - 1.0/13.0; red = vnl_math_max( 0.0, red ); red = vnl_math_min( 1.0, red ); RealType green = 63.0/26.0 * value - 11.0/13.0; green = vnl_math_max( 0.0, green ); green = vnl_math_min( 1.0, green ); RealType blue = 4.5 * value - 3.5; blue = vnl_math_max( 0.0, blue ); blue = vnl_math_min( 1.0, blue ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkJetColormapFunctor.h000066400000000000000000000044721147325206600231120ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJetColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkJetColormapFunctor_h #define __itkJetColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class JetColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT JetColormapFunctor : public ColormapFunctor { public: typedef JetColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: JetColormapFunctor() {}; ~JetColormapFunctor() {}; private: JetColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkJetColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkJetColormapFunctor.txx000066400000000000000000000035761147325206600235120ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkJetColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkJetColormapFunctor_txx #define __itkJetColormapFunctor_txx #include "itkJetColormapFunctor.h" namespace itk { namespace Functor { template typename JetColormapFunctor::RGBPixelType JetColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = -vnl_math_abs( 3.75 * ( value - 0.75 ) ) + 1.625; red = vnl_math_min( red, 1.0 ); red = vnl_math_max( 0.0, red ); RealType green = -vnl_math_abs( 3.75 * ( value - 0.5 ) ) + 1.625; green = vnl_math_min( green, 1.0 ); green = vnl_math_max( 0.0, green ); RealType blue = -vnl_math_abs( 3.75 * ( value - 0.25 ) ) + 1.625; blue = vnl_math_min( blue, 1.0 ); blue = vnl_math_max( 0.0, blue ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkLabelContourImageFilter.h000066400000000000000000000150331147325206600240270ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabelContourImageFilter.h,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabelContourImageFilter_h #define __itkLabelContourImageFilter_h #include "itkInPlaceImageFilter.h" #include "itkImage.h" #include "itkConceptChecking.h" #include #include #include "itkProgressReporter.h" #include "itkBarrier.h" namespace itk { /** * \class LabelContourImageFilter * \brief Give the pixels on the border of an object. * * LabelContourImageFilter labels the pixels on the borders * of the objects in a binary image. * * \sa ImageToImageFilter */ template class ITK_EXPORT LabelContourImageFilter : public InPlaceImageFilter< TInputImage, TOutputImage > { public: /** * Standard "Self" & Superclass typedef. */ typedef LabelContourImageFilter Self; typedef InPlaceImageFilter< TInputImage, TOutputImage > Superclass; /** * Types from the Superclass */ typedef typename Superclass::InputImagePointer InputImagePointer; /** * Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef typename TOutputImage::PixelType OutputPixelType; typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::InternalPixelType InputInternalPixelType; itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); /** * Image typedef support */ typedef TInputImage InputImageType; typedef typename TInputImage::IndexType IndexType; typedef typename TInputImage::SizeType SizeType; typedef typename TInputImage::OffsetType OffsetType; typedef typename TInputImage::PixelType InputImagePixelType; typedef TOutputImage OutputImageType; typedef typename TOutputImage::RegionType RegionType; typedef typename TOutputImage::IndexType OutputIndexType; typedef typename TOutputImage::SizeType OutputSizeType; typedef typename TOutputImage::OffsetType OutputOffsetType; typedef typename TOutputImage::PixelType OutputImagePixelType; typedef std::list ListType; /** * Smart pointer typedef support */ typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** * Run-time type information (and related methods) */ itkTypeMacro(LabelContourImageFilter, ImageToImageFilter); /** * Method for creation through the object factory. */ itkNewMacro(Self); /** * Set/Get whether the connected components are defined strictly by * face connectivity or by face+edge+vertex connectivity. Default is * FullyConnectedOff. For objects that are 1 pixel wide, use * FullyConnectedOn. */ itkSetMacro(FullyConnected, bool); itkGetConstReferenceMacro(FullyConnected, bool); itkBooleanMacro(FullyConnected); // Concept checking -- input and output dimensions must be the same itkConceptMacro(SameDimension, (Concept::SameDimension)); /** */ itkSetMacro(BackgroundValue, OutputImagePixelType); itkGetMacro(BackgroundValue, OutputImagePixelType); protected: LabelContourImageFilter() { m_FullyConnected = false; m_BackgroundValue = NumericTraits< OutputImagePixelType >::Zero; m_NumberOfThreads = 0; this->SetInPlace( false ); } virtual ~LabelContourImageFilter() {} LabelContourImageFilter(const Self&) {} void PrintSelf(std::ostream& os, Indent indent) const; /** * Standard pipeline methods. */ void BeforeThreadedGenerateData (); void AfterThreadedGenerateData (); void ThreadedGenerateData (const RegionType& outputRegionForThread, int threadId); /** LabelContourImageFilter needs the entire input. Therefore * it must provide an implementation GenerateInputRequestedRegion(). * \sa ProcessObject::GenerateInputRequestedRegion(). */ void GenerateInputRequestedRegion(); /** LabelContourImageFilter will produce all of the output. * Therefore it must provide an implementation of * EnlargeOutputRequestedRegion(). * \sa ProcessObject::EnlargeOutputRequestedRegion() */ void EnlargeOutputRequestedRegion(DataObject *itkNotUsed(output)); private: OutputImagePixelType m_BackgroundValue; bool m_FullyConnected; // some additional types typedef typename TOutputImage::RegionType::SizeType OutSizeType; // types to support the run length encoding of lines class runLength { public: // run length information - may be a more type safe way of doing this long int length; typename InputImageType::IndexType where; // Index of the start of the run InputImagePixelType label; }; typedef std::vector lineEncoding; // the map storing lines typedef std::vector LineMapType; typedef std::vector OffsetVec; // the types to support union-find operations typedef std::vector UnionFindType; bool CheckNeighbors(const OutputIndexType &A, const OutputIndexType &B); void CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour); void SetupLineOffsets(OffsetVec &LineOffsets); void Wait() { if( m_NumberOfThreads > 1 ) { m_Barrier->Wait(); } } typename Barrier::Pointer m_Barrier; LineMapType m_LineMap; long m_NumberOfThreads; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLabelContourImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkLabelContourImageFilter.txx000066400000000000000000000334371147325206600244330ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabelContourImageFilter.txx,v $ Language: C++ Date: $Date: 2009/03/10 17:30:41 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabelContourImageFilter_txx #define __itkLabelContourImageFilter_txx #include "itkLabelContourImageFilter.h" #include "itkNumericTraits.h" // don't think we need the indexed version as we only compute the // index at the start of each run, but there isn't a choice #include "itkImageLinearConstIteratorWithIndex.h" #include "itkImageLinearIteratorWithIndex.h" #include "itkConstShapedNeighborhoodIterator.h" #include "itkImageRegionIterator.h" #include "itkMaskImageFilter.h" #include "itkConnectedComponentAlgorithm.h" namespace itk { template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // We need all the input. InputImagePointer input = const_cast(this->GetInput()); if( !input ) { return; } input->SetRequestedRegion( input->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::EnlargeOutputRequestedRegion(DataObject *) { this->GetOutput() ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() ); } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::BeforeThreadedGenerateData() { typename TOutputImage::Pointer output = this->GetOutput(); typename TInputImage::ConstPointer input = this->GetInput(); long nbOfThreads = this->GetNumberOfThreads(); if( itk::MultiThreader::GetGlobalMaximumNumberOfThreads() != 0 ) { nbOfThreads = vnl_math_min( this->GetNumberOfThreads(), itk::MultiThreader::GetGlobalMaximumNumberOfThreads() ); } // number of threads can be constrained by the region size, so call the SplitRequestedRegion // to get the real number of threads which will be used typename TOutputImage::RegionType splitRegion; // dummy region - just to call the following method nbOfThreads = this->SplitRequestedRegion(0, nbOfThreads, splitRegion); // std::cout << "nbOfThreads: " << nbOfThreads << std::endl; m_Barrier = Barrier::New(); m_Barrier->Initialize( nbOfThreads ); long pixelcount = output->GetRequestedRegion().GetNumberOfPixels(); long xsize = output->GetRequestedRegion().GetSize()[0]; long linecount = pixelcount/xsize; m_LineMap.clear(); m_LineMap.resize( linecount ); m_NumberOfThreads = nbOfThreads; } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::ThreadedGenerateData(const RegionType& outputRegionForThread, int threadId) { typename TOutputImage::Pointer output = this->GetOutput(); typename TInputImage::ConstPointer input = this->GetInput(); // create a line iterator typedef itk::ImageLinearConstIteratorWithIndex InputLineIteratorType; InputLineIteratorType inLineIt(input, outputRegionForThread); inLineIt.SetDirection(0); typedef itk::ImageLinearIteratorWithIndex OutputLineIteratorType; OutputLineIteratorType outLineIt(output, outputRegionForThread); outLineIt.SetDirection(0); // set the progress reporter to deal with the number of lines long pixelcountForThread = outputRegionForThread.GetNumberOfPixels(); long xsizeForThread = outputRegionForThread.GetSize()[0]; long linecountForThread = pixelcountForThread/xsizeForThread; ProgressReporter progress(this, threadId, linecountForThread * 2); // find the split axis IndexType outputRegionIdx = output->GetRequestedRegion().GetIndex(); IndexType outputRegionForThreadIdx = outputRegionForThread.GetIndex(); int splitAxis = 0; for( int i=0; iGetRequestedRegion().GetSize(); outputRegionSize[splitAxis] = outputRegionForThreadIdx[splitAxis] - outputRegionIdx[splitAxis]; long firstLineIdForThread = RegionType( outputRegionIdx, outputRegionSize ).GetNumberOfPixels() / xsizeForThread; long lineId = firstLineIdForThread; OffsetVec LineOffsets; SetupLineOffsets(LineOffsets); outLineIt.GoToBegin(); for( inLineIt.GoToBegin(); !inLineIt.IsAtEnd(); inLineIt.NextLine(), outLineIt.NextLine() ) { inLineIt.GoToBeginOfLine(); outLineIt.GoToBeginOfLine(); lineEncoding Line; while (! inLineIt.IsAtEndOfLine()) { InputPixelType PVal = inLineIt.Get(); runLength thisRun; long length=0; IndexType thisIndex; thisIndex = inLineIt.GetIndex(); //std::cout << thisIndex << std::endl; outLineIt.Set( m_BackgroundValue ); ++length; ++inLineIt; ++outLineIt; while( !inLineIt.IsAtEndOfLine() && inLineIt.Get() == PVal ) { outLineIt.Set( m_BackgroundValue ); ++length; ++inLineIt; ++outLineIt; } // create the run length object to go in the vector thisRun.length=length; thisRun.where = thisIndex; thisRun.label = PVal; Line.push_back(thisRun); } // std::cout << std::endl; m_LineMap[lineId] = Line; lineId++; progress.CompletedPixel(); } // wait for the other threads to complete that part this->Wait(); // now process the map and make appropriate entries in an equivalence // table // assert( linecount == m_ForegroundLineMap.size() ); long pixelcount = output->GetRequestedRegion().GetNumberOfPixels(); long xsize = output->GetRequestedRegion().GetSize()[0]; long linecount = pixelcount/xsize; long lastLineIdForThread = linecount; if( threadId != m_NumberOfThreads - 1 ) { lastLineIdForThread = firstLineIdForThread + RegionType( outputRegionIdx, outputRegionForThread.GetSize() ).GetNumberOfPixels() / xsizeForThread; } for(long ThisIdx = firstLineIdForThread; ThisIdx < lastLineIdForThread; ++ThisIdx) { if( !m_LineMap[ThisIdx].empty() ) { for (OffsetVec::const_iterator I = LineOffsets.begin(); I != LineOffsets.end(); ++I) { long NeighIdx = ThisIdx + (*I); // check if the neighbor is in the map if ( NeighIdx >= 0 && NeighIdx < linecount && !m_LineMap[NeighIdx].empty() ) { // Now check whether they are really neighbors bool areNeighbors = CheckNeighbors(m_LineMap[ThisIdx][0].where, m_LineMap[NeighIdx][0].where); if (areNeighbors) { // Compare the two lines CompareLines(m_LineMap[ThisIdx], m_LineMap[NeighIdx]); } } } } progress.CompletedPixel(); } } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::AfterThreadedGenerateData() { m_Barrier = NULL; m_LineMap.clear(); } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::SetupLineOffsets(OffsetVec &LineOffsets) { // Create a neighborhood so that we can generate a table of offsets // to "previous" line indexes // We are going to mis-use the neighborhood iterators to compute the // offset for us. All this messing around produces an array of // offsets that will be used to index the map typename TOutputImage::Pointer output = this->GetOutput(); typedef Image PretendImageType; typedef typename PretendImageType::RegionType::SizeType PretendSizeType; typedef typename PretendImageType::RegionType::IndexType PretendIndexType; typedef ConstShapedNeighborhoodIterator LineNeighborhoodType; typename PretendImageType::Pointer fakeImage; fakeImage = PretendImageType::New(); typename PretendImageType::RegionType LineRegion; //LineRegion = PretendImageType::RegionType::New(); OutSizeType OutSize = output->GetRequestedRegion().GetSize(); PretendSizeType PretendSize; // The first dimension has been collapsed for (unsigned int i = 0; iSetRegions( LineRegion ); PretendSizeType kernelRadius; kernelRadius.Fill(1); LineNeighborhoodType lnit(kernelRadius, fakeImage, LineRegion); setConnectivity( &lnit, m_FullyConnected ); typename LineNeighborhoodType::IndexListType ActiveIndexes; ActiveIndexes = lnit.GetActiveIndexList(); typename LineNeighborhoodType::IndexListType::const_iterator LI; PretendIndexType idx = LineRegion.GetIndex(); long offset = fakeImage->ComputeOffset( idx ); for (LI=ActiveIndexes.begin(); LI != ActiveIndexes.end(); LI++) { LineOffsets.push_back( fakeImage->ComputeOffset( idx + lnit.GetOffset( *LI ) ) - offset ); } LineOffsets.push_back( 0 ); // LineOffsets is the thing we wanted. } template< class TInputImage, class TOutputImage> bool LabelContourImageFilter< TInputImage, TOutputImage> ::CheckNeighbors(const OutputIndexType &A, const OutputIndexType &B) { // this checks whether the line encodings are really neighbors. The // first dimension gets ignored because the encodings are along that // axis OutputOffsetType Off = A - B; for (unsigned i = 1; i < OutputImageDimension; i++) { if (abs(Off[i]) > 1) { return(false); } } return(true); } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::CompareLines(lineEncoding ¤t, const lineEncoding &Neighbour) { bool sameLine = true; OutputOffsetType Off = current[0].where - Neighbour[0].where; for (unsigned i = 1; i < OutputImageDimension; i++) { if (Off[i] != 0) { sameLine = false; } } long offset = 0; if (m_FullyConnected || sameLine) { offset = 1; } // std::cout << "offset: " << offset << std::endl; typename TOutputImage::Pointer output = this->GetOutput(); typename lineEncoding::const_iterator nIt, mIt; typename lineEncoding::iterator cIt; mIt = Neighbour.begin(); // out marker iterator for (cIt = current.begin();cIt != current.end();++cIt) { if( cIt->label == m_BackgroundValue ) { continue; } //runLength cL = *cIt; long cStart = cIt->where[0]; // the start x position long cLast = cStart + cIt->length - 1; bool lineCompleted = false; for (nIt=mIt; nIt != Neighbour.end() && !lineCompleted; ++nIt) { if( nIt->label == cIt->label ) { continue; } //runLength nL = *nIt; long nStart = nIt->where[0]; long nLast = nStart + nIt->length - 1; // there are a few ways that neighbouring lines might overlap // neighbor S------------------E // current S------------------------E //------------- // neighbor S------------------E // current S----------------E //------------- // neighbor S------------------E // current S------------------E //------------- // neighbor S------------------E // current S-------E //------------- long ss1 = nStart - offset; // long ss2 = nStart + offset; // long ee1 = nLast - offset; long ee2 = nLast + offset; bool eq = false; long oStart = 0; long oLast = 0; // the logic here can probably be improved a lot if ((ss1 >= cStart) && (ee2 <= cLast)) { // case 1 // std::cout << "case 1" << std::endl; eq = true; oStart = ss1; oLast = ee2; } else if ((ss1 <= cStart) && (ee2 >= cLast)) { // case 4 // std::cout << "case 4" << std::endl; eq = true; oStart = cStart; oLast = cLast; } else if ((ss1 <= cLast) && (ee2 >= cLast)) { // case 2 // std::cout << "case 2" << std::endl; eq = true; oStart = ss1; oLast = cLast; } else if ((ss1 <= cStart) && (ee2 >= cStart)) { // case 3 // std::cout << "case 3" << std::endl; eq = true; oStart = cStart; oLast = ee2; } if (eq) { // std::cout << oStart << " " << oLast << std::endl; assert( oStart <= oLast ); IndexType idx = cIt->where; for( int x=oStart; x<=oLast; x++ ) { // std::cout << idx << std::endl; idx[0] = x; output->SetPixel( idx, cIt->label ); } if( oStart == cStart && oLast == cLast ) { lineCompleted = true; } } } } } template< class TInputImage, class TOutputImage> void LabelContourImageFilter< TInputImage, TOutputImage> ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "FullyConnected: " << m_FullyConnected << std::endl; os << indent << "BackgroundValue: " << static_cast::PrintType>(m_BackgroundValue) << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkManifoldIntegrationAlgorithm.cxx000066400000000000000000000507271147325206600255150ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit (ITK) Module: $RCSfile: itkManifoldIntegrationAlgorithm.cxx,v $ Language: C++ Date: $Date: 2006/10/13 19:21:27 $ Version: $Revision: 1.3 $ =========================================================================*/ #ifndef _itkManifoldIntegrationAlgorithm_cxx_ #define _itkManifoldIntegrationAlgorithm_cxx_ #include "itkSurfaceMeshCurvature.h" #include "vtkFeatureEdges.h" #include "vtkPointLocator.h" #include "vtkCellLocator.h" #include "vtkTriangleFilter.h" #include "vtkCleanPolyData.h" #include "vtkPolyDataConnectivityFilter.h" namespace itk { template ManifoldIntegrationAlgorithm::ManifoldIntegrationAlgorithm() { m_SurfaceMesh=NULL; m_QS = DijkstrasAlgorithmQueue::New(); m_MaxCost=vnl_huge_val(m_MaxCost); m_PureDist=false; // m_LabelCost=0; m_ParamWhileSearching=false; this->m_DistanceCostWeight=1; this->m_LabelCostWeight=0; } template float ManifoldIntegrationAlgorithm::dstarUestimate( typename TGraphSearchNode::Pointer G) { typedef itk::SurfaceMeshCurvature surfktype; typename surfktype::Pointer surfk=surfktype::New(); surfk->SetSurfacePatch(G); surfk->FindNeighborhood(); float dsu=(float) surfk->dstarUestimate(); return dsu; } template void ManifoldIntegrationAlgorithm::InitializeGraph3() { if (!m_SurfaceMesh) return; // Construct simple triangles vtkTriangleFilter* fltTriangle = vtkTriangleFilter::New(); fltTriangle->SetInput(m_SurfaceMesh); cout << " converting mesh to triangles " << endl; fltTriangle->Update(); /* Clean the data vtkCleanPolyData* fltCleaner = vtkCleanPolyData::New(); fltCleaner->SetInput(fltTriangle->GetOutput()); fltCleaner->SetTolerance(0); fltCleaner->ConvertPolysToLinesOn(); cout << " cleaning up triangle mesh " << endl; fltCleaner->Update(); // Go through and delete the cells that are of the wrong type //m_SurfaceMesh vtkPolyData* clean= fltCleaner->GetOutput(); for(vtkIdType i = clean->GetNumberOfCells();i > 0;i--) { if(clean->GetCellType(i-1) != VTK_TRIANGLE) clean->DeleteCell(i-1); } clean->BuildCells(); m_SurfaceMesh=clean;*/ m_SurfaceMesh=fltTriangle->GetOutput(); typedef float labelType; typedef std::vector LabelSetType; LabelSetType myLabelSet; vtkPoints* vtkpoints = m_SurfaceMesh->GetPoints(); vtkPointData *pd=m_SurfaceMesh->GetPointData(); int numPoints = vtkpoints->GetNumberOfPoints(); vtkDataArray* scs=pd->GetScalars(); m_GraphX.resize(numPoints); for(int i =0; i < numPoints; i++) { NodeLocationType loc; double* pt = vtkpoints->GetPoint(i); typename GraphSearchNode::Pointer G= GraphSearchNode::New(); G->SetUnVisited(); G->SetTotalCost(m_MaxCost); G->SetValue(scs->GetTuple1(i),3); /** here we put the label value */ labelType label = scs->GetTuple1(i); if( find( myLabelSet.begin(), myLabelSet.end(), label ) == myLabelSet.end() ) myLabelSet.push_back( label ); // std::cout << " label " << scs->GetTuple1(i) << std::endl; // std::cout << " set3 " << scs->GetTuple3(i) << std::endl; // std::cout << " set4 " << scs->GetTuple4(i) << std::endl; for (int j=0; jSetLocation(loc); G->SetPredecessor(NULL); G->m_NumberOfNeighbors=0; G->SetIdentity(i); m_GraphX[i]=G; } std::cout << " you have " << myLabelSet.size() << " labels " << std::endl; for ( unsigned int i=0; i < myLabelSet.size(); i++) std::cout <<" label " << myLabelSet[i] << std::endl; std::cout << " allocation of graph done "; // now loop through the cells to get triangles and also edges vtkCellArray* vtkcells = m_SurfaceMesh->GetPolys(); vtkIdType npts; vtkIdType* pts; /* count possible neighbors ... */ for(vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); ) { m_GraphX[pts[0]]->m_NumberOfNeighbors+=2; m_GraphX[pts[1]]->m_NumberOfNeighbors+=2; m_GraphX[pts[2]]->m_NumberOfNeighbors+=2; } for(int i =0; i < numPoints; i++) { m_GraphX[i]->m_Neighbors.resize(m_GraphX[i]->m_NumberOfNeighbors); // std::cout <<" Num Neigh " << i << " is " << m_GraphX[i]->m_NumberOfNeighbors << std::endl; m_GraphX[i]->m_NumberOfNeighbors=0; } for(vtkcells->InitTraversal(); vtkcells->GetNextCell(npts, pts); ) { m_GraphX[pts[0]]->m_Neighbors[ m_GraphX[pts[0]]->m_NumberOfNeighbors ]=m_GraphX[pts[1]]; m_GraphX[pts[0]]->m_NumberOfNeighbors++; m_GraphX[pts[0]]->m_Neighbors[ m_GraphX[pts[0]]->m_NumberOfNeighbors ]=m_GraphX[pts[2]]; m_GraphX[pts[0]]->m_NumberOfNeighbors++; m_GraphX[pts[1]]->m_Neighbors[ m_GraphX[pts[1]]->m_NumberOfNeighbors ]=m_GraphX[pts[0]]; m_GraphX[pts[1]]->m_NumberOfNeighbors++; m_GraphX[pts[1]]->m_Neighbors[ m_GraphX[pts[1]]->m_NumberOfNeighbors ]=m_GraphX[pts[2]]; m_GraphX[pts[1]]->m_NumberOfNeighbors++; m_GraphX[pts[2]]->m_Neighbors[ m_GraphX[pts[2]]->m_NumberOfNeighbors ]=m_GraphX[pts[0]]; m_GraphX[pts[2]]->m_NumberOfNeighbors++; m_GraphX[pts[2]]->m_Neighbors[ m_GraphX[pts[2]]->m_NumberOfNeighbors ]=m_GraphX[pts[1]]; m_GraphX[pts[2]]->m_NumberOfNeighbors++; } // now go through each node and make its list of neighbors unique // had to do this b/c it's easier than fixing the junk above ... too tired! for(int i =0; i < numPoints; i++) { std::vector neighlist; for ( unsigned int n=0; nm_NumberOfNeighbors; n++) { neighlist.push_back(m_GraphX[i]->m_Neighbors[n]->GetIdentity()); } std::sort( neighlist.begin(), neighlist.end() ); std::vector::iterator new_end_pos; new_end_pos = std::unique( neighlist.begin(),neighlist.end() ); neighlist.erase( new_end_pos, neighlist.end() ); // std::cout << " new leng " << neighlist.size() << " old " << len1 << std::endl; } } template void ManifoldIntegrationAlgorithm::InitializeGraph2() { if (!m_SurfaceMesh) return; /* // Construct simple triangles vtkTriangleFilter* fltTriangle = vtkTriangleFilter::New(); fltTriangle->SetInput(m_SurfaceMesh); cout << " converting mesh to triangles " << endl; fltTriangle->Update(); cout << " this mesh has " << fltTriangle->GetOutput()->GetNumberOfPoints() << " points" << endl; cout << " this mesh has " << fltTriangle->GetOutput()->GetNumberOfCells() << " cells" << endl; // Clean the data vtkCleanPolyData* fltCleaner = vtkCleanPolyData::New(); fltCleaner->SetInput(fltTriangle->GetOutput()); fltCleaner->SetTolerance(0); fltCleaner->ConvertPolysToLinesOn(); cout << " cleaning up triangle mesh " << endl; fltCleaner->Update(); // Go through and delete the cells that are of the wrong type //m_SurfaceMesh vtkPolyData* clean= fltCleaner->GetOutput(); for(vtkIdType i = clean->GetNumberOfCells();i > 0;i--) { if(clean->GetCellType(i-1) != VTK_TRIANGLE) clean->DeleteCell(i-1); } clean->BuildCells(); */ vtkFeatureEdges* fltEdge = vtkFeatureEdges::New(); fltEdge->BoundaryEdgesOff(); fltEdge->FeatureEdgesOff(); fltEdge->NonManifoldEdgesOff(); fltEdge->ManifoldEdgesOn(); fltEdge->ColoringOff(); fltEdge->SetInput(m_SurfaceMesh); cout << " extracting edges from the mesh" << endl; fltEdge->Update(); // Got the new poly data vtkPolyData* m_EdgePolys = fltEdge->GetOutput(); m_EdgePolys->BuildCells(); m_EdgePolys->BuildLinks(); unsigned int nEdges = m_EdgePolys->GetNumberOfLines(); cout << " number of edges (lines) : " << nEdges << endl; cout << " number of cells : " << m_EdgePolys->GetNumberOfCells() << endl; cout << " number if points : " << m_EdgePolys->GetNumberOfPoints() << endl; vtkPoints* vtkpoints = m_EdgePolys->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); m_GraphX.resize(numPoints); for(int i =0; i < numPoints; i++) { NodeLocationType loc; double* pt = vtkpoints->GetPoint(i); typename GraphSearchNode::Pointer G= GraphSearchNode::New(); G->SetUnVisited(); G->SetTotalCost(m_MaxCost); for (int j=0; jSetLocation(loc); G->SetPredecessor(NULL); G->m_NumberOfNeighbors=0; m_GraphX[i]=G; } std::cout << " allocation of graph done "; vtkIdType nPoints = 0; vtkIdType *xPoints = NULL; for(unsigned int i=0;iGetCellPoints(i, nPoints, xPoints); // Place the edge into the Edge structure assert(nPoints == 2); // Place the edge into the Edge structure // std::cout << " nPoints " << nPoints << std::endl; // std::cout << " pt " << xPoints[0] << " connects " << xPoints[1] << std::endl; assert(nPoints == 2); m_GraphX[xPoints[0]]->m_NumberOfNeighbors++; } std::cout << " counting nhood done "; // second, resize the vector for each G for (int i=0; im_Neighbors.resize(m_GraphX[i]->m_NumberOfNeighbors); m_GraphX[i]->m_NumberOfNeighbors=0; } for(unsigned int i=0;iGetCellPoints(i, nPoints, xPoints); // Place the edge into the Edge structure assert(nPoints == 2); m_GraphX[xPoints[0]]->m_Neighbors[ m_GraphX[xPoints[0]]->m_NumberOfNeighbors ]=m_GraphX[xPoints[1]]; m_GraphX[xPoints[0]]->m_NumberOfNeighbors++; } // vtkPolyDataConnectivityFilter* con = vtkPolyDataConnectivityFilter::New(); // con->SetExtractionModeToLargestRegion(); // con->SetInput(m_EdgePolys); // m_SurfaceMesh=con->GetOutput(); m_SurfaceMesh=m_EdgePolys; } template void ManifoldIntegrationAlgorithm::InitializeGraph() { if (!m_SurfaceMesh) return; std::cout << " Generate graph from surface mesh " << std::endl; // get size of the surface mesh vtkExtractEdges* edgeex=vtkExtractEdges::New(); edgeex->SetInput(m_SurfaceMesh); edgeex->Update(); vtkPolyData* edg1=edgeex->GetOutput(); vtkIdType nedg=edg1->GetNumberOfCells(); vtkIdType vers = m_SurfaceMesh->GetNumberOfPoints(); int nfac = m_SurfaceMesh->GetNumberOfPolys(); float g = 0.5 * (2.0 - vers + nedg - nfac); std::cout << " Genus " << g << std::endl; edg1->BuildCells(); // now cruise through all edges and add to each node's neighbor list // first, count the num of edges for each node // m_SurfaceMesh=edg1; vtkPoints* vtkpoints = edg1->GetPoints(); int numPoints = vtkpoints->GetNumberOfPoints(); m_GraphX.resize(numPoints); for(int i =0; i < numPoints; i++) { NodeLocationType loc; double* pt = vtkpoints->GetPoint(i); typename GraphSearchNode::Pointer G= GraphSearchNode::New(); G->SetUnVisited(); G->SetTotalCost(m_MaxCost); for (int j=0; jSetLocation(loc); G->SetPredecessor(NULL); G->m_NumberOfNeighbors=0; m_GraphX[i]=G; } std::cout << " allocation of graph done "; std::cout << " begin edg iter "; vtkIdType nPoints = 0; vtkIdType *xPoints = NULL; for(unsigned int i=0;iGetCellPoints(i, nPoints, xPoints); // Place the edge into the Edge structure // std::cout << " nPoints " << nPoints << std::endl; // std::cout << " pt " << xPoints[0] << " connects " << xPoints[1] << std::endl; assert(nPoints == 2); m_GraphX[xPoints[0]]->m_NumberOfNeighbors++; } std::cout << " counting nhood done "; // second, resize the vector for each G for (int i=0; im_Neighbors.resize(m_GraphX[i]->m_NumberOfNeighbors); m_GraphX[i]->m_NumberOfNeighbors=0; } for(unsigned int i=0;iGetCellPoints(i, nPoints, xPoints); // Place the edge into the Edge structure assert(nPoints == 2); m_GraphX[xPoints[0]]->m_Neighbors[ m_GraphX[xPoints[0]]->m_NumberOfNeighbors ]=m_GraphX[xPoints[1]]; m_GraphX[xPoints[0]]->m_NumberOfNeighbors++; } m_SurfaceMesh=edg1; return; } template void ManifoldIntegrationAlgorithm ::ConvertGraphBackToMesh() {// this is a sanity check } template void ManifoldIntegrationAlgorithm::InitializeQueue() { int n = m_QS->m_SourceNodes.size(); // GraphIteratorType GraphIterator( m_Graph, m_GraphRegion ); // GraphIterator.GoToBegin(); // m_GraphIndex = GraphIterator.GetIndex(); NodeLocationType loc; // make sure the graph contains the right pointers for (int i=0; i::Pointer G = m_QS->m_SourceNodes[i]; G->SetPredecessor(G); m_QS->m_Q.push(G); loc=G->GetLocation(); // for (int d=0;dSetPixel(m_GraphIndex,G); } for (unsigned int i=0; im_SinkNodes.size(); i++) { typename GraphSearchNode::Pointer G = m_QS->m_SinkNodes[i]; G->SetPredecessor(NULL); loc=G->GetLocation(); // for (int d=0;dSetPixel(m_GraphIndex,G); } m_SearchFinished=false; } /** * parameterize the boundary --- an estimate */ template bool ManifoldIntegrationAlgorithm ::ParameterizeBoundary( ManifoldIntegrationAlgorithm::SearchNodePointer rootNode ) { std::vector neighborlist; bool I_Am_A_Neighbor=false; SearchNodePointer neighbor=NULL; SearchNodePointer curNode=rootNode; // unsigned int rootnn=rootNode>m_NumberOfNeighbors; unsigned int ct=0; bool canparam=false; unsigned int qsz= this->m_QS->m_Q.size(); while ( ! I_Am_A_Neighbor && ct <= qsz*3 ) { unsigned int limit = curNode->m_NumberOfNeighbors; for (unsigned int i = 0; i < limit; i++) { neighbor=curNode->m_Neighbors[i]; bool inb=false; for ( unsigned int q=0; q 2 ) { I_Am_A_Neighbor=true; canparam=true; } if ( neighbor->IsInQueue() && !inb ) { // add to border list neighborlist.push_back(neighbor); curNode=neighbor; i=limit; } // add to border } // neighborhood ct++; }// while if ( neighborlist.size() >= this->m_BoundaryList.size() && canparam ) { neighborlist.push_back(rootNode); this->m_BoundaryList.clear(); this->m_BoundaryList.assign(neighborlist.begin(),neighborlist.end()); } // if ( ct > 0 && canparam) std::cout <<" qfrac " << this->m_BoundaryList.size() << " canp "<< canparam << " qsz " << qsz << " cost " << m_CurrentCost << std::endl; return canparam; } /** * Compute the local cost using Manhattan distance. */ template typename ManifoldIntegrationAlgorithm:: PixelType ManifoldIntegrationAlgorithm::MyLocalCost() { NodeLocationType dif=m_CurrentNode->GetLocation()-m_NeighborNode->GetLocation(); float mag = 0.0; for (int jj=0; jjGetValue(3)-m_NeighborNode->GetValue(3)); if ( dL > 0.5 ) dL=this->m_MaxCost*this->m_LabelCostWeight; else dL=0; return (mag*this->m_DistanceCostWeight+dL); } } template bool ManifoldIntegrationAlgorithm::TerminationCondition() { if (!m_QS->m_SinkNodes.empty()) { if (m_NeighborNode == m_QS->m_SinkNodes[0] && !m_SearchFinished ) { // std::cout << " FOUND SINK "; m_SearchFinished=true; m_NeighborNode->SetTotalCost( m_CurrentCost + MyLocalCost()); m_NeighborNode->SetPredecessor(m_CurrentNode); } } if (m_CurrentCost>=m_MaxCost) m_SearchFinished=true; return m_SearchFinished; } template void ManifoldIntegrationAlgorithm::SearchEdgeSet() { int i=0;//,j=0; for (i = 0; i < m_CurrentNode->m_NumberOfNeighbors; i++) { m_NeighborNode=m_CurrentNode->m_Neighbors[i]; // std::cout << " i " << i << " position " << m_NeighborNode->GetLocation() << endl; // std::cout << " i " << i << " position " << m_NeighborNode->GetLocation() << " label " << m_CurrentNode->GetValue() << endl; TerminationCondition(); if (!m_SearchFinished && m_CurrentNode != m_NeighborNode && !m_NeighborNode->GetDelivered()) { m_NewCost = m_CurrentCost + MyLocalCost(); CheckNodeStatus(); } } } template void ManifoldIntegrationAlgorithm::GetSearchBoundary() { unsigned int gsz=this->GetGraphSize(); for ( unsigned int j=0; jm_CurrentNode=this->m_GraphX[j]; if ( this->m_CurrentNode ) { cost=m_CurrentNode->GetTotalCost(); if ( cost <= this->m_MaxCost && (cost >= this->m_MaxCost-4) ) { this->m_BoundaryList.push_back(this->m_CurrentNode); } } } } template void ManifoldIntegrationAlgorithm::CheckNodeStatus() // checks a graph neighbor's status { NodeLocationType dif=m_CurrentNode->GetLocation()-m_NeighborNode->GetLocation(); // std::cout << " visited? " << m_NeighborNode->GetVisited() << // " old cost " << m_NeighborNode->GetTotalCost() << " new cost " <GetVisited() && ! m_NeighborNode->GetUnVisitable() ) { // set the cost and put into the queue m_NeighborNode->SetTotalCost(m_NewCost); float delt=fabs(m_CurrentNode->GetValue()-m_NeighborNode->GetValue());//*dif.magnitude(); m_NeighborNode->SetValue(m_CurrentNode->GetValue()+delt); m_NeighborNode->SetPredecessor(m_CurrentNode); m_NeighborNode->SetVisited(); float mag = 0.0; for (int jj=0; jjSetValue(m_CurrentNode->GetValue(2)+mag,2); // the actual manifold distance travelled // if ( m_QS->m_Q.push(m_NeighborNode); // } // else { // m_NeighborNode->SetUnVisitable(); // } // std::cout << " Pushing new node on " << m_NewCost << std::endl; } else if (m_NewCost < m_NeighborNode->GetTotalCost()&& ! m_NeighborNode->GetUnVisitable() ) { // std::cout << " Updating " << std::endl; float delt=fabs(m_CurrentNode->GetValue()-m_NeighborNode->GetValue());//*dif.magnitude(); m_NeighborNode->SetValue(m_CurrentNode->GetValue()+delt); m_NeighborNode->SetTotalCost(m_NewCost); m_NeighborNode->SetPredecessor(m_CurrentNode); float mag = 0.0; for (int jj=0; jjSetValue(m_CurrentNode->GetValue(2)+mag,2); // the actual manifold distance travelled m_QS->m_Q.push(m_NeighborNode); } } template void ManifoldIntegrationAlgorithm::FindPath() { if (m_QS->m_SourceNodes.empty()) { std::cout << "ERROR !! DID NOT SET SOURCE!!\n"; return; } // std::cout << "MI start find path " << " Q size " << m_QS->m_Q.size() << " \n"; while ( !m_SearchFinished && !m_QS->m_Q.empty() ) { m_CurrentNode=m_QS->m_Q.top(); m_CurrentCost=m_CurrentNode->GetTotalCost(); if ( this->m_ParamWhileSearching ) this->ParameterizeBoundary( this->m_CurrentNode ); m_QS->m_Q.pop(); if (!m_CurrentNode->GetDelivered()) { m_QS->IncrementTimer(); ///std::cout << " searching " << m_CurrentNode->GetLocation() << " \n"; this->SearchEdgeSet(); //if ( (m_CurrentNode->GetTimer() % 1.e5 ) == 0) // std::cout << " searched " << m_CurrentNode->GetTimer() << " \n"; } m_CurrentNode->SetDelivered(); } // end of while m_NumberSearched = (unsigned long) m_QS->GetTimer(); // std::cout << "Done with find path " << " Q size " << m_QS->m_Q.size() << //" num searched " << m_NumberSearched << " \n"; // std::cout << " Max Distance " << m_CurrentCost << std::endl; if ( ! this->m_ParamWhileSearching ) this->GetSearchBoundary(); return; } } #endif ants-1.9.2+svn680.dfsg/Temporary/itkManifoldIntegrationAlgorithm.h000077500000000000000000000254541147325206600251440ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit (ITK) Module: $RCSfile: itkManifoldIntegrationAlgorithm.h,v $ Language: C++ Date: $Date: 2008/03/11 16:33:05 $ Version: $Revision: 1.2 $ Copyright (c) 2001 Insight Consortium All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of the Insight Consortium, nor the names of any consortium members, nor of any contributors, may be used to endorse or promote products derived from this software without specific prior written permission. * Modified source versions must be plainly marked as such, and must not be misrepresented as being the original software. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================*/ #ifndef _itkManifoldIntegrationAlgorithm_h_ #define _itkManifoldIntegrationAlgorithm_h_ namespace itk { /** * \class ManifoldIntegrationAlgorithm * \brief General shortest path / greedy dynamic programming solver. */ template class ManifoldIntegrationAlgorithm : public itk::LightObject { public: typedef ManifoldIntegrationAlgorithm Self; typedef LightObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; itkTypeMacro(ManifoldIntegrationAlgorithm,LightObject); itkNewMacro(Self); // Computation Data typedef TGraphSearchNode SearchNode; /** dimension of the graph */ typedef typename SearchNode::Pointer SearchNodePointer; enum{GraphDimension=SearchNode::GraphDimension}; /** dimension of the graph */ typedef typename SearchNode::PixelType PixelType; /** pixel type for the cost */ typedef typename SearchNode::CoordRep CoordRep; /** coordinate type */ typedef typename DijkstrasAlgorithmQueue::Pointer QType; typedef typename DijkstrasAlgorithmQueue::NodeListType NodeListType; typedef typename TGraphSearchNode::NodeLocationType NodeLocationType; typedef vtkPolyData TriangulationType; typedef vtkPolyData* TriangulationTypePointer; typedef vector GraphType; // FUNCTIONS // estimate the metric tensor of the surface and also the (conjugate harmonic) function dstarU void GetSearchBoundary(); float dstarUestimate(SearchNodePointer G); void InitializeGraph3(); void InitializeGraph(); /** initializes all graph values appropriately */ void InitializeGraph2(); /** initializes all graph values appropriately */ void InitializeQueue(); /** initializes all queue values appropriately call AFTER source and sink are set*/ inline void EmptyQ() { m_QS->EmptyQ(); m_QS->EmptyPath(); } /* adds a source to the source set */ void SetSource(typename TGraphSearchNode::Pointer G) { G->SetTotalCost(0.0); m_QS->m_SourceNodes.push_back(G); }; // adds a sink to the sink set void SetSink(typename TGraphSearchNode::Pointer G) { m_QS->m_SinkNodes.push_back(G); } // Backtracks from the given node to its source node; float BackTrack(typename TGraphSearchNode::Pointer SinkNode) { m_QS->m_Path.clear(); typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetPredecessor(); if (!P) {std::cout << " ERROR NO PRED TO SINK " << std::endl; return 1.;} m_QS->m_Path.push_back(G); // if (P->GetAncestor() && G) // { // if (P->GetAncestor()->GetTotalCost() < G->GetTotalCost() ) P->SetAncestor(G); // } // else if (G) P->SetAncestor(G); // if (P->GetValue(1) < G->GetValue(1) ) P->SetValue(G->GetValue(1),1); while(P && G != P) { // std::cout << " Backtrack " << G->GetValue(0) << std::endl; G=P; P=G->GetPredecessor(); // if (P->GetValue(1) < G->GetValue(1) ) P->SetValue(G->GetValue(1),1); P->SetAncestor(G); if (P) m_QS->m_Path.push_back(P); } // m_QS->m_Path.push_back(P); // std::cout << " final cost " << P->GetTotalCost() << " high " << highcost << std::endl; if (!P) cout << " null pred "; //else cout << " pred == self \n"; return P->GetValue(2); } // Backtracks from the given node to its source node performing integration void IntegrateBackward(typename TGraphSearchNode::Pointer SinkNode) { typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetPredecessor(); float intval=0.0; G->SetTotalCost(intval); while(P && G != P) { // NodeLocationType dif=P->GetLocation()-G->GetLocation(); float dU = (P->GetValue()-G->GetValue()); intval+=dU; P->SetTotalCost(intval); G=P; P=G->GetPredecessor(); } // std::cout << " intval " << intval << " at " << G->GetLocation() << std::endl; if (!P) cout << " null pred "; //else cout << " pred == self \n"; return; } // Backtracks from the given node to its source node performing integration void IntegrateForward(typename TGraphSearchNode::Pointer SinkNode) { typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetAncestor(); float intval=0.0; G->SetTotalCost(intval); while(P && G != P) { // NodeLocationType dif=P->GetLocation()-G->GetLocation(); float dU = (P->GetValue()-G->GetValue()); intval+=dU; P->SetTotalCost(intval); G=P; P=G->GetAncestor(); } // std::cout << " intval " << intval << " at " << G->GetLocation() << std::endl; if (!P) cout << " null pred "; //else cout << " pred == self \n"; return; } // Inverse of backtrack - from the given node to its sink node; float ForwardTrack(typename TGraphSearchNode::Pointer SinkNode) { typename TGraphSearchNode::Pointer G=SinkNode; typename TGraphSearchNode::Pointer P=SinkNode->GetAncestor(); if (!P) return G->GetValue(2); // float highcost=G->GetTotalCost(); while(P && G != P && G) { G=P; P=G->GetAncestor(); if (!P) return G->GetValue(2); // if (P->GetTotalCost() > highcost) highcost=P->GetTotalCost(); } // SinkNode->SetValue(highcost); // if (!P) cout << " null pred "; //else cout << " pred == self \n"; return P->GetValue(2); } bool ParameterizeBoundary( SearchNodePointer); bool TerminationCondition(); /** decides when the algorithm stops */ virtual void SearchEdgeSet(); /** loops over the neighbors in the graph */ void CheckNodeStatus(); /** checks if the node has been explored already, its cost, etc. */ virtual PixelType MyLocalCost(); /* computes the local cost */ /* alternatively, we could pass the function as a template parameter or set a function pointer. the latter method is used in dijkstrasegment. */ virtual void FindPath(); /* runs the algorithm */ inline unsigned int GetPathSize() { return m_QS->m_Path.size(); } inline void EmptyPath() { m_QS->m_Path.clear(); } inline typename TGraphSearchNode::Pointer GetPathAtIndex(unsigned int i) { return m_QS->m_Path[i]; } inline typename TGraphSearchNode::Pointer GetNeighborNode() { return m_NeighborNode; } inline typename TGraphSearchNode::Pointer GetCurrentNode() { return m_CurrentNode; } PixelType GetMaxCost(){ return this->m_MaxCost; } void SetMaxCost(PixelType m) { this->m_MaxCost=m; } void ResetMaxCost() { this->m_MaxCost=vnl_huge_val(this->m_MaxCost);} inline void SetDistanceCostWeight(float d) { this->m_DistanceCostWeight=d; } inline void SetLabelCostWeight(float d) { this->m_LabelCostWeight=d; } inline void SetWeights(float a, float b, float c) { this->m_MaxCost=a; this->m_DistanceCostWeight=b; this->m_LabelCostWeight=c; } inline void PrintWeights() { std::cout << this->m_MaxCost << " " << this->m_DistanceCostWeight << " " << this->m_LabelCostWeight << std::endl; } void SetSearchFinished(bool m){ m_SearchFinished=m;} /** sets the boolean that indicates if the algorithm is done */ void SetSurfaceMesh( TriangulationTypePointer mesh) { m_SurfaceMesh=mesh;} TriangulationTypePointer GetSurfaceMesh( ) { return m_SurfaceMesh;} SearchNodePointer GetGraphNode(int i) { return m_GraphX[i]; } int GetGraphSize() { return m_GraphX.size(); } // sanity check to see if mesh to graph conversion is ok // see if genus is the same void ConvertGraphBackToMesh(); void SetParamWhileSearching( bool b ) { this->m_ParamWhileSearching=b; } std::vector m_BoundaryList; protected: QType m_QS; vector < unsigned int > m_EdgeTemplate;/** defines neighborhood connectivity */ typename TGraphSearchNode::Pointer m_PredecessorNode; /** holds the predecessor node */ typename TGraphSearchNode::Pointer m_CurrentNode; /** holds the current node */ typename TGraphSearchNode::Pointer m_NeighborNode; /** holds the current neighbor node */ bool m_PureDist; bool m_SearchFinished; PixelType m_NewCost; PixelType m_CurrentCost; float m_MaxCost; // This creates an insurmountable barrier unless all costs are max float m_DistanceCostWeight; float m_LabelCostWeight; GraphType m_GraphX; unsigned long m_NumberSearched; TriangulationTypePointer m_SurfaceMesh; bool m_ParamWhileSearching; ManifoldIntegrationAlgorithm(); ~ManifoldIntegrationAlgorithm(){}; private: ManifoldIntegrationAlgorithm(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkManifoldIntegrationAlgorithm.cxx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkOverUnderColormapFunctor.h000066400000000000000000000045461147325206600243030ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkOverUnderColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkOverUnderColormapFunctor_h #define __itkOverUnderColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class OverUnderColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT OverUnderColormapFunctor : public ColormapFunctor { public: typedef OverUnderColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: OverUnderColormapFunctor() {}; ~OverUnderColormapFunctor() {}; private: OverUnderColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkOverUnderColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkOverUnderColormapFunctor.txx000066400000000000000000000034751147325206600246770ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkOverUnderColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkOverUnderColormapFunctor_txx #define __itkOverUnderColormapFunctor_txx #include "itkOverUnderColormapFunctor.h" namespace itk { namespace Functor { template typename OverUnderColormapFunctor::RGBPixelType OverUnderColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = value; RealType green = value; RealType blue = value; if( value == 0.0 ) { // pixel is saturated in the dark red = 0.0; green = 0.0; blue = 1.0; } else if( value == 1.0 ) { // pixel is saturated in the white red = 1.0; green = 0.0; blue = 0.0; } // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkRedColormapFunctor.h000066400000000000000000000044721147325206600231020ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkRedColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkRedColormapFunctor_h #define __itkRedColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class RedColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT RedColormapFunctor : public ColormapFunctor { public: typedef RedColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: RedColormapFunctor() {}; ~RedColormapFunctor() {}; private: RedColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkRedColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkRedColormapFunctor.txx000066400000000000000000000026431147325206600234740ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkRedColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkRedColormapFunctor_txx #define __itkRedColormapFunctor_txx #include "itkRedColormapFunctor.h" namespace itk { namespace Functor { template typename RedColormapFunctor::RGBPixelType RedColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( value ); pixel[1] = 0; pixel[2] = 0; return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkScalarToRGBColormapImageFilter.h000066400000000000000000000116431147325206600252010ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkScalarToRGBColormapImageFilter.h,v $ Language: C++ Date: $Date: 2009-05-15 12:51:13 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkScalarToRGBColormapImageFilter_h #define __itkScalarToRGBColormapImageFilter_h #include "itkImageToImageFilter.h" #include "itkColormapFunctor.h" namespace itk { /** \class ScalarToRGBColormapImageFilter * \brief Implements pixel-wise intensity->rgb mapping operation on one image. * * This class is parameterized over the type of the input image and * the type of the output image. * * ScalarToRGBColormapImageFilter * * \sa BinaryFunctorImageFilter TernaryFunctorImageFilter * * \ingroup IntensityImageFilters Multithreaded */ template class ITK_EXPORT ScalarToRGBColormapImageFilter : public ImageToImageFilter { public: /** Standard class typedefs. */ typedef ScalarToRGBColormapImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( ScalarToRGBColormapImageFilter, ImageToImageFilter ); /** Some typedefs. */ typedef TInputImage InputImageType; typedef typename InputImageType::ConstPointer InputImagePointer; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::PixelType InputImagePixelType; typedef TOutputImage OutputImageType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename OutputImageType::PixelType OutputImagePixelType; typedef Functor::ColormapFunctor ColormapType; /** * Set/Get the colormap object. */ typename ColormapType::Pointer GetColormap() { return m_Colormap; } void SetColormap( ColormapType *colormap ) { if ( m_Colormap != colormap ) { m_Colormap = colormap; this->Modified(); } } /** * Enum type that provides for an easy interface to existing colormaps. */ typedef enum { Red, Green, Blue, Grey, Hot, Cool, Spring, Summer, Autumn, Winter, Copper, Jet, HSV, OverUnder } ColormapEnumType; void SetColormap( ColormapEnumType ); /** * Set/Get UseInputImageExtremaForScaling. If 'true', the colormap uses the * min and max values from the image to scale appropriately. Otherwise, * these values can be set in the colormap manually. */ itkSetMacro( UseInputImageExtremaForScaling, bool ); itkGetConstMacro( UseInputImageExtremaForScaling, bool ); itkBooleanMacro( UseInputImageExtremaForScaling ); protected: ScalarToRGBColormapImageFilter(); virtual ~ScalarToRGBColormapImageFilter() {}; void PrintSelf( std::ostream& os, Indent indent ) const; /** ScalarToRGBColormapImageFilter * can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() routine * which is called for each processing thread. The output image data is * allocated automatically by the superclass prior to calling * ThreadedGenerateData(). ThreadedGenerateData can only write to the * portion of the output image specified by the parameter * "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, int threadId ); /** Process to execute before entering the multithreaded section */ void BeforeThreadedGenerateData(); private: ScalarToRGBColormapImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typename ColormapType::Pointer m_Colormap; bool m_UseInputImageExtremaForScaling; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkScalarToRGBColormapImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkScalarToRGBColormapImageFilter.txx000066400000000000000000000214471147325206600256000ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkScalarToRGBColormapImageFilter.txx,v $ Language: C++ Date: $Date: 2009-05-15 12:51:14 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkScalarToRGBColormapImageFilter_txx #define __itkScalarToRGBColormapImageFilter_txx #include "itkScalarToRGBColormapImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkProgressReporter.h" #include "itkRedColormapFunctor.h" #include "itkGreenColormapFunctor.h" #include "itkBlueColormapFunctor.h" #include "itkGreyColormapFunctor.h" #include "itkHotColormapFunctor.h" #include "itkCoolColormapFunctor.h" #include "itkSpringColormapFunctor.h" #include "itkSummerColormapFunctor.h" #include "itkAutumnColormapFunctor.h" #include "itkWinterColormapFunctor.h" #include "itkCopperColormapFunctor.h" #include "itkHSVColormapFunctor.h" #include "itkJetColormapFunctor.h" #include "itkOverUnderColormapFunctor.h" namespace itk { /** * Constructor */ template ScalarToRGBColormapImageFilter ::ScalarToRGBColormapImageFilter() { this->SetNumberOfRequiredInputs( 1 ); this->m_UseInputImageExtremaForScaling = true; typedef Functor::GreyColormapFunctor< InputImagePixelType, OutputImagePixelType> DefaultColormapType; typename DefaultColormapType::Pointer greyColormap = DefaultColormapType::New(); this->SetColormap( greyColormap ); } /** * BeforeThreadedGenerateData */ template void ScalarToRGBColormapImageFilter ::BeforeThreadedGenerateData() { if( this->m_UseInputImageExtremaForScaling == true ) { ImageRegionConstIterator It( this->GetInput(), this->GetInput()->GetRequestedRegion() ); InputImagePixelType minimumValue = NumericTraits::max(); InputImagePixelType maximumValue = NumericTraits::min(); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { InputImagePixelType value = It.Get(); if( value < minimumValue ) { minimumValue = value; } if( value > maximumValue ) { maximumValue = value; } } this->GetColormap()->SetMinimumInputValue( minimumValue ); this->GetColormap()->SetMaximumInputValue( maximumValue ); } } /** * ThreadedGenerateData performs the pixel-wise mapping */ template void ScalarToRGBColormapImageFilter ::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId ) { InputImagePointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); // Define the portion of the input to walk for this thread, using // the CallCopyOutputRegionToInputRegion method allows for the input // and output images to be different dimensions InputImageRegionType inputRegionForThread; this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread); // Define the iterators ImageRegionConstIterator inputIt(inputPtr, inputRegionForThread); ImageRegionIterator outputIt(outputPtr, outputRegionForThread); ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels()); inputIt.GoToBegin(); outputIt.GoToBegin(); while( !inputIt.IsAtEnd() ) { outputIt.Set( this->m_Colormap->operator()( inputIt.Get() ) ); ++inputIt; ++outputIt; progress.CompletedPixel(); // potential exception thrown here } } template void ScalarToRGBColormapImageFilter ::SetColormap( ColormapEnumType map ) { switch( map ) { case Red: { typedef Functor::RedColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Green: { typedef Functor::GreenColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Blue: { typedef Functor::BlueColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Grey: default: { typedef Functor::GreyColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Hot: { typedef Functor::HotColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Cool: { typedef Functor::CoolColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Spring: { typedef Functor::SpringColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Summer: { typedef Functor::SummerColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Autumn: { typedef Functor::AutumnColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Winter: { typedef Functor::WinterColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Copper: { typedef Functor::CopperColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case Jet: { typedef Functor::JetColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case HSV: { typedef Functor::HSVColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } case OverUnder: { typedef Functor::OverUnderColormapFunctor< InputImagePixelType, OutputImagePixelType> SpecificColormapType; typename SpecificColormapType::Pointer colormap = SpecificColormapType::New(); this->SetColormap( colormap ); break; } } } template void ScalarToRGBColormapImageFilter ::PrintSelf( std::ostream& os, Indent indent ) const { this->Superclass::PrintSelf(os, indent); os << indent << "Class Name: " << this->GetNameOfClass( ) << std::endl; if( this->m_Colormap.IsNotNull() ) { os << indent << "Colormap " << this->m_Colormap << std::endl; } else { os << indent << "Colormap is NULL " << std::endl; } os << indent << "Use Input Image Extrema for Scaling " << this->m_UseInputImageExtremaForScaling << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkSpringColormapFunctor.h000066400000000000000000000045251147325206600236310ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSpringColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkSpringColormapFunctor_h #define __itkSpringColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class SpringColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT SpringColormapFunctor : public ColormapFunctor { public: typedef SpringColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: SpringColormapFunctor() {}; ~SpringColormapFunctor() {}; private: SpringColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSpringColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkSpringColormapFunctor.txx000066400000000000000000000030741147325206600242230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSpringColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkSpringColormapFunctor_txx #define __itkSpringColormapFunctor_txx #include "itkSpringColormapFunctor.h" namespace itk { namespace Functor { template typename SpringColormapFunctor::RGBPixelType SpringColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = 1.0; RealType green = value; RealType blue = 1.0 - value; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkSummerColormapFunctor.h000066400000000000000000000045251147325206600236370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSummerColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkSummerColormapFunctor_h #define __itkSummerColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class SummerColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT SummerColormapFunctor : public ColormapFunctor { public: typedef SummerColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: SummerColormapFunctor() {}; ~SummerColormapFunctor() {}; private: SummerColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSummerColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkSummerColormapFunctor.txx000066400000000000000000000031021147325206600242210ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSummerColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkSummerColormapFunctor_txx #define __itkSummerColormapFunctor_txx #include "itkSummerColormapFunctor.h" namespace itk { namespace Functor { template typename SummerColormapFunctor::RGBPixelType SummerColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color mapping. RealType red = value; RealType green = 0.5 * value + 0.5; RealType blue = 0.4; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/itkWinterColormapFunctor.h000066400000000000000000000045251147325206600236370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWinterColormapFunctor.h,v $ Language: C++ Date: $Date: 2009-05-15 19:22:31 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWinterColormapFunctor_h #define __itkWinterColormapFunctor_h #include "itkColormapFunctor.h" namespace itk { namespace Functor { /** * \class WinterColormapFunctor * \brief Function object which maps a scalar value into an RGB colormap value. * * \author Nicholas Tustison, Hui Zhang, Gaetan Lehmann, Paul Yushkevich and ̈James C. Gee * * This code was contributed in the Insight Journal paper: * * "Meeting Andy Warhol Somewhere Over the Rainbow: RGB Colormapping and ITK" * http://www.insight-journal.org/browse/publication/285 * http://hdl.handle.net/1926/1452 * */ template< class TScalar, class TRGBPixel > class ITK_EXPORT WinterColormapFunctor : public ColormapFunctor { public: typedef WinterColormapFunctor Self; typedef ColormapFunctor Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef typename Superclass::RGBPixelType RGBPixelType; typedef typename Superclass::ScalarType ScalarType; typedef typename Superclass::RealType RealType; virtual RGBPixelType operator()( const TScalar & ) const; protected: WinterColormapFunctor() {}; ~WinterColormapFunctor() {}; private: WinterColormapFunctor(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace functor } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkWinterColormapFunctor.txx" #endif #endif ants-1.9.2+svn680.dfsg/Temporary/itkWinterColormapFunctor.txx000066400000000000000000000031701147325206600242260ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWinterColormapFunctor.txx,v $ Language: C++ Date: $Date: 2009-05-15 02:47:59 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWinterColormapFunctor_txx #define __itkWinterColormapFunctor_txx #include "itkWinterColormapFunctor.h" namespace itk { namespace Functor { template typename WinterColormapFunctor::RGBPixelType WinterColormapFunctor ::operator()( const TScalar & v ) const { // Map the input scalar between [0, 1]. RealType value = this->RescaleInputValue( v ); // Apply the color map. RealType red = 0.0; RealType green = value; RealType blue = 1.0 - 0.5 * value; // Set the rgb components after rescaling the values. RGBPixelType pixel; pixel[0] = this->RescaleRGBComponentValue( red ); pixel[1] = this->RescaleRGBComponentValue( green ); pixel[2] = this->RescaleRGBComponentValue( blue ); return pixel; } } // end namespace Functor } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Temporary/topological_numbers.h000066400000000000000000000300031147325206600226560ustar00rootroot00000000000000#ifndef TOPO_INCLUDED #define TOPO_INCLUDED /* This file provides some code to compute the topological numbers introduced by Giles Bertrand and Gregoire Malandin. This code is the result of my understanding of their paper, and is not optimized. In fact, it is possible to generate look-up tables to greatly speed-up computations... Given a binary 3*3*3 neighborhood ( the structure TOPOLOGICAL_NEIGHBORHOOD or NBH ) and a pair of consistent connectivities ( 1=(6+,18), 2=(18,6+), 3=(6,26), 4=(26,6) ), the function checkTn computes the topological number associated with the structure NBH and a specific connectivity. The fucntion checkSimple checks if the point is simple or not (see definitions below). The topological neighborhood NBH has to be initialized as a binary object 0-1, where 1 represents the Foreground Object and 0 the Background Object. The first connectivity in the pair of digital connectivities ( 1=(6+,18), 2=(18,6+), 3=(6,26), 4=(26,6) ) refers to the Foreground Object, the second one to the Background Object */ /* ////////////////////////////////////////////////////////////////////// // COMPATIBLE CONNECTIVITIES / TOPOLOGICAL NUMBERS // // TOPOLOGICAL CONVENTION // 0: No topological constraint // 1: (6+,18) // 2: (18,6+) // 3: (6,26) // 4: (26,6) // default: (6+,18) //////////////////////////////////////////////////////////////////// */ typedef unsigned char TOPOLOGICAL_NEIGHBORHOOD[3][3][3]; #define NBH TOPOLOGICAL_NEIGHBORHOOD #define TMP 100 #define MAXIMUM_NUMBER_OF_COMPONENTS 10 //maximum number of components in a NBH #define MAX_COMP MAXIMUM_NUMBER_OF_COMPONENTS /*The connectivity number is equal to the maximum allowed distance (||.||1 norm) used to generate the topological neighborhood*/ int connectivityNumber(int connectivity) { int con; switch(connectivity) { case 1: /*for the connectivity 1 [=(6+,18)], the topological neighborhood of a point x is defined by {x / ||a-x||1<=1 } -> the 6 neighborhood! */ con=1; break; case 2: /*the 18-neighborhood*/ con=2; break; case 3: /*the 6-heighborhood*/ con=1; break; case 4: /*the 26-neighborhood*/ con=3; break; default: con=1; break; } return con; } //Digital topology requires a pair of compatible connectivities int associatedConnectivity(int connectivity) { switch(connectivity) { case 1: return 2; break; case 2: return 1; break; case 3: return 4; break; case 4: return 3; break; default: return 2; break; } return 0; } NBH* reverseNBH(NBH* nbh_src,NBH *nbh_dst) { NBH *nbh; int i,j,k; if(nbh_dst) nbh=nbh_dst; else nbh=(NBH*)malloc(sizeof(NBH)); for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) if((*nbh_src)[i][j][k]) (*nbh)[i][j][k]=0; else (*nbh)[i][j][k]=1; return nbh; } NBH *N_6_1(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; if(!nbh_dst) { nbh=(NBH*)calloc(1,sizeof(NBH)); if((*nbh_src)[0][1][1]) (*nbh)[0][1][1]=1; if((*nbh_src)[2][1][1]) (*nbh)[2][1][1]=1; if((*nbh_src)[1][0][1]) (*nbh)[1][0][1]=1; if((*nbh_src)[1][2][1]) (*nbh)[1][2][1]=1; if((*nbh_src)[1][1][0]) (*nbh)[1][1][0]=1; if((*nbh_src)[1][1][2]) (*nbh)[1][1][2]=1; return nbh; } else nbh=nbh_dst; if((*nbh_src)[0][1][1]) (*nbh)[0][1][1]=TMP; if((*nbh_src)[2][1][1]) (*nbh)[2][1][1]=TMP; if((*nbh_src)[1][0][1]) (*nbh)[1][0][1]=TMP; if((*nbh_src)[1][2][1]) (*nbh)[1][2][1]=TMP; if((*nbh_src)[1][1][0]) (*nbh)[1][1][0]=TMP; if((*nbh_src)[1][1][2]) (*nbh)[1][1][2]=TMP; for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) if((*nbh)[i][j][k]==TMP) (*nbh)[i][j][k]=1; else (*nbh)[i][j][k]=0; return nbh; } NBH* N_6_2(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; nbh=N_6_1(nbh_src,NULL); for(i=0;i<3;i=i+2) if((*nbh)[i][1][1]) { if((*nbh_src)[i][0][1]) (*nbh)[i][0][1]=1; if((*nbh_src)[i][2][1]) (*nbh)[i][2][1]=1; if((*nbh_src)[i][1][0]) (*nbh)[i][1][0]=1; if((*nbh_src)[i][1][2]) (*nbh)[i][1][2]=1; } for(j=0;j<3;j=j+2) if((*nbh)[1][j][1]) { if((*nbh_src)[0][j][1]) (*nbh)[0][j][1]=1; if((*nbh_src)[2][j][1]) (*nbh)[2][j][1]=1; if((*nbh_src)[1][j][0]) (*nbh)[1][j][0]=1; if((*nbh_src)[1][j][2]) (*nbh)[1][j][2]=1; } for(k=0;k<3;k=k+2) if((*nbh)[1][1][k]) { if((*nbh_src)[0][1][k]) (*nbh)[0][1][k]=1; if((*nbh_src)[2][1][k]) (*nbh)[2][1][k]=1; if((*nbh_src)[1][0][k]) (*nbh)[1][0][k]=1; if((*nbh_src)[1][2][k]) (*nbh)[1][2][k]=1; } if(nbh_dst) { for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) (*nbh_dst)[i][j][k]=(*nbh)[i][j][k]; free(nbh); nbh=nbh_dst; } return nbh; } NBH* N_6_3(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; nbh=N_6_2(nbh_src,NULL); i=0;j=0;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=0;j=0;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=0;j=2;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=0;j=2;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=2;j=0;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=2;j=0;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=2;j=2;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; i=2;j=2;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1]) (*nbh)[i][j][k]=1; if(nbh_dst) { for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) (*nbh_dst)[i][j][k]=(*nbh)[i][j][k]; free(nbh); nbh=nbh_dst; } return nbh; } NBH *N_18_1(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; if(!nbh_dst) nbh=(NBH*)calloc(1,sizeof(NBH)); else nbh=nbh_dst; (*nbh)[0][0][0]=TMP;(*nbh)[2][0][0]=TMP; (*nbh)[0][0][2]=TMP;(*nbh)[2][0][2]=TMP; (*nbh)[0][2][0]=TMP;(*nbh)[2][2][0]=TMP; (*nbh)[0][2][2]=TMP;(*nbh)[2][2][2]=TMP; (*nbh)[1][1][1]=TMP; for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) if((*nbh)[i][j][k]!=TMP) { if((*nbh_src)[i][j][k]) (*nbh)[i][j][k]=1; else (*nbh)[i][j][k]=0; } else (*nbh)[i][j][k]=0; return nbh; } NBH* N_18_2(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; nbh=N_18_1(nbh_src,NULL); i=0;j=0;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=0;j=0;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=0;j=2;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=0;j=2;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=2;j=0;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=2;j=0;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=2;j=2;k=0; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; i=2;j=2;k=2; if((*nbh_src)[i][j][k]) if((*nbh)[1][j][k]||(*nbh)[i][1][k]||(*nbh)[i][j][1] ||(*nbh)[1][1][k]||(*nbh)[1][j][1]||(*nbh)[i][1][1]) (*nbh)[i][j][k]=1; if(nbh_dst) { for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) (*nbh_dst)[i][j][k]=(*nbh)[i][j][k]; free(nbh); nbh=nbh_dst; } return nbh; } NBH *N_26_1(NBH* nbh_src,NBH* nbh_dst) { int i,j,k; NBH* nbh; if(!nbh_dst) nbh=(NBH*)calloc(1,sizeof(NBH)); else nbh=nbh_dst; for(k=0;k<3;k++) for(j=0;j<3;j++) for(i=0;i<3;i++) if((*nbh_src)[i][j][k]) (*nbh)[i][j][k]=1; else (*nbh)[i][j][k]=0; (*nbh)[1][1][1]=0; return nbh; } NBH* Nnk(NBH* nbh_src,NBH *nbh_dst,int connectivity) { NBH* nbh; if(!nbh_dst) nbh=(NBH*)calloc(1,sizeof(NBH)); else nbh=nbh_dst; switch(connectivity) { case 1: //T6+(x,X)=#C6(N_6_3(x,X)) N_6_3(nbh_src,nbh); break; case 2: //T6+(x,X)=#C18(N_18_2) N_18_2(nbh_src,nbh); break; case 3: //T6(x,X)=#C6(N_6_2) N_6_2(nbh_src,nbh); break; case 4: //T26(x,X)=#C6(N_26_1) N_26_1(nbh_src,nbh); break; default: //T6+(x,X)=#C6(N_6_3(x,X)) N_6_3(nbh_src,nbh); break; } return nbh; } /*This function computes the topological number associated with NBH and a certain connectivity. This function is a "hack": a more elegant/efficient implementation should be done... NBH is a binary object (0-1) connectivity should be equal to 1,2,3, or 4 according to the convention above*/ int checkTn(NBH *nbh_src,NBH *nbh_dst,int connectivity) { int i,j,k,a,b,c,ik,jk,kk,ct; int con,nvox,label,sum; int comp_table[MAX_COMP]; int min_val; int x,y,z; NBH* nbh; if(!nbh_dst) nbh=(NBH*)calloc(1,sizeof(NBH)); else nbh=nbh_dst; con=connectivityNumber(connectivity); Nnk(nbh_src,nbh,connectivity); memset(comp_table,0,MAX_COMP*sizeof(int)); for(i=0;i<3;i++) for(j=0;j<3;j++) for(k=0;k<3;k++) if((*nbh)[i][j][k]) { for(nvox=0,ik=-1;ik<=1;ik++) { a=i+ik; if(a<0 || a>=3) continue; for(jk=-1;jk<=1;jk++) { b=j+jk; if(b<0 || b>=3) continue; for(kk=-1;kk<=1;kk++) { sum=abs(ik)+abs(jk)+abs(kk); if(sum>con || (!sum)) continue; c=k+kk; if(c<0 || c>=3) continue; label=(*nbh)[a][b][c]; if(label>1) { comp_table[label-1]=2; nvox++; } } } } if(!nvox) //find new basin! { for(ct=1;comp_table[ct] && ct float GetTensorFA( TensorType dtv) { // inner product float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); // Computed as // FA = vcl_sqrt(1.5*sum(sum(N.*N))/sum((sum(D.*D)))) // where N = D - ((1/3)*trace(D)*eye(3,3)) // equation (28) in http://lmi.bwh.harvard.edu/papers/pdfs/2002/westinMEDIA02.pdf if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; float fractionalAnisotropy =( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); return fractionalAnisotropy; } return 0.0 ; } template float GetMetricTensorCost( TVectorType dpath, TTensorType dtv , unsigned int matrixpower) { typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType inv = vnl_matrix_inverse(DT); for (unsigned int lo=1; lo TVectorType ChangeTensorByVector( TVectorType dpath, TTensorType dtv, float epsilon) { typedef TVectorType VectorType; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e3 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e1 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType evec1(3,1);//biggest evec1(0,0)=eig.V(0,2); evec1(1,0)=eig.V(1,2); evec1(2,0)=eig.V(2,2); MatrixType evec2(3,1);// middle evec2(0,0)=eig.V(0,1); evec2(1,0)=eig.V(1,1); evec2(2,0)=eig.V(2,1); MatrixType evec3(3,1);//smallest evec3(0,0)=eig.V(0,0); evec3(1,0)=eig.V(1,0); evec3(2,0)=eig.V(2,0); float temp; temp=(vec.transpose()*evec1)(0,0); temp=sqrt(temp*temp); e1 *=( 1.0 - epsilon*temp); if (e1 < 1.e-11) e1=1.e-11; temp=(vec.transpose()*evec2)(0,0); temp=sqrt(temp*temp); e2 *=( 1.0 - epsilon*temp); if (e2 < 1.e-11) e2=1.e-11; temp=(vec.transpose()*evec3)(0,0); temp=sqrt(temp*temp); e3 *=( 1.0 - epsilon*temp); if (e3 < 1.e-11) e3=1.e-11; DT = (evec3*evec3.transpose())*e3 + (evec2*evec2.transpose())*e2 + (evec1*evec1.transpose())*e1; itk::Vector newtens; newtens[0]=DT(0,0); newtens[3]=DT(1,1); newtens[5]=DT(2,2); newtens[1]=DT(0,1); newtens[2]=DT(0,2); newtens[4]=DT(2,1); return newtens; } template float GetTensorADC( TensorType dtv, unsigned int opt = 0) { float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return 0; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return 0; if (mag < eps) { return 0; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); if (opt <= 1 ) return (e1+e1+e3)/3.0; // else if (opt == 4 ) return e2; else if (opt == 3 ) return (e2+e1)/2.0; else if (opt == 2 ) return e3; } template itk::RGBPixel< unsigned char > GetTensorRGB( TTensorType dtv ) { itk::RGBPixel< unsigned char > zero; zero.Fill(0); float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return zero; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return zero; if (mag < eps) { return zero; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); itk::RGBPixel< float > rgb; float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); float fa=0.0; if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; fa=( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); } //rgb[0]=eig.V(2,0)*fa*255;//+eig.V(1,0)*e2; //rgb[1]=eig.V(2,1)*fa*255;//+eig.V(1,1)*e2; // rgb[2]=eig.V(2,2)*fa*255;//+eig.V(1,2)*e2; rgb[0]=eig.V(0,2)*fa*255;//+eig.V(1,0)*e2; rgb[1]=eig.V(1,2)*fa*255;//+eig.V(1,1)*e2; rgb[2]=eig.V(2,2)*fa*255;//+eig.V(1,2)*e2; return rgb; } template itk::RGBPixel< float > GetTensorPrincipalEigenvector( TTensorType dtv ) { itk::RGBPixel< float > zero; zero.Fill(0); float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return zero; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return zero; if (mag < eps) { return zero; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); itk::RGBPixel< float > rgb; float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); float fa=0.0; if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; fa=( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); } //rgb[0]=eig.V(2,0)*fa*255;//+eig.V(1,0)*e2; //rgb[1]=eig.V(2,1)*fa*255;//+eig.V(1,1)*e2; // rgb[2]=eig.V(2,2)*fa*255;//+eig.V(1,2)*e2; // biggest evec rgb[0]=eig.V(0,2);//+eig.V(1,0)*e2; rgb[1]=eig.V(1,2);//+eig.V(1,1)*e2; rgb[2]=eig.V(2,2);//+eig.V(1,2)*e2; return rgb; mag=rgb[0]*rgb[0]+rgb[1]*rgb[1]+rgb[2]*rgb[2]; mag=sqrt(mag); rgb[0]=rgb[0]/mag; rgb[1]=rgb[1]/mag; rgb[2]=rgb[2]/mag; return rgb; } template TTensorType TensorLogAndExp( TTensorType dtv, bool takelog , bool success=true) { float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { dtv.Fill(0); //dtv[0]=eps; dtv[3]=eps; dtv[5]=eps; return dtv; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return dtv; if (mag < eps) { success = false; return dtv; } // typedef itk::Vector TensorTypeIn; typedef TTensorType TensorType; typedef TTensorType TensorTypeOut; typedef TTensorType TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[2]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[3]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); // std::cout << " eig.D " << eig.D << std::endl; // std::cout << " eig V " << eig.V << std::endl; double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); float peigeps=1.e-2; float eigeps=1.e-6; float eigmx=10000; if ( e3 < peigeps ) { success=false; return dtv; } MatrixType eigmat(3,3); eigmat.fill(0); if (takelog) { eigmat(0,0)=log(e1); eigmat(1,1)=log(e2); eigmat(2,2)=log(e3); } else //take exp { eigmat(0,0)=exp(e1); eigmat(1,1)=exp(e2); eigmat(2,2)=exp(e3); } // std::cout << " e1 " << e1 << " e2 " << e2 << " e3 " << std::endl; MatrixType DTrec=eig.V*eigmat*eig.V.transpose(); dtv2[0]=DTrec(0,0); dtv2[2]=DTrec(1,1); dtv2[5]=DTrec(2,2); dtv2[1]=DTrec(0,1); dtv2[3]=DTrec(0,2); dtv2[4]=DTrec(1,2); return dtv2; } static float GetMetricTensorCost( itk::Vector dpath, itk::Vector dtv ) { typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType inv = vnl_matrix_inverse(DT); MatrixType sol= vec.transpose()*inv*vec; float cost = sol(0,0)/etot; return cost; } */ #endif ants-1.9.2+svn680.dfsg/Tensor/TensorFunctions.h000066400000000000000000000510501147325206600212470ustar00rootroot00000000000000#ifndef _TensorFunctions_cxx_ #define _TensorFunctions_cxx_ //#include "itkSmallStrainDiffusionTensorReorientationImageFilter.h" //#include "itkVectorIndexSelectionCastImageFilter.h" #include "itkSymmetricSecondRankTensor.h" #include "itkVector.h" #include "itkVersor.h" #include "itkVariableSizeMatrix.h" #include "itkDecomposeTensorFunction2.h" #include "itkRotationMatrixFromVectors.h" #include "vnl/algo/vnl_matrix_inverse.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" template MatrixType Vector2Matrix( TensorType dtv ) { MatrixType dtm(3,3); dtm(0,0) = dtv[0]; dtm(0,1) = dtm(1,0) = dtv[1]; dtm(0,2) = dtm(2,0) = dtv[2]; dtm(1,1) = dtv[3]; dtm(1,2) = dtm(2,1) = dtv[4]; dtm(2,2) = dtv[5]; return dtm; } template void Vector2Matrix( TensorType &dtv, MatrixType &dtm ) { dtm(0,0) = dtv[0]; dtm(0,1) = dtm(1,0) = dtv[1]; dtm(0,2) = dtm(2,0) = dtv[2]; dtm(1,1) = dtv[3]; dtm(1,2) = dtm(2,1) = dtv[4]; dtm(2,2) = dtv[5]; } template TensorType Matrix2Vector( MatrixType dtm ) { TensorType dtv; dtv[0] = dtm(0,0); dtv[1] = dtm(0,1); dtv[2] = dtm(0,2); dtv[3] = dtm(1,1); dtv[4] = dtm(1,2); dtv[5] = dtm(2,2); return dtv; } template void EigenAnalysis(TensorType dtv, MatrixType &evals, MatrixType &evecs) { MatrixType dtm = Vector2Matrix(dtv); itk::DecomposeTensorFunction2 decomposer; decomposer.EvaluateSymmetricEigenDecomposition( dtm, evals, evecs ); } template float DiffusionCoefficient( TensorType dtv, VectorType direction, bool normalized = false) { vnl_matrix tensor(3,3); tensor[0][0] = dtv[0]; tensor[1][0] = tensor[0][1] = dtv[1]; tensor[2][0] = tensor[0][2] = dtv[2]; tensor[1][1] = dtv[3]; tensor[1][2] = tensor[2][1] = dtv[4]; tensor[2][2] = dtv[5]; vnl_matrix tangentmat(3,1); tangentmat(0,0) = direction[0]; tangentmat(1,0) = direction[1]; tangentmat(2,0) = direction[2]; vnl_matrix fddmat = tangentmat.transpose() * tensor * tangentmat; float fdd = (float) fddmat(0,0); if (normalized > 0) { fdd = fdd/(tensor[0][0]+tensor[1][1]+tensor[2][2]); } return fdd; } template TensorType TensorLogAndExp( TensorType dtv, bool takelog , bool success=true) { float eps=1.e-12,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { dtv.Fill(0); //dtv[0]=eps; dtv[3]=eps; dtv[5]=eps; success=false; return dtv; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) { success = false; return dtv; } if (mag < eps) { success = false; return dtv; } //typedef vnl_matrix MatrixType; typedef itk::VariableSizeMatrix MatrixType; //MatrixType DT = Vector2Matrix(dtv); MatrixType D; MatrixType V; EigenAnalysis(dtv,D,V); double e1 = D(0,0); double e2 = D(1,1); double e3 = D(2,2); //float peigeps=1.e-12; if ( fabs(e3) < eps ) { success=false; std::cout << "-4" << std::flush; return dtv; } MatrixType eigmat(3,3); eigmat.Fill(0); if (takelog) { eigmat(0,0)=log(fabs(e1)); eigmat(1,1)=log(fabs(e2)); eigmat(2,2)=log(fabs(e3)); } else //take exp { eigmat(0,0)=exp(e1); eigmat(1,1)=exp(e2); eigmat(2,2)=exp(e3); } if ( vnl_math_isnan(eigmat(0,0)) || vnl_math_isnan(eigmat(1,1)) || vnl_math_isnan(eigmat(2,2))) { dtv.Fill(0); success=false; return dtv; } typedef typename MatrixType::InternalMatrixType VnlMatrixType; VnlMatrixType DTrec=V.GetVnlMatrix()*eigmat.GetVnlMatrix()*V.GetTranspose(); TensorType dtv2 = Matrix2Vector(DTrec); return dtv2; } template TensorType TensorLog( TensorType dtv, bool success=true ) { return TensorLogAndExp( dtv, true, success ); } template TensorType TensorExp( TensorType dtv, bool takelog , bool success=true) { return TensorLogAndExp( dtv, false, success ); } template float GetTensorFA( TensorType dtv ) { // inner product float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); // Computed as // FA = vcl_sqrt(1.5*sum(sum(N.*N))/sum((sum(D.*D)))) // where N = D - ((1/3)*trace(D)*eye(3,3)) // equation (28) in http://lmi.bwh.harvard.edu/papers/pdfs/2002/westinMEDIA02.pdf if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; float fractionalAnisotropy =( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); return fractionalAnisotropy; } return 0.0 ; /* // Computed as // FA = vcl_sqrt(1.5 * ( \sum_i ( lambda_i - lambda_mean )^2 ) / \sum_i ( lambda_i^2 ) ) // as in http://splweb.bwh.harvard.edu:8000/pages/papers/martha/DTI_Tech354.pdf // [lambda = eig(A)]. EigenValuesArrayType eigenValues; ComputeEigenValues( eigenValues ); eigenValues[0] = vnl_math_abs(eigenValues[0]); eigenValues[1] = vnl_math_abs(eigenValues[1]); eigenValues[2] = vnl_math_abs(eigenValues[2]); const RealValueType norm_E = vnl_math_sqr(eigenValues[0]) + vnl_math_sqr(eigenValues[1]) + vnl_math_sqr(eigenValues[2]); if( norm_E > 0.0 ) { const RealValueType anisotropy = vnl_math_sqr(eigenValues[0] - eigenValues[1]) + vnl_math_sqr(eigenValues[1] - eigenValues[2]) + vnl_math_sqr(eigenValues[2] - eigenValues[0]); const RealValueType fractionalAnisotropy = vcl_sqrt( 0.5 * anisotropy/norm_E); return fractionalAnisotropy; } return 0.0; */ } template float GetMetricTensorCost( TVectorType dpath, TTensorType dtv , unsigned int matrixpower) { typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType inv = vnl_matrix_inverse(DT); for (unsigned int lo=1; lo TVectorType ChangeTensorByVector( TVectorType dpath, TTensorType dtv, float epsilon) { typedef TVectorType VectorType; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e3 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e1 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType evec1(3,1);//biggest evec1(0,0)=eig.V(0,2); evec1(1,0)=eig.V(1,2); evec1(2,0)=eig.V(2,2); MatrixType evec2(3,1);// middle evec2(0,0)=eig.V(0,1); evec2(1,0)=eig.V(1,1); evec2(2,0)=eig.V(2,1); MatrixType evec3(3,1);//smallest evec3(0,0)=eig.V(0,0); evec3(1,0)=eig.V(1,0); evec3(2,0)=eig.V(2,0); float temp; temp=(vec.transpose()*evec1)(0,0); temp=sqrt(temp*temp); e1 *=( 1.0 - epsilon*temp); if (e1 < 1.e-11) e1=1.e-11; temp=(vec.transpose()*evec2)(0,0); temp=sqrt(temp*temp); e2 *=( 1.0 - epsilon*temp); if (e2 < 1.e-11) e2=1.e-11; temp=(vec.transpose()*evec3)(0,0); temp=sqrt(temp*temp); e3 *=( 1.0 - epsilon*temp); if (e3 < 1.e-11) e3=1.e-11; DT = (evec3*evec3.transpose())*e3 + (evec2*evec2.transpose())*e2 + (evec1*evec1.transpose())*e1; itk::Vector newtens; newtens[0]=DT(0,0); newtens[3]=DT(1,1); newtens[5]=DT(2,2); newtens[1]=DT(0,1); newtens[2]=DT(0,2); newtens[4]=DT(2,1); return newtens; } template float GetTensorADC( TTensorType dtv, unsigned int opt = 0) { float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return 0; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return 0; if (mag < eps) { return 0; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); if (opt <= 1 ) return (e1+e1+e3)/3.0; // else if (opt == 4 ) return e2; else if (opt == 3 ) return (e2+e1)/2.0; else if (opt == 2 ) return e3; else return (e1+e1+e3)/3.0; } template itk::RGBPixel< unsigned char > GetTensorRGB( TTensorType dtv ) { typedef TTensorType TensorType; itk::RGBPixel< unsigned char > zero; zero.Fill(0); float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return zero; } } mag=sqrt(mag); itk::RGBPixel< unsigned char > rgb; if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return zero; if (mag < eps) { return zero; } typedef itk::VariableSizeMatrix EigenMatrixType; EigenMatrixType evals(3,3); EigenMatrixType evecs(3,3); EigenAnalysis(dtv,evals,evecs); float fa = GetTensorFA(dtv); rgb[0]=(unsigned char)(vcl_fabs(evecs(0,2))*fa*255); rgb[1]=(unsigned char)(vcl_fabs(evecs(1,2))*fa*255); rgb[2]=(unsigned char)(vcl_fabs(evecs(2,2))*fa*255); return rgb; } template itk::RGBPixel< float > GetTensorPrincipalEigenvector( TTensorType dtv ) { itk::RGBPixel< float > zero; zero.Fill(0); float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return zero; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return zero; if (mag < eps) { return zero; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); itk::RGBPixel< float > rgb; float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); float fa=0.0; if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; fa=( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); } //rgb[0]=eig.V(2,0)*fa*255;//+eig.V(1,0)*e2; //rgb[1]=eig.V(2,1)*fa*255;//+eig.V(1,1)*e2; // rgb[2]=eig.V(2,2)*fa*255;//+eig.V(1,2)*e2; // biggest evec rgb[0]=eig.V(0,2);//+eig.V(1,0)*e2; rgb[1]=eig.V(1,2);//+eig.V(1,1)*e2; rgb[2]=eig.V(2,2);//+eig.V(1,2)*e2; return rgb; mag=rgb[0]*rgb[0]+rgb[1]*rgb[1]+rgb[2]*rgb[2]; mag=sqrt(mag); rgb[0]=rgb[0]/mag; rgb[1]=rgb[1]/mag; rgb[2]=rgb[2]/mag; return rgb; } template itk::Vector< float > GetTensorPrincipalEigenvector( TTensorType dtv , unsigned int whichvec) { itk::Vector< float,3 > zero; zero.Fill(0); float eps=1.e-9,mag=0; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; mag+=ff*ff; if ( vnl_math_isnan( ff ) || vnl_math_isinf(ff) ) { return zero; } } mag=sqrt(mag); if ( dtv[1]==0 && dtv[2] == 0 && dtv[4]==0) return zero; if (mag < eps) { return zero; } // typedef itk::Vector TensorTypeIn; typedef itk::Vector TensorType; typedef itk::Vector TensorTypeOut; typedef itk::Vector TensorTypeIn; const unsigned int ImageDimension = 3; typedef itk::Image InTensorImageType; typedef itk::Image OutTensorImageType; typedef itk::Image TensorImageType; typedef InTensorImageType::Pointer TensorImagePointer; typedef float PixelType; typedef itk::Vector VectorType1; typedef itk::Image FieldType; typedef itk::Image ImageType; typedef itk::ImageFileReader readertype; typedef itk::ImageFileWriter writertype; typedef ImageType::IndexType IndexType; typedef ImageType::SizeType SizeType; typedef ImageType::SpacingType SpacingType; // typedef itk::AffineTransform AffineTransformType; // typedef itk::LinearInterpolateImageFunction InterpolatorType1; // typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; itk::Vector dtv2; typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; // if (takelog ) std::cout << " TAKING LOG " << std::endl; else std::cout << "TAKING EXP " << std::endl; // std::cout << " dtv " << dtv << std::endl; vnl_symmetric_eigensystem< double > eig(DT); itk::Vector< float ,3 > rgb; float xx = dtv[0]; float xy = dtv[1]; float xz = dtv[2]; float yy = dtv[3]; float yz = dtv[4]; float zz = dtv[5]; float isp = ( xx*xx + yy*yy + zz*zz + 2.0*(xy*xy + xz*xz + yz*yz) ); float fa=0.0; if( isp > 0.0 ) { float trace = dtv[0]; trace += dtv[3]; trace += dtv[5]; float anisotropy = 3.0 * isp - trace * trace; fa=( vcl_sqrt(anisotropy / ( 2.0 * isp ) ) ); } rgb[0]=eig.V(0,whichvec);//+eig.V(1,0)*e2; rgb[1]=eig.V(1,whichvec);//+eig.V(1,1)*e2; rgb[2]=eig.V(2,whichvec);//+eig.V(1,2)*e2; return rgb; } template static float GetMetricTensorCost( itk::Vector dpath, TTensorType dtv ) { typedef vnl_matrix MatrixType; MatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< double > eig(DT); double e1 = (eig.D(0,0)); double e2 = (eig.D(1,1)); double e3 = (eig.D(2,2)); double etot=e1+e2+e3; if (etot==0) etot=1; MatrixType vec(3,1); vec(0,0)=dpath[0]; vec(1,0)=dpath[1]; vec(2,0)=dpath[2]; MatrixType inv = vnl_matrix_inverse(DT); MatrixType sol= vec.transpose()*inv*vec; float cost = sol(0,0)/etot; return cost; } template VersorTensorType VersorTensor( TensorType dtv ) { typedef itk::VariableSizeMatrix EigenMatrixType; typedef itk::Vector VectorType; EigenMatrixType D; EigenMatrixType V; EigenAnalysis(dtv,D,V); VectorType e3; e3[0]=V(0,2); e3[1]=V(1,2); e3[2]=V(2,2); VectorType e2; e2[0]=V(0,1); e2[1]=V(1,1); e2[2]=V(2,1); VectorType xAxis; xAxis[0]=1; xAxis[1]=0; xAxis[2]=0; VectorType yAxis; yAxis[0]=0; yAxis[1]=1; yAxis[2]=0; MatrixType R1 = RotationMatrixFromVectors(e3,xAxis); e2 = R1*e2; MatrixType R2 = RotationMatrixFromVectors(e2,yAxis); MatrixType R = R2*R1; itk::Versor versor; versor.SetMatrix( R ); VersorTensorType dtq; dtq[0] = D(0,0); dtq[1] = D(1,1); dtq[2] = D(2,2); dtq[3] = versor[0]; dtq[4] = versor[1]; dtq[5] = versor[2]; return dtq; } template VersorTensorType VersorTensor( TensorType dtv, MatrixType frame ) { typedef itk::VariableSizeMatrix EigenMatrixType; typedef itk::Vector VectorType; EigenMatrixType D; EigenMatrixType V; EigenAnalysis(dtv,D,V); VectorType e3; e3[0]=V(0,2); e3[1]=V(1,2); e3[2]=V(2,2); VectorType e2; e2[0]=V(0,1); e2[1]=V(1,1); e2[2]=V(2,1); VectorType xAxis; xAxis[0]=frame(0,0); xAxis[1]=frame(1,0); xAxis[2]=frame(2,0); VectorType yAxis; yAxis[0]=frame(0,1); yAxis[1]=frame(1,1); yAxis[2]=frame(2,1); MatrixType R1 = RotationMatrixFromVectors(e3,xAxis); e2 = R1*e2; MatrixType R2 = RotationMatrixFromVectors(e2,yAxis); MatrixType R = R2*R1; itk::Versor versor; versor.SetMatrix( R ); VersorTensorType dtq; dtq[0] = D(0,0); dtq[1] = D(1,1); dtq[2] = D(2,2); dtq[3] = versor[0]; dtq[4] = versor[1]; dtq[5] = versor[2]; return dtq; } #endif ants-1.9.2+svn680.dfsg/Tensor/itkDecomposeTensorFunction2.h000066400000000000000000000056311147325206600235210ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDecomposeTensorFunction2.h,v $ Language: C++ Date: $Date: 2009/01/29 00:15:47 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDecomposeTensorFunction2_h #define __itkDecomposeTensorFunction2_h #include "itkVariableSizeMatrix.h" namespace itk { /** \class DecomposeTensorFunction2 * */ template > class DecomposeTensorFunction2 { public: /** Standard class typedefs. */ typedef DecomposeTensorFunction2 Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef TInput InputMatrixType; typedef TOutput OutputMatrixType; /** Define the data type and the vector of data type used in calculations. */ typedef TRealType RealType; // Wrappers for vnl routines void EvaluateEigenDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSymmetricEigenDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateQRDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSVDDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSVDEconomyDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateLeftPolarDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateRightPolarDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateCholeskyDecomposition( InputMatrixType&, OutputMatrixType& ); RealType EvaluateDeterminant( InputMatrixType& ); DecomposeTensorFunction2(); virtual ~DecomposeTensorFunction2() {} protected: void PrintSelf ( std::ostream& os, Indent indent ) const; private: DecomposeTensorFunction2(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkDecomposeTensorFunction2.txx" #endif #endif ants-1.9.2+svn680.dfsg/Tensor/itkDecomposeTensorFunction2.txx000066400000000000000000000233211147325206600241110ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDecomposeTensorFunction2.txx,v $ Language: C++ Date: $Date: 2009/01/29 00:15:47 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkDecomposeTensorFunction2_txx #define _itkDecomposeTensorFunction2_txx #include "itkDecomposeTensorFunction2.h" #include "vnl/algo/vnl_cholesky.h" #include "vnl/algo/vnl_qr.h" #include "vnl/algo/vnl_real_eigensystem.h" #include "vnl/algo/vnl_svd.h" #include "vnl/algo/vnl_svd_economy.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "vnl/vnl_matrix.h" #include "vnl/vnl_matrix_fixed.h" #include "vnl/vnl_det.h" #include "vxl/vcl/vcl_complex.h" namespace itk { template DecomposeTensorFunction2 ::DecomposeTensorFunction2() {} template void DecomposeTensorFunction2 ::EvaluateEigenDecomposition( InputMatrixType &M, OutputMatrixType &D, OutputMatrixType &V ) { unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); D.SetSize( RowDimensions, RowDimensions ); V.SetSize( RowDimensions, RowDimensions ); D.Fill( 0.0 ); vnl_matrix v( RowDimensions, ColumnDimensions ); for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { for ( unsigned int i = 0; i < RowDimensions; i++ ) { v.put( i, j, M[i][j] ); } } vnl_real_eigensystem eig( v ); for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { for ( unsigned int i = 0; i < RowDimensions; i++ ) { V[i][j] = static_cast( (eig.Vreal).get( i, j ) ); if ( i == j ) { D[i][j] = static_cast( vcl_real( eig.D(j) ) ); } } } } template void DecomposeTensorFunction2 ::EvaluateSymmetricEigenDecomposition( InputMatrixType &M, OutputMatrixType &D, OutputMatrixType &V ) { // The resulting eigenvectors and values are sorted in increasing order // so V.column(0) is the eigenvector corresponding to the // smallest eigenvalue. unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); D.SetSize( RowDimensions, RowDimensions ); V.SetSize( RowDimensions, RowDimensions ); D.Fill( 0.0 ); vnl_symmetric_eigensystem eig( M.GetVnlMatrix() ); for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { for ( unsigned int i = 0; i < RowDimensions; i++ ) { V[i][j] = (eig.V).get( i, j ); if ( i == j ) { D[i][j] = eig.D(j); } } } } template void DecomposeTensorFunction2 ::EvaluateRightPolarDecomposition( InputMatrixType &M, OutputMatrixType &R, OutputMatrixType &S ) { OutputMatrixType U; OutputMatrixType W; OutputMatrixType V; this->EvaluateSVDDecomposition( M, U, W, V ); R = U * V.GetTranspose(); S = V * W * V.GetTranspose(); } template void DecomposeTensorFunction2 ::EvaluateLeftPolarDecomposition( InputMatrixType &M, OutputMatrixType &S, OutputMatrixType &R ) { OutputMatrixType U; OutputMatrixType W; OutputMatrixType V; this->EvaluateSVDDecomposition( M, U, W, V ); R = U * V.GetTranspose(); S = U * W * U.GetTranspose(); } template void DecomposeTensorFunction2 ::EvaluateQRDecomposition( InputMatrixType &M, OutputMatrixType &Q, OutputMatrixType &R ) { unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); Q.SetSize( RowDimensions, ColumnDimensions ); R.SetSize( ColumnDimensions, ColumnDimensions ); vnl_qr qr( M.GetVnlMatrix() ); for ( unsigned int i = 0; i < RowDimensions; i++ ) { for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { Q[i][j] = qr.Q()(i, j); } } for ( unsigned int i = 0; i < ColumnDimensions; i++ ) { for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { R[i][j] = qr.R()(i, j); } } } template void DecomposeTensorFunction2 ::EvaluateSVDDecomposition( InputMatrixType &M, OutputMatrixType &U, OutputMatrixType &W, OutputMatrixType &V ) { unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); U.SetSize( RowDimensions, RowDimensions ); V.SetSize( ColumnDimensions, ColumnDimensions ); W.SetSize( RowDimensions, ColumnDimensions ); bool isidentity=true; float tol=1.e-12; for ( unsigned int i = 0; i < RowDimensions; i++ ) { for ( unsigned int j = 0; j < RowDimensions; j++ ) { if (i==j) { if (fabs(M[i][j]-1.0) > tol) isidentity=false; } else { if (fabs(M[i][j]) > tol) isidentity=false; } } } if (isidentity) { for ( unsigned int i = 0; i < RowDimensions; i++ ) { for ( unsigned int j = 0; j < RowDimensions; j++ ) { if (i==j) { U[i][j]=1.0; V[i][j]=1.0; W[i][i]=1; } else { U[i][j]=0.0; V[i][j]=0.0; } } } return; } vnl_svd svd( M.GetVnlMatrix() ); for ( unsigned int i = 0; i < RowDimensions; i++ ) { for ( unsigned int j = 0; j < RowDimensions; j++ ) { U[i][j] = svd.U(i, j); } } for ( unsigned int i = 0; i < ColumnDimensions; i++ ) { for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { V[i][j] = svd.V(i, j); } } W.Fill( 0.0 ); unsigned int minDimensions = ColumnDimensions; if ( static_cast( RowDimensions ) ( ColumnDimensions ) ) { minDimensions = RowDimensions; } for ( unsigned int i = 0; i < minDimensions; i++ ) { W[i][i] = svd.W(i, i); } } template void DecomposeTensorFunction2 ::EvaluateSVDEconomyDecomposition( InputMatrixType &M, OutputMatrixType &W, OutputMatrixType &V ) { /** * Same as SVD except the routine does not return U --- * allows for faster computation. */ unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); V.SetSize( ColumnDimensions, ColumnDimensions ); W.SetSize( RowDimensions, ColumnDimensions ); vnl_svd_economy svd( M.GetVnlMatrix() ); for ( unsigned int i = 0; i < ColumnDimensions; i++ ) { for ( unsigned int j = 0; j < ColumnDimensions; j++ ) { V[i][j] = svd.V()(i, j); } } W.Fill( 0.0 ); unsigned int minDimensions = ColumnDimensions; if ( static_cast( RowDimensions ) < static_cast( ColumnDimensions ) ) { minDimensions = RowDimensions; } for ( unsigned int i = 0; i < minDimensions; i++ ) { W[i][i] = svd.lambdas()[i]; } } template void DecomposeTensorFunction2 ::EvaluateCholeskyDecomposition( InputMatrixType &M, OutputMatrixType &L ) { // Assumes symmetric tensor of type double vnl_matrix m( M.Rows(), M.Cols() ); for ( unsigned int j = 0; j < M.Cols(); j++ ) { for ( unsigned int i = 0; i < M.Rows(); i++ ) { m.put( i, j, M[i][j] ); } } vnl_cholesky cholesky( m, vnl_cholesky::quiet ); L.SetSize( M.Rows(), M.Cols() ); for ( unsigned int i = 0; i < L.Rows(); i++ ) { for ( unsigned int j = 0; j < L.Cols(); j++ ) { L[i][j] = cholesky.L_badly_named_method().get(i, j); } } } template typename DecomposeTensorFunction2::RealType DecomposeTensorFunction2 ::EvaluateDeterminant( InputMatrixType &M ) { if ( M.Rows() == M.Cols() && M.Rows() >= 2 && M.Rows() <= 4 ) { vnl_matrix_fixed m2; vnl_matrix_fixed m3; vnl_matrix_fixed m4; for ( unsigned int i = 0; i < M.Rows(); i++ ) { for ( unsigned int j = 0; j < M.Cols(); j++ ) { switch( M.Rows() ) { case 2: m2.put( i, j, M[i][j] ); break; case 3: m3.put( i, j, M[i][j] ); break; case 4: m4.put( i, j, M[i][j] ); break; } } } switch( M.Rows() ) { case 2: return static_cast( vnl_det( m2 ) ); break; case 3: return static_cast( vnl_det( m3 ) ); break; case 4: return static_cast( vnl_det( m4 ) ); break; } } else { vnl_qr qr( M.GetVnlMatrix() ); return static_cast( qr.determinant() ); } } template void DecomposeTensorFunction2 ::PrintSelf( std::ostream& os, Indent indent ) const { } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Tensor/itkExpTensorImageFilter.h000066400000000000000000000107401147325206600226550ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkExpTensorImageFilter.h,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkExpTensorImageFilter_h #define __itkExpTensorImageFilter_h #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkNumericTraits.h" #include "itkDiffusionTensor3D.h" namespace itk { /** \class ExpTensorImageFilter * \brief Applies an averaging filter to an image * * Computes an image where a given pixel is the mean value of the * the pixels in a neighborhood about the corresponding input pixel. * * A mean filter is one of the family of linear filters. * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * * \ingroup IntensityImageFilters */ template class ITK_EXPORT ExpTensorImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Extract dimension from input and output image. */ itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); /** Convenient typedefs for simplifying declarations. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; /** Standard class typedefs. */ typedef ExpTensorImageFilter Self; typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(ExpTensorImageFilter, ImageToImageFilter); /** Image typedef support. */ typedef typename InputImageType::ConstPointer InputImagePointer; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputPixelType::ValueType InputRealType; typedef typename OutputPixelType::ValueType OutputRealType; //typedef typename DiffusionTensor3D TensorType; //typedef typename TensorType::EigenValuesArrayType EigenValuesArrayType; //typedef typename TensorType::EigenVectorsMatrixType EigenVectorsMatrixType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename InputImageType::SizeType InputSizeType; typedef typename OutputImageType::SizeType OutputSizeType; typedef typename InputImageType::IndexType InputIndexType; typedef typename OutputImageType::IndexType OutputIndexType; /** Set the radius of the neighborhood used to compute the mean. */ //itkSetMacro(Radius, InputSizeType); /** Get the radius of the neighborhood used to compute the mean */ //itkGetConstReferenceMacro(Radius, InputSizeType); protected: ExpTensorImageFilter(); virtual ~ExpTensorImageFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; /** ExpTensorImageFilter can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() * routine which is called for each processing thread. The output * image data is allocated automatically by the superclass prior to * calling ThreadedGenerateData(). ThreadedGenerateData can only * write to the portion of the output image specified by the * parameter "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void GenerateData( void ); private: ExpTensorImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkExpTensorImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Tensor/itkExpTensorImageFilter.txx000066400000000000000000000045751147325206600232620ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkExpTensorImageFilter.txx,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkExpTensorImageFilter_txx #define _itkExpTensorImageFilter_txx #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "itkOffset.h" #include "itkProgressReporter.h" #include "itkObjectFactory.h" #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "itkExpTensorImageFilter.h" #include "TensorFunctions.h" namespace itk { template ExpTensorImageFilter ::ExpTensorImageFilter() { } template< class TInputImage, class TOutputImage> void ExpTensorImageFilter< TInputImage, TOutputImage > ::GenerateData() { InputImagePointer input = this->GetInput(); OutputImagePointer output = this->GetOutput(); ImageRegionConstIterator< InputImageType > inputIt( input, input->GetLargestPossibleRegion() ); InputSizeType inputSize = input->GetLargestPossibleRegion().GetSize(); output->SetRegions( input->GetLargestPossibleRegion() ); output->Allocate(); ImageRegionIterator< OutputImageType > outputIt( output, output->GetLargestPossibleRegion() ); for ( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd() && !outputIt.IsAtEnd(); ++inputIt, ++outputIt) { InputPixelType result = TensorLogAndExp(inputIt.Value(), false); outputIt.Set( result ); } } /** * Standard "PrintSelf" method */ template void ExpTensorImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Tensor/itkLogTensorImageFilter.h000066400000000000000000000107341147325206600226450ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLogTensorImageFilter.h,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLogTensorImageFilter_h #define __itkLogTensorImageFilter_h #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkNumericTraits.h" #include "TensorFunctions.h" namespace itk { /** \class LogTensorImageFilter * \brief Applies an averaging filter to an image * * Computes an image where a given pixel is the mean value of the * the pixels in a neighborhood about the corresponding input pixel. * * A mean filter is one of the family of linear filters. * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * * \ingroup IntensityImageFilters */ template class ITK_EXPORT LogTensorImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Extract dimension from input and output image. */ itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension); itkStaticConstMacro(OutputImageDimension, unsigned int, TOutputImage::ImageDimension); /** Convenient typedefs for simplifying declarations. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; /** Standard class typedefs. */ typedef LogTensorImageFilter Self; typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(LogTensorImageFilter, ImageToImageFilter); /** Image typedef support. */ typedef typename InputImageType::ConstPointer InputImagePointer; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputPixelType::ValueType InputRealType; typedef typename OutputPixelType::ValueType OutputRealType; //typedef typename DiffusionTensor3D TensorType; //typedef typename TensorType::EigenValuesArrayType EigenValuesArrayType; //typedef typename TensorType::EigenVectorsMatrixType EigenVectorsMatrixType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename InputImageType::SizeType InputSizeType; typedef typename OutputImageType::SizeType OutputSizeType; typedef typename InputImageType::IndexType InputIndexType; typedef typename OutputImageType::IndexType OutputIndexType; /** Set the radius of the neighborhood used to compute the mean. */ //itkSetMacro(Radius, InputSizeType); /** Get the radius of the neighborhood used to compute the mean */ //itkGetConstReferenceMacro(Radius, InputSizeType); protected: LogTensorImageFilter(); virtual ~LogTensorImageFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; /** LogTensorImageFilter can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() * routine which is called for each processing thread. The output * image data is allocated automatically by the superclass prior to * calling ThreadedGenerateData(). ThreadedGenerateData can only * write to the portion of the output image specified by the * parameter "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void GenerateData( void ); private: LogTensorImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLogTensorImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Tensor/itkLogTensorImageFilter.txx000066400000000000000000000045741147325206600232460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLogTensorImageFilter.txx,v $ Language: C++ Date: $Date: 2009/03/17 18:59:48 $ Version: $Revision: 1.3 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkLogTensorImageFilter_txx #define _itkLogTensorImageFilter_txx #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkImageRegionConstIterator.h" #include "itkOffset.h" #include "itkProgressReporter.h" #include "itkObjectFactory.h" #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "itkLogTensorImageFilter.h" #include "TensorFunctions.h" namespace itk { template LogTensorImageFilter ::LogTensorImageFilter() { } template< class TInputImage, class TOutputImage> void LogTensorImageFilter< TInputImage, TOutputImage > ::GenerateData() { InputImagePointer input = this->GetInput(); OutputImagePointer output = this->GetOutput(); ImageRegionConstIterator< InputImageType > inputIt( input, input->GetLargestPossibleRegion() ); InputSizeType inputSize = input->GetLargestPossibleRegion().GetSize(); output->SetRegions( input->GetLargestPossibleRegion() ); output->Allocate(); ImageRegionIteratorWithIndex< OutputImageType > outputIt( output, output->GetLargestPossibleRegion() ); for ( inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd() && !outputIt.IsAtEnd(); ++inputIt, ++outputIt) { InputPixelType result = TensorLog(inputIt.Value()); outputIt.Set( result ); } } /** * Standard "PrintSelf" method */ template void LogTensorImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Tensor/itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.cxx000066400000000000000000000465711147325206600337230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.cxx,v $ Language: C++ Date: $Date: 2009/03/17 19:01:36 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkPreservationOfPrincipalDirectionTensorReorientationImageFilter_txx #define _itkPreservationOfPrincipalDirectionTensorReorientationImageFilter_txx #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkImageRegionConstIterator.h" #include "itkNeighborhoodAlgorithm.h" #include "itkOffset.h" #include "itkProgressReporter.h" #include "itkObjectFactory.h" #include "itkVector.h" #include "itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkNumericTraitsFixedArrayPixel.h" #include "itkVariableSizeMatrix.h" #include "itkDecomposeTensorFunction.h" #include "itkSymmetricSecondRankTensor.h" #include #include #include "vnl/algo/vnl_qr.h" #include "vnl/algo/vnl_svd.h" //#include namespace itk { template PreservationOfPrincipalDirectionTensorReorientationImageFilter ::PreservationOfPrincipalDirectionTensorReorientationImageFilter() { m_DeformationField = NULL; m_ReferenceImage = NULL; } template vnl_matrix PreservationOfPrincipalDirectionTensorReorientationImageFilter ::FindRotation( vnl_vector from , vnl_vector to) { #define CROSS(dest,v1,v2){ \ dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0];} #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2){ \ dest[0]=v1[0]-v2[0]; \ dest[1]=v1[1]-v2[1]; \ dest[2]=v1[2]-v2[2];} /* * A function for creating a rotation matrix that rotates a vector called * "f rom" into another vector called "to". * Input : from[3], to[3] which both must be *normalized* non-zero vectors * Output: mtx[3][3] -- a 3x3 matrix in colum-major form * Author: Tomas Moller, 1999 */ VnlMatrixType M(3,3); M.fill(0); float v[3]; float e,h; CROSS(v,from,to); e=DOT(from,to); float EPSILON=1.e-5; if(e>1.0-EPSILON) /* "from" almost or equal to "to"-vector? */ { /* return identity */ M(0, 0)=1.0; M(0, 1)=0.0; M(0, 2)=0.0; M(1, 0)=0.0; M(1, 1)=1.0; M(1, 2)=0.0; M(2, 0)=0.0; M(2, 1)=0.0; M(2, 2)=1.0; } else if(e<-1.0+EPSILON) /* "from" almost or equal to negated "to"? */ { float up[3],left[3]; float invlen; float fxx,fyy,fzz,fxy,fxz,fyz; float uxx,uyy,uzz,uxy,uxz,uyz; float lxx,lyy,lzz,lxy,lxz,lyz; /* left=CROSS(from, (1,0,0)) */ left[0]=0.0; left[1]=from[2]; left[2]=-from[1]; if(DOT(left,left) itk::SymmetricSecondRankTensor< float, 3 > PreservationOfPrincipalDirectionTensorReorientationImageFilter ::ReorientTensors( itk::SymmetricSecondRankTensor< float, 3 > fixedTens, itk::SymmetricSecondRankTensor< float, 3 > movingTens, typename TTensorImage::IndexType index) { // get from and to vectors VnlMatrixType fDT(3,3); fDT.fill(0); fDT(0,0)=fixedTens[0]; fDT(1,1)=fixedTens[3]; fDT(2,2)=fixedTens[5]; fDT(1,0)=fDT(0,1)=fixedTens[1]; fDT(2,0)=fDT(0,2)=fixedTens[2]; fDT(2,1)=fDT(1,2)=fixedTens[4]; VnlMatrixType mDT(3,3); mDT.fill(0); mDT(0,0)=movingTens[0]; mDT(1,1)=movingTens[3]; mDT(2,2)=movingTens[5]; mDT(1,0)=mDT(0,1)=movingTens[1]; mDT(2,0)=mDT(0,2)=movingTens[2]; mDT(2,1)=mDT(1,2)=movingTens[4]; // find rotation that maps 1st eigvecs - apply vnl_symmetric_eigensystem< float > eig(fDT); vnl_symmetric_eigensystem< float > meig(mDT); // get angle between vecs vvec from = meig.get_eigenvector(2); vvec to = eig.get_eigenvector(2) ; float dp = dot_product(from,to); float angletheta=0; if (dp >= 0.9999) angletheta = 0; else angletheta = acos(dp ) *180/3.1614 ; if ( angletheta > 90 ) { from = from * (-1.0); angletheta = 180 - 90; } // this->m_ThetaE+=theta; // if ( theta >= 45 ) { from = from * (90-theta)/90 + to * theta/90; from = from / sqrt(dot_product(from,from)); } //from = from * 0.5 + to * 0.5; from = from / sqrt(dot_product(from,from)); VnlMatrixType M = this->FindRotation(from, to ); // VnlMatrixType rDT = M*mDT*M.transpose(); vvec rvec = M*meig.get_eigenvector(1); // find rotation that maps 2nd eigvecs - apply from = rvec; to = eig.get_eigenvector(1) ; dp = dot_product(from,to); float anglepsi=0; if (dp >= 0.9999) anglepsi = 0; else anglepsi = acos(dp ) *180/3.1614 ; if ( anglepsi > 90 ) { from = from * (-1.0); anglepsi = 180 - 90; } if(this->m_AngleEnergyImage) { float mag=angletheta;//+anglepsi*anglepsi); this->m_AngleEnergyImage->SetPixel(index,mag); } VnlMatrixType M2 = this->FindRotation(from, to ); M2= M2*M; VnlMatrixType rDT = M2*mDT*M2.transpose(); TensorType rmovingTens; rmovingTens[0] = rDT[0][0]; rmovingTens[1] = rDT[1][0]; rmovingTens[2] = rDT[2][0]; rmovingTens[3] = rDT[1][1]; rmovingTens[4] = rDT[1][2]; rmovingTens[5] = rDT[2][2]; return rmovingTens; } template typename TTensorImage::PixelType PreservationOfPrincipalDirectionTensorReorientationImageFilter ::PPD(typename TTensorImage::IndexType index, vnl_matrix jMatrix ) { // typedef vnl_matrix VMatrixType; InputImagePointer input = this->GetInput(); InputPixelType dtv = input->GetPixel(index); itk::Vector dtv2; VnlMatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; vnl_symmetric_eigensystem< float > eig(DT); typedef vnl_vector vvec; vvec e1 = eig.get_eigenvector(2); vvec e1p = jMatrix*e1; e1p = e1p / sqrt(dot_product(e1p,e1p)); vvec e2 = jMatrix*eig.get_eigenvector(1); vvec e2p = e2 - dot_product( e2, e1p)*e1p; e2p = e2p / sqrt(dot_product(e2p,e2p)); vvec e3p = vnl_cross_3d(e1p,e2p); e3p = e3p / sqrt(dot_product(e3p,e3p)); VnlMatrixType DTrec = eig.get_eigenvalue(2) * outer_product(e1p,e1p) + eig.get_eigenvalue(1) * outer_product(e2p,e2p) + eig.get_eigenvalue(0) * outer_product(e3p,e3p); // if ( (eig.get_eigenvalue(2) - eig.get_eigenvalue(1)) > 0.5 ) { // std::cout << " DT IN " << DT << std::endl; // std::cout << " DT OU " << DTrec << std::endl; // std::cout << " eig1 " << eig.get_eigenvalue(0) << " 2 " << eig.get_eigenvalue(1) << std::endl; } dtv2[0]=DTrec(0,0); dtv2[3]=DTrec(1,1); dtv2[5]=DTrec(2,2); dtv2[1]=DTrec(0,1); dtv2[2]=DTrec(0,2); dtv2[4]=DTrec(1,2); return dtv2; } template void PreservationOfPrincipalDirectionTensorReorientationImageFilter ::GenerateData() { typedef VariableSizeMatrix MatrixType2; // get input and output images InputImagePointer input = this->GetInput(); OutputImagePointer output = this->GetOutput(); InputSizeType inputSize = input->GetLargestPossibleRegion().GetSize(); output->SetRegions( m_DeformationField->GetLargestPossibleRegion() ); output->SetSpacing( m_DeformationField->GetSpacing() ); output->SetOrigin( m_DeformationField->GetOrigin() ); output->SetDirection( m_DeformationField->GetDirection() ); output->Allocate(); this->m_AngleEnergyImage=FloatImageType::New(); this->m_AngleEnergyImage->SetRegions( m_DeformationField->GetLargestPossibleRegion() ); this->m_AngleEnergyImage->SetSpacing(m_DeformationField->GetSpacing()); this->m_AngleEnergyImage->SetOrigin(m_DeformationField->GetOrigin()); this->m_AngleEnergyImage->Allocate(); this->m_AngleEnergyImage->FillBuffer(0); ImageRegionConstIterator< InputImageType > inputIt( input, input->GetLargestPossibleRegion() ); ImageRegionIteratorWithIndex< OutputImageType > outputIt( output, output->GetLargestPossibleRegion() ); typedef itk::VectorLinearInterpolateImageFunction< InputImageType > VectorInterpType; typename VectorInterpType::Pointer inputInterp = VectorInterpType::New(); inputInterp->SetInputImage( input ); //DeformationFieldPointer tempField=DeformationFieldType::New(); // copy field to TempField //tempField->SetSpacing(m_DeformationField->GetSpacing() ); //tempField->SetOrigin(m_DeformationField->GetOrigin() ); //tempField->SetLargestPossibleRegion( // m_DeformationField->GetLargestPossibleRegion() ); //tempField->SetRequestedRegion( // m_DeformationField->GetRequestedRegion() ); //tempField->SetBufferedRegion(m_DeformationField->GetBufferedRegion() ); //tempField->Allocate(); // tempField->FillBuffer( ); //for ( inputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt ) //{ // tempField->SetPixel( inputIt.GetIndex(), m_DeformationField->GetPixel( inputIt.GetIndex())); //} ImageRegionIteratorWithIndex< DeformationFieldType > dispIt( m_DeformationField, m_DeformationField->GetLargestPossibleRegion() ); //double det=0.0; unsigned int posoff=1; //float difspace=1.0; float space=1.0; unsigned long ct = 0; // for all voxels for ( outputIt.GoToBegin(), dispIt.GoToBegin(); !outputIt.IsAtEnd(), !dispIt.IsAtEnd(); ++outputIt, ++dispIt ) { MatrixType2 jMatrix; jMatrix.SetSize(ImageDimension,ImageDimension); jMatrix.Fill(0.0); // Get Jacobian of displacement field typename DeformationFieldType::IndexType rindex=dispIt.GetIndex(); float mindist=1.0; bool oktosample=true; float dist=100.0; // ignore outer edges of warpfield for (unsigned int row=0; rowGetLargestPossibleRegion().GetSize()[row]-(float)rindex[row] ); if (dist < mindist) oktosample=false; } typename OutputImageType::PointType outputPt; output->TransformIndexToPhysicalPoint(outputIt.GetIndex(), outputPt); if (!inputInterp->IsInsideBuffer(outputPt)) oktosample=false; if (oktosample) { typename DeformationFieldType::IndexType temp = rindex; typename DeformationFieldType::PixelType cpix =this->TransformVector( m_DeformationField, rindex); typename DeformationFieldType::IndexType difIndex[ImageDimension][2]; for(unsigned int row=0; row< ImageDimension; row++) { difIndex[row][0]=rindex; difIndex[row][1]=rindex; typename DeformationFieldType::IndexType ddrindex=rindex; typename DeformationFieldType::IndexType ddlindex=rindex; if (rindex[row] < (int)m_DeformationField->GetLargestPossibleRegion().GetSize()[row]-2) { difIndex[row][0][row] = rindex[row]+posoff; ddrindex[row] = rindex[row]+posoff*2; } if (rindex[row] > 1 ) { difIndex[row][1][row] = rindex[row]-1; ddlindex[row] = rindex[row]-2; } float h=0.25; space=1.0; // should use image spacing here? typename DeformationFieldType::PixelType rpix = this->TransformVector( m_DeformationField,difIndex[row][1]); typename DeformationFieldType::PixelType lpix = this->TransformVector( m_DeformationField,difIndex[row][0]); typename DeformationFieldType::PixelType rrpix = this->TransformVector( m_DeformationField,ddrindex ); typename DeformationFieldType::PixelType llpix = this->TransformVector( m_DeformationField,ddlindex); rpix = rpix*h+cpix*(1.-h); lpix = lpix*h+cpix*(1.-h); rrpix = rrpix*h+rpix*(1.-h); llpix = llpix*h+lpix*(1.-h); //4th order centered difference typename DeformationFieldType::PixelType dPix; dPix= ( lpix*8.0 - rpix*8.0 + rrpix - llpix )*space/(12.0); //4th order centered differenceX for(unsigned int col=0; col< ImageDimension;col++) { float val; if (row == col) val=dPix[col]/m_DeformationField->GetSpacing()[col]+1.0; else val = dPix[col]/m_DeformationField->GetSpacing()[col]; jMatrix(col,row) = val; } } bool finitestrain = false; //finitestrain=true; bool ppd=true; if (finitestrain) ppd=false; InputPixelType outTensor; if (finitestrain) { // std::cout <<" use finite strain " << std::endl; // Copy tensor to matrix form //InputPixelType inTensor = inputIt.Value(); InputPixelType inTensor = input->GetPixel(rindex); //inputInterp->Evaluate(outputPt); MatrixType2 tensor; tensor.SetSize(3,3); tensor[0][0] = inTensor[0]; tensor[0][1] = tensor[1][0] = inTensor[1]; tensor[0][2] = tensor[2][0] = inTensor[2]; tensor[1][1] = inTensor[3]; tensor[1][2] = tensor[2][1] = inTensor[4]; tensor[2][2] = inTensor[5]; // replace with Polar Decomposition MatrixType2 rotationMatrix; MatrixType2 rotationMatrixT; VnlMatrixType M = jMatrix.GetVnlMatrix(); VnlMatrixType PQ = M; VnlMatrixType NQ = M; VnlMatrixType PQNQDiff; const unsigned int maximumIterations = 100; for(unsigned int ni = 0; ni < maximumIterations; ni++ ) { // Average current Qi with its inverse transpose NQ = ( PQ + vnl_inverse_transpose( PQ ) ) / 2.0; PQNQDiff = NQ - PQ; if( PQNQDiff.frobenius_norm() < 1e-4 ) { //std::cout << "Polar decomposition used " << ni << " iterations " << std::endl; break; } else { PQ = NQ; } } rotationMatrix = NQ; rotationMatrixT=rotationMatrix.GetTranspose(); // Rotate tensor MatrixType2 rTensor = rotationMatrixT * tensor * rotationMatrix; // Copy tensor back to vector form and update output image outTensor[0] = rTensor[0][0]; outTensor[1] = rTensor[1][0]; outTensor[2] = rTensor[2][0]; outTensor[3] = rTensor[1][1]; outTensor[4] = rTensor[1][2]; outTensor[5] = rTensor[2][2]; } else if (ppd) { // std::cout <<" use ppd reorientation " << std::endl; //InputPixelType inTensor = inputIt.Value(); InputPixelType inTensor = input->GetPixel(rindex); //inputInterp->Evaluate(outputPt); InputPixelType dtv = inTensor; // valid values? bool docompute=true; for (unsigned int jj=0; jj<6; jj++) { float ff=dtv[jj]; if ( vnl_math_isnan(ff)) { docompute=false; } } if (docompute) { TensorType dtv2; bool verbose=false; VnlMatrixType DT(3,3); DT.fill(0); DT(0,0)=dtv[0]; DT(1,1)=dtv[3]; DT(2,2)=dtv[5]; DT(1,0)=DT(0,1)=dtv[1]; DT(2,0)=DT(0,2)=dtv[2]; DT(2,1)=DT(1,2)=dtv[4]; if (verbose) std::cout << " DT " << DT << std::endl; if (verbose) std::cout << " jM " << jMatrix << std::endl; vnl_symmetric_eigensystem< float > eig(DT); typedef vnl_vector vvec; vvec e1 = eig.get_eigenvector(2); vvec e1p = jMatrix.GetTranspose() * e1; e1p = e1p / sqrt(dot_product(e1p,e1p)); vvec e2 = jMatrix.GetTranspose()* eig.get_eigenvector(1); vvec e2p = e2 - dot_product( e2, e1p)*e1p; e2p = e2p / sqrt(dot_product(e2p,e2p)); vvec e3p = vnl_cross_3d(e1p,e2p); e3p = e3p / sqrt(dot_product(e3p,e3p)); VnlMatrixType DTrec = eig.get_eigenvalue(2) * outer_product(e1p,e1p) + eig.get_eigenvalue(1) * outer_product(e2p,e2p) + eig.get_eigenvalue(0) * outer_product(e3p,e3p); if (verbose) std::cout << " DTrec " << DTrec << " ind " << rindex << std::endl; dtv2[0]=DTrec(0,0); dtv2[3]=DTrec(1,1); dtv2[5]=DTrec(2,2); dtv2[1]=DTrec(0,1); dtv2[2]=DTrec(0,2); dtv2[4]=DTrec(1,2); outTensor = dtv2; } else outTensor=inTensor; } if (this->m_ReferenceImage) { typename InputImageType::PixelType refTensor=this->m_ReferenceImage->GetPixel(outputIt.GetIndex()); outTensor=this->ReorientTensors(refTensor, outTensor,outputIt.GetIndex()); } outputIt.Set( outTensor ); //std::cout << inputIt.Value() << " - " << outputIt.Value() << " "; }//oktosample if else outputIt.Set( inputIt.Value() ); ct++; } //pixelIterations } /** * Standard "PrintSelf" method */ template void PreservationOfPrincipalDirectionTensorReorientationImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Tensor/itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.h000066400000000000000000000142711147325206600333400ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.h,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkPreservationOfPrincipalDirectionTensorReorientationImageFilter_h #define __itkPreservationOfPrincipalDirectionTensorReorientationImageFilter_h #include "itkImageToImageFilter.h" #include "itkVectorInterpolateImageFunction.h" #include "itkImage.h" #include "itkMatrix.h" #include "itkNumericTraits.h" #include "itkVector.h" #include "itkSymmetricSecondRankTensor.h" namespace itk { /** \class PreservationOfPrincipalDirectionImageFilter * \brief Applies an averaging filter to an image * * Computes an image where a given pixel is the mean value of the * the pixels in a neighborhood about the corresponding input pixel. * * A mean filter is one of the family of linear filters. * * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * * \ingroup IntensityImageFilters */ template class ITK_EXPORT PreservationOfPrincipalDirectionTensorReorientationImageFilter : public ImageToImageFilter< TTensorImage, TTensorImage > { public: typedef TTensorImage InputImageType; typedef TTensorImage OutputImageType; typedef TVectorImage DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef Matrix MatrixType; typedef Vector VectorType; typedef Vector FakeVectorType; itkStaticConstMacro(ImageDimension, unsigned int, TTensorImage::ImageDimension); typedef itk::Image FloatImageType; // typedef Vector TensorType; typedef itk::SymmetricSecondRankTensor< float, 3 > TensorType; typedef Image TensorImageType; typedef typename TensorImageType::Pointer TensorImagePointer; typedef vnl_matrix VnlMatrixType; typedef vnl_vector vvec; /** Standard class typedefs. */ typedef PreservationOfPrincipalDirectionTensorReorientationImageFilter Self; typedef ImageToImageFilter< InputImageType, OutputImageType> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); itkSetMacro(DeformationField, DeformationFieldPointer); itkGetMacro(DeformationField, DeformationFieldPointer); /** Run-time type information (and related methods). */ itkTypeMacro(PreservationOfPrincipalDirectionTensorReorientationImageFilter, ImageToImageFilter); /** Image typedef support. */ typedef typename InputImageType::ConstPointer InputImagePointer; typedef typename OutputImageType::Pointer OutputImagePointer; typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputPixelType::ValueType InputRealType; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef typename InputImageType::SizeType InputSizeType; typedef typename OutputImageType::SizeType OutputSizeType; typedef typename InputImageType::IndexType InputIndexType; typedef typename OutputImageType::IndexType OutputIndexType; InputPixelType PPD(typename InputImageType::IndexType ind , VnlMatrixType jac); vnl_matrix FindRotation( vnl_vector , vnl_vector); TensorType ReorientTensors( TensorType fixedTens, TensorType movingTens, typename TTensorImage::IndexType index); // ::ReorientTensors( Vector fixedTens, Vector movingTens, typename TTensorImage::IndexType index) TensorImagePointer m_ReferenceImage; typename FloatImageType::Pointer m_ThetaImage; typename FloatImageType::Pointer m_PsiImage; typename FloatImageType::Pointer m_AngleEnergyImage; protected: PreservationOfPrincipalDirectionTensorReorientationImageFilter(); virtual ~PreservationOfPrincipalDirectionTensorReorientationImageFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; /** PreservationOfPrincipalDirectionTensorReorientationImageFilter can be implemented as a multithreaded filter. * Therefore, this implementation provides a ThreadedGenerateData() * routine which is called for each processing thread. The output * image data is allocated automatically by the superclass prior to * calling ThreadedGenerateData(). ThreadedGenerateData can only * write to the portion of the output image specified by the * parameter "outputRegionForThread" * * \sa ImageToImageFilter::ThreadedGenerateData(), * ImageToImageFilter::GenerateData() */ void GenerateData( void ); typename DeformationFieldType::PixelType TransformVector(DeformationFieldType* field, typename FloatImageType::IndexType index ) { typename DeformationFieldType::PixelType vec=field->GetPixel(index); typename DeformationFieldType::PixelType newvec; newvec.Fill(0); for (unsigned int row=0; rowGetDirection()[row][col]; return newvec; } private: PreservationOfPrincipalDirectionTensorReorientationImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented DeformationFieldPointer m_DeformationField; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkPreservationOfPrincipalDirectionTensorReorientationImageFilter.cxx" #endif #endif ants-1.9.2+svn680.dfsg/Tensor/itkRotationMatrixFromVectors.h000066400000000000000000000133661147325206600240020ustar00rootroot00000000000000/* from * @article{MollerHughes99, author = "Tomas Mller and John F. Hughes", title = "Efficiently Building a Matrix to Rotate One Vector to Another", journal = "journal of graphics tools", volume = "4", number = "4", pages = "1-4", year = "1999", } http://jgt.akpeters.com/papers/MollerHughes99/code.html */ #include #include #include template MatrixType RotationMatrixFromVectors(VectorType from, VectorType to) { double EPSILON = 0.000001; typename VectorType::ValueType e,h,f; MatrixType mtx; VectorType v = CrossProduct(from, to); e = from*to; f = (e < 0) ? -e: e; if (f > 1.0 - EPSILON) /* "from" and "to"-vector almost parallel */ { VectorType u, v; /* temporary storage vectors */ VectorType x; /* vector most nearly orthogonal to "from" */ float c1, c2, c3; /* coefficients for later use */ int i, j; x[0] = (from[0] > 0.0)? from[0] : -from[0]; x[1] = (from[1] > 0.0)? from[1] : -from[1]; x[2] = (from[2] > 0.0)? from[2] : -from[2]; if (x[0] < x[1]) { if (x[0] < x[2]) { x[0] = 1.0; x[1] = x[2] = 0.0; } else { x[2] = 1.0; x[0] = x[1] = 0.0; } } else { if (x[1] < x[2]) { x[1] = 1.0; x[0] = x[2] = 0.0; } else { x[2] = 1.0; x[0] = x[1] = 0.0; } } u[0] = x[0] - from[0]; u[1] = x[1] - from[1]; u[2] = x[2] - from[2]; v[0] = x[0] - to[0]; v[1] = x[1] - to[1]; v[2] = x[2] - to[2]; c1 = 2.0 / (u*u); c2 = 2.0 / (v*v); c3 = c1 * c2 * (u*v); for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { mtx[i][j] = - c1 * u[i] * u[j] - c2 * v[i] * v[j] + c3 * v[i] * u[j]; } mtx[i][i] += 1.0; } } else /* the most common case, unless "from"="to", or "from"=-"to" */ { /* ...otherwise use this hand optimized version (9 mults less) */ float hvx, hvz, hvxy, hvxz, hvyz; /* h = (1.0 - e)/DOT(v, v); old code */ h = 1.0/(1.0 + e); /* optimization by Gottfried Chen */ hvx = h * v[0]; hvz = h * v[2]; hvxy = hvx * v[1]; hvxz = hvx * v[2]; hvyz = hvz * v[1]; mtx[0][0] = e + hvx * v[0]; mtx[0][1] = hvxy - v[2]; mtx[0][2] = hvxz + v[1]; mtx[1][0] = hvxy + v[2]; mtx[1][1] = e + h * v[1] * v[1]; mtx[1][2] = hvyz - v[0]; mtx[2][0] = hvxz - v[1]; mtx[2][1] = hvyz + v[0]; mtx[2][2] = e + hvz * v[2]; } return mtx; } // /* // * A function for creating a rotation matrix that rotates a vector called // * "from" into another vector called "to". // * Input : from[3], to[3] which both must be *normalized* non-zero vectors // * Output: mtx[3][3] -- a 3x3 matrix in colum-major form // * Authors: Tomas Mller, John Hughes // * "Efficiently Building a Matrix to Rotate One Vector to Another" // * Journal of Graphics Tools, 4(4):1-4, 1999 // */ // void fromToRotation(float from[3], float to[3], float mtx[3][3]) { // float v[3]; // float e, h, f; // CROSS(v, from, to); // e = DOT(from, to); // f = (e < 0)? -e:e; // if (f > 1.0 - EPSILON) /* "from" and "to"-vector almost parallel */ // { // float u[3], v[3]; /* temporary storage vectors */ // float x[3]; /* vector most nearly orthogonal to "from" */ // float c1, c2, c3; /* coefficients for later use */ // int i, j; // x[0] = (from[0] > 0.0)? from[0] : -from[0]; // x[1] = (from[1] > 0.0)? from[1] : -from[1]; // x[2] = (from[2] > 0.0)? from[2] : -from[2]; // if (x[0] < x[1]) // { // if (x[0] < x[2]) // { // x[0] = 1.0; x[1] = x[2] = 0.0; // } // else // { // x[2] = 1.0; x[0] = x[1] = 0.0; // } // } // else // { // if (x[1] < x[2]) // { // x[1] = 1.0; x[0] = x[2] = 0.0; // } // else // { // x[2] = 1.0; x[0] = x[1] = 0.0; // } // } // u[0] = x[0] - from[0]; u[1] = x[1] - from[1]; u[2] = x[2] - from[2]; // v[0] = x[0] - to[0]; v[1] = x[1] - to[1]; v[2] = x[2] - to[2]; // c1 = 2.0 / DOT(u, u); // c2 = 2.0 / DOT(v, v); // c3 = c1 * c2 * DOT(u, v); // for (i = 0; i < 3; i++) { // for (j = 0; j < 3; j++) { // mtx[i][j] = - c1 * u[i] * u[j] // - c2 * v[i] * v[j] // + c3 * v[i] * u[j]; // } // mtx[i][i] += 1.0; // } // } // else /* the most common case, unless "from"="to", or "from"=-"to" */ // { // #if 0 // /* unoptimized version - a good compiler will optimize this. */ // /* h = (1.0 - e)/DOT(v, v); old code */ // h = 1.0/(1.0 + e); /* optimization by Gottfried Chen */ // mtx[0][0] = e + h * v[0] * v[0]; // mtx[0][1] = h * v[0] * v[1] - v[2]; // mtx[0][2] = h * v[0] * v[2] + v[1]; // mtx[1][0] = h * v[0] * v[1] + v[2]; // mtx[1][1] = e + h * v[1] * v[1]; // mtx[1][2] = h * v[1] * v[2] - v[0]; // mtx[2][0] = h * v[0] * v[2] - v[1]; // mtx[2][1] = h * v[1] * v[2] + v[0]; // mtx[2][2] = e + h * v[2] * v[2]; // #else // /* ...otherwise use this hand optimized version (9 mults less) */ // float hvx, hvz, hvxy, hvxz, hvyz; // /* h = (1.0 - e)/DOT(v, v); old code */ // h = 1.0/(1.0 + e); /* optimization by Gottfried Chen */ // hvx = h * v[0]; // hvz = h * v[2]; // hvxy = hvx * v[1]; // hvxz = hvx * v[2]; // hvyz = hvz * v[1]; // mtx[0][0] = e + hvx * v[0]; // mtx[0][1] = hvxy - v[2]; // mtx[0][2] = hvxz + v[1]; // mtx[1][0] = hvxy + v[2]; // mtx[1][1] = e + h * v[1] * v[1]; // mtx[1][2] = hvyz - v[0]; // mtx[2][0] = hvxz - v[1]; // mtx[2][1] = hvyz + v[0]; // mtx[2][2] = e + hvz * v[2]; // #endif // } // } ants-1.9.2+svn680.dfsg/Tensor/itkWarpTensorImageMultiTransformFilter.h000066400000000000000000000303651147325206600257460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpTensorImageMultiTransformFilter.h,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef ITKWarpTensorImageMultiTRANSFORMFILTER_H_ #define ITKWarpTensorImageMultiTRANSFORMFILTER_H_ #include "itkImageToImageFilter.h" #include "itkVectorInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkPoint.h" #include "itkFixedArray.h" #include "itkRecursiveGaussianImageFilter.h" #include #include namespace itk { /** \class WarpTensorImageMultiTransformFilter * \brief Warps a tensor image using an input deformation field. * * WarpTensorImageMultiTransformFilter warps an existing tensor image with respect to * a given deformation field. * * A deformation field is represented as a image whose pixel type is some * vector type with at least N elements, where N is the dimension of * the input image. The vector type must support element access via operator * []. * * The output image is produced by inverse mapping: the output pixels * are mapped back onto the input image. This scheme avoids the creation of * any holes and overlaps in the output image. * * Each vector in the deformation field represent the distance between * a geometric point in the input space and a point in the output space such * that: * * \f[ p_{in} = p_{out} + d \f] * * Typically the mapped position does not correspond to an integer pixel * position in the input image. Interpolation via an image function * is used to compute values at non-integer positions. The default * interpolation typed used is the LinearInterpolateImageFunction. * The user can specify a particular interpolation function via * SetInterpolator(). Note that the input interpolator must derive * from base class InterpolateImageFunction. * * Position mapped to outside of the input image buffer are assigned * a edge padding value. * * The LargetPossibleRegion for the output is inherited from the * input deformation field. The output image spacing and origin may be set * via SetOutputSpacing, SetOutputOrigin. The default are respectively a * vector of 1's and a vector of 0's. * * This class is templated over the type of the input image, the * type of the output image and the type of the deformation field. * * The input image is set via SetInput. The input deformation field * is set via SetDeformationField. * * This filter is implemented as a multithreaded filter. * * \warning This filter assumes that the input type, output type * and deformation field type all have the same number of dimensions. * * \ingroup GeometricTransforms MultiThreaded */ template < class TInputImage, class TOutputImage, class TDeformationField, class TTransform > class ITK_EXPORT WarpTensorImageMultiTransformFilter : public ImageToImageFilter { public: /** transform order type **/ // typedef enum _TransformOrderType {AffineFirst=0, AffineLast} TransformOrderType; /** transform type **/ typedef enum _SingleTransformType {EnumAffineType=0, EnumDeformationFieldType} SingleTransformType; /** Standard class typedefs. */ typedef WarpTensorImageMultiTransformFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro( WarpTensorImageMultiTransformFilter, ImageToImageFilter ); /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Inherit some types from the superclass. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImagePointer InputImagePointer; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImagePointer OutputImagePointer; typedef typename Superclass::InputImageConstPointer InputImageConstPointer; typedef typename OutputImageType::IndexType IndexType; typedef typename OutputImageType::SizeType SizeType; typedef typename OutputImageType::PixelType PixelType; typedef typename OutputImageType::SpacingType SpacingType; typedef typename OutputImageType::DirectionType DirectionType; /** Determine the image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro(DeformationFieldDimension, unsigned int, TDeformationField::ImageDimension ); /** Deformation field typedef support. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType DisplacementType; typedef typename DisplacementType::ValueType DisplacementScalarValueType; /** songgang: Affine transform typedef support. */ typedef TTransform TransformType; typedef typename TransformType::Pointer TransformTypePointer; /** Interpolator typedef support. */ typedef double CoordRepType; typedef VectorInterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef VectorLinearInterpolateImageFunction DefaultVectorInterpolatorType; typedef typename DefaultVectorInterpolatorType::Pointer VectorInterpolatorPointer; /** Point type */ typedef Point PointType; typedef struct _DeformationTypeEx{ DeformationFieldPointer field; VectorInterpolatorPointer vinterp; } DeformationTypeEx; typedef struct _AffineTypeEx{ TransformTypePointer aff; } AffineTypeEx; typedef struct _VarTransformType{ AffineTypeEx aex; DeformationTypeEx dex; } VarTransformType; typedef std::pair SingleTransformItemType; typedef std::list TransformListType; /** Set the interpolator function. */ itkSetObjectMacro( Interpolator, InterpolatorType ); /** Get a pointer to the interpolator function. */ itkGetObjectMacro( Interpolator, InterpolatorType ); /** Set the output image spacing. */ itkSetMacro(OutputSpacing, SpacingType); virtual void SetOutputSpacing( const double* values); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputSpacing, SpacingType); /** Set the output image spacing. */ itkSetMacro(OutputDirection, DirectionType); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputDirection, DirectionType); /** Set the output image origin. */ itkSetMacro(OutputOrigin, PointType); virtual void SetOutputOrigin( const double* values); /** Get the output image origin. */ itkGetConstReferenceMacro(OutputOrigin, PointType); /** Set the output image size. */ itkSetMacro(OutputSize, SizeType); // virtual void SetOutputSize( const double *values); itkGetConstReferenceMacro(OutputSize, SizeType); /** Set the edge padding value */ itkSetMacro( EdgePaddingValue, PixelType ); /** Get the edge padding value */ itkGetMacro( EdgePaddingValue, PixelType ); TransformListType & GetTransformList(){ return m_TransformList; } void PrintTransformList(); /** WarpTensorImageMultiTransformFilter produces an image which is a different * size than its input image. As such, it needs to provide an * implemenation for GenerateOutputInformation() which set * the output information according the OutputSpacing, OutputOrigin * and the deformation field's LargestPossibleRegion. */ virtual void GenerateOutputInformation(); /** It is difficult to compute in advance the input image region * required to compute the requested output region. Thus the safest * thing to do is to request for the whole input image. * * For the deformation field, the input requested region * set to be the same as that of the output requested region. */ virtual void GenerateInputRequestedRegion(); /** This method is used to set the state of the filter before * multi-threading. */ virtual void BeforeThreadedGenerateData(); /** This method is used to set the state of the filter after * multi-threading. */ virtual void AfterThreadedGenerateData(); /** precompute the smoothed image if necessary **/ void SetSmoothScale(double scale); double GetSmoothScale() {return m_SmoothScale;}; // void UpdateSizeByScale(); void PushBackAffineTransform(const TransformType* t); void PushBackDeformationFieldTransform(const DeformationFieldType* t); bool MultiInverseAffineOnlySinglePoint(const PointType &point1, PointType &point2); bool MultiTransformSinglePoint(const PointType &point1, PointType &point2); bool MultiTransformPoint(const PointType &point1, PointType &point2, bool bFisrtDeformNoInterp, const IndexType &index); void DetermineFirstDeformNoInterp(); inline bool IsOutOfNumericBoundary(const PointType &p); // set interpolator from outside // virtual void SetInterpolator(InterpolatorPointer interp); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(SameDimensionCheck1, (Concept::SameDimension)); itkConceptMacro(SameDimensionCheck2, (Concept::SameDimension)); //removed to be compatible with vector form input image // itkConceptMacro(InputHasNumericTraitsCheck, // (Concept::HasNumericTraits)); itkConceptMacro(DeformationFieldHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif bool m_bFirstDeformNoInterp; protected: WarpTensorImageMultiTransformFilter(); ~WarpTensorImageMultiTransformFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; /** WarpTensorImageMultiTransformFilter is implemented as a multi-threaded filter. * As such, it needs to provide and implementation for * ThreadedGenerateData(). */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); InterpolatorPointer m_Interpolator; PixelType m_EdgePaddingValue; SpacingType m_OutputSpacing; PointType m_OutputOrigin; SizeType m_OutputSize; DirectionType m_OutputDirection; TransformListType m_TransformList; DeformationFieldPointer m_FullWarp; double m_SmoothScale; InputImagePointer m_CachedSmoothImage; private: WarpTensorImageMultiTransformFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkWarpTensorImageMultiTransformFilter.txx" #endif #endif /*ITKWarpTensorImageMultiTRANSFORMFILTER_H_*/ ants-1.9.2+svn680.dfsg/Tensor/itkWarpTensorImageMultiTransformFilter.txx000066400000000000000000000532751147325206600263470ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpTensorImageMultiTransformFilter.txx,v $ Language: C++ Date: $Date: 2009/01/27 19:56:28 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWarpTensorImageMultiTransformFilter_txx #define __itkWarpTensorImageMultiTransformFilter_txx #include "itkWarpTensorImageMultiTransformFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include #include "vnl/vnl_matrix.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "TensorFunctions.h" namespace itk { template TTensorType LogExpTensor( TTensorType inTensor, bool doLog ) { TTensorType result; if ( (inTensor[0] != inTensor[0] ) || (inTensor[1] != inTensor[1] ) || (inTensor[2] != inTensor[2] ) || (inTensor[3] != inTensor[3] ) || (inTensor[4] != inTensor[4] ) || (inTensor[5] != inTensor[5] ) ) { result[0] = result[1] = result[2] = result[3] = result[4] = result[5] = 0; //std::cout << " - " << inTensor << std::endl; return result; } double sigma = 1.0e-15; if ( (inTensor[0] < sigma ) || (inTensor[1] < sigma ) || (inTensor[2] < sigma ) || (inTensor[3] < sigma ) || (inTensor[4] < sigma ) || (inTensor[5] < sigma ) ) { result[0] = result[1] = result[2] = result[3] = result[4] = result[5] = 0; //std::cout << " - " << inTensor << std::endl; return result; } vnl_matrix tensor(3,3); tensor[0][0] = inTensor[0]; tensor[1][0] = tensor[0][1] = inTensor[1]; tensor[1][1] = inTensor[2]; tensor[2][0] = tensor[0][2] = inTensor[3]; tensor[2][1] = tensor[1][2] = inTensor[4]; tensor[2][2] = inTensor[5]; //std::cout << " + " << inTensor << std::endl; if ( ((tensor[0][0] == 0) && (tensor[0][1] == 0) && (tensor[0][2] == 0) && (tensor[1][1] == 0) && (tensor[1][2] == 0) && (tensor[2][2] == 0)) || (tensor.has_nans()) || (!tensor.is_finite()) ) { result[0] = result[1] = result[2] = result[3] = result[4] = result[5] = 0; } else { vnl_symmetric_eigensystem eSystem(tensor); for (unsigned int i=0; i<3; i++) { if (doLog) { eSystem.D[i] = vcl_log(vcl_fabs(eSystem.D[i])); } else { eSystem.D[i] = vcl_exp(eSystem.D[i]); } } vnl_matrix leTensor = eSystem.recompose(); result[0] = leTensor[0][0]; result[1] = leTensor[1][0]; result[2] = leTensor[1][1]; result[3] = leTensor[2][0]; result[4] = leTensor[2][1]; result[5] = leTensor[2][2]; } return result; } /** * Default constructor. */ template WarpTensorImageMultiTransformFilter ::WarpTensorImageMultiTransformFilter() { // Setup the number of required inputs this->SetNumberOfRequiredInputs( 1 ); // Setup default values m_OutputSpacing.Fill( 1.0 ); m_OutputOrigin.Fill( 0.0 ); m_EdgePaddingValue = NumericTraits::Zero; // Setup default interpolator typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_Interpolator = static_cast( interp.GetPointer() ); m_SmoothScale = -1; // m_bOutputDeformationField = false; // m_TransformOrder = AffineFirst; } //template //void //WarpTensorImageMultiTransformFilter //::SetInterpolator1(InterpolatorPointer interp) //{ // m_Interpolator = static_cast (interp.GetPointer()); // std::cout << "set interpolator in WarpImage:" << interp << std::endl; //} template void WarpTensorImageMultiTransformFilter ::PrintTransformList() { std::cout << "transform list: " << std::endl; typename TransformListType::iterator it = (m_TransformList.begin()); for(int ii=0; it != m_TransformList.end(); it++, ii++){ switch(it->first){ case EnumAffineType: std::cout << '[' << ii << "]: EnumAffineType" << std::endl; std::cout << it->second.aex.aff << std::endl; break; case EnumDeformationFieldType: std::cout << '[' << ii << "]: EnumDeformationFieldType: size" << it->second.dex.field->GetLargestPossibleRegion().GetSize() << std::endl; } } } /** * Standard PrintSelf method. */ template void WarpTensorImageMultiTransformFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "OutputSpacing: " << m_OutputSpacing << std::endl;; os << indent << "OutputOrigin: " << m_OutputOrigin << std::endl; os << indent << "EdgePaddingValue: " << static_cast::PrintType>(m_EdgePaddingValue) << std::endl; os << indent << "Interpolator: " << m_Interpolator.GetPointer() << std::endl; os << indent << "m_bFirstDeformNoInterp = " << m_bFirstDeformNoInterp << std::endl; } /** * Set the output image spacing. * */ template void WarpTensorImageMultiTransformFilter ::SetOutputSpacing( const double* spacing) { SpacingType s(spacing); this->SetOutputSpacing( s ); } /** * Set the output image origin. * */ template void WarpTensorImageMultiTransformFilter ::SetOutputOrigin( const double* origin) { PointType p(origin); this->SetOutputOrigin(p); } /** * Setup state of filter before multi-threading. * InterpolatorType::SetInputImage is not thread-safe and hence * has to be setup before ThreadedGenerateData */ template void WarpTensorImageMultiTransformFilter ::BeforeThreadedGenerateData() { if( !m_Interpolator ) { itkExceptionMacro(<< "Interpolator not set"); } // Connect input image to interpolator // m_Interpolator->SetInputImage( this->GetInput() ); if (m_CachedSmoothImage.IsNull() && (this->GetInput() )){ m_CachedSmoothImage = const_cast (this->GetInput()); } m_Interpolator->SetInputImage( m_CachedSmoothImage ); } /** * Setup state of filter after multi-threading. */ template void WarpTensorImageMultiTransformFilter ::AfterThreadedGenerateData() { // Disconnect input image from interpolator m_Interpolator->SetInputImage( NULL ); } template void WarpTensorImageMultiTransformFilter ::GenerateInputRequestedRegion() { // call the superclass's implementation Superclass::GenerateInputRequestedRegion(); // request the largest possible region for the input image InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if( inputPtr ) { inputPtr->SetRequestedRegionToLargestPossibleRegion(); } return; } template void WarpTensorImageMultiTransformFilter ::GenerateOutputInformation() { // call the superclass's implementation of this method Superclass::GenerateOutputInformation(); OutputImagePointer outputPtr = this->GetOutput(); if ( !outputPtr ) { return; } typename TOutputImage::RegionType outputLargestPossibleRegion; outputLargestPossibleRegion.SetSize( this->m_OutputSize ); // outputLargestPossibleRegion.SetIndex( 0 ); outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion ); outputPtr->SetSpacing( this->m_OutputSpacing ); outputPtr->SetOrigin( this->m_OutputOrigin ); outputPtr->SetDirection( this->m_OutputDirection ); //this->m_FullWarp->SetLargestPossibleRegion( outputLargestPossibleRegion ); //this->m_FullWarp->SetSpacing( this->m_OutputSpacing ); //this->m_FullWarp->SetOrigin( this->m_OutputOrigin ); //this->m_FullWarp->SetDirection( this->m_OutputDirection ); //this->m_FullWarp->Allocate(); // determine if the deformation field is the same dimension as the image // so that it does not need interpolation in the first step DetermineFirstDeformNoInterp(); } template void WarpTensorImageMultiTransformFilter ::SetSmoothScale(double scale) { /* if (m_SmoothScale != scale){ // compute the new cached // std::cout << "change smooth scale: " << m_SmoothScale << " ---> " << scale << std::endl; m_SmoothScale = scale; typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSpacing(); typename InputImageType::RegionType::SizeType inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize(); typename InputImageType::SpacingType outputSpacing; typename InputImageType::RegionType::SizeType outputSize; double minimumSpacing = inputSpacing.GetVnlVector().min_value(); double maximumSpacing = inputSpacing.GetVnlVector().max_value(); InputImagePointer image = const_cast (this->GetInput()); for ( unsigned int d = 0; d < ImageDimension; d++ ) { double scaling = vnl_math_min( 1.0 / scale * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); double sigma = 0.25 * ( outputSpacing[d] / inputSpacing[d] ); if (sigma < 0) sigma=0; typedef RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); // std::cout << "scale = " << scale << " => " << "sigma of dim " << d << ": " << sigma << " out size " << outputSize << " spc1 " << outputSpacing << " in " << inputSpacing << std::endl; smoother->SetSigma( sigma ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); image = smoother->GetOutput(); } } SetOutputSpacing( outputSpacing ); SetOutputOrigin( this->GetInput()->GetOrigin() ); SetOutputSize(outputSize); } */ InputImagePointer image = const_cast (this->GetInput()); m_CachedSmoothImage = image; } /** * Compute the output for the region specified by outputRegionForThread. */ template void WarpTensorImageMultiTransformFilter ::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, int threadId ) { InputImageConstPointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); //std::cout << "inputPtr->GetOrigin():" << inputPtr->GetOrigin() << std::endl; //std::cout << "outputPtr->GetOrigin():" << outputPtr->GetOrigin() << std::endl; // exit(-1); // Need to get full warp for reorientation of tensors IndexType index; index.Fill(0); this->m_EdgePaddingValue=inputPtr->GetPixel(index); // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // iterator for the output image ImageRegionIteratorWithIndex outputIt(outputPtr, outputRegionForThread); while( !outputIt.IsAtEnd() ) { PointType point1, point2; // get the output image index IndexType index = outputIt.GetIndex(); outputPtr->TransformIndexToPhysicalPoint( index, point1 ); bool isinside = MultiTransformPoint(point1, point2, m_bFirstDeformNoInterp, index); // std::cout << "point1:" << point1 << " point2:" << point2 << " index:" << index << std::endl; // exit(-1); //DeformationFieldType::PixelType diff; //diff[0] = point2[0]-point1[0]; //diff[1] = point2[1]-point1[1]; //diff[2] = point2[2]-point1[2]; // warp the image // get the interpolated value if( isinside && (m_Interpolator->IsInsideBuffer( point2 )) ) { PixelType value = static_cast(m_Interpolator->Evaluate(point2)); outputIt.Set( value ); } else { // std::cout << "OUTSIDE" << " isinside:" << isinside << " m_Interpolator->IsInsideBuffer( point2 ):" << m_Interpolator->IsInsideBuffer( point2 ) << std::endl; outputIt.Set( m_EdgePaddingValue ); } ++outputIt; } progress.CompletedPixel(); } //template //void //WarpTensorImageMultiTransformFilter //::UpdateSizeByScale() //{ // // // DeformationFieldPointer field = this->GetDeformationField(); // // // // SetOutputSpacing( field->GetSpacing() / m_SmoothScale ); // // SetOutputOrigin( field->GetOrigin() ); // // // // typename InputImageType::SizeType imgsz = field->GetLargestPossibleRegion().GetSize(); // // for(int ii = 0; ii < InputImageType::ImageDimension; ii++) imgsz[ii] = (typename InputImageType::SizeType::SizeValueType) (imgsz[ii] * m_SmoothScale + 0.5); // // // // SetOutputSize(imgsz); // //} template void WarpTensorImageMultiTransformFilter ::PushBackAffineTransform(const TransformType* t) { if (t){ VarTransformType t1; t1.aex.aff = const_cast (t); m_TransformList.push_back(SingleTransformItemType(EnumAffineType, t1)); } } template void WarpTensorImageMultiTransformFilter ::PushBackDeformationFieldTransform(const DeformationFieldType* t) { if (t){ VarTransformType t1; t1.dex.field = const_cast (t); t1.dex.vinterp = DefaultVectorInterpolatorType::New(); t1.dex.vinterp->SetInputImage(t1.dex.field); m_TransformList.push_back(SingleTransformItemType(EnumDeformationFieldType, t1)); } } template bool WarpTensorImageMultiTransformFilter ::MultiTransformSinglePoint(const PointType &point1, PointType &point2) { IndexType null_index; bool isinside = MultiTransformPoint(point1, point2, false, null_index); return isinside; } template bool WarpTensorImageMultiTransformFilter ::IsOutOfNumericBoundary(const PointType &p) { const DisplacementScalarValueType kMaxDisp = itk::NumericTraits::max(); bool b = false; for (int i = 0; i < ImageDimension; i++) { if (p[i]>=kMaxDisp ){ b = true; break; } } return b; } template bool WarpTensorImageMultiTransformFilter ::MultiInverseAffineOnlySinglePoint(const PointType &p1, PointType &p2) { bool isinside = true; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; TransformTypePointer aff_inv = TransformTypePointer::ObjectType::New(); // std::cout << "aff before:" << aff << std::endl; aff->GetInverse(aff_inv); // aff->GetInverse(aff); // std::cout << "aff after:" << aff << std::endl; // std::cout << "aff_inv after:" << aff_inv << std::endl; point2 = aff_inv->TransformPoint(point1); point1 = point2; isinside = true; break; } case EnumDeformationFieldType: break; default: itkExceptionMacro(<< "Single Transform Not Supported!"); } if (IsOutOfNumericBoundary(point2)) {isinside = false; break;} point1 = point2; } p2 = point2; return isinside; } template bool WarpTensorImageMultiTransformFilter ::MultiTransformPoint(const PointType &p1, PointType &p2, bool bFisrtDeformNoInterp, const IndexType &index) { bool isinside = false; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; point2 = aff->TransformPoint(point1); point1 = point2; isinside = true; } break; case EnumDeformationFieldType: { DeformationFieldPointer fieldPtr = it->second.dex.field; if (bFisrtDeformNoInterp && it==m_TransformList.begin() ){ // use discrete coordinates DisplacementType displacement = fieldPtr->GetPixel(index); for(int j = 0; jTransformPhysicalPointToContinuousIndex(point1, contind); isinside = fieldPtr->GetLargestPossibleRegion().IsInside( contind ); VectorInterpolatorPointer vinterp = it->second.dex.vinterp; typename DefaultVectorInterpolatorType::OutputType disp2; if (isinside) disp2 = vinterp->EvaluateAtContinuousIndex( contind ); else disp2.Fill(0); for (int jj=0; jj void WarpTensorImageMultiTransformFilter ::DetermineFirstDeformNoInterp() { m_bFirstDeformNoInterp = false; if (m_TransformList.size() >0 ){ if ((m_TransformList.front().first == EnumDeformationFieldType)){ DeformationFieldPointer field = m_TransformList.front().second.dex.field; m_bFirstDeformNoInterp = (this->GetOutputSize() == field->GetLargestPossibleRegion().GetSize()) & (this->GetOutputSpacing() ==field->GetSpacing()) & (this->GetOutputOrigin() == field->GetOrigin()); // std::cout << "in set: field size: " << field->GetLargestPossibleRegion().GetSize() // << "output spacing: " << this->GetOutputSize() << std::endl; // std::cout << field->GetSpacing() << " | " << this->GetOutputSpacing() << std::endl; // std::cout << field->GetOrigin() << " | " << this->GetOutputOrigin() << std::endl; } } } } // end namespace itk #endif //__itkWarpTensorImageMultiTransformFilter_txx ants-1.9.2+svn680.dfsg/Utilities/000077500000000000000000000000001147325206600164335ustar00rootroot00000000000000ants-1.9.2+svn680.dfsg/Utilities/BinaryImageToMeshFilter.h000066400000000000000000000364531147325206600232740ustar00rootroot00000000000000/******************************************************************************** * Create a VTK mesh from the white matter image *******************************************************************************/ #ifndef __BinaryImageToMeshFilter_h_ #define __BinaryImageToMeshFilter_h_ #include "itkImage.h" #include "itkResampleImageFilter.h" #include "itkWindowedSincInterpolateImageFunction.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkAntiAliasBinaryImageFilter.h" #include "itkUnaryFunctorImageFilter.h" //#include "itkBinaryWellComposed3DImageFilter.h" #include "itkMinimumMaximumImageCalculator.h" #include "itkCommand.h" #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; template void ConnectITKToVTK(itk::VTKImageExport *fltExport,vtkImageImport *fltImport) { fltImport->SetUpdateInformationCallback( fltExport->GetUpdateInformationCallback()); fltImport->SetPipelineModifiedCallback( fltExport->GetPipelineModifiedCallback()); fltImport->SetWholeExtentCallback( fltExport->GetWholeExtentCallback()); fltImport->SetSpacingCallback( fltExport->GetSpacingCallback()); fltImport->SetOriginCallback( fltExport->GetOriginCallback()); fltImport->SetScalarTypeCallback( fltExport->GetScalarTypeCallback()); fltImport->SetNumberOfComponentsCallback( fltExport->GetNumberOfComponentsCallback()); fltImport->SetPropagateUpdateExtentCallback( fltExport->GetPropagateUpdateExtentCallback()); fltImport->SetUpdateDataCallback( fltExport->GetUpdateDataCallback()); fltImport->SetDataExtentCallback( fltExport->GetDataExtentCallback()); fltImport->SetBufferPointerCallback( fltExport->GetBufferPointerCallback()); fltImport->SetCallbackUserData( fltExport->GetCallbackUserData()); } class UnaryFunctorBinaryToFloat { public: UnaryFunctorBinaryToFloat() { m_InsideValue = 1.0f; } void SetInvertImage(bool invert) { m_InsideValue = invert ? -1.0f : 1.0f; } inline float operator()(short in) { return in == 0 ? -m_InsideValue : m_InsideValue; } inline bool operator != (const UnaryFunctorBinaryToFloat &otro) const { return this->m_InsideValue != otro.m_InsideValue; } private: float m_InsideValue; }; template class BinaryImageToMeshFilter : public itk::ProcessObject { public: typedef BinaryImageToMeshFilter Self; typedef itk::ProcessObject Superclass; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; typedef itk::Image FloatImageType; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension); /** Get the result mesh */ vtkPolyData *GetMesh() { return fltTriangle->GetOutput(); } /** Get the intermediate antialiased image */ FloatImageType *GetAntiAliasImage() { return fltAlias->GetOutput(); } /** Whether to invert the binary image */ itkSetMacro(InvertInput,bool); itkGetMacro(InvertInput,bool); /** Whether to invert the binary image */ itkSetMacro(ResampleScaleFactor,float); itkGetMacro(ResampleScaleFactor,float); /** Whether to decimate the mesh and how much, 0 for none*/ itkSetMacro(DecimateFactor, double); itkGetMacro(DecimateFactor, double); /** Smoothing iterations, or 0 for none */ itkSetMacro(SmoothingIterations, int); itkGetMacro(SmoothingIterations, int); /** Set the input */ void SetInput(TImage *image) { this->SetNthInput(0,image); } /** Update method (why?) */ void Update() { this->GenerateData(); } /** Set the anti-aliasing quality parameter */ void SetAntiAliasMaxRMSError(double value) { fltAlias->SetMaximumRMSError(value); } /** Get the 'distance image' based on anti-aliasing the binary image */ FloatImageType *GetDistanceImage() { return fltAlias->GetOutput(); } /** Get the floating point 'resampled' image, if resampling was enabled */ FloatImageType *GetResampledImage() { if(m_ResampleScaleFactor != 1.0f) return fltResample->GetOutput(); else return fltToFloat->GetOutput(); } void PrintMeshStatistics(vtkPolyData *mesh) { vector cellHist(100,0); for(vtkIdType i = 0;i < mesh->GetNumberOfCells();i++) { cellHist[mesh->GetCellType(i)]++; } cout << " mesh has " << mesh->GetNumberOfPoints() << " points." << endl; cout << " mesh has " << mesh->GetNumberOfCells() << " cells. " << endl; cout << " mesh has " << cellHist[VTK_VERTEX] << " vtk_vertex" << endl; cout << " mesh has " << cellHist[VTK_LINE] << " vtk_line" << endl; cout << " mesh has " << cellHist[VTK_POLY_LINE] << " vtk_poly_line" << endl; cout << " mesh has " << cellHist[VTK_TRIANGLE] << " vtk_triangle" << endl; cout << " mesh has " << cellHist[VTK_TRIANGLE_STRIP] << " vtk_triangle_strip" << endl; } protected: BinaryImageToMeshFilter() { // Set the cardinality of the filter this->SetNumberOfInputs(1); this->SetNumberOfOutputs(1); // Begin with the well-connectedness filter //fltTopology = TopologyFilter::New(); // Create the converter to float fltToFloat = ToFloatFilter::New(); // fltToFloat->SetInput(this->GetInput());//fltTopology->GetOutput()); typename FloatImageType::Pointer imgPipeEnd = fltToFloat->GetOutput(); // Initialize the interpolation function fnInterpolate = ResampleFunction::New(); // Create a resampling image filter fltResample = ResampleFilter::New(); fltResample->SetInput(imgPipeEnd); fltResample->SetTransform(itk::IdentityTransform::New()); fltResample->SetInterpolator(fnInterpolate); imgPipeEnd = fltResample->GetOutput(); // Create an anti-aliasing image filter fltAlias = AAFilter::New(); fltAlias->SetMaximumRMSError(0.024); fltAlias->SetInput(imgPipeEnd); imgPipeEnd = fltAlias->GetOutput(); // Cast the image to VTK fltExport = ExportFilter::New(); fltImport = vtkImageImport::New(); fltExport->SetInput(imgPipeEnd); ConnectITKToVTK(fltExport.GetPointer(),fltImport); // Compute marching cubes vtkImageData *importPipeEnd = fltImport->GetOutput(); fltMarching = vtkImageMarchingCubes::New(); fltMarching->SetInput(importPipeEnd); fltMarching->ComputeScalarsOff(); fltMarching->ComputeGradientsOff(); fltMarching->SetNumberOfContours(1); fltMarching->SetValue(0,0.0f); vtkPolyData *meshPipeEnd = fltMarching->GetOutput(); // Keep the largest connected component fltConnect = vtkPolyDataConnectivityFilter::New(); fltConnect->SetInput(meshPipeEnd); fltConnect->SetExtractionModeToLargestRegion(); meshPipeEnd = fltMarching->GetOutput(); // Clean up the data // fltClean = vtkCleanPolyData::New(); //fltClean->SetInput(meshPipeEnd); // meshPipeEnd = fltClean->GetOutput(); // Decimate the data fltDecimate = vtkDecimatePro::New(); fltDecimate->SetInput(meshPipeEnd); fltDecimate->PreserveTopologyOn(); meshPipeEnd = fltDecimate->GetOutput(); // Smooth the data, keeping it on the contour fltSmoothMesh = vtkSmoothPolyDataFilter::New(); fltSmoothMesh->SetInput(meshPipeEnd); fltSmoothMesh->SetSource(meshPipeEnd); meshPipeEnd = fltSmoothMesh->GetOutput(); // Compute triangle strips for faster display fltTriangle = vtkTriangleFilter::New(); fltTriangle->SetInput(meshPipeEnd); meshPipeEnd = fltTriangle->GetOutput(); // Set up progress typedef itk::MemberCommand CommandType; typename CommandType::Pointer cmd = CommandType::New(); cmd->SetCallbackFunction(this, &Self::ProgressCommand); // Add progress to the two slow filters fltResample->AddObserver(itk::ProgressEvent(),cmd); fltAlias->AddObserver(itk::ProgressEvent(),cmd); // Invert - NO m_InvertInput = false; // Resample - NO m_ResampleScaleFactor = 1.0f; // Decimate - NO m_DecimateFactor = 0.0f; } ~BinaryImageToMeshFilter() { // CLean up fltMarching->Delete(); fltConnect->Delete(); fltImport->Delete(); fltTriangle->Delete(); //fltClean->Delete(); fltDecimate->Delete(); fltSmoothMesh->Delete(); } /** Generate Data */ virtual void GenerateData( void ) { // Run the computation cout << "Computing mesh from binary image" << endl; // Get the input and output pointers typename TImage::ConstPointer inputImage = reinterpret_cast(this->GetInput(0)); // Pass the input to the topology filter //fltTopology->SetInput(inputImage); // Compute the max/min of the image to set fore/back typedef itk::MinimumMaximumImageCalculator CalcType; typename CalcType::Pointer calc = CalcType::New(); calc->SetImage(inputImage); calc->Compute(); // Set the background and foreground in the topology filter //fltTopology->SetBackgroundValue(calc->GetMinimum()); //fltTopology->SetForegroundValue(calc->GetMaximum()); //fltTopology->Update(); // Pass the input to the remapper fltToFloat->SetInput(inputImage); // Set the inversion if necessary m_ToFloatFunctor.SetInvertImage(m_InvertInput); fltToFloat->SetFunctor(m_ToFloatFunctor); // Convert the image to floats fltToFloat->Update(); // Peform resampling only if necessary if(m_ResampleScaleFactor != 1.0) { // Include the filter in the pipeline fltAlias->SetInput(fltResample->GetOutput()); // Set the size parameter FloatImageType::SizeType szOutput = inputImage->GetBufferedRegion().GetSize(); szOutput[0] = (unsigned long) (szOutput[0] * m_ResampleScaleFactor); szOutput[1] = (unsigned long) (szOutput[1] * m_ResampleScaleFactor); szOutput[2] = (unsigned long) (szOutput[2] * m_ResampleScaleFactor); fltResample->SetSize(szOutput); // Set the scale and origin FloatImageType::SpacingType xSpacing = inputImage->GetSpacing(); xSpacing[0] /= m_ResampleScaleFactor; xSpacing[1] /= m_ResampleScaleFactor; xSpacing[2] /= m_ResampleScaleFactor; fltResample->SetOutputSpacing(xSpacing); fltResample->SetOutputOrigin(inputImage->GetOrigin()); // Compute the resampling cout << " resampling the image " << endl; fltResample->Update(); cout << endl; } else { // Exclude the filter from the pipeline fltAlias->SetInput(fltToFloat->GetOutput()); } // Run the filters if(fltAlias->GetMaximumRMSError() > 0.0) { cout << " anti-aliasing the image " << endl; fltAlias->Update(); fltExport->SetInput(fltAlias->GetOutput()); } else { fltExport->SetInput(fltAlias->GetInput()); } bool verbose=true; if (verbose) cout << endl << " converting image to VTK" << endl; fltImport->Update(); if (verbose) cout << " running marching cubes algorithm" << endl; fltMarching->Update(); if (verbose) cout << " mesh has " << fltMarching->GetOutput()->GetNumberOfCells() << " cells and " << fltMarching->GetOutput()->GetNumberOfPoints() << " points. " << endl; if (verbose) cout << " extracting the largest component" << endl; fltConnect->Update(); if (verbose) cout << " mesh has " << fltConnect->GetOutput()->GetNumberOfCells() << " cells and " << fltConnect->GetOutput()->GetNumberOfPoints() << " points. " << endl; //if (verbose) cout << " cleaning the mesh " << endl; //fltClean->Update(); // if (verbose) cout << " mesh has " // << fltClean->GetOutput()->GetNumberOfCells() << " cells and " // << fltClean->GetOutput()->GetNumberOfPoints() << " points. " << endl; // If decimation is on, run it if(m_DecimateFactor > 0.0 ) { if (verbose) cout << " decimating the mesh by factor of " << m_DecimateFactor << endl; fltDecimate->SetTargetReduction(m_DecimateFactor); fltDecimate->Update(); fltTriangle->SetInput(fltDecimate->GetOutput()); // if (verbose) cout << " mesh has " // << fltClean->GetOutput()->GetNumberOfCells() << " cells and " // << fltClean->GetOutput()->GetNumberOfPoints() << " points. " << endl; } //else // { // fltTriangle->SetInput(fltClean->GetOutput()); // } if (verbose) cout << " converting mesh to triangles" << endl; fltTriangle->Update(); m_Result = fltTriangle->GetOutput(); if (verbose) cout << " mesh has " << fltTriangle->GetOutput()->GetNumberOfCells() << " cells and " << fltTriangle->GetOutput()->GetNumberOfPoints() << " points. " << endl; // If smoothing is on, run it if(m_SmoothingIterations > 0 ) { if (verbose) cout << " smoothing the mesh " << m_SmoothingIterations << endl; fltSmoothMesh->SetNumberOfIterations(m_SmoothingIterations); fltSmoothMesh->SetInput(m_Result); fltSmoothMesh->SetSource(m_Result); fltSmoothMesh->Update(); //m_Result = fltSmoothMesh->GetOutput(); std::cout << " Done " << std::endl; } } private: typedef itk::ImageRegionIterator IteratorType; typedef itk::ImageRegionConstIterator ConstIteratorType; // Topology correction filter // typedef itk::BinaryWellComposed3DImageFilter TopologyFilter; // Functor for remapping to float UnaryFunctorBinaryToFloat m_ToFloatFunctor; // Filter to remap image to floating point typedef itk::UnaryFunctorImageFilter< TImage, FloatImageType, UnaryFunctorBinaryToFloat> ToFloatFilter; // Windowed sinc for resampling typedef itk::Function::WelchWindowFunction<4> WindowFunction; typedef itk::NearestNeighborInterpolateImageFunction< FloatImageType, double> ResampleFunction; // Filter to resample image typedef itk::ResampleImageFilter ResampleFilter; // Antialiasing filter typedef itk::AntiAliasBinaryImageFilter AAFilter; // Export to VTK filter typedef itk::VTKImageExport ExportFilter; // typename TopologyFilter::Pointer fltTopology; typename AAFilter::Pointer fltAlias; typename ExportFilter::Pointer fltExport; typename ToFloatFilter::Pointer fltToFloat; typename ResampleFilter::Pointer fltResample; typename ResampleFunction::Pointer fnInterpolate; vtkImageImport *fltImport; vtkImageMarchingCubes *fltMarching; vtkPolyDataConnectivityFilter *fltConnect; vtkCleanPolyData *fltClean; vtkTriangleFilter *fltTriangle; vtkDecimatePro *fltDecimate; vtkSmoothPolyDataFilter *fltSmoothMesh; bool m_InvertInput; float m_ResampleScaleFactor; double m_DecimateFactor; int m_SmoothingIterations; vtkPolyData *m_Result; void ProgressCommand(itk::Object *source, const itk::EventObject &evt) { // Get the elapsed progress itk::ProcessObject *po = reinterpret_cast(source); float progress = po->GetProgress(); cout << setprecision(4) << (100 * progress) << " " << flush; } }; #endif ants-1.9.2+svn680.dfsg/Utilities/ReadWriteImage.h000066400000000000000000000405151147325206600214420ustar00rootroot00000000000000#ifndef __ReadWriteImage_h_ #define __ReadWriteImage_h_ #include #include #include #include "itkVector.h" #include "itkImage.h" #include "itkImageFileWriter.h" #include "itkImageFileReader.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkWarpImageFilter.h" //#include "itkInverseWarpImageFilter.h" #include "itkAffineTransform.h" #include "itkImageRegionIterator.h" #include "itkResampleImageFilter.h" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNearestNeighborInterpolateImageFunction.h" #include "itkVectorIndexSelectionCastImageFilter.h" #include "itkLogTensorImageFilter.h" #include "itkExpTensorImageFilter.h" #include bool ANTSFileExists(std::string strFilename) { struct stat stFileInfo; bool blnReturn; int intStat; // Attempt to get the file attributes intStat = stat(strFilename.c_str(),&stFileInfo); if(intStat == 0) { // We were able to get the file attributes // so the file obviously exists. blnReturn = true; } else { // We were not able to get the file attributes. // This may mean that we don't have permission to // access the folder which contains this file. If you // need to do that level of checking, lookup the // return values of stat which will give you // more details on why stat failed. blnReturn = false; } return(blnReturn); } // Nifti stores DTI values in lower tri format but itk uses upper tri // currently, nifti io does nothing to deal with this. if this changes // the function below should be modified/eliminated. template void NiftiDTICheck(itk::SmartPointer &target, const char *file, bool makeLower) { typedef typename TImageType::PixelType PixType; return; //typedef itk::ImageFileWriter Writer; //typename Writer::Pointer writer = Writer::New(); //writer->SetInput( target ); //writer->SetFileName( "testdt.nii" ); //writer->Update(); // Check for nifti file std::string filename = file; std::string::size_type pos1 = filename.find( ".nii" ); std::string::size_type pos2 = filename.find( ".nia" ); if ((pos1 == std::string::npos) && (pos2 == std::string::npos)) return; if (PixType::Length != 6) return; std::cout << "Performing lower/upper triangular format check for Nifti DTI" << std::endl; // swap elements 2 and 3 for lower<->upper conversion itk::ImageRegionIteratorWithIndex iter(target,target->GetLargestPossibleRegion()); unsigned int looksLikeLower = 0; unsigned int looksLikeUpper = 0; unsigned int nBadVoxels = 0; unsigned int count = 0; unsigned int el2Neg = 0; unsigned int el3Neg = 0; while (!iter.IsAtEnd()) { bool isValid = true; for (unsigned int i=0; i<6; i++) { if ( iter.Get()[i] != iter.Get()[i] ) { ++nBadVoxels; isValid = false; } } double el2 = iter.Get()[2]; double el3 = iter.Get()[3]; if (el2 < 0) ++el2Neg; if (el3 < 0) ++el3Neg; if (isValid) { if (el2 > el3) { ++looksLikeLower; } else { ++looksLikeUpper; } } ++count; ++iter; } //std::cout << "Invalid: " << nBadVoxels << "/" << count << std::endl; //std::cout << "Lower: " << looksLikeLower << ", Upper: " << looksLikeUpper << std::endl; //std::cout << "el2Neg: " << el2Neg << ", el3Neg: " << el3Neg << std::endl; if ( ((looksLikeUpper > looksLikeLower) && makeLower) || ( (looksLikeLower > looksLikeUpper) && !makeLower) ) { std::cout << "Performing lower/upper triangular format swap for Nifti DTI" << std::endl; iter.GoToBegin(); while (!iter.IsAtEnd()) { PixType pix = iter.Get(); typename PixType::ValueType temp; temp = pix[2]; pix[2] = pix[3]; pix[3] = temp; iter.Set(pix); ++iter; } } } template void ReadTensorImage(itk::SmartPointer &target, const char *file, bool takelog=true) { if ( ! ANTSFileExists(std::string(file)) ) { std::cout << " file " << std::string(file) << " does not exist . " << std::endl; return ; } // Read the image files begin typedef TImageType ImageType; typedef itk::ImageFileReader< ImageType > FileSourceType; typedef typename ImageType::PixelType PixType; typedef itk::LogTensorImageFilter LogFilterType; typename FileSourceType::Pointer reffilter = FileSourceType::New(); reffilter->SetFileName( file ); try { reffilter->Update(); } catch( itk::ExceptionObject & e ) { std::cout << "Exception caught during reference file reading " << std::endl; std::cout << e << " file " << file << std::endl; target=NULL; return; } target=reffilter->GetOutput(); NiftiDTICheck(target, file, false); if (takelog) { typename LogFilterType::Pointer logFilter = LogFilterType::New(); logFilter->SetInput( reffilter->GetOutput() ); logFilter->Update(); target = logFilter->GetOutput(); std::cout << "Returning Log(D) for log-euclidean math ops" << std::endl; } } template //void ReadImage(typename TImageType::Pointer target, const char *file) void ReadImage(itk::SmartPointer &target, const char *file) { if ( std::string(file).length() < 3 ) { std::cout << " bad file name " << std::string(file) << std::endl ; target=NULL; return; } if ( ! ANTSFileExists(std::string(file)) ) { std::cout << " file " << std::string(file) << " does not exist . " << std::endl; target=NULL; return ; } /*// std::cout << " reading b " << std::string(file) << std::endl; typedef itk::ImageFileReader readertype; typename readertype::Pointer reader = readertype::New(); reader->SetFileName(file); reader->Update(); target=(reader->GetOutput()); */ // std::cout << " Entering Read " << file << std::endl; // Read the image files begin typedef TImageType ImageType; typedef itk::ImageFileReader< ImageType > FileSourceType; typedef typename ImageType::PixelType PixType; // const unsigned int ImageDimension=ImageType::ImageDimension; typename FileSourceType::Pointer reffilter = FileSourceType::New(); reffilter->SetFileName( file ); try { reffilter->Update(); } catch( itk::ExceptionObject & e ) { std::cout << "Exception caught during reference file reading " << std::endl; std::cout << e << " file " << file << std::endl; target=NULL; exit(1); return; } //typename ImageType::DirectionType dir; //dir.SetIdentity(); // reffilter->GetOutput()->SetDirection(dir); //std::cout << " setting pointer " << std::endl; target=reffilter->GetOutput(); // reffilter->GetOutput()->Print( std::cout ); // std::cout << " read direction " << << std::endl; //if (reffilter->GetImageIO()->GetNumberOfComponents() == 6) //NiftiDTICheck(target,file); } template typename ImageType::Pointer ReadImage(char* fn ) { // Read the image files begin typedef itk::ImageFileReader< ImageType > FileSourceType; typedef typename ImageType::PixelType PixType; // const unsigned int ImageDimension=ImageType::ImageDimension; typename FileSourceType::Pointer reffilter = FileSourceType::New(); reffilter->SetFileName( fn ); try { reffilter->Update(); } catch( itk::ExceptionObject & e ) { std::cerr << "Exception caught during reference file reading " << std::endl; std::cerr << e << std::endl; return NULL; } typename ImageType::DirectionType dir; dir.SetIdentity(); // reffilter->GetOutput()->SetDirection(dir); typename ImageType::Pointer target = reffilter->GetOutput(); //if (reffilter->GetImageIO->GetNumberOfComponents() == 6) //NiftiDTICheck(target,fn); return target; } template typename ImageType::Pointer ReadTensorImage(char* fn, bool takelog=true ) { // Read the image files begin typedef itk::ImageFileReader< ImageType > FileSourceType; typedef typename ImageType::PixelType PixType; typedef itk::LogTensorImageFilter LogFilterType; // const unsigned int ImageDimension=ImageType::ImageDimension; typename FileSourceType::Pointer reffilter = FileSourceType::New(); reffilter->SetFileName( fn ); try { reffilter->Update(); } catch( itk::ExceptionObject & e ) { std::cerr << "Exception caught during reference file reading " << std::endl; std::cerr << e << std::endl; return NULL; } typename ImageType::Pointer target = reffilter->GetOutput(); NiftiDTICheck(target, fn, false); if (takelog) { typename LogFilterType::Pointer logFilter = LogFilterType::New(); logFilter->SetInput( target->GetOutput() ); logFilter->Update(); target = logFilter->GetOutput(); } return target; } template void WriteImage(itk::SmartPointer image, const char *file) { if ( std::string(file).length() < 3 ) return; typename itk::ImageFileWriter::Pointer writer = itk::ImageFileWriter::New(); writer->SetFileName(file); if (!image) { std::cout <<" file " << file << " does not exist " << std::endl; exit(1); } // typename TImageType::DirectionType dir; //dir.SetIdentity(); //image->SetDirection(dir); // std::cout << " now Write direction " << image->GetOrigin() << std::endl; //if (writer->GetImageIO->GetNumberOfComponents() == 6) //NiftiDTICheck(image,file); writer->SetInput(image); writer->Update(); } template void WriteTensorImage(itk::SmartPointer image, const char *file, bool takeexp=true) { typedef typename TImageType::PixelType PixType; typedef itk::ExpTensorImageFilter ExpFilterType; typename itk::ImageFileWriter::Pointer writer = itk::ImageFileWriter::New(); writer->SetFileName(file); typename TImageType::Pointer writeImage = image; if (takeexp) { typename ExpFilterType::Pointer expFilter = ExpFilterType::New(); expFilter->SetInput( image ); expFilter->Update(); writeImage = expFilter->GetOutput(); std::cout << "Taking Exp(D) before writing" << std::endl; } // convert from upper tri to lower tri NiftiDTICheck(writeImage, file, true);// BA May 30 2009 -- remove b/c ITK fixed NIFTI reader writer->SetInput(writeImage); writer->Update(); } template typename TField::Pointer ReadWarpFromFile( std::string warpfn, std::string ext) { typedef TField FieldType; typedef typename FieldType::PixelType VectorType; enum { ImageDimension = FieldType::ImageDimension }; typedef itk::Image RealImageType; typedef RealImageType ImageType; // typedef itk::Vector VectorType; // typedef itk::Image FieldType; // std::cout << " warp file name " << warpfn + ext << std::endl; std::string fn=""; // First - read the vector fields // NOTE : THE FIELD SHOULD WARP INPUT1 TO INPUT2, THUS SHOULD POINT // FROM INPUT2 TO INPUT1 fn=warpfn+"x"+ext; typename RealImageType::Pointer xvec=ReadImage((char*)fn.c_str()); // std::cout << " done reading " << fn << std::endl; fn=warpfn+"y"+ext; typename RealImageType::Pointer yvec=ReadImage((char*)fn.c_str()); //std::cout << " done reading " << fn << std::endl; fn=warpfn+"z"+ext; typename RealImageType::Pointer zvec=NULL; //std::cout << " done reading " << fn << std::endl; if (ImageDimension == 3) zvec=ReadImage((char*)fn.c_str()); typename FieldType::Pointer field=FieldType::New(); field->SetLargestPossibleRegion( xvec->GetLargestPossibleRegion() ); field->SetBufferedRegion( xvec->GetLargestPossibleRegion() ); field->SetLargestPossibleRegion( xvec->GetLargestPossibleRegion() ); field->SetOrigin(xvec->GetOrigin()); field->SetDirection(xvec->GetDirection()); field->Allocate(); itk::ImageRegionIteratorWithIndex it( xvec, xvec->GetLargestPossibleRegion() ); // std::cout << " spacing xv " << xvec->GetSpacing()[0] //<< " field " << field->GetSpacing()[0] << std::endl; field->SetSpacing(xvec->GetSpacing()); field->SetOrigin(xvec->GetOrigin()); unsigned int ct = 0; for (it.GoToBegin(); !it.IsAtEnd(); ++it) { ct++; typename ImageType::IndexType index=it.GetIndex(); VectorType disp; disp[0]=xvec->GetPixel(index); disp[1]=yvec->GetPixel(index); if (ImageDimension == 3)disp[2]=zvec->GetPixel(index); field->SetPixel(index,disp); // if (ct == 10000) std::cout << " 10000th pix " << disp << std::endl; } return field; } template typename TImage::Pointer MakeNewImage(typename TImage::Pointer image1, typename TImage::PixelType initval ) { typedef itk::ImageRegionIteratorWithIndex Iterator; typename TImage::Pointer varimage=TImage::New(); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->SetBufferedRegion( image1->GetLargestPossibleRegion() ); varimage->SetLargestPossibleRegion( image1->GetLargestPossibleRegion() ); varimage->Allocate(); varimage->SetSpacing(image1->GetSpacing()); varimage->SetOrigin(image1->GetOrigin()); varimage->SetDirection(image1->GetDirection()); Iterator vfIter2( varimage, varimage->GetLargestPossibleRegion() ); for( vfIter2.GoToBegin(); !vfIter2.IsAtEnd(); ++vfIter2 ) { if (initval >= 0) vfIter2.Set(initval); else vfIter2.Set(image1->GetPixel(vfIter2.GetIndex())); } return varimage; } template void WriteDisplacementField(TField* field,std::string filename) { typedef TField FieldType; typedef typename FieldType::PixelType VectorType; enum { ImageDimension = FieldType::ImageDimension }; typedef itk::Image RealImageType; // Initialize the caster to the displacement field typedef itk::VectorIndexSelectionCastImageFilter IndexSelectCasterType; for (unsigned int dim=0; dimSetInput( field ); fieldCaster->SetIndex( dim ); fieldCaster->Update(); // Set up the output filename std::string outfile=filename+static_cast('x'+dim)+std::string("vec.nii.gz"); std::cout << "Writing displacements to " << outfile << " spacing " << field->GetSpacing()[0] << std::endl; typename RealImageType::Pointer fieldcomponent=fieldCaster->GetOutput(); fieldcomponent->SetSpacing(field->GetSpacing()); fieldcomponent->SetOrigin(field->GetOrigin()); fieldcomponent->SetDirection(field->GetDirection()); WriteImage(fieldcomponent, outfile.c_str()); } std::cout << "...done" << std::endl; return; } template void WriteDisplacementField2(TField* field, std::string filename, std::string app) { typedef TField FieldType; typedef typename FieldType::PixelType VectorType; enum { ImageDimension = FieldType::ImageDimension }; typedef itk::Image RealImageType; // Initialize the caster to the displacement field typedef itk::VectorIndexSelectionCastImageFilter IndexSelectCasterType; for (unsigned int dim=0; dimSetInput( field ); fieldCaster->SetIndex( dim ); fieldCaster->Update(); // Set up the output filename std::string outfile=filename+static_cast('x'+dim)+std::string(app); std::cout << "Writing displacements to " << outfile << " spacing " << field->GetSpacing()[0] << std::endl; typename RealImageType::Pointer fieldcomponent=fieldCaster->GetOutput(); fieldcomponent->SetSpacing(field->GetSpacing()); fieldcomponent->SetOrigin(field->GetOrigin()); WriteImage(fieldcomponent, outfile.c_str()); } std::cout << "...done" << std::endl; return; } #endif ants-1.9.2+svn680.dfsg/Utilities/antsCommandLineOption.cxx000066400000000000000000000047361147325206600234360ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsCommandLineOption.cxx,v $ Language: C++ Date: $Date: 2009/01/22 22:48:30 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "antsCommandLineOption.h" namespace itk { namespace ants { CommandLineOption ::CommandLineOption() : m_ShortName( '\0' ), m_LongName( "" ), m_Description( "" ) { this->m_Values.clear(); this->m_UsageOptions.clear(); } void CommandLineOption ::AddValue( std::string value, char leftDelimiter, char rightDelimiter ) { std::string::size_type leftDelimiterPos = value.find( leftDelimiter ); std::string::size_type rightDelimiterPos = value.find( rightDelimiter ); if( leftDelimiterPos == std::string::npos || rightDelimiterPos == std::string::npos ) { this->m_Values.push_front( value ); ValueStackType parameters; this->m_Parameters.push_front( parameters ); } else { ValueStackType parameters; this->m_Values.push_front( value.substr( 0, leftDelimiterPos ) ); std::string::size_type leftPos = leftDelimiterPos; std::string::size_type rightPos = value.find( ',', leftPos+1 ); while( rightPos != std::string::npos ) { parameters.push_back( value.substr( leftPos+1, rightPos - leftPos - 1 ) ); leftPos = rightPos; rightPos = value.find( ',', leftPos+1 ); } rightPos = rightDelimiterPos; parameters.push_back( value.substr( leftPos+1, rightPos - leftPos - 1 ) ); this->m_Parameters.push_front( parameters ); } this->Modified(); } void CommandLineOption ::SetValue( unsigned int i, std::string value ) { this->m_Values[i] = value; this->Modified(); } void CommandLineOption ::SetUsageOption( unsigned int i, std::string usage ) { if( i >= this->m_UsageOptions.size() ) { this->m_UsageOptions.resize( i + 1 ); } this->m_UsageOptions[i] = usage; this->Modified(); } } // end namespace ants } // end namespace itk ants-1.9.2+svn680.dfsg/Utilities/antsCommandLineOption.h000066400000000000000000000117651147325206600230630ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: antsCommandLineOption.h,v $ Language: C++ Date: $Date: 2009/01/22 22:48:30 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsCommandLineOption_h #define __antsCommandLineOption_h #include "itkDataObject.h" #include "itkObjectFactory.h" #include "itkMacro.h" #include "itkNumericTraits.h" #include #include #include namespace itk { namespace ants { /** \class CommandLineOption \brief Simple data structure for holding command line options. An option can have multiple values with each value holding 0 or more parameters. E.g. suppose we were creating an image registration program which has several transformation model options such as 'rigid', 'affine', and 'deformable'. A instance of the command line option could have a long name of "transformation", short name 't', and description "Transformation model---rigid, affine, or deformable". The values for this option would be "rigid", "affine", and "deformable". Each value would then hold parameters that relate to that value. For example, a possible subsection of the command line would be " --transformation rigid[parameter1,parameter2,etc.] -m mutualinformation[parameter1] --optimization gradientdescent" */ class ITK_EXPORT CommandLineOption : public DataObject { public: typedef CommandLineOption Self; typedef DataObject Superclass; typedef SmartPointer Pointer; itkNewMacro( Self ); itkTypeMacro( Option, DataObject ); typedef std::string ValueType; typedef std::deque ValueStackType; typedef std::deque ParameterStackType; ValueStackType GetValues() { return this->m_Values; } unsigned int GetNumberOfValues() { return this->m_Values.size(); } std::string GetValue( unsigned int i = 0 ) { if( i < this->m_Values.size() ) { return this->m_Values[i]; } else { return std::string( "" ); } } ValueStackType GetUsageOptions() { return this->m_UsageOptions; } unsigned int GetNumberOfUsageOptions() { return this->m_UsageOptions.size(); } std::string GetUsageOption( unsigned int i = 0 ) { if( i < this->m_UsageOptions.size() ) { return this->m_UsageOptions[i]; } else { return std::string( "" ); } } ValueStackType GetParameters( unsigned int i = 0 ) { if( i < this->m_Parameters.size() ) { return this->m_Parameters[i]; } else { ValueStackType empty; return empty; } } std::string GetParameter( unsigned int i, unsigned int j ) { if( i < this->m_Parameters.size() && j < this->m_Parameters[i].size() ) { return this->m_Parameters[i][j]; } else { return std::string( "" ); } } std::string GetParameter( unsigned int j ) { return this->GetParameter( 0, j ); } unsigned int GetNumberOfParameters( unsigned int i = 0 ) { if( i < this->m_Parameters.size() ) { return this->m_Parameters[i].size(); } else { return 0; } } itkSetMacro( ShortName, char ); itkGetMacro( ShortName, char ); itkSetMacro( LongName, std::string ); itkGetMacro( LongName, std::string ); itkSetMacro( Description, std::string ); itkGetMacro( Description, std::string ); void AddValue( std::string, char, char ); void AddValue( std::string s ) { this->AddValue( s, '[', ']' ); } void SetValue( unsigned int, std::string ); void SetUsageOption( unsigned int, std::string ); protected: CommandLineOption(); virtual ~CommandLineOption() {}; private: char m_ShortName; std::string m_LongName; std::string m_Description; ValueStackType m_UsageOptions; ValueStackType m_Values; ParameterStackType m_Parameters; }; } // end namespace ants } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/antsCommandLineParser.cxx000066400000000000000000000351121147325206600234120ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: antsCommandLineParser.cxx,v $ Language: C++ Date: $Date: 2009/01/22 22:43:11 $ Version: $Revision: 1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "antsCommandLineParser.h" #include namespace itk { namespace ants { CommandLineParser ::CommandLineParser() { this->m_Options.clear(); this->m_Command.clear(); this->m_CommandDescription.clear(); this->m_UnknownOptions.clear(); this->m_LeftDelimiter = '['; this->m_RightDelimiter = ']'; } void CommandLineParser ::AddOption( OptionType::Pointer option ) { if( ( option->GetShortName() != '\0' || !this->GetOption( option->GetShortName() ) ) || ( !option->GetLongName().empty() || !this->GetOption( option->GetLongName() ) ) ) { this->m_Options.push_back( option ); } else { if( option->GetShortName() != '\0' && this->GetOption( option->GetShortName() ) ) { itkWarningMacro( "Duplicate short option '-" << option->GetShortName() << "'" ); } if( !( option->GetLongName().empty() ) && this->GetOption( option->GetLongName() ) ) { itkWarningMacro( "Duplicate long option '--" << option->GetLongName() << "'" ); } } } void CommandLineParser ::Parse( unsigned int argc, char **argv ) { std::vector arguments = this->RegroupCommandLineArguments( argc, argv ); unsigned int n = 0; this->m_Command = arguments[n++]; while( n < arguments.size() ) { std::string argument = arguments[n++]; std::string name; name.clear(); if( argument.find( "--" ) == 0 ) { name = argument.substr( 2, argument.length()-1 ); } else if( argument.find( "-" ) == 0 && argument.find( "--" ) > 0 ) { name = argument.substr( 1, 2 ); } if( !( name.empty() ) ) { OptionType::Pointer option = this->GetOption( name ); if( !option ) { OptionType::Pointer unknownOption = OptionType::New(); if( name.length() > 1 ) { unknownOption->SetLongName( name ); } else { unknownOption->SetShortName( name.at( 0 ) ); } if( n == arguments.size() ) { unknownOption->AddValue( "1", this->m_LeftDelimiter, this->m_RightDelimiter ); } else { for( unsigned int m = n; m < arguments.size(); m++ ) { std::string value = arguments[m]; if( value.find( "-" ) != 0 ) { unknownOption->AddValue( value, this->m_LeftDelimiter, this->m_RightDelimiter ); } else { if( m == n ) { unknownOption->AddValue( "1", this->m_LeftDelimiter, this->m_RightDelimiter ); } n = m; break; } } } this->m_UnknownOptions.push_back( unknownOption ); } else // the option exists { if( n == arguments.size() ) { option->AddValue( "1", this->m_LeftDelimiter, this->m_RightDelimiter ); } else { for( unsigned int m = n; m < arguments.size(); m++ ) { std::string value = arguments[m]; if( value.find( "-" ) != 0 ) { option->AddValue( value, this->m_LeftDelimiter, this->m_RightDelimiter ); } else { if( m == n ) { option->AddValue( "1", this->m_LeftDelimiter, this->m_RightDelimiter ); } n = m; break; } } } } } } } std::vector CommandLineParser ::RegroupCommandLineArguments( unsigned int argc, char **argv ) { /** * Inclusion of this function allows the user to use spaces inside * the left and right delimiters. Also replace other left and right * delimiters. */ std::vector arguments; std::string currentArg( "" ); bool isArgOpen = false; for( unsigned int n = 0; n < argc; n++ ) { std::string a( argv[n] ); // replace left delimiters std::replace( a.begin(), a.end(), '{', '[' ); std::replace( a.begin(), a.end(), '(', '[' ); std::replace( a.begin(), a.end(), '<', '[' ); // replace right delimiters std::replace( a.begin(), a.end(), '}', ']' ); std::replace( a.begin(), a.end(), ')', ']' ); std::replace( a.begin(), a.end(), '>', ']' ); if( isArgOpen ) { std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter ); if( leftDelimiterPosition != std::string::npos ) { itkExceptionMacro( "Incorrect command line specification." ); } std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter ); if( rightDelimiterPosition != std::string::npos ) { if( rightDelimiterPosition < a.length()-1 ) { itkExceptionMacro( "Incorrect command line specification." ); } else { currentArg += a; arguments.push_back( currentArg ); currentArg.clear(); isArgOpen = false; } } else { currentArg += a; } } else { std::size_t leftDelimiterPosition = a.find( this->m_LeftDelimiter ); std::size_t rightDelimiterPosition = a.find( this->m_RightDelimiter ); if( leftDelimiterPosition == std::string::npos ) { if( rightDelimiterPosition == std::string::npos ) { currentArg += a; arguments.push_back( currentArg ); currentArg.clear(); } else { itkExceptionMacro( "Incorrect command line specification." ); } } else if( leftDelimiterPosition != std::string::npos && rightDelimiterPosition != std::string::npos && leftDelimiterPosition < rightDelimiterPosition ) { if( rightDelimiterPosition < a.length()-1 ) { itkExceptionMacro( "Incorrect command line specification." ); } currentArg += a; arguments.push_back( currentArg ); currentArg.clear(); isArgOpen = false; } else if( rightDelimiterPosition == std::string::npos && leftDelimiterPosition != std::string::npos ) { currentArg += a; isArgOpen = true; } } } return arguments; } CommandLineParser::OptionType::Pointer CommandLineParser ::GetOption( std::string name ) { if( name.length() == 1 ) { return this->GetOption( name.at( 0 ) ); } OptionListType::iterator it; for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ ) { if( name.compare( (*it)->GetLongName() ) == 0 ) { return *it; } } return NULL; } CommandLineParser::OptionType::Pointer CommandLineParser ::GetOption( char name ) { OptionListType::iterator it; for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ ) { if( name == (*it)->GetShortName() ) { return *it; } } return NULL; } void CommandLineParser ::PrintMenu( std::ostream& os, Indent indent, bool printShortVersion ) const { os << std::endl; os << "COMMAND: " << std::endl; os << indent << this->m_Command << std::endl; if( !this->m_CommandDescription.empty() && !printShortVersion ) { std::stringstream ss1; ss1 << indent << indent; std::stringstream ss2; ss2 << this->m_CommandDescription; std::string description = this->BreakUpStringIntoNewLines( ss2.str(), ss1.str(), 80 ); os << indent << indent << description << std::endl; } os << std::endl; os << "OPTIONS: " << std::endl; OptionListType::const_iterator it; for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ ) { os << indent; std::stringstream ss; ss << indent; if( (*it)->GetShortName() != '\0' ) { os << "-" << (*it)->GetShortName(); ss << Indent( 2 ); if( !( (*it)->GetLongName() ).empty() ) { os << ", " << "--" << (*it)->GetLongName() << " " << std::flush; ss << Indent( 5 + ( (*it)->GetLongName() ).length() ); } else { os << " " << std::flush; ss << Indent( 1 ); } } else { os << "--" << (*it)->GetLongName() << " " << std::flush; ss << Indent( 3 + ( (*it)->GetLongName() ).length() ); } if( (*it)->GetNumberOfUsageOptions() > 0 ) { os << (*it)->GetUsageOption( 0 ) << std::endl; for( unsigned int i = 1; i < (*it)->GetNumberOfUsageOptions(); i++ ) { os << ss.str() << (*it)->GetUsageOption( i ) << std::endl; } } else { os << std::endl; } if( !( (*it)->GetDescription().empty() ) && !printShortVersion ) { std::stringstream ss1; ss1 << indent << indent; std::stringstream ss2; ss2 << (*it)->GetDescription(); std::string description = this->BreakUpStringIntoNewLines( ss2.str(), ss1.str(), 80 ); os << indent << indent << description << std::endl; } if( !printShortVersion ) { if( (*it)->GetValues().size() == 1 ) { os << indent << indent << ": " << (*it)->GetValue( 0 ); if( (*it)->GetParameters( 0 ).size() > 0 ) { os << "["; if( (*it)->GetParameters( 0 ).size() == 1 ) { os << (*it)->GetParameter( 0, 0 ); } else { for( unsigned int i = 0; i < (*it)->GetParameters( 0 ).size()-1; i++ ) { os << (*it)->GetParameter( 0, i ) << ","; } os << (*it)->GetParameter( 0, (*it)->GetParameters( 0 ).size()-1 ); } os << "]"; } os << std::endl; } else if( (*it)->GetValues().size() > 1 ) { os << indent << indent << ": "; for( unsigned int n = 0; n < (*it)->GetValues().size()-1; n++ ) { os << (*it)->GetValue( n ); if( (*it)->GetParameters( n ).size() > 0 ) { os << "["; if( (*it)->GetParameters( n ).size() == 1 ) { os << (*it)->GetParameter( n, 0 ) << "], "; } else { for( unsigned int i = 0; i < (*it)->GetParameters( n ).size()-1; i++ ) { os << (*it)->GetParameter( n, i ) << ","; } os << (*it)->GetParameter( n, (*it)->GetParameters( n ).size()-1 ) << "], "; } } else { os << ", "; } } unsigned int n = (*it)->GetValues().size()-1; os << (*it)->GetValue( n ); if( (*it)->GetParameters( n ).size() > 0 ) { os << "["; if( (*it)->GetParameters( n ).size() == 1 ) { os << (*it)->GetParameter( n, 0 ) << "]"; } else { for( unsigned int i = 0; i < (*it)->GetParameters( n ).size()-1; i++ ) { os << (*it)->GetParameter( n, i ) << ","; } os << (*it)->GetParameter( n, (*it)->GetParameters( n ).size()-1 ) << "]"; } } } os << std::endl; } } } std::string CommandLineParser ::BreakUpStringIntoNewLines( std::string longString, std::string indentString, unsigned int numberOfCharactersPerLine ) const { std::vector tokens; this->TokenizeString( longString, tokens, " " ); std::string newString( "" ); unsigned int currentTokenId = 0; unsigned int currentLineLength = 0; while( currentTokenId < tokens.size() ) { if( tokens[currentTokenId].length() >= numberOfCharactersPerLine ) { newString += ( std::string( "\n" ) + tokens[currentTokenId] + std::string( "\n" ) ); currentTokenId++; currentLineLength = 0; } else if( currentTokenId < tokens.size() && currentLineLength + tokens[currentTokenId].length() > numberOfCharactersPerLine ) { newString += ( std::string( "\n" ) + indentString ); currentLineLength = 0; } else { newString += ( tokens[currentTokenId] + std::string( " " ) ); currentLineLength += ( tokens[currentTokenId].length() + 1 ); currentTokenId++; } } return newString; } void CommandLineParser ::TokenizeString( std::string str, std::vector &tokens, std::string delimiters ) const { // Skip delimiters at beginning. std::string::size_type lastPos = str.find_first_not_of( delimiters, 0 ); // Find first "non-delimiter". std::string::size_type pos = str.find_first_of( delimiters, lastPos ); while( std::string::npos != pos || std::string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back( str.substr( lastPos, pos - lastPos ) ); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of( delimiters, pos ); // Find next "non-delimiter" pos = str.find_first_of( delimiters, lastPos ); } } /** * Standard "PrintSelf" method */ void CommandLineParser ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Command: " << this->m_Command << std::endl; os << indent << "Options: " << std::endl; OptionListType::const_iterator it; for( it = this->m_Options.begin(); it != this->m_Options.end(); it++ ) { (*it)->Print( os, indent ); } if( this->m_UnknownOptions.size() ) { os << indent << "Unknown Options: " << std::endl; OptionListType::const_iterator its; for( its = this->m_UnknownOptions.begin(); its != this->m_UnknownOptions.end(); its++ ) { (*its)->Print( os, indent ); } } } } // end namespace ants } // end namespace itk ants-1.9.2+svn680.dfsg/Utilities/antsCommandLineParser.h000066400000000000000000000117251147325206600230430ustar00rootroot00000000000000/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: antsCommandLineParser.h,v $ Language: C++ Date: $Date: 2009/01/22 22:43:11 $ Version: $Revision: 1.1 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __antsCommandLineParser_h #define __antsCommandLineParser_h #include "antsCommandLineOption.h" #include "itkDataObject.h" #include "itkObjectFactory.h" #include "itkMacro.h" #include "itkNumericTraits.h" #include #include #include #include namespace itk { namespace ants { /** \class CommandLineParser \brief Simple command line parser. \par Parses the standard ( argc, argv ) variables which are stored as options in the helper class antsCommandLineOption. Also contains routines for converting types including std::vectors using 'x' as a delimiter. For example, I can specify the 3-element std::vector {10, 20, 30} as "10x20x30". */ class ITK_EXPORT CommandLineParser : public DataObject { public: /** Standard class typedefs. */ typedef CommandLineParser Self; typedef DataObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods). */ itkTypeMacro( CommandLineParser, DataObject ); typedef CommandLineOption OptionType; typedef std::list OptionListType; typedef std::list StringListType; /** * Interface routines */ OptionType::Pointer GetOption( char ); OptionType::Pointer GetOption( std::string ); void Parse( unsigned int, char ** ); void AddOption( OptionType::Pointer ); void PrintMenu( std::ostream& os, Indent indent, bool printShortVersion = false ) const; itkSetStringMacro( Command ); itkGetStringMacro( Command ); itkSetStringMacro( CommandDescription ); itkGetStringMacro( CommandDescription ); OptionListType GetOptions() const { return this->m_Options; } OptionListType GetUnknownOptions() const { return this->m_UnknownOptions; } template TValue Convert( std::string optionString ) { TValue value; std::istringstream iss( optionString ); iss >> value; return value; } template std::vector ConvertVector( std::string optionString ) { std::vector values; std::string::size_type crosspos = optionString.find( 'x', 0 ); if( crosspos == std::string::npos ) { values.push_back( this->Convert( optionString ) ); } else { std::string element = optionString.substr( 0, crosspos ); TValue value; std::istringstream iss( element ); iss >> value; values.push_back( value ); while( crosspos != std::string::npos ) { std::string::size_type crossposfrom = crosspos; crosspos = optionString.find( 'x', crossposfrom + 1 ); if( crosspos == std::string::npos ) { element = optionString.substr( crossposfrom + 1, optionString.length() ); } else { element = optionString.substr( crossposfrom + 1, crosspos ); } std::istringstream iss( element ); iss >> value; values.push_back( value ); } } return values; } protected: CommandLineParser(); virtual ~CommandLineParser() {} void PrintSelf( std::ostream& os, Indent indent ) const; private: CommandLineParser( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented std::vector RegroupCommandLineArguments( unsigned int, char ** ); std::string BreakUpStringIntoNewLines( std::string, const std::string, unsigned int ) const; void TokenizeString( std::string, std::vector &, std::string ) const; OptionListType m_Options; std::string m_Command; std::string m_CommandDescription; OptionListType m_UnknownOptions; char m_LeftDelimiter; char m_RightDelimiter; }; } // end namespace ants } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkBSplineControlPointImageFilter.h000066400000000000000000000353131147325206600253410ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBSplineControlPointImageFilter.h,v $ Language: C++ Date: $Date: 2009/05/04 14:10:34 $ Version: $Revision: 1.5 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBSplineControlPointImageFilter_h #define __itkBSplineControlPointImageFilter_h #include "itkImageToImageFilter.h" #include "itkBSplineKernelFunction.h" #include "itkCoxDeBoorBSplineKernelFunction.h" #include "itkFixedArray.h" #include "itkPointSet.h" #include "itkSingleValuedCostFunction.h" #include "itkVariableSizeMatrix.h" #include "itkVector.h" #include "itkVectorContainer.h" #include "vnl/vnl_matrix.h" namespace itk { /** * \class BSplineControlPointImageFilter * * \brief Auxilary class for the output of the class * itkBSplineScatteredDataPointSetToImageFilter. * * \par The output of the class itkBSplineScatteredDataPointSetToImageFilter * is a control point grid defining a B-spline object. This class is used to * hold various routines meant to operate on that control point grid. In * addition to specifying the control point grid as the input, the user * must also supply the spline order and the parametric domain (i.e. size, * domain, origin, direction, spacing). The output of the filter is the sampled * B-spline object. * * Other operations include * 1. Evaluation of the B-spline object at any point in the domain. * 2. Evaluation of the gradient. * 3. Evaluation of the Jacobian. * 4. Evaluation of the Hessian. * 5. Refinement of the input control point lattice such that the * corresponding B-spline mesh resolution is twice as great as * the original while maintaining the same valued B-spline object. * 6. Inverse estimation. Given a user-specified data point, one can * find the parameters which minimize the "distance" between the evaluated * data point and the B-spline object evaluated at those parameters. * This is useful, for example, in determining the parametric values of * a point on the curve closest to a user-specified point. */ /** * Class definition for ParameterCostFunction */ template class ITK_EXPORT ParameterCostFunction : public SingleValuedCostFunction { public: typedef ParameterCostFunction Self; typedef SingleValuedCostFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Extract dimension from input image. */ itkStaticConstMacro( ParametricDimension, unsigned int, TControlPointLattice::ImageDimension ); /** Run-time type information (and related methods). */ itkTypeMacro( ParameterCostFunction, SingleValuedCostFunction ); /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef Superclass::MeasureType MeasureType; typedef Superclass::DerivativeType DerivativeType; typedef Superclass::ParametersType ParametersType; typedef FixedArray ArrayType; itkSetObjectMacro( ControlPointLattice, TControlPointLattice ); itkSetMacro( Origin, typename TControlPointLattice::PointType ); itkSetMacro( Spacing, typename TControlPointLattice::SpacingType ); itkSetMacro( Size, typename TControlPointLattice::SizeType ); itkSetMacro( Direction, typename TControlPointLattice::DirectionType ); itkSetMacro( SplineOrder, ArrayType ); itkSetMacro( CloseDimension, ArrayType ); itkSetMacro( DataPoint, typename TControlPointLattice::PixelType ); virtual MeasureType GetValue( const ParametersType & parameters ) const; virtual void GetDerivative( const ParametersType & parameters, DerivativeType & derivative ) const; virtual unsigned int GetNumberOfParameters() const; protected: ParameterCostFunction(); virtual ~ParameterCostFunction(); private: ParameterCostFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typename TControlPointLattice::Pointer m_ControlPointLattice; typename TControlPointLattice::PointType m_Origin; typename TControlPointLattice::SpacingType m_Spacing; typename TControlPointLattice::SizeType m_Size; typename TControlPointLattice::DirectionType m_Direction; ArrayType m_SplineOrder; ArrayType m_CloseDimension; typename TControlPointLattice::PixelType m_DataPoint; }; /** * Class definition for BSplineControlPointImageFilter */ template class BSplineControlPointImageFilter : public ImageToImageFilter { public: typedef BSplineControlPointImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Extract dimension from input image. */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); typedef TInputImage ControlPointLatticeType; typedef TOutputImage ImageType; /** Image typedef support. */ typedef typename ImageType::PixelType PixelType; typedef typename ImageType::RegionType RegionType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::PointType PointType; typedef typename ImageType::PointType ContinuousIndexType; typedef typename TOutputImage::SpacingType SpacingType; typedef typename TOutputImage::PointType OriginType; typedef typename TOutputImage::SizeType SizeType; typedef typename TOutputImage::DirectionType DirectionType; /** Other typedef */ typedef float RealType; typedef Image RealImageType; typedef FixedArray ArrayType; typedef VariableSizeMatrix GradientType; typedef RealImageType HessianType; /** PointSet typedef support. */ typedef PointSet PointSetType; typedef typename PointSetType::PixelType PointDataType; typedef typename PointSetType::PointDataContainer PointDataContainerType; /** Interpolation kernel type (default spline order = 3) */ typedef CoxDeBoorBSplineKernelFunction<3> KernelType; typedef BSplineKernelFunction<0> KernelOrder0Type; typedef BSplineKernelFunction<1> KernelOrder1Type; typedef BSplineKernelFunction<2> KernelOrder2Type; typedef BSplineKernelFunction<3> KernelOrder3Type; /** Helper functions */ void SetSplineOrder( unsigned int ); void SetSplineOrder( ArrayType ); itkGetConstReferenceMacro( SplineOrder, ArrayType ); itkSetMacro( CloseDimension, ArrayType ); itkGetConstReferenceMacro( CloseDimension, ArrayType ); /** Gets and sets for the output image. */ itkSetMacro( Spacing, SpacingType ); itkGetConstMacro( Spacing, SpacingType ); itkSetMacro( Origin, OriginType ); itkGetConstMacro( Origin, OriginType ); itkSetMacro( Size, SizeType ); itkGetConstMacro( Size, SizeType ); itkSetMacro( Direction, DirectionType ); itkGetConstMacro( Direction, DirectionType ); /** * Evaluate the resulting B-spline object at a specified * point or index within the image domain. */ void EvaluateAtPoint( PointType, PixelType & ); void EvaluateAtIndex( IndexType, PixelType & ); void EvaluateAtContinuousIndex( ContinuousIndexType, PixelType & ); /** * Evaluate the resulting B-spline object at a specified * parameteric point. Note that the parameterization over * each dimension of the B-spline object is [0, 1). */ void Evaluate( PointType, PixelType & ); /** * Evaluate the gradient of the resulting B-spline object at a specified * point or index within the image domain. */ void EvaluateGradientAtPoint( PointType, GradientType & ); void EvaluateGradientAtIndex( IndexType, GradientType & ); void EvaluateGradientAtContinuousIndex( ContinuousIndexType, GradientType & ); /** * Evaluate the gradient of the resulting B-spline object * at a specified parameteric point. Note that the * parameterization over each dimension of the B-spline * object is [0, 1). */ void EvaluateGradient( PointType, GradientType & ); /** * Evaluate the Jacobian of the resulting B-spline object at a specified * point or index within the image domain. */ void EvaluateJacobianAtPoint( PointType pt, GradientType &jac ) { this->EvaluateGradientAtPoint( pt, jac ); GradientType I( jac.Rows(), jac.Cols() ); I.SetIdentity(); jac += I; } void EvaluateJacobianAtIndex( IndexType idx, GradientType &jac ) { this->EvaluateGradientAtIndex( idx, jac ); GradientType I( jac.Rows(), jac.Cols() ); I.SetIdentity(); jac += I; } void EvaluateJacobianAtContinuousIndex( ContinuousIndexType cidx, GradientType &jac ) { this->EvaluateGradientAtContinuousIndex( cidx, jac ); GradientType I( jac.Rows(), jac.Cols() ); I.SetIdentity(); jac += I; } /** * Evaluate the Jacobian with respect to the image of the resulting B-spline * object at a specified point or index within the image domain. */ void EvaluateSpatialJacobianAtPoint( PointType pt, GradientType &jac ) { this->EvaluateGradientAtPoint( pt, jac ); for ( unsigned int i = 0; i < jac.Cols(); i++ ) { RealType factor = static_cast( this->GetOutput()->GetLargestPossibleRegion().GetSize()[i] ) * this->GetOutput()->GetSpacing()[i]; for ( unsigned int j = 0; j < jac.Rows(); j++ ) { jac(i, j) *= factor; if ( i == j ) { jac(i, j) += 1.0; } } } } void EvaluateSpatialJacobianAtIndex( IndexType idx, GradientType &jac ) { PointType pt; this->GetOutput()->TransformIndexToPhysicalPoint( idx, pt ); this->EvaluateSpatialJacobianAtPoint( pt, jac ); } void EvaluateSpatialJacobianAtContinuousIndex( ContinuousIndexType cidx, GradientType &jac ) { PointType pt; this->GetOutput()->TransformContinuousIndexToPhysicalPoint( cidx, pt ); this->EvaluateSpatialJacobianAtPoint( pt, jac ); } /** * Evaluate the Hessian of the resulting B-spline object at a specified * point or index within the image domain. Since the Hessian for a vector * function is a 3-tensor, one must specify the component. */ void EvaluateHessianAtPoint( PointType, HessianType &, unsigned int ); void EvaluateHessianAtIndex( IndexType, HessianType &, unsigned int ); void EvaluateHessianAtContinuousIndex( ContinuousIndexType, GradientType &, unsigned int ); void EvaluateHessian( PointType, GradientType &, unsigned int ); /** * Given a B-spline object value and an initial parametric guess, use * bounded optimization (LBFGSB) to find the parameters corresponding to the * B-spline object value. */ void CalculateParametersClosestToDataPoint( PointDataType, PointType & ); /** * Generate a refined control point lattice from the input control point * lattice such that the resolution is doubled for each level. */ typename ControlPointLatticeType::Pointer RefineControlPointLattice( ArrayType ); protected: BSplineControlPointImageFilter(); virtual ~BSplineControlPointImageFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: BSplineControlPointImageFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented void GenerateOutputImageFast(); void CollapsePhiLattice( ControlPointLatticeType *, ControlPointLatticeType *, RealType, unsigned int ); void SetNumberOfLevels( ArrayType ); /** Parameters for the output image. */ SizeType m_Size; SpacingType m_Spacing; OriginType m_Origin; DirectionType m_Direction; ArrayType m_NumberOfLevels; bool m_DoMultilevel; unsigned int m_MaximumNumberOfLevels; vnl_matrix m_RefinedLatticeCoefficients[ImageDimension]; ArrayType m_CloseDimension; ArrayType m_SplineOrder; ArrayType m_NumberOfControlPoints; typename KernelType::Pointer m_Kernel[ImageDimension]; typename KernelOrder0Type::Pointer m_KernelOrder0; typename KernelOrder1Type::Pointer m_KernelOrder1; typename KernelOrder2Type::Pointer m_KernelOrder2; typename KernelOrder3Type::Pointer m_KernelOrder3; RealType m_BSplineEpsilon; inline typename RealImageType::IndexType NumberToIndex( unsigned int number, typename RealImageType::SizeType size ) { typename RealImageType::IndexType k; k[0] = 1; for ( unsigned int i = 1; i < ImageDimension; i++ ) { k[i] = size[ImageDimension-i-1]*k[i-1]; } typename RealImageType::IndexType index; for ( unsigned int i = 0; i < ImageDimension; i++ ) { index[ImageDimension-i-1] = static_cast( number/k[ImageDimension-i-1] ); number %= k[ImageDimension-i-1]; } return index; } }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkBSplineControlPointImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkBSplineControlPointImageFilter.txx000066400000000000000000001000361147325206600257300ustar00rootroot00000000000000#ifndef __itkBSplineControlPointImageFilter_txx #define __itkBSplineControlPointImageFilter_txx #include "itkBSplineControlPointImageFilter.h" #include "itkImageDuplicator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkLBFGSBOptimizer.h" namespace itk { /** * ParameterCostFunction class definitions */ template ParameterCostFunction ::ParameterCostFunction() { this->m_ControlPointLattice = NULL; } template ParameterCostFunction ::~ParameterCostFunction() { } template typename ParameterCostFunction::MeasureType ParameterCostFunction ::GetValue( const ParametersType & parameters ) const { typename TControlPointLattice::PointType point; for( unsigned int d = 0; d < ParametricDimension; d++ ) { point[d] = parameters[d]; if( this->m_CloseDimension[d] ) { MeasureType sign = -1.0; if( point[d] < 0.0 ) { sign = 1.0; } while( point[d] < 0 || point[d] >= 1.0 ) { point[d] += sign; } } } typedef BSplineControlPointImageFilter BSplineFilterType; typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetOrigin( this->m_Origin ); bspliner->SetSpacing( this->m_Spacing ); bspliner->SetSize( this->m_Size ); bspliner->SetDirection( this->m_Direction ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetCloseDimension( this->m_CloseDimension ); bspliner->SetInput( this->m_ControlPointLattice ); typename TControlPointLattice::PixelType value; bspliner->Evaluate( point, value ); MeasureType metric = 0.0; for( unsigned int d = 0; d < value.Size(); d++ ) { metric += vnl_math_sqr( value[d] - this->m_DataPoint[d] ); } return metric; } template void ParameterCostFunction ::GetDerivative( const ParametersType & parameters, DerivativeType & derivative ) const { typename TControlPointLattice::PointType point; for( unsigned int d = 0; d < ParametricDimension; d++ ) { point[d] = parameters[d]; if( this->m_CloseDimension[d] ) { MeasureType sign = -1.0; if( point[d] < 0.0 ) { sign = 1.0; } while( point[d] < 0 || point[d] >= 1.0 ) { point[d] += sign; } } } typedef BSplineControlPointImageFilter BSplineFilterType; typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetOrigin( this->m_Origin ); bspliner->SetSpacing( this->m_Spacing ); bspliner->SetSize( this->m_Size ); bspliner->SetDirection( this->m_Direction ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetCloseDimension( this->m_CloseDimension ); bspliner->SetInput( this->m_ControlPointLattice ); typename TControlPointLattice::PixelType value; bspliner->Evaluate( point, value ); typename BSplineFilterType::GradientType gradient; bspliner->EvaluateGradient( point, gradient ); derivative.SetSize( this->GetNumberOfParameters() ); derivative.Fill( 0.0 ); for( unsigned int i = 0; i < gradient.Rows(); i++ ) { for( unsigned int j = 0; j < gradient.Cols(); j++ ) { derivative[j] += ( 2.0 * ( value[i] - this->m_DataPoint[i] ) * gradient(i, j) ); } } } template unsigned int ParameterCostFunction ::GetNumberOfParameters() const { return ParametricDimension; } /** * BSplineControlPointImageFilter class definitions */ template BSplineControlPointImageFilter ::BSplineControlPointImageFilter() { this->m_SplineOrder.Fill( 3 ); for( unsigned int i = 0; i < ImageDimension; i++ ) { this->m_NumberOfControlPoints[i] = ( this->m_SplineOrder[i]+1 ); this->m_Kernel[i] = KernelType::New(); this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] ); } this->m_KernelOrder0 = KernelOrder0Type::New(); this->m_KernelOrder1 = KernelOrder1Type::New(); this->m_KernelOrder2 = KernelOrder2Type::New(); this->m_KernelOrder3 = KernelOrder3Type::New(); this->m_NumberOfLevels.Fill( 1 ); this->m_CloseDimension.Fill( 0 ); this->m_BSplineEpsilon = vcl_numeric_limits::epsilon(); } template BSplineControlPointImageFilter ::~BSplineControlPointImageFilter() { } template void BSplineControlPointImageFilter ::SetNumberOfLevels( ArrayType levels ) { this->m_NumberOfLevels = levels; this->m_MaximumNumberOfLevels = 1; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_NumberOfLevels[i] == 0 ) { itkExceptionMacro( "The number of levels in each dimension must be greater than 0" ); } if( this->m_NumberOfLevels[i] > this->m_MaximumNumberOfLevels ) { this->m_MaximumNumberOfLevels = this->m_NumberOfLevels[i]; } } itkDebugMacro( "Setting m_NumberOfLevels to " << this->m_NumberOfLevels ); itkDebugMacro( "Setting m_MaximumNumberOfLevels to " << this->m_MaximumNumberOfLevels ); if( this->m_MaximumNumberOfLevels > 1 ) { this->m_DoMultilevel = true; } else { this->m_DoMultilevel = false; } this->SetSplineOrder( this->m_SplineOrder ); this->Modified(); } template void BSplineControlPointImageFilter ::SetSplineOrder( unsigned int order ) { this->m_SplineOrder.Fill( order ); this->SetSplineOrder( this->m_SplineOrder ); } template void BSplineControlPointImageFilter ::SetSplineOrder( ArrayType order ) { itkDebugMacro( "Setting m_SplineOrder to " << order ); this->m_SplineOrder = order; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_SplineOrder[i] == 0 ) { itkExceptionMacro( "The spline order in each dimension must be greater than 0" ); } this->m_Kernel[i] = KernelType::New(); this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] ); if( this->m_DoMultilevel ) { typename KernelType::MatrixType C; C = this->m_Kernel[i]->GetShapeFunctionsInZeroToOneInterval(); vnl_matrix R; vnl_matrix S; R.set_size( C.rows(), C.cols() ); S.set_size( C.rows(), C.cols() ); for( unsigned int j = 0; j < C.rows(); j++ ) { for( unsigned int k = 0; k < C.cols(); k++ ) { R(j, k) = S(j, k) = static_cast( C(j, k) ); } } for( unsigned int j = 0; j < C.cols(); j++ ) { RealType c = vcl_pow( static_cast( 2.0 ), static_cast( C.cols()-j-1 ) ); for( unsigned int k = 0; k < C.rows(); k++) { R(k, j) *= c; } } R = R.transpose(); R.flipud(); S = S.transpose(); S.flipud(); this->m_RefinedLatticeCoefficients[i] = ( vnl_svd( R ).solve( S ) ).extract( 2, S.cols() ); } } this->Modified(); } template void BSplineControlPointImageFilter ::GenerateData() { for( unsigned int i = 0; i < ImageDimension; i++) { if( this->m_Size[i] == 0 ) { itkExceptionMacro( "Size must be specified." ); } } this->GetOutput()->SetOrigin( this->m_Origin ); this->GetOutput()->SetSpacing( this->m_Spacing ); this->GetOutput()->SetRegions( this->m_Size ); this->GetOutput()->SetDirection( this->m_Direction ); this->GetOutput()->Allocate(); /** * Calculate the appropriate epsilon value. */ unsigned int maximumNumberOfSpans = 0; for( unsigned int d = 0; d < ImageDimension; d++ ) { unsigned int numberOfSpans = this->m_NumberOfControlPoints[d] - this->m_SplineOrder[d]; numberOfSpans <<= ( this->m_NumberOfLevels[d] - 1 ); if( numberOfSpans > maximumNumberOfSpans ) { maximumNumberOfSpans = numberOfSpans; } } this->m_BSplineEpsilon = 10.0 * vcl_numeric_limits::epsilon(); while( static_cast( maximumNumberOfSpans ) == static_cast( maximumNumberOfSpans ) - this->m_BSplineEpsilon ) { this->m_BSplineEpsilon *= 10.0; } this->m_BSplineEpsilon = 0.0001; for( unsigned int i = 0; i < ImageDimension; i++) { this->m_NumberOfControlPoints[i] = this->GetInput()->GetLargestPossibleRegion().GetSize()[i]; } this->GenerateOutputImageFast(); } template typename BSplineControlPointImageFilter ::ControlPointLatticeType::Pointer BSplineControlPointImageFilter ::RefineControlPointLattice( ArrayType numberOfLevels ) { this->SetNumberOfLevels( numberOfLevels ); typedef ImageDuplicator ImageDuplicatorType; typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New(); Duplicator->SetInputImage( this->GetInput() ); Duplicator->Update(); typename ControlPointLatticeType::Pointer psiLattice = ControlPointLatticeType::New(); psiLattice = Duplicator->GetOutput(); for( unsigned int m = 1; m < this->m_MaximumNumberOfLevels; m++ ) { ArrayType numberOfNewControlPoints; for( unsigned int i = 0; i < ImageDimension; i++ ) { numberOfNewControlPoints[i] = psiLattice->GetLargestPossibleRegion().GetSize()[i]; } for( unsigned int i = 0; i < ImageDimension; i++ ) { if( m < this->m_NumberOfLevels[i] ) { numberOfNewControlPoints[i] = 2 * numberOfNewControlPoints[i]-this->m_SplineOrder[i]; } } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { size[i] = numberOfNewControlPoints[i] - this->m_SplineOrder[i]; } else { size[i] = numberOfNewControlPoints[i]; } } typename ControlPointLatticeType::Pointer refinedLattice = ControlPointLatticeType::New(); refinedLattice->SetRegions( size ); refinedLattice->Allocate(); PixelType data; data.Fill( 0.0 ); refinedLattice->FillBuffer( data ); typename ControlPointLatticeType::IndexType idx; typename ControlPointLatticeType::IndexType idx_Psi; typename ControlPointLatticeType::IndexType tmp; typename ControlPointLatticeType::IndexType tmp_Psi; typename ControlPointLatticeType::IndexType off; typename ControlPointLatticeType::IndexType off_Psi; typename ControlPointLatticeType::RegionType::SizeType size_Psi; size.Fill( 2 ); unsigned int N = 1; for( unsigned int i = 0; i < ImageDimension; i++ ) { N *= ( this->m_SplineOrder[i] + 1 ); size_Psi[i] = this->m_SplineOrder[i] + 1; } ImageRegionIteratorWithIndex It( refinedLattice, refinedLattice->GetLargestPossibleRegion() ); It.GoToBegin(); while( !It.IsAtEnd() ) { idx = It.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( m < this->m_NumberOfLevels[i] ) { idx_Psi[i] = static_cast( 0.5*idx[i] ); } else { idx_Psi[i] = static_cast( idx[i] ); } } for( unsigned int i = 0; i < ( 2 << ImageDimension - 1 ); i++ ) { PixelType sum( 0.0 ); PixelType val; off = this->NumberToIndex( i, size ); bool outOfBoundary = false; for( unsigned int j = 0; j < ImageDimension; j++ ) { tmp[j] = idx[j] + off[j]; if( tmp[j] >= static_cast( numberOfNewControlPoints[j] ) && !this->m_CloseDimension[j] ) { outOfBoundary = true; break; } if( this->m_CloseDimension[j] ) { tmp[j] %= refinedLattice->GetLargestPossibleRegion().GetSize()[j]; } } if( outOfBoundary ) { continue; } for( unsigned int j = 0; j < N; j++ ) { off_Psi = this->NumberToIndex( j, size_Psi ); bool outOfBoundary = false; for( unsigned int k = 0; k < ImageDimension; k++ ) { tmp_Psi[k] = idx_Psi[k] + off_Psi[k]; if( tmp_Psi[k] >= static_cast( this->GetInput()->GetLargestPossibleRegion().GetSize()[k] ) && !this->m_CloseDimension[k] ) { outOfBoundary = true; break; } if( this->m_CloseDimension[k] ) { tmp_Psi[k] %= psiLattice->GetLargestPossibleRegion().GetSize()[k]; } } if( outOfBoundary ) { continue; } RealType coeff = 1.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { coeff *= this->m_RefinedLatticeCoefficients[k]( off[k], off_Psi[k] ); } val = psiLattice->GetPixel( tmp_Psi ); val *= coeff; sum += val; } refinedLattice->SetPixel( tmp, sum ); } bool IsEvenIndex = false; while( !IsEvenIndex && !It.IsAtEnd() ) { ++It; idx = It.GetIndex(); IsEvenIndex = true; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( idx[i] % 2 ) { IsEvenIndex = false; } } } } typedef ImageDuplicator ImageDuplicatorType; typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New(); Duplicator->SetInputImage( refinedLattice ); Duplicator->Update(); psiLattice = Duplicator->GetOutput(); } return psiLattice; } template void BSplineControlPointImageFilter ::GenerateOutputImageFast() { typename ControlPointLatticeType::Pointer collapsedPhiLattices[ImageDimension+1]; for( unsigned int i = 0; i < ImageDimension; i++ ) { collapsedPhiLattices[i] = ControlPointLatticeType::New(); collapsedPhiLattices[i]->SetOrigin( this->GetInput()->GetOrigin() ); collapsedPhiLattices[i]->SetSpacing( this->GetInput()->GetSpacing() ); typename ControlPointLatticeType::SizeType size; size.Fill( 1 ); for( unsigned int j = 0; j < i; j++ ) { size[j] = this->GetInput()->GetLargestPossibleRegion().GetSize()[j]; } collapsedPhiLattices[i]->SetRegions( size ); collapsedPhiLattices[i]->Allocate(); } typedef ImageDuplicator DuplicatorType; typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage( this->GetInput() ); duplicator->Update(); collapsedPhiLattices[ImageDimension] = duplicator->GetOutput(); ArrayType totalNumberOfSpans; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { totalNumberOfSpans[i] = this->GetInput()->GetLargestPossibleRegion().GetSize()[i]; } else { totalNumberOfSpans[i] = this->GetInput()->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i]; } } FixedArray U; FixedArray currentU; currentU.Fill( -1 ); typename ImageType::IndexType startIndex = this->GetOutput()->GetRequestedRegion().GetIndex(); typename ControlPointLatticeType::IndexType startPhiIndex = this->GetInput()->GetLargestPossibleRegion().GetIndex(); ImageRegionIteratorWithIndex It( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { typename ImageType::IndexType idx = It.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { U[i] = static_cast( totalNumberOfSpans[i] ) * static_cast( idx[i] - startIndex[i] ) / static_cast( this->m_Size[i] - 1 ); if( vnl_math_abs( U[i] - static_cast( totalNumberOfSpans[i] ) ) <= this->m_BSplineEpsilon ) { U[i] = static_cast( totalNumberOfSpans[i] ) - this->m_BSplineEpsilon; } if( U[i] >= static_cast( totalNumberOfSpans[i] ) ) { itkExceptionMacro( "The collapse point component " << U[i] << " is outside the corresponding parametric domain of [0, " << totalNumberOfSpans[i] << "]." ); } } for( int i = ImageDimension-1; i >= 0; i-- ) { if( U[i] != currentU[i] ) { for( int j = i; j >= 0; j-- ) { this->CollapsePhiLattice( collapsedPhiLattices[j+1], collapsedPhiLattices[j], U[j], j ); currentU[j] = U[j]; } break; } } It.Set( collapsedPhiLattices[0]->GetPixel( startPhiIndex ) ); } } template void BSplineControlPointImageFilter ::CollapsePhiLattice( ControlPointLatticeType *lattice, ControlPointLatticeType *collapsedLattice, RealType u, unsigned int dimension ) { ImageRegionIteratorWithIndex It ( collapsedLattice, collapsedLattice->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PointDataType data; data.Fill( 0.0 ); typename ControlPointLatticeType::IndexType idx = It.GetIndex(); for( unsigned int i = 0; i < this->m_SplineOrder[dimension] + 1; i++ ) { idx[dimension] = static_cast( u ) + i; RealType v = u - idx[dimension] + 0.5*static_cast( this->m_SplineOrder[dimension] - 1 ); RealType B = 0.0; switch( this->m_SplineOrder[dimension] ) { case 0: { B = this->m_KernelOrder0->Evaluate( v ); break; } case 1: { B = this->m_KernelOrder1->Evaluate( v ); break; } case 2: { B = this->m_KernelOrder2->Evaluate( v ); break; } case 3: { B = this->m_KernelOrder3->Evaluate( v ); break; } default: { B = this->m_Kernel[dimension]->Evaluate( v ); break; } } if( this->m_CloseDimension[dimension] ) { idx[dimension] %= lattice->GetLargestPossibleRegion().GetSize()[dimension]; } data += ( lattice->GetPixel( idx ) * B ); } It.Set( data ); } } template void BSplineControlPointImageFilter ::EvaluateAtPoint( PointType point, PixelType &data ) { for( unsigned int i = 0; i < ImageDimension; i++) { point[i] -= this->m_Origin[i]; point[i] /= ( static_cast( this->m_Size[i]-1 ) * this->m_Spacing[i] ); } this->Evaluate( point, data ); } template void BSplineControlPointImageFilter ::EvaluateAtIndex( IndexType idx, PixelType &data ) { PointType point; this->GetOutput()->TransformIndexToPhysicalPoint( idx, point ); this->EvaluateAtPoint( point, data ); } template void BSplineControlPointImageFilter ::EvaluateAtContinuousIndex( ContinuousIndexType idx, PixelType &data ) { PointType point; this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, point ); this->EvaluateAtPoint( point, data ); } template void BSplineControlPointImageFilter ::Evaluate( PointType params, PixelType &data ) { vnl_vector p( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( params[i] == NumericTraits::One ) { params[i] = NumericTraits::One - this->m_BSplineEpsilon; } if( params[i] < 0.0 || params[i] >= 1.0 ) { itkExceptionMacro( "The specified point " << params << " is outside the reparameterized domain [0, 1)." ); } p[i] = static_cast( params[i] ) * static_cast( this->GetInput()->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i] ); } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w; w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); PointDataType val; data.Fill( 0.0 ); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = p[i] - static_cast( static_cast( p[i] ) + idx[i] ) + 0.5*static_cast( this->m_SplineOrder[i] - 1 ); switch( this->m_SplineOrder[i] ) { case 0: { B *= this->m_KernelOrder0->Evaluate( u ); break; } case 1: { B *= this->m_KernelOrder1->Evaluate( u ); break; } case 2: { B *= this->m_KernelOrder2->Evaluate( u ); break; } case 3: { B *= this->m_KernelOrder3->Evaluate( u ); break; } default: { B *= this->m_Kernel[i]->Evaluate( u ); break; } } } for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->GetInput()->GetLargestPossibleRegion().GetSize()[i]; } } if( this->GetInput()->GetLargestPossibleRegion().IsInside( idx ) ) { val = this->GetInput()->GetPixel( idx ); val *= B; data += val; } } } template void BSplineControlPointImageFilter ::EvaluateGradientAtPoint( PointType point, GradientType &gradient ) { for( unsigned int i = 0; i < ImageDimension; i++) { point[i] -= this->m_Origin[i]; point[i] /= ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); } this->EvaluateGradient( point, gradient ); } template void BSplineControlPointImageFilter ::EvaluateGradientAtIndex( IndexType idx, GradientType &gradient ) { PointType point; this->GetOutput()->TransformIndexToPhysicalPoint( idx, point ); this->EvaluateGradientAtPoint( point, gradient ); } template void BSplineControlPointImageFilter ::EvaluateGradientAtContinuousIndex( ContinuousIndexType idx, GradientType &gradient ) { PointType point; this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, gradient ); this->EvaluateGradientAtPoint( point, gradient ); } template void BSplineControlPointImageFilter ::EvaluateGradient( PointType params, GradientType &gradient ) { vnl_vector p( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( params[i] < 0.0 || params[i] > 1.0 ) { itkExceptionMacro( "The specified point " << params << " is outside the reparameterized image domain [0, 1)." ); } if( params[i] == 1.0 ) { params[i] -= this->m_BSplineEpsilon; } p[i] = static_cast( params[i] ) * static_cast( this->GetInput()->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i] ); } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w; w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); PixelType val; gradient.SetSize( val.Size(), ImageDimension ); gradient.Fill( 0.0 ); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); for( unsigned int j = 0; j < gradient.Cols(); j++ ) { for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = p[i] - static_cast( static_cast( p[i] ) + idx[i] ) + 0.5*static_cast( this->m_SplineOrder[i] - 1 ); if( j == i ) { B *= this->m_Kernel[i]->EvaluateDerivative( u ); } else { B *= this->m_Kernel[i]->Evaluate( u ); } } for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->GetInput()->GetLargestPossibleRegion().GetSize()[i]; } } if( this->GetInput()->GetLargestPossibleRegion().IsInside( idx ) ) { val = this->GetInput()->GetPixel( idx ); val *= B; for( unsigned int i = 0; i < val.Size(); i++ ) { gradient( i, j ) += val[i]; } } } } } template void BSplineControlPointImageFilter ::EvaluateHessian( PointType params, GradientType &hessian, unsigned int component = 0 ) { vnl_vector p( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( params[i] < 0.0 || params[i] > 1.0 ) { itkExceptionMacro( "The specified point " << params << " is outside the reparameterized image domain [0, 1)." ); } if( params[i] == 1.0 ) { params[i] = 1.0 - this->m_BSplineEpsilon; } p[i] = static_cast( params[i] ) * static_cast( this->GetInput()->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i] ); } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w; w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); RealType val; hessian.SetSize( ImageDimension, ImageDimension ); hessian.Fill( 0.0 ); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); for( unsigned int j = 0; j < hessian.Rows(); j++ ) { for( unsigned int k = j; k < hessian.Cols(); k++ ) { for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = p[i] - static_cast( static_cast( p[i] ) + idx[i] ) + 0.5 * static_cast( this->m_SplineOrder[i] - 1 ); if( i == j && j == k ) { B *= this->m_Kernel[i]->EvaluateNthDerivative( u, 2 ); } else if( ( i == j || i == k ) && j != k ) { B *= this->m_Kernel[i]->EvaluateDerivative( u ); } else { B *= this->m_Kernel[i]->Evaluate( u ); } } for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->GetInput()->GetLargestPossibleRegion().GetSize()[i]; } } if( this->GetInput()->GetLargestPossibleRegion().IsInside( idx ) ) { val = this->GetInput()->GetPixel( idx )[component]; val *= B; hessian( j, k ) += val; hessian( k, j ) += val; } } } } } template void BSplineControlPointImageFilter ::CalculateParametersClosestToDataPoint( PointDataType point, PointType ¶ms ) { typedef ParameterCostFunction CostFunctionType; typename CostFunctionType::Pointer costFunction = CostFunctionType::New(); costFunction->SetControlPointLattice( const_cast( this->GetInput() ) ); costFunction->SetOrigin( this->m_Origin ); costFunction->SetSpacing( this->m_Spacing ); costFunction->SetSize( this->m_Size ); costFunction->SetDirection( this->m_Direction ); costFunction->SetSplineOrder( this->m_SplineOrder ); costFunction->SetCloseDimension( this->m_CloseDimension ); costFunction->SetDataPoint( point ); /** * Rescale parameters between [0, 1) */ typename LBFGSBOptimizer::ParametersType initialParameters; initialParameters.SetSize( ImageDimension ); for( unsigned int d = 0; d < ImageDimension; d++ ) { initialParameters[d] = ( params[d] - this->m_Origin[d] ) / ( static_cast( this->m_Size[d] - 1 ) * this->m_Spacing[d] ); } typename LBFGSBOptimizer::BoundSelectionType boundSelection; boundSelection.SetSize( ImageDimension ); for( unsigned int d = 0; d < ImageDimension; d++ ) { if( this->m_CloseDimension[d] ) { boundSelection[d] = 0; } else { boundSelection[d] = 2; } } typename LBFGSBOptimizer::BoundValueType lowerBounds; typename LBFGSBOptimizer::BoundValueType upperBounds; lowerBounds.SetSize( ImageDimension ); upperBounds.SetSize( ImageDimension ); for( unsigned int d = 0; d < ImageDimension; d++ ) { lowerBounds[d] = 0.0; upperBounds[d] = 1.0; } typename LBFGSBOptimizer::Pointer optimizer = LBFGSBOptimizer::New(); optimizer->SetMinimize( true ); optimizer->SetCostFunction( costFunction ); optimizer->SetInitialPosition( initialParameters ); optimizer->SetCostFunctionConvergenceFactor( 1e1 ); optimizer->SetLowerBound( lowerBounds ); optimizer->SetUpperBound( upperBounds ); optimizer->SetBoundSelection( boundSelection ); optimizer->SetProjectedGradientTolerance( 1e-5 ); optimizer->StartOptimization(); typename LBFGSBOptimizer::ParametersType finalParameters = optimizer->GetCurrentPosition(); for( unsigned int i = 0; i < ImageDimension; i++) { point[i] -= this->m_Origin[i]; point[i] /= ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); } for( unsigned int d = 0; d < ImageDimension; d++ ) { params[d] = finalParameters[d] * this->m_Spacing[d] * static_cast( this->m_Size[d] - 1 ) + this->m_Origin[d]; } } /** * Standard "PrintSelf" method */ template void BSplineControlPointImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); for( unsigned int i = 0; i < ImageDimension; i++ ) { this->m_Kernel[i]->Print( os, indent ); } os << indent << "Spline order: " << this->m_SplineOrder << std::endl; os << indent << "Close dimension: " << this->m_CloseDimension << std::endl; os << indent << "Parametric domain" << std::endl; os << indent << " Origin: " << this->m_Origin << std::endl; os << indent << " Spacing: " << this->m_Spacing << std::endl; os << indent << " Size: " << this->m_Size << std::endl; os << indent << " Direction: " << this->m_Direction << std::endl; } } //end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkBSplineScatteredDataPointSetToImageFilter.h000066400000000000000000000252501147325206600274070ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBSplineScatteredDataPointSetToImageFilter.h,v $ Language: C++ Date: $Date: 2009-10-11 19:24:30 $ Version: $Revision: 1.10 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBSplineScatteredDataPointSetToImageFilter_h #define __itkBSplineScatteredDataPointSetToImageFilter_h #include "itkPointSetToImageFilter.h" #include "itkBSplineKernelFunction.h" #include "itkCoxDeBoorBSplineKernelFunction.h" #include "itkFixedArray.h" #include "itkVariableSizeMatrix.h" #include "itkVector.h" #include "itkVectorContainer.h" #include "vnl/vnl_matrix.h" namespace itk { /** \class BSplineScatteredDataPointSetToImageFilter.h * \brief Image filter which provides a B-spline output approximation. * * Given an n-D image with scattered data, this filter finds * a fast approximation to that irregularly spaced data using uniform * B-splines. The traditional method of inverting the observation * matrix to find a least-squares fit is made obsolete. Therefore, * memory issues are not a concern and inverting large matrices is * not applicable. In addition, this allows fitting to be multi-threaded. * This class generalizes from Lee's original paper to encompass * n-D data in m-D parametric space and any *feasible* B-spline order as well * as the option of specifying a confidence value for each point. * * In addition to specifying the input point set, one must specify the number * of control points. The specified number of control points must be * > m_SplineOrder. If one wishes to use the multilevel component of * this algorithm, one must also specify the number of levels in the * hierarchy. If this is desired, the number of control points becomes * the number of control points for the coarsest level. The algorithm * then increases the number of control points at each level so that * the B-spline n-D grid is refined to twice the previous level. * * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * http://hdl.handle.net/1926/140 * * \par REFERENCE * S. Lee, G. Wolberg, and S. Y. Shin, "Scattered Data Interpolation * with Multilevel B-Splines", IEEE Transactions on Visualization and * Computer Graphics, 3(3):228-244, 1997. * * \par REFERENCE * N.J. Tustison and J.C. Gee, "Generalized n-D C^k Scattered Data Approximation * with COnfidence Values", Proceedings of the MIAR conference, August 2006. */ template class BSplineScatteredDataPointSetToImageFilter : public PointSetToImageFilter { public: typedef BSplineScatteredDataPointSetToImageFilter Self; typedef PointSetToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Extract dimension from input and output image. */ itkStaticConstMacro( ImageDimension, unsigned int, TOutputImage::ImageDimension ); typedef TOutputImage ImageType; typedef TInputPointSet PointSetType; /** Image typedef support. */ typedef typename ImageType::PixelType PixelType; typedef typename ImageType::RegionType RegionType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::PointType ContinuousIndexType; /** PointSet typedef support. */ typedef typename PointSetType::PointType PointType; typedef typename PointSetType::PixelType PointDataType; typedef typename PointSetType::PointDataContainer PointDataContainerType; /** Other typedef */ typedef float RealType; typedef VectorContainer WeightsContainerType; typedef Image PointDataImageType; typedef typename PointDataImageType::Pointer PointDataImagePointer; typedef Image RealImageType; typedef typename RealImageType::Pointer RealImagePointer; typedef FixedArray ArrayType; typedef VariableSizeMatrix GradientType; /** * Interpolation kernel type (default spline order = 3) */ typedef CoxDeBoorBSplineKernelFunction<3> KernelType; typedef BSplineKernelFunction<0> KernelOrder0Type; typedef BSplineKernelFunction<1> KernelOrder1Type; typedef BSplineKernelFunction<2> KernelOrder2Type; typedef BSplineKernelFunction<3> KernelOrder3Type; /** Helper functions */ void SetNumberOfLevels( unsigned int ); void SetNumberOfLevels( ArrayType ); itkGetConstReferenceMacro( NumberOfLevels, ArrayType ); void SetSplineOrder( unsigned int ); void SetSplineOrder( ArrayType ); itkGetConstReferenceMacro( SplineOrder, ArrayType ); itkSetMacro( NumberOfControlPoints, ArrayType ); itkGetConstReferenceMacro( NumberOfControlPoints, ArrayType ); itkGetConstReferenceMacro( CurrentNumberOfControlPoints, ArrayType ); itkSetMacro( CloseDimension, ArrayType ); itkGetConstReferenceMacro( CloseDimension, ArrayType ); itkSetMacro( GenerateOutputImage, bool ); itkGetConstReferenceMacro( GenerateOutputImage, bool ); itkBooleanMacro( GenerateOutputImage ); void SetPointWeights( WeightsContainerType * weights ); /** * Get the control point lattice. */ itkSetMacro( PhiLattice, PointDataImagePointer ); itkGetConstMacro( PhiLattice, PointDataImagePointer ); /** * Evaluate the resulting B-spline object at a specified * point or index within the image domain. */ void EvaluateAtPoint( PointType, PointDataType & ); void EvaluateAtIndex( IndexType, PointDataType & ); void EvaluateAtContinuousIndex( ContinuousIndexType, PointDataType & ); /** * Evaluate the resulting B-spline object at a specified * parametric point. Note that the parameterization over * each dimension of the B-spline object is [0, 1]. */ void Evaluate( PointType, PointDataType & ); /** * Evaluate the gradient of the resulting B-spline object at a specified * point or index within the image domain. */ void EvaluateGradientAtPoint( PointType, GradientType & ); void EvaluateGradientAtIndex( IndexType, GradientType & ); void EvaluateGradientAtContinuousIndex( ContinuousIndexType, GradientType & ); /** * Evaluate the gradient of the resulting B-spline object * at a specified parametric point. Note that the * parameterization over each dimension of the B-spline * object is [0, 1]. */ void EvaluateGradient( PointType, GradientType & ); protected: BSplineScatteredDataPointSetToImageFilter(); virtual ~BSplineScatteredDataPointSetToImageFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; /** Multithreaded function which generates the control point lattice. */ void ThreadedGenerateData( const RegionType&, int ); void BeforeThreadedGenerateData(); void AfterThreadedGenerateData(); /** Only the points are divided among the threads, so always return * a valid number */ int SplitRequestedRegion(int, int, RegionType&) { return this->GetNumberOfThreads(); } void GenerateData(); private: //purposely not implemented BSplineScatteredDataPointSetToImageFilter(const Self&); void operator=(const Self&); void RefineControlPointLattice(); void UpdatePointSet(); void GenerateOutputImage(); void GenerateOutputImageFast(); void CollapsePhiLattice( PointDataImageType *, PointDataImageType *, RealType, unsigned int ); bool m_DoMultilevel; bool m_GenerateOutputImage; bool m_UsePointWeights; unsigned int m_MaximumNumberOfLevels; unsigned int m_CurrentLevel; ArrayType m_NumberOfControlPoints; ArrayType m_CurrentNumberOfControlPoints; ArrayType m_CloseDimension; ArrayType m_SplineOrder; ArrayType m_NumberOfLevels; typename WeightsContainerType::Pointer m_PointWeights; typename PointDataImageType::Pointer m_PhiLattice; typename PointDataImageType::Pointer m_PsiLattice; typename PointDataContainerType::Pointer m_InputPointData; typename PointDataContainerType::Pointer m_OutputPointData; typename KernelType::Pointer m_Kernel[ImageDimension]; typename KernelOrder0Type::Pointer m_KernelOrder0; typename KernelOrder1Type::Pointer m_KernelOrder1; typename KernelOrder2Type::Pointer m_KernelOrder2; typename KernelOrder3Type::Pointer m_KernelOrder3; std::vector m_OmegaLatticePerThread; std::vector m_DeltaLatticePerThread; RealType m_BSplineEpsilon; vnl_matrix m_RefinedLatticeCoefficients[ImageDimension]; inline typename RealImageType::IndexType NumberToIndex( unsigned int number, typename RealImageType::SizeType size ) { typename RealImageType::IndexType k; k[0] = 1; for ( unsigned int i = 1; i < ImageDimension; i++ ) { k[i] = size[ImageDimension-i-1]*k[i-1]; } typename RealImageType::IndexType index; for ( unsigned int i = 0; i < ImageDimension; i++ ) { index[ImageDimension-i-1] = static_cast( number/k[ImageDimension-i-1] ); number %= k[ImageDimension-i-1]; } return index; } }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkBSplineScatteredDataPointSetToImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkBSplineScatteredDataPointSetToImageFilter.txx000066400000000000000000001222221147325206600300000ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkBSplineScatteredDataPointSetToImageFilter.txx,v $ Language: C++ Date: $Date: 2009-10-02 12:36:37 $ Version: $Revision: 1.20 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkBSplineScatteredDataPointSetToImageFilter_txx #define __itkBSplineScatteredDataPointSetToImageFilter_txx #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkImageDuplicator.h" #include "itkCastImageFilter.h" #include "itkNumericTraits.h" #include "vnl/vnl_math.h" #include "vnl/algo/vnl_matrix_inverse.h" #include "vnl/vnl_vector.h" #include "vcl_limits.h" namespace itk { /** * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * http://hdl.handle.net/1926/140 */ template BSplineScatteredDataPointSetToImageFilter ::BSplineScatteredDataPointSetToImageFilter() { this->m_SplineOrder.Fill( 3 ); for( unsigned int i = 0; i < ImageDimension; i++ ) { this->m_NumberOfControlPoints[i] = ( this->m_SplineOrder[i] + 1 ); this->m_Kernel[i] = KernelType::New(); this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] ); } this->m_KernelOrder0 = KernelOrder0Type::New(); this->m_KernelOrder1 = KernelOrder1Type::New(); this->m_KernelOrder2 = KernelOrder2Type::New(); this->m_KernelOrder3 = KernelOrder3Type::New(); this->m_CloseDimension.Fill( 0 ); this->m_DoMultilevel = false; this->m_GenerateOutputImage = true; this->m_NumberOfLevels.Fill( 1 ); this->m_MaximumNumberOfLevels = 1; this->m_PhiLattice = NULL; this->m_PsiLattice = PointDataImageType::New(); this->m_InputPointData = PointDataContainerType::New(); this->m_OutputPointData = PointDataContainerType::New(); this->m_PointWeights = WeightsContainerType::New(); this->m_UsePointWeights = false; this->m_BSplineEpsilon = vcl_numeric_limits::epsilon(); } template BSplineScatteredDataPointSetToImageFilter ::~BSplineScatteredDataPointSetToImageFilter() { } template void BSplineScatteredDataPointSetToImageFilter ::SetSplineOrder( unsigned int order ) { this->m_SplineOrder.Fill( order ); this->SetSplineOrder( this->m_SplineOrder ); } template void BSplineScatteredDataPointSetToImageFilter ::SetSplineOrder( ArrayType order ) { itkDebugMacro( "Setting m_SplineOrder to " << order ); this->m_SplineOrder = order; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_SplineOrder[i] == 0 ) { itkExceptionMacro( "The spline order in each dimension must be greater than 0" ); } this->m_Kernel[i] = KernelType::New(); this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] ); if( this->m_DoMultilevel ) { typename KernelType::MatrixType C; C = this->m_Kernel[i]->GetShapeFunctionsInZeroToOneInterval(); vnl_matrix R; vnl_matrix S; R.set_size( C.rows(), C.cols() ); S.set_size( C.rows(), C.cols() ); for( unsigned int j = 0; j < C.rows(); j++ ) { for( unsigned int k = 0; k < C.cols(); k++ ) { R(j, k) = S(j, k) = static_cast( C(j, k) ); } } for( unsigned int j = 0; j < C.cols(); j++ ) { RealType c = vcl_pow( static_cast( 2.0 ), static_cast( C.cols() )-j-1 ); for( unsigned int k = 0; k < C.rows(); k++) { R(k, j) *= c; } } R = R.transpose(); R.flipud(); S = S.transpose(); S.flipud(); this->m_RefinedLatticeCoefficients[i] = ( vnl_svd( R ).solve( S ) ).extract( 2, S.cols() ); } } this->Modified(); } template void BSplineScatteredDataPointSetToImageFilter ::SetNumberOfLevels( unsigned int levels ) { this->m_NumberOfLevels.Fill( levels ); this->SetNumberOfLevels( this->m_NumberOfLevels ); } template void BSplineScatteredDataPointSetToImageFilter ::SetNumberOfLevels( ArrayType levels ) { this->m_NumberOfLevels = levels; this->m_MaximumNumberOfLevels = 1; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_NumberOfLevels[i] == 0 ) { itkExceptionMacro( "The number of levels in each dimension must be greater than 0" ); } if( this->m_NumberOfLevels[i] > this->m_MaximumNumberOfLevels ) { this->m_MaximumNumberOfLevels = this->m_NumberOfLevels[i]; } } itkDebugMacro( "Setting m_NumberOfLevels to " << this->m_NumberOfLevels ); itkDebugMacro( "Setting m_MaximumNumberOfLevels to " << this->m_MaximumNumberOfLevels ); if( this->m_MaximumNumberOfLevels > 1 ) { this->m_DoMultilevel = true; } else { this->m_DoMultilevel = false; } this->SetSplineOrder( this->m_SplineOrder ); this->Modified(); } template void BSplineScatteredDataPointSetToImageFilter ::SetPointWeights( WeightsContainerType * weights ) { this->m_UsePointWeights = true; this->m_PointWeights = weights; this->Modified(); } template void BSplineScatteredDataPointSetToImageFilter ::GenerateData() { /** * Create the output image */ itkDebugMacro( "Size: " << this->m_Size ); itkDebugMacro( "Origin: " << this->m_Origin ); itkDebugMacro( "Spacing: " << this->m_Spacing ); itkDebugMacro( "Direction: " << this->m_Direction ); for( unsigned int i = 0; i < ImageDimension; i++) { if( this->m_Size[i] == 0 ) { itkExceptionMacro( "Size must be specified." ); } } this->GetOutput()->SetOrigin( this->m_Origin ); this->GetOutput()->SetSpacing( this->m_Spacing ); this->GetOutput()->SetDirection( this->m_Direction ); this->GetOutput()->SetRegions( this->m_Size ); this->GetOutput()->Allocate(); /** * Perform some error checking on the input */ if( this->m_UsePointWeights && ( this->m_PointWeights->Size() != this->GetInput()->GetNumberOfPoints() ) ) { itkExceptionMacro( "The number of weight points and input points must be equal." ); } for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_NumberOfControlPoints[i] < this->m_SplineOrder[i] + 1 ) { itkExceptionMacro( "The number of control points must be greater than the spline order." ); } } /** * Calculate the appropriate epsilon value. */ unsigned int maximumNumberOfSpans = 0; for( unsigned int d = 0; d < ImageDimension; d++ ) { unsigned int numberOfSpans = this->m_NumberOfControlPoints[d] - this->m_SplineOrder[d]; numberOfSpans <<= ( this->m_NumberOfLevels[d] - 1 ); if( numberOfSpans > maximumNumberOfSpans ) { maximumNumberOfSpans = numberOfSpans; } } this->m_BSplineEpsilon = 10.0 * vcl_numeric_limits::epsilon(); while( static_cast( maximumNumberOfSpans ) == static_cast( maximumNumberOfSpans ) - this->m_BSplineEpsilon ) { this->m_BSplineEpsilon *= 10.0; } this->m_InputPointData->Initialize(); this->m_OutputPointData->Initialize(); if( this->GetInput()->GetNumberOfPoints() > 0 ) { typename PointSetType::PointDataContainer::ConstIterator It; It = this->GetInput()->GetPointData()->Begin(); while( It != this->GetInput()->GetPointData()->End() ) { if( !this->m_UsePointWeights ) { this->m_PointWeights->InsertElement( It.Index(), 1.0 ); } this->m_InputPointData->InsertElement( It.Index(), It.Value() ); this->m_OutputPointData->InsertElement( It.Index(), It.Value() ); ++It; } } this->m_CurrentLevel = 0; this->m_CurrentNumberOfControlPoints = this->m_NumberOfControlPoints; /** * Set up multithread processing to handle generating the * control point lattice. */ typename ImageSource::ThreadStruct str1; str1.Filter = this; this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() ); this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str1 ); /** * Multithread the generation of the control point lattice. */ this->BeforeThreadedGenerateData(); this->GetMultiThreader()->SingleMethodExecute(); this->AfterThreadedGenerateData(); this->UpdatePointSet(); if( this->m_DoMultilevel ) { this->m_PsiLattice->SetRegions( this->m_PhiLattice->GetLargestPossibleRegion() ); this->m_PsiLattice->Allocate(); PointDataType P( 0.0 ); this->m_PsiLattice->FillBuffer( P ); } for( this->m_CurrentLevel = 1; this->m_CurrentLevel < this->m_MaximumNumberOfLevels; this->m_CurrentLevel++ ) { ImageRegionIterator ItPsi( this->m_PsiLattice, this->m_PsiLattice->GetLargestPossibleRegion() ); ImageRegionIterator ItPhi( this->m_PhiLattice, this->m_PhiLattice->GetLargestPossibleRegion() ); for( ItPsi.GoToBegin(), ItPhi.GoToBegin(); !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi ) { ItPsi.Set( ItPhi.Get() + ItPsi.Get() ); } this->RefineControlPointLattice(); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CurrentLevel < this->m_NumberOfLevels[i] ) { this->m_CurrentNumberOfControlPoints[i] = 2*this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i]; } } itkDebugMacro( "Current Level = " << this->m_CurrentLevel ); itkDebugMacro( " Current number of control points = " << this->m_CurrentNumberOfControlPoints ); RealType avg_p = 0.0; RealType totalWeight = 0.0; typename PointDataContainerType::Iterator ItIn = this->m_InputPointData->Begin(); typename PointDataContainerType::Iterator ItOut = this->m_OutputPointData->Begin(); while( ItIn != this->m_InputPointData->End() ) { this->m_InputPointData->InsertElement( ItIn.Index(), ItIn.Value() - ItOut.Value() ); if( this->GetDebug() ) { RealType weight = this->m_PointWeights->GetElement( ItIn.Index() ); avg_p += ( ItIn.Value() - ItOut.Value() ).GetNorm() * weight; totalWeight += weight; } ++ItIn; ++ItOut; } if( totalWeight > 0 ) { itkDebugMacro( "The average weighted difference norm of the point set is " << avg_p / totalWeight ); } /** * Set up multithread processing to handle generating the * control point lattice. */ typename ImageSource::ThreadStruct str2; str2.Filter = this; this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() ); this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str2 ); /** * Multithread the generation of the control point lattice. */ this->BeforeThreadedGenerateData(); this->GetMultiThreader()->SingleMethodExecute(); this->AfterThreadedGenerateData(); this->UpdatePointSet(); } if( this->m_DoMultilevel ) { ImageRegionIterator ItPsi( this->m_PsiLattice, this->m_PsiLattice->GetLargestPossibleRegion() ); ImageRegionIterator ItPhi( this->m_PhiLattice, this->m_PhiLattice->GetLargestPossibleRegion() ); for( ItPsi.GoToBegin(), ItPhi.GoToBegin(); !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi ) { ItPsi.Set( ItPhi.Get() + ItPsi.Get() ); } typedef ImageDuplicator ImageDuplicatorType; typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New(); Duplicator->SetInputImage( this->m_PsiLattice ); Duplicator->Update(); this->m_PhiLattice = Duplicator->GetOutput(); this->UpdatePointSet(); } if( this->m_GenerateOutputImage ) { //this->GenerateOutputImage(); this->GenerateOutputImageFast(); } } template void BSplineScatteredDataPointSetToImageFilter ::BeforeThreadedGenerateData() { this->m_DeltaLatticePerThread.resize( this->GetNumberOfThreads() ); this->m_OmegaLatticePerThread.resize( this->GetNumberOfThreads() ); } template void BSplineScatteredDataPointSetToImageFilter ::ThreadedGenerateData( const RegionType &itkNotUsed(region), int threadId ) { /** * Ignore the output region as we're only interested in dividing the * points among the threads. */ typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { size[i] = this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i]; } else { size[i] = this->m_CurrentNumberOfControlPoints[i]; } } this->m_OmegaLatticePerThread[threadId] = RealImageType::New(); this->m_OmegaLatticePerThread[threadId]->SetRegions( size ); this->m_OmegaLatticePerThread[threadId]->Allocate(); this->m_OmegaLatticePerThread[threadId]->FillBuffer( 0.0 ); this->m_DeltaLatticePerThread[threadId] = PointDataImageType::New(); this->m_DeltaLatticePerThread[threadId]->SetRegions( size ); this->m_DeltaLatticePerThread[threadId]->Allocate(); this->m_DeltaLatticePerThread[threadId]->FillBuffer( 0.0 ); for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); typename PointDataImageType::Pointer phi = PointDataImageType::New(); phi->SetRegions( size ); phi->Allocate(); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); ImageRegionIteratorWithIndex Itp( phi, phi->GetLargestPossibleRegion() ); vnl_vector p( ImageDimension ); vnl_vector r( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { r[i] = static_cast( this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i] ) / ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); } /** * Determine which points should be handled by this particular thread. */ int numberOfThreads = this->GetNumberOfThreads(); unsigned long numberOfPointsPerThread = static_cast( this->GetInput()->GetNumberOfPoints() / numberOfThreads ); unsigned int start = threadId * numberOfPointsPerThread; unsigned int end = start + numberOfPointsPerThread; if( threadId == this->GetNumberOfThreads() - 1 ) { end = this->GetInput()->GetNumberOfPoints(); } for( unsigned int n = start; n < end; n++ ) { PointType point; point.Fill( 0.0 ); this->GetInput()->GetPoint( n, &point ); for( unsigned int i = 0; i < ImageDimension; i++ ) { unsigned int totalNumberOfSpans = this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i]; p[i] = ( point[i] - this->m_Origin[i] ) * r[i]; if( vnl_math_abs( p[i] - static_cast( totalNumberOfSpans ) ) <= this->m_BSplineEpsilon ) { p[i] = static_cast( totalNumberOfSpans ) - this->m_BSplineEpsilon; } if( p[i] >= static_cast( totalNumberOfSpans ) ) { itkExceptionMacro( "The reparameterized point component " << p[i] << " is outside the corresponding parametric domain of [0, " << totalNumberOfSpans << "]." ); } } RealType w2_sum = 0.0; for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = static_cast( p[i] - static_cast( p[i] ) - idx[i] ) + 0.5*static_cast( this->m_SplineOrder[i] - 1 ); switch( this->m_SplineOrder[i] ) { case 0: { B *= this->m_KernelOrder0->Evaluate( u ); break; } case 1: { B *= this->m_KernelOrder1->Evaluate( u ); break; } case 2: { B *= this->m_KernelOrder2->Evaluate( u ); break; } case 3: { B *= this->m_KernelOrder3->Evaluate( u ); break; } default: { B *= this->m_Kernel[i]->Evaluate( u ); break; } } } Itw.Set( B ); w2_sum += B*B; } for( Itp.GoToBegin(), Itw.GoToBegin(); !Itp.IsAtEnd(); ++Itp, ++Itw ) { typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->m_DeltaLatticePerThread[threadId] ->GetLargestPossibleRegion().GetSize()[i]; } } RealType wc = this->m_PointWeights->GetElement( n ); RealType t = Itw.Get(); this->m_OmegaLatticePerThread[threadId]->SetPixel( idx, this->m_OmegaLatticePerThread[threadId]->GetPixel( idx ) + wc*t*t ); PointDataType data = this->m_InputPointData->GetElement( n ); data *= ( t / w2_sum ); Itp.Set( data ); data *= ( t * t * wc ); this->m_DeltaLatticePerThread[threadId]->SetPixel( idx, this->m_DeltaLatticePerThread[threadId]->GetPixel( idx ) + data ); } } } template void BSplineScatteredDataPointSetToImageFilter ::AfterThreadedGenerateData() { /** * Accumulate all the delta lattice and omega lattice values to * calculate the final phi lattice. */ ImageRegionIterator ItD( this->m_DeltaLatticePerThread[0], this->m_DeltaLatticePerThread[0]->GetLargestPossibleRegion() ); ImageRegionIterator ItO( this->m_OmegaLatticePerThread[0], this->m_OmegaLatticePerThread[0]->GetLargestPossibleRegion() ); for( int n = 1; n < this->GetNumberOfThreads(); n++ ) { ImageRegionIterator Itd( this->m_DeltaLatticePerThread[n], this->m_DeltaLatticePerThread[n]->GetLargestPossibleRegion() ); ImageRegionIterator Ito( this->m_OmegaLatticePerThread[n], this->m_OmegaLatticePerThread[n]->GetLargestPossibleRegion() ); ItD.GoToBegin(); ItO.GoToBegin(); Itd.GoToBegin(); Ito.GoToBegin(); while( !ItD.IsAtEnd() ) { ItD.Set( ItD.Get() + Itd.Get() ); ItO.Set( ItO.Get() + Ito.Get() ); ++ItD; ++ItO; ++Itd; ++Ito; } } /** * Generate the control point lattice */ typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { size[i] = this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i]; } else { size[i] = this->m_CurrentNumberOfControlPoints[i]; } } this->m_PhiLattice = PointDataImageType::New(); this->m_PhiLattice->SetRegions( size ); this->m_PhiLattice->Allocate(); this->m_PhiLattice->FillBuffer( 0.0 ); ImageRegionIterator ItP( this->m_PhiLattice, this->m_PhiLattice->GetLargestPossibleRegion() ); for( ItP.GoToBegin(), ItO.GoToBegin(), ItD.GoToBegin(); !ItP.IsAtEnd(); ++ItP, ++ItO, ++ItD ) { PointDataType P; P.Fill( 0 ); if( ItO.Get() != 0 ) { P = ItD.Get() / ItO.Get(); for( unsigned int i = 0; i < P.Size(); i++ ) { if( vnl_math_isnan( P[i] ) || vnl_math_isinf( P[i] ) ) { P[i] = 0; } } ItP.Set( P ); } } } template void BSplineScatteredDataPointSetToImageFilter ::RefineControlPointLattice() { ArrayType NumberOfNewControlPoints = this->m_CurrentNumberOfControlPoints; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CurrentLevel < this->m_NumberOfLevels[i] ) { NumberOfNewControlPoints[i] = 2*NumberOfNewControlPoints[i]-this->m_SplineOrder[i]; } } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { size[i] = NumberOfNewControlPoints[i] - this->m_SplineOrder[i]; } else { size[i] = NumberOfNewControlPoints[i]; } } typename PointDataImageType::Pointer RefinedLattice = PointDataImageType::New(); RefinedLattice->SetRegions( size ); RefinedLattice->Allocate(); PointDataType data; data.Fill( 0.0 ); RefinedLattice->FillBuffer( data ); typename PointDataImageType::IndexType idx; typename PointDataImageType::IndexType idx_Psi; typename PointDataImageType::IndexType tmp; typename PointDataImageType::IndexType tmp_Psi; typename PointDataImageType::IndexType off; typename PointDataImageType::IndexType off_Psi; typename PointDataImageType::RegionType::SizeType size_Psi; size.Fill( 2 ); unsigned int N = 1; for( unsigned int i = 0; i < ImageDimension; i++ ) { N *= ( this->m_SplineOrder[i] + 1 ); size_Psi[i] = this->m_SplineOrder[i] + 1; } ImageRegionIteratorWithIndex It( RefinedLattice, RefinedLattice->GetLargestPossibleRegion() ); It.GoToBegin(); while( !It.IsAtEnd() ) { idx = It.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CurrentLevel < this->m_NumberOfLevels[i] ) { idx_Psi[i] = static_cast( 0.5*idx[i] ); } else { idx_Psi[i] = static_cast( idx[i] ); } } for( unsigned int i = 0; i < ( 2 << (ImageDimension-1) ); i++ ) { PointDataType sum( 0.0 ); PointDataType val( 0.0 ); off = this->NumberToIndex( i, size ); bool OutOfBoundary = false; for( unsigned int j = 0; j < ImageDimension; j++ ) { tmp[j] = idx[j] + off[j]; if( tmp[j] >= static_cast( NumberOfNewControlPoints[j] ) && !this->m_CloseDimension[j] ) { OutOfBoundary = true; break; } if( this->m_CloseDimension[j] ) { tmp[j] %= RefinedLattice->GetLargestPossibleRegion().GetSize()[j]; } } if( OutOfBoundary ) { continue; } for( unsigned int j = 0; j < N; j++ ) { off_Psi = this->NumberToIndex( j, size_Psi ); bool IsOutOfBoundary = false; for( unsigned int k = 0; k < ImageDimension; k++ ) { tmp_Psi[k] = idx_Psi[k] + off_Psi[k]; if( tmp_Psi[k] >= static_cast( this->m_CurrentNumberOfControlPoints[k] ) && !this->m_CloseDimension[k] ) { IsOutOfBoundary = true; break; } if( this->m_CloseDimension[k] ) { tmp_Psi[k] %= this->m_PsiLattice->GetLargestPossibleRegion().GetSize()[k]; } } if( IsOutOfBoundary ) { continue; } RealType coeff = 1.0; for( unsigned int k = 0; k < ImageDimension; k++ ) { coeff *= this->m_RefinedLatticeCoefficients[k]( off[k], off_Psi[k] ); } val = this->m_PsiLattice->GetPixel( tmp_Psi ); val *= coeff; sum += val; } RefinedLattice->SetPixel( tmp, sum ); } bool IsEvenIndex = false; while( !IsEvenIndex && !It.IsAtEnd() ) { ++It; idx = It.GetIndex(); IsEvenIndex = true; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( idx[i] % 2 ) { IsEvenIndex = false; } } } } typedef ImageDuplicator ImageDuplicatorType; typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New(); Duplicator->SetInputImage( RefinedLattice ); Duplicator->Update(); this->m_PsiLattice = Duplicator->GetOutput(); } template void BSplineScatteredDataPointSetToImageFilter ::UpdatePointSet() { typename PointDataImageType::Pointer collapsedPhiLattices[ImageDimension+1]; for( unsigned int i = 0; i < ImageDimension; i++ ) { collapsedPhiLattices[i] = PointDataImageType::New(); collapsedPhiLattices[i]->SetOrigin( this->m_PhiLattice->GetOrigin() ); collapsedPhiLattices[i]->SetSpacing( this->m_PhiLattice->GetSpacing() ); collapsedPhiLattices[i]->SetDirection( this->m_PhiLattice->GetDirection() ); typename PointDataImageType::SizeType size; size.Fill( 1 ); for( unsigned int j = 0; j < i; j++ ) { size[j] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[j]; } collapsedPhiLattices[i]->SetRegions( size ); collapsedPhiLattices[i]->Allocate(); } collapsedPhiLattices[ImageDimension] = this->m_PhiLattice; ArrayType totalNumberOfSpans; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { totalNumberOfSpans[i] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]; } else { totalNumberOfSpans[i] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i]; } } FixedArray U; FixedArray currentU; currentU.Fill( -1 ); typename PointDataImageType::IndexType startPhiIndex = this->m_PhiLattice->GetLargestPossibleRegion().GetIndex(); typename PointDataContainerType::ConstIterator ItIn; ItIn = this->m_InputPointData->Begin(); while( ItIn != this->m_InputPointData->End() ) { PointType point; point.Fill( 0.0 ); this->GetInput()->GetPoint( ItIn.Index(), &point ); for( unsigned int i = 0; i < ImageDimension; i++ ) { U[i] = static_cast( totalNumberOfSpans[i] ) * static_cast( point[i] - this->m_Origin[i] ) / ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); if( vnl_math_abs( U[i] - static_cast( totalNumberOfSpans[i] ) ) <= this->m_BSplineEpsilon ) { U[i] = static_cast( totalNumberOfSpans[i] ) - this->m_BSplineEpsilon; } if( U[i] >= static_cast( totalNumberOfSpans[i] ) ) { itkExceptionMacro( "The collapse point component " << U[i] << " is outside the corresponding parametric domain of [0, " << totalNumberOfSpans[i] << "]." ); } } for( int i = ImageDimension-1; i >= 0; i-- ) { if( U[i] != currentU[i] ) { for( int j = i; j >= 0; j-- ) { this->CollapsePhiLattice( collapsedPhiLattices[j+1], collapsedPhiLattices[j], U[j], j ); currentU[j] = U[j]; } break; } } this->m_OutputPointData->InsertElement( ItIn.Index(), collapsedPhiLattices[0]->GetPixel( startPhiIndex ) ); ++ItIn; } } template void BSplineScatteredDataPointSetToImageFilter ::GenerateOutputImage() { ImageRegionIteratorWithIndex It( this->GetOutput(), this->GetOutput()->GetBufferedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PointDataType data; this->EvaluateAtIndex( It.GetIndex(), data ); It.Set( data ); } } template void BSplineScatteredDataPointSetToImageFilter ::GenerateOutputImageFast() { typename PointDataImageType::Pointer collapsedPhiLattices[ImageDimension+1]; for( unsigned int i = 0; i < ImageDimension; i++ ) { collapsedPhiLattices[i] = PointDataImageType::New(); collapsedPhiLattices[i]->SetOrigin( this->m_PhiLattice->GetOrigin() ); collapsedPhiLattices[i]->SetSpacing( this->m_PhiLattice->GetSpacing() ); collapsedPhiLattices[i]->SetDirection( this->m_PhiLattice->GetDirection() ); typename PointDataImageType::SizeType size; size.Fill( 1 ); for( unsigned int j = 0; j < i; j++ ) { size[j] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[j]; } collapsedPhiLattices[i]->SetRegions( size ); collapsedPhiLattices[i]->Allocate(); } collapsedPhiLattices[ImageDimension] = this->m_PhiLattice; ArrayType totalNumberOfSpans; for( unsigned int i = 0; i < ImageDimension; i++ ) { if( this->m_CloseDimension[i] ) { totalNumberOfSpans[i] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]; } else { totalNumberOfSpans[i] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i] - this->m_SplineOrder[i]; } } FixedArray U; FixedArray currentU; currentU.Fill( -1 ); typename ImageType::IndexType startIndex = this->GetOutput()->GetRequestedRegion().GetIndex(); typename PointDataImageType::IndexType startPhiIndex = this->m_PhiLattice->GetLargestPossibleRegion().GetIndex(); ImageRegionIteratorWithIndex It( this->GetOutput(), this->GetOutput()->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { typename ImageType::IndexType idx = It.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { U[i] = static_cast( totalNumberOfSpans[i] ) * static_cast( idx[i] - startIndex[i] ) / static_cast( this->m_Size[i] - 1 ); if( vnl_math_abs( U[i] - static_cast( totalNumberOfSpans[i] ) ) <= this->m_BSplineEpsilon ) { U[i] = static_cast( totalNumberOfSpans[i] ) - this->m_BSplineEpsilon; } if( U[i] >= static_cast( totalNumberOfSpans[i] ) ) { itkExceptionMacro( "The collapse point component " << U[i] << " is outside the corresponding parametric domain of [0, " << totalNumberOfSpans[i] << "]." ); } } for( int i = ImageDimension-1; i >= 0; i-- ) { if( U[i] != currentU[i] ) { for( int j = i; j >= 0; j-- ) { this->CollapsePhiLattice( collapsedPhiLattices[j+1], collapsedPhiLattices[j], U[j], j ); currentU[j] = U[j]; } break; } } It.Set( collapsedPhiLattices[0]->GetPixel( startPhiIndex ) ); } } template void BSplineScatteredDataPointSetToImageFilter ::CollapsePhiLattice( PointDataImageType *lattice, PointDataImageType *collapsedLattice, RealType u, unsigned int dimension ) { ImageRegionIteratorWithIndex It ( collapsedLattice, collapsedLattice->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PointDataType data; data.Fill( 0.0 ); typename PointDataImageType::IndexType idx = It.GetIndex(); for( unsigned int i = 0; i < this->m_SplineOrder[dimension] + 1; i++ ) { idx[dimension] = static_cast( u ) + i; RealType v = u - idx[dimension] + 0.5*static_cast( this->m_SplineOrder[dimension] - 1 ); RealType B; switch( this->m_SplineOrder[dimension] ) { case 0: { B = this->m_KernelOrder0->Evaluate( v ); break; } case 1: { B = this->m_KernelOrder1->Evaluate( v ); break; } case 2: { B = this->m_KernelOrder2->Evaluate( v ); break; } case 3: { B = this->m_KernelOrder3->Evaluate( v ); break; } default: { B = this->m_Kernel[dimension]->Evaluate( v ); break; } } if( this->m_CloseDimension[dimension] ) { idx[dimension] %= lattice->GetLargestPossibleRegion().GetSize()[dimension]; } data += ( lattice->GetPixel( idx ) * B ); } It.Set( data ); } } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateAtPoint( PointType point, PointDataType &data ) { for( unsigned int i = 0; i < ImageDimension; i++) { point[i] -= this->m_Origin[i]; point[i] /= ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); } this->Evaluate( point, data ); } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateAtIndex( IndexType idx, PointDataType &data ) { PointType point; this->GetOutput()->TransformIndexToPhysicalPoint( idx, point ); this->EvaluateAtPoint( point, data ); } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateAtContinuousIndex( ContinuousIndexType idx, PointDataType &data ) { PointType point; this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, point ); this->EvaluateAtPoint( point, data ); } template void BSplineScatteredDataPointSetToImageFilter ::Evaluate( PointType params, PointDataType &data ) { vnl_vector p( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( params[i] == NumericTraits::One ) { params[i] = NumericTraits::One - this->m_BSplineEpsilon; } if( params[i] < 0.0 || params[i] >= 1.0 ) { itkExceptionMacro( "The specified point " << params << " is outside the reparameterized domain [0, 1]." ); } p[i] = static_cast( params[i] ) * static_cast( this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i] ); } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w; w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); PointDataType val; data.Fill( 0.0 ); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = p[i] - static_cast( static_cast( p[i] ) + idx[i] ) + 0.5*static_cast( this->m_SplineOrder[i] - 1 ); switch( this->m_SplineOrder[i] ) { case 0: { B *= this->m_KernelOrder0->Evaluate( u ); break; } case 1: { B *= this->m_KernelOrder1->Evaluate( u ); break; } case 2: { B *= this->m_KernelOrder2->Evaluate( u ); break; } case 3: { B *= this->m_KernelOrder3->Evaluate( u ); break; } default: { B *= this->m_Kernel[i]->Evaluate( u ); break; } } } for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]; } } if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) ) { val = this->m_PhiLattice->GetPixel( idx ); val *= B; data += val; } } } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateGradientAtPoint( PointType point, GradientType &gradient ) { for( unsigned int i = 0; i < ImageDimension; i++) { point[i] -= this->m_Origin[i]; point[i] /= ( static_cast( this->m_Size[i] - 1 ) * this->m_Spacing[i] ); } this->EvaluateGradient( point, gradient ); } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateGradientAtIndex( IndexType idx, GradientType &gradient ) { PointType point; this->GetOutput()->TransformIndexToPhysicalPoint( idx, point ); this->EvaluateGradientAtPoint( point, gradient ); } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateGradientAtContinuousIndex( ContinuousIndexType idx, GradientType &gradient ) { PointType point; this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, gradient ); this->EvaluateGradientAtPoint( point, gradient ); } template void BSplineScatteredDataPointSetToImageFilter ::EvaluateGradient( PointType params, GradientType &gradient ) { vnl_vector p( ImageDimension ); for( unsigned int i = 0; i < ImageDimension; i++ ) { if( params[i] == NumericTraits::One ) { params[i] = NumericTraits::One - this->m_BSplineEpsilon; } if( params[i] < 0.0 || params[i] >= 1.0 ) { itkExceptionMacro( "The specified point " << params << " is outside the reparameterized domain [0, 1]." ); } p[i] = static_cast( params[i] ) * static_cast( this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i] ); } typename RealImageType::RegionType::SizeType size; for( unsigned int i = 0; i < ImageDimension; i++ ) { size[i] = this->m_SplineOrder[i] + 1; } typename RealImageType::Pointer w; w = RealImageType::New(); w->SetRegions( size ); w->Allocate(); PointDataType val; gradient.SetSize( val.Size(), ImageDimension ); gradient.Fill( 0.0 ); ImageRegionIteratorWithIndex Itw( w, w->GetLargestPossibleRegion() ); for( unsigned int j = 0; j < gradient.Cols(); j++ ) { for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw ) { RealType B = 1.0; typename RealImageType::IndexType idx = Itw.GetIndex(); for( unsigned int i = 0; i < ImageDimension; i++ ) { RealType u = p[i] - static_cast( static_cast( p[i] ) + idx[i] ) + 0.5*static_cast( this->m_SplineOrder[i] - 1 ); if( j == i ) { B *= this->m_Kernel[i]->EvaluateDerivative( u ); } else { B *= this->m_Kernel[i]->Evaluate( u ); } } for( unsigned int i = 0; i < ImageDimension; i++ ) { idx[i] += static_cast( p[i] ); if( this->m_CloseDimension[i] ) { idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]; } } if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) ) { val = this->m_PhiLattice->GetPixel( idx ); val *= B; for( unsigned int i = 0; i < val.Size(); i++ ) { gradient( i, j ) += val[i]; } } } } } /** * Standard "PrintSelf" method */ template void BSplineScatteredDataPointSetToImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); for( unsigned int i = 0; i < ImageDimension; i++ ) { this->m_Kernel[i]->Print( os, indent ); } os << indent << "B-spline order: " << this->m_SplineOrder << std::endl; os << indent << "Number Of control points: " << this->m_NumberOfControlPoints << std::endl; os << indent << "Close dimension: " << this->m_CloseDimension << std::endl; os << indent << "Number of levels " << this->m_NumberOfLevels << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkCoxDeBoorBSplineKernelFunction.h000066400000000000000000000135751147325206600252770ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCoxDeBoorBSplineKernelFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCoxDeBoorBSplineKernelFunction_h #define __itkCoxDeBoorBSplineKernelFunction_h #include "itkKernelFunction.h" #include "itkNumericTraits.h" #include "vnl/vnl_math.h" #include "vnl/vnl_real_polynomial.h" #include "vnl/vnl_matrix.h" namespace itk { /** \class CoxDeBoorBSplineKernelFunction * \brief BSpline kernel used for density estimation and nonparameteric * regression. * * This class enscapsulates BSpline kernel for * density estimation or nonparameteric regression. * See documentation for KernelFunction for more details. * * This class is templated over the spline order to cohere with * the previous incarnation of this class. One can change the * order during an instantiation's existence. Note that * other authors have defined the B-spline order as being the * degree of spline + 1. In the ITK context (e.g. in this * class), the spline order is equivalent to the degree of * the spline. * * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * http://hdl.handle.net/1926/140 * * * \sa KernelFunction * * \ingroup Functions */ template class ITK_EXPORT CoxDeBoorBSplineKernelFunction : public KernelFunction { public: /** Standard class typedefs. */ typedef CoxDeBoorBSplineKernelFunction Self; typedef KernelFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( CoxDeBoorBSplineKernelFunction, KernelFunction ); typedef double RealType; typedef vnl_vector VectorType; typedef vnl_real_polynomial PolynomialType; typedef vnl_matrix MatrixType; /** Get/Sets the Spline Order */ void SetSplineOrder( unsigned int ); itkGetMacro( SplineOrder, unsigned int ); /** Evaluate the function. */ inline RealType Evaluate( const RealType & u ) const { RealType absValue = vnl_math_abs( u ); unsigned int which; if( this->m_SplineOrder % 2 == 0 ) { which = static_cast( absValue+0.5 ); } else { which = static_cast( absValue ); } if( which < this->m_BSplineShapeFunctions.rows() ) { return PolynomialType( this->m_BSplineShapeFunctions.get_row( which ) ).evaluate( absValue ); } else { return NumericTraits::Zero; } } /** Evaluate the first derivative. */ inline RealType EvaluateDerivative( const double & u ) const { return this->EvaluateNthDerivative( u, 1 ); } /** Evaluate the Nth derivative. */ inline RealType EvaluateNthDerivative( const double & u, unsigned int n ) const { RealType absValue = vnl_math_abs( u ); unsigned int which; if( this->m_SplineOrder % 2 == 0 ) { which = static_cast( absValue+0.5 ); } else { which = static_cast( absValue ); } if( which < this->m_BSplineShapeFunctions.rows() ) { PolynomialType polynomial( this->m_BSplineShapeFunctions.get_row( which ) ); for( unsigned int i = 0; i < n; i++ ) { polynomial = polynomial.derivative(); } RealType der = polynomial.evaluate( absValue ); if( u < NumericTraits::Zero && n % 2 != 0 ) { return -der; } else { return der; } } else { return NumericTraits::Zero; } } /** * For a specific order, return the ceil( 0.5*(m_SplineOrder+1) ) * pieces of the single basis function centered at zero for positive * parametric values. */ MatrixType GetShapeFunctions() { return this->m_BSplineShapeFunctions; } /** * For a specific order, generate and return the (this->m_SplineOrder+1) * pieces of the different basis functions in the [0, 1] interval. */ MatrixType GetShapeFunctionsInZeroToOneInterval(); protected: CoxDeBoorBSplineKernelFunction(); ~CoxDeBoorBSplineKernelFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; private: CoxDeBoorBSplineKernelFunction( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented /** * For a specific order, generate the (this->m_SplineOrder+1) pieces of * the single basis function centered at zero. */ void GenerateBSplineShapeFunctions( unsigned int ); /** * Use the CoxDeBoor recursion relation to generate the piecewise * polynomials which compose the basis function. * See, for example, L. Piegl, L. Tiller, "The NURBS Book," * Springer 1997, p. 50. */ PolynomialType CoxDeBoor( unsigned short, VectorType, unsigned int, unsigned int ); MatrixType m_BSplineShapeFunctions; unsigned int m_SplineOrder; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkCoxDeBoorBSplineKernelFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkCoxDeBoorBSplineKernelFunction.txx000066400000000000000000000122501147325206600256600ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkCoxDeBoorBSplineKernelFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkCoxDeBoorBSplineKernelFunction_txx #define __itkCoxDeBoorBSplineKernelFunction_txx #include "itkCoxDeBoorBSplineKernelFunction.h" namespace itk { /** * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * http://hdl.handle.net/1926/140 * */ template CoxDeBoorBSplineKernelFunction ::CoxDeBoorBSplineKernelFunction() { this->m_SplineOrder = VSplineOrder; this->GenerateBSplineShapeFunctions( this->m_SplineOrder+1 ); } template CoxDeBoorBSplineKernelFunction ::~CoxDeBoorBSplineKernelFunction() { } template void CoxDeBoorBSplineKernelFunction ::SetSplineOrder( unsigned int order ) { if ( order != this->m_SplineOrder ) { this->m_SplineOrder = order; this->GenerateBSplineShapeFunctions( this->m_SplineOrder+1 ); this->Modified(); } } template void CoxDeBoorBSplineKernelFunction ::GenerateBSplineShapeFunctions( unsigned int order ) { unsigned int NumberOfPieces = static_cast( 0.5*( order+1 ) ); this->m_BSplineShapeFunctions.set_size( NumberOfPieces, order ); VectorType knots( order+1 ); for( unsigned int i = 0; i < knots.size(); i++) { knots[i] = -0.5*static_cast( order ) + static_cast( i ); } for ( unsigned int i = 0; i < NumberOfPieces; i++ ) { PolynomialType poly = this->CoxDeBoor(order, knots, 0, static_cast( 0.5*( order ) ) + i ); this->m_BSplineShapeFunctions.set_row( i, poly.coefficients() ); } } template typename CoxDeBoorBSplineKernelFunction::PolynomialType CoxDeBoorBSplineKernelFunction ::CoxDeBoor( unsigned short order, VectorType knots, unsigned int whichBasisFunction, unsigned int whichPiece ) { VectorType tmp(2); PolynomialType poly1(0.0), poly2(0.0); RealType den; unsigned short p = order-1; unsigned short i = whichBasisFunction; if( p == 0 && whichBasisFunction == whichPiece ) { PolynomialType poly(1.0); return poly; } // Term 1 den = knots(i+p)-knots(i); if ( den == NumericTraits::Zero ) { PolynomialType poly(0.0); poly1 = poly; } else { tmp(0) = 1.0; tmp(1) = -knots(i); tmp /= den; poly1 = PolynomialType(tmp) * this->CoxDeBoor( order-1, knots, i, whichPiece ); } // Term 2 den = knots(i+p+1)-knots(i+1); if ( den == NumericTraits::Zero ) { PolynomialType poly(0.0); poly2 = poly; } else { tmp(0) = -1.0; tmp(1) = knots(i+p+1); tmp /= den; poly2 = PolynomialType(tmp) * this->CoxDeBoor( order-1, knots, i+1, whichPiece ); } return ( poly1 + poly2 ); } template typename CoxDeBoorBSplineKernelFunction::MatrixType CoxDeBoorBSplineKernelFunction ::GetShapeFunctionsInZeroToOneInterval() { int order = this->m_SplineOrder+1; unsigned int NumberOfPieces = static_cast( order ); MatrixType ShapeFunctions( NumberOfPieces, order ); VectorType knots( 2*order ); for( unsigned int i = 0; i < knots.size(); i++ ) { knots[i] = -static_cast( this->m_SplineOrder ) + static_cast( i ); } for( unsigned int i = 0; i < NumberOfPieces; i++ ) { PolynomialType poly = this->CoxDeBoor( order, knots, i, order-1 ); ShapeFunctions.set_row( i, poly.coefficients() ); } return ShapeFunctions; } template void CoxDeBoorBSplineKernelFunction ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf( os, indent ); os << indent << "Spline Order: " << this->m_SplineOrder << std::endl; os << indent << "Piecewise Polynomial Pieces: " << std::endl; for ( unsigned int i = 0; i < this->m_BSplineShapeFunctions.rows(); i++ ) { RealType a = 0.0; RealType b = 0.0; os << indent << indent; PolynomialType( this->m_BSplineShapeFunctions.get_row( i ) ).print( os ); if( i == 0 ) { if( this->m_SplineOrder % 2 == 0 ) { b = 0.5; } else { b = 1.0; } } else { a = b; b += 1.0; } os << ", X \\in [" << a << ", " << b << "]" << std::endl; } } } // namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkDecomposeTensorFunction.h000066400000000000000000000065501147325206600241410ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDecomposeTensorFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDecomposeTensorFunction_h #define __itkDecomposeTensorFunction_h #if defined(_MSC_VER) #pragma warning ( disable : 4786 ) #endif #include "itkProcessObject.h" #include "itkVariableSizeMatrix.h" namespace itk { /** \class DecomposeTensorFunction * */ template > class ITK_EXPORT DecomposeTensorFunction : public ProcessObject { public: /** Standard class typedefs. */ typedef DecomposeTensorFunction Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro( DecomposeTensorFunction, ProcessObject ); /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef TInput InputMatrixType; typedef TOutput OutputMatrixType; /** Define the data type and the vector of data type used in calculations. */ typedef TRealType RealType; // Wrappers for vnl routines void EvaluateEigenDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSymmetricEigenDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateQRDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSVDDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateSVDEconomyDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateLeftPolarDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateRightPolarDecomposition( InputMatrixType&, OutputMatrixType&, OutputMatrixType& ); void EvaluateCholeskyDecomposition( InputMatrixType&, OutputMatrixType& ); RealType EvaluateDeterminant( InputMatrixType& ); DecomposeTensorFunction(); virtual ~DecomposeTensorFunction() {} protected: void PrintSelf ( std::ostream& os, Indent indent ) const; private: DecomposeTensorFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkDecomposeTensorFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkDecomposeTensorFunction.txx000066400000000000000000000217071147325206600245360ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkDecomposeTensorFunction.txx,v $ Language: C++ Date: $Date: 2009/05/11 13:55:21 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkDecomposeTensorFunction_txx #define __itkDecomposeTensorFunction_txx #include "itkDecomposeTensorFunction.h" #include "vnl/algo/vnl_cholesky.h" #include "vnl/algo/vnl_qr.h" #include "vnl/algo/vnl_real_eigensystem.h" #include "vnl/algo/vnl_svd.h" #include "vnl/algo/vnl_svd_economy.h" #include "vnl/algo/vnl_symmetric_eigensystem.h" #include "vnl/vnl_matrix.h" #include "vnl/vnl_matrix_fixed.h" #include "vnl/vnl_det.h" #include "vxl/vcl/vcl_complex.h" namespace itk { template DecomposeTensorFunction ::DecomposeTensorFunction() {} template void DecomposeTensorFunction ::EvaluateEigenDecomposition( InputMatrixType &M, OutputMatrixType &D, OutputMatrixType &V ) { unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); D.SetSize( RowDimensions, RowDimensions ); V.SetSize( RowDimensions, RowDimensions ); D.Fill( 0.0 ); vnl_matrix v( RowDimensions, ColumnDimensions ); for( unsigned int j = 0; j < ColumnDimensions; j++ ) { for( unsigned int i = 0; i < RowDimensions; i++ ) { v.put( i, j, M[i][j] ); } } vnl_real_eigensystem eig( v ); for( unsigned int j = 0; j < ColumnDimensions; j++ ) { for( unsigned int i = 0; i < RowDimensions; i++ ) { V[i][j] = static_cast( (eig.Vreal).get( i, j ) ); if( i == j ) { D[i][j] = static_cast( vcl_real( eig.D(j) ) ); } } } } template void DecomposeTensorFunction ::EvaluateSymmetricEigenDecomposition( InputMatrixType &M, OutputMatrixType &D, OutputMatrixType &V ) { // The resulting eigenvectors and values are sorted in increasing order // so V.column(0) is the eigenvector corresponding to the // smallest eigenvalue. unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); D.SetSize( RowDimensions, RowDimensions ); V.SetSize( RowDimensions, RowDimensions ); D.Fill( 0.0 ); vnl_symmetric_eigensystem eig( M.GetVnlMatrix() ); for( unsigned int j = 0; j < ColumnDimensions; j++ ) { for( unsigned int i = 0; i < RowDimensions; i++ ) { V[i][j] = (eig.V).get( i, j ); if( i == j ) { D[i][j] = eig.D(j); } } } } template void DecomposeTensorFunction ::EvaluateRightPolarDecomposition( InputMatrixType &M, OutputMatrixType &R, OutputMatrixType &S ) { OutputMatrixType U; OutputMatrixType W; OutputMatrixType V; this->EvaluateSVDDecomposition( M, U, W, V ); R = U * V.GetTranspose(); S = V * W * V.GetTranspose(); } template void DecomposeTensorFunction ::EvaluateLeftPolarDecomposition( InputMatrixType &M, OutputMatrixType &S, OutputMatrixType &R ) { OutputMatrixType U; OutputMatrixType W; OutputMatrixType V; this->EvaluateSVDDecomposition( M, U, W, V ); R = U * V.GetTranspose(); S = U * W * U.GetTranspose(); } template void DecomposeTensorFunction ::EvaluateQRDecomposition( InputMatrixType &M, OutputMatrixType &Q, OutputMatrixType &R ) { vnl_qr qr( M.GetVnlMatrix() ); Q.SetSize( qr.Q().rows(), qr.Q().cols() ); R.SetSize( qr.R().rows(), qr.R().cols() ); for( unsigned int i = 0; i < Q.Rows(); i++ ) { for( unsigned int j = 0; j < Q.Cols(); j++ ) { Q[i][j] = qr.Q()(i, j); } } for( unsigned int i = 0; i < R.Rows(); i++ ) { for( unsigned int j = 0; j < R.Cols(); j++ ) { R[i][j] = qr.R()(i, j); } } } template void DecomposeTensorFunction ::EvaluateSVDDecomposition( InputMatrixType &M, OutputMatrixType &U, OutputMatrixType &W, OutputMatrixType &V ) { unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); U.SetSize( RowDimensions, RowDimensions ); V.SetSize( ColumnDimensions, ColumnDimensions ); W.SetSize( RowDimensions, ColumnDimensions ); vnl_svd svd( M.GetVnlMatrix() ); for( unsigned int i = 0; i < RowDimensions; i++ ) { for( unsigned int j = 0; j < RowDimensions; j++ ) { U[i][j] = svd.U(i, j); } } for( unsigned int i = 0; i < ColumnDimensions; i++ ) { for( unsigned int j = 0; j < ColumnDimensions; j++ ) { V[i][j] = svd.V(i, j); } } W.Fill( 0.0 ); unsigned int minDimensions = ColumnDimensions; if( static_cast( RowDimensions ) < static_cast( ColumnDimensions ) ) { minDimensions = RowDimensions; } for( unsigned int i = 0; i < minDimensions; i++ ) { W[i][i] = svd.W(i, i); } } template void DecomposeTensorFunction ::EvaluateSVDEconomyDecomposition( InputMatrixType &M, OutputMatrixType &W, OutputMatrixType &V ) { /** * Same as SVD except the routine does not return U --- * allows for faster computation. */ unsigned int RowDimensions = M.Rows(); unsigned int ColumnDimensions = M.Cols(); V.SetSize( ColumnDimensions, ColumnDimensions ); W.SetSize( RowDimensions, ColumnDimensions ); vnl_svd_economy svd( M.GetVnlMatrix() ); for( unsigned int i = 0; i < ColumnDimensions; i++ ) { for( unsigned int j = 0; j < ColumnDimensions; j++ ) { V[i][j] = svd.V()(i, j); } } W.Fill( 0.0 ); unsigned int minDimensions = ColumnDimensions; if( static_cast( RowDimensions ) < static_cast( ColumnDimensions ) ) { minDimensions = RowDimensions; } for( unsigned int i = 0; i < minDimensions; i++ ) { W[i][i] = svd.lambdas()[i]; } } template void DecomposeTensorFunction ::EvaluateCholeskyDecomposition( InputMatrixType &M, OutputMatrixType &L ) { // Assumes symmetric tensor of type double vnl_matrix m( M.Rows(), M.Cols() ); for( unsigned int j = 0; j < M.Cols(); j++ ) { for( unsigned int i = 0; i < M.Rows(); i++ ) { m.put( i, j, M[i][j] ); } } vnl_cholesky cholesky( m, vnl_cholesky::quiet ); L.SetSize( M.Rows(), M.Cols() ); for( unsigned int i = 0; i < L.Rows(); i++ ) { for( unsigned int j = 0; j < L.Cols(); j++ ) { L[i][j] = cholesky.L_badly_named_method().get(i, j); } } } template typename DecomposeTensorFunction::RealType DecomposeTensorFunction ::EvaluateDeterminant( InputMatrixType &M ) { RealType det = 0.0; if( M.Rows() == M.Cols() && M.Rows() >= 2 && M.Rows() <= 4 ) { vnl_matrix_fixed m2; vnl_matrix_fixed m3; vnl_matrix_fixed m4; for( unsigned int i = 0; i < M.Rows(); i++ ) { for( unsigned int j = 0; j < M.Cols(); j++ ) { switch( M.Rows() ) { case 2: m2.put( i, j, M[i][j] ); break; case 3: m3.put( i, j, M[i][j] ); break; case 4: m4.put( i, j, M[i][j] ); break; } } } switch( M.Rows() ) { case 2: det = static_cast( vnl_det( m2 ) ); break; case 3: det = static_cast( vnl_det( m3 ) ); break; case 4: det = static_cast( vnl_det( m4 ) ); break; } } else { vnl_qr qr( M.GetVnlMatrix() ); det = static_cast( qr.determinant() ); } return det; } template void DecomposeTensorFunction ::PrintSelf( std::ostream& os, Indent indent ) const { } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkDeformationFieldFromMultiTransformFilter.h000066400000000000000000000122441147325206600274330ustar00rootroot00000000000000#ifndef ITKDEFORMATIONFIELDFROMMULTITRANSFORMFILTER_H_ #define ITKDEFORMATIONFIELDFROMMULTITRANSFORMFILTER_H_ #include "itkWarpImageMultiTransformFilter.h" namespace itk { template < class TOutputImage, class TDeformationField, class TTransform > class ITK_EXPORT DeformationFieldFromMultiTransformFilter : public WarpImageMultiTransformFilter< TOutputImage, TOutputImage, TDeformationField, TTransform> { public: /** Standard class typedefs. */ typedef TOutputImage TInputImage; typedef DeformationFieldFromMultiTransformFilter Self; typedef WarpImageMultiTransformFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro( DeformationFieldFromMultiTransformFilter, WarpImageMultiTransformFilter ); /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Inherit some types from the superclass. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImagePointer InputImagePointer; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImagePointer OutputImagePointer; typedef typename Superclass::InputImageConstPointer InputImageConstPointer; typedef typename OutputImageType::IndexType IndexType; typedef typename OutputImageType::SizeType SizeType; typedef typename OutputImageType::PixelType PixelType; typedef typename OutputImageType::SpacingType SpacingType; /** Determine the image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro(DeformationFieldDimension, unsigned int, TDeformationField::ImageDimension ); /** Deformation field typedef support. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType DisplacementType; typedef typename DisplacementType::ValueType DisplacementScalarValueType; typedef typename Superclass::PointType PointType; virtual void GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); } virtual void BeforeThreadedGenerateData() {}; virtual void AfterThreadedGenerateData() {}; virtual void GenerateOutputInformation(){ // call the superclass's implementation Superclass::GenerateOutputInformation(); }; protected: DeformationFieldFromMultiTransformFilter() : Superclass(){ this->SetNumberOfRequiredInputs( 0 ); const DisplacementScalarValueType kMaxDisp = itk::NumericTraits::max(); Superclass::m_EdgePaddingValue.Fill(kMaxDisp); } ~DeformationFieldFromMultiTransformFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const{ Superclass::PrintSelf(os, indent); }; /** WarpImageMultiTransformFilter is implemented as a multi-threaded filter. * As such, it needs to provide and implementation for * ThreadedGenerateData(). */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ){ OutputImagePointer outputPtr = this->GetOutput(); // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // iterator for the output image ImageRegionIteratorWithIndex outputIt(outputPtr, outputRegionForThread); // int cnt = 0; while( !outputIt.IsAtEnd() ) { PointType point1, point2; // get the output image index IndexType index = outputIt.GetIndex(); outputPtr->TransformIndexToPhysicalPoint( index, point1 ); bool isinside = MultiTransformPoint(point1, point2, Superclass::m_bFirstDeformNoInterp, index); if (isinside){ PixelType value; for(int ii=0; ii::max(); for(int ii=0; ii class ITK_EXPORT GaussianInterpolateImageFunction : public InterpolateImageFunction { public: /** Standard class typedefs. */ typedef GaussianInterpolateImageFunction Self; typedef InterpolateImageFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(GaussianInterpolateImageFunction, InterpolateImageFunction); /** Method for creation through the object factory. */ itkNewMacro(Self); /** OutputType typedef support. */ typedef typename Superclass::OutputType OutputType; /** InputImageType typedef support. */ typedef typename Superclass::InputImageType InputImageType; /** RealType typedef support. */ typedef typename Superclass::RealType RealType; /** Dimension underlying input image. */ itkStaticConstMacro(VDim, unsigned int,Superclass::ImageDimension); /** Index typedef support. */ typedef typename Superclass::IndexType IndexType; /** ContinuousIndex typedef support. */ typedef typename Superclass::ContinuousIndexType ContinuousIndexType; /** Compute internals */ virtual void ComputeBoundingBox() { const TInputImage *img = this->GetInputImage(); if(img == NULL) return; // Set the bounding box for(size_t d = 0; d < VDim; d++) { bb_start[d] = -0.5; bb_end[d] = img->GetBufferedRegion().GetSize()[d] - 0.5; nt[d] = (int)(bb_end[d] - bb_start[d] + 0.5); dx[d].set_size(nt[d]); gx[d].set_size(nt[d]); sf[d] = 1.0 / (sqrt(2.0) * sigma[d] / img->GetSpacing()[d]); cut[d] = sigma[d] * alpha / img->GetSpacing()[d]; } } /** Set input */ virtual void SetInputImage(const TInputImage *img) { // Call parent method Superclass::SetInputImage(img); this->ComputeBoundingBox(); } void SetParameters(double *sigma, double alpha) { // Set the parameters for(size_t d = 0; d < VDim; d++) this->sigma[d] = sigma[d]; this->alpha = alpha; // If the image already set, recompute this->ComputeBoundingBox(); } /** Evaluate the function at a ContinuousIndex position * * Returns the linearly interpolated image intensity at a * specified point position. No bounds checking is done. * The point is assume to lie within the image buffer. * * ImageFunction::IsInsideBuffer() can be used to check bounds before * calling the method. */ virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType & index ) const { return EvaluateAtContinuousIndex(index, NULL); } virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType &index, OutputType *grad) const { // The bound variables for x, y, z int i0[VDim], i1[VDim]; // Compute the ERF difference arrays for(size_t d = 0; d < VDim; d++) { double *pdx = const_cast(dx[d].data_block()); double *pgx = grad ? const_cast(gx[d].data_block()) : NULL; compute_erf_array(pdx, i0[d], i1[d], bb_start[d], nt[d], cut[d], index[d], sf[d], pgx); } // Get a pointer to the output value double sum_me = 0.0, sum_m = 0.0; vnl_vector_fixed dsum_me(0.0), dsum_m(0.0), dw; // Loop over the voxels in the region identified ImageRegion region; for(size_t d = 0; d < VDim; d++) { region.SetIndex(d, i0[d]); region.SetSize(d, i1[d] - i0[d]); } for( ImageRegionConstIteratorWithIndex it(this->GetInputImage(), region); !it.IsAtEnd(); ++it) { size_t j = it.GetIndex()[0]; double w = dx[0][j]; if(grad) { dw[0] = gx[0][j]; for(size_t d = 1; d < VDim; d++) dw[d] = dx[0][j]; } for(size_t d = 1; d < VDim; d++) { j = it.GetIndex()[d]; w *= dx[d][j]; if(grad) { for(size_t q = 0; q < VDim; q++) dw[q] *= (d == q) ? gx[d][j] : dx[d][j]; } } double V = it.Get(); sum_me += V * w; sum_m += w; if(grad) { for(size_t q = 0; q < VDim; q++) { dsum_me[q] += V * dw[q]; dsum_m[q] += dw[q]; } } } double rc = sum_me / sum_m; if(grad) { for(size_t q = 0; q < VDim; q++) { grad[q] = (dsum_me[q] - rc * dsum_m[q]) / sum_m; grad[q] /= -1.4142135623730951 * sigma[q]; } } // return sum_me / sum_m; return rc; } protected: GaussianInterpolateImageFunction() {} ~GaussianInterpolateImageFunction(){}; void PrintSelf(std::ostream& os, Indent indent) const { this->Superclass::PrintSelf(os,indent); } private: GaussianInterpolateImageFunction( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented /** Number of neighbors used in the interpolation */ static const unsigned long m_Neighbors; vnl_vector dx[VDim], gx[VDim]; double bb_start[VDim], bb_end[VDim], sf[VDim], cut[VDim]; int nt[VDim], stride[VDim]; double sigma[VDim], alpha; void compute_erf_array ( double *dx_erf, // The output array of erf(p+i+1) - erf(p+i) int &k0, int &k1, // The range of integration 0 <= k0 < k1 <= n double b, // Lower bound of the bounding box int n, // Size of the bounding box in steps double cut, // The distance at which to cut off double p, // the value p double sfac, // scaling factor 1 / (Sqrt[2] sigma) double *gx_erf = NULL // Output derivative/erf array (optional) ) const { // Determine the range of voxels along the line where to evaluate erf k0 = (int) floor(p - b - cut); k1 = (int) ceil(p - b + cut); if(k0 < 0) k0 = 0; if(k1 > n) k1 = n; // Start at the first voxel double t = (b - p + k0) * sfac; double e_last = vnl_erf(t); double g_last = gx_erf ? 1.128379167095513 * exp(- t * t) : 0.0; for(int i = k0; i < k1; i++) { t += sfac; double e_now = vnl_erf(t); dx_erf[i] = e_now - e_last; if(gx_erf) { double g_now = 1.128379167095513 * exp(- t * t); gx_erf[i] = g_now - g_last; g_last = g_now; } e_last = e_now; } } }; } // end namespace itk // Define instantiation macro for this template. #define ITK_TEMPLATE_GaussianInterpolateImageFunction(_, EXPORT, x, y) namespace itk { \ _(2(class EXPORT GaussianInterpolateImageFunction< ITK_TEMPLATE_2 x >)) \ namespace Templates { typedef GaussianInterpolateImageFunction< ITK_TEMPLATE_2 x > \ GaussianInterpolateImageFunction##y; } \ } #endif ants-1.9.2+svn680.dfsg/Utilities/itkGaussianProbabilityDensityFunction.h000066400000000000000000000140571147325206600263440ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGaussianProbabilityDensityFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGaussianProbabilityDensityFunction_h #define __itkGaussianProbabilityDensityFunction_h #include "itkArray.h" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkVariableSizeMatrix.h" #include "vnl/algo/vnl_matrix_inverse.h" #include "vnl/algo/vnl_determinant.h" #include "vnl/vnl_math.h" #include "itkMatrix.h" #include "itkDensityFunction.h" namespace itk{ namespace Statistics{ /** \class GaussianProbabilityDensityFunction * \brief GaussianProbabilityDensityFunction class represents Gaussian * Density Function. * * This class keeps parameter to define Gaussian Density Function and has * method to return the probability density of an instance (pattern). * If the all element of the covariance matrix is zero the "usual" density * calculations ignored. if the measurement vector to be evaluated is equal to * the mean, then the Evaluate method will return maximum value of * RealType and return 0 for others * */ template< class TMeasurementVector > class ITK_EXPORT GaussianProbabilityDensityFunction : public DensityFunction< TMeasurementVector > { public: /** Standard class typedefs */ typedef GaussianProbabilityDensityFunction Self; typedef DensityFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Strandard macros */ itkTypeMacro( GaussianProbabilityDensityFunction, DensityFunction ); itkNewMacro( Self ); /** Typedef alias for the measurement vectors */ typedef TMeasurementVector MeasurementVectorType; /** Length of each measurement vector */ typedef typename Superclass::MeasurementVectorSizeType MeasurementVectorSizeType; typedef double RealType; /** Type of the mean vector */ typedef Array MeanType; /** Type of the covariance matrix */ typedef VariableSizeMatrix MatrixType; typedef Array EigenValuesType; typedef VariableSizeMatrix EigenVectorsType; typedef typename Statistics ::MersenneTwisterRandomVariateGenerator GeneratorType; /** Sets the mean */ void SetMean( const MeanType mean ) { if( this->GetMeasurementVectorSize() ) { if( mean.Size() != this->GetMeasurementVectorSize() ) { itkExceptionMacro( "GaussianProbabilityDensityFunction::SetMean() " << "Size of measurement vectors in the sample must the same as " << "the size of the mean." ); } } else { this->SetMeasurementVectorSize( mean.Size() ); } if ( this->m_Mean != mean ) { this->m_Mean = mean; this->Modified(); } } /** Gets the mean */ const MeanType GetMean() const { return this->m_Mean; } /** Sets the covariance matrix. * Also, this function calculates inverse covariance and pre factor of * Gaussian Distribution to speed up GetProbability */ void SetCovariance( MatrixType cov ); /** Gets the covariance matrix */ MatrixType GetCovariance(); MatrixType GetInverseCovariance(); void SetSigma( RealType sigma ) { if ( this->m_Sigma != sigma ) { if ( sigma <= 0 ) { itkExceptionMacro( "Sigma must be greater than 0." ); } this->m_Sigma = sigma; this->m_UseAnisotropicCovariance = false; this->m_PreFactor = 1.0 / ( this->m_Sigma * vcl_pow( sqrt( 2.0 * vnl_math::pi ), RealType( this->GetMeasurementVectorSize() ) ) ); this->Modified(); } } const RealType GetSigma() const { return this->m_Sigma; } itkSetMacro( GenerateRandomSamples, bool ); itkGetConstMacro( GenerateRandomSamples, bool ); itkBooleanMacro( GenerateRandomSamples ); /** Gets the probability density of a measurement vector. */ RealType Evaluate( const MeasurementVectorType &measurement ) const; /** Gets the probability density of a measurement vector. */ MeasurementVectorType GenerateRandomSample(); protected: GaussianProbabilityDensityFunction( void ); virtual ~GaussianProbabilityDensityFunction( void ) {} void PrintSelf( std::ostream& os, Indent indent ) const; private: MeanType m_Mean; // mean MatrixType m_Covariance; // covariance matrix RealType m_Sigma; // sigma - use for isotropic gaussian bool m_GenerateRandomSamples; EigenValuesType m_EigenValues; EigenVectorsType m_EigenVectors; // if isotropic covariance is used, we don't want to make // unnecessary calculations. bool m_UseAnisotropicCovariance; // inverse covariance matrix which is automatically calculated // when covariace matrix is set. This speed up the GetProbability() MatrixType m_InverseCovariance; // pre_factor which is automatically calculated // when covariace matirx is set. This speeds up the GetProbability() RealType m_PreFactor; /** if the all element of the given covarinace is zero, then this * value set to true */ bool m_IsCovarianceZero; typename GeneratorType::Pointer m_Randomizer; }; } // end of namespace Statistics } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkGaussianProbabilityDensityFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkGaussianProbabilityDensityFunction.txx000066400000000000000000000200531147325206600267310ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGaussianProbabilityDensityFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGaussianProbabilityDensityFunction_txx #define __itkGaussianProbabilityDensityFunction_txx #include "itkGaussianProbabilityDensityFunction.h" #include "itkDecomposeTensorFunction.h" namespace itk { namespace Statistics { template GaussianProbabilityDensityFunction ::GaussianProbabilityDensityFunction() { this->m_Mean.SetSize( this->GetMeasurementVectorSize() ); this->m_Mean.Fill( 0.0 ); this->SetSigma( 1.0 ); this->m_UseAnisotropicCovariance = false; this->m_GenerateRandomSamples = false; this->m_Randomizer = GeneratorType::New(); this->m_Randomizer->SetSeed(); } template void GaussianProbabilityDensityFunction ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf(os,indent); os << indent << "Mean: "; os << this->m_Mean << std::endl; if( this->m_UseAnisotropicCovariance ) { os << indent << "Covariance: " << std::endl; os << this->m_Covariance.GetVnlMatrix(); os << indent << "InverseCovariance: " << std::endl; os << indent << this->m_InverseCovariance.GetVnlMatrix(); } else { os << indent << "Sigma: " << this->m_Sigma << std::endl; } os << indent << "Prefactor: " << this->m_PreFactor << std::endl; } template void GaussianProbabilityDensityFunction ::SetCovariance( MatrixType cov ) { if( this->m_Covariance != cov ) { // Sanity check if( cov.GetVnlMatrix().rows() != cov.GetVnlMatrix().cols() ) { itkExceptionMacro( << "Covariance matrix must be square" ); } if( this->GetMeasurementVectorSize() ) { if( cov.GetVnlMatrix().rows() != this->GetMeasurementVectorSize() ) { itkExceptionMacro( "Length of measurement vectors in the sample must be" << " the same as the size of the covariance." ); } } else { this->SetMeasurementVectorSize( cov.GetVnlMatrix().rows() ); } this->m_Covariance = cov; this->m_IsCovarianceZero = this->m_Covariance.GetVnlMatrix().is_zero(); if( !this->m_IsCovarianceZero ) { // allocate the memory for this->m_InverseCovariance matrix this->m_InverseCovariance.GetVnlMatrix() = vnl_matrix_inverse( this->m_Covariance.GetVnlMatrix() ); // the determinant of the covaraince matrix typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); RealType det = decomposer->EvaluateDeterminant( this->m_Covariance ); // calculate coefficient C of multivariate gaussian this->m_PreFactor = 1.0 / ( vcl_sqrt( det ) * vcl_pow( sqrt( 2.0 * vnl_math::pi ), RealType( this->GetMeasurementVectorSize() ) ) ); // calculate eigendecomposition if( this->m_GenerateRandomSamples ) { typename DecomposerType::OutputMatrixType eigValues; decomposer->EvaluateSymmetricEigenDecomposition( this->m_Covariance, eigValues, this->m_EigenVectors ); this->m_EigenValues.SetSize( this->GetMeasurementVectorSize() ); for( unsigned int i = 0; i < this->m_EigenValues.GetSize(); i++ ) { this->m_EigenValues[i] = eigValues[i][i]; } } } this->m_UseAnisotropicCovariance = true; this->Modified(); } } template typename GaussianProbabilityDensityFunction::MatrixType GaussianProbabilityDensityFunction ::GetCovariance() { if( this->m_UseAnisotropicCovariance ) { return this->m_Covariance; } else { MatrixType covariance( this->GetMeasurementVectorSize(), this->GetMeasurementVectorSize() ); covariance.SetIdentity(); covariance *= ( this->m_Sigma * this->m_Sigma ); return covariance; } } template typename GaussianProbabilityDensityFunction::MatrixType GaussianProbabilityDensityFunction ::GetInverseCovariance() { if( this->m_UseAnisotropicCovariance ) { return this->m_InverseCovariance; } else { MatrixType invCovariance( this->GetMeasurementVectorSize(), this->GetMeasurementVectorSize() ); invCovariance.SetIdentity(); invCovariance *= ( 1.0 / ( this->m_Sigma * this->m_Sigma ) ); return invCovariance; } } template inline typename GaussianProbabilityDensityFunction::RealType GaussianProbabilityDensityFunction ::Evaluate( const MeasurementVectorType &measurement ) const { RealType temp; const MeasurementVectorSizeType measurementVectorSize = this->GetMeasurementVectorSize(); MeanType tempVector; MeasurementVectorTraits::SetLength( tempVector, measurementVectorSize ); // Compute |y - mean | for( unsigned int i = 0; i < measurementVectorSize; i++ ) { tempVector[i] = measurement[i] - this->m_Mean[i]; } if( this->m_UseAnisotropicCovariance ) { MeanType tempVector2; MeasurementVectorTraits::SetLength( tempVector2, measurementVectorSize ); // Compute |y - mean | * inverse(cov) for( unsigned int i = 0; i < measurementVectorSize; i++ ) { temp = 0; for( unsigned int j = 0; j < measurementVectorSize; j++ ) { temp += tempVector[j] * this->m_InverseCovariance.GetVnlMatrix().get(j, i); } tempVector2[i] = temp; } // Compute |y - mean | * inverse(cov) * |y - mean|^T temp = 0; for( unsigned int i = 0; i < measurementVectorSize; i++ ) { temp += tempVector2[i] * tempVector[i]; } return this->m_PreFactor * vcl_exp( -0.5 * temp ); } else { temp = 0; for( unsigned int i = 0; i < measurementVectorSize; i++ ) { temp += ( tempVector[i] * tempVector[i] ); } return this->m_PreFactor * vcl_exp( -0.5 * temp / ( vnl_math_sqr( this->m_Sigma ) ) ); } } template typename GaussianProbabilityDensityFunction ::MeasurementVectorType GaussianProbabilityDensityFunction ::GenerateRandomSample() { MeasurementVectorType measurement; measurement.Fill( 0 ); if( this->m_GenerateRandomSamples ) { if( this->m_UseAnisotropicCovariance ) { MeanType sample( this->GetMeasurementVectorSize() ); for( unsigned int d = 0; d < this->GetMeasurementVectorSize(); d++ ) { sample[d] = this->m_Randomizer->GetNormalVariate( 0.0, this->m_EigenValues[d] ); } sample = this->m_EigenVectors * sample + this->m_Mean; for( unsigned int d = 0; d < this->GetMeasurementVectorSize(); d++ ) { measurement[d] = sample[d]; } } else { MeanType sample( this->GetMeasurementVectorSize() ); for( unsigned int d = 0; d < this->GetMeasurementVectorSize(); d++ ) { sample[d] = this->m_Randomizer->GetNormalVariate( 0.0, vnl_math_sqr( this->m_Sigma ) ); } sample += this->m_Mean; for( unsigned int d = 0; d < this->GetMeasurementVectorSize(); d++ ) { measurement[d] = sample[d]; } } } return measurement; } } // end namespace Statistics } // end of namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkGeneralToBSplineDeformationFieldFilter.h000066400000000000000000000072501147325206600267570ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGeneralToBSplineDeformationFieldFilter.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGeneralToBSplineDeformationFieldFilter_h #define __itkGeneralToBSplineDeformationFieldFilter_h #include "itkImageToImageFilter.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkPointSet.h" namespace itk { template class GeneralToBSplineDeformationFieldFilter : public ImageToImageFilter { public: /** Standard class typedefs. */ typedef GeneralToBSplineDeformationFieldFilter Self; typedef ImageToImageFilter< TInputImage, TOutputImage> Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Extract dimension from input and output image. */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); /** Convenient typedefs for simplifying declarations. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; typedef typename InputImageType::PixelType InputPixelType; typedef typename OutputImageType::PixelType OutputPixelType; typedef typename InputPixelType::ValueType InputPixelComponentType; typedef InputPixelType VectorType; typedef InputPixelComponentType RealType; typedef Image RealImageType; typedef PointSet PointSetType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::ArrayType ArrayType; // itkSetMacro( ConfidenceImage, RealImageType ); // itkGetConstMacro( ConfidenceImage, RealImageType ); itkSetMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( NumberOfControlPoints, ArrayType ); itkSetMacro( NumberOfLevels, unsigned int ); itkGetConstMacro( NumberOfLevels, unsigned int ); itkSetMacro( SplineOrder, unsigned int ); itkGetConstMacro( SplineOrder, unsigned int ); itkSetMacro( IgnorePixelValue, InputPixelType ); itkGetConstMacro( IgnorePixelValue, InputPixelType ); protected: GeneralToBSplineDeformationFieldFilter(); virtual ~GeneralToBSplineDeformationFieldFilter(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: // typename RealImageType::Pointer m_ConfidenceImage; InputPixelType m_IgnorePixelValue; unsigned int m_NumberOfLevels; unsigned int m_SplineOrder; ArrayType m_NumberOfControlPoints; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkGeneralToBSplineDeformationFieldFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkGeneralToBSplineDeformationFieldFilter.txx000066400000000000000000000070741147325206600273570ustar00rootroot00000000000000#ifndef __itkGeneralToBSplineDeformationFieldFilter_txx #define __itkGeneralToBSplineDeformationFieldFilter_txx #include "itkGeneralToBSplineDeformationFieldFilter.h" #include "itkBSplineControlPointImageFilter.h" #include "itkImageRegionConstIteratorWithIndex.h" namespace itk { template GeneralToBSplineDeformationFieldFilter ::GeneralToBSplineDeformationFieldFilter() { this->m_IgnorePixelValue.Fill( NumericTraits::max() ); this->m_SplineOrder = 3; this->m_NumberOfControlPoints.Fill( this->m_SplineOrder + 1 ); // this->m_ConfidenceImage = NULL; } template GeneralToBSplineDeformationFieldFilter ::~GeneralToBSplineDeformationFieldFilter() { } template void GeneralToBSplineDeformationFieldFilter ::GenerateData() { typename PointSetType::Pointer fieldPoints = PointSetType::New(); fieldPoints->Initialize(); // typename BSplineFilterType::WeightsContainerType confidenceValues; // confidenceValues->Initialize(); ImageRegionConstIteratorWithIndex It( this->GetInput(), this->GetInput()->GetRequestedRegion() ); itkDebugMacro( << "Extracting points from input deformation field. " ) unsigned int N = 0; for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { InputPixelType data = It.Get(); if ( data != this->m_IgnorePixelValue ) { typename PointSetType::PointType point; this->GetInput()->TransformIndexToPhysicalPoint( It.GetIndex(), point ); fieldPoints->SetPointData( N, data ); fieldPoints->SetPoint( N, point ); // if ( this->m_ConfidenceImage ) // { // confidenceValues->InsertElement // ( N, this->m_ConfidenceImage->GetPixel( It.GetIndex() ) ); // } N++; } } itkDebugMacro( "Calculating the B-spline deformation field. " ); typename OutputImageType::PointType origin; typename OutputImageType::SpacingType spacing; typename OutputImageType::SizeType size; for ( unsigned int i = 0; i < ImageDimension; i++ ) { origin[i] = this->GetInput( 0 )->GetOrigin()[i]; spacing[i] = this->GetInput( 0 )->GetSpacing()[i]; size[i] = this->GetInput( 0 )->GetRequestedRegion().GetSize()[i]; } typename BSplineFilterType::ArrayType close; close.Fill( false ); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetOrigin( origin ); bspliner->SetSpacing( spacing ); bspliner->SetSize( size ); bspliner->SetNumberOfLevels( this->m_NumberOfLevels ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetNumberOfControlPoints( this->m_NumberOfControlPoints ); bspliner->SetCloseDimension( close ); bspliner->SetInput( fieldPoints ); bspliner->SetGenerateOutputImage( true ); bspliner->Update(); this->SetNthOutput( 0, bspliner->GetOutput() ); } /** * Standard "PrintSelf" method */ template void GeneralToBSplineDeformationFieldFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Ignore pixel value: " << this->m_IgnorePixelValue << std::endl; os << indent << "Number of control points: " << this->m_NumberOfControlPoints << std::endl; os << indent << "Number of levels: " << this->m_NumberOfLevels << std::endl; os << indent << "Spline order: " << this->m_SplineOrder << std::endl; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkGridImageSource.h000066400000000000000000000120231147325206600223230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGridImageSource.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkGridImageSource_h #define __itkGridImageSource_h #include "itkImageSource.h" #include "itkFixedArray.h" #include "itkKernelFunction.h" #include "itkVectorContainer.h" #include "vnl/vnl_vector.h" namespace itk { /** \class GridImageSource * \brief Generate an n-dimensional image of a grid. * * GridImageSource generates an image of a grid. * * The output image may be of any dimension. * * \ingroup DataSources */ template class ITK_EXPORT GridImageSource : public ImageSource { public: /** Standard class typedefs. */ typedef GridImageSource Self; typedef ImageSource Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( GridImageSource, ImageSource ); /** Method for creation through the object factory. */ itkNewMacro(Self); typedef double RealType; /** Dimensionality of the output image */ itkStaticConstMacro( ImageDimension, unsigned int, TOutputImage::ImageDimension ); /** Typedef for the output image types. */ typedef TOutputImage ImageType; typedef typename TOutputImage::RegionType ImageRegionType; typedef typename TOutputImage::PixelType PixelType; typedef typename TOutputImage::SpacingType SpacingType; typedef typename TOutputImage::PointType OriginType; typedef typename TOutputImage::SizeType SizeType; /** Other convenient types. */ typedef FixedArray ArrayType; typedef FixedArray BoolArrayType; typedef vnl_vector PixelArrayType; typedef VectorContainer PixelArrayContainerType; /** Gets and sets for the output image. */ itkSetMacro( Spacing, SpacingType ); itkGetConstMacro( Spacing, SpacingType ); itkSetMacro( Origin, OriginType ); itkGetConstMacro( Origin, OriginType ); itkSetMacro( Size, SizeType ); itkGetConstMacro( Size, SizeType ); /** Gets and sets for grid parameters */ itkSetObjectMacro( KernelFunction, KernelFunction ); itkGetObjectMacro( KernelFunction, KernelFunction ); itkSetMacro( Sigma, ArrayType ); itkGetConstMacro( Sigma, ArrayType ); itkSetMacro( GridSpacing, ArrayType ); itkGetConstMacro( GridSpacing, ArrayType ); itkSetMacro( GridOffset, ArrayType ); itkGetConstMacro( GridOffset, ArrayType ); itkSetMacro( WhichDimensions, BoolArrayType ); itkGetConstMacro( WhichDimensions, BoolArrayType ); itkSetMacro( Scale, RealType ); itkGetConstMacro( Scale, RealType ); protected: GridImageSource(); ~GridImageSource(); void PrintSelf(std::ostream& os, Indent indent) const; virtual void ThreadedGenerateData(const ImageRegionType& outputRegionForThread, int threadId ); virtual void BeforeThreadedGenerateData(); virtual void GenerateOutputInformation(); private: GridImageSource(const GridImageSource&); //purposely not implemented void operator=(const GridImageSource&); //purposely not implemented /** Parameters for the output image. */ SizeType m_Size; //size SpacingType m_Spacing; //spacing OriginType m_Origin; //origin /** Parameters for the grid. */ /** Internal variable to speed up the calculation of pixel values */ typename PixelArrayContainerType::Pointer m_PixelArrays; /** The kernel function used to create the grid */ typename KernelFunction::Pointer m_KernelFunction; /** The standard deviation of the gaussians or width of the box functions. */ ArrayType m_Sigma; /** The grid spacing of the peaks. */ ArrayType m_GridSpacing; /** The grid spacing of the peaks. */ ArrayType m_GridOffset; /** Which dimensions which are gridded. */ BoolArrayType m_WhichDimensions; /** A scale factor multiplied by the true value of the grid. */ RealType m_Scale; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkGridImageSource.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkGridImageSource.txx000066400000000000000000000125541147325206600227300ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkGridImageSource.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkGridImageSource_txx #define _itkGridImageSource_txx #include "itkGaussianKernelFunction.h" #include "itkGridImageSource.h" #include "itkImageLinearIteratorWithIndex.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkProgressReporter.h" namespace itk { template GridImageSource ::GridImageSource() { this->m_Size.Fill( 64 ); this->m_Spacing.Fill( 1.0 ); this->m_Origin.Fill( 0.0 ); this->m_Sigma.Fill( 0.5 ); this->m_GridSpacing.Fill( 4.0 ); this->m_GridOffset.Fill( 0.0 ); this->m_WhichDimensions.Fill( true ); this->m_Scale = 255.0; this->m_KernelFunction = dynamic_cast( GaussianKernelFunction::New().GetPointer() ); } template GridImageSource ::~GridImageSource() { } template void GridImageSource ::BeforeThreadedGenerateData() { typename ImageType::Pointer output = this->GetOutput( 0 ); this->m_PixelArrays = PixelArrayContainerType::New(); m_PixelArrays->Initialize(); for ( unsigned int i = 0; i < ImageDimension; i++ ) { if ( this->m_GridOffset[i] > this->m_GridSpacing[i] ) { this->m_GridOffset[i] = this->m_GridSpacing[i]; } PixelArrayType pixels = m_PixelArrays->CreateElementAt( i ); pixels.set_size( this->m_Size[i] ); pixels.fill( 1 ); if ( this->m_WhichDimensions[i] ) { ImageLinearIteratorWithIndex It( output, output->GetRequestedRegion() ); It.SetDirection( i ); /** Add two extra functions in the front and one in the back to ensure coverage */ unsigned int numberOfGaussians = static_cast( ceil( this->m_Size[i]*this->m_Spacing[i]/this->m_GridSpacing[i] ) + 4 ); for ( It.GoToBegin(); !It.IsAtEndOfLine(); ++It ) { typename ImageType::IndexType index = It.GetIndex(); typename ImageType::PointType point; output->TransformIndexToPhysicalPoint( index, point ); RealType val = 0; for ( unsigned int j = 0; j < numberOfGaussians; j++ ) { RealType num = point[i] - static_cast( j-2 )*this->m_GridSpacing[i] - this->m_Origin[i] - this->m_GridOffset[i]; val += this->m_KernelFunction->Evaluate( num/this->m_Sigma[i] ); } pixels[index[i]] = val; } pixels = 1.0 - pixels/pixels.max_value(); } this->m_PixelArrays->SetElement( i, pixels ); } } template void GridImageSource ::ThreadedGenerateData( const ImageRegionType& outputRegionForThread, int threadId ) { // Support progress methods/callbacks ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() ); typename ImageType::Pointer output = this->GetOutput( 0 ); ImageRegionIteratorWithIndex It( output, outputRegionForThread ); for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { RealType val = 1.0; typename ImageType::IndexType index = It.GetIndex(); for ( unsigned int i = 0; i < ImageDimension; i++ ) { val *= this->m_PixelArrays->GetElement( i )[index[i]]; } It.Set( this->m_Scale * val ); progress.CompletedPixel(); } } template void GridImageSource ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "Output image information: " << std::endl; os << indent << " Size = " << this->m_Size << std::endl; os << indent << " Spacing = " << this->m_Spacing << std::endl; os << indent << " Origin = " << this->m_Origin << std::endl; os << indent << " Scale = " << this->m_Scale << std::endl; os << indent << "Grid information: " << std::endl; os << indent << " Kernel = " << this->m_KernelFunction << std::endl; os << indent << " Sigma = " << this->m_Sigma << std::endl; os << indent << " Grid spacing = " << this->m_GridSpacing << std::endl; os << indent << " Grid offset = " << this->m_GridOffset << std::endl; } //---------------------------------------------------------------------------- template void GridImageSource ::GenerateOutputInformation() { ImageType *output; output = this->GetOutput( 0 ); typename ImageType::IndexType index; index.Fill( 0 ); typename ImageType::RegionType largestPossibleRegion; largestPossibleRegion.SetSize( this->m_Size ); largestPossibleRegion.SetIndex( index ); output->SetLargestPossibleRegion( largestPossibleRegion ); output->SetSpacing( this->m_Spacing ); output->SetOrigin( this->m_Origin ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkLabelOverlapMeasuresImageFilter.h000066400000000000000000000151161147325206600255060ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabelOverlapMeasuresImageFilter.h,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabelOverlapMeasuresImageFilter_h #define __itkLabelOverlapMeasuresImageFilter_h #include "itkImageToImageFilter.h" #include "itkFastMutexLock.h" #include "itkNumericTraits.h" #include "itk_hash_map.h" namespace itk { /** \class LabelOverlapMeasuresImageFilter * \brief Computes overlap measures between the set same set of labels of * pixels of two images. Background is assumed to be 0. * * \sa LabelOverlapMeasuresImageFilter * * \ingroup MultiThreaded */ template class ITK_EXPORT LabelOverlapMeasuresImageFilter : public ImageToImageFilter { public: /** Standard Self typedef */ typedef LabelOverlapMeasuresImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Runtime information support. */ itkTypeMacro( LabelOverlapMeasuresImageFilter, ImageToImageFilter ); /** Image related typedefs. */ typedef TLabelImage LabelImageType; typedef typename TLabelImage::Pointer LabelImagePointer; typedef typename TLabelImage::ConstPointer LabelImageConstPointer; typedef typename TLabelImage::RegionType RegionType; typedef typename TLabelImage::SizeType SizeType; typedef typename TLabelImage::IndexType IndexType; typedef typename TLabelImage::PixelType LabelType; /** Type to use form computations. */ typedef typename NumericTraits::RealType RealType; /** \class LabelLabelOverlapMeasuress * \brief Metrics stored per label */ class LabelSetMeasures { public: // default constructor LabelSetMeasures() { m_Source = 0; m_Target = 0; m_Union = 0; m_Intersection = 0; m_SourceComplement = 0; m_TargetComplement = 0; } // added for completeness LabelSetMeasures& operator=( const LabelSetMeasures& l ) { m_Source = l.m_Source; m_Target = l.m_Target; m_Union = l.m_Union; m_Intersection = l.m_Intersection; m_SourceComplement = l.m_SourceComplement; m_TargetComplement = l.m_TargetComplement; } unsigned long m_Source; unsigned long m_Target; unsigned long m_Union; unsigned long m_Intersection; unsigned long m_SourceComplement; unsigned long m_TargetComplement; }; /** Type of the map used to store data per label */ typedef hash_map MapType; typedef typename MapType::iterator MapIterator; typedef typename MapType::const_iterator MapConstIterator; /** Image related typedefs. */ itkStaticConstMacro( ImageDimension, unsigned int, TLabelImage::ImageDimension ); /** Set the source image. */ void SetSourceImage( const LabelImageType * image ) { this->SetNthInput( 0, const_cast( image ) ); } /** Set the target image. */ void SetTargetImage( const LabelImageType * image ) { this->SetNthInput( 1, const_cast( image ) ); } /** Get the source image. */ const LabelImageType * GetSourceImage( void ) { return this->GetInput( 0 ); } /** Get the target image. */ const LabelImageType * GetTargetImage( void ) { return this->GetInput( 1 ); } /** Get the label set measures */ MapType GetLabelSetMeasures() { return this->m_LabelSetMeasures; } /** * tric overlap measures */ /** measures over all labels */ RealType GetTotalOverlap(); RealType GetUnionOverlap(); RealType GetMeanOverlap(); RealType GetVolumeSimilarity(); RealType GetFalseNegativeError(); RealType GetFalsePositiveError(); /** measures over individual labels */ RealType GetTargetOverlap( LabelType ); RealType GetUnionOverlap( LabelType ); RealType GetMeanOverlap( LabelType ); RealType GetVolumeSimilarity( LabelType ); RealType GetFalseNegativeError( LabelType ); RealType GetFalsePositiveError( LabelType ); /** alternative names */ RealType GetJaccardCoefficient() { return this->GetUnionOverlap(); } RealType GetJaccardCoefficient( LabelType label ) { return this->GetUnionOverlap( label ); } RealType GetDiceCoefficient() { return this->GetMeanOverlap(); } RealType GetDiceCoefficient( LabelType label ) { return this->GetMeanOverlap( label ); } #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro( Input1HasNumericTraitsCheck, ( Concept::HasNumericTraits ) ); /** End concept checking */ #endif protected: LabelOverlapMeasuresImageFilter(); ~LabelOverlapMeasuresImageFilter(){}; void PrintSelf( std::ostream& os, Indent indent ) const; /** * Pass the input through unmodified. Do this by setting the output to the * source this by setting the output to the source image in the * AllocateOutputs() method. */ void AllocateOutputs(); void BeforeThreadedGenerateData(); void AfterThreadedGenerateData(); /** Multi-thread version GenerateData. */ void ThreadedGenerateData( const RegionType&, int ); // Override since the filter needs all the data for the algorithm void GenerateInputRequestedRegion(); // Override since the filter produces all of its output void EnlargeOutputRequestedRegion( DataObject *data ); private: LabelOverlapMeasuresImageFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented std::vector m_LabelSetMeasuresPerThread; MapType m_LabelSetMeasures; SimpleFastMutexLock m_Mutex; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLabelOverlapMeasuresImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkLabelOverlapMeasuresImageFilter.txx000066400000000000000000000324211147325206600261000ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabelOverlapMeasuresImageFilter.txx,v $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkLabelOverlapMeasuresImageFilter_txx #define _itkLabelOverlapMeasuresImageFilter_txx #include "itkLabelOverlapMeasuresImageFilter.h" #include "itkImageRegionConstIterator.h" #include "itkProgressReporter.h" namespace itk { #if defined(__GNUC__) && (__GNUC__ <= 2) //NOTE: This class needs a mutex for gnu 2.95 /** Used for mutex locking */ #define LOCK_HASHMAP this->m_Mutex.Lock() #define UNLOCK_HASHMAP this->m_Mutex.Unlock() #else #define LOCK_HASHMAP #define UNLOCK_HASHMAP #endif template LabelOverlapMeasuresImageFilter ::LabelOverlapMeasuresImageFilter() { // this filter requires two input images this->SetNumberOfRequiredInputs( 2 ); } template void LabelOverlapMeasuresImageFilter ::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); if( this->GetSourceImage() ) { LabelImagePointer source = const_cast ( this->GetSourceImage() ); source->SetRequestedRegionToLargestPossibleRegion(); } if( this->GetTargetImage() ) { LabelImagePointer target = const_cast ( this->GetTargetImage() ); target->SetRequestedRegionToLargestPossibleRegion(); } } template void LabelOverlapMeasuresImageFilter ::EnlargeOutputRequestedRegion( DataObject *data ) { Superclass::EnlargeOutputRequestedRegion( data ); data->SetRequestedRegionToLargestPossibleRegion(); } template void LabelOverlapMeasuresImageFilter ::AllocateOutputs() { // Pass the source through as the output LabelImagePointer image = const_cast( this->GetSourceImage() ); this->SetNthOutput( 0, image ); // Nothing that needs to be allocated for the remaining outputs } template void LabelOverlapMeasuresImageFilter ::BeforeThreadedGenerateData() { int numberOfThreads = this->GetNumberOfThreads(); // Resize the thread temporaries this->m_LabelSetMeasuresPerThread.resize( numberOfThreads ); // Initialize the temporaries for( int n = 0; n < numberOfThreads; n++ ) { this->m_LabelSetMeasuresPerThread[n].clear(); } // Initialize the final map this->m_LabelSetMeasures.clear(); } template void LabelOverlapMeasuresImageFilter ::AfterThreadedGenerateData() { // Run through the map for each thread and accumulate the set measures. for( int n = 0; n < this->GetNumberOfThreads(); n++ ) { // iterate over the map for this thread for( MapConstIterator threadIt = this->m_LabelSetMeasuresPerThread[n].begin(); threadIt != this->m_LabelSetMeasuresPerThread[n].end(); ++threadIt ) { // does this label exist in the cumulative stucture yet? MapIterator mapIt = this->m_LabelSetMeasures.find( ( *threadIt ).first ); if( mapIt == this->m_LabelSetMeasures.end() ) { // create a new entry typedef typename MapType::value_type MapValueType; mapIt = this->m_LabelSetMeasures.insert( MapValueType( (*threadIt).first, LabelSetMeasures() ) ).first; } // accumulate the information from this thread (*mapIt).second.m_Source += (*threadIt).second.m_Source; (*mapIt).second.m_Target += (*threadIt).second.m_Target; (*mapIt).second.m_Union += (*threadIt).second.m_Union; (*mapIt).second.m_Intersection += (*threadIt).second.m_Intersection; (*mapIt).second.m_SourceComplement += (*threadIt).second.m_SourceComplement; (*mapIt).second.m_TargetComplement += (*threadIt).second.m_TargetComplement; } // end of thread map iterator loop } // end of thread loop } template void LabelOverlapMeasuresImageFilter ::ThreadedGenerateData( const RegionType& outputRegionForThread, int threadId ) { ImageRegionConstIterator ItS( this->GetSourceImage(), outputRegionForThread ); ImageRegionConstIterator ItT( this->GetTargetImage(), outputRegionForThread ); // support progress methods/callbacks ProgressReporter progress( this, threadId, 2*outputRegionForThread.GetNumberOfPixels() ); for( ItS.GoToBegin(), ItT.GoToBegin(); !ItS.IsAtEnd(); ++ItS, ++ItT ) { LabelType sourceLabel = ItS.Get(); LabelType targetLabel = ItT.Get(); // is the label already in this thread? MapIterator mapItS = this->m_LabelSetMeasuresPerThread[threadId].find( sourceLabel ); MapIterator mapItT = this->m_LabelSetMeasuresPerThread[threadId].find( targetLabel ); if( mapItS == this->m_LabelSetMeasuresPerThread[threadId].end() ) { // create a new label set measures object typedef typename MapType::value_type MapValueType; LOCK_HASHMAP; mapItS = this->m_LabelSetMeasuresPerThread[threadId].insert( MapValueType( sourceLabel, LabelSetMeasures() ) ).first; UNLOCK_HASHMAP; } if( mapItT == this->m_LabelSetMeasuresPerThread[threadId].end() ) { // create a new label set measures object typedef typename MapType::value_type MapValueType; LOCK_HASHMAP; mapItT = this->m_LabelSetMeasuresPerThread[threadId].insert( MapValueType( targetLabel, LabelSetMeasures() ) ).first; UNLOCK_HASHMAP; } (*mapItS).second.m_Source++; (*mapItT).second.m_Target++; if( sourceLabel == targetLabel ) { (*mapItS).second.m_Intersection++; (*mapItS).second.m_Union++; } else { (*mapItS).second.m_Union++; (*mapItT).second.m_Union++; (*mapItS).second.m_SourceComplement++; (*mapItT).second.m_TargetComplement++; } progress.CompletedPixel(); } } /** * measures */ template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetTotalOverlap() { RealType numerator = 0.0; RealType denominator = 0.0; for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) { // Do not include the background in the final value. if( (*mapIt).first == NumericTraits::Zero ) { continue; } numerator += static_cast( (*mapIt).second.m_Intersection ); denominator += static_cast( (*mapIt).second.m_Target ); } return ( numerator / denominator ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetTargetOverlap( LabelType label ) { MapIterator mapIt = this->m_LabelSetMeasures.find( label ); if( mapIt == this->m_LabelSetMeasures.end() ) { itkWarningMacro( "Label " << label << " not found." ); return 0.0; } RealType value = static_cast( (*mapIt).second.m_Intersection ) / static_cast( (*mapIt).second.m_Target ); return value; } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetUnionOverlap() { RealType numerator = 0.0; RealType denominator = 0.0; for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) { // Do not include the background in the final value. if( (*mapIt).first == NumericTraits::Zero ) { continue; } numerator += static_cast( (*mapIt).second.m_Intersection ); denominator += static_cast( (*mapIt).second.m_Union ); } return ( numerator / denominator ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetUnionOverlap( LabelType label ) { MapIterator mapIt = this->m_LabelSetMeasures.find( label ); if( mapIt == this->m_LabelSetMeasures.end() ) { itkWarningMacro( "Label " << label << " not found." ); return 0.0; } RealType value = static_cast( (*mapIt).second.m_Intersection ) / static_cast( (*mapIt).second.m_Union ); return value; } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetMeanOverlap() { RealType uo = this->GetUnionOverlap(); return ( 2.0 * uo / ( 1.0 + uo ) ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetMeanOverlap( LabelType label ) { RealType uo = this->GetUnionOverlap( label ); return ( 2.0 * uo / ( 1.0 + uo ) ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetVolumeSimilarity() { RealType numerator = 0.0; RealType denominator = 0.0; for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) { // Do not include the background in the final value. if( (*mapIt).first == NumericTraits::Zero ) { continue; } numerator += ( ( static_cast( (*mapIt).second.m_Source ) - static_cast( (*mapIt).second.m_Target ) ) ); denominator += ( ( static_cast( (*mapIt).second.m_Source ) + static_cast( (*mapIt).second.m_Target ) ) ); } return ( 2.0 * numerator / denominator ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetVolumeSimilarity( LabelType label ) { MapIterator mapIt = this->m_LabelSetMeasures.find( label ); if( mapIt == this->m_LabelSetMeasures.end() ) { itkWarningMacro( "Label " << label << " not found." ); return 0.0; } RealType value = 2.0 * ( static_cast( (*mapIt).second.m_Source ) - static_cast( (*mapIt).second.m_Target ) ) / ( static_cast( (*mapIt).second.m_Source ) + static_cast( (*mapIt).second.m_Target ) ); return value; } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetFalseNegativeError() { RealType numerator = 0.0; RealType denominator = 0.0; for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) { // Do not include the background in the final value. if( (*mapIt).first == NumericTraits::Zero ) { continue; } numerator += static_cast( (*mapIt).second.m_TargetComplement ); denominator += static_cast( (*mapIt).second.m_Target ); } return ( numerator / denominator ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetFalseNegativeError( LabelType label ) { MapIterator mapIt = this->m_LabelSetMeasures.find( label ); if( mapIt == this->m_LabelSetMeasures.end() ) { itkWarningMacro( "Label " << label << " not found." ); return 0.0; } RealType value = static_cast( (*mapIt).second.m_TargetComplement ) / static_cast( (*mapIt).second.m_Target ); return value; } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetFalsePositiveError() { RealType numerator = 0.0; RealType denominator = 0.0; for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) { // Do not include the background in the final value. if( (*mapIt).first == NumericTraits::Zero ) { continue; } numerator += static_cast( (*mapIt).second.m_SourceComplement ); denominator += static_cast( (*mapIt).second.m_Source ); } return ( numerator / denominator ); } template typename LabelOverlapMeasuresImageFilter::RealType LabelOverlapMeasuresImageFilter ::GetFalsePositiveError( LabelType label ) { MapIterator mapIt = this->m_LabelSetMeasures.find( label ); if( mapIt == this->m_LabelSetMeasures.end() ) { itkWarningMacro( "Label " << label << " not found." ); return 0.0; } RealType value = static_cast( (*mapIt).second.m_SourceComplement ) / static_cast( (*mapIt).second.m_Source ); return value; } template void LabelOverlapMeasuresImageFilter ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf( os, indent ); } }// end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkLabeledPointSetFileReader.h000066400000000000000000000106511147325206600242600ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabeledPointSetFileReader.h,v $ Language: C++ Date: $Date: 2009/03/04 23:10:58 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabeledPointSetFileReader_h #define __itkLabeledPointSetFileReader_h #include "itkMesh.h" #include "itkMeshSource.h" #include "itkArray.h" #include "itkImage.h" #include "itkVectorContainer.h" #include namespace itk { /** \class LabeledPointSetFileReader * \brief * Reads a file and creates an itkMesh. * */ template class LabeledPointSetFileReader : public MeshSource { public: /** Standard "Self" typedef. */ typedef LabeledPointSetFileReader Self; typedef MeshSource Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Extract dimension from the output mesh. */ itkStaticConstMacro( Dimension, unsigned int, TOutputMesh::PointType::Dimension ); /** Run-time type information (and related methods). */ itkTypeMacro( LabeledPointSetFileReader, MeshSource ); /** Hold on to the type information specified by the template parameters. */ typedef TOutputMesh OutputMeshType; typedef typename OutputMeshType::MeshTraits MeshTraits; typedef typename OutputMeshType::Superclass PointSetType; typedef typename OutputMeshType::PointType PointType; typedef typename MeshTraits::PixelType PixelType; typedef Array MultiComponentScalarType; typedef Array LineType; typedef VectorContainer MultiComponentScalarSetType; typedef VectorContainer LineSetType; typedef Image LabeledPointSetImageType; typedef std::vector LabelSetType; /** Set/Get the name of the file to be read. */ itkSetStringMacro( FileName ); itkGetStringMacro( FileName ); itkSetMacro( ExtractBoundaryPoints, bool ); itkGetMacro( ExtractBoundaryPoints, bool ); itkBooleanMacro( ExtractBoundaryPoints ); /** * Percentage of points selected randomnly */ itkSetClampMacro( RandomPercentage, double, 0.0, 1.0 ); itkGetConstMacro( RandomPercentage, double ); LabelSetType* GetLabelSet() { return &this->m_LabelSet; } unsigned int GetNumberOfLabels() { return this->m_LabelSet.size(); } MultiComponentScalarSetType* GetMultiComponentScalars() { return this->m_MultiComponentScalars.GetPointer(); } LineSetType* GetLines() { return this->m_Lines.GetPointer(); } protected: LabeledPointSetFileReader(); ~LabeledPointSetFileReader() {} void PrintSelf( std::ostream& os, Indent indent ) const; /** Reads the file */ void GenerateData(); bool m_ExtractBoundaryPoints; std::string m_FileName; double m_RandomPercentage; LabelSetType m_LabelSet; typename MultiComponentScalarSetType::Pointer m_MultiComponentScalars; typename LineSetType::Pointer m_Lines; private: LabeledPointSetFileReader( const Self& ); // purposely not implemented void operator=( const Self& ); // purposely not implemented void ReadPointsFromImageFile(); void ReadPointsFromAvantsFile(); void ReadVTKFile(); void ReadPointsFromVTKFile(); void ReadScalarsFromVTKFile(); void ReadLinesFromVTKFile(); }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLabeledPointSetFileReader.txx" #endif #endif //_itkLabeledPointSetFileReader_h ants-1.9.2+svn680.dfsg/Utilities/itkLabeledPointSetFileReader.txx000066400000000000000000000370501147325206600246560ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabeledPointSetFileReader.txx,v $ Language: C++ Date: $Date: 2009/03/13 19:48:16 $ Version: $Revision: 1.23 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabeledPointSetFileReader_txx #define __itkLabeledPointSetFileReader_txx #include "itkLabeledPointSetFileReader.h" #include "itkBinaryThresholdImageFilter.h" #include "itkImageFileReader.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkLabelContourImageFilter.h" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkByteSwapper.h" #include #include #include namespace itk { // // Constructor // template LabeledPointSetFileReader ::LabeledPointSetFileReader() { this->m_RandomPercentage = 1.0; this->m_ExtractBoundaryPoints = false; this->m_MultiComponentScalars = NULL; this->m_Lines = NULL; // // Create the output // typename TOutputMesh::Pointer output = TOutputMesh::New(); this->ProcessObject::SetNumberOfRequiredOutputs( 1 ); this->ProcessObject::SetNthOutput( 0, output.GetPointer() ); } template void LabeledPointSetFileReader ::GenerateData() { if( this->m_FileName == "" ) { itkExceptionMacro( "No input FileName" ); return; } // // Read input file // std::ifstream inputFile( m_FileName.c_str() ); if( !inputFile.is_open() ) { itkExceptionMacro("Unable to open file\n" "inputFilename= " << m_FileName ); return; } else { inputFile.close(); } /** * Get filename extension */ std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos+1, this->m_FileName.length()-1 ); if( extension == "txt" ) { this->ReadPointsFromAvantsFile(); } else if( extension == "vtk" ) { this->ReadVTKFile(); } else // try reading the file as an image { this->ReadPointsFromImageFile(); } if( this->m_RandomPercentage < 1.0 ) { typedef Statistics::MersenneTwisterRandomVariateGenerator GeneratorType; typename GeneratorType::Pointer generator = GeneratorType::New(); generator->SetSeed(); typename OutputMeshType::Pointer output = OutputMeshType::New(); output->Initialize(); if( this->GetOutput()->GetNumberOfPoints() > 0 ) { typename OutputMeshType::PointsContainerIterator It = this->GetOutput()->GetPoints()->Begin(); unsigned long count = 0; while( It != this->GetOutput()->GetPoints()->End() ) { if( generator->GetVariateWithClosedRange() <= this->m_RandomPercentage ) { output->SetPoint( count, It.Value() ); PixelType label; bool elementExists = this->GetOutput()->GetPointData() ->GetElementIfIndexExists( It.Index(), &label ); if( elementExists ) { output->SetPointData( count, label ); } count++; } ++It; } } this->GraftOutput( output ); } this->m_LabelSet.clear(); /** * If the number of points does not match the number of * point data, fill the point data with zeros */ if( !this->GetOutput()->GetPointData() || this->GetOutput()->GetPointData()->Size() != this->GetOutput()->GetPoints()->Size() ) { itkWarningMacro( "Number of points does not match number of labels. " << "Filling point data with label zero." ); typename OutputMeshType::PointsContainerIterator It = this->GetOutput()->GetPoints()->Begin(); while( It != this->GetOutput()->GetPoints()->End() ) { this->GetOutput()->SetPointData( It.Index(), NumericTraits::Zero ); ++It; } } if( this->GetOutput()->GetNumberOfPoints() > 0 ) { typename OutputMeshType::PointDataContainerIterator ItD = this->GetOutput()->GetPointData()->Begin(); while( ItD != this->GetOutput()->GetPointData()->End() ) { if( find( this->m_LabelSet.begin(), this->m_LabelSet.end(), ItD.Value() ) == this->m_LabelSet.end() ) { this->m_LabelSet.push_back( ItD.Value() ); } ++ItD; } } } template void LabeledPointSetFileReader ::ReadPointsFromAvantsFile() { typename OutputMeshType::Pointer outputMesh = this->GetOutput(); std::ifstream inputFile( m_FileName.c_str() ); unsigned long count = 0; while( !inputFile.eof() ) { PointType point; PixelType label; if( Dimension == 2 ) { float trash; inputFile >> point >> trash >> label; } else // Dimension == 3 { inputFile >> point >> label; } if( ( point.GetVectorFromOrigin() ).GetSquaredNorm() > 0.0 || label != 0 ) { outputMesh->SetPointData( count, label ); outputMesh->SetPoint( count, point ); count++; } } inputFile.close(); } template void LabeledPointSetFileReader ::ReadVTKFile() { this->ReadPointsFromVTKFile(); this->ReadScalarsFromVTKFile(); this->ReadLinesFromVTKFile(); } template void LabeledPointSetFileReader ::ReadPointsFromVTKFile() { typename OutputMeshType::Pointer outputMesh = this->GetOutput(); std::ifstream inputFile( this->m_FileName.c_str() ); std::string line; bool isBinary = false; while( !inputFile.eof() ) { std::getline( inputFile, line ); if (line.find( "BINARY" ) != std::string::npos ) { isBinary = true; } if( line.find( "POINTS" ) != std::string::npos ) { break; } } itkDebugMacro( "POINTS line" << line ); std::string pointLine( line, strlen( "POINTS " ), line.length() ); itkDebugMacro( "pointLine " << pointLine ); int numberOfPoints = -1; if( sscanf( pointLine.c_str(),"%d",&numberOfPoints ) != 1 ) { itkExceptionMacro( "ERROR: Failed to read numberOfPoints\n" " pointLine = " << pointLine ); return; } itkDebugMacro( "numberOfPoints = " << numberOfPoints ); if( numberOfPoints < 1 ) { itkExceptionMacro( "numberOfPoints < 1" << " numberOfPoints = " << numberOfPoints ); return; } outputMesh->GetPoints()->Reserve( numberOfPoints ); // // Load the point coordinates into the itk::Mesh // PointType point; if (isBinary) { itkDebugMacro( "Data is binary" ); float p; float * ptData = new float [ numberOfPoints*3 ]; inputFile.read( reinterpret_cast< char * >( ptData ), 3 * numberOfPoints * sizeof(p) ); ByteSwapper::SwapRangeFromSystemToBigEndian(ptData,numberOfPoints*3); for (long i = 0; i < numberOfPoints; i++ ) { for (long j = 0; j < Dimension; j++ ) { point[j] = ptData[i*3+j]; } outputMesh->SetPoint( i, point ); } delete [] ptData; } else { for( long i = 0; i < numberOfPoints; i++ ) { if( Dimension == 2 ) { float trash; inputFile >> point >> trash; } else // Dimension = 3 { inputFile >> point; } outputMesh->SetPoint( i, point ); } } inputFile.close(); } template void LabeledPointSetFileReader ::ReadScalarsFromVTKFile() { typename OutputMeshType::Pointer outputMesh = this->GetOutput(); std::ifstream inputFile( this->m_FileName.c_str() ); std::string line; bool isBinary = false; // // Find the labels associated with each pixel // while( !inputFile.eof() ) { std::getline( inputFile, line ); if (line.find( "BINARY" ) != std::string::npos ) { isBinary = true; } if( line.find( "SCALARS" ) != std::string::npos ) { break; } } if( inputFile.eof() ) { inputFile.close(); return; } std::string::size_type pos = line.rfind( " " ); std::string temp = std::string( line, pos+1, line.length()-1 ); unsigned int numberOfComponents = std::atoi( temp.c_str() ); std::getline( inputFile, line ); if (isBinary) { int numberOfValues = outputMesh->GetNumberOfPoints()*numberOfComponents; float p; int * scalarData = new int [ numberOfValues ]; inputFile.read( reinterpret_cast< char * >( scalarData ), numberOfComponents * sizeof(p) ); ByteSwapper::SwapRangeFromSystemToBigEndian(scalarData,numberOfValues); if( numberOfComponents == 1 ) { //PixelType label; for( unsigned long i = 0; i < outputMesh->GetNumberOfPoints(); i++ ) { outputMesh->SetPointData( i, scalarData[i] ); } // itkExceptionMacro( "Only single label components are readable" ); } else { this->m_MultiComponentScalars = MultiComponentScalarSetType::New(); this->m_MultiComponentScalars->Initialize(); for( unsigned long i = 0; i < outputMesh->GetNumberOfPoints(); i++ ) { MultiComponentScalarType scalar; scalar.SetSize( numberOfComponents ); for( unsigned int d = 0; d < numberOfComponents; d++ ) { scalar[d] = scalarData[i*numberOfComponents + d]; } this->m_MultiComponentScalars->InsertElement( i, scalar ); } } delete [] scalarData; } else { if( numberOfComponents == 1 ) { PixelType label; for( unsigned long i = 0; i < outputMesh->GetNumberOfPoints(); i++ ) { inputFile >> label; outputMesh->SetPointData( i, label ); } // itkExceptionMacro( "Only single label components are readable" ); } else { this->m_MultiComponentScalars = MultiComponentScalarSetType::New(); this->m_MultiComponentScalars->Initialize(); for( unsigned long i = 0; i < outputMesh->GetNumberOfPoints(); i++ ) { MultiComponentScalarType scalar; scalar.SetSize( numberOfComponents ); for( unsigned int d = 0; d < numberOfComponents; d++ ) { inputFile >> scalar[d]; } this->m_MultiComponentScalars->InsertElement( i, scalar ); } } } inputFile.close(); } template void LabeledPointSetFileReader ::ReadLinesFromVTKFile() { typename OutputMeshType::Pointer outputMesh = this->GetOutput(); std::ifstream inputFile( this->m_FileName.c_str() ); std::string line; bool isBinary = false; // // Find the labels associated with each pixel // while( !inputFile.eof() ) { std::getline( inputFile, line ); if (line.find( "BINARY" ) != std::string::npos ) { isBinary = true; } if( line.find( "LINES" ) != std::string::npos ) { break; } } if( inputFile.eof() ) { inputFile.close(); return; } std::string::size_type pos = line.rfind( " " ); std::string temp = std::string( line, 6, pos-1 ); unsigned int numberOfLines = std::atoi( temp.c_str() ); temp = std::string(line, pos, line.length()-1 ); unsigned int numberOfValues = std::atoi( temp.c_str() ); this->m_Lines = LineSetType::New(); this->m_Lines->Initialize(); if (isBinary) { int p; int * lineData = new int [ numberOfValues ]; inputFile.read( reinterpret_cast< char * >( lineData ), numberOfValues * sizeof(p) ); ByteSwapper::SwapRangeFromSystemToBigEndian(lineData,numberOfValues); unsigned long valueId = 0; unsigned long lineId = 0; while (valueId < numberOfValues) { int lineLength = lineData[valueId]; ++valueId; LineType polyLine; polyLine.SetSize( lineLength ); for (long i = 0; i < lineLength; i++) { polyLine[i] = lineData[valueId]; ++valueId; } this->m_Lines->InsertElement( lineId, polyLine ); ++lineId; } delete [] lineData; } else { for( unsigned int i = 0; i < numberOfLines; i++ ) { LineType line; unsigned int numberOfPoints; inputFile >> numberOfPoints; line.SetSize( numberOfPoints ); for( unsigned int d = 0; d < numberOfPoints; d++ ) { inputFile >> line[d]; } this->m_Lines->InsertElement( i, line ); } } inputFile.close(); } template void LabeledPointSetFileReader ::ReadPointsFromImageFile() { typename OutputMeshType::Pointer outputMesh = this->GetOutput(); typedef ImageFileReader ImageReaderType; typename ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName( this->m_FileName.c_str() ); imageReader->Update(); if( !this->m_ExtractBoundaryPoints ) { ImageRegionIteratorWithIndex It( imageReader->GetOutput(), imageReader->GetOutput()->GetLargestPossibleRegion() ); unsigned long count = 0; for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( label != NumericTraits::Zero ) { typename LabeledPointSetImageType::PointType imagePoint; imageReader->GetOutput()->TransformIndexToPhysicalPoint( It.GetIndex(), imagePoint ); PointType point; point.CastFrom( imagePoint ); outputMesh->SetPoint( count, point ); outputMesh->SetPointData( count, label ); count++; } } } else { typedef LabelContourImageFilter ContourFilterType; typename ContourFilterType::Pointer contourFilter = ContourFilterType::New(); contourFilter->SetInput( imageReader->GetOutput() ); contourFilter->SetFullyConnected( true ); contourFilter->SetBackgroundValue( 0 ); contourFilter->Update(); this->m_LabelSet.clear(); ImageRegionIteratorWithIndex It ( contourFilter->GetOutput(), contourFilter->GetOutput()->GetLargestPossibleRegion() ); unsigned long count = 0; for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { PixelType label = It.Get(); if( It.Get() > 0 ) { typename LabeledPointSetImageType::PointType imagePoint; contourFilter->GetOutput()->TransformIndexToPhysicalPoint( It.GetIndex(), imagePoint ); PointType point; point.CastFrom( imagePoint ); outputMesh->SetPoint( count, point ); outputMesh->SetPointData( count, It.Get() ); count++; if( find( this->m_LabelSet.begin(), this->m_LabelSet.end(), label ) == this->m_LabelSet.end() ) { this->m_LabelSet.push_back( label ); } } } } } template void LabeledPointSetFileReader ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf(os,indent); os << indent << "FileName: " << this->m_FileName << std::endl; os << indent << "RandomPercentage: " << this->m_RandomPercentage << std::endl; } } //end of namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkLabeledPointSetFileWriter.h000066400000000000000000000117311147325206600243320ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabeledPointSetFileWriter.h,v $ Language: C++ Date: $Date: 2009/03/04 23:10:58 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabeledPointSetFileWriter_h #define __itkLabeledPointSetFileWriter_h #include "itkMesh.h" #include "itkArray.h" #include "itkImage.h" #include "itkVectorContainer.h" namespace itk { /** \class LabeledPointSetFileWriter * \brief * Writes an itkMesh to a file in various txt file formats. * */ template class LabeledPointSetFileWriter : public Object { public: /** Standard "Self" typedef. */ typedef LabeledPointSetFileWriter Self; typedef Object Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory */ itkNewMacro( Self ); /** Write the Input mesh to the Output file. * Use either Update() or Write(). */ void Update( void ); void Write( void ); /** Extract dimension from the output mesh. */ itkStaticConstMacro( Dimension, unsigned int, TInputMesh::PointType::Dimension ); /** Run-time type information (and related methods). */ itkTypeMacro( LabeledPointSetFileWriter, Object ); /** Hold on to the type information specified by the template parameters. */ typedef TInputMesh InputMeshType; typedef typename TInputMesh::Pointer InputMeshPointer; typedef typename InputMeshType::MeshTraits MeshTraits; typedef typename InputMeshType::Superclass PointSetType; typedef typename InputMeshType::PointType PointType; typedef typename MeshTraits::PixelType PixelType; typedef Array MultiComponentScalarType; typedef Array LineType; typedef VectorContainer MultiComponentScalarSetType; typedef VectorContainer LineSetType; typedef Image LabeledPointSetImageType; typedef typename LabeledPointSetImageType::SizeType ImageSizeType; typedef typename LabeledPointSetImageType::PointType ImageOriginType; typedef typename LabeledPointSetImageType::SpacingType ImageSpacingType; typedef typename LabeledPointSetImageType::DirectionType ImageDirectionType; /** Set the Input */ void SetInput( InputMeshType * input ); /** Set/Get the name of the file where data are written. */ itkSetStringMacro( FileName ); itkGetStringMacro( FileName ); /** Specify other attributes */ itkSetMacro( Lines, typename LineSetType::Pointer ); itkSetMacro( MultiComponentScalars, typename MultiComponentScalarSetType::Pointer ); /** Specify image attributes if output is an image. */ itkSetMacro( ImageSize, ImageSizeType ); itkGetConstMacro( ImageSize, ImageSizeType ); itkSetMacro( ImageOrigin, ImageOriginType ); itkGetConstMacro( ImageOrigin, ImageOriginType ); itkSetMacro( ImageSpacing, ImageSpacingType ); itkGetConstMacro( ImageSpacing, ImageSpacingType ); itkSetMacro( ImageDirection, ImageDirectionType ); itkGetConstMacro( ImageDirection, ImageDirectionType ); protected: LabeledPointSetFileWriter(); virtual ~LabeledPointSetFileWriter(); virtual void GenerateData(); std::string m_FileName; InputMeshPointer m_Input; typename MultiComponentScalarSetType::Pointer m_MultiComponentScalars; typename LineSetType::Pointer m_Lines; /** * If output is an image type, the attributes must be specified. */ ImageSizeType m_ImageSize; ImageSpacingType m_ImageSpacing; ImageOriginType m_ImageOrigin; ImageDirectionType m_ImageDirection; void PrintSelf(std::ostream& os, Indent indent) const; private: LabeledPointSetFileWriter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented void WritePointsToAvantsFile(); void WritePointsToImageFile(); void WriteVTKFile(); void WritePointsToVTKFile(); void WriteScalarsToVTKFile(); void WriteLinesToVTKFile(); }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkLabeledPointSetFileWriter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkLabeledPointSetFileWriter.txx000066400000000000000000000243671147325206600247370ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkLabeledPointSetFileWriter.txx,v $ Language: C++ Date: $Date: 2009/03/04 23:10:58 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabeledPointSetFileWriter_txx #define __itkLabeledPointSetFileWriter_txx #include "itkLabeledPointSetFileWriter.h" #include "itkImageFileWriter.h" #include namespace itk { // // Constructor // template LabeledPointSetFileWriter ::LabeledPointSetFileWriter() { this->m_Input = NULL; this->m_FileName = ""; this->m_MultiComponentScalars = NULL; this->m_Lines = NULL; this->m_ImageSize.Fill( 0 ); } // // Destructor // template LabeledPointSetFileWriter ::~LabeledPointSetFileWriter() { } // // Set the input mesh // template void LabeledPointSetFileWriter ::SetInput(InputMeshType * input) { this->m_Input = input; } // // Write the input mesh to the output file // template void LabeledPointSetFileWriter ::Update() { this->GenerateData(); } // // Write the input mesh to the output file // template void LabeledPointSetFileWriter ::Write() { this->GenerateData(); } template void LabeledPointSetFileWriter ::GenerateData() { if( this->m_FileName == "" ) { itkExceptionMacro( "No FileName" ); return; } if( this->m_ImageSize[0] == 0 ) { this->m_ImageSize.Fill( 100 ); this->m_ImageOrigin.CastFrom( this->m_Input->GetBoundingBox()->GetMinimum() ); for( unsigned int d = 0; d < Dimension; d++ ) { this->m_ImageSpacing[d] = ( this->m_Input->GetBoundingBox()->GetMaximum()[d] - this->m_Input->GetBoundingBox()->GetMinimum()[d] ) / static_cast( this->m_ImageSize[d] + 1 ); } this->m_ImageDirection.SetIdentity(); } // // Read output file // std::ofstream outputFile( m_FileName.c_str() ); if( !outputFile.is_open() ) { itkExceptionMacro( "Unable to open file\n" "outputFilename= " << m_FileName ); return; } else { outputFile.close(); } /** * Get filename extension */ std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos+1, this->m_FileName.length()-1 ); if( extension == "txt" ) { this->WritePointsToAvantsFile(); } else if( extension == "vtk" ) { this->WriteVTKFile(); } else { try { this->WritePointsToImageFile(); } catch(...) { itkExceptionMacro( "Unknown extension: " << extension ); } } } template void LabeledPointSetFileWriter ::WriteVTKFile() { this->WritePointsToVTKFile(); this->WriteLinesToVTKFile(); this->WriteScalarsToVTKFile(); } template void LabeledPointSetFileWriter ::WritePointsToVTKFile() { // // Write to output file // std::ofstream outputFile( this->m_FileName.c_str() ); outputFile << "# vtk DataFile Version 2.0" << std::endl; outputFile << "File written by itkLabeledPointSetFileWriter" << std::endl; outputFile << "ASCII" << std::endl; outputFile << "DATASET POLYDATA" << std::endl; // POINTS go first unsigned int numberOfPoints = this->m_Input->GetNumberOfPoints(); outputFile << "POINTS " << numberOfPoints << " float" << std::endl; typename InputMeshType::PointsContainerIterator pointIterator = this->m_Input->GetPoints()->Begin(); typename InputMeshType::PointsContainerIterator pointEnd = this->m_Input->GetPoints()->End(); while( pointIterator != pointEnd ) { PointType point = pointIterator.Value(); outputFile << point[0] << " " << point[1]; if( Dimension == 2 ) { outputFile << " 0 " << std::endl; } else if( Dimension == 3 ) { outputFile << " " << point[2] << " " << std::endl; } pointIterator++; } outputFile.close(); } template void LabeledPointSetFileWriter ::WriteScalarsToVTKFile() { // // Write to output file // std::ofstream outputFile( this->m_FileName.c_str(), std::ios::app ); // No point data conditions if (!this->m_Input->GetPointData()) return; if (this->m_Input->GetPointData()->Size() == 0) return; unsigned int numberOfPoints = this->m_Input->GetNumberOfPoints(); outputFile << std::endl; outputFile << "POINT_DATA " << numberOfPoints << std::endl; std::string type = std::string( "float" ); if( !this->m_MultiComponentScalars ) { outputFile << "SCALARS pointLabels " << type << " 1" << std::endl; outputFile << "LOOKUP_TABLE default" << std::endl; typename InputMeshType::PointDataContainerIterator pointDataIterator = this->m_Input->GetPointData()->Begin(); typename InputMeshType::PointDataContainerIterator pointDataEnd = this->m_Input->GetPointData()->End(); while( pointDataIterator != pointDataEnd ) { outputFile << pointDataIterator.Value() << " "; pointDataIterator++; } outputFile << std::endl; } else { MultiComponentScalarType scalar = this->m_MultiComponentScalars->GetElement( 0 ); unsigned int numberOfComponents = scalar.GetSize(); outputFile << "SCALARS scalars " << type << numberOfComponents << std::endl; outputFile << "LOOKUP_TABLE default" << std::endl; typename MultiComponentScalarSetType::Iterator It = this->m_MultiComponentScalars->Begin(); typename MultiComponentScalarSetType::Iterator ItEnd = this->m_MultiComponentScalars->End(); while( It != ItEnd ) { outputFile << It.Value() << " "; It++; } outputFile << std::endl; } outputFile.close(); } template void LabeledPointSetFileWriter ::WriteLinesToVTKFile() { if( this->m_Lines ) { std::ofstream outputFile( this->m_FileName.c_str(), std::ios::app ); unsigned int numberOfLines = this->m_Lines->Size(); unsigned int totalSize = 0; typename LineSetType::Iterator It = this->m_Lines->Begin(); typename LineSetType::Iterator ItEnd = this->m_Lines->End(); while( It != ItEnd ) { totalSize += ( It.Value() ).Size(); totalSize++; It++; } outputFile << "LINES " << numberOfLines << " " << totalSize << std::endl; It = this->m_Lines->Begin(); while( It != ItEnd ) { unsigned int numberOfPoints = ( It.Value() ).Size(); outputFile << numberOfPoints << " "; for( unsigned int d = 0; d < numberOfPoints; d++ ) { outputFile << ( It.Value() )[d] << " "; } outputFile << std::endl; ++It; } outputFile << std::endl; outputFile.close(); } } template void LabeledPointSetFileWriter ::WritePointsToAvantsFile() { // // Write to output file // std::ofstream outputFile( this->m_FileName.c_str() ); outputFile << "0 0 0 0" << std::endl; if( this->m_Input->GetNumberOfPoints() > 0 ) { typename InputMeshType::PointsContainerIterator pointIterator = this->m_Input->GetPoints()->Begin(); typename InputMeshType::PointsContainerIterator pointEnd = this->m_Input->GetPoints()->End(); typename InputMeshType::PointDataContainerIterator pointDataIterator = this->m_Input->GetPointData()->Begin(); while( pointIterator != pointEnd ) { PointType point = pointIterator.Value(); outputFile << point[0] << " " << point[1]; if( Dimension == 2 ) { outputFile << " 0 "; } else if( Dimension == 3 ) { outputFile << " " << point[2] << " "; } outputFile << pointDataIterator.Value() << std::endl; pointIterator++; pointDataIterator++; } } outputFile << "0 0 0 0" << std::endl; outputFile.close(); } template void LabeledPointSetFileWriter ::WritePointsToImageFile() { typename LabeledPointSetImageType::Pointer outputImage = LabeledPointSetImageType::New(); outputImage->SetDirection( this->m_ImageDirection ); outputImage->SetRegions( this->m_ImageSize ); outputImage->SetOrigin( this->m_ImageOrigin ); outputImage->SetSpacing( this->m_ImageSpacing ); outputImage->Allocate(); outputImage->FillBuffer( NumericTraits::Zero ); if( this->m_Input->GetNumberOfPoints() > 0 ) { typename InputMeshType::PointsContainerIterator pointIterator = this->m_Input->GetPoints()->Begin(); typename InputMeshType::PointsContainerIterator pointEnd = this->m_Input->GetPoints()->End(); typename InputMeshType::PointDataContainerIterator pointDataIterator = this->m_Input->GetPointData()->Begin(); while( pointIterator != pointEnd ) { PointType point = pointIterator.Value(); PixelType label = pointDataIterator.Value(); typename LabeledPointSetImageType::IndexType index; typename LabeledPointSetImageType::PointType ipoint; ipoint.CastFrom( point ); if( outputImage->TransformPhysicalPointToIndex( ipoint, index ) ) { outputImage->SetPixel( index, label ); } pointIterator++; pointDataIterator++; } } typedef ImageFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName( this->m_FileName.c_str() ); writer->SetInput( outputImage ); writer->Update(); } template void LabeledPointSetFileWriter ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf(os,indent); os << indent << "FileName: " << this->m_FileName << std::endl; } } //end of namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkManifoldParzenWindowsPointSetFunction.h000066400000000000000000000144251147325206600270020ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkManifoldParzenWindowsPointSetFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkManifoldParzenWindowsPointSetFunction_h #define __itkManifoldParzenWindowsPointSetFunction_h #include "itkPointSetFunction.h" #include "itkGaussianProbabilityDensityFunction.h" #include "itkKdTreeGenerator.h" #include "itkListSample.h" #include "itkMatrix.h" #include "itkMersenneTwisterRandomVariateGenerator.h" #include "itkMeshSource.h" #include "itkPointSet.h" #include "itkVector.h" #include "itkWeightedCentroidKdTreeGenerator.h" #include namespace itk { /** \class ManifoldParzenWindowsPointSetFunction.h * \brief point set filter. */ template class ITK_EXPORT ManifoldParzenWindowsPointSetFunction : public PointSetFunction { public: typedef ManifoldParzenWindowsPointSetFunction Self; typedef PointSetFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Extract dimension from output image. */ itkStaticConstMacro( Dimension, unsigned int, TPointSet::PointDimension ); typedef typename Superclass::InputPointSetType InputPointSetType; typedef typename Superclass::InputPointType InputPointType; /** Point set typedef support. */ typedef TPointSet PointSetType; typedef typename PointSetType::PointType PointType; typedef typename PointSetType ::PointsContainerConstIterator PointsContainerConstIterator; typedef Vector MeasurementVectorType; typedef typename Statistics::ListSample SampleType; typedef typename Statistics ::WeightedCentroidKdTreeGenerator TreeGeneratorType; typedef typename TreeGeneratorType::KdTreeType KdTreeType; typedef typename KdTreeType ::InstanceIdentifierVectorType NeighborhoodIdentifierType; /** Other typedef */ typedef TOutput RealType; typedef TOutput OutputType; typedef Vector VectorType; typedef typename Statistics ::MersenneTwisterRandomVariateGenerator RandomizerType; typedef typename Statistics ::GaussianProbabilityDensityFunction GaussianType; typedef std::vector GaussianContainerType; typedef typename GaussianType::MatrixType CovarianceMatrixType; /** Helper functions */ itkSetMacro( CovarianceKNeighborhood, unsigned int ); itkGetConstMacro( CovarianceKNeighborhood, unsigned int ); itkSetMacro( EvaluationKNeighborhood, unsigned int ); itkGetConstMacro( EvaluationKNeighborhood, unsigned int ); itkSetMacro( RegularizationSigma, RealType ); itkGetConstMacro( RegularizationSigma, RealType ); itkSetMacro( KernelSigma, RealType ); itkGetConstMacro( KernelSigma, RealType ); itkSetMacro( BucketSize, unsigned int ); itkGetConstMacro( BucketSize, unsigned int ); itkSetMacro( Normalize, bool ); itkGetConstMacro( Normalize, bool ); itkBooleanMacro( Normalize ); itkSetMacro( UseAnisotropicCovariances, bool ); itkGetConstMacro( UseAnisotropicCovariances, bool ); itkBooleanMacro( UseAnisotropicCovariances ); virtual void SetInputPointSet( const InputPointSetType * ptr ); virtual TOutput Evaluate( const InputPointType& point ) const; PointType GenerateRandomSample(); typename GaussianType::Pointer GetGaussian( unsigned int i ) { if ( i < this->m_Gaussians.size() ) { return this->m_Gaussians[i].GetPointer(); } else { return NULL; } this->Modified(); } void SetGaussian( unsigned int i, typename GaussianType::Pointer gaussian ) { if ( i >= this->m_Gaussians.size() ) { this->m_Gaussians.resize( i+1 ); } this->m_Gaussians[i] = gaussian; this->Modified(); } void GenerateKdTree(); NeighborhoodIdentifierType GetNeighborhoodIdentifiers( MeasurementVectorType, unsigned int ); NeighborhoodIdentifierType GetNeighborhoodIdentifiers( InputPointType, unsigned int ); protected: ManifoldParzenWindowsPointSetFunction(); virtual ~ManifoldParzenWindowsPointSetFunction(); void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: //purposely not implemented ManifoldParzenWindowsPointSetFunction( const Self& ); void operator=( const Self& ); unsigned int m_CovarianceKNeighborhood; unsigned int m_EvaluationKNeighborhood; unsigned int m_BucketSize; RealType m_RegularizationSigma; RealType m_KernelSigma; typename TreeGeneratorType::Pointer m_KdTreeGenerator; typename SampleType::Pointer m_SamplePoints; typename RandomizerType::Pointer m_Randomizer; GaussianContainerType m_Gaussians; bool m_Normalize; bool m_UseAnisotropicCovariances; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkManifoldParzenWindowsPointSetFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkManifoldParzenWindowsPointSetFunction.txx000066400000000000000000000261001147325206600273670ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkManifoldParzenWindowsPointSetFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.17 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkManifoldParzenWindowsPointSetFunction_txx #define __itkManifoldParzenWindowsPointSetFunction_txx #include "itkManifoldParzenWindowsPointSetFunction.h" #include "vnl/vnl_vector.h" #include "vnl/vnl_math.h" namespace itk { template ManifoldParzenWindowsPointSetFunction ::ManifoldParzenWindowsPointSetFunction() { this->m_BucketSize = 4; this->m_CovarianceKNeighborhood = 5; this->m_EvaluationKNeighborhood = 50; this->m_SamplePoints = NULL; this->m_KdTreeGenerator = NULL; this->m_RegularizationSigma = 1.0; this->m_KernelSigma = 1.0; this->m_Normalize = true; this->m_UseAnisotropicCovariances = true; this->m_Randomizer = RandomizerType::New(); this->m_Randomizer->SetSeed(); } template ManifoldParzenWindowsPointSetFunction ::~ManifoldParzenWindowsPointSetFunction() { } template void ManifoldParzenWindowsPointSetFunction ::SetInputPointSet( const InputPointSetType * ptr ) { this->m_PointSet = ptr; /** * Generate KdTree and create set of gaussians from input point set */ this->m_SamplePoints = SampleType::New(); this->m_SamplePoints->SetMeasurementVectorSize( Dimension ); std::vector inputGaussians; inputGaussians.resize( this->GetInputPointSet()->GetNumberOfPoints() ); this->m_Gaussians.resize( this->GetInputPointSet()->GetNumberOfPoints() ); MeasurementVectorType mv; unsigned long count = 0; PointsContainerConstIterator It = this->GetInputPointSet()->GetPoints()->Begin(); while( It != this->GetInputPointSet()->GetPoints()->End() ) { PointType point = It.Value(); typename GaussianType::MeanType mean( Dimension ); for( unsigned int d = 0; d < Dimension; d++ ) { mv[d] = point[d]; mean[d] = point[d]; } this->m_SamplePoints->PushBack( mv ); inputGaussians[count] = GaussianType::New(); inputGaussians[count]->SetGenerateRandomSamples( false ); inputGaussians[count]->SetSigma( this->m_KernelSigma ); inputGaussians[count]->SetMean( mean ); count++; ++It; } this->m_KdTreeGenerator = TreeGeneratorType::New(); m_KdTreeGenerator->SetSample( this->m_SamplePoints ); m_KdTreeGenerator->SetBucketSize( this->m_BucketSize ); m_KdTreeGenerator->Update(); /** * Calculate covariance matrices */ It = this->GetInputPointSet()->GetPoints()->Begin(); while( It != this->GetInputPointSet()->GetPoints()->End() ) { PointType point = It.Value(); unsigned long index = It.Index(); this->m_Gaussians[index] = GaussianType::New(); this->m_Gaussians[index]->SetGenerateRandomSamples( true ); this->m_Gaussians[index]->SetMean( inputGaussians[index]->GetMean() ); if( this->m_CovarianceKNeighborhood > 0 && this->m_UseAnisotropicCovariances ) { CovarianceMatrixType Cout( Dimension, Dimension ); Cout.Fill( 0 ); MeasurementVectorType queryPoint; for( unsigned int d = 0; d < Dimension; d++ ) { queryPoint[d] = point[d]; } typename TreeGeneratorType::KdTreeType ::InstanceIdentifierVectorType neighbors; this->m_KdTreeGenerator->GetOutput()->Search( queryPoint, this->m_CovarianceKNeighborhood, neighbors ); RealType denominator = 0.0; for( unsigned int j = 0; j < this->m_CovarianceKNeighborhood; j++ ) { if( neighbors[j] != index && neighbors[j] < this->GetInputPointSet()->GetNumberOfPoints() ) { MeasurementVectorType neighbor = this->m_KdTreeGenerator->GetOutput()->GetMeasurementVector( neighbors[j] ); RealType kernelValue = inputGaussians[index]->Evaluate( neighbor ); denominator += kernelValue; if( kernelValue > 0.0 ) { for( unsigned int m = 0; m < Dimension; m++ ) { for( unsigned int n = m; n < Dimension; n++ ) { RealType covariance = kernelValue * ( neighbor[m] - queryPoint[m] ) * ( neighbor[n] - queryPoint[n] ); Cout( m, n ) += covariance; Cout( n, m ) += covariance; } } } } } if( this->m_Normalize && denominator > 0.0 ) { Cout /= denominator; } else { Cout /= static_cast( this->m_CovarianceKNeighborhood ); } for( unsigned int m = 0; m < Dimension; m++ ) { Cout( m, m ) += ( this->m_RegularizationSigma * this->m_RegularizationSigma ); } this->m_Gaussians[index]->SetCovariance( Cout ); } else { this->m_Gaussians[index]->SetSigma( this->m_RegularizationSigma ); } ++It; } } template void ManifoldParzenWindowsPointSetFunction ::GenerateKdTree() { /** * Generate KdTree and create set of gaussians from input point set */ this->m_SamplePoints = SampleType::New(); this->m_SamplePoints->SetMeasurementVectorSize( Dimension ); MeasurementVectorType mv; typename GaussianContainerType::const_iterator it; for( it = this->m_Gaussians.begin(); it != this->m_Gaussians.end(); ++it ) { typename GaussianType::MeanType mean = (*it)->GetMean(); for( unsigned int d = 0; d < Dimension; d++ ) { mv[d] = mean[d]; } this->m_SamplePoints->PushBack( mv ); } this->m_KdTreeGenerator = TreeGeneratorType::New(); this->m_KdTreeGenerator->SetSample( this->m_SamplePoints ); this->m_KdTreeGenerator->SetBucketSize( this->m_BucketSize ); this->m_KdTreeGenerator->Update(); } template TOutput ManifoldParzenWindowsPointSetFunction ::Evaluate( const InputPointType &point ) const { if( !this->m_KdTreeGenerator ) { MeasurementVectorType measurement; for( unsigned int d = 0; d < Dimension; d++ ) { measurement[d] = point[d]; } OutputType sum = 0.0; typename GaussianContainerType::const_iterator it; for( it = this->m_Gaussians.begin(); it != this->m_Gaussians.end(); ++it ) { sum += static_cast( (*it)->Evaluate( measurement ) ); } return static_cast( sum / static_cast( this->m_Gaussians.size() ) ); } else { MeasurementVectorType queryPoint; for( unsigned int d = 0; d < Dimension; d++ ) { queryPoint[d] = point[d]; } unsigned int numberOfNeighbors = vnl_math_min( this->m_EvaluationKNeighborhood, static_cast( this->m_Gaussians.size() ) ); OutputType sum = 0.0; if( numberOfNeighbors == this->m_Gaussians.size() ) { for( unsigned int j = 0; j < this->m_Gaussians.size(); j++ ) { sum += static_cast( this->m_Gaussians[j]->Evaluate( queryPoint ) ); } } else { typename TreeGeneratorType::KdTreeType ::InstanceIdentifierVectorType neighbors; this->m_KdTreeGenerator->GetOutput()->Search( queryPoint, static_cast( numberOfNeighbors ), neighbors ); for( unsigned int j = 0; j < numberOfNeighbors; j++ ) { sum += static_cast( this->m_Gaussians[neighbors[j]]->Evaluate( queryPoint ) ); } } return static_cast( sum / static_cast( this->m_Gaussians.size() ) ); } } template typename ManifoldParzenWindowsPointSetFunction ::NeighborhoodIdentifierType ManifoldParzenWindowsPointSetFunction ::GetNeighborhoodIdentifiers( MeasurementVectorType point, unsigned int numberOfNeighbors ) { if( numberOfNeighbors > this->m_KdTreeGenerator->GetOutput()->Size() ) { numberOfNeighbors = this->m_KdTreeGenerator->GetOutput()->Size(); } NeighborhoodIdentifierType neighbors; this->m_KdTreeGenerator->GetOutput()->Search( point, numberOfNeighbors, neighbors ); return neighbors; } template typename ManifoldParzenWindowsPointSetFunction ::NeighborhoodIdentifierType ManifoldParzenWindowsPointSetFunction ::GetNeighborhoodIdentifiers( InputPointType point, unsigned int numberOfNeighbors ) { MeasurementVectorType queryPoint( Dimension ); for( unsigned int d = 0; d < Dimension; d++ ) { queryPoint[d] = point[d]; } return this->GetNeighborhoodIdentifiers( queryPoint, numberOfNeighbors ); } template typename ManifoldParzenWindowsPointSetFunction ::PointType ManifoldParzenWindowsPointSetFunction ::GenerateRandomSample() { typename GaussianType::MeasurementVectorType gaussianSample; gaussianSample = this->m_Gaussians[this->m_Randomizer->GetIntegerVariate( this->GetInputPointSet()->GetNumberOfPoints()-1 ) ]->GenerateRandomSample(); PointType sample; for( unsigned int d = 0; d < Dimension; d++ ) { sample[d] = gaussianSample[d]; } return sample; } /** * Standard "PrintSelf" method */ template void ManifoldParzenWindowsPointSetFunction ::PrintSelf( std::ostream& os, Indent indent) const { os << indent << "Covariance: " << this->m_CovarianceKNeighborhood << std::endl; os << indent << "Evaluation: " << this->m_EvaluationKNeighborhood << std::endl; os << indent << "Regularization sigma: " << this->m_RegularizationSigma << std::endl; os << indent << "Kernel sigma: " << this->m_KernelSigma << std::endl; os << indent << "Bucket size: " << this->m_BucketSize << std::endl; os << indent << "Normalize: " << this->m_Normalize << std::endl; os << indent << "Use anisotropic covariances: " << this->m_UseAnisotropicCovariances << std::endl; } } //end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkN3MRIBiasFieldCorrectionImageFilter.h000066400000000000000000000277621147325206600260660ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkN3MRIBiasFieldCorrectionImageFilter.h,v $ Language: C++ Date: $Date: 2009/06/09 16:22:05 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkN3MRIBiasFieldCorrectionImageFilter_h #define __itkN3MRIBiasFieldCorrectionImageFilter_h #include "itkImageToImageFilter.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkPointSet.h" #include "itkSingleValuedCostFunction.h" #include "itkVector.h" #include "vnl/vnl_vector.h" namespace itk { /** \class N3MRIBiasFieldCorrectionImageFilter.h * \brief Implementation of the N3 MRI bias field correction algorithm. * * The nonparametric nonuniform intensity normalization (N3) algorithm * is a method for correcting nonuniformity associated with MR images. * The algorithm assumes a simple parametric model (Gaussian) for the bias field * but does not require tissue class segmentation. In addition, there are * only a couple of parameters to tune with the default values performing * quite well. * * N3 has been publicly available as a set of perl scripts * (http://www.bic.mni.mcgill.ca/software/N3/) but, with this class, has been * reimplemented for the ITK library with only one minor variation involving * the b-spline fitting routine. We replaced the original fitting approach * with the itkBSplineScatteredDataPointSetToImageFilter which is not * susceptible to ill-conditioned matrix calculation as is the original proposed * fitting component. * * Notes for the user: * 0. Based on our experience with the filter, sometimes the scale of the bias * field is too small particularly for large mesh element sizes. Therefore, * we added an option (which is true by default) for finding the optimal * scaling of the bias field which is based on minimizing the coefficient * of variation of the corrected image. This cost function is given below * in N3BiasFieldScaleCostFunction. * 1. Since much of the image manipulation is done in the log space of the * intensities, input images with negative and small values (< 1) are * discouraged. * 2. The original authors recommend performing the bias field correction * on a downsampled version of the original image. * 3. A mask and/or confidence image can be supplied. * 4. The filter returns the corrected image. If the bias field is wanted, one * can reconstruct it using the class itkBSplineControlPointImageFilter. * See the IJ article and the test file for an example. * 5. The 'Z' parameter in Sled's 1998 paper is the square root * of the class variable 'm_WeinerFilterNoise'. * * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * * \par REFERENCE * J.G. Sled, P. Zijdenbos and A.C. Evans, "A comparison of retrospective * intensity non-uniformity correction methods for MRI". Information * Processing Medical Imaging Proc, 15th Int. Conf. IMPI'97, vol.1230, * pp 459-464,1997. * * J.G. Sled, A.P. Zijdenbos and A.C. Evans. "A Nonparametric Method for * Automatic Correction of Intensity Nonuniformity in MRI Data" * IEEE Transactions on Medical Imaging, Vol 17, No 1. Feb 1998. * */ /** * Class definition for N3BiasFieldScaleCostFunction */ template class ITK_EXPORT N3BiasFieldScaleCostFunction : public SingleValuedCostFunction { public: typedef N3BiasFieldScaleCostFunction Self; typedef SingleValuedCostFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( N3BiasFieldScaleCostFunction, SingleValuedCostFunction ); /** Method for creation through the object factory. */ itkNewMacro( Self ); typedef Superclass::MeasureType MeasureType; typedef Superclass::DerivativeType DerivativeType; typedef Superclass::ParametersType ParametersType; itkSetObjectMacro( InputImage, TInputImage ); itkSetObjectMacro( BiasFieldImage, TBiasFieldImage ); itkSetObjectMacro( MaskImage, TMaskImage ); itkSetObjectMacro( ConfidenceImage, TConfidenceImage ); itkSetMacro( MaskLabel, typename TMaskImage::PixelType ); itkGetConstMacro( MaskLabel, typename TMaskImage::PixelType ); virtual MeasureType GetValue( const ParametersType & parameters ) const; virtual void GetDerivative( const ParametersType & parameters, DerivativeType & derivative ) const; virtual unsigned int GetNumberOfParameters() const; protected: N3BiasFieldScaleCostFunction(); virtual ~N3BiasFieldScaleCostFunction(); private: N3BiasFieldScaleCostFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented typename TInputImage::Pointer m_InputImage; typename TBiasFieldImage::Pointer m_BiasFieldImage; typename TMaskImage::Pointer m_MaskImage; typename TConfidenceImage::Pointer m_ConfidenceImage; typename TMaskImage::PixelType m_MaskLabel; }; /** * Class definition for N3MRIBiasFieldCorrectionImageFilter */ template::ImageDimension>, class TOutputImage = TInputImage> class ITK_EXPORT N3MRIBiasFieldCorrectionImageFilter : public ImageToImageFilter { public: /** Standard class typedefs. */ typedef N3MRIBiasFieldCorrectionImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Runtime information support. */ itkTypeMacro( N3MRIBiasFieldCorrectionImageFilter, ImageToImageFilter ); /** Standard New method. */ itkNewMacro( Self ); /** ImageDimension constants */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); /** Some convenient typedefs. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; typedef TMaskImage MaskImageType; typedef typename MaskImageType::PixelType MaskPixelType; typedef float RealType; typedef Image RealImageType; /** B-spline smoothing filter typedefs */ typedef Vector ScalarType; typedef PointSet PointSetType; typedef Image ScalarImageType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::PointDataImageType BiasFieldControlPointLatticeType; typedef typename BSplineFilterType::ArrayType ArrayType; void SetMaskImage( const MaskImageType *mask ) { this->SetNthInput( 1, const_cast( mask ) ); } const MaskImageType* GetMaskImage() const { return static_cast( const_cast ( this->ProcessObject::GetInput( 1 ) ) ); } void SetConfidenceImage( const RealImageType *image ) { this->SetNthInput( 2, const_cast( image ) ); } const RealImageType* GetConfidenceImage() const { return static_cast( const_cast ( this->ProcessObject::GetInput( 2 ) ) ); } void SetInput1( const TInputImage *input ) { this->SetInput( input ); } void SetInput2( const TMaskImage *mask ) { this->SetMaskImage( mask ); } void SetInput3( const RealImageType *image ) { this->SetConfidenceImage( image ); } itkSetMacro( MaskLabel, MaskPixelType ); itkGetConstMacro( MaskLabel, MaskPixelType ); itkSetMacro( NumberOfHistogramBins, unsigned int ); itkGetConstMacro( NumberOfHistogramBins, unsigned int ); itkSetMacro( WeinerFilterNoise, RealType ); itkGetConstMacro( WeinerFilterNoise, RealType ); itkSetMacro( BiasFieldFullWidthAtHalfMaximum, RealType ); itkGetConstMacro( BiasFieldFullWidthAtHalfMaximum, RealType ); itkSetMacro( MaximumNumberOfIterations, unsigned int ); itkGetConstMacro( MaximumNumberOfIterations, unsigned int ); itkSetMacro( ConvergenceThreshold, RealType ); itkGetConstMacro( ConvergenceThreshold, RealType ); itkSetMacro( SplineOrder, unsigned int ); itkGetConstMacro( SplineOrder, unsigned int ); itkSetMacro( NumberOfFittingLevels, ArrayType ); itkGetConstMacro( NumberOfFittingLevels, ArrayType ); void SetNumberOfFittingLevels( unsigned int n ) { ArrayType nlevels; nlevels.Fill( n ); this->SetNumberOfFittingLevels( nlevels ); } itkSetMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( LogBiasFieldControlPointLattice, typename BiasFieldControlPointLatticeType::Pointer ); itkSetMacro( UseOptimalBiasFieldScaling, bool ); itkGetConstMacro( UseOptimalBiasFieldScaling, bool ); itkBooleanMacro( UseOptimalBiasFieldScaling ); itkGetConstMacro( BiasFieldScaling, RealType ); itkGetConstMacro( ElapsedIterations, unsigned int ); itkGetConstMacro( CurrentConvergenceMeasurement, RealType ); protected: N3MRIBiasFieldCorrectionImageFilter(); ~N3MRIBiasFieldCorrectionImageFilter() {}; void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: N3MRIBiasFieldCorrectionImageFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented typename RealImageType::Pointer SharpenImage( typename RealImageType::Pointer ); typename RealImageType::Pointer SmoothField( typename RealImageType::Pointer ); RealType CalculateConvergenceMeasurement( typename RealImageType::Pointer, typename RealImageType::Pointer ); RealType CalculateOptimalBiasFieldScaling( typename RealImageType::Pointer ); MaskPixelType m_MaskLabel; /** * Parameters for deconvolution with Weiner filter */ unsigned int m_NumberOfHistogramBins; RealType m_WeinerFilterNoise; RealType m_BiasFieldFullWidthAtHalfMaximum; /** * Convergence parameters */ unsigned int m_MaximumNumberOfIterations; unsigned int m_ElapsedIterations; RealType m_ConvergenceThreshold; RealType m_CurrentConvergenceMeasurement; /** * B-spline fitting parameters */ typename BiasFieldControlPointLatticeType::Pointer m_LogBiasFieldControlPointLattice; unsigned int m_SplineOrder; ArrayType m_NumberOfControlPoints; ArrayType m_NumberOfFittingLevels; /** * other parameters */ RealType m_BiasFieldScaling; bool m_UseOptimalBiasFieldScaling; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkN3MRIBiasFieldCorrectionImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkN3MRIBiasFieldCorrectionImageFilter.txx000066400000000000000000000647541147325206600264640ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkN3MRIBiasFieldCorrectionImageFilter.txx,v $ Language: C++ Date: $Date: 2009/06/09 16:22:05 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkN3MRIBiasFieldCorrectionImageFilter_txx #define __itkN3MRIBiasFieldCorrectionImageFilter_txx #include "itkN3MRIBiasFieldCorrectionImageFilter.h" #include "itkDivideImageFilter.h" #include "itkExpImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkIterationReporter.h" #include "itkLBFGSBOptimizer.h" #include "itkLogImageFilter.h" #include "itkSubtractImageFilter.h" #include "vnl/algo/vnl_fft_1d.h" #include "vnl/vnl_complex_traits.h" #include "vxl/vcl/vcl_complex.h" namespace itk { /** * N3BiasFieldScaleCostFunction class definitions */ template N3BiasFieldScaleCostFunction ::N3BiasFieldScaleCostFunction() { this->m_InputImage = NULL; this->m_BiasFieldImage = NULL; this->m_MaskImage = NULL; this->m_ConfidenceImage = NULL; this->m_MaskLabel = NumericTraits::One; } template N3BiasFieldScaleCostFunction ::~N3BiasFieldScaleCostFunction() { } template typename N3BiasFieldScaleCostFunction::MeasureType N3BiasFieldScaleCostFunction ::GetValue( const ParametersType & parameters ) const { ImageRegionConstIterator ItI( this->m_InputImage, this->m_InputImage->GetRequestedRegion() ); ImageRegionConstIterator ItB( this->m_BiasFieldImage, this->m_BiasFieldImage->GetRequestedRegion() ); MeasureType mu = 0.0; MeasureType N = 0.0; for( ItI.GoToBegin(), ItB.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItB ) { if( ( !this->m_MaskImage || this->m_MaskImage->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) && ( !this->m_ConfidenceImage || this->m_ConfidenceImage->GetPixel( ItI.GetIndex() ) > 0.0 ) ) { mu += static_cast( ItI.Get() ) / ( parameters[0] * ( static_cast( ItB.Get() ) - 1.0 ) + 1.0 ); N += 1.0; } } mu /= N; MeasureType value = 0.0; for( ItI.GoToBegin(), ItB.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItB ) { if( ( !this->m_MaskImage || this->m_MaskImage->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) && ( !this->m_ConfidenceImage || this->m_ConfidenceImage->GetPixel( ItI.GetIndex() ) > 0.0 ) ) { value += vnl_math_sqr( ( ItI.Get() / ( parameters[0] * ( static_cast( ItB.Get() ) - 1.0 ) + 1.0 ) ) / mu - 1.0 ); } } value /= ( N - 1.0 ); return value; } template void N3BiasFieldScaleCostFunction ::GetDerivative( const ParametersType & parameters, DerivativeType & derivative ) const { ImageRegionConstIterator ItI( this->m_InputImage, this->m_InputImage->GetRequestedRegion() ); ImageRegionConstIterator ItB( this->m_BiasFieldImage, this->m_BiasFieldImage->GetRequestedRegion() ); MeasureType mu = 0.0; MeasureType dmu = 0.0; MeasureType N = 0.0; for( ItI.GoToBegin(), ItB.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItB ) { if( ( !this->m_MaskImage || this->m_MaskImage->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) && ( !this->m_ConfidenceImage || this->m_ConfidenceImage->GetPixel( ItI.GetIndex() ) > 0.0 ) ) { MeasureType d = parameters[0] * ( static_cast( ItB.Get() ) - 1.0 ) + 1.0; mu += ( static_cast( ItI.Get() ) / d ); dmu += -static_cast( ItI.Get() ) * ( static_cast( ItB.Get() ) - 1.0 ) / d; N += 1.0; } } mu /= N; dmu /= N; MeasureType value = 0.0; for( ItI.GoToBegin(), ItB.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItB ) { if( ( !this->m_MaskImage || this->m_MaskImage->GetPixel( ItI.GetIndex() ) == this->m_MaskLabel ) && ( !this->m_ConfidenceImage || this->m_ConfidenceImage->GetPixel( ItI.GetIndex() ) > 0.0 ) ) { MeasureType d = parameters[0] * ( static_cast( ItB.Get() ) - 1.0 ) + 1.0; MeasureType t = static_cast( ItI.Get() ) / d; MeasureType dt = -t * ( static_cast( ItB.Get() ) - 1.0 ); value += ( ( t / mu - 1.0 ) * ( dt / mu - dmu * t / ( vnl_math_sqr( mu ) ) ) ); } } derivative.SetSize( 1 ); derivative( 0 ) = 2.0 * value / ( N - 1 ); } template unsigned int N3BiasFieldScaleCostFunction ::GetNumberOfParameters() const { return NumericTraits::One; } /** * N3MRIBiasFieldCorrectionImageFilter class definitions */ template N3MRIBiasFieldCorrectionImageFilter ::N3MRIBiasFieldCorrectionImageFilter() { this->SetNumberOfRequiredInputs( 1 ); this->m_MaskLabel = NumericTraits::One; this->m_NumberOfHistogramBins = 200; this->m_WeinerFilterNoise = 0.01; this->m_BiasFieldFullWidthAtHalfMaximum = 0.15; this->m_MaximumNumberOfIterations = 50; this->m_ConvergenceThreshold = 0.001; this->m_SplineOrder = 3; this->m_NumberOfFittingLevels.Fill( 4 ); this->m_NumberOfControlPoints.Fill( 4 ); this->m_UseOptimalBiasFieldScaling = true; this->m_BiasFieldScaling = 1.0; } template void N3MRIBiasFieldCorrectionImageFilter ::GenerateData() { /** * Calculate the log of the input image. */ typename RealImageType::Pointer logInputImage = RealImageType::New(); typedef ExpImageFilter ExpImageFilterType; typedef LogImageFilter LogFilterType; typename LogFilterType::Pointer logFilter1 = LogFilterType::New(); logFilter1->SetInput( this->GetInput() ); logFilter1->Update(); logInputImage = logFilter1->GetOutput(); /** * Remove possible nans/infs from the log input image. */ ImageRegionIteratorWithIndex It( logInputImage, logInputImage->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { if( vnl_math_isnan( It.Get() ) || vnl_math_isinf( It.Get() ) || It.Get() < 0.0 ) { It.Set( 0.0 ); } } } /** * Provide an initial log bias field of zeros */ typename RealImageType::Pointer logBiasField = RealImageType::New(); logBiasField->SetOrigin( this->GetInput()->GetOrigin() ); logBiasField->SetRegions( this->GetInput()->GetRequestedRegion() ); logBiasField->SetSpacing( this->GetInput()->GetSpacing() ); logBiasField->SetDirection( this->GetInput()->GetDirection() ); logBiasField->Allocate(); logBiasField->FillBuffer( 0.0 ); /** * Iterate until convergence or iterative exhaustion. */ IterationReporter reporter( this, 0, 1 ); bool isConverged = false; this->m_ElapsedIterations = 0; while( !isConverged && this->m_ElapsedIterations++ < this->m_MaximumNumberOfIterations ) { typedef SubtractImageFilter SubtracterType; typename SubtracterType::Pointer subtracter1 = SubtracterType::New(); subtracter1->SetInput1( logInputImage ); subtracter1->SetInput2( logBiasField ); subtracter1->Update(); typename RealImageType::Pointer logSharpenedImage = this->SharpenImage( subtracter1->GetOutput() ); typename SubtracterType::Pointer subtracter2 = SubtracterType::New(); subtracter2->SetInput1( logInputImage ); subtracter2->SetInput2( logSharpenedImage ); subtracter2->Update(); typename RealImageType::Pointer newLogBiasField = this->SmoothField( subtracter2->GetOutput() ); this->m_CurrentConvergenceMeasurement = this->CalculateConvergenceMeasurement( logBiasField, newLogBiasField ); isConverged = ( this->m_CurrentConvergenceMeasurement < this->m_ConvergenceThreshold ); logBiasField = newLogBiasField; reporter.CompletedStep(); } typedef ExpImageFilter ExpImageFilterType; typename ExpImageFilterType::Pointer expFilter = ExpImageFilterType::New(); expFilter->SetInput( logBiasField ); expFilter->Update(); /** * Calculate the optimal scaling */ if( this->m_UseOptimalBiasFieldScaling ) { this->m_BiasFieldScaling = this->CalculateOptimalBiasFieldScaling( expFilter->GetOutput() ); ImageRegionIterator ItE( expFilter->GetOutput(), expFilter->GetOutput()->GetRequestedRegion() ); for( ItE.GoToBegin(); !ItE.IsAtEnd(); ++ItE ) { ItE.Set( this->m_BiasFieldScaling * ( ItE.Get() - 1.0 ) + 1.0 ); } } /** * Divide the input image by the bias field to get the final image. */ typedef DivideImageFilter DividerType; typename DividerType::Pointer divider = DividerType::New(); divider->SetInput1( this->GetInput() ); divider->SetInput2( expFilter->GetOutput() ); divider->Update(); this->SetNthOutput( 0, divider->GetOutput() ); } template typename N3MRIBiasFieldCorrectionImageFilter ::RealImageType::Pointer N3MRIBiasFieldCorrectionImageFilter ::SharpenImage( typename RealImageType::Pointer unsharpenedImage ) { /** * Build the histogram for the uncorrected image. Store copy * in a vnl_vector to utilize vnl FFT routines. Note that variables * in real space are denoted by a single uppercase letter whereas their * frequency counterparts are indicated by a trailing lowercase 'f'. */ RealType binMaximum = NumericTraits::NonpositiveMin(); RealType binMinimum = NumericTraits::max(); ImageRegionIterator ItU( unsharpenedImage, unsharpenedImage->GetLargestPossibleRegion() ); for( ItU.GoToBegin(); !ItU.IsAtEnd(); ++ItU ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { RealType pixel = ItU.Get(); if( pixel > binMaximum ) { binMaximum = pixel; } else if( pixel < binMinimum ) { binMinimum = pixel; } } } RealType histogramSlope = ( binMaximum - binMinimum ) / static_cast( this->m_NumberOfHistogramBins - 1 ); /** * Create the intensity profile (within the masked region, if applicable) * using a triangular parzen windowing scheme. */ vnl_vector H( this->m_NumberOfHistogramBins, 0.0 ); for( ItU.GoToBegin(); !ItU.IsAtEnd(); ++ItU ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { RealType pixel = ItU.Get(); float cidx = ( static_cast( pixel ) - binMinimum ) / histogramSlope; unsigned int idx = vnl_math_floor( cidx ); RealType offset = cidx - static_cast( idx ); if( offset == 0.0 ) { H[idx] += 1.0; } else if( idx < this->m_NumberOfHistogramBins - 1 ) { H[idx] += 1.0 - offset; H[idx+1] += offset; } } } /** * Determine information about the intensity histogram and zero-pad * histogram to a power of 2. */ RealType exponent = vcl_ceil( vcl_log( static_cast( this->m_NumberOfHistogramBins ) ) / vcl_log( 2.0 ) ) + 1; unsigned int paddedHistogramSize = static_cast( vcl_pow( static_cast( 2.0 ), exponent ) + 0.5 ); unsigned int histogramOffset = static_cast( 0.5 * ( paddedHistogramSize - this->m_NumberOfHistogramBins ) ); vnl_vector< vcl_complex > V( paddedHistogramSize, vcl_complex( 0.0, 0.0 ) ); for( unsigned int n = 0; n < this->m_NumberOfHistogramBins; n++ ) { V[n+histogramOffset] = H[n]; } /** * Instantiate the 1-d vnl fft routine */ vnl_fft_1d fft( paddedHistogramSize ); vnl_vector< vcl_complex > Vf( V ); fft.fwd_transform( Vf ); /** * Create the Gaussian filter. */ RealType scaledFWHM = this->m_BiasFieldFullWidthAtHalfMaximum / histogramSlope; RealType expFactor = 4.0 * vcl_log( 2.0 ) / vnl_math_sqr( scaledFWHM ); RealType scaleFactor = 2.0 * vcl_sqrt( vcl_log( 2.0 ) / vnl_math::pi ) / scaledFWHM; vnl_vector< vcl_complex > F( paddedHistogramSize, vcl_complex( 0.0, 0.0 ) ); F[0] = vcl_complex( scaleFactor, 0.0 ); unsigned int halfSize = static_cast( 0.5 * paddedHistogramSize ); for( unsigned int n = 1; n <= halfSize; n++ ) { F[n] = F[paddedHistogramSize - n] = vcl_complex( scaleFactor * vcl_exp( -vnl_math_sqr( static_cast( n ) ) * expFactor ), 0.0 ); } if( paddedHistogramSize % 2 == 0 ) { F[halfSize] = vcl_complex( scaleFactor * vcl_exp( 0.25 * -vnl_math_sqr( static_cast( paddedHistogramSize ) ) * expFactor ), 0.0 ); } vnl_vector< vcl_complex > Ff( F ); fft.fwd_transform( Ff ); /** * Create the Weiner deconvolution filter. */ vnl_vector< vcl_complex > Gf( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { vcl_complex c = vnl_complex_traits< vcl_complex >::conjugate( Ff[n] ); Gf[n] = c / ( c * Ff[n] + this->m_WeinerFilterNoise ); } vnl_vector< vcl_complex > Uf( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { Uf[n] = Vf[n] * Gf[n].real(); } vnl_vector< vcl_complex > U( Uf ); fft.bwd_transform( U ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { U[n] = vcl_complex( vnl_math_max( U[n].real(), static_cast( 0.0 ) ), 0.0 ); } /** * Compute mapping E(u|v) */ vnl_vector< vcl_complex > numerator( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { numerator[n] = vcl_complex( ( binMinimum + ( static_cast( n ) - histogramOffset ) * histogramSlope ) * U[n].real(), 0.0 ); } fft.fwd_transform( numerator ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { numerator[n] *= Ff[n]; } fft.bwd_transform( numerator ); vnl_vector< vcl_complex > denominator( U ); fft.fwd_transform( denominator ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { denominator[n] *= Ff[n]; } fft.bwd_transform( denominator ); vnl_vector E( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { E[n] = numerator[n].real() / denominator[n].real(); if( vnl_math_isinf( E[n] ) || vnl_math_isnan( E[n] ) ) { E[n] = 0.0; } } /** * Remove the zero-padding from the mapping */ E = E.extract( this->m_NumberOfHistogramBins, histogramOffset ); /** * Sharpen the image with the new mapping, E(u|v) */ typename RealImageType::Pointer sharpenedImage = RealImageType::New(); sharpenedImage->SetOrigin( unsharpenedImage->GetOrigin() ); sharpenedImage->SetSpacing( unsharpenedImage->GetSpacing() ); sharpenedImage->SetRegions( unsharpenedImage->GetLargestPossibleRegion() ); sharpenedImage->SetDirection( unsharpenedImage->GetDirection() ); sharpenedImage->Allocate(); sharpenedImage->FillBuffer( 0.0 ); ImageRegionIterator ItC( sharpenedImage, sharpenedImage->GetLargestPossibleRegion() ); for( ItU.GoToBegin(), ItC.GoToBegin(); !ItU.IsAtEnd(); ++ItU, ++ItC ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { float cidx = ( ItU.Get() - binMinimum ) / histogramSlope; unsigned int idx = vnl_math_floor( cidx ); RealType correctedPixel = 0; if( idx < E.size() - 1 ) { correctedPixel = E[idx] + ( E[idx + 1] - E[idx] ) * ( cidx - static_cast( idx ) ); } else { correctedPixel = E[E.size() - 1]; } ItC.Set( correctedPixel ); } } return sharpenedImage; } template typename N3MRIBiasFieldCorrectionImageFilter ::RealImageType::Pointer N3MRIBiasFieldCorrectionImageFilter ::SmoothField( typename RealImageType::Pointer fieldEstimate ) { /** * Get original direction and change to identity temporarily for the * b-spline fitting. */ typename RealImageType::DirectionType direction = fieldEstimate->GetDirection(); typename RealImageType::DirectionType identity; identity.SetIdentity(); fieldEstimate->SetDirection( identity ); typename PointSetType::Pointer fieldPoints = PointSetType::New(); fieldPoints->Initialize(); typename BSplineFilterType::WeightsContainerType::Pointer weights = BSplineFilterType::WeightsContainerType::New(); weights->Initialize(); ImageRegionConstIteratorWithIndex It( fieldEstimate, fieldEstimate->GetRequestedRegion() ); unsigned int N = 0; for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { typename PointSetType::PointType point; fieldEstimate->TransformIndexToPhysicalPoint( It.GetIndex(), point ); ScalarType scalar; scalar[0] = It.Get(); fieldPoints->SetPointData( N, scalar ); fieldPoints->SetPoint( N, point ); if( this->GetConfidenceImage() ) { weights->InsertElement( N, this->GetConfidenceImage()->GetPixel( It.GetIndex() ) ); } else { weights->InsertElement( N, 1.0 ); } N++; } } fieldEstimate->SetDirection( direction ); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); bspliner->SetOrigin( fieldEstimate->GetOrigin() ); bspliner->SetSpacing( fieldEstimate->GetSpacing() ); bspliner->SetSize( fieldEstimate->GetLargestPossibleRegion().GetSize() ); bspliner->SetDirection( fieldEstimate->GetDirection() ); bspliner->SetGenerateOutputImage( true ); bspliner->SetNumberOfLevels( this->m_NumberOfFittingLevels ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetNumberOfControlPoints( this->m_NumberOfControlPoints ); bspliner->SetInput( fieldPoints ); bspliner->SetPointWeights( weights ); bspliner->Update(); /** * Save the bias field control points in case the user wants to * reconstruct the bias field. */ this->m_LogBiasFieldControlPointLattice = bspliner->GetPhiLattice(); typename RealImageType::Pointer smoothField = RealImageType::New(); smoothField->SetOrigin( fieldEstimate->GetOrigin() ); smoothField->SetSpacing( fieldEstimate->GetSpacing() ); smoothField->SetRegions( fieldEstimate->GetLargestPossibleRegion().GetSize() ); smoothField->SetDirection( direction ); smoothField->Allocate(); ImageRegionIterator ItB( bspliner->GetOutput(), bspliner->GetOutput()->GetLargestPossibleRegion() ); ImageRegionIterator ItF( smoothField, smoothField->GetLargestPossibleRegion() ); for( ItB.GoToBegin(), ItF.GoToBegin(); !ItB.IsAtEnd(); ++ItB, ++ItF ) { ItF.Set( ItB.Get()[0] ); } return smoothField; } template typename N3MRIBiasFieldCorrectionImageFilter ::RealType N3MRIBiasFieldCorrectionImageFilter ::CalculateConvergenceMeasurement( typename RealImageType::Pointer fieldEstimate1, typename RealImageType::Pointer fieldEstimate2 ) { typedef SubtractImageFilter SubtracterType; typename SubtracterType::Pointer subtracter = SubtracterType::New(); subtracter->SetInput1( fieldEstimate1 ); subtracter->SetInput2( fieldEstimate2 ); subtracter->Update(); /** * Calculate statistics over the mask region */ RealType mu = 0.0; RealType sigma = 0.0; RealType N = 0.0; ImageRegionConstIteratorWithIndex It( subtracter->GetOutput(), subtracter->GetOutput()->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) { RealType pixel = It.Get(); N += 1.0; if( N > 1.0 ) { sigma = sigma + vnl_math_sqr( pixel - mu ) * ( N - 1.0 ) / N; } mu = mu * ( 1.0 - 1.0 / N ) + pixel / N; } } sigma = vcl_sqrt( sigma / ( N - 1.0 ) ); /** * Although Sled's paper proposes convergence determination via * the coefficient of variation, the actual mnc implementation * utilizes the standard deviation as the convergence measurement. */ return sigma; } template typename N3MRIBiasFieldCorrectionImageFilter ::RealType N3MRIBiasFieldCorrectionImageFilter ::CalculateOptimalBiasFieldScaling( typename RealImageType::Pointer biasField ) { /** * This section is not described in Sled's paper but rather stems from * our own experience with N4ITK and the resulting innovation. For an initial * B-spline mesh of large resolution and a low number of fitting levels, * although the shape of of the bias field appears correect, the scale is too * small. This section finds an optimal scaling by minimizing the coefficient * of variation over masked region. */ typedef N3BiasFieldScaleCostFunction ScaleCostFunctionType; typename ScaleCostFunctionType::Pointer scaleCostFunction = ScaleCostFunctionType::New(); scaleCostFunction->SetInputImage( const_cast( this->GetInput() ) ); scaleCostFunction->SetBiasFieldImage( biasField ); scaleCostFunction->SetMaskImage( const_cast( this->GetMaskImage() ) ); scaleCostFunction->SetConfidenceImage( const_cast( this->GetConfidenceImage() ) ); typename LBFGSBOptimizer::BoundSelectionType boundSelection; boundSelection.SetSize( 1 ); boundSelection.Fill( 1 ); // only set a lower bound on the scale factor typename LBFGSBOptimizer::BoundValueType lowerBound; lowerBound.SetSize( 1 ); lowerBound.Fill( 1.0 ); typename LBFGSBOptimizer::BoundValueType upperBound; upperBound.SetSize( 1 ); upperBound.Fill( NumericTraits::max() ); typename LBFGSBOptimizer::ParametersType initialParameters; initialParameters.SetSize( 1 ); initialParameters.Fill( 1.0 ); typename LBFGSBOptimizer::Pointer optimizer = LBFGSBOptimizer::New(); optimizer->SetMinimize( true ); optimizer->SetCostFunction( scaleCostFunction ); optimizer->SetInitialPosition( initialParameters ); optimizer->SetCostFunctionConvergenceFactor( 1e1 ); optimizer->SetLowerBound( lowerBound ); optimizer->SetUpperBound( upperBound ); optimizer->SetBoundSelection( boundSelection ); optimizer->SetProjectedGradientTolerance( 1e-10 ); optimizer->StartOptimization(); typename LBFGSBOptimizer::ParametersType finalParameters = optimizer->GetCurrentPosition(); return finalParameters[0]; } template void N3MRIBiasFieldCorrectionImageFilter ::PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Mask label: " << this->m_MaskLabel << std::endl; os << indent << "Number of histogram bins: " << this->m_NumberOfHistogramBins << std::endl; os << indent << "Weiner filter noise: " << this->m_WeinerFilterNoise << std::endl; os << indent << "Bias field FWHM: " << this->m_BiasFieldFullWidthAtHalfMaximum << std::endl; os << indent << "Maximum number of iterations: " << this->m_MaximumNumberOfIterations << std::endl; os << indent << "Convergence threshold: " << this->m_ConvergenceThreshold << std::endl; os << indent << "Spline order: " << this->m_SplineOrder << std::endl; os << indent << "Number of fitting levels: " << this->m_NumberOfFittingLevels << std::endl; os << indent << "Number of control points: " << this->m_NumberOfControlPoints << std::endl; if( this->m_UseOptimalBiasFieldScaling ) { os << indent << "Optimal bias field scaling: " << this->m_BiasFieldScaling << std::endl; } } }// end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkN4MRIBiasFieldCorrectionImageFilter.h000066400000000000000000000233561147325206600260620ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkN4MRIBiasFieldCorrectionImageFilter.h,v $ Language: C++ Date: $Date: 2009/06/09 16:22:05 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkN4MRIBiasFieldCorrectionImageFilter_h #define __itkN4MRIBiasFieldCorrectionImageFilter_h #include "itkImageToImageFilter.h" #include "itkArray.h" #include "itkBSplineScatteredDataPointSetToImageFilter.h" #include "itkPointSet.h" #include "itkSingleValuedCostFunction.h" #include "itkVector.h" #include "vnl/vnl_vector.h" namespace itk { /** \class N4MRIBiasFieldCorrectionImageFilter.h * \brief Implementation of the N4 MRI bias field correction algorithm. * * The nonparametric nonuniform intensity normalization (N4) algorithm * is a method for correcting nonuniformity associated with MR images. * The algorithm assumes a simple parametric model (Gaussian) for the bias field * but does not require tissue class segmentation. In addition, there are * only a couple of parameters to tune with the default values performing * quite well. * * N4 has been publicly available as a set of perl scripts * (http://www.bic.mni.mcgill.ca/software/N4/) but, with this class, has been * reimplemented for the ITK library with only one minor variation involving * the b-spline fitting routine. We replaced the original fitting approach * with the itkBSplineScatteredDataPointSetToImageFilter which is not * susceptible to ill-conditioned matrix calculation as is the original proposed * fitting component. * * Notes for the user: * 1. Since much of the image manipulation is done in the log space of the * intensities, input images with negative and small values (< 1) are * discouraged. * 2. The original authors recommend performing the bias field correction * on a downsampled version of the original image. * 3. A mask and/or confidence image can be supplied. * 4. The filter returns the corrected image. If the bias field is wanted, one * can reconstruct it using the class itkBSplineControlPointImageFilter. * See the IJ article and the test file for an example. * 5. The 'Z' parameter in Sled's 1998 paper is the square root * of the class variable 'm_WeinerFilterNoise'. * * \author Nicholas J. Tustison * * Contributed by Nicholas J. Tustison, James C. Gee * in the Insight Journal paper: * * \par REFERENCE * J.G. Sled, P. Zijdenbos and A.C. Evans, "A comparison of retrospective * intensity non-uniformity correction methods for MRI". Information * Processing Medical Imaging Proc, 15th Int. Conf. IMPI'97, vol.1230, * pp 459-464,1997. * * J.G. Sled, A.P. Zijdenbos and A.C. Evans. "A Nonparametric Method for * Automatic Correction of Intensity Nonuniformity in MRI Data" * IEEE Transactions on Medical Imaging, Vol 17, No 1. Feb 1998. * */ template::ImageDimension>, class TOutputImage = TInputImage> class ITK_EXPORT N4MRIBiasFieldCorrectionImageFilter : public ImageToImageFilter { public: /** Standard class typedefs. */ typedef N4MRIBiasFieldCorrectionImageFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Runtime information support. */ itkTypeMacro( N4MRIBiasFieldCorrectionImageFilter, ImageToImageFilter ); /** Standard New method. */ itkNewMacro( Self ); /** ImageDimension constants */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); /** Some convenient typedefs. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; typedef TMaskImage MaskImageType; typedef typename MaskImageType::PixelType MaskPixelType; typedef float RealType; typedef Image RealImageType; /** B-spline smoothing filter typedefs */ typedef Vector ScalarType; typedef PointSet PointSetType; typedef Image ScalarImageType; typedef BSplineScatteredDataPointSetToImageFilter BSplineFilterType; typedef typename BSplineFilterType::PointDataImageType BiasFieldControlPointLatticeType; typedef typename BSplineFilterType::ArrayType ArrayType; typedef Array VariableSizeArrayType; void SetMaskImage( const MaskImageType *mask ) { this->SetNthInput( 1, const_cast( mask ) ); } const MaskImageType* GetMaskImage() const { return static_cast( const_cast ( this->ProcessObject::GetInput( 1 ) ) ); } void SetConfidenceImage( const RealImageType *image ) { this->SetNthInput( 2, const_cast( image ) ); } const RealImageType* GetConfidenceImage() const { return static_cast( const_cast ( this->ProcessObject::GetInput( 2 ) ) ); } void SetInput1( const TInputImage *input ) { this->SetInput( input ); } void SetInput2( const TMaskImage *mask ) { this->SetMaskImage( mask ); } void SetInput3( const RealImageType *image ) { this->SetConfidenceImage( image ); } itkSetMacro( MaskLabel, MaskPixelType ); itkGetConstMacro( MaskLabel, MaskPixelType ); itkSetMacro( NumberOfHistogramBins, unsigned int ); itkGetConstMacro( NumberOfHistogramBins, unsigned int ); itkSetMacro( WeinerFilterNoise, RealType ); itkGetConstMacro( WeinerFilterNoise, RealType ); itkSetMacro( BiasFieldFullWidthAtHalfMaximum, RealType ); itkGetConstMacro( BiasFieldFullWidthAtHalfMaximum, RealType ); itkSetMacro( MaximumNumberOfIterations, VariableSizeArrayType ); itkGetConstMacro( MaximumNumberOfIterations, VariableSizeArrayType ); itkSetMacro( ConvergenceThreshold, RealType ); itkGetConstMacro( ConvergenceThreshold, RealType ); itkSetMacro( SplineOrder, unsigned int ); itkGetConstMacro( SplineOrder, unsigned int ); itkSetMacro( NumberOfFittingLevels, ArrayType ); itkGetConstMacro( NumberOfFittingLevels, ArrayType ); void SetNumberOfFittingLevels( unsigned int n ) { ArrayType nlevels; nlevels.Fill( n ); this->SetNumberOfFittingLevels( nlevels ); } itkSetMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( NumberOfControlPoints, ArrayType ); itkGetConstMacro( LogBiasFieldControlPointLattice, typename BiasFieldControlPointLatticeType::Pointer ); itkSetClampMacro( SigmoidNormalizedAlpha, RealType, 0.0, NumericTraits::max() ); itkGetConstMacro( SigmoidNormalizedAlpha, RealType ); itkSetClampMacro( SigmoidNormalizedBeta, RealType, 0.0, 1.0 ); itkGetConstMacro( SigmoidNormalizedBeta, RealType ); itkGetConstMacro( ElapsedIterations, unsigned int ); itkGetConstMacro( CurrentConvergenceMeasurement, RealType ); itkGetConstMacro( CurrentLevel, unsigned int ); protected: N4MRIBiasFieldCorrectionImageFilter(); ~N4MRIBiasFieldCorrectionImageFilter() {}; void PrintSelf( std::ostream& os, Indent indent ) const; void GenerateData(); private: N4MRIBiasFieldCorrectionImageFilter( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented typename RealImageType::Pointer SharpenImage( typename RealImageType::Pointer ); typename RealImageType::Pointer UpdateBiasFieldEstimate( typename RealImageType::Pointer ); RealType CalculateConvergenceMeasurement( typename RealImageType::Pointer, typename RealImageType::Pointer ); MaskPixelType m_MaskLabel; /** * Parameters for deconvolution with Weiner filter */ unsigned int m_NumberOfHistogramBins; RealType m_WeinerFilterNoise; RealType m_BiasFieldFullWidthAtHalfMaximum; /** * Convergence parameters */ VariableSizeArrayType m_MaximumNumberOfIterations; unsigned int m_ElapsedIterations; RealType m_ConvergenceThreshold; RealType m_CurrentConvergenceMeasurement; unsigned int m_CurrentLevel; /** * B-spline fitting parameters */ typename BiasFieldControlPointLatticeType::Pointer m_LogBiasFieldControlPointLattice; unsigned int m_SplineOrder; ArrayType m_NumberOfControlPoints; ArrayType m_NumberOfFittingLevels; RealType m_SigmoidNormalizedAlpha; RealType m_SigmoidNormalizedBeta; }; // end of class } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkN4MRIBiasFieldCorrectionImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkN4MRIBiasFieldCorrectionImageFilter.txx000066400000000000000000000605111147325206600264500ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkN4MRIBiasFieldCorrectionImageFilter.txx,v $ Language: C++ Date: $Date: 2009/06/09 16:22:05 $ Version: $Revision: 1.6 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkN4MRIBiasFieldCorrectionImageFilter_txx #define __itkN4MRIBiasFieldCorrectionImageFilter_txx #include "itkN4MRIBiasFieldCorrectionImageFilter.h" #include "itkAddImageFilter.h" #include "itkBSplineControlPointImageFilter.h" #include "itkDivideImageFilter.h" #include "itkExpImageFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkIterationReporter.h" #include "itkLogImageFilter.h" #include "itkSubtractImageFilter.h" #include "vnl/algo/vnl_fft_1d.h" #include "vnl/vnl_complex_traits.h" #include "vxl/vcl/vcl_complex.h" namespace itk { template N4MRIBiasFieldCorrectionImageFilter ::N4MRIBiasFieldCorrectionImageFilter() { this->SetNumberOfRequiredInputs( 1 ); this->m_MaskLabel = NumericTraits::One; this->m_LogBiasFieldControlPointLattice = NULL; this->m_NumberOfHistogramBins = 200; this->m_WeinerFilterNoise = 0.01; this->m_BiasFieldFullWidthAtHalfMaximum = 0.15; this->m_SplineOrder = 3; this->m_NumberOfFittingLevels.Fill( 1 ); this->m_NumberOfControlPoints.Fill( 4 ); this->m_SigmoidNormalizedAlpha = 0.0; this->m_SigmoidNormalizedBeta = 0.5; this->m_MaximumNumberOfIterations.SetSize( 1 ); this->m_MaximumNumberOfIterations.Fill( 50 ); this->m_ConvergenceThreshold = 0.001; } template void N4MRIBiasFieldCorrectionImageFilter ::GenerateData() { /** * Calculate the log of the input image. */ typename RealImageType::Pointer logUncorrectedImage = RealImageType::New(); typedef ExpImageFilter ExpImageFilterType; typedef LogImageFilter LogFilterType; typename LogFilterType::Pointer logFilter = LogFilterType::New(); logFilter->SetInput( this->GetInput() ); logFilter->Update(); logUncorrectedImage = logFilter->GetOutput(); /** * Remove possible nans/infs from the log input image. */ ImageRegionIteratorWithIndex It( logUncorrectedImage, logUncorrectedImage->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { if( vnl_math_isnan( It.Get() ) || vnl_math_isinf( It.Get() ) || It.Get() < 0.0 ) { It.Set( 0.0 ); } } } /** * Provide an initial log bias field of zeros */ typename RealImageType::Pointer logBiasField = RealImageType::New(); logBiasField->SetOrigin( this->GetInput()->GetOrigin() ); logBiasField->SetRegions( this->GetInput()->GetRequestedRegion() ); logBiasField->SetSpacing( this->GetInput()->GetSpacing() ); logBiasField->SetDirection( this->GetInput()->GetDirection() ); logBiasField->Allocate(); logBiasField->FillBuffer( 0.0 ); /** * Iterate until convergence or iterative exhaustion. */ unsigned int maximumNumberOfLevels = 1; for( unsigned int d = 0; d < this->m_NumberOfFittingLevels.Size(); d++ ) { if( this->m_NumberOfFittingLevels[d] > maximumNumberOfLevels ) { maximumNumberOfLevels = this->m_NumberOfFittingLevels[d]; } } if( this->m_MaximumNumberOfIterations.Size() != maximumNumberOfLevels ) { itkExceptionMacro( "Number of iteration levels is not equal to the max number of levels." ); } for( this->m_CurrentLevel = 0; this->m_CurrentLevel < maximumNumberOfLevels; this->m_CurrentLevel++ ) { IterationReporter reporter( this, 0, 1 ); this->m_ElapsedIterations = 0; this->m_CurrentConvergenceMeasurement = NumericTraits::max(); while( this->m_ElapsedIterations++ < this->m_MaximumNumberOfIterations[this->m_CurrentLevel] && this->m_CurrentConvergenceMeasurement > this->m_ConvergenceThreshold ) { /** * Sharpen the current estimate of the uncorrected image. */ typename RealImageType::Pointer logSharpenedImage = this->SharpenImage( logUncorrectedImage ); typedef SubtractImageFilter SubtracterType; typename SubtracterType::Pointer subtracter1 = SubtracterType::New(); subtracter1->SetInput1( logUncorrectedImage ); subtracter1->SetInput2( logSharpenedImage ); subtracter1->Update(); /** * Smooth the residual bias field estimate and add the resulting * control point grid to get the new total bias field estimate. */ typename RealImageType::Pointer newLogBiasField = this->UpdateBiasFieldEstimate( subtracter1->GetOutput() ); this->m_CurrentConvergenceMeasurement = this->CalculateConvergenceMeasurement( logBiasField, newLogBiasField ); logBiasField = newLogBiasField; typename SubtracterType::Pointer subtracter2 = SubtracterType::New(); subtracter2->SetInput1( logFilter->GetOutput() ); subtracter2->SetInput2( logBiasField ); subtracter2->Update(); logUncorrectedImage = subtracter2->GetOutput(); reporter.CompletedStep(); } typedef BSplineControlPointImageFilter BSplineReconstructerType; typename BSplineReconstructerType::Pointer reconstructer = BSplineReconstructerType::New(); reconstructer->SetInput( this->m_LogBiasFieldControlPointLattice ); reconstructer->SetOrigin( logBiasField->GetOrigin() ); reconstructer->SetSpacing( logBiasField->GetSpacing() ); reconstructer->SetDirection( logBiasField->GetDirection() ); reconstructer->SetSize( logBiasField->GetLargestPossibleRegion().GetSize() ); reconstructer->Update(); typename BSplineReconstructerType::ArrayType numberOfLevels; numberOfLevels.Fill( 1 ); for( unsigned int d = 0; d < ImageDimension; d++ ) { if( this->m_NumberOfFittingLevels[d] + 1 >= this->m_CurrentLevel && this->m_CurrentLevel != maximumNumberOfLevels-1 ) { numberOfLevels[d] = 2; } } this->m_LogBiasFieldControlPointLattice = reconstructer-> RefineControlPointLattice( numberOfLevels ); } typedef ExpImageFilter ExpImageFilterType; typename ExpImageFilterType::Pointer expFilter = ExpImageFilterType::New(); expFilter->SetInput( logBiasField ); expFilter->Update(); /** * Divide the input image by the bias field to get the final image. */ typedef DivideImageFilter DividerType; typename DividerType::Pointer divider = DividerType::New(); divider->SetInput1( this->GetInput() ); divider->SetInput2( expFilter->GetOutput() ); divider->Update(); this->SetNthOutput( 0, divider->GetOutput() ); } template typename N4MRIBiasFieldCorrectionImageFilter ::RealImageType::Pointer N4MRIBiasFieldCorrectionImageFilter ::SharpenImage( typename RealImageType::Pointer unsharpenedImage ) { /** * Build the histogram for the uncorrected image. Store copy * in a vnl_vector to utilize vnl FFT routines. Note that variables * in real space are denoted by a single uppercase letter whereas their * frequency counterparts are indicated by a trailing lowercase 'f'. */ RealType binMaximum = NumericTraits::NonpositiveMin(); RealType binMinimum = NumericTraits::max(); ImageRegionIterator ItU( unsharpenedImage, unsharpenedImage->GetLargestPossibleRegion() ); for( ItU.GoToBegin(); !ItU.IsAtEnd(); ++ItU ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { RealType pixel = ItU.Get(); if( pixel > binMaximum ) { binMaximum = pixel; } else if( pixel < binMinimum ) { binMinimum = pixel; } } } RealType histogramSlope = ( binMaximum - binMinimum ) / static_cast( this->m_NumberOfHistogramBins - 1 ); /** * Create the intensity profile (within the masked region, if applicable) * using a triangular parzen windowing scheme. */ vnl_vector H( this->m_NumberOfHistogramBins, 0.0 ); for( ItU.GoToBegin(); !ItU.IsAtEnd(); ++ItU ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { RealType pixel = ItU.Get(); RealType cidx = ( static_cast( pixel ) - binMinimum ) / histogramSlope; unsigned int idx = vnl_math_floor( cidx ); RealType offset = cidx - static_cast( idx ); if( offset == 0.0 ) { H[idx] += 1.0; } else if( idx < this->m_NumberOfHistogramBins - 1 ) { H[idx] += 1.0 - offset; H[idx+1] += offset; } } } /** * Determine information about the intensity histogram and zero-pad * histogram to a power of 2. */ RealType exponent = vcl_ceil( vcl_log( static_cast( this->m_NumberOfHistogramBins ) ) / vcl_log( 2.0 ) ) + 1; unsigned int paddedHistogramSize = static_cast( vcl_pow( static_cast( 2.0 ), exponent ) + 0.5 ); unsigned int histogramOffset = static_cast( 0.5 * ( paddedHistogramSize - this->m_NumberOfHistogramBins ) ); vnl_vector< vcl_complex > V( paddedHistogramSize, vcl_complex( 0.0, 0.0 ) ); for( unsigned int n = 0; n < this->m_NumberOfHistogramBins; n++ ) { V[n+histogramOffset] = H[n]; } /** * Instantiate the 1-d vnl fft routine */ vnl_fft_1d fft( paddedHistogramSize ); vnl_vector< vcl_complex > Vf( V ); fft.fwd_transform( Vf ); /** * Create the Gaussian filter. */ RealType scaledFWHM = this->m_BiasFieldFullWidthAtHalfMaximum / histogramSlope; RealType expFactor = 4.0 * vcl_log( 2.0 ) / vnl_math_sqr( scaledFWHM ); RealType scaleFactor = 2.0 * vcl_sqrt( vcl_log( 2.0 ) / vnl_math::pi ) / scaledFWHM; vnl_vector< vcl_complex > F( paddedHistogramSize, vcl_complex( 0.0, 0.0 ) ); F[0] = vcl_complex( scaleFactor, 0.0 ); unsigned int halfSize = static_cast( 0.5 * paddedHistogramSize ); for( unsigned int n = 1; n <= halfSize; n++ ) { F[n] = F[paddedHistogramSize - n] = vcl_complex( scaleFactor * vcl_exp( -vnl_math_sqr( static_cast( n ) ) * expFactor ), 0.0 ); } if( paddedHistogramSize % 2 == 0 ) { F[halfSize] = vcl_complex( scaleFactor * vcl_exp( 0.25 * -vnl_math_sqr( static_cast( paddedHistogramSize ) ) * expFactor ), 0.0 ); } vnl_vector< vcl_complex > Ff( F ); fft.fwd_transform( Ff ); /** * Create the Weiner deconvolution filter. */ vnl_vector< vcl_complex > Gf( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { vcl_complex c = vnl_complex_traits< vcl_complex >::conjugate( Ff[n] ); Gf[n] = c / ( c * Ff[n] + this->m_WeinerFilterNoise ); } vnl_vector< vcl_complex > Uf( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { Uf[n] = Vf[n] * Gf[n].real(); } vnl_vector< vcl_complex > U( Uf ); fft.bwd_transform( U ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { U[n] = vcl_complex( vnl_math_max( U[n].real(), static_cast( 0.0 ) ), 0.0 ); } /** * Compute mapping E(u|v) */ vnl_vector< vcl_complex > numerator( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { numerator[n] = vcl_complex( ( binMinimum + ( static_cast( n ) - histogramOffset ) * histogramSlope ) * U[n].real(), 0.0 ); } fft.fwd_transform( numerator ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { numerator[n] *= Ff[n]; } fft.bwd_transform( numerator ); vnl_vector< vcl_complex > denominator( U ); fft.fwd_transform( denominator ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { denominator[n] *= Ff[n]; } fft.bwd_transform( denominator ); vnl_vector E( paddedHistogramSize ); for( unsigned int n = 0; n < paddedHistogramSize; n++ ) { E[n] = numerator[n].real() / denominator[n].real(); if( vnl_math_isinf( E[n] ) || vnl_math_isnan( E[n] ) ) { E[n] = 0.0; } } /** * Remove the zero-padding from the mapping */ E = E.extract( this->m_NumberOfHistogramBins, histogramOffset ); /** * Sharpen the image with the new mapping, E(u|v) */ typename RealImageType::Pointer sharpenedImage = RealImageType::New(); sharpenedImage->SetOrigin( unsharpenedImage->GetOrigin() ); sharpenedImage->SetSpacing( unsharpenedImage->GetSpacing() ); sharpenedImage->SetRegions( unsharpenedImage->GetLargestPossibleRegion() ); sharpenedImage->SetDirection( unsharpenedImage->GetDirection() ); sharpenedImage->Allocate(); sharpenedImage->FillBuffer( 0.0 ); ImageRegionIterator ItC( sharpenedImage, sharpenedImage->GetLargestPossibleRegion() ); for( ItU.GoToBegin(), ItC.GoToBegin(); !ItU.IsAtEnd(); ++ItU, ++ItC ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( ItU.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( ItU.GetIndex() ) > 0.0 ) ) { RealType cidx = ( ItU.Get() - binMinimum ) / histogramSlope; unsigned int idx = vnl_math_floor( cidx ); RealType correctedPixel = 0; if( idx < E.size() - 1 ) { correctedPixel = E[idx] + ( E[idx + 1] - E[idx] ) * ( cidx - static_cast( idx ) ); } else { correctedPixel = E[E.size() - 1]; } ItC.Set( correctedPixel ); } } return sharpenedImage; } template typename N4MRIBiasFieldCorrectionImageFilter ::RealImageType::Pointer N4MRIBiasFieldCorrectionImageFilter ::UpdateBiasFieldEstimate( typename RealImageType::Pointer fieldEstimate ) { /** * Calculate min/max for sigmoid weighting. Calculate mean for offseting * bias field calculations since B-spline algorithm biases the result * to zero. */ RealType maxAbsValue = NumericTraits::NonpositiveMin(); RealType minAbsValue = NumericTraits::max(); if( this->m_SigmoidNormalizedAlpha > 0.0 ) { ImageRegionConstIteratorWithIndex It( fieldEstimate, fieldEstimate->GetRequestedRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { RealType pixel = vnl_math_abs( It.Get() ); if( pixel > maxAbsValue ) { maxAbsValue = pixel; } else if( pixel < minAbsValue ) { minAbsValue = pixel; } } } } /** * Get original direction and change to identity temporarily for the * b-spline fitting. */ typename RealImageType::DirectionType direction = fieldEstimate->GetDirection(); typename RealImageType::DirectionType identity; identity.SetIdentity(); fieldEstimate->SetDirection( identity ); typename PointSetType::Pointer fieldPoints = PointSetType::New(); fieldPoints->Initialize(); typename BSplineFilterType::WeightsContainerType::Pointer weights = BSplineFilterType::WeightsContainerType::New(); weights->Initialize(); ImageRegionConstIteratorWithIndex It( fieldEstimate, fieldEstimate->GetRequestedRegion() ); unsigned int index = 0; for ( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { typename PointSetType::PointType point; fieldEstimate->TransformIndexToPhysicalPoint( It.GetIndex(), point ); ScalarType scalar; scalar[0] = It.Get(); fieldPoints->SetPointData( index, scalar ); fieldPoints->SetPoint( index, point ); RealType confidenceWeight = 1.0; if( this->GetConfidenceImage() ) { confidenceWeight = this->GetConfidenceImage()->GetPixel( It.GetIndex() ); } RealType sigmoidWeight = 1.0; if( this->m_SigmoidNormalizedAlpha > 0.0 ) { RealType alpha = ( maxAbsValue - minAbsValue ) / ( 12.0 * this->m_SigmoidNormalizedAlpha ); RealType beta = minAbsValue + ( maxAbsValue - minAbsValue ) * this->m_SigmoidNormalizedBeta; sigmoidWeight = 1.0 / ( 1.0 + vcl_exp( -( scalar[0] - beta ) / alpha ) ); } weights->InsertElement( index, sigmoidWeight * confidenceWeight ); index++; } } fieldEstimate->SetDirection( direction ); typename BSplineFilterType::Pointer bspliner = BSplineFilterType::New(); typename BSplineFilterType::ArrayType numberOfControlPoints; typename BSplineFilterType::ArrayType numberOfFittingLevels; numberOfFittingLevels.Fill( 1 ); for( unsigned int d = 0; d < ImageDimension; d++ ) { if( !this->m_LogBiasFieldControlPointLattice ) { numberOfControlPoints[d] = this->m_NumberOfControlPoints[d]; } else { numberOfControlPoints[d] = this->m_LogBiasFieldControlPointLattice-> GetLargestPossibleRegion().GetSize()[d]; } } typename ScalarImageType::PointType parametricOrigin = fieldEstimate->GetOrigin(); for( unsigned int d = 0; d < ImageDimension; d++ ) { parametricOrigin[d] += ( fieldEstimate->GetSpacing()[d] * fieldEstimate->GetLargestPossibleRegion().GetIndex()[d] ); } bspliner->SetOrigin( parametricOrigin ); bspliner->SetSpacing( fieldEstimate->GetSpacing() ); bspliner->SetSize( fieldEstimate->GetLargestPossibleRegion().GetSize() ); bspliner->SetDirection( fieldEstimate->GetDirection() ); bspliner->SetGenerateOutputImage( false ); bspliner->SetNumberOfLevels( numberOfFittingLevels ); bspliner->SetSplineOrder( this->m_SplineOrder ); bspliner->SetNumberOfControlPoints( numberOfControlPoints ); bspliner->SetInput( fieldPoints ); bspliner->SetPointWeights( weights ); bspliner->Update(); /** * Add the bias field control points to the current estimate. */ if( !this->m_LogBiasFieldControlPointLattice ) { this->m_LogBiasFieldControlPointLattice = bspliner->GetPhiLattice(); } else { typedef AddImageFilter AdderType; typename AdderType::Pointer adder = AdderType::New(); adder->SetInput1( this->m_LogBiasFieldControlPointLattice ); adder->SetInput2( bspliner->GetPhiLattice() ); adder->Update(); this->m_LogBiasFieldControlPointLattice = adder->GetOutput(); } typedef BSplineControlPointImageFilter BSplineReconstructerType; typename BSplineReconstructerType::Pointer reconstructer = BSplineReconstructerType::New(); reconstructer->SetInput( this->m_LogBiasFieldControlPointLattice ); reconstructer->SetOrigin( fieldEstimate->GetOrigin() ); reconstructer->SetSpacing( fieldEstimate->GetSpacing() ); reconstructer->SetDirection( direction ); reconstructer->SetSize( fieldEstimate->GetLargestPossibleRegion().GetSize() ); reconstructer->Update(); typename RealImageType::Pointer smoothField = RealImageType::New(); smoothField->SetOrigin( fieldEstimate->GetOrigin() ); smoothField->SetSpacing( fieldEstimate->GetSpacing() ); smoothField->SetRegions( fieldEstimate->GetLargestPossibleRegion() ); smoothField->SetDirection( direction ); smoothField->Allocate(); ImageRegionIterator ItR( reconstructer->GetOutput(), reconstructer->GetOutput()->GetLargestPossibleRegion() ); ImageRegionIterator ItF( smoothField, smoothField->GetLargestPossibleRegion() ); for( ItR.GoToBegin(), ItF.GoToBegin(); !ItR.IsAtEnd(); ++ItR, ++ItF ) { ItF.Set( ItR.Get()[0] ); } return smoothField; } template typename N4MRIBiasFieldCorrectionImageFilter ::RealType N4MRIBiasFieldCorrectionImageFilter ::CalculateConvergenceMeasurement( typename RealImageType::Pointer fieldEstimate1, typename RealImageType::Pointer fieldEstimate2 ) { typedef SubtractImageFilter SubtracterType; typename SubtracterType::Pointer subtracter = SubtracterType::New(); subtracter->SetInput1( fieldEstimate1 ); subtracter->SetInput2( fieldEstimate2 ); subtracter->Update(); /** * Calculate statistics over the mask region */ RealType mu = 0.0; RealType sigma = 0.0; RealType N = 0.0; ImageRegionConstIteratorWithIndex It( subtracter->GetOutput(), subtracter->GetOutput()->GetLargestPossibleRegion() ); for( It.GoToBegin(); !It.IsAtEnd(); ++It ) { if( ( !this->GetMaskImage() || this->GetMaskImage()->GetPixel( It.GetIndex() ) == this->m_MaskLabel ) && ( !this->GetConfidenceImage() || this->GetConfidenceImage()->GetPixel( It.GetIndex() ) > 0.0 ) ) { RealType pixel = vcl_exp( It.Get() ); N += 1.0; if( N > 1.0 ) { sigma = sigma + vnl_math_sqr( pixel - mu ) * ( N - 1.0 ) / N; } mu = mu * ( 1.0 - 1.0 / N ) + pixel / N; } } sigma = vcl_sqrt( sigma / ( N - 1.0 ) ); return ( sigma / mu ); } template void N4MRIBiasFieldCorrectionImageFilter ::PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Mask label: " << this->m_MaskLabel << std::endl; os << indent << "Number of histogram bins: " << this->m_NumberOfHistogramBins << std::endl; os << indent << "Weiner filter noise: " << this->m_WeinerFilterNoise << std::endl; os << indent << "Bias field FWHM: " << this->m_BiasFieldFullWidthAtHalfMaximum << std::endl; os << indent << "Maximum number of iterations: " << this->m_MaximumNumberOfIterations << std::endl; os << indent << "Convergence threshold: " << this->m_ConvergenceThreshold << std::endl; os << indent << "Spline order: " << this->m_SplineOrder << std::endl; os << indent << "Number of fitting levels: " << this->m_NumberOfFittingLevels << std::endl; os << indent << "Number of control points: " << this->m_NumberOfControlPoints << std::endl; os << indent << "Sigmoid normalized alpha: " << this->m_SigmoidNormalizedAlpha << std::endl; os << indent << "Sigmoid normalized beta: " << this->m_SigmoidNormalizedBeta << std::endl; } }// end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkOptimalSharpeningImageFilter.h000066400000000000000000000120611147325206600250510ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkOptimalSharpeningImageFilter.h,v $ Language: C++ Date: $Date: 2008/12/13 21:51:03 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkOptimalSharpeningImageFilter_h #define __itkOptimalSharpeningImageFilter_h #include "itkNumericTraits.h" #include "itkImageToImageFilter.h" #include "itkImage.h" namespace itk { /** * \class OptimalSharpeningImageFilter * * This filter sharpens an image using a Laplacian. OptimalSharpening * highlights regions of rapid intensity change and therefore * highlights or enhances the edges. The result is an image that * appears more in focus. * * \par The OptimalSharpening at each pixel location is computed by * convolution with the itk::LaplacianOperator. * * \par Inputs and Outputs * The input to this filter is a scalar-valued itk::Image of arbitrary * dimension. The output is a scalar-valued itk::Image. * \sa Image * \sa Neighborhood * \sa NeighborhoodOperator * \sa NeighborhoodIterator * \sa LaplacianOperator * * \ingroup ImageFeatureExtraction */ template class ITK_EXPORT OptimalSharpeningImageFilter : public ImageToImageFilter< TInputImage, TOutputImage > { public: /** Standard "Self" & Superclass typedef. */ typedef OptimalSharpeningImageFilter Self; typedef ImageToImageFilter< TInputImage, TOutputImage > Superclass; /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef typename TOutputImage::PixelType OutputPixelType; typedef typename TOutputImage::InternalPixelType OutputInternalPixelType; typedef typename NumericTraits::RealType RealType; typedef typename TInputImage::PixelType InputPixelType; typedef typename TInputImage::InternalPixelType InputInternalPixelType; itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension); /** Image typedef support. */ typedef TInputImage InputImageType; typedef TOutputImage OutputImageType; typedef typename InputImageType::Pointer InputImagePointer; /** Smart pointer typedef support. */ typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods) */ itkTypeMacro(OptimalSharpeningImageFilter, ImageToImageFilter); /** Method for creation through the object factory. */ itkNewMacro(Self); /** OptimalSharpeningImageFilter needs a larger input requested * region than the output requested region (larger in the direction * of the derivative). As such, OptimalSharpeningImageFilter * needs to provide an implementation for * GenerateInputRequestedRegion() in order to inform the pipeline * execution model. * * \sa ImageToImageFilter::GenerateInputRequestedRegion() */ virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError); void SetSValue(float s) { this->m_SValue=s; } /** Use the image spacing information in calculations. Use this option if you * want derivatives in physical space. Default is UseImageSpacingOn. */ void SetUseImageSpacingOn() { this->SetUseImageSpacing(true); } /** Ignore the image spacing. Use this option if you want derivatives in isotropic pixel space. Default is UseImageSpacingOn. */ void SetUseImageSpacingOff() { this->SetUseImageSpacing(false); } /** Set/Get whether or not the filter will use the spacing of the input image in its calculations */ itkSetMacro(UseImageSpacing, bool); itkGetMacro(UseImageSpacing, bool); protected: OptimalSharpeningImageFilter() { m_UseImageSpacing = true; m_SValue=0.5; } virtual ~OptimalSharpeningImageFilter() {} /** Standard pipeline method. While this class does not implement a * ThreadedGenerateData(), its GenerateData() delegates all * calculations to an NeighborhoodOperatorImageFilter. Since the * NeighborhoodOperatorImageFilter is multithreaded, this filter is * multithreaded by default. */ void GenerateData(); void PrintSelf(std::ostream&, Indent) const; private: OptimalSharpeningImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented bool m_UseImageSpacing; float m_SValue; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkOptimalSharpeningImageFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkOptimalSharpeningImageFilter.txx000066400000000000000000000202251147325206600254460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkOptimalSharpeningImageFilter.txx,v $ Language: C++ Date: $Date: 2008/12/13 21:51:03 $ Version: $Revision: 1.2 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkOptimalSharpeningImageFilter_txx #define __itkOptimalSharpeningImageFilter_txx #include "itkOptimalSharpeningImageFilter.h" #include "itkNeighborhoodOperatorImageFilter.h" #include "itkLaplacianOperator.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkProgressAccumulator.h" #include "itkMinimumMaximumImageCalculator.h" #include "itkImageRegionIterator.h" namespace itk { template< class TInputImage, class TOutputImage > void OptimalSharpeningImageFilter< TInputImage, TOutputImage > ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "UseImageSpacing = " << m_UseImageSpacing << std::endl; } template void OptimalSharpeningImageFilter ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError) { // call the superclass' implementation of this method. this should // copy the output requested region to the input requested region Superclass::GenerateInputRequestedRegion(); // get pointers to the input and output InputImagePointer inputPtr = const_cast< TInputImage * > ( this->GetInput() ); if ( !inputPtr ) { return; } // Build an operator so that we can determine the kernel size LaplacianOperator oper; oper.CreateOperator(); // get a copy of the input requested region (should equal the output // requested region) typename TInputImage::RegionType inputRequestedRegion; inputRequestedRegion = inputPtr->GetRequestedRegion(); // pad the input requested region by the operator radius inputRequestedRegion.PadByRadius( oper.GetRadius() ); // crop the input requested region at the input's largest possible region if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) { inputPtr->SetRequestedRegion( inputRequestedRegion ); return; } else { // Couldn't crop the region (requested region is outside the largest // possible region). Throw an exception. // store what we tried to request (prior to trying to crop) inputPtr->SetRequestedRegion( inputRequestedRegion ); // build an exception InvalidRequestedRegionError e(__FILE__, __LINE__); e.SetLocation(ITK_LOCATION); e.SetDescription("Requested region is (at least partially) outside the largest possible region."); e.SetDataObject(inputPtr); throw e; } } template< class TInputImage, class TOutputImage > void OptimalSharpeningImageFilter< TInputImage, TOutputImage > ::GenerateData() { // Create the Laplacian operator LaplacianOperator oper; double s[ImageDimension]; for (unsigned i = 0; i < ImageDimension; i++) { if (this->GetInput()->GetSpacing()[i] == 0.0 ) { itkExceptionMacro( << "Image spacing cannot be zero" ); } else { s[i] = 1.0 / this->GetInput()->GetSpacing()[i]; } } oper.SetDerivativeScalings( s ); oper.CreateOperator(); // do calculations in floating point typedef Image RealImageType; typedef NeighborhoodOperatorImageFilter NOIF; ZeroFluxNeumannBoundaryCondition nbc; typename NOIF::Pointer filter = NOIF::New(); filter->OverrideBoundaryCondition(static_cast(&nbc)); // Create a process accumulator for tracking the progress of this minipipeline ProgressAccumulator::Pointer progress = ProgressAccumulator::New(); progress->SetMiniPipelineFilter(this); // Register the filter with the with progress accumulator using // equal weight proportion progress->RegisterInternalFilter(filter,0.8f); // // set up the mini-pipline // filter->SetOperator(oper); filter->SetInput(this->GetInput()); filter->GetOutput() ->SetRequestedRegion( this->GetOutput()->GetRequestedRegion() ); // execute the mini-pipeline filter->Update(); // determine how the data will need to scaled to be properly combined typename MinimumMaximumImageCalculator::Pointer inputCalculator = MinimumMaximumImageCalculator::New(); typename MinimumMaximumImageCalculator::Pointer filteredCalculator = MinimumMaximumImageCalculator::New(); inputCalculator->SetImage(this->GetInput()); inputCalculator->SetRegion(this->GetOutput()->GetRequestedRegion()); inputCalculator->Compute(); filteredCalculator->SetImage(filter->GetOutput()); filteredCalculator->SetRegion(this->GetOutput()->GetRequestedRegion()); filteredCalculator->Compute(); RealType inputShift, inputScale, filteredShift, filteredScale; inputShift = static_cast(inputCalculator->GetMinimum()); inputScale = static_cast(inputCalculator->GetMaximum()) - static_cast(inputCalculator->GetMinimum()); filteredShift = filteredCalculator->GetMinimum(); // no need to cast filteredScale = filteredCalculator->GetMaximum() - filteredCalculator->GetMinimum(); ImageRegionIterator it(filter->GetOutput(), filter->GetOutput()->GetRequestedRegion()); ImageRegionConstIterator inIt(this->GetInput(), this->GetOutput()->GetRequestedRegion()); // combine the input and laplacian images RealType value, invalue; RealType inputSum = 0.0; RealType enhancedSum = 0.0; while ( !it.IsAtEnd() ) { value = it.Get(); // laplacian value // rescale to [0,1] value = (value - filteredShift) / filteredScale; // rescale to the input dynamic range value = value * inputScale + inputShift; // combine the input and laplacian image (note that we subtract // the laplacian due to the signs in our laplacian kernel). invalue = static_cast(inIt.Get()); value = invalue - value*this->m_SValue; it.Set( value ); inputSum += invalue; enhancedSum += value; ++it; ++inIt; } RealType inputMean = inputSum / static_cast(this->GetOutput()->GetRequestedRegion() .GetNumberOfPixels()); RealType enhancedMean = enhancedSum / static_cast(this->GetOutput()->GetRequestedRegion() .GetNumberOfPixels()); // update progress this->UpdateProgress( 0.9 ); // copy and cast the output typename TOutputImage::Pointer output = this->GetOutput(); output->SetBufferedRegion(output->GetRequestedRegion()); output->Allocate(); RealType inputMinimum = inputCalculator->GetMinimum(); RealType inputMaximum = inputCalculator->GetMaximum(); OutputPixelType castInputMinimum = static_cast(inputMinimum); OutputPixelType castInputMaximum = static_cast(inputMaximum); ImageRegionIterator outIt = ImageRegionIterator(output, output->GetRequestedRegion()); outIt.GoToBegin(); it.GoToBegin(); while (!outIt.IsAtEnd()) { value = it.Get(); // adjust value to make the mean intensities before and after match value = value - enhancedMean + inputMean; if (value < inputMinimum) { outIt.Set( castInputMinimum ); } else if (value > inputMaximum) { outIt.Set( castInputMaximum ); } else { outIt.Set( static_cast(value) ); } ++outIt; ++it; } // update progress this->UpdateProgress( 1.0 ); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkPointSetFunction.h000066400000000000000000000107511147325206600225730ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPointSetFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkPointSetFunction_h #define __itkPointSetFunction_h #include "itkFunctionBase.h" #include "itkPoint.h" #include "itkIndex.h" #include "itkContinuousIndex.h" #include "itkImageBase.h" namespace itk { /** \class PointSetFunction * \brief Evaluates a function of an image at specified position. * * PointSetFunction is a baseclass for all objects that evaluates * a function of an image at index, continuous index or point. * This class is templated over the input image type, the type * of the function output and the coordinate representation type * (e.g. float or double). * * The input image is set via method SetInputPointSet(). * Methods Evaluate, EvaluateAtIndex and EvaluateAtContinuousIndex * respectively evaluates the function at an geometric point, * image index and continuous image index. * * \warning Image BufferedRegion information is cached during * in SetInputPointSet( image ). If the image BufferedRegion has changed * one must call SetInputPointSet( image ) again to update the cache * to the current values. * * \sa Point * \sa Index * \sa ContinuousIndex * * \ingroup PointSetFunctions */ template < class TInputPointSet, class TOutput, class TCoordRep = float > class ITK_EXPORT PointSetFunction : public FunctionBase { public: /** Dimension underlying input point set. */ itkStaticConstMacro(Dimension, unsigned int, TInputPointSet::PointDimension); /** Standard class typedefs. */ typedef PointSetFunction Self; typedef FunctionBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro( PointSetFunction, FunctionBase ); /** InputPointSetType typedef support. */ typedef TInputPointSet InputPointSetType; /** InputPixel typedef support */ typedef typename InputPointSetType::PointType InputPointType; typedef typename InputPointSetType::PixelType InputPixelType; /** InputPointSetPointer typedef support */ typedef typename InputPointSetType::ConstPointer InputPointSetConstPointer; /** OutputType typedef support. */ typedef TOutput OutputType; /** CoordRepType typedef support. */ typedef TCoordRep CoordRepType; /** Set the input point set. * \warning this method caches BufferedRegion information. * If the BufferedRegion has changed, user must call * SetInputPointSet again to update cached values. */ virtual void SetInputPointSet( const InputPointSetType * ptr ); /** Get the input image. */ const InputPointSetType * GetInputPointSet() const { return m_PointSet.GetPointer(); } /** Evaluate the function at specified Point position. * Subclasses must provide this method. */ virtual TOutput Evaluate( const InputPointType& point ) const = 0; protected: PointSetFunction(); ~PointSetFunction() {} void PrintSelf(std::ostream& os, Indent indent) const; /** Const pointer to the input image. */ InputPointSetConstPointer m_PointSet; private: PointSetFunction(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk // Define instantiation macro for this template. #define ITK_TEMPLATE_PointSetFunction(_, EXPORT, x, y) namespace itk { \ _(3(class EXPORT PointSetFunction< ITK_TEMPLATE_3 x >)) \ namespace Templates { typedef PointSetFunction< ITK_TEMPLATE_3 x > PointSetFunction##y; } \ } #ifndef ITK_MANUAL_INSTANTIATION # include "itkPointSetFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkPointSetFunction.txx000066400000000000000000000032261147325206600231660ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkPointSetFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkPointSetFunction_txx #define __itkPointSetFunction_txx #include "itkPointSetFunction.h" namespace itk { /** * Constructor */ template PointSetFunction ::PointSetFunction() { m_PointSet = NULL; } /** * Standard "PrintSelf" method */ template void PointSetFunction ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "InputPointSet: " << m_PointSet.GetPointer() << std::endl; } /** * Initialize by setting the input point set */ template void PointSetFunction ::SetInputPointSet( const InputPointSetType * ptr ) { // set the input image m_PointSet = ptr; } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkSurfaceCurvatureBase.h000066400000000000000000000220451147325206600234030ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSurfaceCurvatureBase.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _SurfaceCurvatureBase_h #define _SurfaceCurvatureBase_h #include #include #include #include // #include #include "itkObject.h" #include "itkProcessObject.h" #include "itkVectorContainer.h" #include "itkCastImageFilter.h" namespace itk { /** \class SurfaceCurvatureBase * * This class takes a surface as input and creates a local * geometric frame for each surface point. * * \note The origin of a neighborhood is always taken to be * the first point entered into and the * last point stored in the list. */ template < typename TSurface, unsigned int TDimension=3 > class SurfaceCurvatureBase : public ProcessObject { public: /** Standard class typedefs. */ typedef SurfaceCurvatureBase Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(SurfaceCurvatureBase,ProcessObject); /** Method for creation through the object factory. */ itkNewMacro(Self); /** Image types. */ typedef TSurface SurfaceType; /** Image dimension. */ // itkStaticConstMacro(ImageDimension, unsigned int, TImage::ImageDimension); itkStaticConstMacro(ImageDimension, unsigned int, TDimension); itkStaticConstMacro(SurfaceDimension, unsigned int, TDimension); typedef float RealType; typedef vnl_vector VectorType; typedef vnl_vector_fixed FixedVectorType; typedef vnl_vector_fixed PointType; typedef vnl_matrix MatrixType; typedef std::vector PointContainerType; typedef std::vector FunctionContainerType; /** Set input parameter file */ itkSetStringMacro( ParameterFileName ); /** Set input parameter file */ itkGetStringMacro( ParameterFileName ); /** Fill the point list with the points neighboring the current origin */ virtual void FindNeighborhood(unsigned int temp=0); /** A Euclidean relative of L.D. Griffin's compactness.*/ RealType ComputeMeanEuclideanDistance(); /** */ void ComputeAveragePoint(); void ProjectToTangentPlane(PointType); void EigenDecomposition(MatrixType D); /** Estimate the plane tangent to a point using the neighborhood * of the point. This is, in general, an over-constrained least * squares fitting problem. */ void EstimateTangentPlane(PointType); void WeightedEstimateTangentPlane(PointType); void TestEstimateTangentPlane(PointType); /** This function sets the reference tangent arbitrarily. * It can be overridden in case there is a better practical approach. */ void ChooseReferenceTangent(); /** This function fills the weight and angle vectors for * a given neighborhood. */ virtual void ComputeWeightsAndDirectionalKappaAndAngles(PointType origin); /** */ void ComputeFrame(PointType origin); /** */ void ComputeFrameAndKappa(PointType origin); void ShimshoniFrame(PointType origin); /** */ void ComputeJoshiFrame(PointType origin); /** */ void EstimateCurvature(RealType w1=3./8.,RealType w2=1./8., RealType w3=1./8.,RealType w4=3./8.); /** Use the Besl and Jain analytical curvature computation. * We use a least square polynomial fit to the local neighborhood * to estimate the mean and gaussian curvature. */ void JainMeanAndGaussianCurvature(PointType); /** This function returns a weight given a distance * It may be the identity function, a normalization * or a gaussianization of the input distance. */ virtual RealType GetWeight(PointType, PointType); /** This function returns the angle between the reference tangent and the projection onto the tangent plane of the vector between the neighborhood focus and its neighbor. */ virtual RealType GetTheta(PointType Neighbor,PointType origin); /** Estimate the directional curvature using Shimshoni's method (eq 6).*/ virtual void EstimateDirectionalCurvature(PointType, PointType); void PrintFrame(); virtual void ComputeFrameOverDomain(unsigned int which=3) {}; RealType ErrorEstimate(PointType, RealType sign=1.0 ); unsigned int CharacterizeSurface(); itkSetMacro(Origin,PointType); itkGetMacro(Origin,PointType); itkSetMacro(AveragePoint,PointType); itkGetMacro(AveragePoint,PointType); itkGetMacro(Normal,FixedVectorType); itkGetMacro(Sigma,RealType); itkGetMacro(MeanKappa,RealType); itkSetMacro(Sigma,RealType); itkGetMacro(UseGeodesicNeighborhood,bool); itkSetMacro(UseGeodesicNeighborhood,bool); /** Set normal estimates a 3D frame from a given normal */ void SetFrameFromNormal(FixedVectorType); /** We use the cross-product of the tangents times the image spacing to get the local area. */ RealType ComputeLocalArea(const double* spacing); /** We estimate the integral as a sum, assuming the local area (from compute local area) scales the value of the function at the pixel. See http://mathworld.wolfram.com/SurfaceIntegral.html*/ virtual RealType IntegrateFunctionOverNeighborhood(bool norm=false) { return 0; } void SwitchNormalSign() { m_Normal*=(-1.0); } // for conjugate harmonic function float dstarUestimate(); // get this from the local frame - 1st order vs 2nd order shape operator void EstimateMetricTensor(); protected: SurfaceCurvatureBase(); virtual ~SurfaceCurvatureBase(){}; /** Holds the value of Pi. */ double m_Pi; bool m_Debug; /** Data structures to contain points. */ PointContainerType m_PointList; /** Data structures to contain function values associated with points. */ FunctionContainerType m_FunctionValueList; /** This list contains the projection of the vectors onto the tangent plane (T_i Shimshoni). */ PointContainerType m_TangentProjectionList; /** The point that is the origin of the current neighborhood. */ PointType m_Origin; PointType m_AveragePoint; PointType m_PlaneVector; /** Data that represents single vectors */ FixedVectorType m_ArbitraryTangent; FixedVectorType m_Normal; FixedVectorType m_Tangent1; FixedVectorType m_Tangent2; RealType m_dX; // size in local x dir RealType m_dY; // size in local y dir FixedVectorType m_MetricTensor; VectorType m_ThetaVector; VectorType m_WeightVector; VectorType m_DirectionalKappaVector; /** Data for representing neighborhoods and derived from the vector frames*/ /** Approximate directional curvature */ RealType m_DirectionalKappa; RealType m_MetricTensorDeterminant; /** Approximate principal curvature 1*/ RealType m_Kappa1; /** Approximate principal curvature 2*/ RealType m_Kappa2; RealType m_GaussianKappa; RealType m_MeanKappa; /** Solution weights eq. (7) (8) Shimshoni */ RealType m_A; RealType m_B; RealType m_C; /** True Eigenvector weights */ RealType m_W1; RealType m_W2; /** Eigenvalues */ RealType m_Eval0; RealType m_Eval1; RealType m_Eval2; unsigned int m_CurrentNeighborhoodPointIndex; std::string m_ParameterFileName; /** We use this to avoid computing the frame in degenerate cases. */ RealType m_TotalDKap; RealType m_TotalArea; RealType m_Sigma; bool m_UseGeodesicNeighborhood; private: }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSurfaceCurvatureBase.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkSurfaceCurvatureBase.txx000066400000000000000000000756311147325206600240100ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSurfaceCurvatureBase.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _SurfaceCurvatureBase_txx #define _SurfaceCurvatureBase_txx #include #include #include // #include #include #include #include #include "itkSurfaceCurvatureBase.h" namespace itk { template SurfaceCurvatureBase ::SurfaceCurvatureBase() { m_Origin.fill(0.0); m_ArbitraryTangent.fill(0.); m_Normal.fill(0.); m_Tangent1.fill(0.); m_Tangent2.fill(0.); m_DirectionalKappa=0.0; m_Kappa1=0.0; m_Kappa2=0.0; m_GaussianKappa=0.0; m_A=0.0; m_B=0.0; m_C=0.0; m_W1=3./8.; m_W2=1./8.; m_Eval0=0.0; m_Eval1=0.0; m_Eval2=0.0; m_CurrentNeighborhoodPointIndex=0; m_ParameterFileName = ""; m_Pi= 3.14159265358979323846; m_Debug=true; m_Debug=false; m_UseGeodesicNeighborhood=false; m_TotalArea=0.0; } template void SurfaceCurvatureBase ::ComputeAveragePoint() { m_AveragePoint.fill(0.0); unsigned int npts = m_PointList.size(); unsigned int dim = SurfaceDimension; for (unsigned int i =0; i void SurfaceCurvatureBase ::ProjectToTangentPlane(PointType dif) { MatrixType id(ImageDimension,ImageDimension); id.fill(0.0); unsigned int i=0,j=0; MatrixType NN(ImageDimension,ImageDimension); for (i=0; i void SurfaceCurvatureBase ::SetFrameFromNormal(FixedVectorType N) { // WORKS ONLY FOR 3D! RealType mag=N.magnitude(); if (mag != 0.0) m_Normal=N/mag; else { m_Tangent1.fill(0.0); m_Tangent2.fill(0.0); return; } // now estimate the tangent plane if (fabs(m_Normal[0]) > 1.e-1) { float norm=1./m_Normal[0]; m_Tangent1[1]=norm*N[0]; m_Tangent1[0]=-1.*norm*(N[1]+N[2]); m_Tangent1[2]=norm*N[0]; } else if (fabs(m_Normal[1]) > 1.e-1) { float norm=1./m_Normal[1]; m_Tangent1[0]=norm*N[1]; m_Tangent1[1]=-1.*norm*(N[0]+N[2]); m_Tangent1[2]=norm*N[1]; } else if (fabs(m_Normal[2]) > 1.e-1) { float norm=1./m_Normal[2]; m_Tangent1[0]=norm*N[2]; m_Tangent1[2]=-1.*norm*(N[0]+N[1]); m_Tangent1[1]=norm*N[2]; } m_Tangent1/=m_Tangent1.magnitude(); m_Tangent2=vnl_cross_3d(m_Normal,m_Tangent1); m_Tangent2/=m_Tangent2.magnitude(); this->ChooseReferenceTangent(); } template void SurfaceCurvatureBase ::EigenDecomposition(MatrixType D) { // Compute estimated frame using eigensystem of D'*D { vnl_symmetric_eigensystem eig(D.transpose() * D); for (unsigned int j=0; jSetFrameFromNormal(m_Normal); m_Eval0=eig.get_eigenvalue(0); m_Eval1=eig.get_eigenvalue(1); m_Eval2=eig.get_eigenvalue(2); if (m_Debug){ vnl_vector a = eig.get_eigenvector(0); vcl_cout << "Eig residual = " << (D * a).magnitude() << vcl_endl; a = eig.get_eigenvector(1); vcl_cout << "Eig residual = " << (D * a).magnitude() << vcl_endl; a = eig.get_eigenvector(2); vcl_cout << "Eig residual = " << (D * a).magnitude() << vcl_endl; } } } template void SurfaceCurvatureBase::EstimateTangentPlane(PointType origin) { // Build cov matrix D unsigned int npts = m_PointList.size()-1; unsigned int dim = SurfaceDimension; MatrixType D(npts, dim); for (unsigned int i =0; iEigenDecomposition(D); m_dX=m_Tangent1.magnitude(); m_dY=m_Tangent2.magnitude(); m_Tangent1/=m_dX; m_Tangent2/=m_dY; this->ChooseReferenceTangent(); } template void SurfaceCurvatureBase::WeightedEstimateTangentPlane(PointType origin) { // Build cov matrix D RealType twi=0.0; unsigned int npts = m_PointList.size()-1; unsigned int dim = SurfaceDimension; MatrixType D(npts, dim); for (unsigned int i =0; iEigenDecomposition(D/twi); this->ChooseReferenceTangent(); } template void SurfaceCurvatureBase::ComputeFrame(PointType origin) { // Build cov matrix D unsigned int npts = m_PointList.size()-1; unsigned int dim = SurfaceDimension; RealType twi=1.,wi=0.; MatrixType D; bool method1=true; if (method1){ twi=0.0; D.set_size(dim, dim); D.fill(0.0); for (unsigned int i =0; iEigenDecomposition(D/twi); this->ChooseReferenceTangent(); } template void SurfaceCurvatureBase::ComputeFrameAndKappa(PointType origin) { // Build cov matrix D unsigned int npts = m_PointList.size()-1; unsigned int dim = SurfaceDimension; /* if (m_TotalDKap/(float)m_PointList.size() < 0.05) { m_Kappa1=0.0; m_Kappa2=0.0; m_A=0.; m_B=0.; m_C=0.0; m_GaussianKappa=0.0; m_TotalDKap=0.0; return; } */ MatrixType D; // dim=2; D.set_size(dim, dim); D.fill(0.0); for (unsigned int i =0; i eig(D.transpose() * D); m_Eval0=eig.get_eigenvalue(0); m_Eval1=eig.get_eigenvalue(1); m_Eval2=eig.get_eigenvalue(2); } template void SurfaceCurvatureBase ::ShimshoniFrame(PointType origin) { this->ComputeWeightsAndDirectionalKappaAndAngles(origin); this->ComputeFrameAndKappa(origin); this->EstimateCurvature(m_A,m_B,m_B,m_C); // this->EstimateCurvature(); } template void SurfaceCurvatureBase ::JainMeanAndGaussianCurvature(PointType origin) { // Build cov matrix D unsigned int npts = m_PointList.size()-1; if (npts < 7) { m_MeanKappa = 0; m_GaussianKappa = 0; m_Kappa1 = 0; m_Kappa2 = 0; return; } vnl_vector dists(npts); vnl_vector wts(npts); MatrixType D; D.set_size(npts,6); // each row contains [u^2 , uv, v^2, u, v, 1] for point p D.fill(0.0); float totwt=0.0; float wt=0.0; bool robust=true; robust=false; unsigned int i=0; for (i =0; i 0) dists/=totwt; } vnl_svd svd(D); vnl_vector a = svd.solve(dists); // std::cout << " a vec " << a << std::endl; // for (int tt=0; tt<6; tt++) // if (a[tt] < 1.e-6) a[tt]=0.0; /* double fu = a(0); //a(3); double fv = a(2); //a(4); double fuu = a(3); //2.*a(0); double fuv = a(1); //a(1); double fvv = a(4); //2.*a(2); */ double fu = a(3); double fv = a(4); double fuu = 2.*a(0); double fuv = a(1); double fvv = 2.*a(2); m_MeanKappa = (1.0 + fv*fv)*fuu - 2.0*fu*fv*fuv + (1.0 + fu*fu)*fvv; m_MeanKappa /= (2.0 * pow ( 1.0 + fu*fu + fv*fv , 1.5)); m_GaussianKappa = (fuu * fvv - fuv*fuv) / (( 1.0 + fu*fu + fv*fv )*( 1.0 + fu*fu + fv*fv )); m_Kappa1 = m_MeanKappa + sqrt( m_MeanKappa*m_MeanKappa - m_GaussianKappa ); m_Kappa2 = m_MeanKappa - sqrt( m_MeanKappa*m_MeanKappa - m_GaussianKappa ); if (origin[0]==20 && origin[1]==65 && origin[2]==39) { std::cout << " surf params " << a << std::endl; std::cout << " k1 " << m_Kappa1 << " k2 " << m_Kappa2 << std::endl; this->PrintFrame(); for (unsigned int jj=0; jj < npts; jj++) { std::cout << " point " << m_PointList[jj]; std::cout << " dist " << dists[jj] << std::endl; } } // NOTE: THIS IS THE ERROR ESTIMATE // vcl_cout << "SVD residual = " << (D * a).magnitude() << vcl_endl; // vcl_cout << " a " << a << vcl_endl; // MatrixType C(2,2); // C(0,0)=a(0); C(1,0)=a(1); C(0,1)=a(1); C(1,1)=a(2); // vnl_symmetric_eigensystem eig(C); // m_Kappa1=eig.get_eigenvalue(0); // m_Kappa2=eig.get_eigenvalue(1); // // m_MeanKappa=0.5*(m_Kappa1+m_Kappa2); // m_GaussianKappa = m_Kappa1*m_Kappa2; // // std::cout << " eval 0 " << m_Kappa1 << " eval 1 " << m_Kappa2 << std::endl; return; } // end jain frame template void SurfaceCurvatureBase ::ComputeJoshiFrame(PointType origin) { // Build cov matrix D unsigned int npts = m_PointList.size()-1; if (npts < 5) { m_MeanKappa = 0; m_GaussianKappa = 0; m_Kappa1 = 0; m_Kappa2 = 0; return; } vnl_vector dists(npts); MatrixType D; D.set_size(npts,3); D.fill(0.0); float totw=0; for (unsigned int i =0; i svd(D); vnl_vector c = svd.solve(dists); // NOTE: THIS IS THE ERROR ESTIMATE // vcl_cout << "SVD residual = " << (D * c).magnitude() << vcl_endl; // vcl_cout << " C " << c << vcl_endl; MatrixType C(2,2); C(0,0)=c(0); C(1,0)=c(1); C(0,1)=c(1); C(1,1)=c(2); vnl_symmetric_eigensystem eig(C); m_Kappa1=eig.get_eigenvalue(0); m_Kappa2=eig.get_eigenvalue(1); m_MeanKappa=0.5*(m_Kappa1+m_Kappa2); m_GaussianKappa = m_Kappa1*m_Kappa2; // std::cout << " eval 0 " << m_Kappa1 << " eval 1 " << m_Kappa2 << std::endl; } template typename SurfaceCurvatureBase::RealType SurfaceCurvatureBase ::ComputeLocalArea(const double* spacing) { PointType t1; PointType t2; for (unsigned int i=0; i< SurfaceDimension; i++) { t1[i]=m_Tangent1[i]*spacing[i]; t2[i]=m_Tangent2[i]*spacing[i]; } PointType temp=vnl_cross_3d( t1,t2); return temp.magnitude(); } template unsigned int SurfaceCurvatureBase ::CharacterizeSurface() { float th=1.e-6; if (fabs(m_GaussianKappa) < th*th) m_GaussianKappa=0.0; if (fabs(m_MeanKappa) < th) m_MeanKappa=0.0; if (m_MeanKappa > 0 && m_GaussianKappa > 0 ) return 8; else if (m_MeanKappa > 0 && m_GaussianKappa == 0) return 7; else if (m_MeanKappa > 0 && m_GaussianKappa < 0) return 6; else if (m_MeanKappa ==0 && m_GaussianKappa == 0) return 5; else if (m_MeanKappa ==0 && m_GaussianKappa < 0) return 4; else if (m_MeanKappa < 0 && m_GaussianKappa > 0) return 3; else if (m_MeanKappa < 0 && m_GaussianKappa == 0) return 2; else if (m_MeanKappa < 0 && m_GaussianKappa < 0) return 1; else return 0; } template typename SurfaceCurvatureBase::RealType SurfaceCurvatureBase ::ComputeMeanEuclideanDistance() { double totdist=0.0; unsigned int ct=0; unsigned int pls=m_PointList.size(); for (unsigned int i=0; i< pls; i++) { for (unsigned int j=0; j< pls; j++) { PointType p = m_PointList[j]-m_PointList[i]; totdist+=p.magnitude(); ct++; } } RealType meandist=totdist/(float)ct; // 4 pi r^2 = a, r^2 = a/(4pi) RealType spheremeandist=1.0;//sqrt((float)ct/(4.0*3.1418)); RealType compactness=meandist/spheremeandist; return 10.-compactness; } template void SurfaceCurvatureBase::TestEstimateTangentPlane(PointType origin) { // Read points from stdin MatrixType pts; std::cout << " input points " << std::endl; vcl_cin >> pts; // Build cov matrix D int npts = pts.rows(); int dim = pts.columns(); MatrixType D(npts, dim); // get average of points RealType count=0.0; PointType avgpt; avgpt.fill(0); for(unsigned int i = 0; i < npts; i++) { for(unsigned int j = 0; j < dim; j++) { avgpt(j)+=pts(i,j); count+=1.0; } } avgpt/=count; if (m_Debug) std::cout << " avg " << avgpt << std::endl; origin=avgpt; for(unsigned int i = 0; i < npts; i++) { for(unsigned int j = 0; j < dim; j++) D(i,j) = (pts(i,j)-origin(j))*(pts(i,j)-origin(j)); //D(i,dim) = 1; } // 1. Compute using SVD { vnl_svd svd(D); vnl_vector a = svd.nullvector(); vcl_cout << "SVD residual = " << (D * a).magnitude() << vcl_endl; vcl_cout << "SVD normal " << a << vcl_endl; } // 2. Compute using eigensystem of D'*D { vnl_symmetric_eigensystem eig(D.transpose() * D); vnl_vector a = eig.get_eigenvector(0); vcl_cout << "Eig residual = " << (D * a).magnitude() << vcl_endl; vcl_cout << " normal " << eig.get_eigenvector(0) << vcl_endl; vcl_cout << "Eigvec 1 " << eig.get_eigenvector(1) << vcl_endl; vcl_cout << "Eigvec 2 " << eig.get_eigenvector(2) << vcl_endl; vcl_cout << "Eigval normal " << eig.get_eigenvalue(0) << vcl_endl; vcl_cout << "Eigval 1 " << eig.get_eigenvalue(1) << vcl_endl; vcl_cout << "Eigval 2 " << eig.get_eigenvalue(2) << vcl_endl; } } template void SurfaceCurvatureBase::FindNeighborhood(unsigned int temp) { // Read points from stdin MatrixType pts; std::cout << " input points " << std::endl; vcl_cin >> pts; // Build cov matrix D unsigned int npts = pts.rows(); unsigned int dim = pts.columns(); m_AveragePoint.fill(0.0); for(unsigned int i = 0; i < npts; i++) { PointType pt; for(unsigned int j = 0; j < dim; j++) { pt(j)=pts(i,j); m_AveragePoint[j]+=pts(i,j); } if (i==0) m_Origin=pt; m_PointList.insert(m_PointList.begin(),pt); } m_AveragePoint/=(RealType)npts; if (m_Debug) { std:: cout << " point list size " << m_PointList.size() << std::endl; for(unsigned int i = 0; i < m_PointList.size(); i++) { std:: cout << " point " << m_PointList[i]; } std::cout << std::endl; } } /** This function sets the reference tangent arbitrarily. * It can be overridden in case there is a better practical approach. */ template void SurfaceCurvatureBase::ChooseReferenceTangent() { float w=1.; float w2=(1.0-w); //m_ArbitraryTangent[0]=w; m_ArbitraryTangent[1]=1.-w; m_ArbitraryTangent[2]=0.; m_ArbitraryTangent=w*m_Tangent2+(w2*m_Tangent1); m_ArbitraryTangent/=m_ArbitraryTangent.magnitude(); if (m_Debug) std::cout << " arb tan " << m_ArbitraryTangent << std::endl; } template void SurfaceCurvatureBase ::ComputeWeightsAndDirectionalKappaAndAngles(PointType origin) { unsigned int sz = m_PointList.size(); if (sz > 1 ) sz=sz-1; m_TangentProjectionList.clear(); m_DirectionalKappaVector.set_size(sz); m_DirectionalKappaVector.fill(0.0); m_WeightVector.set_size(sz); m_WeightVector.fill(0.0); m_ThetaVector.set_size(sz); m_ThetaVector.fill(0.0); RealType theta=0, w1=0,w2=0,totalWeight=0.0; RealType difMag=0,sqdifMag=0; m_TotalDKap=0.0; m_A=0.0; m_B=0.0; m_C=0.0; for (unsigned int ii=0; ii typename SurfaceCurvatureBase::RealType SurfaceCurvatureBase::GetWeight(PointType p1, PointType p2) { PointType d = p1 - p2; return d.magnitude(); } /** This function returns the angle between the reference tangent and the projection onto the tangent plane of the vector between the neighborhood focus and its neighbor. */ template typename SurfaceCurvatureBase::RealType SurfaceCurvatureBase ::GetTheta(PointType Q, PointType origin) { RealType theta=0.0; PointType Dif=Q-origin; // float dm=Dif.magnitude(); // if (dm==0) dm=1.0; // Dif/=dm; float u1=0.0; float u2=0.0; for (unsigned int i=0; i void SurfaceCurvatureBase ::EstimateDirectionalCurvature(PointType Q, PointType P) { PointType Dif=Q-P; m_DirectionalKappa=0.0; for (unsigned int i=0; i void SurfaceCurvatureBase ::EstimateCurvature(RealType w1, RealType w2,RealType w3, RealType w4) { /* if (m_TotalDKap/(float)m_PointList.size() < 0.05) { m_Kappa1=0.0; m_Kappa2=0.0; m_A=0.; m_B=0.; m_C=0.0; m_GaussianKappa=0.0; m_TotalDKap=0.0; return; }*/ RealType denom=(w4-w2*w3/w1); if (fabs(denom) > 1.e-12) m_Kappa2=(m_Eval2-m_Eval1*w3/w1)/denom; else { w1=m_W1; w2=m_W2; w3=m_W2; w4=m_W1; denom=(w4-w2*w3/w1); m_Kappa2=(m_Eval2-m_Eval1*w3/w1)/denom; } m_Kappa1=(m_Eval1-w2*m_Kappa1)/w1; m_MeanKappa=0.5*(m_Kappa1+m_Kappa2); m_GaussianKappa = m_Kappa1*m_Kappa2; // std::cout << " eval test " << w1*m_Kappa1 + w2*m_Kappa2 << " e1 " << m_Eval1 << std::endl; // std::cout << " eval test " << w3*m_Kappa1 + w4*m_Kappa2 << " e2 " << m_Eval2 << std::endl; } /** */ template void SurfaceCurvatureBase ::PrintFrame() { std::cout << " normal " << m_Normal << std::endl; std::cout << " t1 " << m_Tangent1 << std::endl; std::cout << " t2 " << m_Tangent2 << std::endl; std::cout << " k1 " << m_Kappa1 << " k2 " << m_Kappa2 << std::endl; std::cout << " e0 " << m_Eval0 << " e1 " << m_Eval1 << " e2 " << m_Eval2 < typename SurfaceCurvatureBase::RealType SurfaceCurvatureBase ::ErrorEstimate(PointType origin, RealType sign) { unsigned int npts = m_PointList.size()-1; unsigned int dim = SurfaceDimension; // float error=0.0; float toterror=0.0; double qpt=0.0; double qpnkpt=0.0; double costheta; double sintheta; double kp; RealType theta; PointType Q,est; for (unsigned int pp =0; ppGetTheta(Q,origin); costheta=cos(theta); sintheta=sin(theta); kp=m_Kappa1*costheta*costheta+m_Kappa2*sintheta*sintheta; if (kp != 0.0) { PointType qp=Q-origin; FixedVectorType normal=m_Normal*sign; float w1=0,w2=0; for(unsigned int j = 0; j < dim; j++) { qpt+=qp[j]*normal[j]*kp; w1+=qp[j]*m_Tangent1[j]; w2+=qp[j]*m_Tangent2[j]; qpnkpt+=qp[j]*m_PlaneVector[j]; } vnl_vector f2(4); f2(0) = 0.5*kp*kp; f2(1) = 0.0; f2(2) = 1. - qpnkpt; f2(3) = -1.* qpt; /** commenting out until we can get vnl_rpoly_roots working vnl_rpoly_roots roots(f2); // Evaluate results //vnl_real_polynomial p(f2); //for(unsigned int i = 0; i < p.degree(); i++) // vnl_test_assert("Root residual", vcl_abs(p.evaluate(roots[i])) < 1e-12); float minrel=9.e9; float mins=0.0; float s=0.0; vnl_vector so=roots.real(); // for (s=0.1; s<=2.0; s=s+.01) for (unsigned int ind=0; ind void SurfaceCurvatureBase ::EstimateMetricTensor() { float a=0; for (unsigned int i=0; i<3;i++) a+=m_Tangent1[i]*m_Tangent1[i]; m_MetricTensor[0]=a; float b=0; for (unsigned int i=0; i<3;i++) b+=m_Tangent2[i]*m_Tangent1[i]; m_MetricTensor[1]=b; float c=0; for (unsigned int i=0; i<3;i++) c+=m_Tangent2[i]*m_Tangent2[i]; m_MetricTensor[2]=c; m_MetricTensorDeterminant = sqrt(a*c-b*b); if (m_MetricTensorDeterminant < 0.0) std::cout << "bad metric tensor "; } template float SurfaceCurvatureBase ::dstarUestimate() { //this->FindNeighborhood(); make sure this also fills the function values functionvaluelist this->EstimateTangentPlane(m_Origin); // below, basically replace the heights with the function values // Build cov matrix D int npts = m_PointList.size(); int dim = SurfaceDimension; if (npts < 4) { return 0.0; } vnl_vector dists(npts); vnl_vector surfx(npts); vnl_vector surfy(npts); vnl_vector surfz(npts); vnl_vector funcvals(npts); vnl_vector wts(npts); MatrixType D; D.set_size(npts,3); // each row contains [ u, v, 1] for point p D.fill(0.0); float totwt=0.0; float totfunc=0.0; float wt=0.0; float meanu1=0; float meanu2=0; unsigned int i=0; for (i =0; imeanu2) mx=meanu1; else mx=meanu2; meanu1/=mx;meanu2/=mx; vnl_svd svd(D); float aa,bb,cc; vnl_vector a = svd.solve(surfx); vnl_vector b = svd.solve(surfy); vnl_vector c = svd.solve(surfz); double fu = a(0); double fv = a(1); aa=a(0)*a(0)+b(0)*b(0)+c(0)*c(0); bb=a(1)*a(0)+b(1)*b(0)+c(1)*c(0); cc=a(1)*a(1)+b(1)*b(1)+c(1)*c(1); vnl_vector func = svd.solve(funcvals); double Ux=func(0); double Uy=func(1); float dx=meanu1;//m_dX;//m_Eval1;//m_dX; float dy=meanu2;//m_dY;//m_Eval2;//m_dY; m_MetricTensor[0]=aa; m_MetricTensor[1]=bb; m_MetricTensor[2]=cc; float denom=sqrt(aa*cc-bb*bb); // denom=1.0; // std::cout << " denom " << denom << " dx " << dx << " dy " << dy << std::endl; //std::cout << " a " << aa << " b " << bb << " c " << cc << std::endl; float dstarU = 1.0/denom*( (bb*Ux - aa*Uy)*dx + (cc*Ux - bb*Uy)*dy ); //std::cout << " dstarU " << dstarU << std::endl; return dstarU; } } // namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkSurfaceImageCurvature.h000066400000000000000000000164051147325206600235560ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSurfaceImageCurvature.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _SurfaceImageCurvature_h #define _SurfaceImageCurvature_h #include "itkNeighborhoodIterator.h" #include "itkSurfaceCurvatureBase.h" #include "itkGradientRecursiveGaussianImageFilter.h" #include "itkGradientImageFilter.h" namespace itk { /** \class SurfaceImageCurvature * * This class takes a surface as input and creates a local * geometric frame for each surface point. * * */ template < typename TSurface > class SurfaceImageCurvature : public SurfaceCurvatureBase < TSurface , 3 > { public: /** Standard class typedefs. */ typedef SurfaceImageCurvature Self; typedef SurfaceCurvatureBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(SurfaceImageCurvature,SurfaceCurvatureBase); /** Method for creation through the object factory. */ itkNewMacro(Self); /** Image related types. */ typedef typename TSurface::PixelType PixelType; enum { ImageDimension = TSurface::ImageDimension }; typedef Image ImageType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::SizeType SizeType; typedef ImageRegionIteratorWithIndex ImageIteratorType; /** Image dimension. */ itkStaticConstMacro(SurfaceDimension, unsigned int, TSurface::ImageDimension); typedef typename Superclass::RealType RealType; typedef typename Superclass::PointType VectorType; typedef typename Superclass::PointType FixedVectorType; typedef typename Superclass::PointType PointType; typedef typename Superclass::MatrixType MatrixType; typedef Image OutputImageType; typedef ImageRegionIteratorWithIndex OutputImageIteratorType; typedef typename OutputImageType::Pointer OutputImagePointer; typedef Image FrameImageType; /** Gradient filtering */ typedef CovariantVector GradientPixelType; typedef Image GradientImageType; typedef SmartPointer GradientImagePointer; typedef GradientRecursiveGaussianImageFilter< OutputImageType,GradientImageType > GradientImageFilterType; typedef GradientImageFilter< OutputImageType > GradientImageFilterType2; typedef typename GradientImageFilterType::Pointer GradientImageFilterPointer; typedef NeighborhoodIterator NeighborhoodIteratorType; /** Find all points within some distance of the origin. * The argument gives the number of times to apply the * mean shift algorithm to find the best neighborhood. */ void FindNeighborhood(unsigned int numMeanShifts=0); void FindEuclideanNeighborhood(PointType p); void FindGeodesicNeighborhood(); /** This applies one of the algorithms for finding the local curvature and frame. The default is joshi. */ void ComputeFrameOverDomain(unsigned int which=0); ImageType* GetInput(); void SetInput(typename ImageType::Pointer input); OutputImageType* GetOutput(); /** Apply the level set curvature equation over the whole image */ void LevelSetMeanCurvature(); /** Use the gradient of the image to estimate the normals everywhere. * Also compute area, if boolean is set. */ void EstimateNormalsFromGradient(); /** Use the Weingarten map to estimate the curvature.*/ void WeingartenMap(); /** Computes a neighborhood surface area function everywhere*/ void ComputeSurfaceArea(); /** Use the gradient estimated normal to get the local frame. Requires call to SetNormal to find tangents. */ void EstimateFrameFromGradient(IndexType); /** Implemented version of virtual function from parent class. Here, we just sum the computed function, held in CurvatureImage, over a neighborhood */ RealType IntegrateFunctionOverNeighborhood(bool norm=false); /** Get the neighborhood integral for every surface point.*/ RealType IntegrateFunctionOverSurface(bool norm=false); /** Postprocess the curvature function by, e.g., gaussian smoothing of the curvature (and perhaps frame) in the local neighbhorhood. */ void PostProcessGeometry(); itkSetMacro(NeighborhoodRadius,RealType); itkGetMacro(NeighborhoodRadius,RealType); itkSetMacro(UseLabel,bool); itkGetMacro(UseLabel,bool); itkSetMacro(kSign,float); itkSetMacro(Sigma,float); itkSetMacro(Threshold,float); itkGetMacro(FunctionImage,OutputImagePointer); itkSetMacro(FunctionImage,OutputImagePointer); void ProcessLabelImage(); float CurvatureAtIndex(IndexType index) { PointType p; for (unsigned int k=0; kSetOrigin(p); this->EstimateFrameFromGradient(index); this->FindNeighborhood(); this->WeingartenMap(); float fval=this->m_GaussianKappa; float kpix; fval=this->m_MeanKappa; if (fabs(fval) > 1) fval/=fval; kpix=kpix+m_kSign*fval; return kpix; } inline bool IsValidSurface(PixelType pix, IndexType ind) { // std::cout << "m_UseLabel "<< m_UseLabel << " pix " << pix << " Thresh " << m_Threshold << " ind " << ind << std::endl; if (this->m_UseLabel) { if ( pix == this->m_SurfaceLabel ) return true; else return false; } else { if (pix > this->m_Threshold ) return true; else return false; } } protected: SurfaceImageCurvature(); ~SurfaceImageCurvature(){}; void CopyImageToFunctionImage( OutputImagePointer,OutputImagePointer); /** This function changes the values of the label image for use with the fast marching image filter. */ private: PixelType m_SurfaceLabel; OutputImagePointer m_FunctionImage; RealType m_NeighborhoodRadius; SizeType m_ImageSize; GradientImagePointer m_GradientImage; NeighborhoodIteratorType m_ti; NeighborhoodIteratorType m_ti2; bool m_UseLabel; float m_kSign; float m_Sigma; float m_Threshold; }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSurfaceImageCurvature.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkSurfaceImageCurvature.txx000066400000000000000000001021441147325206600241460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSurfaceImageCurvature.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _SurfaceImageCurvature_txx #define _SurfaceImageCurvature_txx #include #include "itkSurfaceImageCurvature.h" //#include "itkLevelSetCurvatureFunction.h" #include "itkCastImageFilter.h" #include "itkDiscreteGaussianImageFilter.h" #include #include #include namespace itk { /** Quick node class to help get the geodesic neighborhood */ template < typename TSurface > class GeodesicNode { public: /** Image related types. */ typedef TSurface ImageType; typedef typename ImageType::IndexType IndexType; unsigned long neighborhoodindex; float distance; bool connected; IndexType imageindex; GeodesicNode() { distance=0.0; connected=false; neighborhoodindex=0; } GeodesicNode(unsigned long i, float d, bool t, IndexType ind) { distance=d; connected=t; neighborhoodindex=i; imageindex=ind; } ~GeodesicNode(){} }; template class GeodesicNodePriority /* defines the comparison operator for the prioritiy queue */ { public: bool operator() ( pclass N1, pclass N2) { return N1.distance > N2.distance; } }; template SurfaceImageCurvature ::SurfaceImageCurvature() { // outputs are curvature image and normal image this->ProcessObject::SetNumberOfRequiredOutputs( 2 ); m_SurfaceLabel=1; m_GradientImage=NULL; m_UseLabel=false; m_kSign=-1.0; m_FunctionImage=NULL; m_Sigma=1.0; } template void SurfaceImageCurvature::ProcessLabelImage() { ImageType* image=GetInput(); if (!image) return; IndexType index; typename ImageType::RegionType requestedRegion; m_ImageSize=image->GetLargestPossibleRegion().GetSize(); ImageIteratorType ti( image, image->GetLargestPossibleRegion() ); ti.GoToBegin(); while(!ti.IsAtEnd() ) { PixelType pix=ti.Get(); index=ti.GetIndex(); if (ti.Get() == 2 ) { ti.Set(m_SurfaceLabel); } else ti.Set(0); ti.Set(0); // if (index[0] == 20 && index[1] < 100 && index[2] < 100) ti.Set(m_SurfaceLabel); float rad=23,d=0; IndexType cind={{120,120,80}}; for (unsigned int j=0; j void SurfaceImageCurvature::FindEuclideanNeighborhood (typename SurfaceImageCurvature::PointType rootpoint) { //Superclass::FindNeighborhood(); this->m_AveragePoint=this->m_Origin; this->m_PointList.insert(this->m_PointList.begin(),this->m_Origin); typename ImageType::SizeType rad; IndexType oindex,index; long offset=0; for (unsigned int i=0; iIsValidSurface(pix,index)) { PointType p; float dist=0.0; bool isorigin=true; for (unsigned int k=0; km_Origin[k])*(p(k)-this->m_Origin[k]); } dist=sqrt(dist); if (!isorigin && dist <= (m_NeighborhoodRadius)) { this->m_AveragePoint=this->m_AveragePoint+p; this->m_PointList.insert(this->m_PointList.begin(),p); } } } unsigned int npts=this->m_PointList.size(); if (npts > 0) this->m_AveragePoint/=(RealType)npts; else this->m_AveragePoint=this->m_Origin; if (this->m_Debug) { std:: cout << " point list size " << this->m_PointList.size() << std::endl; // for(int i = 0; i < this->m_PointList.size(); i++) { // std:: cout << " point " << this->m_PointList[i]; // } std::cout << std::endl; } } template void SurfaceImageCurvature::FindGeodesicNeighborhood() { typedef std::priority_queue < GeodesicNode , std::vector< GeodesicNode >, GeodesicNodePriority< GeodesicNode > > QType; QType nodeq; std::map > nodes; this->m_AveragePoint=this->m_Origin; this->m_PointList.insert(this->m_PointList.begin(),this->m_Origin); typename ImageType::SizeType rad; IndexType oindex,index; float dist=0.0; unsigned int k=0; unsigned long longindex=0; long offset=0; for (unsigned int i=0; im_Origin[i]+0.5); } index=oindex; for (k=0; k gnode(longindex,0.0,true,oindex); nodes[longindex]=gnode; nodeq.push(gnode); float lastdist=0.0; //if ( this->m_Origin[1]==146 && this->m_Origin[0] > 167 ) //if ( this->m_Origin[1]==146 && this->m_Origin[0] == 168 && this->m_Origin[2]==215) //{ //std::cout << " origin " << this->m_Origin << std::endl; //} while( !nodeq.empty() && lastdist <= m_NeighborhoodRadius) { GeodesicNode g=nodeq.top(); lastdist=g.distance; PointType q; // if ( g.distance < 2.0) // { // this->m_PointList.insert(this->m_PointList.begin(),q); // nodes[g.neighborhoodindex].connected=true; // } // else if ( lastdist <= m_NeighborhoodRadius) { m_ti2.SetLocation(g.imageindex); for (unsigned int jj=0; jjIsValidSurface( m_ti2.GetPixel(jj) ,index) && index[0] < m_ImageSize[0]-m_NeighborhoodRadius && index[0] > m_NeighborhoodRadius && index[1] < m_ImageSize[1]-m_NeighborhoodRadius && index[1] > m_NeighborhoodRadius && index[2] < m_ImageSize[2]-m_NeighborhoodRadius && index[2] > m_NeighborhoodRadius ) { longindex=0; dist=0; for (k=0; km_Origin[1]==146 && this->m_Origin[0] == 168 && this->m_Origin[2]==215) //{ // std::cout << " testing point " << index << " longind " << longindex << " dist " << dist << // " bool " << nodes[longindex].connected << std::endl; //} // if (!nodes[longindex].connected ) //&& !nodes[g.neighborhoodindex].connected) if ( !nodes[longindex].connected && (dist+lastdist) <= m_NeighborhoodRadius) { GeodesicNode gnode(longindex,dist+lastdist,true,index); // GeodesicNode gnode(longindex,dist,true,index); nodes[longindex]=gnode; nodeq.push(gnode); //if ( this->m_Origin[1]==146 && this->m_Origin[0] == 168 && this->m_Origin[2]==215) ///{ // std::cout << " inserting point " << index << std::endl; //} this->m_PointList.insert(this->m_PointList.begin(),q); this->m_AveragePoint=this->m_AveragePoint+q; } // else if ( dist > 0 && dist+lastdist < nodes[longindex].distance ) // { // nodes[longindex].distance=dist+lastdist; // } } } } nodeq.pop(); } this->m_AveragePoint=this->m_AveragePoint/((float)this->m_PointList.size()); } template void SurfaceImageCurvature::FindNeighborhood(unsigned int numMeanShifts) { if (this->m_UseGeodesicNeighborhood) { this->FindGeodesicNeighborhood(); } else { this->FindEuclideanNeighborhood(this->GetOrigin()); for (unsigned int dd=0; dd< numMeanShifts; dd++) { this->m_PointList.clear(); this->FindEuclideanNeighborhood(this->GetAveragePoint()); } } /* if (this->m_Origin[0]==170 && this->m_Origin[1]==137 && this->m_Origin[2]==81) if ( this->m_Origin[1]==146 && this->m_Origin[0] > 167 ) { std::cout << " origin " << this->m_Origin << std::endl; for (unsigned int tt=0; ttm_PointList.size()-1; tt++) { PointType p=this->m_Origin-this->m_PointList[tt]; float dist = p.magnitude(); std::cout << " pt dist " << dist << " point " << this->m_PointList[tt] << std::endl; } } */ } template void SurfaceImageCurvature ::LevelSetMeanCurvature() { /* ImageType* image=GetInput(); if (!image) return; IndexType index; typename ImageType::RegionType requestedRegion; this->m_ImageSize=image->GetLargestPossibleRegion().GetSize(); ImageIteratorType ti( image, image->GetLargestPossibleRegion() ); // Define a level set curvature calculator typedef LevelSetCurvatureFunction CurvatureType; typename CurvatureType::Pointer inCurvature = CurvatureType::New(); inCurvature->SetInputImage( image ); ti.GoToBegin(); while(!ti.IsAtEnd() ) { index=ti.GetIndex(); //if (ti.Get() == this->m_SurfaceLabel) if(this->IsValidSurface(ti.Get(),index)) { double curvature = inCurvature->EvaluateAtIndex( index ); this->m_FunctionImage->SetPixel(index,fabs(curvature)); } ++ti; } */ } template void SurfaceImageCurvature ::EstimateNormalsFromGradient() { typename ImageType::Pointer image=GetInput(); std::cout << " compute normals " << this->m_Sigma << " hood " << (this->m_NeighborhoodRadius) << " spacing " << image->GetSpacing() << std::endl; if (!image) return; typename ImageType::SizeType rad; typename ImageType::SizeType rad2; for (unsigned int t=0; tm_NeighborhoodRadius); rad2[t]=1; } this->m_ti.Initialize( rad , image, image->GetLargestPossibleRegion()); this->m_ti2.Initialize( rad2 , image, image->GetLargestPossibleRegion()); typedef itk::ImageRegionIteratorWithIndex IteratorType; IteratorType Iterator( image,image->GetLargestPossibleRegion().GetSize() ); bool wmgmcurv=true; Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { float pix=Iterator.Get(); if (pix !=0 && pix != 1 && pix != 2) wmgmcurv=false; ++Iterator; } wmgmcurv=false; std::cout << " Using Binary Segmentation curv? " << wmgmcurv << std::endl; if (wmgmcurv) { typename OutputImageType::Pointer laplacian=OutputImageType::New(); laplacian->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); laplacian->SetBufferedRegion( image->GetLargestPossibleRegion() ); laplacian->Allocate(); laplacian->SetSpacing(image->GetSpacing()); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { IndexType ind=Iterator.GetIndex(); if (image->GetPixel(ind) == 2) laplacian->SetPixel(ind,1); else if (image->GetPixel(ind) == 1 ) laplacian->SetPixel(ind,0.); else laplacian->SetPixel(ind,0.); ++Iterator; } //smooth and then reset the values unsigned int totit=50; for(unsigned int iterations=0; iterationsGetPixel(ind) == 2) laplacian->SetPixel(ind,1); else if (image->GetPixel(ind) == 0 ) laplacian->SetPixel(ind,0.); ++Iterator; } typedef itk::DiscreteGaussianImageFilter dgf; typename dgf::Pointer filter = dgf::New(); filter->SetVariance(0.5); filter->SetUseImageSpacingOn(); filter->SetMaximumError(.01f); filter->SetInput(laplacian); filter->Update(); laplacian=filter->GetOutput(); Iterator.GoToBegin(); } // WriteImage(laplacian,"lap.hdr"); // std::cout << "Laplacian Solved " << std::endl; GradientImageFilterPointer filter=GradientImageFilterType::New(); filter->SetInput( laplacian); RealType sigma=this->m_Sigma; filter->SetSigma( sigma ); // Execute the filter filter->Update(); this->m_GradientImage=filter->GetOutput(); GradientPixelType zero; zero.Fill(0); Iterator.GoToBegin(); while( !Iterator.IsAtEnd() ) { IndexType ind=Iterator.GetIndex(); if (image->GetPixel(ind) != 1) { this->m_GradientImage->SetPixel(ind,zero); } ++Iterator; } } else { GradientImageFilterPointer filter=GradientImageFilterType::New(); filter->SetInput( image ); RealType sigma=this->m_Sigma; filter->SetSigma( sigma ); // Execute the filter filter->Update(); this->m_GradientImage=filter->GetOutput(); } std::cout << " compute normals done "; } template void SurfaceImageCurvature ::WeingartenMap() { MatrixType D; float totwt=0,wt=0; unsigned int j=0; unsigned int i=0; unsigned int npts=this->m_PointList.size()-1; if (npts < 4) { this->m_MeanKappa = 0; this->m_GaussianKappa = 0; this->m_Kappa1 = 0; this->m_Kappa2 = 0; return; } unsigned int vars=3; D.set_size(npts,vars); // each row contains [u^2 , uv, v^2, u, v, 1] for point p D.fill(0.0); MatrixType W(2,2); W.fill(0.0); vnl_vector xdists(npts); xdists.fill(0.0); vnl_vector ydists(npts); ydists.fill(0.0); vnl_vector zdists(npts); zdists.fill(0.0); // go through all the points // compute weight // compute dist of unit dif and tangents // compute dif of normal with grad at point PointType Q =this->m_Origin; PointType QN=this->m_Normal; for (j=0; jm_PointList[j]; float difmag=Dif.magnitude(); PointType unitDif=Dif/difmag; float u1=0.0; float u2=0.0; wt=1.0;///difmag; totwt+=wt; IndexType index; for (i=0; im_Tangent1[i]; u2+=Dif[i]*this->m_Tangent2[i]; index[i] = (long) (this->m_PointList[j][i]+0.5); } // if (fabs(u1) < 1.e-6) u1=1.e-6; // if (fabs(u2) < 1.e-6) u2=1.e-6; // get the normal at the point GradientPixelType norm=this->m_GradientImage->GetPixel(index); PointType PN; float nmag=0.0; for (i=0;i 1.e-9) PN/=(nmag); else PN*=0.0; // PointType dN=(PN-QN)*wt; xdists[j]=(PN[0]); ydists[j]=(PN[1]); zdists[j]=(PN[2]); /* float a=0; float b=0; for (i=0; im_Tangent1[i]; b+=dN[i]*this->m_Tangent2[i]; } if ( u1*u1 > u2*u2 ) { W(0,0)=W(0,0)+a; W(1,0)=W(1,0)+b; } else { W(0,1)=W(0,1)+a; W(1,1)=W(1,1)+b; } D(j,0)=u1*u1; D(j,1)=2.*u1*u2; D(j,2)=u2*u2; D(j,3)=u1; D(j,4)=u2; D(j,5)=1.0; */ // each row contains [u^2 , uv, v^2, u, v, 1] for point p if (vars == 6) { D(j,5)=u2*u2; // (0 , 2*u2) D(j,4)=u1*u1; // (2*u1, 0) D(j,3)=u1*u2; // (u2 , u1) } D(j,2)=u2; // (1 , 0) D(j,1)=u1; // (0 , 1) D(j,0)=1.0; } // W=W/totwt; vnl_svd svd(D); vnl_vector ax = svd.solve(xdists); ///totwt); vnl_vector ay = svd.solve(ydists); ///totwt); vnl_vector az = svd.solve(zdists); ///totwt); // now get the first partials of each of these terms w.r.t. u and v // dN/du = (dN/du \dot T_1) T_1+ (dNdu dot T_2) T_2 PointType dNdu; dNdu[0]=ax[1]; dNdu[1]=ay[1]; dNdu[2]=az[1]; PointType dNdv; dNdv[0]=ax[2]; dNdv[1]=ay[2]; dNdv[2]=az[2]; float a=0; float b=0; float c=0; float d=0; for (i=0; im_Tangent1[i]; b+=dNdv[i]*this->m_Tangent1[i]; c+=dNdu[i]*this->m_Tangent2[i]; d+=dNdv[i]*this->m_Tangent2[i]; } /* dNdu=a/(c+a)*this->m_Tangent1+c/(c+a)*this->m_Tangent2; dNdv=b/(b+d)*this->m_Tangent1+d/(b+d)*this->m_Tangent2; a=0; b=0; c=0; d=0; for (i=0; im_Tangent1[i]; b+=dNdv[i]*this->m_Tangent1[i]; c+=dNdu[i]*this->m_Tangent2[i]; d+=dNdv[i]*this->m_Tangent2[i]; } */ W(0,0)=a; W(0,1)=b; W(1,0)=c; W(1,1)=d; // Compute estimated frame using eigensystem of D'*D { vnl_real_eigensystem eig(W); // vnl_diag_matrix > DD(eig.D.rows());// /* for(i = 0; i < eig.D.n(); ++i) { vnl_test_assert("All real", vcl_imag(eig.D(i,i)) < 1e-15); DD(i,i) = vcl_real(eig.D(i,i)); } vcl_cout << "D = " << eig.D << vcl_endl; vcl_cout << "V = " << eig.V << vcl_endl; */ this->m_Kappa1=vcl_real(eig.D(1,1)); this->m_Kappa2=vcl_real(eig.D(0,0)); // std::cout << " k1 " << this->m_Kappa1 << " k2 " << this->m_Kappa2 << " pt "<< this->m_Origin << std::endl; this->m_MeanKappa=(this->m_Kappa1+this->m_Kappa2)*0.5; this->m_GaussianKappa=(this->m_Kappa1*this->m_Kappa2); } } template void SurfaceImageCurvature ::ComputeSurfaceArea() { ImageType* image=GetInput(); if (!image) return; //BUG FIXME if (!this->m_GradientImage) this->EstimateNormalsFromGradient(); IndexType index; const double* spacing = image->GetSpacing(); typename ImageType::RegionType requestedRegion; this->m_ImageSize=image->GetLargestPossibleRegion().GetSize(); ImageIteratorType ti( image, image->GetLargestPossibleRegion() ); RealType area=0.0; this->m_TotalArea=0.0; ti.GoToBegin(); unsigned int ct=0; while(!ti.IsAtEnd() ) { index=ti.GetIndex(); if ( //ti.Get() == this->m_SurfaceLabel && (this->IsValidSurface(ti.Get(),index)) && index[0] < this->m_ImageSize[0]-this->m_NeighborhoodRadius && index[0] > this->m_NeighborhoodRadius && index[1] < this->m_ImageSize[1]-this->m_NeighborhoodRadius && index[1] > this->m_NeighborhoodRadius && index[2] < this->m_ImageSize[2]-this->m_NeighborhoodRadius && index[2] > this->m_NeighborhoodRadius ) { ct++; // this->EstimateFrameFromGradient(index); // BUG FIXME // area=this->ComputeLocalArea(spacing); area=1.0; this->m_FunctionImage->SetPixel(index,area); this->m_TotalArea+=area; this->m_PointList.clear(); if (ct % 1000 == 0) std::cout << " ind " << index << " area " << area << std::endl; } ++ti; } std::cout << " surface area " << this->m_TotalArea << std::endl; return; } template void SurfaceImageCurvature ::EstimateFrameFromGradient(IndexType index) { GradientPixelType g=this->m_GradientImage->GetPixel(index); RealType mag=0.0; for (int i=0; i< ImageDimension; i++) { this->m_Normal(i)=(RealType) g[i]; mag+=g[i]*g[i]; } mag=sqrt(mag); if (mag <= 1.e-9) { this->m_Normal.fill(0.); } else this->m_Normal/=sqrt(mag); this->SetFrameFromNormal(this->m_Normal); } template typename SurfaceImageCurvature::RealType SurfaceImageCurvature ::IntegrateFunctionOverSurface(bool norm) { typename OutputImageType::Pointer image=this->m_FunctionImage; if (!image) { std::cout << " no image " << std::endl; return 0; } std::cout << " allocating temp image "; typename OutputImageType::Pointer tempimage=OutputImageType::New(); tempimage->SetLargestPossibleRegion( image->GetLargestPossibleRegion() ); tempimage->SetBufferedRegion( image->GetLargestPossibleRegion() ); tempimage->Allocate(); std::cout << " done allocating "; typename ImageType::SizeType rad; typename ImageType::SizeType rad2; for (unsigned int t=0; tm_NeighborhoodRadius); rad2[t]=1; } this->m_ti.Initialize( rad , this->GetInput(), image->GetLargestPossibleRegion()); this->m_ti2.Initialize( rad2 , this->GetInput(), image->GetLargestPossibleRegion()); IndexType index; typename ImageType::RegionType requestedRegion; ImageIteratorType ti( this->GetInput(), this->GetInput()->GetLargestPossibleRegion() ); std::cout << " begin integrate "; ti.GoToBegin(); unsigned int ct =0; std::cout << " begin while " << std::endl; while(!ti.IsAtEnd() ) { index=ti.GetIndex(); tempimage->SetPixel(index,0); if ( //ti.Get() == this->m_SurfaceLabel && (this->IsValidSurface(ti.Get(),index)) && index[0] < this->m_ImageSize[0]-this->m_NeighborhoodRadius && index[0] > this->m_NeighborhoodRadius && index[1] < this->m_ImageSize[1]-this->m_NeighborhoodRadius && index[1] > this->m_NeighborhoodRadius && index[2] < this->m_ImageSize[2]-this->m_NeighborhoodRadius && index[2] > this->m_NeighborhoodRadius ) { PointType p; ct++; for (unsigned int k=0; kSetOrigin(p); // std::cout << " find nhood "; this->FindNeighborhood(); // std::cout << " get area "; RealType area=this->IntegrateFunctionOverNeighborhood(norm); tempimage->SetPixel(index,area); if (ct % 10000 == 0) std::cout << " area is : " << area << " ct " << ct << " pix " << ti.Get() << std::endl; // if ( area > 1) std::cout << " ind " << index << " area " << area << std::endl; // SD why sometimes a pixel is NaN ? // if ( !(area > 0)) std::cout << " ind " << index << " area " << area << " pix " << ti.Get() << std::endl; } ++ti; } this->CopyImageToFunctionImage(tempimage,this->m_FunctionImage); return 0; } template void SurfaceImageCurvature ::CopyImageToFunctionImage(OutputImagePointer i1, OutputImagePointer i2) { if (!i1 || !i2) return; typename ImageType::RegionType requestedRegion; OutputImageIteratorType ti1( i1, i1->GetLargestPossibleRegion() ); OutputImageIteratorType ti2( i2, i2->GetLargestPossibleRegion() ); ti1.GoToBegin(); ti2.GoToBegin(); while(!ti1.IsAtEnd() ) { ti2.Set(ti1.Get()); ++ti1; ++ti2; } } template typename SurfaceImageCurvature::RealType SurfaceImageCurvature ::IntegrateFunctionOverNeighborhood(bool norm) { unsigned int npts = this->m_PointList.size(); double curvature=0.0,tw=0; std::cout << " npts " << npts; for (unsigned int pp =0; ppm_PointList[pp][k]; PointType dd=this->m_Origin-this->m_PointList[pp]; double wi=dd.magnitude(); if (wi!=0.0) wi=1./wi; tw+=wi; RealType func=this->m_FunctionImage->GetPixel( localindex ); std::cout << " pp " << pp << " func " << func << std::endl; if (norm) curvature += wi*func; else curvature += func; // curvature*=this->ComputeLocalArea(spacing); } //if (norm ) curvature/=tw; // SD sometimes tw is zero making curvature = NaN if (norm && tw!=0) curvature/=tw; this->m_PointList.clear(); return curvature; } template void SurfaceImageCurvature ::PostProcessGeometry() { typename ImageType::Pointer image=GetInput(); if (!image) return; IndexType index; typename ImageType::RegionType requestedRegion; this->m_ImageSize=image->GetLargestPossibleRegion().GetSize(); ImageIteratorType ti( image, image->GetLargestPossibleRegion() ); std::vector kvec; ti.GoToBegin(); while(!ti.IsAtEnd() ) { PixelType pix=ti.Get(); index=ti.GetIndex(); if ( //ti.Get() == this->m_SurfaceLabel && (this->IsValidSurface(ti.Get(),index)) && index[0] < this->m_ImageSize[0]-this->m_NeighborhoodRadius && index[0] > this->m_NeighborhoodRadius && index[1] < this->m_ImageSize[1]-this->m_NeighborhoodRadius && index[1] > this->m_NeighborhoodRadius && index[2] < this->m_ImageSize[2]-this->m_NeighborhoodRadius && index[2] > this->m_NeighborhoodRadius ) // { PointType p; for (unsigned int k=0; kSetOrigin(p); this->FindNeighborhood(); int npts = this->m_PointList.size()-1; int dim = SurfaceDimension; double curvature=0.0,tw=0.0; for (int pp =0; ppm_PointList[pp][k]; // PointType dd=this->m_Origin-this->m_PointList[pp]; // double wi=dd.magnitude(); // if (wi!=0.0) wi=1./wi; // tw+=wi;vector vec; curvature = this->m_FunctionImage->GetPixel( localindex ); kvec.push_back (curvature); } std::sort(kvec.begin(), kvec.end()); // Sort the vector this->m_PointList.clear(); // curvature/=tw; this->m_FunctionImage->SetPixel(index,kvec[kvec.size()/2]); kvec.clear(); } ++ti; } } template void SurfaceImageCurvature ::ComputeFrameOverDomain(unsigned int which) { ImageType* image=GetInput(); if (!image) return; IndexType index; typename ImageType::RegionType requestedRegion; this->m_ImageSize=image->GetLargestPossibleRegion().GetSize(); ImageIteratorType ti( image, image->GetLargestPossibleRegion() ); // exit(1); // Get Normals First! this->EstimateNormalsFromGradient(); unsigned int ct=1; unsigned long ct2=0; RealType kpix=0; double thresh=0.0; ti.GoToBegin(); while(!ti.IsAtEnd() ) { index=ti.GetIndex(); if (ct2 % 200000 == 0 && ct2 > 0) { std::cout << " ind " << index << " kp " << kpix << std::endl; } kpix=0.0; if ( //ti.Get() == this->m_SurfaceLabel && this->IsValidSurface(ti.Get(),index) && index[0] < this->m_ImageSize[0]-2*this->m_NeighborhoodRadius && index[0] > 2*this->m_NeighborhoodRadius && index[1] < this->m_ImageSize[1]-2*this->m_NeighborhoodRadius && index[1] > 2*this->m_NeighborhoodRadius && index[2] < this->m_ImageSize[2]-2*this->m_NeighborhoodRadius && index[2] > 2*this->m_NeighborhoodRadius ) // { // std::cout << " val " << (RealType) ti.Get() << std::endl; PointType p; for (unsigned int k=0; kSetOrigin(p); this->EstimateFrameFromGradient(index); this->FindNeighborhood(); switch (which) { case( 0 ) : this->ComputeJoshiFrame( this->m_Origin); break; case( 1 ) : this->JainMeanAndGaussianCurvature( this->m_Origin); break; case( 2 ) : this->ShimshoniFrame(this->m_Origin); break; case( 3 ) : this->WeingartenMap(); break; case( 4 ) : kpix=this->ComputeMeanEuclideanDistance(); break; default: this->WeingartenMap(); } // this->PrintFrame(); bool geterror=false; if (geterror){ float error=0.0; float temp1=this->ErrorEstimate(this->GetOrigin()); float temp2=this->ErrorEstimate(this->GetOrigin(),-1); if (temp1 < temp2) { error=temp1; }else{ error=temp2; this->SwitchNormalSign(); // this->ComputeWeightsAndDirectionalKappaAndAngles(this->GetOrigin()); // this->EstimateCurvature(this->m_A,this->m_B,this->m_B,this->m_C); // this->EstimateCurvature(); } std::cout << " best error " << error << std::endl; } // kpix=fabs(2.0/(3.1416)*atan((this->m_Kappa1+this->m_Kappa2)/(this->m_Kappa2-this->m_Kappa1))); // if (kpix >= 0) // kpix = (sqrt(this->m_Kappa1*this->m_Kappa1+this->m_Kappa2*this->m_Kappa2)); // kpix=1.0; // if (this->m_MeanKappa > 0.) kpix +=fabs(this->m_MeanKappa); // kpix =fabs(this->m_MeanKappa); // kpix = kpix+10.0; // if (this->m_Kappa1 > 0) kpix+=fabs(this->m_Kappa1); // if (this->m_Kappa2 > 0) kpix+=fabs(this->m_Kappa2); // else kpix = -1.0*(sqrt(this->m_Kappa1*this->m_Kappa1+this->m_Kappa2*this->m_Kappa2)); // std::cout << " kpix " << kpix << " thresh " << thresh << std::endl; // // if ( fabs(kpix) > 100 ) kpix=0.0; // else if (kpix < -1.0*thresh/ct ) kpix=2; // else kpix=0; kpix=1.1; float fval=this->m_GaussianKappa; fval=this->m_MeanKappa; // fval=fval*(1.0+fabs(this->m_Kappa2-this->m_Kappa1)); if (fabs(fval) > 1) fval/=fval; // if (fval > 0.0) kpix+=(fval); // gyri // if (fval < 0.0) kpix-=(fval); // sulci bright kpix=this->m_kSign*fval; //sulci if( vnl_math_isnan(kpix) || vnl_math_isinf(kpix) ) { this->m_Kappa1=0.0; this->m_Kappa2=0.0; this->m_MeanKappa=0.0; this->m_GaussianKappa=0.0; kpix=0.0; } // kpix=1.0+this->m_Kappa1*this->m_Kappa1+this->m_Kappa2*this->m_Kappa2; // kpix=fabs(this->m_Normal[0]); if (which == 5) kpix=this->CharacterizeSurface(); ct++; this->m_PointList.clear(); } thresh+=kpix; float offset=0; if ( fabs( image->GetPixel(index) - 0 ) > 1.e-6 ) offset=128.0; this->m_FunctionImage->SetPixel(index,offset+kpix); ct2++; ++ti; } std::cout << " average curvature " << thresh/(float)ct << " kSign " << this->m_kSign << std::endl; /* now get s.d. float sd=0.0; float avgc=thresh/(float)ct; ti.GoToBegin(); while(!ti.IsAtEnd() ) { PixelType pix=ti.Get(); if ( //ti.Get() == this->m_SurfaceLabel this->IsValidSurface(ti.Get(),index) ) sd+=(this->m_FunctionImage->GetPixel(ti.GetIndex())-avgc)* (this->m_FunctionImage->GetPixel(ti.GetIndex())-avgc); ++ti; } sd=sqrt(sd/(float)ct); float nsd=1.0; ti.GoToBegin(); while(!ti.IsAtEnd() ) { PixelType pix=ti.Get(); if ( //ti.Get() == this->m_SurfaceLabel this->IsValidSurface(ti.Get(),index) && (this->m_FunctionImage->GetPixel(ti.GetIndex()) - avgc) > nsd*sd ) this->m_FunctionImage->SetPixel(ti.GetIndex(),avgc+nsd*sd); ++ti; } */ } template typename SurfaceImageCurvature::ImageType* SurfaceImageCurvature ::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return NULL; } return static_cast< ImageType * > (this->ProcessObject::GetInput(0) ); } /** * */ template typename SurfaceImageCurvature::OutputImageType * SurfaceImageCurvature ::GetOutput() { return static_cast (this->ProcessObject::GetOutput(0)); } template void SurfaceImageCurvature ::SetInput(typename ImageType::Pointer input) { // Process object is not const-correct so the const_cast is required here this->ProcessObject::SetNthInput(0, input); // const_cast< ImageType * >( input ) ); this->m_ImageSize=input->GetLargestPossibleRegion().GetSize(); typename OutputImageType::RegionType region; region.SetSize( this->m_ImageSize ); if (!this->m_FunctionImage) { this->m_FunctionImage=OutputImageType::New(); this->m_FunctionImage->SetLargestPossibleRegion( region ); this->m_FunctionImage->SetBufferedRegion( region ); this->m_FunctionImage->Allocate(); this->m_FunctionImage->SetSpacing( input->GetSpacing() ); this->m_FunctionImage->SetDirection( input->GetDirection() ); this->m_FunctionImage->SetOrigin( input->GetOrigin() ); } //this->ProcessLabelImage(); //this->ProcessObject::SetNthOutput( 0, this->m_FunctionImage ); } } // namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkSurfaceMeshCurvature.h000066400000000000000000000101121147325206600234150ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkSurfaceMeshCurvature.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _SurfaceMeshCurvature_h #define _SurfaceMeshCurvature_h #include "itkSurfaceCurvatureBase.h" namespace itk { /** \class SurfaceMeshCurvature * * This class takes a surface as input and creates a local * geometric frame for each surface point. * * */ template < typename TSurface , typename TSurfacePatch > class SurfaceMeshCurvature : public SurfaceCurvatureBase < TSurface , 3 > { public: /** Standard class typedefs. */ typedef SurfaceMeshCurvature Self; typedef SurfaceCurvatureBase Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(SurfaceMeshCurvature,SurfaceCurvatureBase); /** Method for creation through the object factory. */ itkNewMacro(Self); typedef typename Superclass::RealType RealType; typedef typename Superclass::PointType VectorType; typedef typename Superclass::PointType FixedVectorType; typedef typename Superclass::PointType PointType; typedef typename Superclass::MatrixType MatrixType; typedef TSurfacePatch SurfacePatch; typedef typename TSurfacePatch::Pointer SurfacePatchPointer; typedef typename TSurfacePatch::NodeLocationType VertexType; typedef typename TSurfacePatch::PixelType FunctionValueType; typedef TSurface* SurfacePointer; //probably vtkmesh /** Find all points within some distance of the origin. * The argument gives the number of times to apply the * mean shift algorithm to find the best neighborhood. */ virtual void FindNeighborhood(unsigned int numMeanShifts=0) { this->m_PointList.clear(); this->m_FunctionValueList.clear(); VertexType origin=m_SurfacePatch->GetLocation(); PointType pt; for(int j = 0; j < 3; j++) pt(j)=origin[j]; this->m_Origin=pt; this->m_PointList.insert(this->m_PointList.begin(),pt); this->m_FunctionValueList.insert(this->m_FunctionValueList.begin(),m_SurfacePatch->GetValue()); for (unsigned int i=0; im_Neighbors.size(); i++) { VertexType neigh=m_SurfacePatch->m_Neighbors[i]->GetLocation(); PointType pt; for(int j = 0; j < 3; j++) pt(j)=neigh[j]; this->m_PointList.insert(this->m_PointList.begin(),pt); this->m_FunctionValueList.insert(this->m_FunctionValueList.begin(),this->m_SurfacePatch->m_Neighbors[i]->GetValue(0)); } } void SetSurface(SurfacePointer s) { m_Surface=s;} void SetSurfacePatch( SurfacePatchPointer s) { m_SurfacePatch=s; } SurfaceMeshCurvature() { this->m_Origin.fill(0.0); this->m_ArbitraryTangent.fill(0.); this->m_Normal.fill(0.); this->m_Tangent1.fill(0.); this->m_Tangent2.fill(0.); this->m_DirectionalKappa=0.0; this->m_Kappa1=0.0; this->m_Kappa2=0.0; this->m_GaussianKappa=0.0; this->m_A=0.0; this->m_B=0.0; this->m_C=0.0; this->m_W1=3./8.; this->m_W2=1./8.; this->m_Eval0=0.0; this->m_Eval1=0.0; this->m_Eval2=0.0; this->m_CurrentNeighborhoodPointIndex=0; this->m_ParameterFileName = ""; this->m_Pi= 3.14159265358979323846; this->m_Debug=true; this->m_Debug=false; this->m_UseGeodesicNeighborhood=false; this->m_TotalArea=0.0; } ~SurfaceMeshCurvature(){}; protected: private: SurfacePointer m_Surface; SurfacePatchPointer m_SurfacePatch; }; } // namespace itk #ifndef ITK_MANUAL_INSTANTIATION //#include "itkSurfaceMeshCurvature.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkVectorFieldGradientImageFunction.h000066400000000000000000000215421147325206600256550ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorFieldGradientImageFunction.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVectorFieldGradientImageFunction_h #define __itkVectorFieldGradientImageFunction_h #include "itkImageFunction.h" #include "itkVariableSizeMatrix.h" namespace itk { /** \class VectorFieldGradientImageFunction * */ template > class ITK_EXPORT VectorFieldGradientImageFunction : public ImageFunction { public: /** Standard class typedefs. */ typedef VectorFieldGradientImageFunction Self; typedef ImageFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro( Self ); /** Run-time type information (and related methods) */ itkTypeMacro( VectorFieldGradientImageFunction, ImageFunction ); /** Extract some information from the image types. Dimensionality * of the two images is assumed to be the same. */ typedef TInputImage InputImageType; typedef typename InputImageType::PixelType VectorType; typedef TOutput MatrixType; /** Declare typedefs of superclass */ typedef typename Superclass::PointType PointType; typedef typename Superclass::IndexType IndexType; typedef typename Superclass::ContinuousIndexType ContinuousIndexType; /** The dimensionality of the input and output images. */ itkStaticConstMacro( ImageDimension, unsigned int, TInputImage::ImageDimension ); /** Length of the vector pixel type of the input image. */ itkStaticConstMacro( VectorDimension, unsigned int, VectorType::Dimension ); /** Define the data type and the vector of data type used in calculations. */ typedef TRealType RealType; /** * Evaluate deformation gradient tensor */ MatrixType EvaluateDeformationGradientTensor( const PointType& ) const; MatrixType EvaluateDeformationGradientTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateDeformationGradientTensorAtContinuousIndex ( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateDeformationGradientTensor( point ); } /** * Evaluate Jacobian */ virtual MatrixType Evaluate( const PointType &point ) const { return this->EvaluateJacobian( point ); } virtual MatrixType EvaluateAtIndex( const IndexType &idx ) const { return this->EvaluateJacobianAtIndex( idx ); } virtual MatrixType EvaluateAtContinuousIndex( const ContinuousIndexType &idx ) const { return this->EvaluateJacobianAtContinuousIndex( idx ); } MatrixType EvaluateJacobian( const PointType & ) const; MatrixType EvaluateJacobianAtIndex( const IndexType &idx ) const; MatrixType EvaluateJacobianAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateJacobian( point ); } /** * Evaluate Jacobian determinant */ RealType EvaluateJacobianDeterminant( const PointType& ) const; RealType EvaluateJacobianDeterminantAtIndex( const IndexType &idx ) const; RealType EvaluateJacobianDeterminantAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateJacobianDeterminant( point ); } /** * Evaluate Lagrangian strain tensor */ MatrixType EvaluateLagrangianStrainTensor( const PointType& ) const; MatrixType EvaluateLagrangianStrainTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateLagrangianStrainTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateLagrangianStrainTensor( point ); } /** * Evaluate Lagrangian directional strain */ RealType EvaluateLagrangianDirectionalStrain( const PointType&, const VectorType& ) const; RealType EvaluateLagrangianDirectionalStrainAtIndex( const IndexType &idx, const VectorType &V ) const; RealType EvaluateLagrangianDirectionalStrainAtContinuousIndex( const ContinuousIndexType &idx, const VectorType &V ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateLagrangianDirectionalStrain( point, V ); } /** * Evaluate Eulerian strain tensor */ MatrixType EvaluateEulerianStrainTensor( const PointType& ) const; MatrixType EvaluateEulerianStrainTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateEulerianStrainTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateEulerianStrainTensor( point ); } /** * Evaluate Eulerian directional strain */ RealType EvaluateEulerianDirectionalStrain( const PointType&, const VectorType& ) const; RealType EvaluateEulerianDirectionalStrainAtIndex( const IndexType &idx, const VectorType &V ) const; RealType EvaluateEulerianDirectionalStrainAtContinuousIndex( const ContinuousIndexType &idx, const VectorType &V ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateEulerianDirectionalStrain( point, V ); } /** * Evaluate Right Cauchy-Green strain tensor */ MatrixType EvaluateRightCauchyGreenDeformationTensor( const PointType& ) const; MatrixType EvaluateRightCauchyGreenDeformationTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateRightCauchyGreenDeformationTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateRightCauchyGreenDeformationTensor( point ); } /** * Evaluate Left Cauchy-Green strain tensor */ MatrixType EvaluateLeftCauchyGreenDeformationTensor( const PointType& ) const; MatrixType EvaluateLeftCauchyGreenDeformationTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateLeftCauchyGreenDeformationTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateLeftCauchyGreenDeformationTensor( point ); } /** * Evaluate left stretch tensor */ MatrixType EvaluateLeftStretchTensor( const PointType& ) const; MatrixType EvaluateLeftStretchTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateLeftStretchTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateLeftStretchTensor( point ); } /** * Evaluate right stretch tensor */ MatrixType EvaluateRightStretchTensor( const PointType& ) const; MatrixType EvaluateRightStretchTensorAtIndex( const IndexType &idx ) const; MatrixType EvaluateRightStretchTensorAtContinuousIndex( const ContinuousIndexType &idx ) const { PointType point; this->GetInputImage()->TransformContinuousIndexToPhysicalPoint( idx, point ); return this->EvaluateRightStretchTensor( point ); } protected: VectorFieldGradientImageFunction(); virtual ~VectorFieldGradientImageFunction() {} void PrintSelf ( std::ostream& os, Indent indent ) const; private: VectorFieldGradientImageFunction(const Self&); //purposely not implemented MatrixType operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkVectorFieldGradientImageFunction.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkVectorFieldGradientImageFunction.txx000066400000000000000000000517261147325206600262600ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorFieldGradientImageFunction.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkVectorFieldGradientImageFunction_txx #define _itkVectorFieldGradientImageFunction_txx #include "itkVectorFieldGradientImageFunction.h" #include "itkDecomposeTensorFunction.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "vnl/algo/vnl_matrix_inverse.h" #include "vnl/vnl_vector.h" namespace itk { template VectorFieldGradientImageFunction ::VectorFieldGradientImageFunction() { } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateDeformationGradientTensor( const PointType &point ) const { if ( !this->IsInsideBuffer( point ) ) { unsigned int minDimension = ImageDimension; MatrixType F; F.SetSize( ImageDimension, VectorDimension ); F.Fill( 0.0 ); for ( unsigned int i = 0; i < minDimension; i++ ) { F[i][i] = 1.0; } itkWarningMacro( "The specified point, " << point << ", is outside the image boundaries." ); return F; } typename InputImageType::SpacingType spacing = this->GetInputImage()->GetSpacing(); typedef VectorLinearInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); interpolator->SetInputImage( this->GetInputImage() ); MatrixType F; F.SetSize( ImageDimension, VectorDimension ); typename InterpolatorType::OutputType x; typename InterpolatorType::PointType ipoint; ipoint.CastFrom( point ); x = interpolator->Evaluate( ipoint ); for ( unsigned int i = 0; i < ImageDimension; i++ ) { typename InterpolatorType::PointType::VectorType delta; delta.Fill( 0.0 ); delta[i] = spacing[i]; typename InterpolatorType::OutputType xp1; typename InterpolatorType::OutputType xp2; typename InterpolatorType::OutputType xm1; typename InterpolatorType::OutputType xm2; if ( !this->IsInsideBuffer( point + delta ) ) { xp2 = xp1 = x; } else { xp1 = interpolator->Evaluate( ipoint + delta ); if ( this->IsInsideBuffer( point + delta*2.0 ) ) { xp2 = interpolator->Evaluate( ipoint + delta*2.0 ); } else { xp2 = xp1; } } if ( !this->IsInsideBuffer( point - delta ) ) { xm2 = xm1 = x; } else { xm1 = interpolator->Evaluate( ipoint - delta ); if ( this->IsInsideBuffer( point - delta*2.0 ) ) { xm2 = interpolator->Evaluate( ipoint - delta*2.0 ); } else { xm2 = xm1; } } RealType h = 0.5; xp1 = xp1*h + x*(1.0-h); xm1 = xm1*h + x*(1.0-h); xp2 = xp2*h + xp1*(1.0-h); xp2 = xm2*h + xm1*(1.0-h); RealType weight = 1.0 / ( 12.0*delta[i] ); for ( unsigned int j = 0; j < VectorDimension; j++ ) { F[i][j] = weight*( -xp2[j] + 8.0*xp1[j] - 8.0*xm1[j] + xm2[j] ); } } unsigned int minDimension = ImageDimension; if ( static_cast( VectorDimension ) < static_cast( ImageDimension ) ) { minDimension = VectorDimension; } for ( unsigned int i = 0; i < minDimension; i++ ) { F[i][i] += 1.0; } return F; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateDeformationGradientTensorAtIndex( const IndexType &index ) const { if ( !this->IsInsideBuffer( index ) ) { unsigned int minDimension = ImageDimension; MatrixType F; F.SetSize( ImageDimension, VectorDimension ); F.Fill( 0.0 ); for ( unsigned int i = 0; i < minDimension; i++ ) { F[i][i] = 1.0; } itkWarningMacro( "The specified index, " << index << ", is outside the image boundaries." ); return F; } MatrixType F; F.SetSize( ImageDimension, VectorDimension ); typename InputImageType::PixelType x; x = this->GetInputImage()->GetPixel( index ); typename InputImageType::SpacingType spacing = this->GetInputImage()->GetSpacing(); for ( unsigned int i = 0; i < ImageDimension; i++ ) { typename InputImageType::OffsetType offset1; offset1.Fill( 0 ); offset1[i] = 1; typename InputImageType::OffsetType offset2; offset2.Fill( 0 ); offset2[i] = 2; typename InputImageType::PixelType xp1; typename InputImageType::PixelType xp2; typename InputImageType::PixelType xm1; typename InputImageType::PixelType xm2; if ( !this->IsInsideBuffer( index + offset1 ) ) { xp2 = xp1 = x; } else { xp1 = this->GetInputImage()->GetPixel( index + offset1 ); if ( this->IsInsideBuffer( index + offset2 ) ) { xp2 = this->GetInputImage()->GetPixel( index + offset2 ); } else { xp2 = xp1; } } if ( !this->IsInsideBuffer( index - offset1 ) ) { xm2 = xm1 = x; } else { xm1 = this->GetInputImage()->GetPixel( index - offset1 ); if ( this->IsInsideBuffer( index - offset2 ) ) { xm2 = this->GetInputImage()->GetPixel( index - offset2 ); } else { xm2 = xm1; } } RealType h = 0.5; xp1 = xp1*h + x*(1.0-h); xm1 = xm1*h + x*(1.0-h); xp2 = xp2*h + xp1*(1.0-h); xp2 = xm2*h + xm1*(1.0-h); RealType weight = 1.0 / ( 12.0*static_cast( offset1[i] ) * spacing[i] ); for ( unsigned int j = 0; j < VectorDimension; j++ ) { F[i][j] = weight*( -xp2[j] + 8.0*xp1[j] - 8.0*xm1[j] + xm2[j] ); } } unsigned int minDimension = ImageDimension; if ( static_cast( VectorDimension ) < static_cast( ImageDimension ) ) { minDimension = VectorDimension; } for ( unsigned int i = 0; i < minDimension; i++ ) { F[i][i] += 1.0; } return F; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateJacobian( const PointType &point ) const { return this->EvaluateDeformationGradientTensor( point ); } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateJacobianAtIndex( const IndexType &index ) const { return this->EvaluateDeformationGradientTensorAtIndex( index ); } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateJacobianDeterminant( const PointType &point ) const { MatrixType J = this->EvaluateJacobian( point ); typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); return decomposer->EvaluateDeterminant( J ); } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateJacobianDeterminantAtIndex( const IndexType &index ) const { MatrixType J = this->EvaluateJacobianAtIndex( index ); typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); return decomposer->EvaluateDeterminant( J ); } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLagrangianStrainTensor( const PointType &point ) const { MatrixType F = this->EvaluateDeformationGradientTensor( point ); MatrixType E(ImageDimension, ImageDimension); typename MatrixType::InternalMatrixType ff = F.GetTranspose() * F.GetVnlMatrix(); for ( unsigned int i = 0; i < ff.rows(); i++ ) { for ( unsigned int j = 0; j < ff.columns(); j++ ) { E[i][j] = ff.get( i, j ); if ( i == j ) { E[i][j] -= 1.0; } E[i][j] *= 0.5; } } return E; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLagrangianStrainTensorAtIndex( const IndexType &index ) const { MatrixType F = this->EvaluateDeformationGradientTensorAtIndex( index ); MatrixType E(ImageDimension, ImageDimension); typename MatrixType::InternalMatrixType ff = F.GetTranspose() * F.GetVnlMatrix(); for ( unsigned int i = 0; i < ff.rows(); i++ ) { for ( unsigned int j = 0; j < ff.columns(); j++ ) { E[i][j] = ff.get( i, j ); if ( i == j ) { E[i][j] -= 1.0; } E[i][j] *= 0.5; } } return E; } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateLagrangianDirectionalStrain( const PointType &point, const VectorType &V ) const { MatrixType E = this->EvaluateLagrangianStrainTensor( point ); vnl_vector v = E * V.GetVnlVector(); RealType s = 0.0; for ( unsigned int i = 0; i < v.size(); i++ ) { s += v[i]*V[i]; } return s; } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateLagrangianDirectionalStrainAtIndex ( const IndexType &index, const VectorType &V ) const { MatrixType E = this->EvaluateLagrangianStrainTensorAtIndex( index ); vnl_vector v = E * V.GetVnlVector(); RealType s = 0.0; for ( unsigned int i = 0; i < v.size(); i++ ) { s += v[i]*V[i]; } return s; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateEulerianStrainTensor( const PointType &point ) const { MatrixType F = this->EvaluateDeformationGradientTensor( point ); MatrixType E(ImageDimension, ImageDimension); typename MatrixType::InternalMatrixType ff = vnl_matrix_inverse( F.GetVnlMatrix() * F.GetTranspose() ); for ( unsigned int i = 0; i < ff.rows(); i++ ) { for ( unsigned int j = 0; j < ff.columns(); j++ ) { E[i][j] = -ff.get( i, j ); if ( i == j ) { E[i][j] += 1.0; } E[i][j] *= 0.5; } } return E; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateEulerianStrainTensorAtIndex( const IndexType &index ) const { MatrixType F = this->EvaluateDeformationGradientTensorAtIndex( index ); MatrixType E(ImageDimension, ImageDimension); typename MatrixType::InternalMatrixType ff = vnl_matrix_inverse( F.GetVnlMatrix() * F.GetTranspose() ); for ( unsigned int i = 0; i < ff.rows(); i++ ) { for ( unsigned int j = 0; j < ff.columns(); j++ ) { E[i][j] = -ff.get( i, j ); if ( i == j ) { E[i][j] += 1.0; } E[i][j] *= 0.5; } } return E; } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateEulerianDirectionalStrain( const PointType &point, const VectorType &V ) const { MatrixType E = this->EvaluateEulerianStrainTensor( point ); vnl_vector v = E * V.GetVnlVector(); RealType s = 0.0; for ( unsigned int i = 0; i < v.size(); i++ ) { s += v[i]*V[i]; } return s; } template typename VectorFieldGradientImageFunction ::RealType VectorFieldGradientImageFunction ::EvaluateEulerianDirectionalStrainAtIndex( const IndexType &index, const VectorType &V ) const { MatrixType E = this->EvaluateEulerianStrainTensorAtIndex( index ); vnl_vector v = E * V.GetVnlVector(); RealType s = 0.0; for ( unsigned int i = 0; i < v.size(); i++ ) { s += v[i]*V[i]; } return s; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLeftCauchyGreenDeformationTensor( const PointType &point ) const { MatrixType F = this->EvaluateDeformationGradientTensor( point ); typename MatrixType::InternalMatrixType b = F.GetVnlMatrix() * F.GetTranspose(); MatrixType B; B.SetSize( F.Rows(), F.Cols() ); for ( unsigned int i = 0; i < F.Rows(); i++ ) { for ( unsigned int j = 0; j < F.Cols(); j++ ) { B[i][j] = b[i][j]; } } return B; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLeftCauchyGreenDeformationTensorAtIndex( const IndexType &index ) const { MatrixType F = this->EvaluateDeformationGradientTensorAtIndex( index ); typename MatrixType::InternalMatrixType b = F.GetVnlMatrix() * F.GetTranspose(); MatrixType B; B.SetSize( F.Rows(), F.Cols() ); for ( unsigned int i = 0; i < F.Rows(); i++ ) { for ( unsigned int j = 0; j < F.Cols(); j++ ) { B[i][j] = b[i][j]; } } return B; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateRightCauchyGreenDeformationTensor( const PointType &point ) const { MatrixType F = this->EvaluateDeformationGradientTensor( point ); typename MatrixType::InternalMatrixType c = F.GetVnlMatrix() * F.GetTranspose(); MatrixType C; C.SetSize( F.Rows(), F.Cols() ); for ( unsigned int i = 0; i < F.Rows(); i++ ) { for ( unsigned int j = 0; j < F.Cols(); j++ ) { C[i][j] = c[i][j]; } } return C; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateRightCauchyGreenDeformationTensorAtIndex( const IndexType &index ) const { MatrixType F = this->EvaluateDeformationGradientTensorAtIndex( index ); typename MatrixType::InternalMatrixType c = F.GetVnlMatrix() * F.GetTranspose(); MatrixType C; C.SetSize( F.Rows(), F.Cols() ); for ( unsigned int i = 0; i < F.Rows(); i++ ) { for ( unsigned int j = 0; j < F.Cols(); j++ ) { C[i][j] = c[i][j]; } } return C; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateRightStretchTensor( const PointType &point ) const { MatrixType C = this->EvaluateRightCauchyGreenDeformationTensor( point ); MatrixType D; MatrixType V; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( C, D, V ); MatrixType U; U.SetSize( C.Rows(), C.Cols() ); U.Fill( 0 ); for ( unsigned int d = 0; d < C.Rows(); d++ ) { RealType lambda = sqrt( D[d][d] ); for ( unsigned int i = 0; i < C.Rows(); i++ ) { for ( unsigned int j = 0; j < C.Cols(); j++ ) { U[i][j] += lambda*V[i][d]*V[j][d]; } } } return U; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateRightStretchTensorAtIndex( const IndexType &index ) const { MatrixType C = this->EvaluateRightCauchyGreenDeformationTensorAtIndex( index ); MatrixType D; MatrixType V; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( C, D, V ); MatrixType U; U.SetSize( C.Rows(), C.Cols() ); U.Fill( 0 ); for ( unsigned int d = 0; d < C.Rows(); d++ ) { RealType lambda = sqrt( D[d][d] ); for ( unsigned int i = 0; i < C.Rows(); i++ ) { for ( unsigned int j = 0; j < C.Cols(); j++ ) { U[i][j] += lambda*V[i][d]*V[j][d]; } } } return U; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLeftStretchTensor( const PointType &point ) const { MatrixType B = this->EvaluateLeftCauchyGreenDeformationTensor( point ); MatrixType D; MatrixType V; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( B, D, V ); MatrixType U; U.SetSize( B.Rows(), B.Cols() ); U.Fill( 0 ); for ( unsigned int d = 0; d < B.Rows(); d++ ) { RealType lambda = sqrt( D[d][d] ); for ( unsigned int i = 0; i < B.Rows(); i++ ) { for ( unsigned int j = 0; j < B.Cols(); j++ ) { U[i][j] += lambda*V[i][d]*V[j][d]; } } } return U; } template typename VectorFieldGradientImageFunction ::MatrixType VectorFieldGradientImageFunction ::EvaluateLeftStretchTensorAtIndex( const IndexType &index ) const { MatrixType B = this->EvaluateLeftCauchyGreenDeformationTensorAtIndex( index ); MatrixType D; MatrixType V; typedef DecomposeTensorFunction DecomposerType; typename DecomposerType::Pointer decomposer = DecomposerType::New(); decomposer->EvaluateSymmetricEigenDecomposition( B, D, V ); MatrixType U; U.SetSize( B.Rows(), B.Cols() ); U.Fill( 0 ); for ( unsigned int d = 0; d < B.Rows(); d++ ) { RealType lambda = sqrt( D[d][d] ); for ( unsigned int i = 0; i < B.Rows(); i++ ) { for ( unsigned int j = 0; j < B.Cols(); j++ ) { U[i][j] += lambda*V[i][d]*V[j][d]; } } } return U; } template void VectorFieldGradientImageFunction ::PrintSelf( std::ostream& os, Indent indent ) const { Superclass::PrintSelf(os,indent); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkVectorGaussianInterpolateImageFunction.h000066400000000000000000000227261147325206600271420ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorGaussianInterpolateImageFunction.h,v $ Language: C++ Date: $Date: 2009/07/01 12:59:34 $ Version: $Revision: 1.5 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVectorGaussianInterpolateImageFunction_h #define __itkVectorGaussianInterpolateImageFunction_h #include "itkInterpolateImageFunction.h" #include "vnl/vnl_erf.h" #include "itkImageRegionConstIteratorWithIndex.h" namespace itk { /** \class VectorGaussianInterpolateImageFunction * \brief Gaussianly interpolate an image at specified positions. * * VectorGaussianInterpolateImageFunction linearly interpolates image intensity at * a non-integer pixel position. This class is templated * over the input image type and the coordinate representation type * (e.g. float or double). * * This function works for N-dimensional images. * * \ingroup ImageFunctions ImageInterpolators */ template class ITK_EXPORT VectorGaussianInterpolateImageFunction : public InterpolateImageFunction { public: /** Standard class typedefs. */ typedef VectorGaussianInterpolateImageFunction Self; typedef InterpolateImageFunction Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Run-time type information (and related methods). */ itkTypeMacro(VectorGaussianInterpolateImageFunction, InterpolateImageFunction); /** Method for creation through the object factory. */ itkNewMacro(Self); /** OutputType typedef support. */ typedef typename Superclass::OutputType OutputType; /** InputImageType typedef support. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImageType::PixelType PixelType; /** RealType typedef support. */ typedef typename Superclass::RealType RealType; /** Dimension underlying input image. */ itkStaticConstMacro(VDim, unsigned int,Superclass::ImageDimension); /** Index typedef support. */ typedef typename Superclass::IndexType IndexType; /** ContinuousIndex typedef support. */ typedef typename Superclass::ContinuousIndexType ContinuousIndexType; /** Compute internals */ virtual void ComputeBoundingBox() { const TInputImage *img = this->GetInputImage(); if(img == NULL) return; // Set the bounding box for(size_t d = 0; d < VDim; d++) { bb_start[d] = -0.5; bb_end[d] = img->GetBufferedRegion().GetSize()[d] - 0.5; nt[d] = (int)(bb_end[d] - bb_start[d] + 0.5); dx[d].set_size(nt[d]); gx[d].set_size(nt[d]); this->sigma[d]=1; sf[d] = 1.0 / (sqrt(2.0) * this->sigma[d] / img->GetSpacing()[d]); // std::cout << " sigma " << this->sigma[d] << " spc " << img->GetSpacing()[d] << " sf " << sf[d] << std::endl; cut[d] = this->sigma[d] * alpha / img->GetSpacing()[d]; } this->m_ImageSize=this->GetInputImage()->GetLargestPossibleRegion().GetSize(); } /** Set input */ virtual void SetInputImage(const TInputImage *img) { // Call parent method Superclass::SetInputImage(img); this->ComputeBoundingBox(); } void SetParameters(double *sigma, double alpha) { // Set the parameters for(size_t d = 0; d < VDim; d++) this->sigma[d] = 1.0; //sigma[d]; this->alpha = alpha; // If the image already set, recompute this->ComputeBoundingBox(); } /** Evaluate the function at a ContinuousIndex position * * Returns the linearly interpolated image intensity at a * specified point position. No bounds checking is done. * The point is assume to lie within the image buffer. * * ImageFunction::IsInsideBuffer() can be used to check bounds before * calling the method. */ virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType & index ) const { return EvaluateAtContinuousIndex(index, NULL); } virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType &index, OutputType *grad) const { OutputType Vout; Vout.Fill(0); // The bound variables for x, y, z int i0[VDim], i1[VDim]; // Compute the ERF difference arrays // std::cout << " index " << index << " VD " << VDim << std::endl; for(size_t d = 0; d < VDim; d++) { if ( index[d] <= 0 || index[d] >= this->m_ImageSize[d]-1 || vnl_math_isnan(index[d]) || vnl_math_isinf(index[d]) ) return Vout; double *pdx = const_cast(dx[d].data_block()); double *pgx = grad ? const_cast(gx[d].data_block()) : NULL; compute_erf_array(pdx, i0[d], i1[d], bb_start[d], nt[d], cut[d], index[d], sf[d], pgx); } // Get a pointer to the output value // loop over vector length for ( unsigned int qq=0; qq < Vout.Size(); qq++ ) { double sum_me = 0.0, sum_m = 0.0; vnl_vector_fixed dsum_me(0.0), dsum_m(0.0), dw; // Loop over the voxels in the region identified ImageRegion region; for(size_t d = 0; d < VDim; d++) { region.SetIndex(d, i0[d]); region.SetSize(d, i1[d] - i0[d]); } for( ImageRegionConstIteratorWithIndex it(this->GetInputImage(), region); !it.IsAtEnd(); ++it) { size_t j = it.GetIndex()[0]; double w = dx[0][j]; if(grad) { dw[0] = gx[0][j]; for(size_t d = 1; d < VDim; d++) dw[d] = dx[0][j]; } for(size_t d = 1; d < VDim; d++) { j = it.GetIndex()[d]; w *= dx[d][j]; if(grad) { for(size_t q = 0; q < VDim; q++) dw[q] *= (d == q) ? gx[d][j] : dx[d][j]; } } double V = it.Get()[qq]; sum_me += V * w; sum_m += w; if(grad) { for(size_t q = 0; q < VDim; q++) { dsum_me[q] += V * dw[q]; dsum_m[q] += dw[q]; } } } double rc = sum_me / sum_m; if(grad) { for(size_t q = 0; q < VDim; q++) { grad[q] = (dsum_me[q] - rc * dsum_m[q]) / sum_m; grad[q] /= -1.4142135623730951 * this->sigma[q]; } } if (vnl_math_isnan(rc)) rc=0; Vout[qq]=rc; } // std::cout << " gaussian " << std::endl; // return sum_me / sum_m; return Vout; } protected: VectorGaussianInterpolateImageFunction() {} ~VectorGaussianInterpolateImageFunction(){}; void PrintSelf(std::ostream& os, Indent indent) const { this->Superclass::PrintSelf(os,indent); } private: VectorGaussianInterpolateImageFunction( const Self& ); //purposely not implemented void operator=( const Self& ); //purposely not implemented /** Number of neighbors used in the interpolation */ static const unsigned long m_Neighbors; typename InputImageType::SizeType m_ImageSize; vnl_vector dx[VDim], gx[VDim]; double bb_start[VDim], bb_end[VDim], sf[VDim], cut[VDim]; int nt[VDim], stride[VDim]; double sigma[VDim], alpha; void compute_erf_array ( double *dx_erf, // The output array of erf(p+i+1) - erf(p+i) int &k0, int &k1, // The range of integration 0 <= k0 < k1 <= n double b, // Lower bound of the bounding box int n, // Size of the bounding box in steps double cut, // The distance at which to cut off double p, // the value p double sfac, // scaling factor 1 / (Sqrt[2] sigma) double *gx_erf = NULL // Output derivative/erf array (optional) ) const { // Determine the range of voxels along the line where to evaluate erf k0 = (int) floor(p - b - cut); k1 = (int) ceil(p - b + cut); if(k0 < 0) k0 = 0; if(k1 > n) k1 = n; // Start at the first voxel double t = (b - p + k0) * sfac; // std::cout << " t " << t << " b " << b << " p " << p << " k0 " << k0 << " sfat " << sfac << std::endl; double e_last = vnl_erf(t); double g_last = gx_erf ? 1.128379167095513 * exp(- t * t) : 0.0; for(int i = k0; i < k1; i++) { t += sfac; // std::cout << " t2 " << t << std::endl; double e_now = vnl_erf(t); dx_erf[i] = e_now - e_last; if(gx_erf) { double g_now = 1.128379167095513 * exp(- t * t); gx_erf[i] = g_now - g_last; g_last = g_now; } e_last = e_now; } } }; } // end namespace itk // Define instantiation macro for this template. #define ITK_TEMPLATE_VectorGaussianInterpolateImageFunction(_, EXPORT, x, y) namespace itk { \ _(2(class EXPORT VectorGaussianInterpolateImageFunction< ITK_TEMPLATE_2 x >)) \ namespace Templates { typedef VectorGaussianInterpolateImageFunction< ITK_TEMPLATE_2 x > \ VectorGaussianInterpolateImageFunction##y; } \ } #endif ants-1.9.2+svn680.dfsg/Utilities/itkVectorImageFileReader.h000066400000000000000000000151251147325206600234500ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorImageFileReader.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVectorImageFileReader_h #define __itkVectorImageFileReader_h #include "itkImageIOBase.h" #include "itkImageSource.h" #include "itkExceptionObject.h" #include "itkSize.h" #include "itkImageRegion.h" #include "itkDefaultConvertPixelTraits.h" namespace itk { /** \brief Base exception class for IO conflicts. */ class VectorImageFileReaderException : public ExceptionObject { public: /** Run-time information. */ itkTypeMacro( VectorImageFileReaderException, ExceptionObject ); /** Constructor. */ VectorImageFileReaderException(const char *file, unsigned int line, const char* message = "Error in IO", const char* loc = "Unknown") : ExceptionObject(file, line, message, loc) { } /** Constructor. */ VectorImageFileReaderException(const std::string &file, unsigned int line, const char* message = "Error in IO", const char* loc = "Unknown") : ExceptionObject(file, line, message, loc) { } }; /** \brief Data source that reads image data from a single file. * * This source object is a general filter to read data from * a variety of file formats. It works with a ImageIOBase subclass * to actually do the reading of the data. Object factory machinery * can be used to automatically create the ImageIOBase, or the * ImageIOBase can be manually created and set. Note that this * class reads data from a single file; if you wish to read data * from a series of files use ImageSeriesReader. * * TImage is the type expected by the external users of the * filter. If data stored in the file is stored in a different format * then specified by TImage, than this filter converts data * between the file type and the external expected type. The * ConvertTraits template argument is used to do the conversion. * * A Pluggable factory pattern is used this allows different kinds of readers * to be registered (even at run time) without having to modify the * code in this class. Normally just setting the FileName with the * appropriate suffix is enough to get the reader to instantiate the * correct ImageIO and read the file properly. However, some files (like * raw binary format) have no accepted suffix, so you will have to * manually create the ImageIO instance of the write type. * * \sa ImageSeriesReader * \sa ImageIOBase * * \ingroup IOFilters * */ template > class ITK_EXPORT VectorImageFileReader : public ImageSource { public: /** Standard class typedefs. */ typedef VectorImageFileReader Self; typedef ImageSource Superclass; typedef SmartPointer Pointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(VectorImageFileReader, ImageSource); /** Image types */ typedef typename TImage::RegionType ImageRegionType; typedef typename TImage::InternalPixelType ImagePixelType; /** Deformation field types */ typedef typename TVectorImage::RegionType VectorImageRegionType; typedef typename TVectorImage::InternalPixelType VectorImagePixelType; /** Specify the file to read. This is forwarded to the IO instance. */ itkSetStringMacro(FileName); itkGetStringMacro(FileName); /** Set the Avants' naming convention On or Off */ itkSetMacro(UseAvantsNamingConvention,bool); itkGetConstReferenceMacro(UseAvantsNamingConvention,bool); itkBooleanMacro(UseAvantsNamingConvention); /** Set/Get the ImageIO helper class. Often this is created via the object * factory mechanism that determines whether a particular ImageIO can * read a certain file. This method provides a way to get the ImageIO * instance that is created. Or you can directly specify the ImageIO * to use to read a particular file in case the factory mechanism will * not work properly (e.g., unknown or unusual extension). */ void SetImageIO( ImageIOBase * imageIO ); itkGetObjectMacro(ImageIO,ImageIOBase); /** Prepare the allocation of the output image during the first back * propagation of the pipeline. */ virtual void GenerateOutputInformation(void); /** Give the reader a chance to indicate that it will produce more * output than it was requested to produce. VectorImageFileReader cannot * currently read a portion of an image (since the ImageIO objects * cannot read a portion of an image), so the VectorImageFileReader must * enlarge the RequestedRegion to the size of the image on disk. */ virtual void EnlargeOutputRequestedRegion(DataObject *output); protected: VectorImageFileReader(); ~VectorImageFileReader(); void PrintSelf(std::ostream& os, Indent indent) const; /** Convert a block of pixels from one type to another. */ void DoConvertBuffer(void* buffer, unsigned long numberOfPixels); /** Test whether the given filename exist and it is readable, this is intended to be called before attempting to use ImageIO classes for actually reading the file. If the file doesn't exist or it is not readable, and exception with an approriate message will be thrown. */ void TestFileExistanceAndReadability(); /** Does the real work. */ virtual void GenerateData(); ImageIOBase::Pointer m_ImageIO; bool m_UserSpecifiedImageIO; //keep track whether the ImageIO is user specified /** The file to be read. */ std::string m_FileName; private: VectorImageFileReader(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented std::string m_ExceptionMessage; typename TImage::Pointer m_Image; bool m_UseAvantsNamingConvention; }; } //namespace ITK #ifndef ITK_MANUAL_INSTANTIATION #include "itkVectorImageFileReader.txx" #endif #endif // __itkVectorImageFileReader_h ants-1.9.2+svn680.dfsg/Utilities/itkVectorImageFileReader.txx000066400000000000000000000551011147325206600240420ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorImageFileReader.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkVectorImageFileReader_txx #define _itkVectorImageFileReader_txx #include "itkVectorImageFileReader.h" #include "itkObjectFactory.h" #include "itkImageIOFactory.h" #include "itkConvertPixelBuffer.h" #include "itkImageRegion.h" #include "itkPixelTraits.h" #include "itkVectorImage.h" #include "itkImageRegionIterator.h" #include #include namespace itk { template VectorImageFileReader ::VectorImageFileReader() { m_ImageIO = 0; m_FileName = ""; m_UserSpecifiedImageIO = false; m_UseAvantsNamingConvention = true; this->m_Image = TImage::New(); } template VectorImageFileReader ::~VectorImageFileReader() { } template void VectorImageFileReader ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); if (m_ImageIO) { os << indent << "ImageIO: \n"; m_ImageIO->Print(os, indent.GetNextIndent()); } else { os << indent << "ImageIO: (null)" << "\n"; } os << indent << "UserSpecifiedImageIO flag: " << m_UserSpecifiedImageIO << "\n"; os << indent << "m_FileName: " << m_FileName << "\n"; } template void VectorImageFileReader ::SetImageIO( ImageIOBase * imageIO) { itkDebugMacro("setting ImageIO to " << imageIO ); if (this->m_ImageIO != imageIO ) { this->m_ImageIO = imageIO; this->Modified(); } m_UserSpecifiedImageIO = true; } template void VectorImageFileReader ::GenerateOutputInformation(void) { typename TVectorImage::Pointer output = this->GetOutput(); itkDebugMacro(<<"Reading file for GenerateOutputInformation()" << m_FileName); // Check to see if we can read the file given the name or prefix // if ( m_FileName == "" ) { throw VectorImageFileReaderException(__FILE__, __LINE__, "FileName must be specified", ITK_LOCATION); } // Test if the files exist and if it can be open. // and exception will be thrown otherwise. // std::string tmpFileName = this->m_FileName; // Test if the file exists and if it can be opened. // An exception will be thrown otherwise. // We catch the exception because some ImageIO's may not actually // open a file. Still reports file error if no ImageIO is loaded. try { m_ExceptionMessage = ""; this->TestFileExistanceAndReadability(); } catch(itk::ExceptionObject &err) { m_ExceptionMessage = err.GetDescription(); } std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos, this->m_FileName.length()-1 ); std::string filename = std::string( this->m_FileName, 0, pos ); std::string gzExtension( "" ); if ( extension == std::string( ".gz" ) ) { gzExtension = extension; std::string::size_type pos2 = filename.rfind( "." ); extension = std::string( filename, pos2, filename.length()-1 ); filename = std::string( this->m_FileName, 0, pos2 ); } // unsigned int dimension = itk::GetVectorDimension // ::VectorDimension; // Assume that the first image read contains all the information to generate // the output image. for ( unsigned int i = 0; i <= 1; i++ ) { this->m_FileName = filename; if ( this->m_UseAvantsNamingConvention ) { switch ( i ) { case 0: this->m_FileName += std::string( "xvec" ); break; case 1: this->m_FileName += std::string( "yvec" ); break; case 2: this->m_FileName += std::string( "zvec" ); break; default: this->m_FileName += std::string( "you_are_screwed_vec" ); break; } } else { itk::OStringStream buf; buf << i; this->m_FileName += ( std::string( "." ) + std::string( buf.str().c_str() ) ); } this->m_FileName += extension; if ( !gzExtension.empty() ) { this->m_FileName += std::string( ".gz" ); } if ( i == 0 ) { itkDebugMacro( << "Generating output information from the file " << this->m_FileName ); if ( m_UserSpecifiedImageIO == false ) //try creating via factory { m_ImageIO = ImageIOFactory::CreateImageIO( m_FileName.c_str(), ImageIOFactory::ReadMode ); } if ( m_ImageIO.IsNull() ) { OStringStream msg; msg << " Could not create IO object for file " << m_FileName.c_str() << std::endl; if (m_ExceptionMessage.size()) { msg << m_ExceptionMessage; } else { msg << " Tried to create one of the following:" << std::endl; std::list allobjects = ObjectFactoryBase::CreateAllInstance("itkImageIOBase"); for(std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { ImageIOBase* io = dynamic_cast(i->GetPointer()); msg << " " << io->GetNameOfClass() << std::endl; } msg << " You probably failed to set a file suffix, or" << std::endl; msg << " set the suffix to an unsupported type." << std::endl; } VectorImageFileReaderException e(__FILE__, __LINE__, msg.str().c_str(), ITK_LOCATION); throw e; return; } // Got to allocate space for the image. Determine the characteristics of // the image. // m_ImageIO->SetFileName(m_FileName.c_str()); m_ImageIO->ReadImageInformation(); typename TVectorImage::SizeType dimSize; double spacing[ TVectorImage::ImageDimension ]; double origin[ TVectorImage::ImageDimension ]; typename TVectorImage::DirectionType direction; std::vector axis; for(unsigned int k=0; kGetNumberOfDimensions() ) { dimSize[k] = m_ImageIO->GetDimensions(k); spacing[k] = m_ImageIO->GetSpacing(k); origin[k] = m_ImageIO->GetOrigin(k); // Please note: direction cosines are stored as columns of the // direction matrix axis = m_ImageIO->GetDirection(k); for (unsigned j=0; jGetNumberOfDimensions()) { direction[j][k] = axis[j]; } else { direction[j][k] = 0.0; } } } else { // Number of dimensions in the output is more than number of dimensions // in the ImageIO object (the file). Use default values for the size, // spacing, origin and direction for the final (degenerate) dimensions. dimSize[i] = 1; spacing[i] = 1.0; origin[i] = 0.0; for (unsigned j = 0; j < TImage::ImageDimension; j++) { if (i == j) { direction[j][k] = 1.0; } else { direction[j][k] = 0.0; } } } } output->SetSpacing( spacing ); // Set the image spacing output->SetOrigin( origin ); // Set the image origin output->SetDirection( direction ); // Set the image direction cosines //Copy MetaDataDictionary from instantiated reader to output image. output->SetMetaDataDictionary(m_ImageIO->GetMetaDataDictionary()); this->SetMetaDataDictionary(m_ImageIO->GetMetaDataDictionary()); this->m_Image->SetSpacing( spacing ); this->m_Image->SetOrigin( origin ); this->m_Image->SetDirection( direction ); this->m_Image->SetMetaDataDictionary(m_ImageIO->GetMetaDataDictionary()); typedef typename TVectorImage::IndexType IndexType; IndexType start; start.Fill(0); VectorImageRegionType region; region.SetSize(dimSize); region.SetIndex(start); ImageRegionType imageregion; imageregion.SetSize(dimSize); imageregion.SetIndex(start); // If a VectorImage, this requires us to set the // VectorLength before allocate //if( strcmp( output->GetNameOfClass(), "VectorImage" ) == 0 ) // { // typedef typename TImage::AccessorFunctorType AccessorFunctorType; // AccessorFunctorType::SetVectorLength( output, m_ImageIO->GetNumberOfComponents() ); // } output->SetLargestPossibleRegion( region ); this->m_Image->SetLargestPossibleRegion( imageregion ); } } this->m_FileName = tmpFileName; } template void VectorImageFileReader ::TestFileExistanceAndReadability() { std::string tmpFileName = this->m_FileName; std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos, this->m_FileName.length()-1 ); std::string filename = std::string( this->m_FileName, 0, pos ); std::string gzExtension( "" ); if ( extension == std::string( ".gz" ) ) { gzExtension = extension; std::string::size_type pos2 = filename.rfind( "." ); extension = std::string( filename, pos2, filename.length()-1 ); filename = std::string( this->m_FileName, 0, pos2 ); } unsigned int dimension = itk::GetVectorDimension ::VectorDimension; for ( unsigned int i = 0; i < dimension; i++ ) { this->m_FileName = filename; if ( this->m_UseAvantsNamingConvention ) { switch ( i ) { case 0: this->m_FileName += std::string( "xvec" ); break; case 1: this->m_FileName += std::string( "yvec" ); break; case 2: this->m_FileName += std::string( "zvec" ); break; default: this->m_FileName += std::string( "you_are_screwed_vec" ); break; } } else { itk::OStringStream buf; buf << i; this->m_FileName += ( std::string( "." ) + std::string( buf.str().c_str() ) ); } this->m_FileName += extension; if ( !gzExtension.empty() ) { this->m_FileName += std::string( ".gz" ); } itkDebugMacro( << "Checking for the file " << this->m_FileName ); // Test if the file exists. if( ! itksys::SystemTools::FileExists( m_FileName.c_str() ) ) { VectorImageFileReaderException e(__FILE__, __LINE__); OStringStream msg; msg <<"The file doesn't exists. " << std::endl << "Filename = " << m_FileName << std::endl; e.SetDescription(msg.str().c_str()); throw e; return; } // Test if the file can be open for reading access. std::ifstream readTester; readTester.open( m_FileName.c_str() ); if( readTester.fail() ) { readTester.close(); OStringStream msg; msg <<"The file couldn't be opened for reading. " << std::endl << "Filename: " << m_FileName << std::endl; VectorImageFileReaderException e(__FILE__, __LINE__,msg.str().c_str(),ITK_LOCATION); throw e; return; } readTester.close(); } this->m_FileName = tmpFileName; } template void VectorImageFileReader ::EnlargeOutputRequestedRegion(DataObject *output) { typename TVectorImage::Pointer out = dynamic_cast(output); // the ImageIO object cannot stream, then set the RequestedRegion to the // LargestPossibleRegion if (!m_ImageIO->CanStreamRead()) { if (out) { out->SetRequestedRegion( out->GetLargestPossibleRegion() ); } else { throw VectorImageFileReaderException(__FILE__, __LINE__, "Invalid output object type"); } } } template void VectorImageFileReader ::GenerateData() { typename TVectorImage::Pointer output = this->GetOutput(); // allocate the output buffer output->SetBufferedRegion( output->GetRequestedRegion() ); output->Allocate(); this->m_Image->SetBufferedRegion( output->GetRequestedRegion() ); this->m_Image->Allocate(); // Test if the file exist and if it can be open. // and exception will be thrown otherwise. try { m_ExceptionMessage = ""; this->TestFileExistanceAndReadability(); } catch(itk::ExceptionObject &err) { m_ExceptionMessage = err.GetDescription(); } std::string tmpFileName = this->m_FileName; std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos, this->m_FileName.length()-1 ); std::string filename = std::string( this->m_FileName, 0, pos ); std::string gzExtension( "" ); if ( extension == std::string( ".gz" ) ) { gzExtension = extension; std::string::size_type pos2 = filename.rfind( "." ); extension = std::string( filename, pos2, filename.length()-1 ); filename = std::string( this->m_FileName, 0, pos2 ); } unsigned int dimension = itk::GetVectorDimension ::VectorDimension; for ( unsigned int i = 0; i < dimension; i++ ) { this->m_FileName = filename; if ( this->m_UseAvantsNamingConvention ) { switch ( i ) { case 0: this->m_FileName += std::string( "xvec" ); break; case 1: this->m_FileName += std::string( "yvec" ); break; case 2: this->m_FileName += std::string( "zvec" ); break; default: this->m_FileName += std::string( "you_are_screwed_vec" ); break; } } else { itk::OStringStream buf; buf << i; this->m_FileName += ( std::string( "." ) + std::string( buf.str().c_str() ) ); } this->m_FileName += extension; if ( !gzExtension.empty() ) { this->m_FileName += std::string( ".gz" ); } itkDebugMacro( << "Reading image buffer from the file " << this->m_FileName ); // Tell the ImageIO to read the file m_ImageIO->SetFileName(m_FileName.c_str()); this->m_FileName = tmpFileName; ImageIORegion ioRegion(TImage::ImageDimension); ImageIORegion::SizeType ioSize = ioRegion.GetSize(); ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); typename TImage::SizeType dimSize; for(unsigned int j=0; jGetNumberOfDimensions()) { dimSize[j] = m_ImageIO->GetDimensions(j); } else { // Number of dimensions in the output is more than number of dimensions // in the ImageIO object (the file). Use default values for the size, // spacing, and origin for the final (degenerate) dimensions. dimSize[j] = 1; } } for(unsigned int j = 0; j < dimSize.GetSizeDimension(); ++j) { ioSize[j] = dimSize[j]; } typedef typename TImage::IndexType IndexType; IndexType start; start.Fill(0); for(unsigned int j = 0; j < start.GetIndexDimension(); ++j) { ioStart[j] = start[j]; } ioRegion.SetSize(ioSize); ioRegion.SetIndex(ioStart); itkDebugMacro (<< "ioRegion: " << ioRegion); m_ImageIO->SetIORegion(ioRegion); char *loadBuffer = 0; // the size of the buffer is computed based on the actual number of // pixels to be read and the actual size of the pixels to be read // (as opposed to the sizes of the output) try { if ( m_ImageIO->GetComponentTypeInfo() != typeid(ITK_TYPENAME ConvertPixelTraits::ComponentType) || (m_ImageIO->GetNumberOfComponents() != ConvertPixelTraits::GetNumberOfComponents())) { // the pixel types don't match so a type conversion needs to be // performed itkDebugMacro(<< "Buffer conversion required from: " << m_ImageIO->GetComponentTypeInfo().name() << " to: " << typeid(ITK_TYPENAME ConvertPixelTraits::ComponentType).name()); loadBuffer = new char[m_ImageIO->GetImageSizeInBytes()]; m_ImageIO->Read( static_cast< void *>(loadBuffer) ); // See note below as to why the buffered region is needed and // not actualIOregion this->DoConvertBuffer(static_cast< void *>(loadBuffer), output->GetBufferedRegion().GetNumberOfPixels() ); } else // a type conversion is not necessary { itkDebugMacro(<< "No buffer conversion required."); ImagePixelType *buffer = this->m_Image->GetPixelContainer()->GetBufferPointer(); m_ImageIO->Read( buffer ); } } catch (...) { // if an exception is thrown catch it if (loadBuffer) { // clean up delete [] loadBuffer; loadBuffer = 0; } // then rethrow throw; } // clean up if (loadBuffer) { delete [] loadBuffer; loadBuffer = 0; } ImageRegionIterator Id( this->GetOutput(), this->GetOutput()->GetLargestPossibleRegion() ); ImageRegionIterator It( this->m_Image, this->m_Image->GetLargestPossibleRegion() ); Id.GoToBegin(); It.GoToBegin(); while ( !Id.IsAtEnd() || !It.IsAtEnd() ) { VectorImagePixelType V = Id.Get(); V[i] = static_cast< typename VectorImagePixelType::ValueType>( It.Get() ); Id.Set( V ); ++Id; ++It; } } } template void VectorImageFileReader ::DoConvertBuffer(void* inputData, unsigned long numberOfPixels) { // get the pointer to the destination buffer ImagePixelType *imageData = this->m_Image->GetPixelContainer()->GetBufferPointer(); // TODO: // Pass down the PixelType (RGB, VECTOR, etc.) so that any vector to // scalar conversion be type specific. i.e. RGB to scalar would use // a formula to convert to luminance, VECTOR to scalar would use // vector magnitude. // Create a macro as this code is a bit lengthy and repetitive // if the ImageIO pixel type is typeid(type) then use the ConvertPixelBuffer // class to convert the data block to TImage's pixel type // see DefaultConvertPixelTraits and ConvertPixelBuffer // The first else if block applies only to images of type itk::VectorImage // VectorImage needs to copy out the buffer differently.. The buffer is of // type InternalPixelType, but each pixel is really 'k' consecutive pixels. #define ITK_CONVERT_BUFFER_IF_BLOCK(type) \ else if( m_ImageIO->GetComponentTypeInfo() == typeid(type) ) \ { \ if( strcmp( this->GetOutput()->GetNameOfClass(), "VectorImage" ) == 0 ) \ { \ ConvertPixelBuffer< \ type, \ ImagePixelType, \ ConvertPixelTraits \ > \ ::ConvertVectorImage( \ static_cast(inputData), \ m_ImageIO->GetNumberOfComponents(), \ imageData, \ numberOfPixels); \ } \ else \ { \ ConvertPixelBuffer< \ type, \ ImagePixelType, \ ConvertPixelTraits \ > \ ::Convert( \ static_cast(inputData), \ m_ImageIO->GetNumberOfComponents(), \ imageData, \ numberOfPixels); \ } \ } if(0) { } ITK_CONVERT_BUFFER_IF_BLOCK(unsigned char) ITK_CONVERT_BUFFER_IF_BLOCK(char) ITK_CONVERT_BUFFER_IF_BLOCK(unsigned short) ITK_CONVERT_BUFFER_IF_BLOCK( short) ITK_CONVERT_BUFFER_IF_BLOCK(unsigned int) ITK_CONVERT_BUFFER_IF_BLOCK( int) ITK_CONVERT_BUFFER_IF_BLOCK(unsigned long) ITK_CONVERT_BUFFER_IF_BLOCK( long) ITK_CONVERT_BUFFER_IF_BLOCK(float) ITK_CONVERT_BUFFER_IF_BLOCK( double) else { VectorImageFileReaderException e(__FILE__, __LINE__); OStringStream msg; msg <<"Couldn't convert component type: " << std::endl << " " << m_ImageIO->GetComponentTypeAsString(m_ImageIO->GetComponentType()) << std::endl << "to one of: " << std::endl << " " << typeid(unsigned char).name() << std::endl << " " << typeid(char).name() << std::endl << " " << typeid(unsigned short).name() << std::endl << " " << typeid(short).name() << std::endl << " " << typeid(unsigned int).name() << std::endl << " " << typeid(int).name() << std::endl << " " << typeid(unsigned long).name() << std::endl << " " << typeid(long).name() << std::endl << " " << typeid(float).name() << std::endl << " " << typeid(double).name() << std::endl; e.SetDescription(msg.str().c_str()); e.SetLocation(ITK_LOCATION); throw e; return; } #undef ITK_CONVERT_BUFFER_IF_BLOCK } } //namespace ITK #endif ants-1.9.2+svn680.dfsg/Utilities/itkVectorImageFileWriter.h000066400000000000000000000161431147325206600235230ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorImageFileWriter.h,v $ Language: C++ Date: $$ Version: $ $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkVectorImageFileWriter_h #define __itkVectorImageFileWriter_h #include "itkProcessObject.h" #include "itkImageIOBase.h" #include "itkExceptionObject.h" #include "itkSize.h" #include "itkImageIORegion.h" namespace itk { /** \brief Base exception class for IO problems during writing. */ class VectorImageFileWriterException : public ExceptionObject { public: /** Run-time information. */ itkTypeMacro( VectorImageFileWriterException, ExceptionObject ); /** Constructor. */ VectorImageFileWriterException(const char *file, unsigned int line, const char* message = "Error in IO", const char* loc = "Unknown" ) : ExceptionObject(file, line, message, loc) { } /** Constructor. */ VectorImageFileWriterException(const std::string &file, unsigned int line, const char* message = "Error in IO", const char* loc = "Unknown" ) : ExceptionObject(file, line, message, loc) { } }; /** \class VectorImageFileWriter * \brief Writes the deformation field as component images files. * * \sa VectorImageFileWriter * \sa ImageSeriesReader * \sa ImageIOBase * * \ingroup IOFilters */ template class ITK_EXPORT VectorImageFileWriter : public ProcessObject { public: /** Standard class typedefs. */ typedef VectorImageFileWriter Self; typedef ProcessObject Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods). */ itkTypeMacro(VectorImageFileWriter, VectorImageFileWriter); /** Some convenient typedefs. */ typedef TVectorImage VectorImageType; typedef typename VectorImageType::Pointer VectorImagePointer; typedef typename VectorImageType::RegionType VectorImageRegionType; typedef typename VectorImageType::PixelType VectorImagePixelType; typedef TImage ImageType; typedef typename ImageType::Pointer ImagePointer; typedef typename ImageType::RegionType ImageRegionType; typedef typename ImageType::PixelType ImagePixelType; /** Set/Get the image input of this writer. */ void SetInput(const VectorImageType *input); const VectorImageType * GetInput(void); const VectorImageType * GetInput(unsigned int idx); /** Specify the name of the output file to write. */ itkSetStringMacro(FileName); itkGetStringMacro(FileName); /** Set/Get the ImageIO helper class. Usually this is created via the object * factory mechanism that determines whether a particular ImageIO can * write a certain file. This method provides a way to get the ImageIO * instance that is created, or one can be manually set where the * IO factory mechanism may not work (for example, raw image files or * image files with non-standard filename suffix's. * If the user specifies the ImageIO, we assume she makes the * correct choice and will allow a file to be created regardless of * the file extension. If the factory has set the ImageIO, the * extension must be supported by the specified ImageIO. */ void SetImageIO (ImageIOBase* io) { if (this->m_ImageIO != io) { this->Modified(); this->m_ImageIO = io; } m_FactorySpecifiedImageIO = false; } itkGetObjectMacro(ImageIO,ImageIOBase); /** A special version of the Update() method for writers. It * invokes start and end events and handles releasing data. It * eventually calls GenerateData() which does the actual writing. * Note: the write method will write data specified by the * IORegion. If not set, then then the whole image is written. Note * that the region will be cropped to fit the input image's * LargestPossibleRegion. */ virtual void Write(void); /** Specify the region to write. If left NULL, then the whole image * is written. */ void SetIORegion(const ImageIORegion & region); itkGetConstReferenceMacro( IORegion, ImageIORegion ); /** Aliased to the Write() method to be consistent with the rest of the * pipeline. */ virtual void Update() {this->Write();} /** Set the compression On or Off */ itkSetMacro(UseCompression,bool); itkGetConstReferenceMacro(UseCompression,bool); itkBooleanMacro(UseCompression); /** Set the Avants' naming convention On or Off */ itkSetMacro(UseAvantsNamingConvention,bool); itkGetConstReferenceMacro(UseAvantsNamingConvention,bool); itkBooleanMacro(UseAvantsNamingConvention); /** Set the Avants' naming convention On or Off */ itkSetMacro(UseZhangNamingConvention,bool); itkGetConstReferenceMacro(UseZhangNamingConvention,bool); itkBooleanMacro(UseZhangNamingConvention); /** By default the MetaDataDictionary is taken from the input image and * passed to the ImageIO. In some cases, however, a user may prefer to * introduce her/his own MetaDataDictionary. This is often the case of * the ImageSeriesWriter. This flag defined whether the MetaDataDictionary * to use will be the one from the input image or the one already set in * the ImageIO object. */ itkSetMacro(UseInputMetaDataDictionary,bool); itkGetConstReferenceMacro(UseInputMetaDataDictionary,bool); itkBooleanMacro(UseInputMetaDataDictionary); protected: VectorImageFileWriter(); ~VectorImageFileWriter(); void PrintSelf(std::ostream& os, Indent indent) const; /** Does the real work. */ void GenerateData(void); private: VectorImageFileWriter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented std::string m_FileName; std::string m_ComponentImageFileName; bool m_UseAvantsNamingConvention; bool m_UseZhangNamingConvention; ImagePointer m_Image; ImageIOBase::Pointer m_ImageIO; bool m_UserSpecifiedImageIO; //track whether the ImageIO is user specified ImageIORegion m_IORegion; bool m_UserSpecifiedIORegion; // //track whether the region is user specified bool m_FactorySpecifiedImageIO; //track whether the factory mechanism set the ImageIO bool m_UseCompression; bool m_UseInputMetaDataDictionary; // whether to use the MetaDataDictionary from the input or not. }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkVectorImageFileWriter.txx" #endif #endif // __itkVectorImageFileWriter_h ants-1.9.2+svn680.dfsg/Utilities/itkVectorImageFileWriter.txx000066400000000000000000000310151147325206600241120ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkVectorImageFileWriter.txx,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.16 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkVectorImageFileWriter_txx #define _itkVectorImageFileWriter_txx #include "itkVectorImageFileWriter.h" #include "itkImageFileWriter.h" #include "itkDataObject.h" #include "itkObjectFactoryBase.h" #include "itkImageIOFactory.h" #include "itkCommand.h" #include "vnl/vnl_vector.h" #include "itkVectorImage.h" #include "itkVectorIndexSelectionCastImageFilter.h" namespace itk { //--------------------------------------------------------- template VectorImageFileWriter ::VectorImageFileWriter(): m_FileName(""), m_ImageIO(0), m_UserSpecifiedImageIO(false), m_UserSpecifiedIORegion(false) { m_UseCompression = false; m_UseInputMetaDataDictionary = true; m_FactorySpecifiedImageIO = false; m_UseAvantsNamingConvention = true; m_UseZhangNamingConvention = false; } //--------------------------------------------------------- template VectorImageFileWriter ::~VectorImageFileWriter() { } //--------------------------------------------------------- template void VectorImageFileWriter ::SetInput(const VectorImageType *input) { this->ProcessObject::SetNthInput(0, const_cast(input ) ); } //--------------------------------------------------------- template const typename VectorImageFileWriter::VectorImageType * VectorImageFileWriter ::GetInput(void) { if (this->GetNumberOfInputs() < 1) { return 0; } return static_cast (this->ProcessObject::GetInput(0)); } //--------------------------------------------------------- template const typename VectorImageFileWriter::VectorImageType * VectorImageFileWriter ::GetInput(unsigned int idx) { return static_cast (this->ProcessObject::GetInput(idx)); } //--------------------------------------------------------- template void VectorImageFileWriter ::SetIORegion (const ImageIORegion& region) { itkDebugMacro("setting IORegion to " << region ); if ( m_IORegion != region) { m_IORegion = region; this->Modified(); m_UserSpecifiedIORegion = true; } } //--------------------------------------------------------- template void VectorImageFileWriter ::GenerateData(void) { itkDebugMacro(<<"Writing file: " << m_ComponentImageFileName); // Make sure that the image is the right type and no more than // four components. typedef typename ImageType::PixelType ScalarType; if( strcmp( m_Image->GetNameOfClass(), "VectorImage" ) == 0 ) { typedef typename ImageType::InternalPixelType VectorImageScalarType; m_ImageIO->SetPixelTypeInfo( typeid(VectorImageScalarType) ); typedef typename ImageType::AccessorFunctorType AccessorFunctorType; m_ImageIO->SetNumberOfComponents( AccessorFunctorType::GetVectorLength( m_Image ) ); } else { // Set the pixel and component type; the number of components. m_ImageIO->SetPixelTypeInfo(typeid(ScalarType)); } // Setup the image IO for writing. // m_ImageIO->SetFileName(m_ComponentImageFileName.c_str()); //okay, now extract the data as a raw buffer pointer const void* dataPtr = (const void*) this->m_Image->GetBufferPointer(); m_ImageIO->Write(dataPtr); } //--------------------------------------------------------- template void VectorImageFileWriter ::Write() { typedef VectorIndexSelectionCastImageFilter SelectorType; typename SelectorType::Pointer selector = SelectorType::New(); selector->SetInput( this->GetInput() ); unsigned int dimension = itk::GetVectorDimension ::VectorDimension; std::string filename = this->m_FileName; std::string::size_type pos = this->m_FileName.rfind( "." ); std::string extension( this->m_FileName, pos, this->m_FileName.length()-1 ); std::string gzExtension( "" ); if ( extension == std::string( ".gz" ) ) { gzExtension = extension; filename = std::string( filename, 0, pos ); pos = filename.rfind( "." ); extension = std::string( filename, pos, this->m_FileName.length()-1 ); } for ( unsigned int i = 0; i < dimension; i++ ) { selector->SetIndex( i ); selector->Update(); std::string filename( this->m_FileName, 0, pos ); if ( this->m_UseAvantsNamingConvention && dimension <= 3 ) { switch ( i ) { case 0: filename += std::string( "xvec" ); break; case 1: filename += std::string( "yvec" ); break; case 2: filename += std::string( "zvec" ); break; default: filename += std::string( "you_are_screwed_vec" ); break; } } else if ( this->m_UseZhangNamingConvention && dimension == 6 ) { switch ( i ) { case 0: filename += std::string( "xx" ); break; case 1: filename += std::string( "yx" ); break; case 2: filename += std::string( "yy" ); break; case 3: filename += std::string( "zx" ); break; case 4: filename += std::string( "zy" ); break; case 5: filename += std::string( "zz" ); break; default: filename += std::string( "you_are_screwed" ); break; } } else { itk::OStringStream buf; buf << i; filename += ( std::string( "." ) + std::string( buf.str().c_str() ) ); } filename += extension; if ( !gzExtension.empty() ) { filename += std::string( ".gz" ); } m_ComponentImageFileName = filename; ImageType *input = selector->GetOutput(); this->m_Image = selector->GetOutput(); itkDebugMacro( <<"Writing an image file" ); // Make sure input is available if ( input == 0 ) { itkExceptionMacro(<< "No input to writer!"); } // Make sure that we can write the file given the name // if ( filename == "" ) { itkExceptionMacro(<<"No filename was specified"); } if ( m_ImageIO.IsNull() ) //try creating via factory { itkDebugMacro(<<"Attempting factory creation of ImageIO for file: " << filename); m_ImageIO = ImageIOFactory::CreateImageIO( filename.c_str(), ImageIOFactory::WriteMode ); m_FactorySpecifiedImageIO = true; } else { if( m_FactorySpecifiedImageIO && !m_ImageIO->CanWriteFile( filename.c_str() ) ) { itkDebugMacro(<<"ImageIO exists but doesn't know how to write file:" << m_FileName ); itkDebugMacro(<<"Attempting creation of ImageIO with a factory for file:" << m_FileName); m_ImageIO = ImageIOFactory::CreateImageIO( filename.c_str(), ImageIOFactory::WriteMode ); m_FactorySpecifiedImageIO = true; } } if ( m_ImageIO.IsNull() ) { ImageFileWriterException e(__FILE__, __LINE__); OStringStream msg; msg << " Could not create IO object for file " << filename.c_str() << std::endl; msg << " Tried to create one of the following:" << std::endl; std::list allobjects = ObjectFactoryBase::CreateAllInstance("itkImageIOBase"); for(std::list::iterator i = allobjects.begin(); i != allobjects.end(); ++i) { ImageIOBase* io = dynamic_cast(i->GetPointer()); msg << " " << io->GetNameOfClass() << std::endl; } msg << " You probably failed to set a file suffix, or" << std::endl; msg << " set the suffix to an unsupported type." << std::endl; e.SetDescription(msg.str().c_str()); e.SetLocation(ITK_LOCATION); throw e; } // NOTE: this const_cast<> is due to the lack of const-correctness // of the ProcessObject. ImageType *nonConstImage = input; typedef typename TImage::RegionType RegionType; if ( ! m_UserSpecifiedIORegion ) { // Make sure the data is up-to-date. if( nonConstImage->GetSource() ) { nonConstImage->GetSource()->UpdateLargestPossibleRegion(); } // Write the whole image ImageIORegion ioRegion(TImage::ImageDimension); RegionType region = this->m_Image->GetLargestPossibleRegion(); for(unsigned int i=0; iUpdate(); } // Setup the ImageIO // m_ImageIO->SetNumberOfDimensions(TImage::ImageDimension); RegionType region = this->m_Image->GetLargestPossibleRegion(); const typename TImage::SpacingType& spacing = this->m_Image->GetSpacing(); const typename TImage::PointType& origin = this->m_Image->GetOrigin(); const typename TImage::DirectionType& direction = this->m_Image->GetDirection(); for(unsigned int k=0; kSetDimensions(k,region.GetSize(k)); m_ImageIO->SetSpacing(k,spacing[k]); m_ImageIO->SetOrigin(k,origin[k]); vnl_vector< double > axisDirection(TVectorImage::ImageDimension); // Please note: direction cosines are stored as columns of the // direction matrix for(unsigned int j=0; jSetDirection( k, axisDirection ); } m_ImageIO->SetUseCompression(m_UseCompression); m_ImageIO->SetIORegion(m_IORegion); if( m_UseInputMetaDataDictionary ) { m_ImageIO->SetMetaDataDictionary(input->GetMetaDataDictionary()); } // Notify start event observers this->InvokeEvent( StartEvent() ); // Actually do something this->GenerateData(); // Notify end event observers this->InvokeEvent( EndEvent() ); // Release upstream data if requested if ( input->ShouldIReleaseData() ) { nonConstImage->ReleaseData(); } } } //--------------------------------------------------------- template void VectorImageFileWriter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); os << indent << "File Name: " << (m_FileName.data() ? m_FileName.data() : "(none)") << std::endl; os << "Number of vector components (i.e. number of images created): " << itk::GetVectorDimension::VectorDimension << std::endl; os << indent << "Image IO: "; if ( m_ImageIO.IsNull() ) { os << "(none)\n"; } else { os << m_ImageIO << "\n"; } os << indent << "IO Region: " << m_IORegion << "\n"; if (m_UseCompression) { os << indent << "Compression: On\n"; } else { os << indent << "Compression: Off\n"; } if (m_UseInputMetaDataDictionary) { os << indent << "UseInputMetaDataDictionary: On\n"; } else { os << indent << "UseInputMetaDataDictionary: Off\n"; } if (m_FactorySpecifiedImageIO) { os << indent << "FactorySpecifiedmageIO: On\n"; } else { os << indent << "FactorySpecifiedmageIO: Off\n"; } } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkWarpImageMultiTransformFilter.h000066400000000000000000000303411147325206600252460ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpImageMultiTransformFilter.h,v $ Language: C++ Date: $Date: 2009/01/08 21:36:48 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef ITKWARPIMAGEMULTITRANSFORMFILTER_H_ #define ITKWARPIMAGEMULTITRANSFORMFILTER_H_ #include "itkImageToImageFilter.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkVectorGaussianInterpolateImageFunction.h" #include "itkPoint.h" #include "itkFixedArray.h" #include "itkRecursiveGaussianImageFilter.h" #include namespace itk { /** \class WarpImageMultiTransformFilter * \brief Warps an image using an input deformation field. * * WarpImageMultiTransformFilter warps an existing image with respect to * a given deformation field. * * A deformation field is represented as a image whose pixel type is some * vector type with at least N elements, where N is the dimension of * the input image. The vector type must support element access via operator * []. * * The output image is produced by inverse mapping: the output pixels * are mapped back onto the input image. This scheme avoids the creation of * any holes and overlaps in the output image. * * Each vector in the deformation field represent the distance between * a geometric point in the input space and a point in the output space such * that: * * \f[ p_{in} = p_{out} + d \f] * * Typically the mapped position does not correspond to an integer pixel * position in the input image. Interpolation via an image function * is used to compute values at non-integer positions. The default * interpolation typed used is the LinearInterpolateImageFunction. * The user can specify a particular interpolation function via * SetInterpolator(). Note that the input interpolator must derive * from base class InterpolateImageFunction. * * Position mapped to outside of the input image buffer are assigned * a edge padding value. * * The LargetPossibleRegion for the output is inherited from the * input deformation field. The output image spacing and origin may be set * via SetOutputSpacing, SetOutputOrigin. The default are respectively a * vector of 1's and a vector of 0's. * * This class is templated over the type of the input image, the * type of the output image and the type of the deformation field. * * The input image is set via SetInput. The input deformation field * is set via SetDeformationField. * * This filter is implemented as a multithreaded filter. * * \warning This filter assumes that the input type, output type * and deformation field type all have the same number of dimensions. * * \ingroup GeometricTransforms MultiThreaded */ template < class TInputImage, class TOutputImage, class TDeformationField, class TTransform > class ITK_EXPORT WarpImageMultiTransformFilter : public ImageToImageFilter { public: /** transform order type **/ // typedef enum _TransformOrderType {AffineFirst=0, AffineLast} TransformOrderType; /** transform type **/ typedef enum _SingleTransformType {EnumAffineType=0, EnumDeformationFieldType} SingleTransformType; /** Standard class typedefs. */ typedef WarpImageMultiTransformFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro( WarpImageMultiTransformFilter, ImageToImageFilter ); /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Inherit some types from the superclass. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImagePointer InputImagePointer; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImagePointer OutputImagePointer; typedef typename Superclass::InputImageConstPointer InputImageConstPointer; typedef typename OutputImageType::IndexType IndexType; typedef typename OutputImageType::SizeType SizeType; typedef typename OutputImageType::PixelType PixelType; typedef typename OutputImageType::SpacingType SpacingType; typedef typename OutputImageType::DirectionType DirectionType; /** Determine the image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro(DeformationFieldDimension, unsigned int, TDeformationField::ImageDimension ); /** Deformation field typedef support. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType DisplacementType; typedef typename DisplacementType::ValueType DisplacementScalarValueType; /** songgang: Affine transform typedef support. */ typedef TTransform TransformType; typedef typename TransformType::Pointer TransformTypePointer; /** Interpolator typedef support. */ typedef double CoordRepType; typedef InterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef LinearInterpolateImageFunction DefaultInterpolatorType; typedef VectorLinearInterpolateImageFunction DefaultVectorInterpolatorType; typedef VectorGaussianInterpolateImageFunction DefaultVectorInterpolatorType2; typedef typename DefaultVectorInterpolatorType::Pointer VectorInterpolatorPointer; /** Point type */ typedef Point PointType; typedef struct _DeformationTypeEx{ DeformationFieldPointer field; VectorInterpolatorPointer vinterp; } DeformationTypeEx; typedef struct _AffineTypeEx{ TransformTypePointer aff; } AffineTypeEx; typedef struct _VarTransformType{ AffineTypeEx aex; DeformationTypeEx dex; } VarTransformType; typedef std::pair SingleTransformItemType; typedef std::list TransformListType; /** Set the interpolator function. */ itkSetObjectMacro( Interpolator, InterpolatorType ); /** Get a pointer to the interpolator function. */ itkGetObjectMacro( Interpolator, InterpolatorType ); /** Set the output image spacing. */ itkSetMacro(OutputSpacing, SpacingType); virtual void SetOutputSpacing( const double* values); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputSpacing, SpacingType); /** Set the output image spacing. */ itkSetMacro(OutputDirection, DirectionType); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputDirection, DirectionType); /** Set the output image origin. */ itkSetMacro(OutputOrigin, PointType); virtual void SetOutputOrigin( const double* values); /** Get the output image origin. */ itkGetConstReferenceMacro(OutputOrigin, PointType); /** Set the output image size. */ itkSetMacro(OutputSize, SizeType); // virtual void SetOutputSize( const double *values); itkGetConstReferenceMacro(OutputSize, SizeType); /** Set the edge padding value */ itkSetMacro( EdgePaddingValue, PixelType ); /** Get the edge padding value */ itkGetMacro( EdgePaddingValue, PixelType ); TransformListType & GetTransformList(){ return m_TransformList; } void PrintTransformList(); /** WarpImageMultiTransformFilter produces an image which is a different * size than its input image. As such, it needs to provide an * implemenation for GenerateOutputInformation() which set * the output information according the OutputSpacing, OutputOrigin * and the deformation field's LargestPossibleRegion. */ virtual void GenerateOutputInformation(); /** It is difficult to compute in advance the input image region * required to compute the requested output region. Thus the safest * thing to do is to request for the whole input image. * * For the deformation field, the input requested region * set to be the same as that of the output requested region. */ virtual void GenerateInputRequestedRegion(); /** This method is used to set the state of the filter before * multi-threading. */ virtual void BeforeThreadedGenerateData(); /** This method is used to set the state of the filter after * multi-threading. */ virtual void AfterThreadedGenerateData(); /** precompute the smoothed image if necessary **/ void SetSmoothScale(double scale); double GetSmoothScale() {return m_SmoothScale;}; // void UpdateSizeByScale(); void PushBackAffineTransform(const TransformType* t); void PushBackDeformationFieldTransform(const DeformationFieldType* t); void ComposeAffineOnlySequence(const PointType ¢er_output, TransformTypePointer &affine_output); bool MultiInverseAffineOnlySinglePoint(const PointType &point1, PointType &point2); bool MultiTransformSinglePoint(const PointType &point1, PointType &point2); bool MultiTransformPoint(const PointType &point1, PointType &point2, bool bFisrtDeformNoInterp, const IndexType &index); void DetermineFirstDeformNoInterp(); inline bool IsOutOfNumericBoundary(const PointType &p); // set interpolator from outside // virtual void SetInterpolator(InterpolatorPointer interp); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(SameDimensionCheck1, (Concept::SameDimension)); itkConceptMacro(SameDimensionCheck2, (Concept::SameDimension)); //removed to be compatible with vector form input image // itkConceptMacro(InputHasNumericTraitsCheck, // (Concept::HasNumericTraits)); itkConceptMacro(DeformationFieldHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif bool m_bFirstDeformNoInterp; protected: WarpImageMultiTransformFilter(); ~WarpImageMultiTransformFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; /** WarpImageMultiTransformFilter is implemented as a multi-threaded filter. * As such, it needs to provide and implementation for * ThreadedGenerateData(). */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); InterpolatorPointer m_Interpolator; PixelType m_EdgePaddingValue; SpacingType m_OutputSpacing; PointType m_OutputOrigin; SizeType m_OutputSize; DirectionType m_OutputDirection; TransformListType m_TransformList; double m_SmoothScale; InputImagePointer m_CachedSmoothImage; private: WarpImageMultiTransformFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkWarpImageMultiTransformFilter.txx" #endif #endif /*ITKWARPIMAGEMULTITRANSFORMFILTER_H_*/ ants-1.9.2+svn680.dfsg/Utilities/itkWarpImageMultiTransformFilter.txx000066400000000000000000000500521147325206600256430ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpImageMultiTransformFilter.txx,v $ Language: C++ Date: $Date: 2009/01/08 21:36:48 $ Version: $Revision: 1.18 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWarpImageMultiTransformFilter_txx #define __itkWarpImageMultiTransformFilter_txx #include "itkWarpImageMultiTransformFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include namespace itk { /** * Default constructor. */ template WarpImageMultiTransformFilter ::WarpImageMultiTransformFilter() { // Setup the number of required inputs this->SetNumberOfRequiredInputs( 1 ); // Setup default values m_OutputSpacing.Fill( 1.0 ); m_OutputOrigin.Fill( 0.0 ); m_EdgePaddingValue = NumericTraits::Zero; // Setup default interpolator typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_Interpolator = static_cast( interp.GetPointer() ); m_SmoothScale = -1; // m_bOutputDeformationField = false; // m_TransformOrder = AffineFirst; } //template //void //WarpImageMultiTransformFilter //::SetInterpolator1(InterpolatorPointer interp) //{ // m_Interpolator = static_cast (interp.GetPointer()); // std::cout << "set interpolator in WarpImage:" << interp << std::endl; //} template void WarpImageMultiTransformFilter ::PrintTransformList() { std::cout << "transform list: " << std::endl; typename TransformListType::iterator it = (m_TransformList.begin()); for(int ii=0; it != m_TransformList.end(); it++, ii++){ switch(it->first){ case EnumAffineType: std::cout << '[' << ii << "]: EnumAffineType" << std::endl; std::cout << it->second.aex.aff << std::endl; break; case EnumDeformationFieldType: std::cout << '[' << ii << "]: EnumDeformationFieldType: size" << it->second.dex.field->GetLargestPossibleRegion().GetSize() << std::endl; } } } /** * Standard PrintSelf method. */ template void WarpImageMultiTransformFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "OutputSpacing: " << m_OutputSpacing << std::endl;; os << indent << "OutputOrigin: " << m_OutputOrigin << std::endl; os << indent << "EdgePaddingValue: " << static_cast::PrintType>(m_EdgePaddingValue) << std::endl; os << indent << "Interpolator: " << m_Interpolator.GetPointer() << std::endl; os << indent << "m_bFirstDeformNoInterp = " << m_bFirstDeformNoInterp << std::endl; } /** * Set the output image spacing. * */ template void WarpImageMultiTransformFilter ::SetOutputSpacing( const double* spacing) { SpacingType s(spacing); this->SetOutputSpacing( s ); } /** * Set the output image origin. * */ template void WarpImageMultiTransformFilter ::SetOutputOrigin( const double* origin) { PointType p(origin); this->SetOutputOrigin(p); } /** * Setup state of filter before multi-threading. * InterpolatorType::SetInputImage is not thread-safe and hence * has to be setup before ThreadedGenerateData */ template void WarpImageMultiTransformFilter ::BeforeThreadedGenerateData() { if( !m_Interpolator ) { itkExceptionMacro(<< "Interpolator not set"); } // Connect input image to interpolator // m_Interpolator->SetInputImage( this->GetInput() ); if (m_CachedSmoothImage.IsNull() && (this->GetInput() )){ m_CachedSmoothImage = const_cast (this->GetInput()); } m_Interpolator->SetInputImage( m_CachedSmoothImage ); } /** * Setup state of filter after multi-threading. */ template void WarpImageMultiTransformFilter ::AfterThreadedGenerateData() { // Disconnect input image from interpolator m_Interpolator->SetInputImage( NULL ); } template void WarpImageMultiTransformFilter ::GenerateInputRequestedRegion() { // call the superclass's implementation Superclass::GenerateInputRequestedRegion(); // request the largest possible region for the input image InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if( inputPtr ) { inputPtr->SetRequestedRegionToLargestPossibleRegion(); } return; } template void WarpImageMultiTransformFilter ::GenerateOutputInformation() { // call the superclass's implementation of this method Superclass::GenerateOutputInformation(); OutputImagePointer outputPtr = this->GetOutput(); if ( !outputPtr ) { return; } typename TOutputImage::RegionType outputLargestPossibleRegion; outputLargestPossibleRegion.SetSize( this->m_OutputSize ); // outputLargestPossibleRegion.SetIndex( 0 ); outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion ); outputPtr->SetSpacing( this->m_OutputSpacing ); outputPtr->SetOrigin( this->m_OutputOrigin ); outputPtr->SetDirection( this->m_OutputDirection ); // determine if the deformation field is the same dimension as the image // so that it does not need interpolation in the first step DetermineFirstDeformNoInterp(); } template void WarpImageMultiTransformFilter ::SetSmoothScale(double scale) { /* if (m_SmoothScale != scale){ // compute the new cached // std::cout << "change smooth scale: " << m_SmoothScale << " ---> " << scale << std::endl; m_SmoothScale = scale; typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSpacing(); typename InputImageType::RegionType::SizeType inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize(); typename InputImageType::SpacingType outputSpacing; typename InputImageType::RegionType::SizeType outputSize; double minimumSpacing = inputSpacing.GetVnlVector().min_value(); double maximumSpacing = inputSpacing.GetVnlVector().max_value(); InputImagePointer image = const_cast (this->GetInput()); for ( unsigned int d = 0; d < ImageDimension; d++ ) { double scaling = vnl_math_min( 1.0 / scale * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); double sigma = 0.25 * ( outputSpacing[d] / inputSpacing[d] ); if (sigma < 0) sigma=0; typedef RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); // std::cout << "scale = " << scale << " => " << "sigma of dim " << d << ": " << sigma << " out size " << outputSize << " spc1 " << outputSpacing << " in " << inputSpacing << std::endl; smoother->SetSigma( sigma ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); image = smoother->GetOutput(); } } SetOutputSpacing( outputSpacing ); SetOutputOrigin( this->GetInput()->GetOrigin() ); SetOutputSize(outputSize); } */ InputImagePointer image = const_cast (this->GetInput()); m_CachedSmoothImage = image; } /** * Compute the output for the region specified by outputRegionForThread. */ template void WarpImageMultiTransformFilter ::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, int threadId ) { InputImageConstPointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); //std::cout << "inputPtr->GetOrigin():" << inputPtr->GetOrigin() << std::endl; //std::cout << "outputPtr->GetOrigin():" << outputPtr->GetOrigin() << std::endl; // exit(-1); IndexType index; index.Fill(0); this->m_EdgePaddingValue=inputPtr->GetPixel(index); // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // iterator for the output image ImageRegionIteratorWithIndex outputIt(outputPtr, outputRegionForThread); while( !outputIt.IsAtEnd() ) { PointType point1, point2; // get the output image index IndexType index = outputIt.GetIndex(); outputPtr->TransformIndexToPhysicalPoint( index, point1 ); bool isinside = MultiTransformPoint(point1, point2, m_bFirstDeformNoInterp, index); // std::cout << "point1:" << point1 << " point2:" << point2 << " index:" << index << std::endl; // exit(-1); // warp the image // get the interpolated value if( isinside && (m_Interpolator->IsInsideBuffer( point2 )) ) { PixelType value = static_cast(m_Interpolator->Evaluate(point2)); outputIt.Set( value ); } else { // std::cout << "OUTSIDE" << " isinside:" << isinside << " m_Interpolator->IsInsideBuffer( point2 ):" << m_Interpolator->IsInsideBuffer( point2 ) << std::endl; outputIt.Set( m_EdgePaddingValue ); } ++outputIt; } progress.CompletedPixel(); } //template //void //WarpImageMultiTransformFilter //::UpdateSizeByScale() //{ // // // DeformationFieldPointer field = this->GetDeformationField(); // // // // SetOutputSpacing( field->GetSpacing() / m_SmoothScale ); // // SetOutputOrigin( field->GetOrigin() ); // // // // typename InputImageType::SizeType imgsz = field->GetLargestPossibleRegion().GetSize(); // // for(int ii = 0; ii < InputImageType::ImageDimension; ii++) imgsz[ii] = (typename InputImageType::SizeType::SizeValueType) (imgsz[ii] * m_SmoothScale + 0.5); // // // // SetOutputSize(imgsz); // //} template void WarpImageMultiTransformFilter ::PushBackAffineTransform(const TransformType* t) { if (t){ VarTransformType t1; t1.aex.aff = const_cast (t); m_TransformList.push_back(SingleTransformItemType(EnumAffineType, t1)); } } template void WarpImageMultiTransformFilter ::PushBackDeformationFieldTransform(const DeformationFieldType* t) { if (t){ VarTransformType t1; t1.dex.field = const_cast (t); t1.dex.vinterp = DefaultVectorInterpolatorType::New(); t1.dex.vinterp->SetInputImage(t1.dex.field); // t1.dex.vinterp->SetParameters(NULL,1); m_TransformList.push_back(SingleTransformItemType(EnumDeformationFieldType, t1)); } } template bool WarpImageMultiTransformFilter ::MultiTransformSinglePoint(const PointType &point1, PointType &point2) { IndexType null_index; bool isinside = MultiTransformPoint(point1, point2, false, null_index); return isinside; } template bool WarpImageMultiTransformFilter ::IsOutOfNumericBoundary(const PointType &p) { const DisplacementScalarValueType kMaxDisp = itk::NumericTraits::max(); bool b = false; for (int i = 0; i < ImageDimension; i++) { if (p[i]>=kMaxDisp ){ b = true; break; } } return b; } template void WarpImageMultiTransformFilter ::ComposeAffineOnlySequence(const PointType ¢er_output, TransformTypePointer &affine_output) { // std::cout << "test " ; // TransformTypePointer affine_output = TransformType::New(); affine_output->SetIdentity(); affine_output->SetCenter(center_output); // std::cout << affine_output; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; affine_output->Compose(aff, 0); // std::cout << affine_output; break; } case EnumDeformationFieldType: std::cout << " Ignore deformation type ... " << std::endl; break; default: itkExceptionMacro(<< "Single Transform Not Supported!"); } } return; } template bool WarpImageMultiTransformFilter ::MultiInverseAffineOnlySinglePoint(const PointType &p1, PointType &p2) { bool isinside = true; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; TransformTypePointer aff_inv = TransformTypePointer::ObjectType::New(); // std::cout << "aff before:" << aff << std::endl; aff->GetInverse(aff_inv); // aff->GetInverse(aff); // std::cout << "aff after:" << aff << std::endl; // std::cout << "aff_inv after:" << aff_inv << std::endl; point2 = aff_inv->TransformPoint(point1); point1 = point2; isinside = true; break; } case EnumDeformationFieldType: break; default: itkExceptionMacro(<< "Single Transform Not Supported!"); } if (IsOutOfNumericBoundary(point2)) {isinside = false; break;} point1 = point2; } p2 = point2; return isinside; } template bool WarpImageMultiTransformFilter ::MultiTransformPoint(const PointType &p1, PointType &p2, bool bFisrtDeformNoInterp, const IndexType &index) { bool isinside = false; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; point2 = aff->TransformPoint(point1); point1 = point2; isinside = true; } break; case EnumDeformationFieldType: { DeformationFieldPointer fieldPtr = it->second.dex.field; if (bFisrtDeformNoInterp && it==m_TransformList.begin() ){ // use discrete coordinates DisplacementType displacement = fieldPtr->GetPixel(index); for(int j = 0; jTransformPhysicalPointToContinuousIndex(point1, contind); isinside = fieldPtr->GetLargestPossibleRegion().IsInside( contind ); VectorInterpolatorPointer vinterp = it->second.dex.vinterp; typename DefaultVectorInterpolatorType::OutputType disp2; if (isinside) disp2 = vinterp->EvaluateAtContinuousIndex( contind ); else disp2.Fill(0); for (int jj=0; jj void WarpImageMultiTransformFilter ::DetermineFirstDeformNoInterp() { m_bFirstDeformNoInterp = false; if (m_TransformList.size() >0 ){ if ((m_TransformList.front().first == EnumDeformationFieldType)){ DeformationFieldPointer field = m_TransformList.front().second.dex.field; m_bFirstDeformNoInterp = (this->GetOutputSize() == field->GetLargestPossibleRegion().GetSize()) & (this->GetOutputSpacing() ==field->GetSpacing()) & (this->GetOutputOrigin() == field->GetOrigin()); // std::cout << "in set: field size: " << field->GetLargestPossibleRegion().GetSize() // << "output spacing: " << this->GetOutputSize() << std::endl; // std::cout << field->GetSpacing() << " | " << this->GetOutputSpacing() << std::endl; // std::cout << field->GetOrigin() << " | " << this->GetOutputOrigin() << std::endl; } } } } // end namespace itk #endif //__itkWarpImageMultiTransformFilter_txx ants-1.9.2+svn680.dfsg/Utilities/itkWarpImageWAffineFilter.h000066400000000000000000000247071147325206600236100ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpImageWAffineFilter.h,v $ Language: C++ Date: $Date: 2008/11/15 23:46:06 $ Version: $Revision: 1.15 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWarpImageWAffineFilter_h #define __itkWarpImageWAffineFilter_h #include "itkImageToImageFilter.h" #include "itkInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkPoint.h" #include "itkFixedArray.h" #include "itkRecursiveGaussianImageFilter.h" namespace itk { /** \class WarpImageWAffineFilter * \brief Warps an image using an input deformation field. * * WarpImageWAffineFilter warps an existing image with respect to * a given deformation field. * * A deformation field is represented as a image whose pixel type is some * vector type with at least N elements, where N is the dimension of * the input image. The vector type must support element access via operator * []. * * The output image is produced by inverse mapping: the output pixels * are mapped back onto the input image. This scheme avoids the creation of * any holes and overlaps in the output image. * * Each vector in the deformation field represent the distance between * a geometric point in the input space and a point in the output space such * that: * * \f[ p_{in} = p_{out} + d \f] * * Typically the mapped position does not correspond to an integer pixel * position in the input image. Interpolation via an image function * is used to compute values at non-integer positions. The default * interpolation typed used is the LinearInterpolateImageFunction. * The user can specify a particular interpolation function via * SetInterpolator(). Note that the input interpolator must derive * from base class InterpolateImageFunction. * * Position mapped to outside of the input image buffer are assigned * a edge padding value. * * The LargetPossibleRegion for the output is inherited from the * input deformation field. The output image spacing and origin may be set * via SetOutputSpacing, SetOutputOrigin. The default are respectively a * vector of 1's and a vector of 0's. * * This class is templated over the type of the input image, the * type of the output image and the type of the deformation field. * * The input image is set via SetInput. The input deformation field * is set via SetDeformationField. * * This filter is implemented as a multithreaded filter. * * \warning This filter assumes that the input type, output type * and deformation field type all have the same number of dimensions. * * \ingroup GeometricTransforms MultiThreaded */ template < class TInputImage, class TOutputImage, class TDeformationField, class TTransform > class ITK_EXPORT WarpImageWAffineFilter : public ImageToImageFilter { public: /** transform order type **/ typedef enum _TransformOrderType {AffineFirst=0, AffineLast} TransformOrderType; /** Standard class typedefs. */ typedef WarpImageWAffineFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro( WarpImageWAffineFilter, ImageToImageFilter ); /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Inherit some types from the superclass. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImagePointer InputImagePointer; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImagePointer OutputImagePointer; typedef typename Superclass::InputImageConstPointer InputImageConstPointer; typedef typename OutputImageType::IndexType IndexType; typedef typename OutputImageType::SizeType SizeType; typedef typename OutputImageType::PixelType PixelType; typedef typename OutputImageType::SpacingType SpacingType; /** Determine the image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro(DeformationFieldDimension, unsigned int, TDeformationField::ImageDimension ); /** Deformation field typedef support. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType DisplacementType; /** songgang: Affine transform typedef support. */ typedef TTransform TransformType; typedef typename TransformType::Pointer TransformTypePointer; /** Interpolator typedef support. */ typedef double CoordRepType; typedef InterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef LinearInterpolateImageFunction DefaultInterpolatorType; /** Point type */ typedef Point PointType; /** Set the deformation field. */ void SetDeformationField( const DeformationFieldType * field ); /** Get a pointer the deformation field. */ DeformationFieldType * GetDeformationField(void); /** songgang: Set / Get the affine transform. */ // void SetAffineTransform( const TransformType * aff ); // TransformType * GetAffineTransform(void); itkSetObjectMacro(AffineTransform, TransformType); itkGetObjectMacro(AffineTransform, TransformType); itkSetEnumMacro(TransformOrder, TransformOrderType); itkGetEnumMacro(TransformOrder, TransformOrderType); /** Set the interpolator function. */ itkSetObjectMacro( Interpolator, InterpolatorType ); /** Get a pointer to the interpolator function. */ itkGetObjectMacro( Interpolator, InterpolatorType ); /** Set the output image spacing. */ itkSetMacro(OutputSpacing, SpacingType); virtual void SetOutputSpacing( const double* values); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputSpacing, SpacingType); /** Set the output image origin. */ itkSetMacro(OutputOrigin, PointType); virtual void SetOutputOrigin( const double* values); /** Set the output image size. */ itkSetMacro(OutputSize, SizeType); // virtual void SetOutputSize( const double *values); itkGetConstReferenceMacro(OutputSize, SizeType); /** Get the output image origin. */ itkGetConstReferenceMacro(OutputOrigin, PointType); /** Set the edge padding value */ itkSetMacro( EdgePaddingValue, PixelType ); /** Get the edge padding value */ itkGetMacro( EdgePaddingValue, PixelType ); /** WarpImageWAffineFilter produces an image which is a different * size than its input image. As such, it needs to provide an * implemenation for GenerateOutputInformation() which set * the output information according the OutputSpacing, OutputOrigin * and the deformation field's LargestPossibleRegion. */ virtual void GenerateOutputInformation(); /** It is difficult to compute in advance the input image region * required to compute the requested output region. Thus the safest * thing to do is to request for the whole input image. * * For the deformation field, the input requested region * set to be the same as that of the output requested region. */ virtual void GenerateInputRequestedRegion(); /** This method is used to set the state of the filter before * multi-threading. */ virtual void BeforeThreadedGenerateData(); /** This method is used to set the state of the filter after * multi-threading. */ virtual void AfterThreadedGenerateData(); /** precompute the smoothed image if necessary **/ void SetSmoothScale(double scale); double GetSmoothScale() {return m_SmoothScale;}; void UpdateSizeByScale(); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(SameDimensionCheck1, (Concept::SameDimension)); itkConceptMacro(SameDimensionCheck2, (Concept::SameDimension)); itkConceptMacro(InputHasNumericTraitsCheck, (Concept::HasNumericTraits)); itkConceptMacro(DeformationFieldHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif protected: WarpImageWAffineFilter(); ~WarpImageWAffineFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; /** WarpImageWAffineFilter is implemented as a multi-threaded filter. * As such, it needs to provide and implementation for * ThreadedGenerateData(). */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); private: WarpImageWAffineFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented PixelType m_EdgePaddingValue; SpacingType m_OutputSpacing; PointType m_OutputOrigin; SizeType m_OutputSize; TransformOrderType m_TransformOrder; // songgang: affine transform TransformTypePointer m_AffineTransform; InterpolatorPointer m_Interpolator; /** cached smoothed image (for downsampling) **/ InputImagePointer m_CachedSmoothImage; double m_SmoothScale; }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkWarpImageWAffineFilter.txx" #endif #endif ants-1.9.2+svn680.dfsg/Utilities/itkWarpImageWAffineFilter.txx000066400000000000000000000375261147325206600242070ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpImageWAffineFilter.txx,v $ Language: C++ Date: $Date: 2008/11/10 15:39:12 $ Version: $Revision: 1.12 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWarpImageWAffineFilter_txx #define __itkWarpImageWAffineFilter_txx #include "itkWarpImageWAffineFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" #include "itkVectorLinearInterpolateImageFunction.h" namespace itk { /** * Default constructor. */ template WarpImageWAffineFilter ::WarpImageWAffineFilter() { // Setup the number of required inputs this->SetNumberOfRequiredInputs( 2 ); // Setup default values m_OutputSpacing.Fill( 1.0 ); m_OutputOrigin.Fill( 0.0 ); m_EdgePaddingValue = NumericTraits::Zero; // Setup default interpolator typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_Interpolator = static_cast( interp.GetPointer() ); m_SmoothScale = -1; m_TransformOrder = AffineFirst; } /** * Standard PrintSelf method. */ template void WarpImageWAffineFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "OutputSpacing: " << m_OutputSpacing << std::endl;; os << indent << "OutputOrigin: " << m_OutputOrigin << std::endl; os << indent << "EdgePaddingValue: " << static_cast::PrintType>(m_EdgePaddingValue) << std::endl; os << indent << "Interpolator: " << m_Interpolator.GetPointer() << std::endl; } /** * Set the output image spacing. * */ template void WarpImageWAffineFilter ::SetOutputSpacing( const double* spacing) { SpacingType s(spacing); this->SetOutputSpacing( s ); } /** * Set the output image origin. * */ template void WarpImageWAffineFilter ::SetOutputOrigin( const double* origin) { PointType p(origin); this->SetOutputOrigin(p); } /** * Set deformation field as Inputs[1] for this ProcessObject. * */ template void WarpImageWAffineFilter ::SetDeformationField( const DeformationFieldType * field ) { // const cast is needed because the pipeline is not const-correct. DeformationFieldType * input = const_cast< DeformationFieldType * >( field ); this->ProcessObject::SetNthInput( 1, input ); } /** * Return a pointer to the deformation field. */ template typename WarpImageWAffineFilter ::DeformationFieldType * WarpImageWAffineFilter ::GetDeformationField(void) { return static_cast ( this->ProcessObject::GetInput( 1 )); } /** * Setup state of filter before multi-threading. * InterpolatorType::SetInputImage is not thread-safe and hence * has to be setup before ThreadedGenerateData */ template void WarpImageWAffineFilter ::BeforeThreadedGenerateData() { if( !m_Interpolator ) { itkExceptionMacro(<< "Interpolator not set"); } // Connect input image to interpolator // m_Interpolator->SetInputImage( this->GetInput() ); if (m_CachedSmoothImage.IsNull()){ m_CachedSmoothImage = const_cast (this->GetInput()); } m_Interpolator->SetInputImage( m_CachedSmoothImage ); } /** * Setup state of filter after multi-threading. */ template void WarpImageWAffineFilter ::AfterThreadedGenerateData() { // Disconnect input image from interpolator m_Interpolator->SetInputImage( NULL ); } ///** // * Compute the output for the region specified by outputRegionForThread. // */ //template //void //WarpImageWAffineFilter //::ThreadedGenerateData( // const OutputImageRegionType& outputRegionForThread, // int threadId ) //{ // // InputImageConstPointer inputPtr = this->GetInput(); // OutputImagePointer outputPtr = this->GetOutput(); // DeformationFieldPointer fieldPtr = this->GetDeformationField(); // TransformTypePointer aff = this->GetAffineTransform(); // // // std::cout << aff << std::endl; // // // support progress methods/callbacks // ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // // // iterator for the output image // ImageRegionIteratorWithIndex outputIt( // outputPtr, outputRegionForThread ); // // // iterator for the deformation field // ImageRegionIterator fieldIt( // fieldPtr, outputRegionForThread ); // // IndexType index; // PointType point1, point2, point3; // DisplacementType displacement; // // // int cnt = 0; // while( !outputIt.IsAtEnd() ) // { // // get the output image index // index = outputIt.GetIndex(); // outputPtr->TransformIndexToPhysicalPoint( index, point1 ); // // // get the required displacement // displacement = fieldIt.Get(); // // // compute the required input image point // for(unsigned int j = 0; j < ImageDimension; j++ ) // { // point2[j] = point1[j] + displacement[j]; // } // // // songgang: followed by affine transform // // use affine transform // point3 = aff->TransformPoint(point2); // // // get the interpolated value // if( m_Interpolator->IsInsideBuffer( point3 ) ) // { // PixelType value = static_cast( // m_Interpolator->Evaluate( point3 ) ); // outputIt.Set( value ); // } // else // { // outputIt.Set( m_EdgePaddingValue ); // } // ++outputIt; // ++fieldIt; // progress.CompletedPixel(); // } // //} template void WarpImageWAffineFilter ::GenerateInputRequestedRegion() { // call the superclass's implementation Superclass::GenerateInputRequestedRegion(); // request the largest possible region for the input image InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if( inputPtr ) { inputPtr->SetRequestedRegionToLargestPossibleRegion(); } // just propagate up the output requested region for the // deformation field. DeformationFieldPointer fieldPtr = this->GetDeformationField(); // OutputImagePointer outputPtr = this->GetOutput(); if( fieldPtr ) { // fieldPtr->SetRequestedRegion( outputPtr->GetRequestedRegion() ); fieldPtr->SetRequestedRegionToLargestPossibleRegion(); } return; } template void WarpImageWAffineFilter ::GenerateOutputInformation() { // call the superclass's implementation of this method Superclass::GenerateOutputInformation(); OutputImagePointer outputPtr = this->GetOutput(); if ( !outputPtr ) { return; } typename TOutputImage::RegionType outputLargestPossibleRegion; outputLargestPossibleRegion.SetSize( m_OutputSize ); // outputLargestPossibleRegion.SetIndex( 0 ); outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion ); outputPtr->SetSpacing( m_OutputSpacing ); outputPtr->SetOrigin( m_OutputOrigin ); // DeformationFieldPointer fieldPtr = this->GetDeformationField(); // if( fieldPtr ) // { // outputPtr->SetLargestPossibleRegion( fieldPtr-> // GetLargestPossibleRegion() ); // } } template void WarpImageWAffineFilter ::SetSmoothScale(double scale) { if (m_SmoothScale != scale){ // compute the new cached m_SmoothScale = scale; typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSpacing(); typename InputImageType::RegionType::SizeType inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize(); typename InputImageType::SpacingType outputSpacing; typename InputImageType::RegionType::SizeType outputSize; double minimumSpacing = inputSpacing.GetVnlVector().min_value(); double maximumSpacing = inputSpacing.GetVnlVector().max_value(); InputImagePointer image = const_cast (this->GetInput()); for ( unsigned int d = 0; d < ImageDimension; d++ ) { double scaling = vnl_math_min( 1.0 / scale * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); double sigma = 0.2 * ( outputSpacing[d] / inputSpacing[d] ); typedef RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); // std::cout << "scale = " << scale << " => " << "sigma of dim " << d << ": " << sigma << " outsize " << outputSize << std::endl; smoother->SetSigma( sigma ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); image = smoother->GetOutput(); } } m_CachedSmoothImage = image; SetOutputSpacing( outputSpacing ); SetOutputOrigin( this->GetInput()->GetOrigin() ); SetOutputSize(outputSize); } } /** * Compute the output for the region specified by outputRegionForThread. */ template void WarpImageWAffineFilter ::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, int threadId ) { InputImageConstPointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); DeformationFieldPointer fieldPtr = this->GetDeformationField(); TransformTypePointer aff = this->GetAffineTransform(); // std::cout << aff << std::endl; // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // iterator for the output image ImageRegionIteratorWithIndex outputIt( outputPtr, outputRegionForThread ); // iterator for the deformation field ImageRegionIterator fieldIt( fieldPtr, outputRegionForThread ); IndexType index; PointType point1, point2, point3; DisplacementType displacement; std::cout << "m_TransformOrder: " << m_TransformOrder << std::endl; int cnt = 0; while( !outputIt.IsAtEnd() ) { // get the output image index index = outputIt.GetIndex(); outputPtr->TransformIndexToPhysicalPoint( index, point1 ); // get the required displacement displacement = fieldIt.Get(); // compute the required input image point bool isinside = false; switch (m_TransformOrder){ case AffineFirst: { for(unsigned int j = 0; j < ImageDimension; j++ ) { point2[j] = point1[j] + displacement[j]; } point3 = aff->TransformPoint(point2); isinside = true; // affine transform is always valid } break; case AffineLast: { point2 = aff->TransformPoint(point1); typedef itk::VectorLinearInterpolateImageFunction DefaultInterpolatorType; typename DefaultInterpolatorType::Pointer vinterp = DefaultInterpolatorType::New(); vinterp->SetInputImage(fieldPtr); typename DefaultInterpolatorType::ContinuousIndexType contind; // isinside = fieldPtr->TransformPhysicalPointToContinuousIndex(point2, contind); // explicitly written to avoid double / float type dismatching for (unsigned int i = 0; i < ImageDimension; i++) { contind[i] = ( (point2[i]- fieldPtr->GetOrigin()[i]) / fieldPtr->GetSpacing()[i] ); } isinside = fieldPtr->GetLargestPossibleRegion().IsInside( contind ); typename DefaultInterpolatorType::OutputType disp2; if (isinside) disp2 = vinterp->EvaluateAtContinuousIndex( contind ); else disp2.Fill(0); for (int jj=0; jjIsInsideBuffer( point3 )) ) { PixelType value = static_cast( m_Interpolator->Evaluate( point3 ) ); outputIt.Set( value ); } else { outputIt.Set( m_EdgePaddingValue ); } ++outputIt; ++fieldIt; progress.CompletedPixel(); } } template void WarpImageWAffineFilter ::UpdateSizeByScale() { DeformationFieldPointer field = this->GetDeformationField(); SetOutputSpacing( field->GetSpacing() / m_SmoothScale ); SetOutputOrigin( field->GetOrigin() ); typename InputImageType::SizeType imgsz = field->GetLargestPossibleRegion().GetSize(); for(int ii = 0; ii < InputImageType::ImageDimension; ii++) imgsz[ii] = (typename InputImageType::SizeType::SizeValueType) (imgsz[ii] * m_SmoothScale + 0.5); SetOutputSize(imgsz); } } // end namespace itk #endif ants-1.9.2+svn680.dfsg/Utilities/itkWarpTensorImageMultiTransformFilter.h000066400000000000000000000302371147325206600264450ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpTensorImageMultiTransformFilter.h,v $ Language: C++ Date: $Date: 2009/01/28 22:37:55 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef ITKWarpTensorImageMultiTRANSFORMFILTER_H_ #define ITKWarpTensorImageMultiTRANSFORMFILTER_H_ #include "itkImageToImageFilter.h" #include "itkVectorInterpolateImageFunction.h" #include "itkLinearInterpolateImageFunction.h" #include "itkVectorLinearInterpolateImageFunction.h" #include "itkPoint.h" #include "itkFixedArray.h" #include "itkRecursiveGaussianImageFilter.h" #include namespace itk { /** \class WarpTensorImageMultiTransformFilter * \brief Warps an image using an input deformation field. * * WarpTensorImageMultiTransformFilter warps an existing image with respect to * a given deformation field. * * A deformation field is represented as a image whose pixel type is some * vector type with at least N elements, where N is the dimension of * the input image. The vector type must support element access via operator * []. * * The output image is produced by inverse mapping: the output pixels * are mapped back onto the input image. This scheme avoids the creation of * any holes and overlaps in the output image. * * Each vector in the deformation field represent the distance between * a geometric point in the input space and a point in the output space such * that: * * \f[ p_{in} = p_{out} + d \f] * * Typically the mapped position does not correspond to an integer pixel * position in the input image. Interpolation via an image function * is used to compute values at non-integer positions. The default * interpolation typed used is the LinearInterpolateImageFunction. * The user can specify a particular interpolation function via * SetInterpolator(). Note that the input interpolator must derive * from base class InterpolateImageFunction. * * Position mapped to outside of the input image buffer are assigned * a edge padding value. * * The LargetPossibleRegion for the output is inherited from the * input deformation field. The output image spacing and origin may be set * via SetOutputSpacing, SetOutputOrigin. The default are respectively a * vector of 1's and a vector of 0's. * * This class is templated over the type of the input image, the * type of the output image and the type of the deformation field. * * The input image is set via SetInput. The input deformation field * is set via SetDeformationField. * * This filter is implemented as a multithreaded filter. * * \warning This filter assumes that the input type, output type * and deformation field type all have the same number of dimensions. * * \ingroup GeometricTransforms MultiThreaded */ template < class TInputImage, class TOutputImage, class TDeformationField, class TTransform > class ITK_EXPORT WarpTensorImageMultiTransformFilter : public ImageToImageFilter { public: /** transform order type **/ // typedef enum _TransformOrderType {AffineFirst=0, AffineLast} TransformOrderType; /** transform type **/ typedef enum _SingleTransformType {EnumAffineType=0, EnumDeformationFieldType} SingleTransformType; /** Standard class typedefs. */ typedef WarpTensorImageMultiTransformFilter Self; typedef ImageToImageFilter Superclass; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Run-time type information (and related methods) */ itkTypeMacro( WarpTensorImageMultiTransformFilter, ImageToImageFilter ); /** Typedef to describe the output image region type. */ typedef typename TOutputImage::RegionType OutputImageRegionType; /** Inherit some types from the superclass. */ typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::InputImagePointer InputImagePointer; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImagePointer OutputImagePointer; typedef typename Superclass::InputImageConstPointer InputImageConstPointer; typedef typename OutputImageType::IndexType IndexType; typedef typename OutputImageType::SizeType SizeType; typedef typename OutputImageType::PixelType PixelType; typedef typename OutputImageType::SpacingType SpacingType; typedef typename OutputImageType::DirectionType DirectionType; /** Determine the image dimension. */ itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension ); itkStaticConstMacro(InputImageDimension, unsigned int, TInputImage::ImageDimension ); itkStaticConstMacro(DeformationFieldDimension, unsigned int, TDeformationField::ImageDimension ); /** Deformation field typedef support. */ typedef TDeformationField DeformationFieldType; typedef typename DeformationFieldType::Pointer DeformationFieldPointer; typedef typename DeformationFieldType::PixelType DisplacementType; typedef typename DisplacementType::ValueType DisplacementScalarValueType; /** songgang: Affine transform typedef support. */ typedef TTransform TransformType; typedef typename TransformType::Pointer TransformTypePointer; /** Interpolator typedef support. */ typedef double CoordRepType; typedef VectorInterpolateImageFunction InterpolatorType; typedef typename InterpolatorType::Pointer InterpolatorPointer; typedef VectorLinearInterpolateImageFunction DefaultInterpolatorType; typedef VectorLinearInterpolateImageFunction DefaultVectorInterpolatorType; typedef typename DefaultVectorInterpolatorType::Pointer VectorInterpolatorPointer; /** Point type */ typedef Point PointType; typedef struct _DeformationTypeEx{ DeformationFieldPointer field; VectorInterpolatorPointer vinterp; } DeformationTypeEx; typedef struct _AffineTypeEx{ TransformTypePointer aff; } AffineTypeEx; typedef struct _VarTransformType{ AffineTypeEx aex; DeformationTypeEx dex; } VarTransformType; typedef std::pair SingleTransformItemType; typedef std::list TransformListType; /** Set the interpolator function. */ itkSetObjectMacro( Interpolator, InterpolatorType ); /** Get a pointer to the interpolator function. */ itkGetObjectMacro( Interpolator, InterpolatorType ); /** Set the output image spacing. */ itkSetMacro(OutputSpacing, SpacingType); virtual void SetOutputSpacing( const double* values); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputSpacing, SpacingType); /** Set the output image spacing. */ itkSetMacro(OutputDirection, DirectionType); /** Get the output image spacing. */ itkGetConstReferenceMacro(OutputDirection, DirectionType); /** Set the output image origin. */ itkSetMacro(OutputOrigin, PointType); virtual void SetOutputOrigin( const double* values); /** Get the output image origin. */ itkGetConstReferenceMacro(OutputOrigin, PointType); /** Set the output image size. */ itkSetMacro(OutputSize, SizeType); // virtual void SetOutputSize( const double *values); itkGetConstReferenceMacro(OutputSize, SizeType); /** Set the edge padding value */ itkSetMacro( EdgePaddingValue, PixelType ); /** Get the edge padding value */ itkGetMacro( EdgePaddingValue, PixelType ); TransformListType & GetTransformList(){ return m_TransformList; } void PrintTransformList(); /** WarpTensorImageMultiTransformFilter produces an image which is a different * size than its input image. As such, it needs to provide an * implemenation for GenerateOutputInformation() which set * the output information according the OutputSpacing, OutputOrigin * and the deformation field's LargestPossibleRegion. */ virtual void GenerateOutputInformation(); /** It is difficult to compute in advance the input image region * required to compute the requested output region. Thus the safest * thing to do is to request for the whole input image. * * For the deformation field, the input requested region * set to be the same as that of the output requested region. */ virtual void GenerateInputRequestedRegion(); /** This method is used to set the state of the filter before * multi-threading. */ virtual void BeforeThreadedGenerateData(); /** This method is used to set the state of the filter after * multi-threading. */ virtual void AfterThreadedGenerateData(); /** precompute the smoothed image if necessary **/ void SetSmoothScale(double scale); double GetSmoothScale() {return m_SmoothScale;}; // void UpdateSizeByScale(); void PushBackAffineTransform(const TransformType* t); void PushBackDeformationFieldTransform(const DeformationFieldType* t); void ComposeAffineOnlySequence(const PointType ¢er_output, TransformTypePointer &affine_output); bool MultiInverseAffineOnlySinglePoint(const PointType &point1, PointType &point2); bool MultiTransformSinglePoint(const PointType &point1, PointType &point2); bool MultiTransformPoint(const PointType &point1, PointType &point2, bool bFisrtDeformNoInterp, const IndexType &index); void DetermineFirstDeformNoInterp(); inline bool IsOutOfNumericBoundary(const PointType &p); // set interpolator from outside // virtual void SetInterpolator(InterpolatorPointer interp); #ifdef ITK_USE_CONCEPT_CHECKING /** Begin concept checking */ itkConceptMacro(SameDimensionCheck1, (Concept::SameDimension)); itkConceptMacro(SameDimensionCheck2, (Concept::SameDimension)); //removed to be compatible with vector form input image // itkConceptMacro(InputHasNumericTraitsCheck, // (Concept::HasNumericTraits)); itkConceptMacro(DeformationFieldHasNumericTraitsCheck, (Concept::HasNumericTraits)); /** End concept checking */ #endif bool m_bFirstDeformNoInterp; protected: WarpTensorImageMultiTransformFilter(); ~WarpTensorImageMultiTransformFilter() {}; void PrintSelf(std::ostream& os, Indent indent) const; /** WarpTensorImageMultiTransformFilter is implemented as a multi-threaded filter. * As such, it needs to provide and implementation for * ThreadedGenerateData(). */ void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId ); InterpolatorPointer m_Interpolator; PixelType m_EdgePaddingValue; SpacingType m_OutputSpacing; PointType m_OutputOrigin; SizeType m_OutputSize; DirectionType m_OutputDirection; TransformListType m_TransformList; double m_SmoothScale; InputImagePointer m_CachedSmoothImage; private: WarpTensorImageMultiTransformFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented }; } // end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkWarpTensorImageMultiTransformFilter.txx" #endif #endif /*ITKWarpTensorImageMultiTRANSFORMFILTER_H_*/ ants-1.9.2+svn680.dfsg/Utilities/itkWarpTensorImageMultiTransformFilter.txx000066400000000000000000000503131147325206600270360ustar00rootroot00000000000000/*========================================================================= Program: Advanced Normalization Tools Module: $RCSfile: itkWarpTensorImageMultiTransformFilter.txx,v $ Language: C++ Date: $Date: 2009/01/28 22:38:04 $ Version: $Revision: 1.1 $ Copyright (c) ConsortiumOfANTS. All rights reserved. See accompanying COPYING.txt or http://sourceforge.net/projects/advants/files/ANTS/ANTSCopyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkWarpTensorImageMultiTransformFilter_txx #define __itkWarpTensorImageMultiTransformFilter_txx #include "itkWarpTensorImageMultiTransformFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" #include "itkVectorLinearInterpolateImageFunction.h" #include namespace itk { /** * Default constructor. */ template WarpTensorImageMultiTransformFilter ::WarpTensorImageMultiTransformFilter() { // Setup the number of required inputs this->SetNumberOfRequiredInputs( 1 ); // Setup default values m_OutputSpacing.Fill( 1.0 ); m_OutputOrigin.Fill( 0.0 ); PixelType Zero; Zero.SetIdentity(); Zero=Zero*1.e-6; m_EdgePaddingValue = Zero; // Setup default interpolator typename DefaultInterpolatorType::Pointer interp = DefaultInterpolatorType::New(); m_Interpolator = static_cast( interp.GetPointer() ); m_SmoothScale = -1; // m_bOutputDeformationField = false; // m_TransformOrder = AffineFirst; } //template //void //WarpTensorImageMultiTransformFilter //::SetInterpolator1(InterpolatorPointer interp) //{ // m_Interpolator = static_cast (interp.GetPointer()); // std::cout << "set interpolator in WarpImage:" << interp << std::endl; //} template void WarpTensorImageMultiTransformFilter ::PrintTransformList() { std::cout << "transform list: " << std::endl; typename TransformListType::iterator it = (m_TransformList.begin()); for(int ii=0; it != m_TransformList.end(); it++, ii++){ switch(it->first){ case EnumAffineType: std::cout << '[' << ii << "]: EnumAffineType" << std::endl; std::cout << it->second.aex.aff << std::endl; break; case EnumDeformationFieldType: std::cout << '[' << ii << "]: EnumDeformationFieldType: size" << it->second.dex.field->GetLargestPossibleRegion().GetSize() << std::endl; } } } /** * Standard PrintSelf method. */ template void WarpTensorImageMultiTransformFilter ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "OutputSpacing: " << m_OutputSpacing << std::endl;; os << indent << "OutputOrigin: " << m_OutputOrigin << std::endl; os << indent << "EdgePaddingValue: " << static_cast::PrintType>(m_EdgePaddingValue) << std::endl; os << indent << "Interpolator: " << m_Interpolator.GetPointer() << std::endl; os << indent << "m_bFirstDeformNoInterp = " << m_bFirstDeformNoInterp << std::endl; } /** * Set the output image spacing. * */ template void WarpTensorImageMultiTransformFilter ::SetOutputSpacing( const double* spacing) { SpacingType s(spacing); this->SetOutputSpacing( s ); } /** * Set the output image origin. * */ template void WarpTensorImageMultiTransformFilter ::SetOutputOrigin( const double* origin) { PointType p(origin); this->SetOutputOrigin(p); } /** * Setup state of filter before multi-threading. * InterpolatorType::SetInputImage is not thread-safe and hence * has to be setup before ThreadedGenerateData */ template void WarpTensorImageMultiTransformFilter ::BeforeThreadedGenerateData() { if( !m_Interpolator ) { itkExceptionMacro(<< "Interpolator not set"); } // Connect input image to interpolator // m_Interpolator->SetInputImage( this->GetInput() ); if (m_CachedSmoothImage.IsNull() && (this->GetInput() )){ m_CachedSmoothImage = const_cast (this->GetInput()); } m_Interpolator->SetInputImage( m_CachedSmoothImage ); } /** * Setup state of filter after multi-threading. */ template void WarpTensorImageMultiTransformFilter ::AfterThreadedGenerateData() { // Disconnect input image from interpolator m_Interpolator->SetInputImage( NULL ); } template void WarpTensorImageMultiTransformFilter ::GenerateInputRequestedRegion() { // call the superclass's implementation Superclass::GenerateInputRequestedRegion(); // request the largest possible region for the input image InputImagePointer inputPtr = const_cast< InputImageType * >( this->GetInput() ); if( inputPtr ) { inputPtr->SetRequestedRegionToLargestPossibleRegion(); } return; } template void WarpTensorImageMultiTransformFilter ::GenerateOutputInformation() { // call the superclass's implementation of this method Superclass::GenerateOutputInformation(); OutputImagePointer outputPtr = this->GetOutput(); if ( !outputPtr ) { return; } typename TOutputImage::RegionType outputLargestPossibleRegion; outputLargestPossibleRegion.SetSize( this->m_OutputSize ); // outputLargestPossibleRegion.SetIndex( 0 ); outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion ); outputPtr->SetSpacing( this->m_OutputSpacing ); outputPtr->SetOrigin( this->m_OutputOrigin ); outputPtr->SetDirection( this->m_OutputDirection ); // determine if the deformation field is the same dimension as the image // so that it does not need interpolation in the first step DetermineFirstDeformNoInterp(); } template void WarpTensorImageMultiTransformFilter ::SetSmoothScale(double scale) { /* if (m_SmoothScale != scale){ // compute the new cached // std::cout << "change smooth scale: " << m_SmoothScale << " ---> " << scale << std::endl; m_SmoothScale = scale; typename InputImageType::SpacingType inputSpacing = this->GetInput()->GetSpacing(); typename InputImageType::RegionType::SizeType inputSize = this->GetInput()->GetLargestPossibleRegion().GetSize(); typename InputImageType::SpacingType outputSpacing; typename InputImageType::RegionType::SizeType outputSize; double minimumSpacing = inputSpacing.GetVnlVector().min_value(); double maximumSpacing = inputSpacing.GetVnlVector().max_value(); InputImagePointer image = const_cast (this->GetInput()); for ( unsigned int d = 0; d < ImageDimension; d++ ) { double scaling = vnl_math_min( 1.0 / scale * minimumSpacing / inputSpacing[d], static_cast( inputSize[d] ) / 32.0 ); outputSpacing[d] = inputSpacing[d] * scaling; outputSize[d] = static_cast( inputSpacing[d] * static_cast( inputSize[d] ) / outputSpacing[d] + 0.5 ); double sigma = 0.25 * ( outputSpacing[d] / inputSpacing[d] ); if (sigma < 0) sigma=0; typedef RecursiveGaussianImageFilter GaussianFilterType; typename GaussianFilterType::Pointer smoother = GaussianFilterType::New(); smoother->SetInputImage( image ); smoother->SetDirection( d ); smoother->SetNormalizeAcrossScale( false ); // std::cout << "scale = " << scale << " => " << "sigma of dim " << d << ": " << sigma << " out size " << outputSize << " spc1 " << outputSpacing << " in " << inputSpacing << std::endl; smoother->SetSigma( sigma ); if ( smoother->GetSigma() > 0.0 ) { smoother->Update(); image = smoother->GetOutput(); } } SetOutputSpacing( outputSpacing ); SetOutputOrigin( this->GetInput()->GetOrigin() ); SetOutputSize(outputSize); } */ InputImagePointer image = const_cast (this->GetInput()); m_CachedSmoothImage = image; } /** * Compute the output for the region specified by outputRegionForThread. */ template void WarpTensorImageMultiTransformFilter ::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, int threadId ) { InputImageConstPointer inputPtr = this->GetInput(); OutputImagePointer outputPtr = this->GetOutput(); //std::cout << "inputPtr->GetOrigin():" << inputPtr->GetOrigin() << std::endl; //std::cout << "outputPtr->GetOrigin():" << outputPtr->GetOrigin() << std::endl; // exit(-1); IndexType index; index.Fill(0); this->m_EdgePaddingValue=inputPtr->GetPixel(index); // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); // iterator for the output image ImageRegionIteratorWithIndex outputIt(outputPtr, outputRegionForThread); while( !outputIt.IsAtEnd() ) { PointType point1, point2; // get the output image index IndexType index = outputIt.GetIndex(); outputPtr->TransformIndexToPhysicalPoint( index, point1 ); bool isinside = MultiTransformPoint(point1, point2, m_bFirstDeformNoInterp, index); // std::cout << "point1:" << point1 << " point2:" << point2 << " index:" << index << std::endl; // exit(-1); // warp the image // get the interpolated value if( isinside && (m_Interpolator->IsInsideBuffer( point2 )) ) { PixelType value = static_cast(m_Interpolator->Evaluate(point2)); outputIt.Set( value ); } else { // std::cout << "OUTSIDE" << " isinside:" << isinside << " m_Interpolator->IsInsideBuffer( point2 ):" << m_Interpolator->IsInsideBuffer( point2 ) << std::endl; outputIt.Set( m_EdgePaddingValue ); } ++outputIt; } progress.CompletedPixel(); } //template //void //WarpTensorImageMultiTransformFilter //::UpdateSizeByScale() //{ // // // DeformationFieldPointer field = this->GetDeformationField(); // // // // SetOutputSpacing( field->GetSpacing() / m_SmoothScale ); // // SetOutputOrigin( field->GetOrigin() ); // // // // typename InputImageType::SizeType imgsz = field->GetLargestPossibleRegion().GetSize(); // // for(int ii = 0; ii < InputImageType::ImageDimension; ii++) imgsz[ii] = (typename InputImageType::SizeType::SizeValueType) (imgsz[ii] * m_SmoothScale + 0.5); // // // // SetOutputSize(imgsz); // //} template void WarpTensorImageMultiTransformFilter ::PushBackAffineTransform(const TransformType* t) { if (t){ VarTransformType t1; t1.aex.aff = const_cast (t); m_TransformList.push_back(SingleTransformItemType(EnumAffineType, t1)); } } template void WarpTensorImageMultiTransformFilter ::PushBackDeformationFieldTransform(const DeformationFieldType* t) { if (t){ VarTransformType t1; t1.dex.field = const_cast (t); t1.dex.vinterp = DefaultVectorInterpolatorType::New(); t1.dex.vinterp->SetInputImage(t1.dex.field); m_TransformList.push_back(SingleTransformItemType(EnumDeformationFieldType, t1)); } } template bool WarpTensorImageMultiTransformFilter ::MultiTransformSinglePoint(const PointType &point1, PointType &point2) { IndexType null_index; bool isinside = MultiTransformPoint(point1, point2, false, null_index); return isinside; } template bool WarpTensorImageMultiTransformFilter ::IsOutOfNumericBoundary(const PointType &p) { const DisplacementScalarValueType kMaxDisp = itk::NumericTraits::max(); bool b = false; for (int i = 0; i < ImageDimension; i++) { if (p[i]>=kMaxDisp ){ b = true; break; } } return b; } template void WarpTensorImageMultiTransformFilter ::ComposeAffineOnlySequence(const PointType ¢er_output, TransformTypePointer &affine_output) { // std::cout << "test " ; // TransformTypePointer affine_output = TransformType::New(); affine_output->SetIdentity(); affine_output->SetCenter(center_output); // std::cout << affine_output; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; affine_output->Compose(aff, 0); // std::cout << affine_output; break; } case EnumDeformationFieldType: std::cout << " Ignore deformation type ... " << std::endl; break; default: itkExceptionMacro(<< "Single Transform Not Supported!"); } } return; } template bool WarpTensorImageMultiTransformFilter ::MultiInverseAffineOnlySinglePoint(const PointType &p1, PointType &p2) { bool isinside = true; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; TransformTypePointer aff_inv = TransformTypePointer::ObjectType::New(); // std::cout << "aff before:" << aff << std::endl; aff->GetInverse(aff_inv); // aff->GetInverse(aff); // std::cout << "aff after:" << aff << std::endl; // std::cout << "aff_inv after:" << aff_inv << std::endl; point2 = aff_inv->TransformPoint(point1); point1 = point2; isinside = true; break; } case EnumDeformationFieldType: break; default: itkExceptionMacro(<< "Single Transform Not Supported!"); } if (IsOutOfNumericBoundary(point2)) {isinside = false; break;} point1 = point2; } p2 = point2; return isinside; } template bool WarpTensorImageMultiTransformFilter ::MultiTransformPoint(const PointType &p1, PointType &p2, bool bFisrtDeformNoInterp, const IndexType &index) { bool isinside = false; PointType point1 = p1, point2; typename TransformListType::iterator it = m_TransformList.begin(); for(;it!=m_TransformList.end(); it++){ SingleTransformType ttype = it->first; switch(ttype){ case EnumAffineType: { TransformTypePointer aff = it->second.aex.aff; point2 = aff->TransformPoint(point1); point1 = point2; isinside = true; } break; case EnumDeformationFieldType: { DeformationFieldPointer fieldPtr = it->second.dex.field; if (bFisrtDeformNoInterp && it==m_TransformList.begin() ){ // use discrete coordinates DisplacementType displacement = fieldPtr->GetPixel(index); for(int j = 0; jTransformPhysicalPointToContinuousIndex(point1, contind); isinside = fieldPtr->GetLargestPossibleRegion().IsInside( contind ); VectorInterpolatorPointer vinterp = it->second.dex.vinterp; typename DefaultVectorInterpolatorType::OutputType disp2; if (isinside) disp2 = vinterp->EvaluateAtContinuousIndex( contind ); else disp2.Fill(0); for (int jj=0; jj void WarpTensorImageMultiTransformFilter ::DetermineFirstDeformNoInterp() { m_bFirstDeformNoInterp = false; if (m_TransformList.size() >0 ){ if ((m_TransformList.front().first == EnumDeformationFieldType)){ DeformationFieldPointer field = m_TransformList.front().second.dex.field; m_bFirstDeformNoInterp = (this->GetOutputSize() == field->GetLargestPossibleRegion().GetSize()) & (this->GetOutputSpacing() ==field->GetSpacing()) & (this->GetOutputOrigin() == field->GetOrigin()); // std::cout << "in set: field size: " << field->GetLargestPossibleRegion().GetSize() // << "output spacing: " << this->GetOutputSize() << std::endl; // std::cout << field->GetSpacing() << " | " << this->GetOutputSpacing() << std::endl; // std::cout << field->GetOrigin() << " | " << this->GetOutputOrigin() << std::endl; } } } } // end namespace itk #endif //__itkWarpTensorImageMultiTransformFilter_txx

O7av59:;0[u`! ŴN0h+\n)sx_۹•^Ǝe<na+R&Sn66e˵y} {w^oe; θ1c]2Љχ[3q79Ч7]m}M(=J1yjK9-+:Skֺp3_c3ӗu =g1'+FWa4ZC{p3&}pAZpj[+ִ "$\x~Ґ5.,UGsv5`WH"ukΕaۇ"x]KLѣ xn: #+}S`]ŷ[M.~DBX/I`+ڝKI~|̰NBq́ɯh |/WI}#]G):.̿(EaܤtZ]")z[S7сk2[׍ BFgp>W^Ď͑gJf80e|_wʝ4:R3ǻ2ف,> * 8`LA R3F5eNL :2,wU7PssڕsEp|+ ^W`=fr@V7"PYe"wTFtR)V1f4Q'Y^iˤ߫gpɣ5xkD~O_lñ3 xq:Z`M2MµuXSYKSJQR6k t @G:o>JBt{\^uq~W}F;[{+{GIZSqD 鐯AHXw#ά2Ma!Skq|r6FM}މ[ ="п.n(OE`xA{A×` }waŊR|=Xu10NOCK04ާ(/F8mR[d9нsJUO>6v~n@@7tn\cB/̔%e-g_ϘY u`=Y1h3oi ڝ AB/܎-sS'LB(tY\0ƋW1o'(Txq>$By{:fp>{$gd@2D 4Sk8ՙ֑vl̈́29hϥ\ܳȲtZ7`|Y#ENۥ'g\]ו { -i;\zfĮAXA5'*G)j%~ѩdI!c1^_s]z(`청&t؈J[%W ~6CT_g¡͹XӁ.C:ucGs7s~=Y|ɑ\ɼ?|ϖ8q$knO4eb Γ=V=ٺۓe1K.vT6Ic^X̮mw="y7/]ӎdzFҎc{Qͅ[Njm+H.į!= /Be:7d^s8W˅F:Sa=]1$ hq 6:ZIwkѮSҡ!a?}s6" *|&+B1iC5f;pwӳtXJF5yuo%i%[\}./g|BGrZu׹OBzxSbS535G 8f>5|`KK.ۃ%U7JgLwHAokyOי>Q5ԃd.y‰oۻ1cGߦ=Jǽ=3keG9w?_v8'Yo\/^ϓszr,W&J\=͝yR;=Ӊz~b=C~Hn]xz$9ԐɖȏChՑ+p[}c=WiZ|] E¬J\)qbN▅I <+yx_U ?Is9'R]5q_W͈8#Z^FI/ipSf;iSmAM-yf=4b j*f>znzcwp⵿\;N<ԕ}ܙ.8sn3x8ʝՕ^x w(p'C=Y7=7vΓv݋^\-Qܙ"3v[ϻ+2d;;qeHOV-sgE+qe+x0Ó=orUw*F@.{M.˲,.Ǜ嘾C.uz\A&Ńfh2^&ʂ/axmmUGf|oh -݉MHm͕6zrc (MBt.NȱbjtTۃEr@_1ە}](~N<ӓ.ޝf)n4]:reHug w9BWƩa^\$tZ/.OlaOHw^l<~+-wsᾕ{rvwn! x2ރMy7]bd/F?Hw仰n`6ZuɭTUEjYeC¹pѕ]̧]9ŁgXSwrhmZ xU}:Hi!ux/ Ct!>Ÿ0SF`( 339 O&A+l7~fX;#oϗS-yΝ[0uE%6o@a ¿=>p#R,WCٱ2lB|Z6q0Pp6\(X<*=c8eȘʚU٣ɕ߳Ewwwwҽ]B@x'ԭ͛9S*CwŶ:C4ls/.zf}@wDOVfoY/xb%]Dy"݂zq#Ysg'oB bu.VIE7̼ 3D_s2i2:'Akh{X ΖJ꣪'4[;h\%ӯ!΅6}%K:B% KT7zN8qe[ e `c0~6 3M9x91t֕}9m=0v?+5?SO%ĝOpr'ٜwc;d'֕cy\Î9,#tw4[gS}5mMUj:\GEvo6r/ Wn\FeN12+lwl`i^6Veh u׻P1n0틆|Rt11cpo̵ [sܫoegxnh~u>Z-wvL7:pu3&sc,p"XuԎ5e8{#w`=5]^MYרH5VczU6P8ENqh@ySn?| *^Gu)->RV~CD f(ųBK 6Fyº_~!-7-W☿ kȧ=YAV~|?Ňgh=㍬ȲK~ëޜ^\ˣn>WTY֍0G\_"m)[pU Vш+.sMe:B@^vhcQ-}׳0i6֞3-mnuGs83V;: vbMWsq"gY?.ͅd{ć[w;"=,uE=5ڳ#;Q=29y=v=9/(زM+NжfcÊ\-I61JQv4N)0xI!5ާ:q?Fc2bAeĽ5g^7Gj9d{Fl&~ou8ݝ\Y?o&_>ǎ|<ԓ;3ƃ=9U6W5=}ܓ_e{@_c|<ɋM-6 c4E*k~Ӎʪl!դrh+~Ew^+iEWQ2)f& U gV,&d;5e?xQ}Sd3t='җExcs2҆?Smu9QMuUƄ秚0<ڐV❅_"qpTŮC>ĺXإK`μ(ƧЇ /`E{mʷmi$\ԛ(9Ys'KՇpOΖK\ZpC{Qu.xS7?zD v,hJlwD:Ux)":+1PGCE Y멵(,O_Qoɾ0y KFPC6a蝁apȈqcy=:s%1~zqN,˸Rߓ8:Ǒ[^Yhϑkm*Ł viG\kǔ6-w?Ѫ>%ˈjMXuڌZZ׊oSTb2W{zM.)2hM=cpPC_//]Z6v8 Jq,oNIzRY*AJ *P.g0 cBwz{yqO|#lx*ZQag+vLwcGo|n9nн(rDR=GeMS.o"Scdu6\zEtl6H,}dhzoqOKBOB8Xг80ՙs|\8m\YЙ3nr%qv(ОxZ  +$m8͑ʎ[p0{aK`n?w7rsH9%ۂ]-x%SUxXcsQzFAoY_nc 0ظS9ۍ]{PՖ Sj&d.(i*۝IAݕG-ޭ,Z ~0 bJ 6;S1sx wirc%ZǕ.(tdj'9P֑=yPu#z3_${;O:{?q喧n̑jgA,CLRk#^O:Lǟ:|O6 &'~Cxhv1~I۴Q(fwkcB@n п30O^"%XyDMw_d8A]U!eC*Ɨ`25;pawFis;yĠT F*ʸEKqAcнr ӻ ky6 ͅͰD\}NŠ/WGa\Awe kFnp`_W;gVz,w8 =x&Kݸf39R3f;sf:0z[d`7z\.Ǩ p]st9{˱*swu d~=^?fӲ`ci:: %cҕ0\ꌰq%;'Ƭ_ʋr6 z5^k+r&urg[ʯR79]݈(rBvlL0`@u~P"dcx8}9JrjqKg6q|79a;h;ߊ5P'%HAa*Gga <SF ++.ĠY^O(W/t\qHHSqNQ #/rO++sQ@ J\Հ;~ ;2wY_rr/s 6 TdBa%T %&|0ӉNn<ٕC\yyj'1yRp_9a\,1Hc}8~W|blpP}ywpi!72/=8QWy"Rٔf7;0ѓ1 sx3ޓ>Zր,8=Tl=t뫶/Wp2\ dGDvwG3 #Fԃ|2i+3< <mQ3NOiF:2Ѐ:zL3.ۡBAȵwJc^Vأ9)W \:\sDŽn3=3=&ƒ1-ݸKNOW4iB[yJƔtl^ȆB)nfcػz%Ww8m &)uY ϕTD.*qLp#̮6+9q\_ 03O(%uhf;~67TUm`?"Rb\4_)x6]m[7FS,cmR&jy!?r`J'.P2ceCM@ynsS\ #Gk=ǚtixUN57&W]=~VʶZF>%HOy⾧1==/1ch b@ . 463}_PsXzo+zSl*a?1;L~n`_x&%HRd7+uzձr|҇Vϼ.ϋ sw.L %mmG6ml~yZϦ*C1h%` uB#LoURr:C:Gd}i݅Y.13t|ޞ:..LXk[i>c؝tؙnS1P윎 |vs_-46gߧD ~Px=EnKRe(p y8jS\'P]5j%| ¿kCgcLFyR!MՄpuH"GwZ7ig4#E6+'eZϖc\EQ*u6bj_G~?M˾l;ؤI>{ٓ]#Ž[>+{3e{aWcev[>J9.Q^(sk}ӏ`Ը뫊G/z\ 2ݙ'[2LC`zo~Չ#fq89#r15$ *mXWed'k>4m.TeQRalOUVs: s[nTm,Eq~?$粧b׏lnE j<%\XG 8#-DԏOQP J;Tp×pW yM=۲SG>)ӽٓo优ڇ_{w% jDazI'*UXUrTTcM ǥ!V:38[%/L {GXb=Llօ39 ԢGG1_V*vTfcJ<)EiR |=3::w֣#խ9~1-5"]UMXoK]{ցAҥ{W*nZZ9LJ4=sqdr)B`uLόB|IP0Qi]-.uYi[*\²Sڼ7͒:Sϕ<Ӄ6n^u᧖lh ƣ&Grldv&.|waPuy!mwnCO+`S<.DOr-Lvg9 Gj3oRLǼ/_\EZK 㖉X|uHVׅ'N:J?{jre=f[}~B _b)@\@8ccR3Lx+Niֈ_6R&KjYﺰWtг |:I;8Jkiyh:7#K=N5܁9h6`#d?ûE%0|/$x#Wreg .UޮO9sN=nt⩮lq׃{…;YeE^ZF-,bPdvEGaIv]+eԬRtk=%U-3œASmho]un™ i0΂32MPC|O>atri\Ytuf4_E N[+NIUAp}Fb7`\<T+Aj'9RL)oqXkkwTg›ʮqӆ-tr"l}qNaao\xn>ҾN|ǂbUJ\\M %3=F۳t=)mc^.fcEn=]{7q2<5XǿJqJ%9ո+-1##"2 WSkȾ,9 V" X0>)[<[ϧ {\sDÝ]444  ߪq/d(^7 ٥?+=xEF  Sjm} |Gz1~ ]ʠgPu*I N C:DD~EN/$]FD%oM`έִiûhφIG͸nSR9<֤o 4{z .GX]JBŲ Eu|WCe3?"g\ɜ*Tb6s_mAs5mڽr&?CKe(7û륽5% (! lй0RNp||_",ƹrǖ)`&%c! MYg_8ԕeEUF6+1>/^?Ih1J%S c`1 v5"]QOiϟ00sPgEڰbNQbqn)l*PütlB"h>-X8m q`|UWZ\S͚TX :ggʎA iɟ>WgKINTt}gc'0N`߬_(R8]jqfg%T1mՌ؞\oTWj "OY=<J ia6{i=cp6j64/p5 ZkhOqN%݊RVDpys +/ |QB'{~fGYј GYWUCq<FqotMAi]j9K5H:ntJ!m65ӎ#([{ҷ?iz~F8,KʴFJ<TF_} O(>--5A-{kWk~4$ .-j,jl}3e:'TGb<itjT,P ._Á~܂VMhUF;,Q>q9=>_`עx76A=irʼnGΛOI_!m ##1 }5LnT K 2|PgUȷkbxnuMf_m/#۸ T, BKrڪQLw]TXBwjty<{E8&ڍC/c쯇3nNLgaa&K0*ruҐ9O̮Ʒ+`N8uBQ{s"uJL c=f6]UZۥ?N=C'@ӊA8ѸkCWiSV9BO0iE>2~|' 9[*|g[a7&6bc5q,=f` 5Nءp/m}GIK-gQM)~Jo;~WC0;&a;cʨ8h}7Lǯ礋wZ-\:IeHS#CN0lbJFwcqNAZt^mq1vkՄ9FUz\ .5^i< UAJ*a&U0R6s4I*ERzTcLCf2F*GFe(V=i6X,#o/:G5d#?}:-Ɂ 8RZ;IB ?B_G{6?AmiD\Y׫]s}"`l~5ä\%ײb+6u|6Uz;tWqh&o/S} ;IFu[wTGzm.<}ͨʀ}$͸5jN/039)y;*+r/"T+lxqn3iӒ?|h´mO**%X%3w EUIp^K̓xwUroaw#IsK:R%`ڽ1)>GHLJİ٘z1ΜÙam &]ZqixNnt;X$9xJrd'{x7OΟ] ,M>QWw~'u|g.}aQyPWM[$o98}d>.ڏ|# ~&BDhagS}9n_C2⍲bdɿ)                                                                                       ~/;ndD mOp?~[9K'%wkGjc 6/FN~HÄ>pFa!^J6I3ZJ[֖דI옼bOJG=E>$K<-yVraMI҂X`vE8̉ 7Ϻ|/+*$o'F?o&rKr[i|'[/҉ 󙧤KAok泽]%Yלi0t`xxZUQm-k6@E<&E=4} 9I["=X#tN쾇%OtD'd}  s:W&ڟ؉ݱ,_:,Qze>q㝏g$KM$U*Ȗ~kTjČYV=߄48< *TU>6K~f:] Zu_6I@W`Q}aAC} BSL_??! [^bs$18-DPrͩKtl[u3\sQi"Pcv1ﷶⷃܼC#f.E+p;]fs }UX5mO'dJpG2,@ZzQ%G1aha 鸪AM3j6gnU=E*=x` Q7Fq|X.YX򧏻 )W%~\_7/ Tl>#] D4"Whr|s NHK_Lk2 LYeXH YdVTQ˕SS9V/>(p.OcxoYAnU:c/C?`MmrzTKVI8ETĐX=u5],ՌsPW_婣a[?̱XR(Ac:3.RƮ%wWY,ogjq{MsN5^CD9U] >݌Kضwhr:$Bj.4Č{ÊGV1j8ʐ>I*r}+DRYx#.OFius ;`KcC jBd\i~CMk~6NSv- ?@o+kvl@lj,׸$igR]%?œ˻c;̽[ -{whW>" -nėƜN iQ-1z KuXȀMyxu#͗ ozy6)qA_yZ)uңE O̫E>rܕlB7d53=qOy ,GG6)pJS%Re)wPdd8KEh,KPEuSd2kjgYq^8_rm ۈRfB,GaP&m__#>K$v;p5CHeT/iXiZ^y56 }oùϸj\3P>,s66Sj`sUFl~ԒlgDŽ4g{5} H @z=]!{ {ޱ(T (Rμ3̻λ;{gMB2]ߒe{)jY3'RrQosK9[_VE) R&]32U}C9[Oى)Tv&RiClM:ROj+{NTQEsࣻsuፇ?Ŧ&xRPCiژ:q ^=&iͰkF>WydSJq1d{qE_DO6ϐ[wOQI1!I_*˨_,=棃 ^rdO` FH7`+p\8F4>LXqÄ/\L2SMpu .8FN,} e: (`a,\(`5" q@dF\o%z5paX!f)fYhPJ٦}4.2XݒZOGz 4-yGSY4]0M=I~yU4.7Ɛ;dqBi,!c% B H{QV8KbR-bmDW㉥&9$rvdj  G^q]OdQ1?1IoH@(^qB2E~LL7t~J]YXǜB.9EncSok̬BrJ Ƌ[^/xw~7|bڣR:bܲh>JBK)k~hj3Mzwn]H3Ħ88 6P;g2Ԙ+G auW9jay4|@T I& bU'DsIQ9r j3waꖪW:4tD)943XANX[]%Ua5}Pcj|;aq$)9ȨMF[y6/b\#r(q|r-Q`5gYd KFrS@H|`?9>~yWy<겿qCm/}FѢKt^i9~0iRK>˥kG`76~|/$񕴼,( )puU!ZT;p[MةpMvu7M{f v8Z MfH'Y[6_ё_0:'҄472|Y8݆[D2_ ʱQ, 3`V;,dtei TU:PGڢG69hٖu%.RFz,}.0+0%3ǐ$DGw6WKo.c6}8Ny*K d,bky\c_?u[;V5džFjg?Kɧ&8C֘܁,x}`ኁ;ES8c\-I:tXП (iÿ0pF9`X+%knkwfGY`%f9"v=jSA]v/M46sG i)Fr"v9%$N }):vuT Rn7,t*hzGwkӁGq- ypҺgk&{4k$Slh(=Wk(uEm!([R b<yQ@%X\F*mo; QL L/ǿp!bg3[=ǫmטP'op-Ls@"x7g%e55NZ'~lċY *qѴ4Gnm+IcU|ԝá "4^3%1E<)%0Vhp/H9RI{^X^c:D_"q{7(`qHH@@^>L2iUP.m~C~Khc\ZKQ͢":JއƘb{Q;^ -(*=gQtp@sKLJұ8TbgTP#/%N5l)"F[+u#}=n5GE&W& hK19ߠB hX$t q GIp&ecyS(xm#Mg3 f\%['QSC 9]W}Cv)[Lfw3¥|G5u{ð32|)Uc-Ek1ip q=39r>JxC kR2+I@fH*0ݍz#n9w9LcV@:W{T{v'˥$)T qyH+}\a[| "_JXk0oUazO -9.r40\(FdjX`yb>g9iߠ@ӳdBaL> >@KҏT:vP#73 + c;ݨo%&tx/Ոjy=޷2 o s +a2%8UG }xmSa(XҶjt'~EGPhڤ$͛i3#ZO#t<"Lh~Nw/}sYI`3= g'I2-1|G4^LBhZhC^TлE2Qfh<"BV [z6QejA RcJ[g,.Dž*1\|5HPi (-9DPLJr; U9Y^ T:Y]C3]B/&ј47~KG7t5Y~ԏO'P:92n"H3("-ƟVEW6fpQ1\AV+S/}ᄠ6҅wLf_b`h@E}՞LcGuPbROrQig_#m?KiS6Z'n56 h<{8}UO`[w9/=EwCX]otOSk$[~Hד ^ǩЇ 6:#QPA)-f=ѣo VW!K;7lV\dCp[?p*THǍ,% kƒ|Zʥa} 23D ]k LT,4{]C3w.\j?<~etF$buRj9-z!tuc[x~fLWU%4i!ya:7P U_I AC74Ug\ovӽl;Qަs`fܢlFٱ+.vqìG[ʰ|#S0-­ &bkLëWְmBÂ%u%J[P1mzj+bnW ?j*-|n*h=Ct8IEH`wx|ǚP1BJ㽫#Ub lDழܟGakw>RmG'XbAM$Мtk MIwQ"hE]'4+و-7:Ҹ\h0w㽴躡oh.q  ok`hb W7; to"EzKۅ7hpm޼8=-xo]m+;bctap3AB &]8OQθ{\Թ2H+v1T5ծʦ~mbl=YB*~ꓴh6Zx,B/IZEkSCS؄I%JJ8Df}ԁKL8}r Ψi%Zp#?D} )/׿7VH.u3 YY7Pv gEMPdJS|%bc$;]ab24%2 f м 8")=tDF1no ;iLty87pY*{cŋVj!C]a e0RzcObY6IIOWQ[+E1zMPbk9N%رO1Br0g=L'~ Oq=pG<,1Ƭ`aOf!I|Xvw/flXDvxm}KUҏdZD^֘#~ТOZ7Gp>lS6L,xGR$RlLtMU}/BڞD6!Jv^Fl:"y?+)r꬐z?7KZ58Q\U`J|R{̬Cㄘ&Zӵ6}EC h@ ȨuڧE{@U'CP ݟƯǒiDZ*>Дx*rMvTն|J# Lq/.a4WtqC;vvGLLQc5%58s܀>Ysأ励5[̴FJG[y4D#6cT|m[1q@nFDC~ ^/#IT[F kl\M 6:Whpk(Kz 1@7}I`)E[Gxuqx1YNjc*ӹ7nr|t%5o-o5tb]dd6Z!(TѶ+qq:+ӯ45M,ӭe.6FYi&Ɇ+N";,Qme53K[K_-F7`]=>d3wZ+LORἵ#\m5Cvos өN>.'Q¶ M.J ҢiL_ʕ v! 6٢[knkMD2 -7i-t:3ӈYm5Ňp¼uhx%dfsʦnyF j$YThd*rȁ?h}e@3*̀i08 7tH­-.X:.qFP;,X)83T3VaAMDRS׳zTIRHoҼK 45Eo[5!0Z0x§uf *6n?>6ͧmlk \#dX|9`kX,|XZG';w j|s/=v./=~_0-0~}5)%E4ܱo. ~%430G%nTHEWrEeW\)5Ѓ}}kqɮNV*l 7pl~2 ,6z Y/@M3\lmT> So8~nж\MNg&!y$BLuϒƣ[ R>ās-1ҌE=9~̢Bz6GCz]qDg z; @:4{7=n3ۮaZԆj>:~賖6 lQHfr/ӣu:j feVԗQFHMXGrҚIat)iJ5$](VtvHx'>lbGs1i%%~yx~7сyu4'DKM$ P;E) hht^ZTA.}犉Uz;zs @[]`X猼Rj!syHlmHxX@-dFNm7[|8ܡ{mсA,MA~Tc8S\')l~jL(W(>ZJœ[V. +R%=&/[AkW 0aj=6Kl~=>Yti\4qXa|+40C 5D4 }rGZr*}k,9.zB):mA&Cs%a >j6<ܰdx{ Qvx8KUל1(VUYѡo csULja|Sjil )gEh,VԯfZ3"nőCqy]7ë6Z}5Gv`3 ^A#U\qgrl ;{p%q'it(Dbc,-0)O0'tƃA.7Q/ljaGoLPr0]qVXa|›*0wv{&j! zހL.R-4/4Z5:F^`RUFbo b]g{ U^@K(gz³ZJ1hA/AsPtp}xD'o$jkmC|&Nxci&ʩjIbx?}<0 x~%[IQLY*cD uPע~j5*Kh%4Lnaztd~no5LLNj4fJtSE0<@ ?IYE}%o]LB T`ϲ0k4Ow ;ҁ߯I-lw)_\ gu Z`k \gpQSbm|ڣS7G\*F1 ybcxtW9rNTcm x5P-r hg7 bmȡaQg#RBE O1#b0 vsf83(2sRАh3TSNɲRz0#}E*/5^?ɤN jQGBs>,\%#׋'Dvaթ;}F`:UFF݁,B *MzD^HwPSwl#Zk s`fɎZdgԦ 1^w]4[5tf'q|3ɕ"S·GEO+ Pv,S4oȡ?~!t=eK"K]MR)K"|M=Doh{Bl#ΨjjĂF2fPj[?ܽ˻)(X_ue_f $VpQ$SI$:/"EpE9ȹB9taG}К;8a F ףdnQ^j-1ޮT5n(yRxLW pqθj@kzKӀŸt>h I>K֨ebG>6`s }DCɢϿRZswwи312\JikJ۹ l,%e÷B7\l," filUџ>l㢧 3+XFviudo?%LVq&4+p ȿB;3sDW ۘOmofӢS4XzAww*vW$6=>{RdY6Fҕfd:QAe_K>Dc͝ǗZrLZ`NvV-5ɦ~mKq ߷FJԷQO4GQiMzo!I_ 7ѣ{NdH\*)vm4 m++@(;e2d$1Ag9ilfjSm#sX2#mgGd Eڪ8H6ATr~]iy_?NШr~㆙Wks5ǥfhfcs6}*"N] yT/( iAbJ\KI9M7ҳ?̰!'D팾*C]d𙫇//ZvʡG&^!8N8=.je %w˥E|N)Y_iϺd Eɴ4\&PߓUj%De-썡$jO܃ k:8&2SLh9r16piA{艮tiF*fMtX=5S7GB~1,ޥG:­~jk>V U9j<þ1zxoҢv씘FhC5Z8K=ԘqP& 丹 !VACl1o9z# w]8&bOǷb̮K|"]`L<@U=-c,U)47qqr%: #{q-&ƹV 3DcUl&xЩ:5g-d"*Y@kRLf}%rt m9p.ᡧ^tE7%:[N]qG@=J|5XYG]KNle&cOSS=et*Dnk3,adͱ'Z|#vzLGX:CkiStzd6R|#'x跪^QՅ&n  ,T8Xsqj> CG(uQamjTLwUYF ¯0dzj &k$U 5V^TBj̶P`{BS񒋋#m=%(b3r7J8P|g\.ĽHt.9=[>;ú \o<*e/0%3g&V*˵R'T#Q%Zϔa!:ttt[8qe4-_tHQcô*vF2{:TPbz6M#|ߧjMA0[ie)<,򫣩 ɴ4;>د]e|YNC,ՠs=p4pU#3q'-ۗӂ{߾WAzƗ*º>:"}8+7/igk݅6h`$I Oc=NyOw&Dc ڷI5nsЦ-)eb& VDIR)TFI-JP7Ԍ6QR!re2Lt ,9ƥ@g+W?aiڪqD'ԸiŮ:Դb@b[|u I.ߢAJWA}Jȯ+0_t%<u5N1GطZ[iOPtN]cXMA&kT^'~GxWgz#XoB-z]WJc&N.cc:q+sW)3Z|'4>pT%,t®Ǫ ('QMD; ɽ5LrUUcWiS_\Eu=s3-c>Iש?]n/uTTMw34A؅-uY؁b&*A-bwb bQts9};^k͚Y3}ڳg3y,gߜxnqLj?Bw!Q-pZixQ{W# ĜMɿZ*.9ru9|laj͐Pzl ^Х7ӓأgw2!\cHP\MR%GOR"[BsEo%g ?RƛV֑۬9ؔ ZzClmhe-8A¼ ;l_ bĂ^͌ 1cU ^ni&No(a %ݗ9~,.̼~RW$XCJs!,)~r9N|Qe<lԀ7zF)]#l\u7`> M&=xu ~s|JJ)d9;}L3] aěi$=w*'|B1RCjVrZw~6pY|WmJ Xc ђZ푚^/u6rR:< ~C; >t0"9wrC_X#0#V\0cB28ƓVH#"f *̅w/Xk]rUAe5LD1\4ÁrcmPfeڛ g{ ЃritZŗz v3b3#6yһ'0/QysL7& s b{LR 9PO|APGUj~Pٹ-].qDž;](h맞ķu_ecBh[ȴE#w80h5 F c7sVx~{7%G E9cBlAco5wS,]a<5 3sOz }܀-khԋ.>@M2#?I5CetUB/(}ir!c-davLIdH=M`^ojMl5SjTwG*y ăN_5|W"&!uqq+F _B_Yu=N>ԉflZ,J\W1၊^tT!;^RpR[}9x~t%JzT1%YnMdqލ>]h1ˁC-i8L :tR7|MǬeﰯ}xxMۋx${н1'{ ?]uiVDLطʜ#Zsr|;dB}4"@t|6x:" M~bE%Zhy-ou3/ƃl(bs $5uQӤzp`'dM*{9{ `l w1v[ 0i,Lmob5R(8,QA2=A'8+:Zq2Ɲ֡OU WúzuS>V|.p:'v-l 9d]+7޳<2VLo!<&]rܭ?X/eQ[/dWk0s4‹z#dK뵇GnY爽gUz'/d⏏=cJ9qY6jvDʆ^ S~wfǜѡ{c]ls{±DžoxSݿE~i/_?-7-&>oSgxry\-GD뺻*>ݧ~_ZrI#H.&8BGpa{4}/g p=ݵJv}ٓ t5L;a*NVS\YlbcFmǎdx6| Cv]x1G;ڏ_qjE隻V~jO w/&`N&L:Q˽h{%ږyYLp|[NJQPUSˡ=O%V aFzMcO(e%dƺwO|BHmpxT k&)] ڍT@9&,gO\˩zÀpS'B?W?FXkW-kpZXp\Zm ؓyH ,`]6𤲇7Gu[ ey,Bl<ً0|| Y!xg4?/é-/~w}W1֊+qg-ɭo ɌL̰}; `ěj-nbD‘`56 H囡6<1‘l/8Tɴj:*9gW)iVNt)FJ8S^;-AP$^X|0:R~p FMU2Zbn'{3*؋1Dr~^,号6߿P=&{^FlU;G׮o.L8i[ ~I4!m1= ǃ+vs6 ?.Xq_õODB##^q"t ?CV$UVsl}j[qI=O|\կF|{!Fܔl9v4h}Ұw?)S*ib/ԲT-`{QvMA%u>Ƿ[`=a)1YWVe((ԵIޅqa$MJ<>Y 'x<ٍuܓBb'iD9ς{: <#NөeB9~˙n|2хqZEMg+su=ʃl3*o&pJ]iuޔKĽh+#Q=:@]WL|"N{~4؇UrLO'^\%Lf<+1G W{ "k liAm󾠺{6§p~^ 2(}JdA^bVxN'{>^]lb&tsֿCL}_hRCJvX1.mrhJ+:YF:աKtbV􍲤#ۜtgtN/TlA*?PӔtTs, ӃC\}{ߔV{c ~jf0F/(lY!MĀu;13U\-UM%s L2蝘3$,em)I酘ty"NđmƆێڱ9'~$7#ʜжq,.Gm 3 gŰa>KU^G n}"G:̘G lYxM=ͧ^a/%cKx=3+e@J:WEmD佈KIJΟ0W²5,1 0ZOp3C_;c-w_a${Bw/ň8<^­8q$3;>qm`\ uŽUSjGm ҘCY#L'dV+j3d l *MSp@ۆJ<:zs15~:v,Z򌆉g$xt6&-"p1{"Bx'<%JZPXWͲ@%iֱRKI);|bj/CJN{ 5k>jp/VhGsԴnɾtK5<_)2)V848:hy ސa6 ɺr)n+#V"ĪQ)^O^%C!>[Zِ9hj*B|[#70WY6x4_gbG3oO+~K</d8 ݆MR5˜' ڥ1BXG鰘=3X.glWbm t+ũeX\si~ -C?(9f8u4GöTojR0OWJ/9)sFQ%BΖBT` G<_{\$SDobKegy-GUcs4\,VU8힋-dĹBhn&´1 #7hDpj :x3] u^cDOaoޡ K4h.wdK*f]?oqn|ǔ="Y<C=q ]W@?v%Z}xt Snfk6cS?Lx!B O@)Þ#`n1"V:T"p ,ÛŸ}Or:mҰw쾒1Z1O&yBvnf 5N0i/˸d,$<Ȝ/K_FD,'P`wc՜T]Fl=ÜE$MɊg*NTS!i2$$Gʘ|_ƌ2ڎmslm,~rMP|o*JJ .OT2-O~J_39Tb'> Ax=bPM_AxǠQm"j7ABOÇA𜁶Oy'4 d^}v4d|yӓE*؉jf|O\)e ٧ѿ fYC Ǫ'h>%\>||)UBW7Hgaԧ iu&13?Pv|Ú-ihoaĎ9"ɴ(+~1#2bL!3&.5yf֜MXdȖZ,UR!L\՘ޜiy񵚉i6f1j{f(ᒣr^:)WΜ4c,#0'3N"rNy2. uTς0V+B hҿOvl74ZW9~EÒja8Єt8Գ sƗ)iۥ" IE\ ?oW!۹I!Jg<vȇKhu[=S&~ (~Wpue =@#/;Nll-eDhHxNcGRr~+>66&47F gsjYs?,gjY԰vUsj)43MsWaq1c9R&F\;֜-YԚ9쁌+|LEJ͗E8\EI`5ٝ?z )I3\d[;5 >X#YJ,c32ܔ`X{a{Dӭ:~0^4''cΕ)Yg!ؘe-;Bqeps2x;բ~[=fN}06Ӹ?0mZ >&uY3Ib{:*ň9mvbvse/!o 3jl-{H%׍UҽݹX,+1:sGKZ=b1.T,Y+b36sXr%ƩG6i??Ovn?Wn@r~`GצX]#opTQ'i;σ2mr=R5-|0LnZ؀1 ~O woVVCf ='5QssJ"*xB%kʙ {wm[Eoώ͊tĎ;[p1La]5L훃>?4ZǶCϝ'%bk7ћcXɬ^4*/t *^.gei`Hxoߤ|T3^*VP %UI`qT|,p'JT`e^.Zvp' Sk߯dZ ֚-y-l[cʘ.y!۳#޼wL:S ŋKt*$ ?T@!#8joιsV3Km8i>?X Qn2bl8bTѸn$UȬXFUHqn3q~\u`(;6&ƊaO9˞+GPqޝmXtOٛ].]+py>Z}^s7_1,4욍;`+pxp1 Cy41HNh`yb:1}"\8|O^K=dc&^jW# zOsRUX7W_ ǨM v9{tT𘊕[<s 7ZtXЙd##}:ߧW}￟dռw_b+tmƗᅡ҅Ƴe\Ed}!ilJi\afE?,"-yn w3s2Q|bθԕe` 9 oymW)B=^;J~٨%!O|dPPʵb^[ 8W^xr'-M"`τPkoI?Gk&}`FOcq=N٢C ww{]L\v>]6 $8w. yi9?äWKÒK8++E|U`5ƜYۼ7(gz}6_r^U[J sRU<E,0dL 0*I͑%Xx0'_xP,A-[*TUɘ W+iL<7DA2V |NFnL(#5Ѕ1K>rHCklĢ0=jl3j[=M{S|[m sS\4F.*B&7bX3K|P .CnfEpq.  qMwgk'%was+yJN ꢠI56TK՜^Ö{?` R^To'urZ_.3{{=+\6ޞ=0ۂ3K=S;ڐYImXڣGF`AT;,{vɋP9wf螖I\^cp2,~Fk8fC_sξ$l[/4k16bn3f{ٜ'*̙9՜,_jɛ9+ |ۈ#{ snj˧=D<ՙ vcx))Y 83Ս_55/&zVg)+5NIxP򾿂[FKE+/d"WGfvdCaͿie'w uR3Tf,yI-͝?\؉ml37we-;Y1*00cҶ ; hqcz97V|~ގ}X1֌{wVvP!RD=UWe:4iQy|{Ô҆8위}^C3CVȨ Q0QHr$tΜ"?[wQmyg֡eT 6 _.ٿ+pJ|^ QmF}MѮ#=طy/?iC#2ӿ33xTI 9*9Y)U{z9Gȧzb*t謠K'7@ƨrGK ʙ^¤ NL b!mƆ%qK8)msW!V:C`J\\u/,D&~ggK-}|[״.{ aV;V=vGv?&$2zWi `OY7f+#7zɰ`p-3sNlW[}94\?$Mşv=2_l2U#i.R-9sX%sK,3<]߅7Fٰ! Wuzܹ΀39ۖn9rt7Σ[$-𱝜Se"_9Mʵ"$G8Y7G۱5KwÑ)Wف c{8Xz W^Ēx,\ːU=qy)%2K5_|v`.t>)a2$x9WOǻQ'Qėh +b{)Å5f<*r{*Y(RvS2Q|[ Kwbp&|&b6[~ _Kocx[0F<ۈ^ǹj*7 I+9ћ"Q>->j9}Oi!urzU3B-E6Fʀ CN 1T3gǽciuәJ\XӕMUz_%*#^*&nW4\J\#U;wɨ7ENu|ׁixf52&"w6߶ŘPC-ȎYuz@Hw͒AWA/kd[%\f E̎ox؞m|^ ~05Lm;kfQ'h4^ 3swNc1>/7wkKnO g3<+rgSN)`6):Ix7ȝW3a&|EHN=?Vbvk%WR3A̶+X3تօlxĞ6vkÙo,ńrF0dr>31a-D,Ø|l:SS;j.?ŀ;٫ݱjf\}&9b|^ g@%F|s”Ypz==dǟ{ё΋s+ǻOOCdܵZ|ғC=J޶jvuQMc5[ lLRZۋ-nFw̘IyXsH/t =sSprU8M3gKh-vk8F2? @]+FذO]Bo#vuyy0۾x%{jZ׮4\V $a4c^:fY&nbϢvn@ʺ*6+ 6yPņܼaQVgB*AOck DEM0dc9.w) GHBuENr sږ'"6r3;Gٱu ޘ[ ]Ƙb@y=}>XN=unǸ#IZQG;]׶:9ַ5JiUM`dVg#d>LaZc!]AI <֌},y%La73;ζ"ziϗю-P؝/9@E75|Z9o;|kP! +WHX;Lkv2UOP){%DҒ[qo{[9rgsn, =9-2}; 6n=찡K[r~&AQS< >~ʏo_gub#vK\F{:RzB9YN?qT2AA۱*̖34GiߖV,nc%Hω0g$"CEd:ڳ4ÕanؕMΝʛRrK\c;uat`#~8gŃ6ӂ65zZؖe]ߩ\j.X|EB<Ty~*;EuӀ ;VgtlG߅lh/dtϬs%nű筩lυj.i fPFԎ%.x;#lT?m:w9wȴhX&?G?;j&lʼb ʵf\'ΫU%|["Yn9ʼ@'m)ݗE: *5Ю=db0 aW(Kh)8ȍJ GaiN<Ρș\R)s׎v.3rt#/z[q{ ={Y2ԌC)n H^%;da ŹOvH;^s>+AaBGtyKq! &Y!gO-oŒ2kE<ȑۄ[2˶:DŞ," - %d{΁7qC;n1z WzX s%,Jmg5%FLX˺fqV#Tbl_4?h>F|#T LaƜbk]:RA5[N`G*Xy%܂YCk',r]ƾ NUR`ôpXq!#.6e Ma uc\٥osE1w<ʞˎXq 3 `ϕ yŇp6b=X3 ~7(V-XbK>Xw =R;NgϠb6tVPr \y~r^i:V+_{m` eYkZ0.͒:OZ!YQ1GKhÛ6ͿT`yJl}1੥F:݄Lyh^"_k|_[Ͱg~׻4ɍiq1p {Kxh|EÝ<8_H5Vaʘۀ>VK >kV[Y͝ZgsЊC<&_S$]*ztfq){|Ah`.rA tUo?ux=@orJGsNJR>JJkXV3FU`~D{&ͥ6I/ǞGa>?ƆjC]B5{4rI?{^77_Nl+Gغsq1g+x3be;9w';*GY$q6Vch8ʀe:,[6{gx_ mDK>a]V\xDfƲpo6Z veωz"n9pw[ƕAz¶9أҝU'QT4z伎rsT?)*R86aJ1Ne;+'^ȁL ՜g.17R:G\G IXWf`̇2c*TgF[3ƁtF=WqΟsj]?i߮ۿE[ug;r&__`:s>b[u:ce 7qƜ~m=Zs1[GE0C7 ˎmlmvww؁RJwJsϿ9YxZ= T~9*Bۑ1ݍuMm+^@p1=faxq[ rc+'5BKY#gw20n<9|=W߲eB{6aǓly#ڛl89t{F%0#UpBs1/3z5t]XqW!U w`r? 74J)|xEqBÆ<&0zVL,^aϤyhȤQL=@kniάHu汋<{Wys3Wq_<1 DgK4ɭ[]x$_֞6+pF RhCď-wxˀGGz+ \88/|ř.G0'Ɍ'S$sDö/uY/EżΜu P̙ 1f~_?&X9/= j{9(9QGҧǂK%p6€/"9$cte/a}}{ʱu-$ڌ/ `&tS šW*χU r5W-YՑ׿дc.Q]OxG ^*+31_v4p,#SSk 4݌q  A0a]<9L(o$ {n.fr^k=SC"AOi*U@lt=uc". 1zHN3Лsq]s u883rɧ.Kxz$}g.z{,3U| fˎ9V7,UǍ%F7gy2c33p{avu64021Vף;#&v)]/ʔ^E(k[XaO\n;lYJliFV̊%"$ZK'~س6h?Ol8 cə_lV-.%|5vjf&{U,<a4=OdGO3fXs&Yc=CCCmnF\ID3ϟ6:[5a>f.z+3o9o[\ٕX!Y8>9oE}AYx~ClJ8fc,;3u1RcF@8v s8Zے;4'bG;o ~8>@&r!VGܷ^jjh!Jaqjz_T򨣚q#_00Rl9!Abn8x<`ɑUm_lK Fo7{f-:~vq?jh'*XsN\T,/s_bfS-M?CӨ~k!w77L7@ S`yj6-QRO],5qܖճl {?j&ww`y'8NNv`Q[8+)xg*^hfNcrɆ|,؈7{nkh]THgJ##wvwy\ϵՌ,E?)vٛcr,G쳫y@9?/v*؎5cEU0L(F㞅Xc SbDVbkh¢E <[ey^ASW0a>%C1n!RQx5z q7jÉg?fD\Q)҆BқT NBΝ}Ռ='3ڐLL\'yv<(vdb#St.V&Nm8e`ЋsHhSRE>e֌xuYnͪ 1~ZL<4DXp3"(@1_ s q;9kvTUC>9YpQpp{*z81q#vb\Îii5ąMsZh=cuhYQo31ws\np[[xR e9WK-oj8\_pz |_͙<gH{m/ _ k̋c }!8$ Սx=gPSOYk (D7OZE"[po jsue[_G )r$7%-sQ{F#24pD?d/tIB8yH( Jq\=;Pezly{Ll}\blxҁ6S\p+mKx-EU{z)9/kś8Gʣr% 2NHsp^4$9;sp9}-J7k͑syU-L9^qboj6 PQw9V󄃉WQQρêYV81`#7ڳ [.c@>{L/|bg/4.8ےfW:#`ME_GSi<}BP b>*04s'C3A.5gug#s=莟Öz|mWa#4Qٖg{#/ղu)&…›+wn|ՍK92Hl8xwjp/.9j! 6Xn g갌>,'%C"kdݬX#rIf%[\WNsWUg^yEG-t\=}5r1p {N׸qgGGsn}Ɓœ8 3k\5\S2Lx̧13u Q^7 pc"q}*ᇿ`o); 12TuSQ6_*9[XfYR::. |Q!wa81q4*hԷofg3{.o^np˚)ZbaZҨ\$f:fAYWkZoZd)1 ǂfVbLX`y\ͣ1G,Baubwa N;` Z!" ߴ0Cy/RGEUtȩ)tExrƅnaUDrtcbt=q[WZ>5긧J+6&-Z"b 5Wpv:p樢}->TNq/lW`` u3Œ6ǨE"cBSV%ΕBr̾ 46Mb2> ;UP9Ef\on*P iKEAH!h "z2{rq|/vӬX-R* |sB-SZycvJhx`kX3}MRiklDyY*RN{k\zνoadN0 Cx4-%u+ʒS4 bO'^6qy/ iU4,@- EZ~keI+2Ҧud$GJuV3s_P™5<2ڤ*N_ rCwUvR79?ԑ򙏘{}Gմ\|[P Rx\eH d['%#5=w~J1-A +QʿKЪezׂPt !`[jDq;87ƚ=7: S=zVK͒$9ϕ_}%& (ƒ"}Ɲ1M@A1յx6 ze&~ 2{vF|bb@;6lo/ ԰[ #8s^7r=~9s;{pk+c?9M:MU3_/ |aLO&^3p`wxx2jXn5j+2xAE3s|?)_Sr^/hjD~f<-*5EK<z&6G6i˜٭#%S\4Օ~3]X6Ǎ78pۀ~Z&J溨b"~%uT1{,7,+_N{LkmkcrmA.+F4,Jpf$zHE8/ţtIŸ98 : lK~_/#03zG_)Q(ǎls. 扭j:/q#JVnVҺZ&z5ΰ㙃nxƙi]usuaa رQ=hxZêKC԰xZ^ч44qR=f30HDgy‚nRZeTgx_(xIpJ>eD%uW3-?񒿑'zuc2'{7s79sp/Oa`-O#מR'̐~602\M R)135P) 4 m#kO(6:>{jghjmK0> >չsߢ0WKƦ;q&FTHU$d[B؋@_rgjlomp?]?~qkGf\/jTz;Ҝ a*cgzjnF}JϾu,({tkg\o!ZQ&x9NoߡbUtdNf=:jdt5הXb%?ۆ{ȓ6Yӧ;TpOy-Z$0L&y[hd&nȦQ6ԗw6cy~%L)8  |-~Z/;rXkinj{DMkV+ˉj yۑ3Pd" u@6a`P] ]О{F66.Hs0gbVrSw*XbXcO*Kr8%Pz*F41"ċpÅn͓ݽ;O8 ߉wm mlbE~F5j7wqyFJI%oW@{)w> K!: %B_F֜$p)ѱ] _22ܑ957weSҁj Upj-ұ'[m!Axő{mJp.\)S g˰Y!ɂMd4< s1(ƈ[voçqݴ7X"߅aay4}wƘ}pM쵺s)hxb 6fyݿ^E#!5`YsXrb}[O\lIBE|#FvVyo.AxlO+ _1¿n~`)'%Yejaes M40H-j| ELB73=]׋fUŅ\y#ȯ2#S͞ ,Y;ˑV:pB\%a&+%90{:뙘/X % 3~N2Ns, XW<ę \8 j?9y #Iƨt9_h8x檖<By=6ɹ䮘&o(9X>0jY?wa`xۋuaæz=z'#{1{?WFI퍸]NEi _m[nFS<|6G!hWD`@)VL zp BO~"`X>a$iVl=E@xmWu|WMob ܾx8Rˮ:k z)ys5&^`s#k҆xSc$VFy.gִFtp ^=l"Nψ%(楑7;;rsO#ƉȊ$l#;`zk{obq# uV#tR4H2f9 [Y56mJ(W]FޜültcNTe=*y#@C"x怚+ɑ2M-L3؞4.AQz9Lhmw ݮ# (|a$|?&?ƌ:ciDo.\BZ'9+X/σT0/ |m B$)r>6Vqf0L:^bw&cL,D!b%pM| ^l˃͜x\t+=Gߔ-q3|Ufnߨ@|*$b')Tw Hl9'N}.VRd?J`3v an=ߍnrV+u.LpFl7ώ[i:x~\?W%Gs+ah&uF2Θfl-qA;35|^F^q,t$wѺ ƷI^l%Q.sgR=hSJ8{T|0b(J3$4h?-Pe%..˵9դcz} e-DRY\ ?!pU!ѢGL{6zEA:Suykbt}\UujR׿h0m2bY5YrD9g@aWbjr<+WA;.w2;_ _`޹hHGKc61gO$`n,뜂I Ѯ̒tB)x8ܚllUd{{5wGN߭!gj=׼friwzq~/VN^n|….] IJ_p|ֽƶ90'9 ˝old/#~R9sko?y O [B;ȓ]ՙeye< ؃]YR^ *QXa3#M$4YΪ\#e2w&a788s#{fV㨝mFp"[dao)s[4\N&gz M<4j0;ٛzszӚˮѵkIMvoMfnl;6b œzQU$;֖3u baa kC /f3ć.g͕yRΏXq̅wQE[u\uPQYZK==WrblM#?qtIn%|-Eӓy`̸H?U3Ag2&ԗsKK/R-8Hm^05[r']c>Hg;OwA4ÿV~t]Nkw$ռO3Qӭ=Vc# t`XktM_m"Zf$!=ёcz8%WCnkLkQ+N##KeX\A-&h (*0AaYO$Q ]]>ÇKbd/[ǹMA=ott9I`n{[n_;cĶa ]jk1Ym]pG^ i Ta/ZuX7D_%hW :}ާGSۖػq3xߐqTiǓ tue(772 .SZb򋕂qx桖/u\nW̴hZIEC,FcwF- 3sp[y~¯++gSjqv=;-V I!k_8bG<:^S E,8cʅw <yZ߯ ] c tD.UxςRv6pOV9JO w.Lv[; ;^2QgWrJbf[S<կp7.e8ΜQO9H-(bwpQɠrOfl5 ꦖV1f'~Aޢ?w>!xзʎ8#I]aӛ~d<QF>FbAZtE7MpxWر \ vkf&Wn=ԍQ fA[iXe&b0:4R{%|QV]#RɃ7UxIϙ'wC=-kW̽ϱV0xi¼E8x H$o+@zuX,P|lx}֓,FAQ_aUPxXs#6~0{MܘPxEA8(@VYs<3hdiv<`&CSSZeѺ&~6pg%S3D׶v OqnMD D ɟYv^ʭw\_d(;&*li=[%R:jr~ղ<|CIۚӇG*/^\‰clhKrԺoo?LZU;<92iʇY]0O?,)o#31;;+8ܸăcy'otgB'ZX!IFO5 U=W㣵T\T0ujn1QoQq+#-vg0]y|°_e<>JDɰ\ӇԚ?tNLXD'!{0|Z+{[(y>Xz2t,#K4=A? wuϒg fM=]5]$qqR A+<`LE NFf(cP EU}aϯ\$)8ID{:f@lx)"wS'gZ.`ςlwΚ[U<.rr8ye3{y>&ov/}<ʃ5>-ױnFF$R`*T p t\^ fmAq`%_盢dHK j<@prH[Uy/k/nC#Ya妜ɀ :À *ODIghvh xǾE߹Ax5n1Fu¨7 =%AvL0j&4bw3Oip^BOgn"{.AZ+-{!l+zz1gx[ųMQˋ=S3}x,! j}\w7 :Gf"PzYoɄzKnEt<~uG\]FOdyr4|*,w MM[ s"`\Ѣj6_b!&1`qm.SH̽ 񥭘0ft9+àhW70uۼb,b sXinI;-;~HrϞI-of ̕pcOW0!}tᾖt8Ǘ>_Ws}&Bl6SP``b"R ›GW{̽6 ^E8sZHb:ǀ=[.kcVD-[yB}anwMXǒ?#3/ vؾ< K,㰺%~cfjbӬX)DILR}L3`"%appzŷh#b_Gw} so}oh"mtqFZfia!71ф1a}NK͍F|ǘ ڈ<{khVjNbQڄe ?T"ux40O-*\x&ԓ={ksy՛K XA){f°w~fI4HtL;k05g? w8|>E`AV,<6Chعr.BoEw@-x| S-|MMWECvybHЖ>[s`hP/?]$F^3#X9ס,E<"9ۧ&UOs''`ѝ\8bA" $>Dq;&5]^ѕ{ 7o_zP̌k@_ZM66lɎp~;l˞[-kIfkO~B~j3HK렼V'N–͠6 B'hcO$c!ؕp÷᳓u^^/ EUWy裈 YӚJx5[ڱdS2I 7bD1rl veܔgs op`e<*x \,OG.c 4$}3u6,é- 0If ~:XBq~0mI?n`MMmdM[P"oux[ǐJk:;]s۝; =6ԕ]ȕ8=[c14d'Y-#Y"ʮ}ơoѮ >]e!<Sj͟VTMqR)[qb9sSU=Laܹ͚-ydsFWltx?G-[xcU8y DۍmQ z> Ƹ(W ռgM礝FZǤkL pB &EƬ}ncӧkh1Ӳ1x}Nd:ܿ_J}VZRŰQ-G:Q̖+.ΕYzɖ82ϔ[̹ϺKUyz:W‰s+>&rM13Lh}Mxq@M8`-,|ٌΧ y7E&qv]ґuB*# )">ۧzh“Jւ2b6XoÆnδ,ai[,a,jAyg6]բ$=F0k2+6d`Ou 2%76tYY%Y1]žJdo#N:wHps\UCŴze~#8)X 泱&k S;,D3TRy4x-u4[ ^5'!)g+ Y/sOsD"bS o05ϟ񝽈\$wg;᫓7fpwCz4ීz.⼊rA|f`|8YhØ1Lۘkf9ÌHS^jF 4Z+M^D,Qqa,o|3U"S`7orjxGtX hݦt3:A-)by$J1^\Ó?k 2vCjѠT[:#"J|L^,j-1=wg O͵ }u?Vsf 3s:4Bb?bNgM:˵PyFȴb+҆٧ǿ{a&aC޸ ǽ!g),NFQ(CC~):UMR#w.cеoeDcN \;pd/wf2\϶ʗ͒- }u:\ZV<4S`q"eXƺ8nĊf'S~\LZ(2⚖FcNSg[. M˝ dJhCsWzQ˚F"7"XV7E|#|9MT%ikɴݖ!nړoIՃ<'xȂT&eOA[/cBs²ǕR## E+Meqc5&>ԁ3s‹33̙!BW;3QցpD`fԅO?g!5:N'`cqƾ0u2*vŀ#_h%Y4._zEhPS~\ -(Ǭܪ+Q PܘD,~"fZxЦoJC!딆7f/zlS֙Xf v`>ݿrX{)4L%[.PޛUA|94]دΑA\AN\ߋG+a[Mv5aJ>)fû3E?'ה`:R}>5&ZqOt;*":‹L2 ?k^|S},-5|i vfoe/րC)D]bkFW[VotW¾jmF\WĻ-šcEX>?gnc:cww K?HN}pZ =/0]*?> VFW4;^"tfc:2ޡ,|Yˆx5񟘤Mg}DrF "0jňkG0d~GȜCe:r;-b\rGt gRAZ9{(8i/v\%c!R&;HwE 7SM9)* oubNO5_ 9a=Oh3DƤ->1%_JQq[K尒i\P,\taW=*ͻ KV = ;GE SoOb^7 |!bUmt>a?F7&y^O9K=;_-p|"ͳOGDh>CK)^;; #FܲJ̝cx/3tfBT͒G:vu 1zjt3VExގEX;^gSػ]5Mv5ܦBY=E&zgݻ]ќaZ -(S숂I4a'tMQ45ejc׋C<8Ћ/⽙V.L Vz1㷌FXRc:U 4 GR9zXr֍$XE9_oƌ-K B %N|ٷԇ"^WZp۟ڎ |*5T5Qzxԣb5֠!]3k6/td/F%KB:Ցu8#0v tyb-Z;wa #fa$"s!TpI̜v֚WLw?$G+ [-''(K5; l|1g]Ej_ pW`nHnSY Jnk VbBb @ئCa|ŕb<7fo)f_/:Pfy d,:(uϖX޼ݍ84N=Eʩv\pM?5xyuf-E|d'%= |ssm7 _NU>tïg/NVrT̛?1y[|ݺǶΨN;c}WՀԳ}#%$Coɜώ4-3ڵ}-Xb ]~y o"@5 cq捲ⲛbM=:'Tbt [cе:FM\ :8&:|Xv窉 j"h00L-ē 7*֮0߸}êH9~юmr"3Г 2F s }y^T)e|oϔ;]jzxJ9zq˦r>9llF|,7劻̴sAr^2{j>C\?ni݌ SӨޗ ׇ!Rp°Gt 8=s›9roJy2wX?@~,gWd$rv@2 ^=2GDQ{G8Ȓ6ɁyOϒۙOs6RC`ɨŚ0h\ }AJoM~O&upRt>֣+\MBq=7K`gסZլLJM,XU\_^Xؚz7ڙ. 8V)xV[ŝ;Ṫ?UUz*fVs7}?;*%3>27mɿd\2ʝA1>?d Be&_}nΘ7Xp9g7}x9v,TuW}@GuI3OU󮱊<ߌCB|'l`ӻ0ڹOcK1jQhVX1I0]Ot)EuX'f);waoZ8.FŷgUzIR9 +80oKa!稏*j?a9cmlQ-e 4W1yw}jE[pG39Omi͙%[^pWs0̒7p?˩}}n1 F'/ T/Ed `3q1h ֗z^h8Wwf懾2z5 11Zυ.V#+&7ԡ{/-̙US"9%į0Q4$g5*1}&ow>[q'=Tgqˊ{rLyz xʴ0YzERZԹymhQj=ԭh1;{߈u5h6uh6 )cU`zZ=42> hƉC$Bn 9 n5*y"LNrf)="or 5oɹ{~U\*Nr_VMoΕ-h~Oˏ)&[ jwTryƩ򕒩}Y6O͒L%QJWɛ>|nj{q7>ax#.ΖڑE}ٳVJ޼",q;_mv2:;4`ڼA͙G>bpN;/($z^:`xuJd^$` S;޴d1 P(rF}Pms}M/lwOwL{͇cn/KqY?ǰ~|I͐lzdXR ӚE~Y(lTBΐro+t+'6Yp`3]Z\TT}]6~W=0QXHFD_ '_=VkK <݈ =njX4?Let?}ףہ'5NhO,|*+Td"qf(nzDF3 O@np qꘆ'j K6a"wRCfUl+w c3αW{'2h*qm8h3+S3xZ(Z%ռ٨仙r^'+Ł׈yԈfcW +%}Qcvs'žuf,hXaJWp\݊GAS8)=yQΝJ^dx.rFxh+Éurv`v|m>WE2j?/0~yhykakK`0_^"nӈ75nU۟qC8B%Mi& ֮{.cl$$dɆCa1*C< Cwy$gJ`A1U'%[;^O&ui?`O~5`v'ZcR<|\)8y&>[JQ7#K`}9Z3;޷9f_FVP/Ls T~I Nȑt}h1ٗO$*\S3{!p P0㸄/rC]~Xv ?2mޔ'd혊Q3kɔA΋)!ed+FϏ~a#5/S9w󔞄wxpcDy?e)O7y2Q===ŕ;9q4g:W[&5 sf6΄̽L7.DBT541ID\bo: sPof0c077&qmuLػ1ثÊe"@*5,/e!^)~j3QD y}i3#J=Z|5@ڴRqf9{tP0pm7P՛)NiRE4aufTTWaĐo0}a'o@Mʟ7@|Z~?'IYdɰ|W#_ ~&jn"c|}(y񢒒r  GmS{'JY̋s6ysT"x K<F9tҍs͙?8ЅecÔVfDb~Sga mηd:=VD Ë18ZUMKo@` ".eB,_j|IY>^x_8h 1h^)8\TbL}*+yk}~IW4BM*]"bBmJlWr>5r}9^;\͍Ke4^.{=U˝ت+?peGGWqq<sVԡ~^@{ZlԿw/(#e@BGRjc۹>ϕ+oRοϺs;E+>Jor.5FrvEMf^w̋IB)nG7z{](83ܓB<ߝzs:GU;m;iB}n/"6UzL^meC/)4z6p7][Eاh5̴SƁ>9~%<ĖT@x58PCۤ̇,@JT>5uJ+hʏm8G^= k#'5K}x_<ɏ>< & mɞ6<nm2sg_q`%SqSL`!xfżGX{-ce"x%s,3^a8%NOtFP KCd;N^>`u)rqS|қrv WpmKEJv ̻̉}ÝFi:K!}?pO+IܱҎaLXm|Ƙf;eM^#3 <3w`6$1gha#/G&Q$@cS۱ߛp'%*M.*Nh~J gjs.jgC%C* nX |=Es*|ہ=sP Fۀu[M(Jz;jڲE!Ka,. \AѤgH؟+V>&:uJ?Dx֧=zhLS{3L^p5 ͅg˛K,90Әc YɩBHJ3N5F{@т7 Sۤ,B4 an.,s-ruހݗ2lQxI>t㬵~Q3Aœ ҇~U/7!CGp_RH{ ]MEԠFm]3Ʈ6|eIڔ3p4"!k^:d˗tEʰIς86BӐ#o-߷qڱ/Ss!*Zd=)۴rP:=Y͝meJ³j7sdW6j'<8։mYփoPǞ7z+v~eVN<DžלtGamɊ+-i`c.Lk50:@[xmm7Jj(&1.q{ܿ M2 RO!69:sg[O_N|8:T9B\`WN~\+DEjoP3 c#Lrc`[:4e#F4YÛo5OOLb:ubvF]a΂6䗦`ss0e4VMBAiП C薛*ͮXXa9tŝ\8OI2NThs=񦹿$xpl'u㹹žAl˃nF9\l_\-W2sc'Zѩ9,Wذ[veҜ_ur6G~㵻zU/yc] <|:থA?}^n--;QWj8ߜ o<}:ronKqwLQӔA#.<قAZ<7-tˉReLSsk5{\Ps-%#ۈ)@D@M6hsZA/sY;=NPaF\ݧ-ڦbk,igk$GУ$|΢xH"az$"/D[q^S8GylSͺE^uӛK/JYGQtН*x7$t…ehxs5ypgvsr㖡.>-FRׁ\(xQ 4 Lv3w੧V f84fR=&`L(psVtS7]/oZ7|MRFR=;1 ڌ1ZQΞyx >=G]hbBՈ뒇 8̹4R=U P9V.l?SC\n5GGd߈?MjY|I}ZLS x6UkC翂wV C~†PDBdY .Cna֧󦫡eL_+a5\=kd]G^|`JFg{Gzs3,';P:ܔ<ʖj3^ 1ƄŒgm/okn"ͤ$||ޯ#PL;Z}ï_kM2&bU\d"S]j0e/uj)ϕȸt#̛qćS6rWw"qeRP9~FÌ'̗ݪ䢩*hG4=c.VaXL9kCmE4jAznD֠8 n_[CCNǮG8L<`av nleɡB#ケ*.Rt7mɸnyfzqv/)֫ٹ J1m'bWZ*wiR>~7 ߌ׎Y &f,l*w\~ӽpπЉu 7lS7 V]3)8ֱW᭱L i3RNA5,[1LޗӋQ'}^5v`~/Yr*d`9 1]m60kwA',XL@Pi ́$ oHP~A^Y tdOY\=ktOCxڎX#Ihhɲ<Vr}/,a/{qTk)g|"/4qf;7v|@G8[})wdc ئA*-.] Xٜ3lӵmfiF uL ޷:>M ˥1&'l!mW̚*[=q׋w7J q/: B%K>i0p ;,hiƩF2Id#\FNq5xZUT,Z&#slFmHC3?r4Fï`fvx53\J>T"Skl@\ttʉ$9F?iAZpH ݃ 8^xsxk2Ʌs Wx1w7op~P, AKlwS1"E(Yb8`L2bk32Mu(4hl&1z}flW＀TXKMŋ}K貛b+ˬo RO;YY IF.d*|0 (x@w. ݾé#x\TQ"o|xDD J,Վ>r71{ uJG}zL41c3GqᎩAsRqU!hfkT~ך1߄ngEüd+-eܥ&k*![RUģk1x&4gLot#W--qU+]J-+ Fe"_)§Ոb>W6sP% Ӽ؝u>\G*wJ ׆-wpa+nzE+NXs6">d1&{p}k !#3q3ת<> &_ú0( @̠Zt.  b>R' >? ;3P>VZVĎ<GjFtQGsDץ:;j}bX7;AA,J+v4[7y?cjpx{=kIy#+3p|A~_Ve8gJn{r>N/HX <-,DAt^2{h)\ lcqMp3g;7~aǥ `S'E6棍_.nJؒ_~ Eq9>+FH4\T@\X}1dr w{R/O; PQ[zU)n 蕄=KkfU Z؊)ڄGZ ޓ{IW5Ǫ9⛒ԍRg%|}=YwPQ]衁s&kΊs9bY̊9瀊b,Fɒs<}{Ν{33ofZztuWS{?{WŊ\TL>n!ܕȑ8Og|(ʏP|G,KFv6/J6( ]{cpD:$|ō'_QRT բk%.MhuR0N1F_*B{%W|> _`]Äzw_6Aew#9gXru#eJ$\JSW-0SyMd_/}"|7aGgC>cM\5uxwA]:߫e46/UԦ}?ES1+m\3܁a7N9oޭ`K%ƄX8>Wbѿ]l^ÒЦe_CWMV2tOW"7.u瘵&~Qٯ1bZmCG$a?. g3P]%3f"no_l8ш1[uݧ )7+cuq<gk^,Monr?a\[M+*oHUxiH۝Fg ?JެLzU5Z/֧tZF#4s~2D*ǵ-^ezSb>uCŏx=wF`^n]SSo~rgN.ՙ0ߒ]z[ik#TfWKZSvźG?Ǜ /aﴫHr ?(7kAg3Jr>1.dc fGX /)}iw;⡪G<#;K;ѭԌ|o/>Kr!js]Z䧦OQ:?+ԇRaV92>Y3~r:p@ʁX,x/Bw|*JUaB]Vn+ 9O19lsc6xHPc?i]U.)NvhΩmH̺r.Тe&D\UGWR09?X$c0=+ftq2Vhbӥޜ4Ol9ϻ_@0TOĆ핎yȋET #$a 2.1҆c-)\xۘ6[pRcB9ky f+@ƓexN_e4w6t#u٘i=&WbqdLz Y(sMOP1d2st#.{"{9ȹDP^Sh\߇#]}`=e]l\-T% liJ},FdyyOoX@:vի-޼@Weӻ< Tdj|3C yE̢>`ˆZ9+F[sGv&"4뗎c^c݊?1$uz}?0iX(\^=@ܷ}c(F`˘grlu6hBT6'zkJ\{b(oKm:V8?8c/c.rm)sxqu)BlLؒ/x _TךH 6W!ڎ3AÖKYSׇöxs~Or#;4u^VGLBmYP~AMCHCbX'hj| \<ʎZJS3b![T, /Ru[Hx+G8Kk:< ʇyvUWbl=< gڌeU+>'Rfc.6M}Rˁ8{]?gb-GonV1ؙz]ٱU=mㆋ=+z:%CRiՍ8CѷWt91ׄY0uώs㬾<ғ&/tpGNa=6)Wqy^i%Îe 'i"5yoxXe4a;ܹDȬ ^4@X| X ֆH_SIR\k ҽB_k9Xת0 v@Hl_TZ76T{l´J>H<\X˔:lS` ObU7ҊR#-s? jE>@zJ1f.;:%|{Ӄz0o\ 4\k qL4BKv8 \ բ\[/4R\$at FEƂ=Vӑ69r /?3en:55~n):'ڠŀMOp 쓉 r|,FQ]yei}cp5|ߘ ^lm ;Э~dS˚jp;Xt%qpbzƀ)#;BܩRk-Lh}ڊ8p =6r;]z2.Ğ_*xp$=PxĞ(B9&ي [H?)ƃxkMuK݌tԿ{v3XU Z/ vGA~[m"q#96iZtp'#/PU.b2u0ޕv_}9·?9gקj09^^wJ8)Q'6WBu{8ƌMHPc>ki4md+W.ұI˃kQJ>Gլ+(<^AåG`ϖliX$gхsǜ>"ӧCc.h5r,(Av)nm l-(Umc%>|kN}$-_DҤlYpVua}x]bP/Wƫr8r[Y9l,|+a`í6C'%?s>2ڴcX`V(%[uW?iYޙs >`&fƒ;r;˜/Mj)_c~Μp˔U`o^|ޏOc88w"C ѿRqO4MGgiyJGƉYZPvi ȻzaTk"zw {;S*u P6~/Fm؜q[- dVC9C{m>rRTk 8O.[?׎?t\ɚ]@U)>}ړ4-GꬺץV{p?*tbi} i@; 2ep] q)腡\u=6͊-UOD?i/\MZ<ÁUÎ?ps^-Bt}ӊ/3%$(=VJJ]W5i7؛;{!JG9.xWoPv:an)2: 6ft= l=˜Sl߄>5X*!}';<,=Dß?rJ0E墆Wuځ/~L|ǽxw,|sNBȞאm:8qM=SˊvjCsxEoA\mF/J=6m3d=)RAttnku`"gd:O豬 2/oa>>,Bx'M%[&kNhlʾjp# "_zF[K6íBc<\+cƟFz͔OuZ[˙JN?z5mt] Ƚ-5.[@s&PK_`?Lx9ՍCey(]Cy*&?b_0c.%xV5fl pɞ>)yJ= yǸ`篖JLtmcYXw>fýa9E]kdO!B -8$ ?a  |O 'Y,^G# &-><֭A̟d\0њ;q)ϧquk 6]hƬH㔼*B纯ॺqLpyOvzdT7DW84W6Gbm$[/)rǹY.u|/LhEg3z=,|& .|,\ ӋȬϿiz BxU38<7JۢڲF  >ÓuL8%ߒsXߜr%O~`z-S5b|-f1e._Enu,VGP/,ˈ6k{H]U8[ g'_0Cцm-gѠtzơ49wP~5 Q'rl}qˏԺQq؍ Ҋ*u֟ Wo^3(VofVn44zOTֆnU<.?VXt/RXq(bw<׿ s#zLFuֿے[G|UWj$)å58ڶ-x^ xt6CxG+=d+EK}=a߼iῼuwZ-Q]O ltt(s3Xz{oeAm~7B/a;;sgyܣhzc=haAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[r[z#lVl X6ef[n;u[Oo"?}Mz؋RXY!ƪkRޫ k; Z_}STIT\$MT+t(EUNϋ,Nīg Vz>2:of:5Il{~])HM` z^Wk?v"x]U==K-9{.'m{~IlMA#.Dsuqt5RjVX?0B{6,\ap:pۄS1Ɛjl RO-%{ksGm؋ߥmJ?](1^}pj>?%)tF/U[!mEԎ>7S3졆(? oGC}Sca/NK3rML ;ac }1G݀*"rڔҮ-l2fvxhP)޶SP'ۂ {.Pz`R^7pIT^MZܼhO- 9Na=# >duQ鰱CO!PsӬWL1q MJMG[d< Sz ;"xNٶ0RH*i^e UP 8À)y6ԙv8p'ΥTsG W\XYe(ke C+6 ^E6z;2lŞz8t-2f|jI8i==΋;sags^cBysniiʀWUUҤ[wlԿ{ r[ZNSC:M;|k$Ԡ4mZ~≨jwU6QՠܳIy>Q^Hvu ߭BirB1+3mXxցM*-)Nj0}嫿 }v Z|. &aZ!tN\u؝ueN"-:c՟5^XgGY C]]kyaf*횜j;uc+iÜ,A<ޒUu \4Ɯ̈8cj1Nbˉ U˘:BNz}64f{qvgܐk~h#8vՔvWՁ'-y#[5ޠjw#^30-uk2:wȋ2iCMGhj5x{8'"G1|Ԓ/JmhюO=Jqva~T2dX._BqwGuãqR;jS?A0%ᆟԝz2vk rr4qM+X#;tۭů c>ZoH 0LZEUbͬj $g) gYRqah-w< Jl.gT[am'>в㩶tsߴrMa¦xFߒcC~>69>/8 ;cc[1;֍5v }݌MkpyWgӶi/J6T\dg7n4ww3j;rF'kǭ,IFA MOۂõ-yb-ݓ`w3J MX8 .y݀z +x34 3=ô8[Ob1%u:X~I3:rT OޜM_!N.kiO j6QG_ey!/,]&Rbx;`s-B( Eb|[!fäD JIb+o=z`z:#{sgnBlZN%=:A|#:򫍊2l؝5y˜sef|ag-x!;©)yBxa'xSɓvgftʄ[*hW-»/&`j͆Z-Colv.?:Xu:o"7./S~"41c6X"[:?^cڼ~$ :i_r^mga+]yCݸh'_v%3́;5S.|{ͅ+_;rW;vf'sI4yςJ,%m,k"dCCGjs_"Z8;݌>Z0Èq 8gIG&FKoONQ*=̐J;ŜܫѣyFqV'NA*<@7g %-ϹӢ3eOV|jt6Bw36O Nɾ8,= c6"r6f_ zg NR]OJg16:րwBLVUOV2p+qfZoҖJqbscly 9~ٳ=#55R+?drSKdt=})Ċ9]z_b%6 k鶴lȢ1ۅGh}X>S[RG2ڂ>ښz>Aϭ=;:8>;زJˁoۻ툒zUٝ3]3]xXvVߍ'FX|ۓmJ\x+Wis3.QK3nM+Mnlj3˞F~b_tdMΦܯkȼ:z;|c0]L| 3cHrj#ScKyS+*WYr&,ta!^P{26ȋxp5eT9Ӷc,|;#tj+Xk wq[r]YY-#.֥mF7|:>2VQC͘cVșU&/d ]vM.Tj#kdG 9Vr ^;fmN>Xc&#F<ƍA{s[ fzY8k~>gUl<ҍfÜ(5rΥn+]g̵ޮ{恒[ϛaru(WScpN|Ԏ]MMia i},uClTC;-=HzG?^B ΜɷbwQhmC`: [xVzyY80RNLo) P.nρtGξbx'xpF[ MΓюea":">3Dn{ƃ.lyl>kJS+nEӚd`OyNȑKl04 Fי-_?fT/%ayIQi!g$$o@:a͊U*XS<ԛoL*d(oa9`ɗkqm/lŧȒQb>wUpoOD>QV7)rFZȩlj,mLE)w72cb q}雃o"QQ} [f?q}}4׏Ĝ PYV[Jxo tٳ\ ޷gn=Ğē:c9[-ɇbtlΚz w㏺*}fTirbw laNZՐR(#=EFI8F~ 5M7{ק/oZDvmڅCkpûYj^XoˮYωv0q `j٘R>~PUfY&Ԝ5AVZώq ; {I wM?/U>7֓PrcwO~PyvO_ƋkpIg l[j 1 T&b|yjǦlbvCؕ{\lÃ,h.gV9븙3KئU Wxsdܘ:7B|7Խ/X%sŇlY }y]HIreOwXoδ]`k5<0=jِ-M5}Z:Rq:%w{H'im{+ .g㠜+s]ZPƩ. YIn؀%E o9-ս~Ֆ?ǴAufږDm]u|.Bwko֧TGܱ׊\r'ɋ!%g=iI~agtb(#xқ3{/m`NGFlƞS! dNA db' y;Ό&L9kGX[n.iֽ<A1M9݌qɵ4LKc1?#2_,UM9Wa2LZġ;r̘Oyr, nxuXtـ|j4jȑ ƺזrh 2ڥ5{>"QNZf4;x;j^=%T2,à \ʚ7X=mU5dh$sqn7ƒ7~-鹾q9j>OWw27NxtmxmS 9~kfSl;,̩>.NZ`|?Q?&$ 9n0"t0$,j_(Nۭ4߿5ltyc_͵ʇ;,84҇G~ :_uiW+yQ˩^וW(Lwi}ǀn6l47grvܘRWE6r]fLrsnyf˽lq}& wsr,KpTS/Y-zΊ.кPu2lspZ#_ѩ1utXSUMJ2KSiłH'ݢy΃SM=՝'ܩ8SpBJ)]J5fNraO-q.v{ݖ:P.lЍ߸1LlƁa;ǒ8!ϼ)EWnǩ~%k{Mvx`2.}qf>Zd@e {y|c#@ \ Ü D\MuT;?Ñj/Qlw(f~7fRz˥ |f;GS#ڱIK;^nnth鹗m+ 5 4{oվ :9]k,8! A%HnTy7Wsߜ˪NK[eݻ>^ey^nKDk+lcx0g7`~w͸2Ƃ=19&<9Ҍ1fvmǫ9LmnDȴl klE+m6 Ő ؽuУ^_ͭ¾lٚu(j-dx'ֹ3.IJM^43b5GUə4[k<[}^VIgScl m>;S'a3{߿rHg|d4/f[ºa9nm.Sۚx1UaD8]AlFx?{pYq3nSG\n(d1'|u>` ڠO:c+1b_-`gx Le&U+x「}ht@î_ or}KŜӃ\y@'Җ;3%ǐQ= r1b{Zy}?eu{Q#b:!Uncx`vLXګt1;UŠ]kr%⪙GXRɔGZ3@߈' txgy)f/̃ oӐt2eaNywoPabK%k^ŋy(+#uOFlv֜ԔgZ17‘=뼂 Lg|,g"-2{XP]Y>+ 0Y e<2 ;{ _bxAor|ȤHcؚ\LNyV Tƣ8 zaC"X*ab-ho=={j>kI 1+y渜'5c7oSIXO~$@wvq?w\ĚZsr+0g j ,8x cUu7d3g@R |s^|)_D0#U壉c]PXG?kg\ŨJl/hQG WWR[fOCڪM#'n/G:PJTqP9+b=(.SɛUb^<"`Oqwo퓰i\hUr wƻ}3-bD K93X:Rn!}z Eaol|0??.Mk>q=au:L17gKڏv˿Y}rs:6*A^<͈QL̙}xe':m-_~s>==ijV+$Hٍ6 U#p%/t %{z>"} _ =Ú1m?DŽ΄Zpj+Ff uDc4&̈?09Ow4ȷU BZ<> BlP{5$^ n1d՘`SզzɂۍJ%}n*X;@_ʩA.dT-o뫹2^ɳjW~Ĭ;ɹ$9]5iMɆ\PB>[>Q:C+p|y`Qپ[M1$3é4>2`ixW=TE7GCWq}1u$O`wCkE20"6?cɒ 6X{ҩ@­ozfSPe Ny86 vzl6n[3{™=TC.(c}6܊1sŔt`7 WXʌp)aJtTr2RdNz>l^&bsÃCz[)Be)bWs&g-Rx+Wt<=b7Xl3Z64iA' 7OЬѴ6Zkp~*t*ݡu66P1}8ҏ'-^=!o~NhW ݏ88![5;r`+z/n!|:#T5n ]Mx>ȁEBn.KWȿS6BA[+Rrm ۫yJkż w~J+MbvJ+V*3YZ;נwVSZ 1V^zL,ě+i'~Lnx}' C?gtAZ"˭:txd<9 Oa>v!#8~5_-qqYz쑬'x~Ģڗ+lûӊcCUZI mQVˆ{rRD*Rp2*T+煱RNx"'B҅m4,_(:RG{=.`XsN;-1I{߃)kݦO%4aP!/3dKXQ`uO7Ӟ;t}+ɎK;#.{rGȸ7(H3lP)uz ޶N63=)-q.w5YvPq̈́Ɖi2[~ĥ^1Hxk}^7M1BAg^!O?!5}+mKΰ r1h, á5kqOLZܰ? nYEHbPK=nnH(=-Aλ W[\1aNC௻zVz6Xj{.OzjSq%kygMIwB޷^|;Hwdl^'B& Otog3Nu4$FŠٿsj1kMAbMu5M-LXNd`0܍٧)a9oƼN"68=VLEѨ\;^nJqLgϮƔl]e/ f[,Ɇr(IpfFnOpge'GHeugwAΫtZ%c:%?$iۡ!êU3ɝ=YTOknsfxh"ꠄN +oqYiax"_21aKhtpxqػ" UvSjMKөHT}6XM~uҴeZ ЭČE!tKeb(nBY1߹'w!a[ZČ6TBأ+'s@ F8E/yЯ*8W^E|Q _3cG+KƦpG~]%6k(xBT!㳌kl0țrub;-b!֌XU;GI00~vTXQ2MΧcD^'`V}ETvu5 >ÓtX=j@+AQv0cNּ}]n):_zyb/:9{ِ6\uԎg6s~}F\D͡tYcm@&> kLNFTTG 9F> ~+Mr+2fP4ՋwFF"~ fCWGE7eWɮs<S9\ék1u=pT#Ιdɀ|+fXC;lgBi"5[GlO0n1֟~Ȁ'DK} ٱ] (B#lYZad&cd/C<јI5)pHkpw`uh'w 69{➛Gl;2Dnjzoksn)\Y˰N]܋uصF[نw8꽚نjvHyr|'2d*(X9\mv|,c^tK&d]έ:bfxy0 {l1F|֔l#eGNvGNjˤfl;WGmx7E C0f6G͸1[M2e[3FwVGvp##:g=>=O+#^o]VY5wĵUEe܎9Q1tmPOGvud+?9 KS; }`_$l݆fɘxkٳ`VKcd•GYg.оÉ fS EpPTL4]%7`XZ,:_zH߶p>L#X؍_J[/sv[\Iyh$ -^u)֧>=8y`^IInjK=$;b\*~"OΔi*+3mXu XK٦S \Еwo;p.+mx(M7_X15 XZx xyh}n6ШhOR{Թ8a,iaʟ 9Ȍ+昍y[Aᶬu*ކYv|j̑ n#l_wإ^TŖB-8)rV1FK[xBǖ*Ω/ɨW+mR^,9}[N=g^ϱt5r gWЙB~0':8|ab O1lC\?aoF.n^z!=^[S׎!lю8p'v 'j3Ѓ|=]_D8p1; _7kB9 sC.eM4W>򤣛m:Y͛yq;5ȔwJ>5h#foU?hn VRq1?-))eʙ8¹RP> s`.7Z=|qsާ6 7miM{N_nv}o!SOt/GtsJhVD*+._V3y[_|pÍEΕX_p/va+A͘*zJ$D̢Z;~`b!jzoa +97_̡Md|S[dz~ e.w$g^ɣߝUiġ u=hH8pF GXxCh;H1".#r(sPeUc\zf'PqSERvNrv~yڅ>[7Bue]i>Kи"ޢ͈ۭ^פCWڏ% ͒x^ץ\"v`vU81?PrL.6 W3D>C>1Aw\τE<VL90ӕY+9xVH!j>aM+: dOСʙ?^M. \ob6_fͷzl i ѮM.a? K?\?!gEd}nnt`;/ע[|9 ֥iY R诩f+w84W58#XB-'fi^`:Yf`skY!rcJzf$9 )w*bghhE,Ybb%_ 3oooF-w W^B.sx)[mS/jwu$GxGI\'26ӑsx)MJy~]ypBGc%oWh㑅aY-Fq *faO=/4!لn"kȚMxŵ VgvuLwDM]p)Dj~ƿʜsT;ՍB?JW74d5[Srv 9OYC /٫b\( _9xt +"|î[p9fN5c"O"g=#+xW,dN<օ\hǑByٌrkp&O]DDmKARkiϞtkVOZZn_ .i:Tœ0a3s3MO6rHE9gWl/VRwMרةVŻo=h]Thz|=v@]| چtB{m Tݾ^dߔqZ;  y~l9TRcݛHq͝-ǹb#Yp>St$$$c~H{MPWKezBcB0Qbw6瘥VjbElcnT3aT(Ϥ`}2=SP i(iUh58[>"b.5vx؋͵j*#UOKӔ|EIj栟a H` E`#rؼ ת1m||`X=ݚ1Z1]Md%cs7#ҁ:sjwh!&:?7G$=A%/;?q4d,>kG#qkHkcL7s1fzLaF.*+KH)L^Wk8}-ÀEȯ.e^է +r#Rxǧ!pD/0f72 ?+9J^ nDŽ|z)?Gpj®b<l>pw 3AEb#B7~ts#/u#gy)|0'v@@\F1 90]mnb=?a}2nM0E=Ŵٿ00Kcl-u#J)c) YS$-~9#,J:,=΀Ť="S#Cgtġ6Լc#bsLMWo݀{虒ə,T?9{=81 y*H´n}TE) a3׿7^b?Ǻۖb զK0v~w^ 6L+ZVUF.gx}Drf3+?)uϫÒ_:(54 УU-n''uD1?RQo|aؤb`59@CyOonaC<4ӏQ< *!y΂exo 7F@|;e !%zb~ *u1z1$܁Ԛgpn9.bgQ>F̷0©&lBDCLIblC/#lx~-*\Q$J:9겜WiNJl1xrv;# \z;OCIP{cЉk˻ N>8}GBBK^̉p+oMUJ&=7)ՆוzL(/RoÓٰ~;`JIy n; /홌7l[i87NG_/K(Vpl{ײOV_!BGV9>þ$V's}j[q=ZѯAZ$bǘ18ӎ5"i`S*6zs 9MYqc/JfI;tf'ĒEx2~>TW":|]y0oȃ.W6ѤXsl'cDbTC)r,{<4C֡is߹ B9Ѕ wʓM% GMșEN%ۧ)x ?Z%nfM~⯩GaFA͸w]1%l})L =(UCV=4<ߋ^{qQUֻd<ޓ[q̇nXƜg᛾ibNmMسjzcI|%ږ ,]R[up?`nxN?`=Ŕ-qhrp%'G2q6M fX1ڍ,BR|mXUI&Tj1H5~:TxQ]~h]fI^H+XGYC,{.#gT*6#j.K=oO*#sT0ܼ_.aP:#6"9u0cLk)(Nrf(8xru;EG85w3vlqՙ~fO^**/(TNfBv`E ob=RTۡ\5 :7󍊯B֜ߢ_Q u}1jT,#+ֹ~R;0tt3<_֝_|ػ7zw<̓8!.>&tWDu{0ܜ~G9S9' dZX߶F 0 9́i.fcd(6m?7nxg`G FwYe)Kw|x \Fg߈߅Iž!ܽĒ~7ZVQH鰝ss2 :sbj~[ɧ&*~`g)9dSv,VWiggfFƁ`l@oh6gyh"' ZPy<^N *Y:Xe:RgJ邘QDlRJFx*Xe!,9gE?TCn?+xfg2na?5?LM xQf4z>3U(.jPocq$p$rĒEpmv%8|rVR]f>Li^E*>3资B`[vkROd74Әf"$cۙTl}X8;&Q&6fltiN|\lC#A{I!KܘGQuG.AVe2,'9֫rtWrc{ .&by~B!GUyHR ߚJ5ܩSGUVb nm$%?ɘ+dw90}kp^ n󄽨= {ŔGvOG~{Yln 2ѓw*RO,e0Ȍ!w7mGz OgKXh!4u!G*DeZ&AKB7WMU[sqS-ݕ<_,>DYQ0fAF\=; 8Yx5z Ax/;*)R6^t6dڃtÍS5X>2% ʙOq\8'ʀ{<fG`8>%㾣3fƮ:87\جLÌwqy9Ϳebw;)wY35- >ː j _Uq3ڞo#*eU<]JeCɀ/Q'ow׸rM5Н+p_ 3Tޫ[ɱ̜J>e6l*Ƽ{ow SqYV]ƯXSƺl3ל)*qO9+*8x22*KxꦘK%\I˜g\v_\T-fc)_r\Mnd% 9el}Ej9lpk?se솔1Ab&9ZxvLjn$/þ g2`ȼA3u/DR!E7݊Szb|%WQ~xaanv⍒G+DkTlt8.څyiP41-ncGxxc?5!Y; @T:_)1?oԛӎl~€R95L0+~5F4[k] 9171ez1^l_9ń j>bkЂ%.i8#]LbΟ=3=8{u5>NHw58怜n ⛔鿤V %SɠEB(FbNp?FIe&w%Pe/%/Y*$dtINE^]q fT yOı10oUkunW#daxQ37./v&Ld9v5"x4А:6SoQ0QrXMu#5^S'GhprARX>yC8}f#Q5]j1ܴ؄ݩ==`;Gwh{-g? Ĺ-[{mp|Pe%vnn<ĕ9ˎl<ޖRցI9w7q%myZqK[u3F zj²PsYszW;-eJZ 'zX v*yr\+r4,Ɯ#B^&F0WY5e;칄*|@9I*pdܲSN$%2 Y2? $f2vw9WN϶R2T#am*~ Pw?R8Y~cbRzKnԇԼQJ~h#{5m+yOӶcl]/fT'vXaI,jV- XE x)Рuu_+0cpc9Z Ӧ%0}U?ô^!pPX,4`%+Z9s.gMONn-=D "୥q2i) rz4dP+d \88%-:ZAKt51MwR+sZ29'*cjdO]xп/6Y:,q{6jW<ȞP;Nʰq| A|fR*˛+ ?emsۿ YCͷ٠3+Wpz;w!`'jܑPlkQF}׌{ |D& fz᧵#y 25ӌ̨:oBQ.p5W-fteQ\<ьqf3_] $5v*1x 2y#LR-`gq5Ѽ4}MH4d\"2z1΍f5SL8=wK7igƤ9$`FE1gbO3tg=e.aruAgJGAԢtmMe5e-i_mmM'sS[L5a?p hC<8Rwk3~޻By )L3s7# lJ*Yht KcgS){E9y'iI[r,&>;,aF-pCFb$W?cU$@ %Q`E~4 #'FZO X;ÁC b;1FwaWI0c/U<pfLr /{ aT#}492}.M|l'p!pDV ZU[!c[-m-(1a_hH ^Io<>Gd@g70(; I„:5HFV"j ա* -?i,s#.jv5EԬw>L% !؟Zrh5uXLBcm.zq'#- nph[f܎vFh3wT8掳']b_3;*{Vѿ W̨9lcU%wԈb9rqj.lMR^Ͽ"hS\XGf8}pqr66#Җq-y*X-c GuB<n>,t=lc1S?t@Jl8R<ЀI&m18Ԉ?]yym]I.|a|JNwÀ^?,-j wqԨJfaL)."8ox豙a@ ]ṾKх~Qu$`>hwǽYQ^,tnΕ< UI ]LڪLG14{hIRHcީPGGva=mq̳ d*yOQSk$:K).m/(a&%UX+뜑hƕ#`;Elpøj7Eb"DOyxw3]axjFV0ǵ[p )&|o`wh1j5 dgVb7[ 85Wr}qĒ, iF"rqx~X2-u7tws\` %<0{T}U zq)qr6v~õmָbGSߔc]DKStD6K3 x}A;F&KHR8\4!g ՚ÄLP^wff4b8|xn6x`qFy WB{Q#|n[] \0JlFE^b`&:{ơ j i73рz+c}zxÔGtZʴ4h*~ L±aŰ<.psi uj><H _u3X.'F\Byꌅ#8K"{dnΡQYyc>[\@%hЅؒ%K0hdn Ԑϔ3x"7ruN҂ mh.k| uDr>ŋ8wt3X&k Hp7֌Gش gx[l6=|`{һ:QT ya?IwӎehRkĴoCd5ͥGk{jVcdzXZo%ˏge^c)e}mhU'V55V(` -;l6٣@V^<+DHO1[ 03!WrtPcB'̴c|7^R+'t"Cb3 /0?.ٿ/gK`+}/EwWloYbRIpvzC(pX YPF(68UHi)`:Ƴh=6/6cWҍ9L`Xէuq<@T6Zq1Aj83ggf#*&ѿNg(CL%R?+q>CŽY d(d8#DsqU6f4' .n;i7z~![=pc3 )M)Ga@4 hb%PFHFY=5vDta,sli N(l03k0v=uHiF ϻ¥r+.aC Br YLO7qF$j`E6(c{&b~j xZ9wň} XjºnF80r"Id 8(W;%񘏝=Ҝկ+np|ԯn 4uZ8?kцCiZ27EG669Bg࣠yb$3a˾u&Lkl0FP*LްUCq˩2'8:ףRL4n]~)1Dז -a11TDGp'gػc^a#x 3? NYZQMytAJY>|OK:{JGҶXLק\daA ÷a쑒ȁ$8;U3'-sF 8sT(> +_7# \6a 0@P?FۣA`9RqYɧyYcr6UKie /Ls 2̀Anm!FtspAg #q ,Feb5WOym?y @c4į/K+&][@UA:'JpI }ylem 4!I!u86ӳ2 3uׅqOCW,ߢF_Na|EeI UERo<_NshQgxjѷ>1^\[h^M #ϋsa<)bH3DẊw%$g!MmEukhoPH.{vs I{]߫Y4"1fE]-(ء[,Eb} phPikT_AUZgF4m7=0n(vEogW$pE?>L?\TyYZ,F2x 5UЎ')vBYN=&ihJ\fѷJNaNXfPNjzD1.IЌKNӿ/K3]Kx?;ֲڲRwedI7:vPV/G,ϖRtQ=֚QL ;+/48 L K1URt._+9쯠ESf] :lavݱ :8pUZ4|uFhq"CL9b$2 Ӈl-s`ll 46 S(7=ZH.Eмu4!˙'SpWSXMs4b\$eѮVAj:c /_;t?`\t >_|r$X.Y[KHLZh`g³f۹ y;b`Έ #> M!?~Ra0VB% sR+5xO?O}p2zÁGvc:ᦍ3=QmQ_5X۴RlAzg 03{{=Կ{O;Wko65+}e)jdJ7z=rM ugYC0FYi*T_5BpAT3Nd(DŽ] 4(Fa%X2Î]eEIzIzR,]E=zKQ^Eb5Pa#?iLbC 5ys#:[X#Ž  b"L,G o'™g-鄦ڝ,γibcymKps-{{TX:,?I<;QL5g%Milph-N> 61E _R{JmMReGvf @Uf>`ToVwj3Hp{jO |5o? &8 1rXzl8?.տ/ؕ^GueS3ںc7lKuë戂RF RUM2#8FhV`;ۋ0>L}_g4qO"2 iCQrxɝd^F\% 25l]t(k ũJoh0p#"KUxףoJg c_;y4N|AFy p<^䈍l1jJWK+(Ϥ}BIe7$|+^KZq~>TS*rd;lPkwFb_b#׏<4C2E+p>[sYR\tn-@^יa|?u KDg%IY2쌭*Ce=Tp' ;x +2w}B[>'\t7m*+ OAG TAr MsZ +` DS>(םEу6ٿDNmf?f>,N i߂$ߚKbm0k;$sD%zb &b|F?)6] 7-)Φ*>_%g~4*!R*Tzifz3E_.p)|jLSHupb+4Hҡ!*x&9#w9>b -w"|{a*k]Vo4-[2.߲l=59Be>t066` v #.`CuJb^"Ea{UpP#5@Z5FrhO.2ѽp;V0"8N6i:ԇ3#X}w>=1SEp %}5HP)`ZƸcG-*קDxMhd>/7?3 OYvb&_=bf`]#3ߏr;M^"]]߉,d@S9ڙ@Q&d٣/Vp'V-N?Ob.LVxb)9G㧟?NS]N]]SNZ8WeZ +p[',b<?p&5U&5n:uyOΫ9NxMKd*!&!6СVyzEߴiԋ{eͧ{Tg m#[f- ccb~7sľ$J=NJ1F9&2Jz|mcK0baj: 41DaB`-sЍ"2jhfx@.%T`L9l ֩F?zP@h$>ş(mk&ʦR5Tap1O$N 4C[w1D. q:7ψ6)qѸW[#ứL[oy'ѓwc..I?R7^N?h38CO[أ㾃YUo}JG=hO_ :I?W, IU96t m'Zw-C^ H~Kᝣ+zia#w39cPl9VreA.\9*)P°N̒?9R^`.:qx7<5<3Pr6$҄bL-=ewްczp<%#jmXX+)O G3XdZ|e\lT Z`B a 06@A 0aه4Xg,-?QkaI$r gjYnWweXXˤ b<'l3U]UNgb>QiKSZd`kR}6Ԑ5Cpq-ON3X8uUTԶXW<;bBo_8@DLRgؔA4el&r3I$5x54C ZXGyiNuܺ싆at[ʤey(JoY-87!x=de!![xw ?$U.GA{)\:cqt:XfSÿr<,ǧ +8)Qxa9r>1?Zy$00^cQV]{dvJЍ$V;2:fۡ,|䬱#{$% Üׯv SH 5%03Vbn ӜQ[/N0jA9Ɍϯ"::+XS-+ʧv)6Ƭ9O=A94p<0sp[H)։ .&󰩿=⯲T˂MIDd#9IO(O#Uy`fXv@'k2UMVK_I>,ESڵRՐ"fNg3b4z ~N/0seu-KShs"[OgtגE93βq{|b96L_ ".5>j(C| N9a7 JMpj2JAmR'Qu@.,^&Ψ{*G"(18rgO٣P2.%GIgu \G‚{v䠩W9`G ѾBf)$~bXK1Q\'/v&%D(^>j\Ѣ H{xyxD=TV k11TP>҆]Vw/&qRpWn-E8_&5Rb{I\\vach1g} w~-3ߣ>_C/VP.4 #Vגlf)TL~P֔El>B,`ד5/BNTM4W7|=ic,R rͣq4ݿkt RJ+B )qx¦{kH[g^84\*%DUD]󔀧 %TtIS4HA;v k,M%";aQa~bX_򰨜I>r78slś(.?d.q,t*ǓlD1s6 ?r0=z >#!'$Ir,;@r91.ogjQTP.؍_pYarn"*gs%M~EFEЍ3}zYBdkl*$6ĸW!*UW&VT!V%vBH G*кi 9*:ra pd;'d8%2lºN)XЄ",@>:,39w[[@rFH=.xy\+ /}o,DZskzQl~LQ&'lxjAERd8PF\1;8mQjMM|Ail]=(>?cxh[>h{ ᳄Η9p÷B͚ZZn΢{uaJM7Sv9= ѩh+HЖchCog{ko;٫z_i*b=; !>b9LKVStWځ˂MR5M#Ip>y$٤UIcJ-iSނwt#= KݒZϫ;A)GD/)z0 k+%6wk{#}WM(+qTȳQz0"BP!ocgS1$QIR],@vG~3CȜlĻPЇ2[Yé=fdB6qKb8;\.ĭ̑b#FmX9*rv վ:;1sI *l `=U)J>qA$r% nk6;,z&EmBPTШ2bG\uZ[6&g ;/`Nc+3:ǨspL-nUR$8R\~4VG?ޡ3!RHAQD] >vw ,ql*i 7 b֐-!Wak_+,ZmQl"+MIMКT8<FҟYYeЀ0>!ɹ˴wں*vCћ*isVlV *{>&ă|"N cRPkFgĺ0>;\ e 8$Bu|*RlefF1lY#6,`i<.Q5[Lٓ%L}_h-ramࡪJfF`x9Z0^5 UX 2P/ #4Zbđjbg-V33k2!n#9 RxX)` B wTҌEգv)ˉE_Z@gbp oZAWF` &(]QI՗ i\ZJ5Skt,˶:굶 &9:ݡN#0- NPuaqeȘfw@>4/`JX 6s>- Y˵Ets٤ҔWjUO?>)GHSpHrpGCGґOtAˤ-XQ"N2,`)$I*{HGS j4 ]AX+c=g S"h >"/#\ >6QS@(&}Lϱu-jXBB{Tsp#K9Xm.bR=_.›bc%BL"$ ˑ?RйJ|Em=6l`T-2`҈jsga55Z^&[2 "\LF"fUn?Ԅ .Wm@-:U@]yB|.^͑}7bd]+-B -m`x\OvzT:K׬ژ#o'Ɩ5 =9V#„"\# Je:o\=BHʥFةI~3D(-Ŵb|gC2D ⠙?A1;,724$~I=9-(qy$B6o)&(oEa3Jijbz,:=ϧ?6.S4eN<5lKמt>֋N-Ź˲x z3"$ƶ^b\HX-ByIBīJh/?h\"Y{A[ y^@ oipOK8jQ6Ut0BOJ &o{GS_!M`>h'bBg\B>IE=Vo%#ѡ@Վ" G/x8EJ>^cw>.*\ \ȱ3>a>kDJ-С\eĢ:,E^ o#YAbHr[j921%8qf~:UABY$ᣑp ~ߊ{̣zW:L3_҇&O)p;j_)5e-b^ߥص'^[Exko=rb-'}TcC3!t{XyH19DߟbpJH2So[ǃ )=>)).=XݒJq.쬧l^ hf3}Ef12!ĶrђGpƽݕ8vf&pLbBw#3N}O:a-0YR\-ycv+퓕VrvG~wW+O6_Ehɒ!I#xx#sF!أH9#AGU8ŀ&|@XZiCw SBy0=0LC_R(Or2؈Nl ՔX@S~O,xLVYkh=d-VEPHr=o-mryB)4'&ؿz $Qwq%lA}|?MHs>w c3xQ~̓qw8z.J=xb= Æ##ؗ3rx[MM>Γ?[)_FNX!6y,@qU0 1<?VŸzK ezIuSWw| c==fdb` A(qO&;t/l -HEkiS* LO{t6F^?kHt$?@QѮү_y'Կ8Fɩ-VAe robRL>b(%-&.U[8#kS{Ht >SO9۷z~*mH}1W"Q1]Q3)^7FLQ'Y(ˈcE\&I!\;BPsX0I櫳YL}&Ėf"xеSտlx+ܚKkH{D +5eϕ&\C^C7gm4T9֔1O.ULYf@ z +a 6Y,SL[е 3%Бd;Vk23ɔu9K9Ō0$=pBm|0ڈGygZ='Ps'G5.v!`׮Sea ̎JEl)I^T]եNǺ;UwNq$޿}<Q8r8ѣ.F^= |j߿=u{ ! ˅"ic8mY-Bg7BՇMYю3VYQ6E}UUYO`O? 4Ja[QЮ&%p)Nu45∑lٯyER~pkX&e_+jqDTI2c. p5k x`f5[-[Z#z߂r&%fXW<͸w%j=lGJ -{[ 0di~a)/y[pjkoKje7c[H8S\ˏo%lNʠrhǞ\nῡr^,WJT婂7MxV#9#cMֺx+dzuex-0cX5"ck}] W", Yri3g<وX\+'Pi{ǫ9*|-:z^nkǩ"ܾS jIgU+:&*)_O7`~6îy|?̖i1gXu*<-yG!W墛72",ec^hz֪r97lRP^f)&h2HJ*{j6-Kq@C$`JN`MܐbG#tʁ ܩaa6K,+zo-0;w1G-eJT9H_ۯEax|71b"c.0)f +3漼ʊXۜ7Z02ǎO#,xJD.y&s\uOtF߀KyQ@ߐGDt:FT835Y+_a$@]_O h_TFՂ-8ey.{dS k 9kC{,}?Y+D\䰣;?]?w!//~NgdNn.B*qT&w8X[ny:T%6:Wad(].,&ǀ87!dޒ.X4yxM_PR[U8!} \!%Z lhqu6Ʌ-R:yiq/'۳FӁ!3h{ؙgj]ܙ.Nȸ@{ϰ/ɬ8.k0a#|o#XxW?&,e/RߠȼywSRq@/*ތ >،},9'ڌi,ѵ۶bIV͂3 i|-)6j]ࣶAMtYQ]GlӔq줦R>*fv ֩#pgLNL_c aւJ"Ƥ{iW LR{U%kjI5{҂2$A;h36oG~;h K_8_B眨̭jAĉsMJ쨭ćb%LDŽ J9c}QDC#'1EEPU [ db8\~?:K=pDSl1cX6\n>QUM &I(S!όf,rN\Ʌ%nFDjSs5xt=>X Epyz"z4|=&)sҢh,[OtۂÑyS3Ә_{X5Ӓ/YҶҚ}GSje/OmXwa j֢N:KxZƤ 9G.BSՂ). ~VEu=]b@g{.U5tO٘13ro$!prz)3% [qbLLP.e8U]o1F:ga@7}LAKo`(t^{sIkSw.=]!y>\lj0wNEh ήߐW7 NqD"t<0r.R@&Hӈmh| ytkHidȓFTeRa?Jypgtle bD\\*?vFɆ5Wؙφ '~+:G֛s}ĵP6ʼnn{0f?Sn =j:aܵ9U91fu2z5nWD1\ϖALf6<`v"iɄkV6Ӽah-fIxX_Az1@n{!dRWgT[1 9QڈU?J'<4Ѽ>73>`Bp!FST)yϦKyAIټ &%URb dNZڔ,L'o9x 7Un+G;~\Kwߴa&¸axQ> ЎƜ{?q)1 >wܷ ]!vȹrx-b{LPgge %+f HOH\ ס S!xerir{& ɝq2zl4_s yWřݜܳۍɋli?vfCߨK0|0WpުԸҫ Jq|'p/׍ĚOS!Γ0ܽ=hsOc#O,p7옓nǭ?55,9Ȝ* ELP+Vhqw)mG1}.ǩ m*J&'J {đLt?f##\y]xV7$wF&i[TتsػR2k &΂|\3?qpO݁>t?>ߞVrm!u)GL%%alZU0 VojT*19~#5׆:mY͐y%cԸ9^0bWX ب z"MܬlD S-򄐁8m=\,z^5&4[+2wpe4]ٍB`λKd$B9n>;`0-UTR<\S׷Nړ5qŕ;/4>n϶B.uⱹvd2f+ ] i𝇘jR V.ƍ2.\ktV FvG"֞Cs5H8ꔌika=&)%F}4#uxy3:ꐔY^f{=guRvÇkg=oc5 !6-FIǂ7,V?oaIr=; AatV xqRzw;P,`2¦G1{; 52K1PϠ/fTRPIښ1b 4Me -JGp᢮>/b9o3G ozjqqF枎eͣvDT, ;Q/HASql>=ŷ8TZ~4ÄϯYsr{|f6LncllͧC%uV ջ^e*h1Ir%M>נXq+ GT_ak$&]矱fZIxlRNp)]Kp6:ԜBB HFӱ33=6h}_ws F@ qi}s49*'dZ4\ VJS̩3y3Sv(̘ԔG |^[*xӐMܯ0\*u+s8Ƽp$)=F^ʬ)ܘ&,+e&veZR%1F/źt50!Y#F:S>ݙڊsgQvz'NQ״0]z">L M7?#{{P]Ka} \`agby5I93،Ylxюp{޿lˌVTQL-DYv~r r +Èޕ/F% ׬c pZ[54[%ȴҩyH] x\AaejI8QBLYZh˥K뀜WĔMPUؒÜhLiϒ@;:~U'c>=GL3c8yP+cW#lWM9 ߬D{C!+pf'TM膀kDاZKJ4^urC2]+v4gIK<|]'5hGDIbn"ZM 59Oq :{{9I2UjM1R_i*}El5//TbGg ]⭂7ʐ]R BG#b-Se*eM L[E*\ u -vwg5}[L*_GH`So߰) La3=& zY> Lˉ'~ṯ ? U 4OuQLY[g,,iS>?iX#kzrN 5ނAMIs;tZG 9N'_Ι?U޾ł [z,y0Y~LByV4m|P fAL?zu7R<O( t>Qʌo[q<+0f6'\*?P: dGL`m-6S.Spz97IhU7sQ(x ަ%äwJдb|qh,՘ݾ0}="L.Zجc`dNѤNh@G%3aھG"O=5APT[L6 s0u.r&`z.4_dc/:)b1cDx,bۅڼaKƜ{Z/e7a (0=%_aIW2Yޞù .uc0\+dL+bLT r4coUz4 '"$l+qXq%[&nGL}z7FRfHݎVV X]\Ep_)ں\WQ>2XhQC~sNO363j?C زچS{906eL]Yh4]1Z|-b17)m/NPc=B_8ĠmG̊٘n\M.?޸31ZFi-jsJ\TJK7`txDل+f+o`Z}+ᑝb[b&ijV31לLmBH* \OI-oc1Px!zYqy\ d}5s55lA|[?%Swe0 PW0mi+cwnt/Q͸F|>X4Iչʵ'UyT eFRtW* ?Y.eyU*q{rSa>Ռ&ÊvaGN[]dmΒi~&=^|MGmʮj<$RC2,yV@O'4La11$x2֎A;]0dm spX }XƧUyIS1AIdM(|_Ҏ|˔&psjt䫶rkoc Up*.Gq6߱!_˟Sb'}Ch  X\<;k19Q30K1e(oa>* .C?9 _a- -ZA{$o>~ W` %ݱ.rfMsUIu@Ƣ1PHO?M. ۫ՠ\I)7,+و-Sa%#XBnqjWM'ro [3aYrƽ:m:;OSgE㽮j`AUkΎOUӛpM 0i/X#v%_N/}k"^t#J,Q/ǷVI*|@#BQm40XGr}CnUz(g,oXE {>P)Lx,^C#xD͒<̀}: ?a}|kK(< 05E)(HǞIiXv'Ը=B3u8I^x?N;Ӎ(z >&{?寰z Dt,~oƀjt.[Ø= 1.=nSys*`!|S"Dz~l h\ \Rbo[M ֔arj(LF`#Rf'vvd?7yft fѧ'}SfeuN^?z=iy GFSm@M %}(ÆJtc}M+ON*Ӭ;T^a v2f8S*#L %u7b6/ѷk 6-.D|YNȵ$dZ JŸ^1ص >q_0Im#k8]Œ~w|O0m{{H-v]_j𞆄Mn j[ X ۆ{%v|k)u\[fEզf$=nqhpn|~x]*? wdgx>bFZ= Mb@ td܅E mZ_d(ԠKMWjQ?8{KSQඝѰ'= Ĥv/*̭qbfua_sR s[UNmĵ__5^ϞjQǀ5 ye2-%4 c{= RPɒ֜'WPyU/<5*6\^)hmhe|]UK߇(LeBΥZmoaR_Tl,l.¯Yxn@9U4}Y/KHoY+9{ƾ~💌?9iGhio:Vkmَ7ugLGԄCۆJ9d2/~ ˳pTƽa' ۞iذ3W"hp݆u(-]5W1o7m)=B UFaRM2[aZ8mJ%J=qq LBq'u vSA,rʣ=N\Q-10Sc¬R*V&fSzTF+1S1Eg#1V좰`5#p\6wi)/ڈp(b:̥l2IAW̙$ &h0/p.Rc5Rg U4&6 |Dw>6OB8z}hA=*갨GiR_C{nD# >oME+"]Be VfEU9tPj Fvޔ6@Dq ^ ?=L>:Ox mxV!?!PQ.)meLM2*8mҡ_ FWTe4*bkei80˷Emp?ܿmO70RMVƢ mZ&fe{1UGsz4WG$;pW;~ ǔL]FJ%ބk[Yi0Fq )݇0d qA7ra wzS6Y3D,hl<ѼVj*UaUN11pC>GS(W9Ѕ1UC5ycR4U{pr1m \]U҇ڶ zJ蝻nBOUJ4C$n7a.c_)xȘ&G҆{]בF6dh S~&-Veuf#6o@ٗt]bq-\Y:.|Ȫ)58m#e~Ts-}Z]jWNnCu rsu'JuHTeC0>~_j[1uUyM-fT9h~sn dđvu`\ٖ=/we1'q wFsg{7Fs!6LeȰbkU2<*sW#JO1Ṙ^2r|cEgjopZWΰwmvaBW>rB&鷅bJn0 OWc_\7"hu3mjfd]S$a XFо4̕ujo )Tf^-67Tة2lz] `-q`^++?̎A/TX|*Y&/-}~ #>`mgu6p |! +5 d\xtWϭ~x򟘌|<3t |<ł5~{0ӍC^J:,Fl 'P/ّ+1GϝsJY ]9m/_uf7Te 4qi#3M~|͙Ͼ8sVoхݘHcÀT\CRTzt^*㔡&͛hߓ 8 Ɖ_H%>Za`5fcK' hƸ"-jrk+prqLw4cafsƣKGaC+$g8^Ĩ4/6OƨY٧,0&j  |ѫO]JQn4ɿ~\_a>g:->N-*%P[5Ra#aDƠ?9&Ps ڱ9ۙ;{vg8G/vb_'v/rxZntpma/k0-&%e6ׄ3ؚ]xMG|14+Ύm<-M^ -d/OwrYS$ 'M✑޼چ8RŝM=y›v9CC"$gH A׼N C DŽPAN,lq p&;fw1eP?M>II.CSi& 0fBRM7U㤱2'mSeI)oeUCn7|k3}5XgЄjUXqJt>ġ*\u0^Rh ws'~\_kWS}{JТBj¦6`JlWuMxQˆ0K j2/\uU),pW^Tw羽k';z;{pv;-<]XrΉݘ_N|ˎg8sE 7'ѷĒ<9Z+^lŲL~цϷ垂6T5QOYξԉu榛Ȣ7{h mϥsw冣2~ ə1hJF̯f g޼Fzr0*Mr` ܐ"-/V+pB`IڔƄ hIFdWt]Jt=݈Uqyo!*.Oi,[&/n년Ìr34Untsgom矷hoUnul#-nj%{;TX@ebJx6GN7ߑF{߂OhvΕ<9)ٝ//5WUdWNy'm o0;#=Y2օ)Fօ;3؁j;3Gxr6\6w۶ooh!3϶^ڞQ.6l<4ڙ=9<97A^4͍W~I.^$/*ou~7OGp_ ,dv<859Ԉ߭lo9lp@-g~Ѵf]nH_j=\jЦp?H#3(1_ǫ2V~Ibvw\Ezܓo̝"cbjj9%xN1>+ߞVkqV]XULtH=hrׅA}ϝWۺr;z1ڋfڢv oóiͬۆ#-di6s7FL`nŪEscn#rm?OxzMn\̃6ܡ'"=,7}9ڰ_##x+ˑV\yz30ocU8"T̩n 2{butSb[Ѵ%iWpzei[1r(Q߀o~B0-U|~N(n8ܿ9V?*7chG\R׈zY_ 'fy0]DNȀ4h8BlS.ո>@p3s?pT-{pKHZw .!@ $N<ēs{{ukaJա;]{WVHы!كeǮ|hM(ܿ`ݳ2$LSag M!Ea5P~$Yʃ07_VPer|T u`X'"xy:JPhz;3f܀s~C3v7=}<݇*a z6 ;zzqb~?66[~]U'ֺc*7ۖrA|tH:8cªQJ=޹gVv;uL)>LÈ\ sK(ړԔZ;:rg-]yJsɋx=|79WўAg9n%K}N(SbRtO?߰d쟄Y4'NL I ZVGD">!BP36SgjFiS {+RF~ 5}A({?GtkUya+K*СO);AOlvtzi1}9ߟ5ݮw^l%ۛ#x3יxă3:֓)|ˉ|;Ο9ʏ %AX wN \mÆ8 g؟XaM#-DxDB,V J\fb23W.:}fܖg>,%yїӼyL6t Ϧ '0udߕ.+̓m}ޅ?]٦ sٮnc*k8ڹ~*Tx>ü[*WaE4$ȁUQ ,M'rF6 Qk~@4o?je[3-cex n^ {Y'z?xBcB!ʃ_eٝ1GKAwXڋwMR6SK/z$zp<$HY"sOycr=YB4LJ.̽س& =,b}/fu KQ+ŽGnLy+6fr fagwntƸ^Ї/4%<'<'w ^ e.9Ho;MG93Xˁc9<#tuT{ncelu-ِ͙z\TkwQ~o}>i mX._w}v`7>%б|W0o)\UG9 =/~$lCJyf];U8r};wn˓KMyk/!'ol<\~4R-mp6qopa;7,:V[{ [t. g;V3:Nm F[1N0Nb)ǻt3`HζkT|БKNy/N^ŵ1nbə͛5:lߕJ^tz+NL>G\)YwuNk:E9ci-(':q`g vbX#uw`:u6tSʜTT,zGYY9d=j nN(ʚʰuLF/ ՘O )G_!)m\|3.DjoYQ+%,y ˓4ӕL/v{%,܋RD7p{h/Tz1E#-(CnaάV~Ɋ4 \]k۴90fê+8 kV≎.N3`˥ˀ f tauwxrgWy?ҫnō {ԗw'>|8X©<TyN m u%,[{q|?K <Owm.uz(FUufuTU7g36%ˠ[kH-q73`=82g(6q:t `H!3ٙN#a/?D:{#v7;wqg[^1E8i3G~mp1ҍkq\1Ӂs&sk;&XY%gڱne|`yo 7KYĉE(pwAYSP<Vh6:2 !s9XAFyjVFW͒Lm?g}whykS_/t!qpW OxPug +_3U&w0~L6cD1m'?E!xea.?f`TE1kN6Sq]: ah2ۼ4V4oxy_ùޔ{ [iUK7ĩgVmqfkk>,Y)lLlpHVqdek'|bG]6ҌakM̌-jmxd]i6>Â} WS̘)JV)Q:}Ck xeUZhifFƋhw/}L-(Vx$Q0547Z[޷Տ?r_'LO=U9rjuOڹx 0/;gGtٮ6t7W7^*q2N*Ӧ s 4~> YטRTluÞbdt9iP9Ny?@h#>^L}#/\r{WbdƏNoΪwgwH8#ɉ#K%S9|=[tbF90`#;;BŞ; it߆LhƐ1Rcne5f̓)}8[ԹFf&n̍RE˔pRwU9;U;|RE\Fݓ5y[M1RUQfӰ>[9-cp^2j|Gb"nr4}GYxݛpv]9׍٪֝u]9;wc.7Nnӄd/t5?fǴr'(s'p 'vq_8x# GO+4*E&[6_*,̴=*L?Έ ZUmh4O~'n95&=ÀXWѭc=ӇVg67XQ*igfra٭g{0Y۾06Ǚ:Q;zKL9VtϒO<œ5*5:DŽQW{XcgSL}_A7W?Bx|g*<˿cqZ34dF/ޟ5Fj? YH,Sk¦lgJ=hC p/'lbyn?^MZ <ؓhχy%?ћZPmdONC'fUW*5pRAmkEUs=6"xS 2*zF {pr5GUT(>·1XoPu͒4ltsf|҉{۸;_&zqS'r/aҩT ,E˽UxQ[g̩ڋ*>7?f;wuݧ; p?6 $aT%(s/Z1y+5|ևG&wv`ɝhEVU*\[;k&CgjzӀxMvMu#OY/Uop̬nmUS(ur2as n#הu(DݏL,Tl<7l3'>wK3󠿋gzӃsmX 5xTU4l kd&KGS߰b,$|;&q,M,lؕ~@7|ebހTewZP{* KPF9ԅkN#;rb='c!;}fε\9 }Z/}NB y5p)9;id(ZyʜOKø쭢oP=FW(>/1gK[琦QiiS7& FLrS\7mv2V e)%3Ve*=BZ<Ռ <݃8ȝG{ZM74_S}05{`Q" t|Agn|p6/}i6^ +м&O6O#.6meu8.;QfBViRTa&'F4Hrs#7y~/íÊ:r_;O8vgdɱtW&ã!%oPvBWGTxs;v|KsFWbذ:"S]URm%[&rN(_cF'Ջ!+N@ cl98ւKg@n+sW*x#p6+Tr24`LW2c\[JIwbWGz1w:)%{xQGԩY/"sT1JF,h(zP̗Xzt|`:i9 iť\|C?4¡E9TM)371"\=[ Ũ㓄GEEOs=у81t )qB|-yʐO&S|[_J)0M"VL1fCbuۛh6,nAN^w0+uH7붎sscNܬKׅ_CnE$tQLj&.Jr4\s˃_:IS}((+o姾 q4Ò!M:Ā;hh}ո"OJq1 *!Xc*C=)?cE2O 3ϒ@9˕XWd ֙-׸q'Jq[ EG)!n`[E&E͠$OUqWXW*:8NӖcǙ20ѐѪA+p.CN/gau.X׈Kʐ:4ope i [{/:{M) .Ӳ0$/& n1V@h(g/ %3%\^jUj,=;S9a+u)^𦟓/?4bgT2< ޣDp\W`˧u33pU 73YKE-} ^ka5Bu|Ϙk3}\8߅8F a>[h|H--D\\l &],MG|ײ2QaE+ 2cSf EQhZ e > ]d-n?V`szVј|}aһHhF`ޘۘ Vs>H U8i)ΊrTV֢"1X}̌n,w 꽙y<ӎxomJ_h:Sw-*yf| smG?}Ty&qP#vmlun=qGECfk`o\ri̕i4Ɗu"s*w.uKqtR)Y:w$ⅼm>2C3 LVgJl~[@$w|N<il2l٪4Y \6˒=)pU/Fޭ9~(E)0R A'#8s{+s^Ͷ9g)1čU+Ne6]UY08c.8Ud 0**}=#V" *\Tw5W;2#G:d#(u/S^(eCen>Q;Wcp${χbT{Vn˳@iP_ċ*1fVÒFYǀ̛\<`x 5z­iOOA8-#(kMPF[A;hqX86GM ?㓡?z"\/Pd|o}/ 8x+P'̩ё#x2Λe8sFu+J"6[DQ+)#5 <=hRD7٬΃٥t ƫn]\1YKnv;ޞ@>vL:lUxjU:p;| Gj#Ql.5(ԪEЛR+hy#/fU"X[,v-5t7ƫW,>UAwSپNS[Yϟ = Bbcm΂jϾÛc0Qm?U>fl5p_[ Rvgmo0gwG f}.xNJZq*v@y ҟѲ]uѰ4V 1oGҔչQdx9qFWp$" Ukޡ~9z..@o.B|կ S!^_`Ubl%xuؤQE+Ѯc~t}:{njs%O_~4fGV ٍn!mzv/c|(̸+Vb257W=9V'W@mSwjQÔ{LǝNhN|ki&aX_.0%}j,p@/(X a~3/3eL˅GEp ʴbs%ot r(퐲Mvb4C(]Ҷ iz|8SAo*