From 1b66a52d99e422697104ba3a32dc89c24a574612 Mon Sep 17 00:00:00 2001 From: Amir Zouerami <53701884+Amir-Zouerami@users.noreply.github.com> Date: Sun, 15 Jun 2025 23:35:18 +0330 Subject: [PATCH 1/4] V2.0: initial commit for v2.0. This commit is the first implementation of the v2.0. This release contains major overhaul and breaking changes, especially in the design. --- .github/workflows/deno.yml | 51 ----- .github/workflows/test.yml | 43 +++++ .gitignore | 21 ++- LICENSE | 2 +- RATELIMITER.svg | 14 -- README.md | 123 +------------ deno.jsonc | 27 +++ grammy-ratelimiter-cover.png | Bin 0 -> 463120 bytes mod.ts | 26 +++ package.json | 56 ++++++ src/README.md | 3 - src/core/builder.ts | 192 +++++++++++++++++++ src/core/middleware.ts | 82 +++++++++ src/core/rule.ts | 68 +++++++ src/lib/event_emitter.ts | 72 ++++++++ src/memoryStore.ts | 18 -- src/mod.ts | 1 - src/platform.deno.ts | 2 +- src/platform.node.ts | 8 +- src/rateLimiter.ts | 57 ------ src/redisStore.ts | 20 -- src/stores/memory.ts | 157 ++++++++++++++++ src/stores/redis.ts | 132 +++++++++++++ src/strategies/fixed_window.ts | 39 ++++ src/strategies/token_bucket.ts | 117 ++++++++++++ src/types.ts | 163 ++++++++++++++++ src/typesAndDefaults.ts | 88 --------- storages.ts | 10 + tests/core.test.ts | 328 +++++++++++++++++++++++++++++++++ tsconfig.json | 13 ++ 30 files changed, 1560 insertions(+), 373 deletions(-) delete mode 100644 .github/workflows/deno.yml create mode 100644 .github/workflows/test.yml delete mode 100644 RATELIMITER.svg create mode 100644 deno.jsonc create mode 100644 grammy-ratelimiter-cover.png create mode 100644 mod.ts create mode 100644 package.json delete mode 100644 src/README.md create mode 100644 src/core/builder.ts create mode 100644 src/core/middleware.ts create mode 100644 src/core/rule.ts create mode 100644 src/lib/event_emitter.ts delete mode 100644 src/memoryStore.ts delete mode 100644 src/mod.ts delete mode 100644 src/rateLimiter.ts delete mode 100644 src/redisStore.ts create mode 100644 src/stores/memory.ts create mode 100644 src/stores/redis.ts create mode 100644 src/strategies/fixed_window.ts create mode 100644 src/strategies/token_bucket.ts create mode 100644 src/types.ts delete mode 100644 src/typesAndDefaults.ts create mode 100644 storages.ts create mode 100644 tests/core.test.ts create mode 100644 tsconfig.json diff --git a/.github/workflows/deno.yml b/.github/workflows/deno.yml deleted file mode 100644 index d53a2b9..0000000 --- a/.github/workflows/deno.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow will install Deno and run tests across stable and canary builds on Windows, Ubuntu and macOS. -# For more information see: https://github.com/denoland/setup-deno - -name: Deno - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - test: - runs-on: ${{ matrix.os }} # runs a test on Ubuntu, Windows and macOS - - strategy: - matrix: - os: [macOS-latest, windows-latest, ubuntu-latest] - - steps: - - name: Setup repo - uses: actions/checkout@v2 - - - name: Setup Deno - uses: denoland/setup-deno@v1 - with: - deno-version: v1.x - - - name: Format Files - run: deno fmt - working-directory: src - - - name: Run linter - run: deno lint - working-directory: src - - - # Currently we have no dependencies - # - name: Cache dependencies - # run: deno cache deps.ts - # working-directory: src - - # Currently we have no need for testing - # - name: Run tests - # run: deno test -A --unstable - # working-directory: src diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..60899a5 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,43 @@ +name: Test and Build + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Deno + uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + + - name: Check formatting + run: deno fmt --check + + - name: Run linter + run: deno lint + + - name: Run Deno tests + run: deno test --allow-net + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install Node.js dependencies + run: npm install + + - name: Build for Node.js + run: npm run build + + - name: Run Node.js tests + run: node --test dist/tests/ diff --git a/.gitignore b/.gitignore index b9cd518..afb4dd3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,21 @@ -/.idea/ +# Build output +dist/ +storages.js +storages.d.ts + +# Node.js node_modules/ package-lock.json -*.tsbuildinfo +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Deno +deno.lock + +# Editor .vscode/ -node-compatible/out/ + +# OS +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/LICENSE b/LICENSE index dd9284f..95911c2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022-2024 Amir Zouerami +Copyright (c) 2022-2025 Amir Zouerami Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/RATELIMITER.svg b/RATELIMITER.svg deleted file mode 100644 index b4b2317..0000000 --- a/RATELIMITER.svg +++ /dev/null @@ -1,14 +0,0 @@ - \ No newline at end of file diff --git a/README.md b/README.md index dd5ecc9..abcc3b8 100644 --- a/README.md +++ b/README.md @@ -1,127 +1,22 @@ -[](https://github.com/Amir-Zouerami/ratelimiter/actions/workflows/deno.yml) +[](https://github.com/Amir-Zouerami/ratelimiter/actions/workflows/test.yml) -# ratelimiter +# Rate Limit Users (`ratelimiter`) + +`ratelimiter` is an advanced and flexible middleware for the grammY framework, designed to protect Telegram bots from spam and resource abuse.
-## ❓ What does it do? -**** -🔌 [ratelimiter](https://github.com/grammyjs/ratelimiter) is a rate-limiting middleware for Telegram bots made with [grammY](https://grammy.dev/) or [Telegraf](https://github.com/telegraf/telegraf) bot frameworks. It rate limits users and stop them from spamming requests to your bot. You should note that this package **does not** rate limit the incoming requests from telegram servers, instead, it tracks the incoming requests by `from.id` and dismisses them on arrival so no further processing load is added to your servers. - -Under normal circumstances, every request will be processed & answered by your bot which means spamming it will not be that difficult. Adding this middleware to your bot limits the number of requests a specific Telegram user can send during a certain time frame. - -## 🔧 Customizability -This middleware exposes 5 customizable options: -- `timeFrame`: The time frame during which the requests will be monitored (defaults to `1000` ms). -- `limit`: The number of requests allowed within each `timeFrame` (defaults to `1`). -- `storageClient`: The type of storage to use for keeping track of users and their requests. It supports Redis as well. The default value is `MEMORY_STORE` which uses an in-memory Map, but you can also pass in a Redis client from [ioredis](https://github.com/luin/ioredis) or [redis](https://deno.land/x/redis) packages. Other redis drivers might work as well, but I have not tested them. -- `onLimitExceeded`: A function that describes what to do if the user exceeds the limit (ignores the extra requests by default). -- `keyGenerator`: A function that returns a unique key generated for each user (it uses `from.id` by default). This key is used to identify the user, therefore it should be unique and user specific. -- `keyPrefix`: The prefix to be added to your key (returned from `keyGenerator`). Will be "RATE_LIMITER" if no value passed. - -> Note: You must have redis-server **2.6.0** and above on your server to use Redis storage client with ratelimiter. Older versions of Redis are not supported. - -## 💻 Runtime Support -This plugin supports both [grammY](https://grammy.dev/) and [Telegraf](https://telegraf.js.org/) bot frameworks, therefore Deno and Node are both supported. The following examples use [express](https://github.com/expressjs/express) but you can use ratelimiter with any grammy/telegraf supported framework or with no frameworks at all. - -## 💻 How to Use -There are two ways of using ratelimiter: -- Accepting the defaults (Default Configuration). -- Passing a custom object containing your settings (Manual Configuration). - -### ✅ Default Configuration - -The following example uses [express](https://github.com/expressjs/express) as the webserver and [webhooks](https://grammy.dev/guide/deployment-types.html) to rate-limit users. This snippet demonstrates the easiest way of using ratelimiter which is accepting the default behavior: - -``` typescript -import express from "express"; -import { Bot } from "grammy"; -import { limit } from "@grammyjs/ratelimiter" - -const app = express(); -const bot = new Bot("YOUR BOT TOKEN HERE"); - -app.use(express.json()); -bot.use(limit()); - -app.listen(3000, () => { - bot.api.setWebhook("YOUR DOMAIN HERRE", { drop_pending_updates: true }); - console.log('The application is listening on port 3000!'); -}) -``` - -### ✅ Manual Configuration - -As mentioned before, you can pass an `Options` object to the `limit()` function to alter ratelimiter's behaviors. In the following snippet, I have decided to use Redis as my storage option: - -``` typescript -import express from "express"; -import { Bot } from "grammy"; -import { limit } from "@grammyjs/ratelimiter" -import Redis from "ioredis"; - - -const app = express(); -const bot = new Bot("YOUR BOT TOKEN HERE"); -const redis = new Redis(); - - -app.use(express.json()); -bot.use(limit({ - timeFrame: 2000, - - limit: 3, - - // "MEMORY_STORAGE" is the default mode. Therefore if you want to use Redis, do not pass storageClient at all. - storageClient: redis, - - onLimitExceeded: ctx => { ctx?.reply("Please refrain from sending too many requests!") }, - - // Note that the key should be a number in string format such as "123456789" - keyGenerator: ctx => { return ctx.from?.id.toString() } -})); - -app.listen(3000, () => { - bot.api.setWebhook("YOUR DOMAIN HERRE", { drop_pending_updates: true }); - console.log('The application is listening on port 3000!'); -}) -``` -As you can see in the above example, each user is allowed to send 3 requests every 2 seconds. If said user sends more requests, the bot replies with _Please refrain from sending too many requests_. That request will not travel further and dies immediately as we do not call `next()`. - -> Note: To avoid flooding Telegram servers, `onLimitExceeded` is only executed once in every `timeFrame`. - -Another use case would be limiting the incoming requests from a chat instead of a specific user: -``` typescript -import express from "express"; -import { Bot } from "grammy"; -import { limit } from "@grammyjs/ratelimiter" -const app = express(); -const bot = new Bot("YOUR BOT TOKEN HERE"); +At its core, `ratelimiter` acts as a configurable gatekeeper for incoming updates. It allows developers to define precise rules for how many messages a user or chat (or any arbitrary entity) can send in a given period, ensuring the bot remains responsive and server resources are protected from overload. -app.use(express.json()); -bot.use(limit({ - keyGenerator: (ctx) => { - if (ctx.chat?.type === "group" || ctx.chat?.type === "supergroup") { - // Note that the key should be a number in string format such as "123456789" - return ctx.chat.id.toString(); - } - } -})); +The plugin inspects each incoming message, identifies its source, and decides if it should be processed or dismissed based on the rules you set. -app.listen(3000, () => { - bot.api.setWebhook("YOUR DOMAIN HERRE", { drop_pending_updates: true }); - console.log('The application is listening on port 3000!'); -}) -``` -In this example, I have used `chat.id` as the unique key for rate-limiting. -## Acknowledgements -This package was heavily inspired by [telegraf-ratelimit](https://github.com/telegraf/telegraf-ratelimit). +> **For more information and how-to instructions, please visit** [**the official grammY ratelimiter documentation.**](https://grammy.dev/plugins/ratelimiter) ## License Distributed under the MIT License. See `LICENSE` for more information. diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 0000000..c02902b --- /dev/null +++ b/deno.jsonc @@ -0,0 +1,27 @@ +{ + "name": "@grammyjs/ratelimiter", + "version": "2.0.0", + "exports": "./mod.ts", + "tasks": { + "check": "deno check **/*.ts", + "test": "deno test --allow-all", + "dev": "deno run --watch --allow-all examples/basic.ts" + }, + "fmt": { + "options": { + "useTabs": true, + "lineWidth": 100, + "indentWidth": 4, + "singleQuote": true + } + }, + "compilerOptions": { + "strict": true, + "lib": ["deno.ns", "deno.window"] + }, + "imports": { + "grammy": "npm:grammy@^1.24.0", + "grammy/types": "npm:grammy@^1.24.0/types", + "@std/assert": "https://deno.land/std@0.224.0/assert/mod.ts" + } +} diff --git a/grammy-ratelimiter-cover.png b/grammy-ratelimiter-cover.png new file mode 100644 index 0000000000000000000000000000000000000000..6b3d96f0ebe0218d13fdb8a67de7c2bf88a5ae97 GIT binary patch literal 463120 zcmYg%1ymbhmp1MW#oeK}OK}e#+$k+?r35MN?gS{VL5sU<(c(^#;tmCZ+fR4*+kbOU z&YYQ?nao^!?|tqwks4|Wm}sPEFfcHfN{X^T7#L=9Gc3jEs<{Z`iHw+(`|l&TaA zOl>^+(?`U&eOOnZf;3Fk1o`3H4(b<016LRrbo_r`SeT3~Vi*{B7!4I|xw~qy*Yk0*HYBQvc*rQ+)B<8BhL z@`t}GL-z`$M7Wi?0soPG(!x)E<chek* X{IAHcGL4VXh4^ vQTYNKvjmocwusHLWndNxJjbFgRT6F;#PROBvGnto? z%C(*ZZU&PG0kH^}M8xsn#wsdmgx0(~{HAO@H@(2T*q`;+!ldZ*q{RG?b=#ug{Lsgf zYZ5Qt7_p71+@fT;?ayX{`1xLJ8CDM^BcIP-Kbtk<)A-d5p$C_2P{QdOc5S){fSw*I zUK{*G>1IX}=5YRxqDn$$n$wVpA+zy{OvpePzMsthk!(1?h84Xzc*0TE?)(2Lh8U9k zrtonD<(Qe)I7Q4Fg2Mj@D2dtkvDaMq#?Jz*Mv!=;MpCrh^Pe9H3ZdCjWnm@NzP)&b zbCR+mVhLS?|3`gF`E!@fSaFFiq%kujaz+1Nf3vcOq60WFGwE_g)%A0Vw@*Af1s6^F ztiPHu)+CG#zh|eNeV*ns3y&%*@Teoi;+-$TMo)gya;@_(Cw;*8tjeVdOOVhSOG|%w zI$wFeG1HSPDMXvip%RPnJRknQ9`R7s^_M^Fp17#~=l{8>?z{ch3TZ8jnPm$W`Txja zroZ14oZq5k+dWl1 iu1D{0vB^th9 zDFXhFf(W`NHn3UtLW+8T!6?}W5TWI?_0QGL#i=-N5fxdrkq{c3f5jwvDfT-Rqu%!* z_vA3rZ~eZ`=KJZ;r}9*c GeB%3@V!giL;Uuq*XC zp5dQMI3oktnT*cr=br7j0k!LHNpF9~pd4FlH)1X<@1GJHbWacQ7C!8RLj4Gy(>6={ zXG?RZNf9JUA=%e`({$^FU#+*h8<@&1J1Yw}@hN7ky! zTB|SgOw?hs>r+EBi$llsL8Q_Zz5BdY p8so2ML_1 4Z)`j88&*M z!>z58EHJoe>S$MJCTn( E>p zpGEw8xaIH++xOYr{L`mG!%F${Ep&ABT}4b%+}ys`JI}_pnuHb{p!pwVMB~;yuah6| z(5^xkCI(LbAaKebJ{5veDfyLSfIn^vG(;ZReD^im{=(Z^gIq+X?1%^gSMqC;^Gc8+ zXZ-cj-1I=7FO=wkdL? OMi zE|KbZ=<=SZ4Fn+fC|gC7rlzJMT(`H6J6gg4NF-R2y<-~D s=->X;Joy``a7E~ zotbI9&Z9v|+xSL`f8Ov^08;aN{I3Ti1ng$+=RlH8?<+;k{1N%9J4lB&-F?OaSAlW;gO-66@DKCMntnSxJBY> zBBoIi3Uq;LO>M$Od}G-#L&vq;jCepO*^be{i!TY8=6rtTi-KCw;Uk7@znbU!KcC0b zjA6;3aD`0WOZR@Rq_aA95r95%g#cu1_&!eu;6|ZCT+wGq3g>{LgceTEMEP@yu8tF2 z{T5EKNBIdOI`1O6+;UIovz{{CnY`R4Lx zL;&kV$gDieUlr+^D|mL9#(svqt1uvD=d>HnY~FxkwD1vAknZoW@ONo#2r3$x)aCYN zjDO~O@EL4jb9Ni%)MzJ_3B;${n*=~E6#Qd}E5EgVOCI>p`}>c3`xkIVa!_wAibSz& zEd0j*vhvehyA(cKf=e2|{9oX?#?7>{bA1F`bfO=vb$k=o7cl`Jv7zy8mbOxGn+Z>9 zmT}-PUbZfv(c)qH+#K1Yem}s*E0QLTvdc?IgaCQ%Xl{yZA6(t^RUEs&?v74+oWDS~ zXD9V)Xu%&Sjcjpo^R?@i9UwE4@k5V;*pVfPX0iy;*N6M+{vF=8`$l?pTE9`WOH$!; z%W@KUign$&+W@5R4y67i_iTIc#I>R7zrgM8{Ppf~JaZqum{*#`c!@NO_w>Zrn3|1# zB8Lb}`+Y?!kbnVHX+jM_CkRz+=nmeHL&ykHGZb$?yI>(G_-mj9De7BH#|ZK{)pL4& zdY(Oh>3`Tu*r35=UZzcqRV1K&&(5w|QSIy`?$-8KnD0K-;q~)uv1+c*<;W0~|7B!k zq~gFr6tXkGlso%^N` zBOzLHhti#fELk8mAdZ|;Xtc0wF|%|wHn<@Ei?=&RMfN*c<`wU%pt%uqX$6j0LuC-w z?iH>yP5gWFyco8^N{YTos_yrDu&{yI5upHd$k*N>>#CQRtrFxk&f8nFimAoMDEl;A zfW+d_;cSU@PJxFtACttR1O8ZixW=!C7u`$=ElCqVB?2goSMeftXq{{SUmYpp3MMs} z7;_oMD P4 zoJ8)Vy}z>&B1n-HycE2IE#fMjF*V8oC}3PW+jqO&vK%LvaidAdeC9FmgqBISLN9pd zD|m{e;Ih^hA09c){Qhc RVVWL4^l-P|3gw#(PArB9+ zq`-;hIcN~Ea}*y>KI-(WwD$YPs)>2+T+!)vt3Zg5>!A26>c% d9Zb3JJG&aIHXRiPj?4Uya-+OcLb2>zP)TYY*f%&6m# zlVLSm&>N7Mc*b+EZ0mRicP14z*f&Ox^d}eqapO+Elou_$ScwBI^4>u8J9}#)Y}o5$ zIB9FzLJx>^ WeElaeDyk@@ZH``U0fmG7*9tG!@+*8*v4 zd+3|GziQ?TpvLi?uV!t%gSwIp=-Y7OEld7D)0t`DV@@vL-iF6l-}&&uUkVu*+CQ2P zJEFNO&d xVh4#4XbYPjjpj6-SsQ+E1L zn}1QgYq>3Zq$(`8;=r~p{H4s0UgbtTysYX)0GvmD?(!^3ImcLM%GF@^f{DnaJZ39F z#r^q9KB&n+L *|O;Y3LG-B5qq&m_9iL>344pu;wgYe2G|b-3+M{$yqSpLg2mK5d5JGB zQrjFCnB9p9%^E}*Vl)mBqldEgPDd$kA#$ _&g_Zc#Yi>$>*QD~+wty( z0H* Adt*`xQ{i;rLJ`^n&Y{)vt`n#G7;a>TQWGz-~uRacF64s2Y8vD{N zT7lm;t^d~`Pq(i{nFvZI<-tJ@GWdX=7>fFse6W$9S?c}Q=i!tSi(DunE6dnz+q9sK z1Wq%+=BoJ;DMD*(lv=wpFOd1EJ9}{sbnasDflVVg! dx!c*X*?d{#)CkCz2uk6OYByg^DC@pKFUCj#V%N` zUGAN5!n}@KfM}uyMy-v>H%D*bRRQRJ)5e4UE9^|IFExShDxAS`KKh87nlaPxzE!#5 zPUv_BGv7-sfsR0;Mr8euhb#bM;?bV7x?Eu(kecx#cle?26-QfC?k}Qj4hIGpc@#2Z z%}(dV==-Gqa5oUyH(P=W;qL?-v>)lDEx#X4pTpp~g?MCRfzmy@{<|51jx#@J?l;xG zWLT5a9){gVE0+WTdkX6pl^ekWd0MPuX;GojD*MYjYiwQF4{v#|0v}Xv2FGfR3t1>_ zXThxm9U}31c`NAR<17C@;u9cskQb<>c*qN`XMIsP!C>dOOzmLC}XJe29@u-uWdFP9!jW^x}m_% zYHC0B*#;6!%(a(? e?tgb3M_;RzZ6;5YCb-&t$jddmP?>Bg@YN&>FGg3s;?4|$c3l&<*8x1 z9pjYI`r6N`>jQ5vE<$QjW!pGC5u}C+>E{3(;O+g gbRbI8_`}G0xHST z6*}sj)v?8}gFoE3e^YYvxV?vRc0Jfl>KU6MqxR(_Cu_}a4^2LB(C_zl@9b1}t4*LM z?I9Edu}JdycthvM8QQ|uco4>ScGjrPHgwwcDpxu)kI#I~ zlas}0m`ZeRx^ycfySmI^)o*P$92=3d|Ew%(H-~IopBGi}7xE~^qM6|H{0FC4_>icb zxt=YcS`r5g&NOTIJYVG(_$hcyxv@O?BYN@Q6wSUL!<@8>qFyH}jqiW ?69i%k}MT*SzY;8E? zFaBQx#JgX=pl#~}i(sXu@S+;d#Wjk}DGIsl1HkIqY4*v;U-w_* WlzV&gT@=7ssc^8&BmZfd@G2KA9BAB4M{t7t*lY3UO zY;U0lA1AgGdX=ss#fr$bb#+BUdTqV1Zh7& a24 zi|y`c%G?e;Bdzzkr`rcoQeT}|yrvOk4SG~snT&<^oYgG6yc3k%bE8oag0P7dy0Dqk z`(0m@0_rO=GmSJf5)fVzN2GQbtB=#uVYWcD6dyt`sCr&t4J5&s#{wAX4^O{-j0J@7 zUEz76a5OB`i}$^C1kafTb2d(zQP{8g^=8c3N~s?1n&n2H_LB5HV|#~hPs-U!(4%ST z`s=XI0FjXwlJwUonBr}nEwP#k?|64{QvJ9v!ADNRPBg3u QOTeX(cOw^FyzBFsfeY nGq1Z z> >*)oQWHvA|F>!HmDQMCqeyP-WAjE4)*x7BfyKFRS4VZ@?F{5*^J1R9_4;a2b zdY2)_-s;Kk)gB)ii^>yBjX _+DJX^&LNFc01DbOxss(b}E7IH%o_^DF0xE7n8T9 zKb-leg8vU;7Vw0Txd;pR=0|Ed*%ZC4cq}K*=XX0IRYo3MR=J 05nuE>G(SU`^7Ysy?_$y2G= `Q?LCi{h{Zvz%gMd79^I1EJDCOB*jA-EbXLM&T;s8s+8 ;c(?t=14mgAa%?8iGlZ@$VExyhA195UOx6PyMr`(!^KESp-hh;##2HxCOxzBN zyP$)owb+%={Ey$c0%4kNM*5XvRzw;wjMooT8noUZ2Cy0t#2MX@&6)~wHyqEu7&>!b z`knNU(Hy!^6Z6&bt;nS*gL!hg=li&jy!t)a11Y*Lj#3@v4}q+-lVGMK3s_m5*&nK2 zS;!*_L%yIT!}0}*ohlT~mQ1S#?9W1%3cEXfPDkrmF!SK~j*rB|=Id1`jhYQvorJr} z7!WyJNGyMyM$ER$Mhf^)6S1H!*I#7#Hd&@n68kk>3N-=Qi|ms>2c?TAef<~#`< z`IeQQZXidXIL0>%QB@T*q?GW>N={Bjd3}d=AQKggS5ag|_A7J2VQd-cD}z_6`?)-q z>Z^#b?|dkJE(&qYBYQB1Mn95BU)vIl$Pigl?^_0=XkBmSbjm#4pdwsYO$Koo*bzev z34=B`LW)vSeDD;Er$|X$FVlX|DPXz66{LO<@=)^ 9Hm3hGH z`6vzxh;%n`wRa>Xb|Xd91qHGAI?5vrxcqV_h_5U3KdNRX6M1c{=A0(@9B-k_6FAfI z$)%K_JRIoQj6<^~yn;$X0a(+Njq)LzNgm +=;`$? ze{0vvM=~`@akG!5XI4Xd>hL&U$7C)Y !u=a}dH~gA3k^$yCT5b&LonHHPNK|e}+Vh?08oLbMm431F zQlm9lUo- T*dXBjt`aZKZUHLK>vZ jH}eNlz$pqih#)E_N7fB7IZ^$3CmQ}O6^JrkGBO1W?sFnnLcV99 z;TwKhkZC2zhzCl4iYlP%vepH*5tqwbyNa%n{uRt4xardWO%aS%)*;>V8Qg3=m(qOC zTjg`BIuKRy9Q?5vTOao-r#e_$B3bl?FHrk*H_VZYzDn)SxdN7~Nz0Mv{W2knByV!( zr8|CL$-70>t@07X$D=hgK4#mK*b{}Wf=6TTu+9{Oqjo#`IXe)mh}R=pDzH8vcD(66 z<`!%~nQ6E Z G~I3$w*ewZx8NIYWFMAv9DEYZgG;Cb!*Rxjp59p0W)BF&V*oWEgP&mbTiOnquZR z7dNf}S$rq8HMD7DZiGhyM6CYc*T>>dojz=wTWSo4uRD|7lgFaOEne8oTwYlzC *L>r3rNZ_n^Qrv!9^}%t8U os^)e@^&h9q)m-5$v|Q5$@7RikJ}FTkI>6Bx8KLJ{ zF6zDy0UAlNq~IyP?tUh2pa{+1D-0f5-dMF<_$e><^Sv>s5$Ky`r^zZ+ERP<0LJ%98 zc8}rZCok{VDzUvlf}VR2c6L?=uWJ0>o9RomM;%oOhaG=l*wCkjP$06C297>yV)7MF zre9@Z%U9HO+*; )IK26_2BbXx zuX9DCiL&JsI@xRM%JMSe?l+>NU)dPs&;N{gp^1xbKMGWdD{}1x7H;-IC;{*Grcgmu znB_& G5x*#E8yVp#Q9+cM=Su0YKQ#$?ea83g=*9lF!S(yH3`#XMV{b3R zEZ4jTm(vw!X@OKoVL-}F?2%INjBSdE$#9NjZ&HW<%eLy0BECpVj-_{|7``I!d>9Q$ zsoIQ5H$bLB!+;-3rqg>#%p@o{M{r^ev3<;@1&r*7;ba#Oudqyxp<-rH2JD&gsRn ZbG=cv+R;_ph|2$gXliD3nG-q0E>s^&rWpAC&0&XSl6GTEYcw{z&P=tlBw6z4p0$ za0Kwwv|RM*=O21AH6rY$CUKF`NVo_uuQ;i)Ti}u5N6oVb-^ULcopW@LcYfXH>3nwO zTrZF-GQ5txgcZc@2Q_&DiC{oJFXH0Nk$3n^#TM2M#hu-})8Awd!%i=sBsE+J>7>bf z;#Vjlc4+yLD??_Y$65G$@l|Xjj1rDiFf?%5m-0ybYh&G3TikbX6+B1=0*D+6ZM*(# zbwlIfJ#bi8rx0IW@mNkpagNoxYo^S?S#24?+2#2+Z&UWeS5>dFFD^}#_9*=2=&1ij z`{?NQtVwUcK-ydPTvn>B)lL8F%Q%hsNl?Pvf-W2NS|F{hGz|MjvYosvBsxsf&b}SA z4IoZp5sK6}3Z$L=<3vJ$e7u545j#BK%Lm}6t3aU= YE#QU;lAH$9PHrvM<+ zNfg1iZ*S2%h0Nw!oqUdBZX}g2dv}3*GtgqGtCOa)mM}Vh%_Cs6pN{Sq@_}oZvy$@! z@wl6jtCdM!Yq~j!DSIz8oy4rbk96NnMd}WU^&3jt+}rRlTTLko=C#)vW6>6&SgA0# zHzw-dO8J1ZsXfgb2BDiE-us_Ks^!V9F48GV6j+wnG@@8Q!pvV+Z*+PMT${}EejBI3 z2@SbwItilroE$SNtJtPwrTCyRq}CZ5@tHK(pz8RvxS n1$KSetujq7b+Y9r6 z$Z{rN+tPWPhNP(sVw+|+G+N|V7rkAR1Fez5=J1djIof2zK}P!ppHT~TBdb1(^avFd zho!%622h1^o&&{|@_JH`WPLeZGsNF}`zK^TfwNlW3suOxlcW-qrYix){z}f2TSmhu z4ZC3X>SvQlHXLIz&A~xh#e6L1cxM)>47zJUKGC3>o9iQf?2Y>8O)gwRD{si%XJ_ZS zwA?bX36Q4s!PjKpET%_qE~qz!noj4nVq@083(&`NC__Ruv8aA*W?UYnpub{{nz0f7 z+-pgB#Z+k%1wUtJk5Zz~K&_IGHx^ 9~&GL^?7@FZ+Z1E${PMTKm`TyR8cN!{%Fu zwZXORosd2m0^kG+Wa<N;aLS+<7?DlJ>7EvsEpv >jvFyO$ #59CKwbt_d{1uJgmYt=Xz5!llxO zx*^1*PWK3im(+g|B0l2X=qkYC=Mhk?*6wL)y;U7jNqTDZo(yzXEbd}Qc!B=nxq!{Q z1So0)nWJ$Vcwo~L?fg}K|HCL+o`#B;Qid#Nl(Jrxai480tl8tA@830sIt4l9eTMkP zaX cYP8qX;(h@K0` MYG7-t=kwy%L11IN#t?nX%scd3w)N QK6`am6hG(sCia@1u0R5F8BTM2eAF~ti{;S@-#oB#pi)P>9YJH)$iuyyR))y z`ed`DIi2q=Z%J`wSQzd8S8fa_3miTjtv`T6 ?=r;fERhleP NUW U5-Ya6%KD89ii-~kk9wg{JeL#fG+X)Q=JES{2k+bcT?OqgL(rMYkZWZ>wzET zEN*m>@VJN7W}YWYo15Q*GW-{*jGHGfl(%xXt2$c)X7Z>7^}-MH=3wWQd@GG-AJHrw z*!ggkuQki>N%KIM%D3|<1eu04QP0v_v&qd)jkN0c5SJZBPGVM_#!`S^cU!JLc@Cp; zbX;5uI VYLMFTVr~Es?tGs;aV+&^kL!-bv0%B91~0w@cr!3g 5#W &DFG6&v_9IhiP m$^J^oe&4;iLPWYKvzt-E3aYxc4Ixri8;5*|O|lhafH7$db~ zO~z6ueI^e-^k^0x+!!+o$$9Ht+--b=l(J-gv^Q&bvf4N+taa94q)vp0)3=IDt%feW z)#7i?a4TKLFmY({Y^g4Bs6h4tNOejj#hgr$R$N)?4e-q;M^U0`T37l*KJh2|XVznU z+>oru-ry<*`dZTUj^M|h+)6}P^7BSIM}=rYO?V;f{yNv_xDQcEsF>}O4~!|xIin8W zP-XuV9Luj`1Rn8-6ee|Rt6+PAEU3MQQopk=GfgVw#6+?XV?+zLnkvt5iUHlv)&O~Y z!|W`!N6ZYOJ(e@xvrAL8?MRHK)KKHFsKSDesib7~T;)<_u}F{uS^=s|$?~+cg`|`B zi7LFkWXO~u71L;6Y8XMcYtL>Er@x8%!rJ`n??X`AmGAHGUnKh34J0j7Z)43aZktzN zN_G?OLv wBy;qD2oGa=qOxCV1y})#>jon!HhZ*F&UnWO3VT7uuE|JuP=#B$r>Y zQAhW4d+cPG2~hzbZy?~fUrs%z$H5M*htHuie5g$ %b#B+X+nrA6v`0=I5p2*;jXdFLsxyz($|j&-&!drt^Oj Ns>6_5z>LYU82O^(8sScuWTeKZFFas# zZAr~Eyg07|>Y1)+TW8S=2N!2}Xje4ooEnPfl?a%$vO^J<11Du)YFH6D_*L)(Z}B8Y zhHj~aSkF$$txvw}=D5|mL7SeR4W5Z;VA&s@uFm!S!k?nfrFRL~-t&~^*q1f#nnxf+ zuBUN&H|We>{1??QDl{}SXl6ZL;3 W_j&pvkoI9SDBLGs z958N zT3!l~@O{{Rr4$*s+J2_WW8r;=*I5iU)ThUvr&0K3DhgLz&HF!X;FwK*!46$fH!Bwd z8icx;GJ;f;I0#^*J&3V}K4M}RR+#|(E!nF%F?}an*ACxmWwaFMo6p_b+ZwEZMj6#x zx~U%5oL*8%q8P3vrMVOLT@*AS=~SvPoi4Nc(zyGpZg8Fpu)_J~Ffe5}4?+Dsge-M= z2N4<_`m+tPQuK(a(iLBD8#ulRNmtIf3~?Y16mYHEc4yl2tNl*Ivj6luVU@mWhlVAy z(<(M}1WqhQ4G}_}s2=g72(X1#sZbT7Ay~UtKmFu`xvi^as&kmIsoLcygT~P@yxv7= z@O$htjRV8jx%I10hNB-+VfKE%>4mr4?LE4GR_c9(U&rIDJMM3|lk4tkOP)iwM(tUK zxmXJ;GSm(-Q`%R#t5A{lM^wR~Hv-ignA52M9F|!5t5>I;yw1;a)QU^2Ua+q>lLuJw z60f`F5(}Q(B&Q%gm=L+F;ksyR7d^SuE ga1AyQ6)X|cR|@~0*_ky|bc<^mW?B0d9{8I@CJ zuC29#7S=p~^%wSPc?FTPf>(zloz$?jB+JB>*-b+0in;hi;K3O_Hze&{hJ9||Spg=M zC!OZyZYi7&t$~fDmII@Wdex?769U79L??QLB|Nq!IofF3XW`ahLfe_Tnwm4$jnU7W zB^<9H#*hG8ZV=6Vn%12UUd(OZLu-`0oB1TStF`s96353kt}XM=KCk$h_D-rpXj+Xn z$2=qED`rmnRO@>}!d~;y{zq7oCk&Uq 9S_J7yJF%8qRE0b1qEAbj3;Eje5W#1;6@C$4RR74zbgoU!&-(f* z$JvEhFc~FGwzwgMV1}lqXr-bQlp w0z|!~eo#_=!gqjAyW^N_dj`0W}baj4UW9!%UG0Wk{{c7yHwtt1DIW+J4xUmX@qV z`6F&@tfGx6<-NfRXh|zAakS+@ONr&AT=?3K`NU^Fk}or2lJgZbuTaDm)_3S%C25mk zhJF_0(-kn%qFvymy_A2=U3gRTZ@Odg@ncef^r0E*tf|R;Wlb)wj?yjyhJ231J=gny z-061-{C^eBT)cEY`czx|W_?ePN;#&qk#u^1!m=J15)d9=a4 s?ioAjm{jg zoan9X>G|i+`gU5h^Sz$#4Ck6fF_4vI?B`Spn1T?0*$b)&GY(F*YXg-LLe~H6wIe9D zg;)SoA+O75R}jiaa AgzmE-TX~4&%saxL zCwJ)lvf0| B>1tzqUoX0n@43&?y#nT=W!*t8NAAaZ12+94L!ahUR5u-)ZxhvQ);x;Ud5C30 zYMdM u!W zn>WbP*t)%q7=sj()^wO6+%eLjGZ%-t=^7!7_J+eCi0eev5Ua#?$^#+ami2jh P`_L=eCp~ht(jIF4x_!9WWua@ n;!l?EGpN>v7~@Tb68jiYm%8sw$qvZ z%@m>Q MVox z6f;wzvHhOC@5Ed(K@?kCB4}umEXu!rf!r3}d=k2?RF9Z92s{k0umIki8ts3t k8Z=2FfA80w@$HR(tS+j_n}M zBQS9)RZd*Oq{u1r^d5JmZtejo_9KV$zWdq?M1`|?hY=LO3|&L2(; P#A^9)jgxl!S!PoIbLU@HoyT%N0NwKjziHL!X5Ts zZ!hWVpF4Ur-xg}FaBZ-q#Hr{x7>^1Yf4Thpx%cBoJq5UZ&;A}wtP- LW`>pkk2HhK zb4OC;SiJSg@%68lO1R-NhIRm6Ir@1S7Ka?%qQNL^8KP=-+p@euw>7VLH!iMv22o8H zF^w~IR*bEq@xBgJ$V8XU<|m68+rqgm&^w`{_I|>PY3A$3<}Exp=bks>8P9 n&J_vvy03x^COtLKgyp3f0VAKYtYME@~cf7RdCO5oD=51JlCl z<*u#A+9s{bm1V?VFAhnl(4*A_1M8`sXW6+rs|yGFs&dpApMmgzD?f8SFMAC6!}iF3 zlRH!;fC|`87NMA|fn+_sA0!eA)aXkr2paB8lp}{N+aAXKo34)IKAfo>P^9y%>t@Ky z+&=x$$-BbQ$ipi{n&Qg*%Z{&CZ@~B7?m>fwrC)PzN$LD2!S4VG^|Oc%YS_bTWUj7= z*jt>=;tZ^RP%)C_*Y{Ddoe4Pk;bS HBuAJT9|30CX#v~Vd4X8BQpZHtrZIyGK@{^lr@$zAZ%G&Qle*_ zBkFOs-sufItS8iQb2Hn+Y-veh)OMp42oz0(s4BX+=&B(n&CX8dc55s=+dK*;+!ed& z2IWuho)$c_?>l4b hhgqmi*FFXvaLZ)5J=;dEO~6Sm)ro{5MD)V zGO{5j#G(IQYdH}`0TN#9tl5+F=Zg6RV7Cue&S#uk0sRtx5h<8*UKw|?>~+(?MP WXMfF!tD;91E(@MpMbwh zqixnT{jmmiq)+*y aP&1})eD+##wl`xJr*YNNOvkHe* z9L#xkq8O_<^{607?tbkhOm&(=i6dXKLFAv+&>*80(fHr+c;HG+D+yxKbSV_iwX)wR zK33iFk;7q_TP$(~@rC}J!i#A+4wG)K@DX15!X(~bwX`O-t@jPJediB#zO@JTb#;B) zhu~E9V|{rs^xCY?$G5FJIJ# J4H-v}{8eF0I_m7?&4`7P9DVQB#vCJJ1!|{Dvlmr8b|#aoXJjRD)T1fg#gN`giJ_ z5z8|xy+W5!A9>1Ge+IMS_BZ}=k)=*GB{lrVDQtSEcp$m#D;JvIZ5g0q<4m1 z)0pRu$ XOkmXDS@uO`E&q8j}C`IDi%H!t6Sg44ga9BDhu--`hoVo=0$ zRTg~*MRS`CJv#W?(6dvW96mZ>iuo~oE|>U-(%~+ogipW#$w`&aVY>LWM_yooow0>l zv;ETkJqd=N^C$E8=qu@e??STuxXmc)^n%WzD_g@CCzG%_)$BNIJYv@>=i;-6M zY~j63On9+AtNNiXz-?=OwypX`lcKhz_=;lOaLEtO_{JG)(b1x!9&6I!2_fNI4j`+h zJNhE>-PhG9PHVyy=}Iaux<30@$hGKG o4t!m`|Rvh5ZwGYr1X^8 z(68yo`Hi^}N{gOGDVgvVzW r$s{&ByN8OD%o-dZc+@ ziQfd99;J8t0?Zi;D>JEHGwDxA4Rdo7|ENp^=*OKY5D }G#`x@?cGIY)c #L6s=qfL zY9*@*{6Ct$f+4DCYg>@+PU#xDrKEf4p}UbT>F#cZ2FU>i0qO2e=}zeoq*LJIzW08A zVV$$~+E1;GD#F7_aD101frm=|AOfTtD7{7ZUr^dUG}+%q2v9oz(FLrosMhM_zvg7Y zXJ^&?q5stUY-p-cy)i;)Bs7zf$*pnu%m6tdJyhdt{5!}%Pi52Xf$5Q9kBNM*Yhq@8 z{kvO2YWy?)N5#KQy(NtKV`Y5@M4)IvRnr6$AP4S$OXr^|fjEV3J_fl~=Xe<=N+H1~ zqff@EL(mM*Ab!QSbvJ3O5UJuL%LY|ZR+Eh8=?ToQZ$ib7(`#VL(_bkkc6@!=jT+=a zrHX8AftGmaf5u tJq(IvtJzI@K#$!=Z(kV^1d^u*;FBurVN {B~CQ#jT`Tb%C6A1&Moi$?x681BE{~i)FqMB&Hx$EUPF_{=>wK$W$mc0_9 z|Ff*D3Z{@KO#=J%UXd`=3>Z2?qz}kA80rZj%8Y7-j xa|Ph?bRSLLnlx+zRf2d9i;R+&00QO^^n Pj#T zqV0glfWK+t(^V+e+nu&?<`vByMfm$i5OE_%3&1MH-7U-VQ;5&KgPR&onNsjc)XbaP zJ=wnDx)TWx L+^Rpfkv{mfJ{oRr(Mi63RzN)=7i)!nA6tp4O^r z`YS$Pd0V@lA&NG~GOJQ(&y5hlKq&>=hY$6iFEJkdmwv%zriVfbg1nLMLhoDRw*S|U z!cOkgi#dl&xC>O59&Jdx)Qi{vQo(4)!D1wZqxBiSW_|ay~!;WqK5rV4U^+A0Oa!6 zu*{ePuGVUtFu2wTd@(x8O3s*|U*|-RXmvM699JLhXizRj9V!w^>n@sZG-9PYfd#42 z8lo@hQrV%02ES7AAw_JYI`YKo {byQ+~Oyu2vVs?+iG zH9JZPsrLI;9@+-C&w;OJ8nzDl;d)F}>El2Zi%m9PY#h)Qm&UDKf|>QjdVsE%--5|~ zv%Ph(8S8~^Z4iEMovPy#cyQNW`*cfdX;YawGTSE7fGnyhEBpVvK&G9dbs8hLBndZ# zf @(G-Tec7A#|UV5I2vb|$DQDp@?D=Q0Wr3l%M_5_GTvJo8a2q*IC z3Bd# ~>VJBRHI)gGt^dI{-*9#?yZx z_vW|<_?w?66uo4Gfd^A18Hp}t1BDEGOJ=u$W=a_nF`h3^;Ly{0PXs=o&z{5U5=kd* z5 &+G%K %_=*V=+ku&SqxL=oV<8NCK7Ts
Zx_9< kJC;VE`Mfwku~wh(JuT-f8Mc}5+qWM(ZG!poOyD*F+T+@9pTJK> z{Qde(G8T1cUVJa*4X?Qxpkf%Cq=B=ouh{b1M0TadXn%zk?DXq`=&53PsV$>Ua^uj0 zt+}s++LFCZ%iG(F-dsl)j*hso2Pf|02Gee~P`G`463)6lNS`EG^&CnQmD(ItCuNjE zpAp*mBEgH8Xj jlT|hox4h6%q6SWc54P34 zOMT)0Ge`X`5D6lK_*AtQqbGjuI1l1k3qBSdqJv@^U(DSd^`xgX%sTBtj2wBb%aHY& zt77FF3DD(-KR`~uOvj<{ED4rMxpo8!DHhvAn98WeaCP+hdhT7phqil&{6=NUI8tph zV3s_SEqzz86v`Bcl6Vnh5!F?c2>(_aG75#@LV`1h<0$6e4E*2YKw=+%eyp^tz3;qW z^$m|k@=1)c(u=*st=X;q(2P~c4$I^Ho0acF35XR4`B}7bG@C6x8?7B__tQU%vm#@x zS~%%a#4>b-QV4F*FXO!XX{YRUi>a+W(dfYNa%$vImh z2l#v8uyxY&gsHNeJ9f=)Kh=_+G35ZMDeW) zYdk}D;~dL$;IQz7VGNrlUwO$%gVSzkN~^dFi2#3`v`tEXlPVdocbT0_!7C8DtWN oW)?SPuIed$Cf`XKJ#(Qu30 zT2hyWhWbJnezY8EcN`e!hp0B7yzAn1vq!j? ;^}yVR*5 zCpXtM4D?^Bn%kfCO`Nt>`FO62UW@DIe%s^bz;l>Ym@=wy-#)KwiKeN93aASf7uTx& zF0wh0{?B@j|40UWbM2kxV@3VZn@c$fR+BQ${cz!+=>^cOu4X^<=-{DZFPns`7et8* z3vCwxZqVvSs Ht2H?Yc7JWo9=4uNp_;Q{bM4b~34 zX%9y*109FYo}L?c8hbw96n?d#;_}wLulK>-zk5Yl2%yj*Q0IIY4*2{$SbTmWp%!)- z@>`I@PDu)G9J6|$`%7^G=-pWRyb#QGfD$$v{?z35KYjvB9^&dx7{Q4lOLO>7glSDE z7C !|_?)a7aCbVyjYr{s`;WcB7Dp}0=v%tRA052dA52*M;EAO`2> zB3a>6-ElN5rQsj~A%le!n$cuA9**$)ikBhgMIGzauVpcySQSwW#@6&90&G0#gid;9 zk( rRLi!J2E|tn5#&pF{$ |2ro`lr3Uulgixi)EufI-6XQ6InHY!?MRsAB_c180(HkWNPnS zRqAJ8|8|!{;6tTzX=DdBH^-H1#MHPA$CIfrjY@QuXRQw8{{sBPR1DjrV%od}T2C<} z1br;NZhg79+6p&Blj%pkFd^wa8^I^OalLm=-M3Fw!NxC(nVpgv97{T==WBA@(4tAR zRb|plf>5#Kt(=$GLiz#tSwuPZn3&1XrxhTNO@-2AcBM}6`D!FZ;DKi>GI>zmjXIx! zZHPf9>@Ir=A3F48W%^;wUt(|gdCycjRFU{Hy2JM(@eI{#h_KLN>;Qdujl(Pk*oPfZ z$*d^jKnJPL>n#U_rEwk<`@#KJ*4`wea*B8(zBFGhkUw`MYJYhyRuk^1Um01mJ0e<| zzWBH1Gs2ugcis*Ii7MGGx>;`e`R=xAr#!v5O7r1{=z(JxYZVf$$f%OFvS$cVt$DZ| zmd>RB;WnT(X=Zcc43)Q@pe`B{Mrj=$XRMv=+ZFu~V{+6#UuWgZ0@7OE@rfH*zlX!~ ziNswDKD~MZFc=8Dvss9DSZfLvRh!}f?%SJTA@GvhRGX&&!aviSr>gk%+#ju~OgCE; zof3r<5?J@c7dV1sINlw$OxJZ!`6(plwOvx~<7XSAl7#-ig@w=z(FpwVDdsUhFQCT@ zH(r@cX36N!my*5XV!REalGyxGF8DK5PS&qTzdjfB5=klk_wVs!1H22{Z`^`R3!WC! zO8xd;tQL7>=_J6v5*j|2wqDQvTg>*Ieg 7Yu^HV-e;P0qDBa;dU#0X z!OPE~@1_-iMy$fN((ouUBW!f#hayw3MB_XnLHWyg7@{d-RRWuJm*<3k;{e?YSkZ^d z=^kFw#_J)pm#cMR$|*2#@ESy% ycS^wmVyOxMZx_nZOH*!^E zS<0@xrpwk~#7{pM`)<~X3BUDxH${+wU#Bvq&Lb}CySft*P9{ukGfQN&i!HexRSlG| zObN?P8GGsc!F|sp=hcSAI@x4dVzJWcf$z3ch+XU#hruRNLbAJ3Rk_X5(sB8ceo8rb zl^~Gyml$|a--}pl6E`0=W3 Gsj q#% z9 J;En}xGU@@+i=y-!v!;2!tY|tf+ 8%nBAqTvbN**Nlbc*7F}#*BWKOU3P=zyjQ?#gnv $$w|}){@3NW$zQ&-lE^oA4EEw9@Xl42?Vr-#7(jTm& z!!7wc^|>TK!b= 4ltge?c#% zmS{I{+ymAl^S^%SW7b4paZ2N9jaLu-)Kur`xz)trrfm)2nLklIsbz1_%oWToiG7a`@fK%g zgEA12J| ?}0fs~9jZu_Tzh4KV)x WS=FTEZ(+qzE**B>lnP2y!zvNxBw zLY1_h2E+$Z1Efa{LrQoBX482Z%G~q-3&2*Ho99MQ4m_%s-_uVOZAw z+W*^NfqI%pY4h{*Co=DDanVm37c)mwpW_-2 z@=Wh%a%S6QWNbBcv6i3aTa<%l*(D^uNs`?cX3etCaH%DdF$RA6t?I5M$pLSU!g5Ow zLq*71s0wWWDEG}6Q`6Ag4-E`h3`-p}Mc}*e`@LShGl`$`$69U-r2mF-6MA34|661| ztry2i_o368hR+KJarGSmz BxV)Lu-!lN+Z(>#^6(gekH-FTM{RXD&mIR1#6XX`2Z=PcLcuo8C1j>p^l zs^2UfNoauX%k1F#FTISz|J#Yt_tcJx59GZ(db94It)1oDAsfAY6=@T&S@ofjkFRD3 zRZ%riokq$ql7*)I7+`W+B5cKql`yEN#V`oua!sla1Cq+vR6-e16tMwI)%b`=^27O3 z-xXJyoi^J13*5<{?+yrP;VS8Dh7<^iC7^t1GJ%>p;`c_aDGl%DQdMUz7NIp7- ?;dR6U5yjuV2CJUxY zJ3MhXDPB%S9y08~S>H)LuyO`u=rjEnBl(Yd@{abk66{QkH98lJf1!b7mhxoZ0{h*y zowZzlB$s4B!olB(#>SbM8Ciuj7plyd(?rVJrbeac^V!rBD&`Z!8CgtrA2)8ldIZ0y z`IZH0neTQRRucAoR{!4&6;lPg @B1E zW2Liw+ars{`C|6>mQq_uLObzQFh$}TdsXk8Km+omHFPIwHzP$&Bx)M}tF5n`LFX@i zeb30>8}77HV1;S98TcH!!ZI-XHnq8i$m{*}Z3{;>P~V&x9q!+7ZC?SwM1=eH4po*M zZbtx;dX(hOMUo6`7#DqS<^>iCafl9#^hiNwfmB75CL?S}Oq8KUC6b<+jk_t+f@7nW z@0L&V+Tt%ykMrwR2})!b@2Ita<|Q?37|DkAjxUEDQ_l|KP(5KoFv!5m>#(4VL=~9D zr-etD=#3XJDX!c}G4xV**JsmEQOZry M#w8xW!?nNfT)=6lq=TFSpi=`9=)OG g*7gb^96uUDfvK zwY87r=fsGFIDwGrE}=TnQDyj)qAnf*fj{%QnTu@I6?H-Le jTv4A$0O4Sn*==G z5Hz#3DB<>J#IkjJPKh9!(j%NLBN;BIeL~x !NHGG_Cb*17JiEetiH!>m?Y&Bl))0NklOq+pr^{pK;6-6j~nC1w(^hnIB}% zAL&17^K7-@)}PU!C)ial+B|4{`dQu{%#P;Dv)%Y=5N<;Eu+TaXiir7{H^SM}yn 8O+b L5xxpJr5^f4t*Y|MbL}~8DyYN zeNAKwD^Ms>G)ygvme&4KB#kvZJX^bN<$P1uu5w{oCp9PG8^1cMIx9&P>7D_Y|`s zz>YPOqK!XS#N8pBSwL8n=cSqKyP+2L2S!~xS_XfEbSxpOZiX8_v#+sHri$28^y1tT zfd_J#w8Yf?T^=4pwW|!$E0i!2cf^MK?u$!;z_3SoA#b)^CN0d`A33p;z6#mP7cwYu zctYwBexz%pbNGUNRD1lOHwWIlb?CH2f*vC~I3)?9+98jIdm;kY#57#2O7z8iEW)qx z$nXBnu9f;7Qb=yMM@=>EV%5oJ4%vf5^2oQ`Kh~9WlO;YDu!`aV12zLSd78Q33~M;u z>w5vw@71$NzU{6xQ5$PG2g({ZwgVb#`RiuMJ2M^5vrp(U0(!p8V-{K-!%>C@qy@P8 zes HQr95Ku!=`U!pMYwvxXg_{qce)DmI zo%^bFq1W}}-8u}(B53>@r&dAqXJ1Hyk(}%e^ZXYki2z+=^9M+O-R}r|&R0$fP5b0= zA<@mIot*S=4QW(^Opy1#_$7*6>M q(2wRWAL%dS}3_#jl*dKNFTF?8*JU<2F8I10sX_(!tLBS7b}ag-eh)YM(uX%=11k zzDlA3FQ(Ih-%*mM7{U42syxoGX3mfO2eASnf0_8oN}T3SNz=2`S7Ks9aB)0JYI (@F&mwz%gz0WC>G#WOWqIL zE00Aomxj8&u7Ub`HAD(GPQP6t>~zLTXk^uUQNc=98Y}TtpH1<8sbmRO*Fxau1R;bV zfs2*rmc)1Pv*BbR(de(|0H2eMi~wj|r5u9 2G*|++;^BA23R!j)1 zk1&t3{K9&xorHv#U4z} =pUX)m;G{W}YLYapp2;#R6h2}njjX4&O&~$=!a$GPsErUZ zGI7RaFv6nji13Ap@bmR5*N}}@1zH5&caOg0L_udPsWkt)m0^9Tm+S^5IcB=dkMeZV zmC;p`q$?|OF;7mRTE3Sk(m4^nG+RbL8wRx}3Mocii{$+;DR*lso(@lQoR?}3Eg4Pi zv(Be#HMoTDr;e3{av11_%XMyazSvp~g%k3XN+`Yw!B?2)Mu~P4K2s~LX0ZMI`y`5j z%4KBcXYHlTOwPl?5v3<|Mn>nvY{Wc9HJIr|@&xDmdbpngQpf8)zu5ZyP5Ckz{XcYd z80RY~qhB*x`4>{86Neczfx1@%i>l{gHHPFKp9t{9v(Y|6zZI5 fg$6dO>nh7GWbfBg}<3xp|4`OkHCCuOu(t7l?trPB1)|WECRFC zy%x}>#VdIZyR{b+mJ(z}2n9hm438B%6D`;SQ>s&o@jg9L^Vy4{>~3h}*VK&tH4!8Q z6tLn1c?+VP8r9J P~!=Ss>^G?WzKEutqnA2a8 G=)A%oXyj;H zYPu>K&aP1$Y9Qo`V8$QQrGWdHOgK9xLDHY;o;(3nmmH<6kO&R)<={!v{SYtr;oM#; z2s5@(9y8%V+Dg*TNup{m-a;%nnG{EvzPQxQq6d|EuCjB7m#Bq@Uxu;evd _%5ETB;h8c@xX9qQDf^J~~7=`A6uy$a*Af~hgm<0p057w|Jz~2gj zZiPOb0hO#|kB`YvT@3yP9l?nYkRlS>Q kC3jZfe+I{qO;=V%SRf6Sb@??NN9e}R; zPqK9STn;ETjjo?aD67d={h%EEFKW&j;WOa#&*QIyil!Yx0zeq~@e&_O#!Ld34^!uf zxaK ew|MkeLJ_S>hRbSKlvL(&`RZ{fhW1e7O??Kd1`mu(vlIs+2iN=xO{GLj> zG&~*vge&76Jt7Itb-(!&r77N(Q?PkgdNKJ{z+JMtrE^O|bG3^d17nt2_+_B6PwL9| zzvze#yRZv+;=M@x{Vy=FhLYK&|7q7)Yc2}INIoZ=CO+b!SW5IJ$6FIs`k?m8b39Sr zQzHB#w!br3OLRm{$0?vydpc1C2F%dJvV2{#8}Rb{^BQjBZ)h8;PFj0@6n(5C){++I zsi(`SPJO%wxGnWPrBM$qfnmw7{EOn6vQCH?;<`lUDB5eGZQ#t#%uJXdeVw8%?gUOx z&;LuZ3j`z>yco*%trQ%M-&9lT1H*lZxRuQLwDY5U{gte@X#oyn*qeXX2gO&o19YT% zRoNcs@XJb$UP#g84U~VdQOs%*ci}D&0q15*K#@eeiSCvkRq{Qu6sPiYRNoU!R5m|# zd+e%T?=URl*|VvDrh}u2Z7AR6aSP^Y0Iv#;{@co?Q^drEOqM~uzuD`4o9@w8wk>Fm zy=BSvHe+Bo77nR*2P%rE|5JAkzt8{_eQ~jHdBcn%bm}`%Xjxia-84M5n&c45O#$Tb z0_A7ebS*kVzH3;GD=}AL&!v|t+Ua!FWZkWz2RiTo+3BG6K;u$+aVVd8mZwDDe(|7) zcjeWXFSgl)6FUE&wtit7O-i9^6DLa#Ce*rC-O5yCWX`}e;57~3AXZu4CPB>50L!&; zll@9eM3@i *F4Z0w$E9GF}@YjZJ<1)mv zWZ;q$6Mk>gyyeqfJDYVkN;;4o0iO-G5PVgbJ#2&XpjqoncO%F6Q86g+5nh!E!a!R- z#^g-Ss~67 8e)}7C+M%iCq)98YGyq@ik#Obq`m}W^uGyc4*nc{`uTLYU&nKW& zvz9 ByF<2(qe?m+XCo4o8oj7$UsyDL zPz3JdoN=}0ygVEhl*$D9Z2Pj6Vduhep0gE~{B#N?P41NW-|+iM^q1=l)1>1My8_up z`s#_taQFD#FSokObG-axDFA$^uklNS2Ehrfcq?fw(#Kr`YFMiP<$-AR1!5?acz=Io z^my%748*vRP*Mya!=*Up3(}XA`Cx(vtKy$v6?%sKIS>y*kgL}Qx`Fa9p^4Tm!F3@6 zgxwy*9gTFn*_aJ~3T`%`Ix1K;6PJ5_X97<0OMjC7%4T!csgKWp-Z$P50~7hdfxH*s zOy8&GS%J)VJAQ*>`OKY*^0^C6p-f~mT(?re%IXV#+*?sGBW@wymFbSahKcPIIZwz2 zc5+tCSTj|35guQl2&Q|I9+@E#k0F>k{n~ct5fN7*TcSorxw#HqCx&DWo&c2eUz#D% zA|-)U;!L*VvjcR}?zacIY;oris(yO}qYlNbiaRnd3~;7azOQt?nAjVpRhNM}CEa8? zp$o%jb>Hk_b#e@8L_tZ|=h4*%rJ;nAGuheyL{I?8H#nWF->*h}j%R{GcA#4$oGnTP z>^-t(E9;}&4w_;2B9Bhge1ZcHACziWY^E8Qd~>vQB7Bs2QpShGsewa?CAWg=@DdrU z)%g+V-0lTJ7%^{T$n$?%2b87(8ei(1liMP+x$~45!*%Rni}TSIW6G(gkky!W$R1MK z=P+?+ KACUc1qW|QBh|wdB;mOzG!|Pet(|v6 zqy#$uzaGn%)uVTC5jO0Cbv~mFYuOP(c;xY2cYOz9R!zGb@38{f7v|Ws$+7WYs}xJP zL^w=HhIm}fjEs&;n}zGH`8&nXl@(KCgGG7mg0(q0-;{*EKtsdhr+;9uM!v>;8bTQS z1D5}Bj%M(6m6{;EWQdVQ=FJ}g21M01i_7e&_Od=$vwjo(F&zgy=amTA8hypsT)BR` zKvc={cnxb0;7^Xc Mk3vi z^Dh*$!^H=!%jxhC=LWrgg)chB;V$5mT`p80AFbbFG)>EzL2R2MCPXfTHl$d`{hv0+ z-bSm%S0qAK#oqv{-q|H1n*Uv?mub(MF*Qh?2JKX|O9xXt?W=`+(9Ls9NgV4H+}Bf; zvr2Fa=k+VLFs^k7eq1>Q6aC2Uwt6gj)R9v$Sg)GoVHA9XVi0I~qV80%%QE!h=ypE|i(3ODLILKO z!JTqv-`S~&>^?y%__Mk=w3Wt^gEGBg2Z}AzUUX@vk{k{>Q3J!GEIg!RKtK$qg6ys^ z;6=q-5(G>X3HE$r-t8>vcW)DXI*5Ch-L>X>-nvt~e-P-KI+NjIHRY2<;z|LyCJL*N z(P{E w-2(!ze0Kh(JC1t!4f6m#;$VUtOHXE_r2@krXN z&>iyHeN!H$qiOO7&zac~AE%&uH@2N_Vx_4gAQ3wv_+vQ0ExjsAy{1op1RjA4+OGO1 zQq?X2RJpSRDrN~^Fg3o@5w&Q7*tfhF7>jWB`&j0YkSzkzJL&Xl#d};n7u6I|I&e`T zn;^Ax0NNR4j3#b{VMAwwbjr9_dd&P$s7uERZK|9_X}lH=M6K|={9@^Ignk$^Pbn&4 z9DjaU#1#FNa~ud|CT-C zTFymvsDL=WB0+Ymi2tbZC0q8psofB^XS0I7+VP2EGnGAgq}0E2m@)4~)i?23aW9;3 zDdU`Q(dPC@M{AOW{5JYrXtyh<4zU#^;M!F?`OEIG3}ZJt`SqS$xdJw2cAXH}2(fi$ z1M*@O)E3C(<&1}+9{angLD4sLJh*AzcWVCKOcK1%C#KEq zoB;HmDk{ZaSsdUG$>kmZIg8jv96SF$vURUyo@~&W{1Ke<@4=g|?fV$*ODTrm_t@R) zSrW*X*QsbaDkVe#eTo@mFu79;q!*^-yZDzAdo|lfLh&z&6mOP0t+AT75_^lP4Px*B zX)SbG;MW+?RV>*%5D|Q*ha{2(lyxl_HZ6SwkhpJMYnahJiP{K6er+3lX663;&NUZj z&inxvdz(r+f22V&>^Q=5=*s7Z-IK}b|6KgraewoLF*!-hiU+x6d%G;7?{5UJ_3OAQ z5R2{X2IZv`PpiV)I9vNq|5zI-c1UM}?gR Sl ~a40DyT3JIpuvl? v?PR@)JZ z95g-;OKj}PexY`~=QNHz-f%mq5qm8E2A{Yg-Xkpp6m6$JRo0Ou>ei-HyER~c0ifXr z$kw-+BhBeAL94U76`5S{-Oj(u{g#LU`<7N$^Ox49dYa+2HZr4Y%p2=T<{#gyQV9O1 z_kUH OkUwT4zwt?3ZiuKj6a%^#!U2S1;UTes-VFjM4j+wNyIesvY_(E_xANqpb zFfHw5rjU~Dx($oq)()+lUtS;cjl4f~@5dpkah=j^IDU#zef)XTe1R&Q$)0yE^jZz3 zta2)0COfyE)fIu3^M-S>8&sdi>(KNd`5~}1 iO_;iH&6hFapl9tZo#L`#&WO`}y zb#=bN4xNG<6RkNO4wFJav{9R0i3ZaO7CdW+i&ODClSkmxR2=SIHZkx(Fzb`_t@pbc z>(`OhZB2WoA#V~%v2ORlY0W@O=`wle7NxZS?u~H${9=rsR;P)dQW<4omJf)X#EkZr zrZW%_P_UHF)Sd(v2dYmy2ngFgae-2)$@gFtu2cRVA)sy5tpH!1-w)2XQPnn6$&!Yj zhM_7k6Y{#i<&_=CSU@y}W_RVF+y0Q23idP}A-0e n7 z9q|dLJ^Pxlm^lz- h5LQh0sM!iJah$`kZyrcQyp_5P9c~1VLJuWBBGShA zIU2X#*XMH4OELl>HswbHvXzAN{6<-sCB+yRSKRb;y&wn<$^0w9oKW5*O1MC-QZ-<~ zjY L9TQ{MqpSMPa#(W3tSEy7z0S>k#ztb~%mOT@MgtJ# zVlD6Z)RE3bCV{T6x)uQewEZL{a&M^ZAY LUS_? zQ|B;{z5J2j9q(jwpHKJxc}P;r-vU LPc-=621PHqZ`%M~DQB6R9J!9W*PP zEsOo~WjxnQ7idUCm+@2kF7y%`7TPKlUgNwkbh`Aj+m+71#x{BM<|zK<1y}`IA-*Ml zK(JCqhsgDhBM#Hl*l@@@D$JGK2){UMo*Zj{5iXGyxPIXdii!*m!U?taN~`YQt>!Lm zQvMHZh(YS;p{< qBMTCw$h#v%~R#Ol);*> z&L47|x^pat_=o8Qp`8Br^_Mz>D_dj)#_Yn}NOgve_wdniF6-S$w{;!?!Clp_ |NoozQ`*54>K_KS{uQq9i(j6ia28ra|Cj1F|XqH9`TN)OGdk!zT zF(0sVs5PLC92ZQt`fIhkV3hOg<3F0Es*Z;@_DgE|Z9h9ARq-EzdJ#Xo531cro~K83 zZ5KtbJ)*Mc4D6A$`l{^ItE39;v;d8=rS(<#ugy9 rw{C$RwBwdXlhK3;TCow#08dS)}3)F#M^y zn%oy|$=RMi-KT(tb+B W_O zBD`v8JFdgqCb@ `UyYSF=B#>DM SI)!)o4lXBnnZghDG7U$@EN;7RbuhmGpt(l+c>r(d|KW2KFxP;u+ z)B312wPq%!a#?{hzVnCrsw%5YGdNp%!4NC(Npyy@S4 %b!j-k#4w60I z!iW;Q6KAi?nI&vm1LbfN&!Nc)e&spwUAa@?0;ModoyVXC-%YX8${Ji4YS|m<*w?B! z?sxB0JFNS}v)XrL0=(!2UY5{v(jN)ml|QbhWu;>afaRx*lbN_?qPE$qpc?ypV2yAe z$9DPP{fK>#)JJf&OJWoUnk$A`>>;WI_4WX-eZGnht$7P?^f!6^y%&*MXdV)zB4Ujd zC0EcF9O7tG42ryfI;1t=P{RA2=uK__{G8~F!h_VUSlM>GTi(-9phS{a(bjLZ^qChJ z_b|Zx?Dkph5YPj+%y8h-$C#Mbku#fT7rIcGySx7wL1HVnx;Is`GBI>*&z4L?mm5K3 zE52)q)O_nGnHUaUvUIW)SznyOC p+$#c19$!@buJ#c&k3zK)G5byL*Z6BQRga_07gNN w(w$oZn&eFC|@-XGGfNN(!;GVA)-VKhHAN zrelKJ7K0MWSw(oAblhWb|H69Dt@VK&%0YNos}<5eZJ+g B>mz*UtWU2CBqB`yF-C z(}0A}_(se3Yd%W*_FA=($7b<#%nb zJ+VD<$`)tC)?E*y3g`xu@p@0c7MN z>fqH1q F&2WlIR49p*=>zaKnCh D=^a$J`l}w%zQ|4hQXxmB_G# z& 6at;R4V% zYtJlfUBwnTUBcSiO|S{5L_F>^P~z0Cb!v4P`1uYu_M9bZVspQ-uKup$fi}Ng?!MMb zLIY=9TB618A;co(tkS^E^)cL?@9yUwfN)=s=*7|gygSlzKn YU0Bzja67-V)tsyA-IL==~<9h{s~~fd}A6f5CS(*u#Fq&sba5nZjpU(@OpC zcm5y@jS $P&Kh;U`?t>fGgu)%3R29w4~@ z>o wuiCv2 9ngvYr5FGS7dww_iO&w5=b@iFn!ZVIYFHK@A} z1LBWVh!*Q2*&l@c?l-k$^2|yt!V5%9o<~z>E!<1PdSQG*_IZC}z35aI`tNeLv1Qy% z?a9dWU+_Tat#e^f+AZh5@umUU;zVo#PwkT(Q%4|v45svq@nztFD<*kZAXVp_$EV)w z#-*XUp8w8(w@Xk~COc!hJ7A8UduXV+ce8G(f)Bkpg?xoPy*gv^;yonpP+na*A@}Q@ zxWyOOCnUll!a?*YzKRQ44)RZWVLhL@@%TmwQwhi7M3HCo+t4DNw2*L@x{Hj`eS)4M zz=O;;X9X{0rl30)b{H}U!2I+F%yb_MlXp(Tn@#X>i{lqvyjaV(F5mx0(^o~s5pCNB zcMa|YcXxMp3vMB}ySux)(?Fxa-7SFtp>cP2cX)lyx$md`YSb9JcCA`_t|?^H8^(Xe z!IsvTWl&CNx8C|rWwtZCo9hv HG-$*yVQlrs;I;s2Feu0(IsPA6+#=$xW1TJ*l8~f z6>TLe2MMYo%K}fqt}xF-aO9RPm} z|z-(ql1jN&J3pHvtPu31(~zh%9d|d{$3e zsh2p%T&Vfkm4GMUAy078f4nhK9ayd+#B}q+L)v*mm<+hoL!Wd|Kq>sNrOAlIH+fhv zj%}RdnaW@{ToraE7HX%`JEy4bs=_ajmcx{U*O~gKXqO77-1N_KI*eIgIsNyn633s* z7;0NS!`d5>bgpEuyN8jPw~#R!t*32rCnkbGJy=uvT~(V4c?bY?IDaY+<_Qz#BoSb% zClWmS?_$SetjAZvO>1#^z8x^a8e%t0!-2)V3EX-?IN@828)CO!#_ph m80Rfqk}euNT72oT0ZAQ8+5 df-&8l=0b*rNl@w`@mPYD~Lzs;I zZfND>CMEl62I^J(aCK F4^asNV9sVAZW9$baMIO<(%Bpl%*<-#LM;#M9z+vz7JjP^!TrI_cn4nsJD~ae ztxaC^6eov__JHNe9^(H9ey>Gt^pq{jS?t7;+58D#+RTr$u8zXfEw|#p454&UQ1|yE zSl0~Eu|4e<_9sip167{G-$tp-+D~aNhy`rS$&) zL7(vbjTCTRH*S%a#dj51Bho?kfD}ic!gkScr{ca5p9kQ|PPP}P^<4DjLRB34!WqW0 z$!z;ySbAnAmnORNM|aYy+m#8zYl@gLPB+bWu;+;c@RT=AZ*@t3{2NcBi$vo9qt{-E zKiwSwAHEy{V%d}8z&xwV&=`@1?Yp{4q-YeA?%5(%TOYxoje3=Pn>*Ul+3U*Id{uH# z4mfs5VSy}_yI%`<$f(L+B`zMT-Tl1WUN^S{%LJ4xUkll78BYv68M!7a;I}EY+Is{G z7$sxjC(TUX(AK0C`# BUpVwzfi@mNPAH`2&wPM!oQtf4T$= zALnEL$c1wk$&W+qS0W1ltfmP1V_x9E0Vi?yZ|TJ{3yU@?`$8Dp< SS5HJ -tW%yGJd8wdEZ(hkPsyj0B?5jC zhMLBz-!&=5sQT>Am)yzc&QzYMOGjVTVv~x@S9*(GMlU=R;Km!3_7VZC0`Z4^S@=IJ z9W;cH8&S}G^cDaf?DF2(BsLwz4p)AHqycO<2i`I3e!u1Khdd78^;b5Go^k(=ApBSf z!%pq$!`RZq(->aOWSDKVtG;wLc{XHe<;tlJ@%o@uAe2W@1Y;Jvn}A{=A) 1J)fT2Af}Ebm~{!qAK*ZR_*>$dvreO zhQJwGj`jX$#Piz1w3c=mYLOGcCLQL+E_32Ubq?i8NHWA=b*{d!P?#y~5(~QbL4CjE zuWItD#07arKI{H`R80| # zXUrp+L_!t#;Q&tqrZZ=vD5OD7vDvSX(0Brd5$AL3Hj@hS#AFlwAa5Y)6Qvj <{ia5LaoLI=%KWgv3iURD6zbFZ-SLA6Uiu3$i85g#2x1=xW7?aRYsp?d zURolyF+0(b&ELRT8Uls2_ca=bPlW#WbzV-*CL+6n=B`YPBuJe^(Q7-5yG}u%NJp#N ziC*5@hCWez|9Z~raK6(hIp<{XR+JY|v)(9=!iW<5MdQlmOUB3l%D-&f6iEfRa?jt% zj{jIG=wc;~O6We5lzVUp-8M4PCfK-d`gWYRw)sI*7m0(R*Jt2Y!j6MeF|thOd3SEM zy @0XQAyV#@vrUsBSW -({rDN_?vDs@3!&;CI#H)k|i*&K3N$p(+hK zF;>CLt)N4_0q7X8STxrn60__(n~^a-bZYOjnb0Ohd+;FR$zhhCM5%EP4mS};MEbTk zh%TQBMgKTvdchf{>dBBcHMV5@(3lDxo5`Zg-~Fg*WYihctK?ZY3AAOfUD~P^%J`8a zCxhe;2m wOgG(&d9EE zAb@F=$e0j{^IeX#8(;sFde+CsB-B0M8AKcR{2E&dG Gq31`0WiG<9|o zy37a?b!w8#yUtg&WJdvT3A^}CsTeZ<^UnbvyTT~lbIZz+W;2D$)_0X0)ojccO-i?j zJ;iJS5zP;SFS*zc^7l)yPHY=qJBc3io7;UQOlADP*B~!gXz30BI9S@x%BlC9C~b+m z=O}(OvB>=xh%@Qr0OJo$d-o6Npq~3&b=7j7Dl_d-Rk4&Ubb?F0QY@h(jJeyo0s~ z*bV>$#PRAK!_lZ=9?7|AKuG-_M1?p5;Q;N4d~`}rb(}iIZ2xkpCKD(w2`go8gRj1l zi?++BO;u{Lu~2cc9SM!Hd$F&gN{5bLku0uud%zM~DN6m{Srw89blL-VeMt=WgTuWa z3oU`T0^0z=1GsAas@c{~%h8c=XP4j9V~Dv)bL 8^jS7gnG&iM&Ll*`h=4$s0tfw zC0$?Ja*Y2k{j@{& FGN|;~PnVmlWnm`d-&1Ng5UBJgA7vRJeSQwKn=r1n=z}s-1u9 zXzm{ziX^a}sIiO*aI{I1Af_Rw6s-THf@;(dN4p1Yc~Zjezk_nPBAXhwpHF!5GLRdW zLsJs9+|q+lc*^}LazPkr@)l6#OnzvV#d9XYR9f_#z>zk$)+|omc~@Jh5svQ(u-p1d zhL&@FGZ_i51O|pscv#T~%l6VTyol@M(?b%Rj-^qb+Kz|xRfnUv1k+jtq~dxC8tFkC zRzxI8RB0_+*UB=-gJV2f9Wi^;7xVW%F-3GReSo%&7xW8-z^w&yr9(2;bNl}aG-xP} z@wPKoGKt@QzDI#$BEi=93HqrkUT`bNK4WxAS=wEo rd1CpXkhP74 z_+A1 =f>#j3wet@5NTFCn#`_AIWorMP8)e6 <%DyfjojgCkCxqW-^y|$g7qxV5R z6NsfV&0yaVKyo-=xeGLwipA-SE9ebE3tfiIIw_7gW}Y@D>Ahx~Dy*;zmdLq%Q)Um@(Bu$#o+wm;Z_=+!Ca2t%GF-4{vvM1F176C}Ygu3hJ* zzxBV*@&~0Mzq9VZG+m bNqo$X^lI^I8|msX-X}x|{$O2_eL}$_QCgA!&^g zcLwNQIqAo$Mg>Dm!PFv43Xv;?6gU9(41LPLS}9_!n<->~)YxlCtlR3WZV<>N4Afm* zA5Jb5;(if^dr2z~pxeC51zk33w9qV zP3rkSofIuT6S1d<`@D(uR(#qO1J~h>Kn}wVy)I{_%UPDMgzqQIkfk>JkpJCuhhoQg z4=;$`shI}=Mq)Je<+8+fn}}F--#}j$nTX&ALtt%fsMHvtgZku)f+nV-=kAAA$8==6 z-`yT!L{(IsP4yN$nz)KjaqXrP0=xKjqb6{5l()yOu`VrvmLDlCB>Lj|+mQlT|Hp`& zVD^1k;x$|=3&23dZU(RK`_OmUB+@S~0lo9S8k?%i|0(o7?r_n <|rf;yjC6XjGlr%R+}5O`Usx>N(ckl&h+98$c4%KuN-Y! z0+h}${aKiqc45KT;wxG?C`bCsHQ_&H4zt|Dp}X}R*z=i8Y(8XZ3GO~mdzsJ!4YQGd z1_KGX0YFVDe|xlL@n5`VZL%*dnM=0~KB#wP17pXRvua9VAPYC0P2Hlo`N#8Jsez4` z6E`rET=fPPD{@~O$EgZ(auIM~PbUr}qXBx--2EjFj-{Yy@CWfwLLasfE9}_>bW$Gc z6qu9RzIJ&l&_k6BqG^S?eGk=0g0#}6mBM3$PP5Tp$b=Mg%-T@ _$pj`fC2Y}|}A+%Pc6`J3o{hYb@VR9L`_UFsbVe0Wp(=YE5I-llNPl(SIRVuQ%V z|M5CJN_BsxAf2uFpdh{igA#tS22rm!c{riKVi1nbLt;FK$Wv}Ip^%T;;ymv=mje|a zeGduY=YdUd-C4Z)KYf~|C@|dDAI>NQl#}__>zveSUw*$V@$ndPo>7jUd%s19lQ^^M zCl^wyA&@_~%(ZUj+rv-$jlX93ac{N+`7<;e0TUMvHer-_(Ziy<@T|yhJNM83lBFSK zj-NLu;O|N377@mc0)AYN IvB-{3ttn`A( zWAWv){Y4c7GMA_TRewFIplTc*rqNFY^EFHy>ix?a&*Ub%K%C1s_u|Pg01hd1Q-MB0 zIS)D;_j8{s9`S-MTs`g(DpKPQ |chBZTe=g^* zBF&T+5Nqw$+b}cFxb#4yZt=Z2c^V3vWn>m`&|iW3l|>t2$-N)6s9go08Dafxu9w>9 zb0T2VjtSG~;nngr0F02-ivdxdHhOOwTjyBm $2~*DUp7vsFx45&Y|Wh z=C-C;1Max^z^m H_5Sqh8WX(L%$o}D71D(4Y7otlkP};_>WUQb z-7dcs9W#j26$_<+2*DD!iV#v3xAGB)dCy%Rk2)mm?~KqG^6$`tc^e9L5KE*~Qi6YD zERHFT{p}$yq&8akv-kKj{f!}Y0Y6hPyVSLE7!ea82{*u@8XCoF9@bahX|>d|_ jf?mWfE zD7SPrpN2^1;{)hcXMk22Y#wf0yC;=nx59^ 7hi0<5#ut^v!Mgog?_i2eCHWhw9 z27XKj!=yI2z3nPZ{oEjAFXtG4ahRK0{;lQ%j6adxj{`1$^i-HVHe66jez;5g_;3n5 z RHfOgF^K{gtZ>t*6hRCeH)I&1}3+Fe! zRvvk5uT08Bm^G{-5bm=?$7Zny@ 44rDis7u*3_twP5kort(NDM>}&dE$V4I0X-f4BwBF<^pKx#3s#n8d zo?PR~q&;=0;r|4yXaMa!U;T&1R!xpSQHv2}!$Unk%-%|4{ m+puomP+Y$b ktZZO=Wn3W%*P8p6^ zwat*`PP!hoV_D_AJD+QdI|Y^HgQfnQZE!IayH1q7cMd}-55~^#55K1;6g%FZ%y$_t zWK>a00z)Hn4aS=1@plbRYw&VSxK8o#^h3oMs`xFs1uRjCQhx@fpx+8V5$uVuBl41R z2Jig-(S1Wj1N<=I`F_Lpz}n2Tn2P9zG62nA5v`7n$3`tq=fCH#ZG>XtN2w&MG#&J+ zUKkW-<|Gt@K9>mALc97BxRsyP7c<@aejQr!6)^=ImBpFvwhRwL#Y5H>CorTP|6_`i z59e3cWY3lsqbu`)9*9b3H^(WSv#>Ih)EbGbwohGVnC3g~USlV % z$dsT-fFKLT3&<56=Au=UYa#o;OyN(Lw1gy1uPux5(w48S01wJ=8NvXBbfrLZ{zQPs zjp0FiUD~k)&zc2)Y?*6+n(1uBIhz!+uC6Uje5@8%17A5ugu+@%z82Ax$?C~2roADW zOr`zOuF%&scE3rRbzlirgBuhBRcUwL_e|}AcwWl>zm(x(mu3X hv9A!fhY zLyB+QI(w}|T?%ubym%_4KqKLY$m>MGs!zorn%@N;zfFaB1=3=!;^kT4hWED( DF8k_`6v62Gl1Eq_*O z1UqU8YaQS7_nc%tdTKgu8u=f(csvkSo=pJ3wgSpZJ-0_G=%M5uU3=|_#hi`BH44FS zeBeQ*$*3kcqjBAL3F+2|YeVf3`Y@D*^^!?eNr@4nf}vO&^!V_<&a?vWDxr~um$%)s z9FDDYcfCO-w%{(9|Hl*s@IIbyRt>K`Q|M=OCOyr&)JAl0#$A0f+lR&bw9nE#8OM&G zi0eK<1@x30xlt`L?flTegWxO-2i_+_n)nWZA!)Wtnv)If)I{YPAqFj;81R`EHljPP z^Y9EEg7 h%CT#3_zo7!I#H=Krfpv};!Bb0A966u
qS6xIE`bA@4SRYpgz@9(O0YKYi1J_;9)LmW zg*)9rLExFGy9cdd%5VVWHzT{`pq@b5$JmIl-Ma;v=;$|=t`=!AGj)a~b}S59DgWbA znZ!;9TFKjgJ!5e!oOEhEJ!-rc!0VHm{aX)_4r9b#WJe}HB%^?KDf0UBsvy6tmP@yg zQJrO7hDF-fmKB-A0PA_Y0up@M*Rvb7Eoufb3JL)ME*7*pe|7Q+W`R<60m38Qo*tjq z@;4L&gyf3Ev!|mh(SN&(VGX|ht SY91DI6s9wJs);wmqBlh##{s#)6a_UrE?7h)Gwr5|p>MEO3i zV^4`3$a&q}_-^_U>}TUXt+pRrp~;&?eNd;Mxw*M7zg242NXgOR(Ph}0VsL+SJ1?g3 z@dZpsWJXPEmp4(OSikoiVg`Q1=sW*Rn$Uizr>>utKCg&kUY7P9qwvnPYoTNLPY# zZsF6NkhwNELclb59^JtG=BL2o${_4QLV@{SgY&0NFc2~$nBZ$vOWN;Jof}y|s=SV- z&QD|JO(NKHnkO>xMFi7*)~2ZmiX=Vn#?G5mrQ91a8@IjfdiTwXO?O#ZtkGy!ACJK! z{<-}1o89qbB3J2^b0ka2@L{>i*>O9K;;FxT^*u&96=E{wCF{46N5o`;5kWbl^iP+} z`p4XjEdJ-%xX)Da;K8Lz8Z+3Opi4EJgFmWafL#pq2hG$5K83%H#UcSIup#G({e06- zebSjk-aN)EX57sLD~yW^VY!^c(2g7yw9fB@VD%bps6O~UztlFSmD6V?P0K`|BPB$! 2ndDO+l6EtRrOyOUs8>Ggk25Ljm95WBtUM_?<(%SMDFQ(|Xr?(~_ZnNLqox4ir~ z-Dr4+iTpNfM_bIgXQCnN|2~!9%;osPWHc5)=DixC9zl=SEK@E0Hz+?+J#+AA{VhjP z?Qp2`RFg}xvKJR+5peZ0;7uy&THD#N^}a*NxgV?n2P2ifs{Defp;^~x?!GP%sW*=G zUjT|-SGeVi?ZY6pSHoqk`8s)EG(e!d8#sQJTv=h$TJSUYb9+w|7I$bUeyCn(i}=x$Www=p(nu{1SQ#Mll-sf517$?nx87VklEOyVG?G_@Xw*+_L{VyMh8ul@Q>(Av{~| zfjDn6Ch`Gt6kzgE;GnJ8ao1r*Ao}g-lT6N=nlNV%X3B~;+{&4(J<~<@`xM1-9^N7f zXf+X8DDQ=8%lWRmIUzMn%URTkvq%H91D;!@udK2qPbe$gPqcc!;!b`6d_W7&mIs5H z{d@w%!T9(+0Qd!<;fprAP)m5KU>qovhVyt?zq D z<>?zDe}EL@zQqFNpxrlUWwQ|6N_YXI|2Fx?n;CVjzwRC;P|dg#Y!${t{wbiED%O|N zwRFWcfSp(Bt-x*QRJl@}TXyhh?MqSeq<6!KzA}&YNICvXWQ(ErgR)1Pn2R6avcM!- zn2HLt8EEmhT@tS{TJGeO0LrkQ^ZWtB=^|NLS{jp<3n}Ao{c?%h9WgTSqyAVXHdaF{ z0P9!%jnOdqFz8={KhSI4|2hSok(IKpho4G|=G2i{ZqLHylRPlbOBv*u*B%k )zUTF?QqDc;MSF*oYjzVM<&iEt48+B+X JUtH- 0x{uF zJjF*nW(QJ;Jo0#%Y2YC4mKw|-g |*OW^;U!eC3{ji|gY34o|&z=kS)H ze*-bvvp`4q4;3+$b&9$6Vtt+=be0k-viBd&7kQn8*tb@B--db%x6R*R1DTg(c3pi! zuYKtkY3YRf(w}bpqF~1#e&W1y{~&;9#nKs=tZb5`JEYJ~0%PX ()pvEA9v5*L+X zQwJP7@fk`TSxs3jfB)U7e6qq4V)^ku7_qykGl(9 >)YBleZt)a$dll1eBE3}sSGAZ @vzPwN$*Kv6>_d9-*WhMVd5C%m!}_h-NE1jM zp}7pDlHtBZ9Qdp{$|g^UM+OEXt{{#v7>QgNJf+Uc;w^?5J;uHvlEA;OWoqtAB7>iL zT*w`m_2fO7x!8IoqGC65Zi?>l!0w~#E2U8Xll-ZTB4NC=)y=@$!RKc0 S}6W@g~SS2p;^ z=y?RufWjn;iL@IwSXNL#rS;w4+?>MW+C(lIy}WBD3NmZw! Vsi5Ffrg{>B}w5Q7k5aWii}&FS{G z1bB>afx}|-xF6D c9y^>7t_r(KdVmq JP nzH1 zGOOGDBVctRVRTQL`-TFt6XoR&iDIrXUlQ 6#X5+23R83p6hz@lzx1r&rJV|I1y@aGq>}li4hm*BBpk?zTV@j zLKLdz0PQ@BiP>0YV`(mgiItw_R;n-)CDE1eZhN_2BVVGN&!3Kj%a%^VP>iwew^IOY zE^V0)`q}+L@wh0RF5Jme>6Hin*@|E)l6nuwMuP1b8dBHIvD*@_ca@WmKj=I9vN@FD zST`=8+#