From b784b7c443e324d51c1b0d7e644aebdaf437b01c Mon Sep 17 00:00:00 2001 From: goyer Date: Wed, 9 Nov 2022 21:57:34 +0100 Subject: [PATCH] Initial commit --- README.md | 67 ++++++++++ conf-generator/Dockerfile | 8 ++ conf-generator/gen_conf.py | 30 +++++ conf-generator/haproxy.j2 | 25 ++++ docker-compose.yml | 44 +++++++ docs/tor-balance.png | Bin 0 -> 25530 bytes tor/Dockerfile | 3 + tor/torrc | 249 +++++++++++++++++++++++++++++++++++++ 8 files changed, 426 insertions(+) create mode 100644 README.md create mode 100644 conf-generator/Dockerfile create mode 100644 conf-generator/gen_conf.py create mode 100644 conf-generator/haproxy.j2 create mode 100644 docker-compose.yml create mode 100644 docs/tor-balance.png create mode 100644 tor/Dockerfile create mode 100644 tor/torrc diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f3fe0a --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# CasTor :beaver: + +Tor HTTP proxy with balanced Tor instances. + +![Tor balance schema](docs/tor-balance.png) + +## Requirements + +- [docker](https://docs.docker.com/engine/install/) +- [docker-compose](https://docs.docker.com/compose/install/) + +## Usage + +### Quickstart + +This command will start one Tor instance and HAProxy: + +```bash +docker-compose up +``` + +The HTTP proxy will be running on port **8080**. + +### Start multiple Tor instances + +Use the docker-compose scale option to set the number of Tor instance to start + +For instance to start 5 Tor instances: + +```bash +docker-compose up --scale tor=5 +``` + +### Run proxy on a different port + +Proxy port can be set using the environement varaible `HTTP_PROXY_PORT`. You can specify it in the [`.env`](.env) file or dirrectly in the shell such as: + +```bash +export HTTP_PROXY_PORT=8080 +``` + +## Test the proxy + +Once the application is started, you can test your proxy with `curl`: + +```bash +# test without the proxy +$ curl https://ipinfo.io/ip +A.B.C.D # => your current IP address + +# test with the proxy +$ curl -x http://localhost:8080 https://ipinfo.io/ip +W.X.Y.Z # => Tor exit node IP address +``` + +## How is it working ? + +When you run the command `docker-compose up`, you start at least 3 services (more if you scaled up the number of Tor instances): **tor**, **conf-generator** and **haproxy**. + +The first service started is **tor**, this service is running a Tor instance with a Tor HTTP Tunnel (mandatory to have an HTTP proxy rather than a sock proxy). + +The second service is **conf-generator**, this services runs a python script that does the following things: + +1. get all the IP address of the Tor instances within the docker network (using the Docker API) +2. generate an HAProxy configuration file with the retrieved IPs + +The final service is an HAProxy load balancer using the configuration file generated by **conf-generator**. diff --git a/conf-generator/Dockerfile b/conf-generator/Dockerfile new file mode 100644 index 0000000..6324e40 --- /dev/null +++ b/conf-generator/Dockerfile @@ -0,0 +1,8 @@ +FROM python + +WORKDIR /usr/app/ + +RUN pip install docker jinja2 + +COPY haproxy.j2 /usr/app/haproxy.j2 +COPY gen_conf.py /usr/app/gen_conf.py \ No newline at end of file diff --git a/conf-generator/gen_conf.py b/conf-generator/gen_conf.py new file mode 100644 index 0000000..7c65106 --- /dev/null +++ b/conf-generator/gen_conf.py @@ -0,0 +1,30 @@ +from jinja2 import Template +import docker + + +def get_tor_ips(): + client = docker.DockerClient(base_url='unix://tmp/docker.sock') + network = client.networks.get("net_tor") + net_tor_id = network.attrs["Id"] + + # get the list of containers + containers = client.containers.list() + + containers = [ + container for container in containers + if (container.attrs["NetworkSettings"]["Networks"]["net_tor"]["NetworkID"] == net_tor_id) + and (container.attrs["Config"]["User"] == "tor") + ] + + ip_addrs = [container.attrs['NetworkSettings']['Networks']["net_tor"]["IPAddress"] + for container in containers] + return ip_addrs + + +if __name__ == "__main__": + tor_ips = get_tor_ips() + with open("haproxy.j2", "r") as file: + conf = Template(file.read()).render(tor_hosts=tor_ips) + + with open("/usr/local/etc/haproxy/haproxy.cfg", "w") as file: + file.write(conf) diff --git a/conf-generator/haproxy.j2 b/conf-generator/haproxy.j2 new file mode 100644 index 0000000..31a7dae --- /dev/null +++ b/conf-generator/haproxy.j2 @@ -0,0 +1,25 @@ +global + log stdout format raw local0 info + +defaults + mode http + timeout client 10s + timeout connect 5s + timeout server 10s + timeout http-request 10s + log global + +frontend loadbalancer + bind :80 + mode http + use_backend tors + +backend tors + balance roundrobin + mode http + option forwardfor + {%- for host in tor_hosts %} + server tor{{loop.index}} {{host}}:9080 check + {%- endfor %} + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..2099cea --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +version: "3.6" + +services: + tor: + build: + context: ./tor + dockerfile: Dockerfile + networks: + - net_tor + + haproxy: + image: haproxy:alpine + restart: always + depends_on: + tor: + condition: service_healthy + haproxy-conf-generator: + condition: service_completed_successfully + ports: + - ${HTTP_PROXY_PORT}:80 + volumes: + - haproxy_conf:/usr/local/etc/haproxy + networks: + - net_tor + + haproxy-conf-generator: + build: ./conf-generator + command: python gen_conf.py + depends_on: + tor: + condition: service_healthy + volumes: + - haproxy_conf:/usr/local/etc/haproxy + - /var/run/docker.sock:/tmp/docker.sock + networks: + - net_tor + +volumes: + haproxy_conf: + + +networks: + net_tor: + name: net_tor diff --git a/docs/tor-balance.png b/docs/tor-balance.png new file mode 100644 index 0000000000000000000000000000000000000000..add4bd07557c8811f6f3169a8487f3bbeeed3719 GIT binary patch literal 25530 zcmagG2|U!_`!{SETPRC*vMU-gjJ@oJVXR}BA)6T#h)L|9tmh{tI;Q$4VJQvpvpd1f5q#5j#JhPBU(s;!_3{9pAYhVm5|YF} z;6pUd3Fk}r-g*B2__B?mGsmPbTB*_ZJ?vCAHmD>Ka-P? zCN@WW*+0bF@#Iqn$3OxebSNb(tpyDC&qCl4!ati3H1SfwXiq~Oq@z2|PfkZyUmQ$= z*oY?%jP%&HM!+oMu#-mQ%zf?g0Z6!(kt9yX&C^8>j9U|_ix1Ve_rU2%d4!tVyT~F? z7QqIV`hLCyDNPSqn1erBP8RK=Cxs0{;7ruzGz?L`mWG}%thAhQh@Xk2i2@w$tQ#1r z?<5J=l9Bf{RQERt!OD2L_=HHxt7$r$I|oQ&)zx)F;p*nbnmT@Nfxh}0CdQslTESB8 zu3p+2`WoIyNnQcF$J5bq}q3zgEfH<59dG({My8Oj?vyGXfVz#~XsI8sB} zgy2dDl-CQfRQEAd@Cz_7BuMA9oa8J5j2%pcrPPBE-a)};=D`RlV_j3Y zmRzWrU$A|kgRZ@ii>r>Gsf)XDpuLWqfxn-Oxv!fn8etDQ@Q?#9`ul16%1Ihx)${}8 zktlCdLztzJUXUzK%}++k53AsUurP2Ab;7%7IXMR#o5)GZ`CtrmO>lYyJ>LKnHV~oV zW})TmD~Yk!$Lq>?>dELxI~#doP0{K&L;VmrS!^&y58;TxV{jh&fgWlBcoPytQr@^=GdF216F)Ca1i?TCBZ~qpp-t>zmd-lCF1iRgH+jEcEgcyR120{e zkBOtcpRF~ z-vuQJN5~n-X4yZ+&k|Ls^f|Kq;Jsk*AMGDBeL5WoZJ}^}@jX zv3@?XM!NbA-j)tJu4owpH%zF4t~<;T4Mv2JbhEHDK)HcN(BQ9Wu%4k4Mk>e$>@9T< zS93%8V0X1p9e0enH`dD&xE}(eCNJq76lCIN;&0&*qF`?7>w~sbCl19zOvg zgdi>DZ4qc@inj1`2~fv+h2RYd2n`RUEQnj`76cT^Nx|7E)XN1$Fm@pj)X~8xcXwQX ztiB%tLBKkBx#}X-6g1SFjnTefN1LiU=)=%RXM(1*v!toBn|X*D(!$WtNzc(47K#gS zQw!DCgZYCI5gc`7G#%}|&D>3}#`^w9e`&0na|j-blXbKVcGFYCS;%Nxs=NBS27!kS z0%VaO1UVNJni$dv_GvM?(iG?g9eM2#us#S!8A$~sT1wW!2yWyKHX0(-8S9O6(m^5Q z1LZNUzH<67O9f9Cq=LC?2u{We?F{$!!FZw(fx4CfEUBSyOL>{5$ z=H+aO_x5%$#A;dwx%b1UkXC5xINoH9RC?Ud{B;m z){`ga#VW$YNBZBd3u=X|(OUJi|NVq7@(Hyh#$k+)^b)mQRADAtt`W`2ZyUkqwO!}Z zZ$oq<{(Y4TwAl5F`5CeQ_x;M)7AIV#OWKtSv@|Is|GqGYh}I%U$_Mg7s$~DZ?3g3{ zqqHiTUVNNSzxCf1$(VJ{W9Xo#d4>MBQC7y1L~G@ht6@RM)%*;uzXeT8-M8@1h)pp> zl0>&ruVrUI?h33eKDysI{?gC!@b7MQ@Vfo(mp6yPU76x(85b=&pO`&$SQ)LW_L)I^ zqd+0C5p#FJ@KlE&u0v0R>)gI%hHft*qbcbfe%uSnY)|CUOB2z57_vD(@G8KKFjoI; zxp{w;5jMJR+-V0Z;>fuIAypa;r*2K_s9GWl;DYBRIQIoSbR?%(CR73#tx=NuUvm=O-19d@&iSR}j8O*xkH; z)0qt~8=qEO zD2!pL#K%ylj39vz@cEG4IQVHhH{yIh1DPg*yr&rO(Bip`Z?D3SY=V0pGg!1|8Y8dy zBew4ZO@=&5;8n2+{j)0mW^d^EL-Zqq$pvjKqAT%TC-b}^WO!fM`dsJ&zv#t_Y0B64 zI<(lV9flP~v)Q4eE-an1^rVp3VnpKIANOzA?EPN3$ad8`67KrBgX`ci^@%;H%TiR#`y)6#P_}K4`-vo9!dRx}z z4)*`Zaanl2UT^7B&FHEn|*zn z{FL!IcFrZrj4h=ZFQ&q+z?3DDMD`poOX|eYW-_!~nE4g{M@eC=g}lcpyOue+tv0qs z*^7GmlrmJko&F-T2x{6xY!Z_hN8H5`*CF0+-622jIeW&m&LgjiXPZA!#>{T1Sq9o& zNn&hSx#(OFQmVj3>!zE%e7@yN&Vg*vP0)`Fb4zY;{>VOX;L<=^I&D_BdfNMZk*6Rw zVe487+n>=r{A14dugfm}3l*wQAm@UoN&RB}pbf7GTfg#0zV-y>6Lg|bX3UmyjC=Wo zIY{xo{{T|C3}Jl|hPVaRx~2QFl}eBP{!r2TvpT_?k>6@>AFQyL!9JRBsy)X3h3ACB z#_UJmzv~~Ig(#j1pG20(Uo@BhjQb4~YoEzc3~((HOrT>O`L4r9LRxNoc|IFI`|S?z ze2hJbP1w!j@WjVM#*VxEv%F?@F3Z-yonA1y&ENf_CAUa~bsvvXV7lA$rcAf9JoSQF z=ZPKI(%8`p?mgy^b`q-A8+~S%D&5#z@Aq_Dy)b6cc{Q|t2o(nV>dMin1sv{EbhOcv zU5@3u?f!7G_J%a8R{QbMn#)X&BS}t=Pd4}zk6-)MG>&CHp1dc48~LC8uvmdE-|mXn4X&R<5p=ABb%JhwH(R18XdhZP25#*A ze7<=~McW+#OB1XNKL{m^RF^=l>btKh$X@&H&J1tf8qgbf>G#8k<+){D=Xlu7o6>qJ zhdcOII44umBlYVj;0>Wxm>u?FxGf#d8~7 zm;UI>ENPIrlF5HqdCzQ^et59oMcj`UEh^wYgD*90nfT4kb>~RW-PMywy+zB`X&Ao2 z>}R+KVjp1%TkR0b5t%RJmif61tsVM%Srq>vDZ}H%ME%v%{_YL7JZc1=S4W5Yj_+d_ zMN)`%og23D$~euVn5}Je7{_vP_SMe{XNm@|- zgvpon7!|s<`tlLn{p+XlH1)NZLWbf^9hIZqz8;;~=rhVL2oXm4Nf5K4gjLKi5`l;}1=w7hS&P#3AUpAb70m3MEDyo#G(v*tE?lbR; zMC;&hw^B=-E7>{tY1d*&5U9$eQ&isg2`aQYWM?9c;j2Sj+unPXzu(SmEIoam8&NKg zOZ*IiszkugVHq`UGNp2b_wAL>>PK~ZG&aG)XW^5t3@0#{802w zL>S(?2rFJmAF6Y+;E?w&OyHE!^#oCmxkD;7q6tzR@(riRX+bJsS*sH`8S+CXm>r6E z`=Ps;abfJm^AV(M=$6ZrX|b{pLvD+{+=LJ~c%=ka8*J!k1mmbF8KJ*_e(8h6Jhgb9 z>GkGd_^%u!e$2flF>I}sYU8Kv(I`q|1`CM?C-f6ZGK?7J^1;^N+{g3x)4?QiRL`Qj zsV~E15|u{y&&-DYnF#9Hvj=HUq&SV;B6S!euZ=NNblZik>@OF|{C@Oi2qwwDEw6I@ zR2XUT%9w*GMx8`(g}vup$2r;Ja_dI(Tu|y%aA+9a>5p%Xrs}H1z3Z;soJm%(IR`D8 z{MEc~(EN8pPul**>dPOUmu~FpN#DAv1MF0;@%rHRSWm5AjZ+V*iOn{wN|anM{g&N& zak8@1;52bNSTVIAq;~p1;1KZ`tEW$lX|;Fp?_S^{O$e{`oY=eb?nO?ez!} z1nr*@XI|-hw`#P1^xgL=eF)pQvmJ~15Mw<+eXdXCD6B@7k%}D8+zEEPmvZy%GrXQr zDDK$Jc-y~4Z*{cG?ACkarqbV?R_eZrzg^~$kW!AVY450<2pof9whFC{Z~0T(^}xbd zf8Ks4LK%h& z=HRz9smP&#k3*_>IwXoQB6+py!#SrQ|F8X8l<}>YP0>CYyV{37Gwo9T3r2l1C85Ax z;LCuS8us%Ry%YQThdY+p@9ki8GV|+kB!Q|kh*SB4x8Gn(8Gc1T+Z-oO9zV^nvs}~X z@M0p6`7eEqbZ%=AIifV?BU8(_5=>v~{{6JM?g3&V1JX*th-<}F5-Qz}%yg_ZHC%4> zH%W$76G8Zn-<*LmCflb(pdtRnGp`=qBU8g6TcpSa9~sL1yyG*TE(^naW}4ZwVQe|5 z2l;m<$QeUQ*fRM49W$Mf(OLptHi-u~ub4a?t69TNr5B{KnCXu9Oql$C(($z@RhH=A z8n@|S&V}E51N7}HA3tbwZW4?b6Y>^>JpaAfTWcC~d=3>dkzOSYCZ<@$zur1RAL8QIe=JD8-H@&Z>Ru<1voU$5U;e`@B) z+?%~i@}hHgVA)g=Lb@EMJRL#ay?sv&UEgZ&@GI%6s*yohuLfCzZ@JYAPv74o&etCE zmW zZS@vM8HDC6u+tJa*;7G0layqmjE^*4SG!L=T`>Z}nuU2eCbi0PIYC;MX>Cc`|HM0BQXPy^ar7hnwfVakpyv8JBeF#uvCBZ_`HBIO@BZoNMg^@U^EKBzLxTy zR+WCsE~Ib{x}nATz9Y;@j|@0M9@OSFrag&A@A8R@2&G&kyT1QBW4YQ^)HA zNP`tc))=BcLkdeR9}XLvut;QO^gr??1d8dC38m1Gu0+s8x1qY<>(+>P4!MeSZUWWF&GG=+R-Sr>**-1|>@RtJ&wnuJ<;HPyL~ z){34y|8kol%jvWGB}l9{vAT>5W5hIgKLE8uKX-?U*W_hvjgx*eiTp#4gT3t%{XE$y z@`u;9mxRTw>iu;>_qB$$qUl&yUYr+3MMShCnI0Et%}0{F87;5zeG`80u)G|#x3wsE zC3Gt#aAnkIqB_8QPmQnqX`Zxm5~|=bwmq5m5^>YP@a-6Al~oa8PmMC(b0l-1T~l>N z2xj)tUWdXKQ%`JzDSKRNeQSn()NDX0RK3rBLwdAcXM zSDY$Zq~d_Sa&_$Fi3KAPFniw(td+wozx7F@OblRE45{swLO|W=#F_T-3>gMt^xWo(0a6?OsFb(7 zj<7l3Gk%6MRlY_^8w|HsR67!cBRW!dC&E;76V&=uI=b&%9SsU8=P_#P)K|b0Hb|T0 z;oeUMKj715z2eLFgee~kF)GV)OUM@Wpc2MR^B!r}k-}dMGBgeuSJV8qYA7u=9lNCJ z((tp3?{3rAsB+3_eIlBCq83(?qyu_od}<#EmMwwW?%DSkM!|<5Vd6lxxTXn6;@jys z;4TbbBoHL!M4KQ;ddgRsKFP;6TAKJWb;w2X1b&S~e=3lTd~3S3H1yPr(|6zp)z#c^ z$uYZBbF_@FGB+yIve(b`AgE52oURI=+Ef|BeL1a83eipfcc zbczOZ*lMWqr;&7^xqtcTw-0tOPPh5MbTCD3vsC*u)m55LeFvUowO;Uj*Bwv@x97g( z5iay$(l&eeRVd{e*_Pj%Jdzczo@UN)I@aPUCr@n}m;Cp}ETXbB4M@KBGLOBNdHQ^h zKi7I0nUvfgT*FtgC(8IK=>jVxJ<+K`^8JA<{5XV1noKeLw~x`;q;(B>N&-fcfsFG! zjmf$DAhcH|gUKl5fn9(sxN#WLI;Fn!=|MEe?j&F8Ud%x4XCipuBK@F)Y|9!aEm=lj zG<{z*E3or4=%N)%xc~n8*qGOwCilsNPqX`Q5JeY9>z>v>{?s?v{GdN4;s2h&Yys%< zrAUO`y0*%m@vT#m17Dw6y_gkyX6g(5O|M9om219e_K;|_D~**R@zh}E0#%}?K=Bqu za&VPYZ});WYeow+?CK0J9jiE;PfND|81`<~ZJDoXd>=IE0@?WjMHhZl35s80aAUa- zfQ6AtoW`!#J*A*b>%bA=m%3@}Sd_lyzSzJHRkYUrvUaQqU!l+4v+r>%LMf!AN74Ab zkOrrrrxuq&jt>5GNuS|SH0|u{oCO(=*wG5etJA){yVC{A=dK%#KMJnRwveAGuQw_8 zxoQ1f2beqVf10xDVg>&;%Jx!YWxDUMy4881Zt2KH;QnYrL)o?$^z zapt%l013SXr;O{_m)GYfnvF@1y+k)}cY@z&YyPu*tkNkH6R-yMWLulwEBqiUin~~m zk}9aJ3*eerB8(xTpL>&e?afP+;3zD)Q9}J{pCtX3U@DX%qk?^;K;eD zk>gyDbAdZyqv`jk+Xgtpax^Mu3_xjLe|cv*daeyrO&Lyc4Z+cRpJd_zwvYmr@_AH@ zSJQT8t=E)|T_b=lEq1(qf2z8+CXEpA6tC7$w0aE(cmQ98#2mT=dwjh^jXjtKTY?6F#0ECo<)Nf_F-o#jBBX%F) zq&m^6IRC1K3KKQ_c({!iCTu2A4)SKkUHvbYq+LYV-r^&t9^TT#eQ=I~V(9+Jc%-Q1 zGRZ0^kP`*(V$Q_)UTR#Hdbz*ah^J@u8OD7J(}WZ~e{%?knU33=XH~%ZZA?`vGY)<{ zI{fpd>xR-?IvP@ZtL=_2UiVz&TF}&Wi$m_MDcl_%hly7KzUyslU7%hxcVs3l2I+Hl zgpy9&ShL#F)*=VJ3T3=9w%`>+1cZ&2TN`Rj9UPI1gOBohn@ou~Tm6ng#g8h{8N(ZU z=#QcC(d{6^se0=a|9D=M1^Rtl6~%&g<&K;NRfaI|^arSWie|3@SH#GvPNxHWBggO5 z^H)n^b<_YFR9kKpK&UY;@VlTCadEpppTCh+Dtoi@Jzngo5;4c!jR({9n$~DM2u*(U z24X;T{egnF8_$HmX>yUJ(1?Zl;ZZKVGl|74-4mXuHzwL8cK%Dit;IQ@?c0}^DkNk) zMn6NmeJC|St%u4}-knWznxz|TXU8hdBuIDPKJ9)E9GxlS{)75aBy38FPj$`e5{06) zID;cm}|`BLJFs2$JilRNameWLUDBORT9Up6F!(<-4`#!O{3Vw$n5k zqR!kBsswSSCX3gmo8c6_X_uSYv4miS&BZ2O+R19~5E$m44BuaI8s!+A`3i|%9L}-{ zGgjoi<{nZRQ#Nts&p6s68g##W8R4Dh_;&u@)91~Wl^=!Ob+@jpj%8WXbP&6IS8p=! zmkSPseDn0TX{vM(2B^)omAZM`vO@$Y#3ko=d*{FE)3tTmbo${1bsTk;t#qXL-@lJpC0ydm#k9 zZ(q5&t)i{x2*M~O{Gb8%U>`*eVajFrf6Q@~e{Z_8mA(dG^FWDS)~OfIgof+_M+xUc zcIUFXekWQFI-L4U%zhH+F;C`*FTWH!n+zF0ZzK>LCs^>Lzi;O8 zd)(fyrauMT*OsfQ!*(~m*0nfg0vxX6CJpmLKvq;`C6l?;dI{9+p&t{M@5Zu${#npc z(S^)pa7@f9n*Op<}H{sVSQNjhIH;xV{f*fZI+{Xv*`WIac^}!5RsPS>OWh6wE07E>+o8QJSKrM@};<-9d`M-4^x+p2{)6@JwT*=POW)M z0@*othNLW48xA%j0^c*9L~N*7%*353CJ{XI)u_6Voo4OIIr>uKN$gUdGiD49BOg<( zIDN7zM!QOOE?w5Mg2!DEec=C+&~k^OpE5*d{A zoU;YDyhs3rCJYMD43MJkms+~+xe$xRvYfW8xN%Ok^0-&+$gnEzZNA9YjKo^6M649wB64#@Y`>)N zYjj(G0Bn_Rv(#{kSR^Sqr4Be69YL{OHvALqm>ZtbT4b2{NFoxHCqmv2!criYg{PM$ zKGCvCr2k$S^Aj7b3B+bc6gm_K!A!`9gfikV~%_@djmW$2#lk%Rb=!bLNCFJh?G zJ|g5=x%Kj7QzPBE%ksZU{cVnj33|FHy1^Vqspm?x4vfT^ag|uTTpKmEXNt)pzD8n} zC2l1`Bn9g|#yUGv1z##Dl1Pu8YyG_05=rj3I{s3MFd#%2Z>aJRP&}Vp%Ii?MkRKxI z%?)-hllFCJG~}wtbZ8~UE?IQ3x>~9g?v#A)3Xx=>;}-YKre^rjogG9Oj(WvMiu zpWE63+)a>Jyx25_`bg_J6tU1A7ryx0ec#7H;ld;bFG?3m;U=~Cb=x3`T2F-Z56!Vh ztd8Yz-XvBw3~kc?A+a&~s)J`NS)r6)hn-|XPyILr?ATDmJok^Ljx2=04+7!OJc(u%JWgwPLv&vX9z@rq7Y;t901)U)c|p@KNM>){eYPWw2c?oRYKwQ62w} z7T^-*sWOEi$mr4|h*ryfEQ)D(MvR_MPp8NK1NPoB9na#OiIegpVs%T<61@yq!j_@N z2Y9163S)L|=W3-(ABNpj~N|jR!Q*?%T)fYDl8L=FXCUxaP7HIvh zo~mgsB#ub?`|*(;Q6C%OaO6HG1!J)XsteSV%z>BXtb6kg9i)wk9%|N*uZ)bOKPr?GHRNeLM@FCG@|gbOqJQk6LP8I z7q#>y+A{wvGzT)yXE&%2@5xY{E@Y>2GNkZpilPrz9=!xjAjyqfm|{{vC}qc0UwBUQ zb@C6(yDvmcrpdG3v_cFFj$ezZLy43!KE#Xk^OQE(all9xk5D{NEsX2CoS4RN9&BOI z!0Q(zOTPq9dicPqde0T)uXj0VXTVA*fY%GSvX|!Wp7>IiNRh>8NdUWA?Vvm|Wg|bd zT@J5EF{O_Sk*m!MEdDHH#Bg(Ax)yz}sQK3z!KAh zpt^fiMzq1GEjMXF<6%D_Y9K!XpSsxC&Px*b_GbXHvMK%7&B%h!3y3%0FUalb}K zrMi{5=wnJ5uNL#f==gD~Ko#*|py^r=$K~M4I+E9H(9+X(J8R#hK*gE^h|WJ9VizC# z+=YJoG*$hO*K0yzKksL&z`=#d`g})%#J+LnxbD!iMJlsaf!k|eDy-c~VL5;KA{-&x zOG9WBa{s}LcBDV&hqE8!sSotECvQEn-j>UX*4j&@EqIXDZ>BOp$oV@6*2lXtMyqvY z>_rwx8GV-&LbyuJ$#4J8ll2g*aqjCKDrHMdd+3x<6u01oH8N~AusG-$vV;8!KRflv zZKL@?Su1F1A-lcixFvaq4hE2RH38C4jGhOh9S5PLW9I`1Ne1rS?GlVzy%`~2h!(j> zZ0eB#8?mX>@N|Q`r01E_-=4*XpXGfNtUIt39T}}vzRM2kZ2#r2uydl=I2njjcQ!wO z#5;#ZwGz`Da2NKhSU(Sz4Qk!++xB$XGgkCajJLeHRScCkvj7k*9XE8f^4;nDsQR7( z*he(`fNfJ~07`h&HlZC^{pt2$CdIb@Qg`v25{P(WPNQ^PVpU|aEc#;?y9oJKBDH{N&ce0I{g%C{}}o} z0G=qq&uAh(eEfP;7>*RsQkfi`DWq(HrqH!a(|1wDD8JB_HW>85W_wj4yw_4_RRI;e9xzxkJ@DB zFI18v(rUEZp$|^|7al!+Wv8%qWp7mC{uvKGJ)WyIUW!2)ANJL#_g}RubjdE-PkAHV6D%?PEo-0pU74C5cNuRmh)?rE+ls9E52R*Xp^S$R5Rwo5oE zbgrdY4Z4IGjS?r?cSqLf6Ath-8$h8#d&p{X=QPhlu->s{i@Dc1pd!O(^Tp+9-^4O4 z%hM{VwaWbBr;MlJd|OfkEFj$U?_$XU31nOgmXG)K$*t>(+W5Aa6wz;Ng)%0voYXj=D!x~ z^;<`x7@?&rawC-Shu2wMCN=0-?*$A6Q+$Ev2D|l^!pFAjteY{*a(<~E0BM5vDGL@iJx|RPE>6X z!PS@C{{dHFFR#`-e;TCG*sf4TnWfr_-Jy?e3#KnyKLch_9aIn3FZMD1*vU&$|I@88 ztfDp&BsCxRf4#AlSpD=sqXf_-%0NA_F(v6L8@A&OiV*y+7f`n(a|cgH4n2wWlf*re z6iv9kxx>hH+ry_oGQW6uQ6t>y;C8G1>t}j1yf0~4ci)Ond5mQJ^W#)Y+fj=|s41oI>0A2l z+h85OEo03j5^u~(U=rBsR7wb(iDxXwhz|X7fb#CrRz<`2QydDu4{P1N7!+LpjU@~` zj6FrO^7Jjs9?tjlonG@dxJvfk0y@^2IdeP#NhhEsDy=*DTIt@(y_l7ap#^B>Wp6-1 zb`rr~iJt#oRMsT^A1d3z`+uOa7`IV5$tOBz?)u4x)$i#~?mzP$E?3MVLbU91*R{I_ z;kkfZ`*{Cw>%0O0D!GSb58PT--yDT20Q9FsEt)bio3PCIxP|-j)@tLg&cC~xT{3Nt zr{3P8r9ije@&`Cx*VN%}Ic#%S$gbD45KBkW&VkA^6ToW_iK#DCi`wf}!@|Hwn7V^^bms_@ z8a9x4jEgdnjQ}{8BZ%|^Rd{XU0SB5mN2a|q(id)Sz*U^XyLM{8g+XXCaBM}&sry+}KRaOOpT!xh{&{oMwDt3gp+wWx z0B3YN-|xpy0wE7wW^U|u**eU1W;j{=!aCm*2Dv#LYxm(^&?FX+w@M+~Llz}KvNHdN zI9Cw!?GA%LVMJsFeFydBXaXr4Q+k#6-9v!Rqf4uasD?Z1vrd^+=*D^;mCXl~nKl%4 zQ=vb_iS$@YCLsPQ)~2Ru?Gp5*z#OH275oP*zPk|hl}$~6Y(!WulNu3P4dhHOxn9ki zXO{A^JjA{ZuBvtEFM8;me0d`#KV&{fhW6a|*h|ejZ@08}Qq=O^mNM_m034X5sP;)s z!>k+~D_*8)Y1RKyR2u+;b10U;#(P6^_E*EqX$2y>4cKmJwAPKI{V9q|H=v07ayOc5 zE6zeIFja3~$D|&eSJ_2EhrvdqLP^ePRPJ0)3C>I4kZy-?f_cmEWOs?`IP<&+2enHY zI9qd7t4a%DabYqP@c{nDgizg?W^nrz7p(LXUw{vV}AO5^kRp$yYBs^ zh^ONAj+my{2TI%AI?XRv{Stu^>qCN+-6-|qsM~Xv*K1pHN>Zg5Yr;m=Mh;ul`wOf&0_C-PSrF&%|v9E!eTpWeDQK&D6xBgQ=qo+rQu0 zocw8d&DR7IlI+F)#GWr;K#lYkTp9aIsp1Yw(#7fU&Ah1&z)XmMaPfj;;syY$do0yH zU)$=}&P!tBJ@@8t`+4FSejH-@#hZg?e0&#oER7}!0inUR|3&8e4gQ17Q^l7=X*%?V znlefWaX=~SyuQ7x1u5ZGfCx1Z6+lq|Pupmu64_yIA$MJVWrwsLe5cqqo0A(_3$K7`AHc8Sjeq*7h|;ZgukR>{T@d@_#h?GAYGTKZ1HLFRTA<;nm>CPyK9_S)Z{ciw zbQ@9ZSgO%d#U9K!4sg`DA2s}{;{Y%0e%v+P8r=hzM#xs_oTFWUQCuH!%*sjfpYP6b zN`C;fDKZ9E+Q;bpOIWDRn^DAG=)Ys!RvxAG*@~S-wBDes5LRZ#C}_$q^WLRHjf%%% z^ddrOJr%8h2?OTQPl+K}1&6nsAmOxioOn2t7pwG!4JjHj?2#+U7>M;$J_Cc=cB|b8H^1Q^Yu1=iWX9GRBK2 zxh&T}b{=A`(s{%@?1*!C?E5ypI`{zd?akQ6HZ>sJUB%%1Zq2h8 zUADC8u)x&B7&Ag*7yhoZ6$jmtwV`I^7tC~+Ca2a@VCbH{K%d|Za_7!`bTE(@X2jnl zsdVluaO$MUaF+thhf$`AjbuX<4M3C$G>y0>$*w#B=pNDT>6hx=o z?B|Ar5+J78_J=^?*Ryb8lFCfD+u!bE7l_nWa}Oqhk@yf4PT$_l5w~(-Qs&mpAO?4g z0&bYRRdep_m(6UZwuMV!Z-Q?Nc^ru@+##W(dX%N>vuj*dtw#|r@8!4rwQ7#nI{4Sj zfyxQF?UoVF{P6k=#}23R+ZLYY+x5&cFPG#pwud1~#yPv$w(t6O?HDQFckq-(!nPA` zW`)jawT#+TeJY!Aw8lJ4>TiF`dFgdaf22X4Y|rOddh&*Ka7E$a)WK>{={rAB%=^du zh#dH0HaNYPI9xCNqHSe<;PK3IK`KM+PHDB?Ud6F zh*kokY3e-DV7dnq5F$ zVpHy@9HB%9?6hb^84{^&r%ujDHy||b{=lVt7$vmhye=`%7xF!vQqNj4DlUj@_JfY_ z>=TKh&y-I(+^opw0=)T%|vbt%PyQ&ycgixi^DYQX0)4K(#UXyoS4?$7d-hRtKYQfV55-ER*+}6(fv-(^3S;fl$ zT~C18Gt(Zj4EvY|G9*C}T*zmh4vZeOKdsjexf2;hBQar7{so&4`$Z4?8JuW2hAsQFHe1IF$1xzb9-b z$Tt6n4?D_rt#=*t4B*SGUt@HOB-!@YG?1DF%(hA0BH$7e@r`K~|Gr0J$ z0dcBMFqNI7eIyNoFn(<_(w^GZ@b`jCWlY_x>DYRD*n zRbGb;jl?wGBoC-^Vl2L}u=R=2-k-8KW1+SRI|s)4bdjzqoYpoAoXqS^YUiWas1&VV zx5Oo{_2$1` z-(tYl!`z8Uq8HrUX?pT>^~uuKa5)zLmp(i?ReOiJv}^hXd*t7DyoYwfzwN~ZWFv9+ zg#MOQ=08}&-EJW#6+FE5>84`*nXjjFFID_t=s1|+Ju>1=HVf&oH&eso?gU)jxGnxj zQabt%=V8#WD80%lPH2%eZ{Sy))7CjR)~aR(5VTV^^eP*eE0nt^zHN4 zZXA91>(t!bZgG-Lw-co?dbf@e1FUp_nZ8oQWodu2v-Qtx`}z92Ovu*2lTmtWF_&4- z1@G4vlf^PmG0_UUxbNdxm1WVrE zHzK}0bziaxYv35m*-qZcjyAL(<=}P2)JKkxpwf!)?>{S*K4R3gSJ3`+^WIyGMUI)6 za;T1=hUorV){-a$SD?n&S!n5;wpz5-01|_05yB= zR{N_PrP$M@O;uZ@&Wf%~rxmrwx&?3t>{0l9|3ZD4dw@KJk4nD6T(8XjY*hv~+e@vl z^VofTZ0lDm@p{J?z_mi@PdK8vL-m@xcu~l**~W(faPRS5wm@F+BptM6+G~4K$jU zv~TFrO6omad>uxDC)U2sdR#443SYk^&V&uE;cNy7i*x8Jw=B*bJgzmf zCKik9p=HM<*Z)Aj%NfoYYZ0_ zatsA@P{zC@8J9^UPszGud(Q8pebS%S)+2e}$3zY@-EhA>s%lSNHvaSI6Z56K`zD{D z^s2Wn>F^DT?RfrW#hYTgy`?(Zsg03#`j4 zkb^Ge=0b(u$G`(A%=tHa#m4)gf(A6(3ptOkm1?q{<1VtTXL}tWc6ko} z=f(JRh3)vWdk(%m&2+43?)1OYJsPLLO1yY>jHw*^T`pp#{4O^ZtcVy-^TBT`Y4IlC zIbCLWh1Cm#H7=$o&8ubRfSo0Lt$grOj_XZH>eWp-%6LNUscTD>$4)$kfD>V&{~#ph zNFXrD?xp29e$EE2^ef%FC)r&(f=D2bm1m`1253xbOqIFYF&gs}=8MU8`|Vhn{SL7d z(OI#Z>Y+naAdEUSCCv82a}zWZ>MT$2p2XC5ZvjFh9;D%x7w48=w>NhXGAd_D`{|hA ztdn~QKq{&dk1t;Wcf(xBu}jlg*H^Br3}5QS)?<`@mR>I&(K?Y=P0kL(IeF9Ti7UPN zfZm~ud?oMnbzg%!e&%(bn)^H4jDXRds{T08`< z*D*0|NJC$ZRA0maxLnHR6CXgL%>&gRUae_Iny~hmS~R_JOmD zXV>Q%7PRY)KOeWnuW>uO(Of%`vt%F(_wba3$eA<$m8o_;JcNo3$s<`eZf(DSIyl}_ zB$L?7d-?;axT3v$`Dp-@?Lg;Gsm>umUxi&Ba}_A!fQqaD-T!gy(h%njqXJ(39 zm0AX6W)Pudg<~lBA1V!?RHpj7pMdq0anifE%LFW z*8!K%9M`5>vGpv&Jmiu8I91;|^Qs7aph+$~Z4EgPhb#V+a{BHC3ka5=ieG+F?srRv z%<;Q+s!+XLO)0M_RXp+DDjAh4p{H|a=@1#cSL)irOr?u-j#QN>33ZbPP zK$Qu3*ZNOX4fC#jCVciIx%NLz^$1jO0cZwSOAF$AihY>4x^-{Vw4Q2pT8UoQY3CU^T8s-1uxztN!4Ad?E@psc) zC+wKqPxO6NA_4taRry4zpF&33%k!QBOXRf@;uX7mh?=8(lZ3Z-RmmV%o46E7&qD7) zUZ3!Pq4+?tBL2#fv^6)gcgcP8@ex0NK7!`e#m?u$BIjc<;az3Teu3s&hc;S`ERuC@_0vuc6F{ze89^mRw z@|f8l*wJ?9>#alz6B8R22l*=uE?S3=*#u1lI6>HtDqhZW?o*WBysesPeE0Yb2RA-a zB_bVcK!1US=Am{(t9@wsyJ7gj(4rJxM4R>9Mi*Y0$UwuA#X;)Wj*N+iY#6kBY<#fk z312cKlVLc{K1T9=iKFZ#>+}tOhjlrdPvrMD)J~XF?YzRw3^1gdYyXJ57P%8<(rfsU zawKuAMv-A1>SWxOb)PPr1s73Tm`;8#j3{Pb1WYdS)!i!D;kUJpvBOtz7Cw-a?7FJULLUjEOr=Z*o_nZn5pdPWFEKh_C@EsGgr8vf6 z91pNO=KN&}fyi{4wfwg9$UBdd^Ewel|t&`j_H$qc?oY6y_NL}ZzmCqYXgqs6YrjCwMip;;7==_1!m zc7P!U4X7cUa#mSAgu z+Z#Km;{j~F6gGMx2K?kE`^mj0o&RYKk1rZY3AOmKO5gnDGIY#77b8l)_7m6GQomcD zY?XO>;?wW36uE}4UV>vnAfnT;deoeoL*4?tnlQ#>q(rnqf_sbF+IOG3geOCN{}^Y8 zOOkOOYakATNd9}-<1V;Y#ST?;lsKhF27HL9If+c!09R0eFUw6t|78A_CKD{YdN~Kr z4el%uO4Gr0u@ePEw8@;G4N;n65$9ZiN)oK-9=XE?{609a8%b7w@{C8Fz??4e{s0rp z&0A>^3u zagOLDZJMYSbq}JpVl3c6m{1BlQZ-0ple*_&Ps;|9&-`R?Y6 z141%Z64PxsR#dus5AuQy6Ni4BKnPJ zKCW#?>KrRz+|L8I^mvhSedGA5&+n0BrV>@~s%Xr+|EI4rkB4%9`#2iR6f)Fg8B6wM zvd4&ovTtdTrDg204~aTN)-)lzL@G-{3@S-SGiA$~H6d9mg+e;E>bY(@&+nYyInVQY zdG&|EJ##PL<+|RVcQVMZB+SJ)Ji>)JC8z9x+)LG-B1de;#q!p}(+{~vnr_eFDlFDV z!cMJK%iG(KTbh|{&HRfJ$=i5PO?y>JT5-q~(sOCn`9+D4u^T(I+wFc?B5*$LY|Ew2 zav83EIlz1uu7PaxcrIK@xF?XOp|Wa+coULnQsPWFniO^vc^ZzsyQv_?xn+GqQp8OV z>UP5s$YyHICQM}ROWO#xnhtzwl4%A^avMiVrV>uY8y$>$U<$PaTg5G+jI5Xgn{fg? z=_1M6f*TLZIX7$%c?)u4wKh)dPcKG1x~WFCt|as!yYc$u_WCQKogF#U{#>WL)^A7C zu9(lIe#B%mxWjt9tXJ$PSBH)1<&vk9?kn^mW(wml<;O!dcPoVCsMCk}iu0SdTdhyG zhx!w`_};$Sp1dhm{~d%Chl$`%*x$Ew5shkX4*$mWg+hZ?m-AR%tdiG&$~85g8%V}f zo|(I^Anno!dzOCDsi(D&kJjH4I7_y!lf0%LpWX;)o*BYGW zBN)=KJ;lco4tHVOVDSmLs>rr!Z-jKZ&UeV2>rz4(G=d$KO;*3nI70_8>wJ8fy3_(6Ag2*3Pfi86T76jE8Fic;S8hdyU_3Mn8=qW%sqx))1Ev@os7I%* zGg<#UAc-6!aCT(d8BH_V<3pPdcS2du5;bm!kFQeRo?wb4zf7X{@GwVL{e{sG}{T0PU-b+31Ic=@PwPUMDkkN=r1)3%l8-Lh(7 zuuH$(NZUeq*S=RK4R|u=&5&Hne}Pw#eAopwMtDCV$VTz6bnG-IYK<53%^;c6h0vk9 zFG06#d=Q4Xv}tLVu{glL2RHV4|D9i3n8;+99Yjce=LMJGjNqIC z^K2O)Bh5+=u~5n@dLejKZ{1m`a15Cqw`WU9V#M?i@^9+B(E~IVMcKE~nILl{EV04+ z&13On((uEt-Pa=M4*xwLjP$8f_8q*LBiSobyA_u#Xj5`pk@-Jl$XS&@GdZ^!+s?^X z#Ml`XDItuQ8O*F*k#A&${u2$W{_-ciu-kbFAa&b~9qwNd+TR1oR=C#hiRvErTT?50>Y2r7zORM9xB4R=RMAK8Dz1L=ECoAeH)} zvO`POEK?;GrD{t3U|}eP$+pq@0ySA{B#WiZ3=!bS*saU@q(*_jZNZbOZZBzSy@gvb zYudsEHxdK)zc02FfC%+GB1Ok{z=u1fdoI&IiAiy|A+~W%Hm|u^jL2Bd! z2zUCkh^jUSKk$BI3vva4*WNWVy3g6U3DKpkl~Nxu%KiEp%9h6mH*`kT9BZ_KRJSB z$dqkx1ZOum0*KV()xq!5Dsc@|P%j`FV6R_8O_MXc{2by-b92{_#<1UL)Q-(RSd8po z5fs>^6FH`gtiY1Z_ZYSB{o^?O6q4r;M3YoWFmOv8ERlA*BAP)vBM>euhB6ZhT`M07 z8jpMTGspKCrmMoa<-o}H@OmhOG(rFKbMRj>X#H+z{!t#mU(I~2iHJPnG=H9;P!7Nf zt`pFp1D`<>U@4JYIdk#aZ)-#Hp(O5dCLGyx2{5G^6c%ma8|RSV`2PcGi=nbsC7k%( z5r44%C6GoJQ5{)tX=U~=Ce{Nh--6_^mZ9%k+`Ia<+akSDC{*)c#FfF?i!zH7w+6jy z%oN{ zx!~RxzH{UgpqadM`a2HOP6t-sJLcK$_{0Mz@qTfMIbf8@98oGg?S{X8h$uvcE;eGK zNzaY+BwEaYH%00v`zLP2>@~y>uvUfGtQ2gmgQe68Ca~yn>k4QYYfMukKwn@kSG(kJ z4)B*E&+{Y|;Q6_IS&hhpYKGahnz;fB_S6rQ$-6O^X&_p1i}%fdI);ppki}Pls-8h+IH>ibsyLY8nEbL z0BT%z^+U=o-{Vy&Vk3Y+c8dC)FGamk4qIHiYjfqH{eltR1E;w8vbMar z>QU)v>30yn8<@`f0gz8o&(E+;918E{0V%58-tqLF%V~T>J+19Dg>`Oc_(Pi~Q-zPa zcnHz1ZCM=LwDf%^jWYxt;5jP1p*@;a-)s>u-EUc7kyESZvS#%Wotl?ZhHnxHqbLi5 zWyWFPD@apRL|qa0i>QZd7CHL$%ZqKIz)vP!_kL_d{lr5*`7)9;7rsSK!DE>^iu$xn z?UaZoVf|S4o{}$oGVq?df92|ajzsW?m^}{oB*Akx@_1$)$#Q@3SmmQM?Dacm--i65 z9i^}_0va;Z%ql#y?lo@=Zy#Ei%w4>j9L)gXI-Q*b5ygBq2dGEX>lcFqpaD2v*RW&F z#L)@+i4(f#XO(BzzEd$Q-S>j3MyxY*e?{7q6~5_Gms(E!IHd3~I{O*gY8;I#U*Ms8 zrD3k0Ev;Q~r%R+$U(Av^hi^D`-qv$Dp!lI&ooX=~uJ>Epj=mEa@`Q^BF7l3oJN46) z%y}>iEA_yooM=eEKNJd7uyl9AzTYf}G|!57JaFWLirUkn!}YR4E(JuBpp(%!53sg0>?PnX+#THSW{)v=hd z;Ubd8{D-kf+Q}v?KEQ0_5K>oUtagY=Y$rU{DRhx0QL%mubzfrgQ>2ZVm^GAxK7B4N?b-$TqlQ33e z@@%3@WD(VVqE37Fmqa+WsEFG3rkbp>+&VeOJJcT@&`_`T6(t?D;kvM6$`C1na1ig*nAjwW9!|=ZJ#mP) zkgoL-mu~qC8k>0lJJNktVv7X_ju~(@p0Z!o&qzSAQ1639&*;VN@J ziS8if**d|05k}|cP6Ht?@7*+Y5^{6Ra+4IWtQ|DTC#rO8O4_GuUoLlQhEJIqF-LGp+*g5jxQd8R*8(fS2v=?y~NPyGaH@ zG5qaSPO-7}Pp~UB`CH^J^DgMljD0_0O9R<7iZ0ngA*40aV&W1qC$~|2AaJ1Gm06S& zmV@FkT{`_L+zL6NGjE?hIo#2)t@rG)aX8R3(w`dJHyal zzkbqXv?!$8A-?##Z`!-tdKBH6FuAm3x`VBipzJ;g(@fl?9GK!RtR^uJR4>ON=->4>o%S5^4;c37fe&=V+vf8i#7TBet0<6RCmwV4b)~_(E4R` zE1x;&O8rnJU!9-r9B~zakB7j4!_@fPBo=v~cERrqRis-DI8A%l801BUi^hXba$Ptl z3;wZMrNG_cd3c}WvCgRpOJlK5vs8)5~c zuG@}n25vmsBeykGlnJS#!=`7BI*WguRkWhRz^X3~{*?CxEB5W1ZAaE<1!mWqq1Uyy zM=r~l82sDEp1Vqp4Oe`bk0ev*4%3D=q%2p zf$@${V@W>w6pE7*NsoY`XENPk=Yw+y)hWa*2g`qqjdAa5IA`%G%qxZ?_o{}I9OKm+ zjzdA# zh*&{395=mLH$*Hf;<2K@UI?ksJNKB{agDg)?V`+3IJx6ekjQv{^uU|2ACPMN6FbCu}V@N4%jK@+FGXE1Dp+73md>-CwiG#OQ-|`IJ7FIv& zawv>2e(bpkECuGnSlWQznSuz`t>4VmB)45AH`~L`EX zqhv%5#^H`lXzE|Qk~j}*{v%KI6`e-fNs5AlOEyEr%W3$@xeAEKfAUH@#t5|;d9Q){iJ)sWDLeVQ-|yF$)nWl+dz!pyt0r}g zHls3FpGJ2Wek*pm%k{)CC#^ROvBwShK4X6T6)9wk1fs0a4Gb}Y@d4P*+#C1v%Vy-_<( zW>j;q;gr=FnZG2`np0&bfrL}0TrC5hzk0f&rS;X$4c9FLCPgI7=B}N0wVwCmDT&H+ z^O+u{i9m(F-fYc=yQi=z>Psp^{5jfDN5p&ab!PAwmA3#2ShYnazi;%KQc$q9SFSwm z3|OHb5~VIxs#CO36=$KS+C)?YnK0;xa?Hu$e}5cF%Q5mqlm3_orzPr@@j5s{RSNwP?7zwu{(L`&`hj@j7#dM-D)0RvvDuV` zV);Q)9wT;O1V)D4fj7sZB6e&o#nn;J-Tgs|qs&n|wx6^{W@7l7;wn5^oVHAAjM2~< zDfi$N`U=CJqR`UP%f^-GU=7=Qg3eVGM|aRA*$^=OW?|eeX9r`tkoylxp@3I7ZZTfB z&~E&-KI{^xWQ8LFqHk$$d@i|^LiBdZ@~;-;y1dU* z7`me@vQFZgST9tH{0#YhB4<}zT( zc%@LtOGiw?=py_ZHsN2-N-DhF3NpMVW*RmggW2RVhrEreQWt-2WxZOTx6)