[
  {
    "path": ".claude/settings.local.json",
    "content": "{\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(cmake:*)\"\n    ]\n  }\n}\n"
  },
  {
    "path": ".gitattributes",
    "content": "## Prevent Git from affecting line endings\n\n\n## GRAPHICS\n*.psd  binary\n*.ppm  binary\n*.pbm  binary"
  },
  {
    "path": ".github/workflows/benchmarks.yml",
    "content": "name: Performance Benchmarks\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\npermissions:\n  contents: write\n  pull-requests: write\n\njobs:\n  benchmark:\n    runs-on: ${{ matrix.os }}\n\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu-latest, windows-latest, macos-latest]\n        include:\n          - os: ubuntu-latest\n            platform: Linux\n            bench_exe: ./build-bench/Doxa.Bench/doxa_bench\n          - os: windows-latest\n            platform: Windows\n            bench_exe: ./build-bench/Doxa.Bench/Release/doxa_bench.exe\n          - os: macos-latest\n            platform: macOS\n            bench_exe: ./build-bench/Doxa.Bench/doxa_bench\n\n    steps:\n    - uses: actions/checkout@v4\n\n    - name: Configure CMake\n      run: cmake --preset benchmarks\n\n    - name: Build\n      run: cmake --build build-bench --config Release\n\n    - name: Run Benchmarks\n      run: ${{ matrix.bench_exe }}\n           --benchmark_out=benchmark_results.json\n           --benchmark_out_format=json\n           --benchmark_min_time=1s\n           --benchmark_repetitions=5\n           --benchmark_report_aggregates_only=true\n\n    - name: Upload Benchmark Results\n      uses: actions/upload-artifact@v4\n      with:\n        name: benchmark-results-${{ matrix.platform }}\n        path: benchmark_results.json\n\n    - name: Store Benchmark Results\n      uses: benchmark-action/github-action-benchmark@v1\n      with:\n        tool: 'googlecpp'\n        output-file-path: benchmark_results.json\n        # Each platform gets its own independent dataset and history\n        name: 'Doxa Benchmarks (${{ matrix.platform }})'\n        github-token: ${{ secrets.GITHUB_TOKEN }}\n        # Store history in gh-pages branch (only on push to master)\n        auto-push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}\n        # Alert on PRs if perf regresses beyond threshold\n        alert-threshold: '120%'\n        comment-on-alert: true\n        fail-on-alert: false\n"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: Publish to npm\n\npermissions:\n  contents: read\n\n# Disabled: NPM_TOKEN secret not yet configured.\n# Re-enable by uncommenting the release trigger below.\non:\n  # release:\n  #   types: [published]\n  workflow_dispatch: # manual trigger only for now\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          registry-url: 'https://registry.npmjs.org'\n\n      - name: Setup Emscripten\n        uses: mymindstorm/setup-emsdk@v14\n\n      - name: Install dependencies\n        working-directory: ./Bindings/WebAssembly\n        run: npm install\n\n      - name: Build WASM\n        working-directory: ./Bindings/WebAssembly\n        run: npm run build\n\n      - name: Run tests\n        working-directory: ./Bindings/WebAssembly\n        run: npm test\n\n      - name: Publish to npm\n        working-directory: ./Bindings/WebAssembly\n        run: npm publish --access public\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/pythonpackage.yml",
    "content": "name: Python Package\n\non:\n  release:\n    types:\n      - published\n\njobs:\n  build_sdist:\n    name: Build SDist\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: ./Bindings/Python\n    steps:\n    - uses: actions/checkout@v4\n      with:\n        submodules: true\n\n    - name: Build SDist\n      run: |\n        python copy-cpp-files.py\n        pipx run build --sdist\n\n    - name: Check metadata\n      run: pipx run twine check dist/*\n\n    - uses: actions/upload-artifact@v4\n      with:\n        name: dist-sdist\n        path: Bindings/Python/dist/*.tar.gz\n\n\n  build_wheels:\n    name: Build Wheels\n    runs-on: ${{ matrix.os }}\n    defaults:\n      run:\n        working-directory: ./Bindings/Python\n\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu-latest, macos-latest, windows-latest]\n\n    steps:\n    - uses: actions/setup-python@v5\n    - uses: actions/checkout@v4\n      with:\n        submodules: true\n\n    - name: Build setup\n      run: |\n        python copy-cpp-files.py\n        pip install -r requirements.txt\n        python -m pip install cibuildwheel==2.22.0\n\n    - name: Build wheels\n      run: python -m cibuildwheel --output-dir wheelhouse\n\n    - name: Upload wheels\n      uses: actions/upload-artifact@v4\n      with:\n        path: Bindings/Python/wheelhouse/*.whl\n        name: dist-${{ matrix.os }}\n\n  upload_all:\n    name: Upload to PyPi\n    needs: [build_wheels, build_sdist]\n    runs-on: ubuntu-latest\n    if: github.event_name == 'release' && github.event.action == 'published'\n\n    steps:\n    - uses: actions/setup-python@v5\n    - uses: actions/download-artifact@v4\n      with:\n        path: dist\n        pattern: dist-*\n        merge-multiple: true\n\n    - uses: pypa/gh-action-pypi-publish@release/v1\n      with:\n        user: __token__\n        password: ${{ secrets.pypi_password }}\n"
  },
  {
    "path": ".github/workflows/test-and-coverage.yml",
    "content": "# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.\n# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml\nname: Build and Test with Coverage\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n\n    strategy:\n      # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.\n      fail-fast: false\n\n      # Set up a matrix to run the following 3 configurations:\n      # 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>\n      # 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>\n      # 3. <macOS, Release, latest Clang compiler toolchain on the default runner image, default generator>\n      #\n      # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.\n      matrix:\n        os: [ubuntu-latest, windows-latest, macos-latest]\n        build_type: [Debug]  # Changed to Debug for better coverage\n        c_compiler: [gcc, clang, cl]\n        include:\n          - os: windows-latest\n            c_compiler: cl\n            cpp_compiler: cl\n          - os: ubuntu-latest\n            c_compiler: gcc\n            cpp_compiler: g++\n          - os: macos-latest\n            c_compiler: clang\n            cpp_compiler: clang++\n        exclude:\n          - os: windows-latest\n            c_compiler: gcc\n          - os: windows-latest\n            c_compiler: clang\n          - os: ubuntu-latest\n            c_compiler: cl\n          - os: ubuntu-latest\n            c_compiler: clang\n          - os: macos-latest\n            c_compiler: gcc\n          - os: macos-latest\n            c_compiler: cl\n\n    steps:\n    - uses: actions/checkout@v4\n\n    - name: Set reusable strings\n      # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.\n      id: strings\n      shell: bash\n      run: |\n        echo \"build-output-dir=${{ github.workspace }}/build\" >> \"$GITHUB_OUTPUT\"\n\n    - name: Install dependencies (Ubuntu)\n      if: runner.os == 'Linux'\n      run: |\n        sudo apt-get update\n        sudo apt-get install -y cmake\n        pipx install gcovr\n\n    - name: Install dependencies (macOS)\n      if: runner.os == 'macOS'\n      run: |\n        brew install cmake\n\n    - name: Configure CMake\n      # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.\n      # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type\n      run: >\n        cmake -B ${{ steps.strings.outputs.build-output-dir }}\n        -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}\n        -DCMAKE_C_COMPILER=${{ matrix.c_compiler }}\n        -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}\n        -DCMAKE_CXX_FLAGS=\"${{ runner.os == 'Linux' && '-fprofile-arcs -ftest-coverage' || '' }}\"\n        -DCMAKE_C_FLAGS=\"${{ runner.os == 'Linux' && '-fprofile-arcs -ftest-coverage' || '' }}\"\n        -S ${{ github.workspace }}/Doxa.Test\n\n    - name: Build\n      # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).\n      run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}\n\n    - name: Test\n      working-directory: ${{ steps.strings.outputs.build-output-dir }}\n      # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).\n      # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail\n      run: ctest --build-config ${{ matrix.build_type }} --output-on-failure\n\n    - name: Generate Coverage Report\n      if: runner.os == 'Linux'\n      working-directory: ${{ steps.strings.outputs.build-output-dir }}\n      run: |\n        # Use gcovr to generate XML coverage report for GCC\n        # Filter to only the core library headers - exclude test files and build artifacts\n        gcovr --xml --xml-pretty --gcov-ignore-parse-errors=suspicious_hits.warn --root .. --filter '../Doxa/' > coverage.xml\n\n    - name: Upload Coverage Report\n      if: runner.os == 'Linux'\n      uses: codecov/codecov-action@v3\n      with:\n        file: ${{ steps.strings.outputs.build-output-dir }}/coverage.xml\n        fail_ci_if_error: false\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\nbuild/\nbuild-cpp-tests/\nbuild-python/\nbuild-wasm/\nbuild-matlab/\nbuild-bench/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/Algorithms.m",
    "content": "classdef Algorithms\n    %ALGORITHMS Binarization algorithms available in the Doxa framework.\n    %\n    %   Global Thresholding:\n    %       Doxa.Algorithms.OTSU\n    %\n    %   Local Adaptive Thresholding:\n    %       Doxa.Algorithms.BERNSEN, NIBLACK, SAUVOLA, WOLF, NICK, SU,\n    %       TRSINGH, BATAINEH, PHANSALKAR, ISAUVOLA, WAN, GATOS, ADOTSU\n    %\n    %   See also Doxa.binarize\n\n    enumeration\n        OTSU\n        BERNSEN\n        NIBLACK\n        SAUVOLA\n        WOLF\n        NICK\n        SU\n        TRSINGH\n        BATAINEH\n        PHANSALKAR\n        ISAUVOLA\n        WAN\n        GATOS\n        ADOTSU\n    end\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/Grayscale.m",
    "content": "classdef Grayscale\n    %GRAYSCALE Grayscale conversion algorithms available in the Doxa framework.\n    %\n    %   Algorithms:\n    %       Doxa.Grayscale.MEAN      - Mean of R, G, B (Gleam/Intensity)\n    %       Doxa.Grayscale.QT        - Qt framework formula (default)\n    %       Doxa.Grayscale.BT601     - ITU-R BT.601 (NTSC)\n    %       Doxa.Grayscale.BT709     - ITU-R BT.709 (sRGB)\n    %       Doxa.Grayscale.BT2100    - ITU-R BT.2100\n    %       Doxa.Grayscale.VALUE     - HSV Value (max channel)\n    %       Doxa.Grayscale.LUSTER    - HLS Lightness\n    %       Doxa.Grayscale.LIGHTNESS - CIELAB/CIELUV Lightness\n    %       Doxa.Grayscale.MINAVG    - Min-Average (for multi-color text)\n    %       Doxa.Grayscale.LABDIST   - L*a*b* Euclidean Distance (used by Phansalkar)\n    %\n    %   See also Doxa.Image\n\n    enumeration\n        MEAN\n        QT\n        BT601\n        BT709\n        BT2100\n        VALUE\n        LUSTER\n        LIGHTNESS\n        MINAVG\n        LABDIST\n    end\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/Image.m",
    "content": "classdef Image < handle\n    %IMAGE Doxa image container wrapping a C++ Doxa::Image.\n    %   Handles the column-major (Matlab) to row-major (C++) memory layout\n    %   conversion at construction and extraction boundaries.\n    %\n    %   Construction:\n    %       img = Doxa.Image('file.ppm')                     % from file\n    %       img = Doxa.Image('file.ppm', Doxa.Grayscale.QT)  % from color file\n    %       img = Doxa.Image(gray_uint8)                      % from 2D uint8\n    %       img = Doxa.Image(rgb_uint8)                       % from 3D, default grayscale\n    %       img = Doxa.Image(rgb_uint8, Doxa.Grayscale.QT)    % from 3D, specific algorithm\n    %\n    %   Methods:\n    %       arr = img.toArray()   % convert back to Matlab uint8 matrix\n    %       disp(img)             % display dimensions\n    %\n    %   See also Doxa.Grayscale, Doxa.binarize\n\n    properties (Access = {?Doxa.Image})\n        Handle uint64 = uint64(0)\n    end\n\n    methods\n        function obj = Image(input, algorithm)\n            %IMAGE Construct a Doxa.Image from a file path, 2D, or 3D uint8 array.\n\n            if nargin == 0\n                % Internal: empty construction for fromHandle factory\n                return;\n            end\n\n            % Load from file if given a path\n            if ischar(input) || isstring(input)\n                input = imread(input);\n                % imread returns logical for PBM; scale to 0/255\n                if islogical(input)\n                    input = uint8(input) * 255;\n                end\n                input = uint8(input);\n            end\n\n            if ~isa(input, 'uint8')\n                error('Doxa:Image:InvalidInput', 'Input must be uint8.');\n            end\n\n            if ndims(input) == 3\n                % Color image: convert to grayscale\n                if nargin < 2\n                    algorithm = Doxa.Grayscale.MEAN;\n                end\n                obj.Handle = image_mex('from_grayscale', char(algorithm), input);\n            elseif ismatrix(input)\n                % 2D grayscale or binary\n                obj.Handle = image_mex('create', input);\n            else\n                error('Doxa:Image:InvalidInput', 'Input must be a 2D or 3D uint8 array.');\n            end\n        end\n\n        function arr = toArray(obj)\n            %TOARRAY Convert back to a Matlab uint8 matrix.\n            %   arr = img.toArray()\n            obj.checkValid();\n            arr = image_mex('to_array', obj.Handle);\n        end\n\n        function w = width(obj)\n            %WIDTH Image width in pixels.\n            obj.checkValid();\n            w = image_mex('width', obj.Handle);\n        end\n\n        function h = height(obj)\n            %HEIGHT Image height in pixels.\n            obj.checkValid();\n            h = image_mex('height', obj.Handle);\n        end\n\n        function disp(obj)\n            %DISP Display Doxa.Image summary.\n            if obj.Handle == uint64(0)\n                fprintf('  Doxa.Image: [empty]\\n');\n            else\n                fprintf('  Doxa.Image: %dx%d uint8\\n', obj.width(), obj.height());\n            end\n        end\n\n        function delete(obj)\n            %DELETE Free the underlying C++ image memory.\n            if obj.Handle ~= uint64(0)\n                image_mex('destroy', obj.Handle);\n                obj.Handle = uint64(0);\n            end\n        end\n    end\n\n    methods (Hidden)\n        function h = getHandle(obj)\n            %GETHANDLE Return the raw uint64 handle for MEX interop.\n            obj.checkValid();\n            h = obj.Handle;\n        end\n    end\n\n    methods (Static, Hidden)\n        function obj = fromHandle(handle)\n            %FROMHANDLE Wrap an existing C++ image pointer without re-transposing.\n            obj = Doxa.Image();\n            obj.Handle = handle;\n        end\n    end\n\n    methods (Access = private)\n        function checkValid(obj)\n            if obj.Handle == uint64(0)\n                error('Doxa:Image:InvalidHandle', 'Image has been destroyed or is uninitialized.');\n            end\n        end\n    end\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/binarize.m",
    "content": "function outputImage = binarize(algorithm, inputImage, options)\n%BINARIZE Convert a grayscale Doxa.Image to binary.\n%   binary = Doxa.binarize(Doxa.Algorithms.SAUVOLA, img)\n%   binary = Doxa.binarize(Doxa.Algorithms.SAUVOLA, img, window=75, k=0.2)\n%\n%   Common parameters (defaults vary by algorithm):\n%       window        - Local window size in pixels (default: 75)\n%       k             - Sensitivity parameter (default: 0.2)\n%\n%   Algorithm-specific parameters:\n%       threshold     - Bernsen: global threshold (default: 100)\n%       contrastLimit - Bernsen: contrast limit (default: 25)\n%       R             - AdOtsu: range parameter (default: 0.1)\n%       distance      - AdOtsu: grid distance (default: window/2)\n%       minN          - Su: minimum neighborhood (default: window)\n%       glyph         - Gatos: estimated stroke width (default: 60)\n%\n%   See also Doxa.Algorithms, Doxa.updateToBinary, Doxa.Image\n\n    arguments\n        algorithm Doxa.Algorithms\n        inputImage Doxa.Image\n        options.window = []\n        options.k = []\n        options.threshold = []\n        options.contrastLimit = []\n        options.R = []\n        options.distance = []\n        options.minN = []\n        options.glyph = []\n    end\n\n    params = Doxa.buildParams(options);\n    handle = binarize_mex(char(algorithm), inputImage.getHandle(), params);\n    outputImage = Doxa.Image.fromHandle(handle);\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/buildParams.m",
    "content": "function params = buildParams(options)\n%BUILDPARAMS Convert name-value options to a parameter struct for MEX.\n%   Internal utility. Strips empty fields before passing to the MEX layer.\n\n    params = struct();\n    fields = fieldnames(options);\n    for i = 1:numel(fields)\n        value = options.(fields{i});\n        if ~isempty(value)\n            params.(fields{i}) = value;\n        end\n    end\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/calculatePerformance.m",
    "content": "function metrics = calculatePerformance(gtImage, binaryImage, options)\n%CALCULATEPERFORMANCE Calculate binarization quality metrics.\n%   metrics = Doxa.calculatePerformance(gt, binary)\n%   metrics = Doxa.calculatePerformance(gt, binary, precisionWeights=pw, recallWeights=rw)\n%\n%   Returns a struct with all standard metrics:\n%       accuracy, fm, recall, precision, psnr, nrm, mcc, drdm\n%\n%   When precisionWeights and recallWeights are provided, pseudo-metrics\n%   are also included: pseudoFM, pseudoPrecision, pseudoRecall\n%\n%   See also Doxa.Image, Doxa.readWeights\n\n    arguments\n        gtImage Doxa.Image\n        binaryImage Doxa.Image\n        options.precisionWeights double = []\n        options.recallWeights double = []\n    end\n\n    metrics = calculate_performance_mex( ...\n        gtImage.getHandle(), binaryImage.getHandle(), ...\n        options.precisionWeights, options.recallWeights);\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/readWeights.m",
    "content": "function weights = readWeights(filePath)\n%READWEIGHTS Load a DIBCO-format weight file for pseudo-metrics.\n%   pw = Doxa.readWeights('precision_weights.dat')\n%   rw = Doxa.readWeights('recall_weights.dat')\n%\n%   Returns a double column vector of weights.\n%\n%   See also Doxa.calculatePerformance\n\n    arguments\n        filePath {mustBeTextScalar, mustBeFile}\n    end\n\n    fid = fopen(filePath, 'r');\n    weights = fscanf(fid, '%f');\n    fclose(fid);\nend\n"
  },
  {
    "path": "Bindings/Matlab/+Doxa/updateToBinary.m",
    "content": "function updateToBinary(algorithm, inputImage, options)\n%UPDATETOBINARY Binarize a Doxa.Image in-place.\n%   Doxa.updateToBinary(Doxa.Algorithms.SAUVOLA, img)\n%   Doxa.updateToBinary(Doxa.Algorithms.SAUVOLA, img, window=75, k=0.2)\n%\n%   Modifies the Doxa.Image directly. No new image is created.\n%   See Doxa.binarize for available parameters.\n%\n%   See also Doxa.Algorithms, Doxa.binarize, Doxa.Image\n\n    arguments\n        algorithm Doxa.Algorithms\n        inputImage Doxa.Image\n        options.window = []\n        options.k = []\n        options.threshold = []\n        options.contrastLimit = []\n        options.R = []\n        options.distance = []\n        options.minN = []\n        options.glyph = []\n    end\n\n    params = Doxa.buildParams(options);\n    update_to_binary_mex(char(algorithm), inputImage.getHandle(), params);\nend\n"
  },
  {
    "path": "Bindings/Matlab/BinarizeMex.cpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#include \"mex.h\"\n#include \"DoxaMexUtils.hpp\"\n\n/// <summary>\n/// MEX function to create a new binarized image from a Doxa.Image handle.\n/// Matlab Signature: handle = binarize_mex(algorithm_name, image_handle, params_struct)\n/// </summary>\nvoid mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])\n{\n    if (nrhs < 2 || nrhs > 3) {\n        mexErrMsgIdAndTxt(\"Doxa:binarize:InvalidInput\", \"Usage: binarize_mex(algorithm, image_handle, params_struct)\");\n    }\n\n    // 1. Get Algorithm Enum\n    std::string algorithmStr = mxArrayToString(prhs[0]);\n    Doxa::Algorithms algorithmEnum = DoxaMexUtils::StringToAlgorithmEnum(algorithmStr);\n\n    // 2. Get Input Image from handle\n    Doxa::Image* grayImage = DoxaMexUtils::HandleToImage(prhs[1]);\n\n    // 3. Get Parameters\n    const mxArray* paramsMx = (nrhs == 3) ? prhs[2] : nullptr;\n    Doxa::Parameters params = DoxaMexUtils::MxStructToParameters(paramsMx);\n\n    // 4. Create output image and run algorithm\n    Doxa::Image* binaryImage = new Doxa::Image(grayImage->width, grayImage->height);\n    Doxa::IAlgorithm* algorithm = Doxa::BinarizationFactory::Algorithm(algorithmEnum);\n    algorithm->Initialize(*grayImage);\n    algorithm->ToBinary(*binaryImage, params);\n    delete algorithm;\n\n    // 5. Return handle to the new binary image\n    plhs[0] = DoxaMexUtils::ImageToHandle(binaryImage);\n}\n"
  },
  {
    "path": "Bindings/Matlab/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(DoxaMatlab)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Find MATLAB and its components\nfind_package(Matlab COMPONENTS MAIN_PROGRAM)\n\n# Include the root Doxa directory for header files\ninclude_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)\n\n# Define output directory for MEX files and Matlab sources\nset(MEX_OUTPUT_DIR ${CMAKE_BINARY_DIR}/mex)\nfile(MAKE_DIRECTORY ${MEX_OUTPUT_DIR})\n\n# Add each MEX file as a separate target\nmatlab_add_mex(NAME image_mex SRC ImageMex.cpp)\nmatlab_add_mex(NAME binarize_mex SRC BinarizeMex.cpp)\nmatlab_add_mex(NAME update_to_binary_mex SRC UpdateToBinaryMex.cpp)\nmatlab_add_mex(NAME calculate_performance_mex SRC CalculatePerformanceMex.cpp)\n\n# All MEX targets\nset(MEX_TARGETS image_mex binarize_mex update_to_binary_mex calculate_performance_mex)\n\n# Set output directory for all MEX targets\nset_property(TARGET ${MEX_TARGETS} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${MEX_OUTPUT_DIR})\n\n# SIMD optimizations\noption(DOXA_ENABLE_SIMD \"Enable SIMD optimizations\" ON)\nif(DOXA_ENABLE_SIMD)\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64|AMD64|x64\")\n        if(NOT MSVC)\n            foreach(target ${MEX_TARGETS})\n                target_compile_options(${target} PRIVATE -msse2)\n            endforeach()\n        endif()\n    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|ARM64\")\n        # ARM64: NEON is enabled by default\n    endif()\nendif()\n\n# Copy test files to the build directory (for CTest)\nfile(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test/TestDoxa.m DESTINATION ${MEX_OUTPUT_DIR})\n\n# Copy +Doxa package alongside the MEX files.\n# TARGET_FILE_DIR resolves to the correct output directory on both\n# single-config (mex/) and multi-config (mex/Release/) generators.\nadd_custom_command(TARGET image_mex POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E copy_directory\n        ${CMAKE_CURRENT_SOURCE_DIR}/+Doxa\n        $<TARGET_FILE_DIR:image_mex>/+Doxa\n)\n\n# Enable testing and add the MATLAB tests to CTest\nenable_testing()\nmatlab_add_unit_test(\n    NAME MatlabTests\n    UNITTEST_FILE ${MEX_OUTPUT_DIR}/TestDoxa.m\n    ADDITIONAL_PATH ${MEX_OUTPUT_DIR}/$<CONFIG>\n)\n"
  },
  {
    "path": "Bindings/Matlab/CalculatePerformanceMex.cpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#include \"mex.h\"\n#include \"DoxaMexUtils.hpp\"\n\n/// <summary>\n/// MEX function to calculate performance metrics between two Doxa.Image handles.\n///\n/// Signatures:\n///   metrics = calculate_performance_mex(gt_handle, bin_handle)\n///   metrics = calculate_performance_mex(gt_handle, bin_handle, p_weights, r_weights)\n/// </summary>\nvoid mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])\n{\n    if (nrhs != 2 && nrhs != 4) {\n        mexErrMsgIdAndTxt(\"Doxa:calculatePerformance:InvalidInput\",\n            \"Usage: calculate_performance_mex(gt_handle, bin_handle, [p_weights, r_weights])\");\n    }\n\n    // 1. Get Images from handles\n    Doxa::Image* groundTruthImage = DoxaMexUtils::HandleToImage(prhs[0]);\n    Doxa::Image* binaryImage = DoxaMexUtils::HandleToImage(prhs[1]);\n\n    if (groundTruthImage->width != binaryImage->width || groundTruthImage->height != binaryImage->height) {\n        mexErrMsgIdAndTxt(\"Doxa:calculatePerformance:MismatchedDimensions\",\n            \"Input images must have the same dimensions.\");\n    }\n\n    // 2. Compute classifications (with or without pseudo-weights)\n    Doxa::ClassifiedPerformance::Classifications classifications;\n    bool hasPseudoWeights = false;\n\n    if (nrhs == 4 && !mxIsEmpty(prhs[2]) && !mxIsEmpty(prhs[3])) {\n        std::vector<double> precisionWeights = DoxaMexUtils::MxArrayToDoubleVector(prhs[2]);\n        std::vector<double> recallWeights = DoxaMexUtils::MxArrayToDoubleVector(prhs[3]);\n\n        Doxa::ClassifiedPerformance::CompareImages(\n            classifications, *groundTruthImage, *binaryImage, precisionWeights, recallWeights);\n        hasPseudoWeights = true;\n    } else {\n        Doxa::ClassifiedPerformance::CompareImages(\n            classifications, *groundTruthImage, *binaryImage);\n    }\n\n    // 3. Build output struct with all metrics\n    int numFields = hasPseudoWeights ? 11 : 8;\n    const char* fieldNames[] = {\n        \"accuracy\", \"fm\", \"recall\", \"precision\", \"psnr\", \"nrm\", \"mcc\", \"drdm\",\n        \"pseudoFM\", \"pseudoPrecision\", \"pseudoRecall\"\n    };\n\n    plhs[0] = mxCreateStructMatrix(1, 1, numFields, fieldNames);\n\n    mxSetField(plhs[0], 0, \"accuracy\",  mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculateAccuracy(classifications)));\n    mxSetField(plhs[0], 0, \"fm\",        mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculateFMeasure(classifications)));\n    mxSetField(plhs[0], 0, \"recall\",    mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculateRecall(classifications)));\n    mxSetField(plhs[0], 0, \"precision\", mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculatePrecision(classifications)));\n    mxSetField(plhs[0], 0, \"psnr\",      mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculatePSNR(classifications)));\n    mxSetField(plhs[0], 0, \"nrm\",       mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculateNRM(classifications)));\n    mxSetField(plhs[0], 0, \"mcc\",       mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculateMCC(classifications)));\n    mxSetField(plhs[0], 0, \"drdm\",      mxCreateDoubleScalar(Doxa::DRDM::CalculateDRDM(*groundTruthImage, *binaryImage)));\n\n    if (hasPseudoWeights) {\n        mxSetField(plhs[0], 0, \"pseudoFM\",        mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculatePseudoFMeasure(classifications)));\n        mxSetField(plhs[0], 0, \"pseudoPrecision\",  mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculatePseudoPrecision(classifications)));\n        mxSetField(plhs[0], 0, \"pseudoRecall\",     mxCreateDoubleScalar(Doxa::ClassifiedPerformance::CalculatePseudoRecall(classifications)));\n    }\n}\n"
  },
  {
    "path": "Bindings/Matlab/Doxa.prj",
    "content": "<deployment-project plugin=\"plugin.toolbox\" plugin-version=\"1.0\">\n  <configuration file=\"${PROJECT_ROOT}\\Doxa.prj\" location=\"${PROJECT_ROOT}\" name=\"Doxa\" target=\"target.toolbox\" target-name=\"Package Toolbox\">\n    <param.appname>Doxa</param.appname>\n    <param.authnamewatermark>Brandon M. Petty</param.authnamewatermark>\n    <param.email>brandonpetty1981@gmail.com/param.email>\n    <param.company />\n    <param.summary>Fast, header-only C++ image binarization framework with MATLAB bindings</param.summary>\n    <param.description>Doxa is an image binarization library focusing on local adaptive thresholding algorithms. It provides 13 binarization algorithms including Sauvola, Niblack, Wolf, and others, with performance metrics (Pseudo F-Measure, PSNR, DRDM) and grayscale conversion options.</param.description>\n    <param.screenshot>${PROJECT_ROOT}\\..\\..\\Demo\\2JohnC1V3.png</param.screenshot>\n    <param.version>1.0.0</param.version>\n    <param.output>${PROJECT_ROOT}\\Doxa.mltbx</param.output>\n    <param.products.name />\n    <param.products.id />\n    <param.products.version />\n    <param.platforms />\n    <param.guid>a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d</param.guid>\n    <param.exclude.filters>% List files contained in your toolbox folder that you would like to exclude\n% from packaging.  Excludes should be listed relative to the toolbox folder.\n% Some examples of how to specify excludes are provided below:\n%\n% A single file in the toolbox folder:\n% .svn\n%\n% A single file in a subfolder of the toolbox folder:\n% example/.svn\n%\n% All files in a subfolder of the toolbox folder:\n% example/*\n%\n% All files of a certain name in all subfolders of the toolbox folder:\n% **/.svn\n%\n% All files matching a pattern in all subfolders of the toolbox folder:\n% **/*.bak\n%\nbuild\nbuild-*\nCMakeLists.txt\n*.cpp\n*.hpp\ntest\n.git*\n*.yml</param.exclude.filters>\n    <param.exclude.pcodedmfiles>true</param.exclude.pcodedmfiles>\n    <param.examples />\n    <param.demosxml />\n    <param.apps />\n    <param.registered.apps />\n    <param.docs />\n    <param.getting.started.guide />\n    <param.matlabpath.excludes />\n    <param.javaclasspath.excludes />\n    <param.exported.on.package>false</param.exported.on.package>\n    <param.required.addons />\n    <param.matlab.project.id />\n    <param.matlab.project.name />\n    <param.release.start>R2019b</param.release.start>\n    <param.release.end>latest</param.release.end>\n    <param.release.current.only>false</param.release.current.only>\n    <param.compatiblity.windows>true</param.compatiblity.windows>\n    <param.compatiblity.mac>true</param.compatiblity.mac>\n    <param.compatiblity.linux>true</param.compatiblity.linux>\n    <param.compatiblity.matlabonline>false</param.compatiblity.matlabonline>\n    <param.installation.map />\n    <param.additional.sw.names />\n    <param.additional.sw.licenses />\n    <param.additional.sw.win.url />\n    <param.additional.sw.mac.url />\n    <param.additional.sw.linux.url />\n    <unset>\n      <param.company />\n      <param.output />\n      <param.products.name />\n      <param.products.id />\n      <param.products.version />\n      <param.platforms />\n      <param.exclude.pcodedmfiles />\n      <param.examples />\n      <param.demosxml />\n      <param.apps />\n      <param.registered.apps />\n      <param.docs />\n      <param.getting.started.guide />\n      <param.matlabpath.excludes />\n      <param.javaclasspath.excludes />\n      <param.exported.on.package />\n      <param.required.addons />\n      <param.matlab.project.id />\n      <param.matlab.project.name />\n      <param.release.current.only />\n      <param.compatiblity.windows />\n      <param.compatiblity.mac />\n      <param.compatiblity.linux />\n      <param.installation.map />\n      <param.additional.sw.names />\n      <param.additional.sw.licenses />\n      <param.additional.sw.win.url />\n      <param.additional.sw.mac.url />\n      <param.additional.sw.linux.url />\n    </unset>\n    <fileset.rootdir>\n      <file>${PROJECT_ROOT}</file>\n    </fileset.rootdir>\n    <fileset.rootfiles>\n      <file>${PROJECT_ROOT}\\+Doxa</file>\n      <file>${PROJECT_ROOT}\\README.md</file>\n    </fileset.rootfiles>\n    <fileset.depfun.included />\n    <fileset.depfun.excluded />\n    <fileset.package />\n    <build-deliverables>\n      <file location=\"${PROJECT_ROOT}\" name=\"Doxa.mltbx\" optional=\"false\">${PROJECT_ROOT}\\Doxa.mltbx</file>\n    </build-deliverables>\n    <workflow />\n    <matlab>\n      <root>${MATLAB_ROOT}</root>\n      <toolboxes />\n    </matlab>\n    <platform>\n      <unix>false</unix>\n      <mac>false</mac>\n      <windows>true</windows>\n      <win2k>false</win2k>\n      <winxp>false</winxp>\n      <vista>false</vista>\n      <linux>false</linux>\n      <solaris>false</solaris>\n      <osver>10.0</osver>\n      <os32>false</os32>\n      <os64>true</os64>\n      <arch>win64</arch>\n      <matlab>true</matlab>\n    </platform>\n  </configuration>\n</deployment-project>\n"
  },
  {
    "path": "Bindings/Matlab/DoxaMexUtils.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef DOXAMEXUTILS_HPP\n#define DOXAMEXUTILS_HPP\n\n#include \"mex.h\"\n#include \"Doxa/Image.hpp\"\n#include \"Doxa/Parameters.hpp\"\n#include \"Doxa/BinarizationFactory.hpp\"\n#include \"Doxa/ClassifiedPerformance.hpp\"\n#include \"Doxa/DRDM.hpp\"\n#include \"Doxa/Grayscale.hpp\"\n#include <string>\n#include <vector>\n#include <unordered_map>\n#include <cstring>\n\nnamespace DoxaMexUtils\n{\n    /// <summary>\n    /// Casts a uint64 scalar mxArray handle to a Doxa::Image pointer with validation.\n    /// </summary>\n    inline Doxa::Image* HandleToImage(const mxArray* arr)\n    {\n        if (!mxIsUint64(arr) || !mxIsScalar(arr)) {\n            mexErrMsgIdAndTxt(\"Doxa:InvalidHandle\", \"Expected a Doxa.Image handle (uint64 scalar).\");\n        }\n        uint64_t handle = *static_cast<uint64_t*>(mxGetData(arr));\n        if (handle == 0) {\n            mexErrMsgIdAndTxt(\"Doxa:NullHandle\", \"Image handle is null or has been destroyed.\");\n        }\n        return reinterpret_cast<Doxa::Image*>(static_cast<uintptr_t>(handle));\n    }\n\n    /// <summary>\n    /// Wraps a Doxa::Image pointer into a uint64 scalar mxArray.\n    /// </summary>\n    inline mxArray* ImageToHandle(Doxa::Image* image)\n    {\n        mxArray* arr = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);\n        *static_cast<uint64_t*>(mxGetData(arr)) = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(image));\n        return arr;\n    }\n\n    /// <summary>\n    /// Creates a new Doxa::Image from a Matlab 2D uint8 array, transposing from column-major to row-major.\n    /// </summary>\n    inline Doxa::Image* CreateImageFromMxArray(const mxArray* arr)\n    {\n        if (!mxIsUint8(arr) || mxGetNumberOfDimensions(arr) != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:InvalidImage\", \"Image must be a 2D uint8 matrix.\");\n        }\n        const mwSize* dims = mxGetDimensions(arr);\n        int height = static_cast<int>(dims[0]);\n        int width = static_cast<int>(dims[1]);\n        const uint8_t* matlabData = static_cast<const uint8_t*>(mxGetData(arr));\n\n        Doxa::Image* image = new Doxa::Image(width, height);\n\n        // Transpose: col-major (Matlab) → row-major (Doxa)\n        for (int row = 0; row < height; ++row) {\n            for (int col = 0; col < width; ++col) {\n                image->data[row * width + col] = matlabData[col * height + row];\n            }\n        }\n\n        return image;\n    }\n\n    /// <summary>\n    /// Creates a new Matlab 2D uint8 mxArray from a Doxa::Image, transposing from row-major to column-major.\n    /// </summary>\n    inline mxArray* ImageToMxArray(const Doxa::Image& image)\n    {\n        mwSize dims[2] = { (mwSize)image.height, (mwSize)image.width };\n        mxArray* arr = mxCreateNumericArray(2, dims, mxUINT8_CLASS, mxREAL);\n        uint8_t* matlabData = static_cast<uint8_t*>(mxGetData(arr));\n\n        // Transpose: row-major (Doxa) → col-major (Matlab)\n        for (int row = 0; row < image.height; ++row) {\n            for (int col = 0; col < image.width; ++col) {\n                matlabData[col * image.height + row] = image.data[row * image.width + col];\n            }\n        }\n\n        return arr;\n    }\n\n    /// <summary>\n    /// Creates a new Doxa::Image from a Matlab 3D uint8 color array by converting to grayscale.\n    /// Matlab stores [H,W,C] as C separate column-major planes; Doxa expects interleaved row-major RGB.\n    /// </summary>\n    inline Doxa::Image* CreateImageFromGrayscale(const mxArray* arr, Doxa::GrayscaleAlgorithms algorithm)\n    {\n        if (!mxIsUint8(arr)) {\n            mexErrMsgIdAndTxt(\"Doxa:InvalidImage\", \"Color image must be a uint8 array.\");\n        }\n        mwSize ndims = mxGetNumberOfDimensions(arr);\n        const mwSize* dims = mxGetDimensions(arr);\n\n        if (ndims != 3 || (dims[2] != 3 && dims[2] != 4)) {\n            mexErrMsgIdAndTxt(\"Doxa:InvalidImage\", \"Color image must be [H,W,3] or [H,W,4] uint8.\");\n        }\n\n        int height = static_cast<int>(dims[0]);\n        int width = static_cast<int>(dims[1]);\n        int channels = static_cast<int>(dims[2]);\n        const uint8_t* matlabData = static_cast<const uint8_t*>(mxGetData(arr));\n\n        int pixelCount = width * height;\n\n        // Reorder Matlab planar col-major to interleaved row-major\n        std::vector<Doxa::Pixel8> interleaved(pixelCount * channels);\n        for (int row = 0; row < height; ++row) {\n            for (int col = 0; col < width; ++col) {\n                int doxaIdx = (row * width + col) * channels;\n                for (int c = 0; c < channels; ++c) {\n                    interleaved[doxaIdx + c] = matlabData[c * pixelCount + col * height + row];\n                }\n            }\n        }\n\n        // Convert to grayscale using Doxa\n        Doxa::Image* image = new Doxa::Image(width, height);\n        Doxa::Grayscale::ToGrayscale(image->data, interleaved.data(), width, height, channels, algorithm);\n\n        return image;\n    }\n\n    /// <summary>\n    /// Converts a Matlab double array to a std::vector of doubles.\n    /// </summary>\n    inline std::vector<double> MxArrayToDoubleVector(const mxArray* arr)\n    {\n        if (!mxIsDouble(arr)) {\n            mexErrMsgIdAndTxt(\"Doxa:InvalidWeights\", \"Weights must be a double array.\");\n        }\n        double* data = mxGetPr(arr);\n        size_t n = mxGetNumberOfElements(arr);\n        return std::vector<double>(data, data + n);\n    }\n\n    /// <summary>\n    /// Converts a Matlab struct into a Doxa::ParameterMap.\n    /// </summary>\n    /// <summary>\n    /// Maps Matlab-friendly field names to C++ parameter names.\n    /// Matlab struct fields cannot contain hyphens, so camelCase is mapped here.\n    /// </summary>\n    inline std::string MapParameterName(const std::string& matlabName)\n    {\n        static const std::unordered_map<std::string, std::string> nameMap = {\n            {\"contrastLimit\", \"contrast-limit\"}\n        };\n\n        auto it = nameMap.find(matlabName);\n        return (it != nameMap.end()) ? it->second : matlabName;\n    }\n\n    inline Doxa::Parameters MxStructToParameters(const mxArray* aStruct)\n    {\n        Doxa::ParameterMap paramMap;\n        if (aStruct != nullptr && !mxIsEmpty(aStruct)) {\n            if (!mxIsStruct(aStruct)) {\n                mexErrMsgIdAndTxt(\"Doxa:InvalidParams\", \"Parameters must be a struct.\");\n            }\n\n            int numFields = mxGetNumberOfFields(aStruct);\n            for (int i = 0; i < numFields; ++i) {\n                const char* matlabFieldName = mxGetFieldNameByNumber(aStruct, i);\n                mxArray* fieldValue = mxGetFieldByNumber(aStruct, 0, i);\n                std::string paramName = MapParameterName(matlabFieldName);\n\n                if (mxIsScalar(fieldValue)) {\n                    if (mxIsDouble(fieldValue)) {\n                        paramMap[paramName] = mxGetScalar(fieldValue);\n                    } else { // Treat other numeric types as int\n                        paramMap[paramName] = static_cast<int>(mxGetScalar(fieldValue));\n                    }\n                }\n            }\n        }\n        return Doxa::Parameters(paramMap);\n    }\n\n    /// <summary>\n    /// Converts a string algorithm name to a Doxa::Algorithms enum.\n    /// </summary>\n    inline Doxa::Algorithms StringToAlgorithmEnum(const std::string& algorithmStr)\n    {\n        static const std::unordered_map<std::string, Doxa::Algorithms> algorithmMap = {\n            {\"OTSU\", Doxa::Algorithms::OTSU},       {\"BERNSEN\", Doxa::Algorithms::BERNSEN},\n            {\"NIBLACK\", Doxa::Algorithms::NIBLACK}, {\"SAUVOLA\", Doxa::Algorithms::SAUVOLA},\n            {\"WOLF\", Doxa::Algorithms::WOLF},       {\"NICK\", Doxa::Algorithms::NICK},\n            {\"SU\", Doxa::Algorithms::SU},           {\"TRSINGH\", Doxa::Algorithms::TRSINGH},\n            {\"BATAINEH\", Doxa::Algorithms::BATAINEH}, {\"ISAUVOLA\", Doxa::Algorithms::ISAUVOLA},\n            {\"WAN\", Doxa::Algorithms::WAN},         {\"GATOS\", Doxa::Algorithms::GATOS},\n            {\"ADOTSU\", Doxa::Algorithms::ADOTSU},   {\"PHANSALKAR\", Doxa::Algorithms::PHANSALKAR}\n        };\n\n        auto it = algorithmMap.find(algorithmStr);\n        if (it == algorithmMap.end()) {\n            mexErrMsgIdAndTxt(\"Doxa:UnknownAlgorithm\", \"Unknown algorithm specified: %s\", algorithmStr.c_str());\n        }\n        return it->second;\n    }\n\n    /// <summary>\n    /// Converts a string grayscale algorithm name to a Doxa::GrayscaleAlgorithms enum.\n    /// </summary>\n    inline Doxa::GrayscaleAlgorithms StringToGrayscaleEnum(const std::string& algorithmStr)\n    {\n        static const std::unordered_map<std::string, Doxa::GrayscaleAlgorithms> grayscaleMap = {\n            {\"MEAN\", Doxa::GrayscaleAlgorithms::MEAN},\n            {\"QT\", Doxa::GrayscaleAlgorithms::QT},\n            {\"BT601\", Doxa::GrayscaleAlgorithms::BT601},\n            {\"BT709\", Doxa::GrayscaleAlgorithms::BT709},\n            {\"BT2100\", Doxa::GrayscaleAlgorithms::BT2100},\n            {\"VALUE\", Doxa::GrayscaleAlgorithms::VALUE},\n            {\"LUSTER\", Doxa::GrayscaleAlgorithms::LUSTER},\n            {\"LIGHTNESS\", Doxa::GrayscaleAlgorithms::LIGHTNESS},\n            {\"MINAVG\", Doxa::GrayscaleAlgorithms::MINAVG},\n            {\"LABDIST\", Doxa::GrayscaleAlgorithms::LABDIST}\n        };\n\n        auto it = grayscaleMap.find(algorithmStr);\n        if (it == grayscaleMap.end()) {\n            mexErrMsgIdAndTxt(\"Doxa:UnknownGrayscale\", \"Unknown grayscale algorithm: %s\", algorithmStr.c_str());\n        }\n        return it->second;\n    }\n}\n\n#endif // DOXAMEXUTILS_HPP\n"
  },
  {
    "path": "Bindings/Matlab/ImageMex.cpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#include \"mex.h\"\n#include \"DoxaMexUtils.hpp\"\n\n/// <summary>\n/// MEX gateway for Doxa.Image lifecycle management.\n/// Dispatches on an action string to create, convert, extract, or destroy images.\n///\n/// Actions:\n///   handle = image_mex('create', uint8_2d_array)\n///   handle = image_mex('from_grayscale', algorithm_str, uint8_3d_array)\n///   uint8_2d = image_mex('to_array', handle)\n///   width = image_mex('width', handle)\n///   height = image_mex('height', handle)\n///   image_mex('destroy', handle)\n/// </summary>\nvoid mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])\n{\n    if (nrhs < 1) {\n        mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex(action, ...)\");\n    }\n\n    std::string action = mxArrayToString(prhs[0]);\n\n    if (action == \"create\")\n    {\n        // create(uint8_2d_array) → handle\n        if (nrhs != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('create', uint8_2d_array)\");\n        }\n\n        Doxa::Image* image = DoxaMexUtils::CreateImageFromMxArray(prhs[1]);\n        plhs[0] = DoxaMexUtils::ImageToHandle(image);\n    }\n    else if (action == \"from_grayscale\")\n    {\n        // from_grayscale(algorithm_str, uint8_3d_array) → handle\n        if (nrhs != 3) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('from_grayscale', algorithm, color_array)\");\n        }\n\n        std::string algorithmStr = mxArrayToString(prhs[1]);\n        Doxa::GrayscaleAlgorithms algorithm = DoxaMexUtils::StringToGrayscaleEnum(algorithmStr);\n\n        Doxa::Image* image = DoxaMexUtils::CreateImageFromGrayscale(prhs[2], algorithm);\n        plhs[0] = DoxaMexUtils::ImageToHandle(image);\n    }\n    else if (action == \"to_array\")\n    {\n        // to_array(handle) → uint8_2d_array\n        if (nrhs != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('to_array', handle)\");\n        }\n\n        Doxa::Image* image = DoxaMexUtils::HandleToImage(prhs[1]);\n        plhs[0] = DoxaMexUtils::ImageToMxArray(*image);\n    }\n    else if (action == \"width\")\n    {\n        // width(handle) → double\n        if (nrhs != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('width', handle)\");\n        }\n\n        Doxa::Image* image = DoxaMexUtils::HandleToImage(prhs[1]);\n        plhs[0] = mxCreateDoubleScalar(static_cast<double>(image->width));\n    }\n    else if (action == \"height\")\n    {\n        // height(handle) → double\n        if (nrhs != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('height', handle)\");\n        }\n\n        Doxa::Image* image = DoxaMexUtils::HandleToImage(prhs[1]);\n        plhs[0] = mxCreateDoubleScalar(static_cast<double>(image->height));\n    }\n    else if (action == \"destroy\")\n    {\n        // destroy(handle) → void\n        if (nrhs != 2) {\n            mexErrMsgIdAndTxt(\"Doxa:Image:InvalidInput\", \"Usage: image_mex('destroy', handle)\");\n        }\n\n        Doxa::Image* image = DoxaMexUtils::HandleToImage(prhs[1]);\n        delete image;\n    }\n    else\n    {\n        mexErrMsgIdAndTxt(\"Doxa:Image:UnknownAction\", \"Unknown action: %s\", action.c_str());\n    }\n}\n"
  },
  {
    "path": "Bindings/Matlab/README.md",
    "content": "# Δoxa Binarization Framework - Matlab\n\n## Introduction\nDoxa is an image binarization library focusing on local adaptive thresholding algorithms. In English, this means that it has the ability to turn a color or gray scale image into a black and white image.\n\nThis binding provides a simple, high-level interface for using the Doxa C++ framework directly within Matlab, with idiomatic naming and a `Doxa.*` package namespace.\n\n## Build & Test\n\n### Using CMake Presets (Recommended)\n```sh\n# From the project root\ncmake --preset matlab\ncmake --build build-matlab --config Release\nctest --test-dir build-matlab -C Release\n```\n\n### Package Toolbox (.mltbx)\nAfter building MEX files, create the distributable toolbox from MATLAB:\n```matlab\ncd Bindings/Matlab\nmatlab.addons.toolbox.packageToolbox('Doxa.prj')\n% Produces Doxa.mltbx\n```\n\n## Matlab Example\nAdd the build output directory to your Matlab path, then use the `Doxa.*` API.\n\n```matlab\n% Add the build directory to the path\naddpath('path/to/build-matlab/mex');\n\n% Read a color image and convert to grayscale\nimg = Doxa.Image('photo.ppm', Doxa.Grayscale.QT);\n\n% Binarize with Sauvola (name-value parameters)\nbinary = Doxa.binarize(Doxa.Algorithms.SAUVOLA, img, window=75, k=0.2);\n\n% Display the result\nimshow(binary.toArray());\n\n% Or binarize in-place for efficiency\nDoxa.updateToBinary(Doxa.Algorithms.SAUVOLA, img, window=75, k=0.2);\n```\n\n## Algorithms\nAll 14 binarization algorithms are available via `Doxa.Algorithms`:\n\n| Global | Local Adaptive |\n|--------|---------------|\n| `OTSU` | `BERNSEN`, `NIBLACK`, `SAUVOLA`, `WOLF`, `NICK`, `SU`, `TRSINGH`, `BATAINEH`, `PHANSALKAR`, `ISAUVOLA`, `WAN`, `GATOS`, `ADOTSU` |\n\n## Grayscale Conversion\nTen grayscale algorithms are available via `Doxa.Grayscale`:\n\n`MEAN`, `QT`, `BT601`, `BT709`, `BT2100`, `VALUE`, `LUSTER`, `LIGHTNESS`, `MINAVG`, `LABDIST`\n\n```matlab\n% Smart constructor handles files, 2D arrays, and 3D color arrays\nimg = Doxa.Image('color.ppm', Doxa.Grayscale.MEAN);\nimg = Doxa.Image(rgb_array, Doxa.Grayscale.QT);\nimg = Doxa.Image(gray_array);\n```\n\n## Performance Metrics\n\n```matlab\n% Calculate metrics\nmetrics = Doxa.calculatePerformance(gt, binary);\n\n% With weight files\npw = Doxa.readWeights('precision_weights.dat');\nrw = Doxa.readWeights('recall_weights.dat');\nmetrics = Doxa.calculatePerformance(gt, binary, precisionWeights=pw, recallWeights=rw);\n```\n\n**Metrics:** accuracy, fm, recall, precision, psnr, nrm, mcc, drdm, pseudoFM, pseudoPrecision, pseudoRecall\n\n## License\nCC0 - Brandon M. Petty, 2026\n\nTo the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.\n\n[View Online](https://creativecommons.org/publicdomain/zero/1.0/legalcode)\n\n\"*Freely you have received; freely give.*\" - Matt 10:8\n"
  },
  {
    "path": "Bindings/Matlab/UpdateToBinaryMex.cpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#include \"mex.h\"\n#include \"DoxaMexUtils.hpp\"\n\n/// <summary>\n/// MEX function to binarize a Doxa.Image in-place.\n/// Matlab Signature: update_in_place_mex(algorithm_name, image_handle, params_struct)\n/// </summary>\nvoid mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])\n{\n    if (nrhs < 2 || nrhs > 3) {\n        mexErrMsgIdAndTxt(\"Doxa:updateToBinary:InvalidInput\", \"Usage: update_in_place_mex(algorithm, image_handle, params_struct)\");\n    }\n    if (nlhs > 0) {\n        mexErrMsgIdAndTxt(\"Doxa:updateToBinary:InvalidOutput\", \"updateToBinary modifies the image in-place and has no return values.\");\n    }\n\n    // 1. Get Algorithm Enum\n    std::string algorithmStr = mxArrayToString(prhs[0]);\n    Doxa::Algorithms algorithmEnum = DoxaMexUtils::StringToAlgorithmEnum(algorithmStr);\n\n    // 2. Get Image from handle (already row-major, operates in-place)\n    Doxa::Image* image = DoxaMexUtils::HandleToImage(prhs[1]);\n\n    // 3. Get Parameters\n    const mxArray* paramsMx = (nrhs == 3) ? prhs[2] : nullptr;\n    Doxa::Parameters params = DoxaMexUtils::MxStructToParameters(paramsMx);\n\n    // 4. Run algorithm in-place on the C++ buffer\n    Doxa::IAlgorithm* algorithm = Doxa::BinarizationFactory::Algorithm(algorithmEnum);\n    algorithm->Initialize(*image);\n    algorithm->ToBinary(*image, params);\n    delete algorithm;\n}\n"
  },
  {
    "path": "Bindings/Matlab/test/TestDoxa.m",
    "content": "classdef TestDoxa < matlab.unittest.TestCase\n    % Test suite for the Doxa Matlab bindings.\n\n    properties\n        TestData\n    end\n\n    methods (TestClassSetup)\n        function loadTestData(testCase)\n            % Locate test resources\n            baseDir = fileparts(mfilename('fullpath'));\n            resourceDir = fullfile(baseDir, '..', '..', 'Doxa.Test', 'Resources');\n\n            % Store resource dir for weight files\n            testCase.TestData.resourceDir = resourceDir;\n\n            % Create grayscale image using Qt algorithm (matches ground truth generation)\n            rgb = imread(fullfile(resourceDir, '2JohnC1V3.ppm'));\n            testCase.TestData.rgb = rgb;\n            testCase.TestData.grayscaleImage = Doxa.Image(rgb, Doxa.Grayscale.QT);\n\n            % Load ground truth images\n            testCase.TestData.groundTruth = Doxa.Image(fullfile(resourceDir, '2JohnC1V3-GroundTruth.pbm'));\n            testCase.TestData.sauvolaGroundTruth = Doxa.Image(fullfile(resourceDir, '2JohnC1V3-Sauvola.pbm'));\n\n            % Keep raw ground truth for comparison\n            testCase.TestData.sauvolaGroundTruthArray = ...\n                uint8(imread(fullfile(resourceDir, '2JohnC1V3-Sauvola.pbm'))) * 255;\n        end\n    end\n\n    methods (Test)\n        function testBinarize(testCase)\n            % Tests the binarize function for correctness.\n            binary = Doxa.binarize(Doxa.Algorithms.SAUVOLA, ...\n                testCase.TestData.grayscaleImage, window=27, k=0.10);\n\n            result = binary.toArray();\n\n            % Verify binary output (only 0 and 255)\n            testCase.verifyEqual(unique(result(:)), uint8([0; 255]));\n\n            % Verify against ground truth\n            testCase.verifyEqual(result, testCase.TestData.sauvolaGroundTruthArray, ...\n                'Binarized image does not match ground truth.');\n        end\n\n        function testUpdateToBinary(testCase)\n            % Tests the in-place update function.\n            img = Doxa.Image(testCase.TestData.grayscaleImage.toArray());\n            Doxa.updateToBinary(Doxa.Algorithms.SAUVOLA, img, window=27, k=0.10);\n\n            testCase.verifyEqual(img.toArray(), testCase.TestData.sauvolaGroundTruthArray, ...\n                'In-place binarized image does not match ground truth.');\n        end\n\n        function testCalculatePerformance(testCase)\n            % Tests performance metrics match Python/C++ expected values.\n            metrics = Doxa.calculatePerformance( ...\n                testCase.TestData.groundTruth, ...\n                testCase.TestData.sauvolaGroundTruth);\n\n            testCase.verifyEqual(metrics.accuracy, 97.671, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.fm, 93.204, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.recall, 91.381, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.precision, 95.103, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.psnr, 16.329, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.nrm, 0.048, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.mcc, 0.918, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.drdm, 1.952, 'RelTol', 1e-2);\n        end\n\n        function testPseudoPerformance(testCase)\n            % Tests pseudo-metrics with weight files.\n            pWeights = Doxa.readWeights(fullfile( ...\n                testCase.TestData.resourceDir, '2JohnC1V3-GroundTruth_PWeights.dat'));\n            rWeights = Doxa.readWeights(fullfile( ...\n                testCase.TestData.resourceDir, '2JohnC1V3-GroundTruth_RWeights.dat'));\n\n            metrics = Doxa.calculatePerformance( ...\n                testCase.TestData.groundTruth, ...\n                testCase.TestData.sauvolaGroundTruth, ...\n                precisionWeights=pWeights, recallWeights=rWeights);\n\n            testCase.verifyEqual(metrics.pseudoFM, 93.393, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.pseudoRecall, 92.795, 'RelTol', 1e-2);\n            testCase.verifyEqual(metrics.pseudoPrecision, 93.998, 'RelTol', 1e-2);\n        end\n\n        function testGrayscale(testCase)\n            % Tests grayscale conversion matches manual Qt formula.\n            rgb = testCase.TestData.rgb;\n            img = Doxa.Image(rgb, Doxa.Grayscale.QT);\n            result = img.toArray();\n\n            % Compute expected using Qt formula\n            r = double(rgb(:,:,1));\n            g = double(rgb(:,:,2));\n            b = double(rgb(:,:,3));\n            expected = uint8((r * 11 + g * 16 + b * 5) / 32);\n\n            testCase.verifyEqual(result, expected, 'AbsTol', uint8(1), ...\n                'Grayscale conversion does not match Qt formula.');\n        end\n\n        function testImageFromFile(testCase)\n            % Tests that loading from file matches loading from array.\n            resourceDir = testCase.TestData.resourceDir;\n\n            imgFromFile = Doxa.Image(fullfile(resourceDir, '2JohnC1V3.ppm'), Doxa.Grayscale.QT);\n            imgFromArray = Doxa.Image(imread(fullfile(resourceDir, '2JohnC1V3.ppm')), Doxa.Grayscale.QT);\n\n            testCase.verifyEqual(imgFromFile.toArray(), imgFromArray.toArray(), ...\n                'File-based and array-based construction produce different results.');\n        end\n\n        function testReadWeights(testCase)\n            % Tests weight file loading.\n            weights = Doxa.readWeights(fullfile( ...\n                testCase.TestData.resourceDir, '2JohnC1V3-GroundTruth_PWeights.dat'));\n\n            testCase.verifyFalse(isempty(weights));\n            testCase.verifyTrue(isa(weights, 'double'));\n            testCase.verifyGreaterThan(numel(weights), 0);\n        end\n\n        function testImageDisplay(testCase)\n            % Tests that disp works without error.\n            img = testCase.TestData.grayscaleImage;\n            testCase.verifyWarningFree(@() disp(img));\n        end\n\n        function testAllAlgorithmsRun(testCase)\n            % Ensures all algorithms can be called without error.\n            algorithms = enumeration('Doxa.Algorithms');\n            img = testCase.TestData.grayscaleImage;\n\n            for i = 1:length(algorithms)\n                alg = algorithms(i);\n                testCase.verifyWarningFree(@() Doxa.binarize(alg, img), ...\n                    ['Algorithm ' char(alg) ' failed to run.']);\n            end\n        end\n    end\nend\n"
  },
  {
    "path": "Bindings/Python/.gitignore",
    "content": "build\ndist\nsrc/Doxa\n__pycache__"
  },
  {
    "path": "Bindings/Python/CMakeLists.txt",
    "content": "message(STATUS \"DoxaPy - CMake Build\")\n\ncmake_minimum_required(VERSION 3.16...3.27)\nproject(doxapy)\n\nif (CMAKE_VERSION VERSION_LESS 3.18)\n  set(DEV_MODULE Development)\nelse()\n  set(DEV_MODULE Development.Module)\nendif()\n\nfind_package(Python 3.12 \n  REQUIRED COMPONENTS Interpreter ${DEV_MODULE} \n  OPTIONAL_COMPONENTS Development.SABIModule\n)\n\nif (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)\n  set(CMAKE_BUILD_TYPE Release CACHE STRING \"Choose the type of build.\" FORCE)\n  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS \"Debug\" \"Release\" \"RelWithDebInfo\")\nendif()\n\nmessage(STATUS \"Build Type: ${CMAKE_BUILD_TYPE}\")\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nadd_compile_definitions(NB_TARGET_ABI_VERSION=312)\n\n# SIMD support for Python bindings\noption(DOXAPY_ENABLE_SIMD \"Enable SIMD in Python bindings\" ON)\n\nif(MSVC)\n    # so far so good\nelse()\n    add_compile_options(\"-Wno-narrowing\")\nendif()\n\n# Detect the installed nanobind package and import it into CMake\nexecute_process(\n  COMMAND \"${Python_EXECUTABLE}\" -m nanobind --cmake_dir\n  OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT\n)\nfind_package(nanobind CONFIG REQUIRED)\n\ninclude_directories(./src/Doxa)\n\nnanobind_add_module(\n  doxapy\n  NB_STATIC STABLE_ABI LTO NOMINSIZE\n  src/DoxaPy.cpp\n)\n\n# Speed optimization for header-only library (algorithms compile within binding module)\ntarget_compile_options(doxapy PRIVATE\n    $<$<AND:$<NOT:$<CONFIG:Debug>>,$<CXX_COMPILER_ID:MSVC>>:/O2>\n    $<$<AND:$<NOT:$<CONFIG:Debug>>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>:-O3>\n)\n\n# Platform-specific SIMD flags (same logic as test)\nif(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64|AMD64|x64\")\n    # x86-64: SSE2 is always available (baseline for x64)\n    if(MSVC)\n        # MSVC x64: SSE2 is enabled by default, no special flags needed\n        message(STATUS \"DoxaPy SIMD: x86-64 with SSE2 (MSVC)\")\n    else()\n        # GCC/Clang: SSE2 is default for x64, but be explicit\n        target_compile_options(doxapy PRIVATE -msse2)\n        message(STATUS \"DoxaPy SIMD: x86-64 with SSE2 (GCC/Clang)\")\n    endif()\n\nelseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|ARM64\")\n    message(STATUS \"DoxaPy SIMD: ARM64 with NEON\")\n\nendif()\n\n# Copy built module + __init__.py to dist/doxapy/ as a proper package\nadd_custom_command(TARGET doxapy POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/dist/doxapy\n    COMMAND ${CMAKE_COMMAND} -E copy\n        $<TARGET_FILE:doxapy>\n        ${CMAKE_CURRENT_SOURCE_DIR}/dist/doxapy/\n    COMMAND ${CMAKE_COMMAND} -E copy\n        ${CMAKE_CURRENT_SOURCE_DIR}/src/doxapy/__init__.py\n        ${CMAKE_CURRENT_SOURCE_DIR}/dist/doxapy/\n    COMMENT \"Copying doxapy package to dist/\"\n)\n\ninstall(TARGETS doxapy LIBRARY DESTINATION doxapy)\n"
  },
  {
    "path": "Bindings/Python/DoxaPy.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"17ccb794-7c43-4c40-89ff-693df6b7b513\",\n   \"metadata\": {},\n   \"source\": [\n    \"# DoxaPy Notebook\\n\",\n    \"\\n\",\n    \"https://github.com/brandonmpetty/Doxa\\n\",\n    \"\\n\",\n    \"DoxaPy is an image binarization library focused on local adaptive algorithms and metrics.\\n\",\n    \"This notebook will document the API while allowing you to interact with it.\\n\",\n    \"\\n\",\n    \"## Setup\\n\",\n    \"The first thing to do when getting started with this library is to install it.\\n\",\n    \"```\\n\",\n    \"pip install doxapy\\n\",\n    \"```\\n\",\n    \"Form more details, see: https://pypi.org/project/doxapy\\n\",\n    \"\\n\",\n    \"Alternatively, you can build the library from source as described in the README.MD.\\n\",\n    \"\\n\",\n    \"From there, it is as simple as importing the library.  NumPy and Pillow are two other libraries we will use in this demonstration.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"532b64af-c7f0-4f68-87fe-c17d3322c219\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Prioritize a local build first\\n\",\n    \"import sys, os\\n\",\n    \"sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(\\\"__file__\\\")), \\\"dist\\\"))\\n\",\n    \"\\n\",\n    \"from PIL import Image\\n\",\n    \"import numpy as np\\n\",\n    \"import doxapy\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"5fd90377-1177-4e16-aeb8-b1da0a525269\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Reading an Image\\n\",\n    \"The first step is to read the image you intend on processing.  The *read_image* helper function uses Pillow to read in a local image and convert it to grayscale.  We then use NumPy to turn that image into an array.\\n\",\n    \"\\n\",\n    \"DoxaPy exposes a number of Color of Grayscale algorithms.\\n\",\n    \"\\n\",\n    \"### Grayscale Algorithms\\n\",\n    \"- **MEAN**\\n\",\n    \"- **QT**\\n\",\n    \"- **BT601**\\n\",\n    \"- **BT709**\\n\",\n    \"- **BT2100**\\n\",\n    \"- **VALUE**\\n\",\n    \"- **LUSTER**\\n\",\n    \"- **LIGHTNESS**\\n\",\n    \"- **MINAVG**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"5993f8a0-a499-412f-b832-767d97c8efe9\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def read_image(file, algorithm=doxapy.GrayscaleAlgorithms.MEAN):\\n\",\n    \"    '''Read an image.  If it is color, turn it into 8 bit grayscale.'''\\n\",\n    \"    image = Image.open(file)\\n\",\n    \"\\n\",\n    \"    # If already in grayscale or binary, do not convert it\\n\",\n    \"    if image.mode == 'L':\\n\",\n    \"        return np.array(image)\\n\",\n    \"    \\n\",\n    \"    # Read the color image\\n\",\n    \"    rgb_image = np.array(image.convert('RGB') if image.mode not in ('RGB', 'RGBA') else image)\\n\",\n    \"\\n\",\n    \"    # Use Doxa to convert to grayscale\\n\",\n    \"    return doxapy.to_grayscale(algorithm, rgb_image)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"a475bd49-b1ec-4ebd-b146-8cb819817a18\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"grayscale_image = read_image(\\\"../../Doxa.Test/Resources/2JohnC1V3.ppm\\\", doxapy.GrayscaleAlgorithms.LIGHTNESS)\\n\",\n    \"display(Image.fromarray(grayscale_image))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"3665c6d0-0a4e-4950-a025-69ae0dae60e3\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Converting the Image to Binary\\n\",\n    \"Converting an image into black and white may seem easy, but it has been the focus of much research spanning decades.  Doxa was designed to expose this research, traditionally mired by PHD technical jargon, in a very easy to consume fashion.  A lot of work was put into ensuring these algorithms were implemented correctly and effeciently.  Many of these algorithms were first made public by this project and many of them leverage state of the art enhacements to reduce memory utilization and increase speed of operation found nowhere else.\\n\",\n    \"\\n\",\n    \"### Algorithms\\n\",\n    \"The Doxa library implements a large number of popular and unique local adaptive binarization algorithms.  Each algorithm has a set of parameters that are required for it to operate.  These parameters can vary from algorithm to algorithm.  Doxa provides sensible defaults that are applied automatically unless you supply your own.  Below is a list of algorithms and their defaults:\\n\",\n    \"\\n\",\n    \"* **OTSU**\\n\",\n    \"* **BERNSEN** - {\\\"window\\\": 75, \\\"threshold\\\": 100, \\\"contrast-limit\\\": 25}\\n\",\n    \"* **NIBLACK** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **SAUVOLA** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **WOLF** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **NICK** - {\\\"window\\\": 75, \\\"k\\\": -0.2}\\n\",\n    \"* **SU** - {\\\"window\\\": 9, \\\"minN\\\": 9}\\n\",\n    \"* **TRSINGH** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **BATAINEH**\\n\",\n    \"* **ISAUVOLA** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **WAN** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\n\",\n    \"* **GATOS** - {\\\"window\\\": 75, \\\"k\\\": 0.2, \\\"glyph\\\": 60}\\n\",\n    \"* **ADOTSU** - {\\\"window\\\": 75, \\\"k\\\": 1.0, \\\"R\\\": 0.1, \\\"distance\\\": window/2}\\n\",\n    \"* **PHANSALKAR** - {\\\"window\\\": 75, \\\"k\\\": 0.2, \\\"p\\\": 3.0, \\\"q\\\": 10.0}\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"656a290b-9c83-4ee4-9eee-6a5126e1e574\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Initialize an image array with the same shape as our grayscale image\\n\",\n    \"binary_image = doxapy.to_binary(doxapy.Binarization.Algorithms.SAUVOLA, grayscale_image, {\\\"window\\\": 75, \\\"k\\\": 0.2})\\n\",\n    \"display(Image.fromarray(binary_image))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"58ae263b-3341-4388-b0f8-0bae06f8a13d\",\n   \"metadata\": {},\n   \"source\": [\n    \"One of the quickest and most efficient ways of turning your grayscale image into a binary image is to use the *update_to_binary* function.  Instead of allocating more memory to write the image to, it will update the existing image in-place.  It also only takes one line to write!\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"6b444625-0b48-4197-b884-2f2ba591906e\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"doxapy.update_to_binary(doxapy.Binarization.Algorithms.SAUVOLA, grayscale_image, {\\\"window\\\": 27, \\\"k\\\": 0.12})\\n\",\n    \"display(Image.fromarray(grayscale_image))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"24d8b5dc-9b75-4c33-8814-50fc00082d40\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Performance Metrics\\n\",\n    \"In order to analyze the performance of an algorithm, Doxa provides a set of common metrics that can all be calculated with one function.  To start that process you need an exemplar binary image, or \\\"ground truth.\\\"  By comparing the ground truth to the resulting image of the binarization algorithm, you can start to compare the affects of different algorithms and algorithm parameters.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"70ba6fef-7a29-4dcd-a75b-5fa4cf016414\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"groundtruth_image = read_image(\\\"../../Doxa.Test/Resources/2JohnC1V3-GroundTruth.pbm\\\")\\n\",\n    \"display(Image.fromarray(groundtruth_image))\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"73cddbae\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Read our Pseudo F-Measure weights\\n\",\n    \"p_weights = doxapy.read_weights(\\\"../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_PWeights.dat\\\")\\n\",\n    \"r_weights = doxapy.read_weights(\\\"../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_RWeights.dat\\\")\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"90439c66-67d5-4b2d-a450-5c1c823f2414\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# Help us 'pretty print' our JSON\\n\",\n    \"import json\\n\",\n    \"\\n\",\n    \"# Both of these were done with the Sauvola algorithm, but with different parameters\\n\",\n    \"# NOTE: grayscale_image was updated in-place above into binary \\n\",\n    \"performance1 = doxapy.calculate_performance(groundtruth_image, binary_image, p_weights, r_weights)\\n\",\n    \"performance2 = doxapy.calculate_performance_ex(groundtruth_image, grayscale_image, drdm=True, accuracy=True, mcc=True)\\n\",\n    \"\\n\",\n    \"print(\\\"Sauvola - Window = 75, K = 0.2\\\") # Default\\n\",\n    \"print(json.dumps(performance1, indent=2))\\n\",\n    \"print()\\n\",\n    \"print(\\\"Sauvola - Window = 27, K = 0.12\\\") # Adjusted\\n\",\n    \"print(json.dumps(performance2, indent=2))\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.13.3\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"
  },
  {
    "path": "Bindings/Python/README.md",
    "content": "# Δoxa Binarization Framework - Python\n\n## Introduction\nDoxaPy is an image binarization library focusing on local adaptive thresholding algorithms. In English, this means that it has the ability to turn a color or gray scale image into a black and white image.\n\n**Algorithms**\n* Otsu - \"A threshold selection method from gray-level histograms\", 1979.\n* Bernsen - \"Dynamic thresholding of gray-level images\", 1986.\n* Niblack - \"An Introduction to Digital Image Processing\", 1986.\n* Sauvola - \"Adaptive document image binarization\", 1999.\n* Wolf - \"Extraction and Recognition of Artificial Text in Multimedia Documents\", 2003.\n* Gatos - \"Adaptive degraded document image binarization\", 2005. (Partial)\n* NICK - \"Comparison of Niblack inspired Binarization methods for ancient documents\", 2009.\n* AdOtsu - \"A multi-scale framework for adaptive binarization of degraded document images\", 2010.\n* Su - \"Binarization of Historical Document Images Using the Local Maximum and Minimum\", 2010.\n* T.R. Singh - \"A New local Adaptive Thresholding Technique in Binarization\", 2011.\n* Bataineh - \"An adaptive local binarization method for document images based on a novel thresholding method and dynamic windows\", 2011. (unreproducible)\n* Phansalkar - \"Adaptive Local Thresholding for Detection of Nuclei in Diversely Stained Cytology Images\", 2011.\n* ISauvola - \"ISauvola: Improved Sauvola's Algorithm for Document Image Binarization\", 2016.\n* WAN - \"Binarization of Document Image Using Optimum Threshold Modification\", 2018.\n\n**Optimizations**\n* Shafait - \"Efficient Implementation of Local Adaptive Thresholding Techniques Using Integral Images\", 2008.\n* Petty - An algorithm for efficiently calculating the min and max of a local window.  Unpublished, 2019.\n* Chan - \"Memory-efficient and fast implementation of local adaptive binarization methods\", 2019.\n* SIMD - SSE2, ARM NEON\n\n**Performance Metrics**\n* Overall Accuracy\n* F-Measure, Precision, Recall\n* Pseudo F-Measure, Precision, Recall - \"Performance Evaluation Methodology for Historical Document Image Binarization\", 2013.\n* Peak Signal-To-Noise Ratio (PSNR)\n* Negative Rate Metric (NRM)\n* Matthews Correlation Coefficient (MCC)\n* Distance-Reciprocal Distortion Measure (DRDM) - \"An Objective Distortion Measure for Binary Document Images Based on Human Visual Perception\", 2002.\n\n\n## Overview\nDoxaPy uses the Δoxa Binarization Framework for quickly processing python Image files.  It is comprised of three major sets of algorithms: Color to Grayscale, Grayscale to Binary, and Performance Metrics.  It can be used as a full DIBCO Metrics replacement that is significantly smaller, faster, and easier to integrate into existing projects.\n\n### Example\nThis short demo uses DoxaPy to read in a color image, converts it to binary, and then compares it to a Ground Truth image in order to calculate performance.\n\n```python\nfrom PIL import Image\nimport numpy as np\nimport doxapy\n\n\ndef read_image(file, algorithm=doxapy.GrayscaleAlgorithms.MEAN):\n    \"\"\"Read an image.  If its color, use one of our many Grayscale algorithms to convert it.\"\"\"\n    image = Image.open(file)\n\n    # If already in grayscale or binary, do not convert it\n    if image.mode == 'L':\n        return np.array(image)\n    \n    # Read the color image\n    rgb_image = np.array(image.convert('RGB') if image.mode not in ('RGB', 'RGBA') else image)\n\n    # Use Doxa to convert grayscale\n    return doxapy.to_grayscale(algorithm, rgb_image)\n\n\n# Read our target image and convert it to grayscale\ngrayscale_image = read_image(\"2JohnC1V3.png\")\n\n# Convert the grayscale image to a binary image (algorithm parameters optional)\nbinary_image = doxapy.to_binary(doxapy.Binarization.Algorithms.SAUVOLA, grayscale_image, {\"window\": 75, \"k\": 0.2})\n\n# Calculate the binarization performance using a Ground Truth image\ngroundtruth_image = read_image(\"2JohnC1V3-GroundTruth.png\")\nperformance = doxapy.calculate_performance(groundtruth_image, binary_image)\nprint(performance)\n\n# Display our resulting image\nImage.fromarray(binary_image).show()\n```\n\n### DoxaPy Notebook\nFor more details, open the [DoxaPy Notebook](https://github.com/brandonmpetty/Doxa/blob/master/Bindings/Python/DoxaPy.ipynb) and to get an interactive demo.\n\n\n## Building and Test\nDoxaPy supports 64b Linux, Windows, and Mac OSX on Python 3.x. Starting with DoxaPy 0.9.4, Python 3.12 and above are supported with full ABI compatibility. This means that new versions of DoxaPy will only be published due to feature enhancements, not Python version support.\n\n**Build from Project Root**\n```bash\n# From the Doxa project root\ngit clone --depth 1 https://github.com/brandonmpetty/Doxa.git\ncd Doxa\ncmake --preset python\ncmake --build build-python --config Release\npip install -r Bindings/Python/requirements.txt\nctest --test-dir build-python -C Release\n```\n\n**Local Package Build**\n```bash\npython -m build\n```\n\n**Local Wheel Build**\n```bash\npip wheel . --no-deps\n```\n\n## License\nCC0 - Brandon M. Petty, 2026\n\nTo the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.\n\n[View Online](https://creativecommons.org/publicdomain/zero/1.0/legalcode)\n\n\"*Freely you have received; freely give.*\" - Matt 10:8"
  },
  {
    "path": "Bindings/Python/copy-cpp-files.py",
    "content": "import glob, os, shutil\nfrom itertools import chain\n\nsrc_dir=os.path.join(\"..\", \"..\", \"Doxa\")\ndst_dir=os.path.join(\"src\", \"Doxa\")\n\nos.makedirs(dst_dir, exist_ok=True)\n\n# Copy only modified .HPP files, since the last run\nfiles = chain(\n    glob.iglob(os.path.join(src_dir, \"*.hpp\")),\n    glob.iglob(os.path.join(src_dir, \"*.h\"))\n)\nfor src_file in files:\n    if os.path.isfile(src_file):\n        dst_file=os.path.join(dst_dir, os.path.basename(src_file))\n        if not(os.path.isfile(dst_file)) or (os.stat(src_file).st_mtime - os.stat(dst_file).st_mtime > 0):\n            shutil.copy2(src_file, dst_dir)\n            print(f\"Copying {src_file}\")\n\n"
  },
  {
    "path": "Bindings/Python/pyproject.toml",
    "content": "[build-system]\nrequires = [\"cibuildwheel >= 2.22.0\",\"scikit-build-core >= 0.11.3\", \"nanobind >= 2.7.0\"]\nbuild-backend = \"scikit_build_core.build\"\n\n[project]\nname = \"doxapy\"\nversion = \"0.9.6\"\ndescription = \"An image binarization library focussing on local adaptive thresholding\"\nreadme = \"README.md\"\nauthors = [\n    {name = \"Brandon M. Petty\", email = \"brandonpetty1981@gmail.com\"}\n]\nlicense = {text = \"CC0-1.0\"}\nrequires-python = \">=3.12\"\ndependencies = [\n    \"numpy>=1.20.0\"\n]\n\n[project.urls]\nHomepage = \"https://github.com/brandonmpetty/doxa\"\n\n[tool.scikit-build]\ncmake.build-type = \"Release\"\nminimum-version = \"0.4\"\nbuild-dir = \"build/{wheel_tag}\"\nwheel.py-api = \"cp312\"\nsdist.include = [\n    \"src/Doxa\"  # Include all files in the Doxa directory\n]\nsdist.exclude = [\n    \"copy-cpp-files.py\",\n    \"DoxaPy.ipynb\",\n    \".gitignore\",\n    \"test\",\n    \"dist\"\n]\n\n[tool.cibuildwheel]\n# Necessary to see build output from the actual compilation\nbuild-verbosity = 1\n\n# Run tests to ensure correct builds\n#test-command = \"python test/test_doxa.py\"\n\narchs = [\"auto64\"]          # Only target 64 bit architectures"
  },
  {
    "path": "Bindings/Python/requirements.txt",
    "content": "numpy>=1.20.0\nPillow>=8.0.0\nbuild>=1.2.0"
  },
  {
    "path": "Bindings/Python/src/DoxaPy.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/ndarray.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/map.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/variant.h>\n\n#include \"Doxa/BinarizationFactory.hpp\"\n#include \"Doxa/ClassifiedPerformance.hpp\"\n#include \"Doxa/DRDM.hpp\"\n#include \"Doxa/DIBCOUtils.hpp\"\n#include \"Doxa/Grayscale.hpp\"\n\nnamespace nb = nanobind;\nusing namespace Doxa;\n\n// Nanobind helper for converting from an array to a Doxa Image. This will reference the array, not create a copy.\nImage ArrayToImage(const nb::ndarray<Pixel8, nb::ndim<2>>& imageArray)\n{\n\treturn Image::Reference(imageArray.shape(1), imageArray.shape(0), reinterpret_cast<Pixel8*>(imageArray.data()));\n}\n\nnb::dict CalculatePerformance(\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& groundTruthImageArray,\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& binaryImageArray,\n\tconst std::vector<double>& precisionWeights = {},\n\tconst std::vector<double>& recallWeights = {})\n{\n\tImage groundTruthImage = ArrayToImage(groundTruthImageArray);\n\tImage binaryImage = ArrayToImage(binaryImageArray);\n\n\tauto dict = nb::dict();\n\n\tClassifiedPerformance::Classifications classifications;\n\n\tif (!precisionWeights.empty() && !recallWeights.empty())\n\t\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage, precisionWeights, recallWeights);\n\telse\n\t\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\n\tdict[\"accuracy\"] = ClassifiedPerformance::CalculateAccuracy(classifications);\n\tdict[\"fm\"] = ClassifiedPerformance::CalculateFMeasure(classifications);\n\tdict[\"recall\"] = ClassifiedPerformance::CalculateRecall(classifications);\n\tdict[\"precision\"] = ClassifiedPerformance::CalculatePrecision(classifications);\n\tdict[\"mcc\"] = ClassifiedPerformance::CalculateMCC(classifications);\n\tdict[\"psnr\"] = ClassifiedPerformance::CalculatePSNR(classifications);\n\tdict[\"nrm\"] = ClassifiedPerformance::CalculateNRM(classifications);\n\n\tdict[\"drdm\"] = DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\n\tif (!precisionWeights.empty() && !recallWeights.empty())\n\t{\n\t\tdict[\"pseudo_fm\"] = ClassifiedPerformance::CalculatePseudoFMeasure(classifications);\n\t\tdict[\"pseudo_precision\"] = ClassifiedPerformance::CalculatePseudoPrecision(classifications);\n\t\tdict[\"pseudo_recall\"] = ClassifiedPerformance::CalculatePseudoRecall(classifications);\n\t}\n\n\treturn dict;\n}\n\nnb::dict CalculatePerformanceEx(\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& groundTruthImageArray,\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& binaryImageArray,\n\tbool accuracy = false,\n\tbool fm = false,\n\tbool recall = false,\n\tbool precision = false,\n\tbool mcc = false,\n\tbool psnr = false,\n\tbool nrm = false,\n\tbool drdm = false,\n\tbool pseudo_fm = false,\n\tbool pseudo_precision = false,\n\tbool pseudo_recall = false,\n\tconst std::vector<double>& precisionWeights = {},\n\tconst std::vector<double>& recallWeights = {})\n{\n\tImage groundTruthImage = ArrayToImage(groundTruthImageArray);\n\tImage binaryImage = ArrayToImage(binaryImageArray);\n\n\tauto dict = nb::dict();\n\n\tconst bool needsPseudo = (pseudo_fm || pseudo_precision || pseudo_recall)\n\t\t&& !precisionWeights.empty() && !recallWeights.empty();\n\n\tif (accuracy || fm || recall || precision || mcc || psnr || nrm || needsPseudo)\n\t{\n\t\tClassifiedPerformance::Classifications classifications;\n\n\t\tif (needsPseudo)\n\t\t\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage, precisionWeights, recallWeights);\n\t\telse\n\t\t\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\n\t\tif (accuracy)\n\t\t\tdict[\"accuracy\"] = ClassifiedPerformance::CalculateAccuracy(classifications);\n\n\t\tif (fm)\n\t\t\tdict[\"fm\"] = ClassifiedPerformance::CalculateFMeasure(classifications);\n\n\t\tif (recall)\n\t\t\tdict[\"recall\"] = ClassifiedPerformance::CalculateRecall(classifications);\n\n\t\tif (precision)\n\t\t\tdict[\"precision\"] = ClassifiedPerformance::CalculatePrecision(classifications);\n\n\t\tif (mcc)\n\t\t\tdict[\"mcc\"] = ClassifiedPerformance::CalculateMCC(classifications);\n\n\t\tif (psnr)\n\t\t\tdict[\"psnr\"] = ClassifiedPerformance::CalculatePSNR(classifications);\n\n\t\tif (nrm)\n\t\t\tdict[\"nrm\"] = ClassifiedPerformance::CalculateNRM(classifications);\n\n\t\tif (needsPseudo)\n\t\t{\n\t\t\tif (pseudo_fm)\n\t\t\t\tdict[\"pseudo_fm\"] = ClassifiedPerformance::CalculatePseudoFMeasure(classifications);\n\n\t\t\tif (pseudo_precision)\n\t\t\t\tdict[\"pseudo_precision\"] = ClassifiedPerformance::CalculatePseudoPrecision(classifications);\n\n\t\t\tif (pseudo_recall)\n\t\t\t\tdict[\"pseudo_recall\"] = ClassifiedPerformance::CalculatePseudoRecall(classifications);\n\t\t}\n\t}\n\n\tif (drdm)\n\t{\n\t\tdict[\"drdm\"] = DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\t}\n\n\treturn dict;\n}\n\nnb::ndarray<nb::numpy, Pixel8, nb::ndim<2>> ToGrayscale(\n\tGrayscaleAlgorithms algorithm,\n\tconst nb::ndarray<Pixel8, nb::ndim<3>>& colorImageArray)\n{\n\tconst int height = colorImageArray.shape(0);\n\tconst int width = colorImageArray.shape(1);\n\tconst int channels = colorImageArray.shape(2);\n\n\tPixel8* output = new Pixel8[width * height];\n\n\tGrayscale::ToGrayscale(\n\t\toutput,\n\t\treinterpret_cast<const Pixel8*>(colorImageArray.data()),\n\t\twidth, height, channels, algorithm);\n\n\t// Return an ND Array that will correctly manage the allocated memory\n\tconst size_t shape[2] = { (size_t)height, (size_t)width };\n\tnb::capsule owner(output, [](void* p) noexcept { delete[] static_cast<Pixel8*>(p); });\n\treturn nb::ndarray<nb::numpy, Pixel8, nb::ndim<2>>(output, 2, shape, owner);\n}\n\n/// <summary>\n/// Binarization is a helper class to help interface the C++ Doxa framework with Python.\n/// It exposes through enumeration all of the algorithms supported by the library.\n/// </summary>\nclass Binarization\n{\npublic:\n\tBinarization(const Algorithms algorithm)\n\t\t: algorithm(algorithm)\n\t{\n\t\talgorithmPtr = BinarizationFactory::Algorithm(algorithm);\n\t}\n\n\t~Binarization()\n\t{\n\t\tdelete algorithmPtr;\n\t}\n\n\tvoid Initialize(const nb::ndarray<Pixel8, nb::ndim<2>>& grayScaleImageArray)\n\t{\n\t\tImage image = ArrayToImage(grayScaleImageArray);\n\t\talgorithmPtr->Initialize(image);\n\t}\n\n\tvoid ToBinary(const nb::ndarray<Pixel8, nb::ndim<2>>& binaryImageArray, const ParameterMap& parameters={})\n\t{\n\t\tImage image = ArrayToImage(binaryImageArray);\n\t\talgorithmPtr->ToBinary(image, parameters);\n\t}\n\n\tAlgorithms CurrentAlgorithm() { return algorithm; }\n\nprotected:\n\tconst Algorithms algorithm;\n\tIAlgorithm* algorithmPtr = nullptr;\n}; // Class: Binarization\n\nnb::ndarray<nb::numpy, Pixel8, nb::ndim<2>> ToBinary(\n\tconst Algorithms algorithm,\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& grayImage,\n\tconst ParameterMap& parameters = {})\n{\n\tconst int height = grayImage.shape(0);\n\tconst int width = grayImage.shape(1);\n\n\t// Allocate new memory for the image data\n\tPixel8* binaryImage = new Pixel8[width * height];\n\n\t// Apply the algorithm\n\tconst Image grayImageRef = ArrayToImage(grayImage);\n\tImage binaryImageRef = Image::Reference(width, height, binaryImage);\n\n\tIAlgorithm* algorithmPtr = BinarizationFactory::Algorithm(algorithm);\n\talgorithmPtr->Initialize(grayImageRef);\n\talgorithmPtr->ToBinary(binaryImageRef, parameters);\n\tdelete algorithmPtr;\n\n\t// Return an ND Array that will correctly manage the allocated memory\n\tconst size_t shape[2] = { (size_t)height, (size_t)width };\n\tnb::capsule owner(binaryImage, [](void* p) noexcept { delete[] static_cast<Pixel8*>(p); });\n\treturn nb::ndarray<nb::numpy, Pixel8, nb::ndim<2>>(binaryImage, 2, shape, owner);\n}\n\nvoid UpdateToBinary(\n\tconst Algorithms algorithm,\n\tconst nb::ndarray<Pixel8, nb::ndim<2>>& imageArray,\n\tconst ParameterMap& parameters = {})\n{\n\tBinarization binAlg(algorithm);\n\tbinAlg.Initialize(imageArray);\n\tbinAlg.ToBinary(imageArray, parameters);\n}\n\n// Expose routines using the PEP8 style guide\nNB_MODULE(doxapy, m) {\n\tm.doc() = \"DoxaPy: Python bindings for the Doxa image binarization framework\";\n\n\tm.def(\"calculate_performance\", &CalculatePerformance,\n\t\tnb::arg(\"groundTruthImageArray\"),\n\t\tnb::arg(\"binaryImageArray\"),\n\t\tnb::arg(\"precision_weights\") = std::vector<double>{},\n\t\tnb::arg(\"recall_weights\") = std::vector<double>{},\n\t\t\"Obtain binarization performance information based on a Ground Truth. \"\n\t\t\"Optionally pass precision and recall weight arrays for pseudo-metrics.\");\n\n\tm.def(\"calculate_performance_ex\", &CalculatePerformanceEx,\n\t\tnb::arg(\"groundTruthImageArray\"),\n\t\tnb::arg(\"binaryImageArray\"),\n\t\tnb::arg(\"accuracy\") = false,\n\t\tnb::arg(\"fm\") = false,\n\t\tnb::arg(\"recall\") = false,\n\t\tnb::arg(\"precision\") = false,\n\t\tnb::arg(\"mcc\") = false,\n\t\tnb::arg(\"psnr\") = false,\n\t\tnb::arg(\"nrm\") = false,\n\t\tnb::arg(\"drdm\") = false,\n\t\tnb::arg(\"pseudo_fm\") = false,\n\t\tnb::arg(\"pseudo_precision\") = false,\n\t\tnb::arg(\"pseudo_recall\") = false,\n\t\tnb::arg(\"precision_weights\") = std::vector<double>{},\n\t\tnb::arg(\"recall_weights\") = std::vector<double>{},\n\t\t\"Obtain specific binarization performance information based on a Ground Truth. \"\n\t\t\"Pseudo-metrics require precision and recall weight arrays.\");\n\n\tnb::enum_<GrayscaleAlgorithms>(m, \"GrayscaleAlgorithms\")\n\t\t.value(\"MEAN\", GrayscaleAlgorithms::MEAN)\n\t\t.value(\"QT\", GrayscaleAlgorithms::QT)\n\t\t.value(\"BT601\", GrayscaleAlgorithms::BT601)\n\t\t.value(\"BT709\", GrayscaleAlgorithms::BT709)\n\t\t.value(\"BT2100\", GrayscaleAlgorithms::BT2100)\n\t\t.value(\"VALUE\", GrayscaleAlgorithms::VALUE)\n\t\t.value(\"LUSTER\", GrayscaleAlgorithms::LUSTER)\n\t\t.value(\"LIGHTNESS\", GrayscaleAlgorithms::LIGHTNESS)\n\t\t.value(\"MINAVG\", GrayscaleAlgorithms::MINAVG)\n\t\t.value(\"LABDIST\", GrayscaleAlgorithms::LABDIST)\n\t\t.export_values();\n\n\tm.def(\"to_grayscale\", &ToGrayscale,\n\t\tnb::arg(\"algorithm\"),\n\t\tnb::arg(\"color_image\"),\n\t\t\"Convert an RGB or RGBA image to 8-bit grayscale.\");\n\n\tm.def(\"to_binary\", &ToBinary,\n\t\tnb::arg(\"algorithm\"),\n\t\tnb::arg(\"image\"),\n\t\tnb::arg(\"parameters\") = ParameterMap(),\n\t\t\"Convert a grayscale image to binary, returning a new image.\");\n\n\tm.def(\"update_to_binary\", &UpdateToBinary,\n\t\tnb::arg(\"algorithm\"),\n\t\tnb::arg(\"image\"),\n\t\tnb::arg(\"parameters\") = ParameterMap(),\n\t\t\"Convert a grayscale image to binary in-place.\");\n\n\tnb::class_<Binarization> binarization(m, \"Binarization\");\n\n\tbinarization.def(nb::init<const Algorithms>())\n\t\t.def(\"initialize\", &Binarization::Initialize)\n\t\t.def(\"to_binary\", &Binarization::ToBinary,\n\t\t\tnb::arg(\"binaryImageArray\"),\n\t\t\tnb::arg(\"parameters\") = ParameterMap())\n\t\t.def(\"algorithm\", &Binarization::CurrentAlgorithm);\n\n\tnb::enum_<Algorithms>(binarization, \"Algorithms\")\n\t\t.value(\"OTSU\", Algorithms::OTSU)\n\t\t.value(\"BERNSEN\", Algorithms::BERNSEN)\n\t\t.value(\"NIBLACK\", Algorithms::NIBLACK)\n\t\t.value(\"SAUVOLA\", Algorithms::SAUVOLA)\n\t\t.value(\"WOLF\", Algorithms::WOLF)\n\t\t.value(\"NICK\", Algorithms::NICK)\n\t\t.value(\"SU\", Algorithms::SU)\n\t\t.value(\"TRSINGH\", Algorithms::TRSINGH)\n\t\t.value(\"BATAINEH\", Algorithms::BATAINEH)\n\t\t.value(\"ISAUVOLA\", Algorithms::ISAUVOLA)\n\t\t.value(\"WAN\", Algorithms::WAN)\n\t\t.value(\"GATOS\", Algorithms::GATOS)\n\t\t.value(\"ADOTSU\", Algorithms::ADOTSU)\n\t\t.value(\"PHANSALKAR\", Algorithms::PHANSALKAR)\n\t\t.export_values();\n}"
  },
  {
    "path": "Bindings/Python/src/doxapy/__init__.py",
    "content": "from .doxapy import *\n\n\ndef read_weights(file):\n    with open(file) as f:\n        return [float(x) for x in f.read().split()]\n"
  },
  {
    "path": "Bindings/Python/test/test_doxa.py",
    "content": "import unittest\nfrom PIL import Image, ImageChops\nimport numpy as np\nimport os\n\nimport sys\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dist')))\n\nimport doxapy\n\n# Get the absolute path to the RESOURCES directory (at project root)\nRESOURCES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'Doxa.Test', 'Resources'))\n\ndef read_image(file, algorithm=doxapy.GrayscaleAlgorithms.QT):\n    full_path = os.path.join(RESOURCES_DIR, os.path.basename(file))\n    image = Image.open(full_path)\n\n    # If already in grayscale or binary, do not convert it\n    if image.mode == 'L':\n        return np.array(image)\n    \n    # Read the color image\n    rgb_image = np.array(image.convert('RGB') if image.mode not in ('RGB', 'RGBA') else image)\n\n    # Use Doxa to convert to grayscale\n    return doxapy.to_grayscale(algorithm, rgb_image)\n\ndef read_weights(file):\n    full_path = os.path.join(RESOURCES_DIR, os.path.basename(file))\n    return doxapy.read_weights(full_path)\n\n\nclass DoxaPyTests(unittest.TestCase):\n    def test_binarization(self):\n\n        # Read in a color image, transforming it into a grayscale image\n        image = read_image(\"2JohnC1V3.ppm\")\n\n        # Create a new binary image\n        binary_image = np.empty(image.shape, image.dtype)\n\n        params = {\"window\": 27, \"k\": 0.10}\n        sauvola = doxapy.Binarization(doxapy.Binarization.Algorithms.SAUVOLA)\n        sauvola.initialize(image)\n        sauvola.to_binary(binary_image, params)\n\n        # Update the grayscale image to binary in-place\n        doxapy.update_to_binary(doxapy.Binarization.Algorithms.SAUVOLA, image, params)\n\n        # Ensure they are equal\n        self.assertTrue((binary_image == image).all())\n\n        # Compare against our control\n        expected_image_path = os.path.join(RESOURCES_DIR, os.path.basename(\"2JohnC1V3-Sauvola.pbm\"))\n        expected_image = Image.open(expected_image_path)\n        #expected_image.save(\"expected_image.png\")\n        \n        output_image = Image.fromarray(binary_image)\n        #output_image.save('output_image.png')\n\n        diff = ImageChops.difference(expected_image, output_image);\n        #diff.show()\n        self.assertIsNone(diff.getbbox())\n\n\n    def test_performance(self):\n\n        # Setup\n        image = read_image(\"2JohnC1V3.ppm\")\n        groundtruth_image = read_image(\"2JohnC1V3-GroundTruth.pbm\")\n        params = {\"window\": 27, \"k\": 0.10}\n        doxapy.update_to_binary(doxapy.Binarization.Algorithms.SAUVOLA, image, params)\n\n        # Functions under test\n        performanceAll = doxapy.calculate_performance(groundtruth_image, image)\n        performance = doxapy.calculate_performance_ex(groundtruth_image, image, drdm=True, psnr=True)\n\n        # Assert All\n        self.assertAlmostEqual(performanceAll.get(\"accuracy\"), 97.671, 2)\n        self.assertAlmostEqual(performanceAll.get(\"fm\"), 93.204, 2)\n        self.assertAlmostEqual(performanceAll.get(\"recall\"), 91.3811, 2)\n        self.assertAlmostEqual(performanceAll.get(\"precision\"), 95.1025, 2)\n        self.assertAlmostEqual(performanceAll.get(\"psnr\"), 16.329, 2)\n        self.assertAlmostEqual(performanceAll.get(\"nrm\"), 0.048, 2)\n        self.assertAlmostEqual(performanceAll.get(\"mcc\"), 0.918, 2)\n        self.assertAlmostEqual(performanceAll.get(\"drdm\"), 1.9519, 3)\n\n        # Assert Partial\n        self.assertEqual(performance.get(\"accuracy\"), None)\n        self.assertEqual(performance.get(\"fm\"), None)\n        self.assertEqual(performance.get(\"nrm\"), None)\n        self.assertEqual(performance.get(\"mcc\"), None)\n        self.assertEqual(performance.get(\"psnr\"), performanceAll.get(\"psnr\"))\n        self.assertEqual(performance.get(\"drdm\"), performanceAll.get(\"drdm\"))\n\n\n    def test_pseudo_performance(self):\n\n        # Setup\n        image = read_image(\"2JohnC1V3.ppm\")\n        groundtruth_image = read_image(\"2JohnC1V3-GroundTruth.pbm\")\n        params = {\"window\": 27, \"k\": 0.10}\n        doxapy.update_to_binary(doxapy.Binarization.Algorithms.SAUVOLA, image, params)\n\n        # Load pseudo weights\n        p_weights = read_weights(\"2JohnC1V3-GroundTruth_PWeights.dat\")\n        r_weights = read_weights(\"2JohnC1V3-GroundTruth_RWeights.dat\")\n\n        # Calculate performance with pseudo weights\n        performance = doxapy.calculate_performance(groundtruth_image, image, p_weights, r_weights)\n\n        # Assert pseudo metrics\n        self.assertAlmostEqual(performance.get(\"pseudo_fm\"), 93.393, 2)\n        self.assertAlmostEqual(performance.get(\"pseudo_recall\"), 92.7954, 2)\n        self.assertAlmostEqual(performance.get(\"pseudo_precision\"), 93.9983, 2)\n\n\nif __name__ == '__main__':\n    unittest.main()"
  },
  {
    "path": "Bindings/Python/test/test_speed.py",
    "content": "\"\"\"\nSpeed Tests for DoxaPy\n\nMeasures execution time for:\n- Sauvola binarization\n- WAN binarization\n- GlobalThresholding (Otsu) binarization\n- DRDM calculation\n- Classified Performance calculation\n\nRun with: python test_speed.py\n\"\"\"\n\nimport unittest\nimport time\nimport numpy as np\nfrom PIL import Image\nimport os\nimport sys\n\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dist')))\n\nimport doxapy\n\n# Get the absolute path to the RESOURCES directory\nRESOURCES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'Doxa.Test', 'Resources'))\n\n# Number of iterations for timing\nWARMUP_ITERATIONS = 3\nTIMING_ITERATIONS = 10\n\n\ndef read_image(file, algorithm=doxapy.GrayscaleAlgorithms.MEAN):\n    full_path = os.path.join(RESOURCES_DIR, os.path.basename(file))\n    image = Image.open(full_path)\n\n    # If already in grayscale or binary, do not convert it\n    if image.mode == 'L':\n        return np.array(image)\n    \n    # Read the color image\n    rgb_image = np.array(image.convert('RGB') if image.mode not in ('RGB', 'RGBA') else image)\n\n    # Use Doxa to convert to grayscale\n    return doxapy.to_grayscale(algorithm, rgb_image)\n\n\ndef measure_time(func, warmup=WARMUP_ITERATIONS, iterations=TIMING_ITERATIONS):\n    \"\"\"Measure execution time of a function.\"\"\"\n    # Warmup runs\n    for _ in range(warmup):\n        func()\n\n    # Timed runs\n    times = []\n    for _ in range(iterations):\n        start = time.perf_counter()\n        func()\n        end = time.perf_counter()\n        times.append((end - start) * 1000)  # Convert to ms\n\n    return {\n        'min': min(times),\n        'max': max(times),\n        'avg': sum(times) / len(times),\n        'median': sorted(times)[len(times) // 2]\n    }\n\n\ndef format_results(name, results, image_shape):\n    \"\"\"Format timing results as a string.\"\"\"\n    pixels = image_shape[0] * image_shape[1]\n    mpixels = pixels / 1_000_000\n    throughput = mpixels / (results['avg'] / 1000)\n    return (\n        f\"\\n{name}\\n\"\n        f\"  Image size: {image_shape[1]}x{image_shape[0]} ({mpixels:.2f} MP)\\n\"\n        f\"  Min:    {results['min']:8.3f} ms\\n\"\n        f\"  Max:    {results['max']:8.3f} ms\\n\"\n        f\"  Avg:    {results['avg']:8.3f} ms\\n\"\n        f\"  Median: {results['median']:8.3f} ms\\n\"\n        f\"  Throughput: {throughput:.2f} MP/s\"\n    )\n\n\nclass DoxaPySpeedTests(unittest.TestCase):\n\n    @classmethod\n    def setUpClass(cls):\n        \"\"\"Load test images once for all tests.\"\"\"\n        print(\"\\n\" + \"=\" * 60)\n        print(\"DoxaPy Speed Tests\")\n        print(\"=\" * 60)\n        print(f\"\\nWarmup iterations: {WARMUP_ITERATIONS}\")\n        print(f\"Timing iterations: {TIMING_ITERATIONS}\")\n        print(\"\\nLoading test images...\")\n\n        cls.image = read_image(\"2JohnC1V3.ppm\")\n        cls.groundtruth_image = read_image(\"2JohnC1V3-GroundTruth.pbm\")\n\n        print(f\"Grayscale image shape: {cls.image.shape}\")\n        print(f\"Ground truth shape: {cls.groundtruth_image.shape}\")\n\n        # Create a binary image for performance metric tests\n        cls.binary_image = np.empty(cls.image.shape, cls.image.dtype)\n        params = {\"window\": 27, \"k\": 0.10}\n        sauvola = doxapy.Binarization(doxapy.Binarization.Algorithms.SAUVOLA)\n        sauvola.initialize(cls.image)\n        sauvola.to_binary(cls.binary_image, params)\n\n        print(\"\\n\" + \"-\" * 60)\n        print(\"BINARIZATION ALGORITHMS\")\n        print(\"-\" * 60)\n\n    def test_sauvola_speed(self):\n        \"\"\"Measure Sauvola binarization speed.\"\"\"\n        binary_image = np.empty(self.image.shape, self.image.dtype)\n        params = {\"window\": 75, \"k\": 0.2}\n\n        sauvola = doxapy.Binarization(doxapy.Binarization.Algorithms.SAUVOLA)\n        sauvola.initialize(self.image)\n\n        def run():\n            sauvola.to_binary(binary_image, params)\n\n        results = measure_time(run)\n        print(format_results(\"Sauvola\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    def test_wan_speed(self):\n        \"\"\"Measure WAN binarization speed.\"\"\"\n        binary_image = np.empty(self.image.shape, self.image.dtype)\n        params = {\"window\": 75, \"k\": 0.2}\n\n        wan = doxapy.Binarization(doxapy.Binarization.Algorithms.WAN)\n        wan.initialize(self.image)\n\n        def run():\n            wan.to_binary(binary_image, params)\n\n        results = measure_time(run)\n        print(format_results(\"WAN\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    def test_otsu_speed(self):\n        \"\"\"Measure Otsu (GlobalThresholding) binarization speed.\"\"\"\n        binary_image = np.empty(self.image.shape, self.image.dtype)\n        params = {}\n\n        otsu = doxapy.Binarization(doxapy.Binarization.Algorithms.OTSU)\n        otsu.initialize(self.image)\n\n        def run():\n            otsu.to_binary(binary_image, params)\n\n        results = measure_time(run)\n        print(format_results(\"Otsu (GlobalThresholding)\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    def test_drdm_speed(self):\n        \"\"\"Measure DRDM calculation speed.\"\"\"\n        print(\"\\n\" + \"-\" * 60)\n        print(\"PERFORMANCE METRICS\")\n        print(\"-\" * 60)\n\n        def run():\n            doxapy.calculate_performance_ex(self.groundtruth_image, self.binary_image, drdm=True)\n\n        results = measure_time(run)\n        print(format_results(\"DRDM\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    def test_classified_performance_speed(self):\n        \"\"\"Measure Classified Performance calculation speed (all metrics except DRDM).\"\"\"\n        def run():\n            doxapy.calculate_performance_ex(\n                self.groundtruth_image, self.binary_image,\n                accuracy=True, fm=True, psnr=True, nrm=True, mcc=True\n            )\n\n        results = measure_time(run)\n        print(format_results(\"ClassifiedPerformance (no DRDM)\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    def test_full_performance_speed(self):\n        \"\"\"Measure full performance calculation speed (all metrics including DRDM).\"\"\"\n        def run():\n            doxapy.calculate_performance(self.groundtruth_image, self.binary_image)\n\n        results = measure_time(run)\n        print(format_results(\"Full Performance (all metrics)\", results, self.image.shape))\n        self.assertGreater(results['avg'], 0)\n\n    @classmethod\n    def tearDownClass(cls):\n        print(\"\\n\" + \"=\" * 60)\n        print(\"Speed tests completed\")\n        print(\"=\" * 60)\n\n\nif __name__ == '__main__':\n    unittest.main(verbosity=2)\n"
  },
  {
    "path": "Bindings/WebAssembly/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(doxajs)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# This file is only used when building with Emscripten\nif(NOT EMSCRIPTEN)\n    message(FATAL_ERROR \"This CMakeLists.txt requires Emscripten. Use: emcmake cmake ..\")\nendif()\n\noption(DOXAJS_ENABLE_SIMD \"Enable WASM SIMD128\" ON)\n\n# Include Doxa headers\ninclude_directories(${CMAKE_SOURCE_DIR}/Doxa)\n\n# Create WASM module\nadd_executable(doxaWasm DoxaWasm.cpp)\n\n# Emscripten compile/link flags (matches build.js)\ntarget_compile_options(doxaWasm PRIVATE\n    $<IF:$<CONFIG:Debug>,-O0,-O3>\n    $<$<CONFIG:Debug>:-g>\n)\n\ntarget_link_options(doxaWasm PRIVATE\n    -sWASM=1\n    -sNO_EXIT_RUNTIME=1\n    -sALLOW_MEMORY_GROWTH=1\n    \"-sEXPORTED_FUNCTIONS=['_malloc','_free']\"\n    \"-sEXPORTED_RUNTIME_METHODS=['HEAPU8']\"\n    --bind\n    # Debug-only options\n    $<$<CONFIG:Debug>:-sEXCEPTION_DEBUG>\n    $<$<CONFIG:Debug>:-sNO_DISABLE_EXCEPTION_CATCHING>\n    $<$<CONFIG:Debug>:-g4>\n    \"$<$<CONFIG:Debug>:--source-map-base=http://localhost:8080/>\"\n)\n\n# SIMD support\nif(DOXAJS_ENABLE_SIMD)\n    target_compile_options(doxaWasm PRIVATE -msimd128)\n    message(STATUS \"DoxaJs SIMD: ENABLED (SIMD128)\")\nelse()\n    message(STATUS \"DoxaJs SIMD: DISABLED\")\nendif()\n\n# Output to dist/ directory\nset_target_properties(doxaWasm PROPERTIES\n    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dist\n)\n\n# Copy JavaScript wrapper after build\nadd_custom_command(TARGET doxaWasm POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E copy\n        ${CMAKE_CURRENT_SOURCE_DIR}/doxa.js\n        ${CMAKE_CURRENT_SOURCE_DIR}/dist/doxa.js\n    COMMENT \"Copying doxa.js wrapper to dist/\"\n)\n\n# CTest integration - run Jasmine tests via Node\ninclude(CTest)\nenable_testing()\n\n# Platform-specific script extension (avoid picking up .cmd on WSL2)\nif(WIN32)\n    set(CMD_EXT \".cmd\")\nelse()\n    set(CMD_EXT \"\")\nendif()\n\nfind_program(NPM_EXECUTABLE NAMES npm${CMD_EXT})\n\nif(NPM_EXECUTABLE)\n    add_test(NAME wasm_tests\n        COMMAND ${NPM_EXECUTABLE} test\n        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n    )\nendif()\n"
  },
  {
    "path": "Bindings/WebAssembly/DoxaJs.nnb",
    "content": "{\n    \"cells\": [\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"# DoxaJs Notebook\\r\\n\\r\\nhttps://github.com/brandonmpetty/Doxa\\r\\n\\r\\nDoxaJs is an image binarization library focused on local adaptive algorithms and metrics.\\r\\nThis notebook will document the API while allowing you to interact with it.\\r\\nIt was designed in VS Code using the \\\"Node.js Notebooks (REPL)\\\" notebook kernel.\\r\\n\\r\\n## Setup\\r\\nDoxaJs does not currently have an NPM package you can download, but distributables are packaged in this repo.  To run the notebook, you first need to install dev dependencies like'sharp'.\\r\\n\\r\\n```\\r\\nnpm install\\r\\n```\\r\\n\\r\\nThe next thing you should do is to load the **doxa.js** module.  It is actually a wrapper around WASM assets built with EMScripten and the C++ based Doxa binarization framework.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"const { Doxa } = require('./dist/doxa.js');\\r\\nconst { display }  = require('node-kernel');\\r\\nconst sharp = require('sharp');\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"While this demo highlights NodeJs with *sharp*, a Web demo is also available leveraging the standard HTML5 canvas.\\r\\nBelow are two helper functions leveraging *sharp*.  Unlike other language targets of Doxa, DoxaJs will actually take in a 32 RGBA image and convert it to grayscale automatically.  This approach was prefered due to the demands of 32b images when working with web technologies.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"// Read an image file and convert it to an 8-bit grayscale Doxa Image\\r\\nasync function readImage(file) {\\r\\n\\treturn sharp(file)\\r\\n\\t\\t.raw()\\r\\n\\t\\t.toBuffer({ resolveWithObject: true })\\r\\n\\t\\t.then(content => {\\r\\n\\t\\t\\treturn new Doxa.Image(content.info.width, content.info.height, content.data);\\r\\n\\t\\t});\\r\\n}\\r\\n\\r\\n// Add Notebook display support for Doxa Images\\r\\ndisplay.dimage = (image) => {\\r\\n\\treturn sharp(image.data(), {\\r\\n\\t\\traw: {\\r\\n\\t\\t\\twidth: image.width,\\r\\n\\t\\t\\theight: image.height,\\r\\n\\t\\t\\tchannels: 1\\r\\n\\t\\t}\\r\\n\\t})\\r\\n\\t.png()\\r\\n\\t.toBuffer()\\r\\n\\t.then((buf) => {\\r\\n\\t\\tdisplay.image(buf);\\r\\n\\t});\\r\\n}\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"Because the JS bindings are leveraging WASM for portability and speed, the library must be initialized to register the WASM.  Once initialized it will return back an enum object that represents all of the binarization algorithms available in the library.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"const Algorithms = await Doxa.initialize();\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"## Reading an Image\\r\\nThe next step is to read in an image.  At the heart of a Doxa Image is an 8-bit byte array.  Your 32-bit color or grayscale image will be converted to an 8-bit image using the mean of the R-G-B channels.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"// A snippet from a 1500 year Greek codex, hand written on velum.\\r\\nconst image = await readImage('../../README/2JohnC1V3.png');\\r\\n\\r\\ndisplay.dimage(image);\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"## Converting the Image to Binary\\r\\nConverting an image into black and white may seem easy, but it has been the focus of much research spanning decades.  Doxa was designed to expose this research, traditionally mired by PHD technical jargon, in a very easy to consume fashion.  A lot of work was put into ensuring these algorithms were implemented correctly and effeciently.  Many of these algorithms were first made public by this project and many of them leverage state of the art enhacements to reduce memory utilization and increase speed of operation, found nowhere else.  For more information on an individual algorithm, click one of the links below.\\r\\n\\r\\n### Algorithms\\r\\nThe Doxa library implements a large number of popular and unique local adaptive binarization algorithms.  Each algorithm has a set of parameters that are required for it to operate.  These parameters can vary from algorithm to algorithm.  Doxa provides sensible defaults that are applied automatically unless you supply your own.  Below is a list of algorithms and their defaults:\\r\\n\\r\\n* **OTSU**\\r\\n* **BERNSEN** - {\\\"window\\\": 75, \\\"threshold\\\": 100, \\\"contrast-limit\\\": 25}\\r\\n* **NIBLACK** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **SAUVOLA** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **WOLF** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **NICK** - {\\\"window\\\": 75, \\\"k\\\": -0.2}\\r\\n* **SU** - {\\\"window\\\": 9, \\\"minN\\\": 9}\\r\\n* **TRSINGH** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **BATAINEH**\\r\\n* **ISAUVOLA** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **WAN** - {\\\"window\\\": 75, \\\"k\\\": 0.2}\\r\\n* **GATOS** - {\\\"window\\\": 75, \\\"k\\\": 0.2, \\\"glyph\\\": 60}\\r\\n* **ADOTSU** - {\\\"window\\\": 75, \\\"k\\\": 1.0, \\\"R\\\": 0.1, \\\"distance\\\": window/2}\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"const binaryImage = Doxa.Binarization.toBinary(Algorithms.SAUVOLA, image, { window: 27, k: 0.12 });\\r\\n\\r\\ndisplay.dimage(binaryImage);\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"## Performance Metrics\\r\\nIn order to analyze the performance of an algorithm, Doxa provides a set of common metrics that can all be calculated with one function.  To start that process you need an exemplar binary image, or \\\"ground truth.\\\"  By comparing the ground truth to the resulting image of the binarization algorithm, you can start to compare the affects of different algorithms and algorithm parameters.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"const groundTruthImage = await readImage('../../README/2JohnC1V3-GroundTruth.png');\\r\\n\\r\\ndisplay.dimage(groundTruthImage);\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"const perf = Doxa.Binarization.calculatePerformance(groundTruthImage, binaryImage);\\r\\n\\r\\nconsole.dir(perf);\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"markdown\",\n            \"source\": [\n                \"## Freeing Resources\\r\\nUnlike Javascript, Web Assembly (WASM) is not as forgiving when it comes to resource management.  When memory is allocated in the WASM system it must be freed, much like traditional C/C++ code.  While this may not be critical for short lived executions, it is best practice to free the image resources when you are finished with them.\"\n            ],\n            \"outputs\": []\n        },\n        {\n            \"language\": \"javascript\",\n            \"source\": [\n                \"groundTruthImage.free();\\r\\nimage.free();\"\n            ],\n            \"outputs\": []\n        }\n    ]\n}"
  },
  {
    "path": "Bindings/WebAssembly/DoxaWasm.cpp",
    "content": "#include <emscripten/emscripten.h>\n#include <emscripten/bind.h>\n#include <sstream>\n//#include <iostream>\n\n#include \"../../Doxa/BinarizationFactory.hpp\"\n#include \"../../Doxa/ClassifiedPerformance.hpp\"\n#include \"../../Doxa/DRDM.hpp\"\n#include \"../../Doxa/DIBCOUtils.hpp\"\n#include \"../../Doxa/Grayscale.hpp\"\n\n//#include \"../Doxa/PNM.hpp\"\nusing namespace Doxa;\nusing namespace emscripten;\n\n/// <summary>\n/// Structure for measuring performance characteristics of the different algorithms\n/// </summary>\nstruct Performance\n{\n\tdouble Accuracy;\n\tdouble FM;\n\tdouble Recall;\n\tdouble Precision;\n\tdouble MCC;\n\tdouble PSNR;\n\tdouble NRM;\n\tdouble DRDM;\n};\n\n/// <summary>\n/// Structure for measuring pseudo performance characteristics, including standard and pseudo metrics\n/// </summary>\nstruct PseudoPerformance\n{\n\tdouble Accuracy;\n\tdouble FM;\n\tdouble Recall;\n\tdouble Precision;\n\tdouble MCC;\n\tdouble PSNR;\n\tdouble NRM;\n\tdouble DRDM;\n\tdouble PseudoFM;\n\tdouble PseudoPrecision;\n\tdouble PseudoRecall;\n};\n\nPerformance CalculatePerformance(intptr_t groundTruthData, intptr_t binaryData, const int width, const int height)\n{\n\tImage groundTruthImage = Image::Reference(width, height, reinterpret_cast<Pixel8*>(groundTruthData));\n\tImage binaryImage = Image::Reference(width, height, reinterpret_cast<Pixel8*>(binaryData));\n\t\n\tClassifiedPerformance::Classifications classifications;\n\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\t// TODO: If this fails, we may want to 0 out the return values\n\n\tPerformance perf;\n\tperf.Accuracy = ClassifiedPerformance::CalculateAccuracy(classifications);\n\tperf.FM = ClassifiedPerformance::CalculateFMeasure(classifications);\n\tperf.Recall = ClassifiedPerformance::CalculateRecall(classifications);\n\tperf.Precision = ClassifiedPerformance::CalculatePrecision(classifications);\n\tperf.MCC = ClassifiedPerformance::CalculateMCC(classifications);\n\tperf.PSNR = ClassifiedPerformance::CalculatePSNR(classifications);\n\tperf.NRM = ClassifiedPerformance::CalculateNRM(classifications);\n\tperf.DRDM = DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\n\treturn perf;\n}\n\n\nPseudoPerformance CalculatePseudoPerformance(\n\tintptr_t groundTruthData, intptr_t binaryData,\n\tconst int width, const int height,\n\tconst std::string& precisionWeightsText,\n\tconst std::string& recallWeightsText)\n{\n\tImage groundTruthImage = Image::Reference(width, height, reinterpret_cast<Pixel8*>(groundTruthData));\n\tImage binaryImage = Image::Reference(width, height, reinterpret_cast<Pixel8*>(binaryData));\n\n\t// Parse weight text via DIBCOUtils\n\tstd::stringstream precisionStream(precisionWeightsText);\n\tstd::stringstream recallStream(recallWeightsText);\n\tconst size_t allocatedSize = static_cast<size_t>(width) * height;\n\tauto precisionWeights = DIBCOUtils::ReadWeights(precisionStream, allocatedSize);\n\tauto recallWeights = DIBCOUtils::ReadWeights(recallStream, allocatedSize);\n\n\t// Compute weighted classifications\n\tClassifiedPerformance::Classifications classifications;\n\tClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage, precisionWeights, recallWeights);\n\n\tPseudoPerformance perf;\n\tperf.Accuracy = ClassifiedPerformance::CalculateAccuracy(classifications);\n\tperf.FM = ClassifiedPerformance::CalculateFMeasure(classifications);\n\tperf.Recall = ClassifiedPerformance::CalculateRecall(classifications);\n\tperf.Precision = ClassifiedPerformance::CalculatePrecision(classifications);\n\tperf.MCC = ClassifiedPerformance::CalculateMCC(classifications);\n\tperf.PSNR = ClassifiedPerformance::CalculatePSNR(classifications);\n\tperf.NRM = ClassifiedPerformance::CalculateNRM(classifications);\n\tperf.DRDM = DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\tperf.PseudoFM = ClassifiedPerformance::CalculatePseudoFMeasure(classifications);\n\tperf.PseudoPrecision = ClassifiedPerformance::CalculatePseudoPrecision(classifications);\n\tperf.PseudoRecall = ClassifiedPerformance::CalculatePseudoRecall(classifications);\n\n\treturn perf;\n}\n\n\nvoid ToGrayscale(intptr_t outputData, intptr_t inputData,\n\tint width, int height, int channels, GrayscaleAlgorithms algorithm)\n{\n\tGrayscale::ToGrayscale(\n\t\treinterpret_cast<Pixel8*>(outputData),\n\t\treinterpret_cast<const Pixel8*>(inputData),\n\t\twidth, height, channels, algorithm);\n}\n\n\n/// <summary>\n/// Binarization is a helper class to help interface the C++ Doxa framework with WebAssembly.\n/// It exposes through enumeration all of the algorithms supported by the library.\n/// The Doxa.js code wraps the exported symbols to make it easier to use in JavaScript.\n/// </summary>\nclass Binarization\n{\npublic:\n\t\n\tBinarization(const Algorithms algorithm)\n\t: algorithm(algorithm)\n\t{\n\t\talgorithmPtr = BinarizationFactory::Algorithm(algorithm);\n\t}\n\t\n\t~Binarization()\n\t{\n\t\tdelete algorithmPtr;\n\t}\n\t\n\tvoid Initialize(intptr_t data, const int width, const int height)\n\t{\t\t\n\t\t// Set width and height\n\t\tthis->width = width;\n\t\tthis->height = height;\n\t\t\n\t\tImage image = Image::Reference(width, height, reinterpret_cast<Pixel8*>(data));\n\t\talgorithmPtr->Initialize(image);\n\t}\n\t\n\tvoid ToBinary(intptr_t data, const std::string& params)\n\t{\n\t\tImage image = Image::Reference(this->width, this->height, reinterpret_cast<Pixel8*>(data));\n\t\talgorithmPtr->ToBinary(image, Parameters::FromJson(params));\n\t}\n\t\n\tAlgorithms CurrentAlgorithm() { return algorithm; }\n\n/*\n\tstatic void Debug(Pixel8* data, const int width, const int height)\n\t{\n\t\tstd::cout << \"Debug - start (\" << width << \"x\" << height << \")\" << std::endl;\n\t\tconst size_t size = width * height;\n\n\t\tfor (size_t idx = 0; idx < size; ++idx)\n\t\t{\n\t\t\tconst Pixel8 pixel = data[idx];\n\t\t\t\n\t\t\tstd::cout \n\t\t\t\t<< \"Index: \" << idx << \" Value: \" << std::to_string(pixel) << std::endl;\n\t\t}\n\t\t\n\t\tdata[0] = 42; // Verify the ability to set\n\t\tstd::cout << \"Debug - stop\" << std::endl;\n\t}\n*/\nprotected:\n\tconst Algorithms algorithm;\n\tIAlgorithm* algorithmPtr = nullptr;\n\tint width = 0;\n\tint height = 0;\n}; // Class: Binarization\n\n\n\nEMSCRIPTEN_BINDINGS(doxa_wasm) {\n\tclass_<Binarization>(\"Binarization\")\n\t\t.constructor<Algorithms>()\n\t\t.function(\"initialize\", &Binarization::Initialize, allow_raw_pointers())\n\t\t.function(\"toBinary\", &Binarization::ToBinary, allow_raw_pointers())\n\t\t.function(\"currentAlgorithm\", &Binarization::CurrentAlgorithm);\n\tenum_<Algorithms>(\"Binarization.Algorithms\")\n\t\t.value(\"OTSU\", Algorithms::OTSU)\n\t\t.value(\"BERNSEN\", Algorithms::BERNSEN)\n\t\t.value(\"NIBLACK\", Algorithms::NIBLACK)\n\t\t.value(\"SAUVOLA\", Algorithms::SAUVOLA)\n\t\t.value(\"WOLF\", Algorithms::WOLF)\n\t\t.value(\"NICK\", Algorithms::NICK)\n\t\t.value(\"ADOTSU\", Algorithms::ADOTSU)\n\t\t.value(\"SU\", Algorithms::SU)\n\t\t.value(\"TRSINGH\", Algorithms::TRSINGH)\n\t\t.value(\"BATAINEH\", Algorithms::BATAINEH)\n\t\t.value(\"ISAUVOLA\", Algorithms::ISAUVOLA)\n\t\t.value(\"WAN\", Algorithms::WAN)\n\t\t.value(\"GATOS\", Algorithms::GATOS)\n\t\t.value(\"PHANSALKAR\", Algorithms::PHANSALKAR);\n    EM_ASM(\n        Module['Binarization']['Algorithms'] = Module['Binarization.Algorithms'];\n        delete Module['Binarization.Algorithms'];\n    );\n\n\tvalue_object<Performance>(\"Performance\")\n\t\t.field(\"accuracy\", &Performance::Accuracy)\n\t\t.field(\"fm\", &Performance::FM)\n\t\t.field(\"recall\", &Performance::Recall)\n\t\t.field(\"precision\", &Performance::Precision)\n\t\t.field(\"mcc\", &Performance::MCC)\n\t\t.field(\"psnr\", &Performance::PSNR)\n\t\t.field(\"nrm\", &Performance::NRM)\n\t\t.field(\"drdm\", &Performance::DRDM);\n\tfunction(\"calculatePerformance\", &CalculatePerformance, allow_raw_pointers());\n\n\tvalue_object<PseudoPerformance>(\"PseudoPerformance\")\n\t\t.field(\"accuracy\", &PseudoPerformance::Accuracy)\n\t\t.field(\"fm\", &PseudoPerformance::FM)\n\t\t.field(\"recall\", &PseudoPerformance::Recall)\n\t\t.field(\"precision\", &PseudoPerformance::Precision)\n\t\t.field(\"mcc\", &PseudoPerformance::MCC)\n\t\t.field(\"psnr\", &PseudoPerformance::PSNR)\n\t\t.field(\"nrm\", &PseudoPerformance::NRM)\n\t\t.field(\"drdm\", &PseudoPerformance::DRDM)\n\t\t.field(\"pseudoFM\", &PseudoPerformance::PseudoFM)\n\t\t.field(\"pseudoPrecision\", &PseudoPerformance::PseudoPrecision)\n\t\t.field(\"pseudoRecall\", &PseudoPerformance::PseudoRecall);\n\tfunction(\"calculatePseudoPerformance\", &CalculatePseudoPerformance, allow_raw_pointers());\n\n\tenum_<GrayscaleAlgorithms>(\"Grayscale.Algorithms\")\n\t\t.value(\"MEAN\", GrayscaleAlgorithms::MEAN)\n\t\t.value(\"QT\", GrayscaleAlgorithms::QT)\n\t\t.value(\"BT601\", GrayscaleAlgorithms::BT601)\n\t\t.value(\"BT709\", GrayscaleAlgorithms::BT709)\n\t\t.value(\"BT2100\", GrayscaleAlgorithms::BT2100)\n\t\t.value(\"VALUE\", GrayscaleAlgorithms::VALUE)\n\t\t.value(\"LUSTER\", GrayscaleAlgorithms::LUSTER)\n\t\t.value(\"LIGHTNESS\", GrayscaleAlgorithms::LIGHTNESS)\n\t\t.value(\"MINAVG\", GrayscaleAlgorithms::MINAVG)\n\t\t.value(\"LABDIST\", GrayscaleAlgorithms::LABDIST);\n\tEM_ASM(\n\t\tModule['Grayscale'] = { 'Algorithms': Module['Grayscale.Algorithms'] };\n\t\tdelete Module['Grayscale.Algorithms'];\n\t);\n\tfunction(\"toGrayscale\", &ToGrayscale, allow_raw_pointers());\n};"
  },
  {
    "path": "Bindings/WebAssembly/README.md",
    "content": "# Δoxa Binarization Framework - WebAssembly\n\n## Introduction\nThis is an **experimental** project that exposes the ΔBF, written in C++, to JavaScript via WebAssembly.  It works both server side and client side.  For a simple example of how it works, checkout the [WebJS](../../Demo/WebJS) and [NodeJS](../../Demo/NodeJS) demos.\n\nA Visual Studio Code [Notebook](./DoxaJs.nnb) was developed to easily test and document the API.  It uses the *Node.js Notebooks (REPL)* kernel.\n\n## Building\n\nDoxaJs is built using CMake with the Emscripten toolchain. You must have [Emscripten](https://emscripten.org/docs/getting_started/downloads.html) installed and available in your path.\n\n### Using npm (Recommended)\n\n```bash\ncd Bindings/WebAssembly\nnpm install\n\n# Release build\nnpm run build\n\n# Debug build (with source maps and exception debugging)\nnpm run build:dev\n\n# Run tests\nnpm test\n```\n\n### Using CMake\n\n```bash\n# From project root\ncmake --preset wasm\ncmake --build build-wasm --config Release\nnpm install --prefix Bindings/WebAssembly\nctest --test-dir build-wasm -C Release\n```\n\n### Run the Web Demo\n\n```bash\nemrun --no_browser --port 8080 .\n# Navigate to: http://localhost:8080/Demo/WebJS\n```\n\n\n## License\nCC0 - Brandon M. Petty, 2023\n\nTo the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.\n\n[View Online](https://creativecommons.org/publicdomain/zero/1.0/legalcode)\n\n\"*Freely you have received; freely give.*\" - Matt 10:8"
  },
  {
    "path": "Bindings/WebAssembly/dist/doxa.js",
    "content": "/**\n * Doxa WASM\n * A set of classes that further simplify the Doxa WASM interface.\n * This same wrapper can be run in NodeJS or directly in the web.\n * See Demo/WebJs and Demo/NodeJS for an example of how to use it.\n */\n\nconst Doxa = {\n\n\tWasm: (typeof Module !== 'undefined') ? Module : require('./doxaWasm.js'),\n\n\tinitialize: async function() {\n\t\tif (!Doxa.Wasm) throw new Error('Missing: Doxa WASM Module');\n\n\t\t// Extract enum values from an Emscripten enum object\n\t\tconst extractEnums = function(enumObj) {\n\t\t\tconst enums = {};\n\t\t\tfor (const key in enumObj) {\n\t\t\t\tconst entry = enumObj[key];\n\t\t\t\tif (entry?.value === undefined) continue;\n\t\t\t\tenums[key] = entry.value;\n\t\t\t}\n\t\t\treturn enums;\n\t\t}\n\n\t\tconst buildInstance = function() {\n\t\t\tconst instance = {\n\t\t\t\tbinarization: extractEnums(Doxa.Wasm.Binarization.Algorithms),\n\t\t\t\tgrayscale: extractEnums(Doxa.Wasm.Grayscale.Algorithms),\n\n\t\t\t\t/**\n\t\t\t\t * Convert raw pixel data to an 8-bit grayscale Doxa.Image.\n\t\t\t\t * If the data is already single-channel, it is copied directly.\n\t\t\t\t * @param {Uint8Array|Uint8ClampedArray} data - Raw pixel data (1, 3, or 4 channels)\n\t\t\t\t * @param {number} width - Image width\n\t\t\t\t * @param {number} height - Image height\n\t\t\t\t * @param {number} channels - 1 for grayscale, 3 for RGB, 4 for RGBA\n\t\t\t\t * @param {number} algorithm - Grayscale algorithm enum value (e.g. doxa.grayscale.MEAN). Defaults to MEAN.\n\t\t\t\t * @returns {Doxa.Image} 8-bit grayscale image (caller must free)\n\t\t\t\t */\n\t\t\t\ttoGrayscale: function(data, width, height, channels, algorithm) {\n\t\t\t\t\t// Already grayscale — just copy directly\n\t\t\t\t\tif (channels === 1) {\n\t\t\t\t\t\treturn new Doxa.Image(width, height, data);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Allocate WASM heap for input\n\t\t\t\t\tconst inputSize = width * height * channels;\n\t\t\t\t\tconst inputPtr = Doxa.Wasm._malloc(inputSize);\n\t\t\t\t\tDoxa.Wasm.HEAPU8.set(data.subarray(0, inputSize), inputPtr);\n\n\t\t\t\t\t// Allocate output image\n\t\t\t\t\tconst outputImage = new Doxa.Image(width, height);\n\n\t\t\t\t\tconst algEnum = Doxa.Wasm.Grayscale.Algorithms.values[\n\t\t\t\t\t\talgorithm ?? instance.grayscale.MEAN\n\t\t\t\t\t];\n\t\t\t\t\tDoxa.Wasm.toGrayscale(outputImage.heapPtr, inputPtr, width, height, channels, algEnum);\n\n\t\t\t\t\t// Free input buffer\n\t\t\t\t\tDoxa.Wasm._free(inputPtr);\n\n\t\t\t\t\treturn outputImage;\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Convert an HTML5 Canvas ImageData to an 8-bit grayscale Doxa.Image.\n\t\t\t\t * Convenience wrapper for browser usage.\n\t\t\t\t * @param {ImageData} imageData - Canvas ImageData (32-bit RGBA)\n\t\t\t\t * @param {number} algorithm - Grayscale algorithm enum value (e.g. doxa.grayscale.MEAN). Defaults to MEAN.\n\t\t\t\t * @returns {Doxa.Image} 8-bit grayscale image (caller must free)\n\t\t\t\t */\n\t\t\t\tfromImageData: function(imageData, algorithm) {\n\t\t\t\t\treturn instance.toGrayscale(\n\t\t\t\t\t\timageData.data, imageData.width, imageData.height, 4, algorithm\n\t\t\t\t\t);\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Binarize a grayscale image using the specified algorithm.\n\t\t\t\t * @param {number} algorithm - Binarization algorithm enum value (e.g. doxa.binarization.SAUVOLA)\n\t\t\t\t * @param {Doxa.Image} imageIn - Input grayscale image\n\t\t\t\t * @param {object} parameters - Algorithm parameters (e.g. { window: 75, k: 0.2 })\n\t\t\t\t * @param {Doxa.Image} imageOut - Optional output image (allocated if not provided)\n\t\t\t\t * @returns {Doxa.Image} Binary image (caller must free if newly allocated)\n\t\t\t\t */\n\t\t\t\ttoBinary: function(algorithm, imageIn, parameters, imageOut) {\n\t\t\t\t\tif (!imageOut) {\n\t\t\t\t\t\timageOut = new Doxa.Image(imageIn.width, imageIn.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst algEnum = Doxa.Wasm.Binarization.Algorithms.values[algorithm];\n\t\t\t\t\tconst paramString = JSON.stringify(parameters || {});\n\t\t\t\t\tconst binarization = new Doxa.Wasm.Binarization(algEnum);\n\n\t\t\t\t\tbinarization.initialize(imageIn.heapPtr, imageIn.width, imageIn.height);\n\t\t\t\t\tbinarization.toBinary(imageOut.heapPtr, paramString);\n\n\t\t\t\t\treturn imageOut;\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Calculate performance metrics comparing a binary image against ground truth.\n\t\t\t\t * If precision/recall weight texts are provided, pseudo metrics are included.\n\t\t\t\t * @param {Doxa.Image} groundTruth - Ground truth binary image\n\t\t\t\t * @param {Doxa.Image} binary - Binary image to evaluate\n\t\t\t\t * @param {string} precisionWeightsText - Optional precision weights (enables pseudo metrics)\n\t\t\t\t * @param {string} recallWeightsText - Optional recall weights (enables pseudo metrics)\n\t\t\t\t * @returns {object} Performance metrics (accuracy, fm, precision, recall, mcc, psnr, nrm, drdm, and optionally pseudoFM, pseudoPrecision, pseudoRecall)\n\t\t\t\t */\n\t\t\t\tcalculatePerformance: function(groundTruth, binary, precisionWeightsText, recallWeightsText) {\n\t\t\t\t\tif (precisionWeightsText && recallWeightsText) {\n\t\t\t\t\t\treturn Doxa.Wasm.calculatePseudoPerformance(\n\t\t\t\t\t\t\tgroundTruth.heapPtr, binary.heapPtr,\n\t\t\t\t\t\t\tbinary.width, binary.height,\n\t\t\t\t\t\t\tprecisionWeightsText, recallWeightsText\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Doxa.Wasm.calculatePerformance(\n\t\t\t\t\t\tgroundTruth.heapPtr, binary.heapPtr,\n\t\t\t\t\t\tbinary.width, binary.height\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn instance;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\t// Ensure the library has not already been initialized\n\t\t\tif (typeof Doxa.Wasm.Binarization !== 'undefined') {\n\t\t\t\treturn resolve(buildInstance());\n\t\t\t}\n\n\t\t\tDoxa.Wasm.onRuntimeInitialized = async _ => {\n\t\t\t\tresolve(buildInstance());\n\t\t\t};\n\t\t});\n\t},\n\n\tImage: class {\n\n\t\tbufferSize = 0;\n\n\t\t/**\n\t\t * Initialize an Image object.  All Image objects allocate WASM memory.\n\t\t * That memory should be freed, explicitly.  If 8-bit data is passed,\n\t\t * it will be copied directly into WASM memory.\n\t\t * Use doxa.fromImageData to convert from RGBA to grayscale.\n\t\t * @param {number} width Image Width\n\t\t * @param {number} height Image Height\n\t\t * @param {Uint8Array} data 8-bit grayscale data.  Optional.\n\t\t */\n\t\tconstructor (width, height, data) {\n\t\t\tthis.initialize(width || 0, height || 0);\n\n\t\t\tif (data) {\n\t\t\t\tDoxa.Wasm.HEAPU8.set(data.subarray(0, this.size), this.heapPtr);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * The number of pixels in the image.\n\t\t */\n\t\tget size() {\n\t\t\treturn this.width * this.height;\n\t\t}\n\n\t\t/**\n\t\t * Draws the Image directly to an HTML5 Canvas.\n\t\t * The Canvas should accept 32bit data, which is standard.\n\t\t * @param {*} canvas HTML5 Canvas, or a node-canvas\n\t\t */\n\t\tdraw(canvas) {\n\t\t\tcanvas.width = this.width;\n\t\t\tcanvas.height = this.height;\n\n\t\t\tconst ctx = canvas.getContext('2d');\n\t\t\tconst imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n\t\t\tthis.toImageData(imageData);\n\n\t\t\tctx.putImageData(imageData, 0, 0);\n\t\t}\n\n\t\tdata() {\n\t\t\treturn new Uint8ClampedArray(Doxa.Wasm.HEAPU8.buffer, this.heapPtr, this.size);\n\t\t}\n\n\t\t/**\n\t\t * Frees the memory allocated by this object.\n\t\t */\n\t\tfree() {\n\t\t\tif (this.heapPtr != null) Doxa.Wasm._free(this.heapPtr);\n\t\t}\n\n\t\tinitialize(width, height) {\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\n\t\t\tif (this.size > this.bufferSize) {\n\t\t\t\tthis.free();\n\t\t\t\tthis.bufferSize = this.size;\n\t\t\t\tthis.heapPtr = Doxa.Wasm._malloc(this.bufferSize);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Writes the 8-bit grayscale image data into a 32-bit RGBA ImageData object.\n\t\t * @param {ImageData} imageData - Target ImageData to populate\n\t\t */\n\t\ttoImageData(imageData) {\n\t\t\tconst buffer = this.data();\n\t\t\tconst size32 = imageData.width * imageData.height * 4;\n\n\t\t\tfor (var idx = 0; idx < size32; idx += 4) {\n\t\t\t\tconst gsIdx = idx / 4;\n\t\t\t\timageData.data[idx] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+1] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+2] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+3] = 255;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Only export if running in NodeJS\nif (typeof module !== 'undefined') {\n\tmodule.exports = { Doxa };\n}\n"
  },
  {
    "path": "Bindings/WebAssembly/dist/doxaWasm.js",
    "content": "var Module=typeof Module!=\"undefined\"?Module:{};var ENVIRONMENT_IS_WEB=!!globalThis.window;var ENVIRONMENT_IS_WORKER=!!globalThis.WorkerGlobalScope;var ENVIRONMENT_IS_NODE=globalThis.process?.versions?.node&&globalThis.process?.type!=\"renderer\";var arguments_=[];var thisProgram=\"./this.program\";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=globalThis.document?.currentScript?.src;if(typeof __filename!=\"undefined\"){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory=\"\";function locateFile(path){if(Module[\"locateFile\"]){return Module[\"locateFile\"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require(\"node:fs\");scriptDirectory=__dirname+\"/\";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:\"utf8\");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\\\/g,\"/\")}arguments_=process.argv.slice(2);if(typeof module!=\"undefined\"){module[\"exports\"]=Module}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(\".\",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open(\"GET\",url,false);xhr.responseType=\"arraybuffer\";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open(\"GET\",url,true);xhr.responseType=\"arraybuffer\";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:\"same-origin\"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+\" : \"+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith(\"file://\");var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);Module[\"HEAPU8\"]=HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module[\"preRun\"]){if(typeof Module[\"preRun\"]==\"function\")Module[\"preRun\"]=[Module[\"preRun\"]];while(Module[\"preRun\"].length){addOnPreRun(Module[\"preRun\"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports[\"A\"]()}function postRun(){if(Module[\"postRun\"]){if(typeof Module[\"postRun\"]==\"function\")Module[\"postRun\"]=[Module[\"postRun\"]];while(Module[\"postRun\"].length){addOnPostRun(Module[\"postRun\"].shift())}}callRuntimeCallbacks(onPostRuns)}function abort(what){Module[\"onAbort\"]?.(what);what=\"Aborted(\"+what+\")\";err(what);ABORT=true;what+=\". Build with -sASSERTIONS for more info.\";var e=new WebAssembly.RuntimeError(what);throw e}var wasmBinaryFile;function findWasmBinary(){return locateFile(\"doxaWasm.wasm\")}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw\"both async and sync fetching of the wasm failed\"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:\"same-origin\"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err(\"falling back to ArrayBuffer instantiation\")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){var imports={a:wasmImports};return imports}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;assignWasmExports(wasmExports);updateMemoryViews();removeRunDependency(\"wasm-instantiate\");return wasmExports}addRunDependency(\"wasm-instantiate\");function receiveInstantiationResult(result){return receiveInstance(result[\"instance\"])}var info=getWasmImports();if(Module[\"instantiateWasm\"]){return new Promise((resolve,reject)=>{Module[\"instantiateWasm\"](info,(inst,mod)=>{resolve(receiveInstance(inst,mod))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name=\"ExitStatus\";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var runDependencies=0;var dependenciesFulfilled=null;var removeRunDependency=id=>{runDependencies--;Module[\"monitorRunDependencies\"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}};var addRunDependency=id=>{runDependencies++;Module[\"monitorRunDependencies\"]?.(runDependencies)};var noExitRuntime=true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>2]=type}get_type(){return HEAPU32[this.ptr+4>>2]}set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>2]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}get_caught(){return HEAP8[this.ptr+12]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}get_rethrown(){return HEAP8[this.ptr+13]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var __abort_js=()=>abort(\"\");var structRegistrations={};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function readPointer(pointer){return this.fromWireType(HEAPU32[pointer>>2])}var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var InternalError=class InternalError extends Error{constructor(message){super(message);this.name=\"InternalError\"}};var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(type=>typeDependencies[type]=dependentTypes);function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError(\"Mismatched type converter count\")}for(var i=0;i<myTypes.length;++i){registerType(myTypes[i],myTypeConverters[i])}}var typeConverters=new Array(dependentTypes.length);var unregisteredTypes=[];var registered=0;for(let[i,dt]of dependentTypes.entries()){if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}}if(0===unregisteredTypes.length){onComplete(typeConverters)}};var __embind_finalize_value_object=structType=>{var reg=structRegistrations[structType];delete structRegistrations[structType];var rawConstructor=reg.rawConstructor;var rawDestructor=reg.rawDestructor;var fieldRecords=reg.fields;var fieldTypes=fieldRecords.map(field=>field.getterReturnType).concat(fieldRecords.map(field=>field.setterArgumentType));whenDependentTypesAreResolved([structType],fieldTypes,fieldTypes=>{var fields={};for(var[i,field]of fieldRecords.entries()){const getterReturnType=fieldTypes[i];const getter=field.getter;const getterContext=field.getterContext;const setterArgumentType=fieldTypes[i+fieldRecords.length];const setter=field.setter;const setterContext=field.setterContext;fields[field.fieldName]={read:ptr=>getterReturnType.fromWireType(getter(getterContext,ptr)),write:(ptr,o)=>{var destructors=[];setter(setterContext,ptr,setterArgumentType.toWireType(destructors,o));runDestructors(destructors)},optional:getterReturnType.optional}}return[{name:reg.name,fromWireType:ptr=>{var rv={};for(var i in fields){rv[i]=fields[i].read(ptr)}rawDestructor(ptr);return rv},toWireType:(destructors,o)=>{for(var fieldName in fields){if(!(fieldName in o)&&!fields[fieldName].optional){throw new TypeError(`Missing field: \"${fieldName}\"`)}}var ptr=rawConstructor();for(fieldName in fields){fields[fieldName].write(ptr,o[fieldName])}if(destructors!==null){destructors.push(rawDestructor,ptr)}return ptr},readValueFromPointer:readPointer,destructorFunction:rawDestructor}]})};var AsciiToString=ptr=>{var str=\"\";while(1){var ch=HEAPU8[ptr++];if(!ch)return str;str+=String.fromCharCode(ch)}};var BindingError=class BindingError extends Error{constructor(message){super(message);this.name=\"BindingError\"}};var throwBindingError=message=>{throw new BindingError(message)};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type \"${name}\" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){return sharedRegisterType(rawType,registeredInstance,options)}var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>HEAP8[pointer]:pointer=>HEAPU8[pointer];case 2:return signed?pointer=>HEAP16[pointer>>1]:pointer=>HEAPU16[pointer>>1];case 4:return signed?pointer=>HEAP32[pointer>>2]:pointer=>HEAPU32[pointer>>2];case 8:return signed?pointer=>HEAP64[pointer>>3]:pointer=>HEAPU64[pointer>>3];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{name=AsciiToString(name);const isUnsignedType=minRange===0n;let fromWireType=value=>value;if(isUnsignedType){const bitSize=size*8;fromWireType=value=>BigInt.asUintN(bitSize,value);maxRange=fromWireType(maxRange)}registerType(primitiveType,{name,fromWireType,toWireType:(destructors,value)=>{if(typeof value==\"number\"){value=BigInt(value)}return value},readValueFromPointer:integerReadValueFromPointer(name,size,!isUnsignedType),destructorFunction:null})};var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=AsciiToString(name);registerType(rawType,{name,fromWireType:function(wt){return!!wt},toWireType:function(destructors,o){return o?trueValue:falseValue},readValueFromPointer:function(pointer){return this.fromWireType(HEAPU8[pointer])},destructorFunction:null})};var shallowCopyInternalPointer=o=>({count:o.count,deleteScheduled:o.deleteScheduled,preservePointerOnDelete:o.preservePointerOnDelete,ptr:o.ptr,ptrType:o.ptrType,smartPtr:o.smartPtr,smartPtrType:o.smartPtrType});var throwInstanceAlreadyDeleted=obj=>{function getInstanceTypeName(handle){return handle.$$.ptrType.registeredClass.name}throwBindingError(getInstanceTypeName(obj)+\" instance already deleted\")};var finalizationRegistry=false;var detachFinalizer=handle=>{};var runDestructor=$$=>{if($$.smartPtr){$$.smartPtrType.rawDestructor($$.smartPtr)}else{$$.ptrType.registeredClass.rawDestructor($$.ptr)}};var releaseClassHandle=$$=>{$$.count.value-=1;var toDelete=0===$$.count.value;if(toDelete){runDestructor($$)}};var attachFinalizer=handle=>{if(!globalThis.FinalizationRegistry){attachFinalizer=handle=>handle;return handle}finalizationRegistry=new FinalizationRegistry(info=>{releaseClassHandle(info.$$)});attachFinalizer=handle=>{var $$=handle.$$;var hasSmartPtr=!!$$.smartPtr;if(hasSmartPtr){var info={$$};finalizationRegistry.register(handle,info,handle)}return handle};detachFinalizer=handle=>finalizationRegistry.unregister(handle);return attachFinalizer(handle)};var deletionQueue=[];var flushPendingDeletes=()=>{while(deletionQueue.length){var obj=deletionQueue.pop();obj.$$.deleteScheduled=false;obj[\"delete\"]()}};var delayFunction;var init_ClassHandle=()=>{let proto=ClassHandle.prototype;Object.assign(proto,{isAliasOf(other){if(!(this instanceof ClassHandle)){return false}if(!(other instanceof ClassHandle)){return false}var leftClass=this.$$.ptrType.registeredClass;var left=this.$$.ptr;other.$$=other.$$;var rightClass=other.$$.ptrType.registeredClass;var right=other.$$.ptr;while(leftClass.baseClass){left=leftClass.upcast(left);leftClass=leftClass.baseClass}while(rightClass.baseClass){right=rightClass.upcast(right);rightClass=rightClass.baseClass}return leftClass===rightClass&&left===right},clone(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.preservePointerOnDelete){this.$$.count.value+=1;return this}else{var clone=attachFinalizer(Object.create(Object.getPrototypeOf(this),{$$:{value:shallowCopyInternalPointer(this.$$)}}));clone.$$.count.value+=1;clone.$$.deleteScheduled=false;return clone}},delete(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError(\"Object already scheduled for deletion\")}detachFinalizer(this);releaseClassHandle(this.$$);if(!this.$$.preservePointerOnDelete){this.$$.smartPtr=undefined;this.$$.ptr=undefined}},isDeleted(){return!this.$$.ptr},deleteLater(){if(!this.$$.ptr){throwInstanceAlreadyDeleted(this)}if(this.$$.deleteScheduled&&!this.$$.preservePointerOnDelete){throwBindingError(\"Object already scheduled for deletion\")}deletionQueue.push(this);if(deletionQueue.length===1&&delayFunction){delayFunction(flushPendingDeletes)}this.$$.deleteScheduled=true;return this}});const symbolDispose=Symbol.dispose;if(symbolDispose){proto[symbolDispose]=proto[\"delete\"]}};function ClassHandle(){}var createNamedFunction=(name,func)=>Object.defineProperty(func,\"name\",{value:name});var registeredPointers={};var ensureOverloadTable=(proto,methodName,humanName)=>{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(...args){if(!proto[methodName].overloadTable.hasOwnProperty(args.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${args.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[args.length].apply(this,args)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module[name].overloadTable.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{name=name.replace(/[^a-zA-Z0-9_]/g,\"$\");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};function RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast){this.name=name;this.constructor=constructor;this.instancePrototype=instancePrototype;this.rawDestructor=rawDestructor;this.baseClass=baseClass;this.getActualType=getActualType;this.upcast=upcast;this.downcast=downcast;this.pureVirtualFunctions=[]}var upcastPointer=(ptr,ptrClass,desiredClass)=>{while(ptrClass!==desiredClass){if(!ptrClass.upcast){throwBindingError(`Expected null or instance of ${desiredClass.name}, got an instance of ${ptrClass.name}`)}ptr=ptrClass.upcast(ptr);ptrClass=ptrClass.baseClass}return ptr};var embindRepr=v=>{if(v===null){return\"null\"}var t=typeof v;if(t===\"object\"||t===\"array\"||t===\"function\"){return v.toString()}else{return\"\"+v}};function constNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass \"${embindRepr(handle)}\" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}function genericPointerToWireType(destructors,handle){var ptr;if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}if(this.isSmartPointer){ptr=this.rawConstructor();if(destructors!==null){destructors.push(this.rawDestructor,ptr)}return ptr}else{return 0}}if(!handle||!handle.$$){throwBindingError(`Cannot pass \"${embindRepr(handle)}\" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(!this.isConst&&handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);if(this.isSmartPointer){if(undefined===handle.$$.smartPtr){throwBindingError(\"Passing raw pointer to smart pointer is illegal\")}switch(this.sharingPolicy){case 0:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{throwBindingError(`Cannot convert argument of type ${handle.$$.smartPtrType?handle.$$.smartPtrType.name:handle.$$.ptrType.name} to parameter type ${this.name}`)}break;case 1:ptr=handle.$$.smartPtr;break;case 2:if(handle.$$.smartPtrType===this){ptr=handle.$$.smartPtr}else{var clonedHandle=handle[\"clone\"]();ptr=this.rawShare(ptr,Emval.toHandle(()=>clonedHandle[\"delete\"]()));if(destructors!==null){destructors.push(this.rawDestructor,ptr)}}break;default:throwBindingError(\"Unsupported sharing policy\")}}return ptr}function nonConstNoSmartPtrRawPointerToWireType(destructors,handle){if(handle===null){if(this.isReference){throwBindingError(`null is not a valid ${this.name}`)}return 0}if(!handle.$$){throwBindingError(`Cannot pass \"${embindRepr(handle)}\" as a ${this.name}`)}if(!handle.$$.ptr){throwBindingError(`Cannot pass deleted object as a pointer of type ${this.name}`)}if(handle.$$.ptrType.isConst){throwBindingError(`Cannot convert argument of type ${handle.$$.ptrType.name} to parameter type ${this.name}`)}var handleClass=handle.$$.ptrType.registeredClass;var ptr=upcastPointer(handle.$$.ptr,handleClass,this.registeredClass);return ptr}var downcastPointer=(ptr,ptrClass,desiredClass)=>{if(ptrClass===desiredClass){return ptr}if(undefined===desiredClass.baseClass){return null}var rv=downcastPointer(ptr,ptrClass,desiredClass.baseClass);if(rv===null){return null}return desiredClass.downcast(rv)};var registeredInstances={};var getBasestPointer=(class_,ptr)=>{if(ptr===undefined){throwBindingError(\"ptr should not be undefined\")}while(class_.baseClass){ptr=class_.upcast(ptr);class_=class_.baseClass}return ptr};var getInheritedInstance=(class_,ptr)=>{ptr=getBasestPointer(class_,ptr);return registeredInstances[ptr]};var makeClassHandle=(prototype,record)=>{if(!record.ptrType||!record.ptr){throwInternalError(\"makeClassHandle requires ptr and ptrType\")}var hasSmartPtrType=!!record.smartPtrType;var hasSmartPtr=!!record.smartPtr;if(hasSmartPtrType!==hasSmartPtr){throwInternalError(\"Both smartPtrType and smartPtr must be specified\")}record.count={value:1};return attachFinalizer(Object.create(prototype,{$$:{value:record,writable:true}}))};function RegisteredPointer_fromWireType(ptr){var rawPointer=this.getPointee(ptr);if(!rawPointer){this.destructor(ptr);return null}var registeredInstance=getInheritedInstance(this.registeredClass,rawPointer);if(undefined!==registeredInstance){if(0===registeredInstance.$$.count.value){registeredInstance.$$.ptr=rawPointer;registeredInstance.$$.smartPtr=ptr;return registeredInstance[\"clone\"]()}else{var rv=registeredInstance[\"clone\"]();this.destructor(ptr);return rv}}function makeDefaultHandle(){if(this.isSmartPointer){return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this.pointeeType,ptr:rawPointer,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(this.registeredClass.instancePrototype,{ptrType:this,ptr})}}var actualType=this.registeredClass.getActualType(rawPointer);var registeredPointerRecord=registeredPointers[actualType];if(!registeredPointerRecord){return makeDefaultHandle.call(this)}var toType;if(this.isConst){toType=registeredPointerRecord.constPointerType}else{toType=registeredPointerRecord.pointerType}var dp=downcastPointer(rawPointer,this.registeredClass,toType.registeredClass);if(dp===null){return makeDefaultHandle.call(this)}if(this.isSmartPointer){return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp,smartPtrType:this,smartPtr:ptr})}else{return makeClassHandle(toType.registeredClass.instancePrototype,{ptrType:toType,ptr:dp})}}var init_RegisteredPointer=()=>{Object.assign(RegisteredPointer.prototype,{getPointee(ptr){if(this.rawGetPointee){ptr=this.rawGetPointee(ptr)}return ptr},destructor(ptr){this.rawDestructor?.(ptr)},readValueFromPointer:readPointer,fromWireType:RegisteredPointer_fromWireType})};function RegisteredPointer(name,registeredClass,isReference,isConst,isSmartPointer,pointeeType,sharingPolicy,rawGetPointee,rawConstructor,rawShare,rawDestructor){this.name=name;this.registeredClass=registeredClass;this.isReference=isReference;this.isConst=isConst;this.isSmartPointer=isSmartPointer;this.pointeeType=pointeeType;this.sharingPolicy=sharingPolicy;this.rawGetPointee=rawGetPointee;this.rawConstructor=rawConstructor;this.rawShare=rawShare;this.rawDestructor=rawDestructor;if(!isSmartPointer&&registeredClass.baseClass===undefined){if(isConst){this.toWireType=constNoSmartPtrRawPointerToWireType;this.destructorFunction=null}else{this.toWireType=nonConstNoSmartPtrRawPointerToWireType;this.destructorFunction=null}}else{this.toWireType=genericPointerToWireType}}var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError(\"Replacing nonexistent public symbol\")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var embind__requireFunction=(signature,rawFunction,isAsync=false)=>{signature=AsciiToString(signature);function makeDynCaller(){var rtn=getWasmTableEntry(rawFunction);return rtn}var fp=makeDynCaller();if(typeof fp!=\"function\"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};class UnboundTypeError extends Error{}var getTypeName=type=>{var ptr=___getTypeName(type);var rv=AsciiToString(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([\", \"]))};var __embind_register_class=(rawType,rawPointerType,rawConstPointerType,baseClassRawType,getActualTypeSignature,getActualType,upcastSignature,upcast,downcastSignature,downcast,name,destructorSignature,rawDestructor)=>{name=AsciiToString(name);getActualType=embind__requireFunction(getActualTypeSignature,getActualType);upcast&&=embind__requireFunction(upcastSignature,upcast);downcast&&=embind__requireFunction(downcastSignature,downcast);rawDestructor=embind__requireFunction(destructorSignature,rawDestructor);var legalFunctionName=makeLegalFunctionName(name);exposePublicSymbol(legalFunctionName,function(){throwUnboundTypeError(`Cannot construct ${name} due to unbound types`,[baseClassRawType])});whenDependentTypesAreResolved([rawType,rawPointerType,rawConstPointerType],baseClassRawType?[baseClassRawType]:[],base=>{base=base[0];var baseClass;var basePrototype;if(baseClassRawType){baseClass=base.registeredClass;basePrototype=baseClass.instancePrototype}else{basePrototype=ClassHandle.prototype}var constructor=createNamedFunction(name,function(...args){if(Object.getPrototypeOf(this)!==instancePrototype){throw new BindingError(`Use 'new' to construct ${name}`)}if(undefined===registeredClass.constructor_body){throw new BindingError(`${name} has no accessible constructor`)}var body=registeredClass.constructor_body[args.length];if(undefined===body){throw new BindingError(`Tried to invoke ctor of ${name} with invalid number of parameters (${args.length}) - expected (${Object.keys(registeredClass.constructor_body).toString()}) parameters instead!`)}return body.apply(this,args)});var instancePrototype=Object.create(basePrototype,{constructor:{value:constructor}});constructor.prototype=instancePrototype;var registeredClass=new RegisteredClass(name,constructor,instancePrototype,rawDestructor,baseClass,getActualType,upcast,downcast);if(registeredClass.baseClass){registeredClass.baseClass.__derivedClasses??=[];registeredClass.baseClass.__derivedClasses.push(registeredClass)}var referenceConverter=new RegisteredPointer(name,registeredClass,true,false,false);var pointerConverter=new RegisteredPointer(name+\"*\",registeredClass,false,false,false);var constPointerConverter=new RegisteredPointer(name+\" const*\",registeredClass,false,true,false);registeredPointers[rawType]={pointerType:pointerConverter,constPointerType:constPointerConverter};replacePublicSymbol(legalFunctionName,constructor);return[referenceConverter,pointerConverter,constPointerConverter]})};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i<count;i++){array.push(HEAPU32[firstElement+i*4>>2])}return array};function usesDestructorStack(argTypes){for(var i=1;i<argTypes.length;++i){if(argTypes[i]!==null&&argTypes[i].destructorFunction===undefined){return true}}return false}function createJsInvoker(argTypes,isClassMethodFunc,returns,isAsync){var needsDestructorStack=usesDestructorStack(argTypes);var argCount=argTypes.length-2;var argsList=[];var argsListWired=[\"fn\"];if(isClassMethodFunc){argsListWired.push(\"thisWired\")}for(var i=0;i<argCount;++i){argsList.push(`arg${i}`);argsListWired.push(`arg${i}Wired`)}argsList=argsList.join(\",\");argsListWired=argsListWired.join(\",\");var invokerFnBody=`return function (${argsList}) {\\n`;if(needsDestructorStack){invokerFnBody+=\"var destructors = [];\\n\"}var dtorStack=needsDestructorStack?\"destructors\":\"null\";var args1=[\"humanName\",\"throwBindingError\",\"invoker\",\"fn\",\"runDestructors\",\"fromRetWire\",\"toClassParamWire\"];if(isClassMethodFunc){invokerFnBody+=`var thisWired = toClassParamWire(${dtorStack}, this);\\n`}for(var i=0;i<argCount;++i){var argName=`toArg${i}Wire`;invokerFnBody+=`var arg${i}Wired = ${argName}(${dtorStack}, arg${i});\\n`;args1.push(argName)}invokerFnBody+=(returns||isAsync?\"var rv = \":\"\")+`invoker(${argsListWired});\\n`;if(needsDestructorStack){invokerFnBody+=\"runDestructors(destructors);\\n\"}else{for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){var paramName=i===1?\"thisWired\":\"arg\"+(i-2)+\"Wired\";if(argTypes[i].destructorFunction!==null){invokerFnBody+=`${paramName}_dtor(${paramName});\\n`;args1.push(`${paramName}_dtor`)}}}if(returns){invokerFnBody+=\"var ret = fromRetWire(rv);\\n\"+\"return ret;\\n\"}else{}invokerFnBody+=\"}\\n\";return new Function(args1,invokerFnBody)}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError(\"argTypes array size mismatch! Must at least get return value and 'this' types!\")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=usesDestructorStack(argTypes);var returns=!argTypes[0].isVoid;var retType=argTypes[0];var instType=argTypes[1];var closureArgs=[humanName,throwBindingError,cppInvokerFunc,cppTargetFunc,runDestructors,retType.fromWireType.bind(retType),instType?.toWireType.bind(instType)];for(var i=2;i<argCount;++i){var argType=argTypes[i];closureArgs.push(argType.toWireType.bind(argType))}if(!needsDestructorStack){for(var i=isClassMethodFunc?1:2;i<argTypes.length;++i){if(argTypes[i].destructorFunction!==null){closureArgs.push(argTypes[i].destructorFunction)}}}let invokerFactory=createJsInvoker(argTypes,isClassMethodFunc,returns,isAsync);var invokerFn=invokerFactory(...closureArgs);return createNamedFunction(humanName,invokerFn)}var __embind_register_class_constructor=(rawClassType,argCount,rawArgTypesAddr,invokerSignature,invoker,rawConstructor)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);invoker=embind__requireFunction(invokerSignature,invoker);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`constructor ${classType.name}`;if(undefined===classType.registeredClass.constructor_body){classType.registeredClass.constructor_body=[]}if(undefined!==classType.registeredClass.constructor_body[argCount-1]){throw new BindingError(`Cannot register multiple constructors with identical number of parameters (${argCount-1}) for class '${classType.name}'! Overload resolution is currently only performed using the parameter count, not actual type info!`)}classType.registeredClass.constructor_body[argCount-1]=()=>{throwUnboundTypeError(`Cannot construct ${classType.name} due to unbound types`,rawArgTypes)};whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{argTypes.splice(1,0,null);classType.registeredClass.constructor_body[argCount-1]=craftInvokerFunction(humanName,argTypes,null,invoker,rawConstructor);return[]});return[]})};var getFunctionName=signature=>{signature=signature.trim();const argsIndex=signature.indexOf(\"(\");if(argsIndex===-1)return signature;return signature.slice(0,argsIndex)};var __embind_register_class_function=(rawClassType,methodName,argCount,rawArgTypesAddr,invokerSignature,rawInvoker,context,isPureVirtual,isAsync,isNonnullReturn)=>{var rawArgTypes=heap32VectorToArray(argCount,rawArgTypesAddr);methodName=AsciiToString(methodName);methodName=getFunctionName(methodName);rawInvoker=embind__requireFunction(invokerSignature,rawInvoker,isAsync);whenDependentTypesAreResolved([],[rawClassType],classType=>{classType=classType[0];var humanName=`${classType.name}.${methodName}`;if(methodName.startsWith(\"@@\")){methodName=Symbol[methodName.substring(2)]}if(isPureVirtual){classType.registeredClass.pureVirtualFunctions.push(methodName)}function unboundTypesHandler(){throwUnboundTypeError(`Cannot call ${humanName} due to unbound types`,rawArgTypes)}var proto=classType.registeredClass.instancePrototype;var method=proto[methodName];if(undefined===method||undefined===method.overloadTable&&method.className!==classType.name&&method.argCount===argCount-2){unboundTypesHandler.argCount=argCount-2;unboundTypesHandler.className=classType.name;proto[methodName]=unboundTypesHandler}else{ensureOverloadTable(proto,methodName,humanName);proto[methodName].overloadTable[argCount-2]=unboundTypesHandler}whenDependentTypesAreResolved([],rawArgTypes,argTypes=>{var memberFunction=craftInvokerFunction(humanName,argTypes,classType,rawInvoker,context,isAsync);if(undefined===proto[methodName].overloadTable){memberFunction.argCount=argCount-2;proto[methodName]=memberFunction}else{proto[methodName].overloadTable[argCount-2]=memberFunction}return[]});return[]})};var emval_freelist=[];var emval_handles=[0,1,,1,null,1,true,1,false,1];var __emval_decref=handle=>{if(handle>9&&0===--emval_handles[handle+1]){emval_handles[handle]=undefined;emval_freelist.push(handle)}};var Emval={toValue:handle=>{if(!handle){throwBindingError(`Cannot use deleted val. handle = ${handle}`)}return emval_handles[handle]},toHandle:value=>{switch(value){case undefined:return 2;case null:return 4;case true:return 6;case false:return 8;default:{const handle=emval_freelist.pop()||emval_handles.length;emval_handles[handle]=value;emval_handles[handle+1]=1;return handle}}}};var EmValType={name:\"emscripten::val\",fromWireType:handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},toWireType:(destructors,value)=>Emval.toHandle(value),readValueFromPointer:readPointer,destructorFunction:null};var __embind_register_emval=rawType=>registerType(rawType,EmValType);var enumReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?function(pointer){return this.fromWireType(HEAP8[pointer])}:function(pointer){return this.fromWireType(HEAPU8[pointer])};case 2:return signed?function(pointer){return this.fromWireType(HEAP16[pointer>>1])}:function(pointer){return this.fromWireType(HEAPU16[pointer>>1])};case 4:return signed?function(pointer){return this.fromWireType(HEAP32[pointer>>2])}:function(pointer){return this.fromWireType(HEAPU32[pointer>>2])};default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};function getEnumValueType(rawValueType){return rawValueType===0?\"object\":rawValueType===1?\"number\":\"string\"}var __embind_register_enum=(rawType,name,size,isSigned,rawValueType)=>{name=AsciiToString(name);const valueType=getEnumValueType(rawValueType);switch(valueType){case\"object\":{function ctor(){}ctor.values={};registerType(rawType,{name,constructor:ctor,valueType,fromWireType:function(c){return this.constructor.values[c]},toWireType:(destructors,c)=>c.value,readValueFromPointer:enumReadValueFromPointer(name,size,isSigned),destructorFunction:null});exposePublicSymbol(name,ctor);break}case\"number\":{var keysMap={};registerType(rawType,{name,keysMap,valueType,fromWireType:c=>c,toWireType:(destructors,c)=>c,readValueFromPointer:enumReadValueFromPointer(name,size,isSigned),destructorFunction:null});exposePublicSymbol(name,keysMap);delete Module[name].argCount;break}case\"string\":{var valuesMap={};var reverseMap={};var keysMap={};registerType(rawType,{name,valuesMap,reverseMap,keysMap,valueType,fromWireType:function(c){return this.reverseMap[c]},toWireType:function(destructors,c){return this.valuesMap[c]},readValueFromPointer:enumReadValueFromPointer(name,size,isSigned),destructorFunction:null});exposePublicSymbol(name,keysMap);delete Module[name].argCount;break}}};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(`${humanName} has unknown type ${getTypeName(rawType)}`)}return impl};var __embind_register_enum_value=(rawEnumType,name,enumValue)=>{var enumType=requireRegisteredType(rawEnumType,\"enum\");name=AsciiToString(name);switch(enumType.valueType){case\"object\":{var Enum=enumType.constructor;var Value=Object.create(enumType.constructor.prototype,{value:{value:enumValue},constructor:{value:createNamedFunction(`${enumType.name}_${name}`,function(){})}});Enum.values[enumValue]=Value;Enum[name]=Value;break}case\"number\":{enumType.keysMap[name]=enumValue;break}case\"string\":{enumType.valuesMap[name]=enumValue;enumType.reverseMap[enumValue]=name;enumType.keysMap[name]=name;break}}};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this.fromWireType(HEAPF32[pointer>>2])};case 8:return function(pointer){return this.fromWireType(HEAPF64[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=AsciiToString(name);registerType(rawType,{name,fromWireType:value=>value,toWireType:(destructors,value)=>value,readValueFromPointer:floatReadValueFromPointer(name,size),destructorFunction:null})};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync,isNonnullReturn)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=AsciiToString(name);name=getFunctionName(name);rawInvoker=embind__requireFunction(signature,rawInvoker,isAsync);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,argTypes=>{var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=AsciiToString(name);const isUnsignedType=minRange===0;let fromWireType=value=>value;if(isUnsignedType){var bitshift=32-8*size;fromWireType=value=>value<<bitshift>>>bitshift;maxRange=fromWireType(maxRange)}registerType(primitiveType,{name,fromWireType,toWireType:(destructors,value)=>value,readValueFromPointer:integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=HEAPU32[handle+4>>2];return new TA(HEAP8.buffer,data,size)}name=AsciiToString(name);registerType(rawType,{name,fromWireType:decodeMemoryView,readValueFromPointer:decodeMemoryView},{ignoreDuplicateRegistrations:true})};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.codePointAt(i);if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63;i++}}heap[outIdx]=0;return outIdx-startIdx};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var lengthBytesUTF8=str=>{var len=0;for(var i=0;i<str.length;++i){var c=str.charCodeAt(i);if(c<=127){len++}else if(c<=2047){len+=2}else if(c>=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var UTF8Decoder=globalThis.TextDecoder&&new TextDecoder;var findStringEnd=(heapOrArray,idx,maxBytesToRead,ignoreNul)=>{var maxIdx=idx+maxBytesToRead;if(ignoreNul)return maxIdx;while(heapOrArray[idx]&&!(idx>=maxIdx))++idx;return idx};var UTF8ArrayToString=(heapOrArray,idx=0,maxBytesToRead,ignoreNul)=>{var endPtr=findStringEnd(heapOrArray,idx,maxBytesToRead,ignoreNul);if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str=\"\";while(idx<endPtr){var u0=heapOrArray[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heapOrArray[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heapOrArray[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heapOrArray[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}return str};var UTF8ToString=(ptr,maxBytesToRead,ignoreNul)=>ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead,ignoreNul):\"\";var __embind_register_std_string=(rawType,name)=>{name=AsciiToString(name);var stdStringIsUTF8=true;registerType(rawType,{name,fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){str=UTF8ToString(payload,length,true)}else{str=\"\";for(var i=0;i<length;++i){str+=String.fromCharCode(HEAPU8[payload+i])}}_free(value);return str},toWireType(destructors,value){if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var length;var valueIsOfTypeString=typeof value==\"string\";if(!(valueIsOfTypeString||ArrayBuffer.isView(value)&&value.BYTES_PER_ELEMENT==1)){throwBindingError(\"Cannot pass non-string to std::string\")}if(stdStringIsUTF8&&valueIsOfTypeString){length=lengthBytesUTF8(value)}else{length=value.length}var base=_malloc(4+length+1);var ptr=base+4;HEAPU32[base>>2]=length;if(valueIsOfTypeString){if(stdStringIsUTF8){stringToUTF8(value,ptr,length+1)}else{for(var i=0;i<length;++i){var charCode=value.charCodeAt(i);if(charCode>255){_free(base);throwBindingError(\"String has UTF-16 code units that do not fit in 8 bits\")}HEAPU8[ptr+i]=charCode}}}else{HEAPU8.set(value,ptr)}if(destructors!==null){destructors.push(_free,base)}return base},readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var UTF16Decoder=globalThis.TextDecoder?new TextDecoder(\"utf-16le\"):undefined;var UTF16ToString=(ptr,maxBytesToRead,ignoreNul)=>{var idx=ptr>>1;var endIdx=findStringEnd(HEAPU16,idx,maxBytesToRead/2,ignoreNul);if(endIdx-idx>16&&UTF16Decoder)return UTF16Decoder.decode(HEAPU16.subarray(idx,endIdx));var str=\"\";for(var i=idx;i<endIdx;++i){var codeUnit=HEAPU16[i];str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite<str.length*2?maxBytesToWrite/2:str.length;for(var i=0;i<numCharsToWrite;++i){var codeUnit=str.charCodeAt(i);HEAP16[outPtr>>1]=codeUnit;outPtr+=2}HEAP16[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead,ignoreNul)=>{var str=\"\";var startIdx=ptr>>2;for(var i=0;!(i>=maxBytesToRead/4);i++){var utf32=HEAPU32[startIdx+i];if(!utf32&&!ignoreNul)break;str+=String.fromCodePoint(utf32)}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{maxBytesToWrite??=2147483647;if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i<str.length;++i){var codePoint=str.codePointAt(i);if(codePoint>65535){i++}HEAP32[outPtr>>2]=codePoint;outPtr+=4;if(outPtr+4>endPtr)break}HEAP32[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i<str.length;++i){var codePoint=str.codePointAt(i);if(codePoint>65535){i++}len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=AsciiToString(name);var decodeString,encodeString,lengthBytesUTF;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16}else{decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32}registerType(rawType,{name,fromWireType:value=>{var length=HEAPU32[value>>2];var str=decodeString(value+4,length*charSize,true);_free(value);return str},toWireType:(destructors,value)=>{if(!(typeof value==\"string\")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);HEAPU32[ptr>>2]=length/charSize;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},readValueFromPointer:readPointer,destructorFunction(ptr){_free(ptr)}})};var __embind_register_value_object=(rawType,name,constructorSignature,rawConstructor,destructorSignature,rawDestructor)=>{structRegistrations[rawType]={name:AsciiToString(name),rawConstructor:embind__requireFunction(constructorSignature,rawConstructor),rawDestructor:embind__requireFunction(destructorSignature,rawDestructor),fields:[]}};var __embind_register_value_object_field=(structType,fieldName,getterReturnType,getterSignature,getter,getterContext,setterArgumentType,setterSignature,setter,setterContext)=>{structRegistrations[structType].fields.push({fieldName:AsciiToString(fieldName),getterReturnType,getter:embind__requireFunction(getterSignature,getter),getterContext,setterArgumentType,setter:embind__requireFunction(setterSignature,setter),setterContext})};var __embind_register_void=(rawType,name)=>{name=AsciiToString(name);registerType(rawType,{isVoid:true,name,fromWireType:()=>undefined,toWireType:(destructors,o)=>undefined})};var __tzset_js=(timezone,daylight,std_name,dst_name)=>{var currentYear=(new Date).getFullYear();var winter=new Date(currentYear,0,1);var summer=new Date(currentYear,6,1);var winterOffset=winter.getTimezoneOffset();var summerOffset=summer.getTimezoneOffset();var stdTimezoneOffset=Math.max(winterOffset,summerOffset);HEAPU32[timezone>>2]=stdTimezoneOffset*60;HEAP32[daylight>>2]=Number(winterOffset!=summerOffset);var extractZone=timezoneOffset=>{var sign=timezoneOffset>=0?\"-\":\"+\";var absOffset=Math.abs(timezoneOffset);var hours=String(Math.floor(absOffset/60)).padStart(2,\"0\");var minutes=String(absOffset%60).padStart(2,\"0\");return`UTC${sign}${hours}${minutes}`};var winterName=extractZone(winterOffset);var summerName=extractZone(summerOffset);if(summerOffset<winterOffset){stringToUTF8(winterName,std_name,17);stringToUTF8(summerName,dst_name,17)}else{stringToUTF8(winterName,dst_name,17);stringToUTF8(summerName,std_name,17)}};var readEmAsmArgsArray=[];var readEmAsmArgs=(sigPtr,buf)=>{readEmAsmArgsArray.length=0;var ch;while(ch=HEAPU8[sigPtr++]){var wide=ch!=105;wide&=ch!=112;buf+=wide&&buf%8?4:0;readEmAsmArgsArray.push(ch==112?HEAPU32[buf>>2]:ch==106?HEAP64[buf>>3]:ch==105?HEAP32[buf>>2]:HEAPF64[buf>>3]);buf+=wide?8:4}return readEmAsmArgsArray};var runEmAsmFunction=(code,sigPtr,argbuf)=>{var args=readEmAsmArgs(sigPtr,argbuf);return ASM_CONSTS[code](...args)};var _emscripten_asm_const_int=(code,sigPtr,argbuf)=>runEmAsmFunction(code,sigPtr,argbuf);var getHeapMax=()=>2147483648;var alignMemory=(size,alignment)=>Math.ceil(size/alignment)*alignment;var growMemory=size=>{var oldHeapSize=wasmMemory.buffer.byteLength;var pages=(size-oldHeapSize+65535)/65536|0;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignMemory(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var ENV={};var getExecutableName=()=>thisProgram||\"./this.program\";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(globalThis.navigator?.language??\"C\").replace(\"-\",\"_\")+\".UTF-8\";var env={USER:\"web_user\",LOGNAME:\"web_user\",PATH:\"/\",PWD:\"/\",HOME:\"/home/web_user\",LANG:lang,_:getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var _environ_get=(__environ,environ_buf)=>{var bufSize=0;var envp=0;for(var string of getEnvStrings()){var ptr=environ_buf+bufSize;HEAPU32[__environ+envp>>2]=ptr;bufSize+=stringToUTF8(string,ptr,Infinity)+1;envp+=4}return 0};var _environ_sizes_get=(penviron_count,penviron_buf_size)=>{var strings=getEnvStrings();HEAPU32[penviron_count>>2]=strings.length;var bufSize=0;for(var string of strings){bufSize+=lengthBytesUTF8(string)+1}HEAPU32[penviron_buf_size>>2]=bufSize;return 0};init_ClassHandle();init_RegisteredPointer();{if(Module[\"noExitRuntime\"])noExitRuntime=Module[\"noExitRuntime\"];if(Module[\"print\"])out=Module[\"print\"];if(Module[\"printErr\"])err=Module[\"printErr\"];if(Module[\"wasmBinary\"])wasmBinary=Module[\"wasmBinary\"];if(Module[\"arguments\"])arguments_=Module[\"arguments\"];if(Module[\"thisProgram\"])thisProgram=Module[\"thisProgram\"];if(Module[\"preInit\"]){if(typeof Module[\"preInit\"]==\"function\")Module[\"preInit\"]=[Module[\"preInit\"]];while(Module[\"preInit\"].length>0){Module[\"preInit\"].shift()()}}}var ASM_CONSTS={26400:()=>{Module[\"Binarization\"][\"Algorithms\"]=Module[\"Binarization.Algorithms\"];delete Module[\"Binarization.Algorithms\"]},26516:()=>{Module[\"Grayscale\"]={Algorithms:Module[\"Grayscale.Algorithms\"]};delete Module[\"Grayscale.Algorithms\"]}};var ___getTypeName,_malloc,_free,memory,__indirect_function_table,wasmMemory,wasmTable;function assignWasmExports(wasmExports){___getTypeName=wasmExports[\"B\"];_malloc=Module[\"_malloc\"]=wasmExports[\"D\"];_free=Module[\"_free\"]=wasmExports[\"E\"];memory=wasmMemory=wasmExports[\"z\"];__indirect_function_table=wasmTable=wasmExports[\"C\"]}var wasmImports={e:___cxa_throw,r:__abort_js,i:__embind_finalize_value_object,n:__embind_register_bigint,w:__embind_register_bool,y:__embind_register_class,t:__embind_register_class_constructor,f:__embind_register_class_function,u:__embind_register_emval,l:__embind_register_enum,a:__embind_register_enum_value,m:__embind_register_float,h:__embind_register_function,d:__embind_register_integer,c:__embind_register_memory_view,v:__embind_register_std_string,g:__embind_register_std_wstring,j:__embind_register_value_object,b:__embind_register_value_object_field,x:__embind_register_void,o:__tzset_js,k:_emscripten_asm_const_int,s:_emscripten_resize_heap,p:_environ_get,q:_environ_sizes_get};function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module[\"calledRun\"]=true;if(ABORT)return;initRuntime();Module[\"onRuntimeInitialized\"]?.();postRun()}if(Module[\"setStatus\"]){Module[\"setStatus\"](\"Running...\");setTimeout(()=>{setTimeout(()=>Module[\"setStatus\"](\"\"),1);doRun()},1)}else{doRun()}}var wasmExports;createWasm();run();\n"
  },
  {
    "path": "Bindings/WebAssembly/doxa.js",
    "content": "/**\n * Doxa WASM\n * A set of classes that further simplify the Doxa WASM interface.\n * This same wrapper can be run in NodeJS or directly in the web.\n * See Demo/WebJs and Demo/NodeJS for an example of how to use it.\n */\n\nconst Doxa = {\n\n\tWasm: (typeof Module !== 'undefined') ? Module : require('./doxaWasm.js'),\n\n\tinitialize: async function() {\n\t\tif (!Doxa.Wasm) throw new Error('Missing: Doxa WASM Module');\n\n\t\t// Extract enum values from an Emscripten enum object\n\t\tconst extractEnums = function(enumObj) {\n\t\t\tconst enums = {};\n\t\t\tfor (const key in enumObj) {\n\t\t\t\tconst entry = enumObj[key];\n\t\t\t\tif (entry?.value === undefined) continue;\n\t\t\t\tenums[key] = entry.value;\n\t\t\t}\n\t\t\treturn enums;\n\t\t}\n\n\t\tconst buildInstance = function() {\n\t\t\tconst instance = {\n\t\t\t\tbinarization: extractEnums(Doxa.Wasm.Binarization.Algorithms),\n\t\t\t\tgrayscale: extractEnums(Doxa.Wasm.Grayscale.Algorithms),\n\n\t\t\t\t/**\n\t\t\t\t * Convert raw pixel data to an 8-bit grayscale Doxa.Image.\n\t\t\t\t * If the data is already single-channel, it is copied directly.\n\t\t\t\t * @param {Uint8Array|Uint8ClampedArray} data - Raw pixel data (1, 3, or 4 channels)\n\t\t\t\t * @param {number} width - Image width\n\t\t\t\t * @param {number} height - Image height\n\t\t\t\t * @param {number} channels - 1 for grayscale, 3 for RGB, 4 for RGBA\n\t\t\t\t * @param {number} algorithm - Grayscale algorithm enum value (e.g. doxa.grayscale.MEAN). Defaults to MEAN.\n\t\t\t\t * @returns {Doxa.Image} 8-bit grayscale image (caller must free)\n\t\t\t\t */\n\t\t\t\ttoGrayscale: function(data, width, height, channels, algorithm) {\n\t\t\t\t\t// Already grayscale — just copy directly\n\t\t\t\t\tif (channels === 1) {\n\t\t\t\t\t\treturn new Doxa.Image(width, height, data);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Allocate WASM heap for input\n\t\t\t\t\tconst inputSize = width * height * channels;\n\t\t\t\t\tconst inputPtr = Doxa.Wasm._malloc(inputSize);\n\t\t\t\t\tDoxa.Wasm.HEAPU8.set(data.subarray(0, inputSize), inputPtr);\n\n\t\t\t\t\t// Allocate output image\n\t\t\t\t\tconst outputImage = new Doxa.Image(width, height);\n\n\t\t\t\t\tconst algEnum = Doxa.Wasm.Grayscale.Algorithms.values[\n\t\t\t\t\t\talgorithm ?? instance.grayscale.MEAN\n\t\t\t\t\t];\n\t\t\t\t\tDoxa.Wasm.toGrayscale(outputImage.heapPtr, inputPtr, width, height, channels, algEnum);\n\n\t\t\t\t\t// Free input buffer\n\t\t\t\t\tDoxa.Wasm._free(inputPtr);\n\n\t\t\t\t\treturn outputImage;\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Convert an HTML5 Canvas ImageData to an 8-bit grayscale Doxa.Image.\n\t\t\t\t * Convenience wrapper for browser usage.\n\t\t\t\t * @param {ImageData} imageData - Canvas ImageData (32-bit RGBA)\n\t\t\t\t * @param {number} algorithm - Grayscale algorithm enum value (e.g. doxa.grayscale.MEAN). Defaults to MEAN.\n\t\t\t\t * @returns {Doxa.Image} 8-bit grayscale image (caller must free)\n\t\t\t\t */\n\t\t\t\tfromImageData: function(imageData, algorithm) {\n\t\t\t\t\treturn instance.toGrayscale(\n\t\t\t\t\t\timageData.data, imageData.width, imageData.height, 4, algorithm\n\t\t\t\t\t);\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Binarize a grayscale image using the specified algorithm.\n\t\t\t\t * @param {number} algorithm - Binarization algorithm enum value (e.g. doxa.binarization.SAUVOLA)\n\t\t\t\t * @param {Doxa.Image} imageIn - Input grayscale image\n\t\t\t\t * @param {object} parameters - Algorithm parameters (e.g. { window: 75, k: 0.2 })\n\t\t\t\t * @param {Doxa.Image} imageOut - Optional output image (allocated if not provided)\n\t\t\t\t * @returns {Doxa.Image} Binary image (caller must free if newly allocated)\n\t\t\t\t */\n\t\t\t\ttoBinary: function(algorithm, imageIn, parameters, imageOut) {\n\t\t\t\t\tif (!imageOut) {\n\t\t\t\t\t\timageOut = new Doxa.Image(imageIn.width, imageIn.height);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst algEnum = Doxa.Wasm.Binarization.Algorithms.values[algorithm];\n\t\t\t\t\tconst paramString = JSON.stringify(parameters || {});\n\t\t\t\t\tconst binarization = new Doxa.Wasm.Binarization(algEnum);\n\n\t\t\t\t\tbinarization.initialize(imageIn.heapPtr, imageIn.width, imageIn.height);\n\t\t\t\t\tbinarization.toBinary(imageOut.heapPtr, paramString);\n\n\t\t\t\t\treturn imageOut;\n\t\t\t\t},\n\n\t\t\t\t/**\n\t\t\t\t * Calculate performance metrics comparing a binary image against ground truth.\n\t\t\t\t * If precision/recall weight texts are provided, pseudo metrics are included.\n\t\t\t\t * @param {Doxa.Image} groundTruth - Ground truth binary image\n\t\t\t\t * @param {Doxa.Image} binary - Binary image to evaluate\n\t\t\t\t * @param {string} precisionWeightsText - Optional precision weights (enables pseudo metrics)\n\t\t\t\t * @param {string} recallWeightsText - Optional recall weights (enables pseudo metrics)\n\t\t\t\t * @returns {object} Performance metrics (accuracy, fm, precision, recall, mcc, psnr, nrm, drdm, and optionally pseudoFM, pseudoPrecision, pseudoRecall)\n\t\t\t\t */\n\t\t\t\tcalculatePerformance: function(groundTruth, binary, precisionWeightsText, recallWeightsText) {\n\t\t\t\t\tif (precisionWeightsText && recallWeightsText) {\n\t\t\t\t\t\treturn Doxa.Wasm.calculatePseudoPerformance(\n\t\t\t\t\t\t\tgroundTruth.heapPtr, binary.heapPtr,\n\t\t\t\t\t\t\tbinary.width, binary.height,\n\t\t\t\t\t\t\tprecisionWeightsText, recallWeightsText\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Doxa.Wasm.calculatePerformance(\n\t\t\t\t\t\tgroundTruth.heapPtr, binary.heapPtr,\n\t\t\t\t\t\tbinary.width, binary.height\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\treturn instance;\n\t\t}\n\n\t\treturn new Promise((resolve) => {\n\t\t\t// Ensure the library has not already been initialized\n\t\t\tif (typeof Doxa.Wasm.Binarization !== 'undefined') {\n\t\t\t\treturn resolve(buildInstance());\n\t\t\t}\n\n\t\t\tDoxa.Wasm.onRuntimeInitialized = async _ => {\n\t\t\t\tresolve(buildInstance());\n\t\t\t};\n\t\t});\n\t},\n\n\tImage: class {\n\n\t\tbufferSize = 0;\n\n\t\t/**\n\t\t * Initialize an Image object.  All Image objects allocate WASM memory.\n\t\t * That memory should be freed, explicitly.  If 8-bit data is passed,\n\t\t * it will be copied directly into WASM memory.\n\t\t * Use doxa.fromImageData to convert from RGBA to grayscale.\n\t\t * @param {number} width Image Width\n\t\t * @param {number} height Image Height\n\t\t * @param {Uint8Array} data 8-bit grayscale data.  Optional.\n\t\t */\n\t\tconstructor (width, height, data) {\n\t\t\tthis.initialize(width || 0, height || 0);\n\n\t\t\tif (data) {\n\t\t\t\tDoxa.Wasm.HEAPU8.set(data.subarray(0, this.size), this.heapPtr);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * The number of pixels in the image.\n\t\t */\n\t\tget size() {\n\t\t\treturn this.width * this.height;\n\t\t}\n\n\t\t/**\n\t\t * Draws the Image directly to an HTML5 Canvas.\n\t\t * The Canvas should accept 32bit data, which is standard.\n\t\t * @param {*} canvas HTML5 Canvas, or a node-canvas\n\t\t */\n\t\tdraw(canvas) {\n\t\t\tcanvas.width = this.width;\n\t\t\tcanvas.height = this.height;\n\n\t\t\tconst ctx = canvas.getContext('2d');\n\t\t\tconst imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n\t\t\tthis.toImageData(imageData);\n\n\t\t\tctx.putImageData(imageData, 0, 0);\n\t\t}\n\n\t\tdata() {\n\t\t\treturn new Uint8ClampedArray(Doxa.Wasm.HEAPU8.buffer, this.heapPtr, this.size);\n\t\t}\n\n\t\t/**\n\t\t * Frees the memory allocated by this object.\n\t\t */\n\t\tfree() {\n\t\t\tif (this.heapPtr != null) Doxa.Wasm._free(this.heapPtr);\n\t\t}\n\n\t\tinitialize(width, height) {\n\t\t\tthis.width = width;\n\t\t\tthis.height = height;\n\n\t\t\tif (this.size > this.bufferSize) {\n\t\t\t\tthis.free();\n\t\t\t\tthis.bufferSize = this.size;\n\t\t\t\tthis.heapPtr = Doxa.Wasm._malloc(this.bufferSize);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Writes the 8-bit grayscale image data into a 32-bit RGBA ImageData object.\n\t\t * @param {ImageData} imageData - Target ImageData to populate\n\t\t */\n\t\ttoImageData(imageData) {\n\t\t\tconst buffer = this.data();\n\t\t\tconst size32 = imageData.width * imageData.height * 4;\n\n\t\t\tfor (var idx = 0; idx < size32; idx += 4) {\n\t\t\t\tconst gsIdx = idx / 4;\n\t\t\t\timageData.data[idx] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+1] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+2] = buffer[gsIdx];\n\t\t\t\timageData.data[idx+3] = 255;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Only export if running in NodeJS\nif (typeof module !== 'undefined') {\n\tmodule.exports = { Doxa };\n}\n"
  },
  {
    "path": "Bindings/WebAssembly/package.json",
    "content": "{\n  \"name\": \"doxajs\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Doxa Binarization Framework for JavaScript/WebAssembly\",\n  \"main\": \"dist/doxa.js\",\n  \"files\": [\n    \"dist/\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/brandonmpetty/Doxa\"\n  },\n  \"keywords\": [\n    \"binarization\",\n    \"image-processing\"\n  ],\n  \"scripts\": {\n    \"test\": \"jasmine\",\n    \"build\": \"emcmake cmake -S ../.. -B ../../build-wasm -DCMAKE_BUILD_TYPE=Release && cmake --build ../../build-wasm --config Release\",\n    \"build:dev\": \"emcmake cmake -S ../.. -B ../../build-wasm -DCMAKE_BUILD_TYPE=Debug && cmake --build ../../build-wasm --config Debug\",\n    \"prepublishOnly\": \"npm run build\"\n  },\n  \"author\": \"Brandon M. Petty\",\n  \"license\": \"CC0-1.0\",\n  \"devDependencies\": {\n    \"canvas\": \"3.2.1\",\n    \"jasmine\": \"6.0.0\"\n  }\n}\n"
  },
  {
    "path": "Bindings/WebAssembly/spec/binarization.spec.js",
    "content": "const fs = require('fs');\nconst path = require('path');\nconst { loadImage, createCanvas } = require('canvas');\nconst { Doxa } = require('../dist/doxa.js');\n\n// Note: I would love to give an example of sharp but it cannot live\n// in the same project as canvas.  See the DEMO for an example.\n//const sharp = require('sharp');\n\n\ndescribe(\"Doxa Binarization Class Test Suite\", function() {\n\n    let doxa;\n\n    async function readImage(file) {\n\n        const image = await loadImage(file);\n        const canvas = createCanvas(image.width, image.height);\n        const ctx = canvas.getContext('2d');\n\n        ctx.drawImage(image, 0, 0);\n\n        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n        return doxa.fromImageData(imageData);\n    }\n\n    beforeAll(async function() {\n\n        // Initializing is required for setting up the WASM module.\n        doxa = await Doxa.initialize();\n    });\n\n    it(\"Binarization toBinary runs successfully\", async function() {\n\n        const rgba = new Buffer.from([\n            0,0,0,0,    255,255,255,0,  120,120,120,0,\n            15,15,15,0, 230,230,230,0,  90,90,90,0,\n            5,5,5,0,    245,245,245,0,  69,1100,77,0\n        ]);\n        const image = doxa.toGrayscale(rgba, 3, 3, 4);\n\n        // Function under test\n        const binImage = doxa.toBinary(doxa.binarization.OTSU, image);\n\n        expect(Array.from(binImage.data())).toEqual([\n            0, 255, 0,\n            0, 255, 0,\n            0, 255, 0\n        ]);\n    });\n\n    it(\"Binarization calculatePerformance runs successfully\", async function() {\n\n        const groundTruthImage = await readImage('../../README/2JohnC1V3-GroundTruth.png');\n        const binaryImage = await  readImage('../../README/2JohnC1V3-Sauvola.png');\n\n        const metrics = doxa.calculatePerformance(groundTruthImage, binaryImage);\n\n        expect(metrics.accuracy).toBeCloseTo(97.671, 3);\n        // NOTE: This PNG is slightly different than the PBM used by other tests\n        //console.log(4122975586 / (2112 * 1000000)); // DIBCO Metrics\n        //console.log(4122922964 / (2112 * 1000000)); // This algorithm.\n        // Possible rounding error due to the weighted matrix?\n        expect(metrics.drdm).toBeCloseTo(1.9522, 3); // TODO: Change to 4!\n        expect(metrics.fm).toBeCloseTo(93.204, 3);\n        expect(metrics.recall).toBeCloseTo(91.3811, 2);\n        expect(metrics.precision).toBeCloseTo(95.1025, 2);\n        expect(metrics.mcc).toBeCloseTo(0.918, 3);\n        expect(metrics.nrm).toBeCloseTo(0.048, 3);\n        expect(metrics.psnr).toBeCloseTo(16.329, 3);\n    });\n\n    it(\"Binarization calculatePerformance with pseudo metrics runs successfully\", async function() {\n\n        const groundTruthImage = await readImage('../../README/2JohnC1V3-GroundTruth.png');\n        const binaryImage = await readImage('../../README/2JohnC1V3-Sauvola.png');\n\n        const pWeightsText = fs.readFileSync(path.resolve(__dirname, '../../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_PWeights.dat'), 'utf8');\n        const rWeightsText = fs.readFileSync(path.resolve(__dirname, '../../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_RWeights.dat'), 'utf8');\n\n        const metrics = doxa.calculatePerformance(groundTruthImage, binaryImage, pWeightsText, rWeightsText);\n\n        expect(metrics.pseudoFM).toBeCloseTo(93.393, 2);\n        expect(metrics.pseudoRecall).toBeCloseTo(92.7954, 2);\n        expect(metrics.pseudoPrecision).toBeCloseTo(93.9983, 2);\n    });\n\n    it(\"Algorithm defaults are applied\", async function() {\n\n        const image = await readImage('../../README/2JohnC1V3.png');\n\n        const binImage1 = doxa.toBinary(doxa.binarization.SAUVOLA, image);\n        const binImage2 = doxa.toBinary(doxa.binarization.SAUVOLA, image, { window: 75, k: 0.2 });\n        const binImage3 = doxa.toBinary(doxa.binarization.SAUVOLA, image, { window: 25, k: 0.12 });\n\n        expect(binImage1.data()).toEqual(binImage2.data());\n        expect(binImage2.data()).not.toEqual(binImage3.data());\n    });\n\n});\n"
  },
  {
    "path": "Bindings/WebAssembly/spec/image.spec.js",
    "content": "const { createCanvas, createImageData } = require('canvas');\nconst { Doxa } = require('../dist/doxa.js');\n\n\ndescribe(\"Doxa Image Class Test Suite\", function() {\n\n    let doxa;\n\n    beforeAll(async function() {\n\n        // Initializing is required for setting up the WASM module.\n        doxa = await Doxa.initialize();\n    });\n\n    it(\"Constructor no arguments\", function() {\n\n        const image = new Doxa.Image();\n\n        expect(image.width).toBe(0);\n        expect(image.height).toBe(0);\n        expect(image.size).toBe(0);\n\n        expect(Array.from(image.data())).toEqual([]);\n\n        image.free();\n    });\n\n    it(\"Constructor no Data\", function() {\n\n        const image = new Doxa.Image(2, 3);\n\n        expect(image.width).toBe(2);\n        expect(image.height).toBe(3);\n        expect(image.size).toBe(6);\n\n        // Some compilers might zero out image.data, others will not.\n\n        image.free();\n    });\n\n    it(\"Constructor with 8-bit Data\", function() {\n\n        const gray = new Uint8Array([\n            255, 0, 128,\n            85, 85, 85,\n            80, 80, 80\n        ]);\n\n        const image = new Doxa.Image(3, 3, gray);\n\n        expect(image.width).toBe(3);\n        expect(image.height).toBe(3);\n        expect(image.size).toBe(9);\n\n        expect(Array.from(image.data())).toEqual([\n            255, 0, 128,\n            85, 85, 85,\n            80, 80, 80\n        ]);\n\n        image.free();\n    });\n\n    it(\"Image Resize\", function() {\n\n        const image = new Doxa.Image(2, 3);\n\n        expect(image.width).toBe(2);\n        expect(image.height).toBe(3);\n        expect(image.size).toBe(6);\n        expect(image.bufferSize).toBe(6);\n\n        image.initialize(3,3);\n\n        expect(image.width).toBe(3);\n        expect(image.height).toBe(3);\n        expect(image.size).toBe(9);\n        expect(image.bufferSize).toBe(9); // Buffer grew\n\n        image.initialize(2,1);\n\n        expect(image.width).toBe(2);\n        expect(image.height).toBe(1);\n        expect(image.size).toBe(2);       // Reflects actual image\n        expect(image.bufferSize).toBe(9); // Buffer retained\n\n        image.free();\n    });\n\n    it(\"Grayscale fromImageData\", function() {\n\n        const rgba = new createImageData(new Uint8ClampedArray([\n            255,255,255,0,   0,0,0,0,      128,128,128,0,\n            255,0,0,0,       0,255,0,0,    0,0,255,0,\n            70,80,90,0,      90,80,70,0,   80,90,70,0\n        ]), 3, 3);\n\n        const image = doxa.fromImageData(rgba);\n\n        // MEAN grayscale: (r+g+b)/3\n        expect(Array.from(image.data())).toEqual([\n            255, 0, 128,\n            85, 85, 85,\n            80, 80, 80\n        ]);\n\n        image.free();\n    });\n\n    it(\"toImageData\", function() {\n\n        const gray = new Uint8Array([\n            255, 0, 128,\n            85, 85, 85,\n            70, 70, 70\n        ]);\n\n        const image = new Doxa.Image(3, 3, gray);\n        const imageData = new createImageData(3, 3);\n        image.toImageData(imageData);\n\n        expect(Array.from(imageData.data)).toEqual([\n            255,255,255,255,   0,0,0,255,      128,128,128,255,\n            85,85,85,255,      85,85,85,255,   85,85,85,255,\n            70,70,70,255,      70,70,70,255,   70,70,70,255\n        ]);\n\n        image.free();\n    });\n\n    it(\"draw\", function() {\n\n        const canvas = createCanvas(3, 3);\n\n        const rgba = new createImageData(new Uint8ClampedArray([\n            255,255,255,0,   0,0,0,0,         128,128,128,0,\n            255,0,0,0,       0,255,0,0,       0,0,255,0,\n            0,0,0,0,         255,255,255,0,   0,0,0,0,\n        ]), 3, 3);\n\n        // Create an Image via Grayscale conversion\n        const image = doxa.fromImageData(rgba);\n\n        // Draw image onto our canvas\n        image.draw(canvas);\n\n        // Pull data out of the canvas and compare\n        const result = canvas.getContext('2d').getImageData(0, 0, image.width, image.height);\n        expect(Array.from(result.data)).toEqual([\n            255,255,255,255,   0,0,0,255,         128,128,128,255,\n            85,85,85,255,      85,85,85,255,      85,85,85,255,\n            0,0,0,255,         255,255,255,255,   0,0,0,255\n        ]);\n\n        image.free();\n    });\n});\n"
  },
  {
    "path": "Bindings/WebAssembly/spec/speed.spec.js",
    "content": "/**\n * Speed Tests for DoxaJs\n *\n * Measures execution time for:\n * - Sauvola binarization\n * - WAN binarization\n * - GlobalThresholding (Otsu) binarization\n * - Full Performance calculation (ClassifiedPerformance + DRDM)\n *\n * Run with: npx jasmine spec/speed.spec.js\n */\n\nconst { loadImage, createCanvas } = require('canvas');\nconst { Doxa } = require('../dist/doxa.js');\n\n// Number of iterations for timing\nconst WARMUP_ITERATIONS = 3;\nconst TIMING_ITERATIONS = 10;\n\nlet doxa;\n\n/**\n * Read an image file and convert to Doxa.Image\n */\nasync function readImage(file) {\n    const image = await loadImage(file);\n    const canvas = createCanvas(image.width, image.height);\n    const ctx = canvas.getContext('2d');\n\n    ctx.drawImage(image, 0, 0);\n\n    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n    return doxa.fromImageData(imageData);\n}\n\n/**\n * Measure execution time of a function.\n * If the function returns a Doxa.Image, it will be freed AFTER timing measurement.\n */\nfunction measureTime(func, warmup = WARMUP_ITERATIONS, iterations = TIMING_ITERATIONS) {\n    // Warmup runs (free any returned images)\n    for (let i = 0; i < warmup; i++) {\n        const result = func();\n        if (result && typeof result.free === 'function') {\n            result.free();\n        }\n    }\n\n    // Timed runs\n    const times = [];\n    for (let i = 0; i < iterations; i++) {\n        const start = performance.now();\n        const result = func();\n        const end = performance.now();\n        times.push(end - start);\n\n        // Free after timing measurement\n        if (result && typeof result.free === 'function') {\n            result.free();\n        }\n    }\n\n    times.sort((a, b) => a - b);\n\n    return {\n        min: times[0],\n        max: times[times.length - 1],\n        avg: times.reduce((a, b) => a + b, 0) / times.length,\n        median: times[Math.floor(times.length / 2)]\n    };\n}\n\n/**\n * Format timing results for display\n */\nfunction formatResults(name, results, width, height) {\n    const pixels = width * height;\n    const mpixels = pixels / 1_000_000;\n    const throughput = mpixels / (results.avg / 1000);\n\n    return `\n${name}\n  Image size: ${width}x${height} (${mpixels.toFixed(2)} MP)\n  Min:    ${results.min.toFixed(3)} ms\n  Max:    ${results.max.toFixed(3)} ms\n  Avg:    ${results.avg.toFixed(3)} ms\n  Median: ${results.median.toFixed(3)} ms\n  Throughput: ${throughput.toFixed(2)} MP/s`;\n}\n\ndescribe(\"Doxa Speed Test Suite\", function() {\n    let grayscaleImage;\n    let groundTruthImage;\n    let binaryImage;\n    let imageWidth;\n    let imageHeight;\n\n    beforeAll(async function() {\n        console.log('\\n' + '='.repeat(60));\n        console.log('DoxaJs Speed Tests');\n        console.log('='.repeat(60));\n        console.log(`\\nWarmup iterations: ${WARMUP_ITERATIONS}`);\n        console.log(`Timing iterations: ${TIMING_ITERATIONS}`);\n\n        // Initialize WASM module\n        doxa = await Doxa.initialize();\n\n        // Load test images\n        console.log('\\nLoading test images...');\n        grayscaleImage = await readImage('../../README/2JohnC1V3.png');\n        binaryImage = await readImage('../../README/2JohnC1V3-Sauvola.png');\n        groundTruthImage = await readImage('../../README/2JohnC1V3-GroundTruth.png');\n\n        imageWidth = grayscaleImage.width;\n        imageHeight = grayscaleImage.height;\n\n        console.log(`Image: ${imageWidth}x${imageHeight}`);\n        console.log('\\n' + '-'.repeat(60));\n        console.log('BINARIZATION ALGORITHMS');\n        console.log('-'.repeat(60));\n    });\n\n    afterAll(function() {\n        // Clean up WASM memory\n        if (grayscaleImage) grayscaleImage.free();\n        if (groundTruthImage) groundTruthImage.free();\n        if (binaryImage) binaryImage.free();\n\n        console.log('\\n' + '='.repeat(60));\n        console.log('Speed tests completed');\n        console.log('='.repeat(60));\n    });\n\n    it(\"Sauvola binarization performance\", function() {\n        const params = { window: 75, k: 0.2 };\n\n        const results = measureTime(() => {\n            return doxa.toBinary(doxa.binarization.SAUVOLA, grayscaleImage, params);\n        });\n\n        console.log(formatResults('Sauvola', results, imageWidth, imageHeight));\n        expect(results.avg).toBeGreaterThan(0);\n    });\n\n    it(\"WAN binarization performance\", function() {\n        const params = { window: 75, k: 0.2 };\n\n        const results = measureTime(() => {\n            return doxa.toBinary(doxa.binarization.WAN, grayscaleImage, params);\n        });\n\n        console.log(formatResults('WAN', results, imageWidth, imageHeight));\n        expect(results.avg).toBeGreaterThan(0);\n    });\n\n    it(\"Otsu (GlobalThresholding) binarization performance\", function() {\n        const results = measureTime(() => {\n            return doxa.toBinary(doxa.binarization.OTSU, grayscaleImage, {});\n        });\n\n        console.log(formatResults('Otsu (GlobalThresholding)', results, imageWidth, imageHeight));\n        expect(results.avg).toBeGreaterThan(0);\n    });\n\n    it(\"Full Performance (ClassifiedPerformance + DRDM) calculation\", function() {\n        console.log('\\n' + '-'.repeat(60));\n        console.log('PERFORMANCE METRICS');\n        console.log('-'.repeat(60));\n\n        // Note: The WebAssembly binding calculates ClassifiedPerformance and DRDM together.\n        // Use Python binding's calculate_performance_ex for isolated measurements.\n        const results = measureTime(() => {\n            return doxa.calculatePerformance(groundTruthImage, binaryImage);\n        });\n\n        console.log(formatResults('Full Performance (ClassifiedPerformance + DRDM)', results, imageWidth, imageHeight));\n        expect(results.avg).toBeGreaterThan(0);\n    });\n});\n"
  },
  {
    "path": "Bindings/WebAssembly/spec/support/jasmine.json",
    "content": "{\n  \"spec_dir\": \"spec\",\n  \"spec_files\": [\n    \"**/*[sS]pec.?(m)js\"\n  ],\n  \"helpers\": [\n    \"helpers/**/*.?(m)js\"\n  ],\n  \"env\": {\n    \"stopSpecOnExpectationFailure\": false,\n    \"random\": true\n  }\n}\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Overview\n\nDoxa is a **header-only C++ image binarization framework** that converts grayscale images to binary (black and white). The core library has zero external dependencies and is designed to be lightweight and easy to integrate with other frameworks (OpenCV, Qt, etc.). Language bindings exist for Python and WebAssembly/JavaScript.\n\n## Build and Test Commands\n\nThe project uses CMake presets for unified builds. All commands run from the project root.\n\n### Quick Start (CMake Presets)\n\n```bash\n# Build and run C++ unit tests\ncmake --preset cpp-tests\ncmake --build build --config Release\nctest --test-dir build -C Release\n\n# Build and test Python bindings\ncmake --preset python\ncmake --build build-python --config Release\nctest --test-dir build-python -C Release\n\n# Build and test WebAssembly (requires Emscripten in PATH)\ncmake --preset wasm\ncmake --build build-wasm --config Release\nctest --test-dir build-wasm -C Release\n\n# Build and run performance benchmarks (Google Benchmark)\ncmake --preset benchmarks\ncmake --build build-bench --config Release\n./build-bench/Doxa.Bench/doxa_bench              # Linux/Mac\n.\\build-bench\\Doxa.Bench\\Release\\doxa_bench.exe  # Windows\n\n# Build everything (C++, Python, WASM)\ncmake --preset all\ncmake --build build --config Release\nctest --test-dir build -C Release\n```\n\n**Note:** On Windows with Visual Studio (multi-config generator), `--config Release` and `-C Release` are required. On Linux/Mac with single-config generators (Make, Ninja), these flags are optional.\n\n### C++ Unit Tests\n\nThe C++ test suite uses Google Test (fetched automatically via CMake).\n\n```bash\n# Using preset (recommended)\ncmake --preset cpp-tests\ncmake --build build --config Release\nctest --test-dir build -C Release\n\n# Or build directly from Doxa.Test\ncd Doxa.Test\ncmake -S . -B ./build\ncmake --build ./build --config Release\nctest --test-dir ./build -C Release  # Or run directly:\n./build/doxa_test  # Linux/Mac\n.\\build\\Release\\doxa_test.exe  # Windows\n```\n\n### Python Bindings (DoxaPy)\n\nDoxaPy requires Python 3.12+ and uses nanobind for C++ interop.\n\n```bash\n# Using preset (recommended)\ncmake --preset python\ncmake --build build-python --config Release\nctest --test-dir build-python -C Release\n\n# Or build from Bindings/Python directory\ncd Bindings/Python\npip install -r requirements.txt\npython copy-cpp-files.py\ncmake -S . -B ./build\ncmake --build ./build --config Release\npython test/test_doxa.py\n\n# Build distributable wheel (uses cibuildwheel)\npython -m build\n```\n\n### WebAssembly Bindings (DoxaJs)\n\nDoxaJs uses CMake with Emscripten toolchain.\n\n```bash\n# Using preset (recommended, requires emcmake in PATH)\ncmake --preset wasm\ncmake --build build-wasm --config Release\nctest --test-dir build-wasm -C Release\n\n# Or build directly with emcmake\nemcmake cmake -S . -B build-wasm -DCMAKE_BUILD_TYPE=Release\ncmake --build build-wasm --config Release\ncd Bindings/WebAssembly && npm test\n\n# Output: ./dist/doxaWasm.js and ./dist/doxaWasm.wasm\n```\n\n## Architecture\n\n### Header-Only Core Library\n\nThe entire core library is in `Doxa/*.hpp` files. There is no build step for the core library - just include the headers.\n\n**Key Files:**\n- `Doxa/Image.hpp` - Core 8-bit image data structure with move semantics\n- `Doxa/Algorithm.hpp` - Base algorithm interface using CRTP (Curiously Recurring Template Pattern)\n- `Doxa/Parameters.hpp` - Key-value parameter system (supports `{\"window\": 75, \"k\": 0.2}`)\n- `Doxa/PNM.hpp` - Image I/O for Portable Any-Map formats (PBM, PGM, PPM, PAM)\n- `Doxa/BinarizationFactory.hpp` - Factory pattern for algorithm instantiation\n- `Doxa/ClassifiedPerformance.hpp` - Performance metrics (Accuracy, F-Measure, Precision, Recall, MCC, PSNR, NRM)\n- `Doxa/DRDM.hpp` - Distance-Reciprocal Distortion Measure metric\n\n### Algorithm Organization\n\nAll binarization algorithms inherit from `Algorithm<T>` base class (CRTP pattern):\n\n**Global Thresholding:**\n- `Otsu.hpp` - Histogram-based single threshold\n\n**Local Adaptive Thresholding:**\n- `Sauvola.hpp`, `Niblack.hpp`, `Wolf.hpp`, `Nick.hpp`, `TRSingh.hpp`, `Bernsen.hpp`, `Phansalkar.hpp`, `ISauvola.hpp`, `Wan.hpp`, `Su.hpp`, `Gatos.hpp`, `Bataineh.hpp`, `AdOtsu.hpp`\n\nEach algorithm can be called statically via:\n```cpp\nImage binaryImage = Sauvola::ToBinaryImage(grayImage, parameters);\n```\n\nOr instantiated for reuse:\n```cpp\nSauvola sauvola;\nsauvola.Initialize(grayImage);\nsauvola.ToBinary(binaryImage, parameters);\n```\n\n### Calculation Optimizations\n\nThe framework includes multiple optimization strategies for local window operations:\n\n- `ChanMeanVarianceCalc.hpp` - Memory-efficient sliding window (Chan 2019)\n- `IntegralImageMeanVarianceCalc.hpp` - Integral image acceleration (Shafait 2008)\n- `LocalWindow.hpp` - Generic window iteration template\n- `GridCalc.hpp` - Grid-based calculations\n\nAlgorithms use these via template inheritance to avoid virtual function overhead.\n\n### Language Bindings Architecture\n\n**Python (DoxaPy):**\n- `Bindings/Python/src/DoxaPy.cpp` - nanobind wrapper exposing all 14 algorithms\n- Converts NumPy arrays ↔ Doxa Image objects\n- Usage pattern:\n  ```python\n  sauvola = doxapy.Binarization(doxapy.Binarization.Algorithms.SAUVOLA)\n  sauvola.initialize(grayscale_image)  # NumPy array\n  sauvola.to_binary(binary_image, {\"window\": 75, \"k\": 0.2})\n  ```\n- Build system: scikit-build-core + cibuildwheel for cross-platform wheels\n- Published to PyPI as `doxapy`\n\n**WebAssembly (DoxaJs):**\n- `Bindings/WebAssembly/DoxaWasm.cpp` - Emscripten bindings\n- `Bindings/WebAssembly/doxa.js` - JavaScript convenience wrapper\n- Works with raw memory pointers (WASM memory model)\n- Build output: `./dist/doxaWasm.js` and `./dist/doxaWasm.wasm`\n- Live demo: https://brandonmpetty.github.io/Doxa/WebAssembly\n\n### Integration with External Libraries\n\nThe `Image` class supports external memory management via `Image::Reference()`, allowing zero-copy integration with:\n- OpenCV (see `Demo/Cpp/demoOpenCV.cpp`)\n- Qt (see `Demo/Cpp/demoQt.cpp`)\n- PIL/Pillow (see `Demo/Python/demo.py`)\n\n## Testing Structure\n\n**C++ Tests (`Doxa.Test/`):**\n- Uses Google Test framework (fetched via CMake FetchContent)\n- Test files mirror the module structure: `ImageTests.cpp`, `BinarizationTests.cpp`, `CalculatorTests.cpp`, etc.\n- `ImageFixture.hpp` provides test utilities and sample images\n- `Resources/` contains ground truth images for validation\n- Requires C++17 standard\n- Tests focus on **correctness only** - no timing assertions\n\n**Performance Benchmarks (`Doxa.Bench/`):**\n- Uses Google Benchmark framework (fetched via CMake FetchContent)\n- Separate from unit tests - measures runtime performance with statistical rigor\n- Benchmark files: `GlobalThresholdBenchmarks.cpp`, `ClassifiedPerformanceBenchmarks.cpp`, `DRDMBenchmarks.cpp`, `CalculatorBenchmarks.cpp`\n- `BenchmarkHarness.hpp` exposes internal methods for benchmarking\n- Resource path is baked in at build time via `configure_file` (works from any working directory)\n- Always built in Release mode (benchmarks in Debug are meaningless)\n- Output formats: console table (default) or JSON (`--benchmark_out=file.json --benchmark_out_format=json`)\n\n**Comparing Benchmark Runs:**\n```bash\n# Save JSON output from two runs (e.g., before/after a change, or different platforms)\n./doxa_bench --benchmark_out=before.json --benchmark_out_format=json\n# ... make changes, rebuild ...\n./doxa_bench --benchmark_out=after.json --benchmark_out_format=json\n\n# Compare all benchmarks\npython build-bench/_deps/googlebenchmark-src/tools/compare.py benchmarks before.json after.json\n\n# Compare only specific benchmarks\npython build-bench/_deps/googlebenchmark-src/tools/compare.py benchmarksfiltered before.json after.json BM_ToBinary\n\n# Compare two benchmarks within the same run (e.g., scalar vs SIMD)\npython build-bench/_deps/googlebenchmark-src/tools/compare.py filters results.json BM_ToBinary_Scalar BM_ToBinary_SIMD\n```\n\n**Python Tests:**\n- `Bindings/Python/test/test_doxa.py` - Basic functionality and performance tests\n- Run with: `python test/test_doxa.py`\n\n## Key Design Patterns\n\n1. **CRTP (Curiously Recurring Template Pattern)**: `Algorithm<T>` base class provides static polymorphism without virtual function overhead\n\n2. **Template-Based Calculators**: Algorithms inherit from calculator classes (e.g., `ChanMeanVarianceCalc`) using templates for zero-cost abstractions\n\n3. **Factory Pattern**: `BinarizationFactory` enables dynamic algorithm selection at runtime\n\n4. **Parameter Variant System**: `Parameters` class uses variant<int, double> for flexible, serializable configuration\n\n5. **Move Semantics**: `Image` class uses move constructors/assignment for efficient memory management\n\n## Common Development Workflows\n\n### Adding a New Binarization Algorithm\n\n1. Create `Doxa/MyAlgorithm.hpp`\n2. Inherit from `Algorithm<MyAlgorithm>` (CRTP pattern)\n3. Choose appropriate calculator base class (e.g., `ChanMeanVarianceCalc`)\n4. Implement `CalculateThreshold()` method with algorithm-specific logic\n5. Add algorithm to `BinarizationFactory.hpp`\n6. Create corresponding test in `Doxa.Test/BinarizationTests.cpp`\n7. Update bindings in `DoxaPy.cpp` and `DoxaWasm.cpp`\n\n### Modifying Python Bindings\n\n1. Edit `Bindings/Python/src/DoxaPy.cpp` (nanobind code)\n2. Rebuild: `cmake --build ./build --config Release`\n3. Test: `python test/test_doxa.py`\n4. For distribution: update version in `pyproject.toml` and run `python -m build`\n\n### Modifying WebAssembly Bindings\n\n1. Edit `Bindings/WebAssembly/DoxaWasm.cpp` (Emscripten bindings)\n2. Optionally update `doxa.js` (JavaScript wrapper)\n3. Rebuild: `emcmake cmake -S . -B build-wasm && cmake --build build-wasm`\n4. Test: `cd Bindings/WebAssembly && npm test`\n\n### Adding or Modifying Benchmarks\n\n1. Edit or create benchmark files in `Doxa.Bench/` (e.g., `SIMDBenchmarks.cpp`)\n2. Use `BenchmarkHarness.hpp` for test harness classes that expose internal methods\n3. Setup code goes **before** the `for (auto _ : state)` loop (not timed)\n4. Only the loop body is measured; use `benchmark::DoNotOptimize()` to prevent dead code elimination\n5. Add new `.cpp` files to `Doxa.Bench/CMakeLists.txt`\n6. Build: `cmake --build build-bench --config Release`\n7. Run: `./build-bench/Doxa.Bench/doxa_bench` (or with `--benchmark_filter=BM_MyBench` to run specific benchmarks)\n\n**CI Integration:** The `benchmarks.yml` workflow runs on all 3 platforms (Linux, Windows, macOS). Each platform has its own independent baseline tracked via `benchmark-action/github-action-benchmark` in the `gh-pages` branch. PR comments alert on regressions >20%.\n\n## Performance Metrics\n\nThe framework includes comprehensive performance evaluation tools:\n\n- **ClassifiedPerformance**: Accuracy, F-Measure, Precision, Recall, MCC, PSNR, NRM\n- **Pseudo-Metrics**: Pseudo F-Measure, Precision, Recall (for degraded documents)\n- **DRDM**: Distance-Reciprocal Distortion Measure (perceptual quality)\n\nUsage:\n```cpp\nClassifiedPerformance performance = ClassifiedPerformance::CalculatePerformance(groundTruth, binaryImage);\n```\n\n## Build System Notes\n\n- **C++ Core**: Header-only, no build required\n- **C++ Tests**: CMake 3.16+ or Visual Studio 2019+\n- **Python**: CMake + nanobind + scikit-build-core (requires Python 3.12+)\n- **WebAssembly**: CMake + Emscripten toolchain (use `emcmake cmake`)\n- **Standard**: C++17\n- **Architecture**: 64-bit only (enforced in cibuildwheel config)\n- **Performance Benchmarks**: CMake + Google Benchmark (fetched via FetchContent)\n- **CMake Presets**: `cpp-tests`, `cpp-tests-debug`, `python`, `wasm`, `benchmarks`, `all`\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.16)\nproject(doxa VERSION 1.0.0)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Build options\noption(DOXA_BUILD_CPP_TESTS \"Build C++ unit tests\" ON)\noption(DOXA_BUILD_PYTHON \"Build Python bindings\" OFF)\noption(DOXA_BUILD_WASM \"Build WebAssembly bindings (requires emcmake)\" OFF)\noption(DOXA_BUILD_BENCHMARKS \"Build performance benchmarks (Google Benchmark)\" OFF)\noption(DOXA_BUILD_MATLAB \"Build MATLAB MEX bindings (requires MATLAB)\" OFF)\noption(DOXA_ENABLE_SIMD \"Enable SIMD optimizations\" ON)\n\n# Enable CTest for all test types\ninclude(CTest)\nenable_testing()\n\n# Propagate SIMD option to subdirectories\nset(DOXA_ENABLE_SIMD ${DOXA_ENABLE_SIMD} CACHE BOOL \"\" FORCE)\nset(DOXAPY_ENABLE_SIMD ${DOXA_ENABLE_SIMD} CACHE BOOL \"\" FORCE)\n\n# C++ Tests (native build only)\nif(DOXA_BUILD_CPP_TESTS AND NOT EMSCRIPTEN)\n    add_subdirectory(Doxa.Test)\nendif()\n\n# Performance Benchmarks (native build only, always Release)\nif(DOXA_BUILD_BENCHMARKS AND NOT EMSCRIPTEN)\n    add_subdirectory(Doxa.Bench)\nendif()\n\n# Python Bindings (native build only)\nif(DOXA_BUILD_PYTHON AND NOT EMSCRIPTEN)\n    find_package(Python 3.12 REQUIRED COMPONENTS Interpreter)\n    # Sync headers from core library\n    execute_process(\n        COMMAND ${Python_EXECUTABLE} copy-cpp-files.py\n        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Bindings/Python\n    )\n    add_subdirectory(Bindings/Python)\n\n    # Add Python tests to CTest\n    add_test(NAME python_tests\n        COMMAND ${Python_EXECUTABLE} -m unittest discover -s test -p \"test_*.py\" -v\n        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Bindings/Python\n    )\n    # Set PYTHONPATH so tests can find the built doxapy module in dist/\n    set_tests_properties(python_tests PROPERTIES\n        ENVIRONMENT \"PYTHONPATH=${CMAKE_SOURCE_DIR}/Bindings/Python/dist\"\n    )\nendif()\n\n# MATLAB MEX Bindings (native build only)\nif(DOXA_BUILD_MATLAB AND NOT EMSCRIPTEN)\n    find_package(Matlab COMPONENTS MAIN_PROGRAM)\n    if(Matlab_FOUND)\n        add_subdirectory(Bindings/Matlab)\n    else()\n        message(WARNING \"DOXA_BUILD_MATLAB=ON but MATLAB not found. \"\n            \"Skipping MATLAB MEX bindings. Install MATLAB or set Matlab_ROOT_DIR.\")\n    endif()\nendif()\n\n# WebAssembly - two modes:\n# 1. Direct Emscripten build (when using emcmake)\n# 2. ExternalProject build (when doing native build with DOXA_BUILD_WASM=ON)\nif(EMSCRIPTEN)\n    add_subdirectory(Bindings/WebAssembly)\nelseif(DOXA_BUILD_WASM)\n    # Platform-specific script extensions (avoid picking up .cmd/.bat on WSL2)\n    if(WIN32)\n        set(CMD_EXT \".cmd\")\n        set(BAT_EXT \".bat\")\n    else()\n        set(CMD_EXT \"\")\n        set(BAT_EXT \"\")\n    endif()\n\n    # Build WASM as external project using emcmake\n    find_program(EMCMAKE NAMES emcmake${BAT_EXT}\n        HINTS ENV EMSDK\n        PATH_SUFFIXES upstream/emscripten\n    )\n\n    if(EMCMAKE)\n        message(STATUS \"Found emcmake: ${EMCMAKE}\")\n        include(ExternalProject)\n        ExternalProject_Add(wasm_build\n            SOURCE_DIR ${CMAKE_SOURCE_DIR}\n            BINARY_DIR ${CMAKE_BINARY_DIR}/wasm\n            CONFIGURE_COMMAND ${EMCMAKE} cmake ${CMAKE_SOURCE_DIR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}\n            BUILD_COMMAND cmake --build . --config ${CMAKE_BUILD_TYPE}\n            INSTALL_COMMAND \"\"\n            TEST_COMMAND \"\"\n        )\n        # Add WASM tests to CTest (runs after wasm_build)\n        find_program(NPM_EXECUTABLE NAMES npm${CMD_EXT})\n        if(NPM_EXECUTABLE)\n            add_test(NAME wasm_tests\n                COMMAND ${NPM_EXECUTABLE} test\n                WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Bindings/WebAssembly\n            )\n        endif()\n    else()\n        message(WARNING \"DOXA_BUILD_WASM=ON but emcmake not found. \"\n            \"Make sure Emscripten SDK is installed and run emsdk_env before configuring CMake.\")\n    endif()\nendif()\n"
  },
  {
    "path": "CMakePresets.json",
    "content": "{\n  \"version\": 6,\n  \"configurePresets\": [\n    {\n      \"name\": \"cpp-tests\",\n      \"displayName\": \"C++ Tests\",\n      \"binaryDir\": \"${sourceDir}/build-cpp-tests\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"cpp-tests-debug\",\n      \"displayName\": \"C++ Tests (Debug)\",\n      \"binaryDir\": \"${sourceDir}/build-cpp-tests\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Debug\",\n        \"DOXA_BUILD_CPP_TESTS\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"python\",\n      \"displayName\": \"Python Bindings\",\n      \"binaryDir\": \"${sourceDir}/build-python\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"OFF\",\n        \"DOXA_BUILD_PYTHON\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"wasm\",\n      \"displayName\": \"WebAssembly Bindings\",\n      \"binaryDir\": \"${sourceDir}/build-wasm\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"OFF\",\n        \"DOXA_BUILD_WASM\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"benchmarks\",\n      \"displayName\": \"Performance Benchmarks\",\n      \"binaryDir\": \"${sourceDir}/build-bench\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"OFF\",\n        \"DOXA_BUILD_BENCHMARKS\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"matlab\",\n      \"displayName\": \"MATLAB MEX Bindings\",\n      \"binaryDir\": \"${sourceDir}/build-matlab\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"OFF\",\n        \"DOXA_BUILD_MATLAB\": \"ON\"\n      }\n    },\n    {\n      \"name\": \"all\",\n      \"displayName\": \"All Components (C++, Python, WASM, MATLAB)\",\n      \"binaryDir\": \"${sourceDir}/build\",\n      \"cacheVariables\": {\n        \"CMAKE_BUILD_TYPE\": \"Release\",\n        \"DOXA_BUILD_CPP_TESTS\": \"ON\",\n        \"DOXA_BUILD_PYTHON\": \"ON\",\n        \"DOXA_BUILD_WASM\": \"ON\",\n        \"DOXA_BUILD_MATLAB\": \"ON\"\n      }\n    }\n  ],\n  \"buildPresets\": [\n    { \"name\": \"cpp-tests\", \"configurePreset\": \"cpp-tests\" },\n    { \"name\": \"cpp-tests-debug\", \"configurePreset\": \"cpp-tests-debug\" },\n    { \"name\": \"python\", \"configurePreset\": \"python\" },\n    { \"name\": \"wasm\", \"configurePreset\": \"wasm\" },\n    { \"name\": \"benchmarks\", \"configurePreset\": \"benchmarks\" },\n    { \"name\": \"matlab\", \"configurePreset\": \"matlab\" },\n    { \"name\": \"all\", \"configurePreset\": \"all\" }\n  ],\n  \"testPresets\": [\n    { \"name\": \"cpp-tests\", \"configurePreset\": \"cpp-tests\", \"configuration\": \"Release\" },\n    { \"name\": \"cpp-tests-debug\", \"configurePreset\": \"cpp-tests-debug\", \"configuration\": \"Debug\" },\n    { \"name\": \"python\", \"configurePreset\": \"python\", \"configuration\": \"Release\" },\n    { \"name\": \"wasm\", \"configurePreset\": \"wasm\", \"configuration\": \"Release\" },\n    { \"name\": \"matlab\", \"configurePreset\": \"matlab\", \"configuration\": \"Release\" },\n    { \"name\": \"all\", \"configurePreset\": \"all\", \"configuration\": \"Release\" }\n  ]\n}\n"
  },
  {
    "path": "Demo/Cpp/.gitignore",
    "content": "*.png\n*.obj\n*.dll\n*.exe"
  },
  {
    "path": "Demo/Cpp/demo.cpp",
    "content": "#include <iostream>\n#include \"../../Doxa/Sauvola.hpp\"\n#include \"../../Doxa/ClassifiedPerformance.hpp\"\n#include \"../../Doxa/DRDM.hpp\"\n#include \"../../Doxa/PNM.hpp\"\n\n// Visual C++ Compiler:\n//cl /EHsc /std:c++17 /O2 demo.cpp\n\n// Clang C++ Compiler - Mac OSX:\n//clang++ -Wall -std=c++17 -L /usr/local/Cellar/llvm/7.0.1/lib/ -lc++fs -O3 demo.cpp -o demo\n\n\nvoid DisplayPerformance(const Doxa::Image& groundTruthImage, const Doxa::Image& binaryImage)\n{\n\tDoxa::ClassifiedPerformance::Classifications classifications;\n\tbool canCompare = Doxa::ClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\tif (!canCompare)\n\t{\n\t\tstd::cout << \"Files cannot be compared.  Ensure both images have the same height and width.\" << std::endl;\n\t\treturn;\n\t}\n\n\tdouble scoreAccuracy = Doxa::ClassifiedPerformance::CalculateAccuracy(classifications);\n\tdouble scoreFM = Doxa::ClassifiedPerformance::CalculateFMeasure(classifications);\n\tdouble scoreMCC = Doxa::ClassifiedPerformance::CalculateMCC(classifications);\n\tdouble scorePSNR = Doxa::ClassifiedPerformance::CalculatePSNR(classifications);\n\tdouble scoreNRM = Doxa::ClassifiedPerformance::CalculateNRM(classifications);\n\tdouble scoreDRDM = Doxa::DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\n\tstd::cout << std::endl\n\t\t<< \"Accuracy:\\t\"\t<< scoreAccuracy << std::endl\n\t\t<< \"F-Measure:\\t\"\t<< scoreFM << std::endl\n\t\t<< \"MCC:\\t\\t\"\t\t<< scoreMCC << std::endl\n\t\t<< \"PSNR:\\t\\t\"\t\t<< scorePSNR << std::endl\n\t\t<< \"NRM:\\t\\t\"\t\t<< scoreNRM << std::endl\n\t\t<< \"DRDM:\\t\\t\"\t\t<< scoreDRDM << std::endl\n\t\t<< std::endl;\n}\n\nint main()\n{\n\t// Read image and turn it into an 8bit grayscale.\n\t// The PNM reader is obviously limiting, but does offer 8 different color to grayscale algorithms.\n\tDoxa::Image doxaGsImage = Doxa::PNM::Read(R\"(2JohnC1V3.ppm)\", \n\t\tDoxa::Parameters({{\"grayscale\", Doxa::GrayscaleAlgorithms::MEAN}})); // Optional\n\n\t// Use a binarization algorithm to convert it into black and white\n\tconst Doxa::Parameters parameters({ {\"window\", 25}, {\"k\", 0.10} });\n\tDoxa::Sauvola::UpdateToBinary(doxaGsImage, parameters);\n\n\t// If you want to store the binary image in a new object, run this:\n\t//Doxa::Image doxaBinImage = Doxa::Sauvola::ToBinaryImage(doxaGsImage, parameters);\n\n\t// Load the ground truth image\n\tDoxa::Image doxaGtImage = Doxa::PNM::Read(R\"(2JohnC1V3-GroundTruth.pbm)\");\n\n\t// Get Performance information\n\tDisplayPerformance(doxaGtImage, doxaGsImage);\n\n\t// Save the processed image\n\tDoxa::PNM::Write(doxaGsImage, R\"(binary.pbm)\");\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Demo/Cpp/demoOpenCV.cpp",
    "content": "#include <opencv2/opencv.hpp>\n#include \"../../Doxa/Sauvola.hpp\"\n#include \"../../Doxa/ClassifiedPerformance.hpp\"\n#include \"../../Doxa/DRDM.hpp\"\n\n// Visual C++ Compiler:\n//cl /EHsc /std:c++17 /O2 /I\"%OPENCV_DIR%\\include\" \"%OPENCV_DIR%\\x64\\vc15\\lib\\opencv_world451.lib\"  demoOpenCV.cpp\n\n\nDoxa::Image ToDoxaImageReference(const cv::Mat& gsImage)\n{\n\tassert(gsImage.channels() == 1);\n\treturn Doxa::Image::Reference(gsImage.cols, gsImage.rows, (Doxa::Pixel8*)gsImage.data);\n}\n\ncv::Mat FromDoxaImage(const Doxa::Image& binaryImage)\n{\n\treturn cv::Mat(binaryImage.height, binaryImage.width, CV_8UC1, binaryImage.data);\n}\n\nvoid DisplayPerformance(const Doxa::Image& groundTruthImage, const Doxa::Image& binaryImage)\n{\n\tDoxa::ClassifiedPerformance::Classifications classifications;\n\tbool canCompare = Doxa::ClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\tif (!canCompare)\n\t{\n\t\tstd::cout << \"Files cannot be compared.  Ensure both images have the same height and width.\" << std::endl;\n\t\treturn;\n\t}\n\t\n\tdouble scoreAccuracy = Doxa::ClassifiedPerformance::CalculateAccuracy(classifications);\n\tdouble scoreFM = Doxa::ClassifiedPerformance::CalculateFMeasure(classifications);\n\tdouble scoreMCC = Doxa::ClassifiedPerformance::CalculateMCC(classifications);\n\tdouble scorePSNR = Doxa::ClassifiedPerformance::CalculatePSNR(classifications);\n\tdouble scoreNRM = Doxa::ClassifiedPerformance::CalculateNRM(classifications);\n\tdouble scoreDRDM = Doxa::DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\t\n\tstd::cout << std::endl\n\t\t<< \"Accuracy:\\t\"\t<< scoreAccuracy << std::endl\n\t\t<< \"F-Measure:\\t\"\t<< scoreFM << std::endl\n\t\t<< \"MCC:\\t\\t\"\t\t<< scoreMCC << std::endl\n\t\t<< \"PSNR:\\t\\t\"\t\t<< scorePSNR << std::endl\n\t\t<< \"NRM:\\t\\t\"\t\t<< scoreNRM << std::endl\n\t\t<< \"DRDM:\\t\\t\"\t\t<< scoreDRDM << std::endl\n\t\t<< std::endl;\n}\n\nint main()\n{\n\t// Read image and turn it into an 8bit grayscale.  This should be a CV_8UC1 structure.\n\tcv::Mat cvGsImage = cv::imread(R\"(2JohnC1V3.png)\", cv::IMREAD_GRAYSCALE);\n\t\n\t// Create a reference to the cv::Mat image.\n\t// Not only is this effecient, but any changes made by our algorithm apply directly\n\t// to the image being referenced.\n\tDoxa::Image doxaGsImage = ToDoxaImageReference(cvGsImage);\n\n\t// Use a binarization algorithm to convert it into black and white\n\tconst Doxa::Parameters parameters({ {\"window\", 25}, {\"k\", 0.10} });\n\tDoxa::Sauvola::UpdateToBinary(doxaGsImage, parameters);\n\t\n\t// If you want to store the binary image in a new object, run this:\n\t//Doxa::Image doxaBinImage = Doxa::Sauvola::ToBinaryImage(doxaGsImage, parameters);\n\t//cv::Mat cvBinImage = FromDoxaImage(doxaBinImage);\n\n\t// Load the ground truth image\n\tcv::Mat cvGtImage = cv::imread(R\"(2JohnC1V3-GroundTruth.png)\", cv::IMREAD_GRAYSCALE);\n\tDoxa::Image doxaGtImage = ToDoxaImageReference(cvGtImage);\n\t\n\t// Get Performance information\n\tDisplayPerformance(doxaGtImage, doxaGsImage);\n\n\t// Save the processed image\n\tcv::imwrite(R\"(binary.png)\", cvGsImage);\n\t\n\treturn 0;\n}\n"
  },
  {
    "path": "Demo/Cpp/demoQt.cpp",
    "content": "#include <QImage>\n#include <iostream>\n#include <cassert>\n#include \"../../Doxa/Sauvola.hpp\"\n#include \"../../Doxa/ClassifiedPerformance.hpp\"\n#include \"../../Doxa/DRDM.hpp\"\n\n// Build Instructions - Windows\n// qmake\n// nmake\n\n\nDoxa::Image ToDoxaImageReference(const QImage& gsImage)\n{\n\tassert(gsImage.format() == QImage::Format_Grayscale8);\n\treturn Doxa::Image::Reference(gsImage.width(), gsImage.height(), (Doxa::Pixel8*)gsImage.bits());\n}\n\nQImage FromDoxaImage(const Doxa::Image& binaryImage)\n{\n\t// This QImage object does not contain a copy of the image memory, but a reference to it.\n\treturn QImage(binaryImage.data, binaryImage.width, binaryImage.height, binaryImage.width, QImage::Format_Grayscale8);\n}\n\nvoid DisplayPerformance(const Doxa::Image& groundTruthImage, const Doxa::Image& binaryImage)\n{\n\tDoxa::ClassifiedPerformance::Classifications classifications;\n\tbool canCompare = Doxa::ClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage);\n\tif (!canCompare)\n\t{\n\t\tstd::cout << \"Files cannot be compared.  Ensure both images have the same height and width.\" << std::endl;\n\t\treturn;\n\t}\n\t\n\tdouble scoreAccuracy = Doxa::ClassifiedPerformance::CalculateAccuracy(classifications);\n\tdouble scoreFM = Doxa::ClassifiedPerformance::CalculateFMeasure(classifications);\n\tdouble scoreMCC = Doxa::ClassifiedPerformance::CalculateMCC(classifications);\n\tdouble scorePSNR = Doxa::ClassifiedPerformance::CalculatePSNR(classifications);\n\tdouble scoreNRM = Doxa::ClassifiedPerformance::CalculateNRM(classifications);\n\tdouble scoreDRDM = Doxa::DRDM::CalculateDRDM(groundTruthImage, binaryImage);\n\t\n\tstd::cout << std::endl\n\t\t<< \"Accuracy:\\t\"\t<< scoreAccuracy << std::endl\n\t\t<< \"F-Measure:\\t\"\t<< scoreFM << std::endl\n\t\t<< \"MCC:\\t\\t\"\t\t<< scoreMCC << std::endl\n\t\t<< \"PSNR:\\t\\t\"\t\t<< scorePSNR << std::endl\n\t\t<< \"NRM:\\t\\t\"\t\t<< scoreNRM << std::endl\n\t\t<< \"DRDM:\\t\\t\"\t\t<< scoreDRDM << std::endl\n\t\t<< std::endl;\n}\n\nint main()\n{\n\t// Read image and turn it into an 8bit grayscale.\n\tQImage qtGsImage(R\"(2JohnC1V3.png)\");\n\tqtGsImage = qtGsImage.convertToFormat(QImage::Format_Grayscale8);\n\t\n\t// Create a reference to the QImage.\n\t// Not only is this effecient, but any changes made by our algorithm apply directly\n\t// to the image being referenced.\n\tDoxa::Image doxaGsImage = ToDoxaImageReference(qtGsImage);\n\n\t// Use a binarization algorithm to convert it into black and white\n\tconst Doxa::Parameters parameters({ {\"window\", 25}, {\"k\", 0.10} });\n\tDoxa::Sauvola::UpdateToBinary(doxaGsImage, parameters);\n\t\n\t// If you want to store the binary image in a new object, run this:\n\t//Doxa::Image doxaBinImage = Doxa::Sauvola::ToBinaryImage(doxaGsImage, parameters);\n\t//QImage qtBinImage = FromDoxaImage(doxaBinImage);\n\n\t// Load the ground truth image\n\tQImage qtGtImage(R\"(2JohnC1V3-GroundTruth.png)\");\n\tqtGtImage = qtGtImage.convertToFormat(QImage::Format_Grayscale8);\n\tDoxa::Image doxaGtImage = ToDoxaImageReference(qtGtImage);\n\t\n\t// Get Performance information\n\tDisplayPerformance(doxaGtImage, doxaGsImage);\n\n\t// Save the processed image\n\tqtGsImage.save(R\"(binary.png)\");\n\t\n\treturn 0;\n}\n"
  },
  {
    "path": "Demo/Cpp/demoQt.pro",
    "content": "######################################################################\n# Automatically generated by qmake (3.1) Fri Jan 22 23:00:16 2021\n######################################################################\n\nTEMPLATE = app\nTARGET = demoqt\nINCLUDEPATH += .\n\nCONFIG += console\nQMAKE_CXXFLAGS += /std:c++17\n\n# The following define makes your compiler warn you if you use any\n# feature of Qt which has been marked as deprecated (the exact warnings\n# depend on your compiler). Please consult the documentation of the\n# deprecated API in order to know how to port your code away from it.\nDEFINES += QT_DEPRECATED_WARNINGS\n\n# You can also make your code fail to compile if you use deprecated APIs.\n# In order to do so, uncomment the following line.\n# You can also select to disable deprecated APIs only up to a certain version of Qt.\n#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0\n\n# Input\nHEADERS += ../../Doxa/Sauvola.hpp \\\n           ../../Doxa/Algorithm.hpp \\\n           ../../Doxa/Image.hpp \\\n           ../../Doxa/Types.hpp \\\n           ../../Doxa/Parameters.hpp \\\n           ../../Doxa/Palette.hpp \\\n           ../../Doxa/LocalWindow.hpp \\\n           ../../Doxa/Region.hpp \\\n           ../../Doxa/ChanMeanVarianceCalc.hpp \\\n           ../../Doxa/ClassifiedPerformance.hpp \\\n           ../../Doxa/DRDM.hpp\nSOURCES += demoQt.cpp\n"
  },
  {
    "path": "Demo/Matlab/demo.m",
    "content": "% Doxa Binarization Framework - MATLAB Demo\n%\n% This demo shows how to read an image, convert it to grayscale, binarize it,\n% and calculate performance metrics using the Doxa framework.\n%\n% Requirements:\n%   - Build the MEX files: cmake --preset matlab && cmake --build build-matlab --config Release\n%   - Add the MEX output directory to the MATLAB path\n\n% Read a color image and convert to grayscale\nimg = Doxa.Image('../../Doxa.Test/Resources/2JohnC1V3.ppm', Doxa.Grayscale.QT);\n\n% Binarize using the Sauvola algorithm\nbinary = Doxa.binarize(Doxa.Algorithms.SAUVOLA, img, window=27, k=0.1);\n\n% Load a ground truth image and calculate performance\ngt = Doxa.Image('../../Doxa.Test/Resources/2JohnC1V3-GroundTruth.pbm');\n\n% Example: Pseudo-metrics with weight files\npw = Doxa.readWeights('../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_PWeights.dat');\nrw = Doxa.readWeights('../../Doxa.Test/Resources/2JohnC1V3-GroundTruth_RWeights.dat');\nmetrics = Doxa.calculatePerformance(gt, binary, precisionWeights=pw, recallWeights=rw);\n\ndisp('Performance Metrics:');\ndisp(metrics);\n\n% Display results\nfigure('Name', 'Doxa Binarization Demo');\nsubplot(1, 3, 1);\nimshow(imread('../../Doxa.Test/Resources/2JohnC1V3.ppm'));\ntitle('Original');\n\nsubplot(1, 3, 2);\nimshow(img.toArray());\ntitle('Grayscale');\n\nsubplot(1, 3, 3);\nimshow(binary.toArray());\ntitle('Sauvola Binary');\n\n% Example: In-place binarization (modifies the image directly)\n% Doxa.updateToBinary(Doxa.Algorithms.SAUVOLA, img, window=75, k=0.2);\n"
  },
  {
    "path": "Demo/NodeJS/.gitignore",
    "content": "*.png"
  },
  {
    "path": "Demo/NodeJS/index.js",
    "content": "/**\n * Doxa NodeJS Demo\n * This demo uses the WASM bindings and helper classes to seemlessly call into Doxa's binarization routines.\n * The code below gives an example of how to read an image, convert it to binary, and get performance stats.\n * We are using the image processing library Sharp to show how to read and write images in NodeJS.\n */\nconst { Doxa } = require('../../Bindings/WebAssembly/dist/doxa.js');\nconst sharp = require('sharp');\n\n/**\n * An example image reader wrapper around Sharp.\n * @param {object} doxa Initialized Doxa instance\n * @param {*} file Input file location.  Should be 8b grayscale, 24b RGB, or 32b RGBA.\n * @param {number} algorithm Grayscale algorithm enum value (e.g. doxa.grayscale.MEAN). Defaults to MEAN.\n */\nasync function readImage(doxa, file, algorithm) {\n\treturn sharp(file)\n\t\t.raw()\n\t\t.toBuffer({ resolveWithObject: true })\n\t\t.then(content => {\n\t\t\treturn doxa.toGrayscale(\n\t\t\t\tcontent.data, content.info.width, content.info.height, content.info.channels, algorithm);\n\t\t});\n}\n\n/**\n * An example image writer wrapper around Sharp.\n * @param {*} image A binary Doxa Image object\n * @param {*} file Output file location.  This can be any supported format.\n */\nasync function writeImage(image, file) {\n\treturn sharp(Buffer.from(image.data()), {\n\t\traw: {\n\t\t\twidth: image.width,\n\t\t\theight: image.height,\n\t\t\tchannels: 1 // b&w\n\t\t}\n\t}).toFile(file);\n}\n\nasync function demo() {\n\n\t// Initialize the Doxa framework\n\tconst doxa = await Doxa.initialize();\n\n\t// Read in the Ground Truth - 8bit\n\tconst gtImage = await readImage(doxa, '../../README/2JohnC1V3-GroundTruth.png');\n\n\t// Read in the target image - 8b, 24b, 32b.  If color, convert to grayscale.\n\tconst image = await readImage(doxa, '../../README/2JohnC1V3.png', doxa.grayscale.MEAN);\n\n\t// Generate a binary image\n\tconst binImage = doxa.toBinary(doxa.binarization.SAUVOLA, image, { window: 27, k: 0.10 });\n\n\t// Get performance information\n\tconst perf = doxa.calculatePerformance(gtImage, binImage);\n\tconsole.dir(perf);\n\n\t// Write file\n\tawait writeImage(binImage, 'binary.png');\n\n\t// Remember to free the memory of your WASM based images\n\tgtImage.free();\n\timage.free();\n\tbinImage.free();\n}\n\n// Run our demo\ndemo();\n"
  },
  {
    "path": "Demo/NodeJS/package.json",
    "content": "{\n  \"name\": \"nodejsdemo\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A simple demo showing how to use the Doxa library with NodeJS.\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node index.js\"\n  },\n  \"author\": \"\",\n  \"license\": \"CC0-1.0\",\n  \"devDependencies\": {\n    \"sharp\": \"^0.34.5\"\n  }\n}\n"
  },
  {
    "path": "Demo/Python/demo.py",
    "content": "from PIL import Image\nimport numpy as np\nimport os\n\n# Attempt to load your local doxapy.abi3.so / doxapy.pyd build first\nimport sys\nsys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'Bindings', 'Python', 'dist')))\n\nimport doxapy\n\n# Read an image.  If its color, use one of our many Grayscale algorithms to convert it\ndef read_image(file, algorithm=doxapy.GrayscaleAlgorithms.MEAN):\n    image = Image.open(file)\n\n    # If already in grayscale or binary, do not convert it\n    if image.mode == 'L':\n        return np.array(image)\n    \n    # Read the color image\n    rgb_image = np.array(image.convert('RGB') if image.mode not in ('RGB', 'RGBA') else image)\n\n    # Use Doxa to convert grayscale\n    return doxapy.to_grayscale(algorithm, rgb_image)\n\n\n# Use Doxa to convert our image into grayscale, if it isn't already\ngrayscale_image = read_image(\"../../Doxa.Test/Resources/2JohnC1V3.ppm\", doxapy.GrayscaleAlgorithms.MEAN)\n\n# Convert the grayscale image to binary, returning a new image\n# NOTE: Algorithm parameters are options.  Defaults are provided.\nbinary_image = doxapy.to_binary(doxapy.Binarization.Algorithms.SAUVOLA, grayscale_image, {\"window\": 75, \"k\": 0.2})\n\n# Calculate the binarization performance using a Ground Truth image\ngroundtruth_image = read_image(\"../../Doxa.Test/Resources/2JohnC1V3-GroundTruth.pbm\")\nperformance = doxapy.calculate_performance(groundtruth_image, binary_image)\nprint(performance)\n\n# Display our resulting image\nImage.fromarray(binary_image).show()\n\n# Example: How to update a grayscale to binary in place\n#doxapy.update_to_binary(doxapy.Binarization.Algorithms.SAUVOLA, grayscale_image, {\"window\": 75, \"k\": 0.2})\n\n# Example: For testing parameter changes in a tight loop\n#binary_image = np.empty(grayscale_image.shape, grayscale_image.dtype)\n#sauvola = doxapy.Binarization(doxapy.Binarization.Algorithms.SAUVOLA)\n#sauvola.initialize(grayscale_image)\n#sauvola.to_binary(binary_image, {\"window\": 75, \"k\": 0.2})\n"
  },
  {
    "path": "Demo/WebJS/index.html",
    "content": "<!doctype html>\n<html lang=\"en-us\">\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\n\t\t<title>Δoxa Binarization Framework - WebAssembly Demo</title>\n\t</head>\n\t<body>\n\t\t<canvas id=\"democanvas\">\n\t\t\tSorry. Your browser does not support HTML5 canvas element.\n\t\t</canvas>\n\n        <script type=\"text/javascript\" src=\"../../Bindings/WebAssembly/dist/doxaWasm.js\"></script>\n        <script type=\"text/javascript\" src=\"../../Bindings/WebAssembly/dist/doxa.js\"></script>\n        <script>\n\n            async function loadCanvas(canvas, src) {\n\n                return new Promise((resolve, reject) => {\n\n                    // Load image into canvas using onload callback\n                    const img = new Image();\n                    img.onerror = function() {\n                        reject();\n                    };\n                    img.onload = function() {\n                        const ctx = canvas.getContext('2d');\n\n                        canvas.width = img.width;\n                        canvas.height = img.height;\n                        ctx.drawImage(img, 0, 0);\n\n                        resolve();\n                    };\n\n                    img.src = src;\n                });\n            }\n\n            function readCanvas(doxa, canvas, algorithm) {\n\n                const ctx = canvas.getContext('2d');\n                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n                return doxa.fromImageData(imageData, algorithm);\n            }\n\n            async function demo() {\n\n                // Load an image into the Canvas\n                const canvas = document.getElementById('democanvas');\n                await loadCanvas(canvas, '../../README/2JohnC1V3.png');\n\n                // Initialize the Doxa framework\n                const doxa = await Doxa.initialize();\n\n                // Generate an Image object from the Canvas\n                const grayImage = readCanvas(doxa, canvas, doxa.grayscale.MEAN);\n\n                // Generate a binary image\n                const binImage = doxa.toBinary(doxa.binarization.SAUVOLA, grayImage, { window: 27, k: 0.10 });\n\n                // Draw image back to the same Canvas\n                binImage.draw(canvas);\n\n                // Remember to free the memory of your WASM based images\n                grayImage.free();\n                binImage.free();\n            }\n\n            demo();\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "Doxa/AdOtsu.hpp",
    "content": "﻿// Δoxa Binarization Framework\n// License: CC0 2025, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef ADOTSU_HPP\n#define ADOTSU_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"Otsu.hpp\"\n#include \"MultiScale.hpp\"\n#include \"GridCalc.hpp\"\n#include <cmath>\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The AdOtsu Algorithm, v2010: Reza Farrahi Moghaddam, Mohamed Cheriet\n\t/// \n\t/// This is the core, non-multi-scale, AdOtsu algorithm referenced in (5) of their paper.\n\t/// It should be noted that the paper uses a special color to grayscale algorithm in order to create a\n\t/// \"non-sensitive gray-value image.\"  This would be \"GrayscaleAlgorithms::MINAVG\".\n\t/// \n\t/// The second iteration of this algorithm was introduced a year later in their work:\n\t/// \"AdOtsu: An adaptive and parameterless generalization of Otsu’s method for document image binarization\"\n\t/// \n\t/// This later work builds on top of their earlier work.  Our implementation features their earlier work\n\t/// which will act as a base for future improvements.\n\t/// </summary>\n\t/// <remarks>\"A multi-scale framework for adaptive binarization of degraded document images\", 2010.</remarks>\n\tclass AdOtsu : public Algorithm<AdOtsu>\n\t{\n\tpublic:\n\t\tstatic const int HISTOGRAM_SIZE = 256;\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 1.0);\n\t\t\tconst double R = parameters.Get(\"R\", 0.1);\n\t\t\tconst int distance = parameters.Get(\"distance\", (int)(windowSize / 2));\n\n\t\t\tOtsu otsu;\n\t\t\tconst Pixel8 globalThreshold = otsu.Threshold(Algorithm::grayScaleImageIn);\n\n\t\t\t// Bypass the \"Grid\" optimization.  There is nothing to interpolate.\n\t\t\tif (distance < 2)\n\t\t\t{\n\t\t\t\tLocalWindow::Process(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const Region& window, const int&) {\n\n\t\t\t\t\tconst double localThreshold = k * LocalThreshold(otsu, Algorithm::grayScaleImageIn, window);\n\n\t\t\t\t\tconst double u = (std::abs((double)globalThreshold - localThreshold) / R);\n\n\t\t\t\t\t// Apply the Unit Step Function\n\t\t\t\t\treturn (u < 255) ? localThreshold : -1;\n\t\t\t\t});\n\t\t\t}\n\t\t\telse // Use the \"Grid\" optimization\n\t\t\t{\n\t\t\t\tGridCalc gridCalc;\n\n\t\t\t\t// Calculate all thresholds through interpolation\n\t\t\t\tgridCalc.Process(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, distance, [&](const Region& window, const int&) {\n\n\t\t\t\t\tconst Pixel8 localThreshold = 0.5 + k * LocalThreshold(otsu, Algorithm::grayScaleImageIn, window);\n\n\t\t\t\t\treturn localThreshold;\n\t\t\t\t});\n\n\t\t\t\t// Turn the image into a binary image using the Unit Step Function\n\t\t\t\tfor (int idx = 0; idx < binaryImageOut.size; ++idx)\n\t\t\t\t{\n\t\t\t\t\tconst Pixel8 localThreshold = binaryImageOut.data[idx];\n\t\t\t\t\tconst Pixel8 localPixel = Algorithm::grayScaleImageIn.data[idx];\n\n\t\t\t\t\tconst double u = (std::abs((double)globalThreshold - localThreshold) / R);\n\n\t\t\t\t\t// Apply the Unit Step Function\n\t\t\t\t\tconst int unitStep = (u < 255) ? localThreshold : -1;\n\n\t\t\t\t\t// Binarize the pixel\n\t\t\t\t\tbinaryImageOut.data[idx] = localPixel <= unitStep ?\n\t\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t\t}\n\t\t\t} // Use grid interpolation?\n\t\t}\n\n\t\tPixel8 LocalThreshold(const Otsu& otsu, const Image& grayScaleImage, const Region& window)\n\t\t{\n\t\t\t// Create Local Histogram\n\t\t\tunsigned int histogram[HISTOGRAM_SIZE]; // Placed on stack for performance.  This shouldn't be too large.\n\t\t\tmemset(histogram, 0, (HISTOGRAM_SIZE) * sizeof(unsigned int));\n\n\t\t\t// Initialize Histogram from Local Window\n\t\t\tLocalWindow::Iterate(grayScaleImage.width, window, [&](const int& windowPosition)\n\t\t\t{\n\t\t\t\t++histogram[grayScaleImage.data[windowPosition]];\n\t\t\t});\n\n\t\t\treturn otsu.Algorithm(histogram, window.Area());\n\t\t}\n\t};\n\n\t/// <summary>\n\t/// A multi-scale local adaptive Otsu varient\n\t/// </summary>\n\ttypedef MultiScale<AdOtsu> AdOtsuMS;\n}\n\n\n#endif //ADOTSU_HPP\n"
  },
  {
    "path": "Doxa/Algorithm.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef ALGORITHMS_HPP\n#define ALGORITHMS_HPP\n\n#include \"Image.hpp\"\n#include \"Parameters.hpp\"\n#include \"Palette.hpp\"\n#include \"SIMDOps.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// Algorithm Interface - Useful if you want to dynamically instantiate an algorithm.\n\t/// </summary>\n\tclass IAlgorithm\n\t{\n\tpublic:\n\t\tvirtual ~IAlgorithm() { /* Virtual DTOR */ };\n\n\t\t/// <summary>\n\t\t/// Sets the Gray Scale image that will later be used to generate a binary image.\n\t\t/// This allows the derived class to also initialize the image with any one time calculations.\n\t\t/// </summary>\n\t\t/// <param name=\"grayScaleImageIn\">An Image object containing gray scale content</param>\n\t\tvirtual void Initialize(const Image& grayScaleImageIn) = 0;\n\n\t\t/// <summary>\n\t\t/// Takes the initialized Gray Scale image and returns back a Binary image by reference.\n\t\t/// The Binary image memory should already be allocated before being passed by reference.\n\t\t/// This method was designed to be called repeatedly with different parameters.\n\t\t/// </summary>\n\t\t/// <param name=\"binaryImageOut\">An Image object with preallocated memory which will store the output</param>\n\t\t/// <param name=\"parameters\">Any parameters the algorithm may need</param>\n\t\tvirtual void ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters()) = 0;\n\t};\n\n\n\t/// <summary>\n\t/// This is a base class for all of our binarization algorithms.\n\t/// It uses the Curiously Recurring Template Pattern for compile time inheritance.\n\t/// </summary>\n\ttemplate<typename BinaryAlgorithm>\n\tclass Algorithm : public IAlgorithm\n\t{\n\tpublic:\n\t\t/// <summary>\n\t\t/// Sets the Gray Scale image that will later be used to generate a binary image.\n\t\t/// This allows the derived class to also initialize the image with any one time calculations.\n\t\t/// </summary>\n\t\t/// <param name=\"grayScaleImageIn\">An Image object containing gray scale content</param>\n\t\tvirtual void Initialize(const Image& grayScaleImageIn)\n\t\t{\n\t\t\tthis->grayScaleImageIn = grayScaleImageIn.Reference();\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A convenience method for taking in a Gray Scale image /w params and returning a Binary image.\n\t\t/// </summary>\n\t\tstatic Image ToBinaryImage(const Image& grayScaleImageIn, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Generate space for the binary image\n\t\t\tImage binaryImageOut(grayScaleImageIn.width, grayScaleImageIn.height);\n\n\t\t\t// Run Binarization Algorithm\n\t\t\tBinaryAlgorithm algorithm;\n\t\t\talgorithm.Initialize(grayScaleImageIn);\n\t\t\talgorithm.ToBinary(binaryImageOut, parameters);\n\n\t\t\t// The Move semantics allow this our underlying image to move without being copied\n\t\t\treturn binaryImageOut;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// A convenience method for safely converting a Gray Scale image to Binary.\n\t\t/// Note: You may need to create a temp image and copy it, depending on your algorithm.\n\t\t/// </summary>\n\t\tstatic void UpdateToBinary(Image& image, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tBinaryAlgorithm algorithm;\n\t\t\talgorithm.Initialize(image);\n\t\t\talgorithm.ToBinary(image, parameters);\n\t\t}\n\n\tprotected:\n\t\tImage grayScaleImageIn;\n\t};\n\n\n\t/// <summary>\n\t/// The base class for all Global Thresholding algorithms.\n\t/// </summary>\n\ttemplate<typename BinaryAlgorithm>\n\tclass GlobalThreshold : public Algorithm<BinaryAlgorithm>\n\t{\n\tpublic:\n\t\t/// <summary>\n\t\t/// Calculates and returns the global threshold of the image.\n\t\t/// </summary>\n\t\t/// <returns>A global binarization threshold value</returns>\n\t\tvirtual Pixel8 Threshold(const Image& grayScaleImage, const Parameters& parameters = Parameters()) = 0;\n\n\t\t/// <summary>\n\t\t/// Global binarization based on a single threshold\n\t\t/// </summary>\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tconst Pixel8 threshold = Threshold(Algorithm<BinaryAlgorithm>::grayScaleImageIn, parameters);\n\t\t\tconst int size = Algorithm<BinaryAlgorithm>::grayScaleImageIn.size;\n\t\t\tconst Pixel8* input = Algorithm<BinaryAlgorithm>::grayScaleImageIn.data;\n\t\t\tPixel8* output = binaryImageOut.data;\n\n\t\t\t#if defined(DOXA_SIMD)\n\t\t\t\tToBinary_SIMD(input, output, size, threshold);\n\t\t\t#else\n\t\t\t\tToBinary_STD(input, output, size, threshold);\n\t\t\t#endif\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Scalar implementation of threshold binarization - always available\n\t\t/// </summary>\n\t\tstatic void ToBinary_STD(const Pixel8* input, Pixel8* output, int size, Pixel8 threshold)\n\t\t{\n\t\t\tfor (int idx = 0; idx < size; ++idx) {\n\t\t\t\toutput[idx] = input[idx] <= threshold ? Palette::Black : Palette::White;\n\t\t\t}\n\t\t}\n\n#if defined(DOXA_SIMD)\n\t\t/// <summary>\n\t\t/// SIMD implementation of threshold binarization - only available when SIMD is enabled\n\t\t/// </summary>\n\t\tstatic void ToBinary_SIMD(const Pixel8* input, Pixel8* output, int size, Pixel8 threshold)\n\t\t{\n\t\t\tusing namespace SIMD;\n\n\t\t\tint idx = 0;\n\t\t\tconst int simd_end = size - (size % SIMD_WIDTH);\n\t\t\tvec128 threshold_vec = VEC_SPLAT_U8(threshold);\n\n\t\t\tfor (; idx < simd_end; idx += SIMD_WIDTH) {\n\t\t\t\tvec128 pixels = VEC_LOAD(input + idx);\n\n\t\t\t\t// Compare: mask = (pixels <= threshold) -> 0xFF if true, 0x00 if false\n\t\t\t\t// Use min to implement <= comparison for unsigned bytes\n\t\t\t\tvec128 mask = VEC_CMPEQ_U8(VEC_MIN_U8(pixels, threshold_vec), pixels);\n\n\t\t\t\t// Since Black=0x00 and White=0xFF, result is simply NOT(mask)\n\t\t\t\t// mask=0xFF -> ~0xFF = 0x00 (black), mask=0x00 -> ~0x00 = 0xFF (white)\n\t\t\t\tVEC_STORE(output + idx, VEC_NOT(mask));\n\t\t\t}\n\n\t\t\t// Handle remaining pixels with scalar\n\t\t\tfor (; idx < size; ++idx) {\n\t\t\t\toutput[idx] = input[idx] <= threshold ? Palette::Black : Palette::White;\n\t\t\t}\n\t\t}\n#endif // DOXA_SIMD\n\t};\n}\n\n\n#endif //ALGORITHMS_HPP\n"
  },
  {
    "path": "Doxa/Bataineh.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef BATAINEH_HPP\n#define BATAINEH_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"IntegralImageMeanVarianceCalc.hpp\"\n\n//////////////////////////////////////////////////////////////////////////////\n// This algorithm is being deemed unreproducible as of 09/10/2019.          //\n// See: BatainehTests for a deep analysis of this implementation.           //\n//////////////////////////////////////////////////////////////////////////////\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Bataineh Algorithm: Bilal Bataineh, Siti Norul Huda Sheikh Abdullah, Khairuddin Omar\n\t/// \n\t/// This implementation was painstakingly put together and does not match up perfectly with the results of the paper.\n\t/// While the results are usable, I have been unable to work with the authors to overcome many challenges presented\n\t/// in the paper.  Due to the number of issues, this work is being deemed unreproducible.\n\t/// \n\t/// This algorithm should not be cited by any reputable research paper until these items have been addressed:\n\t///\t\t1. An obvious divide by zero problem in the SAdaptive equation\n\t///\t\t2. Partial code snippet from the author shows part of the Window Threshold equation being mult. by 2\n\t///\t\t3. No independent example of this algorithm actually working\n\t/// \n\t/// Bilal Bataineh did provided me with a code snippet that was of some assistance.\n\t/// It should be noted that his implementation uses a Luma BT601 conversion: GrayscaleAlgorithms::BT601\n\t/// \n\t/// </summary>\n\t/// <remarks>\"An adaptive local binarization method for document images based on a novel thresholding method and dynamic windows\", 2011.</remarks>\n\tclass Bataineh : public Algorithm<Bataineh>, public IntegralImageMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid Initialize(const Image& grayScaleImageIn)\n\t\t{\n\t\t\tAlgorithm::Initialize(grayScaleImageIn);\n\n\t\t\t// Initialize Integral Images\n\t\t\tBataineh::imageWidth = grayScaleImageIn.width;\n\t\t\tBataineh::integralImage.resize(grayScaleImageIn.size);\n\t\t\tBataineh::integralSqrImage.resize(grayScaleImageIn.size);\n\t\t\tBuildIntegralImages(Bataineh::integralImage, Bataineh::integralSqrImage, Algorithm::grayScaleImageIn);\n\t\t}\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Get global std-dev and mean values\n\t\t\tdouble sigmaGlobal;\n\t\t\tdouble meanGlobal;\n\t\t\tCalculateGlobals(meanGlobal, sigmaGlobal);\n\n\t\t\t// Get Max Gray Value\n\t\t\tconst Pixel8 maxGrayValue = GetMaxGrayValue();\n\n\t\t\t// Calculate Confusion Threshold\n\t\t\tconst double confThreshold = ConfusionThreshold(meanGlobal, sigmaGlobal, maxGrayValue);\n\n\t\t\t// Find total Red and Black pixels and temp. store them in our output.  Red pixels are the confused pixels.\n\t\t\tint redCountImage;\n\t\t\tint blackCountImage;\n\t\t\tRedBlack(redCountImage, blackCountImage, binaryImageOut, confThreshold, sigmaGlobal);\n\n\t\t\t// Break the image into Primary and Secondary windows\n\t\t\t// Our output image is temporarily storing our Black/White/Red image\n\t\t\tstd::vector<DetailedWindow> windows = GetWindows(binaryImageOut, blackCountImage, redCountImage, sigmaGlobal, maxGrayValue);\n\n\t\t\t// Get Sigma Max and Min as well as local window Sigma and Mean\n\t\t\tdouble sigmaMax;\n\t\t\tdouble sigmaMin;\n\t\t\tSigmaMinMaxAndMean(sigmaMin, sigmaMax, windows);\n\n\t\t\t// Apply threshold\n\t\t\tfor (auto &detailedWindow : windows)\n\t\t\t{\n\t\t\t\t// Calculate threshold for the Window\n\t\t\t\tconst double sigmaAdaptive = SigmaAdaptive(detailedWindow.stddev, sigmaMin, sigmaMax, maxGrayValue);\n\t\t\t\tconst double threshold = WindowThreshold(detailedWindow.mean, meanGlobal, detailedWindow.stddev, sigmaAdaptive);\n\n\t\t\t\t// Convert to binary\n\t\t\t\tLocalWindow::Iterate(Algorithm::grayScaleImageIn.width, detailedWindow.window, [&](const int& positionWindow) {\n\t\t\t\t\tbinaryImageOut.data[positionWindow] =\n\t\t\t\t\t\tAlgorithm::grayScaleImageIn.data[positionWindow] <= threshold ? Palette::Black : Palette::White;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\tprotected:\n\t\tenum PixelColor\n\t\t{\n\t\t\tBLACK = Palette::Black,\n\t\t\tRED = 128,\n\t\t\tWHITE = Palette::White\n\t\t};\n\n\t\tstruct DetailedWindow\n\t\t{\n\t\t\tRegion window;\n\t\t\tdouble mean;\n\t\t\tdouble stddev;\n\t\t};\n\n\t\tvoid CalculateGlobals(double& mean, double& stddev) const\n\t\t{\n\t\t\tconst Region window(Algorithm::grayScaleImageIn.width, Algorithm::grayScaleImageIn.height);\n\n\t\t\tCalculateMeanStdDev(mean, stddev, window);\n\t\t}\n\n\t\tinline void CalculateMeanStdDev(double& mean, double& stddev, const Region& window) const\n\t\t{\n\t\t\tdouble variance;\n\t\t\tCalculateMeanVariance(mean, variance, Bataineh::imageWidth, Bataineh::integralImage, Bataineh::integralSqrImage, window);\n\n\t\t\tstddev = std::sqrt(variance);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calculates the size of the Primary Window.  These windows are fixed to the image and do not surround the pixel.\n\t\t/// Note: While this algorithm does not have a fixed Windows Size nor K value, it does have these magic numbers.\n\t\t/// I believe these numbers assume an image of a certain size, with a certain resolution or character size.\n\t\t/// </summary>\n\t\tvoid inline constexpr PrimaryWindow(int& primaryWidth, int& primaryHeight, double p, double sigmaGlobal, Pixel8 maxGray, int imageWidth, int imageHeight)\n\t\t{\n\n\t\t\tif (p >= 2.5 || (sigmaGlobal < 0.1*maxGray))\n\t\t\t{\n\t\t\t\tprimaryWidth = imageWidth / 6;\n\t\t\t\tprimaryHeight = imageHeight / 4;\n\t\t\t}\n\t\t\telse if (p > 1 || (imageWidth + imageHeight < 400))\n\t\t\t{\n\t\t\t\tprimaryWidth = imageWidth / 30;\n\t\t\t\tprimaryHeight = imageHeight / 20;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprimaryWidth = imageWidth / 40;\n\t\t\t\tprimaryHeight = imageHeight / 30;\n\t\t\t}\n\t\t}\n\n\t\tdouble inline constexpr SigmaAdaptive(const double sigmaWindow, const double sigmaMin, const double sigmaMax, const Pixel8 maxGray)\n\t\t{\n\t\t\t// Note: In the original paper, this had a divide by 0 problem (SigmaMax - SigmaMax).  Bilal helped clear this confusion.\n\t\t\treturn ((sigmaWindow - sigmaMin) / (sigmaMax - sigmaMin)) * maxGray;\n\t\t}\n\n\t\tdouble inline constexpr WindowThreshold(const double meanWindow, const double meanGlobal, const double sigmaWindow, const double sigmaAdaptive)\n\t\t{\n\t\t\t// Note: In the original paper, the Mw^2 * Sw was Mw^2 - Sw.  The authors later corrected it.\n\t\t\t// Note: The author gave me some partial code that contained this function.  SigmaAdaptive was multiplied by 2!\n\t\t\t// This threshold value can go negative at times, and even return NAN!  In both cases the block will be white.\n\t\t\treturn meanWindow - ((meanWindow*meanWindow * sigmaWindow) / ((meanGlobal + sigmaWindow)*(2*sigmaAdaptive + sigmaWindow)));\n\t\t}\n\n\t\tdouble inline constexpr ConfusionThreshold(const double meanGlobal, const double sigmaGlobal, const Pixel8 maxGray)\n\t\t{\n\t\t\t// Note: In the original paper, the Mg^2 * Sg was Mg^2 - Sg.  The authors later corrected it.\n\t\t\treturn meanGlobal - ((meanGlobal*meanGlobal * sigmaGlobal) / ((meanGlobal + sigmaGlobal)*(0.5*maxGray + sigmaGlobal)));\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the largest gray value in the image.\n\t\t/// </summary>\n\t\tPixel8 GetMaxGrayValue() const\n\t\t{\n\t\t\tPixel8 maxGrayValue = 0;\n\t\t\tfor (int position = 0; position < Algorithm::grayScaleImageIn.size; ++position)\n\t\t\t{\n\t\t\t\tconst Pixel8 tmpMax = Algorithm::grayScaleImageIn.data[position];\n\t\t\t\tif (tmpMax > maxGrayValue) maxGrayValue = tmpMax;\n\t\t\t}\n\n\t\t\treturn maxGrayValue;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Gets the local std dev and mean, as well as calculates the global sigma min and max\n\t\t/// </summary>\n\t\tvoid SigmaMinMaxAndMean(double& sigmaMin, double& sigmaMax, std::vector<DetailedWindow>& windows) const\n\t\t{\n\t\t\tsigmaMax = 0;\n\t\t\tsigmaMin = std::numeric_limits<double>::max();\n\n\t\t\tfor (auto &detailedWindow : windows)\n\t\t\t{\n\t\t\t\tCalculateMeanStdDev(detailedWindow.mean, detailedWindow.stddev, detailedWindow.window);\n\n\t\t\t\tif (detailedWindow.stddev > sigmaMax) sigmaMax = detailedWindow.stddev;\n\t\t\t\tif (detailedWindow.stddev < sigmaMin) sigmaMin = detailedWindow.stddev;\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Returns the total Red and Black count for the image and builds a Red Black White image.\n\t\t/// </summary>\n\t\tvoid RedBlack(int& redCountImage, int& blackCountImage, Image& redBlackImage, const double confusionThreshold, const double sigmaGlobal) const\n\t\t{\n\t\t\tconst double halfSigmaGlobal = sigmaGlobal / 2;\n\n\t\t\tredCountImage = 0;\n\t\t\tblackCountImage = 0;\n\n\t\t\tfor (int position = 0; position < Algorithm::grayScaleImageIn.size; ++position)\n\t\t\t{\n\t\t\t\tconst Pixel8 val = Algorithm::grayScaleImageIn.data[position];\n\n\t\t\t\tif (val <= confusionThreshold - halfSigmaGlobal)\n\t\t\t\t{\n\t\t\t\t\t++blackCountImage;\n\t\t\t\t\tredBlackImage.data[position] = PixelColor::BLACK;\n\t\t\t\t}\n\t\t\t\telse if (val >= confusionThreshold + halfSigmaGlobal)\n\t\t\t\t{\n\t\t\t\t\tredBlackImage.data[position] = PixelColor::WHITE;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t++redCountImage;\n\t\t\t\t\tredBlackImage.data[position] = PixelColor::RED;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Breaks the image into Primary and Secondary windows.\n\t\t/// This is different from most other algorithms where the window is based around the pixel.\n\t\t/// </summary>\n\t\t/// <returns>Primary and Secondary Windows.  NRVO should not make a copy of the vector.</returns>\n\t\tstd::vector<DetailedWindow> GetWindows(\n\t\t\tconst Image& image, \n\t\t\tconst int blackCountImage, \n\t\t\tconst int redCountImage,\n\t\t\tconst double sigmaGlobal, \n\t\t\tconst Pixel8 maxGrayValue)\n\t\t{\n\t\t\t// Calculate the Primary Window size\n\t\t\tint windowWidth;\n\t\t\tint windowHeight;\n\t\t\tPrimaryWindow(windowWidth, windowHeight,\n\t\t\t\t(double)blackCountImage / redCountImage,\n\t\t\t\tsigmaGlobal,\n\t\t\t\tmaxGrayValue,\n\t\t\t\timage.width,\n\t\t\t\timage.height\n\t\t\t);\n\n\t\t\t// Build list of Primary Windows\n\t\t\tstd::vector<DetailedWindow> windows = GetPrimaryWindows(image, windowWidth, windowHeight);\n\n\t\t\t// Break some Primary Windows into smaller Secondary Windows\n\t\t\tUpdateWindowsWithSecondarySize(windows, image);\n\n\t\t\treturn windows;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Break the image into a set of fixed windows.\n\t\t/// We take some liberty on the edges, so that we are not left with a window that is too small.\n\t\t/// </summary>\n\t\tstd::vector<DetailedWindow> GetPrimaryWindows(const Image& image, const int windowWidth, const int windowHeight) const\n\t\t{\n\t\t\tstd::vector<DetailedWindow> windows;\n\t\t\tint offsetY = 0;\n\t\t\tint offsetX = 0;\n\t\t\t\n\t\t\tfor (int y = 0; y < image.height; y = offsetY + 1)\n\t\t\t{\n\t\t\t\t// Do not overshoot Y\n\t\t\t\toffsetY = std::min(image.height - 1, y + (windowHeight - 1));\n\n\t\t\t\t// Do not undershoot Y\n\t\t\t\tif ((image.height - 1) - offsetY < windowHeight / 2)\n\t\t\t\t\toffsetY = image.height - 1;\n\n\t\t\t\tfor (int x = 0; x < image.width; x = offsetX + 1)\n\t\t\t\t{\n\t\t\t\t\t// Do not overshoot X\n\t\t\t\t\toffsetX = std::min(image.width - 1, x + (windowWidth - 1));\n\n\t\t\t\t\t// Do not undershoot X\n\t\t\t\t\tif ((image.width - 1) - offsetX < windowWidth / 2)\n\t\t\t\t\t\toffsetX = image.width - 1;\n\n\t\t\t\t\twindows.push_back(DetailedWindow{ Region(x, y, offsetX, offsetY) });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn windows;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Breaks up certain Primary Windows into smaller window sizes\n\t\t/// </summary>\n\t\tvoid UpdateWindowsWithSecondarySize(std::vector<DetailedWindow>& windows, const Image& image) const\n\t\t{\n\t\t\t// Iterate each primary window.  If it needs to be broken up, remove it and add the secondary windows.\n\t\t\tstd::vector<DetailedWindow> secondaryWindows;\n\t\t\twindows.erase(std::remove_if(windows.begin(), windows.end(), [&](const DetailedWindow& detailedWindow) {\n\t\t\t\tint redCountWindow = 0;\n\t\t\t\tint blackCountWindow = 0;\n\n\t\t\t\t// Count Red and Black pixels in the Window\n\t\t\t\tLocalWindow::Iterate(image.width, detailedWindow.window, [&](const int& positionWindow) {\n\t\t\t\t\tconst Pixel8 val = image.data[positionWindow];\n\n\t\t\t\t\tif (val == PixelColor::BLACK) ++blackCountWindow;\n\t\t\t\t\telse if (val == PixelColor::RED) ++redCountWindow;\n\t\t\t\t});\n\n\t\t\t\t// If there are more Red pixels, create a second window by quartering the primary window\n\t\t\t\tif (redCountWindow > blackCountWindow)\n\t\t\t\t{\n\t\t\t\t\tconst int halfX = detailedWindow.window.Width() / 2;\n\t\t\t\t\tconst int halfY = detailedWindow.window.Height() / 2;\n\n\t\t\t\t\tconst Region& win = detailedWindow.window;\n\t\t\t\t\tsecondaryWindows.push_back(DetailedWindow{ Region(win.upperLeft.x, win.upperLeft.y, win.upperLeft.x + halfX - 1, win.upperLeft.y + halfY - 1) });\n\t\t\t\t\tsecondaryWindows.push_back(DetailedWindow{ Region(win.upperLeft.x + halfX, win.upperLeft.y, win.bottomRight.x, win.upperLeft.y + halfY - 1) });\n\t\t\t\t\tsecondaryWindows.push_back(DetailedWindow{ Region(win.upperLeft.x, win.upperLeft.y + halfY, win.upperLeft.x + halfX - 1, win.bottomRight.y) });\n\t\t\t\t\tsecondaryWindows.push_back(DetailedWindow{ Region(win.upperLeft.x + halfX, win.upperLeft.y + halfY, win.bottomRight.x, win.bottomRight.y) });\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t}), windows.end());\n\n\t\t\t// Merge Secondary Windows into our main Window vector\n\t\t\twindows.insert(std::end(windows), std::begin(secondaryWindows), std::end(secondaryWindows));\n\t\t}\n\n\n\t\tint imageWidth = 0;\n\t\tIntegralImage integralImage, integralSqrImage;\n\t};\n}\n\n\n#endif //BATAINEH_HPP\n"
  },
  {
    "path": "Doxa/Bernsen.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef BERNSEN_HPP\n#define BERNSEN_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"Morphology.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Bernsen Algorithm: John Bernsen\n\t/// </summary>\n\t/// <remarks>\"Dynamic thresholding of gray-level images\", 1986.</remarks>\n\tclass Bernsen : public Algorithm<Bernsen>\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tPixel8 min, max;\n\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst int GT = parameters.Get(\"threshold\", 100);\n\t\t\tconst int L = parameters.Get(\"contrast-limit\", 25);\n\n\t\t\t// Build Min and Max images\n\t\t\tImage minImage(Algorithm::grayScaleImageIn.width, Algorithm::grayScaleImageIn.height);\n\t\t\tImage maxImage(Algorithm::grayScaleImageIn.width, Algorithm::grayScaleImageIn.height);\n\t\t\tMorphology::Erode(minImage, Algorithm::grayScaleImageIn, windowSize);\n\t\t\tMorphology::Dilate(maxImage, Algorithm::grayScaleImageIn, windowSize);\n\n\t\t\tLocalWindow::Process(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const Region& window, const int& position) {\n\t\t\t\tmin = minImage.data[position];\n\t\t\t\tmax = maxImage.data[position];\n\n\t\t\t\treturn (max - min) > L ? (max + min) / 2 : GT;\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //BERNSEN_HPP\n"
  },
  {
    "path": "Doxa/BinarizationFactory.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2025, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef BINARIZATIONFACTORY_HPP\n#define BINARIZATIONFACTORY_HPP\n\n// Note: Only include this header if you are prepared to pull in 95%+ of the entirety of this library.\n#include \"Otsu.hpp\"\n#include \"Bernsen.hpp\"\n#include \"Niblack.hpp\"\n#include \"Sauvola.hpp\"\n#include \"ISauvola.hpp\"\n#include \"Nick.hpp\"\n#include \"TRSingh.hpp\"\n#include \"Bataineh.hpp\"\n#include \"Wan.hpp\"\n#include \"Wolf.hpp\"\n#include \"Su.hpp\"\n#include \"Gatos.hpp\"\n#include \"AdOtsu.hpp\"\n#include \"Phansalkar.hpp\"\n\n\nnamespace Doxa\n{\n\tenum Algorithms\n\t{\n\t\tOTSU = 0,\n\t\tBERNSEN = 1,\n\t\tNIBLACK = 2,\n\t\tSAUVOLA = 3,\n\t\tWOLF = 4,\n\t\tNICK = 5,\n\t\tSU = 6,\n\t\tTRSINGH = 7,\n\t\tBATAINEH = 8,\n\t\tISAUVOLA = 9,\n\t\tWAN = 10,\n\t\tGATOS = 11,\n\t\tADOTSU = 12,\n\t\tPHANSALKAR = 13,\n\t};\n\n\n\t/// <summary>\n\t/// A factory class for creating instances of binarization algorithms.\n\t/// </summary>\n\tclass BinarizationFactory\n\t{\n\tpublic:\n\t\tstatic IAlgorithm* Algorithm(const Algorithms algorithm)\n\t\t{\n\t\t\tIAlgorithm* algorithmPtr = nullptr;\n\n\t\t\tswitch (algorithm)\n\t\t\t{\n\t\t\tcase OTSU:\n\t\t\t\talgorithmPtr = new Otsu();\n\t\t\t\tbreak;\n\t\t\tcase BERNSEN:\n\t\t\t\talgorithmPtr = new Bernsen();\n\t\t\t\tbreak;\n\t\t\tcase NIBLACK:\n\t\t\t\talgorithmPtr = new Niblack();\n\t\t\t\tbreak;\n\t\t\tcase SAUVOLA:\n\t\t\t\talgorithmPtr = new Sauvola();\n\t\t\t\tbreak;\n\t\t\tcase NICK:\n\t\t\t\talgorithmPtr = new Nick();\n\t\t\t\tbreak;\n\t\t\tcase WOLF:\n\t\t\t\talgorithmPtr = new Wolf();\n\t\t\t\tbreak;\n\t\t\tcase SU:\n\t\t\t\talgorithmPtr = new Su();\n\t\t\t\tbreak;\n\t\t\tcase TRSINGH:\n\t\t\t\talgorithmPtr = new TRSingh();\n\t\t\t\tbreak;\n\t\t\tcase BATAINEH:\n\t\t\t\talgorithmPtr = new Bataineh();\n\t\t\t\tbreak;\n\t\t\tcase ISAUVOLA:\n\t\t\t\talgorithmPtr = new ISauvola();\n\t\t\t\tbreak;\n\t\t\tcase WAN:\n\t\t\t\talgorithmPtr = new Wan();\n\t\t\t\tbreak;\n\t\t\tcase GATOS:\n\t\t\t\talgorithmPtr = new Gatos();\n\t\t\t\tbreak;\n\t\t\tcase ADOTSU:\n\t\t\t\talgorithmPtr = new AdOtsuMS();\n\t\t\t\tbreak;\n\t\t\tcase PHANSALKAR:\n\t\t\t\talgorithmPtr = new Phansalkar();\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn algorithmPtr;\n\t\t}\n\t};\n}\n\n\n#endif // #BINARIZATIONFACTORY_HPP\n"
  },
  {
    "path": "Doxa/ChanMeanCalc.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2020, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef CHANMEANCALC_HPP\n#define CHANMEANCALC_HPP\n\n#include \"Image.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// A version of the Chan algorithm for calculating just the Mean.\n\t/// </summary>\n\t/// <see cref=\"ChanMeanVarianceCalc\"/>\n\tclass ChanMeanCalc\n\t{\n\tpublic:\n\n\t\ttemplate<typename Algorithm>\n\t\tvoid Process(Image& binaryImageOut, const Image& grayScaleImageIn, const int windowSize, Algorithm algorithm)\n\t\t{\n\t\t\tIterate(grayScaleImageIn, windowSize, [&](const double& mean, const int position) {\n\t\t\t\tbinaryImageOut.data[position] =\n\t\t\t\t\tgrayScaleImageIn.data[position] <= algorithm(mean, position) ?\n\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t});\n\t\t}\n\n\t\ttemplate<typename Processor>\n\t\tvoid Iterate(const Image& grayScaleImageIn, const int windowSize, Processor processor)\n\t\t{\n\t\t\t// Setup constants\n\t\t\tconst int width = grayScaleImageIn.width;\n\t\t\tconst int height = grayScaleImageIn.height;\n\t\t\tconst int leftWindow = (windowSize + 1) / 2;\n\t\t\tconst int rightWindow = windowSize - leftWindow;\n\t\t\tconst int dr1 = rightWindow;\n\t\t\tconst int dr2 = width - rightWindow + 1;\n\n\t\t\t// Initialize structure\n\t\t\tuint16_t* integral = new uint16_t[width + 1];\n\t\t\tmemset(integral, 0, (width + 1) * sizeof(uint16_t));\n\n\t\t\t// Starting at the top of the image, sum the columns to half our window height.\n\t\t\t// Note that Left and Right Window names are synonymous with Top and Bottom since this is a square window.\n\t\t\t// Our structures have now been primed.\n\t\t\tfor (int y = 0, ind = 0; y < rightWindow; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 1; x <= width; x++, ind++)\n\t\t\t\t{\n\t\t\t\t\tintegral[x] += grayScaleImageIn.data[ind];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int y = 0, ind = 0; y < height; ++y)\n\t\t\t{\n\t\t\t\tconst int winTop = std::max(y - leftWindow, -1);\n\t\t\t\tconst int winBottom = std::min(height - 1, y + rightWindow);\n\n\t\t\t\t// As our windows slides down, these two blocks will remove the top row from our structure and add on the bottom row.\n\t\t\t\tif (y >= leftWindow) {\n\t\t\t\t\tfor (int x = 1, index = winTop * width; x <= width; ++x, ++index)\n\t\t\t\t\t{ \n\t\t\t\t\t\tintegral[x] -= grayScaleImageIn.data[index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (y + rightWindow < height)\n\t\t\t\t{\n\t\t\t\t\tfor (int x = 1, index = winBottom * width; x <= width; ++x, ++index)\n\t\t\t\t\t{\n\t\t\t\t\t\tintegral[x] += grayScaleImageIn.data[index];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// At this point we slide our window from left to right.\n\t\t\t\t// We calculate the sums for the first half of our window.\n\t\t\t\tint sum = 0;\n\t\t\t\tfor (int x = 1; x <= dr1; x++)\n\t\t\t\t{\n\t\t\t\t\tsum += integral[x];\n\t\t\t\t}\n\n\t\t\t\t// As our window moves across, we are now able to use our sums to calculate mean, variance, etc.\n\t\t\t\t// This happens until the right most edge of our windows hits the end of the image.\n\t\t\t\tfor (int x = 1; x < dr2; ++x, ++ind)\n\t\t\t\t{\n\t\t\t\t\tconst int winLeft = std::max(x - leftWindow, 0);\n\t\t\t\t\tconst int winRight = x + rightWindow;\n\t\t\t\t\tconst int area = (winBottom - winTop)*(winRight - winLeft);\n\t\t\t\t\tsum += integral[winRight] - integral[winLeft];\n\n\t\t\t\t\tconst double mean = ((double)sum) / area;\n\n\t\t\t\t\tprocessor(mean, ind);\n\t\t\t\t}\n\n\t\t\t\t// Now that our windows is sliding through the right side of the image, we have to remove the left most column.\n\t\t\t\t// As we do that, we are able to continue with our calculation.\n\t\t\t\tfor (int x = dr2; x <= width; ++x, ++ind)\n\t\t\t\t{\n\t\t\t\t\tconst int winLeft = std::max(x - leftWindow, 0);\n\t\t\t\t\tconst int winRight = width;\n\t\t\t\t\tconst int area = (winBottom - winTop)*(winRight - winLeft);\n\t\t\t\t\tsum -= integral[winLeft];\n\n\t\t\t\t\tconst double mean = ((double)sum) / area;\n\n\t\t\t\t\tprocessor(mean, ind);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Free up our dynamically allocated structures\n\t\t\tdelete[] integral;\n\t\t}\n\t};\n}\n\n\n#endif //CHANMEANCALC_HPP\n"
  },
  {
    "path": "Doxa/ChanMeanVarianceCalc.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2020, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef CHANMEANVARIANCECALC_HPP\n#define CHANMEANVARIANCECALC_HPP\n\n#include \"Image.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Chan Algorithm: Chungkwong Chan\n\t/// This algorithm is an advancement over Integral Images for extremely fast Mean / Variance calculation.\n\t/// It also uses only a fraction of the memory while allowing for much larger images.\n\t/// </summary>\n\t/// <remarks>\"Memory-efficient and fast implementation of local adaptive binarization methods\", 2019.</remarks>\n\tclass ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\ttemplate<typename Algorithm>\n\t\tvoid Process(Image& binaryImageOut, const Image& grayScaleImageIn, const int windowSize, Algorithm algorithm)\n\t\t{\n\t\t\tIterate(grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int position) {\n\t\t\t\tbinaryImageOut.data[position] =\n\t\t\t\t\tgrayScaleImageIn.data[position] <= algorithm(mean, variance, position) ?\n\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t});\n\t\t}\n\n\n\t\ttemplate<typename Processor>\n\t\tvoid Iterate(const Image& grayScaleImageIn, const int windowSize, Processor processor)\n\t\t{\n\t\t\t// Setup constants\n\t\t\tconst int width = grayScaleImageIn.width;\n\t\t\tconst int height = grayScaleImageIn.height;\n\t\t\tconst int leftWindow = (windowSize + 1) / 2;\n\t\t\tconst int rightWindow = windowSize - leftWindow;\n\t\t\tconst int dr1 = rightWindow;\n\t\t\tconst int dr2 = width - rightWindow + 1;\n\n\t\t\t// Initialize structures\n\t\t\tuint16_t* integral = new uint16_t[width + 1];\n\t\t\tint32_t* integralSquare = new int32_t[width + 1];\n\t\t\tmemset(integral, 0, (width + 1) * sizeof(uint16_t));\n\t\t\tmemset(integralSquare, 0, (width + 1) * sizeof(int32_t));\n\n\t\t\t// Starting at the top of the image, sum the columns to half our window height.\n\t\t\t// Note that Left and Right Window names are synonymous with Top and Bottom since this is a square window.\n\t\t\t// Our structures have now been primed.\n\t\t\tfor (int y = 0, ind = 0; y < rightWindow; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 1; x <= width; x++, ind++)\n\t\t\t\t{\n\t\t\t\t\tconst int pixel = grayScaleImageIn.data[ind];\n\t\t\t\t\tintegral[x] += pixel;\n\t\t\t\t\tintegralSquare[x] += pixel * pixel;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int y = 0, ind = 0; y < height; ++y)\n\t\t\t{\n\t\t\t\tconst int winTop = std::max(y - leftWindow, -1);\n\t\t\t\tconst int winBottom = std::min(height - 1, y + rightWindow);\n\n\t\t\t\t// As our windows slides down, these two blocks will remove the top row from our structure and add on the bottom row.\n\t\t\t\tif (y >= leftWindow) {\n\t\t\t\t\tfor (int x = 1, index = winTop * width; x <= width; ++x, ++index)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst int pixel = grayScaleImageIn.data[index];\n\t\t\t\t\t\tintegral[x] -= pixel;\n\t\t\t\t\t\tintegralSquare[x] -= pixel * pixel;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (y + rightWindow < height)\n\t\t\t\t{\n\t\t\t\t\tfor (int x = 1, index = winBottom * width; x <= width; ++x, ++index)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst int pixel = grayScaleImageIn.data[index];\n\t\t\t\t\t\tintegral[x] += pixel;\n\t\t\t\t\t\tintegralSquare[x] += pixel * pixel;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// At this point we slide our window from left to right.\n\t\t\t\t// We calculate the sums for the first half of our window.\n\t\t\t\tint sum = 0;\n\t\t\t\tint squareSum = 0;\n\t\t\t\tfor (int x = 1; x <= dr1; x++)\n\t\t\t\t{\n\t\t\t\t\tsum += integral[x];\n\t\t\t\t\tsquareSum += integralSquare[x];\n\t\t\t\t}\n\n\t\t\t\t// As our window moves across, we are now able to use our sums to calculate mean, variance, etc.\n\t\t\t\t// This happens until the right most edge of our windows hits the end of the image.\n\t\t\t\tfor (int x = 1; x < dr2; ++x, ++ind)\n\t\t\t\t{\n\t\t\t\t\tconst int winLeft = std::max(x - leftWindow, 0);\n\t\t\t\t\tconst int winRight = x + rightWindow;\n\t\t\t\t\tconst int count = (winBottom - winTop)*(winRight - winLeft);\n\t\t\t\t\tsum += integral[winRight] - integral[winLeft];\n\t\t\t\t\tsquareSum += integralSquare[winRight] - integralSquare[winLeft];\n\n\t\t\t\t\tconst double mean = ((double)sum) / count;\n\t\t\t\t\tconst double variance = ((double)squareSum) / count - mean * mean;\n\n\t\t\t\t\tprocessor(mean, variance, ind);\n\t\t\t\t}\n\n\t\t\t\t// Now that our windows is sliding through the right side of the image, we have to remove the left most column.\n\t\t\t\t// As we do that, we are able to continue with our calculation.\n\t\t\t\tfor (int x = dr2; x <= width; ++x, ++ind)\n\t\t\t\t{\n\t\t\t\t\tconst int winLeft = std::max(x - leftWindow, 0);\n\t\t\t\t\tconst int winRight = width;\n\t\t\t\t\tconst int count = (winBottom - winTop)*(winRight - winLeft);\n\t\t\t\t\tsum -= integral[winLeft];\n\t\t\t\t\tsquareSum -= integralSquare[winLeft];\n\n\t\t\t\t\tconst double mean = ((double)sum) / count;\n\t\t\t\t\tconst double variance = ((double)squareSum) / count - mean * mean;\n\n\t\t\t\t\tprocessor(mean, variance, ind);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Free up our dynamically allocated structures\n\t\t\tdelete[] integral;\n\t\t\tdelete[] integralSquare;\n\t\t}\n\t};\n}\n\n\n#endif //CHANMEANVARIANCECALC_HPP\n"
  },
  {
    "path": "Doxa/ClassifiedPerformance.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef CLASSIFIEDPERFORMANCE_HPP\n#define CLASSIFIEDPERFORMANCE_HPP\n\n#include <vector>\n#include \"Image.hpp\"\n#include \"Palette.hpp\"\n#include \"SIMDOps.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// A performance calculator for the family of classification metrics.\n\t/// Implementations: Accuracy, (pseudo)Recall, (pseudo)Precision, (pseudo)F-Measure, PSNR, MCC and NMR\n\t/// </summary>\n\tclass ClassifiedPerformance\n\t{\n\tpublic:\n\t\tstruct Classifications\n\t\t{\n\t\t\tint truePositive = 0;\t// A correctly chosen black pixel\n\t\t\tint trueNegative = 0;\t// A correctly chosen white pixel\n\t\t\tint falsePositive = 0;\t// An incorrectly chosen black pixel\n\t\t\tint falseNegative = 0;\t// An incorrectly chosen white pixel\n\n\t\t\tdouble wpTruePositive = 0.0;\t// Weighted Precision\n\t\t\tdouble wpFalsePositive = 0.0;\t// Weighted Precision\n\t\t\tdouble wrTruePositive = 0.0;\t// Weighted Recall\n\t\t\tdouble wrFalseNegative = 0.0;\t// Weighted Recall\n\n\t\t\tint Total() const noexcept\n\t\t\t{\n\t\t\t\treturn truePositive + trueNegative + falsePositive + falseNegative;\n\t\t\t}\n\n\t\t\tvoid Clear() noexcept\n\t\t\t{\n\t\t\t\ttruePositive = trueNegative = falsePositive = falseNegative = 0;\n\t\t\t\twpTruePositive = wpFalsePositive = wrTruePositive = wrFalseNegative = 0.0;\n\t\t\t}\n\t\t};\n\n\t\tstatic bool CompareImages(\n\t\t\tClassifications& classifications, \n\t\t\tconst Image& controlImage, \n\t\t\tconst Image& experimentImage)\n\t\t{\n\t\t\t// Initialize\n\t\t\tclassifications.Clear();\n\n\t\t\t// Verify Input\n\t\t\tif (controlImage.width != experimentImage.width || controlImage.height != experimentImage.height)\n\t\t\t\treturn false;\n\n\t\t\t#if defined(DOXA_SIMD)\n\t\t\t\tCompareImages_SIMD(classifications, controlImage.data, experimentImage.data, controlImage.size);\n\t\t\t#else\n\t\t\t\tCompareImages_STD(classifications, controlImage.data, experimentImage.data, controlImage.size);\n\t\t\t#endif\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Scalar implementation of image comparison - always available\n\t\t/// </summary>\n\t\tstatic void CompareImages_STD(Classifications& classifications, const Pixel8* control, const Pixel8* experiment, int size)\n\t\t{\n\t\t\tfor (int i = 0; i < size; ++i)\n\t\t\t{\n\t\t\t\tif (control[i] == experiment[i])\n\t\t\t\t\tif (experiment[i] == Palette::Black)\n\t\t\t\t\t\tclassifications.truePositive++;\n\t\t\t\t\telse\n\t\t\t\t\t\tclassifications.trueNegative++;\n\t\t\t\telse // Not a match\n\t\t\t\t\tif (experiment[i] == Palette::Black)\n\t\t\t\t\t\tclassifications.falsePositive++;\n\t\t\t\t\telse\n\t\t\t\t\t\tclassifications.falseNegative++;\n\t\t\t}\n\t\t}\n\n#if defined(DOXA_SIMD)\n\t\t/// <summary>\n\t\t/// SIMD implementation of image comparison - only available when SIMD is enabled\n\t\t/// </summary>\n\t\tstatic void CompareImages_SIMD(Classifications& classifications, const Pixel8* control, const Pixel8* experiment, int size)\n\t\t{\n\t\t\tusing namespace SIMD;\n\n\t\t\tint idx = 0;\n\t\t\tconst int simd_end = size - (size % SIMD_WIDTH);\n\n\t\t\tvec128 black_vec = VEC_SPLAT_U8(Palette::Black);\n\t\t\tvec128 ones_vec = VEC_SPLAT_U8(1);\n\n\t\t\t// Accumulators for SIMD counts\n\t\t\tint tp_sum = 0, tn_sum = 0, fp_sum = 0, fn_sum = 0;\n\n\t\t\tfor (; idx < simd_end; idx += SIMD_WIDTH) {\n\t\t\t\tvec128 ctrl = VEC_LOAD(control + idx);\n\t\t\t\tvec128 exp = VEC_LOAD(experiment + idx);\n\n\t\t\t\t// match_mask: 0xFF where control == experiment, 0x00 otherwise\n\t\t\t\tvec128 match_mask = VEC_CMPEQ_U8(ctrl, exp);\n\t\t\t\t// black_mask: 0xFF where experiment == black, 0x00 otherwise\n\t\t\t\tvec128 black_mask = VEC_CMPEQ_U8(exp, black_vec);\n\n\t\t\t\t// TP: match AND black\n\t\t\t\tvec128 tp_mask = VEC_AND(match_mask, black_mask);\n\t\t\t\t// TN: match AND NOT black\n\t\t\t\tvec128 tn_mask = VEC_ANDNOT(black_mask, match_mask);\n\t\t\t\t// FP: NOT match AND black\n\t\t\t\tvec128 fp_mask = VEC_ANDNOT(match_mask, black_mask);\n\t\t\t\t// FN: NOT match AND NOT black\n\t\t\t\tvec128 not_match = VEC_NOT(match_mask);\n\t\t\t\tvec128 not_black = VEC_NOT(black_mask);\n\t\t\t\tvec128 fn_mask = VEC_AND(not_match, not_black);\n\n\t\t\t\t// Count set bytes (mask has 0xFF for set, we need count of 1s)\n\t\t\t\t// AND with 1s to convert 0xFF to 0x01, then horizontal sum\n\t\t\t\ttp_sum += vec_hsum_u8(VEC_AND(tp_mask, ones_vec));\n\t\t\t\ttn_sum += vec_hsum_u8(VEC_AND(tn_mask, ones_vec));\n\t\t\t\tfp_sum += vec_hsum_u8(VEC_AND(fp_mask, ones_vec));\n\t\t\t\tfn_sum += vec_hsum_u8(VEC_AND(fn_mask, ones_vec));\n\t\t\t}\n\n\t\t\tclassifications.truePositive = tp_sum;\n\t\t\tclassifications.trueNegative = tn_sum;\n\t\t\tclassifications.falsePositive = fp_sum;\n\t\t\tclassifications.falseNegative = fn_sum;\n\n\t\t\t// Handle remaining pixels with scalar\n\t\t\tfor (; idx < size; ++idx) {\n\t\t\t\tif (control[idx] == experiment[idx])\n\t\t\t\t\tif (experiment[idx] == Palette::Black)\n\t\t\t\t\t\tclassifications.truePositive++;\n\t\t\t\t\telse\n\t\t\t\t\t\tclassifications.trueNegative++;\n\t\t\t\telse\n\t\t\t\t\tif (experiment[idx] == Palette::Black)\n\t\t\t\t\t\tclassifications.falsePositive++;\n\t\t\t\t\telse\n\t\t\t\t\t\tclassifications.falseNegative++;\n\t\t\t}\n\t\t}\n#endif // DOXA_SIMD\n\n\t\tstatic bool CompareImages(\n\t\t\tClassifiedPerformance::Classifications& classifications, \n\t\t\tconst Image& controlImage, \n\t\t\tconst Image& experimentImage, \n\t\t\tconst std::vector<double>& weightsPrecision, \n\t\t\tconst std::vector<double>& weightsRecall)\n\t\t{\n\t\t\t// Initialize\n\t\t\tclassifications.Clear();\n\n\t\t\t// Verify Input\n\t\t\tif (controlImage.width != experimentImage.width || controlImage.height != experimentImage.height)\n\t\t\t\treturn false;\n\n\t\t\t// Ensure that weights are properly passed\n\t\t\tif (!weightsPrecision.size() || !weightsRecall.size())\n\t\t\t\treturn CompareImages(classifications, controlImage, experimentImage);\n\n\t\t\t// Analyze using Pseudo Weights\n\t\t\tfor (int i = 0; i < controlImage.size; ++i)\n\t\t\t{\n\t\t\t\tif (controlImage.data[i] == experimentImage.data[i])\n\t\t\t\t{\n\t\t\t\t\tif (experimentImage.data[i] == Palette::Black)\n\t\t\t\t\t{\n\t\t\t\t\t\tclassifications.truePositive++;\n\t\t\t\t\t\tclassifications.wpTruePositive += weightsPrecision[i];\n\t\t\t\t\t\tclassifications.wrTruePositive += weightsRecall[i];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tclassifications.trueNegative++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse // Not a match\n\t\t\t\t{\n\t\t\t\t\tif (experimentImage.data[i] == Palette::Black)\n\t\t\t\t\t{\n\t\t\t\t\t\tclassifications.falsePositive++;\n\t\t\t\t\t\tclassifications.wpFalsePositive += weightsPrecision[i];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tclassifications.falseNegative++;\n\t\t\t\t\t\tclassifications.wrFalseNegative += weightsRecall[i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tstatic double CalculateAccuracy(const Classifications& classifications)\n\t\t{\n\t\t\treturn (((double)classifications.truePositive + classifications.trueNegative) / classifications.Total()) * 100;\n\t\t}\n\n\t\tstatic double CalculateRecall(const Classifications& classifications)\n\t\t{\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (classifications.truePositive == 0) return 0.0;\n\n\t\t\tconst double recall = (double)classifications.truePositive / (classifications.truePositive + classifications.falseNegative);\n\n\t\t\treturn recall * 100;\n\t\t}\n\n\t\tstatic double CalculatePrecision(const Classifications& classifications)\n\t\t{\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (classifications.truePositive == 0) return 0.0;\n\n\t\t\tconst double precision = (double)classifications.truePositive / (classifications.truePositive + classifications.falsePositive);\n\n\t\t\treturn precision * 100;\n\t\t}\n\n\t\tstatic double CalculateFMeasure(const Classifications& classifications)\n\t\t{\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (classifications.truePositive == 0) return 0.0;\n\n\t\t\tconst double recall = (double)classifications.truePositive / (classifications.truePositive + classifications.falseNegative);\n\t\t\tconst double precision = (double)classifications.truePositive / (classifications.truePositive + classifications.falsePositive);\n\n\t\t\treturn ((2 * recall * precision) / (recall + precision)) * 100;\n\t\t}\n\n\t\tstatic double CalculatePseudoRecall(const Classifications& classifications)\n\t\t{\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (classifications.wrTruePositive == 0) return 0.0;\n\n\t\t\tconst double pseudoRecall = classifications.wrTruePositive / (classifications.wrTruePositive + classifications.wrFalseNegative);\n\n\t\t\treturn pseudoRecall * 100;\n\t\t}\n\n\t\tstatic double CalculatePseudoPrecision(const Classifications& classifications)\n\t\t{\n\t\t\tconst double pseudoTruePositive = classifications.wpTruePositive + classifications.truePositive;\n\t\t\tconst double pseudoFalsePositive = classifications.wpFalsePositive + classifications.falsePositive;\n\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (pseudoTruePositive == 0) return 0.0;\n\n\t\t\tconst double pseudoPrecision = pseudoTruePositive / (pseudoTruePositive + pseudoFalsePositive);\n\n\t\t\treturn pseudoPrecision * 100;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Pseudo F-Measure\n\t\t/// </summary>\n\t\t/// <remarks>\"Performance Evaluation Methodology for Historical Document Image Binarization\", 2013.</remarks>\n\t\tstatic double CalculatePseudoFMeasure(const Classifications& classifications)\n\t\t{\n\t\t\tconst double pseudoTruePositivePrecision = classifications.wpTruePositive + classifications.truePositive;\n\t\t\tconst double pseudoFalsePositivePrecision = classifications.wpFalsePositive + classifications.falsePositive;\n\t\t\tconst double pseudoTruePositiveRecall = classifications.wrTruePositive;\n\t\t\tconst double pseudoFalseNegativeRecall = classifications.wrFalseNegative;\n\n\t\t\t// Prevent divide by zero.  Range is 0.0 to 1.0\n\t\t\tif (pseudoTruePositivePrecision == 0 || pseudoTruePositiveRecall == 0) return 0.0;\n\n\t\t\tconst double pseudoPrecision = pseudoTruePositivePrecision / (pseudoTruePositivePrecision + pseudoFalsePositivePrecision);\n\t\t\tconst double pseudoRecall = pseudoTruePositiveRecall / (pseudoTruePositiveRecall + pseudoFalseNegativeRecall);\n\n\t\t\tconst double pseudoFMeasure = ((2 * pseudoRecall * pseudoPrecision) / (pseudoRecall + pseudoPrecision)) * 100;\n\n\t\t\treturn pseudoFMeasure;\n\t\t}\n\n\t\tstatic double CalculatePSNR(const Classifications& classifications)\n\t\t{\n\t\t\t// Calculate MSE\n\t\t\tconst double mse = ((double)classifications.falsePositive + classifications.falseNegative) / classifications.Total();\n\n\t\t\t// Perfect match.  Prevent divide by zero error.\n\t\t\tif (mse == 0) return std::numeric_limits<double>::max();\n\n\t\t\t// Calculate Peak Signal to Noise Ratio\n\t\t\treturn 10 * log10(1 / mse);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Matthews Correlation Coefficient\n\t\t/// This should be more reliable than F-Measure for binary classification.  See article below.\n\t\t/// </summary>\n\t\t/// <remarks>https://en.wikipedia.org/wiki/Matthews_correlation_coefficient</remarks>\n\t\t/// <returns>A number between -1 and 1, where 0 is totally random guessing.</returns>\n\t\tstatic double CalculateMCC(const Classifications& classifications)\n\t\t{\n\t\t\tconst double n = (double)classifications.truePositive * classifications.trueNegative - (double)classifications.falsePositive * classifications.falseNegative;\n\t\t\tconst double d =\n\t\t\t\t((double)classifications.truePositive + classifications.falsePositive) *\n\t\t\t\t((double)classifications.truePositive + classifications.falseNegative) *\n\t\t\t\t((double)classifications.trueNegative + classifications.falsePositive) *\n\t\t\t\t((double)classifications.trueNegative + classifications.falseNegative);\n\n\t\t\t// If undefined, return 0 to highlight the issue.\n\t\t\treturn d == 0 ? 0 : n / std::sqrt(d);\n\t\t}\n\n\t\tstatic double CalculateNRM(const Classifications& classifications)\n\t\t{\n\t\t\tconst int fntp = classifications.falseNegative + classifications.truePositive;\n\t\t\tconst int fptn = classifications.falsePositive + classifications.trueNegative;\n\n\t\t\t// Prevent divide by zero error\n\t\t\tif (fntp == 0 || fptn == 0) return std::numeric_limits<double>::max();\n\n\t\t\tconst double nrfn = (double)classifications.falseNegative / fntp;\n\t\t\tconst double nrfp = (double)classifications.falsePositive / fptn;\n\n\t\t\t// Calculate Negative Rate Metric\n\t\t\treturn (nrfn + nrfp) / 2;\n\t\t}\n\n\t\t// Convenience Method\n\t\ttemplate<typename CalcFunc>\n\t\tstatic double Calculate(const Image& controlImage, const Image& experimentImage, CalcFunc calcFunc)\n\t\t{\n\t\t\tClassifications classifications;\n\t\t\treturn CompareImages(classifications, controlImage, experimentImage) ? calcFunc(classifications) : 0.0;\n\t\t}\n\t};\n}\n\n\n#endif //CLASSIFIEDPERFORMANCE_HPP\n"
  },
  {
    "path": "Doxa/ContrastImage.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef CONTRASTIMAGE_HPP\n#define CONTRASTIMAGE_HPP\n\n#include <vector>\n#include \"Types.hpp\"\n#include \"Otsu.hpp\"\n#include \"Palette.hpp\"\n#include \"Region.hpp\"\n#include \"Morphology.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// Contrast Image generation class\n\t/// </summary>\n\t/// <remarks>\"Binarization of Historical Document Images Using the Local Maximum and Minimum\", 2010.</remarks>\n\tclass ContrastImage\n\t{\n\tpublic:\n\t\tstatic inline void GenerateContrastImage(Image& contrastImage, const Image& grayScaleImage)\n\t\t{\n\t\t\tconst int windowSize = 3;\n\n\t\t\tPixel8 min, max;\n\n\t\t\tImage minImage(grayScaleImage.width, grayScaleImage.height);\n\t\t\tImage maxImage(grayScaleImage.width, grayScaleImage.height);\n\n\t\t\tMorphology::Erode(minImage, grayScaleImage, windowSize);\n\t\t\tMorphology::Dilate(maxImage, grayScaleImage, windowSize);\n\n\t\t\tLocalWindow::Iterate(grayScaleImage, windowSize, [&](const Region& window, const int& position) {\n\n\t\t\t\tmin = minImage.data[position];\n\t\t\t\tmax = maxImage.data[position];\n\n\t\t\t\tconst double contrastMultiplier = (double)(max - min) / (0.0001 + max + min);\n\n\t\t\t\t// Note: The paper leaves out the fact that the Contrast Image actually has to be normalized.\n\t\t\t\t// To normalize it back into an 8bit gray scale image, simply multiply by 255.\n\t\t\t\tcontrastImage.data[position] = 255 * contrastMultiplier;\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Estimates the text stroke width from a contrast image by scanning each row\n\t\t/// for peak contrast pixels and building a histogram of distances between adjacent peaks.\n\t\t/// The most frequent distance corresponds to the stroke width.\n\t\t/// </summary>\n\t\tstatic inline int EstimateStrokeWidth(const Image& contrastImage)\n\t\t{\n\t\t\tstd::vector<int> histogram(contrastImage.width, 0);\n\n\t\t\tfor (int y = 0; y < contrastImage.height; ++y)\n\t\t\t{\n\t\t\t\tconst int row = y * contrastImage.width;\n\t\t\t\tint lastPeakX = -1;\n\n\t\t\t\tfor (int x = 1; x < contrastImage.width - 1; ++x)\n\t\t\t\t{\n\t\t\t\t\tconst Pixel8 val = contrastImage.data[row + x];\n\n\t\t\t\t\tif (val > contrastImage.data[row + x - 1] && val > contrastImage.data[row + x + 1])\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lastPeakX >= 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t++histogram[x - lastPeakX];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlastPeakX = x;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The mode is the estimated stroke width (skip distance 1 as sub-pixel noise)\n\t\t\tint strokeWidth = 3;\n\t\t\tint maxCount = 0;\n\n\t\t\tfor (int d = 2; d < contrastImage.width; ++d)\n\t\t\t{\n\t\t\t\tif (histogram[d] > maxCount)\n\t\t\t\t{\n\t\t\t\t\tmaxCount = histogram[d];\n\t\t\t\t\tstrokeWidth = d;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn strokeWidth;\n\t\t}\n\n\t\tstatic inline void GenerateHighContrastImage(Image& highContrastImage, const Image& grayScaleImage)\n\t\t{\n\t\t\t// Generate Contrast Image\n\t\t\tGenerateContrastImage(highContrastImage, grayScaleImage);\n\n\t\t\t// Run it through Otsu binarization to make it a high contrast image\n\t\t\tOtsu otsu;\n\t\t\totsu.Initialize(highContrastImage);\n\t\t\totsu.ToBinary(highContrastImage);\n\t\t}\n\t};\n}\n\n\n#endif //CONTRASTIMAGE_HPP\n"
  },
  {
    "path": "Doxa/DIBCOUtils.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2025, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef DIBCOUTILS_HPP\n#define DIBCOUTILS_HPP\n\n#include <fstream>\n#include <istream>\n#include <vector>\n\n\nnamespace Doxa\n{\n\tclass DIBCOUtils\n\t{\n\tpublic:\n\n\t\t/// <summary>\n\t\t/// Read DIBCO Weighted .dat files.\n\t\t/// </summary>\n\t\t/// <remarks>\"Performance Evaluation Methodology for Historical Document Image Binarization\", 2013.</remarks>\n\t\tstatic std::vector<double> ReadWeightsFile(const std::string& fileLocation, size_t allocatedSize = 0)\n\t\t{\n\t\t\tstd::ifstream file;\n\t\t\tfile.open(fileLocation.c_str(), std::ios::binary);\n\n\t\t\tconst auto weights = DIBCOUtils::ReadWeights(file, allocatedSize);\n\n\t\t\tfile.clear();\n\t\t\tfile.close(); // Automatically closes, but done explicitly for posterity.\n\n\t\t\treturn weights;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Read DIBCO Weighted content from either a file or string stream.\n\t\t/// </summary>\n\t\tstatic std::vector<double> ReadWeights(std::istream& stream, size_t allocatedSize = 0)\n\t\t{\n\t\t\tstd::vector<double> values;\n\t\t\tvalues.reserve(allocatedSize);\n\n\t\t\tdouble value;\n\t\t\twhile (stream >> value)\n\t\t\t{\n\t\t\t\tvalues.push_back(value);\n\t\t\t}\n\n\t\t\treturn values;\n\t\t}\n\t};\n}\n\n\n#endif //DIBCOUTILS_HPP\n"
  },
  {
    "path": "Doxa/DRDM.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef DRDM_HPP\n#define DRDM_HPP\n\n#include <algorithm>\n#include \"Image.hpp\"\n#include \"Palette.hpp\"\n#include \"Region.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"SIMDOps.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Distance-Reciprocal Distortion Measure (DRDM) Algorithm: Haiping Lu, Jian Wang, A.C. Kot, Y.Q. Shi\n\t/// </summary>\n\t/// <remarks>\"An Objective Distortion Measure for Binary Document Images Based on Human Visual Perception\", 2002.</remarks>\n\tclass DRDM\n\t{\n\tpublic:\n\t\tstatic double CalculateDRDM(const Image& controlImage, const Image& experimentImage)\n\t\t{\n\t\t\tconst uint64_t sumDRDk = SumDRDkForMismatchedPixels(controlImage, experimentImage);\n\n\t\t\t// To avoid rounding issues we are using ints instead of doubles, which we accomplished by using a 1000000 multiplier.\n\t\t\treturn sumDRDk / (double)(NUBN(controlImage) * 1000000);\n\t\t}\n\n\tprotected:\n        static constexpr int N = 5;\n        static constexpr int R = N / 2;\n\n        // Normalized Weighted Matrix\n        // Values have been multiplied by 1000000 in order to avoid slight rounding errors with doubles.\n        // These values are more granular than the example matrix given in the research paper.\n        // If you use those values, you will hit rounding problems with their sample data because they are actually using more\n        // precise Normalized Matrix values when calculating DRD than what is provided in that example.\n        static constexpr uint32_t Wm[N * N] = {\n            25582, 32359, 36179, 32359, 25582,\n            32359, 51164, 72357, 51164, 32359,\n            36179, 72357,     0, 72357, 36179,\n            32359, 51164, 72357, 51164, 32359,\n            25582, 32359, 36179, 32359, 25582\n        };\n\n        /// <summary>\n\t\t/// Sum DRDk for all mismatched pixels between control and experiment images.\n        /// This is an optimized algorithm,\n\t\t/// </summary>\n        static uint64_t SumDRDkForMismatchedPixels(const Image& control, const Image& experiment)\n        {\n            uint64_t sum = 0;\n            const int w = control.width;\n            const int h = control.height;\n\n            const Pixel8* ctl = control.data;\n            const Pixel8* exp = experiment.data;\n\n            for (int y = 0; y < h; ++y)\n            {\n                const int row = y * w;\n\n                // Clamp region - Y\n                const int y0 = (y - R < 0) ? 0 : y - R;\n                const int y1 = (y + R >= h) ? h - 1 : y + R;\n\n                for (int x = 0; x < w; ++x)\n                {\n                    /* TODO: Validate that this is truly better on a wide range of images\n                    // Compare 16 pixels at once for a ~20% speedup\n                    // This is only beneficial if your images are very similar\n                    if (x + 15 < w) // Read X + 15 More = 16\n                    {\n                        //if (VEC_ALL_EQ_U8(VEC_LOAD(ctl + row + x), VEC_LOAD(exp + row + x)))\n                        if (memcmp(ctl + row + x, exp + row + x, 16) == 0) // No SIMD necessary\n                        {\n                            x += 15;\n                            continue;\n                        }\n                    }\n                    */\n\n                    const Pixel8 g = exp[row + x];\n\n                    if (ctl[row + x] == g)\n                        continue;\n\n                    uint32_t localSum = 0;\n\n                    // Clamp region - X\n                    const int x0 = (x - R < 0) ? 0 : x - R;\n                    const int x1 = (x + R >= w) ? w - 1 : x + R;\n\n                    // Walk neighborhood\n                    for (int ny = y0; ny <= y1; ++ny)\n                    {\n                        const int base = ny * w;\n                        const int wy = ny - (y - R);\n                        const int wyRow = wy * 5;\n\n                        for (int nx = x0; nx <= x1; ++nx)\n                        {                    \n                            const int wx = nx - (x - R);\n\n                            // Compute weight index\n                            const uint32_t weight = Wm[wyRow + wx];\n\n                            // Branchless add:\n                            localSum += weight * (ctl[base + nx] != g);\n                        }\n                    }\n\n                    sum += localSum;\n                }\n            }\n\n            return sum;\n        }\n\n\n        /// <summary>\n        /// Calculate the number of non-uniform MxM windows (both white and black pixels).\n        /// \n        /// This uses an over-engineer set of algorithms that attempt to make this otherwise\n        /// simple calculation as fast as possible.  Because M = 8 is a standard, this path\n        /// has been optimized.\n        /// \n        /// NOTE: DIBCO Metrics do not process partial windows\n        /// NOTE: DRDM defaults to 8x8 windows, which DIBCO Metrics uses\n        /// \n        /// </summary>\n\t\tstatic unsigned int NUBN(const Image& controlImage, const int M = 8)\n\t\t{\n\t\t    // Use optimized path for standard 8x8 blocks\n            if (M == 8)\n            {\n                #if defined(DOXA_SIMD)\n                    return NUBN_SIMD_8x8(controlImage);\n                #else\n                    return NUBN_STD_8x8(controlImage);\n                #endif\n            }\n\t\t\t\n\t\t\treturn NUBN_STD(controlImage, M);\n\t\t}\n\n        /// <summary>\n        /// Calculate the number of non-uniform NxN windows (both white and black pixels).\n        /// NOTE: DIBCO Metrics do not process partial windows\n        /// \n        /// Algorithm\n        /// This is a memory optimized algorithm that iterates through an image pixel by pixel\n        /// not window by window.  It has many early exit optimizations.\n        /// \n        /// To accomplish this it stores a special row for keeping track of the state of each\n        /// window as we iterate across each window.\n        /// \n        /// </summary>\n        static int NUBN_STD(const Image& controlImage, int N)\n        {\n            const int numWindowCols = controlImage.width / N;\n            const int numWindowRows = controlImage.height / N;\n    \n            if (numWindowCols == 0 || numWindowRows == 0)\n            {\n                return 0;\n            }\n\n            constexpr int MIXED = -1;  // Sentinel: valid sums are always >= 0\n            const int whiteRowSum = 255 * N;\n    \n            std::vector<int> expected(numWindowCols);\n            int totalMixed = 0;\n    \n            const uint8_t* bandPtr = controlImage.data;\n            const int bandStride = N * controlImage.width;\n    \n            for (int wy = 0; wy < numWindowRows; ++wy)\n            {\n                int mixedCount = 0;\n                const uint8_t* px = bandPtr;\n        \n                // === Row 0: Classify all windows ===\n                for (int wx = 0; wx < numWindowCols; ++wx)\n                {\n                    int sum = 0;\n                    for (int i = 0; i < N; ++i)\n                    {\n                        sum += px[i];\n                    }\n                    px += N;\n            \n                    if (sum == 0 || sum == whiteRowSum)\n                    {\n                        expected[wx] = sum;\n                    } \n                    else\n                    {\n                        expected[wx] = MIXED;\n                        ++mixedCount;\n                    }\n                }\n        \n                // === Rows 1 to N-1: Verify uniformity ===\n                const Pixel8* rowPtr = bandPtr + controlImage.width;\n                for (int localY = 1; localY < N; ++localY)\n                {\n                    if (mixedCount == numWindowCols) break;\n            \n                    px = rowPtr;\n                    for (int wx = 0; wx < numWindowCols; ++wx)\n                    {\n                        const int exp = expected[wx];\n                        if (exp == MIXED) {\n                            px += N;\n                            continue;\n                        }\n                \n                        int sum = 0;\n                        for (int i = 0; i < N; ++i)\n                        {\n                            sum += px[i];\n                        }\n                        px += N;\n                \n                        if (sum != exp)\n                        {\n                            expected[wx] = MIXED;\n                            ++mixedCount;\n                        }\n                    }\n\n                    rowPtr += controlImage.width;\n                }\n        \n                totalMixed += mixedCount;\n                bandPtr += bandStride;\n            }\n    \n            return totalMixed;\n        }\n\n        /// <summary>\n        /// Calculate the number of non-uniform 8x8 windows\n        /// NOTE: DIBCO Metrics do not process partial windows\n        /// \n        /// Algorithm\n        /// This algorithm is identical to NUBN_STD, except we are able to further optimize it\n        /// based on the known 8x8 window size, standard for DRDM.\n        /// \n        /// These memory tricks get this implentation about as close to SIMD speed as possible.\n        /// \n        /// </summary>\n        static int NUBN_STD_8x8(const Image& controlImage)\n        {\n            constexpr uint64_t ALL_BLACK = 0x0000000000000000ULL;\n            constexpr uint64_t ALL_WHITE = 0xFFFFFFFFFFFFFFFFULL;\n            constexpr uint64_t MIXED = 1ULL;  // Sentinel: impossible for uniform row\n            constexpr unsigned int N = 8;\n    \n            const int numWindowCols = controlImage.width / N;   // NOTE: Compiler will optimize to >> 3\n            const int numWindowRows = controlImage.height / N;\n            const int rowStride = controlImage.width;\n            const int bandStride = rowStride * N;\t            // NOTE: Compiler will optimize to << 3\n    \n            if (numWindowCols == 0 || numWindowRows == 0)\n            {\n                return 0;\n            }\n    \n            std::vector<uint64_t> expected(numWindowCols);\n            int totalMixed = 0;\n    \n            const Pixel8* bandPtr = controlImage.data;\n    \n            for (int wy = 0; wy < numWindowRows; ++wy)\n            {\n                int mixedCount = 0;\n                const Pixel8* px = bandPtr;\n        \n                // Row 0: classify all windows (no branches for state check)\n                for (int wx = 0; wx < numWindowCols; ++wx, px += N)\n                {\n                    uint64_t row;\n                    std::memcpy(&row, px, N);\n            \n                    if (row == ALL_BLACK || row == ALL_WHITE)\n                    {\n                        expected[wx] = row;\n\n                    } else\n                    {\n                        expected[wx] = MIXED;\n                        ++mixedCount;\n                    }\n                }\n        \n                // Rows 1-7: verify uniformity (no UNCLASSIFIED check)\n                const Pixel8* rowPtr = bandPtr + rowStride;\n                for (int localY = 1; localY < N; ++localY)\n                {\n                    if (mixedCount == numWindowCols) break;\n            \n                    px = rowPtr;\n                    for (int wx = 0; wx < numWindowCols; ++wx, px += N)\n                    {\n                        const uint64_t exp = expected[wx];\n                        if (exp == MIXED) continue;\n                \n                        uint64_t row;\n                        std::memcpy(&row, px, N);\n                \n                        if (row != exp)\n                        {\n                            expected[wx] = MIXED;\n                            ++mixedCount;\n                        }\n                    }\n\n                    rowPtr += rowStride;\n                }\n        \n                totalMixed += mixedCount;\n                bandPtr += bandStride;\n            }\n    \n            return totalMixed;\n        }\n\n#if defined(DOXA_SIMD)\n\n\t\t/// <summary>\n\t\t/// SIMD implementation of NUBN for 8x8 blocks\n\t\t/// </summary>\n        static unsigned int NUBN_SIMD_8x8(const Image& controlImage)\n        {\n            unsigned int nubn = 0;\n            const int M = 8;\n            const int stride = controlImage.width;\n            const int columns = stride / M;\n            const int rows = controlImage.height / M;\n            const Pixel8* rowPtr = controlImage.data;\n\n            for (int row = 0; row < rows; ++row)\n            {\n                const Pixel8* blockPtr = rowPtr;\n                for (int column = 0; column < columns; ++column)\n                {\n                    if (!IsBlock8x8Uniform(blockPtr, stride))\n                    {\n                        ++nubn;\n                    }\n\n                    blockPtr += M;\n                }\n\n                rowPtr += stride * M;\n            }\n\n            return nubn;\n        }\n\n        /// <summary>\n        /// Check if an 8x8 block is uniform (all pixels match reference value)\n        /// SIMD Required\n        /// </summary>\n\t\tstatic inline bool IsBlock8x8Uniform(const uint8_t* ptr, int stride)\n\t\t{\n\t\t\tSIMD::vec128 ref = VEC_SPLAT_U8(*ptr);\n\n\t\t\tfor (int row = 0; row < 8; row += 2)\n            {\n\t\t\t\tSIMD::vec128 rows = VEC_LOAD_2x64(ptr, ptr + stride);\n\t\t\t\tif (!VEC_ALL_EQ_U8(rows, ref)) return false;\n\t\t\t\tptr += stride * 2;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n#endif // DOXA_SIMD\n\t};\n}\n\n\n#endif //DRDM_HPP\n"
  },
  {
    "path": "Doxa/Doxa.vcxitems",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Label=\"Globals\">\n    <MSBuildAllProjects Condition=\"'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'\">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>\n    <HasSharedItems>true</HasSharedItems>\n    <ItemsProjectGuid>{d81f2737-6340-49c1-ae65-8d217415c67e}</ItemsProjectGuid>\n  </PropertyGroup>\n  <ItemDefinitionGroup>\n    <ClCompile>\n      <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>\n    </ClCompile>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ProjectCapability Include=\"SourceItemsFromImports\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)AdOtsu.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Algorithm.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Bataineh.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Bernsen.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)BinarizationFactory.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ChanMeanCalc.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ChanMeanVarianceCalc.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ClassifiedPerformance.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ContrastImage.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)DRDM.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Gatos.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Grayscale.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)GridCalc.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Image.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)IntegralImageMeanVarianceCalc.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)ISauvola.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)LocalWindow.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Morphology.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)MultiScale.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Niblack.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Nick.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Otsu.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Palette.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Parameters.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)PNM.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)DIBCOUtils.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Region.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Sauvola.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)SIMD.h\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)SIMDOps.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Su.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)TRSingh.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Types.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Wan.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)WienerFilter.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Wolf.hpp\" />\n    <ClInclude Include=\"$(MSBuildThisFileDirectory)Phansalkar.hpp\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "Doxa/Gatos.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef GATOS_HPP\n#define GATOS_HPP\n\n#include \"Types.hpp\"\n#include \"Sauvola.hpp\"\n#include \"Palette.hpp\"\n#include \"Region.hpp\"\n#include \"Image.hpp\"\n#include \"WienerFilter.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Gatos binarization workflow: B. Gatos, I. Pratikakis, S.J. Perantonis\n\t/// This is a 5 step workflow consisting of:\n\t///\t\tWiener Filter\n\t///\t\tSauvola binarization algorithm\n\t///\t\tA background estimation based thresholding algorithm\n\t///\t\tUpsampling and other post-processing measures\n\t/// \n\t/// The optional Upsampling on the fourth step is not currently performed, nor the Post-processing for the fifth step.\n\t/// </summary>\n\t/// <remarks>\"Adaptive degraded document image binarization\", 2005.</remarks>\n\tclass Gatos : public Algorithm<Gatos>\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int glyphSize = parameters.Get(\"glyph\", 60);\n\n\t\t\t// Step 1 - Pre-processing: Run greyscale through Wiener Filter\n\t\t\tImage filteredImage(Algorithm::grayScaleImageIn);\n\t\t\tWienerFilter::Filter(filteredImage, Algorithm::grayScaleImageIn, 3);\n\n\t\t\t// Step 2 - Rough estimation of foreground regions: Apply Sauvola binarization\n\t\t\tSauvola algorithm;  // TODO - Allow this algorithm to be swapped with any in the library\n\t\t\talgorithm.Initialize(filteredImage);\n\t\t\talgorithm.ToBinary(binaryImageOut, parameters);\n\n\t\t\t// Step 3 - Background surface estimation\n\t\t\tImage backgroundImage(filteredImage);\n\t\t\tExtractBackground(backgroundImage, filteredImage, binaryImageOut, (glyphSize * 2) + 1);\n\n\t\t\t// Step 4 - Final thresholding\n\t\t\tdouble d, b;\n\t\t\tGatosCalculations(d, b, backgroundImage, filteredImage, binaryImageOut);\n\n\t\t\tfor (int index = 0; index < binaryImageOut.size; ++index)\n\t\t\t{\n\t\t\t\tconst double threshold = Threshold(backgroundImage.data[index], d, b);\n\n\t\t\t\tbinaryImageOut.data[index] = backgroundImage.data[index] - filteredImage.data[index] > threshold ?\n\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t}\n\n\t\t\t// Step 4.5 - Upsampling\n\t\t\t// This increases your image size.  Not implementing.\n\n\t\t\t// Step 5 - Post-processing\n\t\t\t// Resulted in a significant loss of detail.  Not providing until refined.\n\t\t}\n\n\tprotected:\n\n\t\t/// <summary>\n\t\t/// Calculates Average Foreground / Background Distance, and Average Background Text Value.\n\t\t/// </summary>\n\t\tvoid GatosCalculations(double& averageFgBgDistance, double& averageBgTextValue, const Image& backgroundImage, const Image& filteredImage, const Image& binaryImage) const\n\t\t{\n\t\t\tint backgroundCounter = 0;\n\t\t\tint numeratorAverageFgBgDistance = 0; // Calculate Average Foreground / Background Distance\n\t\t\tint numeratorAverageBgTextValue = 0; // Calculate Average Background Text Value\n\n\t\t\tfor (int index = 0; index < binaryImage.size; ++index)\n\t\t\t{\n\t\t\t\tnumeratorAverageFgBgDistance += backgroundImage.data[index] - filteredImage.data[index];\n\n\t\t\t\tif (Palette::White == binaryImage.data[index])\n\t\t\t\t{\n\t\t\t\t\tnumeratorAverageBgTextValue += backgroundImage.data[index];\n\t\t\t\t\t++backgroundCounter;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taverageFgBgDistance = (double)numeratorAverageFgBgDistance / (backgroundImage.size - backgroundCounter);\n\t\t\taverageBgTextValue = (double)numeratorAverageBgTextValue / backgroundCounter;\n\t\t}\n\n\t\tdouble Threshold(const int backgroundValue, const double d, const double b, const double q = 0.6, const double p1 = 0.5, const double p2 = 0.8) const\n\t\t{\n\t\t\tconst double expVal = exp(((-4 * backgroundValue) / (b * (1 - p1))) + ((2 * (1 + p1)) / (1 - p1)));\n\t\t\treturn q * d * (((1 - p2) / (1 + expVal)) + p2);\n\t\t}\n\n\t\t// Note: backgroundImage must be a copy of grayScaleImage.  This avoids us having to set pixels for the background entirely\n\t\tvoid ExtractBackground(Image& backgroundImage, const Image& filteredImage, const Image& binaryImage, const int windowSize = 51) const\n\t\t{\n\t\t\tLocalWindow::Iterate(filteredImage, windowSize, [&](const Region& window, const int& position)\n\t\t\t{\t\n\t\t\t\tif (binaryImage.data[position] == Palette::Black)\n\t\t\t\t{\n\t\t\t\t\tunsigned int numerator = 0;\n\t\t\t\t\tunsigned int denominator = 0;\n\n\t\t\t\t\t// Build a window around our black pixel and traverse it\n\t\t\t\t\tLocalWindow::Iterate(filteredImage.width, window, [&](const int& windowPosition)\n\t\t\t\t\t{\n\t\t\t\t\t\t// This is usually mathematically described as:\n\t\t\t\t\t\t//     Numerator += B(x, y) * (1 − S(x, y))\n\t\t\t\t\t\t//     Denominator += (1 − S(x, y))\n\t\t\t\t\t\t// This assumes that your binary image's black value is 1, and white 0.\n\t\t\t\t\t\t// Blindly following this mathematical formula also impacts performance!\n\t\t\t\t\t\tif (binaryImage.data[windowPosition] == Palette::White)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnumerator += filteredImage.data[windowPosition];\n\t\t\t\t\t\t\t++denominator;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tif (denominator > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tbackgroundImage.data[position] = numerator / denominator;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //GATOS_HPP\n"
  },
  {
    "path": "Doxa/Grayscale.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2022, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef GRAYSCALE_HPP\n#define GRAYSCALE_HPP\n\n#include <algorithm>\n#include <array>\n#include <optional>\n#include <vector>\n#include \"Types.hpp\"\n\n\nnamespace Doxa\n{\n\tusing GrayscaleFunc = Pixel8(*)(Pixel8, Pixel8, Pixel8);\n\tusing XYZ = std::tuple<float, float, float>;\n\tusing Lab = std::tuple<float, float, float>;\n\n\tenum GrayscaleAlgorithms\n\t{\n\t\tMEAN = 0,\n\t\tQT = 1,\n\t\tBT601 = 2,\n\t\tBT709 = 3,\n\t\tBT2100 = 4,\n\t\tVALUE = 5,\n\t\tLUSTER = 6,\n\t\tLIGHTNESS = 7,\n\t\tMINAVG = 8,\n\t\tLABDIST = 9\n\t};\n\n\t/// <summary>\n\t/// This entire class was greatly influenced by the Color-to-Grayscale article written by Christopher Kanan and \n\t/// Garrison W. Cottrell.\n\t/// \n\t/// With the PNM input format, despite the Ref 709 gamma correction scheme specified, there are many variants.\n\t/// The most important aspect to know, however, is not  the format of sRBG, 601, 709, etc, but if gamma correction\n\t/// has been applied in the first place.  Reading in a PNM color image, one should assume it is gamma corrected.\n\t/// \n\t/// The top 2 grayscale formulas found by Kanan and Cottrell are Gleam and Intensity'.\n\t/// The great news is that these share the same formula which is very fast, referred to here as Mean(...).\n\t/// The bad news is that if you are given a Linear RGB set, your Intensity' is now just Intensity and drops you\n\t/// from 2nd place to 8th.  Luckily, for color images, you should safely assume you are receiving gamma corrected\n\t/// RGB values.\n\t/// \n\t/// Because we should assume some form of gamma correction, we are also far more likely to get the result of Luma\n\t/// than Luminance (exact formula isn't as important), which should be reassuring as that would be a drop from 5th\n\t/// 10th.  But to show the power of correctly controlling your gamma conversion, if one applied that same formula to\n\t/// to Linear RGB values and then gamma corrected after the fact, you end up with the 3rd place finisher, Luminance'.\n\t/// Basically the same formula can take you from 3rd to 10th place, simply due to gamma correction!\n\t/// \n\t/// It is therefore this naive author's opinion that as long as you start with gamma corrected RGB values, you\n\t/// should be set regardless of your exact gamma compression scheme, or grayscale conversion formula you want to try.\n\t/// It is also recommended that when you finally do convert to Grayscale, that you apply your image processing \n\t/// algorithms to an uncompressed, linear, grayscale image.\n\t/// \n\t/// Also see:\n\t/// https://en.wikipedia.org/wiki/Grayscale\n\t/// https://blog.johnnovak.net/2016/09/21/what-every-coder-should-know-about-gamma/\n\t/// </summary>\n\t/// <remarks>\"Color-to-Grayscale: Does the Method Matter in Image Recognition?\", 2012.</remarks>\n\tclass Grayscale\n\t{\n\tpublic:\n\t\t/// <summary>\n\t\t/// Linear Y value that will be sRGB gamma corrected\n\t\t/// </summary>\n\t\tstatic inline void LinearTosRgb(double& y)\n\t\t{\n\t\t\ty =  y <= 0.0031308 ? y * 12.92 : Gamma((1.055 * y - 0.055) / 1.055, 2.4);\n\t\t}\n\n\t\tstatic inline void LinearTo709(double& y)\n\t\t{\n\t\t\ty = y <= 0.0018 ? y * 4.5 : Gamma((1.099 * y - 0.099) / 1.055, 2.2);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Return a fast linear conversion LUT for uncompressing a color space\n\t\t/// </summary>\n\t\tstatic std::array<float, 256> LinearLUT()\n\t\t{\n\t\t\tstd::array<float, 256> lut;\n\t\t\t\n\t\t\tfor (int i = 0; i < 256; i++)\n\t\t\t{\n\t\t\t\tconst float v = i / 255.0f;\n\t\t\t\tlut[i] = (v <= 0.04045f) ? v / 12.92f : powf((v + 0.055f) / 1.055f, 2.4f);\n\t\t\t}\n\n\t\t\treturn lut;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// RGB are linear values that this function will gamma correct.\n\t\t/// </summary>\n\t\tstatic inline void Gamma(double& r, double& g, double& b, const double gamma = 2.2)\n\t\t{\n\t\t\tr = Gamma(r, gamma);\n\t\t\tg = Gamma(g, gamma);\n\t\t\tb = Gamma(b, gamma);\n\t\t}\n\n\t\tstatic inline double Gamma(const double channel, const double gamma = 2.2)\n\t\t{\n\t\t\treturn std::pow(channel, 1 / gamma);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The formula used by the Qt framework which is used by our default.\n\t\t/// Note: There are serious unanswered questions around this formula.\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T Qt(T r, T g, T b)\n\t\t{\n\t\t\treturn (r * 11 + g * 16 + b * 5) / 32;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// If RGB are Linear, this calculates the Intensity.\n\t\t/// If RGB are Gamma Corrected, this calculates Gleam.\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T Mean(T r, T g, T b)\n\t\t{\n\t\t\treturn (r + g + b) / 3;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// BT601 calculates the Luma when RGB are Gamma Corrected. The Y' from Y'UV & Y'IQ.\n\t\t/// When Linear, can generate the luminance Y from the CIE 1931 XYZ color space.\n\t\t/// Aka: NTSC RGB formula, with a White Point of \"C\".\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T BT601(T r, T g, T b)\n\t\t{\n\t\t\treturn 0.2989 * r + 0.5865 * g + 0.1144 * b;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// BT709 calculates the Luma when RGB are Gamma Corrected. The Y' from Y'UV & Y'IQ.\n\t\t/// When Linear, can generate the luminance Y from the CIE 1931 XYZ color space.\n\t\t/// Aka sRGB formula, with a White Point of \"D65\".\n\t\t/// The D50 weights, for ICC, are: 0.2225045  0.7168786  0.0606169\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T BT709(T r, T g, T b)\n\t\t{\n\t\t\treturn 0.2126 * r + 0.7152 * g + 0.0722 * b;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// BT2100 calculates the Luma when RGB are Gamma Corrected. The Y' from Y'UV & Y'IQ.\n\t\t/// When Linear, can generate the luminance Y from the CIE 1931 XYZ color space.\n\t\t/// Has a White Point of \"D65\".\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T BT2100(T r, T g, T b)\n\t\t{\n\t\t\treturn 0.2627 * r + 0.6780 * g + 0.0593 * b;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// HSV V Value.  Calculates Value when RGB are Linear.\n\t\t/// Gamma Corrected RGB values produce the same result as a Gamma Corrected Value.\n\t\t/// </summary>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T Value(T r, T g, T b)\n\t\t{\n\t\t\treturn std::max({ r, g, b });\n\t\t}\n\n\t\t/// <summary>\n\t\t/// HLS L Value.  Calculates Lightness when RGB are Linear.\n\t\t/// </summary>\n\t\t/// <remarks>Named Luster as to not be confused by CIE Lightness</remarks>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T Luster(T r, T g, T b)\n\t\t{\n\t\t\treturn (std::max({ r, g, b }) + std::min({ r, g, b })) / 2;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// The purpose of MinAvg is to produce a grayscale image whose values are less sensitive to multi color text.\n\t\t/// It was introduced for the first AdOtsu algorithm.\n\t\t/// </summary>\n\t\t/// <remarks>\"A multi-scale framework for adaptive binarization of degraded document images\", 2010</remarks>\n\t\ttemplate<typename T>\n\t\tstatic inline constexpr T MinAvg(T r, T g, T b)\n\t\t{\n\t\t\treturn (Mean(r, g, b) + std::min({ r, g, b })) / 2;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// CIELAB & CIELUV L Value.  Calculates Lightness when RGB are Linear.\n\t\t/// Notice that this has built in gamma correction.\n\t\t/// Note: BT709 has a White Point of D65.  The ICC calls for D50.\n\t\t/// This is also known as a chromatic adaptation transformation (CAT).\n\t\t/// See:  https://drafts.csswg.org/css-color/#rgb-to-lab\n\t\t/// </summary>\n\t\tstatic inline constexpr float Lightness(float r, float g, float b)\n\t\t{\n\t\t\tconst auto addGamma = [&](double y)\n\t\t\t{\n\t\t\t\treturn y > 0.00885 ? Gamma(y, 3) : 7.78703 * y + 0.13793;\n\t\t\t};\n\n\t\t\treturn 116 * addGamma(BT709(r, g, b)) - 16;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Linear sRGB to XYZ color space with a D65 white point\n\t\t/// </summary>\n\t\tstatic constexpr inline XYZ RGBToXYZ(float r, float g, float b)\n\t\t{\n\t\t\treturn {\n\t\t\t\t0.4124564f * r + 0.3575761f * g + 0.1804375f * b,\n\t\t\t\t0.2126729f * r + 0.7151522f * g + 0.0721750f * b,\n\t\t\t\t0.0193339f * r + 0.1191920f * g + 0.9503041f * b\n\t\t\t};\n\t\t}\n\n\t\t/// <summary>\n\t\t/// XYZ to L* a* b* color space with D65 whitepoint tristimulus values\n\t\t/// </summary>\n\t\tstatic inline Lab XYZToLab(float X, float Y, float Z)\n\t\t{\n\t\t\tconst auto f = [](float t) {\n\t\t\t\treturn (t > 0.008856f) ? cbrtf(t) : (7.787037f * t + 0.137931f);\n\t\t\t};\n\n\t\t\t// D65 Tristimulus Values - D50: [0.96422, 1, 0.82521]\n\t\t\tconst auto fx = f(X / 0.95047f);\n\t\t\tconst auto fy = f(Y / 1.0f);\n\t\t\tconst auto fz = f(Z / 1.08883f);\n\n\t\t\treturn {\n\t\t\t\t116.0f * fy - 16.0f,\n\t\t\t\t500.0f * (fx - fy),\n\t\t\t\t200.0f * (fy - fz)\n\t\t\t};\n\t\t}\t\n\n\t\t/// <summary>\n\t\t/// L* a* b* Euclidean Distance\n\t\t/// Takes into account chromatic spearation, not just Lightness.\n\t\t/// All input parameters are linear and must be uncompressed.\n\t\t/// Source: Used by Phansalkar\n\t\t/// </summary>\n\t\tstatic inline float LABDist(float red, float green, float blue)\n\t\t{\n\t\t\tconst auto [X, Y, Z] = RGBToXYZ(red, green, blue);\n\t\t\tconst auto [L, a, b] = XYZToLab(X, Y, Z);\n\n\t\t\treturn sqrtf(L * L + a * a + b * b);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Convert an RGB/RGBA buffer to 8-bit grayscale.\n\t\t/// </summary>\n\t\tstatic void ToGrayscale(\n\t\t\tPixel8* output,\n\t\t\tconst uint8_t* input,\n\t\t\tint width, int height, int channels,\n\t\t\tGrayscaleAlgorithms algorithm = GrayscaleAlgorithms::MEAN)\n\t\t{\n\t\t\tconst int size = width * height;\n\n\t\t\tswitch (algorithm)\n\t\t\t{\n\t\t\t\tcase GrayscaleAlgorithms::QT:\n\t\t\t\t\tGrayscaleConverter<Qt<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::BT601:\n\t\t\t\t\tGrayscaleConverter<BT601<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::BT709:\n\t\t\t\t\tGrayscaleConverter<BT709<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::BT2100:\n\t\t\t\t\tGrayscaleConverter<BT2100<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::VALUE:\n\t\t\t\t\tGrayscaleConverter<Value<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::LUSTER:\n\t\t\t\t\tGrayscaleConverter<Luster<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::MINAVG:\n\t\t\t\t\tGrayscaleConverter<MinAvg<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Linear Algorithms - Assumes we are working in a compressed sRGB colorspace\n\t\t\t\tcase GrayscaleAlgorithms::LIGHTNESS:\n\t\t\t\t\tGrayscaleConverterLightness(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t\tcase GrayscaleAlgorithms::LABDIST:\n\t\t\t\t\tGrayscaleConverterLABDist(output, input, size, channels);\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Default - The Mean algorithm is safe, efficient, and effective\n\t\t\t\tdefault:\n\t\t\t\t\tGrayscaleConverter<Mean<Pixel8>>(output, input, size, channels);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\tprivate:\n\n\t\tstatic inline std::optional<std::array<float, 256>> m_lut;\n\n\t\t/// <summary>\n\t\t/// An optimized grayscale conversion loop where all algs are inlined\n\t\t/// </summary>\n\t\ttemplate<auto Algorithm>\n\t\tstatic void GrayscaleConverter(\n\t\t\tPixel8* output,\n\t\t\tconst uint8_t* input,\n\t\t\tint size,\n\t\t\tint channels)\n\t\t{\n\t\t\tfor (int i = 0, offset = 0; i < size; ++i, offset += channels)\n\t\t\t{\n\t\t\t\toutput[i] = Algorithm(input[offset], input[offset + 1], input[offset + 2]);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Lightness has a known range of 0-100, allowing a single-pass conversion.\n\t\t/// </summary>\n\t\tstatic void GrayscaleConverterLightness(\n\t\t\tPixel8* output,\n\t\t\tconst uint8_t* input,\n\t\t\tint size,\n\t\t\tint channels)\n\t\t{\n\t\t\tif (!m_lut) m_lut = LinearLUT();\n\t\t\tconst float scale = 255.0f / 100.0f;\n\n\t\t\tfor (int i = 0, offset = 0; i < size; ++i, offset += channels)\n\t\t\t{\n\t\t\t\toutput[i] = static_cast<Pixel8>(\n\t\t\t\t\tLightness((*m_lut)[input[offset]], (*m_lut)[input[offset + 1]], (*m_lut)[input[offset + 2]]) * scale);\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// LABDist has an unknown range requiring two passes: compute values, then normalize.\n\t\t/// </summary>\n\t\tstatic void GrayscaleConverterLABDist(\n\t\t\tPixel8* output,\n\t\t\tconst uint8_t* input,\n\t\t\tint size,\n\t\t\tint channels)\n\t\t{\n\t\t\tif (!m_lut) m_lut = LinearLUT();\n\n\t\t\tstd::vector<float> values(size);\n\n\t\t\tfor (int i = 0, offset = 0; i < size; ++i, offset += channels)\n\t\t\t{\n\t\t\t\tvalues[i] = LABDist((*m_lut)[input[offset]], (*m_lut)[input[offset + 1]], (*m_lut)[input[offset + 2]]);\n\t\t\t}\n\n\t\t\tauto [mn, mx] = std::minmax_element(values.data(), values.data() + size);\n\t\t\tconst float min = *mn;\n\t\t\tconst float scale = 255.0f / std::max(*mx - *mn, 1.0f);\n\n\t\t\tfor (int i = 0; i < size; ++i)\n\t\t\t{\n\t\t\t\toutput[i] = static_cast<Pixel8>((values[i] - min) * scale);\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n#endif // GRAYSCALE_HPP\n"
  },
  {
    "path": "Doxa/GridCalc.hpp",
    "content": "﻿// Δoxa Binarization Framework\n// License: CC0 2025, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef GRIDCALC_HPP\n#define GRIDCALC_HPP\n\n#include \"Image.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// A Grid based calculation algorithm designed originally for Sauvola and the original AdOtsu.\n\t/// It calculates a limited number of thresholds in a grid pattern throughout the image and then uses those\n\t/// values to interpolate the thresholds of the remaining pixels.\n\t/// \n\t/// By setting the Distance parameter to \"windowSize / 2\", you get overlapping windows as called for by\n\t/// the AdOtsu paper.  If you set the Distance to windowSize, you get no overlap, like what is written about\n\t/// by Feng.\n\t/// \n\t/// Note: While statistic based algorithms have the luxury of leveraging optimizations like Chan or Integral\n\t/// Images, function based algorithms like AdOtsu do not.  This is intended for un-optimized algorithms only!\n\t/// This algorithm is not a free lunch.  It is semi-expensive to run and it only *estimates* thresholds.\n\t/// </summary>\n\t/// <remarks>\"A multi-scale framework for adaptive binarization of degraded document images\", 2010.</remarks>\n\tclass GridCalc\n\t{\n\tpublic:\n\n\t\ttemplate<typename Algorithm>\n\t\tvoid Process(Image& binaryImageOut, const Image& grayScaleImageIn, const int windowSize, const int dist, Algorithm algorithm)\n\t\t{\n\t\t\t// Calculate thresholds at specific intervals throughout the image\n\t\t\tIterate(grayScaleImageIn, windowSize, dist, [&](const Region& window, const int& position) \n\t\t\t{\n\t\t\t\tbinaryImageOut.data[position] = algorithm(window, position);\n\t\t\t});\n\n\t\t\t// Estimate the remaining thresholds using Bilinear Interpolation\n\t\t\tInterpolate(binaryImageOut, dist, [&](const int& position, const int& threshold)\n\t\t\t{\n\t\t\t\tbinaryImageOut.data[position] = threshold;\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Iterates the image, calculating the corners of the window.\n\t\t/// Window Size and how far windows are apart from each other are somewhat independent.\n\t\t/// Distances between 2 and Window Size are possible.\n\t\t/// </summary>\n\t\ttemplate<typename Processor>\n\t\tstatic void Iterate(const Image& imageIn, const int windowSize, const int dist, Processor processor)\n\t\t{\n\t\t\tconst int HALF_WINDOW = windowSize / 2; // Note: Compiler rounding -  3 / 2 = 1\n\n\t\t\tconst int imageWidthSub = imageIn.width - 1;\n\t\t\tconst int imageHeightSub = imageIn.height - 1;\n\n\t\t\tconst int xCount = (std::ceil((float)(imageWidthSub) / dist) + 1) * dist;\n\t\t\tconst int yCount = (std::ceil((float)(imageHeightSub) / dist) + 1) * dist;\n\n\t\t\tRegion window;\n\n\t\t\tfor (int y = 0; y < yCount; y += dist)\n\t\t\t{\n\t\t\t\tconst int yCoord = std::min(y, imageHeightSub);\n\t\t\t\tconst int rowIdx = imageIn.width * yCoord;\n\n\t\t\t\twindow.upperLeft.y = (std::max)(0, yCoord - HALF_WINDOW);\n\t\t\t\twindow.bottomRight.y = (std::min)(imageHeightSub, yCoord + HALF_WINDOW);\n\n\t\t\t\tfor (int x = 0; x < xCount; x += dist)\n\t\t\t\t{\n\t\t\t\t\tconst int xCoord = std::min(x, imageWidthSub);\n\t\t\t\t\tconst int idx = rowIdx + xCoord;\n\n\t\t\t\t\twindow.upperLeft.x = (std::max)(0, xCoord - HALF_WINDOW);\n\t\t\t\t\twindow.bottomRight.x = (std::min)(imageWidthSub, xCoord + HALF_WINDOW);\n\n\t\t\t\t\tprocessor(window, idx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Interpolates an image that has already been Iterated.\n\t\t/// This algorithm attempts to iterate the image in a memory efficient way.\n\t\t/// It is very... verbose, but it is well optimized.\n\t\t/// </summary>\n\t\ttemplate <typename Processor>\n\t\tstatic void Interpolate(const Image& imageIn, const int dist, Processor processor)\n\t\t{\n\t\t\tconst int regularColCount = (imageIn.width - 1) / dist;\n\t\t\tconst int regularRowCount = (imageIn.height - 1) / dist;\n\t\t\tconst int remainingX = (imageIn.width - regularColCount * dist) - 1;\n\t\t\tconst int remainingY = (imageIn.height - regularRowCount * dist) - 1;\n\n\t\t\t// An optimized algorithm for rows that pre-calculated values in them\n\t\t\tauto processRowOptimized = [&imageIn](int& idx, const int colCount, const int dist, const int remainingDist, Processor processor)\n\t\t\t{\n\t\t\t\t// Seed our Left-most value\n\t\t\t\tPixel8 q00Val = imageIn.data[idx];\n\n\t\t\t\t// Iterate through all standard distance cells\n\t\t\t\tfor (int colIdx = 0; colIdx <= colCount; ++colIdx)\n\t\t\t\t{\n\t\t\t\t\t// Make sure we stay within the bounds of the row\n\t\t\t\t\tconst int interval = (colIdx != colCount) ? dist : remainingDist;\n\n\t\t\t\t\t// Set our Right-most value\n\t\t\t\t\tconst Pixel8 q01Val = imageIn.data[idx + interval];\n\n\t\t\t\t\tidx++; // Skip - Already processed\n\n\t\t\t\t\t// Process standard spaced nodes\n\t\t\t\t\tfor (int x = 1; x < interval; ++x, ++idx)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Pre-calculated for optimization\n\t\t\t\t\t\tconst float xDivInt = (float)x / interval;\n\n\t\t\t\t\t\tconst Pixel8 threshold =\n\t\t\t\t\t\t\t0.5f +\n\t\t\t\t\t\t\t(1.0f - xDivInt) * q00Val +\n\t\t\t\t\t\t\txDivInt * q01Val;\n\n\t\t\t\t\t\tprocessor(idx, threshold);\n\t\t\t\t\t}\n\n\t\t\t\t\t// What was once our Right-most value, is now our Left-most\n\t\t\t\t\tq00Val = q01Val;\n\t\t\t\t}\n\n\t\t\t\tif (remainingDist > 0)\n\t\t\t\t{\n\t\t\t\t\tidx++; // Skip - Processed\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Process all of the rows for a block of rows\n\t\t\tauto processRows = [&imageIn, &processRowOptimized](int& idx, const int rowGap, const int rowCount, const int colCount, const int dist, const int remainingDist, Processor processor)\n\t\t\t{\n\t\t\t\tconst int yIdx00 = idx;\n\t\t\t\tconst int yIdx10 = yIdx00 + rowGap;\n\n\t\t\t\t// Process first row\n\t\t\t\tprocessRowOptimized(idx, colCount, dist, remainingDist, processor);\n\n\t\t\t\t// Iterate through every row\n\t\t\t\tfor (int rowIdx = 1; rowIdx < rowCount; ++rowIdx)\n\t\t\t\t{\n\t\t\t\t\t// Seed our Left-most values\n\t\t\t\t\tPixel8 q00Val = imageIn.data[yIdx00];\n\t\t\t\t\tPixel8 q10Val = imageIn.data[yIdx10];\n\n\t\t\t\t\tint yIdx01 = yIdx00;\n\t\t\t\t\tint yIdx11 = yIdx10;\n\n\t\t\t\t\t// Pre-calculated for optimization\n\t\t\t\t\tconst float rowIdxDivRowCount = (float)rowIdx / rowCount;\n\n\t\t\t\t\t// Iterate through all standard distance cells\n\t\t\t\t\tfor (int colIdx = 0; colIdx <= colCount; ++colIdx)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Make sure we stay within the bounds of the row\n\t\t\t\t\t\tconst int interval = (colIdx != colCount) ? dist : remainingDist;\n\t\t\t\t\t\tyIdx01 += interval;\n\t\t\t\t\t\tyIdx11 += interval;\n\n\t\t\t\t\t\t// Set our Right-most values\n\t\t\t\t\t\tconst Pixel8 q01Val = imageIn.data[yIdx01];\n\t\t\t\t\t\tconst Pixel8 q11Val = imageIn.data[yIdx11];\n\n\t\t\t\t\t\t// Column optimized equation\n\t\t\t\t\t\tconst Pixel8 threshold =\n\t\t\t\t\t\t\t0.5f +\n\t\t\t\t\t\t\t(1.0 - rowIdxDivRowCount) * q00Val +\n\t\t\t\t\t\t\trowIdxDivRowCount * q10Val;\n\t\t\t\t\t\tprocessor(idx, threshold);\n\n\t\t\t\t\t\tidx++;\n\n\t\t\t\t\t\t// Process standard spaced nodes\n\t\t\t\t\t\tfor (int x = 1; x < interval; ++x, ++idx)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Pre-calculated for optimization\n\t\t\t\t\t\t\tconst float xDivInt = (float)x / interval;\n\n\t\t\t\t\t\t\tconst float top =\n\t\t\t\t\t\t\t\t(1.0f - xDivInt) * q00Val +\n\t\t\t\t\t\t\t\txDivInt * q01Val;\n\n\t\t\t\t\t\t\tconst float bottom =\n\t\t\t\t\t\t\t\t(1.0f - xDivInt) * q10Val +\n\t\t\t\t\t\t\t\txDivInt * q11Val;\n\n\t\t\t\t\t\t\tconst Pixel8 threshold =\n\t\t\t\t\t\t\t\t0.5f +\n\t\t\t\t\t\t\t\t(1.0f - rowIdxDivRowCount) * top +\n\t\t\t\t\t\t\t\trowIdxDivRowCount * bottom;\n\n\t\t\t\t\t\t\tprocessor(idx, threshold);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// What was once our Right-most values, is now our Left-most\n\t\t\t\t\t\tq00Val = q01Val;\n\t\t\t\t\t\tq10Val = q11Val;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Column optimized equation\n\t\t\t\t\tif (remainingDist > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst Pixel8 threshold =\n\t\t\t\t\t\t\t0.5f +\n\t\t\t\t\t\t\t(1.0f - rowIdxDivRowCount) * q00Val +\n\t\t\t\t\t\t\trowIdxDivRowCount * q10Val;\n\n\t\t\t\t\t\tprocessor(idx, threshold);\n\n\t\t\t\t\t\tidx++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// The Interpolation Algorithm\n\t\t\tint idx = 0;\n\t\t\tconst int rowGap = dist * imageIn.width;\n\n\t\t\tfor (int y = 0; y < regularRowCount; ++y)\n\t\t\t{\n\t\t\t\tprocessRows(idx, rowGap, dist, regularColCount, dist, remainingX, processor);\n\t\t\t}\n\n\t\t\tif (remainingY)\n\t\t\t{\n\t\t\t\tprocessRows(idx, remainingY * imageIn.width, remainingY, regularColCount, dist, remainingX, processor);\n\t\t\t}\n\n\t\t\tprocessRowOptimized(idx, regularColCount, dist, remainingX, processor);\n\t\t}\n\t};\n}\n\n\n#endif //GRIDCALC_HPP\n"
  },
  {
    "path": "Doxa/ISauvola.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef ISAUVOLA_HPP\n#define ISAUVOLA_HPP\n\n#include <unordered_set>\n#include \"Sauvola.hpp\"\n#include \"ContrastImage.hpp\"\n//#include \"Morphology.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The ISauvola Algorithm: Zineb Hadjadj, Abdelkrimo Meziane, Yazid Cherfa, Mohamed Cheriet, Insaf Setitra\n\t/// \n\t/// This algorithm has been abstracted so that any binarization algorithm can leverage this technique.\n\t/// Example: Improved&lt;Sauvola&gt;::ToBinaryImage(...);\n\t/// </summary>\n\t/// <remarks>\"ISauvola: Improved Sauvola’s Algorithm for Document Image Binarization\", 2016.</remarks>\n\ttemplate<class BinarizationClass>\n\tclass Improved : public Algorithm<Improved<BinarizationClass>>\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Step 1 - Initialization Step\n\t\t\tImage highContrastImage(Improved::grayScaleImageIn.width, Improved::grayScaleImageIn.height);\n\t\t\tContrastImage::GenerateHighContrastImage(highContrastImage, Improved::grayScaleImageIn);\n\n\t\t\t// Step 1 b - Removing Open because it removes too much detail\n\t\t\t//Morphology::Open(highContrastImage, highContrastImage, 3);\n\n\t\t\t// Step 2 - Binarization Step\n\t\t\tImage binImage = BinarizationClass::ToBinaryImage(Improved::grayScaleImageIn, parameters);\n\n\t\t\t// Step 3 - Sequential Combination\n\t\t\tCombine(binaryImageOut, highContrastImage, binImage);\n\t\t}\n\n\tprotected:\n\t\t/// <summary>\n\t\t/// This algorithm leverages a high contrast image to find where the foreground might be.\n\t\t/// Once a foreground pixel is found, all connected pixels are associated with it as part of the\n\t\t/// final binary image.\n\t\t/// </summary>\n\t\t/// <param name=\"binaryImageOut\">Final image</param>\n\t\t/// <param name=\"highContrastImageIn\">A high contrast image of the grayscale image</param>\n\t\t/// <param name=\"binaryImageIn\">A high detail, but probably noisy, binary image</param>\n\t\tvoid Combine(Image& binaryImageOut, const Image& highContrastImageIn, const Image& binaryImageIn)\n\t\t{\n\t\t\t// Ensure that everything is white to start off with\n\t\t\tbinaryImageOut.Fill(Palette::White);\n\n\t\t\t// Iterate every pixel of our high contrast image\n\t\t\tfor (int idx = 0; idx < highContrastImageIn.size; ++idx)\n\t\t\t{\n\t\t\t\t// Detect a high contrast region that contains a foreground pixel\n\t\t\t\tif (Palette::White == highContrastImageIn.data[idx] &&\n\t\t\t\t\tPalette::Black == binaryImageIn.data[idx])\n\t\t\t\t{\n\t\t\t\t\t// If we haven't already analyzed this pixel's connections, analyze them\n\t\t\t\t\tif (Palette::White == binaryImageOut.data[idx])\n\t\t\t\t\t{\n\t\t\t\t\t\tSpider(binaryImageOut, binaryImageIn, idx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Spider is a fairly crafty algorithm that tracks down all connected foreground pixels given a \n\t\t/// starting point.  It does this non-recursively by searching a 3x3 area around the target pixel.\n\t\t/// \n\t\t/// This takes advantage of the fact that many Niblack based binarization algorithms create a\n\t\t/// small background buffer around the foreground that is free from noise.\n\t\t/// </summary>\n\t\t/// <param name=\"binaryImageOut\">Image containing the traced foreground.</param>\n\t\t/// <param name=\"binaryImageIn\">Image containing the foreground to trace.</param>\n\t\t/// <param name=\"startIdx\">A foreground pixel location to start the trace.</param>\n\t\tvoid Spider(Image& binaryImageOut, const Image& binaryImageIn, const int startIdx)\n\t\t{\n\t\t\tstd::unordered_set<int> pixelPositions = { startIdx };\n\n\t\t\t// Initialize our Start Index\n\t\t\tbinaryImageOut.data[startIdx] = Palette::Black;\n\n\t\t\t// If we find an attached cell that hasn't been analyzed, mark it and add it to our list\n\t\t\tauto processCell = [&](const int position)\n\t\t\t{\n\t\t\t\tif (Palette::Black == binaryImageIn.data[position] &&\n\t\t\t\t\tPalette::White == binaryImageOut.data[position])\n\t\t\t\t{\n\t\t\t\t\tbinaryImageOut.data[position] = Palette::Black;\n\t\t\t\t\tpixelPositions.insert(position);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Process a Row of our 3x3 window from Left to Right\n\t\t\tauto processRow = [&](int position, const bool checkLeft, const bool checkCenter, bool const checkRight) \n\t\t\t{\n\t\t\t\t// Start on the Left\n\t\t\t\tif (checkLeft)\n\t\t\t\t\tprocessCell(position);\n\n\t\t\t\t// Move to Center\n\t\t\t\t++position;\n\t\t\t\tif (checkCenter)\n\t\t\t\t\tprocessCell(position);\n\n\t\t\t\t// Move to Right\n\t\t\t\tif (checkRight)\n\t\t\t\t\tprocessCell(++position); // Note: Position is incremented\n\t\t\t};\n\n\t\t\t// Iterate through all of the black pixels, forming a 3x3 search window.\n\t\t\t// This loop may keep adding to that list when a black neighbor is found.\n\t\t\twhile (!pixelPositions.empty())\n\t\t\t{\n\t\t\t\t// Pop target position index\n\t\t\t\tconst int idx = *pixelPositions.begin();\n\t\t\t\tpixelPositions.erase(pixelPositions.begin());\n\n\t\t\t\t// Build Coordinates and detect if we are on the far left or right\n\t\t\t\tconst int top = idx - binaryImageIn.width;\n\t\t\t\tconst int bottom = idx + binaryImageIn.width;\n\t\t\t\tconst bool checkLeft = idx % binaryImageIn.width;\n\t\t\t\tconst bool checkRight = (idx + 1) % binaryImageIn.width;\n\n\t\t\t\t// Process Top Row\n\t\t\t\tif (top > 0)\n\t\t\t\t\tprocessRow(top - 1, checkLeft, true, checkRight);\n\n\t\t\t\t// Process Center Row\n\t\t\t\tprocessRow(idx - 1, checkLeft, false, checkRight);\n\n\t\t\t\t// Process Bottom Row\n\t\t\t\tif (bottom < binaryImageIn.size)\n\t\t\t\t\tprocessRow(bottom - 1, checkLeft, true, checkRight);\n\t\t\t}\n\t\t}\n\t};\n\n\t/// <summary>\n\t/// A convenience name for backwards compatibility with this library.\n\t/// </summary>\n\ttypedef Improved<Sauvola> ISauvola;\n}\n\n\n#endif //ISAUVOLA_HPP\n"
  },
  {
    "path": "Doxa/Image.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef IMAGE_HPP\n#define IMAGE_HPP\n\n#include <cstring>\n#include \"Types.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Image structure holds the 8-bit image data and meta data.\n\t/// This struct hides all memory management details and can be thought of as living on the stack.\n\t/// Due to C++ Move semantics and our Reference(...) method, deep copies can be avoided.\n\t/// </summary>\n\tstruct Image\n\t{\n\t\t// Default CTOR\n\t\tImage() {}\n\n\t\t// CTOR\n\t\tImage(int width, int height, const Pixel8* bits = nullptr)\n\t\t\t: width(width), \n\t\t\theight(height), \n\t\t\tsize(width*height)\n\t\t{\n\t\t\tdata = new Pixel8[size];\n\n\t\t\tif (bits != nullptr)  \n\t\t\t\tstd::memcpy(data, bits, size);\n\t\t}\n\n\t\t// DTOR\n\t\t// Note: https://en.wikipedia.org/wiki/Copy_elision\n\t\t~Image() \n\t\t{ \n\t\t\tif (!managedExternally) \n\t\t\t\tdelete[] data;\n\t\t}\n\n\t\t// Copy Constructor\n\t\tImage(const Image& image)\n\t\t\t: width(image.width), \n\t\t\theight(image.height), \n\t\t\tdepth(image.depth), \n\t\t\tmaxVal(image.maxVal), \n\t\t\ttupleType(image.tupleType), \n\t\t\tsize(image.size)\n\t\t{\n\t\t\tdata = new Pixel8[size];\n\t\t\tstd::memcpy(data, image.data, size);\n\t\t}\n\n\t\t// Move Constructor\n\t\tImage(Image&& image)\n\t\t\t: width(image.width),\n\t\t\theight(image.height),\n\t\t\tdepth(image.depth),\n\t\t\tmaxVal(image.maxVal),\n\t\t\ttupleType(image.tupleType),\n\t\t\tsize(image.size),\n\t\t\tdata(image.data),\n\t\t\tmanagedExternally(image.managedExternally)\n\t\t{\n\t\t\timage.managedExternally = true; // Now managed by the copy\n\t\t}\n\n\t\t// Copy Assignment Operator - This will always deep copy, even a reference.\n\t\tImage& operator=(const Image& that)\n\t\t{\n\t\t\tif (this != &that)\n\t\t\t{\n\t\t\t\tif (size != that.size)\n\t\t\t\t{\n\t\t\t\t\tdelete[] data;\n\n\t\t\t\t\t// Reset in case of a thrown exception allocating memory\n\t\t\t\t\tsize = 0;\n\t\t\t\t\tdata = nullptr;\n\n\t\t\t\t\t// Reallocate\n\t\t\t\t\tdata = new Pixel8[that.size];\n\t\t\t\t\tsize = that.size;\n\t\t\t\t}\n\n\t\t\t\twidth = that.width;\n\t\t\t\theight = that.height;\n\t\t\t\tmanagedExternally = false;\n\n\t\t\t\tstd::memcpy(data, that.data, size);\n\t\t\t}\n\n\t\t\treturn *this;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Generates a reference image of the current image object\n\t\t/// </summary>\n\t\tImage Reference() const\n\t\t{\n\t\t\treturn Reference(width, height, data);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Generates an image reference, typically from a 3rd party image buffer.\n\t\t/// Any change to the reference image will affect the original image buffer.\n\t\t/// The buffer must be an 8-bit grayscale or binary image.\n\t\t/// The buffer will not be freed when the reference Image destructs.\n\t\t/// </summary>\n\t\tstatic Image Reference(int width, int height, Pixel8* data)\n\t\t{\n\t\t\tImage referenceImage;\n\t\t\treferenceImage.width = width;\n\t\t\treferenceImage.height = height;\n\t\t\treferenceImage.size = width * height;\n\t\t\treferenceImage.data = data;\n\t\t\treferenceImage.managedExternally = true;\n\n\t\t\treturn referenceImage;\n\t\t}\n\n\t\tvoid Fill(const Pixel8 pixel)\n\t\t{\n\t\t\tmemset(data, pixel, size * sizeof(Pixel8));\n\t\t}\n\n\t\t// External Memory Management\n\t\tbool managedExternally = false;\n\n\t\t// PNM Values\n\t\tint width = 0;\n\t\tint height = 0;\n\t\tint size = 0;\n\t\tint depth = 1;\n\t\tint maxVal = 255;\n\t\tstd::string tupleType = TupleTypes::GRAYSCALE;\n\n\t\t// The raw image buffer containing all image pixels\n\t\tPixel8* data = nullptr;\n\n\t\tinline Pixel8& Pixel(int x, int y) { return data[(y * width) + x]; }\n\t\tinline Pixel8  Pixel(int x, int y) const { return data[(y * width) + x]; }\n\t\tinline Pixel8  Pixel(int x, int y, Pixel8 defaultValue) const { return (x < 0 || x >= width || y < 0 || y >= height) ? defaultValue : Pixel(x, y); }\n\t};\n}\n\n\n#endif // IMAGE_HPP\n"
  },
  {
    "path": "Doxa/IntegralImageMeanVarianceCalc.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef INTEGRALIMAGEMEANVARIANCECALC_HPP\n#define INTEGRALIMAGEMEANVARIANCECALC_HPP\n\n#include <vector>\n#include \"Image.hpp\"\n#include \"Region.hpp\"\n#include \"LocalWindow.hpp\"\n\n\nnamespace Doxa\n{\n\ttypedef std::vector<int64_t> IntegralImage;\n\n\t/// <summary>\n\t/// The Shafait Algorithm: Faisal Shafait, Daniel Keysers, Thomas M. Breuel\n\t/// An integral image based calculator for calculating Mean, Population Variance.\n\t/// \n\t/// Note: For extremely large images, this algorithm will fail.\n\t/// This algorithm has been replaced by Chan.  Chan is roughly 3x faster, consumes a fraction of the memory,\n\t/// and allows for large image processing.\n\t/// </summary>\n\t/// <remarks>\"Efficient Implementation of Local Adaptive Thresholding Techniques Using Integral Images\", 2008.</remarks>\n\tclass IntegralImageMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\ttemplate<typename Algorithm>\n\t\tvoid Process(Image& binaryImageOut, const Image& grayScaleImageIn, const int windowSize, Algorithm algorithm)\n\t\t{\n\t\t\tconst int imageWidth = grayScaleImageIn.width;\n\n\t\t\t// Initialize Integral Images\n\t\t\tIntegralImage integralImage(grayScaleImageIn.size), integralSqrImage(grayScaleImageIn.size);\n\t\t\tBuildIntegralImages(integralImage, integralSqrImage, grayScaleImageIn);\n\t\t\t//BuildIntegralImagesLowMem(integralImage, integralSqrImage, grayScaleImageIn); // This can significantly reduce the memory used, but may be slower\n\n\t\t\t// Run our binarization algorithm\n\t\t\tdouble mean, variance;\n\t\t\tLocalWindow::Process(binaryImageOut, grayScaleImageIn, windowSize, [&](const Region& window, const int& index) {\n\t\t\t\tCalculateMeanVariance(mean, variance, imageWidth, integralImage, integralSqrImage, window);\n\n\t\t\t\treturn algorithm(mean, variance, index);\n\t\t\t});\n\t\t}\n\n\t\ttemplate<typename Processor>\n\t\tvoid Iterate(const Image& grayScaleImageIn, const int windowSize, Processor processor)\n\t\t{\n\t\t\tconst int imageWidth = grayScaleImageIn.width;\n\n\t\t\t// Initialize Integral Images\n\t\t\tIntegralImage integralImage(grayScaleImageIn.size), integralSqrImage(grayScaleImageIn.size);\n\t\t\tBuildIntegralImages(integralImage, integralSqrImage, grayScaleImageIn);\n\t\t\t//BuildIntegralImagesLowMem(integralImage, integralSqrImage, grayScaleImageIn); // This can significantly reduce the memory used, but may be slower\n\n\t\t\t// Run our binarization algorithm\n\t\t\tdouble mean, variance;\n\t\t\tLocalWindow::Iterate(grayScaleImageIn, windowSize, [&](const Region& window, const int& index) {\n\t\t\t\tCalculateMeanVariance(mean, variance, imageWidth, integralImage, integralSqrImage, window);\n\n\t\t\t\treturn processor(mean, variance, index);\n\t\t\t});\n\t\t}\n\n\t\tinline void CalculateMeanVariance(double& mean, double& variance, const int imageWidth, const IntegralImage& integralImage, const IntegralImage& integralSqrImage, const Region& window) const\n\t\t{\n\t\t\t// Note: This data type has a large impact on performance.\n\t\t\tdouble diff, sqdiff;\n\t\t\tCalculateDiffs(diff, sqdiff, imageWidth, integralImage, integralSqrImage, window);\n\n\t\t\t// Get the Mean and Variance using our Shafait inspired algorithm\n\t\t\tconst int area = window.Area();\n\t\t\tmean = diff / area;\n\t\t\t\n\t\t\t// Sample Variance\n\t\t\t//variance = (sqdiff - diff*diff / area) / (area - 1);\n\n\t\t\t// Population Variance\n\t\t\tvariance = (sqdiff / area) - (mean * mean);\n\t\t}\n\n\t\tinline void CalculateDiffs(double& diff, double& sqdiff, const int imageWidth, const IntegralImage& integralImage, const IntegralImage& integralSqrImage, const Region& window) const\n\t\t{\n\t\t\t// Optimization Note: With MSVC, simplifying this to match MeanCalculator::CalculateDiffs incurred a small performance hit.\n\n\t\t\tconst int bottomRight = (window.bottomRight.y * imageWidth) + window.bottomRight.x;\n\n\t\t\tif (window.upperLeft.x)\n\t\t\t{\n\t\t\t\tconst int bottomLeft = (window.bottomRight.y * imageWidth) + (window.upperLeft.x - 1);\n\n\t\t\t\tif (window.upperLeft.y)\n\t\t\t\t{\n\t\t\t\t\tconst int upperRight = ((window.upperLeft.y - 1) * imageWidth) + window.bottomRight.x;\n\t\t\t\t\tconst int upperLeft = ((window.upperLeft.y - 1) * imageWidth) + (window.upperLeft.x - 1);\n\n\t\t\t\t\tdiff = (integralImage[bottomRight] + integralImage[upperLeft]) - (integralImage[upperRight] + integralImage[bottomLeft]);\n\t\t\t\t\tsqdiff = (integralSqrImage[bottomRight] + integralSqrImage[upperLeft]) - (integralSqrImage[upperRight] + integralSqrImage[bottomLeft]);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdiff = integralImage[bottomRight] - integralImage[bottomLeft];\n\t\t\t\t\tsqdiff = integralSqrImage[bottomRight] - integralSqrImage[bottomLeft];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (window.upperLeft.y)\n\t\t\t\t{\n\t\t\t\t\tconst int upperRight = ((window.upperLeft.y - 1) * imageWidth) + window.bottomRight.x;\n\n\t\t\t\t\tdiff = integralImage[bottomRight] - integralImage[upperRight];\n\t\t\t\t\tsqdiff = integralSqrImage[bottomRight] - integralSqrImage[upperRight];\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdiff = integralImage[bottomRight];\n\t\t\t\t\tsqdiff = integralSqrImage[bottomRight];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid BuildIntegralImages(IntegralImage& integralImage, IntegralImage& integralSqrImage, const Image& grayScaleImage)\n\t\t{\n\t\t\t// This algorithm uses two temporary images.  See BuildIntegralImagesLowMem for an alternative.\n\t\t\tIntegralImage rowSumImage(grayScaleImage.size);\n\t\t\tIntegralImage rowSumSqrImage(grayScaleImage.size);\n\t\t\tint rowIdx = 0;\n\n\t\t\tfor (int y = 0; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\trowIdx = (y * grayScaleImage.width);\n\t\t\t\trowSumImage[rowIdx] = grayScaleImage.data[rowIdx];\n\t\t\t\trowSumSqrImage[rowIdx] = grayScaleImage.data[rowIdx] * grayScaleImage.data[rowIdx];\n\t\t\t}\n\n\t\t\tfor (int y = 0; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 1; x < grayScaleImage.width; ++x)\n\t\t\t\t{\n\t\t\t\t\trowIdx = (y * grayScaleImage.width) + x;\n\t\t\t\t\trowSumImage[rowIdx] = rowSumImage[rowIdx - 1] + grayScaleImage.data[rowIdx];\n\t\t\t\t\trowSumSqrImage[rowIdx] = rowSumSqrImage[rowIdx - 1] + grayScaleImage.data[rowIdx] * grayScaleImage.data[rowIdx];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int x = 0; x < grayScaleImage.width; ++x)\n\t\t\t{\n\t\t\t\tintegralImage[x] = rowSumImage[x];\n\t\t\t\tintegralSqrImage[x] = rowSumSqrImage[x];\n\t\t\t}\n\n\t\t\tfor (int y = 1; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 0; x < grayScaleImage.width; ++x)\n\t\t\t\t{\n\t\t\t\t\trowIdx = (y * grayScaleImage.width) + x;\n\t\t\t\t\tintegralImage[rowIdx] = integralImage[rowIdx - grayScaleImage.width] + rowSumImage[rowIdx];\n\t\t\t\t\tintegralSqrImage[rowIdx] = integralSqrImage[rowIdx - grayScaleImage.width] + rowSumSqrImage[rowIdx];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// This is a \"low memory\" version of BuildIntegralImages(...).\n\t\t/// It achieves this by removing the need for two temporary integral images.\n\t\t/// Warning: The speed performance compared to the reference may be slower depending on image size.\n\t\t/// </summary>\n\t\tvoid BuildIntegralImagesLowMem(IntegralImage& integralImage, IntegralImage& integralSqrImage, const Image& grayScaleImage)\n\t\t{\n\t\t\tint row;\n\t\t\tint cell;\n\n\t\t\tintegralImage[0] = grayScaleImage.data[0];\n\t\t\tintegralSqrImage[0] = integralImage[0] * integralImage[0];\n\n\t\t\tfor (int y = 1; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\trow = (y * grayScaleImage.width);\n\t\t\t\tintegralImage[row] = integralImage[row - grayScaleImage.width] + grayScaleImage.data[row];\n\t\t\t\tintegralSqrImage[row] = grayScaleImage.data[row] * grayScaleImage.data[row] + integralSqrImage[row - grayScaleImage.width];\n\t\t\t}\n\n\t\t\tfor (int x = 1; x < grayScaleImage.width; ++x)\n\t\t\t{\n\t\t\t\tintegralImage[x] = integralImage[x - 1] + grayScaleImage.data[x];\n\t\t\t\tintegralSqrImage[x] = grayScaleImage.data[x] * grayScaleImage.data[x] + integralSqrImage[x - 1];\n\t\t\t}\n\n\t\t\tfor (int y = 1; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\trow = (y * grayScaleImage.width);\n\t\t\t\tint rowSum = grayScaleImage.data[row];\n\n\t\t\t\tfor (int x = 1; x < grayScaleImage.width; ++x)\n\t\t\t\t{\n\t\t\t\t\tcell = row + x;\n\t\t\t\t\trowSum += grayScaleImage.data[cell];\n\n\t\t\t\t\tintegralImage[cell] = integralImage[cell - grayScaleImage.width] + rowSum;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (int x = 1; x < grayScaleImage.width; ++x)\n\t\t\t{\n\t\t\t\tint colSqrSum = grayScaleImage.data[x] * grayScaleImage.data[x];\n\n\t\t\t\tfor (int y = 1; y < grayScaleImage.height; ++y) {\n\t\t\t\t\trow = (y * grayScaleImage.width) + x;\n\n\t\t\t\t\tcolSqrSum += grayScaleImage.data[row] * grayScaleImage.data[row];\n\n\t\t\t\t\tintegralSqrImage[row] = colSqrSum + integralSqrImage[row - 1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n#endif //INTEGRALIMAGEMEANVARIANCECALC_HPP\n"
  },
  {
    "path": "Doxa/LocalWindow.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef LOCALWINDOW_HPP\n#define LOCALWINDOW_HPP\n\n#include <algorithm>\n#include \"Image.hpp\"\n#include \"Palette.hpp\"\n#include \"Region.hpp\"\n\n\nnamespace Doxa\n{\n\tclass LocalWindow\n\t{\n\tpublic:\n\n\t\t/// <summary>\n\t\t/// Converts a Gray Scale image into a Binary image given a specific algorithm.\n\t\t/// The algorithm should return a threshold under which a gray pixel will become black and\n\t\t/// over which it will become white.\n\t\t/// </summary>\n\t\ttemplate<typename WindowCalculator>\n\t\tstatic void Process(Image& binaryImageOut, const Image& grayScaleImageIn, const int windowSize, WindowCalculator calculator)\n\t\t{\n\t\t\tIterate(grayScaleImageIn, windowSize, [&](const Region& window, const int& position) {\n\t\t\t\tbinaryImageOut.data[position] =\n\t\t\t\t\tgrayScaleImageIn.data[position] <= calculator(window, position) ?\n\t\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t});\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Iterate an Image, providing the current position and a window.\n\t\t/// A Window is a region of the image surrounding a specific pixel that needs to be processed.\n\t\t/// </summary>\n\t\ttemplate<typename Processor>\n\t\tstatic void Iterate(const Image& imageIn, const int windowSize, Processor processor)\n\t\t{\n\t\t\tconst int HALF_WINDOW = windowSize / 2;\n\t\t\tRegion window;\n\n\t\t\tfor (int y = 0, ind = 0; y < imageIn.height; ++y)\n\t\t\t{\n\t\t\t\t// Set Y Window Coordinates\n\t\t\t\twindow.upperLeft.y = (std::max)(0, y - HALF_WINDOW);\n\t\t\t\twindow.bottomRight.y = (std::min)(imageIn.height - 1, y + HALF_WINDOW);\n\n\t\t\t\tfor (int x = 0; x < imageIn.width; ++x, ++ind)\n\t\t\t\t{\n\t\t\t\t\t// Set X Window Coordinates\n\t\t\t\t\twindow.upperLeft.x = (std::max)(0, x - HALF_WINDOW);\n\t\t\t\t\twindow.bottomRight.x = (std::min)(imageIn.width - 1, x + HALF_WINDOW);\n\n\t\t\t\t\tprocessor(window, ind);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Iterate a Window, providing the current position within the window.\n\t\t/// </summary>\n\t\ttemplate<typename Processor>\n\t\tstatic void Iterate(const int width, const Region& window, Processor processor)\n\t\t{\n\t\t\tfor (int y = window.upperLeft.y; y <= window.bottomRight.y; ++y)\n\t\t\t{\n\t\t\t\tconst int row = y * width;\n\n\t\t\t\tfor (int x = window.upperLeft.x; x <= window.bottomRight.x; ++x)\n\t\t\t\t{\n\t\t\t\t\tprocessor(row + x);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n#endif //LOCALWINDOW_HPP\n"
  },
  {
    "path": "Doxa/Morphology.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef MORPHOLOGY_HPP\n#define MORPHOLOGY_HPP\n\n#include <set>\n#include \"Image.hpp\"\n#include \"LocalWindow.hpp\"\n\n\nnamespace Doxa\n{\n\tclass Morphology\n\t{\n\tpublic:\n\t\t/// <summary>\n\t\t/// Open is simply Erode followed by Dilate.\n\t\t/// This can help reduce background noise.\n\t\t/// </summary>\n\t\tstatic void Open(Image& morphedImage, const Image& grayScaleImage, const int windowSize = 3)\n\t\t{\n\t\t\tImage erodedImage(grayScaleImage.width, grayScaleImage.height);\n\t\t\tErode(erodedImage, grayScaleImage, windowSize);\n\t\t\tDilate(morphedImage, erodedImage, windowSize);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Close is simply Dilate followed by Erode.\n\t\t/// This can help fill holes in the foreground.\n\t\t/// </summary>\n\t\tstatic void Close(Image& morphedImage, const Image& grayScaleImage, const int windowSize = 3)\n\t\t{\n\t\t\tImage dilatedImage(grayScaleImage.width, grayScaleImage.height);\n\t\t\tDilate(dilatedImage, grayScaleImage, windowSize);\n\t\t\tErode(morphedImage, dilatedImage, windowSize);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Iterates through the gray scale image, recording the minimum value within the window.\n\t\t/// </summary>\n\t\tstatic void Erode(Image& morphedImage, const Image& grayScaleImage, const int windowSize = 3)\n\t\t{\n\t\t\t// For small window sizes, manually analyzing the window is faster.\n\t\t\tif (windowSize < 17)\n\t\t\t{\n\t\t\t\tIterativelyErode(morphedImage, grayScaleImage, windowSize);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMorph(morphedImage, grayScaleImage, windowSize, [](const std::multiset<Pixel8>& set) {\n\t\t\t\t\treturn *set.begin(); // Min Value\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Iterates through the grayscale image, recording the maximum value within the window.\n\t\t/// </summary>\n\t\tstatic void Dilate(Image& morphedImage, const Image& grayScaleImage, const int windowSize = 3)\n\t\t{\n\t\t\t// For small window sizes, manually analyzing the window is faster.\n\t\t\tif (windowSize < 17)\n\t\t\t{\n\t\t\t\tIterativelyDilate(morphedImage, grayScaleImage, windowSize);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMorph(morphedImage, grayScaleImage, windowSize, [](const std::multiset<Pixel8>& set) {\n\t\t\t\t\treturn *std::prev(set.end()); // Max Value\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\tprotected:\n\t\t/// <summary>\n\t\t/// Author: Brandon M. Petty\n\t\t/// Date: Jan 19, 2019\n\t\t/// \n\t\t/// This routine allows one to Erode or Dilate a grayscale image efficiently for medium to large window sizes.\n\t\t/// Many binarization algorithms require the min/max value within a local window.  Iterating through each window\n\t\t/// can be extremely slow with larger window sizes.  The goal of this algorithm is to greatly improve the\n\t\t/// performance characteristics for varying window sizes.\n\t\t/// \n\t\t/// This algorithm was born out of necessity because I could not, for the life of me, understand vHGW.\n\t\t/// The vHGW algorithm, as referenced in many papers, can apparently do this very efficiently.\n\t\t/// But like most papers I've read, something supposedly so simple is completely undermined by an overly complex\n\t\t/// description with absolutely no example of how it works with real data.\n\t\t/// \n\t\t/// Algorithm:\n\t\t/// 1. For each row, iterate pixel by pixel to the end of the row, creating a 1-D horizontal window around each pixel.\n\t\t/// 2. For each window, take the min value (for Erode), or max value (for Dilate), and store it in a temp image\n\t\t///    at the same coordinates as the targeted pixel.\n\t\t/// 3. Using the temp image, repeat steps 1 and 2 except now you will be going down column by column using a 1-D\n\t\t///    vertical window to capture min / max values for your final morphed image.\n\t\t/// \n\t\t/// The algorithm's performance hinges on its ability to find the min/max of a given window.  By using an ordered\n\t\t/// set, when sliding the window over by one pixel, we simply need to add the next pixel to the set and remove\n\t\t/// the single pixel no longer in the window from the set.  Because the set is ordered, the first item in the\n\t\t/// set is the min value, and the last item is the max value.  In the end, it comes down to how fast you can add\n\t\t/// and remove items from an ordered set.\n\t\t/// \n\t\t/// Anecdotal Evidence:\n\t\t/// Base on an AMD Phenom II 1090T Processor running Windows 10, compiled with MSBuild using /O2 /Ot\n\t\t/// The follow are: Window Size, Speed of Wan's algorithm using Morph, Speed of Wan simply searching each window.\n\t\t/// 3   | 0.091808 | 0.028856\t\t* Using the Morph implementation is slower for small windows\n\t\t/// 17  | 0.127909 | 0.134349\t\t* This is the window size which breaks in favor of Morph\n\t\t/// 25  | 0.130928 | 0.238442\t\t* 1.8x faster\n\t\t/// 75  | 0.143578 | 1.652775\t\t* 11.5x faster\n\t\t/// 125 | 0.146470 | 4.218453\t\t* 28.8x faster\n\t\t/// 255 | 0.149844 | 15.32876\t\t* 102.3x faster\n\t\t/// </summary>\n\t\t/// <remarks>If this is a known algorithm, please provide a source and I will attribute it here.</remarks>\n\t\ttemplate<typename MorphRoutine>\n\t\tstatic inline void Morph(Image& morphedImage, const Image& grayScaleImage, const int& windowSize, MorphRoutine routine)\n\t\t{\n\t\t\tconst int windowHalfWidth = ((windowSize - 1) / 2);\n\t\t\tconst int windowHalfWidthPlusOne = windowHalfWidth + 1;\n\n\t\t\t// Store the minimum values, by row\n\t\t\tImage tempImage(grayScaleImage.width, grayScaleImage.height);\n\n\t\t\t// For each row (y) in grayScaleImage, calculate the min/max value within the 1-D window for that row\n\t\t\tfor (int y = 0; y < grayScaleImage.height; ++y)\n\t\t\t{\n\t\t\t\t// Instead of paying the cost of calling Pixel(x,y), roll our own to save a few cpu cycles\n\t\t\t\tconst int row = y * grayScaleImage.width;\n\n\t\t\t\t// Set is used because it automatically orders everything we add into it\n\t\t\t\tstd::multiset<Pixel8> set;\n\n\t\t\t\t// Initialize set with first half of our 1-D window\n\t\t\t\t// This sets pixel 0,0 with the max of the half window.\n\t\t\t\tfor (int w = 0; w <= windowHalfWidth; ++w)\n\t\t\t\t{\n\t\t\t\t\tset.insert(grayScaleImage.data[row + w]);\n\t\t\t\t}\n\t\t\t\ttempImage.data[row] = routine(set);\n\n\t\t\t\t// Fill it up until we hit the full width of the 1-D window\n\t\t\t\t// This allows us to set the next few pixels as we iterate to that point\n\t\t\t\tint x = 1;\n\t\t\t\tfor (; x <= windowHalfWidth; ++x)\n\t\t\t\t{\n\t\t\t\t\tset.insert(grayScaleImage.data[row + x + windowHalfWidth]);\n\t\t\t\t\ttempImage.data[row + x] = routine(set);\n\t\t\t\t}\n\n\t\t\t\t// Now that we have a full window set, simply add the next item and remove the last time.\n\t\t\t\t// This will take use almost to the end of the row, finding the min/max value for that point within a 1-D window\n\t\t\t\tfor (; x < grayScaleImage.width - windowHalfWidth; ++x)\n\t\t\t\t{\n\t\t\t\t\t// Optimization: Calculate position since we are calling this 3 times\n\t\t\t\t\tconst int position = row + x;\n\n\t\t\t\t\t//set.erase(grayScaleImage.data[position - windowHalfWidthPlusOne]);\n\t\t\t\t\tconst std::multiset<Pixel8>::iterator hit(set.find(grayScaleImage.data[position - windowHalfWidthPlusOne]));\n\t\t\t\t\tif (hit != set.end()) set.erase(hit);\n\n\t\t\t\t\tset.insert(grayScaleImage.data[position + windowHalfWidth]);\n\t\t\t\t\ttempImage.data[position] = routine(set);\n\t\t\t\t}\n\n\t\t\t\t// Because there is nothing left to add, simply remove items from out set until we reach the end\n\t\t\t\t// This will wrap up the calculation for the row\n\t\t\t\tfor (; x < grayScaleImage.width; ++x)\n\t\t\t\t{\n\t\t\t\t\t//set.erase(grayScaleImage.data[row + x - windowHalfWidthPlusOne]);\n\t\t\t\t\tconst std::multiset<Pixel8>::iterator hit(set.find(grayScaleImage.data[row + x - windowHalfWidthPlusOne]));\n\t\t\t\t\tif (hit != set.end()) set.erase(hit);\n\n\t\t\t\t\ttempImage.data[row + x] = routine(set);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For each column (x) in erodedImage, calculate the min/max value within the 1-D window for that column\n\t\t\t// After this routine, erodedImage will contain an array of all min/max values\n\t\t\tfor (int x = 0; x < tempImage.width; ++x)\n\t\t\t{\n\t\t\t\tstd::multiset<Pixel8> set;\n\n\t\t\t\t// Note: We are calling Pixel(x,y) here because we are traversing columns\n\n\t\t\t\t// Initialize set with first half of our 1-D window\n\t\t\t\t// This sets pixel 0,0 with the max of the half window.\n\t\t\t\tfor (int w = 0; w <= windowHalfWidth; ++w)\n\t\t\t\t{\n\t\t\t\t\tset.insert(tempImage.Pixel(x, w));\n\t\t\t\t}\n\t\t\t\tmorphedImage.Pixel(x, 0) = routine(set);\n\n\t\t\t\t// Fill it up until we hit the full height of the 1-D window\n\t\t\t\t// This allows us to set the next few pixels as we iterate to that point\n\t\t\t\tint y = 1;\n\t\t\t\tfor (; y <= windowHalfWidth; ++y)\n\t\t\t\t{\n\t\t\t\t\tset.insert(tempImage.Pixel(x, windowHalfWidth + y));\n\t\t\t\t\tmorphedImage.Pixel(x, y) = routine(set);\n\t\t\t\t}\n\n\t\t\t\t// Now that we have a full window set, simply add the next item and remove the last time.\n\t\t\t\t// This will take use almost to the end of the column, finding the min/max value for that point within a 1-D window\n\t\t\t\tfor (; y < tempImage.height - windowHalfWidth; ++y)\n\t\t\t\t{\n\t\t\t\t\t//set.erase(tempImage.Pixel(x, y - windowHalfWidthPlusOne));\n\t\t\t\t\tconst std::multiset<Pixel8>::iterator hit(set.find(tempImage.Pixel(x, y - windowHalfWidthPlusOne)));\n\t\t\t\t\tif (hit != set.end()) set.erase(hit);\n\n\t\t\t\t\tset.insert(tempImage.Pixel(x, y + windowHalfWidth));\n\t\t\t\t\tmorphedImage.Pixel(x, y) = routine(set);\n\t\t\t\t}\n\n\t\t\t\t// Because there is nothing left to add, simply remove items from out set until we reach the end\n\t\t\t\t// This will wrap up the calculation for the column\n\t\t\t\tfor (; y < tempImage.height; ++y)\n\t\t\t\t{\n\t\t\t\t\t//set.erase(tempImage.Pixel(x, y - windowHalfWidthPlusOne));\n\t\t\t\t\tconst std::multiset<Pixel8>::iterator hit(set.find(tempImage.Pixel(x, y - windowHalfWidthPlusOne)));\n\t\t\t\t\tif (hit != set.end()) set.erase(hit);\n\n\t\t\t\t\tmorphedImage.Pixel(x, y) = routine(set);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstatic inline void IterativelyErode(Image& morphedImage, const Image& grayScaleImage, const int& windowSize)\n\t\t{\n\t\t\t// Iterate entire image creating a window around each pixel\n\t\t\tLocalWindow::Iterate(grayScaleImage, windowSize, [&](const Region& window, const int& target)\n\t\t\t{\n\t\t\t\tint min = 255;\n\n\t\t\t\t// Iterate each window, finding the max value\n\t\t\t\tLocalWindow::Iterate(grayScaleImage.width, window, [&](const int& position) {\n\t\t\t\t\tconst int value = grayScaleImage.data[position];\n\t\t\t\t\tif (value < min)\n\t\t\t\t\t{\n\t\t\t\t\t\tmin = value;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmorphedImage.data[target] = min;\n\t\t\t});\n\t\t}\n\n\t\tstatic inline void IterativelyDilate(Image& morphedImage, const Image& grayScaleImage, const int& windowSize)\n\t\t{\n\t\t\t// Iterate entire image creating a window around each pixel\n\t\t\tLocalWindow::Iterate(grayScaleImage, windowSize, [&](const Region& window, const int& target)\n\t\t\t{\n\t\t\t\tint max = 0;\n\n\t\t\t\t// Iterate each window, finding the max value\n\t\t\t\tLocalWindow::Iterate(grayScaleImage.width, window, [&](const int& position) {\n\t\t\t\t\tconst int value = grayScaleImage.data[position];\n\t\t\t\t\tif (value > max)\n\t\t\t\t\t{\n\t\t\t\t\t\tmax = value;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tmorphedImage.data[target] = max;\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //MORPHOLOGY_HPP\n"
  },
  {
    "path": "Doxa/MultiScale.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2025, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef MULTISCALE_HPP\n#define MULTISCALE_HPP\n\n#include <cassert>\n#include \"Algorithm.hpp\"\n#include \"Morphology.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// Multi-Scale Algorithm: Reza Farrahi Moghaddam, Mohamed Cheriet\n\t/// \n\t/// This algorithm takes in an initial scale, aka the window size, and stitches together a final binarized output\n\t/// based on the output for binarized images taken at different scales.  These images are eroded and any connecting\n\t/// pixels are assigned to the final output image.\n\t/// \n\t/// This algorithm, in the paper, is paired with a Grid image processor.  Depending on the number of scales, a\n\t/// grid-based approach may be necessary in order to reduce the overall runtime of the underlying algorithm.\n\t/// \n\t/// Note:\n\t/// This should not be confused with \"Efficient Multiscale Sauvola’s Binarization\" by Guillaume Lazzara and Thierry Géraud.\n\t/// \n\t/// </summary>\n\t/// <remarks>\"A multi-scale framework for adaptive binarization of degraded document images\", 2010.</remarks>\n\ttemplate<class BinarizationClass>\n\tclass MultiScale : public Algorithm<MultiScale<BinarizationClass>>\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tconst int Slow = 9;\n\t\t\tconst int Shigh = parameters.Get(\"window\", 75);\n\n\t\t\tdouble k = parameters.Get(\"k\", 1.0);\n\n\t\t\t// Input and Output cannot be the same\n\t\t\tassert(MultiScale::grayScaleImageIn.data != binaryImageOut.data);\n\n\t\t\tImage binarizedMap(MultiScale::grayScaleImageIn.width, MultiScale::grayScaleImageIn.height);\n\t\t\tImage binarizedMask(MultiScale::grayScaleImageIn.width, MultiScale::grayScaleImageIn.height);\n\n\t\t\t// Seed our binary output\n\t\t\tBinarizationClass algorithm;\n\t\t\talgorithm.Initialize(MultiScale::grayScaleImageIn);\n\t\t\talgorithm.ToBinary(binaryImageOut, parameters);\n\n\t\t\t// Create our first binarized mask\n\t\t\tMorphology::Erode(binarizedMask, binaryImageOut, Shigh / 4);\n\n\t\t\t// Copy parameters and only change 'windows' and 'k', keeping all others\n\t\t\tParameters msParams(parameters);\n\n\t\t\t// Iterate over multiple window scales\n\t\t\tfor (int S = Shigh / 2; S >= Slow; S = S / 2, k = k / 2)\n\t\t\t{\n\t\t\t\t// Get scaled map\n\t\t\t\tmsParams.Set(\"window\", S);\n\t\t\t\tmsParams.Set(\"k\", k);\n\t\t\t\talgorithm.ToBinary(binarizedMap, msParams);\n\n\t\t\t\t// Apply mask\n\t\t\t\tfor (int idx = 0; idx < binarizedMask.size; ++idx)\n\t\t\t\t{\n\t\t\t\t\tif (binarizedMask.data[idx] == Palette::Black && binarizedMap.data[idx] == Palette::Black)\n\t\t\t\t\t{\n\t\t\t\t\t\tbinaryImageOut.data[idx] = Palette::Black;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Avoid calculating the next Mask if we aren't going to use it\n\t\t\t\tif (S / 2 < Slow) break;\n\n\t\t\t\t// Obtain the next Mask\n\t\t\t\tMorphology::Erode(binarizedMask, binarizedMap, S / 4);\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n#endif //MUTISCALEGRID_HPP\n"
  },
  {
    "path": "Doxa/Niblack.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef NIBLACK_HPP\n#define NIBLACK_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Niblack Algorithm: Wayne Niblack\n\t/// </summary>\n\t/// <remarks>\"An Introduction to Digital Image Processing\", 1986.</remarks>\n\tclass Niblack : public Algorithm<Niblack>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int&) {\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn (mean + (k * stddev));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //NIBLACK_HPP\n"
  },
  {
    "path": "Doxa/Nick.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef NICK_HPP\n#define NICK_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The NICK Algorithm: Khurram Khurshid, Imran \u0001Siddiqi, Claudie Faure, \u0001Nicole Vincent\n\t/// </summary>\n\t/// <remarks>\"Comparison of Niblack inspired Binarization methods for ancient documents\", 2009.</remarks>\n\tclass Nick : public Algorithm<Nick>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", -0.2);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int&) {\n\n\t\t\t\treturn mean + (k * std::sqrt(variance + (mean * mean)));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //NICK_HPP\n"
  },
  {
    "path": "Doxa/Otsu.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2022, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef OTSU_HPP\n#define OTSU_HPP\n\n#include \"Types.hpp\"\n#include \"Algorithm.hpp\"\n#include \"Image.hpp\"\n#include \"Palette.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Otsu Algorithm: Nobuyuki Otsu\n\t/// \n\t/// This implementation was actually inspired by:\n\t/// \"A C++ Implementation of Otsu’s Image Segmentation Method\", 2016.\n\t/// Thank you, Juan Pablo Balarini & Sergio Nesmachnow\n\t/// </summary>\n\t/// <remarks>\"A threshold selection method from gray-level histograms\", 1979.</remarks>\n\tclass Otsu : public GlobalThreshold<Otsu>\n\t{\n\tpublic:\n\t\tstatic const int HISTOGRAM_SIZE = 256;\n\n\t\tPixel8 Algorithm(const unsigned int* histogram, const int N) const\n\t\t{\n\t\t\tPixel8 threshold = 0;\n\n\t\t\t// Init variables\n\t\t\tint sum = 0;\n\t\t\tint sumB = 0;\n\t\t\tint q1 = 0;\n\t\t\tdouble max = 0;\n\n\t\t\t// Calculate sum\n\t\t\tfor (int idx = 0; idx < HISTOGRAM_SIZE; ++idx)\n\t\t\t{\n\t\t\t\tsum += idx * histogram[idx];\n\t\t\t}\n\n\t\t\tfor (int idx = 0; idx < HISTOGRAM_SIZE; ++idx)\n\t\t\t{\n\t\t\t\t// q1 = Weighted Background\n\t\t\t\tq1 += histogram[idx];\n\t\t\t\tif (q1 == 0)\n\t\t\t\t\tcontinue;\n\n\t\t\t\t// q2 = Weighted Foreground\n\t\t\t\tconst int q2 = N - q1;\n\t\t\t\tif (q2 == 0)\n\t\t\t\t\tbreak;\n\n\t\t\t\tsumB += (idx * histogram[idx]);\n\n\t\t\t\tconst double m1m2 =\n\t\t\t\t\t(double)sumB / q1 -\t\t\t// Mean Background\n\t\t\t\t\t(double)(sum - sumB) / q2;\t// Mean Foreground\n\n\t\t\t\t// Note - There is an insidious casting situation going on here.\n\t\t\t\t// If one were to multiple by q1 or q2 first, an explicit cast would be required!\n\t\t\t\tconst double between = m1m2 * m1m2 * q1 * q2;\n\n\t\t\t\tif (between > max)\n\t\t\t\t{\n\t\t\t\t\tthreshold = idx;\n\t\t\t\t\tmax = between;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn threshold;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Get the Global Threshold for an image using the Otsu algorithm\n\t\t/// </summary>\n\t\t/// <param name=\"grayScaleImage\">Grayscale input image</param>\n\t\t/// <param name=\"parameters\">This algorithm does not take parameters</param>\n\t\t/// <returns>Global Threshold</returns>\n\t\tPixel8 Threshold(const Image& grayScaleImage, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tconst int N = grayScaleImage.size;\n\t\t\tunsigned int histogram[HISTOGRAM_SIZE]; // Placed on stack for performance.  This shouldn't be too large.\n\t\t\tmemset(histogram, 0, (HISTOGRAM_SIZE) * sizeof(unsigned int));\n\n\t\t\tfor (int idx = 0; idx < N; ++idx)\n\t\t\t{\n\t\t\t\t++histogram[grayScaleImage.data[idx]];\n\t\t\t}\n\n\t\t\treturn Algorithm(histogram, N);\n\t\t}\n\t};\n}\n\n\n#endif //OTSU_HPP\n"
  },
  {
    "path": "Doxa/PNM.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2022, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef PNM_HPP\n#define PNM_HPP\n\n#include <bitset>\n#include <string>\n#include <fstream>\n#include <filesystem>\n#include <cassert>\n#include \"Image.hpp\"\n#include \"Palette.hpp\"\n#include \"Parameters.hpp\"\n#include \"Grayscale.hpp\"\n\nnamespace Doxa\n{\n\tnamespace fs = std::filesystem;\n\n\t/// <summary>\n\t/// Portable Any-Map (PNM)\n\t/// \n\t/// This class will allow you to read and write PNM formatted files natively, without a 3rd party library.\n\t/// \n\t/// Reading a 24 or 32 bit image will automatically convert it into grayscale.\n\t/// It should be assume that external PNM images are gamma compressed.\n\t/// See the Grayscale class for more information.\n\t/// \n\t/// File Format Support:\n\t///\t\tPortable Bitmap (PBM P4)\n\t///\t\t8bit Portable Graymap (PGM P5)\n\t///\t\tPortable Pixmap (PPM P6)\n\t///\t\tPortable Arbitrary-Map (PAM P7) - Supports reading 8 bit Grayscale, 24 bit RGB, and 32 bit RGBA\n\t/// \n\t/// We do not support ASCII formats (P1, P2, or P3) nor 16bit Grayscale.\n\t/// </summary>\n\tclass PNM\n\t{\n\tpublic:\n\n\t\t/// <summary>\n\t\t/// Reads any supported (aka: binary) PNM image from the filesystem.\n\t\t/// 24 and 32 bit images will be converted to 8-bit grayscale automatically.\n\t\t/// The PNM format specifies 709 gamma compression, but some are know to use sRGB.\n\t\t/// When converting to grayscale, this could impact your choice of algorithm.\n\t\t/// </summary>\n\t\t/// <param name=\"params\">Select a grayscale conversion algorithm via: grayscale</param>\n\t\t/// <returns>An 8 bit Image object</returns>\n\t\tstatic Image Read(const std::string& fileLocation, const Parameters& params = Parameters())\n\t\t{\n\t\t\tstd::ifstream file;\n\t\t\tfile.open(fileLocation.c_str(), std::ios::binary);\n\n\t\t\tPNM pnm;\n\t\t\tImage image;\n\t\t\tpnm.ReadPNM(file, image, params);\n\n\t\t\tfile.clear();\n\t\t\tfile.close(); // Automatically closes, but done explicitly for posterity.\n\n\t\t\treturn image;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Writes an 8-bit grayscale Image to the filesystem\n\t\t/// </summary>\n\t\tstatic void Write(const Image& image, const std::string& fileLocation)\n\t\t{\n\t\t\tif (image.data == nullptr) return;\n\n\t\t\tstd::ofstream file;\n\t\t\tfile.open(fileLocation.c_str(), std::ios::binary);\n\n\t\t\t// Save the file based on file extension\n\t\t\tstd::string ext = fs::path(fileLocation).extension().string();\n\t\t\tstd::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); // C++, please steal from C#\n\n\t\t\tPNM pnm;\n\t\t\tif (ext == \".pbm\")\n\t\t\t{\n\t\t\t\tpnm.WriteP4(file, image);\n\t\t\t}\n\t\t\telse if (ext == \".pgm\")\n\t\t\t{\n\t\t\t\tpnm.WriteP5(file, image);\n\t\t\t}\n\t\t\telse if (ext == \".ppm\")\n\t\t\t{\n\t\t\t\tpnm.WriteP6(file, image);\n\t\t\t}\n\t\t\telse if (ext == \".pam\")\n\t\t\t{\n\t\t\t\tpnm.WriteP7(file, image);\n\t\t\t}\n\n\t\t\tfile.clear();\n\t\t\tfile.close(); // Automatically closes, but done explicitly for posterity.\n\t\t}\n\n\tprotected:\n\t\t// Hide default CTOR\n\t\tPNM() {}\n\n\t\tvoid Read1BitBinary(std::istream& inputStream, Image& image)\n\t\t{\n\t\t\tconst int delta = image.width % 8;\n\t\t\tconst int paddedWidth = delta == 0 ? image.width : image.width + 8 - delta;\n\n\t\t\tfor (int y = 0; y < image.height; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 0; x < paddedWidth; x+=8)\n\t\t\t\t{\n\t\t\t\t\t// Each row is always padded to a full byte\n\t\t\t\t\tconst std::bitset<8> byte(inputStream.get());\n\t\t\t\t\tconst int position = (y * image.width) + x;\n\n\t\t\t\t\tfor (int offset = 0; offset < 8 && x + offset < image.width; ++offset)\n\t\t\t\t\t{\n\t\t\t\t\t\timage.data[position + offset] = byte.test(7 - offset) ? Palette::Black : Palette::White;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid Read8BitBinary(std::istream& inputStream, Image& image)\n\t\t{\n\t\t\tinputStream.read(reinterpret_cast<char *>(image.data), image.size);\n\t\t}\n\n\t\ttemplate<int Channels>\n\t\tvoid ColorToGrayscale(std::istream& inputStream, Image& image, GrayscaleAlgorithms algorithm)\n\t\t{\n\t\t\tauto readRgb = [&]() -> std::tuple<Pixel8, Pixel8, Pixel8> {\n\t\t\t\tPixel8 r = inputStream.get(), g = inputStream.get(), b = inputStream.get();\n\t\t\t\tif constexpr (Channels == 4) inputStream.get(); // Discard alpha\n\t\t\t\treturn { r, g, b };\n\t\t\t};\n\n\t\t\tif (algorithm == GrayscaleAlgorithms::LABDIST)\n\t\t\t{\n\t\t\t\t// Two-pass: unknown range requires min/max discovery\n\t\t\t\tconst auto lut = Grayscale::LinearLUT();\n\t\t\t\tstd::vector<float> values(image.size);\n\n\t\t\t\tfor (int idx = 0; idx < image.size; ++idx)\n\t\t\t\t{\n\t\t\t\t\tauto [r, g, b] = readRgb();\n\t\t\t\t\tvalues[idx] = Grayscale::LABDist(lut[r], lut[g], lut[b]);\n\t\t\t\t}\n\n\t\t\t\tauto [mn, mx] = std::minmax_element(values.begin(), values.end());\n\t\t\t\tconst float min = *mn;\n\t\t\t\tconst float scale = 255.0f / std::max(*mx - *mn, 1.0f);\n\n\t\t\t\tfor (int idx = 0; idx < image.size; ++idx)\n\t\t\t\t\timage.data[idx] = static_cast<Pixel8>((values[idx] - min) * scale);\n\t\t\t}\n\t\t\telse if (algorithm == GrayscaleAlgorithms::LIGHTNESS)\n\t\t\t{\n\t\t\t\t// Single-pass: known range 0-100\n\t\t\t\tconst auto lut = Grayscale::LinearLUT();\n\t\t\t\tconst float scale = 255.0f / 100.0f;\n\n\t\t\t\tfor (int idx = 0; idx < image.size; ++idx)\n\t\t\t\t{\n\t\t\t\t\tauto [r, g, b] = readRgb();\n\t\t\t\t\timage.data[idx] = static_cast<Pixel8>(\n\t\t\t\t\t\tGrayscale::Lightness(lut[r], lut[g], lut[b]) * scale);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Single-pass: non-linear algorithms with gray shortcut\n\t\t\t\tauto toGrayscale = GrayscaleAlgorithm(algorithm);\n\n\t\t\t\tfor (int idx = 0; idx < image.size; ++idx)\n\t\t\t\t{\n\t\t\t\t\tauto [r, g, b] = readRgb();\n\n\t\t\t\t\t// If the pixel is already gray, do not apply the correction\n\t\t\t\t\timage.data[idx] = (r == g && g == b) ?\n\t\t\t\t\t\tb : toGrayscale(r, g, b);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid ReadPNM(std::istream& inputStream, Image& image, const Parameters& params = Parameters())\n\t\t{\n\t\t\tstd::string magicNumber;\n\n\t\t\tinputStream >> magicNumber;\n\n\t\t\t// Note: We do not currently support the ASCII formats (P1, P2, P3)\n\n\t\t\tif (magicNumber == \"P4\") // PBM 1 bit - Binary\n\t\t\t{\n\t\t\t\t// Read Header\n\t\t\t\tinputStream >> image.width >> image.height;\n\t\t\t\tinputStream.get(); // Skip trailing white space\n\n\t\t\t\t// Initialize storage structure\n\t\t\t\timage.size = image.width * image.height;\n\t\t\t\timage.data = new Pixel8[image.size];\n\n\t\t\t\treturn Read1BitBinary(inputStream, image);\n\t\t\t}\n\t\t\telse if (magicNumber == \"P5\") // PGM 8 bit - Binary\n\t\t\t{\n\t\t\t\t// Read Header\n\t\t\t\tinputStream >> image.width >> image.height >> image.maxVal;\n\t\t\t\tinputStream.get(); // Skip trailing white space\n\n\t\t\t\t// Assertions about our header\n\t\t\t\tassert(image.maxVal >= 0 && image.maxVal <= 255);\n\n\t\t\t\t// Initialize storage structure\n\t\t\t\timage.size = image.width * image.height;\n\t\t\t\timage.data = new Pixel8[image.size];\n\n\t\t\t\treturn Read8BitBinary(inputStream, image);\n\t\t\t}\n\t\t\telse if (magicNumber == \"P6\") // PPM 24 bit - Binary\n\t\t\t{\n\t\t\t\t// Read Header\n\t\t\t\tinputStream >> image.width >> image.height >> image.maxVal;\n\t\t\t\tinputStream.get(); // Skip trailing white space\n\n\t\t\t\t// Assertions about our header\n\t\t\t\tassert(image.maxVal >= 0 && image.maxVal <= 255);\n\n\t\t\t\t// Initialize storage structure\n\t\t\t\timage.size = image.width * image.height;\n\t\t\t\timage.data = new Pixel8[image.size];\n\n\t\t\t\tauto algorithm = static_cast<GrayscaleAlgorithms>(params.Get(\"grayscale\", (int)GrayscaleAlgorithms::MEAN));\n\t\t\t\treturn ColorToGrayscale<3>(inputStream, image, algorithm);\n\t\t\t}\n\t\t\telse if (magicNumber == \"P7\") // PAM arbitrary bit - Binary\n\t\t\t{\n\t\t\t\tstd::string widthTxt, heightTxt, depthTxt, maxValTxt, tuplTypeTxt, endHeader;\n\n\t\t\t\tinputStream\n\t\t\t\t\t>> widthTxt >> image.width\n\t\t\t\t\t>> heightTxt >> image.height\n\t\t\t\t\t>> depthTxt >> image.depth\n\t\t\t\t\t>> maxValTxt >> image.maxVal\n\t\t\t\t\t>> tuplTypeTxt >> image.tupleType\n\t\t\t\t\t>> endHeader;\n\n\t\t\t\t// Assertions about our header\n\t\t\t\tassert(widthTxt == \"WIDTH\");\n\t\t\t\tassert(heightTxt == \"HEIGHT\");\n\t\t\t\tassert(depthTxt == \"DEPTH\");\n\t\t\t\tassert(maxValTxt == \"MAXVAL\");\n\t\t\t\tassert(tuplTypeTxt == \"TUPLTYPE\");\n\t\t\t\tassert(endHeader == \"ENDHDR\");\n\n\t\t\t\tinputStream.get(); // Skip trailing white space\n\n\t\t\t\t// Initialize storage structure\n\t\t\t\timage.size = image.width * image.height;\n\t\t\t\timage.data = new Pixel8[image.size];\n\n\t\t\t\tswitch (image.depth)\n\t\t\t\t{\n\t\t\t\tcase 1:\n\t\t\t\t\t// \"Such a PAM image has a depth of 1 and maxval 1 where the one sample in each tuple is 0 to represent a black pixel and 1 to represent a white one.\"\n\t\t\t\t\t// We are not supporting B&W at this time because they want 0 = black and 1 = white.  It offends me to even think about writing such a routine.\n\t\t\t\t\t// Why not fall back to PBM's 1bit B&W, or 0 for black and 255 for white.  But 8 bits and 1 is suppose to equal white?  Please.\n\t\t\t\t\tif (image.tupleType == TupleTypes::BLACK_WHITE && image.maxVal == 1) throw \"PAM: Black and White not supported.  Use PBM instead.\";\n\n\t\t\t\t\treturn Read8BitBinary(inputStream, image);\n\t\t\t\tcase 3:\n\t\t\t\t{\n\t\t\t\t\tauto algorithm = static_cast<GrayscaleAlgorithms>(params.Get(\"grayscale\", (int)GrayscaleAlgorithms::MEAN));\n\t\t\t\t\treturn ColorToGrayscale<3>(inputStream, image, algorithm);\n\t\t\t\t}\n\t\t\t\tcase 4:\n\t\t\t\t{\n\t\t\t\t\tif (image.tupleType != TupleTypes::RGBA) throw \"PAM: Only 32bit RGBA is supported.\";\n\t\t\t\t\tauto algorithm = static_cast<GrayscaleAlgorithms>(params.Get(\"grayscale\", (int)GrayscaleAlgorithms::MEAN));\n\t\t\t\t\treturn ColorToGrayscale<4>(inputStream, image, algorithm);\n\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow \"Unsupported Format\";\n\t\t}\n\n\t\tvoid WriteP4(std::ostream &outputStream, const Image &image)\n\t\t{\n\t\t\toutputStream\n\t\t\t\t<< \"P4\" << std::endl\n\t\t\t\t<< image.width << \" \" << image.height << std::endl;\n\t\t\t\n\t\t\tconst int delta = image.width % 8;\n\t\t\tconst int paddedWidth = delta == 0 ? image.width : image.width + 8 - delta;\n\n\t\t\tfor (int y = 0; y < image.height; ++y)\n\t\t\t{\n\t\t\t\tfor (int x = 0; x < paddedWidth; x += 8)\n\t\t\t\t{\n\t\t\t\t\t// Each row is always padded to a full byte\n\t\t\t\t\tstd::bitset<8> byte;\n\t\t\t\t\tconst int position = (y * image.width) + x;\n\n\t\t\t\t\tfor (int offset = 0; offset < 8 && x + offset < image.width; ++offset)\n\t\t\t\t\t{\n\t\t\t\t\t\tbyte.set(7 - offset, image.data[position + offset] == Palette::Black);\n\t\t\t\t\t}\n\n\t\t\t\t\toutputStream << static_cast<Pixel8>(byte.to_ulong());\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteP5(std::ostream &outputStream, const Image &image)\n\t\t{\n\t\t\toutputStream\n\t\t\t\t<< \"P5\" << std::endl\n\t\t\t\t<< image.width << \" \" << image.height << std::endl\n\t\t\t\t<< image.maxVal << std::endl;\n\n\t\t\tconst size_t size = image.size * sizeof(Pixel8);\n\t\t\toutputStream.write(reinterpret_cast<char *>(image.data), size);\n\t\t}\n\n\t\tvoid WriteP6(std::ostream& outputStream, const Image& image)\n\t\t{\n\t\t\toutputStream\n\t\t\t\t<< \"P6\" << std::endl\n\t\t\t\t<< image.width << \" \" << image.height << std::endl\n\t\t\t\t<< image.maxVal << std::endl;\n\n\t\t\tfor (int idx = 0; idx < image.size; ++idx)\n\t\t\t{\n\t\t\t\tconst Pixel8 pixel = image.data[idx];\n\t\t\t\toutputStream << pixel << pixel << pixel;\n\t\t\t}\n\t\t}\n\n\t\tvoid WriteP7(std::ostream &outputStream, const Image &image)\n\t\t{\n\t\t\tassert(image.depth == 1); // We are only supporting 8 bit for now\n\n\t\t\toutputStream\n\t\t\t\t<< \"P7\" << std::endl\n\t\t\t\t<< \"WIDTH \" << image.width << std::endl\n\t\t\t\t<< \"HEIGHT \" << image.height << std::endl\n\t\t\t\t<< \"DEPTH \" << image.depth << std::endl\n\t\t\t\t<< \"MAXVAL \" << image.maxVal << std::endl\n\t\t\t\t<< \"TUPLTYPE \" << image.tupleType << std::endl\n\t\t\t\t<< \"ENDHDR\" << std::endl;\n\n\t\t\tconst size_t size = image.size * sizeof(Pixel8);\n\t\t\toutputStream.write(reinterpret_cast<char *>(image.data), size);\n\t\t}\n\n\t\tGrayscaleFunc GrayscaleAlgorithm(GrayscaleAlgorithms algorithm)\n\t\t{\n\t\t\tswitch (algorithm)\n\t\t\t{\n\t\t\t\t// Works in Non-Linear Color Space\n\t\t\t\tcase GrayscaleAlgorithms::QT:        return Grayscale::Qt<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::BT601:     return Grayscale::BT601<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::BT709:     return Grayscale::BT709<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::BT2100:    return Grayscale::BT2100<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::VALUE:     return Grayscale::Value<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::LUSTER:    return Grayscale::Luster<Pixel8>;\n\t\t\t\tcase GrayscaleAlgorithms::MINAVG:    return Grayscale::MinAvg<Pixel8>;\n\n\t\t\t\t// Linear algorithms (LIGHTNESS, LABDIST) are handled directly by ColorToGrayscale\n\n\t\t\t\t// Default\n\t\t\t\tdefault:                             return Grayscale::Mean<Pixel8>;\n\t\t\t}\n\t\t}\n\t};\n}\n\n\n#endif // PNM_HPP\n"
  },
  {
    "path": "Doxa/Palette.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef PALETTE_HPP\n#define PALETTE_HPP\n\n#include <cmath>\n#include \"Types.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// Palette provides many pixel manipulation routines for getting and setting colors.\n\t/// Note that it is tuned only for Little Endian systems.\n\t/// On Big Endian systems, make sure to avoid any methods taking a Pixel32.\n\t/// </summary>\n\tclass Palette\n\t{\n\tpublic:\n\t\t// RGBA 32b Pixel Decoding\n\t\tstatic inline constexpr int Red(Pixel32 rgba) { return (rgba & 0xff); }\n\t\tstatic inline constexpr int Green(Pixel32 rgba) { return ((rgba >> 8) & 0xff); }\n\t\tstatic inline constexpr int Blue(Pixel32 rgba) { return ((rgba >> 16) & 0xff); }\n\t\tstatic inline constexpr int Alpha(Pixel32 rgba) { return rgba >> 24; }\n\n\t\t// RGBA to Pixel\n\t\tstatic inline constexpr Pixel32 RGB(int r, int g, int b)\n\t\t{\n\t\t\treturn (0xffu << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);\n\t\t}\n\n\t\tstatic inline constexpr Pixel32 RGBA(int r, int g, int b, int a)\n\t\t{\n\t\t\treturn ((a & 0xff) << 24) | ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);\n\t\t}\n\n\t\tstatic inline constexpr Pixel32 UpdateAlpha(Pixel32 rgba, int a)\n\t\t{\n\t\t\treturn (rgba & 0x00ffffff) | (a << 24);\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Using the RGB color space, calculate the difference between two colors.\n\t\t/// The results should be very similar to equations using the more common L*u*v* color space.\n\t\t/// </summary>\n\t\t/// <remarks>https://www.compuphase.com/cmetric.htm</remarks>\n\t\t/// <returns></returns>\n\t\tstatic inline int ColorDistance(Pixel32 left, Pixel32 right)\n\t\t{\n\t\t\tconst int rmean = (Red(left) + Red(right)) / 2;\n\t\t\tconst int r = Red(left) - Red(right);\n\t\t\tconst int g = Green(left) - Green(right);\n\t\t\tconst int b = Blue(left) - Blue(right);\n\n\t\t\treturn std::sqrt( ((2 + rmean/256) * r*r) + (4 * g*g) + ((2 + (255 - rmean)/256) * b*b) );\n\t\t}\n\n\t\tstatic inline constexpr bool IsGray(Pixel32 rgba)\n\t\t{\n\t\t\treturn Blue(rgba) == Green(rgba) && Blue(rgba) == Red(rgba);\n\t\t}\n\n\t\t// Black and White\n\t\tstatic const Pixel8 Black = 0;\n\t\tstatic const Pixel8 White = 255;\n\t};\n}\n\n\n#endif // PALETTE_HPP\n"
  },
  {
    "path": "Doxa/Parameters.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef PARAMETERS_HPP\n#define PARAMETERS_HPP\n\n#include <map>\n#include <variant>\n#include <string>\n#include \"Types.hpp\"\n\n\nnamespace Doxa\n{\n\ttypedef std::variant<int, double> ParameterValue;\n\ttypedef std::map<std::string, ParameterValue> ParameterMap;\n\n\t/// <summary>\n\t/// Parameters can be passed into any algorithm, much like a key value pair.\n\t/// The Key is the name of the parameter, while the Value can be any Integer or Double.\n\t/// \n\t/// Note: All window values should be ODD.  We are currently not enforcing this.\n\t/// </summary>\n\tclass Parameters\n\t{\n\tpublic:\n\t\ttemplate<typename Type>\n\t\tconst Type Get(const std::string& name, const Type& defaultValue) const\n\t\t{\n\t\t\tParameterMap::const_iterator pos = parameterMap.find(name);\n\t\t\tif (pos == parameterMap.end()) \n\t\t\t{\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn std::visit(\n\t\t\t\t\t[](auto&& value) -> Type {\n\t\t\t\t\t\t// Some languages, like Javascript, store 1 and 1.0 identically.\n\t\t\t\t\t\t// std::get<Type>(pos->second), in this situation, will throw a std::bad_variant_access\n\t\t\t\t\t\t// exception due to its inability to implicitly cast Int to a Float/Double.\n\t\t\t\t\t\treturn static_cast<Type>(value);\n\t\t\t\t\t},\n\t\t\t\t\tpos->second\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tvoid Set(const std::string& name, const ParameterValue& value)\n\t\t{\n\t\t\tparameterMap[name] = value;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// CTOR\n\t\t/// Example: Parameters param({ {\"window\", 75}, {\"k\", 0.1 } });\n\t\t/// </summary>\n\t\tParameters(const ParameterMap& parameterMap)\n\t\t{\n\t\t\tthis->parameterMap = parameterMap;\n\t\t}\n\t\t\n\t\t/// <summary>\n\t\t/// A very naive JSON object parser.  Useful for WebAssembly.\n\t\t/// Example: Parameters params(R\"({\"window\": 75, \"k\": -0.01})\");\n\t\t/// </summary>\n\t\t/// <param name=\"json\">A simple JSON object</param>\n\t\tstatic Parameters FromJson(const std::string& json)\n\t\t{\n\t\t\tParameters params;\n\n\t\t\tstd::size_t keyStart = json.find('\"');\n\t\t\twhile (keyStart != std::string::npos)\n\t\t\t{\n\t\t\t\t// Get Coordinates\n\t\t\t\tstd::size_t keyStop = json.find('\"', ++keyStart);\n\t\t\t\tstd::size_t valueStart = json.find(':', keyStop);\n\t\t\t\tstd::size_t valueStop = json.find_first_of(\",}\", ++valueStart);\n\n\t\t\t\t// Get Key / Value\n\t\t\t\tstd::string key = json.substr(keyStart, keyStop - keyStart);\n\t\t\t\tstd::string value = json.substr(valueStart, valueStop - valueStart);\n\n\t\t\t\t// Value Type: String\n\t\t\t\tif (value.find('\"') != std::string::npos)\n\t\t\t\t{\n\t\t\t\t\t// Filtered Out: We do not currently support string parameters.\n\t\t\t\t}\n\t\t\t\t// Value Type: Double\n\t\t\t\telse if (value.find('.') != std::string::npos)\n\t\t\t\t{\n\t\t\t\t\tparams.parameterMap[key] = std::stod(value);\n\t\t\t\t}\n\t\t\t\t// Value Type: Integer\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tparams.parameterMap[key] = std::stoi(value);\n\t\t\t\t}\n\n\t\t\t\tkeyStart = json.find('\"', ++keyStop);\n\t\t\t}\n\n\t\t\treturn params;\n\t\t}\n\n\t\tParameters() {}\n\n\tprotected:\n\t\tParameterMap parameterMap;\n\t};\n}\n\n#endif //PARAMETERS_HPP"
  },
  {
    "path": "Doxa/Phansalkar.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef PHANSALKAR_HPP\n#define PHANSALKAR_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Phansalkar Algorithm: Neerad Phansalkar, Sumit More, Ashish Sabale, Madhuri Joshi \n\t///\n\t/// This papers calls for the logical OR of the thresholding algorithm ran on:\n\t///    RGB Grayscale - BT601\n\t///    L* a* b* Grayscale - sqr_root(L*^2 + a*^2 + b*^2)\n\t/// \n\t/// This algorithm is unique in its use of LAB to take into account Color!\n\t/// NOTE: Run this twice with different grayscale algorithms and then OR the images together.\n\t///\n\t///\tOptimization Approach (from paper):\n\t///   \"Such a global threshold should not reject a single pixel that corresponds to a nucleus...\"\n\t///   \"Such a threshold is obtained using Otsu’s method.\"\n\t/// This is not true of document glyphs.  Because of this, the Otsu speed optimization is not implemented.\n\t/// </summary>\n\t/// <remarks>\"Adaptive Local Thresholding for Detection of Nuclei in Diversely Stained Cytology Images\", 2011.</remarks>\n\tclass Phansalkar : public Algorithm<Phansalkar>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\t\t\tconst double p = parameters.Get(\"p\", 3.0);\n\t\t\tconst double q = parameters.Get(\"q\", 10.0) / 255; // Normalized to 0 to 255, not 0 to 1.\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int&) {\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn mean * (1 + p * exp(-q * (mean)) + k * ((stddev / 128) - 1));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //PHANSALKAR_HPP\n"
  },
  {
    "path": "Doxa/Region.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef REGION_HPP\n#define REGION_HPP\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// A structure which denotes a specific area, or window, within an Image.\n\t/// Note that only Points are stored.  All other calls will be calculated.\n\t/// </summary>\n\tstruct Region\n\t{\n\tpublic:\n\t\tstruct Point\n\t\t{\n\t\t\tPoint() {}\n\t\t\tPoint(int x, int y) : x(x), y(y) {}\n\n\t\t\tbool operator==(const Point& rhs) const\n\t\t\t{\n\t\t\t\treturn (x == rhs.x) && (y == rhs.y);\n\t\t\t}\n\n\t\t\tint x;\n\t\t\tint y;\n\t\t};\n\n\t\tRegion() {}\n\t\tRegion(const Point& upperLeft, const Point& bottomRight) : upperLeft(upperLeft), bottomRight(bottomRight) {}\n\t\tRegion(int x1, int y1, int x2, int y2) : upperLeft(x1, y1), bottomRight(x2, y2) {}\n\t\tRegion(int x1, int y1, int size) : upperLeft(x1, y1), bottomRight(x1 + size - 1, y1 + size - 1) {}\n\t\tRegion(int width, int height) : upperLeft(0, 0), bottomRight(width - 1, height - 1) {}\n\n\t\tinline bool InRegion(const Region& region) const\n\t\t{\n\t\t\treturn (region.upperLeft.x >= upperLeft.x &&\n\t\t\t\t\tregion.upperLeft.y >= upperLeft.y &&\n\t\t\t\t\tregion.bottomRight.x <= bottomRight.x &&\n\t\t\t\t\tregion.bottomRight.y <= bottomRight.y);\n\t\t}\n\n\t\tinline int Width() const\n\t\t{\n\t\t\treturn (bottomRight.x - upperLeft.x) + 1;\n\t\t}\n\n\t\tinline int Height() const\n\t\t{\n\t\t\treturn (bottomRight.y - upperLeft.y) + 1;\n\t\t}\n\n\t\tinline int Area() const\n\t\t{\n\t\t\treturn Width() * Height();\n\t\t}\n\n\t\tPoint upperLeft;\n\t\tPoint bottomRight;\n\n\t\tbool operator==(const Region& rhs) const\n\t\t{\n\t\t\treturn (upperLeft == rhs.upperLeft) && (bottomRight == rhs.bottomRight);\n\t\t}\n\t};\n}\n\n\n#endif // REGION_HPP\n"
  },
  {
    "path": "Doxa/SIMD.h",
    "content": "// ?oxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n// Purpose: Compile-time SIMD detection for SSE2, NEON, and WASM SIMD (128-bit)\n#ifndef SIMD_H\n#define SIMD_H\n\n\nnamespace Doxa::SIMD\n{\n    // ============================================================================\n    // Compile-Time SIMD Detection\n    // ============================================================================\n    # define DOXA_SIMD 1\n\n    #if defined(__wasm_simd128__)\n        // WebAssembly SIMD128\n        #define DOXA_SIMD_WASM 1\n\n    #elif defined(__SSE2__) || (defined(_MSC_VER) && defined(_M_X64))\n        // x86-64 with SSE2 (always available on x64, standard since Pentium 4)\n        #define DOXA_SIMD_SSE2 1\n\n    #elif defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__aarch64__)\n        // ARM NEON (always available on ARM64/aarch64)\n        #define DOXA_SIMD_NEON 1\n\n    #else\n        // No SIMD options available\n        #undef DOXA_SIMD\n    #endif\n\n    // ============================================================================\n    // SIMD Width Constant\n    // All supported SIMD architectures use 128-bit vectors = 16 bytes\n    // ============================================================================\n\n    constexpr int SIMD_WIDTH = 16;\n\n} // namespace Doxa::SIMD\n\n\n#endif // SIMD_H\n"
  },
  {
    "path": "Doxa/SIMDOps.hpp",
    "content": "﻿// Δoxa Binarization Framework\n// License: CC0 2026, \"Freely you have received; freely give.\" - Matt 10:8\n// Purpose: Unified 128-bit SIMD operations for SSE2, NEON, and WASM SIMD\n#ifndef SIMDOPS_HPP\n#define SIMDOPS_HPP\n\n#include \"SIMD.h\"\n\n// ============================================================================\n// Platform-Specific Includes\n// ============================================================================\n\n#if defined(DOXA_SIMD_SSE2)\n    #include <emmintrin.h>\n#elif defined(DOXA_SIMD_NEON)\n    #include <arm_neon.h>\n#elif defined(DOXA_SIMD_WASM)\n    #include <wasm_simd128.h>\n#endif\n\n\nnamespace Doxa::SIMD\n{\n    // ============================================================================\n    // Vector Type Definition\n    // ============================================================================\n\n    #if defined(DOXA_SIMD_SSE2)\n        typedef __m128i vec128;\n    #elif defined(DOXA_SIMD_NEON)\n        typedef uint8x16_t vec128;\n    #elif defined(DOXA_SIMD_WASM)\n        typedef v128_t vec128;\n    #endif\n\n    // ============================================================================\n    // Unified SIMD Macros\n    // These provide a common interface across SSE2, NEON, and WASM SIMD.\n    // Only macros that are actually used in the codebase are defined.\n    // ============================================================================\n\n    #if defined(DOXA_SIMD_SSE2)\n        // SSE2 implementations\n        #define VEC_LOAD(ptr)         _mm_loadu_si128((const __m128i*)(ptr))\n        #define VEC_STORE(ptr, v)     _mm_storeu_si128((__m128i*)(ptr), v)\n        #define VEC_SPLAT_U8(val)     _mm_set1_epi8((char)(val))\n        #define VEC_CMPEQ_U8(a, b)    _mm_cmpeq_epi8(a, b)\n        #define VEC_MIN_U8(a, b)      _mm_min_epu8(a, b)\n        #define VEC_AND(a, b)         _mm_and_si128(a, b)\n        #define VEC_ANDNOT(a, b)      _mm_andnot_si128(a, b)  // ~a & b\n        #define VEC_NOT(a)            _mm_xor_si128(a, _mm_set1_epi8(-1))\n        #define VEC_ALL_TRUE_U8(v)    (_mm_movemask_epi8(v) == 0xFFFF)\n        #define VEC_LOAD_2x64(p0, p1) _mm_unpacklo_epi64( \\\n            _mm_loadl_epi64((const __m128i*)(p0)), \\\n            _mm_loadl_epi64((const __m128i*)(p1)))\n\n    #elif defined(DOXA_SIMD_NEON)\n        // ARM NEON implementations\n        #define VEC_LOAD(ptr)         vld1q_u8((const uint8_t*)(ptr))\n        #define VEC_STORE(ptr, v)     vst1q_u8((uint8_t*)(ptr), v)\n        #define VEC_SPLAT_U8(val)     vdupq_n_u8(val)\n        #define VEC_CMPEQ_U8(a, b)    vceqq_u8(a, b)\n        #define VEC_MIN_U8(a, b)      vminq_u8(a, b)\n        #define VEC_AND(a, b)         vandq_u8(a, b)\n        #define VEC_ANDNOT(a, b)      vbicq_u8(b, a)  // b & ~a (note: reversed args)\n        #define VEC_NOT(a)            vmvnq_u8(a)\n        #define VEC_ALL_TRUE_U8(v)    (vminvq_u8(v) == 0xFF)\n        #define VEC_LOAD_2x64(p0, p1) vcombine_u8(vld1_u8(p0), vld1_u8(p1))\n\n    #elif defined(DOXA_SIMD_WASM)\n        // WebAssembly SIMD implementations\n        #define VEC_LOAD(ptr)         wasm_v128_load(ptr)\n        #define VEC_STORE(ptr, v)     wasm_v128_store(ptr, v)\n        #define VEC_SPLAT_U8(val)     wasm_i8x16_splat(val)\n        #define VEC_CMPEQ_U8(a, b)    wasm_i8x16_eq(a, b)\n        #define VEC_MIN_U8(a, b)      wasm_u8x16_min(a, b)\n        #define VEC_AND(a, b)         wasm_v128_and(a, b)\n        #define VEC_ANDNOT(a, b)      wasm_v128_andnot(b, a)  // b & ~a\n        #define VEC_NOT(a)            wasm_v128_not(a)\n        #define VEC_ALL_TRUE_U8(v)    (wasm_i8x16_bitmask(v) == 0xFFFF)\n        #define VEC_LOAD_2x64(p0, p1) wasm_v128_load64_lane(p1, wasm_v128_load64_zero(p0), 1)\n    #endif\n\n    #if defined(DOXA_SIMD)\n        // Check if all bytes in two vectors are equal\n        #define VEC_ALL_EQ_U8(a, b)   VEC_ALL_TRUE_U8(VEC_CMPEQ_U8(a, b))\n    #endif\n\n    // ============================================================================\n    // Helper Functions - Platform-Specific Implementations\n    // ============================================================================\n\n    #if defined(DOXA_SIMD)\n\n        // Horizontal Sum of Bytes\n        inline int vec_hsum_u8(vec128 v) {\n            #if defined(DOXA_SIMD_SSE2)\n                vec128 sad = _mm_sad_epu8(v, _mm_setzero_si128());\n                return _mm_cvtsi128_si32(sad) + _mm_extract_epi16(sad, 4);\n\n            #elif defined(DOXA_SIMD_NEON)\n                return vaddvq_u8(v);\n\n            #elif defined(DOXA_SIMD_WASM)\n                vec128 sum16 = wasm_u16x8_extadd_pairwise_u8x16(v);\n                vec128 sum32 = wasm_i32x4_extadd_pairwise_i16x8(sum16);\n\n                return wasm_i32x4_extract_lane(sum32, 0) +\n                       wasm_i32x4_extract_lane(sum32, 1) +\n                       wasm_i32x4_extract_lane(sum32, 2) +\n                       wasm_i32x4_extract_lane(sum32, 3);\n            #endif\n        }\n\n    #endif // DOXA_SIMD\n\n\n} // namespace Doxa::SIMD\n\n\n#endif // SIMDOPS_HPP\n"
  },
  {
    "path": "Doxa/Sauvola.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef SAUVOLA_HPP\n#define SAUVOLA_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Sauvola Algorithm: J. Sauvola, M. Pietikäinen\n\t/// </summary>\n\t/// <remarks>\"Adaptive document image binarization\", 1999.</remarks>\n\tclass Sauvola : public Algorithm<Sauvola>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int&) {\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn mean * (1 + k * ((stddev / 128) - 1));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //SAUVOLA_HPP\n"
  },
  {
    "path": "Doxa/Su.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef SU_HPP\n#define SU_HPP\n\n#include \"Types.hpp\"\n#include \"Otsu.hpp\"\n#include \"Palette.hpp\"\n#include \"Region.hpp\"\n#include \"Morphology.hpp\"\n#include \"ContrastImage.hpp\"\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Su Algorithm: Bolan Su, Shijian Lu, and Chew Lim Tan\n\t/// This is a 3 step workflow consisting of:\n\t///\t\tContrast Image generation\n\t///\t\tHigh contrast pixel detection using Otsu binarization\n\t///\t\tA novel local thresholding algorithm\n\t/// \n\t/// Parameters window and minN are auto-detected from stroke width when not provided.\n\t/// </summary>\n\t/// <remarks>\"Binarization of Historical Document Images Using the Local Maximum and Minimum\", 2010.</remarks>\n\tclass Su : public Algorithm<Su>\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// 0 will trigger the auto detection of these parameters as detailed in the paper\n\t\t\tint windowSize = parameters.Get(\"window\", 0); // Based on Stroke Size\n\t\t\tint minN = parameters.Get(\"minN\", windowSize); // Roughly based on size of window\n\n\t\t\t// Step 1 & 2 - Generate Hight Contrast Image Construction\n\t\t\tImage contrastImage(Algorithm::grayScaleImageIn.width, Algorithm::grayScaleImageIn.height);\n\t\t\tContrastImage::GenerateHighContrastImage(contrastImage, Algorithm::grayScaleImageIn);\n\n\t\t\t// Optional Parameter Auto Detection\n\t\t\tif (windowSize == 0)\n\t\t\t{\n\t\t\t\tAutoDetectParameters(windowSize, minN, contrastImage);\n\t\t\t}\n\n\t\t\t// Step 3 - Historical Document Thresholding\n\t\t\tThreshold(binaryImageOut, contrastImage, Algorithm::grayScaleImageIn, windowSize, minN);\n\t\t}\n\n\tprotected:\n\t\t// <summary>\n\t\t// Calculates Stroke Width and Min-N from the estimated stroke width.\n\t\t// \n\t\t// In Su's 2010 paper, they provide no specifics on window size... just make it bigger than the stroke width.\n\t\t// In their 2013 paper, \"Robust Document Image Binarization Technique for Degraded Document Images\",\n\t\t// they empirically show that (Window Size = 2 x Stroke Width) to be the best.\n\t\t// </summary>\n\t\tvoid AutoDetectParameters(int& windowSize, int& minN, const Image& contrastImage)\n\t\t{\n\t\t\tconst int strokeWidth = ContrastImage::EstimateStrokeWidth(contrastImage);\n\t\t\twindowSize = strokeWidth * 2;\n\t\t\tminN = windowSize;\n\t\t}\n\n\t\t/// <summary>\n\t\t/// Calculates Ne, meanE, and stdE in one iteration.\n\t\t/// This is a very optimized set of calculations compared to the math found in the paper.\n\t\t/// </summary>\n\t\tvoid SuCalculations(int& Ne, double& meanE, double& stdE,\n\t\t\t\t\t\t\tconst Image& contrastImage, const Image& grayScaleImage,\n\t\t\t\t\t\t\tconst Region& window) const\n\t\t{\n\t\t\tuint64_t sumI  = 0;  // Σ I(x,y)\n\t\t\tuint64_t sumI2 = 0;  // Σ I(x,y)²\n\t\t\tNe = 0;\n\n\t\t\t// Single pass: accumulate first and second raw moments over high-contrast pixels.\n\t\t\t// Uses identity:  Var(X) = E[X²] - (E[X])²\n\t\t\tLocalWindow::Iterate(grayScaleImage.width, window, [&](const int& position)\n\t\t\t{\n\t\t\t\tif (Palette::White == contrastImage.data[position])\n\t\t\t\t{\n\t\t\t\t\tconst uint32_t I = grayScaleImage.data[position]; // promote once\n\t\t\t\t\tsumI  += I;\n\t\t\t\t\tsumI2 += I * I;\n\t\t\t\t\t++Ne;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (Ne == 0) { meanE = 0.0; stdE = 0.0; return; }\n\n\t\t\tmeanE = static_cast<double>(sumI) / Ne;\n\n\t\t\t// variance = ΣI²/Ne − meanE²\n\t\t\tconst double variance = static_cast<double>(sumI2) / Ne - meanE * meanE;\n\n\t\t\t// Clamp tiny negatives from floating-point round-off (happens when true variance ≈ 0)\n\t\t\tstdE = variance > 0.0 ? std::sqrt(variance) : 0.0;\n\t\t};\n\n\t\tvoid Threshold(Image& binaryImageOut, const Image& contrastImageIn, const Image& grayScaleImageIn, int windowSize, int minN) const\n\t\t{\n\t\t\tint Ne;\n\t\t\tdouble meanE, stdE;\n\n\t\t\tLocalWindow::Iterate(grayScaleImageIn, windowSize, [&](const Region& window, const int& position)\n\t\t\t{\n\t\t\t\tSuCalculations(Ne, meanE, stdE, contrastImageIn, grayScaleImageIn, window);\n\n\t\t\t\tbinaryImageOut.data[position] =\n\t\t\t\t\t(Ne >= minN && grayScaleImageIn.data[position] <= meanE + (stdE / 2)) ?\n\t\t\t\t\tPalette::Black : Palette::White;\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //SU_HPP\n"
  },
  {
    "path": "Doxa/TRSingh.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef TRSINGH_HPP\n#define TRSINGH_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The T.R. Singh Algorithm: T. Romen Singh, Sudipta Roy, O. Imocha Singh, Tejmani Sinam, Kh. Manglem Singh\n\t/// </summary>\n\t/// <remarks>\"A New local Adaptive Thresholding Technique in Binarization\", 2011.</remarks>\n\tclass TRSingh : public Algorithm<TRSingh>, public ChanMeanCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const int& position)\n\t\t\t{\n\t\t\t\t// Unlike Sauvola, the Singh algorithm necessitates a value between 0 and 1, not 0 255.\n\t\t\t\t// This adapts his formula to 8bit grayscale to avoid conversion operations.\n\t\t\t\tconstexpr double R = 255.0;\n\n\t\t\t\t// TR Singh's algorithm does not expressly mention the need for an absolute value.\n\t\t\t\t// However, I believe it is implied because we are talking about deviation\n\t\t\t\tdouble meandev = std::abs((double)Algorithm::grayScaleImageIn.data[position] - mean);\n\n\t\t\t\t// This clamping operation prevents a divide by zero situation\n\t\t\t\t// Alternative: Add std::numeric_limits<double>::epsilon() to the denominator\n\t\t\t\tmeandev = std::min(meandev, R - 1.0);\n\n\t\t\t\treturn mean * (1 + k * ((meandev / (R - meandev)) - 1));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //TRSINGH_HPP\n"
  },
  {
    "path": "Doxa/Types.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef TYPES_HPP\n#define TYPES_HPP\n\n#include <string>\n\nnamespace Doxa\n{\n\t// Forward Declarations\n\tstruct Image;\n\tstruct Region;\n\n\t// Type Definitions\n\ttypedef uint32_t Pixel32;\n\ttypedef uint8_t  Pixel8;\n\n\tnamespace TupleTypes\n\t{\n\t\tstatic const std::string BLACK_WHITE = \"BLACKANDWHITE\";\n\t\tstatic const std::string GRAYSCALE = \"GRAYSCALE\";\n\t\tstatic const std::string RGB = \"RGB\";\n\t\tstatic const std::string RGBA = \"RGB_ALPHA\";\n\t}\n}\n\n#endif // TYPES_HPP\n"
  },
  {
    "path": "Doxa/Wan.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef WAN_HPP\n#define WAN_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n#include \"Morphology.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The WAN Algorithm: Wan Azani Mustafa, Mohamed Mydin M. Abdul Kader\n\t/// </summary>\n\t/// <remarks>\"Binarization of Document Image Using Optimum Threshold Modification\", 2018.</remarks>\n\tclass Wan : public Algorithm<Wan>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\t// Use Dilate to generate a Max Image for the target Window\n\t\t\tImage maxImage(Algorithm::grayScaleImageIn.width, Algorithm::grayScaleImageIn.height);\n\t\t\tMorphology::Dilate(maxImage, Algorithm::grayScaleImageIn, windowSize);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int& position) {\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn (((double)maxImage.data[position] + mean) / 2) * (1 + k * ((stddev / 128) - 1));\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //WAN_HPP\n"
  },
  {
    "path": "Doxa/WienerFilter.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef WIENERFILTER_HPP\n#define WIENERFILTER_HPP\n\n#include \"Types.hpp\"\n#include \"Region.hpp\"\n#include \"Image.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// Wiener Filter - Implementation based on the wiener2 MathWorks algorithm.\n\t/// \n\t/// TODO: Improve performance\n\t/// </summary>\n\t/// <remarks>Resource: https://www.mathworks.com/help/images/ref/wiener2.html </remarks>\n\tclass WienerFilter\n\t{\n\tpublic:\n\t\tstatic void Filter(Image& outputImage, const Image& inputImage, const int windowSize = 3)\n\t\t{\n\t\t\tChanMeanVarianceCalc calculator;\n\n\t\t\t// Obtain the average variance for all pixels\n\t\t\tdouble sumVariance = 0;\n\n\t\t\tcalculator.Iterate(inputImage, windowSize, [&](const double&, const double& variance, const int&)\n\t\t\t{\n\t\t\t\tsumVariance += variance;\n\t\t\t});\n\n\t\t\tconst double avgVariance = sumVariance / inputImage.size;\n\n\t\t\t// Apply Wiener Filter\n\t\t\tcalculator.Iterate(inputImage, windowSize, [&](const double& mean, const double& variance, const int& position)\n\t\t\t{\n\t\t\t\t// The avgVariance is simulating noise-variance.  It should always be greater than variance.\n\t\t\t\toutputImage.data[position] = variance < avgVariance ?\n\t\t\t\t\tmean : // Variance can be 0, so avoid the divide by 0 issue by using mean value.\n\t\t\t\t\tmean + ((variance - avgVariance) * (double)(inputImage.data[position] - mean)) / variance;\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //WIENERFILTER_HPP\n"
  },
  {
    "path": "Doxa/Wolf.hpp",
    "content": "// Δoxa Binarization Framework\n// License: CC0 2018, \"Freely you have received; freely give.\" - Matt 10:8\n#ifndef WOLF_HPP\n#define WOLF_HPP\n\n#include \"Algorithm.hpp\"\n#include \"LocalWindow.hpp\"\n#include \"ChanMeanVarianceCalc.hpp\"\n\n\nnamespace Doxa\n{\n\t/// <summary>\n\t/// The Wolf Algorithm: Christian Wolf, Jean-Michel Jolion\n\t/// </summary>\n\t/// <remarks>\"Extraction and Recognition of Artificial Text in Multimedia Documents\", 2003.</remarks>\n\tclass Wolf : public Algorithm<Wolf>, public ChanMeanVarianceCalc\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tdouble min = std::numeric_limits<double>::max();\n\t\t\tdouble maxVariance = std::numeric_limits<double>::min();\n\n\t\t\t// Find global min value and max standard deviation value\n\t\t\tIterate(Algorithm::grayScaleImageIn, windowSize, [&](const double&, const double& variance, const int& position) {\n\t\t\t\t\n\t\t\t\tif (variance > maxVariance) maxVariance = variance;\n\n\t\t\t\tconst double tmpMin = Algorithm::grayScaleImageIn.data[position];\n\t\t\t\tif (tmpMin < min) min = tmpMin;\n\t\t\t});\n\n\t\t\tconst double maxStdDev = std::sqrt(maxVariance);\n\n\t\t\tProcess(binaryImageOut, Algorithm::grayScaleImageIn, windowSize, [&](const double& mean, const double& variance, const int& position) {\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn mean - k * (1 - (stddev / maxStdDev)) * (mean - min);\n\t\t\t});\n\t\t}\n\t};\n}\n\n\n#endif //WOLF_HPP\n"
  },
  {
    "path": "Doxa.Bench/BenchmarkHarness.hpp",
    "content": "#ifndef BENCHMARKHARNESS_HPP\n#define BENCHMARKHARNESS_HPP\n\n#include \"pch.h\"\n#include \"config.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\t// Exposes GlobalThreshold internals for benchmarking\n\tclass GlobalThresholdBenchHarness : public GlobalThreshold<GlobalThresholdBenchHarness>\n\t{\n\t\tPixel8 Threshold(const Image& grayScaleImage, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\treturn 128;\n\t\t}\n\t};\n\n\t// Exposes DRDM internals for benchmarking\n\tclass DRDMBenchHarness : public Doxa::DRDM\n\t{\n\tpublic:\n\t\tusing DRDM::NUBN_STD;\n\t\tusing DRDM::NUBN_STD_8x8;\n\t\tusing DRDM::SumDRDkForMismatchedPixels;\n\n\t\t#if defined(DOXA_SIMD)\n\t\t\tusing DRDM::NUBN_SIMD_8x8;\n\t\t#endif\n\t};\n\n\t// Switchable calculator backend for Niblack, used to benchmark calculators\n\ttemplate<typename Calculator>\n\tclass NiblackBase : public Algorithm<NiblackBase<Calculator>>, public Calculator\n\t{\n\tpublic:\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tCalculator::Process(binaryImageOut, Algorithm<NiblackBase<Calculator>>::grayScaleImageIn, windowSize,\n\t\t\t\t[&](const double& mean, const double& variance, const int&) {\n\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn (mean + (k * stddev));\n\t\t\t});\n\t\t}\n\t};\n\n\t// Resource path helper\n\tinline std::string ResourcesDir()\n\t{\n\t\treturn std::string(DOXA_BENCH_RESOURCES_DIR) + \"/\";\n\t}\n}\n\n#endif // BENCHMARKHARNESS_HPP\n"
  },
  {
    "path": "Doxa.Bench/BinarizationBenchmarks.cpp",
    "content": "#include \"pch.h\"\n#include \"BenchmarkHarness.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\tstatic Image ReadTestImage()\n\t{\n\t\treturn PNM::Read(ResourcesDir() + \"2JohnC1V3.ppm\", ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t}\n\n\t// --- Global Thresholding ---\n\n\tstatic void BM_Otsu(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Otsu::ToBinaryImage(image);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Otsu);\n\n\t// --- Local Adaptive Thresholding ---\n\n\tstatic void BM_Niblack(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Niblack::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Niblack);\n\n\tstatic void BM_Sauvola(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Sauvola::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Sauvola);\n\n\tstatic void BM_Wolf(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Wolf::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Wolf);\n\n\tstatic void BM_Nick(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", -0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Nick::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Nick);\n\n\tstatic void BM_Bernsen(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"threshold\", 100 }, { \"contrast-limit\", 25 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Bernsen::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Bernsen);\n\n\tstatic void BM_TRSingh(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = TRSingh::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_TRSingh);\n\n\tstatic void BM_Wan(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Wan::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Wan);\n\n\tstatic void BM_Gatos(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Gatos::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Gatos);\n\n\tstatic void BM_ISauvola(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = ISauvola::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_ISauvola);\n\n\tstatic void BM_Su(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Su::ToBinaryImage(image);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Su);\n\n\tstatic void BM_Bataineh(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Bataineh::ToBinaryImage(image);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Bataineh);\n\n\tstatic void BM_Phansalkar(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = Phansalkar::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Phansalkar);\n\n\tstatic void BM_AdOtsu(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = AdOtsu::ToBinaryImage(image);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_AdOtsu);\n\n\tstatic void BM_AdOtsuMS(benchmark::State& state)\n\t{\n\t\tconst Image image = ReadTestImage();\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = AdOtsuMS::ToBinaryImage(image);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_AdOtsuMS);\n\n} // namespace Doxa::Benchmarks\n"
  },
  {
    "path": "Doxa.Bench/CMakeLists.txt",
    "content": "message(STATUS \"Doxa Bench - CMake Build\")\n\ncmake_minimum_required(VERSION 3.16)\nproject(doxa_bench)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# SIMD Options\noption(DOXA_ENABLE_SIMD \"Enable SIMD optimizations (compile all paths, runtime detection)\" ON)\n\nif(MSVC)\n    # so far so good\nelse()\n    add_compile_options(\"-Wno-narrowing\")\nendif()\n\ninclude(FetchContent)\nFetchContent_Declare(\n  googlebenchmark\n  URL https://github.com/google/benchmark/archive/refs/tags/v1.9.1.zip\n)\nset(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL \"\" FORCE)\nset(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL \"\" FORCE)\nFetchContent_MakeAvailable(googlebenchmark)\n\ninclude_directories(../Doxa)\n\n# Resolve absolute path to test resources (shared with Doxa.Test)\nget_filename_component(DOXA_RESOURCES_DIR \"${CMAKE_CURRENT_SOURCE_DIR}/../Doxa.Test/Resources\" ABSOLUTE)\nconfigure_file(config.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/config.hpp @ONLY)\n\nadd_executable(\n  doxa_bench\n  GlobalThresholdBenchmarks.cpp\n  ClassifiedPerformanceBenchmarks.cpp\n  DRDMBenchmarks.cpp\n  CalculatorBenchmarks.cpp\n  BinarizationBenchmarks.cpp\n)\n\ntarget_include_directories(doxa_bench PRIVATE ${CMAKE_CURRENT_BINARY_DIR})\n\n# Platform detection and SIMD compiler flags\nif(DOXA_ENABLE_SIMD)\n    message(STATUS \"SIMD optimizations: ENABLED (runtime detection)\")\n\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64|AMD64|x64\")\n        if(MSVC)\n            message(STATUS \"SIMD: x86-64 with SSE2 (MSVC)\")\n        else()\n            target_compile_options(doxa_bench PRIVATE -msse2)\n            message(STATUS \"SIMD: x86-64 with SSE2 (GCC/Clang)\")\n        endif()\n\n    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|ARM64\")\n        message(STATUS \"SIMD: ARM64 with NEON\")\n\n    elseif(EMSCRIPTEN)\n        target_compile_options(doxa_bench PRIVATE -msimd128)\n        message(STATUS \"SIMD: WebAssembly with SIMD128\")\n\n    else()\n        message(STATUS \"SIMD: Unknown platform, will use scalar fallback\")\n    endif()\n\nelse()\n    message(STATUS \"SIMD optimizations: DISABLED (scalar only)\")\nendif()\n\ntarget_precompile_headers(\n  doxa_bench\n  PUBLIC\n    pch.h\n)\n\ntarget_link_libraries(\n  doxa_bench\n  benchmark::benchmark\n  benchmark::benchmark_main\n)\n\nmessage(STATUS \"Compiler: ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_VERSION}\")\nmessage(STATUS \"Build type: ${CMAKE_BUILD_TYPE}\")\nmessage(STATUS \"System processor: ${CMAKE_SYSTEM_PROCESSOR}\")\nmessage(STATUS \"Resources: ${DOXA_RESOURCES_DIR}\")\n"
  },
  {
    "path": "Doxa.Bench/CalculatorBenchmarks.cpp",
    "content": "#include \"pch.h\"\n#include \"BenchmarkHarness.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\tstatic void BM_Niblack_Chan(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage image = PNM::Read(dir + \"2JohnC1V3.ppm\", ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t\tconst Parameters parameters({ { \"window\", 223 }, { \"k\", -0.61 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = NiblackBase<ChanMeanVarianceCalc>::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Niblack_Chan);\n\n\tstatic void BM_Niblack_IntegralImage(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage image = PNM::Read(dir + \"2JohnC1V3.ppm\", ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t\tconst Parameters parameters({ { \"window\", 223 }, { \"k\", -0.61 } });\n\n\t\tfor (auto _ : state) {\n\t\t\tImage result = NiblackBase<IntegralImageMeanVarianceCalc>::ToBinaryImage(image, parameters);\n\t\t\tbenchmark::DoNotOptimize(result.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_Niblack_IntegralImage);\n\n} // namespace Doxa::Benchmarks\n"
  },
  {
    "path": "Doxa.Bench/ClassifiedPerformanceBenchmarks.cpp",
    "content": "#include \"pch.h\"\n#include \"BenchmarkHarness.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\tstatic void BM_CompareImages_Scalar(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage binaryImage = PNM::Read(dir + \"2JohnC1V3-Sauvola.pbm\");\n\t\tImage groundTruthImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tClassifiedPerformance::Classifications classifications;\n\t\t\tClassifiedPerformance::CompareImages_STD(classifications, groundTruthImage.data, binaryImage.data, groundTruthImage.size);\n\t\t\tbenchmark::DoNotOptimize(classifications);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * groundTruthImage.size);\n\t}\n\tBENCHMARK(BM_CompareImages_Scalar);\n\n\n#if defined(DOXA_SIMD)\n\n\tstatic void BM_CompareImages_SIMD(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage binaryImage = PNM::Read(dir + \"2JohnC1V3-Sauvola.pbm\");\n\t\tImage groundTruthImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tClassifiedPerformance::Classifications classifications;\n\t\t\tClassifiedPerformance::CompareImages_SIMD(classifications, groundTruthImage.data, binaryImage.data, groundTruthImage.size);\n\t\t\tbenchmark::DoNotOptimize(classifications);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * groundTruthImage.size);\n\t}\n\tBENCHMARK(BM_CompareImages_SIMD);\n\n#endif // DOXA_SIMD\n\n} // namespace Doxa::Benchmarks\n"
  },
  {
    "path": "Doxa.Bench/DRDMBenchmarks.cpp",
    "content": "#include \"pch.h\"\n#include \"BenchmarkHarness.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\tstatic void BM_NUBN_STD(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage binaryImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tunsigned int count = DRDMBenchHarness::NUBN_STD(binaryImage, 8);\n\t\t\tbenchmark::DoNotOptimize(count);\n\t\t}\n\t}\n\tBENCHMARK(BM_NUBN_STD);\n\n\tstatic void BM_NUBN_STD_8x8(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage binaryImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tunsigned int count = DRDMBenchHarness::NUBN_STD_8x8(binaryImage);\n\t\t\tbenchmark::DoNotOptimize(count);\n\t\t}\n\t}\n\tBENCHMARK(BM_NUBN_STD_8x8);\n\n\tstatic void BM_SumDRDk(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage controlImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\t\tImage experimentImage = PNM::Read(dir + \"2JohnC1V3-Sauvola.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tuint64_t result = DRDMBenchHarness::SumDRDkForMismatchedPixels(controlImage, experimentImage);\n\t\t\tbenchmark::DoNotOptimize(result);\n\t\t}\n\t}\n\tBENCHMARK(BM_SumDRDk);\n\n\t\n#if defined(DOXA_SIMD)\n\n\tstatic void BM_NUBN_SIMD_8x8(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage binaryImage = PNM::Read(dir + \"2JohnC1V3-GroundTruth.pbm\");\n\n\t\tfor (auto _ : state) {\n\t\t\tunsigned int count = DRDMBenchHarness::NUBN_SIMD_8x8(binaryImage);\n\t\t\tbenchmark::DoNotOptimize(count);\n\t\t}\n\t}\n\tBENCHMARK(BM_NUBN_SIMD_8x8);\n\n#endif // DOXA_SIMD\n\n} // namespace Doxa::Benchmarks\n"
  },
  {
    "path": "Doxa.Bench/GlobalThresholdBenchmarks.cpp",
    "content": "#include \"pch.h\"\n#include \"BenchmarkHarness.hpp\"\n\n\nnamespace Doxa::Benchmarks\n{\n\tstatic void BM_GlobalThreshold_Scalar(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage image = PNM::Read(dir + \"2JohnC1V3.ppm\", ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t\tImage binary(image.width, image.height);\n\t\tconst Pixel8 threshold = 128;\n\n\t\tfor (auto _ : state) {\n\t\t\tGlobalThresholdBenchHarness::ToBinary_STD(image.data, binary.data, image.size, threshold);\n\t\t\tbenchmark::DoNotOptimize(binary.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_GlobalThreshold_Scalar);\n\n\t\n#if defined(DOXA_SIMD)\n\n\tstatic void BM_GlobalThreshold_SIMD(benchmark::State& state)\n\t{\n\t\tconst std::string dir = ResourcesDir();\n\t\tImage image = PNM::Read(dir + \"2JohnC1V3.ppm\", ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t\tImage binary(image.width, image.height);\n\t\tconst Pixel8 threshold = 128;\n\n\t\tfor (auto _ : state) {\n\t\t\tGlobalThresholdBenchHarness::ToBinary_SIMD(image.data, binary.data, image.size, threshold);\n\t\t\tbenchmark::DoNotOptimize(binary.data);\n\t\t}\n\n\t\tstate.SetBytesProcessed(int64_t(state.iterations()) * image.size);\n\t}\n\tBENCHMARK(BM_GlobalThreshold_SIMD);\n\n#endif // DOXA_SIMD\n\n} // namespace Doxa::Benchmarks\n"
  },
  {
    "path": "Doxa.Bench/config.hpp.in",
    "content": "#pragma once\n#define DOXA_BENCH_RESOURCES_DIR \"@DOXA_RESOURCES_DIR@\"\n"
  },
  {
    "path": "Doxa.Bench/pch.h",
    "content": "//\n// pch.h\n//\n\n#pragma once\n#include <vector>\n#include <string>\n#include <cmath>\n\n#include <SIMD.h>\n#include <SIMDOps.hpp>\n#include <PNM.hpp>\n#include <Algorithm.hpp>\n#include <BinarizationFactory.hpp>\n#include <ChanMeanVarianceCalc.hpp>\n#include <IntegralImageMeanVarianceCalc.hpp>\n#include <ClassifiedPerformance.hpp>\n#include <DRDM.hpp>\n\n#include <benchmark/benchmark.h>\n"
  },
  {
    "path": "Doxa.Test/AlgorithmTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass AlgorithmTests : public ::testing::Test {\n\tprotected:\n\t\tconst Pixel8 input[4] = {\n\t\t\tPalette::Black, Palette::White,\n\t\t\tPalette::White, Palette::Black\n\t\t};\n\n\t\tconst Pixel8 expected[4] = {\n\t\t\tPalette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::Black\n\t\t};\n\t};\n\n\t// A dummy binarization algorithm that turns everything black\n\tclass BinarizationTestharness : public Algorithm<BinarizationTestharness>\n\t{\n\tpublic:\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// NOTE: Linker unable to find Palette:Black on Linux with Clang and G++\n\t\t\tstd::fill_n(binaryImageOut.data, binaryImageOut.size, 0/* Palette::Black */);\n\t\t}\n\t};\n\n\tTEST_F(AlgorithmTests, AlgorithmToBinaryTest)\n\t{\n\t\t// Obtain 2x2 Gray Scale Image\n\t\tconst Image grayScaleImageIn(2, 2, input);\n\n\t\t// Initialize the memory for our 2x2 Binary Image\n\t\tImage binaryImageOut(grayScaleImageIn.width, grayScaleImageIn.height);\n\n\t\t// Execute our method under test\n\t\tBinarizationTestharness algorithm;\n\t\talgorithm.Initialize(grayScaleImageIn);\n\t\talgorithm.ToBinary(binaryImageOut);\n\n\t\t// Assert correctness\n\t\tTestUtilities::AssertImageData(binaryImageOut, expected);\n\t}\n\n\tTEST_F(AlgorithmTests, AlgorithmToBinaryImageTest)\n\t{\n\t\t// Obtain 2x2 Gray Scale Image\n\t\tconst Image grayScaleImageIn(2, 2, input);\n\n\t\t// Execute our method under test\n\t\tImage binaryImageOut = BinarizationTestharness::ToBinaryImage(grayScaleImageIn, Parameters());\n\n\t\t// Assert correctness\n\t\tTestUtilities::AssertImageData(binaryImageOut, expected);\n\t}\n\n\tTEST_F(AlgorithmTests, AlgorithmUpdateToBinaryTest)\n\t{\n\t\t// Obtain 2x2 Gray Scale Image\n\t\tImage image(2, 2, input);\n\n\t\t// Execute our method under test\n\t\tBinarizationTestharness::UpdateToBinary(image);\n\n\t\t// Assert correctness\n\t\tTestUtilities::AssertImageData(image, expected);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/BatainehTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\t// Exposes protected members for Unit Testing\n\tclass BatainehTestharness : public Bataineh\n\t{\n\tpublic:\n\t\tBatainehTestharness() : Bataineh() {}\n\t\tusing Bataineh::GetMaxGrayValue;\n\t\tusing Bataineh::ConfusionThreshold;\n\t\tusing Bataineh::RedBlack;\n\t\tusing Bataineh::PrimaryWindow;\n\t\tusing Bataineh::GetWindows;\n\t\tusing Bataineh::SigmaMinMaxAndMean;\n\t\tusing Bataineh::SigmaAdaptive;\n\t\tusing Bataineh::WindowThreshold;\n\t\tusing Bataineh::CalculateMeanStdDev;\n\n\t\tusing Bataineh::DetailedWindow;\n\n\t\t/// <summary>\n\t\t/// A method that draws the bottom, and right side of every window onto the image.\n\t\t/// </summary>\n\t\t/// <returns>An Image with window outlines</returns>\n\t\tImage GenerateWindowImage(const Image& image, const std::vector<BatainehTestharness::DetailedWindow>& windows)\n\t\t{\n\t\t\tImage windowImage(image); // Make a deep copy\n\n\t\t\tfor (auto it = windows.begin(); it != windows.end(); ++it)\n\t\t\t{\n\t\t\t\t// Draw bottom horizontal bar\n\t\t\t\tfor (int x = it->window.upperLeft.x; x < it->window.bottomRight.x; ++x)\n\t\t\t\t{\n\t\t\t\t\twindowImage.Pixel(x, it->window.bottomRight.y) = 75;\n\t\t\t\t}\n\n\t\t\t\t// Draw right vertical bar\n\t\t\t\tfor (int y = it->window.upperLeft.y; y < it->window.bottomRight.y; ++y)\n\t\t\t\t{\n\t\t\t\t\twindowImage.Pixel(it->window.bottomRight.x, y) = 75;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn windowImage;\n\t\t}\n\t};\n\n\tTEST(BatainehTests, BatainehToBinaryTest)\n\t{\n\t\t// Note: This algorithm, nor the numbers asserted, may be correct.\n\t\t// This test is mainly used, for now, to analyze the characteristics of an image\n\t\t// If you just want image details - turn off the assertions.\n\t\tbool enableAssertions = true;\n\t\tSUCCEED() << \"Bataineh Algorithm Analysis\";\n\n\t\t// Setup\n\t\tconst std::string filePath = TestUtilities::ProjectFolder() + \"2JohnC1V3.ppm\";\n\t\tconst Image grayScaleImage = PNM::Read(filePath, ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::BT601} });\n\t\tBatainehTestharness bataineh;\n\t\tbataineh.Initialize(grayScaleImage);\n\n\t\t// Get global std-dev and mean values\n\t\tdouble sigmaGlobal;\n\t\tdouble meanGlobal;\n\t\tbataineh.CalculateMeanStdDev(meanGlobal, sigmaGlobal, Region(grayScaleImage.width, grayScaleImage.height));\n\t\tif (enableAssertions) EXPECT_NEAR(31.6197, sigmaGlobal, 0.001);\n\t\tif (enableAssertions) EXPECT_NEAR(186.3858, meanGlobal, 0.001);\n\t\tSUCCEED() << \"Mg = \" << meanGlobal << \", Sg = \" << sigmaGlobal;\n\n\t\t// Get Max Gray Value\n\t\tconst Pixel8 maxGrayValue = bataineh.GetMaxGrayValue();\n\t\tif (enableAssertions) EXPECT_EQ((Pixel8)222, maxGrayValue);\n\t\tSUCCEED() << \"MAXlevel = \" << maxGrayValue;\n\n\t\t// Calculate Confusion Threshold\n\t\tconst double confThreshold = bataineh.ConfusionThreshold(meanGlobal, sigmaGlobal, maxGrayValue);\n\t\tif (enableAssertions) EXPECT_NEAR(151.0563, confThreshold, 0.001);\n\t\tSUCCEED() << \"Tc = \" << confThreshold;\n\n\t\t// Find total Red and Black pixels\n\t\tImage rbwImage(grayScaleImage.width, grayScaleImage.height);\n\t\tint redCountImage;\n\t\tint blackCountImage;\n\t\tbataineh.RedBlack(redCountImage, blackCountImage, rbwImage, confThreshold, sigmaGlobal);\n\t\tif (enableAssertions) EXPECT_EQ(19513, redCountImage);\n\t\tif (enableAssertions) EXPECT_EQ(34320, blackCountImage);\n\t\tSUCCEED() << \"REDg = \" << redCountImage << \", BLACKg = \" << blackCountImage;\n\n\t\t// Create a Red Black White image for analysis\n\t\tPNM::Write(rbwImage, TestUtilities::ProjectFolder() + \"2JohnC1V3-Bataineh-RBW.pgm\");\n\n\t\t// Calculate P Value - helps determine window size\n\t\tdouble p = (double)blackCountImage / redCountImage;\n\t\tSUCCEED() << \"p = \" << p;\n\n\t\t// Calculate the Primary Window size\n\t\tint primaryWindowWidth;\n\t\tint primaryWindowHeight;\n\t\tbataineh.PrimaryWindow(primaryWindowWidth, primaryWindowHeight,\n\t\t\tp,\n\t\t\tsigmaGlobal,\n\t\t\tmaxGrayValue,\n\t\t\trbwImage.width,\n\t\t\trbwImage.height\n\t\t);\n\t\tif (enableAssertions) EXPECT_EQ(23, primaryWindowWidth);\n\t\tif (enableAssertions) EXPECT_EQ(22, primaryWindowHeight);\n\t\tSUCCEED() << \"PWw = \" << primaryWindowWidth << \", PWh = \" << primaryWindowHeight;\n\n\t\t// Break the image into Primary and Secondary windows\n\t\tstd::vector<BatainehTestharness::DetailedWindow> windows = bataineh.GetWindows(rbwImage, blackCountImage, redCountImage, sigmaGlobal, maxGrayValue);\n\t\tif (enableAssertions) EXPECT_EQ((size_t)1121, windows.size());\n\t\tSUCCEED() << \"PW & SW Count = \" << windows.size();\n\n\t\t// Create a window breakdown image for analysis\n\t\tImage windowImage = bataineh.GenerateWindowImage(rbwImage, windows);\n\t\tPNM::Write(windowImage, TestUtilities::ProjectFolder() + \"2JohnC1V3-Bataineh-Windows.pgm\");\n\n\t\t// Get Sigma Max and Min as well as local window Sigma and Mean\n\t\tdouble sigmaMax;\n\t\tdouble sigmaMin;\n\t\tbataineh.SigmaMinMaxAndMean(sigmaMin, sigmaMax, windows);\n\t\t// Note: Values calculated with Population Variance\n\t\tif (enableAssertions) EXPECT_NEAR(0.7890, sigmaMin, 0.001);\n\t\tif (enableAssertions) EXPECT_NEAR(52.6966, sigmaMax, 0.001);\n\t\tSUCCEED() << \"Smin = \" << sigmaMin << \", Smax = \" << sigmaMax;\n\n\t\t// Get a target Window and analyze it\n\t\tSUCCEED() << \"First Window Details:\";\n\n\t\tBatainehTestharness::DetailedWindow detailedWindow = windows.front(); // First Window\n\t\tif (enableAssertions) EXPECT_NEAR(185.8893, detailedWindow.mean, 0.001);\n\t\tif (enableAssertions) EXPECT_NEAR(26.9451, detailedWindow.stddev, 0.001);\n\t\tSUCCEED() << \"Mw = \" << detailedWindow.mean << \", Sw = \" << detailedWindow.stddev;\n\n\t\tif (enableAssertions) EXPECT_EQ(23, detailedWindow.window.Width());\n\t\tif (enableAssertions) EXPECT_EQ(22, detailedWindow.window.Height());\n\t\tSUCCEED() << \"Ww = \" << detailedWindow.window.Width() << \", Wh = \" << detailedWindow.window.Height();\n\n\t\tconst double sigmaAdaptive = bataineh.SigmaAdaptive(detailedWindow.stddev, sigmaMin, sigmaMax, maxGrayValue);\n\t\tif (enableAssertions) EXPECT_NEAR(111.865, sigmaAdaptive, 0.001);\n\t\tSUCCEED() << \"Sadaptive = \" << sigmaAdaptive;\n\n\t\tconst Pixel8 threshold = bataineh.WindowThreshold(detailedWindow.mean, meanGlobal, detailedWindow.stddev, sigmaAdaptive);\n\t\tif (enableAssertions) EXPECT_EQ((Pixel8)168, threshold);\n\t\tSUCCEED() << \"Tw = \" << threshold;\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/BinarizationTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n#include \"ImageFixture.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass BinarizationTests : public ImageFixture {};\n\n\tTEST_F(BinarizationTests, BinarizationSauvolaTest)\n\t{\n\t\tconst Parameters parameters({ {\"window\", 27}, {\"k\", 0.10} });\n\n\t\tImage imageSauvola = Sauvola::ToBinaryImage(image, parameters);\n\n\t\tImage imageSauvola2(image);\n\t\tSauvola::UpdateToBinary(imageSauvola2, parameters);\n\n\t\tTestUtilities::AssertImages(imageSauvola, imageSauvola2);\n\t\tTestUtilities::AssertImageFile(imageSauvola, projFolder + \"2JohnC1V3-Sauvola.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationNiblackTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 223 }, { \"k\", -0.61 } });\n\n\t\tImage imageNiblack = Niblack::ToBinaryImage(image, parameters);\n\n\t\tImage imageNiblack2(image);\n\t\tNiblack::UpdateToBinary(imageNiblack2, parameters);\n\n\t\tTestUtilities::AssertImages(imageNiblack, imageNiblack2);\n\t\tTestUtilities::AssertImageFile(imageNiblack, projFolder + \"2JohnC1V3-Niblack.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationWolfTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 21 }, { \"k\", 0.18 } });\n\n\t\tImage imageWolf = Wolf::ToBinaryImage(image, parameters);\n\n\t\tImage imageWolf2(image);\n\t\tWolf::UpdateToBinary(imageWolf2, parameters);\n\n\t\tTestUtilities::AssertImages(imageWolf, imageWolf2);\n\t\tTestUtilities::AssertImageFile(imageWolf, projFolder + \"2JohnC1V3-Wolf.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationNICKTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 45 }, { \"k\", -0.10 } });\n\n\t\tImage imageNICK = Nick::ToBinaryImage(image, parameters);\n\n\t\tImage imageNICK2(image);\n\t\tNick::UpdateToBinary(imageNICK2, parameters);\n\n\t\tTestUtilities::AssertImages(imageNICK, imageNICK2);\n\t\tTestUtilities::AssertImageFile(imageNICK, projFolder + \"2JohnC1V3-NICK.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationBernsenTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 61 }, { \"threshold\", 150 }, {\"contrast-limit\", 25} });\n\n\t\tImage imageBernsen = Bernsen::ToBinaryImage(image, parameters);\n\n\t\tImage imageBernsen2(image);\n\t\tBernsen::UpdateToBinary(imageBernsen2, parameters);\n\n\t\tTestUtilities::AssertImages(imageBernsen, imageBernsen2);\n\t\tTestUtilities::AssertImageFile(imageBernsen, projFolder + \"2JohnC1V3-Bensen.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationTRSinghTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 27 }, { \"k\", 0.1 } });\n\n\t\tImage imageTRSingh = TRSingh::ToBinaryImage(image, parameters);\n\n\t\tImage imageTRSingh2(image);\n\t\tTRSingh::UpdateToBinary(imageTRSingh2, parameters);\n\n\t\tTestUtilities::AssertImages(imageTRSingh, imageTRSingh2);\n\t\tTestUtilities::AssertImageFile(imageTRSingh, projFolder + \"2JohnC1V3-TRSingh.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationWANTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tImage imageWAN = Wan::ToBinaryImage(image, parameters);\n\n\t\tImage imageWAN2(image);\n\t\tWan::UpdateToBinary(imageWAN2, parameters);\n\n\t\tTestUtilities::AssertImages(imageWAN, imageWAN2);\n\t\tTestUtilities::AssertImageFile(imageWAN, projFolder + \"2JohnC1V3-WAN.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationGatosTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 75 }, { \"k\", 0.2 } });\n\n\t\tImage imageGatos = Gatos::ToBinaryImage(image, parameters);\n\n\t\tImage imageGatos2(image);\n\t\tGatos::UpdateToBinary(imageGatos2, parameters);\n\n\t\tTestUtilities::AssertImages(imageGatos, imageGatos2);\n\t\tTestUtilities::AssertImageFile(imageGatos, projFolder + \"2JohnC1V3-Gatos.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationSuTest)\n\t{\n\t\tImage imageSu = Su::ToBinaryImage(image);\n\n\t\t// Ensure the auto parameters are understood\n\t\tImage contrastImage(image.width, image.height);\n\t\tContrastImage::GenerateContrastImage(contrastImage, image);\n\t\tstd::cout << \"Stroke: \" << ContrastImage::EstimateStrokeWidth(image) << std::endl;\n\n\t\tImage imageSu2(image);\n\t\tSu::UpdateToBinary(imageSu2);\n\n\t\tTestUtilities::AssertImages(imageSu, imageSu2);\n\t\tTestUtilities::AssertImageFile(imageSu, projFolder + \"2JohnC1V3-Su.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationISauvola)\n\t{\n\t\tconst Parameters parameters({ {\"window\", 15}, {\"k\", 0.01} });\n\n\t\tImage imageISauvola = ISauvola::ToBinaryImage(image, parameters);\n\n\t\tImage imageISauvola2(image);\n\t\tISauvola::UpdateToBinary(imageISauvola2, parameters);\n\n\t\tTestUtilities::AssertImages(imageISauvola, imageISauvola2);\n\t\tTestUtilities::AssertImageFile(imageISauvola, projFolder + \"2JohnC1V3-ISauvola.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationOtsuTest)\n\t{\n\t\tImage imageOtsu = Otsu::ToBinaryImage(image);\n\n\t\tImage imageOtsu2(image);\n\t\tOtsu::UpdateToBinary(imageOtsu2);\n\n\t\tTestUtilities::AssertImages(imageOtsu, imageOtsu2);\n\t\tTestUtilities::AssertImageFile(imageOtsu, projFolder + \"2JohnC1V3-Otsu.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationAdOtsuTest)\n\t{\n\t\t// AdOtsu\n\t\tParameters param({ {\"distance\", 0} }); // Disable Grid Optimization\n\t\tImage imageAdOtsu = AdOtsu::ToBinaryImage(image, param);\n\t\tTestUtilities::AssertImageFile(imageAdOtsu, projFolder + \"2JohnC1V3-AdOtsu.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationAdOtsuGTest)\n\t{\n\t\t// AdOtsu /w Grid Optimization\n\t\tImage imageAdOtsuG = AdOtsu::ToBinaryImage(image);\n\n\t\tImage imageAdOtsuG2(image);\n\t\tAdOtsu::UpdateToBinary(imageAdOtsuG2);\n\n\t\tTestUtilities::AssertImages(imageAdOtsuG, imageAdOtsuG2);\n\t\tTestUtilities::AssertImageFile(imageAdOtsuG, projFolder + \"2JohnC1V3-AdOtsuG.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationAdOtsuMSTest)\n\t{\n\t\t// AdOtsu /w Multi-Scale\n\t\tParameters param({ {\"distance\", 0} }); // Disable Grid Optimization\n\t\tImage imageAdOtsuMS = AdOtsuMS::ToBinaryImage(image, param);\n\t\tTestUtilities::AssertImageFile(imageAdOtsuMS, projFolder + \"2JohnC1V3-AdOtsuMS.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationAdOtsuMSGTest)\n\t{\n\t\t// AdOtsu /w Multi-Scale Grid\n\t\tImage imageAdOtsuMSG = AdOtsuMS::ToBinaryImage(image);\n\t\tTestUtilities::AssertImageFile(imageAdOtsuMSG, projFolder + \"2JohnC1V3-AdOtsuMSG.pbm\");\n\t}\n\n\tTEST_F(BinarizationTests, BinarizationPhansalkarTest)\n\t{\n\t\tconst Parameters parameters({ {\"window\", 27}, {\"k\", 0.10} });\n\n\t\tImage imagePhansalkar = Phansalkar::ToBinaryImage(image, parameters);\n\n\t\tImage imagePhansalkar2(image);\n\t\tPhansalkar::UpdateToBinary(imagePhansalkar2, parameters);\n\n\t\tTestUtilities::AssertImages(imagePhansalkar, imagePhansalkar2);\n\t\tTestUtilities::AssertImageFile(imagePhansalkar, projFolder + \"2JohnC1V3-Phansalkar.pbm\");\n\t}\n\n\n\tTEST_F(BinarizationTests, BinarizationBatainehTest)\n\t{\n\t\tImage imageBataineh = Bataineh::ToBinaryImage(image);\n\n\t\tImage imageBataineh2(image);\n\t\tBataineh::UpdateToBinary(imageBataineh2);\n\n\t\tTestUtilities::AssertImages(imageBataineh, imageBataineh2);\n\t\tTestUtilities::AssertImageFile(imageBataineh, projFolder + \"2JohnC1V3-Bataineh.pbm\");\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/CMakeLists.txt",
    "content": "message(STATUS \"Doxa Test - CMake Build\")\n\ncmake_minimum_required(VERSION 3.16)\nproject(doxa_test)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# SIMD Options\noption(DOXA_ENABLE_SIMD \"Enable SIMD optimizations (compile all paths, runtime detection)\" ON)\n\nif(MSVC)\n    # so far so good\nelse()\n    add_compile_options(\"-Wno-narrowing\")\nendif()\n\ninclude(FetchContent)\nFetchContent_Declare(\n  googletest\n  URL https://github.com/google/googletest/archive/refs/tags/v1.16.0.zip\n)\n# For Windows: Prevent overriding the parent project's compiler/linker settings\nset(gtest_force_shared_crt ON CACHE BOOL \"\" FORCE)\nFetchContent_MakeAvailable(googletest)\n\nenable_testing()\n\ninclude_directories(../Doxa)\n\nadd_executable(\n  doxa_test\n  AlgorithmTests.cpp\n  BatainehTests.cpp\n  BinarizationTests.cpp\n  CalculatorTests.cpp\n  ContrastImageTests.cpp\n  GrayscaleTests.cpp\n  ImageTests.cpp\n  ISauvolaTests.cpp\n  LocalWindowTests.cpp\n  MorphologyTests.cpp\n  PaletteTests.cpp\n  ParametersTests.cpp\n  ClassifiedPerformanceTests.cpp\n  DRDMTests.cpp\n  PNMTests.cpp\n  DIBCOUtilsTests.cpp\n  RegionTests.cpp\n  SIMDTests.cpp\n  SuTests.cpp\n  WienerFilterTests.cpp\n)\n\n# Platform detection and SIMD compiler flags\nif(DOXA_ENABLE_SIMD)\n    message(STATUS \"SIMD optimizations: ENABLED (runtime detection)\")\n\n    # Detect platform and add appropriate flags\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64|AMD64|x64\")\n        # x86-64: SSE2 is always available (baseline for x64)\n        if(MSVC)\n            # MSVC x64: SSE2 is enabled by default, no special flags needed\n            message(STATUS \"SIMD: x86-64 with SSE2 (MSVC)\")\n        else()\n            # GCC/Clang: SSE2 is default for x64, but be explicit\n            target_compile_options(doxa_test PRIVATE -msse2)\n            message(STATUS \"SIMD: x86-64 with SSE2 (GCC/Clang)\")\n        endif()\n\n    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64|ARM64\")\n        # ARM64: NEON is always available, no special flags needed on GCC/Clang\n        # MSVC ARM64: NEON is enabled by default\n        message(STATUS \"SIMD: ARM64 with NEON\")\n\n    elseif(EMSCRIPTEN)\n        # WASM: Add SIMD128 flag\n        target_compile_options(doxa_test PRIVATE -msimd128)\n        message(STATUS \"SIMD: WebAssembly with SIMD128\")\n\n    else()\n        message(STATUS \"SIMD: Unknown platform, will use scalar fallback\")\n    endif()\n\nelse()\n    message(STATUS \"SIMD optimizations: DISABLED (scalar only)\")\nendif()\n\ntarget_precompile_headers(\n  doxa_test\n  PUBLIC\n    pch.h\n)\n\ntarget_link_libraries(\n  doxa_test\n  GTest::gtest_main\n)\n\ninclude(GoogleTest)\ngtest_discover_tests(\n  doxa_test\n  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}\n)\n\nmessage(STATUS \"Compiler: ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_VERSION}\")\nmessage(STATUS \"Build type: ${CMAKE_BUILD_TYPE}\")\nmessage(STATUS \"System processor: ${CMAKE_SYSTEM_PROCESSOR}\")"
  },
  {
    "path": "Doxa.Test/CalculatorTests.cpp",
    "content": "#include \"pch.h\"\n#include \"ImageFixture.hpp\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass CalculatorTests : public ImageFixture {};\n\n\t// A sample algorithm that will allow us to switch out the calculator seemlessly\n\t// The library does not use this pattern because there is no reason to ever use Integral Images.\n\ttemplate<typename Calculator>\n\tclass NiblackBase : public Algorithm<NiblackBase<Calculator>>, public Calculator\n\t{\n\tpublic:\n\n\t\tvoid ToBinary(Image& binaryImageOut, const Parameters& parameters = Parameters())\n\t\t{\n\t\t\t// Read parameters, utilizing defaults\n\t\t\tconst int windowSize = parameters.Get(\"window\", 75);\n\t\t\tconst double k = parameters.Get(\"k\", 0.2);\n\n\t\t\tCalculator::Process(binaryImageOut, Algorithm<NiblackBase<Calculator>>::grayScaleImageIn, windowSize, \n\t\t\t\t[&](const double& mean, const double& variance, const int&) {\n\n\t\t\t\tconst double stddev = std::sqrt(variance);\n\n\t\t\t\treturn (mean + (k * stddev));\n\t\t\t});\n\t\t}\n\t};\n\n\n\tTEST_F(CalculatorTests, CalculateIntegralImagesTest)\n\t{\n\t\t// Setup\n\t\tconst Pixel8 bits[] = {\n\t\t\tGrayscale::Qt(10, 20, 30), Grayscale::Qt(40, 50, 60), Grayscale::Qt(70, 80, 90),\n\t\t\tGrayscale::Qt(30, 40, 50), Grayscale::Qt(50, 05, 05), Grayscale::Qt(50, 30, 10),\n\t\t\tGrayscale::Qt(03, 05, 07), Grayscale::Qt(11, 13, 17), Grayscale::Qt(00, 25, 12)\n\t\t};\n\t\tImage image(3, 3, bits);\n\n\t\tconst IntegralImage integralImage = {\n\t\t\t18,  66, 144,\n\t\t\t56, 124, 235,\n\t\t\t60, 140, 265\n\t\t};\n\n\t\tconst IntegralImage integralSquareImage = {\n\t\t\t324, 2628,  8712,\n\t\t\t1768, 4472, 11645,\n\t\t\t1784, 4632, 12001\n\t\t};\n\n\t\t// Test Integral and Squared Integral Image Creation\n\t\tIntegralImageMeanVarianceCalc meanVarianceCalculator;\n\t\tIntegralImage testIntegralImage(integralImage.size());\n\t\tIntegralImage testIntegralSquareImage(integralSquareImage);\n\t\tmeanVarianceCalculator.BuildIntegralImages(testIntegralImage,testIntegralSquareImage, image);\n\n\t\t// Assert Single and Squared Integral Image Creation\n\t\tEXPECT_TRUE(testIntegralImage == integralImage);\n\t\tEXPECT_TRUE(testIntegralSquareImage == integralSquareImage);\n\t}\n\n\tTEST_F(CalculatorTests, CalculateProcessMeanVarianceTest)\n\t{\n\t\ttypedef std::vector< std::tuple<double, double> > meanVarianceVector;\n\n\t\t// Setup\n\t\tPixel8 bits[] = {\n\t\t\tGrayscale::Qt(10, 20, 30), Grayscale::Qt(40, 50, 60), Grayscale::Qt(70, 80, 90),\n\t\t\tGrayscale::Qt(30, 40, 50), Grayscale::Qt(50, 05, 05), Grayscale::Qt(50, 30, 10),\n\t\t\tGrayscale::Qt(03, 05, 07), Grayscale::Qt(11, 13, 17), Grayscale::Qt(00, 25, 12)\n\t\t};\n\t\tImage image(3, 3, bits);\n\t\tImage output(3, 3);\n\n\t\t// Output variables\n\t\tmeanVarianceVector meanVarianceII;\n\t\tmeanVarianceVector meanChan;\n\t\tmeanVarianceVector meanVarianceChan;\n\n\t\t// Integral Image Mean Variance\n\t\tIntegralImageMeanVarianceCalc meanVarianceCalculator;\n\t\tmeanVarianceCalculator.Process(output, image, 3, [&](const double& mean, const double& variance, const int&) {\n\t\t\tmeanVarianceII.push_back({ mean, variance });\n\t\t\treturn 0.0;\n\t\t});\n\n\t\t// Chan Mean Variance\n\t\tChanMeanVarianceCalc meanVarianceCalculatorChan;\n\t\tmeanVarianceCalculatorChan.Process(output, image, 3, [&](const double& mean, const double& variance, const int&) {\n\t\t\tmeanVarianceChan.push_back({ mean, variance });\n\t\t\treturn 0.0;\n\t\t});\n\n\t\t// Chan Mean\n\t\tChanMeanCalc meanCalculatorChan;\n\t\tmeanCalculatorChan.Process(output, image, 3, [&](const double& mean, const int&) {\n\t\t\tmeanChan.push_back({ mean, 0.0 });\n\t\t\treturn 0.0;\n\t\t});\n\n\t\t// Assert\n\t\tEXPECT_NEAR(std::get<0>(meanVarianceII.at(4)), 29.44, 0.01);\n\t\t// Note: If you use Sample Variance the value will be 524.77.  We are using Population Variance.\n\t\t//EXPECT_NEAR(std::get<1>(meanVarianceII.at(4)), 524.77, 0.01);\n\t\tEXPECT_NEAR(std::get<1>(meanVarianceII.at(4)), 466.469, 0.01);\n\t\tEXPECT_TRUE(meanVarianceII == meanVarianceChan);\n\t\t\t\n\t\tfor (int i = 0; i < image.size; ++i)\n\t\t{\n\t\t\tEXPECT_NEAR(std::get<0>(meanVarianceII.at(i)), std::get<0>(meanChan.at(i)), 0.01);\n\t\t}\n\t}\n\n\tTEST_F(CalculatorTests, CalculatorAlgorithmTest)\n\t{\n\t\tconst Parameters parameters({ { \"window\", 223 }, { \"k\", -0.61 } });\n\n\t\tImage imageNiblackChan = NiblackBase<ChanMeanVarianceCalc>::ToBinaryImage(image, parameters);\n\t\tImage imageNiblackII = NiblackBase<IntegralImageMeanVarianceCalc>::ToBinaryImage(image, parameters);\n\n\t\tTestUtilities::AssertImagesWithDetails(imageNiblackChan, imageNiblackII);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/ClassifiedPerformanceTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(ClassifiedPerformanceTests, PerformanceClassificationsTest)\n\t{\n\t\tClassifiedPerformance::Classifications classification;\n\t\tclassification.truePositive = 3;\n\t\tclassification.trueNegative = 5;\n\t\tclassification.falsePositive = 7;\n\t\tclassification.falseNegative = 11;\n\n\t\tEXPECT_EQ(classification.Total(), 26);\n\n\t\tclassification.Clear();\n\n\t\tEXPECT_EQ(classification.Total(), 0);\n\t}\n\n\tTEST(ClassifiedPerformanceTests, PerformanceTest)\n\t{\n\t\tImage control(3, 3);\n\t\tcontrol.Pixel(0, 0) = Palette::Black;\n\t\tcontrol.Pixel(1, 0) = Palette::White;\n\t\tcontrol.Pixel(2, 0) = Palette::Black;\n\t\tcontrol.Pixel(0, 1) = Palette::White;\n\t\tcontrol.Pixel(1, 1) = Palette::Black;\n\t\tcontrol.Pixel(2, 1) = Palette::White;\n\t\tcontrol.Pixel(0, 2) = Palette::Black;\n\t\tcontrol.Pixel(1, 2) = Palette::White;\n\t\tcontrol.Pixel(2, 2) = Palette::Black;\n\n\t\tImage experiment(3, 3);\n\t\texperiment.Pixel(0, 0) = Palette::Black;\n\t\texperiment.Pixel(1, 0) = Palette::White;\n\t\texperiment.Pixel(2, 0) = Palette::White; // False Negative\n\t\texperiment.Pixel(0, 1) = Palette::White;\n\t\texperiment.Pixel(1, 1) = Palette::Black;\n\t\texperiment.Pixel(2, 1) = Palette::White;\n\t\texperiment.Pixel(0, 2) = Palette::Black;\n\t\texperiment.Pixel(1, 2) = Palette::Black; // False Positive\n\t\texperiment.Pixel(2, 2) = Palette::Black;\n\n\t\t// Compare\n\t\tClassifiedPerformance::Classifications classifications;\n\t\tconst bool ret = ClassifiedPerformance::CompareImages(classifications, control, experiment);\n\t\tEXPECT_TRUE(ret);\n\n\t\t// Assert correctness\n\t\tEXPECT_EQ(classifications.truePositive, 4);\n\t\tEXPECT_EQ(classifications.trueNegative, 3);\n\t\tEXPECT_EQ(classifications.falsePositive, 1);\n\t\tEXPECT_EQ(classifications.falseNegative, 1);\n\n\t\t// Calculate Performance\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculateAccuracy(classifications), 77.777, 0.001);\n\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculateFMeasure(classifications), 80.0, 0.001);\n\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculatePSNR(classifications), 6.532, 0.001);\n\n\t\t// TODO - Calculate the NRM and verify\n\t\t//EXPECT_EQ(ClassifiedPerformance::CalculateNRM(classifications), 0.00);\n\t}\n\n\tTEST(PerformanceTests, PseudoMetrics)\n\t{\n\t\t// NOTE: Based off of 2018 DIBCO Metrics PR sample\n\t\tClassifiedPerformance::Classifications classification;\n\n\t\t/*\n\t\tstd::string projFolder = TestUtilities::ProjectFolder();\n\t\tauto precisionWeights = DIBCOUtils::ReadWeightsFile(projFolder + \"PR_PWeights.dat\");\n\t\tauto recallWeights = DIBCOUtils::ReadWeightsFile(projFolder + \"PR_RWeights.dat\");\n\t\tauto controlImage = PNM::Read(projFolder + \"PR_GT.pbm\");\n\t\tauto experimentImage = PNM::Read(projFolder + \"PR_bin.pbm\");\n\n\t\tClassifiedPerformance::CompareImages(classification, controlImage, experimentImage, precisionWeights, recallWeights);\n\t\t*/\n\n\t\tclassification.truePositive = 61573;\n\t\tclassification.trueNegative = 251404;\n\t\tclassification.falsePositive = 1929;\n\t\tclassification.falseNegative = 6493;\n\t\tclassification.wpTruePositive = 0.0;\n\t\tclassification.wpFalsePositive = 644.86664099999996;\n\t\tclassification.wrTruePositive = 11562.182811000408;\n\t\tclassification.wrFalseNegative = 64.369443000000018;\n\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculatePseudoPrecision(classification), 95.9875, 0.0001);\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculatePseudoRecall(classification), 99.4464, 0.0001);\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculatePseudoFMeasure(classification), 97.6863, 0.0001);\n\t}\n\n\tTEST(PerformanceTests, PSNRBoundsTest)\n\t{\n\t\tClassifiedPerformance::Classifications classification;\n\t\tclassification.truePositive = 3;\n\t\tclassification.trueNegative = 5;\n\t\tclassification.falsePositive = 0; // Possible Divide By Zero\n\t\tclassification.falseNegative = 0; // Possible Divide By Zero\n\n\t\tEXPECT_TRUE(ClassifiedPerformance::CalculatePSNR(classification) > 1000);\n\t}\n\n\tTEST(ClassifiedPerformanceTests, FMeasureBoundsTest)\n\t{\n\t\tClassifiedPerformance::Classifications classification;\n\t\tclassification.truePositive = 0; // Possible Divide By Zero\n\t\tclassification.trueNegative = 5;\n\t\tclassification.falsePositive = 7;\n\t\tclassification.falseNegative = 11;\n\n\t\tEXPECT_EQ(ClassifiedPerformance::CalculateFMeasure(classification), 0.0);\n\t}\n\n\tTEST(ClassifiedPerformanceTests, NRMBoundsTest)\n\t{\n\t\tClassifiedPerformance::Classifications classification;\n\t\tclassification.truePositive = 0; // Possible Divide By Zero\n\t\tclassification.trueNegative = 5;\n\t\tclassification.falsePositive = 7;\n\t\tclassification.falseNegative = 0; // Possible Divide By Zero\n\n\t\tEXPECT_TRUE(ClassifiedPerformance::CalculateNRM(classification) > 1000);\n\t}\n\n\tTEST(ClassifiedPerformanceTests, MCCTest)\n\t{\n\t\t// Numbers and expected value pulled from: https://en.wikipedia.org/wiki/Matthews_correlation_coefficient\n\t\tClassifiedPerformance::Classifications classification;\n\t\tclassification.truePositive = 6;\n\t\tclassification.trueNegative = 3;\n\t\tclassification.falsePositive = 1;\n\t\tclassification.falseNegative = 2;\n\n\t\tEXPECT_NEAR(ClassifiedPerformance::CalculateMCC(classification), 0.478, 0.001);\n\t}\n\n\tTEST(ClassifiedPerformanceTests, ClassifiedPerformanceSauvola)\n\t{\n\t\tstd::string projFolder = TestUtilities::ProjectFolder();\n\n\t\t// Grayscale Image\n\t\tconst std::string filePathBinary = projFolder + \"2JohnC1V3-Sauvola.pbm\";\n\t\tImage binaryImage = PNM::Read(filePathBinary);\n\n\t\t// Ground Truth\n\t\tconst std::string filePathGT = projFolder + \"2JohnC1V3-GroundTruth.pbm\";\n\t\tImage groundTruthImage = PNM::Read(filePathGT);\n\n\t\t// Load Pseudo Weights\n\t\tconst std::string filePathRWeights = projFolder + \"2JohnC1V3-GroundTruth_RWeights.dat\";\n\t\tauto rWeights = DIBCOUtils::ReadWeightsFile(filePathRWeights);\n\n\t\tconst std::string filePathPWeights = projFolder + \"2JohnC1V3-GroundTruth_PWeights.dat\";\n\t\tauto pWeights = DIBCOUtils::ReadWeightsFile(filePathPWeights);\n\n\t\t// Run Classified Metrics\n\t\tClassifiedPerformance::Classifications classifications;\n\t\tbool canCompare = ClassifiedPerformance::CompareImages(classifications, groundTruthImage, binaryImage, pWeights, rWeights);\n\t\tEXPECT_TRUE(canCompare);\n\n\t\tconst double accuracy = ClassifiedPerformance::CalculateAccuracy(classifications);\n\t\tconst double fm = ClassifiedPerformance::CalculateFMeasure(classifications);\n\t\tconst double recall = ClassifiedPerformance::CalculateRecall(classifications);\n\t\tconst double precision = ClassifiedPerformance::CalculatePrecision(classifications);\n\t\tconst double pfm = ClassifiedPerformance::CalculatePseudoFMeasure(classifications);\n\t\tconst double precall = ClassifiedPerformance::CalculatePseudoRecall(classifications);\n\t\tconst double pprecision = ClassifiedPerformance::CalculatePseudoPrecision(classifications);\n\t\tconst double mcc = ClassifiedPerformance::CalculateMCC(classifications);\n\t\tconst double nrm = ClassifiedPerformance::CalculateNRM(classifications);\n\t\tconst double psnr = ClassifiedPerformance::CalculatePSNR(classifications);\n\n\t\t// Test\n\t\tEXPECT_NEAR(accuracy, 97.671, 0.001);\n\t\tEXPECT_NEAR(fm, 93.204, 0.001);\n\t\tEXPECT_NEAR(recall, 91.3811, 0.001);\n\t\tEXPECT_NEAR(precision, 95.1025, 0.001);\n\t\tEXPECT_NEAR(pfm, 93.393, 0.001);\n\t\tEXPECT_NEAR(precall, 92.7954, 0.001);\n\t\tEXPECT_NEAR(pprecision, 93.9983, 0.001);\n\t\tEXPECT_NEAR(mcc, 0.918, 0.001);\n\t\tEXPECT_NEAR(nrm, 0.048, 0.001);\n\t\tEXPECT_NEAR(psnr, 16.329, 0.001);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/ContrastImageTests.cpp",
    "content": "#include \"pch.h\"\n#include \"ImageFixture.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass ContrastImageTests : public ImageFixture {};\n\tTEST_F(ContrastImageTests, GenerateContrastImageTest)\n\t{\n\t\tImage contrastImage(image.width, image.height);\n\t\tContrastImage::GenerateContrastImage(contrastImage, image);\n\n\t\tPNM::Write(contrastImage, projFolder + \"2JohnC1V3-ContrastImage.ppm\");\n\t}\n\n\tTEST_F(ContrastImageTests, EstimateStrokeWidthTest)\n\t{\n\t\t// Peaks spaced 5px apart\n\t\tconstexpr int width = 30;\n\t\tconstexpr int height = 4;\n\t\tPixel8 contrastData[width * height];\n\t\tstd::memset(contrastData, 0, sizeof(contrastData));\n\n\t\tfor (int y = 0; y < height; ++y)\n\t\t{\n\t\t\tconst int row = y * width;\n\n\t\t\tcontrastData[row + 5] = 180;\n\t\t\tcontrastData[row + 10] = 180;\n\t\t\tcontrastData[row + 15] = 180;\n\t\t\tcontrastData[row + 20] = 180;\n\t\t}\n\n\t\tImage contrastImage(width, height, contrastData);\n\n\t\tEXPECT_EQ(5, ContrastImage::EstimateStrokeWidth(contrastImage));\n\t}\n\n\tTEST_F(ContrastImageTests, GenerateHighContrastImageTest)\n\t{\n\t\tImage highContrastImage(image.width, image.height);\n\t\tContrastImage::GenerateHighContrastImage(highContrastImage, image);\n\n\t\tPNM::Write(highContrastImage, projFolder + \"2JohnC1V3-HighContrastImage.pbm\");\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/DIBCOUtilsTests.cpp",
    "content": "#include \"pch.h\"\n#include <sstream>\n#include <string>\n#include \"DIBCOUtils.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(DIBCOUtilsTests, ReadWeightsTest)\n\t{\n\t\t// Note: A sample copied from a DIBCO .dat file\n\t\tstd::string weights = \"0.000000  1.000000  0.750000  0.500000\";\n\t\tstd::stringstream stream(weights);\n\n\t\tauto result = DIBCOUtils::ReadWeights(stream, 4);\n\n\t\tEXPECT_EQ(result.size(), 4);\n\t\tEXPECT_EQ(result.at(0), 0.0);\n\t\tEXPECT_EQ(result.at(1), 1.0);\n\t\tEXPECT_EQ(result.at(2), 0.75);\n\t\tEXPECT_EQ(result.at(3), 0.5);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/DRDMTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\t// Exposes protected members for Unit Testing\n\tclass DRDMTestHarness : public Doxa::DRDM\n\t{\n\tpublic:\n\t\tusing DRDM::SumDRDkForMismatchedPixels;\n\t\tusing DRDM::NUBN;\n\n\t\t// NUBN may call any of these three routines\n\t\tusing DRDM::NUBN_STD;\n\t\tusing DRDM::NUBN_STD_8x8;\n\n\t\t#if defined(DOXA_SIMD)\n\t\t\tusing DRDM::NUBN_SIMD_8x8;\n\t\t#endif\n\t};\n\n\tTEST(DRDMTests, DRDMSauvolaTest)\n\t{\n\t\t// Setup\n\t\tstd::string projFolder = TestUtilities::ProjectFolder();\n\n\t\tconst std::string filePathGT = projFolder + \"2JohnC1V3-GroundTruth.pbm\";\n\t\tImage gtImage = PNM::Read(filePathGT);\n\n\t\tconst std::string filePathSauvola = projFolder + \"2JohnC1V3-Sauvola.pbm\";\n\t\tImage binImage = PNM::Read(filePathSauvola);\n\n\t\t// Run DRDM\n\t\tconst double drdm = DRDMTestHarness::CalculateDRDM(gtImage, binImage);\n\t\tconst uint64_t sumDRDk = DRDMTestHarness::SumDRDkForMismatchedPixels(gtImage, binImage);\n\t\tconst int nubn = DRDMTestHarness::NUBN_STD(gtImage, 8);\n\n\t\t// DRDM - Value optained from the DIBCO perf tool\n\t\tEXPECT_NEAR(1.9519, drdm, 0.0001);\n\t\tEXPECT_EQ(4122339441, sumDRDk);\n\t\tEXPECT_EQ(2112, nubn);\n\t}\n\n\tTEST(DRDMTests, DRDMTest)\n\t{\n\t\t// (3, 4) = Black is changed to White\n\t\t// One 8x8 Block with a 5x5 Window\n\t\tPixel8 dataGT[] = {\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::Black, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::Black,\n\t\t};\n\t\tImage groundTruthImage(8, 8, dataGT);\n\n\t\tPixel8 dataExp[] = {\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::Black, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::White,  Palette::Black,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White, Palette::White, Palette::Black,\n\t\t};\n\t\tImage expImage(8, 8, dataExp);\n\n\t\tdouble drdm = DRDM::CalculateDRDM(groundTruthImage, expImage);\n\n\t\tEXPECT_EQ((double)(72357 + 72357 + 32359) / 1000000, drdm);\n\t}\n\n\tTEST(DRDMTests, NUBNUniformityCountTest)\n\t{\n\t\t// This is a 24x24 image creating a 3x3 set of windows that are 8x8\n\t\tPixel8 data[] = {\n\t\t\t// ===== Window Row 1 (rows 0-7 of array) =====\n\t\t\t// Window 1-1: All White | Window 1-2: All Black | Window 1-3: White with black center\n\n\t\t\t// Window row 0: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 1: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 2: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 3: Window 1-1 | Window 1-2 | Window 1-3 (black center)\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::Black, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 4: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 5: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 6: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 7: Window 1-1 | Window 1-2 | Window 1-3\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// ===== Window Row 2 (rows 8-15 of array) =====\n\t\t\t// Window 2-1: Checkerboard | Window 2-2: All White | Window 2-3: All Black\n\n\t\t\t// Window row 0: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 1: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 2: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 3: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 4: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 5: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 6: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// Window row 7: Window 2-1 | Window 2-2 | Window 2-3\n\t\t\tPalette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White, Palette::Black, Palette::White,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\n\t\t\t// ===== Window Row 3 (rows 16-23 of array) =====\n\t\t\t// Window 3-1: Black with white center | Window 3-2: White with black border | Window 3-3: Black with white border\n\n\t\t\t// Window row 0: Window 3-1 | Window 3-2 (top border) | Window 3-3 (top border)\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\n\t\t\t// Window row 1: Window 3-1 | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 2: Window 3-1 | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 3: Window 3-1 (white center) | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 4: Window 3-1 | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 5: Window 3-1 | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 6: Window 3-1 | Window 3-2 | Window 3-3\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::White,\n\n\t\t\t// Window row 7: Window 3-1 | Window 3-2 (bottom border) | Window 3-3 (bottom border)\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black, Palette::Black,\n\t\t\tPalette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White, Palette::White,\n\t\t};\n\n\t\t// This image contains 4 fully black or white windows\n\t\t// and 5 mixed windows\n\t\tImage binaryImage(24, 24, data);\n\n\t\tconst unsigned int countStd = DRDMTestHarness::NUBN_STD(binaryImage, 8);\n\t\tconst unsigned int countStd8x8 = DRDMTestHarness::NUBN_STD_8x8(binaryImage);\n\t\t\n\t\tEXPECT_EQ(countStd, 5);\n\t\tEXPECT_EQ(countStd8x8, 5);\n\n\n\t\t#if defined(DOXA_SIMD)\n\t\t\tconst unsigned int countSimd8x8 = DRDMTestHarness::NUBN_SIMD_8x8(binaryImage);\n\t\t\tEXPECT_EQ(countSimd8x8, 5);\n\t\t#endif\n\t}\n\n\tTEST(DRDMTests, NUBNVariousWindowSizesTest)\n\t{\n\t\t// This a 15x15 image with window sizes of 8x8, 7x7, and 25x25\n\t\tImage binaryImage(24, 24);\n\t\tbinaryImage.Fill(Palette::White);\n\t\tbinaryImage.Pixel(7, 3) = Palette::Black;\n\t\tbinaryImage.Pixel(15, 3) = Palette::Black;\n\t\tbinaryImage.Pixel(23, 3) = Palette::Black;\n\n\t\tconst unsigned int count1 = DRDMTestHarness::NUBN(binaryImage, 8);\n\n\t\t// Try an smaller window size of 7\n\t\t// We do not process partial windows, so 7x7 should only see 2\n\t\tconst unsigned int count2 = DRDMTestHarness::NUBN(binaryImage, 7);\n\n\t\t// Lets make our window size larger than the image\n\t\t// Since we don't do partial windows, this is an interesting edge case\n\t\tconst unsigned int count3 = DRDMTestHarness::NUBN(binaryImage, 25);\n\n\t\tEXPECT_EQ(count1, 3); // Window 8x8\n\t\tEXPECT_EQ(count2, 2); // Window 7x7\n\t\tEXPECT_EQ(count3, 0); // Window 25x25\n\t}\n\n    TEST(DRDMTests, NUBNImplementationConsistencyTest)\n    {\n\t\tstd::string projFolder = TestUtilities::ProjectFolder();\n        const std::string filePathGT = projFolder + \"2JohnC1V3-GroundTruth.pbm\";\n\t\tImage binaryImage = PNM::Read(filePathGT);\n\n\t\tconst unsigned int countSTD = DRDMTestHarness::NUBN_STD(binaryImage, 8);\n\t\tconst unsigned int countSTD8x8 = DRDMTestHarness::NUBN_STD_8x8(binaryImage);\n\t\t\n\t\tEXPECT_EQ(countSTD, countSTD8x8);\n\n\t\t\n\t\t#if defined(DOXA_SIMD)\n\t\t\tconst unsigned int countSimd8x8 = DRDMTestHarness::NUBN_SIMD_8x8(binaryImage);\n\t\t\tEXPECT_EQ(countSTD8x8, countSimd8x8);\n\t\t#endif\n    }\n}\n"
  },
  {
    "path": "Doxa.Test/Doxa.Test.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{5723f19a-a7ab-45d0-a78c-b04fe035865f}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>\n    <ConfigurationType>Application</ConfigurationType>\n    <PlatformToolset>v143</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\" />\n  <ImportGroup Label=\"Shared\">\n    <Import Project=\"..\\Doxa\\Doxa.vcxitems\" Label=\"Shared\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" />\n  <PropertyGroup Label=\"UserMacros\" />\n  <ItemGroup>\n    <ClInclude Include=\"ImageFixture.hpp\" />\n    <ClInclude Include=\"pch.h\" />\n    <ClInclude Include=\"TestUtilities.hpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"AlgorithmTests.cpp\" />\n    <ClCompile Include=\"BatainehTests.cpp\" />\n    <ClCompile Include=\"BinarizationTests.cpp\" />\n    <ClCompile Include=\"CalculatorTests.cpp\" />\n    <ClCompile Include=\"ClassifiedPerformanceTests.cpp\" />\n    <ClCompile Include=\"ContrastImageTests.cpp\" />\n    <ClCompile Include=\"DRDMTests.cpp\" />\n    <ClCompile Include=\"GrayscaleTests.cpp\" />\n    <ClCompile Include=\"GridCalcTests.cpp\" />\n    <ClCompile Include=\"ImageTests.cpp\" />\n    <ClCompile Include=\"ISauvolaTests.cpp\" />\n    <ClCompile Include=\"LocalWindowTests.cpp\" />\n    <ClCompile Include=\"MorphologyTests.cpp\" />\n    <ClCompile Include=\"PaletteTests.cpp\" />\n    <ClCompile Include=\"ParametersTests.cpp\" />\n    <ClCompile Include=\"PNMTests.cpp\" />\n    <ClCompile Include=\"DIBCOUtilsTests.cpp\" />\n    <ClCompile Include=\"RegionTests.cpp\" />\n    <ClCompile Include=\"pch.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"SIMDTests.cpp\" />\n    <ClCompile Include=\"WienerFilterTests.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemDefinitionGroup />\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\packages\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\\build\\native\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets\" Condition=\"Exists('..\\packages\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\\build\\native\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')\" />\n  </ImportGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <LanguageStandard>stdcpp17</LanguageStandard>\n      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\n      <PreprocessorDefinitions>X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <WarningLevel>Level3</WarningLevel>\n      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\n      <LanguageStandard>stdcpp17</LanguageStandard>\n      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <SubSystem>Console</SubSystem>\n      <OptimizeReferences>true</OptimizeReferences>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n    </Link>\n  </ItemDefinitionGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\\build\\native\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.7\\build\\native\\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "Doxa.Test/Doxa.Test.vcxproj.filters",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <ClCompile Include=\"AlgorithmTests.cpp\" />\n    <ClCompile Include=\"BatainehTests.cpp\" />\n    <ClCompile Include=\"BinarizationTests.cpp\" />\n    <ClCompile Include=\"CalculatorTests.cpp\" />\n    <ClCompile Include=\"ContrastImageTests.cpp\" />\n    <ClCompile Include=\"GrayscaleTests.cpp\" />\n    <ClCompile Include=\"ImageTests.cpp\" />\n    <ClCompile Include=\"ISauvolaTests.cpp\" />\n    <ClCompile Include=\"LocalWindowTests.cpp\" />\n    <ClCompile Include=\"MorphologyTests.cpp\" />\n    <ClCompile Include=\"PaletteTests.cpp\" />\n    <ClCompile Include=\"ParametersTests.cpp\" />\n    <ClCompile Include=\"PNMTests.cpp\" />\n    <ClCompile Include=\"RegionTests.cpp\" />\n    <ClCompile Include=\"pch.cpp\" />\n    <ClCompile Include=\"GridCalcTests.cpp\" />\n    <ClCompile Include=\"SIMDTests.cpp\" />\n    <ClCompile Include=\"ClassifiedPerformanceTests.cpp\" />\n    <ClCompile Include=\"DRDMTests.cpp\" />\n    <ClCompile Include=\"DIBCOUtilsTests.cpp\" />\n    <ClCompile Include=\"WienerFilterTests.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"ImageFixture.hpp\" />\n    <ClInclude Include=\"pch.h\" />\n    <ClInclude Include=\"TestUtilities.hpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "Doxa.Test/GrayscaleTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(GrayscaleTests, GrayscaleAlgorithmsTest)\n\t{\n\t\t// Mean, Value, and Luster contain obvious formulas.\n\t\tEXPECT_EQ(100, Grayscale::Mean(100, 30, 170));\n\n\t\tEXPECT_EQ(200, Grayscale::Value(50, 100, 200));\n\t\tEXPECT_EQ(200, Grayscale::Value(50, 200, 100));\n\t\tEXPECT_EQ(200, Grayscale::Value(200, 100, 50));\n\n\t\tEXPECT_EQ(125, Grayscale::Luster(50, 100, 200));\n\n\t\tEXPECT_EQ(150, Grayscale::MinAvg(100, 200, 300));\n\n\t\t// Assert that all weights sum to exactly 1\n\t\tEXPECT_NEAR(1.0, Grayscale::BT601(1.0, 1.0, 1.0), 0.001);\n\t\tEXPECT_NEAR(1.0, Grayscale::BT709(1.0, 1.0, 1.0), 0.001);\n\t\tEXPECT_NEAR(1.0, Grayscale::BT2100(1.0, 1.0, 1.0), 0.001);\n\t}\n\n\tTEST(GrayscaleTests, GrayscaleColorSpaceTest)\n\t{\n\t\tconst Pixel8 red = 225;\n\t\tconst Pixel8 green = 128;\n\t\tconst Pixel8 blue = 15;\n\n\t\t// Non-Linear to Linear /w LUT\n\t\tconst auto lut = Grayscale::LinearLUT();\n\n\t\tconst auto redLin = lut[red];\n\t\tconst auto greenLin = lut[green];\n\t\tconst auto blueLin = lut[blue];\n\n\t\t// Validate LUT is correct\n\t\tEXPECT_NEAR(0.753, redLin, 0.001);\n\t\tEXPECT_NEAR(0.216, greenLin, 0.001);\n\t\tEXPECT_NEAR(0.005, blueLin, 0.001);\n\n\t\tconst auto [X, Y, Z] = Grayscale::RGBToXYZ(redLin, greenLin, blueLin);\n\n\t\tEXPECT_NEAR(X, .3885, 0.0002);\n\t\tEXPECT_NEAR(Y, .3148, 0.0002);\n\t\tEXPECT_NEAR(Z, .0448, 0.0002);\n\n\t\tconst auto [L, a, b] = Grayscale::XYZToLab(X, Y, Z);\n\n\t\tEXPECT_NEAR(L, 62.91, 0.01);\n\t\tEXPECT_NEAR(a, 30.95, 0.01);\n\t\tEXPECT_NEAR(b, 67.00, 0.01);\n\t}\n\n\tTEST(GrayscaleTests, GrayscaleLinearLightnessTest)\n\t{\n\t\t// 3 pixels: flanking values bracket the test pixel to enable normalization\n\t\tconst uint8_t input[] = {\n\t\t\t 64,  32, 128,  // pixel 0\n\t\t\t225, 128,  15,  // pixel 1 - test pixel\n\t\t\t200, 160,  80   // pixel 2\n\t\t};\n\t\tPixel8 output[3] = {};\n\n\t\tGrayscale::ToGrayscale(output, input, 3, 1, 3, GrayscaleAlgorithms::LIGHTNESS);\n\n\t\tEXPECT_EQ(160, output[1]);  // TODO: replace with correct expected value\n\t}\n\n\tTEST(GrayscaleTests, GrayscaleLinearLABDistTest)\n\t{\n\t\t// 3 pixels: flanking values bracket the test pixel to enable normalization\n\t\tconst uint8_t input[] = {\n\t\t\t 64,  32, 128,  // pixel 0\n\t\t\t200, 160,  80,  // pixel 1 - test pixel\n\t\t\t186, 128,  15   // pixel 2\n\t\t};\n\t\tPixel8 output[3] = {};\n\n\t\tGrayscale::ToGrayscale(output, input, 3, 1, 3, GrayscaleAlgorithms::LABDIST);\n\n\t\tEXPECT_EQ(218, output[1]);  // TODO: replace with correct expected value\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/GridCalcTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(GridCalcTests, GridCalcIterateInterwovenTest)\n\t{\n\t\t// Setup\n\t\tImage image(7, 3);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\t// Expected values\n\t\tconst int ar1[8][5] = {\n\t\t\t{ 0, 0, 0, 2, 2},\n\t\t\t{ 2, 0, 0, 4, 2},\n\t\t\t{ 4, 2, 0, 6, 2},\n\t\t\t{ 6, 4, 0, 6, 2},\n\n\t\t\t{ 14, 0, 0, 2, 2},\n\t\t\t{ 16, 0, 0, 4, 2},\n\t\t\t{ 18, 2, 0, 6, 2},\n\t\t\t{ 20, 4, 0, 6, 2}\n\t\t};\n\n\t\tint inc = 0;\n\n\t\t// Function under test\n\t\tgrid.Iterate(image, 5, 2, [&](const Region& window, const int& position)\n\t\t{\n\t\t\tconst auto exp = ar1[inc];\n\t\t\tEXPECT_EQ(exp[0], position);\n\t\t\tEXPECT_EQ(exp[1], window.upperLeft.x);\n\t\t\tEXPECT_EQ(exp[2], window.upperLeft.y);\n\t\t\tEXPECT_EQ(exp[3], window.bottomRight.x);\n\t\t\tEXPECT_EQ(exp[4], window.bottomRight.y);\n\n\t\t\tinc++;\n\t\t});\n\n\t\tEXPECT_EQ(8, inc);\n\t}\n\n\tTEST(GridCalcTests, GridCalcIterateUnevenTest)\n\t{\n\t\t// Setup\n\t\tImage image(7, 7);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\t// Expected values\n\t\tconst int ar1[9][5] = {\n\t\t\t{ 0, 0, 0, 2, 2},\n\t\t\t{ 5, 3, 0, 6, 2},\n\t\t\t{ 6, 4, 0, 6, 2},\n\n\t\t\t{ 35, 0, 3, 2, 6},\n\t\t\t{ 40, 3, 3, 6, 6},\n\t\t\t{ 41, 4, 3, 6, 6},\n\n\t\t\t{ 42, 0, 4, 2, 6},\n\t\t\t{ 47, 3, 4, 6, 6},\n\t\t\t{ 48, 4, 4, 6, 6}\n\t\t};\n\n\t\tint inc = 0;\n\n\t\t// Function under test\n\t\tgrid.Iterate(image, 5, 5, [&](const Region& window, const int& position) \n\t\t{\n\t\t\t\tconst auto exp = ar1[inc];\n\t\t\t\tEXPECT_EQ(exp[0], position);\n\t\t\t\tEXPECT_EQ(exp[1], window.upperLeft.x);\n\t\t\t\tEXPECT_EQ(exp[2], window.upperLeft.y);\n\t\t\t\tEXPECT_EQ(exp[3], window.bottomRight.x);\n\t\t\t\tEXPECT_EQ(exp[4], window.bottomRight.y);\n\n\t\t\t\tinc++;\n\t\t});\n\n\t\tEXPECT_EQ(9, inc);\n\t}\n\n\tTEST(GridCalcTests, GridCalcIterateEvenTest)\n\t{\n\t\t// Setup\n\t\tImage image(6, 6);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\t// Expected values\n\t\tconst int ar1[4][5] = {\n\t\t\t{ 0, 0, 0, 2, 2},\n\t\t\t{ 5, 3, 0, 5, 2},\n\n\t\t\t{ 30, 0, 3, 2, 5},\n\t\t\t{ 35, 3, 3, 5, 5}\n\t\t};\n\n\t\tint inc = 0;\n\n\t\t// Function under test\n\t\tgrid.Iterate(image, 5, 5, [&](const Region& window, const int& position)\n\t\t{\n\t\t\tconst auto exp = ar1[inc];\n\t\t\tEXPECT_EQ(exp[0], position);\n\t\t\tEXPECT_EQ(exp[1], window.upperLeft.x);\n\t\t\tEXPECT_EQ(exp[2], window.upperLeft.y);\n\t\t\tEXPECT_EQ(exp[3], window.bottomRight.x);\n\t\t\tEXPECT_EQ(exp[4], window.bottomRight.y);\n\n\t\t\tinc++;\n\t\t});\n\n\t\tEXPECT_EQ(4, inc);\n\t}\n\n\tTEST(GridCalcTests, GridCalcInterpolateTest)\n\t{\n\t\t// Setup\n\t\tconst Pixel8 bits[] = {\n\t\t\t100, 0, 0, 80, 0, 0, 60,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,\n\t\t\t 90, 0, 0, 70, 0, 0, 50,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,\n\t\t\t100, 0, 0, 80, 0, 0, 60\n\t\t};\n\t\tImage image(7, 7, bits);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\tgrid.Interpolate(image, 3, [&](const int& position, const int& threshold)\n\t\t{\n\t\t\timage.data[position] = threshold;\n\t\t});\n\n/*\n  Directly taken from Moghaddam and Hedjam's interpolation_a_grid_on_domain\n  Matlab routine, with a simple 3x3 dataset, expanded to 7x7.\n  We store integers between 0-255, not decimals.\n\n  100.0000   93.3333   86.6667   80.0000   73.3333   66.6667   60.0000\n   96.6667   90.0000   83.3333   76.6667   70.0000   63.3333   56.6667\n   93.3333   86.6667   80.0000   73.3333   66.6667   60.0000   53.3333\n   90.0000   83.3333   76.6667   70.0000   63.3333   56.6667   50.0000\n   93.3333   86.6667   80.0000   73.3333   66.6667   60.0000   53.3333\n   96.6667   90.0000   83.3333   76.6667   70.0000   63.3333   56.6667\n  100.0000   93.3333   86.6667   80.0000   73.3333   66.6667   60.0000\n*/\n\t\tconst Pixel8 expectedBits[] = {\n\t\t\t100, 93, 87, 80, 73, 67, 60,\n\t\t\t 97, 90, 83, 77, 70, 63, 57,\n\t\t\t 93, 87, 80, 73, 67, 60, 53,\n\t\t\t 90, 83, 77, 70, 63, 57, 50,\n\t\t\t 93, 87, 80, 73, 67, 60, 53,\n\t\t\t 97, 90, 83, 77, 70, 63, 57,\n\t\t\t100, 93, 87, 80, 73, 67, 60\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expectedBits);\n\t}\n\n\tTEST(GridCalcTests, GridCalcInterpolateWideTest)\n\t{\n\t\t// Setup\n\t\tconst Pixel8 bits[] = {\n\t\t\t100, 0, 0, 0, 80, 0, 0, 0, 60,\n\t\t\t  0, 0, 0, 0,  0, 0, 0, 0,  0,\n\t\t\t  0, 0, 0, 0,  0, 0, 0, 0,  0,\n\t\t\t  0, 0, 0, 0,  0, 0, 0, 0,  0,\n\t\t\t 90, 0, 0, 0, 70, 0, 0, 0, 50,\n\t\t\t  0, 0, 0, 0,  0, 0, 0, 0,  0,\n\t\t\t  0, 0, 0, 0,  0, 0, 0, 0,  0,\n\t\t\t100, 0, 0, 0, 80, 0, 0, 0, 60\n\t\t};\n\t\tImage image(9, 8, bits);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\tgrid.Interpolate(image, 4, [&](const int& position, const int& threshold)\n\t\t{\n\t\t\timage.data[position] = threshold;\n\t\t});\n\n\t\tconst Pixel8 expectedBits[] = {\n\t\t\t100, 95, 90, 85, 80, 75, 70, 65, 60,\n\t\t\t 98, 93, 88, 83, 78, 73, 68, 63, 58,\n\t\t\t 95, 90, 85, 80, 75, 70, 65, 60, 55,\n\t\t\t 93, 88, 83, 78, 73, 68, 63, 58, 53,\n\t\t\t 90, 85, 80, 75, 70, 65, 60, 55, 50,\n\t\t\t 93, 88, 83, 78, 73, 68, 63, 58, 53,\n\t\t\t 97, 92, 87, 82, 77, 72, 67, 62, 57,\n\t\t\t100, 95, 90, 85, 80, 75, 70, 65, 60\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expectedBits);\n\t}\n\n\tTEST(GridCalcTests, GridCalcInterpolatePlusOneTest)\n\t{\n\t\t// Setup\n\t\tconst Pixel8 bits[] = {\n\t\t\t100, 0, 0, 80, 0, 0, 60,  40,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,   0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,   0,\n\t\t\t 90, 0, 0, 70, 0, 0, 50,  60,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,   0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0,   0,\n\t\t\t100, 0, 0, 60, 0, 0, 60, 100,\n\t\t\t 40, 0, 0, 60, 0, 0, 80, 100\n\t\t};\n\t\tImage image(8, 8, bits);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\tgrid.Interpolate(image, 3, [&](const int& position, const int& threshold)\n\t\t{\n\t\t\t\timage.data[position] = threshold;\n\t\t});\n\n\t\tconst Pixel8 expectedBits[] = {\n\t\t\t100, 93, 87, 80, 73, 67, 60,  40,\n\t\t\t 97, 90, 83, 77, 70, 63, 57,  47,\n\t\t\t 93, 87, 80, 73, 67, 60, 53,  53,\n\t\t\t 90, 83, 77, 70, 63, 57, 50,  60,\n\t\t\t 93, 84, 76, 67, 62, 58, 53,  73,\n\t\t\t 97, 86, 74, 63, 61, 59, 57,  87,\n\t\t\t100, 87, 73, 60, 60, 60, 60, 100,\n\t\t\t 40, 47, 53, 60, 67, 73, 80, 100\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expectedBits);\n\t}\n\n\tTEST(GridCalcTests, GridCalcInterpolatePlusTwoTest)\n\t{\n\t\t// Setup\n\t\tconst uint8_t bits[] = {\n\t\t\t100, 0, 0, 80, 0, 0, 60, 0,  40,\n\t\t\t  0, 0, 0,  0, 0, 0,  0, 0,   0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0, 0,   0,\n\t\t\t 90, 0, 0, 70, 0, 0, 50, 0,  60,\n\t\t\t  0, 0, 0,  0, 0, 0,  0, 0,   0,\n\t\t\t  0, 0, 0,  0, 0, 0,  0, 0,   0,\n\t\t\t100, 0, 0, 60, 0, 0, 60, 0, 100,\n\t\t\t  0, 0, 0,  0, 0, 0,  0, 0,   0,\n\t\t\t 40, 0, 0, 60, 0, 0, 80, 0, 100\n\t\t};\n\t\tImage image(9, 9, bits);\n\n\t\tGridCalc grid = GridCalc();\n\n\t\tgrid.Interpolate(image, 3, [&](const int& position, const int& threshold)\n\t\t{\n\t\t\timage.data[position] = threshold;\n\t\t});\n\n\t\tconst Pixel8 expectedBits[] = {\n\t\t\t100, 93, 87, 80, 73, 67, 60, 50,  40,\n\t\t\t 97, 90, 83, 77, 70, 63, 57, 52,  47,\n\t\t\t 93, 87, 80, 73, 67, 60, 53, 53,  53,\n\t\t\t 90, 83, 77, 70, 63, 57, 50, 55,  60,\n\t\t\t 93, 84, 76, 67, 62, 58, 53, 63,  73,\n\t\t\t 97, 86, 74, 63, 61, 59, 57, 72,  87,\n\t\t\t100, 87, 73, 60, 60, 60, 60, 80, 100,\n\t\t\t 70, 67, 63, 60, 63, 67, 70, 85, 100,\n\t\t\t 40, 47, 53, 60, 67, 73, 80, 90, 100\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expectedBits);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/ISauvolaTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\t// Exposes protected members for Unit Testing\n\tclass ISauvolaTestharness : public ISauvola\n\t{\n\tpublic:\n\t\tISauvolaTestharness() : ISauvola() {}\n\t\tusing ISauvola::Combine;\n\t\tusing ISauvola::Spider;\n\t};\n\n\tPixel8 sauvolaBinaryOutput[38] = { \n\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,\n\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,  Palette::White,\n\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::Black,\n\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,\n\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::White,  Palette::Black,  Palette::Black,\n\t\tPalette::Black,  Palette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::Black\n\t};\n\n\tTEST(ISauvolaTests, ISauvolaSpiderTest)\n\t{\n\t\t// Setup\n\t\tImage image(6, 6, sauvolaBinaryOutput);\t\t\t// Sauvola Binary\n\t\tImage outputImage(image.width, image.height);\t// Output of Spider\n\t\toutputImage.Fill(Palette::White);\n\n\t\t// Method under Test\n\t\tISauvolaTestharness isauvola;\n\t\tisauvola.Spider(outputImage, image, 19);\n\n\t\t// Assert Correctness\n\t\tPixel8 expected[] = { \n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,  Palette::White,\n\t\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::Black,\n\t\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::White,  Palette::Black,  Palette::Black,\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::Black \n\t\t};\n\n\t\tTestUtilities::AssertImageData(outputImage, expected);\n\t}\n\n\tTEST(ISauvolaTests, ISauvolaSpiderSinglePixelTest)\n\t{\n\t\t// Setup\n\t\tImage image(6, 6, sauvolaBinaryOutput);\t\t\t// Sauvola Binary\n\t\tImage outputImage(image.width, image.height);\t// Output of Spider\n\t\toutputImage.Fill(Palette::White);\n\n\t\t// Method under Test\n\t\tISauvolaTestharness isauvola;\n\t\tisauvola.Spider(outputImage, image, 30);\n\n\t\t// Assert Correctness\n\t\tPixel8 expected[] = {\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White,\n\t\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::White\n\t\t};\n\n\t\tTestUtilities::AssertImageData(outputImage, expected);\n\t}\n\n\tTEST(ISauvolaTests, ISauvolaCombineTest)\n\t{\n\t\t// Setup\n\t\tPixel8 highContrastData[] = {\n\t\t\tPalette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,  Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,\n\t\t\tPalette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,\n\t\t\tPalette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black,\n\t\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::Black\n\t\t};\n\t\tImage highContrastImage(6, 6, highContrastData);  // High Contrast Image\n\n\t\tImage sauvolaImage(6, 6, sauvolaBinaryOutput);  // Sauvola Binary\n\t\tImage outputImage(sauvolaImage.width, sauvolaImage.height);  // Output of Spider\n\n\t\t// Method under Test\n\t\tISauvolaTestharness isauvola;\n\t\tisauvola.Combine(outputImage, highContrastImage, sauvolaImage);\n\n\t\t// Assert Correctness\n\t\tPixel8 expected[] = {\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::Black,  Palette::Black,  Palette::White,\n\t\t\tPalette::White,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,  Palette::White,\n\t\t\tPalette::Black,  Palette::White,  Palette::White,  Palette::White,  Palette::White,  Palette::Black,\n\t\t\tPalette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::White,  Palette::Black,\n\t\t\tPalette::White,  Palette::White,  Palette::Black,  Palette::White,  Palette::Black,  Palette::Black,\n\t\t\tPalette::Black,  Palette::White,  Palette::Black,  Palette::Black,  Palette::White,  Palette::Black\n\t\t};\n\n\t\tTestUtilities::AssertImageData(outputImage, expected);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/ImageFixture.hpp",
    "content": "#ifndef IMAGEFIXTURE_HPP\n#define IMAGEFIXTURE_HPP\n\n#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass ImageFixture : public ::testing::Test\n\t{\n\tprotected:\n\t\tvoid SetUp() override {\n\t\t\tprojFolder = TestUtilities::ProjectFolder();\n\n\t\t\t// Load Color Image\n\t\t\tconst std::string filePath = projFolder + \"2JohnC1V3.ppm\";\n\t\t\timage = PNM::Read(filePath, ParameterMap{ {\"grayscale\", GrayscaleAlgorithms::QT} });\n\t\t}\n\n\t\tImage image;\n\t\tstd::string projFolder;\n\t};\n}\n\n#endif // IMAGEFIXTURE_HPP\n"
  },
  {
    "path": "Doxa.Test/ImageTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass ImageTest : public ::testing::Test\n\t{\n\tprotected:\n\t\tImage image;\n\n\t\tvoid SetUp() override\n\t\t{\n\t\t\timage = Image(3, 2);\n\n\t\t\t// Set pixel values for image\n\t\t\timage.data[0] = 0xF0;\n\t\t\timage.data[1] = 0xF1;\n\t\t\timage.data[2] = 0xF2;\n\t\t\timage.data[3] = 0xF3;\n\t\t\timage.data[4] = 0xF4;\n\t\t\timage.data[5] = 0xF5;\n\t\t}\n\t};\n\n\tTEST_F(ImageTest, ImagePixelTest)\n\t{\n\t\t// Verify each pixel\n\t\tEXPECT_EQ(image.Pixel(0, 0), image.data[0]);\n\t\tEXPECT_EQ(image.Pixel(1, 0), image.data[1]);\n\t\tEXPECT_EQ(image.Pixel(2, 0), image.data[2]);\n\t\tEXPECT_EQ(image.Pixel(0, 1), image.data[3]);\n\t\tEXPECT_EQ(image.Pixel(1, 1), image.data[4]);\n\t\tEXPECT_EQ(image.Pixel(2, 1), image.data[5]);\n\n\t\t// Out of bounds pixel\n\t\tEXPECT_EQ(image.Pixel(0, 3, 0xF6), (Pixel8)0xF6);\n\t}\n\n\tTEST_F(ImageTest, ImageCopyCTORTest)\n\t{\n\t\t// Copy Image using Copy CTOR\n\t\tImage copy(image);\n\t\tEXPECT_FALSE(copy.managedExternally);\n\t\tEXPECT_EQ(copy.height, image.height);\n\t\tEXPECT_EQ(copy.width, image.width);\n\t\tEXPECT_NE(nullptr, copy.data);\n\t\tEXPECT_NE(copy.data, image.data);\n\n\t\t// Copy Image using Copy CTOR - Identical to above due to direct instantiation\n\t\tImage copy2 = copy;\n\t\tEXPECT_FALSE(copy2.managedExternally);\n\t\tEXPECT_NE(copy.data, copy2.data);\n\t}\n\n\tTEST_F(ImageTest, ImageMoveCTORTest)\n\t{\n\t\tImage move = std::invoke([]() {\n\t\t\tImage iLiveOnTheStack;\n\t\t\treturn iLiveOnTheStack; // Triggers our Move CTOR\n\t\t});\n\n\t\tEXPECT_FALSE(move.managedExternally);\n\t}\n\n\tTEST_F(ImageTest, ImageExternalReferenceTest)\n\t{\n\t\t// Copy Image using Copy CTOR\n\t\tImage copy(image);\n\n\t\t// Create a scope to trigger the reference image destructor\n\t\t{\n\t\t\t// Create Image Reference\n\t\t\tImage reference = Image::Reference(image.width, image.height, image.data);\n\t\t\tEXPECT_TRUE(reference.managedExternally);\n\t\t\tEXPECT_EQ(reference.height, image.height);\n\t\t\tEXPECT_EQ(reference.width, image.width);\n\t\t\tEXPECT_EQ(reference.data, image.data);\n\n\t\t\t// Set pixel value from coordinate.\n\t\t\timage.Pixel(1, 1) = 0xFA;\n\t\t\tEXPECT_EQ(image.Pixel(1, 1), (Pixel8)0xFA);\n\t\t\tEXPECT_EQ(copy.Pixel(1, 1), (Pixel8)0xF4); // Copy should not change.\n\t\t\tEXPECT_EQ(reference.Pixel(1, 1), image.Pixel(1, 1)); // Reference should change\n\n\t\t\t// Copy a memory managed Image but no longer manage the memory\n\t\t\tImage deepReference = Image(reference);\n\t\t\tEXPECT_FALSE(deepReference.managedExternally);\n\t\t\tEXPECT_NE(image.data, deepReference.data);\n\n\t\t\t// Reference should not change\n\t\t\tdeepReference.Pixel(1, 1) = 0xFF;\n\t\t\tEXPECT_EQ(reference.Pixel(1, 1), (Pixel8)0xFA);\n\t\t}\n\n\t\t// Reference should not free our image storage\n\t\tEXPECT_EQ(image.Pixel(1, 1), (Pixel8)0xFA);\n\t}\n\n\tTEST_F(ImageTest, ImageReferenceTest)\n\t{\n\t\t// Create a reference from an Image object\n\t\tImage reference = image.Reference();\n\t\tEXPECT_EQ(reference.data, image.data);\n\t\tEXPECT_TRUE(reference.managedExternally);\n\t}\n\n\tTEST_F(ImageTest, ImageCopyAssignmentOperatorTest)\n\t{\n\t\t// Create a reference from an Image object\n\t\tImage reference = image.Reference();\n\n\t\t// Ensure our Copy Assignment Operator issues a deep copy\n\t\tImage copy;\n\t\tcopy = reference;\n\t\tEXPECT_FALSE(copy.managedExternally);\n\n\t\t// Copy should now be a deep copy of image\n\t\tEXPECT_EQ(image.width, copy.width);\n\t\tEXPECT_NE(image.data, copy.data);\n\t\tEXPECT_EQ(copy.Pixel(1, 1), (Pixel8)0xF4);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/LocalWindowTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(LocalWindowTests, LocalWindowIterateTest)\n\t{\n\t\t// Build dummy image for a 3x3 window\n\t\t// This array will be updated by our iterator\n\t\tPixel8 data[] =\n\t\t\t{  1,  2,  3,  4,  5,  6,\n\t\t\t\t7,  8,  9, 10, 11, 12,\n\t\t\t\t13, 14, 15, 16, 17, 18,\n\t\t\t\t19, 20, 21, 22, 23, 24,\n\t\t\t\t25, 26, 27, 28, 29, 30,\n\t\t\t\t31, 32, 33, 34, 35, 36  };\n\n\t\tImage image(6, 6, data);\n\n\t\t// Test that we can iterate a 3x3 window around our image\n\t\tLocalWindow::Iterate(image, 3, [&](const Region& window, const int& positionImage) {\n\n\t\t\tint sum = 0;\n\n\t\t\tLocalWindow::Iterate(image.width, window, [&](const int& positionWindow) {\n\t\t\t\tsum += image.data[positionWindow];\n\t\t\t});\n\n\t\t\tdata[positionImage] = (std::min)(sum, 255);\n\t\t});\n\n\t\t// Compare to our known output\n\t\tconst Pixel8 expected[] =\n\t\t\t{  18,  30,  36,  42,  48,  34,\n\t\t\t\t45,  72,  81,  90,  99,  69,\n\t\t\t\t81, 126, 135, 144, 153, 105,\n\t\t\t\t117, 180, 189, 198, 207, 141,\n\t\t\t\t153, 234, 243, 252, 255, 177,\n\t\t\t\t114, 174, 180, 186, 192, 130  };\n\n\t\tEXPECT_TRUE(std::equal(std::begin(data), std::end(data), std::begin(expected), std::end(expected)));\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/MorphologyTests.cpp",
    "content": "#include \"pch.h\"\n#include \"ImageFixture.hpp\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass MorphologyTests : public ImageFixture {};\n\n\tclass MorphologyTestHarness : public Morphology\n\t{\n\tpublic:\n\t\tMorphologyTestHarness() : Morphology() {}\n\t\tusing Morphology::Morph;\n\t\tusing Morphology::IterativelyErode;\n\t\tusing Morphology::IterativelyDilate;\n\t};\n\n\n\tTEST_F(MorphologyTests, MorphologyErodeTest)\n\t{\n\t\tconst Pixel8 data[] = {\n\t\t\t1,  2,  3,  4,  5,  6,\n\t\t\t7,  8,  9, 10, 11, 12,\n\t\t\t13, 14, 15, 16, 50, 18, // Note 5th column\n\t\t\t19, 20,  3, 22, 23, 24, // Note 3rd column\n\t\t\t25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36\n\t\t};\n\n\t\t// For each row (y) in data, calculate the min value within the window for that row\n\t\tconst Pixel8 minArrayX[] = {\n\t\t\t1,  1,  2,  3,  4,  5,\n\t\t\t7,  7,  8,  9, 10, 11,\n\t\t\t13, 13, 14, 15, 16, 18,\n\t\t\t19,  3,  3,  3, 22, 23,\n\t\t\t25, 25, 26, 27, 28, 29,\n\t\t\t31, 31, 32, 33, 34, 35\n\t\t};\n\n\t\t// For each column (x) in minArrayX, calculate the min value within the window for that column\n\t\tconst Pixel8 minArray[] = {\n\t\t\t1,  1,  2,  3,  4,  5,\n\t\t\t1,  1,  2,  3,  4,  5,\n\t\t\t7,  3,  3,  3, 10, 11,\n\t\t\t13,  3,  3,  3, 16, 18,\n\t\t\t19,  3,  3,  3, 22, 23,\n\t\t\t25, 25, 26, 27, 28, 29\n\t\t};\n\n\t\tconst Image grayScaleImage(6, 6, data);\n\n\t\tImage erodedImage(6, 6);\n\t\tMorphology::Erode(erodedImage, grayScaleImage, 3);\n\n\t\tTestUtilities::AssertImageData(erodedImage, minArray);\n\t}\n\n\tTEST_F(MorphologyTests, MorphologyDilateTest)\n\t{\n\t\tconst Pixel8 data[] = {\n\t\t\t1,  2,  3,  4,  5,  6,\n\t\t\t7,  8,  9, 10, 11, 12,\n\t\t\t13, 14, 15, 16, 50, 18, // Note 5th column\n\t\t\t19, 20,  3, 22, 23, 24, // Note 3rd column\n\t\t\t25, 26, 27, 28, 29, 30,\n\t\t\t31, 32, 33, 34, 35, 36\n\t\t};\n\n\t\t// For each row (y) in data, calculate the max value within the window for that row\n\t\tconst Pixel8 maxArrayX[] = {\n\t\t\t2,  3,  4,  5,  6,  6,\n\t\t\t8,  9, 10, 11, 12, 12,\n\t\t\t14, 15, 16, 50, 50, 50,\n\t\t\t20, 20, 22, 23, 24, 24,\n\t\t\t26, 27, 28, 29, 30, 30,\n\t\t\t32, 33, 34, 35, 36, 36\n\t\t};\n\n\t\t// For each column (x) in maxArrayX, calculate the max value within the window for that column\n\t\tconst Pixel8 maxArray[] = {\n\t\t\t8,  9, 10, 11, 12, 12,\n\t\t\t14, 15, 16, 50, 50, 50,\n\t\t\t20, 20, 22, 50, 50, 50,\n\t\t\t26, 27, 28, 50, 50, 50,\n\t\t\t32, 33, 34, 35, 36, 36,\n\t\t\t32, 33, 34, 35, 36, 36\n\t\t};\n\n\t\tconst Image grayScaleImage(6, 6, data);\n\n\t\tImage dilatedImage(6, 6);\n\t\tMorphology::Dilate(dilatedImage, grayScaleImage, 3);\n\n\t\tTestUtilities::AssertImageData(dilatedImage, maxArray);\n\t}\n\n\t// TODO: Update this test to force calls to Morph(...), IterativelyDilate(...), etc using a test harness.\n\tTEST_F(MorphologyTests, MorphologySpeedTest)\n\t{\n\t\t// Find sample image\n\t\tconst std::string filePath = TestUtilities::ProjectFolder() + \"2JohnC1V3.ppm\";\n\n\t\t// Read image\n\t\tImage grayScaleImage = PNM::Read(filePath);\n\t\tImage wanBinary(grayScaleImage.width, grayScaleImage.height);\n\n\t\t// Window Size 17 is the tipping for my CPU.  This will trigger the Morph algorithm to be applied.\n\t\tParameters parameters({ { \"window\", 17 },{ \"k\", 0.2 } });\n\n\t\t// Time algorithms\n\t\tdouble wanMorphedSpeed = TestUtilities::Time([&]() {\n\t\t\tWan wan;\n\t\t\twan.Initialize(grayScaleImage);\n\t\t\twan.ToBinary(wanBinary, parameters);\n\t\t});\n\n\t\t// This window size will trigger a manual window analysis to be ran.\n\t\t// This is faster for small window sizes, but very costly for large windows.\n\t\tparameters.Set(\"window\", 15);\n\t\tdouble wanSpeed = TestUtilities::Time([&]() {\n\t\t\tWan wan;\n\t\t\twan.Initialize(grayScaleImage);\n\t\t\twan.ToBinary(wanBinary, parameters);\n\t\t});\n\n\t\tSUCCEED() << \"Morphed Wan Speed (W=17): \" << wanMorphedSpeed;\n\t\tSUCCEED() << \"Manual Wan Speed (W=15): \" << wanSpeed;\n\t\t//EXPECT_TRUE(wanSpeed < wanMorphedSpeed);\n\t}\n\n\tTEST_F(MorphologyTests, MorphologyErodeComparisonTest)\n\t{\n\t\tconst int windowSize = 25;\n\t\tImage morphedImage(image.width, image.height);\n\t\tImage iterativelyMorphedImage(image.width, image.height);\n\n\t\t// Manually find the min within each window\n\t\tMorphologyTestHarness::IterativelyErode(iterativelyMorphedImage, image, windowSize);\n\n\t\t// Utilize a Max Image to speed up the morphology transformation\n\t\tMorphologyTestHarness::Morph(morphedImage, image, windowSize, [](const std::multiset<Pixel8>& set) {\n\t\t\treturn *set.begin(); // Min Value\n\t\t});\n\n\t\tTestUtilities::AssertImages(iterativelyMorphedImage, morphedImage);\n\t}\n\n\tTEST_F(MorphologyTests, MorphologyDilateComparisonTest)\n\t{\n\t\tconst int windowSize = 25;\n\t\tImage morphedImage(image.width, image.height);\n\t\tImage iterativelyMorphedImage(image.width, image.height);\n\n\t\t// Manually find the max within each window\n\t\tMorphologyTestHarness::IterativelyDilate(iterativelyMorphedImage, image, windowSize);\n\n\t\t// Utilize a Max Image to speed up the morphology transformation\n\t\tMorphologyTestHarness::Morph(morphedImage, image, windowSize, [](const std::multiset<Pixel8>& set) {\n\t\t\treturn *std::prev(set.end()); // Max Value\n\t\t});\n\n\t\tTestUtilities::AssertImages(iterativelyMorphedImage, morphedImage);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/PNMTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\t// Exposes protected members for Unit Testing\n\tclass PNMTestharness : public PNM\n\t{\n\tpublic:\n\t\tPNMTestharness() :PNM() {}\n\n\t\t// Reads\n\t\tusing PNM::Read1BitBinary;\n\t\tusing PNM::Read8BitBinary;\n\t\tusing PNM::ColorToGrayscale;\n\t\tusing PNM::ReadPNM;\n\n\t\t// Writes\n\t\tusing PNM::WriteP4;\n\t\tusing PNM::WriteP5;\n\t\tusing PNM::WriteP6;\n\t\tusing PNM::WriteP7;\n\t};\n\n\tclass PNMTests : public ::testing::Test\n\t{\n\tprotected:\n\t\tvoid TestWriteAndReadGrayScale(std::function<void(std::ostream& outputStream, const Image& image)> writeFunc)\n\t\t{\n\t\t\t// Setup\n\t\t\tImage input(3, 2);\n\n\t\t\tinput.data[0] = 255;\n\t\t\tinput.data[1] = 0;\n\t\t\tinput.data[2] = 255;\n\t\t\tinput.data[3] = 55;\n\t\t\tinput.data[4] = 125;\n\t\t\tinput.data[5] = 200;\n\n\t\t\t// Test\n\t\t\tTestWriteAndRead(input, writeFunc);\n\t\t}\n\n\t\tvoid TestWriteAndReadBinary(std::function<void(std::ostream& outputStream, const Image& image)> writeFunc)\n\t\t{\n\t\t\t// Setup - Image will require padding\n\t\t\tImage input1(3, 2);\n\n\t\t\t// Row 1\n\t\t\tinput1.data[0] = 255;\n\t\t\tinput1.data[1] = 0;\n\t\t\tinput1.data[2] = 255;\n\n\t\t\t// Row 2\n\t\t\tinput1.data[3] = 0;\n\t\t\tinput1.data[4] = 255;\n\t\t\tinput1.data[5] = 255;\n\n\t\t\t// Test Padded Image\n\t\t\tTestWriteAndRead(input1, writeFunc);\n\n\t\t\t// Setup - Image will NOT require padding\n\t\t\tImage input2(8, 2);\n\n\t\t\t// Row 1\n\t\t\tinput2.data[0] = 255;\n\t\t\tinput2.data[1] = 0;\n\t\t\tinput2.data[2] = 255;\n\t\t\tinput2.data[3] = 0;\n\t\t\tinput2.data[4] = 255;\n\t\t\tinput2.data[5] = 255;\n\t\t\tinput2.data[6] = 255;\n\t\t\tinput2.data[7] = 255;\n\n\t\t\t// Row 2\n\t\t\tinput2.data[8] = 0;\n\t\t\tinput2.data[9] = 0;\n\t\t\tinput2.data[10] = 0;\n\t\t\tinput2.data[11] = 0;\n\t\t\tinput2.data[12] = 255;\n\t\t\tinput2.data[13] = 0;\n\t\t\tinput2.data[14] = 0;\n\t\t\tinput2.data[15] = 0;\n\n\t\t\t// Test Padded Image\n\t\t\tTestWriteAndRead(input2, writeFunc);\n\t\t}\n\n\t\tvoid TestWriteAndRead(const Image& inputImage, std::function<void(std::ostream& outputStream, const Image& image)> writeFunc)\n\t\t{\n\t\t\t// Execute - Write\n\t\t\tstd::ostringstream stream;\n\t\t\twriteFunc(stream, inputImage);\n\n\t\t\t// Execute - Read\n\t\t\tPNMTestharness pnm;\n\t\t\tImage outputImage;\n\t\t\tstd::istringstream iss(stream.str());\n\t\t\tpnm.ReadPNM(iss, outputImage);\n\n\t\t\t// Assert\n\t\t\tEXPECT_EQ(inputImage.width, outputImage.width);\n\t\t\tEXPECT_EQ(inputImage.height, outputImage.height);\n\t\t\tTestUtilities::AssertImages(inputImage, outputImage);\n\t\t}\n\t};\n\n\tTEST_F(PNMTests, PNMRead1BitBinaryTest)\n\t{\n\t\t// Setup - 1-bit Binary Data\n\t\tchar buffer[] = { static_cast<char>(0xA0), static_cast<char>(0x40), static_cast<char>(0xA0) }; // 10100000 01000000 10100000\n\t\tstd::istringstream stream(buffer);\n\n\t\t// Execute - Will convert to 8-bit Gray Scale\n\t\tPNMTestharness pnm;\n\t\tImage image(3, 3);\n\t\tpnm.Read1BitBinary(stream, image);\n\n\t\t// Assert\n\t\tconst Pixel8 expected[] = { \n\t\t\tPalette::Black, Palette::White, Palette::Black,\n\t\t\tPalette::White, Palette::Black, Palette::White,\n\t\t\tPalette::Black, Palette::White, Palette::Black \n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expected);\n\t}\n\n\tTEST_F(PNMTests, PNMRead8BitBinaryTest)\n\t{\n\t\t// Setup - 8-bit Gray Scale Data (0 to 255)\n\t\tconst char buffer[] = { \n\t\t\tstatic_cast<char>(0xFF), static_cast<char>(0x01), static_cast<char>(0xFF), \n\t\t\tstatic_cast<char>(0x01), static_cast<char>(0x7C), static_cast<char>(0x7B), \n\t\t\tstatic_cast<char>(0x7A), static_cast<char>(0x79), static_cast<char>(0x78) \n\t\t};\n\t\tstd::istringstream stream(buffer);\n\n\t\t// Execute\n\t\tPNMTestharness pnm;\n\t\tImage image(3, 3);\n\t\tpnm.Read8BitBinary(stream, image);\n\n\t\t// Assert\n\t\tTestUtilities::AssertImageData(image, (Pixel8*)buffer);\n\t}\n\n\tTEST_F(PNMTests, PNMRead24BitBinaryTest)\n\t{\n\t\t// Setup - 24-bit RGB Data\n\t\tconst char buffer[] = { \n\t\t\tstatic_cast<char>(0xFF), static_cast<char>(0x01), static_cast<char>(0x01),\tstatic_cast<char>(0x01), static_cast<char>(0xFF), static_cast<char>(0x01),\tstatic_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0xFF), \n\t\t\tstatic_cast<char>(0xFF), static_cast<char>(0xFF), static_cast<char>(0xFF),\tstatic_cast<char>(0x78), static_cast<char>(0x78), static_cast<char>(0x78),\tstatic_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0x01) \n\t\t};\n\t\tstd::istringstream stream(buffer);\n\n\t\t// Execute - Will convert to 8-bit Gray Scale\n\t\tPNMTestharness pnm;\n\t\tImage image(3, 2);\n\t\tpnm.ColorToGrayscale<3>(stream, image, GrayscaleAlgorithms::MEAN);\n\n\t\t// Assert\n\t\tconst Pixel8 expected[] = { \n\t\t\tGrayscale::Mean(0xFF, 0x01, 0x01), Grayscale::Mean(0x01, 0xFF, 0x01), Grayscale::Mean(0x01, 0x01, 0xFF),\n\t\t\tGrayscale::Mean(0xFF, 0xFF, 0xFF), Grayscale::Mean(0x78, 0x78, 0x78), Grayscale::Mean(0x01, 0x01, 0x01)\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expected);\n\t}\n\n\tTEST_F(PNMTests, PNMRead32BitBinaryTest)\n\t{\n\t\t// Setup - 32-bit RGBA\n\t\tconst char buffer[] = {\n\t\t\tstatic_cast<char>(0xFF), static_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0x01),\t\tstatic_cast<char>(0x01), static_cast<char>(0xFF), static_cast<char>(0x01), static_cast<char>(0x01),\t\tstatic_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0xFF), static_cast<char>(0x01),\n\t\t\tstatic_cast<char>(0xFF), static_cast<char>(0xFF), static_cast<char>(0xFF), static_cast<char>(0x01),\t\tstatic_cast<char>(0x78), static_cast<char>(0x78), static_cast<char>(0x78), static_cast<char>(0x01),\t\tstatic_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0x01), static_cast<char>(0x01)\n\t\t};\n\t\tstd::istringstream stream(buffer);\n\n\t\t// Execute - Will convert to 8-bit Gray Scale\n\t\tPNMTestharness pnm;\n\t\tImage image(3, 2);\n\t\tpnm.ColorToGrayscale<4>(stream, image, GrayscaleAlgorithms::MEAN);\n\n\t\t// Assert\n\t\tconst Pixel8 expected[] = {\n\t\t\tGrayscale::Mean(0xFF, 0x01, 0x01), Grayscale::Mean(0x01, 0xFF, 0x01), Grayscale::Mean(0x01, 0x01, 0xFF),\n\t\t\tGrayscale::Mean(0xFF, 0xFF, 0xFF), Grayscale::Mean(0x78, 0x78, 0x78), Grayscale::Mean(0x01, 0x01, 0x01)\n\t\t};\n\n\t\tTestUtilities::AssertImageData(image, expected);\n\t}\n\n\tTEST_F(PNMTests, PNMReadPNMBadFormatTest)\n\t{\n\t\t// There is no P8\n\t\tstd::istringstream stream(\"P8 1 0 255\");\n\t\tPNMTestharness pnm;\n\t\tImage image;\n\n\t\tEXPECT_ANY_THROW(pnm.ReadPNM(stream, image));\n\t}\n\n\tTEST_F(PNMTests, PNMWriteAndReadP4Test)\n\t{\n\t\tPNMTestharness pnm;\n\t\tTestWriteAndReadBinary([&](std::ostream &outputStream, const Image &image) {\n\t\t\tpnm.WriteP4(outputStream, image);\n\t\t});\n\t}\n\n\tTEST_F(PNMTests, PNMWriteAndReadP5Test)\n\t{\n\t\tPNMTestharness pnm;\n\t\tTestWriteAndReadGrayScale([&](std::ostream &outputStream, const Image &image) {\n\t\t\tpnm.WriteP5(outputStream, image);\n\t\t});\n\t}\n\n\tTEST_F(PNMTests, PNMWriteAndReadP6Test)\n\t{\n\t\tPNMTestharness pnm;\n\t\tTestWriteAndReadGrayScale([&](std::ostream &outputStream, const Image &image) {\n\t\t\tpnm.WriteP6(outputStream, image);\n\t\t});\n\t}\n\n\tTEST_F(PNMTests, PNMWriteAndReadP7Test)\n\t{\n\t\tPNMTestharness pnm;\n\t\tTestWriteAndReadGrayScale([&](std::ostream &outputStream, const Image &image) {\n\t\t\tpnm.WriteP7(outputStream, image);\n\t\t});\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/PaletteTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(PaletteTests, PaletteTest)\n\t{\n\t\tconstexpr Pixel32 rgb = Palette::RGB(10, 21, 32);\n\t\tconstexpr Pixel32 rgba = Palette::RGBA(10, 21, 32, 43);\n\t\tconstexpr Pixel32 gray = Palette::RGB(124, 124, 124);\n\n\t\t// Verify Endian\n\t\tEXPECT_EQ((Pixel32)0xFF20150A, rgb); // 0A = 10, 15 = 21, 20 = 32\n\t\tEXPECT_EQ((Pixel32)0x2B20150A, rgba); // 2B = 43\n\n\t\t// Compaire that the colors are equivolent\n\t\tEXPECT_EQ(Palette::Red(rgb), Palette::Red(rgba));\n\t\tEXPECT_EQ(Palette::Green(rgb), Palette::Green(rgba));\n\t\tEXPECT_EQ(Palette::Blue(rgb), Palette::Blue(rgba));\n\n\t\t// Get individual colors from Pixel\n\t\tEXPECT_EQ(Palette::Red(rgba), 10);\n\t\tEXPECT_EQ(Palette::Green(rgba), 21);\n\t\tEXPECT_EQ(Palette::Blue(rgba), 32);\n\n\t\t// Update Alpha\n\t\tEXPECT_EQ(Palette::Alpha(rgb), 255);\n\t\tEXPECT_EQ(Palette::Alpha(rgba), 43);\n\t\tEXPECT_EQ(Palette::UpdateAlpha(rgb, 43), rgba);\n\n\t\t// Gray Values\n\t\tEXPECT_FALSE(Palette::IsGray(rgba));\n\t\tEXPECT_TRUE(Palette::IsGray(gray));\n\t}\n\n\tTEST(PaletteTests, PaletteColorDistanceTest)\n\t{\n\t\t// When there are no differences, 0\n\t\tint noDistance = Palette::ColorDistance(Palette::RGB(255, 0, 0), Palette::RGB(255, 0, 0));\n\t\tEXPECT_EQ(0, noDistance);\n\n\t\t// Changing from one color to the next should result in a distance change\n\t\tint hueDistance1 = Palette::ColorDistance(Palette::RGB(0, 255, 0), Palette::RGB(0, 0, 255));\n\t\tEXPECT_NE(0, hueDistance1);\n\n\t\tint hueDistance2 = Palette::ColorDistance(Palette::RGB(255, 0, 0), Palette::RGB(0, 0, 255));\n\t\tEXPECT_NE(0, hueDistance2);\n\n\t\tint hueDistance3 = Palette::ColorDistance(Palette::RGB(0, 0, 255), Palette::RGB(0, 255, 0));\n\t\tEXPECT_NE(0, hueDistance3);\n\n\t\t// Ensure that evenly distributed changes have an effect\n\t\tint brightnessDistance1 = Palette::ColorDistance(Palette::RGB(10, 20, 30), Palette::RGB(12, 22, 32));\n\t\tEXPECT_NE(0, brightnessDistance1);\n\n\t\t// Technically this is grayscale, it is questionable if this should effect things.\n\t\t// TODO: Research this.  It seems to comply with CIE Delta-E results. \n\t\tint brightnessDistance2 = Palette::ColorDistance(Palette::RGB(10, 10, 10), Palette::RGB(12, 12, 12));\n\t\tEXPECT_NE(0, brightnessDistance2);\n\n\t\t// Verify the degree of change is great enough to be detected\n\t\tint colorDistance1 = Palette::ColorDistance(Palette::RGB(255, 255, 0), Palette::RGB(255, 128, 0)); // Yellow to Orange\n\t\tint colorDistance2 = Palette::ColorDistance(Palette::RGB(255, 255, 0), Palette::RGB(128, 255, 0)); // Yellow to Light Green\n\t\tint colorDistance3 = Palette::ColorDistance(Palette::RGB(255, 128, 0), Palette::RGB(128, 255, 0)); // Orange to Light Green\n\n\t\t// Orange to Green should obviously be farther that the difference between Yellow to Orange, and Yellow to Light Green.\n\t\tEXPECT_TRUE(colorDistance3 > colorDistance1 && colorDistance3 > colorDistance2);\n\n\t\t// Even though equally distributed, Light Green is a lot closer to Yellow than Orange.\n\t\t// This is consistant with CIE Delta-E calculations.\n\t\tEXPECT_TRUE(colorDistance1 > colorDistance2);\n\n\t\t// Ensure that color comparison order does not matter\n\t\tint left = Palette::ColorDistance(Palette::RGB(255, 128, 50), Palette::RGB(50, 128, 128));\n\t\tint right = Palette::ColorDistance(Palette::RGB(50, 128, 128), Palette::RGB(255, 128, 50));\n\t\tEXPECT_EQ(left, right);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/ParametersTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(ParametersTests, ParametersGetTest)\n\t{\n\t\tParameters param({ {\"x\", 1}, {\"y\", 1.1 } });\n\n\t\t// Int Exists\n\t\tint x = param.Get(\"x\", 4);\n\t\tEXPECT_EQ(1, x);\n\n\t\t// Double Exists\n\t\tdouble y = param.Get(\"y\", 2.2);\n\t\tEXPECT_NEAR(1.1, y, 0.0001);\n\n\t\t// Does not exist\n\t\tint z = param.Get(\"z\", 4);\n\t\tEXPECT_EQ(4, z);\n\t}\n\n\tTEST(ParametersTests, ParametersGetCastTest)\n\t{\n\t\tParameters param({ {\"intVal\", 1}, {\"doubleVal\", 1.0 } });\n\n\t\t// Cast Double to Int\n\t\tint x = param.Get(\"doubleVal\", 4);\n\t\tEXPECT_EQ(1, x);\n\n\t\t// Cast Int to Double\n\t\tdouble y = param.Get(\"intVal\", 4.4);\n\t\tEXPECT_EQ(1.0, y);\n\t}\n\n\tTEST(ParametersTests, ParametersSetTest)\n\t{\n\t\tParameters param({ { \"z\", 4 } });\n\n\t\t// Verify it was initialized\n\t\tEXPECT_EQ(param.Get(\"z\", 0), 4);\n\n\t\t// Set Int\n\t\tparam.Set(\"x\", 1);\n\t\tEXPECT_EQ(1, param.Get(\"x\", 22));\n\n\t\t// Set Double\n\t\tparam.Set(\"y\", 1.1);\n\t\tEXPECT_NEAR(1.1, param.Get(\"y\", 22.22), 0.0001);\n\n\t\t// Set Existing Value\n\t\tparam.Set(\"z\", 5);\n\t\tEXPECT_EQ(5, param.Get(\"z\", 22));\n\t}\n\n\tTEST(ParametersTests, ParametersParser)\n\t{\n\t\t// Parsed as a JSON string\n\t\tParameters params = Parameters::FromJson(R\"({\"window\": 75, \"custom\": \"test\", \"k\": -0.01})\");\n\n\t\tEXPECT_EQ(params.Get(\"window\", 0), 75);\n\t\tEXPECT_NEAR(params.Get(\"k\", 0.0), -0.01, 0.0001);\n\t}\n}\n\n"
  },
  {
    "path": "Doxa.Test/RegionTests.cpp",
    "content": "#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tTEST(RegionTests, RegionConstructorTest)\n\t{\n\t\tRegion::Point upperLeft(0, 0);\n\t\tRegion::Point bottomRight(10, 15);\n\t\tRegion regionPoints(upperLeft, bottomRight);\n\n\t\tRegion regionCoords(0, 0, 10, 15);\n\n\t\tRegion regionWH(11, 16);\n\n\t\tRegion regionWindow(0, 0, 15);\n\n\t\tEXPECT_TRUE(regionPoints == regionCoords);\n\t\tEXPECT_TRUE(regionCoords == regionWH);\n\t\tEXPECT_EQ(15 * 15, regionWindow.Area());\n\t}\n\n\tTEST(RegionTests, RegionTest)\n\t{\n\t\tRegion region(10, 20, 30, 40);\n\n\t\tEXPECT_EQ(region.Height(), 21);\n\t\tEXPECT_EQ(region.Width(), 21);\n\t\tEXPECT_EQ(region.Area(), 441);\n\t}\n\n\tTEST(RegionTests, RegionInRegionTest)\n\t{\n\t\tRegion regionParent(10, 10, 50, 50);\n\t\tRegion regionChild(20, 20, 40, 40);\n\t\tRegion regionNeighbor(50, 10, 100, 50);\n\t\tRegion regionThirdCousin(40, 15, 60, 45);\n\n\t\tEXPECT_TRUE(regionParent.InRegion(regionParent));\n\t\tEXPECT_TRUE(regionParent.InRegion(regionChild));\n\t\tEXPECT_FALSE(regionParent.InRegion(regionNeighbor));\n\t\tEXPECT_FALSE(regionParent.InRegion(regionThirdCousin));\n\t}\n\n\tTEST(RegionTests, RegionPointTest)\n\t{\n\t\tRegion region1(0, 0, 10, 10);\n\t\tRegion region2(10, 10, 20, 20);\n\n\t\tEXPECT_FALSE(region1.upperLeft == region1.bottomRight);\n\t\tEXPECT_FALSE(region1.upperLeft == region2.upperLeft);\n\t\tEXPECT_FALSE(region1.upperLeft == region2.bottomRight);\n\t\tEXPECT_TRUE(region1.bottomRight == region2.upperLeft);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/Resources/2JohnC1V3.ppm",
    "content": "P6\n707\n441\n255\nƳƳǴǴȵȵȵǴǴƳȵȵȵȵȵȵȵȵƳƳŲıııŲƳȶȸɹɹʸʸʷʷ˵ʴȰƮĬſľº·ºǼǿŮǳȱűŮƲȳͺ˸ǴððıǴǴɶʷʷɶɶȵ˸˸̹̹̹˸ʷɶʷɶɶʷ˸ȵðſºƾìȰɱȰȰɳʴ˴̵ʹ˳ɯǬæɿşƠʤЭϴ˷ȲȲʴ̶˳ʲǭɳкѻͷʴ̶кккϹϹϹθθθкϹкѻӽҼθʴʴ˵̶ͷθθθθкккккккккѻѻккθͷ̶̶ͷθθθθ̶̶ͷͷ̶̶˵˵˵˵ʴ̶θθͷ̶ͷθ˵̶ͷθθͷ̶˵̹̹̹̹̹̹̹̹˸˸˸˸˸˸˸˸˹˹˹̺̺ͻͻͻͻͻͻͻͻͻͻͻ̹̹̹̹̹̹̹̹̹ͺͺλλϼϼϼккϹθθͷ̶̶ϹкѻҼѻкθͷλλϼϼϼннннннѾѾѾҿҿннѾѾннннѾѾѾѾннѾѾѾѾѾннϼϼϼнннннϼλͺλλλλλλλλϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺκϼмммннѽѽнннϼϼλͻλѻϹθϹнѾоϽ̼ξѾϿϼξнѾѾнϼͻͻͻͻμϽϼϼϼϼϼϼϼϼнѾѾҿҿѾѾннϼϼλλλϼϼѾѾѾннϼλͺҼҼҼѻѻԾӽкθθϹҹͲγδͳ˱ǭéêƭǯɱʲʴ˵͸ϺлѼѼлϺϺϺϺϺϺϺϺϺͶͶϸййййϸι͸͸̷̷͸͸ιιлѼлι͸ιлϹθ̶̶θϹϹθͷͷ̶ͷθϹкѽннѾѾѾҿҿҿϼϼϼϼϼϼϼлԺҶжилѽϾν̻ͼͽϼμͺͷ̶̶θкҼѻλ˸ɵӿӿѽннϼϽμμμλλϼϼϿϿ̻̻ͼνоѿҿҿѾѾѾнннμμμϽϽоооϽϽϽϽϽϽϽϽннϼλͺͺ̹̹ͺͺͺλλϼϼϼμϽϽμ̺˹ͻϽϽооѿѿѿоооϽμμоѿоϽϽϽϽϽϽϽϽϽϽϽϽϽμμμоϽμͻ̺̺ͻͻμμμϽϽϽооооϽϽϽμμμμŲŲǴǴȵȵȵǴƳŲǴǴǴǴǴǴǴǴƳŲıııŲƳƳʸʸɷɷȶȶȵȵȲǱůíſľſľļýƾðưǴɳɶʴȵȲǴȵȵƳ¯ƿðŲȵȵɶʷʷʷʷʷ̹̹̹̹̹˸ʷɶ̹ʷɶʷʷ˸ʷʴƱǰɲ˴͵͵˳ʲɱʲ˴˴ʴʱɱɯǭũŧɪ˫ʪ˫вз̶ʴɳʲ˳̴̴ʰĪŬĩȾ¨ɲθкϹ˵ʴ̶ϹкккϹϹϹθθӽѻккϹθ̶ʴϹϹθθθθϹϹккккккккккккϹθͷ̶˸˸̹̹̹̹̹̹̹̹̹̹˸˸ʷʷȲʴ̶ͷ˵ʴ˵̶ɳʴ˵˵̶ͷθθ̹̹̹̹̹̹̹̹˸˸˸˸˸˸˸˸˹˹˹̺̺ͻͻͻͻͻͻͻͻͻͻͻ̹̹̹̹̹̹̹̹ͺλλλλϼϼϼккϹθθͷ̶̶ϹкѻҼѻкθͷλλϼϼϼнннѾѾѾѾҿҿҿннϼϼннннѾѾѾѾҿҿѾѾѾѾѾннϼϼϼϼϼннϼϼλͺλλλλλλλλϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ̹̹͹ϼϼннѾѾѾѾооϾννͼͼλѻϹθϹнѾнϼμϽооϿϿѾононѾҿѾнϼλͺͺͺ̹ϼϼϼϼϼϼϼϼѾѾѾѾѾѾѾѾнϼϼλλϼнѾҿҿѾнннϼϼռҹε̳εӺ׾ռӺзεεзѸҹззззз϶ζ͵͵̵ͶͶ̶̶˵˶ʷ̸κϻммϻκκκκκκκκκ͹͹κϻϻϻϻκ͹̸̸˷˷̸̸͹̸κϻϻ͹͹κмҽлιιϺллϺιι͸ιϺлѼҽннѾѾѾҿҿҿλλλϼϼϼнѼӻѹиιлнϾνʷ̹ͻϼѻиϵδ̵ηѺӼӼҼϹͷӿӿӿӿҿҿѾннϼλλ̺ͻͻͻͻμμμ˼˼̽;ϽϽооҾҾҾѽҽҽѼѼμμμϽϽоооϽϽϽϽϽϽϽϽннϼϼλͺ̹̹ͺͺͺλλϼϼϼϽооμ̺̺ͻϽϽооѿѿоϽϽоϽμоѿоϽϽϽϽϽϽϽϽѿооϽϽμμμѿоϽμͻͻͻμμμϽϽϽооооооϽϽϽμμμððŲƳǴȵȵǴŲıŲŲŲŲŲŲŲŲŲŲıııŲƳǴ˹˹ɷȶȶȶȵɶɳǱůíſſžĿĽĿƿïıǳȵʶɶʶɶɵǴƳı¯žƿðŲȵȵɶɶʷ˸˸̹̹̹̹̹˸ʷɶȵ˸˸ʷɶɶʷʷ̶ɴɲɲɲ˳˳˳˳ɱ˳ʳʳǱưǱɱʲȯɮͲϳ̰αжзθ̶˵ʲ˳̴̴˱˱̳εγ˰ʯʰͶθθ̶ʴʴͷϹѻкккϹϹϹϹҼѻѻккϹϹϹѻкϹθθϹкѻѻккϹϹккѻккккϹθ̶̶˸˸˸˸˸̹̹̹̹̹ͺͺ̹˸ʷʷ˵̶̶˵ɳǱȲɳͷͷͷͷθθθθ̹̹̹̹̹̹̹̹̹̹˸˸˸˸ʷʷ˹˹˹̺̺ͻͻͻμμͻͻͻͻ̺̺̹̹̹̹̹̹̹̹λλλϼϼϼϼϼϹϹϹθθͷͷͷϹкѻҼѻкθͷͺλλλϼϼϼнѾѾѾѾҿҿϼϼϼλϼннѾнѾѾҿҿҿҿѾѾѾннϼϼϼλλϼϼϼϼλͺϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺ̹̹̹̹̹̹̹̹λλͺͺͺ̹̹̹ϼнѾѾҿѾннооϾνοͼ;ͼнкθϹϼнλͺμϽоϽξξҿӽѾннѾҿҿҿѾнϼλͺ̹˸ϼϼϼϼϼϼϼϼѾѾѾѾѾѾѾѾннλλλϼѾҿҿѾѾннѾҿӽؿҹȯÿǮ϶ӺֽѺйϻϹϻкнҼѾҼнѻϼϹλλ͹͹κϻϻϻκκϻϻϻϻϻϻϻϻκκκκκκκκ͹͹̸̸̸̸͹͹˷͹κκκκϻѽҽлιιϺллιιι͸ιϺлѼҽϼнннѾѾѾҿϼϼϼϼнннѼҽлϺϻнѾпλϻнӽӻҸѴϳͳϵϹһӼһѼѻѾҾҾҾҿҿҿҿѾѾѾннϼϼϼͻͻͻͺͻͺͻμ̽;;;μϽϽϽӿҾҾҾҽһһһλμμϽϽоооооооооооѾннϼλͺͺͺͺͺͺλλϼϼϼϽооϽͻ̺μоϽооооϽμμоϽϽоѿоооϽϽϽϽоооϽμμμϽѿоϽϽμμϽϽϽϽϽϽоооѿѿоооϽϽϽϽϽðıƳȵȵǴŲıððððððððŲııııŲƳǴʷɶȵǴȵɶʷ˸ɶȵǱĮí¬¬¬½½¯ıƳɶɶɶɶʷɶȵƳǴŲððıǴǴǴǴȵɶʷ˸̹ͺͺ̹˸ʷɶȵʷʷʷɶȵȵɶ˵ȳǰǰƯȰȰɱʲ˳̴˴ɲƯŮưɳɳǱȲͶι˶̶ϹѸззε˳ʲ˳˳˱δ϶εʹεʹ̲Ͷͷ˵ʴʴ̶θкѻѻкккϹϹϹкѻѻѻккѻѻккккѻѻѻѻѻѻϹϹϹϹѻѻϹккϹϹͷ̶˵ʷʸʸʸ˹̺̺ͻ̺̺ͻͻͻ̺ʸɶ̶̶˵ɳǱǱɳ˵ккккϹϹθθ̹̹̹̹̹̹̹̹̹̹̹˸˸ʷʷʷ˸˸˸̹̹ͺͺͺλλλͺͺ̹̹̹̹̹̹̹̹̹̹̹ϼϼϼϼϼϼϼϼϹϹθθθθͷͷϹкѻҼѻкθͷ̹ͺͺͺλλλϼннѾѾѾҿҿҿϼϼλλλϼѾҿϼнҿҿҿѾѾѾннϼϼϼͺλλϼϼϼλͺϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺ̹̹̹̹̹̹̹̹ϼϼλλͺͺͺ̹ϽнѿѿѿоϿξο;;нϼͺͺλλ̹˸̹ͺͺ̹˹̺μоѼѺлϺϺлѼѼѻѻннмϻκκϼϼϼϼϼϼϼϼҿѾѾннѾѾҿѾнλͺλнҿѾѾннѾҿؿ϶tmnrzī϶ӼлϺͺιλѼѾҾҿѽнκͻκμϻϻϻκ͹͹͹κκϻϻϻϻϻϻϻϻϼλͺ̹̹ͺλϼκκ͹͹͹͹κκʶ̸κκκκмҾҿѽϻϻммϻκκκ͹κϻмѽҾϺлллѼѼѼҽҽҽҽҽѼѼѼѼӾнϼϾѾҾӻӹҶα̬ɩŪƫǯʱ̳δηϷҼҼҾҾӾӾҿҿѾнннннмϻϼϼϼкϼкϼϼпоонϼӿӿҼҼӼҹҹһλμμϽϽоооѿѿѿѿѿѿѿѿѾѾнϼλλͺͺͺͺͺλλϼϼϼооѿϽͻͻμооооооϽμͻоϽϽѿѿϽѿоϽϽоѿѿϽμμϽϽооϽϽϽоѿѿϽϽϽоооѿѿѿѿоооϽϽϽϽžžðŲǴǴǴŲı¯¯¯¯¯¯¯¯ıııııŲǴǴǴǴƳǴȵʷ̹λɶȵǱůííĮİ¿¿¿¯ŲǴȵ̹˸˸̹ͺ̹˸ɶ̸ʷǴıð¯¯¯ŲŲŲƳǴȵɶʷͺͺͺ̹˸ʷɶȵȵɶʷʷȵȵȵʴ˶ʳʳʳ˳˳̴͵̴͵̵ɲŮĭǲʵƲŰƱʷ˸ɶɷ̹ѸѸѸз̴ʲʲʲȮͳε˲ʱ̳̳ɲ͸̶ʴɳ˵θкҼѻѻѻккϹϹϹкѻѻѻϹθϹϹҼԾտԾӽҼѻϹθθϹѻҼϹϹϹϹθͷ̶˵ʷʸʸʸʸ˹ͻͻ˹̺ͻμͻ̺ʸɶ˵˵ʴȲưǱʴͷθθϹккϹθθ̹̹̹̹̹̹̹̹̹̹̹˸˸ʷʷʷ˸˸˸̹̹ͺͺͺλλλͺͺ̹̹̹̹̹̹̹̹̹̹̹ϼϼϼϼϼϼϼϼϹϹθθθθͷͷϹкѻҼѻкθͷ̹̹̹ͺͺͺλλнннѾѾҿҿҿϼλͺͺλϼѾҿϼнҿҿѾѾѾннϼϼϼͺͺλϼϼϼλλϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺ̹̹̹̹̹̹̹̹нϼϼλλͺͺͺϼоѿоϿξ;ѿϼͺͺͺͺ˸ɶʷ˸˸ʷɶɶ̺ϼйжθηηϺϺлθϹϼнѽѽммϼϼϼϼϼϼϼϼҿѾѾннѾѾҿѾнλͺλнҿѾнннѾؿԻ˲hljQ_]D\\ZAb`GpnUlƭͶι̹̹̹ͺϼѾҿнϼ̹ʷʷʷ̹ͺѽмκ͹̸̸͹κϻϻϻϻϻϻϻϻнλ̹ʷʷ̹λϼϻκκ͹͹κκϻʶ̸κκκκмҾҿѽϻϻммϻκκκ͹κϻмѽҽϺϺϺлллѼѼӾӾӾҽҽѼѼѼѾпѽҼҺҵͰɩĢȽɾʿ¨ŬǮȱѹѻѽѽҽҽѾѾннннннммҿӽҼҼҼҼѼѼѿннӿӿӽҼӺҹҹһλμμϽϽоооѿѿѿѿѿѿѿѿѾѾнϼϼλͺͺͺͺͺλλϼϼϼоѿѿϽͻͻμооооооμͻͻоϽоϽооооѿϽμμϽϽϽϽϽϽоѿϽϽϽооѿѿѿѿѿѿооϽϽϽϽƿĽžŲǴƳŲŲŲŲŲıð¯ðǴʷƳŲŲııŲŲƳ˵ɳưưȲʴ˸˸ʷɶȵƳııðİĲƴʸ˹ͻμͻ̺ɷǴʶȵǴƳŲŲııııƳǴɶ˸̹ͺ˸˸˸ʷʷʷɶɶ˸̹ͺ˸ɶǴȵʴƱǰʳ̵ζϷζζ˴˴˴˴̶̶˸˸ȵȵȵɷȷȷɺʷʱ˰̱̱˱˱̲ͳηηͷ̶˵ʴȲȱ͸ͷ̶̶ͷθкѻкϹϹθθϹϹккѻҼкθ̶̶ͷкϹкҼԾԾҼϹϹккѻѻккϹϹϹθͷͷͷθθʷ˸˸̹̹̹ͺͺͺ̹˸̹̹˸ǴŲǱǱǱǱɳʴ̶ͷθθθθθθθθͺͺͺ̹̹˸˸˸ɶ˸̹̹ʷȵȵɶθθθϹϹϹϹϹϹϹϹϹϹϹϹϹ̹̹̹ͺͺͺλλϼϼϼϼϼϼϼϼϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹͺͺͺͺͺͺͺͺнϼϼϼϼнѾҿѾѾѾѾѾѾѾѾϼͺѾҿнѾѾѾнϼλλλλλλλλλλλλϼϼϼλλͺͺͺϼннѾнλͺ˸ϼϼϼλλͺͺͺͺλλλλλλλͺϼѾѾнλλλѾҿнϼϼͼʹο˿˿μλλλλλλλϹ̶ʴ˵θкϼϺ϶ҷҺҹѸѻйηѺйҼԾӿннннннннҿѾϼλλϼѾҿѾҿҿнϼнѾҿнϼλλнѾӽҹ׼ؽ̱{~cuqVsoT|auè˰϶ѽѾнλ̹ͺнҿѾѾϼͺ˸̹ϼҿӿҿҿнͺ̹ͺλнннϼϼλλλнϼ̹ʷȵʷͺнλλλλλͺͺ̹̹˸˸˸̹λϼѽӾҽѼллѼҽӾιϺϺϺллллϺηͶͶϸйһԽһӼԽԽԽӼѺлнλͼϾоͺϷжβǧŻĪʲ͵ѻӽҽлҾѿҿӿҾӽҼлѺӼԽҼѻӽӽԾԾվԽӼһλμμϽϽоооѾҿҿҿҿѾнϼͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμμоѿѿϽϽоͻͻμϽѿѿоϽμμμμμμϽϽϽоооϽϽϽооѿѿѿѿѿоϽϽμͻͻͻƿ¯ıŲŲŲŲƳŲƳŲı¯ðƳɶǴǴƳƳƳƳǴǴʴǱůĮǱɳɶɶɶȵǴƳıððı°ųǵʸ˹ͻͻͻ˹ȶƳƲƳƳƳŲð¯¯¯ıŲǴȵʷʷ˸ʷʷʷɶɶɶɶ˸̹ͺ˸ɶǴȵʴƱȱʳ̵ζζζζ˴˴˴̴̶̶˸̸ɶɶɷȶȹɺʻ̹ɱ˰̱̱˱˱̲ͳηηͷͷ̶ʴɳɲιθͷ̶̶θϹккϹϹθθϹϹкϹкѻϹͷ̶ͷθ̶̶ͷкӽӽҼкϹккѻѻккϹθθͷͷͷθϹϹʷɶʷʷ˸̹ͺλͺ̹˸̹̹˸ȵŲʴʴɳʴʴ̶ͷθθθθθθθθθͺͺͺ̹̹˸˸˸̹ͺλͺʷɶɶʷ˵˵˵˵̶ͷθϹϹϹϹϹϹϹϹϹ̹ͺͺͺλλλϼϼϼϼϼϼϼϼϼϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹλλλλλλλλнннϼннѾѾннннннннλͺѾѾϼϼннϼλλλϼϼϼϼϼϼϼϼϼϼнϼλλͺͺͺλλλнѾѾнϼλϼϼλλλλλλλλλλϼϼϼϼλϼнѾнϼϼϼ͸ικϺлѾѾϾп;μλλλλλλλθͷ̶ͷϹϹ˵ǰɯ̰̲ʰȮɰ˲̵йѺӽӽҾмҾннннннннѾѾнϼϼнѾѾѾҿҿѾннннϼнѾнϼλλкӻؽٿԹ¨|puéȭ̲зλмѿҾоѽҿҿѽλ̷ȵʵ̹лнѾѾϼ̹˸̹λͺͺͺλλϼϼϼϼλͺ˸ʷʷͺϼλͺ̹ʷɶʷʷ˸ʷ˸ͺλͺͺͺͺмл͹͸̸ιϻѼ͹ι̸͸͹ϺκлͷͶ̶Ͷ̶ϸϹѺϹѺѻӼѻѺϹϸӾϼννϿͻ˸ȵ˳ͳɬľ{slmkowɿʰ̴кӽԿҽҾӿѿҿҿҾҼӽӻѺһӼԺӺӺԾԾԾԾԽӼһҽμμϽϽϽоооѾѾҿҿѾѾнϼͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμϽѿѿϽμϽѿμμϽооѿѿооϽμμμμμμμμϽϽϽоϽϽϽооѿѿѿѿѿоϽϽμͻͻͻ¯¯ððððıŲƳƳǴǴƳŲððŲȵȵȵȵȵȵȵȵȵȲƮĬĬưȲȲȲɶȵǵƴųĲñı¿¿¯ŲǴʷ˸˸˸ʷȵƳŲűŲǴǴǴŲ¯¯ðıŲǴɶʷʷʷʷʷɶɶȵȵȵ˸̹ͺ˸ɶǴȵʴǲȱɲ˴͵ζζζ̷̷ͷͷͷͷ͹ι͹̸ʷɶȶʸ˺λʲˮˮ̯˱̲̲̲ηϸθθ͹̸˷˶ϺϹθ̶̶ͷθϹϹϹθθθθϹϹͷϹкϹͷͷθϹʴʴ̶θҼӽѻϹϹϹккккϹϹͷͷͷͷθϹкѻϹθͷ̶̶θϹкϹθͷϹкѻϹͷθͷͷ̶̶ͷθθθθθθθθθθͺͺ̹̹̹̹˸˸ͺͺͺ˸ȵǴȵʷ̶˵˵̶ͷϹкѻϹϹϹϹϹϹϹϹͺλλλϼϼϼнϼϼϼϼϼλλλϹϹϹϹϹϹϹϹккккккккϼϼϼϼϼϼϼϼѾнннннннϼϼϼϼϼϼϼϼнͺͺҿнλλϼϼλλλϼннϼϼϼϼϼϼϼϼѾнλͺ̹ͺλϼ˸̹λϼннннλλλλλϼϼϼннннϼϼϼϼϼϼϼϼϼϼϼϺȲȲɳ˵̶̸͹ͻѾϾνοϿϿμλλλλλϹϹͷͷζииʲſøƸǹ·Ż©ͳйԾҼϹθлѽннннннннѾѾннннѾѾҿѾѾѾннннͺнҿϼ̹̹θѹӹ׽׽ҸūžĪĪéūǯʵͷϼкλθͺϹнѻϻ̶ʶʴιѼλϼϼͺ˸ʷ̹ͺͺͺͺͺͺͺͺͺϹϹͷ̶̶̶̶ͷҿнͺ˸ʷ˸̹ͺȵ̹ннλ˸˸̹кϹθͷͷθϹккϹθͷθϹѻҼϹϹθθθθϹккѻҼҼӽҼҼѻмϻλλϼλ˹ɶŲʳδƩ}j^|YxWvUyYe{ɿ˱̲϶ѻӾмѿѿҾӿҾҼϹϷηж϶ϴδ϶ԺӼӼӼӻӽӽӽտտԿӾҽнμϽϽϽооооѾѾҿҿѾнϼϼͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμѿѿϽμμϽооооооооооϽϽϽϽϽμͻͻͻμμϽϽϽϽϽооооѿѿѿѿоϽϽμͻͻμıŲƳıðŲƳǴǴȵȵƳıðŲƳǴǴȵȵȵȵǴȲɱƮĬŭưȲȲǱɶɶɷȶǵƴųĲ¿ıǴȵʷʷ˸ʷɶǴŲıƳǴʷ˸˸ȵŲðŲƳǴȵʷ˸̹̹ʷʷɶɶȵȵȵȵ˸̹ͺ˸ɶǴȵʴȳȱɲʳ̴͵͵͵̷̷ͷͷͷηιιϺιʶɵȶʷ̻л˱ˮˮˮ̲̲̲˱ηηθθκ͹̸͸лкθͷ̶̶ͷθϹϹθͷͷθϹϹθϹѻкϹθкѻ̶̶ͷϹѻҼкθθϹккккϹθ̶̶̶ͷθϹѻѻкϷͷ˳˵˳ͷζ˵ʲ˵͵кҺѻккϹθͷͷͷͷͷͷͷͷͷͷͷͷͷ̹̹̹̹̹̹̹̹ʷ˸ʷɶƳƳȵʷ˵̶ͷθϹϹθθθθθθθθθθλλϼϼϼнннϼϼϼλλλλͺϹϹϹϹϹϹϹϹккккккккѾѾѾѾѾѾѾѾннѾѾннϼϼнннϼϼϼϼϼнͺϼнλϼλλλλϼнѾѾннннннннѾнλ̹̹ͺλϼ̹̹ͺͺλλλλλλλϼϼϼϼнѾѾѾннннϼѾϼλλϼϼϼιʹɯȮʰʲɳʴ͹ϺннϾϿϿμλλλλλϹϹͷ͵ζи͵}~~|z{é̲ӻѻͷ̶лҽннннннннѾѾѾннѾѾѾҿѾннѾѾнλ̹нѾͺ˸ͺѻͶδ϶ԺֽҸǮƿŻƿɿǱǱǱƯíĭƯɱȰʲ͵εʹʹʹθ̹ͺͺ̹ʷʷ̹ͺϼϼλλͺ̹˸˸кϷθ͵θ͵̶˳нϼλͺ̹̹ͺͺȵ̹ннͺ˸ͺϼкϷ͸͵̷ζιиϺζ̷̴̷ζϺҼιθ͸ͷ̷ͷ̷ͷϺкϺѻлѻлѻθκϻнннͻ̹ɴϸӹȫ{bvRwTtRrPvUc|Ǫβδ͵εһѼоѿҾӿҿӾҾѻζϷϵϳ̱˰˱ͲγϳϳϵϵϷϷϹտտҿнϼϽϽϽоооѿѿѿѿѿѿѿѿѿѿнѾѾѾѾнϼλͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμѿѿϽͻͻϽѿѿѿооϽϽϽμμϽϽоϽϽϽͻͻͻͻμμϽϽоооооооооооϽϽμμμμŲƳȵı¯ŲƳƳǴȵȵǴŲıŲƳŲƳǴȵȵǴƳưɱȮƮƮȰȰȲưʷʷ˹˹ʺȸǷƴ¯®ïűǳȴɵɵɵɵȴƲűűƳȵʷ̹̹ʷǴıǴǴȵɶʷ˸̹̹ʷʷʷɶɶȵȵȵ˸̹ͺ˸ɶǴȵʴȳȱɲɲ˳̴̴͵˹̹̹̹͹ιηϷиϷ˴ɳȵ˵ͺйͰ̭ʭˮͰα̲ʰͶͶ͹κκκͻλлкθͷ̶̶ͷθϹθͷͷͷͷθϹϹѻҼҼккѻӽѻккѻҼѻθ˵θθϹккϹθθ̶̶̶ͷθϹѻѻ̴̲˳ʰʲ˱͵δ˳ɯȰʰ̴δ͵͵ϹϹͷ̶˵˵˵̶ͷͷͷͷͷͷͷͷ̹̹̹̹̹̹̹̹ɶʷ˸ʷȵǴɶʷʴ˳͵ϷϷ͵˳ɱζζζζζζζθλλϼϼϼнннϼϼϼλλͺͺ̹ϹϹϹϹϹϹϹϹккккккккҿҿҿҿҿҿҿҿϼнѾѾѾнϼϼҿҿѾѾнннϼнλнϼλѾλλλλϼнѾѾнннннннннϼλͺ̹ͺλλннϼϼλλλλϼϼϼϼϼϼϼϼѾѾѾннϼϼϼѾϼͺͺλλ̹ɴʰŪ§ƪƬūɰϹͶϺѾнμͻμоμμλλλλϹϹ͵͵ζϵʰtca~_~^z]~`pĪии̶ͷѼҽннннннннѾѾѾҿҿѾѾѾҿнϼϼѾѾϼͺλннϼ̹˸ͺл̳ɮƬɮ˱ɮ˿¸÷ĸǽɽǻȼǻ÷ùžĽ¨ɯͳͳ̱ɮȯ̶̹̹̹ʷʷ̹λλλͺͺͺͺͺ͸ѺжͶδηϵ̵ʰǴȵɶ˸˸˸ʷʷʷͺϼλ̹̹λл̵̲ɳʰȲ˱ʴͳ˵̲ʴ˱ʴͳ̶ηʴ˴ʴ˴ʴʳɳʳͷͶ̶Ͷ̶ηͷηϷкҼҾнϼͺ̷̹ӼԻɮg~tQsOrNsO{XhƻͰѵж̴ɰη׿ӾоѿӿӾѽѻиѹѷͲȮƪũǪƧȨʭ̯ϲϵϵϷտտпϽϽоооѿѿѿѿѿѿѿѿѿѿѿннѾѾннϼλͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμѿѿϽͻͻϽѿооϽμμ̺ͻϽооооϽͻͻͻμμϽϽϽооооооооооϽϽϽϽμμϽŲƳɶıðƳƳıƳǴȵȵƳŲƳǴŲƳǴȵȵǴƳưʲȮǯǯȰɱǱưɶʷ˹˹˻ɹȸƴİïïİİƲǳǳȴȴǳǳǳƲƲƲŲƳȵɶɶȵƳŲŲƳƳǴȵɶɶʷ˸˸˸ʷʷʷɶɶ˸̹ͺ˸ɶǴȵʴɴɲȱȱʲ˳̴͵ʸ˸˸̸̸͸ζζϷζ˴ʳɳ˳˷ηͰ̭ɬʭαϲ̲ʰ˴̵̸͹κκμλϺϹθ̶̶ͷθϹθθͷͷͷͷθθкѻҼҼкϹкѻӽҼѻѻѻк̶ɳθθϹϹϹϹθθͷͷͷͷθϹкѹͳϲδϲϵгϵг̲ˮɯˮ̲αδͳζͷ̶˵˵˵˵˵̶̶̶̶̶̶̶̶˸˸̹̹̹̹ͺͺ̹ͺλͺʷȵǴɳ˵˳̴̴̴̴̴˳͵͵͵͵͵͵͵͵ͺλλλϼϼϼнϼϼλλͺ̹̹̹ϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹϹҿҿҿҿҿҿҿҿͺλнѾҿѾнϼҿҿѾннϼнλϼҿнͺλҿϼϼλλλϼннϼϼϼϼϼϼϼϼϼϼϼλλͺͺͺҿѾϼλλλλѾѾннϼϼϼλѾѾѾнϼλλλѾϼͺͺλ̹ǴìøǻǮʱͶлнͻ˹̺ϽμμλλλλϹϹζ͵δϵʰpyZrQ}nO}nO{lO{mP|`qĽϷѹͷθҽѼннннннннѾѾҿҿҿҿѾѾнͺλѾҿϼ̹ϼλͺ̹˸ɶȵǲīʾĸ}z{Ĩ̮ϲΰ̯ʰʵ˸̹̹˸˸ͺнɶɶʷ˸̹λλϺж̰ȮȬʰ˯ȮƪıƳɶʷ˸̹̹ͺͺͺ̹˸ɶȳȯǬƭŪŬƫǮȭ˲˰̳̱ʹͲʹʹȲɳʴʴ˵ʴʴɳϹθͷ̶˵̶̶Ͷ̴зҹҼϹ̹ʷʷ͸һϹƫĻryV~nJnHpLwSd}ŸɪϲӶζɰ˴־տооѿҾҽѽѻ͵ͳʯèĹȨΰѴҸҺӽӿоооѿѿѿоооооооонннннϼλλͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμѿѿϽμμϽѿѿѿооϽϽϽ˹̺μоѿѿѿоμμϽϽϽоооѿѿооооϽϽϽϽϽϽϽϽϽϽоıŲɶııǴŲ¯ŲƳȵȵǴƳǴȵŲǴɶʷʷɶǴưȰǭƮƮǯǯůíƳǴɷʸʺȸƶųŲưůůůưưưưưưưưưǱȲǴǴȵɶɶȵǴǴƳƳǴǴȵɶɶʷ̹̹̹̹˸˸ʷʷ˸̹ͺ˸ɶǴȵʴʵɲȱȱɱʲ˳̴ȸɸʷ˷˷̷͵͵Ͳ̲˲ʱʲ˱ʴͳαˬɪˬαгͳɯɲʳʶ̸ͻͻͻλιθͷ̶̶θϹкθͷͷ̶̶ͷͷθϹкѻкθ̶ͷθѻкϹккϹ̶ɳͷθθϹϹθθͷθθͷͷͷθϹϷгвϲͯʭƨ¥Ŀ½½Ʃ˭ααζͷ̶˵˵˵̶̶̶̶̶̶̶̶̶̶˸˸˸̹̹ͺͺͺͺϼнλȵðƿſſſŭȰ͵͵͵͵͵͵͵͵̹ͺͺͺλλλϼϼϼλλͺ̹˸˸ϹϹϹϹϹϹϹϹθθθθθθθθѾѾѾѾѾѾѾѾ˸ͺϼҿҿѾҿҿѾнϼλλϼͺͺλ˸ɶ̹ҿннϼλλλϼϼϼϼϼϼϼϼϼϼͺλϼннλ̹˸ͺ̹˸ʷʷʷ˸̹ҿҿнϼλͺͺѾннϼλͺͺ̹Ѿλ̹ͺλ˸ðļxrv|Ǯ˵лϺ˸ɶ˸ͺμμλλλλϹϹиζϵҸгw{ZoMxhGvgFufGseH|qUdϷҺͷθлιннннннннѾѾҿҿѾѾϼ̹ͺѾҿϼ˸ϼͺ˸̹˸ƳĽ}||ohbeezĦʪϱѴʵ˸̹̹˸̹ϼѾʷʷɶɶɶɶɶɴūƿ»Ľ»ļ¯ȵ˸ͺ˸˸ͺͺɶǿʾ¨ĨĪĨ¨ɽʾ˿ǱưĮ¬ƿĪɯ̴̶˵˶̷̷ϸʴèȿcsOqKnHqM~[qĻʭҵҺ̵̳־ԾϽѾѿҾҽѽк͵̲ŪùxwxľɩвӶӻѻҾооѿѿѿооооооооϼннннϼλͺͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμϽѿѿϽμϽѿѿооооооϽɷ˹μоѿоϽϽооѿѿѿѿѿѿѿооϽϽϽϽϽϽϽϽϽϽϽоıðȵıŲǴŲñƴȶȵǴǴȵɶǴȵʷ˸˸ʸȶǴǯƬŭŭƮƮĬ¬ůŲǴȵȶǵĲñƳǱǱưưưůůůůĮůưǱȲɳ˷˷˷˷˷ʷ˸˸ȵɶɶʷʷ˸̹̹ͺκͻ̹̺̹˸˸˸̹ͺ˸ɶǴȵɶʵɴȳǲɳʴ˵̶ȷɶɶʶ˶˶̴̴˱˱ʱ˲ʲʲʳ˱γʭȭʯγϵͳɱȱɲʴ˵̸͹͹͹θͷ̶̶ͷθкѹθ͵͵̴̴͵͵ζθϹкθ̶ʲʲ˳ζ͵͵θϹθ̶ɳͷθθϹϹθθͷϹϹθͷͷͷθζ̯˭Ȫ¢~ǩɬζͷͷ̶̶ͷͷθ̶̶̶̶̶̶̶̶˸˸˸̹̹ͺͺͺ̹Ϲλ̶įļü̵͵͵͵͵ͷͷͷͷͷ̹θͺθλϹϼкλθ̹ͷ̶˵ϹϷϷϷϷϷϷϷ͵͵͵͵͵͵͵͵ѼѼѼѼѺѺѺѺʳ̵ϺѽѿѾѾнϼλλͺ̹λ̶˵˵ȱŮʳһѺѺлϼλμϼμλλλλλλλλ̹λнҿҼк̷ʵįįî­îŰǲɳտҿҾмϻκ͹ннϼλͻ̺̺˹оλ̹ͺϹʴphjlp~ƭ˴кϼʷȵɶ̹λλλλλλλλѻϹкԼӻƬ`pOvfEueDrcDpaDwiNw[}жӻθηη˶ѽѽѽѽѽноноѾԾҼѻϼ̹ͺѾҿϼ˸λͷʵ̵˵īqlijmqtxz¶ȼ´why^uWtV~uV`oſʪдʵ˸̹̹̹ͺнҿϼ͸˶ȳŰʿɿŽ¬˵ʴʴ͹͹ű~}~~¶ƪɯ̴ϹҼθιȱ§Ⱦl~ZyQrJpGwRd}Ʀҵּз϶־׿ѻкѻҽҾҾҽҽкֽӹɮĹtlh`j| ̮ϵҹмѾооѿѿооооооооϼннннϼλͺͺ̹̹̹̹ͺλϼϽоѿоμͻμϽоооϽϽμμμμоѿѿϽϽоооооооооɷ˹μѿѿѿооѿѿѿѿѿѿооϽϽϽϽϽϽϽϽϽϽϽоųȶȶųññųƴñƶʺ˻ƴĲƳƳŰƲȵʷ˹˹˻ʺʷ͵˯ǭĪ¨¨éĬŭȲ˵˵ȲůűŲȲƱȳ̷˶ŰíĮ¬¬¬íůȱȲ˴ι̹˸ʷɶɶʷʷɶʷʸɷƵƵȷ˹ϼλͽλͽϼϽо˺˺ʷȶȶȶȶȶ˺ʹɸȷȶȶȵɶ˷˵˵˴ʳɲǰƯƯưȲʴ̶̶˵˵Ͷʳɴ˴Ͷ̶̶̴ȱͳʹʱɯͳжзиз˲Ǯɰ϶зͲʹͲ̲ͳͳδδϴйлͶɳʲδ̲ǭǭ˱δ˳ʱ̳ϹҼθϹϹϹϹθͷ̶ͷͷͷͷͷͷͷ͵ʯʭħuic^ckwåɯ̶̹κ̸ʶɴʳ˴˴ʳɰɱ˳̵Ͷ̷ͺͺͺͺκκθϹϹ˳θʳɾ·wljkmtȾŬʳйл̶ȵʷͺ˶˴̷Ͷ͸ηкиθ͵˵ʲɳ˲ʹͳжϵδ̲ʰȮȬȬǫƪƩƩȫˮαгʹ϶ѸҷѴϰέέɪǪƫǱʷ̼̽̿ѿ͸ʵ˶ιл͸ɴɳªľüƻƨǫ˯϶лͿͺǳʵѼϼϼѾκ͹̶ͷйжǬɽȽǰ͵ѻҼѺлѼϺ˶нѾҿҿϿͽ̼̼ͺ͹кѸ̳ĩf`}Y{X]g˵ҿͺκιι̷ͺλͼ̻̽ο˺̻нϼιǿttUo`Ao`An]AiX<tdJz`}ƭͳʹʹδ͵ԼҺлҽλ˻ͻнҿӾһѺйϺ˸̺ͺɶʶɶ̵˰Ūοŵi[zQyP]kr{ƿ¥Ŭʱ̿³{rcynRxmOzoQuWe|˲˶Ƶǵ˹˸ȵͷԾҽʳīêȾ~{y}ĹĨũ˯жηο|heegmt~pnqsrt|{wwrtzħ˱϶ͷмʷɴʴíwVvG}oB}pC|oE}qG]uťӵոչּջҸӷԸԻӻѹϹιиԻҸ̯ɻp]{TxNWiʿϲԺտнѿϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿμμͻͻͻμϽϽϽϽϽϽϽϽϽϽѿооϽμμϽϽϽооѿѿѿѿоϽϽѿѿоϽϽоѿѿоооѿѿѿϽϽϽϽϽооϽϽϽоѿѿѿųǵǵĲ°ñųųñĴ˺̼ɷŴǴűøƻƵ˹̼ͽλ̴˯˱ʰɯȮǭǭƮɱ͵͵˲ȯưưǲƱȳ̷˶ƱîůĮĮůůǱʳ˴̵ɴɴǴȳƳǲƳŲȵɶɷɷƵǶȷ˹ѾѾнϿнμμɸʷȶƴĳòòòɹɸȹȷǶȶɷɶʳɲȱǰŮĭ¬ĮůǱɳʴʴɶʶ̹˷ɶ˶͸̶̶˳ʰͳͲͲͱϳдϴϵзʹɰʱ϶еͲͲͲͳααϲϲϴϸиͶɰȮɭũžȾ¦çƭʹҼθθϹϹθθͷ̶ͷͷͷͷͷͷͷ͵˲ȫžt^yQtKrGwMYlƿĪʴʷʷʶʵɴ̴ζ͵˳ɰʱ˴Ͷ̶˵̹ͺͺͺκκϸϸ϶˲̵ʳɽv}_vUqPqPtW~a}êɰϺϺ˸ȵɷ̷̵̵̹ͶͶͶϷϷ͵͵̴˳ʹεеж̰ʮƪĨççæ¥¢ãƦʪήѱϴѸѶб̫ǣûƷοƶ˿Ͻι̷Ϻҽҽ͸ȳŸȽéʳϽ̺Ȳɵлҿϼнκ͹̶̴ϵβçøvmuīʳиѻйϺѼѼϺϼнϿͿͽͽͺ͹θз̱ħþd~ZwRvP{VbȾɵѿо̻͹ιͷ̷͸λͼ̽̽ʾ˼;˺λǲ`vgHo`An]AkZ>tcIqWnƺɯ϶Ѹѷеѹиιлҿξ̼μϾҿӾһѸϹϺʷʸϽ̹ȵɵ˵˴ƪ˼ðm[yNvK|Qcuſæɬʯɰɱ̴Ϻ˺̺òt{^ynPulMvkM~uVk©ʷŴǵʷʷɳ˵ийȮǽxy|}{qihp|ķˮ˱˻sy[wWvXz]gu¸z`[}YZ[an}zspmifkzĻƩʱ˶ͺ˸ȵʷ̸ư~~UqBug8uh;vi=wkAwN^wƦбҵչֺԸѴԷֻֽսҺкϺԽҸͰ˾n\\{SwMUfʽαԼнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿϽμμͻͻμϽϽϽϽϽϽϽϽϽϽѿооϽμμϽϽоооѿѿѿѿоϽϽѿоϽϽоѿѿоооѿѿѿоϽϽϽϽϽѿооϽϽооѿѿĲƴųñ°°ĲĲñŲʷɷ¯ļ·ûııİŭǭɯʰ˱ʰȮƬëƮʲ˳ɱƮĬëĭíǱư««ëëĬŭǮɰɳưǰǳǱƲưűİǳȴɶɶȶȶɷ˹λлϼмϼ͹ʷɶȵȳǳƲŲŲŲŴ̺˹ɹʷɶȳȳȳʱɰȯƭŬŬíí¬íĮưƳǴǴȴ̸̷̷̸̹ͷ˵ɱȮȮȭʯʮʮɮ˰ζкϹ˵˲ε϶̳εε͵ͳδδϵеηηʴǮĪ¦¹ĪϷθθϹϹθͷ̶̶̶̶̶̶̶̶̶̴ʹȫixQ~kCzg=i@oE}UnƽħƩȳɶʴȲȱɲ͵Ϸζ̴ʱ˲˴Ͷ̶˵̹̹̹̹͹͹ηηʹɰ˴ɲȼoqSyiHscBtdCwhKuXw©ȯιιɶǴȶ˸͸͸ͶͶ̵̵̵̵ʲ˳̲ͳδͳͳ̲ĨƿĽĽü»üĽæȫ̯ϲҹҹеͰŦûʼͻιϺҽӾ͸ȳzsswɳͺϾξκ˵˷Ϻϼλнκκ̶˳ͳ˯Ƚp|]~oPrU}`sƼǰ͵ϹͶ̷лнϼ͹κϼнϿϿϿξϿͺ̸̶ε˰Ũd{WsNrLxS`ĺƲϽϽ̻͹ι̶̷ιϼν̽̽ʾ̽˼ǶλϺīqpTq`Do[@p\\At`GudJt\\s©жպҹδζ͵͸ϺнҿξͽμϾҿӾӼҹкϺʷɷ˹ͺʷɶɵ˵Ǯɾ{j\\vOwQ}Xf|ʽťˬͰͳ͵̶̶ιιλͼѾμɲ¬»qvWvpPpgHpjJy\\uȳƳǴ̶ͷʴȳʳǭĽwkhnvɿ©ȾzkcafyŪŷnvXuUuW{^nǼ­îĭì¸r{YuOqM~pKuO[r~zvqużū˵͸ȵȵǴɴ˵ëy|S|nAqc6qd7tg;th>xlD}tM^wŧͯѴӶҵгԷؽӾлϺһҺγr`{SvLTd~Ȼ̯ӻнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿϽϽμμμμϽϽϽϽϽϽϽоооѿооϽμμϽоооѿѿѿѿоϽоѿѿϽооѿооооѿѿѿѿѿѿоϽϽϽϽоѿѿоϽϽооѿоĲĲññ°°ññ°°ǴƳĽ}ummuĽſƾĪǭȮɯȮȮëŭǯȰǯŭëʿůĮʿȽǿ«««ëëŭƮǮȰʱʲ̳̳˲ʱȲǱɵʷɶȶǵȶʶȴ˴˷ͷ̸ʴǴưǲȳȴɵɶʷʷʷ͹̸ʶɵȲɲɰʰɰȯǮƭŬŬůů¬íıŲŲƲ˸κ͸̷̶ͷɱĬĪüĺƻźʼʲϹѻͷ˲ʹʹ̳εε͵͵ζδζϷ̳̳ʱĪĻzvtw|ɯ͵θθθθͷ̶˵˵˵˵˵˵˵˵˳϶ɬ»kyUnF}j@mDsK\\uť˫ȬʳʵɴɳǱɲ̵Ϸζ˴ʱ˲˴̵˵˵˸˸˸˸˷˷̵̵ʱƭȱȱɽlnPwgFrbAtdCwhKvYyƭ̷͸ɶƳȶ˸ϼιηͶ̵˴ʳʳǯɯͳϵδɯé»»Ľžƿ¦ũɭ̰βѻѻзʯ~sljo|˼ɹϿ͹ιϺѼӾѼ͸ɴſ{ohfpuŽĮʶͺмϹ͹͸̹˸ͺн͹κͷʲ̲ȬdqPo`?m^?viI{^~Ŭ˴θʴȴ̷λλ̸̸ͺλξϿϿϿѾκ˷̳ʹ˰Ʃ¤f{WrMpJxS_¸űϽϽͼκϺθ̷ιϼϼͼ̽ʾο˺Ƴ̹ҽ˲ƶy]s_DnZ?r^Cq]DkW>zfN{cĸͳԺҹε̳͵ζιλλ̼˻ͽμнѾҽҽѻѺн̹ɷɷ˸˷ʶʴǰi~YvQsN~]j|̾ǫ̱γж˴ȳȲɶ̸̹ʷǵʷ̷Ͷϵɭi`ztTxrR}`vƱǲʴζϷ̴ǰƬ~od^eq¸Ŭʱʱ˲ʹ˰ĩú}mc_bk~Ⱥ´ucbdn̵ʵ˶̵̵ɰƼmzXsM~nJ|nIuO_{˥ͨʦź©ʲκϼɶɶȵȳƭȺixRnCwf;vg<xi@xjCzlG}qKyUe~ƦϯѳвѴԷջ׾վҽѼѼмҺϴ¥v`zUuK}Rc|ǺˮӻнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿооϽμμμμϽϽϽϽооооѿѿѿѿооϽϽϽоооѿѿѿѿϽоѿооѿоооооооѿооϽμμϽϽоѿоϽϽϽоооĲ°°ññññññıȲ{duY{mRwiNyiOsXhyļûƾìƯǰé¨ƿžĽĽüŹĸʻªɽƺƼ¨¨éǫȫȬɬȮȮǭǯƮȲʴʴȴƲǳǳȲʱ̶εͷ̴ʴȰȱɲɲɲȲǱůĮªëëĬūȭɯ˰Ȯǭūé¨ſðıű˶ιϺ̷˵̶ǯſ»«˵ѻͷɳɳʴɳ̶̶̶ͷͷ͵θζ˲˲ǭ¦ȿuib~^`j|ǫ͵ͷθθͷͷ̶˵˵˵˵˵˵˵˵˳ʹʭƿu_tNnFnFrJYr¢ɪȫ˲˴˴ʲɰɰ˲ʹʹ˲ʱʱʳ˴ʴɳ˸˸ʷʷʶʶʳʳǮêƯȱ˿¶nziKtdCp`?scBwhKtWuɿŬ˶̷ȵƳȶ˸ϼι͸̷˴ʳɲɲǭʰδϳʮ¼žƿĨũƪǭɯ̲ͳͶллη˱vh^^ev˼ȳ̹κι͸͸ιι͸˶ǱĬžxi__ajĬϷкѻм̷ȵȵʷ̸̹ϻͷʲʰǫz~]{mJl^;hY8naAsVyŬ˴Ϲ̶Ǵʷ̼ͺʷ˵˸̹ͻμϿо̹ɶʲ˳ʰǪ¥exToJnHvQ^¸űоѿνмлθ̷ιннͼ̽˿ɽɽνƳɶϺȰν|at_DnY>s^Cq[CfR9p\\C~mSpͲѷѷϳεϸη˷ɵȵȵͻμϼнѼѼѺѺнμ˹ɷɶ˸˸ʵ«o^vQuPxUhzĸªǮǱư̸ȴñıǶʹʹʸƳǴɳ̴жαzrowľǯɱ̵жж̰èżxmc^`l|¬ǱǱưǱɳͱ̰ǪüwcxTvS|Yivtxǻư̵̷Ϲηη̳ȾkrQmGyjCzlGuOc¼ΫаϯȪ¦ɿǻο;Ϳêȳ̹ϼϾ̻̹ʷȱ§z^tPpHlD}kE|jDyiE{kG~pK{X\\hĻ˩аϯгҵѷѸϸϺѽҽϻѻε§v`xStJ|Qb|ǺˮӻнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿѿѿоϽμμμϽϽϽϽооѿѿѿѿооооϽϽооѿѿѿѿооѿооѿоооооооϽϽϽμμμϽϽоѿоϽϽϽϽϽоñ°ĲųųĲñųƳĭhynRrdGqbEo`Am^AsdG|nQ|`n{º»¼ſĮưűİİů̳Ͳγγͳ̲ʰɯĭūìȽĹ·ƻʿ¤ĦȮǭǭƬĪſľſſſ¯ðűȳιϺ˴ɳ˲ĬzfgjjuưϹͷǱưǱȲʴʴ˵˵˵̶˸̶ʱȮũɾµpayVrQvUarɬ̵ͷͷͷͷ̶˵˵ʴʴʴʴʴʴʴʴɰɮĨhxToI~jEmGwSeöƩǮȲɳʳɱɰʱ˲̳ʱȯɰɱɲȲǳʷʷɶɶɵȴɲȱŬìƯ˿ĸqxgIrbAo_>rbAvgJtWtɿŬ˶̷ɶƳɷ̹λι͸̷˴ʳɲʰȮɭʮǫžæŨ˯˱̵̵̲͸ιιͺͺ͸˱ra|XzW_r̾ǰ˵κι͸̷̷̷̷͸˵ͷɲsdzWuRzVewʮ̳Ϲм˶ƳǴɶɶ˷ϻθʲʰƪrwTxjEl^9j\\9na?rRs˿ɰϸͷɶʸ̼ͻ˵˵˵ʷ˹ͻξϿϽ̹ɶʴ̴˱Ǫ¥atPlGlFuP|[|¸űоϾмϺθ̷ιѾѾν̻˼˿ǻɺпǴɴ̷ëνz_t_DpX>s[AoYAjT<kU=t`Gv^zȼʯԺϴѵзͷʴǳƳƳ̺ͻͺλϺϺйлϼϽ̺ȶɶͷ̷ȲùvbwVsPxS^vìǱɳɵǳʶƲïİȶ̺ͻͺͺͷ̴ͳδͰƨľéǭ˱δβ̰Ũrha`bjwŻíʴɳůůưṵ̊дϲȨe}uQ}sP~tQ{[mĶõ´ʾǮ˴̵θθ̵̵˲ȾknM}iDzhB{lEuReľ˫ϱгʰƯȱǳůǰƯǲʶϼ̻ͺ̶Ȯʾt{[oLnKmJlIkHmIpLrN~[xU{XlȾɦͬгдη̴˷͸ϼҿϼк̶u~_tQrH{Pc~ɼͰӻнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿоϽμμμϽϽϽооѿооооооооѿѿѿѿѿоѿоѿѿооооϽϽϽϽμμμͻμϽϽоѿоϽϽϽϽϽñƿ°ųǵƴĲĲƴȵawiLrcDrcDscBn]?o`ArcDwiL|qS{^fluh{b{b|a}b{afr¬ĭŬɮȫǪƩħ¥ƿƿĽ¦¦ſſſſ®İűƱιθȲǱɱiynR{pTrUrUc|˶ʵį­ıŲȵȵȵɶʶʶ˸˷Ȱǭçɾķp]sO~kJqO{YlȪ̲ͷͷͷͷ̶˵ʴɳɳɳɳɳɳɳɳīɮ˯ħu^uQ|jF|jFmIxTi~ƻʾ©ƭɯɯʯʱ˲˲ɰǮǮȲɳǲƱʷɶɶȵȴǳǰǰŬĭʾĸqziKrbAn^=qa@ufIuXxɿƭ̷͸ɶǴʸͺͺͷ̷˶˴ʳ˱˱īƼxqzľãťȫˮ̵̰̲͸ιλλλ˹̹͸˴¥o~[xRvS|Ym̾ɭ˳̶ιϺϺι͸̷̷̹ϺηȮr]vOypIvR^k¹ëʴκʵƳǴ˸ʷɵмϹʲ˱ƪj~pKug@n`9n`;oa>xkIeɿǱȳĲǴȷʷ̴˳˵˵ʷ̹ͻμμ˸ɶ˵͵˱Ǫ¥_sOlGnHvQ|[{İоѿνκ͸˵̵ηѼѾν̻˼˼ɺɺппȵʵ͸ë˷~tZv^DoW=pX>qY?p[@nX@p\\C|hO}cvƸɯ̰ϴϵζʴƳƴǵ˹˹˸̹͸ιϸϺ̹μ̺ǵȵ̷ʴƭewVqPrOyTaªɱɲɲɲƯí¬¬ĮǱɳɳθͷεͲ̱ɬɪʫŤ¡¾§īŪȮͰͱɬä¹o`|YzW^ivè˴йͶʳ˴˴ȱ˯ѵӶͭp~Z~vR|tPtTc˽¨¨Ī˳кѼкѻϹʳɲȯǽkqNmE|jD|mFwTiãʮϵиͷ˸ͺν˻˻˸̻ξʹ˸ɳçĹjuTnMkKkKoNwV^`_}[vSuR]rķ ̰ͲͶ͵̸͸λнϼϼʶ˼q{]rPpG{Pd̿αӻԿнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿѿоϽμμμϽϽооѿооооооооѿѿѿоѿѿѿоооϽϽμμμμͻͻͻμμϽоѿоϽμμϽϽñžñųȶǵųųǵʷbzkLteFueDueDl\\;l\\;m^?reE{mPy[hp~k|rYtjQsiNuiOwkQxjPpWgzzyxz}¾íŬ¥½}{zxvuuĽžžſſſſ®İƲŰ͸θǱƮȰ|_peIrgIwiLvhKvYsļȴɴ­ðŲǴǴǴȵɶɶʷʶȰƬçʿƹr|XoKygCmIvUgƦ̲ͷͷͷͷ̶˵ʴɳɳɳɳɳɳɳɳ©ʱѷϳȽk]zgFweAuc?zgFuSg|ŷǻƭɯɯʱ˲ʱȯƭƭǱȲƱŰɶɶȵǴǳƲǰƯƭ«ȼ¶oyhJp`?jZ9l\\;qbEsVyƭ̷͸ʷȵʸμ̹ͷ˶˶˴ʳ˱˱ɿúxpjfwţȨȨʭͱʰʳ˶͸λλͼͼʸ˸̷˴m|VvQtOyViȽʮͲ˴ϺҽԿҽϺ̷˶ͺѼл˱Ʃi{TvmFulE{qMzWmȼư˷ɴƳɶͺ̹ɵмкʲ˱ǫh{mHuh>pb;oa:m_:qc@xVo˿˾ĲƳ̵̲˳ʴʴ˸̺ͻͻ˸ʴ̶͵̴Ƭ`uQnIqKyT^}ïϽоͼ̸˶ɳ̵ηѼѼϼ̻˼ʻʻɸϾнɴ̷ϸŭƲypVv^DoW=mU;qY?w_Eu_Gs]EvbInU|cr̾ʭαгδʲȲǴɷʸʸʷ˸˶͸ηкʷͻ˹Ƴǲʴʱ¨uzYnMmJpMyTb¨ū¨ĽƼǽȼɽ̾Ϳ¨ƮȯɰʯǪƧɪͮʩǦĥ¥èĩŬīʭͯˮƦżs^uR}pMrO]oǾ¨ɲη̵˴ηͶȱṵ̃ϳʭ¢zcyU|tP}rRa{ͿƬͳɮƬɰϹԽԾҼӽкʳȱǮƺjrOlE|hC{kGuRhħɯζϹ˸ʸͽʻʺ˻;˿ɺɸɵŭƼ|_lImNjKjKsSdsvr|[wUuQ|Xbnŷɬ˱϶ϸθ͹ͺνϼλɵɺnx\\pNoF{PeϲӻӾнҿѾϽϽϽооѿѿѿоϽϽϽϽоѿоϽϽϽϽоѿѿоϽμμμϽϽоѿооооооооѿѿѿѿѿѿѿоооϽϽμμμͻͻͻͻͻμооѿоϽμμμϽ°ƿĲĲĲĲųƴǵȵjpQqbCm]<m]<n^=p`?sdE{nN{^m}nwkQeY?bV<hZ@i[@m]DwgNhŹĸ÷{vrtv}ľýxmfec^dnv}»ƿĭů¬®űǴűɵưɳȲŭȰ{uYqcHrdGn_BqbCwXlůĮɾʿįŰǴƳƳƳǴȵɶɵƮūç¥ƹowS~jEvb=ygAqMaɰ˵˵ʴȲȲʴ̶ɳɳɳʴʴ˵˵˵êǮͳҶȬzhtRrb@s`?n[:q^=}mKvTmõūǭʮαʯƭǮǮƭůưȳ˶ʷ˸˸˸̸˷˴ʳǮɰĭƾǻssbDl\\;iY8l\\;qbEtW|øêƭɴʵɶȵɷʸϼƳʴϹ˴ʳɰɿùzodxX_lţɧǧȨɬ˯ǭǰɴ˶ͺͼννȶ˸͸ͳl|WuQtOwTdĹũƫ̵ιлҽҽѼι̷ǵ̸ʶŬǬ̯ât]ymGthBuiC|nI~Yn¬ïȳ̹Ǵϼͺ˷̸˵˳ϵǫi}oJk\\3n_8m^7m_:pb?qbAyYn}Ʒƹ˾ıʰʰ˱ͶϺѼϼλϼ̹ʵ˶ͶͶʰƫawSqLrLzU_®˹̺ʹ˷ʵǱ˱̵͸͸̹˸̻ͼȷȷϾнɴ̷ηétmTw]DqY?pX>p[@s^CnY>s^CxcHxcH{fKwYvżɬϳɯŮ˶ͺȵǶĳðƳͷкζʴɷλ̺ǴȳʴĬƸbsR}jI~jGlInIeæ½³³ÿäƧɨί̭ȫǪǬǮůŬͰ̮Ͱ˫r\\yTxjEykFrM_vǾĥƬȲ˵θϹϹθͷ̲̯̯ΰ˫ýv~]}tS}tUgʾȮϵϵζεηθ̹͹ɶ˵ȱĭêƺivSnI}iFpL^vȫϵимѾʽ˼οοʹɵëgvP|hCjKkLnO}^|ɴï{a{WuQuQuO|Uk;̱ջӺϹκͺ˸ʸʷűŶhrVjHlC{Pg̿αѹлоѿѿѿѿоооооооооμμμμμϽѿѿѿѿоϽμμͻ̺ͻμϽϽоѿооооооооѿѿѿѿѿоооооооооѿѿϽμϽооѿѿооϽѿϽͻ̺̺ͻͻͻ°ƿ°°°ñĲųƳƯɿ~iwX~oP}mLwfHpQ`s»ýŽļźźqymShZ@eW<hZ?jZ@n^E|lSqǷõĶɽ˿ʾȾƼĺù¸ütjjrz|vmc}YwZz\\~`grûůĮİǳɶǳɵưȲȯŭʰéy}rVl^Ak]@fW8gX9vgHuXw¶ƺƺȽįǲǴǴǴȵɶʷ˷ƭĪéæåʽtxTlGxd?|hCtPcɰ˵̶˵ɳȲɳʴɳɳɳʴʴ˵˵˵ɰ˲ζжʯƻ}`zjHvcBkX7kX7ta@wdCyXyé˯ʯ̰ɯèƭǮȯȯưǱȳʵ˸˸˸˸˷˷˴ʳǮɰĭƾǻpsbDl\\;iY8l\\;rcFtW|øêƭɴʵɶɶɷʸϼƳʴϹʳʳǮƼ|j`wW~qO|ZlȦ˫ɩɬ̰δͶͶ͸̷˸ɸȷȶ˷͹ζ˯ȿj|WuNsLwTeźƩǬȱʵ͸лѼлϺ͸ȶ̸˵ưɰϴʫƽ~e~qNugBse@wgCuQdȽǲ̹ȵѾϼϻϻθζѷʮnsNo`7rc<qb;oa<oa>j[:|mNx[fu˺˰ͱϳжϸϺϼϼҿϼ͸ιη̵Ȯ§bwSoJpJwR|[{®˹˹ɸʶʵȲʰ̵̷̲˸˸˺ͼ˺ɸλͺƱʳͳ¬ofMrZ@pX>nY>r]BxdIr]Bu`EwbGu`CwbEnQdsˮ˯̲ϸϺɶɸƵŲǴͷкθʴʷλ̺ǲȲʲ¨Ĵ||[qPlKkHmJmHbv~}{{ƭɰɳɰͰ̭˫Ťm{VtP{lE{lEqM^vȿƩƯȲ˵θϹϹθͷ̴ʰ˱ϲͰãg~_~_r÷Ĭ̴ζ϶εͶθͷ̸̸ʷ̶ȳĭªǻhuUnJjHrQazȬϵϹϻϿʽ̼Ϳοοо̹˵ū}asI{h@{gFkNrSdʵűb|XuQtPqKtNayó¥ϴҷϸкλ͹ɷ˸ȲȹlwXnLmDzOeгҺлҿоѿѿѿѿоооооооооϽμμμϽϽоѿѿѿооϽμͻͻμμϽоѿѿооооооооѿѿѿѿѿѿѿѿѿѿѿѿѿоѿѿϽμϽооѿѿооϽѿϽͻ̺̺ͻμϽ°ƿƿƿƿƿñðǰūȾ{smenǻīǮȱððð¯­­ȼu}oUk[AgW=hX>iY?rbIt]~ĵ«ƮŭƭƭŬŬƬūũũ¤üùƼȾù{veyX|sR{ZnĿªīŬŬŪĿn]tUzmMviIzoOwYg{ŽưưƲȵʷɵɵưǯƮĭ˱ŬvxmQeW:eW:bS4`Q2jZ9qbC}`sĺƯƱǱȲȴɵɶʵŮŬĪũƪyxT~lHye@|hCrM_;ȯ˵ͷͷʴɳȲȲʴʴʴʴ˵˵˵˵̶ʹ˳̲ʮħĹpsRxeDjW6iU2nZ7lX5zgFb˼ȫʮ̯ʭŨŪǬɰʱȲȲȵɶ˸˸˸ʷ˷ʶ˴˴ƭȯìŽƺltcEm]<jZ9m]<sdGvY}źīƭɴʵʷɶɷʸλǴ˵ϹʳɲŬ~lwZrRzkLyjI|[qſʪʭȫʮͱϵѺйι̷ʷȵƳŲͷ϶δɬĻgyUrLqJwTiǼȫʰƯȳ˶ιллϺιʶ͹̶ȲͳӷгǨrwUugDo_=r_>}iFvVyǼŰ̹ɶҿѾммͷ͵ѷ˯qtOpa:td@sc?scArb@jZ9zjInPrUx\\izŵǫͰѶҹкθκϻѿϻϻϹʴêƼ~]sOlGmGuP{Zz®˹ʸǶɵʵʴɯ˱˴˶ʷʷʹ̻νɸ̹ʷįȱ˱˿jw_GnV>mX=mY>xdIuYuWqS}jLxcDvaB}fGpQwXwɾȫʹѻϻȴ˸ɶǴɶ̹Ϲͷʷɶͺ˹ȳȲʲξptSoNlIlInKnKdz{ywuw~|wrsy~ªʲͷͷϴˬǧǾetPpJmG~lFqM^yȬƱȵ˸ͺλλͺ̹˵˲˳ϵжˮž}vwʿȲ̶θηηθͷ̸̹˸͹θɴĭªǻjvVoKlJuTd|ɭϵϹϻξο̿˻˺̼ϿϿпоϽ͸̳ũsVmBxe;t`?{hHsSauu_zYvRuQrNqM~ZjôŨβ϶ѹϹͷȵ˶ǱȺlxYqOoFxMaãҵԼѼҿҿѿѿѿѿооооооооϽϽϽμϽооѿѿѿооϽμμμϽϽϽоѿѿооооооооѿѿѿѿѿоѿѿϽμооѿѿѿѿооѿϽͻ̺ͻμμо°ƿžžžžƿ°¯íììƼŻƯȳ˵Ǵƴıðëw~pUk[AgW=iX<hW=tfL{cȼǯë˿êǮǮƭǭǭǭǭǭʰɮƫ¨çȾɽŹkz`uZvkMtkJ{rQeüžŨĪŭŭǮưưǮŨĥq`~oNrcDsfFvhKxmOczưɳȵȵɶȵɳưǯƮū̲ǬttiKaS6dW7cT5`Q2fV5jZ9|mNy\\l{ǻ©ƬƯǯǱȴǳȳȳǲǰƭƬȫywU~lHwc@zfAnI~YwĵīȲ̶ͷ̶ʴʴʴʴ˵˵˵˵˵˵˵̶˵ȰǯȮȬɿ·xvWyfFlY8lX5q]:kW4wc@lOl˽ɭͰʮŨŪȭ˲̳ʴɳȵȵ̹˸ʷʷʶʶ˴˴ƭȯ«ŽǻhtcEn^=k[:n^=teHwZƻīǮʵ˶ʷɶʸʸλǴ˵θɲʰr|^zmMviGufEzlIa}ɬȬƪȬ̲δηͶ̷˶ʵɴɶʴ϶ѵϲǧ{bwSrLpLxVnʮ̲ǰɴ˶ιϺϺϺι͹ϻͷʴδӹҶͰż~^xhGp]=p\\;ybBjMpĹį˸ȵѾϼ͹͹ɳȰͳȬrrOn^:rb>scAvfDyiGvfExW~]{]z\\|^frźŦгպӺϹκмоϽκϻθɳù|wV~lH{gBjDtO|[|®˹ʸƵȴʵ˵ɯʰ˴ʳɴɶɸ˺пʷʷȳìǰȮŹzbu]EnX@nZ?o^BsWp}ozY}jJxcD{dEfH}hI`sźƬ϶Ϲ˷̹ʷɶʷ̹ͺͷʷɶ˻˹ȳɳȮ˺kqNmJkHkHnKsPmƣơ¾}uqqrty~ʴͺϹҷˮŧú_qMnHkFkHpObƯǱȵ˸λϼϼͺ̹͹˵̶ϷѹϵȬɾǳ˹˷ϺиϹθ͹͹̹̹κϹɴūëȼmvWoLmKvUf}ʮѷѹмнϾοͿͽ̸̺ͺλнѾмϻͶ̱¥hvK{h=vc8uc?zjHqQzXclkd|[{Z}Y\\|XxT|X`rŶĦɮ̲͵͵ʴʳŬ~fvVrMqGwL^ĤԷԼҽҿѾѿѿѿѿѿѿѿѿѿѿѿѿооϽϽϽооѿѿѿѿооϽϽμϽооѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿоϽооѿѿооѿϽͻͻͻμϽ°ƿƿƿƿƿ°ñ¯įíª˿ĪĪëíŰǱȵʶȵǴĲ¯ǿɾɾĬu|lRjY?gV:jV;gV<rcL}gɾǱ¬ɾǿȱǰƯŭĬĬĬŬȱǰŮíīĬĭƬɿŹ~hqTveKqbEobBvkK~`yæǫĨƬƮǮưůƲǲǰƪĦ¾n{XwhGsfDqdDncEzoSgůʴȵǴǶƳʴƮǯƮū̲ǬsugJbS6fW8fU7bR1eU4fV5n^=ufGsTduƪǭȰɱɳȲɲȳɴɴǰǮǫvzX}mIvd@weA~lH{Wsưʴ̶ͷ̶̶ͷ̶˵˵˵˵˵˵˵ʴ˵ɳǯȱɯɿutUxeEmZ9o[8v_=oY4yc>xcDvXs¥ϰͰȫǬɮ̳ʹʴɳȵɶ̹˸ʷɶʶʶ̵̵Ǯȯ«ƾȼ~dudFn^=l\\;o_>ufIy\\ȽīǮʵ˶ʷʷʸ˹κɵ˸ͷɲɯǽhsVvgHteDueD~nLhżũʮȮƬɯ̵ͶͶ̵˴ʳʳʳ˶̴дѳЯƤw^uOrMpL{Yuħ˱ζ˶̷ιϺϺϺι͸ккθ˵̵жжͱhziMq]Bq\\?w_CzeJkøŰ˸Ƴλ̸̹˷Ȳǯ˱ƪosRo_=rb@qa@ueD~nMtTnusnd}]_itǪѶӺкϻϻ˹ʸ˷͹ͷȲɾ{vU|jFwc>~f@pKxWy˹˹Ƶǳʵ˵ɯʰ˴ʳɴɴʷ̹нɶɶɴĭŮƿqrZv`Hs_FraExiLfǸa~kKvbAxaAzaBwcBrQ_u÷Ʈθϻ˸˸ʷ˸̹̹ͷ˸ȸ˻ʸǲȰǬǶhnLkI~hC{gDnKyVxʪʨǧǥŤâȿȿǾǾǼǼǼǼ|yw{ɴ̹ͺԻ̯ŧú_qMnIiD}iFqPfîǴʶ̸ϻммϻκϼλͺκкϷ˳ǭƬ«­ȶϽϿ̼Ϻкϼϻλͺͺ̹κθʵƬëȼmuVnMkLsSd|ɭҸҺҼҽнпϾϼ͸˵̷θѽӾѼи϶ˮľ`rF{i;zg<zkD}oJqOtOyU\\bbcgnrne_\\dnǼħɯδ͵̲§t~^tTtOsIvK^ťӶԼԿҿѾѿѿѿѿѿѿѿѿѿѿѿѿоϽϽооѿѿѿѿооооϽоѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿоϽоѿѿоѿϽμͻμϽо°ƿƿƿƿƿññŲð°¯įĮĮªíưɴʷɶǴƳǴǴĲñȽǼοnvfLfU9dS7hT9fU;l`H|fʿɳǰĭìʳʲǯŭëīīŮŰűűŰŰůůĮǻ~gnRuaFo[@kZ<pcCuUoƩʮɯȰȰǱưƲǳȵɴȮƪ¨ÿydqPufEo`Al_?shL~uXxʴȵƳƵƳ˵ǯȰǯūʰĩntfIbS4fW8eU4`P/bR1dT3fV5l\\:vgFuTarú¦ūȰ˲˵̵̴ʵɴƱīéüs|[oMvd@vd@}kG{Wt³©ưɳ˵̶̶ͷθ̶̶̶̶˵˵˵˵ʴͷ˵ɳʳɲƼp~oPtdCmZ9qZ8u_:lT.v^:xaAjK}_z´ǩ̯ʬȮ˰ʹʹʴɳɶʷͺ̹ʷȵɵʶ̵Ͷɰɰìǿɽz`udFo_>m]<p`?whKz]ʿŬǮʵ̷˸ʷʸ˹͹ʶ̹ͷȳɯĺ{`{nNrcDsdCueCoKi˿Ȯ̵˱ɲ̵ϸϸйϸ̵ʳɲȱɲʰΰбϬšrYrLrMpL|[{·ƪʳζ͸͸ιιιι͸͸кϹθ̶̵̵ͳ̲©k|kQu_Gv^Dy_FyaI|e·Ʊ˸Ų̹ʷκκʴɱͳƪnvWscBtdCqa@scBqP`sc[cjtǪͲ϶θκȶȶȴʶ˵ưɾzY}kGvb=zb<jEqPpĿ̺̺Ƕǳɴ̳ɯ˯̲˴ʵʵ˸ͺϼɶʵ˶ĭƿzt[~hPvbItcIwhKvYtŸ~_zjHubAwcBzaBybBoNwUcv÷ů̸ȶɶʷʷ˸˸ͷ͹ʺ̻ȶŰƮĪĳfmKjEzd?wc@lI|Yø¥ɬɬȫɬʭȫĩèèèèĩĪƫ§ȿ»ĽİʵɹʷӺ̱ǪƽdsPpKiD~gEnOf¶ðǴʶ͹ϻѽмϻκϿξϼλϹ̶ʲʵʵȳȵ̼ϼϹϻκͺ̹̹˸˷ͷʵǭĬȼjtUlKfHnOaxȫӶӸӺһҽѾѾѽηͳ̲϶ӺԽӻжеȪwXpEk>m?xi@ykFzlG}oJvQ[hoyxkc\\_kz̲˱ʮp{ZuRvQtJwL_ťгӻѾнѿооооѿѿѿѿѿѿоооѿѿѿѿѿѿѿѿѿѿоооѿѿѿѿѿоϽμμϽоѿ°ƿƿƿžƿ°ñŵĳñĳƳİ¬ɾĲǶȶǷĴĳĴĴĲĲ¯ǼƻǸgp_EcO4dP5hS6eT:k_G~i­˶ʵȳȲ̶ʴȲůĮŮƯǲƱųųųıïíhziOo[@lW:kV9kX:qdDbƫʰɯʲɳȴǳǴȵʹʷɱʯƮ¨¦q{YufEl]>l_?peItkNgǱǴǴȷɶ˵ȰʰȮêǮʾhpbE`Q2eV7dT3aQ0fV5jZ9p`>td@|lJvSyXbuǮʱ̳͵ǲŰ­pyX|lJsa=sa={iE{WyƷƭȲʴ˵ʴʴ˵ͷͷͷͷ̶̶˵˵˵ɳ̶˵Ǳɱȱ¸gyjKtdCn[:r[9t^9kS-u]9t]=vaBmMeȪʰ̱ʹ̳ɳɵʷ˸ͺ̹ʷȵɵʶ̵Ͷʱʱĭ˿x^veGp`?m]<qa@xiL{^Ŭȯ˶̷˸ʷ˹˹ͺʷ̶̹ȳȮ~v[xkKsdEvfEzgFqMj˿ǰ˶ʳʵͶϸϸѺϸͳ˱ɯɯɯʰ˫ϭϬšnXqIqLoK{[ĸĪǰ˵ʵ˶̷̷͸͸ιιζζθθͶ˴˴̵ʿn|jRv`Iw_Gy]Gu]Ev_Ʊ̹Ƴͺ˸ϻϻͷ̴ϵǫlsTraCudFq`BtaAqQhŲͺ˸űsgfglwèʱ̶͹ʸɷɵʶʴưȽ¸|[~lHua<x`:}gBmLlþͻμȷǳȳ˲ʰ̰ͳ̵˶˶̹λϼɶ˶̷«x^udJu_Gr^EraG}nQf{p|Y~nL~kJmJkIhF~nL~oNuUcvɾųƴɶɶʷʷͷκ̼ͼǵîĬ¨ı}bjH~hCyc>ua>~jG}Yɾƫʯɮȯʱ˲ɰǱưűűƲȳȴɵǮǬƪƩĦ£ɾǾĹżʾŬȵ̸ʺʷθ˰ȫguRqLkIhFkLc°ŲǴʶ͹мѽѽмϻннϻͺͷ̹ͺʷǶʺ˺̸̹˷˸ʷɸɶɵ˵ʵȮŭȼfrThJ|aDiJy[sƩѴѶѸѺҺҽҽѻг̯̯γӺռӹж̱þfwN~k@j;m?xi@vjBymEtLYgv´Ⱥ˻uf^_gsçƽmzYtQuNuKyNaãͰѹѾнѿоооооѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿооооѿѿѿоϽμμϽѿ°ƿžžžžƿ°²ĴȶȷǴŰ˹ʷȷǵƶŵŵŵ°ñǿļĹ{bl[A^M3cO4gS8eT:l`Hk­ʵ˵ɳȲʶɳưůĮůưɲűųųĲ¯Ƚ|qXiX>bN3cO4hS6iU:pbGlƫ˰̲ʰǯɳɳȴǳȳȵʷ˸ƱʲɱƮêī©óbwgFj[<m^?qcFpeIv[{ưǳǴʷ̶̹ɱʲɯìƭǽck]@]O2eV7eV7eU4m]<rcB~pMsPzW}ZxWxVgyſūɮ˴î¯ÿotSvfDk[7l\\8vfBzVzǺʱ˵̶ʴȲȲɳ˵ͷͷͷ̶̶˵˵˵ƲʴȲëūƪ}]vgFtdCp]<r^=v_?mV6w`@mZ:l\\;tdCsUj˰̲˴ʴȵɶ˸λͺ̹ʷɵȴɳ̵ʹ˲˲Ů«¶v]veIp`?n^=q`ByhL|_Ŭȯ˴ͷ˸ʷ˸ͺ̹ʶ͹̶Ȱǰ|uZzkNveGyiH}jIsOlȾůʴɳɳͷζ͵ϸη̲ʰɯʰ˱ͳȪͮέšm~UpHqInH|Z}ĸ©įǲǲȳɴʵ̷͸ιϺ̶̶θϹϸ̵̳εɽl~jRv`Iw_Gx\\FrZBr[Ȳͺȴλ͹κϹͷ˴βŨh|kMp]=vcEq`BtaCsUrνƨ¤˺ðypihnzżǪ˱̴ͷ˵ʴʴʴůɽ÷zY}jIt`=ua>{gDoNnüͺνɶǳȳɳʱ̳ʹͶ̷˶ͺλϼɴ̷̶qtfLl[AnZ?kZ>n_BqTl|}od{XwTxT{WwTrO~lHzjH{kJtSdwëůǱɴɴ˵ͷͺλͺƳª§|^}iH|hEwc@t`=}iF{XǱ˵ɳǱɳʴɲȴȳƱƱƱȲȵɴɳʱʯʯʯʯɮɮƭƭǱʶͻμ˻ɸ˵ɰȭ¥jwSqNnLhH~iLz_³¯ȵǴʶ͹мѽѽмϻҿѾѾѽϼλλϼ˸ŴǶνʹʷʷʶɵȵȵǶǴǳʶʴǰǮȼdpQgFy^@|eEvVpƦΰϲдзѹҺѼһеͰʰγӺֽӸγŨwZ|mFwf;yf;{h=pGqJuNZjyŶοƦˮˮƧ̽ug]]doĹķkxUqLqHvKzOeãɮиҿѾнҿоооооѿѿѿѿѿѿѿѿѿѿѿѿѿѿооооѿѿѿѿоϽμμоѿƿĽ»»»üžƿ°ĲųƴǵǴǶȶȶǵƴųĲóĴ²ƿƿžý~rZgY?eU<bQ7jV=cQ9l]F|f«̶˵ȵʶʷʶɳǱƮŮƯȱ¬­ïĿ|dwhQhX?dT;eU<_N4k[B~oXźǱ̵ɱŬ˴˴ʳʳɲȲɵɵʶȴǳĮſſ;l{lMk\\=j[<m^?l^A}oRrȮɳİǲ̷˵ͷůʲưƾ|ck_E\\N3aS6dW7bS4pa@{Ylwpehiccir~Ļ§ƪǮĲĳžkuSseBhZ5k]8ugBzUvȻǮǲǲǲǲȳɴʵ̷˶˶ʵʵɴɴɶʷ̷ɰħƦßivL|mFsc?rb@zgI~jO}iQxfNugJreEreEyjKtVe|ͼξĭʷʹƶǸ˺ʷȶǴȴȲ˴Ͷε˲ȭ«ɽ|v_wcHq^@n[=p_CxgKz`ǮʱͶζͷ̶̶ιѼ͸͸˵ɱʳŻv[xiLveGnNnOsRnĳ¨Ȳ˵ȲůȲ˲̴̳͵ͳͳͳͳͳͳεзгǧfxL}nC{lAsJ}XtȵƱȳʵ̷ιϺϺлͼͺλлθ̳ɯʮɻekPwbGv^Du]Cs]Ezcŭ̶Ȳİ˶κϹζͳγçblMu^>vaBp]?tcGy_v´Ĭëʻôunr|ȻƩĩ̲ϵɲɵʶ~wVyiHrbAscBziK}oRoŽλϼȶƴʷͺʷ˵˵̸ιιͺͺ˵̷ʶwt[udJgV:m\\>o`ArcDsSfpm^[\\bnsmf}XuSqOsQvS~Zk|˽˯˰ȮȱͷϹнɶɾī§cxiJwgFwdCwcBiIyWǳɵƲŰȳ˶ͷƯǯȰɱʲʹ͵͵ͷ͸͸ιι͸͸̷˸˺̻;̽˼ʻ˸͵Ͳ˯¥mzYuSnMjKjMv[xɶȲůǱθѻθͷкӿҾмκ͹ϹкҼҼкϹϼҿҿϼ̹˵˵˵ɳȳǲɵʶȳɵ˵̵ʱƺ}_jHfA|b?{e@rNhͯαдзҺӻѼѼиһӼкиҸϴʮɾmxUzlGxiBwhAuf=~lDtN\\p˻êʳɱɱʲ̱ȭæƽ~nb~[\\j{®|ezTrJpFvI|OgŧѸӾҿҼҼҿҿѿоϽϽϽѿѿѿѿѿѿѿѿоϽμͻѿѿϽμμϽѿƿĽüž°°ĲųƴǵǵǵǵǵǵƴųĲññ³ƿƿĿ½{qXcW?dT;`P7hT<aO7k\\E}d˵ʴȵɶʷɵȵǱŮŮŭǮĮþ¬íľŽt^paJbS<`Q:cT=`P7n_Hvaɾɴ͸ʴǱ̵͵̴ʳɲȲȲȲȲƳŲĮſſſ¥sqRm^?iZ;k\\=l]>ykNkūɱưȳ̷˵ͷůʴǱíǿzaj`E\\N3`R7bT7bU5xiJh||se_}_eqǼŨȮűóžptRtfCj\\7m_:wiD~Xyǽȯȳǲȳȳɴʵʵ˶ʵʵʵɴɴȳȵȵ˷ȯŨƤ{]uH{lAvg@yiGsW{c~j~g}rVulKsfFteD|iIsTfvƲϽǲȷĴƷ˼ɹɷʶʶ˴̵̵ʹʱǮǿɽ}t^uaHp[>lX=p\\AwfLz`Ʈ˱̵ζͷ̶ͶͶѼ̷Ͷ˵Ȱɱĺy^zkNveGlLmNqPjĽǰͶʳƯƯɰɰεε͵δζδ͵͵θθδĤcvJ{nAyl?rFyRoʾʿƴǲɴʵ̷ιϺллξͻ˺͸˵ʯǫŨƷa~kMvaDu`CyaGxdIiľȰθɳįɴͷ϶̵ͱ̲¦`~jIt];wbCs`BudHz_y¶Ʋȶų˾ķysuw}öȹ¥ƭƭǱʶñ{uTxgIp_Ao`CtfIzlRmǼ͸ιȶƴɷͺȷʷ̹κ̸̷˵˵̶ͶȲĸf}iQp_EjY;l]<o`?rcBzmK{YbdcciuqdxWpLmHpK~Xi|Ȼåʯѷй̵˷ĮǼǽūƪizmMwhGvcBwcBiIxV˼Ʋ˹ȴįƱʴ˵ɱɱ˲ʹγϴезϹλϼϼϽϽμμɹʺ˾̼̿̿ζγ̰ŧu~^uTtSnNkNsXoͻȳƱİƲ͹ϻ͹͹мӿѽϻ͹̸͹κϻӿмκϻѽҾѽϹ̴˳ʴɳʵʵʶʶȳʵ˵̴ɰù}|]iEf>{a<zd?qMhͭϰдѵҺӻѼѼκѼҽϹηе̱Ʃô|bsQykFvhCykFpLwQ[l~¯ͼǰι̸̹˷̷Ͷ̲ʰȫ|k_~[clsy}q`yQqIsH{NVnˮӺпӽҼҺҿҿѿооооѿѿѿѿѿѿѿѿоϽμμѿѿѿоϽϽоѿѿƿĽüƿñųƴǵȶȶȶȶǵƴƴųųĲññ°þxnUaU=bR9^N5fR:^L4j[D|cʴȲǴǴɶȴƳưŮŮŭƭů¬íľºttjQhYB]N7^P6bT:bR9sdMmïʵ͸̶ɳηζ͵˴ɲǱǱưưưůíÿÿŨƸ}z[paBiZ;j[<k\\=ugJeɱʴ˶̷ʴ̶ů˵ȰĬx_j`E^P5`R7`R5cV6qRvƥãqfz\\{]coƽĨĽĺlpOueCm]9pb={mH\\~ʽȯȳɴɴɴɴʵʵɴɴɴȳȳȳǲǴǴʶɲǪƤûrRqDzk@zkBsOeyfzYzmMteDrbAzfEqR~_vοƳŲƵ˺˸ʸ̸͹ιͶ˴ʳȲůƾȻ|s]r^EmX;iU:nZ?udJx^Ʈʰ̵ζͷ˵ͶͶѼ̷˷ʴƮƮù|a|mPudF|iIkJnKaŬ϶ʹǮŬǮȯ϶϶ζϷϹζθͷϹ϶˱ſ_sIyl@xk?|oEuNjȼʿƲɶʷ̹λϼннѾϿͻʹʵɳȭũ³y|[zjItaAs`@zeH~mQsë˳Ϲɳįǲ˵ε˴˯ʰʿ{\\zfEs\\:ydEtaCtcGw\\x÷İɵͻͻ̺˹Ųĺ|uqqwƶ˻ưоñusRveGn]?l]@pbEwiOlǼ̷ιȶƴɷ̹Ƕ˸λϻ̸ɴʴ˳ɲʰp~nTs_Fm\\@n]?l]<m`>qdBuhHzmMxXaruŽšǣţİhvS~jG|jFtP[kvƬѸзɰǱ©ŻǽǭȬm}pPxiHubAua@iGvTzŷĮκ˵Ưĭǰȱɱɱʲ̴ε϶ззкϼннннϽϽɹɹ˻ͽξкϴͱɫfxWyXrRmMqSdĳĭııƳ̹λͺλѾҿѾλͺ̹̹̹ͺҿѾѾҿҾθ˳ȲȲ̷͸̸ʶȳɴɳʲƭzyZ~fD|b=y_<yc>qMhͭϰдѵѺһѼѼιлѼ϶δγɬ£oyWpL}mI{kGvQ`isŵɯϸҽ˸̺ͻ͸̷ζиҵг¢|l`_afjmfZwMsJvKT_yŽгռҿпӽҼӺҿҿѿооооѿѿѿѿѿѿѿѿѿоϽϽѿѿѿооооѿѿоƿĽ»»»üžñųȶȶɷɷɷȶȶǵųĲĲñ°°°°ô³°°İ®Ŀ½ukR]Q9`P7]M4dP8\\J2j[D{bǿɳǱŲƳȵǳŲưƯƯĬŬĮĿ¬¬ſ¬lmcJbS<[L5]O5aS9cS:xiRvƲȳ˶̶ʴηϷζ˴ɲǱůůůůĮí¬ĿÿŨʼbteFj[<k\\=m^?ugJbžʲ̶̷˶ɳ˵ů˵ɱŭv[kbEbT9cU:_Q4`R5qR|ɪȫwhdbeo}Ż{^|lJscAo]9qa=}mI^ɼɰɴɴʵʵʵɴɴǲǲǲǲǲǲǲǴǴɶɳȮťjuHzm@yj?}nE|Xq~m~\\qPxhFwdC~iJqR}`i«Ǵɶ˸ʸ˹ͺϻϻ͸˴ɲǱĮǿƾǺ|r^o[BjU8gS8lX=sbHw]˿ŭʰ̵͵̶˵̵Ͷл˶˷ɳĮéĺc}pPsdCwgE{iEkF}XsзѸʱǮȯʱ϶϶Ϲккθ̶̹Ϲεǭ|Z}pFxk?xk?zmCqJgɽȴʷ˸ͺλннѾѾϿϽ̹ʵɳ˰ǩuzXyiGs`?q^={gFrT|Ʈ̴кʴįǲʴ̳ɲʮȮȽ}xY{gFt];zeFr_Ap_CsXwùɵ͹μ˹ʸ˹ȵŭ¢ĺwspqmxųͻɷppOveGn]?k\\?n`CwiNmȾ̷͸ȵǵʸ˺ȷ˸λκ˶ɲ̴ϵɯ{y_ufIl[?jY;n_@k\\;l_=sfDuhHylL|\\r£ȩˬ̭˭¦ȳ~izYtRvTzX^erŷũǭƫɰīȾɿȬɬ¼n~tQykHqa?sa=}iFsQsêѸѸʰǭɯɲǯǯȰɱ˲ʹεͷкϼннннϽϽ˻˻̼ͽ̿ξѻϷϵͱ¥r_|[uUpPqQ{]p˽ıƶɹ̼ͽͽξξͽ̼˻˻̼ϿϿϿнθɱůǱ͸Ϻ͹ɵǲȳǱƮutU}eC{a<w_;xb=pLh̯αϴзѺһѼѼлҼҼиϴͱŦʻcsOsOtPtP_v̼Ƨ˱ͳ̷̹ɷͺнϼͺͷкӻҷ˯Ϳpfa\\\\\\[{RtJtJyNUcӶֽӿҼҼҿҿѿѿѿѿѿѿѿѿѿѿѿѿооѿоѿѿѿооѿѿѿϽƿžĽĽĽžƿ°ĲƴȶɷɷɷɷȶǵǵųĲñ°°ññƷŶųųƲİ½qgN[O7_O6]M4cO7ZH0j[D{bǿȲưıŲǴűðůƯǰĬê¬Ŀ¬ªƮºhi_FbT:]O5_Q7aS9cS:zkT{ƲŰȳ̶˵Ͷиζ˴ɲưůĮĮƭƭŬīì«ȺdwhIl]>m^?qbCwiLcž˳ͷ̷ʵȴ˷ů˵ȰĬ~tYlcFfX=gY<`R5^P3|mPwŨƪĩwkdegouĹswUxeDr`<o[8p^:}jIaɺȯɴʵʵʵɴȳǲƱƱƱǲǲǲǲǴǷʹ˷Ȯſa|qDwj=xk?sI^{ƸǹqbwU~kJ|hG~jIoPsUgĺǯʴ˵ɶ˸λмм͹ɵǳǳİǿƾǺ~r^nZAiT7fR7kW<raGv\\ʾŭɯ˴͵̶˵̵̵лȵʶɳ¬¨ƼivTugBuf?yg?{j?wLa˱ж˱ɯʲ̴ͷθϼϼϼͺ˹ʷθ̳ĨyY{nDvi=xk?ylB~pKf˿¬ʶ˸˸ͺλннннνϾλ˴ʹѴʪozUzlGrb>o_;|jFzYǯ˳ϹʴŰɴȲ˲ɲɭǭƻztU~jIv_=xcDo\\>l[?qVwĺ˷ι˸ǴųɷɶȰɬƥǾrkz_dmxf|lJvfEp`?l]>pbEykPq̷͸ɶɶ˹˺̺̻̹˷ʳ˴жԸʭúfpQqbCkZ<gV8k\\=i\\<naAxkK}oRwZpĻǬ˰̲˱ʰɮȯĳuh_{XyV}ZdsɻũȮƬèæȫȨ¼tzW|nKscAtb>kHqLiƽγҷͲʯ̰ͳƯƯȲɳʴ̶ͷͷϹϹккϼϼλλϽϽμͻͽ̼̼̼лижγȫm`{YvTwU{Zf{ķɼ˾˾̿̿̿̿ʽ˾̿̿ʽɼʺ̶ȰĮư̷Ϻ͹ʶȳȳůĬȾqpQ|eC{a<w_;vb=pLh̯αϴзѺҽнмӿտսԺѵˮ;uZqKuO|UXn˼ãˮӷҺк̸˸˸оӿллкѺѸ̲éĶuh{YwSvPvNtJpGtI{QZiģӷվԿӿҼҼҿҿѿѿѿѿѿѿѿѿѿѿѿоѿѿѿѿѿѿϽƿžžžƿñųǵǵȶȶȶǵƴƴųĲ°°ñĲȹǸǵǵǳİĿmcJXL4_O6^N5eQ9[I1k\\E|cǿȲưıŲŲïĮƯǰĬª¬¬Ĭʲû~eg]DbT:aS9bT:aS9bR9{lU}Ʋ­Ʊͷ̶̵Ϸζ˴ɲưĮĮĮƭǭƭǭŮŭ«ë̾ŷcwhIm^?o`ArcDvhKcžʲ˵˶ʵǳʶű˵ǯªĽ{rUkbEfX;hZ=aS6^P3{lOwƬŮƭȭ˿ʼ|nd_\\[ivmtPua>q]:lX5nZ9|hGbɺǮȳɴʵɴȳƱŰƱƱƱǲǲǲȳȵǷʹʶĪyY|pFxk?|oC{Ogöƹ·ƾufwU}jIyfE|iIyiHsToüūɱȳʷ̹λλ̸ʶȴȴıƾȻ~s_nZAiT7fR7kW<raGu[ɽŭɯ˴͵˵ʴ˴̵λǴʶʴ¬x_|nIwj@xi>{j>qE|Rsʭˮ˱̴͵̶ͷλϼμ̺ɷǵ˵ɰ¦wXzmCvi=wj@xkA}oJfĮ˷ʵ˸ͺλϼϼϼϼͼѾл̵γҵɩƼ~fyR}oHwhAvg@tPhʲʲͷɳƱ˶Ȳ˲ɲɭƬĹxrSkJs_<vcCm\\>n_Bv[{ǽʵ̷ɶŲų˹ͺͷͲαˮħź~o}b|az`emvyx~]wgEvfEscBo`AreE|nSt©Ͷι˸˸ͻ̻μ˺ʶɵ˴δдѴŦszXwjHo`?k[:gX7m`@qdD{nNy\\fvĸǮʱ̶θι̷ʵɵȵȳ«Ƹo`yXzW|[aiwɻ¦ũƩŦǧǥſdyVykHyiEpLpK_zŦͮͮͰαβɯȱʴ̶ͷθϻϻϹϹкккϼλλѿѿϽͻ̼̼˻ͺιлй϶˱æmb}Z{Y{Y[jĽƶɹʺͽϿξϿϿϿξξξξͽ˻ȸǷȸʸ˵ȰưȲ͸Ϻϻ͹˶ʵǱĬȾp~oP}fD{c=wa<wc@pOi̯α϶зѼҽнмҿվּӸϴŦ²|ezTqKxR[g}ǸƩͱҸ׼ԿҿѾоѾмҽԾտϷūŷwaxVsLsKsKrHyOYhvȩӷһӾӿҼҼҿҿҿҿҿҿҿҿҿҿѿооѿѿѿѿѿѿѿѿѿѿѿѿоѿѿооѿѿѿѿо°°ƿžĽĽĽƿ°ĲĲųƴƴƴųųƴĲññųƴȹǸǵƴƲ|j`GWK3_O6_O6fR:\\J2l]F}dɳưıŲŲ®íǰȱëŭīŬŬƮ̴»}y`cY>aS9cU;dV;bT9bR8|nT|űŰϹθͶζ͵ʳȱưůĮĮȮɮɯʯȰǯįĮ˽´~~_vgHm^?n_@paBqcF~`üǯɳʵ˶ǴʶİʴƮſ|xoRg^?cU8gY<cU8bT7pV~ļɱǲǰʴůĬɽ·sg]{W|Xbfkqo^lGs_:r[9mV4lX7zeFe˻ůǲȳɴɴǲŰîƱǲǲǲȳȳɴɶǴɶȲľk{U}qG|oCvJZsɼƹxetSlKyfFvfE{lM~^uǫưǳɵ̷̹˸ʷɶȶųǾɼt`p\\CjU8gS8kW<q`FtZǻĬɯ˴̴˵ʴ˴̵ͺƳɵ˵íçƽmzR}pFzmAyk>zl?}pFbyĽũʮ̲ɲ˵̶ͺμͽ˻ȸƳɳǬwXzlEvi?ug@vhA{mHf¨Ŭʴʵ˶̷͸ιιιι̹ѾϺ̲Ͱίr]wOuKsItJ_{ɯζʲ̶ɳƱ̷Ȳ˲ɲɭƬĹwpQzgFp\\9ubBq`BwhKeȳ˶˸ɶʷϼϻͷ˵ε̳ǮèƼwl{^uXuXy\\}`asRp`>ueDtdCqbCtgGqVw¸īϸϺ̹ͺϼϼͽ˹ɵʶ̶ʹʭƧgsPreBob?qc@teDylLx[jxʾƭ̶̸ͺλνͼ̽˺Ƿ˹˷Įɽue^{XyVzW`qǼĥĥťƤĢufxUrNuQpL}Yk~ȧ̭Ͱʯɯɯɲ˶ͷͺλλкиѹѹѹѻккѾнλͺ̺̺ͻϼ̷лѺε̲ʮ~n`Z{VyR\\püŲ˸ͺ̹ͺͺλϼϼϼϼϼ̹ɶðüư˵ʲʴ˵ιлѽҾѼϺ˵ǯrqR~jG~fByb@weAqOi̯α϶змѽϽϼϼһӺѵʭ˼h}XxPvN|Vcwť˱϶ӺվվԾѾпҾͷǯźxg}X}V~UT]l~ϯӷϸҼԿӼҼҿҿҿҿҿҿҿҿҿҿѿоооѿѿѿѿоѿѿѿѿѿѿѿѿоѿѿѿооϽѿѿѿѿѿññžĽü»»üžƿ°°ñĲųųĲĲƴųñ°°ñųǵȹƷƴųİĿ{i_FVJ2_O6`P7hT<^L4l]F~eɳǱŲŲıƿíǰȱëȰǮȯƭǯ̲yuZ`V;`R8dV<fX=bT9cS9}oU|űƱѻкη͵̴ɲȱưůůůȮʯ˰˰ɱȰưů̾||]teFl]>m^?n_@l^Az\\»ŭǱʵ̷ǴʷİɳŭľyulMd[<_Q4eW:dV9fX;v\\ļɳƱȳ͸ȴǱŬ˿Ĺte]xTzWyVwR{W~ZrMua<u_:r\\7mV6mV6zeHfͽĮƱȳɴȳƱį­ǲǲǲȳȳɴɴʷųȴƮcwQ~rHsI{Oa|ƺÜƼsaxWvfEvfEzkLuVdvŦūƮȲɵ˶ʷʸʷɹƶȿȽuaq]DkV9gS8kW<q`FtZǻĬɯʳ̴˵ʴ˴̵̹Ƴɵ˵í¨ũ¢û{[uK}pDxk>uh;uj=zVlȬʮȮʲ̶ͺμλʺƶŲȯƩx[{mHvhAse>tfAzlIfĨŪɰɲʳ˶̵͸Ͷ͸Ͷ˸лϸʰʭʩŻh~VuMxNzP}Vl¥жҺ˳̶ȲƱ̷Ȳ̳ɲɭƬĹv~oPvcBmY6vcCveGqTnūǲ˶λ̹ͺϼ̸ȴǳɳǳíĮŬǻydqTzkNzkN}nOrS}mKl\\:scBueDrcDuhHrUyĺƫϸйθλннͼʸȶ˵϶̱ħĻ~s_|oLpc@pc@zlItRy\\q¶Ʈθ̸κ̺ʹ˼̽ʾɽŹ̼ͼ˸ȱīwg|YuRqOsQ^l£áƤȤɥšr_zWzVqMzV`rĺâʩˬɬǫǭǰȱʴ˸̹ͷѹҺҺӻӻҺҼѻкλͺ̹ͺμϽоʶлмͷ̴ͳǪȿxdZyTtM}Seu¼ªɯ͵̲˳̴͵ζϷϷϷϷª¼˳͵θθϺѼӾθʲêttUkJ~hCxdAxfBrPiƿ̰ͳ϶ϹмѽϽϽ̹θϷβƩĵuYyQyQzR[l;ͰεѹѼҼѻкмҾҿпοомкȮɾygccdm}ľ˫ԷӹζϹԿӾӼҿҿҿҿҿҿҿҿҿҿѿоооѿѿѿѿоѿѿѿѿѿѿѿѿоѿѿѿооϽϽоѿѿоĲ°žĽü»»üžƿƿžƿñƴĲųųƴƴųųĲƷǸɷȶȴűĿoj`GZN6]M4`P7cO7`N6gXAvǿǱíɶıŲűıůĭìǯɰ̱ȭĪɯ}z_bX=_Q6bT9eW<dV;eU;qW|ǲǲ˵θηʲɱǰƯůůưư˱̱̱Ͳ͵͵ʴǱɻz|]teFl]>o`AteFk]@~`»ªůȳȳȵıǳʴȰƬsvmNd[:^P3bT7cU:j\\A{bǿǱ˸˸ʷ˸ʷƱŰêȿĹwk_xU|nKyiE}kGkF{gBxb=u]9v^:qZ:mV6wbEdξưƱǲɴ̷˶ǲîƱǲȳƱîįȳ̷нưp|X}qK|oEvLYqŹ¹~t}^vW{lMufEzkJwUcxƸŪδ̳ǳɶ˹ʸȸƶȿƽɾu^p\\AmX;iU:hT9n]Cw]¨ɱ˱˴̴̶˵˴˴ʷɶǳưůūƪȨĻx`wMzoBwl>xm@wS]nƽŨɭƬȱ̶˸ʶȵǴǳǮɬæv]qLykFqc>xjExUløèǮ̲ͳͶͳʳ˱˴ͳ˷˵̳̱ȩús_~U|S[gvȾͰɯŭǯ̶ϹϺ͸ͷʹʳʮĪttUxeDt`=p]=udFy\\yɴ̶λϼϼͺʵȳ˶˶ʷɴƲůĮŬ÷pz]|nQtfIrcDxhFjZ6scAscAqbAwjJwZǽŪ̵ηкҼн̹ɸȵǴʳ˲Ũ·ucwTrOsQxV`mǻƭ˵κϽλͼ̽˿̿ϽϹʳĩ{iyV|nK{mJsQyXqǥȦʧ̧šƾyg}ZyWyW^gw¸ɾ£æǬƫȮ˴ϸл͸ʵжжϵδҸ׽־ѹԼѻͷ̶ͷλλλͺ̸˷ʴʴʲʰ˯}mb\\Y]iuſæȨȫˮϲгαȫü|sv»ʰ˳ͷкӾԿӾѼθ̴ǮxvWzfE~hC}iF{kGtQgƿȬʰ͵кноνϻȲ¨ǸiVuMxPXjǸƧͱηкϼѽѽҾҾҾѾҿҿпѽ̶ɰúzzŻȧ̯Ѵչ׽׿տӿѾѾѿѿѿѿѿооооооооооѿѿѿѿѿооϽϽоооѿѿų°žĽü»üĽžƿ°žƿ°ųĲųųƴƴųųĲ³ƴȶɵȴǱưnj`GYM5\\L3_O6bN6_M5k\\EzȲíǴ¯ıİıůì«ǯȯ˰ǬĪȮx]aW<^P5bT9fX=eW<fV<qWïǲîưɳʳɱɱǰƯůůưưʰʯʰ̱͵̴ȳǱ´|}^teFk\\=m^?rcDykNkƿëíįðɹŵɶ˵ɱǪpriHcZ9_Q4cU8cU:j\\A~eŽư̶˸˹̺ʸƳȵȳȯʭƦǽ~h\\oMtd@s_<r^9q[6oY4u]9u^<qZ:mX9xeGhϿȲȳȳʵ̷̷ɴƱȳȳȳƱŰƱʵ͸ѹĪiwT{mH{mFVat|xw}ɻɻ{`tUzkJyjI}pMzWguȹƫȮǯɵ˸ʸȸƴǿʿw^q]BoZ=jV;kW<raGz`ĪȰ˱ʳ̴̶˵˴˴ʶɵǳưƮƬǫǪƥƾt`|SsI{rGwT|YboĻ¥ũɯ̴͵̶ʴȴȲƫȩ¢w]qNykFxjE|nKwVh¥ǬȬʮ̲̰˱˯˱ͱ̳ɰƫæƽ{n_[^j{ɿ̬γ˱ǯȰ̶ϹϺ͸˵ʹʳ˯ĪvvW}jIxfBscByjK}`}Īͷθλϼϼͺ˶ʵ̹̹˸ʷȴǳƲưƮʾt~a~pSuhHwgEiY5qa?qa?pa@ylJzZȿƫͳͶϹѻϼ̹ʹʷ˶̵ɰǾ{c{XtQyWdrɽ˿ĬǱʴɵȶǵ̻̽˿˿Ͽλ̴ǫæɾ|dtQykHwiFyjIcvƽǥɧ˨˨ȦĠúzjb^`coz·úĨɯϵйη̵гѴϵδҸ׽־ѹҺϷ˵ʴ̶θкϼλλ͹̸˵˵˳̲˯ãynec`gryťǧɩȨĤý}wolr˱̴θкӾԿлϺͷ͵ȯ{y\\vcBxd?ygCyiGsRkȬʲ̶λϽϽο;ͽɵŹzb|S|SXfy¢ʭγϹϻмѽҾӿӿԿϺ˴ŪĻǾǣ̫ϲѵԸּ׿տӿҿѾѿѿѿѿѿоооооооооѿѿоϽϽооѿѿѿųñĽĽü»üĽƿññ°ƿƿĲĲųųƴƴųųĲȿųǵɵɵȲǱmi_FXL4ZJ1]M4aM5_M5qbKìʴĮɶıðïðĮì«ūƫɮǬħɬ»{^cZ=_Q6aS8dV9dV9cT7ykP{ïǲíưȱȰȰƯƯůưưǱȯɯȯ˱˴̴ɲǯħõ{|]teFk\\=m^?sdEy\\w¨Ĭíî¯ɹŵɶ˷ȰƩnlcBbZ6aT4cU8bT9j\\AgŻì̶̹ͺλ̹ǵĲŲȱ˰˭ťƹ~p}\\{kIs_>nZ7oX6oX6r[9s\\:qZ:nY:{hJl¨ʴʵɴʵ˶̷ʵɴʵʵɴȳƱȳ˶ηжƿr\\|oLwiDxjCzP\\nx||||źĨƪƸqdvU~oN{mJ~pKzU^wɺæƬȲɴǴǵƴƾɾ~w]r^Cp[>mY>o[@wfLeǭȰʰʳ˳˵˵˴˴ʶɵǴǱǯǭȬȫϯʨǾ{j[zSwTwTzW_l~¹ſ¥ȫʭʯɮɭɭʭˬ¢u\\~pMxjGxjGykH~oN{Yo¹¥ƪǪǫǪǫȫƫú~rjhirȿˬոҶδʲʲͷϹϺ͸ʴʹ˴˯ĪwyZpN~lHyiHpQf¸ȮϹϹϻϻͺͺ̷̷̹̺˸˸ʷʵȴȲѻ̳ªĸ|eqTyiGjZ6qa=p`>rcB~qO`ƫ̲̲͵Ϸθ˵˸̷̹˱yh~]zY~\\iz÷ëŭưǱȴɵȴɶȵ̻̽̿оϹʰǫŦżs`uS|oM{nLyYlúǧʪ˫˫ʪ̩ɩȿunffimu}żè˯ϵϵβϲѳгαгոӹϵ̲ȮŭŭȰ̴Ϸѻннλͺ͹̸̶̶и˯ĨĻvoklnpu|¹ú¹ussvƽƦδζкѻӾӾӿӿιϺϹϷ˲Ż~axeDyeByfEzjHvUnȬʲ̶ͺͼͼ˽˽Ͼ̹ïĸzj_ai{̯ϴйͺλϼѾҾտտԾӽϷ˴˱ɭɭˮαѴԷӹԺԺսԼӽҼҼҿҿҿҿҿѾѿѿѿѿоооооѿѿѿѿѿѿѿоооѿѿѿƴĲžĽü»üĽƿñĲĲ°ƿ°ĲųųƴƴųųĲôĵƴǵǳİ¬lh^EWK3YI0\\L3`L4_M5teNŮ̶ư˸Ƴ¯ï¯Į««ūĩȭǬŨȫždi`CbT9`R7bT7bT7^O2qcHqȳįĮǱȱǯƮŮŮůưǱȲɰɰɰʱ̵̵ɲǰtyZteFl]>qbCyjKf~éŭưǲƳȸĶǷʶƮæih`<bZ6cV6cU8`R7i[Aiùé˳ͷκϼ̼Ƿ²ñưǰɮƨȻq{Z|iIs_>r[;qZ8oX8nZ9mX9lY;ziMn¨ʴʵɴɴɴʵʵʵ̷̷ʵɴȳɴ˶̵ˮ}dtQvjDtf?xjCrKXiuz~ȼ¨ǭȮ̽{j|[tQqLsLwPbsɺĪűƳǴƳ¯ŽƻxtYr^Cp[>nZ?r^C|kQiǭǯɯɲ˳˵˵̵˴ʶʴɳɳɱɱɯɭͰˮǨpf|YyVxU{XaqĿãƧǨȩɪϰ̭t\\}oLwiFxjGxjGzkJtRbrľľľſż|xroy}ȿƫ̱϶ջҸζ͵θθι͸ʴεͶ˯¨x}^tRpLoNxXmĽʰкϹκ̸ʷ˸˶̷ʷʸʷʷ˸˸ʶʶͷ˵ɳǯyc}oLo_;td@sc?wiFxVg¥ȫ̲˱ʲ͵ͷʴʷ˵ǰi|Z^dn÷Ƴ®®®ïűǳʷʹ˺˼ͽξоѻ̵˯ħǾqe_~^bq¹Ũ˫̮̬˭ͯα̯ævsomorx{ú¥Ǫɬɬ̮ΰͰʭʭ̯ʰǭſ¼¼Ȱ͵иѼнϼͺ͹̸̹̹˵ɱǯĨȿ}zz~äͮӶжиѻҼӾҽѽѽϺлѻѹ̳Ƽf~kJ}kGzjH}oL|\\sɯʲ˵̹˺˺ʼɻϾʵȾ{xx̯ѷѺнͺͽϼѾӿԾؿ׾ѿտҼͷͷζζϵҷѷҺӻҺѹѹѻѻѻѻҿҿҿҿѾҿҿҿҿѾѿѿѿѿоооѿѿѿѿѿѿѿѿѿѿѿǵųƿžü»»üžƿñĲĲñ°ĲųųƴƴųųĲĵŶƴƴİ½ki_FWK3XH/[K2`L4`N6qbK«ɳĮʷƳ¯®¯Įìì©ĪèǪȫŨɬjneHeW:`R5aS6cU8_P3oaF}hʿʵǲǱůìŭŭĭĭĮưǱȲʴʴʴ˵̶˵ɰǮʼltUrcDl]>teFpQrŹĪŭưȳǴĶĴǳéeh`<c[7dW7cU8`R7i[AhĺĨ˱͵͹ξ;ɺ˼ɹǵǲȯƬŨħɻnvXxeEnY:hT3jU6jW7iV6jY;zkNn˿Ȳɴȳȳǲǲɴʵ͸̷˶ʵʵɴȳȮnX}qKwkCzlEqJYft}¸ǽ©Ŭɱ̴ȲŶm]wSrKoGzO]rŸʿĮɴɴɴŰƼutWs`Bq\\?o[@uaFnTmƬƮȮȱʲ˵˵̵˴ʴʴ˵˳˳˳˳˱Ȯɭʮɭħgb^]`ipvĞƢȧģtawVsRwVxW{Z_js|ü¦Ȯʳ˶ʵվԺиζθͷι͸ʴ϶ϸ˯|f|ZyUzYdw˱Ϲθ˷ɵǴȵʴ˵ȵȵȵɶʷ˸˶˶ɵɳ˵θ˵ȼwyVyjC}mIzjFqN`nŨʭ̲ʰɱ˳̶ʴɵǱue}\\do̽Ƕ˾Ϳ˹ɷǵųƳƳǶȷ˹̺ͻμнϷαϱ˫ázsp}ƽĩʭͰͯʭ̯ϲϳ˰ĩǻĶ}xuvu|¹żſãƦŧþĿþýū˳ζлϺλ̹̹˻̸̻̻̹ʷʳʱǫɾ¸ȾŪ˰ϴӷѺҺҼҼӾҽѽмϺлϹ͵ȯùjqOoKoMwTf|¦˱˳˶˸ɹɻɽɽξɶʿ÷ƽĠ˫ϲѸмн̼ͽϽнӽս־׽׽׽־ҿӿҾҾѽӾӿӿѾѻѻѻѻӽԾֿҿҿѾѾнѾѾҿҿҿѾѿѿѿѿоооѿѿѿѿѿѿȶƴƿĽü»»üĽ°ñĲĲ°°ñĲųųƴƴųųĲ³ųųű®Ŀ½ki_FXL4XH/[K2aM5bP8n_H|ƾůǴð¯ïðůĭĭªêū§ǪɬǪʭħswnQj\\?bT7cU8gY<cT7rdIxcøƱƱưëĬìĭĮưȲɳ̶˵ʴ˵˵ʱǮīĶc~oPrcDo`AzkLyZǭŭĮŰðľ²ű¨þ`jb=e]8fY9dV9bT9n`FmǾŨ̯˳̸ͼ;ɽ;ʺǴůĬŪŪū̾ntVt_BfS3hU5gW6fU7iZ;zlOoȾǰȳɴɴǲƱǲɴ̷̷˶̷˶ȳîwa|SvNwO|U\\muŬǱưǱʴȵůî³m\\wQoDrFxL]tʾȲʳ˴ȱĪɿwzZubDs^Ar^CxdIsYpūŭǭȱʲ˵˵̵˴ʴ˵̴͵͵͵̴̴ǰȮɲͳδɯƿytokjjjtw|zpkjmpty{úļǾŨɭɲ̷н̻վԺѹϷͷͷιι˵зй̰¨·vkhlvū̲θͷ˷ɵƳƳȲȲƳƳǴɶʷ˸̷͸˷̸κѻλĮkX[{W_pzȫͰβʰȰʲ˵ʴȴůýwqo{ƶǸɻȶƴĲŲǴȷɸ˹˹̺λнѽҿнϷͳҵѳ̬ţõǻ§Ǭ˯ͰͰʭʯ˱ͳϵʹȲū̽Ǻþþǭ̴Ͷκ͹ͺ̺̼̼οοϾͺͺ͸̳ɯǭ˿ǽŻŻǽɿɿɿʿɾȽʿűȲ˷ͷ͹ηѺҺӽӽӾҽѽѽϺιʴǯ©qzXyUzXbvǾȬͳ͵̹̹ɻɻɽɽͿ˹Ʊ¦ȿŞɢ̧άϱϴηνϾξξϽѾӽսּ׺ػػ׽վҿҿӿпҿҿԾҿҿѾнннннѾҿҿҿҿѾѿѿѿѿооѿѿɷƴñƿü»°ĲĲñ°ñĲĲųųƴƴųųĲ³ôųƴƲİ¬kkaHYM5XH/[K2bN6cQ9rcLǿůƳ¯ðİıưŮŮĬŬƩ¥ǪˮɬˮǪ}`ugJgY<fY9i\\<eV7qcHr]{ļůªë«ìĮưȲɳ˸ɶɳɳȰƮªſtxYzkLufGxiJyZlȽǭʰƮĮŰ¯ſ¼ű¨þ`ld?g_:gZ:fX;hZ?vhNtȨ̯ʰɵ̻̽ʽ˻ȷűí¨ɴîʺorTubDjW9hW9gV8j[<|nQqǽƯɴ˶˶ɴǲȳɴ˶˶˶̷˶ƱŽ~hW~SW_lt|ļĤǩȪʱ̶̸ƲİűƴðƱƯξoa{QwIvH{ParȾìƯŮ¦z~\\xeGvaDvbG}iNw]sūĬǭǰɱʴ˵̵̵ʲ˳͵ζζζͷͷʴɱȲ˵ιιɴīŶĴzwuuvwxx|ĿÛßÞÞÞĠǣʩ̫̬ϳϵ˶̺ϿӾӹѹϷͷ̶ιϺʴѸѺβƬʿ·¥ʰϵθͷ̸ʶɵȴǱǱǱȲɳ˵ͷθϺϺͻͻμϻͼǴ˾ǸuwqyɾˮϲϳʰȰʲ̴˳ǱưſȷʳʷɼĻ÷²²²ĳƵʷ̹˸˸͹θϻкѽѾ̿ξϼθͳαΰͭʪƦŤŧŨëȯ˲ͳͳ̲Ͳ̳˳ζѺһмζ˰ɪǨä̿Ȼķµ½Ŀþ½ĿæȮͳϵηκ͹λμξͿͻͺ˷ȳǱȲƲİƲʶ͹͹̸̼̾̾˻ʼɹȺǷ˽̼ͿϿξͿͼѼҺӽӽԿӾҾѽҽлʴŭƼqnpyżɬϳϵηͺ̹ʼɻɾʾϿϹͱήϫЫЫӯԴӶзι;ϿоѾӽԺչոֹֺպֽӽӽտпҿҿѾнϼϼϼнѾҿҿҿҿҿѿѿѿѿооѿѿѿɷǵĲ°ƿüƿ°ĲĲññĲųĲųųƴƴųųĲƶǷȶȶȵű¬jl`H\\N4YI0\\J2`N6dR:wkSįɳ¯ȴııűŲǱƱƯůůƬ§Ƭ˱Ȯ̯ɭĽn}rVj_AeZ:g\\<aT4m_BymUrŽŰĮ½¬ĮưȳɴʵȳǰƯƬéƿ»}f~oPxiJyjKrSgõ¦˰̲ȰǱǲŲ¯űëžcndAk^<gZ:hY<l^C}oTvæȫ̯ɱȴ˸̻ʻ;ϿνʸưëŲȹôeoShY<hY:gZ:k^>|qQsǾŮʴθι˶ɴɴʳʳɳʴ̶˲īùo\\RS_n¹ȿƦȫȪƨçƯʴʶűĲǵ˹̸¯ǯūȺvfV|MyMUdoüžƽ|~axiLveKveK}mSzawŭŬƯǰɱʴ˵˵˵ʲ˳͵ζϷϷθͷͷɳưǱ˸ͺ˸Ǳæ ;ɼŸøǹ˽¥¤ʿƽƽſýľľýľƢ˧Ǧɧʩ˩ˬͭίгѵԺйʷɷϿͽҽһѹϷ̶˵͹κɳϹӻж˰ƫʿ·ŸŸƹȽŨ˯ϵиθθ͹̸ʶɵȲǱȲɳʴ̶θкѼѼ̹̹̺̺˹ɷȶǱʿα̱джʰȰʲ̴˳ȲȲĬ»Ķ̾¨˱ιʹǺʾǽ̽˺ȸǶƵƵǴȵ˸˸ͷͷθϹϹн˾̼μλθ̴жгϲˮȫƩȫɯƭůǱʴηη͵˳϶εͷкӾԿкζβ̱˯ʮȪǩǧȨȧģǿºƾĦæƩƩǭǭȮ̲иҺҺйκμϼϽпϽ˸ɵ̺ʷǴȵ̹ϼϼλ̽нҼӽӽӿӾѾѾӿͷǱŮê¸ƻȫжһлϼλ̻˺ʼʼ˼ξмѷҴѱѯӰյ׺պѺλϽѿѾӽӽԼԺչչֺռֽտԾӽӽԾҿѾпϿҿѾннϼλϼϼнҿҿҿҿҿѿѿѿѿооѿѿѿʸɷƴųñƿ»»üž°°°ñññĲĲƴƴƴƴƴƴƴƴɹǷŵƳųŲĮlo`I]M4XH/ZI/dS9o_Ft^ưǴǴǴŲȵıŲƳǴȵʴɴɴʷɶǴǲɴɲǰǭhsjKe\\;aX7d[:f]>uiQr]o÷ɽíůǱɳɳʴ̳˲ūç¦´^uT~nMpOwXd|ŨɭͱδʹɳǰƱŰǲȳʵȱǽoxgKl[?eT8iX<rcDvVwéɱϷϹ˵ǳȴʶʶʷ̹λι̷ʳǳƲĳ˾ķĸ}x^shLodFlaCtiI}\\xã͵͹̸˵˵ʲɲɯϴ̲ʯ˰ʭYRV]qīǮȭǭǪũɲɴʵʵʵɴȳȳǳĮ¬īŬɽk_VzQ|Ubr~¹ƽùnw_s]}q[xbr¬ɲȳȳȳȳʴ˵̶˵ͷθͷ˵̶кԾθθͷ˵˵ʴ˵ʵȮɯʱͳͳ˯ȮƪƩæþ½þūǯȰǭŮūǭȮδͳ̲ʰȱȱȱɯūūūƬȮ˱δϵҸжδ̲˱̲δϷ͵̴̶̶̹λнѾӽӽӽҼкθ̶˵ͷθϹиηͶ˴˱ǭƬƬȮ˴Ϸик̶̶˵ʴɳȲȲǱɳʴ˵ͷθϹккҼк̷ʵʵ̷ιлϵͳɰʰͳжѷѺͶ̴ʲɱʴ˵ͷϹ˵ʴȲƮìŮɲͶкѺлѼҿѾμ˹̺̹˸˸˸ʷʷʷ̹ͺͺλλͺͺ̹ʸ˹̺ͻͺͺ̹ͷ̶̶˵ʴɳɳȲȲŰŰŰƱɳ˵̶θϹкннϼϼҿѼѻ͸͵ζϵжѵӷӶгˮǨǨȧȩ̰̰βдͳ˱˱δηͶ̷͸ϺлϺλͺ̻ͻͻϽξ̺ʸȷȵȵ˹˸ʷɶʷ̹ϼѾϿξ̼˻Ͽͽ̼Ѿϼϻѽӿӿнλ̶̹ɴŰéæäŨɭδһѿϿͽμоѾϼ̹ϼλλлкҹӺԻѸҹѻѺϺϺнҿӾҽҽӾӼԽվԽӼһӾԿҿѾмϼнϽѾҿѾҾҾӿӿоооооооооѿѿѿѿѿѿѿоѿѿѿѿѿѿѿѿѿѿɷɷųųĲžüĽƿñññĲĲĲųųƴƴƴƴƴƴƴǴǷǶĴĴĲı¯hk]C\\L3YH.\\K1dS7m_E|h¯ıƳƳıŲıŲƳǴȵɶɶɶɸȷƵǴɶɴǰƯ|duoOkeCe_=e\\=maGsdM~oXh|Ʒʻ˼οìƯȱɲʳɯǭɻŷnvUrQrQ{Zgxƽèǭ˱˳ɳǱƯǯǰɲʴʳǰŹnkSuaHp\\AtcG}nO^}ýƬ˵кѻͷʴʴ̶ʴ˵̶ͷͷ̶˵ʴƴǵñȽǼjw\\}tW|sTz[jť˲˶ʶ˵˳˳˱˯ɯȬƩħϾósZW^jǬ¬ĭůǯȱȭƬƬƯǲȳȳȳȳǲǲɴǲǲȳȳîvjb`hr{ǾƽŻ~srrzǿǲɴɴȳȳɴɴʵ˶ͷθϹͷ˵ʴ̶θͷ̶̶̶̶ͷͷͷʴʴʴʴʴ˵̶ͷ˵ɳưĮíĮưǱ˵ͷθͷ˵ʴ˵ͷϹθͷ˵ʴʴʴʴƱƱƱƱȳ˶͸Ϻкθ̶˵ʴ˵̶ͷϹθͷͷθϹѻҼѻѻѻѻкϹθθ˵̶ͷθϹккϹʴɳɳ˵θкѻкͷͷ̶˵ʴɳɳȲɳʴ̶ͷϹϹккθ̶˵ʴʴ˵ͷϹϹͷ̶ͷкҼҼѻϹθ̶˵ʴ̶ͷθ˵̶̶˵ʴʴ̶θӽҼѻѻҼҼкθͺ̹̹̹˸˸˸ʷ˸˸̹ͺͺ̹˸˸ʷʷ˸̹̹̹̹˸ʷʷɶɶȵǴƳƳƳƳǴǴɶ˸̹ͺͺλϼϼλϼҿѽмҼԾս־ּԺдɭŨæäæȬʰͳδ˴ʳ˴ηϺ͸̹ͺϼннλ˹˹˹̺μоѿоͻ̺ʸʸ˸̹˸ʷʷ˸ͺϼѾппϾϾϾλоѾϼнѾнϼλλϼλ̹ʴгΰαϵѻҿ̿˻ͽоѾнϹѽҽҽѼѼѼллϺлѼϺιιлмտԿӾӾӾӾԿԿԿӾҽҽӾԿҿѾнннϼннҿѾѾѾҿҿооооооооѿѿѿѿѿѿѿѿѿоооѿѿѿѿѿѿѿѿɷȶųƴƴų°ƿƿĲĲųųųƴƴƴųųųųųųųƳƶŴóóĲı¯hk]C]O5]M3aQ7jY?rdJpıŲ¯ıŲŲǴȵɶɶɶȵɸȷƵǴɶɴǰƯǭmzZsmKofEmbFi^Bi^BtiM}axĹȽ¦ũȬɭū¨ȼkzZnPqS|]m~ǼɮĩǭɱȲưűƱƱʳ̵̴ʳĭ÷qv^oVmRvYap¢ɯͷѻҼϹ̶̶ͷʴʴʴ˵˵˵˵˵ƴɷƲɾĹ~spouǧȯɴɳʴ˳˳˱˯ĪĨȺvlbdl}Ŀɭ͵ưǲǱȰǰǬǭǭĭįƱǲǲǲǲǲɴʵ˶̷˶ȳŰĪļzux|ǾǽȾȾǿǲ˶ɴɴȳȳɴʵ˶˶θϹкθ˵ɳȲȲ˵̶̶ͷθϹϹкͷ˵ɳȲɳ̶ѻӽϹθ̶ʴɳʴ˵˵ϹкѻкθͷͷθкϹθͷ̶̶̶̶ȳȳǲȳɴ̷ιлкϹθ̶̶ͷθϹккθͷθϹкѻϹккѻѻккϹʴ˵˵ͷϹѻӽԾθͷͷθкҼѻкθθͷͷ̶˵˵ʴʴ˵̶θϹϹкϹ̶˵˵˵̶ͷθϹͷͷϹѻԾԾѻϹѻкθ̶̶̶ͷθɳ˵θϹθͷͷͷӽѻкϹѻҼѻкλͺͺͺ̹̹̹˸ʷʷ˸̹̹˸ʷʷɶʷ˸̹̹̹̹̹ʷʷɶȵȵǴƳƳɶɶɶɶʷ̹ͺλʷ̹ͺλλϼҿѾѾտջ˰§żɯͳζϷиҺкϹͺλнѾнϼ˹˹ͻμϽооооϽͻ̺̺ͺͺ̹˸˸˸ͺϼнппппнϽҿҿнннλͺͺϼҿҿѻԺԷҵҸӽҿѿϿ̿˾˾ͽоҿѾѾӿӿӿҾмϻ͹̸͹κκ͹̸˷͹ϻԿԿԿԿԿҽҽҽҽҽҿѾѾѾнннѾѾҿѾѾѾҿҿѿѿѿѿѿѿѿѿѿѿѿоооϽооооѿѿѿѿѿѿоѿѿѿѿѿѿѿѿѿѿѿȶǵĲƴȶȶųñƴƴƴǵǵǵȶȶųųųųųųųƳǷƵóĴųŲð­on_H_Q7aQ8gW=raGzlRt¯ııðƳƳƳǴȵɶɶɶȵɸȷƵǴɴɴǰƯɯʰǫ»vg^vWvkKmbDqfFwYk|·ƻɾ˿ȼzi|\\x\\dsź¨ʱǭǰȲǱűűǲȳηϸ͵ȱ«ĸsnnr{ȨʰͷѻѻϹͷͷͷʴʴɳɳɳʴ˵˵ƴȶűɾźĹǾģȨȯɴʴ˵˳˳ʰʰĩ¦ʼ|wsrtżŨʱ̷ʵʵȳǰǮǭǫȮìįƱǲȳɴɴɴɴ˶͸̷ʵɴ˶δƥûǽ§©êíȽļ­ȳ˶˶ʵɴɴɴɴʵ˶̷θϹкϹͷʴȲǱ̶ͷθθϹϹϹϹϹͷ˵ɳʴͷѻԾθθ̶˵ʴʴʴʴͷθϹθ˵ʴ˵̶ѻкϹθθθθθ˶ʵʵʵ˶͸ϺлӽҼѻкккѻҼѻϹθͷͷͷϹϹккѻѻѻкϹθ̶̶̶̶θкӽտкϹθϹѻѻкθϹϹθθͷͷͷ̶˵˵ͷθϹϹϹϹͷͷθϹϹккѻ˵ͷϹӽտԾϹ̶ӽҼкθͷͷͷͷȲʴ̶ͷ̶˵˵̶ҼкθͷϹѻѻѻλλλͺͺͺ̹̹ʷ˸̹̹̹̹˸ʷʷ˸̹ͺλλλͺ̹˸˸ʷɶɶȵȵ̹̹˸˸̹ͺλϼɶʷ̹ͺͺϼҿѿϼѾֿʹǽ~x{ͳӻսսӻкϹͺλнѾѾϼͻμоѿоѿоμͻͻͻͻͺͺ̹̹ͺλϼнпппϾϼμϼѾҿѾнϼλ˸˸̹λҿҼϵδδϷѾѾӿӿӿѽϻ͹̸͹κϻκ̸̸κϼԿӾҽѼѼлҿҿѾнннѾѾѾѾҿҿѿѿоооϽϽϽооооооооѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿǵǵñƴɷʸȶųññǵǵǵǵȶȶȶɷųųųųųųųƳȸǶƳƳǵǴƳįol`H]Q7`R8hZ@vfMr[xǴɶƳ¯˸ǴǴȵɶɶɶɶȵʸɷǴǴʴʴȰǯǭ˱αɫþre}\\|Xdmvv|}ĺ~vszõʼëĮɲʵʴȵǴƳȵ˷кһ͵ƯȽôúĥͰʲ̶θθͷ̶̶̶ɳɳɳɳɳʴ˵̶ǵƴĹøƼǽĻȿĥǨǨƩʱ˶̶̶̴ʲȮǭèø~Ƿ̾ĩǯȴɵ͸̷ʵɲɰȮȬɯƯƱȳɴʵ˶˶˶ɴ˶̷ʵƱƱʵϵˬʦƥâ££æèĩȯ˲ȲǱƲïʿŰîîįȳ˶̷̷ʵʵɴɴʵʵ˶̷θθϹϹϹθ̶ʴθϹϹкϹθͷ̶кϹθͷͷθϹϹ̶̶̶̶˵ʴɳȲ˵ͷͷ̶ʴɳʴ˵ѻѻкϹϹϹϹк͸̷˶˶˶͸ϺлҼѻѻѻѻѻҼҼкϹͷ̶̶̶θθҼҼҼѻкθͷ̶кϹθͷθϹѻҼкϹθϹккθ˵ϹϹϹϹθθθθ̶̶θϹϹкϹϹθθϹϹкккѻ˵̶θҼӽҼͷʴҼҼѻϹθθͷͷ˵̶̶˵ɳɳ˵ͷкͷ˵˵θкѻкλλλͺͺͺ̹̹̹̹ͺλλͺ̹̹˸˸ͺλϼннϼλλͺͺ̹˸˸ʷλλͺͺͺλλϼɶʷ̹ͺͺϼҿпнտѻѸǻpz^{mRxjMynR}`}˰ռؿռзкϹκϻѽҾѽмͻμоѿооϽμͻ̺̺ͻͻλλλλλϼϼнпппϾνλͻͺλϼнϼλ̹˸ʷ˸̹ϼнϼθ̴̴̴θнѿѿѿѾѾѾѾѾнϼλϼннϼͺͺϼѾԿԿԿӾҽѼлҿѾѾѾѾѾѾѾҿҿѿѿѿѿѿоооϽϽϽооооооооѿѿѿѿѿѿѿѿѿųƴñƴɷʸȶƴųųǵǵǵǵȶȶɷɷƴƴƴƴƴƴƴƴȸȷǴǴȶȶǴŰquiSh\\Dj[DrdJrXhʷʷȵððͺȵȵɶɶɶɶȵȵʸɷǴǴʴʴȰǯȰʰ̲̯ȫåþ|y|~}²ɻĬŭưů®˶˸̹ʷɶɶʹ͹кѻζǰë¬ͽϿξϿ§ƪʫϯѴʲ˵̶̶̶̶˵˵ɳɳʴʴ˵̶̶̶ʷųʿĹźƭ©§ĩȫˮˬȩƪ̳͸ͷθ͵˳ȮƬ©Ⱦ¶ʹϾĪȮɳʴɶɶ̸̸̷̵˲ʰʮʰȱɴʵ˶̷̷̷̷ʵʵʵǲįįȳ̵ϲίͰ̯ʯʯʯʱεϹϹ͹ʶǵƴųϺ̷ɴȳʵ̷͸͸ʵʵʵʵʵ˶̷̷θͷͷθккϹͷθϹϹкϹͷ˵ʴϹϹккϹθͷͷͷθϹϹθ̶ʴɳ̶θϹθͷ̶ͷϹѻкϹϹϹϹккι͸̷˶˶̷ιϺθθϹϹϹϹккϹθͷ̶̶ͷϹкӽӽӽҼкθ̶˵ҼѻкϹϹϹϹϹϹθθϹкϹ̶ʴϹϹϹϹϹϹθθͷͷθϹккϹϹϹθͷͷ̶ͷθθ̶̶ͷϹѻкͷ˵ѻккϹϹθθͷϹϹθ̶ʴɳ˵ͷ˵ʴɳʴͷϹϹθλͺͺͺ̹̹̹˸̹ͺλλλλͺ̹ʷ˸̹λϼнннннϼλλͺ̹̹нϼλλͺλλλʷ̹ͺλλϼҿӽ̶ʾ~drfLcU:YK0\\N1bW;zuXxǬзռӺʹϹθ͹κмѽмϻ˹˹ͻμϽоооϽμͻͻ̺ͻͻμϼϼϼϼϼϼϼϼппϾϾϾϼλͺ̹ͺλϼϼλͺ̹˸̹λλ̹ʷкϹϹϼѿϿϽоѾѾнϼннѾҿѾҿҿѾϼϼѾӾԿԿӾԿҽҽѾѾѾҿҿѿѿѿѿѿѿѿѿѿѿѿоооϽѿѿѿѿоооооѿųųñƴȶȶǵƴƴƴƴƴǵǵǵȶȶȶǵǵǵǵǵǵǵǵǷƶƳƳǵȶǴŰm|f|fjxǴǴʷǴŲ̹ȵɶɶʷʷɶȵȵʷɶǴǴʴʴȲǯ̴˱ʰʰ˱ˮȫƨƿý¼ýľžƿĽĽž»ĺæȰ˵ǱưȴȴƳʷ˺ͻ̺ʺɹɹ˸̷ииɳƮưǱĭȱɯʰ̰ͱггг̴˵˵˵̶̶˵ʴȲɳ˵ͷͷͷͷ̶˶ǲ­ǿƾĭɯɯɭʮ̯ͰͰɬƪ˲˵θϹϷ͵ʳɯƬ¦Ƽź˽Ͽīȱ˵ʸɷʷ˺ʹ˸͸ηε̲˯ʰʳ˶̷̷̷̷˶˶ʵʵȳǲƱǲʵ̵ϵϳϳϳδδͳ̵ηϺѼнͺɸɸ̹Ѽι˶ɴʵ˶̷˶˶ʵʵʵʵ˶̷͸кͷ˵˵θϹθ̶˵̶θϹϹͷ˵ʴͷθθϹϹϹϹϹͷϹкѻкθ˵ɳͷϹѻѻккҼӽкϹϹθθϹккι͸̷˶˶˶͸ιͷͷθϹϹϹϹϹкϹθθϹкҼӽҼҼҼѻкϹθͷкѻѻѻкϹϹθθθθкѻкͷʴθθθθθθθθͷθϹкккϹϹҼкθ̶˵̶ͷθѻϹͷͷϹкϹθθϹϹϹϹθθͷθϹкθ˵ȲǱȲǱưǱɳ̶θͷ̶ͺ̹̹̹˸˸˸ʷ˸̹ͺͺͺͺ̹˸ȵɶʷ̹ͺλλλннϼλͺͺ̹̹ннϼλͺͺͺλͺλϼϼλϼҿͷíqtfL`R8XJ/ZL1gY<ujNoǫ˲ҹԻзϸͶ͸ιлѼлκ˸˸˸̹λнѾҿϼϼλλλϼϼнϻмммммϻϻҿҿѾѾннϼϼҿѾнннѾҿҿϼ̹̹ϼѾҿѾϼλλϼннλ̹нϼλϽѿϿξϿѿҿнλλнҿѾҿѾннҿѼӾԿԿӾѼԿԿԿѾѾѾҿҿѿооϽϽооѿѿѿѿѿоѿѿоооѿĲųñųǵǵƴųƴǵƴƴƴǵǵȶȶȶȶȶȶȶȶȶȶȶƶĴıŲƴǵƳıǿɾȵı¯ʷ˸ƳʷɶɶʷʷʷɶȵȵʷɶǴǴʴʴȲǱи͵ʲɯ˱˱ȮƩȬȬɭʮɭƪç¦çĨƪǫǫǫǭǰǰʰͳɯĪƭγ¯ɵȵİïȴ˸ɶȷʹͻ̺ʺɹɹʷȳϷѺ̶ɱɲǱůȰɱʲ˰̱ϲϲ̯͵̶˵˵̶ͷ̶˵Ǳɳ̶θϹϹͷ̶̷ȳƱƱƯƯǰɲ˱˱˱ͱβͰʮȫɰʴͷкѹи̵˴ɯǭī§§ħĪū;­ƳȶǶȶɹ̼ȷʷιθϷδ̰˱˴˶̷̷̷˶ʵʵ˶ʵȳǲȳʵ̷͸˴ͳͶͶηηιι˶̷ϼн̻ʹ̻нͺ˶ɴɴɴʵȳǲ˶ʵʵʵʵ˶̷͸ѻͷʴɳ˵ͷ̶ʴȲɳ̶θϹθ̶˵̶̶̶̶ͷϹѻҼͷθкѻѻθ˵ɳͷϹѻѻѻѻӽտϹϹθθθϹккι͸̷ʵʵ˶̷͸θθкѻѻѻѻѻѻѻккѻӽտϹккѻѻкϹϹθϹѻҼҼѻϹθθθϹѻҼѻθ˵θθθθθθθθθθϹкккϹϹԾкͷ̶ͷϹкԾѻθͷθкѻѻͷͷθϹϹϹθθɳ̶Ϲθ˵ư¬ĮĮưɳ̶ͷ̶ʴ̹̹˸˸˸ʷʷʷʷ˸˸̹̹˸˸ʷŲƳȵʷ˸̹̹ͺϼϼλλͺ̹˸˸ѾнϼλͺͺͺͺλϼннϼϼҿпϾǱǻ|dj\\B]O5_Q6k]BuXq˯ʮɰѸ׾ֽηͶ̷͸ϺлϺιͺͺͺͺϼҿннϼϼϼнѾҿммѽѽѽмϻϻҿҿҿѾнϼͺ̹ϼλλϼнѾͺ̹ϼѾннѾѾϼͻ̺̺ͻ̼ϿξͽϿѿнͺͺϼҿѾҿҿѾнϼѾлҽԿԿҽлԿѾѾѾҿҿѿоϽϽμμϽϽоѿѿѿѿѿѿоѿƴȶȶȶȶȶȶȶȶȶʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶƳɶ˸ȵññǴ̹ıûļŰıƳȵʷ˸ʷȵǴɶɶɶɶɶɶɶɶ˷˷ʶɵȴȴǱư˵̳ʹʹʹ̳˲˲˳̶ͷ̶ʴǱĮȲȲȲɳɳʴʴʴ˳ʲʲɱɱʲɲ˱ɷʷɷʷʷʷɸɸʸʸʸʸʺʺʺ˸͸ͶͶ˵˳ɲɲȲǱɰʱ̲ͳβͳͳ̴˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷ˵ʴǱưŭƮȰɱʲ˱̲ͳͳαͳ̲ʹͷͷθζ͵͵̴ȱȮƬūƬǫɰʱŲŴƵǷɸʸʺɹ˸˸˷̶̴ͳͱͳ˴̷̷͸͸̷̷˶̷˶˶ʵʵ˶˶̷ϹϷϹϹϹϹλλλλμμμμμλ̹͸͸͸͸̷˶ʵʵʵɴʵ˶̷͸ιθ̶ʴʴ̶ͷ̶˵ͷͷͷ̶̶˵˵˵˵̶θϹкϹθͷͷθϹкϹθͷ̶ѻѻѻѻѻѻѻѻ̶ͷϹккϹͷ̶˶̷ιϺлϺι͸θθθϹϹкккѻѻѻѻѻѻѻѻккккккккѻѻѻккϹϹϹϹϹϹϹϹϹϹϹθϹϹϹϹθͷ̶θθθϹϹкккҼҼҼѻкϹͷ̶Ϲθͷ̶̶θϹкȲ˵θѻѻҼԾӽӽҼѻθ˵ȲưůưǱɳʴ˵˵˵̹̹̹˸ʷɶǴƳıŲǴȵɶȵǴƳŲƳɶ˸̹ͺ̹̹̹λннλͺλϼϼнѾнλͺλϼͺλλλλ̹˸˸ͼʹ̹˵ʿu|pVpdJykP~czçȬƪȯзԻԻϸϸϺϺϺϺιιͷͷͷθϹҼԾҼк̶̶ͷкѻѻҼѻкθͷͷͷθѾѾѾнϼͺ̹˸ѾѾннѾѾϼнннннннннϽϽμϽоѾϼϼнҿҿѾѾѾѾҿԿҽϺ͸ӾӾԿԿԿӾоϽϽϽϽϽѿооƴȶɷɷɷɷɷɷɷɷʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶǴʷ˸ɶĲñǴ˸̹ɶı­ƳɶǴǴɶʷʷɶȵȵɶɶɶɶɶɶɶɶ˷˷ʶʶɵȴǱǱʴ˵ʹʹʹʹ̳˵˸̺̺̺ʸǵĲ°ȶȶɷɷʸʸʸ˸̶˳˳ʲʲ˳ʳ˴ʷʷʷʷʷʷɸɸʸʸʸʸ˸˸ʺ˸̶Ͷ̶˵˳ʲɲɲȱɲ˱̲ͳδͳ͵̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷ˵ʴȲưƮǯȰɱʲ˳̲ͳͳͳͳ̴̶̶̳ͷ͵̴̴˳ʳɲɯȮȮʰ̵̲ǳǵǷȸʹʹʸ˸˸˷˵̶̴͵ͳͳ˴̷̷͸͸̷̷˶̷˶˶ʵʵ˶˶̷ϹϹϹϹλλλλλλμμμμμλ̷͸͸͸͸̷˶ʵʵʵɴʵ˶̷͸ιϹͷ˵˵ͷθͷ̶ͷͷͷ̶̶˵˵˵̶ͷθϹкϹθθͷθϹккϹθͷѻѻѻѻѻѻѻѻ̶ͷϹккϹͷ̶̷͸ιлллϺιθθθϹϹкккѻѻѻѻѻѻѻѻккккккккѻѻѻккϹϹϹθθθθθθθθθθϹϹθͷ̶̶ͷθϹϹккϹϹҼҼҼҼѻкϹθϹθθͷͷθθϹͷϹҼҼҼҼӽԾкѻѻѻϹͷʴɳůưȲɳ˵̶ͷͷ̹̹̹̹˸ʷɶȵƳǴɶɶɶȵǴƳðŲȵʷ̹ͺͺͺ̹λннλͺλϼϼѾѾнλͺλнλλλλλλλλϽͻϼӼ˵Ż{twȿĿƪȬǫȯʹ϶̳ййлллѼѼѽθͷͷͷθϹѻҼӽкͷ̶ͷϹϹϹ̶̶̶̶̶ͷͷͷнѾѾѾнϼλͺλλͺͺλϼнѾҿнϼнҿнλннннннноϿϿμͻλнҿҿҿѾѾѿѿѿҿѾнннҿҿнннѾѾӾԿԿҽлӾӾԿԿԿӾҽҽѿооϽϽϽоѿѿƴȶɷɷɷɷɷɷɷɷʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶȶʸ˹ȶųñƴɷѿμ˹ɶǵȵɷ˸ʷʷɶɶȵȵɶɶɶɶɶɶɶɶɶɶ˷˷ʶʶɵȴȴȴʴʴ˵ͷͷͷͷ͹ͺ̼ͽ̼˻ȸƶĴʺʺʺʺ˻˻˻̹͹̶˵˵˵˵̶ͷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʸ˷̶ʹ̴˳˳ʲʲʲɱʲ˳̴͵ζ͵͵̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷ̴ʲɱǯǯȰɱɱʲ˳̴͵͵͵͵̴ʲ˳̴̴̴̴˳ʲ͵̴˳˳˳̴ζηʵʷ˸̹̹̹̹˸ʷ˵˵̶˴̵̵̵̷̷͸͸͸͸̷̷̷˶˶ʵʵ˶˶̷λλλλλλλλλλλλλλλλ͸͸͸͸͸̷˶˶ʵʵɴʵ˶̷͸ιϹθ̶̶ͷϹθͷͷͷͷͷ̶̶̶̶̶ͷθϹϹϹϹθ̶ͷθкккккѻѻѻѻѻкккͷθϹккϹθͷ͸ιϺллллϺθθθϹϹкккѻѻѻѻѻѻѻѻккккккккккккϹϹϹϹθθθθθθθθͷͷθθθͷ̶˵̶ͷϹкккϹθкккккϹϹϹθθθϹϹθθͷϹѻҼҼкθθϹϹϹкккθ̶˵ưǱȲʴ̶θϹϹ̹̹ͺͺͺ̹̹˸ʷʷ˸˸˸ɶǴƳðƳɶ̹ͺͺͺ̹λннλͺͺλнѾҿѾϼλϼнͺ̹˸˸̹λϼѾϽнѾֿϵƬǽĺĻƽå̯ŨȭʯʯʹѸз̳θθκκϻмѽҾϹθͷͷ̶ͷθθӽкͷ̶ͷθθθ˵̶ͷϹкккклѼҽӾӾҽѼлϺϺϺϺϺϺϺϺϼλϼнѾѾλ˸ннннннноξͻͺѻӽտӽҼѻнѾҿϼннѾҿϺлҽԿԿԿҽҽԿԿԿԿӾҽѼѼҿҿҿѿѿоϽоооѿǵɷʸʸʸʸʸʸʸʸʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶɷ˹˹ɷƴĲųǵ̺̺˹ʸɷɷɷɷͺ̹ɶǴǴȵɶʷʷʷʷʷʷʷʷʷ˷˷˷ʶʶɵɵȴɳʴ˵ͷθθκκ̼ͽͿͽ̾ʺȺǷʼʺʼʺ˽˻˽˻͸̵˵ʴʴ˵˵̶ʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸̶̴̴̴˳˳ʲʲʲɱʲ˳̴͵ζ͵ͷ̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷ̴˳ʲɱȰɱɱʲʲ˳̴͵͵͵͵̴˳̴̴͵͵̴̴˳ζ͵̴̴̴ζϷкͷ̷ͺ͸ι͸θͷ˵˵˵̶˴̵̵̵̷̷͸ιι͸̷̷̷˶˶ʵʵ˶˶̷λλλλλλλλλλλλλλλλ͸͸ιι͸͸̷˶ʵʵɴʵ˶̷͸ιкθ̶ͷθϹϹθͷͷͷͷͷͷͷ̶ͷͷθθϹϹϹϹ̶ͷθϹкѻѻҼѻѻѻккккϹθθϹккϹθθιιϺϺллллθθθϹϹкккѻѻѻѻѻѻѻѻкккккккккϹϹϹϹϹϹϹͷͷͷͷͷͷͷͷͷͷθθͷ̶˵˵˵̶θкккθͷͷͷ̶ͷͷθϹϹͷθϹккθͷ̶̶ͷϹθ̶ʴʴ˵Ϲкѻѻкθ̶˵ǱȲɳʴ̶Ϲкѻ̹ͺλλϼλλͺ̹ͺͺͺ̹ɶǴƳ¯Ųɶ̹ͺλλͺϼннλͺͺλнҿҿѾϼλϼн˸ʷȵȵɶ˸λнѾҿӿӿӽԾ־Ժжͱ̰ȫħŦʭǪȭʯͲѸԻҹ϶ͷͷ̸̸͹κϻϻкϹϹθͷ̶̶̶кθ̶̶θϹϹϹ˵ͷθккккϹιлҽԿԿԿҽѼϺϺлѼѼѼѼѼλλλϼнѾѾнѾѾннннϼϽϽλϹӻջԺӹѷϷϷкҼнѾҿҿҿҿҿ˶̷ιлѼҽҽҽԿӾҽѼҿҿҿҿҿѾѾҿҿѿѿоооѿѿѿѿȶɷʸʸʸʸʸʸʸʸʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶʷ˸˸ʷȶƴǴǴǴȵɶʷɹɹɹʷͺ˸ɶƳƳǴɶʷʷʷʷʷʷʷʷʷ˵̵̵˴˶˶˶ʵɴʵ̷͸ιϺλλͺͺͼͺͼ̹˺ʷ˺˸˺˸ʹʷʹʷ˶ʵʵɴɴʵɵʶ˷˷˷˷˷˷˵˵̶̶̶̶̶̶̶̴̴̴̴˳̳˲ʴʴɳʴ˵̶ͷθͷͷ̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷʹ̳̳˲˲˲ʴʴʴ˵̶ͷͷͷͷ̶͵ζζϷϷζθͷ̶̶̶̶ͷͷθθθζϹϷϷϷͶ̵ʳʳʳ˴˶̷̷̷̷͸ιιιι͸̷̷˶˶ʵʵ˶˶̷λϻϻϻϻϻϹϹϹϹϹϹϹϹϹϹ͸ιιιι͸̷˶ʵʵɴʵ˶̷͸ιкθ̶ͷθϹϹθͷͷͷͷͷͷͷθͷͷͷͷθθϹϹͷͷͷθϹкѻҼѻѻѻккϹϹθϹϹϹккϹϹϹιιιιϺϺллθθθϹϹкккѻѻѻѻѻѻѻѻккккккккθϹϹϹϹϹϹϹͷͷͷͷͷͷͷͷͷθθθθͷ̶˵˵̶θϹϹϹθͷθͷͷͷθϹкѻθθϹкϹθ̶˵ɳ˵ͷͷ˵ʴ˵̶ҼҼҼҼкθ˵ʴɳɳɳʴ̶θѻҼͺλϼϼϼϼϼλλλλλ̹ʷȵƳðƳɶ̹λλλͺϼннλ̹̹ͺнѾҿѾϼλϼн̹˸ɶȵɶ˸ͺмԿѺйҹռѶγ̯̯ȪĦťʬɬǭȮ˱͵͵̴˳̶̶̹̹ͺͺͺ̹кииϷζ͵͵̴͵˳˳̴Ϸѹѹиʳ˴˴˴˴˴˴ʳ̷ιѼӾԿӾѼлϺллѼҽӾӾԿҿҿнϼϼнҿѾѾѾннϼϼϽϽθζжӶϲαͰ̯̲ϷѹӽκϻмѽѽѽѽѽӿѾ͸͸ϺлѼҽӾӾԿӾӾҿҿҿҿѾѾннѾѾҿѿѿооѿѿоȶɷɷɷɷɷɷɷɷɷʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶɶʷʷʷɷȶȵǴŲƳȵʷʺʺʺ˸˹ɶǴƳŲǴȵʷ˸˸˸˸˸˸˸̸˵̵̵̵̷˶˶˶ɴʵ˶̷̹̹̹̹ι͸͸͸͸͸͸͸̷̷̷̷˶˶˶˶ʵʵɴȳȳɴɵɵ˷˷˷˷˷˵˵˵ͷͷͷͷͷ͵͵͵˴˴̴˳̳˲ʴʴɳʴ˵̶ͷθ͹͹̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷʹʹʹ̳̳̳ʴʴʴ˵̶ͷͷͷ͹̶θζϷииϷθθ˵̶̶̶ͷͷ͹ͷзеϷжϵϵδͳ˱ʳʳ˴˶̷̷̷͸͸ιιιι͸͸̷˶˶ʵʵ˶˶ͷλϻϻϻϻϻϹϹϹϹϹϹϹϹϹϹιιϺϺι͸̷̷ʵʵɴʵ˶̷͸ιϹθ̶̶ͷϹθͷͷͷͷͷθθθθθͷͷͷͷθϹкͷͷͷͷͷθккѻѻккϹθθθккккккккι͸͸͸͸ιϺлθθθϹϹкккѻѻѻѻѻѻѻѻккккккккθθθθϹϹϹϹθθθθθθθθθϹϹϹϹθͷ̶ͷͷͷͷͷθθϹѻкϹϹϹѻӽԾϹϹϹϹθͷ̶˵ʴ̶θϹθͷθкҼӽӽҼкθ˵ɳ˵ʴʴʴ˵ͷϹѻλϼϼнϼϼλͺλλλλͺʷȵƳðıǴ˸ͺλλλλнѾнλ̹̹̹ϼнѾнλͺλϼϼλ̹˸ʷ˸̹͹ԿӻѺѸѸѵ˰ɬʭʫŧťȪʭȮȮȮŭĬưȲ˸λϼϼλθθζϷиϷϷζ͵̴˳ʲ̴ϷииϷͶ̵˴˴˴˴̵̵ɴ̷ϺѼҽлι̷ҽѼлϺϺѼӾԿҿҿҿнλͺϼѾҿҿѾннϼλλϿϽ̹ȰūŨŧǩǩȪɫ̯ϵҸԼϹммѽѽҾӿӿӿӿѽϻҼѼѼҽҽӾӾԿӾԿԿԿӾҿҿѾннннѾҿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿоѿɷʸɷɷɷɷɷɷɷɷʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶȵɶɶʷ˹ʸɶȵƶƶȷɸʹʹʹʷǵǴƳŲŲƳȵɶ˸˸˸˸˸˸˸̸˵̵̵̵̷̷̷̷ɴʵʷʷ˸ʷʷʵͶ̳̳̳̳̳ʹʹεεʹʹ̳̳̳˲˶ʵʵɴɴʵɶʷ̵̵̵̵̵̵˵̳εε͵͵͵ͳͳͳ˴˴̴˳̳˲˴˴ʳ˴̷͸͹κ͹͹̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷʹʹεʹʹ̳˵ʴʴ˵̸͹͹͹͹̶ͷζζϷϷζθͷ˵̶ιιϺϺϺϸегеггϲͱ̰ʯʱɳʴ˶̷̹̹͸ιιϺϺιι͸̷˶˶ʵʵ˶˶ͷλϻϻϻϹϹϹϹззззззззιιϺϺιι͸̷ʵʵɴʵ˶̷͸ιϹͷ˵˵ͷθͷ̶ͷͷͷθθϹϹϹθθͷ̶ͷθϹкθͷ̶˵˵̶θθѻѻккϹθͷͷкккϹϹккк͸̷̷˶̷͸ιϺθθθϹϹкккѻѻѻѻѻѻѻѻккккккккͷͷͷθθϹϹϹθθθθθθθθкккккϹθͷθͷ̶˵˵ͷϹкѻкθͷͷϹѻҼѻкϹθͷ̶̶̶˵ͷϹϹθͷθϹѻѻҼҼѻϹͷ̶̶˵ʴɳɳ˵ͷϹϼϼнϼϼλͺ̹̹ͺͺͺ̹ʷȵǴŲǴɶ̹λϼϼλλнѾнλ̹˸̹λϼнϼͺ̹̹λλͺ̹ʷȵƳŲƲʶ̷ϹҼӻӻҸжӷͱʬ̮ʫ£Žı˸ϼнλ͸ʴ˳͵ζϷϷϷζζ͵̴͵ζϷ͵˳ɲǰƯŮŮȱ˴ͶǰɲͶϸϸͶʳȱȱŮ«ìŲɶͺϼλͺλϼҿҿѾннϼλλξξ̺ǱſħƬȰɳɴɴɴʵ˶͸ι͸ϺѼҽӾҽѼϻӽҽѼлллллϺлѼҽӾӾӾӾѾнϼϼϼϼнѾѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿооѿѿɷʸȶȶȶȶȶȶȶȶʸʸʸɷɷȶȶȶȶȶȶȶȶȶȶȶȶȵȶʸ˹̹ʷȵȵȵȵɵȴȴȴǴƲŲŲŲŲƳǴȵ˸˸˸˸˸˸˸̸˵̵̵̵̷̷̷̷ʵʵɶʷʷɶȵǳ̵̳˲˲˲̳ʹε϶϶϶εεβʹʹ̵˶˶ʵɵʶʷ˸̵̵̵̷̷̷˷˵ͷͷͷ͵͵ͳͳͳ̴̲̲˱̳˲˲˲ʱ˲˵̶ͷθͷͷ̶˵˵˵˵̶ͷθͷ̶̶˵˵̶̶ͷ̶ͷͷͷͷ̶˷ʶʶ˷̸ιιιι͸̶ͷͷθθͷͷ̶̶ͷκлϻйϻθзеееδͳ̲̲˱˱ʳ˴̶ͷͷͷ͸ιιϺϺϹϹθͷ̶̶˳˳˴˴̵ϹϹϹϹϹϹϹϹϹϹϹззϷϷϷιϺϺϺϺϹθͷ˵ʵɴʵ˴˵̶ηͶ˶ɴʴ̶ͷ˸ʷ̹̹̹͸͸ιιιλͺ̶̷̹͸Ϻй͸̵ʵʴʴ˵̶ͷѻѻкϹθθͷ̴ѻϸϸηηϸϸй̷̷˶ʵʵ̷͸ιͺͺͺϹϹϺϺϺлллѻѻнннϼкккккккͷͷͷθθϹϹϹϹϹϹϹϹϷϷϷиййллϺλͺλ̹˵ɳʴ˴ηйδͳ˱ɯɯ˱ͳͶҼѻϹͷ̶̶ͷͷ˵̴ζζ̴˳˳̴ͶηйѺѼѻкϹͷ̶ʴȲȵʴ˸̹нннϼλͺ˸ʷ̶ͷ͸͸̵˴ȲǰȲɳ˸ͺϼмϼϻλнѾнλ̹˸̹ͺλϼλ̹˸̺ͺ˸ʵɴǰĭȾžþŰ̵ѺӼйʹӺβʮʭƩ~~~vovǽƯ̵ιͷ̶ưȲʴͷθϹϹϹҹзδϲβͱʭȫžü»ƿçƪƭȯ˲εͷ˲ǱŬŽǲιѻнннҿӿѿѽнϼλλͻͺʷ­|sv{ýľƬȰ̳θмнϼϼѼϹͷʹ˲˲ʱʯ̳ʹϵѷѺһҽӽѾнϼλλϼоѾѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿооѿѿ˹ʸȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶ̺˹ʺɷɶʷ̸ι̷̷̷̶˵ʴɳǲűŲǴɶʷʷɶȵ̹̹̹̹̹̹̹͹ʶ˶˶˶ʶʶʶʶɵʶɶʷɶȵƳŲȴ˶͸ϺлϺ̶˵̶θϹθ̶˲ɳʴʷɶȵɶ˸̹˸ʷ˵˵˷˸ʺʺʺʺͽλͺ͹εͲͲͰα̯ɯʭ˱̲˱˰ʰ˰ʰʰ˱˱̴̲ȳǴǴȵɶʷ˸̹ϼͺ˸ʷʷ˸ͺλͺ̹ʷɶɷʸͺλǶȷʹ̸͹͹͹͹̷̷͸͸͸̷˶ʵʴ˵̶ͷθ϶θͷθϹкѻѻϹ͵˳˳̴ε϶϶϶϶εͶ̶ͶͶͷ̶̷̷ηϸ϶Ͳˮʭ˭̰ʱɳ˴ͷθκκι͸͸̸ͷͷ͸ͶͶ̵̵ͷͷ̹͹͹͹˷ʷȳǰɰʲʰǭʲɳȴȳɶʷ̺ͻ̺˹ʹʸʶʷ̶̹̻ͻ˺ʷǳȴ˵εθ̳ǱƯɱ̴θй϶зѸѸϷζ˴˱ϸε̳˲̳εϷҹ˶ɶȵɶͺλͺʷͺ˹˹̹͸͹̶˵̶ʴʶιнϽμμ̻λλϼкϹз϶з϶ʹʱȲɳ̹ϼλͺ̷͸ϸжϳβϳͲ̳ʴʶ̺̼νнͺ˷̶˴ȯĪç˽ŷĶȺƫ˴λϹʴȲ˵͵̴ƮȮǭĪĿ¥Ⱦ¨ʱεͷͶ̷˶˸ͺͺɶĳŲǶ̹̹͸λλϻκθͷζͳȯʻõưɳͶϹһ͹κϼнϾξξξμλ̻˺̺̺ͽͻɶǱĪʿöïιкθθк϶̳ū|omhhf`Z]grúʭ˰ǮƱ̹м͹˶ιкϺиԸѳɧġ˽¶»ǭ˳ɯĬwpjehsεϸθͺѽѾξϼϼϼ͹˷˵Ϸ̵vh\\X]dks~{~ǾɯλξʴɯǫĹŻǦϰչ׽־սӽԾտԾѻϹӿҿҿѾѾнннλнҿҿѾѿѿоооѿѿѿѿ˹ʸɷɷɷɷɷɷɷɷȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶ˻ʺɹȸʷ˸͸ιлϺ͵˳˳̳ʹ̴ƲƳȵɶʷʷʷɶ̹̹̹̹̹̹̹͹ʶ˶˶˶ʶʶʶʶȵɶɶʷɶȵǴƳɶʷ̹λϼλ͹͹̸κλͺ̶ʴɳʴʷɶȵɶ˸̹˸ʷ˵˵˷˸ʺʼʾʼ̼̾ͺ͹̶ͲͲͰ̲ʰȮȮɯʰʰɯ̲̲̲̲ͳͳδζɴȵȵȵɶʷ˸̹λ̹˸ʷʷ˸ͺϼλͺ˺ʹʺɹɹȸ˺˺ʹ˷̸ͷ͸ιϻϻϻϺιι͸̶̶ͷϹѹѹиζ̴ɴʷʷʷ˸˸̶˵˵̶εε϶εεʹͳ̵̳ζͷη͸͸͵ͳ˲˭ɬʫɩɬͲ˳ɳʳ̶̹ͺͺ̸̹̹͹̷̷̶̶̵̵ͷͷ͹͹ͺͺ˷ʶȳɲʲ̲˰ʯʰɱȲǳȳɶʸ˻˻˹ʹʸʷ˵˶̹˺̺˺˸ɶ˵͵Ϸ˳ǯīéìǯɳʳ϶зззζ͵ͳ̲϶ε̳ʰ˱ͳϵи̷ʷɶʷͺλͺ˸ʺɷǶɶʶ˵ʴɳ̶ʴɵ˷ͺ̻˹ʸ̻˻λϼкй϶жδδʹ̳˵˵ͷλͺ̷̹ͶϵβʭȫˮʭǯǱƳȶȸʻͽͺͺϹ̵ĩǹz{Ÿç̵ϼк˵Ȳ˵̴˳ū¨þǹʾůɳ̷̷λμ̺ƵŴǶ˸̷̹̹̹κκθ϶ϷβǬȽĵůηһӼҽҽѽнпϿξ̼μμͼ̻̼̼̼̺ǵưµoeft}÷ıʵɶɶθͷɱ¨uec\\\\\\Y~STZ^l~Ĥˬ˯ǲ˷̸˶ɷιϺθжҴ̬ĸyxwurwzƬǭér}buVpOmLpMvUnƸƬɰɱ˸ϻѾпννϼϼ͹̶ʲ̲ǱʾuaRKNS]dtsd]Y}Tbr̸ʴǩ˽}|~¶˪ѴԸԼռӽվԾտѿϽϺѻѻҹкӿҿҿѾѾннннҿҿѿѿооѿѿѿѿѿѿѿѿѿѿѿ˹ʸ˹˹˹˹˹˹˹˹ȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶȶɷȶȶȶʷ˸͸ιѼι̴ɱɱʲͲζǳǴɶʷ˸˸˸˸̹̹̹̹̹̹̹͹ʶ˶˶˶ʶʶʶʶȵɶɶɶɶȵǴǴʷ˸ͺλϻϻϻϻ̸κλͺ̶ʴʴʴʷɶȵɶ˸̹˸ʷ˵˵˷˸ʺʺʼʼ˽̼ͺ͹ͷγγγζ̶ʴʴ̶ͷͷ̶̶̶̶ͷͷθθθʷʷɶɶɶʷ˸˸̹˸ʷʷ˸̹λϼλλͻ̺˹ɷȵƳ˸˶ʵʵʵ͵ηϸ͸͸̷̷ʶʴʴʴɳ˳̵ϵϵͳ˱ɲ˶˸˶˶ͷͷθθ̶̶εεεʹ̳̳̲˲˴͵ͷηιιζ̲ɰʬʭʬɩǪγ˱ʱʳͷͺλͺ̸̸̷̷̹̹˵̶̵̵ͷͷ͹͹ͺͺ̸ʶɴʳ˳˱ɮȭǭƮƭůǲɶ˸̺˹˹ʹ˹ʷ̶˶̶˸˹˺̹˵̴ʳ˱ʰƬè¦ĪȮ̳ʹййϸηεε͵͵ηͶ̵˲̳ʹ϶Ϲ̷˸ʷ˸ͺλͺ̹ɷȵǴȳɵɳȲŮȱȰưƲɴ˸ʷɶ̹̺λλϹй϶ϵ̲ͳ̳̳̳˳ɲɴɴǳǱɰʱȭƩ¥ħħê¬®ıóŴ˻ͺнк˴ɿqd}\\~]ftǼ˴ϼк̶ɳ˵̴ʲǭſ¸©ɲ˶ιѾϼ˹ȶȶʷ̹˶ʷʷ̸͹ϹѸ̴ʮth`dmzľεӼӼѼϺͺμ˻Ͻμͼ̻̼˻˻˹ĲĮʼoYzPyQ|`i~¯̷ͺͺϹͷɱ¨se`\\\\^]WTT|T^mzĦȫ˵ι͸˶͹ӽѼϷ˯ɪwoimnopuyüĬƮŭ¨{gvWrQpOrOuTiŷǭʱʲ̹ѽϼλ̹ͺλϼ͹̶ζϵʴĮ˼~fXOOR[dw~f|WwPuKrK[yʶ̽ʱå´ofdgrŤͰдѹӺԾվӿӿҿҿѽκιѻӻռռտӿҿҿѾѾнннҿѿѿооѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿѿ˹ʸʸʸʸʸʸʸʸʸɷɷɷɷɷɷɷɷɷɷȶȶȶȶǵǵǵǵǵȶɶʷ˷͸˶ʵȱȰǯȰʯʰɵȵɶʷ˸˸̹̹˸˸˸˸˸˸˸̸˷̷̷̷˷˷˷˷ɶɶɶɶɶɶȵȵ˸̸ͺκϻммм˷͹ͺͺ̶ʴʴ˵˸ɶȵɶ˸̹˸ɶ̶̶̸̸̹˻˻˻̼ͺκθ϶ϴгеͷʷɷɶ˹̹̺˸ʸʷʸ˸˹˸̺̹˸ʷʷɶʷʷ˸˸˸˸ʷʷ˸ͺλϼλͺ̺ʸɷȵɵɵǳǱȲʱ˲ʹγεʴ˴ʶʴɳɳɳɱȰȮȮȮɯʮʱ̲ʵ̷ιϺкϹ̶˵̶̶ʹεʹʹ̳˲˱ʱʳ˳̶ͷϺϺѹϵ˲ʭˮ˭ɩƧǫūƮʱηѻϻ̹˸˸̸̸̶̷˵˵ͶͶθθκκλλ͹ʶȳʳȰ¨˽ɻƻƻǻɿ«ǲͷϼʷ˸̷̶̴̹˴̶ɶɶɶɴǯĪͿʼʿƻ·Ľū˱зйϸηͶ̳ʹζϷζͶ̵˴˴ͳ̶ηͷ̹̹̹ͺͺͺ̹˸˵ɴȱǱĬο˽ʼʻǻƻȳ̶ʷ˹˹ͺͺθθεϵͳ̲ʱʱɱɱǰĮĮ¬˿ɿƽƽǽíðĲʺλнкʳǽwbtSzkJ|mLuTc~ǰ̹Ϲ̶˵̶͵ʲʰ}sopqyƼƯ˶ҼҿϽͺ̸̹̹˶ʷɶʶ͹Ϲҹ˳ɭȾs_rQzjH}nQsYg͵ԻһͶ˶ɶ̹о˻оϻλ̻̼˻˻˹ĲíȺgxOpFqI~mOu\\tíϺѾѾкϹ͵ȰĽsmhhjkg]W}T[dmyĿ˱ʹ˵ʴϸһ϶ɰ¾znhegqx~ƮɱǯĬhrU}lNnMqPsRjƶƬɰǰ˵ϻͺ̹˸̹λϼκ̶ѹж̵ɳǯξocZUW`l̾ȺdvO}pF{nDxjCuOlǰѿʸ˲å{e~X{T~W_qʭβѹӺֿӿҾѾҿѾϼκϹѺԼԼӻӼӼӽԽվֿҿҿҿѾѾнннҿоѿѿѿѿѿѿѿѿѿѿѿѿѿ˹ʸʸʸʸʸʸʸʸʸɷɷɷɷɷɷɷɷɷɷɷȶȶǵǵǵƴƴǵȶȵɵʶʶůǰɲɲɰɯǭŬɵɶɶɶʷ˸̹ͺ˸˸˸˸˸˸˸̸˷̷̷̷˷˷˷˷ɶɶɶɶɶɶʷʷ˸ͷͺϹϹϹϹθʷ̹ͺͺ˸ʷʷ˸̸˷ʶʶ̸̸˷ʶ̶̶˸˸˹˹˹˹ͻͻͺϹϷϵгϵȵŴĵŴǸȷȹǶɺʹʻʹ˼˺˼˺ʷʷɶɶɶʷ˸̹˸˸˸˸̹ͺͺλͺ͹ʶȴȴɳ˵͵ʲ˱̲̲̯ʭȫƩƮȯɳʲ˳ɲɲɯǭèȾŻŻéǬŮ˴йѺͶɱŭʹʹεεεʹʹ̳˱ʱɲʲ˵̶ϺлйʹʱƩæƽĻƺŬηҼϻ˷˸˸˷̸̶̶̵̵ͶͶθθκκλλϻʶǲȱƿɱθ˵̶̷Ͷ̶̴ʳ˳ɴɳƯū˿·|ħ̱϶ϷͶ̵̵ͶθϹͷͷͷ̶̶̴̷ͷ̹̹ͺ̹̹˸̹̹˵ʲǰū÷ǿʲ˵ʸʸ̹̹ͷͷͶͶ̳ɰȯɰʰ̲ʱȯ˽õ¹ĻüſĮůƲ̹ϼϼͷɲx~_qPwhGzkJqP|[u«ɳͷ˵˵ͷ͵˳ʰé¼½rld_bnéͷӽӿѼϼлͺ̷ʷɶ˷͹ϹҹϷβ§o|YlKwdCudFwgMv[w˱ӹԻϹ͹̹λϿξʹϽκλ̻̼˻˻˹ǵůȺctKlB~lDsbDzjQiɽʳ̷̶ͷͷζ͵ǭĽre\\]^ajvūƬǭɯʰérf]\\`j|ĻǾƽĻĻüƬʲʲǯĬkpSxgI|iHmLnM}]s÷Ⱦưʶͺ̹˸̹κϻͺ̶͵̴ɴȲʲ¨veZTU_kĨȭʿatLzmCylBuiAznH`̹̼˹̳ȩøg{VwPxQyReĻʭдҺӺӿҽӾӿԾϹθθзѷѷδ̲ϴеϵѶҹӺӽԽӼԿԿԾӿѾнҿҿҿѾѾнннѾѾҿҿоѿѿѿѿ˹ʸɷɷɷɷɷɷɷɷʸʸʸʸʸʸʸʸʸʸɷȶȶǵƴƴƴǵǵȶȵǴǳǳůǱɳ̵̳ʱǮŬɳȵȵȵɶʷ̹̹ʷʷʷʷʷʷʷ˷̸͸͸͸̸̸̸̸ʷɶɶɶɶʷ˸˸̶ͷϹккθ̶ʴɶ˸ͺͺ˸ʷʷ̸͹˷ʶʶ̸̸˷ɵͷͷ̹̹̹̹̺̹ͺͺθ͵ͳ̲Ͱ̲ɶǶŴƵȷʹʹʹʹʹ˺˺˺̻̻̻ǴǴǴȵɶʷ˸̹̹̹̹̹̹̹̹̹͹˷ɵȲȲ˲˱ͳϲβ̯ɬħż»ýŭŮƬĪ¦ɿ¸ìͶһй̴Ȱ˳ʹε϶϶϶϶϶̲̲ɲʲʴ˵ιϺͶʱŬ|ī̵ͷɵʷ˸˷˷̶̶˴˴ηηϹϹϻϻϼϼϻɵŰŮŹvnefjtſȰʲ˳̵ϵε̲˱ʰ˴ɱūø|nea~^fuĽʭʹζͶͶͶηͷθͷ̶̶̶̶˵ʷʷ˸̹ͺ̹ʷɶʷ˸ɱȮĪǽujcgjn~ìǰʵʷ˸̹ͷ̶̵̵ʳȯǮɯͳβʯǫɹ²ýľæŪǮǱȳ̹ϼλ˵ɲĩ~bsRzkJ~oNsRzYqƾư˵˵˵̶̴ɱƬ¨¨Ƭħ|qc{WwT{ZgrªθҾӾҾнϼιͺ̹͹͹Ϲз͵ͱiuRzgFubAq^@q`D|mPkβѷԻӽҾѾξ˻ɹɷμ͹ͺ̹̺̼ͽͻ̺ǱǹbpGyf<we=q`BwgM}cƺȱɴɳǱȲʴ̴˴ǭɿĺúźķ|ia\\[^dp|ƻ¥ħæȿzna~[}Y\\eqɬɮƩè¥Īūǭʰ̴ʲƮªƿzz]zkLyiH}jI}jInN{]sƾǲ̹ϼλ̹ͺκϻ̶̹ζ͵˶ʶ˵Ƭô|bWPQ\\iȬˮcwOrH~qGsg?vjD~[üȲ˸ͺϵˬɾk}XwPxQsL]yʭԷռӼԿӿӽһҼҺиζ̴ʰʱɯƬ§ƪǩǩȪʮ˰˰̳ʹϸѼӾҿнϼҿҿҿѾѾнннϼϼϼннѾѾѾѿѿ˹ʸ˹˹˹˹˹˹˹˹ʸʸʸʸʸʸʸʸʸʸɷȶȶǵƴƴǴǴȵȵǴƳůĮůưȰʱɱɰȭǮɳǴǴǴȵɶ˸̹ʷʷʷʷʷʷʷ˷̸͸͸͸̸̸̸̸ʷɶɶȵɶʷ˸̹ʵ̵ϸѺϸ̵ǲįʴ̶ͺͺ̸˷̸͹͹͸˶˶͸͸˶ʵͷͷͷͷͷͷ̹ͷ̶̴˳ʰɯȮȫǭȳƳŲƳȵʷʷʷȵȵȵȵɶɶʷʷŰŰŰƱȳʵ˶̷͸͸͸͸̷˶ʵ˵ʶ̷̶̶̱ˮɫǪɩŦȿøĽ¨īèǽĸwmggk{ǽɯδͶ͵˳̴εзкккѸδͳʳɱɳʴ̷ιɳɰphgbdp«ȲǱʶʶ˷˷˵̶˴˴ηηϹϹϻϻϼϼ͹Ʋįĭ}ewZ~oN~qNuR}]oʰ˱ͳϵεͲ˱˰δ˱Ƭƿm]sR|oMylJ~sSfż˯˲̵Ͷηηηιι͸͸̸̸̸˷ʷʶɶ̶ͷ̶ɳȲɳ˵ɯȮ©¸sy\\zkLwhI{mPzoQ~sWlŮɴʵ˶̶̸̸̷˴Ȳȯǯʰ˯Ʃƻ{zĻťƦǪɬɮʮȯǰʷλλ˵˴ȭõbrQzkJ~oNsRyXqƾư˵ʴɳɳǯëĬªªŭʲʰĬžzg|UpL~pKvS}[sǮθҽҾҾнлϼϼϻκθ϶ǯȬŻ`{mJubAr_>q\\=r]@xeGx\\xžĪʹкҾм˸ǴǷʸ̸̶̷̹̺ͻμϽϽǱĶ~apIxe=tb<tdCxhN}cǻʳ˶ʴűůǱʲ˴˱ǮūĪȮˮɭȫƧƻ}rf^zVxT\\h}ķǺö~re}\\{X~\\bivøʰβ̲ɭȮɭȮɯʲ͵θ̶ȲĬücyjKqa@o\\;kX7vcC|kM}`wƾʵѻѽмκκλλͷ̶ҹѹιʶɳé³}cVOP[jʿvY|pHxlBwkAwkCznH_ĽƮʶλѷͮʿj{VvOxQpI}XrʭֹռѺѼҾҽҾҼйϷδȮ¨ɻ·öķøĹźƻƼêǮ̶ӾҿнҿҿҿѾѾнннϼϼϼϼϼнѾѾѿѿѿ˹ʸ̺̺̺̺̺̺̺̺ʸʸʸʸʸʸʸʸʸʸɷȶȶǵƴƴǴȵȵȵǴŲĮ¬ůŭĬĬìŭūƮȲǴƳƳǴȵʷ̹ʷʷʷʷʷʷʷ˷̸͸͸͸̸̸̸̸ʷɶɶȵɶʷ̹͸ʳ̵ϹѺй˴Űʴ̶ͺͺ̸˷̸͹Ϻ͸˶˶͸͸˶ɴͷͷͷͷͷͷͷ͵˳ʰɯǭƬĪħħžļžé«¨«ĪìĪĭūĭŮìîįŰǲɴ˶͸ιιι͸̷˶ɴɳȴ̵θѸг˭ť żɯ˰ɮƫèȽtcvYrU}rVw]g{éȱɲʲ˳͵зѻҼҼӺηͳ˳ɱȲɳ̷͸ʴʱt{_~sUrU~mOoQx[qĺìǱʶʶʶ˷˵̶˴˴ηηϹϹϻϻϼϼ˷űîìww\\{mPvhEvhCxkHuRe}ʰ˱ͳϵдγ̰˰дͰƪƿfxVxjGrdAo`?uhF}]{·ʭʯ˲Ͷηϸη͸͸͸͸̸̸˸ʷɶɵɳ˵ͷ˵ȲǱȲʴ̲ʮèi|mNj[<m^?rcDrdGshJcƿǭɲʵ˵̶̸˷̷˶ʴʱɯɭƩĹ|pnmrƻäˬ̮ͰͰͱ˯ɯǯȵλλ˵̵˰ŷ`pOwhG|mLqPxWsǱ̶ʴȲǱëſŭëëƮʲ̴ʲȬl~W~oHyjC|lHrOcv˵лѽѽѾѼѾѾмϻͷʹȰȬŻ~_zlIubAua>v_@u^?vaDpRjǮ̶˷Ʋıǵ˺˷˵̷̷ͺμϽнμů~csL{h@vd>scBwhK{`ŹȱʵɳƲűưɳ˴˴ɰǰǯ϶ѹϵϲ̯ĥørdyWqMtP}YfuuezWwVtRxVcq{ʻèʰηж̵˱˴ϵʰʰ̴Ϸѻк̶ɳƮéxwZxgIp]=iV6o\\<taCnRjùǰθӿѽϻϻλϹͷ˵зз̶ƱȺw`UMNZkĦâx]vN~rJ}qIsKwPh¥ǮȴθҵήȿgwSsMvPoI{Vnɬ׺ռиιϻлкиϵ̲̰ĶzyzyƼɳѻҿҿҿѾѾннннϼϼϼϼнѾҿѿѿоѿѿѿѿѿѿѿѿо̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹ʸʸʸɷɷȶȶȶðǴǴðŽûûĭůǴɶɶƳŲǴʷ̹ʷɶɶ˸ͺͺ͹̸̷̷˶ʶ˷̸̸Ǵʷ˸ɶƳƳǴȳ˿ɿǿȳʴ̶ѽ̸ȴϻлι˶˶̷ιι͸ʵʵʳ˴˴̵Ͷδ˱˯ȬĻƽǾ»ûƾ«ǰʳʳɲͶͶηͶ̵˴ʳ̴ɳ˵͵ͳͯȨý}ywvvǽĪ˱ͳ˰ȭǬǬĨƻ|gsVseHh]?qfJvmPv[l¨ʰ̵Ȱǯ̴ϹθθѸηδ̴ʲɳɳɵʶ˵ɰusXugJvgJtaCvcE}lNb}ǿǱ̸̸˷ʶʴ˵˵˵ййѻѻѽмϼλ˷ȴǿºt}oTwjJpb=ug@rf@ukGc}ħϴͲ˱˱ͱͱ˰ʮ̯α˯æ·iwTwgEqc@l^;m`=~qOkäɬʯ˲˲ʱʱ˵ͷκ͹̸˷˸˸̸̹ʴ˳̴͵͵˳ʲɱɭȬĩ¹|\\qbCfW6hY8fW6j]=mbD{rU}ɯ̵ηϹͷɵȴʶ̸Ϲʱǭǫʿte{YzX~\\lŸ¤ƧͰααͲββͱͳ̹λ̹˵Ͷʯõ~`qPwhGyjI|mLvUržŭʲǯĮíííĮưʴͷθ̶ʮ̿ŷz]pIzkDyjCwgCtSb}ɰѼм˸ȵ˶ϼнϻ͹̶ʹǯçxz[ykHta@q]:ybCu^?t_@{hHsUduſůưŲȵ˸Ǳʱ̵ιλͺ̺˸ȶǱǸ_pL}iD|jDrbAteHdìȳíİİůưƯȱȲʳҼӼѻҹзδ̰ʯõo`wSpMnJxT]msm}YnM{kG|iHtRap~οȫ˲͵θϷϹϷϹϷȰʲͷϹϹθ˵ɳŭūŻewfHmZ:kX8kX8jW9p_Cy_ĺȱ̶мϻммѻк̷˳θθɶîíw^{J}ISYiµ£pZ}tM{oI|pJzqJ]xſɰ͹кҵϯȿh{WsMoI~lFuQjǪѴѸѹϻѽҽҼԼҸũ·qjc|_}`{`rw}ƼưкϼҿѾѾнϼϼλλλϼннѿоϽϽоѿѿѿѿѿѿѿѿо̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹ʸʸʸɷɷɷȶȶƳȵŲŽ}ź­ŲȵȵƳŲȵ˸ɶȵǴȵʷ̸̹̹˷˶˶ʵʶʶ˷̸Ǵʷ̹ʷʷʷǴ®ºįȲʴϻ˷Ʋ͹Ϻ͸ʵʵ̷͸͸̷˶˶̵˴˴ʰɯȬçž~}ywuuvzǿƯɲʳʳ˴̵ʳȱǰɲ˴ζ͵ʰƪyppty}ǹīȮ˱˱ɰȭʯ̱˱ũøze~pSqfHmbFkbEofIzqT}bvĪìĭǯɱʴ̶ͷθζͳ˳ʲɳɳʶ˷ɳȰuoUn_Bl[=r]>r]>wdDvWs¸ʷʶʶɵɳɳʴʴ̵ͶθϹϻϻϼλ̸ʶût}oTxiJrb>wh?rd?wjGeʭϴͲ˱̲ͳͱ˰˯ʭˮɬ¥¹itQwgEscAk]:j\\9ufE~\\zžæɬ˱̲˳˳˵˵˷̸͹ͺλλϻ̶͵ζζ͵˳ɱȰʮɭǪź}]qbCfW6gX7dU4fW8hZ=vkOyǽɯ̵ηϹͷɵȴʶ̸˵Ʈ¨ǾycyUuQvR}[nǼƨʭ˯˱˱ͲʹβʹͶ̹ͺ̹ʴ̵ʯ´}{\\|mLteDvgFzkJtSpǯ̴ɱưůĮ¬ůůưɳ̶ͷ˸ʰ¢ɼhxQ~oH}kEzhD}mKxWqſ˵̷ɴɳ˶ͺͺ͹˷˵ʹȰĨx{\\{mJwdCua@ybCu^?s^?{hHqSz]enwûǿïư˲̵̵̳ͷ̹˹˹ʸʴʻapL|hCygAscBufGc¶ūȳíİİĮĮįŮưǲͷιθθθε͵̲ȭp`uRnIoKtN}Y\\{WnJzfCxfBqM~]pƹħͱ˴ͷθθθθθͷȰɱ̶θθ̶ʴȲůƮǽhzkLn^=n[;lY9kX8o^@tWxí̷λ͹̸̶ͷθͶζͷͷǴʾv]{J{JRXhǾ~fyU{qM}pMsP~Zl½ǭ˵ιйϲ̬ľfyUqLmHlGvRlǪѴзиӾҼѹʯƻya~]wXuVz]}`xµƼƭϸѾҿҿѾѾнϼϼλλϼннѿооѿѿѿѿѿооо̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹ʸʸʸʸɷɷɷȶɶȳ­|nwat\\|pX|pXw]nıǴȵŲŲǴʷǴƳŲǴɶ˸ʷʶȴɴɴɴȴɵ˷˷ɶʷʷɶ˸˸¯wh~dfkvǿĮư̸ȴıʷ˷ɵǳȴɵʶʶɵȴɵ˵˵ʱŪ¥Ǿ~|~}}}yskc^~Z|[cmzǰɲǰɲʳȱŮŮɲ̵ηɯykabkwǷȱɱȰǯŮȮ˱βеͲƫƽ{fuYlaCeZ<dY;j_AmdGxoRréȱŮĮɳ̹˵͵̲˳ɱɳʴ˷̸ʴ˳Ưx}mSiX<eR4t`?r^=vcCsUr¸ȵȵȴȴǴǴɳʴɲʳ̶ͷκκλλɵȴûqzlQufGp`<sd;l^9sfCgƿαϴʹ̳ʹ͵δͳ̲ƬǪŨ¥ƽjpOtdBrb@m]<iY8m\\>{lMevʮͱ˱ɯǯŭǱɳ̶κϻϼϻ˵̴͵͵˳ɱǯƮȯǬĨøyZn]?bQ3gV8aR3aR5cU8rgKwŻȮ̵ζθ̶ʶɶʷ̸ȲĬƿdtM|mF|mFrM\\sʮ̱ɯȱ˳ʹ̶ʹ̶Ͷʷ̹ʷɳ˴ȭ|wXxiHpa@sdCxiHsRoɱ͵˳ǱǱưĮƳŲŲƳɶʷʸʴǪâw_tP~lFygAxfBoMcƮɵǳɳɴʷʷɵȴɳ̳ɱĨw{\\|nKyfExdC{dEx`DxcFoQx\\{^{]{^~alzƮ˰˰˱ʳʴɶɷȶ˹˷;dpNzfCvd@ueCwhIe÷ƬɴĮűűðĮîîïįǱȲʶ˷̸ͷͷ͵Ͷɮĵn|[oL|hC|iA~jEmE|hCua<wa<zfCyVkŶ˽ǭε˶̹̹̹̹̹˸ʷǯɱ˵̶̸̷ʵǱĮĬŻhzkLn^=mZ:lY9lY9m\\>zkNhźʳ˵ʴȲǱƱȱʳ͵˵˵ıƾɾȼt]zIyHPVfvawWxU|Y^qĻ̯Ϸ̶̷Ͷ̯ɩ}dxTpKmHmHxTnȪѳѷиѿҿкͳŨgtRsQoMoNxYdŸƣĤȽǼŻȮϵһստԾҿҿҿҿҿҿҿҿннϼϼϼϼнноѿѿѿѿѿѿѿоѿоϽϽѿ̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹˹˹ʸʸʸɷɷɶɶƱǿsu_ocKi]EdX@gXAoaGu[xıȵǴıðıƳƳŲŲǴɶ˸ʷɵűƱƱǲǳȴʶʶʷʷƳıɶɶûux^rbHj\\Am_EsgMv^mº¬Įɵǳ¯ǴȴǳƲƲȴɵɵǳűǳɳʱŪƽyw|tj]uQukGnfBsiNyqZj~ûĭȱŮǰɲȱƯǰʳϵǯȼpbZYhuõȺʻϾıǲȯưĬĬĭǰʰ˱˰̱ȭǽ|mwlNi^@dY;j_Ah_Bf]@zpUrƿ˴ŮȲ̹ɳ̴˱ʲɱɳ˵̸͹ͷͶȲ¶znTkW<fQ4t]=t];yeDyXwȼìǲǴȴǳǴǴɳʴʳʳ̶ͷ͹͹̹̹İűƾkseJn_@iY5n\\6fV2n`=g¦ͳ϶ʹ̳ʹͷζ̵˱ƫŪ¨ç¥n}nMn^=o_=n^=k[:jY;q`BnR{^yƪǬĩé¨Ĭǯʴ˸̸˷ʶǯȰɱɱɱǯŭĬǮīɽxpSfU9\\K-eT6`O1_P3cU:ugLyƼǭ̵͵̶˵ʷʷʷ˸ȵĭǽrxT|jBwh?vhA~rL`zũ˰̳ȱɴʵ̶˸˵ʴɵȵʷȵǱɲƫztUufEn_>rcBwhGrQoɱ͵˳ǱǱưĮȵƳŲŲǵɷɷȵɯǪżlxT}kGye@xdA|iHy[wū˵ȵǲȳȵǴƲƲǱʱȰ¦twXzlIyfExeDydGydIlQ}bpphb}_dmvɹĩĪƫɯɲʴȵƴųȶɵ˼d~nLxdAtb>vfDxiHdĸǭʳůȴȴŲıîî®îǱȲɵ˷̸̸̸̶̶˴Ȯèĵ~dsR|hCyf>xe=xe=xb;v`9{e@lG`xŴƩȮƭưʵ˸˸̹̹˸˸ʷɶɱʲ̶̶͸̷ʵɴícseHhW9dT3lW8kV7kX:o^B~nTpǿưǱǱưĭìĭƮ˵̵űžƾƼr[xIxGNTfykilswɭҸк˶ɵʵ̰Ȩ{bwSpKmHmHyUpɫѳжи̺Ͻϼͷʰ¥z\\~nJpL|lH~nLyXgʿϰϱˬˮȫħȬǫɭ̲ϵҺԻԼԾнѾѾѾҿҿѾѾнϼϼϼϼнѿѿѿμϽϽооѿѿѿѿооѿоϽμо̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹˹˹˹ʸʸʸɷɶǴîƾºvs]o`IhYBbT:dT;l\\CoVuŲȵǴð¯ǴǴǴȵʷ˸ɶȴ®îįįűǳȴɵɶɶıȵ˸û~dvgJ`Q4YK.[M2bV<thP|c¬ĮȴƳıƲıðŲǴȵǴŲƲƲů}snnq|ùż¢ɿǽŻŻĺĺrbvSvmLxnS}v\\j}»ĪȮƬǭɯʰ˱˱˱ʱ˼{j|[wT{V^uŸìðóŵƳȱǳǱȲǱưŭëǭ˱δɯĽ}_rgGdY9g\\<eZ<`U7jaD~tYʳǰîȳ̹ʴ̴˱ʲɱɳ˵̸͹θ̵ưw~mSlX=iT7mV4oX6xdC{[}ĭƱǱǳǳǳȴȵʴͶͶθͷ̸˷ʷɶ®İǿhoaFj[<gU1kY3dT0l^;gũͳ϶̶˵˵̸̶˵ɱƭŪéũƩq~oNjZ9o\\<p]?n[=lX=l[?raGxiL`l~Ƹʿ¦èèƬǰɲɴɳȲưŭƬǭȮȮȮƬūĮɿkufIaP4ZI-dS7`O3aQ7gY>{mSȾƯͳ̴ʴʴʷ˸ʺʷǴîĺhpIwf;vg<th>}tMeúǬ˲ɵʸʸ˹˸ɸǴıðƳȵƳůǰĩxsTufEn_>rcBwhGsRoƿǯ˳ɱůůĮ¬ǴƳĲųǷɹɹȶɳɰtyX|jFwc@wc@zfErRpªɵȳƱǲǴŲİİůȯŭƿnqRugDvcBubAt_DycKt\\vzpjgdkzŶźȾĪȱ˵ʷȶƴñİƷ~b|lKvbAr`<ueCwhGdŹȮ̵ư̸˷ɶǴƳŲİİɲ˳˵˸̸̹˸˷Ǵɴ˵ʰϿoyX{gBwd<wa:xb;xb;wa:|fAlGe~̽γ϶ɴƳǵ˷̸̸͹͹̸˷˷̶̶͹͹ι̷˶ʵůſyvZk]@bQ3_O.hS4iT5gT6fU9m]Cu[{ſíɳ˵ȱĭ˵͸Ǵǽs[xHwEOUeĽǽƭйӽκɶʶ̷̰ɨzavRpKnImHyVrʬѳѶҹͻϿλͷʭv|UyjCmG}kGnM|[lçӷպҶԸѵβӹѷѷѷҷҷԸӸӺѻнѾҿҿҿҿѾнϼϼϼнооѿμμϽϽоѿѿѿѿѿооѿоϽϽϽ̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹̺˹˹˹ʸʸʸʷǴîǿǿɾ{s]qbKiZCfV=iY@o_FoVuɾðǴǴðƿƿȵȵȵɶʷʷǴűĿ­ïűǳɵŲȵŲðɶ̹º~nTkZ<YJ-VG*WG-\\N3maGx_ůůɶȵ¯ððððıǴȵƳŲɵíønb~Z\\csǾæƪŧåȪǩĦȽwqlr|žūǭǭǭȮ˱ͳʰ¨ĺ|fwVoMqL~WhͿĪıƶƹȹʷ˶̷͸͹̶ȲůĬǰ̲̲ƬĽswTf[;^S3]R4\\Q3cZ=pgJpǿǰǲɴ̶̹͵̲˳ɱɳʴ˷̸ʵȲ¬t~jQmX=kS7mU3pX4{dB_ȺūɯįůűűƲǳǴɳιηθͷ˷ɵȵǴİǳ­ļhoaFj[<hU4o]7kX7pa@kǬϷϹͷ˷ʶʶʶǴưůƭĬǭŪ´spRmZ<n[;n[=n[=nZ?p\\AraGudHuT~[iwʼçǫǬȯɲȱǲŰŭūƬȮɯȮȮƬūʿxu\\l\\B`O5^M1dS7`O3bR8jZApYʿǰͳ˱ɳɳʷ˸ʺʷŴʿ_{iCub8uf;ri>wPjǾȭɳǵɹʺʺʺǷŴǾóƳıíŮ§vtUufEn_>rcBwhGrQožŭʲǯĮí¬ŲıĲųȸɹɹȸɶɴí{xZzgFxdAyb@ybBkLjοưïŰƱǴŲİïíŬëügzkLoa>q^=r_?oYAxdL}eŵɹ´zma`ht~ǯʴɷȶôz^yiHt`?p^:scAufEbźɯͶȲϻκ˸ɶȵǴƲƲ˵̵̷ͷͺ̹˸ʷȶɶ̷˵¨u}]vb=r_7r\\5u_8u_8t^7wa<zfCe|ɺ̲л̹ȸȸ˷˷̸͹κκ͹͹ͷͷκ͹ι̷˶˶ư¾owlPeW:_P1_O.dQ1gS2fS3aP2cT7ocI|dzĮ˵ʳƯ©˵͸ɶñðɾrYvFvF~NUeĿ»Ƽ¥ĪƬ̳ϸѼѽͺ˸ͻϺͱɨy`uQnIkGkFyVtʭѳӸԻѾθˮu|Sxi@}kE}kEqM}\\iѷһϵйѷϵջֻּպԸӷӷӷҹӽҿҿѾнϼϼϼнѿѿѿϽϽоооооѿѿѿѿоѿооо̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹̺̺˹˹˹ʸʸʷʷƱ¬íwymUj[DdU>eU<jZAr`HmUsźŲƳð¯ɶȵȵȵɶǴð½®İǳȴıʷ˸ƳȵŲwo_EaP2XG)YJ-XH.YK0i]Cw^ºɳȲ˸ʷðð¯¯ðŲǴȵƳŲïr~avW}tS~vR^i~ƩƫƫǭūĪééĪƬǭ¨¨ʾŹ»éǭɯɯƬƬʰͳūt{bmR{kJ}jIsObyʽũĬ±ŷȿɿͽ͹͹ιϺιʵůííĮƮǯŭžkxkIdW7[P2[P2_V9e\\?}sZuĭʵɶ˸ιζͳ̳˲ɳɳʶ˷ȳǱ¬t~jQlW<jR6oW5pX4zcA~]ɺūɯ¬®®ïİıưʵ˴˵˵ʶȴǴƳïǳįŽgm_DhY:hU4sa;r_>ufEmȯζϹ͹ʷɶɶǴĲ®ĮƭŭǭèrpRp]?mZ<kV;nY>uaH~jQrZw\\}]\\afqƸĩééī¬¬«ūƬƬƬĪ¨ľ{ybrbIbR8_N4cR8eT:_N4^N5fV=|mVʿǰ̲ʰȲȲʷ̹ʺɶƵȽz{Ywe=r_4se8qj@~yQmʰ˶ɶǷȺȻȻƹĴǾ²ıðĭutUufEn_>qbAvgFqPmĽŭʲǯííƿ°°óƶɹʺȻǹ˹ʶİ}x[|gH|eE|dBybBjKgξîïŰǴǴűï¬êëcufGk]:n[:o\\<nZA|gRpϿŪ¥ķ~pifhlwųȶ°®³}w[vfEq]<n\\8p`>sdC`źɯηʴϻκ̺ʸɶȵǵǳʴʴ̷ͷ̹̹˺ʹ̼ʸȳĮɺqxZwc@q^6o\\4q^6t^7s]6t^9vb?}\\sê̹ͺ˼ʹʶ˵̶θϹϹккͷͷι͸˸ʷɶʵí|alaE_Q4]N/aQ0cP0gS2gT4bQ3_P3eY?vjRycǿĭĭêĭɲ̷ʷųŲɾoXtDuE~NUfũǭȮɭɰʯ̳εεͶ̷̸̹̻˼̸̰ȧw]pMkFhDiDyVtˮҴԹֽҿϹͰŤ}`sHqIoIsO|[cíưȰɱҹռԻԸӷҶҶҶѸտҿѾнϼϼϼѿѿѿѿѿооооѿѿѿѿѿѿѿѿ̺̺̺̺̺̺̺̺̺̺˹˹˹˹˹˹˹˹̺̺̺˹˹ʸʸʷλȳìííqqeMbS<]N7`P7iY@q_G}kSpü¯ŲıðıŲɶȵȴǴǴưľ­ıƳȵŲλϼȵïźwadT:[J.WF*[L/ZJ0XJ0g[Au\\ļ̶ɶ͹˸ıï¯íðŰȳȳǲŰƺuw[tiKtiIzrNxSgvɪˮʱʱůĮí¬íůȲʴǱǱǱǱůĮ¬üƬɯʰ˱ƬĪȬ˱ɿxu[{gNs_DwdF~kKyXrʽǫʲűŻξ̹ɶʷ˷˷ȴűưíſſžźaqdDcU8]R4]R6\\P6pdL}d˶ȳʷѻϷζ̴˲ɳɳɵʶ˵ʳůwmRlX=gR3kT2jS1q]:uTxʾ¨ſſĿĿ¬­îǰǰȱɱɳȲǱưĭìƼ~cj\\AeV7gT3uc?scAwhGoǭ̶м͹ʷȵǴű°ƿĭƭǮƬqpRq^@kX:gT6mY>ziM{apslf`]boͿ̾ɾɽȾȾɿɿĨŧħåkxiRdT;YI/]L2eT8eT:]L2[K1aQ8whQ˿ȱ̴˲Ǳȴ˷̹ʸȶɶɾvyXwe=r_5sd9qhA~ySn¥˱̵ʷŵƶȺɻȺĴı®ĪrtQugBm_:pb?tfC~pMjžūʰǯĮí¯ƿóǷʺ˻ɹǷ̺˶Ű|yY{hH~gG~gE{dDkLjį˾®ŲȵȵƲï®ĬbsdEiZ9lY8mZ:r^EnVuƬʰȮȬŧ˽zrjghnvǿİưĬõ{uYscBn[:mZ9m^=pcA_ĺɯкʴκκ˹ʷɶɶȶȴɴʵ˵̸̸̹˸˸ϼʷĭȾgoOzhDtb<p^8r^9s_:t^9v_=wcBrSgĸŰʶ˸ʷɵʴ̶θкѻѻѻ̹̹˸˸ʷɶȴǳý{|rYcW=WL0ZL1_Q4`O1dS5fU7cR6_O5cU;oaGxlTgwŻɿèǭǰ˶ʷƴƳɾlWtDuE~NVgǭʰδδ̲˱˲ϵɳȱǱƳʷ˸ɸǲ̰Ǧu|ZnKiD}gB|hCyUu̮ӷպонϹϵʫǽtY{TuOvR{W{ZsĬϴҹѶѶеѵҶҶҹҿѾнϼϼϼѿѿооϽоѾҿҿҿѿѿѿѿѿ˹˹˹˹˹˹˹˹˹˹˹˹˹˹˹˹˹ʸͻͻͻ̺̺˹˹˸ǴǱʴȳxi^H[O7ZK4]M6bR;eS;n\\DyaǴȷɷǸȸ̺˹ȵűíǿǽĽſƴȶɷƵʷʷ{do_FN>%P@'UE,WI/TE.VG0i]Ev`ǿͺ˸̸ȴ®ĮĬªʲɲ²zsVqbCl_=pc@}sO_kťʮ˱ɴͷʷʷ˸̹̹ͺͺͺƳŲǴʷͺͺȵůƾƾſ¨ƫɮ˰ȫɬʮˮŪ}el[AjY?iX>n]C}lRl¯ĲĴŹĺż̼̺̺̺˸˸ʷʷ̶ɴŰ­ǿǿǿȿzqTfX=aS8TF,WI/^O8ufOxø̵ʳ˵Ϸθ̶ʴɳȴɵʶʶ̶ʳĮ´zqUmZ<dQ1cP0bO/eU4ufG`{ĽƿɿɿīƫƫũƿĩƺźƻõxYm^?dU4jW7r_?p_A{lOx«ɳ͹̸ʶȴƳǱǴȲʳεȭ¦ʿivUo\\<mZ:hX7n_@uXvwi`^gr{ĹʿɾƻúĠ {k|mVm_EgW=eV9dS7bQ3^M1ZI-[L/cS9|nTì̶̵˶˷̸˸ɶƲ;noNwc>wa:tb<uhFwVqʯʱưǲɴʷ˸ʷȵƳĲĳǴư¨¥Že|oCob6i\\0m`6rf>|pHe½æɬʯǮí®ðǷŵĴŵɶ̹ͺιѺϵƫy~[~nL~lHzfE|hGsVtĴĴƵȶɷɶȵƳűĮ|`paDgX7lY8n[;uaFsZy¨ĬĮưεɰªɽĶtrc{^ftƸʻƷxqSn^=iY8iY8hY:n`CeøǲѻκҿҿѽмͺʴƱů̷ȴȴιϺ˶˴Ϲ˳ɯĨƸcpM|jFxjEwiDvhCvfBvcBua@vaBydExcFrWpūʲɱɳʴ̶θлҽӾӾ̽ʼɹǵŲ­ʿppeO[Q8UK2WP6]S:YO4^S7`R7]O4_O6fV=n\\Dp_E~mStZj~ŤƦǮʵȵųƳɾl}TtEuFzK{Rg´Ȯɱ˳̴ζζͶζȱȰƮůůưȲʱǪƦn~]nL|d@}gB{lEzTu½ѴҶηлϾѾθǰ§ɾ{i^\\`acuzüǫαϵжҸӹӹҸжϷӽҿѾнѾҿҿҿҿѾнϼϽоѿѿѿѿѿϼкϼѻҼӽտҿҿҿҿҿҿҿҿҿоооѿѿѿ˹˹˹˹˹˹˹˹˹˹̺̺̺̺˹˹˹˹ͻͻͻ̺̺˹˹˸ȵǱʴȲǿxj_I\\P8WK3ZJ3]M6_M5dR:zhPkĽƳŴ³ŵȺǷǵŴűůì©©ľñƶȶƵʷŲfvbJ_N4P>(O?(SD-UF/QB-QE/g[Et^ƾ̹ʷ˷ǳŬŬ¨ʰȮgxhGiY8fX5k^;{oIZvǧǪʰʲƳɶ˷̸λϻнϻͺ̸ǴƲƳȴʷ˷ȵŲ§Ūɭ̰ˮʭȫƩƻj|nSjY=fU9eT:n]CsZyƹñĴƷŹźƻǾʿʻʹɸɶɶɶɶɴʵȳŰ«Ⱦ~bjZ@_O5SC*ZJ1[K4l]FkíȰȰʹʵɴɳɳɵɵɵɵ̶˴Ǳ÷|sTmZ<eR2cR4_P1`S3j_?uWn¶ùĺĺúqpQj[<dU4jW7p`?q`D|nS{¸Ű˵͹̸ʶȴǱǱǲɳʱβǬǼa}mLq^>m]<l\\;reC|_~|qijlo|źĹ·ûþxpriu[ykPscIk\\?cR4\\K-^M/\\K-]N1dU8zlR©Ůͷ͸̷̸̹̹ȴưͽilKt`=u_:tb>rcB~sUnƽǬǬŬǰȱɴ˵ʷɶȵȵĳƳů¨¢Ž~c~qDre8l_2pc7rf<|pHgǨ̯ͲʱưŲƳĴĴŵɶ̹͹˷̴չҳǨv|X{mH{iEzfE}hIwZxŵ´ƵƵȶɷʷȵǴűız^n_BfW6kX8n[;wdFvZ{´«ŭİƲ̷ɴűïŹwewXxY`lyŵooNk[:eU4dU6iZ=pbGhźʴѾϻѾѾмκ̶ʴǰǱ̸ȳȳͷ͸ʳɰ˱ͱŨŸnySjEzhB{oI{qMsPtSrQlL{hJzeHu`E~jO|buèʰȰʴͷϹлϺϺϺʿɽǹƶĳ°ʾ|dj_IYN8SK4VN9YQ:YR8\\R7[O5WI/XH/_N4hT;jV;uaF~kMz\\jzļƣειɶŲƱ˿i{RrCrDxJ{RhĶʱ˳̴͵ζζζ͵˳ɱǯŭĬëĬĪǨƣm~^qMiEmE}mIzVr̮ʹ̶нξξϿнͺʵƯèƺ~|{{|æ˯дϳдҸӹӹҸжηӽҿҿҿѾнѾҿҿҿҿѾнϼϽоѿѿѿѿѿѻѻкѻѹӻԼսҿ˹˹˹˹˹˹˹˹˹˹̺̺̺̺ͻͻͻͻͻͻͻ̺̺˹˹˸ʷȲɳưƾyk`J_S;YM5YI2[K4\\J2]K3iW?wgNiþôŶǵƵƲưĭĭìýƴɷŴıxcn^E_K3SB(TB,SC,TE.UF/PA,PD.fZD~s]ƾ˸ȵʶƲ¬©ƭŬ¨ɯūpuWm]<cS2bT1i\\9zmJ[ͭɭʰɱıƳȵ˵̹Ϲλθ˸ʴ˸ʴȵɳɶ˵ʷʴĭ«ſĩɭ˯̯ʭƩytYl^AgV8bR1aP2n]?x[zŬưɴɶȵȶɹ˹˺˸ɶȵǴȳɴʵǲƯĭéɿǾøqp`F]M3RB)]M4XH1cT=s\\źŭǯ˲ƱƱȲɳɵɵȴȴʴ̵ʴƺ}rSlY;dQ1cR4_P3^P3f[={pRi}~wdtfIfW:eV7gT4m]<o^B|nS}ĺǲ̶͹̸ʶȴǱȲȳɳȯ̰Ūƿ·{tVscBp]=l\\;l\\;tgEdƽǧàɿ~vomu{|tngamliew]whKeT6WF(_N0^M/`Q4eV9ykQǰͷ͸̸̸̹̹ɵǱįξkkLr^;s_:uc?pa@|oOg·çŪīǰǰɳɳȵɵɶɶĳǴű¨¢ļd~qEsf:na5ob6pc9zlEhǪ̱γ˲ǱƳǴðıǴʷ͹̶ɳǮԶήáqyV{kG{iEzfElM~cò²ƶõƵȵɷɷʷȵǴƲıvZl]@eV5kX8n[;yfHx\\~ĶĭƮűǲʷɶɴɵʴư˿Źq|]uVwX`jr||f}mLk[:eU4cT5k\\?qcHiǼ˵ҿϻнϼκ̸˵ʴȱɳ˶ǲǲ˶̷ʳɰȮʭƻp}[nHiDmGwT\\eljbtVlNwcHyeJ~mQ{^r¹ũŭȲ̶̶˵ɳɴɴɽȹĴıı®̽s~pVeYAZN6WM4XM7YN8\\R9[Q6VJ0RD)UE+_N4hT;kW<r^CyfHoQxWarϴϸʶŲƱɽeyPoAqCxJ{Rhŷ˲̴͵ζζζ͵̴͵˳ȰŭªǨŢl~^tPlHqIpL{Wqǩʱ˵ѽϼϼϼϻκ̶ʳɮȭƨã;˼ɻɹƹǾĽĽƿæȫβѵдѵҸӹһѺйϸӽҿҿѾннѾҿҿҿҿѾнϼϽоѿѿѿѿѿѿҼҼѻѻѹѹҺӻҿ˹˹˹˹˹˹˹˹˹˹̺ͻͻͻͻμμμͻͻͻ̺̺˹˹˸˸ɳɳưŽylaKcW?\\P8\\L5^N7`N6`N6dR:iY@xlRi˼˹ʹɶƲíſ¾ïȴʷ}gm^G\\L3WF,VE+YI2XH1YJ3XI2SD/SG1h\\Fu_ǿ˸ɶʶǳ¬í©ƭƭéȮenPjZ9cS2dV3j]:{nK]¡̬ǫɯȰĮưưǯȰɱʲ˳˳˳͵͵˳˳˳ʲʲɱƯìľÿ§Ȭ˯ʭȫŨƿq{mRhZ=cS1aQ-bR0l\\:qPmǼŦǪɭɭȮǭȰʲ̷ʵȵǲƱǲɴʳȱɯȮƬūç¨ƽǾǼvueKaQ7UE,_O6XH1\\M6ufOzƮɱ̳îįǱȲɵɵȴǳǱ˴ʴŹ{~oPiV8aQ0`O3^O2bT7odF|^w|u|aqcFdT:cT7`O1hX7jY=xjO{ĺƱʴ͹̸ʶȴȲȲȳʴƭʮèžt}lNm]<lY9hX7hX7reCcƽŨŧĤǼ~|{xsljiihty}~rwZl[?ZI+_N0_N0bS6eW<xjP©ɲθι̸͹ͺ̹ɵǳǲopPt`?t`=xfBpa@{nLa|ũŪɯǰǱưƲƲǴǴƵȵǳë¥Žg{nDre;m`6m`6l^7vhCgŨ˰̳ɳƲűŲŲŲƲɵ˵̳ɰǬ̭ţjwR{lE~jElKuVnɸŴǹŷƵȵɷʸʷɶǴƲư}}rViZ=dU4kX7n[;{hJ{_ǹƯȲƲǲʷʷʵ̷̶ɳŭŷueabdekli}\\zjIl\\;gW6eV7j[>qcHjǼ˵Ѿκϼλ̸ʶʴʴʳ̴ʳȱȱ˴ͷʹɯƪʿs^rN}kGnIwSbrzkw\\mR{gLwfJ~mQ{auùůȲǱůíİƱ˺ɸƳıŰ¬̽ʺz}drbIcS:^O8]N7]N9[O7\\P6ZO3WI.VF,`O5o^B|hMlN}jL~kM{kJ{kJrOa{ưɶǲİŹexPoAqCwIzQi´Ȯɱʲ̴͵͵͵͵͵˳ȰŭëªªéǨàh|\\sOmIqItP[tɫ˲̶ѽѼлϺη̶̳˱˱ɭˮ̮˫ǧťţǧˬʭȫƩǪʭβдѵѵҸӹһѺййѾҿҿҿҿѾнϼѾҿҿҿҿѾнϼϽоѿѿооѿѿѿҿҿӽӽҼѻиииѹҿ˹˹˹˹˹˹˹˹˹˹̺̺̺ͻͻμμμͻͻͻ̺̺˹˹˸̹ɳʴưŽxk`JbV>]Q9]M6`P9eS;eS;fT<fV=n`FymSg|ĿƳ̻̻˺ʷǴïĿ½þǲ˶ǳknbL]N7VF-XG-\\K1ZJ3ZJ3[L5[L5UF1SG1h\\Fu_ͺʷ˷ȴïůĮêǮǮéƬü|^{jLjZ9eU4eV5j];zmK\\¹ãƿéĬí¨¨ūȮʰȮȮɯɯȮǭǭǭǰĭľÿ§ǫʮȫƩħƿjtfKdW7aQ-cT-fV2iY5qc>zTtƾáĢã¢ãĦǭŮįì«ìĭūɯɭɭǫũ¥ƿĽnvfLgW=YI0_O6WG0WH1m^GrƮɱ˲­įưȲɵȴǳǳĮɲȲtwhIfS5aQ0^M1_P3hZ=|qSs¥¥¥ɿȾǿŽŽǿźitfKcU;bR8^M/eU4fU9ugLzĺƱʴ͹̸ʶɵȲɳɴ˵Ŭǫ§ĽpziKl\\;kX8fV5fV5pcAcú¥ĪūƪĨƻwojdbekszfudHbQ5_N2`O3cS9fX=zlRêʳͷͶ˷̸̹̹ɷǳƱοxvXvcBsa=xfBtdB|nK]tƻĨǬȮƯưĮïðòòȷʷɵŭĨƽj{mFsd=n_8n^:l^9vhEhƿĪʲ˳ɳŲııǴŲůŭǭɬɬȪťu`sL}kEkFwVd;ƵǹǸǶȵɶʷ˸ɶȴǳưy{pRhY:dU4kX7n[;ziK|`ɻȱɳǳȳʷʷʵ˶˵ʴȰƬ˯ʿvmcxYz[yZuWnPtdCk[:hX7gX9iZ=qcHiƻʴϼ̸ϼλ̸˷ʴ˵˴͵ʱʱʱͲϵβȫ{evTmImItO~ZvĹovZ}lPveIyhLsVezüĬŭªêưʴκ˶ȴȲȮ§ǹi}lRgV<_N4_M5_M5^N7_O8]O4\\N1[M0aR5sbFx\\ijxZqQxhGscBxjGzWjyȲɴïĸj{SqCrDwIxOf¨ëƮȰ˳̴͵ζ̴ʲȰǯƮƮǯǭȩbwWpLjFoGwS_zв϶θҽҺѹϷͳʱʱʯɯȫʮ̯ˮƪŧɫ̮Ѵϲ̯ʭʮ̰βдҸҸѺһһѺѺѺѾѾҿҿѾѾнϼѾҿҿҿҿѾнϼϽоѿѿоооѿѿѿҿҿӽӽѻкиϷииҿҿҿҿҿҿҿҿҿ˹˹˹˹˹˹˹˹˹˹˹˹˹̺ͻμμμͻͻͻ̺̺˹˹˸˸ɳʴǱƾwi^H^R:[O7\\L5^N7cQ9fT<fT<eS;fV<j\\AwiN~d¬ʶƳǶȷɸǴŲ¯Ŀ½¬ɳűushR\\R9SG-SE+WG-ZJ0XH1XH1ZK4[L5UF1SG1fZD}r\\­λʷ̸ɵİưůīǮȯĪūtVudFgW6dT3cT3fY7tgEvVuĺĽŻžȾæŪɭƬìſèǫʮɬǪŨž}ak]B_R2`P,eV/gX1eV/gY4wkEbzƿƾƾƾŽžĽĽƿƿžü|x\\o_EhX>[K2_O6VF/UF/iZCoŭȰȯŰŰǱȲȴȴǳǳĮȱůlpaBdQ3bQ3_P3`R5l^Az\\ĦåƩƩƩƩĪĪê¬įįįƱƲưíȼ÷v{mSeV?`P6_N0eU4dS7seJyĺȳ̶̸˷ʶɵɳʴʵ̶ƭǫĽlwfHm]<lY9gW6fV5reCeż¦ȯǱǯǯƮëȼźø·}sjdciq|¸ǻ¶kxgKeT8^M1]N1bR8gY>{oUīɲ̶̵ʶ˷˸˸ɶƲ̽²b{hHs`?vd@xfB|lHxTiͿƪŪƬŭůİð±±ȷʷȵĭ§ǼkoKtd@o_;p`>pb?zkJmƬ˳ͷʴƳŲƳȵǱĬéƩǩǩȥ{h}VoIkFnKew˻ðƶƺǸǶɶʷʷ˸ʷȴǱůx{pRiZ;eV5kX7mZ:yhJ{aʼʴʴɴɴɶɶ˸̷̸ͷͷ͵ж˯˿zfrUsV|mNwfHsbDm]<gW6fV5hW9iZ=qcHjǼɳλ˷ϼϼκ͹̶̶˴˴Ȱɯ˱̰βˮɾzizXpNnJsO}Yf¥ĩ¦gtX{jN{jNpSwZhzŭŭƮʴθζ˴ɳʲǬȽsXr^C`L3^J1`L4_K3`K6aO7`P6^P3aR5l]@rVnxy`uUzjIvfE{mJwT\\cyļ¬ŷl|QrDsBvHwPeŽëƮɱ̴͵ζʲɱȰǯǯȰʲ˱Ǩÿ~]tTnJiEnFyUb~âԶҹθйѷѴϵͳʱɰʮɮ̯ͰͰʮȬȭ̱еԷҵϲͰ̰βѵӷӹӹһһһһһҽѾѾѾѾѾнϼϼѾҿҿҿҿѾнϼϽоѿѿϽоооѿѿѿѿѿѿѿѿѿѿѾѾӽҼѻкϷϷϷиннннннннҿ˹˹˹˹˹˹˹˹˹˹ɷʸʸ˹̺ͻͻμͻͻͻ̺̺˹˹˸ʷɳ˵Ȳǿvh]G]Q9[O7[K4ZJ3^L4aO7cQ9bQ7aP4aR5hY<ykPkľðƳǴȷƵò¯ýľ¼ªƮv~w]g]DYO4UI/UG,VH-ZJ0VF/XH1\\M6^O8XI4UI3g[E|q[­ͺɶ˷ȴİưưīǮȯĪĪ~|lKn^=cR4`O1_P1`S3m`@{pRmƻħĪ«§ĩǫɭʭǪƩƿz^i[@_Q4aQ/dT0eU1cS/eW4uhEaw»üžžžü|~qhqfJcS9cS9ZJ1_O6XH1XI2m^GsǯɱɰȳǲȲǱǳǳǳȴưɲĮfl]>cP2fU7cT7`R7k]B|`ȫæŨŨƫƫūūĭĭŲƳȵȵȵȳȴʶ˷ůʾ}qYgXCaQ8`O1cS2aP4oaFu¸Ʊ˵̸˷ʶɵɳʴ˶ͷȯǫ»htcEl\\;kX8fV5fV5sfDhȿĨǳȶɵɵȲǱưƭƭèż{vx~ĶǿéêĸgsdG`Q4\\M0[L/`P6hZ?sYůɱ˵˴ɳʴʷʷȵű̿˿ȺrrQueDwdCvd>zhBpJ[rƹ§ĪŭǱǳȳƳŲƳɶƳ«źjoNscAm];qa@tdC}nOlƿŭ˵̶ɳưıŲǱƮūƩǩǧƣßn]yQqLtO{XuɷįǶƶŹȻȵɴʷ˸˷ʶȴǱůx|qSk\\=gX7lY8lY8wfJz`ʼ˵˵ɴʷʸ˸̷̸̶̹θз˲̱ʱĸyby\\|mPraCn]?mZ:hU5hU5jY;j[>rdIlȽ˵ϼ˷ннммϹͷ˴ʳƬɭʮɬȪ|g|XoKnJuS_n{§Ȯͱ§~my\\tWoQnPwYjĪƬƬȰ˳ȯɭɮʭŨnmOnY<`K0aL1dN6bL4dN7iU<dU8dU6fW8rcDxZnvsf}_wVvUzY^_`i|¶fzOpBrAuGwPeƾëǯɱ˳͵͵ʲɱǯƮǯȰɱʰŦz|ZrRnJkGpHzVb}Ҵз̶ϸϳбϲϲβͱͱͱѵеϴ̲˱̲ϵҸԸҶϳͱͱβѷӹӹӹһѺѼҽҽҽнѾѾѾѾнϼλѾҿҿҿҿѾнϼϽоѿѿϽϽоооѿѿѿѿѿѿѿѿѿѾѾҼѻкϹϷϷииннннннннҿ˹˹˹˹˹˹˹˹˹˹ȶɷɷʸ˹̺ͻͻͻͻͻ̺̺˹˹˸ɶɳ̶ɳvf[E^R:]Q9\\L5XH1ZH0^L4`N6`O5^M1^M/bS6o`CtYr¯űǴǴŴñ¼¼é{asiNcY>\\R7ZO3VK/XJ/\\N3WG0ZJ3_P9bS<\\M8XL6i]G~s]˸ȵɵǳïůưīȯɰĪé{vfEjZ9`O1_N0]N/^P3k]@xmQj}|~~{uokfffgmzèŪȬɭɬǪǪ¥|`l^CdV9bQ3bR1aQ0aQ0hY8zmKfy¾»Ľž»Ľü»{ugy]f[?YI/\\L2WG._O6\\L5]N7sdMxø˳̴̳ʵɴȲǱƲƲǳȴȲʳí|biZ;dQ3iX:eV9`R7g\\@|_ƨˮŨħŨŪŪūūŮŰıƵʷɶǴȵ˹ϻӿ̸í~r\\gXCbR9^M1aQ0\\K/j\\ApîȲ̸˷ʶɵɳ˵˶ͷʱȬdp_AjZ9iV6dT3eU4reCiƬƴƶǷʸʸʶȴȲưŬīƫȭƩǾ´ʼƩ«Ůīù}bm]CZK.[L/ZK.^P5g[Aw^ǰȰʴʳȲɳɶɶǴŲ®¬ŷ~{\\zkLyiGuc=wd<|jDxQgȽʿūɱ˵̷˶ʵŲǳůȾŷi}lNp`?jZ9n^=tcE~mOlüªȰɳưí¬íŭūǪȪɩȥğwdWxPwR\\hʵʸƷƹȻȵɴʷ˸˷ʶȴǱŭx}rTl]>hZ7lZ6lY8veIy_ȼ˵͸ʷʷͻͻͺ̹ʵɵʴ˵íɳ̶˲ǯɽxgsVtcGo^@n[=jW7jW7l[=l]@tfKmʿ̶н̸ѾѾҾҾкθ˴ʰũɬɬŧãȹm|XqM{iE~nL|Znȯж˱ǽm|_rUziKnP{^n¨ƬĪ«ĬũħƩǪt~`kNoZ=fN4fQ6iS;fP8iS<o[BjY=hY:iZ;sdEwXilejhggkjjh~akxy[xMn@p?uGwPfëŭȰʲ˳̴̴ʲȰǯƮŭƮǯȮäwzXrRpLmItLzVa{ΰʹʴη̰ίбѲддддҶѵεεε϶ϷϷӹѵβ̰˯ͱϵѷԺӹһѺѼҽҽӾнѾѾѾѾнϼλѾҿҿҿҿѾнϼϽоѿѿϽϽϽооѿѿѿѿѿѿѿѿѿѾѾѻккϹϷииѹннннннннҿʸʸͻͻͻͻͻͻͻͻɷʸ˹˹̺ͻμμμμͻ̺̺˹ʸʷʷ˵̶ưƾxeZD]Q9WK3WG0YI2\\J2\\J2_M5cR8cR6eT6gV8hY<o`C}oThw¼İŲıĲð½žƿn|rWk`DbW;cX<i^BujNynRn`EbR;ZJ3YJ3^O8ZK6TH2i]G{e̹ǴȴƲïǱưŬȯǮéĪrtdChX7_N0^M/ZK.YK.m_Dx^xwrn}_tVy[epĻȾƾèĩƪǫƩħƩæ}ai[@]O4bQ5`O3]L2_N4n^D|a~úĻĽŧƨŧĦ¨ūǭǫƪũĨħž»y|`i^BYI/XH.\\L3^N5WG0^O8yjS}øʲ̴ʹɴȳȲǱǳǳǳȴ˵ƯísYhY:ZG)dS5`Q4]O4i^BgŨʭȫǫǫŬŬŭŭŮƱŲƴȶɷɸɶȵǴʶϻǳ}q[`T>_Q7`O3]M,bQ5k]BrƼ­ͷ˷˷ʶʶʴ˵˶̶ǮʮĩĽdp_AiY8gT4hX7eU4reCoǾǭʷɸȷȷȷɶɶɴƯǭǭǫƪũĨæȽȽȽɾçƪȬįĺy^k[A`P6]M3ZJ0_Q7j^Dx_Ưʴ϶ε˵ʴȵɶʷʷű˿ȼv|\\qPmG{iA}kEuN^oŻƬ͵ζͷʴɳ¬íì©ƸmpRwdFr_AubDtcEziKg¨̲ʳŮìììçǪ˩ǣ¼zdzT{UZbo~ĳ̼ǲ˸ɹǸǺɼʷɴʴɳɵʶ˵˵ës~sSo`?i[8lZ6n[:tcG{aǻɳ͸̹ʸͺͺ̷̺̹˶ȴȴɴɴɴ˴Ȳ©¶~h|kOkZ<iV8kX:lY9iX:j[>xjOnůкͺ͹ннмκ̶̶˴ͳɮȫũƷsetPsOuS|Ziȿÿì˴з͵ʰĽo|buXpT~oR{`nŻ¨ɬɬʬǧĻfqP|gHt_BnY>q\\A|fNpWrZpXpT|mNxkKzmMsV}`inrzunjjr|}n^uKtFq@oAuNfõĭȰʲʲȰȰʲ͵̴˳ɱƮĬëª¨txVqQoKlHrJuQa~¿̮ɰȲ̵ͱϰбѲѵдϳβжϵ̵˴̵ηϹѻѷдβ̰̲δϸйӼһҽѼѼлллннннннннѾҿҿҿҿѾнϼμμоѿѿѿѿѿооѿѿѿооооооннкккѻѹҺҺҺннѾѾҿҿѾѾ˹ʸͻͻͻͻͻͻͻͻʸʸ˹̺ͻͻμμμμͻ̺̺˹ʸʷ˸˵̶ưŽwcXB]Q9XL4XH1YI2\\J2_M5hV>q`FsbFp_AjY;dS5cT7n_BqTd}ƲŲ¯¿ý¼üĽpy[ujNf[=dY=mbF{pThn~bk\\E_O8XI2ZK4VG2RF0h\\F{e̹ǴȴƲïǱưŬȯƭ¨éqo_>eU4_N0_N0[L/]O4tfLhŽº¹úĹ{kdentèŪǫȬˮǪƩ|`i[@]O4eT:`N6]K3dR:yiPp÷©ĪƬȮȮǭƬƬǭɯʰ˱ʮʮɭʮȫƩħæ¢ſýoshL_O5YI/ZJ1ZJ1TD-^O8|mVźʲ̴̳ɴȳɳȲǳǳȴȴɳĭ¬qWgX9YF(bQ3^O2ZO3i`ChƩˮɫǫǫƭƭŭƮƯȲǴȶɷ˹ʹ˸ɶɶƲ̸İ|pZ`T>_Q7cR6aQ0fU9m_DsƼ̶̸˷˷ʶʴ˵ʵ̶Ǯʮè»`m\\>gW6fS3gW6fV5sfDpȿȮʷɸȷȷǶȵǴǲƱƯǰȮǭǫƬũħ¤¦çũǫȮʰǲîĺx^j\\AaQ7]M3YK0]Q7j^Dx_ǲ̶зε˵ɳǴȵɶʷĲ®íë÷k~\\qM|mD}kErKzUbp~ǫɯǭŭĬëĭƭūɻrlNs`BmZ<p]?n]?raCy[zƿ˯ͳʰȱȱȮūçæťţſn^wS}YenʺǴ̺˺ɺȽɼɶɴɳɳɵʴ˵̳Ƭs}rRn_>gY4kY5jZ8qbEy_¶ű̷ͻͻͺͺ̺˹˸ʵɵʵнλ̹˶ɴĮǼ÷|z^tcGkX:hU7hU5fU7hY<vhMlíͷ˸˷ͺͺ͹̸̶̶̵δ̱ɬ¤Ÿwe[yUzV~\\gyĻĨĭʳͶ̳ɱér}cqWzjPykPw[mɿǬ˰ʭʬɩw|[zjIzgGvcEwcHlS|cpvsgb}`}`dkqv}tjhjg}]xRsHsErApBwPg³ĭǯɱɱȰȰʲ̴̴˳ɱƮĬªz~\\tToKjFnFpL^|˭ʱȲ̵ͱϰѲӴѵдβ̰δͳ̵̵ͶϸлѻҸдϳͱͳϵϸѺһһѼѼѼлллннннннннѾѾҿҿѾѾнϼμϽооѿѿѿооооѿѿѿооооооннкккѻѹҺҺҺѾҿҿҿѾѾ˹˹ͻͻͻͻͻͻͻͻ˹˹˹̺ͻͻμμμμͻ̺̺˹ʸʷʷʴʴĮļvdYC]Q9YM5YI2YI2\\J2eS;weMv^~dx[yjMk\\?dS5hW9tcE}nQsYg~ſűïýŽǽvz\\viIm_BdW7h]?|qSj{rcLaQ:VG0VG0TE0TH2maKk­˸ǴȴǳİǱǱƭǮŬpm];dT3`O1`O1\\M0^P5xjPpȳŰʲ˳ǯɯȬȫƫŨžĺūìëªĩƫɭ˯Ͱȫħždn`E`R7eS;]K5ZH2dR<}mVwȼĮůǲɴ˵˵˸̶ʳʳʳ˴˴̲̲̰ͱ̰ʮʭˮˮʭȫʭy{pTdT:ZJ0WG.VF-RB+bS<u^Ƚ˳˳˲ʵɴɳȲȴȴȴɵǱìoUgX9YF(_N0ZL1YM3j`Elȫ̱ʮǮǭƭƭůưǱȲȵʷʸ̺̹˸ʷʵƱ̷Į}r\\aV@`T:fU9dT3iX<pbGuƼ̶̸̸˷ʶʴ˵ʵ̶Ǯɭ§{[iX:dT3eR2gW6gW6viGsȬʵʷɶȵǴƳŲŰƱƯǰȱȱɯȱȮȫȫǬǬȭɮ˲˲ʴư«ùv\\i[@aS8]O4YK0]Q7j^Dy`ȳͷѸ϶˵ȲƳǴȷ˸ıŰǱ˲ès^}VwSxSzW}ZbjþèĨǹruW|iKubDvcEubDveGy[sħɮȭǮŬ©êȿǾĻ|i_]jz²ìưɷ˺˼˻ȽǺȵȱɳɳɳʴ˵ʹénwlLj[:eW2jX4jZ8teH{a¶İ˶ͻϼξͽ̹˸ʷʷ˶̹ҿλʷȵƱ¬˿ɻppTo\\>fS5gR3gT6hY<vhMm¬˵ʷʶʷʷʶʶ˵̶Ͷϵ̰Ǫźwf~ZyT}Y^hy¨ŭìŮƯȱɲɰɰɰūƿty_zlRvhMykNtWjǼɫɫťgpOscBveGyhJqUi~ƼŻȼʾ˼Ⱥny_rXpRoNnIqFrBrArDyRhĭƮȰȰȰȰɱ˳͵̴ɱƮëy}[sSlH~fB}jBrNa¿̮˲Ȳɳ̳ϳҶӷҹ϶˲ȯʳʳ˴̵ηϸлкҺѷжϵϵжйѺѼѼѼлннϼϼннннннннѾѾҿҿѾнϼϼμϽϽоѿоооϽϽоооѿѿѿооооооннкккѻѹҺҺҺҿѾѾ̺̺ͻͻͻͻͻͻͻͻ˹̺̺ͻͻμμμμμͻ̺̺˹ʸʷȵȲȲíļyg\\F]Q9ZN6[K4ZJ3^L4lZBu]u|ny\\{jNudFveGxgIraEzjP}c}ŽŽù|bzmMobBi\\<h[;viIb~rcLaQ:UF/WH1WH3ZN8uiSuî˸ƳȴǳİưǱƭǮīpm];eU3aP2`O3ZJ0\\N4ufOpï˶ǲ˳˳Ȱʰ̲̲˱ʰȮƬūĪūĽɯȱƯŭëĩƫʮ̰ʭƩħƿnwiNfX=eS;_M5]K3fT<yiRnŹïǴɶʷ˸ͻλʵɲɴȱȱɲʳ˱˱ɭȬɭ˯ˮʮȫ̯uxmQdT:YI/VF-UE,VF/l]Fl¬͵̴̳ʵʵʴɳɵɵɵɵǱìʿ~~nTiZ;ZG)_N0WI.XL2lbGoɬͱʮƬƬŬŬĮůưưȴɶʸ˸̶̹ʵɴʵйǱu_dYCbV<dS5dT3kZ>qcHuƼ̶͹̸˷ʶʴʴʵ˵ǮɭvVfU7cS2eR2iY8jZ9zmKw¥ɭ˴ʵɴȳƱŰįîƱƱȱɲʳʳʳ˱ɭɬȭɭȭɭȯɯ̶Ǳ«sYgY?`R7]O4ZL1^R8j`GybɳθѸ϶ʴǱŲƳȷʹƳǴɵ˵ɰɿwmeb^}Z]apw~ƽǼ³qqSyfHq^@q^@p]?q^>}mL^zĻ¥ħǽ¸ùztqwȽŭ͵˵ʶɸɸ˻ʽȻǷȳȱȲȲɳʴ̳̳ſiujJj[:i[6o]7o_=zkNgźǳ̹̺ͺϿͽ̹ʷɶ˸͸λϾ˻ɶƴŲï¬̽|`vcEhU7hS4iV8j[>ykPpí˵ʷ˷ɶɶɵʶ̶θͶͳéüzg~\\|X~X^et¨ŬìíůǱȱǰƯǮȯ˲̳˳Ů·tzcuZ~pS}oRx[o¹ryYxiJqbAxiJqTf|ƺȼƻø©ǿɾ̿ìĶv}coT~kMlKoGpBqAsBtGzSiĭƮǯȰȰȰɱʲ͵̴ɱƮëſw{YpPkGgCmEyUjģв϶ʴȲ̳ϳҹԻҹ϶ʱƭǰȱʳ̵ηϸйϹҺҸѷжжѷѺѺлллϺϼϼϼϼϼϼϼϼϼϼϼϼнѾѾѾѾнϼλμϽϽоооϽϽμϽϽϽооооϽϽϽϽϽϽϼϼкккѻѹҺҺҺҿҿҿѾѾͻͻͻͻͻͻͻͻͻͻ̺ͻͻͻͻμμμμμͻ̺̺˹ʸʷŲůư¬Ž}k`J_S;\\P8\\L5[K4`N6r`Hi´ny[lNxeEzgIziKqTdxºf{mPqbCm^=pa@uhF~\\uxsdMdT=ZK4\\M6[L7^R<znXzįʷŲȴȴİưȲƭǮīql\\:cS1_N0_N2ZJ0ZL2rcLjʵƱɱȰūȮ˳ʲʲɱɱɱɱɱɱŭªªëëƮ˳˴ɲǯŭŪǬ˯ͱɬȫȫŨzrWk]BfU9dS7dS7jY=scIy^¶ʿíȳ˸ʷʸ˹̺ʷɴɶȳȳȳɴɲʳʰɯʰ˱ʮǭĨħhpeI`P6XH.VF-VF-cS<}nW~ưζζε˶˶˵ʴɵɵʶʶɳĭɾ{}mSk\\=]J,`O1VH-YM3ndIqɮβ˯ūūììííĮůǳȴɵ˵˵˵ʴɱͶһʳ~t[bX?_T8`O1aQ0jY=rdIuƼ­θ͹̸˷ʶʴʴɴʴƭȬÿ~sSfU7eU4gT4l\\;o_>rP|úħʮ̲˳ʲɱǯƮŭĬǯȰɳ˵̶ͷͷ͵ʰˮʰʰɯɯǰȰʷǱ«~|pVfX>`R8^P6[M3`T<lbI{dɳ̶ζ̴ɳǱƳǴɷ˹ȷɶɴȱɯȬçȿysldbdorvxyy{||mrU|gJu`At_@r_?r_>yiGuRjyúĻȾǮʱ̷ιλ˺ʸɹȻȻǺǷɴȱȰȰȲȲʱ˲ľetjGl^;l^9sa;sc?|mPjɾʶͺ˹ʺϾν˻˸ʷ˸λϼͼμͼ̹ɷǴİĮ̽õi|iKkX:hS6iV8m^A}oTs¬ɳȵɵʷʷʶ̸θθʳȮk}\\yW~Z`ksǰŰůǯȰɰǮƭǯȰʲ˴η̶ůk}^vYx[j|}huUzmMxkKz]gzîȲɳ©æƫȬǫŬƭŮĮíñǱʼpz_qTmKmFoAp@sBuH{TjŮƮƮǯɱʲʲʲ̴˳ȰŭëſyzXnNjFiErJ}Yoƥѳҹθʶ˵εѻӽѻθɳůůưȲ˵ʹ϶϶϶ҸѷѷѷййлѼιιλϼϼϼϼϼϼϼϼϼϼϼϼϼннѾѾннϼλμϽϽооϽμμμμμμϽϽϽоϽϽϽϽϽϽϼϼкккѻѹҺҺҺннѾҿҿҿѾѾμμͻͻͻͻͻͻͻͻͻͻͻμμμμμμμͻ̺̺˹ʸʷƳưǱ¬ŽncMaU=]Q9\\L5\\L5cQ9xfNqʾʾĶpxZ~kKyfFwdDtcEyjMx]qh}oRrcDp`?rb@sP\\vƽǥuvgPiYB`Q:`Q:\\M8\\P:ymW{ŰʷŲɵɵűưȲƭǮīéujZ8`P.[J,^M1[K1\\M6o`KyfȽɴǲʲɱǭʲɳɳɶʴɶʴɶʴɶɳǴȲǴɳɶ˵˴ʳȰƮǬǬʮ˯Ͱ̯̯ˮɾ~crdGgV8dT3eU4gW6iZ;viInƼɲ̷ʷǵǵȶ˸˸˸˸˸ʵʵʵ̷̵Ͷϵϵ̲ǭé~vZg\\@\\L2WG-XH/ZJ1scLkɳζϷз̷˶˵˵ʶʶ˷˷˵ƯȽvyiOk\\=`M/bQ3XJ/ZP5pfKrȭβ̰ūūììíĮůůƲǱɳʴ˵ʲɱȰ˴ѷȮ{qX^T9\\Q5_N0aQ0kZ>seJuŻ­Ϲκ͹̸˷ʴʴɴʴŬǫ¾}sSiX:jZ9kX8p`?tdCxVƽƩˮ̯̯ʰɯȮǯƮƮǯȰʴ˵̶̶̶̴̲Ͱͳγ̲̱ʲ˲ȵƳî~zpWdX>aS9_Q7[O5bX?oeL~gƳɳʴɱȲȲǴȵʸ˹ʹʹȵįƯ˱̲ɬºzvxwxwurmopuy}~~vkz]qR~iJ}iH}jI}jIoMvSZjyüìʳιθ˸ʷͻͽ̼ʺȻȻȻʺʵɲɱȰǱǱȯȭ`rhEl^;m_8sa;rb>sVq̹λ̼˻νν̼˻˹̹λϽ̻ξ˹ʷɵ¬ȺnlQmZ<iT7iV8qaGsXw¬ȲƳȴ̹˸˷͹θ˵ìŽubzY}[bj¦ɰʵȵŰưŮƯǯɰȯȰȰȰʲ̷ι˷¯ukfku}mc_`wíǱʵʳǭƬƬɮͱϵϵζ̴ʵ˶ɶƳôȵɺs~aqOjCoAp@rAtG{TjǰǯǯȰʲ̴˳ʲʲɱǯŭëxxVjJgChDsK\\rŤвӺк̸ʷͷϼѻѻθʴǱưǱȲʱ˲ʹε϶жжѷѷййϺϺ͸͸ͺλλλϼϼλλλλλλλλнннннϼλλμϽϽϽϽμͻͻͻͻͻμμμϽϽμμμμμμλλкккѻѹҺҺҺλλϼнѾѾҿҿҿѾѾμμͻͻͻͻͻͻͻͻμμμμμμμμμμͻ̺̺˹ʸʷʷɳɳĮƾ~ncMcW?^R:\\L5]M6fT<|jRtʿ¬ƭéȸrcmL}jJyfFudFyjMv[kwyrg~sWvhKvgH}mLtRitɿģȦsteNiYBbS<`Q:XI4YM7znXƱʷıɵɵűưȲƭǮŬ¨ūxn^<bR0\\K-_N2^N4]N7j[F|o\\ıŰɱʲȮ̴ȴɵʷ˷̸̹˸˷̹͹ͺ̸ͺ͹ͺ̹˶ʳɱȰȭǬɭɭ̯̯̯ͰũtvYqa?iZ3eU1dT0bT1i\\9wWwéȱȲŲŲƳʹ˺̻ͺ̹˸ʷȳʵ̷ιйй˴ĭlpeI\\Q5YI/XH.\\L3`P7r[|Ŷȯɳ̴ζѸ͸̷̶˵˷˷˷̸˵ŮźqueKj[<`M/bQ3ZL1\\R7qgNtǬ̳ͳǭǭƮŮůůưǱǱȲʴ̳ʹ̳ʲɯɯδƬ}{qV^T9\\Q5bQ3eU4o^BvhMwŻθκ͹̸˷ʴɳȳʴīƪ}uUm\\>p`?n[;tdCyiH}[Ǫˮ̮̮ˮˮʭɯȮȮȰɱʴ˵ʷ˸ʷ˵ʹϳϴдϴϳʹ̳ɵƳŰ|rYfZ@aU;]Q7\\P6dZAsiPiıůưƮȲɳɶʷ˹˹̺̺ɶůƯͳδʮ̬Ƥ ȿû|wrtvxz{y{~{tg}^vWwVyXzV{W}YcmzĻǾéǯʴ̶̹ͺͺ̻˻ͿͿʽɼ˼ν̷˴ʲȰǮƭƭƫawmJvhEzlEoIpLkí̹ͺ̼ͽͼͼͼͽͻμλμ;μλκǱ˽ooTs`Bp[>q^@yiO{`¸Ǳʴȵʶ̹˸˷͹ͷǱû}oeelwĴ˾ɬͳͶʵɸɶưêĪƬ˲̳˳Ȱʴʴ˷̹λ˹Ƿ®ŷ{wz}Ǭɲɴʵ˶͵˴ʲ̳϶ѹѹѺͷ̷͹ͼƶƿȾƴ¥Ͽ̹ıp{YnGoAp@rAsFzSjɲȰǯɱ̴ζ͵˳ȰǯƮĬëªª¨y{YpPnJpL|Tg}ȧвӺϹʶʷ˸̻ϼλͺ̶ʴȲȲȯȯɰ˰ͲγϷηϸϸϸϸιι̷̷ͺͺͺλͼͼλλλλλλλλϼннннϼλͺϽϽϽϽϽμͻ̺̺̺ͻͻͻμμμμμμμμμλλкккѻѹҺҺҺͺλλϼнѾѾҿҿѾѾѿѿѿϽϽͻͻͻͻͻͻͻͻμμμμμμμμμμͻ̺̺˹ʸʸλ˸˵ŭƾymaGfX>aQ7\\L3^L4hV>~lTvȽíȱʱūǹjd{]pRxiLwiL~pUw[y^wZ{pTvkMxjMrS~_f|̿ťĥħrpaJfV?`P9]N7UF1YJ5}q[ƱɶıɵʶűưȲƭƮĬéƬzufEfW6]N/`Q4^P5[L5bV@rfPyŽŮǯƬʲƳȵɷ̹˹̹ʸʷ˹ͺ̺̹ʸ̹˹ɶ˳ʰʲɯȭǬƫƫȫȫɬ˯ɮŻjtQthBi]7eY3cU0fZ4|pJd|¹çƬƮǯɳɶʷ̹ͺ̹ʷȵƳįǲʵιηɲĺzx\\eW<VH-VF,YI/`P7fX>{dʾ˲ȱɱεѸθ̷˸ʷʷʷ˸̶ʵĭ÷mqcFiZ;^M/aR3\\N3^T9piOtƫ̳ʹȯȯǰǰǱǱȲɳȲɳ˵̶ε̴˳ʰȮβŪ~tXcX<bT7eU4hX7raCyjMxƺͷͺ͹̸˷ʴɳɳɳêŬ¼{vVo`?tdBo_=wgE{lK`¥Ȭ˯̯̯ˮˮʰʰʰʲȰɱʴ˵ʷʷɶʴ̳ͱεдεʹ̳˲ɵɳǲļtZj\\BeW<_Q7_Q7i[AvjRk­ííĬǱʴ˸˸˸˸˹ͺ˸ưǲͶͶɯ˭ǧħť¢żĹƻķö³}}}~~}¹Ļ¹¸¸ùùĺǽæƪʲ̶̶ʶʶλѾҿɹξ˾˻;͸̵˳ȰǮƭŬīmz\\{[aehŽɴͺ͹ͺλ̻̹νϼϼμλϼοͽλϼҽʴʾprVveGveGziMrUhɿͶιͺϻ̹˷˷ͷ̴ëvkgqȹɭҸӺ͸ǵȷɷưŭ̳η̴Ȱ̶˶̸ͺϼнͽ˸Ūź·ƽɿŹ÷¸Ȯ̳˴ȳɵ˶ͷ˳ɳɲʳ̴˵ʴɴɴ˷̻Ŵ»¨¥ͽògxPoEoDpDqFxTlôʳɱȰɱ͵Ϸͷ˳ǱƮįĬëªªéh__blx¢̭ϴѸ̶Ųʷ˸̹ͺλθͷ̶ʴɳǱǮȯʱ̳εζηηϸϸηι͸˶̷̹ͺͺλλλλϹλϹλλλλϼннннϼλͺϽϽϽϽϽͻ̺̺̺̺̺ͻͻͻμμμμμμμμλλкккѻѻҺҼҼλλϼϼнѾҿҿҿѾѾѿѿѿоооͻ̺ɷʸʸ̺ͻμϽϽͻ̺̺̺̺ͻμϽͻͻͻ̺̺˹˹˹̹ͺλǰŻopa@fV5cP0gT6hT9gS;jUİƳ˵˴ȯ©ȼncz]vV{mPrgGoeBtjFyoL|qQvVezĶʼĪȰêvl\\E^L6ZH2`P9\\K7[L7ymWŽðıűƲƱľëļƬü~`odF[P2]R6dX>cW=`V=aW>u_xíìư̷˺ͽ̽˻ɺɹʻͽǸʺ˼̼ɺɹȹʷɱˮʰɬƩŨūǭ̲ūéǭextQkeAjb=ja:k_7sg=tJ[lħǫʮȯī¬ůʶ̸ɷųĲñƲʶ˵©{`ufIaQ7XH.UE+WG-eW=uiOuȮ˱Ȯ˰Ͳ̳ɶʷ̺̹ʷȳȳɲƭéjseHfW8`Q2YK.[O5b[AyrXyȰ˳ǯɳȲƳŲŲƳȵɶǴȵɶʷ̶̵˴˲ǮɮǭĹ|uXl^AfW8gW5jZ8scByZǸưƲͺ˹ȶƳǱȲ̳ʹëw}[ymGse@k]8rf@vSoƿɯ˳˳˳ʲɱȰȰǯưưǱȲɳʴʴʴʴʴ˲ʴʱɳȲȲȲĮȯƯĺfueKfU9dP7`O5eT:wgNoɽȴƱǱȲȲʴ̶ͷθ˸̶̶˵˵ʴʴʲȰǭƮūĪé¨¨ȾȾɿ¨ĪľĽƿéīŬȾɿȾǽƼŻǽȾũũƬǭū¨ƾļƾƾǿ«ĭŮƯȰȰɱ˵ͷϼҿͻͻμμξϽϽϼϹζ͵̴˳ʲʲʲ}x}ľư˷͹Ϻιι˸ʵɶ̷ιϻϻͺѿνͺϻҼ˴Īkz\\wYy[n}¦ʳ͸ͺͺ˸ʷ̶̵ʰžsqs|¥ʰ̵ͷ˸˸˸˹ʸɶıŰưǱȲɵʶʶ͹͹κϻλλͻͺ˵̴̴̴˳ʲɱʱ͸˶ʵȳƱŮŰŰɴȲưůűǳʶ̸̸̶̷˶˶ʵɴɴ͸̷ʵı¿¯ðȴȲ«ǻqwSoIqKpKpMxXpĴƯǮůȲ̶θʷǲȵįŽŽªý~Ľūͳѹи͵ʴʴ˵̶ͷͷͷͷηʴʳɲɱȱʲ˴̵˵̶θϹкϹι͸̷͸̸̸κϻѽӾͷ˲ɳʹѻҼθɳɳͷнѾϼͻ̺ѾнϼλλλϼϼͺͺͺͺͺͺͺͺͺλϼλͺͺλнϼнѾнλθλϼͺλϼϼнѾҿҿнѾѾҿҿҿҿҿѿѿѿѿѿѿѿѿѿ̺̺ʸʸʸ˹̺ͻͻͻ̺̺̺̺ͻͻμϽͻͻͻ̺̺˹˹˹˻˸̹ǰǾoscAlY8hT3jU6kV;kU=oZñƳȵ̸λθɲŮŻyqh~^wT|U[bfnzůȲɳ˵íun^GbP:^L6bR;\\K7[L7{oYļððİƲŰýǿļ¨Ȯwx[f]@^U8]S8[Q6\\R7aW<vlSfĺêůȵʷʹʷǶǴȷʷǶȵǶɶɸʷɸʵ˱Ͱ̯ʭȫƩƬǭʰūëƮʲƮ}j|wWvpLqiBkb7od7yl?{N[nžŪŪǮ˲ͷκ̺ɷȶǳɵ˵Ǯ¸twgMgV:\\K1]M3eU;n`E}qWiͳδ˰Ͳд̳ʷ̺ͻͺʷɴȲɳȰūjqcFbU5]N/WI,]S8ibH|bº˴̵ȱɴȳȵȵȵȵɶɶƴǵȶɶʷʵɳɳǯȮǬǹ}yYrcDk\\;iY7n^<xhG~_ȹưƲ˻ʹȶƴƲȲ˴ʹĮƮé{atNymEuiC}qK_yéʴʴ̶˵˵ʴɳȲǱǱȲɳʴʴ˵ʴʴʴʴʴʴɳɳɳȲȲɰ̳ʰžjziMmY>gS8fR7jV={jPq˼ȲǲȲȲɳʴ̶ͷθ̶̶̶˵˵ʴʴʴȲȲǱưůĮĮí¬íĮĮííůȲǱů¬¬ĮȲʴʴůůĮí¬íĮůǲȳɴɴȳŰ­­îįŰƱƱɱɱʲ˳ͷϹҼӽͺͺͻͻμμμλθζ͵͵̴˳ʲʲý®ŰʵιѼѼѼлι̷̷͸ϺллϺоλ͸͹ϹȰĪzy}ĽɭͶ͸̹̹˸ʷɴʳʮ¥~þƬ̶κͺ̼˻˺ʷɶɶŲƳƳǴȵɶʷʷ̹ͺͺλλͺͺ͹̸͸ιι͸̷˶˶ͺ̹ʷɶǴƳƳƳɶǴŲııƳɶ̸̸͸̷˶˶ʵɴɴ͸̷ʵƱ­­ð³ƷǶ®Ľt{XpLpLlK|gHlO}b|¨Ȯʳʳǰ¬íʿȽʿǿŽƾ«ëſëƮʲζииϷζʱ˲̳ʹεʹͶͶʳɲɴɴʵ˶̷͸ӽҼѻкϹϹιιιι̸̸̸͹κлε˲ɰ̳зҹθʴʴθнҿѾϼμμнϼλͺͺͺͺͺͺͺͺͺͺͺͺͺͺλϼλ̹̹λнϼнѾнλͺλϼλλϼнѾҿҿѾѾҿҿҿҿҿѾҿҿҿѿѿѿѿѿѿѿѿѿ˹̺ʸʸʸʸ˹˹˹˹̺̺̺ͻͻμμμͻͻ̺̺̺̺˹˹˻ɶɶƯɿ´sueCjW6eR1gT4gS8jV=r]³Ŵȵɶ͹ϼҼиζͳĨypv|¸ʿɳ̸̸˷ʶql\\EbP:^N7`P9YH4XI4znXŽ¯ðİűŰ¼ǿǿƾū˱ūsyoTf\\A\\R7VL1YO4aW<h^CrhM{`wĺŻūȮɲ˱ɲʰʳ̲˴ɯƯȮ˴δ̵˱ʭˮ̯ˮɬǪǭȮȰǯǯʲͷʴĮÿpbzSvmBuj=xm@tH|P^lvĻŬůĮï®ǳǳǳưȾv~bn^DdS9`P6n^DqWhzǫѷжεззͶͺμϽλ̹ʵʳʳ˲ȭmqcF_Q4[N.WL.bX=rkQp«Ͷ̵ȱɴʵʷʷʷʷɶɶųƴǵɶɶʵʳɲɰʯƪø~{^uhHpa@n^<tdBqPi˼ȲǳʺɸǵƴƲǱʳ˴Ǵʴǰo^|V}ZbuƼɯ˵ȵ̶˵˵ʴɳɳȲȲ˵˵̶̶̶˵ʴʴʴʴʴʴɳɳɳȲʱʹ˱rtWtcGm\\@l[?p_EpVt˼ǱǲȲȲɳʴ̶ͷθ̶̶̶˵˵ʴʴʴɳɳɳȲǱǱưưůưȲȲǱȲ˵ͷ˵ȲưǱʴͷϹк˵ʴɳȲɳʴ˵̶̷͸͸͸̷ʵȳƱŰŰŰƱƱǲǲǲ˳˳˳̴ͷϹкѻͺͺͻͻ̶̺̺̺̹͵ζζ͵̴ʲɱƮƮŭŭŭŭƮǮƲɴ͸ѼӾӾӾҽлι͸ιллϺιμоϼ͸ʶʴǯƬçĽúǾṴ̃жϸ͸˸ʷ˸ɶȳɲ˱ɭæſĿĿĿſåǪ˳θϻϼͽ̼˸ʷɶɴǴȵȵɶʷʷ˸˸̹ͺͺλλͺ̹͹̸ιιιι͸̷̷ͺ̹˸ʷɶȵȵȵɶȵƳŲŲǴɶ̸̸͸̷˶˶ʵɴɴ͸͸ʵǲî­įŲ³ƷŲžx}ZnJ|jFwcBq\\=s^AjOhwĢǨƧæʿɾƻŻȿĽĿ¥¨ëĬŭƮǯȰȰ͵͵̴̴̴͵͵ζʱʱ˲̳ʹ̵̵̳ȱȱʳ˴̵Ͷ͸͸Ծӽкθͷθкѻѻкι͸̷̷͸͸϶̱ʯ˰εзθ˵ͷϹнѾнϼϼнλλͺ̹˸˸̹̹ͺͺͺͺͺͺͺͺͺλϼλ̹̹ͺϼϼнѾнλͺλϼϼϼнѾѾҿҿҿҿҿѾѾѾѾнѾѾѾҿҿҿѾҿҿѿѿѿѿѿʸ˹˹˹˹ʸʸɷɷɷ˹̺ͻͻμμμμ̺̺̺̺̺̺̺̺̼ȵǴƯɿpscBiV6dQ1fS5gS8nZB|fȹȷɶɶ˷θѻѹиδɯèɾźżȿ¬ǲɵ̷ʸȳűûjm]FdT=`P9_P9WH3XL6~r\\ƾııűǳǲíſƬ˱ǭƿjyoTg]B\\R7\\R7aW<cY>i`CulOaxýħȨȫ˫̯ϯϲ˫ŨǧˮήˮǪæŨǪȫǪǪǭɯǯɱ̴͵ͷ̶˵˲§zk]TR{QU\\birz¸ǼǼǼŻr~brX{kQ|lR~cxùǫβѷδ϶ѸѸͶϼоѿн͸˶˴˴̳ȯrwiNeW:bT7bW9ndIy_~ǰͶʳƯȳɴ˸˸˸ʷȵǴƴǵȶɶʵ˶˴ʳ̳ʱé~{^wiLreEteD}nM}^tɳȴ˸ȷǵƴƲǳʳ˴˸̹ʳ¨uqw~ƽɯ̵ʷǴ̶̶˵˵ʴʴɳɳθθθθͷ̶˵ʴ˵˵ʴʴʴɳɳɳɰ˲˰éiwZ|mP{lOoU}c|ʾǱȳɳɳɳʴ̶ͷθ̶̶̶˵˵ʴʴʴʴʴʴʴɳɳɳɳɳʴ˵˵ʴʴ̶θ˵ɳȲɳ̶Ϲкѻθ̶ʴʴ˵ͷϹϹϺϺϺϺι͸˶ʵɴɴɴɴɴɴȳȳ̴̴̴̴ͷθϹкͺͺͻ̺̺˹˹ʷ˵̴ζϷζ̴ʲȰŭƮȰʲʲɱǯưȴ˶ιѼӾӾӾӾлι͸͸ϺϺι̷̺μпϼ͸ȴưɱɱɯƪĨħǪʭдѵҸйϺ͸˸ʷ˸ʷʷ̷ηϵ̰ɬ˩˧˩ʭˮ̲ͷͺѾнξͺ̹ʷʵʵɶʷʷʷ˸˸̹̹ͺͺλλλͺ̸̹͹ιϺϺϺιι͸ͺͺ̹ʷʷʷʷʷɶȵƳƳƳȵɶ̸˷̷̷˶˶ʵʵʵ͸͸˶ǲįįƱǴŶȹŲĽvyXwdCr`<lX7gR3dO2kV;|hPx\\emŹŹķöƽľÿ¨ŭɱ̴͵͵̴ʲ͵̴ʲɱɱɱʲ˳ʱʱ˲̳̳˲˴ʳƯȱʳ̵ηηηͶ̶̶̶̶θϹкѻѻкϹθ͸θ͸Ϸжϴ̱̱εзϹθϹкнϼλλнҿλλͺ̹̹̹̹̹ͺͺͺͺͺͺͺͺλλϼͺ˸˸ͺλϼнѾнλͺλϼннѾѾҿҿҿҿҿѾннннннѾѾѾҿҿнѾҿҿѿѿѿɷʸ̺˹˹ʸɷɷȶȶ˹̺ͻμμμͻͻ̺̺̺̺̺̺̺̺ͽȵǴƱǽmo`AhW9dS5fU7iX<tbJr±¯˺˸ɵɵ˵ͷ͵͵ɯǭƪƩǪŨȿĻĤƨūĬįŲǴɶǶı¯ko`KhXAcS<aR;[L7`T>{eûƳƳǳɵʵưĬūĬëƮɱǯªǼsw\\oeJf]@d[>h_BlcDulMwVeoz~¼Ġɣ˧ǡÝƢȢßſ½æĪūǭɯɱ̴Ϲθ̶ʴ˵ε˰ĥzqlffggjnsw{u|vwʾéǬ̲ͳ̴˳ʹѸѸηϼоҿѾι̷̵Ͷ˲ȯ¸}{_wlPvkOynR}bu̵η˴ȱȳɴʷ˸ʷȵǴŲȶɷʷ˸̷̷̵̵εʱèf}rV{mPtU`oë˵ʶʷɶȵǴȴȴʳʳ˸ͺ̷ǰȾøʯϸϺ˸Ǵ̶̶̶̶˵˵˵˵θϹϹϹθͷ̶˵˵˵˵ʴʴʴɳɳɱʱ˰ǭĽxmmp{Į˶ʴʴʴʴ˵̶ͷθ̶̶̶˵˵ʴʴʴʴʴʴ˵˵˵˵˵ͷθθ̶ʴɳʴ̶ʴȲǱȲ˵ͷθθ̶ɳưưɳͷθθϺϺϺιι͸̷˶˶˶ʵʵʵɴɴɴ͵̴̴̴̶ͷθϹλλͻ̺˹ʸʸɶʴ̶ͷϹθͷʴɳʴ˵˵̶˵ʴȲǱɵ˶͸ϺѼѼѼѼι̷˶˶͸͸̷ʵʹ˺λнн̸ȴĮʲʲʰʭȬȬɭʮѷϸη͸͸ͺ˺ʹɸ˸ͺлҽйͶ̲ͰͰͱ̴̲ͷ̹̺Ѿнϼλͺ̷̷˶˸˸˸˸̹̹̹̹λλλλλͺ̸̸̹ιιϺϺϺιιͺ̹˸˸ʷ˸˸̹ȵȵǴǴǴȵʷ̸˷̷˶˶˶˶ʵʵ͸͸˶ȳƱƱȳʷ˹˹ƲüqrQmZ9gT3`M-[H(VC%WC(cO7p_AuHN_jqqrrqwÝŠǤˮ˳͵ϷϷζ̴˳ȰȰɱʲ˳ʲʲɱʱ˲˲̳̳˲ʱʱƭǮʱ̳ʹεʹʹɰ˲εѸҹҹѸзззз϶ϷѸѹѹҸжͳͳδϵϷϷϹккϹͺλнҿϼϼλͺ̹ͺͺͺͺͺͺͺͺͺͺͺλϼϼͺ˸ʷ̹ͺϼнѾнλͺλϼннѾѾѾѾҿҿҿҿҿѾннϼϼнннѾѾѾҿҿнѾҿҿѿѿѿɷɷ̺̺˹˹ʸʸɷɷʸ˹ͻϽϽμͻ̺˹˹̺̺̺̺ͻλͽȵɷɴǽmrcFhW;eT8gV:iY?xhQ{Ŷ¯ͺ̹ɵȴɳʴʲɱȱɯȮȬȬƩĽ½åħëí¯ıǵʷȶƳĲpk_IcT=]N7[O7YM7dYCjŽîǴǴȴʶ̷ȲȰƬŭŭƮǯƮĬɾh~tYulOsjKvmNzqP|sRvU}Yaflotz½þ½þ¥éūǭɯ˳ζкθ˵ɳɳ˳еͯȩģÿ~|zxy{|}}´Ĺé̱ϴγ˱ʰɱʲʹ϶зθλϽѾнϺ͸Ͷηʴȯǽ{ppu»ɯййη˴ʵʵʷɶɶȵǴƳɷʸ˸̹͸͸ͶͶͷʱīùvkiozǻǮ˵ɵ˸ʷɶɶɵɵ˴ʶ˸̺̹ʵƭ§Ĩǫ˰϶лλ˹ɷ˸̶̶̶̶̶̶̶ͷθθϹθθͷ̶̶˵˵˵ʴʴʴʴ̴˴̳Ͳʭ¦»ŭ˶Ϲ˵˵˵˵˵̶ͷθ̶̶̶˵˵ʴʴʴʴʴʴ˵̶̶ͷͷθϹθ̶ɳȲɳ˵ɳȲǱǱʴ˵˵˵ʴů¬Ǳ˵ͷ̶͸͸͸̷̷˶˶˶ʵʵʵʵʵɴɴɴ̴̴̴̴ͷθϹϹннϽͻ̺ʸɷɶʷ̶ͷθͷͷ˵ʴͷͷ̶˵ʴɳȲȲȴʵ̷͸ιιϺι̷˶ʵʵ̷͸̷ʵɸʹ̹ϼнλɵůɳɱȰɯɯʮ˯̲˴ʵʵ˶ͺλͼ̻ȷ˺ϼҿҿл͸ʳ˴˱ʳʳ˵˸̺ͻннϼϼϺιι͸˸˸̹̹̹̹̹̹λλλλͺ̹˸˷˷̷͸ιιιι͸˸˸ʷʷʷ˸̹̹ȵȵȵȵȵɶʷ˷ʶ˶˶˶˶˶˶˶ι͸̷ɴǲȳʵ͸̸˸ǱŻlzkJfS3]J)WD$S@\"M9\u001eL8\u001fXD,gW6zn>v@~IPQP|LyKxLWmȢ̥ΫͰ̴̴̴˳ɱȰǯƮȰ˳͵Ϸζ͵̴̳̳̳ʹ̳˲ʱʱƭǮɰʱ˲̳̳̳ʹ϶ӺռռӺ϶ʹ϶϶εε϶зѸҹжжϵδδδζϷͷϹϹϹͺͺϼѾϼϼλͺͺͺͺͺͺͺͺͺͺͺͺͺλϼϼͺʷʷ˸ͺϼнѾнλͺλϼннннннннѾѾѾѾнннннѾѾѾҿҿҿѾҿҿѿѿȶȶ̺̺̺̺˹˹˹˹ʸ˹ͻϽϽμͻ̺˹˹˹̺̺ͻͻλ˻ɶ̺͸ȽqwiNn^Dk[An^DoaG~oXǺïλ͹˷ʶ˵̶̶˳͵̲̲̲ʰɬĨ¥ÿ©¬įŲƵɹͼʺȵȵ¿tk`J`T<YM5YM5]Q;laKrŽîǴƳǳʶ˷ɳȰƬĬŭưưưǱįƱƱ}rhgc^[Z\\\\bdhlryĪūƬȰɱ̶θϹθʷȵǴɳεͰͮ˪ʧƢŽ»ž¢ã£Ĩ¨éǭͲ϶ϵʰʰ˳̴θθθϹ˸λннιιιϸͶʰĪüĽƬ̲ϸйηͶ͸̷˸ɶɶȵȵȵȵɶʷ̷̹͸͸̵Ͷ˱Ȯéƻʾëɰɳȱ̷˶˸ʷ˷˷˷˷˸˸˸˶ɳɰɱɯǭɱ˲˵̷̹̺λ̹ͷͷͷͷͷͷͷ̶̶ͷθθθͷͷ̶̶˵˵˵ʴʴʴ̵˴˲Ͳгϲ˭Ȫƿ¦Ʃɯʹͷͷ̶˵˵˵˵̶ͷθ̶̶̶˵˵ʴʴʴɳɳʴ˵̶ͷͷθθθθͷʴʴ˵ͷ˵ʴɳɳ˵̶˵ʴɳíſů˵̶̶̷̷˶˶ʵʵʵ˶ȳȳȳɴɴɴɴɴ˳˳˳̴ͷθккҿѾоμͻ˹ʸɶ˸̶̶̶̶̶̶̶˵˵˵ʴʴɳȲǱɵʵ˶̷̷͸͸͸˶ʵʵ˶͸ιι̷ɹȸ˸λнн̸ȲǱƮƮǯɱ̲δδʵɶʷͺпϾͼȷʹͼнϼλ̹̹˸˸ʷɶʷ̺μϽϼϼϻϻллйй˸˸˸˸˸˸˸˸λϼϼλͺ̹˸˷ʶ˶̷͸ιι͸͸ʷʷɶɶʷ˸̹ͺȵȵȵȵɶɶʷ˷ʶ˶˶˶˶˶˶˶ιι̷ʵȳɴ̷Ϻ˶˶ưƼiteD`M-VC#P=\u001fP=\u001fM< Q@&dR:yiHPKMP}Jr@xd2oZ+p^0|k?\\þƠʤ̫ǭȰɱɱɱȰǯƮȰɱ˳ζϷϷϷϷ̶ͶͶηʹ̳˲ʱȯȯǭǭǭȮɯʰεзҹԻԻҹз϶϶εʹ̳̳ͳʹʹͳβββͳ̲ʳʳ˳͵Ϲθͷͷθкλλͺ̹˸˸̹̹ͺͺͺͺͺͺͺͺλϼλͺʷɶʷ̹ϼнѾнλͺλϼϼϼϼϼϼϼϼλϼнннннѾѾѾҿҿҿѿѿѿȶǵ̺̺̺̺̺̺̺̺ʸ˹ͻϽоϽͻ̺˹˹˹̺̺ͻͻλʺɸннv~pV{mSykQ{mS{oW}gű˶ϼκ̸͹θϹθͷϷϷϷϵδ̲ɯɬ¦¦«îŲȷʹ̽ο̻ɸȵuqiRf\\C^R:_U<f[EynXºŽîƳŲƲɵʶȲǯĪëŭưưƳɶ¯ǲ̷̷ɲé}uqmjhegilqx½ĪǭȮȮȰɱ̶θϹϹ̹ɶȵȲɰ˰ˮͮήЭͪȦƤģä£æȾãá¢ƿĽžé¨éĪƪȫ˫˫˫ˮʯǭƫƫȭ˱˱˱˱͵икθθкʷ̹ϼϼιιϺлηʳǰǭūūǭ˱ͳ˱ɯʰ˴ͶͶ˴Ϻι̹ʷɶɶʷʷǴȵɶʷ˶̷˶˶̵ʳɲʰūžžƼĩɱʱɰʱɲƯ̷̷̹˸̸̸˷˸ʷʷʷʷʵʴ˵̴ǯȯȲȳɶʷλѾ̹ͷͷͷͷͷͷͷ˵˵̶ͷθθθθ̶̶̶˵˵ʴʴʴ˴ɲȱ˲ϴҵѴбˬ̭Ͱγ϶ʹʴȲ̶̶˵˵˵̶ͷͷ̶̶̶˵˵ʴʴʴȲɳɳʴ̶ͷͷθ̶ͷθͷ˵˵ͷϹθ̶˵˵̶ͷ˵ʴɳíľſư˵ͷ̶̷̷˶ʵʵʵʵ˶ǲǲǲȳȳɴɴɴ˳˳˳̴ͷϹкѻҿѿϽͻ˹ʸɷ̶̹˵˵˵̶ͷͷʴ˵̶ͷͷ̶ʴɳɵ˶˶̷̷̷͸͸̷ʵʵ̷ιллιʷȸʷͺнѾ͹ʶưůĮŭȰ˳͵ζ̹̹ͺѾͼȷɸ˺̻̹̹ͺͼͼ˺ʹɸʸͻϽѿλκϻϻлѼѺѺ˸˸˸˸˸˸˸˸ϼϼϼλͺ̹˸˷ɵʵ˶̷͸͸͸̷ɶɶɶɶɶ˸̹ͺȵȵȵɶɶʷʷ˷ʶ˶˶˶˶˶˶˶ιι͸˶ɴʵ͸лȳȲŭƼjrcDZI+R?!M:\u001cO>\"TC)_N4xfNdia_[Rq@q[,bL\u001dfQ&sb7V|ţŦǬǯʲ͵ζ͵˳ʲɱʲʲ˳̴ζϷзͷηηηεʹ̳˲ɰȭƬūūǪȮɯɯ˲̴εзѸҹӺ϶ε̳˲ʰʰɯɭˮ̰̱ͱ̲ʰȱȱʲ̴θθͷ̶ͷθͺ̹˸ʷʷʷʷ˸ͺͺͺͺͺͺͺͺλϼλ̹ʷɶʷ˸ϼнѾнλͺλϼλλλλλλͺͺλϼϼннѾѾҿҿҿҿѿѿѿ˹˹ʸ˹ͻϽϽμͻ̺̺ͻͻͻͻͻͻμ̺˹˹ʸʸ˹˹ͺνʷǴ¯lighsǲԾ˸˸̹ͺϻмкѻϹѸӺӺҹзʹ˰ǮȮȮɱʵ̸μο̽ǵƴȴï~fwpVpfMrkQ|t]n¯Ųȴ˷͹θ̳˲ɰǮůůİİ˹ɶǴʴͷζ̲ʭþĿþ¼ýľſƿǪȮʲȰŭĬưȲȲɳɶʷ̹ͺλкʹγϴггϰί̬˫˫ʭʮɮȯȯȯɬ˫̮˭ɬȮʲ̴͵̲˱ͰϱаϯήʭʮɮɭȮɯ̵ϸиикϹθͷ̶˵˸ͺλλͺ̹ϹкҼиζ̴˳͵ζж˱ʰʰɯȱɲɲʳιϺнϼͺ˸ʷ˸ʷʷʷ˸˸˸ͷͷϹϷζζζ͵͵ͳηδ̶̵̵˴˴˴ͷͷͷͷ͹͹ͺͺ˸˸˸˸˶ʳȲȲưưǳɴ˸̹λλͺͷͷͷͷͷͷͷ̶̶˵˵˵ʴʴʴ˵̶̶̶̶̶̶̶̸ʴȲȯʮͯвӵ̮ΰϴѵ϶̵ȳűɳʴ˵ʴȲȲʴ̶ͷͷθθͷ˵ɳȲ˵ʴɳȲȲʴ˵̶ͷͷͷͷͷ̶ʴʴͷͷͷ̶̶̶˵˵ưưưǱɳ˵̶ͷιιϺι͸̷˶ʵŰƱǲǲƱƱȳʵ˳˳˳̴ͷθкѻҿѾоμͻ̺̺˹˸˸ʷɶɶɶʷʷɶɶɶɶȵǴƳƲ̸͸ιϺϺϺιιιιι͸͸̷̷̷ɶȶȶ˹ͻϽλ̹ǳưưưȲ˵θкͺͼпҿҿ˸ͺϼнνννп;ʻʻ̺μϼϼϻϻϻкѺһһһλͺ̹ʷʷʷʷʷͺͺͺͺͺ̹˸˷ȴʵ˶̷͸͸͸͸ɶǴƳǴɶʷɶǴƳǴɶʷ˸ʷʷʶ˷̷˶ʵ˶̷ιϺι͸͸̷̷˶˶ʵͷǮëĪȾewhK]L0N=!L;\u001fQ@$VE+m]Ci{zjzNw^5hO&iQ+t`;^ú¦īƭǯɱȰɱ˳˳ɱ˳ɱȰɱ̴ϷиѸкη̵˴̳ʹʹʹƬǭȮƪçæŪʮʰͳжж̲ʰ˰ͲѶ̱ʮɭʮɭɭ˯ȬɮǭŪŪɮ˱Ȯδͳ˳ɱ˵θθ˵ɶʷ˸̹ͺλλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺнϼϼϼϼϼλλнϼλͺͺͺͺͺϼϼнѾҿҿҿѾѾоооѿѿѿѿѿ̺̺˹̺ͻͻμμμͻͻͻͻͻͻͻͻͻ˹˹ʸʸʸʸ˹̹ϿͼʷʷƵƾʴкʷʷ˸̹κϻϹк˵̶϶϶ε̳ʱȯŬƬƮǯǳɵʸʻʻʸǵǳʶɴtns}ͶůůŲǴɵʶ˷̸θεʹ˲ʴʴʶʶμʸǴƳȵʴʲɯƩȪȪǧġÿþ»üĽĽž¦çĨũƪǫƪƪȮʰ˳ɱƮĬůưɳɳɶʷ̹ͺλλͷεγγͲˮʭɬʭʭʭɯɰɰȲɰˮ̯ͯͯɯɱʲ̴ͷ̴˳̲ϲвϱΰͱβͱ̰˱̲ηѺζζθθͷ̶˵ʴʷ̹ͺͺ̹̹θккϹζ̴̴ʹ͵ζ̲˱˱ʰɲʳʳ˴͸ιнϼ̹ʷʷ˸ʷʷʷ˸̹̹θθѻѻѹиизϷϷ̶˶˶ʳʳɲɲɲͷͷͷͷ͹͹ͺͺ˸̷˷ʷʵʵʴʴȲɳʵ˶̹͹ϺϺθθθθθθθθͷͷ̶̶˵˵˵˵˵˵˵˵˵˵˵˵ͺ̹˵˵ʹϳҴӵͯΰϳ϶η̵ʵǳʴ˵˵ʴɳȲʴ̶ͷͷθθθ̶˵ɳ˵˵ɳɳɳʴ˵̶̶ͷͷͷ̶̶˵ʴ˵˵ʴʴʴɳɳɳɳɳɳʴ̶ͷϹкϺϺϺϺι͸̷˶ƱǲǲǲƱƱȳʵ̴̴̴͵θкѻҼҿѾϽͻ̺˹˹˹ʷʷɶɶɶʷ˸˸ͺͺͺͺ̹˸ʷʶ̸͸ιϺϺιι͸ллϺϺιιι̸ʸɷȶɷ̺ͻ̹˸ƲƲűůǳʴ͹ϻμνпҿҿҿѾлͺнпͼ̻˺ο̽˺̺λϼкκθθϹййѺѺλͺ̹˸ʷɶɶȵ˸˸˸˸˸ʷɶɵȴʵ˶͸͸ιι͸ɶȵǴȵʷʷȵƳŲǴɶ˸̹˸ɶɵ˷˶˶ʵ˶̷͸ιιι͸͸̷˶ʵʳƭ§ǼexiL_N2P?#L;\u001fQ@$XH.ueKtƸŶƴ¯s}U{_:kO*pV3~gGiŭǰɲǮǯȰȰɱʲʲɱ˳ʲȰʲ͵ϷиѸйη˴˴̳ʹʹ̱ɯɬǫƩŨŨŨƩɮʱ˲̲̲̲δѶе̱ȭʮ˯˯ɭƫȾȼŹǽŬʰ̲ͳ̴ɱʴͷͷ˵ɶʷ˸̹ͺλλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺϼϼϼϼϼϼϼнѾнϼλͺλλλннѾҿҿҿҿҿҿѾоооѿѿѿѿѿ̺̺ͻ̺̺̺ͻͻμϽϽμμͻͻ̺̺˹˹ʸʸɷɷʸʸ̹ͽͼʺ˸ɸȵĲųİïƱʴ̶̶̶ɶʷʷ˸̸͹κκ˴̵ͶͶ̵˳ɲǰŬŬŮƯƳǴɸʹǶȷȷȵʷ̷ƯƮԼɳɳȵȵȵȵȵȵθͷͷ̶̸̸͹͹о̺ǵŲŲǱȲȰʲ̲δϲ̮̮ͯͰɲɴɴɴȳȳȳǲȳɴʵ˶̷̷̷˴˳̴̴ʲǱůůůȵɶɶʷ̺ͻͻλθ͵ʹ˲ɰɭɭȬʮʯɯɲȲɳʴ˲βϲϲͳʰʲ˵ͷͺ̶˳̲δггαгϵϵδ̲ͳиҺͷͷͷͷ˸ʷɶȵɶ˸̹̹˸˸̹λͷͷͷͷͷͶ˵̳ͳ̲˱˱ʳʳ˴̵̷͸ϼλ̹ʷʷʷɶʷʷ˸̹ͺλλѻѻкккйϹϹ˸˸ʷ˵˵ʴʲʲ͵͵ͷͷ̹̹̺ͺ̷̵ʴʴɴ˶˷͹˷˷͸͸θθϸϸθθθθθθθθθθͷͷͷ̶̶̶˵˵˵˵˵˵˵˵̷̹̹ͷεϴввϰϰβδͶ̵˷˷ʴ˵̶ʴɳɳʴ̶ͷͷθθθθͷ̶̶˵ʴʴɳʴ˵˵̶̶̶ͷ̶˵˵ʴ˵˵ʴʴʴɳɳɳ˵˵˵˵̶θϹк͸ιι͸̷˶ʵɴƱǲȳǲƱƱȳʵ͵͵͵͵ϹкҼӽнϼμ̺˹˹ʸʸɷɷɷɷʸ˹̺ͻϽϽϽϽμͻ̸̺̹͸ιιιι͸͸ιιιι͸͸͸̸˹ȷǶǶʸ˹ʸɷŲŲŲűǴʵ̹ͺͻͼнѾѾѼϺηлҽҿͺɸȷοͼλϹкиͷεε϶ϸϸϺлͺͺͺ̹˸ɶǴƳɶɶʷʷɶɶȵȴɵʵ̷͸ιιιιɶɶɶʷ˸ʷƳðŲǴʷ̹̹˸ȵȴʶ˶ʵʵʵ˶̷͸ιιι͸͸˶ʵɲè¥¦·exgMaP6Q@&M<\"SB(_O5pVɼȻ˻ǵz|Yy\\:iL,rW9kMqíɶʷ̷ʴʲʲ˳˳˳˳̴̴˳ʲ˳͵иизϸ͸˴ʳ˲̳˱ɯʰȬƫȫǫŧʿźŹǻǮ˲δ̲ʰδ̱ɮ˯ͱ̰ƪÿ{{Ⱦǭ̲͵ɱȯ˲ʹʴʷʷ̹ͺλλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺλλλϼннѾѾѾѾнϼλϼϼϼѾѾѾҿҿҿҿҿѾѾҿҿҿҿѾоооѿѿѿѿѿѿͻͻμͻ̺˹˹ͻϽооϽμμ̺̺˹ʸʸʸɷɷɷɷʸ˸ͽν̼ʺɷȷɹ˹̼ͺλкѻйͶʳʶɶɶʷ˷̸̸̸ͶηηϷϷζ˶˳ʱʱɲɲʵʷ˺̻ɸ̹ͺʵɴʳɰƫǬūƮŭɱϷɳɳȵȵȵǴǴǴʴʴʴʴʶ˷̸͹ͻ̺ɷȶǴȵȵɳɳ˵͵͵̲̲ͳϷ͸̹̹˸˸ʷʷʷɶʷ˸̹ͺͺ̷̶̴̹˳ʲɳǱǱǱɶɶʷ˸˹̺ͻͺθ͵̳ʱɰɰʱʱʳ˲̴̵̶̶̳ͷжѷжζ̴ʴ˸̹ͻ̶̹͵Ϸжϵδͳδδͳ˱˱͵Ϸͷͷͷͷ̹˸ʷɶɶʷ̹˸ʷʷ˸ͺ˵̶ͷϸϸͶ˶ɳ̴˱˱ʰɲʳʳ˴˶͸λλ˸ʷʷ˸ʷʷ˸̹ͺλϼϼθθθηηη͸͸ͺ̺̺̹ͷͷ͵͵͵͵ͷͷ̹̹̺ͺͶ̵ɳɳʴ˶͹ϻ͹ι͸θͷͷͶͶ̶̶̶̶ͷͷͷͷϹϹϹθθͷͷͷͷͷͷͷ̶̶̶̶ȷʸ˹̷͵ʹͱ̮бβͳ̵̲Ͷ͹κ˵̶̶˵ɳɳʴ̶ͷθθθϹϹθθ̶̶˵˵ʴʴʴʴ˵˵̶̶̶˵˵ʴͷͷͷ̶̶̶˵˵ʴʴʴʴ˵̶ͷͷ˶˶˶˶ʵɴǲǲǲȳɴȳƱƱȳʵ̴̴̴̴θϹѻҼϼλͻ̺˹ʸʸʸȶȶȶɷʸ˹ͻͻͻͻͻͻ̺˹ʸʷ̸ιιιι͸̷̷˶˶˶˶˶˶ʵɵͻɸǶƵȶɷɷȶŲııŲƳȵʷ˸˹̹λлѼѺйѷӹӼһϺ˶ǴŴŴ˺ͼϾнкииѷϴϴ϶϶ϸϸллͺͺͺ̹˸ȵƳŲȵɶɶʷʷɶȵɵɵ˶̷͸ιιιιɶɶʷ̹̹ʷŲ¯ŲǴʷͺͺ˸ȵǳɵʵʵʵʵʵ˶˶͸ιιι̷˶ɴǱĪħ¥Ļ~|bwfLaP6SB(P?%WG-gW=|aø¹źɼŵ{wUrX7eH(lQ3hJq¬ɶ˸ʷʴȰȰʲʲɱɱ̴͵̴˳̴ζиϷ϶͸˶ʳʳ˲˲ɯȮȬǪǪɪɫŹĬʱƭéͳ̲ʰ˰Ͳͱçt|bqV{mSv\\rĽȮζɱƭʱʹ˲˸˸̹ͺλλλͺͺͺͺͺͺͺͺͺ̹̹ͺͺͺͺλλͺλλϼнѾҿҿѾѾнϼϼннѾҿҿѾѾнннѾѾѾѾѾҿҿҿҿҿҿоооѿѿѿѿѿѿѿѿѿѿͻͻμͻ̺˹˹ͻϽооϽμμ̺̺˹ʸ˹ʸʸɷɷʸʸ̹̼νξͽʺɹɺ˺ʻʹʹ̹κϺζ̴ʴʴʴ˵˷˷˷˷ιιιιιθι̷̵̳ʴʴʶ˷̹̹ɶλλɵůȯʯɮγʯǬȭȯǮǮʱưưƳƳǴǴȵȵȴɴɴɴʵ˶̵Ͷʷ˸ͺλͺ̹˸˷ʶ˷̸˷ʶʶ˷̹ʷʷʷʷ˸˸˸˸ʷʷ˸̹̹̹˸˶˵ʲʴʴ˵˵ʷʷɶɶʸ˹˹̺ͻͺͷ̶˵ʴ˴͵Ϸи͸ͶͷθικͺϹѹҹҹϹ̶˷̹λͽͺ̸ͷϹѸзϴϴееϴ̶̳̳ͷθθͺλͺͺ̹˸ɴɵ̷˶ʷʷ˸ͺʶ̸ϺлϺ͸˷ɴʲɯɯȮǰȱȱɲ˶͸λλ̹˸˸̹ʶʶ̷͸λϼϼнκκιι͸͸͹̹̼̼̼ͺ͹ͷεεγεͷͷ̹̹̺ͺͶ̳˲ʱʲ͵Ϻл͸͸Ͷ͵ʹ̳̳̳ʴʴʴ˵˵̶̶̶ϹϹϹϹθθͷͷϹϹϹθθͷͷͷǸȸʹ̸ζεͱ˯дϳ̳˲ʴ̸ͻλ̶ͷͷ˵ɳɳʴ̶θθθθθθϹϹ̶̶̶̶˵˵ʴʴʴʴ˵̶̶˵˵ʴͷͷͷ̶̶̶˵˵˵˵ʴʴʴ˵̶̶˶̷̷˶˶ɴȳǲȳɴɴȳǲƱȳʵʲʲʲ˳̶θϹкλλͻ˹˹ʸ˹˹ȶȶȶɷʸ˹ͻͻ̺̺̺̺˹ʸȶȵ̸ιιι͸̷˶˶ʵʵ˶˶˶˶˶ʶ̹ɷȵȵȷȷȶƴŲŲŲƳǶȷʸʷȶʷͺлѺӹӷӷҶϳɯºļ¯ɴͶϵгѴѴѴѴѶѸѺѺлϼͺ̹̹˸ʷȵǴƳʷʷ˸̹̹˸˸˷ɵ˶̷ιιϺϺιʷʷ˸̹ͺʷƳ¯Ƴȵʷ̹̹ʷǴǳɵʵʵʵʵʵɴɴ̷͸͸͸̷ɴǲĮ¥Ļz|dygOaO7UC+RB)\\L3n^EkżvqOnV4bH'fL+fGoɴʷʵǱëªƮǯŭƮ˳͵̴˳̴ζϷ͵ʹ˶ʵɲɲʱʱȮƬĨæĨǩħµ}jv\\zbn˽ĪƬʯͱͱ̯̯ʭÿvx^o_EbT9]O4aV:znTo¦δʰƭʱʹ̳̹̹ͺλλλλͺͺͺͺͺͺͺͺͺ̹̹̹ͺͺλλλλλϼнѾҿҿѾннϼϼнѾѾҿҿѾннϼϼѾѾѾѾѾнннҿҿҿоооѿѿѿѿѿѿѿѿѿоϽ̺̺ͻ̺̺̺ͻͻμϽϽμμͻͻ̺̺˹̺˹˹ʸʸ˹˹ͺ˻νϿϿξͽ̽;̼̽˹̹Ϻлиζ˵˵˵˵˷˷˷̷˶˶˶˶̷̷̷˶˴ʱɳȲȴȴȵɶǴ̸̸ǱŬȭ̯̯е̱ȭǬȯɰɰɰĮĮıŲƳǴȵʶʶʵʵʵ˶̷ͶηǴ˸ϼѾнλ̹̹λϼξ̼ʺʺ˻λ˸˶̷̹ͺιλϺ̷̹ͺ͸λ͸ͺ̷˵ʲɳ˵ͷθͺ̹ʷʷʸ˹˹̺̺̺˸̶̶ͶηилѼιιϺϹικͺϻиҹѻϻ͹̹̼ξξ̼ͺκмѻк϶ѸҷӸѶεʹ̶ͷθθλλλͺͺ̹ȴʶ̷̷˸˸̹λ˷̸Ϻлмκ̸ʵɱɯȮǭƯǰȱȱ˶͸ϼϼͺ̹̹ͺ̸̸ιιλϼϼϼмϻллϻϻϻμʻɻɹ˸˷˵ʹʹγγ͵ͷ̹̹̼ͺʹβ̳̳˳͵ιϺ͸Ͷ͵͵ʹβͱͱʱʴʴ˵̶̶ͷͷϹϹϹθθͷͷͷкϹϹθͷͷ̶̶Ⱥɻ˻κϺиϴдѵдʹ̳˷̸̺ͺ̹θθ̶ʴɳʴ̶Ϲθͷͷ̶ͷθθͷͷͷͷ̶˵ʴɳɳɳʴ˵˵˵˵ʴ˵˵ʴʴʴɳɳɳθͷͷ̶̶̶̶ͷ͸ιι͸͸˶ʵɴɴʵʵɴǲƱȳʵɱɱɱʲ˵ͷθϹϼλͻ̺˹˹̺̺ɷɷɷɷʸ˹̺ͻͻͻͻͻ̺˹ɷɶ̸ιιι͸̷ʵʵ͸͸͸͸ιιι͹˸ɷɶʷʹʹȶƴŲƳƳǴȷɸʸʷɷ˸͸йӹԸԷԷαȫ»éʭͯϱѳӴӴҵѶѸѺнϼ̹˸ʷɶȵȵȵɶ˸˸̹ͺͺͺͺ͹ʶ˶͸ιϺϺϺϺʷʷʷ˸̹˸Ǵıȵɶʷ˸ʷɶȵȴȴɴʵʵʵɴȳǲʵ˶̷̷ʵȳį©~j~lTbP8WE-UE,^N5rdJqþroLmU1fL)fL)jHqɲɳǰưƮǯĬǯζ͵̴˳̴͵͵˳ʱʵȳȱɲʱɰƬŨķb}lNp\\Cq]EvbJqYoɹȮ¨˰γ˯ʮʭq~mSaQ7VF,SC)UG,i]Cz_»δ˱Ǯ˲϶εθͺλλλλͺͺͺͺͺͺͺͺͺͺ˸˸̹ͺͺλϼϼϼϼннѾҿҿҿϼϼϼλϼнѾѾҿҿѾѾннϼϼѾѾнннϼϼϼѾҿоооѿѿѿѿѿѿооооμ̺̺˹̺ͻͻμμμͻͻͻͻͻͻͻͻͻͻͻ̺̺̺̺ͻλξνͿ˿ξͽ̺λлѼиϷ̶˶̶̶̸˷̷̷ʵɴɵʵʵʵ˶˵ʱȮǯưŲŲŲŲȵ̶̹ǯūɬ̯ˮ̱ʮǫƪȯ˲˲ɰưưƳƳǴȵȵʶ˸ʷʷɶ˶˶̵Ͷɶ̹ϼϼ̼ʺɹʺξξ̾ʼʼ˽ͽͺͶ͸Ͷιηιη͸Ͷιηιη͸͸θ̶ʴ˵θϹͺ˸ʷʷ˹˹˻˻̼̺˸ͷκϺϺϺллϺιι̹ͺ̺˸˸θϹмκͺ˻ͽͽ̼λмѻкззҹҹѸε̳ʴ˵̶ͷ̹ͺͺͺ̺̹ɵ˷͸͸̹̹ͺϼ͹κϼϼмκι̷ʲɯɯȮǰȱȱɲ̷ιннλͺλϼϻκϺϺϼλλλϻϻϼλϻϻϺμʻʻʹ˸̷ͶʹͲγγ͵ͷ̹̹̼ͺεбϳγͳͳ̵̵ͶͶζδϴϳϳϳ̳˵̶ͷθθϹϹθθθθͷͷͷ̶θθͷ̶˵˵ʴʴǺȺʺ̹κиѶҶѵѵ϶ε̸˸ʹ˸ͺθθ̶ʴɳʴ̶кϹͷ̶˵˵̶̶ͷͷθθͷ˵ɳȲȲɳʴ˵˵˵˵˵˵˵ʴʴʴɳɳɳθͷ̶˵˵˵˵˵̷̷̷̷˶ʵȳȳʵ˶˶ɴǲƱȳʵʲʲʲʲ̶ͷϹкϼϼμͻ̺ͻͻͻʸʸɷɷɷʸ˹˹ͻͻͻͻ̺˹ɷʷ͹ιι͸̷˶ʵɴ͸ιιιϺϺлϻɶȶʸ̺ͼ̻ɷƴŵƶȷɸʸ˹˹ʷͻλлһӷӶҵӳɩƿ}m~vaxp]vn[~vapȨ̬ϯұҳѴезйλλ̹ʷȵƳƳȵʷ̹˸˸̹ͺλλͺκʶ̷͸ιϺϺϺϺ˸ʷɶʷ̹˸ɶǴ˸ʷʷɶȵȵȵɵǳɴɴʵɴȳǲƱȳɴ˶˶ɴƱ­rpXeS;YG/UE,]M4seKv»¦Ŧ£l}kGkU.fN(jP+oKsȬǬ¼¼ſ¼ſȰ̴˳˳˳͵̴ɱȯȳǲǲȱɰɰūħȿƻj|mLiX:^J1_I2aK4hT<yeMgĸƫͲ˯ȬʭŨ»xnR`O5WG-TD*QC(_S9vlQxͳͳȭͲӷзθλλϼϼλͺͺͺͺͺͺͺͺͺͺ˸˸̹ͺͺλϼϼнѾѾѾѾѾѾѾλλλͺλϼнѾѾѾнннннннннϼϼϼλλѾҿоооѿѿѿѿѿооϽϽϽͻ˹˹ʸ˹ͻϽϽμͻ̺̺ͻͻͻͻͻͻμμμͻ̺̺ͻμμϾ̾˽˾ͽ̼ʺʺʸ̹κѼѼи̵̶̶̶̶̶̶͸Ͷʵʵɴʴɴ˵̶˶˲ɱȰưưŲŲŲ̹кθȰƬȮɬǪŪĩ©©ƭʱʱǮɳɳȵȵȵȵȵȵʷɶȵȵȴɴɳʳ̹λϼ̹ɶǴǷʺʺ˻ʺɹǹǹɻ̼ͷ͵͵̴̴̴̴̴̷Ͷ͸ι͸͸̷̷ѻθ̶̶θϹ˸ɶʷʷ˸˹˹˹̺̺̹θϻϻлι̸˷͹̸̹˸˸ʸȵɵͷκϻλ̹̼ͽϿͽ̼λнѽмϹηϸйη˴ȱǱǱ˷˷˸̹̹̹˹˹˸͸ιιͺ̹λϼϻϻϼϼϼλκ͸˵ʲɲɱȱʲɴ˵͸ϼѾѾϼλνнѼѼлϺϼλͺͺ͹͹͸͸͹̷̸̸̽˽˻ͺͺκ϶зεεεͷͷ͹̺͹εϳддϴͳ̴̴ηϷϷϷззѵзͷͷθϹкѻѻҼθθͷͷͷ̶̶̶̶̶ʷʴȵȲȲǱŷǸȷʸ̷θзѸѸззϸ͹̸ʸɶθϹθ̶ʴɳʴ̶кϹͷ˵ʴʴʴ˵̹̹ͺͺ̹ʷɳȲȲȲɳ˵˵˷˷˷̹̹̹˸˸˸ʷʷʷʷȵȲȲǱǱǲȵǵǵȵǴƱưů˵̶̶ʴȲǱɳ˵˵˵˵̶ͷθϼннϼμͻͻͻμμ˹˹ʸɷɷɷʸʸ˹˹˹˹ʸɷȶȵͺιι͸̵˴ʳɲ˵̵̷͸̹ͺͺͺȵȴʶλнμʸǴƶǶɸʹʹʹʹʷѿҿԾԼԺӶѴвħq{tZf^GZR;UM6f\\CzpWrĦʬϰѲггϴ϶ͷ͹̷̹ɵǴŲŲȵ˸λʷ˸̹ͺͺͺͺͺʶ̷͸ιϺлϺϺ˸ɶȵɶ˸̹˸ʷ̹˸ɶȵǴǴȵɶǳȳȴʵȴȳűŰƲȱɵʳǱŮ¾Ļƻ·vqYjV>[I1VD,\\L3tdKyŷɿƫǩ¤fzg?jS*gN%mT+sKrĲ̿Ũ¥˱ʲʲ̳ʹ̳ɰƭǰǰǰȱɰȭūæ¥ȿ·y}\\q`B^M/S?&UA)XD,]I1gS;vdLy`n˱ɮƫʮȬtZcS:[K4VF/N?*WK5k`JrͳϲȮγӸѸϹλϼϼϼλͺͺͺͺͺͺͺͺͺͺ˸˸̹ͺͺλϼϼҿҿѾѾѾѾѾнͺͺͺͺͺλϼннннннннннннϼϼλλͺѾѾоооѿѿѿѿѿооϽϽϽ̺̺ͻͻͻͻͻͻͻͻͻμμμμμμμμͻͻͻͻͻͻͻͻͽξξξξλͺ̹ͺ͹͹ͷͷηηη̵̳̳̳̳̳̳̳ͶͶηϷηζ͵̵˵ʴɳȲǱǱǱǱȲʴ̶̶ʲȰǯǯƮĬíĮǱ˵ͷθι͸̷˶ɴȳǲǱǴȴȵɵȵʶɶʶʷ˸˸˸˸ʷɷȶ˹˹˹˹˹˹˹̸̶̶̶ͷͷθθθ̹ͷ̹̹̹̹̹̹ͷͷͷͷͷͷͷͷɳɳʴʶʶʶʶʶȵȵȵɶʶʶ˷˷̸̸˸˸˸˸˸˸˸ͺϼннϼͺ̹ɹ˸̹ͺλϼλκ˷̸͹κ͹̸ʶɵλλλͺͺ̹̹ʸͺͺͺͺͺͺͺͺͺͺͺκκκκκʶʴʴ˵˵˵˸̸ϼнμλ̺̹˻ʸλϹϹϹϹϹϹϹθθϸйлѺѼѼμξμϼμϻϻϹθθθϸθϸκϸ϶зззз϶εʹθϹϹϹϹθͷ̶͹͹κϻммѽѽ͹͹͹͹͹͹͹͹˷˷˸˷˸˷ʶʶʹɸʸ̹κκ͸˶лϺϺι͸̷̷͸ͷͷ̶˵˵˵̶̶ѻкϹͷ˵ɳȲƳȸʼ̿ξ;˺ɶƳʴ˵˷˶˶̷͸κҿпνʹȸƶǷɹ˸ʷȶǴǴȵʵ̹ƶƶƶŵƵƳǳƲ˶͸Ͷ̵ɳȲȲɳȴʶ̸ϻϼноооͼʹɸʹ˼̻˹ʷʷɶɶʷʷ˸ͺͺ̹˸˸ʷɶʷ̸κϺηʹ˲̱Ͳͳ̳ɳ˶ͼο̻ǲǱʳ˶̹̹˸ʹ̻˺ʹʹ˸˸ʷɶͽҿн͹ͷϹӺ̲msnQe`Cd]AynRjĪͲз϶ѸҹҹϷϷϸϹл̸ʷȵƵųǶ̺ʷɶȴʶ̶θ͸̶͹˸ʷ˸κϻϻκ͸˶ȳƱɳ˵ͷθ̶ʴʴ˵̶ʴȲǱɶ˷˸̸ʷʶȲǱĮŬĮŬĬŬĬŨȽƹȻȹŴxlTlV>`J2V@)_K3mXɷìƭŪ˽^xa8jR&lQ$pU({Pv®ʺæĸxbfklmséǮǮɱʲŭ©èǬɬɬȫȽydxcFhS8mX=cQ9fV?bP8_M5fU;iY?rbHsYṴ̄ǭĩèæfhYDTD4L</L>3YK@h\\NsɭҴ̯ʭδҺҼϹ̶̶ͷθθͷͷͷͷθθϹϹϹϼλλͺͺλλϼнϼϼϼϼϼϼϼͺͺλϼϼнѾѾнϼͺ̹̹ͺϼнҿѾнϼϼϼϼннннѾѾҿҿҿннннннннλϼѾҿҿѾλ̺ͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμͽξξξϼλ͹̸͹͹ͷͷͷͷͷͷ̳̳̳̳̳̳̳̳ʹʹεεεʹ̳˲ɳɳȲȲǱǱȲȲȲɳ˵ʴȲǱǱȲʵȳƱǲʵ͸ϺϺʵʵʵɴȳȳǲǲƳǴǴǴȵȵȵɶʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸̸̶ͶͶηηϸκκ͹͹̹̹̺̺˺̹ͺθθͷͷͷͷͷʴ˵˵˵˵˵˵˵ȵȵɶɶɶʷʷʷ˸˸˸˸˸˸˸˸ͺͺλϼϼλͺͺɶʷ˸̹ͺͺͺͺͺλϼнϼλͺ̹ннϼϼλλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ˷˷˷˷̸̸͹͹ннϼϼͽͽ̼ͺ̹θθθθθθθϹϹййѺѺһѻͻ̻ͻͻͻͻκκκκϺϺϸϸϸϸ϶зззз϶εʹͷͷͷθͺ̹˸˸ͺκκκϻϻϻϻκ͹͹̸̸˷˷ʶ˸˸˸˸̸̸̹̹ͺ̹̹ͺϼϼͺ˸ϻκ͸˶ʵʵ̶̷ͷ̶̶˵˵˵̶ͷккθͷ˵ɳȲǴ˽;˺ʷȳǲȲȲɴʴʵ˶̷̹ʹ˺ɸȸǷȸɹ˻̹˹˹ʷʷʵɷȸǺƹǹȷɶɵɴ͸ιϷ͵ʳɲɳ˵űƲȵʶ˹˸˹˹ѿϽ̻ʹɸɸʹ˺˸ʷʷɶɶʷʷ˸ͺͺ̹˸ʷʷɶʶ̸κϺϸεͰαϲͱ̯ɱʶ̻ο̿ʻȳɰʳ̶̹̹˺̺̺˹ʹ˸̸̹˸˸ɹ̻ͼͺ˸̷κѻ϶ƭhz]~wZrüǿǯ̶θιѼѻѻηͳ̳˳˳ʴɵɶǴƴǴɷɶȵȴɵ̶ͷ̵̶̹̹˸˷͹κͺ̷̹˴ɴɴ˵̶ͷͷͷ˵˵˵˵ʴȲǴȵɶʷʷʷɶȲȲŭƮƮƮƬūéæǼöôo{fKhP8`H0XB+eO8r]ɷп«ȹ\\w`6lQ$lQ\"x\\-Syư˸̽z}_{hG}mLoNpQtT{]z¥Ǭƭǯǯŭê¨ƩȫǪƩźinSmX=jP7u]E{iQ|lSrbIiY@iY?gW=hX>tdJqèβɯŪèèkmaKXK;OA8O@;XKEeXOyhçϲ̮Ȫ˱ϵҼкͷ̶ͷϹθθͷͷͷθθϹϹϹϼλλͺͺλλϼнннϼϼλλͺͺͺλλϼнѾѾнϼͺ̹̹ͺϼнҿѾнϼϼϼϼннннѾѾҿҿҿннннннннλϼѾҿҿѾнλ̺ͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμλϼϼϼϼλ͹̸͹͹ͷͷͷͷεε̵̵̵̵̵̵̵̵ͶͶηηͶ̵˴˴ȲȲȲȲȲɳɳɳȲɳɳȲưůǱɳͷ˵ɳɳ̶θϹϹȲȲȲȲȲȲȲȲŲƳƳƳǴǴǴȵʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸̸̸͸͸͸ιι͹͹̺̺̺̺˺˺˺̹ͺθθθθθθθ̶̶̶̶̶̶̶̶ɶɶɶʷʷʷ˸˸˸˸˸˸˸˸˸˸͹͹κκκκ͹͹ɵɵʶʶ˷̸͹͹͹͹κϻϻϻκκѽѽмммϻϻϻͺͺͺͺͺͺͺͺλλλλλλλλ̶̶̸͹͹͹κκммннϼϼϼϼ̹ͷ̶̶̶̶̶̶ͷͷθθθϹϹϹ̺˺˺˺̹̹̹̹κκϺϺϸϸϸϸϸййййϸͷ̶˵˵˸̹̹̹˸˸θθθͷͷͷ̶̶ѻѻкϹθ̶̶˷˸˸̹̹͹͹κκ̹˸˸̹ͺλ͸˶Ϻллι̴˳̴Ͷ̶̶˵˵˵˵̶ͷкϹθ̶˵ɳȲǴ̼˾ʾ̽ʺʸɵɲȱɱʱʳ˳˵̵˵Ʋȵʷʷȶƴųƴȶɶʷ˸˸˸ɶǵȸȹɹɹʹ˸ʶ˶̷̷͵˳ȱȱʱ̶ȲȲȵʴɶʴʷʷϼλ̹ʷɶʷ˸˸˸ʷʷɶɶʷʷ˸ͺ̹̹˸ʷɶɶʶʷ̹ιεͲͰͰαˮʮɱʴ̹̻ʾȺȳȲʵ̶˸̹̻̺̺̺˸˸ʶʴɴʴǴȵɶɵȴȴ˷ͷεɰë¼}ȾëǱȲ̸ϻѻкʳƬʾп­űƳƳɶȵǳȴ˵̶ʳʴ̹˷˷̸̹θ̶ʴȱɯȱȱɲɲʳ˴ͷͷ˸ʷɶɶȵǴƳǴȵɶɶɶʴɳǯȰɱɱȮƬéø~wpx]mX=aI1]E-[E.kU>xcȶ̽ʾĵZwa8lT(kS%|a4X{űȸƸpnPlY8l\\;l\\;k\\=pcCynPqȭȬūūƮūī¨¨ŨƩŨħxpTkW<^I.hN5~fLjmy_wfLm\\BcR8_O5hX>~céжʲê§ppdNZM=PB9N?8TG?]PGriX{»ͱ˭ƨǭ˱ӽкθͷθϹϹθͷͷͷθθϹϹϹϼλλͺͺλλϼѾѾнϼλͺ̹̹ͺͺͺλϼннѾнϼͺ̹̹ͺϼнѾѾнϼϼϼϼϼнннѾѾҿҿҿннннннннλϼѾҿҿҿѾнλ̺ͻ˹˹˹˹˹˹˹˹μμμμμμμμϽϽϽϽϽϽϽϽλϼϼϼϼλ͹̸̸̸̶̶̶̶ʹʹ˵̵̵̵̵̵̵̵ͶͶηͶͶ̵ʳɳưǱȲɳʴʴ˵˵ȲȲȲưĮůǱɳ˵ɳǱǱɳ˵˵ʴɳɳɳɳȲȲȲȲŲŲŲƳƳƳǴǴʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸̸̸͸͸͸͸͸̸͹˹˹˹˹ʹʹʹʹͺθθθθϹϹϹθθͷͷͷͷ̶̶ʷʷʷʷ˸˸˸̹̹̹̹̹̹̹̹̹͹͹͹κκ͹͹͹ʶʶʶʶ˷̸͹κ˷˷̸̸̸̸̸̸ммϻϻϻϻϻϻ̹̹̹̹̹̹̹̹λλλλλλλλͷͷ͹κκϻϻϻммммнмѾѽͷͷͷͷ̶̶̶̶˵˵˵˵̶̶̶ͷ̹̹˺̹̹̹̹̹κκϺϺϸϸϸϸϸййййϸͷ̶˵̶̹ͺͺͺ̹̹θθͷͷ̶˵ʴʴθθθͷͷ̶̶˵˷˷̹͹κϻϻм˸ʷʷʷ̹˸˶ȳ̷ϺѼйͶ˳ɲ˴˵˵ʴʴ˵˵̶ͷϹθͷ̶˵ɳȲǴʺʺɺɸɷɵɳʱȯȮǭȯȯɱǯŭǯɲ˴˴ʴǱưůǱǴǴȵȵȵȵǵǷȸɹʹʹ˸ʶʵȳȳɱȰƯǰʱʹ̴˳ɱȰǯǯȲȲ͸̷˸ʷɶʷʷ˸˸ʷʷɶɶʷʷ˸̹̹˸˸ʷɶȵȵɵʶɳǯƩħŦǨåŨȮ˳̹ͺʼɹɶȴʵʷ˹̹̻ͻͻ͹̹ʶȲƮŮŮȲȴȲȲȲɳʴ˵ʱʱɱƮƻɿſůǱ˷ͷϹ˳¨ĵǲȵɵǴǳȴʴ˵ɴɳ˵ʴ˷̶ͷ̶ȲŭƿžĽĽǿìǰʴͷ̹ɶȵɷɷȶŲŲƳǴȵɶʴʴɱʲ˳̴ʰƬ¨ti}_uWxcH]H-]E-ZD,^H1p\\D~hɹ;īȾ_{h>p[.pZ+zc7Wy³ɺǹs}lNhU4fV5eU4dU6j]=wiLpĿ˰˰ƭƬȰɯŪé¨ħŨħ¥osbF\\H-S>#fL3jPu}poUjY?[J0[K1iY?~cƬҷɰƿsthPZM<PB7O@9SF>YLCf]Loʮ˭ŨĪȰӽѻθͷθϹϹϹͷͷͷθθϹϹϹϼλλͺͺλλϼҿѾнϼͺ̹˸˸̹̹ͺλϼϼнннϼͺ̹̹ͺϼнѾнϼϼλλϼϼнннѾѾҿҿҿннннннннλϼѾҿҿѾнϼλ̺ͻ˹˹˹˹˹˹˹˹μμμμμμμμϽϽϽϽϽϽϽϽͻμμμλͺ̹˸̶̶̶̶̴̴̴ʹ˵˷˷˷˷˷˷˷̸̸̸̸˷ʶȴȴůưȲʴ˵˵˵˵ǱȲǱưĮůȲʴʶȴƲǳɵɵɵȴ͹̸˷ʶɵȴǳƲŲŲŲƳƳƳǴǴʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸̸̹̹̹̹̹̹̹˸˹˹ʹʹʹʹʹʹ̹̹̹ͺͺλλλλͺͺͺ̹̹˸˸ʷ˸˸˸̹̹̹̹̹̹̹̹̹̹̹̹ͷͷͷ̶̶ͷͷͷ̶˵˵˵̶ͷϹк̶̶̶˵̶̶̶̶ͷͷͷͷͷͷͷͷ̹̹̹̹̹̹̹̹λλλλλλλλͷͷθθϹϹϹϹккккϼкнѻϹϷζζ͵͵̴̴˳˳̴̴̴͵͵ͷιιλιιιϹϹκκκκϺϺϺϺϺлллϻκ͹̸ͺͺλϼϼλλͺϹζ͵̴˳ʲɱɱǯȰȰɱɱʲʲʴ˵˵˸ͷθϹϹкͺ̹˸̹͹͹ʶȴȲͷҼҹʹȯǮȯʴʴʴʴʴ˵̶ͷθͷ̶˵ʴɳȲǴɸɸȶȴȲȰȰȮƬŪĩūƬƭêǭɭ˯̰ʰɯȱɲʳɴȳƱŲŲŲĲĴŵǷɸʷʶɵɴǯȰȱǰƭǮɱ˳˱ɯƬĪééĭĭ̵̵˶˶ʵʵʵ˶˸ʷʷɶɶʷʷ˸̹̹˸ʷɶɶȵȵȵư»Ĺɯ̷ͺ̼˻ɶȶɶɷʸʺ̻̻ʷ̸̹ɳū¦çɯɱȰɱ˳͵ζζȲ˵ͷ̶ɳưĮ«êéĬŭȲ˵ɳ˵˵ŭymfiowŻȱ̶ɵȴǳȴɶ˵ɴȲȲʱʴ̴ʲŭļļįʵͺɷǵʺʺǷĲıŲƳǴȵʴ˵ɱʲ˳˳ɯƬƿyh}ZlLwdDjU8T?\"ZE*[E-bL5uaImʺǭkyP}l@|j<oD_}´ɼży~oPgT4bQ3_N0_P3eW:oaFeɮ̱ɰɯ˱̳ƫé¨¨ŨŨħ¥ȿlo^BXD)P; cI0gNrztYfU9XG+`P6wgMoǮжɯ¨¨ũvvjPZM:PB7QC:TG?XKB`WFzeĨʭŨĪǯӽкͷͷθϹϹθͷͷͷθθϹϹϹϼλλͺͺλλϼѾѾнϼͺ̹˸ʷ̹̹ͺͺλϼнннϼͺ̹̹ͺϼнѾнϼλλλλϼнннѾѾҿҿҿннннннннλϼѾѾѾнϼλλͻͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμͻμμμλͺ̹˸˵˵˵˵˳˳˳˳˷˷˷˷˷˷˷˷̸͹̸̸˷ɵȴǳůǱɳ˵̶̶˵ʴưǱȲǱưưȲʴʶɵȴɵ˷̸˷ɵκ͹̸ʶɵǳƲűŲƳƳƳǴǴǴȵʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸˸̹̹̹̹˸˸˸˸ʸʸɸɸɸɸɸɸʷʷ˸̹̹ͺͺλλλͺ̹̹˸ʷʷ˸˸̹̹̹ͺͺͺͺͺͺͺͺͺͺͺͷͷ̶̶̶̶ͷͷͷ̶˵˵̶θкѻккθͷͷͷͷθʴʴ˵˵˵̶̶̶˸˸˸˸˸˸˸˸ͺͺͺͺͺͺͺͺͷͷͷθθϹϹϹккккϹϷϹϷϷϷϷζ͵͵̴̴͵͵ζζζϷϷϷιιιιιιϹϹͺκκκϺϺϺϺϺлллϻκ͹̸ϼнннϼλͺ͸ζζ͵̴˳˳ʲɱɱʲʲ̴͵ζϷϷ˵˵̶̶ͷͷθθѾϼλϼмϻ͹ʴ˵ѸռӺ̴ȭȰʲɳɳɳɳʴ˵̶ͷͷ̶̶˵ʴɳȲȲ˸˸ɵȲƮéè¦ĩȬȮƫ¥¢¢¢¥ƪɭʱɲɲǲƱıð¯óŵȷɶɵȳǲʲ˳˴ʳȯƭƮǭǫŨæ¦¦ũȬ˱ͳ̵̵̵̷˶˶˶˸ʷʷɶɶʷʷ˸˸˸˸ʷɶȵȵǴɳywy|·ĩʴ͸˺ʹɸɶȷɷɹʺ̻ͼȵʵɳĬĽ¹»þ¨ȮζҺӻʴϹѻϹͷͺͺ̶ʱŪéūƮƭůǱǱɳɱzcsS~nLsOxV`zʰζʴɵȴɵɶʷɴȳǯɰʲɱësqmklvļǲͻɷǷʺʼƶĲıııŲǴɳʴȰȰɱɱǭĪžwdvTwdDo\\<eP3T?\"YD)\\H-gS:zhPsʻȮæüiZV]pķƽü~vWjW7aP2]L.^O2aS6eW<}rVw¼Ǭȯɰ˲˲ǬĪééƩƩŨħȿmsbF\\H-R=\"`F-z`Ei}z]o\\>bQ5qaG|aū̲ɯǭȮȫmpeITH2L>1N@7PC:PC:ZQ@umX|ŨĪĬȲҼϹ̶̶ͷθθͷͷͷͷθθϹϹϹϼλλͺͺλλϼннϼλͺ̹˸˸˸̹̹ͺλϼϼϼнϼͺ̹̹ͺϼнннϼλͺͺλλнннѾѾҿҿҿннннннннϼϼѾѾѾнλͺλͻͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμͺλλλλͺͷ̶˵˵˳˳˳˳˱˳˷˸˸˸˸˸˸˸ͺͺ̹̹ʷɶǴƲưȲʴ̶̶̶ʴɳůǱɳʴɳȲɳʴʶʵʵ˶͸ι͸̷̷˶˶ʵɴȳǲƲƳǴǴǴȵȵȵɶʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸˸̹˻˻ʺʺɹɷɷɸɸɸɸɷɷɷʷȵɶɶʷ˸̹ͺͺλͺͺ̹˸ʷɶɶ̹̹̹ͺͺͺλλͺͺͺͺͺͺͺͺͷ͵̴˳˳̴͵͵̴˳ʲʲʲ͵ϷиҺѹϷ͵̴̴̴͵ɱʲʲʲ˳˳̴̶˸˸˸˸˸˸˸˸̶̹̹̹̹̹̹̹̹ͷͷͷθθζζииϷϷζδ͵͵з϶϶ε̴˳ʲʲ˴˴˴˴̵̵̵Ͷ̶̶̶̶ͶͶ͸θθθκκκκκκλϼϼϼϼλ̹˸нннн͹̸ʶʵζδδͳ̲̲˱˱ͳͳͳδϵϵжж˳˳˳˳̴̴̶̶нϼκκϻκ˵ɳȲ˳˳ūž½Ȯɱɳɳɳʴ˵̶ͷ̶̶˵˵ʴɳɳȲɴȴưë˽ƶ³ĹĨþĹƼůȳǴıñƴɶʷɵȱǰ˳͵̳ʱŬſü»ú¹¹ƽæʭͲͱͳδδͶͶ͵ͷ˸ʷʷɶɶʷʷ˸˸˸ʷʷɶȵǴȲȱƿ|h^]_dtɾǯʶ˸ɸɸɸȹȸɹʺ̻ͼȵȴĬ||{»ǭϵй˵кѾͺ͹нҿϼʴīĭǱí­ưɳȰſruYteFqa=xiBoKzWtɭ˱̶ʴɵʶʷ˸ʷȳǯȮɯūvhtTtTrRzoQ{pRz]o}î̺ɷǷ˽˿ŷųııııƳȲɳƮƮƮŭéƿtbsQtaAkX8dO2VA$UA&^J/mY@rXxȼȾƬæſvrx÷Żľ½~am\\>bQ3_N0`Q4`R5]O4odHw\\sèȭɮȭƬūĪĪǪȫǪƩowfJaM2U@%]C*rX=z[vzbnP}lP}cz¸Īɯʰ˱ǭæbmbDTH0M@0OA6M@7I=1RI8f^Ihý¨ůɳѻθ˵ʴ̶ͷͷ̶ͷͷͷθθϹϹϹϼλλͺͺλλϼϼλλͺͺ̹̹̹˸˸̹ͺλλϼϼнϼͺ̹̹ͺϼннϼλλͺͺλλнннѾѾҿҿҿннннннннϼϼнѾѾϼͺ̹λͻͻͻͻͻͻͻͻͻͻμμμμμμμμͻͻͻͻͻͻͻͻͺλλλλͺͷ̶˵˳˳˳˳˳˱˳ʷ˸˸˸˸˸˸˸ͺͺ̹˸ʷȵǴƲǱȲ˵̶ͷ̶ʴɳůȲʴ˵ʴɳɳʴȴȳɴʵ͸ι͸˶ȳȳȳȳȳȳȳǳǴǴȵȵȵɶɶɶʷ˸˸˸˸ʷɶȵ˸˸˸˸˸˸˸˸˻˻˻ʺʺʷɷɷɸɸɸʷɷɵɷɷǴȵȵɶʷ˸̹̹ͺͺ̹˸ʷʷɶȵ̹̹ͺͺͺλλλͺͺͺͺͺͺͺθζ͵˳ʲʲ˳͵ζ˳ʲɱȰɱ˳ζϷҺиζ˳ɱɱɱɱɱʲʲ˳˳̴̴̴̶˸˸˸˸˸˸˸˸˸˸˸˸˸˸˸̶̶̶ͷͷ͵ζζижϷδͳͰ̲˱γεʹ̳ʲʲɱȰǰǰǰȱȱȱȲȲ˵˵˵˵̵̵̷̷θθͺκκκκκλϼϼϼϼκ̹˸нлнϺ̸ʴȴǱδδδͳͳͳ̲̲ɯɯɯɯɯȮȮȮ˱˳˳˳˳˳ʴʴͺ˸ʶʶ˷ʴȲŭ¼ü»ȰȲȲɳʴ˵̶ͷ̶˵˵ʴʴɳɳȲűĮȼó||~}topu|©ȱɴǵĲ¯ıǴʷ˷˶ɲǰ˳̲˲Ǯſúæȫͱβδϵηηζθ˸ʷʷɶɶʷʷ˸˸˸ʷɶɶȵǴȲȱŻp{[~qN~pMrMxUfƸŭɳɵɶʹɸɹȸɹʺͼλʶȲſ~jb^}\\ak{žȬͳɱϹϼʷʷϼϽ̵ū«ɱ̶Ǳįįůɳɱƿp~pSpa@m^7vg>~nJ{XsȫȮε˵ʶʶ˸˸ʷɴȰɯɯéfxqUo`?ob@obBnaApbEwlPy_l˸ɷȸ̾˿ĶƴŲıððŲǱȲŭĬëªſƿr_qOq^>hU5bM0UB$S?$\\K/o^Dx^~Ƽüé¥åƤßùƼŽſ½dm\\>aP2]L._P3^O2UG,cX<ocI|a~ýŪƬéƬūĪūȫɬȫǪæpxgKdP5VA&[A(mS8nOjufahzĺƬɯ˱ʮç}bshH\\P6WJ9XJ=SG;L@4LC2[S>|u[Ųɶкͷʴʴ˵̶̶˵ͷͷͷθθϹϹϹϼλλͺͺλλϼͺͺͺͺͺͺͺ̹˸˸̹ͺͺλϼϼнϼͺ̹̹ͺϼннϼλͺͺͺͺλнннѾѾҿҿҿннннннннϼннѾнϼͺ̹λ˹˹ͻͻμϽϽϽμμоϽμͻ̺̺̺̺ͻͻͻͻͻͻͻͻϼϼλͺ̷˶˶ʵȱȱɲʰʰ˱̴̲ʴɶɶȵǴǴȵɶʷʷȵǴǴǴǴȵȲȲɳʴʴʴɳȲǱȲȲɳɳȲǱǱɳɳɳɳȲȲǱǱĿĿ¬ĮůůĮɶɶǴƳƳǴɶɶʷʷʷʷʷʷʷʷ˸˸̹ͺͺͺ̹̹ʺʺ˻̼̺˹ɸɶǴɶɷȴȴʴɵǳɴɴɴʵʵʵʵʵƱ̷͸ȳƱʵ˶ȳʷȵ˸нϼʷ˸нȵλнͺ̹λλͷʳδ̲ūĪȮɯūūé¨éƬʰͳɯƬé¨éūūūǭɯ˱ʰ˱̲˱ȱҼ̹˸ͺʷƳʷҿ̹˸ʷɶʷ˸̹ͺιι͸͸ͶηϸѷϵджͱȬħ¦¥ǬǬƫŪé¨ƿžžǽŻĺĺǻȾêʱʹʱʱεйͶлкϹθͺͺϻϻλλ̺̺˸˸˸˶˶̵̸ͷ̶˲Ǳƭɯʮ̰̰˯ɭǫũũ¦ƿü»»ĨȮ̲ͳ˱ɯȱɲȵȵǳȴͷθį{sqtļ̶˵íɳͷʴ̶ưȲʴʴȲǱȲɳưǮ¶|mc_bfrtfZyU{X\\bwƼįǵɷðŲǴɶ˵˴ɲɱɰʹ̳èzrlho¥ɮʯ˱̴̲˳˵ʴǴȵɶʷ˸̹̹̹˸ʷɶȵǴǴƳǱǭȾi{nNseBtdBvfB}mI~[zõéưǳʸ̻˺ʸɷȸɹ˸̹ǳĮotTuhHqdBg]:ja@wlLeũʰŮɴλλ̹ʷʺ̺ȳȱǰǯưĮî­ưưŭĽjykNn_>k\\5o`7xhDzWuƩɯε̶̸˷ʷ˸˸̷ȱéūƿ~htjOrb@j\\9eV5dW7fX;mbFu[qǿǴų˻ξ̽ͽ˹ȵƳƳȵȵɳȲǯƮƮǯǭĪĽp{W|lHvcBkX7_L,XE%_L.dS5whKkĺ¼ťɧɤŞšãsq`DcT7`Q4]M3_O5WI.\\Q5_T8ofIgĿçȫƬĪéūʭͰˮɬ¥nsbFbN3YD)[A(eK0fE_vuvêɯʮƪçæǾye{XwlPi\\IXJ=K?3G;-JA0RJ5jbKnƳθͷ˵ʴɳɳʴ˵θθθϹϹккѻͺͺͺλλϼϼϼλλλλλλλλ˸˸˸˸˸̹λλλλλλλλλλϼϼϼλλͺͺͺλϼнѾѾѾннѾѾѾѾѾѾѾѾλϼнѾнλ˸ɶ̹̺̺ͻμμϽϽμμͻμμͻ̺̺̺ͻͻμμμͻͻͻͻͻλͺͺͺ̷˶˶ʳɲɲ˱˱˱˱˱˱θͺ̹˸ʷɶʷ˸ǴȵȵȵɶɶʷʷʴʴʴɳɳȲȲǱɳɳʴʴʴɳȲȲɳǮí©¾ƭɳ˵ʷɶȵǴǴȵɶʷʷʷʷʷʷʷʷʷ˸̹̹ͺ̹̹˸ʷ̹˻˻˹˹˸˸˶ʵʵɵȲȲʱʱȲȲȱǲƯŰƯƱƯįɲʵŮîƯȳŰ˸ɶ̹нϼɶɶͺɶ˸˸ǴǴʷɶǱǰ̲ʰūéūĪƿƿƿžƿĪƬȮĪüüƿ¨ĽūȮ˱ͳͳ˴ͷɶɶͺ̹ɶɶͺ̹˸ʷɶʷʷ̷̹̹˶ʵʳ˴̲̲˯̰ʮǫ»~īʱзй̵ϺϺϹθͺͺκκϼλ̺ʷʷ˵̷ͶͶδʹ˲ɰŪɿŻĽƿƿžüƬȮɯɲʳʷɶǳǳ˵̴ufz\\wY}]pʴʴĮɳ̶ɳʴůǱʴʴɳǱǱǯìêɿn{\\pOzjI}mLsR_v|h{W|pJ{mH|nIvSd~ǼîƳƳðıŲȴɲɲɱȮȯʱȭľwevVuStRzXmøȿɮɮ˱˴̴˵ʴʴǴȵɶʷ˸˸˸˸ɶɶʷɶȵǴƳưʰjzmMpb?o_=p`<yiE{Xx´éưȴ̹̹˸ʸȶɶɶ˸˷ímpSrcDm^=eX6e[8peE|\\|ĩ˯Ȯ˴θͺ˸ʷ˻ϼϹζ̴˲ǱůŰįĮĬìĺexiJm]<m[7o`9xhD{Xxǫʰͷͷ̸̸˸˸̷̹ȱĪǭéx{`yiGo_=gW6dU6eV9l^ArXmȵƴ̹ͽ˺ͼʸȵǴȵʷ˸̶̶ǯƮŭŭūĪĽoyU{kGvcBmZ9dQ1_L,bQ3m^?wZyžĿľ¥ǩ˩˧ȣğĢĦĿvraEaR5]N1[K1]M3UG,[M2VK/dY=zpUsƿƪƪƬƬūūƩƩƩƩǾhn]A^J/WB']C*jP5v^<xVq}ŷŪɭū˱̰ƩȽĹwri|o\\cVFRF8MA3JA0OG2`XAx^°ɷϼϹθ̶˵˵̶̶θθθϹϹϹккͺͺͺλλλϼϼλλλλλλλλ̹˸˸˸˸̹ͺλλλλλλλλλϼϼϼλλͺͺͺϼϼнѾѾѾѾѾѾѾѾѾѾѾѾѾλϼнѾнλ˸ʷ̹μμͻμμϽϽμͻͻ̺̺˹˹̺̺ͻμμμμμμμμμнϻϻмϻϻθͷȲʱʱʱʯɮȭɯ˵ʴʴʴɳɳɳȲǱȲɳɳɳɳɳȲǱǱưưưǱǱȲʴ˵˵˵ʴɳȲȲª}txz«ʲ˵ɶɶȵȵɶɶʷ˸˸˸˸˸˸˸˸̹̹̹̹˸ʷɶȵμͻ˹ɶȵȳɴʳθʹ˲ɮƬūūƫêɾǽƻƼȽɿ¬ȯɳȯưɰʴɲʴɶ˸λͺʷʷλϼλʷǴɶͺ̹ȲƬƫĩȾĺ¸¸ù¸Ǭʯ˰̲ʴǴȵͺλ˸ȵȵ̹˸ʷʷʷʷ˸˸˶ɵʴ̶Ϲз̳ȭɿú}y}qjikmnmxĩϴѸεϸηι͸ͺ̹̺̺ͺ̹ʷɳǲȱɲ˱ȯƫƽ~sieglpyȾŪɰ̳˷ʶƳƳɴɲȽ}i}rTviItgGzmK_wưʴĮɳ˵ưǱíưʴ˵ɳǱůŭŭūçúntUufEn^=o_>teDsRn¹þp}YxkHqc>o_;vfDpOhùƱǴƲðĮĮůƯƯǭǭʱ̰ɮ¨pvZteFugDvgF{nL`|ȭɰʳʳ˵ʷɶȵȵȵɶɶɶɶɶɶǴȵʷʷʷȵŲĮʳjxkKk^;hZ7hZ5seBwTvĬǱɵͺ̶̹ɶȵȴɵʶ˷¬ªl|mPn]?hW9aR1_R0h[;~sSwƫͲ˱̵ͷ˵ȴȴ˸ϼҼкͷɳǳƱŰŰíë¸~ateFk[:m[7n^:wgE{Y{Ȯ˳θκ͹͹̹̹͸͸ɲŮȱƯƻypPubBhU7cR4bS6hZ=}oUkʴƳ̸λʷ̹ȵǴƳǴʷ̹θͷɱǯĬëé¨žmyRyjCuc?o\\;kX8iV6p_AsTrż¥¤¨ŨʬͭΫʨǣ¢åuo_E_O5\\L2[K1^N4UG,ZL1TI-]R6laEy\\ĻŨĪūūéæ¥ħŨ}`gV:YE*VA&bH/u[@pQe~Ⱥǫ˰ɯƬ̲ͱħĹ}~hi\\KRF8J>.KC0ME0UM6jbKoʸϼϹθͷ̶̶̶̶ͷͷθθθϹϹϹͺͺͺͺλλλϼλλλλλλλλ̹̹˸˸˸̹ͺλλλλλλλλλϼϼλλλλͺͺϼнѾҿҿҿҿѾҿҿҿҿҿҿҿҿλϼннϼλ̹ʷ̹ϽϽμμϽϽϽμͻ̺˹ʸʸʸ˹̺ͻμμμμμμϽϽϼμϻмммϻθͷɰʱɰɰȭǬƫŬŮŭůǯɳɱɳȰɳʲʴɱȲƮĮíííííůǱɳʴ˵˵˵ʴɳȲưƮĽ|k}b~w[wmRmfJvlQyrV{`m}ĺū˵ɶɶɶɶɶɶʷ˸˸˸˸˸˸˸˸˸̹˸˸ʷȵǴƳнλ˸ɳǲƯƯǭҹ̱ƫħɾźźǼȾèǬʯͲϵǲǴȵɶɶʷλѾѾϼʷǴ˸Ѿϼɳ©ɿ~yojiijx}ŻŪʰʵȵȵ˸ͺ˸ȵƳ˸˸˸ʷʷʷʷʷƲǳʴϹӺ϶Ūǽud}\\`jur|dpYxiRvfOueLrdI{pTgŪ϶Ѹηηι͸ͺ̹˹ʸ˸̶˵ɱƯĪ¨Ƽ}}}{m|_|sVypSzqT|sVz]eqŻƭʹ˷ʶƳǱɲɲɿx~`xkKrcBo`?seBvTmȲĮȲɳĮĮůʴ̶ʴǱůĮĬĪƬçwxXvgFo_>m^=o`?{nLiźħ¿{b~pMtd@o_;q^=scAuV|ùʲʴƲưůĮŮŮƯȮȮʮ̰ʰȮuuZvfExhFwgFxiHxYwȯǱɲɴɶɶȶȵɶȵȵǴǴǴǴȵŲǴɶ˸ʷȵŲĮȱgtiIh[9eW4dV3n`=sQvĬȴʷͺ̶˳ɱȲȲȴɵʶůŰȽmziOkW<dQ3^M/ZK,`Q2viIoĪͲ̲ͳ͵ʴưƲʵϺкͷʴưƱŰƱǲĮĬ¨z[scBjZ9kX7m];veGz]ĺɲ̶κκκϻλθ͸͸ɴƯȳǰuWubDfS5cO4aP4gW={mSkĪʳȲͷκ˶͸ȵƳŲƳɶʷ̶˵ɱǯëªſĽnyRwhAsa=p^:o\\;q^>qSkú¨Ǫʭ̮̬˫ɧþþniY?^N4^N4_O5`P6VH-[M2XM1^S7f[?tiMlż¹éæħħæwZcR6WC(WB'kQ8jOpƳ̽çǬǭéɯ̰ʭɾŻükobOTH8G;+KC0KC.ME.[S<{u_üƴ̶̶̹˵ʴʴʴʴͷͷͷͷͷθθθ̹̹ͺͺͺλλλλλλλλλλλͺ̹˸˸˸̹ͺͺͺͺͺͺͺͺͺͺλλλλλλλλϼнѾҿҿҿҿҿҿҿҿҿҿҿҿҿλϼϼϼϼλ̹̹̹ϽоϽϽϽϽϽμͻ̺ʸʸɷɷʸ˹̺ͻͻͻͻμμϽϽϼ˹̸͹͹˵ɳǱůɰȯǬŪè§§ƿƿǿéƯɯȱǭǰȮǰȮǰǭƯŮĮĮůưǱȲʴʴʴʴʴɳǱůĮ«Żm}tWrgKkbEf[?aX;cX<g^AshL|_vǼƫɴɶɶɶɶɶɶɶʷʷʷʷʷʷʷʷʷʷʷʷɶǴƳŲλθ̷˴ɲɯƭƫǪǾzsmigkrǾŨʮȳɶɶǴǴɶͺϼ˸ɶƳıȵ̹ȵù|tprt~¹rg|_vY|sVy\\{^i{ƽƪ˶˸ɶȵȵɶȵǴ˸˸˸ʷʷɶɶȵïűɳ˵ȯǽym}^{rQ{rQ\\o¾þz}dyiPo]EiY@cU8g\\>tiK~`{©ʹ̶̶͸͸̹ʹɷȵͷ͵̵ʰĪü}vvx~zk}^|sTvmNsjKsjKxoPxYh~ɿȯʶʶȲȲ˴̵©rvYsdEo`?n^<n^:~lH_¼ů¬ǱǱíĮ¬ưʴ̶ʴǱůĮ©§ūƪwvVqdDl]<j[:iZ;sfFc·ȾĪhsPweAr`<o[8n[:|mNuȰȲĮȲǱǱǰǮȮɯɯũȬɬȫr~pUtcEueDscBqbA}nOnȼǮưȳȵȶȶǷȵȵǴƳŲŲƳƳǴıƳɶʷʷȵŲĮĬ»eqfHdZ7cV4cV4k^<rPvůɴʷ̹˳ʰɯǯȯǱȲɳǱȳʿjtcIdP7]I.\\K/WH+[L/m_BfŹŪʰ̲͵˳ɰǱ˴ϸ̶ʴȴǲƱǲɴʵưƮé{wXqa@iY8iV8kZ<tcIz`źʵʷ͹λϻϻϹϹ͸̷ȴűǵİİǺtYt_DeP5cO6bQ7gW={mSléʰǯʹͷ˴̵ʷȵǴǴȵɶʴɳɱƮëſľüoxQuf?p^:n\\8q^=ubA^wȿſþ¿ƿĨǫȫɩɩɩĤãƿž¦¦|bbR9\\L3_O6^N5^N5RD)WI.XJ/^P5bT9i^BvZ{ūýſħŨtWbQ5YE*\\G,v\\C|`̽æŪǭʰ̴δ˯ĥöwy}ʾzn|o\\`TDNB2IA.H@+IA*VN7smW²ɶʴ˵˵˵˵˵˵ͷͷͷͷͷ̶̶̶̹̹̹ͺͺͺλλλλλλλλλλͺͺ̹˸˸˸̹ͺͺͺͺͺͺͺͺͺλλλλλλλλϼнѾҿҿҿѾѾҿҿҿҿҿҿҿҿλλϼϼλλͺͺ̹ϽоϽϽϽϽμͻ̺˹ʸʸɷɷɷʸ˹˹˹˹̺ͻͻμμϼμκκ͹ʴư¬êƼùüƿ¦ūƬƮǱȲɳɳɳɳȲʴʴɳȲưĮ¬eujJg\\>cX8bW9aV6\\Q3^S3i^@tTtɾƩǰȵȵɶɶȵȵǴȵȵȵȵȵȵȵȵȵȵɶȵȵǴŲŲɳʲ˴ͳ˱ǫȿzxupt|}ynewVvmNpgFqhIwnM{\\k|žŮʷ̹ʷȵɶɶǴɶʷȵŲı¯~rkgipx¹Ǿúwiz]{rUqhKneHtkN}`p~üįȵɶƳŲǴʷɶʷ˸˸˸ʷɶǴǴɵ˷ʴĮuhz[}tUwnMvnJxTgĥƨȫʭˮɬƪũʰɯé´i~lTrbHfX;cX8g\\>shJ{_wê˵̶͸͸˺ɸȶƳкϵ˱Ĩ|ljlow£äĥŦŦƧȿúwj`yZzqP{rQvWbwù©ʶʶȲȲ̵δªouUqbAqa?r`<m[7xf@zWĮưíůĮǱ˵̶ʴȲǱưȯŬȭʭx}rTm`@iZ;fW6eX8pcCbĹĮhoNr_>mY6nZ7lY8|lKs¨īíɳɳʳʳʰʰʰɯƪɭɬǫȾmyiOn]?p]=mZ:kZ<ziMnȼůűǴǶȸǷƶƶǵƳıðıŲƳǴıƳǴɶɶǴŲı~alcDbW7cV6eX6l_=~sSyǰɶȶɶʰʭɬƬǬȯȲȲîİɽ}gp\\D_I2YE,_K2YH,YJ-eV9~nTqǽéȰʲʱʱ̳ϸʴʴʵɴɴʵ̷͸ưƮéwsTo_>hX7gS8hW=q_Gw`ƻʷʷ̹ͺκϻϹθ̵˶ɷǵǵñʿűƹrZr\\DcM5fP8gS:hW=zjQjƿƬĪʯ˰ȯɰͷʷǴǴȵɶɳȲȰƮëſ¼lvOsd=m[7m[7r_>vfDa|øþüȾ§ũũŨƩȨȨȨæũĨsY^N5\\L3_O6[K2ZJ1PB'XJ/ZL1[M2^P5eW<shLfſýſæsVdS7\\H-bM2fMrǶũêū˲зϵũtms{{wvwnshV]R@KC0H@+JB+YQ<ohUs»ȵʴ̶ͷϹϹϹϹͷͷ̶̶̶˵˵˵˸̹̹̹ͺͺͺͺλλλλλλλλλͺ̹˸˸˸̹̹̹̹̹̹̹̹̹̹ͺͺλλλλϼϼλϼннѾѾннѾѾѾѾѾѾѾѾλλλλλλλλ̹μϽϽооϽμͻ̺˹˹ʸɷɷȶɷɷɷɷʸʸ˹̺ͻμλμκͷʴưŻ¸|y{~~ýſíưȲɳȲǱ̶˵ʴɳǱĮ¬exkIh[;aT2aT4bU3^Q1]P.fY9rPuåŮƳǴȵȵǴƳŲǴǴǴǴǴǴǴǴƳƳǴǴǴƳƳŲįƯȱȮ¨sf`cfen{{r`~uTvnJofEmeAqhG{sO}\\ewðͺϼϼϼɶ¯ɶͺͺƳüoc}^`fo}ƽ£ŦƧŦĥŦ£ƽ{j`tkLjaBg^?qhI}tU`tȵŲðƳʷ˸ʷʷ˸˸ʷȵǴƳ͹̸ư·r{`~uXqhIsjKxoNyUezĠбϱαͰͰ̯˯˯ǭūʺ}zbxhNk]@fY9cV6hZ=rgK~bǽʴ˵͸͸˺ȷƵŲηʰykb~]`itɽɥȧȧȧɨʩ˪˪ǦŤ¹zulijsŻ§˸ʷȲȲʳ˱˿qtUqa@qa?q_;lZ4vb=vTýý¬ůĮǱưɳ˵̶ʴɳȲɳͶȯʮˮx|qSk`@fY9dW7eW:qcFeŻéİĿh|kMo\\;iU4nZ7n[:oNtľ©ƯȲɳ˲˲̲˱ɭȬƪɭʭũĺjxhNmZ<lY9hU7hW9{jNq˿ĮűǴƵǷƹƸŷųı¯¯ðıǴȵŲƳƳǴǴǴƳŲĿz^h_B_V5aV6cX8laAuU{¸ɴɶǵȴˮʬɪǪƫǮǱȲƹ{eo[C`J3[G.bN5\\K1YH.\\L2k[A~pUjv¨ƫƫɭʱʳʵʵʵɵɵɴʵůŭs~oPk[:hU5eQ8eS=o]IvcǼʷɷʷ̹͹ϻϹͷ˴ɴʸȸǷñʿųŸq[sZDdN7iS<kW?hV>wgNeĿŨȪũƪǱıððŲƳǱưƮŭëªſerKpa:kY5lZ6rb@yiGdǼĢ¡£¿»ǽ§çæŨǪȫȫçêz{mS[K2]M4`P7\\L3]M4]M3k[AqcHgY>bT9gY>oaD{mPgý¾tWfU9`L1fQ6mT}ϼ;ŨūĬůǮȮm`_hurtyotiWYQ>PH3QI2^VAibOwp^ŲȲ˵ͷкѻѻѻ̶̶̶˵˵˵ʴʴ˸˸̹̹̹ͺͺͺλλλλλλλλλͺ̹˸˸˸˸̹̹̹̹̹̹̹̹̹ͺͺͺλλϼϼϼͺͺλϼннϼϼннннннннλλλͺλλλϼͺμμоооϽμͻ̺˹˹̹ɷȶȶȶȶȶȶɶɷʷ˸̹ͺͺưůĬǻ|trswysoorwxtnhgffjpv|·ǿĭǰǰƯ͵͵̴ʲȰŭëźotTm`@bU5`S3aT4cV6aT4i\\<vV|ƹťŧĭưǱȲȲǱưůƳƳƳƳƳƳƳƳıŲƳǴǴǴƳƱìŪƫævk^xTuR[cgtzlbypOphDia=jb>nfBvnJ~Zl¼̶ͺðƳ˸˶whvYzqR}rT~_lzú¥ħǪɮ˰ʯȭǬƩǪǪħú|pwZpgJe\\?g^AlcFtkL}`uƳŲðƳʷ̹ʷʷ˸˸ʷȵƳưƲĮƻuy^ynRulOsjKypQ|[j{áήӶѶγʰȮȮɯʰʹǯìŮĭ²}}cl^AcX8^S5`U7i^Bv[Ⱦʴ˷͸ͺ̹ȷŴįʱætbwW|rO]fuùǣɦǨǪǪǪǪȫɬɬɬȫǪæǾ»§ƪ̹ʷȲǱɲȱƼopQj[:k[:lY8fT0p^:rQ|ĮĮɳȲʴ̶̶ʴɳʴ˵ʳêĩƬv{pTm_BdV9bT7dU8oaD~c·Ⱦëſf|kMp]=kW6p\\;q^=tSzýêʱǱɰ˲̳˲ʰȮƬèĪgwgMlY;jU6eR4hU7ziMqɽŬůƱǴǵƴƶųıĮ¬­ůǲʴƱǱƱǱƱǱƱǱ~wZf]>^S5`U5cX8obBwY}ĺɴɶƴƲʰɫȫƩƫǮȯǱ«ƹ|fr]HcO7`L4aP6\\L2WG-VF,]M3k]B|nTz`vž¤ĦǯǱǱȳǲƲűįİĮǿq{lMiY8fS3aP6dR<l[Gu`Ǽɶɶɶ˷͹θθ͵ʳȳ̹ʹɹóǵƹq[q[CeO8jV>mYAhV>tdK{aüæ¥ľýľíííůĬëëªſ}c~oHp^:jX4mZ9ubA|lKkäȨĦĥÿ»ǽ¨é¨¦ĨǪũũĽɿǽnwiOYK1]O5aS9^P6dV<k]CqVexmQm_DlaCnaAk`@}pPhütWfW:aM2hS8rXʿȽ§ɭɭǪĦkZyO~Sbpt}ºƻliaJ[S<XQ7bZCe]Hg_LxgĮȲ˵θϹкк̶̶̶˵˵ʴʴɳ˸˸˸̹̹ͺͺͺλλλλλλλλλλ̹˸˸˸˸˸̹̹̹̹̹̹̹̹ͺͺͺλλϼϼϼ̹ͺλλϼϼλλϼϼϼϼϼϼϼϼλλͺͺͺλϼϼͺμϽϽϽϽμμͻͻͻ˸˸˸˸˸˸˷˷̹ȲŲɳ͸ι̷ʴ¨ǭ¨}pl~bz_fsuy|{{|{tn}_y[uW|qQujJtiIuRczƷ˼ŭʱɯ̲ϵ̲Ū¾||`mbF`U9_T8dY=aV:`U9h]Ax\\ǼɭˮƬʮ˰βʹ̳ɰǮɳɳɳɳȲȲǱǱɴȳƱŰ®­űɳéʿøyg]X}sOxnJzrN_uǻɽĪønxXrhEka>g]9f\\8rhDzVx̶кϹɶıι̸í~hxX}pPylLujJ}oReèʯε˲ȱɴʵʵǴįŽƮȱĭg~tYg[A]Q7cW=f[?nbH~tYxİȳïȳ˶˶ǱȲʴ̶˵ȲȲɳȲŹn~pVxmQpbGtiKtiMz]kǬȬʱʴɳȲƱƱƱǲȳʵ̸ʶɵ͹ʶ}~uXi`A`W:mcHzpW|eƾ˸ɶȵʷʷȵǴǱˮĵzexUzlIxkH}pM\\rĻħŨĨƯƮìŭƯȰǰǯȱ˳ȱªǯǰŭƿľĽľ¨Ƭɯ˱ȲȲĮ¬ììƼq{mRhY<l]@n]?fU7n^=pS|ƾìʳǰȱɲʳͶϸϸ̵ʲŭʰɯƭ¶swgNn^DfV<bS6cR6paD~aźyyYtdCr_AtaCiV8yhJfŨȭĩ˳˳ʲʱǱǰƯŮůŬ¨Ľ{x]rcFeR4jU6hU5fU7xiJsäŨũũūĪé¨¨ĪêǭȯǭǮū©ɿžzuWi\\<`S3`S3`S3sdGuXȱʷ̹ɵ̴ɱƮë©êŬƭſȼiweMdP8jX@cU:_T8ZN4WK1]Q7l^DwiO{mS}bkzƸƨɮ˱ɱŰ­½o|mNiY8`P/aR5cU:l^Dw]ʴİɵ˶˷̶̶̴˴ʳ˸ȶʷɶıŲøs[s^CeO7jV=mY@gV<n^D}oTržĽþýľ­­îļºº{]xhDp]<nW7jS4p]?}lNlĿǪǭûȽźȰȰëéȫ¨ħĽȾ|v[h\\B`T<\\P8]Q9\\P8bV>{oWr~ktVsjIndAkc>riBzrMj~üæuXiZ=aR5gV:tVíƿ¦ǨȨġkzOzi>s`6yf>Wt}ƾŦȫ|sVi`C_V9bW;]Q7ZN4qeKpýɳ̶˵ͷкк˵˵˵˵˵˵˵˵ͺͺͺ̹̹˸˸˸нϼϼλλͺͺͺ̹̹̹̹̹̹̹̹ͺͺͺͺͺͺͺͺμμμμμμμμͻͻͻμμμϽϽϼϼϼϼϼϼϼϼнϼͺ˸ʷ˸ͺλнϽϽϽϽμμμͻͻλ˸˸˸˸˸˸˷˷ͷȲưɳͶη̵ɰͽǶymf{^sV{mP{mPwZl|~tj}`uUwjJpcAtgE~qQ~dpĴ̾Īɮȭʮ̯ɬæirfL_S9[O5_S9_S9\\P6cW=~rX~÷ƬɮƩɫ˭ͯͱ̰˯ʮɳɳɳȲȲȲǱǱǲƱİïïïűȲͿµtbwQwnGulE}tMyUcuºŽǼȽ̿İưīȼr|^zqPqgDia=pfB{rQsêεͷ˵ɶɴǳkyW|nKwiFviI|oO}`vȽȯʹůůƳɶ˺ʹǸòžůɳư«ƾwfmaI]Q9^R8]Q7`T:maIjǼűűǳɴƱíĮǱʴʴɳɳɱǼzqWk]Bl^CfX;oaDvkOezê˴ȳɴðıƳȵɶɶɶɶʷ̹ʷɶλнǿs_}vZ~bq~Ų̻ʹɸɸʷȵƱƭ̻hwS{kGueAzlGwQj¹ĥȫɭʰȱʴȲŲǱǴɳǴǱȵ̶ɶůðȲȵưƮŭªªëƮȰɱʴɳů¬ìĭǽrymSgW=jZ@l[?eT8m\\>qT~ûìɲƯʳɲɲ˴̵Ͷ˴ɲūʰȯŬõrweMn\\DhW=eT:dS7q`D}`ƻǤğrtSpa@m\\>p_Am\\@qTqƩȮƫ˱˱ʲɱǱưƱƱĮīž{wZpaBhU7iT5gT4hX7yjKiú¢¥¥Ǿż§§ƫȭǬƫĩ§§èè§ǾutTj[<bS4bS4bS4rcFtWưɳɶǳȳƱĮ©êŬƭüɿgueLbN6fT<bW;`W:^T9`V;nbHsY~degggiowοĦȭʰư­ïþp|mNkX8bR1aR3bT7i^Bx[ſɳĮɴʵʴ˵̴̴̲˴ʷǵʷɶŲƳĹtYt_DfR7kW<jY?eT:l\\B}mSi}ºrzUscAo[:nW8kT5r]@}nQo¾ƫŭźʽǺý©ǮǮŬêĪƬéĽĻosjMaW<]S:ZP7ZP7_T>oeLij{WvnImf<mf<rjC~sUg}ĺ¥æ¥vYgY<`Q4eV7tVƾþſħǦàǺi~Pwe7jW,hU-r`:|Xu¼ĤãȨ̬ȿhwnOdY;]R4WI,TF)j\\?}aư˵˵̶ͷͷ˵˵˵˵˵˵˵˵ͺͺͺ̹̹˸˸˸ϼϼλλλͺͺͺ̹̹̹̹̹̹̹̹ͺͺͺͺͺͺͺͺμμμμμμμμͻμμμϽϽϽϽϼϼϼϼϼϼϼϼнϼͺ˸˸̹ͺλϼϽоϽμμμͻͻͻλʷʷʷʷʷʷʶʶ̶ɳǱɳͶηʳīȸmx\\pSwhKrdGrdGoaDzlOd|ƻ˿˿ɽtdtVrgGmbBpbEyiOoWfzƸ¨ǬʯʮɬǪæw{oUaU;YM3[O5\\P6XL2]Q7uiOu¨ȭǪɫʬ˭˯˯˯˯ȲȲǱǱưưưưî­®İűİ¬hwUxkIna>h^:i_;vRg~ŻǮɲîǾǾʾòȶ̷̸ͶŻ|n~_{uU~uV}`wȯ϶Ȳůǲ˶ktWviGseBrdAwjJy[sźĨɰʱʿŲɶ̻˺ɷƴıɳʴȲŮìǿvvjR_S;\\P6XL2VJ0^R:vkUxƲȴǲ­¬ůȲɳʴɳȰen`FaS8gY>dV9pbEzoSr¼ʹϸȳȳƿŲɶ˸̹˸˸̹λ̹ɶͺҿ˸ǿʷ̻˺ɸȷɶɶƱêptTwdCn^<o_={mHYxâ̭Ͱͱ̲ɲʳɲǲȱɴʳȳǰǲɲȳŮŰǰȳƯɱǯŭĬĬƮȰʲ̶ʴưíĭŮɿsymSfV<gW=iX<cR6m\\>qT~ûìɲŮ̵ʳȱȱɲʳɲȱūɯǮī´qucKlZBgV<eT:dS7o^B{^´Ǽȥj}nMl]<m\\>sbDveI|bƼƬɯɮ˱˱ʲɱȲǱǲǲíī«{vYo`AkX:hS4fS5jY;whI}]x¸¸ùȾȾȾǽŻƼǽȾǽƽnzoOhY:bS4cT5dU6qbEtWůưƳïįî¬©īƭĪƿgscJ^J2aO7aU;`V;cY>oeJ|d{si}^{X\\envķƪǯŮ®Űp{lOlY;fS3aR3`R5g\\@wZýȲĮȳɴɳ˵̴̴̲˴˵ƳɶɶƳƳøtYt`EiU:mY>iX>cR8k[A~nTi|hrMn^:mY8nW8lU6s^A~oRpèëĹ˾ɼêīŬūūūūƿ¦¦ž|_cZ=]R6^R8\\P6YM3eYAw_ǻm|XtkBkb9ja:j_AujNdʿøx[gX9`O1gW6tS~ƩƥǻnwKve9eT(`O$eS-vd@_z¹ŧɬŨƩͰɬƽdlaE]R6TI-TI-k`D~cĮɳʴ˵˵ʴ̶˵ʴʴʴʴ˵˵̹̹̹̹˸˸˸˸λλλͺͺͺ̹̹̹̹̹̹̹̹̹̹ͺͺͺͺͺͺͺͺμμμμμμμμμμμϽϽооонннннннннϼͺ˸˸̹ͺλϼϽоμμμͻͻͻ̺ͺʷʷʷʷɶɶɵɵ̶ʴȲɳ̵ͶĭĺooSveIpaDk\\?l^AtfItWg~øȽ¤ǫªůưůǽȼp}`ynRqfJo_FrbI|lSg˿ƫβ˯ʭɬȫħĸ¶y_fZ@ZN4ZN4ZN4UI/XL2maGjɽǬʭʬʬʬɭɭȬȬůĮĮĮííííǿǿɾİűɾgwiLj]=fY9fY7i_<qgD_{ǮклƳ³ŶɸͺϺî{|˲̳ů¬įǲǼorWseHm`@o`?qdB|oOhʿ¨ī©Űɶʹʹʸɶ̹θͷʴƯĭĭìv^eYA`T:[O5VJ0\\P8g\\F{gĹİǳƱ­ůǱȲɳ˵ȲĬrtZl^DgY>m_Di[>ugJw[ùȮѸϸȳɴ¯ŲǴʷ̹̹ͺϼѾн˸˸λ̹ǲǫæ»ŽǲʷȵʹʹȷȵɶʵƱe{hJo\\<iY8k[9{mJ\\{¡ɨɩǪƪūȮǭƭȮʱ˱ɰɯêūīĪêƬŬūŭŭŭŭŭǯ˳͵ͷ̶ȲůƯǰswkQcS9dT:fU9aP4m\\>rU{ƾ«ɲƯͶʳǰŮƯȱȱǰĪȮƭêosaIiW?aP6bQ7cR6m\\@y\\ŷ̿Ⱦw]uhFj[:p_AyjMtZqƿūȮʯ˱˱ʲɱȲǱȳǲíŬĭ¦|uXm^AmZ<fQ2cP2jY;sdE|qQg{}brgGdU6aR3cT5dU6qbEuXêưůıſ©īƭƬêfp`GZF.]K3]Q7]S8e[@{qVzõzi^}[]`duú¥īì­®űo{jNmX;gT6aR5_Q4f[?x[¼ǱĮǲȳȲʴ˳˳̲ʳʴƳȵɶƳǴqVt`EkW<nZ?hW=bQ7n^DuZzc}oJl\\8mY6nW7mV7s^A}nOqø̿˾Ĭê©īǭȮǭĪü¦üwwnQXO2[P4`U9`R7ZN4n`Fm̾ƻ~e~uLnb8d[2`U5f[?wlPjǹ̿ʻz[iY8aQ0iY8vU{ÿħɩßmWud9l[0fT,kY3ygC{YvĽɫ̰Ǫũˮ˰Ǫx}qWk`DfZ@ncGz`zůȲȲ˵˵ʴ̶˵ʴɳɳɳʴ˵̹˸˸˸˸˸˸˸ͺͺͺ̹̹̹̹̹˸˸˸˸˸˸˸˸̹̹̹̹̹̹̹̹ͻͻͻͻͻͻͻͻμμϽϽооооннннннннϼλͺ̹̹̹ͺͺλμϽμμͻͻͻ̺̺ͺʷʷɶɶȵȵǳǳʴ˵ɳɳʳɲûwuXl]@hY<gX;eV9l^A{mPrƻǾŦʭíîîïį®«ư«Ĺ|guZqcIqaHvfMx^y˿ȭͱʮɬʭˮɬŧÿȼƺgmaG]Q7YM3YM3VJ0WK1fZ@v\\~ĩ̯ˮʭȫǬŪĩĩſſŽƾǼɾï®jzlQbT9[M2]O4cU8qfHwWrĩȯθιòµöĹŸŸǷȸɷųƿêȯȯưǱǲŰ~v\\qcHi[>gZ:l]<qdBvVqźèī©Ưǰǲȳȵɶ˹ͺͺͷ̶ʴƯŮǰʳɿhj^FaU;\\P6XL2\\P8aV@}r\\ǱǰŮƮʲ˳ɱ˲̳Ǯý{cykQn`FoaFrdIj\\?ugJeĩ˱϶̵ȳʵǴƳŲŲƳɶ̹λ˸ϼнͺ˸˸ʷȳдϲʮƬɲϺ̹ıƵǶǴŲȵ˶ƱȾ{y^t`ElY;gW6hX6vhE}Zsż¼ȾȾʾ§ĪƫĪĩʾǽȼȾɽɿ˿§Īǯɱʲɱɱ̴ζͷ̶ɳǱȱȱpuiO`P6aQ7dS7`O3m\\>sVwûƾʳǰͶʳƯĭŮǰȱȱĪȮŬlp^FfT<^M3bQ7dS7m\\@x[ŷ˾zfuRqdDk^>ufIsVlƼƿ¨Ƭɮ˱˱ʲʲɳȲɴȳưǮŮ¦{tWk\\?lY;dO2bO1hW9qbCxmMbvsyYk`@`Q2`Q2cT5dU6paDwZŬǱůı©êŬƭǭ©|cn^EWC+ZH0WK1YO4e[@w\\ɽëǻuf\\ZX^esĽī¬ĭɾlzfKlW:iT7bS6_Q4g\\@{^ýưůƱǲȲɳʲʲʰɲʴŲǴȵƱŰlQr^CiX<l[?hW=dS9ueKfĸȾƼžĨľdqJn^:nZ7oX8lU6q\\?zkLqø̿̿ŭīĪɯʰǫĨĽkneHVK/XJ-_Q4`Q4`R7zjP{óɻͽ̾Ǹp}Utg=dX0`S3bT7m_BqTfwɸ{ZkX7eR1p]<zY}ÿåĤļ~_~pIl]4k\\5rb>qOd{˽ƿˮϵ̯Ȯ˯̲ɭêt}b|dnŽĮɳǱǱ˵θͷͷ̶ʴȲȲȲɳʴʷ˸˸˸˸˸˸˸˸˸˸̹̹̹̹̹˸˸˸˸˸˸˸˸̹̹̹̹̹̹̹̹ͻͻͻͻͻͻͻͻμμμϽϽоооϼϼϼϼϼϼϼϼϼλͺͺ̹̹̹̹̹ͻμͻͻͻͻ̺̺̺̹ʷɶɶȵǴǴƲƲɳ˵˵ɳȱì{`whKhY<eV9dU8fX;vhK|_ƻɾǾȩ̱˶ɶƳı¯¯¯îȳɴŰƾptZrXtZg}ɮȬȬȫɬʭɬǩæĺȼƺqwkQ`T:VJ0YM3WK1WK1_S9sgMlȾˮʭʭɬǬŪ§ĿĿĿĿľľýýļŽǼȽǼs{lUi[AZK4XJ0YK1aS8vkOh§īĮǳȳ±óŸȻȻǺǷǷȶǵıľ¼¼ýƭǮŬƭʴθʵ«jrdIeW:dV9dW7iZ9m`@|^wƻǬʱȯɲɲɴǲƳȵ˹λʴɳʴ˵ȱŮɲйīpmaI_S9YM3VJ0\\P6dYC{pZ{Ǳɲȱʲζ͵ɱʱ̳īy{oWrdJpbHtfKtfKk]@ykNoɮɯʱɲǲ˶˸ɶƳıŲȵ̹λƳɶͺλͺ̹˸ʵддδͳιл̹ƳĳǶƳ¯Ʊʳĭ¸tpWnZAjV;fU7dT3rcByVl|·źƻźøĻƬʲϷи͵ʲʲ̴˵˵ʴɳʳɲkqeK]M3`P6cR6`O3m\\>sVwûƾ«ʳǰ̵ɲƯŮƯȱɲɲéǭījn\\DdR:_N4eT:gV:kZ>rUyygyVxnKsfFtgGsVfŻȾžūȮ˱˱ʲʲɳɳʵɴȲȯĭv~pSgX;hU7cP2aP2gX9reEwWpsxXj_?`Q2`Q2bS4bS4n_BvYǮȲůı®­­ííīŬƭǮƬƿɿx_k[BVB*ZH0TH.VL1dZ?y^ƮɽŶĶxi`~Y|S~U]k}»êȼfwaIkS9gR5cT7`R5i^BdǱưǲȳȲȲɱɱȮǰɳıƳǴŰîzyeJmY>hW;kZ>hW=gW=qVwĩƬƬū˱ʭƩƿƾļûŽŽhtMp`<nZ7nW7iR2nY:whImø̿ĬīĪǭ˱˱ǫĨĻ{{^h_BXM/SE(ZK._P3iZ=w]ɹο̽˼ĵpZwj@fX1bU3aS6eW:paBzkL|[zɶytShU4gT3wdC`þĿſdvQwgC}mIzXnƮĪ̲ѹδ˴ͳ˴ʰ̶ɿĸíƱ˵˵ȲǱ̶ϹϹθ̶ɳǱǱǱɳʴʷʷʷʷ˸˸˸˸ʷʷʷ˸˸˸̹̹ʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̺̺̺̺̺̺̺̺ͻͻͻμμμϽϽͺͺͺͺͺͺͺͺλλλͺͺ̹̹̹̹̺̺ͻͻͻ̺̺̺˹̹ʷɶɶȵǴƳűűǱ̶̶ɳƯƾnseKn^DgW=cS9bT9l^Cx]u·ƽ¥ȫʯɴɷȶƴĲ°°¯ıȵȵíĽ}yyǫǫȬʭʭȫƩŨƩɿʾǻz`g[ATH.XL2YM3XL2YM3dX>u[ƩǪȫɬȭƫĩ§ĿĿſľľľļƾǼǼʿ}r^iZE_P9ZK6\\M6\\M6aS9|pVvŹĮíïįŲųȸ˻̹ɶǳǳȴǳưĮ§©ɰȲǱȲ͵ϷƯº|uZfX=_Q4cU8dW7gX9i\\<c~ùɿǬ˱ȮŮǰʴɳȲȲ˷κɳɳ̶θɲĭǰϸīuocK^R8XL2YM3aU;i^H}r\\{¬ɳɲȱɱζ͵ǯɰ̳êrrfNj\\Bk]CpbGpbGk]@~pSu˰ȮȯȱǲʵʴȳǲƱǲɴ̷ιȳɴ˶ιϺι͸Ͷ˱ʮ̲ϵϺ̷˸˸ƵȷƳîȱǿn~jQjV=iU:gV8fV5teD}[m|}z}~~ƿƮζи͵ɱȰȰȲʴ˵˵̵ʳȾgmaG[K1_O5cR6aP4n]?tW|ºǿìʳƯ˴ȱƯƯȱʳʳʳéǭīɿilZBbP8^M3eT:eT8dS7teHfvtbvSukHvlI{pPyYmŻ©ļǿŭȰ˱˱ʲʲʴɳʵʵɳǮ«»pxjMbS6aP2eR4dS7iZ=zlOlüžĽž¨žžĽüüü{~^ncCcT5bS4bS4`Q2j[>tWǮǱĮðŰįůůǮǮǮȯĪĽŻu\\iY@VB*[I1UG-XL2g[Czbʾíǻ˿ɽĹ}peU}PzPWi}úǽȺ{bs]EiQ7fQ6dU8aS6mbFiéȲȲȳɴȲȲȰǯƬŮʴĮưǱįrp_AgV8eT8jY=gW=k[A|bëƭŮƯǯζ̰ǫ¦ìŰıðîǿļjuNpa:mY6kT4gP0lW8ufGlù˿˿éǭʰ̰˯ǫĨƩkxmOdY;ZO1TG'YJ+bS4teFhȹʻƷrd~WzmCi[4h[9cV6dU6iZ9n^=zgGb|ykiIeQ.iU2kHfà þľû{njq}ŷĮíȰʹθ͵̶̴ɴǰ˶ɲ®ƻĹɾïűƱʴ˵ȲȲͷϹθθ̶ɳǱưǱȲʴɶɶɶʷʷ˸˸˸ɶɶʷʷʷ˸˸˸ʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̺̺̺̺̺̺̺̺̺̺̺̺ͻͻμμ̹̹̹̹̹̹̹̹λλλλͺͺ̹˸˸˹˹ͻͻͻ̺̺˹˹̹ɶɶȵǴƳƳűİư̶ͷɳŮº}d`R8cS9bR8\\N3\\N3n`EfǪ¥Ǿ¥ƩƬ¬ñƴƴųñƿŲǴ¯ðûƼ¦Ȭ˯α̯ȫŨŨǪèʾ÷mnbHUI/WK1YM3XL2UI/[O5vjPx¥ħǪɬɮȭŪĩſſſļǿȽǼɾwodP_P;ZK6]N9bS>`Q<eV?waɽȼůƲ®îɳȲ˵̸ʴưŬŬǮīŪĩ§æǪɬɮʱ˵̶ͷϷ̴ƾqxoR`R7^P3eW:fY9gX9hZ=iƼĩƬŭɳʴɳȲʶ̸ͷͷϹѻʳ«ìʳwqeM_S9[O5_S9i]CmcJt^}ůʴɲȱǯ̴˳ŭȯ˲©lj^F`R8_Q7eW<gY>fX;~pSxúͲȮǮȱǲȳǱƱǲȳɴ˶̷͸Ϻ͸͸Ϻлι͸ͶūĨǭͶιȳɶϼȷ˸ǴǿƬül|hPiU<jV;iX<jY;zkJcq{xqjgikkq{ýȰ͵˳ȰƮǯưɳ˵̶Ͷʳǽ~dk_EZJ0_O5dS7bQ5n]?tWƾììĭɲŮɲȱǰǰʳ˴˴ʳéƬêȾhkYAaO7]L2dS9bQ5[J.fW:qT}`{[}rRqgDlb?vlIyYhȾĨƬļǿƮȰ˱˱ʲʲʴʴʵʵȲƭǿltfI^O2^M/fS5gV:k\\?rU|ü˭ǨǨƩƩŨħ¦ƿéūĪūȮǭĪƬūūƬǭūžeshHgX9dU6bS4_P1gX;rUƭưí¯ƱƱǱǱȯȯȯȯé»ùrYhX?VB*\\J2WI/[O5j^F{cȼŹư˿ĸt\\RuJuK[qɻͿȸy`pZBgO5eP5eV9bT7odHmūɳȲɴɴȲȲǯƮūĪʴĮůǱîǿnl[=dS5cR6hY<gW=m_Di÷ƭǰ«ƯȲɳи˱ƬŰȳǴŲƳȵȳįŽkuNn_8kW2iR0eN.jU6teDk¨ù˿ʾƿéɯͳͱʮƪĨʭæbpeG`U7]P0[L+]N-fW8}nOp³ĵr`}XyR{mFm_8pcAh[;fW6hY8kX8n[;nMck`yb@cL*jV3pLjǤţàáǿµƸʾĬưïƾɳ˵˵ɳȲɳƱįŰʵ̸ȴƲƲűįǱɳȲɳͷθ̶Ϲ̶ɳưůưȲʴɶɶɶʷʷ˸˸˸ȵɶɶʷʷ˸˸˸ʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̺̺̺̺̺̺̺̺˹˹˹̺̺̺ͻͻ˸˸˸˸˸˸˸˸ͺλλλλͺ̹˸ʷʸ˹ʸ˹μооϽͻͺʷȵǴǴǴǴűİʴȲ˵ϹŮksiP`T:]O5[M3]O5_Q7j^Df¸ǽžĽƬíðŲǴȵȵǴƳƳɶǴ¯ðǴŲü»ĺĽĨũƪʭʭɬȫȫȫɬɬɿǭȮĸemaGVJ0RF,VJ0XL2UI/VJ0j^DiǪˮħƬǭ¬¬íí¬ľ¼ƾ­ȽǼƻxdi^JZK8]N;_P=[L9WH5dU@vcöȻíưƯĬūƩǬǪƩŦĥ£ŦƧȩɨʩɨȧǨƭǳͷ̶ƮɱĪnriL\\N3\\N1`R5]O2cT7oaDiù¨¨Ȯ¨ĬƮʲʹε̳ɳǱϹ̶ʴ˵̵Ͷ˴ɲwvjRdX>ZN4ZN4eY?tjQwĺêŬĪɯжϵȮéȭ˰lg[C]O5^P6^P5^P5eW:{^ĻȭƬ˲ͶǲŰưƯȱɲɲʳ̵ηηйһѺϸ̵˴˴ʰȮƯǰɴ˸ʹɸʷȵŲ­ìyamYAhT;bN3^M1raCzYwøż»Ǿ{tsrryʲζ̴ɱȰɱʴ̶ʴȲ̵Ͷɿ~di]CcS9`P6`O3bQ5jY;{^ûļƾļĭìŮŮĭĭƯȱʳ̵ƬūŬnsaI]K3WF,^M3bQ5aP4dU8n_BxjM}pPtgGzmKwWewũũūūŭŭůŭʰʰɱȰǱǱǲƱưǮŮĽeqcFdU8bQ5cO4dS7qcFgžƨɬɬʭʭȮǭūĪǯǯȰȰȰǯƮƮëëĬƮǯƮªƿ¹kujJdU6_P1bS4eV7m^AuXĺưưıȴǲǲɳɳɰǮƭīū»|yiP_O6\\H0VD,VH.OC)dX@hȼŲ˾ɾŻ¸mZxMvLxS\\l{òt\\kU=cK3cM5fW:cU8peInȮʴưʵɴȲǱƮŭĪĪííĭŽfcR4bQ3eV9iZ=fV<m_DhȼŬʳȳǱǴȵȲìūŮƱǲȵƵƵŴƳƱŰctJqb;p\\7nW5jS3p[<{lKk¾ƼªĨɭʮƪ¦æǪɬgrgIbW9`S3bU5^O.^O.bS4paBz]u}|wqkhd__axXwhGj[:iV6o\\<zfElLvWlMs\\:fO-gS0~lHkġ ¿ãģ¢åç¬ïƳɶʷʶʶʶʶʶʶɶɶɶʷʷ˸ʸɷɷɶʵʴʴɳɳʴʴ˵ʴɳǱưưǱɳʴɶɶɶɶɶɶɶɶɶɶɶʷʷ˸˸˸̹̹̹˸˸ʷʷʷ˸˸˸̹̹ͺͺͺͻͻͻ̺̺˹˹˹μμμμμμμμͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷ˸˹ͻ˹̺ͻμμͻ̺̹ɶȵƳǴȵȵǳűưůǱ˵ǿybj`GXL4WI/XJ0\\N4\\P6g[Az`¸üëëĮĮĮĮííý¬ſžƿƿƿçĨĨĨɬȫȫȫȫȫȫɬéʾyy_i]CTH.UI/VJ0XL2WK1VJ0aU;tZyæͰǪĪū¬íĮĮí¬ſŽƻĹø~s_eZFZK8\\M:^O<ZK8VG4_P=xkXsźƻǼȾž»þàƠǤʤʧ˪ǮƲ˷˵ǯɯ¦emdGZL/[M0^P3[M0cT7qcHmĺ¨¨ȮéǯȰ˲ʹεʹʴɳθ̶ʴʴ˴̵ʳȱxsgObV<\\P6\\P6cW=rhOuŻƭǮūǭͳ̲ǭéǬɮjg[C_Q7^P6]O4\\N3cU8z]ƽȭƬʱ˴ƱŮĮƯʳʳɲɲ˴ͶηϸйϸͶ˴˴̵˱ɯǰǲɶ˸ʹɸɶȵŰììƿt\\gS:cO6`L1`O1xgI`}Ȼåȩħ¨«§̿̿̿̿ɼƹµĽĬ̴Ϸ͵ʲɱ˳ʴ̶ʴɳ̵η}ck_EgW=dT:bQ5cR6kZ<}`ļŽǿ«ŽŮĭŮŮŮŮƯȱɲʳƬƬƭmr`H]K3YH._N4aP4_N2aR5l]@xjMqTuU|ZjzŨĨƩūūƮƮưƮɲʰɱɱȲǱǲǲɳʱǰždqcFeV9bQ5aP4dU8seHjƿƨȫɬɬɬǭƬĪéŭƮǯǯǯǯǯƮĬĬĬƮǯŭªľ¹kujJcT5_P1bS4dU6l]@tWĺůưıȴƱǲɳʴʱȯŬīĪzxhO_O6]I1WE-WI/PD*fZBjɽŲ˾ʿȽƻĺ¸}hY{QwRyV`j~zqYlV>eM5eO7cT7aS6ncGkƬɳưȳȳưưŭŭĪĪ¼¼ǿºfeT6cR4fW:iZ=dV;j\\A~dɿǰ˶ʴƳǴȴǳĭŮŰƱƳƳŴŴŴŲŲį»hxNsd=q]8oX6kT2r^=}nMj¥ĺʾȾ¦ǫȬƪçħǪȫĻaodF`U7_R2aT4]P._R0eV7obBvYnzzroqtyxmyYufEk[:kX8s\\=w`@}dEx_@nW7fR/m[7sOpħŨçééíïƳȵʸ̹ʶʶʶʶʶʶɶɶɶʷʷ˸ʸɷɷɶ˵ʴʴɳɳʴʴ˵ʴɳǱưưǱɳʴɶɶɶɶɶɶɶɶɶɶɶʷʷ˸˸˸̹̹̹˸˸ʷʷʷ˸˸˸̹̹ͺͺͺͻͻͻ̺̺˹˹˹μμμμμμμμͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷʷͻϽͻͻ̺̺˹ʸɷʷȵǴƳǴɶʷɵȴưůǱɳºxpYaW>WK3XJ0ZN4]Q7^R8dX>zpUn}ºļììįƱŰ«æŨǪǪƩħæȫǪǪǪǪǪǪǫɿĸ|i{oUeY?TH.WK1TH.WK1[O5WK1XL2ocIeͰˮ¨¨ĮĮůůůĮííƾƻź·ynZaVBYJ5[L7\\M:ZK8VF6ZJ:l_NsbǢɩǮİȴɳǯʰžwZg^?XJ-ZL/\\N1YK.dT:ugLqü¨¨ʰūʲ˲̳̳ʹʹʹʹͷ˵ɳʴʳʳȱǰ©ùxocK^R8]Q7]Q7`T:lbIpĺȯʱūĪȮɯƬéǬɮfh\\DaS9_Q7\\N3ZL1aS6wZĻǬĪɰ˴ȳȱ¬Ư˴̵ɲǰʳͶηηηͶʳɲ˴̵Ͷ̵ʵʵ̹ͺ̻˺ƳǴƱŮĭž~tZhT9fR7dQ3dS5{kJd̿ǩͰ̱˴̵ʵưʰɫǩƨǩȪǩŧ¤Ǽ¹éȰ͵Ϸ̴ʲ˳͵ɳ˵ʴɳ̵Ͷɿ|bmaGm]CjZ@eT8cR6kZ<~aļƾìƾƯŮĭŮƯǰȱȱȱȱƬƬƭkq_G]K3\\K1`O5aP4^M1aR5paDqT{^gp~ĻãħƩéĩŬƭǱȲȳȱɲʰɱɱȲǱȳȳɳʱƯü|`m_BbS6`O5aP6eU;vhMnŨǪɫɭȬǬŪëªëĬŭƮǯǯǯǯƮŭƮǯǯŭªľújshHcT5_P1bS4cT5k\\?sV~ùůưıǳŰƱʴ˵˲ȯŬêéwueL`P7`L4ZH0YI0UG-j^FnʽǵȽǼļļžĽ»zka}XyVxW|[kruf{gNfR9_I1_K2_P3^P3j_CgéȲưƱƱůůĬĬĪĪſļij[<hY:j[<m^AgY>k]B|bȱ̷ʷǵɶɶǴƱƱƱƳĳĳĵôĳŲıîül|Pvg>s`8pZ5lU3t`?pOl¥¸ȼŹĺƿĨƪƩƩƩŨɾp}pPgZ:\\O/[N.]P0aT2g]:reEzoO}`r~Ǻǽt{[xgIp]=oX9nW8kR4kR3kT4mY8yfE}[uþƿĨŪƫƭůůƱǴʶ˸̹˶˴˴˴ʴʴʴʴʴ˵ʵ˶˶ʵʵɴ˵ʴʴɳɳʴʴ˵ʴɳȲǱǱȲɳʴɶɶɶɶɶɶɶɶɶɶʷʷʷʷ˸˸̹̹˸˸˸˸ʷʷ˸˸̹̹̹̹ͺͺͻͻͻ̺̺˹˹˹μμμμμμμμͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷʷϽоμͻ̺ʸȶȶȶɶǴƳƳǴʷ˸˷ʶʴȲʴɳ|skT\\Q;WK3[M3\\P6]Q7ZN4\\P6lbG~tYkt~ý¥ƩɬɬǪŨħȫȫȫɬȫȫǪƪŻy~d|pVocIaU;VJ0VJ0RF,UI/]Q7YM3TH.cW={qVxǪʭ¨ľéůưưǱǱǱǱǱîɾȽøvkW`UAWH3YJ5[L9ZK8WG7ZJ:gZIxkZz~}||||z{|ÿãǱ¯űȲȰʭxoPcZ;XJ-[M0[M0XJ-eU;xjPxüƿé¨̲Ȯʹ̳˲ʱʱ˲ʹʹ˵ʴʴɳȱȱǰƯŬŻvj^FZN4]Q7\\P6[O5cY@h¸ȯ˲ĪéƬȮǭūɮʯ~ei]EdV<`R8[M2YK0`R5tW|Ūéȯ̵˶ͶƯ̵̵ȱƯȱ̵ͶͶͶʳȱȱʳͶһйιιϼнνͼıƳǲǰǭžxz^q^@q^@lY9dT3wgF`Ƹƫȯʵͺ˺ɶ˲ɮūŪūȭǭȭƬĩ˿ȾǻƼȼɿȮʲ͵̴˳ʲ˳͵ɳ̶ʴȲʳʳĺx^maGqaGn^DhW;dS7kZ<}`ļƾ«ĭǿǰŮŮƯȱʳʳʳɲȱǭǭƭɿho]E]K3\\K1_N4aP4aP4j[>~oRgsĻ¢¤¾§èīƭǱɳʵ˶ɲʰʲɱɳȲɴȳǱȯì~uYgY<\\N1^M3^N4eU;vkOq¥ħȪȪǫǫŪĩªªªëĬƮǯǯȰǯȰȰȰɱʲȰĬüishHbS4_P1bS4bS4j[>sV~¸ůưıȴįƱʴ˵˲ȯŬ©¨sqaH_O6bN6\\J2ZJ1XJ0ocKu̿ȶȽŽŽƾǿľü¸vld}\\zYz\\}_|`pTq]DbN5\\H/]I0\\M0[M0h]AeǱưįįĮĮĬĬĪĪë¼ļmsdEpaBqbCreEm_DncGeǿǲ̹ʷɶ˸˻˸ȵȳǴŲòòôôĳıðìžpTxi@ta9pZ5mW2ua@sPnŹĽĨƩȫŨ~^reEbU5[N.]P0aT4laAzqPanyúȽ¡ǧýv}a~kMs^AnW8iO4mV7s^?lK}[o¾ĪůȲĮƱƱȲɵ˶˸̷ʳʳ˴˴ʴʴ˵˵ʴ˵ʵ˶˶ʵʵɴ˵ʴʴɳɳʴʴ˵ʴɳȲǱǱȲɳʴʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̹̹̹̹̹̹̹̹ͻͻͻ̺̺˹˹˹ͻͻͻͻͻͻͻͻͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷɶϽоμͻ̺ʸȶǵǵȵƳŲŲǴɶ˸˷ʶ̶ʴʴǱwnfOXM7TH0VJ2YM5XL4UK2ZP7i_FyoVhpz~|yzztqqonnqruttsu{ħȫȫǪƩƩʭʭʭʭɬȫƩĨùixlRk_EcW=]Q7XL2XL2SG-VJ0[O5XL2RF,^R8pfKfçƿ¨ūȲȲȲȲȲȲɳɳ­îʿʿøqfR^S?UF1VG0YJ5ZK6YJ7_P=obQtc}zrrvzĿƲİǱǯɬ{vmNbY8ZL/]O2]O4YK0fV=zlRzƾĬë͵ʲͲ˰˯ɭɭʮ̰̳˵˵ʴɳǰƯƯƯīoeYAXL2ZN4YM3XL2^T9}bƫɮççƩʭʭȫˮ̯hmaIfX>`R8\\N3[M2aS6qT{ǬĪǮʳɴ˴ëǭ̲̲Ȯǭɯ̲ͳͳͳ˱ɯɯ˱ͶѺϺͺ̹̻ͼ̻˺ıƳǲǰȮz|[vcCyfFp]<bR0o_=wVzǼêĮƳȹȼǸ˶ɯīĪŬɯɰʰȯȮŬĪ©ĪīūɱʲʲɱȰȰʲ˳ʴ̶ʴǱȱƯtZk_ErbHrbHl[?fU9kZ<|_ûƾ«ŮǰŮƯȱʳ˴̵̵˴ʳȮǭīŻ}cm[C]K3ZI/]L2`O3gV:yjMhŸȻʿäħĦ¦çêƭǱʴʷ˶ɲʰʲɱɳɳʵɴǱȯìz|qUeW:\\N1]L2]M3dT:wlPt¥æȬȬǫƪīêêêííůưǱȲȲȲ˵ʴʴ̶̶˵ǱëƿirgGcT5aR3cT5bS4j[>rU~ùůưŲɵŰǲɳʴ˲ȯŬê¨om]D_O6cO7]K3[K2[M3thPzɷǿƾľ½żźzmcsTqR}lPtcGjY=cR6`O5`O5[L/[M0j_CfſưưįįĮĮĬĬĪĪªªľĽkxiHsdCqdDsfFoaFqfJgûîɶɷɹ̼ξʸɶƵŴĵôôĵŴıð«žrUzkBub:r\\7nX3ua@sPo÷ƽ¥ƩȫørsSm`@dW7cV6j[:qdD{ZpĺĽǼĽǽĩǪȫȨʫƧ»z}a}hMq\\?qY?w_CkN}]qý¥çĬǲɴįŲƳǴȴʵʵʵʳʱʱ˲˲̳̳̳ʲ˳˳̴˴ʳʳɲ˵ʴʴɳɳʴʴ˵˵ʴɳȲȲɳʴ˵ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̹̹̹̹̹̹̹̹ͻͻͻ̺̺˹˹˹ͻͻͻͻͻͻͻͻͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷɶμμͻͻ̺˹ɷȶǵǴƳııƳȵʷɵȴʴȲǱ¬pjbKTL5VJ2XL4ZN6ZN6]S:kaHw^o{|{xtrqpojhffly¥ƩƩƩǪɬˮˮˮʭȫŨæy_nbHbV<^R8^R8aU;h\\BdX>aU;]Q7WK1UI/]Q7g]B|rWlƿ¨ūɯʴʴɳȲȲȲɳɳɾʿzmbN[P:TE.UF/XI4YJ5ZK8eVC~q`vƼŻ¹ùĲðưŭǪywnMcZ9[M0_Q4_Q6ZL1eU<whQxƾĬª˳ɱ̱˰˯ɭɭʮ˯̰˳̶̶ʴǰŮŮƯȾ|dbV>YM3XL2WK1ZN4cY>h¸ĩŪçƪǪˮ̯ɬ̯ͰæoqeMhZ@`R8^P5`R7dV9~pS|úʯǭǮȱŰǰƮȮɯɯȮȮɯ˱̲ͳͳ̲ʰʰ̲δι̷ɶɶȷȷǶƵŲƱǲȮȮæ{Ytb>vcBo\\;bR0l\\:}nMlĸíƲŶŹƼŹͺʳǲǰʵ̵͸ηȳʳȳĭįǰȳƯȰȰȰǯǯȰɱʲʴ̶ʴǱȱŮ~rXi]CqaGtdJq`DkZ>m\\>z]ºŽ«ŮǰŮƯǰɲʳ̵̵ͶͶɯǭ©x^kYA]K3[J0[J0_N2m\\@y\\}Ƹ̿£æŦħŧ©Ŭưɳɶʵɲʰʲʲʴɳʵʵɳʱĭz|qUgY<_Q4]M3]M3cU:xmQwŨŨɭȬǫũīêīīůůǱȲȲȲȲȲʴʴ˵̶θ̶ɳƮ¥jshHdU6bS4dU6cT5j[>sV~ĺưȲƳʶǲǲɳɳɰǮƭīĪ»kiY@^N5dP8^L4\\L3^P6ymWòɹ±½ħĨƸ~prSzkLq`DiX<eT8cR6bQ7aQ7ZL/]O2ncGkǱǱƱƱůůĬĬĪĪľſ¼ĽfufEn_>l_?m`@i^BodHiǵȶɹͽ̺˸ǶƵŶŶŶƷǸŴðƿ»rV|mDxe=t^9pZ5wcBtQm½ĸźħǪǼyatgGh[;eX8i\\<vgFvVxƿƩ¨ªƾſǿéƬɬǫǩȪɪŧĻuw^~iNx`FydIlQ~`uêīĮĮıǴɶıŲƳȴʵɴʴʲɰɰʱ˲˲̳ʹʹʲ˳˳̴˴ʳʳɲ˵ʴʴɳɳʴʴ˵˵ʴɳȲȲɳʴ˵˸˸˸˸˸˸˸˸˸˸ʷʷʷʷɶɶʷʷ˸˸˸˸̹̹ͺͺ̹̹̹̹˸˸ͻͻͻ̺̺˹˹˹̺̺̺̺̺̺̺̺ͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷȵ̺˹̺̺ͻͻ̺ʸȶǴŲıðŲǴȵǳƲɳǱĮýlh`IUM6ZN6[O7\\P8]Q9f\\C~t[y¸ĸ¶uokgdfqåǩƨƨȫˮʭʭʭɬƩ¥þw}qWj^DbV<cW=k_EuiO|by_znTh\\B\\P6\\P6`T:aW<pfK~w[tĽƬɯ˱̶˵ɳȲǱȲȲɳɾ·ylaM\\Q;TE.VH.WH1VG2XI6j[HlƹŬħ£ģşèȼŻɽñıůëƩ|zqPe\\;[N._Q4_Q6YK0aQ8qbKr¼ľɰǮͲ̱̰˯˯˯˭˯˳ͷͷ˵ǰŮŮǰznV_S;\\P6XL2WK1`T:qgLvȾĩèçʮǪ̯̯ȫˮͰŨvvjRhZ@_Q7`R7eW<gY<~pSwʯȮɰɲƱȱ˳Ȯūūǭʰʰʰ˱̲δδͳ̲̲ͳι̷ɶȵǶǶŴĳǴǲƱǭɯƩbuc=r`<n\\8hX4qa?xiH{[{ǵĸĺżŻͻ̶ɶ˵̹кнкʷͷɶĮ¯ǱǴůȰǯǯǯɱʲʲʲɳ˵˵ɳʳȱ~rXg[AqaGwgMwfJraEp_A{^ļŮǿƯĭĭŮƯǰɲ˴ͶηʰƬɿ{sYiW?^L4]L2[J0^M1q`DfƸɻ̽˽ɾȿäħŧ¬ůǱȵȴɲʰʲʲʴʴ˶˶Ȳʱĭy{pTgY<`R5`P6`P6eW<zoSzȮɮʮɭƭŬīīīŬǱȲȲɳɳɳȲȲǱǱɳ˵ͷ̶ɳǯŨktiIfW8dU6fW8dU6k\\?tWŻȲɳȵ̸ȳȳȲǱǮǮƭƭūĽhfV=\\L3dP8]K3]M4`R8p[Ŵɹĵ±°ïĿ¼ƿũǬƩ¦ǼfxYufGhY:cT7bS6`Q4\\N1\\N1aS6shLpéǱǱȳȳưưŭŭĪĪý¨é~cob@h[9eX8gZ:eZ>ncGjǵǵȸ̾ͽ˺ȹƷƷƷǻɺɺƵıƿü¹rXpE|iAyc>t^9zfEwTmŹĸɾæææŨ·juUpcCj]=m^=sdCvUj̯ͰƬŬůưưůůȯȰɮƬŨǫʬˮƪĸviqYoTpU|_qíűıųƵȷųƴȵʶ˴̴˳ʲɰʮ˯̰̰ͱͲͲ˰̱˱̲̲˱˱ɲ˵ʴʴɳɳʴʴ˵̶˵ɳȲȲɳ˵̶˸˸˸˸˸˸˸˸˸˸˸ʷʷɶɶɶʷʷʷ˸˸̹̹̹ͺͺͺ̹̹˸˸˸ͻͻͻ̺̺˹˹˹̺̺̺̺̺̺̺̺ͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷȵʸɷ˹̺ͻμͻ˹ȶȵŲıðıƳǴƲű˵ǱĮ¼ljbKWO8WM4XN5WM4XN5e[Bz`ľľƽǽȾȾǽŻù~zæƩŨŨȫ̯ɬɬɬǪæĿlwlPi]CeY?k_EznT}b|lsgMcW=dX>eY?aU;k`DulOgĺǬ̲ͳͷ̶ʴȲǱǱǱȲĮî­İź{ncQ`S@UF1VG0VG2TE0VG4k\\ItðǱȯũŨɩʧƦƫŭƮƮǱǱǱǱ®ʿƻĹĹǼįİ­ƱƯêħ~|sTe\\=ZL/^P3_Q6YI/^N4l^DkÿƫĩͲͲβͱͱ̰̮ʯ̴ζζ̴ǰƬƯɯuqeM^R:^R8XL2WK1fZ@}sXǽĩŪ§Ḭ̃ǪˮʰƬȮͲū{{mSiY@_O5bR8hZ=j\\?~pSlȫȬʲ̶˴̶ζȮ«¨Ư˱ʳɯɲ̲ηжͶͳ˴̵Ѻι˶ʷʷʷȵǴɶȳŮŮɯɬünzhDq_;m]9o_=wiFufE|oOeøİĳĵĸǸʸȵǴɶ˸ͺλͺʷ̹ȵƿðıǯǯǯȰʲ˳˳ʲǳ˵˵ʴ̵˲ĺrXjZ@raGziO}iNyeJuaFz`~ļĭǿŮì««ìĭƯʳͶϸʰƬǽw~pVgW>^L4_N4\\K1^M3rcFmǹĹͿͿ¦æħŪ¬ĮŰƱǲɲʰʲʲʴʴʶʶưưv{mReW<aR5cT7bS6hY<}oT{ṵ̈˱ʯɮǮŬīīĮůɳɳʴʴʴɳȲȲůůưɳ̸˵ɵƮƫkviIgX7eV5fW6dW5k^>uXƼɲɶʶ͹ʷɳǱưƭƭǮǭƬž~ddT:]L2bQ7]L2]O5`T:s[µƲ˹°ĳòðððíſƬīŪéȽrwZsdGk\\?gX;aS6]O2^P5aV:vkOuìȰǱɵȴȲǱưŭìĬſŭȰǯĭ}bo`?eX6cT5dW7fX=ncGjǴǵǷʼ;̾ξ˺ɺǸǸȹɺ˼ʻǶıƿüúsYrG~lDzfAua<{iEyVlƼƽ¥Ʃħ¥ħjxXtiIrgGxkKtRiæγͲǮưɳ̶ȴȴɳ˵θзεʹǫ˯ϲβŪĶqi}cgt®űƲƳȶʷǵɵʶ͸Ͷ͵̴˳ɰʮʱ̰˲̱ʹͲ˲̱˳̴̲˱ʳɲ˵ʴʴɳɳʴʴ˵̶˵ɳȲȲɳ˵̶˸˸˸˸˸˸˸˸˸˸˸ʷʷɶɶɶʷʷʷ˸˸̹̹̹ͺͺͺ̹̹˸˸˸ͻͻͻ̺̺˹˹˹̺̺̺̺̺̺̺̺ͺͺͺ̹̹˸˸˸ʷ˸˸̹̹˸˸ʷȵ˹˹ɷ˹ͻооϽμλʷɶȵȵʷʷɵȴɳưĮýhe]FTL5UM6WO8WO8YQ:g_H~fľýʿêêīŬŻ¸ĺ¨ééūȮʰūɯǬ§èŪqyYqcFl^CmaGymSno~pVqcIi[AeU;l]@ufG{\\xǼŪʯͷͷʳŭůȲȲůƲıƳƳ{o_aTC]L:]L:ZI7SB0RB2jZJwñįǱɳʱȯǮǯƯưưǱǱȲȲʳƯĭëĬĬŬȭȮĪĨũx[jaDZL1XJ/\\L2\\K1_N4dV9~`|ţĦǩ̮ͯͰαϲαͰ̯ʰжӹɯˮδž|rWdZ?YO4ZN4\\P6YM3maGz_ĨƪƬūĪȮǭƬƯǰȱǯ«ɾfsbHdS7cR6hY:paBviI`ƻƫ˱Ͷ˳ĬǱǮůŬĮǮɳ˲ɳεкѸθʹθийͷ̶˷˷ʶȳƱưȰʲ˳ɱƫžvzYqa@m]<tdCvgHsdEpbE~sUhŻǭƬŮȱɳʴʴ˵˵̶̶̶ͷ̶ɳưĮ¬ǯȮʰ̴̲ʲȰǯƳ̷̸ʴʳȯǹrXnZ?t_D|gL}gOycKwaI}c|ſƮëëĬŭǯʲ̴͵ʰũĺlseKbR9aQ8XH/YI0`P7seJoĺ¸ŻǽĪƬǭǭǯªªſƾǿʯ˰̳ʹ˵ɳŲı®οu|lRgW=cR6hW9dS5kZ<uV}ĹƪǬɯȮǯǮůĮŰůǱǯƮƮưǱȲɳŲƳȵɶɷȵƴįͿlufEi[8fX5bV0cZ3g_:~Zþɳ͹ʺɸɵ˷̸ȲëªƬ˱Ǭx[fW8_N0bQ3aR5YN2cY>x]ɿƬŮȱƯƯƱŰįĮ¯ðŲƱǰůŬĬ÷w{^vhKj]=cT5^P3ZL2dX>|pVzǰ̵˳˵ʴȵǴƳǱǱǱ®İűűưho^@iZ;iX:k\\=l\\BugLkŽưɶ˸ʺ̻ͽͻͻͻ̺˹ʸȶǴƳǴɳȲŭrYrIzkBvg@uf?rM_užǧ˫Ȩãľqez[{\\cmūưȲȲǱǴȵʷʷ̹ϼϼͺ̶˵˵̳Ͳ̲˱ǭùxuy«Ưȱɳʶ˵ȴɲʳ˴˴˴ʳʳȲɰȲʱʴ˳̶͵˵˳˵ʲʴɱɳɳ̶˵˵ʴʴ˵˵̶̶˵ʴɳɳɳɳʴʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶɶɶɶʷ̹̹ͺͺͺͺͺ̹ʷʷ˹˹˹˹˹̺̺̺̺˹˹ʸʸ˹˹̺̹̹̹̹̹̹̹̹ʷ˸˸̹̹˸˸ʷ˸ʸʸɷʸ˹ͻͻͻͻͺ˸ʷȵɶʷ˸ʶɵʴưíýkh`IWO8WQ9[U=\\V>]W?gaI}eſľľ¼ſůðıŲŲŽºƾ«ĭĪūƬƬūūƬǭūǭĪ¨èa{lMk]@l^AwkQdǿļov\\vfMk[AgV8o_>qPlȽƫ˵˵ȲĭŭɳʴǱİİŲǴżuegWGXG7[H9XG7TC3TD4k[Kv¯ıƲƲƱǲǱƯůůưưưǰǰƮĬëªŬŬŬêƨǪæçĨz^kaFZL1WI.[K1ZI/[J.^P3wrRpäŦǩǩȫɬ˰̱̱˰Ȯǭ̯ϲѴʭħ̯ȬuqgL_U:XN3\\P6^R8[O5ocIz_ĨȮɯƬȮƯŮƯȱʵɴƱíplSl[?fU7fW8j[:o`?sSpȽǬγ̳ŮȰǱưůůưȲɳʴ̶ϹϹͷͷϹѻѺкѻѻϹͷ̵˴Ȱɱ˳˳ʱƭ©žmoQsdErcDrcDpbEpbEodF{pRjãŨȫɱɱʴ˳ʴɱȲǯȲȰǱƮĮëƬȮʰ̴̲˳ɱȰȴ̸˷ɳȱūĶnSkV;s[AzbH{cKx`Hu_Gzb~ªªªǯĬĬŭƮȰʲ̴ͳɯĨĺjqcIbR9`P7\\L3]M4aS9thNrĽ»Žǿ«ĭŮĭì«ǿƾƾǿªɮ˯̳ʹ˵ʴǴŲ˼r{jPjY?fU9cR4_O.fV5qR|ǹǫɬƭǭƮŭĮİŰŮưƮƮƮưǱȲȲƳǴɷʸʸȶųįƶkufEi[8dX2_V/b[1nf?_ĿǱʷ˺˺ɶ̷̸ɳĬëƬ˯ǭy\\kZ<bR1bR1_P1aX;kdHgũūɯʰʰȱƯĭǿƾñĲųǴǴǲůĮ¶osVobBeV7^P3[O5h\\Dv]Ȳ̵ɲɴȳǴƳƳƳƳǳƳǴƳű|ep_AjY;iX:m^AscIrWvʿìȲʴʷʷʷ˸˹˹˹˹ʸɷȵǴɳʴʴɳŭs]uL}oHykDxlFyRd|þĥĿƦʪȨťyux¦Ǳȵʷ˸˸˸λн˸̹̹ʷȵȵʷͷ˳̲̲˱ɯƬéĭƯǰȱʳ˴ʳʳʳ˴ʳʳɲɲɳȲȲɳʴ˵̶ͷ˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶̶̶˵ʴʴʴʴʴʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶɶɶʷ˸˸̹̹ͺͺͺ̹̹˸ʷɷʸʸʸ˹˹˹˹̺˹˹ʸʸ˹˹̺̹̹̹̹̹̹̹̹ʷ˸˸̹̹˸˸ʷ˸ȶȶȶȶȶȶɷʸ˹ͺ̹ʷȵȵʷ˸ʶɵɳưĮľpldMXP9RJ3XP9\\T=ZR;_W@vnWľīɳ¯°ððıŲưưů¬ſľŭȮɯūūƬƬƬƬūūéĪſľx~pSo`AfX;qcFz`zǰĭìǼxy`wgMiX<l[=whI|]sʿǯʱǮééǯʱȯĮíưɳ¯}ll\\LXG7ZG6ZI7XG5WH5j[HoįǱȲȲȲ˴˵ƯůůůůĮŮŮƮŭĬĬǮƭī©èĩ¦ĨiukPaS8ZL1\\L2[K1[J0\\N3kdGaŨƫƫǭɮʱ˲˲ʱȲǯ˱ɭʮȬƪʮŻx^cW=ZN4VJ0\\N4^P6[M3l`Fy^üǭʰȮɯƯƯǰʳ̷͸˶Ȳe|mPqbCj[<hY8i\\:qdB|\\wźƪƬȰǯƮƮŭƮǯǯɱ˳̴˳˳̴ζи̵̶ͷ˵Ǳůȱ˴˳̴̴̴ʱǮêĶhqTufIn`CnaAqdDg\\<laA|sRnãȨȮʰ˴ͳ̵ʰƯūìūŮǭŮĪūƬɯ˱̴˳ɱȰȴ̸ʶȲȱĪ´kPgS8mX=s^Cs]EpZBq[Cx`ĬëëëȰĬŭŭƮǯɱ˳̲ȮĨùen`FaQ8_O6aQ8`P7eW=ymSvžĽǿĭƯƯĭƾǿǿǿǿȯɰ˲̶̳˵ɴȳŲĮ˼ozkNl[=jY;eU4`P/eV7rS}ȺǫǪŬƬŭĬĮĮƱƯưŭŭŭůưǱȲǴȵʸ˹ʸȶƴįókxiHm_<g[5aX1e]6vnIhůȵ˺ͼɶ̷̶ɳŭĬǭʮĪĹvYl]>dU6cS2_P1jaDxqUuĨĨĪȮ̵˴ɲƯîǿŽĲųǵȵȵȳǰƯǮdxjMi\\<cU8aU;ndK}dĹȲʳƯȳǲǴƳǳǳǳȴȵȵƳ®»w~v_p_AjY;j[>teHrXjŻ¬Ưʴ˵ʷɶɶɶɷɷʸʸʸɷɶȵ˵̶̶ʴƮzgXyTwRxUapľťĦƩĿħȫȫǪħĽĽȫϳǱȵ˸̹̹ͺнҿͺ̹ɶƳıŲɶθ͵ͳ̲ʰɯȮǭǭĪ¨ſìŮƯƯǰɲ˴̵˴˴ʳʳɲɲȱɳɳɳɳʴ˵̶ͷ˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶ͷͷ̶˵ʴ˵˵˵ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸˸˸̹̹̹ͺ̹˸˸ʷȶȶȶɷɷʸʸʸ̺˹˹ʸʸ˹˹̺̹̹̹̹̹̹̹̹ʷ˸˸̹̹˸˸ʷ˸ǵǵǵƴųĲųȶʸͺ˸ɶǴƳȵɶɵɵǱưůvogPUM6OD.UJ4ZO9VN7UM6g_Hoýªêƭɰ¯¯¯ððůůůǱŭªªëŭūūéūƬūééùkqcFiZ;i[>zoSqƾ̵«ʿƻsw]teHqbCsdE}nO~auƻëǬƭ¨ūȭǮŬĮůɳŰtrcP]L:\\K7\\K7[L7ZK6eYCycļìȰȰɰʱ̳̳ȱǱưưůĮŮŮǯƮƮǯɰȯŬ©èè¦ũſ{|ak`DaS8`P6^N4_N4^N4dZ?unToŽ«ŭĬůǱȲȴȴǳưʰĨũǫǫĩnwkQ]Q7ZN4XL2[M3]O5ZL2j^Dx]üéƬǭ̲ȱǰȱʳ̷͸˶Ȳ;|itWtgGl_=k^<pcA~qObuǼǭǯǯǯǯǯǯǯɱɱɱɱɱʲ̴ͶǱưĹʳζ͵͵̴ʱǮīǼjtWugJqdDodDlaAlaAtkJ]t ħǫ˯βϳ̰ɭƪ¦ĨǫȬǫĨžſ¨ūȮɱɱȰǯǳ˷ɵȲɲƬõlQhT9lW<p[@nX@kU=mW?v^ëëĬªǯĬĬĬĬŭǯȰɯǭũ¸z`l^D`P7^N5dT;bR9gY?}qWzžžƾŮȱȱŮƾ«««ëǮȯʱ˲˵˵ʵʵȲƮ̾m{lMm]<k[:l\\;gX9m^?zZɾǫŪȮǭƮƮưưȳȱůŭŭŭůưǱȲƳǴʸ̺̺˹ɷȵǸo{nNob@g]9e[7ld?zuOnŨưǴʹ̻ɶ̷̶ʴȰƮǭȮèysVn_Bj[<jY;gX9neHz^üȬƪĪǭ̵˴ɲƯį­ƴǵɷʷʵɴȱǰ©©ŹswZugJmbDndI{qXpǼǱǰ«ǲǱƳŲƲǳȴɵɶǴıx|ewfJsdGwhKwZnêĭƯʴʴɵɶɶʷȶɷʸ˹˹˹˸˸˵˵˵ʴȰëſüxniilyŨʬƩȫ§æǫɬʮȫĨƿçȫ˯̯βϵưǴɶɶɶɶ˸ͺ̹̹ʷǴŲƳɶθ͵ͳͳ˱ɯǭūéǭƬƬǭǭĪ¬ĭƯƯƯǰʳ̵Ͷ̵˴ʳɲȱȱȱɳɳɳɳɳʴ˵̶˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶θͷ̶̶˵˵̶̶ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸˸˸˸˸˸˸˸̹̹̹˸˸ʷƴǵǵȶȶɷʸʸ̺˹˹ʸʸ˹˹̺˸˸˸˸˸˸˸˸ʷ˸˸̹̹˸˸ʷ˸ǵƴƴųññĲǵʸλʷȵŲıƳȵȴȴĮůůí~tlUXM7UI1YM5^R:[Q8XN5cY@z`ÿèèèŪƭïïïíĮĮĮŬǮƭīŪƫǬŪĩ¥ŨƩŨæ¦èƫĩ||aj[>j[<tfIeìʳ­­ʿȽǻnrUxjMrdGtfIqThŷǪǬũħƩȫǬǬǮƮǯŮ{{lW`P9ZJ3WG0YJ3ZK4`T<ymUpĪƬǬʯʯǭʰɰɰȯǮǮǭǭɯȮǭȮʯɮŪĨèééīǫĪpymSi[AbR8_O5^N4^N5_P9h\\F}q[sȽŰ¯ıƳȵȵǴŲ̲ĩŪȭƫɽy_seK_Q7`R8\\N4]M4_O6^N5pbH}bƿžūδɲȱǰȱʵʵɴưȰȼirRreCna>xkH}pMyVdy̽ĩƬȮʰʰʰʰɯɯȮȮȮɯʰʰʰưƾ̵Ϸζ͵˳ɰǮƭĪ̾´r}_{pPshHoeBld@phD}uP^m~ĻǪɬȫƩħæƩǪŨżſéƮǯǯǯǳʶɵȲ˴ɯŷpUlX=nZ?o[@lX?hT;lX?y`ªſªëŭëëëëëĬƮƬƬƪ¸v\\i[A`P7^N5cS:aQ8hZ@u[~ĽĽûǿĭȱɲǰĭĭĭŮŮŮŮĭŭƭǮǱɳʴ˵ʵʵưŬȽhylIk]:j\\9qbCo`CxiLfȮǬ˱ʰɱɱȲɳʵʳưƮŭŭůưǱȲıƳɷ̺μμͻ̹ʻr}oRqdBh^:h^:skF}YxȮʴɶɸʹɶ̷̶̶ʲȰǭƬŪv~sUoaDm_BqbEqcFulOh¦̲ɯƬǭɲȱǲƱŰŰƱƱȶɷ˸̹˶ʵɲȱêm{_uY}boìɲǰìưưŲƲƲǳȴɵʷȵƲűſ{hglzȼêĭƯɳʴɵʶ˸ͺɷʸ˹̺ͻͻͺͺɳʴʴ˵ɱǯĬçŸž˯̯Ƭɮī¾çƬʮ̲ʮɯȬǭɭʰʮʰ˯ʰɯȲȵɶȵƳŲƳǴ˸̹ͺ̹ʷɶʷ̶˳̴ζϷζʲƮëʲɱȰɱɱȰƮŬĭƯƯǰȱ̵ηηͶ˴ɲȱȱȱȱʴʴɳɳɳʴ˵̶˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶θͷ̶̶˵˵̶̶ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸̹̹̹̹ʷʷʷʷ˸̹̹˸˸ʷųƴƴǵȶɷʸʸ̺˹˹ʸʸ˹˹̺˸˸˸˸˸˸˸˸ʷ˸˸̹̹˸˸ʷ˸ǵƴųųĲĲųȶ˹λ˸ȵŲıƳȵɵɵ¬ĮĮíxabWAYM5[L5^O8]Q9ZN6]S:siPièĩũêĮĮĮĮůƭƭƭīĩŪǬʯʯȭƨå¾¥ħħ¥çèŪū˿ux^k\\?sfFy[y¨ȱȱɴȳíʿʾĸgx[{mPvhKzlO|_yĹ¥ȫǪǪȫʭɬȭɮǭƮĭ|deW=YI0QC)VH.XL2]Q7mcHw\\¥ȫˮααɬʰɰɰȯȯȯɯɯɯǭƬƬǬǬĩçèĪƬǮȯƬūfuiOi[@bR8^N4]M4_O8bR;o_Hs\\sʿîƳɶ˸̸̸̶ͳŪȭʯ¨{|pVi[AZL2^P6YK1ZJ1bR9fV=|nTqũƿüžéͳɲȱǰǰȳɴȳƱ̶ƭƼz_|oMviF}qK{oI|pJwQ`wķżžƬǮɯȯȮŬūīƬƭƬêĹȱζ͵˳ɱȯǮǮƬɯ˰ǬȽ~kzZumIqiEphCumF{vNXgtĻżĻ¹ĻƽȿǾúſĬǯȰȰȴʷɵɳ̵ʰĶsWnZ?o[@o[@lX?hW=n]CfªſªëĬĬĬëëëĬĬūƬǫù}rXhZ@`P7_O6`P7^N5i[Az`üüºŽ«ƯɲȱǰŮƯƯǰǰǰǰƯǯƭƭưǱȲɳȳɲīøeznHoc=pc@whIykNx[tƩ̱˰δͳ̴˳ʴɳʵʴǯǯƮƮǱǱȲɳŲǴʸͻϽϽϽλƺvx\\ynNqiEtlH{Wm˱ͷ̸ʷǴʵ˶̶ͷ̴ɱǭūȾs~sWrdIqcFwiL|nS~cyǫδ˱ɯȮǰƯŰŰƱȳɴ˸˸˹̹ͺ͸̷ʳɲưɰǮɿzvɿɲ̵ɲƯůĮűűƲȴɵʶͺʷɵ˷Ǳľȼ§ê©Ůǰɳʴɵʶ̹ͺ˹˹̺ͻμμλͺȲɳʴ˵˳ʲȰǭ¤̿ȺĹĹƽĩĨϵͳǯʱƭŭéŮ˱̵˱ʳͳ˴δ˴ȮƯɯȱŮʴʷʷɶƳıŲƳʷ̹ϼнλ˸ʷ˵Ȳ˳ϷҺҺϷ˳ȰʲȰǯǯȰɱɱɰĭǰȱȱʳ̵ηͶ̵ʳɲȱȱɲʳ˵ʴʴɳɳʴ˵˵˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶ͷͷ̶˵ʴ˵˵˵ʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸̹ͺͺͺ̹ʷɶɶɶʷ˸˸˸˸ʷųųƴǵɷʸʸ˹̺˹˹ʸʸ˹˹̺ʷʷʷʷʷʷʷʷʷ˸˸̹̹˸˸ʷ˸ȶǵųųųƴȶʸ̺ϼͺʷǴŲǴɶ˷˷Įí¬ļrtiS]N7XI2YJ3\\P8[O7XN5cY@qjPl¦ƪȬŬȱȱȱȯȯȯȯɭũũǫɫ˭ʬƨåæŨçʾɻjtZyjMx[sƼɯʳɳ˵ʴƱʾ³tfx\\}rVw[izĤŧǩʫɪȫˮʭūūxxjPcU:UG,XJ/[P4[P4cZ=qhKeĦʬвϱȫȮǮǮǮǮȯɯɯȮūé¨èèìǰȯǮƬǭk}oUoaGfX>cS:hV>hT<kYAxfNt^oĸźƾíưȲȲɱɯèƬƬ÷nvhNdV<YK1aQ8^N5bR9rbIoWsžȬƿƿéĪȮȱǰƯƯɴʵʵɴɲɯǫs`~Z|VvN}oH|nGuN^o}ǻǽȼǽƺĺŹŻǻĺĭ͵˳ɱǯǮǮȯȰ̳̲˱ǫçĻwd}Y}uP~vO{TW^cpv|ľĬȰʲ˳ʷ˸ʶȲ˴ǭ~pTjY=l[?m\\@kZ@jZ@scIn¼ëëŭªŭǯƮŭŭĬŭŭƬǭɭĺ|~pVgY?aQ8`P7^N5]M4j\\BeĽüļƾ«ŮȱȱǰǰŮƯǰȱȱǰƯƮƭƭůůưưƯǰǭ¥evO{rIxQyYetƺȭ̳̲ϸη͵˳ɳȲȲȲȰȰǯǯȲɳʴʴȵʷͻϽоϽͻ̹ǻqlcfwǪ͵θ͹˸Ǵɵʴ̶ͷ͵˳ƯĪvdw[x\\fnžɯͳͳ˴ʳǲƱŰŰƳȵ˸ͺ̹ͺλλι͸˶ʳɲʰɯƬ»ǭʳ˴ɱǯíĮİűǲɴʵ˶̸ȴȴ̸˵ưįǲ¨¨¨ĬƮɰǱŮȳɴ˵ʴɵȴʶ̸˹˹̺ͻͻͻ̹̹˵˵̶̶˳ʲɱȮūƪƪũĪǬȭɯȮѺζȲ˵ɳ¬ĮȲĭŰʳ̷ɲʵη͸ϸ͸ȱƱʳʵƱǴȵɶȵƳıŲƳʷͺннλ̹ʷ˵˵̴Ϸииζ̴ʲǯŭëĬŭǯƮƭíǰʳ˴ʳɲʳ˴Ͷ˴ɲȱȱɲ˴̵˵ʴʴɳɳʴʴ˵˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶̶̶˵ʴʴʴʴʴʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸̹ͺλλ̹ʷȵȵɶʷ˸˸˸˸˸ŲƳǴȵɶʷ˸̹̹˸˸ʷʷ˸˸̹ʷʷʷʷʷʷʷʷʷ˸˸̹̹˸˸ʷ˸ȶȶųƴƴȶɷ̺ͻϼн̹ȵǴɶ˸͹͹ůíſýļ~xb`Q:ZJ3XI2_P9^R:YM5\\R9f\\C~t[sȬɮȬ˲˲ʱʱʱ˯˯˯ǫǩȪɫȪŦƪȬǽŹõryapVz]léʳ˵ȲưǱį­¬¬ʻ|ky]~sWy\\h}ľĦƧŦȫ̯ˮƩūĪdrdI^P5]R6_T8[P4\\S6f]@ohKj¤ʬȪƿĩŬŬƭƭǮȮɯƬéľÿÿÿ¾ìǰȯƭŭǭū¨k~pVrdJl\\BvbIq\\Aq\\AvbG}iPtZl~¦Ⱦ¨~}cn`Fj\\BaS9l\\Cl\\CtdKzauƪȬƿéȮƬĪǰŮŮǰʵ̷͸͸ŭȰ̲˯żtoh^{TtJrKyR_oyƯ˳ʲȰƮƭǮɰɱǮǮĬƫ̱αrc_cb`_hmszľŭʲ͵ζ̹ͺʶȲɲŪx}nQgV:jY=k\\?jZ@l\\BxhNtľŭŭƮĬƮɱȰǯƮƮƮǯǭǭʮŻ{}oUgY?aQ8aQ8]M4\\L3l^DhĺžĽƾ«ŮƯǰǰǰŮŮǰȱȱǰŮƮŭŬĮĮĮůŮŮ̲Ũh~WWbnyèʯ̲˱ϸη͵ʲȲǱưưɱɱȰȰɳɳʴ˵̹ͺϽоϽμ˹ʷʿŻʰ͵θκ˸ǳɵʴ̶θζ̴Ư«yvyžǭ˱̲ͳ̵̵ɴǲƱŰƳȵ˸̹ͺλϼϼϺ͸˶ʵƯŮŮǭɯʰɯȮĪūƬȮȱȰƮĬííïİǲɴ˶̷ȴİűɵʴȲɴлɱ˲ɱȯɰ̵̳ʳ˶̷ͷ˵ȴǳȴɵʸ˹˹̺̺˹˸ʷͷͷͷͷ˳ʲɱǰŬȭȰɰɰʱ˱ǰʳһϹɳͷ˵űǳɴŰŰʵ˶ȳʵϺ̷Ϻιɴȳ̷̷ȳıŲƳŲıðıƳ˸ͺϼλ̹˸˸˸ϹϷζ̴ʲȰǯƮƮŭĬŭƮǯŭŬůɲ̵Ͷ˴ȱǰǰ̵˴ɲǰȱɲ˴Ͷ˵˵ʴɳɳɳʴʴ˵˵˵ʴʴɳɳɳ̶˵˵ʴʴ˵˵̶̶˵ʴɳɳɳɳʴʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷʷ˸̹λϼλ̹ʷȵȵȵɶ˸˸˸˸˸ƳƳǴȵʷ˸̹ͺ̹˸˸ʷʷ˸˸̹ʷʷʷʷʷʷʷʷʷ˸˸̹̹˸˸ʷ˸˹̺ɷɷʸ̺ͻμϽѾнͺ˸˸̹̹˷ʶĮíìz~rZk]CZL2ZL2ZN4YM3]Q7dZ?qgL~bzæɬŪǬȭʯ̱ͲͲ̱̯Ǫʫ̭ˬŦƿż·n}c{b~dl~ŪʰǰưưİŲǴȳůɽƺ}qfwZ~pSmwĿŧɪʫȫˮ̯ʭȮƬȼwbtiKf[=^S5XO0WN/YP1e\\=ypQlƿĩǬƫè§ŪƪĨĿ½ìŮĮīĬŭʳɯêĺ{fqWubDt_@r]>taA|iIsR{\\`oqw|t}c~rXxjPykQ|nTw]k}ȾƪɭʰȮūéìƯɲ˶ʵȳǲȲ̴жгƩ¼|reZ{T|U\\blpsyźƯɲζ̴ȰŭêêêëƯǰǱ˱˯ʭɬɩ~zvwxy|~Ƭʲ̴͵̴λͺɵǱȱkrcFj[>iZ=o`Cm]Cl^CqVqªǯƮŭŭǯƮȰ˳˳ȰŭëéȮƪtwiOcU;`P7aQ8^N5^N5l^Dgǽ¦«ìŮƯǰȱȱȱƯǰȱɲɲɲȱɱƮǮǮƭůĮĮĬɯǫƿxv|Īδѷη̵ζ͵̴˳ɳȲǱǱƮƮǯȰȲɳʴʴ̹ͺϽоϽͻ˹ɶǲĭʿĽüž¦Ĩɬɯʰ̴̶̸̹˷ϻθͷ̶ʲɱȰǯûǽ¨Ȯɯɲ˴˴ʳɴȳƱƱǴǴǴǴǴǴƳƳǴǴȵȵʴʴȲǯŭŭĬŭƮǭǭǭȮɯȰǯŭŬíĮűǲɴʵ˶̷˷˷̸͹̶̶̹̹ʴ˴˵̵̵Ͷ͸͸˵ɳǴŲűűƲǳƴǵɷ˹̺̺̹˸̶˵˵˵̴̴ζζͶ˱Ǳʳ̵Ͷ˴ɴ˵˵ȵǴƲűİïðƳɶʷʷʷ̹ͺ˸˸̹̹̹̹ͺͺ˸˸ʷɶȵȵȵȵȵɶʷʷ˸˸ʷʷͷͷ̶˵ʴʴɳȲȲǱưůůůůưȲɲʳ˴˴˴ʳʳ˴ʳʳɲɲʳʳ˴̶˵˵ʴʴ˵˵̶˵˵˵˵ʴɳȲǱʴ˵̶ͷͷͷͷ̶̶̶ʴɳȲǱǱǱȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷʷ̹λϼϼͺʷȵȵɶʷ˸˸˸˸ʷɳʴ˵̶ͷθͷͷ̶˵ɳȲȲɳ˵̶ɶɶɶʷ˸̹λλʷ˸˸˸˸ʷɶȵʷʸ˹ɷʸ˹̺ͻμϽѾϼͺ˸ʷ˸̹˷ʶůĮŮƾq~rXl^DcW=^R8XL2WK1\\P6cY>ukPfy»½ĪƫƬɮȮɬȫɪǩȩŧ}~¤žqf}cioȭȱƮưǱűƲǴǴűɽŻŻwj}`emyƧɪȫʭɬūūǭǻ{c{pRneFe\\=bY:bY:g^?tkL_p|ŻǽƼǽüŮȱǱůĬĬŮĭê÷xc~]yXwVyX}[`aikptz}rjlqzŵƸŻƿ¦ƪȮȮǭƬŮǰɲ˴˶ʵȳƱíȰζг̯ƦǿļƼwposwz{{·ĹǼĮȲ̵η͵˳ȰŭīīŬŬĬĭƯȱʰ˯˯̯ȩŤûûŽŽļ¨Ƭʰ͵ζ͵͵ͺλ˸˵˵èlxiLl]@hY<l^An`ErgKdëǯƮĬŭǯƮȰ˳˳ȰƮŭūĪoseKaS9_O6bR9_O6`P7n`FiȾũĨŮƯƯǰȱȱȱȱǰǰȱȱȱȱȱȱǯǮǮƭůůůůŮƬç¼ü¨ɯϵжͶʳ̴͵̴̴ʴɳǱưƮƮǯȰɳɳʴʴ̹ͺϽϽϽͻ˹ʷȳǰƯŮŮȮɲ˱˳ʲɱɳɳʶ˸̸θθͷ̶ʲɱȰȰĭì¨éūƬȮɯȱȱȱȱǲǲƱǲǴǴȵɶɶɶɶɶʷʷ˸˸̶̶ɳȲƮĬĬƭƮǯǭȮɯɯȰǯƭŬ¬íŰǲɴ˶̷͸̸̸̸̸˸˸˵˵ʳ˴˴̵̵Ͷ͸͸ʴɳƳŲűűƲƲƴǵɷ˹̺̺˸˸˵˵ʴ˵˳̴ζζη˴ʳʳ̵Ͷ˶ɴ˵ʴȵǴƲİï¯ðƳȵʷʷʷ̹ͺ̹̹̹̹̹̹̹̹˸ʷɶȵȵȵȵȵɶɶʷ˸̹˸˸˸ͷͷ̶̶˵ʴɳɳȲǱǱưůůưưȲʳʳ˴˴ʳʳɲ˴ʳʳɲɲʳʳ˴̶˵˵ʴʴ˵˵̶˵̶̶˵˵ɳȲǱɳʴ˵̶̶̶̶̶˵˵ʴɳȲȲȲȲȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷʷ̹λϼϼͺʷȵȵɶʷ˸˸˸˸ʷɳʴ˵̶ͷθͷͷ̶˵ɳȲȲɳ˵̶ɶɶɶɶʷ̹ͺλ˸˸˸ʷʷɶɶɶ˸ɷɷɷɷʸ˹̺ͻμϼλ̹ʷʷ˸̹˷ʶư¬íƯĭºsx^wmRlbG`V;ZN4ZN4^R8eY?vjPeuü½ž¥|x{ťã{mcbkxʼçȭȭŮĬǱ˷ƳƳƳƳİɽƻƿ~thjqŨɬɮɮū«ǰǱĬèqdvYxoRxoRtkNxoRx[eoxǳʶʴǱůí«êŬŬŻ~wqqppopqsv}ĸȼȼȺĸƼƿĨǭȮɯʰɲʳ˴̵˶ʵȳƱŮʳβͰ̬ɨɥͩȣȾ¸üȾɿȲȲɳʴ̶ͷϸϸ˳ɱǯƮƭƭǮǮǱǱǱǯȰɯ˱˯ѵϲ̭ɪƥŤƢƢǥǥȦȦǥƤĢ  áţƤƤţĢãƩǭʰͳζ͵̴˳ȵ˸̹ϹθƫlxjMk]@cU8gY<m_DxmQoľĬƮŭĬƮȰƮȰʲ˳ɱǯǯǭĽhoaG_Q7_O6bR9`P7bR9rdJlȬɭɲɲɲɲʳʳʳʳȱȱȱȱȱǰǰǰǭǭƮŭůůıůĮƮǭƩħĤȨ̬ɯȰɱ˳͵ζ͵˳˳̴͵͵̴ʲǯŭƮǯǯȰɳʴʴʴ̹ͺμϽϽͻ̺ʸȵʴ˵̶ͷϷкиϹͷʴǱǱɳʷ̹θ͵͵̴ʲɱɱȰ̴͵ζζζ͵˳ʲɲȱǰƯƱŰŰƱǴǴȵɶɸʹ˺˺̹̹ͺͺͺλλλʴɳưĮĮƯưȯȮȮɯɯȰƮŬīìĭŰǲʵ̷͸ι͹̹˸˸ʷɶɶȵʴʴ˵̶ͷθϹϹɶȵǴŲıııŲƴǵɷʸʸ˹ʷʷʴʴʴʴ˳̴͵ζкθͷͷθθ̶ʴ˵ʴɳǱưĮí¬îŰȳʵʵʵ̷ι̷̷̷̷̷̷̷̷ʷɶȵǴǴǴȵȵʷʷ˸̹̹̹̹̹̹̹˸˸ʷɶɶɶȵǴƳŲŲŲŲǳȲʳʳ˴˴ʳɲɲ˴ʳʳɲɲʳʳ˴˵˵ʴʴʴʴ˵˵̶̶̶̶˵ʴȲȲȲɳʴ˵˵˵˵ʴʴʴʴɳɳɳɳɳȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷʷ˸ͺλλ̹ʷȵȵɶʷ˸˸˸˸ʷɳʴ˵̶ͷθͷͷ̶˵ɳȲȲɳ˵̶ɶɶɶɶʷ˸̹ͺͺ̹ʷɶȵɶʷʷͺȶȶǵǵȶɷʸ˹˹ͺͺ˸ɶɶʷ˸˷ʶǱíſìĭĽyo~cyoTocIk_Ei]CfZ@l`F~pV|biuú~~Ʀɩȿwpjiq´çƩƫūëĮɵϻǴǴƳŲįʾǼéƬǭèĺyvwþǪ˰ɮɰŭ«ȱȵưŪżxqpihinv}İȴʶɳǱưưĭì¬ŬǮǮŬ¨ȻŷĽŻĺù÷¸÷¸¦çũǭɯ˱̲ʳʳʳʳʵɴȳȳŰǰȲ˱ɭǪǨǦ̫ʩǦģ£¥ƿü»»žƿĪǭɯ̲ͳͷ̶̶˵˵ʴ˴˴ɱȰǯƮǮȯɰʱͷ˵ɳǱƮƮƯȮͳ̲ʯȭȫȫȩȩʭ˭ˮ̮ˮ˭ȫɫȫɫɬɫǪǩħĦǪǭɯ˱˳ʲɱȰıɶ˸θ̶§hxjMk]@dV9g\\>rgKz]{ëƮǯŭŭƮȰŭȰʲʲɱȰȰɯĪĽel^D^P6_O6cS:`P7dT;ugMnɿɭ˯̵̵˴˴ʳ˴˴˴ɲɲȱǰƯƯƯƯȮǭƮĬĮĮıŲıƳɳɱȰɯ̯ϲ͵ʲȰȰʲ̴͵͵ʲ˳ζϷζ˳ǯŭǯǯȰȰɳʴ˵˵̹ͺμμμͻ̺̺ɶɶɶʴʷͷλкϼϹ̶ʴʴʴ˸ͷ͵̴̴˳˳ʲʲɱ͵ζϷииϷ͵̴̵˴ȱƯŰŰƱǲǴȵɶʷʹ̻ͼͼλλλλλλλλ̶ʴǱƯŮŮǲȱɰȮɯɯȰǮŬīìĭŰȳʵ̷ιϺκ̹˸ɶȵȵǴǴȵʴʷ̶ͷθϹϹɶȵǴƳƳŲŲıǵǵȶȶɷɷɶɶɳɳɳɳʲ˳͵͵кϹθͷͷͷ̶˵˵ʴɳǱưĮí¬­Űȳʵʵ˶͸ιι͸͸̷̷˶˶ʵɶȵǴǴǴǴȵȵʷ˸̹ͺͺͺͺ̹̹̹̹˸˸ʷʷɶȵȵǴƳƳƳƳǳɳʳ˴˴˴ʳɲȱ˴ʳʳɲɲʳʳ˴˵˵ʴɳɳʴ˵˵̶̶̶̶˵ʴɳȲǱȲɳʴʴʴʴɳɳɳʴʴʴʴʴʴȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷʷ˸ͺͺͺ˸ʷȵȵɶʷ˸˸˸˸ʷɳʴ˵̶ͷθͷͷ˵ʴʴɳɳʴʴ˵ɶɶȵȵɶʷ˸̹λ̹ʷȵǴȵʷ˸λȶȶųųƴƴǵȶȶɶ˸ɶȵȵʷ˸ʶʶǱĮſǿĽsf{_tXwiNseJ}mSu[|bo~żȿĥǨĥ·{pqt|ʼ¤ħĩĪëůʶлȵǴųı­ɾɾƿĪǭȮũǽ¸ſǬʱɰɳǱůŰɴƵ¯žžƿ»ÿǱǴǴƳŲŲȲ˵ȳƯĭìūƬƬĩʼȺźƻǼǼƽùĺŻƼɿêƭɯɬɫƩŨħŨǪȫʭƪĽĺ»ŻĽĨĨĨĨūǭɯʰȱȱȱȱȳɴʵʵȴɳɳȯŪŨŦƧ̬ͭͭͰ̱ͱͳ̲ǯĬªĬŭƮǯȰɱ˳̴ζϷηʴɳɳȲǱǱǰǰȰȰȰȰɰʱ˲˲ηͶʴȲǱǱȲɱʳʳȲǱȯȯȰɰɬʭˮˮ̯̯̯̯ˮˮʭɬǪƩħæƬǭȮʰʲʲʲɱȵ̹̹ʴůĺ~bxjMpbEk`BujL{^rĿūƮȰȰǯǯǯȰƮȰɱɱȰǯȰɯɯel^D^P6_O6cS:_O6eU<ykQrȾǫ˯Ͷ̵˴ʳʳ˴˴̵˴ɲȱƯŮŮŮŮȮǪĪëííűƳŲǴȵɵɵɳʴ˵Ϲ˵ȲǱɳ̶θθʴ˵ζϷζ̴ȰƮǯǯȰɱʴʴ˵˵̹ͺͻͻμͻͻͻκ̸ɵǳǴɵ̹κϼϻλλθͷ̶̶˳˳˳˳˳˳˵˵˵˵˵̶ͷθϹϹϸͶ˶ɴȳȳɶɶȵȵȷʹ˺ͼνν̸̺͸͸ͺ̸̹̹̹˷ʵȳƱƱƲƱǮǭȮɯɰȯƭŬĭŮƱȳʵ̷ιϺͷ̶˵ɳǴǴȴȴɶʶʷ˷̸͹κκʶʶɶȵȲǱǱŲǵǵǵǵǵȶȵɶɳɳɳɳɱʲ˳˳θθθͷ̶̶ʹʹ̳̳ʲȰƮŭĬë«ĭȱʳʳ˴ͶϸϸηͶͶ˴˴ʳɴɶȵȵǴǴȵɶɶʷ˸̹ͺͺͺͺ̹̹̹̹˸˸˸˸ʷɶɶȵǴƳƳǴȴʴ˴˴˴˴ʳɲȱ˴ʳʳɲɲʳʳ˴˵ʴɳɳɳɳʴ˵̶ͷͷ̶̶ʴɳȲǱǱȲɳʴʴɳɳɳɳʴ˵˵˵ʴʴȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷ˸˸̹̹̹˸ɶȵȵɶʷ˸˸˸˸ʷɳʲ˳̴͵ζ͵͵ʲʲʲʲʲʲʲʴɶȵȵȵȵɶʷʷλ̹ʷȵǴȵʷ˸λȶȶĲĲųųƴƴǵȵʷȵǴǴɶʷʶɵȲưíƾǿ¨Ũå½|ph{a|bir·ĹùȾŧŧƨĦɾ}w}øʿåŧŨŪǭǭưưʵ̷ɶȵƳñʿʿƿ¨ūɯʰǬŪȼùŬƭȲʴɳǱǴʷƵ®©çȬͱ˯çŻùŻùùƼƼùżƽú»þ£äŦǪ˵ɶȵŲðıɳ̶˶ȳĭìūƬǭǭêêīī¬ʿ¬İƲǳɵʳȭɫȪǩǩȫʭˮʭɬȫƪũçççççĪūƬǭɲȱǰƯǲȳʵ˷ɶʴʲȰƬƫɬʫͭͰαβͳ̴ʴȲǯŭëëŭǯȰȰɱɱɱʲʲ˳˳˳ɲȲȲǱǱǱǰǰȰȰɱɱ˲˲˲˲ʳʳɳʴʴ̶ͷθʵɴǵƲƲȴȵʶʲ̰̳ͱʹϳ϶д̳̰ʱʮȯȬƭƫɯʰ˱̲͵͵͵͵нҿλȲeqTynP}rTbvŨȮɱɱʲʲɱɱȰƮȰȰȰƮŭƮȮʰdl^D^P6_O6aQ8_O6hX?~pVvǽƪʮ̵˴ʳɲɲʳ̵Ͷ̵ʳȱŮĭĭĭūȫƩéðĴóĴŷƶɶʷ˸̹Ҿϻ̶ʴ˵ͷͷͷ˵̶͵ζζ̴ʲȰȰȰȰɱʴ˵˵̶̹̹̺ͻͻͻμμӿϻ˸ǴƳȵ˸λͺλλϼкϹͷ̶ʲʲ˳˳˳˳̶̶˵ʴʴʴ˵ͷмѽкη͸̷˶˶˸̹ɶɶɸʹ˺̻ͼͼ˹ʶ˶˶˸ʷʷʷ˷˷̷˶ɵƲİîŬūǭȮʱɰȯǮƯƯǲɴʵ̷͸ι̶˵ɳǱƳƳȴɵ˸˸˸˸̸̸̸̸˷̸˸˸˵ɳȲǱǵǵƴƴƴǵǴȵ˵ʴɳȲȰȰȰɱ˵̶ͷͷ˵˵ʹεεʹ˳ʲȰƮŭŭĭǰɲʳ˴ͶϸйϸηͶ˴ʳɲȱʴɶȵȵȵɶʷ˸ʷʷ˸̹̹̹̹̹̹̹̹̹̹˸˸˸ʷɶȵȵǴǴȵɵʴ˴˴˴ʳɲȱǰ˴ʳʳɲɲʳʳ˴ʴʴɳɳɳɳʴʴͷͷͷͷ̶˵ɳɳǱȲɳʴʴʴɳɳɳʴ̶̶̶˵ʴȲȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷ˸˸˸˸˸ʷɶɶȵɶʷ˸˸˸˸˵ɳʲ˳̴͵ζ͵͵ʲʲʲʲʲʲʲʲȵȵǴǴǴȵȵɶͺ̹ʷɶȵɶʷʷͺɷȶƴƴƴƴǵǵǵȵɶǴƳƳȵʷʶɵɳɳȲů«ĪƩǨƧĥĽưƲó´õŷȺ˽æ̿̿̿áƤǥħŨŨæͿƸźʿ£äŦƧȫǬȮȮǱǱȳȵʷȵƳ°ʿƿžéǭɯɯȮí¬ëíĮůȴʶȵŲƵʹȸųůǭ˱ϵͳƬ©ǮƭŬŬĬĬëŨƩŨæħ¥ƨǩȪȪǨǨɪʭ˵ʸȵƳııǲɴ̷ȳĭìĭƯǰǰƱŰįŰǴȵǴĳ˿óŷƹƹŸǴȭʫʫʫˬ˭˭˭ȫȫɬɬɬȫƩƩçĨũƪȮɯʰʰͶ˴ɲǰǲȳʵ˷ȲȳɲɱǭǭˮͰˮ̰ͳ͵˵ȲűïưůĮůǱȲǱưȲȲȲɳɳɳɳɳʳɳɳɳɳȲɲɲȰɱʲʲ˲˲˲˲ɲʳ˴Ͷκϻλλ˸ɶŵĴĴƶɹ̺˵ͳ̵ͳ̵ͳͶδ̵̲ʳ˱ɲʰɲɰγͳͳδζζζζѾҿͺǱíɿ|rpsåɬɯɱʲ̴͵̴ʲȰǯȰȰƮĬëĬƬū»{`j\\B]O5]M4_O6`P7k[Bv\\|ȾũɭɲȱǰƯǰɲ˴ͶͶ˴ȱŮìììūǪŨſſƿ¯óõõ÷Ŷȹ˼̻ͼѾлιιϺϺͷ˵̶̶͵͵͵̴˳ʲȰȰɱɱʴ˵̶̶̹̹̺̺ͻͻμϽҿн̹ʷɸʹ˻̼̹̹˸˸̶ͷͷθʲʲʲ˳˳̴̶̶̶˵̷̷͸ιϺκθ͸ιιι͸ͺ̹ʷʷɸʹ˼˼˼̻ʸʶ˶ʵʷɶɶɶʶ˷̹̹˷ǳįêŪǬɮʱʱʱɰȱȱɴɴʵ˶ͷ̷˵ɳȲưŲƳɵʶ̹̹̹˸˸˸ʶʶ͹͹ͺͺͷ̶ʴɳȶǵƴųųƴǴǴ̶˵ʴȲǯƮƮƮǱʳʹ̳˲˲ʹ϶ϴϴͳ˱ɯȮǭƬ¨ĪȮʰ˱ͳϵѷҸѷжδ̲ʰɯǰ˵ʷɶɶʷ˸̹̹ɶɶʷ˸̹˸˸˸̹̹̹̹̹̹̹̹˸ʷɶȵȵȵȵʶʴ̵̵˴ʳɲȱǰ˴ʳʳɲɲʳʳ˴ʴɳɳȲȲɳɳʴͷͷͷͷ̶˵ʴɳȲȲɳʴ˵˵ʴʴʴ˵ͷͷͷ˵ɳǱȵɶʷ˸˸˸˸ʷʷʷʷʷʷʷʷʷ˸˸˸˸ʷʷɶɶȵɶʷ˸˸˸˸˵ɳʲ˳̴͵ζ͵͵ɱʲʲ˳˳ʲʲɱȵȵǴƳƳǴǴȵ˸˸˸ʷʷɶɶɶ˸ɷɷǵȶȶȶȶȶɷɷȵǴĴƳȵʷʷɵɶ̶̶ɳŰìįǯèħħæħǪǫŪé̾ŵʸªĬϽ¨¨¨éƪȬ˯ͱʮʬʬɩɩȨȨǧ¥æƨǩƨ¦ɾƻǾħɬɬŨ¥èƫƫǭƬƮưƲǴɶ˸ɶű®ýýľĪƬŭĬűǳʵ˵ɳǱǱǱɳɳǱĮƳ˸˹ȶǰǯȰ˳ɱĪĪƬ̲̲˱ʰȯȭɰʯǬ˯ʯɭȭ˯˯ǫɬʭˮʭȫǪȫʯɳɶɶɳƳůŰǲ̷ɴĭ«ìĭŮưȴǴǴɶʸʸɷǵ±ŵȸɹǸŶı̯ίίϰί̮ͮ˭̮ͯȭƫƫȮ˱ͳħƩȫ˯βϵжжһϸ̵ɲǰȱʳ˴ȲɳɱȰƮǬɮʯͱδϷϷθ˷ɵǳǱưưǱɳɳǱůȲȲɳɳʴ˵˵˵̵˵ʴʴɳɳʳɲɱʲʲ˳˳̳ʲ˲˵̶θϹϹθ̹˸нͺɷǵǷɹͽҿ˷˴ʳɲȱȱȱȱʳʳɲɲɲʳʳ˴ζδζ͵͵̴̴̴͹κʷǱɲ̲Ľǫαггɯʲ˳͵ζ͵˳ȰǯȰǯŭëªëĪȾx\\hZ@\\N4\\L3^N5aQ8m_Ez`ɿũɯɯȮŮƬƯɯ˴δͶ̲ȱƬìéìĪƩħľýſïƳóòòƵɸʹ˸˶˶ʶ͸κϻͷ˵ͷͷ̶̴̴̴̴˳ǰǰɱʲʴ˵̶̸͹ͺ̺̺ͻͻνϽ͹ι͸͸˸˸˸˸̹˸ɵȴǴ˵ͷϹɱʯʰ̳˳ʹͷͷ˷̸̹ͺͺ̻ʹʷ˹̹λϼϼλͺ̹ʷ˸˸ʹʹʹʹ˸ʶʴʴʵɴɶɶȵȵ˸ͺλ͸ȳ­©ĩƫɮ˲˲˲˴ɲɴɴʶʶ˷˷˶ʴȲǱůŲǳɵ˷ͼͺ̹˸˸ʶɵɵͺͺλλͺ̹ʷɶȶǷŵĲĲųƳǴͷ̶ʴȲǮƭŬŬƯɲ˴̳ʳʱ̶ззϵδ̲ʰʭɬȫĪȮʰ˱ͳϵйѺйϸͶ˴ɲȱǰ̶˵˵ʷ˸̹ͺͺȶɶʸʷ˸˸ʷʷ̹̹̹̹̹ͷ̹ͷ˸ʷɶɵȵɵɶʶ̷̷̷˴ʳɲȱǰʴʳʳɲɲʳʳʴʴɳȳȲǲɳȳʴ̷ͷͺͷ˸˵ɶɳȲɳʴ˵˵˵˵ʴʷ̶θθͷ˵Ȳưȵɶʷ˸˸˸˹ʷʷʷʷʷ˵˵˵˵̶̶̸˷˷ʶʶɶȵɶʷ˸˸˸˸ʵɳʲ˳̴͵ζ͵εʱ˲˲̳˵ʴʴɳȵȵǴƳƳƳǴǴʷ˸˸˸˸ʷɶȵʷ̺̺ʸʸʸʸʸʸʸʸɹȸǺɹ˻˻ɹǵĲǴɶɶȵǱƳȲƮŭĬĬĬƮȰȱͶ˴ɲưůůůưʳʲȰȰȰʲ̴͵ŭǭʭʭɫɫȨɩŨǪɬʭʭȬũçƿĪǰȱƯŭŰƯʳȱƯĮíïƳȵʶȴƯê£çũǭɯʳʳʺǷĲƳʷ̸˵ȲʴɰǮŬŬƮȲʴȲʴʴǱĮŬɰʹʯɮǪƩƩȩɬʭȮɯɯʰʰɯɯȮĪĪĪūūūūŭȰȲɳɱɳʲʲʲɱɱɱɱȰǯǯưŲǳȴɵȳǲŮĭ©ŭʱ˳ǮϽƴǤɦ˩ˬͮˬͱʱĭŮʶ̸ɱǨƥĤƧɬʯʯʯɯȮȮʰˮʭɫɭǭĮííĮɯ̲δȮɲ˴̵Ͷ̶˵ɳɱʲʲȰŭëĬĬɱɱȰȰɱ˳͵ζϸη̵ʳȱǰƯƯǰȱɲʳ˴̴˴̴ζ͵͵̴̴̵̷͸ȳɴ˶̷͸ιιιϹθͷ̶ʴɳȲǱưưȲɳʴ˵˵ʴ̶˳˵ʴʴ˵˵̶ɳɳʴ϶ѹѹ̲Ȯ¨ĪǭȮ˰̱˱ɱȱɲʳ˴˴˴˴ŮǰɲƯ«ƾƾɿt|nQi[@dV;_Q6YK0cU;rfLlŻȾɿīƬũé¦éƪʰ̰Ҹϳ̲ȬūĨĪũ¦æŨǪŨŪƭƭȱɴ˶̷̶ʴɳɳ˸ͺλλ˸˸˸̶̶̶̶˶˵ȲŰůǴ˷ιλͺ̻ʺʺ˻˼̼нѻзͶ˴ʵ˶̷̹˸˸̹ι͹ϺϻйͲ̮ʭ̰ʹ϶йϺͺν̾̾̿̿ͽ̼˹˹ʷʷ˸˶̷̵̵̲γ˰˰̳ȴŲıȶ°ȵͺϺͶɲŬê©ŬȯɰʳɲɲʵʵʷʷʹʹʹɸȵʳʱȲɲɵɵɶʷɺʸʹ˸˸ɶɶɳɴθϼͺ͹̹˸ɹƺɽŶ±ĳǴƳɳɳɰȯǮǮǭǭ˳ɴȳȱȳɳʷ̶˵ɱɯɯˮˮɬǪ¨éƬɯ̴ϷиѻӽѻͺʷǶǶȷʷθεεͷ͹͹̺̺ʺʸʺʸʸʸ˷˷̶̶̶ͷͷ͵θ϶̶̶̶̵˷˶ʷʷɶ̹ϼлκ˷ʴʴ̴ʹ̳ʱɲɲʳ˵ǲƱİƱȶʷǵƳǵɶɹ̹˻̹ɹʷȯʱ̶̳˵˷̸̸λ͹˷ʴȲȯȯȯȲ̸ͻ̺˹˹ʻȷǶȵȵʴ˲̱̱ͱ̲ͳϷϷη̵˴ʴ˵̶ͷ˶ǳǳǴʶƱǲȲɳ̳ʹͲϳʱ̳ϸη˷ʷ̹ϼƳȵʷʷǴŲŲŲȲɳ˵̶ͷͷ̶˵Ȳ̺̺ɷɷɷɷɷɷɷɷȻǺƹǺʺʺȸƶĲǵɶɶǴƳƳǴǱưưůưǱȲɳ̶˵ʴɳȲȲȲȲʶ˷˷˷˷ʶɵɳƲǱȯȭȭȭʭˮɫɫɫɫȫȫƬƬŭȰ̶ͷɶǴǴȲȱʰʲȲưŲǳʶɵǱŬê¦¤åäääŨƩȭȮɱʲ˽ʺɹ˸ͺ͹̶˵̳ʱǬƫƫǬʱ̳ʵʵʵȳǰȱ˲ʹʮʮʬʬʫʫˬ̮ɯɱʲʲʲʲɱɱŭŭƮǯȰɱʲʲǯȰȰȰɱɱɱʲǯɱ˳̴̴ʲǯưǳȶʵʵʴɱǯŬƫʭ̱ɮοxtzºÝȣ˨άˬͯ˯ŬíǱȵŮɾĹ¸ˮ̮ʬ˭ɯǰƯƯǰʳͶηȱɲ˴̵̵ʳȱǰɱʲʲɱƮĬŭƮɱɱȰȰɱ˳̴ζηη̵ʳɲȱȱȱɲʳ˴˴̵˴˴˴ͶͶ̵˴˴̵ͶͶɲʳ˴̵ͶͶͶͶ͸͸̷˶ɴȳǲǲƱƱȳɴʵʵʵʵ˵˵ʴʴʴʴ˵˵˲˲˲εззʹʱ̳̳ʹʹʹʹ̳̳ǰȱɲʳʳʳʳɲƯȱȱƯƾƾɿȺm{lOi[>fX;dV;`R7dX>xlRu©īɰƪũççĨǫʮ̰β̰ɭũç¦¦ççãƥǦȧȩȪȬɰʱ˴̵ʴɳȲɳʷ̹̹̹̹̹˸˸̶̶̶̷ʴȲűǱȵ˷̹κ̺˺ʺʺʻ˼˻ͻѸ϶ʹ˲˴̵͸ιллϼϺϺιιε˭ʫȫ˯̳ε̶̷̹ͼͿ̾ʽʺɷȶɶȵȳɴ˴ϵжѵҶͱȭŬɾ·ĴǵʶʴɰǫũĨȬɭɰɰǮƯůƱƲǴǴȵǷɸȸɶȱɰɲɲȳƳĴĴȹȹɸʷɷɶɴɴȳʵʷɶɶʷʹȸĸǻȼŶòƵɶǴǱǱɰɰʰʰ˰ʲ˵ʴɴʵʶ̸ͺк˶ɲɯɯʭɬȩŧĪūȰʲ͵Ϸккϼλ˸ȶƵŴƵǴ˲̰̳ʹ̸̸˻˻˻ʺʺɹɷʸ˷̸̶ͷͷͷζζ϶϶εε̵˴ʵʵɶɶȵʷ̹͸˷ɵʴʴȰǯȯǮƯǰɲʴɴǲİįïıĲŲǵɶǷʷǷȵŵǴ˲̰̳̳ʴʶ˸̹ͺ̸ʶȲɰɭʮʮưȵʷʸʸ˻ʻɺȷȷʷ˵̳Ͳΰΰ̰̲̲˱ʲȱȱɲȲʴ˶̷ʶȵǴƳŲŲƳȲ˲̳ββɰ̲Ͷ̵ȳŲŵƶƴȵʷʷȵƳŲƳȲɳ˵̶ͷ̶˵ʴȲ˹̺ɷɷɷɷɷɷɷɷɼȻȸɹʺɹǵųųƴȵȵǴƳƳǴɳȲȲȲȲɳʴʴɳɳʴʴʴʴɳȵɶ˸ͺλͺ˸ȵű̹˷ʶɳʴ̳εϴˮʭȫǪūƬǭȮȰʲ͵ζ̶ʴɳɱƬɭ̲˱ȰǱȲʴɳǱŬêç¤¤å¦çĨƪǭǮȯȯʺͺϼϻκ̶̶̶̳˲ȯǮǮȯ˲̷̳ʵȱȱʳ̵ʹʹɭʮ˭̮̮ͯͯͮʰʲ˳˳˳˳ʲʲƮǯȰɱ˳̴ζζƮǯǯǯȰȰȰɱŭȰ˳ζζ̴ɱưȳɵʶ˷ʵʲǰƭĩƪŪʼxetUpJ}TfxºǿÝɥ˩ɧĥ¥çç˾ɼöww|yɭͰʭ˯˱ʳɲɲʳ̵ϸйɲʳ˴˴ʳɲǰƯȰɱʲɱǯƮƮȰɱɱɱɱɱ˳̴͵ͶͶ̵˴ʳ˴˴˴̵̵ͶͶͶ̵˴ʳͶͶ̵̵̵̵ͶͶ˴̵̵ͶͶ̵̵˴͸̷̷˶ɴȳȳǲǲȳɴʵ˶˶˶˶ʴʴɳɳɳɳʴʴʹ̳˲̳εεʹ̳ʹʹʹ̳˲˲ʱʱǰȱȱɲʳɲɲɲǰȱǰŮǿƾɿŷiwiLhZ=fX;eZ>dY=l`Fx^ŻƭƭǮ˲ƬūĪĪūȮ˱̲ͳ̲ɯƬĪĪĪĪĪç¦¤Ħŧƨɪɪʬʮʱʳ˶˶ɳȲȲʴ̶ͷ˸ɶͺ̹ͷ̶̶ͷθ͸ʴȲƲȲʴ˵̷˶ɶʷ˸̹˺˺ʺ˹ϹϸͶ̵̵ͶιϺѼѺлηͶ̵˴ʱˮʭʰͲϷзͷ˷˸ͺξʿȽȻȻȻɼɼʺʸʸʷȵȳɴͶйӹӷֺдɮųƴɵɳȯƫȬɫʭɬǭǬūŬĬĮȲȴǴȴǵɶɷ˷ɳ˲ʴʴʶɶǷƶɹȹɸɶȶɶɴʳȱǰǲɳɵɵɶȸȹȺƷòŴʷ˸ȵưǱɲɲ˳̴͵͵̶̶˶˶ʴ̶̷͸ʵȱǭǭɬɬȩƨƮǯɳ˵ͷθθθι͸̷ʷɶɶɶʴ̱βʹεκκξξ̼˻ɹȸȶɶ̸͹ͷͷ͵ζζϷзззε˵ɳȴȴɵʶ˷̸͹̸˷˵ͷθʲɱȯǮưǱɳʴ˳ʲȱƮĭưǲ˵̷ͷ˸˵ʷʴȵɳ̰˭ɮȯȲɳ˷̸ϻκ˷ʴʱ˯̰ͱǭƯȳɶʷɸɸɸɸɸʷ̶ʹͲγγϳдϳͱɰɰ˲ʹǯȰɴ̷̸˷ȴűıŲƳȲʱ˲̱β˯ͱεͶʶǴƳƳƳȵʷʷȵƳƳǴȲɳ˵̶̶̶˵ʴȲ˹˹ʸʸʸʸʸʸʸʸ̼ʽʺʺ˻ʺǵųųƴȵǴƳŲƳǴ˵ʴʴʴʴ˵˵˵ǱȲʴ˵̶˵ʴȵɶɹ˻ͽ̼ʺȵǴͺ̹˷˷̶̶˵˵ɯȮǭǭƬƬƬǭƮȰʲ̴̴ʲɱȮƩʪ̯˯ȮǯǯɳʴɳǮīççƪǮɰɰʮǳ˷ϹϹ̶ɳȲʴ̳˲ɰȯȯɰ˲˵̶ʵǰɲͶй϶ʹȬɭ˭ͯΰ̭ͯˮʰ˳˳̴̴˳˳ʲȰɱʲʲ˳̴͵ζƮƮƮǯǯǯȰȰŭƮɱ˳̴˳ɱȲȴɶʷ̷˶ʳȯǮŹyy^{fKq\\=mW0xc8vK^n{żƽǻŹŷŷŵó|d}oTtiM|pXzb}eu\\hǫͱʭ˯̲˴˴˴̵Ͷϸйʳʳ˴ʳɲȱƯŮȰɱʲɱȰǯȰɱɱɱɱɱʲ˳˳̴̵̵˴˴̵̵ͶηηϸϸηͶ̵˴ʳͶͶ̵̵̵̵ͶͶ̵ͶͶͶͶ̵˴ʳ̷̷˶ʵʵɴȳȳɴɴ˶˶̷̷̷˶ʴɳɳȲȲɳɳʴε̳˲˲˲̳ʹεʱʱʱʱʱ˲˲˳ɲɲʳ˴˴ʳʳɲɲɲǰŮ«ǿŽǽ´dtfIfX;dV9dY=eZ>ymSm§ȯŬŬɯƬƬūūƬɯ˱ͳϵδ̲˱ɯɯɯɯǭǭūũŨƨǩǩɪɬ˯ʱ˴˶˶ʶɳɳʴ̶θθ̶ʴͺͷ̶̶̶ͷϹιʴȲǳȳ˵˵ʶɴʵʷ̹ͻͼ̼˻ʺκη͸̵̵Ͷηηηεʹ̳˲ɰɰȭɯʭʰͳηϷ˶ɳǲɶ˺μ;ͽɺɹƶǷǷɹ˻ͻμϼͺ̷̷ιййͳʰèȽvqüƿĮǮǬǪȫɬȪƨæĦĨǪǭǭƯƮĭŭįǱȳʴ˳˲ɳȲȵɶȸɹʺʺʹʷʷ˵ʳʳɲƯǲ˶̹˷ɶʷƵŵðŲ˸˸ǴȲȲʳ˴˴͵ζζ͸̷̷ʴɳɳȳǰǰǭūƬɬʭˬʬǮǱǴʴ˵˵˵˵̷˶˶˴˴˴˴ͳϴͰ̱˲ʴ̸ͻϿͽ˻ɹǵǴɶ̸θͷͷζζϷϷзззε˵ɳɳʴ˷̶͹ͷ̸ʴȲɳ˵θ˳ɱȯǮǱǱǱǮƮȮɱȮǯǯʲ͵̴̴˳˳ʲʲʲ˲ʭȫƫƫǮɳ˷̸̸˵ʴɰȭȫȫɬɭǫůʳ̷ʷɶɸȷȷɶʷ˵̳ʹͲ̲ϲδ̲ʰʰ̴иɱȰȳʵ͸̷ȴƱųƴƴǴɳ˲̱̱ɮ̰Ͳʹ̶ʴɵȴƳȵɶɶǴƳǴȵȲɳ˵̶̶˵ʴɳȲ˹˹̺̺̺̺̺̺̺̺ξ̼˻˻̼˻ɷƴŲƳǴƳưůǱȲ̶̶̶̶̶̶˵˵ǱȲʴ̶̶̶˵ɶȸǺȻȻɹɹɹȸȶǵƳȵɶȵı¬ưǯɱɱɱǯŭĬĪƬȮ˱̲̲ʰʭɧȤǥƦŨǫɯ˳ε̳ɰŬçŪɮʯʰˮŭɱ͵ζʲȰȰɱʴʴɳȲȲɳʴʴ̶ɳǱɳεз϶ʹǬȭʯ˰̯ˮʭɬʰ˳˳̴̴˳˳ʲʲʲʲʲɱɱɱɱƮƮƮǯǯǯȰȰƮƮƮƮǯȰɱʴȵʷ˷̷˷ɳɰȯūf{gNmX=hQ2cL#nV*|e9xK[it{|||}}{y{|j{nNbT9YK0`Q:i]EqeOqeOzbè˰ʭɮ̲˴˴˴̵Ͷηη˴˴˴ʳɲȱǰƯɱʲ˳ʲɱȰɱʲɱɱʲʲʲ˳ʲʲ˴˴˴˴̵Ͷηϸϸϸϸϸη̵˴ʳͶ̵˴˴˴˴̵ͶͶͶͶͶ̵˴ʳɲ̷̷˶ʵʵɴȳȳʵʵ˶̷̷̷̷˶ʴɳɳȲȲɳɳʴ͵̴˳ɱȰɱ˳͵ζ͵̴˳˳̴͵ζ̵̵ͶͶͶ̵˴˴˴ʳȱƯìǿû¸vx[pbEfX;fX;i^BmbFf}èūéǯǮǮǮɰ˲ʹεзз϶εεʹε͵ʳɲȱȮȬȬȫɬǪȫʯ˲̵̷ʷʷ̶ʳ˴Ͷϸη̵ʳ͸̵ʳʳʳ̵ηϸ˵ɳȲɲ˳̳ɳǱʴ˷̹λνͽ̼˻̺͹̹˷˷˵˵̳˲˰˰˰˰˰˰˰ƬǭǮʰ˲˱ưŮĮǲȴ˶˷̷ʶʷȷȷȷɸʹͺϼнͺ͸ιѺѺ˴}}dlaKf[E{s^yŭƬƩƩƧĤƽſæææǽžƼĽɿĪǮ˱˳ɱưĮ°°Ĵķ˻̼̻ͺ̶̹ʳɲǮêìɲͷȲűƲǿƾîʵ˸Ƴʶʶʶ˶˶˶˶˶̵̵̵̳˳ɲǱȯɰǫũƩȫɬɫɭůƲųƳǴǴƱƱʳʳȲɰʱ˲̱βͰʭƬëĮƳ˸ͺͽ˻ɷǵǴɶ̶θͷ͵͵ζθϹϹϹͷ̶˳ʲʲʲ˵̴ʴʲȲŭëĬǯʲƮĬëŭǯǯŭªæƫȫȭɮʯʯȭȭɮɮɮɮɮɬϲ̮ȫƬǯɱɳȲíĮưǯǭƩħ¥£ȿ˿Ǭ̳Ȳȵɶǵǵȶȵȵʴʴʲǫɬʮǫç¦ūʰƬƬƯǰɲ˳ɲɳȶȸȶȵʴʲʰʰɬʭʭʰʰɱǯƮƳǴȵǴƳŲǴɶȲɳ˵˵˵ʴɳȲȲʸʸ̺̺̺̺̺̺̺̺ͽ̼˻˻̼˹ɷǵŲƳƳŲůůǱȲ̶ͷͷͷͷ̶˵˵Ȳɳʴ˵̶̶̶ʷȶȸȸȸǵǵƴƳǴŲůǱʴʴǱíůǱɳ˵ʴȰŭëƬƬȮ̯ααˮɩƢýħ̯ͳͳ̳ʱƭçūȮˮˮʭǪɬˮ˱ʰɱɱʲɳɳȲȲȲȲɳɳʴɳɳʴʹεεʹɮɮʯʯʭʭɬɮʲʲ˳˳˳˳ʲʲʲɱɱȰǯǯƮƮƮǯǯǯȰȰȰɱȰǯŭëĬŭȰɳǴȵɶ˷ʴɳɰƮƬȾvqWmY@eM5cJ,`G\u001fhP$v^2mA~Q]jqvtuxvqprrwZj\\A[M3ZK4_P9eYCthRnɮɮʯ˱ʳ˴˴̵̵̵Ͷ̵̵˴ʳʳɲɲɲʲ̴̴˳ɱȰɱʲɱɱʲ˳˳ʲʲɱʳʳʳʳ˴̵ηϸϸϸϸηͶ̵˴ʳ˴˴ʳɲɲʳ˴˴ͶͶͶͶͶ̵ʳʳ˶˶˶ʵʵɴɴɴʵ˶˶̷̷̷˶ʵʴʴɳɳɳɳʴʴ̴̴̴ʲȰȰʲ̴иϷ͵ʲɱɱɱʲͶηηηηͶ̵̵Ͷ˴ʳȱŮǿ~jqTseHqcFshJ}rVz^|Żƿƿȯȯȯɰʱ̳ʹε̳̳ʹʹʹʹʹʹ̵˴˴ʳʰɭɬȫħƫȯʴ̷˸˺ʷθ̵̵ͶηжͶ̵̲˱ɲȱɲ˴ηϸͷʴȲǱȱɱȰȯʲ˵̶̹̺̼̼˻˹̹̹˸ʶɳɰɮɮɬʭ̭̯ίͰαʱɰɰ˲ʹ̳ʱȯɰʱ˲̳ʹʹʹ̶͹ͺ̹˶ʷ˶ͺι˶˶ͶѺйƯwfrhO_U<cXBybļëǭȫŧ¤ú¹¹ǾħǬǭǯưůðñµµ˻ͻϽѼϻ̶ǰƬɿºļüĽŽ«ɴʷǴʶʶʶʶʶ˶ʶ˶ɳ˲̴̳˴˲˲ʯɮƫĨæħħŧêïıĲųŲŲįĭϸδʱȭȫɬʬ̭ȫǫūūǱʴλн̼˻ɷȶȵɶ̶ͷ̴̴̴͵ͷͷθθ̶̶˳ʲɱȮǭƬȮȮȮƮŭƮʲ͵ƮŭƮȰ˳ɲìƿĿŨɫʭʬȫɫʬ˭˭ɫǩƨͰɬŨĨƬȰƮë¬ŭɱ̲ɭæüȽƬǮƱɶƳƴǵǵǴȵȵȱɮȪĦƻù¸ƼŮǯȰʲ̶ɹȻɹȶǴǯǭǫ̰ʭɭʭˮ̯ˮȮůŲƳŲııƳȵɳɳ˵˵˵ʴȲǱȲʸʸʸʸʸʸʸʸʸʸʺȸȶɷʸʸȶƳŲƳǱưĮĮưɳ̶ͷͷθͷ̶˵ʴ˵˵ʴʴʴ˵̶̶ȵɷɶɶȲůªſéſ¼ľĬɱɱȰǱƳǴɳȲǱƮŭȮǭȫʭ̯˭ƨãwyýǪ̯ʰɯȯƭè¾¼ſ¨ƬȬȬǫƩťťŧƨɬɯɱȰȲȲǱǱǱǱȲȲʱ˲ʹ̳˲˲˲̳ͲͲ˰ʯʯɮɮɮɱɱʲʲʲʲɱɱǯǯǯǯǯƮƮƮǯȰȰȰɱɱɱʲɱȰǯƮƮƮǯǱǴȵɶʴʴȲǯƮūƼupXp\\CkS;lR7nT/v]4jAyO[dns}z{~{pmq~rx[o_E_O6ZK4\\M8eVAva¶ǭ̱̱̲˴̵̵ͶͶͶ̵̵̵˴˴˴˴˴˴̴͵ζ̴ɱȰȰɱɱʲ˳˳˳ʲɱȰʳɲɲɲʳ˴̵ͶͶͶηηͶ̵˴ʳʳɲȱȱȱȱɲʳ̵̵ͶͶͶ̵˴˴˶˶ʵʵʵʵɴɴʵʵ˶˶˶˶ʵɴ˵˵ʴʴʴʴ˵˵ʲ̴͵˳Ȱǯɱ˳Ϸ͵˳ɱȰȰɱʲͶηηηηͶ̵˴ηͶ̵˴ǰǿ}jy[uWz\\et¸žééȯȱɲʳ˴̵ηηɲʳ˴̵̵ͶͶ˵˶ʶɳɳɯȮƪƩ¨Ǯɳ˷˸ʺʷϹ̵˴˴ͳβδ̰˱ʮȮǭǰʳͶϸϹ̶ɰǮȮȮȮȮɯȱȱɴɷʸʺ˻˻˻ʸɷǴǱŭĪƩƨǩȨɫʪʬ˭˲ɳȲɳʲ˳ɱȮƬūũçççĦŨʴɵȴȲɵ˵͹Ϲ̵̵ͶѺҽɴxhyoVh^EcY@rhOpž¨üļ­ƳŴ¶ɹ̺оѼϻʴìɿĽ«ȳʷɶǵǵǵȶɷʷʷ˷ɳʲʲʰǮĪé¦Ľþ¥ĨêðóĴƳŲŲŰŮ˲ǬǼøøƹƻźǽǭ˵θϼϼ̹˸˸ʷɶ˵ʵ̶˳̶̶̱̳̳ͷͷ˶˶ʳȱƬ¦Ľ»ɿ§ĪūȮ̴Ϸ̶˵ɲɲɯ~{|ƩǨŨƧȩɪǨäǾżĻĻūĪĭɯ̲˯tc`pɾèŮʵǴǴǵȶǶǶȷȴʯäĵuryƼĪūǬʱͷɹɻǷƴıì¨¥ǾƩʭ̯̰ĬůůĮííưȲɳɳʴ˵˵ɳǱưȲʸʸȶȶȶȶȶȶȶȶǷƶųǵɷɷǴŲŲƳǱůĮĮưɳ̶ͷͷθͷ̶ʴɳͷ̶ʴɳɳʴ̶ͷɳ˵͵ͳɯħ½ƩƬɳǴƳŲůưǯǯȮƬƩǪǩŧobeyƩƬƬƮƭĩ§ÿƾĪǭȬƪħæğÿŧȫǭŭǱǱǱǱǱǯǯǯǯ̳εʹʱȯʱ̳ѶϴͲ˰ʯʯʯ˰ȰɱɱʲʲɱɱȰŭƮƮƮǯȰȰȰȰȰɱɱɱʲʲʲȰɱɱʲɱȰƮŭƱǲȳɴɳȲƮŭǭ~|d~jRzdM}eKmKwR^irw|~~~{nglmhvYo_EZJ1P@)O@+SD/gXCn˿ªȰγγ̵̵ͶηηηͶͶ̵̵̵˴̵̵ͶηζζϷ͵ʲȰȰɱɱʲ˳̴̴ʲɱȰɲɲɲɲɲʳ˴̵̵̵ͶͶͶ̵˴ʳɲȱǰǰǰǰȱɲ˴̵̵ͶͶ̵̵˴˶˶ʵʵʵʵɴɴɴʵʵ˶˶ʵɴɴ̶˵˵ʴʴ˵˵̶ɱ̴͵̴ȰǯȰʲиϷ͵̴͵ϷҺԼͶͶͶͶͶ̵˴ʳηηͶ̵ȱǿsggoy¸Ĩƿžéǭǭȯȱɲʳ̵Ͷηηɲʳ˴̵ͶηηͷʵɵɳȲȮƬĨçľĬȲʶ˸ʺʸι̵ɲʰ˯̰Ͱ̯ˮɬǫƪǭɲ̵ϸк̶ȯƭǭȬȬȬǬȮǭƯűǵȸ˺ɽ˻ʺɶȲŭéæ¤ãããĤĤťħĬ¬ª¨ƻĹéīëƭɰεҹԾϸηϸӼϺ¬}f{qX|rYj|xxuuz}zrkffgkv¯òǾǷʸϻѼθȰɿĺylmoowžĪȱ˸˸ĲĲųǵɷʷ̹ͷ̴˱ɯŪǼø·½¥ǫǰðóĴƳƳǱƯǭǽ¹}~÷ǰʴȴƳ˸˸˸˷˵˵ʵ˳ʰ˰˲̳˵˵̶̶̷̷˴ɯçü·ĺž¨ǯʲθ˵ƯìǽxtY}oToUdzʻ̾ɺʽ;̿ɺµú¦ç¦Īǫǫu|\\zlIzjF}kE}Y|ĶʿīʳɳȵȶɷȷɸɸɳħɹfqS|kMsW}cwĪūƫɰͶɹȸƶĲ­ɾȾȽúĤʪˮëĮĮí¬íůȲɳʴʴ˵ʴɳǱưȲʸɷɷɷɷɷȶǵƴųųųƴǵǴȵɶɶȲưĮĮǯɱʲʲ˵̶ͷθθͷ˵ʴɳɳɳɳɳɳɳɱɲɯʮˮĢ{xwɧʭ͵ʷȵƳưǱɱʲȮƬŨƩƨ{^}uN|WsǪǭǭƮŭĪ¨ƾƾɿɿźƪĪɴįĭŮūūȮʰʰʰ˱ʰƬĪĪɱʲ˳̴˳ʲȰǯȰȰɱɱɱȰǯǯƮƮƮǯǯȰȰȰʲʲʲɱɱȰȰȰȰȰȰȰȰȰȰȰŰƲɴʳ̴ʲȰǯū|olmtx¸û»qjg}^zkNfV<TF,N?(WH3dU@{n[ŹǱɰʹϴͲϸηͶͶ̵̵ͶͶʳʳɲȱȱȱɲɲ̴̴˳˳ɱǯƮŭǯɱʲ̴̴˳ʲʲȱɲ˴̵Ͷ̵˴ʳ˴˴˴˴˴˴˴˴ʳɲȱȱȱȱɲʳ˴˴ʳʳʳɲɲɲ˶˶ʵʵʵɴɴɴʵʵ˶˶ʵʵɴȳ̶̶̶̶̶̶̶̶ȱʳ˴˴ʳʳ˴Ͷʳ̵ηͶʳɲ̵ηͶͶͶ̵˴ʳɲȱʳɲɲʳƯŽ¹¥˯ǫç¦ūǭǭūʱȯǮɰʹ϶ε̳εʹ˲ʱ˲̳εζʳưí¬ŬǬʮʮ¨ŭɳ˸˹ǷĲʵĮŬǮĩƽĻǾĻĻƫȯǮǱ̶˴Ů©ŬƫƩŨƩɭȭƭůƲȶʹ˺˿ʻɺ˸ͶͳɬǧĢ ſ¼ǻ˼̽̽ʻɺʼ˽Ķwzɻū˱еѸεʹηйԾӽϹ̴¸olżvjfhjqz~uf}ZwT~qNwmJwYg{Ǽ±ƳĲƲ˶θɱŻguZvZw[vZ~dqåūȱǴ˸ŴòŲȵʷʵɲȯŪɾƪǰƳƵƶɶɶɳŮéwkighkxƺƯ̶͹̸ɶɶʶʶʴʴɲ˳Ȯɮɰʱʴ˵˸̹ι̷Ȳƭzy|»¨ŭŭɳʴǰprXmY@bN5aL1nZ?sXpwij``tżħɬȬħƽvxWsdCm]9p\\7nX1ye@eʼĩɯǱɳȵǴȷʹƴ˿ilKoZ;lW8p[>s`BqUrƼ¥ħǫȮıĴųƳŮƼuljrʪƬŭŭȰȰǯŭƮůưǱɳɳȲǱưǱʸɷʸʸʸʸɷǵƴųųųƴǵǴȵɶɶȲưĮĮǯɱʲʲʴ˵̶ͷͷͷ̶˵ɳɳɳɳɳɳȲȰǭħãſzia_cm}Ƣǧ̴ʷȵǱǱǱɱʲȮƬŨŨƩ¤xb|U^xžũɯȮȰǯƬĪĩ¨ŽžǽȾȾżſƪū«Ʊ«ūƬçæŨǪǭɯʰɯǭūƬʲʲ˳˳˳ʲȰǯǯȰɱɱɱȰȰǯƮƮƮǯǯȰȰȰʲʲʲɱɱȰȰȰȰȰȰȰȰȰȰȰƱǲɲ˳˳ʲȰǯĪūĸ²ǹɾ¥ťǧɦȢǠŞětkv\\tfKfW@dU>o`K{oYvǱǱͳ϶δηͶͶ̵˴˴̵̵ɲɲȱǰǰǰǰȱʲʲʲɱȰƮŭĬǯȰʲ˳̴˳ʲɱɲʳ˴ͶͶͶ˴˴̵̵̵˴˴˴˴˴ʳʳɲɲɲɲʳʳ̵˴˴˴ʳʳʳɲ̷˶˶˶ʵʵʵɴ˶˶˶̷˶ʵɴɴ̶̶̶̶̶̶̶̶ɲɲʳ˴̵̵˴ʳɲ̵ηͶʳɲʳ˴ͶͶͶ̵˴ʳȱǰȱȱȱǰìŽĻźƽȿæɬȬũĪƬƬūéèªŪǯɮƮŪƮǬƮƫŭƫǯɱǱĮèƫɭɭçĨƬʲͷͺ̹ɷɵíǽȿèêíưŮƾùĺżĻǼçūȯȲɵ˺̻ʻʻʹ͸ϵͱɩĢĵǸʻʻ˼̾Ϳ´vkim{ʼƪ˯γεʹηϸҼҼкθǰƼ¹tle_`dqwŸǺŸösd{X{nKqdBpcCxmO~bvȽŲŲðİɴ̶ȮƼxc}oR|nQ}oRzoQw[gƨƩʰɴıƳĳ±¯Ƴʵ˵̶ǮĪʿvmgiltêŮðƲɳʲȮŪf~[|W{W}V}Yn~ʼůʳ̶͸˸˶ʶʴʴʲɲʰʯʯʱʱʴ˵˸̹λ̷ɰŪȽrjnwĽéƮȲɳĭŻ{tZkZ@^F.W?'W=&aI/rX?gMtYcekopnetU|eEwdCp`>ueD{Zx˫æǾh|lJjZ8hT1rZ4pY0zd?\\ŸçȬȱʴȵƳȵʸǵǷz}Xv_=gP.dM-fO/gR3ubDz^|»ŨʮɰȳǴű¬Ƽ~ixgIsbDscB|mL_qëŭƮƮŭƮĮưǱȲɳȲǱưǱʸʸ̺̺̺˹ʸȶƴųŲŲƳǴǴȵʴʴȲưĬŭǯɱʰʲȲɳʴ˵̶̶̶˵ʴʴɳɳȲȲǱǯʮŨļs`[\\fxȣʦʪ̲ʴɳǱǱȰɱʲȮƬéŨŨæþwov§ʱʰɲɲȱȮǭƩƩžĽüü»zxĻĩŬ¬ĮīæƽúýħȫɬȮȮȮȮʲʲ˳˳ʴɳȲȲǯȰɱɱɱɱȰȰǯǯǯǯȰȰȰȰʲʲɱɱɱɱȰȰȰȰȰȰȰȰȰȰƯǰȱʲʲʱɰȯ¨ƬīοĭíưȲ˱ʰʭ̮ͮѱά̪˧ʧ˥ȣƢzmhjxƾɵɲǰ̲ϵͳͶ̵˴ʳʳʳʳʳɲȱǰƯƯƯƯƯɱɱɱȰǯŭĬëǯȰɱ˳˳ʲɱɱɲʳ̵ͶͶͶ̵˴̵̵̵̵̵̵̵̵̵˴˴ʳʳ˴˴̵Ͷ̵̵̵˴˴˴ʳ͸̷̷̷˶˶˶ʵ̷̷̷̷̷˶ʵʵ̶̶̶̶̶̶̶̶ʴȲȲ˵θͷʴưưȲ˵˵ɳǱǱǱͶͶͶ̵˴ɲǰƯƯǰƯìƾŽžŨää¥Ʃç¦¥¥ĪƬǬƬéħéƩƬƩ¨¨ŨƬŨ¨¥ĪǭʾȼȼŨǪȫǪƪƪȮ̴θλλȴ÷qiilrɽʾʾûĹçȮɳʶ̻ͼƶǷʶ̶̱ǪǾ~ŹʾªĪƬʿ·zmfcfkuɾ˲˲̵̵θλλкηƯéüǾȿwla~[zX|Zbm|ǼĤƦĤàɿ¸tb{qMl_<cV4i\\:uhHwYq·űǴŲİȳ˵ɯøw_{lMyjKxiJviIqT`|ɫˮͶʵ¯ȿ˿ʾɽĮȯȮȮͿɻsd|ZxS~[`m~ìĿïȲʲɯȫ}bxUtPtPuOvRezξǱʳ̶η͸͸̷˵ʴɱȱɯʯ˯˲˲˵˸ʹ̹ͻ˷ȰĨȺwh]`ixŭ˵̶ȱɿw{jP_K2X>'V<%X<&[A*aE-fL3tY>eJ{^hruoalKrZ8gP.cO,gT3xhGa|ȿże|iHnZ9mW2qW2uY2x`<pNnǫɲ˳ǲîİȴǴĪǷv{St^9hP,fN,fM.eL.hQ2xeGc}ŨͰβ̵˴ů¼inPiV8eR2fS3n^=|mN`y»ľªëëĬŭƮĮůǱȲɳȲǱǱǱɷʸͻͻͻ̺ʸȶƴųƳƳƳǴǴȵɳɳɳưŭŭǯʲʰʰǱȲɳʴʴ˵˵˵ʴʴɳɳȲǱǱƮȯŨäºxtx»śˤ̫ͩͭʰʲɱȰȰȰɱʲɯƬĪĪūĪƿúɿƭ̶ȱɲɲɲɯȮȫǪžĽü{w¹èŬ¬Į¬©ĻǪȫǭɯʰɯʲʲʲʲɳɳȲȲǯȰɱɱʲʲɱɱǯȰȰȰȰȰȰȰɱɱɱɱɱɱɱɱȰȰȰȰȰȰȰȰǰȰɱ˲ʱɰȯǮèūƬŬŬǯʴʴ˷˷ʵȰǮɭʮϰ̭ͮ˫ˬͫέͭʫðʷ͸ʴȰʹͳ̲˴˴ʳɲȱȱɲɲʳɲȱǰƯƯƯƯɱɱɱɱȰƮŭĬƮǯȰʲʲʲɱȰɲʳ̵ͶͶͶ̵˴̵̵̵̵̵ͶͶͶͶ̵̵˴˴̵̵ͶͶͶͶ̵̵̵˴˴͸͸͸̷̷̷˶˶̷͸͸͸͸̷˶ʵ˵˵˵˵˵˵˵˵˵ɳȲ̶ϹθǱɾíůưưưǱͶͶ̵̵ʳɲǰƯƯǰƯǿƽ»½Ŀ¨ĩéæüĺùǽ¹ýǯ̶͸ǱʾizW~tPvOxT]rƻʾɽɾzpiow}ƸéǱɵ̹ͼƶȶɳȯ¥wx{}~ĸȻ¬ưȰɱʲ˱ɯũȽ~tlc`bjtŪǮʳʳʷ˸ͺнϺȱɯǫȿƽzi\\wS~tPvS^n}źçǫǩĦ¢ãʿqyVnd@i[8i[8l]<tgGx]y̹ɴǳɲ˲ɯǼz`}nMyjIxiHwhGrSa{ɫˮη˸ǻȼɾª¨ʼue[{W{W`fu«Ŀíǯʰɮɬʼk}[wStPtNuRbxɱ˴ͷйιιͶ˵ʲȱȯȮˮ̮̳ʹ˸̹˺ʹ̺ʶǯĨȻrcZ\\dsƮɳ˶˵ŭŵ~nSbM2[B,\\A,]B-]C,]C,dJ1v\\CoThs{glJmU3dL*cL*dP-p]<tQkinKu^<s[7rT0vX4u[8zcA~]ɾƪʰʲƯůƱĪ;x~Txb;oW1nT1mS2kP2eL-oX9lNjħгϴͳͳŬ}_vaDdO0_J+`K,fS3m\\>yjKe~ľĬĬªëĬŭĮůǱȲɳɳȲǱȲɷʸͻͻ̺̺ʸɷǵƴƳƳǴǴȲȲɳɳɱǯŭŭȮʰ˱˱ǱǱȲȲȲɳʴʴɳɳɳȲȲǱǱưȽɿæ¡ŽºüŞơƢƧǪȬɯɯɯȮɯɯɯʰɱǯƮŭƮƮŭĪȿǼȽʾʾɽǳűƲǰȱȮȮȫǪħ¥Ŀþż§ê¬ưŬèȿwyƿǫǫƪɭ˱ʰɲɲȳȳǲǲǴǲǯȰɱʲʲʲʲʲɱȰȰȰȰȰȰȰɱɱɱɱɱɱɱɱȰȰȰȰȰȰȰȰɯɯɯʯʮɭȬȬɯɰȯȯƮǰɳ˵̶ͷͷ̵ʲʱ˯̰˯˭˭˭ʭˬ˭˭ѱɩ¥¦įʴǴ˷̶ʴ˲ʹͲ˰˳ʳɲȱǰȱȱȱ̵˴ʳȱǰǰǰǰʲʲʲʲɱȰǯƮŭƮȰɱɱɱȰǯȱɲ˴̵Ͷ̵˴ʳ˴˴˴̵̵ͶͶͶͶͶ̵̵̵̵ͶͶͶͶͶ̵̵̵˴˴͸͸͸̷̷̷˶˶̷͸͸͸͸̷˶ʵ˵˵˵˵˵˵˵˵̶ʴɳʴ˵ưƻƻůǱ˴˴˴˴ʳɲȱǰǰɲǰ««ǿzxxøy}}|xtxwwªǰůȼrvVtjGqhAqh?ulEvOiǼ¨tbxV{XaivĹ©Ʋɶʹ˹ɶƮʾriemvȼůȲ̶ͷ̶̳̳̳˲ɮĩȿ~l^zV|Y`jzȾīʳ̵˸˸нӾ̵δβŨżo~XsKvjDwkEsN`v¶ŻƫȭǬè¥¥ĥäǾcukHpb=m_8i[6k^;zmMjĸͺ˶ȴǰǮĨǾĹ}boN{kI{kIykHuTd|ƨƬʵɶòĵȼɽ̿Ⱥrb{W|V[amwĽ¨ŬůĭêīƫȮʭȭȫsawSnKmJpO}awоǯʳͷѺϺιη̶˳ɲȯȯ̯ͯʹεͺ̹˺ʹʸȵƯĩɺo_UX_nçʲĮǲȲƮɹqVcN3XB+XB-YC.ZD-^H1lV>rWmȴ͹űvvSpY7ZB\u001e\\D _I$hT1{kIflpKs[7mS.rQ.vU2sV4rZ8pOvūǭūɿ«¥ɺs{Pv`7oX/qW2uX6tW7qT6oV8s^AtX}źɭʭʮͮǩfzeFlU6eN/aL/dQ3gV:o`Cw\\tľȮƬ¨¨ĪéíĮưȲɳɳȲȲȲɷʸ˹˹˹˹ʸɷȶǵǴǴǴǴȲȲȲȲɱǯŭƮȮʰ˱˱ȲȲǱưưǱǱȲǱǱǱǱǱȲȲǴʾȽʿīǪŤƢɤ̥ɤƢ¡¥§ĮƯȬɬʭʭɯʰʰʰɱɱɱȰȲǱǱƯŬéŭƮíʽʿİïİƯǰȮȬȫȫƩŨæ¥¤ýļ¹ɿ©¬Ǳƭèȿ|qsɭǫƪʮ̲ɯɲɲȳǲƱƱǴǲǱȰɱʲ˳˳˳˳ɱɱɱɱȰȰȰȰȰȰɱɱɱɱʲʲȰȰȰȰȰȰȰȰɯʯɮʮɭɬɬɬ̱ʰɯǮȯɱ˳̵ɳʲ̴ʹ̲˱̱Ͱ˰̯αͰˮʭɭʭϲʪũɭ˴ʲɳʴƲȴʴ̵̳̳̰ʯ˳ʳɲȱǰǰȱȱͶ̵˴ɲȱǰǰǰʲʲʲʲʲɱȰǯĬŭǯȰɱȰǯƮǰȱɲ˴˴˴ɲɲɲɲʳ˴˴̵̵ͶͶ̵̵˴˴̵̵ͶͶ̵̵̵˴˴˴ʳ͸̷̷̷˶˶˶ʵ̷̷̷̷̷˶ʵʵʴʴʴʴʴʴʴʴ̶ʴǱĮɾ}|~Ǳɲɲʳʳʳʳɲɲȱʳȱìììsf~_}]`ku~tg~`bbdir|zre}Y}uQ|tPzqPysQ}]qìůȼjwlLlb>kb;md;of=ypGcȽūƮů|crOoKuQ|ZdyƺïȵɶʷǱʾm_Y[hy÷ȲͷθϹͷʴȲɰɰ˲̳ʱƫī¸xavRrNvT~[l{Ⱦ˴йλͺѾʳ̵βŨbuMxlDrf>vjBwRfķ˿ĮǱȲȯǮƫĩƩŨäƽpvStf?pa8j\\5k]8yjIdʷɴƱĭ©ž¹y`}mKyiGzjH{kIxUgæįŴ³Ŷʾɽɼȼŷ}tnawWvR}Waj{ȿħƬɰȲʱɭǬȫɬɫǪƧãôjxW~jG{gDjJx]nò̽Ƭ˵йιιη̶˳ʳȰɰ̯ΰϴзϹͺ˺ʹȷǴƯĩɺlYzO|QZkũͳưǲȲŮʺqWdO4UA)SA+XF0`N8lZBoWsȷϾǦ˩ţbxf@_G!aG\"cK'iU0|lHi¸Ⱥ²uwStZ5iM(rQ.tR/pR0oU4yeDcž¨éȼɽͽ˼lyMva6qZ1z^7eAjHfGx]?pX<xeGjȾæȩ̬ɪźqpQx_AmT6hP4kV9lX=n^DrXqɯȮééé¬ĮưȲɳɳɳȲɳɷʸȶȶɷɷɷɷȶǵǴǴǴǴȲȲȰȰʲȰƬƬȮ˱̲˱ʴȲǱůůůůưůưưǱǱȲɳȵĸųǱƫȩ̫έɨŦæīưųŰǭɫʬʬˮˮʰʰɱʲ˵˵ɶȵǴǲȲǰȳʷƳñǵñİƯǰȮȬȬɫǩƧŦŦƧƧãǿȿäèïůŬŨx|æ̯ȫũʮ̲ȮʳɲǲƱƳƳǴǲǱȰɱʲ˳˳˳˳ʲʲʲɱɱȰȰȰȰȰȰɱɱʲʲʲȰȰȰȰȰȰȰȰ˰ʭɮɭȬɬȫɫǬǬƬƭȯɰȲǰ«Ŭȯ˱ʰɮʮ˭ˮ̯ͰˮǫƪǬʭϲȨŨʭζ϶˵˷ȴʵ̷ζͳ˱˱˲̴ʳɲȱȱȱȱȱ̵˴ʳȱǰƯƯƯȰɱɱɱɱȰǯǯĬŭƮȰȰȰƮƮŮƯȱɲʳɲȱǰǰȱȱɲʳ˴̵̵̵̵˴˴˴˴̵̵̵˴˴˴ʳʳʳɲ̷˶˶˶ʵʵʵɴ˶˶˶̷˶ʵɴɴʴʴʴʴʴʴʴʴʴɳůǼozdv`t^u_i|źĮƯǰȱʳʳ˴˴ʳȱʳǰĭŮ«{k}^{rSvmNvpP}wWfr}ķµ{gwW{nN}pP|oO~qQ|\\nxh}XzrMphCnfBmgEwqQgĪǱʾdqgDh_8ja8lc8ne:wnE`ǼƬȰȲȱūĺhrOyiE|mFsOzXj®ȵȵ¬ɺ~j[{SzP^nȺ;ŲʷͷηͶ˴ȱƯȱɲ̵ηͶ̵̲δŮƻgxRrKqMtQ`oƯη̹ɶ̹м̹ìƯ˯s}V~rJwkAug@|nG}YpǮǲǲǲȳȱȱɯǭƪũŨħb}oHzk@uf=ug@sPhɵǲƱŭ©žúw]{kIwgCyiE|lHzXk¨ſɽȺŸ~upjh}`{Z~[dpyŷ̿ƥǪǭưǱͱ˭ɫȫȫɫƩŦƦ̽w}\\|hGzcAhHmRx_sƼưͶζζͶ̶̴˴ʲʱͰϱеѸкλ˺ɸȷǴƯ¨ȸ~e~RxKzMWhçʰȲȳǱìʸrXeP5VF/UI3_S=qeMz`vźʿŢʦȤdse>iQ+kQ,jR.pZ5rNn¸μ`}c>oQ+uS0sO-pO.mS2p\\;~mOkþƿǻƻȸĵfyKze8yb8lE{Wd|]kMsY>r]@y^øƿŦ̪̪Ţɹ{xXu\\>gN0_G+aL/aM2_O5o_Fu]ȮɯĪĪĪ¬ĮưȲɳʴɳɳɳɷʸƴǵȶȶɷɷȶȵǴǴǴǴȲȲȰȰʲȰƮƬɱ˱̴̴˵ɳǱůĮíĮĮĮĮůưȴɳʶɷŹĳŲìƬʮ˯ǫéìǲȵĳǭȫʭʭˮʰʰʰɱ˳͵͵˵ɳǲǰǱưǱɳƳïñȶïİƯȮɭɭɬʬƩŨħŨƩǪǨƧâĢƩɭƭŮíūŨĢûħαɬũʮ˱ǭʳʲȲǱŲƳǴɳǯȰȱʲʳ̴˴̴ɲʲɲɯɯȮȮȮȮȮȮɯɯʰʰʰȮȮȮȮȮȮȮɬ˭ˬʫɪȩȨȨȨƧǨȬɮ˲ɱǱ¬Ƭʰ̲̱ʯʮʮǪȫǪħæȪˬæžĪ˳̶ɶɵ˷͸ϺϺ͵ɯɯ˲̴˳ɲȱȱȱɲɲ˶ʳɲưĮĮíĭǭǭȮȮȮǯƮƮëĬƮǭȮǭƬũũƪǬɭɰɯȮǭǭȮǰɯɲ˱̲̲ͳ˴˴ʳʳ˴˴̵˴˴ʳ˱˱ʰʰʰ˲˲ʱʱʱɰȲɲɳʳ˶˶ʵʵɴȳʴʴʴʴʴʴʴʴɳȲín{qXoeLmcJkaHlbIwmTjŮƯǰɲʳ˴̵̵ǰɲƯìƯn{^{rStkLtkLxrR}]o|ľ¥øxbzlOqcFseHqcFseHtWpȽøø·yi]yqMsmKrlLztTjǫʯ`oeBi]7l`8nb:pd<xlF_źŭȲɳʵȱlqMvg@xi@qJtPa{îȷȵĵn}ZtOtNvPhyʿéĮƳʸ͸Ͷ˶ɲƱǰɴ̵ɴ˴ʵȱ˶ηƱŻr}YsOoK|nKuTbzɿɲȳıƳȵȳĨˮnvPznFth@rf@}oJ]tŧ̵ʷȵƳưůưƮƮŭĪƬʭæu|YxQtOuR]sĻǴȵȳǲƭ¨Ƚǹv\\zjHwgEzjH~nL}\\pŻêȽʿʽƹȻķzrjggfcdkvôɻǧʭɬŭíí̳˯ɭȬȭȫƪŨƪŴ~~^yfEt`={dD~dImS|av¨ʯ̳ʹʹʹ̴˴̵̵̲γзѻϼλ̺ʷɷȲƯĵ|bwO}PR[jƭĮĮ«ʾĴqTcP2YI0ZN6i]Ev\\uʩʦʦϫϬƼp|nKbL'fL'gO+mY6tRvƾĠξ«gjGuW3wU2rN.nM,oR2nU6s^?wYsúʿɾƻĹõzbwJ|e9~f:tLctjxWx_@q]<vV{ķŤ̫ͫƤĢͽ}z[~cFmR5bH-dL0bL4^J1hV@zkTwũȬĪūū§¬íưȲɳʴɳɳɳŲŲɶɶʷ˸˸˸ʷʷƳǱǱǱǱǱǱǱʴɳɳȰȲɱɳʴǱǱưĮíìİǲïŰȳ˶˸̷˸ʷǷǷǵȶɷȵŲĮȲǱǴɶʷɷų¯ŬèǬϴе˰ɯ̲̲ͳ̲ʰȬɭǬĩȭȯǮŬêĪƬȮǭǭƬƪƪǫȬʭȮǮŬŬǮɰʱʱɯɯɯȮǰȰƯǭĪŨħĤáſǪĩèƫ̰ͱɯĪêŬƭŮƯȱʴȱȱǱʳ˵̵ɰȮƭɯɰɭǬǫƫǬɭȬũũȬ̰ˮǪƩŨŨŨǪȫȫȨɦ˦˦ȣɣ˥ɣÝſ¢ǬɰíɾȽƻ¬Ȳɲʲ̴̲ɯħƿýĻķµż§ɯʳʵʷʸѾ̹ɴǰȯɰ̰ȭ̴̱ȰǱɳȳƱȶʶɵı¬ªħťŨƩȫǭɮʯƬƬǭƫƪǫƩȨǤȣƣƥĦƩƩŪȬȬȮȬȮʭˮ̯ǫȮɯʰʳ˴̷̷̵˴ʰʮ̯̯˫ȩǧɦʪɩǩǩȬʯƬȯɳɳȴƲŲðʵ˶˶˶˶ʵɴȳǯɽyxlReZ>g\\@h]Af[?dX>k_Ew]«ĭʳͶͶʳɲ˴ǰƯ«ǿmyrVpiLibEmfI~wZqüƨǪɫǫƩ¥æsXvfLk[Am]Ck[Al^C}oTtæŨǧƦƦƦã{ifel|§Ͱ˫¡eviFj\\9j\\7l^;m_<vgF}`¶İűɷ¯ɺj~lFsa9yh=}lA}nE}XwȿƴrhxX}mL{kJwhG}]v¸ʳ˶Ǵ˸ɶɳǴȲȵ˵̹θλθ̹θͺ̶ȵŮ·frP}oLzlIzlIuRcƻǬǰǱɵɶ˱αʫŧƻzzW}oLpb=pc@reCwmJ`ũɳǳƲƲǳɵʶʴɳĮĮɳǱvpnoxĪȸǵǵȵ˵ɲ˿Ķx}_ziKueDwfH{jL|^vɷоϽ˹ȸƶĴxqmkgbikpzʿŤǨȫɯȰưůƲǳһϵ˳˴ͷͷɳį¬Ʈ̾~]yiGweAzhD{fGzeHoQe{£ҲǪɬǭƭǯͷκ˷μͻ̺˹˷˷˵˳ɱȮǭèô}f|YVU\\iǯĭêt{kI^N-ZI+aR5ykNoùğŠġħ˽nRhQ2aJ(`L+r_?|]zĤ¢ȿ¢äîjfHsV6tS2sP0uR2wV5tV4uX6iH}[¯ν;ǹøùǺy^zMnAk>UuƮ|`~kAuc;xQqήϱǪƽȹŲvuVnS5jL0gL1kP5hN7bJ2hO;p\\Dhʿ¥ɯ̳ƭíĮůưȲɳʴ˵ʴƳƳɶʷʷ˸˸ʷʷɶǱǱǱǱǱǱǱǱɳȲǱưưǱȲɳɳȲưí¬ìĮƱįįŰŰŲȳȵɶʷʷʷ̹ͺͺ̹̹ɶɶɶ˸̹˸ȵƲǱƭɰ϶Ѹʹ˱δ˱˱ɭǫƩƩƩŨʮ˯ʮɭǫƪȬʮȬǫǫǫƪǫǫǭƮůĭŮǰɲʳʳɳɱɱȰǯƬūŨæåĦĤĤĤġ¢Ũ§§ĩȭ˯ʰɯūȯʱɰȯǯǯǰǰưưȲʴʴɰǮʱɰȭǬƩŨƩƩħŨŨŨƩǪƨåɾƽżƽȿ ½þ·ʿéëİɾŰ˵̶ͷͷɰ§}xqnrȲ˷˸ɸͻ̺̹ʶʳɰɰɭ̱ϴ϶˲ɳ˵˶ɴȶƲĸþæƫȭƬǭŪæ˽ƹĵµĺɾ¦¥æĦŧũƪǭɯɲɲɴɴǰƬūŨǪǧá˾ɼɼɾŬǱȲȴȳȳ˶˶̷̷˶˶ʵɴɳªȼxynRf[?f[=bW9aV8`U9h]Av\\ɾĭǰ˴˴ʳɲɲȱȱŮǿ}jby\\}`nžæƩǪƩħæ¦ĨrXtdKiY@l\\CjZAk]CymSs¦ƩǨƤŦƧƨ¤Ȭ̯ǥbwiFk]:l\\:o_=q`B{jNeɼñƵı˼hnHub8ud8{j>{lA|WwĻȽc}\\qP}jL|kMnRiǼ«˵˵ǳ˷ȵǴƳŲƳǴɶʷ̹˸˸̹ͺ̹ɶǱŻouR}nMykHxjEsN]yŸǪǮǱǴɳȬˬĤʿstQwiFqc@qdAsfFwnMdǬưƱŰŰǲɴʵʵ˶ƱîįǲŰȰǷǷƵȵʷȲ˿õz|`yhJveGxgK{jNy]rí~ypmkjosyy~žçĪƬǯǱǳǳȴ˶һϷʵ˶̹ͺȶıïư˽a|nKyiE{kG}jJ{hJ~nM{ZjyǽƥȩǫĪƭ˵Ϻλ̿˿̼˹̶̶̹ͲʰȬȫ¦|hz[|SSZjɱɯȯƩt|nK`P,]M,hX7rQrĻƿŠġ¢ĪͽoWgR5cL,fQ2wgFfħ̽ggIwZ:uT3qO,rP-vT/uT1uU/`=rMnѽâ˽øöv[{LqBpAXxʴ­~fwKqF[{ǻĠƦǪæømvWfH{^@rT8iN3cG/cG1iN9rYCoQvȺʮɮɱů«ĮůůưȲɳɳʴɳƳǴɶʷʷ˸˸ʷɶɶǱǱǱǱǱưưưȲưĮííĮưȲȰƮëſªĮǱưĮĭİǰȴʶȴǴȵɶʷ̹ͺλǴǴǴɶ˸˸ȵƳɳȯɰ̳ͳ˱˱δͱ˯ʮȬǪƩƩƩ˯̰̰ʮȬȬʮ̰ǫǫǫǫǫǫǫǭƮŬêêŬƭƭŬŮƬƬƬūĨ¦ƿ¢Ĥťţţť¥¦çææħƪɬȫɮ˰ʯǬŬŬŬƯĮůǱʱʱȯƭ˰ʯȭŪŨħħħͿħħɻĹøýŹʾíȽìǰʲͷͷƭ~md_ZX[gqêɳʵǴǴȵ˷̸̶˲ɰȬεз͵ɱɱ͵η̵İʿrjfluſĩǬǭǭĩǾ|wolq}úú»»½þ¦ĪƬƯŮį­«ƿſ¶Ƽ©ůȲʳʵ˶̷̷̷̷˶ʵɴȵíȼ{uYk`DeZ>_T8^S7^R8fZ@~rZ}ííŮƯȱɲʳȱƯȱʳɲĭļ{~ž¥ħƩǪƩħ¥çƪ¸~}oUrbIgW>iY@gW>hZ@vjPqŨȩŦäŦȪʬȬũçſêīŬħ ļbwiFl^;n^<p`>raC|kOgķǼʿĮʼdrKxf>tc8zi>|mD}ZzŽútvVqP|hGxeG|kMqUpĺìʴɳƲʶȵǴŲıııŲƳ˸ʷɶʷ̹̹ʷɳvyV}nMwiFugB}oJxUqħƭǱǴǱǫɪ¢źl}oLtfCrdAreBtgGypOg½ȭ­îįŰǲɴʵ˶ȳįî­­þľŽýľſªůǱŵǷǶȴ˵Ȳ˿wy]xgIwfHyhJ{jLtXiz}}vnhayXxW|[dlwǾǾú¹Ľ¦éƮǯǱȲ˷ιйζ˴˴̸̸Ǵðīŷ~~_}mKyiEzjF~kK{hJzjIpOyXevƽäƪĪīǱ˷̹ʽɽ˻˹ͺͷθϴ˱ɭƩɾvdxYxO{QZj¦Ȱ˱̳ȫqzlG_O+`P/o_>|[zĻĽžŠŢĤū̼qXgP1cL,iT5mMnúĥǷerQhFb?zZ4vT/xV0xV1uU.zZ4d>ZxѺŤĹpY|LuEvE]ë}θǲoYZqƣ¢ȿµvjbaz\\iLqV;eI1dJ3iN9jR:kZ>|]ũɮĬưưưǱǱȲȲȲȲȵȵʷʷ˸˸˸ʷɶȵǱǱǱưưưưůȲưĮ¬¬ĮưȲŭ¨Ž¼ļſëǯƮŭŭŭƮǯȲĮůıůıưȵ̶ƳưŲȲȵʴǴưȯǮƭǮƬǭɯʰʮȬȬʮɬŨæħȬɭʮɭȬǫȬʮĨũƪǫȬȬɭʭƬŪèèĩĩ§¦ǾſĻ¼ƽſȿȿȿɾ¤ũçɾżǾ¦ĨƩƩĪ¨èŪƮĭ¬íůɰɰǮŬƫƫƫƫǪƩæ˽˽̾ɻ¼ľÿysszŹƼǿĭ˵̶Ŭu}`vUwUzW|W~Y\\bp¸īƯįưǱɶ̶ͷʹ˲˯̳ʹ˳ǯɱ͵Ͷ˱ɿ|m|`x]|`iuľéǬɮȮɬŨĻvh`ZZbrú½½žéūĭ«ƾƿžƿ¼{wttu}ǽ©ůȱɲʵʵʵʵʵɴȳǲƳð˿jvjPg\\@bW;`T:_S9dX@wkSuưȱǰƯȱʳǰ«ìȱ˴ȱ«ƾƾž¥ŨƩǪǪƩħ¥Ĩǫĺ|{mSo_FeU<gW>dT;eW=sgMoħˬȩŦŦǩʬʮʮǫƪūƬȯƭêºbvhEk]:l\\:o_>q`B|kMgĹȽʽõ{~[qM}kCvg<yjAqJ`ƺ®úooO~jIwcBtaCxgIpTrɿíìɳȲű˷ɶȵƳıððııɶȵǴɶ˸̹˸ʴŪƽ~}Z|mLugDrd?ykF~pMjŬǱƳưʮ̭åźj|nKugDrdAseBuhF|qQjĽǭĿîįŰǲɴ˶˶ʵƱ­îűưƮƮŭĬêóȶȷǳɳɰɽpuYudFveGyhJyhJpT|`ii~ev[sUsRpO{kJxiHuThyźúƽȾǽŻŻééƮǯǱȲ˵ηϸζ̵̵̸˷ƳîʿȼtuWyiGueAueAyfFyfHxhGyiH}nMzYiwæƪŭưǱŲǸǸɹ˹̸ͷͷε̲ɭŨźq|axWvMzP[l»ũĪĬɯ˰Ʃhtd@[K'bR0wgEe¶ĻüüǿßàæǸzoTcL-bI*jS4nOqźãοó}la]ySiB~\\6|[2{Z1wV-xX/|_7pIiȲͿķiTJzG{H`í~͸Ʊuhmɺ¢¡Ƚqr{ztb}dFlR7iO6gM6^H0cR6ufInǽŽſűǱǱǱǱǱǱǱǱǱɶʷ˸˸˸˸˸ʷɶȵǱǱǱưưůůĮɳǱưĮĮưǱɱĪƼüǽ¨ĪūƬǭǭƬūūĭŮŰĭ­ìƱɲƱŮŰƯǲȱƱƮǮǮĪ¨éūǫǫũçħȫǪƽȿ¦ĨũũĨçĨũ¦ũǫɭʮ˯̯ƩŨħŨƩƩŨæɽǾƺú·ʽ¥ɻøĹƽħħæƿçƬ©ŬǮȯƫĩɿħȫˮɬæǾȺĶsnqrzúľĦĦýtlgkr|Ⱦ¨Īɱ˳Ŭn}tWvmL}pNuRzU~XXYbsĻĨƬŮǯɳ˳̴εεεʲ˳ɲȱʰͳʱĩ¹{j{]~sUuX~bqļŭȰʱ̳ǭʭƩúm\\{S|TVauƻȿƼƿƿƿ¥æ¦ĨǭɯǰŮ­ì¨ææ¼iecdkw¹Ⱦ§ŬǭǰǲǲȳȳǲƱŰŰ±ððʾw]j^DbV<`T:^R:aU?nbL|iøůʳʳǰǰɲǰǿĭʳ˴ƯìȮĨçççũũũĨũƪƪǫǫũĨççǫĺ{xjPm]DdT;eU<bR9bT:qeKlƿħ̭ʫɪȩȫɬȬȬȮǭƮǯɰʱȯƫ¢ĻbvgFj[:jZ9k[:q`B{jLgĸƻɾɼɺlqPzlG{lEyjA~oHxSiɽűºlkKyeDua@s`BveGoStɿí«ǱǱƲ̸˸ʷȵŲııŲŲȵǴƳǴɶ˸˸˵ȭä]{lKrdAoa<ugBxjGcĻêǱƳů˯ϯƧźh{mJugDqc@rdAtgE}rRlĽƩĿ®űƲƲƲɵ̸ʶɵƲþĿİȴǱưůíĿþȶȷƲǱǮŹjpRraCtcExgIxgIpR}_dawY}mLwgFwgEwgEtfCqc@tQmȺɾ˿ɿŻĺɿ¨«ëŭǯǯȯȯʱ̵Ͷ͵̵Ͷ̶ʴƱîʿ÷gpOvfDvd@ubAwgF{jL}mL{kJykHrO]gsžȬ˱ʲưĵŶȸʸ̸̶̶ʹ˱ɭħøkz\\vUvM{R]pƿȯȰëȮ˰_o_;\\J$fV2pLm÷ĻüüĽƾȿ;p~kMcJ+bH'lS4pPrǸ˾ĢǤϿvpnl\\oF~^5z[/z[/wX,xY-{^2h=XwıƷĶdQI~F~K`|ȳıy³ɾŤù{uɳǰi~eGjP5fN4dL2\\G,cR6fW:~nT|ŽŲȲȲǱǱǱǱưưǱʷ˸˸˸˸˸ʷɶȵǴǱǱưưůĮĮĮȲȲǱǱǱǱȲǰêɿƼƼȾɽƼʾ¨ũūũ¨§īȮǱȮíūư˱ǱȮĮƬůȮĮĭƮȯƬ¨¨ūƪĨĨžǾ¥ú¹ǾüžƿžƿĨȬʮ˯˯˯ŧŤŦŤƨť¥øķķȽʿʾɿèɿɾêƭƭŪèǽȾ¥Ǫˮɬæƽõym}`|^dhtĻħȫɬƨĤſ{ofdgp{żɿèūȮɱªmyrUsjKvkK}pNtQySVUXezžũĪƬȰʲ˳̴͵͵ʲ˴̵˱̲ʮyh|\\}rRxmMvVe~ưǱȲ˲ƬɬŨf|UvN{S[kåƩèƬūūūūǪȫɬ˯̰ͳδ̵ʳȳƱǰƬūǪƩľz_\\[]gwĺƻħƫǬǭǭŮƱƱƱƱŰįîĳƵðɼjl`F^R:[O7YM7ZN8bUBxkX|Ƚǰ˴ǰƯɲǰ«Ư˴ɲĭĭȮʰʮ˯˯˯ʮȬȬƪƪǫǫǫƪƪũ¦ƪŻyvhNl\\CdT;cS:`P7`R8ocIkŨɪʫˬ̭̯̯˯˯ʰȮƮƮȯɰȯǬæżcwhGiZ9hX7iY8q`B{jLeĵʾȽǼŶ}`whGseBykF~pKzUbwɿïf|eEvbAt`?taCveGpTvɿ¬ǱȲǳ͹̹˸ȵǴƳƳƳǴȵǴŲƳȵʷʷʴȭƧ^zkJqc@n`;tfAugD_ưƳűɯ̯ƩúfykHtfCoa>pb?reC~qOjż¦İȴȴǳǳɵ̸ɵȴƲï®űȴȲǱĮíîįȶɶİĮīd~mOraCtcEwfHyhJuWipmduSwgEqc@pb=oa<m_<~pMhõͿ¨ëůǼĹʿ«ŭǯȰȰǮǮȯʱ˴͵Ͷη˵ɳŰ¬~`}mLyiG|jF{hGrQz\\^wV}oL|nKtQxUcwʮ̲ȱ­ĳŴɷ˹͹̸̶̳ʰȬ§·fyYvSvP}Tbvç˲ɲƮʱʰĽ{Xo]9`N(p`<|Xv÷úüĽ»żǾȺdxcDgM,gJ*qV8uVw²´ϿǵwjoroXnB|]1yZ,yZ,wX*yZ,~_1b6uI`sĵ²^LHIKazðųͿŮ­̾ġǾ|w~°͹˷`u^>bK,^I,bM2bN3cO4`O3r`Hoʿ¯ǱǱǱǱǱǱǱǱȲ˸̹˸̹̹˸ʷɶȵǴǱǱưưůĮííưǱȲɳɳȲǱŮȼĸ÷źøõõĶĶǻëĩëǬƮĩ˿Ⱦ¨Ƭūƿççúüü»»¦çƪɭʮʮɭȫǧŢ¼||~{|ĶɾͿ˿ȾȾɿ©ŪŪĩ§¥æǨǨ£ƽ}ldz]sVwYcny¹żæƬȮɯǪũŨ~md`ahqǾĨǭǭw~avWuWxX}[_ZWUZh{Ļƿ¦Ƭʰ˴ʳȱƯɲʴ̳ʱǬsc{XxUwTxUbwǴŲĮĮǮĪǪäzaxQsKwO\\qȽǩʭȭɯǰǰȮȮɯˮ̯ββϵδ̵˴ɴȳɲȮǭɬȫľt[XY_hyǽȾʿäƧǪǪƪūŮƱƱƱƱŰįîŴƵð̿qk_G\\P:YM7VJ4TG4UH7dWFxhǿɲƯĭȱɲŮƯ«ǰʳǰŮȮʰʮ˯˯ʮɭɭʮȬȬȬǫǫƪũũƪĺyugMl\\CdT;cS:`P7`R8nbHkƩƩɫʭˮ̯̯̲ͳȮƬĬĬůưŮĩæżgxiHj[:iY8iY8o^@wfH}`ĵɽøltWuhHreC|oL|Yjw·©®ezcCt`?t`?taCtcE~mQtĮìȲȲǳ̸̶˵ɳǱǱǱȲɳʴȲưưȲɳʴɱƫȩ_yjIpb?n`;se@tfC]~ȾưƳƲǭͯƩĻfykHtfCl^;m_<pcA}pNjúƿůɳʴǱůȲ˵ȲǱůůůưưůǱưűİįŰŲŲȶɶ¬ª|}a~mOscBueDwgF{kJ~`w~ivSvhCqc>nb<ma;wjG|ZpĶͿªïɾø·źɾŭƮȰȰǬǬɮʱʳ̷ͷͷ˳ȰĭêʾuxY{kJlKqMqPbouk|YsP}qK|pJzVf{żƫȯŮǴɶ˸ͺϻκͷʹȮǫè·fxXvSwP~UdxĨ̳ɲǰ̳ʰutPo[6dQ)mGd¶¶üžúżĶ~~\\t`=gM,jM+v\\;|Zy~v_XfokZuHf:d5c4z^.{\\-~_1|`1h;vJa{ǵĲzZIJKQd}ŵŶȸοƱȵ²οŹrvǵĲpvUs_>eP1_L,bO1gT6bN3_N2jX@x_Ĺ¯ǱǱǱǱǱǱǱǱɳ̹̹̹̹̹˸ʷɶȵǴǱǱưůĮĮí¬ůưȲʴʴȲưĭȾĸ}}}~ǻȼƺŹȼ˿ȼǻǻƺŹ¸ž¨¨ýüƿ~ttqovũƪȬɭɭȬƪŨʪǤſ}wtrpps|~ztlgejltǹϿ̾ȼǽȾĩŪè§ǪæȿȿäŦ£Ǿr{^uXrU~pSxZfyĻƽ¢ŨȮɱȰūƬʮȫĤȿue[{T~W^rȿũūſsjjkora\\W~W]lƿũ˱̲ɲíůȲɱǬæm\\uQ}sOzV]dw·˸ͺǴíëƩ£v]tM|pHsM[sʿȬʯʱȱǰǰǰȮɯˮ̯ͱͱ̲˱ɲȱǲƱʳȮǭʭɬýp\\Y[_kzȾ£ĥŨħçƯƱǲǲǲƱŰį²ƶĳ˾rj^H^R<[O9VI6PC0K>-UH7sfVsǰŮ«ȱ˴ɲ̵«ƾĭʳȱƯƯƬǫȬȬǫǫȬʮʮʮɭȬǫũĨĨƿũĺxugMl\\CeU<bR9_O6_Q7nbHkǪƩȪȫɬȫɬɯ˱ǭƬƮǯȲȲƯīżgyjKl]<jZ9k[:kZ<q`BvY}Źzjw\\}oTwiLuhHvTf}·ƭíg{dDua@ua@s`Bq`ByhLo§ưŮʴɳƲ̸˵ʴȲǱưǱȲɳ˵ȲưưǱɳɳȰŪȩ_xiHpb?n`;se@ugD]|ǽůǴƲǭαɭžhzmKvhEj\\9k]:na?|oMiøĽůʴʴưĮưɳǱưůưȲȲưíííïïŰįððʵɶ¬ɿx|^oNueDvfExhG~nMfŸô|bsMvjDrf@rf@tgD}pN_yǹ˿ȻǼƻƻƻǼ­ëŭǯǯȭȭʯ̳ɲ˶ͷͷ˳Ȯī§ƻlrQ{hGnMvRwVn~zf{VtN|pJsM}YgxǾƫǮʵ˸λϼѽмθͷƮƬħøexWvSwP~WfxĨ˲ȱȱ̳ǭnnJnX3fP)wQnƺ¶üƿ¹Ļ´y|Uq]8dJ'jL*z]=}\\ywkoobvKyLalhcTvHrCm>d4z^.|`0{_0{`1k?VxɶñtYHHNSiŶȺοǱɸǶ³οͿƷ|nxĵȶubrQzjHr_?dT3bO1gT6cO4aM2fR9xhOtʿðưưưǱǱȲȲȲʴ̹̹˸˸˸ʷʷɶɶɶưǱȲɳȲưíĮĮưǱȲɳɳȱǽƺqiy]d}_|^_at·ƻǼźøøøüüzjxZtV}rTuWas»üüĽȬ˯ʮũçƪǫƩ˩pd`kns{µŸȻȻȻȻƹķwkf^uT~oPpQpShŵ̻˻Źè§èŪħħäŦub|nQ|nQwZdpzƽƽż¥ȰǯǯǯƯǭǫǪĥúq`zS}tM{rK`rƽǪɭȮƬ¨~wi]Y~W]k{ħɮǮī¬íȲů«˿~kcwS}sO{qMyUh|ǳƶǶƵƴŲİíëȫkyS{mFth@~rLxQpĨȭǮŮŮĭĭūƬǭǭʮ˯̲ʰǰŮƱǲǰǭȮʭǪkYTUZizɿ¥æĨĪƯǲǲȳȳǲƱƱóȸŴɼķi^R<VJ4VJ4XK8XK8TG6VI8gZJzo]ŮŮǿĭìɲƯì«Ůȱ˴̵˱ʰɯǭūƬʰͳ̲ʰȮūééééĨ¸wugMk[BdT;dT;bR9cU;sgMnħŨǩǪȫȮɯȱȱǰĭ¬¬íĮŮīĻizkLk\\=gW6fV5eU4kZ<|mPoesY{mR}oT}rTwYiƽƩʮʰ«h|eEt`?q]<o\\>n]?ziMsǽǱɲǱǱȴǳɳʲɱȰǯǯʲ̴˳ʲɱɱʲȰŭ¨§£^zkJoa>m_:se@ugD]}©ʴȵű˲ʭǪžoyWxkHseBqc@pb?wjG]yȿūĬĬƮȰɱɱɱʲȰƮƮɱ˳˳˳ưůí­­ųʵɶȲʲĩxsUwgF{kJueCwgFuTdöźŸs`tNuiCzmJreBreCtRoɽŹ·øƻȽǿƾǯȰȮɯʯ˰˰̶̳κθʴȰȮĩx~_tSoNnMyXf||`sN|pHuiA}qKzWdvźèɲʵ˵ɳ̸ϻ͹ǱɱȮ¥xcyUtOxQ}VhĹū̳ϸ̶̳¦cxd?pX2s]6~Xyõƺʾż¹ŸqtKlY1cI$gI%x[9{XlezWsPvQvNqIpE}Odt|pqm_|Nm>e6}b3y^/z_0g;yMkvXEIQYmǺɾɽŲĳ̿̾îȸu`dx}xrlg~`qRq`BhW9hS6dO4bN3n]C|eǼȴȲȲȲȲȲȲȲȲɳ˸̹˸˸˸ʷʷɶɶɶǱȲɳɳȲů¬ĮůưȲɳɳɳȱȾɽĶnx\\{jNpRlN}jJpPqRi|ø|e~uVtiKrgIqfHtiKuUfzĽɭ̰˯ƪũǫȬƩ¡}pc~\\}[iq|ķʽ  ã¢̿ʼɼqg|[}nOteFqbCrcFtWhr~Ŵʺȼ§èŨææ££ä£¹~drUtfIykN{^n}øǾƽżſǯȲȰȰǰǰǭǫǪǾyf~W~uLzqJvSaxȿǪˮʰɯū¨ƿǽĻte\\zUyT]gwȿ¨ĬǯʴįοȺn^|XvOwP|XevøʾƲŵƵƵƴųűĮŭȮhvS{mHuiCtNwSpũɰǮƯŮŮĭŭƬǭǭʮ˯̲ʰǰŮƱǲȱȮɯˮǪ~iVRS\\júĠ££æħĨĪȱȳɴʵɴɴȳȳŵǶƵ̿ķv`[O7VJ4XL6]Q;_R?ZM<WJ9_RBj_MnûŽĭĭ˴ȱƯŮǰɲɲɲʰʰȮƬĪūȮ˱̲ʰȮƬĪéééƿçuseKiY@bR9dT;bR9dV<thNpƿæħƨǪȫȮɯȱȱƯĭ¬¬íĭêƿ¹hwhIhY:fV5eU4dT3gW6teF}`vzvm|atZuZ|afl}ɿũʮ̲˱Īf{dDs_>r^=p]?p_A{jNrǽǱɲǱǱǳǱɳʲʲȰǯǯʲ̴˳ʲʲʲʲɱŭéȿ^zkJpb?l^9se@wiF`©ɳȵƲɰȭŨy^}pMrdAoa>m_<tfCzXsúªŭȰɱɱȰɱƮĬĬƮȰȰȰɱȯíĿìų˶˶ɳʲĩuvUxhG|lJvfDxhGwVfƸɾɾp]rOzmJqdAob@{nLbx´¶·źƾ¨ǯǭȮȮʯ˰˰̳˵͹ͷʲ˱ʮæźkvU~nMlKrQ`rĶõ~bvO~pI|pHsKuOxUawɾǮʳ˵ʴ̸ϻ͹ɳʴȮv`zTvNyR}XkƻǭʹѺк͵¦~\\s_:oW1u^5\\|ŷɽȿ¹żi~oFkX0kQ,oS.}a<vS}YoMw`>o[8r^9s_:s`8yh=|Ngz°vc~Om?}e7ya3x`2zc7sHby|qRCIUat¶Ⱦ¥é®ųƴóʽǸc}SZqgwhIcR4iT7hP4eP3nZ?rYzǼȲȲȲȲȲȲȲȲɳ˸˸˸˸ʷʷʷʷɶɶʴʴʴɳǱĮ¬ůưǱȲɳɳɳȳ¬ī˿÷õpuYwfJ|iKvcEwbCjKpQküĺ¸ntVtiKoaDobBqdDtgGuUhyž¦Ȭ˯ʮƪũǫƪæyk_yW{X]o{ùȾ¢Ĥ¢¤¤¤ʿźsdqTpbEhZ=eU;p`FzjPrX|dxǷʾ§§ȾǾæƩǪä£äúwjsVxjMtfIsVløǼʿȿżżæƬǯȰȰǰǰƯǭȭæp\\vMwnEymGtQbzɬɯǮǮǯȮȮũȾĻrf\\yUyU}Ycpǹ¨ȱͶìʺt`wTuO{T]l|¹§ǮűųƳƳƴƴƲưȰɯƼesQzlIwjGrOuQlƪʱǮǰƱƱŮƮƮǭǭʮ˯̲ʰǰŮƱǲʳɯɯʭƩ|h}T{Q}S\\oȿȤġãĥħèĩūūɲʵʵ˶˶˶ʵʵǶƵƵðµwkSXL2RF.TH0ZN8]Q;ZM:UH5UH7XM;xmYvŽ«ƯƯ˴ɲǰȱɲɲȱǰɯɯɯƬĪĪƬɯ˱ʰȮƬūĪééƿ¦sqcIgW>`P7cS:bR9eW=vjPqƿèũƫȭȮɯȱȱǲįí¬ïïîždsdEfW8eU4fV5eU4eU4m^?rUgjf|b}`}`iyƿȮɯɯɯɯĪaybBr^=q]<p]?raC{jNpǽȲʳǱưƲưʴ˳ʲɱǯǯʲ̴̴˳˳˳˳ʲƮĪǽ¹\\|mLrdApb=wiD}oLgżêȲȵȴȱǫæixUwiFqc>m_:rd?tQhƿªƮʲ̴͵̴˳ʲȰƮŭǯɱʲɱȰūľýëƭƱ˶˶ʱʰæsxWzjH}mKwgEyiGyWiĸɿ§ȿq^zpMpfCl_=qdBrRcx¸ƿçƬǭǭȮʯ˰̸̸̱̳˵˳δ̰ȿs~]|lKwgE~kJvUj}v]rKylB~qG~pI~pI~pKvSfõèȮʲɳɵ̸˷ȲʴȮȿs_{SyQyR~YlȽɯζѻθ˳ǽtSnX1pW/{d;dʼġļļ¹|^xi>kX.hO'pT-~b;oJmIv^:jS1gS0eQ.dR,hV0uf=Wt´Ⱥ˾˽ʻųybtJ|e9v_3u^4w`6mD^uzpP|CJ[kƼäƪȰŰıǵȶƹdyLnC{QlµĹ˾ƸuXgV8eP1fO/dO0kX:ziMkǻȲȲȲȲȲȲȲȲɳʷʷʷʷʷʷʷʷʷʷ˵˵˵ɳǱĮưǱȲɳʴʴɳɳƱȲưȺw}c}lP~jOwdFydGpQ{\\xƿũũƿüçh|qSrgInaApcCsfF{nNavĽǫɭȬũĨĨĻ|l_xVxV`k~ƼĠȿʿâʿʿʾúxe{mPn`EbR8gW=k[Ao_FzhP~fƺ§ɿǾ¥ƩǪ£ä¡życvUwiLugJ{mPc|ƻʿʿʿǾżúż¢ƩĪŭƮǯƯƯŮĭɰŪȽ{dvOvjBzlG{mHwTiçƬ©īŭƮŮéȾĺ}pf]}Y}ZbpŷŮówfzWxRzTcrƽíƲïïııŲƴȴȴ˵ɱù}`{nNxiHwjH{nKzpLjǭ̳ȲȳȳǲƱǯǯǭȮʮ˯̲ʰǰŮƱǲȱȮȮɬŨ{g|SzP|R^sʧťŧƩŪŪīūĭȳɴʵ˶˶˶ʵʵǶıŲůqnbH[O5SG-TH.VJ2XL6XL6VI6UH5UJ6g\\F~v_}ìƯĭƯƯƯȱɲɲǰŮɯʰʰɯƬūƬȮ˱ʰɯǭƬūĪĪçrpbHgW>`P7cS:bR9fX>wkQsƿèũƫǬȮȮȱȱȳƱůĮİİîƿdrcFeV7fV5hX7gW6gW6n_@rRdkkinr¸ü¨˳ɱƮëªūé~^xaAq]<o[:o\\>q`ByhLkùǱʳǱůƲư˳˳˳ɱǯǯʲ̴͵̴˳̴̴ʲǯĪùx|Y~oNvhEtfA}oJxUqīǱȵɵɲǮĩæƿx^qNwiDqc>se@qN`vĽªȰ͵ζ͵̴˳ɱǯƮƮȰʲʲɯĪĺüƬŰɳʵȯǭlwVyiG|lJvfDxhFyWj÷ǼʿɿŻpwWwmJna?l_=reE~qQeu¹úžçƩǪǭȮʯ˰̱̳͹̸ɶ̴ϵˮ·bvSyiGyfElKyXl}|xsof|U~qGzmC{nD~qGsLtMwR_uǾūɯȰǱȴȴƲ˵ǭżp\\|T|QxQ}ZlɾɯζѻͷʲƼ|sPs[5|`9rJnàǥƣȿûûĺuUte:kZ/fO%qX/h?sJlFv`;r[9s_<lZ6gW3iY5zkD`~ǺŞ̾Ƹn|Ri@v`7wa8|f?uMg|wSzD~L_qȬȮ˵Ǳ¬Ʊɳ¶vOl@kAUtǩƪƪũɾjwhInW7lT2jS3jU6taCz]ĸɳɳɳɳɳɳɳɳʴɶɶʷʷʷʷʷʷʷʷ̶̶˵ɳǱĮ¬ȲȲɳʴʴʴʴɳįȳȳĮĮf~mQ}iNtaCwbErUbùſƬʰʰɯʰ˱ūéſľľľ¼»ƿǪƽfxmOncEi\\<k^>pcC|oOf¹žǫʮɭǫũ¦|m_wVxV^n~ţľǾãæææçèĨīũħ¢ż{~bvjPfX>fX>gW>gW@m]F~nWqƽæ¥æŦŦääȿg|tPofEn`CseHsVmǹ¤ǾĻĻƽ¢Ũ¥¨ĪƬŮŮì«ǮǬçøiwPthB|nGykF|oL^zƬȯȯȲǯĭǿº}mbyW{Y`ixtcyXwT|W_uĹĨůï²ïíîîıŲȴɵ̶Ȱzv[vhKufIviItgEukGhȮʹʴʵɴȳǲǯǯȰȮʮ˯̲ʰǰŮƱǲŮūūǪæzf}VyQ{S`uǧƨƪǪƫŬĮŮŮƱǲȳɴɴɴɴɴŲ¯Į}cj^D`U9`U9_S9]Q7[O7[O7\\P:]P=\\Q=XM7d\\E|t]xǿŮ««ŮȱɲǰŮȱʳ˴˴ȱǰǰȱɲȱȱǰƯŮĭĪçũroaGfV=`P7bR9bR9fX>wkQsæĩƪƫǬǯǯƱƱȳƱŲŲƲƲŰ¬¸esdGgX9hX7jZ9gW6iY8teF|\\py~}Ƹũʯʰ̴Ϲ˵Ǳſ¨¨a{dDr^=mY8lY;p_AudHcĮɲưůǳȲ̴̲̲ʰȮǭɯ̲ͳ̲˱̲̲ʰǭĪĺryV~oNxjGwiDsNc|ŸŨŬưǴʶ̵ʱǬŨŨƽivS{kGueAwgC~pM}ZnžƬʰʰȮƬƬūĪĪūƬƬūéȾú¸ž­ưǲŬĪĻfsRvfDzjFueAwgExVh·ĻƾƾƾfxXwjJobBo`AvgHuVcvĻƽƽŧƨǪȫɮ˰̱̳ͺ˸ɶ˳ͳŨtxWsP|lJ~lHoNyXgroga^\\}V|R}Q|P{O{RzSxQ{Wh~ɯɱǱȴȴǳʴŮúlZ~S~SwP|YlȼȮ͵ϹϷ̲ɾyV|d>lDWyȸâĢȨǧ££ƽǾǽs|Rte:n]1nY,|e9vJUzTsNrPxUnMxhFwgEwTmǾŠȤĢȾĺ}f}WrJvN}Xh}}ZwHzNawƩʰʱ˵ǱƬǮxvOsGzPhŷȻǼ̰ʯŪǽ}~a~gEw_;oY4lX5q^>sTwɳɳɳɳɳɳɳɳʴȵȵɶɶʷʷʷʷ˸˸̶̶ʴȲǱůĮíɳʴʴ˵˵˵ʴʴǿðı®h}mSyhLr^CvaDsVféƬȮɯʰ̲δɯū¨ſľɬŨȫúftiKj_AfY9h[;obB~qQmƽĽĽü»üçɭ̰̰ʮǫl~]rQrQ{Zi} ſſ¢ŨƩũũĪĪūƬƬũŨ¥žpu[l^DiZCfV?dT=eU>q`Lwcv¥ħæħĥĥĥ£úpyXphDg_;k]@ugJy\\tæȪĦƨĦ£ȿǾǾã¥ŨƬƯŮì«ĮƭūɾpyUuiC{mFxiBxjEyVs¥ˮ̳̳ʴǱ«­ŽǿǿĽ~m~\\yWsSuU}`lx|wkz^uWvU|YcnǯȴĴ÷õİíì«ĮŲǳɵ˵ưwqWqcHqaGseHqdBvlImçǭ̶˵˶ʵɴȳȰȰȰȮʰ˯̲ʰǰŮƱǲĭĪĪŨva|UxPzT`wʿŧũĪŪƭůůƯƱįŰƱǲȳȳȳȳðí{|qUg\\@dY=i^BlaEmaGj^Dg[CfZBcWA]R<VK5YQ:g_HybìƯƾƾìǰɲȱƯǰɲ̵̵˴ɲɲɲȱȱȱȱǰƯĭĪĪƪqn`FeU<_O6aQ8aQ8eW=vjPsçƩƫǫǬǬƮƮįįƱŰıŲǳǳƱíùftdJiZ;iX:l\\;fV5m]<~oPkǸοɪдеζͷθѽ͹Ǳë«¦ikKvbAmY8jW9n]?raEz]|ǰưůȴʴ͵ͳ̲ʰȮǭɯ̲̲˱˱˱˱ʰƬŨŻmvSpO{mJ|nIzUsʽƩŬǱǴʵ̷δʱǪȫŦv{YqMzjF|lHqNyVgz»ĪȮǭƬƬǭȮǭȮɯȮūĺůŮêaoNscAxhDtd@wgExVfĸŽɿĺ|jwWylLvgHwhI}nOwUcoĤŧƩȫɮ˰̱̳˸ʷǴǯê}crOqNoKnJoNuT|]d_zYyV}X[]chog`YxQtM[nūʲɳɵ˷ʶȲì¹kY~S~SwP}ZnȼȮ˵ͷ˳ɯȽ]lGtL]ϿƥãŨǩæħ¡¸zWyjAsb6oZ+i:}Nbipv}phfqƢ̬ͩȨãȿŻwns|ŲƵ}[sKxOf}Ȭ˲ʳ˴ȯĩƩħa`i~ɷο¦ƫɯǭé©ȾwpN}e?v^8wc>nMaƸʴʴʴʴʴʴʴʴ˵Ǵȵɶɶɶʷʷ˸˸˸̶˵ʴȲǱưůůʴ˵˵̶̶˵ʴʴƿ¯Žɾʿi}mSyhLr^CwbEuXkɿêŬƭȯɰ˲̳˲ȯī©©©©ɬƩɬĻbsfFk^>gZ:l_?teDuTrżĽĽüüžĨǫʮ̰ɭũycrTziKpQcw¾¤ŧǪǪūĪëªëĬŭŨŨ¥ĿlqeMj^HfWBaR=aP<kZHq_sȿ¥æŦŦƥ¡~avnJjb>e]9k]@ugJwZpͿŧȿȿåƩȮȱǰŰĭ¬ǮȮçv~ZymGykDvg@vhCtQlƿˮʱ˲ʴǱ¬ſǿƽðŻobrQxiH{jLqUx^{at[oVoTxW_huȻçǱǵõ¶űŬĪ«íůƲȴȵíuzkTm_En^EpbGsfF|rOvƻƪƬ˵˵̷˶ʵȳȲȲȰȮʰ˯̲ʰǰŮƱǲƯūĪæĽp[xTuOvSaxʿŧĨéīĮůűǲǲîįŰǲȳȳȳȳíŭʾhodHcX<cX:i^@xmO{_~by_}qYpdLbWA\\Q;XP9]U>nfOiǿìƯȱǰƯìǰ˴̵˴ʳɲɲǰȱɲɲȱƯŮūĪũnl^DcS:]M4aQ8`P7cU;uiOrũʭǬȯȯǮƮĬ­­ðƲƲı®ǿ¸gueKiZ;iX:k[:hX7scB{\\{ɾ¥åŤ˪ϰдʹ̴˵̸ϼϺʴƮĭĨƽtuU|hGnZ9jW9n]?q`DvYsƻŮůưʶͷζδͳʰȮȮɯ˱˱ʰʰʰʰɯūħc{qNrQuR{VfƩŬǱǴȳʵδ˲ȫʭˬǼm_zVxTuQuQ_p»éƬɯɯʰɯƬž|tosůŮê}^|lKqa?xhDvfByiGyWf÷ǾĻķòįƼ|eyYrQ}nM}nM~qN|U`vŽĤĤƨǪɮ˰̱̳ȵȵı¸mvTykH{mHmI~lHkJpOuVyZyXyW}Zbjpzô}rj^vOvR^oĬưȴ˷̸Ǳ«kY~R~RzU]pʾȮ˵̶ǯǭ̾oZ^nƲŤǨ¥ũħŨƧťȾ_pGwf:n\\,~j8Qh}Ʋ̸ͺóǾĢɧή̯ɬƩĦ£ɾǸó²ƶʺνͼzWnIvRmƻʰȲʳ˳ɰɮǩ¢Ĺ|z©̶äèū©ǰǰĬŮǭŻc{RuO]nĵȩʴʴʴʴʴʴʴʴ˵ǴǴɶɶɶʷʷ˸˸˸˵˵ɳȲǱưưư˵˵̶̶̶˳ʴʴ¯ıýƾɾfzjQwfLn]At`EuWmžëƭƮȯǯȯ̴ʱŭêªĩª¨ǫžũȫúz\\naAh[;gZ:m`@vgFwVsŻĽžĽĽľĪéƪȬŪkz\\mMwgFrSiľ¢åĦŧŨŨɯȮƬūĬŭƮǯæ¥Ŀü|uiSmaKgXCbS>aP<jYEq]sƽȿãƧǨǦx}ZrhEh^;h[9h[;pcC|oOa{·úżȿ¢ťǪʮ˱ɲǰŮ¬Ǯɱū{_|oL{lExiBvhCrOgǭȯ˲˵ɳůƽð­ĮƭȼrxYvgHrcFteHxgMyhNyhNziOqUbo|¤ƫưĲ̿˿ưŬĪ«íĮƲǳǴ¬qxiRk]Cl\\Bn`CviIwT}ȬƬʴʴ̷̷ʵɴɳȰȰȮʮ˯̲ʰǰŮƱǰɲǭũ¥úkxUtQqLtQ_xƪ§êêíĮůǲȳįįƱǲȳɴɴȳ¬ưȼu[i[AbT9aV:k`Dx\\wrw]sdM^R:YO6XN5_U<oeL}dŮììĭƯǰǰƯūɲ˴˴ʳɲɲǰȱɲɲȱȰŮĭéĨnj\\BbR;[K2aQ:_O6bS<thNtǭ˱ɮɰȯƮŭëƾſƿ®űűðŽ¶gufIiZ;iY8jZ9l\\;xiHfʭ̯̯ʭαе̲Ȳȳʴ˷ȴʶɳưĭƬǹ~|]lMo\\<kX8n^=o`?vVjùĪĬư˷Ϲζδͳ˱ȮȮɯ˱˱ʰɯɯʰȮū¦vxXylJuT~[exŸ¤ŪŮǲǴƲǰ̳̱ɬˮϰãth`{YsQ{Xg{ùƿæ§ĺ|pkedm~źƮƯĩ}`{kJp`>yiGwgE{kJzYgǿǼǺƴŲ«ùqd{[tU~oP|mLvPXkĸáĤŧǪɮ˲̶̳ƳŲíûcylJugDxjE|jFzhD|hElIrRwV~\\_hwƺŝ̾´q~ZsQvSzZtüĬȲʴį·n\\}U}U}Ybt˿ɯ˳̴ʲ˱ɭ˼y~ɳȸȫǪʿ¥ħ¥ħȨȩɨàiuNzh@{f9rCYp˼Ϳ˼ƦƩǫħ¥ŨɰǮƫŨħä˽ħūǭǭǭ¥sPiDuSqʾʲư˶ɴʳ̳ȫƽ̿͹̶̸ҿĥèĪǮìȱǱ­ɲŮŹzuƷͿɮʴʴʴʴʴʴʴʴ˵ŲƳɶȵȵȵȵɶʷ˸ǴǴǴǴǴǴȲȲǯǯǯȰʲʰɱǯǮ¬ĮªļǽzavfMo_ErbHsbHrVyźįȲǰǯƯǯʰǭūūƬŨýɳǭȬwZm^?n_@n_@l]>rcDxYyùüſ©ëĬȰūĩũɻn~]nM~lHyiGqPjĿ¥æƩǪǪŨ¨¨éƩåþħĿ»|~r\\h\\F[L5`P9gU?o]Es[rľãɩɩţƥȿmvUvgFm];gW5hY8l]<wjH~\\nyĻƽ£¥¥¦Ľǽʾƺy{^yiHqa=qa=tfCsQhĽ̲ǮȯȯȯƮĪ¨ǿƾ®űưíȼ÷~x^ugMn`Ej\\Al\\Co_Fo_F{kR~dxĻ¦éūƯǲǴĴĲí¬¬ĮưǱĮ¼jzlQpbEqbCqdB|oOdźȬʰʴɳ˶ʵȱƯƮƬǭɬȬȫɭɭȮƬĬëƮƬƪ~etQyiE~lHtRavȽƩçĪūƬƬƬĩūʲϷ͵ʲ˳͵͵˸ų³p\\lZFeS=cT=h\\B~chn]CdT:]M3ZL2aS9eY?pdJ~dȾǰƯįƱȲĭɯƫŬǮʱ˲ʰȮȰɱɱɱȲȲǱƮǿ¨Ǽjj[D\\K7]M6`O;]M6UF1uiQ{ǰʰǭǭǭƬŭªľſĿïűƱįǽõz]sdEn_>j[:bS2l]<{nLmħȫʯͳ˱˲ʴʴ˶ʵɴɳʴɳǱį­«y|a{hJp]<n^:tfAznH[nūȲɵɵγαͰˮɬʭ̰ϳʮʯʯʯ˱Ȯƺu^~pMqNyXbvǹȽĮǲƳĲð˲˰ʰʮʭɬǩƦµridccsu{xpi}]bhnxʿƲ¬ſƿƺt{]nPyfFtaAwdD~mO|^yƻǿ¯ð¯xhz]wZwXtSvT_tƸ˾ɾæũǭ˵лιȳǱĬǿkrUxkKpa@seBzhD|jFkFqL{S]ov¹£ǩʬͿǹ~m~]wV[`p¹ƭ˲ŭʾzia}\\{Y{\\rźĩɮͳϵĪŨĨ¥ȿǾɾħŪƫǪǩǦȥɦǤɦȦ|gxWxQ\\oŻâɩ̮ͰͲʹ˵˵ʶɵɶǲĭŨħǩȬʰɴ̺˺ȵǰħwpJy`8qLhƷǼǰǳɶɶɶɵȲŮêĪūŭǮưȱȳȳ˵ʴǴǱŲưǱǲƺĺȲ̵˴˸ʷȵǴǴȵʷ˸ʷƳƳɶȵȵȵȵɶʷ˸ǴǴǴǴǴǴȲȲǯƮƮǯɯʰȮȭǮêŬªžǽ~v]scJm]Cp`FqaGsYzƻǿįǲǰƯƯǰʰȮūūũĨýʵǯȮwZn_@paBpaBo`AufG{\\|ĺļíĮǯé§¤Ǹh{WpL}nG{kIuRm»¥¥æħŨæ¥ĦåĿ¥ĿĽ{{oYg[E^N7bR;iW?p_ErXl¢ťȨǤġŤǾktSvfEq]<kX7gW5j\\9wjG[lty}øø¹¹orVtcEubAqa=scBrPlδɰɰʱɰǭĪ¦ǿİůíʾƺ÷{dvgPl^DgY?hZ@l^Dp`GoVlĪŬƭǯȰȳǲűİí¬«¬ĮưǱĬ¼i{mPreCsdCsfCrRfźūɯɳɳʵɴǰƯƬƬȫȫȫɬɭʮɯǭƭŬūǪĩ|arP{iE}kErQ`yɾƩééĪĪũũƩƪƬ̴ζʲǯʲ̴̴ͻıv|gViTAeP=dT=qeMmkwcHgV:`O3\\L2^N4^P5dV;vjPfŽ­ȳʴǰŬĩŪȭ˲̳ʰǭȰɱɱɱɳȲȲȲìĭȽ}hhYDZI5[J6^M9ZI5TE0sgQyŮƯƬǭǭǭŭëſĿïǲǲŰɽõ~xYrcDm^=j[:dU4m`>|rOrŨɬʱε˵ʵ˶˶ʵʵɴȳȳǲŰî­rvXyiGtfAuiAxlB|SbxðǱʯˮˮʭɬʭ˯β˰ʯǭĪ¨ʼhzSoKwUco§¬ìııĲıɱɯʰʮɭȫǪƨ¤ɼzspmoosuyz}|zz{vpgb_^jw·ǼſŽȾĸqvZ~kMxeGvcE{jLtXiɿ¨ëë~pe|^uVtUxYdpzʽäũūǱ˶ʷǲëƿ|~`ykNreEqbAufE|lJpLvP~Vak~þũɭɰȯ;Ƹ~m_}WWcvȽĪū˽vga_~`hzȾǬʯͱϳȫȫȫǪŨŨȫʭʰʰɯǪƧƤȤʤ˥ͧͫȩʼtpxŵɼǧͮβϵϷиͺͺ̻ʺȷƴŮĨħƨȭʱȶ̼ɻȶǲæsrIzc:sLiǸǼƯƲȵɸȸʷǶƳİįƳƳǴǴǴȵȵȵɶȵǴǴǴȵɶʷǴðƿƳ˸˸ʷʷʷȵȵȵȵʷʷʷǴȵȵȵȵȵȵɶʷʷǴǴǴǴǴǴȲȲƮŭŭƮȮɯǭǬǮêƭëžƼxoVn^EjZ@n^Dp`FtZ{ǼŰǲǰƯƯǰɯȮƬūĨ¦ƿ¼ʵǯǭwZo`AqbCrcDrcDyjK~_ŻŽª¬ĮƮéʿ³zbvRpL~oH~nLxUpĽĿĿĿĿ¥¥æ¥ĿåĿþ»ƿwthReYC_O8cS<iW?m\\B|kQbwýǧȨƦŢģżhqPtdCr^=n[:l\\:rdAuRj{ĹĹú¹u}c{jNo^@wdCqa=qa@~qOoĨδ˲̳̳˲ȮūçǿǿʿííʾȼkxiRj\\BdV<eW=j\\BrbIt[wĸ¨ƬȮɰɰɱʲɴǲűİí¬«¬ĮưǱĬ¼j}oRtgEvgFwjGwWjźĪǭȲɳʵɴǰŮūūǪȫɬɬʮʮʰȮǮƭĪƩèǾx^pN{iE|jDpO_yɾƩé¨¨¨çũǪȬ̲Ϸ͵ǯŭɱ̴̴ʷºyhr]LdO<fQ>jZC{oWv~cvbGfU9_P3\\L2\\L2YK0XJ/bV<rfLftƾȱʵȱīŪƫɮ̳̳ʰǭɱɱɱɱʴʴʴʴƯǰɾ{feVAWF2XG3[J6XG3RC.rfPxìĭƬǭǭǭƮĬª®İǲȳƱí˿zvWpaBl]<k\\;gX7pcAwTwŨɬ˲ʹ˵ʵ˶˶ʵɴȳȳƱƱįî­˼²q~]uR|pHypGwPXhxſæħŨħŨƪȬȭǬǻĶr^wSwUcuɯǬí«¯ıƳɰɮɯɯɯȬǫƩʭƨǺ}|}}~||{vwwuúĻŻǽľļƼlrV{hJyfHziKsUewƻêĪĬªĿþůīƾsgy\\tUrStUyZewƹħŨŭȲɵǱéùnuWugJreEyjIqP{Xahr}Ħ̯ϳͳǰĭ©ë¨ʼnY~UZfsźͿŷreceitĩʯ˰̰ͱ̯̯̯ˮʭ̯гӶѷϵ̲ȫŦŤȦʦʧ̩ϯίȬͽĲŲ˹âťǧɩͮϳ϶ϸйϼϼͽͽɸǵƯũŨƨȭɰȶ˻ȺǵǲæqtKh?zSo˼ȽƯƲǴȷȸɶǶǴƲƱǴǴǴȵȵȵɶɶǴǴǴǴȵɶ˸̹λ˸ȵȵ˸̹ʷȵʷɶɶȵȵɶɶʷ˸ȵɶȵȵǴǴȵȵɶʷȵȵǴǴǴǴǱǱŭĬĬƮȮȮǭƫǮêƭĬƿĺpxhOjZAgW=k[Ao_Ev\\~ȽŰǲǰƯǰǰǭƬūéž»Ŀʵ¬ǯƬvYo`ArcDufGufG|mNbǽǿªë¬¬ĮƮéɾv~^sOoK}nG~nLyVqĽĿĿĿĿĿ¥¥æ¥ĿĿåþĽüok_IaU?^N7bR;eS;gV<raGqTjýɩȨťà¡ĻfoNscBs_>q^=qa?zlI`}ýľĿý¼żǾɾɾȿȿƿžüüt|_{jNp_A{hGrb>qa@sQsç˱ʹʹʹ̳ɯǭĨ¨ǿȽʿí¬r{lUi[AcU;eW=i[AscJy`ëʰʰʰ˲̴̴̳ʵȳűİ¬¬««íĮůưĬýlqTwjHyjIzmJ{[nƻ¨ĪưȲɴȳƯĭĪūƩǪɬʭ˯˯˱ɯȯǮéŨ§żt|[}mKzhD{iCoN^yʿƩé¨¦ĨǪȭжи˳ŭŭʲ͵̴íw}kWjUBdO:kVArbI|b~otVs`BcR6`Q4`P6aQ7]O4ZL1]Q7eY?tjQw^uŮɴȱȯȭȭɮʱʱʰʰʲʲɱʲʴʴ˵˵ǰǰȽxccT?WF2YH4[J6XG3SD/thRzììǭȮȮȮȰƮĬª¬¬®İǲȳǲĮvsTo`Al]<l]<j[:tgE}Z}Ʃʭ˲ʹʴʵʵʵʵɴȳǲŰįî­­­ð̽xi\\~W{T}V]htüžȾȾŹsd`hxµ˽ǫɮǬĭ«¬¯ıƳǱɰɰɯȮȮǭǫǫǪȫǨåʿƻĹƽžǽžɿ¦¬ſ}erV}jL}lNsUasõƭƬĬ½íêǻrez]tWpPpPyXk}ȿæǭ˳˵ɱħq|^zoOylL|oO|\\dr~ȺŨˮδϵʳĭʿʿ¬ŭìȺh_\\]dnwmntxɿ˰Ͳ˰̰̰ггϲͰ̯ͰѴպййϷ˱ȫǨȩʨǦɨ˫ͰʰƯ«оĨǨʪʬɬǪɬˮʹεϸϻϻμͻ̻ʺɷȱǫȫȪɮʱɷ˻ȺǵǲæowNmD[wʿȱȴƳƵƶǴƵǴƲǲȵȵȵɶɶɶɶɶǴǴǴȵȵɶɶʷϼͺ˸˸̹̹ɶƳɶɶɶɶɶɶɶɶ˸ɶɶȵǴǴǴǴȵɶʷȵȵȵǴǴƳǱǱŭĬĬƮȮȮǭƫǮīƭŭƿùhtdKhX?fV<jZ@p`Fy_ʿîƱǲƯƯǰȱūūĪž½ɴƮé~uXo`AsdEufGvgH}nOc·ɿĬĬí¬¬íǯĪ§Ƚs|\\rNmI{lE|lJxUpüĿĿĿ¥¥æŨŨæ¤åãĽ}xbdXB]Q;]M6_O8`N6`O5iX>ufI~b~ȨȨťà¡Ļf~nMrbAt`?s`?p`?{lKeȾǣȦɦƥƥĤ¢ƿžȿɾʿ£ççé¨žž÷goStdC}jIueAueDxVyūʹεεʹʰȮũĪǿǼȽ¬ííĬu|mVi[AdV<fX>i[AscJ|cȼɱͳ˱ʰʹʹ͵͵˶ɴűİ««ĮĮůưŭýmsVylJ{lK|oL}]qȽ¨éůȲȳǲŮìĪĪƩƩȫɬʮ˯˱ɯɰȯéƩ§ĻpyX{kIygCygAmL]zƩĪé¨¦ĨǪȭжϵʰƬȮͳͳɯzer`JfQ<dP8mYAueKmw`nNtaAiZ=j\\An`EqcHl^CeW<`T:bV<h\\BrfLzazƼƯ˴̳˰ɮȭǮȯ˱ͳ˳ʲʲɱɳʴ˵̶ƯŮźvacT?YH4]L8]L8[J6WH3ymW~ƯŮɯɯʰʰɱǯŭëí¬®ïǲȳǲůrqRo`Ak\\;l]<l]<ylJaǪˮ̳̳ʴɴʵʵɴɴȳǲįįî­­­îîĲ®ʾ¶vocaackvyzȹ̿ũèèììĮůıŲǱȱɲʱʱʱɰȮĪǫ˯ͱͲ̯ɬǪʿɾȽǼƻźźøźǾǫǪũ¨¨Ī¬ýsdx[vX{]gr˽éƭƬë½­ÿŽ˿øwpg{]uWuV`mtƽƩ˯˱ƫɻs~^}pPxkKrR|\\o{ƹťȪˬƪȮʰ˳ɲǲı¯°Įư¶zne]}]`o|}Żȯ϶ε˲˱̲жжδ̲ʯʯ̱ϴ˴ͶиϵͲʭʫʫƧȩȬʰ˲ʴȳȳɯɯ˰ʯɯɯ̱ʹ̶̸̳̹̹̹˸ɹ˻˹ʳʮˮ˭̱̳̺ͽɻȶȳæktKnE_|äʿƯƲŲŴĴƳĳƳƲȳʷʷʷɶɶɶɶɶȵȵȵȵȵǴƳƳʷʷʷʷ˸ʷȵƳɶɶɶɶɶɶɶɶ˸ɶɶǴǴƳƳǴȵɶɶɶɶȵǴǴƳưưƮŭŭƮȮɯǭǬǮīǮƮw`qaHhX?hX>k[AqaG}cįƱǲƯƯǰȱūūĪüǲĬ{sVo`ArcDteFteF{lMbøìŭŭí¬¬íǯū§Ƚq{[qM~lHzkDzjHvSnü¥æħƩȫȫƩħħĦ¤ť½jtiS^R<ZN8[K4\\L5]K3_N4iX>teHe~ƦƦťġà¡żh~nMrbAt`?ta@qa@|mLeǽƢǥȥǦǦťãƿƿæ¢ŦǪȬȬȮȮǭȮĪźnsUwgF|iHxhD}mL`¦¨̳̳ʹʹ˱ɯƪūǿǼȽ¬ííësyjShZ@fX>hZ@hZ@ueLf˿ʲ̲ʰȮʹʹ͵͵˶ɴƲű«ìĮůůůƮľmsVylJ{lK|oL}]rʿééĮǱȳƱĭìééŨŨǪȫɭʮʰɯɰȯĪǪèúmwVzjHxfBxf@~kJ\\zƩƬūĪéĨũƩȫͳ̲ʰȮ̲δȮƿt{lUlZBfR:eQ8mY@teHm||hzWpOlLsVx]~cdx]ykPl`FeY?cW=h\\BtjQf|»ȮȭȭȭƫŬƭ˱δ̴˳ɱȰȲȲɳʴŮì·t_cT?[J6`O;_N:^M9[L7}q[ɲǰ˱̲̲˱ʲǯĬëí®ƱǲǲĮnpQo`Ak\\;l]<m^=}pNgľȫ̯ʹ˲ʴɴɴɴɴȳǲǲįįîîîįŰƳĲĲįĽ{uqos{¸ĸ÷Źǻ÷ĴɺοĤæççɿìƮǱǱŲűȱɲʳ˴ʴ˲ʱʱ˲ͲϷѷѷϵ̲ʮŪūūƬƬūūĪʰʰɯǭūūǭʯéŬƮȯǯƭĮê{rljns{Ǽ¨èĪĪªþþįŽ˿ɾƸti|]}[_eqʿǩũɾ|euT{lK|oM~^lƻǪˮˮʯ˯ʰʰɱɳȳȵǶǶƶĴĲűƲĮƽti`_hsŶŷȼŬʹзʹɰʰ̲ϵжϵ̲ɮǬǬȯɳ˶кѹз̱˭ʫɬɬʰʳ̵̸˺˸Ȳɲʲ˳̶ͷθϹ˵˵˸˸ʷɶǵǵɹʸʳ˯̯ͯͲεμξɻǵǲ¥eoFlC`}äǼìİƳƵŵƳĳƳǳȳ˸˸˸ʷʷʷɶɶʷʷʷʷɶȵƳŲǴǴȵȵɶȵȵǴȵɶɶʷʷɶɶȵʷȵȵǴǴƳƳǴǴȵɶɶɶȵǴǴƳưưǯƮƮǯɯʰȮȭǮīǮǯqZqaHiY@jZ@l\\BscIf¬įƱǲƯƯǰɲƬǭƬ¨üƱĿëžyqTo`AqbCrcDrcDyjK`ø©ĭƮƮĮ¬¬íŭéƻnzZqMmIzkDzjHtQmĽ¤¥¥¥æħħŨǪʭʭȫƩŨŧȨ½ynXg\\FZN8YM7[K4\\L5^L4dS9raG}nQoĤťťŢġ¡ǾjoNrbAs_>s`?scB}nMeźĢƦǧȧȧƨĦ¥¥Ũȫƨǩɬʭ˯˱˱˱˱ͳɯɾnrTueDyfEzjFuTlȿũūʱ˲̳̳˱ɯȬƬ«Ƚɾ¬¬¬msdMfX>hZ@i[AfX>wgNh˿ɱʰȮȮ˲̴̴̳˶ɴƲűììůůůůǯſmsVxkIzkJ{nK|\\s¤ūéĮưǲƱĭ«¨¨ħŨƩǪȬɭɯȮȯǮūȫĩúluTzjHxfBwe?|iH~[zƩǭǭǭƬƪƪƩƩɯʰʰʰͳ˱žyz^l^DfU;iU<jV;p\\AvgHmv}tf^`ex}luYtiMh\\BfZ@k_EvjPz_pŻɿèŪƭǮʰͳζ̴ɱǯưưǱȲƯìr]aR=ZI5`O;`O;`O;]N9t^ʳɲδδδ̲ʲǯĬª¬įƱƱĮ˿lpQpaBl]<l]<n_>tRlȫͰʹ˲ɳɴɴɴɴȳǲƱŰŰįįŰƱǲȵŵŵƴưū¥ǾƼɿȾ§ĩèĩǬŪģƧǨǪƩƪũéĭƮǱǱǳǳɴʵ˶͵̵̵̵̵ϸзϹззεʹ˳ȱɰʱʱ˲˲ʱʱŬǮȯƭīìĮǰǱǰï«ƾ}~ǹéŭ©ĿįƱíê˿ȹ³odbelwŸãͿƷxf~\\{X`rúèʮ˱ʰ˳̴˳˳ʴʴʷʹ˺˼ȹȷƵƳŰŮíĨ¼|pinvȹ˼ʼ̾¦ƫ˲з϶ʱǮɯ̲δϵжδ˰ȭƫƭ˵ͷϹϷε˰ʯʭ̱Ͳ̴ͷͺλͼͼɶʶʶ˷͹ϻϻϻ˸̹˸˸ɷǵŲĳƶǵȱʮ̯̮ͲεμͽǹųŰ̾_mDlCdƧȽĭűʷɸǷȵƵȵȴʵ̹̹˸˸˸ʷʷʷʷ˸̹̹̹˸ʷɶȵȵɶȵȵȵɶɶȵȵʷʷʷʷȵȵɶǴȵǴƳƳƳƳǴȵɶɶɶȵǴǴƳưưǯǯǯȰʰʰɯȭǮīǮǯ~}nWqaHjZAk[An^DueKh¬ŰƱǲƯƯǰɲǭɯɯĪžŰþªĽw~pSo`ApaBpaBpaBwhI~_øêŮǯƮĮ¬¬íë¨źmyYqMnJ{lEzjHtQlžĦææ¥¥ææħŨŨȫʭˮɬƩŨŧĿɩþwncM_T>YM7YM7\\L5]M6aO7jY?ziOwZy¼Ĥťťƣġ¡ȿlqPrbAs_>s`?p`?yjIa~ ťȨƥƥŧåæƩɬƨƨȫȫȮȮǭƬ̲ͱɯȽhoQscAvcB{kG{ZsħɭȮȯɰ˲̳˱ʰȬǭ«ɾɾ¬ȼho`IeW=i[Ai[AdV<yiPj˿ȰɯȮȮʱ˲˳̴ʵɴƲűìĭůůůĮǯſmsVxkIyjIzmJ{[såƬéíưǲŰì«¨¨ħħŨƩǫȬɯȮǮǮūɬŪúkuTzjHxfBvd>{hG~[zƩȮɯɯȮȬƪŨħǭȮʰ̲δȮeohLaS8cR8lX=o[@vcE|mNt|yopwɾȽmy]pdJj^Dg[Aj^DpfK~tYrŪǮǮʰ˱ζ̴ɱƮůůůưȱĭp[`Q<YH4_N:`O;`O;^O:u_˴ɲжжϵͳʲǯë¬ĿîŰŰĮʾkpQqbCl]<l]<n_>uSo¢ȫͰʹ˲ɳɴɴɴɴȳǲƱŰŰŰŰƱǲȳɶǷȷǷȴǯǪƩƤǽŸķȺ˽ͽ˼¦¦¦Ūɮɮ̱Ͳ˰˰Ͳ˰ƪǧɨˬɪȫȫɭɬƭǭƮƮǱǱȴɴʵ˶̷͸ͶͶͶͶηηͶͶ̵̵̵˵ƯưǱǱȲǱǱǱůȲʴʴǱí«ǳƱî­­îîîǿļôǸȺȺǭȯĽƿŰǲĮŬ«¦ʾ¥ŪĬ˿ƺøummpvô;ĵ|qjksǼ¥Ȯʰɱɱ̶Ϲɱʲ˵̶˺˺˼˼ƷǸǶƳð­«ĨŢvyŶ¥Ũææƨƪ˰εѸεȯŬɯͳͳϵѷжγʯǬǮϹλϹͷ˲ɰʯ˰Ͳγͷθͻμ;ξʷɶɶ˸ͺλκ͹ͺͺ̹˸ɷǵıðóĲƯȬʭ̮̱ʹͻ̼Ƹñîɻ}ZoFoFhʫǰɵͺ̻ʺʷȷɶʶ̷ͺ̹̹˸˸ʷʷʷʷ˸ͺλϼϼλͺʷ˸˸ʷȵȵʷ˸Ǵȵʷ˸˸ʷȵǴȵɶɶƳƳŲŲƳȵʷ˸ɳʴ˵˵ʴɳǱưǱǱȲɳɳɳȲȲǳïŰƯʾwxhNm^Ak\\?p`FpbGtfLhįưǱȲɳɳɳɳʴȲů¬ý¼¼ÿÿ¦ƺh}lNmZ<o\\>o\\>o\\>veI}aƸŬǭȮƬĪɿ̾ŷx{^zkLuhHzmK~sS|\\sŨĮííĮƯŮƮȰʲʲǯê¦ǾȿĻz^i[@^P5YI/[K1`O5eT:lX?vbIv]nǾ¡áţȦɧŤ¡ywYraCmX;mZ:oa>znHa{ãåƧȬȬȭǬǯȰíŰǵȶȶǵƵƳůȮæsW}rDph9pg<|uKhżƩ˯δȲɳʴʴɳȲǮŬëĬªſĪĪŻ~blaEbW;dY=f[?fZ@sgOlǿŭëƭ̳ʱʱ˳̴˴ʳǱǱ¬¬¬ìîĮĮĮīh~uXulKqfFukH\\qǦ̫ȧǨɪƩƩŪŪīê©¨ũǪȮɯȱǰŰį¬ǮŭĹjuUykH}g>zc9h?ZȺĮŰȷȶȶǴǲɯȯɮůưǮȯʱêuzmKob@_U2XP,^U6idDwrT|]»íǰʱ̳Īu}argGeV7fW6n^<vfDuSd}ǭɯʰ˱ȱȱȱȱȳȳȳǰĮƮȼ~sWaV:[P2`U7[P4XM1eY?{cķòɷιϹͷ˵ȲưĮíĮíſſʾjpVscIj[>k\\=rcD|\\xƩˮ̳ɰɳɴɴɴȳǲƱƱƱƱǲȳʵ˶̷̷ưưǱǱǱǱǱǱ˵ɳǱůůǱɳ˵ʴʴɳůĮǱɳʴ̶ͷͷ̶ʴȲȵȵɶʷ˸ͺϹкʲɱɱȰȮɯɯʰ̶̶ͷθθθͷͷʴʴ˵˵˵ʴɳȲ˲˲ʱɰǯƮƮŭƯȱưíĮǱư«Ǵ®Ŀ¬Ŀÿ¦­ŰǴı±³³¿İȴǱ¬ȰǯūƿĨȬƬǭǭūƿ¦Ȭɲɲɴɴȷȷȷɶȵ˵ͷкѻѻкϹ˵ɳǱůĮíĮĮĮůůſĮɳʴȲǱ˵ϹϹϹϹθθͷͷͷθθккϹ̶ɳǱζζζ͵ʴǱĮ¬˸˸̺ͻμоѿϼλ̹˸̹λнѾλλλͺ̹˸ʷʴɭɬȮȮǲȳȷȷʹ˸ŲǿìzWrJyNg³ŢǦɭеɳʳʶʶɶɶɴɴ˸̹̹ͺͺ̹̹˸ʷʷʷ̹ϼѾѾнϽμ̺ɷƴƴȶʸɶʷ̹λλ̹ʷɶǴǴǴƳƳŲŲƳȵʷ˸˵̶̶̶˵ɳǱưǱǱȲȲȲȲǱǱȴïŰĭǻqrbHm^Ak\\?p`FpbGtfLjįưǱɳɳʴɳɳʴɳưíſľýÿÿƿƺg|kMmZ<n[=p]?q^@xgK~bĶĪūƬū¨§¨˽Ķ{cqTwjHwjHwlLvVqħưƮưĬ¬©©íŬƯȮɱȮƮī¦ȿǾtXfX=]O4`P6]M3]L2_N4gS:vbIzatģĢţƤţǾxxZsbDn[=n[;m_<uhE{XsǾ£¤Ũʮ˱ʰɱɱʲưƱųųĲñ±¯ĮéɻkU}rDtl=ypGZuȫ˱̵ʴʴʴʴɳɰȯǮĬŭëſĪéƿ¸z^j_C`U9aV:cX<cW=thPn«Ȱŭȯʹɰʱʲ˳ʳɲǱưíííĭůůůů¼f~uVwlLuhFxnK\\qƥʩǦǨɪħŨĩŪŬŬīūũǪȮɯȱǰŰįŬë·g}rRwiF|f=zc9i@]ȺůƱȶȶǵǴǲȮȯȭīŬŬŬī¸gob@fY7[Q.ZQ0f]>xsSht©ƿƳƳĮǰʱ̳ɯtz\\reEn_>p`?rb@}mKzYp}éȮʰ̲ʳɲɲɲȳǲǲǰůƮǻ~sWaV:ZO1^S5^S7^S7maGjȻĳȶ̷̶ʴɳǱưůůůĮ¬¬«ʾ~eyiOm^AgX;k\\=teF_{¥Ǫ˰ʹʱʴɴʵʵɴȳǲǲǲǲȳɴɴʵ˶˶ȲȲȲȲȲȲȲȲɳȲůĮĮưɳ˵ʴʴȲůůȲʴ˵ͷθθͷ˵ʴʷʷɶɶɶʷ˵̶ʲɱɱȰȮɯɯʰʴ˵̶̶ͷͷ̶̶˵̶̶̶̶˵ʴʴ̳̳ʹ̳˳ʲȰȰǰȱů¬ĮǱǱĭů¬¾«íŰűƱð¯ſĿïǳȴʴ̶ɳªëĬĪé¨é¨éƬǭũü¼ľľ»ũȮɲɲʵ˶ʹɸȷɶɶ˵ͷϹккθͷʴɳǱůĮĮůưǱȲȲưíſſůɳ̶˵ǱǱʴθϹϹϹθθͷͷͷθϹѻѻкθ̶˵ϷϷζ̴ʴǱůĮ˸˸̺ͻμоѿϼλ̹̹̹λнѾλλͺ̹˸˸ʷ˵˯ʮʰɯȳȳȷȷȷ˸Ǵ«ŮxXpHxNh Ŧǫ͵˵̵˷˷ɶɶɴɴ˸̹̹ͺͺ̹̹˸ʷɶɶ˸λннϼϽμͻʸǵƴȶʸɶʷ̹ͺͺ̹ʷɶȵŲŲƳƳƳƳǴȵɶʷͷͷͷ̶˵ɳǱưưǱǱȲȲǱưưȴïî«÷kk[Al]@k\\?o_EpbGugMküįưǱɳʴʴʴʴ˵ʴȲůíĿÿƿŹg|kMmZ<o\\>p]?r_AziMfĶéŬĬªçũèɾĹjvY|oMwjGuhF}sPlȽä«ūŮū§êŪǮȬƭƪīĩ¦ȿżuvkOaS8\\N3aQ7^N4]M3]M3cR8q`Fz`uâŤţţţáǾƽ}c|kMs`Bp]?qbAtgEtRk¹ĩȯʳʳȳȳɴȲƱï®ĮɽzbxN}rEzrD}VmȿǨɬʰ˴̶̶ʴɳɰɰɰɮƮƮĬé¨žx\\j_CaV:aV:bW;bV<uiQqĭʲȰʱʹȯɰɱʲɲȱưůĮĮİŰưưưư¼asSzmKxjG~qN\\tģȩǨǪȫèèĩĩŬƭǮȮƪȫȮɯȱǰƱŰíƭëe|qQvhEyf<ze:mE`ȽưǲȶȵȴǳǱȮȮɭīŬŬĩȾtvZeX6aT2^S3d[:wnOiɭɰīí˵λ̹Ȳɲʱ˲˱ʰƪæy`rPxiHsdCwgE~oN}`nžǭ˱ͳ̵˴ʳɲȳǲƱƯǱǯƺvZf[?_T6cX:bW;f[?xlRuǶɷʵʴȲưưưǱǱǱůí¬Įĭʾw^qaGhY<eV9k\\=teFb~ĹæƩʯ̳˲˵ʵ˶˶˶ʵɴȳɴɴɴɴɴɴɴɴʴʴʴʴʴʴʴʴȲưůĮĮưɳ˵ʴɳǱí¬ưʴ˵̶ͷθϹθ̶˵ͺ̹ʷɶȵǴȲȲɱɱȰȰȮȮɯɯɳɳʴ˵̶̶̶˵ͷͷθθͷ̶˵˵̳ʹ϶зϷ͵˳ʲǰȱĮíǱȲĮĬƾľĩƬǮë¬¬¯®žþƿíūȰǯǰɲȱūƿ¨ììƾéĪǭɯʮʮɭɬˮƦſľáţľãǧȫɬȬȮɲʳ̷͸̻˺ɸɶʷ̶ͷθϹθ̶˵ȲǱưůůưȲȲɳɳɳʴ̶ͷ̶ʴ˵ͷͷ˵Ǳưɳ̶θθθθͷͷͷͷϹкѻҼҼѻϹθиϷ͵˳ɳǱǱư˸̹̺ͻμооѿλͺ̹̹̹ͺϼнϼλ̹˸ʷʷ˸ͷδͱ̲˱ɴɴȷȷǶ̹ʷǰȱ}_wS~YqãǪȮ͵ͷ͹̸̸ʷʷɴɴ˸˸̹̹̹̹˸˸ʷɶɶʷͺλλͺϽϽͻ˹ȶǵɷ˹ȵɶ˸̹̹˸ɶȵɶŲŲǴǴǴǴȵȵɶɶͷ̶˵ʴɳǱưůǱǱǱȲǱǱưůǳ®­ijZ@l]@j[>o_EpbGugMmžįưȲɳʴ˵˵˵̶˵ɳǱůĮíí¨Żh}lNp]?p]?o\\>p\\AziOgŹƬƭĬſſ¨ũ¦ƽlwY~qOylIwjHrPf·åȾȾžħŨƬǪŪĦèħ¥újpeI`R7^P5\\L2_O5aQ7aQ7aP6kZ@tZp¡ŤţƤţ ȿȿźsy[{hJq`ByhJwhI}nOb~ȼéŭůİŰǲȳǱŰ®°ï¯íl}W~rJ}qGwNb{úȩʭȭɲɲͷ̶ʴȰȯȭɮʯȰȰŭéĽw[laEeZ>dY=dY=dX>vjRsŮ˳ʲ˲̳ǮȯɱɱȱȱůĮĮĮŰŰưưưƮ»x|\\qP{kI{iErN^wâǨǨȫȫŪŪŪŪŬƭǮȮƪȫȮɯȱǰƱŰưȯĬe|qQviFxg<zg<qIeʿȱɳȴȴǳǱǯǭȮȬǬǬǬŪŻj{pTaT4dW7i^>wnMe~ĨǫŬ©Įʴ˸ȵ˵̵˲ʱɯȮǫƪħ~l}^qP|lK}nM~uXey»Ƭ̲δͶͶ̵ʳɴȳƱƯǱŭŹ{_mbFg\\>j_AdY=mbFw]~Ƴ˺˹ʵʴǱůĮůưǱǱưĮ¬¬ĮůƯǻ~qWm]CgX;eV9j[<rcDcźæéȭ˲ʱ˵˶˶̷̷˶ʵʵʵʵʵɴɴȳȳȳ̶̶̶̶˵˵˵˵ȲǱưưưȲʴ̶ʴȲĮíȲ˵ʴ˵̶ͷͷͷ̶˵λͺ˸ʷɶȵɳɳɱɱȰǯǭȮɯɯɳɳ˵̶̶ͷ̶̶ͷθθθͷ̶˵ʴʱ̳϶ѸѹϷ̴ʲȱȱĮ¬ǱȲĮ¬ǭƬ¨ƿĽ«ǿºļæƩŨɿǽ§Ǭɭ¨ììǿǿɯɯɯʰʮʮ˯˯ѴˮĤľ¼ſáǥĢǧ˫ήαͱʰɯɲ˴͸Ϻϼ̻ʹɶ˸̶ͷͷͷ˵ʴɳǱǱưưưȲʴ˵ɳǱǱʴϹѻϹͷͷͷ̶ɳưůȲ˵θͷͷͷͷͷͷͷθθкѻѻѻѻкиϷ̴ʲȲȲȲɳ˸̹ͻμϽоооͺͺ̹̹̹ͺϼϼнλ̹ʷɶʷ̹θжϳδ˴ʵʷɸɸȷ̻̹ɴʳĪripɺǬ˰˴Ϲϻκκ͹˸ʷɴɴʷ˸̹̹̹̹˸ʷʷɶɶʷ̹ͺ̹˸μμμ˹ɷȶʸ˹ȵɶʷ˸˸ʷɶȵɶƳƳǴǴȵȵɶɶɶɶ˵ʴɳǱưůĮĮȲȲȲȲȲǱưůǳ®­÷ll\\Bl]@j[>n^DoaFugMmįưȲɳ˵˵̶̶̶˵ɳȲưůůůĮ¬ª¨Żi~oRsbDp_Al[?m\\@ziOj˿ɯɰǮêÿ¨¥¦¦úmvWviFvhCxjG~pM|[qʾ¥ȿŹĻɿŨ¦Ħũƨħĥ¥ħdodHbW;bW;]O4`R7dT:`P6[K1eU;u[wƻâģĢá¾ſ¡ŸkrTveGyhLufIxiLx[u÷Ⱦ©Ī«ªíƲɵůìíƲǳıíŹv`tQznHsK}Vkʯɮȯɲɴ̶˵ɱǯǬȫɬɬɯɱƮéüz~sWlaEg\\@eZ>dY=dX>xlTwĭɱɱʱɰǮȯɱɱȱȱůĮ®îîîĮĮììĺqxWoK|hC}g@rLcäƩȫɬȫɮȭǬƫŬŬƭǭǫɬɯʰɲȱǲƱưȯª~d|qQviFwh?zk@wPmæ˱˵ɵȴȴǱȯɮȮʭ˯ɬǪ¥}}`sjKbT7j\\?xmOc{ĿȫũĨ¬ưƳð˵̵ʹ˲Ȯūç¦ʭȿtd{ZyY~al|üǭͳϵηη̵˴ʵȳǲǰưª{_peIj_Ak`BlaEynRjƺʷνͻ˶˵ɳưůĮĮĮưưůĮůůưƯy}mSm]CiZ=hY<j[<n_@cźæ¨ŪȯǱ˵˶̷̷̷̷˶˶˶˶ʵɴɴȳǲǲθθθͷ̶̶̶˵ʴʴɳɳɳʴ̶ͷɳůľſíɳ̶Ȳɳʴʴ˵˵˵˵ͺͺ̹˸˸˸ͷͷɱȰǯǯǭǭȮɯɳʴ̶ͷθθθθͷͷͷͷ̶˵ɳȲȯ˲ʹзϷ͵ʲɱȱɲů¬íǱưíì̾ŶvmkfqŻȾƼĺǽɿúķ˾ɼĹɾŧɬĩŬĭî¬¯ů̵̲ʰȮǫǫǫȬͰʭƩã¢ĤǧȨɫ˭̮Ͱ̯ʰʰʲ̴Ϲѻнλ˹ɶ˸̶̶˵ʴʴɳȲǱưưưǱʴ̶ͷʴȲǱʴθкθ˵˵ʴɳưůưɳ˵̶ͷͷͷͷͷͷͷ̶̶ͷθϹкккϷζ̴ʲɳɳʴʴ˸̹ͻϽϽϽϽϽ̹̹̹̹̹ͺλλϼλ˸ʷɶ˸̹Ϲйжη̵˶˸ʹʹ˺ͼ̹ɴʳɯĳʳ̶͸λϻλκ͹̶˵ʴʴʷʷ˸̹̹˸ʷʷ̹ʷɶʷ̹ͺ̹ʷ̺ͻͻ̺ɷȶɷ˹ȵȵɶɶɶɶȵȵɶǴǴǴȵɶɶʷɶȵȵȲȲưůĮĮĮůɳɳʴɳɳǱưůǳ®î«Źoo_El]@j[>n^Dn`EtfLkƿįưȲʴ˵̶ͷͷ̶˵ɳȲǱưưǱůíª¨ĺk~oRsbDp_Al[?n]A}lRoë˳˲ɰƭ©ſ¥¥ħƩƿs{\\ob?rd?wiF|nKuTcµ̾¦§ʿĹøȽææ¥¥æħĦĽĻww[ncGf[?f[?dV;cU:aS8^N4_O5qaGkɻ¢Ǧģ ÿſáŤyaoQxgIveGvgHqRg|ʾĬɳ̴««¬ůǱůʾŹ{exX}pNylIuO^zŪɰȯȲ˶ʵ̶̶ʲɯɬʫʫɬɯɱƮĪ¨ĽrwlPj_Cg\\@dY=bW;cW=}qY|ìǯɱʱȯȯɰɱʲɲȱưůîîîîĮĮìĪ¸ltRmJ}g@~g>sNkƽŨǪʭˮɬ˰ʯȭƫŬŬƭȮȫɬɯʰɲȱǲƱůǮ|c|qQukHzlE~qGYsŨ̲˳ʴɳɳɰɰʯʭˮˮǪæĽuyZtkLn`CzlOcxħɬȬǫīêĮưŲưȲ˴ʹʹɯƬĨçħź}upzʰδϵηηͶ̵˶ʵɴȱůdynRshJtiKvZh}˿˸ν̺˶˵ʴɳǱůĮíĮůưǱǱǱưĭryiOk\\?j[>iZ=hY:j[<|_ƻĨ¨Ŭǰưʴʵ˶̷̷̷˶˶ʵʵʵɴɴȳȳȳϹϹθθͷ̶̶˵̶̶˵˵˵˵̶̶Ȳí¼ýíɳͷǱȲȲɳɳʴ˵˵̹̹̹̹̹ͺϹкȰȰǯǯǭǭȮȮɳʴ̶ͷϹϹϹϹͷͷͷͷ̶ʴɳȲȯʱ˲ʹ˳ʲȰƮɲʳǱĮĮưĮ˿̼ueoUveKqbEm_EykQ~dxzromwķ˾ūǮƱı¯°ĲǴɲɯǭƬƪƪǫȬȫɬɬȫƩƦƩȫȪȪǩȫɬʭʰ˱˳̴θϹλͺ˹ʷ˵˵ʴɳɳȲȲȲǱǱǱǱȲʴͷθ̶̶̶ͷθθͷ˵ɳȲǱưưȲɳʴ̶̶̶̶ͷͷͷͷ˵˵̶̶ͷͷθθζ͵̴˳˵ʴ˵˵˸̹μϽоϽμμ˸˸̹̹ͺͺͺͺλͺ˸˸ʷ˸̹θϸηͶ̷̹˸˺˺̻ͼ̹ɶʵ˴ŮƼôǷͽįɳ˷̹̹̺ͺ̸̸˵˵ʴʴʷʷ˸˸˸˸ʷʷͺ̹ʷ˸̹ͺ˸ʷʸ˹̺˹ɷȶȶʸȵȵȵȵȵȵȵȵȵǴǴȵȵʷʷʷɶȵǴȲǱưůůůưǱ˵˵˵˵ʴȲǱưȴïįìŹoo_Em^Aj[>m]Cm_DrdJjžįưȲʴ̶ͷͷͷ˵ʴɳȲǱǱǱǱİ¸i|mPp_Co^Bn]AsbFsYvĬɱ˴ʳȱī©§èĩèæƩæ~hzmJzlG{mHqLtQ|Yl~Ķ˼˽ǹŷɻŧ£ɾŦƦú}dtiMf[?aV:aV:cX<^S7]R6gY>wiNfŷŧǨĥãĤ¢ĿãťǨĦźtdrQpN~oNrQ{Zhyƻ¥Ũɭ˯ĪĪīƭŬȾxfrU|oOzmMzmKxVdùɰȲǱ˷ι̷ͷͷ͵ͳͰ̭ͮˬȮɱƮª¨ĪéžmshLi^Bi^BeZ>cX<eY?w_øĭƮɱ˲ɰɰʱʲ˳ʳɲǱưįůůůůůĭūdqMlG~f@h@vQr¦ǫȬ̰ͱɭ˯ʮȬǫƬȮɯʰȫɬʰ˱ʳɲǲƱȲɰªfuUzpMzqJwN_zǪͰ̴˵˵˴˲˲̰̯ͯʬƦãſ{kd~co¸¥ƬʯʱɰǮǮůůŰɳưʱ̳̳ȮūĨũ¥ƽøƿǭͳδδͶͶͶ̵˶˶˶ʳưê¸wlgjyŻĮ̸ͻȶȳʴ˵˵ʴȲưĮíưȲɳǱů«mscIfW:gX;hY:gX9hY:z]~Ƚǫūƭȱǳɳɴʵ˶˶˶˶˶ʵɴɴɴɴɴɴȳϹϹθθͷ̶˵˵ͷͷ̶˵ʴʴʴɳư¬ɳ̶ȲȲȲɳʴ˵̶ͷ̹̹˸˸̹̹θϹȰǯǯƮƬǭǭȮȲɳ˵̶θθϹϹϹϹϹθͷ˵ʴɳʱʱʱʱɱǯƮŭɲ˴ɳưůư¬ǻz}dnRuaFiX<cO4_N0[K1eU;ueKu[iorpupiazWrO{mJzjFyN[gin~ǹéƭȳǴųĴĴųƯǭƬƬǫȬɭʮƪɭ˯˯ȬǪȬɭƩŨŨūǭɯ˳͵˵̶ͷͷ̹̹˸ʷɳɳȲȲȲȲȲȲɳȲǱȲɳ˵ͷθͷθкϹͷ̶̶ͷʴɳȲȲɳɳɳȲ˵˵˵̶̶ͷͷͷ̶̶̶̶̶ͷͷθ̴̴͵͵̶̶˵ʴ˸̹μооϽμͻ˸˸̹̹ͺͺͺͺ̹̹̹̹̹̹̹̹͸͸̷̷˸̹̹ͺ̹ͺͺʷʵ̷ʵƲ²ĳƵʸ˺̺ʸʸʷʷʴʴʴʴɶʷʷ˸˸ʷʷɶϼͺ̹̹ͺͺ̹ʷȶɷ˹ʸȶǵǵȶȵǴǴǴǴǴǴȵǴƳǴȵɶʷ˸˸ɶȵǴȲǱưůưǱȲɳ̶̶̶˵˵ɳȲǱʶűŰìŹmm]Cm^Aj[>m]Cl^CqcIiĽįưȲʴ̶ͷθθʴɳȲǱǱǱǱȲîþýgzkNm\\@m\\@p_CwgMx_zëǯɲʳɲǮŬīŪǬè§ħħu]xSuPvQvSwT_kôȹƸŷȺͿƨƻɾƧǨȿl{pTg\\@]R6ZO3YN2]R6XM1]R6shLiʼ̾¥ĦäťɩʪȨȨɩʪȩu]Y|WxSxSZhqǼģƥǨũūŬƭ©{htXugJvhKykN|oO{[l̶ɳǳ͹Ѽ͸ϹϹижѴбέ̭ȮȰƮª¨ūĪƿmtiMk`DlaEi^Bf[?h\\B|dźĭƮʲʹʱʱʱ˳̴˴ʳǱǱŰưưưưưŮƬapLlGgAjBzUxũɭɭββʮʮɭǫƪǭɯ̲ͳȫɬʰ˱ʳɲǲƱ̶ʹƮ·l{[wT{sL{Sd}ȫα̴̲ʹ̳˲̰ͱΰͰɫťťĤȾèǪǭʯɰȯǮǮí¬îȲƮʱ˲ɰĪ¦ççũƩħæŦƪǪǫũĨǫ˱ϵϵδͶ̵̵̵̷̷̷̵ɳǮīǱ̸ʸŲưȲʴ̶̶˵Ȳưſ¬ưʴʴȲĮin_BaR3dU6fW8fW8gX9y\\ɽʰǯǱɴȴɳȳɴʵ˶˶˶˶ɴɴɴɴɴɴɴɴϹϹθͷ̶̶˵ʴͷͷ̶˵ɳȲȲǱůľȲ̶ɳɳɳʴ˵̶ͷθ̹̹˸ʷʷ˸̶ͷȰǯǯƮƬǭǭȮǱȲɳ˵̶ͷθθѻѻккθ̶˵ʴ˲˲ʱɰǯƮŭŭɲ˴ʴǱưưĸ~ezfKlX=fR7bN3`M/_L.YH._N4jY?udJ~mQrVtVtVtSpOzjHtdBp`<k[7fV2cT-s`5|j<nDnCrLc´Ŭȴʷȸŵ´ðȱȮȮȮȬɭʮʮũȬʮʮǫƪǫɭħéĪƬȮ˱͵ζ̶̶̶̶˸˸˸˸ɳȲǱǱǱȲȲɳɳɳȲȲɳ˵ͷθ˵θкϹ̶ʴ˵ͷ̶˵ʴ˵˵ʴȲǱ˵˵˵̶̶ͷͷͷθͷͷ̶̶̶ͷͷ˳̴͵ζθͷ˵ʴ˸̹ϽоѿϽμ̺ʷ˸̹ͺͺͺͺ̹˸˸̹ͺͺͺ̹˸̷̹˶˶˸̹ͺͺ˸ͺͺ̹˶̷˶ȶƶǷŸĴŵɹͼͼȶȶɶɶʴʴʴʴɶʷʷ˸˸ʷʷɶнλͺͺλͺ̹ʷǵȶʸʸȶƴǵȶȵǴǴƳƳǴǴȵƳııŲƳǴȵɶʷʷʷȲȲǱǱȲȲɳʴ˵˵ʴɳɳɳʴʴȴɵȳĭ~v\\o_EgX;iZ=hX>i[@xjPqūǲɳʴ˵̶ͷ̶̶˵̶̶ʴưĮĮĮįįĮëfykPpaDrcFscIvfLy`³ǯůǱ˵˵ȯǮɰ˲Ǭũƪƨse}ZyVuTrQuT|[pz³Ʒʽ˾ĤǧǾltXujNj_C]R6ZO3`U9_V9jaD}tWmɾĨ¥ƨʫ̬ʪȨƦɨȨɩɩǨɾumd_]_cdqwúżżûŻùwn~b}a|adluɽīɳʴǳǳͺҿϹθ͵̲̯̭ͬͮȮŭſūʰƬĽkshLh]Ah]Ah]Ai^BmaGjĮ˴Ȱɱεʹεε͵̴˴ʳɳɳ˳ʱȲǱǱůªƿy}^pOhFgAtLbʰɯƬʰͳ˱̲˱ʭȫǪɬˮͰ̯αͳ̲ȱǰȳʵǱʱǯȽzldcgsͰͱʰɯǬƫȭ̱ϴвͰŧǩȪȪħžǸ˽ªǮǮȮȰɰȯȯȯɰȲȲǲȲɱ˲̳̳ʰɯǭū˯ɭȬȬʮ̯˰˯ʮɭȬǫǭȮɯʰȱʳηйѼϺ͸˴˴ʰƪž»Ũȫ̰δ̵˶˸˸Ǳɳ˵ͷθͷ˵ʴȲ¬ů̶˵ĮƾfpaDfW8eV7cT3fW8n_@}`ɽɯȰȲʵȴůƱɴ̷͸͸˶ʵɴɴɴʵʵ˶˶˶ϹθθͷͷθθϹ̶ͷͷ̶˵ȲưĮưſſǱ̶θͷ̶˵ʴ˵̶θϹϼͺ˸˸ͺͺ̶ʴƮȰɱɱǭūūƬưưǱʴͷϹϹθѻкϹθ̶˵ʴɳȯ˲ε̳ȰƮǯɱȱ˴Ǳ¬ưɳȽnqSmZ<gT6dQ3`M/cP2kX:gV<q`F|kQtZ|`gfbc^zXyWzVyUsO~oHqFtFsItIxRd~ɻêɵ̹ɹŵŷǴǰȬȬȬȬȬǭǭɯʰʰʰʰʰʰʰɯǮīīǮ˲ͷθ̶̶̸˷˷˷ʶʶɳȲưůůưȲɳưǱȲɳ˵̶ͷͷ˵˵˵̶̶̶ͷͷͷͷ̶˵ʴɳɳȲǱǱɳ˵ͷϹѻѻкϹθͷͷͷͷθ˳˳˳˳˵˵˵˵ʷ˸μоѿоϽμ˸˸˸˸˸˸˸˸̹̹̹ͺͺλλϼʷʷʷ˸˸˸̷̷̷̷̹̹̹̹̹˺ĶĶĸƷȹʻ̻ͼʷ˸˸̹͹͹̸̸ɶɶɶʷʷ˸˸˸˸̹ͺλͺ̹˸ʷȶȶȶɷɷʸʸʸɶɶɶȵȵǴǴǴȵııŲƳǴȵɶʷʷɶȲȲȲȲȲɳʴ˵˵˵ʴʴɳɳɳʴʶ˷ʵŮ}tZm]CgX;hY<hX>l^CqWxǭǲɳʴ˵̶̶̶̶̶ͷ̶ʴǱůůůįįůĬhykPqaGsdGscIwgM{aĵíȳǱǱ˵˵Ȳȯ˲з̳Ǭǫƨ¤th`}[wUwV|ZdmxöȻ˾ɾȽʿʿ}lx\\|qUshLh]Ag\\@ncG{rU{^nżħǪåħǩɪʫʪɩȨͬ˪ʪʪʪŦȿĺwplkmlqv}xqlns{´Źǯ˲θθ̸̸ϼѾϹϹθ̴̱ˮˬʭƬŭëªȮ˱ƬüjqfJeZ>eZ>f[?j_CpdJqů̵ɱʲ϶ε϶϶ζ͵̵̵ʴʴ˳̳ʴʴɳůſydzYuTtR\\p¼ʲɯǭ̲δ˱ϵδ̯ˮʭʭʭʭƩɬ˱˱ɲȱȳȳɳ̳ɱ}{z{ťήͰʮ˱ȮƬǭ˰̱ʭȫɬʬ̮ͯʭƩ¥ƿο«ǯʱʱ˱̴ʹʱʱʱʱɳɳȳȱʲ̳̳̳˱ʰɯɯ˯ɭǫǫɭ˯̰˯ɭȬȬǫǭȮȮɯʳ̵ϸѺѼлι̵ɲɯȬǫƩƩǧǧȫˮβϵͶ̷˸̹ʴ˵̶ͷ̶˵ʴɳ˵ůĮʴɳ¬ºao`AfW8fW6eV5iZ;sdEe˿ɲɳʶ˸ɶǴȳʵ̷͸͸˶ʵɴɴʵʵʵ˶˶˶ϹθθͷͷθθϹθθͷ̶ʴȲǱưȲɳͷθ̶̶˵ʴʴ̶ͷϹλͺ˸˸ͺͺ̶˵ǯɱʲɱǭūūƬưưǱʴθккθѻкϹθ̶˵ʴʴʱ˲̳̳ɱȰȰɱŮɲưíưƻqy[|iKyhJ{hJudFwdFziKrX}cnw}~w~wssttpj_^_^csɽī˶̹ɷƶǷȶȱɭɭɭɭɭɯȮʰʰʰʰ˱˱ʳ˳ɱǮŬŬȯ˲̶ͷ̶̶˷˷˷ʶʶʶȲǱưůůưǱȲȲȲɳ˵̶ͷθϹ˵̶̶̶ͷͷͷθθθͷ̶˵ʴʴɳǱȲɳ˵ͷϹкѻϹϹθθͷͷͷͷ˳˳˳˳˵˵˵˵ɶ˸ͻоѿоϽμ˸˸˸˸˸˸˸˸˸˸̹̹ͺͺͺλɸɸʹ˸˸̷̷̷̷̹̹̹̹̹˺˼ƹƹƹǸȹɸ˺ͺ̹̹ͺ̹͹̸̸˷ɶɶʷʷʷ˸˸˸ʷ˸̹ͺͺͺ̹˸ɷɷɷɷɷɷɷɷɶɶɶȵȵǴǴǴȵııŲƳǴȵɶɶɶɶɳȲȲȲȲɳʴ˵˵˵˵ʴʴɳɳɳɵʶ˶Ư~w]p`Fl]@m^Am]CtfK}cĺȮǲɳɳʴ˵̶̶ͷͷͷͷ˵ȲưưǱŰƱưŭhzlQrbHrbHscJyiP}fĸǱ˶ȵǴʷʵȲȲ̶иεɮŪ§§çæ}sjc`aejqw|øź·uli}avZx[dyžħƩǪǫƫǫɬɬɬʬˬί̭ʫȪʬɬȫǦĝȿ÷}z}{}ʼŮȰϷеѸкϻκλλͺθθ͵ʹ˰ɮȭƮǯǯǯ˱̲ĪgodHcX<cX<f[?ncGxlR|ư̵ʲ˳϶϶ззζζͶ̵˵˵ͳγεε̵Ư½snkjsªʴɱɱζϷ˳ϵδͰ̯̯ˮɬȫƩʭͳϵͶ̵˶˶ɳ̳ʲũǼ˫ϰαˮʯɮȭʮ̯̯ʯȫʭˮͰαϲα˯ʮŰǲʴʴɳ˳͵зʹʹ̳̳˳˳ʳʳ˳˱˱˱˱̲ͳͳ̲ɯƬƬǭʰ˱˱ʮʮ˯˯˱˱ʰʰ˴ͶϸѺҽлιͶɲʰ̰ͱααϯϯʭͰджη̷̹̹θθͷ̶ʴɳȲǱ̶Ǳ¬íǱưſ_paBiZ9iZ9iZ9pa@{lMl¨˴ʴ˷ͺ˸ʷ˶̷ιι͸˶ʵɴʵʵʵ˶˶˶˶θθͷͷͷͷθθкϹͷ˵ʴȲȲȲʴůĮʴθθ̶˵ʴʴʴ̶ͷθλ̹˸˸ͺͺͷ˵ɱ˳̴˳ȮƬƬǭǱǱȲ˵θккϹккϹθͷ̶˵˵̳˲˲˲˳˳ɱǯ«ȱǱź}ohlpmkm~ŷǹõĶµµ~}ø¨Ǯ˶̹ʷȶɷ˸ʰʮʮʮʮʮʰʰ˴˴˴˴ʳʳʵ˵ɳǱĮůǱʴ̶ͷ˷˷˷ʶʶʶɵɵǱǱưůůưǱǱɳʴ˵̶ͷθϹϹ̶ͷͷͷθθθϹϹθθͷͷ̶˵˵Ȳɳʴ˵ͷθϹкϹϹθθͷͷͷͷ˳˳˳˳˵˵˵˵ɶʷͻϽоѿоо̹̹̹̹̹̹̹̹˸˸˸˸̹̹̹̹ʹʹʹ˺̹̹͸͸̷̷̹̹˺˺˼̼ɻɻȸȸɷʷ˸˶͸͸θͷ͹̸˸˸ɶʷʷʷ˸˸˸˸ɶʷ˸ͺͺͺͺͺ˹˹ʸʸɷȶȶǵɶɶɶɶȵȵȵȵȵŲŲƳǴȵɶɶɶɶɶǱǱǱǱǱȲɳɳ˵˵˵˵ʴɳȲȲİǳɴŮ|bxhNteHteHvfLrWqɿȮȳɳɳɳʴ˵̶ͷͷθθ̶ɳȲȲɳƳȴɴůi{oUseJtdJvfM~pVlǻ˵ͻɷǵʷɵǲɴͷ˳ʲȰŪŪɬƩľvtqprux{z}ƿæƨǩƩʮȭȬȫǪɫʬ̭ʫɪȩȩȪɫɬ˫ǢĝǿƾŽĻ¹úú¹¹·˽éǰȳȳȲϵϴγεͷ͹˸ɶʷ˸˸ͷ̶̳˲ʱȰ˳̴̴ͳ˱eqfJh]Ai^BodH{pT|bư˴ʲ˳εε϶϶͵͵̵˴ʴʴδγʹʹ˴ǰʿǱʴɳʴζζ˳ʰʰˮ̯ͰͰˮʭʭͰϵϵͶʳʵʵưɰʲɭũ¤âŢģĤȨͮϱ̰ȬéĪūȭʮˮȮȭʯʭʰ˱̲̲ͳͳǴȳɳȲưȰ˳ε϶϶϶ε͵͵˴˴˱ʰɯɯʰ̲δж̲ɯƬūǭɯʰ˱ͱβдѵѷжδͳ̵ͶϸйлϺ͸̵˴ͳβϳϲͰ̬ͭɬ̯βϵͶ͸ͺλҼкθ˵ɳǱưưʴǱ¬Įůľ|}]rcBl]<l]<l]<ufEtSuĪ˴ʴ̹ͼ̹ͺιιιι͸˶ʵʵʵʵ˶˶˶̷̷θθͷ̶̶ͷθθѻкͷʴɳȲɳɳ̶ȲůůȲ̶θθ̶˵ʴɳʴ˵ͷθͺ̹˸˸ͺͺͷ̶ʲ̴͵̴ʰȮȮȮȲȲɳ̶ϹѻкϹθθθͷ̶̶˵˵ε˲ʱ˲͵͵ʲƮ«ǰȲíʿɾźŻèŪǬĩɿ§ȿ¥¥ɾʽǺķŸƻɾʿȿƫɰ˴˶˵ʷ̹Ϲʰʮ˯˯˯˯̵̵̵̲̲˴˶˶˶˵ʴǱűưȲ˵̶̶ʶʶʶʶɵɵɵȴǱǱưưưưǱǱɳʴʴ˵̶ͷθθͷͷθθθϹϹϹϹϹϹθθͷͷͷʴʴ˵̶̶ͷθθθθθθθͷ̶̶ʲʲ˳˳˵˵̶̶ɶʷ̺μоѿѿѿͺͺͺͺͺͺͺͺ˸˸˸˸˸˸˸˹˼˼˼˺ͺͺ͸ι͸͸̹̹˺˼ʻ˻̽˺˺ʷɶʴʵʳ˴ʳʵ˵˷̸̹̹ʷʷʷ˸˸˸̹̹ɶʷ˸̹ͺλλλͻͻ̺ʸɷȶǵƴɶɶɶɶɶɶɶȵɶŲŲƳǴȵɶɶɶȵȵưưůůưưǱȲ˵̶̶̶˵ɳȲưİƱ«~d}mSxiLzkNpVd~ŬɯȳȲȲȲɳʴ̶ͷͷθθͷʴȲɳʴɵʶ˶ưpz`}oT|nSrX~dyʾͷͼɸǶɷȷƴǳ̷ŰȰʲǯéèƫʯ̯ǩž¹ĹƸĹĹĻæææĦĦŧǩƩʮȭǫƩŨǩȪʫǨȩɪʫʫɪȪȪǧťţţǥƤâ áâģģĠ¢¥ääĥâ¢àĤƨǬȮǲƳĴð˱̯˰˲˵˷ʷȵǵȶɷʷ̸̶̶̶˳ζϷ͵̲Ȯžk~sWynR|qUx\\jyźĮȱɱɱ̳̳ʹʹ̴˳ʳʳȲȲϵͰ˰ʱɲȱŰîùĸɻ˿ɴ˷˷ɳʴͷε̳ȭɮˮ̯ˮˮ̭ͮˮ̯̲˱ǰŮŰŰůɰ̴βͱʬȨȧĤƧǩˮϲβȭĩ̼éƬǬǫƬū˰ʯʱʱɱɱʲʲȸɶȵǳűǱɳ̶йй϶϶͵͵˴˴ɯɯȮȮɯ˱϶зε˲ȯǮɰʱ˲ʰβϳѵҶҸѷϵδ˴̵ͶͶ͸̷˶ʳζδгѴвΰ̬˫Ȫ˭Ͱͳ͵ͷλнҼѻθ˵ɳǱưůưůſíưýuyWqbAl]<l^;m_<xiHyX}Ƭʳȵ˸ͼʺϼϺϺι͸̷̷˶ʵʵ˶˶˶̷̷̷θͷ̶̶̶̶ͷθѻϹͷʴȲȲȲȲ˵ɳȲȲʴ̶θθ˵˵ʴɳɳ˵̶ͷͺ˸ʷ˸ͺλθ̶˳͵ζζ̲ʰʰ˱˵ʴ˵ͷкѻкθ̶̶̶̶˵˵˵˵ʹ˲ɰʱ̴̴ɱƮĭȱɳůʿȽƼæȿƽħæ¥¥ĪǭǭĪĪǭȮūƬū«««ħ¥§ǬɮǬĨɯʰʳʳʳʵ̷ηʮʭ˯˯̰̰̲ͳ̵̵̷˶˸ʷʷʷʶɴƳȳʵ̷͸̷˶ʵʵʵɲɲɲȲǱǱǱȲȲǱǱǱɳɳɳʴ˵˵̶̶ͷͷθθθϹϹϹϹϹϹθθθθθ̶̶̶̶̶̶̶̶ͷͷθθθͷ˵˵ʲʲʲ˳˵̶̶̶ʷ˸̺μϽоѿѿͺͺͺͺͺͺͺͺ˸˸˸˸˸˸˸˹ʾ˿̻̽λλιι͸͸ͺ̹˺ʻɽʽͼ͹˸˷ʴʲʳʱǮȮǰȲʶ˸ͼλʷʷ˸˸˸̹̹̹ʷʷʷ˸̹ͺλϼμμ̺˹ɷȶǵƴɶɶɶɶɶɶɶʷɶƳƳǴǴȵɶɶȵȵǴưưůůưǱȲȲ˵̶̶̶˵ɳǱůİŰiu[tWy\\ftȼɰ˱ȳȲȲǱȲʴ̶ͷ̶ͷθ̶ʴȲɳʴʶ̷̷Ȳſtiio|¬ͺ˻ǷƶɸȷŴŲɵİɴ̵͵ʰǭɮʯʯɬŨƿ»ŷĶ´øĻżĽ¥ĽƿħĨèĨç¦æŨɬȫȪǩǩǩʫɫǬƫĩħæĦŧƧƧɪ̭ͮˬɪǩǪɯȮǭȮɯȮƬĪƬǫȮɭȭȭȭɬǪȨǨȧɨʩ˨˨˫ʬɮǰƱŵĵŲɯ̭̯̱˲ʴʵʷȶȶȶȶʷ˷ͺκ̶ϷϷ˳ɯƬžznosxȼĮǰȰɱ˲˲̳̳˳ʲɲɲǱȯβ̯ɮȭɲ˳ɴɴïðııŰŮůƯ̹͹̸ʶɳɳ˲˲ʯͲαɬ£Ʃɬ˱˱ɲǰǲǲǱʱ̴ϳϳͯɩȩɫʬˮαβʯéϿʺξīɯɯɮǮȮ̴ʹʹ̳ʴɳɳȲɹʺʷɵǳɳ˵ͷϸϸ϶ε̴˳ʳʳɯɯɯɯʰ̲ε϶ε̳ʱʱ˲̳˲ʱ̲ͱͱβδͳͳ̲˴̵̵̵̷˶ʵʳ͵δϲгѳѳааɫ˭Ͱ̴̲ͷλнкϹθ̶ʴȲǱư¬Į¬ſíůlsQo`?l]<l^;n`=|mL^øȮʳǴ˸ο˻ϼιι͸͸̷̷̷˶˶˶˶̷̷̷͸ͷͷ̶̶̶̶ͷͷϹθ̶ʴȲǱǱưȲȲɳʴ̶̶ͷͷ˵ʴɳɳɳʴ̶ͷ̹˸ʷ˸ͺλθͷʲ̴ϷϷδͳδϵθͷͷθккθ̶ɳɳɳʴʴʴʴʴ˲ʱʱʱʲʲȰƮȱɲȲưíʭȨƦǧǪȪǫǪɯ˰ƬŬǯưȲȲŲűð®Ĭ¨ªŭȱɲǰƬȮȮȱɲɲ˱˴̲ɭɬʮ˯˯̰ͳͳ̵̵̷˶ʷɶɶɶʷɶǴȵ˶̷̷˶ʵʵɴɴɲȱȱȱȲȲɳʴʴɳȲȲɳɳɳʴʴʴ˵˵̶ͷͷͷθθθϹθθθθθθθθͷͷͷ̶̶˵˵˵̶ͷθθθͷ˵ʴɱɱʲ˳˵̶ͷͷ̹̹ͻμμϽооλλλλλλλλ̹̹̹̹˸˸˸˹˿;ͼϼϺϺιιͺ˺˼ɽȾɼκθ͸̵̳˱˲˲ȯȯǰȲȵ˸ͼϾ̹˸˸˸̹̹̹ͺ˸˸˸˸˸ͺλϼμμͻ˹ʸɷȶǵɶɶɶɶʷʷʷʷʷƳƳǴȵȵɶɶȵȵǴȲȲǱǱȲȲɳʴ˵̶ͷͷ̶ɳưů®ƲȳŮŹ{qqxĶĪʱɯȳȲǱǱǱɳ̶ͷ˵̶ͷ̶ɳȲɳʴȴ˶͸˵ưüǻ˿ư̹ɹƸƶɹȸŴıǳǳʵͶͶ͵ʲȰȭǬɮȭŪǬˮʭŨƬūūūūƫŪĩŪçĨȫȫħŨɭȬƫĩèƪǫȫǪǪȫʬ˭̭ˬʫȪūĪ¨ƨɫ̮̮ȫƩǪǭʶɶȵȴɵǴŲıǴȲǴȲȳɴɴ˱ȫɩȩɨʩ˧˨˨ʪʬȭƯƳŵŶƵȬˬίͰȯůǲɶ̺ʺȸƶƶɶʺͺʴ͵̴ȰƬƬ¨üø¨ǯưůǰɱʲ˲̳ʹʹ˳˳ʳɲȲɰͱ̯ʯʯ˴̴ʵɴȶɷɸɶɶɶɶȵ̸̸̹˷Ȳưȯ˲γѶϲ¨ɯʳɲǲǲưǮǯɭɭɫǧƧȫȫħ¥ǼĶʹūǬȯ˱͵ͷͷͷ̸ʶȵǴȸɹ˺ʸɷɶ̶ͷηηʹ̳ʲʲȱȱɯʰ˱̲ͳͳεεεʹ̵Ͷηη˴ɰ̲̰˯˯˱˱̲̲ͶͶͶ̵̷˶˶ʳ̴̲ͰαϱвѱҲΰϱгδ̴̶̹λͷͷͷͷ̶ʴȲưůĮíĮd~qNpb?pb?rdAvhExWkɾ˳˶ɶͺͽλ͸͸̷̷̷̷̷˶˶˶̷̷̷͸͸ͷ̶̶˵˵̶̶ͷ̶̶˵ʴɳǱůĮĮưɳ˵̶̶̶̶˵ʴɳȲɳʴ̶ͷ̹˸ʷ˸ͺλθͷɱ̴ζиϵϵѷҸѻкϹϹкϹͷ˵ưǱǱȲȲɳɳɳȯɰ˲ʱȰƮƮǯʳȱưůĮ¬éɬʫȪǨƩǪĪèɮ˯ƭĭůŰȴɴȵƳóòðİï®®ĮĮĮëƮƮǭȮʰʮʰɭȫȫɭʮ˯̰̲ͳ̵˴˶ʵɶȵǶǵʷɶȵɶ˸̷̹˶ɴɴɴȳȱȱǰǰɳʴ˵̶̶˵ʴɳʴʴʴ˵˵˵˵̶˵̶̶̶ͷͷͷθͷͷͷͷͷθθθϹθͷͷ˵˵ʴɳ˵̶θθθ̶ʴɳɱɱʲ˳˵̶ͷͷλλμͻμμμϽϼϼϼϼϼϼϼϼλͺͺͺ̹̹˸˹ονϼлйηιͺ˺˼ɽȾɼ͹ζ͵̳̱Ͱ̱̱γ̳ʳʴɶ˸ͼν̹˸˸̹̹̹ͺͺͺ̹˸˸˸̹ͺλμͻ̺˹ʸɷɷȶɶɶɶʷʷ˸˸˸ʷƳƳȵȵɶɶɶȵǴǴʴʴɳɳʴʴ˵̶˵̶ͷͷ̶ɳưĮ®Ƴ̶˶í÷ĶǻªɰȲŮɳȲǱưǱɳ̶ͷʴ̶̶˵ɳȲȲɵƳɵ͸κ̶Ʈž¸ƺŪʱɯʰηɸǷǸ˺ʺŴĲųʷʷ˶̶̶ʴǱůŬɰɰƭȯγͲƫȯȯȯʱʱʮǮƪʮũŨɬɬħħȬɬǫĨçǫˮʭǪæƩ˭̭ͯͯǩæ¨¨žþ¾æƩǪƩħħūȰǴƷĴŲƴǴƱİưưǰǰǲȳɴʳȬȫɩʪɨɨɨɨʩʫȬǭưıĳĮƩ̪έˬĨªůϻ̺ɶŲĲǴɶ˷ȲʲɱŭĪƬūȾ¸¸ūϴζ˲ǰɯ˳˱˳Ͳ͵ͳ͵̲˴˱ɳʱ̰̯̱ʹη̵ȳűȴʶɶȵȵʶɶǴ˷̷ι˵ǱīŭʰϵҶ̰}jhl~ȿŨħ¥ŧåßľ~vnjjvƸɾ§Ƭ˳̶ͷͷ̶ɶǴƳǶȷʸʸɶɳʴ̶̶̶̳˲ɱȲǲƯɲ̲ͳϵϵδͳͲͲͲε϶з϶˲ȭϵδ̲˱˳̴ζϷϷϷϹθ͸̷̷̷͵̲˱ˮˮ̯ͯϱӶԷӶж͵˵̶ͷʴ˳͵θͷ˵ɳǱưƮëéb}sOsfCuhExkH~pMaz¦εͶ˵лѾϼθ̵̷̶̶ͷͷͺ˸˸˸ͷͷθθθ͹̸̸˷˷̸˸ͷʴ˵˵ʴɱƮĬªĮȲ˵˵˵˵̶˵ʴɳȲɳʴ̶ͷ̹̹ʷ˸θιͶ̵ɯ˱ͶϸиѹҼԾҽѼϺϺϸη˴ɱŭŭƮƮǯȰȰɱŭȮʰɯƮĬŭǯ˴ǲįŰŰį­«ƩɪɪǪǪƩĩǫɭǭìį­űŲƳŲò±òòŲŰðĿĿſĬĬŭǭɯʰȮƬǫȬɭɭʮ˯̰̰̲̲ʳɲȳǲǴƴ˸ɶȵʵ̷Ͷ̵˲ɰɰȱȱȱǰǲƲʴ˵̶ͷͷ̶˵ʴ˵˵̶̶̶̶ͷͷ˵˵˵̶̶̶ͷͷͷͷͷͷͷͷͷͷϹϹθͷ˵ʴɳɳ˵̶θϹθ̶ʴɳɱɱʲ˳˵̶ͷͷнϼλͺͻͺμλϼϼϼϼϼϼϼϼϼλλͺͺ̹̹̺;οονнлйιιͺ˺˼ʻȼʺ͸͵͵̳̳̲ͳδӺѺη̶ʷ˸̻ͼ̹˸˸̹̹ͺͺͺλͺ̹˸ʷ˸̹ͺͻͻ̺˹˹ʸɷɷɶɶɶʷʷ˸˸˸ʷɳɳǱǱǱǱǱǱǱǱɳɳʴ˵̶ͷͷθ˵̶̶̶̶˵ʴɳŲƳɶʷȳįŽîǲʵ˶ʵȳȲʷɶȵȵɶʷ̹ͺɶǴııŲȵɶɶɶɶʶ˷͹̶ɱƬ¨Ūȫʭʭ̮ΰγͺͽ̽˹ȸȶɷ˹ɷ˹̺ͺ˸ɶɶʷǲǯȰȱɲ˲˲ʱɲȱǰƯǰɯʳ̲ǭƬūūƩƩǪȫɭȭȭǬǬɭʮʮçũɭ˯˯ʭũçɬɬȫǪŨæǭƬūĪūƬǰɳǶȶŲðůǭƩäϿο¢ƧǪȫǪǪȫɬˮˮʭȫŨʭʭʭɬȫƪĨæãà ŸʹĨ˱ǭê˳η˳̵͵˱ɯȮʰʰʰȮȮʰ˱˯ȯɭɰ̰ɰʮʰʮ̲ͱϵѴϵβδͱͳ̰̲̲ʲɱȰɳ˵̶˵ʶκ̸ʶƳŲǱȲɳȱʲ̴̵̶̴ʳɰǯɯonSvbGtaC~]hyõö}{}ķǼžwgUxFsAvDyIYlyƹťˮūȰʳζη͸˶ɴǶȷʷɶȲȲʴ̴̴̴˵ɳȲȵ˸λʵʳʴͶϵδ˱ɬɬˮίϰϰί̭ʭʳ˶˶˵ʴ˴ϷҺԼԼӾѽϼλͺ̷Ϸ϶϶ϴϴϴγγѶѶҷѸзε˲ʱʰͳϵϷ̶ɳŲıĮʲɯħåw]}xPvnGwoHvR`vũɭʰʱ̲Ϸӻҷδʲɳʴ˷͸̸̹͹κϹϹϹҺԾӿν˺ʷɶʷʶ̸˵ʴʱƬŨæ¥ĭƯʳͶηͶ˴ʳ˴˴ʳɲȱʳͶѻϼν̶̵̹ʹ̲ͱǫȮʱɳιͽͻнн̶̳γʯæžŧƨŨŨŪƩǫǫƪũūūŮŮůŲƴƴŵĴ²¯ɭ̭̰ͯɭǫƪƪʯȭƫé«ĭĮůǱƲðİƱƱŰįîª¬í¬ĮííīŬǮɰʱʵȲȲȯȭʭˬˬˬˬˮʯʱʱɳʷɸ̺͹ζ˲˯ˬ̭ȩǨƩƫƭűŲƳǴʴͷͷͷ̶ͷϹʴ˵˵̶̶˵˵ʴʴɳɳɳɳʴ˵̶кϹͷ˵ʴʴ˵˵̶̶ͷθθθͷͷʴ˵̶ͷͷͷͷ̶ưȲʴ̶ͷͷͷ̶кϹϹθͺϹλϼϼϽμͻͻ̺˹˹μμμϽϽоооͻͻͻͻͺλнѻϼϼϼϼϽϽϽϽλ͹˷ʶɶʷ̹ͺннϼλ̺˹˸ʷͺͺͺ̹̹˸˸˸λλͺ̹̹˸ʷʷ˸˸˸̹̹ͺͺͺȵɶʷ˸˸˸˸ʷ˸ɳȲǱǱǱǱǱǱǱǱȲȲɳʴ˵̶̶ͷ˵˵˵˵˵ʴɳȲıŲȵɶɶǴŲðıƳȵʷ˸ʷɶȵ˸ʷɶɶɶʷ˸̹ʷǴııƳȵɶɶɷǵŲƳɵ˵̳̳̱̯̮̭̭ͯͮϱɳɵɷɵƴǳȶ˷ȶ˷˹ʶǵűĲűʵʳʳʳʳ˲̶ʹɳȲǱǱǯɱʲ˳ɯȮǭǭȫȫɬʭȬȬǫǫȬɭʮ˯ĨƪȬʮʮȬƪĨɬȫȫƩŨæūūūūĭŮƯǱ̸̸ɳǭĨ˻ȶ˸ͻǟ˧ΪΫ˫ʭʭɭɬʭʭɬɬĤĤťĤĤá¢~x~ǴħĨͳд͵иζ̲ʰʰ˱̲˱ʰ˱̲ͳ̲ʰʰ˱̲ʰʮ˯̰̰ͱβββββͱͱ̰̰̲ʲɳȲɳ˵̶˵ʴͷ˵ɳǱưưǱȲɱʲ̴̵̳˳ɯƮĪ©ȷy^s[AfN2cL-mZ9wgCzSepvrokhdchoyûlSp:s`(t^%{e,p=Peuö¡ǪūƯɲ˴̵˴ʳɲȶɷʷɶɳɱʲ̴˳˳ʴȲƳǴʸ̺ȶȶɵ˷̵˴ɯǭʭˮίббϰͬˮǰȵʷ˷˶̷ϺҼտտӾӾѽϼͻ͸Ϸзз϶϶϶϶εѸҹҹѸзε̳˲˱δѹиθɶǵƳƳ˵ʲŨåw]}T}xR~XdsĹũȭ˱Ͳ̳δиԹҷδ̳ʴ̷͸ͺ͹μллйηε϶Ѹϻμͼ̻˺˸˸̷˷˵˲ʱǭǪŧħƬǰɲ̵ͶͶ̵˴˴˴ʳɲɲʳͶкϼν͹ͷͳͰˮʭǪˮ̲ʴ˹Ͼ˻λ̷ǰǭɭǨĢĢĤťɪ̭ͰαɭɬǪŪīêììůıųŵŵĶ´ɰ̰βͱʮȬǫǫɮȭŪ¨íưǱǱȲɳʴʳǰǯĬêĭŬůŭîìǿ¬ŬůƭƯůǴǳǳɰɮˮˬ˪̫˪ˬʭɮʱɳ˶̼ͻ˸˴̰ˬ˩˧ƢƣƥǨƭůŲŲŲɳ̶θͷ̶̶ͷʴ˵˵̶̶˵˵ʴʴʴɳɳʴ˵˵̶кϹͷ˵ʴʴ˵̶̶ͷͷθθθͷ̶˵˵̶ͷͷͷ̶̶Ȳɳ˵̶ͷͷͷͷкϹϹθθϹϹкͻͻͻͻ̺̺̺̺μμμϽϽоооλͺͺͺͺλϼнϼϼϼϼϼϼϼϼͻ̺˹ʸʸ˹̺ͻѿоϽμͻ̺˹ʸͺͺͺ̹̹˸˸˸ͺͺ̹̹̹̹˸˸˸˸˸̹̹ͺͺͺȵɶʷ˸˸˸˸ʷʷȲȲưưưǱǱǱǱǱǱȲȲɳɳʴ˵˵ɳʴʴʴʴɳȲǱıŲƳȵɶʷʷʷɶɶʷʷʷʷʷʷ̹˸ʷɶɶɶʷʷʷǴŲŲǴɶʷɶ˸Ǵñ¯Ųʴ͵ζδαˮʫɨɨʩʪ̲ͳ˴ʰǰɯʳδ̵ϵϸδʳȮǰȰʲ˲˲ʱȯǬǯɮǱǱǱưǯȰɱɱ˱ʰɯɯʭʭˮ̯ƪƪƪƪǫɭʮ˯ƪǫȬȬȬȬǫƪȫȫǪŨħ¥¨éūƬƯŮĭŭɰɯǪĤŻ|tw|ĶǟɢɣƢĠɾȽǼǼǼźźƻǼȽȾȽǾýr_xV}\\gɶ¥ȬжѶͶѺζ˴ɲȱɲʳɲȱ̵ͶηͶ˴ɲʳ̲ʰ˱ͳͳδͳ̲˱˱˱˱˱ʰʰʰʰʲɳȲɳ˵̶˵ʴ˵ʴȲưůưǱǱɲɲ˴ʴ˲ɱǭĬȮêòznSgR7ZE(WB#fV4oa<rKYchigWUY^kzµɾĖwVwg4dS\u001fkV!wb-{KazĶȾƧʭƬƯȱɲɲʳɲɲɷʸ˸ʷɳɱʲ˱ʰʰʲȲŲƳȶʸƶǷȸȸʷȵǲŰ˳̴͵ζϴγͲ˱Űǲʵ̶ͶζиҺսսӼһѻк͹ιиѸзз϶϶϶εҹҹҹѸзεʹ̳ͷкѾѾμ˹ɹɹǷʸȵĬĿ}minwɾɯƮȯʳ̵̳͵Ϲѹҹеʹ˵̸κλͺ̹κκ͸˳ʯ˰˱ʵʷ˸̹ͺ̸˷ʶ˷˵˲ʱʯɮȫǭǰȱɲʳ˴̵ͶͶ̵˴ʳɲɲ˴̵Ϲϼλθ̴ʮȫæãťɬ˱˲ʶͼ̽˺̷ȲȼǼúæǬȫ˯ɮȭƫŬê«ůııųŲóóðʳ̳εʹʱǮƭƭũƪũ¼ĭĭƯȱ˳̳ɰǮŬīƫȯǭĭĪ©źǽĪŭĩ¾îŰǲ˱̰̯ˮ˫̬̬ɬȫȬɯʳʷнͼɶȲʭɨŢ¾ÿ¬ĮȲ̶θͷ̶˵˵˵˵̶̶̶̶˵˵˵ʴʴʴʴ˵̶ͷкϹͷ˵ʴ˵̶̶ͷͷθθθθͷ̶̶̶ͷͷͷ̶̶˵ʴ˵̶ͷθθͷͷϹϹϹϹϹϹϹϹ˹˹˹̺̺̺ͻͻμμμϽϽоооλλͺͺͺλϼнϼϼϼϼϼϼϼϼͻ̺˹ʸʸ˹̺ͻѿѿоϽμͻ̺̺̹̹̹̹˸˸˸˸˸˸̹̹̹̹ͺͺ˸˸̹̹̹̹ͺͺȵɶʷ˸˸˸˸ʷȵȲǱůưưưưǱǱǱǱǱǱȲȲɳɳɳȲɳɳɳɳȲǱưıŲŲƳȵɶ˸̹̹˸ʷȵȵȵɶʷ̹˸˸ʷɶɶɶɶʷȵƳƳȵʷʷʷͺʷųıǴ˵͵δ̯ȫħã ǾĻǾäæĥŨĥ¥ȿȬɭɭȬƪĨĨƩưưưưǯǯȰȰ˱ʰʰɯʭˮˮ̯ĨĨĨũǫɭʮ˯ȬȬȬǫǫȬȬȬȫǪƩħæ¥¦éūǭǰŮìéǩƧĤľq`YW`rźŽ´õ´ĶŶǸɺ˼̽̽˾âf}mLs`?xdClMtʰӹи̵й͵ʳȱǰɲɲɲǰͶηηͶʳɲɲʳʳ̲δϵδ̲ʰȮȮȮȮȮȮȮǭƯʴɳȲɳ˵̶˵ʴɳȲǱưůưưǱȲɳɳʴɱǰŬīͳĪunRhW;cP2aP2eV5m`=|nI}U\\_[Y[]bm|ĸȣԭϥȞluEp`/we5tEjоŠƣƧɬ˯ȱȱȱɲɲʳʳ˴ɷʷ̶̹ʲɯʰ˱ʰ˱˳ɱǱƳȶɸƸȺɽɻȹƵŴƳ̹̹ͺθθͷ̶˵ǲȴ͸ϹθηηиӻӻѺϹϹ͸̸ͶиѸѸз϶϶εεҹѸѸз϶εʹʹλоϿ˾ʽʽƹɹǵðªſú˿Ƭʲůưȳɳʵ˶̸̷ҹз̶̶κϻϼλʷ˷̸˵ɰȬȪȭɱʴ̶ͷͷ̶ʴȲʴʴ˲ʱʱ˲˲˲ʲɲȱɲʳ̵ηϸͶ˴ɲɲʳ̵̵͵κθ˳Ƭȿøķʽ¦Ǯ̸н˻òǴ«Ź~}vty¥ȮɯɯȭǮǮƭŬììĮĮııİııİʳ̳ʹ̳ɰƭŬŬŧǩƩæþ»ǽ©īůǰƮīê§ĪǪƬçȼ÷ôõõƺɿ¼ǿ¯Ʊʳͳͱ˯ɬʭȫǪƪƬƯǲɶͻɷƳǯȫ¢ºľ¬Ǳ̶θθ˵ʴɳ˵˵̶ͷͷ̶˵˵˵˵˵˵˵̶ͷͷкϹͷ˵˵˵̶ͷθθϹϹθθͷ̶ͷͷθθͷͷ̶˵̶ͷͷͷθθͷͷϹϹϹϹϹϹϹϹɷʸʸ˹̺ͻμμμμμϽϽоооϼλͺͺͺλϼϼλλϼϼϼϼннμͻ̺˹˹̺ͻμѿѿоϽμͻͻ̹˸˸˸˸˸˸˸ʷʷ˸̹̹ͺλλ̹̹̹̹̹̹̹̹ȵɶʷ˸˸˸˸ʷǴȲǱĮůůưưǱǱǱǱǱǱȲȲȲȲȲȲȲɳɳȲǱưưƳƳŲŲƳǴȵɶ̹˸ɶǴƳǴȵɶ˸˸˸˸ʷɶɶȵʷȵǴȵʷ˸˸ʷϼ̸̼̹̹ͷʳɯũ¹{~ƼùŻǽƼŻùĺĺøøźȽæǪȫȫůưưǱǯȰȰȰɯɯȮȮɬɬʭʭĨĨĨũǫɭʮ˯ɭɭȬǫǫȬɭɭȫǪŨæ¥¥¦¦éƬɯȱƯì¨˪ɣĞuXyHuCtAM_nw{}}}³ƷŶôɹʺ̼ξ¡¡ʿbwgFmZ:s^?}fGf˺Ƭзη˵ϹϹ̷ʵʵ˶˶˶ʵ̷͸͸̷ɴȳȳɲʳ̵ͶηͶ˴ȱǰȱȱȱȱɲɲɲɲʴɳȲɳ˵̶˵ʴȲȲǱǱưưưǱȲɳɳɴȱưŬīȮ̾tvYxiLxiJ}nO{Ycq|{~ƼƦ̦ͬͩayM~Sc˼ʥ̪ɪǫǭǯʳʳʳ˴˴˴̵̵ɶ˸ͺ̷ʳʰɯʮ˯̰ͳʳȳǲȵɸȼʾɽƺĶƷǸ̻̽ͻͺ̸̹̹ʷ̷ͷйѹ϶ʹ̳̳з϶εʹ˳˴˵̵ижϵδͳ̲̲˱жϵϵδͳͳ̴̲λʾǻɺȹƵƳįļĽĩƭŭĮưƲǴǴʷʷʹʷкθ̶̹μϽμͻɶʷ̴˱ȬƩƦŨȯǱɲʳʳɲȱɱ˲˲ʳʳʳ̵Ͷη˳ɲɲɲʳ̵ϸйͶ˴ɲʳ̵̵˴ʳ͵ʰħ|{§ϹԿȶº÷nz^|qSzqR~uTtkJvpN{[qëƮŮŬůưưưƯƯĬĬííĮİİĮɲʳ˵ɳưíǨɪȪħȿżƻǻ˿īĪĨƺŷƻƼƼŽǱ˳ͳͰˮɬȫǪƩĪĬůưƳǴŲįūvvtsv~ªǱ̶θθ˵ʴɳ˵̶ͷͷͷͷ̶˵̶̶˵˵̶ͷθθкϹͷ̶˵̶ͷθϹϹϹϹϹθͷ̶ͷͷθθθͷͷ̶θθͷͷͷͷͷͷθϹϹккϹϹθɷʸʸ˹ͻμϽϽμμμϽϽоооϼϼλͺͺͺλϼλλλϼϼнннϽμͻ̺̺ͻμϽѿѿооϽμμͻʷ˸˸˸˸˸˸˸ɶʷʷ˸ͺλλϼ̹̹̹̹̹̹̹̹ȵɶʷ˸˸˸˸ʷǴǱưĮĮĮůưưǱǱȲȲȲȲȲȲȲȲȲȲɳɳɳȲǱưǴƳƳƳƳƳǴǴ˸ʷɶǴƳǴȵȵʷʷ˸˸˸ʷɶȵʷɶȵɶ˸̹˸ʷξξϼмϼζɲǫǾrjb]Z[[Z\\bn|wttɾƨɬưưǱȲɱȰȰȰȮȮǭƬǪȫɬɬƪƪƪƪǫɭʮ˯ɭɭȬȬȬȬɭɭǪƩħ¥¦ç¨ĪǭɯɲǰŮĨ̬ƠŽevG{k8~m9o<{GVaimqrs|ô˼;;;ͽâŤŧƨƨǨĤɾdscBiV6nY:u`A}`ĳ̴̶˵кҽϺͺ͸λϺλ͸˸̷ͺ˶ɶȳɶʵ˶̵̵Ͷ̵˴ɲȱ̵̵ͶͶͶͶηηʴɳȲɳ˵̶˵ʴȲȲȲȲȲǱǱǱǲǲȴȴȲǱƭŬūʾpkowv|Ƽƾĺĺº·¹ƻ¥ūɮʬ˪ȥsxǹà˫ʬȬȰɳȲ̴˴̵ͶͶ̵̵˴ʷ̷ιͶ̲ʮɭɭ̰ͱδ̲ɲȳȵȷȺ˿ʾŷõƷȹ̻̻̺̹˹ʷ˸ʷϸϹѺϸ͵˲˲˲εʹ˲ɱȱɲʴ̵ϵϵδͳ̲˱ʰɯδδͳ̲˱˱̴̲̹ͼοο˿ɽɽʾ;̽˺˺˸ɴŰƩʮʮ˰̱ʲŭưůŰǲɶ̸˸ʷͺ̶˸̹ͻͼ̻˹ɷʶ˲ǬǼĹ·Ⱥƺƺǻʾèƭɯ˱˲ɳɲʳ˶͸ι˵ʳɲɲ˴Ͷϸйη˴ɲʳ̵Ͷ˴ȱ˱ũuifgmzҸվǴ~hwlNdY;ZO/\\S2d[:aX7h_>voRiƯ¬íůǱȲǱȱǰëëëªíŬŬƭǱɳʴɳů¬ȦţĻŷʼ§¨ĨŷysollovǹʾŽưʲ̴˱ɯȫƬƬƬƮưưŲŲï®·sccbeit»ìȲ̶θͷ̶˵˵̶̶ͷͷͷͷ̶̶ͷͷ̶̶ͷͷθϹϹθͷ̶̶ͷθϹккккϹθͷ̶̶̶ͷθϹϹθθϹθͷ̶˵˵˵̶ͷθкѻѻкθͷ˹˹̺ͻμϽϽоμμμϽϽооонϼλͺͺͺλλͺͺλϼϼнѾѾоϽμͻͻμϽоооϽϽμμͻͻʷʷʷʷ˸˸˸˸ɶʷ˸˸ͺͺλϼͺͺ̹̹̹̹˸˸ȵɶʷ˸˸˸˸ʷȵǱưííĮůưưǱǱɳɳɳɳɳȲȲȲɳɳʴʴɳȲǱǱƳǴǴȵȵȵɶɶ˸ʷʷɶɶɶɶʷȵɶʷ˸˸˸ʷɶʷɶɶʷ̹ͺ̹ʷ̼ͼλϻϼϷʳǬǼp}ZrO|lHyiEwhAp`<rd?xhD}oJvR]iqopqokihhayWsQ}\\tŧưǱȲʴʲʲɱȰȮȮǭƬǪȫɬɬȬȬǫǫȬɭʮ˯ɭɭɭɭɭɭɭɭǪƩæ¦çĪƬȮɯɲȱƯƪɩcwJqC{JOUbjmquz|ɼÙĝÞŠƣǦǨȫɬȮȮȯɮˮŨdqa@hU5oZ;vaBlȷ¨͵ͷʵλѾϼ̻ͺͼϼͼͺʹ̹̻ͺʹʷʹ̹˶˶˶˶˶˶ʵʵ͸͸͸ιιϺϺϺʴɳȲɳ˵̶˵ʴȲȲɳɳɳɳȲǲűƲǴȵɳɳȯǮǬŪúģȦʫάέͩʦȤ¡áæħƭ˱̶ϸͲˮʫť¼·Ȩ̮Ͱʰɱ̶͹̸ʴʳ̵ͶͶ̵ʳɲʵ̷ιηͳʮɭɬˮ̯ͱ̲ɲǰǲȵǷʺ˻ȸóĲǵͺͺ̹ʵʷʴɶʴͶεϵ̲ʰȮɯ˱ͳ̲ʰɯɯʰ˲ͳδδͳ˱ʰɯȮǭͳ̲˱ʰɯʰ˱˱ʵ̷ͺ̹ʷɶʷ˸ϼͺ̷̷ʵȱŮūǪͭͰʭʭͰʯŪ©«ƯɱɳǱ˸ʷʷ˸ͺλ̺ɸǴǱéʼ~{Ⱦƪ̯˰ɰȱȳʶ̸̹ʴɲʳ˴̵Ͷϸйϸ˴ȱʳͶηʳǭŪǾt`zV{W[`t¥ϵѺɴƾ~dujLaV8YN.bW7oeBxW~]m}ŻǱͷïİƲȴȴǳƯŮëëª¨êĩƫǬȲɶʷȵŲǿǿßɻ¦§¦ħĨɻzk~cz_u[rXtZu[y^eqõƿêƭʱ˲˲ɰȭȯɰ˲˵˵ʶȴǱĮëŹyg[YY_jwŮɳ̶θͷ̶̶ͷ̶ͷͷθθͷͷ̶θͷͷͷͷθϹкϹθͷ̶̶ͷϹкккккϹθͷ̶ʴ˵ͷθϹкккϹθ̶˵ʴʴʴʴͷθкѻѻкθͷͻͻͻμϽϽооμμμϽϽооонϼλͺͺͺͺλͺͺλϼϼнѾѾоϽμͻͻμϽоμμμμͻͻͻͻɶɶɶʷʷ˸˸˸ʷ˸˸̹̹ͺͺλͺͺͺ̹̹˸˸˸ȵɶʷ˸˸˸˸ʷʷǱư¬íĮĮůưǱǱɳɳɳɳɳɳɳɳɳʴʴʴʴɳȲǱŲƳȵɶ˸˸˸˸˸˸˸˸˸˸˸˸Ǵȵʷ˸̹̹˸ʷʷʷɶ˸ͺͺ̹˷̹˺˸̸ͺζʴɮũoxUzjHxhD{iE|jFsQxV^fmu}|xvv_rNueC~nLi̾ƨǱȲɳ˵˳ʲɱɱɯȮȮǭȫɬɬʭɭɭɭȬȬɭʮʮȬɭɭʮʮɭɭȬǪŨæçĨƬǭȮɯɲȱǰȮ˫ßùp[[ilrz}ĸɢ̥ʦȥʧ˫˭˯˱˳ʲʴɳȰȭ¥csbDo\\<zgGqSĳǰкͺȶ˸ͼ˺ɸɸʹʹʹɸʹ̻ͼͼ˺˺̻ϼ̹˶˶ʵʵ˶˶̷˶˶˶̷̷͸͸ιʴɳȲɳ˵̶˵ʴȲɳɳʴʴʴɳȳűŲǴȵʴʴʱɰŪǬȫŨ¢ţʨ̬̬˫ʪʪɧɧɧǧǪǫȮȱɴʷʷε˯ǬƩħħʭѷѶͳǯǳ˷ͺ˷Ȳɲ̵ͶͶ˴ȱƯʵ̵ϸжͱʭɬȫɬˮ̰˯ȮƯŰűǱʴ˵Ȳ¬íưͶ̵˴ʳʲɱɱɯʱ˲˱ɯǭǭȯ̲ʹͳʱɯʰ˱̳εͳͳ̲ʰɯȮǭƬ̲˱ɯȮȮɯʰ˱ʰ̲̲̲ʰɯʰ˱δ˱ɯɯǭéťɧǦâżƽĻĽ¦ĨĨ¨˵ɶɶ˸ͺ̺ʹȵį˻qfadfhnyˮˮȰưȳɵ˹̹ʴɲʳ̵Ͷηϸϸϸ˴ȱʳηηʳƭ¤ŸiyU{qMuQ{W~[rħ̰δʳůȽqxZpeEk`@wmJ~[jmu}ǼűƲȴɵȴưŮìë¨èĩƩǬʴʷ˸ʷƳíĺtijnsr{õè¦æ¦Ǹnx]sXpVkRgNnUlSlRqV{`pèƫɰʱʱȯȯɰ˲ͷϹϻ͹ʶǲƮūϿõrb~X|UWan~ȿǧǰʴͷͷͷ̶ͷϹ̶ͷͷθθͷͷ̶θθͷͷͷθϹкϹθͷ̶̶θϹкѻѻѻкϹθͷ̶ɳʴ̶θкѻѻѻϹθ̶ʴɳɳɳʴͷθкѻѻкθͷμμϽϽϽоооμμμϽϽоооннλͺͺͺͺͺͺͺλϼϼнѾѾѿоμͻͻμоѿͻͻͻͻͻ̺̺̺ɶɶɶʷʷ˸˸˸˸˸˸̹̹ͺͺͺͺͺͺ̹̹˸˸˸ȵɶʷ˸˸˸˸ʷ˸ǱǱůưưǱǱȲȲɳǱǱǱȲȲɳɳɳɳɳɳɳɳɳɳɳɶɶʷ˸˸˸ʷʷʷ˸˸̹̹˸˸ʷȵȵɶʷʷ˸̹̹̹ʷʷ˸ͺλͺ͹ɶʷʷ˷ʷ̴ʴ̱ƪ}f{YzV~Z_mzôŶɺ;οɺj}YpNrPgʼɫȲɳʴ˵˳˳˳ʲʰʰɯȮʭˮͰαȬȬɭɭȬȬǫƪȬɭ˯̰̰˯ɭȬɬȫƩħ¥ūƬȮʰʳʳʳʰ̯ǨȽ~ƶȹ˻ξ ˧̧̩̩̬̮ͯͰδζ̶ʷʷʸʸʷ̲οbxgItcEsUeͼȯ̵̶˸ʸƶ˺ʹɸȷ˺ͼʹƵǶɸͼϾпν˺ʷ̹˶ʵɴʵ˶͸ι͸͸̷˶ʵɴȳȳȲɳʴ˵˵˵ʴʴɳɳɳʴʴ˵˵ʵűŲŲƳưưƭŬȬǫǪɫɩ˫ͪΫʪɬȫǧĤãťƦǪƩƪǭȳɶɶɶɵʳȲʱʲ̲δжʹȱĭư˷ϼϾ̹ʴʳ̵̵˴ʳ˴˴ůͷθɰƫʭ̯ʫʫȩŨŪǮȯĮêĪȭͱ˯Ĩ¥ŨŨŨǪɬɬƩħȭȭǬŪèĩūɮͳɮƬȭɮȭǬǬũƪȬɭȬǫĨçũƪžĨũĥǨɪɪȧȧȧǦб̭Ƨƽúļûºº¹ȿ¥éįǳ˷͹˸ʷȵİòfwVrNqM|iIxgI{jLvWetĤɫͳ˵ű¯ƵʺȲǰȱʳͶϸһӼййͶȱȱ̵˴ƫʽj}WuO}qK}sOwS\\{żǪɮεͷȯ¨Ǽj_bmtuuvvzİȴʴưůǱȱǭéſæƩȫɮǱȵǲįįƱƻxd}XwTuS|[em{ǼèĨ¨³huWoRoSnSmRlQgL~fJ~iLnPvXkȫƬūǭȰƮ˵ʴɳɳʷ˸ɶȳƬħɸmb^Y}W`pƾģȨɲ˵̶ͷθϹϹϹͷͷͷͷͷͷͷͷͷͷͷͷͷͷͷͷ̶ͷθϹϹϹϹθϹϹϹθθͷͷͷ̶ͷͷθθϹϹкθͷ̶ʴʴɳɳʴϹϹкѻкϹͷ̶ооϽϽϽϽϽμϽϽϽϽϽϽϽϽннϼλͺͺ̹˸ϼλλнҿѾϼѿоϽϽϽϽѿѿооμ̺˹ʸȵȵɶɶʷ˸̹̹̹̹˸˸˸̹ͺͺ̹ͺͺͺͺ̹˸ʷɶɶɶʷ˸̹ͺλʷǱǱưưǱǱǱǱȲȲǱǱȲȲȲɳɳɳɳɳɳɳɳɳɳɳɶʷʷ˸˸˸ʷɶʷ˸˸̹̹˸˸ʷȵȵɶʷʷ˸̹̹̹˸ʷ˸ͺλλ̹˸˸ʷʶʴ˵˴̳ɯ~~´̼¨ūŬƬŬū˽ǷĴxmn{ɾŧȲɳʴ˵˳˳˳ʲʰɯȮȮɬˮ̯ͰɭɭʮʮɭȬǫǫɭɭ˯˯˯˯ɭɭȫǪŨæ¥¨ĪƬɯɲʳʳʰȭȫæźǸο£äĥŦŨŨŨƨʬ̭̭ͯͲϳ϶϶ͷι̹̻˻;ͿμȰοt`~_n}Ǹ˱̶˸̺ʺǷͼ̹ʹʷ˺λʹȵǶɶ˺λͼλ̷̻̹˶˶˶˶˶̷̷͸͸͸͸̷˶˶ʵʴ˵˵˵˵˵ʴɳɳɳɳʴʴ˵˵ʵǳƳƳǴȲɳʱʱɭɭɫɫʪʪ̩̬ˮˮʭȫƦĤťǧɬǪƪǭǲȳɶɶ˷̷˵˵̴ζϷѹͶɱưǱ̸ннλȲɲ˴̵̵˴˴̵ư̳ʱ§żƽǾƽ¹¹ż¥ŪêĺýľſǾǽǽĺ¶´¸ĺƼüĽžƿžü»ƿƿüüŽğŠĝƾûº~~¸ʿǱ˵̶ɶȳɹt}\\nM|jF}kGyfFwdFwfH~nMwVct¹¢ɯʲŲðĴȸȲȱɲʳ̵ηйѺйй̵ɲʳ˴ǰɿs\\qLxjEwkE}sO|Yg£ˮʹзͷȯ˱ʮĨ~h^a_]~[{[y\\~cs÷ǱȯưȯȮƬéħǪȫȮŰƱŰįŰůɾ~n_yTsQsQyXbs¦ƫŨfrTkNjNkOkOmRjNgK}hK|iKnP|^m¦ǭʰɱɴɳȳʴ˶˵ȵůɸwd|Y{X\\ak{Ǩʭʲ˵̶ͷθϹϹϹͷͷͷͷͷͷͷͷ̶̶̶ͷͷͷͷͷ̶ͷθθϹϹθθϹϹϹθθͷͷͷͷͷθθθθϹϹͷͷ̶˵˵˵˵̶Ϲккѻкθͷ̶μϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽннϼϼλͺ̹̹ϼλλнҿҿѾϼѿѿооϽϽоооооϽμ̺˹ʸȵȵɶʷ˸˸̹̹ͺ̹̹˸˸̹̹ͺ̹ͺͺͺͺ̹˸ʷʷʷʷʷ˸̹ͺλ˸ǱǱȲȲǱǱǱǱưưǱȲȲȲɳɳɳɳɳɳɳɳɳʴʴʴʷʷ˸˸˸˸ʷɶʷʷ˸˸˸˸ʷʷȵȵɶʷʷ˸̹̹ͺ̹˸̹λϼλ̹κ͹ʶɵɳʴʳͳȯĪ˽˽;̽˽îǴ̹̹ɶƳƳǴɶɶɶɶǴŲıìʼƷµƻħȲɳʴ˵˳˳˳ʲɯɯȮȮɬʭˮ̯ʮʮ˯˯ʮʮɭȬɭʮʮ˯˯ʮʮɭǪƩŨæ¥¥¦¦¨ūǭȱɲɲɲȮɭɭƫèéȮͳ˱˱ɯȮǭƬƬƬʯ˯˲ͳͶϷιϺͺͻ̻;;ѾǯèƸĶɭ̲˵˷λͼ˺ϼ̷˸˶̷̹˸ʵɶɴʷʵʷʵʷʵ˶˴˴̵˴˴ʳʳ˴̵̵ͶͶ̵̵˴̶ͷͷͷ̶˵ʴɳɳɳɳʴʴ˵˵ʵǳǳǳǳȲʴʹδ̰˯˭ʬʪʪ˨˫̯ͱ̯ɬǧĤĢţȨŨħçĪŮɴ̶κ͹ͷͷθϹкѻθʴȲɳͷѽѽмȲȱʳ̵ͶͶ̵̵ƮǯǼ¦ƺ~romigglq{xuvxz~{wrstw|~zupnikl}ɽŮɲȳǰͽójtSwgEtd@vfDveGudFudFxhGzkJtQapȮǲųŵƶȳȱɲʳ̵Ͷηϸη̵ɲǰʳɲƾvcsOtd@n`=reBwTc}ɬϳ϶ϹͷȲ˲γϴŨiuRxnK{nKwjGuhEteDteFyjMz]n©ȭɰɰȮūĪ¨ĩǬȭǭĭí¬¬ůĬĸrd|WuPrPtR|[fʼǬǭé©iqV~jOjOlQmRpVnSlQ~jO{gLyhLnRyYixƽĨƭƯűƱƲȳȴǰ®˿Ǹwi~YsNxU`o{úƦʭϲ˳˵ͷθϹϹϹθ̶̶̶ͷͷͷͷͷ̶̶̶̶̶̶̶̶̶̶ͷθϹϹθθϹϹθθθθͷͷϹϹθθθθͷͷͷ̶̶̶̶ͷθϹккккϹθ̶˵ͻͻμμϽоооϽϽϽϽϽϽϽϽннϼϼλͺͺͺнϼλнҿҿѾϼϽϽооооѿѿоооϽμͻ˹ʸɶɶʷʷ˸̹ͺͺͺͺ̹˸˸̹̹ͺ̹ͺͺͺͺ̹˸ʷʷʷʷʷ˸̹ͺλͺǱǱɳȲȲǱǱưưůȲȲȲɳɳɳʴʴɳɳɳʴʴʴʴ˵˸˸̹̹˸˸ʷɶɶʷ˸˸˸˸ʷɶȵȵɶʷʷ˸̹̹ͺ̹˸̹ͺλͺ̹мκ˷ȴǱɳʵ̵ƯůƭȯȮȮūªȴ˹ͻ̺ʸɷʸ̺̺˹ʸɷɷɷɷɳéĦĦåææŨƩȲɳʴ˵˳˳˳ʲɯɯȮȮɬʭʭʭ˯˯̰̰̰˯ʮɭʮʮʮʮʮʮʮʮȫǪƩŨħħĨũéĪƬȮȱɲȱǰǭɭ̲̲˱ʱ̳ε˲ɱǯŭĬĭŮǮʱʱʳ˴˶̷̷˸ͺͺ̻̻̽;ολɰȭŨʿøøɾƧʭ̱̳ʳ̷нп̻͸ɴƱǲȳǲɴ̷˶ʵɴȳȳȳȳȱʳ˴̵̵̵ʳȱǰȱɲʳ˴̵˴˴ʳθθθͷ̶˵ʴɳɳɳɳʴʴ˵˵˵ǲƱűǲǱʳͳδ̰˯˭ʬɩȨɦɩʭ̰̯ɬƦſľý¼»ǭ˴ͷͷͷͷθϹϹкͷ˵ʴ˵θѻҼѻȱɲ˴ͶϸϸͶ˴Ʈ·zqqroxĹʿ|fyVxPtN}qK}qKxR_gw~nz`sYnTrXv\\z_guxqqqphca_djrxº¼}sh^yWuTdnɻ«ĭŮõjtSxjGvhExjGziKyhLxgIxhGvhEykFySav·ĩǱǵŷŵȳɲʳ˴˴̵̵̵ɲȱŮŮȱĭh|WlIsa=m];tgE\\r̰δ̶ͷͷʴůȯɰɿatjGj`=tgDqdAqc@qc@rcBvgFsRatúŪȭɮȮūūé¨ƫȭȯǯĭ¬ëgZuPqLsQ{Zivõ¨ǮĪĩĹs~avZuZw\\y^z_z_x]vZpT{lO{lO{nN~[fyƽʾ¯ůůƺ´qb[yT~rL{XkżŨǫȫ̲ж̶̶ͷθϹϹϹθ˵̶̶̶̶ͷͷͷ̶̶̶̶̶˵˵˵˵̶ͷθθθθͷθθθθθθθθкϹϹθθͷͷ̶̶̶̶ͷθϹкѻкккϹθͷ̶̶̺̺ͻμϽооѿϽϽϽϽϽϽϽϽнннϼϼλλͺнϼϼнҿҿнλμμϽоѿѿѿѿоооϽμͻ̺˹ʷʷʷ˸̹ͺͺλλͺ̹˸˸˸̹̹̹ͺͺͺͺ̹˸ʷ˸˸˸˸˸̹ͺλλǱǱɳȲȲǱǱưưůȲȲɳɳɳʴʴʴɳɳɳʴʴ˵˵̶̹̹̹̹̹˸ʷɶɶɶʷ˸˸ʷɶɶȵȵɶʷʷ˸̹̹ͺ̹˸˸̹ͺ̹ʷкθ˵ȲǱɳ˵ͷ˵ɴɴ˶͸̷ʵǲʷ˸˸˸˸̹λнλͺ˸ʷɶȵɶʴǭɭʮɭǫƪǫʭȲɳʴ˵˳˳˳ʲɯɯɯɯʭʭʭɬ̰̰̰̰̰˯ʮɭʮʮʮʮʮʮʮʮɬɬȫǪƩƩƪƪǭȮɯʰɲɲǰǭǪɫˮͰͰ˯˱̲ɯǮƭŬƭƮȮʱʲ˲˲̳˵˵˵˷κκ̸˷ʶɵɵɳǬɭʮɬǨǨȩ̬̯̰˱ɱͷѾо̺Ʊǿûļļļɲʳ˴˴̵̵̵̵̵ȱʰʰʰɯǭūĪĪƬɯ˱ͳͳ̲˴θθθͷ̶˵ʴɳɳɳɳʴʴ˵˵˵ʴɳȳɳȱɱʰʰȬǫƩħĤĤĢĤħƫȫƩȬʲ˳˳̴͵͵϶϶϶ε̴͵Ϸиии˴˴̵ηйй̵ȱ˿÷}kbdgkvźǼn|qUuhFse@na>na>uhEwTfrĻȿż¹¹úĻĻ·zbziMn]AmY>p_CsdGwiLxZpoc\\[YVWZciu~·ǼæƧȫɩƦãýs~bnSyfH}nOxXi{ĶͿĪéźubyVvRvTqT~nT}nO{lKxjGvhC}qK{UfuƻëŲƶƶƲȱɲʳ˴˴ʳʳǰƯŮŮŮŽz~]uP~jGvd@scA|oMhæȬ˱ɲǱʶ˸˸ʶȴí~{]sfFk^<qc@pb=qc>ugBwgCxhDoMyVbxƽħɬȬũūĪëĬǮɰǱƮĮªʾȼ˽ŷw\\yQ|nI}oJxUcwĶȼê«ëǮ¦xrrtvxywpgy]|qUwlLyRXi{Ƹȼ˼˿Ĭǻu^|S{QxQwTcyū˱ʲȲ˵ϹͷͷθϹϹϹϹθʴ˵˵̶̶ͷͷͷͷͷͷ̶̶˵˵˵˵̶ͷͷθθͷͷθθθθθθθθкϹϹθθͷͷ̶̶̶̶ͷθкѻҼϹϹθθͷͷͷͷ˹̺̺ͻμϽооϽϽϽϽϽϽϽϽнннϼϼϼϼλѾнϼнҿҿнλͻμоѿѿѿѿоϽϽϽϽμͻ̺˹ʷ˸˸̹ͺλλλλͺ̹˸˸˸˸˸̹ͺͺͺͺ̹˸ʷ̹̹˸˸̹̹ͺλϼǱǱȲȲǱǱǱǱưưɳɳɳɳʴʴʴ˵ɳɳʴʴ˵̶̶̶ͺͺͺͺ̹˸ʷɶɶɶʷʷʷʷɶɶȵȵɶʷʷ˸̹̹̹˸ɶʷ˸˸ʷȵθͷʴɳɳʴʷ̹ʷɵȶʷͺλͺ̹ʶ˴ʵʳʵ˴̷ͶҽѺϺͶ˶ʳʵɲ̳̳̳˲ɰȭȰʯȲɳʴ˵˳˳˳ʲʰʰ˱˱̯ˮʭɬ˯̰̰̰̰˯ʮɭ˯ʮʮɭɭʮʮ˯ˮʭȫǪƩƩƪƪǭȮʰ˱ʳɲȱȮǩȨʪͬͯϰαα̯˯ʮʮȭɮȮʯǭǭǰȱʳ˴̵̵ηͶ˴ɲȱǰƯǭĩǪɬˮͭήήή̯ͯɯɰ̹н̼Ĳ«ȱʳͶййη̵˱ƿƿžĽüüƬ˱ͳδδ̴ͷͷͷ̶˵ʴɳɳɳɳʴʴ˵˵˵ͷ̶̶ʴȰƮĪ¨ƿžĽ»úǽ¥~xqopotǾƬǯɱ˳̴͵εε϶϶ζδδϲϲδη̵̵ηϸͶǰoa~[bkvɾø~dshLo`Al]<i\\:m`>{nNd{Ǽ¤ɬ̯ɮƫŪƩƧƧ|{_t`EeQ6fR7jV;kZ>qbEwZxǾǾǾȿȿȿĻn\\~tP}tMwNyPV`s|øǼŭƮƮȲ̳ϵϵ̲ˮū§ȼlnWvbIsbDvgFqPavŷ¨Ƚ{rklh}cz]wVrOzlGxlD{oG}Wcxŵ̽óİǰɲʳ˴ʳɲɲǰȱǰĭǿkrQlHhF|iHoN~^x˯ʰȱǰƲȴɸʹϽɷ{z\\tgGna>n`;m_8pb;ug@whAvg@zkDqL{Xj}úħǪĨƬūĬŭǱȲǱưīǻ}k|TtL|nIuR`rȼɿſ½ĮȰƬȿ|o~a|sRwOyOZjzŷȹʻο̾~`~QvIyMWctɱͷ˷ɶ˸ιθθϹϹϹϹθθʴʴʴ˵̶̶ͷͷϹϹθͷͷ̶̶˵˵˵̶ͷͷͷͷͷͷͷθθθθϹϹϹϹθθθθͷͷ̶̶̶ͷθϹѻѻͷͷ̶̶ͷθϹϹ̺̺̺ͻμμϽϽϽϽϽϽϽϽϽϽнннннϼϼϼѾнϼнѾѾϼͺμϽоѿоϽμϽϽϽϽμͻ̺˸˸̹ͺλλϼϼϼλͺ̹˸˸˸˸̹ͺͺͺͺ̹˸ʷͺͺ̹̹̹̹ͺλϼǱǱưưǱǱǱǱȲȲɳɳɳʴʴʴ˵˵ɳɳʴʴ˵̶ͷͷͺͺͺͺ̹˸ʷɶȵɶɶʷʷɶɶȵȵȵɶʷʷ˸̹̹˸ʷȵȵɶɶȵƳ˵˵ʴʴʶ˷̹ͺɶȵƶȷ˺ͼ;ͻ˶˱ʲʰʲʰʲɯҺҸѹϵ͵̲ʲɱ̵̵˴˴˴˲ɳʱȲɳʴ˵˳˳˳ʲ˱̲ͳͳͰ̯ˮʭ˯˯˯˯˯ʮɭɭ˯˯ɭɭɭɭ˯˯ʭɬǪƩħæççéūǭɯʳʳɲʮ̬ͧ˨̨ͬϭϰϰίͯ˭ɫƩæȿŹƺɽĬǯɯʰ̲˱˯ʮɭȬȬȬɬǬɬˮήаϯϮϰͯɮȯ̸͹ó|}}Ȯ˱ϵжͳƬĽ»çɭ̰ͳʲ˵˵˵˵˵ʴɳɳɳɳʴʴ˵˵˵̶̶˵ȲŬÿźĹ~nc^[\\Z^kèƬȮ˱ͳδζζδϵϵгͱ̯ˮ˯ж̵ʳ˴̵ȱ}qg_^kyyy]peIo`Cl]>k\\?sdGwZu˽ʰʰ˲˲ʴ˵̶ʹͮͬƦķ|{]r_AcN1gR5iV8hW9o`A|\\ƽħħŨƩǪȫʭˮɬˮˮƩæƽnyYujJvlI{qMwP[hź¨ªĮŲŵƵǷ˹λλ̹ʴƳǳƳ;ue|fQq^@o_=pb?zkJ~_{ç¥ȿ¼xncyS|nGxkA}oHxSex²̹οíŮȱʳ˴˴ʳɲƯȱƯƾoqW|eE}c@hFsR`rĻ˱ȱǰɴʸʸȷȷɹƶh|oOtgDtfArd=te>xi@{iAzh@}kCrKwS^k|Ǿæ¦ǭƬŭƮȲɵȴư©ʿĶ~n`zTwQxUaqǹɽȾƾ­İƱƮƫ¦ƿƼŻǻʼʼ˻ʾs`}UxLxNYhuóǷȸó|k|QzKyLScvūʴ̸̹˺˺˸κϹϹккϹθθɳɳʴ˵̶̶ͷͷѻккϹθͷ̶̶ʴ˵̶ͷͷͷͷ̶ͷͷͷθθϹϹϹͷͷθθθθϹϹͷ̶̶̶ͷθϹк˵˵˵˵̶θкҼͻͻͻͻͻͻͻμϽϽϽϽϽϽϽϽннннннннҿнннѾѾϼͺμоѿѿϽͻμμϽϽϽμͻ̺̹̹ͺͺλϼннϼλͺ̹˸ʷʷ˸̹ͺͺͺͺ̹˸ʷλͺͺ̹̹̹ͺλλǱǱůưưǱǱȲȲɳɳɳɳʴʴ˵˵˵ɳɳʴ˵̶̶ͷͺϼϼϼλ̺˹ʸɶȵɶɶʷʷɴɶȳȳɳʴ˵˵̶ͷͷ˵ʴȲȲɵɳȴƲɵʶʶ˷̷͸̹ͺͺ̹˸̹ͼνͼ͹Ϸδδδϵжϵδϵϳϵβͱ˯ɭȮʲȳȳ˳ζη̵ʱȲɳʴ˵˵˵˵ʴ̴εζϴͳͲʰʭʮʭˮˮˮʮɭȬ̰˯ɭȮȮɯ˱̰ɭȫƩħ£ȿèǭɲʳ̴̲ӲЭͫ˩˩ˬ̭̭̮˭ȨťǾ²Ƹ˽§ƫȭ˰̰˯ʮʮʮ˯˯δ̲ʯˮͰϱί̭вΰʮʮ̳˲þslmnrʰͳϵͱĩzxurpoppx~Ļæȫɮǰȳʴ˵ʷʷʶʶɵɵȵɶʴ˵ʵ˳ȮɬȮŨĿõvcX{S{RwOvMxP]räĩȬ˱δϷϷϹϷижϵ̰ʮɬɮϸ̷ɲɲɲīĺzpf`_ctȽƦ¤wu[pdJoaGl^Cl^DvhN~d÷ȰζɳĮ¬İȴ̸θγίȪŷ{_r^CbN3gS8iU:gV:o`Cb¥ǪƫǬɭ˯ͱϳд̰ϳγˮǪjsVreEtgG{nLuR_m·¦ȭǮï®ñŵŵƸʹ̻̻ʸȵƳʸͼɶȷnmXq^@k[9iY7n_>rSrɿĩƪɭ̰ͯʬťƿ©xcvPymEtf?|nIzXi{Ŵ˻ĭǰʳ˴̴˵ʲĬƮĪuvYn`Cr_>w`>~jG{Yo·ǬȮƯǲ̷κ͹ɵƴųƴǳīx}]rP~rL{mFzlE|oE~oF~oFsJzPwN}V`n¹¢ȫƬǮǱɵɶȵưʽ{pd|Y|Y}Yapŷ˿ǽĽľǲȳǱĬ©¨éūǭǮƮƮʾĬŬƿs`{RtLxR~[dsl~]xQ}PV^qǾħǭȰʴ˷̹̹˺ʷϻϹкккϹθθȲɳʴʴ˵̶ͷͷҼѻѻкϹθͷͷʴ˵̶ͷͷͷͷ̶ͷͷͷθθϹϹϹ̶ͷͷθθϹϹкͷ̶̶̶̶ͷθϹʴʴʴʴ̶Ϲѻҿλͻͻͻͻͻ̺̺ϽϽϽϽϽϽϽϽннннннннҿѾннѾѾϼͺϽооμ̺μμϽϽϽμͻͻ̹̹ͺλϼϼннϼλͺ̹˸ʷʷʷ̹ͺͺͺͺ̹˸ʷλλͺ̹̹̹ͺͺͺȵȵƳǴǴŲııƳɶʷɶɶȵȵɶɶʷǴǴȵɶɶʷ˸̹ʹ;;ɺƶǷǷĲıŲȳɵȴůűǱɰδϵʰȮʰ̴˳˲ʱɰȯǰȯʲ˳̷ϽӾӾκʶɴʵʵʵʴ̶ϹϹθ̶ɰʱ˲̳̳̳̱̱˱ʭʰˮȫæĨʯȰ˵Ϸиζ˱ɯȬʱ̳ͷη˵˶˷͸ɵɴȲ˴˵̳ɰǬŨǨɫˬɫɬʭʯ˯˱ʰǰǯȰ̴ϷɯĨżĶ§ɯʲʴ̵ʹͱ̰ͱγγ˱ɯɮŨź~xwy}ʻħɮ˯ʯɯʰ˳̴̴ɳ̵ʲʱ˳ʹͶ̴˲βѵгͮʩ¢|kb`dkx˳̲̰Ǫƻxmkhfcceikljq|Ϳʯ̴˵ʵʷ˹λϾп̻ν˸Ĳıʵ˵ʯȨɿ¸Ƹɼʻ~l]~X{V|VzSyQxQYfsǪβͳʳ˸ͺѾͺͺѼθȲǮ˲ɷɷɵɳȯȽylayY}]gw·¦¨˿nznXk`JmbLtiSxbyȽɳϹι̷˶˶̷ιϺʳ̳˲ȼy`p`FiX>cR8dT:bR9rdJuƼĪǭɯ˱̴̴̶̲ͷиϷ̲ʯˮitWxiJufIteHrcFvYxȾɿūŮǲǲǴȵȵɷɶɶȵǴȲʵȳʶǱǻ~pWp]?lY8hX7iZ;qbEv[ĺĭɱɱƮƬʰ˱ɯĬü~g|X}pMxjE}mI|Xahw´Ƚî­Ǳθ̸Į˲ƫp^vP{oIoc=ylI}ZoĻèĪĭŮǰǰǰŮĭ¬íĬūø{pfdfhlg^WvKzO}T]pþ̳ηƱİɷ˹Ůʿ~md^~Z|X{[fxĻü»¼ſªƭǮǮǮůưǱȲȲǲǲƱǲį­¬vf{Y~vRtRwV^frwzsf}\\|[^~^en{üƪȮ̲˳˳˵˵̸͹κͷͷ̶̶̶˵˵˵ʴʴʴʴʴʴʴʴʴ˵θϹкϹͷ̶ưưǱȲʴ˵̶̶ͺλλλλͺ̹˸ʷʷ˸̹̹̹˸˸ͺͺͺ̹̹˸˸˸ͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλнҿҿнϼнннϼϼϼλλλͺͺͺͺͺͺ̹̹ͺͺλλϼϼнͺͺ̹̹̹̹˸˸λλλͺ̹˸ʷɶλλͺ̹̹ͺλλ̹ǴȵǴǴǴŲııǴɶʷɶɶȵȵɶɶʷǴǴȵɶɶʷ˸̹ȹ̿ɺȹɹɹƴƳƱǳɳǱííƮŬʯͱʮǫʰ̲˱ʯɮȯǮȮɯ̴̷̱λнι˶ɳȳʲʳʱʱʹ϶еδ̲˳̳ʹʹʹ˰ȮǭȬũ¦Ļü©ǯʲ̲˱ɯȬȬʱ˲ͶͶ˶ʵʷ˸˸˸̷̷̵ʱȯƩŦťťãæŨɭɯɲǰǱǱɳ̴Ƭ|ĹĪȯɲ˶Ͷ̵̵Ͷͷͷʳɯƻwmkipsw³˾ĦȬȭɯʲ˵͹͹̷˴ɱɲɴʷ̷˵ɳεҶгʪŢn\\X\\frū˳˴ʯĨŸsjheb_bcdc``gtĵͿǭʱʴ̶ʸɹ˺ͻ˼ν̼ȵǲ˴ʲȬ̾}~¹ƽȾȾǽǻʼ;̽´m`~Y|W}X}XzSxQ}V_izľȫ˱˴ͺнϾ˺˺λ͹Ȳɰ˵̺˹ʶǮ~ne_]gtƻëëĮíȻs|hjq}­ȳι͸˶ʵʵ̷ιϺɴ˶Ȳźw`o_FfV=`P7cS:bS<qeMyƾĭƯɯʲ˳˵˵͸ιθεɲɭūĹ}}`ziKq`Bq`DtcGvfLd©êĭŮǱȲȲȲ˷˷˷˷ʷɶɳȲȱƯɳǱȾw[p]?kX7hU7fW8jZ@xlRvîȲɳưŮɲʴɲ̴ʱƬéü~o]uRrMxQ|TVcwźŽůθ͹ƯīwbzTsI{oE{sL[mçʰʰŮĭììĪé¨§ũŨʿynX~S}RWetǬ̵Ʊİȶƴ~n`X|U|U{Tfq»ľĩŪŪŬůıŲŲŲııðŲ¯¯Ľqd{YtTqOrQuS[_`ZvStPxV]nyƬδδ̴̴˳˳̶ͷθϹθθͷͷ̶̶̶̶ʴʴʴʴʴʴʴʴ˵̶θϹϹθ̶ʴůưǱȲʴ˵̶ͷͺλλλλͺ̹˸˸˸̹̹̹˸ʷʷͺͺͺ̹̹̹˸˸ͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλнҿҿѾнϼнϼϼϼλλλͺͺͺͺͺͺͺͺͺͺͺλλλλϼϼͺͺ̹̹̹̹˸˸ͺλλͺ̹˸ʷɶͺͺ̹̹̹̹ͺͺ̹ƳǴǴǴǴƳııǴɶʷɶɶȵȵɶɶʷǴǴȵɶɶʷ˸̹Ƕ˼̽ɸȸ˸ɷŲ¯ǿǼȽƺ¶ŶɽȾŬ˱ɯǭȱ˳˳ȯǮǮƭȰɱ˳͵˶̷˶ȳŰŰǲɲưƭǯʰͳϵδαͳͳδδ˱ǭéž©ŬǮȬȬɭɭ˯˲˴ɴȳȵʷ˸ͺϺι˴ȯƭƩŦàɿùĻĨƪȮȮǯƮǯȰéĽzokfko}Ľīǰ˶̵̵ʴ˵ͷͷʳʰź~sihfjkms{Ǽ¦èƬȰʴ˵̸˶ʵɲƲɳʶ˶˵ɳʹα̮ƣýxfYXap»Ưɴɲȯ¨ŷypmhdbgigd}]|\\_jt}Ƚ©Ǳ˵ȵƳŲƳȷ̹λ˷ȳǰªȽxz~ɾèŪǮƭĮé¥Ĥķsg`_aa]Y}WZ]hwĻ§Ǯ˵ϻϼ˸ɶʵʵȱʰͳ˷ɳǮqfabkx·ʿëĬůǱıȻļîǲǲ˶ʵɴɴɴ˶͸ιǲȳů·t]l\\CdT;]M4bR9bS<sgO|ǰǰȮɱʲʴ˵͸͸̶̳ȱǫpqTq`BjY;m\\@sbF{kQmƺŬƭǰȱɳɳɳɳ͹͹͹̸ʷɶȲǱŮìǱǱùcr_AlY8gT6dU6eU;nbHkǱɳưŮɲʴ˴̴˲ȮǭçqbzUwPvMwLVfǿʲȲ|fzWuOuNxPbqƿ˯ϵηǲîǿŽžüƿ¥ƩɬȫŨľƽľȿá¡l_WXZ^lŬĮïıo_wSsOvR|X\\u¹ľīŬŬŬĮıııð¯žĽƿsf|\\oMyfE{dBiEjFiG}fDzfEmLzXd{¨ʰδδ̴̴̴̴ͷϹкѻϹϹθθθͷͷͷʴʴʴʴʴʴʴʴ̶ͷθθθ̶ʴɳůưǱȲʴ̶ͷθͺλλλλͺ̹˸̹ͺͺͺ̹˸ʷɶͺͺͺͺ̹̹̹˸ͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλнѾҿѾнϼϼλλλͺͺͺ̹˸̹̹ͺͺλλϼϼϼλλλλͺͺͺͺͺ̹̹˸˸˸ͺͺͺͺ̹˸ʷɶ̹˸˸ʷʷ˸˸̹̹ƳƳǴȵǴƳıŲǴʷʷɶɶȵȵɶɶʷȵȵȵɶɶʷʷ˸Ƕ˹˺ɶɶʶŲǰǰƯȱ˳˳ƭƭŬŬƯɱ˳͵˶ʵǲŮìĭƯȯī¨¨ĪȮʮ˯˯ʰ̲ͳͳɯħĽ{vpryūǭȮɮɭʮɰɰǰǲǴɶʷ͸Ϻη˲ɭȬȩƥĽũǭǭǭǯȮ¨Ľte\\}Y^ct©ǰ˳ʳʳȲʴ˵̶ɲȮīȽzqlhihgiozƽĨǭȰȲɵʴʴǲƱǱɴʵʴɱ˰ɬťľnc\\`m~¸ǿîƱǲưīȽ|xrsxxsmfb`flqz¶ƯǱůİƱǲ˶κͷƯǽ~xw}µǼƪƬɮ˲˲ʴȲȯǫǩæǼvonpqmga][]iyŻŬ˵ι̷ɴȱȱȮɯ˱Ǯèȿshdgo|źɾ˿ªªĮưǴŲȽȽǿ­ǲ˶͸˶ɴɴȳȳȳɴʵ˶̷ŰƱí}pYiY@aQ8[K2`P7bS<uiQîɲȱȮǯȰʴ̶͸̷̶̳ɲǫǻctfIm\\>hW9l[?raE|lRrȼƭǮȱɲ˵̶̶̶͹͹̸˷ɶǴưů«ǿíưêȾivcEn[:iV8fW8dT:i]C}eƾưɳǱƯɲ˵̵ȰȯƬƬũƿug]}VzQ}U^r¸éý|i{ZvSxU\\ev¢ȬδϸηʵįŽûĽžü¥ħȫʭˮʭȫǪæħŨƩǧ¢pc`}Y}tS|]p~ƾýpawS}mI~nJxTajúǾ¹þĪǮǮǮǮŲŲıı¯ƿžü»üžžüykwUyfEs_<u_:s]8pY7nZ7ubAsQfxħĪǭ˱˱̴̴̴͵θϹѻҼкккϹϹθθθ̶̶̶̶̶̶̶̶θθθͷ̶ʴȲǱůưǱɳ˵ͷθϹͺλλλλͺ̹˸λλλͺ̹˸ɶȵλλͺͺͺ̹̹̹ͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλϼнѾннϼλλͺͺͺ̹̹̹ʷ˸̹̹λλϼннϼϼλλͺͺ̹λλͺ̹̹˸ʷʷͺͺͺͺͺ̹˸ʷ˸ʷʷɶɶʷʷ˸̹ƳƳȵȵȵƳŲŲȵʷʷɶɶȵȵɶɶʷȵȵɶɶɶɶʷ˷ȵ˸˸ɴȴȲ~ph}c|anļƱǲƱǲʴʴůĮíĭŮǰʳ˴ͶʳǰŬīŬŬūéü»ƽǾžçƪɭʮǫ~slifbelw¸¦ƪȬʭǪȫȭǮůůǳɵǳɵ˷˵˲ɮȭȪšƼz{žæǫɬɬɯʭũsd~Z{W}Yas»īǰ̴ȱǮǮɰʴʴȱǭǾyqlmjeben|¹ǾĨȮȰȲȵɶʶȴƲǲȳ˵˳ʲ˱ƨľqd^cl|¸©ŰııŰƲưéͿȺŷyqhedeks¨ǭʱʴ˵ɳ̳͵̲¨ytu~õǫƬɮʱ˲˵̵˶ʵȲɮʭǫ¥Ĺzqid[^hr~ȽǬδδδ̲˱˱˱ʭħżte`dvźʾĮŲƳƵƴȴɴɴ˶͸ι͸̷ȳȳǲȳȳɴʵʵįįy|mVfV=^N5ZJ1_O6aR;uiQøŰ˴ʳȮǯǯʴͷι͸̶̳ʳȬ÷wZm_BiX:fU7kZ>q`D}mSvȼêīǰɲ̶θϹϹ˷˷˷ʶǴŲůĮŽĮêlvcEmZ9jW9gX9dT:fZ@yaŽư˵ɳƯȱʴ̵ʲɱɯɯȬŨ¥ȿzoh^Z[`ju~sdvWuW{[cq~Ʀʭͱжйη̷ǲļüĽü»åŧǩʬˮˮˮˮǪƩƩƩǪƩéum`zqRzqR|_ftwc|YrO{mJrO]p|ħŻ¨éƮȰ˲˲˲ʱǴǴƳŲı¯ƿƿžĽžžžĽx^~kJua>r[9nW5kT2mY6zgF_yħʭȫĪƬɯʰ͵͵̴͵θϹкѻккккϹϹθθθθθθθθθθθθͷ̶ʴɳǱưưưȲɳ˵ͷθϹͺλλλλͺ̹˸λλλλͺ˸ʷɶλλλͺͺͺ̹̹ͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλλϼϼнϼϼλλͺͺͺ̹̹̹ʷ˸̹̹λλϼннϼϼλλͺͺ̹λλͺ̹̹˸ʷʷ̹̹ͺͺͺ̹˸ʷʷʷɶɶɶɶʷʷ̹ƳǴȵɶȵǴŲƳȵʷʷɶɶȵȵɶɶʷɶɶɶɶɶɶɶʶɵ̷̷ʳɳɰſpw]|qUykPykN{^uƳɴƱǲɳʴůĮííĮƯǱȲʹʰȮǭƬƩ¨ƿžĨȬƪ¹vnfda_aeirĹĩȬȫȫȭƫŬĮǳɵǳưưɰ˰ˮȫťŽzuzýŨȫɬɬʭˮȬŨƻwf[|X[duƿƫɰ˴ǮǮǮȯʴʴȱȮ©ȽĹyvojb_dow¹¥ǫɯɱ˵ͷ˶ɴƱǱɳ˳̴˱Ͱrb\\]jzȲʷǴıŲǵȴɱȮǬƪȾüùüżtlc^`ex¸ũͰϵж˱ȮǪ¦{ss~˽ƬȮƮɰɰɳɳʵɴɴȳʰʮȯǫ§ž¸~t`^`epȽƩˮβϲϲгͰȪtg]^iȽåĨĨɽíðŲƵȶ˶ɴǲǲɴ̷͸͸ȳȳȳȳȳȳȳȳįįʿwzkTdT;]M4ZJ1_O6`Q:sgO~·ƱͶ̵ʰǯǯ˵θϺι̶̳ʳǫxqTk]@eT6dS5iX<p_CoUzŷʾ©Ůȱ̶θϹкɵɵɵɵƳŲůĮ«ƾíīls`BjW6hU7gX9bR8aU;t\\Žư̶ʴƯǰɳ˴ʳʲɯǭƬũħĥȽ{od]|Y^ajy}nuYwlPvkMxZjvǾƦ̯ͱϵҸѺη˶ȳĭǿĽüĽž¤ŧȪʭˮ̯˱ūĬëªëĬưǯ¥qz]ynRwlPymSw]kx}ym|buVuRtSxU^l~Ļħ§ɿĽ»Īūǯʲ̳̳̳ʴǴǴǴƳŲðŲŲıı¯žþ~cmLua>s\\:nW5iU2o\\;qPk·ǪȫħĪǭǭ͵͵͵̴ͷθϹϹкккϹϹθθθϹϹϹϹϹϹϹϹͷͷ̶ʴɳȲǱưȲȲɳʴ˵̶ͷθͺλλλλͺ̹˸ͺλλλͺ̹˸ʷϼλλλͺͺͺͺͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλͺλλλϼϼϼнϼλλλͺͺͺ̹˸̹̹ͺͺλλϼϼϼλλλλͺͺϼλλͺ˸ʷʷɶ˸̹̹ͺͺ̹˸˸˸ʷʷɶɶʷʷ˸̹ǴȵȵɶɶǴŲƳȵ˸ʷɶɶȵȵɶɶʷɶɶɶɶɶɶɶʶʶͶ̶̴̳˳i~sWwlNugJtgGvWqƵʷǴǴȵȵııíííĮůƮʰɭɭɭȬħǽzy}Ǫȫæƻ~ujgebaccjw´ʿŨɫɫȫūĬĬǱʴʴưíŭʰˮƩ|ts~ûĢǥɩʪɫȪȪɫʮȫʿyg[|V]ewȭɰ˴ȯǭǯɱʳ˴ʳʰǮǪĦʽƹ÷{ricdkrūƯʳθͷɶǴǱɳ̴ͳͱħtfZ\\ewøĮɵʷƵƵǶǷɷʶʴɱɱŮƮƯʰ̲̯Ȭƨſyl`Z]ioyúǪ̯̯Ǫžzuw~øʾ¨ƮǯůȲȲɴɴɶɶɶɴʳʰȱɯȮǪé¥çĦ¥¤üqkechsľŨɬ̮ΰˬ¢nd^[fvȿȫǪĩĩêíůưƲǳȴɵ˶ȳƱƱȳʵ˶˶ʵʵʵʵɴȳǲƱįîɾvyjScS:\\L3[K2_O6_P9qeM|ƱͶη˱ǯȰͷкѼϺ̶˲ȱƪs|nQj\\?gV8fU7kZ>q`DqW~Ⱥ˿©ĭǰʴ̶ͷͷȴɵɵɵǴƳưưǰ¬ůŬ©ltaCjW6hU7hY:aQ7^R8}qYŽǱθ˵ŮƯȲʳ˴ʲȰĪ££ȿĹwke`zXwV`kc}rTseHn`CwiNgõ¤ɪˮˮʮͳйл͸ȳɴǰ«ĽĽ¤ŦǪɬˮˮʯɮƭůĮ¬¬éütz`ykQqcHtdJ{jPrXv]t[mR}iN|mNuSajxµùĺƼèèĽ¨éƮȰɳɳȲȲǴǴǴƳŲı¯ǴȵȵǴŲƿĿ~c~kJs_>u^>pY9mY8ubByXvżħŨ¥¨ǭɯǭζζ͵̴̶̶̶ͷϹϹϹϹθθθͷθθθθθθθθ̶̶˵ɳȲȲǱǱʴʴʴ˵˵̶̶̶ͺλλλλͺ̹˸̹ͺͺλλͺ̹̹ϼϼλλλͺͺͺͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλλͺͺͺλλϼннϼϼϼλλλͺͺͺͺͺͺͺͺͺͺͺλλλλϼϼϼϼλͺ˸ʷɶɶ˸̹̹ͺͺ̹̹˸˸˸ʷʷʷʷ˸˸̹ȵȵȵɶɶǴƳƳȵ˸ʷɶɶȵȵɶɶʷɶɶɶɶɶɶɶɶʴͶʹεϷδĨ}h}rTynPviItgGuVpǶʹȵǴǴȵŲůĮ¬¬ëĮĭȭȫɬʭɬħĻ~rmovǾǪʭƩɾĹ~rnjebbdgnvǹ¦ɫɫȫƩĪŭȲ˵ͷƮĪʭ˭å}wruĠʨ̪ͭ˫ɫǩƨǩ˯ɬyc}WzT]dx¥ȭɰ˲ʯȮɱ˳̵Ͷ̵˴ȯƫĨ̿˾ʽʾ˾ĸ}rigkpr¹ƿéȮ˴ͷ˷ȴȲʲ̲βα¹ug]Z`n§ƭűǵƵ±ʻʻȸȸȶȴǳǳǱɳ̶Ϸиϵ̲̯ʬwf][]ak|ȿåģʿ}upq{õëƮŭƮǱůȲȲɴʵʷʷʷʷ˵ʲɱʲʲɯǭūɯɬȫǪæ½yohdhnuĻ ǧɩĤo_[[`rŻƩ˰ǬèĩīíůȲɳɵɵʶʶ̷ʵǲǲɴʵʵɴ˶˶˶ʵɴȳƱŰįîɾuxiRcS:\\L3[K2_O6^O8pdL{Űηй̲ǯȰͷѻҽϺ˵ɰǰĨpzlOj\\?kZ<kZ<o^BsbFrXǹȼ©ĭƯȲɳʴʴɵɵʶʶɶȵȲȲ˴ĭĮưǮīlwdFmZ9kX:j[<bR8^R8|pXŽȲϹ̶ŮŮǱɲϸζʲƮ¨ħ¥ȽǼƻ¸~uhxV|lJpOwV}nOl_?m_Bl^A|nSrĶ˱Ͱ̯ȬūȱηιʵŰȳɲĭĽüæǩʫʭ̯ˮɬǬŬɳʴɵǳðþþſƿºptZo_El[?lX=p\\At_Du`Cu]As^AyjKxXn~ŷƻŻù¸ǽèŪéƿëŭưưưůŲŲƳŲŲð¯ŲǴȵǴıĽý¾~b}jIq]<w`@q]<o\\<yhJ`}žħǪȫȫ˱ѷѷͳϷζ͵˳˵ʴʴ˵ϹϹθθθͷͷͷ̶̶̶̶̶̶̶̶̶˵ʴɳȲǱȲȲ˵˵˵˵˵˵˵˵ͺλλλλͺ̹˸̹̹ͺλλλͺͺϼϼϼλλͺͺͺͺͺͺͺͺͺͺͺϼϼϼλλͺͺͺ̹̹˸̹ͺλϼннннϼϼλλλλͺͺͺͺλϼннннϼϼϼλλλͺͺͺͺͺͺ̹̹ͺͺλλϼϼннϼλͺ˸ʷɶȵ˸˸̹ͺͺͺ̹̹̹˸˸ʷʷ˸˸̹̹ȵǴǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵɳεзε˱˱ǫ¦l}oRuhHufGvgHtSiʸ˹ǴȵɶƳ­îì«éìƬ̯ȪŧåĹvqlny»ũũż¹·{wqkcacjryõľãǪȬƬǭʳϸ̵ŮĪȬŨzsrwƾţɧͭͭɫŧĦĦŨŨʿxb{UwO~WbyǬɰ̳ʰ˯̲δͶ̵ʴɳƭƫƩŦãĠßěț~uplkntŻ§Ƭư˶ʴɳ̴δǪżyke_^j}žǭɲű°óǷɻɻǹƶƵǴǴȵƳɵ̸̶̳ʯʯˮͮʩàvib^~^alw¸~umkq{÷ưíĮůíǲǲƱƱƳǴȵȵ˵ʴɳȲȲɰɰʱʱǬĩæťɽ³vngdfisſ~pg`^hx˱˯˱˱ʰȮĭìŮƯǰȱɴʵʵʵ͸̷˶ʵ˶̷ιϺ˶ʵɴǲǲƱƱǲʵƱɾvxiRbR9\\L3\\L3\\L3\\M6rfN~­˴ɲ˱͵ζккѼѼʴʱɲƪoxjMhZ=fU7kZ<kZ>m\\@tZǹ˿êêĭƯʴ˵˵ʴȴȴʶ̸ͺ̹ɳưìŮʴ˵Ǯên{hJq^=iV8dU6bR8fZ@w_ºĮ̶̶ƯìưͶʳ˳ɲȱǭĪ¦ŨäȿƽĹxnoMo_=tdBl\\;n_@gX;l]@sX|˿Ĭɰͱ̰˱ɯȱɴʷ˸Ǵȳǰ»ĽåƩȫʭˮɮǬƭǮɳɳɵȴŲ¼ýľŽƾɾu}mSm\\@dP5iT7oW;nW8sZ<ydEzlOkøżƼƼǽɿ©©ƾýľíůưǱǱȵƳŲŲƳǴŲıɶɶȵǴŲðbzgFubAt`?s_>s`@zkLhĻ¦ŨƩȫˮ̲ϵѷҸζ͵͵̴̶ͷͷθθθθͷͷ̶̶̶̶̶̶˵˵ʴʴʴ˵ʴɳȲɳʴ̶ͷϹͷ˵ʴɳ˵ͷθͺͺͺͺͺͺͺͺͺͺλϼϼϼλλϼϼλͺͺ̹˸˸̹̹̹ͺͺλλλϼλͺ̹̹̹ͺͺͺͺͺλλϼϼнͺͺͺͺͺͺͺͺϼλλͺͺλλϼѾѾѾѾѾѾѾѾннϼλ̹˸ʷɶʷʷ˸̹λϼннѾнϼλ̹˸ʷɶʷʷ˸̹ͺͺͺͺ˸˸˸ʷʷɶɶȵ̹ȵǴǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵɳε϶ʹ̲ͳʮŪprUwjJufGufGrQf˹̹ȵɶɶƱîĭĭĪ¨¦èŪɫƨåȽymmoxüæéĨçƿƽħȿø~jb_afl|ƩȫƪūƬȱ˴ȮĪĨæ¼qpv~ƼĠȤƤɧ̬̬ɫƨŧƨǪǧzc|VwOYe{æȫ˯βͰͱͳδ̵ʳȲǱƭƫƫƧĤġġĝĚƺztpjmuúƿíȱȲǯǭũĻzlccfkyĽ¨ƯǲİĲƶʺ˽ʼɻɻɸɸ˸˸ɶ̸κͷʴɰȯȭˮʫƥtj}\\vVuU{[bjrzoib^eqȼ¬ů¬¬ůů¬ȳȳȳȳɳʴʷ̶˵ʴʴɳɳȲʱʱɰǮĩ§§ħħǥŷ|maZ_eq~vrihgnxƻŧδϵϵδͳ˱ȱǰĭŮƯǰȳɴɴȳ˶ʵɴɴɴʵ̷͸͸̷ʵɴȳȳȳȳɴŰȽtxiRcS:]M4\\L3\\L3[L5qeM}­˴ʳ̲͵ζϹϹллʴɰǰçq{mPl^AiX:kZ<jY=l[?rXƸǮȯȱʳ̶̶˵ʴɵʶ˷͹λͺʴǱɲǰʴʴƭ©o}jLs`?kX:fW8fV<maG~fûíʴ˵ƯìĮǱǰȰǰǰȮǭūũèæ¥£æ£ȿǼŶzsRl\\;m]<eU4iX:j[>o`Cw\\¶íȱͳ̲̲ʳʵʵʷʷȵɴȳ«Ľ»ƿæȫʭ̯ˮȭƫŬŬǱǱǳƲïĽſǿ¬ȾqWn]AcP2gR5nW8nW8sZ;ydEbúɿƽƽǽƼǽ©©ƾľſíưǱȲȲɶǴƳƳǴǴƳıȵȵƳŲðģ`xeDs`?s_>q^>q`B|mPnɬƩƩȫʭ˱ͳδϵζ͵͵̴̶ͷͷθθθθͷͷ̶̶̶̶̶˵˵˵ʴʴʴʴʴɳɳɳʴ̶ͷθͷ˵˵ʴ˵̶ͷ̹ͺͺͺͺͺͺλͺͺλϼϼλλͺϼϼλͺͺ̹˸˸̹̹̹ͺͺλλλϼϼͺ̹̹̹̹̹̹̹ͺͺλλλϼͺͺͺͺͺͺͺͺλλͺͺͺͺλλннннннннѾнϼλͺ̹˸ʷ˸˸̹ͺͺλλϼнϼϼͺ̹˸ʷʷ˸˸̹ͺͺͺ̹̹ͺ̹˸ʷɶɶʷʷͺǴǴǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵɳͷ͵˳ʳͳ˰ȭuvYzlOvgHteFnPdɶʷǴȳȳŮêê§å¤ɼ{qlms}¦ȬʰʯǯūééĪĨǫŨèħæƽ}tjddhs~ú¥ŨŪǮɰƭī§ȿsouƼȤʩǧɩɬɬɬǪǪȪɬȨʿ|f~XwO[h~ùƦɬ̰ϳβαͲ̱˲ɰǱưǮǬƫǨƥƢšŠÜȿúxnlnqxſŬǭƩ|la^fq|ſɬǯưŰűȴʹ̻̼̼˻˻ͼμϽоͺλϹͷɳƮĬĪˮʬȪȨĤzgy[}pP~qQuTyX~[_]}ZxW{YgzƻŬůĮ¬íưƯìììĬŭƮȰɳʴ˵˵ʴʴʴɳɱɱȰƮĪ¨¨ħħ¤ʽöpcZY\\dfffhlr{ȽˮԷηηηηͶ˴ʳɲĭŮƯǰȱȱȱȱɴȳȳȳȳɴʵ˶ι͸̷˶ʵʵʵʵǲŰǼqvgPdT;^N5]M4]M4[L5pdL}­˴˴ͳ͵ζθθιιʴɰƯ¦tqToaDkZ<jY;fU9iX<oUzõéǮȯʳ˴ͷ̶̶˵ʶʶ˷κλͺ˵Ȳ̵ǰǱǱêǽk|iKs`?lY;hY:l\\BxlRrŽ¬ǱɳǰĭîįŮǰȱɯɯɯūĨĨŨǫǪƩĥŨƷwYjY;gV8`O1fU7k\\?qbEz_üŭưȲ˴̵Ͷ͸͸˸ɸȷȵɴǲìƿžŨɬʰ˱ʰǭĪëëƮǯǱưůƿĽ¬íy_q`DbO1eR4lW8kV7r[;xeEnĽ¨žüǽǽȾ©êǿſ¬ůǳȴɵɵʷȵǴǴȵȵǴŲȵǴı¯¬æǦľ}~]ubBp]=jW7jW7kZ<wiLm¨ɯǪǪȫɬɯ˱˱̲͵͵̴̴̶̶ͷͷθθθͷͷ̶̶̶̶˵˵˵ʴʴʴʴʴʴɳɳʴ˵̶̶̶̶̶̶̶̶̶̶̹̹̹ͺͺλλλͺͺλλλλͺͺϼϼλͺͺ̹˸˸̹̹ͺͺͺͺλλнϼλ̹˸˸˸˸̹̹̹̹ͺͺͺͺͺͺͺͺͺͺͺͺͺͺ̹̹̹̹ͺͺϼϼϼϼϼϼϼϼѾѾнϼλͺ̹̹̹̹̹ͺͺͺͺͺλλͺͺ̹̹̹˸̹̹ͺͺͺ̹˸˸λͺ˸ɶɶʷ˸ͺλǴƳǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵʴͷ̶ɱǰʳɰƫvw\\{mPwhKteFnP~cŲɳŰǰȱƬɿ§¥ɾǼƻǼö{roozĽæǭ˱εʹɳɰȯɮɱʰūƩƬǫƪ¥ĺ~skilqs|ȿæŪƭɿȾĻ}vruŢŢƥǨȨǪȫȬɬɬȮʭˮȦɾzfWwO\\hŻǧȫ˯β̰̯˰˰ʱɰȲǱȯȯȭȫǨƥǣƢàġƣƣàĺ|uoilvľæyngacp~Ʀγʱưưɴ˷ʹɸ˺˻˻ͼϽѾҿͺϹϹ̶Ȳůŭŭ̲ʭɬ̯ͰǪzgtW}pPpOpOqOrPvUuSwV^qĹũʹɳůĮǱɳȱĭ««ëĪŭǭʱ˲˵˵˵˵˵ʲʲɱȰǭūé¨éŨũĻɾåƦǤʽp[U{QyRzS}V_j{ɾ¦ƪ̳Ѹ̷˴˴ʳɲȱǰǰƯƯǰȱɲɲɲȱȳȳȳȳɴɴʵʵι͸̷˶ʵʵʵʵƱŰƻkteNdT;`P7^N5]M4\\M6qeM}­˴̵ͳ͵͵ͷ̶̷˶ɳ˲ȱĨyuXpbEjY;fU7bQ5fU9zjPrêǰɲ˵˵˵˵ʶʶʶ̸ͺ̹ʴȲ˴ĭĮĮȾ}avcEo\\;kX:k\\=tdJy_íưɳȱƯȽîįŮǰȱɲʰʰƬƬƬǫɭʮɭǪĩȸz`l[?gV:`O3fW:hY<n`Ez`ľưǳɵ̶̵ιлϼ̹ȷƵƳƱŰéƿ¥Ĩǭɯ˱ʰǭūĬĬȰȰɱɱȰƮŭĬĮĮǿʿǽesdG`O1eR4kX8jU6o[:wfHl»žǽǽȾêêǿíưȴɵʶʶʷɶǴȵɶɶȵƳȵǴı¯Ĭħǧľ{|[taAp]=hU5eT6gX;vhMnĩʯɬɬʭʭʰʰʰʰ͵͵̴˳˵̶ͷͷθθθͷͷ̶̶̶˵˵˵ʴʴʴɳɳʴʴʴʴ˵˵̶̶ʴ˵̶ͷͷͷ̶̶˸˸̹ͺͺλϼϼͺλλλλͺ̹̹λλλͺͺ̹̹̹ͺͺͺͺͺͺͺͺнϼλ̹˸ʷʷʷ̹̹̹̹̹̹̹̹ͺͺͺͺͺͺͺͺͺ̹̹˸˸̹̹ͺλλλλλλλλҿѾѾнϼλͺͺλͺͺ̹̹˸˸˸̹̹̹̹̹̹̹̹ͺͺͺͺ̹˸ʷʷϼͺʷȵȵʷ̹λλƳƳǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵʷ̹˸ǱįƯĮstZ|mPxgKveIoSdĮȲƱȱʰǫæåʿƹzwv|üĪǭɮʲʹ˴̴̷̵Ͷʹͷε˲˰ʲʰɯȫĪȿwogcjrƻɽ˿ƺ÷xpsuʧɩƦŦƧȫȬǫȮɯɯɱȮʭǥȽvc}UyNYhŻťŨȬ̮ʭʫʭɮʱ˲˲̳ʱɰʮɬɩȦȤȦȩȫȫɬȩäƻsgcis}uibehp~Ƨ̯ͱɰǮɱ̵̶ɶŲʷɸ˹̹ͻнѾҾͷ̵̵ʳǰƯƯǰ̵ɯƬɯδ̲Ī»ty\\~oP{kJ{hH{hG|iHkJmLtTczʿǭѸ̶ɰɰ̲̲ɯǭȮȮȮʭ˰Ͱϴе˳˶˴̵˴ʳɲɯǭǭūĨĨĨũƪ¨Ŭȭˮ̫ġp`WxNsJtK|Scwǹƪ˯ɱǯȴʶʷ˵ʴɳɳȲȲȲʴʴ˳̴̴̴˳˳ɴʵʵ˶˶˶˶˶̷˶ʵɴȳȳȳȳƱƱź}fqbKdT;`P7^N5_O6^O8thP­ʳ̵ͳ͵͵̶˵˶ʵɳʹ̵ɭĸ|_rdGkZ<dS5_N2dS7ueKg÷ɿêȱʳʴɳɳʴɵȴȴʶʷʷɳǱ˴ĭĮĮùx}rVmZ<jW6jW9o`AoUnûîĮưȲɲǰ¬ȽįŰƱȳȱɲɲȱɱȮȮɯʰʰȮƬ˿ĵ|em]DhX>_O5dT:bR8i[@x]ÿȱɴ˶̶͸ϼнν˺ȷŴðî­¨¥çĪŮȱȱǰƯƬǭȮȮȮȮȮǭƬƬìį«ǿȽƼiufI`Q2eT6iY8hU5n[;yjKoýŭȰƮɱȾȾȾ¬¬­ǿ¬ðŲȴʶʶ˷ʷɶǴȵɶɶȵƳɶǴı¯¯ðıǯ¥ƦľyzYs`@p]=kZ<iX:k\\?ynRtȯʹ˱̯̯̯˱˱˱˱͵̴˳˳˵˵̶ͷθθθͷͷ̶̶̶˵˵ʴʴʴɳɳɳʴʴ˵˵̶̶̶̶ʴʴ̶ͷͷͷͷ̶̹̹̹ͺͺλλλͺλλλͺ̹˸˸λλͺͺͺͺ̹̹ͺͺͺͺͺͺͺͺϼλͺ˸ʷʷʷʷ̹̹̹̹̹̹̹̹ͺͺͺͺͺͺͺͺͺ̹̹˸˸̹̹ͺλλλλλλλλѾѾннϼλλͺλͺͺ̹˸˸ʷʷ˸˸˸̹̹̹̹ͺͺͺͺͺ̹˸ʷʷλ̹ɶȵȵʷͺϼλƳƳǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵɶ̹˸ƳıįȼpqXzjPwfLveIoSdůɱƯɯɭŨæȽ~|xyxx}¨ɮ̳ʹεϸȳɴ˶͸Ϻϸηηϸεʹ̳˲ɯȮȮƩĦü}od`eq}ɽ¨vjis|ġ˨ʪȨȩʭɭȬȮɯʲʲȰƬǪţźnYzRzOYiƼĤĥŧʬȫȩȫɬɮ˲̳ʹ˲˲˯ʭɬʪɧɧʯɰȯȭȭȫĨǼpfdgkvy|xl_Y[fqþƧ̮дɰȯɰ̳Ͷηɳıȵɵɷʷ˹λϼм˵˴˴ɲǰƯȱɲ˴ǰŮƯʳ̵ȳ¬itW{jLyfFzfE|hGyeD}iHtTiĶū˳з˵ʱ̳ͳʰȮɯȮɬɬɬʭ̯Ͱα˴˶̵ͶͶ˴˱ɯǭǭƪũũƪƪǭîƱǰȮ̯Ǧr^~StIpEsHUm˼§ʰ͵˵ȵȶɷ̹˸˵ʴʴʴʴ˵˵̶͵͵͵͵̴̴ʵ˶̷͸͸͸͸̷˶ʵȳǲƱƱƱƱƱǲźw`m^GcS:_O6_O6`P7aR;xlTø­ɲʳ̴̴̲˵ʴʵʵʴεη˯ɽi{mPp_AfU7aP4gV:rbHv[vɿŬʳ̵˵ȲȲʴɵȴǳȴɶɶȲư˴Ůů¬lvkOiV8iV5o\\>xiJ}c~įůưǱǰƯíƱƱǲȳɲɲȱȱ̴˳ʰʰ˱˱ȮƮʿ|gn^GhX?]M4`P6^P5eY?u\\ȳ˶̸˸͸λϼͼʹǶĳ¦¥ç¨ĭưȱưƯǮȮŬƪĩŨŨħħĨ«ĭì¶iugLbT7gX9hY:bS2l\\;}oRuý¼ªƮĬŭȾȾɿ¬í­¯ŲȴɵʶʶʷȵǴǴȵȵǴŲǴƳŲıııŲǯťývvUp]=o\\<iX:fW8hZ?wkQuƯʱ̱̯̯̯˱˱˱˱̴̴˳˳˵˵̶̶θθθͷͷ̶̶̶ʴʴʴʴɳɳɳȲʴʴ˵̶ͷͷ̶̶ʴʴ˵̶̶ͷθθͺͺͺͺͺͺͺͺͺλλλͺ̹ʷʷͺͺͺͺͺͺͺͺλλͺͺͺͺ̹̹ͺ̹̹˸ʷ˸˸˸ͺͺͺͺ̹̹̹̹ͺͺͺͺͺͺͺͺͺͺ̹̹̹̹ͺͺλλλλλλλλннϼϼλλͺͺͺͺ̹̹˸˸ʷʷ˸˸˸˸˸̹̹̹̹̹ͺͺͺ̹˸˸˸ʷȵǴȵɶ̹ͺͺƳŲǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵǵ˹ʹȵųűȼl~nUwgMveKtcI~mS}cĬǯĪçƽ|snprz|üžſƭɳͶηηɴʵ˶̷͸̷̷̷͸ͶͶ̵ʳȯǮǬʯ̯ȫr~[\\`kyƸxlgm}ùȽĤǧȪǩʭˮʮɯȱɲ̶˵Ǳë¥á·e{QvN{PYjǽĢäĦɫʭȪȬǫȭʯ˲̳̳˲̰ˮʭʪʨʪʱȴǱȲɳʱǭƪåǼtic_``b_yVqLuPXk|Ǩɫ̰ͳɯɰʱʹδδʲɳɳɳɵ˵ʷ̸λϺ˴̳˲ɰůůǱȲȴƲűƲȴɵǵűʾtz]|kMvcCyeDiIxaAyeDpPfõéɱ˲ɰʱε̲ƬƩɬǪƩƩǨȩɪʫɬ˴˵̶ͷε̳ʱɰƫƫƫŪƩǪǪǭñıƮ̰ʫsZ{PsHoDtIYtǳŨŮǰȳɸɹʺʺͺ̹˸ʷɶʷ̶̶˵̶̴͵͵̴̴˳ʵ˶͸ιιι͸̷ʵʵȳǲƱƱƱƱǲɴƻs\\j[DaQ8^N5^N5aQ8dU>|pXźîȱɲʰ˳˳˵ʴʵʵ˵϶Ͷɭ˿w|_yhJn]?hW;m\\@rbHykPf|ȾƯʳʴɳ˵θʶȴȴȴɶɶɳǱ˴ì¬Ĺrx_peIkX:o\\;yfHvWrŹĭ­Įůůĭì¬íŰƱǲȳɴʵ˳ʲ͵̴˳̴εε̳ɳñxem\\HiYB^N5`P7`R8e[@}v\\Ȳ˶͸͹̹ͺͺ˺ɸƷĳ¨éĨħħ¬İǱǱưůŭƭĪƩĨĥ¤ä¤æĪŮƯĪ©gshLcX:j]=h[;_R2k\\=tVw¼¼ý¼ȽȽɾíí­ſ¯ıǳɵɶʷɶǴƳƳǴǴƳıııııııŲƮæǧľrrQkX8kX8bQ3_P1aS8qgLrìƭ˰ˮˮˮʰʰ˱˱̴˳˳ʲʴ˵˵̶θθθͷͷ̶̶̶ʴʴʴɳɳɳȲȲɳʴ̶ͷͷͷ̶̶˵˵ʴʴ˵ͷϹкϼϼλͺͺ̹˸˸λλλͺ̹˸ʷɶͺͺͺͺͺͺͺͺλλλͺͺ̹̹̹˸˸ʷʷʷ˸̹ͺϼλλλͺͺ̹̹ͺͺͺͺͺͺͺͺλλͺͺͺͺλλϼϼϼϼϼϼϼϼλλλλͺͺͺͺ̹̹˸˸˸˸˸˸̹̹˸˸˸˸˸˸˸˸̹ͺͺͺ̹̹ȵȵȵǴȵɶʷ˸̹ƳŲǴȵʷʷȵȵʷ˸ɶɶɶɶɶɶɶɶȵʷ˸˸ɶǴȵȵųɷʹɶǵǳðʾk}mTvfLtcIraE|kOz`¨éžü¹}qf_afqĽħǪŨĪ§©ǰ˴̵˴˶˷ʶɵɵɴʵ˶̷ηθε˲ȯƭŪǭ˰ʭħþ|hc^_eq{wrjdhuĺãŤťƥŧƧȫɮʰɯɲ˴ͷ˵ư}_tMtLzRZkȾţâĥɪ̯ˬɭȫȫȭɮʱ̳̳̰̰ˮʭʪɬȲȴǳʵ˴˴ɰǮƫŨȿsd~[uStRuRtQ|nIxjEsN\\rʪʭȬǫǭɰʱ̴̵̳δͷͷʴɳʵʵʷ̸ιͷͶʹ̳ɰůĮƲȳűǲȳɴɴȳǲưwz]xgIp]=r_>zfCr^;sa={hGzYtƸʾǬƫʱε˱éæɬɬɬɬȫȫɬʭʭ̲˵ͷθεʹʱɰƭƫƭƫƫƫƫȮƲɶƳƮˮȧjVxMrGrGwOaλʯȲưŲȶʺ˻̶̻̹ʷɳȵʴ˵̶˵˵̴̴̴˳ʲʲʵ˶̷ιι͸̷̷˶ʵɴǲǲƱƱǲȱɳƼqZi[A`P7]M4^N5bR9fW@s[Žîȱȱȱʲ˳˵ʴʶɵ˵θ˴ǭmqTtcEn]AraErcFtdJuZpɿƫɯ˱ϵӹ˳ʲɱɱʳʳɲɯʰǽ{}bxnUlaEm^AtcE~oRc|ɿŮëĮë¬ŮîįƱȳʵ˶̴̴͵̴̴͵зз϶̶Ƴtal[Gk[DaQ8cS:cU;h\\Bx^Ȱʴ̷͹̹̹̹˸ǶŴĳ¯«ūƪƪũĮƲȲȲưíīīȭǬǪƩŦŦŦŨǭɱɯūƼeshLgY<l^Ah[;^Q1j]=vZyľſý¼ȽȽɾíí­ſıƳȴȵȵȵƳŲŲƳǴŲı¯ðıııðĬŨȨſr}nMfV5gT4aP2^O0aS6riLtƭɰɮȮɯɯɯɯʲʲ̴˳˳ʲʴ˵˵̶θθθͷͷ̶̶̶ʴʴʴɳɳȲȲȲɳʴ̶ͷθͷ̶˵̶˵ʴɳʴ̶Ϲѻннϼλ̹˸ʷʷλλλͺ̹˸ʷɶͺͺͺͺͺͺͺͺλλλͺͺ̹̹̹ʷʷʷʷ˸̹ͺλнϼϼλλͺͺͺͺͺͺͺͺͺͺͺϼλλͺͺλλϼϼϼϼϼϼϼϼϼͺͺͺͺͺ̹̹̹˸˸˸˸˸˸˸˸̹̹̹˸˸ʷʷʷʷʷ˸̹ͺͺͺͺƳǴǴȵȵɶɶɶ˸ƳƳȵȵȵǴǴƳƳƳʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵųȶɶƳƳǲĮhqWteHsbDxgIziK`|¦ù}od~]_[~W_s¾¥ǪɮǬƫũ©êǮɰȯưƳųƴȶ˸˸ɶȲɳɱɱȮǭƬĪŨǫɬʮʭĨĽ{uk~^wWvU{Z_xWzX^l|ýǧǧƧťæħǫʮɯ˱˴̵˶ɴƱŮæ¢y_uStPvP|VlȾƢǤɧʨͭ˫ȩɩ˫̯Ͱͱβͱ̰˯ɭȬǫƪɯȱȱʲʴ˵˵˵̴ͳɭ¥·vbvRxiBtd@|lH|lHvhCuRh|¹ȨȪ̯̰ǫȯ˲ʴ˵˶̷̵͸ι̸̷̷˶˶̶ͷ͵ʹ˰ʰɯǰȳʷ̹ȵɶ˵˵ʲɯǭƪʾpvV{lKwiDse>na7na5ob8uh>sL`sɾǪȫǬŪȬ˯ʰƬǭǭɮɮ˰ͲϴϵηηηηηͶ˴˴ɲʰȱȮȮǭƬƮȱǰŬƪȩ˾e}VsLrKtOyVoøɰɴȳǲǲǴȵȵ˵˳˵˳˵˳˳˳͵͵͵͵͵͵͵͵ϹϹϹθθͷͷͷ̶ʴȲȲʴͷθ̵ɰɯǻ}|nTeU<`N6bP8`P9[K4eV?yaǿȱɱǰƱŰįŰǱɳʴ̶˶ȳŮƯjtWrcDk\\=k\\=o`A{lMyYu̿ǧʪ˫̬ǨƧƧȩͮίͮʭǪʿj~sWqeKk`Dl`FwkQd|ŻéūƬǭǰƬ¨éŮįůưǱɳ˵ͷθ˵˵̶ͷͷͷ̶̴ɲǽ|do_HdT;eU<gW>hX?rdJ}c¼ǬȬƭ̶̶̶˵˵ȵǴƳǱưůůŭŭƮǯŮƯȱɲɲȱƯŮūǭȮǭĪ¨¨éèƫƫ¨ž¸dpbGiZ=eV9eV9iZ=l^Ay]ºûļû­­î­ǿŽŽƾ­įưƱƱƱƱƱƱŰįî­įǲȳǲŰįŭʰ¥çk{lMcR4kX:dQ3_N0cT7wlPuŪ˲ȰǯƮƮǯȰʴ̶ϹϹϹθθͷͷͷθθͷ̶̶˵ʴʴȲȲǱǱǱȲɳɳʴ̶θϹϹθ̶ʴ˵ɳǱȲ˵θϹϹкϹθͷͷͷθθθθθͷͷ̶̶̶ʷʷ˸̹ͺͺͺͺ˸˸˸˸˸˸˸˸̹ͺϼннϼͺ̹˸˸˸̹̹ͺͺͺμμμμμμμμͻͻͻͻͻͻͻͻλϼϼннϼϼλͺͺͺͺͺͺͺͺϼλͺͺ̹˸ʷʷʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹ʷʷʷ˸˸̹̹̹˸ǴǴȵȵȵǴǴƳƳƳʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵųȶɶǴǲɲůhrUteFraCwgFyiH`x¦ĨŻ~l~az[}Z{WzSZjÿƨƫũǫũêīȯʱʱȲȵǶǶȷʷʷǲŰǰȱɯɯȬǫũĨƪǫɭȬũ»ubtU~oNqNtQqNxUduŦǧǧǧƦħŨɭ̰̲ͳ̵̵˶ɴǲƯæ¤x^sQqNrO|XkȾšȢʥ˦ή̬ʪʪ̬ήͰͰͱͱ̰˯ɯȮǭǭȮɯʲ˳˵˵̷̷ͷѸηʮkwS{h@uc=}kE{kGvhCuTkýƩŧɮʯɭ˰ʴɴʵʵ˶̷͸͸͸͸̷̷̷̷͸Ͷϳͱ˱ɲȳɶ˹̺ɷʷ̶϶ϵͰǩ¥e~qQylIznH{oGymCwl?ti<ui?|pFzRcz¤ȫʭɬʮͱ̲ɯǭǭȯɰ˲ʹ϶зͶηηηͶͶ̵˴ɲɲȱȱǰƯŮƮɰɭǬǪƦǺz^wQ~oHoKuR}[vžʲʴɳɳɳɳɳʴ˳˳˳˳˳˳˳˳͵͵͵͵͵͵͵͵ϹϹθθθͷͷͷͷ˵ʴ˵ͷθͷ˴ƫǫŷy|lReU;`N6aO7cS<]N7iZCf«ɱȰǲƱŰįŰƱǲɴɴ˶ɴǲȳƱºksTufGo`Ao`AvgFqPcpõͿġǤȥŢŢǤʧ̩˨ťźq}a}rVynRwnQw^i{ƿéĪūǭȮƬééūǭůưưǱɳ˵ͷθ˵˵̶ͷͷ̶̶˳Ǯĺy_l\\CbR9cS:dT;gW>qcI}cƼȫȫǬ˳˵˵˵ʴȲǱưưǱǱǱǱǱǱưƮǯɱʲʲɱǯƮƮǯȰǯŭëëīèǫƫ¨ƿù|bo_EhY<dU8dU8iZ=m_B|`ºŽǿĭî­­î­ǿŽŽƾǿîįįįŰƱƱƱŰįîî­įǲȳǲŰįŭʲ§¦jyjMaP2iV8fS5aP2eV9ynPwū̱ǱưưưǱɳ˵̶ϹϹϹθθͷͷͷθθͷ̶˵˵ʴʴȲȲǱǱǱȲɳʴ˵ͷθккθͷ˵˵ɳǱȲʴͷͷͷϹθθͷͷͷθθθθθͷͷ̶̶̶˸˸̹ͺͺͺ̹̹˸˸˸˸˸˸˸˸ͺͺλϼϼλͺͺ˸˸˸̹̹ͺͺͺμμμμμμμμͻͻͻͻͻͻͻͻλϼϼннϼϼλͺͺͺͺͺͺͺͺλλͺ̹˸ʷʷɶʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹ʷʷ˸˸˸̹̹̹˸ǴɶȵȵȵȵǴǴǴǴʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵųȶɶǴɴ˴ưgsVteFraCwgFyiH`{ĨȬùqf~^~[{VxQ~Taw½£æ¥ƫŪŬǮɳʴʴʴʷȷȷɸʷɶƱîǰȱʰ˱ʰȮƪĨūƬǫǫƪĨ¥ǾfrSwhGvhEwiF{mJ|YpĿŧɪǧȨȨǧƩǪʮͱϵϵͶ̵ʳɲȳǰħ¤w~]rPoLoL|XkǽšȢɥ˧ϯ̬ʪʪ̬ήͰͰͱ̰̰˯ɯȮȮǭȮɯʲ̴̶̶̷˶̶зϸϳȮɾtyU|iAuc={iCyiEvhCwVnƩ¤ƫɮ˯ϴʴɴʵʵ˶̷̷̷͸͸͸͸͸ιιηϵδ̲˳˵ʷ˹̺ɶɶʵиҶΰãsz]{nN{nLvS}WY|TtLznFznF~rL}Whzɬˮ̰ͱ̰ɭƬƬǭȮ˲ʹ϶зͶͶͶηͶ̵̵˴ɲɲɲȱǰƯƯƮɰʮɮȫťös~WqKzkD}mIwT`|¹çʲʴʴʴʴʴʴʴ̴̴̴˳˳˳˳˳͵͵͵͵͵͵͵͵ϹθθθͷͷͷͷθͷͷθϹϹ̶ɲĩ¦t{kQfV<`P7`P7dT=aR;o`ImƯ˳ȰǲƱŰįŰƱȳɴȳʵ˶ʵʵʵŰȽlx[{nNuhHwjJ|oOwUasȻ̿ġǤʧɩĤǼ·tdx\\x\\cj}ü¨¨ūǭǭƬūūǭɯưưưǱɳ˵ͷθ˵˵̶̶̶̶˵˳Ŭu[iY@_O6`P7aQ8eU<pbH~dƼȫȫȭɱɳʴɳɳǱưůưǱɳ˵˵ɳǱưƮǯɱʲʲɱǯƮƮǯɱȰŭĬĬŬĩǫƫ¨ĺx^l\\BgX;cT7eV9j[>pbEdºĭĭȱįî­­î­Žƾƾǿ­­îįŰŰƱŰŰįîîŰȳȳƱŰįƮɱè¦eufI`O1gT6hU7cR4gX;|qSyǭγưưưǱȲʴ̶ͷθθθθͷͷͷͷθͷͷ̶˵ʴʴʴȲȲǱǱȲɳʴʴ̶ͷϹккϹͷ̶˵ɳǱǱɳ˵̶̶θͷͷ̶̶ͷθθθθθͷͷ̶̶̶̹̹ͺͺͺ̹˸˸ʷʷʷʷʷʷʷʷͺͺλλλλͺͺ̹̹̹̹ͺͺͺͺμμμμμμμμͻͻͻͻͻͻͻͻλϼϼннϼϼλͺͺͺͺͺ̹̹̹ͺͺ̹̹˸ʷʷɶʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹ʷ˸˸˸̹̹̹̹˸ȵɶȵȵȵȵȵȵȵǴʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵƴȶȵȵʵ̵ưfrUsdEq`BvfEzjIbǫ˯ƭêǻ}qia|W{TZgsĽūƫǮȯɳʴʴɵʷȷȷʷ˸ʷǲŰǰȱ˱ͳ̲ʰǫũǭǭƪƪũũŨŨæepQufEseBugDqNa|żĦȩǧȨɩɩȫɬ̰βжϵ̵ʳȱǰǲǰŨ¢t}\\rPoKoK~Zmǽšǡɥ˧ϯͭʪʪ̬ͭͰ̯̰˯˯ʮʰɯɯȮȮɯ˳͵ͷ̶̷˶ʴ̳ʳ˯ǭ}~ZlDvd>zhBxhDvhExWqĤǪæǬ˰˯εʴɴɴʵʵ˶˶̷͸͸ιιϺϺϺιиϷζ̶˸˸˹̹ȵǲɲϵѴɪ¹ykzZsSzZfpsncyVsP~rLvPZiɬ˯̰ʮȬūūƬǭʱʹ϶з̵̵ͶͶͶ̵̵˴ʳʳɲȱǰǰƯǯȯ˯˰ʭťpzSoIxiB}mIyVdƽũɱʴʴ˵˵˵˵˵͵̴̴̴̴˳˳˳̴̴͵͵͵͵ζζθθθͷͷͷ̶̶ͷͷθϹкθʴŮèɾnyiOhX>bR9aQ8aQ:cT=thPvʲ̴ɱȳǲƱŰƱǲɴʵȳʵ̷˶˶˶˶ʴʿre{[vVuUtT|ZftĺƼɿɾź}vmedn}éūééƬǭǭǭȮɯʰ˴ưưǱȲɳ˵̶ͷ˵̶̶̶̶˵ʴʲŬ|~rXgW>^N5_O6_O6cS:pbHeƼǪȫȭȰȲȲȲȲǱưůưȲ˵θθ˵ȲưƮǯɱʲʲɱǯƮƮȰɱȰƮŭŭǮŪǫƫéŻv\\k[AgX;dU8fW:m^AugJkļû«ƯƯʳƱįîîîîǿǿǿƾƾǿǿîîįŰŰŰįįįƱȳȳƱįįƮʲŪç}asdG`O1gT6hU7dS5iZ=~sU{ǭͲůưưȲɳ˵̶ͷθͷͷͷͷͷͷͷͷͷ̶̶˵ʴɳɳȲȲǱȲȲɳ˵˵ͷθϹϹϹϹθͷ˵ɳưưȲʴʴʴ̶˵˵˵̶ͷθϹθθθͷͷ̶̶̶ͺͺͺͺ̹˸ʷʷʷʷʷʷʷʷʷʷͺͺͺλλͺͺͺ̹ͺͺͺͺͺͺͺμμμμμμμμμμμμμμμμλϼϼннϼϼλͺͺͺ̹̹̹̹˸̹̹˸˸ʷʷɶɶʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹˸˸˸̹̹̹ͺͺ̹Ǵɶȵȵȵȵȵȵȵɶʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵǵȶȵȵʵ̵ůǽdrUsdEp_AvfE{kJeũȬƭȯǮèŹp`~X{U}[`myüĪūǯȲȴȴȴȴȵǴȵʷ̷̹ʵȳȱɲ˴̵ͳ˱ɯȮ˱ɯǭūĨĨĨũæ~b|mNsdCtfCwiFtQeƽåȩƩȫɬɬɭɭ˯ͱͳ̲˱ɯǰƯƯǭŨp|[sQrNrN]pǿšƣɧʩϯ̬ʪɩ˫̬ˮˮʮʮʮʮʰʰʰʰɯʰ˳̴ͷ̶͸̷˵˲ŮũĪ^oJxf@{iCyiEwiFzYsƦʭǪ˰Ͳʱ˲ʴɴɴʵʵʵʵ˶̷͸ιϺлϺϺϹкϹθ͹̸̸ʷʷɴȱɮαί¢}ld^bpm^yStLwM}Vg¥ȫˮɭƪĨĨūǭɯ̲϶з˴˴̵ͶͶ̵̵˴ʳʳɲɲȱǰƯǯǮ˯̱ˮťpzSpJxiB}mIzWfǾĨɱʴ˵̶ͷͷ̶̶ζ͵͵̴̴˳˳˳̴̴̴͵͵ζζζθθͷͷͷ̶̶̶̶̶ͷϹϹͷȲìĩżgugLhZ?dT;bR9]N7fW@}qYº˳͵˳ɴȳǲǲǲɴʵ˶ʵʵ˶˶ɴȳʵͷĪ̾}tjbzZ|\\afow}~{wv|ƼĭƯìƾļŮǰǰƯǰɲ˴̵̵ǱǱǱȲɳʴ̶ͷ˵̶̶̶˵ʴɳɱƭ{|pVgW>_O6_O6_O6bR9pbHfƼƩǪȭǯǱǱȲǱǱưůưɳ̶ϹϹ̶ɳưƮǯɱʲʲɱǯƮƮȰʲɱǯƮƮȯǬɭǬĪçƼu[k[AhY<eV9gX;o`CykNqǿļìǰŮȱƱį­­įįî­ǿƾŽƾƾǿ­îįŰŰŰŰƱǲɴȳƱįŰǯʲƫĨz^sdGaP2iV8gT6dS5k\\?vX~ƬʯưưǱɳʴ˵̶̶̶ͷͷͷͷͷͷͷͷͷ̶˵ʴʴɳɳȲȲȲȲɳʴ̶̶ͷθθθθθθͷ̶ʴǱǱȲɳɳɳʴʴʴʴ˵ͷθϹθθθͷͷ̶̶̶ͺͺͺͺ̹˸ʷʷ˸˸˸˸˸˸˸˸ͺͺͺ̹̹ͺͺͺλͺͺͺͺͺͺͺμμμμμμμμμμμμμμμμλϼϼннϼϼλͺͺͺ̹̹˸˸ʷʷʷʷʷɶɶɶɶʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹˸˸̹̹̹ͺͺͺ̹ǴȵȵȵȵȵɶɶɶɶʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵȶȶǴǴʵ˴¬ù}apSsdEp_AvfE}mLh¦Ĩīɰ˲ɰǯ¨ƻrc}ZzWyX~]gtǽìưƳǳǳǴǴǴȵʷ̷͸˶ɴʳ˴˴˴̲̲˱˱δ̲ɯǭĨççĨæ|_yjKqbAseBwiFrOb~ǾãƨʫǪɬʭʭɭȬɭ˯ʰʰɯɯǰƯƯƬħżkzWtQtPuQbtƤǤȧʩή˫ɩȨɩ˫ʭɬɭɭʮʮʰʰ˱˱˱˱˳˳̶̶ιιкʹŮĨĪç´^oJygA}kG|lJ{mJ^zǪ̰ɬγϴʱɰʴɴɴɴɴʵʵʵʵ˶͸ϺлϺιϹϻлλ͹̸˷ɶɳ˴ʱ̯˭ƦƹtaaftõŰɺraxP|qDypGyYoǾŨƪĨçĨūƬɯ˱϶Ϸʳʳ˴̵̵̵̵˴˴ʳʳɲȱǰǰȰƭ˯Ͳˮão{TrLyjC|lHyVfƽĨɱʴ̶θθθͷ̶ζζζ͵̴̴˳˳˳˳̴͵͵ζϷϷͷͷͷͷ̶̶̶˵˵˵̶θθ̶ȲĬƫz^pbGgY>dT;aQ8]N7m^Ggʲʹʹ˶˶ʵɴɴ˶̷ι̷ʵɴɴȳŰǲ˵ɯɭø~tlhginrvx¶ȯƯƯìǿûŽìɲʳȱǰȱ˴ͶͶͶȲǱǱȲɳʴ˵̶˵̶̶̶˵ʴȲȰǮy{oUfV=_O6_O6^N5bR9rdJhƼŨƩƫƮǱǱȲȲǱưưǱɳ̶ϹϹ̶ɳǱƮǯɱʲʲɱǯƮƮȰʲʲȰǯǯɰʯ˯ȭūĨƼsYjZ@hY<eV9fW:o`C{mPtŽŽĭǰŮƯŰî­­įƱƱŰî­ƾŽŽƾƾ­įŰŰŰŰǲȳɴȳŰįŰǯɱǬĨw[rcFcR4kX:eR4dS5n_Bz\\ūǬǱȲɳʴ˵˵˵˵̶̶̶̶ͷͷͷͷ̶̶̶˵ʴɳɳȲȲǱȲȲɳ˵̶ͷͷͷͷͷͷͷͷͷθ˵ȲǱȲɳɳȲȲȲȲɳ˵ͷθϹθθθͷͷ̶̶̶̹̹ͺͺͺ̹˸˸ͺͺͺͺͺͺͺͺͺͺ̹̹̹̹ͺͺλλλλͺͺͺͺμμμμμμμμϽϽϽϽϽϽϽϽλϼϼннϼϼλͺͺ̹̹˸ʷʷʷɶɶɶɶɶɶɶɶʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹ͺͺͺλ̹ƳǴȵȵȵɶɶʷʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵɷɷǴƳɴɲʿ{z^~oRrcDp_AwgFoNkêŬĮȲʴȯʱɮǪvi`{YwU}\\fqùǿĮıƳȶ˸ɶɴɴ˶̷̷ʵǲ͸̷˴ʳʳ˴̵Ͷϸη̲ɯǭƬũũæz}]xiJqbAugDzlI}oL_{ťǩɪȬɭʮʮȬǫǫȬȬȬʰʰʰɯȮǫduRsNvRxTgxßƤƦȩʫͭʪǧǧȨɩȫǪɭɭɭʮʰ˱˱˱ͳ̲ʲʲʴ̶ϺлӽзȱƪƬĨ´~ZmHxfBmIpNsPe·ɬͱɬϴзʱɰʴɴɴɴɴɴɴɴȳʵ̷ιϺϺιͺλϻνͺ˷ʶɳǰʱɮȪĤȻxk]dq¶íɸ˻ŵǺu]xJzqF|rO~`o}ǾǾççĨƪɯ˱δϵɲʳ˴̵̵̵̵̵˴˴ʳɲȱȱǰȰǮ˯̱ɬlxQrLxiBzjFwTeǾĨȰʴ̶θϹϹθͷϷϷζ͵̴̴˳˳˳˳̴͵͵ζϷϷͷͷͷ̶̶̶˵˵̶̶̶θϹͷʴǯǬw|qUi[@cU:aS9^P6aR;whQvĭɱʱʹι͸̷˶̷͸ϺлιȳƱȳȳŰŰɲʱ̱ǭǻúĺƼȾɿɿīǮǰŮƾƾ«ȱ̵̵ʳȱɲ̵ηη̵ȲȲȲȲɳʴ˵̶̶̶̶˵ʴɳȲǯǮwymSeU<^N5^N5]M4cS:seKjŻæħŪǯǱȲȲȲȲǱǱǱɳ̶ͷͷ̶ɳǱƮǯɱʲʲɱǯƮǯɱʲʲɱȰȰʱͲͱɮƬĨƼ|qWiY?fW:cT7dU8m^AzlOtƾŽĭȱŮƯį­­ŰǲȳȳŰįƾŽŽŽƾǿîŰŰƱƱȳɴɴȳŰįŰǯƮŪ¦}~sWpaDcR4lY;dQ3eT6qbEbþūƫȲɳʴ˵˵˵ʴɳ˵˵˵̶̶ͷͷͷ̶̶˵˵ʴɳȲȲǱǱȲȲʴ˵ͷθ̶̶˵˵˵˵̶̶кͷʴɳɳʴɳȲǱǱǱɳʴ̶θкθθθͷͷ̶̶̶˸˸̹ͺͺͺ̹̹λλλλλλλλͺͺ̹˸˸̹ͺͺϼϼϼλλͺͺͺμμμμμμμμϽϽϽϽϽϽϽϽλϼϼннϼϼλͺͺ̹̹˸ʷɶɶȵȵȵȵȵȵȵȵʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹̹̹̹ͺͺͺλλͺƳŲȵȵȵɶɶʷʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶȵȵȵɷɷƳƳɴȱȽyy]}nQrcDp_AxhGpOm¸ȯʱǱʴʴưǱʱ˰ʭĥ¹xi^wUxW}^esźįƳʷλ˶˶ʵ˶̷˶ȳŰι͸˴ʳʳ˴Ͷϸйϸδ̲ʰȮǭǫy|\\xiJteDykHqN~pM`|£ƦŧĥȬʮ˯ʮǫƪƪƪǫȬ˱̲ͳ̲ʰȬƽy^~rLqLvR{Vj{ĠƧƦǩɫ̬ɩǧƦǧȨǪƩȬȬɭʮʰ˱̲̲δͳʲɱɳ˵ϺѼҼзɲȬȮĨzV~jEweAnJsQvUlźˮͱǭεз˲˲ʴɴɴɴɴɴɴɴǲɴ˶ιϺι͸̹λμͼ̹˷ɳǰǭƫƪĤʽ~maaizʾƳȸŸƻ̿ķnX{PyoLuW~`j}¦çĨƪȮ˱δϵɲɲʳ̵̵̵̵̵˴˴ʳɲɲȱǰȰȯ̰̱ǪȽhuNrLwhAyiEvSdȿƪȰʴͷϹкϹθͷиϷζζ͵̴˳˳˳˳̴͵͵ζϷϷͷͷͷ̶̶˵˵˵θͷͷθϹϹ̶ɱȬrvkOdV;`R7_Q7\\N4fW@}qY»Ȱȯɰʹкι͸̷͸ιлѼιǲįȳɴƱŰɲȯʯȭ§§ĩúĻ¹úƽǾż¹¹żƽƽĻżȿ§ȭʯ˲ɰƭê©ǰĭìȱ˴Ͷη˴ɲʳͶϸη̵ȲȲȲȲɳʴ˵̶̶̶̶˵ʴɳȲǯƭvwkQdT;]M4]M4\\L3dT;tfLkŻ¥æĩǯǱȲɳɳɳȲȲȲɳ˵̶̶˵ɳȲƮǯɱʲʲɱǯƮǯɱ˳˳ɱȰɱ˲ϴβʯƬũŻzoUgW=eV9bS6bS6k\\?xjMsŽļĭɲƯǰî­­ŰȳʵʵǲŰ­ǿŽŽŽƾƾǿîŰƱƱƱɴʵɴȳŰįŰȰëèz{pTo`CcR4lY;dQ3fU7teHfƬŪɳʴ˵̶˵ʴɳǱ˵˵˵̶̶ͷͷͷ̶̶˵ʴʴɳȲȲǱǱȲɳʴ̶ͷθ̶˵ʴʴʴʴ˵̶ѻθ˵ɳʴʴʴɳưưǱȲʴ̶θкθθθͷͷ̶̶̶ʷʷ˸̹ͺͺͺͺϼϼϼϼϼϼϼϼλͺ˸ʷʷ˸ͺλϼϼϼλλͺͺͺμμμμμμμμϽϽϽϽϽϽϽϽλϼϼннϼϼλͺͺ̹˸ʷʷɶȵȵȵȵȵȵȵȵȵʷʷʷ˸˸̹̹̹̹̹̹̹̹̹̹̹̹̹̹ͺͺλλλͺɶɶȵǴǴǴǴȵɶʷ̹̹̹˸˸ʷʷʷȵȵȵȵȵȵȵȵƴ˹ʷŲŰƯǼw~sWyjMteFtcEyiHtSwƭ̳˵ʴƲ®Űǰ˱̰ɬãú~pc}\\yZz[hwźʿŰʶѼ͸̵ͶͶͶ˴ǲįȳʵ˶̷͸̷˶ʵͶ̵̵ʳȱǭĪéȿuzZwhIrcBtfCxjG~pM^yƦŧĥɭʰ˱ʰȮǭǫɭβͱ˯˯̰˯ʮȫżq|YsMuOzU~YmŻȤɪʪʬʬͭͭ˫ʪɩȨǪǪƪǫȬʮ˱̲ͳͳɯɯɱʲ˵̶ιϺԾѸʳ̰ͳɭ~xWmJ}kGqMsQxWpʿƩ˯˱̳ʹͶɳͷ˶ʵɴȳǲȳȳʵʵ̷͸͸͸͸ͺ˻νпλɵǱǰʰȫȽöolro|ëĳŸǼǺƺrayWxXy[aisƪƪƪ˯ϳϵɲʳ˴̵Ͷηηη̵˴ʳɲȱǰȱɱɰβ̱ŨƻgrKoIxiBzjFtQb¥ǫɱʴ̶̶̶θкӽӻи͵˳̴̴˳ʲɱɱʲ˳˳̴͵͵θθθθθθθθккϹθθͷ̶̴ũdpgJeZ>`U9dV<gY?j^FiĪʲ̳ʹεϹ͸˶ʵ˶͸ϺѼɴɴʵ˶˶˶ʵʳȮɯɯȮǭƪĨĨçæææħťťƦææħƪȬɭʮ˱ϵͳɲƯĭììîŰŰįįƱȳ˶̷͸͸͸͸͸͸͸͸Ȳɳʴ˵˵˵˵˵θ˵ȲưưǱưŭɿprfL`P7]M4\\L3YI0aQ8zlRuŻæŪǯǱɳʴʴʴʴʴɳʴ̶θͷʴǱůƮǯǯǯǯƮŭĬŭȰʲ˳ɱȰǯɰͲд̱ƬƪyoUgW=fW:bS6bS6hY<rdGjºļ«ƯŮȱŰƱƱǲǲƱƱŰƱŰ­ƾƾƾǿ­îŰƱƱȳɴɴǲǲȳʲŪptiMiZ=gV8gT6hU7dS5ufIpéǬǱȲɳɳʴʴɳɳʴ˵̶ͷͷ̶˵ʴ̶˵ɳȲǱưưưȲɳʴʴ˵̶ͷͷθθθͷͷ̶̶̶ɳɳʴʴʴʴʴ˵ǱǱǱȲʴ̶θϹθθθθθͷ˵˵ʷʷ̹ͺͺͺͺͺλͺͺ̹̹ͺͺλ̹̹ͺͺͺλλλ̹̹̹ͺͺλλλϽϽϽϽϽϽϽϽμϽϽооϽϽμλλλλλλλλнλͺͺͺͺ̹ʷ̹˸ʷʷɶɶɶʷ̹̹ͺͺͺ̹˸˸ʷʷ˸̹̹ͺͺͺʷʷʷ˸˸̹̹̹̹ɶɶȵǴǴǴǴȵɶʷ̹̹˸˸˸ʷʷʷȵȵȵȵȵȵȵȵɷͻ̹ǴǲǰǼt|qUwhKrcDraCyiHtSw¸īȯǱȲǳűįǲʳ̲ʮƩƽsh`zZ|_fq{Ƽíɳ̵˴˴˴˴˴ʵɴʵ˶̷̷̷˶ʵɴɴɲɲȱǰƯūĪ¥z_}nOwhGxjG|nKqN`{£ǧǩŨɯʰ˱ʰȮǭȬɭβ̰ʮʮ˯˯ɭǪĹk{UtNxR~X\\oƼǦʪɬʭʭ̯̬˫ɩȨȨǪǪƪǫɭʮ̲̲ͳͳʰɯɱʲ˵̶ιϺкεɲ˯δɭ|xWmJ{iEmLqPwVsʿǫ˱˱˲ʹͶɳʴɴȳȳǲǲȳȳɴʵ˶˶̷̷̷˸˻ͼͺ̸ɳǯƬƫwloxǩɱȷȻǾǼŵ¯Ĺuc~^xZy[}_hzƽçĨĨȬ̰̰ɲʳ˴̵Ͷηηη̵˴ʳɲȱȱȱɱ̳β˰¥cpIoIxiBzjFtQcæǫʲ˵ͷͷ̶ͷкҼҺи͵˳˳̴˳ɱɱɱʲ˳˳̴͵͵θθθθθθθθккϹθͷͷ̶̴{^neHh]Af[?gY?gY?vjRrƬʲ̳̳̳θ̷˶ʵʵ̷ιлʵʵ˶˶˶ʵɴɴȱɯɯɯȮǭūũũƪƪƩǪǪǪȫƩƪǫȬɭ˯˱̲δ̲ɲƯĭĭįįŰŰŰƱǲɴʵ˶˶˶˶˶˶˶˶˶ɳɳɳɳʴʴ˵˵θ˵ȲǱǱȲǱƮ©nqeKbR9`P7_O6[K2eU<qW|ǽæƫǯȲɳʴʴʴʴɳɳʴ˵̶̶ʴȲǱƮǯǯǯǯƮŭĬŭȰʲʲȰƮƮȯǬʮƫ¨¦ǽu}mSfV<fW:cT7cT7iZ=tfIlļŽìǰƯɲŰŰƱƱƱƱŰŰǲƱîǿǿǿǿ­îŰŰǲȳʵɴȳǲȳʲªĩlrgKgX;eT6eR4iV8gV8zkNuæĪȭɳʴ˵̶̶̶̶˵ɳʴ˵̶̶˵ʴɳ˵ʴɳȲǱǱǱǱɳɳʴ˵̶̶ͷͷθθθͷͷ̶̶̶˵ʴʴʴʴʴʴʴǱǱȲȲʴ̶ͷθͷθθθθͷ̶˵ʷ˸˸̹̹̹̹˸ͺͺͺͺͺͺͺͺ˸˸̹̹ͺͺλλ̹̹̹ͺͺλλλооооооооμϽϽооϽϽμλλλλλλλλϼͺ̹̹λλͺ˸˸ʷʷɶɶɶʷʷ̹̹̹̹̹̹̹̹̹̹̹̹ͺͺͺͺʷʷʷ˸˸̹̹̹ͺɶɶȵǴǴǴǴȵɶʷ̹˸˸˸ʷʷʷʷȵȵȵȵȵȵȵȵɷͻ˸ƳƱŮøpzoSwhKrcDsbD|lKxWyĺ©êíǳʷɶŲƱʴ̴̲ˮɬǪ¢Ÿsf}`}_dkuƷȯȮȮȮȱɲ˴̵̷̷̷̷˸ʷɶȳŰŰƱƱƯŮĭĭæ}crSzkJ{mJ}oLrOb}ĥɩȪȫɯɲʳɲȮȮȮʰ̰˯ɭɭɬɬȫƧ¸exRvP{SY^qȾƥɩʭʮɭˮ˫ʪȨȨȨǪǪǫȬɭ˯̲̲ͳ̲ʰʰʲʲ˵̶ιϺ̶˲ȱ̰ϵɭzvUlIyfE|iH}mLvUtȬ̲˳ʴ̶͸ɵȲǲȳȳȳȳɴɴɴɴʵ˶˶˶˶ʷͻ̼̺̹˳Ȯȿuqpq|Żß˪ϲ̶ʸɻʾĸǻȸʸ̳ɬĻvhyYsStT|\\kwħƪʮ˯ʮʳʳ̵ͶηηηͶ̵̵ʳɲȱȱȱɱεβɮƿ{_~oHoIxiB{kGvSdħȬ̴ͷθͷ̶̶θѻѹζ̴˳˳˳ʲɱɱɱʲ˳˳̴͵͵θθθθθθθθкϹϹθͷ̶̶̴~~wZneHmbFmbFk_Ei]C}e¸ɯ˳̳̳˲θ̷˶ʵ˶̷ιϺ˶̷̷̷˶ʵɴȳʴʲʲʲɱȮǭƬɯʭʭˮˮ̮̮̮ʮʰʰ˱˱̲˴˴ʳɲǲŰŰŰƳƳıŲƳȵɶʷʷʷʷʷʷʷʷʷʷʷʴɳȲǱȲɳʴ˵ͷʴȲȲɳɳȲǯŬiocIdT;cS:bR9^N5jZAx^ù¥ħǬǯȲɳʴʴʴɳɳɳɳʴʴʴ˵˵˵ƮǯǯǯǯƮŭĬƮǯɱȰƮĬĬƭĩƪèƼr{kQeU;gX;eV9eV9l]@vhKoǿìƾìǰǰ˴ƱǲǲȳȳǲǲƱȳǲŰî­įįǲɴʵʵɴǲȳʲëhpeIfW:fU7hU7hU7kZ<rUzħƬɮɳʴ˵̶̶̶̶˵ȲɳɳʴʴɳɳȲɳɳȲȲȲȲɳɳʴʴʴ˵̶̶ͷͷθθͷͷͷͷ̶̶̶̶˵˵ʴɳɳɳȲȲȲɳʴ˵ͷθͷͷθθθͷ̶˵ʷ˸˸˸˸˸ʷɶ˸̹ͺλλͺ̹˸ɶɶʷ˸̹ͺλλ̹̹̹ͺͺλλλϽϽϽϽϽϽϽϽμμϽϽϽϽμμλλλλλλλλͺ̹˸̹λϼλͺɶɶȵȵȵɶʷʷͺ̹˸ʷʷ˸̹ͺλλλλͺͺͺͺ˸˸˸˸̹̹̹̹λɶɶȵǴǴǴǴȵɶʷ˸˸˸ʷʷʷɶɶȵȵȵȵȵȵȵȵǵʸȵðîmzoSxiLsdEveGqP~]~Żïǳ˸ʷǴǴȵʴ˳ͲͲͰ̬Ŧƽ}rldehjr~ɿ¨ūȮȱɲʳ˴͸͸̷˶ʷȵǴǴįįŰŰĭì««|cqRyjIykH{mJsPcºĥȨɫɬɯɲʳʳɯȮɯ˱˯ʮȬȫȫȫǪŦy]uOuMzRX\\vƧǪʮ˱ɭʭʪɩȨȨȨǪǪȬȬʮ˯̲̲̲̲ʰʰʲʲʴ˵͸ιɳʱȱβжɭwtSkHxeDyfE{kJwXvɭ˴˳ʴ̶͸ʶȲȳɴʵ˶˶˶̷ʵʵ˶̷̷̷˶˸ννλϺͳŪúylnxȺťʫαγ˵ɵȶǷ´Ƹȸ˹κθƭǻu`uUsSxXenƽǪ̰ϳβ˯̲˴̵ͶηηηͶͶ̵˴ɲɲȱȱʲ̳̰ɮz^pIoIyjC|lHwTfŨɭζϹϹθ̶̶θкиζ˳˳̴̴ʲȰɱɱʲ˳˳̴͵͵ϹϹϹϹϹϹϹϹϹϹθθͷ̶˵˳~atmPriLtiMwkQznTyʰʹεϵʹϹι͸̷̷͸ιϺ͸͸͸̷˶ʵȳǲʴ˵˳˳ʲʲȰȮ˱˱˱̯ͰͰͰα̲̲̲̲̲˱ʳʳȱǰƱŰŰƱǴȵıƳȵʷ˸˸ʷɶʷʷʷʷʷʷʷʷ˵ɳǱưưȲʴ˵˵ʴȲȲʴʴɳȰŬ}cl`FeU<eU<cS:_O6l\\C|bǽ§¥ŨʯȰȲɳʴʴʴɳȲɳɳȲȲɳ˵ͷθƮǯǯǯǯƮŭĬŭǯȰǯĬëëŬǬɭŪ¨ĨǽoxhNdT:hY<hY<hY<n_BykNsĭƾìƯƯʳȳɴɴʵʵɴɴȳȳǲƱįî­ǿǿǿ­­ǲɴ˶˶ɴǲǲɱªcncGgX;hW9kX:gT6o^@y\\~ħƬɮǱȲɳɳʴʴɳɳȲȲȲȲȲȲȲȲȲȲȲȲȲɳʴ˵ʴ˵˵̶̶ͷͷͷͷͷͷͷͷͷͷͷͷͷ̶˵ʴɳɳȲɳɳɳɳʴ˵̶̶̶ͷθθθͷ̶̶˸˸˸˸ʷɶȵǴʷ˸ͺϼϼͺ˸ʷȵȵɶʷ˸̹ͺλ̹̹̹ͺͺλλλμμμμμμμμͻμϽϽϽϽμͻͺͺͺͺͺͺͺͺ̹˸ʷ̹λнϼλɶȵȵȵȵɶʷʷͺ̹ʷɶɶ˸ͺλннϼλλͺͺͺ˸̹̹̹̹̹̹̹ͺɶɶȵǴǴǴǴȵɶʷ˸˸ʷʷʷɶɶɶȵȵȵȵȵȵȵȵǵʸǴðîhxmQxiLsdEwfHuTaǻ©ĮƲʶ˸Ƕʸɶɶɳɳ˲˲̱̯ʬǩ¤»~mic}]`jwéɯ˱˱ʳʳι͸̹ʷȷƵƵƳƱƱƱŰį­ȿ{bqRyjIykH{mJuRfļĥȨȪɬȱɴʳʳȱȱʰ̲˯ɭǪǪȫɩǧģövZsKsKvN}TZyâŦƩʯ˲ȯʭʪɩȨȨȨȫȫɭɭ˯̰̲ͳ̲̲˱˱ʲʲʴ˵͸ιɳʱɲϳжǫrqQ~jIwdCxeD{kJz[{¨ʮ̵ʲʴ̶͸ʶɳɴ˶͸ιιιι̷͸͸ιι͸̷̷ͻ̸̸̶ǬƻwoowͿɭɮ˰ʹʹ˵ɳȴȴȶʸɷɷ̺Ͻ̺ůŷn_yYyY~`gpƩαҵгʯͳ̵ͶηηηηͶͶ̵˴ʳɲɲɲʲȯʮʯƩ·{^qJoIyjC~nJyVhƩ˯Ϸккθ̶̶θϹϷ͵̴̴͵͵˳ɱɱɱʲ˳˳̴͵͵ϹϹϹϹϹϹϹϹϹϹθͷ̶̶˵˳½s~avYvY}cmĪʰʹ϶ѷзѻϺϺιιιϺϺ͸͸͸͸̷ʵɴȳʴ˵˵˵˵˲ʱʱ˲˰˰̱̱ͰͰͰ˱˱˳˳ʲʲʴʴǱǱıııƳǵɷƳǴɶ˸˸˸ʷɶ̶̹̹̹̹̹̹̹̹ʴȲǱưȲʴ˵ʴɳȲɳʴʴɳǯ©x^i]CeU<eU<cS:`P7n^E~dȾèħǪ̱ȰɳʴʴʴɳȲȲɳȲȲǱɳ˵ͷϹƮǯǯǯǯƮŭĬŭƮǯŭëªëƭ˰̰ȭĪũǽivfLdT:j[>k\\?k\\?paD|nQvŮǿ«ŮĭǰǲǲȳȳȳȳǲǲƱƱŰŰįîî­ǿǿƾƾǿǿƱȳ˶˶ɴƱŰǯª{^laEdU8eT6iV8iV8veGdæƬɮǱȲɳɳʴʴɳɳȲȲȲǱǱȲȲȲȲȲȲȲɳʴ˵̶˵̶̶̶̶ͷͷͷͷͷͷͷͷͷͷͷθͷͷ̶˵ʴɳɳʴʴɳɳɳʴ˵˵̶̶ͷθθθͷ̶˸˸˸˸ʷɶȵǴɶ˸ͺλλͺ˸ɶɶɶʷʷ˸̹ͺͺ̹̹̹ͺͺλλλ̺̺̺̺̺̺̺̺ͻͻμϽϽμͻͻͺͺͺͺͺͺͺͺ˸ʷʷ̹λннϼʷɶɶȵȵɶʷʷ̹˸ɶȵɶʷͺϼннϼλλͺͺͺͺ̹̹̹̹̹̹̹˸ɶɶȵǴǴǴǴȵɶʷʷʷʷʷɶɶɶȵȵȵȵȵȵȵȵȵɷ˹ɶŲƱì~dvkOwhKrcDxgIyXfõɽíưɵͻ˺Ƶ̺˹˸ʶɵȲʳʱͱͯ˭ƩæĿ~th~\\zY~[ckĪȮɯʳ˴ι͸˸ɶǶƵƵǴȵȳǲǲŰî«|crS{lK|nKqNyVkǿƧȨȪʭȱɴ˴ʳɲɲ˱ͳ˯ɭȫȫɩɩǧŤµuWsK}qI|sJ{R[}ŤŦħʯ̶Ǯʭ˫ʪɩɩʪɬʭʮʮ˯̰ͳͳ̲̲̲˱˳ʲʴ˵͸͸˵˲ʳͱͳçlnN}iHxeDxeE}lN`źĪ˱̵ʲɳ̶ι˷˵˶͸ϺллϺϺιιϺϺιι͸˷ȵɳǱëƻuoqzʿǭʹɳʴ̶ͷθͷʹ̳θκ̺ɷɹͿɸ§³rhacgnæˮϲͰȭδͶηηηηͶͶͶͶ˴ʳɲɲɲʲȯɭ˰ɬĹ{^sLoIyjCoK{Xjȫ̰ϷккϹͷͷθкϷζ͵͵Ϸζ̴ʲɱɱʲ˳˳̴͵͵ккккккккθθθͷ̶˵˵ʲæzqq|ĽƬʯ̳϶ҸѸкϺϺϺϺιιι̷͸͸͸̷˶ʵʴɳʴ˵˵˵ʴ˲ʱʱʱʯ˰˰˰̯̯ʰʰʲʲʲʲɳɳǱưıııŲǵȶȵɶʷ˸˸˸˸˸ͺͺͺͺͺͺͺͺ̶˵ʴɳȲɳʴ˵ʴȲȲȲɳɳǱĬȾu[j^DfV=eU<cS:bR9tdKgǽĩŨȫͲɱɳʴʴʴɳȲǱɳɳȲȲɳ˵ͷθƮǯǯǯǯƮŭĬĬŭƮŭëëŭȯ̱̰ǬĪũŻ}cueKeU;m^An_Bm^ArcF}oRw«ƯĭŮ«ĭîîįįįįîî­îįŰŰŰįįįǲʵʵȳŰîĬſyx[laEeV9eT6jW9ubDtVsù¥ūȭɳʴ˵̶̶̶̶˵ɳȲȲǱǱȲȲɳɳɳȲȲɳʴ˵̶̶̶̶ͷͷͷͷͷ̶̶ͷͷͷͷθθͷͷͷ̶˵˵ʴʴ˵˵ʴɳɳɳʴʴ˵̶ͷθθθͷͷʷ˸˸˸˸˸ʷɶʷ˸̹ͺͺ̹˸ʷ˸˸˸˸̹̹̹̹̹̹̹ͺͺλλλ̺̺̺̺̺̺̺̺ͻͻμμμμͻͻ̹̹̹̹̹̹̹̹̹˸ʷ̹λнϼλ̹˸ʷʷɶɶɶʷʷɶɶɶɶ˸ͺλλλλλͺͺͺͺͺͺͺͺ̹̹̹̹ʷɶɶȵǴǴǴǴȵɶʷʷʷʷɶɶɶȵȵȵȵȵȵȵȵȵȵɷ˹ɶƳȳĭ~~dxmQ{lOvgH}lN_mȺ˿Įưʶμͼɸͽ̺̹˷˶ʳʳʱждͱɫȪȩĿwi`}YzYzYmz»Ưʳ͸̷ʷȵƵƵƵȵǴȳȳȳǲǲŮŮæ|bqR{lK~pMsP\\qĠɪɩʬ̯ǰɴ˶ʵɲɲ̲ͳ̰ʮȫȫʪʪȨŤuYuM}qI{rI|SaºǦĥæ˰̶Ǯˮ̬˫ʪ˫˫ˮˮʮ˯̰ͱͳͳ̲̲̲˱˳ʲʴ˵̷͸̶̳ȱʮɯȽe~kK}iHyfF{hHpRfʿū̵̲ʲɳ̸ι˷˵̷ιлллι͸ιιιιι͸̷ʶɴǲ«Ⱥ|vwȿĩɰʴʶ̹͸йѺҸдϳϵйιɸɺƸŪ˼~tru|ƩʭˮȭδηηϸϸηͶͶηͶ̵ʳʳɲɲ˳̳˯˰ȫ·w\\tMoIzkDoK|Ykɬ̰ζϹкϹͷͷϹѻϷζζϷии͵˳ɱɱʲ˳˳̴͵͵ккккккккθθͷͷ̶˵ʴʲȫĿùȾūɯȭɰʹжεθιιι͸̷̷˶˶̷̷͸͸̷˶̶Ǵɵʶʶʴʴɳɳʱʱʯʯ˰˰˰̱ʲʲʲʲʴʴ˵˵ƳŲıðĲųƴǵ˸ʷʷʷʷ˸̹̹λλλλλλλλͷ̶̶˵˵˵ʴʴɳȲǱȲȲǱĮŻw]maGhX?eU<dT;fV=}mTlǽŪǪɬ˰ɱʴʴʴʴɳȲǱɳɳɳɳʴ˵̶̶ƮǯǯǯǯƮŭĬĬŭŭŭĬŭǯ˲ʯʮƫéũƼ{atdJfV<o`CqbEo`CsdG~pSxĭʳĭǰǰ««­îįįįįî­ǿ­įŰƱƱŰŰįîîîîįįîƱɴɴƱîªuz]ujNqbEtcEzgIuWiƼ¥ĪǬɳʴ˵̶̶̶̶˵ʴɳȲǱǱȲɳʴʴʴɳɳɳʴ˵˵ͷͷͷͷͷͷͷͷ̶̶̶ͷͷθθθ̶̶̶̶̶̶̶˵̶̶ʴɳɳɳɳɳ˵̶ͷθθθθͷʷ˸˸̹̹̹̹˸˸˸˸˸˸˸˸˸ͺͺͺͺ̹̹̹̹̹̹̹ͺͺλλλͻͻͻͻͻͻͻͻ̺ͻͻμμͻͻ̺̹̹̹̹̹̹̹̹ͺ˸˸̹λϼϼͺϼλͺ˸ʷɶɶɶȵȵɶʷʷ˸̹ͺ̹̹̹̹ͺͺͺͺλλλͺͺ̹̹̹˸ɶɶȵǴǴǴǴȵɶʷʷʷʷɶɶȵȵȵȵȵȵȵȵȵȵȵǵȶƳįƱì|g}rVqTzlOsVhvɽĮƱɷнϾͻͻλͺͺ͸̷˶˴ӹӹϳʮʯͰǩü¼zlazYuUwZgxȱͶ˶ɴȵǴǴȵɶƳǲȳɴɴɴɲɲz_~oNzlI}oLsP`vťˬʭ˭̲ǰɴ˶˶ʳɲ̲β̰ˮɬʪʪʨɧǣu[wO|sJ|sJVhûȧĥ§̲ͷǰ̯̬̬˫˫̬̯̯˯˯̰ͳ̳ͳʴ̲˴˴˳ʲʴʴ̷̷ͷ̳ȮȬǪĹ}`}jJ{hHzgG|iKrTlƬ˲Ͷʲɳ̸ι˷˵˶ιϺлϺ͸̷͸͸͸͸͸͵ʳʳ̵ɲ¨õƻ¥īưǳǳɷ˶͸ϸѺҸжα˱ζθʷȹȼƼè;ɺǾ§Ȭʯ˯ηηϸϸϸηͶͶηͶ̵˴ʳʳʳ˳ѵͱʭƦs~WsMoI|jDpL}ZnɬͳθϹλϹͺθϼҼϷϷϷиѹѹζ̴ɱɱʲ˳˳̴͵͵иикикикиθζͷ̴̶˳ʴʲˮåĽƿĨƭʰʰǭǮ˲ʹ̶̷̷̷̳˶ʵɴɴ˶˶̷͸͸͸̷̷ȲȲɵʴʴɳɳȲʱʱʯ˰˰˰̱˱ʰʰʰ˳ʵ̶˶̶ƳŲıððıƳǴ̹ʹɸɶʷ˸̹͸͸͸͸ͺͺͺͺͺͷ͵͵͵͵̴˳ʲɱȰǯǯǯƮªƿy]peIi[@dV;dV;gY?u[qǽƪǭɮʯʲʴʴʴʴɳǱǱɳɳʴʴʴ˵˵˵ƮǯǯǯǯƮŭĮíĮůůĮưɳ̶ʱɮƫƩȫȿ}`teFfW8paBsbDq`DtcGpSxǯ̵Ȱʳɱ«ëŲǱƳȲǲǱǱưýſ¬ıŲƳƳƳɳȲƱƳŲƳƳǴ¯ŲȵȳƱ­ǿr~b~uXqVvY|_gzżæŪǬǯȰɱɳʴʴɳɳ˵ʴȲȲȲȰʲ˳˳ʲʴɱɳʲʴ˳ͷ͵ͷ͵ͷ͵ͷ͵̶̴̶͵ͷζθζ˵̴̶ʹ̶ʹͷͷͷ̶˵ʴɳɳɳɳ˵˵ͷθθζθθʷʷ̹ͺͺͺͺͺ̹˸˸ʷʷ˸˸̹ϼϼλλͺ̹˸˸̹̹̹ͺͺλλλϽϽϽϽϽϽϽϽ̺ͻͻμμͻͻ̺̹̹̹̹̹̹̹̹ͺ̹˸̹λϼλͺѾнλ̹˸ʷɶɶǴȵɶʷ˸̹̹̹ʷʷ˸̹̹ͺͺͺλλλͺͺ̹̹̹̹˸˸ɶɶɶɶɶɶɶɶ̹˸˸ʷʷɶɶɶ˸ʷʷʷʷʷʷɶĳʹɷï¬©ojc~bjyƾðǴ˸λнҾϻϻϻϺλͺͺιϹζ͵˳ɱǭƬūü»pfcfnzūͳͳ˴ʳɴɴɴɴʷʸɷȴȴɵɵưĮ¢qzWykHvfBzjFpN_wƩȬʰʲʵ˶˶̷̵˴̲˯ˮ˫ʪɧɧǣĠpZzQxOyP\\hĤħƬθλʴ̯̬̬̬ˮˮ˯˯˲˲˲˵˵̶˸̶˶˶˵˵˷̸ιιй϶̲˯Ǩ¹y_~mO{jLwfH{jNy]wʰʯʰ˳ͷͷι̸ι˵ɵ˷μоѾϼнϼϹθ̴̱ˮʭ˱ʰǫɾǽīɲʷȷǶƶʴʹ˵ʳ˴кϹ˵̶ʴȲɳ˵̶ɴƭäťæ˽ɾɾ¦èƫʰ˱̲˴ʳǰɲ˴ͶηηηͶηηηͶͶ̵̵ͳαί̬ģkzRpHnF}kE~nJ~\\yŪ˵λͺ̻ͺ̻λνнйϸηηϸϸͶ˴Ͷ̵˴ʳʳʳʳ˴Ͷϵηжϸϵηδ̵δͶδͶͳ˴˱ͰȫħæŨǪƬĪʰ˱̴˳ɱʱ˵ͷ̵̵˶˶˶ʵʷʷʷ˸͸͸͸͸˴ʳ˳ɱǱƮȰʲʲʲĬŭƮȰɱʲʲʰ̰̰ʯ˱ɳɴȶɶƴƳİŰůȮɰʳνͽ̼ʸɶʷ˵̴̴͵ζθͷ̶ɶɳʳͳδжϵδ̲ʰʰ̲˱ȮȮʰƬsxTqiEj_?dY9h]?qfJ|bĩɰ˱Ŭ̳ʲʲɱɱʲʲ˳ɱɱɱʲʲ˳˳˳ůưǱȲȲȲȲǴŲƳǴŲññƴɶưɱƬŤ}{Use>k]6o_=p]=fS5q]B~fþưȲĮíĲƲǵʶɶɵǳƲűƲǳȵɶɶɸȵȴɵɶʸɷȶƶŵƶƶŴȵʵǲû|wvzþŨŨæŧŨūǭ˱̴ʲȰ˳иζ͵̴˳ʲɯɯɯ̲̲˴̲˴̲˴̲˴̲˴̲˴̲˴̲ʳ˱˴ͳͶδϷжεͲʹβʹβͳ̳θͷʴɳȲʴ̳ε˲̳ε϶зϴεʹ̶˸˸˸˸̹λλ˸ʷɶȵȵɶʷ˸λλͺ̹̹˸ʷʷʷʷʷ˸˸̹̹̹оооϽϽϽμμ̺̺̺̺̺̺̺̺̺̺̺̺̺̺̺̺˹̺̺ͻͻμμϽϼλͺ̹ʷɶȵǴŲƳȵɶʷ˸˸˸ʷʷ˸̹̹ͺλλϼϼϼλλͺͺͺ̹˸ʷɶɶɶɶɶɶɶɶ˸ʷʷʷɶɶȵȵʷʷʷʷʷʷʷʷƶ̺˹ůĮŬĺ}ytt|ƽñǵʷͺмѽммллλͺ̸̹θ̵˴ɲȱƯĭìǿŽºrqt{é̲ͳ̲ʳʳɲɲʵʵ˹ɷȴɵʶɵǱůjvSwgCsc?wgC~nJbzĵåƬʮ˴̴ʵ˶˶̵̵̲̰ˮˮ˫˩˩˧ɥşmWxOwN{R_m¢çƮθϼ˵Ͱ̯̯̰̰ͭͭͭ˲˲ʴ˵ʷ˸˸˸˷̷˶̶̸̸ιηѸеͳͯȩúy_~oP{jNwfJziMy]wèȮȭȯʰ̴ͷηͷɲǱȲ̸оѿпνϼϼλͷʹ̱̯̯Ͳ˱Ȯ¨ǽĻŻƼǮʱϺѾп˵̴˵ʳ˶кϻ̷͸˴ȯɰʰˮȬƩǪɬʭɬǪǫȬʭɮ˯̲ͳζζθθɲʳ̵ηηηηͶηηηͶͶ̵̵ͳҵѰͭĠhwOmC~kC{iC~nJ^|ɰϹλͺ̻ͺ̻λνнйϸηηϸϸͶ˴Ͷ̵˴˴ʳʳ˴˴δϵϵжжϵϵδͳδδδδͳ̲˱αɬŨŨȫʭȮǭ˱̲͵̴ʲʲ̶θ͸̵̷̷˶˶˸ʷ˸̹͸ιι͸̵˴̴ɱǯǯɱʲʲʲŭƮǯɱʲ˳˳˱̰̯˰˲ɳɵɷȶǵǵƲůƭǬɮ˱μ˾ʺȶǴȲȰȰʰ˱̴͵̶˵ȵȲʰ̰βϳϳβ̰˯ʮ̰̰ɭɭɭĨĽl}uPqiEmeAkbArgI|qUoüèŬ˱̴Ȱ˲ʲɱɱɱɱʲʲǯȰȰɱɱɱʲʲʲʲʴʴɳȲǱƳȵȶȶų°ñƶɷǴɱūƢÜz}Suh>k^4k\\5kX7gR3ydIoĮí¬íůŲƲǴɵȴǳűŰƱǲǴǴȵȶǶǶƲƲȴɶȶȸƹŸƹƶƵɶʵɲŮ¨ÿǪɬŨ£ħŨƬȮǯƮȰ̴ζ͵̴˳˱˱̯Ͱ̲̲̲̲̲̲̲̲̲̲̲̲̲̲̲̲ʱʱ̲̲ͳδϵϵͲͲββδβϴϵϸͷ˵ɳɳʴ˵ʹ̳ʹε϶зϴγεͷ˸˸˸˸̹ͺλ̹˸ʷɶɶʷ˸̹λλͺ̹̹˸ʷʷʷʷ˸˸˸̹̹̹оϽϽϽμμμͻͻͻͻͻͻͻͻͻ̺̺̺̺̺̺̺̺̺̺ͻͻͻͻμμλλͺ̹˸ɶɶȵǴǴɶʷʷ˸ʷʷʷʷ˸̹̹ͺλλϼϼϼλλͺͺͺͺʷʷɶɶɶɶɶɶɶɶɶɶɶɶȵȵȵȵȵɶɶʷʷ˸˸̹ʺμ̺ǱưɰĹƽñƴɶ̹κϻѻккϹκ͹̸̸̶˴˴ʳȱƯŮĭì«««ƾé̵̵̲˴ʳɴɴʵʵͺ˸ʷ˸˶ʵȳƱ˾drOueAqa=vfB}mIe}ƷƨȮ̵̰͵ʵ˶˴̵̵̲̰ˮʭ̬ͫάΪ˧ǡoWyPyP}Tcqçǭθϼ̶Ͱ̯̯̰̰ͭͭͭ˲˲ʴ˵˵̶˸˸̶Ͷ̵̴̶ͷηϸѸеδͯɪ¹x^~oPziKudFxgIyZvæȬɬȭɯʰ˲˲ʲƬƭȲ̶мпϾμλͺͷʹͲγͳ̷˷˷Ȳưưȯ˲Ȳʶ̹ʹɺǻȾʻʷ͵̶ʳ̷кϻ˷ϸη̳̳̲̰ʯɬʯ̱̱ͱ̰˱ͳе϶жηϷθϹϹк̵ͶηηηηͶͶηηηηͶͶͶδӶұͭĠhwOmE~kC~lFuSi¼̳ѻϹ͸ͺ͸ͺιϼлѺϸηϸййϸͶͶͶ̵˴ʳʳ˴˴ͶηηϸϸηηͶͶͶͶͶͶ̵˴̲ϲˮƬǭʰͳ̴ʲ̴͵θ̶˵˵̹θϹθθθ̹̹̹˸̹ͺͺλϹθθͷ̴ʲȰȰʲ˳ʲɱƮǯȰʲ˳̴̴̲ͱͱͳ̲˴ʵʷɸɸʷɴȱɯɭʮɲ˹ɼȸƴŲůŭūȮɯʰ˳˵ʴȲǯɯʮ̰βϳβͱͱʮͱͱʮɭȬh~vRvmLxmM|qSz\\iŬŮʲ̶ʲʱɱȰȰȰȰɱɱƮǯǯȰɱɱȰȰ̴̲˳ʲȰǯƮůȲǴŲð¯ðǵʷʴʲĪŤ{}Swj@i\\2fW0gW5kX8qV~ȽªëĬŭƮŲǱǴȲȲưĮíưǱȴɵɵɶȵȵưǱȲȵɷɷɹɹƷŴŴǴȳȱƯūƿƿüüƿħȪ˭ɫĦŨƩƬǭȮʰ˱̲̲˱˱ʰʰʰ̴̴̴̴̴̴̴̴̴̴̴̴̴̴̯̯̲˴ʱʱ̲̲ͳδζζ̳̳̳ʹϷϵииϸ͹˷ʶɵʴ˵̶˵̶ͷθθ϶϶εͷ̹˸˸˸̹ͺλͺ̹̹˸˸̹̹ͺλλͺ̹̹˸ʷʷʷ˸˸˸̹̹̹̹Ͻμμμͻͻͻ̺μμμμμμμμ̺̺̺̺̺̺̺̺μμͻͻͻͻ̺̺ͺ̹̹̹˸˸ʷʷɶɶʷ˸˸ʷʷɶʷʷ˸̹̹ͺλλϼϼϼλλͺͺͺλʷɶʷʷɶɶɶɶȵȵȵȵȵȵȵȵȵȵǴȵɶɶ˸˸̹ͺ˻ͽ̺ȴȲʱƫȾżżĺŻƼɿîȿĲƴɶʷ̸͹θθθθθθθθ˴˴̵˴ʳɲǰƯŮììĭŮƯƯūüžǭ̲Ͷ̵˴ʳʵʵʵ˶λ̹˸˸˶ʵȳƱ̿`~pMwgCsc?wgCoKg~ȹƨȮ̵̰͵ʵ˶˴̵ͳ̲̰˯ʭ̬ήѯѯͩǣÝs]VW[jwĤũɯζλ̶αήήήͰͰͱͱ˲˲ʴ˵˵̶˸̶ͷ̶˵̵̶ͷͷηзϴͳ̮Ǩx|Z}nOxgIraCveGxYvĦȬʭʭɭɬȫȭȮɭɮ˲̶Ϲѽҿμͻ̹˸ͷεзϹ˺ʼʺʺ̺͹ϻѽ͹μнν̽ʾ˿̾˸ζ̶˴̷кϻʶͶͶʹ̲ͱͰͰ˯ʮ˯ʰʯȮʯ̱ϵϵδ͵̴̶ͷθϹϸϸϸϸηηͶͶηηηηηηηδгбͭšlySnFlGsM_xé̴θι͸͸͸͸ιϺлѺйηηйййηηͶ̵˴˴˴˴̵ͶηηϸϸηηͶͶͶηηͶͶ̵˴ϵ˱ɯʰͳжϷ͵͵ζθͷ̶ʷ̹λλϹϹθͺͺ̹̹ͺͺͺλϹθθθ͵˳ɱʲ˳˳ʲɱǯȰʲ˳̴͵͵͵ͳͱͳ̵˶˸ɸɸ˺ʹ˸ʵɲʰʰɲȶǷƴƳưŭūūǭȮʰ˱˳ʴɳȰȮʮ˯ͱββββ˯βϳ̰ʮǫ~m^|[ajxƼĭĬíǰʵʲǱȰȰȰȰȰȰǯƮǯȰɱʲɱɱȰ˱̯ʰȮȮǭǭǯƮůí¬íưɶͷ˵ʲū¥ģļuyPuiAi[4gW3l\\:xeEgɷƭŭëëĬƮƮŭǲȰȳɳȳȲŰưíĮůǱȲȲǴȲŭƮƮǱƳƴǵƴƵƳıįìĪĪĨĨǫʯ̯ȭŨæĤ¢¢ýýſ¢¤ŨūƬȮ̲ͳ˱ʰɯȮȮǭǭɬȮ˳˳˳˳˳˳˳˳˳˳˳˳˳˳˳˳˱ʱ˱̲̲ͳ͵ζ˲˵̵͸ιϺллϻκ̸˷ʶʶ˵˵̶̶ͷͷθθθθͺ̹˸˸˸̹ͺͺͺͺͺͺͺͺͺͺͺͺͺ̹̹˸˸˸˸˸˸̹̹̹ͺͺμμͻͻͻ̺̺̺ϽϽϽϽϽϽϽϽͻͻͻͻͻͻͻͻϽμμͻͻ̺̺˹̹̹̹̹̹̹̹̹˸˸̹̹˸ʷɶȵ˸˸˸̹̹ͺͺͺϼϼϼλλͺͺͺϼɶɶʷʷʷɶɶȵȵȵȵȵȵȵȵȵȵȵǴȵɶɶ˸˸̹ͺ˻˻˹ȴǱɰȭĩħħèĩīê¬î¯ñųǵɶʷʷ˸ɳʴ˳̴͵ζϷиʳ˴ͶͶͶ˴ɲǰǰŮ««ŮǰǰȮɯǫũĨĪƬɯʰͶ̵˶˶ʵʵ˶˶λ̹˸˸˸ʷȲưɼ{}Z|nKwgCtd@vfB~nJg~Ǹƨǭʮʳ˳ʳ˴˴̵ͳ̲̰˯ˮͭϯѯҰΪȤşxhfimy¼ Ȩɭ˱ζͺ̶αΰΰΰͱͱͱͱ˲˲ʲ˳˵̶̶̶͵ʹ̴̳̲ʹʹʹεγ˱˭ŦtxX|mLvfEp`?ueDyZwãǩʫͭˮʬʬˮͯͰααͲͷκҿμͻ̺˸̸θкнɽȿɽʾ̾ͽϽϽʸ˹̺˻ɹɻʼ˻ͷϷͷ˴̷кϻʶȲȲɱʰʮʭʮ˯˱Ͳʹͳʱʰ˱͵̴̴˵ʴ˵ͷϻкййϸηͶͶͶͶηηηηηηηжͰͮ˫¡jvR{lEmIxTkƽɯ̴˵ηͶͶͶͶηϸйѺϸͶͶϸййϸηͶ̵̵˴˴̵̵͸ιιϺϺιι͸͸ιιιι͸̷˴Ϸ̴ʲ̴Ϸѹкθͷθͺ̹˸ʸ̺λϻϻϻκκκ͹͹κκκκκκκθζ̴˳˳̴̴ʲɱǯȰʲ̴͵͵ζζͳͳ͵̴̶ʷʸʸ̺̺˸̶˳˱ʰɱĳĵŴƳǲǰȮȮǫȬʮ̲˴˴ʵɲɯɭʮ̰ͱͱββ˯βϳͱ˯ɭ|sr{ʾ¬ŰĮ®ŰǲȱǱǯȰɱɱȰǯǯǯȰʲ˳̴˳ʲɯͱ̯˯ʮʮʮ˯̲ȮŮì«ĭǰʵ˴ɲɲǭħ£pwNwkCnb:pb=xjGtSsųƼü»üƿ¨¨ĮǭůǰǱȱǱǰǿìŮƯƯƯĪĪĪììîððȵǴŰ«èȫ˯̭ǫ£ƻž¦çƪ˯˯ȬʮɭȬǫǫǫǫȮ˳˵˵˵˵˵˵˵˵˵˵˵˵˵˵˳˱˯˱̲˴˴̶ͷ˵˷̸ͺλϼϼнϻͺ̹˸ʷʷɶɶ˸˸˸˸̹̹ͺͺͺͺ̹˸˸˸̹ͺͺͺͺλλͺͺͺͺͺ̹̹̹̹˸˸˸˸̹̹̹ͺͺͺμμͻͻͻ̺̺̺ϽϽϽϽϽϽϽϽͻͻͻͻͻͻͻͻϽμμͻͻ̺̺˹˸̹̹̹̹ͺͺͺ̹ͺͺͺ̹˸ɶɶ˸˸̹̹̹̹ͺͺϼϼϼλλͺͺͺϼɶȵ˸˸ʷɶɶȵǴǴȵȵȵȵɶɶɶɶȵɶɶʷʷ˸˸̹ʹɹʸȴǳǱǮǬƫǪƫƫŬī¬­ŲųǵȶɶʷʷʷǱȲɱʲ˱ͳδδɲʳ̵ͶͶ˴ɲȱɲƯì«ĭƯȱȱʰ˯˯˯˱ʰȮǭͶͶ̷˶˶˶˶˶ͺ̹ʷʷʷɳưĮķtvSzlIxhDsc?td@zjFg~ǸŧƬɭȱɱʳ˴˴ͳͳ̲̰˯ˮ̯ήаѯάɥšvy~ƾĠǥʪˮͳζͷ̶Ͱ̰̰̰̰ͯͯͯ˲˲ʲ˳˵̶̶̴ͳͱ˱ʱ˱ʲ˳̳ʹʹʰʭħsuU|mLvfEqa@whG}^{ŤƧɪ̬ͭɩȨ˫ήͮίϰϲʹͷлҿоμ̺˹̹κмѿɽǾǾɽ˽̼ͻ̸ʶʶʶȴǵȶ˹μθзθ̵θкϻʴ˵εδͱˮˬ˭̮γѷӹҸжϵϷϷ̴̴̶ͷθϹмѻйϸηͶ̵̵ͶͶηηηηϸϸϸжͳ˭ǪǾiwT|lHsQ^xĩδϷ̶ηͶͶͶͶηϸййη˴˴ͶϸйϸηηͶ̵̵̵̵̵͸ιιϺϺιι͸ιιϺϺι͸̷̷Ϸ͵˳̴иѹϹ̶̶ͷͺ˸ʸʸ̺ͻϻκκκ͹͹͹̶κ͹͹̸̸͹͹κθ͵̴͵ζ͵˳ȰǯȰʲ˳̴͵͵͵̲̲˳˵˵ɶɷɷʸʷ˸̶̶˳ʲʲĳŴǴǲȱȮȮǫƪȬʮ̰ͳ̵˴˴ʰʮʮ˯̰̰ͱͱ˯βϳͱ̰˯ũĽʾĬůůİîðűƱƯǱȰɱʲʲɱȰǯǯȰ˳͵͵̴ʲɯгϯ̬ɩǪƩƩƪ¦ūȮɯʰȱʰɯŨǾp~WvP}qKtQxW|^sƼƼȾ¬Įů¬¬ĮƭŭǬūƫƩŨũūūŮƱƱƳƱŮéƿüüĽǾ¤ʿź{wsruy}ççĨʭˮǪǪǪǪǫȬɭʮ˱˲ʴʴʴʴʴʴʴʴʴʴʴʴʴʴ˲˱˯˱˱ʳ˴̶̶̸̸ͺͺͽϾξξμλͺ̹˸ʷɶɶ̹˸˸˸˸̹ͻλλͺ̹˸˸˸̹̹̹ͺͺλλͺͺ̹̹̹̹̹̹̹̹̹̹̹̹̹ͺͺͺλϽμμμͻͻͻ̺ϽϽϽϽϽϽϽϽμμμμμμμμμμͻͻͻͻ̺̺̹̹̹ͺͺͺͺͺͺͺͺͺͺ̹˸ʷ̹̹̹̹̹̹̹̹ϼϼϼλλͺͺͺͺɶȵ˸˸ʷɶɶȵǴǴȵȵɶɶʷʷʷ˸ʷʷʷʷʷʷʷʷʹʹ˸˶ɴǰȮɭɭɭȮǭƯŮŰįȲɵʶ˷ʷ˸ʷʷǲǲǰɯɭɬʭʮƬǰʳ̵̵ʳȱƯǰĭ««ĭǰɲɲȮʰ˱̲̲˱ȱǰι͸̷˶˸˸˸̹̹˸ʴʴɳȲůªµptQ{mJ{kGueAsc?yiEhȹŧƬɭȱȰ˱̲̲ͳͳ̰̰˯̯̯ͭήϭάʨǣɿ¹úǿǠǣǥɩˮδζͷ͵̲ͰͰͰ̰̰̰̰˰˰ʲ˳˳̴̴̲̱̮˯ʭɭɯɯɯʹʹ˱ˮħr~sS}oLxhFseB|nKb~øƥȩ˫˩ǥûƾšɨίг϶̶͸λѿоͽ˻˻ͺноɽȾǻʻͼϼ̶˲ԻҷͲȭŭȰϷսзѸθ̵θкϹʴϹѹѷβɬƨƦǩ̰ϷӻԼӻѹккͷθθϹϹϹθθηη̵˴˴̵ͶͶηηηϸϸййѷж̮ħĻpa\\hsǼ˰ҸѹϹηδδδδϵжѷϸ̵ʳɲ̵ηϸϸϸηͶ̵̵̵̵Ͷ͸λλϼϼλλͺλλϼϼλλͺ̷Ϸ̴˳̴ϹϹ̶ɳʷ˸̺˹ɷɷ˹ͻλͺιιͶͶͶ̳ηͶ̵˴˶̷̹͹Ϲζ͵ζζ͵˳ȰƮǯɱ˳̴͵͵͵̳̳ʴʴɳɳɵɵȴɵ˷̶̶̳˲ʴǴƵȵȳǰƬĨæħƩȫʮ̰̲̲˱˯˯˯˯˯˯̰̰˯ββ̰ͱβʮçþ½ǻŮǰȲůİŰǱǱƲưǱɱʲ̴̴ʲɱǯŭǯʲ̴̴˳ɱǭ̬Ȧ ¼ƿƪɭɭʰ̲ʰ¥wifbdb}^hph~dmxŹȼʾο˿̾ȽɻƻżżżƽȾ¬íƾǿžżȽ˽˽˾oic]\\^aezƽǾƽ£Ŧ£ǾȿæƩɬ˰δʴ˶˶˶˶˶˶˶˶˶˶˶˶˶˶ʴ˱˯˱˱ʳʳ˵˵̹ͺͻͽ̿Ϳ̿ͽϽλλͺ̹ʷɷȶ̺̺˹ʸ˹̺ͽμλͺ̹˸˸˸˸̹˸̹ͺλλͺ̹˸̹̹̹̹̹̹̹̹̹̹̹ͺͺͺλλоϽϽϽμμμͻμμμμμμμμμμμμμμμμ̺̺ͻͻͻͻμμͺͺͺͺͺͺ̹̹̹ͺͺλͺͺ̹˸̹̹̹̹̹̹̹̹ϼϼϼλλͺͺͺ̹ȵȵ˸˸ʷɶɶȵǴǴɶɶɶʷʷ˸˸̹˸ʷʷʷʷʷʷɶʻʻ˺ͺ˶ǰȮɯ̰˯ɯȮƯƯǲȲʴʴ˷̸˸˸˸ʷɴȱɯȬǪȨƧǧĪŮȱʳʳɲƯĭìǿĭȱʳ˴Ȯɯ˱̲ͳͳ˴˴ι͸̷˶˸˸˸̹̹˵ȳɳȳǯìöquR~pMoKxhDueAzjFjɺƨǭɭȱɱ˱̲̲ͳͱ̰̰˯̯ˮ̬ͭήͫʨȦ˨ŻßǢǣƢǧʭαδζζ˱̯̯̯˯˯˯˯˰˰ʲ˳˳̴̴̲̬˫ʪȪɬȬȬȮ͵ε̲˱ũttT~pMzjFvhErOfżɩ̬̬ʨŽĠͮҵѶͷ˶˸оͽ˻˻̼ϼѾ˾ɺȹ̹ϺѺ϶ͰƧƻçзѸй̵θѻϹʴ˳̲˯ǪʿǺƹźĪȰζѹѹϷͷͷͷθϹϹθ̶ʴɳͶ̵˴ʳʳ˴ͶηηηηϸϸййѷҸ̯æ|ttøƩжӼҼиηδδδδϵжѷη˴ɲȱʳͶηηϸηͶ̵̵̵̵Ͷ͸λλϼϼλλͺλϼϼϼϼλͺ̷Ϸ̴ʲ˳θθ˵Ǳɶʷ˹ʸȶȶʸ̺ͺι͸ͶͶ̳̳ͱβͱ˲ʳʳ˶̷̸ϹζζζϷζ˳ȰƮǯȰʲ˳̴̴̴˲˲ɳɳɳȲȲȲǱȲʴ˵̶˵̳ʴɶɶɴȱǭĨƿ¥ħƩɬʮ˯˱ʰ̰̰˯ʮʮʮ˯˯˯ͱͱ̰ͱϳͱǫŧŧĨç¨ƬȱǰȲůĮƲɴɳǱưȰɱ˳͵͵˳ɱȰĬƮɱ˳˳ʲȰǪáľyttrvħʭˮ˱̲ɭxvsrjz]z]y_|nS{oU{apy}~÷ĵôøpc\\zUvOuNwPzS{VføƽǪʰδʴ˶˶˶˶˶˶˶˶˶˶˶˶˶˶ʴ˱˯˱˱ʳʳ˵˵λλͻͽͽ̼̿̿ϼϼλλ̹ʷɷȶͻ̺˹ʸ˻̼ξϽμλ̹˸˸˸˸˸ʷ˸ͺͺͺͺ˸ʷ̹̹̹̹̹̹̹̹̹̹̹ͺͺλλλоооϽϽϽμμμμμμμμμμμμμμμμμμ˹̺̺ͻͻμμϽλλλͺͺ̹̹̹̹ͺͺλλλͺ̹̹̹̹̹̹̹̹̹ϼϼϼλλͺͺͺ˸˸ʷͺ̹ʷȵǴǴȵȵȵɶʷ˸˸˸˸˸ɶɶɶɶɶɶɶɶǷʺͻͺ˵ɱʰ˱˱˱̲ͳ͵͵̶̶̶̶̳̳˸ʷɶɶ͸Ͷ̳Ǭ¹ļĭƯǰɲǰĭ««ìĭǰʳͶϸ˱̲˴˴˴˴̷̷ιϺϼλͺ̹˸ʷ˶ʳǱŮ¬ĪêĪqxUuRuQoK~nJuQlʬƬƪǰ˳˱˯˯˯̰ͱαϲˮ̯αаѱаϯϭΫ̩ȥƢɥͩʥĠȨʭ̯̲ζϷ˱ʰɯɯɯɯʮ˯Ǭ̱δ˱Ȯʰ̲̱ɨɦƥƦƧƩƪǪ˱˱̲ͳǫvy[}oL|lH}oLzXnͰɬ̬ĢjaqļͮӶеϹѼѾϽϽϿϿϿϿннϽλ˸͵Ҹոϯţzony̱˵̵̵ͷͷͷͷͶʰèĻ~ĮζϷ͵͵ζζζζѹӻϷȰŮɲȱʳͶͶ̵ʳʳ˴ϸηηйѺѺϸͳӹα¥ƸɾƪͲҸѺϹ͵ϸϵδͳͳͳͳδη̵˴ʳʳ˴Ͷη̵ͶηηͶ̵ʳɲ̷̷̷͸ιϺлѼιιϺϺϺι͸̷˳˳̴̴͵͵θθϹͷʷʷ˸˸ʸɷ˷̸ͷεͲ̯ˮ̯ɬʭ̱Ͳʹ˵ɵȴϹϷииϷ͵˳ʲǯǯǯɱ̴͵̴˳ɱǯƮƮȰȰȰƮŭƮǯǯȰɱɱɱʵʶɵůǽǾȿǾȿäȫɬƫè˯˯˯ʮɭɭ̰β̰˯ʮɭɭȬɭɭʭ̯̰˯ǭūììŭǯȲưƯƯȰɱ˳͵ζζ̴ʲȰǯɱʲ˳ʲȰŭŨľ~pe^~Z{ZxW^mäˬˮɰʱȭxgwY{mPzlO|nS}qW}cq{~~~qmomnu~{x~xlbxTqMtMsLoGqIxTew~´Ǽéʱʲ˵˵˵ʴɳʴ˵̶ͷ̶ʴ˵ͷ̶ʴϵͳ˱ʰɲʳɴȳƳ̹ͼȷȷ̽;ʹ̷̷͸ιι̷Ǵıͼ˺ɸȷȹʻ;νϽλλͺͺ̹̹̹̹̹̹̹̹̹̹̹˸˸˸˸˸̹λλλͺͺ̹̹ͺͺλϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺λλλͺͺ̹̹̹̹̹ͺλλλͺͺͺͺ̹̹̹ͺλλλλλλͺ̹˸˸λ˸ʷͺ̹ʷȵǴǴȵȵȵɶɶʷ˸˸˸ʷʷʷɶɶɶɶɶɷƶɹ̼̺ʷʴʲ̲δϵϵϵζ͵̶˵̳ʹ̶ͷ̹˸ʷʷ̷ʳŬ¹xpoƾĭŮƯĭ«ìĭƯȱ˴Ͷϸ̲̲˴˴˴˴˶ʵϺϺϼϼλ̹ʷɴ˵ȯƼĸ¸ĸĺjtQqNpL|lH~nJwSvæɫĪũȱ̲̰˯ʮʮɭʮʭˮˮ̯ͰͰϯϯϯϯɩȥɿǣŠŽšɧ̬̮̯̲͵˱˱ʰʰʰʰ˯˯ȭ̱̲ȮȮ˱˱ȫƤͽʻʿŦȫɭȮȮ˱ͳȮzctSuSzYh{æΰͰʬjsM{oG\\{ɪѴ϶θѼҿооѾѾѽѾѻζͳѴԴͩĞoZXf{ĸƤ̶̵̵̲ͷͷθζϵũpciz͵Ϸ͵̴͵̴һϵδϵδʰɰͳ˴Ͷϸϸ̵ʳʳʳʳʳ˴Ͷηη˴ɯϵ̯ƩǾǾȿçƫɮ̳ηϸкϹϸжϵδͳδδδ̵̵ͶͶͶͶ̵̵ηηηϸηηͶ̵ͶͶ͸Ͷ͸ηлйлϸϺη͸̵˶ʳ̴̲͵͵͵͵̴̶θ̶ʴɶʷ˸ʷȵ˸̶̴̱ˮˬʪ̫ɩ˪˭ˮʰ˲ʴɳ˳̴ζϷϷζ͵̴Ȱǯǯɱ̴͵̴ʲ̴˳ɲʰɯǪþĽ½»Ľ«ĭƲǱư©ŻúĩŪɭɭɭȬǫǫʮͱͱ̰˯ʮɭɭɭɭʭˮʮȬé˿˽ɻǸɻʻȼȼȾĪƮǯʲ̴̴̴ʲɱȰɱ˳˳ʲȰŭçtb|XyU}Y\\hpúĥȩȫƫȯȭŪżĻƽr~^|qS{pRwY~bv÷ǻ̽οôyf]]~[^hw}|}ti[vOuNrJmEqFxQh}{rilpwĶȰȱ˲ʴ˲ɳʱɳ˲ǱǮůƭǱ˲ɳǯ͵̲ʰʰʳʳʳɴɴ͸̹ǴǴͺξλ̵ͳ̵̵ηιιλ˸ʹʹʹ˼˼˼˺˹˸˸˸˸̹̹̹̹̹̹̹̹̹̹̹̹˸˸˸̹̹ͺλλͺͺ̹̹ͺͺλоооϽϽϽϽϽϽϽϽϽϽϽϽϽͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺λλλͺͺ̹̹̹˸̹̹ͺλλλλλͺͺ̹̹ͺͺλͺͺͺλͺͺ̹̹ͺ˸ʷ̹˸ɶȵǴǴȵɶȵȵɶɶɶʷʷʷ˸˸ʷʷɶɶȵȶƶȸʺ˹ʷʴ˳̴δδζζ̶˵ȵȲ̳ͱʹͷ̹˸˸ʷʶȯǻj{UsKsMwûŮǰƯĭ«Ůǰʳ˴ͶͶ̵̵̵˴ʵʵɴɴλϼϼнν̻ʹɵǯʾ{etQqN~nJ|lHsO\\ĵŨɫĪũɲͳβͰ̯ˮʭɬɬʭͰ̯ˮˮˮ̯αаʪãĺǽǿûĠɧ̬̯ͯ˱˱͵̴̴˳˱̲̲ͳʯ˰ɯǭɭ˯ƪ̾Ĵ|}¥ǫǭǭɱ̲ɯpdfo~žɬαγǪm{qNeY3hZ3qLoŦгε̶ϺѾϽϽϽϽнммккзγ̯ϯѮɥz]ypG~uJh˨δͷ͸̷ͷθϷиδǽkvUrP[m̵η̲˱̲˱Ѹʯƫȭ˰˰ʰ̱ϵйѺϸͶ˴ʳ˴˴˴̵ηйϸ˴ʰͳ̰˯˯˯ͰϳѵͲͳ̲˴˴̵͸ιηͶ̵˴˴˴˴̵˴̵ηййη̵ʳͶͶ̵̵̵Ͷηη̵ͳ˴̲˴ͳͶδѺѷηͳ˴˱ɲʰ̲αδδͳ̲ʰɱ͵˳ɱʴ˵˵ʴɳͷ̴ʰɬȨȥȤɤšǢȦɩʮ˱ʳ˳Ȱʲ̴ζϷζζ͵ɱȰȰʲ̴͵̴ʲʰʰɰʮŪƿŻííƺ~zuvzȫƪƪƪũĨũȬʮʮʮɭȬȬǫƪƪǩǩħƻüªƮɱ˳˳ʲɱʲʲ˳̴ʲǯĬ¦o~Z|rO}sP~[exƻåĨ§êŪƫŪħ¥nxYypQwXguùĽƼüǽƿæ¥®ðı̽ȹów_uQrNqOwTauŹƺźƻļûvf}VxQrJnCpFxRkŶye}V~Y\\dp̼ūǮȮǰȮǰȮǰȮƯĪĪǰ˱ʳʲʲʲʲʲʳʳʳ˴ɳɳǱ¬íɳͷͷ̱˰ʱɰʱ̶Ϲѽȴʸ̺ͻ̼ʺȺȷȶȵɶɶʷ˸˸̹̹̹̹̹̹̹̹̹̹̹̹˸̹ͺͺλλͺͺ̹̹ͺͺλооооооооϽϽϽϽϽϽϽϽͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺ͺͺͺͺ̹̹̹̹ʷ˸˸ͺλϼϼнλλͺ̹̹ͺͺλ̹̹̹ͺͺͺͺͺ̹˸ʷ̹˸ɶȵǴȵɶɶɶȵȵȵȵȵɶɶ̹˸˸ʷɶɶȵȶǷǺɹɷʸ˵̶̴ʰʰʲʲɳȲƳǱʱ̰˲̳ʷʷʷɴ˷ƭy{XvjBuh<xlDnŽʳ˴ʳǰĭǿĭǰɲʳʳʳͶ̵̵˴ʵɴȳȳ˸̹λнϾν̻˷̾zey\\~^irtdwTsPoK~nJzVeǸƩɫūǫɲ˱ϳϲαͰ̯̯ͰͰгαˮʭʭ̯αг̮ʿ|~ûþÝȦ̪̮̯ͯ˱ζ͵͵̴̲ͳͳδʯʯȮȬ˯ɭȽwg[\\ożƩ˱ɯȰʲɯƿɿȮγ϶ʱĩgsiFbT/hY2qLoƩϴ̶ʶͺн˹˹˹˸̸̶̶̶˵ʹ˰ʭ̮ΫȦſg{T\\xŸȥήϵθ͸̷ͷθиѹʰŻiyX|Xg|ìͶδ˱ʱʱȭǬʿǼ¥ʭ̯ʭʮʹηϸη̵˴˴̵̵̵Ͷϸйϸ̵˱δβϳддѵѵѷжη̵ʳʳ˴̷͸̵˴ʳɲɲɲɲʳͶͶηϸϸη̵˴ʳɲȱǰȱʳ̵Ͷͳ̰˱˯ʰ˯˱̰Ҹѵϵ̰˱ʮʰʮαϱггϲͰʭȮ̲˱ʲ˳̴̴˵ɱʳǭǾſǿþǥʭ̵̰̳ɱ˳̴ζϷϷζ͵̴˳ʲ̴ζζ̴ɲīĩéħɾwuuy¶ʾȼ{lb]~[}]cs·ħɿĨƪũĨĨç¦½~uursqwüľªƮɱʲʲʲʲ˳̴̴ʲȰĬ¦¹v`uRuR^j{Ĺø·ǼŻƼȾ§ĩ§Ⱦżqa}^hx»ž¨ĪȪǪĪ«­°ñò±οʺ~dwSsMsQxVdyȺ̽ʾʿ­«ſý··öp\\{TtLpEsI|Vnȹ;yb|R{TzS}XdyʺĪŪĨɿƿǽüƼüǫʱδǯȰʲ˳ʳ˱̲ͳ˲ɮŪ§ūǭȬɬʭʭʭȭɰ̳ͷ̶̸͹μ̼ʺǷǶɶʷʷʷʷʷʷʷ˸˸̹̹̹̹ͺͺͺͺ̹̹̹ͺͺλλͺͺ̹̹ͺͺλоооооѿѿѿμμμμμμμμͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺ͺ̹̹̹̹̹̹̹ʷʷ˸̹ͺϼнѾϼλͺ̹̹̹ͺͺ˸˸˸˸̹ͺλλͺ˸ʷ˸ʷɶȵǴȵɶʷɶȵǴǴƳǴȵȵ̹˸˸ʷʷɶɶɷȸȺǷɶʷ˵˵̳Ǯȯɰʱʴʴɵɳɭʮʱ˲ɶɶɶɴʶªswRxkA{m@tMr̵Ͷ˴ɲǰǿìƯȱɲɲȱ̵̵˶ʵɴȳȵǴǴɶ˺νϾϾͼ̸ŷcvgFm]<teDwVcmaxUrO~nJpL~ZjȹƩʬȮʮɲɯͱ̯̯̯̯ͰαϲѴϲ̰ʮʮ̰ϳѴȪ{fh{ţʨ̮ͯαδζθ͵͵̵̵δδɮʯʮ˯̰ǩiXsKtMdƽˮѷͳɱȰǰŮƾ¶ɸɸ˼¦ȯ͵ϹйưŬpvTtfA{iC~Z}ɰϹ˵ʶ̹ͼʸʸʷʷ˵̳̳̳ʵ̷˵˲ͳвˮťxɭδзϸι͸θϹиѹɯzpuȶ¦ɰε̱ʯǭéʿο̭ϰ̭ȫɰʳ̵˴˴˴̵η̵˴˴̵ͶͶ˴ʰδϳдѵѷжϵζζθϹϹιϺϺϺ͸͸̷˶˶˶˶˶йϸͶ̵˴̵̵ͶȱȱǰƯǰȱʳͳβαͱ̯̰̯ͱͰдϲͱ̯˯ʭɭɬϱϯввϱΰ̮ˮ̯ˮʰ̲ͳͳ˳ɯêƼ~ťʫʰ˲˴͵ζϷϷζ͵̴ζ͵̴͵ζζ̴ʰūĨͿƻtk^^`iwȼªȼozZxnKzpMyoKzpMuRauüƿƿƿƿžĽ»ziz[z]xYwZyYcpýŭȰʲʲɱʲ˳̴̴˳Ȱŭçȿn_zZ`hux}~zùǽǽĺ|zžſªëŭȰ˳ˮʭɮǯƳƵȷȸĴ±οĶhzVvOtSyWd{˽®ıŰǱưůƭƮūĪ¦ȿɾɾt_}VuMqIxM[uͼξxbT{RxOxT`w˺˿żz}̱ìǱʲ˳ʰʰ˱ͱϴʭĦ̿ʿĥɪ̭Ͱ̯̱ʹзθ͹̸ʸʸɷʷλλͺ̹˸ʷʷɶ˸˸˸̹̹ͺͺͺλλͺ̹̹ͺͺλλͺͺ̹̹ͺͺλϽϽϽооѿѿѿμμμμμμμμͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺˸̹̹̹̹̹̹̹ʷʷʷ˸ͺϼѾҿϼλͺ̹̹̹̹̹˸˸ʷʷ˸̹λϼϼ˸ʷ˸ʷȵǴǴȵɶʷɶȵǴŲŲƳǴȵʷʷʷ˸˸˸˸˹˻ɻǷȵɶʶʴʱȯɰ˲̶̳ͷ͹ͷɭɫʯ˲ʴʷʷɴȵv\\{OS]«ʳʳɲȱŮìŮǰȱɲɲ˴˴ʵʵɴȳȵȵƳȵʹͼνͼ˺ɵô{yYm];eR1n^:rQ`i`xUsPpLvRbq²̽Ǫ˭ʰ̰ʳȮȬȫȫɬɬˮ̯ͰѴϲ̰ɭɭ˯ͱϲçubbvĠǥɩ˭αϵζͷ͵̴˴̵ͳδȭʯ˯̰ͯǩk\\{Q}VhȽʭչϵʲȰɲ˴ʳȯǭƪūǭɳͷκιƲʱr`_pȾ̶θʶʸ̻ͼ̺̹̹ͷεγγε˸λнϹѻӻѷ˯ȼ·õɻ©ǰɳ͹̶ͶιιϹϹζδɰǫͿôȴԾĠʭͲγ̱ɯĨø~|ɹʩϮ˫ɪȭɲʳʳʳ˴ͶйϸͶ˴˴̵ηηδ̲ͱϳдѷѷиϷ̶ͷкҼҽҽҽѼѼѼнϺλϺϼϺйη̵ʳɲʳ˴Ͷɲɲɲɲɲɲʳ̲ϳααͰααϲϲ̯̯̯ˮɬƩħĤɩɩɩɩʪʪ˭˭ʬʭʭ̯αͳ˱ȬƼ}wupnnsĺũǬ˱̴͵ζζ͵̴˳ζ̴˳̴͵̴ʲȮɯæǹqbXvPyS~[gw´ʼūëʾj}sPmc@ukGtjFsiFvlIuUg|žƿƿƿĽ»s{\\zkLzkLyjKxiJ{lKxYjüſªƮɱɱɱɱɱʲ̴̴̴ʲǯū£Ƽ|necekd}_z\\tXtXgyùȾ©©§ĽýþĬȰ˳͵̮˯ɰȲǵɹʻ˼ŷĳƸeuQ~nJmLqQ}_wͽ­°ıƳǴɳʴʴ˵ʲȰƬĪ¦ɾv`|UtNqIwO\\yʹǷn^TyNvKyRdzǶɹvplhdz^w[{_kvȭ«Ǳ˵̴ʰɯʮͰαĥĹȧʫˬ̯̱˰ʱɳɵɵɷʸ̹ѾѾнλͺ˸ʷɶʷʷ˸̹̹ͺλλϼϼλͺͺͺͺλλͺͺ̹̹ͺͺλͻͻμϽϽооѿͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺˸˸˸˸̹̹̹̹̹˸˸˸̹λнѾнϼλͺ̹̹̹̹̹̹ʷʷʷ˸ͺλн˸ʷʷʷȵǴǴȵʷ˸ʷȵƳııŲƳǴɶɶʷ˸˸̹̹ͻͿʼǷǴɶʶɳǱʱ˲̳ʹͷ͹ͺͷʮ˭˰ʹ̶̷̹̹ƳªƸxopzļƯȱǰȱǰĭĭĭŮƯǰɲ˴̵ʵɴɴɴɴɴɶɶȵʷ˺ͼ̽ɺƷ¯±x{Zsa=kW4vd>wTbog]}Z~Zduͽģʭʬɯͱ˴ɯɬʪɩɩȫȫɬʭα̯ʮȬǫȬʮˮũøvwÝĠţƦȨ˭α͵ͷ̶̶˴˴ͳͳʯ̱̰˯̮ʬʿysorʿȫӷϵ˳ʲ̷ϺлзɯǫƬǯʵʷʷɶȳθǯ¹ðͿȲͷ˷ȶʸͼνͺͺͺθ϶ϴϲ϶ͼѾѾҿϺʳưĮƱ˸̺ɹǸɹɵ̷͸Ϻкθ̵˱ɰβήǤĠơʣʤ̬̰˯˯ɮ̾qbdsѾŤƥǦɯ˴̵˴ʳ˴ͶйͶɲŮĭŮȱʳ˱ɯʮ̲δϷϷϹϹʶ˷̹ͺϺлллҿѾϾϼνϼνϼͶͶ̵˴ʳɲɲɲȱɲɲɲɲȱȱȮʭʪʪʪ˫̬ͭή˫̬˫ʪƦ¼ÿãǧǩȪʬ̮̯ɬƪǻumkfcfhnwȺǭȰʲ˳̴̴˳ʲ˳ʲɱɱʲɱƮĪ§ȹ|na}VyOyR~Wdt˼§ǭŭźouRmc@pfBnd@lb?ndAxmMaz»žĨĨũũçĽÿ¼v{ZvgFueDtdCueDykHyXmøªŭȰɱʲɱȰȰɱ˳̴̴˳ɱǭǨ¢Ĺxsoe~sUodHh]AeZ>mbFy_yùêêêīƭũç¥æƦǧǤĤſþþíǱɳ˵ɭȬƭƯŲƶƺǻŷóŷboKwgCyfE|iItVo˻­¯òĳǵȵɵɳ˵ʱȯǬƬũǾt^yRrK}nEsK}YsuaT{N{NzOZmsex[uXuXtWrU{mPxjM{mPuX{^hƺȲͷ͵ʰȮȭˮɾ{rkfbfoz¹ĻǾȾêưɵʶ˷̷ннϼλͺ̹˸˸ʷʷ˸̹̹ͺλλнϼλͺͺͺͺͺλͺͺ̹̹ͺͺλ˹̺̺ͻμϽооͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺ʷʷʷ˸˸̹̹̹λͺ˸˸˸ͺϼѾнϼλͺ̹˸˸̹λͺ˸ɶɶʷ˸ͺн˸ʷʷɶȵǴǴɶʷ˸ʷȵƳıðıƳǴȵȵɶʷ̹ͺλμϿ˽ǷƴǴȵȲưʲ˲̳̳˵ʴɵɳ˰̯Ͳ϶θλλλǳƭ¨ɾǺŹǼȿ¥ǰʳȱǰɱɱưȲȲǱȰɱ˴Ͷϸɳȵɶʴʴʴʴ˵̶ͷλλ˺Ƶʾ¯x}[|eCt^9}iD{Ve{rjgmyɺǨˮ̯ʮʭ̯Ͱˮή̬ͭʪɬɬɬɬˮʮȬǭƬƬǭȮͲƩøǾĠĠĠšĢĤťɫ̯͵̶˶ʵʵ˴˴ͳ˲Ͳ˱ʮ˯̰ǫ̿ɺʹȹɺ˽àǨʭдδ̴̴ϺѼҽкŬĪūƮɴɶǴƲȲҺδƪƩģɨʰιιɴȵ̹нѾ˸̶̶̴̲ͰͯͲͺϼλк̵ƯϹͷλ˾ŻŸȶʵ͸ϺϺθʳɲɯеԸаέѯѭͬʮʯɮʮɬɺx|ZmLtPazƲмģͳϵϵͳ̲̰βϴ§Ⱦù¸ŻȾȬȫɭ˯˯̰̲̲ǰǰƯǰȱʳ̵Ͷϸη͸̵̷̵̷Ͷʱ˰̳ͳ̲ʰȮƬǭǭȮɯȮƫī§æĤĤĤťǧȨɩʪ˫ʪȨã¼ĤĤŨǪʬʭǪĨ˿xqnieecdivǼ¥çƪɯʰ˱˳ʲɱȰƮƮǯƬéķ{j_}VyRwP[et̿ŨȭǭȯĪɾtxXsfDl_=j];h[9j]=wjJcĺüĽĽĽž¨ūʰʰ˱˱ɯƬé¥ģƦĢ|~]whGtdCtdBueC|nK~[s¨ĬǯɱʲʲȰǯǯȰ˳̴͵̲ʲɯαʫäĻzawlLbW9ZO1\\Q3m_B~cĺƭƭ©©ƬɯǪĨŧȪʩƦŦůȲʴʴɰȯǰűŲŵŸŹĵñŷb~nJxfBwdCyfFpUnʺ­¯°òòųųƳƳǳ˴ɲǮȯɯɬ§ȿs^vQ~nJyjCnHxTg{l\\|RyMVXdzi_qRxkK{lMrRtUvVzkLuhHvgHxkKxiJ~qQnȴ̹ͷɱǭǬˮx`vS~pKykDzkD}oH[gt{Ⱦůʶͺͺ̹λλλͺͺͺͺͺʷʷ˸̹̹ͺλλннϼͺͺͺͺͺλͺͺ̹̹ͺͺλʸ˹˹̺ͻμϽϽͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻμμμͻͻ̺̺̺ʷʷʷ˸˸̹̹̹ϼλ̹ʷ˸̹λннϼλͺ̹˸˸˸ϼͺ˸ɶȵɶ˸̹ϼ̹ͺͺ˸ɶǴƳǴɶʷ˸ʷɶȵȵȵȵɶ˸˸˸˸ʷɶȵȵȶȶƵŲðıǲʵƯ˳ζ͵ʱŬīŬĪë̶нͺ˹λǴɳʲɯȪǧȥȦͰ˲ɯƯƮǱȲɵȳȳǳǱȲʴ˳̶˷̹ͺκͷ̶˲ʱγϴѹҺѻ˵ƺtvUx^=rZ8hF^oƺë˲ʯɮˮ̩ͭͫͪʨάϮέʫǩ˯ϳʰεε˴̷ѻϹȲʳȮŬũƩƩƦţĢ æǫɯƱǴƴǵȶɵʶʴȲȯǮǮǮɮ˰ͰʦˤˤȤǣƥɩˮͱδηͶ˶˸̹͹͵˱ʲ˲ʴʴȲǮ̳ɯ˱ϴϲɪŧȫ̵̹̹ʷɳɳ˵͵ииϸϵδϲϲдҽͻ͸Ͷ̰ʭͭҲˮʮʲ̶ͽϾκ͹͸ιϺҼӽϷ͵˴ͳϵдϳͳεεδгʭŵmsL~f@iC{Toŵ£ȬͲˮŤ¡·{ŦĥǼȨʨɦã¤¦ĨūƩɩʨ˫̪̬˩ʪɧåƦȪȩĥǾȿƩǪĥƽ¹ø¼ý¢ǧȨ˫ǧãããľzuutvĹ¦ŪƪƬǭƯ̻ŴsijouŻ¡æ˯ͳʰĭĭ«ǭʮvh\\zPtLzR_myź¦ũƬɮǭȮȭĨ{|]vgHhY:iZ;gX9hY<xhNmƺưǰŮĭĭŮǰǰͶͶ̵˴ʳȱȱȮƩɪ̮˫ƽ~|[rdAl^;oa>pb?vhEzXv£¨­îŰǰȱʳʳ˱ɯǭɯ˱˯Ȯū˱̲ʮçžút\\ob@aT2eX8{lMlƼìǰì«éƬƩŨƩƩƧĥëí­í­Įįưíí¬¬ïıƳƴƳȳŷcxhGyfEvcCxeEoSmŹ­ııƳǴȵʴʴʴưȱʱ̳̲ʭèk\\~nJ{iE|jDwc>qMxVkzsb|U{W~W_hwtuV|nK~pKn^:oa<pN_pdsRvgFueDxiHscBm^=uW}Ʊм̶˳ѷ˰ȿ|\\oNyiGxfBsa;nZ5oJxTdsvuuy|ºŰ̹μϽϽλλλͺͺͺ̹̹̹̹̹̹̹̹̹̹λϼϼϼϼλͺ̹ʷ˸̹ͺͺͺͺ̹˹̺ͻμμμμͻͻ̺̺˹̺ͻϽоμμμμμμμμͻͻͻͻͻͻͻͻʷʷʷ˸˸̹̹̹̹̹̹ͺͺλλλ˸˸˸˸˸̹λλϼλ˸ʷɶ˸ͺλϼ̹ͺͺ˸ɶǴǴȵɶʷ̹̹˸ʷɶɶʷʷʷʷ˸˸˸ʷɶɶȵɶɶǴųųȴʶɲʳ̴˳ɮǬǬǬūªɳ˸ɶɶ̹ʶʶ˶ɲȯɭʬʭ˰ʯʰɯȲɳʵ˶ɵɵ˶̷̶ε͵ͷͺ̹˸̷˴ʱ˯ʮαϴѶӺѹ˵ĮȼmoQw]<w^?rPk{÷ĸĸȼİʶηδͱ̨̯̦ͫ˥˧ϫѰЯ˭ʬ̱ϴ˱͵̳ȱɴкк̶˶ɴǰȮɯɬȫȨá ħǫʰǳǵȶȶɷʶʶʴɳȲȲȯɰʱ˲ͰάΪͩ˧ɧȨɬˮджη̵ʵʵ̹ϺεʹʹεεͲɯǫɮǬɮαϲˮʭ̱ϸкϻͷʴʴ̴ζδϵϵϵββϳд̶ɳɰ˰ˬǦɥͩʧʪ˰˵̹;Ͼκ͹̸ιϺҼӽͷ̶̶θкҼҼѻӼһϵαťixOjBjAtK`s~ũ̯ʭǾ~vkgntuź¹¹ýĿſľþŸƹŻŻúúĻ~|ƦȨ̬ɩƦƦƦ¢}uoigltĺūǭƯı̻Ƕóxsppt{ɾɬͲͳůǰĮêè¥scX}QzP|Tap}¥ǬȭȯʰǭȮȭǪƸ}_wfHkZ<jY;gV:iX<{kRrƺǳǲƱŰŰƱǲȳʵɴɴȳǲǲƱǯǭʭ̯˫ź{xWn`=j\\7l^9oa>tgD{Ywĥ«îįƱȱɲʳ˴̲ʰȮɯ˯ʮȬūƮʴʲǭĨť¡ƾl|oLh[8gX7teD{]qĭƯ«ëŭƬƫŨŨƨŧĦ§ŭîîîîįįŰî­ííİűǳȴưǰ¶bxeGxeEubBueDnRkĺîĮǳǳɵʶ˵˵ʵ˵ʴ˴˲ʹ̲ʭĩn`qO|jFzhDq]8zhBrPanj^Z^cny}bteFqa=yjCl]6sd=yUm~n}[zjHm];m];iY8hX7pOsðϺʴʴδǮĻytUziKwdDvbAua>u^<vQeq|ztquuȶ̺ξнϽλλλͺͺͺͺͺͺͺͺͺͺͺͺλλλλλͺ̹̹˸̹ͺͺλλͺͺ˹̺ͻμμμμͻͻͻ̺˹̺ͻϽоμμμμμμμμͻͻͻͻͻͻͻͻʷʷʷ˸˸̹̹̹̹̹̹ͺͺλλλ̹˸˸˸˸̹ͺλ˸˸ʷɶʷʷ˸̹λ̹ͺͺ̹ɶȵǴȵʷ˸ͺͺ̹˸˸˸˸˸ɶʷʷ˸˸˸˸ʷɶ˸̹˸ɶɶʵ̷ϸͶ̴˳˱̲̱˰ǭé«ƯɳǴǵȶͺ̸ʵɲȯʮ̰̯ɭɮ˱˱̶̶̷̷̸̸ιϺθ͵ʳʲκͺ̹ʶʴ̳ͲγͲγ϶ѻк̹ųʿouVhHpQhóĨǬȯǱȲ̸ϻ˵ʹͲίͩ˦ɢɡ˧ϭұұΰ˭˰̱γͳʯǭɯϷӺѹʵǳůƭǮȫƩĥȿǾƽƽȿ¥ŪǮȲɵʶʶʶʴɳɳʴ˲ʱʯʯ˰̱αͬέͬ˪ɪȩɬʭγγʹɳǱǱʶͷ̳˰˰˰̱ʯūçɾ˽æãĥȭжиϹ͵ʲɱʲ̴Ͷ̵ͳͳͳͳͳͳëæâĠȣ˨Ͱʹʶɹ̽нκ͹̸ιϺѼҽкθθθкѻкϹѻз̰ƨȹh}TsJoFsL\\m{åæɬŨyoe`]ckquthimorytmmnqüĽüǪʭͰˮɬɬɬƩ¼}sha}^bgm{ƩǭŲðì«ʼĶzronovƬɮĬǮŭȼxbUyOzPYgwø¥ȭʱɰưƯǭǭǬɬ̾audFl[=iX:dS7jY=oVxȼǳǲƱƱƱƱǲȳȳȳȳȳǲǲǲȰɯˮˮɩøwtSi[8j\\9l^;oa>viF~\\|úȩĭŰƱǲɲʳ˴̵̲˱ɯʰʮɭǫū¬Ǳʲɯɭˮ̭ʦĺ{zXob@hY:m^?}lNz]oƼŬĪ¨éūǭƬƫŪĩèèĩƮưưůůůůůįîĮůűǳȴɵưƯʿ`vcEubBtaArbA|kOhùîưɵɵ˷̸̶ͷ̷̶̶̵˲˲ɯȫ§masQ}kGxfBmY4tb<}mK{Xccadlrl|mPgX9gW5ueAm]9xhDa²y^xhGgW6eU4cR4eT6yhJi˷ɳȲʰ©usT{jLvcCt`?vb?zfC^{~yzyƾƴʸ˻ͺμλλλͺͺ̹̹ͺͺͺͺͺͺͺͺͺͺͺλͺ̹˸˸˸̹ͺλλλλͺ̺̺ͻμμμμμͻͻ̺̺̺ͻμϽμμμμμμμμͻͻͻͻͻͻͻͻ˸˸˸˸̹̹̹̹̹̹̹ͺͺλλλ̹̹˸˸˸̹ͺλǴȵɶʷʷ˸˸ʷͺ̹ͺͺ̹ʷȵȵɶ˸ͺͺͺ̹˸ʷ˸˸˸ȵɶʷ˸̹̹̹̹ʷ̹λλ̹˸˶̷ϸ˴ɱɱ˱˱Ȯū¦¨Ůɱʴɶɷϼ̹ʵȳɲ˲ʹγǭɭ̲ζϹθι͸ϻϻι̶˳ʲɯǰ˷˷ʶ˵̳ʹγγ̱ʹͷϻϼͻȸñleqɺĥɯ˱ͳ̵ʳʴ̸ϹŬȭ̯ͬ˦ǠȥͫϮͯ˭ɮɮʯȭƪŨȬͰгϵɲƲĮīĩħȿżĻĻżǾ¥ĩƫɳʴ˷̶˵˲ɳɰ̳̱˰̯˰Ͱ̱Ͱˬ̫̭ͮʫɪʭ̯ɮ˰˰ʱȯȯɰ˲ɮǬè§ɾǼøƷ̾ǫɯ̲̲ʰȰȰȰͶ̵˴ʳʳɲǰǭĺɤϯгʹɳʷ̹нκ͹̸ιϺѼҽԾҼкθθͷʴȲʲǫæƻq_|UwPwP}XhyƻˮǬȭxke^`fuƸ·p~]xUzW|YcqĻ½½¾ʿǼźǼƻvnoja_iv}üǫǪĨǪ̰ϲβ̯˯̯̰ʭũ¥úwl~ax[uXuX}bsƿƪǱ¯οíȱ˳ǰĪȮçɻunhhmuŷȼǼwiZ{TzRZk}ȽƫʱʱǱĮìǭƬǬʭbsbDkZ<fU7aP4jY=u\\ĵǳȳǲǲǲǲȳȳȳȳɴɴʵʵʵ̴ǭɬɬǧwrQhZ7m_<oa>qc@ylI`żɬƯƱǲȳʳ˴̵̵˱˱˱ʰʮȬƪū¬ǴʴȰȮʭʫǦxyWob@gX9hY:raCzkNx\\tĺçũĪʰɯȮƫè§èīưǱǱǱưưůůįįưưǳȴɵɵůƯɾ}^taCs`@r_?qa@yhLe¸įǱɵʶ˷̸̶̶˶̶̶˴ȯǮūħȾżi^pN{iEygCo[6xfB}mKzWdhnvľ¡}{^rcFfW8dT2ueAp`<{kGgótxWwgFk[:k[:kZ<m\\>oQnɵȲȰȮɿ{y\\~oPrbAp]=wcBlKfó˻Ǹįɷʸɹɶͺͺ̹̹̹˸˸˸̹̹̹̹̹̹̹̹̹̹ͺͺ̹̹˸ʷʷ˸̹ͺͺͺͺͺ̺ͻμμϽϽμμͻͻͻͻͻͻͻμͻͻμμμμϽϽͻͻͻͻͻͻͻͻ˸̹̹̹̹̹̹̹̹̹̹ͺͺλλλͺ̹˸˸˸̹ͺͺŲƳɶ˸̹̹˸ʷ˸̹ͺλ̹ʷɶɶ˸ͺλ̹̹˸ʷʷʷʷʷɶʷ˸̹̹̹̹̹ʷ̹λλͺ˸ͷθ͵ʲŮĭĪžĭʵ̹˸н̹ȵǳʵͶηεǭɯ˴ϷкϹϺ̹λͺ˷ʴɱʲ̵̲ʴʴʴ˵ʲʲɱȰ̴̶˸ͻξ̿ɾŶ˿˽Ǫˮ͵ε˳ɳȲȳ˴ͶƩȪǤĸɪ̮ͯʭɬƩæåŦɧ˨̩̮˴ȴǱǮƫħƽĻżżǾĥǪȭʱ˲˵ʹʹ̱ʱɮ˰̯̯̭̯̭ˮˬɬˬͰͰ̯̯ͰϲƩɬ̯̱˰ɮɮɮɬŨž¹úĻĻ}}üĨɭʮɯɯȮϸ̵ʳɴɴƱ­ƾ~zvtvzȣ̶̱ͭͯθнμͻ̺ͻμѾҿҿнͺ˸ʷɶǳůȬ¥źyavQtMtM{Vfz¹ũβʰũofhkp}ʼͿ˽Ȯʿȿu~]rQ~pM~pM^qƩȪȫɬɬʪȫɩȫɩɬʪȪƦǧɩƦøn__zZvV}]pŻǫжβ˱˯δϳͳ̰̲̰̲˯ȮƪǪŨ|jw]tW{lOykNy[n¥ɰí˿Ǳ̳ʲȯƮǬūèǻ}jbadkwǷǹŵnc]yV}W_nȽʿŨŪȯɳ˴ʵǲŰȰƬƫȫ̾}_q`BgV8bQ3_N2jY=y`ʻǯǳȳɴɴɴɴȳȳǲǲȳɴɴʵʵ̴ĪƩƩĤwsRj[:n`=oa>qbAylJbúħǰǲȳɴʳ˴̵̵ʰ˱˱˱ɭȬǫƬıǴʴȰȮɭŨɾm}nOj[<eT8eT8kZ>paDxjM|^tƩƪ˯̯˱ǭë¬ůưǱǱǱưůůįįưǱȴɵɵɵưƯɾ{\\r_Aq^>q^>p`?yhLe¸įǱȴȴɵʶʴʴɴɳ̶˴ɰǮūæȾżh{Z{kIweAxfBs_:mItRbr|ſťĥwrWn^DgX;cT3seBn`={mJgi~oPsdEm^?n_@o`CxiLfįʴɳɱȮȾ}{^|mNm]<kX8ubAmLjĴп£οʼƸø­ɴ˹ʸɷȶ˸˸˸ʷʷɶɶɶʷʷʷʷʷʷʷʷ̹̹ͺͺ̹̹˸ʷʷʷ˸̹̹̹̹̹̺ͻμϽϽϽϽμͻͻͻͻͻͻͻ̺ͻͻͻμμϽϽϽͻͻͻͻͻͻͻͻͺ̹̹̹̹̹̹̹̹̹̹ͺͺλλλͺͺ̹˸˸˸̹ͺŲǴʷͺλͺ̹ʷʷ̹ͺλͺ˸ʷʷ̹λϼ̹̹˸ʷɶɶʷʷʷ˸̹̹ͺ̹̹˸ʷ̹ͺ̹˸ʷ̶θҺζƯƾz~«˵˸μ˸ǴǴʷιι̶ǯɯ̴϶ϹϺͺ̷̹̹ʴɳʲ˱˲̳ʳ˵ʵʲɲʲɱɱͷ˸˹̼ǺȱæƼǾèʭ˰ˮϻͷʶȲȲɳ˴δĩƧŢɼ|tuṱ̌ͯˮʪťġǣǡȢȦʱȲȯȭǬƧ£ȿĻżƽäƧɬˮȭɮ˲ͲͲͰʯɬʭʫˬˬˬʩɪȩǪɬ̯̯̯ˮ̯ͰŨȫʭʭȫŦħæȫæĽúƽȿ~vnknuĽæȬ˯ͳйͶʵɴɶǴļsmkefiu~ȥ̮гҸϻμͻ̺ͻμѾҿͺ˸ʷɶʷʷɵǯȬɼhvQmHpKtO^tĻçǭɯ¨{olswͿɮʯȮǰ˱ũĥy~]pOzlIxjG{ZqȩαͰ̲ϴ̰˯˯ʮʮ˯˯̰Ȫɫ˭ͭȨ|hvVvV~sStTc|Ƭͳйϵ˴ͳ̵̵̲ͳ̵̲˴ʰȱȮȮɭǬu}cy\\zkNpbEviIwWj˯Ư¬ìư˴ʴ˴Įɲ˵˴Ǳ«ug`\\^cnwygwVtSxW{Ydr¤ǫƪȭȯȲʶ͸λ̹ʵɱǭŪħĶwYn]?eT6bQ3`O3l[?za̽ʲǳɴʵʵʵʵɴȳŰŰŰƱǲǲȳɱªĩũ¥wuTl]<l^;l^;m^=viG`~ǰǲȳɴʳʳ˴˴Ȯʰ˱˱ɭȬȬȮǴȶǴɳ˴˰w_sdEfW8dS7eT8hW=k\\?obBvlIyYh|ƽũȬʰǭëſſíĮůǱǱǱưůîįưȲȴɵȴȴǱǰɾ{\\q^@p]=q^>p`?ziMfùįưǳǳȴȴɳȲǲǱθͶ̳˲ɯǪǾiyXwgEuc?xfBvb=rN_rúááƦǧ£v}rVm_DiZ=eV5oa>j[:xiH`pu}^rcDk\\=gX;j[>qbErUxǲʴʴʲȰ{z_|mPk\\=jY;wdDnNg~Ǹ˾̾ɾƺ¶øȽŰʵ˸˹ʸʸ˸˸ʷʷʷɶɶɶʷʷʷʷʷʷʷʷͺͺͺλͺ̹˸˸ʷ˸̹ͺͺͺ̹̹ͻͻμϽооϽϽͻͻμμμͻ̺˹̺̺ͻμμϽооͻͻͻͻͻͻͻͻͺͺͺͺ̹̹̹̹̹̹̹ͺͺλλλλͺ̹˸˸˸̹̹Ǵȵ˸ͺͺͺ˸ʷɶ̹ͺλͺ˸ʷ˸̹ϼнλͺ̹˸˸˸˸˸̹̹ͺͺͺ̹˸ʷʷ˸˸ɶȵɵ˵θԻ˳ļrkf{\\~]bkîɶ̺ȶŵƶ˻λͺʶȰɱ˵ͷ͹ι̹͹͸͸̶ʴǯéȾŻƻºøǽéʰͶιͺʹ˼Ƚ̶ˮʯ̯ͳϲ̲˯ͺ͸˸̷̶ͷ̵ͱǪãȻynlrṶ̃ʬťķƼǻǻɽ˿ʿǼźøƻʿ¤ũƪƩȫʯͰαͮˮɪǨȧɨɨȧȤƥŤ¦éūūç¦¦¤¤Ǽ·ƿľſ¢ƦƥǦǾ|pf`bkq|ȿɮ϶йͶʵ˸̻ʹų{tpiecfnwß̪ϲϹͼ̻˺ͻμоѿͺ˸ʷʷʷʷɶǰͿyi}YmHmHvQ_oøũɯʱɰɭͱ˱ɱɲʲȬätzY}nMxiHvgFxWqˬϲαͳе̲˱ʰɯɯʰ˱̲ʭʫˬɪʿn}[}pN}pN}rR{[rȿƪ˴ηι˴˶Ͷ̷ȱ̷Ͷ͸̵˶ɲɴɲƮʲʳƭĶw|_zkNl_?l_?rgGyUqǫǭȮɯʳ̴˴̶ʵθλ˸ʷʷòû|of`|Z}\\bljh~]qPyiGqO^lzʮ˱ȯʱȲȳʷͺνͼ̹ʲȮĩǾuqSkZ<fU7dS5cR6n]Ay`ʻȰǳɴʵ˶˶ʵɴȳŰƱƱƱƱƱƱȰëŪũwtSl]<j[:j[:l]<viGaƯǲǲȳɲɲʳʳƬȮ˱˱ɭȬɭ˱̹ȷƳǲ˵ʯƻktWn_BfW:hW=kZ@o[Bp_Cm^=reBxkI}sP]tĺūūŽƾĿ«ŮǰȱȱǰƯ­îưǱȴȴȴǳȲȱʿ{\\q^@o\\<q^>qa@{jNhùîůǳǳȴȴȲȲƱư̶Ͷʹʹ˱ɬ§ȿdvUvfDvd@|jF|hCyUmøĥǧȨǧɫǩ¥}cwiOpbGk^>ob@gZ:viIyY}]a}oRoaDk]@m_DykPy^pɽǱʵʴɳɱǯky\\yjKwhIqPrQct·÷ʿ¬ǲʵʷʷʸ˹̹̹̹̹˸˸ʷʷ̹̹̹̹̹̹̹̹λλλλλͺ̹̹̹ͺλϼϼϼϼλͻμϽϽооϽϽͻͻμϽμͻ˹ʸ̺̺ͻμμϽооͻͻͻͻͻͻͻͻλλλͺͺ̹̹̹̹̹̹ͺͺλλλλͺ̹˸˸˸˸̹Ǵȵʷ˸˸ʷɶȵɶ̹ͺλͺ˸ʷ˸ͺϼѾϼλͺ̹̹̹ͺͺͺͺͺͺͺ˸ʷʷʷʷɶǴƲǳ˵ͷʱzy`sgOmaIl`FpgFrjFsjKypSiŽǴ˹ǵĴǷ˻ξ̹ȴɳʲ˵˵͸͸̸̸ιϺθʲé©̲ϸ͸˺˼ɽιϳзҶѸе϶γ˷˷̹ϺϹзͳ˯Ħ|milwɬˮƧƻ~tkjlimxĹȽʿħƩʭͰίͮˬɪŤƥǦȧȤƢšâȽɽ˿ɽƻøǼľãȨ̬˪ʩ̫ģŻoc`[_grƩϴѷͶ˶ͺϾϾʺıƼ}slfdekuğɨϹͼ̻˺ͻμоѿѾϼͺ˸˸ɶǴī|e}YqL}iDqL\\sæ˱зϸ̵˵ĭǿžƿ¥ĥǨͮϳͳ˳˳˶̴ˮ£owX{lKxiHwhGwVs´̯ϴα̲е̵˴ʳɲɲʳ˴̵ͱ̯ʭĥ~ctRxkIzmKsSb~¹ȫ˯ηι̷ʵ̷лιȳιιι͸˶ʵʵʵůʴ˶ʳɳƮƷ|b{lOk^>i\\<m`>xnKfåƬʰͳ͵̴˵̶нҿϽɷȶ˻ɹ­Ť÷vgzXsRuTtSrQoPlKvcBtdBuSiȽéǭ̲ʹɰɳƲƳǴʹ̻̻˸˳ɯèĻn}lNiX:gV8gV8fU9p_Cx_ǸƮȴɴ˶̷̷˶ɴɴȳȳȳȳȳȳȳɳŭǬƬ¦xtUk\\;k\\;k\\;m^=xkIeƽƩƯƱǲȳȱɲɲʳĪǭ˱˱ɭȬʮ̲нʹŲŰɳƫ~c{mPk\\?gX;m\\BraGwcJxgKoa>sgAviFtgDxkI|Yn|¸éǿŽƾ½ĭƯȱȱǰǰ­ůǱȴȴǳƲȲȱ{\\q^@o\\<q^>qa@}lPjĺ­ĮǳȴȴɵɳȲƱǱɳʳ˲̳˱ȫƽ~^sRwgEygCpLnI\\uȩȨǧȨȪɫƨçžrv\\{mStfIpeEhZ=tiIrUynP~pSpeIwiNujNtYoǸŬʴ˶ɳȲȰƮƿ{p|_y\\}^vWbnxưȲ˶˶ʷɶɷʸλλλͺͺͺ̹̹λλλλλλλλλϼϼϼϼλͺ̹λϼнѾѾѾѾнͻμϽооооϽͻμμϽμͻ˹ʸ̺̺ͻμμϽооͻͻͻͻͻͻͻͻλλλͺͺ̹̹̹̹̹̹ͺͺλλλλλ̹˸˸˸˸˸ȵȵɶɶɶȵǴǴɶͺͺ˸ʷʷ˸̹ͺϼϼ̹̹̹̹̹̹̹̹̹̹̹˸˸ʷʷʷȵ̹̹ȵǳʵ̵ʳ˲īqukRg[CcT=`R8eZ:jb>i`AriLmƳȷɷɹɹɹȸɶɵȲɳʶʶ˸̹κκ͸͸̶Ȱvojhfisíǳ˺ο˿ɴ̱ζжѹзй϶Ͻ˹Ǵʵ̶εɭŨʿ|sidmŨƩȫɪĹkc[VVXbq|yuv~·ƽƽǾŦƧâȿǾƽƾŽû~ýŧȪɩ˫ήѱͬʩâúq^{T}V|V}Yf~Ⱦȯʴ̷˸̺Ͽ˾ǴŪâļxqg]\\kvƮ̹ϼ˸ɶͺκʶȴ͹͸ȳɴ˶ǿ{i~ZtPoKrN]pöŨͱͳ˲ͶϸɳȰƮūũǪʭˮ̯̯̱Ͳ̴˵ʷʴ˰ȿeqR{lMwhGqbAsTqȫͲϵζʹ̷ʵȳǲȳ˶ιѼ̲̰ͰƧmwVqPrcBxkIuUg̰˱͸ͺͺ̹˸ʷɶȵͺ̹˸˸ʷʷ˸˸ƳǳƳȳ̶ʲʻowhKn_@j]=m`>siEyU|Ũγе϶зϹͷѽѽнξ˻ȺŷðɩŠŻxevUlK~gGxdAvbAvcBxeDlK_t÷¨ƮǮʱ˵ʴȳȳȵɶɷʸʺʸ͵ʰƫǾgyhJkZ<hW9fU7dS7m\\@v]ǸƮɵʵɴȳȳɴɴʵ˶ʵʵɴǲƱŰưëƫȮçn~oPpaBj[:l]<n_@wjJcżƫƯƱȳɴɲɲɲɲ¨ūǭū¦¦ǫ̲ȵȷƴƲǱ˿q}nQrcDgV8eT6p\\A|hMpWuY|nKug@qc>rf@tgDylJxXg|¸ʿ¬¬ĮǱɳʴȲǱîîůưǳǳǳƲĮìyZtaCkX8q^>rbA}lPjĺîĮȴȴȴǳǱǱŰư̶Ͷ˲ʱ˱̯|ZpOyiGzhD|jF~jE_xȽ¥¥ƩȪŨȫɬȮĪ~rgb~bbgiihhrǽ¬ů˵Ȳůíëëé¨}{{|¸ŻǽŮǰʵ̷ͺ̹˸ʷλλλͺͺ̹̹̹λλλλλλλλλλͺ̹̹˸ʷʷ̹ͺλϼнѾннϽϽϽооѿѿѿμϽооϽͻ̺ʸ˹̺ͻμϽоооμμμͻͻ̺̺̺ͺ̹̹˸˸̹̹ͺ˸̹̹ͺͺ̹̹˸˸˸˸˸˸˸˸˸ɶɶɶɶɶɶɶɶ̹ͺ̹ʷʷʷʷ˸̹λλ̹̹̹̹̹̹̹̹̹̹˸˸˸ʷʷʷȵ̹̹ɵȳʵ̵ʳ̳ƭsuiQfW@bR;aQ8cX:g^=f]>sjMuļƳɸɸʺʺɹɷʷʶɵɳʶ̷̹ͺκϻҽѺͷész_rWyiPyiPzjQ{mRv[k~ǻȴͼο̾͸ϷϷиϷ͵ʳɲϾ˸ǴɴʹͳȫĤļulfguũȭǪɬŨ}]yVvPvNyPUarxifa`gs{ú¹¹żȿż¹zttqmd}a}_bflmmqwæǩˮͯͰήαаίͬʩƥʿl~XyQuOsP{Ykư˶˸̺ξξʸѷбϰ˪šº~ob\\bjo|ǹɶ˵˸θ˸Ǳȴ̶̷Ưîh~ZtPqMtP~\\oķʿɬгϷεηйʴɳȲȰȮɭ˯̯ͰͰͲʹ̶̶ʷ˵ɮżb{lMufGqbAm^=rSpǪʹϵζʹ̷ʵȳǲȳ˶ιлϷδ˯grQ{lKtdCzkJxXnç̲ʲ̷̹̹̹˸ʷȵǴ˸ʷʷɶʷʷ˸˸ɶɶǴȵ̸˵;w}mSrcFl]>l_=reBsPv¥̱γʹεͷ˵ммѾϿ̾ȺŷïʬȦ¡¸nzYmLzcAw`>t`=vb?zgFsQh~ɽƮǯȯʱʴɳȳȳȵɶɷʸʺʸ̴ʰǬǾfwfHiX:hW9eT6dS7m\\@v]Ʒŭȴȳȳȳȳȳɴʵ˶ʵɴȳǲǲǲȲĬǮȮçm|mPn_@iZ9j[:m^?viIcĻŪǰȳɴʵʳʳʳʳ¨ĪéĨɯƱȵǳưĬĸewhIpa@iX:hW9s`BkPtYy[pNwiBqc>rd?tfCuhE|oMxXep~Ż©¬ůĮůưǱȲȲȲîŰǱɳɵɵɵȴůĭyZtaClY9q^>p`?{jNh¸¬ƲƲƲƲưưƱǱ˵Ͷ˲ɰʰʭɿ~{Y~nMxhFygC{iE}iD_yƽȿƿĦƩħȫɬʰȮɾĮȲ˵η˵ȲůĮŭŭĪé©ȾĸĺƼȾɿɿƯǰʵ̷ͺ̹˸ʷλλλͺͺ̹̹̹λλλλλλλλλλͺ̹̹˸ʷʷ˸̹ͺλϼϼϼϼϽϽϽооѿѿѿϽϽооϽͻ̺˹˹̺ͻμϽооϽμμμͻͻ̺̺̺ͺ̹̹˸˸̹̹ͺ˸̹̹ͺͺ̹̹˸˸˸˸˸˸˸˸˸ɶɶɶɶɶɶɶɶ̹̹̹ɶɶɶɶʷ˸̹ͺ̹̹̹̹̹̹̹̹̹˸˸˸ʷʷʷʷȵ̹ͺʶɴ˶͵˳ʹȯwwhQdT=aO9bP8`R5aV8`U7shLzʿĲ˺˺ʹʹʸʷɶʶʶ˶̷̷̹κκϻιͶɳ{_seJm]CtbJvdLxgMxhN|lRx[ky©ɵλ̻̼̹ϺкϺϺ͸˶ǳƲн˸ǳɳͳαƦſ|khksŻȩ˯˯ȫȫsxVtQsPxRZbrv^uR|oLzmKsQ}]j}úúúĻǾȿǾǾƽ¹tmlf{^~qQvhKtgGxkK|oOrRyYdn}ǹĦȫˮδѴгΰ˯ˮˮϯбϰͮģezU|nKxkHzmKtTi~ʿ˶̹̹ͻϽλйҶӷҵίģob^^`hy;Ůɴ˳ȲĬǱ̳˵īļrxWqMmIrN^pµǧɫͰгиѸзϹ˵˵̶͵ͳαͱͱββεεͷ͹̺˷ȭ¹|{]ufGn_@k\\=hY:qRpǪ̳ͳ͵̶˶ʵȳȳȳ˶͸ϺҼϷɯ¸`|lKvfDxeD~nM|]uƬ̴ʴ˶˶˶˶ʵɴȳǲȳȳȳȳɴʵ˶ͷ̸̷ɵȵ̸ͷìƸtZvgJn_@l]<na?ylJoĿɯ˱ʲ˳̶ʴλϼоϽͽɹŵïʭͬ˫ģy~]mLu^<r[9p\\;t`?|iI|[uȼŬʴȲǱȲʵɴȳȳɶɶɶɶ˸˷˳ʰǬǾcsbDeT6hW9eT6cR6m\\@w^ƷëƲǲƱƱǲȳɴʵ˶ʵȳǲǲȳɴ˵ưȯȮ¦jyjMk\\=gX9iZ;l]>viIdĻĩȱɴʵʵ˴˴ʳʳƿ¨é¨ũɯïƲȴư˿qvVm^=j\\9hX7kX8q\\=zeHoRvX}mKwgCtd@xhD|lJ|nK~oNrP|oOwZerƺĭůîĮîĮįưįŰɳ˵̸̸ʶɵưŮ~yZubDmZ:o\\<o_>yhLeŽſïİİűưưƱǱ̶Ͷ˲ʱʰɬȾ|yW}mLwgExfB{iE}iD^|ŻŻ»ŪèŪƫȰȱưí˿ȼĺ»ĽĽƾ«ǰʵ˶̷ιϺ˵ɳưưǯǯƯƬǭƪ§ɿǽƽǻǽ§ĪūƬǭǭƯƯǲȳʵ̷ͺ̹˸˸λλλͺͺ̹̹̹λλλλλλλλλλͺ̹̹˸ʷʷʷ˸̹λλϼϼλϽϽϽооѿѿѿϽϽоϽμͻ̺˹˹̺ͻμϽϽϽϽμμμͻͻ̺̺̺̹̹˸˸˸˸̹̹̹̹ͺͺͺͺ̹̹˸˸˸˸˸˸˸˸ʷʷʷʷʷʷʷʷ̹˸˸ɶȵȵȵɶɶ˸˸˸˸˸˸˸˸˸˸˸˸˸ʷʷʷɶɶȵ̹ͺ˷ʵ̷͵˳δʱ~|mVeS=bM8bP8\\N3\\Q5[P4pdJ}Ĳ̻̻˺̹˸˵˵ʴʶ˶̷̷͹͹κκɴɳǯ}v[qbEm\\@t`GwcKyeLveKtcGxiLsV}`|ǽĭȳɶ˷͸ιϺлϺι̸ʶͻ˷ʴ̴гʭſtilvŹƢͰͳ˯ȭǪĽqyYwUzXalxȾŪͿɻö~]{nKuhEreCviGsSe¥ħƧǨǨƧģż~vvobuSviGqdDreEtgGuhHwWiyõ¥ɭūʯ͵ϵδˮȮǫƪˮαбгˬƽu]oMxjGteDreEuXpùɲιͷͺϼѾʵ˴δϵγʭæǾthb[]ezǹĪūĪɮͲ˰wesRoKpL|Zmķ¢вϲ̰̰ϵҷиз˷͹λѻѹжϵͱϳϳ϶θκ͹̸̺ɰ{xZrcFiZ;hY:gX9qRsǬ˲̴̶̶˶ʵɴȳɴʵ̷ιкϹȰ{}^zjIubAyfEoNa|Ȱ̶ɳʴʵʵʵɴȳǲǲŰƱƱǲȳʵ˶ͷϻϺ˷ʴ̷θƯ̽w]wgMn_Bk\\=m^=uhHi½ɯ̲ʲ˳̶̶θλноμɷųḭ̈ΰΰʪź~amLqZ:nZ7mY8p]<{kJa~§ȯʴȲưɳ˶ʵɴɴɶɶɶɶʶʶɱɯǬǾ}`p_AbQ3gV8dS5dS7o^B{bƷªűƱŰƱƱȳɴʵʵɴȳǲȳɴ̷θȲɳǰivgJhY:gX9hY:l]>xkKhƽĩȱȳɴʵʳɲɲȱ¨éĪé¦çǫʰíưǱī`xkIl^;m]9n[:lY8mY8r]>zeFlMxeDvfB|lHwS`ca}\\qRtTwW{^j{Ǽǿ­­îŰɳ˵̸˷ʶȴǱŮ}xYubDn[;n[;m]<veI}bû¼®ïůưƱǱͷϸʹ˲˱ʭǽ{xV}mLvfDxfB{iE~jEbƼ»Ūĩ§ëŭƯưƳǱƬĪ¨éūǰȱŮƱȳȳȳȳʷͷ˵ɳǱȲɱʲȱƯ¨ɿɿɿūƬȮʰ̲ͳ̵̵ȳɴʵ̷̹̹̹̹λλλͺͺ̹̹̹ͺͺͺͺͺͺͺͺͺͺͺ̹̹˸˸˸˸̹ͺλϼннϼϽϽϽооѿѿѿооϽϽμͻ̺̺̺ͻμϽϽϽϽϽμμμͻͻ̺̺̺̹̹˸ʷʷ˸̹̹̹̹ͺλλͺ̹̹̹̹̹̹̹̹̹̹˸˸˸˸˸˸˸˸̹ʷʷɶȵȵȵȵɶʷʷ˸˸˸˸˸˸˸˸˸˸ʷʷʷɶɶɶǴ̹λ̸˶̷͵˳ͳʱ¼v_kYCdN9eP;]O5\\P6ZN6maKzŵ̼˻ͺ̹˶ʳʲ˲ʴ˶˷̸̸̸̺̺͸ͷ̴Ľ{`vgJraEwcJ{eN~hP{gNyeJwfH{lMrR~^gyƿǭ˳̶ιϺммϻͺ̹ɶ˵˴δˮqmnxùß˩̲ͯʮȭǪĽxb`gq}ʽ˩̱ƬƫƩæ˾{XzmJtgDob?reB|oMaźǫȭȭɮɮ̯αϰŦĥ£ƽo~[ylIna?k^<k^<naAxXu˽èéëȯ̶϶͵˱ɱȮƬʮ̰̯̱ͰĩƻkvUzkJqbCk^>xjMdūͶͷθѻѾͺ̹̹͸ͷεʲɭèƸ}naZ[hr}Ƹ¦ɭ˯̰ȫĻygwYqPtRzXh}¢ȪдͰɭɭͱҵжϷ̸κѽӽӻҸжδжжϸϸκͻ˻˷˲xvXqbEhY<hY:k\\=sVuĶɮ˲˳̶̶ʳʳɲȱɲʳ˴̵͸ͷƮ{}^|lKubAyfEoNcĺʲ̶ɳʴɲʳʳʳɲȱǰŮŮŮƯȱʳ˴͵Ѻй̶ʴ˶ͷǰw]veKm\\@j[>l]>teHh»ʰͳ̲̲ͶηͶιϺϼͺɶƳĮ˱Ͳ̰Ǫ¹`lKnZ9mY8lW8n[;{jLg·ƭȯǮǰ˴̵˴ʲʲʴʴʴʴʴʴȰȮƫży\\m\\>aP2eT6dS5fU9tcGhɺªűƱƱƱƱǲȳɴʵɴɴɴɴ˶͸ϹɳɳǰƿgteHfW:hY:iZ;m^AzlOnɿŬǰǲȳȳȱǰƯƯ¨¨¨¦ĨǫʮƭƭéǼnsRseBueAuf?tb>o]9lX5mY8t`?{gFzgFoN~]n}zq_{ZtSsSxXewʽ®¯̿îįȲɳʶɵǳƲưìɾyvWs`BmZ:lY9k[:udH{`~º¼ïĮưƱȲθϸεʹͳˮȾzxV|lKvfDygC|jFkFcǽ»ƭƭ©¬­įűƲʳʲɱɱɱ˳ͷкʴʷʷȵǴǴɷ̹˵ʴɱɱ˳˳ɱȰ¨ĪūƬŮǯɱ˳͵ϷϹϹɴɴʵ˶̹ͺͺͺλλλͺͺ̹̹̹ͺͺͺͺͺͺͺͺͺͺ̹̹̹̹˸˸ͺλϼнѾѾѾѾϽϽϽооѿѿѿооϽμͻͻ̺̺̺ͻμϽϽϽμμμμμͻͻ̺̺̺̹˸ʷʷʷʷ˸̹̹ͺλλλλͺ̹̹̹̹̹̹̹̹̹˸˸˸˸˸˸˸˸̹ɶɶʷɶȵȵȵɶɶʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶɶȵǴͺϼι̷θε̳˱ɰmvaLgQ<fP;aQ:`T<[O9i]Gqȼȸ˻̺̹˶ʳʰɯɯʳʵʶʶʸʸʶʶιͷʲŻ}`whIraEv`HycL}gOjO~kM}jJ{kJzkJviG|rO~[mžǫʴ˷˸͹̹˸ɶȵűɲ˲ȭȿ}qimwßȤʪ̭˰ɭʮȫyxǺƦϲͲȮȭǪŨxUuhEpc@l_<m`=uhF}[~Ĺǫɮ˰˰˰̱ͲгǪŦĥĥĥâȿƾ˿w]xkHk^;eX6eX6qdDa´ͿǬǭëưɳθкϹ͵̴̴ɲͳͳ˯˰ͲʯĨw`~nMp_AiZ;qcF}rTn»Ȯ̴Ϲѻѻпο˼ʹ˹˷ʴɱɯèȺre^~]~_fn{¢å¹uawX|qQsR}Zhwʿɫ̭ͰʭȬɭͱддδ˸λмҾҼѹиδжжϸϺͻ̺ʺʸɰttXo`CgX;j[<paBvYyȺ˰˵ʲ˵̶ʳʳɲɲɲɲʳʳɴɳuz\\lLvcBxeDlLbǽ˳̸ʶʲɲʳʳʳʳɲȱŮŮƯƯȱʳ˴͵ѺҺηʴʳ˵ǯοs[saIkZ@iY?k\\?scIh»˱ϵͳͳϸйηηηͶ̷ɲǲưʲʱȮæa~kKnY:nZ9lY9l\\;|mNjɿêƭƭȱͶη˴˳˳ʴʴʴʴɳʱƬǭĩvYl[=bQ3cR4dS5iX<ziMqοĬȴȳǲǲǲǲȳȳʵʵʵ˶̷̷̷ͷʴɳƯĽerbHdU8hY:iZ;m^A|nQqƭƯǲǲǲǰƯŮŮƿƿžƿçũǫǮèǼw}[zlItfAyjCvg@tb<m[5kW4mY6ua>|hG{Zfwŵɹsi}\\vStRyVetö˾¯¯ŰŰưưƲűűİĮźurSq^@kX8lY9jZ9tcGz_~ļſ®ïůưƱǱ˵ηʹʹͳˮȾxuSzjIueCxfB{iEkFcž»ǮȯŬŬĮĮįįïįǰʲ˳˳ʲʲͷϹͺͺ̹ɶƴųǵɶ˵ʴɱʲ˳˳ȰƮǿĪƬȮʲ˳̴͵ζζͷͷʵʵʵ˶̹ͺͺλλλλͺͺ̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹λϼнѾҿҿҿҿϽϽϽооѿѿѿѿоϽμͻ̺ͻͻͻͻμϽϽμμͻμμμͻͻ̺̺̺˸˸ʷʷʷʷ˸˸ͺͺλλλλͺͺͺͺͺͺͺͺͺͺ̹̹̹̹̹̹̹̹̹ɶȵ˸ʷɶɶɶɶʷʷʷʷʷʷʷʷʷʷʷʷʷɶɶɶȵȵǴͺϼϺ͸θε˲ȮǮë{lWnUAeO:`P9bS>[L7`Q>raŵ̺˹˸ʵɲɯȬǭɲɵɵɵɷɷɵɵʵȲƮƼmwXnPzdL~eO~hPmRqSoO{kJvhEuhEvlH{qM{Wey¬įǱǲǲƱƱíǮƬɾzmgnwşɥ˩̫̭̯̰β˰ĨƼ÷ŵ̽¥Ǫγδ˱˰ɬǪáyVrf@nb<k^;k^;qdBwUy¨ƭʱ˲ʱʯ˰αʭȫƩƧȩɪɪɥÝq|Trf@h[8gZ8j];|oOoʰϵ˴ŭʴ͹ϻмϻͷͷζ͵иη̲˲ʹʱũƵlsRq`Bj[<m_BqfHw[sʰиӺѻο˿ʾ˼˽˻ɸǴ˶ʳƬƶxna|[yZ|[cj|}k}\\zrNypO}sP]lȺȪͱͰʯ˯˯ͱϲгϲδ˸ͺϻмкѸϷζϷϷιι̺˹ȸȶŬnzoSl]@eV9j[<rcDz]}˽γ˵ʲʴ˵ʳɲɲɲɲɲɲɲƳűisU}jJxdCwcB|iI~`Ⱦʲ˷˷ʲ˱̲̲̲̲˱˱ȮȮȮȮɯ˱̲ͳзѷε˲ɲɳĬ˼qYq_GiW?hV>kZ@qaHf¸ʱε̳̳϶Ѹ϶϶ʹ˲ɳɰǱȰɳȱǬç`|iInY:oZ;n[;o_>pQqúɿêƭǮ˱жж̲˳˳̳˲˲ʱʱʱūƬ§{tWl[=dS5aP2cR4l[?pTyóìƮʶʵɴȳǲǲǲǲɴʵ̷ιι͸˶˵ɳȲŮüdrbHdU8fW8gX9l]@|nQrŬǰȳȳȳǰǰƯŮƿžĽžçũƪƫȾf|oMtfAwiB{lEwh?sa9o]5r^9zfAqLyVrʷѾ̼Ĵ}oc~[yT\\hw³Ǹ˼ıɴȳǱůİïïİ¬ƾq}nOn[=hU5lY9jZ9tcG{`ǿ¬®®ïİůưƱǱȲʳʱ˲˱ʭǽtrPwgFrb@uc?ygC}iDaĽ»ǮǮǰȱȲɳǴŲ°­«ƮɳʴȲǱǴɶ˸˸˹ɷǵƴȶɶ̶˳ʲʲ˳ʲǯĬſý¼ļǿéƬ˳̶̶ͷ̶̶˵ʴ˵˵ʵ˶̷͸λλλλλͺͺ̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹ͺλϼѾѾҿҿѾϽϽϽооѿѿѿѿоϽͻ̺̺ͻͻͻμμϽϽμμͻμμμͻͻ̺̺̺˸ʷʷɶɶʷʷ˸ͺλλϼϼλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ̹ɶȵ˸˸ʷɶɶʷʷ˸ʷ˵ʷ˵ʷ˵ʷ˵ʷ˵ʷʴɶɳȵȵǴͺѽϺ͸Ϸ͵ʲƭƭĬ·t^nXCdO:\\K7_P;VG4VG4qaQt˹̷˶˳ɯȮȫǪȱȳȳȳȴȴǳǲȳǱɱƬuoppptupg~]~qOzpMxnKyqMyXh{źǿìŮƯǰéūçleczļƢ˩άήϰ̰ͱϳѵγǭê¨˿Ϳéǭǭé¨Ƭͳ˱˱ɭƨwUreCob@m`>l_=qdDvVwŬʱ̲˱ʰʰ̰Ȭƪç¦ħǪȫȩĺg|oLi\\9dW5i\\<obBvYyĶūʰζʲ̶κϻϻ͹˷̶̶͵иϸ̵˴̲Ǳ̻¯vwVsbDm\\>m^Al^AujNgɯѹӻн̽˿;оͺλкͶʯæȹmbxYtUtTxVbpokcyYwlLshHynNxXmȽũαϴ̱̰ͱϵѵеϴγδ̶͹ͺθϹϹζζζϷι͸˷ʸȶȴiykNiZ=cT5iZ;sdE|_ϴδʲʴ˵ʲɲɲɲɲɲɲɲƳï{y_}lN{fGwcBvbAzgG|`Ǽʴ˸˷˳˱̲ͳͳͳ̲̲ɯɯɯɯʰ˱̲͵ϸѹηʱɱǱªɺqYp^FgU=gU=jX@o_F~dɰε˲˲϶Ѹз϶̳ʱɰȯȯʲȲȱƬĨbyhJlY;o\\<m]<paBsVuüīưȯ̵ѷи˳˳˳˳˲ʲʱɱɱŭūyrUl[?eT6`O1cR4m\\@tZ~ƸƯǱ͸̷˶ɴȳǲǲǲɴ˶ιϺϺ͸˶ʴɳǱįĹdrbHeT8eT6fU7k\\?|mPrūɲʴɴɴɲȱƯƯƿçƪȬǬƪȺuzYtfCqc>ykDtM~oHxiBwgC}mI{Ygrʹ;ħ£˼;wh}[|Yagtĵ˼«̳˱ǭĬ¬¬įŰýn|kMlY9gT4kX8lY9tcE{^ĮíïİűůưƱǱĮưǱɰ˰ɬüo}nMvcBq^=sa=weAxhD_»ƭƭĮưɳʴɴǲñƮʴ˵ʴȲǴɶɶʷ˸˸˹˸μн̶˳ʲʲ˳ɱŭªëľ¼ļǿìǯǱȲɳʴ˵˵ʴʴ̶̶˶˶̷͸λϼλλλͺͺ̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹̹ͺλϼнѾннϽϽϽооѿѿѿоϽͻ̺̺ͻμμμϽϽϽμͻͻμμμͻͻ̺̺̺˸ʷʷɶɶʷʷ˸ͺλλϼϼλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺ̹ʷɶ̹̹̹˸˸ʷʷʷ̶͵θ͵˵ʲ˵̴˵˳˵ʲʴɱɳɳɳͶϸηϸѺͶƭëŻt]gW>_O8_N:eTB]L:UF3eVCr_~Ȱ̴ͲͲϴвͯ˲ʳɲȱȱȱȱȱʳʳȲůvl~`|qSshJtiKtVdoɿǮȮūǨĥźq~aerĶƩϳϲ̯̮αеѸѸ϶̴ʲɲ˱˴̲˱ʰɯɯȮȮ̲̲δʰ§ǻ~pUo_En_BsdGsdGpaDwZìǰʲʲ˳ʹγɮ̱ʰƬĪƬǭĩr{\\rcFhY<hY<fV<xhN{aʾƭδи͵͵̶ͷͷθθͷͷ̶ϹϹϹθͷʲǲŬ§Ǹ{]veGp_Am\\>fW8sdGu[|¶ʴҽѻϼͺλѾԿҾѽκ˵̶ʹȯɿ¶w}cqWzlOwjJwjJzmMtTtUpQufIn]CsbHqYh}©˲̳δδδжҸԽջӹѷжйηϹιζͶ̵̵˴̵ηйѺй͸ɴǮȽ~^whIl]>gX7k\\;teD|\\Ĩеϵ϶ͷ˵̴ʲɱʲ̴͵̴ʲƴqmUxdIyaEw`Ar[<s^At[źıǷ̹˵̳˳ʹ̴ε͵ε˳̳˳˲ʲʱɱɳîȴʵȲȰưɻ}lRo^DjY?cQ9gU=scLhȱͶʳ˴ϸѺԽѺηʳǰǰǰȰ˴ƯƭūĺbyjKfU7n]?k\\=o`Cz]{ĩĭƯʵͶлйллι̷ʵ˵ʵ˵ȳƯƯŬʾs}nQkZ>fU9dS7dS7m]Cx^ȺȰ˵̷ͷͷʴȲȲʴ̶ͷθϹϹθͷ˵ɳɶɳƱȼ|bt`GkV;jU8fS5iX:{lMnƿɬ˳ͷϹͷɱƮǯȰŬêèƫȭǫпwdxT}mI{lE|nGzlEvP\\dmxǻɽ˿ɿȼȾ©ƭŬɿ{ph}]|[csʻŢʦάͯǪ©ëŭ­ĿnnPq\\=hT3kW6jW6s`@y[~íůǱȲɱɳŲŲ˵ʱèħýf{hGu^>mY8lY8n`=reB_ªýƮȱƯìƾǱȲʴ̶ͷͷͷ̶ɳɳɳʴʷ̶̹θͷθϹϹͷʴưĮľý¼ľíǱȵɶ˸̹̹˸ʷɶɶɶʷ˸̹ͺλʷ˸ͺλϼλͺ̹̹ͺͺͺͺͺͺͺλͺ˸ʷʷ˸̹ͺ̹̹̹̹̹ͺϼϼооооооооооϽμͻͻͻͻϽϽϽϽϽϽϽϽͻ̺̺μϽϽ̺ʸ̹˸˸ʷʷ˸˸̹ͺλλϼϼλλͺнϼλͺͺͺλλ˸˸̹λλλλλͺ˸ʷͺͺͺ̹̹̹˸̶̶͵ζ͵˳ʲ˳̴˳˳˳ʲʲɱɱʱʳϷϸηϸк̴ŭĭȾ}qYcW=]N7ZI5bO>\\K9WF4^O<m`M|fªʯȭƪǫʫʫʮɰɰɰɰʱ˴̵˴˴ʵȳŰŽƿvd}rVykP|nStYy^js÷èƭéǾsd}`r˻ɯδͲˮʭ̱Ϸииζ̴ʲʲ˳̴̴̴˳ʲɱɱɰεʹ϶˳ĪƼ~oXrbIp`GueKscIp`Fv\\īǰ˳͵εε϶ѸʱʹʹȯŭǯƯīlqWm]CdT:dT:bR9tdK|eʾƬ˳ʹɰɰʴ˵̶ͷͷ̶˵ʴϹϹϹθͷʴȲŮȬͿcyhJq`Bn]?jY;l[?pSwíɴ̹нϺѼӾԿӾ͸˶˶ιлϺȳôweqVseHnaAobBsdEufGwfJtcGwcKnVl|«ȱʳͶϸϸйһԽӼѺϸηηϸϸηηͶͶͶ̵ηϸйѺϸ̵ɲǮɾ}\\whGl]<fW6j[:sdC}]çдδεϸͶ˳ʲɱʲ͵ζ͵̴Ŵq}kSq]BqY=pY:nV:nY<nU~ðƶʷ̶ʹʹʹʹʹ̳̳˲˲ʱʱɰɰɰɲðǳȳưƯƭʾĶwxgMp_En]CgU=jX@ueNiɲ̵ʳ˴ηйһйͶʳȱǰǰɱǱīìƪƺbyjMdU6l]>j[>m_By^zêĭƱʵ͸ϺϺϺι͸̷ʵʵ˶˶ɴȳưƭ˿r{lOiX<eT8dS7dS7m]Cx^ŹǮʳ̷θͷ˵ʴʴ̶θϹϹϹθͷ̶ʴʴɶɳűǻ{bu`EkS7lT8hS6lY;}nOp¥̯˲˵̶˵ȰƮǯɱūī©§Ǭȭƫɶk{XpJ}kE~oHuN\\iyļ­ƾƾįǲ­ºwf]`fptƽÜɥ˨ȩũƮȰį«nnPs\\=kT4jV3jV3r_?xZ}ɿíůǱȲȰɳȵȵ˸ʱĨĥcyeDt[<nW7kX7m_<phCbļƾŽŮƯĭǿƾưǱɳ˵ͷͷͷͷʴʴʴ˵˵̶ͷθ̶ͷθͷ̶ɳưĮſýýľ¬ĮŲǴʷ̹ͺ̹˸ʷʷʷʷʷ˸̹ͺλ˸̹ͺλϼλͺͺ̹̹̹̹̹̹̹̹λͺ̹˸˸̹ͺλλͺͺͺͺλλϼооооооооϽϽμͻͻͻμμϽϽϽϽϽϽϽϽμͻͻϽооμ˹̹˸˸ʷʷ˸˸̹ͺλλϼϼλλͺнϼλͺͺͺͺλ̹ͺλϼϼϼϼϼͺ̹̹λλλͺͺͺ̹ͷ̶͵ζ͵˳ʲ˳̴˳˳˳˳ʲʲʲ˲˴ϷηͶͷϹ˳ŭȮéǽvwkQaS9[L5ZI5`O=^M;[J8[L9[N;pdNoý˰ʯŧĦȪ˭ɭɭʮ̰̳ʹηϸͶͶ̷˶ɴǲŰïůë«ǭʰȯƭ|k{_tX|qUzoSrU{^k|ȿƼo|^tWbĳ̻é̲δ˰ɬǭʯϷииζ̴ʲʲ˳͵͵̴˳˳ʲɱʱʹ˲ε˳Īĺ|mVscJqaHueKscIp`Fv\\Ŭȱ̴ζ϶϶зѸ̳εʹɰǯȰƯê|axhNhX>bR8cS9`P7rbIiǭ˳̳ǮǮʴ̶θϹϹθ̶ʴϹϹϹθͷʴȲŮɭægyhJo^@n]?l[=eT8xiLqɽįʷҿлѼӾԿԿӾҽѼ̷˶̷лӾӾιȲǱʻy{`rdGgZ:fY9gX9j[<o^BtcGlTgûìƯʳϸѺϸѺһӼһйηͶηййϸϸϸηηηϸйѺйϸ˴ȱƭ^yjIl]<fW6j[:rcB_ͱ̲εϸη˳ʲʲ˳ζϷϷζƳ­u~nTo\\>mV7mV6kT5iT7zfMsƴʷθ϶϶εʹ˲ɰȯɰɰɰɰȯȯǮǰƱŰįĮǰǮȼmudHsbFraEk[Ao_E{kRpŽʳ̵ʳ˴Ͷηϸη˴ɲȱȱȱʲůê«ũƺ~axiLdU6j[<gX;j\\?w\\z©Ůǲɴ̷͸͸͸̷͸̷ʵ˶̷͸˶ʵǱǮ˿pyjMhW;eT6fU7fU7o`Cy_Źƭȱ̷ͷͷ̶˵˵θкѻкθͷ˵ʴʴʴɳɳůŹzat_DiQ5lT8iT5n[=qRsƦϱ˲ʴɳǱŭŭǯɱǭƬȾǬƫt}\\mJzhB|jDvOZl{úžƿįîįį­îȳįǿºujc_aeowż¢ħƪȰʵǰĮºlnNs\\<lU3kW4kW4s`@z[~éíůǱȲȰȲ˸ɶ̹ʱç£{_wcBsZ;mV6kX7m_<qiDdººŽƾ«ŮŮ«ǿůưȲʴ̶ͷθθ̶̶̶̶̶ͷͷͷ˵˵̶˵ʴǱůíſ¬ĮůıǴ˸λϼͺ˸ɶʷʷʷʷ˸̹ͺλ˸̹ͺλλλλͺ̹̹̹̹̹̹̹̹λλͺͺͺͺλϼнϼλλλλλϼоооооϽϽϽμμͻͻͻμϽϽϽϽϽϽϽϽϽϽϽμμϽѿѿϽͻ̹̹˸˸˸˸̹̹ͺλλϼϼλλͺϼλͺͺ̹̹ͺͺλλϼннннϼͺͺͺλλͺͺ̶̹̹̹̹͵ζ͵˳ʲ˳̴˳˳˳˳˳˳˳˲̵Ϸη̵̶θ˳ŭǭéŻorfL^P6XI2aP<aP>^M;_N<^O<XI6dXBv`ǭ̱ƩŧȪ̮ʮ˯̰βε϶ϸϸйϸι͸̷ʵʵȲưëƬʰ˲˲ĩƼ{n}atX}oRtW|_mzkxZ{pRtWkξéɮͳγ˯ɬȮ˰ζϷиζ̴ʲ˳̴͵͵͵̴˳ʲʲʱ˲ȯ̳˳é|whQqaHn^EscIrbHo_Ev\\īǰ˳͵εʹε϶̳ε̳ȯƮȰĭ~sXrbHgW=dT:eU;aQ8ueLnŭʰ͵϶ʱʱͷϹѻӽӽѻϹͷϹϹϹθͷʴȲŮçhwfHm\\>m\\>n]?fU9teHiɽŰ˸ҿϺллллϺ͸̷лϺϺѼӾѼ͸ȲͷƯʼkvhKh[;fY9gX9iZ;o^BxgKv^uóɾìƯȱ̵ѺѺͶϸйѺѺϸηηйййййййййѺѺѺйη˴ǰŬĦb|mLpa@iZ9m^=ufEaʿ˯˱εйϸ˳ʲʲ̴ϷѹѹиǴŰx^sbDnY:nZ9iT5gT4sbFjǿǴ˷ззз϶̳ʱǮƭʱɰɰɰȯȯȯǮƯĭëɯɮȺiudHudHsbFk[AtdJv]{ʳ˴ʳ˴ͶͶ̵˴ʳɲȱȱȱʲůê«ũŹ{^ufIdU6iZ;dU8gY<uZy©Ưǲɴʵ˶̷̷˶͸˶ʵ˶͸ι͸̵ɰǬ˿kvgHgV8eT6hW9hW9qbE|_ŹƫȮʳ˵̶˵ʴ˵θкҼкθ˵ʴɳʴʴȲɱŬz^t_BgR3lU6jU6o^@uVwȨϱʹʴȲůëëĬƮūéȾǽ§Ū·|eqNvd@uc=|mF~WhyĪìîîįįįįîîįįŰîƾŽº~rhccinvľīȱ˶ɲȯǽmmNt]=nW5mY6mZ9ueD~_ĺūŭ¬íůưǱȰȲʷȵʷʱĨäy}]vbAsZ;nW7lY8oa>tlGhļļûǿ««ĭŮƯŮ««ĮůǱɳ˵̶ͷθͷͷθθθͷ̶̶ʴʴʴɳȲưĮí¬¬ĮůıǴ̹ϼнλʷȵ˸˸˸˸˸̹ͺλ̹̹ͺͺλλλλλλλλͺͺͺͺλλλλλλϼϼҿѾнϼλλλλоооϽϽϽϽμͻͻͻͻμϽооϽϽϽϽϽϽϽϽμͻ̺ͻϽоϽͻͺ̹˸˸˸˸̹ͺͺλλϼϼλλͺλλͺ̹˸˸̹̹λλϼϼнϼϼλ̹λͺ̹̹̹̹˸˸ʷʷ̶ͷθͷ˵ʴ˵̶˵˵˵˵˵˵˵̶Ͷηη˴̳εʲĬĪ¨ĺipbH\\N4WH1dS?_N<XG5[J8_P;XI4\\P:shRiææ¥ħƩ˰̱ͲγϴϴεεкϹθ̶˷ɵȴȲǱƮƮǯɯ̲ͳͳɮƫ¥żtgvYtUsTvWbnmfwYxmOshJ{pRf~¨ƭʰ̲Ͳ˱ʰ˱γζϷϷζ̴˳˳̴͵͵̴˳˳ʲɱʱɰŬɰʲ¨wsdMk[BiY@n^Dn^Dm]Cv\\ĸīǰ˳͵ʹʹʹε̳ʹʱǮƮǯ«ŻxzlQl\\BeU;eU;eU;aQ8vfMnĬʰζѸεεθкѻӽӽѻкθϹϹϹθͷʴȲŮɾ˽hyhJo^@q`BsbDkZ>paDza˿ɴ˸λлллϺϺι͸̷ѼѼѼѼѼϺ̷Ȳ̶˳ūu|nQl]>iZ;k\\=k\\=p_C}lPh˻íǰʳ˴ϸһйʳ̵ͶϸϸηηйһйййййѺѺѺѺѺѺϸͶʳȱƭȪepOsdCl]<pa@xiHbȽɭʰεйη˳ʲʲ̴Ϸѹѹи̶ɲȾi{jLo\\<lY8jW6hU5p_A|_ǯ˳ζδϵδ̲ɯƬĪʰɯɯɯȮȮȮȯŬê¨ʭɪƸhufGrcDn_@j[>zkNgȾŮʳɲʳ̵η̵ʳʳɲȱȱȱȱɱǱī«Ĩ¶x[rcFeV7hY:aR5dV9sXy©ǰǲɴʵ˶˶̷̷͸˶ʵ˶͸ι͸̵ȯǬiteFfU7fV5fV5fV5o`Az]øèūȱʴʴɳȲɳ̶ϹѻϹͷ˵ɳɳʴʴȰɯê|z^vcEhU5lW8lY8tdC}[{Ȩΰ϶˵ǱĮªªªªɿĩèk{UzhBpa:sd=rKasƽèŮŰŲƳ­­îįƱƱƱƱǿǿǿŽĹ}usrrqxƲȴɳȰɽjnMu^<pY7nZ9n[;wgFbĺĪë¬ĮůƮǯǯǱǴŲȵȯĨĥy|\\vbAu\\=pY9mZ9qc@woJmûûļĭĭƯǰǰƯĭìĭŮĮůưǱɳ˵̶ͷͷͷθθθͷ̶˵ɳɳȲǱưůĮí¬¬¬¬ííıǴ̹нѾλ˸ȵ̹̹˸˸̹̹ͺλ̹̹̹̹ͺͺλλнннϼϼλλλ̹ͺλλϼϼϼϼҿѾнϼλλλλоооϽϽμμͻͻͻͻͻμϽооϽϽϽϽϽϽϽϽ̺˹ʸ˹ͻμμͻͺͺ̹˸˸̹ͺͺͺλλϼϼλλͺͺͺ̹˸˸˸˸˸ͺͺλλλͺͺ̹̹ͺͺ̹̹˸˸˸ʷʷʷ̶ͷθͷ˵ʴ˵̶˵˵˵˵̶̶̶̶̶ϸͶʳ˲ʹɱĪ¨¶|bn`F^P6ZL2`O;^M;WF4XG5\\M8WH3UI3cW?vlSkþŨǪƩ˰̱γϴеϴεʹθθͷ̶˷ɵǳůǯȰɱʲ˱˱˱ʰʯɮɬȫçvf~_rSvgHufGxiJwhIpcCh]?eZ<ncEz\\{ʼĩȮɯ̱̱̲̲ͳе͵ζϷζ̴˳̴͵̴̴˳ʲɱɱȰɰȯêȯ˳éspaJfV=dT;iY?jZ@jZ@tZ÷ƭɲ͵Ϸ϶ε϶϶̳̳ʱƭƮƮ¸utfKeU;`P6bR8bR8_O6tdKlªȮ͵зε϶ͷθθϹϹθθͷϹϹϹθͷʴȲŮɾ˽k~mOudFwfHxgIo^Bo`Cv]ʵɶʷӾҽҽѼѼлллιιлѼѼлιͶ̶͵˱ź{rUm^?iZ;k\\=j[<n]A~mQoȶĮɲ̵̵ϸһϸɲ̵ͶηͶ̵ͶϸһϸϸйййѺѺѺѺѺйϸͶ˴ɲǮƨdpOsdCl]<pa@yjIbǼɭ˱϶ϸ̵˳ʲʲ˳ζϷϷζϷ̲ũxuTp`?kX7lY8hX6m^=rRtɯ˱̲ͳδ̲ʰƬĪʰʰɯɯȮȮȮȮŪĨ§æǨã~dteDqbCn_@paDvYtêǰɲȱʳηϸ̵ɲɲɲȱȱǰƯǯǱī}wZrcFfW8hY:_P3bT7rWyêǰȳɴʵ˶̷ιι͸̷ʵ˶̷͸˶ʳǮǪʿdrcBgW6hX7dT3cT3n_@{[æĪɱʴʴȲǱǱʴͷθͷ̶˵ʴʴʴʲɯʮ§w|]xhGmZ:o\\;qa?|mLdżɩ˭϶˵ǱĮëëéīīĩǽ{~[qJuf?se>{mF~Xn~úɿêįıųƴ¯­įǲȳǲƱǿƾƾǿƾƻɽɾǹ}ıǱǱǰʾimLw_=r[9lY8l[=xiJg»ľ¬íĮůƮǯǯưŲ¯ŲǮũƧy|\\wcBv]>r[;n[:qc@xpKoºǿ«ĭŮǰƯŮĭŮǰưưưưȲɳ˵̶ʴ˵ͷθθͷ̶˵ɳȲȲǱưůĮĮ¬¬¬íííííƳȵ̹ϼнλ̹ʷͺͺ̹̹̹̹ͺλͺ̹̹̹̹ͺλϼѾннϼλλͺͺ˸̹ͺλϼϼϼλнϼλλλλλϼооϽϽμͻͻͻμμͻͻͻμϽϽϽϽϽϽϽϽϽϽ˹ʸȶɷ˹ͻͻͻͺͺ̹̹̹̹ͺͺͺλλϼϼλλͺͺ̹˸ʷʷʷʷ˸ͺͺλλͺͺ̹˸˸ͺͺͺͺ̹̹̹˸˸˸̶ͷθͷ˵ʴ˵̶˵˵˵̶̶ͷͷͷε϶ʹʱɱ˳ɯĪê{tYk]BdT:cS:`O;gVBdU@_P;_P;XI4QE-WK3e[BunRkŧʬǩȫʭͰϲее϶ε˲̶̳ͷ̶ɳǱůŬǮȰȰȮȮɯɯ̰ʮɬ̯̯Ũt_{kJp`?o_>o_>l]<g\\@g\\@vkOoūƬȮʯ˲̲̲̲͵ζ͵ζϷζ̴˳̴͵˳ʲʲɱȰǯǯȯɰêɰζūrpaJcS:aQ8fV<fV<fV<pVƭɲ͵ζεʹʹεεʹʱǮǯǯurdIaQ7^N4aQ7`P6]M4tdKnĬȮ͵Ѹε϶Ϲθͷ̶̶ͷθϹϹϹϹθͷʴȲŮ̾mpRyhJziKyhJraEsdG{bůʵȵ˸ӾҽҽѼѼѼѼҽ͸ϺлѼѼллѺ˴ε̱Ƚx[qbCj[<l[=iX:l[?~mQqʺĮʳ̵˴̵ϸϸ̵ϸϸϸͶ˴˴̵ϸηηϸϸйййѺййϸηͶ˴ʳɰ_zkJn_>hY8m^=ufEa~Ǽɭ̲϶ϸ˴˳ʲɱʲ͵ζ͵̴ͳʰǫȿe}mLrb@jZ8hX6iZ9tgG_çȮʰ̲ͳͳ˱ȮƬȮȮȮȮǭǭƬƬƫŨħå£ƻs_tfCwhGzkLsVnĸǮɲȱǰʳϸйͶɲɲɲȱǰƯŮŭůŽž}z]vgJgX9hY:^O2aS6rWzīǰȳɴʵ̷ιлѼ͸̷ʵʵ˶˶ɴȱǫƩȿcpcAfW6j\\9fX5gY6rcB_ƽȫȬ˳˵˵ɳǱǱʴ̶˵˵̶̶̶˵˵ʲʮˮ¥r}\\|lKp`>tdByiGwVoʪʬ˲ȲůůƮƮĬ¨ūŬ©ƼivS|nGykDsK[mźƽ«î¯°°ð­­įǲȳŰîǿǿŽûĩĬɽǽĸ·ƾ¯ŰƱŰƭ˽fmLx`>t];n[;o`A~oRož®ïĮůƮƮƬŮŲıǮũƧw{[vbAw^?qZ:mZ9pb?woJoŽƾŽ«ĭŮĭĭŮƯǱǱưưưǱɳʴȲɳ˵ͷθͷ̶˵ɳɳȲǱưůůůĮĮůůůůĮĮǴɶ̹λϼλͺ˸λͺͺ̹̹̹ͺλͺͺ̹˸̹ͺλϼϼϼλͺ̹̹˸˸ɶʷ̹ͺλλλͺλͺͺͺͺλλϼооϽϽμͻ̺̺ϽϽμͻͻͻμμϽϽϽϽϽϽϽϽ̺ʸɷɷ̺μϽμλͺͺ̹̹ͺͺλͺλλϼϼλλͺ̹˸˸ʷɶɶʷʷλλϼϼλͺ̹̹˸̹̹λλλͺͺ̶̹̹̹ͷθͷ˵ʴ˵̶˵˵˵̶̶ͷͷͷε϶ʹɰɱ˱ɯĪŪu|nSj\\AgW=jZAcS<tcOufQk\\GdU@[L5QE-TH0WM2e[@zpUoĽŨåŨǪˮαеѶззȯʱ˵ͷͷ˵ȲưƭȯȰȰȮɯ˱̲̰ɭȫ̯гϲƩȽǸrxWxhGvfExhGxhGshLtiMx\\}ź˯˱ȭʯ̴̴̴̰̲̲̲̲ζϷζ̴˳̴ζʲʲɱȰǯǯƮǮ˲ŬʱиǭrqbKcS:aQ8eU;dT:cS9}mS}êƯʲ˳˲ʱʱ˲϶϶˲ȯȰɱwseJaQ7^N4aQ7`P6^N5ueLsǯ˱ϷҹзѸҼкθͷͷθкҼϹϹϹθͷʴȲŮ̾lqSziKyhJwfHveIyjMkȲ˶ʷнѼллϺϺллѼлҽӾӾѼллйɲ̲˰ȿ|_ufGn_@m\\>iX:kZ>}lPqǸ˿Įʳ˴ɲȱ̵ййһһйͶʳȱʳ˴ͶηηϸϸййййϸηηͶ̵˴ʱƻ}{ZufEj[:eV5iZ9rcBa~Ǽɭͳзηɲ̴ʲɱʲ̴͵̴ʲɯǭȬƩw|[~pMhX6fX5fW6l_=tTrǾƪȮ˱ͳͳ̲ʰȮǭǭǭƬƬūūƩǪȩŧ¢Ǿ}k]ugD~oNzZhʰɲȱƯʳйѺηɲɲɲȱǰŮĭĬí¾º»~}`zkNhY:hY:^O2aS6sX{Ŭǰȳɴʵ͸ϺѼӾι̷ʵʵʵʵȳƯũŨǾbpcAgX7k]:k]:m_<xkIfĥϲϳ͵ͷͷʴȲȲʴ̶Ȳɳ˵̶ͷ̶˵ʲ˯̯p]~pMseBxhF}oL~\\xŦ˫ɬǯůĮưȰɱƮë¨ūêǽq{\\~tP{rIsKZm~ȿȿìŰŲıñ°Ųîîįǲǲîî­ŽºɾƭɳȯǱʱůɿ̿ʿʿıƳǲǲ¬ĬʼfmLw`>t`=q`BseHuZwëĮþ®ïĮůƮƮƬŮƳ¯ıǮũŦuyYua@v]>pY9kX7n`=vnInļļººŽŽûļǿ«ĭìììĭȲǱưůůưȲɳưȲʴͷθͷ̶˵ʴɳȲǱưưưưưưǱǱǱưưůȵʷ˸ͺλλͺͺλλͺ̹̹̹ͺͺλͺ̹˸̹ͺϼнͺͺ̹˸ʷɶɶȵȵɶ˸ͺλλͺͺ̹̹̹̹̹ͺϼϼооϽμͻͻ̺˹ооϽμͻͻͻͻϽϽϽϽϽϽϽϽͻ˹ʸʸͻϽооλͺͺ̹̹ͺͺλͺλλϼϼλλͺ̹˸ʷɶɶɶɶʷнннннϼͺͺ˸λλͺͺλϼϼϼλλͺͺͺͺͺͺͺͺ̹̹̹˸˸ʷʷ˵ʱȯ˰еͳƬƬ̰˰ɽgxhNm]CiY?fV=l]Fvaqi}nWpaJbV>XL2VJ0]Q7dY=ofIfĻž½æ̯ггͰ˱˱˱̲͵͵̶˵ɳȲȯȯȯɰʯ˰̲ͳ˯˯̯ͰαϲϲϱȩŤ{ZxhGvfE|lKxW}oTx]sè̱γдʰʰɲ˳˳̴̴͵̴͵ζζζζ͵̴˳ɱǯƮŭŭƮǮŬ̳īʲƬvvgPfV=`P7bR8cS9dT:}mS{êƯɱʲɰɰ̳϶ҹ̳ȯɰ˳ɱ¸wseJdT:cS9aQ7[K1]M4oVt˳ʰɱ̳̳зҼѻкϹθθθθθθθϹ̶ȲǱȱɭǹcoQxgItcEraCm\\@x[¶ůιϼ̹ҽѼлϺϺϺϺϺϺѼӾԿҽллйζδ˯Ǿ~aufGm\\>lY;kX:m\\@|kOq˼ůƯǰȱʳ̵ηϸֿԽѺϸ̵˴˴˴һѺйϸϸϸϸϸηййͶͶϸ̵ƭĹvpOo`?iZ9dU4fW6l]<`̰˱ʹηͶȰȰȰɱʲ˳̴͵ϴ̱ʭȫo|ZvhEi\\9eX6m`>xkIzZvç˯ͱͱϳͱɭȬǫǫȬɭɭƪŨɬƨƿviarOwT_p˿ƫδɲƯȱͶйη˴ȱǰŮĭ«««ëſļž|z]whKgX9fW8aR5dV9~pU}¸êƯɴɴǲɴϺҽл͸˶ɴɴʵ˶ʵɲū¥¹_pcAgX7k\\;m^=sdCuUnͰжζͷ̶˵ʴʴʴʴɳɳʴ̶θθ˵ȰǫƩu^uSrPwV^pƽɬˮɬƮĮííŭǯǯƮĪƬīƼ{iz[wR{T`s¹¥ūĭ«¯ĲĲŲƱǲȳǲƱįîîî­ǿûºûìŰŮŰŮǲɲɷɷȶȵŲ¯ǿŽíªŷb}iHvbAvcBufI}rVkƮư®îįíĮĬŭūŮŲƳȵǮũɪryYq]<rY:pY9kX7j\\9vnIuûììŽûŽǿ«ĭƯǰǰǰȲǱůĮííĮůǱɳ̶ϹкϹͷ˵ǱȲȲȲȲǱưůǱǱǱǱǱǱȲȲʷ˸̹λλͺ̹˸λλλͺͺͺ̹̹ʷʷ˸̹ͺͺλϼ˸˸˸˸˸˸ʷʷȵɶɶʷ˸̹ͺͺ˸˸˸̹̹ͺͺͺͻͻͻͻͻͻͻͻͻμμμμͻ̺˹ͻͻͻμμϽϽϽͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹˸˸˸ʷʷɶɶɶͺλλλλͺ̹˸˸λλͺλλλλλλλͺͺͺͺͺͺͺͺ̹̹̹˸˸ʷʷʷ̳ʱ˰γ˱ƬƪʯƬĸ}btdJjZ@iY?iY?yjSrvw`l`FYM3SG-WK1\\Q5g\\@|qUoĿʭггαͳδδϵϷζͷ˵ȲǱȯȯȯɰʯ˰̲ͳ̰̰̯̯̯̯̯˭̭ȧ_~nM}mLrQ}\\~cizŪͱͱ̰Ȯɯʲ˳˳˳˳˳̴̴͵͵͵͵̴̴˳ʲȰƮŭƮƮȯŬ˲īʲƬuufOgW>aQ8cS9cS9dT:oU~īƯʲʲʱ˲ʹ϶з̳ɰʱ˳ȰƾvrdIcS9`P6^N4YI/ZJ1zjQu̴˱ʲ̳ʹҹѻкϹθθθθθϹϹϹθ̶ɳȲȱɭĶz|]yhJp_Am\\>l[=tcGdȼȲϺнλҽҽѼлϺϺллϺѼӾӾѼлϺйζδͰbveGm\\>lY;kX:l[?{lOqʾ©Ưǰǰȱʳ̵ηϸվӼѺηͶ̵̵̵ѺѺѺѺййϸϸηйϸ̵Ͷη˴Ŭøt~oNo`?j[:fW6iZ9pa@d¦̰˱ʹͶ̵ɱɱɱɱʲ˳̴͵ϴͲ˱̯ǪlxVylJqdBsfDxkItRiĨǫʮʮǫǫǫƪǫȬǫĨ¦žynhdcjwȭ̳Ͷʳǰȱ̵ϸ̵ɲȱǰƯĭì««ë¾ļĽ{x[ufIgX9fW8bS6eW:qV~©ƯɴɴǲɴιлϺ˶ʵɴɴʵʵɴǰéĽzy[k`@h[;o`?teD{nN`zħʮ˱͵̶˵ʴʴʴ˵˵ɳɳʴ̶θθ̶ɱǫƩ{h`^isæʯ̰ʰƮĮ¬¬ĬƮƮƮūƬīƼtkgkuƩȬŮĭî­¯ðıŲǲǲɴɴɴǲƱŰîįîļºļǿ­îîîįƱǴǴǴŲðƾŽīɽ{{]|lK{hH|kMsVf|ªɳǳïîįíĮŭŭƬŮŲŲȵǮũȩqsSmY8pW8pY9lY8k]:umHrƾŮƯļļƾǿìŮǰȱȱȱȲǱưůĮĮůưȲʴ̶θϹͷ˵ʴůưǱǱǱǱưưȲǱǱǱǱǱȲȲɶʷ̹ͺλͺ̹˸λͺͺͺ̹̹̹˸ʷʷ˸˸̹ͺλλ̹̹̹ͺͺͺͺͺʷʷ˸˸̹̹ͺͺ˸˸˸̹̹ͺͺͺͻͻͻͻͻͻͻͻͻμμμͻͻ̺˹ͻͻͻμμμϽϽͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹˸˸˸ʷʷʷɶɶ̹̹̹̹̹˸ʷʷʷλλλλλλλλͺͺͻͻͻͻͻͻͻͻ̺̺̺̺˹˹˹˸ζ˱ɯ˱ʮȬǬʯusXn_BhY<n]AtdJ~gĵȹt}oUeW=YK0WI.YK0`R7j\\?ujLz]jǩвϲˮˮ̯жжиϷ͵˳ȰƮȯȯȯɰʯ˰ͲγͰͰˮˮʭɬȫȫˮɩesTpQrSz[fjzŪͱ˱Ȯǯɰʱ̳˵ʴȳǲʲ˳˳̴̴˳˳ʲ˳ʲɱǯǯƮƮȯŬ˲êɱūtteNiY@bR9cS9bR8eU;sYŬǰ˳̴̳ʹε϶ε˲ʱ˲˳ǯŽvtfKdT:_O5]M3YI/ZJ1vfMrʲ˱ʲ˲˲ѸкϹθͷͷθθθккϹͷ̶˵˵ɲĨruVsbDl[=l[=n]?qUrĬ˵ιϼϼӾҽѼлллѼѼлҽӾӾѼϺϺѹ϶еϲ¥cveGl[=jW9jW9kZ>{lOqūǰǰǰȱʳ̵ηϸһѺйϸηͶηηйѺһӼһѺйϸͶϸη˴̵Ͷʳīq{lKo`?k\\;gX7k\\;teDi¦̰ʰ̵̳ʳɱɱɱɱʲ˳̴͵϶γϴгϲħsdyYtT~qO~qO|ZjùȾȾɿǽƼǽǽƼĺxpmoq~ʼū̳϶йη˴ȱɲ̵ͶʳǰȱȱǰƯŮììë¬ÿļüwuXrcFgX9fW8bS6fX;sXŮȳɴƱȳ͸Ϻ͸ɴȳȳɴʵʵǲĭwy]rgItgG|oOvV`sżǫɭƬ˳˵˵ʴ˵̶̶ͷȲȲȲ˵ͷθͷ̴ǭǪ¥zww¥ǬʱɳʳǱĮªŭƮǯƬƬêǽƩɯ̴ƮůĮĮĮĮůưȳȳɴʵʵȳǲƱŰŰįŽººĽııııŲƳƳǱưůíǿ©÷s|auXw[}`l{ŽǯɳűîîîíĮŭŮŬƭƳŲǴǮĨƧpoOkW6pW8qZ:o\\;pb?xpKrüȱȱìǿ««ĭǰȱɲȱȱɳȲǱǱưǱǱȲɳ˵̶θͷ˵ɳǱíĮůưǱǱǱǱȲǱǱưưưǱǱȵɶ˸ͺͺͺ̹˸ͺ̹̹̹˸˸˸ʷʷʷ˸˸̹ͺͺͺͺͺͺλϼϼнн̹̹̹̹ͺͺͺͺ˸˸˸̹̹ͺͺͺͻͻͻͻͻͻͻͻμͻͻͻ̺̺̺˹ͻͻͻͻμμμϽͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹˸˸˸˸ʷʷʷɶʷʷʷʷɶɶȵȵʷϼϼλλͺͺͺͺͺͺμμͻͻͻͻ̺̺̺̺̺̺̺̺̺˸и̲ɯɯ˯˯ɮȭ~ctfKgX;gX;wfJw]|ʻʻzy_seKeW<]O4ZL1]O4^P3aS6pbEvX|ΰαɬǪǪδδϷζ͵˳Ȱǯȯȯȯɰʯ˰Ͳγ̯ˮʭɬȫȫǪǪƪħhsV{lMwhI{lM{mSsYnũϲ˱ȭǮȯʱ˲ʴɳƱŰɱʲʲ˳˳ʲʲɱ˳ʲʲɱȰǯǯȯŬ˲êȰérqbKiY@cS:cS9bR8gW=x^Źƭȱ˳͵϶϶϶϶̳˲˲̴̳ǯļwxjOhX>_O5^N4^N4]M4tdKhëʰ˳ʱǮ̳θͷͷ̶ͷͷθϹкѻϹͷθкθʳȽipQraCn]?tcE{jLe̼˳̶͸λϼҽҽѼѼлѼѼҽѼӾԿҽлϺϺѹ϶ѵϲ¥cveGkZ<iV8iV8kZ>{lOq¨Ƭǰǰȱɲʳ̵ͶηϸϸϸϸϸϸϸϸϸѺӼԽԽһйϸ̵ηͶ˴˴ͶɲênyjIn_>j[:eV5j[:ufEkɭȮ˲̵ʳʲʲʲʲʲ˳̴͵϶϶зѶж̯çżsha{Y~]fx{y|³Ǹǫ˲Ͷηηη̵ʳʳ˴˴ȱƯɲɲȱǰƯŮĭĬíÿûtqTn_BgX9fW8cT7i[>v[¸ɿŮȳɴƱȳ̷͸ʵǲǲǲɴʵɴŰ­m|`~ahqyĨʰɯǯʴʴʴʴ˵ͷθϹɳȲǱɳ̶θθζɰɮŪǾǾǪʯȯůƲɶȲĮþĬǯȰǭǭīɿ¸¢ŧŨĪƮɳưưůůůŭƮƮǲȳɴʵɴȳƱŰƱƱƱîǿûºº»ƿŲȵɶȵȵɶʵʳʳȲȲǯƮŮɿwnntyºŭưĭ­­îîíĮĭƬƫǮȵıƳǮĨänpPmY8qX9r[;r_>wiFxSyìȱȱĭ«ĭìĭƯȱɲɲɲȱɳȲȲȲȲɳɳʴ˵˵̶̶˵ɳưů¬íůưǱǱǱǱưůĮĮĮůưǴȵʷ̹̹̹˸˸̹̹˸˸˸ʷʷʷʷʷʷ˸˸̹̹ͺ˸̹ͺλϼннѾλλͺͺͺͺͺͺ˸˸˸̹̹ͺͺͺ̺̺ͻͻͻͻμμμͻͻ̺̺˹̺̺̺̺ͻͻͻμμμͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹̹̹˸˸˸ʷʷʷ˸ʷʷɶȵȵȵɶʷϼϼϼλͺ̹˸̹̹ͺμμμͻͻ̺̺̺̺̺̺̺̺̺̺ͺϷ̲ʭʭ̰ͱȫ¥n{lOj[>dS7iX<pTp¶̾Ƹv{`|nSugLl^CfW:bS6\\M0YJ-fW:wiLh|ŨˮʭȬȬɭʮ˱̲˴ɲȱȰȯȯȯɰ˯̰Ͳγʭʭʬʬɬɬɬɬæ¦h}rVseHj\\?i[>eW=qcIeĪδͲʮȯȯȲɳɳȲƱŰɱɱʲʲʲʲɱɱ˳˳˳ʲɱȰȰȯŬ˲©ǯ¨po`IhX?cS:cS9aQ7hX>}cȼǮȱ˳͵зз϶εʱʱ˲ʹ̴ǯŽz}oTl\\B`P6_O5aQ7^N5p`Gs\\ĸƬζ̳Ǯɰ̶̶˵˵̶ͷθϹθѻкͷϹҼϹǰ}~_{lMraCsbD}lNxZvŬϷͷ̷ͺϼѼѼлллѼҽҽӾӾԿҽϺιϺѹ϶дͰ}`tcEkX:gT6gT6jY=ykNréȮȱȱȱɲʳ˴ͶηηηηϸййййηйһӼԽһйϸ̵ηͶ˴˴ͶɲêmwhGm^=iZ9bS2gX7ufEkȽũƬ˲Ͷ̵˳˳ʲʲ˳˳̴͵ϸϸϹзз̲ɯƪƼxspu|ĵɺ¨ƬǯǱȳʵͷ̵̵˴˴˴ʳǰŮʳʳʳɲȱƯŮĬíÿºq}nQk\\?gX9fW8eV9l^A{`ĺɿŮɴʵǲȳ˶˶ɴƱƱǲɴʵɴŰ­ľ}~Ⱦǭʳ˳˵ʴʴʴ˵̶θϹкʴȲǱȲ˵θϹϷ̳˰ɮƩƿ¥ŨȬδͶǳĲĴȷǴůĿĬǯȰȮǭŬȾƼȾŦɬɮƭííűƲƲǱǱǯǭǪƬƯǲȳȳȳƱŰįƱǲǲŰŽûûĽ®ȴ˷̸˷˷̸̴̴˳ɰɰɰȰȮžļŮȲİ¿®ïîíůŮǭǬȯɶıŲǮçlrRo[:qX9pY9s`?}oL\\ìƯŮì«ĭĭŮǰɲɲɲȱǰȲȲɳʴʴ˵˵˵˵˵˵˵ɳǱĮííůưǱȲȲưůí¬íƳǴɶ˸̹̹˸ʷ̹̹˸˸˸ʷʷʷʷʷʷ˸˸˸˸̹ʷʷ˸̹ͺλλϼλλͺͺͺͺͺͺ˸˸˸̹̹ͺͺͺ̺̺̺ͻͻμμμμͻ̺˹ʸ˹˹̺̺̺̺ͻͻͻμμͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹̹̹̹˸˸˸ʷʷͺ̹˸ʷɶɶʷ˸˸ϼннϼͺ˸ʷ˸̹̹ϽϽμͻͻ̺˹˹̺̺̺̺ͻͻͻͺζͳʭʭ˯ʮvuZl]@dU8dS7jY=tXwƺ˽p|av[~cx]~oRsdGhY<bS6gX;oaD{rUfȫ̰ͱǫȬɯ˱ʳɲȱȰȯȯȯɰ˯̰Ͳγˮˮ˭˭ʭʭʭʭĩ§fymSmbFdV;cU8aS9pbHhĪγͲ̰ʱʱȲȲȲǱƱƱɱʲʲ˳˳ʲʲɱ˳̴̴˳˳ɱȰȯŬʱ©Ʈnm^GeU<bR9cS9aQ7jZ@hɽǮǰʲ͵ѸѸ϶ʹʱʱ̳ʹ̴ȰŻy^tdJcS9`P6cS9]M4iY@xiRsĽ͵϶ɰʱʴʴʴʴ̶ͷθϹͷѻк̶ͷкɳŽotUwhIudFziKy[kȹ˲ѹͷ̷ͺλллϺϺϺлѼҽԿԿԿѼϺιϺѹεβʭ»z]q`BjW9fS5fS5iX<ykNrūɯɲȱȱɲʳ˴̵ͶͶηϸййййϸηϸйѺһѺйϸͶϸη˴̵Ͷʳī·lufEm^=j[:bS2gX7whGnǼçū˲ϸͶ̴̴˳˳˳˳̴͵ηйкϹ̶̳˳̲ȮøúżĻĻ¹¹ƸʼħƬɯȱǱİıȵ̹ʵ˴˴̵˴ɲǰŮʳ˴˴˴ʳȱŮŭí¾nzkNiZ=gX9fW8fW:oaDeȾǰʵ˶ɴɴ̷˶ȳȳǲǲȳɴȳƱîýõʼɽŮȳ̶ͷ˵˵˵˵̶θϹк̶ɳǱǱʴͷϹϹ̶ʹ̳ɮȬɬˮαȬ̲ϸ͸ǵóĶȷǴů¬ëƮȰȰȮȮǮī§èƪŨȬʯ˲ɳǳűűƲǳȲɰȮɬȪǪŮƱǲȳǲƱįîŰǲȳƱîǿƾľžïǳɵʶʶʶ˷̴̱˰ȮȮǮǬƬĽǼìɱͷ˵Ʊ­®İïîïƭŮȮȭɰʷðıǮ¦jtTq]<sZ;qZ:wdCwTe¦«ìì«ìŮƯǰɲɲȱǰƯưǱɳʴ˵̶̶˵˵˵ʴɳǱůí¬¬ĮưǱȲȲȲǱů¬ſ¬íıƳȵʷ˸˸˸ʷͺ̹̹̹˸˸˸ʷʷʷʷʷʷ˸˸˸ɶɶʷʷ˸̹̹̹̹̹̹̹ͺͺͺͺ˸˸˸̹̹ͺͺͺ˹˹̺ͻͻμϽϽμͻ˹ʸɷʸ˹̺˹̺̺̺ͻͻͻͻͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹ͺ̹̹̹˸˸˸˸ϼͺ̹ʷʷʷ̹̹ͺннѾϼͺʷʷʷ˸̹ϽϽμͻͻ̺˹˹̺̺̺ͻͻμμλδαʮȬȭè|aqcHbS6dU8gV8jY;rTttgflyhuVzkLtcEn_@neFvpPdzĨȬɭʮ˱̲˱ʰɯȮȯȯȯɰ˯̰Ͳγϲαΰ̮ͯͯʭʭɭéy^pfKh_BbW;cX<jZAykQqé˰ʹεδ̲ɲǱưǱǲȳʲʲ˳˳˳˳ʲʲ˳̴̴͵̴ʲȰȯīʱŭlk\\EbR9aQ8bR8aQ7l\\BkȼƭƯɱ͵ѸѸε˲ʱʱ̳ʹ̴ɱìnqWk[AeU;gW=]M4eU<o`I{c{Ĭʹɰ˲ɳɳɳʴ˵ͷϹкθҼѻʴɳɳľv}`zkLwhI}lNxZoŴæ϶ҺϹϺннιιιιιϺлѼԿԿѼι͸ιѹδ̰Ǫ|vYn]?hU7eP3eR4hW;ykNrƬ˱ɲɲɲɲʳ˴̵ͶͶηϸйййϸηͶηηϸϸϸййηйϸ̵Ͷη˴Ŭ·kufEn_>l]<eV5k\\;}nMuɾĨƬ̳ϸη͵̴̴˳˳˳̴͵ιѼҽѼ̸˵ͷиϵɮç̾;οɾħŨ¥¥ŨǪƩħ¥¥æħæ˿§éĪǮʰʳȲİıȶ̺ȳʳ̵̵˴ȱǰƯ˴˴̵̵˴ɲƯŭlyjMhY<fW8fW8gX;rdGj§īȱ̷͸ʵʵ̷˶ǲʵȳǲǲȳȳǲŰ¯žƾ­Īŭŭī¬îŲȵ̸̶̶̶̶̶ͷϹϹθ˵Ǳưɳ̶θϹ˵̳˲ʯʮ˯αгɯ˱˴ɴó´ŶǴưĮĮƮȰȰȰȮɯɰǮĩèĩƪŪƭǮʳ͸̹ʷǴƳǳȲʱʭɫȨǩƯǲȳɴȳǲŰįįƱȳǲįĮǱȲȲȲɳ˵ϴͲ̱ʭȬȬǬǬǭǭƮĬĮȵͷʲ͵Ϲͷɴį®ïïîïƭƯȮɮɰ˸¯ðǮ¦hwWwcB{bCzcCnM`pç«««ìŮƯǰȱȱǰŮĭĮưȲʴ˵̶̶˵ʴɳɳǱưĮí¬íĮůǱȲȲȲȲɳǱĮíĮðŲǴɶ˸˸ʷʷλͺͺͺ̹̹̹˸ʷʷʷʷʷʷʷʷʷʷʷʷʷ˸˸˸ʷʷ˸˸̹̹ͺͺ˸˸˸̹̹ͺͺͺ˹˹̺ͻͻμϽϽμͻ˹ɷɷʸ˹̺˹˹̺̺̺ͻͻͻͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹ͺͺ̹̹̹˸˸˸ϼͺ˸ʷɶʷ̹ͺϼннѾϼ̹ʷɶʷ˸̹ϽϽξͻͻ̺˹˹̺̺̺ͻͻμμλ϶ϴʰǭŬǽt~nThX>^M1fU7jY;jZ9~nMlq{ax^l~Ⱥ̾ŷserUpbEj_AmdExoPcyṵ̲̈ͳ͵̴ʲȰȯȯȯȯɰ˯̰ͲαӶӴѳϱ̮ͯʭɬ˯{qXi_DdZ?cX<f[?p`GqWvǭʹҹ϶ʹʳưưƱǳɵɲ˳˳̴̴˳˳ʲ̴̴͵͵̴˳ɱǯīʱŭȽmj[D_O8_O6bR9bR8m]DlȼƭŮȰ̴ѸѸεʱʱ˲̳ʹ˳ʲƯīƺ|}cscIk[Al\\B_O5dT:iY?|nSgúǪǩʭȮȮȰɯ˳ͳϷжζӹѹɯŭéiqTsfFwjJvWkɺͽȮҸҺмоҿѾ͸͸͸͸͸ιϺлԿѼι͸ιѻʹ˯ĩysVm\\@gT6dQ3dP5gX;ykPsƬ˱ʲɲɲɲʳ˴̵ͶͶηйѺѺйϸηͶͶͶͶͶηϸйηййͶͶϸ̵ƫ·gtgDob?na>gZ7na>tRy£Ʃǭ̲зʹ͵͵̴˳˳˳̴̴κѽӿѽ͹̸ϹӽѺδȭĪƫʭˮȫȫ̰̱ɭǬ˯̱̰ŪĨ¦ĩǫǬȬɰɰȯǮūĪĪĪĭɱ˵ɵƱıǵ˸ǲɲ˴̵˴ȱǰƯ˴̵ͶͶ̵ɲƯƮ©jyjMiX:gV8gV8iX<ufIméƭɲ͸ι˶˶͸˶ǲ˶ɴǲǲȳɴȳǲȵŲıȳʵɳʴ϶ǱǱůî­¯Ųɵͷͷ̶̶̶ͷθϹк̶ȲưȲ˵ͷθʳʳʱ˱ʰ˯˱̲ȮȰǰįȿʾǴưůůǯɱɱȰǰʰɳɰƭê©Īê©íȱ͹ϼ̹ɶǴǳɳ˲ʰʭȪȫǰȳɴʵɴȳƱŰîŰȳȳŰî¬ůưȲȲȲȲʴ̶ѹиγ˱ʰɰɰʱ̴ζθ˵ƳǴ˸ѻɱ˱͵ͷɳŰîíŭǭɭɮʱ̷¯íǬg|X|jFlIoKzXkxĨĪ««ŭŮǯȰɱȰǯƮĬëƭǱʴ˵̶̶˵ɳɳȲǱůĮ­¬ĮůưȲȲɳȲȲ˵ɳů¬¬ĮưðıǴɶʷ˸ʷʷλλλͺͺͺ̹̹ʷʷʷʷʷʷʷʷ˸˸˸˸˸˸ʷʷȵɶɶʷ˸̹ͺͺ˸˸˸̹̹ͺͺͺ˹˹̺ͻͻμϽϽμͻ˹ɷȶɷ˹̺˹˹˹̺̺ͻͻͻͻͻͻͻͻͻͻͻλͺͺ̹̹ͺͺλλλλͺͺ̹̹̹ͺͺͺ̹̹˸˸˸ϼͺ˸ɶɶʷ˸̹нϼλͺͺͺͺͺͺͺͻ˻˻˾ͽͽξϿϿͻ̺˸ʷʷʷʷ̸̷Ϻιɳ­ys[lX?hT;hS8iT7iT5lY8zgFxWmnh}`x\\hɽƺo{`~oRpaBk\\=ufIuXh}ƿɱз̶ɲ˴˶ɴůưƮƭŪǬ̮вѳбϰ̫ȨǧȨʪèŻ{uiOaU;[O5\\N4bT:i[AxlRrĪǭɮͲεʹ̳ʲʴɴȴȴʵ̶ͷθθθͷͷ˵ͷϹθ˵ɳȲȲȲůƻ|ihWCcQ=dR<eU>aQ8iZCkȱȰ˳ѹѹ̴ʲ̳Ȱ˳͵˳ǯƮʲδé{y^seHj\\?j[<k\\=l]<ufEvSg|ȥʩ̬ˮͭͰϯϲаα̬ˮͭɬn|]xXuUzZkĪ͵͵θϻϽϿҿлкϹͷͷθϹϹҼҼѻкϹϹϹϹ˳ɯéxqVj[>cR6_N2bS6]M3wiOvη̴ʲʲɱȰǯȰ̴ϷҺҺѹиζ͵̴̴ηϸйѺѺѺѺййһйͶ̵̵ȱçfypGqh?qhAqhA{rK\\ƧȫʭҶӷͱииζ͵̴˳˳˳ϹϹϹϹϹϹιι̷̵˴ʴ˵εзѸѷжͳ˱ʰɯʰʰɯȮǭȮʰ˱ʰɱ˴˴˴ʳɲȱƯŮŮŮƱǲȲɳɶʴǱȲɳʴ˵ʴɳȲ̶ʴɳʴ̶ͷ̶ʲȭ`vcElY9iT5kV7n[=|iKmĪ˲̵͸͸ιι͸͸̷ȳǲǲƱƱǲǲȳʴ˵˵̶˵ɴǲƯƱƱŰưưǱȲȲкθ˵ɳȲɳʴ˵θͷ˵ɳʴ˵θϹʲζйѹϷδиҺɱɱɱɱȲư­¬îůƱȳʵ͸ιϺʵʳɴɲɲȱȱȱȲɳ˵̶ͷ͹˸ʷʷ˵̶˵˳ɱȰǯůǱɳ˵˵ɳưĮȲɳɳɳȲưĮ¬ƿ¯Ųȵʷ˸ʷʷ͹̸ɵƲűűŲƳǴʷ̹˸ȶǵȶ˵ǫǪƪūŭůŲƲ®ūɭˮʯʳʴɯȬ nYtJrHrHyQbxÿæŨūƩūūƬȭǭɮ˲̳˲ɰƭī©ǫɰ˲ʱɰɰɰȲǱðǿʿŲƳȵɶʷɶȵǴ̹ȵı¯ðııðȵǴǴǴȵʷ̹λ̹̹̹ͺͺλλλ̹̹̹̹̹̹̹̹λλͺ̹˸˸ʷɶȵʷͺϼнϼλͺλλͺ̹̹̹ͺͺʷʷʷʷ̹ͺϼн̹̹˸˸˸̹ͺͺλλͺ̹̹̹ͺͺͺ̹˸̹λϼλͺͻ̺̺˹˹̺̺ͻϽμμμϽоѿѿͻͻͻͻͻͻͻͻ̹˸˸ʷʷ˸˸̹λϼλͺͺͺͺͺͺͺͻ̼˾˾̿ͽͽξξ̸̺̺̹̹̹̹̹ϻκɶ®lweMiU=fP8dO4fQ4jU6o\\;~kJ{ZvVz[~acjy¸ŪèƼ}x\\yhJl[=l]>qbEykPcwý˲̵ʳ˳ɴƱíîŭĬŪǬ˭ΰвббέʪɩʨ˫¥vqeK`T:\\P6]O5aS9dX>wmRtƬɯ˰γεε̴̴˶ʵȵȴʵ˵ͷθθθθθͷϹкϹ̶ɳȲȲǴŲðîɼ|jjYEaO;bP:eU>eU>n_HpêȱȰ˳иѹ̴ʲ̴Ȱ˳͵˳ǯƮɱͳƬȺry^ykNrcDn_>n`=sc?}mI|Uhzų̾ƢƤȦɧ˩̪ͫάͫʨǥĢýwgzY|[`nȭԻͷͷκϻξϿҿѾѻкϹθϹϹкӽҼѻϹθθθθʳȱ©w~pUiY?bS6`Q4cT7]O5uiOwͶʳʲ˳ʲɱǯȰ˳ζѹииϷϷζ͵͵ηϸйѺѺѺѺйϸѺй̵̵ͶɲħexqEpi?rkAwoH}VjȿˬˬˮѴҵͱδζ̴˳ʲʲʲʲιιιιιιιι̷̷˶˶̷ιлѼѹϷ͵˳ʲʲʲʲɱȰǯȰʲ˳ʲɱ˵˵̶˵˵ʴȲȲǱȲȲȲȲɳɳɳưǱɳ˵˵˵ʴɳ̶ʴɳʴ̶̶˵˲Ǭ½~`vcClW8jS4mV7q\\?mOqĪʱ˵͸ιιιι͸̷ɴȳǲƱƱƱǲǲʴʴ˵̶˵ʴȲǱȲǱǱưưǱȲȲϹθ˵ɳȲɳʴ˵̶˵ʴʴʴ˵ͷθȰ˳ϷϷζ͵ϷѹɱʲʲʲȰƮĬëîįƱǲɴ˶͸͸ʵʵʵɴɴɴȳȳȲɳ˵̶̶̶˵˵˵˵˵˵ʴȲǱưưǱɳʴʴɳȲǱɳɳʴɳȲưĮ¬¯Ųȵʷ˸ʷʷ̺˹ȶƴĲĲųƴųȶʸɷǵųƴɳǫƩũĪìîııǿƬɭˮ˯ʲɱȮħ¸~b|OtGvI}R_sãŨȫɬȫŨéƫȭ˰˰̳̳˲ɰǮƭĪƪɭɭǮƭƭǮǱưð¯ðƳǴɶʷ˸ʷɶȵ˸ȵı¯¯ðððŲŲƳǴȵɶ˸˸̹̹̹ͺͺλλλ̹̹̹̹̹̹̹̹λλͺͺ̹˸ʷʷɶʷͺϼнϼλͺͺͺ̹̹̹ͺλλ˸˸˸˸̹ͺλϼͺ̹̹˸˸̹ͺͺλͺͺ̹̹ͺͺλͺ̹˸̹λϼλͺ̺̺˹˹˹˹̺̺μμͻͻμϽооμμͻͻͻͻͻͻ̹˸˸ʷʷ˸˸̹λλλͺͺͺͺͺͺͺͻͽ̿ͽͽ̼̼̺̺ʸ˹ͺλλͺ̸̹ι̷İt]jX@fR:bN5aM2gT6q^@{kJ{Zhfmt}ĺŪĩêīíɾxd~mQqbEk[Al^CxmQ}b|ſʱʱȯŮĬŭŪƫɭ˭ΰϰѲбͭ˫̬̬omaG`T:^R8]O5^P6_S9vlQwȮ̲ͲеʹεζϷ͸̷ɶɵɴ˵̶θϹϹϹϹϹѻѻϹ̶ɳȲȲưǱƱŰʽ}il\\E^N7_O8eU>hX?seKrīɲɱ˳ии̴ʲ̴Ȱʲ̴ʲǯƮɱ˴˲ĪŹ|guXzmMwjHwiFxjGqL~Yj|¼ľãťƦãulmq|¥̱ҹͷͷκϻξϿҿҿҼѻккккѻԾӽѻϹθͷ̶̶ʳȱ©v|nShX>aR5bS6eV9^P6uiOw̵ɲ̴̴˳ʲȰȰʲ͵ϷϷϷϷϷζζζηϸйѺѺѺѺйηйϸ̵Ͷη˴ƪj}vLumFzrK|Wjżȩбα̱ееͳ˴̴ʲɱɱȰȰɱιιιιιιιι͸̷˶˶̷͸ϺлиϷζ̴˳ʲʲʲʲȰǯȰʲ˳˳ɱʴ˵˵̶̶˵ʴʴʴʴɳɳɳȲȲȲůǱɳ˵̶̶˵˵̶˵ɳʴ˵̶˵ʱƫþ~`vcCkV7jS4lU6r]@qStéɰ̶͸ιιιι͸͸ʵɴȳǲƱƱƱǲʴʴ˵˵˵ʴɳȲȲȲǱǱǱǱȲȲθͷ˵ɳɳɳʴʴʴʴʴ˵˵̶̶̶ǯɱ̴͵͵͵Ϸиʲ˳ʲʲɱǯƮŭįŰƱǲȳɴʵ˶˶˶ʵʵʵɴɴɴɳʴʴ˵̶˵˵˵̶̶˵ʴɳǱưůǱǱȲɳɳʴʴʴɳɳʴʴȲưĮíıǴɶʷʷʷ̺˹ȶƴųųųƴñųǵǵƴųųƳǭƪũĪĬĮðð¯ëǭˮ˯˯ʲʲƬĽu^yOxNVdvĦɬƩɯ˱ɯĪªŬɰεεʹ̳ɳȲǱǮƬǭƭŬêêíůůĮ­­­įűǲȵɶʷ̹̹̹ʷʷ˸Ǵð¯ðð¯ðıƳȵɶʷɶɶ̹̹ͺͺͺͺλλ̹̹̹̹̹ͺͺͺλλͺͺ̹˸˸˸ɶ˸ͺλϼϼλͺ̹̹̹̹ͺλϼнͺͺ̹̹̹ͺͺλͺͺ̹̹̹̹ͺͺλͺͺ̹̹ͺλλλ̹˸̹λϼϼͺ̺˹˹ʸʸ˹˹̺μͻͻͻͻμϽϽϽϽμμͻͻ̺̺̹̹˸˸˸˸̹̹λλͺͺͺͺͺͺͺͺͻϿξͽ̼˻ʸʸȶɷ̹ͺλͺ˸ɶȲȲĮoxhQfT>cQ9aP6fR9o^BoSfwƩȭȭƫŪŬŬů¬ȽŹnv\\vhMn`EqfJ{pTbxǪƩéǿ«ŭƮǬǬɭ˯˭ͯббΰ̬̬ˮèmj^D`T:_S9\\N4[M3[O5vlQ{ɯ̲γϴʹεϷѹϺιʷɵɴ˵̶θϹкккϹккθʴȲǱȲĮƮǲƯȽ|el\\EaQ:_O6dT;hZ@tfLqŪʰɱ˳Ϸи̴˳͵ɱʲ˳ʲȰǯɱ̴ͳ̳ɰvjb~\\xVwT}Zes~Ļ¥ƫʱ˲θθκϻϽϿϿѾҿӽҼҼѻѻѻѻԾӽѻϹͷ˵˵ʴʳɲêtykPfV<aR5dU8gX;_Q7vjPw˴ȱ̴͵͵˳ɱȰʲ˳͵͵͵ζζϷϷиηϸйѺѺѺѺйͶϸϸ̵Ͷϸ̵Ȭv_ZalŦͰѴγͲззϵ˴˳ʲɱɱɱɱɱ͸͸ιιιιϺϺ͸͸̷˶̷͸ϺлϷϷζ͵̴˳˳˳ʲɱȰɱ˳̴˳ʲɳʴ˵̶ͷͷ̶̶̶̶˵ʴɳȲȲǱůǱɳ˵ͷͷͷͷ̶˵ɳʴ˵˵ʴɰŪ¥Ŀ}_vcCkV7jS4iT5o\\>pTuȯͶ͸ιιιι͸͸ʵʵȳǲǲƱǲǲʴʴʴʴʴʴʴɳɳɳȲǱǱǱǱȲͷ̶˵ɳɳɳʴʴȲɳʴ˵̶̶̶̶ǯɱ˳͵ζϷϷи˳˳˳ʲɱȰǯƮŰŰƱƱǲȳȳɴ̷˶˶˶ʵʵʵʵʴʴʴʴ˵˵ʴʴ̶̶˵ʴɳǱůĮɳɳȲȲɳʴ̶ͷɳʴʴʴɳǱĮíıƳȵʷʷʷ̺˹ɷǵƴƴƴƴñĲƴǵǵǵǵǴɱȮǭŭůůııð¯¯ůȰʰ˱ʰʲȰ¨tfbbl|¼ħȮɯĪȮ̴ʲĬªǮ̳Ѹзε̳ɳȲȲȲȱɯǰī©íů¬­ŰƲɴɶʷ̹ͺλͺ̹˸ʷǴð¯¯¯¯ıȵʷ̹˸ɶȵͺͺͺͺͺͺͺͺ̹̹̹ͺͺͺͺλλλλͺͺ̹̹˸˸˸ͺλλλλͺ˸˸˸̹ͺλнннϼλͺͺͺͺͺλλͺ̹̹̹̹ͺͺͺ̹̹̹ͺλϼλͺ̹ͺϼнϼλ˹˹ʸʸʸʸ˹˹ͻͻ̺̺̺ͻͻμоϽϽμͻͻ̺̺ͺ̹˸˸˸˸̹ͺλͺͺͺͺͺͺͺͺͺͻϿξͽ̼˻ʺɷɷƳȵʷ˸̶˵ɳȲŮǰí{r[n^GfV?cS<hX?r`HpVk·¹ƽæɮγϴγʱɰȲȲȲȲưŭ̾sz_xjOncGmbFshLz^yż¥ŦȫìǯȰȭȭ˯̰ɫ˭Ͱϰ̮˭ʭˮȭnk_E`T:_S9[M3ZL2XL2xnS»Ȯ˱ͲγʹεϷѹлϺ˸ʶʵ̶ͷϹккккθθθ˵ȲưưǱêȭɱǭŻ{ak]CgW>aQ7bT9hZ?ugLoƩ˱ɱʲϷϷ̴˳͵ʲ˳˳ʲɱɱʲ̴̴Ͷη̲ūùwporx}¹ǾħɮγѸҹθθϻϻϽϽϿѾҿӽӽӽҼҼѻѻӽҼкθ̶˵ʴʴʳɲêrvhMdT:`Q4dU8gX;`R8xlRy˴ǰ̴͵͵̴ʲɱʲ˳̴̴͵͵ζϷϷиηϸйѺѺѺѺйͶϸϸͶηйͶɭżvu|żȫ̱γʹʹϹкϸ̵͵̴˳˳˳˳̴͸͸͸ιιϺϺϺι͸̷˶̷͸ιϺϷϷζζ͵̴̴˳ʲɱȰɱ˳̴˳ʲʴʴ̶ͷθθθͷͷͷ̶˵ʴɳȲȲưȲʴ̶θθθͷ̶˵ɳɳʴʴɳȯŪħ}{]vcCkX8jU6hS4mZ<pStʰ̵̷͸ιι͸̷̷ʵʵɴȳǲǲǲȳʴʴʴʴʴʴʴ˵ʴʴɳȲǱǱǱȲ˵˵ʴɳɳɳɳʴȲɳʴ˵̶ͷͷͷʲʲ˳͵Ϸиии˳˳ʲɱȰȰȰȰƱƱƱǲǲȳȳȳ̷̷̷̷˶˶˶ʵʴʴʴʴɳɳʴʴ̶̶˵˵ɳǱưů˵ʴɳȲɳʴ̶θʴʴ˵ʴɳǱůíðŲǴɶʷʷ̺˹ʸȶǵƴƴƴųųƴȶɷʸʸɶ˳˲ʱɰǱƲƳǴıİİưʱ̳̳ʲŭª»yy{Ļ¦ƬǱǱ¬ƮɳɳưůɳͷкϹͷ˵ʴɳɳɳ˴˴ɴŮ¬¬ĮǱ«ĭǰɲ˵˸ͺλλλͺ̹˸Ǵð¯ðð¯ðƳʷͺλͺ˸ɶͺͺͺͺͺͺͺͺ̹̹̹ͺͺλλϼλλλͺͺͺͺ̹̹̹ͺͺλλͺͺ˸˸˸̹ͺλннѾнϼλͺͺͺͺϼϼλͺ̹̹̹ͺ̹̹̹̹̹ͺλϼλͺ̹ͺϼнϼλ̺˹˹ʸʸ˹˹̺μͻͻ̺̺̺ͻͻоϽϽμμͻͻͻͺͺ̹˸˸̹ͺͺλͺͺͺͺͺͺͺͺͺͺξξͽ̼˻ʸɷɷǴȵɶɶʴɳǱŮŬ¨ŹhqbKgW@iYBm]FwhQw`pɿīŪƩƩǪɮ˰˰ʯƭƭưǱɳʴ˵˵Ȱõ{fzoSncGj_AshJz]uƹãʬ©ĭǯǯȭɮ̰βɫ˭̯̯ˮʬʮ˯ʯ¸pk_E`T:^R8\\N4[M3ZN4}sXĽȮ˱ͲͲʹεζϷϺι˸˷̷θθϹкϹϹϹ̶̶̶ʴǱưǱȰŪʯ˱ƪy_k]BiY?aQ7cU:l^AxmOqƩ̲ɱʲζζ˳˳ζ̴̴˳˳˳˳̴͵˳̴͵͵˳ǭéŻ¹»žƿžžžŨȫƩǪȫɮ̱ϴҹԻϹϹϻϻϽϽξнҼӽӽӽӽҼѻкѻкϹͷ˵ʴʴʴʳʳīptfKcS9`Q4bS6fW:aS9znT{ʳŮ˳̴͵͵˳ʲ˳̴̴̴͵͵ζζϷϷηϸйѺѺѺѺйͶйϸͶηйͶɯ¹ƽȭʱ̶̳ͷϹϹйζζ͵͵̴͵͵ζ̷̷͸ιιϺллι͸̷˶˶̷ιϺζζϷϷζ͵̴˳˳ɱɱʲ̴͵̴ʲ˵̶ͷθθθθθθͷͷ̶˵ʴɳɳȲɳ˵ͷθθθͷ̶˵ɳɳʴʴȲƮǬƩyz]wdFmZ:mX9iV8n]AvYy¦˱ʳ˶̷̷̷̷˶ʵɴɴȳȳȳȳɴʵʴʴɳɳɳʴ˵̶˵˵ɳȲǱǱǱȲʴʴʴʴɳɳɳɳɳʴʴ˵ͷθϹϹ̴˳̴͵ииϷζ˳ʲɱȰǯǯȰȰƱƱǲǲȳȳɴɴ͸͸͸̷̷̷˶˶˵ʴʴɳȲɳɳɳ˵˵̶˵˵ɳȲǱͷ̶˵ʴʴʴ̶ͷʴ˵˵˵ʴȲůĮ¯ıƳȵʷ˸̺˹ʸɷȶǵƴųƴƴƴɷ̺ͻ̺˸ͷʹ̳ɳȴǳǴǴŲŲűȴ˵ʹ̳ʱøźȿ§ĭưŲŲíıưǱȲʴ˵ͷͷ̶̶˵ʴɳɳ˷̷ʵǲĮĮưȲëªªª«ŮȮȱ˵˸ͺλλλͺ̹̹ɶıððııðıǴʷͺϼλ̹˸λλͺͺͺͺ̹̹̹̹ͺͺλϼϼϼλλλλλͺͺͺͺͺͺͺͺͺͺͺ̹̹̹̹ͺλϼнѾѾнϼλλλϼннλͺ̹̹̹ͺ̹̹̹̹ͺλϼнϼͺͺλнѾнλͻ̺̺˹˹̺̺ͻϽϽμͻͻͻͻμμμμϽϽϽϽϽͺͺ̹̹̹̹ͺͺλͺ̹ͺͺͺͺͺͺͺͺͽ̼̺˹˹ʸʸʷ˸ʷ˵ʴɳǱưŮ´n|lSiY@hYBpaJp[lɴʳϵϳβ̰ɭȬȮȮéĪŮƯǲȳɴʴ˵ɰĬʾpy^vhKreEyjK}\\sĶ§ĭŭŭƫǬ˯βͱβͲ̱ɯʭʰ̰Ǭpk_E^R8]Q7]O5^P6`T:{`Ȯ˱Ͳγʹʹ͵͵͸͸˸̸ιϹкккϹθͷ˵̶˵ʴǱǱɳ˳ɮαϲƪy^m_DfX=_Q4fX;tfIwYv¹Ȩ̲ɱʲζζ˳˳ζϷ͵̴̴͵ζζζ̶̶˵ʴʴʲʲ˱ɯȬũ¦ɿǾƽƽ¦¦çĨĨĨɭɭɭ˯ͱβββѵϳβ̲̲ͳͶηллллннннѻҼӽӽӽѻкϹкϹͷ̶˵˵ʴ˵ʳʳīnrdIbR8`Q4_P3eV9bT:}qW~ʳĭʲ˳͵͵̴˳̴͵͵͵͵͵͵͵ζζηϸйѺѺѺѺйηѺйηηйͶȮçƿžæǫǫǫȮ˱ʳ˴ιллϺϺζζ͵͵͵͵ζϷ̷̷͸ιιϺллϺι̷˶˶̷ιι͵ζϷϷϷζ͵̴˳ʲɱʲ̴͵̴˳̶ͷθθϹθθͷͷͷͷ̶˵˵ʴʴʴ˵ͷθϹθͷͷͷ˵ɳɳɳɳǱƮȭȫty\\xeGo\\>n[=mZ<veIeūͳɲɴʵ˶˶ʵɴɴȳȳǲȳȳʵ˶̷ʴʴɳȲɳʴ̶ͷ̶˵ʴɳȲǱǱǱȲɳɳʴʴɳɳɳ̶˵˵˵̶ϹѻҼ͵˳˳̴ζϷ͵ʲʲɱǯƮƮƮǯȰƱƱǲȳɴʵ˶˶ιι͸͸͸̷̷̷̶˵ɳȲȲȲɳɳ˵˵̶̶̶̶˵ʴθθͷ˵˵ʴʴ˵ʴ˵˵˵ʴȲưĮ¯ıƳȵʷ˸˹˹˹ʸɷǵƴųƴųųȶ̺Ͻͻ͹ηͶ̵ʵȴǳƳƳŲıƲɵ̷Ͷ̵ʱÿøǼĨĪƭǱȵȶǷƶıï¯İƳȵǴƳȵɶʵ˶˶ʵɴɳɵʷɵǳűűǱɳȰǯƮŭƬǭȮʲ˵˸̹λλλ̹̹ͺʷƳııŲŲıŲǴɶ̹ͺͺ̹˸λλλͺͺ̹̹̹̹̹ͺͺλϼннλλλλλλλλλͺͺͺ̹ͺͺͺͺͺ̹̹̹ͺλλѾѾнϼϼϼннѾнϼλͺ̹̹̹̹˸˸̹ͺλϼнϼλͺλнѾнϼμμͻͻͻͻμμооϽμͻͻμμͻͻμϽϽооѿλͺͺ̹̹ͺͺλλͺ̹ͺͺͺͺͺͺͺͺ̺̼˹˹˹ʸʷʷλͺ̶ʴȲǱǱƯɻoqWo_FfX>m^GwkSlǿɶͺͷȮʮ˯˯ɭɭʰ̲ǭȮȱȱȳǲȳɴȳǰǱʱȯƺswZxiJsdCpObt§ìĬëèŪʮβддγ̱ɯɯ˱δèoj^D]Q7\\P6^P6aS9dX>eçɯ˱ϴϴʹʹ̴̴˶̷˸͹ϺкккϹθͷ̶̶̶̶ʴɳɳ˵ζ̱ѴѴȫ~z^oaFbT7^P3i[>ynP_|Ļɩ̲ʲʲ͵ζ˳˳ζиζ͵͵ζϷϷζ͹̸ʴȲǱɳʴ̴̴̲˱˱˱˯ʱʯ˯˯˯˯ʮʮʮʮ˯˯̰ϳӷӷѵϳ˯˱ʰʰ˱̲ͶηллллннннкѻҼӽҼѻϹθθθ̶˵˵˵˵˵ʳ˴īmqcHaQ7_P3]N1dU8bT:~rX˴ĭȰ˳͵͵̴̴͵ζ͵͵͵͵͵͵͵͵ηϸйѺѺѺѺйϸѺѺηηй̵ƯĪçū˱ϵϵͳ˴̵˴̷лѼлλιθ͵͵̴̴͵ζζ̷̷͸ιιϺллϺι͸˶˶̷͸ι͵ζϷиϷζ͵̴˳ʲɱʲ̴͵̴˳ͷθϹϹϹθθͷͷͷͷ̶̶̶˵˵˵̶θϹϹθͷ̶ͷ˵ɳɳɳɳǱůʱɮtx[wfJp]?p]?n]?|mPqžȮζȳȳɴʵʵɴȳȳǲǲǲȳɴʵ̷͸ʴɳɳȲɳʴ̶ͷ̶˵ʴɳȲǱǱǱȲȲɳʴʴʴɳɳͷ̶˵˵̶ϹҼԾ͵˳ɱ˳͵͵ʲǯɱȰǯŭŭƮǯȰƱƱǲɴʵ˶̷̷ιιι͸͸͸̷̷̶˵ɳȲǱǱȲɳʴ˵̶ͷͷͷͷ̶ϹϹθͷ̶ʴɳɳ˵˵˵˵ʴȲưĮ¯ðŲȵʷ˸˹˹˹ʸɷȶƴųųĲĲȶ̺Ͻμ̹͸͵˶ɴǳŲııŲŲƳɵ͸ι͵˳©½»ǾʾƬȯɳ˶̺˻ɻɹƶıðƳȵŲŲǲɴ˶̷ʳȴǲǴȴɵǳűűưȲ̴˳ɱȰǭȮɯʲʴʷ̹ͺλͺ̹˸λ˸ǴŲŲƳƳŲıƳȵʷ˸˸˸˸λλλͺͺ̹̹̹̹̹ͺλϼϼнѾλλλλλλλλλλͺ̹̹̹ͺͺλλͺ̹̹̹ͺͺѾннϼϼнѾѾѾнϼλͺ̹̹̹˸˸˸̹ͺλϼнϼλͺλнѾнϼϽϽμͻͻμϽϽѿѿоϽμμμϽ̺̺ͻμоѿλͺͺ̹̹ͺͺλλͺλ̹ͺλϼнϼλͺʸ˹ͻμλͺ˸ʷͷθͷ̶ζ͵ŭùq~mSm]CgW>i[AyjS}eƾððƴʸ˸ʰɬȫɬʰ̴̴̲˳ɱȲʴͷϹ̶ɳɳǱǲηӼ̳ĸrbrQ|mLrP\\rż¨ɯʰǮŬƭɰ϶϶϶϶ζζͶδ§faU;VJ0XL2^P6eW=j^DtĨδѷеҷз϶͵̴˶͸̹κϺкϹθͷͷͷͷϹθ̶˵ʴ˵̶̴γͯʭŨvvZqfJk]@gY<qfHz\\nƥͭʰ͵ϷиϷζζϷϷϷϷϷϷϷϷϷʶ˶ʵɴɵʴ̶ͷʴʲ̴͵ηѷѺӹϵжѷҸҸѷϵδδϵѷҸѷϵͳ̲˱ɱǯŭƮȰ˵ͷккϼннѾѾѾҼҼѻккϹθθͷ̶̶̶ͷ̶Ȳưʳ̵ê~dl^C`P6`Q4_P3ZK.cU;u[ùŮȱȰ͵ϷϷϷѹи˳͵͵͵͵͵͵͵͵ηηϸϸϸηͶͶѺѺһһѺη˴ɲǯʰ͵͵̴˳ʲ˵θϹλλλͺ̶̹ͷ̴ʲɱɱʲ̴͵ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ˳ʲɱȰɱ˳ζиϹϹϹϹϹϹϹϹͷͷͷͷͷͷͷͷθϹккϹθ̶˵ɳɳɳ˵̶ʴǱĮзʯ»nsVtcGp\\Am\\@xgK|b}ȫеӺ˵ʵʵʵɴȳǲƱŰƱǲȳʵ˶̷͸θͷ̶˵˵˵˵˵̶̶˵ʴɳɳɳɳȲȲȲɳɳʴʴʴ˵˵˵˵̶ͷθθ͵˳ʲʲ̴͵͵̴ȰȰǯĬªëƮȰ̷˶ʵʵʵʵ˶̷ʵ˶͸ιι͸˶ʵʴʴɳɳɳȲȲȲɳɳʴ˵ͷθϹϹͷͷ̶˵˵ʴɳɳ̶ͷθθͷʴǱů¯ðıƳǴǴ˹˹˹˹ʸɷȶǵųǵʸʸɷȶǵɶʵ˶ʳȱůĮįŰİŰưưɲʳ̷ζɰɮȮȮǭƪīêǮȲʶͺ̺ʺƸŴǷǴƳƳƳƳðŰǲɵɳȲǮůů˵̶̶ɳůĮưɳʱʱʱʱʱʱʱʱͷͺͺλλͺͺ̹λͺʷƳððŲȵŲǴʷ˸ʷɶɶʷϼϼλͺͺ̹˸˸˸˸̹ͺͺλϼϼϼϼϼϼϼϼϼϼϼλλͺͺλλϼλλλλλλλλнѾҿѾϼλϼнннϼϼλͺ̹̹ʷʷ˸˸ͺϼнѾнϼϼλλϼннϽϽϽϽϽϽϽϽоϽͻ̺̺ͻϽоϽϽϽооѿѿѿͺͺͺͺͺͺͺͺλλλͺͺϼϼнϼλͺ˹̺ͻͻͺͺ̹˸̶̶̶˵͵˳ľ~fziOn^Dl^DqeKyayûǴʷȶʸ̺̹ͳ̯ˮ̯ͳϵϷζɱɱɳʴ̶ͷ˵ʴ̹ɶȵͷϺ̵¶|h{ZwT}[k|¹ɯʰǮŬȯʹεε϶зϷζ̷̵ǽ}caU;XL2ZN4_Q7fX>l`FwĺǫͳδγѶзз͵͵̷͸̹κιϹθͷͷͷͷͷθͷ̶ʴʴʴ˵ʹ̰ʬȫ¥w|`|qUzlQxjMy[p̪ή˱ζѹѹиϷϷиϷϷϷϷϷϷϷϷ̶̷˶ʵɵ˷ͷθͷͷ͵͵ͶͶηη˴ͳϵжжжϵϵδϵѷѷѷϵͳ̲˳ʲȰƮǯɱ˵ͷккϼнннѾѾҼҼѻкϹϹθθͷ̶̶̶ͷ̶ɳưʳ˴|bk]B`P6`Q4_P3[L/eW=w]Ƽȱ̵˳Ϸиζζѹи̴͵͵͵͵͵͵͵͵ͶηηϸϸηηͶйѺһһйη˴ɲɱ˳ζζ͵̴̶ͷϹкϼϼϼλͺͷ͵̴ʲɱɱʲ̴͵ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ˳ʲɱɱɱ̴ζиϹϹϹϹϹϹϹϹͷͷͷͷͷͷͷͷͷθϹкϹθ̶˵ɳɳɳ˵̶˵ȲůʹƮjpVveIuaFraE~oRk»ʯεεʴɴʵʵʵɴȳǲƱƱǲȳʵ˶̷͸Ϲθͷ̶˵̶̶̶˵˵ʴɳɳɳʴʴȲȲȲɳɳʴʴʴ˵˵˵˵˵̶ͷͷʲȰȰɱ˳̴˳ɱƮǯƮŭëĬƮɱ˶˶̷̷̷̷˶˶ʵ˶͸ιι͸˶ʵʴʴʴɳɳɳȲȲɳɳʴ˵ͷθϹϹͷͷ̶˵˵ʴɳɳ̶ͷθθͷʴǱư¯ðŲƳǴȵɶɷɷɷɷȶǵǵƴǵȶʸʸȶǵǵɶ͸ζͶʴǱŮůưůůƯȲɳ˴̷ζ̳ͱͲ̲˱˱ɰɰǱȴ˸̹˹ɹȷǶƳŲıűŲŲðĭưȯŭ¨ǰʲ˵ɳưůưȲʱɰɰȯǱɰȲɳ̹ͺͺλλͺͺ̹ͺ̹˸ȵŲŲǴɶƳȵ˸̹˸ʷʷ˸ϼϼλͺͺ̹˸˸˸˸̹ͺͺλϼϼϼϼϼϼϼϼϼϼϼλλλλλλϼλλλλλλλλϼѾѾнλͺλннϼϼλͺ̹̹̹˸˸˸̹ͺϼнѾϼϼλλλϼϼнϽϽϽϽϽϽϽϽϽμͻͻͻͻμϽϽϽооооооͺͺͺͺͺͺͺͺλλϼλλϼϼϼϼλͺ̹̹ͺͺͺͺͷͷʴʴʲ˳̴Ʈhs[ygOvfMxiRw_zûǱϼϼ̺̺̻̹Ϸͳ̲̲δϵϷζȲʴ̶̶ʷʷʷ˸Ѿκ˷˵̶˴̲ɮ§tf`jyʰʰƭīʱѸ̵ηϹккϹ̹ʵ¸y_bV<ZN4[O5^P6eW=l`Fzǽɭ̲˱̱ѶѸзζζ̷͸̹͹͸θͷͷͷ̶̶̶ͷ̶˵ɳɳʴ˵ʹʮɭǬ~pkkl{ťѱϱ̲ϷҺҺѹииѹϷϷϷϷϷϷϷϷθ̶ʴɳɳ˵θкϹϹ͸̷˶˶ʶʴ˴̵ͶηηηηηηϸйййϸͶ̵̶ʴɳǱȲʴ̶θϼϼϼϼнннѾҼѻѻкϹθθθͷ̶̶ͷͷ̶ɳǱ˴ʳǽx^j\\A`P6aR5_P3]N1hZ@{aɿ˴ϸϷҺѹ͵͵иѹζζζζ͵͵͵͵͵ͶͶηϸϸηηͶйѺѺѺйη̵˴˵ͷϹϹθθθкккѻѻккϹθ̴˳ʲɱɱʲ˳̴ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ˳˳ʲɱʲ̴ζϷϹϹϹϹϹϹϹϹͷͷͷͷͷͷͷͷͷθϹϹϹθ̶˵ʴʴʴ˵̶˵ɳưȰëhqW}lP~mQpTb{ŨͲ̳ȯȲȳɴʵʵʵɴɴǲǲȳɴʵ˶̷̷ϹϹθͷ̶ͷͷͷʴʴɳɳɳʴ˵˵ȲȲɳɳɳɳʴʴʴ˵˵˵˵̶̶̶ʲʲʲ̴ζζ̴ʲƮǯǯƮŭŭǯɱ˶̷͸ιι͸̷˶˶̷͸ιι͸̷˶˵˵ʴʴʴɳɳɳɳɳʴ˵ͷθϹϹͷͷ̶˵˵ʴɳɳ̶ͷͷͷ̶ʴȲư¯ðŲǴɶʷ˸˸˹˹˹˹˹˹ʸʸɷʸʸȶƴųǵɶϺиϸ̳ǰŬŭƮìĬƭǰʱ˲̴͵ʹʹʹ͵̵̵̶̶ȴɵʷ˸ʷʷɶɶƳŲİűŲưîȽ˽ȺƸƸǽĭƯǯǯǯȰɳȲǱưǲȱɴɵ̹̹ͺͺͺͺ̹̹˸̹̹˸ɶȵɶʷȵʷͺͺ̹˸˸̹ϼϼλͺͺ̹˸˸˸˸̹ͺͺλϼϼϼϼϼϼϼϼϼϼλλλλλλλλλλλλλλλλλнѾнλͺͺϼϼϼλͺͺ̹˸˸˸˸˸̹ͺλнѾϼϼλͺͺλλϼμμμμμμμμμμͻͻͻͻμμоооооϽϽϽͺͺͺͺͺͺͺͺλϼнϼϼϼϼϼλλλ̹ͺͺͺͺͺθͷɳɳɱ˳̴ë}ybu\\t]v_}esý¬˵нϼ̺˺˺ʷζ̲ʰʰ̲ͳ͵̴ʴͷкϹ˸ʷ˸λҿѾϻ˷ȵʴϷӹδƫƽvxĺĪ̲ʰŬêʱҹ˴ͶϹѻнλ˸ɴw]cW=\\P6[O5\\N4bT:j^DyȾɭʰɯ˰ҷѸѸϷϷ͸͸˸̸˶ͷͷͷͷͷ̶̶ͷ̶ʴɳɳʴ˵̶̳̰˲ƫħͭԶϱ̲ζѹҺѹиииζζζζζζζζϹͷʴȲȲ˵θѻкι̷˶ʵɵʶʶηηηηηηηͶϸϸйййϸͶ͸̶˵ɶɳʴ˵ͷθλλϼϼϼнннѻѻккϹθͷͷͷ̶̶ͷθͷʴȲ˴ȱ¸tZhZ?`P6bS6^O2^O2k]CfͶѺҺԼҺ͵̴иѹϷϷζζζζ͵͵͵̵ͶηϸϸϸηηϸййййϸͶ̵˵ͷϹϹθθϹѻϹϹкккϹθͷ̴˳ʲɱɱʲ˳̴ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ̴˳˳ʲ˳̴͵ζθθθθθθθθθθͷͷͷͷ̶̶̶ͷθϹϹθ̶˵˵ʴʴ˵̶̶ʴȲǯëm{`z`cmyǽʰϳ˱ƭǱǲȳɴʵ˶˶˶ȳȳɴɴʵ˶˶˶ϹϹθͷͷθθϹɳɳɳɳʴ˵̶̶ɳɳɳɳɳɳɳɳʴʴʴ˵˵˵ʴʴɱɱʲ̴ζ͵ʲǯǯɱʲɱǯƮǯȰ˶̷ιллι̷˶˶̷͸ιι͸̷˶̶˵˵˵ʴʴʴʴɳɳʴ˵ͷθϹϹ̶̶̶˵˵ʴʴʴ̶ͷͷͷ̶ʴɳǱıŲǴʷ˸̹̹̹̺̺˹˹˹̺̺ͻ˹˹ʸȶųĲƴɵϸ϶ʹȮ©ʾ̾ͽ̼˽˿©ūȯʱ̴ʱʱʱ˲˳˴˵̶ɵʵʵ˵˵˵̵̵ʵɴǳǱǱƮ«Żĺ¶ƬȰȰȰ˵ʴȴǳǴȵʷ˸̸̹ͺͺͺͺ̹˸ɶ˸λλ̹˸˸̹˸ͺλλ̹̹ͺλλλλͺͺ̹̹̹̹̹̹ͺͺλλλλλλλλλλλλϼϼϼϼϼϼλλλλλλλλλλϼнϼͺ̹ͺλϼλλͺ̹˸˸˸˸˸˸̹ͺλϼнϼλͺͺ̹ͺͺͺͻͻͻͻͻͻͻͻμͻͻͻͻͻͻμоооϽϽϽϽμλλλλλλλλϼнѾѾннϼϼλλλλͺͺͺθθθϹɱʲ˳˳˱¨npvz}ǱĮ̶кϹ̹̺̺˷͵̱˰˰ʹ϶ͷ̶̶кҾҾκ͹κмнҿҿκɵȲͷҺϷδ̲ũȮͳʰīêɰзʳ̵κмϽͻɸȵu[dX>^R8ZN4YK1`R8g[AwƼǫɯɯ̱ӸѸѸииιι˸̸˶̶ͷθθθͷ̶̶˵ʴɳɳ˵̶ͷѺѷйʹª¸ǽʾǬ̱ʮͰӶϲʰ͵иѹϷζζϷζζζζζζζζζ̴ʲɱɱ˳ͶϸͶ˵ʶɵɵʷ˸κӾҽѼлϺιι͸лллллϺιι̸̹˸˷̸͹κϻϻϻϻмккѻѻѻѻкϹθθͷͷ̶̶̶ͷθθ˵ɳ˴Ůz}oUeW<`P6cT7^O2aR5qcIlê̵ϸӻԼѹ̴˳иѹииϷϷζζ͵͵͵̵Ͷηϸϸϸϸϸϸϸϸйϸϸηηʴ̶θθͷθѸӺε϶϶϶϶εʹ̴̳˳˳˳˳˳˳̴ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ̴̴̴̴̴̴͵͵θθθθθθθθθθθͷͷ̶̶̶˵̶ͷθθθ̶˵̶˵ʴ˵ͷͷ̶ʴʴƮùzqtzǻǫͲβ˰ȰưƱȳɴʵ˶˶˶ʵʵʵʵʵʵ˶˶ϹθθͷͷθϹϹɳɳɳɳʴ˵̶̶ɳɳɳɳɳɳɳɳɳɳʴ˵˵ʴɳȲƮƮǯȰɱȰĬȰʲ̴˳ɱǯǯǯ˶̷ιллι̷˶̷͸ιϺϺι͸̷̶̶̶̶˵˵˵ʴɳɳʴ˵ͷθϹϹ̶̶˵˵˵˵ʴʴ̶̶̶̶˵ʴɳɳıƳɶ˸̹̹˸˸ɷȶȶȶȶɷ˹̺˹˹ʸȶųĲƴɵͶ̳ǭø»ǮɰʲȱǱȲɳ˵˶̷ʵʵʵ˳̳̳βδйη˵ɳȲƮéywy|{¦ǭɱɱ̶̸˸ʷʹ˺̻̹̽˸̹ͺͺ̹˸˸ɶ˸λϼλ̹̹ͺͺλϼλ̹̹ͺϼλλͺͺͺͺ̹̹̹̹ͺͺͺͺλλλλλλλλλλλϼннннϼλλλλλλλλλλϼнϼͺ̹ͺλϼϼλͺͺ̹˸˸̹̹̹̹ͺλϼнϼλͺ̹̹˸̹̹ͻͻͻͻͻͻͻͻ̺ͻͻͻͻͻͻ̺ϽϽϽϽϽϽϽϽλλλλλλλλϼѾҿҿҿнϼλλλϼλλͺͺθθϹϹ˳͵͵̴ʰĪ½ȲǱͷкι̺νν͹͵Ͳ̱Ͳ϶ѸкϹϹкҾѽмϻϻϻͺѾн˷ȴʶθϹѸҺжǭ¼¼ǭʰ˱ɯŬŬɰε˴̵͹ϻμ̺ɸɶsYdX>`T:ZN4YK1`R8h\\BvŻǫ˱̲ͲӸҹҹѹѹϺι˸˷˶ͷθккϹθͷͷ̶˵ʴ˵̶ͷϹԽӻһѺ˵Ʈư̳Ϸʲ϶еɭ˯ҵδʲ̴ϷиϷζζζ͵͵͵͵͵͵͵͵͵͵̴˳̴͵ηϸ̶˵ʶɵɶ̹λнԿҽлϺϺϺϺѼѼллϺϺϺϼ̺ͺͺͺ͹κϻмκϻϻϻкккккккϹθͷͷ̶̶̶̶ͷϹϹ̶ʴ̵ìtxjPcU:`P6dU8aR5fW:ykQuŬ˴̵ѹӻи̴˳иѹииииϷζζ͵͵˴̵Ͷηϸϸϸϸηϸϸϸϸϸйѹ˵̶ͷͷͷθҹԻʹεεεεʹ̳˲͵͵͵͵͵͵͵͵ιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ̴̴͵͵͵͵͵͵ͷͷͷͷͷͷͷͷϹϹθͷͷ̶˵˵ʴ˵ͷθθθ̶̶ͷ˵ʴ˵ͷθͷ̶θɳɾʺͿū˯Ͳ̲˳ʲǱǲȳɴʵ˶˶˶˶˶˶˶ʵʵʵʵͷͷͷ̶ͷθϹϹʴʴɳɳɳʴ˵˵ʴʴɳɳɳɳȲȲȲɳʴ˵ʴɳǱưȰǯƮƮƮŭľëƮɱ˳ʲȰǯǯ˶̷͸ιι͸̷˶̷͸ιϺϺι͸̷ͷͷͷ̶̶̶˵˵ɳɳʴ˵ͷθϹϹ˵˵˵˵˵˵˵˵̶̶̶˵˵ʴʴʴŲǴɶ˸˸ʷȵǴȶȶǵǵȶʸ̺ͻɷʸʸȶƴųǵȵʴɮ{wwy|èȯ̴˳ɲȲɳ˵̷ιɴʳ̴̲γΰϰίҹй̶̳ʲǭĨ·tidfikrĽũȮȰ̶̸̹ͼ;˿̹̿̽˸̹̹̹̹˸˸ɶ̹λϼλ̹̹ͺλϼϼλ̹˸ͺϼͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺλϼнѾѾнϼλλλλλλλλλλнѾнλͺͺϼннϼϼλͺ̹̹ͺ̹̹̹̹ͺλϼλλͺ˸˸ʷ˸˸̺̺̺̺̺̺̺̺̺̺ͻͻͻͻ̺̺ͻͻμμϽϽϽоϼϼϼϼϼϼϼϼнҿҿҿѾϼλλϼϼϼλͺͺθθϷи͵ижͳʰǭǸʽɾŽſíȱʳθϹ̷˷ͺλ˸˳ʱʱ˲εѸѻккϹκϻмϻͺ̹˸ϼҿѾͺ˶̷ιлϸϹѸ̳ŬêƭɯɭȮƬǮȯ̵ϸ̷͸ͺͺ̺̺ʻʷ|pVdX>aU;\\P6[M3dV<nbHzƼȬδϵγѶҹҹҺҺлιʷʶ˶ͷкѻҼѻϹθθͷ̶˵̶ͷϹкѼιιѺϹ̶˷θϹ̳ззɯ˱ѷϵ˳͵иѹиϷϷϷ͵͵͵͵͵͵͵͵δϵϵжжѷззθͷ˵ʴ˵ͷϼѾонϼϼϼнѾҿѾѾннϼϼϼϼͻλλλϼϼммκκϻϻϹкккккϹϹθͷ̶̶̶̶̶θϹϹͷʴ̵«pugMbT9`P6dU8eV9l]@tZ~ĸɰ˴ʳζиϷ˳̴иѹϷѹѹиϷζζ͵͵˴̵ͶηϸййϸηηηηϸййҺ̶θ϶϶϶зԻֽγγϴϴγγͲ̱ζζζϷϷζζζιιιϺϺлллϺι̷˶˶̷ιϺиѹѹѹѹиϷζ͵͵͵͵͵͵͵̴ͷͷͷͷͷͷͷͷϹϹθͷͷ̶˵˵ɳʴ̶θθͷ̶̶ͷ̶ʴ˵ͷϹθͷѻ̶íǽǹƸȷɸŪʯͰͱ˱̴͵Ȳǲȳɴʵʵʵʵ̷̷̷˶˶ʵʵɴ̶̶̶˵̶ͷθϹ˵˵ʴɳɳɳʴʴʴʴʴɳɳȲȲȲǱȲʴ˵ʴȲưůƮĬſľýľëǯȰȰȰɱ˶˶̷̷̷̷˶˶̷͸ϺллϺ͸̷θθͷͷͷ̶̶̶ɳɳʴ˵ͷθϹϹ˵˵˵˵˵˵˵˵̶̶˵˵ʴʴʴ˵ŲǴɶʷʷȵŲðñ°°°ñųȶʸǵȶʸʸȶǵǵȵʱƫüqgc~_ahsľǮ͵̴ʵȴȵɶ̷͸ǰɲ̲ϲϲбϯήϳʹ˲˲ʰɬũæȽxi___biw¦ƬƮʴ˸ͼο˿ɽ˸˸˸̹̹˸˸ʷ˸ͺλλ̹˸˸̹ϼϼϼͺ˸˸ͺϼͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺλϼѾҿҿѾϼλλλλλλλλλϼѾѾнλͺλнѾѾѾнϼλλͺͺͺ̹̹̹ͺλϼλͺ̹˸ʷʷʷʷ˹˹˹˹˹˹˹˹˹̺ͻͻͻͻ̺˹˹̺̺μϽоѿѿϼϼϼϼϼϼϼϼнҿѾϼλλϼϼнϼͺ̹ͷθкѹθҺҺ͵ʲɱǯ«ıʶʵȲǱǱǰɳͷͷɴȴʷ˸ȵǯƭƭȯ̳϶Ϲθкͷ˷̸ϻϻ̹ȵ˸κѾҽλ͸ιϺϺ˶ʳ̵̵ɲɲʹʲǭŭƭȯ˵ϸйͶ̸̸̸˸˸ʹ˶||nSeW<dV;`R8^P6hZ@siPƿʰжѷε϶ҹҹҺҺлι˷ʶ̶θкҼӽҼкϹθθͷ̶ͷθкѻιʵʵ͹Ϲθ̷͸˵ɲθѷȱ˱Һи̴ϷҺҺѹѸиҹ͵ε͵͵͵ͳͳͳжѷҸԺԺԺҸҸѻϹ̶˵˵ͷϼҾͺͺ̹ͺλнҿѾнкϼкϼнκκϻϻϻммкκθκϹϹкккккϹθθͷ̶̶̶̶̶θкϹͷʳ̳jtdJbS6`Q2eV7hY:qbEz_Ⱦ̴̲ʲ˳ζζ˳̴иѹϷҺѹииϷζ͵͵˴̵ͶηϸйййηηηηϸѷѺһζϹѸѸзҹռؿϴееееϴγͲδϷииииϷζιιιϺϺлллϺι̷̶˶͵ιииҷҹҹҹѸϷζ͵͵ζζζ͵̴̴ͷͷͷͷͷͷͷͷϹϹθ͵ͷ̴˵˳ɱʲ̶ͷθ͹͹̸κ̸˷˷ͷϹϹθӽ͵ƯīīĪéū˯̲ͱ˱ͲζȲɳɶ˵ʷ˵ʴʴθθͷ̶˶ʵɴɴ˳˳˳ʳʳ˴̵͸˶˶˵ʴɳɱɳɳʴʴʴɳɳȲȲȲǱȰʴ˳ʲȰƮĬĽžĪǭȰɱʲ̷˶ʵʵʵʵ˶̷̷͸ϺллϺ͸̷θθθͷ͵͵̴˴ȱȱɲʵ̷͸ͻιʳʳ˳˳˳˵˵˵̶̶˵ʴʴʴʷʷųǴȶɶɶǱíºŽǿŲǴʸʸɷȸǷȶɳĪyh{\\xWrQsTyYfxüǬ˲˳ȳǲǳǴʷ̶Ʊɱ͵ϵѶвΰ̰˲ȲȲɰɯʭȫŨƩʿrd\\Z_fsĪŬȴʷ̻οο˿ɽȹʸ˸˸̹̹˸˸ʷ̹ͺλͺ˸ʷ˸̹ϼϼλ̹ʷʷ̹λͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺͺλϼѾҿҿѾϼλλλλλλλλλнѾҿѾϼλϼнҿҿѾѾнϼλλͺͺ̹̹̹ͺλλλͺ̹˸ʷɶɶɶ˹˹˹˹˹˹˹˹ʸ˹ͻμμͻ˹ʸʸ˹̺ͻϽоѿϼϼϼϼϼϼϼϼнѾҿλͺ̹˸̹ͺϼнϼϼϼϼϼϼϼкϼкϹθͷͷ̶˵ȵɶ˸̹ͺ̹˸̸ͺͺͺ̹̹˸˸ʵɱɱɱɱɱʲ˳̴ͷͷͷθͺλλϻмѺѼйлйϸϸηηηηη̵˴˴ʴʴʴʴʴʴʴʴͷкϹ̶Ͷй̵êm|mNn_@gX;`R7aS8f[?~gľɱ̴ѹҼθͷϹкҼҼѻϺϹͺ̸ʶʶ̸κϹϹ˵̶϶зз϶ʹ̳ϹϹϹϹϹϹϹϹϺкϺϷθ͵˵ʴϹϹϹϹϹйϹйкз϶ͲͲ̯ͰͰ̲͵ϷѹҺҺҺѹйййййййлҿѿѾѾҿҿѻϹԾѻθзҼԻҼзֽԻѻϹϹϹкиθζϹϷηиϸϸϺϺϺϺϺϺϺϺϺӾԿлϺлл̶ʯɸ|xXs`@iV5iV5hX6gX7wjHlʭͰ˯ʯɱ˴ηϸηͶηηϸηηͶͶηηϸ̲δжҸӹҸжϵȮδжͳͳѵжʰ͵иӻҺζ͵иҺиζζζϷϷ͵ʰжѷҸӹԻҹкϹ͹κϻмлϺθ̶Һѹиз͵Ͳ˳˰ͱϱϳͱϳҶϴʯǬ˰ɱëªɱζ͵Ϲһӽվӽкʹ˲εε͵ͳ͵ͳ͵ͳ̲ͳ͵θϺκμͻ̼̺ͻϻѼϻ̶ɳ˲˰Ȯū¨¨ūȬ¨ǭͳѶγ˯ȬǮƱȳȵʵȵɴʶ̸͹Ҿӽͷɳʴ̶̴βˮǫƫʱεζθůưƯĬƭʱɳȳȳǲǰƯƯŮƯȮȱ˱˱ȮéƿurqomnxĹƬȰɱ̴̴˳˳˳˳̴̴ɱʲ̴͵ζ͵̴˵ͷǱ̶ѹ˱˱ͱƫŪéŭǲƳо²ŭɮɯƬǭ̳εʹηͶ˷ƳðŲȸνɻȹǷʷʴĩxtx~ƺȼ®ƳĳŵȻ˾ʺɶǯƾn}_wWvVuUwV_tʭȯ̷͸͸лҾѽ͹Ǵɶ̹ϼнϹͷ˷ɷ̺λϷͲʭȫǭǯǰ¬}eW}R]dsĻƩǮŭȳɵ˷˸̹˷ɶɳɶʷʷ˸̹ͺλλͺλͺ˸ɶɶ˸λннϼλλϼϼϼнϼϼλλϼϼнҿϼ̹ɶɶ˸λѾ̹ͺλϼϼϼϼλннннннннλλλλλλλλооϽϽϽϽϽμμϽϽϽϽϽооͻͻͻμμϽϽϽͻͻͻ̺̺˹˹˹̺̺̺̺̺̺̺̺ȶɷʸʸ˹˹ʸʸɷʸͻϽоѿооϼλλͺͺλλϼλѾѾͺͺ̹˸˸ͺλнϼϼϼϼϼϼϼϼϼϼλλͺ̹˸˸ɶʷ˸ͺͺͺ̹˸λͺͺͺ̹̹˸̶ʴʲɱɱʲ˳̴̴ͷͷͷθͺͺλϻййййϸϸηηηηηηηͶ̵˴˶˶˶˶ʶʶʴʴ˳ϷѹϷжжɯɿfxhGhY:cT7bT7i^BvkOs¬˵ͷѻѻθϹϹкѻѻѻѻѻҾϻ͹̸κѽҼҼ̶ͷε϶϶εεʹϹϹϹϹϹϹϹϹϹкккϹθͷ̶ϹϹϹϹѺѺѺѺй϶ϳβ̯̯ͯͰͳζϷиѹѹѹѹѹѹѹѹѹѹѹѻλͻͺϼҿҼѻտҼззӺռԻӺҷҷз϶͵͵͵͵͵͵ͶͶηϸϸϸϺϺϺϺϺϺϺϺ͸ѼҽϺιллʹǫɶxxWvbAlX5jX4jZ6wgEyVx̮ϲϳдζϸййηͶͶηηηͶͶͶͶηη˱ͳδϵжжϵδ˱жҸждӷҶͱ͵иӻҺϷζиӻѹϷζϷииζ̴ϵгжжѸѸкк͹͹͹͹ιιθζζ͵εʹͲͲͲαвҳѲϰдӷҶͲ˰γ˱ǯȰζи͵˵ͶϸйѺйεʹεεͳͳͳͳͳͳ˰̵̲ͷικμϾͽͽͻϻѼкθ˳γγͲʯǬŪŪƫȭ̱ϴϴ̱ɮȭȯŮǲɴʵ˶̷Ϻҽ̸мϹ˵ɳ̶θ͵̯ʪƩƩǫȮǭŮêíĪèɭ̱ʲɴȳȳǰǰǰƯȮȮȮɯɭǫçȿyib_[Y[jsǼçƯȰ̴˳ʲɱɱʲ˳̴ɱʲ̴͵ζ͵̴˳̹Ǳ̶жʰɭʭæź²ùǪɯγε˱ζη̸ʶǴǴȸ˻Ȼɻʺ͹̳kd]ajtʾĮǳƵǷɼʿɼȵưɾudvXsRsRvU`tʮǯʵ˶ɴ˶Ϻλ˸Ƴȵʸ̺μμͻ̺ɽʻ˸̴Ͳ̯ʯɰǱȵ®gYS[anŨǮƮʵ˶̸͸̸̴ʳɲ˵˸˸̹ͺλϼϼλλλ̹ʷʷ̹λѾнϼλͺͺλλϼϼϼϼϼϼϼϼϼλ˸ʷʷ̹λн̹ͺλϼϼϼϼλϼϼϼϼϼϼϼϼλλλλλλλλμϽϽϽϽϽϽϽϽϽϽϽϽϽϽμͻͻμμμϽϽϽͻͻͻ̺̺̺˹˹̺̺̺̺̺̺̺̺ɷʸʸ˹̺̺˹˹ɷ˹ͻϽѿѿѿоϼλͺͺͺͺλϼϼнѾͺ̹˸˸˸ͺλϼϼϼϼϼϼϼϼϼϼϼλλͺ̹̹̹˸˸̹ͺλͺͺ̹λλλͺͺͺ̹ͷ˵˲˲˲˲̳ʹʹͷͷͷͷθθθϹϸϸϸηηηͶͶͶηηηηͶ̵̵̷̷̷̷˷˷˵˵ʲϷҺҺжʰƿz_teFgX9eV9l^A}rVhȲθθккͷккϹϹкѻҼҼѽͷ̶θѻҼӽθͷεʹʹεε϶ϹϹϹϹϹϹϹϹϹϹккккϹθϹϹϹккѻѻҼ϶϶γͲͰͰͰαжиϷϷϷииѹииииииикʷʷ˸ͺѾӽҼӽз϶еѶҷѶжжжжϵδ͵̴ʳ˴̵̵ͶηϺϺϺϺϺϺϺϺϺϺ̷ϺлιιϺιʱ¯swVwdCo\\;p^:rb>xVg̮ͰβеҺһһйͶ̵ͶϸͶͶ̵̵̵̵ͶͶ˱̲̲̲ͳͳͳͳ̰дѵддҶѵβ̴иӻӻиϷѹԼҺиϷϷѹѹϷζδδ͵͵εзкѻ̶˵ʴʴ˴̵̵δ˱ʰɯɯ˰̱αϲѳҳбͮͰѴѴ̯αα̰ʰͳѷϵʰʱʱ˲̳ʹε϶϶ʹεͳδδͳͳ̲˲̲˴̶ιϻмоͻ̸˸͹Ϸϵͳ˱гггͰɬƩƩƩɬɬɬǪħææĪêůȲɳ˵̶ϹҼͷθ̶ɳʴϹк͵ǪƤ£ʿɾɻǹĸǽ©ƩŨƩ˭γ˳ʵɴɴɲȱȱȱɯǭƬƬǫƪçvb}VvOpI~oHrKzXbvĭƮ˳ʲȰƮƮȰʲ˳ɱʲ̴͵͵͵̴˳̹ȲͷϵɯǫƩĻzql~hpuwɯγ˲ƭʱ˲˵ʴȳǲƵɷǵɷ˸̴Ǫq^}UwQxT^mưʶɸɹɼʾȺǴưǽlz\\pOoNsR^qʽɭƮɳȲůűʶ̸ʶİƲǵɷ˹ͻͻμ˿ɺǴɱͲαͲʱǱȵïj[SX]i}æȯɱ̷͸͹ι͹͵˴˴ͷ̹ͺλλϼϼнϼϼϼͺ˸˸ͺϼѾнϼͺ̹̹̹̹ͺλϼннϼλͺ̹̹˸˸̹ͺλϼͺͺλϼϼϼϼϼϼϼϼϼϼϼϼϼλλλλλλλλͻͻμμϽооооооϽμμͻͻͻμμμϽϽϽϽͻͻͻͻ̺̺̺˹̺̺̺̺̺̺̺̺ʸ˹̺ͻͻͻͻͻ˹̺μоѿѿѿоλλͺ̹̹ͺλλϼннͺ̹˸ʷ˸̹λϼλλλλλλλλϼϼϼλλͺͺ̹ͺͺͺͺλͺͺͺλλλͺͺͺͺͺ̶ʹ̳̳̳̳ʹε̶̶ͷͷͷθθθηηηͶͶ̵̵̵ͶηηϸϸηͶͶ͸͸͸͸̸̸̶̶ʲζҺѹʰĽo}^}nOuhHwiLvXoýͷѻккϹ̶ϹϹͷͷͷϹкҼӽϹ˵ʴ˵θкѻϹθʹ̳̳ʹ϶зϹϹϹϹϹϹϹϹϹϹкѻѻѻккθϹϹкѻѻҼӺзϴϴγϲϲгѴѹиϷζ͵ζϷиϷϷϷϷϷϷϷϷ˸ʷ˸λѾӽҼտӺ϶ʹ̱̱Ͳγͳδϵжϵδ͵˳ʳʳ˴̵ͶηϺлϺϺϺϺϺϺϺϺ͸лл͸͸͸ʵíǷiqQwdDta@zgFpLdwŦ˭ʭʯ̱ѹѺйη̵̵ηйͶ̵̵˴˴̵̵Ͷͳ̲̲˱˱̲ͳͳͱͱ˯ʮɭ˯̰̰ʰζҺӻѹиҺԼӻѹииѹҺѹиϵδ̴˳ʹзҼԾ˵̳˵̵̳ͳ̲˱̲˱ɯȮɮʯˮ̯ίίˬǨȩ˭ʭƨʭǪũǫͱѵ̱Ȯ̲̳̳̳̳ʹʹε̳ʹͳδδδͳ̲̲̲˳˳̶ϺлѼι̷ʴʲʱ˰ʮʭͱͰˮȫæææĿ»ƿĪǭɯ˱ͳϷζθʴȲ˵кϹʰãſĹ¥ƪȫɬ̮γ˳ʵʵʵʳʳʳʳʰǭūĪĨĨçydyR}nGvg@uf?yjC~nLzWlĪŭʲȰƮĬĬƮȰʲɱʲ˳͵͵̴˳˳̹ȵθϷǭƩpz]|mPveKsbHweM|lSu^s»Ƭ̱ɰīǮǮȯǯƯůǱȲưƯŬpb{UyRvR{YfzĹǱ̷ʷȸɹȺŷƳǱůƭ̾xerQ~nMoNyXh|¤ƬɳȲĮĮȴ̸˷ǳȴǵɷʸ̺ͻͻȹıƮ̱гϴ̳ǱƳ®¶l[~R}UYdx¥ɰ̴ιι͹ι͹ζͶͶϹλλϼϼнннннϼλ̹̹λнѾнϼͺ˸ʷʷʷ̹ͺϼѾѾϼͺ̹ɶʷ˸̹ͺλλλͺλϼϼннϼϼλλλλλλλλλλλλλλλλ̺̺ͻμϽооѿѿооϽμͻ̺̺μμμϽϽϽооμμͻͻͻ̺̺̺ͻͻͻͻͻͻͻͻ̺̺ͻμϽϽμμ˹ͻϽѿѿѿѿоͺͺ̹̹̹̹ͺͺϼϼн̹̹˸ʷʷ̹ͺλλλλλλλλλϼϼϼλλλλͺλλͺͺͺͺͺͺͺͺͺͺͺͺͺͺθηͶͶͶͶͶηͶͶͶηηηϸϸͷͷ̶̶˵˵˵˵̶ͷͷθθθͷͷ͸͸͸͸̸̸̶̶˳͵Ϸ̴¨}lhfhoyýǱкҼѻϹθ̶θͷ̶˵˵ͷϹкҼϷ˳ʲ̴ζϷϷϷζ̴˳˳̴ζϷϹϹϹϹϹϹϹϹϹϹкѻѻѻккϹϹϹкиѹѹѷϵϵϵгѴҵӶӶѹиζ͵͵ζϷиϷϷϷϷϷϷϷϷϼλλϼҼӽѻкиϷζ̲˱̲δжʮ˯ͱβϳϳδͳ˴˴̵ͶιιϺϺϺϺϺϺϺϺϺϺлҽл͸̷̷ƱȽw{]|lKxeEzgFrQ]vɾˬ̯̯˰˰ζͶͶ̵˴̵ϸѺͶ̵̵˴˴̵̵ͶϷ϶ͳͳͳͳββͱȬ¥ǾƽȿæȬȮ̴ѹӻѹиѹԼӻѹϷϷѹҺҺҺиϷ̶˵̶ϹҿεϴѸѶзͲʮȬβ̰ˮɬǪǪǪǪȩɨť¢ƿ»ǾȫͰͱ̯ϵϵδδͳ˱ʰʰʰ˱ͳϵϵϵͳ̴̴̲̲̲͵ͷθϹϷ̴ȯƫŪƩŦæƩħƿǼƫʯδϵϷ̴ɱ˵Ϲ̶Ƭſ||ȿǪʬˬ̭̯˳ʵʵʵʳ˴˴˴ʰȮūéĨĨç¥~i|W|mFsd=rc<uf?yiGuRi¦ūūɱǯƮĬĬƮǯɱȰɱ˳̴͵̴˳ʲ̹ɶϹζǭƩǾn]}nMteDo_>m]<p_AteH~oXqŭ̳̱ȭȭǬūūƬǮǯȮƬ¦Ĺ~l]xRuQzW]gwȺ¨ªǱ˶ȵƶǷƸóƳȲȲ˲ƬĶowVoN{kJqP|[k¨ǯɱƮƮʴθθʷʷʷʷʸ˹˹˹ȹıŭ̱геʹưŲ¶lYzNzR|V`tʱ͵ϺϺκι͹ζͶηкϼϼϼϼнннннϼλ̹̹λнѾнϼͺ˸ʷʷʷ˸ͺϼннϼͺ˸ȵɶ˸̹λλλͺͺλϼннннϼλλλλλλλλλλλλλλλλ˹̺̺ͻμϽооооϽμͻ̺̺˹μμϽϽϽоооμμμͻͻͻ̺̺ͻͻͻͻͻͻͻͻͻͻμϽоϽϽϽ̺ͻϽоѿѿоϽ̹̹˸˸˸˸̹̹ϼϼϼ̹˸ʷʷʷ˸ͺλͺͺͺͺͺͺͺͺϼϼϼϼϼλλλλλͺ̹˸̹̹ͺ˸˸˸̹̹̹ͺκйϸηηͶͶηη̵ͶͶͶηηηηͷͷͷ̶̶˵˵˵̶ͷͷθϹθθθιιιι͹͹ͷͷ̴̴̴ʲƿ|}ŻʴͷѻҼкθͷͷ̶̶̶̶̶ͷθθҺи͵͵ζϷϷζζ͵͵̴̴͵͵ζϹϹϹϹϹϹϹϹϹϹккккϹθϹϹϹϹϷϵϵϵδββгѴҵԷԺϷζζζζζϷϷζζζζζζζζҼнϼнҼҼϹͷ̴͵δδͳδжӶʮˮͱϳѵҶӹӹͶͶηηιϺϺϺϺϺϺϺϺϺϺϺѼҽл͸͸̷Űƻrz]pRpRuUboĵãɩˮͰгδʳ̵Ͷ̵̵̵ϸѺͶͶ̵̵̵̵ͶζϷзϵϵϵδββʮƿȿūʲϷѹиϷѹӻӻѹζζиҺӻҺѹиͷ̶ͷϹѾҵҵѴг̱ȫĨ¦ȬȬȫȫǪƩŨƧťƦĤĿýý·ʿŧˬɭ˱δϵϵ̲ɯǭɯʰͳϵжϵδ̲̲ͳζζζ͵̲̲εʯèͿ̼̹̽ȹĹ}wqmryøçʯ˰ϵͶ̴̶ͷʴĪſvkhmr{øťɩʬʫʭʲɴʵʵʳ˴˴˴˱ȮƬūũũç¥ĺq\\oKrc<o`9qa=vfBrOe·ŨǫūǯǯƮƮƮƮǯǯȰɱʲ̴̴̴˳ʲ˸ʷкϷȮǪżg~ZqN{mH|lH{kG}mIpO{azǼǰ͵δ˱˱ʭɬǪȫȫũçͿŶtc|YuQtOyXalyøŬíȳʷƳĴŵƸĴƳȲȲɰ¨s{ZqPzjI|lKrQ}\\rǯǯȰ˳θθ˸˸̹̹˹ʸɷɷ˿ȹƳǯ˰αϴεǱƳ÷lWwKwOyS^sʱ͵ϺϺ͹͸̸͵Ͷηкϼϼϼϼϼϼϼϼϼϼͺ˸˸ͺϼѾнϼͺ̹̹̹̹̹ͺλϼϼλͺ̹ɶʷ˸̹ͺͺͺ̹λλϼнѾѾннϼϼϼϼϼϼϼϼλλλλλλλλ̺̺̺ͻμμϽϽϽϽμμͻ̺̺̺ϽϽϽϽоооѿϽμμμͻͻͻͻμμμμμμμμͻͻμϽооϽϽ˹̺μϽоϽμͻ̹˸ʷʷʷʷ˸̹ϼϼϼ̹˸ʷɶʷ˸ͺλͺͺͺͺͺͺͺͺϼϼϼϼϼϼϼϼλͺ̹ʷʷʷ˸̹ɶʷʷʷ˸˸̹͹ѼлϺιϷϷϷϷͳͳδδδϵϵεθͷͷͷ̶̶̶̶̶ͷθθϹϹϹθϺϺϺϺκκθθ͵˳˳ʲéźɾéȭʱ˱ѻкккϹͷͷͷͷͷθϹϹϹϹϹиδͳδϵϵ͵˳̴͵͵ζθͷͷ̶ϹϹϹϹϹϹϹϹϹкккϹθͷ̶ϼλι͸̵̳˲˰˰̯̯ͰϳдҸӹ̴̴͵ζϷϷϷϷ͵͵͵͵͵͵͵͵ѻкϹкѻкζ̴Ͷϸѷϵʮǫƪǫ£ħƩɬ̯γеѷѷййϺϺккϺϺϺϺϺϺϺϺллϺ͸ϺϺǲǼzjgklwŶȻźǾǪͱͳ˴ͶϸϸηͶηϸηηͶͶͶͶηϷζзѸѸжϵͱ̰tqs¨ǯζиϷζиҺӻи͵͵ϷҺӻӻкϹͷ̶˶͸Ϻлΰ˭ƨƽ¹»ĽæǩǩǩǩȨʪȨãǾżxuy~úƿǫβдβʮƪȮʰͳжѸѸ϶ʹ̴͵ϵжϵͳɮǫŪͿǶuh}]tStSvU|[izźĪ˰жϷͷ̶ɳūrcZ^akxǥɩɨɪɱȳɴɴʳʳʳ˴˱ɯǭƬǫƪĨ¥ʿ{euQtd@m]9m]9rb>|nKaøƩɭƬŭƮǯȰȰǯƮŭǯɱʲ̴̴˳ʲʲ˸˸ѻϷɯȫżfYvOwP{R}TT]míȲ̵̲ʮ˯ʭʭʫɪäź}n_xTvR{W[kvƫêůʵʷŲóƶȸȵƳȲů©ŷ|p{ZqP{kJ}mL~oNtSezéƬǭʰ˴ʳȲɳʷ̹͹̸ʷǵɽɺɶɱ˰̯ͲεɳȵïŹnWuIvNxR]rĿɰ͵Ϻι̸̷˷̴Ͷηкϼϼλλλλλλλλ̹ʷʷ̹λѾнϼλͺͺλλͺͺͺͺͺͺͺͺ˸˸˸˸˸˸̹̹λϼннѾѾннϼϼϼϼϼϼϼϼλλλλλλλλͻͻͻͻͻͻͻμμͻͻͻͻͻͻͻϽϽϽоооѿѿϽϽμμμͻͻͻμμμμμμμμ̺ͻμϽϽϽϽϽʸ˹ͻμμμͻ̺˸˸ʷɶɶʷ˸˸ϼλϼ̹˸ʷɶʷ˸ͺλͺͺͺͺͺͺͺͺϼϼϼϼϼϼϼϼλͺ˸ʷɶɶʷ˸ȵɶɶʷʷ˸˸̸ѼѼлϺϷϷϷϷͳͳͳδδϵϵεθθθͷͷͷ̶̶̶̶θϹϹϹϹϹϺϺϺϺκκθθ͵ʲʲ̴ȮéʰȭʭȮʯγѶҸϵԾѻϹϹθͷͷθͷϹкҼҼѻкϷ̲̯˱̲ͳ̲ɱƮ˳̴ζϷϹθ̶˵ϹϹϹϹϹϹϹϹкккϹθͷ˵ʴϼλι̵˲ɯȮɭȭɭɭˮͱϳѷҸʲ˳͵ϷиииϷ͵͵͵͵͵͵͵͵θͷͷθкиζ̴ѺԺӹδĨüżɿ§ӹӹѺѺлϺϹϹϺϺϺϺϺϺϺϺ͸ιι͸лѼʵ}~²żŪȬηйһһйͶͶͶϸηηͶͶηηиε϶Ѹҹжδ̰ʮn_{[`qƮ̴ϷϷζϷѹҺϷ͵̴ϷѹҺӻϹθͷ̶ʵ˶̷͸ɩãźƨɫʬʬˮήͭȨäȿ|sljghqɿ˯дϳ˯ǫǭʰͳжҹѸ϶ʹ̴ζжҸѷ̱ȬħʻŴ{wssz~m~^yfEvb?q]<q^=|iI~]wɮзѷζͷʴǭâļq_{UxSyR^mûţɦȨȪǰȳȳɴɲʳʳʳ˱ɯȮȮȬǫĨ¥ƦŸnzVvfBl\\8l\\8m]9xjE^{·ȨɬǪūƮȰʲʲȰƮŭǯȰʲ˳̴˳ʲɱ˵˸ѻиʰɬż~fZzP|PVY\\drĹůȲɰƬħǫȩɫ˪Ǧƽpg[uQsOzVbkɿȯɰĭȳ̶ʷŲıǷʺ˸ƳǱíŻtkyXpO|lKpOpOqP~^rȿĨƪȮɯƯëůȵ˸͹̸ʷȵȼʻ˸˳˰ʭ̱ε̶ʷűǻoWtHvNxR]sɰ̴ιι̸˶˷̴̵ηϹλλλλλλλͺλͺ˸ɶɶ˸λннϼλλϼϼϼλͺͺ̹̹ͺͺλ̹̹˸ʷʷʷ˸˸λϼнѾѾѾѾнннннннннλλλλλλλλμͻͻͻͻͻ̺̺̺̺ͻͻͻͻͻμϽϽϽооѿѿѿϽϽϽμμͻͻͻμμμμμμμμ̺ͻμϽϽϽμμʸ˹̺ͻμͻ̺˹˸ʷʷɶɶʷʷ˸λϼϼλͺ̹˸˸˸˸̹ͺͺͺλλϼϼϼнннϼϼλλλ̹λннͺ˸ʷ˸˸˸˸̹̹ͺͺκϼϼϺϺϺιηηεεдѵҶӷԸӺѻккϹϹϹϹкθθθϹϹкккιιιι͹͹̶̶ϷϷ͵̴˱˱̲̲̲ʮȯ˱ϵѷϸͶѻкθͷͷθкѻϹкϹ̶ͷкθʲʮ̯βͱ̰̰ʰǭͶ˴ͶһѼ˶̷ҽͷͷͷθθϹϹϹѻѻϹθθθθθͺʷɴ˴ȯʾĶ´Ʒ»¦δٿҺҺҺѹиϷζ͵ζ͵͵̴̴̴͵͵ѻθʴɳʲ͵ηϵδж϶ƫ¸ywuuz¸ƭɰηйҼѻнѾιιιϺϺлллҽϺ̷ʵɴ˶͸ϸƿŻǸ|zntqyƫ̵ϸη˴˴ηϸ̵ͶηйѺѺйηζϹѺзʹͳжϳʮżwbrRsT^d~Ĭ̴̴˳͵иѹиϷζζϷиҺӻζ͵̵ηϸ˴íȽ|~úũƪȬ˯ϲҵгͰ̯ˬƧú~ska{Y}Zcp}ƽƩʭʮȬȬ̰жжεʹεзɱ˳̲ͳʯĨʼŶórigfjrǼ¦çʿøĹȽ¦v|[lIua>s`?ubByiH}^uɿ϶жζϷ̶ūŦɿwbzSwPzPYg ǤȨʭĭŰƱǲȱȱȱȱʰʰʰɯɭȬȬȫƨu|XxhDn^:l\\8m]9qc>tSqŨɬǭǯȰ˳͵̴ȰĬŭƮȰɱʲ˳˳˳̶ͷ˵ɱɯƪĻp`}S}Q}PxI{JV}bëȰɯǭũŪå̾ƻwmb^[~ZalzŻéǭǰǰǱθʷƳİðŲȵʷǴɳĮŻwfy[tS|lKwgFyiHyjIyjIrRzZm}ȫ˰̰˱ǰìůͷм̸ɶʷȼ˼˸ǯè¥Ǭ̳˵ɶǳpWxLxPyS]sȯɱ͸ι͹ι͹̴˴ʳ̶̹ͺλͺ̹ʷɶͺ̹ʷɶɶʷ̹ͺͺͺͺͺͺϼнннͺʷɶʷ̹λϼλͺ˸˸̹ͺλλλλϼϼнннннннннннϼϼλͺͺ̹˸˸̺̺̺ͻͻμμμ̺̺ͻμϽϽϽϽооооооооϽϽϽμμͻͻͻϽϽϽϽϽϽϽϽоμͻͻμμ̺ʸɷʸ˹̺̺̺˹˹̹˸ʷʷʷʷ˸̹ϼλϼλͺ̹̹˸˸̹̹ͺͺͺλλϼϼϼнннϼϼλλλλнѾѾλ̹̹̹˸˸˸̹ͺͺλλͺͺ̷̹ʶ˶ɳʳɰʱ˰ͱͲϳϴϴϷϹθͷͷͷͷͷʴ˵˵̶ͷθθϹмѼллκ͹ͷ̶ииϷζͳͳ̲̲ϵͳ̲ͳжҸйηккϹθθϹккθкϹ̶ͷѻϹʲϳггϲββ̲ʰη˴̵йл̷͸ѼͷͷθθθϹϹϹѻкϹθθθθϹѾ̹ȳīĸ||xzūҸϷϷииииϷϷζζζ͵͵͵ζζѻθ˵ʴ̴ζδδжж˰vod`__dnǬɰ̵ηθ̶̹̹ιιιϺϺлллѼϺ͸̷˶̷͸ιʳɯ¨Ƽɾ˽xl~]a{\\ewȼʹйϸ̵˴ηϸ̵ͶηйѺѺйηζϹһзεδжβʭp|\\|mL~oNzX_z¸Ĭ͵͵̴ζииϷϷζ͵ζϷиѹϷϵηжδǭƼ}yvxƽũȬɭʰδѵдβͱͰͰˬƧ£sdwU~qNrP}]j{ø¥Ūǫɭ˯δϵ϶εεε˳˱̲˰ɭô|pb]^clxɬ̰ˮǫŨ¦ŨȬͰʮ¥s]nMwdCq^>p`?~oPeĹɮ˱ʳ͵̴ūƧx`zSxNzPXhȿĤƨǪƯǲȳȳɲȱȱǰɯɯɯɯɭɭɭɬ̮Ʀĵz~\\wgCm]9k[7k[7m_:{mJeƿƩȮǯȰ˳Ϸи˳ǯŭƮȰɱ˳˳˳˳ͷθͷ˳˱ɭp^{OuHq@rAuIb~ɽ¨ĩƫŨǸ|tkd_aflvȷŽ«ǯȱʴʴɳ˸ɶǳűıŲǴȴ˸̶ůùox\\nP~nMwgFscBwgFyjIzkJ}pPuU`oåˮ̯˯ʰŮǱθѽ͹̹λ˻˼˸ȰèæǬ̳ʴȵƲpXyMxPxR\\rǮɱ͸ι͹ι͹̴˴ʳͷͺλλλ̹˸ʷ̹̹˸ʷʷ˸̹̹ͺͺͺͺͺλϼнѾнλ̹˸˸̹ͺϼλͺ̹̹̹ͺλλλλϼϼнннннннннннϼϼλͺͺ̹˸˸̺̺̺ͻͻμμμͻͻμμϽϽμμооооооооϽϽϽμμͻͻͻϽϽϽϽϽϽϽϽϽͻ̺̺ͻͻ̺ʸɷʸ˹̺̺̺̺̺ͺ̹˸˸˸˸̹ͺϼλϼλλͺ̹˸˸̹̹ͺͺͺλλϼϼϼнннϼϼλλλϼнҿѾϼͺ̹ͺ˸˸̹ͺλλϼϼμϼͻͺ˸˷ʴʴɱʱʰ̱αϲгϵикϹϹθθθθ̶̶ͷθϹкѻѻѽѼѼл͹̸̶˵ӻӻӻҺҸжϵδҺиϷиѹҺѹиккϹϹϹϹккθкϹͷθѻϹʲͰ̭ʫɪȫǪƫǬ϶˲ʴͷϻ͹ͻнͷθθθϹϹϹϹѻкϹθθθϹϹҿλǲƼve_zZxWz[ftȰ˳̴ζϷиѹѹѹϷϷϷϷϷϷϷϷѸ϶ʹʹζϷδδγͲǭȼ{k}`zYwTrQrPtTb|ɮ˲ηηθθͺϼιιιϺϺлллϺϺϺιιιιιҺҸδȭɭæwepRpR|kMrXlȺεѺйͶ̵ϸϸ˴ͶηϸййϸηζкӼѸ϶δжβɬq}^~oNpNzV^yë͵Ϸ͵ζиϷϷϷζ͵͵͵ζζϵгϵͱŪùpmmp|·ʿƫǬɰʱ˱˴ηѺ͵ͳͳϲдϲͰ˫äżo|YukGpc@wjH~qQ_ræȫʮʮ˱ͳззη̳͵˱ʱʯŪɺ|j`|Y|Y^j{ʿũʯдеβȭƪƫʮ̱ϳ˰ƪǽ·n{[oNxhGxiJwZkèǫȮ˱˱ƪɪyazSvMxMXh~Ǿ¢ħéɲɴʵʵʳɲȱǰɯɯɯɯɭɭɭɬʬƦŶz|ZueCl\\8k[7k[7j\\7rdAzWqƨȮƮƮʲϷѹ͵ȰŭƮȰʲ˳̴̴̴̴ζζ͵δδŪƽźo~TsFrArA}pCvVsǹ˻ʻǸŶvplkighq{ɹ©ǮʴʴɳȲȲɵʶʶʶɵȴǳǴƳƳűʷ˵ígpTxgI{kJueDtdCzjI~oN~oN{nNylLsQ}[møĥȫȭʰȮʲͷκ̸͸λ̼˼˸Ȱĩħȭ̳ɳǴűqZ{OwOwQ~ZoþǮʲιι͹͸̸̴˴˴Ϲλλϼλͺ̹̹̹̹˸˸˸˸̹̹λͺͺͺͺλϼϼϼϼλλͺ̹̹̹λͺͺ̹̹ͺλλλλλϼϼнннннннннннϼϼλͺͺ̹˸˸̺̺̺ͻͻμμμϽϽμμμμͻͻооооооооϽϽϽμμͻͻͻϽϽϽϽϽϽϽϽμ̺˹˹ͻͻ̺ʸȶɷ˹̺ͻμμμλλͺ̹̹ͺλλϼλλϼλͺ̹̹̹̹ͺͺͺͺλλϼϼϼнннϼϼλλλλнѾϼͺ˸̹ͺ˸̹̹ͺλϼϼнͽͽ̻̺˺˸˶̶ʳ˳̲αβгϳжζθϹϹϹθθͷͷθθθϹϹккκϺιι̸̸˵˵Ϸииѹжϵͳ̲ӻҺѹѹѹѹиϷкккϹϹккккҼѻθθϹ̶ƮƩƽżĻĻȾè̳ʱȲ˵κϻμλ͸θθϹϹϹккккϹθθθϹкѿͺű÷guWrR}hIyfFxhGqTcxʲ˳̴ζϷиииϷϷииѹѹиѸѸ϶ε϶ϷжϵͳʯʯȮo}`}\\vTqPpOrS`~·ȭʯͶηθϹнѾιιιϺϺлллιϺлѼллιθкҹζ̲̱Ȭza}jL}jLzgIoSi}ȺʹѺѺηͶϸϸ˴ͶηϸϸϸϸηζѻӼҹ϶δѴ̱Ǩq~]pNpL{W^{ª͵иϷϷиζииϷζζ͵͵ͳαΰ˯ħ¹zpdelwŷĨɯ̱̳˲ɳʳ˶͸Ϻ̶ʹ͵ϵждϳϲɬŦȿi~tQpfBqbAqbAzkL`xȽɬ˯ɭɯ˱ззͶɰ̲˯ɮȬæŴo^|Y{X^fv;ƫɯ˱̲̲ʰǭūɯ̲δͳʰū¨shefr§ƫȮʰʰƫɫã{cyRuLvKVf}ǼéĬ˶˶˶˶ʳɲȱȱȮȮɯɯɭɭʮɮʼtwVqa?k[7l\\8m]9i[6l^;xnJa{ǩǭŭĬȰ͵ζʲŭƮǯȰʲ˳̴̴̴˳͵ζ͵δϵʱèw~WsHxIvE|oBxkHkȻǸ|pkeekpwyȹοůȵʷϼ̹ȵűıűȵʶɵɵʶ˷ʷȵƳűưůɾ|coSyhJ~nM{kJ~nMvU}\\{ZrRwjH|nK~pM|YnȽħɭʰ̴̴ʴȴʵ˸ͽ̽˸ȰƫƩɮ̳ǱŲİ˿r[|PwOwQ|XlǮ˳ιι͹͸̸̴˴˴кϼϼϼλλͺͺ̹̹̹˸˸̹̹̹λͺͺ̹̹ͺλλλλϼϼϼλ̹˸ͺͺ̹ͺͺͺλλλλλϼϼнннϼϼϼϼϼϼϼϼλλλͺͺ̹̹̹̺̺̺ͻͻμμμооϽμͻͻͻͻооооооооϽϽϽμμͻͻͻμμμμμμμμͻ̺ʸ˹̺ͻ̺ʸɷʸ˹ͻμϽϽϽнϼλλλλϼнϼͺλϼλͺͺ̹̹ͺͺͺͺͺλλϼϼϼнннϼϼλλλͺλϼͺ˸ɶʷ̹̹̹̹ͺͺλλλɺɺǹȷǷɶȴȳȲɲɰʮʯˮˮ˯ȱɴʵ̷̷̷˶˶ʵʵ˶˶˶˶˶̶͹ιιικκθθʲ˳˳̴̲̲˱ʳѻѻѻкϹθθθкккѻѻкккӽտӽϹθͷɳ¨żĺŬǮȲʴ͹ϻμλ͸θϹϹϹккккϹθθθϹккϽ̹ű¶bnO~jIybBt`?qa@whIv[rëʲ˳̴͵͵ζ͵͵ζϷиѹҺҺѹҹҹз϶зжѷжβȭɯʯɮξxfyXqM{kI}oLtSbǼǬɮ̵Ͷͷ˸͹λιιιϺϺллл͸ιлѼѼлϺθϹкεʰ̱ʮõ{]xeGyfHxeGlQ}bwĴ˲ϸйηηйϸ˴ͶηηηηηηζкӼҹ϶δгʯĥl{Z}mK~lHuP}Xv͵иϷииϷѹѹѹииϷζδͰ̬Ũwh_}^fvĶèʰͳ͵˵ɳȴȴɷʸ˸͹ηθз϶δδϲʬɩƦz_yoLrdAn`=qbArPf{æʮȬȮʰ϶з̵ɰʰɮǭǫ;vfuTtSxWanū̲˳ɱȰǯȰɱʲϷѹѹи̴ɱȰǭéɻȾǬɮɮʯɮǬɭ¥³|bxQtKuL{Rc|ǼĭŰ˶˶̷˶˴ʳɲȱɯɯɯɯɭɭɭȭȽŷnrQo_=iY5k[7l\\8gY4hZ7pfBxUmūŭǯ˳͵̴ȰĬƮǯɱʲ̴̴͵͵Ȯ˱̲˱˴δ˲ƫĹs|WsJvKtExk>wkEeyneuXuWvXap~Ź˿İųŵǶȹν̺ǶıòŲȷ˸ɶʷ̹ͺ͹ʶǳűĮíźv{^oS|kM~nMrQ|[gpnbtRqLzlG|nI|Yl~¹ǫ̲Ϸ͵ɳǱʵ˸Ͽ;˸ȰǬǪʯ̳ǱŲİ˿s\\}QxPvP{Wjȯ͵Ϻι͹̷˷̴˴̵ѻϼϼλλͺͺͺ̹̹̹ͺͺ̹̹̹λͺͺ̹̹̹ͺͺͺλϼннϼͺ˸˸̹̹ͺλλλλλλλϼϼнннϼϼϼϼϼϼϼϼλλͺͺͺͺ̹̹̺̺̺ͻͻμμμѿоμͻͻͻͻμооооооооϽϽϽμμͻͻͻμμμμμμμμͻ̺˹˹ͻμͻ˹ʸ˹̺μϽϽϽϽннϼϼϼϼннϼͺͺϼϼλͺͺͺͺͺͺͺͺλλϼϼϼнннϼϼλλλͺλͺ˸ɶȵʷ˸ͺͺ̹̹̹˸˸ʹɻȺǹƸŵųĲïůƭƭŪŨŨħèìįǲɴ˶˶˶˶ɴɴʵ˶̷͸ιкϻлллϻϻϹϹ̴̴̴͵δϵѷҺϹмкϹͷ̶ͷθккѻѻѻѻккԾտԾкθͷǱynijlzŻêȲʴ˷κμͺιϹϹϹкккѻϹϹθθθϹкѻμ˸űǸemN|eEw`>p\\9n[;paB|nSlëɱʲ˳̴̴̴̴̴̴ζиѹҺҺѹѸӺѸ϶϶жѷѵд˱˱ͲͲūĴlxWmIzgFoMxWcĹȮ̱йѺϼͺ͹͹ιιιϺϺллл̷͸ϺлллϺϹԿϹ̴δ˯ŷ}_yfHyfHzgIlQy^qǯ̵ηͶͶйϸ̵ͶͶͶͶͶͶͶζϹһҹ϶ͳαǬi{YmIkFtO}Xv̴ζζϷѹѹииѹѹѹиϷϵαɧýxe}[xUxYhǭʰ˳̶ɶȴȶɷɹȸȷλллϸ̶̳ʹͳˮ˭ȫĤ¼ozVvhEp`>m^=whGuVgǬȬɯ˱ʹʹ˴ɰȮȭȬæŶk~]rQrQzYizŹɰҼкͷʴʴ˵θкϹϹкϹθ̶ʴȲʱȭīƼŻǽ§ƫ˰̱˰ɮȭƬǭ{cwPsLuLzQb|Ƚ©Űǲʵʵ˶˶˴ʳɲɲʰʰʰɯɭȬȬǬçǹkpOo_=iY5jZ6jZ6fX3gY6lb>xnK]yſĬ˳ζ͵ʲǯŭǯȰɱ˳̴͵͵͵Ȯ˱˱ɯǰʳɰƭĸr\\wPvMrExk?{oGavwk_vWsTlOnQvXf|øȼʿðĴǶŹƹƻȼ;˼ȹǵƵǶʹ̻ȵʷ̹ͺ͹ʶǳİǱůønuX|kO{jLyiHvUhytavR{lEvhC~pK|YfyȿʮѹϷɳɳ͸λ;˸ɱȭɬ˰̳ǱŲİ˿r[|PzRwQzVhɰилϺ̸˶ʶ˳̵Ͷкϼλͺ̹ͺͺͺ̹̹ͺͺͺͺ̹̹λͺͺ̹˸̹̹̹ͺλϼннϼλͺʷ˸̹λλλλλλλλϼϼнннλλλλλλλλͺͺͺͺͺͺͺͺ̺̺̺ͻͻμμμоϽμ̺̺ͻμϽооооооооϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻͻ̺˹̺μϽμͻͻͻμϽϽϽϽμннϼϼϼϼннϼ̹ͺнϼλͺͺͺͺλͺͺͺλλϼϼϼнннϼϼλλλλλλ̹ɶɶʷ̹λͺ̹˸ʷɶȵǶƸĹµ̾ɼƹöµƺŹĸ¶ûƾǿǿǿǿîƱʵ͸ϺҼѽѼлϺ̸˷ʴɳɱȰǯȰʰͳѷԼͷлҽѼι͸ͷϹккѻҼҼѻккѻӽӽкϹϹɳ¨l|X|sRxoPzqRctȾɳʴɵ̺μλιϹϹкккѻѻϹθθθθϹкѻͻʷű̽puUjHw_=qZ8jU6iX:pbGz_ŭǯȰʲ̴͵͵ζ˳͵ϷѹҺҺизպӷϴϴϵѷҶҶжδͲ̲ɯνz`rL}kGtR|[av˿Ū˴ϸнϼϼκιιιϺϺллл̷̷͸ιιιιϹԿѻζѷͱƸd{hJzeHzeH~iNuZmëɲ̵˴Ͷйй̵ηͶͶͶͶͶͶϷθѺѺε̲̯Ūȿg{YmI~jEsN|Uvª˳͵̴ϷҺҺ͵ζϷиѹиϷϵ̬ßxczUsPsMx[nʺūȮɲ˶̶ɶɷʺͽͿ˽ʻλѽҾл͸̵εеˮͮɫƦã}d|nKtdBo_=rdAxiHwWuŪȬʰ˱˲ʱʳ˲ǭɮɭͿt_tSqPsR}^r˳Ҽѽϻκ͹͹͹κʶɵʶ͹мм˷ǱŭȮȱȮƯɯ˱ͳȯɰ˰ͲʰǭƪūūͿ{bwPrLsK|Uf}ȼ©ŰƳȳɴɴʵʳʳʳɲ̲˱˱ʰȬǫǫŪũĶe~nMqa?l\\8l\\8k[7i[6k]8lb>rhE{uQg{ýɱζʲŭĬƮǯȰɱ˳̴͵͵͵ɯͰ̲ȮŮǰǱŬǻq_zVvOsHrFvNcsoauTpQoPnRqTw\\jźɿ¯ŵƺɼǾǽƾȿ˽˽ɼȹȹȹɷʸǴȵʷ˸˶ɴűïɳůg}oRyhL{jLxhG{Zs{gxT}nGwhAzlGqNwUh|̴˳Ǳɳιнο˸ɱɮʭ̱̳ȲƳű˿rZ{O{SxRzVg˲ҺлϺ̸˶ʶ˳̵Ͷкλͺ˸˸˸̹ͺ̹̹ͺλλͺ̹̹λͺ̹̹˸˸˸̹λλϼϼнϼϼλɶ˸̹λϼϼλλλλλϼϼнннλλλλλλλλͺͺͺͺͺͺͺͺ̺̺̺ͻͻμμμоμͻ̺̺ͻϽѿооооооооϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻμͻ̺ͻϽооμϽϽооϽϽμͻннϼλλϼннϼ̹̹нϼλͺͺͺͺλͺͺͺλλϼϼϼнннϼϼλλλϼнϼͺʷ˷͹ϻϻϻ̹˸ɶǴƳĲʽʻƷ~Ź˿ĮǳʵкйηʴǱŭë¨ĽüƼǬ˱͹лѾѼλιϻѽϷиҼӽӽҼϼλͺнѾмϼк˵ĬmyVxmMrgGtiKxZoǻʱ˵ɵ˹λλιϹϹккѻѻѻθθθθθϹѻѻ˹ȵƲëó}auTvbAo[:fS3bQ3gW=zlRwìŮȱ̴ζϷиʲ̴ϷѹҺѹϸϷ־Ӹδͳϵѷӹӷռϵ̲̲ͳūõjxV~nLuSzYzYewȼĮɴʷʷ˸ιηηϸϸйлѻ̷ͷͷͷθϹϹϹιйϹϷҷдȺdyfFu`Cs^AvaDmRdȮ˱̲δѷѷͳϵδδͳͳδδϵεѸзʹ˱ʮħǼauQzhBxd?nFwOn¨˳̲˳ϵӻԺ˳̲ζϵижϷϲƤjzUwmIxlF{mHz[sǬȮ˳θ̶˷˹μξͺκѼҽѼͷ̶϶ҷ̯̯ɬǪȫ¢tqPxhFrb@scBsdC|oOnèȬ̲̲ɱȯɳ̳ƪʭɫ˾jwVnJmIoMzYqȫζθθθ̶ʴȲưɳȲɳϹտϺʲǭʰʰȮƬǭɯʰɰɰʯ̱ɯƬĪĪé˽zavOrJsK~WfȽ©ïŰƯǰȱɲʳʳʳʳ̵˴ʳʰȮȫƪĩz~`}mLscAp`<o_;o_;n`;pb=rf@sfCxnK~[mū˱ƮĬǯȰʲ˳̴γͳͳʰͳͳȰĭƯǮĬĸf|[xTsLqHvLXo}n_xYuVoRoRuWbt´Ŵɺ˼ʽȼǻǼȹȹȹȹǸǵƴųƳǴȵɶɴǲïư~}b{lOziKlL|iI_z²ubxTnJ{iE}kG|lH}oJ~[oũƬĬǱ͹ϼϿ˹ɳʯ˰̱̳ȵǴųοsZzO|RyQ{Tf»̳ҽϻκ̸ʷʶ˵͵ζλͺ̹ʷʷ˸̹̹˸̹λϼϼϹ̹˸λλ̹˸˸˸˸˸ϼϼϼϼϼϼϼнɶʷ̹λϼϼλλλλλϼϼнннλλλλλλλλͺͺͺͺͺͺͺͺ̺̺̺ͻͻμμμϽμ̺˹̺μоооооооооϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻϽμͻμоѿѿϽооѿооμͻ̺нϼϼλλϼϼнϼϼϼϼϼϼλλͺͺͺʷ˸ͺϼѾҿҿҿннϼλλͺ̹̹ξ˻ͼѿϼɶɶϼͺλʷųȶ˺ŵȼzwuuuy|yrnpmlloqomqs~ƶνǱ͵϶ʹȭéǽ}ƸĨǮϺҽомѾʷҸҸҺҼҼѾҿҿͽξλϼϻƮivWteFo^@tcExgIc̾ʰǮ˷лͺ̹Ϻ͸̷͸ϺлϺι͸ιιϺϺιι͸̻ͺȴȾwxXreCbU5]N/dS7hT;nXAsbȹůɳʳζиззҹҼѻθ̷͹кҼкθ̶˵ηϸѷѺѷδ˱˱˱ém}]vWtSsSwX~_t}ʺůƲɶͷϸжжϵϵϵζ϶ζззѸккϹθѻ̶ζϵ̱ͱ̿~^vcBq^>o\\<ubBpRcæȬ̰˯̰βͱɭ̰ͱͱͱͱͱͱͱӹ˱Ͱ̰ʭίʩĺ~|Y|lHqb;tb:}lAxMsúƪжѵжҶӹӷϵджϳδͱ̲ˮģu\\|oLwiFzjH|lJxWr¥Ȭʯͱδ̲͵ϷйҸҸеѵѷҷеϴͳͳͳϲͱͱʯǬƫæbvfEo_>hW9iZ;uhH}`Ƽ˯ɯĬȰȰ˱ˮ̭Ħu\\tMpIqHsJYoºÜʦгϳβ̰˯˯ʯʯƬƬȮ̲ϵδʰūƩǪǬƫƫǬʯͲ̱Ͳεε̳ɰŬ¨ĩ˼s~ZsMrJwLyQgµɾŨƭŬȬȬɯ˱ʳʳ˵˵ɳ̶ͷɱǯǬ¨üôn|[qP{mJ{mH|nItMqJzlEwgCueA{hGrQ}[uǪūªªůĮưɰ̳γϱαͲ͵˶˶ʳǱǮƬƪʼ~jyUsMtLoD}TbķõuiazZsSqPyU]ix°Ƿì̴ʴʳθмϺʹȷǶɸ˺̹ɶƳƳƳƳƳƳŲŲİƿmqUzgI|gHkKoP_tvdYvUoPmMoMpKpHvMUmū˵κ˻ɼȸɵʹε̳ɳıƳųʻsZvKuHuJzRe«ȵȵʹͼͺ͸̶ε϶ϼμͻ̺˹ʸʷʷθ̶ɳɳʴ̴̶˵˸˸˸̹̹ͺͺͺλλλλλλλλ˸˸˸ͺϼнϼͺλλλϼϼннѾϽооѿѿооϽμμμμμμμμϽϽϽϽϽϽϽϽμμμϽϽооооооооооооооϽϽμμμμμμμμμμμμμμϽϽоооѿѿѿооϽϽϽоооϽϽϽμμϽλϼϼϼϼλλͺͺͺ˸̹ͺϼѾѾҿҿннϼλλͺ̹̹ͽȸǶͻѾλ͹κ͹ι˸ƳǴųɼsjdemtxyvqlid\\{WyXyY~apɷŰ͵зγǪžngc~_bsĶ̷лѽмѿλдѷѹѻннͿξνͺϼӾϺȰmwYveGr_AvcEyfH}_ʼɯǮ˵ѻλκι͸̷͸ϺлϺι͸ιιϺϺιι͸ɷ˹ɴƯƬĿkxoNf[;^P3bQ5dN7fK6|_M}lϾȲ̶ии϶зҹҼѻι͸κϼѻкͷ̶˵̶ϸйѹѹ϶̳ε϶ɰl}]sRkLlLqR~`j~Ǳ˶Ϲждггδδϴϴ϶ззѸййϸηϹ˲˴ͱɯ˭ʻ}^xeDubAta@vfErQcŨǪƩǪˮ̯ʭͰͰͰͰͰͰͰͰдɭʭʭǨʫť{{V|lHsd=vd<nCyNqøũϳѵдѵӷӷϳϳϳϳβͱ̰ˮßoyUwiFtfC{hGlK{XtĤȬˮͱϲγϴϵжѵѴггͱαͰ̯ʮʮʮ˯˰˰Ȯūū¶exhGp_AhW9gX9sfFz_ƫǭƿĬȰǯʰ̯ʫɾkyT~oH|mDrIsHVmżśɢɪɬʭʭʭʭȬȬŪŪǬ˰δͳɯǬåŦŨŨŨǪʯͲ˰̱ʹʹ˲ȯŬ¨ĩ˼r~ZrJrJvKyQgµ˾Ĩƫĩǫȫɭʮʳʳʷʷȵ˸̶ȲȯȭŪž±izYqO~pMtOyT_]XuN}iFyeBjHrOgy¢ĨéĬůíĮǮʯͱΰϰαͷ̷˶ʳɰȭǫƨ̽|k|UtNvNrGVjʽʽvf{[uQuOzRWdtòϿũȭβѶз˸ɶǴȵʷ˸ɶƳııı¯¯íĽ~b}lNvcCybC}dElN}[mvsfYxRuVrVtUxXxStLtIyMZmžɱ̹˻Ƚƶȴʴʹ˵ʴòŴòɺrYvKvIvI{QdĶíɶǵɹ̻ͺ̹͸ηϹϼμͻ̺˹ʸʷ˸θ˵ȲȲɱ˳˳˳˸˸˸̹̹ͺͺͺλλλλλλλλ˸˸˸ͺϼнϼͺͺͺλλϼϼϼнϽооѿѿооϽμμμμμμμμϽϽϽϽϽϽϽϽμμμϽϽооооооооооооооϽϽμμμμμμμμμμμμμϽϽϽоооѿѿѿоооϽϽоϽϽϽμμμͻϽλϼϼϼλλλλͺͺ˸̹λϼнѾѾѾннϼλλͺ̹̹ͼƷĳ˹ҿҿϺ͸ɴʳɵưƹlc][bqȾğğÝ¿{l^xVzjHueDxeGpThůϹѸγŨi}pPwhIsdEpaBteFtWrǽưιҽлλѼҿѽϵϵϸϺнн̼Ͽν˸ʷϺϸʰpxZwfHr_AubDwdFy[}ǹȮǮ˵Ҽλмι̷˶͸ϺлϺι͸ιιϺϺιι͸ȶʸɴȱ˱ǩy~uVj_A^O2bN3`J3^C.jM;}bOr²ë̳ѷиʹѸҹҺҺϺϺϻѽкϹͷ̶˵̶ηϸии϶̳εҹ϶ɮ{fsR{fG{dDgHlNsWlȹů˶ηϵϳββδͳͳͳззззйϸηͶ̶ɰʳ̰ǭȪƷy|[wdCvcBubAueD}mLz[|»žĽƿħȫǪȫȫȫȫȫȫȫȫ˯ĨũŨäʿwyT|lHuf?yg?oGyNpçβдϳдҶѵβϳϳββ̰˯ʭkuQtfCrdAzgFlKxWrũȫ˯̲ͲͲ̲̲̰̯̯̯ϳϲϲαͱͱͱβ˰ʯƬéé÷exhGq`BiX:fW8pcCuZ§ūƿĬȰƮǭˮƧ{_}oJxiByjCpIpG{TkúǿǾȿ¥ħŨŨ¦¦¦èǬʯʯǭƫĨŨƩŨŨǪʯͲʯ˰̳̳ɳưíèʻq~ZrJqIvKyQgö˽çĩèƪǪȬʮɲʳʷʷȵʷʴǱǯɯūȿyauSoMsP~XcvwrbrOzfC{dB}iFxRd{żéŭëĬƭȭ˰Ͱϰϲ͵̷̷˴ʱȭǫƨ˼|k|UvPxPtIYsĤɻĵvi}\\vRsMtL{S]qɻçʮͳͲ͸˶ɴȳɴʵɴȳįįîoxYyhJubBxaBzcCmNzXfhb~YzTxT~aeimh\\zQwMyO_p¨ȳɷʿǾǷǳɳ˲˵ʴ±òǸqXuJwJvK|ReøĮ˸ȶɹ̻̹̹͸ͷϹϼμͻ̺˹˹˸˸̶ʴǱưȰʲ˳˳˸˸˸̹̹ͺͺͺλλͺͺͺͺλλ˸˸˸ͺϼнϼͺͺͺͺͺλλλλϽооѿѿооϽμμμμμμμμϽϽϽϽϽϽϽϽμμμϽϽооооооооооооооϽϽμμμμμμμμμμμμϽϽϽооооѿѿѿѿоооϽϽμμμͻͻͻ̺μλϼλλλλλλλλͺͺλϼннннϼϼϼλλͺͺͺͽʺɷͺҿӾϺ̵ŮŬªļq^[`fpϮЮϯϮͬˬɪȩǦŢ¼rgqPvgHpaDwgMy`yưѻѺ̳é{^m`@l]>gX9dU6gX;tdJ|bĸĬ϶ԾҼͷθѻҼηηϺлнѿξѾн̷ʵͶ϶ͳqxZwfHr_AtaCtaCuWwõƬǮ˵ѻϼѽ͸˶˶̷ιлϺι͸ιιϺϺιι͸ʸ˹ɴǰɯƩx|sTg\\>\\M0`L3aK4^E/cH5nUAmXm÷ǮжиʹѸҹҺҺѼлммϹθͷ˵˵˵Ͷηии϶̳ʹѸз̱ŨluT{fGzcC}dE|cEhLz_~Ȳ̵δβͱͱ̲̲̲̲϶зззϸη̵̵˵Ȳʳ̲ǭƨ³vvVs`?ta@r_>o_>scB|mNpüƿƿƿƿƿƿžçĽƿžĻ·twR|lHvg@yg?nFwLm̰ϳβϳддββββͱ̰ʮʭßkuQtfCrdAxeD|iH}nMhøȽ¥ƬǭȭǬūĪççħħͱͰͰ̯̰̰ͱβɮȭéʾʾȼ`vfEq`BkZ<iZ;qdDsX}èƬŭǯëĪƩtzYxjGueAwhAzjFzjFvQhúżƽĻ··øǹɻ˽̼̾ʼææ¥¥Ũɮ̱ɮʯ˲˲ɳưí§ɺp}YqKpHuJyQhö˽¨êũƩǫɭɲɲɴɶȵʴɳƮȮʭƩǾqzYoM{kIrO]np{WkH|eCzfCqc>}qKavȾĪūƬǯɮʭ̯ία͵̷̵̵ʱȭƪĤȹyg{TuMxPuJZt˾¥ĩϿȹm^vRqKrLuQ~^oǼħǫȬ͸˶ɴȳȳȳȳȳįŰįzcrPyiHxeEydE}fGkLuU_`|[yX~Zcv}ucX|TZdsʿŲȿȸȴȲʱɳɳ¯ıƷmUvHvKuJ{SføĮ˸ɶʺ̻̹˸͸θкμͻ̺˹˹˹˸˸˵ȲůĮƮɱʲ˳˸˸˸̹̹ͺͺͺϼλͺ̹̹ͺλϼ˸˸˸ͺϼнϼͺͺͺͺͺͺͺͺͺϽооѿѿооϽμμμμμμμμμμμμμμμμμμμϽϽоооϽϽϽϽϽϽϽϽоооϽϽμμμϽϽϽϽϽϽϽϽϽϽϽоооѿѿѿѿѿоооμμͻͻͻ̺̺̺ͻλϼλλλλλλλλλλϼнннϼϼϼϼλλλλͺͺͽϿҿѾлϺͶ˲ƭſq~bwY|Y`o~ùȩҵҴгϲͲ̳̳ͱ̮ʭɫǪ£{fzZ}oRuYj¸˴ӽѺ˲ébpbEl]>fW8aR5cT7k[A}mSsͳּԺϷϷѹӻϺϺлнппнҿ͹˴εѵαovXudFq^@s`Bq^@qSrƬǮ˵ѻλѽ̷ʵʵ̷ιлϺι͸ιιϺϺιι͸̹ͺɴƯǭ¦wxoPhZ=\\L2aM4eO8cJ4dI4jQ;p\\DrYtǽͱҸѷϵϵиҺһһмϻͷεʹ̳̳ͳͳͳϵжδʰ˰γγʭɫǾmuT{fG{dE{dEx`D{cGrWsȼǮδ̰̰̰̰˱˱ʰʰεε϶϶ηͶ̵˴̶ɳ˴δȮƨtsSq^>r_?o\\<jY;l[=teFhüü»üüü»»Ľ»ruPzjFuf?xf>}kCrGgƿ˯βͱβϳβͱͱͱͱ̰˯ɭɬjuQugDpb?s`?s`?sdC^~»éêýĻü¥¥¦çĨŪèɽ÷¶yZrbAq`Bn]?l]>sfFsX{ƫʰéǯǯª¨ĻrzYxjGueCwgCxhFzjHwVn¸ȾŪ˰ȯɰɳʴɳưíª§ɺp|XpJpHsKyShķ˽ȾçħƪȬȱɲɴɴȳȳǲŮȮɭ¦ø}grQyiGwgE}oL`vķy^nM{gFxdAkY3rc:rK_sŷǬȬɯʭˮˮˮ̴̷̵̵̱ʱǬĨ¢ôtcxQsKxMtI[uƻĪ¨˽˻órawUpN~kJrR|^oƻ¦ȫɳɳɳȲǱưǱǱĮůů¼pyWylJwgFtdCubBxcDydEmNuVxXwY|^jwƶ̽ɺyj_[\\cuɾɿȿɼɷȲȯȯǱðıŷmTvHtIsIySgĭʷʷ˸̻˸ʷ̷θкμͻ̺˹˹˹̹̹˵ȲĮíŭȰ˳˳˸˸˸̹̹ͺͺͺϼλ̹˸˸̹λϼ˸˸˸ͺϼнϼͺͺͺͺͺͺͺͺͺϽооѿѿооϽμμμμμμμμμμμμμμμμμμμϽϽоооϽϽϽϽϽϽϽϽоооϽϽμμμϽϽϽϽϽϽϽϽϽϽоооѿѿѿѿѿѿооμμͻͻͻ̺̺̺ͻλϼͺͺλλλλϼϼϼϼнннϼλλλλλλλλλϻνҿι̵ʱǭscrTlN}mL^lƥȩɬͰ̵̲̳̳͸ιϸздϴϲ̯ä~smq¨иӽѺ˲ƬnykNm^?dU6_P3`Q4dT:m]Cu[qȿͰϴγѷӹӹллннννϿϿϽӿϹ϶ҶвʬjqSraCp]?r_Ao\\>nPoƬȯ˵кͺм˶ʵɴ˶ιϺϺι͸ιιϺϺιι͸˸̷ɲƯǭtwlPhZ=^N4cO6gQ:fM7fK6hP8hW=wgM}bx§γҸͳͳζиһһϻͷʹʹ̳̳ͳ̲̲̲ͳϵδʰʯ̱˰ȫɬƽgqPyfFwbCw`Av^Bu`C~jOe§β˯˯˯ʮʰʰɯɯ˳̳ʹεηͶͶ̵̶ʴͶϵɯũqtTr_?s`@p]=jY;n]?yjKoç¦¦ƿƿžĽĽĽĽĽütvS{kGte>uc=zh@mEbüɭͱ̰ͱβ̰̰̰̰̰˯ʮɭȫºd{qMqc@m_<n[:mZ9rcB}\\|éê»½Ľžɿƺ{xYqa@p_Am\\>m^?tgGuZ~¸ɮ˱Īǯǯª¨ȿútzYykHvfDxhFxhFpOc¸§ȭȯɰʴʴʴǱůëȹpzYoIoIrJySjķ˽Ƽ¦æũǭǰȱɴɴȳȱǰǭȬǪĽt~]~kJvfDueC{mJazµȻw~\\nMxeDr^;mZ2sb7}kCxQbvǹĨǪȫˮ̯ˮʭȮʳʳ˴̲ɮǪ¤p`uLqIwLtI[wʿììοǰêǷtcwV}mLnNpP{]nǹŧůǱɳɳȲǱǱȲưưưů¬þhrOuhErcBo_>n^=s`BvcE}iNqVw[{ak{ĵȼªūũɾ~kb\\]fvúƺȶǱƭŬƭðį¶kTwIsIrJxTgĭ˵ʷ˸˺˸ʷ̷κѽͻͻ̺˹˹̺̹ͺ˵ȲĮíŭɱ̴͵˸˸˸̹̹ͺͺͺϼͺ˸ʷʷ˸ͺϼ˸˸˸ͺϼнϼͺλλλλͺͺͺͺϽооѿѿооϽμμμμμμμμͻͻͻͻͻͻͻͻμμμϽϽоооμμμμμμμμоооϽϽμμμооооооооооооѿѿѿѿѿѿѿϽμμμͻͻͻ̺μλλͺͺͺλλϼϼϼнннннϼͺͺλλλλλλλϻͼӿλ͸̶ȰhuT{hHwcB~jIuTm}ƥ̭̯˯ʰ˳˵˷˷̹̹ͼͺѼйϹѹҸβƩſȮзӼйʹ˱Ȯt}oRk\\?bS6]N1`Q4aQ7cS:oaGrWtǫ̱ϴϳκκͻ̺̻˺ʹ˹ͻϽѽкӺӸͰĦd}lNn]?mZ<q^@n[=}lNlƬȯʴθ˸κʵɴɴ˶ιϺϺι͸ιιϺϺιι͸˵ͷʲƮūĽlrgKfX=^N4bN5fP8dN6eM5fP8fU9n_BzlO}`yħ˰˰˯̲ϵѺһθ˵ͳͳͳͳͳ̲˱˱ɯδϵ̲˱̲˱ȫäz|]{jLxeGwbEs^AvaDt_BxeGtXlŨɮɮɮɮɯɯȮȮɱɱ̳ʹ̶ͷ̶̶̸ʴͶϵȮĨntTr_?taAq^>n]?udFuX}ƿʮ̰ʮɭɭȬǫǫƪũũĨçç¨ĪĨƽȿʿxzW}mIte>tb<we=|jBa»Ȭ̰̰ͱͱ˯̰̰̰˯˯ɭȬǪ|^ukGn`=m_<p]<p]<|mNhźƿūȰɰƭĺĽƿçũƪĩè˿ǻŹ}^tdCo^@jY;iZ;sfFw\\¸ȭʰéƮȰĬĪ¥żsyXxiHvfEyiHxhGtVsȹɽǼȽ¨çĨçĽ¸¸ȯɰʱ˵˵˷ȴƲĮǸozYoInHrJySjķ˽˿ɿŻæĪƬǰȱɴɴǱȲǱǮǬħivSygCueCwgE|mLd¸pzYoNvfDp^:s]4zd;lCsKzTcxʽŦɬ̮˭ɬǭȱɲʳ˱ȭŨȽn^tKpHwLtHZzéūªĮưůȳʳĭŷ|l{\\tSnNpOzYhyƹŭɱ˳ɱǯǯȰƮŭƮȰȰªx^zmJtgDteDo`?paBveIoStZ{cju®Ƴǲǭȭȩȿ}sga`hxĺŲƮĪīŬıŰ÷kUyJtIsMyWhŮ̶˸˸˸ʷɶ˷κѽͻ̺̺˹˹̺̹ͺ̶ȲĮíŭɱ͵ζ˸˸˸̹̹ͺͺͺϼͺ˸ɶɶ˸ͺϼ˸˸˸ͺϼнϼͺнϼϼϼλλͺͺϽооѿѿооϽμμμμμμμμͻͻͻͻͻͻͻͻμμμϽϽоооμμμμμμμμоооϽϽμμμоооооооооооѿѿѿѿѿѿоϽϽϽμμμͻϽλλͺͺͺλλϼϼϼннннϼλͺ̹λλλλλλλϻͺϻ͹ʵ̶ϷȮülrSscBn[:t`=pNb{ȿήѴϳͳ͵ккϼλͼ̻˼˺ɶɴɵͷйѷ˰ȫæüĿƬʯ˰ʹһлθϷͳùv}oRk\\?aR5^O2cS9dT;aQ8gY?tfKvYjʼǫ˯ʭ͹̸˷ʸʷȷǶǶ˹ͺϹѸռԷˮĿ~aziKkZ<lY;p]?mZ<{jLkƬȯʴͷʷ͹ʵɴɴʵ͸ϺϺι͸ιιϺϺιι͸̶͵ʲŭ¨}cm_EcS9\\K1aM4eO7dN6gO7iT9eT6hY:m`@ykNeøæʯɮʱδѺһͷ˴̲̲ͳͳ̲̲˱ʰǭͳϵͳ̲ͳ̲ɭĹqtUwfHveGwdFt_B{fIvcEtcE}lN{\\nøʭɮȭȭɯȮȮȮǯȰʲ̶̳ͷͷͷ˷ɵ͸ηȰ¨nrTq^>s`@q^>o^@yhJ}`ùƪдд̰̰ͱͱ˯˯ʮɭȬǫǫƪǭƬ˱ʰ§Ʃƨƻ~|[oMueAtb<vd>{iA_ǫ˯˯̰̰˯˯˯˯˯ʮɭȬǪ|\\siEn`=oa>ubAwdCxYrǼ˿ūɲ͵з̳ŭĽžɿ¦¥¥æĨƪȬɭɮɮǭĪé˿ewgFn]?fU7eV7qdDx]ƫȮƮȰŭǭǪȿqvWvgFvfEzjIveGuYyðĲƲ˱˯̰˯ʮƪ§ȭȭĪʾ÷õ÷¸¸Ƽêȯɰ˲˵̶˷ɵǳůǷoyXoKnHrJySkķ˽˿ȽºæĪƬǰȱȳɴǱȲȯǬȫäaqLweAvfByiG~oNilwXpOyiHr`<u_8~g=nEqIrJzTgwĵǺǨʭ˭ɬǪȮȱʰʰǬħʿǽk[tKrGwKuI[yƬȰíĮƳǴı˵˶ëƸp|^rQ{kJoNyXf{ľëɱ̴ʲȰǯȰŭĬƮʲ̴ŭo}WxkHviFwjHuhHxiLqVejs~Ƶ˾ɸ̹ɶǱʰͱɩǾuja_mǻðŭéīŬưư¸nVzMuLtPzYkȰθ̷̹˸ʷɶ˸κҾ̺̺˹˹˹̺ͺͺͷɳĮíƮʲ͵Ϸ˸˸˸̹̹ͺͺͺϼͺ˸ɶɶ˸ͺϼ˸˸˸ͺϼнϼͺѾннϼϼλλλϽооѿѿооϽμμμμμμμμͻͻͻͻͻͻͻͻμμμϽϽоооμμμμμμμμоооϽϽμμμоооооооооооѿѿѿѿѿоооϽϽϽμμϽннѾнλͺͺλнѾѾнϼϼннλ˸λλλͺͺ̹̹͹λ˷Ƴȳ̶ʲùo}nQjY;kX8iU4jV3pNq¼ǧˮɬɬ˱ϷͷкҿѾ̼ɹɹʺɶ˶ɵȲǰ˱̱̱̯ƩĨʭͲ˯ʱʹӼ͸ͷи˱ƼyseJhY<bS6bR8iY?l\\CiY@hYBk]CyjKsRbw·ŧůưȲʶ˹ʸǴð˸ϼѻиϷϲȫz]veGkZ<mZ<o\\>mZ<nPpéīȲͷ˸͹͸͸͸͸͸͸͸͸̷̷̷͸ιϺлѼϷγǭ»nufOeU>eS;`N6^J2dN6lV>oZ?lX=hY8gZ8h[9naA}pPg¦ūǯɰ˵Ϲηȱɯˮ̯̯ˮɬƪũʮβͱɭʮͱʮ¥zctU|kMwfHvcEwdF}jLzgIxgIziK|mNzXtĻ§ƫĩŬʰ̲ȱȰɱ͵кѻθʴ̸ɵ̷ͶǯelNmZ<n[=lY;n]AoSj§ǭȮȮ̲ѷѷδ̲̲̲˱˱ʰʰɯ˴Ưʰͳ̱Ӷΰɾ_~nLtd@uc=zhB}kEbʮϳβͱͱ̰̰̰̰ͱβ̰ȬŨpwSukGtfCrdA|iHtSbɻũƬδѺиθθ̴ǯééƫ̰çŨƩǪƪɭͱд˰γ̲ƬūĪĸb~nMo^@l[=k\\=reEgŻǬ̲Īǯ˳Ȯʭĥx{\\yjKveGyhJwfJuYxįȵǵƲ̵δϵδ˱ɯɯ˱ʱ˲˲ȯëĬè§©Įʴ˵̶ϻмϻ̸ɵǱìɹoxXmI}kEmGxTj´˽ªû¥¨éĭǰȲʴɳưªåɾuySoGzhByiE{kIrQkxgyY~qO}nM~nJpHtKuNoG{h@~lF~Wh|ʿŤȩ̯ͭɭūȱ˱˱ɮɬùk\\wNsHvJvJa¨ǯǱȲʶʸǵɵ˸ͷȰȾo|[~nMoNsRzYk}ūƬǭ˱ϵȮɯɯʰ̲ƬewTylJ{nL~qQ~sS}`q{ôǺɹоͺȵƲǮǭȪȨżviceoĸūʭɯƮǱưmX|PyT{ZeyƿȰʴ˶˶ʷʷ˸̹̺̺Ͻμ̺˹˹̺ͺλͷɳůĮȰ˳̴̴λͺͺͺͺλϼннλ̹ʷɶʷ̹ͺ̹̹˸ʷ˸̹ͺϼҿҿҿѾѾнннѿѿоϽμμ̺̺̺̺̺̺̺̺ʸ˹˹̺ͻμϽϽѿѿоϽμμμμμμμμμμμͻͻ̺̺˹̺ͻͻμμϽϽϽϽϽϽооѿѿѿѿѿѿооϽϽϽѿѿѿѿѿѿѿѿоннѾнϼͺͺλϼннϼλϼннλ̹λλλͺͺ̹̹͹λι̷̶θŮ~w]q`DeR4gT4hT3jV3oLnŨʭɬǪȮ˳̴Ϲϼϻ˹ʷɷ˸̸̸̹˵ɲ˱ʯʯαȫȫ̯Ͳ˯ʰ͵ԿιθиɲŻyqcHfV<bS6bR8gW=iY@hX?j[DpbHzkLpOzYfyøŪǬɰʴʶȶǴƳ˸λкϹиж̯ħ}`yhJn]?p]?r_Ao\\>qSréêů˵ɶ̸͸͸ιιιιιι̷̷͸͸ιϺлҺγ̱ǭ~gqaJeS=cQ;cO7fR:u_GnSqVoQrdAm`=j]:m`>tgEuUmȺçȮɱʴͷͶ˱˱̯̯̯ˮʭǫǫ˯βͱ˯ͱϳȬǾr{\\qRnP}lNziKyhJmOziKwfHwgFxiHtQf{ƼĩŪŬȯ̲̲ɲɲ˳ζѻѻϹ˵ͺɶ˸̷ưgmRo\\>p]?mZ<p_CqUlèȮɯɯ̲ѷѷδжϵϵϵδδͳͳηǰȱ˱ɰϴβʿ}\\|lJscAuc?zhB}kEcʮϳβͱͱ̰̰̰̰ͱͱ̰ȬŨq{WzpLxjGtfC{hGqPc̾ǫŭʰ˴ʲ̶̶ʴƮ«éƭ˯ȬˮˮˮɭʮͱϳʯͲ˱ƬƬé`{kJl[=jY;l]>wjJm˰δƬëɱ͵ʰȫ£{}^zkLveGxgIudHoSn;Ƴɵʵ͵ͳͳ̲˱˱̲ͳʱ˲̳ʱƮĬƮȰƫèèĩī©ů˵ϹϹммϻ̸ɵǱ«ȸnwW~kJ|jFmGwSj´̾ªûž¨ĭȱɳ˵ɳɰƬũæɼnrMiBxd?ygCxhF|oOe}zoawYtTvTzW`bcZsMqJyR[rĺƦ̭̯ʭȮ˱̲ʮȫƧɾdWuJtHxLyKbĪɱȲȲȶȶȶʸ̸͸ʴĪùnb}\\z\\wY~`kĽ¨ūʰϵʰȮƬȮ̲Īv~^~qOwjH}pPxXbrǺʽǷͼȸǶŲƱǱ˲̯̮Ʀȿpc_ezƿǪʭɯȲȲîùvc[]dpĪ˲̳ǰȳȵɶ˸ͺμϽͻ̺̺̺̺ͻͺλθʴůůȰ̴ζζλλλλλϼнннλ̹ʷʷ˸̹ͺͺ̹˸˸˸̹λϼҿҿѾѾѾнннѿоϽϽμμ̺̺̺̺̺̺̺̺˹̺̺ͻμϽооѿѿѿѿоϽμμμμμμμμϽμμμͻͻ̺̺ͻͻμμϽϽϽоϽϽϽоооѿѿѿѿѿооϽϽϽѿѿѿѿѿѿѿѿонѾҿѾϼͺͺͺλϼϼλλϼѾѾϼλͺͺͺͺ̹̹̹̹κϻмҼ͹ɽhyhNlX=dQ3hS4hS4hT3}iHdüçç¦¦ĪƬǰȱȰŰưƱȲʴɳɱʰʰȭǬɬ̯ɬˮαγ˲˳͵ϺϹиȱ¸voaFaQ7`P6`P7bR9dT=jZCufQsY{\\yXxW{ZeuĹɾĪǭǱűűƲ˸λλ͸иѹδȬc{jLp_Aq^@s`Bp]?qSqéêĮɳǴʶ̷͸͸ιιϺϺϺ̷̷͸ιιϺлѹ˰ͯɮt_iXDcQ=cN9dP8r^Fw^qvluPthBk_9k^;l^;pa@vWpŷĪȮȯɰ˴̲ͳα̯ˮʭʭʭʭ˯˯ʮ˯γ̱zetU}nOqTtWuXwZ{]tUzkJvgFvhE}oJ}Xgɽéȯ˲˲ɰʳʳ˴ͶѻѻϹͷλʷ˸˶ůjmRo[@p\\AmY>p_CpTmĩɯ˱ʰ̲ѷѷϵжжжжϵϵϵϵйɲɲʰƭ̱̰ʿzYzjHqa?tb>zhD~lFd»˯дβββͱ̰˯˯̰ͱ̰ɭƩu]uQ|nKvhEzgFmL~a̾ɭƮȮǰǱʶʴȲƮ«Īƭɯ̰αϲα˯ʮ˯ͱʯͲ˱ǭǭzz[wgFiX:iX:o`ArRxȭϴѷʰǯ̴иδɮħeqRyiHxhGwfH}lP~dôíȲ̵ϵγʰɯ˱ͳϵϵɯʰ˲ʱɰɰʱ˲ʱǮƭǮŬêů˵ѽѽѽϻͻ˹ɷǴìȸowWlK}kGmItPfõͿªļĽľſ¨ĭǰɳ˵ȰɱɯǪ£ôz`mE{e<vc;xfByiH}pPewzvogbdio}}sc}VzS|UewŻãɩ˭ʭȮ˱˱ȬǪŦȽ_|StItHzN|Nfźɮ̳ɳǱǵǴ̹˸̹θ̵ʰĪ|tm}ax]{`nxƼĩɮȭƫĩƫɮɿlwZ}nO{nNx[ixºǿįƴŵƸɻ;Ĵųıǲʳ̳ʹ˱ʮƩƽ~la{^lyɫʰʴɶƳɾuonwƿɯʹ̳ǰȰɴʵ˸ͺͻμʸ˹ͻμϽμλͺ˵Ȳí¬Ĭɱ̴ζϼϼϼϼнннѾϼλ̹˸˸˸̹ͺͺ̹̹̹̹ͺλϼҿѾѾѾннннѿѿѿоϽϽμμ̺̺̺̺̺̺̺̺ͻͻμϽϽооѿѿѿѿоϽϽμμμμμμμμϽϽϽμμμͻͻμμϽϽϽоооϽϽϽϽоооѿѿѿооооϽϽѿѿѿѿѿѿѿѿонҿҿнϼͺ̹̹ͺλλͺͺϼѾҿнϼͺ̹̹̹̹̹̹̹˸λѻлʴôxnXwcKnZAkV;lW:iT7gT6vcCyZvüüĽžžžƼüù¸ŻżǾ¥ħǪʮͳʹ˲͵ιϼѽкƯsm_E_O5`P6_O6^N5`P9o_Hxcu{pf^_fqyźê¬ůȴ˸ͺͺ˸θкͷȮc{jLo^@o\\>p]?n[=nPjĪŬǱʴƳɵʵ˶˶̷͸͸ιι̷͸͸ιϺϺϺи̱ΰ˰vyjUeS?dO<bM:fQ<zfNm~]ymEk_7l`:k]8hZ7wgF}_rȺéĬǮʳͳгϲͰˮʭʭˮ̯ȬƪƪʮͲƫl~]qR}nOrUz]hrwhwV{mJxjE|nGwP~Yu˿ȯʹ̳ȯʳʳ˴ͶϹϹθ̹нʷʷɴĮnkPmY>nZ?kW<m\\@nRjŬ˱ͳ˱̲ϵжδͳͳͳͳͳ̲̲˴Ϻɴ˴˴Ǯ˰ɯǼxYxhGp`>sa=zhDmGdṵ̈ѵϳϳϳͱ̰˯ʮ˯̰˯ɭǪzbxT|nKvhEyfE}jIx[{ȺȮɱɲʵ˵ʶʶɳǱŮŮǮɯɭ̯αα˯ɭɭʮ˰γ̲ȮūȼmsTscBhW9l[=xiJ_Ƚ̱ѶҸ̲ɱ͵иϵγɬƻp{\\~nMyiHoN~mOx[uǻƭ̲жγɯɯ˱δϵϵɯʰʱʱʱʱʱʱ̳ɰǮȯƭêůʴϻϻκ͹˹ʸʸȵĭʺpyYmL~lHnJqMb´Ϳ¬ʿŽſſ¨ìŮưǱƮɯʯŨʻkySlC|g<xe=|jFqPz]n}~}|lb[\\h|ȻãǪɭĩȮɭƪŨŦɾ{\\zQsHuI{M}OgƻˮͲ˲ɳʵɶϼͺ˸̶͵ʹʰɬžtjgflv¸ȾĩŪƫŪgu[sYz_nĮǱɶɸȷŷƸȹɸɵȵʵ̷˴Ȳƭūũ~qi~dmxãɬ˵˸ʷįŻĽȮγʹʱ˳̴˶̷˸˸ʸɷʸ̺ϽѿѿϽͺ˸ưíſýſĬɱ̴ϼϼннѾѾѾѾλλ̹̹̹̹ͺλͺͺͺͺͺλϼϼѾѾѾнннϼϼѿооϽϽμμμͻͻͻͻͻͻͻͻϽϽϽооѿѿѿоѿѿѿѿоϽμμμμμμμμμϽϽϽμμμμμϽϽϽϽϽоооμμϽϽϽоооооооооооооооооооϽнѾѾнλ̹̹̹ͺλλͺͺϼѾҿнϼ˸̹̹̹̹̹̹̹˵̷̸ʷînxcNt^Iq[DoYBmW?iU<iX<xgKz]w¹ú¹¹ǾĻzwy}Ĺ¥ɭ˱˲˴ιлϼѽкŮql^DhX>k[AhX?`P7_O8scLq}rheegjw·Ƚůɵʸ̺̻ɸʷ̹ɶì}`xgIkZ<kX:kX:hU7yhJ~bĪɰ˵̶ȵʶȳɴɴɴʵʵ˶˶̷͸ιϺϺϺιϷϱв̱ľjraOcP?cN=cN;iS>}gPn}^xoDl`6pd<rd?k[9q^>}lNw[rƺȯ̵δгбί̭ˬˬ˭̮ɬŨƩˮ˯ʿ|`yXsTrSwZf~~fvS|nIqJvMyTj|ƺƮ͵εʱǱȲʳ˴ʵʵ˵˸н˸ʷɴĮpmRnZ?o[@lX=n]CnTkīʳͶ˴ʳ̵ηͶʳʳʳʳʳʳʳʳ˶ɴηϸʱ˰ǭźz[zjIqa?tb>zhDmIeṵ̈ѵдϳϳβ˯ʮɭʮ˯˯ɭǪhyU{mJvhEzgF}jIwZv´Ƭʲ˴̷ͷ̸˷ʴʴɲȱȯȮƪʭαϲͱ̰˯̰Ͳеͳū˿}|a{lMqa@m\\>wfHyZqçͲеж̲˳͵ϷϷѸ̱{ftS{kJrQ}mLrQf¥ɭͳʹ˲˲˳̴̴̴̵̵ͶͶͷ̶ʴɳ˲ȯǮǮĮïɵɵɵɷʸʸʸ˹ʷƱ̼t{]oNnJpLnM_|Ϳʿªè¨¨«¬¬ƮʰɯĴ~csKlA}h={h@pJ}\\n¹úƻĹsk\\bn~ķ;ħĩȮȬƪŨäƻ{]{RtIuIzL{MdĻʫϲͳ̵͸̷Ѿλͷ̶ʹʹ˰ʭ¤ĽĻĹ|oprv|ʿũǫʿqcu\\y`můưȴʷʸȶƵĶŶ̷̷̹͸̸ʴưī¨éæ»|mnt|ÿŨ˵˸˺ɶ¬ƽø·ĺȮ̲γ˲ȯ̴͵͸͸̹̹ʺɹ̺μоѿоͻʷǴľýľªȰ̴λϼнѾҿѾѾнͺͺͺͺͺͺλλͺͺλϼϼϼϼϼѾѾнннϼϼϼоϽϽϽϽμμμͻͻͻͻͻͻͻͻоооооѿѿѿооѿѿооϽμμμμμμμμμμμμμμμμμϽϽϽϽϽϽϽϽμμμϽϽϽооооооооооооооооооϽϼнϼλͺ̹̹ͺλϼϼλλϼѾѾϼλ˸˸˸˸̹̹̹̹ʵʶɶȵϾ~it^IlVAmWBnXCjV>hV>rbIy`rƽȿǾĻĹãŻyth|]}tUuUyY`o~ɾɮ˱ɳ˵лҽϼҾкįrl^DxhN~nTzjQk[BeU>xhQyȽĹ{rie_iyƺêȲɷ˹˺ɸɸʹǵ|_veGiX:hU7hU7dQ3udFz^ū˲ͷθɶ̸ȳȳȳȳȳȳȳȳ̷͸ϺллϺ͸ζϱа˭~r\\iXFaN=cN=dO<kTBxbKy`punYwIznDsIpIsc?o\\;r_?|iK{_yĸȮͶеαϰ̭ͮˬˬʬʬɬƩǪ̯ǫs|[xVwV{\\gvϿɺx^wPvLvKuN~as̴зεǱȲʳʳȳȳʴ˸нʷɸʵıpqVr^Cs_Dp\\AraGrXnīʳηʳȱʳ̵˴˴˴˴̵̵̵ͶͶʵɴйһ̳ͲȮź~_}mLscBvcB{iEmIdĽͱҶѵддϳ˯ɭȬɭʮ˯ʮȫŽp[~pMykH|iH}jIz]sɳ˴˶ͷκ͹̶̶˴ʳǮūũʭϲҵѵϳϳϳͲѶ̲n~pUwhItdCxgIxZqƸǫ̱̱δͳζζζζз̳¨·r}\\qOqO{kI{mJ}[pĪɰʹ϶͵˳ʲʲйϸϸѺѻкθ˵ʱǮƭƭíïȴűƲǵɷʸ˹˹ɶƱ̼t{]oNmLpLmL~]y˽˿îĬĩ¨ʿǰʯǪʻs\\rJk@j?lCzTkºŽƿĽýżýyifgoyǹèȮɭǪŨø}]}TwJvJzL{JbúɪίβδηϹѾмͷ̶ʹ̳ʮȬŨå¦¥ɾŷ~ȽĨçvj~c|em~·«ưȱʵ˶˸̹ʸɷƷŴɵɴʵ˶˷˷Ȳư¬īǮȭŨ||¾Ħʲ˹˼ʹƲĩååŪȮ˱ͳγ̱ʱȯʲ˳͸ϺϼϼξͽͻμϽμ̺ǵ¯ſĬɱ͵ͺλнѾѾѾнϼͺͺͺλλλλλͺλϼннннϼннннϼϼϼλϽϽϽμμμμμμμμμμμμμоооооооооооооϽμμμμμμμμμμ̺̺̺ͻͻͻμμϽϽμμμͻͻͻͻμμμϽϽϽϽϽϽооооѿѿϽϽϽϽϽϽϽϽϽλλͺ̹˸˸̹λϼѾнϼλϼннλ̹ʷʷʷ˸˸̹̹̹ʶ̶˶ȴѿzhqWFjP?lUCmVDiT?lZDqZy¶ǻ¦ǫȪŧ¤ǥġ˿ƺ|l{[vkKtgEviGrPczʿ̱ͳɳ˵лѾѾλѽкîrl^DqX|c|c{kRo_HoX~ũƧĥǾvl^`grùʿƴʸ˺˼̽;ȹ}`wfHiX:hU7gT6cP2tcE~bƬʱ˵ͷʷϻʵʵɴȳȳǲǲƱ̷͸ϺллϺ͸͵ͮ˫ĦqqbM`O=^K<aL;gP>lUCr\\E|hOvX}_\\YX^bZnJs_>n[;taC{jNx^sžȱ˰̯̭ͮͮͮˬȪȪƩħŨȫʿxi|[xVzYgyȺȭ¥ʽp]~UyNtMuXgxĬ̳̳Ȳʴ̵˴ȳȳʵ̹ϼʷʹ˶ŲªpsXt`EuaFq]BsbHsYpêʳηʳƯǰʳʳ̵̵̵ͶͶηηη˶ʵѼһ̳ͲʰɾdqPwgFxeD|iHmIdžβӷѵѵѵд˯ɭǫȬɭʮʮɬzdwT~pM~kJ}jIy\\k÷ů̵ιϼϻ͹˸̶˴ɲĮ¨Ĩɬϲҵѵϳͱͱ̱еʰĸy{aseJvgHyiHtVnǺèɭʯʯ̲ϵѹиζ͵θʹǭôk~\\qO|lHzlGuR`pêεҹ϶̳ʲ̴͵͵̵ϸѻҼϹ̶ȲůĮůíİʶűƲɷ˹̺˹ɹǶŰʺsy[nMlKoKmL{ZuɺʾƱëèǿǿʿŮǬ{h{VpHk>nAvMb}ŹƻŽǿª¨ƭ¬ŨȪĢ|pfdip}Ż¨ƪǪǪģƻ~^VxKwK{M|KcûɨίͱδζζкϹθϸ϶ʹʮǫǫŨé¦μ˹ŷ´´Ķɻ̾Ⱥxss{ʴ˷ʵι͸ͺͺ̺˹ǶŴƲůůưɳɳȴǱĮƭǮ˯ʯǩÿüþÞȪɱʸ˻ʻȶȯɭʮʹͶͶ̴̳˲˲̲˱͵ϺѼѾѾϿ;μͻ̺ɷĲƿ¼ľ¬ªĬɱ͵˸ͺϼнѾнϼͺ̹ͺͺλϼϼϼϼͺλнѾѾѾнϼнннϼϼϼλλμμμμμμμμμμμμμμμμоооϽϽϽϽϽϽооооϽμͻμμμμμμμμʸ˹˹˹̺̺ͻͻμμͻͻ̺̺̺˹ͻͻμμμϽϽϽϽϽϽооѿѿѿϽϽϽϽϽϽϽϽμͺͺ̹˸˸˸̹λнҿѾнϼϼннλ˸ʷʷʷ˸˸̷̹̹̹θϹ͸ygoUDlRArXGpYGkVCq_K|eŹɿ§ɬͰϲαʮɫƨťƣȤȢĞȼ}e|qQtjGtjG}sPh¦ϴϵʲ˵ϻҽнιѽкpn^ErYimv]yiRw`γдѴͰäx_]Z_mëȲ˷̺ξϿʼĲbxgKjY=gV:fU7bQ3udFgǭȯɲ˵˸ѽͷ̶̶˵ɳȲǱǱ̷͸ϺйлϸͶ̲ɪƧ~egXAYH4\\I8_J7fQ>kVAlX@p\\CyeJnPrQ`m{{ivTxeEp]=o\\>o^BudHv\\zĪʭ̮̯ͯˮʫǩƨ¥ƿä·k_~]yVzYnŷ¨ȮūũƸk^~TtM{lMw\\k{ǻūǬʱ̳ʹ̵ɲȳ˶͸κʶ̶̵Ǳ¨nsWs`BtaCp\\AraErXn©ʳͶɲŮƯȱɲʳ˴˴̵̵ͶͶͶ͸̷ѼѺɳͲͳ§gtSyiGyfE|jFmIcžδӷҸѵѷд˱ɭǭǫɯʮʰɬl~\\tS~nLzjHrT`yĪγҹԽϷ͵˵˳ʳɯ«žǭ̲ϵδ˱ɭȬ̯гȬk~sUk`BuhH|mL`|ķŨ˯˰ɮȯ̲йӽѻθ̷Ѻ϶̱ɭͿyiuSoK|lHqLxS^lzþͳԷж̯˱ͱǭƪȮ˰зѶε˲ʱǮƭǮŬêů˵Ǳɳ˷͹͹˷ɵǳĬȺqxZlL}jIlKmLyYvƺȽ­ȳ¥¨Ǹp`vRmGnCtIZsɾêʿ«Ĭé¦¥ťŨƮ¬Ũˮ̬ĠŻyg^^cq¹ƧȪȨŸ}`VxOxM~Q|Pgúʫαͱͳ͵̴θθϹкҹ϶ʱƭīīǿŭŮĭƬéʾʾʿźźöʿȵͺ͹ʵϺϺͺͺ̺ʸƵŲŲůíĮůưűİĮĮƭʱʹͱȭæ£ƻĺĠßǧͰȲɷ˻˹ʷɳ̱Ͳϸη͵˳ʱʱʹ϶϶йһҾѽϽ̺ʹͺ̹ɶŲƿſªƮʲ˵̹λннϼλ̹̹̹λϼϼϼϼϼͺϼнѾҿѾнннннϼϼλλλμμμμμμμμμμμμμμμμϽϽϽϽϽϽϽϽϽооооϽμͻμμμμμμμμɷʸʸ˹˹̺̺̺ͻͻͻ̺̺˹˹ʸͻͻͻμμϽϽϽϽϽϽооѿѿѿϽϽϽϽϽϽϽϽμλλ˸˸˸̹̹̹ͺͺλͺ̹ͺλλ̹ʷƳǴȵʷ̹λϼѽηϹտϻ˼{ijP?tYFfM9mWBmXCgU?hĵǽũƨɬ̯δηͶ̵ʳ̲̳ͲͰ̭˪ʩ{nksʭ̱дϵͳ˳̴θѼ͸ϻιĬqm\\BpVf|bx^seK~dĽδҸԺҸ˱¶vj`_afnz˾ɮȰǱɸǷ̿w_vdLm\\BkZ@hY<dV9ykNiƫɯʳθλϹθͷ̶̶̶ʹεҺζ̴ͳижͳɭ˫ǧnynRl^CdV<^N5`P7aO7`N6aO7gU=veKw]j|svYsdGj[>n]Ao^BudH{_Ŵ̾ɯεϴ̲ɯɬǪƩĥȽ·q`}Z|Ybo¬ǲįŽŽŻvc~YvStSyXdtĶǩͱͲͲʹ˵˵ʴ˴Ѹʱʯˮƫ`}mLtdCp]=q^@q`B}lPnêĭƯǰȱɲɲɲʳ˴̵̵ηηϸйϹкιʳɳ̱Ȯèn|ZmI{gD~jElG`Ľ̵ҸйжϸϵǰȮȱɯǰȮƯƬǪʿl|\\pO{lKsOzVhŶȨΰίɬũũɬɬĪǴʷʸǳǳ˵ʹˮ̭âj{V{sL|tO~vRbzƽǪͲҸδηϺлнϼ̻̹Ͷ˱ɭǬƩǼl~\\tPtPtPuQ\\m~ƽȧͮέбұˬʩʫʪ˭̬ΰϱˮȭŪè§èɿŪǬȭȭƫũŨqwX}lNmMoPmN}_xŻ«ŭūƿãäĥĥä£ƧǼzb|rOwmJzpMzpM\\rç¨çĨĨũǫǩťáǺoa^cköǺáʨze{VyT{VXf{ƿȮ̵Ͷ˴˶˶˶ͷϹϹͷʴưíưưůůŰǲȳɴ˶˶˶ʵȳƯĭìĽ»±ðĲǵ˹нϼϼѾоϽ̺ʸȵƳůſſĮǱǱǱȲʴ˵˲ǯĬĭƯɯ˱˱ʰɱǱȵɶʸ̹̹͸͸̷ʴʴɳʴʴ̶ͷθϹθͷ˵˵˸̹θ̴ζζɱª¨ĪƬȮɱ̶˸̹λλλλλɶ˸λѾѾнλ̹̺ͻоѿоϽϽϽϽϽϽϽϽμμμμμμμμϽϽϽμμͻͻͻμμμμμμμμϽϽϽμμͻͻͻμμμͻͻ̺̺̺̺̺˹ʸʸʸ˹˹̺̺̺̺̺̺̺̺̺ͻϽооϽͻ̺ͻͻμϽϽоѿѿμμμμμμμμμͺλ˸˸̹̹̹ͺͺͺλͺ̹ͺλλ̹ʷǴǴɶʷ̹ͺϼмѹиѻ̷ȹygfL;nS@bI5jT?kVAdR:|b¸¤ŦǪ˰ζкϼλʷ˸̷Ͷδ̰˯ʭ¥ýžʮͱϳδ̲˱̲ζй͸Ϲηëpn]ClQz^sYqVn`F~cý͵ε϶ζ˴ȱ¬˿zmd_Y[czɼ̾Ʊó˻r\\q_GhV>gW=fX=cU8ujLhǫȮ˳ͷͺҾкйϸϸηη϶϶з϶ͳϵжϵ˯ȫǩź}{[qcFi[>cU:\\N3^N4]M3^N5bR9m]DoViuɿȾh~pUm]Cl\\Bm\\@p_CnPj̻ū̳ζʰƬǪȫɩäżxh[Y]j|ƼǲȵĲƿǿüpczUvQvS}ZftǺŧɭ̱Ͳ̳ʴ˵Ͷӷ̰ˮ˭Ǫ_}mKscAn[;l\\;o^@|kMnīŮǰȱʳ˴˴˴ʳʳ˴̵̵ͶͶηϹкι˴˲̱Ȯ¥n~\\nJ}iDmHnGcļ̵йϸϸϸηǰǰǰǰǰƯŮƬǭ¦øzfwW~qOrJuM[nɼƣʪɨȫȫʭɬƩéðŵǷǵʶͷʹɬäo]zPzP}Vfuæʭδѷηηϼϼͼ̻˼˺Ϸ̲ɯɭǬ¥øna[zVtOxS`q|ŻǤ̩Э̩̩ͪΫϬЭЭϯȩŨĻżæǪǪƩħƧszZoQoQpSqTc~ȾĪƭŪƿ¡âģâ¡p}\\vmLtkJypO~xXi¥ũç¨¨éêĪé§èƫǬǪǧãʽ~ofder~̽ȥâŷ}k_^bfuȾįʵ͸͸˶˶˶˶͸ιι̷ɴŰîðıŲǴȵȵǴǴʸʸʸɶȵǴưưſſľýľŨǭǴȶɷȶǵȶʸ̺ͻμϽоϽ̺ʸȵƳů¬íưȲʴɳɳ˵̶̶ʴǱǴȵʷ̹̹˸ʷɶɶʷʷ˸˸˸˸˸ʴ˵˵˵̶̶̶̶θͷͷͷͷͷθϷζϵϵ˱Ƭ¨é¨¨¨éūǭɱ˵˸̹ͺλλλλʷ̹ϼѾҿнλͺ̺ͻоѿоϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμͻͻͻμμμμμμμμϽϽϽμμͻͻͻμμμͻͻ̺̺̺̺˹˹ʸ˹˹̺̺ͻͻͻͻͻͻͻͻͻͻϽϽϽϽͻͻͻͻμϽϽоѿѿμμμμμμμμμ̹ͺ̹̹̹ͺͺͺλλϼͺͺͺλλ̹ʷǴȵɶʷ̹ͺλмԽϸϹʵƺ{hcL:gN:`G3hR=jU@dR:u[ƿæƬ˱ζкϼϽʹ̹͸ηδͱ˯ʭʭȫħžũʮ˱̲ͳ̵ʳʳ˴͵ϸ̷Ϲηªon]CxdInRudJqcHgY?}bſζ̳ɱ˳Ͷϸͷ˵̾ti\\~V}UixĴννǶoYn\\DeS;gW=i[@fX;vkMgǫɯ˳̶̹ѽѻѺйϸϸϸ϶з˱̲ϵждβ˯ȫħgseHgY<eW:aS8[M2\\N3\\N3`R8k]C}oUkùƫƫȾzeueKo_El[?n]AuaFrWzǷ˰δɯéŨȫʪävi^\\_fwǾǮ̷ʷĲĲ¯¨Ƚrb~YwQvPzWdyøɮͲ̳˲ʹжӷͱ̯̮Ʃȿ^oNueDm]<l\\;p_A~oPqīŮǰɲ˴̵ͶͶ˴˴˴˴˴˴̵̵Ϲкη˴˲̱ǭo]pL~lFpJqLfû˴ϸηηηηȱȱȱǰǰǰƯƯȰū˿vf{[ySwQ{U_nzĺģǪȫǪƩŨĪįƴȶȴ˷˵ƭȿl`\\\\eqƦˮͰδδϸηͺͺ˺˺˺̹кγʰʭʮȫħɾvnd{WxT}Yeo|øǧťƦȨʪʪʪɩɩĥȿƽħƩŨæǩäv}]rTqSqTsVfƬƭĪ£äää£ȿyg~uVulMxoPwXi{žħƪũĨĨéé«ìĭīɯǫĨĨǫʮ˭˭˭Ȩ¢yplr|ǺƤťɼvnmtxǮʵ͸ι̷˶˶˶̷͸ιι̷ɴƱį¯ıƳɶɶɶǴƳʷɶɶʴɳɳȲȲŭŭƮǭɯ̲δи˸ͻμμ̺ʸ˹̺ͻͻμϽμ̺ʸɶǴưí¬íůȲ˵ͷ̶˵̶ͷθͷ˵ɶ˸̹λλͺ̹˸ʷʷʷʷɶɶɶɶ˵̶ͷθͷ̶˵ʴɳʴ˵̶ͷͷͷ͵̴̲˱ɯǭƬȮʰǭūéĪǭɱʴʷ̹ͺλλλλ̹ͺнѾҿѾϼͺ̺ͻϽѿѿѿоϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμͻͻͻμμμμμμμμϽϽμμμμͻͻμμμͻͻ̺̺̺˹˹˹˹˹̺μμμμμμμμμμͻμμϽϽμμͻͻͻμϽϽоѿѿμμμμμμμμμ̹ͺͺͺͺͺλλλϼϼλͺͺλλ˸ɶȵȵɶʷ̹ͺλϻֿйк͸nhQ?dK7^H3gQ<kVAgU=~pV~Ʃʰζкϼμμ̻̻λϺηͳ˱ʮɭʭʮɭȬɭ˯δ̲˴˴ʳʳʳ˶ͷι̷кηnm\\BnZ?raEeT:eW<aS9}béҺεɱʲϸѺθ˵Ȩùob[_eluĳ}nXo]EfT<iY?n`Ek]@zoQiɭ˱̴θ̹ѽкйϸηηηε϶ʰ̲δϵϳͱ˯ʭ̾~pSfX;aS6bT7_Q6ZL1^P5bT9l^D}qWo¶ūǬǬŪŻvtZueKm\\@o^Br^CzfKkü˰ѷˮæĦǧȦȿvg][aitȽɬδ͸˸ƴȶð¨æȽvgYwQtQ{Xizħ˰˰ʱʹҸԸβͲ̯Ũƽ]sRyiHqa@m^=rcDuVwêĭƯɲʳ̵ͶͶͶͶ̵̵̵̵̵̵θкϸ̵˲̱ǭp^qOnJrLtOiûʳηͶͶηη˴ʳɲɲȱȱȱȱǮǯƮ÷{na\\Z`grżæŨħ¥ħūǲȴȴưůêqedmyý¢ɩήгϳδ̲Ͷ̵˶˸ʹ̻ͼϼҼ϶̳ʰ˱˯ʮɬƻvg`aagnu}ƻǼʿʿȽú~ywv{ƽŨȫŨæɫĥzcwXsUrTrUg©ȰǱŭŨŦŦĥ£ȿżúqbvW|sT{\\g~ĽæħħũũȬǫƬūĭŮƯȮɮȫũǪȬ̯˯̯ʮ̯ʮƩɾʼťħʿõʿʴ˶̷̷˶˶̷͸̷͸ι͸̷ʵǲŰıŲƳǴȵȵȵȵɶʴɳɳɳʴʴ˵˳˳˳̴ζζ͵̶ʷ̺ϽоϽͻͻμ̺̺ͻͻͻ̺˹˸ǴǱůĮůǱʴ̶Ϲͷ˵̶ͷϹϹθʷ˸ͺλλλͺͺ̹˸ʷɶȵǴǴǴ̶ͷϹϹθ̶ɳǱĮưȲʴ˵˵ʴʴŭĪé¨éƬʰͳʰǭĪ¨ƬȰʴɶ˸̹λλλλͺλнѾѾнϼλ̺ͻϽоѿѿѿоϽϽϽϽϽϽϽϽооооооооϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμμμμͻͻ̺̺̺˹˹˹˹̺μϽоϽϽϽϽϽϽϽϽμμμμμμμμμμμϽϽоооϽϽϽϽϽϽϽϽϽ̹ͺͺλλλϼϼϼϼнλͺλλͺ˸ɶȵɶɶʷ̹ͺͺϻһηклư³wq\\IdN9`J5dN9iT?hV>vhNnžū̵ѺѼϼ̻˺ͼνϼлϸδ̲ʰʰ˯̲˱˱̲δйͶ˶ʵʵʵ˶̹̹ι͸ѻη˿kkZ@eQ6hW;\\K1^P5^P6~cȮи̴ʲ͵йһηɲˬˬȩ¡¹xk_}[yZ|_l~s{iSo]EfT<iY?oaFn`C}rTk˯ͳϷкλҾθηͶ̵̳̳ʹʹʰ˱̰ͱͱ˯ȬƩlraEaR5`P6`P6^P5]O4eY?maG~rXoɿ©ĪƬƬȮʯƫl~nTp_EsbHtcGtcGw\\{ƩѴʬ¥ãĤ~i^Z_iuƨ˰̷̲˸ʷʷðŽž£ƻwfZwTwT`lzżǪʭ˯βҸҷβγ̯æĻ~^sR{lKrcDpaBwhK|_©ìŮǰɲʳ˴˴ηηηηηηͶͶ͸лϸͶ̳̱Ƭo^rO~nJtPvRlļʳηͶͶϸϸͶͶ˴ʳʳʳ˴˴ůưɳʱŭŹrlhjknt~»ž½ſé¬¬ɿŻvopyȿǦȨʪ̯ϲддͳ˱˴ʳʵ˶̹ϼпӽѺη̳̳˱˱˯Ĩȿø{snijkmqw~}yxyzȭɮƫĨƩ{fz]vXsUtYiêɱɳȰɭȫǪħżqgbdp{ĽɬˮǫĨĨ¦ǭƬĭììĭƯɯƪƩǪɬʯ̰ɮȬƫȬȭɭȭƪɿƽ£çǨũäɾ¹øƽ¦Ǭʳɴȳȳʵ̷͸ι͸͸͸͸̷ʵȳǲȵǴŲıŲǴʷ̹˵ʲɱɱɱʲ˵̶θͷ̶ͷϹϹ̶ȵʸͻϽоμ̺̺̺˹˹̺̺̺̺̺̹ɶɳǱưǱɳ˵̶θ̶ʴ˵ͷϹϹθʷ˸˸̹̹̹̹̹ͺ̹ʷȵǴǴǴǴ̶ͷϹϹθ˵ȲǱůưȲʴ˵˵ʴʴľľƮʲ͵̴ɱŭªŭǯɳɶʷ̹ͺλλλλϼнннϼλͺ̺ͻμϽооооϽϽϽϽϽϽϽϽооооооооϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμμμμͻͻ̺̺̺̺̺̺̺ͻϽоѿϽϽϽϽϽϽϽϽμμμμμμμμμμϽϽϽϽооϽϽϽϽϽϽϽϽϽͺλλλϼϼϼннннϼλλλͺʷȵɶɶʷ˸˸̹ͺκ̵ɲͷθưǸmZlWBdO:`K6bP:dT;k[BsYu»ǰлѼλ˺ʹνнѾлϺͶ˴˱ɯɯʰɯɯɲ̵ηϺ͸ʵʵ˸ͺͺͺϺιҼηɽhiX>aM2eT8[J0^P5^P6~cɯ̴˳˳ϷѺһη˳̯ϱв̬ƦĻoexYsTvZcinyasaKlZBdR:dT:k]Bk]@{pRlͱϵѹѻλѾͷͶ̵̵˲˲̳̱˱ʰʮ˯˯ƪĽxsXkW<bQ5cR8bR8eW<n`EznTy^qƬƬǭȮȮɯͲͲ¨¶dyiOwfLveIraE~jO}cɫƦ ľqa]`juʭɮȮʲ̹̹˸ůŽüȾæ¤ķwj`}Y\\co~ǪʭͱгѶʹγ̯æú_rQ|mLufGreE{mPg¶êĭŮǰȱɲɲɲηηϸϸϸϸϸϸ͸лйͶ̳̳ūʿo`rQpNuQyUnŽ˴ϸͶηйѺϸͶ̵ʳʳ˴̵Ͷůưɳ̶̶Ʈȼ~yyvruxĺŻǾæǪˮ˫˫ˮͰϳдδ̲ʳʳ˶̷λнҾһйη̶̳ʲʰʰǫçƽ{wwsvv{|}|}Ƽƫ˰˰ɮǫħĿohc~`esĸĮȱɳȰɭȫǪħĻxsswĽǪα̯ǫũĨ¦é¨ǿǿ«ŮȮĨƨƩʬ̰̯ɭƬƬŭĭƮȱʲɴȱȮɭȭȬǬȬƫƪŪçèȬɮ˱ɲǲƱǲʵ͸ιι͸͸͸͸̷˶ɴɴʷȵŲðıǴ˸λ̴˳ʲɱɱʲ̶ͷͷ˵ɶ˸нѾϽ̺μϽоμ˹ȶȶȶʸʸʸ˹̺̺ͻͺʷʴɳȲȲɳʴ˵̶˵ʴ˵θϹθͷʷʷʷ˸˸˸̹̹λ̹ʷȵǴǴȵɶ̶̶ͷͷ̶ʴȲǱȲɳʴ˵̶̶̶̶Ĭªŭɱ͵ζ˳ɱƮëªëŭƮǴȵʷ˸ͺλλϼλλϼϼλλͺ̹̺ͻͻμϽооѿϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμͻͻͻ̺̺̺̺̺̺̺̺ͻͻμμμμϽϽμμμͻͻ̺̺̺ͻͻͻͻμϽоѿϽϽϽϽϽϽϽϽϽμμͻͻμμϽϽϽϽϽϽϽϽϽоооооооооϼϼϼϼϼнннѾѾѾϼλλλͺʷȵɶɶʷ˸˸̹ͺκ˴ȱ˵˵ĮʾqygQlZD`N8aO9dT;bR9pbH}cźȴκ͹̺˹нѾѾѼлη̴˳Ưȱʳʳɲɴ˶̷Ѿλʷʷ˺ͼνμѼлԾηȼefU;bN3iX<`O5cU:`R8}bƬ̵̵ηϸѹиϷ϶̱ее̯ʭǪƿ{i{\\sUpRpRpU}kSlZDkYAcQ9`P6fX=hZ=ynPlͱжѹкͺнθεʹ̳̳̳˱̲˱ɭɭ̰̯z`wcJiU<hW=jY?jZ@xjPet~¨ǬȰɱʲ˳ʰʰδзɯ|{a~nTveKo^DtcI}mSqýľthaen{ǫˮǬǭʲ̹͹̸Ǳ¬ŨƪǩáȻrd`biuťʪ̯Ͱϴ̳γ̯¥ú`vVrRzmMzmMwZrɿǭƯǰȱɲɲȱȱ̵ͶͶηηϸйй͸лйηʹ̳ūɾpauSrQyV}Zsǿ̵ϸηϸѺһη̵ʳɲȱɲ˴̵ɵȴȴ˷κͷưȹµżȾùƼƫʯɮɮ̱̯ʭɭ˯ϳѵжδͶͶιллѼѾѾлѼҽӻйʹ̳˲˲ʰǭ¦žúüçɭͱͱ˯ʮǪħ}|y{ǱɲǱưūũũçĽçɭ̰ɭǫǫƬé¨ǿƾîǲɲȫȩǪȫˮ̯ʰʯɱưĮůȵ̸˸˵͵ͳͳ̲ʰǭƬƬƬƬƬǭʰͳͳ˴ʵȳƱǲ˶͸ι͸͸͸͸͸̷˶ʵʵȵǴƳŲƳȵ˸ͺδ̲ʰɯɱʲ˵ͷ˸ȵƴɷϽμϽϽϽ̺ɷȶȶʸɷɷʸʸ˹̺ͻλ˸˵ʴȲȲȲȲȲʴʴ˵ͷккϹͷ˸ʷʷʷ˸̹̹ͺλͺʷɶȵɶʷ˸˵˵˵ʴɳɳȲȲɳɳȲȲȲɳɳʴɱƮĬŭɱ̴ζζɱȰƮĬĬĬŭƮƳǴɶ˸ͺλλϼλλͺͺͺ̹̹˸ͻͻͻͻμϽоѿϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμͻͻͻ̺̺̺̺̺̺̺̺ͻͻͻμμϽϽϽμμμͻͻ̺̺̺ϽϽμμμϽϽоμμμμμμμμϽϽͻͻͻͻϽϽϽϽϽϽϽϽϽϽоооооооооϼнϼϼнннѾѾѾѾϼλλλͺʷǴɶʷʷ˸˸̹̹κ̶ʳ˵ʴŮí³v_weOdR<bP:eU<_O6gY?tZp®˷͹͹͹ѼѼҽѼлι̴˳ʳͶйѺлϺϺϺϼ˸ʷ̻ϾϾϽѼѼտηǻ~deT:eQ6m\\@fU;gY>aS9{`éѺһһйζ͵϶з˲϶εʯ˰гͱƩȿ~iwY}lNyfHxdIucKiWAlZBdR:_O5eW<gY<ynPk̰ϵик̹кϹ϶εʹʹͲ̲ͳʮȬɭͱ̯żl~mSp\\CjV=n]Cq`FtdJ|bƿǭʯʯ˲ʹ˳̴˱ɯ̲ϵ˲Ī̾qv\\wfLn]Cq`FxhN`zſ}ogen~ļğƨˮʯȮǯ˳ͷ̸˷ɳǯŭūƫȮ˭̪ƣɿpfgfqĤʪˮˮγ˲ε˱¦úazZxXtTtTc|ƫɯɲɲʳʳɲɲȱʳ˴̵̵ηηϸй͸лѺηʹ̳ĪɽsevVuU{Z~]vǿͶйϸйһӼ̵˴ȱǰƯǰɲʳͻɷǳʶκϻʷưʭƦƻ¹úŻħǪ¸¸ŻǽɿèʱѸѸʹεӺͱˮɭ˯ϳҶѷжϸйѼҽҽлϼλιлӾԿӼϸʹ̳ȯȯƬĪéħé¦ƽĻú¹¹ƿ»»žžƪʮ̰ͱ̰˯̯ʭʾȯ˴ɴŲí¨¦ç¦ƿü»žĨĨȬɭƪǫɭɯūĪéîǲ˶ζˮʫƩǪɬ̯Ͳʹ̶ɳǳȴ̹λλ͹Ҽѹѹи̴ƮĬŭëŭƮȰ̴ϷϷ̴̷ʵǲɴ̷ι͸˶ι͸͸̷̷˶˶ʵƳƳǴǴȵɶʷʷгα˱ɯȰɱ˵̶˸ǴĲǵ̼Ͽ̼̺̺̺˹ɷʸͻϽɷɷɷʸ˹̺μϼ̶̹ʴɳȲǱǱǱʴ˵̶ϹҼҼϹͷ̹˸˸˸˸̹ͺλλͺ˸ɶɶʷ˸ͺ˵ʴɳȲȲȲȲɳǱưĮííĮůư˳ȰƮǯʲ͵͵̴ȰǯƮƮŭŭŭůƳǴɶ˸ͺλλϼͺͺͺ̹̹˸˸ʷͻͻ̺ͻμϽоѿϽϽϽϽϽϽϽϽμμμμμμμμϽϽϽμμͻͻͻ̺̺̺̺̺̺̺̺ͻͻͻμμϽϽϽμμμͻͻ̺̺̺ооϽμμμϽϽμμμμμμμμоϽͻ̺̺ͻϽоϽϽϽϽϽϽϽϽоооооооооѾѾϼϼϼϼϼϼϼϼλ̹̹̹ͺͺ˸ɶ̹˸ʷɶɶɶʷ˷̶η˵Ȳȱưȼv{dwgPk[DdT;bR9gY?qcIvapíʴ˵˵ͷҼӼϸ̴͵̴ʲʳͶйѺѼллѼнѾҿнͼ˺̻μӾҽкͶ˿z`o^Dp\\AkZ>m\\BfX=gY?{`ϹϹϸ̵̴͵ҹֽҺѹиʹʹ̱˱̰ƫɾõiyZ~nMn]?q_G`N8gU=iW?eU;cU:eW:~sUoβ̲˳̶˸Ϲͷ϶δͳ˱ʰʰ˯ʮʮˮˮ¥qx\\l[Ap\\Ct`GwfLoWh}ĺɿĭȰɰɰ̳϶̳̳˳˳ʳ˱ʱʱƬ÷j~nTscIp_Eo_E~sUaqxjltÝɣɥʭɮɰ˱̴͵ϹѺ˴˵˳ʲʰȬƫƩ̬̩ǧ{vqyȪ˭̯ε϶Ѹδƪyjgfiwĺǫδ˴ʳ̵ηϸ̵ɲʳʳɲʳ˴ͶйѺҼθʴ˵εʹȭè~j__dp~Ⱦìʳϸййϸηʳʳʳʳɲȱǰǰ̹̹ͺͺ̸̺͹͹̰ͮ˯ʫɬȫǪŪƪƪũç¨èŨǪǪŪƫǬɮʹʹ̶ͷͷθθθдϳϵδδϵϵжѺѺѺййϸϺклѼҽӾһйͶ˴ʱʱɰȯɰʯʲ̲˯˯˯ʮɭǫƪũȬƪĨ¦¦ũȬʮʰȮū¨ſſſ¨Īǭʰ̲̲ͳ̲̲˱ɭǫŨç¤¤ũȮ̵̳ɴı¬Ĭéé¨ſ¨éūƬƬȬɭ˯̰˱ɯƯŮì«­Űȳ˳γΰ̮ͯͱβ϶зηηιϺλϼϾнκͷ̶ʴȲưůĮůưǱȲʴ˵̶̶͸̷̷˶˶̷̷͸͸ιιιι͸̷˶ȵȵȵȵȵȵȵȵ˱̴̴̴̲˳ʴɳ˸˹̼ͽ̿Ͽμͻ̺˹˹˹˹̺˹̺̺ͻͻ̺̺˸˸˵ʴɳɳɳɳɳ˵̶θϹкϹϹθ̹ͺͺλλͺͺ̹ɶʷʷ˸˸ʷʷɶʴʴʴʴɳȲǱưůĮí¬¬íůưȲɳ˵ͷθθͷͷ̶ʴưí¬íðıŲǴɶ˸̹ͺʷ˸˸̹̹ͺͺͺμμμϽϽоооϽϽϽϽϽϽϽϽоооооооооϽͻ̺̺ͻϽоͻͻͻͻͻͻ̺̺ϽμμͻͻμμϽ̺˹ʸɷɷ˹̺ͻоϽϽμμͻͻͻμμμμμμμμμμμμμμμμμμμϽϽооооѿѿѿѿоϽμоннλλλλλλλλλͺ̹ͺλͺʷȵɶɶȵȵȵȵɶʷ˵ηͷʴ˳˴íƺz{d|lUqaHjZAj\\BoaGrcLq\\rôé˱е̱Ѷӷδ˱˳ʲǯɲ̵ϸѺһҽӾͺϼнϼ̻˺˺μѼѼϹ̵˿{aq`Fo[@l[?o^Dk]Bn`FgĪθϹϸηζϷԻֽӻҺѹηεʹ̴̲ͳŪpa{lMr`HaO9hV>jX@gW=dV;eW:}rTrϳδζθ̹к϶϶δͳ˱˱˯̰ʮɭȫæeynRqaGudJ}lRx^p÷ŻĬƮǮɰ̳϶̳̳˳˳ʳʳʱʱʲʾ{eoUwfLqaGvkM}tU_ltxwvz} ʦͩάʭɰ˱˱̴εϸй˴˴˲ɱȮǭīĩ̮̮ʬŧȿĦʬϱгзϹζ˱īú¦ʰɲȱȱ˴ηйη̵ʳʳʳʳ˴ͶйѺҼθ˵˵϶εʯŪ·{tuxƯ̵йѺйϸηʳʳʳʳʳɲȱǰ̷̹ͺͺ̺ͻ͹͹γϲͲͰʯɮȭȭ˯ʮɭȬǭūĪĪĩǪɬɬǬǬɮ˰ʹʹ̶ͷͷθκθжϳϵδδϵϵжѺѺйййϸϺкйҺҽӼһйη̵˲ʱɰɰɰʱ̳ʹ̲̰ͱ̰̰ʮɭȬͱ˯ɭȬȬʮͱϳ̲ʰǭū¨¨¨ĪūȮʰ̲̲̲̲̲˱ʰɭǬǪǪǨũȭ˲ʹ̷ɴŲĮƮƬūĪé¨¨éūƬǭǭȮɭ˯˯˱ɯƯŮì«­įǲʲͲͯͯͯͱβε϶ηηιϺϺλϼϼκͷ̶ʴȲǱůůưưǱɳʴ˵̶ͷ͸̷̷˶˶̷̷͸͸ιιιι͸̷˶ȵȵȵȵȵȵȵȵ˳̴̴̴̶˵ʴȵ˹˹̼ͽ̿Ͽμͻ̺˹˹˹˹̺̺̺ͻͻͻͻ̺̹ʷ˵ʴɳȲȲɳɳ˵̶θϹкϹθθ̹̹ͺλλͺ̹̹ʷʷ˸˸˸˸ʷʷʴ˵˵ʴʴɳǱǱưůůĮĮůǱȲȲʴ˵ͷθθͷͷ̶˵ȲůíííĮıŲƳǴɶ˸̹ͺ˸̹̹̹ͺͺλλμμμϽϽϽооϽϽϽϽϽϽϽϽооооооооϽϽͻͻͻͻϽϽϽϽϽϽϽϽϽϽϽμμͻͻμμϽͻ̺ʸɷʸ˹̺ͻϽμμμͻͻ̺̺μμμμμμμμμμμμμμμμμμμϽϽооооооооϽμμμϼϼͺͺͺͺͺͺͺͺλͺͺͺλͺʷǴƳƳƳƳǴȵɶʷʴͷϹͷ͵η˵Ǳqx_zjQscJrbIp`IxhQw`qȽĨȫͰгβͰͳ˱Ȯǭʰͳδͳ̵ηϸʵ̷ιιͺ̹ͺλϺϺθ˴ɽ|bsbHo[@kZ>o^Dm_DseKmȮͷθѺѺҺҺռ׾ԺӹѺйϸϸθζϸʱ˰ƪ·ybwgNdR<iW?iW?fV<dV;eW:}rTvϳϵикͺкϷδͳ̲̰̰ͱͱ̯ʭænvXtiMxhN~nUzatǻ˿ǼǿªëůȲ̶Ϲ˵˵˵˵˳˳ʳʱ˳ŭȺ|hpWvfLujLxmO}rTz\\eow|ǧ˨̬ͪʯɳʳ˴͵εϸϸʳʳʱȰƯĭȭʭˮʭǪæž»üĽĿæǪ̯гӸѻϹ̴ɯŬ¥Ǽø»éƬƯŮǰʳηййϸ˴˴ʳʳ˴ͶйѺѻθʹεзз̱ȭżæǭʳηѺйϸηηʳʳ˴˴ʳʳɲȱͷͷ͸͸ιι͹κѷѵжϳδͳ̲̲ͳ̲̲˱ɯȮȮǭƫȭʯʯɰɰ˲ʹεεͷͷθθθθжжϵϵϵϵжжѺйййϸϸϸиѸѸѻҹҹзε̳˲ʱʱʱʱ˲̳ʹͳδδϵϵδͳͳжϵͳ̲̲δжҸϵͳʰǭūĪĪĪƬǭɯ˱̲̲˱ʰɲ˱̲̰̰̯̯ˮ˰ͱδδ̷ʵǴƳɳȰǯƮŭëªªëĬĬƮǯȰɱɯɯʰ˱˱˱ʰǰƯįî­­¯ıƳȲ˲˰̱ͲͲͲʹʹʹʹͷͷͷκκκͷͷ̶ʴɳǱưưǱǱȲɳʴ˵̶ͷ͸̷̷˶˶̷̷͸͸ιιιι͸̷˶ɶȵȵǴǴȵȵɶ̶̶̶̶˸ʷɶɶ˹˹̺ͻͽξϿϿμͻ̺˹˹˹˹̺ͻͻμμμμͻͺʷʴɳɳȲȲɳɳ̶ͷθϹкϹθͷ˸̹ͺͺͺͺ̹˸˸˸̹̹̹̹˸˸˵˵˵˵ʴɳǱǱưưưưưǱɳɳȵɶʷ̹̹̹̹̹ͺ˸ɶƳŲııŲƳǴǴȵɶ˸ͺλͺͺͺͺλλλλμμμμϽϽϽоϽϽϽϽϽϽϽϽооооооооϽμμͻͻμμϽоѿѿѿѿѿѿѿϽμμͻͻμμϽͻ̺˹ʸʸ˹̺ͻͻͻͻͻ̺̺̺̺μμμμμμμμμμμμμμμμμμμμϽϽϽϽϽϽϽоϽμͻͻ̺ϼϼλλλλλλλλϼλλλλ̹ȵŲðııŲǴɶ˸̶̹θкϹϷϷйϹзƮŶ{it[|lSygO{iQnVy_n|úȨȫʬαϲͰʰ˯̲˱Ȯǭǭǰȱʵ͸Ϻιιϼнιιͷɲƺx^p_Ep\\AjY=kZ@j\\ArdJnȮ˵θӼԽսս־ؿռԻӺѺййϹϹкɲͳβƩtw^o]Gm[CjX@eU;eW<hZ=vX|¹ͱδѹк̹киδͳ̲ͱͱͱ̰ʭŨ¹r~`~sUzoQu[gyõɽĮȲͷк̶̶̶̶̴̴˴˴ʱǯ¨Ƹygt[x]y[z^~`lwŨǩǩȪˮ̲˴̵͵εεηηʳʳɰȯƮìʿ©īƭȯɰȯǭƬɯȮǭȫɯ̯ϴекκ˵ʲɰɮȬƨääħƩƩŪŪƮƯȱʳͶηϸϸ̵˴˴˴̵ͶϸѺϹθε϶ѸѸγ̱ɮŪæ¥ħǪ̯ϴʰ̵ϸйη̵̵̵ʳ˴˴˴˴˴ʳɲͷͷ͸͸ιϺκϻѺѷѷжϵδͳͳ˱˱ʰʰɯȮǭǭǮɮʱʱʱʱ̳ʹε϶θθθθθθѷжϵϵϵϵжѷйййϸϸϸηηиѶиѶϷ϶εʹ˲˲˲˲˲̳ʹʹͳδϵжжжжжϵδͳ̲̲δжѷжδ˱ɯǭƬūƬȮɯ˱̲̲̲˱ʰǰȱ˱ͳβϳααѵдϵͶ˶ʷȷɶʴɱȰǯŭĬëªƮƮǯȰɱʲʲ˳ʰʰ˱˱˱ʰǰǰŰįįîðıŲƱȰ˰̱γγγ̳̳ʹʹʹʹʹεεε̶̶˵ʴɳȲȲǱȲɳɳʴ˵̶ͷͷ͸̷̷˶˶̷̷͸͸ιιιι͸̷˶ɶɶǴǴǴǴɶɶ˸˸̹̹˹˸ʷɶ˹˹̺ͻͻμϿϽμͻ̺˹˹˹˹̺ͻμμϽϽμμͺ˸˵ʴʴʴʴ˵˵̶ͷϹккϹθͷ˸˸̹̹̹̹˸˸˸̹̹ͺͺ̹̹˸̶̶˵˵ʴȲǱưůůưưǱɳʴʴɶʷʷ˸̹̹̹̹λͺ˸ɶǴǴǴǴɶȵȵȵɶ˸ͺλλλλλλλλλͻͻμμμϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμμμμμμμоооѿѿѿѿϽμμͻͻμμϽμͻ̺ʸʸ˹̺ͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμμμμμμμμϽμμϽϽμμͻ̺ʸѾѾннннннннϼϼλϼϼ̹Ǵð¯¯ðŲȵ˸ͺλϹϹккϷζϷѺѸεȰʾtgoW~mS{jP~oRz[fqxþŧʫȪɭʭʮȬũĨũƬȮ˴ηѺѺѺѼӽιϺͷǰ}sYl[Ar^ChW;fU;dV;m_EkūͶйԽֿֿ־׿׿պպӺѻкмммϻɳ˳δ̯ʬ½mzhRq_GhV>cS9dV;k]@{]Ļʮ̲ϷθɶθиδͱͱββˮɬǾtbvXwYz\\pĬƭǮɰ«ǿîȳ͸ѻ̶Ͷ̶̶̶̶˴˴ɰɰƮõ~vwuvyĻçǫˮˮɬɬͰϵ̵̷͸θθͷʹδʰɰȲǱưĮ­¬Įưȱɲʳʳ̴͵͵ͳ϶ϴ϶϶ͷ̸̶͵϶ϴβ̰ʫʫʭʭˮ̯̱Ͳɱɲ˴̵̵̵̵ͶͶ̵̵˴̵ηϸѺз϶϶зѸз϶εͱββ̰̰βдд̵̲ηͶ˴ʳɲʳʳ˴̵̵̵̵˴˴͵͵ζϷϸййѺѻииϷϷζ͵͵ʳɲɲȱɯȮǭǭǮȯɳɳɳɳʴ̶Ϲθ϶϶϶϶϶϶ййϸηηϸййѷѷжжжϵϵϵϵгϵϲδͳ̲˱ʰʰ˱̲̲̲ʹʹ̴͵ζиииииζζ͵͵͵ζиии϶̳ɰǮƭƭƭ˲̳ʹεεʹ̳ʲǰȱʰ̲αϲввԷҵϵ͵ʵʷɸʷɳɳȲǱůĮííȲȲɳʴʴ˵˵̴˱˱˱˱ʳɲȳȳŰŰŲŲŲƳƳƱȰɱ˳̴͵̴˱ʰ̲̲̲̲̲˱˱˱˴˴ʳʳɲȱȱȱɲɲɲʳ˴˴̵̵͸̷̷˶˶̷̷͸͸ιιιι͸̷˶ʷɶǴƳƳǴɶʷ˹̺̺̺̼˹ʸɷ˹˹̹ͺͺλϽϽμͻ̺˹˹˹˹̺ͻμμϽϽμμͺ˸̶˵˵˵̶̶ͷͷθϹккϹͷ̶ʷʷ˸˸˸˸ʷʷ˸̹̹ͺͺ̹̹˸˵˵˵ʴɳǱůĮííůưȲɳʴʴ˸˸ʷ˸˸˸̹̹λλ̹˸ʷɶɶɶ˸ʷȵȵȵʷ̹λλλλλλλλλͻͻͻμμμϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμμμμμμμμμμϽϽооѿѿϽμμͻͻμμϽϽμ̺˹ʸ˹̺ͻ̺̺̺̺̺̺̺̺μμμμμμμμμμμμμμμμμμμμμμμͻμμϽϽμμͻ̺ʸѾѾѾѾѾѾѾѾѾѾнϼϼнϼ˸Ƴ¯ƿ¯Ųȵ˸ϼнҼϹθѻи͵͵Ϸ̲϶ζɱ¨Ƹqfx]tVyX]aanv¿ĽƿƿƿžžçȮ̲жһһѺһӻϸϺθƯzqWkZ@r^CgV:dS9cU:oaGnéηѺԽվվԽ־׿ֹոӸҹкмннѽʶ̶зγѳȩs}kUp^FfT<aQ7dV;l^A}_ȿȬɯ͵˵Ǵͷиδͱβϳͱȫæyi|^{]emèͲ˲ȯʱεĭ«Ʊ˶ιлͷηͷͷͷͷ̵̵˲˲ɱƮǹ÷ȾèɭʰʰɯɯʰεѸ͸͸ϹкϹηͳ̲˱˱ʳɳȲǱŰįűűƴǳɶ˶̷̹θϹкѹӺҹзϹ˷̸ͷикѶͳ̰ˬʫɬʬʭͯϳϴ˳̵ηη̵˴˴̵ηͶ̵̵̵ηϸй϶϶ззз϶εεͱѵҶβ̰ββͱ̵ͶͶ̵ɲȱɲʳ˴˴̵ͶͶͶͶ̵͵͵ζϷϸйѺѺккϷϷζζ͵͵˴˴˴ʳ˱ʰʰʰưȲʶʴɳɳ˵ͷϹϹзз϶϶϶϶ййϸϸϸϸййжжжжϵϵϵβββͱ̰˯˯ʰʰʰ˱̲ͳͳͳεʹ͵͵ϷиииииϷϷϷϷϷиѹѹѸ϶̳ɰǮƭƭƭ˲̳ε϶϶εʹ̳ɲɲʰʰ̯ͰϱвҵѴ͵˳ɶɶɸʸǴȲȲǱưůůůʴʴʴ˵˵̶̶̶˴̲˱˱ɲɲɴɴƱƱǴǴȵȵȵɶɳɱʲ˳˳˳˱˱̲Ͱ̯̮̮˭˭ˮ˱ʳʳʳʳɲɲɲʳʳʳ˴˴̵̵̵͸̷̷˶˶̷̷͸͸ιιιι͸̷˶˸ɶǴŲŲǴɶ˸˾̼̿ͽ̼˻ʺʸ˹˹̹ͺͺλϼϼμͻ̺˹˹˹˹̺ͻͻμμμμͻͺ˸˵˵˵˵̶ͷͷͷθϹкϹθͷ̶ɶɶʷ˸˸ʷɶɶ˸˸̹̹̹̹˸˸ʴʴʴɳǱůĮííůǱɳʴ˵˵̹˸˸ʷʷ˸̹̹λλͺ̹˸˸ʷɶ̹ʷȵǴǴɶ˸̹λλλλͺͺͺͺ̺ͻͻͻμμμμϽϽϽϽϽϽϽϽμμμμμμμμͻμμϽϽμμͻ̺ͻͻμϽϽооϽμμͻͻμμϽоϽͻ˹˹˹̺̺̺̺̺̺ͻͻͻͻμμμμμμμμμμμμμμμμμμμμͻͻͻͻϽϽϽоϽμͻͻ̺ннннннннннннннϼ˸ŲüĽƿðǴ˸λнԾθ̶ѻԻѸ̴͵˱϶Ϸ̴˱ȮϿųxnkigcou|Ľǫ˯дҸҸѷѷѹηлϹǰ{sYn]Cr^ChW;hW=k]BykQw¸ƬйһԽԽӼӼԽվշԷҸѹкмннѾ͸лһѵնΰv`}kStbJrbHugL|nQnæɭȮ̴ʴǴθϵͱͱϳдͱħż{qlqzþʰϵ̲ǭƯȱĮ¬®ȴ̸ϻлͷηͷͷͷͷ̵̵˵˵˳˳ȱŮĪ¨ȹǸǸǸǻʾ©êūìĬƮɱ˳̶˵͸λкѻкηͳ˱˱̲˴˵˵ʴȵȵȶȶǷȶɸ˸̺ͺͺλϻкккϹϹ͹͹ͷϷϹϴ̱ʭɬɬȫȪȫɫʮ˯̴ηйϸͶ̵̵ηϸηͶ̵̵ηϸй϶϶зз϶ʹʹʹ˱ѷҸͳˮαϲͰηηη̵ʳɲʳ̵˴˴̵ͶηηͶͶͳͳδϵѷҸӹӹкккϹϹϹθθ͵͵̵˴̲̲˱ʳȴʶ̸̺˷˷ͷϹккѸзеϴϴ϶ѺлйϸϸййѺжжжϵϵϵββ˰̯ˮʭɬȫȬȬʮ˯ͳδδδͳ̲ϷϷиѹѹѹииϷϷϷϷииѹѹҹзʹʱȯǮǮǮ˲̳ε϶з϶εεη̵˱ɯʭ̯αгϲα˳ʲȵɶȷʸȵɵɵȴȴȴȴȴʶʶ˷˷˷̸̸̶˴˴ʳʳɲɲɴɴƱǲȵɶʷ˸ʹ˸ɴɴȱȱɲɲ˱̲˯ˮˮ˫˫˫ʪɬʱɳɳɳɳɳɳɳʴʴʴ˵˵˵˵̶͸̷̷˶˶̷̷͸͸ιιιι͸̷˶˸ɶǴŲŲǴɶ˸˾̿˾̼˻ʺ˹˹̹ͺθϹккλͻ̺˹˹˹˹̺̺̺ͻͻͻͻ̺̹ȵɳɳɳɳʴ˵̶θθϹкϹθ̶˵ȵɶʷʷʷʷɶȵʷʷ˸˸˸˸ʷʷɳɳɳǱưĮ¬¬íưɳ˵̶ͷͷͺ̹˸ʷʷʷ˸̹ͺͺͺͺ̹˸ʷʷ̹ʷǴƳŲǴɶ˸λλͺͺ̹̹̹˸̺̺ͻͻͻμμμϽϽϽϽϽϽϽϽμμμμμμμμͻͻϽϽϽϽͻͻ̺̺ͻμϽооѿϽμμͻͻμμϽѿϽͻ̺˹˹̺̺̺̺ͻͻμμμϽμμμμμμμμμμμμμμμμμμμͻͻ̺̺̺оооооϽμμμϼϼϼϼϼϼϼϼϼϼнннѾϼ˸Ų»ĽŲʷλнԾͷ˵ҼӺͷ̴̵йϹ̶͵и˴ūξƵƿĽĽ¦ƪʮϳѵѷжϵϷηϺϹȱ|vZraEp]?hW;k\\?rdIu[ƾɱѺӼԿԽҽһӾվոӹҸѹкϻмнϼ˸мԽѸҹβtl}f~dhmùƫɯȮ̴ʴȵкͶͳͳжѷ̲ũʰϵѷ̵ǰĭìŮìŰʶκϻлͷͷͷͷͷͷ̵̵˴ʴ˵ʹ̶˳˳ʲëª˿é«ĬȰθкͷʴλλѻѻкη̳ʱ˲˲̵̶̶̶˸ʷʷɶƶȵȷʷ̺ͺͺ̸̹˷˵̶ͷθϻκͷθηδʯȬ˰̰̯ˮʯʮɭǮ˳ηййηͶηйϸηͶ̵Ͷηϸйεзззε̳˲̳˱ѷҸ̲ɯαϵͳϸϸϸͶʳʳ̵η˴̵ͶηηηηηͳͳδϵѹҸһԺѻѻккккϹϹ̴˳ʳʳʳ˱ɲɲʶ̸ͻκ͹͹ϹкккѸззϴ϶϶ѺлйϸϸййѺжжжϵϵδδβ˰ʯɮǬǬƫǫǫʰ̲ͳδϵδͳͳиѹѹҺҺѹѹи͵͵͵ζζζϷϷҺѸ͵˲Ȱȯǯȯɱ̳͵϶Ϸеζζӻи̲ɯʭˮαг̯˰ʰɱɳɳɶɶȵɳʶʴʶ˵˷˵ʶʴ˷˵˷˵̸̶͵̴ʳʲɲʲɴ˵ƱȲȳ˵̹ͺͺͺʵʲȱȰǰʲ̲ͳ˯̯ˮ˭˫ʪʪȫʰȲɳɳɳɳʴʴʴ˵˵˵˵˵̶̶͸̷̷˶˶̷̷͸͸ιιιι͸̷˶˸ɶǴŲŲǴɶ˸˾ͽ̿ͽͽ̼˹ʸ˹˹̹ͺͺϹккλͻ̺˹˹˹˹̺˹̹̹κκ͹͹̸ǱǱǱǱǱȲɳʴθϹϹкϹθ̶˵ɳʴʶ˵ʷʴɶɳɶ˵ʷ̶˸˵˷ʴɳȲȲǱůíĿíĮǱ˵̹θλλͺ̹˸ɶɶʷ˸̹ͺͺͺͺ̹˸ʷʷ̹ʷǴŲıƴȶʸͻͻͺ̶̶̹̹˵̹̺̺ͻͻμμμϽϽϽϽϽϽϽϽμμμμμμμμ̺ͻϽооϽͻ̺̺ͻͻμϽоѿѿϽμμͻͻμμϽѿоμ̺˹˹̺̺ͻͻͻμμϽϽоμμμμμμμμμμμμμμμμμμμͻͻ̺̺̺оѿѿѿѿоϽμоѻѻѻккϹϹккѻϼͺ̹ͺͺʷıƿ»üƿðȵ̹ϼѾҿѾѾнѻѾҼӾѼ͸ʵȱǱ©ŻĺǽƿüĽ¥¨ĪǭƪƪƪƪǫǫǭǭϵѷҸҸжδδϷӾҽϹȮ|wYs`@lY9k[:n_BynRsɳӿѾԾտҼҼкϹͺ̹̹̹ϼѽѾҾк̶Ȳů̵˴ɲȱȳɴ˶̷θζζ͵̴ɱƮĬŽûûĭȱϷ͵ʲǯưưǱȲůůŰǱȳ˶͸Ϲ̶̶ʴʴʴ̶θϹԾҽϺͶ̷˴̵̵ʳȱìǿŽŽŽſľëɱ͵ϷϷϷϹθθ̶˵ʴɳɳʴʴʴʴʴʴʴʴϹͷ˸̶ͺθ̹˵ʴʴ˵̶ͷͷͷ̶ҼϹͷ̶̶͵˴ʲ̵ζϷζ˳ʱʱɱɲʳ˴˴̵̵˴˴йη̵̵ηϸηͶ˴̵̵ͶͶ̵̵˴̵ͶηηͶͳʳɲʳ˴̵̵ͶͶ̵̵˴̵ͶηηηͶͶηηϸѺѼѺѼѺлѻϺι͸̷̷˶͸͸͸̷̷˴˶˴ιηιϸϸйййϸϸϸйѺӹԽԽйϸηͶͶͶͶηйһһϸ˴ɲ˴δͳ̲ʰɯȮȮɯʰ˴˴̵ͶϸйѺѺԽӼһйη̵˴ʳ̵̵̵ͶͶηηη͸ͷ˶˵ɲɱɲʲ̲ͳͳδδαͳ̲δͲʰʯʯ˰Ͳγγ̱˰ɮɰɰʲʲʲʲ˵˳˵ʲɳɱʴɱɳɱɳʲ˵̴̴̳˳̳˳̳˳˲͵ε͵εͷͷͷε˱˰ɯʯɯʯʰ̱ͳͲ˱˰ɯɮȮȰȱȱɲɲʳ˴̵̵Ͷ̵̵˴˴̵̵Ͷ͸͸͸ιιϺϺϺιιι͸͸̷̷̷˸ɸȷǶǶɸʹ˺мϹϻθ̶˵˷ʶɵʶ̸κϻϻκ̹ʹ˺˺˺̹̹̹ͺ͹ͷͷͶ̵˴ʲɲưưưưưǱȲɳʴ̶ͷϹϹθͷͷ˴̳Ͷε̶˳ȳǰ˶ʳ˵˳̶ʹ˴ɲȰǯƯŮŰƱƱǲƲȴ˷͹ϼмѾнμͻ̺ʸʷ˸̹ͺ˸˸ͷͷͷ̶˵ʴɴʵ˸˸ȷǸȹʻ;;ͼͺ͸Ͷͳ̵ͷ̹̹ͺͺͺλλλλλλλλλλμμμϽϽоооϽϽμμμͻͻͻ̼̼̼ͽͽξξξϿϿϿϿϿξξξ̺ͻͻͻͻͻͻμϽооѿѿооϽϽϽϽϽϽϽϽϽμμμμμμμμϽμͻ̺̺̺̺ͻоϽϽϽϽоѿѻѻкϹϹθθϹϹкϼλͺͺͺ˸ŲĽƿ¯ŲɶͺнѾҿҿѾѾѾҿҿѾϼͺ˸˵ůªªƮǯëſªĬŭŭŭŭȰʲǭȮȮɯʰ˱̲ͳϵѷӹҸжϵϵиҽѼͷérsRq^=kX7o_>xiJ|`лӿҿҿѾнϼͺ˸˸ʷʷλϼҿҿϼͺƱîŽŽî͸̷ʵɴɴʵ̷͸ͷͷθθθ̶˵ʴǱưůĮưɳͷϹϹθ̶ɳȲȲȲɳůůưǱɳ˵ͷθ̶˵˵˵˵˵̶ͷѻкϹθ̶̶̶̶͵ɱĬſýýªëĬŭǯʲ͵ϷѹϹθθͷ̶˵ʴʴ̶̶̶̶̶̶̶̶̶˵ʴ˵̶ͷ̶˵̶ͷθθϹϹϹθϹͷ̶̶̶̶ʴȲ˵ͷθͷ˵ɳɳɳ̵ͶͶͶͶηηϸѺϸͶͶϸйϸη˴̵̵ͶͶ̵̵˴ʳʳ˴̵̵ʳȱǰ˴˴̵ͶηηͶͶ˴̵ͶηηηηͶιϺлѼѼѼѼѼѼллϺι͸͸̷͸͸͸̷̷̷˶˶ͶηηϸϸййѺйййййѺӼӼйϸηηͶͶηηйѺһϸ̵ʳ˴Ͷ˴ʳɲȱȱȱɲʳ˴̵ͶηϸйѺһӼӼѺйηͶ˴˴̵̵̵ͶͶͶηηι͸̷˶ʳʳʳʳ̲̲ͳδβͱ̰Ͱ˱˰ʯɮʯ̱γеγͲ̱˰˰˰˰˰ʲ˳̴̴̴˳˳ʲɱɱɱʲʲ˳˳˳̳̳̳̳̳̳̳̳ʹʹʹʹʹʹʹʹ̱̯˰˰˰˰̱̱϶εʹ̳˲˲ʴʴȱȱɲʳ˴˴̵̵ηͶ̵˴˴˴̵̵͸͸ιιιϺϺϺϺϺϺιι͸͸͸ʹʹȷǶǶȷʹ˺϶϶εʹ̳˲ʴɳʶ˷͹κϼϼϼͻ˺ʺ˺˺˺̹̹̹͹ͷηεδ̲̱ʰưưůůưǱȲȲ̶̶ͷθθθθθ̳δεε͵˳ɲȱʳɲɱʲ̳̳˱ɯȰȰǯǯƱƱǲǲȳʵ̹ϼѾѾнϼμͻ̺˹˸˸ͺͺͺͺθͷͷͷ̶̶˶̷ͺ̹ɺɺʾ˿̻̽ͺ͸δͳͳͷͺͺͺλλλϼλλλλλλλλμμϽϽϽооооϽϽϽμμμͻͽͽͽͽͽξξξϿϿϿϿξξξξͻͻͻͻͻͻͻͻϽооѿѿооϽϽϽϽϽϽϽϽϽμμμμμμμμϽμͻ̺̺̺̺ͻϽμμμμϽоѿоѻѻϹϹθͷͷθϹϹϼλλλλ˸ǴððŲȵ̹ϼѾҿҿѾѾнѾѾҿҿѾнλͺͺ̹ͷíëŭʲζ͵ɱĬɱʲ̴̴˳ʲ̴ζʰ˱̲ͳϵѷҸҸжҸӹӹѷϵϵиллʴĽjrQtdCn^=xhGxYrůԿҿѾнѾҿѾϼ̹ʷɶȵȵͺϼѾҿѾӾҽѼ͸ɴǲȳɴι͸˶ʵʵ˶͸ι˵̶ͷϹϹкϹϹϹθθθϹкҼӽϹθͷ̶˵ʴɳɳůůůưȲʴ˵̶˵̶̶̶̶̶˵˵ͷͷͷͷͷ̶˵ʴζɱª¼¼ŭ˳ʲǯƮǯ˳ϷҺθθθͷ̶̶˵˵ϹϹϹϹϹϹϹϹʴȲȲɳ˵̶̶˵θϹкѻѻѻккͷ̶˵̶ͷ̶ɳǱɳ˵̶̶˵ɳʴ˵ηηͶ̵ͶηϸйѺйηηϸѺйϸ̵̵ͶͶͶͶ̵̵ʳ˴̵̵̵˴ɲȱ̵Ͷηηϸϸηη̵ͶηηϸϸηηϺϺлѼѼѼѼлѼѼѼлϺιιι͸͸͸͸̷̷̷˶̵ͶηηййѺһѺѺййййѺһййϸηͶͶηηйѺѺϸͶ˴˴̵ʳʳɲɲɲʳ˴˴̵̵ͶηйѺһһӼһѺйηͶ̵˴̵̵̵̵ͶͶͶηιι͸͸̵˴ʳʳ˱̲ͳͳͱͱ̰̯ɯʱɰɰʱʹ϶зʹεεεεʹ̳˲˳˳̴͵͵̴̴˳ǯȰʲ˳̴˳ʲʲʱ˲˲̳̳ʹʹεʹʹʹʹʹʹʹʹγͲͲ̱̱ͲͲγз϶εʹ̳̳̳̳ɲɲʳʳ˴̵ͶͶϸηͶ̵˴˴˴̵͸ιιιϺϺϺϺлϺϺϺιιιι˺ʹȷǶǶȷɸʹ̶̶̶˵ʴʴɵɵ˸̹λϼϿϿϿϿ;˽̽˺˺ʹ˹ʷ͹ͷηηζ͵̴ʳǱưưưưǱȲȲͷ̶̶̶̶ͷθϹͶϷηͷͷ̶ʵɴʵȳɳɳ˵˴ʲȰɱɱȰǯƱǲȳȳʵ̷ϻѽѿоμ̺ͺͺ̹˸̹̹ͺλнϼθͷ̶̶ͷθϹкλͺ˻̼̼̼̺̹ͷͳδδθλλλϼϼϼнλλλλλλλλμϽϽϽооооѿоооϽϽϽμξξξξξξͽͽϿϿξξξͽϽμμͻͻ̺̺˹ϽϽооооϽϽϽϽϽϽϽϽϽϽμμμμμμμμϽμͻ̺̺̺̺ͻμͻͻͻͻμϽоϽҼҼкϹϹθθϹϹкϼϼннϼ̹ɶǴǴȵɶ̹λнҿнϼϼϼϼнѾѾѾϼλ̹̹ͺλλưǯɱ͵иϷ˳ǯ͵ϷииϷζϷиͶϵϵжѷҸӹӹѷҸԺӹѷжжѹллʴ»o}^vUrQ}^pʴӾҿҿϼλϼҿнͺ˸ɶɶȵ̹λϼнѾϼλͺҽԿԿҽϺ˶ɴɴ͸̷˶˶˶˶̷͸˵̶ͷθϹккккккѻѻкккͷͷͷͷ̶ʴɳȲưưưưǱɳʴ˵̶ͷθϹϹͷ̶˵˵̶θθθͷ˵ʴ͵ȰƮ̴ʲǯƮǯʲζѹθθθθͷͷͷͷϹϹϹϹϹϹϹϹɳȲȲɳ̶θͷ̶ккѻѻҼѻѻк̶̶ͷθϹθʴǱɳ˵ͷͷ̶̶̶θηͶ˴ʳʳ̵ηйһйηϸйѺѺй̵̵ͶηηͶ̵̵̵ͶϸϸϸηͶ̵ͶηϸйййϸϸͶͶηϸййϸϸллѼҽҽѼѼлѼѼѼллϺϺϺιι͸͸͸̷̷̷̵ͶͶηйѺѺһһѺййϸйййѺйϸηηηηϸϸййϸη̵̵̵ɲɲʳʳ˴˴̵Ͷ̵ͶηϸйѺһһһһѺйηͶ̵̵˴˴̵̵̵ͶͶͶ͸͸͸͸̵˴ʳɲ˱˱̲̲̰̰˯˱ʲʱʱʱʱ̳ʹεʹε϶з϶ε̳˲ɱʲ˳̴̴̴˳˳ƮȰʲ̴͵̴ʲɱɰʱ˲˲ʹʹε϶̳̳̳̳̳̳̳̳ϴγγͲͲγγϴ϶εʹ̳̳̳̳˳ʳʳʳ˴̵ͶͶηϸϸͶ̵̵˴̵̵ιιιϺϺϺллϺϺϺιιι͸͸˺ʹɸȷǶȷɸʹ̶̶̶˵˵˷˷˷ͺͺλϼϿϿο̾̽̽ʻʹʸɷͺ͹Ϻϸηζ͵˴ɳȲȲǱǱȲɳɳ̶˵ʴɳɳ˵ͷθηηͷͷ̶̶ʵʵʵɴɴʴ˵˵ʳɱʲʲɱɱȳȳɴɴ̷ιмӿҿнͻ˸̹̹̹̹ͺͺλλнλͷ˵ʴ˵̶θккλͺ˹̼ξʺʸ˸̶͵ͳϲδϹλϼϼϼнннϼϼϼϼϼϼϼϼϽϽϽоооѿѿѿѿѿоооϽϽϿϿϿϿξξξξϿϿξоϽμμ̺̺˹ʸμϽооооϽμϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμͻ̺̺̺̺ͻμμͻͻμϽоооҼҼҼѻѻккѻѻҼнѾѾѾϼͺ̹˸˸̹ͺϼнҿϼλͺͺͺλϼϼϼλͺ̹̹ͺϼн̶̶̶ͷͷͷ˵ɳͷϹҼҼкϹкиѺѺѺѺѺййййһԽӼѺййҺмѼ̶ƿvtu~¨θԿҽҿϼλϼҿϼͺ˸ʷʷ˸̹ͺλϼλλͺϺллϺ̷ʵɴʵ̷̷̷˶˶̷̷̷ͷͷͷͷθθθϹθϹккϹθͷ̶˵̶̶̶˵ʴɳȲǱǱǱǱȲɳʴʴθϹкѻѻкθͷ̶ͷθϹϹθ̶˵˳Ʈſ¼ªƮƮƮƮȰɱ̴ζϷθθθθϹϹϹϹϹϹϹϹϹϹϹϹ̶ʴʴ̶θкϹθϹккѻккϹϹͷͷθкѻкͷɳʴ̶ϹϹθθϹкϸͶ̵˴˴ͶϸѺһйηϸйѺѺй̵ͶηηηηͶ̵ͶηϸййϸηͶͶηϸйййййηηϸйййййѼѼҽҽҽѼѼлѼѼѼллллϺιιι͸͸͸̷̷ͶͶηϸϸйѺѺѺѺйϸϸϸййѺйϸϸηηϸϸϸϸϸϸϸη̵˴ɲʳ˴˴̵̵ͶͶ̵̵ͶηйѺһһӻҺҺѹϷζζ͵̴̴̴͵͵͵ζζ˶̷̷̷˴ʳȱǰʰʰ˱˱˯˯ʮʰ̴˵ʴʴɳɳɳɳ˵̶ͷθͷ̶ʴɳǯȰɱʲʲʲʲʲƮȰʲ̴͵̴ʲɱȰɱʲʲ̴̴͵ζ˳˳˳˳˳˳˳˳ζζ͵͵͵͵ζζ̲˱ʰʰɯʰʰʰʳ˴˴̵ͶηηηϸϸηͶ̵̵̵ͶιιϺϺϺлллϺιιι͸͸͸͸̻˺ɸȷǶȷɸɸ˸˸˸̹̹̺̺̺̼ͽͽͽ˿̽ʻʻʺɷͺλλϺϺι͸͸˵˵ʴɳɳʴʴ˵ɳɳǱǱǱɳʴ̶ιι̸̸ʷʷɷɷ˹˸ʷ˸͹͹̷ʵʵʵɴɴɴɴʵʵ̶θкҼҼѻͺ˸̹̹ͺͺλλλλϼͺʷȵǴȵɶʷθθκ͹˸̹λнɶɶʶ˵ʹγϲϴϹλϼϼϼнннϼϼϼϼϼϼϼϼϽϽоооѿѿѿѿѿѿоооϽϽϿϿϿϿϿоϽμμ̺̺˹ʸμμϽооϽμμϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽϽμͻ̺̺̺̺ͻϽϽϽϽϽоѿѿӽӽӽҼѻѻѻѻҼӽнҿҿнλϼϼϼϼнѾѾҿнϼλͺͺͺͺͺϼϼλλλλϼϼѻкθ̶˵ʴʴʴ˵θѻҼѻккѻӼһһѺййϸϸѺӼվԽһѺѺӻҾӼϹƬùôȺĩ˱ӺԿѾϼнҿнλͺ̹̹ɶʷ̹ϼѾҿϺϺϺι̷˶̷ι͸͸͸͸͸͸͸͸кϹθͷͷͷθθкккккϹθͷ̶˵˵˵ʴʴɳɳʴɳɳȲȲɳʴʴͷθϹкккккθϹϹϹθͷ̶̶ɱƮý¼ſëƮëĬƮɱ̴͵ζζθθθϹккѻѻθθθθθθθθθͷͷθкѻѻϹϹϹккϹϹθͷϹθθкѻѻθ̶̶θкѻкϹкѻѺйϸϸϸйһӼѺйηηϸѺйϸͶͶηηηηͶͶ˴̵ͶϸϸηͶ̵ͶηϸййййϸηϸйѺѺѺѺйҽҽҽӾҽѼѼлллллϺϺϺϺϺιιι͸͸͸͸ηηϸϸϸϸйййϸϸϸϸϸйѺѺѺйϸϸϸϸϸϸηηϸйϸ̵ʳ˴˴̵ͶͶͶ̵̵˴˴̵ͶηйѺѺҺҺѹииϷζζ˳̴̴̴͵͵͵͵ʵ˶̷̷˴ɲǰƯɯɯʰ˱˯ʮɭɯ̴̶˵ʴɳȲǱưʴʴ˵˵ʴɳɳȲƮƮǯɱɱʲɱɱǯȰʲ˳̴˳ʲʲɱʲʲ˳˳̴̴͵̴̴̴̴̴̴̴̴ζ͵͵̴̴͵͵ζ˱ʰʰɯɯɯʰʰ˴˴̵ͶηηϸϸηηͶͶͶͶηϸϺϺϺϺлллѼлϺϺϺιιι͸ͺ˺ɸȷǶǶȷɸ˸˸˸̹ͻͻμμ̼̼̼̼̿˿˿ʾ˼ʻ˻ʺλλϼϼϻϺκ͹̶˵ʴʴɳɳʴʴȲȲǱǱȲȲɳʴ͹͸˷ɶɶɶȶɷ̺˹˸̹ͺκ͸˶̷˶ʵʵʵʵ˶̷̶ͷϹккϹθθ˸̹ͺλϼϼϼϼλ̹ʷȵǴǴǴȵ˷̶κ͹̹˸̹ͺǴȴɳ˲ͲγϲеθλλλϼϼϼнннннннннооооѿѿѿѿоооϽϽϽμϿϿϿϿϽμμͻͻ̺̺˹μμϽϽϽϽμμϽϽϽϽϽϽϽϽооооооооϽμͻ̺̺̺̺ͻооϽϽооѿӽӽҼѻѻккѻѻҼнҿѾϼнҿҿҿҿҿҿҿҿҿҿѾϼλͺͺͺϼϼннннϼλккϹθ̶ʴʴ˵ʴͷкҼҼѻѻѻһһһѺѺѺѺѺһԽվվӼѺѺӻԽѻ˱ŪçũɫŪ˯βͲжռҿѾҿѾϼλͺ̹̹˸̹ͺϼѾϺллϺ̷˶̷͸ϺллллллϺѻкϹθθϹкѻҼҼҼѻѻѻѻѻθͷ̶ʴʴ˵̶̶̶˵ʴʴɳʴʴ˵˵˵̶̶θϹкѻкϹθ̶˵˵ʴʴȰǯŭëëĬƮǯŭƮȰʲ̴ζϷϷͷθθϹкѻҼҼϹϹϹϹϹϹϹϹкϹθϹкѻкϹкккккϹθͷϹθͷͷϹкθͷ̶θккϹθϹкйййѺѺѺһһѺϸͶͶϸйϸηͶηηϸϸηηͶ˴̵ηϸϸϸηͶͶͶηϸϸϸϸϸϸййѺһһѺѺҽӾӾӾҽҽѼлιιιιϺϺϺϺϺϺιιι͸͸͸ййϸϸϸϸηηηηηηϸйѺһһѺйϸϸϸϸйηͶͶϸѺйͶɲ̵ͶηηηͶ̵˴ʳʳ˴̵ͶηϸйҺҺѹииϷζζ˳˳̴̴̴͵͵͵˶̷͸͸ͶʳȱǰȮɯʰʰʮʮɭȮʴɶɶɶȵǴǴƳȵǴǴƳŲŲƳǱƮǯȰɱʲʲʲʲɱɱɱʲʲ˳˳˳˳˳˳˳˳˳˳˳̴̴̴̴̴̴̴̴ͷͷ̴̴̴̴͵͵˱˱ʰʰʰ˱̵̵̯̲ͶͶηϸййͶͶ̵ͶͶϸйѺϺϺϺлллѼѼҽҽҽѼѼлллλͺ˸ɶȵȵɶɶɶɶʸ˹̺ͻͽξ̼˻ʽʽ˾̿ʾʾʾʾ̼̼ͽͽμϽϽϼλͺ˵ʴɳȲȲȲȲȲȲȲɳʴʴʴʴʴ̸˸ʷȶƵǶƶǷ˻ɹʹʹͻͺ˸ɶ̷̷˶˶˶˶˵˵̶̶͵͵̵Ͷηη˵̶θкѻѻϼϼͺͺ̹ʷɷȶǵǴɵ͸ллϺ͸̷̷ǲǰɲʱͱϳдзͷͺͺͺλλλϼнннннннноооѿѿѿоϽϽϽμμμͻξξϿϿξͽͻͻͻͻͻͻͻͻͻμμϽϽμμͻϽϽϽϽϽϽϽϽооооооооϽμͻ̺̺̺̺ͻϽϽμμϽооѿѿӽӽѻккϹϹккѻнѾнѾҿҿҿҿҿҿѾϼλλλϼнѾҿҿнϼλθкѻкθ̶˵˵ɳ̶кҼҼҼҼҼѼѺѺһһӼӼӼһԽվվӼѺһӽտԾѹζ̲̱ϵӷɭϲѶжѹԼտӿҿѾѾϼλͺ̹̹̹λϼϼϼϼϼϼϼ͸ϺлϺ̷ɴɴɴҽҽӾӾӾӾҽҽѻккϹкѻӽԾӽҼҼѻѻѻҼҼкϹ̶˵ʴ̶θϹͷ̶˵˵ʴʴ˵˵ʴɳɳɳ˵ͷкҼкϹ̶ʴȲȲɳɳɱɱɱɱȰȰȰȰʲʲʲʲ̴ζиѹͷθθкѻҼӽӽккккккккѻϹθϹккϹͷѻѻѻѻкϹθθϹͷ˵˵ͷθθͷ̶θккθͷͷθͶηϸйййϸϸйη̵̵ηϸηͶͶηηϸϸηηͶͶηйһһһѺй̵ͶηϸϸϸηηϸйѺһһһһѺӾӾӾӾӾҽлл͸ιιιιιιιϺϺϺιι͸͸͸ѺѺйϸϸηͶͶͶͶͶηϸйһһһѺйϸϸϸϸйηͶͶϸһѺͶɲͶηϸϸηͶ˴ʳɲɲʳ˴̵ηηϸҺѹѹииϷϷζ˳˳˳̴̴͵͵͵̷͸ιϺη̵ɲȱȮɯɯʰʮɭɭȮȲǴȵɶɶɶȵȵǴƳŲðððıưǯȰɱʲ˳̴̴̴ʲɱɱɱɱʲ˳̴̴˳˳˳˳˳˳ʲ͵͵͵͵͵͵͵͵ͷ̶̶˳˳̴̴͵̲̲˱˱˱Ͱααͳ̵Ͷηϸϸйй̵̵̵ͶηϸѺһϺϺϺллѼѼѼԿԿԿӾӾӾҽҽλͺ˸ɶȵȵɶɶǴȵȶɷ˹̺̼ͽ˻˻ɼɼʽ˾ɿʾʾʾʾ̼ͽͽͽμϽϽϽλλɳȲǱưưưưưȲʴ˵ͷͷ̶˵ʴ˷ʷȶƴŴƵƶƶɹȸȸɸ˹˹ʷȵ͸̷̷˶˶̷˵̶̶ʹ˳˳˴̵ηй˳̶θкѻѻϼϼλλͺͺ˹ɷȶȵȴ͸Ѽҽлι̷̵ƯǮȯʱͱϳдзͷ̹̹ͺͺͺλλнннннннноооѿѿϽϽμμμͻͻͻͽξϿξͽ̼˻̺ͻͻͻͻͻͻμͻμμϽϽμμͻϽϽϽϽϽϽϽϽооооооооϽμͻ̺̺̺̺ͻμͻͻͻͻμϽооҼҼѻѻѻѻѻѻѻѻҿҿѾѾѾҿѾѾѾҿҿҿѾнϼλλλѾѾѾѾѾѾѾѾҿҿѾнннѾѾҿҿѾѾҼлллѼѼҽҽҽԿԿԿӾӾҽҽӽտԾҺиϵϳγϴѶѶзѷѹҺӽӽҿѾнϼλλλϼϼнѾѾѾннϺϺι̷̷̷̷̷ιιϺлҽӾԿԿԾԾӽӽҼѻѻѻҼѻϹθθϹѻҼкϹθͷͷͷͷͷͷ̶˵˵˵˵̶ͷ̶ͷͷθθϹϹϹѻϹ̶ɳǱưưǱʲɱȰǯȰɱ˳̴Ȱɱʲ˳͵ζϷϷкккѻѻҼҼӽϹккѻѻккϹӽҼѻкϹθθθϹϹϹϹϹϹϹϹθϹкϹθθкҼͷθθϹϹθθͷηηηϸйһӼԽηͶ̵˴̵ϸѺӼԽѺϸϸйһһһһһѺѺѺѺѺѺϸϸйййѺѺѺϸϸϸϸϸϸϸϸϺϺϺϺϺϺϺϺϺιιιιϺлѼι̷˶̷ιлѼлѺйϸͶͶηϸйѺѺйѺһѺϸ̵йϸηηϸϸ̵ʳϸηηйѺѺη̵ηϸйϸͶ˴ʳʳηͶ̵˴̵ͶϸйизззѸѸ϶ʹ̳˲ɰʱʹзѸи̷ιϺѼйϸͶ˴ƬȮʰ̲ͱ̰ʮɯͶʵɴ˶ʵƱƱɴʵȳŰŰǲȳɴȳȰȰȰɱɱʲʲʲʲʲɱɱɱʲ˳˳ȱǰǰƯǰȱʳ˴ʳȱŮŮǰʳ˴˴˶ȳįŰȳ˶̵˴δͳ̰ʮɭȬȬȬͳͶϸйѺѺйй̵̵ͶηϸϸйѺιϺлϺ͸ʵɴɴϺιлӾѼ͸ιӾι͸̷˶̷͸ιϺ˸ɶȵʷͼν̻ɸɺ̽˼ȹǻ˿ɼʽʽʽɺʻ˼;νͼʹƵǴɶ˸ʷǱɳʴɳǱưưȲǱȲɳ˵˵ʴɳɳʶ˷ʷȵƳƴȷ̻̻ͻ̺̹˸ʷʶʶʵ̷̷ʵůĮưȲʲɱȱ˱δϵδͳʲʲ˳ζкѻѻкλλͻͻ̼˻ʺ˸ɵϺӾѼ˴ƯƯɰʱ˯˯̰ͱβϳ϶Ҽϼͺ˸ʷ˸ͺλλλϼϼϼнннͻμϽооооϽоооϽϽμμμͽξϿξξξξͽ˻˹˹˹̺̺ͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμоѿѿѿѿоϽμϽμμͻͻ̺̺˹ϽμμͻͻμμϽоҼҼѻѻѻѻѻѻѻѻҿҿҿѾѾѾҿҿҿѾҿҿҿѾнϼλλλѾѾѾѾѾѾѾѾҿннϼнѾҿҿҿѾѾѾнннϼллѼѼҽҽӾԿԿӾҽҽӽտԾҺиϵϵждҹҸҸѷѹҺҼӽҿѾнϼϼϼϼϼннѾѾѾнϼϺι͸̷̷̷͸͸ιιϺϺлѼѼҽѻѻѻкккккѻѻϹϹϹϹѻѻѻкϹθθθθθͷͷ̶̶̶̶ͷͷͷͷθθϹϹϹккθ̶ɳǱǱǱǱʲɱȰǯȰɱ˳̴ɱɱʲ˳͵ζϷϷкккѻѻѻҼҼϹϹкѻѻкϹϹҼҼѻккϹθͷθθθθθθθθθϹϹθ̶̶ͷϹͷθθθθθθͷηηηηϸйѺһηͶ̵˴̵ηйһԽѺϸηϸййϸϸϸϸϸϸϸϸϸϸϸϸйййѺѺηηηηηηηηллллллллϺιιιιϺлѼϺ͸̷̷ιллϺͶͶ̵˴̵ηϸѺӼѺηͶϸйϸη˴ʳʳ˴ηηͶ˴ʳɲɲ˴Ͷη̵˴ͶηϸηͶ̵˴˴ͶͶ̵˴̵Ͷηииз϶зѸѸ϶ʹ̳ʱȯɰ̳ε϶϶̷͸ϺлѺϸηͶȮɯʰ˱̰˯ʮɯϸ̵˶Ͷ̷ȱǲʳǲŮįŮǲɲʵɲȰȰȰɱɱɱʲʲ˳ʲɱɱɱʲʲ˳ƯƯƯƯǰɲ˴̵˴ɲƯŮȱʳ˴˶ʷȵƳƱʵ̷̵˴̲̲ʮɭȬȫȫȬͳͶϸййϸηηʳ˴˴̵Ͷηϸϸ̷̷̷ιι͸ʵǲ˶ɴǲįļƾȳιι͸̷ʵʵ˶͸̹ʵȵʷͺλʹǶʹ;̽ȹȹ˼̽ʽ˻ʽʺȹɺ˼̻˺̹ʹɶʷ̷˹˶˵˵ʴɳȲǱưǱưǱȲʴʴʴɳȲɵʶɶȵƴƴǶɸȷȷɷȶȵȵȵɵɵ̷̷ʵưůǱɱɱȮȮʰͳϳβͱ˱˳̴ζϹкϹθλͺͻ̺˻ʺʺɹʷлӾлɲŬŬɭ˯̰ͱͱ̰ͱдҹѻϼͺ˸˸˸ͺλͺλλλϼϼϼнͻμϽооооϽоооϽϽϽμμξϿξͽͽξϿͽ̼˹˹˹̺̺ͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμооѿооϽϽμμμͻͻͻͻ̺̺ϽμμͻͻμμϽоҼҼѻѻѻѻѻѻѻѻҿҿҿѾѾѾѾнѾѾҿҿҿҿнϼλλλϼѾѾѾѾѾннноϽϽоѿѿоооϽϽϼλϼннҿҿҿҿտԾҺѹѹиѹѷһӻҺѹѹҺҼӽҿѾнϼϼϼϼннѾѾѾѾнϼι͸͸̷͸͸ιϺιιιιιιϺϺθθθθθϹϹϹѻккϹϹккѻҼѻкϹϹϹккϹθθͷͷθθϹθθϹϹϹкккϹθ˵ɳȲǱȲȲʲɱȰȰȰɱ˳̴ʲʲ˳̴͵ζϷϷϹϹкккѻѻѻθϹккккϹθкѻѻѻѻϹͷ̶̶̶̶̶̶̶̶̶θθθͷʴʴ˵ͷθθθθθθθθηηͶͶͶͶηϸϸηͶ̵̵ηϸйһйηͶηϸηͶ̵̵ͶηηͶͶ̵ηηϸϸϸйййηηηηηηηηѼѼѼѼѼѼѼѼιιιιιϺлллι͸͸ϺллϺͶ̵̵̵ͶϸѺӼӼй̵ʳ˴ηϸϸ̵̵̵ηйѺϸηʳɲɲ˴Ͷϸϸη̵̵ͶͶͶͶ̵̵̵̵̵˴̵Ͷηии϶϶϶Ѹзε̳ʱɰǮȯʱ˲̳˲ȳʵ̷͸ηηͶ̵ʰʰʰʰʮɭɭɭεʱɳ̳ʴǮůɰíê¬īưɰȲȱȰȰȰȰɱɱɱʲ˳ʲɱɱɱɱʲʲŮĮĮůưȲʴ˵ɳǱůưȲɳɳȴǵƴƴȶʶ˷ʴɳȯȯǬǬȫȫɬɬͳͶηϸϸͶ̵˴ʳʳʳ˴̵̵ͶͶ͸̷͸ѼԿѼȳŽ͸ϺϺ͸ɴǲɴ˶˷ɳǳɵ˷̸ȶųʸͽ̼Ƿƶɹ˽̻ͽ˹ʺɷǶȷɸ˸ȶǳȶ˷͹ͷʷʶ͸̶ʴɳɳȲǱůưưǱȲɳȲȲȲȲȲȳɴǳƲıð®®įưǱȴɵʷʶɵǱǱɱ˳ɲɯɯ˯̱ϲαͱ˱̲ͳδζζͷ̶ͺ̹̺˹ʺɹȻȸ˸ϼѽκȲŬǬˮɬͰα̯ȭǬ̳Ѹѻλͺ˸˸̹ͺλ̹ͺͺͺλλλϼμμϽоооооооооϽϽϽμξͽ̼ͽϿϿϿͽ̺̺̺̺ͻͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμоооϽϽϽμμ̺̺ͻͻͻͻμμμμͻͻͻͻμμоѻҼҼҼҼҼҼҼҼҼҿҿҿѾѾѾннϼнѾҿѾѾнϼλλλϼѾѾѾннннϼϽμμоѿѿѿѿооϽϽλϼϼнҿҿԾԾӻӻҺҺҺҺԼӻҺѹѹѹҼҼҿѾнннннѾѾҿҿѾѾнϼ͸͸͸͸͸ιϺлллϺϺιι͸͸ͷͷͷθθϹккккккккккҼҼѻкккѻѻкϹϹθθϹϹкϹϹϹϹϹкккθͷ˵ɳȲȲȲɳʲʲɱȰȰʲ˳̴ʲ˳˳̴͵ζϷϷϹϹϹϹϹкккθθϹϹϹϹθθθϹѻҼѻкͷ˵ͷͷͷͷͷͷͷͷϹϹϹͷʴɳʴ̶θͷͷͷͷͷͷθηηͶ̵˴˴̵̵йϸηͶͶͶηϸηͶ̵̵ηϸηͶʳ˴̵ηηͶ̵̵ͶηηηϸϸϸϸͶͶͶͶͶͶͶͶллллллллιι͸͸ιιϺлι͸˶̷ϺѼѼѼѺйϸϸϸѺһԽѺη˴ʳ̵ͶηηϸηͶηййϸͶ˴ʳɲʳͶϸϸϸ˴˴˴̵ηηͶ̵̵˴˴̵̵ͶͶϷз϶ε϶ззʹ˲ɰǮƭǮȯɰɰȯůƱǲɴʳʳʳʳ̲˱ʰɯȬȬȬɭ˰ǬƭȭǮĩīǬêèêŪǮȭǮƬƯǯȰȰȰɱɱɱ˳ʲɱɱȰȰɱɱưůůưưǱǱȲǱǱǱɳ˵ʴȲűųŵȶʸ˹˷ʴȲƭŬŪǪǪɬʫˮδͶηηͶ˴ɲȱʳʳ˴˴̵̵ͶͶ̷˶̷ҽԿ̷ºvrs~û̷Ϻлιɴǲɴ͸̶ʱǱȲʴ˵ɵűȴ̺ͻɷŵɷʺ̹ͼ̹ɷȵǶȵȵȳű¬ïȲ̶˳ȲǱ̷˵ɳɳʴʴǱĮůưưǱǱȲȲȲȲǯǲɲȴů˾ƺö÷öĹŽůǱɵɶɵɵȲɳʲ˳̲ʰȬǪɬʭʭɬǫʰδϵϷ͵̶̶̹̹˹ʸɹɹǺǺɹλмθʱȭ̯гˮϲѴ̯Ū§Ǯʹλλͺ̹̹̹ͺλ̹̹̹ͺͺͺλλμϽооѿѿооѿѿоооϽϽϽϿξ̼˻˻̼ξϿξ̺ͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμоϽϽμμμμμ˹̺̺ͻͻμμϽμμͻ̺̺ͻμμоѻҼҼҼҼҼҼҼҼҼҿҿѾѾѾнннλϼѾннϼλλλλϼѾѾѾннϼϼλѿϽϽϽѿѿѿѿѿϼϼнѾѾҿԾԼԾԾԾӽӽҼԾӽҼѻѻѻѹѻҿѾѾннѾѾҿҿҿҿҿѾнϼ͸͸͸͸ιϺлѼѼѼѼлϺιιιθθϹϹккѻѻккккккккҼѻѻкѻѻҼҼккϹϹϹϹккϹϹϹϹϹϹϹϹͷ̶ʴɳȲȲɳʴ˳ʲɱȰɱʲ̴͵˳̴̴͵ζζϷϷϹϹϹϹϹθθθͷͷθθθθͷͷͷθкѻѻϹͷ̶ͷͷͷͷͷͷͷͷкккθ˵ʴ˵ͷθͷ̶̶̶̶ͷθηͶ̵˴ʳʳʳʳϸϸηηͶͶηηʳʳʳ˴ηйϸηʳ˴ͶϸйϸηͶͶͶͶͶηηηϸͶͶͶͶͶͶͶͶιιιιιιιιι͸͸͸͸ιϺл˶ʵɴ˶ϺҽҽҽӼһйϸηϸϸйͶ̵˴̵ηηͶ˴ʳʳʳ̵ηϸη̵̵ɲǰǰɲ̵Ͷη˴ɲɲ˴ηϸͶ˴ʳ˴˴̵̵ͶͶ͵϶εʹε϶϶ʹ˲ȯǮƭǮɰɰȯƭůŰƱǲɲɲʳʳ˱˱ɯȮȬȬȬȬ̱ȫĩŨ§Ũ¥èǪȭʭǬũǭǯǯȰȰȰɱɱ˳ʲɱȰȰȰȰȰɳȲȲǱůĮí¬ưǱȲ˵̶˵Ǳï°ĴǷʸ˹ʶȲǱīīŪƩȫɪˬ̯δͶηηͶ˴ɲǰ̵̵̵̵ͶͶͶͶɴȳʵлѼî~izr]rjUwoZkļʳͶϸη˴ʳ̵ηεʯƭƭȯʱȲưȴ̸ɵƴȴ˹̷λͷɶɳɶȳƱìŻ÷ȼο̾ʻȼìůǱɳ˵ʴȲưưưưưǱǱȲȲȰǭǰʰȲªĵªǯʶɶȵȴɳɳɲɲɯūȾĻ¹úúĽħ˱ϵиϷθͷ̹̺˻ʺȻȻǼǺǷ˹λͷȰǭ̯ѳ˭вӵαūĬɱͺͺͺ̹ͺͺͺλ̹̹̹ͺͺͺλλμϽоѿѿѿѿоѿѿѿоооϽϽϿξͽ˻ʺʺ˻ξϿμͻͻͻͻͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμоϽμͻ̺ͻͻμ˹̺̺ͻͻμμϽμͻ̺̺̺̺ͻμоѻҼӽӽӽӽӽӽӽӽѾѾѾѾнннϼϼнҿҿϼϼλλλλϼϼѾѾннϼλλλооооѿѿѿннѾѾѾѾҿҿҿҿҿԿԾԼտտտԾԾӽտԾӽҼѻѻѹѹҿҿҿҿҿҿҿҿҿѾѾѾѾҿҿҿѾнϼϺιιιιϺϺлѼѼллϺϺιιкккѻѻѻѻѻϹккѻѻккϹѻѻкккѻҼӽкϹϹθθϹϹкϹϹθθθͷͷͷ̶˵ʴȲȲɳʴ˵˳ʲɱɱɱ˳̴͵̴͵͵͵ζζϷϷϹϹθθθͷͷͷ̶̶ͷθθͷ̶̶ͷθϹккϹθͷθθθθθθθθϹккθ̶˵̶θθͷ̶˵˵̶ͷθηͶ̵˴ʳʳʳ˴ηηηηηηηηʳɲʳ̵ϸйϸͶʳ̵ηйѺйϸͶ̵̵̵ͶͶͶηηηηηηηηηη͸͸͸͸͸͸͸͸͸͸̷̷͸ιϺϺɴȳȳʵ͸лѼѼѺйη̵˴ʳ˴˴̵˴̵ηйϸͶ˴ɲɲʳ̵йѺѺй̵ɲƯƯɲͶйѺ˴ɲȱʳηϸͶʳɲʳ˴̵Ͷ̵̵͵εʹ̳ʹεε̳ʱǮǮǮȯʱ˲ʱȯȲǲǲȳɲɲʳʳɯɯɯɯȬȬȬȬαƩȿúúƩɬȫƪƬǯǯǯȰȰȰȰ˳ʲɱȰǯǯǯǯʴʴɳǱůíʿĮ¬¬íí¬óƶȸȶǳǳǱŬŪŪǪȩʫ̭ͰδͶηηͶ˴ɲȱ̵̵ͶͶͶͶͶͶʵʵ͸ӾԿƱoxczr]}hļƱʳʳ˴̵ͶͶ̵̵˰ŪȾŻƼȾȾǽ·¬ʴɵǳȴʶ̷ι̶ʴʴʵȱìƿĺ¼Įɳ˵ʴɳɳǱǱǱưǱȲɳɱʰɬǭɭǯɽ{xz}ľƮʶȵƳƲǴɳǰƯ¨ĪͳиϷϹϹͻ̺̼˻ɼȻȽǺǷ˹̹ʴëŧ¤ȪͯͯɯƬȰ̴̹̹ͺͺͺλλλ̹ͺͺͺλλλϼϽϽоѿѿѿѿѿѿооооϿξͽ˻ʺʺ˻ξϿϿξμμμμͻͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμоμͻ˹˹̺ͻͻ̺̺ͻͻͻͻμμͻͻ̺̺̺̺ͻͻоѻѻӽӽӽӽӽӽӽӽѾѾѾнннϼϼϼѾѾнϼλλͺͺλϼϼѾѾннϼλͺͺμϽоѿѿѿооҿҿѾѾѾѾннϼϼнѾҿӽԼտտӽҼѻкиѹҿҿҿҿҿҿҿҿҿѾѾѾҿҿҿѾнϼллϺιιιϺϺϺϺϺιιιιιѻѻѻѻѻкккϹϹѻѻѻѻϹϹккϹϹкѻҼҼϹϹθθθθϹϹθθͷͷ̶̶̶˵˵ʴɳȲȲʴ˵̶˳˳ʲɱɱ˳̴ζ͵͵͵ζζζϷϷθθθͷͷͷ̶̶˵̶ͷͷͷͷ̶˵θθθθθθθθ̶̶̶̶̶̶̶̶̶ͷθ̶˵ʴ̶θθͷ˵ʴʴ˵ͷθͶͶ̵˴˴˴̵̵̵̵ͶηϸϸϸϸͶ̵̵Ͷϸϸ̵ʳɲ˴ηйѺйϸͶ˴˴̵̵̵ͶͶͶηηηηηηηηιιιιιιιι͸͸̷̷͸͸ιϺ˶ɴȳɴ˶͸͸̷ϸη̵ʳʳʳ˴̵η̵˴̵ηйϸηʳɲɲʳ˴˴ʳȱĭƾĭʳϸѺͶʳȱʳηϸ̵ȱɲʳ˴̵Ͷ̵˴̴εʹ̳̳εʹ˲ɰǮǮȯʱʹε̳ʱǱƱƱŰƯƯǰǰƬǭȮʰʮɭȬǫŨú|vw{v{żäŦŨƬƮǯǯǯȰȰȰ˳ʲɱȰǯǯǯǯɳɳɳǱůíʿǼ·ʾ´ŵƶųűƲǱƭƫǬȫɪˬ̫ͮδͶηϸη̵˴ɲ̵˴˴˴˴˴˴˴ɴɴ͸Ӿлƾǲ͸˴ȱǰɲ̵̵ɲĭ¥¹ƼȯʴȲɳ˵̵Ͷ̴ʲ̴̵ʰùqopoqzɳʴɳʴ̶ɳȲǱǱǱɳʴ˳αʬǫɬūĹte~c~diwéʷǵĲıƳǱŮìĽwmiil|ʭδϷϹϹμͻͽ̼ʽɼɾȻȹ˺˸įüħȮ˱̵η˸̹ͺͺλλλλͺλλλϼϼϼнϽоѿѿѿѿѿѿѿоооϿϿϿξξ̼ʺʺ˻ͽξξͽϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμϽμ̺ʸʸ˹̺ͻμμͻͻͻͻ̺̺ͻ̺̺˹˹̺̺ͻоѻѻӽӽӽӽӽӽӽӽѾѾѾннϼϼϼнѾѾϼλλͺͺͺλϼϼѾѾнϼλλͺ̹̹λѾҿѾѾѾѾннϼϼϼҿѾѾнϼϼ̹ͺλнҿӻԼտվԾӽҼѻиииҿҿҿҿҿҿҿҿҿҿѾѾѾҿҿѾнϼѾҼѻкιϹιϷͶζͶζͶζͶͶѺййииϷϷϹθϹѻҼҼѻλθλϹϹϹϹкѻҼϹθθͷͷθθϹͷͷͷ̶̶˵˵ʴ˵ʴɳȲɳʴ˵̶̴˳ʲɱʲ˳͵ζ͵͵ζζζζϷϷθͺͺͷͷ̶˶˳ʵ̴̶ͷͷ̶̶˵θθͷͷͷθϹϹ˵˵˵˳ʳʳʳʳɲ˳˴˳ȱʴ˵ͷθͷ˵ʴʲ˳͵ζͶ̵̵˴˴̵ͶͶ˴˴ͶηϸййййϸηжжʹʱǮǮ˱δѷѺѹϷ͵˴˴˴̵̵̵ͶͶϸϸϸϸϸϸϸϸϸϸϺϸϺϸϺϸ̶˵˵˵˵̶ͷθ̶˲ȲȯȲʱȲȯηδ̵̲˴̳ͷ϶кϵ˴˱̵жҺҺȱƯĪ¨ɿƼ¸¸ƫʮβ˱ɯ˱ϵи̴Ȱɱʲ̴͵Ͷ̵˴˳ʹ̳˴˵̶̶ʴȲưƮǯ˲ε϶ε˳Īé©¨¨éêƬǮʰʱʰǮƫzmay[y[}_z\\cpĻ¥ƬƮƮǯǯȰȰȰ˳ʲɱȰƯƬŮŮȱǱȲǱưĮ©}~˾ĳĳðíŭǭȬɪȧɨ˩̪ͭͰͳͶηϸϸζ̵̲˱˱˱ʱʱʱʱʱīʴһѺʵîŽû­Űɴ̵ǰĭƯ˴˴Ůƾ~tqqtt¸ǭ̲ʳ˴̷̷ͷ˳˳͵Ͷʰɿ¶u{`wZwZvYz^iƾɱɱȰʲζʲɳȲǱȲȵʷ̶δˮǫȫũjtTrRrRyYj¥˵ǵĲðŲưîül`~[}[]nũͱδζθϼϼͽͽ̼˽ʼʼ˻ͻʷǿ}yxúĩ̲ηϸ˸˸ͺͺλλλλλλϼϼϼнннϽоѿѿѿѿоооξϿϿϿϿξ̼˻ʺ˻ͽξͽ̼ϽϽϽμμͻͻͻͻͻͻͻͻͻͻͻμμμμμμμμϽμ˹ʸɷʸ̺ͻϽμμͻͻ̺̺˹ͻ̺̺˹˹̺̺ͻоҿҿҿҿҿҿҿҿҿҿϼϼϼннѾѾѾннϼϼϼнѾѾϺιι͸͸ιιϺллѼѼι˶͸Ѽϸ˱ǮɯȯɯȮɯɯϵѺϸηϸйηӽҼҼѻѻккϹθϹккѻҼӽӽҺӻԼսսսսֽӻииϷ˴ͶѺҿѿμоѿоѿϽμооϽϽнѽмкѻи϶иԹϵеѴѴϱϰѳշежҷдͳ̲γзͷϸмҾҿѾνλ̻ͺλϼϼλι͸͸̷˴̵ηϸηͶ̶ѻѻ̶ʴͷͷɳθ˵Ȳɳʴʴʴ˵ζ˴ɲȱȱɲ˴Ͷ˴̵̵ͶͶ̵̵˶λͻʹɶȳȳǱɯưȮȰʲ̶ηιηиη͵˳ʴ˵͹κθθϷδ˰ɮʮʮȫȬǬȮɰͶ͸˶ȳʵ˴˴ʰʰ˯ͱ˴˴˴˴ͶηйѺɲɲ˴ϸӼԽԽһɯδ϶ͲɮǭȬȬ̰αѵҶϵ̱̳ε̴˴˴˴˴̵ͶηһϸͶηͶ̵̵Ͷ̶зѻѸϹѸҼҹϵϵδ˱ɭũç¦ɾǼźźƻɾʿèǫɰƫ©Ʈ̲͵γδͱͳϲееɯ|zstyɨʫ̬ˮ̯˰˲̳ηη̶̶̶ͷͶϷθθκ̹ʷʷʸ˺ɸǴƳǱǱŬ·¹ĹúŹɿŭ˲̴ɳĮye]tRreEpaBxiJteHzkN}b|úũǯǱưǱǯɱʲ˳ʰʰɯȮƭǫŬūɲǲŮǰȯǮǼ~idacrĴŮͽæƜȢǤɪͯʲ˴͵̴ʰʯʰͰȫͰαŧ˽ȺĵƻĨɮͳͶϷͷ̶˵ʴɲɲȲʳʵ̶ʴɳ˴̵Ůļ}ia}]xY|\\fṴ̶̳̹̹̃˸ͷ˵Ȱǰɯĸl~mQxgI|iI{hHmNxZvƬƪ˯̯ƩʰɱȲǱȴɶɹ˸ʶ˵ǰĨ·z]}oJzlGwiDznH~ZsɲǴƳƳȵɳȲƮ¨|eyVuPsOrN_tɮ̲͵ͷ̹̹̹̹ͺνϾпͼλʴĽsc[^dtʿ̱жη̹ʷȵȵɶ˸λѾͺͺͺλλϼϼϼμϽоѿѿѿѿооϽϽϽ̼ͽϿϿ˻˻˻̼̼ͽͽͽϿϿϿξξͽͽͽ̼̼̼ͽͽξξξξξξξξϿξ̼˻ʺ˻̼ͽϿϿξξͽͽ̼ͻ̺ʸɷʸ̺μϽоҿҿҿҿҿҿϼϼϼннѾѾѾѾѾнϼϼϼннϺιι͸͸ιιϺѼлллϺ̷˶˴̳ŪȾƼŻŻĽç˯ѷѷѷӹӹҸҼҼѻѻѻѻккϹϹкѻҼҼӽӽӻԼսս־־־սҺζ̴ζη̵жӼҿѿμѿѿоμͻͻϽооϽϽμϽнѽкϹ϶ʹ˰˰̯гϰΰϮ̬˨ͪЮΰγдѴдгееεϸѼҾѿνͼͼͼϼϼϼϼιιι̷˴˴̵Ͷ̵˴˴иθɱȲ̴ͷ˲ͷ˲ȲɰȲɰɳʲ̵˴ɲȱȱɲ˴̵˴˴̵̵̵̵˴˶ʸɷȷȵǳǱȯȯƭǭǭʯ̳ηιηѹжζ̴̶ͷϺлͷ϶ϸϳ̲̰ʭ˭ǩȩȫǬȯʱ˴ʵȳɴ˴̲˱ʮˮͱ̵̵̲Ͷηϸϸϸ˴˴̵ϸѺѺη˴ȮɯǬèæŨɫͮѴԶѷϴ϶зζ̵̵̵̵ͶͶηйηηϸϸͶ˴˴ƭǬȯɮ˲ͲεͲ˰ȭèʼĶ¸÷ǻéɯʰ˰˰ͰαϲѳҴūzqh`}X}UYbluŻȧ˫ȪƩȯͳͶͶͶ̶̶ͷͶͶ̶̸̹˸ȶƵĴŵʺƴ¯̽Źĸȼëɱ˵ȲðzdyVzkJm^=l[=p_AjY=teHy_zƿūƮǱǱȲɱʲʲʲʰʰȯȯǬƫŪŬǰŰĭƯǮƫ˿ƻo}\\wUuQvR`wôͿêͽǷɸŶƧ̰ʲʳ̴̴˰˰ˮͰ˭ϯ̭³zt|ƻƪ˯˱ʲǱȲɳ˵˴Ͷͷη˶ͷ̶˵Ͷϸɲu_vUqQnNrR|Z~Ǩϳϵηλͻ˷˷ʴǱǰɯĹlmOzgG|gH{gFkKvVsȾĩħȫ˭ɫʭȮɰǱǴɶɻʺȸʶƱéʿw~WzlEvi?sf<ymEYs£ɲȵȵǴƳŲưƮŮh|YvOsMrLtPeȺȬͳ˳ʴ˸̸̸̸͹κмѽμϼ˵Ľm}YvOuM|UfĶŪ˲˴ȵȵɶɶʷ˸̹ͺͺͺͺλλλϼϼͻͻϽоѿѿѿѿѿѿѿооϽϽϽ̼ͽϿϿϿ̼̼ͽͽͽξξξϿϿϿξξͽͽͽ˻˻˻̼̼̼ͽͽξξξξξϿϿξ̼˻˻˻̼̼ͽͽͽͽͽ̼̼̼̺˹ɷɷɷ˹ͻμоҿϼϼϼннѾѾѾҿѾнϼϼϼϼϺιι͸͸ιιϺѼлϺϺлιȳ«ŻĪδжѷӹԺҸккѻѻѻѻҼҼкккѻҼҼӽӽӽԾս־־־սսй̵̲δϵδжԽӽϼͺнҿѾѾϼϼнннλѾннѾԾӻҺиϷδ̲̯αɫťƣáſáŧƫʮϲҶӶҷϴεзкҼѾѾννϼϼннннϺιϺ̷ʳɲ̲ͳͳ̲δϵ˴Ȯǰ˱̵̲ʳʰȰǭƮǭɱɱͶ̵ʳɲɲʳ̵Ͷ̵̵ͶͶͶͶ̵̷ȵȵȵȳưǮƮƬƫǫǫɮʱ̳ϷϸҺжϷ͵ͷθллͷ϶ϸд̲ʮŨĦêĮưǲɴ˴̲˱˯ˮͱͳͶϸййϸηͶͶͶηййͶǰìüµɪгӵѷѶҹӺϷηηηηηηηηηηηййͶ˱ȭĨĨƬȬūũʼƸzuttwvusty˿§ŪˮͰϲѳѳſwj^xTtMpJqKuOzS|W[ivŻȧήʬǪɰε˵˵˵̶̴̵˵Ͷθθθ͸˷ȵǴƳɷïʻ{tllnrzŹɽëȰɳǱðiuSsdEk\\=iX:iX:iX<teH|b}¸ȮŭǱɳʴ˳˳ʲʲʰʰȯȯǬƫƫƭŮîìŮǮŪ˿źlyXsQoKoK~XoȽ¨ɻ²ymgjtÿȭȰɲ̴̴̱˰ˮ̯ΰаʫźwh_}[e{ʮʰȰưȲ˵ͷηϸθηʵ̶̶˵̵ϸʳìu~\\rQmMkKpP{Yzȩѵѷϸλ̺ȴɵɳǱǰɯĹmlNyfF{fGyeDhHqQqɿŪæŨȫȫȫǭǯǱǴȵȺɹȸʶƱ¨ɾv}VxjCre;oa:wkCZvĥȱʷ˹ȶŲ®íŭŮi{XrK~lF|jDnJ^|ĶȬϵ͵ʴ˸ʷ˷̸̸κϺϼоѾθlxT}nGoGvO_yƫεϸȵɶ˸̹ͺͺ̹˸ͺͺͺͺλλλϼ̺̺μϽоооϽооооϽϽϽϽͽξϿϿͽͽͽξξξϿϿξξξξͽͽͽͽʺʺ˻˻˻̼̼̼ϿξξξξϿξξͽ̼˻˻̼̼˻˻˻̼̼̼̼̼˹ʸɷȶɷʸ̺ͻоҿϼϼϼннѾѾѾѾнϼλλλϺιι͸͸ιιϺѼлιιѼϺįzkfehr}ž˱ϵжѷѷϸϹккѻѻҼҼӽкѻѻҼҼӽӽӽҼӽӻԼԼԼӻӻӼϵͳδδ̲ϵԺҽտкͷϹѻϹԾҼккҼӽҼѻҼӽԾӽкϹкѻӻԺӻжжѵϳˮŨúõɾȫϴԷѷϴ϶϶кѻннννннѾѾѾнϺϺι̵ɲɲ̲δϵδ˲ʯǮŪƭǬǮǫéƪƬŨéǪȮǭ̲˴ʳɲɲʳ˴˴ͶͶηηηηͶͶʴʴȳǰƭŪĪĨƩǪȫɬʯ˲ϵзжϵζ͵ͷͷιϺθ϶ͶͱǭŷǼ¬Ʊȳ˴̵̲˯̰ͱδηйѺѺϸ̵˴ηηйѺй̵Ů}slowø¤αгжҷӺӺиϸййϸϸηηͶηͶ̵ϸһй˲ɭʿĶõ{z}xqlk~ax\\yoTvlQ|pVz`jpç̯ϲϱͰ¼vi_{XvRvRwPxQwPsMsM}YfȽǨɬʭʰ̳ɳʴ˵̶˴̵˵̵иζ˶ʳɳɳǲƯĭͽ|qke`dmuʾŭȰɳǱ¯ĹsyWufGo`Am\\>iX:m\\@udHx^zŹūŭǱɳ˵̴̴ʲɱʰʰɰȯȭǬǬƭŮįĭƯȯƫ˿źn{ZsQoKnJ|Vlúƺo]VXctĪƯȱ̴̴̱˰ˮ̯ΰϯȩ~hvVoN~nLxUjĹȬ̲˳̶ͷϹкηͶɳȱƱɳɳȲɲ̵ɲìy~\\pOkKjJqQ|ZsǨҶѷηͺ˹ƲȴȲǱȱɯĹm}jLvcCxcDvbAzcC~kKnɿƫħæħŨƩūŭưǳǴǷȸȸʶƱ¨ʿv}VykDre;n`9uiAYw£ǰ˸̺ɷð®ůƮn~[~pKygAuc=}kGwVnɾɭ˳ɳʵɶʶʶ˷̸ιϺоҿѻǭs|X~oHnFtM\\vȭзһ˸˸̹ͺλλλλ̹̹ͺͺͺλλλ̺ͻμϽооϽϽоϽϽϽϽϽϽϽξϿϿξ̼̼̼ͽͽͽξξξͽͽͽͽͽͽͽ˻˻̼̼̼ͽͽͽϿξξͽͽξϿϿξξͽͽ̼̼̼̼˻˻˻̼ͽͽξξ˹˹ʸʸʸ˹̺ͻϽҿҿҿҿϼϼϼннѾѾѾѾнϼλλλϺιι͸͸ιιϺѼѼϺ͸ллî}juY}rVtXx\\k{ȾͳҸййѹϷϹккѻѻҼҼӽѻҼҼҼҼӽӽӽкѻѻҼѹѹϸϸҸ̲ƭƫŪŪɮϵжӼӼϸ̵ηϸͶη̵˴̵ϸѺѺйηϸйϸͶ̵ͶжжҶϵ˯ʯͰɬvsqhhmz̯ҵжϴεεθϹλλλλѾѾѾѾѼлϺιͶ˴ʳ˱ͳϵжεɾŹĹĸø¶ĻȾüüçƬƬūūūūƬƬʰʰ˱˱˱˱ʰʰƮūé¦ȽŨȫȫʮͱдδͳ̴̴˵˵̷͸θε˴ɭpmr{ʿíư˴̵ͳ̰ͰαδηйѺйη˴ʳͶηйѺѺͶǰérc{^~^iuȽˮαͳеѸθϷϸйѺййϸηηη̵ʳͶһϸǮȺ{zrpnuzõĶĶ´~xtku[uiOrdJtfLykQ|nTu[kȫϲϱ̯vnid]\\[|WuO~rLzWcjrɾƫȮȰƱȲɴʵ˴ʴʲ˲ϵ˱ƯƬĬĪ¨ȸxka{_{]ak{ƻȽūǭɱʲɳư¯ƽd~oRufIp_CjY=jY?kZ@xhNjǽĬưɳ˵̴˳ʲȰʰʰɰȯȭȭȭǮǰƱƯȱʱǬ˿źkwVpN}kG|jFxRhƿƼ÷pWPNZk~ƿĭǰ˳̴̱˰ˮˮ̮̬Ƨ{anNyiHwgE{mJzZr¦˱̴θϹккη˴ǱƯŰɳʴȲȱ˴ʳŮºwzX~jI|eE|eEkKwUmŦѵж̵˸ɷƲȴɳȲɲʰĹkzgIs`@u`As_>v_?yfFd~¥¥æƩçéĬůŲƴƶƶȸ˸Ǵ«·yY}oHvi?pb;sg?{UrƱʸ̺ɷıïǱʲ¦~hxS}kEvd>t`=|iHzYq¸«Ǳɴɴɵɵʵ˶̷͸˹ϼѻʰ·{^tM~lD~oHxTnʱ̵ͺ̹ʷɶɶ˸ͺλ̹̹̹ͺͺͺλλμϽϽооооϽμϽϽϽϽϽϽϽϿϿξʺʺ˻˻˻̼̼̼̼ͽͽͽͽͽͽͽͽͽͽξξξϿϿϿξξͽͽͽξξξξξξͽͽ̼̼̼̼ͽͽξϿϿϿ̺̺̺̺ͻͻμμϽҿҿҿѾннϼϼϼннѾѾѾҿѾнϼϼϼϼϺιι͸͸ιιϺлҽл͸ϺϺîx}b{mRwlPynR|qUewѷջӼһԼӻккѻѻѻѻҼҼҼҼҼӽӽӽӽӽϹϹккиϷͶͳǭƿ÷ɿũ˯δ̰̲βδ˯δ̰̲ͱжҶҸҶжҶӹҶждѷҶҶԷеʭʭ̮ƨȻs_~Y|WtOrNyVgvǼȫͰϲϴʹʹ̶̶̹̹ͺͺѾѾѾѾлϺι͸η̵̲̲ͳͳ̲ɮüž»ƿƿƿƿƿƿƿƿéĪĪūūĪĪéſ½úåŨʮβ̴̲̲˳˵˵˶˶θεʳȬʾs_{[}]gr}Ǽ¬ư˴Ͷͳ̲ͰαͶͶηϸηͶ˴ʳ̵ͶηййͶȱūi{[uUvVanƻʮͰ̲δθʴ͵ͶϸѺѺйϸϸ̵ϸͶɲ˴ηƯùuiba|[|^bu~´ǹ̾Ϳ¥ƩȫŪ̾õqu[rdJi[AfX>gY?eW=wkQqĨϲϲ̯Ȯçĺ}{ztogZvPtQzW{Y]i}ƭȮĭƱȳʳʴʴʲʱѷͳɯƫūʺŶrdzZvYy[}]o{źåũƪɯɯʲʲɳưðê¹s|_xiLn]AiX<fU;dS9l\\Bu[{ǻĪĬůǱɳʲʲɱȰʰʰɰɰɮȭȭȯɲȳȱʳ˲ǬɽøhuT~nL{iE{iExRjſƿƼ·rWO~LTdw¸êƯ˳̴Ͳ˰ˮˮɫɩŦ{}^~kKwgFscAqc@xkKaǭʲ˵̶ͷθͶ̵ʴʳǲ̶ͷʴɲ̵̵ȱŽxyW|hGzcCzcCiIsQiĥϳδ˴ʷʸȴʶʴʴʳ˱ĹgvcEo\\<r]>o[:r[;s`@~pUiƿħéůŲųŵŵǷɶƳìø{]tM{nDse>rf@tQkƱȶʸʷǴŲǳʴȰŨúq~Y|mFvd>nZ7s`?~kK|]užɱǳȳǴȴɴʵ˶̷ǳʷθʰĹ~`tM~lD|mFtPhǽǮȱ̹ʷǴŲŲǴʷ̹˸̹̹̹ͺͺͺͺϽϽооооϽϽμμμμϽϽϽϽϿξɹɹʺʺʺ˻˻˻̼̼̼̼ͽͽͽͽξξξϿϿϿϿξξͽ̼ͽͽͽξξϿϿξͽ̼̼ξξξξξϿϿϿͻͻͻμμμϽϽμҿҿѾнϼϼλϼϼϼннѾѾѾѾѾнϼϼϼннϺιι͸͸ιιϺϺԿӾ͸͸ιįw|_yjMwiLwiNujNv\\nȾηӼҼӽտҼҼѻѻѻѻккӽӽӽӽӽӽӽӽккккиϷδͳŻ{w~ƿçǪǫŨɭȫƪǪɭˮ˯ʭʮˮ̰̯ʮʭ˯̯Ͱвβɫ˭а˫̽pyWtPqM{iC{iCpL{\\qȽǪʭαг˰˰ʲʲʵʵʸʸллллϺι̵˴ϸηͳͳ̰ȬĨɿ{kedcfjvƽȿĻĽžžžžžžĽ¨¨¨¨Ľzttto{ƪʯ̲ͳ͵͵̶̶̷˶̶ʹ˴˯és~]wVvW}`iuȼ¬ů˴ͶδͳͰͰ̵̵̵̵̵˴˴˴̵˴̵ͶͶ˴ǰū|dwWrRrP|[iƻ̰α˱ͳ̶Ǳʲ˴ηйѺѺйϸʳϸϸ˴ʳǰq_vVwUwWzXerƻ¤ƪ˯ǫʮβѵϵͱǭĪk{mSk]CgW>gW>j\\B|pVuũϲϲ̯ͰʮŪźƹp]vPrMrNtS|]mƺ¬ĮưɳʴʲȱȰβͰʮɬŧȻlg_wVuS{[fnƽȩʭʭɮʯȭȭɰʱȲǱůŬǪſo{kQjY?fU;eT:dS9hX>zjPgèĬůưưǯȰȰɱʰʰɰɰɮɮɮɰɲɴȱʳʱŪƺerQ|lJzhD{iExRjſƼ·pX~O|KSas©Ůʲ̴Ͳ˰ˮˮɫȨŦzyZyfFscBp`>k]:obBxX}ūɱȲɳʴ˵˴̵̶ηȳͷθʴȱ˴˴ȱ{{Y~jI|eE|eEjJsQhäϳδ˴˸̺ʶ̸ͷ̶̵̲ødr_AkX8oZ;mY8nW7p]=ugL~rXgu~úƿ¨îıųŵĴĴǴıĹ}_vO}oHugBqe?{nKf¥ŰƴǷȸɹ˸͸̶ŭūy^~oHuc=o[8r_>yfFqRe~ëƲǲǲǲȳɴɳ˶ɵ̹ϹʰĹ}_rKmE{lErNfǽǮɲ˸ʷɶȵȵɶʷ˸˸˸̹̹̹ͺͺͺμμϽϽϽϽμͻͻͻͻμμϽϽϽϿξʺʺʺ˻˻˻̼̼˻˻˻̼̼ͽͽͽͽͽξξξϿϿϿϿξͽͽ̼̼̼ͽξξϿϿϿξ̼˻ξξξͽͽͽͽͽ̺̺ͻͻμμμμμҿҿҿѾнϼλλͺϼϼϼннѾѾѾннϼϼϼнѾѾϺιι͸͸ιιϺιԿ͸̷ιŰ}d}nQ{lOxjOugL}qWiùʳϸϹкԾտӽҼҼѻѻккϹӽӽӽӽӽӽӽӽѻѻѻѻиϷδδ|od|_bi~ƿĽƿüüüü»üĽü»üĽŧŧ¤Ȩѱ̫Ƿu{WtPqL}iD}jBsMxZqʿƪɬ̰ѴʯʯɱɱȳɴɷʸϺллϺι͸˴˴йϸδͳʮĨĽsx]oT~mQnRuX}`rú£ĥǾ¨¨¨¨éééé¨¦ƿuh^|Y|Y\\i}Ĩȭͳδζζθͷ͸̷˵̵̳ϳɯǼzc|YwX}^gqȼů˴ͶδͳͰͰ̵˴ʳʳʳ˴˴̵̵˴ʳʳʳɲŮĪ|byYuSuS^mȽβϲ̲ͳ̶ưǰɲͶйѺѺййǰϸһͶʳ«u|^pO|iHoNuT}\\oź¤ʬ̮ɫǩ˯д˯ͱδϵϵδ˱ʰγƫe|nTxhOyiPqWgɭϲͰʭ˯̰˰ʭǫŧĤƣ ̿ʽƹq_|WlInLuV~`l}íưɳʲʲȱȰçħæäʼwh{YyWvStQxVbvĻȩίαˮʯ˰ŪŪǮȯǱǱǱȯαĤĻz}oThW=fU;cR8cR8fV<p`F}oTiŻŭĮĮůŭǯȰɱʰʰɰɰɮɮɮɰɲȳȱɲȯèĸy_|lKvfDvd@weAtNgſülW}N{JQ`oŮʲ̴Ͳ˰ʭʭɫȨŦxuVtaAo_>o_=i[8m`@vV|Ƭʲɳɳɳɳɲ˴˵Ͷǲ̶̶ȲƯȱȱƯzyW|hG{dDzcC~gGpNhĥϳδ˴ͺμ˷κθͷͶ̲ø~ao\\>iV6mX9kW6mV6n[;ueKuiO}rV}ajwžƿ¨ìıŲĴĴı¯˿ø}_vQ~pIvhCpd>xkHbŨŰųŵǷ̻λϼϸǱʰȫżfuQyjCo[8q_;ubBxiJsVmƲűƱǲǲɴɳ˶ͺнҼ̲ź}]~oH|jBxiB}mIaĺŬǰ̹ͺλϼλͺ̹˸˸˸˸̹̹ͺͺͺͻͻͻμμͻ̺̺ͻͻͻμμϽϽϽϿξ˻˻˻̼̼ͽͽͽ˻˻˻̼̼ͽͽͽ̼̼̼ͽͽξξξϿϿͽ̼̼̼̼̼ͽξϿϿξ̼˻ξͽͽ̼̼˻˻ʺʸ˹̺ͻͻͻͻ̺μѾѾнннϼϼλλͺλλλϼϼннннннннннлйѷййϺϺ̻̻νѾн̷˴˴ƬȾhx[whKsbHxgMueLt[}ųȵǴϻտտԾӽкθ̶ӽӽӽӽӽӽӽӽҿѾѽѽѻѹθϴɻpvXlN}jJkLmMbrý~|yyyy{~˺ū˲ʳǰĴosYkRiMiMhLuZrŴ̼ū˱ʰɮɮɮ˰ͳϵжѷӼһѺйηͶ̵̵ηϸ̵ȱǰǰĭȾqvTwgExeEtaAyeJy]rɻǽ©ūū̱ŨƩǪȫɬɬɬɬʭˮˮɬƩŨȫʭŢȻhvRoK|lH{kGpN_xĽƮͳδиѹкϹ͸̷ɳε̵ɭǭç{[yQsMuN|YjľƩʬͳϵ͸̷˹̸ͷεεεε̳˲˲̳˲˲̳ʹ˲ǮçwaxVrQsR~]kͿͲʹ̶̶ȶ̸Ϲ˳ȰʲжӹҸϵɮͲϳβǫz|_yfEyeBvcBvcB~nMeʽи̴Ȱɱ̴ѹҺҺϷиѹҺҺѹиϷ͹ʶʿ~nknzưϹӽϹɳ˴˴˴˴˴˴˴˴ϸηɲpsYwgMsdG{lOtV{]nźŨǩƬʮɰƨǣվ˵ízhZxRwhAzkD~pKyTbsèƯɲ˴ʳʳ˴̵ǰììƯǰŮǰʳƯƯǰļzpWh\\Bh\\Bl^CcU:aR5gX;p_A~mOnúȥ˭æƿĭȵıǵǳȴɰɰʭȬȫʰɯɯʬǪtyV}nMvgFveIyhL~mSpǾ·lZyRtMzSboĵªŮɱ˳Ͳ̱ˮʭʬȨĥ·ztUp]=jZ9iX<eV9eW:ujLpǪ˭ˮˮɬɬȮɯɰ˱ǫˮˮʭ˯β̰ǫʽzxWxiHtfCseBvgF|mLg˴ͷмҿѾɺ˺˸ƴȲĮ}^jY;aQ0gT3jW6lZ6q^=s[?zbF}hKkJpO|Yfpķ˾æŪūŬƭƯêľƿ¹csRufExiHqbAylLgǰůĮǱηйεʱ˰ȮǫĨwsVubDj[>oaDtiIujJqiEzrNi½ɫγưðȸ˿ǻǼϿǳõ|btRmHxdAzfE|^ıɷ˸̹λϼϼλ̹˸ͺͺϼннϼͺͺʸʸʸʸʸʸʸʸʸ˹̺ͻϽоѿϿξͽͽȸɹʺ˻ͽξϿϿϿϿξͽͽͽξξξξ̼˻̼ͽξϿξξξͽͽ̼̼̼̼ͽϿϿξͽʸʸʸ˹˹̺̺̺ȶȶɷʸ˹ͻͻμ̺ѾѾѾѾннϼϼϼλλλλϼϼннннннннннлйѷййϺϺͼ̻νѾн͸̵̵Ȯjx[ufIq`FtcIp`G~nUsʿȵʷϼӿҽտտӽкθӽӽӽӽӽӽӽӽҿҿҾҾѻѹϹеrvX}jL{hH}hI}jJz\\o·ǼǾáȦƠ~|{xvrqprrx̾ìŮͽ{dqVlOiLiMnSi˻ǭͳ̲ʯɮʯ˰δѷӹԺһѺйϸηͶ̵˴ʳ̵ʳǰǰɲƯx{YyiGyfFvcC|hM{_t̾ŬȮǭ̱ȫɬʭˮ̯̯̯̯ɬʭʭȫƩƩɬˮɦ˾iwSoK|lHzjFrPb}ǻçƯʲͳδϷϷϹθ͸̷ʴε˴Ȭū¦|~ZxPsMuP|YiľŨɫͳϵιιͻκͷεεεʹ̳˲ʱ˲˲˲̳ʹ̳ȯũw`wUrQrQ}\\i˽˰˲˵̶ȶκк̴ɱ˳жҸѷδʯγϳȬƻk}oRscBubAvcByiHyXrťҺϷ˳˳͵ϷϷζ˳˳̴̴̴˳˳ɲ͹̸ƲøíʴϹѻθɳ̵̵̵̵̵̵̵̵˴̵ʳŮ«ļkqWteHvgJ|kMpRz\\h|Ǿæūɮʱȫμư}sgYtNpIzkDsNZi{ƼģȬɲ̵̵˴ʳʳ˴ȱŮĭǰǰĭĭǰ««{yoVi]Cl`Fn`EfX=cT7fW:iX:p_AvXpƿĽžĭƱðñİůǮǮǬǪǪȮǭƬǩŨuyV}nMufEudHyhL~mSpǽĻvcYyRvO}Ygx̽īŮȰʲ̱̱ˮʭȪƦĥøztUp]=iY8hW;eV9fX;tiKjƿĦǪƩƩŨūƬǮɯĨǪȫƩǫɭǫŸutSteDqc@qc@teD{lKi˴̶κѾн̺ŴǶǴĮ}^jY;bR1hU4iV5lZ6q^=kNuZ|_|]{Z\\dhrzɻèīǮȱŬ}_pOrcBvgFpa@wjJfƯưůǱʳ˴ɰǮǬǪƫçrrUubDiZ=l_?peEqgDoeBtlH]s¤ʰǮðǷʼƺʾ̾˼®ycyTqLzfCyfE|^øƳ˹˸̹λϼϼλ̹˸̹ͺλϼϼλͺ̹ʸʸʸʸʸʸʸʸ˹˹̺ͻϽоѿѿϿξͽͽɹɹʺ˻ͽξϿϿϿξξͽͽξξϿξͽ̼˻˻̼ͽξξξξͽͽ̼̼̼̼ͽξϿϿξͽ̼ʸʸ˹˹˹̺̺̺ʸ˹˹̺ͻμϽϽͻҿҿҿҿѾѾѾнннϼϼϼϼнннннннннннлйѷйϸϺϺͼͼνѾѾιηϸ˱ĩnx[sdGn]Cp_EiY@vfMwbǱ͹ҽѽ͸ҾԾտҼкҼҼҼӽӽӽӽӽӿҾҼѹϹеǭrtVzgIxeEzeFzgGxZrǩɪ̬ϯϬͧǤşÿ}rkf``eq˿ƮȮ˻sx]kNgIfJjOz`tŵũʯ̯ɬɬʯ˰ͳжӹջййϸηͶ̵˴˴ƯȱȱƯǰʳɲĩµ||ZyiGyfFvcC|hM{_sèǮȮūʯɬʭˮ̯ͰαͰͰɬɬɬȫƩǪɬˮ˫jwSoK|lH{kGsQeøéʮ̵Ϸδδζζͷͷ͸͸˵϶ʳƪ¨ʿz|XwQsOuP{XiſħȪ˱ͳ̷̷̸͹ͷεεʹʹ˲ʱɰʱʱ˲ʹεʹʱǫx`wUrQrQ{Zeǹȭȯɳ˵ɷмѻζ˳̴ϵжϵ̲˰еβʿr~sWn`Cm\\>m]<rbApQi˾ͭҸжͳ̲ͳͳ̲˱ͳ̲̲˱˱̲̲˴ȴʶʶİǼ·ºŽíʴϹθθккͷηηηηηηηηɲ˴ʳɲʳɲ«¸j|nSugJvgHvgHzkLpQdvúĩīzj^yTqMnJpLyTbt¸Ġʦ̰ͬͶηη˴ʳʳ˴ɲƯƯȱƯ«ɾȽŻuymUk_EnbHn`EhZ?fW:gX;fU9fU9sbDtUqƼ®Ƚ­ìūūũŨũūéåæ ĻxzW|mLteDtcGxgK}lRmƺøm\\}WzT|WcsȷƫŬƯǯȰʯ˰ˮˮŧĤäø{tUo\\<hX7gV:eV9fX;odF}_}½Ľžɿž¥žl{lKm^=l]<n_>sdCyjIkʳʴ͹нϼʷįŰĭȽ˿}^kZ<cS2hU4hU4kY5r_>y^n|xmgefdjwƸ˽ŬȱȯéxxX{lKo`?sdCn_>tgGb}ǾìŲǳǳƯĭīŬŪŨħ˽koRwdDm^?m`@obBoeBndAqgCuRa¦é¯ǵɹǹ˽̼ȷȼtb~YvQ}iDzgF~_ǽʵͺ˸̹ͺλλͺ̹˸̹ͺλλλλͺ̹˹˹˹˹˹˹˹˹˹̺̺ͻϽооѿϿͽͽ̼ʺʺ˻̼ͽξϿϿϿξξͽͽξϿϿͽ̼˻ʺʺ˻̼ͽξξͽͽͽͽ̼̼̼̼ͽͽͽͽ̼˻ʸ˹˹˹̺̺̺̺ͻͻͻμϽϽооͻҿҿҿҿҿҿҿҿҿҿϼннннннннннннннлйжϸϸιϺνννѾѾϺйѺδǬĶry\\rcFm\\Bn]CeU<p`GufOmǿͺӿҽ̷ϹѻԾӽѻѻҼҼҼҼӽӽӽӿӿҼѹϹеȮopRwdFvcCxcDxeGz^vȪβϯͰаӲЭ̩ͬ˫̩ʪɦȿĻ}tkjozȮʰŪƵckM{`By^AjNrWdvƻŨǫȫɬɯʰʰͳжӹϸϸηͶ̵˴˴ʳŮǰǰŮǰʳȱèxzXyiGzgGwdDzfKw[qͿèǮƬ¨Ūȫɬʭˮ̯̯̯̯ˮʭɬǪƩƩȫȫɩ̿hvR~nJ}mI|lHqOdƻƬͳͶϷδδ͵̴˵˵͸͸̶϶ɲĨ˿Ǽv{WwQsOuP{Xi ħǩɯʰɲȳȴɳʹʹʹʹ̳ʱɰȯɰɰʱʹ϶ε̳ɭy`wUsRrQyXc{ĶŪŬȲ˵ʸѽҼи͵͵δδͳ˱̱Ѷ˯yy]odHeW<fW:gX;o`CuXu¥˫ʱʰɰʰʱ˱ʱʰεδ̳̲˲δε϶íƲȴǳï­įʴϹѻθθѻӽҼηηηηηηηη˴Ͷ̵ʳʳ̵ǰiuZ{mPwhIvgHxiJ}pP{^tyi~[vRrNrPyW_nzƾƥ˩ʩ˫̵̲ηͶ˴ʳʳ˴˴ǰƯȱŮǿļŽɾǽ¸rymSl`FmaGl^Ci[@j[>j[>iX<gV:n]?xiJ`qŹƻǿ«ĪĨĨŨéſýĿ¥áǾºyzWzkJrcBraEveI{jPjĶwh[zW~[crʯƭƯǯǯɮʯ̯̯åã£ø{sTmZ:eU4eT8eV9eW:i^@|qSlbrcBgX7hY8l]<rcBzkLmɲɳ˷νλ̶ŮƬ¨ĺȾʾ|]k[:fV5jW6gT3jW6taAd~xqkcfmu³øƭǭũstTyjIo`?sdCl]<pcC}]wıȵǳí«īǬȫħȿ|^lLyfFsdEpcAob@qdBreBrhD{qN{XnüƳȷɷ˻̺ǳŹqbZ|UnI~kJc̷ϼ˸̹ͺλλͺ̹˸̹̹ͺͺͺͺ̹̹̺̺̺̺̺̺̺̺̺̺ͻμμϽооϿξͽ̼˻ʺ˻˻̼ͽξϿϿξξͽͽͽξϿͽ̼˻ɹɹʺ˻̼ͽͽͽͽͽͽͽͽ̼̼̼̼̼̼˻˻˹˹˹̺̺̺ͻͻͻμμμμμϽϽμҿҿҿҿҿҿҿѾннннннннннннннлйжηηιϺϾϾνҿҿлѺһϵȭƻtyZsdEo^Bp_CeT:l\\ChYB~rZ~ȲҼһη̶θѻӽԾӽѻккѻѻҼҼӽӽӽӿҾѻѹθϴūk}lNubDubBxcDxeGz`x´ʮжгβвնӲбЯваϱήȫ˫̯̭ǪǾùƫɮʰɮξjmNv_?s\\=gK}hMnSczƽŨɬ̮ͱͱ̰̰ʹзϸηηͶ̵̵˴˴ƯȱǰĭŮȱƯsxV{kIlL{hH{gLvZrŪȯƬĩǭȮɯ˱˱̲̲˱ͳ˱ȮƬūĪĪĨĤǺesQ}mK}mK}mK|lKaźū˱˴̴δͳ̴˳ʴ˵̷̷˵εɲçʾĹqyUvPsOuP{XháǪʬ˱ʰȱǰǳȲʹͲͲ̱˰ɮǬƫȭȭʯ̱ϴγ̱ɭx_wUsRrQxW`x´èŬȲ˵˹ѽӽѹϷ͵ͳͳ̲˱ͲеƪivkOi^BcX<bT9dV;n`Ey]|ɾȼȾ˿§¨ŪƬȭɯɮǭǬƬȭɯ˲íĮưǱůí«Ʈ˳ζ̴ʹѸԻӺηηηηηηηηηйη˴ʳ̵ɲūƪr}_}oRxiJxiJsdGtfIqVk~p`wUoNpNtR}\\jwƽǥʪ˫ʪȫʰʳ˴˴ʳʳ˴Ͷ˴ǰƯƯìŽºûɽ¶mxlRm_Ek]Bk[Al\\Bn_Bo`Cn]AkZ>n]?raCqRaw´ʾëëĪŨŨħ¨ľ½¥ĢȿûyyVyjIpa@q`DtcGwfLeuke`_gtʿŪȮǮǰȰȰʯ˰̯Ͱåã£·yqRkX8cS2bQ5cT7bT7eZ<ujLcw}~^n_>dU4gX7l]<sdE{lMlɲɳ˷ͼ̸˳Ĩçžźz[k[:hX7lY9gT4kX8udFkɹɹvlighozƬƪæuvUyjIpa@teDk\\;m`@vVpļ°ǵǴĮíǯ̲̯æitR|iH{hGufErcBqbAtfCvhEviF{nKuQ\\nĺìɵ̷ȵ˵ưźm]~VXtNsOiīͶкʷ˸̹ͺͺ̹˸ʷ̹̹˸˸˸˸̹̹̺̺̺̺̺̺̺̺̺̺ͻμμϽооϿξͽ̼˻ʺ˻̼̼ͽξξϿϿͽͽͽͽͽξϿξͽ˻ɹɹɹʺ˻ͽͽͽͽͽͽͽͽξͽ̼̼˻˻˻˻˹˹̺̺̺ͻͻͻͻͻͻ̺̺̺̺̺ͻѾѾѾѾҿҿҿѾѾѾѾнннннннннннлйжηͶ͸ϺϾϾҿҿлѺһϵȭøqvWrcDraEsbFgV<l[AdT;sdMiºʲϹθ˵̶θϹкккϹкккѻҼҼӽӽӿѽкϷ̶Ͳ¨h|kMvcEwdDzeFyfHu[uǭзѵҸԷ׺ոѴгϲϲͰˮȬ˯Ͳϴγʯĩ¥ŨƩȫɬɮɮɮʭ˯˭jpPvbAs^?wbEr^CraEpTi}Ǿȩ̯гѵϳβεзϸϸηηͶͶ̵̵ƯȱǰĭĭƯĭɿryWoMrRnNkPx\\véǬʱȮéƫɯʰ˱ͳͳδδͳͳʰǭūūūĪçö~aqO|lJ|lJ|lJzjI`·éȮȱɱ̲̲˳˳˵ʴ˶˶ʴεɲçɽktPrLqMsNxUgáʭ̮Ͱ̲ɲɲɵ˵ʹͲ̱˰ʯȭƫŪǬǬɮ˰ͲͲʯȬu~\\tRqPqPvU~\\vèƭɳ̶ʸмҼѹиζͳ̲̲˱̱̱Ƚw[laEf[?f[?aU;bX?ocK|a}øƺɾ˿ɾǻƻŹŹĺźȽĮůĭ«Ĭɱ̴ʲ˲϶Ѹ϶ηηηηηηηηηѺѺηηйη̲δȫta~qQyjKpaDiZ=k[BxjPxc|fs`wkUwhKvgF{jLuVaożƦɫʬ˭̮αʰʳ˴ʳɲɲ̵η˴ƯììûºǼɽeugMj\\AgY>o_EscIyjM|mPziMtcGo^@l[=udFpQdxŷĬ«ëĬĪĩèèëľþæƤȿºwwTwhGo`?p_CraEsbHy_qtwrgbeis}ɾƫɮƭȱȱʲʲ̱ͲͰαŧĤw~oPhU5aQ0aP4aR5aS6eZ<xmOh|½Ŀ½Ľü`o`?eV5gX7k\\;rcDzkLj˴ɶ˸̻˷ʭãƿ~wXjZ9jZ9mZ:gT4lY9yhLs˿źõvogbdku~ƿ¥µv{ZyjIpa@ufEk\\;j]=}rRkûȿƶǵŲƮʰϳ̯ƽq\\}oLxhF{kIvgFvgFzlIrOsP~pM}pMrOxV_oɿƮ˲ĭȮĪĶ~f}UyQXyS~YsƬ̵Ϲʷ˸̹ͺͺ̹˸ʷ̹˸ʷʷʷʷ˸̹ͻͻͻͻͻͻͻͻͻͻͻμμϽϽϽϿϿͽ̼˻ʺʺ̼ͽͽͽξξϿϿͽͽͽͽξϿϿξ̼ʺʺʺ˻˻̼̼ͽͽͽͽξξϿξͽ̼˻˻˻̼̺̺̺̺ͻͻͻμ̺̺̺˹ʸʸɷɷ̺ннннѾѾҿҿҿҽҽҽѼѼлллллллллллйжͶͶ͸ϺпϾҿлйѺδǬkrSqbCsbFveIhW;kZ@fV<m_E}qWuľȰ˳̶̶̶ͷθθϹкϹϹкѻҼҼӽӽҿҾмϹζ˵˰¨h~mOyfHzgG|gHyfHsZtë̶жӻؽ׼պѶеδͳ̲ʰɯ˱̳ε϶ʹʱȯβдҶӶѵϳͰ̯ˮǩǹdoNvfDwdDtaCm\\>n]?ziKz[i~ɾƧίѴγ̱ʹ϶ϸϸϸϸηηηηŮǰƯìĭƯĭɿsyWoMsSpPnSz^xĪƫɰȮéǬɯɯ˱̲ͳͳͳͳʰǭĪĪūǭǭũķ~aoMzjHzjH{kI{kJa¨ǭǰȰʰ˱˳̴̶ʴʵɴȲʹɲĨɽfnMnJmL}oLsRbƩȪʭʭɯʰʴͷʹͲ̱˰ɮǬŪĩǬǬȭʯ̱˰ȭƪoxVpNnMnMrQzXtĩȯ̶ͷʸϻѻѹиζ̲˱̲ͳ˰ǬrujNdY=cX<fZ@bX?d\\EshRf}Ĺ¬ŮŮƮʲ̴ʲ˲϶ѸзййййййййηһԽѺйһһжϴΰǪ½xb~oRpaDgV:bP8gW>m\\Hl]Hj[Hj[Fn`EsfFsViyħŨǩǪȫʭͰеζͶͶ˴ɲɲ˴ͶʳŮƾûļɿʾƸrrWo_EhX>gW=yjMtWchex[yjMp_Aq`BvfEpRexȼ©éééī©ŭſĿŨǥȿuuRufEn_>p_Cq`Do^DrVcfkkijs}źȾè˱̲ǰȱɲ̴͵ϴϴααȪťt{lMfS3_O.`O3`Q4aS6j_AwYv½ĿžžƼĽƿħƩƩũũƿgufGhY:hY:iZ;o`AvgHg̵˸̹̻ɵʭáſ|uViX:kZ<o\\>hU7n[=}lPxɾɿȽsg``dix·t{YxhFp`>teDj[:i\\<|qSkúǽôŴƳǰ˯αƧzfyV{mJxjEzlIqPvU`jh_{XyVyXzXbrøƪĨt\\wOuJW~Wb}·ǭʳ̶ɶʷ̹ͺͺ̹ʷɶ̹˸ʷɶɶʷ˸̹μμμμμμμμͻͻμμμμϽϽϿϿξͽ̼ʺʺɹͽͽͽξξξϿϿͽ̼̼ͽξϿϿͽ˻ʺ˻˻̼̼̼̼ͽͽξξξξͽ̼̼̼ͽ̺̺̺ͻͻͻμμͻ̺̺˹ʸɷȶȶ˹ϼϼϼннѾѾҿҿҿҽҽҽѼѼллллллллллйѷжͶ̵͸ϺпϾҿлййͳƫf}nOpaBtcGxgKiX<kZ>iY?k[AwiNg¦Ȯζͷ̶̶̶θкѻθϹккѻҼӽӽҿҿѽмθ͵ʴʯéjoQ{hJ|iI}hIyeJv_x¬˴ϷӺ׾Իҹз϶ϷиϷζ̵Ͷͷθͷ̶˵˴ͳгӶԷӶѴϲаɪv}\\zkJugDwgEudFp_Ap_AyiHsR~[kyµɾȨίͰʯ˲ʹйййϸϸϸϸϸìŮŮìĭǰŮtxV|lJpPnNmR{_w¨ĩƭūŪƬǭȮɯʰʰʰʰǭĪ¨éƬɯɯȬĦƹboNyiGyiGyiG}mLb¶ªƯǲɳǰʰ̴͵̶ʴɴǲǱ̳ɲĨɽ~d}jI|iH|iHzlI~oN_ľƿ¤ħŨūȮɳʹͲ̱̱˰ɮǬŪĩǬǬȭʯ˰ʯǬĨktR|lJ~kJ~kJoNwUtŪʱͷθʸκкѹиζ̲˱̲ͳʯèimbF^S7`U9dZ?c[Dh`KumXk|{~}{xrkcz]w[{c~hrź«ĭǯ˳͵ʲ̳ѸռֽѺѺѺѺѺѺѺѺηӼվһйѺйζͱί˭ȫqwZraEhW=aO7`N8^L8[J8_N>fUCqcI{mPczæͰǫȫǪŪĩǫ˯γҺѺйͶʳɲ˴ͶɲìǿƾļºŽ©ʼ´gvfLiY?fV<hX>sVdv}oy\\ziKvcEvcC{hJuWj{§©é¨©¾Ʈ¼ƩǥǾs}sPteDn_>p_Cp_Cl[AoS|^ckoquȽ§ŪĪƬ̲͵ɱȱɲ͵ϷѶеϲαʬƦryjKeR2^N-_N2_P3bT7odFb¥æé¨ũʭ̯̯̰̰ƪƿnzkLk\\=hY:hY:l]>rcFg͸̹ͺ̽ɶͰţzsTiX:kZ<p]?iV8o\\>~nTwļǿ˲ȮɾƸpd~\\{Y{ZdtmwUueCn^<teDi\\:i[>|qSlżǽòŰưȭˬʿraxU|nKykH{mJ}\\fvqe`|[xWz[j˾¢ãʽk}TsKsJVYjĻŬɴ˵ɶʷ̹ͺͺ̹ʷɶ˸˸ɶȵȵɶ˸˸μμμμμμμμͻͻμμμμϽϽϿϿξͽ˻ʺɹɹͽͽξξξξϿϿ̼̼̼ͽξϿξ̼˻˻̼̼̼̼̼ͽͽξξξϿͽ̼̼ͽͽ̺̺̺ͻͻμμμμͻ̺˹ʸɷȶȶʸλλϼнѾҿҿҿѾѾιηϸйѺѺѺѺϸййѺѺййϸжϵηϸѼҽпҿϺɲηδǽ^xkKzkLwfHp_Ao^@m\\>gV:k\\?qbE|nSj»Ĩ͵ѻҼккԾԾҼӽӽӽҼҼҼѻѻҿѾмϻͷ̴ɳɮlnPnPmM{fGzfKs\\vɾ˶ккͷԾӽӽҼҼѻѻѻ͸ικϻмѽҾӼзγγҷӶѴ̯ʫŧw~\\|oMwjGuhEvhEsdEsdEwhG|mL}oLrM~[h~ƦȬʮɯƭ̵ϸйͶǰƯ˴йǰƯììǰƯkzX~nLoOlLxdId}ĩĪǭǬζ̴ʲʲ͵ϷииʲɱǯǯȰǯƮĪźx|[yiHtdCtdCtdCveGcƺŭ˴˶ʴ˴ͳζζθ̶˶ʵǱƭʾ~e~kKzgGxeEwhGpQ`{Ŀ¦ũƭǮǬȫȫǪƩŨŨŨƩɬɬǪǪɬȫ¤buSzjH{hG~kJ|iH|Zv´ȭʹϹкʸκѻϷ͵ζҸӹѷϵɮǽx\\aV:aV:f[?[Q6[S>`ZD|fļʼĶ~pcuX{pTxlRwmT~t[mūʰūǭʰͳϴϴγͲ̵ͶηййѺѺѺйѺһһйͶɲȰϳҶϱŨúk~mSkZ@`L4]K5]K7YF5ZG8aP>j\\BykPmǻ¦ɯʰ˰ɰƭīŬƭ͵̵ʳɲɲɲɲɲìƯìºǿǿù´vx\\q`DeT8hW;p_CsVplqSyfHs`@p]=tdCnPe|żȾÿĿĿĬūĪĦŨţĻg|rOrcBiZ9m\\@jY=fU;sWcqĶŹǭǮǮǰǰɱʲ˳ʳʳ̴ζϴϴϲϲ̮ɩo{lMhU5^N-gV:eV9gY<vkMpħħħŨĪūīūɭ̯̯ˮ˯ͱʮĨõlxiLn_BfW8eV7l]@n_Bw\\}ǻ˶ʷɶ˼ͺѴ̬Ȩ{^o^@iX:kX:gT6o\\>|lRyľ¬ĭȯǬ¨ɾ´tf\\zYy[ajwkrPscAm];k\\;m`>pbEzoQsƺɽɽǼɾŭƪzd{X~qNxkHsP_oµ³mcyZwVbvŶοǹ}_tKrIwNsLzUmǮɴ˸ͺϼнλʷȵɶ˸ǴǴǴȵɶʷ˸̹ооϽμμͻ̺̺ϽμμμμϽоѿξ˻˻̼̼˻ʺͽͽͽͽͽͽͽͽ˻˻ʺ˻̼ξϿͽ̼˻̼̼ͽͽͽͽξξϿϿϿϿξξͻͻ̺̺ͻͻμϽ̺̺ͻͻͻμμμͻλλннѾҿҿҿҿӽϺϸйѺѺѺййϸййѺѺййϸжϵηϸѼҽѾл˴йͳ»]zmM{nNxgIraCp_An]?m\\>m\\>p_CyjK}`xž˳кѻͷ˵θҼӽӽҼҼҼѻѻѻкѾѾмϻθ͵ʴ˰̾ioQsUsSkL~jOxa{˶кϹͷӽҼҼҼѻѻкк͸͸͹κϻммҽѻ϶εеѴαɪťȽetRwjGsfCviF|oLwWz[{ZvS}oJ}oJwPXexȻæ˯̲ʯʴͶϸͶɲǰȱʳƯǰŮìŮǰìƼeuSyiG~kK}jJxdIféŪ©Ƭʰʯ͵˳ʲʲ̴͵͵̴ȰǯƮƮǯǯƮĪȽxz[wgFrbArbArbAtcEdƺŭ˴̹˵̵ͳζζͷ̶˶ʵǱȯĭçʾ~hnP|iIzgGxiH~oP_züžǽǽȿȿȿȿȿǾƽżżħħŨŨĹ^rPvfDubAzgFzgF}[yŷɮ̳θϹʸκϹ͵̴͵жҸѷϵƫùtX^S7_T8f[?\\R7_WBe^Klļ­ŮĩɻǹȺɻɻȺɻƸqicw\\w^}dt¸éǭĪƬɯ̲γγͲ̱˴̵Ͷϸййййййййη̵ɲȰϳд̰ħħz~mSkYA_J5`K6aN=]J9\\I:_N<bT:qcHeĸ§Ūɭͳͳε̳ʱȯǮǮ̴˴˴ʳɲȱǰƯƯȱĭûºǿ~f|kMjY;cR6kZ>udHc|ŶowZyfFr_?n[;p`?yiHyZpżéĿ¬éĪƨǪţcxnKo`?fW6kZ>jY=iX>x\\sĶŷƻʾɰȲɲɲʲ˳͵͵ʳ˴͵ζϴϴϲϲ˭ɩ£o{lMjW7cS2hW;fW:i[>zoQsææħŨūƬŬǭʮͰ̯ʭʮͱ˯ũŷmwhKn_BhY:hY:m^An_Bw]ƺ˸˹ɹ̽ϼϵˮʭ·z]m\\@iX:kX:hU7o\\>zjPwľíįưǮǮéȽtg_xXzZ~^fss`{kIn^<iY7hY8l_=qcF}rTvƺʾʾȽ˿çͿƹq_yVtQsQ]n̾Ϳʼrf}\\_iwʼʼv\\sJrIwPxS_xêưǴɶ̹λϼͺʷȵɶ˸ȵȵȵȵɶʷ˸̹ϽϽμμμͻͻͻϽμμμμϽоѿϿͽ˻˻̼ͽ̼˻ξξξξξξξξͽͽ̼̼ͽξϿͽ̼˻̼ͽͽͽͽͽξξϿϿϿϿξͽͽ̺̺̺˹̺ͻμμ˹̺̺̺ͻͻͻμͻλλнѾҿӽлѺѺѺѺййϸϸййѺѺййϸϵжϸйѼҽнѾлηӼ˱x|YzmK|oMzjIvfEzgGyfF~kKtdCq`BvgFrR`yūͷк˵ưɳϹԾҼѻѻѻкккϹннϻϻθζ˵̱ȺdpRxZyYoPmRhĭʳϷзεѻѻѻѻкккк̷͸͹κϻϻϻϺӽѺθεδͰȩsuTxjGtgDreBzmJ{XoyvctO~oHpGpGtL]uȺǬ̲̱Ȳʳ˴ʳȱƯĭìƯȱǰƯǰƯǿ~^~nLscAyfFyfFxdIgõĪƫīɯͳͲ˳˳ʲ̴͵̴ʲǯƮŭĬŭƮǯǯūvwXtdCqa@rbAscBudFeǻŭ˴̶̵̹ͳ͵͵̶˵ʵɴưɰǰũɽ|hpR~kM{hJyjKpQ_zü»¸¹ú¹ƽȿw|YoMqa?n[:s`?yfE^Ⱥʯ˲̶ͷɷκͷ̴˳͵ϵѷѷжƫ}rV]R6_T8g\\@_U:bZCjbMqįʵͶɲ˱ɭƬƪūƪĪĨĪçʾø|ttyǽĪūĪƬȮ˱ͲͲ̱˰ʳ˴̵ηηϸηηйϸηͶ˴ʳɲɱзϳʮħǪħmUm[C^L6^L6bO>_L;\\K;]L:^P6i[@uZyƼŪͱͳ˱˲ʱ˲̳˲ʱ̴˴˴˴ɲǰŮìȱʳĭļŽ«ǿnsSr_?gT4gT6p_A}lNmĵƷq|_}jJubAo\\;n^<scA~oNasƬ«ıýéƨǪĢavlIl]<cT3hW;jY=l[A}cͿũéĬƮưɳɳʳ˴ͳδжж˴˴͵ζϴϴϲαʬʪĥnzkLlY9gW6hW;gX;k]@tVx¥¥¥ħŨƬǭǮɯ˯Ͱ̯ɬʮͱ˯ǫȺpvgJn_Bj[>l]@paDn_Bx^ƺ˸̺˻ο͵ɭ˯ɭɿʾx[kZ>hW;lX=iU:n[=xiLrľĮíưȳƯɲǮĩʿvj~^zZuVwV~\\[sOvd@m[7hX6hY8l_=tfIxZ|Ǽ˿¯¬ʼ³vd{XwTyV~^oǾũũũũɻxha`er}nYsLtMyT]lƼůƱĳƵ˸̹̹˸ɶȵȵʷȵȵȵȵɶʷ˸̹ͻͻͻͻμμμμμμμμμϽооξ̼ʺ˻ͽξξͽξξξξξξξξϿϿξξξξϿϿξͽ̼̼̼ͽͽͽͽͽξξϿϿϿϿξξͽͽ̼˹˹˹˹˹̺ͻͻʸ˹˹˹̺̺̺ͻͻϼϼнѾҿԾһһһһѺйϸηϸййѺѺййϸϵжѺѺѼѼннлйӼƬluRxkI{nL|lKpOzZ~^csSzjIzjIxiHzmKbưϹ̶ưǱͷҼѻѻкккϹϹϹϼϼϻϻθζ̶Ͳŷ|`pR{]{[oPmOlƻȱ̴ззεкккккккк̷͸͹κκκ͹͸ӿҽκ̴ͳαƨ˾g{mJwiFwiFuhEsPbs~WtKoDxg<}lAsK_t˽ǭ˱ɳɲǰǰǰƯĭɲʳȱŮŮĭļz~[{kIo_=ubBvcCwcHhƸūŪīʰϵϴ̴̴͵ζϷ͵ȰŭĬëªĬƮȰǯƬ¦tuVtcEscBvfEwfHziMk˿ưʵ˸̶ʳ˱˳ʲɳȲȳȳĮɰɲƪǻyfoQ}jLzgIyjKqRb~¼þåæǽƽĻżƽǾżúƽżryV}mKn^<jW6p]<zgFc̾˰ʱʴ˵ɷϻͷ͵͵ζжѷҸҸ̱ù}rV^S7_T8h]AbV<cXBiaLqįʵͶɲʰʯɯʯɯɮǭǬȮȭƬèɽ¸ƭɯǭūƬɯ̲γγͲ̱ʳ˴̵ͶͶͶͶͶϸηͶ˴ɲɲɲʲ϶ʹ˯Ǭƪǽt|lSo]EaO9]K7[H7XG7YG9\\K9_Q7dV;tfKd|ǻȭǮūªīȯ̳϶϶̴̵Ͷ̵ʳǰĭ«ȱɲĭƾŮǿ|b}hIo\\<jW7lY9wdFqSj|vmdtS|lJtdBpb?qc@xjGxUcyȽƭĮ˿ıľ¨Ħħ fyoLn_>cT3fU9hW;l[AeŪɮǯưǳƲʶʶ˴˴ͳϵϴѷ̵̵ζϷеϴϲα˭̬ƧkwhIjW7hX7hW;fW:n`Cy[~¥¥æƩǭɯɰ˱̰α̯ɬɭͱ̰ǫʼpvgJn_Bm^Ao`CrcFo_E{aƹ̹μξ̹ƯȱɲŬǮv\\kZ@iX<lX=hT9mZ<whKpſůůȲȳƱȳŮūĨzodyXrPpLnJygCq_;n\\8iY5jZ9m`>wiL`ʿïǱǭôrdZwTxV~^k~Ż¦Ūĩĩūǻzlb_fq{zrd|UtPxS}Zf|êȳƳĵŶɷʷʷɶɶȵȵɶɶɶɶɶɶʷ˸̹˹˹̺ͻμϽϽоμμͻͻμμϽо̼˻ʺ˻ͽϿϿϿϿϿϿϿϿϿϿϿϿϿξξξξͽͽͽͽͽͽͽͽͽͽξξϿϿϿξξξͽͽ̼̼̼˹ʸʸʸʸ˹̺ͻʸʸʸ˹˹˹̺̺ͻϼϼнѾҿҿӽһӹӹӹӹҸѷжжѷѷҸҸѷѷжϵѷһһѼѼннѼϸηĽ`xnKtgEylJ~nM|[q|}jzYrPwiFqdAtQk̶к˵ʴͷϹѻѻкккϹϹϹλλκκθ͵˵̱Ƹ|`rT|^zZmNmOnīͳͳеҶϳѸѸѸѸииии̵ηθϹϹͷ̶˶Ѿн͹˵̳βħȹ_yiGxjEzlIzlIyViȾ̿b{RqFyf;|i>~mBtNc{ͿȮ˵ʳȱȱɲʳɲȱͶͶȱì«ûx}Z{kIo_=taAubBvbGhƸĪĩêʰδγ͵ͷθкѻθɳůí¬¬íưȲȲƯ¦tsTudFveG{jL|kMpTrëǱɴɶɶǰȮǯƮưưǲǲĮɰɲũƺvblNzgIxeGxiJrUh¢ĤȪ˭ˮɬǪƩȩȩɪȩŦż¹¹żƽqxU}mKo_=jW6q^=}jIẖʱɳ˵ɷϻθϷиѹѷҸӹԺеù}}rV^S7\\Q5dY=`T:dX@j_ImưʵƱȯʰ˲̲ʱʰȯɯȯɯȯɯƭƬê©ǬŪŪȭ˰̱˯ȬǪɬ̯ϲггϲγʳ˴̵̵Ͷ̵̵̵ηͶ̵ʳɲɲɲʲ˲̳̱ʰĨz~cueLl\\CbR;ZI5UD2SC3XH9_P=dT;bS6hX>vhM}bxȾĩ¦ĪʯεѸ͵̵ͶͶ˴ȱĭ«ƯƯ«ƾìǰļowVxdCr^=p[<n[;ubBmMz\\jxxtppoazWqLxlFthBsgAznHvSd{ªð̿˾˿ǿluRrcBdU4eT8fU9kZ@eūȱƲǲǴƳɷɵɳɳ˲ͲβϴδͶϷϷеϴϲα̮ͭŦhteFhU5fV5hW;fW:pbEa¼¥¥ħƩȮʰ˲̲̰αͰʭ˯β̰ǫ˽qvfLo_En_BpaDscIp`F~dǺ̹ϽƵǴȵűȴ}u\\m\\BkZ@mY>gS8mZ<xiLqƯŰǲɶǴǴůíŭƬæudxVnJweAq]8nZ5o]9k[7iY8k^<ugJa¬Įǯƫʻn`yUuQvS~^k}ĪƬǭƬǭȯǱƭʾ·|l_^bhgc[zVyU~[btĺűǶŶĸŹȶȵȵȵɶɶɶɶʷʷɶɶʷʷ˸̹ʸʸ˹̺ͻμϽоμͻͻͻͻμϽо̼˻ʺ˻ξϿϿϿϿϿϿϿϿϿξͽͽ̼ͽͽͽͽͽͽͽͽͽͽξξϿϿϿͽͽͽͽͽ̼̼̼˹ʸʸʸʸ˹̺ͻʸʸʸ˹˹˹̺̺ͻннϼнѾѾҿҿѾҼѺӹӹԺӹӹҸѷжѷѷҸҸѷѷжδѷӼӼллѾҿѼ̵ƯsvVsiFreCxkIoNdŲǴl|[~nLtfC{mJzZyĮϹϹθθͷҼѻѻѻкккϹλͺ͹͹̶˳ɳʯƸ|`rTz\\uUjKmOmɰѷδѶӷϳѸѸѸѸѹѹѹѹηϸкккθ˵ʵλξ˹ȳɱ˰οmwVxfBvfB{kIrO_qɿg~SrG~k@~k@|i?~lDxTi~˿Ǳɲʳ˴̵ͶηηϸͶȱìºu{X{kIp`>ubBubBwcHjƸéĩī˱δ̱θθϹкѻϹʴưĮííĮǱȲȲƯqqTudFxgI|kM}lNtXxĴŭǱǲƵǴĭūŭĬůưȳȳǱʱȱũǻu|_|iKxeGwdFxiJtWk¢ťǧʬ̮ͰͰ̯ˮѲѲѲбͮʫƧäǾǾżżȿúryV~nLqa?n[:ubAmLj¥γʱʴ˵ɷϻкѹӻҺѷѷҸԺϴy{pT\\Q5YN2`U9[O5dX@k_IkɽĮɴƱʰ̲δδ̲̲̲ͳɯɯȮɯɯ˱̲ͳѶеγͲͲ̱ʮǫȫʭͰгѴѴϲα˴˴̵ͶͶ̵̵˴ͶͶ̵̵˴ʳɲʲȯʱʰǭùltYn^EjZAdS?_P;_O?bRBhXIm^Km]DfW:bR8jZ@yiOd~ȼêūƬȮ˳ζ˴˴˴˴ɲǰŮìĭŮŮŮ~`kKt`?t`?s^?mX9n[;xeEpR{]kruxul_zT{oIrf@qe?uhEsQjĵ̼̽μ̿¨ĿƿſlvSteDfW6fU9fU9l[AhƮȳǴǴǶǶɹɷɵʱɯ˯̮ͱεηϷиеϴϲαΰ̬£hufGiV6fV5iX<gX;tfIhſæ¤ææŨǪȮʰ˲ͳʮαα̯ͱϳ̰ƪɻqxhNp`Fm^Ao`CscIrbHkȻ̻ɺɺɸƶȶ|u^q_Gn]CmY>fR7mZ<{jNu¦ȮƯȳʷȵǴŲıǱ˲̰ȫĤövdvRweAnZ5lX3o]9jZ6gW6eX6qcF`Ŭ̾Ⱥw_{UrNvR~]k~ŭūŭŭƮǰɴȲů˿ĹzcZXZZZZ]cjqƴƷŹƼŹȶǴǴȵʷ˸˸ɶ˸˸ʷʷʷʷ˸̹ʸʸ˹̺ͻμϽϽͻͻ̺̺ͻμϽϽͽ̼ʺ˻ξξξξξξξξξϿϿϿξͽ̼˻̼ͽξξξͽͽͽͽͽξξϿϿϿͽͽͽͽͽͽͽͽ˹˹˹˹˹̺ͻͻʸ˹˹˹̺̺̺ͻͻннλλϼнѾѾнѻйҸӹԺԺԺӹӹжѷѷҸҸѷѷжδҸԽӼллҿѼȱƾh{pPqgDtgEzmKqPg̹ǳzcvR|nI{mH|oMjʴϹкϹͷӽҼҼҼѻѻѻкͺͺ̸˷ʴɱưǬ|uY|kMqS~kKwbC|iKiͲոѴӶԶѲѸѸҹҹҺҺҺӻϸйѻҼѻθ˵ʵ˻ͽ˹ŰƮŪƵ|[qMvd@rb>yiEzUnȽǿ~byNqFqCpClA}kCqMxWg}øǿǰ˴˴ʳʳ̵̵̵ɲŮìowTzjHp`>vcCwdDyeJlǹĪŪƭͳδ˰ͷ̶ͷθϹθʴǱưůĮůȲɳȲƯʾopStcEveGyhJxgIsWwĴŭưŰĳƳĭūĬŭưȲ˶̷˵̳ɲǫ˿vz]{gLxdIvbGxiLuXmĤǧȨʪ˫̯̯̯̯ббббϰί̭ˬƧŦä£ŦƧǾszW~nLrb@q^=yfEoNjæγ˲˵̶ɷϻкҺԼҺжϵжҸͲw{pT^S7ZO3`U9[O5dU>j[D}fƺí˶ɴ˳ζϷϷ͵͵ϷҺ͵̴ɱȰɱ˳ϷѷеϴͲ̱˰ʯʮɭȫɬ̯ϲггϲα̵̵ͶͶͶͶ̵̵̵ͶͶͶͶ˴ɲȱɱȰūsx^|lSm]Dk[Bk\\GrcN~n^yh{kxeoVudHkZ>iZ=o`C|nQfv§ʮʰȮɯ˱ȱȱǰǰƯŮĭìŮŮ«Ů«wrRzcAs\\:xa?t`?kW6kX8ubB|kMvXixwh|TvjBma;m`=xiHyZv±ʹϻǿ¨¤¥d{qNqbAeV5fU9hW;p_EmɳʷǴȶȹɸ˻˹ɶʲɯɮ˫˭εϸииееϲαΰʪǾjzkLmZ:iY8l[?j[>xjMoĤŨŧħŨƩȫɯʰ˲̲ɭͰϲαϳд˯ĨƸpyiOqaGl]@m^AscItdJoʽͼǽɿ˿ǹǷ˾xv_vdLraGmY>cO4mZ<nPxĩȯƯȳ˸ʸǴȵȴʳ˲ͱβͯ ȸxalGs_:p\\7q_;l\\8fV5dW5qcFdžŪƺyfY{S{U_o·ǿīê¬ĮůưǴɴɲŬ¥żqc\\~Y[_dnxȾǳǶŹǽǽŻɷǴƳȵ˸ͺ̹ʷ̹˸˸ʷʷʷ˸̹˹˹˹̺̺ͻͻμͻͻ̺̺ͻͻμϽξͽ˻̼ξϿξξξξξξξξͽͽξϿϿξ̼̼ʺ˻ͽξϿξͽͽͽͽͽξξϿϿϿͽͽͽξξξξξ̺̺̺˹̺ͻμμ˹̺̺̺ͻͻͻμͻннͺλϼϼннϼкйѷҸԺԺԺԺԺжѷѷҸҸѷѷжδҸּԽѹкҿһŮ}`xmMsfDwjH}nMrQg˸Ťλj{YtR}oLviI{`|ĭ̵йϸζӻӻӻҺҺҺѹѻιι̸˵ɳȰƭŪs~mQtcGzgIs`@oZ;wdFfϴչҵԷշвҹҹҹӺҺӻӻԼйѺӼԽҼй˵˵˸νʷïëvrOlIwc@q_;xhD\\{ƣǽw_uK~oDtIvKqF~oH~nJ~oNtUgzȭȯŬūĭɲ̴ʳȱƯéirPxhFp`>wdDxeGzgInȺūƬȭβϵʰ̴˵˵̶ͷ̶ʴǱǱưůưȲɳȲƯɽn}nQqbCsbDudFtcEpTuëĮįŲƳĭūŭƮǱʴιϸϹζ˱Ǭçwz[|iKxeGudFxiJuXmħʬʬ˭˭ˮˮ̯̯ˮˮ̯̯ͰαϲϲɬɬǪǪʭʭtyW~nLscAs`@{hHoOi¥ϵ̳Ͷ̶˷мкҺԼҺδ̲δϴ̱wqVdV;_Q6eW<aS8aQ:gW@xaŶ¬ʶ˶˴Ͷϸη̵̵ϸԼҼϹ˵ȲȲ˵Ϲѹδ̱˲ʯʱ˰̲̰ūȫʰαδϲͳ̲ͶͶηηηͶ̵̵˴̵ηϸηͳʳɯͳȯȾyz`{kRvfMqaHp`IsdMu`xxcsTudFm^?l]>rcD}oR{^zɾ˰˰ȭɯ˱ǭƬūìììììưưí©ŬɿlnNua>q]<xdCubAjW7iX:udF{jNuXmȺʾǪƽ{c|oLoa<k]8vfDrQiƵϾıǼħŧŧ_whIn]?dS5gV:jY=rbHr˵˸ǴǴȷɸμͻ̸˳ʰʮ˭˯жииижϵααͰǨƻloNr_?m]<m^?k^>|oOrƧɩǩŨƩǪǫɯʰ˲˲ȬͰϳϳдд˯çŵnzjPqbEj[>k\\?rbHtfLqʿλȽķɼ;ȷǵǼvw^xhNudHlX=bO1mZ<pR}ŪɯƯȳ˸˹ŲǴɵ˴ʳʱ̳ͰʫãȹqwSyeBvb?tb>o_=hY8eW:rgKlūƩwk]|X[eq¶ȽžůŬůǱɳɳɶͷɲȮƪĥ¹sk`ciuõĹɿǱ̹ȷŹǽȾŹɷȴƳɵ̹ϻͺ̸̹͹˸˷ʷ˷˸˸˹˹˹̺̺̺ͻͻͻ̺̺̺̺ͻμϽϿͽ̼̼ξϿϿͽͽͽͽͽͽͽͽ˻̼ͽξξξ̼˻ʺ˻ͽξϿξξͽͽͽͽξξϿϿϿξξξξξξξξͻͻ̺̺ͻͻμϽ̺̺ͻͻͻμμμͻлѼϺϺϺллѼѼѺҸҶҶӷӷԸԸԸӷҶѵддддѵϳӷ׺ԺѶѸռԾѹҺҸƪq{^sdCykHxjGvfDvTsɹâŵ~i|[tSpRqTenī̳϶ҸжϵϵжҵҵѴеϸϷ̵ʱȰȮǮȭludHn]AxeGs^AoW;uaF~c§ϴ׽ӹּϵҺҺҺҺҺҺҺҺѹҺҺҺѺѹϸϹͺ͹ɵŮéɺf~gE|hCxd?uc=qLgĺǥŸp]uQzS^[]^|YsQ|oMvW_r˸âħçʲ˲ǯĬǭƪf|iIxeEubBtcEwfH|kMhɻǫʮˮ̯ͱͰ˳˳̴͵͵̴˳˳ƮǯǯǯƮĬªżl}pPo`Al]>o`ArcDyjMr¬ŰƳŲŮƯɱ̴θϹккѻ͵ʯʮħpyXzgFzgFwgFyjIxXsƩɬʭˮ̯ͰͰ̰˯̲˱ɯȮɯ˱ͳϵ̲ʰƬūɯɯpsSmMzgGxeG{hJoSq̱˱ѸӹѹԼϹϺϸй϶ε̱ʰȮʼ|_o`CeV9fW:gW=fV?m\\Hp\\{ʾưʴ̶˵ʶ˷͹ϻϻлͺ̹̹˸˸̹̹ͺϸҸѺϵʳɯʳδŮɯ˴ͳͶͳ̵ͶϸϺллйϸηͶδϵδ˱ͳдδȭɮæxza}mTvfOqaJsdM~oX~gx·xl]|oLreBqdAxkI}pPe{Ǽçʮ̲̯˭ŦĪǯìîİưȲƯ¨˻sxWqa@rb@qa@o_>n_@qbCxiL|nSy_mǻ¯įƴƳ}a}mLuc?xdAzhDtRf{ŻȬ§¦þĦĦzx\\q\\ApX>nV<iU<jY?ugLsƮ͵ʵ̷ɴŰʵлι̵ɳɰɰɰ˱͵θѹҺӹҸдγȬƩ˼foNvcBrb@ob@rhExUrɨͮʭǫǫȮǮǱȲɳʴȯʮʯʯϴѶʯl|hMn]An]An^DscJzlRwï˸μ̸̼̹ʶɶͷǰpx]yjMrcDiX:cS2scB|]ȱʲǱ̶θʷ˸˸ʴɳȲǱǱȯǮūhpPs`?ubAp`?iZ=g[AynX{íżzlfhlr~ƺɼɼ˿°ĮƮʲ͵͵͵˵ɱ˳ȰƬū¦}~Ǿ§ê˴ʵȵƵƷƺȼ˻ʷɶɶ˸λϼϼλλλλͺͺ̹̹̹μͻ˹ʸʸ˹ͻμϽϽϽϽϽμ̺̺̺̺˹˹̺̺ͻμϽϽμμμͻͻͻ̺ͻͻμμͻͻ̺̺̺ͻμμμͻͻͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽ̺̺ͻμμμͻͻϽμμͻͻ̺̺̺̺лѼϺϺлллѼѼѺҸҶҶӷӷԸԸԸӷҶѵѵддѵѵгӶֹոѶҶռռҹѷдitUtdCxhFxhF{kI]}ƶ̼ƶve{]z[z^|_eiu÷¨ʯϴϳϳϲгѳѳҳгεζ˲ɰǭƬƫƫisbFkZ>taCoZ=lT8s_D}bγռѸּжҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϹ͸̷Ȳì̾±x_xa?yc>vb=xf@xSnŻĢ³}l`\\dpxxti|ZsQtSyWbpμ¡ŧŨĨȮɰƭ¨ũĨbzeFvcCubBudFziKpQmɻǫʮʭ̯Ͱ̴̰̲͵͵͵͵̴̴ǯǯǯǯŭëƽizoOn_@j[<l]>o`AxiLpĮıĮƱǰʲ̴θϹккиͳɮɫ¥nwV{iEwgCvfDxkIxXtȫ˰˰Ͳγδϵϳϳ̵˴ɲȱɲ˴Ͷη̵ʳƯŮɲɲttTnP{hJyfH}jLrXw¨δ̱зҸѶҸθιйѺз϶̲ʰʰ§l|kOm\\@hW9gV:fV=jZC{jVqȹƱϷɳɳɳɶ˸̹͹ͻнϼϼνϽϽϽнιѺһѺη˴˴̵ȱȱǰƯǰɲͶйллллйϸηͶδϵͳʰ̰ϳͱȫǨȷf|lRscJueNzjSt]jzźǩʬǤo[~qNxkHylJ|oMyYl´ɮͱǧ¡Ũǭĭïůǲɲƭͽ±}_yiGm]<m^=n_>o`AqcFxjMuZ|awĹ®ƴǵǶƺĸſsyYlK{dBzfAoK[qƦȿĿ£zv^s[CqU?nT=iS;jY?shLtĭ˴ʳ˴ȱŮʳηͶ̵˴ʳɲɲʲ̶θиҺҸҸϴϲɮƩɺcmLwcBscAnd@tlG~Yv˪ίˬƫƫǮǮǱȲɵʴʱ˰ʯʯͲеʯ§îpmOq`Dp_Ep`FugM|pX}į˶ͻѿѾ̹˶˴ȲȲʲǭlxZxjMteFm\\>iY8zjIcɳɳưʴ̶ʴʴʴȲǱǱǱǱǱǲǰůƿxxZyfFs`@n]?iY?k_G}u`î{pnt|˿í¯²ųƱɱ̴ζϷζ͵˳ζʲƮŭĬ»¦ɭ̵̲ʵʵȷǶǸȹɺʺʷɶɶʷͺϼϼλλλλͺͺ̹̹̹ͻͻ˹˹˹˹ͻͻμϽϽϽμμͻ̺˹˹˹ʸ˹̺ͻͻϽϽϽϽμμμͻ̺ͻͻμμͻͻ̺̺ͻͻμμμͻ̺ͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽ̺̺ͻμμͻͻ̺μμͻͻͻ̺̺̺̺ллϺлллѼѼѼѺҸҶҶӷӷԸԸԸӷӷҶѵддѵѵѴӶֹոҷѸԽԻѸϵͱƼ~a{lMqa@ta@ubA~kJeĴĴzleiotvlhivæ̯ββϲϲϲггеʹ̵ʱȯƬūĩĩisbFjY=s`BmZ<jU6taC}bͲԻзּжҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϹ̷˶Ǳ¨ŷkuTu^<w`>wc>~oH_yùȻvign|l_xYwU~Ybw;ŧǪǫǭȮū¦¦|^vcCtaCubDwfH~mOuXtɻǫˮʭ̯ͰͱͳζζϷϷζζ͵ȰȰǯƮĬªſƽhxmMm^?iZ;k\\=m^?yjMpɿɾ¬ð¬ǲȱ˳͵θϹккϷ̲ɮȪοktSzhDvfBueCviGxXtȫ̱ʹεзѷҸҶҶͶ̵˴ʳ˴̵ηϸ̵ʳǰƯʳʳuvUnP{hJzgIlNv\\|ūε˱϶жγж̴ͶйһҹѸ͵˱̲ʯɻbxiLl]@eV9gU=gU=o_Hv]z̽˱ɱʲ̴θϹϹθκлллннннѻϸҸԺӹж̲ɯɯʰɯǭǭɯ̲ϵйллѼѼйϸηηδδ̲ɯ˯βʮħʻlvZvfLn^EufOt]n}¶¨ͱѵϯɧ˾tcyWsQ}pN~qQ|\\iq}ȺĦĤ¡¤Ʃǭū¬¬ǲȱêƷlqPo_=jZ9m^=reEwjJqT}`q{ƻíȴɵȶȷƺ÷ſļn{ZyeBvb?vd@~pK^qĻæ¤£þ|x`s[CpT>lR;gQ9hW=shLt«ʳȱ˴ȱĭʳ̵ͶͶ̵̵˴ʳʲ˵ͷϷѹҸҸег˰ŨŶ|_|lKwdCueCqgCzrMbǾͬϰˬǬǬǮǮǱȲɵʴʹγ̱ɮ˰γʯèðspUtcGraGscIzlRu]Ű˶̺Ͻϼ˸ɴɴƲưȲŭo|`~pS{nNxiJwhIy[sſʴȲůȲʴɳȲȲǱưưǱǱȲǲȱȲƬƺgqSudFsbFqaGwkSo­ƿŬɳɳǳİĲųɴ˳ζиѹиϷ͵и̴ǯƮǯǯŭ¨ĽĽž¥ǫ˯ͳ̵ʵʵȷȷȹȹɺʺʷɶɶʷͺϼλͺͺͺͺͺ̹̹̹̹ͻ̺̺˹˹̺̺ͻμμμϽμͻͻ̺ʸʸʸʸʸ˹̺̺оооϽϽμμμͻͻμμμμͻͻͻͻμμμμͻ̺ͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽ̺̺ͻͻͻͻ̺̺ͻͻͻ̺̺̺˹˹̺лллллѼѼѼҽһҸҶҶӷӷԸԸԸԸӷҶѵѵѵѵҶҶӶոӹҹҹԽҹ϶ͳɭ·{z]xiJvcCs`?ta@nMixrnrobdtṴ̃βггϲααϴʹ̵˲ɰƬūèèlwfJm\\>ubDp]?nY:xgId˰ҹ϶ּжҺҺҺҺҺҺҺҺѹҺҺҺҺѹизͶͶȰ{_mLxaAxdA{iEuQh|mirýáĢƽ|oe~]}X\\jɾŨȬʰ˱Ȯ¨¦}{]taAs`BubDwfHnPwZwǼȫʭɬˮͰͱδϷϷииϷϷζʲɱȰƮĬſľżfxmMo`Al]>n_@o`A{lOqɿʿíıĮɴʳ̴ζϹϹϹϹ͵˱ȭƨ˼gqPxfBsc?rbAtgGwZwǭ˲̳εѸѷӹӷԺϸηͶͶͶͶηϸ˴ʳǰǰʳʳvvUnPzgIzgImOx^ǭ϶˱εϵ̲δ˳ͶйӼԻҹζ͵̲жɮzz]vgJj[>m\\BhW=hX>vfL|b{ͿƮɯ͵иϷζ̶̶̵Ͷ͸͸θθͺͷѷҸѷж̲ɯƬūȮȮȮʰ̲δδδйллѼйϸηηδδ˱Ȯʮ̰ũƽp~]tV{lOtdJ|nT~g¶ʾªǭȮɭ˫ĢŸ{k`yYxXzZ|\\}]ds¢âŧȪȬūɿĬé˻y`lKp`>n_>whIuUamzǻ˿ĮǱȴǳȶȷȼ÷¯õjoNzhDrb>tfC~qObyƿƩŧŦĿzbu]EqU?kQ:eO7fU;qfJrɲȱʳȱŮʳ˴̵ͶηͶ̵˴ʳ˵̶ζиѷѷее̰ħ³{bpO}jJ}mKzpL|Wm¡έίʭȭǬǮƭưǱɵʴзеͲɮʯͲ˰Ū®yy]zkNwgMzlRs\\}eƱ̷̹ͻͺʷȵɴƲűƳưû{nfcbduºů˵ȲưȲʴʴȲȲǱǱǱȲɳɳǲǰȲɯxcvXvYw]hıŨ¢ǾžũǮʰƭȱȲȱűįĲƱ˵͵ϷиѹиϷζи͵ɱɱʲ̴̴˱ƿƿ¥ƪȮȱǰʵʵɸȷȹɺɺʺʷɶȵʷ̹λλ̹ͺ̹̹̹̹̹̹̹̺̺̺̺̺̺̺̺ͻͻμμμͻͻ̺ʸɷɷɷɷʸ˹̺ооооϽϽμμͻͻμϽϽμͻͻμμϽϽμμͻ̺̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̺ͻͻͻͻ̺˹˹̺̺̺˹˹˹˹˹̺ϺлллѼѼѼҽҽһҸҸҸӹӹԺԺԺԺӹҸҸѷѷҸҶӷԸԺӹӺӺӽԾ϶ʹ˱ƪxz]zkL|iIydEydEqRk~{st{ŨŦzbyYaqũɭͳδͳ̲̲ʹεʹ̳˲ȮƬĩèoziMo^@vcEq^>q\\=|kMg˰ѸεջжҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϷз϶ʰɿqwW|iH{gF{gF}jIvTh{~{tnráȦǥɧâth[zU~Zk~ĻħʮͱʰĪ¦ž|z^taCq`BraCwfHnPvYvȽȫɬɭ˯ββϵϷииииϷϷ˳ʲȰƮĬªúdxmMqbCqbCsdEteF}nQsůǴǱ˶̵ζϷккϹϹ͵˱ɮƨɺdnMuc?qa=p`?tgGx[yƬʱ˲ʹзжҸҸӹϸϸϸηηηϸϸʳɲǰǰʳʳǿuuT~mOxgIxgInPy_²Ȯ϶˱ʹδ˱δ͵ηѺӼԻӺѸ϶˱ѷѷ¦ux]whKudHm\\@hW;p_CpSiȼçɯ̲̲ɯɰɰ˱˱˴̵͵̴˵˳жϳͱ̰˯ʮɭȬũĽĽ¦ȬͱϵϸϺллϸηͶͶͳͳʰȮɭȬžv_tQrQqTpV~dyŹůǱưȯʱȮǬħǺuhe`xXsStT]p}ƨǪƪèʾǹiwV|lJwgEzkLy\\n}÷˿ŬƭǱȲȳȳɶ˹ʻƷ²ƳȲͿycxW|lJviFxnKzYm|¥ĦŦ{cu]EqU?jP9cM5dS9ncGoȱǰʳȱƯ˴ʳ˴ͶηηͶ̵˴̶ͷζϷжжее˯Ħ´j|[yX{Z]h~ƧίͰʭɮȭǮƭůǱȴʴѸѸ϶ʱɰ̳˲ȯĳo|by`~dovǼɴ͸̹̹˹ʷʷʷȵƲǴȲȺĭɳ̶ʴɳʴ̶˵ʴʴɳɳɳʴ˵˵ʵɲȲɯŪƸ~xwz¯ɸǴëéūȮ˱̲ɲȰ«ĮįůįůƱɳ̶̶θϹϹϹθͷθͷ̶̶̶̶ʴɱ¥ħǭɯɱɱ˵˵ʸ˹˹ʸʺʺʷɶȵʷ̹ͺͺ˸˸̹̹̹̹̹̹̹̺̺̺̺̺̺̺̺̺̺ͻμμͻͻ̺ʸɷɷɷɷʸ˹̺оооϽϽμμμͻμϽϽϽϽμͻϽϽϽϽϽμͻ̺̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̺ͻͻͻ̺˹ʸʸʸʸʸ˹˹˹˹˹̺ϺϺѼѼѼѼҽҽҽӼѺҸҸӹӹԺԺԺԺԺӹҸҸҸҸҸչԸӹҸҺӺӽӽ϶˱Ȯ¥rzZ}nO}hI{dE|eFpQdqtrw~ħ̮ΰͭżk}]yY`sĽƬ˱̲˱˳̴εʹʹ̱ɯƪèæoyjKn]?taAo\\<q\\=~mOl§˰зʹջжҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϷѷϵ˯ȿiqS{hH{fGzgFyiGqN^ntswx|Ģ̬̪ʪͫɪǾtaxTsQ}\\lyȬȮé»xz]s`Bp_Aq`BveG}nOuXuȽǪɬȬ˯ββζϷϷииϷϷζ̴˳ɱǯŭĬëébwlLsdEteFvgHvgHpSu´©íȲ˸̶͸ͶϷиккϹϹ͵̲ɮŧǸalKtb>p`>qa@wjJ}`}Ƭʱ˲ʹ϶Ϸжѷѷϸϸϸϸϸηηηʳʳȱȱ˴˴uvUnPziKyhJnPy_~ǭεʰʹεͳжийѺһӺҹѸз˱ѷҸʰɻu}bzkLqa@jY;k[:teFuTkyĹĨ˯̰˯˰̱̰ͳδϵϵδ͵̲ͱ̯˯̯ͱ̯ʮȫ»üʮҶηιιιηͶ̵˴̲˱ɯȮȬĨk}V}oJ|nKtUf{ĸ¬ɶʷɵ˵κθɯǬƫŪ´}pcwW{nNwjHzmKyWcx½¥ǪƩæø|k|[sPpNtQ`q´Ĺɽ¨ǮȯȲȲȳɴ̹μʻȹǴɶʴéŶwhzYrPzoO~uTbnĿ£½~x`s[CpT>jP9dN6dS9ncGoǿȱȱ˴ʳǰͶʳ˴̵Ͷηηηηθθζζδϵγγ˯ƪǹ|qppvȿʫίͰ̯ʯɮǮŬůưȴʴ϶Ѹз˲ʱʹʹʱͼ}Ǽí̷Ϻͺ˸ʸʸʺ˺ɶǴǵɶŲŽøôŷͿȰȱʴʴʴ˵̶ͷͷ̶˵˵ʴʴʴ˵˵̸Ͷ̴˱Ǭ¦ǹ´Žʷ̼ʹűưɳ̶θ̶Ǳí¬Įưɳ˵ͷ̶̶ͷθθͷͷ̶̶ͷͷͷ˵ɳưĬ¨ƬȮɱȰ˵ʷ˹˹˹˹ʺʺʷɶȵɶ˸ͺ̹ʷ˸˸˸˸̹̹̹̹˹̺̺ͻͻ̺̺˹˹˹̺ͻͻͻͻ̺ʸʸʸʸʸ˹̺̺ϽϽμμμͻͻͻμμϽϽϽϽμμооооϽμͻ̺˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻̺ͻͻͻ̺˹ɷɷɷɷɷʸʸʸ˹˹̺ιϺѼѼѼҽҽҽӾӼѺҸҸӹӹԺԺԺջԺӹҸҸҸҸӹռԺһҺҼӽҼҼϷ˱ƬƽmwX~nM~fJ~fJiMsV~cnuyŨʭ̮ͯͮ{k_~]gqüƪʰ˱˴ζ̳̳˱ʰȮũpyjKl]>p`?l\\;p]<oNqŪ̱з̳ԺжҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϵӶϲʭǼbnP{kJyfFyfFwgFzkJzXhqqήгͭͯҲαŦ´o_wUzY`fvüžütwZn]?m\\@p_CteH}nQv[xȽƫȬȬ˯ϲгζζϷϷϷϷζζ͵̴ʲȰƮƮƮƬ¹avkKrcDsdEufGteF~oRt´êĮʴͺϹιϸиѹккϹϹ͵ͳ˰ƨƷ}`lKta@qa?tdC|oOfȮ̶̳ͷ϶ϷижжϸϸϸϸϸηͶͶ̵̵˴˴ηη«vxWrS|mN|kMpRy_~Ƭʹɯ̴϶ϵҹӼѻѻкѸѸѸҹʹзѸ϶Ȱȼy{\\qOwgFrb@qbAwiFuT`øåȪʬͰϲ̯ͱϳдѴгͳͰ̯̯ͭή̯ǧž|vvǪϳ̵̷͸͸̵˴˴ʳʰʰɯȮȬ{^{TtOvScz÷ʾıʸȶȶ̸Ͻϻ̶ʲȰȮǭ¦øtbwWxnKsiFxnKwT`r¹£ȿk~\\vUvS~[gyʿʾȼʾêưǱɲȱȳɴ̷ϼǷɸ˸˶ȲĪͿʻ|nb{[z[dmxqYnV>mQ;jP9fP8gV<qfJrȱɲ̵˴ɲϸ˴˴˴̵ͶηϸйϷϷζζͳͳͲͲ̱ʭ¦·ɪͰϲγγ˰ɮǮŬĮưȲʴδҸҸδͳϵϵ̲ŬȺ¶ȼʿűɵϺѼϼ˸ʷ˹ʺʺȸƳǵʸƵ¯ƳįïůůůȲͷȳǱǱɳ̶ͷ̶̶ͷ̶˵ʴɳɳɳɳɳ̵͵̲ǬũĨũĩĪɾð˸̼˺̻˺˸˸̹ʷǴŰïįíǰɰ̳ʹεͷͷͷͷͷͷͷͷ̶̶̶ʴȲůĮë¨ëƮȰȲȲʷʷ˹̺̺˹ʺʺʷɶȵɶ˸̹˸ʷʷʷʷ˸˸̹̹̹˹˹ͻͻͻͻ˹˹ʸ˹̺ͻͻͻͻͻ˹˹˹ʸ˹̺ͻͻμμͻͻ̺̺̺̺μϽϽооϽϽμооооϽμͻ̺˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻ͻͻͻ̺˹ʸɷȶȶȶɷɷɷʸʸʸ̺ιϺѼѼѼҽҽӾӾӾѺҸҸӹӹԺԺԺջԺӹҸҸҸҸӹռӺѺѺҼӽҼҼи˱ĩúgtS|lKnQnRtX}bku»Ǫ̯̮ˬˬˬšļzj^ajv¦Ȯ˱ͳϸʲ˰ʰɯƪçȿp{lMn_>qa@m]<p`>qPtĺƫͲз̳ԺϵҺҺҺҺҺҺҺҺѹҺҺҺҺѹиϵҵϰȪǺ}}^}lN{jLwfHwgFvgHxkIwWhswǼ¥ɬҵӵΰΰӵѴʭʭ̰na~]|\\zZgv¹qtWkZ<kZ>m^AteH|nQw\\zǾǫȬȬ̯ϲϵ͵ζζϷϷζζ͵͵̴ʲȰǯǯȰȮ¹`ujJqbCqbCrcDqbC}nQs©ĮʴλкϺϸѹѹѻкϹθ͵ͳ˰ƨƷ}_~kJubAscBveGrUmüʲͷͷθϹииϸжϸϸϸϸηͶ̵̵ηηͶηѺйĭxzYuVpQnPrTz`~Ī˳Ȯ̴з϶ԻվӽѻкззѸҹε϶϶зѸʱ¶tf{YrOykHvhE|nKwTguȽƧɪʭ̯βϳгϲͰ˭Ͱήϯήɩľollvťɬ˴˶̷̷˴˴ʳɲɯɯɯȮǫžtzT{T~YauĸȼŲɶ˹ɷɷͻоϽ˸ȲĮŭȰȮéʿøyi{[{qNzpMuU}tUh|úżu_wUvU\\lzõ¨ǭ¨ʾêĮůǰƯƱǲ˶ͺǴʷ̹ͷȱƭƪǪͿwnjou½ukSiQ9kO9jP9gQ9jY?tiMuɲɲͶ̵ʳй̵˴˴˴̵ηйһѹиϷζͳͳ̱̱Ͳ̱Ȭźõ·ż£ʭϲггеѶ̱ʯǮŬĮůȲʴ̲ѷҸϵδжжͳȱɱŮªªƮʴ̶˷̸лҽϼ˸ʷ˸ɹʺȸĴƴɷǶ±̹˸˹͹̸˷ʷ̸ǲůĮȲ̶̶̶˵̶̶ʴɳȲǱǱǱĮȲ̴˳ǭĩƬʰ˱ʹȲįðȶ˻ʹ̽ȹƵƵƵŴıƱƱƯȱʱ̳̳˲θθθθθθθθͷ̶˵ȲůíĮůɱȰǯɱ˳͵̶˵ɶʷ̺ͻͻ̺ʺɹʷɶȵɶ˸̹˸ɶʷʷʷ˸˸̹̹̹ʸ˹ͻμμͻ˹ʸʸʸ˹ͻͻͻͻͻ̺̺˹˹̺̺ͻμͻͻ̺̺̺˹˹˹μϽϽооϽϽμѿѿѿоϽμͻ̺˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻˻ͻͻͻ̺˹ʸɷȶǵȶȶɷɷʸʸʸ̺ϺѼӾӾӾҽҽѼѼѼѺййййѺһӼԽӼйѺһѻϹ͹ιккθͷӻжèq~\\rQ~nMnQw\\iy±ǹĸ§ƪɯ̱ͱ̰̰ͭΩ̦Ġ|jc`enèϴϴ˱éȮȮĨçæ£eviIm`>l]<k]:ugDtSyȾȭ˰̳ɰԺҸӻӻӻӻӻҺииζϷѹӻҺϷ˳ɭԵΫv|]~oP|mNsdEvgHxiL|oO~`uū̲еѵдҵԷαϲϳϳ̱ȭé¦Ķpc{[wW|\\ew¹ǾĻn|mPq`Dl]@qbEscIugL~cɿʮ˯ƬūͳֻϷϷϷϷϷϷϷϷϷ͵ɱŭªe|qQsdEl]>k\\=m^?}nQs©Įʴ̹ͷιϸиѹѻккϹϷжγɫǸ~anM{hHwgF{jLz]xʲ̶̶ͷθϹϷηηͶηηηͶ˴ɲȱȱɲʳʳ̵̵ì¸}fyYvVqRqRj´é˳ɯȰѸռҹջӺӺҹѻккϹվӼѺйηʳĮtcxVrP~qO~qO~^aiuǾäɩ˫ͰϲѳϱͰ˭ȫͭаͭug_esťɩȫȱɴ˶˶ʳ˴̵ηѷϵͳ˱çk{W[kǼʾ˿ï°²ŵʹͼνͻʷ̶̶̶˵ɱǭƪ¦Ǽuh}]wWdlt~ø{rc\\_mɻƮƮêíŮǰȱǰȲɳ˵̹ϼλ̶̹ʳȯƬǫƻþ¿riQhP8jN8kQ:gQ9jY?zoSȱȱȱ˴ηηȱɲʳʳ˴̵ͶͶϷϷηηϵϵϵϵ̱˰ʯɮȭȫūǪǬʭ̱ϴееγͲɰȯǮƭůưȲɳʳ̴͵ζϷиии˵˵˵˵˵̶κκллλͺ̹̹̹̹ɹɹɹʺ˹̺ͻμʹ˸˸ʷʷɶȶɴʴʴʴʴʴʴʴʴɳȲȲǱǱǱȲȲɳɳʲ˳˱ʰɰȯȯǱǱʵ̹ͻ̼˺;˾ǺĵôĲĲűƱǲɱ˳̲ͳβʹɳʷ̹λϼλ̹˸ʷɶȵȵȵƳıíʴ˵˵̶̶˵˷ʶ͹͹λλͺͺ̹˸ʷʷʷʷʷʷʷʷɶʷ˸̹̹̹̹˸ʸ̺μμͻͻͻμμμμͻͻ̺̺̺ȶȶɷɷʸ˹̺̺˹˹˹̺̺̺ͻͻͻμμϽϽооѿѿѿѿоооϽϽͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽͽμμμͻͻ̺̺̺ɷɷʸ˹˹̺̺̺μҽӾӾӾӾҽҽҽѼѼѺѺййѺһһӼԽֿֿӼѺѺӼѻкϻϻѼҼкθи˱ŻiwVpNoNvXh{˻ƪɬ̱ββͱͰͮЭͩȤ¼wmgcgrȫͰ˰ǫʰɭĨ¦¥ƽ~`sfDk^<k]:j\\9tfCtRzȾǬ˰̳ɰԺҸҺӻӻӻӻҺѹииииѹиϷ̴ɭ̩hsTyjKyjK~oRz]hnwǭ˱ѶҷҶѴѴҵгѴѴдγ˰ǭū¦tjcbfl~żúpoUraEj[>paDseJzlQi¦̰αȮǭγպϷϷϷϷϷϷϷϷζ̴ɱƮĬĬĬūĻg~sSufGn_@n_@qbCtWyƸƭư˵ͺθιϸиѹѻккϹζδ˰ŧĵ|apOnNoNsUfì̴ͷͷθϹϹϹͶͶ̵ͶηηͶ˴ɲȱʳ̵˴ʳ˴ʳ|g}]{[wXwXoĶĪ˳ȯȱиԻзԺҹҹҹѻѻккվӼйηͶ˴ǲūźumigddelwžæǩȪȫǪǪʪʭǧüvtxĽǧʭ˯ʳ˶͸̷˴˴̵ηδδ˱é{pgn~ƻ¦Ĭůï°²ŵʹͼνλ̸˸ͷ̶˵ɳǯūūçǼ{vy~¹zsotŭɱȰīíŮǰȱȱȲɳ˵ͷɵɵɳɳȱȱȯȭĪ¦Ƚ·ĽĿĿnkSjR:lP:kQ:gQ9jY?ynRǰǰǰ˴ͶͶɲɲʳ˴̵̵ͶͶϷϷηηϵϵϵϵͲͲ̱˰ʯɮɮȭʯ˰ͲϴееγͲʱɰǮǮưǱȲʳʳ̴͵ζϷϷии̶˵˵˵˵̶͹κлϺλ̹˸ʷʷʷʸ˸ʺ˸˹̺ͻμʹʹ˸ʷʷɶɶɶʴʴʴʴʴʴʴʴʴɳɳȲȲɳɳɳʴʴ˳˳˱ʰɯȱȲȳȳʷ̺ͻ˻ɹ̽ʽǺŶôĲųƲƱǲʲ˳ͳͳβʹʶʷ̹λλλ̹˸ɶɶȵȵȵǴƳı˷˵˷˵˷˷˷˷κκλϼλͺ̹̹˸˸˸˸˸˸˸˸ɶʷ˸̹̹̹̹˸ʸ̺μμͻ̺ͻμμμͻͻͻ̺̺̺ʸʸʸ˹̺ͻͻμͻͻͻͻμμϽϽμμϽϽϽϽϽоооооϽϽμμͽͽͽͽͽ̼̼̼ͽͽͽͽͽͽͽͽμμμͻͻ̺̺̺˹˹˹˹̺̺̺̺ͻԿӾӾӾӾҽҽҽѼһѺѺѺѺһӼԽԽֿֿվӼһһӼҾнмѽҼкʳ¨y`sRrPwUdzɹ©Ȯʲʱʰ˱ε϶϶ϵδͱҳѮΫȥý|rd`brźƨ̭ʮ˯ȭĩææȽ·y}]reCl_<k^;k^;uiCvT{ɿǬʯ̳ʱԺҸҺҺӻӻӻҺѹиҺиϷϷϷϷ͵̰ǣǹo}\\}nO|mNrUgzźȩбϵѹռռӹжϴϴҷҷжжεʹ˳˱̱¥~qgdbt¹quZueKm]CscI|nSy^vŻĨͳϵ˱ʯεӺϷϷϷϷϷϷϷϷ͵˳ɱǯŭŭƮƬƽjvVxiJrcDteFyjK~a˲Ȳ˵ͺϹιϸиѹѻккϹ͵̲ȭzewVzZ|[ctùǰθκϻϻϻϹθͶ̵˴̵ͶͶ̵˴ɲǰͶη̵ɲɲǰƾ~mghffyʺƬ̴ʱɲϷҹζҸѸѸѸѻѻһһԿѼϹθͷ̶ɶȰɭǨ£Ļuqlkrzþ¥ħŨƪŨĨ»žĨɬͱϳͶιϺι̵˴̵Ͷ˱̲Ȯ}{||ũƬȯȲï°òƵ˸λϼλ̸̶ͷͷ˵ɳȯǮǮǬƫŨ¥ƽ÷źƻʿĬȲʴɳů«ìƯǰɱɱȰȰ̳ͷĮůưǱȰȱʰʰʱɮƫèɿȾȾƽĽ½jmUmU=oS=lR;gQ9kZ@zoS»ǰƯƯɲ̵̵ʳʳʳ˴̵̵ͶͶϵϵϵϵϵϵϵϵжϵϵδδͳͳ̲ʹε϶ѸѸзεʹ˲ʱȯǮǮȯɰ˱˴̴͵ζζϷии͸͸̷̷̷͸ιϺϼλ̹˸ɶȵȵȵʷʷ˹˸̹ͺͺλ˸˸˸ʷʷɶɶɶʴʴʴʴʴʴʴʴ˵˵˵˵˵˵˵˵̳ʹ̴̴˳ʲɱɳʵɶɶʷ̺̺˸ɹ˼ɺǸŶĵĳŴƳǲȳʳ˴̳ʹʹʹʶ˹̺μμͻ̺˹ȶȶȶȶȶȶȶȶ̹˷ʷɵɶʷ˸̹ϼϼϼϼϼλͺͺ˸˸˸˸˸˸˸˸ɶʷ˸̹̹̹̹˸ʸ̺μμͻ̺ͻμμͻͻͻ̺̺̺̺˹̺̺ͻμμϽϽμμϽϽϽоооϽϽϽϽμμμμϽϽϽμμμͻͻ̼̼̼̼̼̼̼̼ξξξͽͽͽͽͽͻͻͻͻ̺̺̺̺ͻͻͻͻ̺̺̺̺̺ԿԿԿӾӾӾҽҽҽһһһһһӼԽԽվվվԽӼӼԽԽҿѾҾӿӽѹŮnwXqNvR_n˽ʰδϵзϵϵδ϶зѸѷиʹѴааа˫ſmc|\\atƼťɬʮȭŪŨħɾy]viFpc@ob?na>xlF{WǬʯʹ˲ԺѷѹҺӻӻӻҺѹѹӻиζζиҺиαǡöubxUsT|_k}ɾĨçǫϲԷҺԻԻջӹжγͲѶеͳ̴̲̲̳ʹδʮ§Ļphcq·s{`}mSwgMsXfsƿũͳϵγ̱ʹзииϷϷϷϷζζ̴˳ɱǯŭĬĬĪƽn|\\pQ{lMpQvWoǭεȲʴͺϹιϸиѹѻккϹζͳǬʿ~ncjoxʳϹммммϹθ̷˴ʳ˴̵Ͷ̵˴ɲȱ̵η̵ɲǰƯzx{|{óʰηε̶йѹζзззѸѻѻӼӼӾѻθ̶˸͹̸˵ɯʭɭǫçĽþħħƪũçƿĽ»»ĽũǫǫȬͱѷϸлѼϺͶ˴̵Ͷʰ˱ūŸĤʬǭŭůƲñ°òǴ˸ιϼϹ̶ͷͷͷ̶ʴȯǮêŬȯ˲˲ɰƭī̿ʾøƻʿ¨¨ůǱɳȲůíĭĭƯǰɱɱȰȰ˲ʹĮůưǱȰɱʰʰ̲̲˲ʯɮȭǬƫ¥æ¤¿½hkSmU=pT>lR;iS;o^DtXü«ǰƯŮȱ˴˴ʳ˴˴̵̵ͶͶͶδδδδδδδδϵϵϵϵϵδδδзѸѸѸѸзεʹ̳˲ɰȯȯȯʱ˱͵͵͵͵ζϷϷиλ͸̷̷̹͸ιιͺ̹˸ɶȵǴǴǴ˸˸̹ͺͺλλͺ˸˸˸ʷʷɶɶɶ˵˵ʴʴʴʴɳɳ˵̶̶ͷͷͷͷͷεε͵͵̴˳ʴɳ˸ʷɶʷ̺˹˸ɶȸȷǶƵŴƳǴȳȳɴ˴̵ʹʹʹ̶˸˹̺ͻͻͻ̺˹ǵȶɷȶǵȶɷʸͺ˸ɶȵȵɶ˸ͺϼннннϼλͺ̹̹̹̹̹̹̹̹ɶʷ˸̹̹̹̹˸ɷ˹ͻμ̺̺̺μͻͻͻ̺̺̺˹˹˹˹̺ͻͻμϽϽμμμϽϽоооооϽϽμͻͻͻμμμͻͻ̺̺̺˻˻˻̼̼̼̼̼Ͽξξξξͽͽͽͻ̺̺̺̺̺̺̺ϽϽμͻͻ̺̺̺ʸӾӾԿԿԿӾӾӾҽҽӾӾҽҽӾԿԿӾҽӾԿѼηì~cpOykHuQcyŭѸѸзϸηҺиϹкѻӼѺεгбϱҴҴʪ{j^^hv¸ħƫɬǪƩƩʿĹz_wmIqgCqe?pd>{oI\\ĩɮ˰ε̳ջжѹѹҺӻӻӻҺѹӻиζϷӻԼѹͰͿh~WvS{\\pǻūɯ˰ϲѴгѸккѺҺи϶εε̳ʲȰǰȱɳ˲̲ͰʮŨǼup{·yi{a|aoǽūʰͳεʹʹεиииϷϷζζζ̴˳ɱƮëſżvh~_|]biõ˱εǱʴ̹ͷιϸиѹѻккϹиδʯ¤ĵ}v}ʼƭ̵кммммϼϹ͸̷ʳ˴̵ͶͶ˴ʳɲʳ̵˴ȱǰȱĭƿƶϿȯͳйѸкһҺи϶ζззкѻһһӽк̸̹ͺλͺιɰʯ˱˱˱ʰȮǭŧǼĹø·»ž¨ééɯȮǭǭƬūĪĪĪǭɯȮƬǭ̲жйѼѼлͶ˴̵Ͷ̲ʰūĽǼĦ̮βɮī¬®ıðıǴ̶ϷкϷͷε϶εʹ˲ȲưíưɳʴȲưűǶŵƵǴǯéȽźɾŨʭ˰ʱǮĮïűƲƲƱŰŰƱȲɳʲɱɰɰ˲ʹɰɰɰɰʱʱɱɱȰɯʰ˱ʱɰǭǭææ¤h~hPmU=qU?mS<lV>veK}ažĭȱƯĭȱ˴˴˴̵̵̵̵ͶͶͶδδδδδδͶͶ͵͵͵ζζζζͶѻѻѻкϹθθͷ̶˵ʱɰɰɰʱ̲ζθͷͷͷθϹкμλͻ̹̹̹ͺλ˸˸ɶȵǲǲǲǲͷͷθϹкϹϹθ̶̶̸˷˷ʶʶʶ˵˵˵ʴʴɳɳɳ˵̶ͷϹϹϹθθ͵͵͵͵ͷ̶˷ʶͺ̹˸˸˹˹ɷǴǴǴǴǴǴȴȴɳɳʴ˵̶εεε̶̹̺̺ͻ̺̺̺˹ȶɷʸȶƴųȶʸ˻˺ɸǶǴɶ˸̹ϼнннѼлϺι̹̹̹̹̹̹̹̹ɶʷ˸̹̹̹̹˸ɷ˹ͻͻ̺˹̺ͻͻͻ̺̺̺˹˹˹ɷɷʸ˹̺̺ͻͻ̺̺ͻͻͻμμμϽϽϽμͻͻ̺̺μμͻͻ̺̺̺̺˻˻˻̼̼ͽͽͽϿϿξξͽͽͽ˹̺̺̺̺̺̺̺ϽϽμͻͻ̺̺̺ɷҽҽԿԿԿӾӾӾӾԿԿӾӾԿԿӾѼѼӾҿιʳǿw~^{lKvhCuQfʱѷϵδηͶӻиθϹҼԾҼϹγͰͰгҵͯãxlffgtȽĩʭɬƩŦǼv^wmIqgCrf@rf@tNbɮ̱ͲзʹջϵиѹҺӻӻӻҺҺӻиϷѹԼҺ˳ħo[yRyVf~éǭʲ˳ϴӸӶͲ϶ͷͶηѹҹзε̳˲ʱǯƯǰǱɲͳϵд̯ǩĵôǺƻyv{ĸɿĩĪūȮʰʹεεεѹѹиϷϷζ͵͵˳ʲȰƮëľýƽ|vuzδʹǱ̶ͺ̶ιϸиѹѻккϹижͲǩ̽ĵ±Ƕ˽éɰ̷Ϲϻммѽϼϼι͸˴̵ͶηηͶ˴ʳɲ̵̵ȱǰɲȱũäʿãťĤĪɯ˲δйҺҼӼҺϸзϷззккѺѺҼк͹͹λλͺ̹ȱɲʳʴ̶θϹкϱ̰ͯ˯˯ɭŪ§ççĪūūūĪĪ˱˱˱˱˱ɯȮȮƬƬǭǭǭɯ̲ͶϺлѼϺͶ˴̵Ͷͳ˱ǭūũĨç¦Ȭ̰дδʱĮ®ıðıǲ̴Ϸиϵϵ϶϶϶ε̳ȲǱíůǳȴȴǳųĲȸŶȸ˸̶ȰūǫǫʮϲеѸθ˵ɵĲĲİűƱǲǲǲȲɳʲɱȯȯʱ̳̳̳̳˲ʱʱȰȰƮǯǰȮǮǮƬū¥æĦä¤f|fNmU=rV@oU>oYA}lRiƯɲƯŮȱ˴̵̵̵̵ͶͶͶͶͶͳͳͳͳͳͳ̵̵˳˳̴͵͵ζζζһккϹϹθθθθ̶̳ʱɰɰʱ̲ϹϹͷ̶̶ͷϹкϽμͻ̺̹̹ͺͺɶɶȵȵȳȳɴɴ͵ζиѻѻкϹθ̶̶̸˷˷ʶʶʶ̶̶˵ʴʴɳȲȲ˵̶θкккϹθ̴͵͵ζθθ͹͹λͺ˸̹˹ʸȶųűůƲǱȴɳʴʴʴ˵̶ͷεεεͷͺͻ̺̺̺˹˹˹ʸ˹˹ǵñĲȵʺʹɸȷȵɶʷ˸ϼϼϼϼлϺιι˸˸˸˸˸˸˸˸ɶʷ˸̹̹̹̹˸ȶʸͻͻ̺˹̺ͻ̺̺̺̺˹˹˹ʸȶȶȶɷʸ˹˹̺˹˹˹˹̺̺ͻͻμμμμͻͻͻͻμμμͻͻ̺̺̺˻̼̼ͽͽξϿϿϿξξͽͽ˹˹˹˹̺̺̺̺ͻͻͻͻ̺̺̺̺ɷҽҽԿԿԿӾӾӾԿԿԿԿҽллӾμʵƯr~^qPqL]uéδδ̲ͳиѹӽϹ̶θҿҿкε̱ʰ̯αͯɩƤļxoemźŪαˮŧɾu^wmIsiEsjCvmF}TmγϴϴѸεջδиѹҺӻӻӻӻҺԼѹиҺӻ͵scXWbsƸʰε϶εѶպոе϶̶̵ͶѹӺѸ϶εʹ̳ʲɲȱȲɲϷҸҶα̮ͭƥξ̼̼ο¢úĶʾŬȯǭǭǯɱεѸҹҹѹѹиϷϷζ͵͵ʲɱȰǯĬªſĻȹοʭж̳ɳϹϼ̶ιϸиѹѻккϹϷѷе̮ŨϼϼϼϾŪǭɰ˶ͷκϼнѾннϺϺ̵ͶηϸϸηͶ̵ʳͶͶɲȱʳʳɭή̨˪ήϯή˱ͳ̳ͳηҺӽһѹϸѸжззϹϹлϺнλλλϼλ̻ʷȴɴʵ˶͸Ϻϻϻдϳϳдϵδ̱ʯ˱˱ʳɲʲɱɱȰ̵̵˴˴ʳʳʳɲǰƯŮƯɲ̵ͶͶιϺлϺ̵˴̵Ͷ̲̲˱˱˯̰̰̰δδδ̴ɳű®ıðůȲ̴ϵжгϳдддϵͳʳȱƱǲȵɶɶȵǶŵȻƹȹͽͺɱȮ̲ͳδϴзϹϻκμȶǵƴƴǴȵȲȲɳʴ˲ʱȯȯʱ̳˱˱˲˲ʴɳɳɳȲȰǰƯƭƭūūƿæŧŦ¤}b}gOoW?uYCqW@r\\DpVnéȱ˴ǰŮȱ̵ͶͶͶͶͶͶͶͶͶͳͳͳͳͳͳ͵͵˳˳̶ͷθϹϹкѼϻϻκκκθθϹͷ̳˲ʱʱ˲̲кϹͷ̶̶ͷϹкнϼλͺ̺̺̹ͺǴǴǴǴȳʵ˶̷ζϵѷҺҺѹзεʹʹͶ̵̵˴˴ʴ̶̶˵ʴʴɳȲȲʴ˵θкѻкϹθ˳̴ε϶Ϲϻϼϼϼͺ̹̹̹˸ǵŲĮŭưȰɳʲ˳˳˳̴͵͵ζζͷͷλͻ̺̺˹˹˹˹̺ͻ̺ǵĽŲȸɸɸɸɸɸɸɸλλλϼϺι͸͸˸˸˸˸˸˸˸˸ɶʷ˸̹̹̹̹˸ȶʸ̺ͻ˹˹˹ͻ̺̺̺˹˹˹ʸʸǵȶȶɷʸ˹˹˹ʸ˹˹˹̺̺̺̺̺ͻͻͻͻͻμμϽμμμͻͻͻͻ̼̼ͽξϿϿξξͽͽʸʸʸ˹˹̺̺̺˹˹˹˹̺̺̺̺ʸӾӾԿԿӾӾӾԿԿԿҽϺлԿѾм̶ǰĪoc{[|]p¦ʲи͵˳ζҺԾҼθ˵θҿѻ϶ʹɯɯˮ̯̯ͭɧº}mq¹ƫгͰĦʿɾɾxayoLvlIwmI|rNaxҶѸѷҹϵԺδииҺӻӻӻӻӻսҸѷӹҸȮoa]dr´¦ʯ϶ѸзѶԹֹҷѸηͶϷѹӺѸ϶зз϶ζ͵˴ʳʳиӹӶͱαѳаɧȧǥƦƦåǾ¶ƺĩŬƭʰʰȮǯɱ϶ӺռԻѹѹиϷϷζ͵͵ɱɱȰǯƮĬë¨ũ¥ͿæʭʯѶѷ̳˴ѼҼͷηϸиѹѻккϹζжѶϳɮƩŦƧçūȭɯȰȲʵ̶ͺκμнннлл̵ͶϸййϸηͶ̵ϸϸʳȱʳ˴ʰҵѱбӴӵѵγδ̲ʳ̴ѸҼѺϸηҹѸѸзϹθϺιкλλϻмκ˸ȵͺϺϼѼѾѽѾмеγγγззεδϵηͶͶζζζζͶ˴ʳɲȱɲ˴̵ʳǰƯȱ̵ϸϸͶ͸ιϺι̵˴̵Ͷʳ̵̲ͳ̲̲ϵѷѸ϶˳Ȳǳű°ʿıðůȲ̴ϵжϵдджжϵ̵ʳȱǲǲǴȵɶɶɸȸʽǺ˻пλʴɱεζεʹ˵˷͹Ͻоͻ̷ȶȳȵȳȲǱɳʴ˲ʱȯȯʱ̳ɱɱɱʱɳɳɳɳ˵ʴȱǰůƭǮǮéƩŧz]}iNrZ@v\\CrZ@s^CrXpūʳ̵ȱƯɲ̵ͶͶͶͶͶͶͶͶͶͳͳͳͳͳͳ͵͵˳˳̶ͷϹккѻлκκ͹͹κθϹϹθ̶˲ɳʱʴ˴ѹзεʹ̶εϹѸннλͺ̺̹̹̹ƳǱǴȳɴ˶̷ͶζϷѹӻҺѹϹε̶̶̶̵˵˴ʴʴ̶̶˵ʴʴɳȲȲɳ˵θкѻкϹθʲ˱ͳ϶кмѼнϼλ̹̹̹ʷǵıíĬưȰʲ˳˳ʹ̴ʹε϶϶϶εͷϼϼ̺ͺ˹˹˹˹ͻμͻƴž»ĽǷɸȸʹɹɸȸȷͺͺλλ͹ι̸̷ʷʷʷʷʷʷʷʷɶʷ˸̹̹̹̹˸ȶʸ̺̺˹˹˹̺̺̺̺˹˹ʸʸʸȶȶɷɷʸ˹̺̺˹˹˹̺̺̺ͻͻ˹̺̺ͻͻμμϽϽϽϽμμμͻͻͽͽξϿϿξͽͽʸʸʸ˹˹̺̺̺ɷɷʸ˹˹̺̺̺ʸѾҿտ׾ҷĥyprv˶ͷϹкѻкϹͺͺλϼнѾҿҿԾѹϵʰǭƬɬˮͯ˭ϯϯţæƩˮͰ̯Ʃżnbadj{ǭͳһӻη͵ϷѹйѺѺѺҸѷжϵϵϳѵѵͱž~hfjxĹŨϲϴѵҶҶҶҶѵжϷϷζζϷϷѸѹѹѹиϷζ͵̴˱ϲҵҵϳͰ̯̯ˮʭȫƩħ¦¥éūƬĭĭĬǯȰɱ˳͵ϷѹҺѻѻкϹϹθͷͷͷͷ˵ʴȲưůĬūƬǭɰ˲ʹ϶зѸҹѸη̵̵ηйϸϸϸϸϸиϸϸѺϸδʹʹʹ˰ɰǯǱȲ˵θι̷ɴ͸θϼлллллϸйѺѺйϸͶ˴ηͶͶ˴ʳɲȱȱδϵϵж϶ззѸʹϹҼԽһϸͶͶӼӼһһйηͶ˴ϸϺϺкϹθͷ̶ͷθмҼӿӽѾҼηηϸϸηͶ̵͵ϷϹϹкѻкθ̶ζ͵˳ʲʲ˳̴͵͵̴̴̴͵ζϷϷιлѼϺ̷ʵɴʵ̷˴ʵɲʳ˴ͶηӼѺ̶ʵǲŰŰį­įȳ͸ϸηͶͶͶͶͶ̵ɴǲƱɴɴɴʵ̷ιнѾϽμͻ̸˷͸ͷϸϹϸͶ̷˶̷͸ιȳʲʵ̴˵ʲȰǯ˳˳ʲʲɱȰǯǯȱɴʵ̶˶̶˶ʵɴȳǲƱƱƯǰȲŲɶ˷˳ͱĥ`}jIua@p\\;s^?wdFsWyƭɯ˱ͳδͳ˱ʰȮ˱δϵδδδϵͶͶͶͶͶͶͶͶϸййѺѺѹйϸѽҾӿӿҾѽϻκϻκ͹̶̸̶̸ηжжδͳ͵δижϼ̹ʷʷ˸θ͸̷ȳȱǳǱɳ˵θйҼҼҼѻкϹͺͷ̹˸˸˷ʷ̸˸̹˵˵̶̶̶˵ʴɳɳ˵ͷϹкϹͷ̴δϲѴѷҹѻһҽϺι˸ȵƲİïïƲǱȴɳʴʴʴ˴ʹʹͱͱββϳ϶λν̼̻̹̹ͺͺ˷ϻϼǴ»ž°Ƴȶ̹̺̹ɷȵ˹ͺ̺ͺ̺̹ʸʷƴǴǵȵȶʷʸ˸ƴȵɷ˸˹˸ʸɷ˹˹˹˹˹˹˹˹ʸ˹˹˹˹ʸɷȶʸʸ˹̺μϽооϽμμͻͻ̺̺˹˹˹˹̺̺̺ͻͻϽϽϽμμμͻͻͻͻμϽоѿѿѿѿϽμͻ̺̺ͻʸʸʸʸʸʸʸʸɷɷɷʸʸ˹˹˹˹нѾҿҼҷίǾ{vu}¶ĳ˺ͺλϼϼϼϼλɶʷ˸̹ͺϼнѻѹϵ̲ɯȮɯ̯ͰгӶҴ̮å½þ¢Ǫɬ̯ͰʭŨȿżvy|ü˱иԼԼи͵ζийѺѺѺҸѷжϵϳβͰˮŨxnpzøåˮͰαϲϳдѵѵджϷϷζζζζϷϷϷииϷζ͵̴˱ʰαѴҵѴϲαϲѴгϲͰ̯ʭɬȫĬŭƮȰȰǯƮƮȰȰȰɱ˳͵ϷиккϹϹϹϹθθϹͷ˵ɳȲưưưŮƯǰɲ˴ͶϸйͶηϸη̵̵ηйϸϸϸϸϸϸϸϸѺϸͶͶηͶ̵ʳǲȳɴ̷ϺϺ͸ʵ͸ιϺллллϺηϸйѺйϸηͶͶͶ̵̵˴ʳʳɲ˴̵ͶηйѺһӼηѺԽվӼѺϸηһһһѺйϸͶͶͶηηϸϸϸηηϹкѻҼҼҼѻкԾӽӽӽӽӽӽӽӽѻϹкѻк̶Ȳ͵̴̴̴̴͵͵ζ̴̴˳˳̴͵ζζιлѼϺ͸ʵʵʵʵʵɴȳȳʵ˶͸лι˶ȳŰįîîîîŰɴ͸ϺϺιϺллϺι̷ʵɴʵʵ˶˶͸ιлѼѼлι͸̷͸͸ι͸̷˶˶ʵʵ˶˶ʲ˳̴̴̴˳ɱȰ̴˳ʲɱȰȰȰȰ̷̷͸ιιι͸͸ǲǲƱƱƱǲǲȵʻολͷͱ¤^pLxf@sa=ueC}lN|_Ƹȯʰ˱̲ͳ̲˱˱ȮʰͳδδͳδϵͶͶͶͶͶͶͶͶϸййййййϸмѽҾҾҾмϻκκκ͹̸̸͹͹ηѷжϵδδϵжѷϼ̹ʷɶ̶θ͸̷ɲɲȲȲʴ̶θлннннϼλͺ̹̹˸˸ʷʷ˸˸̹˵̶̶̶̶˵ʴɳɳɳ˵̶̶̶̶˳βϳѴжҹѸѺйϺι˸ɶǳƲƲűǳȴɵʶ˵˵˴˴̳̳̲̰ͳβϳϵͺͼ̻̻̹ͺλλ͹ѽнǴüĲųȶʸ˹ʸɷȶʸʸʸʸʸɷȶǵƴǵǵȶɷʸʸ˹ǵȶɷʸ˹ʸʸɷ˹˹˹˹˹˹˹˹ʸ˹˹˹˹ʸɷȶʸʸ˹̺ͻϽϽоμͻͻͻͻͻ̺̺˹̺̺̺ͻͻͻμϽϽμμμͻͻͻ̺̺ͻμϽооѿооμͻ̺̺̺̺ʸʸʸʸʸʸʸʸɷɷɷʸʸ˹˹˹˹ѾнннѾҿҿҿҿϹγɪĻzx|·óνͼλλλλϼннɶɶʷ˸ͺλϼкиϷζ͵̲̲ͰͰҵӶӵв̮ͯͯϱ̯ͰͰ̯ɬŨǾ˯ϵӻ־սѹζζϷйѺѺѺҸѷжϵѵϳˮǪzu~·ƨʭ̯ͰαϳϳддϵϵϷζζ͵͵ζζϷϷϷϷϷζ͵̴˱ʰαѴҵѴггѴӶӶӶҵѴггϲʲʲ˳˳ʲʲɱȰʲɱǯǯȰʲ̴ζθθϹϹϹϹкккϹ˵ɳǱǱȲɳƯǰȱʳ̵ηϸйɲ˴ηηηͶηйηηηηηηηηѺϸͶͶηηͶ˴ǲǲɴ̷Ϻлι̷͸ιϺлллϺϺͶηϸйййϸϸ̵̵̵̵̵̵̵̵ʳ˴ͶηйһԽԽйһվֿԽѺййѺѺһһѺйϸη̵ͶηϸййййѻѻҼҼҼѻкϹտԾӽӽԾԾкͷϹҼҼθɳ̴̴͵ζϷϷϷϷ̴˳˳˳˳̴͵͵ιлѼл͸˶ʵ˶ʵɴȳǲȳɴ˶̷ι̷ʵǲŰî­­ŰŰǲʵιллϺлллϺι͸˶ʵ˶˶˶̷͸ιлѼҽѼϺι͸̷̷̷̷̷̷̷̷˶ʵʵ˳̴͵ζ͵̴ʲɱ͵̴ʲȰǯȰȰɱ͸ιιιιι͸̷ƱŰŰƱƱǲɴɶ̻онθ˯ɾ~`tP{kGvfD|lJxZnʾʱʳʳʳʳ˴̵̵ǰɲ̵̵˴˴̵ͶͶͶͶͶͶͶͶͶϸϸϸϸϸϸϸϸϻммѽмϻκκκ͹͹͹͹͹κлйѹииииѹѹϻ͹ʷɶ˸̹θͷ̶̶˶˶̷ιϺлннннϼλͺ̹̹˸˸ʷʷ˸˸̶̶̹ͷͷ̶̶˵ʴȲȲȲȲȲɳɳʲϵϵϵжззθͷ͹̸˸ʷɶɶɶɶɵʶ˷̸̶̶̵̵˴˴ʳʱ˴˲ͳζ̹˸˸˸̹ͺκϻѽӿнȵĽý¯ƴǵǵȶɷʸʸʸʸʸ˹˹˹ʸɷȶǵȶȶɷʸ˹˹̺ȶȶɷʸʸʸʸɷ˹˹˹˹˹˹˹˹ʸ˹˹˹˹ʸɷȶɷʸʸ̺ͻμϽϽ̺̺̺̺ͻͻͻͻ̺ͻͻͻμμμϽμμμͻͻͻ̺̺˹˹̺̺ͻμμϽϽμͻ̺˹˹˹˹˹˹˹ʸʸʸʸʸɷɷɷʸʸ˹˹˹˹ҿҿϼͺннѾҿҿѾѾнθͲʭȿƻñɹпϼϼͺͺͺϼнҿϼϼϼϼϼϼϼкϹиииϵδͳαгϲΰϱвѳҴҴααͰˮɬƩħæƽǾħǪǪʭджӻսԼҺииѹйѺѺѺҸѷжϵҶд̯ȫ¥ȽŧŧŧƩȫͰαϳддджжζζ͵͵͵͵ζζϷиииϷζ͵͵ʰͰгѴѴгѴҵҵҵҵҵҵҵҵѷζζ͵͵̴˳ʲɱ̴ʲǯŭŭǯʲ̴ͷͷθϹϹкѻѻҼк̶ɳǱȲʴ˵ȱȱʳ˴̵ηϸϸʳͶййϸηηϸηηηηηηηηѺϸηηϸϸη̵ȳȳɴ˶ιлϺ͸ιιϺлллϺι̵ͶηϸййѺѺ̵̵ͶͶηηηϸ̵ͶηϸйһӼӼйһԽվӼѺйййѺѺһһѺйϸηηϸйѺѺййккѻѻѻѻѻѻԾӽѻккҼԾѻͷʴͷӽӽθ˳͵ϷиѹѹиϷ˳˳ʲʲʲ˳˳̴ιлѼл͸˶˶̷˶ʵɴȳɴʵ̷͸ι͸̷ʵȳƱŰŰȳȳȳ˶ιллϺϺιι͸̷˶ʵʵ̷˶˶˶̷͸ιϺҽѼлι͸̷˶˶͸ιϺлϺι̷˶̴͵ζϷζ͵˳ʲζ̴ʲȰǯȰɱʲʵʵ˶˶˶ʵɴȳŰŰŰƱǲɴʵ˸̻νͺʴũ·z`uS~nJ{kIuTg~ŭ˵˴ɲȱɲʳͶηȱʳ˴̵ʳʳ˴Ͷ̵̵ͶͶͶͶηηϸϸηηηηϸϸϻϻϻϻϻϻκκκ͹͹͹͹κϻϻйѹѹѹѹѹѹѹϻ͹ɶɶʷ̹ͷͷͷͷͷθ͸ϹϺкϼϼϼϼϼλͺ̹̹˸˸ʷʷ˸˸̹ͷͷθθͷ̶˵˵ɳȲǱůůǱɳʴζϵϷϷ϶ε̶˵͹̸˸˸˸˸̸̸̹̹͹͹ͷ̶̵̵ʳʳɴɲɴʳ˶̷ʶʶʷ˷̹͹ϻмҾӿнȵƿüưɷȶǵǵȶɷʸ̺ͻͻͻͻͻ̺˹˹ȶȶɷʸ˹˹̺̺ɷɷʸʸʸʸʸʸʸʸʸʸʸʸʸʸʸ˹˹˹˹ʸɷȶȶɷʸ˹̺ͻμϽ˹˹˹̺ͻͻμμͻͻμμμϽϽϽͻͻͻͻ̺̺̺˹ʸʸ˹˹̺̺̺ͻͻͻ˹˹ʸʸʸ˹̺˹˹˹˹ʸʸʸɷɷɷʸʸ˹˹˹˹ҿѾλ̹нѾѾҿҿѾннкзϲȩȿżȿæƭʴϽнϼλͺλϼѾҿҿнϼλϹϹииѹѹжδδϲͰˮ̯ϱѳѳвͲ̱˰ʯɮȭȭȭǬǬɮͲγ̱̱βжѹӻӻӻҺӻԼйѺѺѺҸѷжϵдβ̯ʭǪæžǩΰϱˮȫʭͰϳϳдѵҸҸѷѷϷζζ͵͵ζζϷѹѹҺҺҺѹии˱ͳϵжϵжѷӹжжѷѷҸҸҸӹиϷζ͵̴˳ʲʲ͵˳ȰƮŭǯɱ˳̶ͷͷθкѻѻҼӽкͷʴɳʴ̶ͷʳʳ˴̵ͶηϸϸηѺӼӼѺϸηηηηηηηηηηѺйηϸййϸͶʵɴɴ˶ιлϺιιϺлллϺιι̵ͶͶηϸѺһһͶͶηηϸййййййййѺѺѺϸѺӼӼѺϸϸϸѺѺһһһѺййѺѺѺѺѺйϸηθθϹкѻӽԾտԾҼкϹϹкӽԾѻθ˵ͷҼտӽк̴ζϷѹѹѹиϷ̴˳˳ʲʲʲ˳˳ιлѼлι̷̷͸̷̷˶ʵʵ̷͸ϺййϸηͶ˴ʳɲʳɲɲ˴ηййϸϺϺι͸͸̷̷̷̷˶˶ʵ˶˶̷͸ѼѼлϺι̷˶ʵ̷͸ιϺι͸˶ʵ͵ζϷϷϷ͵̴˳ζ͵˳ɱȰȰɱʲǰȱȱɲɲȱǰǰŮŮƯǰȱʳ̵θϼϾ̹ưžv`{XwTxWcx̾˳̶̷ɴȳɴ˶͸Ϻɴ˶̷˶ʵʵ̷͸̵̵̵ͶͶηηηϸηͶ̵̵ͶηϸϹϹϹθϹϹϹϹϹθθͷͷθϹϹллллллллϻ̸ʶɵ˷̸͹̸͹κκκλϻͺͺλλϼϼλλͺ̹̹˸˸ʷʷ˸˸̹θθθθθͷ̶̶˵ʴǱůůǱɳ˵ͷ͵θθͷ̶ʷɶ˸˸˹˹˹̺ͽμ͹ͷθͷ͹̸˷ʶȴȴȵȴȵɵʷ˷ʶʴɶʴʷͷθϹѻҼѻʴíĮȲ˹ɷȶǵǵɷ˹̺̺ͻͻͻͻ̺˹ʸȶȶɷʸ˹˹̺̺˹˹ʸʸʸʸʸʸʸʸʸʸʸʸʸʸʸ˹˹˹˹ʸɷȶǵȶɷʸ˹̺ͻμʸʸ˹˹̺ͻͻͻͻͻμμμϽϽϽͻ̺̺̺˹˹˹˹ʸʸʸʸ˹˹˹˹̺̺˹ʸʸʸʸ˹ͻ̺̺˹˹ʸʸʸɷɷɷʸʸ˹˹˹˹ҿҿнϼҿҿҿҿѾннξкѸӸгʫŨɬ˰̳θӿϼϼϼϼϼнѾѾҿѾϼͺ̹˸ϹиииииϵϵгϲααϱѳѳвβͲ̱˰ʯʯ˰˰ͲͲϴеѶϴγϳииѹҺҺӻԼԼйѺѺѺҸѷжϵ˯˯ˮˮʭɬȫȫʫͯϱͯʭȫˮϲϳдѵҶҸҸҸѷиϷϷζζϷϷиҺҺӻӻӻӻҺѹͳδжжϵϵѷӹѷҸҸҸӹӹԺԺѹиζ͵̴˳˳̴ζ͵ʲɱȰɱ˳̴̶ͷθθккѻҼҼѻθ̶˵̶ͷθ̵̵̵ͶͶηηϸѺӼԽӼйηηϸϸϸϸϸϸϸϸϸһйϸϸѺѺйϸ̷˶ʵ˶ιϺϺ͸ϺϺлллϺι͸ͶͶͶηϸйһһηϸϸϸйѺѺѺһѺѺѺййййϸѺһһйηηϸһһӼӼһѺйϸӼӼӼһһйϸηͷͷθϹѻԾտԾҼѻѻѻҼӽտӽкϹккϹθϷϷϷииϷϷζ͵͵̴˳˳˳˳̴ιлѼлι͸͸ι͸͸̷˶˶͸ιϺѺѺѺѺйηͶ̵̵ʳɲʳ̵ϸϸηҽҽѼлϺϺлл͸͸̷˶˶˶̷̷лллϺι͸˶ʵʵʵʵʵʵɴȳǲ̴͵ζϷζ͵̴ʲ̴̴̴˳ʲɱɱȰǰǰȱɲʳʳɲɲȱȱȱɲʳ̵ηкҿ̸ưüzkjkp|ɹƬζ̸̷ʵɴɴ˶͸Ϻ̷͸͸̷ʵʵ̷ι˴˴̵ͶͶηϸϸϸη̵˴˴̵ηϸкϹϹθϹкѻѻѻкϹθθθθθϺϺллллϺϺκ̸ɵɵ˷̸̸̸͹κκκκι͹̸ͺͺλλλλͺ̹̹˸˸ʷʷ˸˸̹θϹϹϹϹθͷ̶̶ʴȲưưǱɳʴ˵˵̶̶̶˵ɶɶ˸˸˹˹˹̺ͽμκθθͷ̸˷ɵɵɶȵȵȵȵɶɹ˸˵ʲʴʴ˵̶ͷθθϹϹ˵ưĮưɳ˹ʸɷȶȶɷʸ˹ɷɷʸʸɷȶȶǵǵȶȶɷʸ˹˹̺̺̺˹ʸʸʸʸ˹ɷɷɷɷɷɷɷɷʸ˹˹˹˹ʸɷȶǵǵȶɷʸ̺̺ͻ˹˹˹˹̺̺̺̺̺ͻͻͻμμμϽ̺̺˹˹˹ʸʸʸʸʸʸʸʸʸ˹˹̺˹˹ʸʸʸ˹̺ͻͻͻ̺˹˹ʸʸɷɷɷʸʸ˹˹˹˹ҿҿҿҿѾн̻ннϸѷԸӷϲɭͱβ˱̵ѼνλϼннѾѾннѾѾнϼϼλͺͺϹϹϹϹϷϷϵжжжѴѴгѴҵӶддϳβͱ̰̰˯ϳддϳдѵѵѵҺѹииѹҺҺҺйѺѺѺҸѷжϵ˯̰ͰͰ̯̯̯Ͱ̯ͰͰʭǪƩɭ̰βϳжѷѷѷҹѸѹѹииииѹѹѹҺҺӻӻҺҺѹϵжѷжϵδжҸѷѷҸҸҸҸӹӹҺѹϷζ͵͵ζζϷζ͵̴̴̴͵͵ͷθθϹϹккѻҼѻϹθͷͷͷθͶͶͶηηηηηйѺѺйϸηйһййййййййһйϸйһһѺйι͸˶̷͸ιι̷ϺллллϺι͸ϸηηͶηϸѺһйййѺѺѺѺѺйѺѺѺѺѺѺѺйһӼһйϸϸѺԽԽԽӼһѺϸηѺһһӼһһѺйϹθθϹкӽտտտԾӽҼѻккԾտԾѻθͷθкѹиϷζ͵͵͵͵ζζ͵̴˳˳̴̴ιлѼѼϺ͸ιι͸̷˶ʵ˶̷ιϺϸϸййϸη̵˴̵ʳȱɲ˴ͶηͶӾҽѼлϺлѼѼллϺι͸͸͸ιιϺϺлϺι̷˶ɴɴȳǲǲǲǲǲ̴͵ζζζ̴˳ʲ˳̴͵͵͵˳ȰǯŮƯȱɲ˴˴˴˴ʳʳʳ˴̵ͶϸѻѾ̹Ȱŷ̾ƫ˱ζ˷̹˸ʷ˸̹ͺλλλλͺ˸˸ͺл˴˴̵ͶͶηϸϸηͶ˴ʳʳ˴ͶηѻкϹϹϹѻҼӽӽҼкϹͷͷͷͷ͸λϼннϼι͸θ̶ɳɳʶ̸̸̸ιιλλλ͹˸ʷ͹ͺͺλλλͺ̹̹˸˸ʷʷ˸˸̹ϹϹккϹθθͷ˵ʴȲǱưǱȲȲɵʵʶ˷˵˵ʵɴ˶˶˸ʷʹʹ̼ͻκϸϸη̸ʶȵǴɶɶȸȸȸɹɼʸ˶˱ʳɲɲʳ˴˴ʲ̴ͷ̶ɳǱȲʴ˹ʸʸɷɷʸʸʸȶȶȶɷȶǵƴƴƴǵǵȶɷʸʸ˹ͻ̺˹ʸɷʸʸ˹ɷɷɷɷɷɷɷɷʸ˹˹˹˹ʸɷȶƴǵǵɷʸ˹̺̺̺̺˹˹˹˹˹ʸ˹̺̺̺ͻͻͻμ˹˹˹ʸʸʸɷɷ˹˹˹˹˹˹˹˹̺̺˹˹˹˹̺ͻμμͻ̺˹˹ʸʸɷɷɷʸʸ˹˹˹˹ҿҿҿҿѾʹλλ̷ͶҸҸϳжԺӹ̵̷ѾҿͼͺλнҿҿѾнϼннннннѾѾϹϹθθζϷижϵжѷҵггӶոӷҶѵϳͱ̰ʮɭͱβͱ˯̰дҶҸԼӻѹииѹиϷйѺѺѺҸѷжϵϳдггαͰͰαҵҵгͰʭɬʮ˯ͱϲϵжжжѸзҺҺѹииѹҺҺииѹҺҺҺѹѹжѷѷжδδжѷϵϵϵжжжжжӻҺиϷζϷиѹζζζζζζζζθθθϹϹкккѻѻккϹθθͷηηηηηηηηηηϸηͶηѺԽѺѺѺѺѺѺѺѺһйϸйһӼһйлι̷̷͸ι͸̷лллллϺ͸͸йϸηͶηϸйһѺѺѺѺѺѺѺѺϸϸйѺһһӼԽһӼԽӼѺйѺһվվԽԽһйϸηϸйѺӼӼӼӼӼѻкϹϹкѻӽԾԾԾӽҼѻϹͷ̶кӽտҼͷ̶кտӻѹϷ͵̴˳̴͵ϷϷζ͵̴̴̴͵ιлѼѼϺιιϺ̷˶ʵɴʵ˶͸ι̵̵ͶηͶ̵ʳɲ̵ʳȱȱʳ̵ͶͶѼлϺι͸ιϺлӾҽѼлϺϺϺϺ͸ιϺлϺι͸̷̷ʵɴǲǲȳɴʵ˳̴͵ζ͵̴ʲɱʲ˳ζϷζ˳ȰƮìĭƯȱɲʳ˴˴̵̵̵̵Ͷηϸйϼ̹˵˳ȮĨȿȿĦɫ˯˰ͳ̵ͷ˷˸˸˸̹̹ͺλϼϼϼͺ̹̹λѼ˴˴̵ͶͶηϸϸηͶ˴ɲɲ˴ͶηѻѻкϹкѻӽԾԾӽѻϹͷ̶̶̶̷ͺϼϼϼϺ͸̷θ̳ɳɳʴ̶̸˷͸ιλλκ̸˷ȵ͹̹ͺλλλͺͺ̹˸˸ʷʷ˸˸̹ϹккккϹθͷɳɳȲǱưưưƲǴȵʵʶ˵ʵʳɳʴʶɵʷʷʹ˹ͺκϸηη˷ɵǴƳʷʷȸȸȸɹȼʹ˴̰ʱʰʰʰʳʳǯʲ̶ͷ˵ɳɳʴʸʸʸʸʸʸʸʸɷɷʸʸʸɷȶǵƴƴǵǵȶɷʸʸμͻ˹ʸɷʸʸ˹ɷɷɷɷɷɷɷɷʸ˹˹˹˹ʸɷȶƴƴǵȶʸ˹̺̺ͻ̺̺˹˹ʸʸɷ˹˹˹̺̺̺ͻͻ˹˹ʸʸʸɷɷɷ˹˹˹˹˹˹˹˹ͻ̺̺˹˹̺ͻͻϽμͻͻ̺˹ʸʸɷɷɷʸʸ˹˹˹˹ҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿѾѾѾнϼϼϹϷииѷѹѹѹикλλλнѾѾнннϼϼϼλλλкккккиииижжѷҵӶӶӶжϵϵδͳͳ̲̲δδδδϵжѷҸ־սҺиϷиѹҺѺѺѺйѷжжжββαϲϲгггѴѴгϲͱ̰˯ʮϵϵиѸѸҹҹҹиѹѹҺҺѹѹиҺҺҺҺҺҺҺҺииииииииϷϷϷϷϷϷϷϷѹиϷζζϷϷи͵͵ζζζϷϷϷϹϹϹккѻѻѻϹϹϹккѻѻѻѺѺйηηηηηϸϸϸййѺѺѺһһһѺѺйййййййййййιιιιιιιιιιιϺϺлллйййѺѺһһһԽӼѺййѺӼԽѺййййѺһӼӼӼӼӼӼӼӼӼֿֿԽӼһѺѺѺййϸϸϸйѺѺѻѻҼҼҼҼҼӽԾӽѻϹθͷθθѻкϹϹѻѻкϹиииииϷ͵͵̴˳˳ʲʲ˳˳̴ιι͸̷˶˶˶˶ʵɴɴɴɴʵ˶̷ηδδͳͳ̲̲˱̲ͳδϵδͳ̲ʳϺϺϺϺϺϺϺϺѼѼѼѼѼѼѼѼѼлι̷˶˶̷͸ȳɴɴʵʵɴȳȳɱʲ˳̴͵̴˳ʲ˳̴͵ζ͵˳ȰǯǭƬĪĪĪƬȮʰ˱˱̲˱ʰ˱δйϺι͸̵˱ʮɭȫααϲϴδδζͷ͹ιιιϺϺллι͸̷̷̷ιлѼͶ̵̵ͶϸϸͶ̵̵˴ʳʳ̵ͶηͶʹʹԻ϶зҹ̳ɰεҹз̳ʴɵ˹κϻκ̸˷˵˴ǭŮɱ˳ʲʴͷͷ˵̷ικ̸ʶɶ˷ʷʷ˸̹ͺϼнʷ˸ʷȵƳƳɶ˸θϹкккθ̶˵ʴʴȲǱưưưǳ̸̸˶ȴưì©ŭĬíïűȵʸͺ̸йҽлʶǳƲƲǴȵƵĳɸп̾ųǮæʾǽĺȮ˱ϷζʴȲȲʴɷʸ̺̺ʸʸ̺ͻμͻͻ̺˹ʸɷȶƴƴƴǵǵȶȶȶ˹ʸɷȶɷʸ̺ͻ̺̺̺˹˹ʸʸʸʸ˹̺ͻͻ˹ʸɷǵǵƴƴƴǵȶɷɷɷɷɷɷɷɷɷ̺̺̺̺̺̺̺̺ʸʸʸʸʸʸʸʸ˹˹˹˹˹˹˹˹˹˹̺ͻͻμϽϽѿоϽμ̺˹ʸʸʸʸʸʸʸʸʸʸ˹ҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿѾѾѾнϼϼλϹииѹѹѹѹкϼϼλλѾѾҿҿѾѾѾнннϼϼϼλѻѻѻѻѻѻѹѹиижѷҵӶӶӶѷѷжϵδͳ̲̲ͳͳͳδϵжҸӹ־սҺиϷиѹҺѺѺййѷжжжββϲϲϲгггѴѴгϲͱ̰˯̯ϵϵзѸѸѸҹҹѹѹҺҺҺҺѹѹҺҺҺҺҺҺҺҺииииииииϷϷϷϷϷϷϷϷииϷζ͵͵͵ζ̴̴̴͵͵ζζζϹϹϹккѻѻѻϹϹϹккѻѻѻѺйϸηηηηηϸϸϸййѺѺѺһһѺѺѺйййййййййййιιιιιιιιιιιϺϺлллйййѺѺѺһһӼӼѺѺѺѺӼӼѺййййѺһӼӼӼӼӼӼӼӼӼֿվԽһѺѺѺѺѺйϸϸϸййѺӽӽӽҼҼҼҼҼӽҼкθθθθϹѻкθϹѻѻкϹϷиииϷϷζ͵˳˳ʲʲʲ˳̴̴̷˶ʵʵɴɴɴɴ˶ʵʵɴʵʵ˶̵ͶδδδͳͳͳͳͳδϵжѷѷжжлллллллллллллллллϺ͸˶˶˶˶̷ɴɴʵ˶ʵʵɴɴʲ˳̴̴̴˳ʲɱʲ˳̴͵̴ʲȰƮǭƬĪééĪƬǭ̲ͳδͳ̲̲δж̵Ͷ̵̵ͳ̲̰̯ʮ˯̰ͲͲͳ͵ʹ̶ηлѺлϸ͸˴ɴɲɴɲʵ˴͸η˴˴˴̵ηϸη̵̵˴ʳ˴̵Ͷηη϶϶Ӻ׾׾ӺӺռӺɰêǮ̳̳̳˵̸͹κκ̸ʴȲȯǬȾ¨ū̲ռѸϹθлϺκ̸˸̸˸˸˸̹ͺλλʷ˸˸ɶȵȵ˸ͺͷͷθͷ̶ʴȲǱʴʴʴɳȲȲȲȴ˷̷˶ȲĬɿŹĶŷĶĵĸǻƳʷɴ̵ι͸ɵǳǳȴȵʷȵǴɷ̺ƴɼ¶Ƭʲ˳ȲưǱȲɷʸ̺˹ʸʸ˹ͻ̺̺̺˹ʸʸɷɷǵǵǵǵȶȶȶȶʸʸɷȶɷʸ˹̺̺̺̺˹˹ʸʸʸʸ˹̺ͻ̺˹ɷȶǵƴƴƴƴǵȶȶɷɷɷɷɷɷɷɷ̺̺̺̺̺̺̺̺ʸʸʸʸʸʸʸʸ˹˹˹˹˹˹˹˹˹˹̺ͻͻμϽϽооϽμ̺˹ʸʸʸʸʸʸʸʸʸʸ˹ҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿѾѾннϼϼккѻѻѻѻѻѻϼϼϼλѾѾҿҿҿҿѾѾҿѾѾѾнннϼннннѻѻѻѻиижѷѷҸҸҸӹӹҸѷϵδͳ̲ͳͳͳδϵѷӹԺ־ԼҺѹииѹҺѺйййжжжжβϳϲϲггггѵѵдϳβͱ̲̲ζ϶ззйѺѺкѹҺҺӻӻҺҺѹѹѹѹѹѹѹѹѹϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷϷиϷζ̴˳˳˳˳ʲʲʲ˳˳̴̴̴ϹϹϹккѻѻѻϹϹϹϹккккййϸηηηηϸϸϸϸййѺѺѺһѺѺѺййййййййййййϺϺϺϺϺϺϺϺιιϺϺϺϺллййййѺѺѺһӼһһѺѺһһӼѺййййѺһӼӼӼӼӼӼӼӼӼվԽӼһѺѺѺѺѺйϸϸϸϸййԾԾԾӽҼҼѻѻѻкϹϹϹϹккѻϹθϹкѻкθϷϷϷиϷζζ͵ʲʲʲʲʲ˳͵͵˶˶ʵʵʵɴɴɴ̷˶˶ʵʵʵ˶˴̵δδδδδϵϵ̲ͳδϵжѷҸҸϺϺϺϺϺϺϺϺϺϺϺϺϺϺϺϺι͸̷˶ʵʵʵʵʵʵ˶̷̷˶˶ʵ̴̴̴̴̴ʲɱȰɱʲ˳˳ʲɱǯŭȮƬĪ¨¨¨ééɯ˱ͳͳ̲˱̲ͳǱȲɳ̲ͳͳͳͲȮȮʰ˱˲̳˳̳̳ϵѺԺһж˴ɯɲ˱ʳ̵̲δηηɲɲɲ˴ηϸη̵̵̵̵˴̵̵ͶηзѸѸҹֽԻ̳ŬĺɿīȯʱккϹͷȲëɽƺ»ɯ̲ʹʹͶηϺϺϺ͹˸˸˸̹̹̹̹˸̹˸ʷȵɶ˸λϹϹϹθ̶ʴȲǱɳɳʴʴʴɳȲǳ̷̷ʵȱ¨¸Ǵ̷ιι͸ʶɵʴ˵ŰƱűİĮ¬ƺzwuyžĪǭǮŬƯǱȶʸ˹˹ʸʸ˹ͻ˹˹ʸʸʸʸʸʸɷɷɷɷȶȶȶȶʸɷɷɷɷʸ˹̺˹˹˹˹ʸʸʸʸʸ˹̺̺̺˹ɷȶƴųųųƴǵȶȶɷɷɷɷɷɷɷɷ̺̺̺̺̺̺̺̺ʸʸʸʸʸʸʸʸ˹˹˹˹˹˹˹˹˹˹̺ͻͻμϽϽϽϽμͻ̺˹ʸʸɷɷɷʸʸʸʸʸ˹ҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿҿѾнϼϼккѻҼҼҼѻѻнϼϼϼѾѾѾҿҿѾѾѾҿҿҿѾѾѾннѾѾѾѾҼҼҼҼиииѷѷҸҸҸջԺӹҸжϵδͳͳͳͳδжҸӹջսԼӻѹииѹѹйййϸжжϵϵϳϳϲгггѴѴѵѵдϳβͱͳ̲ε϶϶϶ййййҺҺӻӻӻӻҺҺииииииииζζζζζζζζζζζζζζζζиϷ͵˳ʲɱȰȰɱɱɱʲʲʲ˳˳ϹϹϹккѻѻѻϹϹϹϹϹϹϹкϸϸηͶͶηηϸϸϸϸййѺѺѺѺѺѺйййϸϸййййййййллллллллϺϺϺϺϺϺϺϺϸϸйййѺѺѺһһһһһһһһѺййййѺһӼӼӼӼӼӼӼӼӼԽӼһѺййѺѺѺйϸϸηηϸϸտտԾӽҼѻкккккѻѻҼҼӽкϹθθкѻϹθζζϷϷϷζζ͵ʲʲʲʲ˳̴͵ζ̷̷̷͸͸̷̷˶̷̷˶ʵʵʵʵ˴ͳͳͳδϵϵжж˱˱˱˱̲ͳϵж̵̷̷̷̷̷̷̷͸͸͸͸͸͸͸͸̷̷˶ʵɴɴȳȳʵ˶̷͸͸͸̷̷͵͵͵̴˳ʲɱȰɱɱʲʲɱǯƮŭȮƬĪ¨ƿƿƿéƬɯ˱˱ʰ˱˲Ĭŭȯʰ˱˱˰˰ʯʯʰ˱˱ʱɱɰδϳѷӷҸдͳ˯̲̰ͳͱͳͱͳͳȱǰȱʳͶϸηͶͶͶͶ̵̵̵ͶϸзҹзʹҹռɰƼêǮккϹ˳ë¶wqmijpĪƬǮɰͶϸκ̹̹̹̹˸˸ʷɶͺͺ̹ɶǴǴȵ˸ͷͷ̶˵ʴɳȲȲǱȲɳʴʴɳȲȴ̷˶ʴȯ¥sjjmuǼǱιι͸̷ɵȲȲȰ¨ȼzrjfgkxūƭŬƯȱȶʸ˹˹ʸɷ˹̺ɷɷɷɷʸʸʸʸʸʸʸɷɷɷȶȶɷɷɷɷʸʸ˹˹˹ʸʸʸʸʸʸʸʸ˹̺̺˹ʸȶǵĲĲĲĲųƴǵȶȶȶȶȶȶȶȶȶ˹˹˹˹˹˹˹˹ʸʸʸʸʸʸʸʸ˹˹˹˹˹˹˹˹̺̺̺ͻͻμμμϽμμͻ̺˹ʸʸȶɷɷɷɷʸʸʸ˹"
  },
  {
    "path": "Doxa.Test/SIMDTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n#include \"ImageFixture.hpp\"\n#include <iostream>\n\n\nnamespace Doxa::UnitTests\n{\n\n    // Implements pure virtual functions\n    class GlobalThresholdTestHarness: public GlobalThreshold<GlobalThresholdTestHarness>\n    {\n        Pixel8 Threshold(const Image& grayScaleImage, const Parameters& parameters = Parameters())\n        {\n            return 128;\n        }\n    };\n\n    // Exposes protected members for Unit Testing\n    class DRDMTestHarness : public Doxa::DRDM\n    {\n    public:\n        using DRDM::NUBN_STD;\n\n        #if defined(DOXA_SIMD)\n            using DRDM::NUBN_SIMD_8x8;\n        #endif\n    };\n\n\n    class SIMDTests : public ImageFixture {};\n\n    TEST_F(SIMDTests, SIMDDetection)\n    {\n        std::cout << \"\\n=== SIMD Compile-Time Detection ===\" << std::endl;\n\n        #if defined(DOXA_SIMD)\n            #if defined(DOXA_SIMD_SSE2)\n                std::cout << \"Detected: SSE2 (16 pixels/op)\" << std::endl;\n                EXPECT_EQ(Doxa::SIMD::SIMD_WIDTH, 16);\n\n            #elif defined(DOXA_SIMD_NEON)\n                std::cout << \"Detected: NEON (16 pixels/op)\" << std::endl;\n                EXPECT_EQ(Doxa::SIMD::SIMD_WIDTH, 16);\n\n            #elif defined(DOXA_SIMD_WASM)\n                std::cout << \"Detected: WASM SIMD128 (16 pixels/op)\" << std::endl;\n                EXPECT_EQ(Doxa::SIMD::SIMD_WIDTH, 16);\n\n            #endif\n        #else\n\n            std::cout << \"No SIMD detected - scalar only\" << std::endl;\n        #endif\n    }\n\n#if defined(DOXA_SIMD)\n\n    TEST_F(SIMDTests, SIMDGlobalThresholdToBinaryTest)\n    {\n        const Pixel8 threshold = 128;\n        Image binarySTD(image.width, image.height);\n        Image binarySIMD(image.width, image.height);\n\n        GlobalThresholdTestHarness::ToBinary_STD(image.data, binarySTD.data, image.size, threshold);\n        GlobalThresholdTestHarness::ToBinary_SIMD(image.data, binarySIMD.data, image.size, threshold);\n\n        TestUtilities::AssertImages(binarySTD, binarySIMD);\n    }\n\n    TEST_F(SIMDTests, SIMDClassifiedPerformanceCompareImagesTest)\n    {\n\t\tstd::string projFolder = TestUtilities::ProjectFolder();\n\n\t\tconst std::string filePathBinary = projFolder + \"2JohnC1V3-Sauvola.pbm\";\n        const std::string filePathGT = projFolder + \"2JohnC1V3-GroundTruth.pbm\";\n\n        ClassifiedPerformance::Classifications classificationsSTD;\n        ClassifiedPerformance::Classifications classificationsSIMD;\n\n\t\tImage binaryImage = PNM::Read(filePathBinary);\n\t\tImage groundTruthImage = PNM::Read(filePathGT);\n\n\t\tClassifiedPerformance::CompareImages_STD(classificationsSTD, groundTruthImage.data, binaryImage.data, groundTruthImage.size);\n\t\tClassifiedPerformance::CompareImages_SIMD(classificationsSIMD, groundTruthImage.data, binaryImage.data, groundTruthImage.size);\n\n        EXPECT_EQ(classificationsSTD.truePositive, classificationsSIMD.truePositive);\n        EXPECT_EQ(classificationsSTD.trueNegative, classificationsSIMD.trueNegative);\n        EXPECT_EQ(classificationsSTD.falsePositive, classificationsSIMD.falsePositive);\n        EXPECT_EQ(classificationsSTD.falseNegative, classificationsSIMD.falseNegative);\n    }\n\n    TEST_F(SIMDTests, SIMDDrdmNubnTest)\n    {\n        const std::string filePathBinary = projFolder + \"2JohnC1V3-GroundTruth.pbm\";\n        Image binaryImage = PNM::Read(filePathBinary);\n\n        const unsigned int nubnSTD = DRDMTestHarness::NUBN_STD(binaryImage, 8);\n        const unsigned int nubnSIMD = DRDMTestHarness::NUBN_SIMD_8x8(binaryImage);\n\n        EXPECT_EQ(nubnSTD, nubnSIMD);\n    }\n\n#endif // DOXA_SIMD\n}\n"
  },
  {
    "path": "Doxa.Test/SuTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n\n\nnamespace Doxa::UnitTests\n{\n\t// Exposes protected members for Unit Testing\n\tclass SuTestHarness : public Su\n\t{\n\tpublic:\n\t\tSuTestHarness() : Su() {}\n\t\tusing Su::AutoDetectParameters;\n\t\tusing Su::SuCalculations;\n\t};\n\n\tTEST(SuTests, SuAutoDetectParametersTest)\n\t{\n\t\t// Setup - Create a small contrast image with a known stroke pattern.\n\t\t// Peaks at stroke edges spaced 3px apart.\n\t\tconst int width = 20;\n\t\tconst int height = 5;\n\t\tPixel8 contrastData[width * height];\n\t\tstd::memset(contrastData, 0, sizeof(contrastData));\n\n\t\tfor (int y = 0; y < height; ++y)\n\t\t{\n\t\t\tconst int row = y * width;\n\n\t\t\tcontrastData[row + 3] = 200;\n\t\t\tcontrastData[row + 6] = 200;\n\t\t\tcontrastData[row + 10] = 200;\n\t\t\tcontrastData[row + 13] = 200;\n\t\t}\n\n\t\tImage contrastImage(width, height, contrastData);\n\n\t\t// Method under Test\n\t\tSuTestHarness su;\n\t\tint windowSize = 0;\n\t\tint minN = 0;\n\t\tsu.Initialize(contrastImage);\n\t\tsu.AutoDetectParameters(windowSize, minN, contrastImage);\n\n\t\t// The dominant peak distance is 3, so strokeWidth = 3\n\t\tEXPECT_EQ(6, windowSize); // 3 * 2 = 6\n\t\tEXPECT_EQ(6, minN);        // windowSize\n\t}\n\n\tTEST(SuTests, SuCalculationsTest)\n\t{\n\t\t// Setup - 3x3 grayscale image with known values\n\t\tPixel8 grayData[] = {\n\t\t\t100, 150, 200,\n\t\t\t 50, 100, 150,\n\t\t\t 75, 125, 175\n\t\t};\n\t\tImage grayImage(3, 3, grayData);\n\n\t\t// High contrast binary image: White = high contrast pixel\n\t\tPixel8 contrastData[] = {\n\t\t\tPalette::White,  Palette::Black, Palette::White,\n\t\t\tPalette::Black,  Palette::White, Palette::Black,\n\t\t\tPalette::White,  Palette::Black, Palette::White\n\t\t};\n\t\tImage contrastImage(3, 3, contrastData);\n\n\t\t// Window covers entire image\n\t\tRegion window;\n\t\twindow.upperLeft = { 0, 0 };\n\t\twindow.bottomRight = { 2, 2 };\n\n\t\t// Method under Test\n\t\tSuTestHarness su;\n\t\tsu.Initialize(grayImage);\n\t\tint Ne;\n\t\tdouble meanE, stdE;\n\t\tsu.SuCalculations(Ne, meanE, stdE, contrastImage, grayImage, window);\n\n\t\t// High contrast pixels (White): (0,0)=100, (0,2)=200, (1,1)=100, (2,0)=75, (2,2)=175\n\t\tEXPECT_EQ(5, Ne);\n\t\tEXPECT_DOUBLE_EQ(130.0, meanE);  // (100+200+100+75+175) / 5\n\n\t\t// variance = sum((x-mean)^2)/Ne = (30^2 + 70^2 + 30^2 + 55^2 + 45^2)/5 = 11750/5 = 2350\n\t\t// stdE = sqrt(2350)\n\t\tdouble expectedStdE = std::sqrt(11750.0 / 5.0);\n\t\tEXPECT_NEAR(expectedStdE, stdE, 0.001);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/TestUtilities.hpp",
    "content": "#ifndef TESTUTILITIES_HPP\n#define TESTUTILITIES_HPP\n\n#include \"pch.h\"\n\n\nnamespace Doxa::UnitTests\n{\n\tclass TestUtilities\n\t{\n\tpublic:\n\t\tstatic std::string ProjectFolder()\n\t\t{\n\t\t\t// GTest will work in the current directory, but IDEs will usually put it in a diff spot.\n\t\t\t// Make sure to set the current working directory to the Doxa.Test folder!\n\t\t\tauto folder = fs::current_path() / \"Resources\";\n\n\t\t\tif (!fs::exists(folder))\n\t\t\t{\n\t\t\t\tthrow \"Could not find resource folder.\";\n\t\t\t}\n\n\t\t\treturn folder.string() + \"/\";\n\t\t}\n\n\t\tstatic double Time(std::function<void()> predicate)\n\t\t{\n\t\t\tstd::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();\n\n\t\t\tpredicate();\n\n\t\t\tstd::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();\n\t\t\tstd::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);\n\n\t\t\treturn time_span.count(); // In Seconds\n\t\t}\n\n\t\tstatic void AssertImageData(const Image& image, const Pixel8* data)\n\t\t{\n\t\t\tEXPECT_EQ(0, std::memcmp(image.data, data, sizeof(Pixel8) * image.size));\n\t\t}\n\n\t\tstatic void AssertImages(const Image& imageA, const Image& imageB)\n\t\t{\n\t\t\tEXPECT_EQ(imageA.size, imageB.size);\n\n\t\t\tEXPECT_EQ(0, std::memcmp(imageA.data, imageB.data, sizeof(Pixel8) * imageA.size));\n\t\t}\n\n\t\tstatic void AssertImageFile(const Image& image, std::string filePath)\n\t\t{\n\t\t\tImage imageFromFile = PNM::Read(filePath);\n\n\t\t\tAssertImages(image, imageFromFile);\n\t\t}\n\n\t\tstatic bool AssertImagesWithDetails(const Image& imageA, const Image& imageB)\n\t\t{\n\t\t\tchar buffer[100];\n\n\t\t\tif (imageA.height != imageB.height || imageA.width != imageB.width)\n\t\t\t{\n\t\t\t\tstd::snprintf(buffer, 100, \"Image dimensions do not match.  %dx%d vs %dx%d\", imageA.width, imageA.height, imageB.width, imageB.height);\n\t\t\t\tSUCCEED() << buffer;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbool diffFound = false;\n\t\t\t\tint firstHeight = 0;\n\t\t\t\tint firstWidth = 0;\n\t\t\t\tint firstIndex = 0;\n\t\t\t\tint count = 0;\n\n\t\t\t\tfor (int index = 0; index < imageA.size; index++)\n\t\t\t\t{\n\t\t\t\t\tif (imageA.data[index] != imageB.data[index])\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!diffFound)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfirstIndex = index;\n\t\t\t\t\t\t\tfirstHeight = index / imageA.width;\n\t\t\t\t\t\t\tfirstWidth = index % imageA.width;\n\t\t\t\t\t\t\tdiffFound = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t++count;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// No differences found!\n\t\t\t\tif (!diffFound) return true;\n\n\t\t\t\tstd::snprintf(buffer, 100, \"%d difference(s) found. Example: Index %d, Width %d, Height %d.\", count, firstIndex, firstWidth, firstHeight);\n\t\t\t\tSUCCEED() << buffer;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t};\n}\n\n#endif // TESTUTILITIES_HPP\n"
  },
  {
    "path": "Doxa.Test/WienerFilterTests.cpp",
    "content": "#include \"pch.h\"\n#include \"TestUtilities.hpp\"\n#include <WienerFilter.hpp>\n\n\nnamespace Doxa::UnitTests\n{\n\t// A Wiener filter (per MATLAB's wiener2) is an adaptive denoiser.\n\t// For each pixel, given local mean (m) and local variance (v):\n\t//\n\t// This test uses a flat background with a single bright pixel.  The expected\n\t// behavior is:\n\t//   - All windows that don't see the bright pixel have v=0, output = m = input.\n\t//   - The 9 windows containing the bright pixel get smoothed: the bright pixel\n\t//     is pulled down toward its local mean, the 8 neighbors nudged up.\n\tTEST(WienerFilterTests, WienerFilterCenterPixelTest)\n\t{\n\t\tconst Pixel8 data[] = {\n\t\t\t50, 50, 50,  50, 50, 50, 50,\n\t\t\t50, 50, 50,  50, 50, 50, 50,\n\t\t\t50, 50, 50,  50, 50, 50, 50,\n\t\t\t50, 50, 50, 100, 50, 50, 50, // Bright pixel at (3,3)\n\t\t\t50, 50, 50,  50, 50, 50, 50,\n\t\t\t50, 50, 50,  50, 50, 50, 50,\n\t\t\t50, 50, 50,  50, 50, 50, 50\n\t\t};\n\n\t\t// Derivation:\n\t\t//   9 windows contain the spike:  m = (8*50 + 100)/9 = 500/9,  v = 20000/81\n\t\t//   40 flat windows:              m = 50,               v = 0\n\t\t//   noiseVar = (9 * 20000/81) / 49 = 180000/3969\n\t\t//   noiseVar / v = 9/49,  so the dampening factor (1 - noiseVar/v) = 40/49\n\t\t//\n\t\t// Center spike (input = 100):\n\t\t//   out = 500/9 + (40/49)*(100 - 500/9) = 40500/441 ~= 91.837 -> 91 (uint8 trunc)\n\t\t//\n\t\t// 8 neighbors (input = 50):\n\t\t//   out = 500/9 + (40/49)*( 50 - 500/9) = 22500/441 ~= 51.020 -> 51\n\t\tconst Pixel8 expected[] = {\n\t\t\t50, 50, 50, 50, 50, 50, 50,\n\t\t\t50, 50, 50, 50, 50, 50, 50,\n\t\t\t50, 50, 51, 51, 51, 50, 50,\n\t\t\t50, 50, 51, 91, 51, 50, 50,\n\t\t\t50, 50, 51, 51, 51, 50, 50,\n\t\t\t50, 50, 50, 50, 50, 50, 50,\n\t\t\t50, 50, 50, 50, 50, 50, 50\n\t\t};\n\n\t\tconst Image inputImage(7, 7, data);\n\t\tImage outputImage(7, 7);\n\n\t\tWienerFilter::Filter(outputImage, inputImage, 3);\n\n\t\tTestUtilities::AssertImageData(outputImage, expected);\n\t}\n}\n"
  },
  {
    "path": "Doxa.Test/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn\" version=\"1.8.1.7\" targetFramework=\"native\" />\n</packages>"
  },
  {
    "path": "Doxa.Test/pch.cpp",
    "content": "//\n// pch.cpp\n//\n\n#include \"pch.h\"\n"
  },
  {
    "path": "Doxa.Test/pch.h",
    "content": "//\n// pch.h\n//\n\n#pragma once\n#include <chrono>\n#include <functional>\n#include <vector>\n#include <tuple>\n\n#include <SIMD.h>\n#include <SIMDOps.hpp>\n#include <PNM.hpp>\n#include <Grayscale.hpp>\n#include <Otsu.hpp>\n#include <Bernsen.hpp>\n#include <Niblack.hpp>\n#include <Sauvola.hpp>\n#include <Wolf.hpp>\n#include <Gatos.hpp>\n#include <Nick.hpp>\n#include <GridCalc.hpp>\n#include <AdOtsu.hpp>\n#include <TRSingh.hpp>\n#include <Wan.hpp>\n#include <Su.hpp>\n#include <ISauvola.hpp>\n#include <Bataineh.hpp>\n#include <Phansalkar.hpp>\n#include <ClassifiedPerformance.hpp>\n#include <DRDM.hpp>\n#include <DIBCOUtils.hpp>\n\n#include \"gtest/gtest.h\"\n"
  },
  {
    "path": "Doxa.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.6.33829.357\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Doxa\", \"Doxa\\Doxa.vcxitems\", \"{D81F2737-6340-49C1-AE65-8D217415C67E}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Doxa.Test\", \"Doxa.Test\\Doxa.Test.vcxproj\", \"{5723F19A-A7AB-45D0-A78C-B04FE035865F}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{5723F19A-A7AB-45D0-A78C-B04FE035865F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{5723F19A-A7AB-45D0-A78C-B04FE035865F}.Debug|x64.Build.0 = Debug|x64\n\t\t{5723F19A-A7AB-45D0-A78C-B04FE035865F}.Release|x64.ActiveCfg = Release|x64\n\t\t{5723F19A-A7AB-45D0-A78C-B04FE035865F}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {148C3EB0-D413-43A2-A7CD-B8BD21321540}\n\tEndGlobalSection\n\tGlobalSection(SharedMSBuildProjectFiles) = preSolution\n\t\tDoxa\\Doxa.vcxitems*{5723f19a-a7ab-45d0-a78c-b04fe035865f}*SharedItemsImports = 4\n\t\tDoxa\\Doxa.vcxitems*{d81f2737-6340-49c1-ae65-8d217415c67e}*SharedItemsImports = 9\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "LICENSE",
    "content": "CC0 1.0 Universal\n\nStatement of Purpose\n\nThe laws of most jurisdictions throughout the world automatically confer\nexclusive Copyright and Related Rights (defined below) upon the creator and\nsubsequent owner(s) (each and all, an \"owner\") of an original work of\nauthorship and/or a database (each, a \"Work\").\n\nCertain owners wish to permanently relinquish those rights to a Work for the\npurpose of contributing to a commons of creative, cultural and scientific\nworks (\"Commons\") that the public can reliably and without fear of later\nclaims of infringement build upon, modify, incorporate in other works, reuse\nand redistribute as freely as possible in any form whatsoever and for any\npurposes, including without limitation commercial purposes. These owners may\ncontribute to the Commons to promote the ideal of a free culture and the\nfurther production of creative, cultural and scientific works, or to gain\nreputation or greater distribution for their Work in part through the use and\nefforts of others.\n\nFor these and/or other purposes and motivations, and without any expectation\nof additional consideration or compensation, the person associating CC0 with a\nWork (the \"Affirmer\"), to the extent that he or she is an owner of Copyright\nand Related Rights in the Work, voluntarily elects to apply CC0 to the Work\nand publicly distribute the Work under its terms, with knowledge of his or her\nCopyright and Related Rights in the Work and the meaning and intended legal\neffect of CC0 on those rights.\n\n1. Copyright and Related Rights. A Work made available under CC0 may be\nprotected by copyright and related or neighboring rights (\"Copyright and\nRelated Rights\"). Copyright and Related Rights include, but are not limited\nto, the following:\n\n  i. the right to reproduce, adapt, distribute, perform, display, communicate,\n  and translate a Work;\n\n  ii. moral rights retained by the original author(s) and/or performer(s);\n\n  iii. publicity and privacy rights pertaining to a person's image or likeness\n  depicted in a Work;\n\n  iv. rights protecting against unfair competition in regards to a Work,\n  subject to the limitations in paragraph 4(a), below;\n\n  v. rights protecting the extraction, dissemination, use and reuse of data in\n  a Work;\n\n  vi. database rights (such as those arising under Directive 96/9/EC of the\n  European Parliament and of the Council of 11 March 1996 on the legal\n  protection of databases, and under any national implementation thereof,\n  including any amended or successor version of such directive); and\n\n  vii. other similar, equivalent or corresponding rights throughout the world\n  based on applicable law or treaty, and any national implementations thereof.\n\n2. Waiver. To the greatest extent permitted by, but not in contravention of,\napplicable law, Affirmer hereby overtly, fully, permanently, irrevocably and\nunconditionally waives, abandons, and surrenders all of Affirmer's Copyright\nand Related Rights and associated claims and causes of action, whether now\nknown or unknown (including existing as well as future claims and causes of\naction), in the Work (i) in all territories worldwide, (ii) for the maximum\nduration provided by applicable law or treaty (including future time\nextensions), (iii) in any current or future medium and for any number of\ncopies, and (iv) for any purpose whatsoever, including without limitation\ncommercial, advertising or promotional purposes (the \"Waiver\"). Affirmer makes\nthe Waiver for the benefit of each member of the public at large and to the\ndetriment of Affirmer's heirs and successors, fully intending that such Waiver\nshall not be subject to revocation, rescission, cancellation, termination, or\nany other legal or equitable action to disrupt the quiet enjoyment of the Work\nby the public as contemplated by Affirmer's express Statement of Purpose.\n\n3. Public License Fallback. Should any part of the Waiver for any reason be\njudged legally invalid or ineffective under applicable law, then the Waiver\nshall be preserved to the maximum extent permitted taking into account\nAffirmer's express Statement of Purpose. In addition, to the extent the Waiver\nis so judged Affirmer hereby grants to each affected person a royalty-free,\nnon transferable, non sublicensable, non exclusive, irrevocable and\nunconditional license to exercise Affirmer's Copyright and Related Rights in\nthe Work (i) in all territories worldwide, (ii) for the maximum duration\nprovided by applicable law or treaty (including future time extensions), (iii)\nin any current or future medium and for any number of copies, and (iv) for any\npurpose whatsoever, including without limitation commercial, advertising or\npromotional purposes (the \"License\"). The License shall be deemed effective as\nof the date CC0 was applied by Affirmer to the Work. Should any part of the\nLicense for any reason be judged legally invalid or ineffective under\napplicable law, such partial invalidity or ineffectiveness shall not\ninvalidate the remainder of the License, and in such case Affirmer hereby\naffirms that he or she will not (i) exercise any of his or her remaining\nCopyright and Related Rights in the Work or (ii) assert any associated claims\nand causes of action with respect to the Work, in either case contrary to\nAffirmer's express Statement of Purpose.\n\n4. Limitations and Disclaimers.\n\n  a. No trademark or patent rights held by Affirmer are waived, abandoned,\n  surrendered, licensed or otherwise affected by this document.\n\n  b. Affirmer offers the Work as-is and makes no representations or warranties\n  of any kind concerning the Work, express, implied, statutory or otherwise,\n  including without limitation warranties of title, merchantability, fitness\n  for a particular purpose, non infringement, or the absence of latent or\n  other defects, accuracy, or the present or absence of errors, whether or not\n  discoverable, all to the greatest extent permissible under applicable law.\n\n  c. Affirmer disclaims responsibility for clearing rights of other persons\n  that may apply to the Work or any use thereof, including without limitation\n  any person's Copyright and Related Rights in the Work. Further, Affirmer\n  disclaims responsibility for obtaining any necessary consents, permissions\n  or other rights required for any use of the Work.\n\n  d. Affirmer understands and acknowledges that Creative Commons is not a\n  party to this document and has no duty or obligation with respect to this\n  CC0 or use of the Work.\n\nFor more information, please see\n<http://creativecommons.org/publicdomain/zero/1.0/>"
  },
  {
    "path": "README.md",
    "content": "# Δoxa Binarization Framework\n\n[![codecov](https://codecov.io/gh/brandonmpetty/Doxa/graph/badge.svg?token=XMG2X9KQKJ)](https://codecov.io/gh/brandonmpetty/Doxa)\n\n<p align=\"center\">\n\t<img src=\"/README/2JohnC1V3.png\" width=\"45%\" height=\"45%\"/>\n\t<img src=\"/README/2JohnC1V3-GroundTruth.png\" width=\"45%\" height=\"45%\"/>\n</p>\n\n## Introduction\nΔBF is an image binarization framework which focuses primarily on local adaptive thresholding algorithms.\nIn English, this means that it has the ability to turn a color or gray scale image into a black and white image.\nIt is written in C++ but supports multiple language bindings.\n\n**Algorithms**\n* Otsu - \"A threshold selection method from gray-level histograms\", 1979.\n* Bernsen - \"Dynamic thresholding of gray-level images\", 1986.\n* Niblack - \"An Introduction to Digital Image Processing\", 1986.\n* Sauvola - \"Adaptive document image binarization\", 1999.\n* Wolf - \"Extraction and Recognition of Artificial Text in Multimedia Documents\", 2003.\n* Gatos - \"Adaptive degraded document image binarization\", 2005. (Partial)\n* NICK - \"Comparison of Niblack inspired Binarization methods for ancient documents\", 2009.\n* AdOtsu - \"A multi-scale framework for adaptive binarization of degraded document images\", 2010.\n* Su - \"Binarization of Historical Document Images Using the Local Maximum and Minimum\", 2010.\n* T.R. Singh - \"A New local Adaptive Thresholding Technique in Binarization\", 2011.\n* Bataineh - \"An adaptive local binarization method for document images based on a novel thresholding method and dynamic windows\", 2011. (unreproducible)\n* Phansalkar - \"Adaptive Local Thresholding for Detection of Nuclei in Diversely Stained Cytology Images\", 2011.\n* ISauvola - \"ISauvola: Improved Sauvola’s Algorithm for Document Image Binarization\", 2016.\n* WAN - \"Binarization of Document Image Using Optimum Threshold Modification\", 2018.\n\n**Optimizations**\n* Shafait - \"Efficient Implementation of Local Adaptive Thresholding Techniques Using Integral Images\", 2008.\n* Petty - An algorithm for efficiently calculating the min and max of a local window.  Unpublished, 2019.\n* Chan - \"Memory-efficient and fast implementation of local adaptive binarization methods\", 2019.\n* SIMD - Supporting: SSE2, ARM NEON, WASM SIMD128\n\n**Performance Metrics**\n* Overall Accuracy\n* F-Measure, Precision, Recall\n* Pseudo F-Measure, Precision, Recall - \"Performance Evaluation Methodology for Historical Document Image Binarization\", 2013.\n* Peak Signal-To-Noise Ratio (PSNR)\n* Negative Rate Metric (NRM)\n* Matthews Correlation Coefficient (MCC)\n* Distance-Reciprocal Distortion Measure (DRDM) - \"An Objective Distortion Measure for Binary Document Images Based on Human Visual Perception\", 2002.\n\n**Native Image Support**\n* Portable Any-Map: PBM (P4), 8-bit PGM (P5), PPM (P6), PAM (P7)\n\n## Overview\nThe goal of this library is to provide the building blocks one might use to advance the state of handwritten manuscript binarization.\nWhat sets this binarization library apart is that it is intended to be used by those interested in experimenting with their own algorithms and enhancements.\nInstead of being relegated to MATLAB, or obfuscated by mathematics in a research paper, a lot of effort has gone into exposing these binarization techniques in an open and transparent way.\nA key objective in designing this framework was to make it modular and as easy to use as possible, without sacrificing speed and without depending heavily on 3rd party frameworks.\nThis library is also heavily unit tested to help ensure quality, and to quickly spot problems after experimenting with the codebase.\n\n### Example\nThis short example shows you how easy it is to use ΔBF to process an image.\n\n```cpp\n// Read a 32-bit color image and automatically convert to 8-bit gray scale\nImage image = PNM::Read(R\"(C:\\MyImage.pam)\");\n\n// Use a binarization algorithm to convert it into black and white\nconst Parameters parameters({ {\"window\", 25}, {\"k\", 0.10} });\nImage imageSauvola = Sauvola::ToBinaryImage(image, parameters);\n\n// Save the processed image\nPNM::Write(imageSauvola, R\"(C:\\MyImage-Sauvola.pam)\");\n```\n\nΔBF is incredibly light weight, being a header-only library.  It can integrate easily with other 3rd party C++ frameworks like OpenCV and Qt.  Examples can be found under the Demo folder.\n\n### Building and Testing\n\nThe core library is header-only and requires no build. For bindings and tests, use CMake presets:\n\n```bash\n# Build everything (C++ Tests, Python, WASM, MATLAB)\ncmake --preset all\ncmake --build build --config Release\nctest --test-dir build -C Release\n\n# Build and run performance benchmarks (Google Benchmark)\ncmake --preset benchmarks\ncmake --build build-bench --config Release\n./build-bench/Doxa.Bench/doxa_bench              # Linux/Mac\n.\\build-bench\\Doxa.Bench\\Release\\doxa_bench.exe  # Windows\n\n# Build and run C++ unit tests\ncmake --preset cpp-tests\ncmake --build build-cpp-tests --config Release\nctest --test-dir build-cpp-tests -C Release\n\n# Build and test Python bindings (requires Python 3.12+, nanobind)\ncmake --preset python\ncmake --build build-python --config Release\nctest --test-dir build-python -C Release\n\n# Build and test WebAssembly (requires Emscripten in PATH)\ncmake --preset wasm\ncmake --build build-wasm --config Release\nctest --test-dir build-wasm -C Release\n\n# Build and test MATLAB bindings (requires MATLAB)\ncmake --preset matlab\ncmake --build build-matlab --config Release\nctest --test-dir build-matlab -C Release\n```\n\n### Language Bindings\n* Javascript / WASM\n* Python\n* Matlab\n\nExamples of how to use each binding are provided in the Demo folder.\n\nSee [Bindings/Python/README.md](Bindings/Python/README.md), [Bindings/WebAssembly/README.md](Bindings/WebAssembly/README.md), and [Bindings/Matlab/README.md](Bindings/Matlab/README.md) for detailed instructions.\n\nA [Live Demo](https://brandonmpetty.github.io/Doxa/WebAssembly) has been created to highlight some of what ΔBF is capable of on the web.\n\n### Benchmarks\nThe project uses [Google Benchmark](https://github.com/google/benchmark) for measuring runtime performance of SIMD optimizations, calculator backends, and core operations. Benchmarks are separate from unit tests to keep correctness and runtime performance concerns independent.\n\n```bash\n# Run benchmarks long enough to lower CV %\n./build-bench/Doxa.Bench/doxa_bench --benchmark_min_time=1s --benchmark_repetitions=10 --benchmark_report_aggregates_only=true\n\n# Compare two runs (e.g., before/after a change, or across platforms)\n# Requires running doxa_bench with: --benchmark_out=results.json --benchmark_out_format=json\npython build-bench/_deps/googlebenchmark-src/tools/compare.py benchmarks before.json after.json\n```\n\n### Performance Analysis\nAnother thing that sets ΔBF apart is its focus on binarization performance.  This makes it incredibly simple to see how your changes affect the overall quality of an algorithm.  All DIBCO metric algorithms, past and present, are provided.  ΔBF's metrics are significantly faster than calling DIBCO_metrics.exe directly.\n\n**NOTE** - DIBCO Weight generation still requires [BinEvalWeights](https://github.com/kzagoris/DibcoEvaluation/tree/master/Prerequisites/BinEvalWeights)\n\n## License\nCC0 - Brandon M. Petty, 2026\n\nTo the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.\n\n[View Online](https://creativecommons.org/publicdomain/zero/1.0/legalcode)\n\n\"*Freely you have received; freely give.*\" - Matt 10:8"
  }
]