From 8635856d4ce2b0ec5d00ab03d67b07bfb6e434a5 Mon Sep 17 00:00:00 2001 From: Jonathan Talmi Date: Tue, 11 Nov 2025 14:34:56 -0500 Subject: [PATCH] wip: toronto spends - operating --- README.md | 16 + data/toronto-operating/sankey.json | 728 ++++++++++++++++++ data/toronto-operating/summary.json | 133 ++++ ...of Toronto Budget Summary (Operating).xlsx | Bin 0 -> 84282 bytes .../toronto/scripts/convert_toronto_sankey.py | 286 ++++++- data/toronto/summary.json | 2 +- src/components/MainLayout/index.tsx | 8 + 7 files changed, 1142 insertions(+), 31 deletions(-) create mode 100644 data/toronto-operating/sankey.json create mode 100644 data/toronto-operating/summary.json create mode 100644 data/toronto/2024 City of Toronto Budget Summary (Operating).xlsx diff --git a/README.md b/README.md index 667d48af..0ac3bf78 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,19 @@ npx simple-git-hooks ``` If linting fails, the commit will be blocked until issues are resolved. + +## Toronto data conversion + +The Toronto Sankey data is generated via `data/toronto/scripts/convert_toronto_sankey.py`. The +script supports both the original dataset (`legacy`) and the new 2024 operating budget dataset: + +```bash +# Legacy dataset (writes to data/toronto) +python3 data/toronto/scripts/convert_toronto_sankey.py --dataset legacy + +# 2024 Operating Budget dataset (writes to data/toronto-operating) +python3 data/toronto/scripts/convert_toronto_sankey.py --dataset operating +``` + +Use `--output-dir` to override the destination or pass custom spreadsheet paths if the files live +elsewhere. diff --git a/data/toronto-operating/sankey.json b/data/toronto-operating/sankey.json new file mode 100644 index 00000000..7da4e374 --- /dev/null +++ b/data/toronto-operating/sankey.json @@ -0,0 +1,728 @@ +{ + "total": 11.67877, + "spending": 15.704151000000001, + "revenue": 11.67877, + "spending_data": { + "name": "Spending", + "children": [ + { + "name": "Community and Social Services", + "children": [ + { + "name": "Community and Social Services \u2192 Toronto Employment & Social Services", + "amount": 1.2445709999999999 + }, + { + "name": "Community and Social Services \u2192 Children's Services", + "amount": 1.066048 + }, + { + "name": "Community and Social Services \u2192 Toronto Shelter and Support Services", + "amount": 0.843995 + }, + { + "name": "Community and Social Services \u2192 Fire Services", + "amount": 0.579616 + }, + { + "name": "Community and Social Services \u2192 Parks, Forestry & Recreation", + "amount": 0.5377029999999999 + }, + { + "name": "Community and Social Services \u2192 Seniors Services and Long-Term Care", + "amount": 0.380527 + }, + { + "name": "Community and Social Services \u2192 Toronto Paramedic Services", + "amount": 0.325914 + }, + { + "name": "Community and Social Services \u2192 Social Development, Finance & Administration", + "amount": 0.12800999999999998 + }, + { + "name": "Community and Social Services \u2192 Economic Development and Culture", + "amount": 0.10205299999999999 + }, + { + "name": "Community and Social Services \u2192 Court Services", + "amount": 0.037442 + } + ] + }, + { + "name": "Agencies", + "children": [ + { + "name": "Agencies \u2192 Toronto Transit Commission - Wheel Trans", + "amount": 2.3824810000000003 + }, + { + "name": "Agencies \u2192 Toronto Police Service Board", + "amount": 1.3911900000000001 + }, + { + "name": "Agencies \u2192 Exhibition Place", + "amount": 0.254511 + }, + { + "name": "Agencies \u2192 Toronto Public Library", + "amount": 0.248052 + }, + { + "name": "Agencies \u2192 Toronto Police Service", + "amount": 0.167917 + }, + { + "name": "Agencies \u2192 Heritage Toronto", + "amount": 0.067217 + }, + { + "name": "Agencies \u2192 Sankofa Square", + "amount": 0.06547 + }, + { + "name": "Agencies \u2192 Toronto Zoo", + "amount": 0.03982 + }, + { + "name": "Agencies \u2192 Toronto & Region Conservation Authority", + "amount": 0.018463 + }, + { + "name": "Agencies \u2192 Toronto Public Health", + "amount": 0.013326000000000001 + }, + { + "name": "Agencies \u2192 Toronto Transit Commission - Conventional", + "amount": 0.011594 + }, + { + "name": "Agencies \u2192 CreateTO", + "amount": 0.0038309999999999998 + }, + { + "name": "Agencies \u2192 To Live", + "amount": 0.001335 + } + ] + }, + { + "name": "Corporate Accounts", + "children": [ + { + "name": "Corporate Accounts \u2192 Debt Charges", + "amount": 0.89362 + }, + { + "name": "Corporate Accounts \u2192 Capital from Current", + "amount": 0.286742 + }, + { + "name": "Corporate Accounts \u2192 Technology Sustainment", + "amount": 0.021297 + }, + { + "name": "Corporate Accounts \u2192 Association of Community Centres", + "amount": 0.011885999999999999 + }, + { + "name": "Corporate Accounts \u2192 Arena Boards of Management", + "amount": 0.011106999999999999 + } + ] + }, + { + "name": "Non-Levy Operation", + "children": [ + { + "name": "Non-Levy Operation \u2192 Toronto Water", + "amount": 0.503995 + }, + { + "name": "Non-Levy Operation \u2192 Solid Waste Management Services", + "amount": 0.403488 + }, + { + "name": "Non-Levy Operation \u2192 Toronto Parking Authority", + "amount": 0.130011 + } + ] + }, + { + "name": "Development & Growth Services", + "children": [ + { + "name": "Development & Growth Services \u2192 Housing Secretariat", + "amount": 0.7475109999999999 + }, + { + "name": "Development & Growth Services \u2192 City Planning", + "amount": 0.07324599999999999 + }, + { + "name": "Development & Growth Services \u2192 Toronto Building", + "amount": 0.067258 + }, + { + "name": "Development & Growth Services \u2192 Development Review", + "amount": 0.00828 + } + ] + }, + { + "name": "Infrastructure Services", + "children": [ + { + "name": "Infrastructure Services \u2192 Transportation Services", + "amount": 0.500696 + }, + { + "name": "Infrastructure Services \u2192 Engineering & Construction Services", + "amount": 0.085084 + }, + { + "name": "Infrastructure Services \u2192 Municipal Licensing & Standards", + "amount": 0.076939 + }, + { + "name": "Infrastructure Services \u2192 Policy, Planning, Finance & Administration", + "amount": 0.022785 + }, + { + "name": "Infrastructure Services \u2192 Transit Expansion", + "amount": 0.007979 + }, + { + "name": "Infrastructure Services \u2192 Toronto Emergency Management", + "amount": 0.006112 + } + ] + }, + { + "name": "Non-Program Expenditures", + "children": [ + { + "name": "Non-Program Expenditures \u2192 Programs Funded from Reserve Funds", + "amount": 0.16631100000000001 + }, + { + "name": "Non-Program Expenditures \u2192 Other Corporate Expenditures", + "amount": 0.117756 + }, + { + "name": "Non-Program Expenditures \u2192 Funding of Employee Related Liabilities", + "amount": 0.083065 + }, + { + "name": "Non-Program Expenditures \u2192 Solid Waste Management Services Rebate", + "amount": 0.075371 + }, + { + "name": "Non-Program Expenditures \u2192 Parking Tag Enforcement & Operations Exp", + "amount": 0.07024899999999999 + }, + { + "name": "Non-Program Expenditures \u2192 Insurance Contributions", + "amount": 0.052411 + }, + { + "name": "Non-Program Expenditures \u2192 Assessment Function (MPAC)", + "amount": 0.047291 + }, + { + "name": "Non-Program Expenditures \u2192 Tax Increment Equivalent Grants (TIEG)", + "amount": 0.040055 + }, + { + "name": "Non-Program Expenditures \u2192 Tax Deficiencies / Write Offs", + "amount": 0.0312 + }, + { + "name": "Non-Program Expenditures \u2192 Tax Increment Funding (TIF)", + "amount": 0.007231 + }, + { + "name": "Non-Program Expenditures \u2192 Heritage Property Taxes Rebate", + "amount": 0.0006360000000000001 + } + ] + }, + { + "name": "Corporate Services", + "children": [ + { + "name": "Corporate Services \u2192 Corporate Real Estate Management", + "amount": 0.22578299999999998 + }, + { + "name": "Corporate Services \u2192 Technology Services", + "amount": 0.174141 + }, + { + "name": "Corporate Services \u2192 Fleet Services", + "amount": 0.079066 + }, + { + "name": "Corporate Services \u2192 Office of the Chief Information Security Officer", + "amount": 0.031236999999999997 + }, + { + "name": "Corporate Services \u2192 Customer Experience", + "amount": 0.024392 + }, + { + "name": "Corporate Services \u2192 Environment & Climate", + "amount": 0.019162 + } + ] + }, + { + "name": "City Building Fund (CBF)", + "children": [ + { + "name": "City Building Fund (CBF) \u2192 City Building Fund (CBF)", + "amount": 0.314096 + } + ] + }, + { + "name": "Other City Programs", + "children": [ + { + "name": "Other City Programs \u2192 Legal Services", + "amount": 0.067054 + }, + { + "name": "Other City Programs \u2192 City Clerk's Office", + "amount": 0.053473999999999994 + }, + { + "name": "Other City Programs \u2192 Mayor's Office", + "amount": 0.003055 + } + ] + }, + { + "name": "Finance and Treasury Services", + "children": [ + { + "name": "Finance and Treasury Services \u2192 Financial Operations & Control", + "amount": 0.067048 + }, + { + "name": "Finance and Treasury Services \u2192 Office of the Chief Financial Officer and Treasurer", + "amount": 0.045003 + } + ] + }, + { + "name": "City Manager", + "children": [ + { + "name": "City Manager \u2192 City Manager's Office (Excluding FIFA)", + "amount": 0.08591700000000001 + } + ] + }, + { + "name": "Special Levy for Scarborough Subway", + "children": [ + { + "name": "Special Levy for Scarborough Subway \u2192 Special Levy for Scarborough Subway", + "amount": 0.040699 + } + ] + }, + { + "name": "Accountability Offices", + "children": [ + { + "name": "Accountability Offices \u2192 Auditor General's Office", + "amount": 0.007781 + }, + { + "name": "Accountability Offices \u2192 Office of the Ombudsman", + "amount": 0.0038399999999999997 + }, + { + "name": "Accountability Offices \u2192 Office of the Lobbyist Registrar", + "amount": 0.0009310000000000001 + }, + { + "name": "Accountability Offices \u2192 Integrity Commissioner's Office", + "amount": 0.0007740000000000001 + } + ] + } + ] + }, + "revenue_data": { + "name": "Revenue", + "children": [ + { + "name": "Community and Social Services", + "children": [ + { + "name": "Community and Social Services \u2192 Toronto Employment & Social Services", + "amount": 1.162375 + }, + { + "name": "Community and Social Services \u2192 Children's Services", + "amount": 0.9726699999999999 + }, + { + "name": "Community and Social Services \u2192 Toronto Shelter and Support Services", + "amount": 0.614602 + }, + { + "name": "Community and Social Services \u2192 Seniors Services and Long-Term Care", + "amount": 0.31587 + }, + { + "name": "Community and Social Services \u2192 Toronto Paramedic Services", + "amount": 0.213976 + }, + { + "name": "Community and Social Services \u2192 Parks, Forestry & Recreation", + "amount": 0.17311600000000002 + }, + { + "name": "Community and Social Services \u2192 Court Services", + "amount": 0.108185 + }, + { + "name": "Community and Social Services \u2192 Fire Services", + "amount": 0.029585999999999998 + }, + { + "name": "Community and Social Services \u2192 Economic Development and Culture", + "amount": 0.018039000000000003 + }, + { + "name": "Community and Social Services \u2192 Social Development, Finance & Administration", + "amount": 0.01718 + } + ] + }, + { + "name": "Non-Program Revenues", + "children": [ + { + "name": "Non-Program Revenues \u2192 Municipal Land Transfer Tax", + "amount": 0.879752 + }, + { + "name": "Non-Program Revenues \u2192 Interest/Investment Earnings", + "amount": 0.39 + }, + { + "name": "Non-Program Revenues \u2192 Other Corporate Revenues", + "amount": 0.232131 + }, + { + "name": "Non-Program Revenues \u2192 Parking Tag Enforcement & Operations Rev", + "amount": 0.134032 + }, + { + "name": "Non-Program Revenues \u2192 Municipal Accommodation Tax (MAT)", + "amount": 0.108 + }, + { + "name": "Non-Program Revenues \u2192 Payments in Lieu of Taxes", + "amount": 0.106597 + }, + { + "name": "Non-Program Revenues \u2192 Provincial Revenue", + "amount": 0.0916 + }, + { + "name": "Non-Program Revenues \u2192 Dividend Income", + "amount": 0.08394 + }, + { + "name": "Non-Program Revenues \u2192 Supplementary Taxes", + "amount": 0.06 + }, + { + "name": "Non-Program Revenues \u2192 Vacant Home Tax", + "amount": 0.055 + }, + { + "name": "Non-Program Revenues \u2192 Tax Penalty Revenue", + "amount": 0.0525 + }, + { + "name": "Non-Program Revenues \u2192 Casino Woodbine Revenues", + "amount": 0.0272 + }, + { + "name": "Non-Program Revenues \u2192 Parking Authority Revenues", + "amount": 0.025678 + }, + { + "name": "Non-Program Revenues \u2192 Administrative Support Recoveries - Water", + "amount": 0.018973 + }, + { + "name": "Non-Program Revenues \u2192 Administrative Support Recoveries - Health & EMS", + "amount": 0.011855000000000001 + }, + { + "name": "Non-Program Revenues \u2192 Third Party Sign Tax", + "amount": 0.010352 + }, + { + "name": "Non-Program Revenues \u2192 Other Tax Revenues", + "amount": 0.010043 + } + ] + }, + { + "name": "Non-Levy Operation", + "children": [ + { + "name": "Non-Levy Operation \u2192 Toronto Water", + "amount": 1.5532260000000002 + }, + { + "name": "Non-Levy Operation \u2192 Solid Waste Management Services", + "amount": 0.42586900000000005 + }, + { + "name": "Non-Levy Operation \u2192 Toronto Parking Authority", + "amount": 0.17113 + } + ] + }, + { + "name": "Agencies", + "children": [ + { + "name": "Agencies \u2192 Toronto Transit Commission - Conventional", + "amount": 1.2761300000000002 + }, + { + "name": "Agencies \u2192 Toronto Police Service", + "amount": 0.19488999999999998 + }, + { + "name": "Agencies \u2192 Toronto Public Health", + "amount": 0.180506 + }, + { + "name": "Agencies \u2192 Exhibition Place", + "amount": 0.068217 + }, + { + "name": "Agencies \u2192 Toronto Zoo", + "amount": 0.051572 + }, + { + "name": "Agencies \u2192 To Live", + "amount": 0.03359 + }, + { + "name": "Agencies \u2192 Toronto Public Library", + "amount": 0.020797999999999997 + }, + { + "name": "Agencies \u2192 CreateTO", + "amount": 0.018463 + }, + { + "name": "Agencies \u2192 Toronto Transit Commission - Wheel Trans", + "amount": 0.008468 + }, + { + "name": "Agencies \u2192 Toronto & Region Conservation Authority", + "amount": 0.005743000000000001 + }, + { + "name": "Agencies \u2192 Sankofa Square", + "amount": 0.0023290000000000003 + }, + { + "name": "Agencies \u2192 Toronto Police Service Board", + "amount": 0.000853 + }, + { + "name": "Agencies \u2192 Heritage Toronto", + "amount": 0.000696 + } + ] + }, + { + "name": "Development & Growth Services", + "children": [ + { + "name": "Development & Growth Services \u2192 Housing Secretariat", + "amount": 0.258788 + }, + { + "name": "Development & Growth Services \u2192 Toronto Building", + "amount": 0.099429 + }, + { + "name": "Development & Growth Services \u2192 City Planning", + "amount": 0.05158 + }, + { + "name": "Development & Growth Services \u2192 Development Review", + "amount": 0.00828 + } + ] + }, + { + "name": "Infrastructure Services", + "children": [ + { + "name": "Infrastructure Services \u2192 Transportation Services", + "amount": 0.220585 + }, + { + "name": "Infrastructure Services \u2192 Engineering & Construction Services", + "amount": 0.079664 + }, + { + "name": "Infrastructure Services \u2192 Municipal Licensing & Standards", + "amount": 0.058732 + }, + { + "name": "Infrastructure Services \u2192 Policy, Planning, Finance & Administration", + "amount": 0.017036000000000003 + }, + { + "name": "Infrastructure Services \u2192 Transit Expansion", + "amount": 0.009922 + }, + { + "name": "Infrastructure Services \u2192 Toronto Emergency Management", + "amount": 0.001307 + } + ] + }, + { + "name": "Capital & Corporate Financing", + "children": [ + { + "name": "Capital & Corporate Financing \u2192 Sustainment Debt Charges", + "amount": 0.167781 + }, + { + "name": "Capital & Corporate Financing \u2192 Capital from Current Technology", + "amount": 0.15 + } + ] + }, + { + "name": "Non-Program Expenditures", + "children": [ + { + "name": "Non-Program Expenditures \u2192 Programs Funded from Reserve Funds", + "amount": 0.16631100000000001 + }, + { + "name": "Non-Program Expenditures \u2192 Other Corporate Expenditures", + "amount": 0.11699599999999999 + } + ] + }, + { + "name": "Corporate Services", + "children": [ + { + "name": "Corporate Services \u2192 Corporate Real Estate Management", + "amount": 0.102509 + }, + { + "name": "Corporate Services \u2192 Technology Services", + "amount": 0.048427 + }, + { + "name": "Corporate Services \u2192 Fleet Services", + "amount": 0.043323 + }, + { + "name": "Corporate Services \u2192 Customer Experience", + "amount": 0.009594 + }, + { + "name": "Corporate Services \u2192 Environment & Climate", + "amount": 0.004221 + }, + { + "name": "Corporate Services \u2192 Office of the Chief Information Security Officer", + "amount": 0.00041799999999999997 + } + ] + }, + { + "name": "Finance and Treasury Services", + "children": [ + { + "name": "Finance and Treasury Services \u2192 Financial Operations & Control", + "amount": 0.042066 + }, + { + "name": "Finance and Treasury Services \u2192 Office of the Chief Financial Officer and Treasurer", + "amount": 0.016367 + } + ] + }, + { + "name": "Other City Programs", + "children": [ + { + "name": "Other City Programs \u2192 Legal Services", + "amount": 0.024591000000000002 + }, + { + "name": "Other City Programs \u2192 City Clerk's Office", + "amount": 0.016242999999999997 + }, + { + "name": "Other City Programs \u2192 City Council", + "amount": 0.000424 + } + ] + }, + { + "name": "City Manager", + "children": [ + { + "name": "City Manager \u2192 City Manager's Office (Excluding FIFA)", + "amount": 0.016877 + } + ] + }, + { + "name": "Corporate Accounts", + "children": [ + { + "name": "Corporate Accounts \u2192 Arena Boards of Management", + "amount": 0.011182000000000001 + }, + { + "name": "Corporate Accounts \u2192 Association of Community Centres", + "amount": 0.000332 + } + ] + }, + { + "name": "Accountability Offices", + "children": [ + { + "name": "Accountability Offices \u2192 Integrity Commissioner's Office", + "amount": 5.3e-5 + } + ] + } + ] + }, + "population": 2930000, + "budget_balance": -4.025381000000001, + "per_capita_spending": 5360, + "property_tax_per_capita": null, + "property_tax_revenue": 0.0 +} diff --git a/data/toronto-operating/summary.json b/data/toronto-operating/summary.json new file mode 100644 index 00000000..977225f9 --- /dev/null +++ b/data/toronto-operating/summary.json @@ -0,0 +1,133 @@ +{ + "name": "Toronto Operating Budget", + "financialYear": "2024 Operating Budget", + "source": "https://docs.google.com/spreadsheets/d/1nbUIUaV75xoTXwj6MvtV3pw4vmw1yb-b/edit?usp=sharing", + "totalProvincialSpending": 15.704151000000001, + "totalProvincialSpendingFormatted": "$15.7B", + "totalEmployees": 44000, + "netDebt": null, + "totalDebt": null, + "debtInterest": null, + "population": 2930000, + "budgetBalance": -4.025381000000001, + "budgetBalanceFormatted": "$4B", + "perCapitaSpending": 5360, + "propertyTaxPerCapita": null, + "propertyTaxRevenue": 0.0, + "propertyTaxRevenueFormatted": "$0M", + "ministries": [ + { + "name": "Community and Social Services", + "slug": "community-and-social-services", + "totalSpending": 5.2458789999999995, + "totalSpendingFormatted": "$5.2B", + "percentage": 33.404410082404326, + "percentageFormatted": "33.4%" + }, + { + "name": "Agencies", + "slug": "agencies", + "totalSpending": 4.6652070000000005, + "totalSpendingFormatted": "$4.7B", + "percentage": 29.706839930410755, + "percentageFormatted": "29.7%" + }, + { + "name": "Corporate Accounts", + "slug": "corporate-accounts", + "totalSpending": 1.2246519999999999, + "totalSpendingFormatted": "$1.2B", + "percentage": 7.79826938750143, + "percentageFormatted": "7.8%" + }, + { + "name": "Non-Levy Operation", + "slug": "non-levy-operation", + "totalSpending": 1.0374940000000001, + "totalSpendingFormatted": "$1B", + "percentage": 6.606495314519073, + "percentageFormatted": "6.6%" + }, + { + "name": "Development & Growth Services", + "slug": "development-and-growth-services", + "totalSpending": 0.896295, + "totalSpendingFormatted": "$896M", + "percentage": 5.707376349093943, + "percentageFormatted": "5.7%" + }, + { + "name": "Infrastructure Services", + "slug": "infrastructure-services", + "totalSpending": 0.6995950000000001, + "totalSpendingFormatted": "$700M", + "percentage": 4.4548412709480445, + "percentageFormatted": "4.5%" + }, + { + "name": "Non-Program Expenditures", + "slug": "non-program-expenditures", + "totalSpending": 0.6915759999999999, + "totalSpendingFormatted": "$692M", + "percentage": 4.403778338606141, + "percentageFormatted": "4.4%" + }, + { + "name": "Corporate Services", + "slug": "corporate-services", + "totalSpending": 0.5537809999999999, + "totalSpendingFormatted": "$554M", + "percentage": 3.526335170872974, + "percentageFormatted": "3.5%" + }, + { + "name": "City Building Fund (CBF)", + "slug": "city-building-fund-cbf", + "totalSpending": 0.314096, + "totalSpendingFormatted": "$314M", + "percentage": 2.0000826533061224, + "percentageFormatted": "2.0%" + }, + { + "name": "Other City Programs", + "slug": "other-city-programs", + "totalSpending": 0.123583, + "totalSpendingFormatted": "$124M", + "percentage": 0.7869448020462868, + "percentageFormatted": "0.8%" + }, + { + "name": "Finance and Treasury Services", + "slug": "finance-and-treasury-services", + "totalSpending": 0.112051, + "totalSpendingFormatted": "$112M", + "percentage": 0.7135119880087754, + "percentageFormatted": "0.7%" + }, + { + "name": "City Manager", + "slug": "city-manager", + "totalSpending": 0.08591700000000001, + "totalSpendingFormatted": "$86M", + "percentage": 0.5470973884548105, + "percentageFormatted": "0.5%" + }, + { + "name": "Special Levy for Scarborough Subway", + "slug": "special-levy-for-scarborough-subway", + "totalSpending": 0.040699, + "totalSpendingFormatted": "$41M", + "percentage": 0.25916077857376685, + "percentageFormatted": "0.3%" + }, + { + "name": "Accountability Offices", + "slug": "accountability-offices", + "totalSpending": 0.013326, + "totalSpendingFormatted": "$13M", + "percentage": 0.08485654525354475, + "percentageFormatted": "0.1%" + } + ], + "generatedAt": "2025-11-11T19:19:32Z" +} diff --git a/data/toronto/2024 City of Toronto Budget Summary (Operating).xlsx b/data/toronto/2024 City of Toronto Budget Summary (Operating).xlsx new file mode 100644 index 0000000000000000000000000000000000000000..69c639790e71245098ad56c074d48638c5d4e4ea GIT binary patch literal 84282 zcmeFZ2UJsC*Dm_n8;A{%t{@$WbfiV)rI$#T8tKwIp`#+86p`LR>Ai*;ic0TF=ppnX zEtCKuq@BR~pZ|N$9sl{xIp00wj&a8)BkVOZ=d;$H>)CVelFXIoD(BAM`Q!5C%YUE( ztPKD7+ut3s>}3ydH#M`jbo;9j;P-N{clb1*-uCFmyUf>+3cl;kuhQRzWfj>3hwh_U;v@*hr6 z#jIbtcMCrWUBbo9c2$S2#Z^Dk$hAbXswqy@UV$YENwMhM^x2aee`)FA@acu4-9C3_ z+J^L03ufTMec4;=w>>?us^jSo>1s=JLW4ZitQ+Y>Eo(i!S;TA}E;#+n==RH=zlo_0 z6?Hye@}{4?8^Rp8HCw-27} zq-c94IBX8(J^bF%Y}`n^@w4wSVK8m2->XqCrYYOw`>TsKz%y@s9Ik#5qcBN8&)j&A zHlj76kEEb?f0UjUDIFNE_*P%?Vm#*Hy=Gn6bC+>3k@X!-`r>-3T;y{-!=>Qj8_hAo zDlut1{K7ZF*@F=7!Yng?aK9^Ncgm>0s?;ZH8h_?zS1#9Gi$@=B_eV_gY;{lB*I0jI z*+{S1qV?zgq4gxe;+(6CiDPaPp5lngZ?m8nJ`&+OeHZcPD`$EGXF>>*D?uSsHd>y; ziS8H;Pq&ymzc1KOD|`nLI)g27-98JQYMiC0wk z#C>~D@Zi30TF<2urqSB8ce%(c%bopaOyB)0iY;7CAvTWIZh-#~P9r%zZorXV;Ku9B z&)YAt%>BbpZnxjkkt^hpbNG|tz`m)vB$#9&S+Tz+X*GUfSY=KWm@y=@NH@f6P})u7 z_h~E+dY6Lx44XasKw}P|mDvf!btO7AjMwgSj_>7tQ=;jZZb0L;YoJFn@3@QD9n9Rd zI^Vu}f__wSox;a%LnNx;Sfp5L_P#!^DE)O#K5?q1tCUZS+?l7)N7TXtxjnnvy`5t< zcPc6tbb>xGwFfQS^u0;H_AKuMZ`Dmo%r47kLe%Hn9nlGi>+eSWd6M6}Tc~Aw;%jk- zR9a~duUO&uI@~e~j#~T=|I}sgAcz<(W+@Mh zKc`?s-H~KgzJI>1>|(2w>M>2ijU^Vv=#rroie}AWY2{!Mbdc)#fJ--rBmtDy#q&z^ zUW?(JbfRzg(PxEnr92qB+i?Eo?c?@ugFQ;u_>tZDgP}*%B^*jmcrL;%RuTC>%=e-# zL`Cnrt}wkz7g6T=fM}kJjy>)PQ#*QSjus+3&KGI*_D>+yVZkRcGxF+7 zLu~(#7y`Rm+W(J{#DAiR9C~VdPJrUVkK6m#<#8{BjN>#rW7W7U3}en+He3{7>g)7W zcEjDRQu-Xu&%QgW04It$u7|2nDp5rE{Lx_+du@R-4U`FkJgczj1c1{z zjrio1-PaqvS$J`5Z10j;4X;9xgk?g2zUGIK;}=p^RkKTU;Lv%>zU(vT*usy4PaZek z99c`j0zC~9USdCOvR6TYJdfIEkWYCsQqPnMR9$nQjgknzl*Z|I?9g)NgoeiOMNBPu zl5GFT;%~=a26f3Bed=(;LFq(F zhnn(Pw|q_Vt8V&7v>7PtN=wWMQv8BLDVOf$#Yhxh8C3Gr9V}j#+k0|3#kajalVf51 z+qsl;i)ftC*+hjK|{l-_e*IU%*(+l@wko(~y3SKhqibRw(RjsAvLD{Ra1> z;xmHO6>%c{0kT`OrFRtEjl9!!h6&Wh*C6ZD9a_m@(h_Sa4?(@Ddv%WKO<#At_|YP= zlBY+shKtv}(qyKzznZn~G@>q<*#uo6(|GCJKZ~gU36(-8*MQ$t{@RFbx=3#cR2nnkN>}4pV{GZyg$t){7}r=Y8odt=?D4$6Sw8#t8`K>TT!+S> zWLm0GQh~2>6+K@vjTb3ae|x0%M8MdkhI=@1HcAXG?2=IwcD3}gBGue*=w4q_>8AZQ zjp#SOWh*bf;Z9#6w)V=44?NB}Jo!>LrmGpH0J|Tb>-#|E>E68av$V=5yyJfy$!#k| zN%>q*(=0P1<`@0+7@*@5_KpASM^$;RpsUWAQjC9if_k(f#31l2lyvifwXUQw?hJhI zg|fxH`wR!?U(Mc~?D!7l+et&!@I6QMEV>%7hw(}s zoR1~b@9Fxq?slKw$i}yiW|!|~Eb*tMfiISVzPC?DpIx0 zW~6#|u!@ElyY+QAf7^>T_LIrkIxIm-C}nrEMMn_v7XAI#hA#Zuv-a0$N$h zI3A$itc59Mo2nnq_4s2g$8;SV(bp19TMo6fS97j>Q|CTtI@5vw`r^m0(nu}7&+B7Q zSNl*4b{hf4kA-#DUo11cuJ|Rr^wpg9$DP{}%YjAoTH|lqzVGN=kl4R*Dds|2u+zJP z51oL55V8JXwv+qM^N`L|35t4+P|aKCu3*(buMZ=mGb!nQN=jfaYi8Oi2-JDk=ylhK ze~SOax(OS+m1j_VtyA+#t*0uxqAwv!%(_k_$0VzVJuLB4)L`D751O8chz$Z|4!+3S z+{mdYU8A`@lF!Ln_(RWOaarGjPYi8#HXuc!P6#GAgr2z>ZxMO3ExRE+KfnAbLsh*X zB-`vy!IsR})ZHT*%PCyxT=VBT&|4r=(K4_O#D9AGCzMbt`S7;L>MqM6o!+V{i)P+~aOMj)5%ngJ7i{zBz{MS?JG@|~UQ%dY_Db+=O zq&rQiKiDse7KLf*giXB{U7z%_*1tx+Oubx#Lz=>66#;J$Uc`({Yk8rJ**aw_NoSM0 z&G)b`6$O7xYd>?MS;Au42I4Ga9vKVR2=jHHk!k<{2N1mjhXHGX5#s?NT^DSgRR}3d zJ3SEqKB5sWs&NUsAk|1&%7|doS2Caoy}e#~P8WOe9-nV8qxa_36tidfM^u*P>jus* z=!scRLYWtyRK0HAiL8+Mc|<+A6VkAA^%aSY>s$J6-t}{iBLea5PoBxFU-^-77fZfM zHD|*y_YS_e-f=_F`UV+=Q|e#i{{E$y&$KAAG3#OcONK7(x6ryFA72-J*>(0tqb#p0 z*dsILXf8{!lV`f8y?_+4&V#Zkx>3XFZb6m-o2po}wQ*v{mN1~R+`!$VN(kpV0n1MI z(`aR&U5p)(`+>gng;GB)#VghVUvV$HXGv%ZI!?~1FOZX*y1fGQJjtoIbIf*m&Zfa; z4CI`GglF(~e4?l$=hQk!z$M<3oKp1ZCqLUIoa9t)_28g*z_l~mhMdCJCGtwfUISp; zI?OliSAv4RroJLS+nr@*J&t@b)U&(f;1@kmf}Ur%8!vaR@UCiB<`y&IW^CD?b)q+; z1-I|-muMJWo!(==##hWjIeQFb6>eRaMc1xCw4T6$dcT#q+Nx)oD!q zJ0%sw$<@y7m8GS-8{oA0>vNK6ge!xR>%}?F9mz*ttuG=(J+yDgjqN}@*2gub800x4{4DQfeJY7HxYPZs`KjemvqeavOdPBkyYEc$BDFc9 z*NBHT!!1D|TEr~SA(NpuHpCGqz=Sjb;_-dsz%7*kBxIK`keG@j$zVLV&>J{3m>JdL zTe_Ps%K#d}ItJpm1DXkY4!hgMuKrX2E8`I*Ol$cesTj&nyD=3%ys=v|hiD|a7r6Ju zKgP3oM|OuohS*7mJM&1?F|HT~z))Gk2x!ck5p+1!c8dwAo`CbjM3o2nPLSMPUf}Vm zq?SqIq1QgHI)5`DFpz|XQw0+6M8C&CsWq=Ha0UrL+M3^l1EOF!L?B`Ye*|}IRTvzS zaSE&_F84Xkc9Ew2W(d$gRneL2QKVIZQ)ox6cNuYw*tdud1c&?k&R{3E29SN_k!$o%Cyw_!A7|+vX4OFFI~q z*s}~~EPVmeGl~>ha_{JJk&`T`pQ!WwrJt0s++ZMClxI8y;N8a#@f?npZI#?*3k5%Q`=uXUb1k&-9IiLM<#WB`B!x`|{)hr&34O3^SRo+IPpNhHbp4 zn2jm7Gx5Rbh_xur9>1`9+O0ylinUCIDR4g%+?~Ec0KD<(a9I(ZBuK!&b3u z5g)T@2+W90NPX27E>kE7mC@HC8+6MS8SUDFM|$d~p}9Z?^{|L^&~@nB!NLy>AKOX- zl>mB@(lEYKAiH`|L@DUwdH!>HwvJ_sf7%h^=X|6d+i3~5Tk;8d$~^w`X0ULw;iGve zxzG6G8h6!Zxps)w;tQ)ye^)N3O5x4Mk8P!tuzj!hQ;kl|+kTok$AeuWVH~$awF!Ctg zrQHS?z2ud&k_X%ZtJy|GfR$t~N2 z-X)|N@Ka8D8bj%E@oS~%N_5Yg6GL3@lA1a2(~?)*y8Q9AzT&?uKe}#>aK-mXcFo6r zSkx$TfFE!47AwV99`r>2N2jg7I@zK?k!|@r=6{)_PIshc0gPJmO5kT;nqgKuCH37Q zmxz)jqqEHB&)B-`7Mn!{{a7Bm*<%aJ6b15rT)tu-MSWB#?6uk@7P;tJzVffS7?CX> zIV?ITw%w&+s181eAnIi5tO1&>?4FD;h$tb%=bNH@3_*s8M2UG@-Q3LFSdlYj&GaHF z2=TeB)KR!I(Pe(Qwr8U-NuEQm8Ry!jZ;A z%a}#1>I6%I?cew1bbs1+iMyyQA)=fbd5I~;Q6as&AutHK&zYp3Jg>uIZIe}?RSm^D z|6t5QDKu}-BIFKk+h|(a`={l8$Wk8|rZL};9a${!m<1POGC!NBk;5mdO;}^B&~(bx z-oM)?!vbm7-S@&`(~sQY)%%p(($2w4Ohws)hKLs=4s%Vifid^P>-Y4zjS=Zo@=!(( z;=aa{{miebMHHnQ;>y?THFM<)%i5meY}~MoD;}{Z!04qJ`tXSKs95M%W*ys@qKI^i z@4m-Coz|i}F1-5m(7D9WOk^voX*!s15Saaq(J6^)6p4UXR`b=x2M;S0;;VnST-I$> zIPi)oyVbHrw{5FQj^Bl{SBaX{+FkcwwDC)4P zd1$!C9iACf#$nmH!YS4GIZ~NYi>Yg_kwWsoD}_Imk-wEgr*no=x$$$lvYM7ZovVwc z%S2JvqI(UY!+aJeu0Bqr-^y06a6dyErA(>qpX}zXS=s6{viPCV$3Cl75jO0Sr#_WA zw|Q2E=8{>VS!X8gwRgC zYC&^MtN`L`hKFtcvBfjnR%^o2z-D8h`7qU#esU$Q=d%vfrts-T?3u#0JZbE!`ZX&$ z$J?o+bO^F1a;XWhafl$R#{@J#$g`S)W`k%#S1;^t@(tT-{j|fVF<5V*?fsw`TA4 zB#G>VJSq@ih~1qC?02E-TffL!1uX4<9(hN>aNU-ipCT+#ERUtRM8>~| z1|2*92pH&ER8Xht^}oO#64d#h@0ACly&l8He?A2>>nB#SdU!_B^UxF}jc|)4wk&M0 zRfmn(JR1M9aFtinIxp@^*4MC+Nmj)3%5PyKL^UQJo)SfeLFkt(^4mcb79I)m+v12X zW?#dm$IC*bW1WW{)L6St2wlObYWU`bNNYI{-Knv*oe;Y4|4xAs`EELNXIg0ESwN4| zgvcy&3e9qhe;ozGDnb^X)j!tYXA;8G*JQx9-E!tF>Dw@Qb+GRg zGI#aS@y2%x(w;Y6(N_z?Uk&cB21{-Vp7;X~T#a4S3!Ofgl<{6)p6^T9+aFTLKfRLH z+m^^N%k#$E`)F^$klmS&YL?Zn`267VJi^Z@{_8g>zfx4`E%D?~r@CgHvkK@Pk?K0- zIeX?7)Pek!Z}U=q8|!3q`m;POXNh3d{5kil$?D(M?g*y8g>zd-T*%kzcE75g|7q<` zn)-b>w|IJ_s&(6%y@dpWx-}bo(piEbc`yV%+3hZxHYlH0J?}0mm`<5r9ld7%cW8dh zns%BxJG@XlT{%z7MIv4`f5Dw6S-oRTTQEHgUT7gfov+p7&ZGV}pnM+OSt3$3f8L!w zS-ovdSTH>VZet-qnGf%Fr&rI9UK37JXM@{_r~d;ek*wae<}R525x!<2!ITg0ahFif zk6m+5Q|E-QiKnaQ!CfTMRr43!{{f`4kT{nw)a`yz-TKoSMcUv!IGuR<(>x((i6B+$ zIrodngJ0Ju1k>NZ$-v65rBCy2$0Ab5Vr8jP-tFwE6EW*Vte!j(V^74ki4*bNi3lG* z5j{@C#W4f2XjLkgcN;x=BI=!p=T1e%6Y=)QiT3e{$ObboTv5*j;?orOWZ5aJY_rXNiJ1FZn-3K|;S87@Bmnv3J zU$K#UTdJtYd&^$#nL+eR-dn?A=YK>0*9^E;u=-}7S6}@WHpBATqaWJIxf75UhDH?_+ z-q`XctJ}*tu#Y8}66Irz}Ywfxtx+kto{SEx=q~GlmZOW$;z`GMH$4NJl z`zIq@IT=jtWJ0$8fEuu!m_$x`{hx>_r!K^u>>=-T52rqIpYGw*^HaaHPM!G&)an#^ zx<|Sb=)kEn@+W=^okF8e{Ej#o^>5I}r_j?;)lZ;qr_k6FXxa&M<#bfelX?6NNN1< z|Bt|NP}UCJoE&QIT2}T_#Y$>!8@aGjMI~NMdpTu;Xfs~T;jlY~(J{I?6Jfuh|4s~a zEAk53%gGx=oAL?{hfx?tN9$TlghfDE+jK2*sOf51*-E=BsOfCvLP~!_|E(BEgR*w% zF6B@^u4Uyc?XIMLY$Nxvv|EYS)m~2BAljVQbvTUCFgjLuX(H@5^xugAE=As}_Hs`R zG+y#v9S%EdsPRen&P3Q-Xx3NVJ2})BYP0T@a#c`Yu#tOH`WyOh#Xt-+t6euPhnl@M z>p>}3B{jQ^+=o&wC0=EFIVA%PGhXH4uv>;2F}iURVZWjOP7D+%^77cr$r)&v^70Ia zT{YB**43T}3xj5T*VWFUrmoFmEiI^^rnZp_F8vMtw_;!{xIHT|*f=`8E3+1X?Akyc zghIe9jwnykt_Q>|5K|A{IXLdxY6S!FUTzq#Lju7Oj3!|B{NAykwjqen{LGAxP0d8V zqxrtWP$aqtT^*XZNdAf$LOM8TDEA<>APIX1o5Xo5-#S=;#2gL{7>8uC0F48YGNo9& zGXXJxjIyShMfwE<5_iUjHsIN?jqO%@k|&|UR|@A&>O*eKqIP}(_3Bnz=YWaZfk#`! z`PJ3djZo5QWdVzIKm#SqAAfuXocSk{BK{W|5Z5tk1y6wD+@|Lsa!oPKoJ6( zV^Th>6}rl5W-ZEEPc8k#UWh8qM#T_ZSNA^b9KTV$YQWyIO2Tr@_C&JZtJ3ICXo|aZ zmL7JtS8zxlsY^7h^pWWz59a01^qN7ZHA4jk-sO3`VSj(+R?1!Ev-h9r*9Dw6x^r@> zTDp>y!Pi39--~=uN*H)YvUno!vMMrRPE6ubE$s1eutRZ?4zy~0B=!SX_wv?m%ykvT zeG$1UX{|onk5;c-TYwGhXNumWVxlx+PPg7Uyb+{F3ppvbkhJxPY9|+wSN-o4k^ha9 zQ#$@CB1ck2A>NBV;m-~=Dhx%-ep9r=YK>8I33sQ^iMSDkNbSk*SP5t_@y8V<51Oda6!#sB zx_S_{iUWyzhs8&>uC3|iWh-JEqYDVVOj=AiaRWv=7}(wzaKf(*l0cj=BI@SE^aHS@7;QIyw>v~|@8d5IS zFEPd!uA1H?9P2ccX0uKvC+v|tw! z%V`6R_&pi!M2Y@7jG4?rU{~rwVdYagGc|_00p8Wq0W%Kca9bIF+`4J?@o~k+@(j^z z-+}S1ZPGD(Yhdwvpm47PWY;QheC^c+=@q_SM5KCLEw)s7b=miu(-?lwMy+nzHiO6Y zRrGetWa(c10A$vFbsID;wlQFVXlZd!^glR;IgL>vQkQLa;a09BXN2w&x@W1q< z0@p-*ydq_q<-bF*dv^GF5#pLia*-MS9ZtH-!h0s~HZ%Gft43Otz0dKA~HpPUB zZ5d3->cWZn{^Q#SmcV1j!+{MD(vB)TjgiK?^3U7TyMp;OmP=mA)xG7tx^5==Iahp| zejwJL5pBMVZ{5wjxSnxw{jl5>U=m+?v{dnaQ}1zl@FTcaM%9;=7wc`1)j(+1H(Un+ zfFd=gmIoO65$i~93npUKNRmJLxXn>*D=cp-rK&Ew>Zy#cWJbWKWAv64h8Glw?^;U* z50ZWow?XmXz!l=&Hp%CO6UnWLG&E0cjtrNn^P|e^#eF)?w=P8D(5CkJ8wfD8 zC`&{vWTS5xZ?)%Gi5+2vp*Trs@%`|gwXWrXQLD=1C|rKvVDIsMK+~Y@#PwFm2jXjo zn+u=!UVyo0)%(_Y0UNwpS{|#Dg89RG#yv&6q7LJ+qqS86-VTDq<-4xdk6tmCtEy={B=gnGCkm)a{Btbsj-PVU2!^>5>H-h z#-3t(;XT-8pBl#@B@XLw(AML2V@OJaZ;uU5gHWMw5wELl1JapFbaH@OMrMYg#u~coy@yM=hvv##mlCI__-i;-{K=(qOIxnhPkbvBJSeq|Wpm3W z9X)P+jOrWAmk)0YX=x0>f8E5N^c^Sn^`JCgr@uHZLQ!V-GO8aJ4OR`%cN#0+^4Wv? z3AGv<)!+oVT%X8^7Io`#yB?NhOt?fZ_Dk}H+55}YHg&s*I_SkwH&jV`M?0uSJ2;=b zA|LJrEYWU7>GmD0V4=2kM^qc52YRi1qII!wZ3Jsc32KZH0iJTfMDFlI5_8Ibh1gF9VOmAEJPq zKmfm3xbc2$yhN5JXVFNZ<~sg7A5-S*264ME<@^@qd~%Ia#~L3F4=lDP9sZqsWIqOZS5JC`112w{J>PZ zX_sXJpKWxmaI=PfthMD&5JF_xqufEG`x=mk&n_h2a$u*v#Jjhz1?)f3kBIcG-{k)S zPVf`kIV|$^Xf}FCle)ZqT#=nwriY`2DtNzezndXq+_rCo!h+Kt|8CX-oJbJ=?}R$gDn zC_oeRTMv&Mrvbnb+SHAX^*!{`HhL8A^V7d+H8`ZfpzVU48hg*JMA~C612-+}pNYPn zPSCNX$rQH}@4oOFYSZ{=Hn8M^R%z>I)1> z%_2reW7@;~J)^~s!)E#Pi%?6=Si{&$&g4XoA8)CWv)oc(cOKZeTt=7iP2>xyU?viV z>=8pBDz>CU?be9Tb!kH!DH9t-;*(UKnIN;LOQm~~g0(|d)SPz4mU>d1Qge)TOlEsU z;}4jqTSVI6byi;Zu@_GMRBS-)dP&;Mz};zzP6x`wI+6I-Dq(KbUVe@o>ayPFx7DUo zq+F{#5zqoxhj2}kWsNU}LQ)=fAzh9GTByTYb%&u#t+k_*0e%g@?U}dXJvNZ$L$7;7 z;S@o&Au3ZT%JsQ&bFOhU!G(`m`dBd`4r&>-7wqaDW@bJ|WL0%%pCvo8KxSwo8?`RKulE&tG{s>8aQo^-K;mWGWO zkDgnbn~0c{o?G>O7@8UpPt9szl}lYo+_A2qAvK8qG?>+W}n zPA*pC?^Eh$lC#@Zbb zf;~JsYbW;0@%ZN=kl2(ot2(${hs>NmfCecgFUAP!r6S@lajJi`D~;(bv?>$hCKsQq zxKEXFm%Cer_bNvz_fGHR^izU*)BGxjVFGo*Gt?H9Yy1V|M9FG?KWOKBH#?zb`I&%T z>Rh}vJAbN6Ldx?(2Pck|Fm7ubgZ^SNMH>1DjW0;pL^)NNIH2UF`Nsk9k6nCJ;mO|WDJy6Q6T)g|Hpb=5^OxHm}svQ^Dj3#jze zMdVdgWM}brN>ltT?^{)P280rCZ68u?CGKkyeyV0~o=Afws> z-f}vgQZPxRO68}S1l0FjbE?=e+F#~*s>P*V`!NfUemtq#`yC?>=8tNDs;Gp+*QaPi zyyq3Z$~%OMJ26!)=D+4i8obh}#IJ`IKmP)XcRCIO$pSr(oZ+6Q*hh+?>Wo7EKbe4l+!?=x* zh^xI8Ue7t&f&{%YUXL-=VDx%Yk(;re(9rj|9XP2zaQXm2+0x|wYxqYGVtcj)>!$mw z>x|yjfm{pCE4j~zyZj2=$(dmWj~5kvWCeR<1p%jLCOgBpE(<{(j@WsDWQwSsC2kH} zrL?WnbHaux5(3E`XWtYUuRB??DB0%Q2TP1BbeLKNtnZ1 zc#NrOuMbu|MHAn_6d%#EW1$+tX}-|%Vw&(7zyahd+dcoYYgcDodB#a!DLn=M(u-B$ zX;Obvxg}ya^_`Ln!cwx+&rHc7w)gu-*sg1PdLo-+a~y!iQ*0&t@CfhS{07I{|Mgwp z*PIw}{eUudg%5DEx*sIswipnP#?S5z>sA-qen3AdY5ZP2br>(l9RI#&=TEW^W_xk( zbuJz0zU*W->SV9+<(733+IQ);tSm$&H*+W6;U0$?>zP1%IrLo?gn5=?=Icw_qq;^u&N~J7|9G+_|Xt*R&M8Pb)rrE!gx5G@qG9fyr%r*^hBZLfGf z+&M!R0{$Kh)`Y>Tq@-n(TVqBrD>M5ld;4}LXZ*xQ@)^HSAs8$ug^!t^Pka$rh%jB9 z?4sJhYy$z?l5#CG1C#wh*WY+2I(sLMpi29JNcAPIotT2rE9Zt&y_7P%dZ6`~tXetC zQiWw>L8X(3;MO|AMS>crZlS$p7$ zNU&RD+_fU;t!vBqPdI(NZ$<{TrYAyOmJ<8)7AX!moe}`w9DhbAhkHZ`CHt|w>Y#xaM4z`#TpCv;5l5BV}X#A%Y@cs?EVSMXJ?A3RUj?*z{tq(Z$^O zubeBijXrmtim;AeR`zA%8el6xxjl~hY-^~U;HG^(w~dWF#?wM=8CBRD&r8U|C%D21 zPSd%ZC7~9cH|l&Ddmh4T%6Z%gZe>ssH`u%Vfen2)Xwcvf-8koIw-$M+Uv}-WEl|FB z$InBVsU(Q;X80oyO@5DI<@VUH*n5F~uMP|zR~^c$rzog@1EJSyt!uWp`^0%%hv%bX zuScbg=v^;CJ^^qb1vjYBJ+MIOI1onT?n7?chc@gzN*y*syRtAdY3Cm^_DbPho@(Yd z#YbujN|p=kl|rpmB%}<7pHH&G-k7MW!!BX?02AWh5 zu0hj@xt3+z*gi>*K19AZSl-~nD@_-gJ5jvIBkiljhw}0%3i4_~4&!lpjWqPs@yyip zYdb#_Lqp~1dE;jy_ZxK{CT0TRU6!XqNIXZ-E+^VV2SsPdMrptdUwFZlwCxP=g@36l?N-OV>>0HhPFOR zCy&CnS)koR1&YV-X!q!8=C(c8Fy-Xjz^?EB0IEq+iI1?#8Sob}mXol>YX7=Gs7C4JjM;~E=+vIjfn!hC z;s_&i&C}6AljQtpv>FZLhd?tKs)9zG&0dUdrWZKQeOh)!LCP|q-FzkUY*Ao|9+)YQ8-*G) zHhu`RUSV{6V2eRuSsZMDe1OEzp_TDiFoJhpE)*q~J}+A?MGMAGv8|%llsSo9t;1{f zD}9_9*qNi=)!q0(p4(c*c-YU#R6B(+ektt9Cez?9- z$#PPG-6X(kVL6o3WafRKLmm>;PEHYrvv$3(-R#&x1#YepJm zXuIC1$!lyloZ%RexY`lwVlcM=eco4Q7BEKhaRGYoOJgdg)8>8@+zS2)cpF>Nc=AA& zYh&t_LKBj2^Au;-%76`joV2CskY1MwV`?Q}GHJK_R_!j_t-8Q(ajizXIO!S-em4Wv z!NW4sEMUmxD81QYQzBlV_0;e#H8gmh+%Q8gu)ac2HREOqQkO@U#<7H-vNtj_S2X~V z#2AG=LuR`(iG6J7PtvdZiW{^uvN3^h^W8uATUA{5zK@IYWTL#8<#QcP+cDA~kG^-= zt{&>mQj70hs`!{`)&mNArdN=VH%BASuullg12@rd2aTmUcEF$+z7X1NOpk!(sgx5r*S>p2TSCK=}aPVC2;{t z`QJz4X`$w_5bFC=Sod&!=JUflT77@!r3{@17CUO|qcoHZ?`DwasbpBd;Q%;XC)8ua z=pkVA(J^i`{}6~1_itHa27-+uzu7-@o-`=vc+r7rf468q01ZePODzp%HB2?weRytE zjfYp7NB>$|Y|SGn{cEEZTXMNDjl{Ly#k1a#rZHAVF;+D{l+m(vOq@1Ch4B+ULBf4O z&`D_0in}f{E2~|UN4|PqAcZpOX9<0_bfTBode<$8g6(sopvq*I%H&bOBEL+D%0+KW zO@G#R2c1?4T~=F<&;S|<@|}?Wv_@evC1}9j%hqaiWV4`tSX$05pw+09v$bqoZ#$8< zoz2`AntdDV}gij=#3`Db1@@mqBe!Uv$nS|)n7Jjs#0 z9rj-QR&8zqxCQMh!e@v9(tl$eb>4?yx`z)g$=}k~Eu_Dw^=MJ^QSsnhFLj?VuZIw? zHKl>mRjZEbWrWVao_^4Q8jrFx&qXpDNt99FHp63k4}%<4n)ORoaFZ<<|NE? z2$j~7lmKcu@*S$X#I?fyhEg#?l@wtZW!JOU$8H-t=%9UU*#-wNWCToV9Uq_^D}Ddi zq6!CPa*{ui?}7DUR|r1U0rf<2Z_Ex6gIz`P8JV)POrKd=lkF6AV}a=zO$0Zw zA!o6}w%cmF;Y&3k0!c0cNu!$ic)qpvs=M|a^yc~-Gxz$#?%9u7p2unx7Bj>HXBVdB z4uf% zjWLsK>eyRF3_3Kv+BdA)f*vt2zthKSR#IgLxZnoQ2>gtMUKDz?DEO%Of_ld|<%Gt? z6@|C|fIkW>LA5XJYy)GYb$sB(=n~?mM2`$4T_$6J zHa!vO!(a-%+3Osh z2|(b!=y#QC`aEh|mxNap%vMK^}z3jDQ0mmEOxsPT_^H=NJ z99izd8@sF_OA3XIT z(+@*+ztt=`K89W`Gye*A71l#hOG0$e@Fk-GH;!GY4A>Y*@rG;+-uB2gvDgi=@V%x^=kb)($t zC4)EBzahCTAXic9_hDMjkgJpFZ(&;9s5{f?&ph+zP$ijNb_)YZ=WT6Fw2c`ZGC_EOq<^u7ll9WcNgFN%Q zkZV1t{d!61$#iB&J|_&mh}yS+_)Mo~Y^q1W{sta=;%WUAN!N{{sFyr9nSKUheGeuy zhoZ26T%1mSvpM)0CiDqO=M1@6C3z0@cW~sUdK=Ql0z!{cXM@3=A@q~!AuxD1N_aY5 z-ZOt5C0r#*3CWK}+SE(_13IYaY2A*b>p?}-OR`O---K8{fC(+2A}k>C)9KNhgYRKN zF-STWhd(RLy;=4x5hHP!BEb9;ipTPy9=7jAT8@)#BrykRM9BMaW+8x>Az82xGL7yKWdw zuG}=`btM<@*~@)|vXb``t-Dk~{g_;~SIeqk5Z$J`q{!>~8~p!MHh!<^_|3q7$-wVY z{@)Dz*9?FRqRAEAO1yg$VNy17%!bkAx^8pcy&P(9d$|lKYgB1BxthC@+Iu)ms+RRP z_%|E8SIPC<_Hu8aS+7gE$W`9ts%~<@cWu@a0}XPmH@OUaBJ8Y<+!;d+a>X~f82mT* zHygj#3;kx`zh)pThg!~FE*hHkzLYCQ_f93X+;A9cZI+^eM!W7ECEl=!FjgD6n}!=tHzrnxRsLlG*K;ye^oFcFCMA$7GxhsYmtfgG0yvpPSCiZe4pjq!qxuSLBDyZ4X z%SwKOf3rc34O^=RG+VU&x_igOMYBrjRHxNhf44gQvRdGbL*mA$KkO?K@3V`+uJ|-G zW;TJH5FPK0+i zl~5rOfm+KSQt5MiJrrISi1lyAI*5&J6M-k?^5RMPL2LZvdihWP@*0BEqWS+~4MFzX z_Y*E`Zw=|FZXo*4Sx*g*bxqH(@?5WXo)^USBm(qHos9eVmt@T&-(4Ac9j&1&mKWp9 zRl9hh;>OQc_NDi)NMCrdnmw9f5MjeH5_yg9sp_ZaUB42Zo!8L{ePgJ=!Jd1-)Tw=} zEUwL2qNrMJ&yVLkw|6FX3wpj4e*2}|_AlDnhkf!tJB!>DI0E$VL%ZxG`0oGIyTk5G zTyJjU2EDj3>tIEKe(hZXLQe{~VTUq7FYL^?7mq?FF{ zCi&iQpSiV&1IfB(JE)nj*gr~Y#t0Z@IecON`T1973+~IG$_+)X51&oQyz1+DU*bG! z*s%xKi3SjlS8)(fKx-rR=7pkgMAPYVXhy%M$2~+voyV`;u1Y-O1%xEe%930(`4_e0-Z_(7o>M_)s~~ z&;P*tsaw@&OnIxN+%~|8h((kKHb^d)LyC{O5D+IP(t)=z7=*_4<+mdJj!^TAf!M|f zkXs83M%WGrB%%7|fO>w2Mk>h4p`WBaA(NLx8iev^lzVs<)l1FL&bE~Fjf02wi3oM{ z!A)<)B^+%g2n!aQZLM#{cSVhFmpNrjz{}Fy89l)Eq!!(Zh&UX2^KE9l)2JwjH-=aHN@*2EsBbNt&1BgKsS- z9Z861`pe)pHXtlO(so-KKpQQ5jj8G3f2N-kcc*iZJ$|~ zFCMJ2Ac8xp!{Il9G7Qt7gg6! zZY&rk9NUcKBX(l-zN0$==%_OTXBHdATpFyikIQ~--PkV<)v)i_NY!oX4yy}CQv-}t z+;z&@wD4Wk8u8u&U3U}k($LLRU3>eERZt}$8#P{)p>JGLMZ}=N#-T2iD3b`Z-*hp1 zp#Q_!#KRo~J1D_wRmJzN4hC39z15{xgw}xc4N=Ocm)$=Uk-|^?iWND+(w`lg*)Z$A zz2g4dffu%P)fN1-in<+p^%ls{#toysRq;0VX^VG8)76Z!&xh1fP5o45_oy_05mU@2 zW^QcP>RA?Psm!hRrGMbI#9)Lr^Bp&Hno{qP1~07HOZN=DQM2=xB7 zOaAsNz+oMfcBwK6-L*g-rHhpxHRH&H`VcBW71e=Ff+J?ZW%iYb|Hj^XfHl=@d*g^= zqlpSAD5xk10znBNND-AL29z3FKza)xy+=g^sR9B50wPU%O{k$My_e8JK%^5oBq4;5 zFTC%2&v(!LpL_2AlzZ=Y&Uv3F&)&0V%}my;S+l0>-<~B06ZgI71|!w|G`%N#o;iSv z&FO+`HLa(n<4V-xHtXn;j4y$9YTm{3I@64>)Y@cXhmtAG4QPeE3u7l(41L2+Dj2zP zr?M}k?>n$uT@NiPijW&6t0odgC{4u8*}kRPiG{frkPa_+Z{AF8^tN~ENUN97Lbt4A z#I|A&8t;XEF_|?_9I+Z<_J8rw!+Ftla(tm+ruN3dm~3yv_LH7%zZC9;s!tV!pREu> z{7)Z%|4Oq3pzhB;mJrUiLLT7H`T$<6+%O0HEss@%=vIgZKH3N1wQ|D(@V7j|2^y`C z$9N4NfZIx@IpA-3L=pyCA^P|MAAsLVrUl?{c`PH`X@w}_@Av>*RxHc`f6F6!veSLV zA_i&i13;I=gYc!RNc&cZ_*f@`P5?+;;wY2l zlB7X1E6vMUT!V)ZV$_I~!-#WPTt}s-5pZfm+F=A|7MJK@gc~&?<1j+vqj%WS&gd9r z{iv9b#^8XM&{vzN#JEBmc~Iz3xhsg?RzD*v(@y{C;59KJqrumSY&kYdiEKmV${^K| z^3Pccw))jsbbpk!{WC9*SVG~Syq)^&$-)mw3}FXvUIW*bvjKkmRH*f|5rJH334Omg zU|CBO&i-sBbIkJXEPUcRMWR;wIOd}1mN5lZ8-Ku8W zv{1;KqV`08zw2YHDKwZ;t?A{+A9k6<&Ky^rVtOovs|akOyAn}T?EES(cF*bo33 zp4|u<-VC`drhP*_FF5(Ajkqs5>N7ga} zeU7{Um`r+m*Xa6?!L9%hhCbhiWd)*N!|p`5Hi-m!0?w=}wE5U( zH-PsW3O9Xi=p~Asc-S1qn-~Qrf&-HfPDkk_OsBJiCK{T;!Il4SllS|8q@f)i?xdDp zP#LqD+*Z5I{vwdHLXApkQCBaERF~T#+U(Pak&fYbxYJsCpO!H{v-@jne96{XBL=Nv)Ai0RbuL+Uw0})k;O+mdaBiq{dCL@E&fWUhtP9tn9XL&yTBTR z(}}-~{H@^1DCEqcEdJtB4%#BFRc4+vvi*X*sLS`loGNQKe) zYt_6HkT9{wII(_i40$xWc6yngYO{*7VH98&}x4 z#+!}`N(To9AvS2}nN6qDg#P8pL5ZJ+W~rU<-$|#H$H#GI9&JxpRYFX)kSoTHPeiUX zgc~@O$y9QWz2WqjwnRJ0A($l`zIVI-92T2~OxTOADY?(ItX7WsPej_ch2L{76RP4K zi{X@*v#fEJD;1Jh>+BYvA7C`zh7m8}P5wYdSW__a;>X&sTx$ zB^v{55R+*I!P@dbcCaT4JpelWuTK7Lwf(zv{<*b60_=H?-Vr*@$Ts=C$-uxfAW))Y zW0-ByWEvz`3lIEPC$Bz@iAgjZIrh7B{;9P>)@1sjpl^8~GkEt5JvVgvD4Xo}CMAR2 zmx0VB8~tqm>g33WAT?WOqjSGY=bu|Ej`@)^0jKIcU0jH*Xl6OND&pE|QoOq3!FD(Ky<8#n?f)^8x3x8yBw7(BxzO zoUi#mdkp0-kcrQvBj$mMsSxYail@y~`I^M}v+7Py#nuPkz-5v!jU ztx?cx=U}yG#%Fj~Rj=-y?@OnlI*kAIhnS5rMzv*vVhL z#7}fPU($`f@q_Q9$LAMfWjF84>`l2PW+2YqwHOQ)x5Fl^>6P77{=%x#c0V`6o1{XM z(DyFbrTUv#B`hV3z?stPyDyl>tTDlKi4Y=#m_-@su45j6^*Khg9!JB;xVd(CwqX2V1M1 zsrCNkxo+%;@g&8Uw1kP*^{Ailm!-5vdQiXl_miQzY*a6*-*<+Q)`D6UQf2G7vNh`t zcGkX8Q7Vxe^9OBa6Xe~QAVP)X`Xps<3BNs(eWI$Kyt{_2A_L@LyK|kmepzyzPo+Bd zg#J1Jk?L9l-w*}LHJ;AdM2od z;<!I9OAA&g^3vr{6&Qf5J<)0vc z&iS-`%t6)N$>AD8Z{*I>=r`&5Yw^LpgzlM#2UxPll&>FQB&mj4N5C3v4@(uC^TC4a z!NMGNo$4tH4o1{P`>ua{Pw-WQ#s?9E{@*%UX@4o_S>z`v5bi7Dc) zPe~%zbNlb^Z4*a5WAVQGQ)~V{!V$WWkp~BBGx4nyr1Yp8rjtEY*4KZJ;!!VmKyg%u znI3e^Tih@f6}DUP0@ZVD?&e98%Ug|quGSQ-*OBHA)+*Qu%&NVSgbe^pR<4cs9nzyB zD?yy|-Cds&60P?l6M|6jU)EDYdZ5z#n|B#uZu+_thFtSG{XsmA0HwW>$n8kKgRvQ+ zRb*@Q3vb8{d5{IGEdeL$m0K5vPBP(UdV2@HVf%{&AZw65J1czUxcUZ<>GmhX$8ihu zj>1YU+`X@Ic=wgh9qf1>2kmCPQ++2VbE>m_kWkc}c{3$MErBl;{iUK%Kb)tar4H4d zhxaqd8@3=R9_55PbJvJJgeNGCcljkDZA5i@7u$PCgN40@a%nT?5q3cBbhnKDafxcd zBsKbb;g?heYYy+rhR!24Icf`0YJ5vW;>kTIRc_VYHDYx_-iZGrK#gy0a_*q)fK7~A z1)p1yRC2P*lnwQkeF2Uw*Us)-QqE)6u7OnW4Z#=B(io_97Dgr6_1`$6<2G)E)A&Aa z#00N-?_R+-3}1A%9OL))@SZXZ70w?1xNs}hug1AtaOP=^+0@!-iqXgy?C>}gF?Fg? zd&D1;?rt@WR$xk>>jUbC0c&O23l)gFt%HMce(psIFZfH>Mk{W$4m(>r2&tEu3+CNj z+4?bZ``}|2i_0hXq`_`Phnd>evCbv>prjWwa4M?w48tFuB0qhGX(P%kr~^!UiWCzlMI&=uEo}e=jLEj~GLJ&K*--PcmZ6?LZiHQ~AlA z>&wt@`&v3krR8@_sN<6?#B!bW@Vfk=pR_vDp26SiS(u@hZNZG3YWQqaF-JPDBxbId zBj_#a%C`;#d+tp6q}sxSj+?ZI zJF}AhkSXnj^+`r&f;qatCVwqeK#c@lu*`QzUG`0k8qw=XePMmT;7plC--<4&4oKv& zlM`-TW?OzPyt2OY_S4guzBe4^4~TeM^L$>dSarUIKHEpJx`L!J+1W6TAj_dEq8$}S z-G;nDxnEk{NG(WUR zCa%@Q(gnT#}ACdm%!%j#oo3Ak53(|6O#;H>AQ00POxcB z3EK7yV=8=V1S%HPLJaYTNt!w{jHTT+pMA@Zi0466Kj-*nSAm-t-E+^0zus+Ibx+Y_ z*7A@v@}(0$i(K*GGr-)^PIa!|O!}nZZvFUTf<_6Fs|3EK&3XiEaLbtZlY|_a{Z#tU zrK9ar$STnxPtwBDTy4x&ZS0P{<4xX$50?`)}P}K`-2SxD90kihMKd4&8Yq+(eP3gN!V zy=dvZ)yX=&@HBJHHbRAB;gpUPzV7U1m5V0=SuhLjiCK5^()^aHBI&Z<*Y(2Gr3#r{ z%l4d>Aim)IWjF2J&)FWnikV&)q>wPlpqSGbv-^g4(6m<2`Qm3#%exp-%6P;%WAp^S z5A5g)e2gssc6Eq(l5l1nO`Aj+rXA=_NY{V;-Bi1X{PPvdLL@n66x`ZoqQ^Kjl1Fwu0{mPvP#`p-NDby0whtlDB55c2^{%J014E??q&{2Rh|Ddd}C)Lfe+k z2W4p%dqk+!K+YX4u9T4MJeNAM-Mlb5MSOcn{e`u3^WgUjc~^#6O^oTehbd zHa|<#@$l%)cir8qnaYJw;g&1yUGVNe(c5a0u&us*6;l_Ndp}$(ToTkKc{*adEf}4> zJ~=;_OFI>7{-ArcFcr%zdWNUAU93A{74S)e>8mvGb2P)()gV$`FG?uNpcxWbC>Gyc zzA(C;#UG@_#i60{cF4h}0~OY>eM&K9l(oykGs<%AW5+`?f%cEfm{W)pjVjo!U0w;z zkS9Y!sSWq=EYkRkwU~DJ!THH=L3(&(pU8Gjr0=}GHNsIjDIi(3+&3%0!=8t< z>)E(7bW8N)A~g5TPaxsBkYwF*-)?SbSAkqW1$~|wpffKj`-T#^ca?9=!_7aUKMaaN zN4w+;yV%S6ipqPCfreabZzzjW?ncJBE0K09s5BgN-IL6@on<*vV>}^be)(uc4g0RM zu`BXR&p7M>d0zi~tu@B*vTY&QrN$~#r&}nU0P!g}rC;U%<+6pA4kOk}jB8K75sRE^~QY|Mt_`;bR4Q74t#*F2mz-MgZ;j;jH8~ z=sKL&y1N>FcS!&Ju=~jI_*~CAjdCR8gkk7w_JX8)Kq+3%%cP=)e8twEb>IDcQu6vs z1mSf=BMA>{*C$d^2njkDF{z)@nD%oO9GB6FZgxS6tr_WNp5Ai z=ZoYx&WfPqc7clCHXlw%RPZSOUp)VF6^loW0uDU@b18Y9| z;@Ojs9BiE-mc!7?iLBk0fsTMgZ?Ri!Tipw5IQpgBf;m^~r_yn&oM=BWY&i!j3tu#4 z;mc=*Bs^1hXlp6Cu$J_A2L8mpb3qQ~vaPishOHuRPy)E z7*Tf=1k=dc`}aQ_Tqv<8NUg{&k`3L-g4|?>mCQC_$4+6Fj+o_3D`u-Dq^Qw)CWP&} z)@(tQUB8RZ!X3LwnOv0**dA9ucD_(M{=i*3>3Gq$)d9P4d+LhYB#a+cXk2&Kc#<(` z)@_n4rQ@D{eNWKw0kg3KTPIkDbYzBHU6-#n*8@`h@gJi@dZR<{FwDj}nytM>?8Iu6 z3yRgahh0LmE~K-hs;rnZ79(+?(4zM!=|eX8Mvn{1%{owKD)buEWrrjYw_GAHM$10s0ENkJ^5>DpSk$c=CyT=#*Gm# z^^M4e*6+`pFcjZ@O;Z#BjXN&LSPI-3c$29Tmj%%;E^iwcP~{U$HeVW2<%|>88+Ts1 zOD@^jGQy$;P$k_1baBGwOJCxdz*21kY4IF_Vx>bn8p?xLY&fJqM+bn)iEq^gUjiAU zv(g5ES3m(7Hj6;UKPJb>Cx&ITyCyOWm|q8F4Vu5_<*~Vw%o_l_s1maTyqM9hocJWW z{R&8Nz+4J++~!U+@1V^c<(Md7g4%z`I{TiN&&D~KHwY-H5`zUwX0)p$8fLd&1*r|p zN`aVcoTGV1Y@C&2Vt`d@F%J_zWwg5`UK*Ia4k{e{4_WCl_>~hMWb?dtjiN=KaLi8T_t^v;*g_gVF}izt6g2b2>TeC6G=HDiEqHO+^Ki5WR=i5vq%*Fgn?L+`VAZETaX-U7u`G_gRjj2x9j{p_5pAke^& z6zGq#J{i1Aj>>v5o^9i2U*`HMlLRb?gvK#}tJMehMlEw12mBI;Tg6o`$E^*P%OdnR zid|E)a8w0+^IJ+bLCmjNn|@2l`D;o@_5DP)=q!b7n^!=g>!47zL0TJqjkjZoac(;#DwxNj%(MS{WrEY?oPCqo*rJ?8k-b6*x9AT3U4x~akjtcrxH_OMH zPJnl>u*p(4&x<$Y1%0jQx&QYH_^p$?`p4n;e_v+*JRJN3LxlgXu-pFx8r}Wdm|-%l zC^%6b$O*1wp_hP8A7^v;-UKqJd=Wb|4zv8{|=DxzdX?Q-y?kg1pfICQ>EW=xc|)XX%YjZHCNPg{ER-^u^rVxgr6m`-O3)iyMRf<0~M0mU2F*dXIg z^n$g)f$@lqe|7S2drilFheZEVL&0Smo2XxaZc&*1bxrar;a!Afp@R7$-)DvhEGM%*OorjWI6`CJH+;{R6zD``>+ka%j{pN+5b)T z|J9N2|HTIZ&_7I^c-bb$n>Yn)-vw46HjdLfnobu8)iyRIfj#XG{r&w;{)ZOJ+_4J> zyWHsJqyRLEzHm~>*2SsD`^U0huK0T&~$I)m{Bj&#N040UDZ- zOMmrIbH4y(|0GWM(LV@I7^T^k`B&qF#e_Yf_Q@DWP0rT1)=k~w^;bXp9Z-y4)hU-_ zR}CIrd2fE*uFQi_LR$)=J9A_9E&<~hVEM*Ut&_;Be%2*x;fbgm$ZqFIh6iPTX8K@} zFtlJQk4MtB#%fiFeBm zB55w+nwGx(T-)?Sr`7Yy=%mU`VFY`1C8oIIB9ovoxGn#Z_CeTzH(_VO)o1r1+^4ce zuP8+~Rf107*g`$og=0ked;B6BFtaVo{XLnw7i&>vY-kKQM_L2AV7 zsVpJ}-`mxGu!(zMU-`-PN|G@T&8`up1ym z%a_)G@%mHamGy4Bysk5pNsp=T2V0T#FLp;)xca9n?ukXRZL@j$R)ra}1+3!ssu?~3 z#6y|ahx68zu&a$po%#jzL=%8n&(`Pt{0oRdSk8XFz)@|2FxhJRQLX?b$QLeNg?~%zj z5c6+F0`}3TrgWZo->$s=lbB=?SXY(lQD zMr_rk(+$xyEAH!~ryD$Izn(xQSIZmaOwx|(m=>XKy570T6tXJ+&HKF#j#=6`4ve*jK>HuNX zhhGILwyJ_PxqU3jo&e_7PCb-nPg!-D*XqPQmO(}hu>{gX`QvBJ`{W;6k@qCOUJrPD zr#w18tYC=0>SVzc&GQS|5oxjM6*<{^hPgz;oDOB}7Tcbf;gZ*P2Q~R~#SiNqZk3k& zWivSw7h`*eIY=YydUK_WiH}#5TG%t0R0W(b8^O%AN85{kt>pqW#Ebhyfk zSnZawp{i^5_;zBJZ>tAsgBD}TmbDv-ZDpQo zNAI|pWnR;YjmizX#rhokG|MWWdPDBtDy{ADZ1vGs@2&nkni@+*4Z=Fr{)TTyV@AW>*pXM7ajr1s{7%>Ah&hBK_8D~cjG1h0l)bI z+100XfdZLNH6^tA(?XcE_2X^TG3Oybo@G{DBbINLQU^~%RnuJ;9>*(I1I16f@^<$( zCDklmE^@QU_32K8fV`0o?zx?{sLbSKg)yku6*%OzGOAmRzo}t#ZKpR0lA~An!SCnt{8qBK`xizIqCuFUN>ixn$OA;pEDdW;k zwOyjStybSRv|T-r86_N!Tj5*f;V`o=Dqgmw9r&%>LW3e5BhdZ%&qpr4x!)4sB!+Pk zJ9be>9#piaDB<0{x$H#tue|#4dTe#<<>B;Y&C6!~fy+YzPB{y1nW{WS9N01SaV4OP z%Fm%%*=5LKGp$;INEJTDZs{3DZI|9$)$DwKTQ0)G?kp;4gOaa$)JV$lv15dH|A)!< zuA?6&vwX)sG(oQCQd_)47?h|n;iIFKX=jwUJdn?iRM=99pD)lLy%`BM^OkdlmIVgn zj@Nt&(~Xaz4SFSuk2 zD;}?&IaB{}&ka`OcFU$F&hq>PhA@pFm%%$1?0kr94~lGr-jwhb=?2~?xWR+C6Uc5F z@2#PGsD>pedl`NWeWK$oa?8JIVOHmDl>#dc^Dg0d-nj zpJT@cTII!cDSLa-ESjTDG%{1zVpL^vZW(bb4S?1C1}+uj2R=mmqxSx9^H%f?xmSS* ziAe$aJj!+%x?vS|4qqNUzw(&3C$m{B+W4D}A|}LGncjZOF784tLc)gSu|Lt+s~>O@ zS6k?6lc8!RLsB6H3n%tz4(@$5IIOxys){Pqn=kRZTWZxMElwMM?&gEVs%KA@bjs{r zd@-k%eX}PC;#S!|hXPSPq+iqyO42plv>htu(w^GYi^*+Le<=J%h4+j>`aBY=QHLFe zpf~7OaVKak^by8N_ykVT7Rj>x%{VBBF3rkd$sMG2x}HUIH}=AqdWEz0R;F=i6xnr~ zHKBI!*waW`2duic_Sfj|p`+cpb`ipdEw&)HbV<}0sY5xrlfLFwpsI=SA1;Ua@b|m9 z9+v-3$@V7;mNg%QkQ>59UK@Pl`u{}z0buoEfl@y%C8kU6@E7Q+DBAz_5xl`6<`uAG9_4DP~yIPZ==OU)YgTK^~y zhmU(VMEGYfw?A`sxMEFvp7P ztLyM6W`5aE>Ql!Rr9}E)v0k$Fas8ZjG?1y>^>g}Bnaj#CCBTcShZm)o7k~Pq9 znLiTX*I;r*1bmW#mo^~0!Q{FK_!NUBZ9sB^$xRXPX@)G?fPw}SK@l)L!#r&OvcW_| z1kAv|do-ZC!2~D*W@NBD8h~jqxhn!@V#qogu-afEEdpj{m_HgoZZNqo0zSjQdn|yl z(d3Z`n1#XeSit2*6J-(bS%$1*0YZ%?Pej1y80L=!$TXTf6#<`T;H3)yHJWINfLR$V z=>m)zO~4{xHij&^0BEC$p$M3rVV*9)uhGOr1bl&k_jo{fqlvi)_#%Vl@qlFcV$qZC z#~XXDj9xr;FTlj=%nHNnzc_Nb{%r${`4#0F?cZF~-^j^doxRc2s(AFGp!@OA@xdfP??ve_>{|F?vzj{di<@+CEwx2(n{`}in;P2$)WUgsg6pezU>-^b_=x{$7HQqzzD&MqVs&!#;{U6`eV6OI zCsa1nqknMUXp~cZ4g2`rco%r;6AMN9)WNH>|1FH0S_O|@yypHkIQi;7U~oU?7Ewue ztG95L8`3U^jE4E%aDThYF57U{>bqRi*?SMa_navaeYC>B@|Ojhdfpd{USDB2b?@Qt z!C&PNn4H$s^YppZ*J4qv(Tf5r46N>NPv3j^|A|JW-ut%n%hp`osGw}E54f;i@I)tx zw2+>Js%Y)*?2MX0ZuNT;iR4YaMdqf?!sI=Xoz~2~>pR(*dxAR)&9WtO5t-DB5X!1V z4uI-4g+0yBKDZJak+e6X;TOF(sNom4x2-|WUuMqL!0hY=>^JaVY8*WP2I-Ig++x#} z@}9f{a7dV)c@o;1FekKqR8+)^TXUjy*6*E2QPWUOdZZKkVY@ArA3Oi^!MVMqSt0MSh^)g_W-Cy^n9_-Rg5>SjuRnXmit<}w${ ztsB-MBPOyZ0=6XE5|}~~QdH{vGjc#CUmB~9o z4u_Tb8TUK|S9uq!0$~ctlZP;bM7pE7*|EfHHz7xfXKzA|5NU7n?r#+f4)tcjp81x~ z2kF|#E+Al#T;tILg%{zSoywcf61hW~*KYx?HnUy_TxrJf02JrkZphh&+*;Iw@SSLO zbN*Nn7HZJ5B_(;YFy>pWg|CTfM0xG&`B)P}!&CoWR$jOZ?7ESEU~V;Tu)^mZ^Lom# zM`Y62;5>Cx_fv(8P@P~AI~L#(*{f7vC{B!+CBIn59n5aq!u6=%2YFZ3>kB)07*7D? z93e`VxeF>h07aC^{FG%sY+b#e#8gUz4z^})#&XlSfzV0_ZAC96H4koCbgg=ClGipn z`>SCdqytZxYRu#@KjQ+J50YhXgK~Hjh9x?9GntKsrlaexJ`d!VjqX3W&;RrvWS@Ua zeD(TYz0WWH%RYZH+8Lu*nw4rYDW8^?5Nvbms|&xqx**`iyJN~PKg#&b>kIWGz6iC; z_hXP#{?1V}!MXcs2kDO01zow1N=ns;7Duo_6kKm_ef=&8L#|LauHWA+^+VPAz97tf z8;MM<+uxh%r0mOO*Js27>SSsuTbtx{<9g~@9b5Hlb;x~VIdTOz)mhAe~Ekc@G^lwI*9n!7pREJ&Yf1caD&H*STj?3H5ac_*OE86d4&SOF0+^ zf;`DYay9^vDp*@(W$#O#i&y7foAf7dEG*OjnAH{64xPJP>89Y(*>ZJ4!?G031k(P} zH!}6b6U@sKH;r8wi!T514O;{Auk^8hD!{QrJUaNLcYU3LU*LwZ#K4qq9qcU;)R`%` z(Lz+$6wH^nK#rFv3$M@bzB}T@(+k@s^wt9cDPvNFm|W3qtYP^vuO6DuRkq0qe3<0R}wz5D$=@BySz`PH|`4rmPRP22DM(gwWM=PzWQi{6KP^5|+D; zda%hR%*sp^Nlgsf+uEV5Q;541is!&6J~s8%PXWt9(_w+tybpB-%{|&H`prn&Rgb*N zst|*`S=~(%QdW6YkwUS6ZY}q;S7T+>+zTHBV`+)}+Mm&^0 z)z7+a=8QIM)5`9kpcPOD6%ympA~*LJkSe(9?;>%ON#puT@;*1EWoAZ0Mk5lITOJmN zADiBk4(|YGbi>cRtcsI+QC+4Z96in8m{3D#jgs1G{ADUZv0b=1_ON7tEoWemx*M?6Gs+^+9|QOo&S#V{R!yr}xMMW1hm{sOuxw zdzP>gqqnu+RiPe@m!6Vq8sOI6nHVuQr2Ggc`!oOik=m`s z53yNaH2U*Wmb96D;NEThSO`wL2+?nW%Bfo%La0DBFm784Q{b`W{ACTyOMkY6`I2$t z2Z++9VWV7ZxGK_Aa|;!5mxys-d{S|Iv;fuP!BB1RaI8Sm6Lpb2Z3Q(1Mr~(5jTq`X zE~AE;a)sY+kS)MZ@~_}+%=dszvIXKbWWQ(FbduR?%p3Beh6H1w=%63ZCuM&qifBm5sk&z#FTkUf-GPN zaV1Pz&dSq~tj~K{gF=g)-fYsaK6r~3&U#R1`^DoLnZyLH?qa39fS%h}u5N|MabAl& zd`hU{&R3|#?h>Owyo?$8f<7v}n$Ay8Ju6rnb=(NrSG+r+_G1N4 zoI3Vs1S0I3P3uoXG00Va0!OY76AYRri09 zH{jOAKG$2;bgQjFz0GQRx&#rJw_8}u;>TcZ3Dr_fa>8PREy%LAu6x!ZrM<5ipYzAX znL=7>-8VE#cFOU0laOMzklI0^nxQYZgqB@Nq^)<_#GnQw z-LZtz_cCEQi)DVN%N~C?>$?guPJc6VZG5Z!hB>{ zX#KF5W4U!-i=xSj&d8^b#7yq5PVm4@+plJMY{&AU7fX2K^@~BVSM9pw&wbQ1XvrVD zn>~zT0;UxSw3sxUqJLD7XD?GX?+qJg)-w>Wgg)=%SiYG@_sq`VZ9yr!g;RsTjLy4L zKwT-g#W9Y=uj+)$)(?!eyL23bj((Lu2zY|T5VnN$k+{>w1{dnzN{!pf)1c#6?6Esu z+h2r^jt+}2SHf)bcEyy=oPD_g&mGx2$)t7VCA9M-!tX{wUX7dF8)(i2M4-I=(@nNu zQ}mrMX!?CcQo@voxO&;VV&@6{TFSormF_DWF)4FbFa-9-nkvujbTa zipr1C=pnR_4+=8pw_zcQ+dl^lZ6yzUk~l1ulO2XL*^F$SWphr&Gc&ZnL);AQR3-F* z)-yAvzLNVDVkR{x_pBzhB?AF>iJOre*gnkSqugi2){5g98oFci8;-7Dwvzpuek}yu zf0Q&*J%7m8=*ck5a-!z5vYn%>=A0k(3RKo!2qBC_Iwx$Mxa^5`X~eK`Z<-?`54JC& zI#z~!&b8$Wm(tNbHqbhE{OJqBTWn`UhE?)PZO4#WVRj}VV#6gUeS0+0B3dll{5~O0 zW%yGv6HJX-OxxJ^GYyl>1NqwBAAs5%_mMAR3zA^D>3OC4V{oleTa!@^>|)2uV$_G{ zd7r*Lp=Z*znDAC3E~SsOf7r}E1xnXEdD&XQG1oV5#U=3u)8~0>lMZc*lU@Eac3)|R zA9>bw-~=w?hyu&oDATT<^6}+|%gy?WOP;X|`a*Gc)RmGixjJtqI}H3L#z{bLS+}L0 z?tkbG3twr*uDiNE#>r$>fnT^j-dp?-k{%P&_LzB-YRfM9!*lxkNWggg2(`i^HdP+g zdhzz0)TSvHkT=REtoXY+ z<}6M&?YrhiX0gp?LlaVa^jfK28=t6KrHaKOEZn7((ywxR`q#JF-{Z?hzUBQqY5m-x zS`7hmmy>|zw2e1SP_t(0@VQSFmSz`*t4#$|gFCx8-}bkc4C-61jU$fmuw`WAc{~3Y z**`zTsXO+VIKEe_rE{w$wuaOGdBw2O0DKf-0PQaj_wgI51JietZ3~!AQB{I2fWt|Z zm18PzAdKJS|5= ztNO#~Fz9_NO8(@tlglghLld9K?ESuYiEump%Lr;$y;7+njAi(4Xe&$NwENVPfE?_u z{?&5Nkd|MyFCFnJ5W-mZe-4if-DFJ?7!eTFe4gbh#QGk6GJ;&ybh#MHF=EzMeT+_vz4|H`^QIP5Ul|>v+BQFoeay82G(hb+I+>wi#g4&y;D+_PmJPO3GVyJe`A zzrs-oKv6xfnxg$|a;nDS+4^e%fgcR~AQ1X)M@U*ctC~yNoTZVtN~(lw(r+WuR-G>d z4JMC&gCkti6#~R%gv2{|H~d$A#dMxo-Fdt9l5MHc~Iy0d2E+T6?d3rf4Q z$~(l9qW=qXHgxa8(8$$q{jWYx#>$h4fwCe=x!C!uOEc(p?dM3PBIVb`{!v2TzuUP> zzx1BDcI%x=VUc1Lxo`4W8ZyA6+a*`2s?M%17=baui1kXnuLXC2>o4L^LXPXnviGsP zhPM5&Y;M(Qh#Nq7)`Olb+r4u25yB|C&!o4qYU!OEe@O0#%S!OTn zs;OwSKJV>pF^=rkGk&*x|J+{g7aN?a0sRI6U5)v)%o z!68XXec^sXU7P)=AZw_gLtKagB6;)5-toEPPaO=+o7-E&arY1oazEX*zOO$04&`+7 zA7QB&WFeT^^ENOUZh}L*%GGC;P;5n81lJpMsC`Xlerb1HX$Jy%;`M^U zd{>s){o<8p#r9}h*(d&TV7wOfiECnb{R5XwTL9pW#MD{)9ezuppO$QSBOh<5_4p`C zZLIi<)vhYO-@v;y8MyuMuS09z&Q~Hj7@W{kDvD`wWY@cmuuRylY|MraxPN~21aE7N zet5+N8Aq=`LV3j1ZIcDoj_Ta>fnuLb^g^tP*!vL+mS(~Z-VQ2EjyJmmeC98#|KCZY zKMVB11EWpF(Bn`$LrT`q-L$X8;^M3=k4K(9`=X?0ZIHSG!%NYxy0Lk)RF&5Y2r6u? z<%;mxlT*Sys&D@$TIYIcA^X~|n%&eXi$QvkMmK0xHrWPWlVGVH_{F~m*xKZ?ym0|e z_=2Al+`1KN8xX+=7&cvXrrZST1e8~SQ)%!E+6vd zXP93U)Fzb*%UgXCm^^^gl3qD?_t7x>PyZBE)}Xcw<|x%;)iRHSOINQtM?smRmQVf0 zniBJhF*fmVE@j3e;!bTeh3)}nt&P=w&Jl!mkn%`2p?5X}l6)$0 zd&%RW@IGgGfo1j#b-OfNvinBCy}mb88^ou#qoC+?&nLEkPYdT3O6@x(T9-KbaP|iE zvwnu5(0hp5l*_&}5_BUERNoqVgFNiL1dcz_};Z!!AiPgzJPn}*FM*j*TzE&dZk+Q>AO9p4akMICl1FIiyTyH zH65o7IBw2 z$IBZGzJ=QRkuv)|B&oBD+Dy&a_HU`5D6Gm9@yATCWe$%uBL5ZnTRs)a)&r20bYauY6{gvujt z=Pu?Q+(_hKQ!Y(Z6L$j@mNmT)*IP9JnT~FnZ4G0$6C}>b=9wHVP%23(CyZY(_ko;Q_v+xC_hEP z0E`T_1Y<0xu5YCMfP?Q9J(U-KNX{&-8V!rM;VfDJ@ts_XGx~M3CHoP->$If#m+bx9 zTALkf$NS}=JJGo#*l_h4zG|=&h z*rd?z88rc~fa=txddO##c?U@!KL|NS*Q+m=I(7x*ny+1YY z$5(VZ8Bi(*(N!PH7bUxkJ5u<`HYNCp29MC2_Ln|CqOSjJp4A7Z#C#voKb+REg@-PV z9jVXpd}lyl4*+G!rLhMloR8U`#^%$Jw&uko6iW$?B}vw{K%8mq|6(de7j zXDexHKb+p)dU0SxTbwJDIo^F<-`sNMmQW3CDN~#Gm73$FoL4ws+8bIV`Cfhx%FN$6 z!5Xf#VY-bZpxl+ty8Y&->2IhdHz6 z-21I_)}5@%KYLZ4dTQ5i?_Jpcs$Jg>BUD#S*k!c~t|>tPb%boo+Hvk2D4E9V;7VWR zV?*+0*yg3)8)w2kPnT$_;sBzD6?s!KV!oRkzY4GjptnVKmC}^2FH1`9nH!1^UgZ5+ z=(EybN?SuH!U1kPFC*rKLMP%*nOFa+q>teVu!tOK&oft19mef-3_1Xc`@VYU!{K3y ztDeF^vJ;_Hc~X0URFLV2a8)z0m}?iTbyFtv&s~3LRT3Lby0X(CsGDCpk+BovNUr+Z z`TCCcl_H4jmq)JWIwt#f$<=dF%|X>~9h&kk&B-m0VTr>>F$A7vH8va^o5Em{d9fx*-djW^hrfV-JJC?44yXHqE!1A#y8TFy;4MfM1&FL`3`XpahPlKq#6f! zf06gq^$*C<$T>dS^dToJQLLX!Dj%0$UF=@N@!_+ka@nymnPHmNSaZO7|NCmpa5%N@ zN{IN8dXCS!WBTXnoH7^M6(zUqC>Zovf&Awba8DDVn7TRP=U5^$2a#WTgyYIh6j?2y zKg6~J?IE>;AIExxBwZv+7Blx?CNAsw-sO}p0t|6_1?v`H&6#j6jH?innWkyYEfwK( zgD4-#8I;9TVV8pGFRAD_HsZzx9nFbyfXt~xHf!iD`$3X06UCL3yI!($la0I-(~QWq zJn9GnCLPM@7h}M3(I*sh*y~PyDyyCen_s6pc%Q8bGHHI8=tyJtQqh%xIDFh0BRwH5 zL_|&?O3ZY)X$uBMm?;vM61xUE%~#K*6Evq^t0~s2IW|jHu>0wMq-QxdVJT$JXZyN3 zV>n5AQcy&XtY?sze|vKi3_Uf|BrZ!VB5s?MC&6@tQ_Q(THw!%u{c9ANdzvrY1uzLW z9sN-+AGTW1no%?+H<75F-#kW+Nk1UBM<+`el@Fvjq%2mZxTx~-bwieFdbXN`(0#oU zsBFI^xo=2WT2tc#W4~HKCI3s%4(SeKsrM0=y82`dWGJk}%<_zkJnltAPz_B;tvwu)?pvb`nspMBZ;dGx0o4}Jy}h4W zz*i!#^^W~tb9$giJ%F1&wSLt{#BOKqwIR9IIPKP*qe5I?C-Q^~g%rAbDrKrIN~QhS z;mW~GzF+P-vx`Saz;ZP(H4XK~k*5!e`GDonKvbH6AZWm9P0)?oXVdejR5oZ*< zeP3mi40C@^WA6M^Uof2C^^U6AWKX881;Q*{G$V|k)Y-*1H$B?Eovc)0kU1uy4C2DwqpMGa_H{z$A-OdG(Ytw z=$56v{f}?>^V+D5w~j+q>8pjNyc2Z;b5$jp5LiE_1aZ2|g(qg*NW*d@@!BK`Z<(r@;n--o-BVOXRLZS4KSOQ7D$_ccgu>uUIyw&}9Jtning4uj6|2ma_R%I6Y7 z{F*#`FMh9zVR4z|XzrDcpI7L5kq^%#sdwsG%j-^w2J436DH6mJOV@Q&`1h!-c zp{K|*=UsnyL(f>)2%2xjD1*I*w!4(t)=#=Up)0j~sQ$pAt(H-_wonY4 z($G00mt2g=wdGHL^_1S70L!)fee0&dB;F>k|K{U`Jd-O&3&ozo3xVPIPWr3P;y1*5 z>^o!92DL?x+3m=fAk-UkrHM{4+@FKvGoJg4)?!`RYucr$*6I7Wa{kTQz30mP;(cSr zuWC};)zDzqTacfWj;+Z_w+bJjn8cc<4zO9=s~VcrUny49s6A1*s8!E8b${bBk&4Z^ zjV{;z&hjVBjE^YH)klt`mfmeewTjNVX;Sw>E>mc>)C#4(5MD&7KQux_jy9c7OKeo!BD+#83NKbY96SM~6qg-*6K$npgPD z@O(Kwhv|e*a;R6R_uRG#zg1Olxn1*w(vr1l8-3!zw28IzY7PD6=6u?=iM0ocF64%p zcg_1&{a0%?&i0S?Ky@dJG*y4Af}6*8^u1YbUvTlSc|}7znDxf0cDYg?+)K`~sjGj8 zR1Kgr+p-;TUf;`%jql_lz5gxG{Bkq=uDwrx(O$=E*YU8Sy+;eScPm5N!guw6XlxI% zgZlNtJp=bBT95eydU>OI4dz3SN15{L<_{X0$7zc7n%G}oZ+~7DF^qcW*ujD9WP2fZ zIIYY7y2Wkz`s7^sJbs0D?fHEEm_S^PSV{rQ8y2U2Bsr%s9;ZLNd<-E!zHoLsa`aVH zIN{oEkS8J3Zcrd$#7uO0;dxf|I@$(7hP=x^k2y8+6amh0pzk?JWnJOT#&U9fG7Wn46cp9Kgkh!BAMd) zPo%&T$t2g8+6aV`oc~A;)ke^r7PWviox*T>7PX4oWbzl>7PUZoWbzl>7PX48-wA$(?5xT2!r9j z(?5y80E6Mb(?5xT5e7Pg$fV~%-u&;KrBAP$FOuAD?Je({DxL10&ek>D?jQFO0t?1R zEw`!PH;6u5>~!@o3rn{uB*z%B6&?uE^Nf-t8~3Xqm_n$C>3lR6niQ9^g&VaNjuDK} zhN`XwFm{=QmZA?f@JaSHU&H)t!L>tX zj!}LZo5o>ghvBaR(dNANr6&u8Abi%Htq7_p(N z!Mq&rLN`wFHm9Fr%Kfu}$;hTg1~-2&MU2Ldg~?7#e&pR-BQOV4h$cwSJIbqKwRn1 z#Lk>%*xQUif3q+s7U9x(8*I>Nel?YYJ!XC}4)F2|dyQv$p106<;a+Z~ivfcn^V< zgnu^IrY^ z!GC2ja~HQ}8{BY^SLhi&{N6Y8hyZgQOj$d^%Aa%K8~1m3&q#PrKY~}>tw->FdmOzm zSgSD9caySAsvvMk_e7m&IFSZ8W0%F0V#BsF}Q>N%m7h(z_0RC5eBQ9C8Y=Y7H{*N|yeK zK<+G-*$wYpF@ahMOtk{mh05n&Z3L$~0y6Xdt7$=)z|hr%TNz;K#ba(#unthLepj}M zoOJcexx*#602ltjEA#_CyvO(WvvBL10Gd2}IN47DKvv5DH_Ckbqq6K$B=~ZqKegA` z9!zyrc+r?(#rUU;NQb__Z+^l1qfNopG6Ic{A%B#8XVk(zT7h`MHzSXzK*_ZWl+ML2I;G8s}S;73NCQG*6n=FWb zR9m;ljT~NcJBcS{duqeNzI3JaUH5<^*6M6v#C+4~FZy1{`U{QKJpZS^*V?jUFv`$; z!RZqty}nwjzFIn6mB#MiUrIIo-kGdxLA`gz?B+3T#s02wzaco8iDHC&&3l*63YbuS zhc~%zRFeL=NNgKw{RZwh>-Rm(-1YFvb(kq10yEyf_O1#z+9i@g1_Z5+6Cnl*?@|RU z3(HQjI{TDV09p?AS0vxNywae1?A|6QuV?e8UBC*LDGHW!y@}4bFS^C>|VudK>pLm4r_h0mjq$Sp1zvOd;)swyqww)4SM!@)S2Gc zL1J$2B)6+zwZD6I?cngj$=|WAA82mupn?_WZDV~cL$Vf#Yw`>GxNttGO>a$kck^p0 zMx_PEQNH@>!#?nf726S8>Ct$zcEj3(5y;DYhCR?+nBi)z>X}=sw+GI6GsKa^$<`%+ z`*K6X@cP)}T_eB`0W@PxN0Mr_ChoWJQoM|VC zDD;2`ItPjZk4WT`jvW}D54urbXBk0E^w=YsF1kB4W-<9Kp@Xsl_?tOT9i4K{=X;^O z&ZXW-?)sBv>B-6BWpSccC%oEzVX}CUYfeFk)DFjt%8mEymE&~et6Y9vue_9T<@PTh zr(*scHqG=sY}!=kg``zGQ14Tx!+07US8q@SVf}W9ol}XInd}Dv2-e$&+i`&C(0bwf zGh+FmEJIfZ16RkoD_cU&hr7GskTlQytCXw7+0F7}`xf@;lIg|8huOXE)yaO;j-A!C zl-}(_GaK5LWbD&dOP89bvw}C5OLL~Tr`=(@=7l0GwN=bh4`qsS*xNfxi4JjUVrJKx zqXT*K2Zj_)36z`p_j5}rM-O&34heS7RTb)}chtmtiY<4Xm?NS%HIf-)k_F=i1)9_a ziXl%DyVD_q*)VUr!w)y3#SOz}`7Og&(+|f6x5ibDY%OZHa>7>4+%Fz%Z5UE(pC)!l z(I$8FUhn3Q)=d)T?U6jwG*hWx9huARncv=dO4G!mc)B;|3|&t3ZGQ9hq@q^9@I)Q& zGlwx)q{hg3quP9%kFk5gZ!3T9!G_{09Xx0*5Strq#vhj5K8R_d3cM57B9=zGUy6(24ZN?ruvV1xUZNcf=o3>yOk%8S~FVM6^sTo$Bz8cp=x#3$}Wlix&c573b>3Y6XUVHZC`?m4G$ID~S zR1ddIJL+xAiBD>)iziIN_BoGaI7hjr_xS;D&WAD{)on)PfnaASa zgIR6uC?I%Xt{do_j=E|g2A&8kieoPJT#!{ICOz(m+f#GW$*-?e-R2*j$R*(2Z4g$f zemqeiXqjEGq*QFo5OB7G+2rDM#IUt$V+Cdpl+Rwt>yfd6QGa8=TIks{&O26ow zKYHOX7Lt_z6~iKbr(D3$z<9dP_=ti&N#A0O?$#jbgyO2ts;)8Chjh4;2! zCYivO871P0q?FsjC^n5=6?z4RtsPszHK$ODHupEfCgn?RY+&>Kq>r2pS*T3cQvn)_ z6Q&q!8vfWQI*bI4p5*YTe1@mso=anE3lpjs=nLvFPc3rmj2d!li(_lc6JQvRM*IZq z!Bu9S0!V>l{yQ;>w-|dq*W>*vKp8eD%r7;({_(T?8-Z)9qU`}n6A45xRxdc!gX6A>&60S zW9*#myqnyMIaQ@mNx2U$&X{U zpYt*7n5w@-ohe?-Cmy}p<#Jt#I__14A3fybq8fwIWUNhfg>%@B5cRC_`=)mKuLSlK z%Zivj@t9L;wz03t@6W+3s&U31>oP&o82uCkf?9&jmSB6;W#ow%EUzi7F%{Pr&kMY; z*+8>$f|)g!lUsA@Gep;*Sc798mM+RzXIM&ieHrG>?_0fQHRz zb2C2S_ELxlhs{)(X$FIio>Y5I3}D{U=X{w@wA7WyUrzWO z9RGPqEk5?OS^#4hVO34-8&VN!Rgx8f{eq;udIGy`0|ui^f3v%Gwvl%BsK4j|wRmk6 zjr4(fm%7O}DFWMt@sam~5yx&n3%659*HTEEkIXx&d$unnR^0BXHtP-MMzI|i1bjNu znIBuo54V5nZpaR_ROjqG=nH*C`ID`&UR&URX(};By`MAa9ahB!5Ba{cLK$vPPI_W z;o(Ao%G+z6ip?Egn3A?D{H9~~)*k?3vCr0=HSsadVt+p%;?4ft_ao3M&D2N4)kuZD z$ss2dG)eL;V||XY(1N&&TDo+FzUkkYh(`K=W#XA}5VdsP3Pck_z$!^RP(?t1Qy4R$yuq9ilvHHUM3juYR;3j?qZt>P)fujKPIpC?p z0`CLra=}f61%C3@;(?<8_krN8!~+)s?h3|Dga>B#(Gr29fbb#Zt^5q$2i%p6n}`VP z>Z2tEM*-<0%3DbaE(Fq5jGKrI+~T991V;hoW6WDg3El_N)r^~n3jFkbwhoR0+9!y& zk``PDv}*`A@n!@-*KKZbDcYKoi}i4{f|V7`lsVG{da+@ z{wJe1U5zVk;8b^V>w9~Se5ZCB11yJs%LRFrhI+0+xeuh&`adI-)X!K^|EEN6I+wKH z#yJ|`o{#dZBzV*7*St3pRwH=b41b=+dgy1@`5z82^?yP1rpvRa4NbzX4pAS^IN&!b zh*y1tj&pN_Mxo~?!h6&&TK``}pz=$@(>4@YKtpf{_`i_6uq@x!R3GeUiS~5<{C4~0 z^(JlsZHn5>`}4bbLW=#%ajDSQ`TNEqtLXKPq5n<(#sP$#ziUjYk{;<8`rqVl9Hw3{ z(Qhr=#S21yy9I_1p0BR&4tje>#}1B1LHPPx9FjTB_SI7VD{S+|d#^u7&%`6{?2 z!U~n$v*4sMJduL=P8}9thN@gxv$7cXMhtaX(^IW>S*x!x->RvCj>c=7qcN)X)$Qai z+7Qaz5sbcwtV)*bh}7;H(F>bOl;|s|3XR5Fo3k!XrIfTa8CaIz&Y7Ui$Hy29OPjN< zP5m$pu?+8=hp$x$sMDV@`~9CNzvhgI70JRUhvef(B|T$YxLDrCF*Nu z$QwBi+4gr6k0O^H+g!dd8_Ez*r3$AB*`nAZj7GihTYjt%G*c*!uVfu_(MsvB!=Brf zE(5D`-af=Lzm=7Y+`T9*5Wd1zftpxpUkg`t%(iaZWIU6)>CJQ|E@%F+>)yB)km9)M zf@ra3d_>uZ%w60tGUxPKNX>BaWYea|kO9n?Y^T70`0xPSM$JwKb!Hfp4fms^-D|8&8P>b*WZ9~$gcEM{{#VV^oUMr36e)b!eU zJT0GW9oX5_zwYQf8e2Eao{l}g;@zC?^&Yzu(d?;Va;M9dxR}5nSw!3sSG`KFBnVn!V0{@8Y|=jv z~oYv(mQ004lVrLL5XrIjtUuBDCsPp`Fkl)7X$E>eJ}_nWuXx{M09 z=(73pzyXSV6KUN%*;SdV}>v5d(1#sTo3wDah` z`ZFKN+k{DfTM=1P20~ur?F@M=MGA*F+8k5`<01n$f=lZ3E3v}J(e(qK^x4J30;l&o zn={1@EVKN!^~0B$=aQm@5FI~(!-ftLks0HHm$bLkE~7mKSO#vN$2Z7(A~qU_$!C63 zuPgQ$zb=>^jCfL)WqLW&pz`dgmYT>eF(Z1uKXC7$IEZdb7NXPM`I8?6EQgPPuh+>k zR!oA9bBo3%+xTUOpMhvp*#UA6GX=LN`C!JQbfc!K<~mSwjnU!~e2S#l<(cH65ODQrmdCJa=o=+X^$|=?_Cz*`a}? z1y-X~ho~FboYuh(#jOl44rWrhz_e)c-}-^?O4Gd42Vvn&Op?+aXKNlDsZUN-^wC}U z;Y(Rq?wI8$!a*}is3fDRSUD#CCryI-dWqr8m+xJi)F&&JQE>+B>`$!=_34UwVD~69 zQ$b{bXVZCb3H0Z8t2>AP-#u?C36OC$^jh7UU#H}mV1*WBFPy^;&fU-Af zdhib9VJJO`=s1G!4a?_3Gm>e@LP4cJh4DdCIl`-CXnQs@)T%?w2|M0Un_Nhrgsa?% zw9sGit*^J<1OJoksLxF7mn-0GW(m+dsLQyNP8R5a??HZqWzQ(|1M=mvo?k!1{$S z7@8VsD#5{_Y-@Ep~puD7|V`G-Wm`T+Y5;Y zPePA^>dc$?h_b`cE%VhmlrJ0y*<2_}SD8L`Gq!6fqoa>IBAWrXg@eVwZ!p*oF*q-p zD!LX9jwY2fEYJ^*bYqwBGCq2WKQ_SYl0P#JwsNyg{S}_0eOU$un?{{q>j5yX)R(u7V#JKV0089kJPE%8hr0mTDcL9%nTQ?TGxLVb~_m|x15yv&S(1NzlRj5H(y`3Ftq~; zvU%LmcM9R_8!LKFN?j60dyTnj1Kj^nd@|_eMkeA1CednyCQ8)vUA>q`v>Q#& zX+ztQ8+??yN60$Tvi*QaO;Ujn5;jM8GM2@sBlp7Z51?UdE-^#NMTdFWk&xUH&WDQF1gdMZw%+pEteola`JQ z&`3<{7ROc|8-K*l^$%knq9zHzLu~uyr4?Hu5AM%1`wWYE$YsNd-h-d+N4<5DNx!a8 zA%4o|V_JlkwJF0QBle`;Q8O%R2G^F>A@7>UBjkIm_^`is>hDmHuu)bl9If;ur*1c6tg#`y&uTuxNY{R~#$JQa-R(2@PzQ${d7JrtT4 zUBS-CNWdvQ4VrrT4da9{_x?C8&^LoXwcdohN4j(*8E^>>ok*S)=h2r8tUIH1CG6smf&^&(1KV`qZ# z!|S=yGT$Tsq{@V-!Wxc)(a0t;D_>-RFA`v&NWGj@?cUaj|trfbrUx!)h`Dm$@3K@ERy@_d}2Tx_{DY6LgU3`D87!?<9>ZzxuDI@Tq)7F z4}x_KHLDjTZEN=wE^|_n;|m5}#PNDu7(=M{{CM@O1;o7>??0AX3+%r@^J$t@saTky z(#@wmRiF!FU?}>?}Ciax)uFNGiqe0To_p6f;*ZI}-&*v`5nYyBuR}q3$3|$!8-T zmj_+9vklAYBA-@A2#|aqey<>0cTg6(du1w`lncR9_!CzoKVZFREH08yBKaewbpixu z>+GEiGau~L!BPuieT-Jst;z&LxR5|lmZ35l^u80`ET@gx(KEZ}25bd;y?{=3$@Qoyq)x1v!-t=ufcI0?A}R zpW71`g|MA*WJuwN#1}S;Qqt#pA|xIqRk42bElb=a9{P(EDp%2w&ZGWELaR@o#H7vW zNs@d`6X*n`icC4E9drY;UC!ls%?#OP${}1P@9<)CF2u)e0S#nipNC=27C2IC^TS)B z*bfjuuvGflCXrf!9>Gxv)WAQD?6Jrc3txhh<-44S7kvgT7_{RZ4h{6Dw{PV0c1~D| zCEyL=@_~oswVE*bP#wg|gpJ}%4H7NH@rEx0%_~G4|K`7lOi&Gmo1t`E1a45N&*-9MX?G2!2r1NHGd_rJZlNh+@J)y;uxMD==xa?)h&Xg_aGG14`EVC5L!v-&xeAq z(BnVc!*m~?>Ahzn@4-rxIY`b8VW2YdB7NdZN3N4m^}m6$+3H?U5b}h>x`YwzDt@{Kxr&%|d3y!|q&yb3!Q`D)lK63%2|1$5#Yd+oM|$*ORZ9x3a*14PQH|GGrb+Pl zgjf31%bZ7+FNbn}H~`cZFJ0K6%3ABF7=|r>BN6dS_8|o(o9-grvEGl77xiH{xqv42 z_=UMAEdig%;bLuRl&N8-MU;`dJlnGo9&ub0-?D-G1(a=eax)OX36xx9fxWe$?z~mQ zg|R59%R>2RWhofegNAYgV%qQ-bTG1zU$!(y8=m;S*31 zWtL#2%weKY7}Z;oJxcngbb>=nBJzfA5$N%$cD5t(TC||#8UnlH>oM6sf1l=t*SljL zuGf0O;oWu^cn-oXPs7zhB~V-Kq%%KVYVHijWN(0ShYP5xjYbpCiBedq6{f zM5{3a6o(i~L~EhG;#6x8S&u4|b7Ys?HA1&fDoYZN{WZiGN=@4?45+Gvt~7nS&{*3} zHBLq6thZ)GvisH-7K90MOkg)iVB(7#4STEU14shp#!i`{WvW{em- zP;i3P1Zr4O^pG5`EY0?!=!6aSl6UCcujtWNKW&9C;(P>oi-$f^L+iF!kMzjE^JVK6 zTTFev=bRLK-R2jEks`&f_Huh$9K0|zv|!>uUk}x406ny8$yv@K)gG<8SWc$xCbzS8 zb=FVZ|GppAM`KS%OBCZx%P=|XbUpYy@L=HJA^f84Xl6&$2a`>+{dgMoVtdko6 zbNaGv*}zf1wzH;bF^cB<)zH-=8)=)1{_>}Z0Y@A`&1U84@Z}B#48|T3n3XH`i|LQO z2zMSST{{-j(Ih#DE`&;e&i%Vg;=4-vkkE~IzLY5f3CWcTvWr?{!C{7rugTv%nU6g= z7w`ZJTon$a;8wr9JljEfnt%I10!7SGiTL%__&mc&sbx;9WA5P^vqjuKGxuvNidSjF z0*>EUfnl6RMb}$yRCq(=*2gX?RTv zJtrbBpP3V4NcN*9Y$S1Nwaz@mGy6-im`p#GIebkgKSIV4UCN`8Gfn`Pza2V>?PWkq zKNd%0O!t{Omfd0tgz)gdFA=;@DYT#AIoZa0U#uByeJWcA6CohPSWjzwqt@r-z63dW z_@4G2U@prl z2slI=`~@-=D4vQ(DqO8xjrS!WLvAILR}R+H+&sHkGs~ap{zo-5<*9Z>Ai0V{<<&u` zi)oAGX0Xlm)D1a$o|?i*_L>oA7L(9R`xUwI^~S)V1%qih!p9{j)eHGY57f@(SyA-X zu)ao;j#E+A(AqCwI2&LXZNwBR^OQ3@I7nn-lH*8|WMRq4Gi0eBDZ`|Vc|T`7`cW2~ zO19m^$U~3`yQqB4x&?o-=gM(MnHNJ=D@NUmMovhUe7@l%@k9`i#w&K2c2#4aG;k4X zH!fIKYK?Zpy45w+V6C#rZ5`6t!F8Sm8`@c^P*ss6P!}rG5M8e0FUv9ux|6QkD0b2< z;8+-Ai&rGH&NDe@3?!_+#HK7t z#o(ojItkeDS!fm}QAb1o=v-d2g%NwAeFV%7xHA^#4Aj}vQdRr2c1hE>dIFNwV1Z@G zFHBU<%5GVsL0nt0(?~o1ol}%@wYt9W6_+5^AQhjOA}}nqRhk;0?_9ep?PuJU zMUt0WH{#Lj`Y^EGcN8OGVe=V0Y*Bj12Mxun{h(fvs%;}R7Q@}SEy5#f>+|n;kL&x5!^|&kkY%ovMum?ti?Nig;=QnKYg>nO(p-mgr2xHhw zJ977;cB4aWD3{!W(Gw3j%W~)JTo>67^j{ciWumEeIrn0jdSyu9^lfwo)a{WG4&6nr zR3L3?@)~op>W2~$UNC0&$XZ-kO}btAr0#()9#0PoGmJk-d{Igri(bd&%rq!dmR0Ok z17&O1I>AE}@0q|f{=PfANK$}}g$HcmV8i~&u20L0i(iW7)AiRi;0jB0pgD-MTcMpQ zLzMg?Wkpay_p}=^AT?i|)PD7cT{ttg$rt2c5s24iLVoi74e%WV z99r`ZA3Xh%?Ox^Mbqwcd4VX=e*Plnej6Wi0>>WO81njT|-PCYs9)iNxW3$j3u5QR1 zTgYM|u(ak=P3~`^xo%n2fRzp#|P4XFpnO|S;VHI#$N-Z6~3L@pfZu-MpcOq8<)>4hx3S6Lb zSq0-l!(5ESk+P#aH1mDtHd`??b;+n^WK-t=Sh@* zz(NOhEu)b+uPM5MhlY64}JsyFmU=uOTqUCek}#vK|DyPJ)dK{caAD25GQ5o`hRn+&IMe)2niZTHk<>KouPUQ@$cdn;%;cy|Xi#={y6{;4*eWz^*<)Phn*@(|FV7LXu%t~+L3v!=*%Swrq z_p&eqhY$JkEjpc(K<{hy{j|4|c04W<+;84DnX#6U&WC*^Xa2 z&SH|^yja6#So$Eui*zU=2i_h5CYux8h46k;Zuqoy>!gs(y&5!_#C~rE>J>ei!zsMy zJ{XsBUg5C^vx=W@B;g!5HU3l$b-IM|Vt; zQEvsc#>|*$-IJnay86?#jqMHMp2@9qyt|ru9-v2yr#`zH=BPWS+`gm_yQ=1@D9D?w zZ{M4Ti>P*`VJhR5hoeu9Imk?kgG2uM*LEdX4IckVodrY!%#DTMg6?$APcu^)wN}&u zi(!_!>re|ta;Qf!SvZ?4lr%BPFIa5sm#gXzew<$anE62N1j{6H;`vT*u>~4B11$jDJB!RR~?z#O8FFtM^Y6pXTR`F6K>%x zXdmlA)4vDS6|-f!uo&c#015%zJL!e3badue!U}>q*-3&Jv*x&Q+L z&27MvKi`tNre3W{WI)oqaXdhwv~*^EJ4|Zs>aD8s$ZKl!|^Dq;Z@%H z#|b|rW242I!O(yJK1R0VIS*!oI?@LL7t0Q@bG6G4F2pY_T@DO=sUR@4cr3AQ_$^7k z)z87wzBQ0x-Mo84lVr0xXy-+g-UNcCgd9cXx(fR4(T`Z6#JV~WnkNTTG z<~5CK>G*i9hW*@9&G=EsOjxU`U6t7K3{)u^7v1tEw;qp}w)kLMA2^iS^0YOPvc<(6 zOuT9c0`wXhOV3wr*u%EIXh;y^UAL_5W;1qIz4@mb!qb@&*7wSodoa9&Ag2e58C2o8 zw|4_&!I?xPS@TaIeKwLZ{w|5G;Bc)C z4N5KMY|z`7?_#iJXyseOtNW0dD5MHQTgO!H;bK8&NB%6JfBd2lEOS; z!5#Q!4)OhLfGoEt_aMrum$Y-cn}z#mj(A{MPF386;OE^8}ygWZ;xDK7B8d z-J#fK#@U>CMvtJ)to+J)9|b!|J2ekq+O#T$xyRQGk)y5(WYf1eF$o*uHTbRo?zH4RjMPD2pL-b!sr(wd`qni&M(I-4Pb= z#Yg1{7hZ#0W@|+Wk~4+cwLHS>ym@!!d)xN4R2ymhcy3-E ze6a;{rzE+ERz8BjUf}2QneN+!U%fh%8ne$^jledD5k`{U;un~VCJK>Gce}Dv?_KDa z+%v=4?J#6VN@0b=rF(Hh`jPB;tKT)y6O(RREx@>lt#i zYL0digk+JB@djj&@sR*=*Q&?a%YB=_A-taYu)09#M#&;!qXB_V-kuNeITg4M9p;0_ zD*)VwcF+wL6yAO=`Efu)XmcYnWf;y5MXxWtKDGu3MGJ_Vauq<#5`YaK^{3R4pub-% z37L0SP@#PYkLh6owSqti8vVGzlEm_{(75bT^n4pEW5^L%?iK&j$)@cjV@dv)xk!cf ze66U|D!PNmJjp>uKB=Y___!3#X4r=E0f7i)y-eqtK8cdI^J6Z6#6G0a2hS=mFXY6m zCj2|S83cm`)>7HjA4p}4ft*+*{gCN-D50Ng3yvV$$OYLSvzMbb;b^XVsq(j|=kv}i zlgr2E09|Wr7sV)R?|ks7^UGW7^IA%^+Aty$k{~CTd0=$~$;rI-1%PqtW$qF6r0nn) zPFFz75TZKfPDw*O5gi8C_}M)~`DcIJLXzx1&_nN1yx4qQC!(0(wkk0a0U$H$83PCD z>KC0ltEO(yL(c3$-|WqAET~ZpjY7>%fAOBx(o*gA$ARM>DrYtIPD=G~Y)$15HC;Hc z?ieQXUK=RRTTgTKTdM!oMn0qB*`YdG^b9Uc5|^-=FiXNNp}!3myU~d=T}?b~`sZ+` z#-Ms);2TGSq;BP)7Y|1GvlV6yxda2Y-pU2 z{sfzNTw8{5?UfDk<@E5bLE{>&Yz*PHXKm{YDE8LJdXCCi7>~3G?UE!J<9Xm5(z3$R zBIDkgZ-2Fc@OE!MWn9fHU33Cmc&jZi^+YxrbDesR^dcp<_| zV+ZbAJFlYQ2^)_Pq(Z{rEqU{yPQ%6!<1v%tF@?8fl)!yfG4wtniw5W}Ca2qQ(4!>m zUP>QYkWT`}ECS}KnYnRo%NnNHF`@>p4#S%>{j%`|uG{N~6Cba4DPIv{R4%XT`I~O6 zNLG)EV~`fuAQ3LrHt-Nn4yyMjUx%FZ!lQp^i<|gLhK4+ zrW6BpCnd~7n(~6nWq4rvN76lfDXoA^4&F4h+P%}ttgRo+^;E+#(WIUP*M!`++hN^@ zPQ(-~`8|NpQ+?voZFLKZQ)NO6nWj$jJQtLKFw%RT@2Wh2*e#<X@wr@n4;FuEBmrpN@-M7t`vj9my!nVcaaUfN?3gvO6Dm)i=~PPk75vD z=IbG)7+T&HGVUs`>|4L{^k_F%rU1M#xt>^2ni>7PlL+UKNoK9~UEeo_HY6RQn}E_- zLFo#3KnSe`qCCR@=jC;=`M%J8akGs8UZ(P)|aYaG{Tw7Dj?KFq^c_W zATafy)T%CKN&Bc7L#{z8hXCFa1|wLE(JMJbp_yIACVj=O(ORxM&oEm#A%l=4xr1a- zN9!6q0YN1Z{}5ZfemN2P9*+IqzFSYkH?Q3KtWp@$Wc~gib4yGc*Yooh)xDba+O4($ zzYf>rOg(TWVy@+j)M~dY?ZtWp|0!h_TQX!%wzpJvGu<6ll>!ewDxt*I(^y&19Q({02m7L zHQiuBH-ugb`=fH3%n$(>&`~j{U{^H;zvV`gyV9!9kWbgonW4H^*);fj`{=i*u|@zJ_ou;%zRoy?f5IA}9k?{t`Qo@!4GFl5B2A zRUI*JpwE&`w!FAL`=FA9G-ZBzkC*O~($Yg}Atc(he%9!jf8&vm*qs?{x{umrbs)vD zCmfq$yKM8TWS;(y={=SsW{GL2tLx2dRLO}}pr7dYG2{N&d2hS;yKesXyC#03^ZwF&0Ldhi5E^XO%N^97a%Bt9(c+;jw&?#uuDZ6T!RXcfZoMu&iAh)xF`{Ble z&t7ziM@D$J_$B@2FFgeBwpSgytTwi>=5)=gh{SCkcCNnEY||6Mb4H~Z4eGS=k|$;s zUuH7OW1u#4j zAEhgaU?cCp%8h}1ki3d&1bpy`V#LbtI0&M8OY$ZiS)%$mf{>h;4EiR!17g0@Dp@)u z?ZhPFq9GGiw3)KQ-87bMHrSlgnDltTN_N4ASOWzmc_U3;N3wB|Q643;w_ohpoAL*> zV)dbvl=!#@-0erdTVxPA(r$K3DVJn+<(iG$a!bVYwVLd@+~v!jgnBSHFkkB>YttQ@ ze#%gY{bo&F!o<2eK@7X_%ClWr6#}<4<`=>)CdVh}>~Ve>bh}uV;`ioExvLWI}7dSx4G2`gEH%$zG2>_s<(@D3V+*Ipdme8Mp-(}%I$%E`Qqq|D4$mGZfXhN&D_B$r?n(Bx#QwN<1G4OUhupE51DJ^vad6f zIljswk+IQIl6$l(uR(@acJa82U%cXdmRt+s!KkG#9#bnGUZ-{Eeegnqq}9W6v{T7# zJy#qQL39!3^0ka|S6`lFMr^BZcytQv-opRg#a`cphefl(qPJ~|k6>|pP~XbYzOcKN z)Y~VLx%+ly>T+e}UDt3)|7aM0IsdVZGrP1gc92tD8GeV^Y0y*Ic|)V4z)tw??W9;_ zBK#+I;M}0P;e*H4F-O*J<~gf1POwT6oqE?e|GY>0S_&<$^`0iPPxz>H{;#&~2KC3S zHd}R{s4Th0Am^m%)_7)6zPK1Y;NG2m!8d(kr$bFg{P6zcCcT5}M;~l4^Yw`wDNg7= zBc$GoVR3vriWlX7TN`>y)U;z_V)d~Y6~TB*>b{aB^FPBoPcL&DF*#|vBg=R+L% zNe$5mx8WWhL^PB+uP)^EDHp4szyIU6UUwf39LhYRdqXXr)uFqqZRLn=m}f9By|H}^h^OVW2(;jL8@?cF>P$JKWTGiThsee}7fr&?sfv3C7bQd(rA>mr7Y zi+!`nn|MXd_bE5CIl%^BF@+mj3)9D!rM?)O-%Ia~QhQMpQbp#r_w=Va2C0ba#TCoQ zPio6OUfv0g-}m;?DBmt?i%NP`m*UQi4qIEY19ATrSyqnos}O+oMFAQ9sU-r!S+U?mxAFrjPQ_P`YQTLW;4p^X#J2$+Bn5aq{}*gih~ zK&YcSbKuRdptm6)8R95PfQzL}A1-I0C<{Gw!m`Nz>{K}bBZD-Dm!%F;9u_!*BK&f5 zQ@qK96l*e+WP}c z!N@{cgtAhpg8HWm5u~&ap2P(KFc6hRIQ>oqwC7v~vS_oS_4{6!f{}%?2xZB}=@0kO z5TsiVj#gV53`AuS&gZU;zZVnB8m@pT7+ENbP!{%C*Z7n-b_oWevIr9d_F>WZOe|`G zDHvIECkX64WAL*2nqeR+i!ec8Z@Pk)W%2>0U}VjmAh7=pfR|;4kceg?VS>Qg>G84# z=fM<=tho~e)=w^R;Y-_)CJEyqpYi0w`2}l#1_=ez?6tAoKUvUW0M^!t2Q=xRUkLV0 z!vO5XK>Qhn)fXsWmKPKzU{}T@7Y(J&X~{I<(D|Wp@vUDbGQ8u4;$H#> Dict[str, Any]: + +def parse_sankeymatic_txt(filepath: Union[str, Path]) -> Dict[str, Any]: """ Parse the sankeymatic.txt file to extract the hierarchical structure. Returns a dict with 'revenue' and 'spending' tier-1 categories and their totals. """ - with open(filepath, 'r') as f: + path = Path(filepath) + with path.open('r') as f: content = f.read() result = { @@ -114,12 +118,13 @@ def parse_sankeymatic_txt(filepath: str) -> Dict[str, Any]: return result -def load_excel_data(filepath: str) -> Dict[str, pd.DataFrame]: +def load_excel_data(filepath: Union[str, Path]) -> Dict[str, pd.DataFrame]: """Load all relevant sheets from the Excel file.""" + path = Path(filepath) return { - 'income_tier2': pd.read_excel(filepath, sheet_name='Income Tier 2'), - 'expense_tier2': pd.read_excel(filepath, sheet_name='Expense Tier 2'), - 'expense_tier3': pd.read_excel(filepath, sheet_name='Expesnse Tier 3') + 'income_tier2': pd.read_excel(path, sheet_name='Income Tier 2'), + 'expense_tier2': pd.read_excel(path, sheet_name='Expense Tier 2'), + 'expense_tier3': pd.read_excel(path, sheet_name='Expesnse Tier 3') } @@ -276,6 +281,85 @@ def build_spending_structure(sankey_data: Dict, excel_data: Dict) -> Dict[str, A return spending_root +CATEGORY_RENAMES = { + 'Non Levy Operation': 'Non-Levy Operation', + 'Non Levy Operation': 'Non-Levy Operation', + 'Non Levy Operation': 'Non-Levy Operation', + 'Non Program Revenues': 'Non-Program Revenues', + 'Non Program Revenues': 'Non-Program Revenues', +} + + +def normalize_category_name(value: Any) -> str: + if not isinstance(value, str): + return str(value).strip() + normalized = value.replace('\xa0', ' ').strip() + normalized = re.sub(r'\s+', ' ', normalized) + return CATEGORY_RENAMES.get(normalized, normalized) + + +def prepare_operating_dataframe( + df: pd.DataFrame, + value_column: str, + *, + drop_revenue_rows: bool = False, +) -> pd.DataFrame: + working = df.copy() + working = working.dropna(subset=['Name', 'Category']) + working[value_column] = pd.to_numeric(working[value_column], errors='coerce') + working = working.dropna(subset=[value_column]) + working['Category'] = working['Category'].apply(normalize_category_name) + working['Name'] = working['Name'].astype(str).str.strip() + if drop_revenue_rows: + revenue_mask = working['Category'].str.contains('revenue', case=False, na=False) + working = working[~revenue_mask] + working = working[working['Name'] != '-'] + working = working.rename(columns={value_column: 'value_m'}) + return working[['Category', 'Name', 'value_m']] + + +def build_hierarchy_from_dataframe(df: pd.DataFrame, root_name: str) -> Dict[str, Any]: + if df.empty: + return {'name': root_name, 'children': []} + + grouped_nodes = [] + for category, group in df.groupby('Category'): + group_sorted = group.sort_values('value_m', ascending=False) + children = [ + { + 'name': f"{category} → {row['Name']}", + 'amount': float(row['value_m']) / 1000, + } + for _, row in group_sorted.iterrows() + ] + total = float(group['value_m'].sum()) + grouped_nodes.append((category, total, children)) + + grouped_nodes.sort(key=lambda item: item[1], reverse=True) + + return { + 'name': root_name, + 'children': [ + {'name': category, 'children': children} + for category, _, children in grouped_nodes + ], + } + + +def build_operating_revenue_structure(revenue_df: pd.DataFrame) -> Tuple[Dict[str, Any], float]: + prepared = prepare_operating_dataframe(revenue_df, '2024 ($Ms)') + structure = build_hierarchy_from_dataframe(prepared, 'Revenue') + total_billion = prepared['value_m'].sum() / 1000 + return structure, total_billion + + +def build_operating_spending_structure(expense_df: pd.DataFrame) -> Tuple[Dict[str, Any], float]: + prepared = prepare_operating_dataframe(expense_df, '2024 ($M)', drop_revenue_rows=True) + structure = build_hierarchy_from_dataframe(prepared, 'Spending') + total_billion = prepared['value_m'].sum() / 1000 + return structure, total_billion + + def calculate_totals(sankey_data: Dict) -> Dict[str, float]: """Calculate total revenue and spending from tier-1 items.""" revenue_total = sum(item['amount'] for item in sankey_data['revenue_tier1']) / 1000 @@ -381,23 +465,30 @@ def generate_summary( return summary +def load_operating_excel_data(filepath: Union[str, Path]) -> Dict[str, pd.DataFrame]: + path = Path(filepath) + return { + 'revenues': pd.read_excel(path, sheet_name='RevenuesT2_Sankey'), + 'expenses': pd.read_excel(path, sheet_name='ExpensesT2_Sankey'), + } -def main(): - """Main conversion function.""" - print("Starting Toronto sankey conversion...") - # Parse sankeymatic.txt +def process_legacy_dataset( + *, + sankeymatic_file: Path, + excel_path: Path, + output_dir: Path, +) -> None: + print("Starting Toronto legacy sankey conversion...") print("Parsing sankeymatic.txt...") - sankey_data = parse_sankeymatic_txt('2024_sankeymatic.txt') + sankey_data = parse_sankeymatic_txt(sankeymatic_file) print(f" Found {len(sankey_data['revenue_tier1'])} revenue tier-1 categories") print(f" Found {len(sankey_data['spending_tier1'])} spending tier-1 categories") - # Load Excel data print("\nLoading Excel data...") - excel_data = load_excel_data('City_of_Toronto_2024_Actuals - Cleaned.xlsx') + excel_data = load_excel_data(excel_path) print(" Excel data loaded successfully") - # Build structures print("\nBuilding revenue structure...") revenue_data = build_revenue_structure(sankey_data, excel_data) print(f" Built {len(revenue_data['children'])} revenue categories") @@ -406,7 +497,6 @@ def main(): spending_data = build_spending_structure(sankey_data, excel_data) print(f" Built {len(spending_data['children'])} spending categories") - # Calculate totals print("\nCalculating totals...") totals = calculate_totals(sankey_data) print(f" Total: ${totals['total']:.3f}B") @@ -419,7 +509,6 @@ def main(): jurisdiction_name = 'Toronto' financial_year = '2024' - # Build final JSON structure final_json = { 'total': totals['total'], 'spending': totals['spending'], @@ -447,14 +536,98 @@ def main(): 'property_tax_revenue': property_tax_total, }) - # Create output directory - import os - os.makedirs('data/toronto', exist_ok=True) + output_dir.mkdir(parents=True, exist_ok=True) + sankey_path = output_dir / 'sankey.json' + print(f"\nSaving to {sankey_path}...") + with sankey_path.open('w') as f: + json.dump(final_json, f, indent=2) + + summary = generate_summary( + totals, + spending_data, + revenue_data, + population=population, + total_employees=total_employees, + source_url=source_url, + name=jurisdiction_name, + financial_year=financial_year, + ) + + summary_path = output_dir / 'summary.json' + print(f"Saving to {summary_path}...") + with summary_path.open('w') as f: + json.dump(summary, f, indent=2) + + print("✓ Legacy conversion complete!") + print(f"Output saved to: {sankey_path}") + print(f"File size: {sankey_path.stat().st_size / 1024:.1f} KB") + + +def process_operating_dataset( + *, + excel_path: Path, + output_dir: Path, +) -> None: + print("Starting Toronto operating-budget conversion...") + print("Loading operating budget Excel data...") + excel_data = load_operating_excel_data(excel_path) + print(" Excel data loaded successfully") + + print("\nBuilding revenue structure from operating data...") + revenue_data, revenue_total = build_operating_revenue_structure(excel_data['revenues']) + print(f" Built {len(revenue_data['children'])} revenue categories") + + print("\nBuilding spending structure from operating data...") + spending_data, spending_total = build_operating_spending_structure(excel_data['expenses']) + print(f" Built {len(spending_data['children'])} spending categories") + + totals = { + 'total': revenue_total, + 'revenue': revenue_total, + 'spending': spending_total, + } + + print("\nCalculated totals from operating budget:") + print(f" Revenue: ${revenue_total:.3f}B") + print(f" Spending: ${spending_total:.3f}B") + + population = 2_930_000 + total_employees = 44_000 + source_url = 'https://docs.google.com/spreadsheets/d/1nbUIUaV75xoTXwj6MvtV3pw4vmw1yb-b/edit?usp=sharing' + jurisdiction_name = 'Toronto Operating Budget' + financial_year = '2024 Operating Budget' - # Save to file - output_path = 'data/toronto/sankey.json' - print(f"\nSaving to {output_path}...") - with open(output_path, 'w') as f: + final_json = { + 'total': totals['total'], + 'spending': totals['spending'], + 'revenue': totals['revenue'], + 'spending_data': spending_data, + 'revenue_data': revenue_data + } + + budget_balance = totals['revenue'] - totals['spending'] + property_tax_node = next( + (child for child in revenue_data['children'] if child['name'] == 'Property taxes & taxation from other governments'), + None, + ) + property_tax_total = sum_node(property_tax_node) if property_tax_node else 0.0 + per_capita_spending = (totals['spending'] * 1_000_000_000) / population + property_tax_per_capita = ( + (property_tax_total * 1_000_000_000) / population if property_tax_total else None + ) + + final_json.update({ + 'population': population, + 'budget_balance': budget_balance, + 'per_capita_spending': round(per_capita_spending) if per_capita_spending else None, + 'property_tax_per_capita': round(property_tax_per_capita) if property_tax_per_capita else None, + 'property_tax_revenue': property_tax_total, + }) + + output_dir.mkdir(parents=True, exist_ok=True) + sankey_path = output_dir / 'sankey.json' + print(f"\nSaving to {sankey_path}...") + with sankey_path.open('w') as f: json.dump(final_json, f, indent=2) summary = generate_summary( @@ -468,14 +641,67 @@ def main(): financial_year=financial_year, ) - summary_path = 'data/toronto/summary.json' + summary_path = output_dir / 'summary.json' print(f"Saving to {summary_path}...") - with open(summary_path, 'w') as f: + with summary_path.open('w') as f: json.dump(summary, f, indent=2) - print("✓ Conversion complete!") - print(f"\nOutput saved to: {output_path}") - print(f"File size: {os.path.getsize(output_path) / 1024:.1f} KB") + print("✓ Operating budget conversion complete!") + print(f"Output saved to: {sankey_path}") + print(f"File size: {sankey_path.stat().st_size / 1024:.1f} KB") + + +def main(): + parser = argparse.ArgumentParser(description="Convert Toronto financial data into Sankey JSON.") + parser.add_argument( + '--dataset', + choices=['legacy', 'operating'], + default='legacy', + help="Select which dataset to process (default: legacy).", + ) + parser.add_argument( + '--output-dir', + type=Path, + help="Override the output directory (defaults to data/toronto or data/toronto-operating).", + ) + parser.add_argument( + '--sankeymatic-file', + type=Path, + default=REPO_ROOT / 'tmp' / '2024_sankeymatic.txt', + help="Path to the sankeymatic.txt file for the legacy dataset.", + ) + parser.add_argument( + '--legacy-excel', + type=Path, + default=REPO_ROOT / 'tmp' / 'City_of_Toronto_2024_Actuals - Cleaned.xlsx', + help="Path to the legacy Excel file.", + ) + parser.add_argument( + '--operating-excel', + type=Path, + default=REPO_ROOT / 'data' / 'toronto' / '2024 City of Toronto Budget Summary (Operating).xlsx', + help="Path to the operating budget Excel file.", + ) + + args = parser.parse_args() + + if args.output_dir: + output_dir = args.output_dir + else: + default_subdir = 'toronto' if args.dataset == 'legacy' else 'toronto-operating' + output_dir = REPO_ROOT / 'data' / default_subdir + + if args.dataset == 'legacy': + process_legacy_dataset( + sankeymatic_file=args.sankeymatic_file, + excel_path=args.legacy_excel, + output_dir=output_dir, + ) + else: + process_operating_dataset( + excel_path=args.operating_excel, + output_dir=output_dir, + ) if __name__ == '__main__': diff --git a/data/toronto/summary.json b/data/toronto/summary.json index c2a93d0f..1f127422 100644 --- a/data/toronto/summary.json +++ b/data/toronto/summary.json @@ -89,5 +89,5 @@ "percentageFormatted": "1.4%" } ], - "generatedAt": "2025-10-21T22:57:13Z" + "generatedAt": "2025-11-11T19:19:43Z" } diff --git a/src/components/MainLayout/index.tsx b/src/components/MainLayout/index.tsx index 25e06036..05c9428b 100644 --- a/src/components/MainLayout/index.tsx +++ b/src/components/MainLayout/index.tsx @@ -129,6 +129,14 @@ export const MainLayout = ({ children }: { children: React.ReactNode }) => { Toronto + + + Toronto (Operating) + +