From 3540be65cab4d636cd83e0b8e9e6b056c25db72b Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Mon, 7 Sep 2020 19:00:10 +0200 Subject: [PATCH] structure --- gengen/.gitignore | 10 ++ gengen/Data/GenType/Serialize.dcl | 10 -- gengen/README.md | 2 + gengen/gen | Bin 184080 -> 0 bytes gengen/{Data => src}/GenType.dcl | 57 +++----- gengen/{Data => src}/GenType.icl | 40 ++++-- gengen/{Data => src}/GenType/CParser.dcl | 4 +- gengen/{Data => src}/GenType/CParser.icl | 52 +++---- gengen/{Data => src}/GenType/CType.dcl | 4 +- gengen/{Data => src}/GenType/CType.icl | 38 ++--- gengen/test.icl | 168 ----------------------- 11 files changed, 107 insertions(+), 278 deletions(-) create mode 100644 gengen/.gitignore delete mode 100644 gengen/Data/GenType/Serialize.dcl create mode 100644 gengen/README.md delete mode 100755 gengen/gen rename gengen/{Data => src}/GenType.dcl (70%) rename gengen/{Data => src}/GenType.icl (95%) rename gengen/{Data => src}/GenType/CParser.dcl (82%) rename gengen/{Data => src}/GenType/CParser.icl (82%) rename gengen/{Data => src}/GenType/CType.dcl (89%) rename gengen/{Data => src}/GenType/CType.icl (82%) delete mode 100644 gengen/test.icl diff --git a/gengen/.gitignore b/gengen/.gitignore new file mode 100644 index 0000000..b46064f --- /dev/null +++ b/gengen/.gitignore @@ -0,0 +1,10 @@ +Clean System Files +*.prj +*.prp +*.exe +*.out +*-data +*-www +*-sapl +*.bc +*.pbc diff --git a/gengen/Data/GenType/Serialize.dcl b/gengen/Data/GenType/Serialize.dcl deleted file mode 100644 index c0e173f..0000000 --- a/gengen/Data/GenType/Serialize.dcl +++ /dev/null @@ -1,10 +0,0 @@ -definition module Data.GenType.Serialize - -from Data.Either import :: Either -from Data.GenType import :: Type - -/** - * Generate a single parser for a type. - * This does not terminate for a recursive type - */ -serialize :: Type -> Either String [Char] diff --git a/gengen/README.md b/gengen/README.md new file mode 100644 index 0000000..6cce793 --- /dev/null +++ b/gengen/README.md @@ -0,0 +1,2 @@ +# Deeply embedded generics + diff --git a/gengen/gen b/gengen/gen deleted file mode 100755 index be20b09c8726b78a270899404ac2396334fcab45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184080 zcmeFa4SZC^^*6qoB?t;?q|pRHZZs$$F9`%tkqC%@$u6J*l59e_ zT-U0tudPL^RkSZ?Yej9V2_XbQ6vP(v%vLG)iLjfX6r>Xb#vJBlH43N1Nz&tni7M%dN6321ocv{RSx7OR#lX`={x*azg$!A*;lC^= zs=_BuQ%N`UB&js(X^c8)Pf`|BNM}iq(pM4UhHklNd&3+;hYghS9w$udq>^qJTaUc) z%y8;0aOyc>+k92;!2K$8>#;QJB{}tyobqnC-C=|qy8I+h_-~cd+^V=Nq?pcP;29); z8$y=lf5UeBZ)UvD1XZ!m1VyJCu5#LQL$}^=)N3Uee%v3I?IWD_TH=exq2CRi<~^ql6&Jmy3!tcfdcwm|rrj zb=5`s#QQp@KKsOPM=d{gYM!#>8U(jYa;66PYndWfT@p4-`-F6i%Nx>DI!j(8J+WlWt|LiG?>#osR6Ar_S)) zGTA?C>dh?cpLw$n)dW);o!PoCuW+;-!1^aB+G=+7KBK6%D$ zQZl)y$Wt`=#+$J&urWlZ&$`h+MfzAcr)a8wvZs*wf_;*I>dYCQ!oZ9uPyADFn~atx z`)A)2C`5gSBT{|h#JM2G&&Gwu4#k0>nY)`ToZl)0nUH!{2-ibu=`)fg{ocJ9u6sz)hz}d=N3lTGX~Bz-uY(FfRIEUJSfV6zcKZ5Ci90?*2C=2Hw^M zBAgWi$3RB^n;QdnOkv4e7z1~0F=i}|fwzld@p$fwfye5@M`GZo$CQ5}22NYc{cl+e zJlO>zd?5yYMhyIw82Fhn@X8o?#~ApU7`S7KOYVjkIOX2`Z*vU1vkOGHJq8|Y+=XM{ zDKX^_#K3T(ss{`^BCoo{Rq!CV|ohn?d|pWFLevkRK@lN zNx#c9Rj^$t>9tH#_1Z5;dL`3Tx%Ly1evN6WTKhgp|CMPjDfU81KhHE(u02cAzh|1N z*1kc~k1fe>9d%o>a&MQx;@iWd3Khh+b~U4XZMkG9Me>B zb~j0X2T#Kksx~`G(ubI)O0zwZ-orFinSJ0G`@fUvZcJ~N^cJS6y6g>-ewS&gEW1+D zYni61vR{z&N~Woz>?b7s8q-uw_I;B6E7Md-_CiTN&oot$JxkKRXPPR=zCqHDF-_HD z4@0`|z8rJo1jF2E1V1}4Y-CPtWm5J)k5OCoLKcJCL!Gld^~uMl$9cZiyAJYrstbGT zUCU701Mx=sl_VJ2MkfFIPp7di)1vho1k`UYysx@2wnCQYbtzx+r36*S;|=qGQ5C+z z@UAvC9{0D4Vrb=HXj*?^=9|@+EP*pe8RqWr0x)>BwgM3E_-co~#_dJ!ExhmgQKQFX zkIWvGJvw_#xKfcAI3v6VlfW=jZvsEU?+^BR!gpZSWlzkWkUc)TVB&=F<1Fp%@8diH z?G?&(b?`f{KfY*qbu2ccR;xvI&gSqf4&w8|_bbG$kz<&dBM{`8nb%9I|40V4m8=mt z-{@NzIkyo$EAt!{w=#RMoYg-SL3jr`97|WV5i0Akkj(}6_B77dwqtY*Q_GPm+7_mQ z+r5BXp&+jaB;3mA`>s)2oz03zzCw0SmHlX=Z2C4;cBk8jsInE1)uD78OV?`kfbu^m z!5gGvw7_sTY3`;l8D?$xFW=YK8|GeUO1lXIu&#SxFAA+&?G_qyVxde9eP9oY z6-YmPqZovI3w}v_zU7}wusO^ib1Dh2(pNI5+MQs8683|Ze=r%ZJx!8KZ75Q!wF$uD zIjreOWce=urx!?W=1i9L)*8WDmwl;(gnHF*L{@9(qFz0Ue=!Zv+Uh5ug%4|QB9Rq{ zH@sVojLi$$Vz$K_8R7Yuc{L6RSwM1Fdy?h+tqe1LAzI5Z_hVt}3HDSw!()Up*C8W( zU4j>s?u96P4gR73VE3wSj!efC{v8XS&BC?XTDPQ?xekqm4}YuVBBo+^57scy-Wg;p zOVrC26R{&nq0DsjEc|{vkXh29@E@2R%Ir?~zZCpc_Bvi$tAc+Z2;Z$rbzrH7RVhnl z-=l(%3La8H1%mK3tW#Ud6)`;PIEmQn(qUz$korqWy_M-@yqD@pH3s&^sc8R54VOB- zYziED_8fR?MyXjBhHjB*Rb`kP6o@SVG|a_rz7y_A8qr?J*AI^AhGMI|z4KT*SlP!2 zuI#fo+q-ypoLjGUHLV2$)wdiIa>tXJE7_&;eSx1j#d6GVIKeO}?}+2X`cloU>hQ-< zZg$5RJW9~Zmk1`AzfOhF+ytvncn~m4ox>on+L$!uyU1C~;sP3kDAKO5WbSc~x7arH z6&;Px^p0(;!5EvN3HFEVblvkVRTw!x4weCm^*Ft?Y^zDSMFKe8QHU=~Xh_{5E%_p2BADrL)eWU97>p6)=`J4W88q*NUyac=ozbpFB z9j2y5da=mzMnwws_E2B0F6C&4>l+ntM|6II6+qWyl*7{+(`2Q$fiX(KX+o8Cd!iA# zBPo1Yqw-@6YdCb}o;VEAWk$(<>H|c_#z9OIMi}OIM%osmYJ0p9%KfOLQU8wNtuli9 zy~Rh2&@VPdbi>N7GlDj#KE(*GPBelMZ*jyhzs;LCKGLfGc9j?0<1PNGe)o98Y6s1X zLeg5Ck>02=!#u+>?c8n0 z@Gz9Q^eY5vu@7JQO?`b-bnK-R_u8rr`jwtAZAZggW27@>{}!oH*F#B!Y10Ef4%4~3 z@{ZQ4z3E1Mm2qUVVXpTNK=0ZV^)X&s|CajCFwyUw)GfiCpt`z`==rowMisb~wrO!E z)Qzm=mZded$YL*XnQM*uwMNGK#rl%*o+WXM&svO$TVE5gS9{sFN)i-_$BMY{Qcs{x z5$I5Dg!0Zbsv_|@X`jw-H9Y(d#yuY#f>Jt`8}iLvM4Lx9%pu@%ZBpbk&U}uYiG{0H zaUNRLhNAKs1L6V`9JSERQ41ZFTJU#OD#70)y1a0LV#yvbHc|g|W%UwCU8WKu|AqPm z0~0^pzVNd_3%|}n5n4jkv8z~cZ#P#Jei5GVl{+X_LXTT3+la2$Znzo4hDJ72h$k&F|Ai}2CNZU{yUJ11eJ%4l(pz$!)yw&051l3mM zl@9boBH<@h>ISB^g@2_|vzU4(T&_}6n8GlgW|*TBbIq$T6IXW(=Rj_9t*hz`YxDub zx;AVCzw8J?r4R}vg}E6(CJJ180GUaW36T$T*9IWu=gY+EFou*JJT~llsP8VMGwpj0 zc`gDo3~{AW)pz^+S=phZj$;t%ef zl539a(Jj|3=+QCPytzkGt~tF22CQF?LwdVGJ$mAAZjV0rJF>^6_*>8;3x99!Vc_rd z9>eh0-y;uy=k>TDyb60ZDf(50t{r zqu}OpCN1p|W_sV}pj3t9U_M$zi2uTgs0~GKX#o~NX815X52Mka4yx*8LAV`OtafN3 ziiG+h+FxgBOM8II0FZG^4<6xWj|NY$CJ`1?*>cLYz9R29EEv5E97WFeakJMMCEs(s zD(;KIiOal!4%cIHgckxdj#a5UBhO(C;*>E5Cx#2z05T$v8YK}}Y@RvoX$BRQk|Mq0 zE@*(r_``z}y@B%p$IRd3#Ui_{XF>nVE(C+V?LvP|qWF6J=Rzwkt}{w@)f0@B7NpE;H7xuZl6kQFYCLur zJ`j+dWPi$tH69(SNfK6+vW~vu%H#Oc*;%~Hx55(4sP>OAg7Xi+@_U|@(l*OH1n%pH z0RvPNVun@FBPl$bIN~vPj9{-G-r_yjd33Y`s-**lzI-!?*ygb(#X`ug(&2#ELtLkBI~1)bu|#w zo{2@`@Jer>pJCn&P0U5}OeuH=QrP%8RuF((Nny0?BW^v|A43MDV^E68b0t~w?eCw0 zNxkS4ZmvqcrOiF(PEeZY?}a2y@xWEw>K12#=TN#3MD4)Qfsj0sJGf2{egY0v8>uql z(IS-}#}@gA6fwD&puUNfC-^1S{tJ!zw+$0^gV6Jk6bjmH6zZYEL_K)7fa~9E44o>_ zbc(%R@i<1I=#s)N>Yz$#N+a5v=c2q6)5F{wYs(RTtiZln$ zsm^++E_1I|MoteNgmwiFWz9U(=>ePJ$e6I1RsWp9yf#S>(q&f-{NCB~h8dwD;8~my zgEp)Yz&{56(4^F>I_&WVE;mABIznlWA)%eb9>`FGJO=aTgy9W_z3@T^14jvMRy(({ z)62^VE}GG7>s8RdUyX$>s|qJ5T2{gy>I#h;ugKbY)JiCyTaLkuPrh&*3WCt`xWJ>W z4KviL2`)-(H!jzY)66* zS9$evI!%p9*+)6S@2$nU;>b2u^?6whgB3eBgDWxmn4iH~j4C8%B?!@xV$0rQXLw$Q zs|%uo!N#PP@uo&V$?G6>nDm_3GL9itaD(tnshx5YFrn@c=nUR*^tiu$l*V&FqdkVg zOD0Q&z^N!4I7JHDM#um-3oW%XGFHN}>H}n$)5raf>GxRFU?3ycO3FUG5(;iC5Dl{O z>k6}jcOH+MJtEf{hMYJshTi|7`igN0Ms3`@iY!k~@cX2Br~A8KW96O|HcaZMwf1}8 zkq$KIq*o!G1D-g^zatro<7%sIM>p?LRt?r2bI8%l9tLfSs2a>vMN|oh^3EOy>Mn~b z&dRlJNE#X%*(02Le(L#oah{>(?wpd(4nQm9RPAe(Q?)lPC%F4)ZhZP|WDd5T?m{<77wm$#r>yjB-$vKlwJ*+5~CsMGQO^^laD#mHv)cZpB#gXTi`>Tl(esiR?c%cW@wt=6#CpaEXrg zCNvOH&O)`R3|;B9=gI^@4e>86(47tB71#=Ujg2tncEJZRI!t#2@X)X$O5x52WKc6G zQ;9NI-HN3nuNx+oEMX7(wdRPhvcJZD)mClil3BYlsUCrq{>labVG=I$V$7`DL`{%Z zOw`C1*d5<+2X@C9>-|2%JkJP?0{?DHj9{sR>)||DtNFm0V;;##!%WkDJqoz0wztYn zt24aXVWe`Z_Qy{MzjF}ceSYSj0VwKuO(@|F6v9R)<*kt@Z+?XS#u?sqbo%0N#%4WO zCz?R(M}k$+97ZkQyR0$5w+TVf1=!e08hd6l#lyBO?L|SUoy`<%KH*(T7o;LEQBt-t zH$G(~1LT@14@mKpuNYXqc>)JLHaPD4T!7je3}8&KQ*aKg)+ip}k8eG~q2=|uxgON6 z)5C6gZCjc52^tKnmmAVMnKCm^C7HEaA_54t$9_=td++rm zCuJW4Q~O+kln(`{^$|QUf6Qu9WWvdk{#$10f7;L*D_85lMMfr_>GNB`55Wj}TGSQ0 zI}s}@y2xiFsQ9wRx(ibNM|7a0^)c35P5~bzHibWZFM%x z?S_dNIT!QKfG!x;5qwQ%Z8NW%Vb1Dl)MoWTlfagBsS{?2O<9{|h~Ze9HH?-g^7Ckr zBD{f)UxZWW3`RJMRx84}r3{@@029XYUZZ5yLLkNQ+}QkFi<@d}3_9jo+*DiKR9pRe zz!5a4M^F64rW${-sm5Pys__?_YW&5f8h^2=#$Rlzv5T0(eY%y>`yI^8knfEEC+IqV z-!Y?k%qXW>)|IeE#$m3`O{`Bsnct`~fzNYI-;uZDK;_=?6D9(Q?@^2g82T6k#YCG6 z9EN+qa11u~&4IqyNa??)`s;#?S9ZWZC2+b?^4;Va{;7dBFw7@q4;>W194tvqM3wse zP&VOh`+%di=C@@7VGfK2d;7i%1=C8Yu>@mdm@dGL;ltHlKg^QWJU@ z@wq+V#$5*@!S+Ps{ETSljabT9CY{m%TwgTb&@mf18Ci zO}K-<_v&Rl(uddlBUop$EaNP+W&|g^xfu&I*v}K=>am6yHmo}^6Q*MJW3{!45Mm)W zry;ykYF>cy!;Tvzd(>LKq9+{8epm)oSm~EDMlZhw%WVYS z7hvX@f?&^vo|%e&Y+<96%9eFLbMm$1qVL)_86?kH$3CW^Pg)UY?t1^lIiUosrP#R2 zx>prRv|cz0~x zr_6|9bZ#9fg;9>pvB;_7>|^?K;KC_-b}{49-6#{kf!p1L9%%2Bnpj9ot(H+s+u%aH+HO`kqV3Fe){)C| z%+IK<+@qe%c^LQbZ$IalXFekJzK9Q3F&)bMD_RaOL|iQ?x#nl#I9;7pBv^Tqhx1PRQ~FSN?`q{X`aYXqXfsmo^G?XVD8ccZ%%M^JZ;nK zb2IkprB}Biy4DUR9lJ=Ro5!Y?LrhWFYdlAFrK%WptE!CK?Z@qUQ||1eI&_S7k_meV7{!t~r1 z2a|kk9S_E?r;C36LG~}mJ74zXQ$U6^o7KPsI67L}37n4D8nB5I=rV%GpjqfZg7QZ3 zc6wPAx|I{^2XeoHA(?2Dd@f86)_AR#$#nhRr@$J_QoZ~knkm+KI8j&JT7-0Aa6UGz zH{xV2DaW*P;Uk6~DcKzzxIfFl^+N4Dl(w?4JxO1E9q^b_>+}^_SU}ce3z{^qU#_{< ze_D=}>kS*Q>+MX?m}9k;cwfX-&3l^EwA#Y^htfJq_~!_b2RRL5h}?m6VF`%z&i==b zpz^OMuG;F>q%BanpcSaZnhmAzH2e_MC7KN^XlT-3lJV!lrQAiVYWbn%Mfb z%CQPMg}K%0auyXXGO*L!%GH^<(tHHXOD>c?s+(Snnz_+F6{O^gM)o2$o>Qy*58`{7 zGzGpD$TRc`WET=}?^bGgCDQW;;d~LoBC^;47iZequzM)%t}F)kadruvjvSI?k;PvF zzbzhGtU@Kb#U%+z_1_Im%B^c$4C1t!6Y$3A_gqbJ4dvQNf!`QbPMtj%7_n-+iNo~V zj5YeAY!Ct@08PX734rEw#&nN!WM5y@2K7Y=$X&;r`qg$FWP#06DX0mcFZv8HRcZ@j zM#(<$W0w5|4AJj-2Y+KqyWQsI8}5BIHx9V-Li!c)S`SgKiw2f=sL;#r757e!w{?dK z;bOlp*|5XGiUjyYfr=ImH%41HmG#ish{$YBmZ4!SX+uNbUc>ho0UHdr*sdmJfI zqx^iyITL_6R`x3}30xIpKwn-%YcK~l1Ve+W>TeGhyR*N-qlQ#)pljNsr72MfbS!JbO-gtzcE z4>uI!^9)#rw3k24E}&^^>*#0r09-vSIJfy0bC_Nz*13kxAg$03ny9Y4p^3W28WJhCpvSD64b~t zyiZn*4od?!u)K1E!MSyNBIg$y;$A7(#%o};@a}1{bYi1qUX68znfK|r+mxM=h4 zvdQh0+1Ci&j)law3s87mv~&!yvp*E|5!vA1LA9oreaq>A8H*)4Z5T~k{oWTS^^Ll* zP`Z(@G%xVHVU713u8#9RSs1(v3+BXJYjDy~vudb!L#|n!Q?lJ%Fb7*wX;66rmdx9s z++;CI{*}Q~NqG0TX6E2{oNHzuzfTs-95d1WJ?O!D$>_s~s#@cl*0ORn>_if6KZ@8h z@kcKce{}Oy>*WWiaunry*)AjsOF+GMcG{03|F5W^2zhVFiR5!N!`jcq)S>E=mKms* zPmU!eFG|XSA4kg19a5TEYc;5s6bxL$VvEhXT5Lfc7h9E`G|pXaGcXw<{hAdMWsuUM z{eX zsT|BW#}k$x>t56&Iy5o!U0?JE)KEsiZ&+6@{D$ZTvn{4G)wwKZg}U<;NH+ABF^Z}n z{bcq{D2S^qA>*(;2GM9cF`7bOMAKEZa}n{n#s(4>&g=#;l^TfuSdcd42SnZ{shQ4KLkGyZBcqRfn7!{M(k}{ltJT5B6A2s8<`<730RLu2Al9 zQ898ZN^wc8N`h@Ii)&SqDv@ix?-b&Fn5um+dm_a+nye1CU5XoguyrD{zve>6ML1aJ zoqZL#iQ^a(_B=d!ju+2LdGK=VhbjNe0BL46PI7E`ReX0b$HEF`VgYT-yDOHdD9!uC#Ta3l*wTE9$mLR@o87~@HZsp-F9&r)U)(%_oA9m$;9T1+7X zl?>ph`{w}c3#^oF5~N=%MOHHpewksc-@K!)J4!?ybuXYY9CbSo&`}5L#bb|v+=zc- z6s?<|&Ob3ek?0!y6FX^2wd9|uL8k8W=9r8BWDfLP6Y5Zx6Rb?k32vW@!@#*Y!Fs5E z?qaYZ?SZ{t0BaOo?sTj0FxMs9;O#cbdTz$H;*XUYRu)G%(fYeAKK&{J)eSAVt>oZp zFk1;c8@U=rcNE7jTfm{07eUXrj7KjY!F9k|!tQW2Y_aD}JTrS>nKc-kA+UwUIi=jS zIb|CvHs=E9l>fvtQ;2$k^*{8?oQwMQf)+h9ZIDfh*+dJTna@NG|L=KbdR(fW-j3(AU>T#nT>0@4w7V)_^CZJi<-36tY?OX)c+-(nRXyWd1hK6raUu$g!03= zs=ovLnQB_sV(H#F*WQjI)lq}2!DX|OqVW^BY`6~C|09=8U(Vndm(7L12>;9(xbe}% zWwSzonz(EZVjd{_=nKT?vf<4{?ptGBHtV9Lst}7>Q9qH(<}R^6nsK<$d}+aD(;6dV z4@5?d&9j74K`**p%!Ke@~1IIffccQ$Z0xNN@Ua!r%4MVslTa@o8ISva`` z^(;y#m(AlW3zyA<2xDC~SwgM2Y~Ert>av;F)Me8;>ayAVzwNTI{vDUigdgp);iYoU z*cg}1-)JK>@BBEyWpmSy@_974Y_?x~qR(UAMLgzc@Y*~Hk{quM4_B14@GYgaAzv8sn0O8i} z;hD=xd>zoL;rYm>1A!?k_kSd)iPPzy9W0>$01gXdsMMkoa8Xa z!qI1WP2feNb&bhWP;dA&vPiEDgP0!VOGA-?Mu>O6=(8lAx8Yzi@NFZ`3vfknK4c{)ji-Ufm>)GQClOz) zXNFgY)oI{pbV)CL1|u$qdIM6IlAEOi6k&&c&Yo>(hJ!c_3(RPpuvGOf7yaUS3i=2a zxM9Ne#rrbs_()_0dGQNh4dR^r?$3Duk#T5F8VJUHE%>_OjMYqOh-3CFVtO!@^qZUP zZ)vUItU}HfGS=!9N4c&5cPRT*@s;N%+BQM1PoHlIg0BSWxK<|zmHWI!$vDSRea3AY ze(Ptq<5)sdqw%(GFKb+O?{nDQI$=4kZt4{e!8Z3+;znnEjq{atdBSr4C8)dMTs8K= zO7yka`d9=)*{4Ijpg^3R3rxh?7Py%;Y_fvSC}ju4!H6--dafJ7vt9U}-L1RQF;;xdk6>~KFO zC^_7(Af^W|=1vI1-9{~JxIXbZRy==uI|UhB=>o0n_J{_qQ8US|rTte6pHR8E)fL)_V@ z^l|#L17BMGV1IZPjK2RJWq)jczTwgn(;ps1zbi-4IFT05C3=7hiRK>LqRG=DFFzJ5 zOAW~eN|QPs@9ogv-JxIV!($-V;w-rm=ML&)sAc8J76+ev6o9ZfP$gI5HW;s)w^exJpmHupZ zjIeh-MlgDY3N8D9Ow$g_jnJ^ee4QlYBfTPxs7$ZjU8V)JRq$AMe3-?Q9Q-~gA4*v1 zqlgi8T1HB2TPcjdwuzzs@^C2p^v7NFhsI=o6CO{)af;6Q=NKsEL6`N?1u%0!uPR`roGuvGiMr$0Ot=ZR3zwSqXjYfUspndEd6*}r`l6TF zHE7aM+bT*Q)?c1e}=MyEKhh?FMn3fLem4ZCamN_1UNc0%+R1E z15xeoxe`1+l0m2-8ADOi4O(4ppS{iJwuDg&~jd?bq5^3+8G z!Tuf{ojbso5DvL_cX1i>IAX;cTPC*ynet*|nt!ioewn6(mHaG&#x$FMm$5s6-ZCkg z9AF^yjsm@rp$gqC3SHihN7rAWJ2#5%u&5?W#K_Vf>rDFoCemd6MkswN>cIO2!Suf3%39iMHtd_Prdii3Y`RTSi51qxv zXam25m>#^s+49^(U1j2XV$B~d@qm;_krH32rR*o&41L9QOl^khJ2^aPZiV@Q%}}+} zNixHV-XqhW>(s$%f4kzq}_0h8m`+m?4K?M zUR%D|JlX!~mJXn}<*iQ4{^>9k3^prY%I3t~Kk?MD@%|~97=Lj8w9LWw1Vd;4wDok< z{CD!sX9Qd0`$z7};7F!385irZ z|7oWNZGd(!VtR0yY+qV%=sfu9w2!i6xKD z0quAaTZ9w#ghuG|?kNT!C?%D|#BW~c^M+-E8``kja6x+zw*)lMHi*15@>c(gAlF;H z1PQ(LQG)2LhMT6SgI>0j=4$ zK+%Yk+S@R47QTYOh#lm$di#D%ePwL<5#zV`IK+JzQX$^wQzf|=$-pm+MwhtrMP;PC zc^Vi&bA=w8RM&57Efn__PD${s)&(p{D{BK?&Q{7ptP*Qp@fP(k`R1L@=IvdbXUD`Z zS)CWCaNV+ZK_DDYGc90zk(`9bWrh$P{MIdF(930!!8@fcvBPj&gc3p5(P@SjVuWEX8ri~Ggv9rcC^LeqlJmZiX`+YGy%J2l^oL0U_(#!uSnhReg z)mCF(dT=fwUnK>m^9!EUgLAr2@IqJN9Ficf(fSkW*uEdxzZRGJwW4wX z1f-M@^$n8$*9|7nagMiR0>O6-H5kIj$!bEtWenAqBdEger^k+!^PXN-!>XKA1F6rH zrE{tCl<`cxRCJz|QgSLM#kv-RQaYOJ9$7%F}q+-4^?RE~?*aqJK}dhz@_9K8^isBLnIAo)StWcHOO z^XmpHu_UVp50q~g4XBe5o@ijetL!}9Efpv0R3Xaw6s9>R>q?Ogd>)67;^Y%KdA@*O zLE#9aw{jTM$&B-TexwFXeVX&Zob40bz4^%;n}t^_3>679b@4cr4UNK^IJX^(*ha?N za5}@gY2kn)8-7ciFkgs|>Ok}7^1YoiNzfYR37;P19KiE78|R!Qjx<0*1F^WEDn9Gm zan!y;Hdt57)L?ol)7DjqBY0dOFY=xjJM+Ge_kRwAV{O?iIA0C+m9GX*n4kX1L?mbS zu~V;=v>4@*{}%a9tiAIYq56Q(J_ca;J)8Y`xJS}qO zgmLPq$sG>p3>l6Asdu-At(h)gw=_O>I)=yFaeL&hR+uU{D#CLdyRolXcu1g=qtI&z zy`In}Pr~tOnrY{Aey#V<$1IqQD*T$bksTI&peD=Ud&2mXvJK<_L%W*yQ=Wq%C?~GE=67qeB ziyFBZZ^9xtQbh$Dz}gLS*1O{>haWj0yqIX2pFCqdbzFdzQqG+DR;yV@KlA92+|x-5>}&_ z5{Z%44Y}5!^`4D*L1p^-#7$pv3e~T1A9A@s^llzL7RUR*N2)neeyqg1@TPTVCmlGz zBPcwtiIH+SQ2R*oiM+;ZRqs z8LO?2Ur|{JL8JScd_O*ug8*NK*5f1VoVfGQzNMW?MA#Y1V?((3gF`Sp_*C3Ar~WOM zrB?bWDAd5s4GD4VDIPn-2VS^|gq=X6cl*l^;}r@l67~eH6zX+q{Kf#@Q~<#s#nlFA zEfSB1!yM9fFp{yR=nU-Y=A(&XXfr7vng|ibu^S&rMUzmPMNlhv?h*}WtS#z@XDWxX zJOn<@c`_NlB!Rll8_1|o{En*Ep+$nXLCe~Irm6)|(lGWRl^|(Zd;mW_5l)Eg;fR7h zw5M&0m-a}XJm?C_*`!d|gtWh^q9-8@GK;rI*?v0PM=L<5P|K{wW3SIaf;|4ua8wL! zpLHw(MT;WR9Cvy*shytlsQCL7H%E$sVkYD9aJ}@OL@_>wIxsr91F7@L)5OlnCXS={ z#I(y@7TO=@6vE3@7zYRw3gPKu{B(oR{v_-h`*s>Rjq9y&>qU=En?e47Tc~yO$OjR5 zhZB*Hb?Y@o&S!VYPamso<5HmnP%kaV)X~fOs#(>MVx(6nKM^d$oJ1TLLzviIPs^C2 z{nJb30^ES)O_XJt-?=Xkg<)W+Z|j3x_O)NKj2A{N9;1=l z7@WhZNb6p~@sU*gMX@Q(7n9uziji%hA&^-$F6!NHE9F9|rHr8ZbMJoA~lii*b<*WGFXDHKo_IuKY9?bn3K9~Sj zW?;fgCDdiS-$BI$bq0x04>1$jHz;Y>;14Pf52SJdarGRQjssXaI-y4m%5GOZe{u=h z`H*@DIxq}(IIv`R)bc^FtRSc3?tm-~$M$3#Sm6!i5=+}XeOFmkH*R){>i^m7{(S`D!x=j2^z3hF8y}qIk z{=x8f?spte5932n#(-^K#oq70-HzY=nI=CbAIIeSVfAwk!2M+n!aI@9h-Iv!hE2Ka zxR)9on$QHHQfBCSOCe8uf$8puP7`p;!l%{kC-pj+3 zZCF_YtMX191H4I3&YAT6=hKslL6Fr-sh!&i&lb4vk8?2FLcZxZccZC^=VZN0Xu#su zV&n_luYL-oK%M>;opwyc;e?ne&ofZJIAffjvI;3Y0j!sP{XB)5KM{ckju|9i#6Q5- zR(k12$U3Zjgm{*JD)ed+F+ly|T}{S937ZkU$ZhCI`YR|IeZ4WzON{MIKJ8h|cYYb+ zUOlar51Q#W*JoQVOeRYxfBa{rN4j4rC7HX`jbj7#ZoW7FjWb0!|(4{SxL}9d@M9WyAD_a zc#bx6Fd`oRR_s`Db$cNlTu(2`f~{T&9f7A}mp+W*wKY~5ejexo_W@h;dp!A=hsML9 zU$bYQhRYd-GOr`-4uS2(H9T{_QzJZC!3-<)a`vKDi=XTM;9uq@K(N}bxd$JgW`54DHiK~wcmUh1K|)a&Nfs{~&$q}4qokO%)&msG2GIF7DY zg$Ny=07S41C$LYz;kr$JCSBy>3y%Zd5V1xaATuf<8${j*LF7rKY26}yDbx2OE#AD^ z>MW*9kjBXd^9=;{432bdC8hyE!w4FuK)CusP#!^s0^#BUK{pV@A3#Ax9HJ03g`l$) z2-`=3W)Y+-ko@>!ZS`D&j&hx>tvpqgT1b$sK)7bcii-*QK!JP;bRR+03MAiG)K))2 z&yWJY1VN80P?7>IBWQ^NwNs!M2%4in?G@-1f^JqIxfWPkT}cohumPzZRH-!t zU9LdytWeGIS{m&ppL2(e-{~`?F5O}x3;pQ0)+`W#QjNaC4U_mr4A6p zuf;{rSYzQon%)u5zU_k&+^^qrKTFAN%$0bJ6HeMz@@jXeS4YE~sm#LAtuWT`pd%h= zudt1Z4~~9i{6U=~LI2P!MyCJtChJT6`oO+r3I4XS@+XKzkbpUVTA={q3I!6!XQ7vL zTHF=3LoPPQ&QGFNhfl{ZrKxkJ+Ny;?{zf0q-O9J#5zl8|G9vT8z$4D{c5?5R5ncc# zj^6~>Y=ow`{hEh$0FOe4Ms`Yadt?s546yk)HCNo&UR2{|e)#nVz##`g1RF*)hgW*= zcx6o#=M@4C)+lb6Yh&1DVUDXG7*QQoOk4Kb%Osi%Znf1>jOA$ zfUiv8i*ZSXmbVbV&H%z9Vr|SZZWqtDn=O#YzqA2!N5Xtte@ZhIh>) zsZKfElT`~6UQObUcAaMoNDII;1Oalm7)dPNqo_C!85fZPQbH=u%35+>)@5mdOR|c znjJH-;b#lyq2CcWE0omA7|Q^kuwjA4HeY_MaCkU;AB@{bE%<%F2<2fKd^)cmFsN7R z*NW+kCzET3B+2{s_$4AD!+9IJ++f+x-&;LA{5!z};cURvwOLFnpTd9>)2iX&sZwb( zwWqyx1=ioL9%@ee9Tlg_w5wH|y3$^u;#89MA5}b&@uezGwP^oJ#i zO7@>C;U)fIk=t_dA;8t4Uwl}dgRcQ1xIA%YuJ=RPxqq!d*qPx+x5gy8-~$RQyAk;% ztuaY%)?SqbTT*Js?`fH1I=b26>YU)7grR9$(7IQeJGV(m(Ah25gv+^MSN4@#`@QNM zY)gaH_*_8!z^NAA4?CCZ6@74}(U3$n*tVnbCv49cyiDa{DE^R$3EH#kW39x774Ly4a8^9*)cl5-+ z-EuBY{AvxYidaii^C`rsQcjcO!a`97yx#o33Q;v0h zPOuv7U4XVQX~0cTg%MhhZq)CDIk#W{Y%>4(*x-VXkvN{2;F1J>gt{Z{U%{kw-f?t( zh#KbGUNID$#wh~JAO$M!jL04aEkd6%!^L^Q6~KjdKJTQ^D%?r^?`wE!gAxQ zj^?za>HwyAW2lAqFPVeMJFh1*`O_Y(M%+?0O-wkqLt*dTd#l5bR=`Hxc*xLuRTk>K zwP(KedWyVI3^JR+D)<`Vh_w6R_igH7ViYAKauMu{;v}QQ{t6Id(=INjJrs5>^A`BL$5+uck6`7iV z)NK3;P;YGwt`X?LKb?b*@c9Qn29%tJOoS;C4$|AF_XOaOp1%?QJ~}i=&$kQpk^FZM ziGux+yHVJ;7nC4>%~$$@)IWX4c%E;=S6&a&8w>T~jr|Js?{^^KTaL^^{j0Z7e=S@4 z2P(2P3EA3f0H9#{L#p6j#QQ&{;$JsQ1-h|5fFC^S{dT~2NH184f7SNyG5HSZN$VWI z8ao?oadTN#FDn7N?X3>){`n1f7kti1y)LPpFeb^PN=fxbai&&Es?HgKE}*tpIJpQ1 z=lY_X&ITtZI-L9zMcFqA*|$#sXtobAocz5iBb+RP{{}?+79DDalarAd%gNiF)+A(W zvj89`b5%j%fsYQ<= z1>UbArl>FpLXfxaP_~{2)OqjV-`n`N9{;K^i`x4R)sc0*tI*9V{DjU{ zRK`!}^n;Wc`jEAevsq?!<1$B(L>cnW&DNdQNxKmna85Y-h%A=vz!Dgl?-EIu%7oZ`mquXCx5YD zSV)$=$V~yl=eYS`AxM7SDoir+_aIw%4jCS@Rc13y^`*A2Ns$JW}ul{^VmC{*VZ=EP0ZjnGX8N zi<1i^(H>>7s8rtHtW;9aqf!ZJ%3CQ^fuQ8veKIuvHPHm8SD{DE$|u=*Gp2?}-mNl6 z3f4rfBsdvAoGRchh+sI@DCS@8mLBYuPG;#VTrl%l8YAiZ9rPdNYlr$hNrHYwmAJ@} zSE`vLXqNmpQL11&@T6PFN7$bsGRZa+Ncu<$VXj8ybu&t3-p10D*XdF`Kdg$2@?#Z< z5vpS}sr)|TSW#ZJt5oR}6(+4^iT;^;*&-&cE3cJE)#Bf3{Hvh=uR^3sCiZ$Xu5ry~ zml(2_(6o6}k*@$dq_7>96p`6JtSdF1acVr&q{eEbQKKs>{^xR=x7+6Pw;)OT2qL8~ zDsdLxcu2CoXtc8oX_7kTm^ZB?#UF`bz1ET{fI-02B&3w-v))V7=S6r;!u*5YC-+7s z!W0QH1nHbFU@kRGi>A*(5p^zNdA@D1)3D^GJ_p5zu(9d$618EB=~Ib{Y)wM8_67i4 zuz#Zp%7VRA#amvm17|`q#pprzVAebj2H6RU6K@Bgb7PF4Ux1ZvY5Q(?P05ie$cP>s z>ZGbA#pj-xS0kyFxM#vtt)y^SK=QhST4nlJxJ{rhx&^+d@XZbOxOJWMZi<@8ng;D(XNrK|M~*P*BM!Ud`1$nuMIWFl{G9olT_M zh$su-9T)UAL1F>?)&>2MAh5MS?&f@aKw^M=1)itR$Jcfx_Wu z-WTM{iTr$z_0Y@hU|NezeU^p5)a5Enc0x_U7MOYjgn=zwfbz91Of=8bnINpFQv*|> z>Q^=8Y%HvSy#?ANmrK(SA$#+*`!GhrxTT0F_CD@{{zQ~IuJbRPC`J$hJgghm)!b+^U z6x<|P(khkoHpxIzYH?-%09k z&K@xr;;k>5i6a5#9ml}W&SGo|?g;3?T)6nd{DWzp{3bG~8YP6Br>+tCZCGS>puYuQ zL~cbP->+4kEG`Q_6Q!1#3(a$aN*n`VtV*2Zv?3u}xd{NO#LHDdP6+4uMEl}-og8~mgZ{PjMmR5YfWWiu3#ZrOm6%XTthNXVRyo&bRvtOuo>Aop~cQ=l6 zSYVo@Om0;tINNw#@GW-+lkMOc2FFI&C8;>aJ<^}U9(=}G^(rLgV#$D*6?bGup2Fr& zUvxLR6`qIA+r7p5Xz$xE0!s^^z_)d$8l)8v58E|QW&nj=F~uPyOHzBey>V9#7>9*w z4NGSTxLPx?DqJk-e5?kIHJqc=k}p^Jsb@$C$=36~7oDx=eSwgMUg{obYGJy;njV9)t&nEi0mBuxx^o5XE;OopvX)M~^Et=J&=uxL=A_`EgqU*93q~V?4 z9#u0-Q37FqhR76yn;rArApkNeX&0G6pw>^7qO(CzKtl6VE>I=8Ax`hiI2J(3rQr;( zLVg??C`v?P8~(x7fRREGcq#IH-$N;=7V>r=<8%CL4>(v}fNkOgkdrqs3BXNMa3eY* zDSBz8497sscD;gMR+9-IL#&WbJy3~%Zd&{2E@!CLIgykHwu5mOvd%K8QxL7=q_xFv zonN|jMx&0)Jk-p*nyWVW#;_6JvIWqDZ$}~ODAky6M+BHJeA~r%6TUg@a#^)O;lN-B zt9GI|*rFFuJRM#kjnc4)3KWB~!60@s8{Opir5cFn6^}R*d<6MddY#e^S`SH0L7x40 z$II|7dyo3xLad~|hxJQ?PW?8*|CKm6rsRH%!g|GL$cxNn`aNlDxXkGGzH?m^sf-{y znZ--rbt-=$h|gf<0nGiSq;s9hAA$MO{$@syy+LprPUYWAY5^*v=h%U^Pu{#u*qQXP za_{6pj*<={lTInjfjr?8m?lmr?gNv;fO5;oVzM3h1bEW>LCvvYUpyknEdckU&Z|8D zc2#t%=ZZd07EFi^h&8K6s0_^;&3+Q zYfmVg?{jELB^K-n$ABRX2cuT|3=i%OP46M zx|yx_zuX}sy}!Z+<5p||C<~gsBj2Hz*)(FrcD9+ULhHWyXa*ep292))u;2g^Rg7@U zn>lu*#X&L)3jbmBLr%RZK~$<{93l*G)X_3LY{vF#aAOCzN6mS zWQamhAt@P$;TJv+M59o_w+O@XluAY=-_P9*(9snDRilMe#`l$k5BULfqx5R%uRzh4zV6FuZtr5fv@nX07dp>d3Z$Bp#2 zW-4-(`i9i(VG+^a0~A7~lrU_&!N3OPjZzqFh&YD#Jw%eT6rva%{`#k+yI_r8imjU` zlF1>u(}h(Gh61p0)k7xzCd#uEUCp9czItmz+@hs_74x*c$ORaZO!*M0=&(hqiEO?H z$Vj#A`Nc!EVW#8iv^qosk#p6+e&W*xM zhoJXBA_LBO>_pQ4j9L-u3GGy;9SPY^oI==iAc8;GPC@cJ(3aB92Tmk?C~BdV%)XrV;1$D0 z1JP3eO$K5Y=e?fPcpyFzpfU{BGJe89Oed}u2jUrpv|%6|o^xV08I9;baAJ{3zfaVIJRrYWP$FCgfQU|J`_MMGTulSuq2l+8) z3>$k4F}=cYX&C3!zlQZOBO_pf^yd&FdTBq0hF>7ND24S$uzu-SxBZPEi=BxifUjJ8 zliR&dOe48Rl(m=IDyb5=wC}mo-w56oVA|$y#XlN6)hHo#`*&CBD4ik3lBF7UQhPB) zP@~12)YmFM^(_gT-$^~8^0XHuY_gMbbOpCl?S1Ew5$F!(h9W~b=Q5$$?}@CzH{9N* zaW*QMlcl+R$|mHB;E{h3gN3$#pfH6IqPM~n!L&36)8E)kBTOYOrWb?)rT&30b2?~8 z*q@S=9FJuoAdgl0SgqMtW0sJCXD()RG?jkq`*Vl`8Ddu#uo#CV(b_@(mOVN;MXg z0|Hdq{$s`)3yP8hM_RBLA7s9)w{IwHO3kAf7Tg$dK`AN#9`WbPu|Dg`g6n(NnJrrw za+JLrN!JOZJW#+&nY1*@MIb_WbfXhV?|@puqg@*?%KX^^Fv>TgxqdF(JjyB~rF$6jhOLo(iz z?aKlXZo$1!sCy{;eo851+zC?|0ugpAauop6mR2rRZ2=poLkLC}Fg(hhCP?{wISK6p za*F$4{`o$C2eEd{e+eUPXc=KZtb>VdKu?5w@C7V^@M_-U|0_Htk(jtu5ugH9cy#RLUrOJ2O-Zu}9dUPN1id|LkV_FxWH|0Tq zotm<_<3akXSz=l^+seWE@Ld2tC--F7`Ab#q4qkA&}6`h@> zVjNl}qx3~99aBpfHC>2NvO%hOLBnN~2nO11o>ALdWE8jMPj*AE5K<~mU=*c67$svv z?I%u5VU$RNVpQTfVN^+TjM@&meuz;|h!EuSijekO#?g+;C^>k`Bcs~;x;d-?`*^is z8&o75D-*D$Hr)RD8nifa#xl=Alb{T3y4cGMWS%QJ4%tx$TFmXQEbxZhyWf#HN*B%B z?FcJ53N&%^xfyK#=rE`3lQ$rOd|}OVvmEG)3kB+&4WkmSW#zwU5QqfvmE<`Ih*$oT zQ=9~B-u(OLG65<362l>lz1q!z(6J#GoW5s1eXgs~wd9I7IUq@7XfyZAz+K!zJJ|&@ zT6FK@ABBPrwq`Dw?dBlWg7`d;m?u}NxV5HOF?ZDQ z-8j&QpAAAsI0q)LrLw?J9FcBU0rtOM7D3oE2my~OKuv6PaNXBQF#@%&FdgjEYPLQ&yX6a=(EQEnH~F~~bO(rejJ zdSb1VPJK_+@;%Kp&ry_b{lNUEfWa1|cU9)RGu3Zv-~y-dW59@M+!?fT8r%KkVoQ5p zZ?x>rc70J2S;%p^LI`TCEHkea>YQorD9d!&vyxdoRql4y_npoTAdKv zNjG6ujR1vNbZVi=a-&&)X^{lF;%|YlgYt;`ji+jlYcQ~U4P#~~< zP8rAuxF=G!TBJ%%za41FnSQ6COylX-#bJ?Ndf1tQTTooDC~?lk6OgZ0yy18OK8J5p zukeb9_SP1&WEpo#GVLG%MT&bcH$*Qc9YzG&D*u46vw*qq1-R>!98bu2Fgtaq%Fh1) z@{ND_$MKH{HjtTMp;EQUy`_!({!ZwoHI?SBAF~;J5QcLrO6{aJCiLmky{D}t)4@To z$=RvyU4_1s-r}4coxy&V{zFa0WDoiYR;RpzGLXLAs2n*HfaFgBV8+8L<0Unepr8O! zGC?+@neoU&hwwp(Zx!>=|E=imNNVbWPthwBR|^R+J(noVOlr(Pa!0GKCLYB}Qw*5K zoJ5%?yRkMpOAadTIh?Cyi`;O%+R-U;zgnd8U*z(K3^AwJQ2J|V2&62LHek+#$tdwz zK$!_^VcY=kxBT-_l+&LwCTbsE9mVsnfmeL1vUc!9hYt5V+^21y*_N$v)GuNrTOV0R z;m0WFm4G0TXu-Huh6yzuP^>Ay4xxP!l% zM4X6uEzO5&S>rMK3-c%_GNkdeT0SM!tyF5e8^00KxK36_mNdLlhf_F5Dvjd=!T$wm zTtz}HNTa}!MnP+|Qvzyg=My?~@rbnZiF~wdPCFUx@VRbn?yr_PeHk5@mWgp1jvR$K zz&bVi2w~>^V!@OHW@cBwWD@3VmA*(i6)>0&VST3Pf z=_^(tV&>JFzZwX!J}CT(z47Nzp>Z)s%)2I@MxvGV82>_Us&`tLWx-gB>4L7cZ;(*I z!cK7Gt>8q;MCSbHjZz5aQq|{zw7?W_=9KRCKzFt^&Vp0EYM$aW{Pg zOe7W*;_f@8{3u%aY7GP%J@f5hlw^4+8 zu;#hL0)QhD010lo-o&LUs=H2QHLMiRb|mso;kUdcI-VZF9dB@vbh$!Qm@=3bD6oF5 zdq@#7p<68YoN8Imt1m@5snQWgI$x5&Uf_g?0K@a|kP|OZ&h<^o|74Ne$#W`I9OBie zTVM@~(uP92S(a~yAb+}WF5No0H}j4fx(ilGo7Yb?w5QwT-Q1-TN_FxKQZ$m(FY+07 z__#`&yIsbqr~A){w4lW2LW!aI?@Ag#MeU68LF#4d5q_6hTB{;RwH3sGT-G0RRD=MJ z2r(kmvzF&7qm9LwoFV2m?-u-@LlwpEJ!+;DK9{QQtt?OB6PyI-DbIa$@?5-J4P(+9 zxIn1{lBgNZy=FNdf@K_n9#~8(JAzn;AxStA#WNa6%c7S((Y?^oxZ#3kj*PLh(tVj+ zu%C)MCl|pjuW&!p6|1f5XTAcqQWu5K<*0kVu71_yYIZ+IEVH_2dwuk;&@v{7oY6gb zibBPo=sAUR4-iSzxiFCz$Un#th9{($LJ@UEQ%M(96W|+LGR#z1!=_e!>SWlzVK}vU zDb=K8Vo~To^NEG*eOZ|LrPyaj>$rB{a!RS+*PPq` z2h~qWjv94|ay9ZSOF*tid;SeZVedRAVG2*bj8~Ggoy+b0pZnwC=r%B*hO!)m?yi86 zd}W=o%YrIXP!)KtwNPz_0hm5P8keK0(SAY>3Y}x&5LU(`^iZ4)4-+e-Ve$_j<=)B% zL&Y81Gh~4F(Qoh()AycheySb;^2{Q=6NFw@pf>Po3FP|=-JQXY*z$(}FtZ~h;4T;2 zR9IbeGY|B+AO5ceaT?Tg+Mj9nPsNosuNu7vK++QcU@7ahdH5O(@3_>$f2C)d?`y!C z$<}%N1DJxE?`~<{(|rM&Yj@raBTjx?AkJav&pClZeAcEI;vb>XDdkV{I|92eBaj2{ znRFjIFe3@nQo2aZe)n|{kolRSl~jRhR3;tx5Ap4H7obv`cNv_Nx!LkteTs$TR;q_=$*Qi>krk$W9MKgTk%2ac2_~qJyg~LhhvkDU}G)dU|w7VA_cYwrFDB z;gn%7xC&SK6sd_W^ zXdqsaU?3n#56HGt*SmoTrH&|V*%rD>S)=6pBbv+sHp+Nmy8Jpq97B7Nv>Q?(I{pF( z_I~tM+^1}mdwJ}e;Tw%29Vn!#w%U@ORRBpRutQMt-tdmvya`x4Vg|y0;Ft)|2Ca0~ z)%ZmjoUuGalDP6`ZEH0E`jjYujQ#?UxQ`9lSw7dI0{o;xf4ZV?762h6FWkk_ zloMHsD3gb$RMMDv=A<4hMmX>h|9n7kz72ZW)r-kU!6z)Gjxw`^??%Q6s=ZJW zP(3-6?^~*EkB54N08|`?C+2v(Z0WapHGmdtJmftC6qw&u@Tl=vm`c=*#zX0QS{bD6SF-YfN&>aJn-9xzvgu+osse=@>?L1 zG)X1YqRi)fRoAsZ>cWZAu=$)!2#CU+O%M=^HlHJ{(gx-;nZ=FGXV;g6KYNNtn9rwF zjXlMkIq!Z6%O7+pWj%jE-u+jB44cnmA%vMnYCcmg1UAm?i6Ub@3?K{Ct`k9yLOWl` z%dA$1{OwtNxdO;IMF7;w7W_rd>fQu_=sax*1Kz&{_VBF!h53dkE#mSu#Z6#nksJ5&ii);E6T?wa z8k%c&UI*I%QMYGXS+a$45j(NkOjT z;2d7$GR}T@QA=c0)b+2bE@PpptAluV1EyLg^0lm_TKZHiqLjj&EJzy00%(GSL7dTv z+)+8iA`E7s`zmQ5yAe3rf$0sw7xpopmsZ%)glcXEu$b?U$j6neqFYCy=YXWz3X+T_i_t8=ZP6Bbf2MqyPl%V8lwXmh}G~6D)3R`)5$|R@D9^} z8Q$R}{6H({bQ%Ue67YaC34lNf9)!V@SQhVjOCZ%>Nt1PM6$7EDmKxV3cDKei)AmAq@&WSjClNl z7n%sSORh(UaE-$evXe*Y%F~ZYFUZJ^PC5y^P?gUIa&6uXk+Bbik&?jm6jkR;Tu@IW zp#iBT{)R=-*3F>p-hs6Nelt1}L@Px6qt0uvo%>T(;=;2B7pO(Z3uOf6wY(4OqB5Kk z_IxCeFtpZ#3R4#eB+LtU#E2~8dzsLkl3sk4q}7=W){2T&)9CIX?ymm@9N2*dAe{og znE_N}^+vR#e!oSPhCLe2^#T{m1)lSSdV#y0{K}hwc&38~H^xBY3R5iq^dqj5t`qzP z+_~#hDA$rH{28<)m4)3??1F>FN5BmhKtNKv4DT5uA^s8hBmMzL(C|u0?Irca4>TNd zZWRAW+=D(y90UyXRn4JD%{HgC+gwMmrxWL zL3@BWFi!l#9cC*YMRE4JXVm!E0coc`18FA#Bk?EYok0*yPF&DVxl=5F=#WPnjps=V z`V?@yp}#tRA@$EOKFn}q7~q~@L!jM-o}XZ#@td?o{bqbFzfJ^d`!I|EHZ{}%ZFEAk zA9*j82TO^Q{A84s==!dz%lHAmAP{9G+)G(Wb^cV$ieXz{k_HWJYsEjM zRV>^3+tZ|P+17m3Iw@6to3j$1%d9VSzomY=u2L2u%C@F-1zFDep&~RVDoT12nKX=7 zS5q=-B9|!L%2=!b`fMNodJ7%4lKvFR!>q+c(lXUvHXc}zGM@!dt5~`vQPJH5z(kR4 zZ+XUyp<4DN3IUoF)~)R{T$XNqOx=3_DHO;Ymvyy!r3H|5vM^DQv_qCV&@Jc^R&=6E zScJ%yZy{8)(DRHK!@`sY)o;e%{SkR34Rj6m%YkSvCbypV2t}&{93WjqpC>7 zI(OqnD_dYa=l?Qfk6gZr7d(&fZeDwJV8oLoq1>F9Y}@p=9Wgb zg3&@uTLDd=W5Dd=B9#O8>XQ)zCv`LiAA(j&Dyy_ao{)0ZJhuDWWe*Yu2#93VBsj@9 zR=j4RCr6{llGj57VVnHk4Usj=ngp# z)NjgT_@y{MQ6seOQIR-8PA zcfP&WL8vYj@0o`PQUe3EaSIAwbq~YKK1C20K-nrQ+LU%?`J&K42K+w{1RnKV+R zF*9c37b1dNL2ePVXFb-5JSgh9SOH{@Apqt9_c(DnfXhr;!ZTS-3pkMVa9(m0t&T-q zk7E&xB4>>XtiI*Aa=%mphC=s^{}7~VGhX5!W>3)DPAQ*1hAQyE7AfzmwO`T`{KaaF z&vA~yWE-xwCQ%|}84dS&6E+6Fo@MGch4u(YqXzOeK`wFrI}vkYrj^dgM2Jo9vDGWu3i!6^)mD#tj5~7kP-FVFEI}ufXR#Q~tSua^8{86IHWKoo; zzGKI^XKRV7A6Vv?uvm_-aQj@Iv=O88!r$3TOI+I}y@)fV_%+`_8b!P77tshjR|+&- zpn5(>gBb&H<^Bc3gm>Cl#&{?1?i`9c3UNN}*zb2RP}DL=Wnse z5dy)@_-~;3=2AQb-_t1RWblpspyXLAfFtDvph<7a4c|bEJs7a6`DUxvdU==w)qFQ# zyTeSx-UfMmGy*stz|$^evzs9p)^2|kQ}r_QTC4p((0FJ)$tK-;Y2CgIBS4glQ4+x4nrUu~z6iseX_2UV1k|C?>NxRs+-Y+s$o`H1 z_I#`4WW2-%1!lfT1_dW-b4Rk^&#J(^5DGN2vxT{*`(E5ygkVpqft=aS!jyp+TX>eX zlH*M3j~{fk>ugX2Ylvn?f2p=q_j?vAiwi3&X)4=!KgWDN${Lv;+1mrMWmyDhWPW73 zo^xtp4(p@L&l9OEikedm&Ckwf`c?ZB_yd5(4W5$}Aub+-a{7|%ap0gg!F zR#}HfY>h+S&r!G(ymesII+}n1+71S|W|K1*@-AHto4ig0fmic~F!DKKScu7BoJZw;UY0!~w2|j~uy&U? zfO}Y2$S~5w1)^f-P{K+U$Sm_b3G%3+?0|hEo)43|N z_CC!e7R)rjaGswBOB6~3x1Iv4q%%r@o%_VL|5xwaz7Q4mCNNP0Cv!Jjktylvc@T`u z%-~fSuBKfld%JxVs+PE;@qe+U;+dAtL;!GRnV6S9*7xz2&?6%+Cp2eR6MY#$S{g9EwLf&2<#XXC!Nb08Nx zkgvvsY~w&Kav=RNArE0Z)M!5LK#q+GxzB-I;6V0?3Ax9CtaKocjtTjb13BM;{05PG zGi?m*6RAcHX>w>pqh9Z06e8&l^i>y?y>9mu{hA-{GYiyTNTCgkT1 zWPtYq4}`3@u!cQGJ8a3FOD@}8KG>mA4(2XbOe$hREGEC(_>CgfTNGSh)P zE+*tE2QuA(G;!6q?<*Y0R0pyuCggGlGTDKAASUDz2QtxuEWI#KdoA~nH}38Jfy?&g z`OJ>GuP#oT`z`9VvdzTet81&x{fbw#h$HYRn;D6Df&9eKxW-K10s?vd4H2J&4E-be zJ{GxYHWG_K@tKHyD||ia_cvE1Ni1h_`967HFfBL@*CUWeCb$XLG5;+RyG4=I8cu? z1GU+KDs2X8qXRXh8K?~oRJUfJ);UmZn}Mo!p!f~>rX;b{fqJbOsKpM{J{CpmyOM>P<-^-+_9w87SR>da4e>{2lw0AW zJYjl~AAB%c4G_mg1jKQX0phsG0C8M6Kr$|W7Je`oetefL_P987Kh^zNjr3yqi6FZi zxY{6I^AACE)J8rGSDj#e)xO4fogm*%s3gJZy+Zve@m*3OehL~OZi{TdFD3IkiukZx zjp1WMd}k7$|HCIC32R%k>shl^;c-vDI5f(_>7IrU!2uum@KvKn!_aIHJ_t%OHzeZY zi3l0-p~gF)V72Kr#_2?}o&OdDjeJ=dBo1Pb%X3=Ul z?L0*b-;8r;$;ZV(2Os+G4m#;1$4~tR@i{y7W#`Nq;{_tb2TGeH8<<=N=yct;lafG- zzp}-8)!+8hhnja_{3y@%(=Jv#;A43X5AvaM@Q|)}$PDvGxfVPvO#nCMWzeb0N`A6eeMj7UACtdw=~1jZJEBes_&&tS zrFiGM%RDZkP6`%E-O;Su%S#KV6!5rv{bi_5$sqD~4vle&{wcYZ{j6!4`D zl}qKr!Y4)4Nx>6Rm%?`SytMi*1?5sFA0GZTqK*ZjNlWD;#BWEGvmi8lX)1oqS0l<< z5V~mTX)J#vqMQYxw56xB+!s;Kf>1~5wDuZ516hqPg4RyE+Dj|tGcc2e;p^@DWSXgI z9yPsI@e7tP2;J33tgSCt8uCSK4PUc`wc!_Iha`CMHBGTi_y}i>5lq6odX$8`O;1a2 zU?6PvpmhB1=9I)WreRu>A}Ay82g}D4$8s3KENkBbG3!5nnI3`*&7?7 zH%=4SMVmul#pghQ*z5n)=m#ZnfO7Gf*jTI*TRODD0rb_?<9o^ubY3l|2QtCnOSK=| z>kCD32ZmJSq6g1SV`qSBG*Ed1ozon2c@0DqtI-H(AClJbk*&hq2Ch%Y!zb=@z1_ab z>$`ns-=VozTpAqS1zrceeuv|t`*&L8>ww82jgO@!6oz|(p<0vt6h2}z^32?5#!qA*_?Jon&kZ0K3s{}hFt&b7SyuL~~?##=xKog$Oy0G3BG!h@rjEU%u`D=)4;J`3!tZVz^12m`cFH%iN=d*v7jxLJkL_ep8RUHBQLN26STfGcx#tLV{**qwQF*yhxM}} zJ8ZG{Ze)u{<#q5|fLUE5IBO1YUXy?@F=4~;H9k-d)Lu;D7n*EggIhd2fVF)LSvG*` z7ir&OavEU_{~k#@+8Fk#uE~$&*q-$1kzCMxb%e1iunkuMkkDkI=@#7w^Api$8$)@w zh<@ba`^+^3&BE{O5dklji`{~`DZsmI!iMG2uwl7^Rt3`|$gtd&kLor}^$!^l2r-o! z*p-5sD~->Op+$L7S(N>lIQh<0CfW#l)xfF@JUbG%WmO(IEUS_S+JA&qK{B~%!}3_q zNIqd$dNg5J3Tnipyy>w_%Fj)jl{G>HntPjJprA!*$1M)XKj^sd*cKwI%KJm0RNbYb(~}`pnE+4C%~-!Qb5W#(|7aX!XBZdGnDK0#lgEtyTO^_AboYW{Yk=1Erb8sAFp z^ThT2t#nQ(9)E|?2X}j4_ixm@ZP5F!oSv%(@fmx*7S3h70iMgNOMB`)M&rx&K_5q2 z_q!k59!Gg?+7JD7K_JF;2Ov2B_BYp|*;;&j-nAV4gZzOCkbPK>p)c(?`_{C?4y9X6 zAEuyOYh|-=37C6;O+H*z+dqwqBLqPG(^83E_XD9do@j17L`ep3P0KQFN85|068SY*G;~!DX{=q?U<~T5= z2b9)btM^uFSmHJU?8%(f)Xq^?=Z+TLuDXyDXB=vlyMS~>HHrIcjVhMZW0AXJ^A4zb z4xvs$87$T5`hvByS?XE=W9zEorSTpl04bJqTnql%uXP{uDX7Stz>I)_@b3>+)gzdi zvrWcfe7*6*KD6+!VWZRZ@n1mQlSxlk5Neu{C8M(d8bmhgYGFD@TY(Pt;k&$y8SIqI z^zuC=Co7-#lOFKwsg6_A%jj%D{2bZ#JyaVPG|~1Ir|m{|3)p|I$-Po0xA@e9dLVl; z5nRveK=w7b)&qz!FC3IO?I@!+81~nM&e4PUaZF8VOOiuf0d`?DSVskRbOc!NlD*Kh z86W!grm2jYkch@s(M9Ulw?Ct_7h12air`H%9%HKJ<>8R)Z^T%YjQ_e!!u_`BD#_1KNw|x6HwNx8km>C z;2Qs72LjnI;@TOs_Qvf%9l~qQ>>+c7{sf@;(LjX+iWo3gFn_OaU)+q3eRZiN=uD5& zY&5zevQbAP4UJ@mBKI9eFC}kKh-$pd`M8uqUtLD&*0u3z890e$WYBG2_5Xrq%}V4U^iNBeorS<91$Q6=?R;Z0{$j$7ugMF=&T;H$m=v-9@UX410*J51EJ*bk_7p*o<{8d7Sx39%9_J3e1 zESnDG-QL&AH2@J)X>S|L4aD+_gJp39mXCfBEJ0!^1Qy@EYf4X0e0+>s-RJo$s^ZLS z+?2mr+67hPOOKm9tF5clqx-s!M&%(hRT`Gq4WCmDb5NIH#^VN7vfHOx`8&8o`x32u zv0Sx9XYUu-uAKq9*W3sxMHBGsA0OvxV^SZ=>q~o}a-vqwY&bX=ua#HGRXp&_Re0V3 z_(8Lh;BS_ukQkXFp)vvRya0fBleuBwyBLyhGkf23cB^ek>DjYq#k)$op#O9 zP@v%cgrX{Qn-sOZUMpwPo|Rg8TU^-#cPj_(w;%0Qi}n+goXUgYKj~)~xEfe}F4X^N^FmY6gBHa&dI81GxxSvN#HP^uJVhuvS5FSWT={i=b&6 ze20#j@h#Rkr>yu7s6pRpTKFFnqeecdKplysv zT$$@325UZ;cYq?aS}QvP7v`1tQ~st_b}nzO#UIhl6%)~*+b3Gt?JT|*f1DCOOJ+xw zT*Z=UktI4y0{8>Wmy~K`)wl?P z(V5@sQU-NV8^HV z+lsjjxrG}#8KMe18MkpWyE11r2_v#rfx7PhS@(Zz+yGf2GQT9y=Ur?piAnSwYIA$m z^2Hnbxt3zyz+PS8DmhjUT&VZGIkhw)aGR^|&FLj4u(Q5ZS$%hxel4v)9x}Cr8V=Na zJ5qK3e*do#UB%L=SGDhudq#(~e#D}T>yshCnd@K6 zCGkbzrfLmm;3Tv#X&iK47I?!vfb6q;`#YEJG|xn_-_Qf+u5pd&=kg+$ymcp>w0|`R zvNP{r$Gw%)HZcoaxxPb(N;`$g66Ol<;vN6vC1Nd2bUfF zmBqNKk_Aj#AimTe|Lfyi^g^gf%UCQc9NEIyW~}@HbM0W8l2hCokryTlM)#1Ny=2-rIDx*8;^s;P{{}=sSQz zG^wJX@yH%_Uc*+l2!oY5keS#2IDbTU{pN?8C;0oFHKDd&&p6cFfL-`$IH}MtL3FCN zUnbO`{=$@Qcf`4FJt}xfoZo#4E@9ntWZjd)x_)Ws65W@bhbO^YC1)=+fd7B+%r5go zO#eX2_S<1J_aCSIjV2-VN!5>3zf-}i$>$CJN2#0DxH9q}A()3$C+6~Hzlmp&TqUP- z;aT-Hm2lg*`ubY;zfsJ|D&3H1sn-2SWLb^O${JZz`uFR;`nWraEa3V$t(+mXFMAS^ z!_53d#D5dSBUprg2+2Y(Bd9wAlJ>6>WaS@d<&-U|>R5HO41#ulwYH?%{3k1doz*Uc zzs{DqZz+XM8j0+5chCUTS3&{HGNs(!pbUu~5Mbj9!JDJqza}qmYg)453qdM@i@s9& zU5`w|O)P1IMz5VM#DF~Do^cywj&r-?k+}J=w4L959SU-^C2PbW$~vAhxkyJWfRn!2 ze0PblFrr7H%N=o*UIG9&0cJ%4WFVcW`nz%)=4h=Rs1nVR&Xw1fc#OOVa2X_LAxYb$ zY|$B%OQ#~5u>Em&^wP_}(8@o+7?l4|qUF9${qr4ctCcg;R+ULD-#QkiNh-|6C~PbT zZ*UR$u*DeU87RP#Spwfv(kX0E zXr!j2!C_jHUB)qJq^!vAxnw$tqMESVU$eQdjE+beGyZrN*hSp@4@dldM2u~yA zd_uknNFp2(Mo4S2%Qyu33fVINiL@r*N1=i>*=2k}xWzzj&8ToIKFT7Um$XL=(QuBIl2y}kt7 ze)VxB9Ye`gn@RuB)f|OvzMI6T1c#x^s}hExd@IUBNMkpgYZLa)CKG$=OFC4!t_0v4 zL=erm9{3*_H*$b)RD?(7ROl1QLzk*_qPUqT;3LQUfIQ?X^GB$5)rDkY94gH3aI4qy zoL7vgue~PhEJ`Suq09XER1f@H^b%68#>sRU1Gv?U+x z{XC>q>FoL)qoF3mH&NFveiLx&_9jfkj6Iwlq#6N~;l z|HtH7yZdF10A|_IGRrjcUJj6J1c*Iw6`9XIfVYJhdx282WP_3D$_N$Y&hMXsaIYrL zSJ$DmGoU^p)HgzSqxmFUcV6EwwX#xNpmG^1Bho{6eb*p81Z^*U(Y#s#R}j-f#H6<2 z&EY7oN+(Bc!I8;BV-57z8+eT}&|aIznT~OvhI2ES<8dyTU!rhkCb0MjMi@&W@B@-7^hIISbAzxo!AevQgz<>3JwWKfYFEqyJ||0Sz; zqAw=m7}uf%tqdz(48&gJO%&!)%twV}ZukfVKzf1r(qHc5xj_z5dPS zLMhp6tOIr4`$-MG>YeA`1m7A>csdC;lC)O-Hax~){{hmU4LqUas&p#D9z3dUQ4XDp zA+fIWwEn9@X;8ZUi=ao8mkorBcJ|pUygAliTMu2-Ep>#3?h8b zp|}!H=y>jZ7`?Y)o{o~s9b0jkUp0nt!6a}J>W}FwixV8(wcZP7Jz7yj5n&ApfMacx)ZQ&3~u|9wE<=0~q|;_zT8OTXAcen>S;u zn|8bzYTdNwO@G{k7#l`L47%TpOm~VGmY~}BcoW3Ib#>%cS`HEgkWn(cjx3wgC+OPk zYha3_q=faXSY$nHk&{DbP0&68HaskizsASgAsEh%sM04{+7_i%4^w*gUx{13FTP33 zEJM4P(kljR)6%<5hxihs#Yd50>H4+N1D)c{vAj9Oy6ME5W38LxcoT2kbmq<8&8kfj zZ?;=EIO+Yh@s)Lh(;Z(M8*me%w~vsO>*Mzrr+tSxF`idne2c5Xs-=`@zu~wZ3^{!a zGEBq7m?;}5&Mp9K$oBY;^?>*~$B(`Ymc%VP0V8%I>*Hp2sM<{=A6-#jU$uh{_AOk6 zCN(*X5*sFu1mF_@Y)DsWyJ)2zxGYicds)IXWKlL5oggNEtwbArYfC&7_U~L=JoP_Am&dE%Og6aTV&-1hR9!#0VqBMt2O0#g_K~p4l>c!HmcO zX(|kK8>EY-65|v?aES(r`ziVbY*$E%1*{)JirpK?)W6;9-)aZlM}sW7D(mIFDlr!k ztT11d>;I+U1czDbyzDgCUgJuXsCDLEV;T6W zN-lsn#^qBSdyQ?M5#t(BC9E^|8V?dAhaeXNByyd(*XR&|YBJ%92zNZ-m{E!zFx}2p zEv5?!kBFVFVgzynT;~lj(p5K4a?({(aM?Irl^W_&wVUenF!G${6vQ1W33VN=jMWrU zWD=^uESgX|PgKbjb!I`WW8tsE>)6g!mF(Ynpi#A$S7-66J?+%#q&pNNi+RR%MdQV6 zSYJ1@>5rE~NR6C!nt7=S*-F= zZ8wI;xI0A?=j$iPE&iDF%Xw0nW0!~-kd6@&Bieh!B>Pm?u#>Qx+#45o8m&y-t zjjG3C-dgdC6{z@MkPiCKN~391`GuO?sI?H+aWt3>hNytuxoYk=#H$>qV2B>TFPbdK$X})%7@veyuj;eVRhQ^fv6J_ z&ufu*-jlocYrEcf8CAA~j;|64C9+EhPAIK-T-#LCS^^o@r)Wb4`>&G|EzRgtGM~%v z^Pw3pAEan(@eGo9LWepfjKbAJyn38c4dTiip%klGt;%A%v4F-t-S^ZzEcv4Ydq!*xQ3* z@#OVO%g||g{!hi?dHH0*F5?y;fKGL&TEX7mjkes@^#-RVNCr$V|DjY1rR2_!KSgC6 zzbZijSi`li^12Ie+d9{^SiKB7#C9X`riX!s-pEN&aZ14ga0IEU6Xib#~&mF2SIT88l zj#b43z8%2O$Vy&Mi`lTnQEW`B(I`IiUgRh)B{6qwVoi+Ve}O>N7H9zCQlOD<+cO5+gbZcv`*n^1R5YfLpI5!*NXGh*aY?W|H-UfiZekZ(jlVvIL7 z7-M_OUqv3LayDY&w3(eu1*26VvV1(Q%#)j(b`iT830DJrTmM+5)Uo-OMkgPlRoF1TfdJ~u5~y935E?so(bfQ8+iST+26tbQfgZq z&UoVQG(1L&!x{;pGX}T4&c&QULk;w{eVoei2FA$+6E%fBelIr`0V@Ha*t!dBi37ko z`&7Ep27_QZS!>tJ*`>rY_W3xb!$A;gyMa*2y)Y5>KSQGa%PxCPC84&-8O~6;HU@IC+Ik zU?@CoUZT88rgBf4Hl;`$Lfm+*SKzJsPI};d9j~2{=avI)^2QgpsmGFMM4cY!ru)0= zct#ORZGc{nOeU7xfwu@*Q@I$7@*nx0`n0+x+Ms($5faW_WhUX%qMySxf81W^?*dwptmVv(e}Dy#aF4%1#3r zjIi)M%;tMKq63P=*k@gcuMfb)?@Tb-V*L)byOHfnQD1;4B(8)<^OX#Z^AS8s1D?U~ z$EStf2MCUCS@q^Ate?~O6=CLo*kQrVTs+6AmEFxFt#kVF0b;G}w)S$fPr#l5SibQW zAqS6lQa(6%VJtXU2X_`lY!e?iBt_Hp2 z93@~)h+&$r;;o;z zlW`j!SF4lhYFJ27D?i^tHiqDT1~^`C1M;o{Z(u_n&BV$$5k=s0@4WXRp<7D+Jh=Re z((m%~e5>N{zir-}EeEJcE5B_+__lBB<9V#Gjd5l}+JTj32SQ>uI`lMI+&LOF--hQl z3sBCI%`92Ql5yZm$urLIkS#vM?laneJsL*iaTp+D9fclrzrLy zk-~bDFAm|1sdOghcbKL5^*6y9a+=%(1TxJo29g4vK^(4UUm%v~2TteguVpsRgq_i| zSIM>8&Fd2d=5D#(C*^#ttYrZe`-Nb8XM*`4Sx~AMS|p-F+yu=xZXbo^U70MMxCM8xRxn(FjZsz$#7Y;UyLSP( zaRm^Y)AyqxS)fq$zzA zouICu-G5S7(C#j{677y7L#yE3!EW6&t?U5`#8-EH$;J3PzGMjg;?(p*suX9D*QqPm z7x4qWI;gaUUNqnEE!D0hF&-nD0u?hmq8zv{N`oW3HZ7s_1S;}{Y zn<|bgiGH8O;_sbeShD)NDZ8NiL^9-q)v9%BUq!7w@V51_G)Os{63uw3PKbkzazGm= z!>Xu$&S2x9`|U#Z6Z*n4H|*hPpf42TWLX1@$UP7z#(^jIZb37c7}3_C`yRA5x}!yl zMxjqDjY21N6pptQhzQuQvTVr%6&L>P3N z1%RJHEDu69mLJ`SLYW&^qr#S{@c_maEvnd}KU-Xj7R^o4=s6m&ktU#Ri*xi1Jg5V? z_m4{!Ms9#D!AQmIODT50+`Y)vOY6YZ`n^qabt7j&gL%7uq}AD}Xx$=TUC9^yd4J1% zqFoypm`&2UDe7A>#8*nDlQZ3SOJJXFN#W^wgcb6ing$C9htf!TbF zJ!-<#-Vj4xUm#~DW0KPvzJBFnO5^*_QNu_vG$}0F+POe(Y+DPq+Bd^iG1-c=|3hq^ z{)MJ3j^Q})^s{!A&D6B!n4+wHy%J0fBU95LW!kH4EXiR>kyY{;OM0^8aw!ofn~vs4}=E zK3oboxTPLMYj*2R;aG0z6XKTO2h?VRS`3%;!fL=6J=n{jyNDbuWQlotlsmcu^#$fJ zw3{~a1W+z8_rsuLO@4h7-lxe~7|-Yvvh8{e*!xZ&hw+HC}UOd{Yx67=`3{*vxW2_bK=D3`)S@ zy=?UYTD9nYdbQI1+y`U@<~G~)yh44<81LZyL-5noNHgvhjVUe_O6>8xdaT>r|;?(G#Z<_*r| z3_)bdl`R5KdsT~=6w(ZAG)5rQr3OYVP#=?_CUI+lid?pe5ltVf?14HKSn#w5*Zn;i z0?X_jCyf<&cx1VlE&T{NwABfrR2!R74_yEooKsvGPAYMm*Ws}e48A?HIMs%g#)}x7 zLI$7q8Zi|BO6;)5jO8ELNv*PDdA`xRN&oT& zp0a~A<2x?Mdn0^4tV=&$6}E`wUzALP$geMf)?h%eErJ1o@G&5G@jC|Oc>Ep5fvS!R zVd=+5)i5yC)>UF?Nu+?|C9z{gqMm#s*`6w)yYr2wWYCCbZd2@Q<=9lLuc@gq9tDrK zise(sw6d8BS>3gz9<;|o&elL2Kq~tiI}9sa(iMNNFF6%|$Cp40>#iv|4u2<`R>OQSWQjD#pN;Az%1iVJ^ly3cK} z&_4yNLA@W=TQ$D$GBmcN1HCebfHlSM(^rAt(hS8f{3U4E$;m`77U;}NYUQV*!iz5q z_%ElmNsP=-+V5M`=UgDxCXFf3K$}HvO54GZb*|s6`!T6UbK3BB46-?&gGKp z+V=N@1$ou1{TkLlt$wdJP|a@3ZEpVb&<^^C?_B{{V-%HQ#{sMjr_3W$gYprv$@0II*VrBNoHJ@@f>+wg4=3>>4 zbz||`@<1_!$G6m?ACiaGtvs}(rvaa!RU|9;N6`zw!!t04jZRA6lPz(iR#F_nvB{7} zx{}A(OuTb23-U;}q@B|`X`6USE_Nn%d9;dWpMpq&?uYR}yN>s3Lh6e|>YKd5q~CNt zeZiNPfv5<6EDnbaN{`?Z42%T>W7AQdGijXDUmfM}++%aVU;*lis)hMM1ztZ+>oO5v z$T2LYE}g1X^dJ}hWAXwzIvoeC%It=|@@;5=O=z7wdm^Tre=LSxx}RCJPwufpI5G!i znP7IKVpa!u{zee<2FL2&VAnoUJP~xq76Aix-^P-ksjsICfmwQR&{Ta+?R=RcX9`KY zy%ds{7ns%#O5JTq-Rqy24g{9Ohot9GztL&qOhE)%gK}_RkgpIIVN_tEYNyg9n0>J! zh@Pfs6_-6}^^~pKPwF1kP48ZG3pBG9^X!8tf})9Tql>@7$$>4rw0clZ!i&AGlhsB zgBKiUI9q>t#|)N|24=v4B*oeqgs z2UEI%X>dVhPR&=Od7Z8}9I3=CqdSNqkYOzb9LA5=1=a+>m<|FPLkg_nm}(8jEU;>i zEBLSm1?u!E_=Ty)nEdlmtcNj&!A5vb$BM_gu$a3wwQXef`7cFNwM8Rwq-6Fbe~Gr( z=?Qu!4n}`~*0=>$2oa0*WNXkfh7~|%Tw_&eA{&~E1MW$ULiMF8U z61(CAyW%d@;sU$kP!EgvZK|S|UGcrDC@lg0v+TkRR^eYzc&1(WKdbN>9{cvBvzQSY zuFs9Q&WX4del3`Si1KSAuBS#^-x_f}-?_H@8{%~M;ag!z%)g)U2io(wwC5f4><{>R zPN)d8v5i*oKISFV!*)2vOHi;_hFW|c;9rP_cR{V2fN#->VqJ3b-x0jfC)s z&jX#5t67`QnCL{U;w4ObytHtm9vFj9AdJB055^d}AA6xgEGsh-&%lpO^#-fn>`<4-c^QGbO z;&t>eFFMA-8`z7>L}fo_g62f@1GXbL2$pUN%~)0u!GaSr(J}`gh1dug(~JNVtm3u$ z{xQ3~{t<@PKW4MC5<3&nNBHMYU@GiBsdw2!K9hHYS;%KHx;q8(VVvUh5BT5~LH-_D zlY^dbXL9qK#7NgTTgH`nbFyxD2dlqRAzD}=mzX<=!x&D`OJcEyX$k(4wTgb^ueSY{ z*G0w;Lo7>Ml?z!}mUfm%03#AiIT^(mm~=>08C!CT(HO0efXWp3w2?W0f%Al&7efnY z?jJi9aI-2EDjM0@P+_nCR6r>?(s|OiFl>Zm)F?ok;5;!3i_nlho8h0=-vyBXz_@uK zLc$*S5!&R4wSAnPeF)Oyd|xlWe3O}{Pc*pF`h#)M+kF-e%K05ozchylW|-W$U183f(Ewg z5FSyCZL8Fr*^YYXI_afIgoG4h|99j?g;C*fQhDJ*Z90bI#=3v$YQx+k7G>3ep z&WO~m>4;^Y`Q53C2kHt$L^Exz58J3ddjVxF4l8&W9F&X&5fnVroCU_wm*K?oXly*x z9XwP3+09-ec(8oTl|*1|viYBQX@5W4k8ZO4y{i2>iw{IR=BA77HRA@hO^w|as&kEM zJO6s84~e{t=)<)Ggok7ln;TDwDGT)B428#Q;UN$EaV$X1x8ZF2Xp?RCAmCyD|EqXl z+gmQQ+g7q|QIl=gsa{AQ$tUlbh0o$qJ81H`->_<|ZzJiJ@$2 zWIl0ZR0@N$nEinNy+E};nbH?Oo1AzMjj(iZ@z-`RwSzLPNG_}6%P6;;3=p1h9k(Aj|xhCdN} z6syp>cFnawZ&sWXQ+`QW#W2N>9j0DHq{3I?3>Y==kPNzTaVfp=HZ_>k132CWZ=4DV zrL&h<5vD5hIw%XSIfq=Lo(rjbT2ihUQ4ilfs0j5~P{Gd!Q@Rivf-Zp3ZV}9O_xO?r z0F}~**UE|(KR1Nu+;Kckx%G6!^cctEw2BAuP>Y&-)eD`WjGvs#X$S@pfG`+=sR6~T zbyGy-S!B|hi^3r4^HEk@pz4dQ0HlfOI9~?9^EA#NU^@01LixD6>MO zf>-mz6V*7iMR%n)Q7Jb>$+Eu0`H^{VwKDvk_m**TfLZ1i&j+e`dDVSnx#1c?;)UjX zU~Sw5|Dxuobe@&QJMl;u(R zi8|LS984za44f6iM1>20>k1;ZgZv84!67&Flhj}-OPtLhIFYj$5fyF7 zNSYv+n?d=ghnZnYDUQKegkdaV%n4nGzg|*l&9Z@sUUnEBce%CNy%f{WeU(370{xK~Ii^eMv|0&i2>+vpL&Znws|hLMQTj_;V9sX>)!V zBAO5}cN?VQpU3<14xgs7B{#EeZF~B7YsH2D04I_qnvnHP17DvAS(=+W$JA5I^Yauw zXOO}<@7DSHHmZF>c#y5R)}*hWO|>{OU!SN|Jci9H^#4gtWTX;StKY;T1{P}GTgoHz z{@M~at02@GN+ods)R>+Vs$7J!Vk-vVe41*x>sbpFe^X<{0BZ3pVL&Bp=p>*w%Z`gF zTkv`)D7@Nnz+y1~%sVuU1NP&L7T8Kfl@$O;Fp&9{3KuW~nKwre5KKCk=iICaMonPk z&6!1(ggKL|;Wa<&A?c~IJhK*xst49OI zk$k~JtQw1ilfuMx74krWB@G9<4gSQofEZ0B ztQdC}kYZP%Uvb&90y7o&PHa-!zT`2Ks?Cg!ytGWD-O(JzLl%403rJ9+vmzbWfGq|w zAjB4i>g@f02Z-t@v7t5

u;yW-)r{au%8ZgLHcH)5JOwop!`$F_i#RSVhRDi-iT4 z5tvy6LUEyGmd)$AcL;y^Hs;Zf3hy?b7ITOMxu+snS1Sk+ry2+~C>AKhiP>cJ-r}HP z@2z5BMbN9}=$Di!<8xnarWFbP@`$h|P%!Z44TuATXVahgla$Uo+rW=MA1c|Rf#>|} zi19bS(_+p~*uELa$3qomFx5_jvavU?T-Kb&Jg3aey65pLqLu}l>>Q+VzO=~3gi33! zttKz+5*07)r0wqe}i7EVp;NUd7rp=q^z4{ZRSwbnk1AE{>p;_i2q-5pURsRFLL&F4Z$W&3R^( z0~?k|7_5n!-DUUs2PP`pmmsTN?txzl6&?m#Q_b8!E7uDc(7@%8#y~^R%zMjbf_l^% zMxd5hR)^+ME%A1*$#rn|nEISflC)*=7Mwb1?N!Ves^Nx;F||D;9fOhs$CYZWBc3O+ zSaDC2&qYxZ(tX)+pxQ!JW#<8;CnII1HbT^{1A3Nb69oVsNnd4VzkA<8$0_UlFN}S<+qFfzD7&^UI@~ zvI9%*1b?;dm3Bwvh+7u}%~kC?%Iu(jPtI>4-*GOcfy@+@XE@A!$0>@QOgCjuy|>BC z6Dw`eZq-`HtN3Us-!UBM%}4R@3Cx!Kv*HBC2-#Z2!{s7BJI=Y5NQJM4an2<}<1qV^ zI`Zdt<~zj0BGG|E96%YF=zy|dZbTgl;L;yJ&{vp5+0NoA2z>X3hl@u;wa-Khc`#TrqODPbw5L)=HUX`9yKVmK{#s=DXI}vQ%i5xxpRNmK~*4oTB&< z?FB!m01l#D!Zr&MBb$Q)B{FuR%^BW`E(t-y(dPz?DFnz@YMK40WiCnZk5aPYrV8o&ST;Wqzso-1uw^pE)%? zrhJdqDz@Aq{kMI^Swt#wXy_}pT`F=HnNysQGp`%1i7_^`EBS;0d$?|xohqnd43La& zn;YB4m;(%gwM=1XCi}MVe2h)d(+;P#VQ&Mxv+eELZs=1h?d?7sdpcr! ztCcUKP+PK*Ez~1wMIbt?^#^aTdyf;b4BT58{Hxib4z5r`@EvJ6eANPDEq2V>?6>on z%WpkGS;{$t{;>Tx&^w1nnn^AWN><^uo$-nE3F%x|z<&%vyaDE=9PdHEE zKa2BD^|vLTuvzu%2z|l_H%osa(>>xUDx zip$AQ(7onlO0_*~YeM>e=@z(G@_K)Xt`kMvYOmxVi-KL(O3lPn+ZH3~m#SiJqz?U4 za?l^f-{Kq+i4O)6rq7PK5#&!SM%$_6MO2TqsTMdcC0WO(oSYc zM?fSpy^2M)mG7Akk($K^WA+*TX2M@(3~WD`BOT`2G1?Ed-rpP`J-0g>Av#tP6^2H0f{B@0R-C;cu4yO)xa$Z@Tq@W&}O=cH>XdNxZZD&4@ptPp$Mf z9oYXPjqkN`cxyCoA;xc^{xJQGeadSnR5BN@!f63}i}jY%;Jm|nq20_Qlt-k`cy|Vn z{7#>7pThBbe8yD@h3Jy9q18$;58G#~7F*F`oLda7HRt17uQUVv7h%)jGd?L5vB>NY zpE2qLXl)ZdgLCXKea2jczld|Ebw1-u)vqJ;8K)?E5%T>{B}gB^I^vhs$#)%w&rHX+ zZIyJRkIsC5kD?dbXIx5}%4bxNUTu4|vDfSx<-mQS z8cq6)(GN)d@9-Hr?iUQr_>5n>Lo53nj9pW?2JQiBpgwNm{J4~Okeu{|fe$JiN`HYRKUq|RO zZcy|h@L3eRU$GDn28XM;c_EF+8i0&v<}E z!LDPZrgc6ef%uNZXI!nwAA!%<4Uw9z*nNi2ID|LcV4B!IBTG8`dwj;VIBsG7eRq>S z199bpq$zs@_Wt>-=OLHhw}1X6>2__FZudrXAOHPy3vi^vT)9j2m%A_FJf3=HTgB4L zC)s`edQs%@>mxodu#R-oExHZj%Xs7~9eVcA=7)#&C9r^XY%=zJ`JhfJ(^bY{o>$Ou z#Kl~+Gv-_Z{Vjj7`)kuL{$uH{BmMLy=}&G%fA$|p-#JilWM>QTE=g<%;B3K&1c*Kn zua!i!;XJ#~(%N?1N64GEF5>CGR-H+JwzbzPZpC|;)Q0%k*gr>fAjbfZ$&_ONI1a!W zo_aiwAo{WO&u#VK5U4?I7Lt#N_VWh)1WSzArWI!ZV5#Kj3KBDuF%KH-{euJU{dd$V zw&Oiku(^GiD)zS*X00Pj)K7JkA=TRRPlrDPUNGw)f)oxOX0!MH<=mEa`c#fm#I=#5 z`ADeph$tS`lN^8iqtKb89WBk(Ysiz>rxCCZVV;g`uFBjbw&=Yrj8Z$&!E=5*?4G_hfSQq^-Kjp*dGf)4g#PR0nB2hEoB;!e^Pz4!^|zW&eYMfXPi%WR^5 z1+C~`6MBKUw|;`iane5={Y!Wnmsb3hqt2*gS-O&gKvTy!a?zG=>1DxGML*xt%kJ;e zpg4~la^m4p^V&5fpkUr=#PAh!c0C3Dw2C2QCFtJLPRsyEBvdW~E(yIp>lqz-!2+aG znPve3r!tV#9f=&PIuD9??2v#@6n;_6vy8aL*)<+ARZWoF#c4@A`HJSnun@DXaBmT- z1G|{sMTQtpGfu(pL}rcCagXD*lH|<-rkss}X$sAdj=Frn;#VCV1w77T@)YsJskjFA zf6PWN!HDw?0~KBt2|d2E0d)BEB+fQiozoS5t8<_e1bzR+9Kc!h#^QQn0Y;^W^ne`K zIE{xhFPYNTIrD;({eZxkG@hqQ1VD1KLJp#QLBtf;Ri?%#f`CemgAo$bfjl2&IQEC3 z=TQ_Ki8e6gs0UFzzKzb|I{Xxo1kD==(K;!*6eBH45sb|8HYLTSLNBHi9~WlXIjYFv zNpW{mQiNm@(eq?51%o3)mJZ2e&R3Fws>m}D@J`gpjEm2r`c9F32F^uqaHgdx6yi*! zDZxIs2-wW2&2}|)IYk?@s|l#W3p}K&2&Hj;iCvzV15Pn^BcY&Fn3+(@h&QKL3X?^& z;c*Nr4EPp>A>TlVZmZb6(e_twck%g=$rVnNzW)3zzkUAbFe&bg{>|e zK*;$YRm5GzEOpScIf*|>FZ0gMn(a6W*jmh*MZdR?dtr#BooD@d&ws*Ibi9OfqL-6j zyk*B?7KUsGFD-w?cSu9`vhd=tdI=0+rNwvQ0H5_-S3cy234l}b>g_(omLHos6}>=oOj*?qeQI&0sJy|0R}(hI8cZv1 z?%7c5%pneA{l5K3TZyeRiE06fcgFnzc+V-NGYCZY1QuM>lSEs%%_7LhLX9^qG zLxjxA9(pkg%%}0$+8B0)XC)OsGTXpUFlFXG3L^GdNzU2B%vZm4mGrki=c4MbZ7-WT zE19MG)vUc_Ut;(l$ajLG7a`vTFM{+DrC*OZz_{{$J5^N0lB453w5S#|xFaAb` zCG?(6yb_x{eOg3pqRz#9&!S-0m!zh3`RZcfGe%t1(z%!y6?qjSTc;Db!k~i|0XKOr z=5dJB%*QuoWAqs@%f12`bK6%fkPb7O74559e=a8RCD7Z9&-6B=2h-OR)3wISH*Y(y zax(Gwk*m_&h9IM|veHP$XOGR(S!Bfk6TqLH?uvfr7wjD0{XqW379_mlsIBr*e6l)x zjoiKAoM>7i1% zx8cX}PwY=C{1aa-diieH0_6A9Cy~By7|SW!e#1!OJ5nEp$=ZSstBw2M6Y70y&&}7y z?TLg(%&GWXKjH}aBzgOM`~yT{?K`TpE7GqF24kF$pWYN~!}Ia*HPwrur-k??F!i)) zU(=l^MZZq}19F$3n}r82%x~~P+2-l4xYDLO<`3|3pu3oK`N7@h=?-(~uKEM$l2&Zn zzh}4%tD0W4H_5L5$OIMNYWba3JySJX=3k3@!HY1FO&uTBB~SbZ6|&z=1>ZVN@gr73 zeCtU+ll9oXm8Rw}ed{R-|KnjJWu2={ZOXSUQ2jbW-@5#YhVrd$g?vTs4W2_-+&cLt z0KIA8OLR)QQS!yJ`R6HqY(KM(NF~OI_A@x^dm;^JQUQPdpl8-(w3&`+uxyHYHh&%Y zPj8a{xx+-BHvgNOV{7vsBUG31Z^!}UX{&e%0^wx;XC zUHBvRFB6t<{PBgL*z~VzL_cwbqXK^f{rRL{+$8<2`3?J@{s+>BzZ<4i{LP^;X$x#w z__>mcdN4$g*ZKV?S@c2zH}89rCggR_tr-B3T(p&8N7k=^UKLsPbo?TnSb$*jWl<}2 zka{+YRmK=e&y03FB(GH3dhci5#{z(GLS8NK%4)ey1sNnh)bl9h45%}qs*+()EY0L~ z0a*h6A|x6msfx0xpYVY?q{PV@60c6Cy7vET?@i#MtiJ#82XG-5Kr4wN1&)X3Uh#+*0_z&t0Bb zm;tO$pI@Kv-{-|}&vVyv&pr3tbI)C#noD+5?8)v(Aq(W0(`BRVMv!32oXn`mfYle# zg(-EiN(EZi7x7?OvQ!k*%!Qx4GQz5c%%a9m+ytP8c-0|e*x;#Psu@hGs38?95K@5< zTfX46WpFaDEtyn@!UnGugbpLna%asj|0;#44eS2G#O zX(fXU#&laKt!PLaE()Gilz|dve@yIxB?U4LvUOTo8r89F1f62RxRn|=pmSl2Ux9qg zFX5YJ)Cb-0vl@GC?>4~QafbYcSPzHF`sXi*SoH%o5F+eTpjcnOc00-Xm+-SZJRNQx zc!rj1E3H|9X$XC=I0&_obAo_=RI~oDrG|lcG>G#V0^JpWi3PicS18|J><))9o(pPG z8g^N1&4hhOK&$wS+W0a7x(87^f7&%<*Vafp1oeJa5!yl)Kn-ryi!Z?ZgvKJKVq7g5 z%uz2ET_%=y8R#ik^x>TaBNEx~$xh1qEsAF>$_&(`2F`P%o#p3!F@L#7NnedsMjGzq8s^h@x=ww>))Ps<}){AKs zjW5eE6nF<>x8hQdH3;+wjuPlmuSI!~Vsr@|mtYwJJ+?L|x~@PCvf^iSQC3-j61py{ zupjR|s4P}Qh{C89dJ-KOrzJFg1B@sknMwd9V-W{Es!uLu?_ix!dUtsXguQ< zAV|mu(~<_lRl$k|LX^Z2{GvE3LKKOk@$gIL&1{i@IHiLXWY*YhDDmQLjf;}O8_38D z!9Jq)e!Q*0BMV!*!B|V&ieQzuH+^(~t>VQrv~Z~yr!=nNOi1@A*@|M?&m!&AUIIt- zQPvauI4d$ZSfHl@J(P#~qn-l27=d0Cu_^qM1zs7zD;9k|*J@-zaygW7R%C1As2Ek8 zR(FvzyWE8d0)t=|3~9&-ITJ?2l7KS^BgDtxzzm!g5026{1h>yn@Q2!_@a&;7`a{It=9a zA!--VTR=zZIa+Vwv@PFT5Kl!s)>{xq>n%iYH1*Qj)Vy>DRUa#1D%4uoD~=n;@Jk~K zEWPHiScY6SZddC~l;XF+qc>|q&RFQCe2D5p8w$O}A|h8SadSNPLbv0$;A?|ZA8$y6 zfn8xdKM)h;E@nF%W9NMo3X)?FW=daz=5K*!sOtF-advPp0CjOj{Kb(p(#yxTvC= zc(ek!6u|9cHuatChm3@ZNkhhD41PGESgyWo_1>zYlQ9}%baYTdsCeuGeQz$Cp!M-> z9uNd_Cj=+5KuBdw0^Ob0b~4pWsF>-HYg7Z$t<~Wk!Rw^dx zxOLrKsI>;D$P*Q1`(^;ss%&~JaMP%|vXF5om1{*&1*#C*ic^$b*Z(=n&-k=Yp6X=ud2uqpww;U)VIPHtQ1J$U>-8|DHke zBye*wNOojhk*jid21zEhSr_@w43a|OXBRM%KqW=%F_?R~qSYweX53iV^oIMtmxo@u z%P9|CtV2O}cu4tY6s`VX81_w``yfiq%?hhF_r^@PYHAlEnulTqozL&{sEjT693Sa& zmCf(L#v?oz3=eaxVQg}&VX)3%t4_GGJ*3QlBIdfz)d}0VE*sCqTo<|#slPV*5gRL^ zIM~cyEczH9T4}a``%^FqiBZNNG3d#m|Kj-qKlo;KIzYM_{4V3eiuhEn-(Rlx0hdKc!MP3wahoa5h*Ihd|4uvLpTNz@6ekKB!SAT2 zQ0M*`_4K`mrS7;MjBQTY_@A@`)~8MUWCslIMRve<@o7w(b(;Et#FAB&&;PI;aB)YQ z4g>Y%AFu-&YcVTJ743jQk*qhv4p-bSQ3nBg#|{{S2KdMAfXc7bT9w-Y&pNaNx^L*2mfyw*ziww-BdYGvwRa0fVkmKl^tMlE;9XlR>f_>xy@5IRDHb>BtV4 z)m~QvWz>BO) z{QtlX$aT;EDLY_w%p15Ju(gk!lwEM~-z#O?mpGNOGq7v?j+Fh!rnAMN#3s9QvAx!u z{|1+T_UByjfuD-ca?W=(bfd!@*#iyT=t7$81VcAEWRX4D(2Wihdd_|lYb%CsbO6G0 z_VaYOv>RPe;yF8^Cc$*!l;>=JcY^7{EzjBEwH2HVuLF;K4;=ofRRlD0_e(ww8wOMxACAVW}R=^jTPn;=TQ0+>K>pyjo6MQ2(WRdDwZUz5N*osXM*> zAM5QGVB_R{qZN+Ok$s4tz!Qw-MPKCtcVX+uG%v7|)LH&V`bP8)tG+Q5>tMWZ^k{C^ zH)fjty?vvF*=gUH%(~5;`Nlsq-#7wuCKv`^h`R57-Z$*`ktayAf-|lE7V$B`dke-#aa$f= zSYKkm*F1m#@53q7hcQqL@IgOT*;v^xSXQiGvwv~L&fRv!vO7y@HmxbI*#9MIc4RB+ zBuDyuF1WE>{gwORZP|Uhu<6DhsqX(y3taRWr_${0pYM$H|KR$5HP~ypG@I0z_l7OrjH5@J ziP(Y@or*iI1_ULzZxZqn__9V zfwy?aNQukX=q$;?>eWsYmHPNG6_%z>T#|a38X?a}`VQ`pYX)&Sgn2Dr=0Kx8PvsQV z-1R%H-q6XI%^L`_wDEB? zrkB|b72yo`O9MpG2xdiH*0;pFHNj?YqFf#Htxx)tC)fb^p&T^oLMo@I=AgCK$OyI8 z%c@ul!#%2{9l_IHaG2JrjV)RGaej_hpR<65}6T|8G z@!hB=eU%Si8tFuJP3H4zek}4Ss)E%*zA*K$`s31QbT&W8B|6#!8xM{)jl+Q^PQOPf z-=dn^cm{N5i|DLOCgfvh6?F!l7TQ13wxh#P_*VG_a+*%u58k-kzpTvE;4ZtdtTD2# zXe_J2i(a`(Zl0imY{oO|?@R+-^ox`Ai4694>S$viK6Eb9>@>~B2YYSC)_0M%B79z= zyo+j95g+u!3XI?lB25n5fs6UQMeVicS+Sb5j!zWh8e-7xPLn*8x2v*bHS8))DSpYUQ|;Y z077S`20Vp9&_v_sN|Lj*MURgI+UeOyP>s!Hu?<29Q3E?SB)(LR%3EEg9EG~;c7oqb z?=gPcw-*k)%z2S$UQf_d=p(#kdAIbOLpl{s&a-Vz*vbrog_mJpH%4gmg84X)NQV&R z{gqybTU0alh8Ujn=_Bl)N6bG=!?SkB6WTlSI@R}A7}uR7;R)9Dw?s#r)sASet91GLl8HzVW}#?qMpvt?rwf|~two@i z87n&=x|nL%^cf7E*oNi9wi(k+$aES)97*tI(Qq|4j#UPiQl@l)H8va3chvEjbHvL) zSgs%90YzAC?$vq#-@b*LZJCzO>z0E04P+mi#=+T8LUv*GS5dyW4bMQ?u-ouT-zKEc zD+yo5YP|l$>VhLd19425jz|~b&RB*lU7C!$FxU}V9E}$D1c-D*-VCJ6wKgsBoA`2B z+4wBG^~Jo52hmPV@O`qnjI;^2L|@~>S4JQ(#+knoN-g)IEo^!K=%W}v1O*o`wCMWf zrar7z3_}AxiGWiiICw~yV*l1^77gUZNe@A4VA>})GXMEJFpD_YGLJxhTHZ(rpperU za{5|5|2hC*YDyetlnXSXDNhiFbjTQT#JZVg6_KEF=iiIZK<&(npK_|hI_-<>l=Li< zi=j0g9Wu-^#tEosXB<4tDyEHg{k0SPE%)*jxY&((L0Ii_*k6V0YeB1FMK$m9uW;T6 z*%uAIHJ{D@&yICmOs=U-twDDl1?=Q#MDngHrdeJzPoTldbeJ~z&>Rb-Hnk)YRempt zIScXF{L0w*NmVH;#&`iAg~=u=Rf=#3j0hBkVz9zjg`ANmyY~-T4A5^#Dft&o2s=Z8 zVMZ4=j@QMhdBc2{)vh_NWySO{U}!PBY9UEc&6}Vpx+Mx`23Ds1EH+@=!Oed(_CRHD z&MIsuXXtK%DVE)+LJHmm4DI4p!lVLI9zNb{qXP{=$&UF!NEqz{X{OJbA?*vp%F2+> zI)e8CHmxM+0zoejRC_oJ?@RE991bJ+CWiwE-aG=aeF!>9P&0xCj0DtxpaTTeB53U> zKng)~MgzLi6j19pK<5d1n4p>zx&jbzI!3;Ru?*f%ur8j#+X&vs;SB_PB{Kg51p9IL zC4yh$@CO86m;%Gn+d+m;dKQ2jbr{R2u|SeQi7LqcpkxrIs7=mN-~R|L9ic( zTM*on!!ZQk;BW_my;E5H()$2MayXFu=W)0j!CN`(Pq1!0i|+309}DIMpeiYz|*1{}UWOLGZ|_EY5obhd$2W*9ork1cRR^*vR4e1YZYi znn6&LX@K4)C>jv>aUQ`ZIJ}tP_S2dF9D)ltoIr4cJmw!m@CpuhAlQ8d^KVJ;O%69A zICK{CuT5|cV3P|$?-A67AQKOFCpdLBi(8LiBZsRK+-eT`{2;Efz^OK_d%n13^ZmvT6T;1UjxA~^DS7H1&At2x|@;A$^0|I^-pGdTPZ`5)wP zbAo+dWN{RN-{SCPiXXU~`5z#-+N%uyjo{TBK1^`v3g-Vc!5JLhOz?LcewyIa*I1lc z1jnvq@MMBRUuW>61m^%Y#S!!#K>-9^=9p8#FI2hf1CfG!fW3lQYMHiA!Z_&CAUerEn}670?4 zLV{gPNckZ_V+dMH&G`4il8qEGL*3Jl>{FJYyMz+)!CBQG)dWrB^rGk83~ zM>#y2;K<9&e=@-Ve=zt_f>$uu0D}ljJD5%RatluybX?f0>PODUr|IS!pxy5AGB1bX zoK#@`yo}u`F3dR0F%3l!RAtyWhQam>RheDrnvW}$aN-4qX3Vo5$6SHgzO8h4Tq#KU zJJ!g!{$AwD)AdEV{bGKmeZ#N{D8g)nR9;$=2=|=@qHbQSZgzEYH$TVg1iq(x(ybq> zIxQyr9Mx&#f22;1QR8)Sx2cQiXnnNVE2XUc_7a@P5a+X$hGba)b=ij*`L?b3MG+vt zUN%#*%u}c}DPQLwcZ|&M4XjvJ%m{~x*8Cm##v>*xMx^$xn%xWb#u8ZcN^o^hF}|;8 zVl%6>699|hbq(%`NV2fckHS0-mg+A+=K^yF-WH}!mr%d1=gR?X6aRb|o4CnqVN>rNG{?g% znYQ@Af)Bff4)<3u%NO0v1)GK+>>F4W=!1JLn&#|5bh^5cJ}Sj7K!v4>8GZ)DA}Ow> zN+)wlMgTi3h?^+$-^&9raQmZnj|JWMHx8)6?n7o2Zr4Nv6pyW^`2$cKS;W$PkdL@* zm9EX8Yp|GAEQa}`rWS6WuNIUz~#PBUh+z!yvNJ-8t)4II5a zf<&AA{K0X?+t~J4W&XA`?NrQc|8IKK=V%JpJM4jTY!nKKRDTUC#T{-fg$lpIYzyzt^82b7#?| zFc-W`H+_gww9lc9A-^q5SLg%y0tF*3M3y$r@-d{bJMqK+nK2|2AJMhp_ue&cm)|Sy z*8jCJ1WS0&(UA!nQj2QRK2u0rG$micqxFLM7+~4f7q$z~=MY`T$v;dCBRm#2X5p*J z`O_%%4StLqsWHf4X)+(;7v@VEgH8F>sgN(&dLtLLSnP7|7avh8VwSlXs(ObR6kD@%O% zMqi>2uhOw@tO#<_V{isc{f?8lFB`k%_2XD%WxWs@DkrtH`+jA*r&`4{|KT5|Ek;D} z0#yIr*Tmom!a!9X=*~7kkW$U$F1`ibmQXFKS=>TWq%Tu zSS(kw^A1d7F2~-C8j>#YAC-8Vzeq~Z3JQ}C9GA0v8fnE$;82ova-E-ql?^*N6HGk6 zl~(!Te%%tbp3n9TFuh`aeX3@a@-wA_4w%oH2XlHDiY)6?o6+NG;=wpUtW!aALB(!! zjf!YpR<8gu$DQ^A@H(8MoQrC%x|gN|a%$~u`V-4v)K^JBIo7gvnub?HTNiViK^DOq zxy_(E!3o?>5Jd0^ZYLN(@EL9=Xhv|s6*lLrPw;nF8QhNG_174D!wqokbp~G`c09Io-|xV$^AQgtiX1*7BsIQ&9tZ{9~j!o zc^!s|X&fz}L!FRzrQ(zbTQHnO3#4|!2J+Ame$+*H`|seZkgQKo``h#f8{YjvB&FLVVyHfUR!+@)P;zK|;?Pov$e)U^u$?E{iWnDR2OXMeVbi)FQFOYSz7Ga6+R1>?9XlJg zp;a;Jt9XY(rQQ2&Kv>L5`i{$dsMmB&G{1N|*>^9CpMm#eaAGdX=F?|+i)4{u3Ch8= zpJv1;OI+}Mg>w&Wc)=iAH^s^+`hR&D!aJxplyK%0)FVF#5CY|3rNA>!_Lo`f}O4hNt1OnL0Mt zEud6b#_uH*$681H>-`WynCxUvVxETKZT?wmXNE6fLu z(R{#i{|N>?5`hq9kfO|jshb4xhdu-mN@5HmuH4uhOhaLn`;izAG4>|$xyXuEQ~>o8 zHp+VOOSZf>v2xjVP0VbajJFuQwK*#>XT^O5O${~VPg3>eE?O#;FuVya|*mnxOwB89+?L zweSKtFSnklnaA1E$xQ1#=nK}mZ~J{>|0r?z-`S&8={*w_e`ZyRrJuMCg#J91<~5)> zLeOsGfhT7d+pmZ0LY3@gCvR|HN-rB+_HEn7W_qV+XsujVn{wAUDL2w-xrg|ig>Tm` zUoP#xWYZW@8Enc%-&oGml1|F)7fi#s#Bf00WP3}Y<=Bj8J`VL`i~c#p5k7K0R!;vk zoxOTXTX+11;G=wQafskRKDXFG@JJ4S%i?f&4Z%@-&as@}P(J7Qh~SMJo=dPFpMOjx zcr%BeA$T^Qi#$niF^7i`+=|aj(g}{_a2UY}93D#WQ4T*qu#V4N8WUW=;f@6V$zfN5 z+w(cil`DXk@;Qws`S0cMN%FtU;j0Au@cGRif@3(mh2RwoHXP`#Aj2}NPE^tOO=D`s z;h2%M;X(?gUnZ4OXgzlJZI=TPSN|^*h5k@-+hzT=I$_^yXdBp*c8@MC^Ep_Kjs+EC zk6GOOL71$$V((`S!z@#SvSLHNOF7b^K2e{Q%e#`S|5|+GBpb&JYMmpR@C z)sUuGbl8S%Yu1jFVVcE&|6wJi&n+9!l^64nIKf(~!hT1zs3N9niKam8+Ucjapw|OAVxm zkv<6#4Sq29Kz-qYmmBz^oqrwX^o&Bq=elQfC8FkZl(W66VP(doo%o6Ol^MZ9K!zMY zv;?-qNAQ+#2U^f3fHf2hyCW}*Rg?*( z<{hqpM0cPv@hMUE4GyM=4WUH`I=jXu@8W>{Fxl)rbR36Og3;1quSFdcrlm=R6)4Xi z=3Wp{M15O{m~ooUbws*-DWHh?-9G8)e)Z+2ptUeiybUQ%>ecp5}G40y>6r*YXv#y@;SpO zg!z`VUC28JU?t`~K?O;6CnK5p#i5RQ3c5W*n;mVTHpCex4{oF1A5~UA#%k7YaDx!! zM_`IvcvFNkyS1s+1+;4f?@xdJ3iu$0_Y)k*+S>pjWuA^|5x-;qTLt^DUL%4#+J`k; z(%5S5A?)r|+gk=X$=kFqFJdLmrNN$uPg9{p@u?Rvm%j~s@u?ig_^$sC;A;vycdLxf zFR>5v4stg?CTNKLi$p{Fxs2(4grky}5IsS)DyrF)bsAzKxku0O@gcsq9?cpZnm3I3JC%?X~u+TW4Q+X~kg`6S;luFhA}swUu=)n`T*l8v5o z_JAswZ(|mYZ9+vgXfx8^+53i#Mo%7QoA|1{{3y58l-Mmo&M{`!k=>DaW2VT!O*P+x!rSinyqYvJ-7_z)qhS0{eqwTba-&@^G}z{Nmu!vZD|&4#qsvCp_m6 zFIBR04x>67b0WcWu$q{WmzYHJ38{_Mgboxk`?qE_AtS7i<1~B^W5c(#9Cx(-rhNGy zUVr1fk%Kh@h!gEl7_9M2@Fi5!$e+N)V+PVbG^{s~5eqWRv~`~y&2K;qR7ms7xFEpX zdQfRuDDZbg^V`wSaHg5jJ(vr$d@h5|pa{OUkL3=bH8~ltD^=oQi>-n^C|TCUN+$C~ z%G+KKz3q)-q(xzo>sNWEuR8mF20P=&XoLB%KxK|G$M(P<=6x}Pn6;fOBU7*X475H}b#9;UnZffyqD`M-20a z-;UfKg)Gy?O=Q5+gbCVJBBA@Vkk;`RB3L29^49__PV?Ekp%MOAMP_f;I zL@MB$*qH2^EvryJ@MFbwD~~n0Fl_9nsS7)_8M9S}G)!{R zrRt{(|N|<#ftoBOOlV*xQPwjnu5eP7Bka)97PHE+=*noXTaxCW3J$gXTkP z2wuwJ=R{=`Jf?ZhRM+Lnx3ikoeMAx#I`aXE(18n^yMaa)r;7*d{6@skqzll|u78AYlFo zSIKIm;XIJ%Z&onh8a7ekltbIuuN?Q$P6Dtu)4 zsPNI@V@My_Nt8l*3L*H;bB6+VC~$`YcPMa&0(U5IhXQvfaEAhSC~$`YcPMa&0{<5% z&@*LRO13UBHzP4VJ263*lBSEx9G5d8F)dr^m6@5IY2(u&BQrg|L+gYN6XG(m6vKdi zy%g@1m6)2;Au%^mX`Py&wD$GyG)^%jB2LQGMBRjxtgMu@amwKAxcEnHd?M0PvQy$x zb;*dTvkB>+n44|oofH?J4OC=K8e%DF*@@#4GnL*0G7{6e>XK4Y6LoQ^nTc@;Q*`O@ zQnIoWQqsHH`X$Aure`IJ*lFq6ET+zfMQx+>?!iNQQ(iJu={+cs7ZH&*DK0f7ffqF) zJt5H&6d#xNpva660V&2Qy@zI|WGD9MsV62@6_l`=>0wbn_gRGiKgbhZGr9aCoJxw<_J0W5K>hB~B z>}eNByvUneCXx-qSZK16*-ptEt4tmXU@Vs^={ew~B;AC>3F(ysJSA$kj!Un;<%JFR+wFGT2BBGP*Fj# zu^c%FkRVVYa>CxglEm`0vdzi$)Nlmo;WIU&sYWZ66HDRVp%1oa?ZAk4z__1(H zNL-o@#Locz84K`icsz~SEwOF#LAWKPf_$_dV2N#$55g@W738CJ3rlR9d=PF4sURQT zS9l9q63DC=1sI*I<1wDL$g(6#m&*E_B?kvZY7%iWNk$!57LiiYG;;HB5VFE>5U9d% zRNPrOlK~{y<5E-8Cku{6RU-xflLQN2IE-h-7<8{N9xLHdd8W4UE9?=@go_=T5Hx&X zVm;n^>_g4QPSLSY!qaIyHoyb*&L4q&sTyoK;4aEAy$OyCT0qyhA$S z#)`rt2DI1ZWF_i&7F27hx0C$hbUA4$6LTOYX|T4$tB`xG;yJ4@FIME|Twrj#9EaP~ zgLcN^aT?!YJ+yosNP4^cs#IU+0*mA2INYWlgRIMS5Z_@vw0M=&1M#X<59b1t*TZqR zO+DzI20TvVJFG|Lg4iyZN0IyEEeuFaC6~?e^gqw4(?lUcfq{^_dHzB&8214uu~%d z?tO3{h8qYs4Q?dd+FNiQ1+LeprDX@1dJ4?$-;BJKLjg!o?_aGkJLb%y*cf*|r_q(FfvW;+~_o7_5@%u~5 z+;KYmG~8Bj>tXwO6x>^IABX$lXNV8?#9{1Ds)_ht;M^G8Cy$htMZLA4>*UP0zoto|i zE;YUIO&JAW164L}xK-AUM{yDt?IGfBMO-vLds^YYAAWn^yH&OxZL4^A_4e@Y>sfoU zd!C|i9MZO9s}>ZI%8$V>`2EtdSIDEMhnMRM9`59yf#0X_r&H*PD*{qH+$qm__}#ss zwCr8Vx4Vbe0@rX4@40T_9=ci8`gj;!-Ilw0=-?IZ;nm#(bfUbr;7jE4zVHa=xX}4%*AGj}XyZSnk4DCnZv#}=4gM|3Kf=Q+ zM)l0`@Rt-j(UtK-?;Dt;OMP@?v z_zro5eq36HkGiq?MTvS`hJP0a{?xyN;I9+$M~L{X;2#G62ZjGw;U5bBe(-N9{3V^D z;Xere)D}e7F^Es}NQM7s_`in!>69J?)ymPs2hmp}?N0RhWWbcxnm=4)Eqp<7k0Ndv z;?AMCmi7m+TwJF}20#$Q5A=<}_P_+&xWp?XWKVZ**d~N^ zAlxkU1}lZV*2JC$35eSc$15JUkE^<6*~cwF+{ZBH&_&Ya z=#_7w7q!t=#4SeLr4*O9(Gns&@x%#)#bC_Jr7)7e;0a1o0{_kMA42{-4T(M0R&~ID zmk`Eevwa^+vXreNX)xjj9x5$+qe9-I{!rksKM>#3xcV%{Qzm~YPy7nt_Y(YG6@2fA z2iz8Mjt#enJB9e*AkyB#xcs8PsS-ZOb9KT8l$STg>b@AuqpFry=Zf-5KwkYZ?tdui zR3TnbZp&OMz-vA7`sg@xq^jk0z*$~Cs3Ykk1HLXT8)(m$IyZwgU$#PA(pj>hqx=Tg zu3wmBzX(N86ykOJwzO=vz|Zlx<(6$Pb12)M_!S`iHJqa!MINj#_oBYsi~4de>dOY| z%LeMpeLU3h4k<;vbprW#ohZ|E7s~F=bB6+VC~$`Y|9_#t`ny$D)jZ*nNT$c$ZOpwD ze0YFAUMh3(5e4=%2=C5ZIZi9n_&aVEWDi6wdt^TDBAn)$^vLi(O3Ua*RK?v*C5Nu4 zW6$QADswS>vnN=Di|MSgUm#3ZaM4403_WaK!$J0+)Iav*ar|iLrl&*%kX}R&hCTK) z67Kq1Dubkduy~hvGaU*sF#TqaEFT-&S$#}*smvc6+S$9LFFwY?-e-z%p8CJ{-%GTE zeThM$eR~Uch;WmHJ4v{6h5MXv-xTg9;qDRcG2xyS?iJzIsHd``8w&RU;RXq}w{V9D zH%YjYggaNb&k6TU;cgP{9^oDn?pfhp5pIq8qI}^#Alx9~_7?6C;U)=pl5pn=_c`Id zDcnuM-6LEJeRUi>EICPpcnMdhaj5XPOEour;>0r0m2@-MF~Sv2o)Pb@Az`sn|fo_E6Zz ziBF%9f&DwQalv79U3XSoExtiWmp&;mGYKoRzM`b)db3_3;T^~o~0&`t- zdUjkY>JX8ZkeG|r<#b(g3dn(NO^-zN43F-G8f5|#WXNNrC60^BPMMVGFvb8~B5i>} zc0?`T)_wsAO24?wM-#D&gi~DmpC_O^$ai|Cv;S5u4=>Tn6vRI?_E0<17((4&ho6dH z9)4^9{x3wJqNo^pB+tn)O%q8xnBhiXo_J?C68t}$0ilmEx(o-_%5d<$>?(eAZOkeB z3h|qcU)g^t0u@Dg&_lS;L-^1`IMH*8{pYw5I92oL%w6$XCSJ=}Vg&KnWo0a}CH{1geme5CdJgOP%i%)q7K`^{@h-=t67hangkKi# z*TnlZ@vaR6MxLL$DqQg{6nn)>yf+Zx4aB=D^7E6f$X6%cOTrZPl;FEt^c)uNO4v&; z((|=mxFVfVy#FNK!k8`__fFb&QC}nDnFjCn`9ZoO{tCVKLp`JaeC?Y4=^cOgjC}gE zbPEkXOl9#0ZEiN_mw_hz*|;MI4<0F1~e6xHt4`*U)oG)Ze6E@@-(fu_;IN?bg5Y{SA+4 zp~?yVzUhMzr?x-SzMEU_)^<1lEYx@VVMqN_v73u#ht&O|JGb+ENRh=bC;*W>wiPk{~V`F^Se|=pXPTNYmRKt@qssA3l;8G z?tfj+-xr69_d@Y5!haL_n58SiXNY`eh{`l9fs&I{? zgCA)#b-br4Tw~5#pO`P z9@o$AKefdl(dnUn!{@EO(&MyVxRNfSoW)yNeG96I@)v9V>GfwB_rLa)Ubuyqj`SPr z74w5$xP^;JUR_4+3Eo_#;*gmc`g702iYi>=jkjW4d$_r(!ZmLE zEumW4Q*NqojUzX&54n1vnkro5{{0F9NV$7-v>HGcKl@zk=(byeXS zpGa=GYTm~ls&I|>eckBGVLC5WxW*4N-%tJhV=q;>#-5$tdUilWJyp2ISdYTww^JIZ z!Zltzym4{$>kU-l8uQ2ZZ};kwdsN|ae1&{t&-E(}RpAh`ofA6WMo(s)?>RtchUiH+$u`8cCyy~s3 z!VT@Y?UyA#Z2CgO=Z){($ql6Uh`>N#k(rrLoar@QQF=2 zm|nPrS!+Y|8&+am2`2xudcSc+&kX(Dw_EAVc8PuNxvE!kUyZuE=a>4J59;6VfAN0Y z+MswncHmq6yD#kzUixw%$@^G}*YnhXNqe23CazAAmtp%ype}%hKKc8 zM&U;aH&;J?B<^g*>Sn15@FXL~l z{?xO0#dm(gCT{;@)*P=9NBqN=`W#&_s<`QddAsAvZ~QgQAku5$g(5sugp2g< zDo=k!zcOxMwP&NB4b@+m_tk)|S4Da)yikO172*2YZSH!qa|^vO=$%=OPy9MSO|ScQ zWZzeN89kc+zI9q^Yjv^yj}e2XoGsjYviBQr4;yD()^AlOFpEavK@nF}f#`+^- zPu2)eP(2^N+Na*KR^WxPyxz#p)^+Ax)eM9fT)x%Hgx3~T( z{L5Yah~J~;yZ+AVo802wumv-gtR42}clvHy@A3Nd){pwEB|p9HdeW>ajAW`i++Ns(HEtOBaQ=Qm@~*dH&`cRjq$_$CqA7?rZ#b z{ztF>@pGQKabmb>$>ycT0cWe-KQd*NS^*yFc;IoSF~?(~yUOr*YMAmg;gMy&dg}`C zDE#^RrHA4bwcE0W8C~zKqh8)$_q*qhdaE6jZb^@3KcJ?E?eAGSAy6&7;JW9zE8*(C zHQVD`pLtkadm?|H8@*1Fl_Mvb$OgI_>afGe&)a=b?^+`HywuN7(dw)@nFiZ zIJM8&h2y$z3^LZ4J#m+*LzsHv^egZ7`J}6{=*;O|FRs5&4Q;mJz|z*I3#Yd_-grRF zIQ_L2k34hX^+{^?1?G(Tt)>{C9AD?sgj(_Ho|s7yCli8<_b07-D(%%@^b5By_%`_^ zmD*{2N!>rFA6{$TcKEhudR)tSal_ArJNEUAUX}8D;VAvUrep4QG4`1=Y((eKdd6<9 z@4w+St%Y&>hIwlS6a^ZM=X38H8*eZ^^ZVt6&8H1FZq>b2?0$HP@hihOxnFIVtuD{1 z{rRxjyNx$}gHL}S_Jg{tU9ZT(jaMte<2>O}|M*pg$LaA8GdvC&W_u7GVF9~if`P|Z z3r4%HAJneDD5wH(Tip#@hFEuQz_iNMrVgF0Y46u#?v64h zcl>Gpv)K=!o~@@X{_K}RQ%&Qx@gec*(7V?LeD->-+IPU330FRvq~08oJALxqW7TcT zKbiQ|U7c0X5ypl+T<+!VDICc3fUgRFnMHHteR}`c&P!TF>?j;~F507L;#U2ep;I0{ z)a#={W57FaeYXAs{n%#XcbRIwUpS+AX#0j8-qC08*?94;YO4zEbwyT=QmhyLg+hm< zZMArc3qwV@$!&SLXWLv@Oyzz*W!K?7DEIsezdu%pa!V&4I`ZDTALv(Xen0K8Z`Kz! z`)onLNYA(B98t_EXNWnaSZ@CM~B_>8S?M;MKAxM zsMoh$TU=iI$NIuk(-%BCbov^-w514lI>*~j&$4~wtHNc^@qEv%@5%E0>9~7C%J=+p zU!Ep<)tLB7%nIatYfZ!4ZGWyW4Ei|Z+1E|TSK4a0tK}%WiJf=+Dwkz#=G_3T`<6XL*M_m6ZepQ=;pckQp)xr`p%zuebmvl zt$v}=eRYF#*Tddi@c1G(pM7BoqsCA4x%+qh)PZ#lU3_H`;h912aMfdP1cg;&;Xmqs z{4x0X;YP@&HsH^5v`n4@jbe{R5UhUeqMYXew zhpIQeJ3V{cqr=t2-nHt!(Enle)iIg-8b91dZCX7nr(K&4YJB7`rOSJ%>Yyfz+HNZj zQuU8?ACmm4xB5}ZV)gryQ~G1GE<9g6x{rF*|D6#o&&8^l%jX^+HY-jY{%6fMCVUyC z4jEWb_;zM{b?SAcZ$wIcbwcSAY0aK$rTQLtFndMJ{pu&(+C4dOldD?%*z3o#Hy_Y@ z{QAJliw@}3p#`r+By1R}>ITd-j?N#h`ZX{uo09mjdh4x>Ps@h1QGIKFw(g61P1I)w zwfM73ulDMWUHu=Mb*iPRT>YhaRD5;yP>tvx9@%z4ziQQ#&)*x2~R`S%A&wdS7mo1s~`kyh))y>9EduxT( zRXa>s`0>~8H&H)4V*Gwtu$Nl<c_ube6qtQP1Soo@~>4|<9Gd;nf^z{U!EHZKJj`jmhnrqSNDd8{XYDj zQw4@2`mc+w{IcVx_4@a}Ha$|5`lSBMC#NsGeq)$EY0s|EX|6u{=SEgfA6WhOu+V#h z16Du0B`k7S_jYA-W{9~d=DL>W8qIm}y7gz%!(r!l&n)}2@R0u3@zsvIKe|r8d-~q= zwHs#Xd#?66GyTLP`bLFc$1V12rBA#zVdSqjFNXba+2dQk=9|KXH9LBIe5WTW&Hn+B z|A#|){+*VrVEI@3x#stjzkB@3d5e&L{Jja=e*W`f*mLno+lv}*3LE~#lLeP9<%YfU zPO&%gTP z$bvlmv(bH%H;o>of8q0I!#ds2>8A#z{xSH>xv-0`eA?yutPNqs6GxUke_uAozvO8n z^25mgw8~tifVJ{pE^d9^rvU?IGNq+>I6Q#nVZOU{!27bFezb!qxXw=I(mO z$lNo}^7ot1@%LNr^Y_ymj4OL>`u*0?61{K>2l+kpl~=^^9>RvP6Nkh3-|&)JrqvsvSS8E4~ppDXUq-<>B-bEs8@L8Ne5wMrikbtt=w=BMtiC#UB>{NMZs4b ztRE_u_8cHB1uOLB1nY;wsod@Z21L@gI;oODy3o-@1ik z74Di+r&>7H0!wf{AY5@%Ov*vH)s$i-s(LtZI-#6_TSGalC^f=CyS>VNaNQLn_ML}g zAJ%3i8g4CRy^;a9wz67T0Jn~^LRk&BuJVGi3$BM!pcKRP#Ob1&aJ^uP@va%J)KhYm zK)CgB8Yv3y-Ab~O3b%n0tIUIY4^A(wg4~(xd!)M>{M^y9}3g?TBQcJ4|ZuE=#|30zrT)J8qh)3R=8ad~dCeaAe4%UIym_)S@kC9lnP zc~QRMQP_K;#kJ%`<%~&5OBkz#@p`$iC@u^aYInxwaH;&Ii0g(32`MQl6pi-K^-f8{ zMJrPiGew-uERKtk5Xa+qTF2?rBRX+HhB7E8O_!ZAA(3y}Xs^r6!7UgMD$0Yjy93AC z#Vg(u(i5}T?Jg7Ivg4DfBeQaWTwRxnSvbHj3RFI$c#%HmsksY$_>U%@OunD@_$0OI=EV1V$YD=QzY}2c~CmahtjqX zKkK|?o{roRqksnzQ(iJ3f_3=aZu!L5<8XV=o2w-+x(mKWfa0Pog}*zXKG9RU$7Q9& zAJXDkc$Ui!itlP2KOACxa_McwkDKEAw#0+-!x=B6uL&3BvtH9*3wK`rT|9oT6uM{u z@XRWt5oJWhrDQ4_sve)ZxpKM+@dXWgrzEB()L$d(SZN&wj2#b7M;&@sJ;}|EiLzvZ5kdu7(2A$v$?#$8CM7KNG{^yXLMD|)}td1;t~DAqr0c)qW@mf!prj# z#S^TgG+tXd9e8}kN=o0`i61vbnX1M27Ch}G#yNK}&JjJ_7>^OpL{I6TI5~Ps28IA- zla|(b8&R7^PvK2;w#xB&^H3Y;)?vJNsjkG)gS@C62H_U~fBuxGpDO~Q!PG;vIL`5- zxE*{g`x#|BGi3^4a-SoOBlPGV3e%A*{bhWTLG;-Bll-H{-e1RjE&hZDJzaIoDHq>9 ze;L2MU3}@U69vn1Nrus*dtAp{=`Zo;zLx#%VzX_EZ*J=^ z=`*4wFQ8mLEp6jVd>(tk79W|=F4c31RT`sR z8q#$&d|3(${W!h3{6#bk*W2}%{UrhyKho1;gQX5$nYMMf8{t-T@0}SJAL8FRP#I#C zX0}}#s<&1Lk)jj)B+VrsP!PN|e_0P2GpzmX;~%jq`|uQ7d>!&h5V#P8ul0eYp6-v? zrgOk2l*(V?Y|9Tp8qQVqpKDe2eR<`}wxV&rxG7^3L;O1hY_Ur7on4yxAdp65nWCeG zmXcL zRk{;%ZPVGdiI%E--)&BUxw(e3)+RiO=C6&f%`ub4pdjn$EPhq}$9`z3`_1{bb)Yk8 zR&C3MepEex&bGf~m9EZ0+jP|LwD#3fbcXpD-e2etvW~L7#_+0F8ehxbE+2dU z(VHxF_gi9H2m89S=0M#^20mw%PJPBUoo(G^DvKP{aA56jX-A7c*N@88o!T8`OMhqa zZ`WV)NzW;1aT8MFwftot?2#PDhH6=^z5HGIk%flsU$Uiz7x1;>pFtu1LBU6?;@82} zMC)b{9*1T@gl4l0SDPKAL}k6Mx7RddkHQbmC9K9*>MK^_W52yHbB=bdz)* z)6!OdmGQf$r!&>3vU0Wd6?(FaU#?wXucAjQSLo4|#npRZ!*Wxo)x6sX5d<#Cj z0Ev(0&+LenF-q(Eyjy7Wm+`C0x3V3h?b`8n=`ZoIAA>YLwBsMm-x>R95mEw*APi-$i3Q4(@9eKi4k4O~0eq4*FfR9X`(JY45+os@#Irws_JQX(b=n zND<=iA8^GgP43&aY3d`5?bw18prPa=**;^Kb;*Ih9UsZ|r?G`tqg+0A@wNOb@!zsl zwvT1rp}uQ7?_hMt3}OtowuJ4ZJYTiCO_ggpy1+(PR%^i*SZt$P94&MW;p z`HjL9BBY}qb@Sy_$n$bxrFjN+9u*Q4ggi+UT&hBzBM()Yr-moGveLV-^19#rveG;? zJUb)Lm$W=B{5|iYEq^A;E#lN-e#+Qt-QNf2BJf#*s}lI-OZY4{32NxJF;G#g*=3 zu;aOoofxwIejeLpUEP({NXKO@w}CiF7YHQ5tN#AIwRDzp&)AjgfJOl@f&_F431+st z3}$`D{9ntfyj^(jHCq3qhuei6;DoC9cSQ61f1~AN!O7=_EiK4KoPlG|*&!W+q}-6> z3zl%$WACqX;_u83WuK3f8_w*x_W8Jq@^sxeP*r^F@s#?KFfS=LcF4B2(C5T0r}Xh} zyR&?JQ<-gi2W{*hJSrrxV@PMLGvm%G+;QtG%uQK%pQh#Mt}Ly^zcEiXw^;a7URe7g zdsffHtoY2741D>bKeilzUp85#ORinjbV2N{Hw@d^ndzy%{nFFo5`2f!fL!y-y@aKp|Z(A`Z~>R(_46@vvSr!`~`OL%ePwqRIva*u&MIEURnS0 z?eEv3Jl%NT4N^vH>73K;4AM)T&~d%}X_&;A)=7C+%g;i$n3lHnE?*By-?39j$3W$R zgY^jO=2WgU9S5{^x=ue~u!>;8ZeR1XK z1ChQ9^Z@0wmcD%3B|l)>cI9aoNcu#Vkburirr@%4F?ykr;_1F$(u8~H@J{XdNdJiF z(OQ`8TCt21*{gT-%nIVroMcc$9|J^?vPO$%p}qCq4w+|Ec*LM%T3pBF_88EA@Qn)M zkjxm=tH*#rJr#xWZGQlDa;e7F!V$#o6cdCXy|ZUxl4Xb{djaWHQg@{E&GGImzVEo~ zgfTD;CQ`;oNjjZ%+7@`PFl`)$@F^V6qrkI`wJQt7eJ>8;)B2Qkd^xYCyaGS7-4j9m1#wA7;~OVzC|sTo zbk5`Zj?0u3c2_8#HGLnbBpp$BjNk*}A=06((^Gy<@MPsudPb{5kOwYq#6Q^2sHI^u z6Pv0z;PLyN#`hhUB&wE%{P|P9Uy3%R{=_UxgwG1Zhf0e5fLNd7`BV51vY2nt@^a26 zR%yaBGBEyEAr0ApKr1Q-7U1;BB+r@NF6>bOpUXP%nt0=#;@|^a8QD`py3o9Ph!)3! z+w680nNMj5H>kMyl2<}V7Z@gaiSY|)MjPDN*U{!$ zr7Q8Xq)UZAwPAKTj~aqC(G6B{SNK;D7Y4MGT3kz81_oI8kn*Scck31sAlk7mvV-quvY3VHW4i2=` zo8l85=zogqm$D4V>rNJWQXIl58I_PW2P%V}WcF>n5u?Jiw3c$#ArDGNI}&9c?b>1d za}c*6sC?Y!%~@it%+~x>8H|$$%nHCaHPe3M=FQvl9mRCLT`E4;$#n>kz{Zj1QlzWV znJquoI4WsismJ-w7TijJJGF5rbV2F^Xdl)Eam`;=cP%Z}NrEl(^MOCn0b+^SK5Xm` z@E?irJc>iI2#i5G7qdx#2cFaNbUtq|qAbFRYz~wcrB6*s%I=4Clw(y$zoLt6`trJO z5Y2xuZ}3+h_)5~pIX*F6tCC+wrjt+7@+;5R3qmY>P4y~|7tIYYpAP84^gC-==^K%N zZR$)NRKC&5u$9Fd;ZJ-lqq-iGb+fd+UpGtJQ+%Q=n+s!b3vduWFw8bS$y<`C7}k`r zT6}!JLT}*@nJ<&eXtSrZcosaCB0ljD^(7gf&n@vSAo#Mniv^MWT6)|1u7^MI3F&~`33o5iNH528AD%o+*rkz4d5AyFFp#D=o{WW;-T!gapG-UT8{77 zoRrjrhtO+$=`A@fD_QYPn39$?Wde7zGkFMPY!>>T&C3{sWhSP^Q33&Fq-Il*IMU&p zjc@5HzDamNSb73%k&16(GR7oKKE@;`Agz4kDWFl(PEnRZ!pNBIV(=Z8j=b>CmleP> z8;g;{7q@(}j|PLBf9s+4b-|CfKYi0h#T);&3%U2vKdXo0T0f*4&{!hV?{Zb~hVOp} z4;_26{Nu93@=jvdI{g_}l?9#=>07Zk%Rl?{qz7KXozAj+cQ=(qb{B?dKarI9jvhI- z@Hc!z2LRDPrVkeBgGKs0Q6TkAs=G{2^GAAm<3~|tdUa-=%~;kZjjOE2%eHi`66BE3ES!dn>+fT}3-llN=~lR|_i zmpj_M;P&;;MmVMKF5=01yVr~K@}6&^Kh1UQ(@%pR(S-10kC!T3?vPxze(c*HQ*xX1 zxVDN#*U^L&&w5!g{>tX51d3o~Hel=W57$>ISUFsuIZC*%Z3Z$O4~0AhV4Ysx%ibWI zrxVQ}qcd7*F8~TedaabG?mRe(`}on~y49nzf(d*9KPq3Q_Z!XA`;F#4yC~4=v8Ugg z2(wOqZ46I;Z46KEZC3%=elpAT00>3VU9i}~(<^B_y?uQ7F5Rt2OZ#nQdU;R1dll2~ zMOxw=nO@$n?j_O}i~39clI6;F`~qnyicDWJo#S63dX$WZDD08xrF#s%*6EczQU45H z|720VNUrg}On=HQeZ~x)K4T(Jzw8m2lDqc!`~+{xOX9CP&ePW^;^_|u+ospqzAESN iPAK}>`OEYJ?fhkRtX)~Qb<|O!{NJrT0n2pK`~L&!w<`|- diff --git a/gengen/Data/GenType.dcl b/gengen/src/GenType.dcl similarity index 70% rename from gengen/Data/GenType.dcl rename to gengen/src/GenType.dcl index c01eca9..062dbc5 100644 --- a/gengen/Data/GenType.dcl +++ b/gengen/src/GenType.dcl @@ -1,14 +1,16 @@ -definition module Data.GenType +definition module GenType import StdGeneric from StdOverloaded import class ==, class toString +//* Auxiliary type to help with casting values, this is gone at runtime :: Box b a =: Box b derive bimap Box unBox (Box b) :== b box b :== Box b reBox x :== box (unBox x) +//* Deeply embedded generic type representation :: GType = GTyBasic BasicType | GTyRef String @@ -24,6 +26,7 @@ reBox x :== box (unBox x) | GTyObject GenericTypeDefDescriptor GType | GTyRecord GenericRecordDescriptor GType +//* Type representation larded with the generic type information :: Type = TyBasic BasicType | TyRef String @@ -35,70 +38,54 @@ reBox x :== box (unBox x) | TyObject GenericTypeDefDescriptor [(GenericConsDescriptor, [Type])] | TyRecord GenericRecordDescriptor [(GenericFieldDescriptor, Type)] +//* Basic types :: BasicType = BTInt | BTChar | BTReal | BTBool | BTDynamic | BTFile | BTWorld +//* Array kinds :: ArrayType = AStrict | ALazy | AUnboxed | APacked +//* Unboxed list kinds :: UListType = ULLazy | ULStrict +//* Kind of a type +:: Kind = KStar | (KArrow) infixr 1 Kind Kind -instance == GType, Type, BasicType, ArrayType, UListType, GenType -instance toString GType, Type, BasicType, ArrayType, UListType, GenType +instance == GType, Type, BasicType, ArrayType, UListType, GenType, Kind +instance toString GType, Type, BasicType, ArrayType, UListType, GenType, Kind /** * Removes recursive types by replacing them with references * * @param gtype * @result the main type - * @result all the separate types grouped in the strongly connected components + * @result the separated types grouped in strongly connected components */ flattenGType :: GType -> [[GType]] -/** - * Convert a GType to a Type. This always returns a Just if the GType was - * constructed using the gType generic function - * - * @param gtype - * @result a type on success - */ +//* Convert a GType to a Type gTypeToType :: GType -> Type -/** - * Gives the name for the type - */ +//* Extract the name of the type typeName :: Type -> String -/** - * Gives the genType for a type - */ +//* Extract the genType for a type typeGenType :: Type -> [GenType] -/** - * Return an approximation of the kind of the type given all the constructors - */ -:: Kind = KStar | (KArrow) infixr 1 Kind Kind +//* Extract the kind of the type's constructors (see `{{typeGenType}}`) genTypeKind :: [GenType] -> Kind -instance toString Kind +//* @type Type -> Kind +typeKind t :== genTypeKind (typeGenType t) -/** - * Predicate whether the outer type is a builtin type - */ +//* Predicate whether the outer type is a builtin type class isBuiltin a :: a -> Bool instance isBuiltin Type, GType -/** - * Predicate whether the outer type is a basic type - * Int, Bool, Char, Real, World, File, Dynamic - */ +//* Predicate whether the outer type is a basic type class isBasic a :: a -> Bool instance isBasic Type, GType -/** - * Replace builtin constructors with their pretty names - */ +//* Replace builtin constructors with their pretty names (e.g. _!Cons with [!]) class replaceBuiltins a :: a -> a instance replaceBuiltins Type, GType, GenType -/** - * Creates a deep representation of the type - */ +//* Creates a deep embedded generic representation of a type generic gType a :: Box GType a derive gType UNIT, EITHER, PAIR, CONS of gcd, FIELD of gfd, OBJECT of gtd, RECORD of grd derive gType Int, Bool, Real, Char, World, File diff --git a/gengen/Data/GenType.icl b/gengen/src/GenType.icl similarity index 95% rename from gengen/Data/GenType.icl rename to gengen/src/GenType.icl index 4d2e311..cfd52e9 100644 --- a/gengen/Data/GenType.icl +++ b/gengen/src/GenType.icl @@ -1,4 +1,4 @@ -implementation module Data.GenType +implementation module GenType import StdEnv, StdGeneric import Control.Applicative @@ -258,7 +258,7 @@ typeName (TyRef a) = a typeName (TyArrow l r) = typeName l +++ "->" +++ typeName r typeName (TyArray s a) = "{" +++ toString s +++ typeName a +++ "}" typeName (TyUList s a) = "[#" +++ toString s +++ typeName a +++ "]" -typeName (TyUMaybe a) = "?" +++ typeName a +typeName (TyUMaybe a) = "?#" +++ typeName a typeName (TyNewType i _ _) = i.gtd_name typeName (TyObject i _) = i.gtd_name typeName (TyRecord i _) = i.grd_name @@ -270,7 +270,7 @@ typeGenType (TyArrow l r) = GenTypeArrow <$> typeGenType l <*> typeGenType r typeGenType (TyArray s a) = GenTypeApp (GenTypeCons (toString s)) <$> typeGenType a typeGenType (TyUList s a) = [GenTypeCons "_#Nil":GenTypeApp (GenTypeCons (toString s)) <$> typeGenType a] typeGenType (TyUMaybe a) = [GenTypeCons "_#Nothing":GenTypeApp (GenTypeCons "_#Just") <$> typeGenType a] -typeGenType (TyNewType _ _ a) = abort "typeGenType for newtypes not yet implemented\n" +typeGenType (TyNewType _ i a) = [i.gcd_type] typeGenType (TyRecord i _) = [i.grd_type] typeGenType (TyObject _ fs) = [c.gcd_type\\(c, _)<-fs] @@ -278,18 +278,32 @@ genTypeKind :: [GenType] -> Kind genTypeKind ts = foldr (KArrow) KStar $ map snd $ sortBy ((<) `on` fst) $ foldr (\t->gt t id) [] ts where gt :: GenType (Kind -> Kind) [(Int, Kind)] -> [(Int, Kind)] - gt (GenTypeCons _) c ks = ks - gt (GenTypeVar i) c ks = case lookup i ks of - Nothing = [(i, c KStar):ks] - Just KStar = [(i, c KStar):filter ((<>)i o fst) ks] - Just _ = ks - gt (GenTypeArrow l r) c ks = gt l id $ gt r id ks + gt (GenTypeCons _) _ ks = ks + gt (GenTypeVar i) c ks + # k = c KStar + = case lookup i ks of + Nothing = [(i, k):ks] + Just k` + | numArr k` > numArr k = ks + = [(i, k):filter ((<>)i o fst) ks] + gt (GenTypeArrow l r) _ ks = gt l id $ gt r id ks gt (GenTypeApp l r) c ks = gt l ((KArrow) KStar o c) $ gt r id ks -instance toString Kind where toString k = concat $ print k [] -instance print Kind + +numArr :: Kind -> Int +numArr KStar = 0 +numArr (l KArrow r) = inc (numArr l + numArr r) + +instance == Kind where - print KStar c = ["*":c] - print (l KArrow r) c = ["(":print l ["->":print r [")":c]]] + (==) KStar KStar = True + (==) (l1 KArrow r1) (l2 KArrow r2) = l1 == l2 && r1 == r2 + (==) _ _ = False +instance toString Kind where toString k = concat $ pr k False [] + + +pr :: Kind Bool [String] -> [String] +pr KStar _ c = ["*":c] +pr (l KArrow r) b c = [if b "(" "":pr l True ["->":pr r False [if b ")" "":c]]] instance isBuiltin String where diff --git a/gengen/Data/GenType/CParser.dcl b/gengen/src/GenType/CParser.dcl similarity index 82% rename from gengen/Data/GenType/CParser.dcl rename to gengen/src/GenType/CParser.dcl index 67db0f3..617594d 100644 --- a/gengen/Data/GenType/CParser.dcl +++ b/gengen/src/GenType/CParser.dcl @@ -1,7 +1,7 @@ -definition module Data.GenType.CParser +definition module GenType.CParser from Data.Either import :: Either -from Data.GenType import :: Type +from GenType import :: Type /** * Generate a single parser for a type. diff --git a/gengen/Data/GenType/CParser.icl b/gengen/src/GenType/CParser.icl similarity index 82% rename from gengen/Data/GenType/CParser.icl rename to gengen/src/GenType/CParser.icl index 130ee3d..0677604 100644 --- a/gengen/Data/GenType/CParser.icl +++ b/gengen/src/GenType/CParser.icl @@ -1,4 +1,4 @@ -implementation module Data.GenType.CParser +implementation module GenType.CParser import Control.Applicative import Control.Monad @@ -19,15 +19,15 @@ import StdEnv import qualified Text from Text import class Text(concat), instance Text String -import Data.GenType -import Data.GenType.CType +import GenType +import GenType.CType instance MonadFail (Either String) where fail s = Left s :: FPMonad :== WriterT [String] (ReaderT Int (Either String)) () indent c = liftT ask >>= \i->tell [createArray i '\t':c] -parsefun t = "parse_" +++ safe (typeName t) +parsefun t c = ["parse_", safe (typeName t):c] (<.>) infixr 6 (<.>) a b = a +++ "." +++ b @@ -42,14 +42,10 @@ tail = ["\treturn r;\n}\n"] parsenameimp t c def = def t [" {\n\t":ctypename t [" ", c, "\n\n"]] ctypename t c = [prefix t, safe (typeName t):c] -/** - * Generate a single parser for a type. - * This does not terminate for a recursive type - */ flatParser :: Type -> Either String ([String], [String]) flatParser t = tuple (parsedef [";\n"]) <$> runReaderT (execWriterT (tell (parsenameimp t "r;" \_->parsedef) >>| fpd t True "r" >>| tell tail)) 1 where - parsedef c = ctypename t [" ", parsefun t, "(uint8_t (*get)())":c] + parsedef c = ctypename t [" ":parsefun t ["(uint8_t (*get)())":c]] fpd :: Type Bool String -> FPMonad fpd (TyRef s) tl r = assign r (parsename s) @@ -65,7 +61,7 @@ where >>| result r "+=" "(int64_t)get()<<8" >>| result r "+=" "(int64_t)get()" BTChar = assign r "(char)get()" - BTReal = assign r "double" +// BTReal = assign r "double" BTBool = assign r "(bool)get()" t = fail $ "flatParse: there is no basic type for " +++ toString t fpd (TyArrow _ _) tl r = fail $ "flatParser: function cannot be serialized" @@ -100,12 +96,8 @@ where fmtField :: (String, Type) -> FPMonad fmtField (name, ty) = fpd ty False name -/** - * generate parsers for the types grouped by strongly connected components - */ :: TPMonad :== WriterT [String] (StateT TPState (Either String)) () :: TPState :== 'Data.Map'.Map String (String, Bool) -import Debug.Trace parsers :: [[Type]] -> Either String ([String], [String]) parsers ts = tuple (parsedefs ts) <$> evalStateT (execWriterT $ mapM_ parsergroup ts) 'Data.Map'.newMap where @@ -113,24 +105,20 @@ where parsedefs = foldr (\t c->parsedef t [";\n":c]) [] o flatten parsedef :: Type [String] -> [String] - parsedef t c - # (pt, _) = trace_stdout (parsefun t, toString $ genTypeKind $ typeGenType t) - = ctypename t [" *", /*parsefun */pt, "(uint8_t (*get)()",pd t, ")":c] + parsedef t c = ctypename t [" *":parsefun t ["(uint8_t (*get)()":pks (typeKind t) True [")":c]]] where - pd (TyBasic s) = "" - pd (TyUList _ _) = ", void *parse_0(uint8_t (*get)())" - pd (TyUMaybe _) = ", void *parse_0(uint8_t (*get)())" - pd (TyObject gtd _) = concat [", void *parse_" +++ toString i +++ "(uint8_t (*)())"\\i<-[0..gtd.gtd_arity-1]] - pd (TyRecord grd _) = concat [", void *parse_" +++ toString i +++ "(uint8_t (*)())"\\i<-[0..recordArity (trace_stdout grd.grd_type)-1]] -// pd (TyNewType _ _ _) = abort "not implemented yet\n" - pd t = abort $ "not implemented yet: " +++ toString t +++ "\n" - - recordArity :: GenType -> Int - recordArity (GenTypeCons _) = 0 - recordArity (GenTypeVar _) = 0 - recordArity (GenTypeApp _ _) = 0 - recordArity (GenTypeArrow _ (GenTypeApp _ _)) = 1 - recordArity (GenTypeArrow l r) = inc $ recordArity l + pks :: Kind Bool [String] -> [String] + pks k tl c = foldr (\(i, k) c->pd k tl i c) c $ zip2 [0..] $ typeArgs k + + pd :: Kind Bool Int [String] -> [String] + pd KStar tl i c = [", void *(*", if tl ("parse_"+++toString i) "", ")(uint8_t (*)())":c] + pd (l KArrow r) tl i c = + [ ", void *(*", if tl ("parse_"+++toString i) "", ")(uint8_t (*)()" + : pks l False $ pd r False (inc i) [")":c]] + + typeArgs :: Kind -> [Kind] + typeArgs KStar = [] + typeArgs (l KArrow r) = [l:typeArgs r] parsergroup :: [Type] -> TPMonad parsergroup ts @@ -145,7 +133,7 @@ where >>= tell parser :: Type -> TPMonad - parser t=:(TyRef s) = tell [parsefun t] + parser t=:(TyRef s) = tell $ parsefun t [] parser (TyBasic t) = case t of BTInt = tell ["\t*r = (Int)get()<<54;\n" diff --git a/gengen/Data/GenType/CType.dcl b/gengen/src/GenType/CType.dcl similarity index 89% rename from gengen/Data/GenType/CType.dcl rename to gengen/src/GenType/CType.dcl index ec6622f..2fb8ad3 100644 --- a/gengen/Data/GenType/CType.dcl +++ b/gengen/src/GenType/CType.dcl @@ -1,8 +1,8 @@ -definition module Data.GenType.CType +definition module GenType.CType from StdGeneric import :: GenericTypeDefDescriptor from Data.Either import :: Either -from Data.GenType import :: Type +from GenType import :: Type /** * generate typedefs for the types grouped by strongly connected components diff --git a/gengen/Data/GenType/CType.icl b/gengen/src/GenType/CType.icl similarity index 82% rename from gengen/Data/GenType/CType.icl rename to gengen/src/GenType/CType.icl index 4a5a63a..a569ab0 100644 --- a/gengen/Data/GenType/CType.icl +++ b/gengen/src/GenType/CType.icl @@ -1,4 +1,4 @@ -implementation module Data.GenType.CType +implementation module GenType.CType import Control.Applicative import Control.Monad @@ -10,7 +10,6 @@ import Control.Monad.Writer import Data.Either import Data.Func import Data.Functor -import Data.GenType import Data.List import qualified Data.Map from Data.Map import :: Map(..) @@ -20,6 +19,8 @@ import StdEnv import qualified Text from Text import class Text(concat), instance Text String +import GenType + instance MonadFail (Either String) where fail s = Left s safe :: String -> String @@ -105,29 +106,30 @@ where fmtField (name, ty) = ftd ty False >>| tell [" ", name, ";\n"] :: TDMonad :== WriterT [String] (StateT TDState (Either String)) () -:: TDState :== 'Data.Map'.Map String (String, Bool) +:: TDState :== ('Data.Map'.Map String (String, Bool), [String]) typedefs :: [[Type]] -> Either String [String] -typedefs ts = evalStateT (execWriterT (mapM_ typedefgroup ts)) 'Data.Map'.newMap +typedefs ts = (\(text, (_, enums))->enums ++ text) + <$> runStateT (execWriterT (mapM_ typedefgroup ts)) ('Data.Map'.newMap, []) where typedefgroup :: [Type] -> TDMonad typedefgroup ts - = liftT (modify ('Data.Map'.putList [(typeName ty, (prefix ty, False))\\ty<-ts])) + = liftT (modify (appFst $ 'Data.Map'.putList [(typeName ty, (prefix ty, False))\\ty<-ts])) >>| mapM_ (\x->printTypeName x >>| tell [";\n"]) (if (ts=:[_,_:_]) (map typeName ts) []) - >>| liftT (modify (flip (foldr $ 'Data.Map'.alter (fmap (fmap \_->True)) o typeName) ts)) + >>| liftT (modify (appFst $ flip (foldr $ 'Data.Map'.alter (fmap (fmap \_->True)) o typeName) ts)) >>| mapM_ (\t->typedef t >>| tell ["\n"]) ts printTypeName :: String -> TDMonad printTypeName tname - = liftT (gets (\s->maybe [safe tname, " "] (\(p, b)->[p, safe tname, if b " *" " "]) $ 'Data.Map'.get tname s)) + = liftT (gets $ maybe [safe tname, " "] (\(p, b)->[p, safe tname, if b " *" " "]) o 'Data.Map'.get tname o fst) >>= tell typedef :: Type -> TDMonad typedef (TyRef s) = printTypeName s typedef (TyBasic t) = case t of - BTInt = tell ["typedef uint64_t Int;\n"] - BTChar = tell ["typedef char Char;\n"] - BTReal = tell ["typedef double Real;\n"] - BTBool = tell ["typedef bool Bool;\n"] + BTInt = tell ["typedef uint64_t Int;"] + BTChar = tell ["typedef char Char;"] + BTReal = tell ["typedef double Real;"] + BTBool = tell ["typedef bool Bool;"] t = fail $ "basic type: " +++ toString t +++ " not implemented" typedef (TyArray _ a) = tell ["*"] >>| typedef a typedef t=:(TyNewType ti ci a) @@ -138,8 +140,8 @@ where >>| tell ["};\n"] //Enumeration typedef t=:(TyObject ti fs) - | and [t =: [] \\ (_, t)<-fs] = tell - [consName ti, " {", 'Text'.join ", " [safe ci.gcd_name\\(ci, _)<-fs], "};\n"] + | and [t =: [] \\ (_, t)<-fs] = enum ti fs >>| tell [";\n"] + //[consName ti, " {", 'Text'.join ", " [safe ci.gcd_name\\(ci, _)<-fs], "};\n"] //Single constructor, single field (box) typedef t=:(TyObject ti [(ci, [ty])]) = tydef ti.gtd_name ci.gcd_type //Single constructor @@ -149,9 +151,9 @@ where >>| tell ["};\n"] //Complex adt typedef t=:(TyObject ti fs) = tell - ["struct ", safe ti.gtd_name, " {\n" - , "\t", consName ti, " {", 'Text'.join ", " [safe ci.gcd_name\\(ci, _)<-fs], "} cons;\n" - , "\tstruct {\n"] + ["struct ", safe ti.gtd_name, " {\n\t"] + >>| enum ti fs >>| tell [" cons;\n\tstruct {\n"] + //, consName ti, " {", 'Text'.join ", " [safe ci.gcd_name\\(ci, _)<-fs], "} cons;\n" >>| mapM_ fmtCons fs >>| tell ["\t} data;\n};\n"] where @@ -163,6 +165,10 @@ where >>| tell ["\t\t} ", safe ci.gcd_name, ";\n"] typedef t = fail $ toString t +++ " not implemented" + enum :: GenericTypeDefDescriptor [(GenericConsDescriptor, [Type])] -> TDMonad + enum ti fs = liftT (modify (appSnd \xs->[consName ti, " {", 'Text'.join ", " [safe ci.gcd_name\\(ci, _)<-fs], "};\n":xs])) + >>| tell [consName ti] + tydef :: String GenType -> TDMonad tydef name (GenTypeArrow l r) = tell ["typedef "] >>| fmtField "" l >>| tell [safe name,";\n"] diff --git a/gengen/test.icl b/gengen/test.icl deleted file mode 100644 index 8d41f40..0000000 --- a/gengen/test.icl +++ /dev/null @@ -1,168 +0,0 @@ -module test - -import StdEnv, StdGeneric - -import Data.Func -import Data.Functor -import Data.List -import Data.Tuple -import Data.Bifunctor -import Data.Maybe -import Control.GenBimap -import Data.Either -import System.FilePath - -import Data.GenType -import Data.GenType.CType -import Data.GenType.CParser -import Text - -derive gType Either, T, R, Frac, Tr, Fix, Odd, Even, SR, List, Enum, NT, Blurp, EnumList, ER, CP, RA, Nest, MR, P - -:: P m = P (Tr m Int) | P2 (m Bool Bool) - -:: T a = T2 a Char -:: NT =: NT Int -:: SR = {f1 :: Int, f2 :: Bool, f3 :: Tr Either Bool, f4 :: Enum} -:: R a = {f1 :: ? (R a), f2 :: Bool, f3 :: T a, f4 :: Char -> Int, - f5 :: [([#Int], [#Int!], [!Int!], [!Int], [Int!])], - f6 :: ({!Int}, {R Bool}, {#Char}, {32#Int}),/*({!Int}, {#Char}, {R Bool})*/ - f7 :: {!Int}} -:: Tr m b= Tr (m Int b) | TrBork -:: Frac a = (/.) infixl 7 a a | Flurp -:: Fix f = Fix (f (Fix f)) - -:: List a = Cons a (List a) | Nil - -:: Blurp a = Blurp (List a) | Blorp - -:: EnumList = ECons Enum EnumList | ENil - -:: ER = {nat :: Int, bool :: Bool} -:: RA a = {a1 :: a, a2 :: Int} -:: MR m = {b1 :: m Int} - -:: CP = CLeft Int Bool | CRight Char Char - -////Start :: [String] -////Start = foldr (\i c->print i ["\n":c]) [] $ catMaybes $ map gTypeToType $ flattenGType $ unBox t -//:: Pair a b = Pair a b -//instance == (Pair a b) | == a where (==) (Pair a1 _) (Pair a2 _) = a1 == a2 -//instance < (Pair a b) | < a where (<) (Pair a1 _) (Pair a2 _) = a1 < a2 -:: Odd a = Odd (Even a) | OddBlurp -:: Even a = Even (Odd a) | EvenBlurp -:: Enum = A | B | C -includes = "#include \n#include \n" - -genFiles :: String (Box GType a) *World -> *World | gType{|*|} a -genFiles bn t w -// # tds = map (map gTypeToType) $ map (filter (not o isBasic)) $ flattenGType $ unBox t - # tds = map (map gTypeToType) $ flattenGType $ unBox t - # (ok, h, w) = fopen (bn <.> "h") FWriteText w - | not ok = abort ("Couldn't open: " +++ bn <.> "h") - # (ok, c, w) = fopen (bn <.> "c") FWriteText w - | not ok = abort ("Couldn't open: " +++ bn <.> "c") - # h = h <<< "#ifndef " <<< toUpperCase bn <<< "_H\n" - <<< "#define " <<< toUpperCase bn <<< "_H\n" - <<< includes - # c = c <<< includes - <<< "#include \n" - <<< "#include \"" <<< (bn <.> "h") <<< "\"\n\n" - # h = case typedefs tds of - Left e = abort ("Couldn't generate typedef: " +++ e) - Right d = foldl (<<<) h d - # (h, c) = case parsers tds of - Left e = abort ("Couldn't generate parser: " +++ e) - Right (hd, cd) = (foldl (<<<) h hd, foldl (<<<) c cd) - # h = h <<< "\n#endif" - # (ok, w) = fclose h w - | not ok = abort ("Couldn't close: " +++ bn <.> "h") - # (ok, w) = fclose c w - | not ok = abort ("Couldn't close: " +++ bn <.> "c") - = w - -genFilesFlat :: String (Box GType a) *World -> *World | gType{|*|} a -genFilesFlat bn t w - # ty = gTypeToType (unBox t) - # (ok, h, w) = fopen (bn <.> "h") FWriteText w - | not ok = abort ("Couldn't open: " +++ bn <.> "h") - # (ok, c, w) = fopen (bn <.> "c") FWriteText w - | not ok = abort ("Couldn't open: " +++ bn <.> "c") - # h = h <<< "#ifndef " <<< toUpperCase bn <<< "_H\n" - <<< "#define " <<< toUpperCase bn <<< "_H\n" - <<< includes - # c = c <<< includes - <<< "#include \"" <<< (bn <.> "h") <<< "\"\n\n" - # h = case flatTypedef ty of - Left e = abort ("Couldn't generate typedef: " +++ e) - Right d = foldl (<<<) h d - # (h, c) = case flatParser ty of - Left e = abort ("Couldn't generate parser: " +++ e) - Right (hd, cd) = (foldl (<<<) h hd, foldl (<<<) c cd) - # h = h <<< "\n#endif" - # (ok, w) = fclose h w - | not ok = abort ("Couldn't close: " +++ bn <.> "h") - # (ok, w) = fclose c w - | not ok = abort ("Couldn't close: " +++ bn <.> "c") - = w - -Start w = foldr ($) w - [ genFiles "maybeInt" maybeInt - , genFiles "eitherIntChar" eitherIntChar - , genFiles "eitherIntMaybeChar" eitherIntMaybeChar - , genFiles "cp" cp - , genFiles "raint" raInt - , genFiles "lmint" lmInt - , genFiles "trEitherInt" trEitherInt - , genFiles "mrMaybe" mrMaybe - , genFiles "pEither" pEither - ] -// ( flatTypedef $ gTypeToType $ unBox t -// , typedefs $ map (map gTypeToType) $ map (filter (not o isBasic)) $ flattenGType $ unBox t -// , flatParser $ gTypeToType $ unBox t -// , parsers $ map (map gTypeToType) $ map (filter (not o isBasic)) $ flattenGType $ unBox t -where - maybeInt :: Box GType (?Int) - maybeInt = gType{|*|} - - eitherIntChar :: Box GType (Either Int Char) - eitherIntChar = gType{|*|} - - eitherIntMaybeChar :: Box GType (Either Int (?Char)) - eitherIntMaybeChar = gType{|*|} - - cp :: Box GType CP - cp = gType{|*|} - - raInt :: Box GType (RA Int) - raInt = gType{|*|} - - lmInt :: Box GType [?Int] - lmInt = gType{|*|} - - trEitherInt :: Box GType (Tr Either Int) - trEitherInt = gType{|*|} - - mrMaybe :: Box GType (MR ?) - mrMaybe = gType{|*|} - - pEither :: Box GType (P Either) - pEither = gType{|*|} - -//Start = typedefs //$ (\x->[[gTypeToType x]]) -// $ map (/*filter (not o isBuiltin) o*/ catMaybes o map gTypeToType) -// $ (\x->[[x]]) -// $ map (map gTypeToType) -// $ map (filter (not o isBasic)) -// $ flattenGType -// $ unBox t - -:: Nest m = Nest (m (m (m Int))) | NestBlurp - -//t :: Box GType (?# Int) -//t :: Box GType (Maybe [Maybe (Either Bool String)]) -//t :: Box GType ([SR], Enum, T Int, NT, Blurp Int) -//t :: Box GType [EnumList] -t :: Box GType (Nest ?, Tr Either (?(Int, Enum))) -//t :: Box GType (Odd Int, (), [Either (R (T *World)) (Frac Real)], Tr Either Bool, Fix Maybe) -t = gType{|*|} -- 2.20.1