From 7afbb8652b3d54c4e8cc0851e71a8c2093bf0745 Mon Sep 17 00:00:00 2001 From: mateipopp Date: Mon, 6 Jun 2022 18:31:00 +0300 Subject: [PATCH 1/3] add ideas --- README.md | 138 +++++++++++++++++++++++++++++++++++++- img/cloud-arhitecture.PNG | Bin 0 -> 25892 bytes schema/nat.png | Bin 0 -> 13915 bytes security.md | 120 --------------------------------- 4 files changed, 135 insertions(+), 123 deletions(-) create mode 100644 img/cloud-arhitecture.PNG create mode 100644 schema/nat.png delete mode 100644 security.md diff --git a/README.md b/README.md index d923cc1..a686411 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,137 @@ -#Connext Router Track +# Connext Router track security advises + +Here are some few security tips if you are planning to run a router on the connext + +## Unexpected Docker/UFW Interaction -- Securing the Router's API Endpoint + +Please be aware that Docker will by default override UFW/iptables rules. If you're using the Docker Router, check that you're not accidentally exposing your Router API endpoint externally. + +**Example:** +After configuring UFW on a server running the Docker Router to block `ROUTER_EXTERNAL_PORT` (defined in the `.env` file -- `8000` by default), we expect the following to fail from an external machine: + +`curl http://x.x.x.x:8000/config` + +Instead, we receive a response indicating that the port is open. + +`{"signerAddress":"0x26Ad85....."}` + +One simple solution to edit the `docker-compose.yml` file to bind the exposed port to **localhost**, by changing: + +``` +... + ports: + - $ROUTER_EXTERNAL_PORT:8080 +... +``` +to: +``` +... + ports: + - 127.0.0.1:$ROUTER_EXTERNAL_PORT:8080 +... +``` + +Restart Docker-Compose after making the change. The endpoint should now only be available from the machine running the Router -- try again from an external machine to make sure the change was successful. +*** +## Admin Token Best Practices + +***[To verify: is REST API still implemented in Amarok? Doc page seems to have been removed]*** + +Each Router has an **Admin Token**, which is a string chosen by the operator and set in its `config.json`. + +The Admin Token is used to authenticate requests made to the Router's REST API endpoint and must be kept secret. + +If your Router's API endpoint is exposed to the public (see section **Docker Port Mappings and UFW**) and your Admin Token is compromised or vulnerable to brute forcing, you could leave yourself at risk of unauthorized access. + +Be sure to use a sufficiently long token (50 characters or more) to avoid the possibility of a brute force attack. You can easily generate a secure token using `pwgen` with the following command: + +`pwgen -s 50 1` + +#### Optional: Move Admin Token Out of plaintext + +The Admin Token is stored in plaintext in the Router's `config.json` file, so for additional security you may wish to follow the steps below to load your **config.json** into `tmpfs` before starting the Router, and unmount it after the Router is started. Keep in mind that using this method will require you to generate and move your configuration into **tmpfs** on each Router restart, and the old contents will be lost -- so don't forget to backup any important information first (e.g. your wallet mnemonic, if using one!) + +1. Create **tmpfs**: +`mount -t tmpfs -o size=100m tmpfs /mnt/tmpfs` + +2. Move config file to **tmpfs**: +`mv config.json /mnt/tmpfs/config.json` + +3. Change the volume point in docker-compose (use type [bind](https://github.com/docker/compose/issues/2781#issuecomment-441653347)): +`- /mnt/tmpfs/config.json:/home/node/router/config.json` + +4. Run `docker-compose` + +5. Finally, unmount the **tmpfs** dir. After this step all data in **/mnt/tmpfs/** will be lost: +`umount /mnt/tmpfs` + + +*** +## Setting Recipient and Owner Addresses + +In addition to the Router's own signing address, each Router is associated with a `Recipient` and `Owner` address. These are configured in the respective `Connext Handler` contracts of each chain. + +- `Recipient`: Whenever liquidity is removed from the Router, the funds will be sent to this address. The rationale is that if an attacker were to compromise your Router, they would at best be able to withdraw your funds to the **Recipient** address (which you hopefully still control). We advise that the recipent address would a hardware wallet. + +- `Owner`: Only the **Owner** has the ability to change the **Recipient** and **Owner** addresses. + +The **Recipient** and **Owner** addresses can be changed by calling the corresponding write methods on the `Connext Handler` contract (`setRouterRecipient` and `proposeRouterOwner`/`acceptProposedRouterOwner` respectively) from the **Owner** address. This must be done on each chain supported. + +It's **HIGHLY** recommended that you set your **Recipient** and **Owner** addresses to something different from your Router's signing address, and to use a hardware wallet. Since the **Recipient** and **Owner** private keys are not accessed by or stored on the Router, simply compromising your Router would not be enough for an attacker to access your funds -- they would need one or both of these keys also. + +Please be aware that each Router's **Recipient** and **Owner** addresses can be publicly queried from the **Connext Handler** contract. + + +*** +## Protecting Your Router's Private Key + +**A little more research needed: any specific problems (eg: griefing, double spend) either for individual operator or network/users that result from a compromised Router colluding with a user? Or is it just best practices?** + +Avoid operating your Router with your private key or mnemonic stored in plaintext. While it's possible to use a mnemonic in `config.json` or stored unencrypted in a `key.yml` file (as in `key.example.yml`), these should be considered for testing purposes only. + +Instead, use one of the supported [Web3Signer methods](https://docs.web3signer.consensys.net/en/latest/HowTo/Use-Signing-Keys/). Using an **external KMS** that explicitly whitelists **Web3Signer** will allow you to move your private key out of plaintext and off your Router server entirely. + +**Web3Signer** supports a variety of external key vaults and HSMs. Consult the [official docs](https://docs.web3signer.consensys.net/en/latest/Reference/Key-Configuration-Files/) to get started, but if you need help getting up and running with a specific method, please feel free to reach out on our Discord... chances are we can connect you with another operator who's already gone through the setup process! + + +Whenever you are joining a crypto project we advie that you should use a brand new wallet each time. +You can generate a private key using the following command: +`openssl rand -hex 32 > private_key.json` + + +*** +## Protect Your Router's IP Address + + +Consider using a setup that doesn't expose your Router IP Address to the public. For example, many cloud providers support features like virtual private networks, private instances and Cloud NATs. An example setup might look like this: +``` + Router <-----> Cloud NAT <-----> Internet + | + | +Key Vault +``` + +To connect to your router host machine you can use a bastion server(jump server) to access it. A great tool for directly access your host machine is [teleport](https://goteleport.com/) + +To have a deep dive understanding how private network works: +![ALT text](schema/nat.png) + +As you can see in the digram above you can't access directly your router, only through the bastion server and then you can connect to the router host. Router is accesing the internet through NAT using it as gateway. + +Using this configuration is less possible for a attack to compromose your router host. + + +**Further reading:** +AWS docs: [Private Instances](https://aws.amazon.com/vpc/), [Cloud NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) +GCP docs: [Private VPC](https://cloud.google.com/data-fusion/docs/how-to/create-private-ip), [Cloud NAT](https://cloud.google.com/nat/docs/overview) + + +If you are connecting straigh from internet to your VM using ssh you should consider the following options: + - Use a private key to connect to the VM instead of the password + - Change default ssh port from port 22 to any other port(for example 9922), they are a lot of bots scraping on the internet for port 22 + - Disable ssh root login + - Restrict ssh access using iptables(ufw), be carefull you can locked out outside of your VM. You should only allow your host public ip address to connect to the router VM + + -Documents (WIP) related to the Connext Router Track community bootstrap program (Amarok release). -- security.md: for brainstorming some security practices for new routers, which could eventually be merged into the official docs diff --git a/img/cloud-arhitecture.PNG b/img/cloud-arhitecture.PNG new file mode 100644 index 0000000000000000000000000000000000000000..39a53ee43f0dfde3a4a38c0b0ee048b18a4a36c9 GIT binary patch literal 25892 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�IKYjNI|a zxt%t5Gm_!Gt1$5-U>aK;f*kT6#q`e&tyntP3lIn^F#Oz5SnFWU_p)1ea@XL-*Dzj> zC6ZW!BjA6oAFt_ys><&Mq802>1d$sCGS2nNHUKP=C(XP(Ub}_Amr6-XXN*A%30ksirrOS->0jl!wu{$}jjkopK}=VD<~6_yFD3 z(@0bp&8Tw&*|XDefCksVx3LtQXQFaz}*-98M znABP#h+uX=bkN#0q#CFKKjf0bvw8sA+xvTfl)6>0Rrfk`{rg4DKP?Dn@x8JI6O?kq z$U3RdO$-tfV{TL$kW>E6jH^bzQ=Q<(*+Err8d_P5lA_H1srvglE4ZY2ebhOSht0^j z-MxnV-589YDF_=YPMvx66J#?Kgc5UnE?$gLj=a@>mERcx)L&rqLf}t^AheFBYwqNN zDKf29Er6B$vR-B~`Xa4xz5JF-@lHN|AGy1fUKN&=$nM#KC)S?14f0}gtUG5=y)H3|El8OL_~*qlv6(Qjak4LIeI*Y@efdnq+9>TJJP+1& zV^!a=e&r)#QNF{VszA8khwJ<6+kVIOz4~)qOjUpgvoOuDLp?~s@jNFR5#bTJHdGj% z0vqzG-KsxMx`tS*Xe25@itG##iDVCJv=^DJM>*du0sIfUAsO6E)jR1aeTlhd`X%i{ z2|J+(37Q!R=F;GsuqTsPPlGARz;Mw zbkYLJ*xb>}dQW)YuPl4sD$lwUuUF&~euyq`v&#p7F0jXW4dkIqI*Aur4nRsc31(ve zLPEhB&9ZG_lMQCeqe2WXQ2@Bssb#L1gQeTqiVA@ru@x=}TW?tAB1DA~Y{R=nk*f0}2vLhU^6@ zm0$t|XtcqE(Z@a=Ahs~j$O)7d&Omc%0KioI{##-A4?re)^8l)+imK-PFbI2>PW=K) zJjWo1RtCE8LXvH^*dfA~kq}Ubbc1+>lND})qdpdTOrQq?;~qcc_u!zBfNop3+V4+>kPk>YU%V@ko-df zj*>tg)eb=YM2GN?RRZLNFB}4heUZocju`3`;uF;QVn+bYJ*R-ZY6nashfgPWK-F^v zh;GhXr=Q5C_Eqai8?0|{wsL}w=7p0B3$P?0UoO$hW|i2*4HuSTz+kZ4lKA50 zK(q_g)E5d3z>Nfim*B7eT9Vjk#O>mLb}$7RTrx6wOUhD4Frxt~?YQ>WOToKA9}sUZ z7F!GiAYXwVq5nvjK4&uKw>qV9$>h&v(&eTvZ4Ussb}+-sa`^%;u_a&#lcJ!vp9TT! zNvMS=&UoV02T(xU~B?kw652hi7vKw3r?K|ZdCw>06^||wg#FrnOfkHTdrFQ<|YA`uxyOZJi2ss zw7np8c_T1r*n@Z`PTF%7!gPVPw0!Qr1AWLB(hajdF+Yoj zXzr(0&_X;9TLP3E^a4A*FgF zI^mT;>!wBqai=9=EFS=cc7za3=#vO0=tI8OW|&b1gJvOdMqAI2%}gh*aYjGbulH_! zOuLR|ovgTGZivD(F_P(JsmL(Hu;YeMxowdW#t*dC=Txu#bjDZ7m>AOtFaZiGC1GVS zDMx_vW3Y<$1766Xn8-9}SS!>V&%{FGo!H@t!=Nq^!qklTuz#0wW*~g_e<#Qe zD$x#X?e2^*ZP#>j41f>?<~wa3?E(|pxNAt5R!6&V|FVff2tfn*A0X$@5lFyS80a!$+5*ly3>p zoZM2NOcNMT90v4<3!N9N5QScymY#B&tjyC4x0@u>6i`6yo0zsRWt@aIrns!E3pWbb z>W-d@yHlmT&B&m~yI~*bn8^t&{Jq;vtU3LKU{?CSSH72L9?K2bLRC;;{u#(6mV4i& zioPUYnIEvke_s;C{F@$45Y|peNN@*P!DoZK|G>)rvo2^^n8v63%rDQj>cQyrW@x%M81en3VeRm3Umm~F@WDzZ xDcs|a|Hgk-LvU=$l7AY*XfnxWn!D2M2lZ@2lcIXj)B{uh1U1;GFS literal 0 HcmV?d00001 diff --git a/schema/nat.png b/schema/nat.png new file mode 100644 index 0000000000000000000000000000000000000000..32c63f3abfdcea5e380962d576e772516c4b1901 GIT binary patch literal 13915 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 R{ Cloud NAT <-----> Internet - | - | -Key Vault -``` - -**Further reading:** -AWS docs: [Private Instances](https://aws.amazon.com/vpc/), [Cloud NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) -GCP docs: [Private VPC](https://cloud.google.com/data-fusion/docs/how-to/create-private-ip), [Cloud NAT](https://cloud.google.com/nat/docs/overview) - -**Potential contributor opportunity: -Write a guide detailing a mainnet-ready cloud setup, and how/why, for points** From 3fadc241d9cf848662c76209fa09ad710bab75b0 Mon Sep 17 00:00:00 2001 From: tibineacsu95 <81976900+tibineacsu95@users.noreply.github.com> Date: Mon, 6 Jun 2022 18:44:52 +0300 Subject: [PATCH 2/3] Update README.md --- README.md | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a686411..a3f7cfc 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Connext Router track security advises -Here are some few security tips if you are planning to run a router on the connext +Here are a few security tips if you are planning to run a Router on Connext ## Unexpected Docker/UFW Interaction -- Securing the Router's API Endpoint -Please be aware that Docker will by default override UFW/iptables rules. If you're using the Docker Router, check that you're not accidentally exposing your Router API endpoint externally. +Please be aware that Docker will override any UFW/iptables rules by default. If you're using the Docker Router, check to see if you're not accidentally exposing your Router API endpoint externally. **Example:** -After configuring UFW on a server running the Docker Router to block `ROUTER_EXTERNAL_PORT` (defined in the `.env` file -- `8000` by default), we expect the following to fail from an external machine: +After configuring UFW on a server running the Docker Router to block `ROUTER_EXTERNAL_PORT` (defined in the `.env` file -- `8000` by default), we would expect the following to fail from an external machine: `curl http://x.x.x.x:8000/config` @@ -31,13 +31,13 @@ to: ... ``` -Restart Docker-Compose after making the change. The endpoint should now only be available from the machine running the Router -- try again from an external machine to make sure the change was successful. +Restart the Docker-Compose stack after making the change. The endpoint should now only be available from the machine running the Router -- try again from an external machine to make sure the change was successful. *** ## Admin Token Best Practices ***[To verify: is REST API still implemented in Amarok? Doc page seems to have been removed]*** -Each Router has an **Admin Token**, which is a string chosen by the operator and set in its `config.json`. +Each Router has an **Admin Token**, which is a string chosen by the operator and set in it the `config.json` file. The Admin Token is used to authenticate requests made to the Router's REST API endpoint and must be kept secret. @@ -94,7 +94,7 @@ Instead, use one of the supported [Web3Signer methods](https://docs.web3signer.c **Web3Signer** supports a variety of external key vaults and HSMs. Consult the [official docs](https://docs.web3signer.consensys.net/en/latest/Reference/Key-Configuration-Files/) to get started, but if you need help getting up and running with a specific method, please feel free to reach out on our Discord... chances are we can connect you with another operator who's already gone through the setup process! -Whenever you are joining a crypto project we advie that you should use a brand new wallet each time. +Whenever you are joining a crypto project we advise that you should use a brand new wallet each time. You can generate a private key using the following command: `openssl rand -hex 32 > private_key.json` @@ -111,14 +111,14 @@ Consider using a setup that doesn't expose your Router IP Address to the public. Key Vault ``` -To connect to your router host machine you can use a bastion server(jump server) to access it. A great tool for directly access your host machine is [teleport](https://goteleport.com/) +To connect to your router host machine you can use a bastion server (jump server) to access it. A great tool for directly access your host machine is [teleport](https://goteleport.com/) To have a deep dive understanding how private network works: ![ALT text](schema/nat.png) -As you can see in the digram above you can't access directly your router, only through the bastion server and then you can connect to the router host. Router is accesing the internet through NAT using it as gateway. +As you can see in the digram above you can't directly access your router. You can only do this through the bastion server and then you can connect to the router host. The Router is accesing the internet through NAT using it as gateway. -Using this configuration is less possible for a attack to compromose your router host. +Using this configuration is less prone to attacks that would compromise your router host. **Further reading:** @@ -126,12 +126,8 @@ AWS docs: [Private Instances](https://aws.amazon.com/vpc/), [Cloud NAT](https:// GCP docs: [Private VPC](https://cloud.google.com/data-fusion/docs/how-to/create-private-ip), [Cloud NAT](https://cloud.google.com/nat/docs/overview) -If you are connecting straigh from internet to your VM using ssh you should consider the following options: - - Use a private key to connect to the VM instead of the password - - Change default ssh port from port 22 to any other port(for example 9922), they are a lot of bots scraping on the internet for port 22 +If you are connecting straight from internet to your VM using SSH you should consider the following options: + - Use a private key to connect to the VM instead of a password + - Change the default ssh port from port 22 to any other port (for example 9922), there are a lot of bots scraping on the internet for port 22 - Disable ssh root login - - Restrict ssh access using iptables(ufw), be carefull you can locked out outside of your VM. You should only allow your host public ip address to connect to the router VM - - - - + - Restrict ssh access using iptables(ufw), be careful because you can get locked outside your VM. You should only allow your host public ip address to connect to the router VM From cde835748f37e0e691a45b223a57ed3579891e1d Mon Sep 17 00:00:00 2001 From: mateipopp Date: Mon, 6 Jun 2022 19:00:26 +0300 Subject: [PATCH 3/3] remove unneed folder --- img/cloud-arhitecture.PNG | Bin 25892 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 img/cloud-arhitecture.PNG diff --git a/img/cloud-arhitecture.PNG b/img/cloud-arhitecture.PNG deleted file mode 100644 index 39a53ee43f0dfde3a4a38c0b0ee048b18a4a36c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25892 zcmeHw2Uyc*+pks%SXtJ}kXdb|6%Y~GBaK$ks$d=L>43@#$evN6P(?v&#eonNmA%9e zc8rK9BN5p%AVQD;K>~!3b)J912&nJ(e((35?>px@=gQRvNdD`2?)kfa_wB_)=4RsG zZ1`ryiWTDf_WpW!#fnu?D^{!|hzf(h)Qe%Az}rf{!)7~I+qG{(I0gGsA|((8 z-IHntUVE0jx9(O&ISYN}AQQv#t%h@Dg|rXn3t6d(Qldc|3SsS@ND6 zYc7lz^>_CV1uyrd?+*SsYxK6ZzI%6^+p6Vp`gD3=sa!H z+3-Q;lb`BCRdYr6+&hxe2wq3POW>XI;5vNUS4kU^l)!7ll6Oa$B(bQqLrp`I;MKJB zy=3VBm}S}if5D>_ZykAPZxl2(!Zmc&*t)gFJII4R*8QK~yF@m@tNm+A%PER*YbN$& zbB9Qd;pnsKt@=KcP!SyMoM&w&1$OgWx`3=o7gz|$R6$p}{8-DWR0mAQ^s`k?W8%&f z^V&jnX?aO!sgc_Q%mRr8A+W786_DY2PjbD?`(3?X>&bAPh63UwT*RVGw8M~b@CB_{ zcBOWM$X8p8l#4>_rk}lA6)L43{rV&6a0j!n5pSh{>OnV$Rrz8HCNwh0UM^DVZx-}q ziGFzL8pYnHlr^-{Uj|r;;Cr~a6%S^vAi}ftip0fZ#YOPB4%d<_8R3OVG8}bb{MiMS zTB=Ig?ZrhuDwk!fvfY;B7c8ZqI6e^($11KD#wQZ8C9bX{ZLoc?pc+e5qT@iIxuK{u z4mnO<6UJ1J#&Xoc4hrL|MlM;2bCQoSGNZ(z{B2UCacdu*&Z7dxfEJM&I|o!BY0@@&T`5 zlFn0wS>eJdO@n+x(P)HZwnV}Jny9kZZQZ;La_|>WvP1^q-LbMBAIq!~gj}{*RPk_t zkVi#1?HP4MGJy><;zpoQ&O_>srxc31r7LuHEE>)wt0QP-c?Prfg8WSnU*CK#A@ZI$Il?^zN~iiU{V!F}fBu;pR;bte%bk@a|Mc|JmKCPM`dwLxEfgv~^(raL`UJ z|EXl?z1^;Vx5xZ{eiJ($COL6uTMJ6ZO4OXU$`%#p4v6^EfjtMoy zqT*mcMeo;|LnKae*qGd`HHPMgX4-QLRng%SZ>oi5lBTelRv~tVR;~9(SS&J(g!A$w ztHKzsJ31wDCJOy?wi;3p7UcIy0m^=vCB$2g44W^t3&uVkrNr^wBYz(;f1S)8aiinL z9l}O2Rc6&{h_Lt9%%tsJc9w`oGr%dTokb|+7db~3RhQ%y%= zvr}rAe*G`6usa)zGs-lQGKaFvRFhm9iaXl(1faE!rhdD`>4NZ#b0LovMeioDyW97v zCjITzS(rUD6x;UuFXYUXYC3O{CXQqTa$1pW zD{dijTm*T@Q}I|2TE;Qhg*)w^^9?q|ukHSb80m~XWpA|oO@|TmxczSB` zmO@=^o;6t-kj^{Ge|KQ|s3oM+3wz2fDZq02%`VCHc8RyA1cP)hdNGpA8R-e5)+5^@ zh{+~ZEv`kd#Uui=&oHF*&^eK-^BF|p)2DwU*RJt!ak<~tAto59>F!fS-Fvob?|gWE zLP{X;e%w&(DuU0uerB|*xBzmIMMc)YMUHFy=JJV)%%l+Va3|tTbeSK}oDU=KuUq7l z*B4c>m!<{>-^vN&$8{$6JIx**^?I3YLw&#g%gM)on<>3%OAcstxQXkZj-Yp2d3w3F z7zu=-f~nM_me&D7Un~9cx!k2^2S~vF$XE3f&8jt zOq*4)U$cA%WP+x#NG5ifBrQFgU{JC@Tbt$C>k!m^W0Zu$wRO~G1qtMeYT>oNcL!oE zEiHM@8eB)+aO%MkO+)sBM$M%^<%SHGP1LB-l(XCNPni8v{Qx-u14S z3&a1V&j=#Q;oCYZBEqJD)JiW`w&fY|KPQy7oe`$M%eBu=QD_0rSF0|!ctZ+RiwQX} zaFqcUo=cX*VDj<~d3r@N7xIFXBZ&`b1S4wQ*0S;EBMoNC8p};l$JllFo5dVEagQo> z!aF|lYnWYq5H#ht_l(gKrRAMpV!$;6H zB!+r8JQlyqu?%byT2%Lrw{H(~cB^MyxNre@sV?*)e9`d(h&I2HR9S#nmTk%sE4zle zar&`d`Olq2z9$M#H$MLKT-csa56+Yy2$6tBf@I^r3oj{eGOYaZ76`5jQqhqmJhlFU z!0*q#9wfd#c*W_@0Y{Ahs`>7VpV=3noQr&mrDbH8xHy}>omByy-QSQrJ$_@=VNYv5e&R(tJ=Eu z%ZvPvHsD|T%->y$`OhJ6z&~~2kjO%h)*Me@3EGoQ!Y(b_3jes{ix?-^x&8b1Gl+WU zKVtw>{JvX+Ji(byE(=jWTsxu{*{}D6%O-L8=8^K;yawY(CUA03v;gpOG!Xk7`_ly| zZCv7sa&wF-IdLY_ZQ)7b6R$B?IcyP(4SA_4$V-8ra`zc(mX17ODIZ3ZPqlP(UbX|a zL+w+1@^McH?Q1sGC(TZ#%f2h;5UE(BwD*~pMX5WB1g8)HUc?^G%z4$p8jb5Dud+(g z?Fj8De3xQ!kV@=92jI`)&LtDZh(5UWXur+~;l|)D;O6cZh`c%5r1T5V{|Ml+BH0D9 zLYb?a4oMt9t#WKl(n|_+-fQ$Hs<)8#yccU&G&L#QjvqZ}l&URidetjrYIwXO5RKoV zgcXb0sV8~QCEesKPu>K;RSDZvSs}@zQ^Ijph!2v-9fFja;6A?l13QXZYO3!9ZWn#I z`U)E4E(PN9x>?0R-L8u}H;+#1PMI5sS~|hQR7&4BjepaZ@NWInGkX&5WjCXiW9phBg zzXEqyY>u!4ovQ7GD>k=J0c#H zf>j0(RfE-96rwBG-1MoZjk@kp$8)vK;adZ8MW>@1&%rVk;>}srk4lF%+yLCHk*$DFwL) z!Xo%p6EHuYL$y!jb;Y?A;kV=&e$gU#oli6V)z@k%Tz|Ffx!?i8WMIYmcN zNYYa-e78EOI#)~*fq|)!oxqYF&BW!FJP^jOWW%s+K}{<9<26o5^jeg2n^`1M8r9p@ z%(Z{3B$Qh`cxNQ9QlfUOoZj=9j7}Nkxt@)W54IbS?_PKCZ`dsmd6wUgP(?rkHRa4;G?Z>*V+@l*u9Rr&h^6Eb0k zBt)+*WM*SfoQ(VP!ZN!e-$A~=K`7ScQFu&)pSQw@z2e#EzjMEp@KmO2M{PnQ>Zh;a z?Ai^D?XSoSg{^W3kg`|osflReUcM(M6pLP~zzGw}K;o9KA24HLQT&=l2b^Mj64iUo zPG;8;*|XlV!|KAf@8i?DbXjE0NS2kPrxD_hvo$eU_pJz*NOmEZ+%ak)Jib_IObj4{KZ}~2>0`Qm)yUbu%XP-9*Mty5le){xT#c|;O&-nU^2EsXfu63VZnuH0Lj!}E!q+x10L#B)5ow*Wj{*GGshb0bI2CK#A zVKj=^v>XA|X%>c=y)eII`;Drb(B(sI$DBm}MnOzY6+ zbdg`+fxx`yS872D*#^M8Z%Aj3V*fXQt%L@2gPd({$ws@&VKskRb9399T?BRrubCCll zlt;ZZTVI)OK{=0Nqb+e&1(DmfTp;w2(-5szBeYAo;yvgTr0Rf5(WxP?_hC$HcBw`r z=^QSmhrBJk)TKG6&n0Yzu55k7N-LymuKIT!VD8@-pWQK6lEh#dPYdH~)S|Rd&NC62 zxzo*~z*beEwa3G{uHFoiupciTYkv8?7OM9aaUg~3!0FDB2-?)W3+a~W;Ix%WWYN;f zCJe{vzgP8J@&Sg#hu7hUdRIQ2uT4TopkR)4JKJ1GR2sHvCPQsYr9~y&r%}9$E3-w$ zWh+9@TPllWMWrd~^-dYZ;@yLfakEwdJ2Xo?h4HH+ojP?-Ucps_O1u`aP4w+)P}=zb z&?r!^fZ~rM7ABvhEg;-0$~k1AuN(a54N;FNKVWv&5j}|WJgM|%ovLqrwRb~S}8eS480kh!Y zEv2CCbBs#71s}gFpUJ!|Cxlan<@!#Nyz;rLm?O9?a@wMnB4w-YNJb5qTESvwt5o#= zoU79=&Dn<(6hnoN8I^|Z&Kp$;t{g|(919O~4?xFo*5hkbth@H~03-C-``AN<%L>)% zxuuH*#|*j&RZE_N57ogOY0NXt#QT9#>ZaUb75xb}X=G3{dhOq+-f>c2FWca4t;*h1 zI4{8_bb6O+7*Vncp2R4H0>A>~`~qQbiZ*!2klooVwu?^&P>o89Zl7b`@_M2zoaCBA z$C@eXbSK5GOQX9`w)tMYZr_LPB8^8fJB1?=2)p{y=sWN{9B~ygk_)UH$5B#N?yl9x zqGmp#xB0_+hg|~53Q&j33PPykc|W&)t!E{2ujiij8Abf?*`r5` z?eM&^b(P;BVhv}w2d#qlH<$eLd902_5_;x^>IB?}Oh|&lN?rnY{EM~nM=cBs?xaP# zZ?)ph(GE=Jv~GV(R?tND{r_Si90bc^q>hPni-;|qB>^6R?5S3nWytIDyyj*?!Yp;V z=u;TtKZwFZx&vAVoQ$ZY)QZnI`^wTk%Rd}M)aZJ5-2$Lj`X^YIs?6UqUrZPOwQQwv zsEj?`S>Q)7P!0PGg!V}(@C$$+glGt0(f=%WB0V4)EnY^+DSg6b(!rwNo+1SFy&SN$ zw};B{7uKwA^$G%ThyetPsEyEwoDrgJHUN5Z0mFid~4uJFUg`Zb-5PS@lG0@AKz7fkWMASPS14{xK`eG|#%A$dvKg zA~5vr&3C?k`fanklv!_J9qbKUP@~~E#^k>69xR(B9xYUp=>fWBz1l#3Trr#hARGCNGw(M2PBHus!^D|$N z6^i-7?Qayu1BS#e)v`i5hM!Nt4}e0+pWlI%q=?OCF0^<-fE#0{Jijd zoe^6#GzL@)=g^Sbz;iFXOOGkzbMuePi+q3a6IiIc02kGPj$%JIh&co*>_D#j?EZcZ zF^62x#1Mj?zUcP`)e3$Graf@e9+-F!%;B)e7B9q;p(aS)m!{>LKa{=yYrm|}wYz7e z%BEWEJd|7eTZ|QB^r7{-i^?9L2|2D6GJL7V-R%R(N+VH3SCLj{X%GUa$7vH-;&CbP zBr0hQ>7drIY_poaEV|3~KAiQjy5L}|JVPu89#9yrF>>8+8?ZAzvM7}|TEg%v=5y5u znfyFyX=wo4eQu-HeSCH-RWW!)a)K8CRDNv>>?s+EN{r>+)`_)y(&$+JqX+%f{&kQs z1eQU>Ly9$I2HP-o!KX(U?^CA1P0pk|&6Mc7Ha58CNdVbPjicI@;NX)+FOKG!CO;$5 zXmZChTIfl|3BNlcPc(A9gG@z*@mqxPzdltGs=OD_d(J2mZ(@$OD6s)}oMU_#OU z$~IB+^U%UMZ`>oPo=KW+G%Eh7_1V5XQ=Kx=!Z|%uCwB1Ey|+gB`lA^dnb=w+62+cQ zkN8e?>nde*JHpB270*!H45>S<7o*tWrtE0kIC)VyA*%spc}7g`u@*ePXw;wTyy(E(L}qk1NOXw0`sPE*072SD7M-$2)tkQAI(-!B z}fLQ zdU)&2DkvhmWV@@wU8EEW|55G8z-aK+30WaE?w!Wc?q~b<)~i?}9~?IMqe=1CC|9Oe zVf?$mO-$>~=kOtHBn9iP-0J>lnw8brbFv}5HOrsViDP%3BL@d3OXi+YVU3bFqn;o< zZ$EX@A%V*c7mw<|7R_Hm_g9b&S4Stu>X2QEhtZ9pQduxfdA8XjEo`E;7Xkm=kM=mxyC#y|iZoFs z40~&P*UyH01&IqzzZL1C#5fK+vtk2MMV3<@pehZ&&erX&K4(YhQ<=FAV_a_!3a<`2 zX{O-&Ytt-;%H@DUnquTk9|qJ)aEQN1cKj&NW|&ooU>4rD0t`(emqjFVlbBXQwf)CO zt0jJlYi8q0hhewUNp@jnN~V_aCM}lcTg)n=-w($#J>*dL9L1sr{Lc7aF}83QDZ4jO z=58b^jV2B`+nQ{xBhiY?frDI!p81tSR|q?BivhMU?DeDR?B8gUUaQMB2?s^+=Q;sG zR-H2;bPw#t81{pyMAsQ}5xkoz?KXo{CCTZPbR|Yk7Zk{p5AAN(%-q zk74vulF5^v=|XI?cMv6s8tw*g`ktwrpn=S>6W$;_xAq^_QA?r*R~tQ{vIx{HV{8~j zju^a$L%Lb^{znE?9Oo*f9)JB^u)PApBR+PMDjLP~K{?mIKAC>zaJn$QAy>phhO{B0 zzSE%XY6(7*6?69vxowDHmwv|dnBw@EdJ%knEZk>rVzpPWH$dE7Y(-3k@zbb#FsTEk zqPhlcb^R)`N?07L7T0C;i%h1muabRVplXu;;lQzCvMZ89MkYJ>)$3%NKTZYyPz}?6 z$Syr78Dt!r;@c;h@!M8J>;1iYMh?I7#=2L&SWI;lCo^V%8i2YtqphZT18`Ys+eLc- z@qppS=!;R_TDW5!;9FX=kf*!0Su1wUZXy4M!Fm9Am(4gIb8GXVyja zjb0avI!M>z1bWyoio{{Nj_Iw4v&#*s_jrJ_76B1vVUwzp*46;N_< z6>S{{0?>WFGvy>^IlJ1`0Nmu&pGBU1i|Wnj>pxk)+A&AAq|P^gnh5?f)Os~}nA};a zi0U;i-zZxl&Bk%*+zF(==d8}=k?W93uPi593=|)}8*@d>xfzxkcrVjH>2g;Nr_9rz zS=3p7vk=wm24l8+Rz{1@m4Ob-vOG6IG=z(??2V4x^WOfY6HeK}l1Dd*6uuV5yE1=5 zI@y%hLlv7n(Jzfy<$j1<<>GU_*8 zY;Ur;E)_hTt%-%R)PY}9R#MM4bc!qNb(at=A9WGuCa*%iJ&AHAjP{?Mc%L>%w9gb) z#s-iaWqQtTVqrti)SrFWkgk{o-&S^9%F!e(>~hO(B0Mj$S+PF@D+%m3SH`Rq8Gly;dyun;g@vtY2h#Lc{%Yf?>#F4Vz#sxp5xE z5Mjc_n$Gvtf8HlEpV5j2l>=upLocU+dsd!H62RT`J)8vyy}W6#3G$Vb7C>F($lV-@LfhuCm z_aLY`E~W4iq%~QyMeH{*raLC8=;DarT^!Q*JwtZ@P}!JqRFAd>FsKc zA1{p@%MCpisgX}&)syO+b{q9y)}BDxucl73TCf#5PJKydDvc&9=;hRUZr^(rjY#Co z#B=qTjWBj2OL+!Z70$*|kRUv%Pt+q5zHjBG%BjccAAN{J_Ee(euPgRZd2U9i8|&m>vDOh=ID5sZ(_(h5rH69jh} zfo<&?Ievloy?wQAxOt!78q%PmX)8p4ByjEMVb8bVOp^eaj`53Z+-fM92C>h$ar zbsYSUFSF39+dyUv?l}?=BEUV1t13LIs;U}!+87G68Xva8m3%ZR5x)ZxMGfH8F@SON zaOhBk$55jMED2{Q<1Mpwhhp3ZNz)l;&To$TcrmrI5}B=(Llqq|j_ftLU-g93>H&Mb zuNgnS#U&UsuFUNsgX20U!k$puUl0zF{>8wb+*LW zM?6GfJ}qnN*R|L785fxlxj`fXoJSKTs|X_b69}U}Y>C9e!BfB7xe2Z2AIYHnIGPS@ zGbxdt;L)|h`Wv2R0ms|}xM>WmZ4BZ=oYn_g!4-&e@Rj0`_|EYQL0zTWB}`$6k`IqZ zzSazebG~Md6cD!-wj_d`$_|mcI`|06-tVNs^TKt;f&9C2D4XjSFaVHscK+E;F7fF< zb3yO1EQ|YC%|5NjyVTAlLjv-}7a~llAw-b*zCVw8^C1=O$SktV9An5;?A{T+Qj+>! zx@Ygb*^hZ(RiS9>QJ_Kwc&pzJ=oCl6BRy6S3L0tqomr%W1t~sonjAMy0U4YyY~nhh zq_ZhIk4QG97Xx8505KCd$;dn7b5;Q0!9;Y$g+)37wrqPmyDfe|Riiof4bQXP=jc$SHo@)?vRzb@QXs;Kuk; z_9r~gks*AlPx%Ifpv;Lm#a&7akb-khYKFYtKY_BU+dYIjYJT9iMnegVjwT-v=uI1^ z{oY6Y!T$J0!Mrhls|a4j*y_0EPUVL_$G87sTYbNfFLJ;mOg)#W*v8%P?fH2u&dSpA zNq1?Gn}x~LQILt|B%@JKqlu`$=LVFs)YhHIF5l__RlTu|lkjg;H=`a0D7bq#0%|2l zSMe?oI7-9CBU#nRIxdWN6KSI=`n5!2245i(TU4w=tBrcDA>op($k}%?IBQQuOoC)M zYG`uv2maz&bpu^$hq44$M0me^tVTKS-n2v|P5|&lcND(ON9Mj{%fvZ^R8r3z7Sfvm zQKsA1nkif}ndwDUCG_y%y1B(mya3;J=#yidEkf#_Ng`(|s}hpu0mfc0YjlXs!*8ZPnUa@g%T4y6;yfusUAi^a?x z-|Qg_k?J)IvldLmoNy_ezxu#NUI;b3dq^2%47ZK7euowjP;?(Xdc@)^19^Ifbyh(( zZM~f(A1<9=hFFwydYNd%j8(7C#vLB2n`@rN?eYrf20OJwkBaK;)mcU1?4L zdRd#0R({3KD}J@hob?FkmYbHzSt;G}S`}>{mgwv87h(U_;`4B+*FTHk?GWXdX>K@WK2|HE(I=WC)U)^ttV?$8D~3qMQ`%)a9fJ~mDTj<<-8@GASBi-PRzf1>)Cg*= z#rfytFn&Gc_7rlZ{0P}IMF};uf{T3V+J8z)j94#^ zDAO9=IQhs1HZE>kD>4Ib9EJpIFhDA+bpF73%YS%-P%YW5G4{<(SN1c#Ki+~QfyP5& z>nSSMLG{lJmw?)j^hJgHHcpx;NBBpc*#T65ca1xf`b{lmpg6m6H%(tO?$c{13atuS zJNq_Ec}DnP=)Af-0Kr=G!X^O_JQuWNuoSU#MH-QQhMXD{hyPN2SV?Gq|JI#Occxa6 z?(K`;yB`|uYTYzqDHkmgP4IrW(yK^pJ zi3_z;Lph%w-#FQ7?{~1m>(c`?!~53IC@EEV9S&ATrMaF$7}Hl2|FZF&W#?z zEvx5UaZWQ$2m;DILZrmJA*ahAA|oTeUGKMc_FL4wIWU~IO*Gm=I9iW=X5miesswGe z%0j3-VgbQW4R#GQV>tfZ9oXqrWo9f4hrl;#>Ezq}1t6AnvvP_EnAi9R7*o-NRx#Ey z5z|AS7x_;%f4(xYC^#_J`vLyWD@!!kDhY|?%IUv`>M9R`eUy#V9nUEptC^;foB;3f zuUxdlUDd3`-ri+=?dPUwdKq~j$Thfsm9*N8^%6UwtbMfKHXGn%1G$x0MfNm;8yI;w zpyub)lK@$jE%6F?)FD?o_(;3#E4eXd3Hhs7omw?x@9vKoC5M9}D+V+WuRFbq2NEvE z?YfJ~KWxu~M+(B%muH^XX$@}X2ks^3q9fK>K+elH>i=Yao-A`x~%N5u4dAJ zT9mrwC6DZKNH=?bn5#YM=8EzY_X<#SdeYp1@vs6Qf>Ox)YXB{|fT$D|fD%Rt)*dcC zz({M>*Ph*>nWPXi394u|LzlHEL?W<(ss<9`oCqBUV{brG&qX!JZ8FxA6S@F&{20HT zx;Uc6;e5pl_FQjub`^n+0n0^tmQYY>Q#FgZ5P> zXu(WOC5%Uk0D?(;q>k@mqk%yNWNSmN`>YKev*4E*5!nGif|Pt;tliWq_MXFI>c73RejS{_c0rE0y5Zcun8+$K4p-G0L3rm{^U>B5-RuhJsDyEz=t(SJG3Z zBlkwKXQvp3A788kfc(QI15LUr=*X@F@(P^_oD6hv&vP%!)pCk9&hih;QTvW#UTJG> z4H|K-A10S|p#kl|l|gihA+v5)Og=hZyA65Gwst^J!Ea>H(Iya@H~YRWt9=IXXujsXqZ3RFN(;zYSyA_ZHd!^m3C9 zZr!QugPfzc6uh;83@&t7hcT$^%~4&-L#RiA(}mUvBK2Zyh7<(8=G|SQgDk)}lm;&A z!^!aL+C8)idQPap!b=+3;5-TbhU-!O>DI-7G$Rtdf<92$t5vOVolU`UJSwg*7g{Cm z1d<1CIwdR1bBA*|?nAo$()2mf{1U2s=4tX3y`Ed;pp)&DMQ9JRhkgcmXP#r3xfXcK z9sUBLIb4gkf_zdmW*_Jjo?8oDi=JqaO+!RE2e~n==GqT@L!!SP-$tJ$(e&>G=!C5Pa&NjVnqC+&2NlEIQoT z;vniWG9=YGD1#@;eBPjKA_2-6U^xzFUjJB?5DdxchNK<=qK(nfBr+O!o41okU{gnS zArhX0h6P?PTvebc$O#xhhGifuBy&8^0{)Pf#v(<>=e8q4mG;8SxrBK-jv_Igwp&stgjdk*Qo{ zM5IrAv1r7_xo#N0HYSP7VFl|1FCMv|!$55TR~yHgNCSb^d_R=cl~Pv~ez%+ShSm`k zS#SFsfMx(zxMk5HU(lcQoZb<=j1~S{KH!Zf@lYw&FWipS3SB5K^FY9g7P#Sl0T=p@ z%!p(TlV8rYw^{w6uG#wJM0MP9iumL1_V*x$``fTm=E<^DbsvLs8KPAMrWw{=f5T4_ zj`2H6Z2u731>v={{n!_`1Uml;-WUY0oyAs6WrGIUp97+i-;0^dmFM@dIi8n*85%w0 zFX6~jJ!o=BVZve`Tm4~j5m=kUz(?`+Tw=G|Om*6LnK;kd^L9mW;|p4BKty@?wW>4}M~@GjqmUp-1iDS}R0Zli#9+D>h%yLEBN5G=NYKSN(8=Eo zOb9h=@y4V#RF+lq~|AfsYY|A;BChrde>_TTGm&hw_cN zZjSrcDD%b}Yjb%;^SS|v)~!bQd@gksE*_Yoya{rnDaS>t`p6A@i4L`-H>I=vX zbKnr}9t3U+;_9adMk7ytQ~h@d&+70sWRpPmPok?E6sqwR+woFT-<@*+dTwf4{Cdlo zMW=hzC{yM>cTf*!6aG+%?^|vjPX!5pB42p~^?QGLBZyC$0>~UTvjF(3Q>8&v!t_Y{ z5fJeuQ;CnE<=oj1s$jT*YKZ`zBjg!a+p&eN4y?3cGq^d2plGy{7}~;m&6+g;a~K4| z6$Olm#tu#wk$o5BMxVL5-Towyx@toC;SgkxK+Rd1-Jm=`Jji#Z(4}nu=qmKGo0i9Y zlyB#Pnij9wjsP)5zM-Dg14KJ$)XW#UHT(h`e5=;C7l1|t)(_M!KjJ8YTB1FoS=J$C zS;TSa2Hm9l#)u$E{K1GdUYTN5w8IS2aBAXvIz%fe=}}FJRJ;t?VP5Wt3CRiP(9pz+ z0lSJH!$v)v?3ljT%^{H!0lR@`ypu|(-CC;7HSDRb>*$g94|B_0d!5+LPQGP2kg7q@#e8fD$S3|iL8ORm z2yY2QLTRCcSQM&N>~0I~dafETx&cKubUmPN0lsiR;(Yg5Pnkaef;lde0NQDS5S0g8 zh4FX~VRH)Ob?bU4=tKy3==vjWMWSp?)^pAGswgOs0{Jn(sR6>Y&Hls=7GpqXRceTW z`zB1k6y&D`#7Hkb33BNR-_HxJe`cdEQMGqe|JUVa$%EXxdq~f#*GvkhgiQ(LKTpFOe)B~jJ`{bm~Ln69@Q)vdH}2) z#ERay8(c&^R}LUQlG1je`aQhp=(@jPKWbr%AqA|`Q$Q>}uzRN9IX^z;bJ6^N62=3u zmKLK_?z&dl8k+C+J|tACydw8JfZ!4ya<555hdcL$N3U^j2xT)rIDr8Dnh z?HoWXWC>;e{@Xl5p0^>B=OM&h%k?wpdx&2pTtZ@{I}0gwZ=@tNjSXP1y`AO_@Mt7x{j zvONG$2M2=pLvuaA43Dyn3xlh&yCBnvIvp@^3EW(k9?30w&g%31c4jMqI!$Ka_nR1e}@A860sr41+CZRvkO41pE6gy(Ex$LKjmo( zN()NAyC9y{sWOa@f_oJIa6r~u=$}ud6Y#Nbxb0}RO@2T#|G0f3aLCqr4Cue-lhOra z&;|p}!UgsT!y!xQ@j?ILXTAt#K8UjE;Y9j-5Q6dxMhCZxLQcjew)(yyL_1&BbSWVZ zj-WWwOGcnd^^++|tDBip$jQKW7geRP?yi49{=I4%FZxghfWq9#WOL+#NAjzsxvdJ-cD%mxC5?_9BQ!wJdjwxe;JYG0gMQ}CAYYE%4sSnGEc&!DbVCLnrHuXP@H8v=+aTA~{bK>r2^NIR+niX-Vk zNIhIPgnYl}5`Fjbn(1>-`$xW8hyKI=Kw1v3QxuRU=F`5I4BAAkCe`V@sTcyK47FZJ z{k%m455UX(X+lj2B1R!6A(c(^LuOs8m>F; zk7PNXj|BM^$#kD8X~U)OZlIil*E@Gr^&!W|k>2m`oKuM5_m3=Xilsb�IKYjNI|a zxt%t5Gm_!Gt1$5-U>aK;f*kT6#q`e&tyntP3lIn^F#Oz5SnFWU_p)1ea@XL-*Dzj> zC6ZW!BjA6oAFt_ys><&Mq802>1d$sCGS2nNHUKP=C(XP(Ub}_Amr6-XXN*A%30ksirrOS->0jl!wu{$}jjkopK}=VD<~6_yFD3 z(@0bp&8Tw&*|XDefCksVx3LtQXQFaz}*-98M znABP#h+uX=bkN#0q#CFKKjf0bvw8sA+xvTfl)6>0Rrfk`{rg4DKP?Dn@x8JI6O?kq z$U3RdO$-tfV{TL$kW>E6jH^bzQ=Q<(*+Err8d_P5lA_H1srvglE4ZY2ebhOSht0^j z-MxnV-589YDF_=YPMvx66J#?Kgc5UnE?$gLj=a@>mERcx)L&rqLf}t^AheFBYwqNN zDKf29Er6B$vR-B~`Xa4xz5JF-@lHN|AGy1fUKN&=$nM#KC)S?14f0}gtUG5=y)H3|El8OL_~*qlv6(Qjak4LIeI*Y@efdnq+9>TJJP+1& zV^!a=e&r)#QNF{VszA8khwJ<6+kVIOz4~)qOjUpgvoOuDLp?~s@jNFR5#bTJHdGj% z0vqzG-KsxMx`tS*Xe25@itG##iDVCJv=^DJM>*du0sIfUAsO6E)jR1aeTlhd`X%i{ z2|J+(37Q!R=F;GsuqTsPPlGARz;Mw zbkYLJ*xb>}dQW)YuPl4sD$lwUuUF&~euyq`v&#p7F0jXW4dkIqI*Aur4nRsc31(ve zLPEhB&9ZG_lMQCeqe2WXQ2@Bssb#L1gQeTqiVA@ru@x=}TW?tAB1DA~Y{R=nk*f0}2vLhU^6@ zm0$t|XtcqE(Z@a=Ahs~j$O)7d&Omc%0KioI{##-A4?re)^8l)+imK-PFbI2>PW=K) zJjWo1RtCE8LXvH^*dfA~kq}Ubbc1+>lND})qdpdTOrQq?;~qcc_u!zBfNop3+V4+>kPk>YU%V@ko-df zj*>tg)eb=YM2GN?RRZLNFB}4heUZocju`3`;uF;QVn+bYJ*R-ZY6nashfgPWK-F^v zh;GhXr=Q5C_Eqai8?0|{wsL}w=7p0B3$P?0UoO$hW|i2*4HuSTz+kZ4lKA50 zK(q_g)E5d3z>Nfim*B7eT9Vjk#O>mLb}$7RTrx6wOUhD4Frxt~?YQ>WOToKA9}sUZ z7F!GiAYXwVq5nvjK4&uKw>qV9$>h&v(&eTvZ4Ussb}+-sa`^%;u_a&#lcJ!vp9TT! zNvMS=&UoV02T(xU~B?kw652hi7vKw3r?K|ZdCw>06^||wg#FrnOfkHTdrFQ<|YA`uxyOZJi2ss zw7np8c_T1r*n@Z`PTF%7!gPVPw0!Qr1AWLB(hajdF+Yoj zXzr(0&_X;9TLP3E^a4A*FgF zI^mT;>!wBqai=9=EFS=cc7za3=#vO0=tI8OW|&b1gJvOdMqAI2%}gh*aYjGbulH_! zOuLR|ovgTGZivD(F_P(JsmL(Hu;YeMxowdW#t*dC=Txu#bjDZ7m>AOtFaZiGC1GVS zDMx_vW3Y<$1766Xn8-9}SS!>V&%{FGo!H@t!=Nq^!qklTuz#0wW*~g_e<#Qe zD$x#X?e2^*ZP#>j41f>?<~wa3?E(|pxNAt5R!6&V|FVff2tfn*A0X$@5lFyS80a!$+5*ly3>p zoZM2NOcNMT90v4<3!N9N5QScymY#B&tjyC4x0@u>6i`6yo0zsRWt@aIrns!E3pWbb z>W-d@yHlmT&B&m~yI~*bn8^t&{Jq;vtU3LKU{?CSSH72L9?K2bLRC;;{u#(6mV4i& zioPUYnIEvke_s;C{F@$45Y|peNN@*P!DoZK|G>)rvo2^^n8v63%rDQj>cQyrW@x%M81en3VeRm3Umm~F@WDzZ xDcs|a|Hgk-LvU=$l7AY*XfnxWn!D2M2lZ@2lcIXj)B{uh1U1;GFS