From a2b14efb19d37e66b87a208899b696863eaae0c0 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Fri, 12 Jan 2024 12:03:48 +0100 Subject: [PATCH 1/5] Etherlink: update changelog for version 9978f3a5f --- etherlink/CHANGES_KERNEL.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/etherlink/CHANGES_KERNEL.md b/etherlink/CHANGES_KERNEL.md index c3f48bbba3dc..9a63739ad69b 100644 --- a/etherlink/CHANGES_KERNEL.md +++ b/etherlink/CHANGES_KERNEL.md @@ -4,6 +4,16 @@ ### Features +### Bug fixes + +### Breaking changes + +### Internal + +## Version 9978f3a5f8bee0be78686c5c568109d2e6148f13 + +### Features + - Fix contract code storage cost (!10356) - Fix contract creation gas cost and transaction data cost. (!10349) - Implementation of EIP-3541, new code starting with the 0xEF byte cannot be -- GitLab From 1c005b9a0e0d4685e983221930c8254396708b0c Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Fri, 12 Jan 2024 12:13:49 +0100 Subject: [PATCH 2/5] Etherlink: update ghostnet compiled version --- .../tests/resources/ghostnet_evm_kernel.wasm | Bin 1817516 -> 1843782 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/etherlink/kernel_evm/kernel/tests/resources/ghostnet_evm_kernel.wasm b/etherlink/kernel_evm/kernel/tests/resources/ghostnet_evm_kernel.wasm index 06d7f7c87951d45a6771b25457a94c50ec21318e..a30b36302e7048371744ec89df2c0afa050f127f 100755 GIT binary patch delta 258358 zcmZ4UJ@43&0%L~6;#@`s1_s7y%mxXZ^)SGYzz$_HB(Q*33<-?&3<*s2b&T~BjeG4F z>ly14*gz6>AQl&h1;Gpn42<;%lj;}}_#hJX_4Rdi_4RcO2@D(mtYWG^&vTZCiJgy+ zorzySfRB$^P>7F_nU9Z|Q&@yah>wq1h>2N~6$`Iwl*S^4-twt)Cdd`wJC zOspWY+1Z(yK^#6-Rz5yHCXiKpeC+I8U^$R;L3Z=8N;2^=F*AaI6caNmD?0-#2=MW7 zaIn@hGqLl5&0=O|<>Th#W@MIT0=o&M1Y#f`A2Z0iOnjUmCou7Gg6v=h$%BkwXXj$# zV`T?a-dD!{5K@rBv%E~NT5908#@`@6^WM$=J zXBP)?A*RWSgVaK8VPyrS29OF?R#tg=Xo6s3=5Ok00YG)Gb?+& zA}cF1AIKyoRwgEpyTN)P!O03z&(6*+&d$sVN_gOyVr6G%0wn}iR*+-4pk}dx0uZ7d zk~+c3mz|Y~or#H!6_lj;n3$EA!0v=719_B{ubzXCjfs_&PZneqD>$7oF@a)~of(u? z*gEOa9*z#e1; zr5a{XIB+sCF@h2;D@cfyPh4D_6BO#8NMVP16GX8xPkzg;QqRoE35r-&kV23$CO#%s zP*jPtvvRSD^MMj02QxD>A2TZ}6F34vu?0%u?4Vc&l_KnXpnzuw=X5!c3?DcN%W`w^ zajC0wacS`I@NjW4fs+O(>$8HgB_|m0@lEdMV6O+|M6OpEx@xy7*XGnOT`Z zCbF`#atd&Aaj`P;fn37JCk{!2e0)sxe5~TEpwbAG#@M+yI5@z`i%$wv0kVFL0MGbkx>fmrNZ>>NydJbZlYpj5=l$j;8m zCC(+z$0e=~vWcCKore>YKgF3ewYasJcrWgCisN8I~n1HlMlwa(rZMU_QcQ zZf&)U#q1bQT03JK=XRdsjL#TPa(!m}!uXZ(8{>DzYaB-zyP1wL?&dkjbcX2^(`lxg zTqhWpvSha~KVw?Rl68df08{3ErUfjA85gr;JYjmk^qBE6Q#12Jrl(9BST?e(Twgg`nI|*vVm-~em-QsmA*Lft$C>6ZH?aI+Ud6nPc^>m>=6_6& znBFkGXL`Z(mT5Zkf2P+=ADCV;y<&RDG?#fIQy)_^Q#(@wQzKI=(-+RqoF|wLGaY3* z#`Ko;9cx}ePHz4r)~T$0ti8-#%-zgA%)glbGcRY}&OCvszMrX$=|5u=Qw!5?=B3QL zng24cWZuazL;=uVKE=`IPe>=W3P}EGt=7u}o!dXK7|x#Jrz*8gn;G zBg-=89n38(9V|in2#`DV}8#3nfVIy zN#?uEPnf?jUt~VRe4Y6N^C#x>%qN&1Grwp4$b5?V7V|sibIhliZ!*7SzRY}(`8M-+ z<{!+*nC~+`Wj@6Gi1``wapoJ$ZtfcOtoK+ivtD7n%i6=bfpsnG zI@a~9&sp!YK4g8u`iT1__hZ&)tPfZpu|8$p&$@?oAL}yK6|75Gm$EKroy~fi^%Cn% z)*Y;iSZ}d*vUal`VBO6+fwh;lpY;{%`()OatVh{qvwdPc$#$CU1luXLnQZ&nI@r3| zI@!9|4znF&o6B~b?FidEwnJ=jcixg-m~3cyU+HC?HSuO zwySKH*}kx?W?#j=fqgyuI`%c}YuT@|zvh_i!z-bFh~p9aWA-QPPuZWbKWBfz{*wI_ z`)l?$>~GoMvA<{k#QvH63;PH5kCQujed}j)%;A{JF^^+D#{!Op9E&&>b1dOl%CU@N zImZf)l^m-$R&%W3Sj(}FV?DQtjbl5<4vw81yEt}p?BUqUv5#Xv z#{rIm9H%)>a9roO%5jq86vrIS=NvCM=5o&F+{1Z|^DyUe&SRWMIS+7t;(Wn5jcYpB z6t1aUGwQi!a<%cy4)wsP&{I?A<&YZupUuESi1xOQ-@ zL%-0QecaPQ(iz`d7yKle87&D`6$cXJ=) z-pIXydk^;+?z7zIxX*KM;@--=h5H)!E$-{wH@Po!U**2SZU2hoFlPpNasneLfRK3{Sx)s3Ns#CSMyQn_??A$90%MlI<|eSO zK;fm!kfFp3w%Q`gQ3B+wM#d~n28a=k79islSR8*cpooD3_9H?}fkl%c)127?5+e17 z8L||>Zf9UnU{PSvWXdsTu;vEYroj}W1PK-mrU(TlM@9i?Sb?0t0E!$7a|Q+l28c_* zF4AOXfCveI90zs~TnOwAa706eSTvY)l(d;$d6_^#s-eIPvw??+8ziEm#0-uU4JN4E zOdvbwb3oAG&O%90BnVdGom}z>;W%2C(=&9QR?0!cHP@)Daa^wJ|UvS<4hu>sJ5fLsnSbF|2IYC^a9w`+U zK=l7$$TDSOP-KV1*bfG98fFItQHdfWG^%9aQ6+&KRgi3;z;4dOqrjrTXvV|=ai;QwyC5aCVXbIXwi3x141jtkc7RQJ6h?EKnIB-I`i7Ez8Nf!}fpcL(C&MW~5ALT3s zu)AUD*~gqg8X8D8N|5l-V6sqPgrzoa1&|BC=~=>@fuSCjpusMJCRGMd$;JY44_pZB z3~<~+g;+G0c$65R>6t@;0cHa=UqF}{% zY4Uyrb;fg(pDS!)Ki}Taz##B+^8!UpM&7&K4Gjzo+>RoSECP2oUsI}OWSY}7IaDQq zX=T&o?JAm#mnJ_{F=U$6x>-auiIMTpkbo7M9fFHTn0FlRhAIa(tMlzX>pC@>zH zd_zN@@z7)r%_zoYlan?3WVV6IKLs`orT`^oM;3QpMg=xqh7evRQ20*f)jG>Gvvu+v ztt6%mO_Lq8O+mbJZ8OG0lh=15{5#Z=y1hJseGr2%#D&w)qY`Uo+ z2juF4ijPgYYD_zuCg0LEWIQyPM=uW=Y)>XP>J>0vn*2#Go$<`%DE*I&hbH?NcrqTE zJk3Cb@zCVm1{QF(q~U7DLz9mhg8cK$P?_=2WG*8Rsb{o?@zCVkMhe0ZH*s(0Vg*&C zjP;CljFZ`nZR!~{m{gRwG?@z&xxrN)E2PL!;^Ad*Vo>A-1t+Tp6N4g$0*@nep(39G zmnL%qqar(qu25tH>)~;%&vIn;N9f>jtSMCF0qJLUP+(VJQ{d2LV3vllnBXi%=}?#; zgR}x~O-)UWBCi66BTE+8zM3qMGq|}G_*{7z5GH|@g4HpC)bTmiXDRXVGH`P%a4Ik= z@G5ZEEcP{KRP<0_P~fm)VBl6@b%dk`4p&}A1(0u`2`JA*i;-{gOp|Ghe3K1Ky%{fU zt}zv6WW2h0f|(y98>OVA5pfFlXjaV0L6MW7@%_!0dQ} zDGO|uz$Q?$L4nz^{sv=~0;2-6;|{RQ38pN8HK68`0<$i|0wyIUM<#b(W(8(YtHx0Q zr1u6R$f26d3`!gjH-Z`v5-=ICiCAK$;mGnXDK*ApV;V@&perw*r%+ z2`HN@g2KxH%wh+X#3D+(;EJ-I0hBOU9U0wuS;5Ja(Gjdl2`t2*z~pF=r3i`u)+|Ln zr~(a;F-rUzOd8U)Ct_Ycew^@H;Ai6iO>{aD&s6qJRRQE(3$2 zpd+N7Hpp^hFcW2BP~g{P2vOn#g*3>^AU{m*wpOZVbLHg$C45jZ25JuS@Ng?Yy~v=z z3aT_292w1+SQHo>*{v8Dc(_2x2o#_!=%8hz^~5`YR#|~lr}iB6nH^FBOve`6nOPa4xmK9;mGF33(~<1PD~R( zX~h5(b)Z(@3`i={WiU`;b>w#EW#?94P!KR>XMnATD%D_`0;&o` za$u3i4T^L~6j^|}BNiYlL9S<3U~)9b(qv*VXEsn^2BqK|j0y}2j0*M4j^J>B)U~=REnXky^$e_p$$^Ivp6!;Z+ znH&_@TzMfK9adfjM@C5djn%Q9EGfwiFYj-0m`coZ1w75L2 z!xTWN4wSvXg)?=^Lqu^{56UCVpo~FTc?gYi1%6Pgh)sbXo+4pIBPhvofm5Ld6R6_^ z?NQZ3QY*MS3ob;E!VVPZpuQj^(5Vs|Oz5$}0V@1iG?^Kuo0PI^gK{IdJOH^6R766e zfdN#yfU_y2=3`tQi@2m_a2YvnGR~IRmJW2PYi^a81epZfG+& zN`g|8L6)N=w2V?8b?m?Q< z;A{5!0oDiR zQeX!aBB0I@hoeB25;t_<2O`RmrNH6Hk)^}~s!o_06xbCwz^n<33ha(MSimJ4LI+5I zBTE5Uu_$O{V+V@@yW7>5lNps<9EnSgsr>k$0e`>+|dD9$ifQ_B5?Z;;%`K&6zpindI@NNAX=sn2?3Zm zxP1gF*udd%fW@5o0HY(fA~Pr%u{&O80d>*}5*mW6pFe)-bLt_q$62#}A*n%|kK~)~N0=uIEs5z>{ zp}_8V5I%?n76m0F1$M`isG<^CN<0eeju#=K^`P_wGD1E}2^3{FAi^LIDX?oY>|``& zRscDUCCgEs7@sOIgBl}Be2zTspgaW$OL>sbK_caFM|TN z0*3-Kqy2?~<~Ae%baKt0!1b7l|^BzgiQIsqmM;(r=Y^F$@~B$yaFZ+;(-*u0Eun@i%#C@^SB;V9SK|kjgEoB zSd$r)GczDeP{~;UVV+LUftw&Uq?86_IR?iIh_vI_$eabK zaY6aWu@l4twa*~U8+ONuU;*%CO}!ad$yDYnP*dI%k`?EIc#gKjCs^8G z2Md#f0&EZmJXOQ!2pO;e^+j(m+j#SU_WG;G86|5LBo^ z%IX~~O3a|D57c#Gux14H4KzVxKj480MQB3+)B$i}FrQo%p$_hOF*tH&foi;+ETB}& z0GjUuS47aNn88sIRMdeSj?`h0goz2lk}kLt0ScTfM?{YSRDFSmn$4IPK>a8l1ul2c z&?q?MM6&8Nm>86xty0H&@Wh3R5{CxU21b8yC3OMZ^a6*z5)VB5PryVuvXnSsHH+gN z&_o_IgEN6@xF=u%a0UlA+d$1F@SFvrgpmV@fu~rIk_NaoQvl6&OkUxyS`TaNgQ`hT zAP8hBAe;gc;K)*dy8@J+IH2hX)Sm^12V}|@REvS8WkE$Rq(K3xpV3^xnV#VaZo6qP&0$gEaph$NiOpb9;DL3$cvwMNK0xNr z!0q-NMIKPX0qfud+XHT=a>8_QEAZ62@`4)dyyi@67!}wRc+8kqz!D(4Bd7}J7T5=B zxPx2_F>414IPO4x1h)=AVFVtx02k`uP6{|vfy5zAA8;)IQV%QSA)}jM_4S}21?7Hl zg9nt05sfVn577_<@nExWpf(b72E6A4l2U-=I!6X~MILb5K!II@;UJ3{6R1C?!0rfY z;4?6oF-!(|?*L1d5+`T~l?U9@+QXv61)h5W1t6qB0P#Aw&q6D&gMD7l0&0gs$~gFB zI;6%W$LpL#d7TU7bxu(F*;CJ=#0T{{k0WEDA`hsHDpcfz#Pu3RB`#>XS;45lg_Ld- zIExf{z$p$C&XXC<7$$?#5xWM{1V%Ha2`r$VrUt`g7I4+8z-h&>2PDl0Y1@Hpp1@+p zu$Kkg(||V=!CfrS2nRb3LqTqa8_EMUlncX9aKQ;GWm&QWAZ9XwM!cD=z~gTgpdu4I zKxL5SG`S~&Ymz*BJx7)!c-VshG{eCF8OiBjbiC7Wpn*Z)J!J3$9wv}Hs{zU?@Z84@ zYJ2ZsRN?^@&`coCPDVu@ZUr7t&x@A{l(Ils0Cfooqfy$N@)gKHaD4^xKcu#D;{{byG^>K@!BZCupn-oY z1`bf#VF2YTPzx7UF)2XnJWzoIFQ~vXLg3;X(S!xh4MD`<^#ypA2qFfnS3nI?21hPX zrOLRgp3$5UR2>U}D@?{LN3JYQMh1wO6iiGAA*KWqlR}7TfW$yue3(X1Xz4QSWCV37 z7!-Iw!`={Yf^s*5BO@dogI5tveyya;$TpcTNLma$76u+FgOpg{sc+C+xp+Nf$Pv_0 z639{jjY>k&6+{JS#6pQ1G+D_FO8f!}+)j+4Fcxi+7>jF1nN2>4W)xa zMS)oXl(a$8;EG*=LxX7xqrf>xX9F~L1)6~XD;1atPEqXOWj>&k#tcd&IpF*ON|~S{ z7ore4k>3Gb83f698yMkZEh`v7lNRq8-M|$hsLD}bRNz?abb_%?U@FKGkPcmj87z(h zps4_MKgYx1G6s|ZA+ZQ*@q^OI3>I^S-Jo$)R#0>@fV$wI*yIJp2q?`%Ml`_fD-n>` zamFkShRGEXa-cE;DIP#+0+N}rml^0_7_#c2?Q2l03Dj=S1PytCX19O z?n=C%NCFK@FzjYj;x}iQ4JwUAvJ}8N7#u+pZXgv53jF5a%26_FvR_1)0H^|hyPH9Q zdGeNsRAIOvD92A=2MxGSZ(Pj$iVa-yaBufFWHe`#g^V*WI(9H-DKRR5<^j05x!18U zgBOBKztGAh#>SDQz$9>NvPVq5>@7&+5;Q^`pu`B8I&}o~3Yc{nLIhqPw%us0tBxz6y2%5TizyR`7Lj%L)^ysbpU|;cbbDv{o0xe*fo_~``q8>CEzzkX= z2kEu3g8F`-!3)q53s8@WnL&XSG|IpLS|Z5`ns{YYU{U}p6IcdH2%xfAffY2-4eiRY zf;uVOpkmnuG}Q`;OIAk#P)VV{4C>mjf~Jg2l-SG}lrt1q71+#~1r%5nKuQ!CLCfSA zl$gN_-ZYpP1ol9}lgR#sRVmzETflI5T+8m_Y&LUPyz9 zdwPL7vlwjkC<}B&3j?TsL&p68P|Q znwt-ktrD^s&re>KAkTPc^09<;o&_AN%+QG-#>s|>(8Wibn#>uBT;Ny$EfNIvP`SaY zFTlM9khzK+3f!Q@N4%hZUjw5e8;Gt@gske|Mp}FX*1_#qQ>e)8#GuH-?4ZD=zzSV_ z1Z6Qv!^9Y+BVkMiX$2ne;v*i|;v;Uynk>+?4L7#}FJ$o%R6kg$B1j#0@ewa*jR`NP zhpoWwxBCWKmz#)GBYuGc9M=HFDS6VMGF&{1sX+u$dIML zyZJ%VJjTf(aVm_*CRfJQ%D^%viw2VhbP*$HrLZo8j=<~5LhZf&ScuwG?_gu0Hl6R zodjqpSzWQ`==#T=lBS>5VGz$t6 zhc~7n;sP*nP)l&S*>QG0Wr%)A`vJTvidmC+2BSH%1E}!{GE898pp?uFDm}Oy85FpsmAD)y8}!Q7gQhmYa)MYs`C@@MZv4E;IW>AWE1g}0)ViouVs&+s% zDvuJIBdFU@0a{VStieq!SkP|x?p>8?@R$8wBDyYDk5Y7UPL9!{Z3akVh!lJsS7dvK_krcdQhhqY`g-qBPYle zEZhn#uDonKV3XH?CM`i(joER@1h5`ZPXN?I24#51D-bbo{ssAN#zfG7(Hls|Kmp_i zNcj%Re+r-$IjC_176vcVIRI+!V+lWyaxCEo5=IR_M{@>v=rMu(cYq-a5-^~M6aa-8 zWFaCqxU&onIEahD5v$3}paB|(g@}V|90Abm9!ebv3S38lEO33J2zEPaB`APV2g-oW zgOuwEpvqg31vE4RV(~Igmdnpc1}~KYc}D@Xh!JU}GDu7UB!*V+fCtWyDrry-1r0~R zTnb&Ij8++IAvpw;C_qb3Ky3&`R@nOU|BQuv%q)y743m!*`0Km!f>)3*If551ftDkI z)nK!F*Q z>{vjnuR*B{k|-~Lm;&$w2U_MA0g6!u1!jR6t&@{WLKzQD-dW0_Xi4O zDb%w$-heGWg_xHDN)n*%i~uyFaw~xL$S^s8IzVRNh06?POgah-PArfW&Fs+V1UnbB z=$Q%30xgDyuWSZYfQ}5-;GswbP}5Za6q;sCu>C%unjEYP)Efk^8|Hv2-~p9(j(-@S zgW@c(Qm#UQ1(e!yKwF$ZNemK1pm7V-6bD|P4IOF)#T0l2IU{J1B8w)2pm{xPl_CqM zM++|jL6ejUU?F(n2cBRA3&9IM@K_UA2wvzhfLAAi25Ufz6+ulE5C)ZX41CPYjLZy> ze9a8%Conn|WYsG%ID%3RXe~C2r!;7=k&l^$1vI_`3KK;JP^N>FkbK}Kiz7#tB6tHP z$OupY0ICE*V%!Q0pr#ABVZ?yw5QA1&!?!|lg9|&*dPdMHMwToMCPxO)SOjQH3u#9d zi(>;Lbfkg%Dl;QSBW&!Nki1Do>Hz4VQr| zmsDVI6ag*0gm?f+5)?CzGN8DJxQhugKmtncpyoGdO+3f~h%YsmR1`r9baI#!8K(>W zWt3!NEdfmeP0wD;q{w(^dhcQ;nM6p&1uubT&|p$gU~<&Sab$sv5P;3pU^0O04P$^b z198|4Z4iMCVsbRdQDg*#xQ(OAbiTiga<XkVm)Idg#mv!e#6qD9?&qXAwu%ESvP*g*N7 z*->NqflcfZ5gH1ht}JM=B1oseN7&#vsK94%VhjQgoq=4}z$EY=BB=mM;Yy(T0<iC}#v>0%5ps&t;UR}CO>ZV5`j$5ffhA8%9(*y%RByVn(Wx7FAFYOxk1hSHH?sW zWdTpPfj8<-?rk$wH)q<~H2F@uDpO0#WabV{#zT{JJBpa@ zH&0&J5g@kaU;}tw91>8VJj>=dW6fmt&L*arO_RGjRTwW#-q5*^@zUh{E)c2LeTnhV zWX7IDj5j79>3PAlzh&~eURw!p8U&4caXOv=jW>W+J}a;ate(u=S0@YE2?d@&lu=*+ z6`mproQ?`v;Kst_#w5^wy|sN#jF%>V=+hU0RQU>=prSwlY@EQg$;SOpnFLl$mYGn& zxOMW>3A-3qPY#$Ez<6o%!igS?Aepz5)R^vr+#)mCaB?STTi)a;lHcjT38V%Ve z>}fZ9g{5Mlj%#}F)1@Xn||^glNRI0>0jP4+49Z-xkG^o zR2&K1nQr%&OS#JyFlGbP))<+0II4aK+_wbZ~)Isfy*M$dKJ(*2?hlw1ttv!Su+M+ z5KEUq2DAx>2{a$a3Tm_y+DtvMMqwFvWn!+7(&AR`G(@ zXFGx-h0&1%w9yqj;0xNO2+{>AofH@xxk0U3CQy3~ywjKo)Tx74ub{dbqDhxQX1eA_ zCL?9=mRAOl1>iOaG{u36e^>=uH2r-qt7Oz4NT~(#H>kG>?v-mWu?YMEITuuufI7dR ztj*xa3fT+CkpJHTDH^>rL0&xZ?dznCrWo8W~1LO_gpb-~ECXfPf z(+AXi5&*4cW7c5e5I7Ig?#QGFT3g4g!6d*7Y8f$WGE0DVmx7upkS;T*pJxU>_W?Zr z&J1chf(BwiLXO;upvgMWm>dJ>Tni>}3WU$hO@FD+EK?8d2}7f(pOq25Z}tKca&-Hq}Uw~@06O5qEDj?QLa0?4m5rTIdf*Q|?S)i?T;ASH;s1iVg8Z2umFl*E^ zoq$$apg|6%GmPd;TR@v6nar3rfObgk0978KB*^Tzfe9s0w=ls&bpxpD3H28@C_MKt zf({A+v34+mQ!Jw*izBNdD=1rl4Fc`I)nGcnC{Vu$R9t{Mil8$@z;^T^oTtlhf>8;y zaR(F;pd=3(7GpTWXvVMwG#1FL!Eln%jA0`v<}QFYDuT*U$14yfXhYNu2otm+5VS0h z+3^lzmg9L?H;0?ap&k@5pjsAOTZ0NvP(u)8r2@Mm6Ue=w={JUrjAr2O0SoA$6NW8} zpjk|2M_y3>HGr7@2qA_XFxQI8Pf@n|F3|Gn{3% zX1oI~$}TV~vVy#Gg;|jeMBiWrZ-)gHAIy$-n6n(GFhYl@K?$9y9uzsCE%>nP3tkWl z@-|ZX*Jr%LWX+%p+M~*l<*1RR1S%OoZbb?M&>1}7-TV;mA%y}+Mj}fIG+hJIgA@)o zKx2vmS>S;HVGEboZE0g5m)aXcC**u?3t7PB5b80&s{z z1hX73!1EGlqc%f5WZyOeXx}!g8H0fWgQE?|f)*4r!0WO=V}hXg1~140?a~CTHv-oL z9H0nf0+qP}&?UHF4hLu(5i@9eCTQLbbc7OExB=`)4v16gL2X1S(C%kY_F(3QrA}BG zfYnE!W06*X=5yH0n3jNORx_prpib8sW=yw(Qy)?(z+%Oq1KMB?S_sX^tprLVOPG;L z0VH`)DbT<=z3d~C7PK8W1=085eyH8AZOdXxm>pn3_Gai~g>l0Hy)4qo7 z+Mk(J7#R;u5BS1#f(KezJ8EPJ+?lTOmC2H6N#peRuV4+;Uzv=BAyojA;{z7ZXzBru zEP>tA4}N8uAqMGrfYK?rm(L0r0hpfujVYV)()8Qkm?Rl5P5=6hNrUmybh+>+QQ5lOd8;-2Rxz$swm%2 z7x={_%MNR^oBU$ZVLUWF@fVW>+>{GoQ`&wp=_5>$0A*gt$_2bfA3_-n^-%Oy+%(~x9nN0f{rc3@|3gSJ{1L|vl+xP;vr&s)83X*yPsb@i* za1L|k2cW8h+3^8mmcZlb_MFV3(|`V9k~Dy9gJ*Z;Wd&_KVpU*+6cwNq1)y|dqQnj= zF2L<5cJSzm(_bb7wTqx)6D0qDQHd42aSyV`d?VOOP+4J+C9rGyjK543jN7LR{$rBl z2e)OxA+`XtduF=jKPDN*L({|lF$FOmn!fTM({5haK3+BjPJz4A3;%=DOD}|4`Jc(c zbqT1?ComP1fk16#$W$N5M}I*rbnqy{7RD^cCQ#J`%D2pp3mCH;d9oav5h5*9)tIf7 zXLN$6OQ3w=v-2g6jK}J5AZp*?f!+2=wLS}VU(5xYNNh7!z-oRwe462bG zTOr1R=d12?Onu92#I&Six*{X9g4`3(EDLC5lm^okSaVB*=>n)j!YFWPdORbuqQg&6 zXn{Ne3S#6E8QRz2VdZw*1M;$?xdOy1U%zSBO zF}6*wVrEu%zXHm&W=snpk-mW`%ZzCQ$bSdG{sYAT*ntYnjy;T7;7L)4_fWhvr(^mH zW{96;SeO+UVL>uIiiKHG4Ug+V6&@p`w41(=g*gzC0UXbO0$t$t^#3f(#_S70t!+id z>Ho}_#X#i-E3=F!q+!Ac-a-vp5zGosagD6Z24Yu0dL8)%K7hhZff-c!G70>gew>v# zjq&?*JvL?!XsH8gj|<$H-o(aiWev}&9H305zziDCfOoeafR4ojEr^2jx51M!jtcNT z_jfjCEyhFBmDrj67!OS^WM?*m`r-%3B?7mnZ((OPw};q(+A&sucIh1%6hYB#kOis> zK)pa7a7R=gwEGcON@#H~gL?MC9LyR54PD?g3F@#IWC?6-ncmI8Yz)oVUqIPg;P&*> z9L!M!GPa&DBu}%s@`5HKKqvGGT$#_7kon2kY$4S%@6sX~^US)K9ObXRU>J;smI zOSqYRdG~+{SOsR#E)9V@)6a1;XE7d{Zpp(8D!0OUn1lHdC51wkz{IxcJ9(JP8MjY2 zyMccX9ch*unXLsz8a$B7(cTG+^?(xD1LPp zU^W2xwNe1=*I5E!zaA1`)@A%S{eu9r5APkQUw<%w>IhFk<_yUBTcBEu8FZ2#cy@;w zbdn$Vw65vr1ev{&0ze>3U{c$34Iyv6ay$mE?LrQ3hV7p}_1Yk!8jNI#5Xi)RMBu5_mFQ zSc=)0{TZkPS74g#H$|M+0z4$H!0c#|CGc^2p%k+h&!$aJn@`XL!+V@^oph#4}HVaT+&ak`-_xES}9 zWp-mcw0(*!GaDmFb)zn`@bvX^%mz#s8>T;$W7cH4&@i1xp4p%2Ys2(dd1gb#OVj)1 zK}mo5c6nwCrXLN{Kgu(UgJ>=VW;v!G4coO8nC~${m%vUpRALeq1g|k-1r>w}j0&s* ze;cM7DKQ@enfz6W*$Yy{DX@ZO2L$d+_fcjxVp`fby+Il5z&XmyYG^9XD>Iuj&4;T{ zQDIg^Q{kh`Y&cDYnGH$RY87TzG*y39m~D_$gsU=}f`(W7RGHO8A;lD^E(O(-{E(v^ zrk_-02DScPsWP7hsobf?EW>zd`ZYE1@b5P@W+lc$(mH` z(PUO(JT(2HCbJPJ%2>6SotXYMO!w4cR)VF8?L}J5LX7at)~yZC0j!Qq(@$tKt1xZo zp8igoS)TF9bUqz$nWd@2tgH-gbbyz^27u0hWQEnwM;H}Y9q)8Z&(~qr2emmC=zz5! zfM~z1!z?F)Qa^(#B2d2P)n!hD2R&%D@}21oy37uY@24NsWfo_AKmDdIvmCtj`A-*I z2Wsjudo!JHm|mvG91Pd|09@K#(__}PgH(d7pwVGA@D2_IR?vwZ(3%#Um>`o88caNn z432j|Z4*aEcuni554I&opIIF=B7N^WtN8Ra`phy&F{T5Wwq#deMKt3d>obQi9-3}p zzX6DD)KdkS2)A;2v<0&|sO)XAU^Zg>K7G3dvpM6T>F+I=ZI!^T zPz3Fb2BrBOpk_Na%yEjG3OoYer~6ql%L)Df2RLXr8FX5%!1spfwU*4DLUX|00ttiq z6C5D%8M!(0%$=S z=%5jB+g{-P^m|s!i2fs!HQ2+t*39ydJm&~@oWSkrk=D$*2vY>Wrho@LAi*}@8p)Ky z5L4b+GuJ^|l6OFU5x70Q(uO%m0@6ifRDi72P*7l0U<6GHKA!&Ah8fn5WC6D$!J~2l zm!_-OGTSg7nx1IOtPk(6fm$hdr_Z%z)?hq7{g^GYBh&7t>6~`VDxj98z8$k9)0U>~ zUUtlUjEsk-N7{pn<{EqEEKp>LlHs-s{FJJ$r?z(w3z7iM!r)1R3ev@{rWsNMAMF3cvX(D_wRVFa0Y;77ED zSwU@KP-|zpzB{wD*cFf~9EG8o7_^Q}fl;7odV)K%qz$BH3K>&TU;rJ}&E%+Q23}b4 z0i?~0NdbJ0r@&TFG=Wz5f%HQrrodf2*tQLXLlhXfzp^m0z(<=|vXz)1PE=rWM0bk; zWbhe2B?6ijVRBGl(q%9Jo#~~^U+nPU{+!T9agBp^oCgx zbh?mZAvg#?^K%xU_A=pFK9=>8)ncPC1_ZP5!7@1 zz$^e8GBW^;m&+7C_qfOd3oEimVFYX$Y|ASc)9~AO=4jdl*4_K_etv z;K#`@fc8Rxx)h+vF35SC_2B#lYWy&PCT&1@0OUi^=sA<)4`z@V;HA}|5f&y#EipPe*g);V9pZQ4AQQM(SrfC=0IZ-uyJURM_H5@T&JJ#W#NIW zS>$2lo@UN0f|y2bV1dt2Fik(t%_?5+*xL`P)nOw8phIK@pq)$b!ZU>|C1!A`20ay& z2`nlBI)#=Iv>6C=&>3i!8FJ>c5@^H`viXe}CdvUihZc6uCP-8Pd`c&?2Pmbdfr8@% zLzci@P<%*%rfWcZrW8P{m_Pvp8rA`y>Hr!r25-Ouxe&3226SR8@-anBptYh3pb8U| z>=eMR71-W6J<*+6!WKRE1t>5%%9%0wC@?uL0fhpn9|O^WEBnd7%YhHD{bUM^+y~j2 z*y@?kZ2=pQqqw@5j^Dtb`Bz! zfyWJ*G?+X&^|OXrUC^f$9fC!Ssb9i2QBD9%6BF3g0uiqkb;sG zsFTg4!DIoNb5vl`XS4y0x#%<6DY8QHJChCgP+ZW8TyRcu5a<9!6wJLI;GE;g1Zwny z&ipgUs#jprXYd8BR%8Na4JJp#5$H^yBli@T93MiC-2tTq(7qi7CdZcyu-OSF(8>f) z(9|?&iWGWOCvyX6fdMIdD0P{X(xPT8#24xmdQwpL3>|rHlD+cgF5s;TbXEF;YFo8X-z~nfE5foBPphPx@ zF-w6HG_S+txP&oFfw>-{i`AO33zR1=T;@zYpiWf-W0nA9 zz7gM(B_YBiMsxOdTL~@@7mR{f>tq`LqFaN+;N{0_#E1Z^p#p2s*k?fq@mg zqY$mGyZ~Lk#=yOok&y{jRVrjFF+yuf(8g;>E_0j%vO(ZBD5rr^IcRoIgGm51oCZp8 zjG9a$=1eT0bqS#23AAiffl**FC{KVVO&OuxV+I9Ajd1Yf6|8u6WKe{xY2abxhRjtl zf@Y;ayIAExyPp^xAA)Q)12=O7Km(YddJTMdr2@3jR$$<6WMyKXyiiAUa`Hb@9;9LU zzR64eX)>*tF!}sHX~rj$U;k6HgbZV{xblMb(1F%L+kh6wfJSXV$8~T(CMrNBE{7Rt zZ~zqj;Eu(|$zJ~xn5MN%Ui068X<^gkd;k5kp~W8P$`Vj1!lnS)oCNh5Xr~rPBWO{D zjKJ%u;fy*KVD+F91bp5psJ#h4Wt0OnI{|7fF@P67@PNz%ZBqxYp`E&$QH62M)CY{M zOfy@ir!z9j)k9avODKR>$bN0eO|{0yLVr3?y;0xv-wCvF7)9ccMG z68|h{76ggE3CtG(wRkijYlI#^mPRu%Ot(JBC|$p6>6@unzO;W3&{-Wbq~D75YDSOco#AkAk`5(Z^k zgDi~Yub}hNP)m(a8H~?gNXxt#|cz$`au^K zIgvLYIna82&~^j{M+HYlfrHaOyRdXYhcZ||UAWuRJ6%~q7~fC7=gK0+_1FOLlNb+8=k#E)yYKnk=O161{Z?xFy7YgrUn1z<}UPkFI`1`gkPu_&OLdV4xmOtpbJ zlTqN#bR%yTLmB8a7-+}}JW3C}l>subQSZ%S2G?+V`aW-Xkb_eOXtgM42LjYzpm+x@ zD*z38vk3fy20526iw4ue#_2vjETGvCe_s}<=`+3I;RSLCmCQvr_0IG@Ulwi9(DrU$ z7D+)!VG6D_Ky{*{!t{7w7BwV~A**IQH2tbCiv?5`G-3uyX_h!s8mNu~$0lfPpTK{R zua#Jw>O;Y+_gDm8PjB&K0nZlru^J&-z zfUJlG-uNEfFKr$dhpCKq*(zTmjxG`8i_?=7 z8bI~N3XnS-TR^11JaAhCv zW>AI5pvmwIt z8a6PSGx;b$1DFFeAOH?w|4V z@B|@X2F@_AU;>PecA$2K=LzmQ6=aSFO+4|po_J@dnK7bEKvUx zR1{taXHkMBQgC|;rUZ183eu8HM$mL3w4=hn{hW=F6VmEoaJ;~PG}s3pw&4=k1}es- z6qrC)seneMnc$~FGwCuYfJXXYCrE39J6WJ*fJ)37OrU#i6c|A}2Em6QC@?zyV8~Je z-E)*(D6nn%c_v0l&?T+#CBhIL;Gwny44~ss!8hS>f|uxnPf&%rfXR^w<|fcl(4f{Q z=$r-6@=)+eB@7Cjpo@<5vk1nz)h2kt@8 z4w7b&hytr4s1I5QUVeq{RnYhfir=|G2kwBInhM|}jX;-Ev4HAA&@csPryQ%mw&@p{ z871l=+qppJib9h8|=J8r=XnoB`x+P}@QgWHv}6%=N5}30X?4 z;1ge<;RI?fD_};JE-bb{Wj%uxg90dTfCeK4E`cH%G>VB7tQY3yvUL0NTKt1?k&i*n@B>%pzt5 zMtF{6#G)P?hu|f$jF98q6&Q7sz!?+S`Hlk6en0mLP>++zK>;2JAT~;8jRB>z2JWjd z!1`*S?jxx8xMaE}AB%=5xH$>h%&d?F9ym(K0-XWG4cf?s+%;p+U|IsI`XOC2@QyIX zw&{T{ndFJu5Z2ZR-Vmk*v5i|C+A#-h@d2$HU=)Dt_1eqK0y;d5sh+8BvcoG8(18_9 z(6M^Rn1aArNQ8lgC^VQXK#LSLm~23sP(VAelt8PBl~|W6GJ-aQJ2f;kG!!(0sR=BQ zZIfphvK*N}BhXBa@Dqpni(|K$Y9Or0~(RmWZ(x) zNiu0Nu!FAo(qLd#WCx`<&xRZWn>? zy#vq2sx&lAj}u^V#{^hh8J|q&5oFO~+SW2Xz>QgC zdw?OM8KXGXGvhw6P4^RIk*|jgJ%CpSfySR09Up+Vazb~` zr6991rn3pLWHEl6UMR%U$oPBuXCamqj31`Y5oVFo0Q=mG=>Q{SGzzq*#&HWMG{Eaa zK{MPN7_$UA8>c@KW=U7Wrg{lnH8bdxFOb@N5f+Kbo1bebfam1lLzNqqz$Y#U!z%j* z&gl=oF@kRel$hSY$|zH>z$mZ+lsmxb&~XM^mI9-|Qjh>>9CZ#Gs9x4!n!yG-@CCFd zkJ*t6v<)6K)~moMuo9vWG$bux&J4PG6=VQt+n>M^Q1J{hV+I>&mQ%=XY}0E+StQs% z21#U1pDW5Dr3rC7c=Vb{lNsdr2+*_(sPWDOnxO>EXMtw2R!mP~XH;fdz&5>|ozYwg z9&$_AKm&eC;8lnq|HDIL`h9jrx%xejgaOKPT%er>5}*ng;!=>QDDeuaTR~w0idoP= zBNNzb96XXBJ)laMS)c@P39SFN~})IfuQ+eP?A&Nbi4wa zg@w4fM2QQeK1T^WQI(Oczy&&zgsU(cawrKC=)hWmPDrq5FqJsgXDLE7fajR&L33hR z3S5O|OgSK9KyzfE0aGPL(9pR6XeQT;i3fBjBj{2^Mg>-oZ$S4bgEr?fXCWM;zy#W^ zr2q?8(48)z=wXJm^FT(IfYN{qXr5PtsX&PZH2Th@P|u{voB^(7K=}x~T^A)EGJ|>! zV51$up$bZwkO628NIalrL-b4tQH98a3qTnTnvOx4uwDU{3z=cL5S$Z0xv&owH!~PP zeI#&F0NbqyN^g*e1~s0+@ihl@-3vJFV0wZJbRs)}WQ9UTlf{s7|r)8YQNd_nam#``FfanEm zio6QAy$ZS!bOAUJ5s?LPJ}3c0G80G!oSBgP&y%G9QAU<8uONy{(D8C?AcxLjQ{=50Dp^ zuz{|$1eb%L)hCdWMIs9&4{^Ejg8HVA0txO@B|%VaR*%E8Lg*O@q7D%?=otx50-Okm z8eN7NY`mb$6sLg_hc3fxHY)~(dgx>|N0x#Rw1onm-vsqC!POgV{ROCDI+M+saSCV} z6`c4W6WriieIR`Bbd;iy0?1>Ef}qfu!=@+<@i5j*$*sUt52^={ixwpjP_RIJ3o6mj z(knO{g2k~US5WN&%aj{H1r4h?Xxkl=0vCAO9oUtSa#CO$s8^}Lq^k-F6dna8$3D;s z8EBw@%1C_%kZ*fH_0KM8Ty1 zW_keS-xVMmL8UI;^`2hUFlmc7YZ2 zFoTWaWdQg07(k0rdYGpt2r;U1fXY=+N}S#+#He2nI$3NIybS_sT}yz%5!%{-&Fu1k z8-F0DfFl}5%Mr8)0+eIHElLJZxx)a_2ruBE8o?(`gPWZ7kVfnR(EI_YLkdba5S^e+ z^`NyGJR-0<9a6)CE(m9u!w6m%#{g0Q+KmNj0ztI#2*Z>kyA;%b1?63&7C*R?$z_SK zkVk+dozp)EGm6(=Kx-s}@9qYLFj2N6Sq>iV-~{`_@hY03Tp)*`hauQYBH%zo4MVQ! zGesEH?e3u&!VNNH0(et8Xn7f=?GH8t$&3lmc;K4;PlQpu{w10j;Cr00It0lKSX_e5 zhDHi_)h{>1cc0M=Wya~SFeFpqE<=PFJcY1<7i%tIR^);Sfi9K>t%_j)74V=ja|H%R zK8W>)rcVDQ%IK*C83zJil`a6u0F17@%nB?DjIc@l>8WCjCQ=QYutBeL>`ct{Om)f) zpylR{ADH32Ulz2E?+Va~8;FiC_})QKM*@7(DWv1e1nKyKh7OQBz8s*l&0*`*1dtjF z9gLu?3955`KpKf)MbP>I*71dG(^r5>>0(`7=2BhN{ z0~(PuV~POPV&G!r2IzoKNKvcHu!0fX<+XtJt`CB*VE`G#pau>`NXuX+M3@cISdsu8 zf}p_UxDg~eeMLE|Vm*^4!%9X-2Oktrpx!^CQM3Z=Pf$Y@w9FTri9lCWfU~|5q}XtT zIRGSq1B?wUis#Dg0JqcQ@1u7pwm;ZTyd|3~=uN~Y!2Cd+QxWFPyU=pNDp~<|0 z5z?(=1L@iTI+2}8gJ}n&BB*Q?0hQt)Yeljgk(S(oI@_RHhYfPD%mXHnG6_&Hff`Pr z6587Lj#>4?SC6)=a zJ{aU01r~6EhRK7@y#Ylxc(pJn6hO0Vg_j8K9l2N@I7dt5P-x8_!Jeec5rAjSVK-v0Skk)gRUY6I}o(=3bNWV zhRJaYc)kYI>4dE3V*+bt?f?Zb+#8_kg99}B&EUud_9*CF9$}ad9q)k#!_7c1_c^D0gXXTeDmC~+}>Mse93f3Rgi90WE`-~(v0 zy#gC(mAHZen#3vm8Z0 zXM{kcAnt=ofpVr2$n`(iK*M7oCxK)@CO5E~GtB`>DP#$>g7YAo;|C6q1_e${CI%%g zP-6)qBm%mFlZioz8zCeEx=DwLL5as4bowZp0-Gk&98M)(bEYq#U7`wEO6;J}0?8_{ zg8~Vxl^xVZ0he?P#0Z-hp*flu z$Ol@N=%L830FKuTCD5g8oC@G$CBZAxW-w+cg3j%3Va!q#P+)d^0-DHVa!}x({z;lq zi$x*JamI968Ae|r0Z_}736exW=Rhb3Os|n)R16US9li=W(16YHBWN+KBQJPrfdLeO zZ@>c3tK~rgpoP?+00G4bI8B0XL;-~rTmaOrWuN|0hS8n}6eH$LPZ$;06xgTR$TGUh zLT}e)bA%sV%?6qc`w3FQH+`Ngqf9;MBy0^P7eztPW^V^YArNJwC=8-Z6h%Okfubmg zl2H@`Q4)&cpb!#KlmJlzijtrMFBlZLKyn(2QXoo2Q5r<)D9S*R?E)4BHU((~8PFl_ zW=wOyJn*gHYzk6_W=vC{0uw+qo8t`5EHkDhERZy;z~(rCB}?E7II6&TX~uMKImUcm zP*UZ{Qj!Lhl2X%;%P}g}3xMuoVFC{|uz_x@S3rpYjG)B`d?Lddw2J}K;b2oh#H9i! zHz;0Vp(;?L7~K8#n1-|IX>|D6QE4S{DaM$X$hk+sEAOI zgdAxNISW@}`nu`t;`OYophIuPL8EJ8yv(4wLjtsq2XsO#vw}FNoh1f6{TeRL1QKUb z5aVS86|0aO&jBi@bh1F@01K!V1jiL9_agBGKx#}tY7i0t#fVNhdGlP-`tPoVla%3rjqz%V2@GUo>^Z{KR&H+lC9-!lu;X5WkB9H@h z>p}CKpb0|A!MI9{js>8i2y_|if5t*b7WA`$!L1l2c8r5|L3`Oj>5m ze2_*YR2%rJPG;nTcI%N=LxUGJtAKAIV1}Ht4LJga-BAa0>Mf@tJ2Pk@Fgx-o!|b3L zQ3m9Nv!HXjA*mm<0ts}@7q|g{yhx1QQ720gWN}DVJ!tm^__SQm`LR$RfYwxiEQK$u z1qBf3xL(MKG|0#Gf=q$WVKRfJS3!3~GCM+I59WRYu=_!4nbEya54trJ;s>}f?2ZNy z=LJB|@&%m&1i2`I8I&MFMXmvSF)ygSBCa3?+bac{zZ3<{YKeddQ3VlX2|=EG2f(P&|`^f)L0cVFe*aggZbM zgR>?$5P2D#CY*zA#9`B5S^~aY0vt6KIZFJF9$88Pjuv^2jDA^;?1iB9%?g}~;5HPq zqXjsy6q%VFz^5L90*4(G9-!G~B@RWp#4&=%jMHX(*ej)`nP-!Eu1vIP%p1EOA zUAmOa{K}x<70E&03OY2U;+(9L5iXJ z9blmj@alAMc>}6v9Jhd5{Zp90MH8qEB#|dzku69fFTo-^ncy`$ zsCoB;(VTe&n*ylk!c^bGWX`k)%2~r?&U6Pn@cxBSkr`U7Nq`!ekY*aV;-3JyQXSO( zhu8feF>qrPGS~!H2W}&yi9t6qLiN@|%4+a{8JZ=aY7o*$L^N^1fdguKKqQdb!yqSs znjjDf3wQ{F8pRBdLL20F26N^Oph^l9OYG*%7wSPZ*8*@u_XT+P84(9R7(g`vsD6iT zZGw9XbmBF{o(u44e~3RobC?jB6G$>ESYampKoVU560HZN63{w1Xn3$W&HxF6MPDEk zgPOn(K({i2Vv0?Zc?Y{W^9QIuZm^p(PheGGbKC&Y$)4r-0#Ox#4#!;rO{U<44r<1n zg{Sm-HVvj9Y~V70O_RBSU6C8qmjWmHKWt`93qVb7H8V)ldpji2&j5+d;Djf7NZB(7 zGExLCq}f0N#0ubZ!$6B`xfPf}y#fU;CkCej>`n{~R4tY6AD*Knol! zKqVMEsPJT;o}$jE!~>CWWKiVbVVeF{jZvIF_F6*hRp12I=S+@oAiZSB)VBuH3zV(3 zY>p3L<5CJ7)5SFz<+<*HV$qRT;B&)t2Teu`#_iK9H5m=LUV(+hkc8iAGOBVlfcnpl zqDaD_T8wWPFHLvSW;`jh1KcKLc6M-g$ zLIMFCwJ#vGGkCQavj$TN(h63v{1;St&}LK6Dpp}#Mm5Gm)2(zF)fo>>Pts*nHij6A z)7fkan9iQQLzfYB(8w)aMj56_P1AqqG8#f|X#}lQ104-DscE`}9-|yPbPLe*SUpBX zIjBv{jvK&NRyH&+a8GAvfm~F=SU3ILIxd;%4bm*U^+;nBpwbOAMgg6fkAW8GJDSXjn!EGEAtU05$=%4<2b@Oayq45VGGBv=|Ol9fHRA z9Kmy@uyPVKyA9C}n=AzF=448N_&ou%!om?0E}#(%G{1oc2hsed#0E-$?4TkZw4N2z z=Lb8@5!^zC3-e?tK-4HO)oU^l@3(%)?3gY?1TW}LTCFSvCS8VT(7sael1V0ghDgw& zI5tft2GDXmO{N${(C~vbXdvkgLzW=}gAI5PPyr+W-telK2I=5I=c2%&1+6GR^)IMG z695GqgQIbl0xM)qoi=ETE65yB$GEF~l@&mhD{b!1KnCfiUhxTujXM?65)f1BgL%HZj!IW1w0Zlq;qyin2&r zL$Uy9^|u0}BZI&)NQ`JORe&}xf>JwpAXR}0qyjoB&H{;di|GO4EMn7nWmp7wYe30a z0-Us&JEm*Pu*mvefSJUh#0*-VzygX}9#Ap_83k^!BU#1>I;jqP0kt{00f6`&GeHpEYiWCg^u7sTn_MbMFV(9SphUK3msyGjh!-qR6@t=K_w?-fK!11 zG&08l8r22OR4OnzwlGe2lw=V}l0eo7%AfEtThOh>pzZ6tpo8@x3Cj_D`o0F_)P3++ zF_SI>4>&D@(iL1Q3ur(UbhRJc9?&_vpiB&kUGM-k6I?O)N)5;;EqJsS>>x)8Py~Ri za6AT09H5>(IEo;X{?L`Qp!voMP}he^lc@$guLmwFTEO)m*bLC(CXRY&Fu@H0-5$UM zI%xxHqy|%s5-2G^Gz$C%t+WQM#L{H0P-1mr3IuO6umDX+D1nylfhJO5Hy1&YL<1ve zy%Xp*8))pJ4D;860}yllULKrm8&CCG0#1M3nGrVa5aVFS0sA*u!K+CHj zqu$I7;0X!~aA1Mb0rM##5j0#1@}LG2B={VO zjW0$}2+^AM!1r4h*frcBQ?gcl(mDnJ{ptIM(b~}O_?Mmzr;VW=Mz{f=^ zaX^I6Fk~sjK$L?U|4Psu`A6W&!3*;sqr0F?0tyUn(98^Yjvee2(5Scq*miI!3$_rv z0vTk-^wS#|W$Qu50)r0{I=~E@q&s2HAz05?$63!@$5_u&2fF1|xdGHFcD%rYJRHvf z8i)qnEWx0_240^HihKbDHYW~H41fnQL4)BhII}?evls+sf&yEC&G8}wsMpMvDmb!0BgCNG$^#k(W^+``QWS*BonXvT6jESw%m&#ekfkUL6=x|@ z6meu!6a|ewKwR~OQ%Q`M!I1;ngEeLPz^N#%02#vLG-v7o^*Y4Nm^whTxRXMg0>|1G zbLIv%1<>Lg0nl~dptKHh=wwA139lEN3jE+hE*c;mE6_cQp!>}PmVrXYkwH-uw8T6> zkptw7WMh1RHZcwO( zC`y8;2t_Fn6{9E(q7p#Ez8Xv^iejMNQwGRGx(o%1vLL$)73CDz^cjm39 zDijq#R0E@;5{T|#R8$5>+;lS~Ccb(OkllP7j7$vd%xtVIjNA%>AR}BrRl1-fQ?obU{T;ukOJ)oU{jEERLD}|Fauetyj)QdbbSMx z257p5Bim8f8=QweaAYZPIEo-UK@sW%P|A`};K)*vP>?iZ5Kxd%P%>xWP>@hi1htVs zApx3#0+|j?{~St^3LM#v%*ZCQAWZ(kp;!-2VLv!PMzd)!fxXL-rJw?FE{7uv%(011JZ zAfXjtp${M-5ECS{0W9%MF@dt8G-!=DDDyFK zC~$zQO9c*)BM-2G?os7%)X1t=Pz2T49H0}pWkG3$1Jr#I2lYNU97VD~r5u9-2gu)` zIb&8(^9kBh;Q(!VfeM1FbBG>Lw~ftl12d8@6*wG0iy~B^3YfAK)F8|YOj-2`>Jat` zrYr^U{jlIcDgj5(8SVn0)n9D73==?WxY_g>Cow8&f(oN4jEY(ydIlq;M4Q8?sI9=} zc!2}7>J6#DX47YMv1Ysgn&6SOVt5at#myO>gJ>}`hQ}bfUdD{!K8PW0#&8=%OPMiT z2hoyd43|MPhZRFVrvjUTvN=OLh*mOZ_zx0SG-vn@q7}>-K7(j^Yle>?TF#0ARFW!a zS~E_AHUl6|6F3JchaFFFf|j+0G61T??Le1a2Hm>^@2M?I9pKt(oa z#`XXYNVft9Tpybz^9fFK<^!N&0^D8!#R*TAz(tUCkaF+{kCGTDL9%Hu9pFKl)=*&6 zsAqb?2{M||i5XOr>NCFKRN_$31Rd#As3hjgD*~x-P`#kZ9000QHJE%LC9{W;6vzzF zoVKDl(;84PNtiLMKzJWCr4MRPt>DZOI1h3cC=r6qs7E)1Nr4TNB#-bYuqjBGf!qr& zKq03gLA`bdRy%npNx1TYS}$zibI0C5ZGHi^8QOM(l+uo%V*C& zeE>N`#f%B;AT2W{h=UkFryYWmse&fNRRWjmQ9=V07~r-5G{RXFICxn>+h~LpxS-ii z7_VKkY+kWULi|?3%XW=nL$Aql)t&)lg#xB!k}Iq z7i=5`qyTj7321QvWRQXn+#-P{H$G6rod7rI!7ZQ{oZJeaga^uc5?Pvz;N=KhkkkS) z5+cA472trW02TU-7dXtBJ?bG*3Q1*-3XahG@VY>wVW4^plH8TVpuPubWIn)S&U^wC z#XC4bCF%*zECI;Pd2EjTpx`uP+5(bohp@rPkyGphE&d^8hFCx^@o2wKGs$3rhb-coaFn-5gL+bAU%l3`C#cfgef%_NN%C zA75}n7wmw_4IUwG(5w#TBF!brd8Nbrlp9^>_q9J^{71 z7$Ip^;1VbmfdT~FYJWXpwCxwpXN@DN^Hiv>3?6^2FMF~VBn?pei+{l)IHnPPOB*2Yqsca<) za2uOjffLjh$x@Jj>gTQpRWn31vO$NAfEw8nutv57ypb&d>fkYeiVR%_?2T+t!xLPl zXfmU>vFn-X(8vatK%j=TCNp{)yPi#xndXgbJZ)@{{h*e$CNtJXHYiaim@_{Bm)oEV zxR`H1nE~d^pdt~Zzyn$xoB&q`psEOZtuU_uq+S7aO5p>7Y?{m-O5%_KL0*M=Hce1P z#K54y3#u5wwKJ%4WCX9%1>KGeDF>jH8CV^7T@uI|NPPxcT?Nif99arHhz#8PH;3(5M3wWYmEP)O%6L0yQZ?EQu@y zXfH<~O99l&saN1|qQl&vE0_nA&u`#K&Edn>uDg#iR3~F;jny4&A zO67XtUqd-4s z9u*Y2>L@X8i9lb*fIrqNOxA?3R-x88hWIKM|}eW zDEWc5l_Kq-0O~RcfR^~Mflg#l5`zuN!TM65${IAtDv+hb1Zycmvm|Kv z3Uup{N9!7lj%nrT|)u1nN%N}_kg;Y=Qeab%v|>mERX3W<6F9)zEWybSnxN3q z6R1HW3L4@BEph{&ekuXV!yJwsjE*0s9B8O#5O@!2)G~nbHK-iI-b|obD*@5|L2FRK zTX3Le0!kB&g&SP0gPo6XJp(98Kyw4&HTDW@ps{oKx#kR@MkrVaQgVXl*fc<$hk9_! z3luM4G4Lu;jx1<*2`nT5QpN#Vy$@FfUUUkcLVyc_>jd!R8bpYP7c>>hWW^xC!_5uK z)a)pknjKW?skrho)GKHyfG;}$C4O!N9Yrw(T}2KBJw-)O%S}R&LqSPV5!Av_Tn_5P zGl8lyST_`MunHTv;FSP%Q6c?%)V}N*a9@@ITJR#|m>d+uomc`vYb6yG^%OW1brr-E z!S}neIUZmIwdBF;{2@sKq*@E4M*%cu3z0#p z;|{Q9)q_?bfMzg2#zE^uP?ZSM1k0oFkcL|XTA2-Rhr=8PN&uh?aex&(gaB%4fr?a6 zJ`)4?l0d~SsFH{0cgGV9^`N*$WK6IUjVuL3VF4;u46@*v7@XBW-5f+Y1Kwl;a|GzD zE(LZN59B1!SR1GpiM@ye?X%}$1*HZ^Jc9dLkaz^&E(T5(1UfOyisGQ$3kos|L^vb5 z2;lfMfEIY*4jIgSjtA;lK|K#8X=rF-Mw=v51~uA1u?AXwk3H68p?Z+oJs`(%WGTr( zW#EekA>+TWXakKKLK-7T%@A?WF&m(58f>70ufd&D#8inG@>B_Ejs-MTA_kr+QQ}b0 z18u0|P|$@8gX%!q2B2ymJ`7sVB%uHv{FDQQ3AnYOk)} zt;)@h^-Q2$GcllMA*c>h2Bp{rMo>3WlevQtG{6nszajxrHH8s0(hchE zfa)xEYX(mRHU%*&25-=sQ!}P1pj{to;Dgk`LwBGKhk`1kf&#?^s9IBoRBMXn%%Eyb z+?=@{G?Bmv9@bD$GG___SBgvl3T&VQVm zMhUc)6LP9Fe1i|@m@L>qW#Ft<&j>!L3?;8IIzmsC2CsT#1RXr4$f3aQ$XWtjEf1O& z0xdZL52}JjVim-Y7af8V6j(`ftd<9f|>!MiUp4<@M27`&!EfW#Uac2 zkqrZNxOk?Y=VVc5yfA&E9-}7XrRj=XERsx98>icFu_!QJnjXu=BFlJbdNmh|8smlS zeoI&uF*076{@;Mng}q}Y=%S$a+YPU=*nkAvjTqh3A?xx$k*~o7t|>u_NCl>Wx-i_J zqv#kMWkCB9rhhSFOkg}TJ=7Sy_^;fUQG@Z&^aaL@piAM78Z(+e4iN?|0c3IGWdvW% zA~3yiI-dz6=q5}Z6GnN)L(_ds7?l|hO)r4(CYUg)C_|0|hOFfT4Yx9aSM7mrFjWxv z4qAdF@MijT6Gm^){ez~AR*cW4$C)z9Gv1wEXUeFGIF=iJrxqjhjA+pEeb7=c@OCJH zUr>`~Su(1Du7I;-6lQ!s{i8XUQZxfoe=Qls*&9K_s{(JPOItB2PxrB8l-GwGP!75m z7@FSne_XVmI4H&+lf)(!}zIYGu1*R2L z4=5xn97Q1>VAWt!Py}7Q2fFe@;QjPMD@I{kVZ*4*4m%B9(V8(#44f5sm=M=RL9R~iwPrLBg?J9t`p3js57#Q72)F(* z@z%eyVYD}c``!TTdkxU}aZoW(iwiWw#;U=jqX1gI)gS=Ba4^}H(H?p}JhIbad4v^7 zuM9}90yA9ebz4R`gjNBtwct(pnAY;3Y1Oi0bcALbCQy8VmYzv~Tnq^b&_Yzu(G;N7 zZ8Gqj8E4O^#`t*pK|4laX-suI0)L@7_`MyY12o&C8V+$69>d>5498T5Vz|=utM-iY zhzphBSrV3xz_}iDAU(4NlMc-JAjdftDzboPC#P?)V3aY0D+h%DXmK|r#ex)qPjCdC zPX;QRWCWU_nYG4&F@W*l^s^3(lF-!73|i#EuD}eMG65yo-wur0@Fc72$Y>5tvPif6 zvMR6$+?`(K$mk9YBxbDkgAx$rqDMpwd~jq`Lue8Jmv*3Y2B7%|v|$bAXdbwuU7Z+x zw0`L@vDdS}macB#$W~&9ENX@9EoKsU4)V4mmm@Hq`q)D|4U= zVi{a{c|oZWG(Z5Yw?Um$R_HoP9t9RCix+fz0ca^R3#bJNx}1dz+_+;`;51{Jz^K3u z>f?Z7iyLW7i{0@9W0nFtXw|F|7ibW)9<$8477`tU4aWM z@`4eRoFG_%-SG=!mcTdA_5&pjh;tl8+<6(m)7=Wpjv@jVdm0)TK>Pa~??4)`9H1b& z!3YVeIgCo2jx||)Ow5e+Oxz0Wjx(6D9DmLR9S>?L(BBN2RAhIY!i;p7J3H)X{2tJ5 zybH6y^M4)83hWB(jt!uD)+a#NGeGPH&=yW6Gp0MN3hYkI=1gZmF?9o?=L9QQPX}|B z8Pg3`1@?N-_>%&=;|bO*0ob%5y9U!7CP*WR9j)03^2HPmMd&;ny9Uz)4kd8x&)`6v zhvPyXSY>eJ0!1-6Mg(Snk`WItwZauhphGGpT=&(N)P||`-a)K7OvO9J_&YfZh-3qSB z%%H>vT1dj~IENXO4mLo}J7ofG+gkz_*?}ao1}t&_Nn{IH;SV96N zJOy^gJnA{!_Po?y*VU{T-}_|^eVewxe|Se+PxcsW46xq)ClU=0B2 zWp}KfzyUhefcXTgz*$g6U~*94gk%D6iUj9^7En2^?8wOg})n&@>D68=$79A z=j3`OsO1;H3PD-?2RL}pa`GD{c6$PzVh6_H23qnTBz$)Lv1tCKZ4tCl#ZeL_CIQ>0%HXI76H`ElX~M)bKw|X}*BHVC4M2kC44?rZ za0$i?I#nN14snC--Gkrk3K}YdluV$6`~ei1j>ZD8Qhx~(wo-o%C>=o43M5H8)`R1H z0VJ`2s{l|U0v*7Er`QKq58#A~HLbKD(nRU5sv3E)gh@RUmOue#L}-}c&b^Qf1j|2&FloS+f2MH2^Unkhq^wX6 z$}26%8K{9ti3KFs!GxNDkZL5*U^}=f#7rXKib`NQsB%=`0PU$js@lMzqro(TQ4wsx z6wo?DP{VBkxaI`69>B%r4aO{Rs|LEF2iA6(!33&4AfvP3dvMqUZh`6xP-6t78Omc- z0JVrf14f{z0&hnK)k$2SY8W)QqQDHPjlerU8S24xI@o34nut?@1wMDpuE~6YRf*4u z33Qk|Bo#muc7W?jNS;(;bvyu{!v!}$K-XCaOaX;};|nH74gpAA#pTM&uE3?h2bx<3 zIZy!{QjYZq&EWIXKqo+hj}hboui|8Pe839LkqTVkgRR&dZy!E}cep6_n3BIP>;cE=~ISxTIs6{(V!GKCU3DD*ONPPru`UI8^g*+Bsc>H(k!C`b%7Kq18ncvlApxa2?z z&kkmA^R}+gQ2~@ZL9u1azyR9z$mtlDrNpYhq0gY8#N)_X;?B$B2s#Fe9hBl`FoKgA z^8|3`QGo|k4RSatWhrt@pB>03Sq};sO$G)5hGd3@KPPAa4>UsoYWQ%1I@WAZ8Fp~0 zSK=~bn!%_5x}HaoRe=Sv=$OY7bZQK^g~r^$3~r%;jGw@0&ZMF+eNzyla6LQdcwDGS z&<5HJX7B+T;MN(q6$gqf$Xpy)Ob68H0$oo5uB6PEz%c=e6i~Yn)YSqNR%{BO+7@xG zCJ!5Ceq-ZSsE0H=(9;K~r-Gh7Kw{X_2Y3M|rz3LuU|@h*7?*{T$Jw~SsRdT~f@hXl z6*wHN;E4`g3JGK>u_$mj8lj4EfbJFNaMXf}g3^nUIWtm*Kg0k^9-NN*>a&zMAXy$< z#LfV>Za|?1%k-cEu>*80vjjNS!Obs7OC6N-!5wD-&>b+45JKvoL83zml(!&Z0*XG6 z9&p@pm@|XAyx_V=B1?%!0d!d^BDI3A6oKuzXLqazrDzV2XTb>#X37jEP(oG!9r~ug z;m9B`7rf4jU4sd<>zN%id&&sgfusnkQ6;k!I6L?Cq5^}XW)|dj46ts)EQpK29Lp@oGBpqfGEL6_+JWo=y7JPD$wh%dfyjBr-e3i%KTvRjyT_oQkjPR3t)W+f5E4TQ z?3zq(>RHX1!J}oMj-3D~Z?ijsdUN~`Ca4bw?N70T#&E!UTOk4p9A*p}3hWAkn4K_A zP!NI}EDGQ(%?YZNKtTxVY;nOkCRqwBpn4p%iw)F?W1hfh&Y%N2hz%Nw%-oPl1+D&N z1m$FQNAyO6BcvSy%KV_D4QYy?9{vStIxuK3fg5)W;Fd!@1Gp<(;>hmK3o;j6U9)R2 zNq|P@KqsVuM>#>mq435D^nfz3A)uj7Py-pI$!C(K1hIsP2V^8(6V$+?rMQh?MV zbb4htqck^oRs@voHgHUzAI_-9cz^nYI7X%EAHo?U81GN_j9`4s`4v2X!zgfnx@jci zDJYjAo4Yx4R@VE@p)4 zketqx%xEtGaV;a%H430<5YRbXH>XD?GfrTvLB>x1(9I}2-6oCk7(8I_Pv=f&Jb}c$lg{`M&V4xjSO((}#*5RtGZ|+y zewePF#aO5E4-{;mgZ;s$86RNG68H@g0WF7f1P{S83Ot;CGK=vy#HVNHFzPVgoIWFm(Sq^c z^ou!+>Y&i~XA|EpkjvNu^8568d5jT^H>ZEkW9(-9IlVa_q-6W*d}yc!6f%Y~-kiRy zkkOj){&f8+M%n5A3mFf>{e6G>$s)!xaPGtD^NJa_GhUn?R>J743?3{8wT)OnD%9kbJMIIBSOlF#8x1BOC2;?bMT5yhffcl319ZrcKn0^DAjVV3XC_Wud8JAVLUYbcO|1SByJz@gUc9DNeNo3 zAOMYU>uSane#lXuED9`+E10tceotRl&8W(FbNZEPMkmJm)5U8TpD=!%{-*|PltC>@ z`J`NjR6gCG{<{uE_FX-a?8E8D8W;~li!T;kh67BX;)@+rd`+L*$hea6;&k^W#^8FS zl(m963l{$hETC)xb0R3NVOfm{A|~ zNmQ%~Yyy|2t28rOGTxdV*UTuvcx!ukGovD?kljA3g;5{Gn0~sI(TnlYcCj|bT*hd~ z5mun_0q`jO3TDvq32=~tJ6jghe(Noe6W=PIh19H&@NX}RRVuQT#2bwePwKIxC zi)s##F$`7=$mUPy?|>KO;GBal@7Td8!FY3eR0p`k?&x4NVZ1qgZwF%$sJJ!kWRzpP zG(Dh`(T4HT^xjTJW5&(f4|X!jFfv}Aey@vhmpU}jODHgc@-UAAqa!p6b0{!^`jaqc z?(YUy1s}Q@Z^6rr`_nJ?pcEr3dKuR-UYs7@$LOp8k8CE#6G)K_y4mamI4#i^aRxLi4t2!|5F4Z)<_^PtMwNgIp!qz|&8a(>vK&EY`#>WIbf`b5 zj5q;`Ah5mAG6F0CG6q_jflfei1Rt#gam&(vMxPjHP!Qt`$Y_KD6IRPup+!29D{fBr zodAxev{*PvLCI}4qa$*y1sceQ# z7-unFntpHrqZZ@M>2DS=N-!Rp&bp8>5^XWvCSn%TK@-XJAB!1PAnm_O@DQ8=qrm;` z^Oi8GGcsWqB1vY?Y8<`wHr!X^s>MYPHT1)~rrsu9=)Wef*x2$3` zW&An))hckhU7gQZ25ObcGfrQ=hLI1H?gI)L6{cTb!)VHQb2{%@Mtw*y$WD)1%eWJs zfbUP2S;rX5xE{IrEHnM!I>vNp8yZqAfU;f#{6fvu%uJm1taZ~TYOo4RX)v)UGJ}^Q zDuSl>;M`^W&j=b2U?K916o}H8hdgS z0ke1%*d1lSEM9OQ33N0aAE;N#qR6kn0PfH$aILKYjU6yJ>VPKpz*`+uvJ`khbMFj} zGFb}XWAnkMVR4%?P0#(z%vBG%=>oKT#3D<7<%LST@%TfeQlIno==Wu`y0#;yC zU1YhV~a$51nXSFOU1paw0J0ecQSYzFEB zfhP7q9aCq}!StYM6o?YYx)zW-pfd&v&@-qR97D2{7(nA=p!5K0je(XX>EwWycnACWBK-bHIS2hXUnf~+)lL^!O z#_75DnIx^D!%AAvx$LjzF7|HM)HDM-QeYKQ=mgKEV>L9 zN{pZr(m_(-;Wf~O<&XplN_Z@wTaH1+v;^o<3Fyokivo)#lL}Z`lUV}PPz0^)0v)@k zn56*LubAby7f!6k}ha)z>&#{K><`&KVY2RQ_HN*3-_r4qrlne2Wpv%r}Ne` zD+s{FL8H2i0{f@i)-yYU_J1icS}{y-uV>a~w3@!Tp1EqeaUHX~AVN8KsbPQT^yE6` zRrU9n7@1&qhg@LDR$_v#E@Kkd2nt~Z#HID1lm_Y_fRZoh2wre6Rl#xMLeLH5OakB= z$Q2kJd9uLQP~*OFU4cmeeEqlrNJ+gbI150!unLY7kPQPR7|6BZOc+;@Hn3XB4CKw{tpb&LXYA#BjVp}=QQbB-UBEf@t3gT$fiz0*H3GKw&*>;W68 z1i9>+A7Z2eqrh&EQf>tQbNBQ{DJEmaQ^a2|ehPBIxE>^DbN8^ZfNqOoLEIR%fH7N% z1sbO;3XI@`&?2VqJjkd}9|1b(l@&51!KBN;sKBDj5D6MJQ(y#VEYJoL(0$q6Tl9|O3dUzq|`UQ4yjs%H-t_OGg!T_pUAeV-N1{0J(*|>)h zBnVLm8c$VVah!rABmr8%qQs@Z0Z{=yuoE=UZO+V4ufXDH02h3MJ^=Gw`@EIGaQAG32N~Q1+KFX9As$sQ?|Q2G?<*(+xnQ z)?f~3GqomjJ$S(xw7_7pfLz7`I)oJ>4sIKQhKJ3W7(koyz{L<~%_vgHfPJUHf)+9c zpfU^MB_&>jPe4P^Aa@x+tJ`|;35U?Viwao^P!I4yT+d?0B%%PmZWrkYXi)jZ0y=4y z9pujfMGjDCr6}?$fU9#B4W=B>urz}sqDD6WogWMKH0ahGa4ioSZwI+!`od$3PTULN zh5YO3?~XC1@`Jnx+GPYzbdy`A=NxA&W&At+(Q(FO5|C7`zyzwZz!ewtX7}j_PB1Rf zJ;KG#RL@igO8g)iUaWnNY)Sl_^iB@Z-$1i7J^0CI5^_*#>?EP>yMOwhoH z$OQ+$ryeUYgIdOn;2VjUK(PeAjtn$*(gV7703^Z=Isl6WbX+xPG@k=BSPsfL8cZ#q zr61r#&7}a<22K4S2XHE|3QPsHM?jqh4W@URp7B>0+|E42T~&oW(SCeumi+H*a70f?BIYH#sV_iK>54KzYv|m$+AKZimyA^aVm_(KmH)LuF>`?)5 zQ6mJ&!7veyEG1z`;{YTA$~6v<&4J)ap?YxaF~i&lnneReDEM}D7ENaG+z%^!S12d^ zPFz076d1@za6}noDRIFs3uXZeS%8i#0B!Dr#2OnY!Wa|;L4E}nIS%Gb917E8FEGka zkNnNaJH7J)qtx`(zd1R^ROA6^p2MgJT2chs!VL~wP-~2RI?E--WWEpZ zvh6oB3)A$BlZ-~wPab3xU}FH6I@33tWE6=4*;5?B%Q7g5A8AW9gKEG1CJQv?l0 zf@WMnYve)24NsO5=-wPf&~ii;4JJ@w!;z%~+8iiwWxB#CMs-HE>Hdiv64Mh-F|zWp zgVw%-!&fCsfpL2ADMo|ozam+A89AnJJjE#L3NBxvg**$$E=Wg#MU#m~5p-La1ZZBB zNd)3gfh+}12n*Dh0wpu>?WSzgxlc1ja6e>cVXSAY1L5ftwz7!UGb%6%ECMwtA+ZP} z6_^F!r_wWn&-P=6USi1%Iz9y4tq4$J1ReAS>NtRp48SP+Uo-76M0n^M1%$iIgpzE0m6hLg|1W>kNR$wt_ zGErbwU;-Vw$_yIz1L+cgoZ=1cJ28RW#{%kysen3G5Pvu_LXHdvdv*FuD`x(BY|aCB zQ9%acaUDbrs33v52;@$PqZmPsV&Y?BW&#h8fle@ocoA~qIuj^jKz;%Fs~)ru7IZi^ z$Sa`C$O68v)Dh%)(BL%q)i%;r1b zHaOf?HF)ZV^kBiE4?1s?1(J~kAQKSN?H!p#IX<#8gRYQZnZEHIm+$tcuE|GY^ zkfi`RE*~^dzyvxRnHjXzCjtEu3GhlIIHLvyKK? z0c1EXp^J1BL7 zq(Etu19GfC_*$hmkc0wG+z8hwKq_jmD0l>e2b9X0K%F=RCQ#oGG%SX=xC80~a2^MX zLi9lHN9N#R0`CrE(qK{n9gM&Lnl%OGdI8X76HE-CWD72TAgu#O9!TO8$Z~9f<$3Vp z3-HBepu5^$Fy(-^l!Nd0;#6V*ZPozaI0tG*fe+dOwU!;{fG@)W4N);DsIh?eKOq)( zfK@=Z-GdEg(O_D_G<~5ZtJw5E9~lK14^8L$#3&UB-9`^yA_7*T0KTXWzKfny0Xzf= z-Wk9MIeUo-ajhG8Sck!k33LYosO=Bwj&pBdVq~74ug)q~-vSy%1_cTesFdMw1Z|FD z0+q@(kO?gv1t!N6kWkP7B@jo@P8QHj!k~?hjvCOdUf?@XK>Z5PlozIO;)H6KF6A2s{AQ&mci?YfS>I((w++Vn{x{4azE@>I{@! zG(dxS3?QR5AhignjDpzc$e_pwiBA?Y@TyQyr%sna2Q&-_8Za?q0`02+Dt@RJno{p+fdrF*^!OKd^~iB1Zsn0U=nMz(q*a4T?}026@YY7j&%^sCscc11=Uo zIT7SXCKpiOhe@AN2fTq5JO}atlsW|Nf)WNuuK;M>0w@3uFl0^kdm~lv3JOnM1`#U; z7X@ZemFb|stiWQ;C;$#7(Cj7Hxl97TKzRVXV~|;c$pvH#cud#PZeB!P}u0}C^NdKut!2I|*AE?#L2ojY++;at< z2~+?zb3vs$xJAdR0KQo(3v>{P0xPtr1uaX)TGWEIKuX$r(8w($5hEA1h;kI%cVaD3 zgiOXTLC^327sa4qMbvB66hQ3)u#N=iObcky2c&$5S-J$YK7h3ZH0jdP(BQzpt-z|l z4w@bUx8!6%9tNi?P~ir>L<=;q0-ESy)?hM$%NsxfWO`iyizIY!1Zbg~1``V;e}aw_ zL0*f<1lc?H@BdQKv{GHW0oU_z&B9F0mWeoDEEM(8H7Os3E*K|4$zq)%%Fxw z4ro%yj44Bb8Qj3$z-Z2#0BNT}T00;$3{XkXnLi0&gIFBv`LmQ*9hnqZL6^w#F*C9- zuz)($b%l;K?!3(0;I!gY4=Ni#B_@m|kOgIdC=LZ?P_s+mBq#xcss>0=>In4$X!!!S zBR6<&E2zK#sdc=-068vIqn?RDkp&t9T~tw$DpDKyzHJCoZeYL*L-U-bAawq)npa`-E0k->S6;erqE}OWs2K5R-@c}xm53CS+96Q(=0q}9`peTpbn+c!=tPG&2 z&}2$6XF9?Ns%OlY4lsgeuR#IC2nsg^M+Sj~phO7DETE{um7o+@co`kJ6?q&P73*1f zm_QSsEZmNaiaemD5zxfAg;9wYTn%V2ZD3U3MVd8+xC_2l5|o~y9a6Lk6YOkI<_6cd zkbDU3;xQ{QYcQmmF|dM~Kg_xeDOL2~X2?huk_C|J1S|(OH~=9BS~|s% zrNjWWp9xlkfWj5D5*@T65z)T@6~GtZLyb!~nb@GyfAtLvj!5%=po9xLB>*&g#o`1S za{&be2rDpyxA!Qq@iI8FC^Ccn4!KwxJnO_#q{sofRT-odf|(t_)8YzD3e1p*S6~5+ zxqyNmwD$!(!Dq%)4;nS)0F5~^SAfD>f)_OO{sPib25mtFr76(3Dsu&>=mpsYUVsi- z^n3&qQD99_4h2?6o*eKji6&^%0uw0HaAYZPLK7YfND=gM z5KuctgDD4+zgRSwGLZ8ZBpemk{CQb<7`W>}Gr}yI%oULS5u|MhYLJ5GVjyONmL-D+ zhXHg7EDLDR7c{fStf0sR^0;Cz*hpwk4v_Do>}sbf%J zMFcCTMgs*aJY7@4E%nTx0t>X>3FKP1TR?3`#I)~rZf4M(dCagyC>xlN7NIyU04+um zH~=aPKqU`o++hKDGJrvW$?*dtXh2PY2~@H}TSpK832wp1#56@2z*7v zo-V@z(0mt@F2h1b@FIO?&`cO8cYr#*;7L3t4W=cGij318otee!!JA${hJj6TL~1*M z+ylZOH!Wa<9OuXcTJE!)(TX8lfk}Z$pJ6GZHA5(fsll{@(Tphq#MEV2!f3@1qQC^Y zl{Wyi?#P-E9GxIrKu!lmD=1_@kzdaQ>0LRpf`)%Jn3gaqae#*ynKYO{9&zMWWOoFe z8NuPm1gd73^cg2Gfwqf-TonR!lm=4(^6ll|a8&@=^no!;;4dg_K&lro@`7gcnO86_ zhhOo-kpr%lK}T>Qf(Wz{U4tn^34Bo}6UcDTIY8h(HaO*hJgCU&$f5`u>jf22pfxI- zpy^ZwM+R#~P=lY{ni1aF0A0BX@)$;lLtUuAA#fGcTm~)10(lxT6$c8SC*W%}LCFb{ zAeljP2uzNUJ3B$bkOT~#S^y;u<`tl;N0~w(XCQ!8gM0;=Tmwx-v6?e+@Gya^OeRg{ z1B{^R5S(?CKqK!U^JG9pGB~M$nsiDWkj#Tv+6Nw&R^o&TgBPcQk~O&Y1cy3W^$8IJ zA4UUFXOX2)4-tgbps+w0gF=)ds!)(8nU*kuIzr&;3^XwdaxS=r-~g3F;Hg(0 z=+;&c2Q+#b0B#+C2A~+g{s$K&h++WJcm}r}z!rokF`I)5An*hhSeQY98Egb-2o$=+ z5LCHo5vy>6U`~d23LMtS2LeXG?$TA?yf`+2Omz!>2g09@>{?5wE1fI!dMhsdU zU_>sYLB$0lY9So}x!4$#PQb^LD?o}afh;A^wqT^f3tUu#@*HT93TROjXy6X24LrL2 z0aCDm7lVKTfH?xR0*nJRtOJTQ=;8^8@f=yuat*ZJ3zWIRa~l_6J#$DJ)&Q4apacaj z!A#((3bewZUdNmnRs=$Oo8V|h>1~2?9i##UIfyC5oC$O}IWy??P0)%9@UXeSVoszs&&3Z1AiPwuK4Ql4Azls(u2z(HsZ+z`IcOpShSptH>B(ZITHnZITV(Hpx9u$qlN3AgO8tXgL^Y zi{i!1Xu6iJ@ZVUAtUfvbl|$015{Om10NL6kOQ{B z5}@PZ!P9{tad@DDTOA5u>k#*{FoA;45gY>_Acxw)O|Sq(%MXMg$kCvJx1K`*lz^CT zfCdOb>23>nLQ0c)2csezXex>U2E2EA%ae#); zz=pDdmRx~ZOrX}y21ba_Ko_O&0M&5dB47h!mH=c33LFyx_0aX)Ag_S7uz{DoKqgYa zra*%SWQYLNWso)ZSc?i!$^f;4K|#v2h0&a;g$dMeHe+gFf(%VDfi?hvk7jm+j81`W z#{mydF=;ThFu{wC2GGV6XbH}(02!WQc4SmU9-U$ab@D-Nd2lld(sKYeR*=tcWaVW9 z&7wFlfZ7OPFN0G8C{ckkBX}qmEDlaKAaSHL2EMuinhGGtyTQTcQa%4qq%ejRTR4HJCuT4Acn#nF+4?kOBrI1`b}NFa(K#D>!f; z0PZ=EFxU~`3q@e(Dnk4Vb_X~D;mRSs7v%dHn81gpLfs8h2g*I590O{nYyssWW;4*3 zCn!;araljVG7~5tfd}{%7@XP~8X7?B7eUQc#|cc+z1K5pTdZ6J-tesentn6`&uq1EJ0T*ViAq7xlsL2FkA>6Mt!ETtTtEHjdhj+>rVWh2jF+Z|ZD4d^yfl6G z21XOcOVclGV2oqDG+loqqY~q#?LiwE{TLa4OkcQ(v7W1GG3Y2(C4siC=~|l^{X`J_ zh6Zq-gV}N7^q$R(DxN1GmV<{IK$qVzJ05_DB!C8%LHX2-sX&3*@dkJ-88qY%K4cX% zs|&hi6O=)3FlGs~cWwWWHC@?#IU;#M_v`mLtgQ-T5k%tX5XgGrfw2bo#gTSTfeLERF z+#!2K6_`OQDL@0}%vp{gNzg6@DFtRwcNijv5Cxg?12UcmmIupBm)!-9pTb>?&Wx9) zZ{5Y{!+2>s({4t0#>v57H5hkJuKB9Mcx&>)ucC~%CU5_$#CT)!t*@<&Hzp^16JxwJ zx%`_vob!DWbczZ1 zv>Hax!BkKlvjU^z3AjoI1!jRe;AS0Y#U}%3dk-ion?XWM4hjrtn^iCb>On{NzhKG& z?}?aEo2A48+ARj2K7&pGGH{oG#>K%#GdMB{Kpo5gI)6h!fl+}$paLS4 zM|MFDgaJ+8gZJOSV;d=OX9RX-hM1g^y8|*yj@iFa;jEtZmPH1Q`!$V7fQQ!e6P87ihB`PrLGAMvk zfdZqWVirV73fu(}*a`{}De&YWNSPx{*&&83ckBvb!3UbyhPe=F3(q~!7C$8Z|5nJB zo~Oib>3Is-(!+RYdei~%O%R|f9iUsPK>-HZ?V-U0-h>I>NmQT!9srnr_yD6CPGE9m5rAF$k^1lTYrH%@YFF;lae4PG3g-N{rE)ye1J-8JG zi)--iG>{035{o{gkw0kgAH0f0P1opFiArf4S@PF zj9H3I3ap@IE()yrj7FZkOgs#rAy!8ewV;NY;~}uav>m@7hX|;bm!-%C>K`aDfu@-t zjbBy;Hb512w6#YQQLsh^oe*te$0u9PT=l4KMj1(9l+YuQR zzzee&!J}^6O=2wk^-Oi3VOV8QCS`Ekz?ZGWHC^!mlLV+O{s+7YNQoQN6{t|+fpl4Z zFk~t6LY6x!@+ojRHt=RSvJ@%uD{wh>aAhe9fM}L1(5@0iK?N?y9o$)pLLgkOpYu?Q3WQ)7RD?^G0;6apkaAMai)3)1<;Mgj`g4`rnnV&vI{|ZR2)R` zfoAn3ofrMR8y6{Hj- zYm_7vBtarh4V{bk%7^hXgWB8N3gC$*F3?)#4i?a=OJ0z392v6;LEUI^1s;gQctDPp zQh=&ckOJK@1v+r=06XZ0O^z)1st1so2F|Q{1s+f+IU??G;&SX@$r5-1D&Roj$qPE? z{s23&Mp1}3l2M>AZr}u^JIIm>DFrSCDNyH`%dr7;VYvcmQ3L26U{DlK0j*%V!qz(mP$2IUXW4RnbVIbsq0JhH-oO$Y{Af0GF1sMfU zgx5H2xO!3qw1*s2f^%sy|KL%S1o@XUOF_`F0j3w?zXmP^P&x#K4%}1)F3?PO1Fr%& zrGir^EKHcdDG_QII7KT+g7zBsgTh*ghnF1`(OjC$8sL=0%aK~hnQTLJ8*8Jr*)8MsckMj4Q0k|2$;3X)KbG77SalH3X`3X-6u@GPLrD4@Wi zAP1VUVNs9=^(JKkKs#FMSwXHk!3f%1&I;01Zr~LOnC6=rm_O04k(9 zSU}TbpbMmsw1EV{X8iz<)PkH2PEDX8Z18>@xLM4a%o*m)9W0PI1E(hiNUjHK5ZDRc z2EYuFhL!{1n_9t1OMy|~Iw*BQ@?8U`5|1M{s44>Mh3a7`QW8hH9t4urITgeq=^j}I zl;#8=cfW!boHIhUQSgA4!hq7Hz;lpQJRIDho60q^AY26o#|9>AM)2{ZT#l1K0}p0Q zN5H39n=v);DsX{Z!JB2q1P&}lGo~q=3S6KS$t|FRgx@R&cYYflgQ@(J*f%#f>yxIjmYfFg(^%MnE!6hjI;^`OYp zVB&FPa0DNi@5m_d2V|qb8xRR{Ljxyhu^pENQwt}^`HTuY0=q#)s3H$&Z3Q?9OaLW0 z4Kt=55WN5rBH&~Qs!7*F6oXdZAQAycD|o)Fo{nLM)C$eX!nwPk1R7|JzE_&Y}9`N zU$zoU2DE3+;@H3f+U#^3l%PS?3TW+yCi4Ooa9cou#qj|VhLz?47SJ(v`ZYckQdH}4|apk zfr2|_0cdp{v`l5uWd6Vo+G(!I{DU2|u~U=z0XwKup~?J$9kh)fT7lMsj>uurWag*= zt&R;*gj{U{-tEs&1G*UqRDUwBRpbCgH7BV4UI5)i0IGagK*z-?aDthjbx8-971#p6E6+rrnT`dP=>#B0c!74!Lb4oa^Dzrr zZewx0zzd4`380Id1ipjnC;{lPh_L7dD*+98Kqd)5(FvX*frz6-Gk6~WL>zJgHfR$! zC;%?-nlmp@hDJY1dO=Go(-oW9#X(E!K*N!csvRktVpL24kLJhAxd^0f`&{E#m_hT+9mG@FESg z3mfe1bXa>{i5ax|$58^R7s7)r+JW#mU~*t{!9%f(h+GLdexDiCs)8)Bfm|g6S~czX zfN}C!9f|q}AU!K!oi5N)D#(&BCUa&6$1N*BLm%3pYzJnwtON~=w1fJX;0@|Om_f$` zusF`(glAaC56qBrMc<%H8}Btda9sI1PL0BECpU@Lyj3#;5=Y9 zXMO{$Z0K;mO*v*-5fHb|}&Jy_4 z*w9eV-~`$b2~I>mKoX$j%_#5?$vn_nQqbiv5QlMOA$1#B9AAK!U4qAjKqWql;~S1F z$1U()Dl;!Ls0wFsoB$p?M{{1JGq+Pe2p8ph^$P^WcIFyhIli zs30#LUK+C_tH*PRk zfiHRjUG~BQ9!gc)6%-Vpraa_&DNv3DuX|hqZbCo>!HE}Av|occQG@9MuM&7OKWH`R z3Z^VY&;ckjII|S_L2E}jvcT!$1QTd{3lel3S)j(0BLiss5u9A>d6fh~U3wNxrYF3R zD)t61sLE9kG-JBJs{o2LrYpRlCWK?X0=tt!$8sfJNAT_eZ)rzHP$|m3T!}}4NrA^( zT8YWAJ}bSS6dd7u&+yy*D?FX%)F4W=8s zio76KUEx*a;Rc;523c9fpdbJ$Tfp<;+@LB1a)b-K8sP?&gb*=!H3GV{22{R)_8cKf zGSH|WIH5d%iGwGPS-``A;8UAG5^zHx;-L9-Xt4t=QUpM08q~0X^TB%I`UD`3ggX$F zE0`ZJnlm@>D)7Mze?CXho+GfY_#9!SJ|C#m2gT+C_AEzG2TlNb_$#>W0ZGx^jt`)F zjif-e9=Oe>1UlFTK>q=*;9ggTc6ECW94g{2MU%OK*POWl zRJB7&6p%|AU?mDDA%MCT;4}lu-U?thA-RYd6ju#Apg|Szt|?)VtxTYq7=bLvkuYG6 zM3#b}CNo1lNFBKJ`@jKi-Y~!5P+$R#r#u1COlC}=?5)6S#&idi%^A#?Zh*wu%$YBM z)H9efp8)aM&6y8yD1cHus7VWVEy(9gps7x9*$FD&K-Dj(1cDU-pkuYL76G8+#TuAE zg}E+6BNI6LGl8~-BV~V9(86kP7aO$0fjdiJGAKoZ$_@>tJKT^-eijX;8=!eKST_?Q zdju|952{1JGa{fu0MrR$alFC}sxzR~k_OWmZqQ~ZN1hx-W^g}<5!w#|?;(V);DQ+s zJ<(2q*|8)GR2G3J0WLtyV|0a_7;pyU9@tvz`UcQVA)qz#ptccGAp}~e4k^bJAi0)N z09@{X@+YL!aRYa;SR7aIg0B1kD{|C;te68;#4L^*cp+_x2EHsMSoO@}xPuqka^TBS z;)5+7VsSjco23LgfoB3=mJ%poK#W+x3qITkl!RySWhsHv608aO0n`KqwL#wSg2D?_ z=4mip;Z+m?CBPft!c2qd0k5Jc==_@}yo#&}plLx!o0kW6BvHKrAH1a?s2~7JtIP}v z!jOatwu#@2=?$nHWHo1c0-{CDm>z&=P)!b^Ma-D4fM_OYdC8*5ynxr7`2#N~P(h7x zNaqj{w4lliRQ-cf3%LBd15Xb46AKN}NBUNC4f>;bhlK*NKe^3#!_UX$SnLIiZ8hbF@rgn(Fr?RPX=H$FBr1SK%4bI6B^*{%kaS`X3z;}&<%XxQ560GDF$*nEqI$$gc5k~eFA*o2^I&5>$zR zdseVEzX7NWhio8&3xQkw2H;6~h#QZA$`Q~`K@CTl97R?~2G9vVpz}dlz*CB>3QXV) zwjjencOWul3ET&jS_({#GN4IB@NofbuDl>;fp*q_%RETh1uZ^X>!i@8z_zxuH7mI9k1|vS@|yw^Xg3GWfih6AYcLsr5)ERTGlL^! zY7kWUf@TLnCn@kSb34k{!;={kXrzY;lw@wfk_>oZ5Q8SeBZL4XmAyg;h=WtvN0v6|Do|hsjdQvvkeAHB#XK`OnSo~U!As}C z`}ATIp)2z0nL&pcfwu%A(ivDAxD^K3Aqc9g!0W6*Ta5+&g5#W7gGmLng&cI*FO#DT ze9H?cR6%(cHnT17$OxO|23_+3nju6sMHXrdXnPy7F`(r(6Bsw2nOexm2RZIr1=PA{ z6xcY~d%6?%Bv7v#v_wwe{^Wusp!3rwADmvV08yy~R;j=&upQLcLVR+tTlUX1IZnI1o?{79(uo!f=$YjMi5sWt{SIyBy5p$nBWu9OX z#4$23+gE}eBMsxO0CS~a+~r`dB$z9(2F#Iwa8`pk;$V&fv%oGeSBx8ULil9%`OZv} zIw$+g2OU^H`QY@Z$rt9UGTxm0ZN4R%gJc$g9Iv;?3{_lS1XQCiS}}lT&q1ZC0L0b8 zpw3BEkY!0y+o?wDVP92iQywh&;%WEnorg4iQF2 zkR=cS(BW4Kj9_Q12de-z$Uw_W6qp4d0^r^xqa(-}5CLXx1x^M9Mn`6llF5wAtdN58 z;c`$quv&p0>e_g2HQYLPXjYl3wWy#aavfQ zT6Un>QV&{W0^UrC=^F*89?*h8RNpW<>SQ@ig;d6%K=R1Jav>xRnvyUSI?ZBHRkHcLyVAc9_u-w4m;yXcNQ0?|(Ts^h0L0d02Hh(U3X}`XldtZ# zu7@}fe7`CusLq|R`alEt+B?wwj39v-2mwf)y8s~os&h3MmV*S$Ko=)E${}WK!)+qoh&Ie8RF=#SR*aY$k zXniGUqMt#Nc?Lqj0MuAuUH}&WWpB`pnGBlD9S}hYPy<+j+0hFyC*+9oXj-6d$QY+6vl&_S0AZlWV}21^uB+LcPFbH zcM3+2tz)2|2Q|cDv2_k10Ew+@2my&KM+OasdmsTwY`p>96h3+9ad|#yq<}7tcl@+! z^0VVcph%HAp}_cLvh@j2q(q!hG(d?IE~FcE1r~x2=4S-W;wXTQLJ#9*6j<0gdF2T& z##xiUoKR)@v1YRLNd;BNN?~?Ku+6X>$PSxshFPC*($L|@D)1274ps%w1;P(NH`Ie} zt9Jz5QNr%HgB5xJ8RSaD9!BuWHPB@W9nj0>Cto}%Cx_x-s065K4Z8pCFze)riBgl* zPh~J(*gWAB8>3AFIQrP3R%m1i`~a=2lmcBm%a|nqlLcMi#17iv0+&|c6!<#%(rH!3 zFOz?q-tGDgq)UNam*EL3e3SaXLCc)tvJd=Y-*@iJco# z@(Em;EV{#y@$TgC9q%OWL6al10;2Q5?)ZRV^4c|eVhg|lid<+g2rOuw{Bg}}#v7A+ z*XlCPp1gal64QlslkcyUQ3fX?1$LB`D)5p+2jZo~&0sItZvc5IW&_Ae23y6AnL$ZP z0iKe;M}2{6Oi1q?bbBW#KZ6v3uP5gb=xLjLcAX*9kH$&sOQ1C*Bj}V@Mo@(~7nb`WAeoRGvZaQrDSy7F=;fVLSx{Rmne$_QHa!se(4?`b3abP{AeD22iN zbP*u{@zYI&0K`uZ5dsiDy#xzLF@PEuYG7Z!2aA9k1|UyO*4rpcf=`6tK4FLXWb)gM zGT~DoHA4jWVr(WKP{Fzm93&nJ?4XMqzJqLav{!%>(m%niAiT*2teJ3lvcX&dszE^0 zXAld1K`j7fGjQvg-4WA;3)X`zfx7Sk$i0qsM7a=j;n1g5ld-03q{wDPaU3f*Xzi1L zBAcTXa%6+jJcA~~3Xo%vBYOiv020|d5CV|MK7bH_MD_`=Ksq?GK`B_1;R09$EC4EG zH5qOo1T3-~8T1(*fCQ|;$-&Bu$wq-4w6V(qBTHL>2JFC%!v+S>{$_T^*2$-~=wM0f zh!nyC^Zw+7t+H{@0u`LnVQf%9K-mfm0vAC=52zLJ0Nxc;VPpjDMKN&XfbK;BpBTu% z&+P~jf@(d>$jCIkQITC@`i2{9ER$s}S}{JE9DY%i@!;gzi}H+@CeOVn%?m5^m=stA z?oK{>F_8l@-ot%m`n;_ipzVPIu#0X4vJg9NK!aQgi~{dLBPyVd0ch(HY_A*W;8pNO zI)N;Kiy#G{=^I@J1Mt3bfh8zPv@qZW^**4+f+{g4M}aKZ-W3HVP(A|>c7ksyfNq2ai$Zr1 zB9;SyMWL$!z%%l&BTAsRu7K)j_|z5HzXG6xP(htli!1@yH93fQ`pk&bWygAZ5PVk- z6MR<=WKj`hS57_X#5S~TIm|GxK>|>h0lX~-lwS@pAaCD+s{?Pi2X%5mV`y;yYk=2y zfKUH}^dmuMY=R~>K|7Y9-DM_YPL4DKH9xN7BJfKA36-ZV}LyE)B?#?;}vQ1D$V#Rge>;lEI8= zdgTOW8EGB{rwcot@BB9X@n)tHgzVdaqGWWOXf-y{zldt{MFx$}mhRK^3 zH2Cp?DMyLLk--DZ+1UMt$mheMePd?^ z-F(0bo6GsYgnY;+D7$034FSB$5BWL-$U%z&S%@1EVjz~io3H+Xa(bY?MV@`4#O%;Jc+7y-1(Cj&IT z0y>9~DFr;O1IijP=1exA(`n6^EI>P9!Mj>5vIHPU@PkLrd0D~gz`LiI9U=EXnK6O3 z(6X2_M}SXMhUgUd2yvzclZ6r^FO%a6P**^a$&pKu(UD7$6?DiygCnyQgAQneEhvSs zgGRt127+cELFd4L_ECY)){9YO8GUv&-%mVk$q zelj56V+X#di5+A-=netU)(-IL3Sf>1^pqM92jnLUa|X~sLagA(fNUaT01cF}fCjSQ zQFEXk7MOP+$MS*?cLO;C5k}w}6Tsr&<48b79w>@ItE!+rfqD>95`a~LOkj=xoo52N zCyOHse8L=PIvBLr0g^;OGiMBrG9aTMIh6ryq6Sj}==KJ1Dw^)7&LL*N%neRoCqXfw z$mGZZ-W>?KQ;HFMDif@Y4muqLu1iz}l<+<f1e;7e!jt0{Y#_0y4EMoPL%nGhHF} z?qD(pouCLh-GZqFw7Z`XJV6JxL;CNhDxoP+Fw34>c=o%IlL@D+97Yau}M!j6q#QP99TSWEzPks3H?A=gQO zZ;k@XC}e?l#zUf&;U^>LNO7*3}j9H){t7l?>-mT#X3Qe$E zZ-5gJw8Ucqi=%|u9dPnF0SX`{P39Mj=FH&3A=u2B)_}wq&6q&p2|Y*xWa?3Hps}C? z8mOJoz?fAJYPx{~*ijLbT8Iufa0r1;g93#oq~HTL9FT(!Bn-Y65E{H7z69vHENB4U zU;x{%#Elk+5ef{B%%Jme^gvDmtsr0k9RaUn4PLAWT3QbpAb^%-phD7-1ymz|S)gdu zWR?K+>KGtN5PTa0yr2aq5^xUDWni#ks0S5+idmqodIk_Znjnk8`5dmt5Gn*&5(l=% z5-J2)pavE?2tJd|0CZa!*l3W+j~KEPxZ%883|XN4Bj8yD2FFVbSqhxaa7#{sDswpR z5Xdl1<_L(J!0R(XGm4JjEDvrBf%mzBw!tt>zt_PkHa(t~gR35t{U9|rR3RsHg)6A@ zp#X_z^h3>Hr4jO>W^B+y%|Po_LGzG~JXxSwe~_0rvK)7V(i5nf2HzP1U)ajR4cf2_ zI-v=Y@6j!SWp!K@F@p|Z=?0Aug3>N1cYt=n(GiQL? z54z)o3AFzXT2`Rj56?Ha900znlzazpD{wJ^wl#yNPNy@j;t*k63BH6BO0j_2r(kh* z5Q~9(@??`g=KL?_fflhVJAPRJ8n^y9x$2KfBB=QdYE3IJWP{r3S)fBn6KPVBc(eZi1AG>n$pLiDHVbHR2!jH6Mi#WH;0<3@L#@vx)Ug5}<|%=v-Y8 zmx%*(?g!{t1MmP0Bd87s?`s8_2wKkr9wlTc0!0aUK@uo&)@PY9X@Hx$j2cWFe9R1t z%nZyjONT7AW_g|qylfjH6^14lL=_WBqQjY zX3$01pm8w{MNn`sfzGD{4~c?T;P8Mf=3{1NWM$@d?AicIo7#?3kUM<}Os=uK%%Fwc zjG#h+1C+#=!PnMpnr}x^aVKK#dbng#$SWf*EmY1T*A3Y0&yGkncdgM=Wl51i4KM-dcPBX)V@+ zm+Qc9zyp_#$X9A1nu-{gYJn#IVOLs#>JB2BjxS&}Kd7|@zE%sV?gupsz;!=J5~;le z5=W`~|A5Z%WCk~qm>^BZ8=yL$)tu=Jh-Nfn0<{Z3%nydylq$jtsfvQLGan!;9j@}(;vvub6-Gpl4A!`mg8mk~ zEhIn|`~fb-1z;UsCQy4D)@p437MufRaTDJU4LnjUiV7bX6BaDyU0k#sFF;#B9a@+EBq}#=s1z%t6?Mo_B>w0jEFR}KL6 zxWP;HK`I62fGQ0IX2&^@Id&b;unhPHFYsBQW=x=KtC+xpDvl2zj)GiU1=_3~=K;Ak z0z7B}SuP9Oe*!4;*qSkbZmt54 zsDj6op=L6G?#8qMU0}fgG6{737c=NsR8Wmm4_;gg+J6mOSjh~kpBO;LA25Ti=>r{A z1s=5rr4D9Yh7f@rpdbaOKJY9L*i07C$T;XqE$p%&OLRaNF@W63q=94|*nS?k6zHsa zSi?mDe9r{9F~z_=kChQ#d~ZO$QyM&B$>4~ZNMKi;D}nZ&fDT3E$Wns!kHOnlJV0Y% zpi}rkJ0@;0WI@vj3oM=3fOl7b?k=-XU;&-&o1?(u#00sa_y;7NM1Yl8WP$GVVF9}W zY%4UKKrXic6>G@$X@E9qfvkhv0LP%fGP#Lgv_3)s*#Pjk9H{*Osv0$zJRpGsyPTaB z8mXXb5g2^U7;Hh#&}HzkVgR|B0W>fOb_b}P0j;4txTybC@i@hmg)pd+|kWE6lL{s79}itJ1dOxfUD z%y^U-c^MoTA=}Ft9qYY7D~VVX7!^37(|{bVysX>`pp!wN2mOFH*g1j^kq5O87!_F^ zL1$#KD>8u+4|HG90SzNUc5i@%z=LNTP*qUl z8LSvQK{wx6F=&7ekkn*gFt29@?S2FKAEXO42*4L;fCB)up@T((2^IiMW}tP(ETE_b z2LMdFz#m8l2ND>dAS(b7CD1Yi6jmP?vS9b{fySB{>Ol?x53+(wkQzh@Qlh}(xC~N) z6ezHO+HwMr5`+~Tgc?kHm>_*O77b7|AZ=k_{RdH0xnOCXuDU;5eTV8ej@6pczsI$LR2}*E|^@dpr93Txa1(sO~;D7`3p$V1|DZzr%>kcN6 zcR|SxDbMa<0{7s-$pM-&K&kHlXsajK?`EKpY!=XL%?(f(fDHj(MUIqiLFdwfO#o@# z1G`NOlyX7Y8&>;)?tBFAg8`d%0wm39#&m=Uk$OP|1T6W2^9V>gEd7GazQYK1BY2x0 zsNV>$!4+6}LB||`T?eX(iSywGP=Um1#WM_ZTQs>ee&pKyoCgE6U(_lmU?eK?@Wa9BmN-pzZYxj;3${1qMf52z3Cz$T>3eWNB<;`Of{4Lx1y(BtUr>Dq>YuPds)$FhK><)X$fU@sz{JZ0Dz7ji zgRveI6OIg^BRWAFlfjo6vw)_66<8b(LIVL*IDo>9#nBQH+#mr+;xL2@fNL*MMrH21P#@C(CKmDo%`V879M%v zh}r?3#f6L6f+7zj2Gt81f!D6nq-mck^-%rv=kx?l#=OUAF$e`hcq2XQCXGr3LY%3?ai_;q?< z4O7r``D~_b5O(Nv?Hr~}5O&aZgIuOkMi}Qu9@AY$rpcY#uNN>$F+oHnr|Xq4IZXF1 zW;zKK*sfQ?#0%8}mbITgrIhIyR2HIqOBq}_SYZ40a;8ca#;@B0YnWI;dc$i$?%B>) z$J7Y6abi7_5EIDdOBtUQa7Eij_J(wi!Drt8NY6y+RBv9$oO^p z-!`UGAidL1b}-EWX-)5BS_7g*yO=hMd4^!Cm>=q`z z=?>jYf6>)|nkfIb2lg;Ef^5Fri?BJYpQ)Ge>-4FuObe#BOkmo>_;tGDM5Zl_U#B0K z%@j91WD?UF#;?;ECxe9=<}zh79@(xmg-H_>hCb7n>=`dk@0rGQ3gkG!3?`T9bEY#b zW&AqbX$I3X#;?==wlV#lt}+YE=AI2QWBY;GOk5yGoSp;XPKO%#W-b#qNc6`%rmc)$ zx38PeRKTozpP7*vG(5|o%i!S%TD}KrmVz+o2xtM&=rl6}CN z2G1aiXq1?EA=`N!|1%ak^11VZhMd9Us-OxGe0m4yf)dc;K=2|Z&{QGlY&p=P98ke4 z1KPg@8n6US?V=oL0BRb8RDwGn3>r)-pna>3Iyp>=jMD}GGD@Dh~!6d4aq z?_JC!lc)hU4P1AFbSN-6>cDrWg6j_rCIgVWKzZ8)tQKrKXki(wVguD%jz=J80fP-< zax};R4Z>(J**L09=ljbj7Y^+NfhMNGjta;Eb?HER6+!#RK#m6MWYA!;Q2=R&ADqYi zz?U7gWD0cE5C{vxdbJn0vXwZeKkR1LtOwmTt;7YMa#8^Au>qG~yTH@Hpe_Me44l&s zF=c_qD3}-&I2BkNH$hc!fJ*v}Op4%G1H~lh*h44AAYRaRixcdi^bEN?3RLnjg9IP2 zg9c2Yhh&1Tq2+W0sRMUACcw|Y1fQ}Bx((z4y8=W3*kPdi7X&VXc6{)H&YA(8qv`bG zeIrvC%svGcfnT7tuL_*H3@6wfIox?!6*wI)FoV}4K@1WB)#*w+pfZuOUV+o`3OlHG z4!Vl)0u;GLlr^c$Ww2|^ny)+%@KSx zq9Tt1rvjHb(;LVc*F3xo3S7$-*_@aZxj^G^oQ@!Kc^r9i6xcMFc(NQzK!=8KI=*1b z5||De4}q8s8ua0WSO^k$!=}gvN{rwE9!?F2b+F{;SkI=&!z0YCz~!XSp}^(D(c$!; zu~~r&Lo% zbJ@@U&CFcOm3VkTXGnqeRBd1Z4HAI%r7$RP);of@uybWN9Z#@EZumjX+1Uc{o zJ1M$398vS9bd2`PWj-37zXNf34xRH3pNE#P38;iiXcCo zUAoW*dI8}nNP5R^1~T+&>_H}fc(M)IhTo3gXsg4f*`1X1f@gJLCc`>nZX@&LK3Ir z1x`?mD{w;N8frCIydKoUg-9S-&1KGffl~n-92;27nQwrDkqK%D#3OJ+K7iK|feKE*MOdy@0 zf&y8Adm(7g4-05NAn0%`5RGX7WDFZaoYV0KxJ*?N0vE6KpfnC$5Ce|43(V%sKbS#s zoLP>%SxO*pZDh();&J2!H}k>U@jwZKBTGp{fd|yMg^ZqXD)4|?{ue;C%nb1KmZGR5 zqarBG7J#{+f`%F7GcP4EUM3z9ZXQ-{kpC~RgGK=rxp;WF6?hcHpu?MjuDtBr3W5rv z3Otad(IAsR^#(ZOf>IA}mVz+IO0bha0vuTiBJl7BWpYkPT5`P2mZcyB_a&&*XM?2D zAN9=U43|M1J_UY9fs!I6P}KnDI|`IpF`NQ1dCZt@Fhk0wD@&afDBRqrA&}G{3a-fdJT~H3073a z1|Y!;NP?i!4&;=2$A_%obOj0$$NelIbuSW80)b1BgNKXTi9r#xTkrup^yo`Y#~TP{J*Wu-uf{-C z)d_YUPS7@0a3os5n@*r{D{xE30Pb7`7RZTIp!5&20TeIHu$F@c(+Tj|kD%HH)H2~x z-~_E!`M?QpG=P#4SG_sY7fw+70(2-1wA}!%8bPHN_@-b)n*kiYun8nc?R|nBbWb_d z+nl-#XV?W^gIX?NBNR9_7|ybrF+pkq#|!LPO3a{^Aj4)BSaqOK&kRzvnFX|}i&KHe zis1~XJ;Y|l1S+^dRmBDtGlsLEwh<@|LW-{=AR9n(6Ihj)L1PM>8lYwp8@B?RD=#}p z0_;m@TLm;@4(e_3W-yJ8BrmDZ3Lx3&}b?w zZ-c@HlwLt&sVHI`Sqh+mRG63oXjK-p42C!#R1$->Tc2Rh64(H$o$Eo)oxlnn`ry=H zdcy{H#|t)Ocd&t~Z&2d}bjchW$WNS_%sZGAIk+7`(>t7?)zJ-1U~y2p6q08_g(EWq zXjwL=;~j8I1C(DN^(Ck|?)Zeg9+cogqL7|HSo95CDI_a`1VI^L0%%nUC@OkDwSp$o z33iClQ$SpBm_Sad0I3HpL4za<(3AiZ)DcVIDkVToXLBY7Q2DzCE~)?(Rp4~o0v7xL zKVX#8k;ROu15_EaSTQs(@o<6i2qg1>Zt>s(?K_0D!NE*WIS!qM0pCK$pvVT&aGnw5 z-&5?MmOQvgUJq)ppJ2CUI17rF8BAGD9ZQhvb0&D61#LS3&u@dGXN!~s6y0nC2^;xmBGYgOQM>I0p``3A`L z58J>~l~+J)1~aA$AezsL;S6Y85#)GAD~6MdpoDA1Z~|ls=&}`a<^v#R2k5HX9gN^? z2RaM|8uXAz1s82Az~KoBFi8A^1s5=Z;~yl-0WUB?y^{kV-yCAfQs4tuL!j>0Wv~H| z${SXdfoJL@KtT#Bkr76K#lZzMNF2#R&{-nj0vaR^avfyP8z)!;xR3@(K$0EUg`g2x zaJhrHFPIa&nh7F^DEmPP^aQ&(^9)e<^O`dp2GN|F%s-gT8BRml;HD@jR40J_vY!Pq z^#UsB9Xr87kZJ*xe?fwvw%`s>h;u=L8FZ5^D4rFd@e8tZ1B*FBBNHfkKm%bAkDP#w zd@67{u3*b@9~XmoGakM z0$EC+Zsi&@VF^&X6P$0L%S<>y$KryfbwDjG(8Xzx!vP_}0-%-^r{jfsaLWj^E& z4p8KSMiL~l6!_s*g9HS!>XE_*Bm$cDMs|yZIr9bZ9!*dk4Z5%jG*iOqxP=)!EW`&I z(S}q}e|kWTHco*LptTX8mOCe?$p)4axC0uPg;dyQ*dcStoS^oB0-Iw!w3Y<*^ud*% zk|-|&s7e8C*x}S*`oXCPs-Z#kEBN3SkTYP|5p*yhqgN+Cvq7qIHZvwr zqsghIp`qab1E`e&DU%>h6L=0j)tpnK9@I<`1kE->QX114&|%cz6bP&Ae+N+=x0@46+J6g|;!I4Rk4K$MjYIksg z91j}vVm^Rip5O#ulEbOVya6_51zH8ns0h9_fZ4I$hgU>_SwRxozhVO~AE{?k5LJNQ z(Ex6tF`F^%VF6WgW=uOkG@BXI7SKg&pes&6G^m5YAn*&4d_WcK4`{aqGE4v&*HGXR zxCd%ofs)D%c11Bzh(ktPG(c@(L6A>D89+(89=zfPk|-S&vXo>L_#Gjw5KvHoJ0=oY zO0o+4pn!(#NruF~K$emmsLO^Zn?W@fN0ySj0zW9Qp=uTQH9@QooC-XUd%P7Dz_&?( zmX#_xGAh=KI5L78e>{#lh%C(q3M^3tKKL00poT5C0-J(@0w1(9ssM>45XqJ$@D#M( z9n^#e6$qf_D`Qh>JH z*}#LJ;OveZ>jD!%gGivk#xv}YK~s1<3&Mwa!AA;1hBHCs9h<-pP=P7%rW14u8YsP- zUWCgLr2P3tZ&}76mp(B;!B>Xa=AvSjvqT zH1rGFT?y_qaD#kyh7B|V!UbZUKpJZ0;o=6BKhc6*xgx z;()qmjuRkape`D?kp2PU!#1abvpBTr4Nk!@HYiy_*^tx*|lE@aY$OVK5=-A{FOy*2$U_Ix0 zPDfBhjyQar)A0^ygaF!TfaMv-D{w(bdlzisLyjyZa9Re>2Xi{U1S>+G&E<6b2or;x zn+I+va9c4v;85TMEs3mO0b+1!GT&e_XF3CN6{x5KZvtq*9Liw=9W@BbS>R#{q!PT= z>I3}RFYr7_hB-56xEWN8DL@NPfo{<9C`dJ=!Sn%qcoet;T(8KczyQA4n@NE|fz1qZ z1^{@32ULl2I!@q%cM+fi?9gHp)Q$(wq(c;gy$LD|AvG+>fuQpD2Xq|R5!50E$Hob! zEG1@mSqbV1f}~&I(352goZR3>xr+Y=Kf>0c~{! zm9Tse3D71i&~z81I^uC;RN#ZvIZ~kNlo_1n`W70*fPb&J5BL0f~Y~ z>QH9QG?_KbnKyu1NQeov32e|AG*D*%)PMoI1bHYBBnUPOc_ zMIf^-aGEns0rkz`jc%m786e}-kl_1+)CHfw0_smf`{EGuz`+I*2M05#h!Lnqlx`pi zaKwNlAZ`U~fDC?s#@4`j7Zf6Jaj-#<+zYEJKn@1=Q73@fv7DOB6F}2RpuQmZ09pl3 z$1@yR3hV;6A-yy3NZ<}eB|b-Pcks97K@7fs8kTMu0)n z!jQF=;2sOi4p9FCY6qxdg;@Y;!{{((<&|m+}b244;1a7@&L3t9F$67z5?0!ffM2-@M*>1Hk;!H=+uG|o8uO+ zJ)i-|dPJ15f!3ix8a_zT%jUR)88p;%13aMz3SvIEK5E8W@K~TuwU@~V|!K?tT zl_!9X{$*BRb36i842oZfVsQKQ3|O!pBnrrpJqAOUy$pWMfWGHAf=`P5ir(jt~ zf&irhkgbky;ezlgo((kTe+T3Y4)DAd8>p&Z0^&29F)e`7b3k-Gj~UYp5Q7VRUn)F z5eUozHIKmq)*4J#*cHXyQv*$Ece z2oA_tK~E`UWqGkgr-WvbvYy9uo3%%BPyG)Xs;)tq4=sFLVs z0uA&?lz~V39YOULWbqEDJ*dD28^i_;`jlBS)c1l$iMh;~CxEmvB2P9z=4wI3_Y82m zZ#x^fweL8A30ydUTJqrfkOMN#i)Fx;M}ZTx=N{Z_1^Ma(CnTY6K@7jv!-i`??Kv#N zwSu5(5}_Pa8g($4GpvVrLy z4<7%ohc1!_C$J~%S)k36&}kdcgb;Wc3b^9=!k(qT2P%HSJW%3;4d!w>f)XEm92XQ9 z>)9alUkXBIOrSm_$l0I<0W@nc{{UqPP$FfqGiPo9^?+E+n5KYwKe$sXsLZ>-1>I4@ z58Zk*J#ive7~|pT3+Hf1G9H|+yObkrnj?p?CU_tOaz7X7Z2cpkAp%9vu2s-EehSR6 zPOred>HBwaNK8MR#3VX>dI*!U<_jj!dO9XY*lB8@Rm7myF{plIcH}T)k^tSX==g$Z zx?wVt%=G^uOq@(}nx-cvF}Vmr3taf7Am-_U(M&qERGSOjtZdkH+}9>W<`6*I!o?f0^H2?jCHK_jCEY~jCG)elb}VEjIhO% z4^XzLf@X_AH#b~sn%>yUB0c$n1*rJ~3Wq7)PbK$MK4 zAc&Gs6arBKiozg@M^OYsaVUy{Cw4j#-z1#fsqoqvM_(pm`T<1@LA<#}{DUjh&$V>4$`nj44I|yq8)=fk8pSoJmB1 zL4g;%cTs`eoC&;}5i~}_1r8MsMM;qBSQMocz}LKk9GwNahA3O$4S1-WS%axSi3zk2 z2eca<6dfE{knN!*ielhV5+*)o76wKZ&`BBfkX5Bz-~%K<<0v3KpftgXNMjKHiexE( zb~Atz73lmuF*7F6J*En*V38vreJn+guu))C;DRPIuqAlxs0RfIXl(%{mN0WGuqrTR z3v35PofP=$IFMIBEXau#AjdI4ig8xZ9tCE{20hRr2h0lfOrXJTW>6Cjbh95Qv_QU4 zU{sKT_yCjwOF)SgydI1f#H~@303DqPx;qPW_6j)4ctGb?LE@3uoCzcki8;^)a`46V z;2rItDOy$qX3%x!N@AK!3`!EI4e3aAI2gaa}ilmfu3 z7b7q`ih$A-=;l^XGG*3e z;!)xShodGFi=qT56l6f>+&GG4DX^P^_X9&SngGJ1+Y&%6c`jZ zKxdOOfNnT(P+(Bt0v%_~pui0}hJXRIxY`6#is>jYDDZ*Kux3!;H)B#!U{DYM%{DQB z?q!uxsAm8*7eV=j4U(6HK~qKy3L>Cv%Ag<$%B2hn(x4Ioa$E~+`iTM5Xbk{u{AU2& zr3X5z5j=VU7B4Vo$^nI!6sQF!t{?@ULI5uoV08lzx`==z>qQkr;IayApeaH|CI&m4hrBIczy*wN2U@-7U+=~Ob!a*c_HwP**wTMW^;hf=HOJ|KvE5g2(YC{ zcJhL1iU+Wh1t#lU(q!-04ysb_PL8=0%Cxa*@|g#p89z*3ep!L>(Bu=BeHaf-7QJG{ z(=+J+cqh3)mcX6K(O0a*-h;E{5O_cN{3AK`KOiZAHvk!h_9pGdnSuGlR~E0?mGai#kvh z!jL7f3&lpzjm4k{S1@M=ofDz}nIr&B-!em%6@hl~D1Z)~22I{VX2cmlL)Ks+$WRY6 zgCm0?c-<5zjWEf8GoB+4)F|lc1JE%Dpi^t0*#LBM1Oq50K_@1lW+?_omMqX&4ze-= zhrp{88Ng*dC|e>9>i#f!^$l768ITx-`Dn7u8;|<0prJsJegR%a5GClySO}VpWB@IG z1MLQ4uwq~Vl{?@gTtpytK=~R>A_AZ&WB{coxCTZm22k;&!NdY81;EFxfXso6$6K4TRD9RleHNlZ)vcVI3Ab$&FM6d)UuKvN@3Dxg*gc=s{rJP+{9Drn2P zBZH%YzZxUphj00$66Hz<-p zqXwX}k|ZIK3|*|m;3x>I1IqaZlb_yEXI}wHACraedO|Zc=&W>sJCif+np;9LHYojpTCm^? zGNI?=gYTaN9sR|u!NlUo;J5)~j3a{pEWh8ltHF3^GUGiBrpc|7weKm3f@1@eX23d` zbs0Nl$$XE67!OTWe5}BDc(T*uP{u=(XFRrH-vJ5{fxDA$KaOD9(KOlg$yLS=lewQN zG9H?&`_zx|(Bzt@$xvT|3JQTclV3lzl7xr20O%-fN64jEs{% z-jQa9mavmwewLrCdsiIP-2oM;Lc>XFG@n7{e&7!ASs0` zfhC|)Z2E#8X0dv3J^^>O1VCj!D2Fo(pi~!-F)?s`0-EfARs|-IQW{hif%K1^R5 zCbzw@3IQh(a14T58M+K20#hKZ08leUz#Ouq0#uBHvb2c6WK>CzAVxJkS>&w|57{eg(vTR>&^?Qqgg>60D(J``QMp9OGa?v%%%V;oIfytO2)`{h{Cz{ zot6^VrJ%tX@B||pFQ~H&I+t95(GiwwPQD9f`r0sA?!7_)xGBTK#_d=LT1C&Gzy_&a z!S$*Ft1d$eBP5OUfX91Sbr~8NLBlDa(FV}T2B1T?VJ>~Z0BW1|z1Lw{+&Fp9duhf) zlW)9NVfxiD`QLjnS#UN0Ig3?;DFsq&vT86TK#p{pZ1_P^9qe#W5Hlz+LRh>#4||n4nmMYli>=4hpmOX8Byr#GDz@(j-ys!)?|=02Oo6}ZL&B@f>$Jf z4m^gmS|qX@1rb8vc8f%oBPUb{Tylc?poCht;PEe%)~yz(*n)Ixz@|XUG^FC!iUHgq zeZVkz_h)saA~z6Tg>rym-0h1#>r!}O%6Mq<#4q9!|3LX46rP|)9IR|N5jZsYz!xRP z!;>F>iH!uuH>mlHD9!j8K&SVD;{PkC55tY%p9bY8ZYI=QUV1=7a%LEUljDA>Fzs!f z-nfEUeY)ucW?81sonVeK69dQy9tNkiOD-*5GIiU16K-Axr$e`z&-bmIKKT*@cQ4cQ zg&Z8B(>G*tuuPwMlIuR>is_Z7xH5UZfZ|mFbX}3ax9PT%m=#!7bT>3i@1M`CEPoT^ zd03k_1(G#DBefh^j-U%nr(c}U+|SVl8mr=Agp9&Yms`N>#MIU`{lEfdh5E-lte_EP z5QdK^e?Z(y59uW_V!O!%v@Fz-BMWf{0yAjs7+3@1E|VHiJ5qzG0(zH;0uyMz5qO{z zq;(}^btGs=1JsQIojnOUAO(E%B=}H!kjD@hl#ePPjebz064F@u!2mkoUJ2adhtyr* z90M+#L2}@6CQymX3>F6;=?$ueK?%1;sh$;dmOj`4pw0cD`%75OnL;3UpMXZYAnv)q z0K5EzS%ay9mkZSWU;rO~2eJY(?gzf0qy{{qbpd=Po(Ak#TF_M_jG&wEK|_NFAm{Uf zn`w?b;MF-wu)9dWXY7Cu0|hf6^}YhLBj~bT)VoN)r}KhGM42_2A26CTZ(vklR$w&; z-D%6Lz+wiv(-syTAl;q2K%>cQ0;^#|b`_w}X2&-S;JaiXOSY6)K?5J)yId5&dLg}A zB@T!%_^5iQ1h~?Jluibq9TcDqETEPR z;1pO33y1mzjF3Z@SrnM{8JB>rqQL1~&|vBXSnPq~9pYe4MB>8ZV2COV2iK#eIt&-j z0K1qQ;bNGB*`N*vo#+I%7aaJSpnL>soPd`*f+Ghm1nygaqY);gz+A7%YygTb1_c&t zMm^AQ8|d;5@H$Nm(78*HK{Q4)CI!$gW<;)QVFZr=g2pRBBQlyyHA>)|1imZ*EDAbo zn2CXh8(hf3LhTMj8w)tdK!H(z1(uY-I>8bUosjmM0%+4JB<{e@M+7@qDJbJYtPW7X zWdH}r1@L%-Ivl3E9_sQ7pe8eDVI9b2s15+%pw6tpxQx+^kxhZYkqgv)2W2X*EPX}> zYeoiWM6g3$3<*TgXfDVS(EdS4UI)7$&3esxi0koK4?1vJfqd)1Jq8BwASmb%bq3Ie zC1wq#21Z3t!eOWf%YaG@4oGx^+zl#5Ayp?-BiJM0Mls~vOUD*assv4DfNy314-J8i zv;m!I59^6S>UEF-pz!|y8+GLFV}u;J0~*#*Vw(PL0kb{h!Rb1jO!Bhe3)Z9{vr`FGC_l-d7)r`7IGpLmlgi|Jd#^uITmY?yvE zOt-$pq{?_`dg3i6SwU!ffmMMWR9~<<&YRwUi%Ci04M;0!)Ed+zwg8{e%L+cDm(}qG zLzcjk=@)M?nMgoR;RQ`{ff|(-N*o}{LEyo3+1pIAjCZG7-)0JCJT$%kHj_a;n-znI z0xM{oTL9F~)?iXFV-N*ZfuLD8aPuE@q6}y}4|FKMBM)Q=0(eZH#gP@X0s+hhp9?Gk z>cTODEE7O#Z-L?ww9^n2)8JAGtX9Dce5mtu+dE9A952P0K@9@d=@adl#n?DNJ;^82 zFUBzoJA-<$3XGuhzCm4H4h0s0O(3^`I0B9WpiN|;kv~YyEC6byLW>$uMr9TNl@SWl z9W_~$8Cj=m@w3U-TkwGHR{&i%V!^`)N+?WL3>J{0h8e`-0g17ISm1($6~qEfO**oH zSezhPb`XmLG&94j%b;k*UJT*F4~f_p(~}dK zH3Tk$LI#x089@y{MYidIIn46YcO^0l)U$(x!I~A=AnHIVBtwbakrgx)%dEkaqsR{G zkb%y@S7HZU5>cYW0kO!F7u1w^!I0(1AaDa5PM{@KO6;KN67Z=`3haE$yo|h{JsqIn z0nK3QGB7A{fI@@akx7Bwak^&`vy2QoFApdsfmfe`&gSA#U8s0N;aHQU#No)Oz%l*4 z0;{MMGw8r8_AEtq@ER~kj6odChTFlA=<`SdM;}i2vVq-O&jxcZDCvP~c*wq2P$+^b zE~JVQvPBkr*Bk7}dW4Z{1jF(aa4>++A%I64 z8zS1+rawqwmaAvuWdT)V?4Y|i*g*-)Qjr7V4R9`D0(*mvkC}y$1>G`EP$B_a2F@fb zp3)$ikC~Mf#aC>+%%BR86C~-#=gtedn6v@Xc42d!UYp7+ThGSJ2pTT{7kA*O0Hs)X zPGMGH)@R7HW>5sRj&vEatr(O+EKTMD(50i`bF_0nZ7XI4b}I%2P$FamP1J+ZCV1-% zn*t{yQ!+ZTSTR&6FoIG#>_)E z0!{@kgf=#KQ2<&Wj$RbhgASyC3c}Ysg9C#Dbm%R#CjNT?{Q}xIsxt0bDMDQV<9$uurc`XO;rp5CN`xA^uTfgLln9 z84=vDgX}G5Lay!<(CYw5eq#X@R^ZYMl2F-E6Y3W5r5?zo*?&f}LPw00x&vB-LsBX{ zw}4VAOlrDs2D4l}J1n7s3pr37slX)g5i)E5^05V|OAhKXutMjwAf*U6O+$(oEZ&6_ zFDTx{QM{O;)_IUh0c-`NVgME4;2I7bB+vp@fgMuAfy)MPnGUJp*da9>+_#{k3*o*6 z)o_vQs5Kn;fJ2nC+li~;z$0v+$YcVAj6jwG+w}LD%#zU-putvfDuh;{RJK4&!5p#@ zqXFJv{>H}0K0VNxOF>bAQI~;%kA;De31v!Hi;QltR7*b3UjVgfa>z~|>NIr3XEfaWMbR~|vH5VRg}x;_V+`t*Q!X36Pmx!Cl1 zki9bfDHod-=xR9uP{R+&X^wo5yF6tS*+5G_BtZ97YA}f?a)5S>@hdWOgS^WJzAIB0 zG}Z~e>PXObGG9NUAp}+wvzd`*h6$NHcrK$iLKr>^imr-B_?V$jz!e$0v ztPC2JY!$L*%urwk&CEjTJakWhyaI9p#3PV?5NLiv1~gc(ficTb1~guR>|~}XkTEN! zJ&fi|JzzG-#q~<8W=tJW?iNNRHZ!Ic5RV0Pj{u}q4LVht8RRR7gB-!bj{<*SLs|{s zumoQ-tijX)4T2U%&=d>kMj%KNehO+3_Ar9ZIbqgho>9-J$OQ>2XrzHo`vqI z0Sh-!K!A3!utS!?AdLrt{0goR!8a3WGBYS~gT|LY5ydP48mDA(P~cwf$X5tirweMi zLb@T$j(b3E3SvO&jzAK}32+(9A}|-U#-7_z27aIb3ux5@_{s_v1@MIp43Pedg*g+4 z0t@KmQqba7mg&3puquEq-~m@@2f)pF&@3Og2MDgn6qp@R0>rV05wxri944S73khOK zVgiMvBeNoCTm`iH88mFd1|A6k4WckWCJZeg>uI^b%kDs{@|Yb#+fX5)$K;^E4);GZ z_?|pS+Y7vU0qjRmN-_X>4wPC2u7dIksHg$?9J*p$0lX9rbWu4wWbqngU9zmZt%1S zIM^Yow(zoo7Nmnl2$*1t&<~(oe%{Ju%?L`v;0-a%j-Zp#K~o4_kSRv+T}%s@lvp6M z70ixbK*QylOk0>h{Z3{_&}LF*O{O(aF6eGLP&U$JS^^aTZ7hY{(2bOCqzeJMJXazMG*AOI9V7s1H-lOrpza&^a$e+yHK=XQVa~h)lu26! ztQlv3X1GC{E15xiaZpPqP*|LR77C!Qbv@{Ea!`nZc4MLyOm`T~nYMuEXEd3vFq(s| zTmW}gE--@1r4?Wq4W=`UpkaDY_<|Ds0`NK4;0OU(bq3@nP^6)iORyLR-Jh<(v;uT; zKeGnY5++c6#SFckj2U!38zh^6yGx)%z^noC><%VHHb*u^&^hmnp#B&*mO&8%Dw{Y^ z$|jKA(3*k+G&=zgM34kWmO?!^PQjfPB~Ea>fh^!KXFdU1jme29oIuqCq?f_$cm*8y zNSzHx+4KNU*~ALDlL}NefooZC%TvRgsUB1~v4QiYQ(Hqrg8-NbI_?CLZ5>sz92?j` z1IrAcyIdfn>7YAALF2NJ%UeL@0wkC~4J>BI8L$C%kQZUOT!9&yY{1DBlBhx6t%rz1 zg9thKf|4Eh;$&t=L|O+0a0g^Z8aOF}QV+N!g>F*=34#Lf0;4(e3{X|YtjY9*5t24R z;tfpZ%nO(xDFZwkSkH8V5j0Jv!34^AkopvK6a*Kjkp#N^4=Mz@4jWW~Kr$0JdrE*Z z7gP!8zBK{(Ezhv*tHiCq4vTP*?JF3~nL+pKfs+WN;s-6m1}6al=rze8A3(CM0ynZ= z5Agk_;PF&Yp$ZOu@Vbo|jG!8Z0hIVbtBF}5tBJwQ1@LNaW=-Y=Oy*3Wd+fm>1&JO= zgefr8JF0+M1@Kcmz+DU-s1T$o1q+#ggcM-y1_sc2IM8Gu{N4tzq7$I&oWZ3WOedsB zfz@kUz}-Y>!vnHc5VVNZ0&Wt#sRhc3j;x9tNR=DN*WjcJ_BFU#WdK!r3ZOX-$ij6N z&`t;N@@!CD%dE+)VGdq*&1TMIpa5MJ3w8_4_l`Q?IY$l9;4nlCl#_HBHZUS8MR2+W zCu7hEHmJ5vdX0e}(o}#}n3K7g*r09H=|{J*3)X`M zT0xc4Bv6eDYQBM-p}|xGy(~?E8MF-(QXim>>^Ob^XEr5JjR0#WfSd>t765JF1UDu? zTMfYJ3M34=FbQ-yB-j(+xNxio2LL3C!qOb55EKAK`UdE+7LYv!pfRHf;F4F9sfE#; z`2!@AF)v^Qk0pV|Qo-3P1Cps47(v^dKrXdgf= zX-FdzoH~_2c^}!2;PMpg^C{qp4OEbu2)U z3MzIo5G@T*WPoeF7xfJ2ZSop(rWR-@mzXpC0S7W@cN2#h(+?;o2UH1u0dZK&m_9&T z8=#{kK?B;*QVXrt`v9$Y!5bxhfTKo(=?kM`J$NPpREB|D%aD6h!AS!&E&2yiYJqOv zRpfMJRRmpq!w4QZ2M@?gWPxJ_T&6+t5Y%#L`U6K3EX=?SaDwYLr&i*s zInV|*nJmb1cU?0;cYWOZawWP=rJ zV3&eRF=%5w0_0L~38ql50G0r4$bpt?(2XLXO@xqgjT5O{gE$5n0iX*z6kxRwL<|&k zx(o(LW2wTa8H0L zBo-_ck_J+JGyz>j&nmO!d8N%)6A;q`?vtv6Sr1w1m)K35< zXK?%WG-L=96v!G(OF-ESbjc-bG7elwO<)8SCrHD!pe=VCSxTVBGDr?~*beAsOpug7 z7WlqjkQDq>aPYoIP(u^c*9FPI&sqW%d`cXkih?lJ228bSjfq6N0Uz?@kEo=BDWVLgs|h&wDGO(l@KIkJ>k;fFu4 zDe%Jm29lJ>QsPBzWl5MbPXKKWfXz2Cg7)JhtYt7~2JP?S0`>2}ttMz&0bEEhI0{H3 z4lsoV1ElAykfp#n{lF(?NmH-`Kq(9qbOn&43_92eJOT|82L%u~bU*{N;Az?u4Ab+2 zSS9KW5b=!^bsAWs8a!yB1R6R3MI^|s6^x*ZSU{aOE>PHkH^7J}FgO}yK|&U6w+19) zz}^Ej*+G}sfH?}xn%vBw-FKjD@PKi8Lo2hoD16Dk40y&DG^H-^etKd9vjOA5>3MTl zv>D$|4`^XlW?I`ceg7O5WyVX>FElZWF}|O^p@mruB)YJTS%&e_bo;q1&W!J-7c?`g ziGjQ3$QOpPD6k3KoxY}-*+>+A4=a*|k5MdqjMc)&)U*)QhuAG7+lSbK6xD~=gA|_+ z<*)}SXjKVlY3lS{oy_4(E1I?ocQIQqG9H@l)6EQ8E>hIZ94P|U3fgmn*qwD``u%QZ zvygM3l{1bEpb`wU=#|M)AWPt1Lqh|Dv?7zEjv^yyViUAI1hi5zOW-)DaSEyvz%i%6 zBmo+O0ws0m<^r(xJJU0Jm<^Z~Hcp@2!z|4SvDVc^Bh_>6?3*jkrLCLjz-$KvVPdkG;&M)0@vR+1Nih23|b~c9P>8 z5JzA!ctH(#1Rk_)i6slP6OYmH1W3}63%pj<@d}6|u()Ts{VG;b(JdgJBeMb%XtTi% z5C+s%q$4{-*-;TU3?G|zJNGzW#Ap>S3yFK0s=FkVZscWq&xr?6om_d=Zuzs1!bUu(^D=nNgK3) z#RME*?FZSy0SUS(V8NCHAR#u0#b6`~?sP?l7=* z+dx8&98l{(lOzg^j%&bzTmmzDrh^0jF=*VF`ytcxg%_A)rUyJ{;(!Es`gtZ{`LAFX zh(JwX1TAJ`bbJaH1o?OR%=1k0^*6zM9#kKE0ec6<2VfzA1>jI(1dUrTI-Ue;1sT=Q z0NO7J4!R9sK}oo!py?t7&@yh&NGGFX7g$;Z;_C$m4zM;bfMV3<0+W3G9k8u@q&WpN z!65)`p(rqd7HJ>nVg`+H!kZ%-1d(su<_4v8W(6it2N=BH2Rv5*T7_26qyXyCf$z_j z$P!ouT1O7*g+MSUAFlu(TgB{nhc63U`2XPsAD7_xf*aHyR%8NiPrbkg?iDdRu3!c+ zpzSnfN02zUe+UwXboW8k6j+=CRG)!HcEGpbz^ZF-4aRKFe1Q+tLEr}UEidq83G_mm zP9WJA+)8Xt%%JPhK+PFYe;2gQ9A>2g_*@TW&_oxw!~%D2AiWfD%?mP^MS<1v3KMt= zs-6LKPDBTIqX5XU40_IFQkQpA(L=Jc; z0y1d<_KOmD)(hM=l7I~NzW{eHERbRk6Pz?CuLna3WR?tN!ppGJV6Emv@(+uS6hrtTgfJgQ~v%=s7oJ*J#nK%^~9a&2h z8JQiX_wq1_*F)}z1hpYRWt>75_`1df*maGpjw>KW!0cE8vV#?I-~ecn$sLqA6~G4! zfR@_4V9J4A=g7mz4atwt5jN0lq#(2y-!L3RwbsAO$U`kE+Wcp~M6^6ccPTBj~VM z&=oA8B994_L780!3PO2gTw?CL7rh^c3^T)01rpH zfR7smS**d7faaGFP-bA(V2S|w1#$=jcnkkpXjZRha!>@7wT=t+fSNdxjvXLc;3Ks0 z&7#1Rr2t+L0%}h(W+^e5F+m3TK@*#B7c*-xB|sbva)mAf2gKRnLk>6<8NsgSWrXB^ z7s%i#$XaG@$9hnpLen)4H!y&A(>6350PT-~Ec9Ro9b>=>k2CPZ0cd`h5u6P`vjyNb z72vqu`$I?pT-I~XY48)lizeB zHl~H3W5lkqFAKksJVQH z0n{F1b^P)F|9|E}MfQ4-a%KncJ}U(l#}ZI#RbX+hmyX=r?dk^?IwIj}+M z1#scZsKA^BZv26EMJTd^=7QdmoR{aIN3mx^Bkc0 zYc>UzECqH2R&Ya%0kn&PMS&Gu19E^5sZwH8U;-EBNT~wkOlaJ$WoBdnU0TMV!Nj4& z=sJB3FKAD~G(IK=#zWH``M{S9C-X5GGai~gosUV0@zC^Ld`ymvho=AGW3qv5iDgg( zo$(G@$HUFd9mvQu-I0q)e7Y((le`o(HG?WpMbMs%5@;>NeRFyoHPx3ISFdmxzjt9I4M1&ViS@D8>9t)uw zc$s9U+j24aF&>)U!^Nb-*gSnF7n7zA)T_*(GLHv-dJlLq4D9s+nAbyKA+*er6%?X; zpBTlb=W;UnGaj10mlN!a`w)tei%D4mYA%DLOcvOj6sS4V1s*U3#@z>1f{F~FwZNdh zk^-Z^7pMqmJs4=Lfl=TsXd|m41E?Fvpui}w3(5s`c0rqGz~vE>;}Xya0qA5TCQ$wa z^|AjPn!f)5lb9c-%!NacsvVT8!5eUJnlS^Wk`dGvQOR;#GF|y0lPd3pgAfxGm>ich zOh4(xsyyAtn^ll$R?l=tA6Aj+^B*$hsz5E)PyjngMuExk3aFGX<6OsYH=_JQ3Yp}^$0bo$CiOeP=~+<(L*8jES< z447KDHaoP0B$4pv+v%rNh zc>f%D#02Wf7od6&tPDHKxY=PfVS%V1687m43MRp_*~O)0^KzbZ-7^N;?wx# zI9#J7XgQ_;%n{(E2Hr0;y>AjB$o8gx)89R162p?tHo)8uw{$w= zLKaahDkos7Onk^Ips3^o)ziyCLXLvau^Dh_!{|5@EXW5JgpR;*WI+aOTI#{_ zqL2}rFQ7yRw;mMf;GLTgr7u8|;PFGAEJsw8pjbv41v&#($pbO-28aVUlLg`>nDtK& z*n)fyIwOiF%W)5iQt)`wGLVoX+ECpBupk>~m<&98*#YK5gKz?f0~&M!jm6c!mSkdq zE-h$aa6G`At;7eNy5a*jxp}f2cY#KDK@B`U&1wO|K5RniCKG5RR0MJQqW}uZ< zd`?W}OiP#)_#9810%x)XObUDoV1vw8l?gq2M;oG26Gl@%^Z@|%uuUeK(s)uzQLFU zwHnkJ;6vCAI;T#9sh&rPAJhQk18tw;N9-Tr(_jiwO3_#8oZK!JvTlmY}nM{O}N zDDXLPfI4V=pcN`Q3VfjUwu%BDXq-*~bk7QCxQ-7rw=AK+2RaB&K!Hzz7j(oMp8`AB z1RK!JZ&`}`(?8}j!?%1OEQD_L0NcjQ0E#z|E@n{FEdbwW362<05OFGS2`mT2uL7Sg z!vZEHR?tuaBZ#w*3A|_$XRW~2VH4sZd$rg0; zf&!N#gTQQ95WHYg;s*5>L8Awt<%i(Z4caiP08U&W7AR;LKrs&rb%o#!LJua9F zxWIQ#FoK3EgkWMq2r(&`m=s(Lbb=k!kqR(DK3#@|Op2i0-^^AFprb0;tw4vWD1f`+ z`~u%WwJ{{8m_SxK^Jy>{D6l);V1N&$a4T>)LXOmAcjaXRuTn#-f(EtLz(EX}Dnd;u z4b0QyDwrjlsSxMW6$_aqAW^*m64l_ehZNNf%%Jd?0VYAw4oc-qK~W6yoGt?_l0lJ1 zStLW^7<^bBAJLJ_%&h>4e+7^$LFo%TxeuDWg}Ml|#1N8-z*nz8mVQF?2*C7!vjOM? zR|bW8h!i+egNy?Y$tnqf^9^Wbd;yb^F!+L9@FGnvkU02UNbrhM@WMAC=<=%SG&_6V-5#?Zraa40JXe|t~gF$C7IqJY~4g_x*fozyg0jg*!wA2Uy?>LI8CB(W&|a4GbW8 zKF2!@S&oRh&1ntj=1*30aODQ7J3$p2tilUH)OP{kY7<;{fwG4JI17Qc>hpolLD<5i zz~_X$y1T#tuI}pLCE5a}EJ$4oO6cIV<6zJ8X@Kffq`lL88ccJTK|6au3#j-sm}W35 zaf7P71B1qBOwLBYZejv#1{9-1FO%g8|+s~Mmb z>y7CjiZh6I7x~!txaAp;C|>C};~kLrMXB9415%Qk5})$H@3JnFADgN%n#Q=W<5|_q7UK z3cR%f>pya<&2ksM>+VUSzGdPB1 zDKUU16hPquIy3<6L1^Q#M1kE=2Y!Pk*m0n9NjXO%O(!Vg4lqMUa=Cx7FtWn;+Aw4* zv8#Ztc!wS@$K=TD%gf+6160N;GC68P4ju-zDZ#C8@ESEm&}IaICeT4(0&k!#aCQwQ z0asoI$HP#K(qN6C_yirR%BjHW%?m2hL3hw8a0)yCEfj!A3MerK86GK~wWOavZ+ zECK1~QDgy89EyzKCJ$`A3*^{fkc>b*=p-;k1$G5?O(qd@CKCmAP*dLkv?CI&DnLsOeo%SIktNXHJiT!-^DAXYT!0o|fQ_0A zYBfV<5uuZa`_F>s3;Q5P>+v%&fTr*6P1y5&-pLKOS*9mVVoqZ`IQ`@#<|4+6(`_a* z+c938UOkz)it*y~ZE~uL2Qprpt}u&PLw5>TFU&M?1y;u;V3Frg^Fh-C(E4BC-t^L0%<_DYkOie` z&{*{JMYEV47%xtLJd3%F@#6HX+00>#7pEVb&79A8aJu0fW_cy}DNIaeOdLp)1&GO? z>EBeC6giiGZ-$o?_%K~Tl}QD3aFUxUlL6!R>E)_S=8T7?uUBQVHTw?AA&Q&|i~?<- zw9V}Vy7rV2)cp={T`=IIC2m<$3ZTmb2lcf11*0qESI;|CDWQ4&>Dfl~nN5(O>=w)z?fTM=}y2z-5> z0vq>~>Hf=DBXL0;~ z5#%Zjfs3F4TvuN3LaZ~rATgNCPmt-Ld3#3aQCA8K;QOgBfII5-%%J7ppp6&MY8rC- zDWf9}LqKgU$cz$b3Kz8az!7}O9fJZhXuydH67b-9$dMZ)0$zcHWIkxj`T_&2qB-a1 z3qJda2UgpBV9QowfD{7)XIdH>7zDn7st*MQPy@yB&J|EvhAc2;&|m^>L16&Rv%w|6 zw-8Nt=w#uj2i9HBCpcV#0y#~`9RwYJWP)CNz z0iqXTnd1YHMuFL&x8*L^|saKL0ZvXodf znL*pWK-&dCmNA(#H-LshAb|+FGYYIl;3~*lkT8RcT7eXS+zVgP>B|`AbGKrWGK6LkCe?Ky2tBDk#ttz!71_bOKaUGB}<9t$pnP zsbMl>+QO^=y6c*02{R~tK}S)U!HKA$o(a^i1WT}hVrBs|qFc$J!L)`6R3w1Upj`nv zl>(ak!Mm^Duz)gw1}F_`Fuh<=Vg^Og2Nrm@61;2xbn**A6DX}h8cmKHE`jps?Rrp^ z3QG8(1Piqb6sk*@!5g2zl|RUTpyUTKAC%xh35>y!0ewPBP;mA239ksIjrDg z%-KMTtr*RiX0STG0A*T7V+96KQQ$ZO%$su!2_0+YaNP>BO} z+Y?Z+=xBoCw)zzyC&HRw5FgH9b-V+L9Y<{xrDu>;f)hNnPKT&cU;y3TCU65(UV&n2 z1}o@zUC@aS47v<+SV89;B72>+NQuSqG($aNWdO4k!yITB&j7VO!Kxik!!KTico1@@ zCuo-&sGtL-9FXaJ%nVGR4k}m;)Fl%^bvsCb1{2IJpv(;^E@!ZUj#E)$MhSn=IQ$G& z1yDLzz?_8=Gc#DBcfNwc7JSeb*ecNIKPzNr6~YHy5DIEYFeos9C~#~wfQwd8%4%o_ z)de6|fb16$_};+Z(7*smPmn}By+MdW40JzUJ%a{Q0~0R;sKR#?0bivk0;F}3|1x3ybUO;Gubje0M+aax(v&htr#AG*^aB3!Gj0P z&{6~BY4DvO<_u>+s|Ga~mNP4|f@^6|(5wL&#A3#@0z@;LLCOom`hHRhtdLzY%nS-#N|T|T$s86?Ah+{?gO1@WivoiNLo?{$0B}_d$-kiL zWgTOd0)sBYBk+7Dk0kR+xl5eJfOmO6fJLy6_IJzN?08pe8;X9B;ppxeTlM)N4y#y|T zcYsSW6@j~;ga(qG!O9B?2T1+_Ee!(s5xlMsRPS720-sjuIHR65%kja70}Y@=3~F0V z2US!M{h(@3m*EJj5*z5O5K#1dU;>@G0r80nJo$mv&? zHB#&11{3Jq0EjS87Wi5?W@sXw13FC_RGT9TFWoH1#n79@r5rCXI>MHAF}w0|K`xb7Zm^4 z18(AhWCXxXQE*3x!4V__I*$Wl8mK%6xeFQ-@N5f8Tad&LYE!Xf30#MHbq1>vJE%AT zMHi@%$_CO7YKVdxsfZ>kC?HT8sV7*F8>#i6+6$CWAAolbLz)eah_Vf|;a`CPWG1XJ z>i7ekjo&~oM}{UHQ1cX2^27WEE;k@Y2Z0JrP`Sjsfe}&`fy+~HgZKbrJ!tC(bX`7J z(E-ru8BC7C@W~cNS6pmkK;2&ChVFKd0KB2Q9>xQgk!bDQ$qfw+8$gK& z+RnWI3c7k|Ll@j=g*J3SEi_0#pf+?t6%uIvWDP5%p$lq8I6{{Tfa(rN%gT&t1*q)= zsf|HJ3V5jks9e%ux`JpUUVyY8VOQXQ8<(IQ4{hi+FhLr+9ZUopx;$BqyFsY}9L_K% z$UmUg9H`w5ayKOTKq^tVADGOU>cO6P0tz=!;|<(eUjSMgfz1<;KtT;w*zD64P-sE} z5EQbIz8h))-T5WE0(F(?Ef`5P?+@wLF0Fe3%v0%k}6u3*L+fc2n4 zlP3#Q3(jQ(r6Wke2(A^@FlIS|52OU0Ysa9#pwGC5(V7t))2wC;vq6nW22JJ}jOGmU zLGA^$lfgTYV3`{^S%d0ZP_TfzCg8LWYC~{j)gvof0Xi)P)V_e%N01PQBrFh{F-zb8 zsEP#@Owi^Lxb-dyZN0xjYQ2L(Zaqk`B53_FsQtinhY@rRAh=sKhZPi9j`a*y5Z5zU zGt33~2-MI5`GytJOa@)G2l6qfAQFHzin&1r26FcTr40+}+kpqXAn6Zu0u`u4h6E41 z6ajf(AWI3<{sZ+?93l5AgUUZ}@gM=(gAHk#OCV}GkR}DtX&Vq31<=$DB-w+SO5oF{ z7##l~N+$5|0eD9`gJTOb!W@ul@L4|$^^QGg;tE+xAn#2<2!kr@3ryzBppG$!{RK9H z0O}vX%T~uVtXT?(a(4?W^n4L;nY@QJ3pDxI5*lMT8u0#c=UHh`w)Ky~LGMkQwGG!b~r2(*M3v`YXoW(`pR>Ro{j^al;5f>IW@ z0t+uE=)g<{$A;+(9ht->K_LsS@F0U5ph^iGrw!9DIx@-DgPX{plpq1B>Opl5czPew zU;&AP^@7B~s}VrrptJ)L0Ixv+34p5!(7hkv{G^fPDD21}Fc;Qt(gAgvK?lo$M?Ri_ z1|&h*8njc&k)d9b;SE9rQl)$b34p2;EOmyXuo-CG8F)Bx4Yb+-r2<%?2P$P@Ys{dv z#tKmR1?}j7hetrAFRa9^2Ti+!Vhyd(LzK8Lz{4Y;ctol;s5U$Tx`Z2)xZ#}?fybbl z1Jr+*!O9EjE`f3wxOf7Ui=ZABJO)8B;Mf7lNMs?6x9ta)mfKmuE3`ltC_&oypo|aB z56mkdhy60>)`ME+jD^sK{v1|CR#2%r3v|W{B=o__0+fc3k_Du@2&qp%#RO>U9;mqt z5(hgKq#iYOfHK4a&^_ajasqBxJt#3jk{Q%rAU}fyQ1ydyJ1C<$c7R7fAjL7FK6(!t ze1LQVbQwBWL7f0yhE7)SJ`ZNl>K1S&>tQuxngGg`dq81q#&m`SbO|qm;{?_$NVNzm zTftQ!G%Gvq0VhT9*oy+VT?lPUpd|_gaOWJcEQA3iIevlE<F26?pZ1a!3S0&KJnbigYp^3jItmVrYV zl)xa-0A7{04lK9>a`+lpWGh%?KNBLIv6?Z?0{M*%S}j9{cNyn_LLCxakf;OYrw@${ z4WQm8q%Z{a6hJex42}}es`CsY@IjRwXhH#!CNH234S~nLV4X@(_u~mDenCYeIBo@2 zfu^HCdjc37(LGiV_6IF|2JJ=@@D`}I3C=R0yo1YMpgo^k z3%2Y@YVL&O3rG}0q8k*^;M@r+(q6ED24NXAnBK4`GJ~dz8S6n;-Liug6*4%2`oW;K z7N|G_FP8(?Ezq`z5~y4N$!KILfwrb12un{4B#yPCup(0Sd$FP_c zHaeuqyaC!>hZeW6AvI7-k6}KmA|IsL2pK6-04K(JkkQbQB5)!H#i%BDz=%PC6|~(N z+&g85v}2eV6gU;Y{YqvA1#U>MotZ&_R{`9!2Yc=XYnB2J+}*IYqdGK89Y(Z9LFN1d z#(HbUC7}GuXU4D`L^FT~s2Em5*`Q)~2Pp4?q7j_Ulo)w=L5FlRfQ|!DU~pW*3UBg( zT4JC9iv`R`!^og?-2t-IaR!Kl4LCzaF79@N>OTfK@`z@shD32a7JUREA9kY)xArUQtE+!65AYM>z)xDnvi{RV`REl5i0A+r&n zYlU1PXXk@cGGv570AnN@JP-^Tas}lR&~a@iW`PFa;4_{c;IUZHjf_YVpkRcgNYLh6 zP`lB^k-_l-NT*{xBewZTCXk{ztf1B@Xv5`hP|Ffj!+@`$0GGiK^Bh@kkG4e8ktS*2~R6!-9sTr(}9XCOP`KZ$=dq85a#0{BE zsZd}pH1H3mV2nd1(~gax>C0+j|xO;%_*RSzpnK;=8Un*l0a znHR8{GcN#@1<<1N2lxseu+@-a6x4XW!<6L+9@U5RJi*~>#snJwP+)L;0NO7C8s~tR zV8#UQq`<~JzzsdnL4RvNb7YVb1=Otv^%=keE|3}xRQ!RP{|cb>)s9C%iUr`gP63>V zC9;skK>-3fz#23btHC6Lvcy1v!Eqia(7-KF1_h>iC&n7c6gZ?!jn)`tg!C&NFMw=? zI}y^A0hP`0em`VgFfhF@UHf=PfX6$Q|mJq8UX9)W)# z&%)LzLRzcPRUDwIN{Izjl0cmaI=0`D0kY5!bOHh!w*m{K-~kQpfX5q|K`Uy&VFp@^ z20*8*k4p3nWJ`D@hG?>E*69CsDE#Pnl7gG(OV*{bJ2dF^^o$!TO2Fe#N zSh57xLAv3Pg4uBmXhzym1)4-IfO!wDfz~3xayrC&n8TuwY7ZidYse2G3+s%abt#~I zE^ypK3lVVqGnz5ggZo^tWIh2@Zo!jz13V`p5+5ulu3<)6ijS|)1sTEwrxMUu7J8Sf z9-6@@965#r5vU4jVS>bV0f<9*;JBWF+tCzxcpWqntqb0Va1<06kl_*yu)qO?0AzE+ z4uk+?bHfIN0AzE+3WNY;Ey@Cf0D~sOjO(EI2id{kw6&q3;Q||EIs%krKxHMQ5P_~j zAv(yxqb|rJEqHpi^&}0@lO4(BTh@d9s|f`SA` z&DwxmT{1CngX?gfEYK>{+C|KY&?_4u!U9#vQGC5 zs9grSV*-2x5Onb_Tu>ZTW9_&-y>23qwWqj1o+>|n($w~!S>1!p|RBDmqs zbiWnMh9KiWw{O=o!7kix+p=lNkv((vu!1h!?tQrQ%EQ$=7xmSH77$Om@Ok#^4NIR` zfH-FlJ!_lRc6gO8NZr}SJL@;ySo7mIc%ku=_GP!GwJy5q2$H&a;Q!Q*56<*$0~>LD z)wL66|NU;y21)%pzj*rXH_PW;W8kjmWpG;m`rf7Ye>dIVRu7VFK7Z-Kjb-1j+yxu? zZr{1)W#6WDJAkB4A6xb9$>P^jmVgybf4ltrjpJQUw}LI$(>VG0hXt!{x`GrQzPaea zt)rW_{QyOX)3fH@-v=ITSa1$(;-t>)OK*2iTT%{EcwX?_{s|o&8&_Oq;D!a{#g)ur zOb2dF2h)EbwA7B<;MGo`1rneUVo=n9)qlASQMcg^gnk31SKNj0uR!Su_aOW;P`cwj znD27rK6Y~(9w3Q>hUOT!`9P^c06wA)=1PFL)7w@vD?#%d=l~6n7^t@9mICX5CQVSA zlL4M;!MZu%DkVWG!No!Ys1NFhW)0$i4zQ81)DB*Y3N?}wdT`aA2h$DLFbgyNfYM7I zLiiV;^dBg_;}Jys378gPd<@~9fzlmMAp9dx`U8|+^AsZf;_38vYnY{`=d5LxRNS@n z&D1Mj+CK;eN<(6iCCiaPfzb(mh}CrMwaha0;0S|Ct%Y4LA1KW&0rEUl9C6b;%q&pd zgxqCzyh>xq-Me!H=G(HDk5 zX>J{`GSGYn55)Zl$4pmT$Lu_vXB{(-Cj2n2KxuRXz>x}05}@dx-nEWd+GjerbjA|- zIHMSB3Lt=BV~7=Q~p(8Xs8Ot5aHfM6S_ zO948+2z06qq%wmg(&_WpGs}BVc?RkbvI@)ttpx|2N(wsVfXQ(tSQvUF=>iZ(;5VqN z>bL>Kb_88A&5`A}1H^$y2z2&LZ`{DFOPPTusBPd4Y8&{1+6Ml>Fi?2bOg0Y?j zcA?sb=>c1qMHC&mKfF$5bl~ z>8bN%IX(udHDdxFfCIiRLxDwsNnjDE#|1hj4RnEqzzPtLm%))qkqNZi2YeDK=$JO9 zEPmf4YmIZI&q^n+WOCF>!UabyYfLmZ;Zu!5NvG%Loe%dno=ilGC{cHF=W zvPp@_jG+@EumvK(XvWYBy2_Pt4fu?^b$iU#F(AJ{JQ4cy9Z#6UMkWhVwmCTAtyyV9K) z6!}5jc4o&3%+p_PXLf|PE1Vb=`9a6C<8&zK;D5@a0^-n}V25&o9jeR#a$E;9FErh1 zF!eA)9V!HO=(!!p4iy496nsD}N`P{JQVi(I0Z@#9Z+Zi}7aUWdfpKO{(A|48z)4$! zNyLn43Ye+M#AD9X17b3nF@bV|;}3B3gG@ODb|@>@q4i*g{$S$e0*ya`9Q}t0>QE7g zLqX}EBTE64D1LzNmH=H-AnK&hv0UIAX#CKLQBg!ebh(lsXkLIxK@i^4QD9aOF=t)@ zN$m<~IRWe~ZUyFgN05ss@fSGAI+(Kr&Vq^oNRb1&KG=~(k;Rcqk;(Bm$h(S+JfM`I z$;6`wzMufM;CcFlUCgnrE11oh6%-gCCwxK|OoB^d15lO$?eKxk%3FX0KtTeZbcbEu zbYi;EZf0eZFHF`9nFN7G}GcZh_xSLtM z9^^hpNZ|xNKN?bSDKdg4h`?ngxG?_>+LHQn9P|$CntgKuYhU=ofQYk5eO?_=VgMCqS5t zpyb}etjGjbP!B4wp`{$C07W){9h5im830y*WIH_Wz*hm`(+O4pT75tL#2#i*CGf?S zEfDvCT+skwf}Q$@Ns)<%dHR7p%(C@N+>mI2jixYzDroScYfyNB&fjDP#S!?h66m4E zJdoRWKwkO43LTT-Uckc4SkF|)Q4hW0bpcbh5)))gpaPTQ0!GlGb2C9DFQ|9`?TFN1 zTENK5z^cIHxQ21M+CF9_y(OTHiOBmLLFEP$=$ipKjG!7-fyr?LfQ|}KfUo!l?aN@| zhM0MG`lbEMfiB?Q0BGOj0w!1(9gAfL9T^Y06qBu!=MYPj({#HIKTtiWuwUE#H`2;YPNx*LV?*4begIXhhu#f9}^=38)yLl=!|Fv zGo}?h3XD#S=FAItK;?v^Kz*4K7cYY&qarux1`0;U2N3gk92pcjL86Wfio75*nL+mx zBY6YVsbWBW2XgiacF2)mN7xkwK*~X42iTPaVLszGV|oJef`A#*0}#z;&isN$ zfp58Dy`X{s*tOt={vaPf`FzYAEF9o-+B#UW6c`=*R;$a7kzVU+nq9EWXPzJj2j7gD6 zK@hYOgC9}%K@>7-FfHLx;LNU9-~&~cN&=u`UKt%1@MI})DhNQ2dS%pLTEL?SwtfYV zA}6;3FX%J@UIlIi&MXCf1p(O3E=G`^EG14*^fEbsY-CVCvJs>Ylpqwi{CU}V7`VAX zDwrWEl0nlV4Gf^;4tNA+fqK@UMO=)I55R3a1y)D+W($azK$ZflqYfxpA_AV((F7p? ziW^o(8-zdy%k;p*%)<3D;811NWD-&216@EQpa{N)h(}QX#N$w80$=|IZe*_j--@8X z>Ufs{yak9Ew7U}|2)6wx19)DF2_y(UGY#aVk4P%_GJ-_DK}0}1Llsyx8R|pLnL#lL zVrPObBvxS6We8Ce0$CoQ$O)o+6nR0Eha#5(DPd8pR9#+ud0hoyhGofK7 z#s(H}LPJim7^xaL>0!@Upk#+P88SMq;s)gdlmrb;#P!@fY~0|aw1fxL9%EGCMoN>6 zAisgKH@5;Oq{IbHscJGGU{_)XmARm>h9(I{N90Te5(L%nj>vfr5&+1)ZD6SfIqVNo z=7R)43%DKzXKPRZ+=1pjP%ea&EEk|9%Nce>0Z;&(UNuAJk+7g?h|zH)k{~DzF*t(AB%# zpprq8VI>DR5rOkDw(tanA1IG2fsR^H;8v&?fH!_YWi{yNH_&Ck;8GZrIr*5G7?~Kj z6l2OP~;)lvWR(REeGZ9EiB1=gS zDg|$-GJ;Nb1Z}khr2|NuLYE9cWWaOW5Q`w|6v3u7@Peu%CD1|BkdTGz0m*sYd|-2a%3rqf?Av4M~i$U<^9NC0$7BZ>-zECqy%K`Jy57p5`7F8_tCQiBM9N=RhqXFyV^0%N@< za{zeXBctO5?kq=M(Bd`7nOzV8jw}UXnB@wLn#>mF%om`EL4iR4eC`1#`#oR=Rq3F{ z2`Gx0K$-e8Gral)Hy^-)-w}cejQR{8nd_|?LD3B2d}X#~1hoP{^*Cr00hCaGK-#jP zg!uui6;kcBuqZNvto_5R$f3Zf%kYI6bbN;<^9yE0KF~T-Nb1C!4M6$+0drP8;!I44 zCaPrvP-r1iv_9hsZkShf8CG#yF*NZiFe>oXn=_pOo%+LX#&iNi3z#t-0ntomOb0-l zyza0=lLNS3d%_Og`vB&>VTUFJFz*YfF$sz)Fz*jL;sS9-1tBYj9uCmiLS{@IAez^V zsRcxHnbk8jfEbLBD~hjxtnBB=0)=T4FSO~S&)C3g&Cmt!%n1N zbc83l&D>a$+;)T@D3xu5M}t1YR&MKhaFWwxUcn8jS9BRRaD!5qF2fdXP>RxE+QF?T z2uf*txIrmRgXsV_v_;DeN`avE5NsI~qvI6F_!-PWN<6v@4B#*X-yIB2|Dbj>Q{{zq_a{=&C-egjgVrYH)LlI}6mLhGYZLCP zpux0<18RZe0f<`gY1XVrr&&YVeJ9}R&Op`GgN8tn6)G?~-hjxlf(FhQHJGk|>;oOK z2g)6|_tOzd)u!x}S;ypuRXS$nCle2iP4sK+B&Q9e;q+*hO|ke+zP7odTod zNp^4p4b%)&VANzd$ZpR30u)OiqZvULqX`@X8_%f8bc9`zkI4aa$q2;#;2>jE;4^1x z0SyK4n=v);fXh1pUIr&7MLy6F5hS7o9C>m;8SxIc5`UIsNfv0iuVVvGmcVrIm=M@F z&^Qm&5^m6dg#w?zUXZLJXmcJ^U{?!h{|i_I+>!&0vhbNRPXJjDwh0z~GawG(TMh|g zh-W5%_Q(qC04?tW1rVr8;ssSxf577j576tfMR6_PgXtXU=WbAH}GV^m@D8+kjMfakWxIA5ToNBaNX9x0`fA%!&|^2 zKj4R2F@n}FLFyP-69we47tHmbGv*;t3o0IwYZOq~E&q_y!V45ex2Jf@B1; zlmtO$g3=tgq~n0;;XrIH0k^v!@IZ<=P}YE?8Q!dV==lNQM56?5#j+_tT+0nI72KEt z`9=`V1Nj!bnFS;V^2GxlkS8F0Cq!!iGz7;1atf$(1wTH3(GesLc05R2q#iLM0+Imx z7bF2cwF2aFrX@_~%%H(Ph|3|(ZgAd!IGYpH_y$KJMDXrqh#XIr5*u6&k_D7N zRq6-!EG2mV1XLx1I;-G@4SSXnqF)8lA(5pd2CAMpvXsO@aS2W@59+~3<10xhFgkW{ zWGP9)WT53GGpGd$isKiM5ePO&PmYN}K?t(v2QCLwzm`-vcD7AOba0 zTtN)Vl2nj@vKZ?XI3X>4kR=P4%pt9RMon;M_ywpr4$8HV9n74NF+$K)n@)_N>lYzm zqX0@|pcqDqSV%lW`^HEK0VEDi2q5*KMi=B5I8Y)3A4YKkvNZE=0Z7u=xJWI;8+ z1RlsZ3Zn+o6dol`Q1L9FzzH8wft1TF2t^G%3W)I*P?w#%9(4X3XmA>2+!bz!8LUWV zC@FNGX^FF z0R?Vr1_lKIP{KLDZqC4_AOJdJhEbF87&~Y&F{1)#R2@_sh?p_G01aHTnlU{A9gzTT zI0~Eu*`-(yt`C_MnH?Dvxk0x@fh9pLb4FMVBY>xdfy!a4VZax}fXZ;DEG5vXrkB~# zJ7=JwsCvii2ysyV>>@j&$8wb&G9sYMaDg4v{nBJU0i9Sl!Vc=5=`vhlR}=!p+zob6 zcT9un4m+s(ror@p9nx)k0v#57!4A43OM~eRJ7{=bgXsf1s12{d^rfC1)ach>`oXRU zZtVYIR|Gfm8#ok&K?b*QDDr?h1sxoqPJjZVV-IBDkl`@6m7u}U$pM*{0Tn)w!XH$~ zfE)b^{JIPbO8k&6;2ZGK843dMM)?b{K)nJ)9@O-1;8hZ^W(2jDK)eS$O8n5Sfq*sR z8&JyOw`P372s&Hl=%WVqJTDqx8W*LtLY1*g~t;AY(f(3A({U|4~l zpjr`~e$94x)o{5+--2l-NW=x>5Bn443rVAiGw8wT9 zq#4pd`&>Pegfgh>@kpdrj0@0*^7(<6tn@XVa`3(F}703v* zK$en_0;A&sg4m}$M%ma-N3WAarmAK9Y3%m&P`!-{K1~3AOungZum5CKn`4~2RHdZ zZ6El)W=2q=0d*KaDRl)mqDcZ8^G0uyfIC;<`J)NYi=QBMF?eYY%48#>22%?{Ndph0 zb6gMVkAOPjppGs#J`1?>D4@Z_ z05KJ8D7ZcZO(TMC>12i8GXSo`1rc>PX#X>}0yi(HcxBXNB)%dCHNPPkG_THB2%1!9 zWnpGwWB}hI#~=W!%R%QsaG=%YJdnDaLrI_>bQgfL2z0+%D0L7RCHApsiEQpj=?L~hm8t3ZN6 zK?&@Lr7$ZXA)(8#6(j(vL1B(q3le}hLXap&fDdm#I07_BA%Tbv(EOhUlMKWW5)emh zgINJ_ga*SgkN|Q>>;nlv96?-kfHu)PA{+sVErBdYK1YUn=s7)%8cZS(M+iV1aSCRI zfFm1tYe0`DtAG=M?v^?Fdp9JH|rJV3^z!L)=4oMl)` zK=%@Wavhc&h8T?ERuFJh$O7v~$Wnr3GA7U_Kaim?YnL!72!L)0VSx-`fjX7YokpPi z#{)hCfUsL>;naE(+}Z%yCJL!~po4GFB7jkY=>aor3=q^H01xWnw@IL_^y9^paWi?|0O^AU`85H;gT15pKSKtB9%s~eCkfuOE4Gs>F zfuN~7P;U;>vj&yh7r4!tAMhv$fvznFCHWuRS&-9m!J}}F9I(M2U(gWG3vSRg5sZqg zkRc|}XdbvhGlLOy)f~J&0f~dH1Bs(r2kPj&;O3sbFp*iZo)f%s2z-1kC+H4je$eH1 zoC^E`kTqDWkYn&c9p4sEHxJ}vCIwanE(K2bP&P=i15{p|0JjgWFd_|;fJM$AiR=K2 z9D#|zhLpih-2)Q^cg~o$fX-3`H7h_3iWAR4`!Qa?mUe*x8Z_0S0Iu~R4L;D26=*>l zc;E%x@>2i@AV`)e%L&p8RuEY0q|m0ow6;Zw&*{bc`bN-gQlRc}n6v_WfHZV=i@}M( zsbT)9J@N{iYn?u@)zvETDeyTpbS~a2A0{o(2x@SG`m4GOD_E4696<-QDlj@u-~lbk z2KS#{gXcd%MIj?-u+xzVG}X-L_#Pn)>OQ?>wytM{j9}_Byk)j#Yyfv(UNA%YPY*!L zuo-n3-Y`S@O&^#c{iZL>kbct-W=Oy34>M#rMFR_@-_*ha>Nh#!=)@om@H6T&)`NQG z){INQ%@}>g2Jr0G0uT?@k6{J%V<15*0KVD-oWcug zg+a5J22&3&xX|Ir!7Qfg859V%1ROyJZ817dfEX$O9ck|Y*^21gJ8~+rfmYI@L<3^F z4J8_o=H2Q+@$iw^8XgUxi8n|zd|(FkE=`%9fTO{b=>hnHF!1~}xcB*k8PXg5!wl)3 zwt$u)GHNh&ut1`x2RiRPfdv$u8cb7IAidNXETG=02GblCMK*7%`>09+kd(FnETqJbh+=pm04o5E@~;H- z9l+gTeZ~nqO7#NBk#Eh29QBTnUN5+34ArmCxPY6g>7kyymLYO#U;uUf(NY6swImbh z=1NY`MtcP&M+SFzD-TqogXRSo6!_{vg#mkuz$wrG3nXP9U{?}=j?pSeKxg`ep)>uU z@dI}7a5ShF1R0g#1XU{vB7Ds3jO?J(2$>udL>&vVlmr|>6)9-Q41PZt2M6f*bum|7 zb_H=>Hc+3bUKBh;%jeF^rXU7dWhm|nS*8XTX9bC~Dv0xf&r=82XOKBX(0MYf$h|Dk z7}5cD&?(`d@eO1dP>BdV{*sd$>{J$ZR&IfN-3|2(3=G@~pzO-bxP+R*tkcLQo2%;qdzTS&Rfg9~AF(J@Mo)G9_ zFjfUN(4}BR^(G7;<_AEHR}h4RA3Ru@K*7qSP%q94I^YHzg}7pknHd^uObQUy3UE^x zL8dS&h`WMLwICJ|7wZ7rnI6V#3cHOB}B9pR7zZIe(C1_d970_a3y@KQ)n35^KS zdWymn>}@s$K}Q3m`%rm7(|KH=b*_*GB&fNnL=gW)ib8N*@_o5P9$ zJdD9-&I}$bVT0yfR>;`B<7M_NaH$C{(&|CWZNQ@+jQWgE7_AvDf<`^Avu7cddJr8t7t|Y3U=r9oea;)^Y>{g&=fAF4J zNf#>Q$PU`62s*QdMPN2)L;&J(DX=(#R(*m589{>c zL4u%O5~DY$6kv9I!;t0F(9qDJ0GeK922HYnqMkv48FYOl=u`|4^AAH7q>az)SkGw2 zlmMDmWd_Z)C@?xQfp$jJWeMB_&1HZ#vBW4bIkJGxdt`>Lq-0b8s|8&S3R#oM47#ip zbXgEo0VGhtK{Sf01Fd&2l zKx1PN;S&g9(DKIsb7l)r=xZ`3KzDg+GB+@SS}Dw$%pRZ(lpueB4psuMz6Y-%WdLcE zFlUlbU~sHgKt6d`1Nq=#gDl8M7w8mXkPZfOCJP0~jx6xmg&=W|;qaM0@ctqTb7s(G z&YYm|2k%S*Zwb?6_AqAxT{Iw&rN9O0CqV+e9=r<-6gc2efZQ(34B0FO5(NjD5;xdG zpsTqdfdCF+B_6OS$Y}|nyN5yEG00MY*bFj(8|(&yTffwRu7BeOh&`zBNj9Du6 zpv1z!eVCbzv7WIGf|+1Dh$k>+D=|Yip)fnP^I0>3;#4CGbbEmUlfXGpuM?DLLCHje z7bFL|ZwtKF3*-ey@YM;R?I$oP@Tym^6nNTNiOn3ete6?R{8a)H^%_}@D&Ph@Y|9pC z-wn8L4BEF9punujqyvst@K!}w;^qLQGX*wqfPe;}IIl`t{zeUG3s z8$rtJL5D}dRca_OgERyvFo1#)bdV)amI4Pj@IW^)us~QcSqf|rmI`bK88|yZV)O=h zbDl;Ps_!4bL?IprZ*l|eUUbs{%`0j$F(|Qt*7`zy#{eocFzn@l*$ZV+C+w0PzbeIQT%v;5mX%_ykL-fDZU%VgSV%DDpx26ta}+ zL7Po2vLG8kAa`stgEeY^rvAYiO~8@Q1DZ+%g^vX+czDg33qX-?qsRx@0H~3r08s^s zZ-p!c@KxH(AdUnm&cLM%Bw0Wm$dLuwhX_j-yyl?2g%BR20$2%~0*4)FnjTcnffsT^ z&9}&MQ~<3khuUBPn%z+n03{TV*DOFuPe~AB1lS84paFhp@`E^Affrm%Io5;1K_v@x z^(gpKH&BVe6k-m#B$i)+8&WPP@W4+r7l0H%%%BAWjL;EzA<$Mf@bC>tGjjpRUh`gVL2C$RrTYQ6)=30M5|?t>}i`HD>}}C=N-~ zKfuWsJvB5if_AK0WH}-y1W3|==U8Z@@hX7Qw2lHR+)>cX1kYfg(g~E~V2OIc^v2K3 zDva-^FZ;}FBn%l5Vgru|v4PH86}UA0^=D>nrvDAoCB87bFus`{`-NFk1JcY?U~yD{ zwnO;AT@7$ggIR%H0NT@NoZhI(AnpPw zINuV^$UcI};SNAcrcj=rX7Xyq=Y(}H`7^uFl#U#ny&kU*%0K8 zgdfcMP_KgQnel^Jj}vai^o{(?B8-QoKluUn9P3Z8R=uChj)Jh(kpO6eH@F4V@RQj< z07;lxfkoi|^aDSc<(Zn>r$7A3Jdg3*^oC!|;-D5>!4wuX#3P%L@!h`%(oqg0^~t8ejt3KrAV61qaG~pe3~opw7G%gMuThS$iI&1~fjd z%TTYt3zB9O*a8v*HOfHip#*+{V~)v@!HPja0kn%0ROo_KKy;yN(qPho95~9P!K8sW zAsiIp5HlPvg6}+H5&&DR06Kd~kr8B;xGn>_VW2xn8>eUNWlWCU4zf~#2~^cWYIN{r zyr79NMuAq491{O28vhSyVjD?*CHSZl&@ng={Tru0T*@jV4ml15A^aDtt#Imj7K!O8 zf0-=}|GWX^7bZuJEP-zzBNQ1GnBW;zff00zFY@VMQ{IBF?!DJJ9ds@i^y*&t=|a=_ zwOPxcDZ^ps#<5U(=YX$f|b)^fk-Pbfo^{}0^$fP?wNjZ4U5S1myImShS;@(j{ISCMA3T% zMelNE7R7o<=Z49_@d1M)2Xxq+ffsa@sv`%itW#ic?0E;8CIpxHETCzCJFqR!prLHo z9j*!t+~E+PgAPnW_#DJT_Q$r==7Wx1 zLYRL7tVmgvh)8(ycDfAs9C|pZ36Ko z=tL)oUQh&scrd+;3Jg{Zp!wJr@1X(5h&xsAz;!vcyoV$UUse|OD3D_i#)Eipg$fLy z`kK*k2Euq^++@ZCa?_Rf(<@n7bP;h6K8gxr6DaP%T$oi1jt5|NFgSwao+Hcg3XbT9 zx&h==h;g8B0r6m_F~S`F;oSk<25@HzPr$%+Ij(_(3)?=B# zTQM*c_wg_u5Fe`F^_D+JU2?bC;7&2f4x;2eS zpHat}0d!6*a~7y>29FYfN-YJb3qYroaDrOBOrYiiD`@c+_zFQLP}@vG3EWNu9Y3r9 z7G-dh0QJg1w|jt;bAhIV!EH1)(C`X_BS)43yIDP0nk7qt!;ArRfjlE*t`j^03hHpf z2I;`9J4abiItJ-<+ybf$AUrNJCKhnnqsauCgaKOtDs!OCN=TOmv=3<>Ue`0)ZSG9U7rg&IhYA1#sMl< zAlqG;L7gi`O$G*Y<{Qikte_4Y=#Ur0m1e98OyG4l8VanSlYu}X0BX2H9SS;3AGGv$ z21qYBjj=jf)Pol9gKY;J2+^p(Dli$;<^qkkSSYfCrXB*67(piiuq&`Su7GVpzX{pN z4RRJ(5VXh9@gb7n0cOyK@0Um-$H5{WAUnkw7!+9RLHoV~!AH(8f=2dPL3a8mvVbTL z(B5+mCKp8x1y)Ta8%0h91_AK8FwjPDP+yHlffaQB5C>@P5|nIM9WB7#5x4?(J!C~W zs2&G58$l{S9e0Q?6tZArm0)oRkZVD{gRd++0DN*N3uw%nMS%k}Y0t>)z%=<@iC8^65rP(-Dl#gtI0iru z4pm@s9oB*vjRkFZX94ZcWCu5)SRnBaI%w39QIP|bQdvNgzTBW8TNVXwXzj(} z%FE2Hz@fmdzyg`%1;r~Q)q%G_2*5UzfD;2K>3~{5;KW9~WT(Jl#w*^p_gEEo=rybKAFkgWad|(8l z;|r#oEG2I6C9#a4gX>ux|FA+PE`Bg&fzmRlA8e7OCnmUycWABP(%&cKfqH0tyr{jt}5XEKp$s-lq-fa)QflQ2Q7$`Uh$XDlj^N zN4!AZ1QoUljEHTwO!c7R6V#@M8vrhJ;K`i{w4MPpvI1H>4r#3mDF`}tz+Awsz^cFr zEt5d`1T;?IC;_WVAX!ZyOMwG)Qxd4~0!1`P9cTrdBS)5IJycME1DxDeFe|Wu69ec3 zFmP%Vm;o9z1r-XK%r}@7L9>4>yrAo4IKi%AasZVUUsyrydj=5m185r{EK@;bTi76@ zzN{Kde^|j;jI~6O1w2v7IQe0T1hkU_4i~UA?C4&Qc@1oEqyK=6W-WpDcNEwaxZQaf zd04@R{1W3H1p$FSAn%|WT+f7IGPn#E_yj6Km>eLJ0=%HogIR&!Q6WnaRC<68e_;U+ z?0`=dW(0K`5XTmS*RU&sYPo?*?CwHBLkq~2i96a@{R(l0%#S#L5>o0 zmJ$azr_{58HcNqX7M~d;M}hV@GArBDqrh3v zh=n4P0uw*D&kY`?JvZGkf<;*UJXnfFfrTHT`~p}EtQ>UmwgRKT!|Bx#EP5i4Haw^a z3A)kHQ4w@-{q(&NEJZ@s!Aqz?1*~JkNASHg(;XvO)S#nmEUvsP+zKq9o#g_TrdLI> zm@qZAPu~#962lHtEgZ$7rv@<}biWR0%?_IaDcVbx)gLevy3ee8&bjAn{851rBke@-Jz>S^B z#K0}U;K=B>1nik<$}260X3gz#woFWUwOW zI(r3X&`A~$E@*g%BTJy8b$WL_i@E~DAW$O~VvquZz*Ue!@K7~K)unnCHFbz8P(ui! zN|6=RG6Id=Kr94JE;0+;oG#zMB4%_0q+gK<)J_83hrkG)bYb?Ch6FOGkb~L*8pVV- zCB1<~qaI=jC6=GP_881!0m&D>OtiUYr9%KyI zg$kg%kA6&F6vJZA_F%Kqm7tD6lKA3;YHND{(k- z2)qQb6gaZ8lsF&;C~^w?0f{Mb!DJP=9Yx@59!CK6PlOVj5ivMBOD z1?dFme+~ssfy>j+C9;J1f@4k*ym$d(g%T}d!v`}etdd!rAyHw45etebELMgPkAm(D z00)C26Ou=nkvz)c2pW3h5O_JgCxyja8C@GQk~UU|w&~AOSOS<@Tc=y3vdBw8gWiz= zbWN24BV;v@BV(Dsv+0GYEOJaOtRk zm<}*2FoGgX;L7yRX)Haa_{@j;4P=TUnQ~9&ty?$ z{5L%`lSRi4ET#mSD1l^V(5-Xq0+&F>fb%a4!vCO>6QuAPND|bA68JuSeWIlsvWx@Kr=odyFq4o^0I>RJ%|Zf zXRp94fb5gJY?isEU@s^zLh>@WjS3C~(145*ha;$8EMKU^QX&8eW<~{;l0t#k(;aeH z++-nUfx-tIkV>oy?2gPOpmfG2@O}E?9F|tb-_td7SptN?mVmm1L`Az-_t+ju_($z zGn@jWKr^V+1NAyUhvGA6FwJ2WXlb2pkk8`DgRE$JYd(tx$VKb(S)}V*L7J4<5Lru! zC)+VIOA&OS86(VzN}RCBQsB(aQUaB4NEsx{Q(B1=8aKQOoC-Wpk1#?@S3a0#MSg@e ziUQy;Q-PF5f(oFDhy`MZk`PRTf>5@Su)xphxdkkG(Bgm}CZ{NXWSAh>Fo;>g3PK8e z0zappDqvA#{5Jh#0ZR}!IPMieL!fV``xUb2%7O(1et-fMR7E;AFoCiWctAto^7I*n zEY0?iq6txAvMaDc-Ny!Z1BU{O0=oiZc9s$gQv89~-=;?uu^1|T0@=U|ZgwazLaPK; zxNVFAm!_{NVhLpYIsIP|i$3G;>3YR1%F1BJfjaqfz;W-$SOgx3hUW}Mf#1_hidl>q zuTNi5%%W-mNgL46Q)CAn2nkvt#R&HwGu%dY1!e(A*~lXBdpc_gOFHB4?YSi^8q98x z6wV6w8&aB3}(tW*X3G=nf#0U|4}! z;PZ5WDi$?vaQlmwU4c#D-E_w)78M?FbpRUmV-|Qfy|9YKRqzGK21wDP#OlZ>@Ob+1 zDi#I#w;*BAf%XdQ5Nj0JKq(4zFmFkgz|ZMy)hrPPV8?ob&YM?Yfv5uOU=jEN(yajM zZa`QJVD`o7ebp>7yx>TKDV)B&n#Iiy5j0UAB%zQyh})*pV_IvjUUAyXmoYEXvA|{syS- zV1@=KlL9-G#h?IUU!1shJFbW(1b%40#8Kx&RvPdwk?3rHG$f9L<0o28G zM4t-=^(Gh{_dw*pGhL1cKpfPGV50S2LD3u7#3C-f66_i=&|o8Y0s*wm0JP|&zKKPh z@&EMYO)U13jUY9kZ91UIwLZ|;9%$5v(XoH}|0Wh=rXL@tKWJu==6eF_AA`~>sQ3GS zdTcX`DNd~uP_!~Wnf|AlMV|cuDBTJi-LBNaqRAwE;%-wT_)0Cr%789VEziB4W%|Mk zOfu60o-+we{}9B%GTo<>MIc@QG*Jl&u`Pc0nKpePAHi#QIvLLRV0g`ltx?u%~1B&1NJ{C>wHz2n=$|x{7vSc~l0dXK>Bpo1C z5J!NS0!w?Q_xEzh*B=0>ag>Irf@$D^>J?Z54FqP017LwL2dqgDV%`Q22kulRRF%Je zg1iq^i5jrrqkOqOfE93o!V9!gfvJUYx?u;4)bxTj7IFIzpFz4o(ZZ4C_y@#++rtR4 z2e$U%3P{osbdn2Cmg55u2NWbA6Q|#5W8s(R_yn0>=hg=gemNch@g4tsn$FnHqGHX% z-~_)kid&nJ348~)fFqNe5|aXBA!tNFfeDnoLA`7ST?P+F26si!{mt(Q)bZ$s4i+7? zDPIpXFeoxZ_D!;6DKa_U_yQ3Dhc{Sc&X?&-oh&&#FF;{$#-yRZsiqF z1|@n&8|dO~CP!%KStu|$F`6^!fX>T-X$7sU(Z~{*)ieEmCyS^yrpgr12^St>EHW)OiKVy1+H;bJhOeYISCr_5+jOqKj zSyXwZKoo*pFauWHKFBD| z3BRyy`ukL_7{-Is7y5IE3LFL%q>wQ{Mn^`0gVPJsxE?XBY@NO_n#qL|K3qC|!X%d2 zAmPL$6yd7LEHWaH#azfXzxac9U6sKvW`9P=Iy}bJ)AOgWs6&_GF|L|6mE{=I>elI4 z7va@!W5lth4zv;nR9ftWM7xOsXoCY!mKl=)=#on_CLc%wwozbmobVSMbrxVH23cm{ zdoUG1dlD?NptmM7ffliX7Se&%3owA10!*6B3g!$3A_@$S!k~3K434Z>3QU>|g7Bpl zprLNiq#byb1^CV)CdUiY7foleWIQna&UBW;qVGX#-arf4Wx&^XfEFzZyq})fz^pob z{wx*_#)H%I=CEipzMme@!mP}=diuUOEGmqbreA1c7Gr!reM1Yg8sqBeigQ_H881z@ zpUdLR_-=YZGqai)WTht)(p-}xqrlziKWDQTi9+tBW(FNA0J@I@mz|HPX(u*+J|@zi zk4g9E{<$oMjE|>(oXcXY1eq^@?CJ)M6@!-XDnMuXl~}<8zHakabOa#km_awWGbw;N z4Ndb{w1pv}?5@0Q+zRXpY~UG$1M^ry7!OSsozJ4A3Y#=w0fjH93B$nch_ZGGBtAW6 zK8tJSm4<^2435H(%Jl_^1Fyf(YSbMdNk>rH<;ik90^-0`GJ&=`tpo`<@*^+(V|1JY z7UTuhod-QwP6f76#OWRd5DU$r=$aTSLM3utlYc0WT#3r5B()8!YlG&5e9zEO`+lkw7Y zMJ^Uerh~21ZMawz7%xqaA@v8)=7yy;I;I#vwObjUlKvO0fOgxZ& z6O#rL2WVfEz@h2(%UM(zKTc0w&Qi&EZ2JA>Ec!erKqi5gnF?&3F13QimGRK@gcU5g zjEAP5Tft(&egh;gux&c$N|tGGCoNmaVghv%v*YgRk5{rNGi~@consY?j10JW3|cy- z!Q=wEKMQ=xl>?|C6F4;8VHJxG7b z0n?310xU zQlu2X>)k-}OiTiomfzUQ!Wi!i={G5YdnW>OK+3?gOpF3^A#BjDW`WP3Obfa~S%FdD zFi0HA-V0)bXF@^C1{eiapz%LXci+x(fbr6Fjve619@QNzo{Yby=kH)?V*LeLf;?S@ znO$YN)J~Qx#_Q8tce2Pc{+hmYCyQr2`nu+g?Vu})5ta5!kc*IP{tBuikob?#`FRrq7Vo&C{zVFiTC}w~Ix96Mi4+_UpS?{)r;l_jEefMV74C zI}k%9AO!)aa9YxQ5VRT-v{4j1@ds-Ufty@1@b)66#y?Hy8mC{p$RetOsqze_$_2q3 z*i`PoRB0H4Rb>MfmGM|rzJYid$%E6kUSjd8?`;8> zkrOTmz8dHWSWpBm2<;_-dM_LbjE*P3(xBc8XwfW)126qS%|!)<>E5eYIYrliWE?^9 zz?0>;1H=J!azI5tD>%hWzjA>^d-{RPELJKDKu!af`=Ay(NXr$72(r(>;fks91g1)G zxMHf@fkh=KTrpLyz*Kqi3QGXv|LIa!Sw5?rXay$^0Z2*%t)hMb5dk&QFSLQm?>E~G zud&#GO8C6%EM_vRKv@J_+$t~%z&HmOKv#XOnttFqOAOQFw&`*=SZ*`*c256&gC&P? z>GX`7EYlg6Zo9?ez{vX$WT+x&If~<>w&}jNS=5*wv`sI)&0;As$A^=>p0N&uAzNq} z>)596yUmgb8o^vKUH=Y?lo+T2V=`mn;L!x_i`&5pvUh3c^n^Pss=7#bigK7UPXM*J zKnj>0C$MBeoyx4iv;(|6OLcnHU6x>w8`@O3X|G%ckeO zWU1vvF?PD=R~8qD0li2D$WNDgz!HS+KH2FLU$EGNRWqKQe(nK_J>%Eud=FV{)FAr> z6odj?d6_^CbUX;MQxUXyN|A|29^zVs=>-p2WQ1j5LC6d~n;x`ieEa-|ELx00pxV!I z0yAjy*8>*t(XZ2QK4NjNzX&Rs!Ta)=9e1#1IjRW!2bI5|p<@N`m4pglap;MzpwlV9 zYk`;@L8eG!Q4A7C94rgb?I;6Lh-@O{^x66b23|&PCk90!(6;~Hj)M&hij0mnieR6D z?!f}v4qA;3b_{6gA7mX6L|g#mpASr+<;~EwKoD{8#fBhp_ySt+&btpx=FB@lJDVS{ zfHdx4&8ipp3~t4MwSg|BWXW=55;y~1Ys2h#fDJSkr@-uZh81>35kwGd?-f?qDlU-W zOh;JFnGb+(eBHsSC=6;f>;WA_!>qw{fK`#viBS=JqvsCDT5Omx^-3b3E)jSOBS;GD zaEP_=BaT6)Gaq0xXWjwYU3q{7w3iVQlE}dU5(hgAI7VM4A_!qW)TXcH-PZr7P@lRQ#z2-v#Lz8(2D<}yv1h@FQBjhIk$ZaWV-_hbN02|kE(Kkm05%6SrU~*T(+p4qF*`9RN`k^` z`o=#jCDJ1Bm|XxqvPyy3@d7vyl|-jI{ADo_f*l3T?6?DRM7GHEw!bW~iqMS13_5KW ze7R%`C~~38%^X=2rKYcW&muit{vV5|k~EJrx8q4@@)Lw6KN(PN0wonjfu)_(mpx@s zXIk1h{rpoFB{`&mNdU88n$G`>B>_|t6+UArWL!0U>2nsP>GdC396)03&skzoazBeJ zuiA9IPmr>U^94(+7IHDd!pn?YI!QzFyE=qY0Tog~DCLs^tbAg9iBUeGSS#YnD?i=m zD~qGNh#AuZMA7s%nF0+I&wV$2N|C+@ar8E?oF8Gqg zDFIV$D$&8|Xf5HgL8TpFa65i>r_vJWWILfP(z=fS)YR zO!M2O>%U`BFvrYKpt4y6X&VqIOMzTv0xHNrWiF_!pWgP4rGimp`u}$_aA6e{0k&_#!cm~}~EHYi@ z1&fKL2sFM#A?1z&Gw1?ulyuC(%LdLM&@3Sf_7RWf^rN3y@=$Vy{B(ye;F>$^3rfz| z|AnO%#Y8?=UO7Ak}w0 zbCv+a3K57EA_T19N3nt*9O&GRx1a`dC^GTzaw~8siYRa@ih_2sF>5lvU^Hif9zk+} z(VWRZ0et$&4n}jP00kKa&=CO4j-W%2;B_ZxpS}XKgr%LXPN=pw|4}r%LJ*2Q(yqE+Xt775|%b+UIC(|%$SydXfZRU1B?m`pgV{5fM^LbrX3(! z5`6eF18A$z6cC@!jA;Uh<}zpQ0MR05OgRb+paZTm6c`jZK%?CZpi?VBr^K+CG3h8U zfcA!IfQCRolT@I+W}xXr1_fa=(1|e$LZH1c3<^AE40}M%;5K8}0it=$7`A|%ycyIQ z(PdBqohZeiz^u=xV9l_R33M8vfGaN-N_ydfrkB0YHb09Z6AuTtgyVMH0Tp9aWa6o3 zg9@&N3UVqk@vuNOFF_Jxf{M+Dim`%n0{B{J@Zl}s9f+Xg96&2{z@7nL(GAL64`A!w zx!3V9vDCA`Pn_Y%R${7$Y*1HV0#(lni~>Kvt!mJ~2527@SQNA!2hw&23xh_^L5dMe z`@zBzpm_sOWe48`02T&MCxC>($LN597c6W5Q(X@}iU%%k0TZ`?wP?Z0LD>P~7Q{(K zObSf83@_NNKv4wV47!6Aa?A*mCi4SUb7s(d2S=78D1Sh-K7gNQ1U3_to0uHyL2kQ& zDszDW=86lb5+C3aA5bMgSqoyx4^#;khDo8GNt1a28|b_h zupdCZg$bY$W{xb!ecHx=>TP7h{OU^ zi5c~bFu%?~m019{WC0VX(FSVjgPh3llHHtPClhF}Sd;k#8~B<^kT~-N(0xdt$tI30 z$2D-xYfv;Z-C;LpTEnEk|j-3a$LcZ1zMa6?)EY|wljKzwlaa1??adFgQ^;^&p~32 z9gKNOtO8%aX`E4k)v<%IK1Yc)TZz%JlhL1-5p+tL0(cw)(ggv{uQOUPYyepVYO8`R zcDw=GK)YRy;=650UT-0=f^XH}~?Gl&Ng-2oD902jus=FDK; z4%RGzE1>aIko*N!(54Vg<`b-n>>&ODRz(gFy@M6JNsdW_=?W8g4KFxEpj9Zyr)=iT z7eKor*v*+wgn}3x=FA5`G$*+84H||5S@fl=p#e0w%;dNP9Jdg&m^7F`xAK6_c>~R( za)V|K9JfFefEOY$X)vvsp2)^3KHbKTgNF@rjO6q#HddMX4G?AEwKO1Qpd*G^k+#z@ zIZoh!F8SjJ4KH>uI_>}sjS0L5jR`YwcW}WE)MBk?gconj@RLR$sY8>QA;6WF!3nf9 z05qfs$`}$^3XDj%je-jX@P06)QVh(8RIbdR8Bj(|W)5>^4kt#?`Ugf`h7C-LpwT)F za6f?&blM)M$^|I}?ZyV{Mk>uTz#|i&-C8hJ^`Nbk8s^NPDRj^=WFR+ziY=Ht=-e~N zZcOBI3ZxReOAV=v0vY51IunfvbQm3I@P*M4soVhzg585$O1%Ib3kNm{sZax%lwl6K zK^Jtb5M=KR=pej}ppzdM6xkrzst0@u^CqS&fp*Y1nIj|U^hYK~P!j{}3FJ};BnY+} zxdZ|Ua)7rQBb7cNyC;CIy=PQl1dWD)cCLW8HAA8ibbXZu=(H>Ff!3TLmvA`Ndns{& znsposT+k^^PVn(XoC@p;9FU>_lp7omfL*+VDNA57sJRI?v7S+rc>^OfX>fzgV{$yf z1lnSM0jWql02VocB(ei6asVNszz7=107u&fP(cVP+87;gFlGsKgMvqa$?*eN%MT=x z3yfKy;}|wDfodvH`Ppul3q0B$5PLDHQ911L9x(+i~f2c=_haR62h zigjo*2D=0_N(-)p!DqO^g}@asI4x>MLn?O$&_;RCR6n9(haA8M7K7&p1_d@NhK-5QoEj*?kLD8GChEcm1TM+7b~|Z6Xxbg2MKrf^-5 zdK7e1G(5jCIDVMEo{Lo~Hba5I@esJO=mED-K_?=Bml*7V3qp=W01Ivc32HL*FhZ6k zKx#%%azl6olui{Osa0UQAUCVXbSrLFAr(-A5|qY3%|}q+&0zu^6ai{hgW8UuR;=Ti z=>^=Z((d4I>?|V80vkK0 zH}6*+8P7I)n#h4s99oaycV*{fTW1uwj$Ry|?N#M=g3QPh$ zpp*tGd@&Cw0#!r`pp();tr(mN>p|;(z~?71f?E9wOahm2841okjJgaP!5fVsCnhN{ zI)Z~ z=+00k=t5w~S_L-HS<6hIOHx25k+6a0v7twofyT+DK)cq!OJKmKLJ8~vWqv7C$AC)# z&=qc=YdLm+9kd9f478*ke3TO?XMy(6)1TLZt-vPMehRW=r zgC=4fxg9w`DHXM7Vbow^0G%}gssZX@$sd-m;f))l#1F1ez~|M#RY9BtGMfX^!~uB% zlGU*#8=S>iJ;s4+kf3J-wQ8_NIwH=&ZlJI@3r0jON#z+fPofrQEZB=P&~aMKpfL+3 z(2fla(8db|__fmDlFk6s33JrQ!d{#~o9Eyj6Zq~_P@{@z(&&_bH&9 zDq;X?XTd9bXdMDOTm;l2t|v3S;7l$j@K%3FMd=H$!g?ZV)DCcML7RHggaJoIi56L) zmk(l=Oy4KWDis8;_c=hFSJa#W+Jy({!b3a^8VmZskR@;vWE`mO z0QK6S9aqrl&CHIB0!?kxwM1B@8Lv%u6JfQepTLOOas%x_g0|eiyOyAA$0?w}XGd+v z8z5TXBcxY~RmBTjDilB)mZ0W!iZOFeKPtj1@An-vQsKw|T73_RT5wMVycExoT@iEw znIkL&S)?JVK)tjLpq2Vepq>Zls18t@1za3YmlI`;W?Im;y;_v@7bDZcw(aHOtZvMV z-=^=AV)bFXG@V#f*soR0Dz9SfEVf zSf3@Z2ox!xp>jt?fo~uWgBI>%SHJ{SzzCXl0iCFf(8~ak;#QbmqQEM``x|5sw-TrU zKc#E>R0Y-|o(tXJ1va47o`)`7l%$|MR~dV{pua{){(sH}&q_N-Q9l@V`% zi8DDKfh@4*0d0+$uBgZ=4>AtCBow-m2g$f6T~MnL#(_6J$SAS;r_JaAEkyyXPvXdO zTms_2S3ZFkPW6C<91%;bK=ri(18Cfu(eVSwJ&s(ET_}G*9JpTaUWXeXAx8<&^4NT+OV#0Z)ls2w!(dBGE>a-J1VT6AT4Ne2NEE1 zJkyVqmH)AY9KyVY4IF&>)kr@^YtcxZZ+25SOz6+BZ@+jQj9 zXdBxgr_naGVO-*J+ou21 zWmOabHwMv_80)dR=&S&xcu@5V>ZmI)3P2VmfJad|%$Y%(XCMRK0$Bp9rZ3iGjbrNX zoX)Jzn!vbfdWt@4D&xxOr}SA3nWnZ)|EtfcCIMaV3UZnw4sYRR~2 zdZ_`cI^&_~a}8K^nC|pUKW)G|&lcTRpb;Q}O`t(UG$(`H%B{el$qX)r967*yBbFJm z>Pw#iNnumX|jJB?YT>!BWnM+Injol)QtE_Z;>lvx96*+?OxZv$uu2y6U- zjDb|447vgQo9D+O!_a-c_%m58|;SOw& z9-M)NoG8Sm2br-3;7%ES=qaNEY%#W!1n~=K<`Od^&VVXTMuDx<<;__oq98*UjF6EO zaHvD|!hAOcYzf}v2O8&sg$e_B#EDU0aohBX=B%QOcc(8mXRTp8I98I5^& z+nzO%sjqGNI(ydrpp8EctX+(&rvG$cEdq(=I%^MMxN7=hC)PNSFtamj zG;B*&J7Tva>-1a?R#E$n6F?OzJGfGC+|myUAlUv?P{&09ban`&`rH6k396KNvfwJG zgH{tW&1#$e(1X>ke##_}VH}Veb`FRGuVJD4S3oP6LEB<~Oa!Tf*2OI-Dj`+2BW&~P zL$FFvCy6J^@dbzjHxueWkeQ$kAj9-|o~)b-H$ZB@TRS|~BP zpkjc#l^L@4<-uhZf$7p-tb#ljK)ONI0%#wWg%_(0&l-ft#pw+okrsr=rRgWUSoIh$ zPyg=4s>*W)6hsism#1rZvzmgMIq}}C0X!=pGN7QjGJUrMj(?T zLdMaDHG%Qs^hG|b_KX*|Kk{LXV`RKE-O-O#s{WlI6FXvF`T`5`O(>x58mI*e9YY5l z`vt!!6U>1P-+(!=Arr`o1qtxk9N_sAi7X{na3dIW3?FDUg8=kW9EL2%dI8V{8jw+N zh(?YqCD27CkU175PMAi}tR?8Y0?>6g;K6T@oeE$r0zW{_W+}+6JfM5q7+|CR%%Fi1 z*r*bigK#mpkL)x((w|ks1#}+@lEI*xUqAz}P=i5L1p39Ak!kSPjWkbyI1#}3GgosH+W@k2V<7NN69DQJ`Hh@Wxg`Ytdf>yG0umtcjfuaDs%oO4%*1zGFTs?Ycj830u7miV+C~Q8#I`}i2`&H6i7QLkbc*LLJ52Y z;(tar(5b_a%atTRi4+8^l{0Sqf0|Kw9A!=76rINdR|$L7@o>aAKn` z8lLYYvXsC>)1VLmc?^_(K;;sH0yBsLMVJ#Kq;LX77c7%NR_!-1xC(p)l^US?%ost( z!0IwEOg|gUDpmgimNvn~8R8^hW=D_=$QF=su;7At6(j>HSfMiTr97a{J2XOHfbt_K zM2(+K^{V$ zOJ#Q4z?h}P4la^GUV+skI~XCA2zbyFs+Sow0jc( zY65LPMO1Cz85$NyvBKm4I-V6IBJg{dlaC4KOTkL4b0O87PCrDe;&o^AcD=_>DJM#y4Z&vYNA=q>cN8&kX|cj zc?E1z2s~H>o+be`jujZ;6Et}I1UgZi7(anqa1ezGqL}6}IVw!oZevwqTs7UVjkSSk zN$2znZLInrnz5Z#i>ae?x^6qG5{Mtz&RPSa&$qK$GG5xw*}=-l$bJIc(%v{-u#?qL za5<=l23i6JTD{09(BC;dxRdoHFI*UW5ypX9=Hlsdx>(iG#4mKQdK-f~k~}Qn>J4<> zi6R?lIpz(JC5lYo>mDbtfzB!foum&c=RkXk{kmDRrziKYnlK)mKBI?KAKp)8fW$O| zBcs5U>HShHk~|ROLAOE(Y@OE2D$RIzx=b&tBFI zf>yS`>-!6hW(R7!_DFm{=g=%S;XmEYOoZ!Dp~C>oYKbt|douBWM8_xcvv3H-aov zg^U0zFj+IQ@GybG7QEOC>L-wTZUqJpM-fn;fx)qJ^1%iMYevuoWn7@12UNsSpv;;P zyz+7;;(X0a#SoOtWV+F`@*4fZ7{f`;51mmIU(2*?jiL9!O;JZ{p z<-q}q@F*K-%?`_2&_&a1Yg+`qPro>kRYnx7h+6^dNRW>>vK*I9p3XFhRg-D%EYEmo`uSH(C4`1Ar@OsjQUZ;Vf-Y48k5+D1j$`!z4an!jv$`;Hc1#0x zLlp#GOy8NndXQ}fsQY_ndP5?sxk4Mr-wIrgJJ_-m*g+e-*&+8tIQ|C>q6(auo|wcc z!@YtvOMweC`O?-l{a+%hI6JbeCTJZbR2Fm&F~l$qkYOB{hN(&*TM0V+(6IsPAdpom zHxO3A4RhQAa*QK`<9iSdbJPoj%IU1htZu^4EC5Qb@Qe_b%<78bT7w@5Z6FIE!&cxZ zfdm6~%R1N)At0N=DsOpa3Mdq(f|imfaDj>za0r06pz|_9OafgsI)O!r7evosftV|B zW_oD~tC18q5SSc5Qd3xzz~`&;D)52UN=`qR!m22NYJ3L^)b`KQf2FWWbAiJ{;7nIT z!}JZAtRmBmQ(5IrQH|sQ4JLyRX@~5H;D)#f;tI5&8whO*QbBXU=?TFGCeSzRSv=HK;i92@VKCtv2i(`nLaU{RTQB`Hv?_} zLeUd6MYFLf`h%=U0&W3=6~hfS1wM#31t1PZm*qu~W!y47J(IPHar^W~nXEdDcc=4b zv1%}0m~N59sx1YXD+Fa_P{bpb0`ur?b&}lP!vsjfFFKmC1 z#o7(phMkkcs>gU}`s^H5H)n9F0u^mspe>o8$#(Ds1zZ|Tb660UWJ46Jfn3l4Q?LT6 zV7f{!s{-Sp>8=ne4MMd;s1*?EB!qeep}6zF8g%klmoi?OekqT2hW`&x-JrnbcmmYY zaXbKDN6iHqigbjR4xo}>fy)uJmJVHP24faN-SnOLtmcg0r+>_6-OhMu`pN>Zg{KNw z6=0+BT#gesAq6i3YPI6{1e9$Y%@w#DSFmL{&Y21-n0|mrfp$<Ldq4)k zmiw+_Vq~gQU~m)xHdlJVuXgs2xzSi=i+H4jgg z601A-h-lFGy8&z-1Qau%cw9eyMk%WymB;nu>s1SfI`IprRAh z#{)Iw^2%BB7*|cdTh5xmxOBQ*1?xn{Rnsq2utqX2ovu~MI+=0R^nI1Akxbj#L2EUo zryp=*<$%=`SIo3bm{WoL|7ATms9dch<66Fs_<@2qgLsEXpac zV!C!6s}|#`>0x!O37qZIK^culVBPfnb*wgwtET?}iB1NKatN%Ro>~tcsef6|n!vbW zyH^8i9cU!>WFzZeroGdqpJ-xLVLCo-`@1IAm5fX)rcIyO!kW&sZrXIFR#qdXP1B~E zwX$l<-2mB)XnldMj$v@*g|y!uO`Bfd$_i@G%x`5C(}KjKf*2^E!B>TfDM*0oK1j1q z7}RhSRS*V=OuygCD$RIk`tMd&X+^L$P)cP0?PO8_H(=SJP7Do1|7g>b)86a~p z;E7ZQft}NfCb7m!-vT9D1<-Vr0%(w3AWL8uNJNQQV8`@VlURcoZ%ntH%&NwCW4iei zR$0bd)0-xhOgqWdj{9&jwD; zEWAwMaUBH?#}A-z7J$ykfNsUJVn8+y0JU}E595I73*F$1V+zh&0+H&0ki84phXW6vQazXf6}3uK!i13x!RsU!H_%jtY8 zxRe>0rrSSfm1cZ0z5WHOIODbH{?AxN86Ql)_>$F=ar^Z3&saT~+PbF8ym4yZxe-ZMSn1*;t63p|FjLJX0^V#o%lAq@=-)8{;8oyGVFk2!c8 z(*QLG;+SXT8L|Lo$ck62pkuwRzGCfXYXv1jp6T+hSzVc0yQXh^&8nq*8zcrANe1nw zViC9o;wmvIFnjYdgHL2<61X${-)mM0q+rvB1>1w!&|ous!+Mu-`*i-dtUe%vW8bot zFfvUSd&gSB-Y^%W=F{|v?^rjnPk?f~-m~USzxb9_UUUIS#E};=|F!|d0UbcpxPe)C zdeRgwBgUuGCp=-*7C8Wt0bSmr!30_{aRHQ8wlgkc4QCXcGY@3J3`h%z$-$8wyz(J; zIje%eb&xL5O_eN;3>pkq=1!lxoK=SxToUqggB9MLer-8x6yxgYhAUV_B{qOO530mK z%}vlE0#?wSE&}VO$E{%1nQqX*B0XJV6|0cw36PbJpqV<*<~$Gw9BN z&MIAh3zT_4V+9&a0!qw|%pm2U3&0)0mz67miar6*@uZ;P1t!q&f`}qB_}X%CHy+ZH z1YO(#8leP@$Ahz^qezwlVz(A3C zUu0%voo*<|E>RB(bWnxHgeOb{?t`KS6j)Xa{GdbYvOrF8%vjw(;LO=>Kv;!KyZqNgzE10PuCxOO&kc&DZpa7a=08PakC@_Qe)iHxspny*r1fN6=8e;}a z2(*LT0=irplpNSVTd9RXj$wAZId9r*@cNAtGg&K{-a>dcr$^3WUCPupA1rrgyVz`2 zZpP`x^H`M_KTHps$7*GG4V1eSSRI)KV23w3UPc#Ua=d^LntpH|s|@4g>G$Tb_A@@6 zo;RPhpYi$hfAd-QK!%k-p$5Jl4V0Zg?bq`QSY0^hfc&YzB(Qn9%tBU4rX^j|-!5cT zk!b@7JBkUc1^EgxL)HosLa1B{Rrwa=0!Im`N*0jE-++V=Dwjc2a^3_9I|>V|oi4SA zRe$>HHLMQm;P?b}a~U<5z|B3-9GAccPM zOc@*nvK$$78SX7S*Z{sv7*axLGF$@*Kz4&MXfm8zIQ`%{Rt?7H>95wYYVtuGt-$OE zI>q$Rbj9_oqNs-QWjQivG8{vg!2uRHfDmBNWZ1EAde(YY1D+KiQBdAsa(p>`*?Lw5 z8R#K_pykUtO3a|d55969wC?!O^hfJim90T%eljRBKuTIxP^yIu<$xMP&~~o^sD~{G zI$RZ0pD=Jcihy(?Hv7NT_aQC?Ep~teYZfT^3*6g&Y89&nBh&0f;KY1uI@cQ3htnB1vRW~o zpKh~}HJI`I^a&eTV>wHw;u% zLNgn9$`7{o_cq9ppc7C8lvqHO1T&~yb(8>YI9CD%f()3&OTDzWNPhjEE9wRdAaMWZfIcFi`!&!pFkM!omPf$pTr>Du`|RyG^W;jBL|+ zwz4YKvvWH(oB-eTq{soj!H+=^bfXg|4=d;@LWmHfA{U4Q5@&a0P~-%+_%)bhlvo`b z8fpp^ITctP8|n%bK^GT-9D^wVK9f{Okwbx5lSu`1bA|?!0%$g0Baul$kqM+n1ayZZ zxIO|MB*FzbrGmqZNd}bkA>}BfrK-RJN?;5M?2ZlpmOmY@K16KCy*EY`XL|Rz7~vApxM}J)q3P#LGB6U>mC}Bh&P}ZLEr{3qi%@ z^j$3+S6%oRKphPQCV>`Em~u;kxu5}g(4D{_nn|DuEF;664~}Ct!ch&if&&7%8sgZ&s?F5izTI>Ot1Khqq3OXpSu+{CrtjU! zDy_?4#Q<7r)4*iS$N`yXfRKzL_%j{OK&v7^8_84@m_hrP!L1;WUS`m`GY-&& zv&^7n0pOC3M8#cozrFR-UVKznvInKM8NG?`o!ITg5~*2{Yu%U{EU(R-c0{XLhv65@>Co?!TAS z0(#s!3;4tW7SN6*flJe8?PYc1g`Kkw-W)XjAU zzq6lJ!*D6sSk!{z9Vj_~PUBjFBFX5;k|l6!y6FK{U1Lb_vV!lGX9itGzyjLX1S+>d zJyS;L0SBO-8YnR{D=-RNm_GFYt1IKh>9-HCN(Mm3Pr>bdaAmImSqaOm!NdYT${REq z20yn1)T)4#Q~Zb#9!3S|Wwz53H?TS?LR`fRb`=A}Rp2RP(9#>wsrQ$rAKt*KEeH#3 z(0!=j2%oNSg;kMhUiiNmhBrOVb5UvFc2JaF$gbWJ20CN=H4881$EyTDos z@-HkL9$bKjgUs}Vi>$mL$^46~&RURypAlN{gZ2}H&es7in`O%aZMErXXkd^6-F`g% z!Fg8Y>9(g><(cNTPe(Y_VEXw}tolqR=1)7#ss%Dv=QOJeMJ*RatWeR2DQ@&!)?u0I`Y#X4OuF^0^@8GqEb?!lL};Emq~ASy+|xD6lDj z_ojpVBQP7J#+8>JQ&17^<6Q`6#NB3{Q9l8sher%FQ>6iE*7SfyMBySV0)1c+5hRhx zU=d*?k*Q!2AtaG0U=cwi5pXo{2q1~{3WF7aC(6Lqvk3IJPw%+Hn!`Q^EW+ptSCN2)_d!r3l{10F z{vJ?xDXjK6l z+ciG2N-{F8obL3Abv4uC_UZ3Gu{zhU1bNL-EJumi@!pby4Gf^gnMy36lgmJBOYb0r z9RL4kF7yVSpQ6C*cnd=ubO;->;|&aPW>A)QyoMnTZdy2AsmG9D1#7s3Ah^U0T`ck(cR*7|+)a$r75lg(r=Oq4A;z?un3 zol>BdSQcoU1w8Z$p1flc=Fj8#%e9I6f}Fv>evCMxgi7nPe2@j`90H*e`A%` z2XP$PkW_GFIi3LvP6m^pNk^V6$2lO5z=EFXpn-PTH6WfNnz>s*f*^B21MbtKzq4{- zY&Qj+q=j_{9ca6$B;&T}E55Vh*lc?DJF6OeVIcA@k6AEG7*m z7J;49_x@&85QR4f!A|1Ha%^A{xU~J#Z&rUsHi+DGZ6OXR*#^*YTN{>xEZqo-Wzeh~ zX!WGy8BhbW?k}r6QJSGw$79z{DoX$hdcU8#9|d+bXci>8F|5p45YNL4E7^1H^OGa9jXZ z0Xqx;lq5EQMWCjG_6;yP-T)~UfC;fEutP=g8n%&@k+mMu69tpg^;p?z823(J&B~U} z4fdcSn*xKt-s!SzZ0azFda<$Tae*bJz;aD&Y#I=ULv43tbYwua9h(!G71$kLfE^8U zA{K25tON}LT@ueUU6Y+noDFQ+yXkK1Y|1dl=CiY@NP)$nwt(&m&H|kgkfp#XaB2El zb~Xu!zW3Wtv$Mr8Lc36~8>^VWs;oHKY~fuf(3QA%x3_Sz&1GafJH3RP&2V}!H=6?E z+3h9VZ0U@Q7pLFhVcX33VfqAKwld*=pt3}P#SwI}2MZ|i3;dog$;UQB4jh6?;G=m# z*MVm#@hC8ZI*kf!HMIhVx1Z-@lVW5%yZseE8$T1{(e1wk+0+;re@<5vW)o%nJ>6WG zEg!+#E6kRI;5mq}WgvL_McBL<4^HP6Ws_$-I9*$mtwL)xc<{D^Nr44)pUEFa1s2B{ z5V0R1_7BD^$A&eaRQYE6Sy8s1j3Pgvo-oK#U;*{*L3==^-x6m#gI#8q1X~K@kLmJ~ zY^~T8+!ANAp8i>q?J?uU>DQ&$E;1gQzEYa4pYix~OBuE<#uL+z$gs^|JUKm9mTfZQ zsp%hO*}51{Z?BPK(`95lvwf938zU%~*C?FZV5co;8E-=oSF#SdF{06JA!LE!&%RW-JgjBlpD zS7Xy<{6Ae*oh_5`&GdG4wmFO!r>khNIWzv8o}t0!#`t;rdJQ&SM#c}*_iD1mih_*+ z9lqiST7Smm_<=D?;P-TWEw*s2v)~v46-J;K`U2WldIlo)0mS~mnB}MTdgG6sS4mLMWBk99UGXl1U^sSr^B{_@x%0VUAAIDuqx1q2}Gs9@9D2~*}V8b z4s}#_JaHc6;E&Ut_1LVS4qm~ezzp)>98hxw>fjk5Hs~O6n1h$=v6(XdpMF=5?G)pi z=_~YMfvi0}-j>at@y&Ec1GW%&oSb0Faspk~y~KdcgYn|@w+3wG(9pcW4B6Xp2DBmv z8k#3SY|v&tSZMYcvRN^Ho_^AhZ3E+n=~YH-^&&7|fzGZ{U;=H*6Zk!y*O)CE>WLXp zb9+E$K|Rp{VuQ9N!920Z80?7~#$Zn@HUWF$q6u3T;{+<)8@?0x|= zWcP#f>ltPR7Dt5pSsanwztIfr{x@b|_s=y)az6{G|HT4ze`6`5*mO4wwors8z=rpL z3`ckZtlSaiiK7;5W>AMRgKpq(;t=>boy(Ffj`8#KOiQ*Mj31^eS+T8U{5k!C6`MHY zhv_e@*m6-)#R_In5>K;cD}~w%y5a$p0@i@0Qla*)0I^pvXTj}dwE+hn-V_idC2Y}7pHG=WV025W6#->11c90gv6wp2@P%{KH{V(uny0bG|D&wW;E1lUI z8S&go8a;ir3)@7d3+?C!w{*L*f%+rYUD+lxP3oMUxPH2)7itwMnnG?NYyX2uYn{@RnRM;1Kb2s+@0%@MK&8hi{HsQ(9= zzng1SU+m3xn(_Dad>^(_#{1Ks`mlkV&g%MjmE`xQI|s5kF`)BA(j{xTlg-W$Tk$;fzd`}9yY3l_$&(>E?*JIMHT`=lr~J0`|+ z+b_njEn;N+Iz8bJo7D8aIJT|zU%?KB6cnK2dX>1H7!+7EnKP7loEQWygBrvNETElw z3Q&mxC0-;6(6VHxM1>L`l7s|!$KeD$~x#<^U*rspqOlM<;%85_UJVly||QZDdU^%GqTu@F*2Up9-qUu7^H_ekL@_)*XgJ8*y0%PPS?t3^I^O@y*!`o zHsihN!3AuIjK`#>2EvP6t+(;Vygma-nfK~poNlUY?nbA<8#=i zZ*Qpp#R53=p&E}>vh}lq!+N^od^U~gO;v2wj2EZ>t77wKygS{mn$3an?)3g@aHAr! zhOLtE;`GZkY_AxPZ{Jr7_Q~}49Jb!=LJe%PAQu@lg1z&jk?lU?*XcK!*g_d!PSxovfYR{2F+InSqi)gq96>|LK;q*w!#!-2QA9+gecc#pkdoY~M16t)7t!oV-9sGcr$)Kg*^M z${k&dU#EYc$F>L-Uf{3*xt0ZVoQ%Nl=^N&=^)nvc?y!KZ3zW}5rcHmnh%L+J61aJ} zff3SSSOV%Kw1Cou8Pfs~8+01-kBgub0^1(T<;dcA0~~X2w@+NmCJ%}@P%ajPIEw|e z^9fYU2>hOIu!2o?`hulwN|2l_KfQkqo85MWWo)+iHQ6DnpRTZs&0#ywN;VddCc#x~ zM;X6PzrKnslJV|z!_{nwjCZF`Ud`sr_G)ohxKzo#>j*@%QwX>)BkO+Q9Av*=x4_;088!kO3ecilF%r)K%)4Zn%O?eEQZ+YzpX_ z9i|s=X8X?gb$Z|zwvg%jx3F0-UYz~|M4j7ixRtFFW-Q~^?X}z4u7V=@Vho$Y_62*{ zN)U3O;!1A&iQR15@hbSbAE99Sg1v0z(_Id+ePjH(-TE-wNsvy%t!(n!RgSXdf{dPY zjO_v>#rRI&aGcFY7@UO^Sirp%7RLkN-U|N-wpzx+(|b>_c{3iFe)9xdB;(=f#wXbp zYC+P>1!$T%0!k-$AYunV>;sHhj?gr-{ohHpt)TLG%W1ZSAe-mhWOJH+?--li^q-g6 z+!()3ceuj#*bv%S0^NWB(%b+!#{+ZK0gt6}^%UGF8h6XN!g z&5QBh^ocLogc*NNU;2_Q3hGu+*#+u*OaZwMnl>kZ*b@+GbGqg$ws^*K(>q_WT}HTZ zyXITA3VhCU_`tS}@#6IFAK0uIFK##b$ff|=RvY|@?Jr1I;1{+S#{bjTePNT)x(KNn zbQugB1>8YPG(aiXv0eZ+Zo~nq&_L&l{hs~>r0x9lz^`oIWjZ<`cW1C@Fu5qPg4PGH zXfQc|8qflVrl)*kGh{qBUGpuQ%=As)*b2EHg34ydMw00drm(3_5B|<(q7F&y1&~5L zMS;Z;8U_iFYy``m(*^#sNo+s%osA9T_Jlud;?tk}V0-J1TpWPUU{C_BGXY(B!va28 z0q!#gkk6PDz@iABLHGi{r%U`|3u3%HJ^L5iVhxCs8lZ`&1mUIvh;mdn`Tb@Sgt`e- z-s|PChfc5l%VviN)Bu>(4UC}EnNR|?0i4Jm|7DA1ygc3UAKOxBvH&FkP_k$NB?V}Z zfLsLL^$1PE+Xeo!NiiybQXHr}0xc>*i?Rz0SpvVOda*Bs26F-=m_ra=3V@EK!Hg7R zWCu6rOqkd=sY5d<$nXc?gQdVucVq&u(P)>+JjEcwKj37KV!SkcqaeEt!Yt0|bGX>kP|cE8V2A32ny$c(YF0fKV|aPcjgiA^ z%v>J!P84Hgr#JGl*P^;a7OxRtU-|N3@l`&mF*10KnaPjgl3D@w22>-Y2^pa}-A9l; z1{gx1WBARj2gxRZ5oh6CSxan3R?AW48T9iEo z)ffr9#w-+NZv$Q)AWYLWfB4mW>^mTF=PRW&L&qhstg80mVB)`wo9YxsXrmHJpgwRU`_7qf~3E(qs z`Wr2F)#-B-*$YvUvHbKbCH8VubNC6HW1x&-&Oc>zbNKL@Ghc;$GMZERRnd*$#cPCt z8v8UfBb3$AGbImRBj&5Ht4@ET&Yp*6&UOuSr*Pvn2OPS!ni%GIXra4@i;y|!p>jtX z-3U&+Ml|TK&qVW0nJ#+)Y8-RmH9|m-eHL0S;MQkvK{bM%kP)iW@9DFbqM5VB0Norm z!sfIaVwe+agl-NiUURsOF}%cPf*!D->0s1)8@a9(&|_Dfe%=JbDN9Y!odTM(#cd9^ zF}v#Y3Ns9I{LI;_Pzwkqd|rYS5HqK5G+~#UE^YzNkjSO^OAB=GfhLYooyCgOl<2i& z??Q{L3M=+vdE^=sG~f(vjX>v#`={&Kv8zm1$Yo=hF5=8CJl)lry@&DKbVVoj*6rao z?7X0^ilP(yyXnDp>`NgM@1{SuN3g3MLG0~{PVAH6Y8ShJ#6X6;n{MugV4rpev9}j` zAgTTA1rmd(ZTCU2rTswc?Fapk)H(-(#2{*~2f^4Uw!4O~D~Usfc%d!it&A79KgnTV z%&2t_+}A~E?Jl_w7K68Tzkt*TyxG1nk6jG4p$#&|rI39QDaK6Sn8z+WUAdS&kn!L4 z(qeWMMm3Q6;1%Pb2Dgp^vttiL1hm;sBg+wL|MdMO?3Wq;O)o8Gx0rsqlzk78`nInv zW531(RV)FSYUEL1c7%Epv^X5JixuQ)fj84vRU04sk{VWX8}(feGd? z59kGDP?v3Yt!5VnP0L5tu>XZxWC78nqre2S2z2`hl5c8i*<(z|S*>-!!rJF@Bg{-OL`v_L{wXOH27I22T9ae$^TZ9CX~)ERyeFwXe6j(oKst1Na+shrnX1(rUzbyti_?2A~bQNSEFC%D0i{qCE)9-Y$ z2g!l;LPbCqQ-fS#kfp#5T81I;d%8~-dneDRj0m5Ftdd^fwOI>>ouObHO@hbXW+ zLY*G~F&XZDkYalx6+;6ZwEBW$xdN!et;T;THb_1)|;)8%%tuuZ?%%^q6+1T??E zComHFkQXHQ3@pe47vup6UIhyZ!UefOf~UZO z2<==T!QGGRK{oNjm2!eaSAdlY!v(=N!7zY#BXcM)I(C7jK`Zz;vK(iCIPhb(*+JU> zgVLBI!X`G5;CHYf2i#0nkl?#V2kRRc968~lp!q__$6%!h{ova=ZlDQ5kN#%K0&Tct zbUXl-W`(ROJOSds-2^^^aR*4q5pF%m@sQok(;uv1VV%CBmpzFeSqb-X@Onp)=>_R5 zY|{($SXrlA^s%eDf@2F2++e4z01FDiJppkVXd?!r;|#DI=;{fMEXM^P8$d-7XyKwL zRwqvfFIarg#~#jjak@o6yDw;hw4c42@#l7?3GD2MI)Vw5({Pun`V-l^grUPGpj%x) z!!=Hf0zbE(naIw_s0fw;?NEn_gU8)KYfV5yLka>Hr@x!TzMS#R^l6jX3m7j>XP?6E z&iHe?{}lFljP;P(pa4>Xq#$aL1O;aBa2>QZfMx(@$0?u_vp{=Qm>s7;^g>V5WoiMP zV+^f-8bEB2?daMUz-|oU<^XM*pD{gW8oNH@v+Z-HvG;&>mTAslU&r*X19Wnbj4EiG z>Ti%|K+EnO8Qnnp{NST(p!3cZm;`=Lmzv4$qYR1}&^}ObNP=#feFG5zZG*Y;6jXq} z+1@#mU7wNh{Pdl(KxOatC$rdDK-`zJLEPygbJ*v=isEf^*y9<`PZygDlG*M!m;DrI zJsi(`b}LMaTAqQ6OC*b?FPP6Rf~gSGMK}~vYN9E`>jIF<8hc~!|??u6b0T+-?ot5foXQn^pA_! zMbtrJW=skYe~2hBIo@~)4r>8NMnzCj3_83>U{=p`oyF{0vJfc=&=C@#y`@Z!8z3T} z?D}jP6NfU>te)xf7qJJ>(D)gP*`INOTn#Rqwzn@~w_#$uI{nBpb|uEk)1NP6mu0*< zopm|8f+J)`6|^r4bUhq{60ZU`=!jy4S_L*I27#-f`UAAePm@_d3AFP}0D9IkSQe~z z`q{FYso2;tF)E|w zniV#%Z)JpWZf|6-Wnz3cJ#q{C2F7>Oxwf*WGQOK$u$BEbgtDF9xs5%E@$&RH+t?+f zz+t5TKD!wd&;m;AP7DgH;F)c??d%fuFnQ224kz%X!5m6pX-Et>f-c)-gK2?^f$qtL z8v_-)!I-7Mfu;_0);7dU0TeSq>t&&4YC&hlnZY*)q8s`G+0g0tx3i1GV`K(n7AQ6# zUV*yd1Y?#0x)Goy>2P;#H{QX%gbA89K#LJUX`=_69zZc;#?%2~gHDczr47d2?A^?a zm#6pcLkdgqJcttmJUj(1Pv5@}DJ(%37icnbD6yc02WYVYNDP$1Vc`xsS`Z}04vG?} zKQ4fp%T5fS@Pr2s|rEVfkF!;kL(FhXo19#%>jiLNDN{`;bC@hO_-xVfdi64HUbnjATh8J z(>ESw7uJO-2VHlq$t(d%tDv+6_W~$q-41jd^;!0{jMJ4)u`8l02t36uEN}r7IH2`_%%F~z zz@_aar`SE1(3K+0GGJo-JKgF$doCMTr_%Hb7uXf1pFPiR&G=?I=LPmI#y8WaTwtHX z_-4BLMRxgkkfRXC&N+&}&pH1ADKL@h%m*N~poR{p6#_k)1ay`Rqa&juST*S2Dh2K= z$MXzXj*JT2*#iAN)0bXk&(MJwB>}0nKv&l7cn&Ukp+`$W^A@BOoWAEGyYlpyOYD}; zuxJ47WdZe<7!+7QsR9%t3e2Ddu8f+@0-!}}NTL>5pj;>c6P+Rc-1$+Ro%QB>~f4(r|*UE9^3#|eE)8+D==Q3E`Jlu zvjtI?r$^sppADWb7^tL?g^6u9yw6_8$Od-k+wEH)fNDVq2NM4ZjE57lp zy}>OTc%o$npPC6?qwIKsLEzH%&d2P=OfU-$J!SU*mDk)a*%vcjp1%GiyBp)>>EB+m zyE9&%Zug4ait+OF%2#0CK?v^;gy-^_-JJ3A^qSY~p^TTOUwX|R%y@aa+8g!+#>>;& z-++0yAv~M6VBUncV7ZTP!Di~b1M6#g2bR0`4lHN>9?a{059Ymr@EksXc?&;)_1*aZ z)@Sq)tg`JRSnfH5XZ;DxoAU`Q_W{BS{0!FD^BJt~(Pyxn*%z?N>0iLS*ASl1S1@nE zSFjx8H?TgNZ(x0szJcYQeFMw6e+Tnse+TpaKzIQ^z`Tt=!1~_&0PA!53067nCs^(~ zgy;PW%vq z=wJ2##>>-}{bi42ygcn6`wnQrpTPl1_&uPZyc>`V+yP>Dfcl=`B=lzbqkrrTlCKUn zfHpgDWI0X%F$Ly<)=w~ScQ8(0_>f6tdjEfRd2kXkW5V7zehzCKfB4UCDGVvRP}EIzfLhPjnK@MP8U=4>+p%yc5~p$@3x_DQ#6q&P1>_SmCQw741ymD&wv^85nI6H& zp+VSKUT|p*>MSZSI0{d9Sj;X)SQE&9s!SY*kb-jw$Ppw5=Zm2eoOfA>2~JSRxU&)& zpW9cla+ESL?wqc`!J*5zd%7P7eA^?_%+Bc(IXE<-+aj4oPGQH%pb@CZ!n zoUYHq@eE=Pw8V83QDAiJcmpzd<91zM4mL(MD94hIV`uFK0&HGQ2R#~hdq0YV%+jBH>(yq%sT%u&U7Zu(te zB-dMHfy{@xepcsp9TAQ^M#f*;XNz*gGBRG;{!@(OB_qxa!kuG41erg&=tkfA$9jw6W$dcs(%3O1I_uE6HF0j&G|GzAVnriGo;0~9#qL3E)4M=ppC^k5O*{#k)Tmyu~< z=XNC}j_XWJ^Eh;1i%+zUz#3b z%;CrjK30VRG^ENXaCiD5V-8!!OVb}1b9e|s&S(K$3*y+o(as2WDG(e&2xa1>9-4T%28Mqy{fOwADjt@XI>^^Wu(0yAFM_e}Na7J;Jq6J3) zia?D8*qL)IICL3LO+RJ9(JKMoLc-0@?braelh5%9h!!|9J>Qa}7j!u z9O+4?K@L%1c7&Y*2R=9O1IRUwMvhCsK7egZ1|3l3*xb<2zyRtHFgwa*If9Q^Wp-jR zX97*Tb-ahR@IiabK*wf+X8D?@KYYL?HC@i1gI)gvNCEtcB}N5S$1PwRVEc-1eF24$ zqT`9LpfLJ4-PoEVmGRc}nbsUSve2jjPdl(=DY1giv1J1t&&850uw(ioYYuzH8`G6+ zI5Zh=O!u+jkY&6zJ1*EHDR65IiZ- zi6+PfQu*;SCv zU=X+lsy(C>SQNP6rxSr}0v#>Q06D!%kqdNMf&vpvDUSk|0)xP%={as3{*1e)?{VWW zXWTITiyMa{+c!{xe>>gUonsT@t?BRFIg}W0O&9dw5S0R_dyv6QpyTHG!N<+>gA?X- z2M-Plq1B+!Q~(VELz5?X;#gw(3^xuLR?qQ)0cX2`0{-RB`gld3m{tH&opn2IL15E4~hx>A9!?)psPCUIkz2BEZQWYHVphAZMd`__$69?#Qu^k|nIC3~10MP<} zrl0lYaAQ0)UBr*W3}!wf)cgoP4hzN`(OkmZ;Vt5Rfb0UzgMrR_z%1f8*nWT_^38M|e~uD-lk(Biuk7OJWV+pnKG*&;fTND_ z;Pi?>4td5)(`N*7m@^)lejyOyB?hRMM1nX193UmV0uw|Gl)kwY7(pQqx??~9%QOQ& zHz)yt)UYTq3S67MB#0wj8RTX&P`?N?5(*lsx$qNOkb~Nm99f{*1-)PnF-(P9Fcn_B z$ResT1H;HEm?{@wHS!BYD+jp41F_pMh69_C7qF;|$EtD-rb_P+4r%U(pri_#Rug!% zy)cBsoT(n7P(pzb5)_P%8~(w9!jU7(aR-QpsK7u~AhMQtJh`^aO}Yq}GPt$d(=e@dVyX z{}9gMU;iIeXh0{!A?pA@AqbmE2a9|Ji$Eu!!6FaABB1J~p@9J`asey?o&E=loB)eJ zXTQ0%Kvgd&D}xRyg%lLbnoJDl)AvPiSaG}rMKkwj#_1E)nZ&0jJZEB^E)&TiR^NE2 zfx!{knijAKbm;)tnl}v~HPE#TV37-85$M!7SY!iOL<~}8f<>l)MWA&!SmXydAdp4w z{I>&zjR=yq17JnSMy~*iKwAi4gQkE*xIk6$`$&#(Z~&v^-8CRTfTIz7tGNJp7(kJM zhYPeoKn6b43pNKu;}jekIq_+%2Nf58K;Fe-C1{ZaJc}?nVp{nGhemdMR)TCi0n^Bd zD4{+$bBV@c+OYzr6s{7~3II2ZnD9ET2Sej@aM^}w#RpKFp!k3Kf?y6&6-<>^FjX4H zaEK{Ggpmi!AtETHAgFA^G;#rk%I%9|IOG`Zz^xx8X7Ev=(1`?4i$xK9G&;z&3<^j& z2I<%V@T~Oo|FIl$j1Q;F#c}vB9-5vV#}TazNgznBT+(z1)EPi_CCKAOTQF2MV5o$| z0u$)CT1J6a(+%P|#4# zq9%LXl=qNFO&az^FoCKi2D6n$+M@B{w&>`*d6S*Q#o3+y~By+Sgb$6k) zPp8jG<%j||U9n3|f0M@Hi(T7tEW+SrfZbi-rimc5&kJu%Fi)S5&an`rD=~@5g%d74 zJu8z#lLNALu@k(~2ywF7nM@94rS3xw42YA}1Ry7?6=Z?#n&9SE0H3TTn8opiv1$9i zERIWzOnqI`FXeD#G0o|kZkNm9CN>*%oUH<*V?~w{BQGd=xg8k=wojjx%V7t(0E~wb zbe915%v@Fl4oBt^aMSWrE=MTi!Ra1(;686^9>){jePEOL6+puPho*<+bCg5ci=b9E zNbK(P+xZ;tm?m^hKV87#1fuy1IrJDWOt&lKxUBc38I*LnKrPU(Ag1Ft5UIf6s=x_q zN;q=3De)94aY-xjDeyUdpKf2oA;$g#q{Q*(^q3-!F2)PfpBHiL^M;rMx~0?+%^X&k zIUI#bY|=`+3cQZrK?W#rNGq^OgHG%M?FZ!GWpIR<`=OYlRtRDs3zEa8*Ozce%R%(A zNh`2OE3znn&l(0LYM9;~B^($4^gYz?}+r9?E1YH2oJe{wML&}f?Jpbm{ z(gKP{=ss}AKOml?jN^<}kmw&!Z;S!dSr*B1gc!*UF$ZKM*c=^CkPdjmf*Eupi;V)a z;}1{{L|G|(r5)lJM^Lj|0dzSv_)2$;EXO+_8G&uvo69)#7@3xLP2XJ3VHVH^Rt|FI zFHm5afp7A_G`0hz*^Eg8w6MfcAq!Lmf{vrn$O5gg0UbB%I02+W;LUW)3XU+wgVQHe zaCk9Zn0~v0Lz1bvVY*Ecu@lid`kl~uP87% zf_oWYqj->v0_)dwK@K1r2GEjH1x5jA5u?BeJ^Bz-iZcoz7ck(_Oz6nw;pu-WIqaGG zyQbS#aU8bp07VXBfP=-crxQuUaSn**DCoEWL<_(o5$wv})2*vHWQ0KmfT|28&|%jg zul{bHKB1CBk`LCSI=7?uJIQ?Tahc@H>>9RE(pBOJq7pUb3Wt!JDJ-wC# zbh+-NS`G{LX`p7+!)enm)^fB!%TzvI76new{e9C@>NwmO4^CfQ$Dw9C51dy)7q2L= zfUN#YXHg!!dcr8AC zemw^(8>G85{dWV0!t_)1915~vv%or0Om}1f4=b`aa9A-d=$h`_z@ZH?ub_cL0>tlX z;7|eaH-Px_x~89M;Lrhy|7hT_$^hHJ!^Z6hxA?v8^*w6(Ecj$nc;{mX! zu;T}?C^X!`cEj|6+yP^wnK6AYe%n<~Sl)`2Xd654mHFK0n zLV^f#ft_PLs1y+Gg(-m7dK*#ahw{WPbfPI3?e+}TG|IhT!77h)jSzXgNw{ScY zJPax;Kx1iHj7;?kpxg5r+Boz;Uf9qE_Cj16ha%&x>BNdkO@G|R5z5#%-Ljpd#SKyx z@<6HtR$c~Z5eq2_nL!E3k;6?|5u^Z8euJ)QfC?kZ)$Pn393_m5ebXyCIkKQ;@E3%P8=k;4tiOpPuMNk)G7I4X;y4XCUP=;n~;289!-Kw@$H zH@&Kx!%n3Klw96`LJE9qwE^fJEX4Q(KCNsJt<$}FI97W>%yoe5P&QFuar^_4HDfYx z1noZt&1^V=mVP-JWI2B51zEWblcAP?d=azcv2D+Ep%W(>b19Ag+(Q!f_2OqR_0gd|$fJ>L!J`NA2-mdA#`#ADI zw0S>AF(}!s=?5pfqx~F)Og&xGfAn*>f`siSaAZNe2`cS*vK(9bK_RpldJgP`2^f=oU?iDNB1 z&oxixaD#I$Oy=-|b5y4w$rMdNk~xknBQh09CUYv1o^4Y(GU`EgI|@540nxA`-f;_v zM;B2|2GC>&G1g5#HjN`m5~LC`|8@e(1f^2Y{F~!+4qX|Lm?OL6eJ~AL+sl*X_yoiO z9gqv&6*G4_hhROl(gal&&}x$bG(dn-ZDLLcIz!s!il7sR;1w^4W-u{umoZMiIE^Dr zs%7G#1_p>WdnQMMCrA}I??XnOSR9`~L^vEl#}u$+Iqm`R6+kEJ zIPRGQN=bV`d6I$KaREreQPOe4WRU2`>04%UIEo(v4F-Z5w4lX|EDEfSOeIQe0*9yb z%;L~yygS`u7RO@7gVXQK;^<>K*fss*Z)TC{4YN6-Kpe)YEK1Y=&E}9W0UHRL=Hx;i zF^3dMaH|i1Rf6j^EQ9foUdsWDUd!{j9J;z7osO)KUK@CX;|W-V4N2qyScC;M=HWPx z!%!d0Wpn%rra`gKk>&UY%;}i|Dvv-yJXwwtKpfDa$_wXlxPT6Lem;*wnH`);dV8h| z&gYP1f}Q4UKcAyR2;AROWan03=VesjP~a4}yZz>T4s}McsUSlo9Y2801ACHzTj1Vw zv4tGDa`1AT2{a2Pqrl|&1Ed@jlT40%(-$t}&;l(TU|h%|sxk*6qXAhH2U2?hA|e4E z?34fxw4PUF#inu#rb4-@lBb0(7LS#R`rrw&|dB{dW3_6&yE=Kx{`r#~UCTR*osKg9>&?k_4Yl%Amo- z0=g!KL4jG|;`B``Iov_l3$5gk7KZdsLDP4-3=ED;C5~@qPuEz*QOPs=Py<62s3Xqo z&I=kR6rO%y6^A+F>*+sMacD5kn69{*LyGbBbeq*28Zt8uH83c0@Mv*6vM7Qw=LrT- z?}P=^`g}dT0ZD}>Oa*BDD>G;{0fWHn=|@(BO?(S6kz);qDdX$ub`Yv$4TlEf^yzcg zfNk3W;XPc#p~HA^I^S9j6~-CUjn{J6If1+nx*W{$0E0WPq5_lSUXY_44=}(k43u>Q zT}#HS$msY5qLxRA8`OqSV0L7JICS$`4o$`x)9V=POgC7^AqhrCsYdG^LT0ih~Xs0(a1$CZAi!p{a(XK$P2Y6@&}A zCIWOU7{V2@>rvGTaXT)Bs)b&tiBOxfoD7O<+`HC4mcuF$=w&+K1C2n}yn~MN?BBv+Y7BBBY+68( z0a9^6_UG{^Fgo43%G|gkBih_JVp|eqZhRioE68YI0yIq{Mgtw;*FjNOKY&7;n`!!<-5iF9yP=pA zSiunqp0fqr2tI~ObryW`Yl4~G)t-RbFjIINiF zbx&Wsha*%3su6VNB52VIL@&=?4hQJD@T{)9pmSu;L1*6YPG4|=Nfxx^1Kc~}_hxk5J`dD(01YgI1`QcNB?zPA3a}t_nh7?1Jrhk3 zyzrtAEC^aQGCkoElf1!$xgg^N96x|*P=|yg%kc-8(*afrU6TP80yTZW-JnBzIpmq% zbWLZR$|A}FTC6br&t48aFYsmoMbMT#@I{+XpsN<7zCU8(PIa*{XF~T_Q`C z1X{q7j0y~nidh0J-P23bU#BqF+_S+W}Ti$d2jn4seJ;f|dwp_v}6SuNuurC1!{>P{Rfk zE)0$bnr=4M!qsC_$GwV$iDP^7K~NL!`}RMFIAob1u0e}vB__xJ|NsAIhk73t1CY>^ zFM}A36kC`f3AzM;L4ygAIuw{7(WJx((GBxJJ%kJL0V35XpeaJA5rC&G+-i7~m>oag zx%-M0>U``f6&b-d8I0aP|U) z@bvk|;E98}APR2jeCq3qfX8bq(-D8g1jDM$}dcv`Q@$dA& z=NuZ-CqLz=fU!-Uaa6+C*Pd}yLD+K`|4x7RoWqmx-}HrVIJ8(n$4~s5e(@`Z?(``y zI1Cy8LfD^QaJa#gG%#fe{G0yqJ%`TpsV~7w!0gX2IozR2rWd^CU}1!+dH;$-heWnE zsNe><o&=i*lmkj+Dn3ZEYT zn}Zz^nflYG{RaE&_HPao#(&cV{%|xi{+&MM4@U>gy9@q;y$g!gsScd5*c(Wu_Vn|N zoFEUJHRm*$&dtP`!uW4`BQqx`I-t}=WzHzp0}P<}gNk6KK+2{c;NxUr{EKD)s&bGz zB8-D-0;!(9K#eF$ zP53B~fy5>OV$|WY3o3U}nKPONT(&?3@KI!i5V5I>hzN(e4HQf)3WV|#R56qS=^@?* zs3v?Akp_|zWD(4a0{BxtK8Kw(=lsO@cl!Yg&QbxUw(jZXo}771t=-cTqd4uSKl9{F zVr>I8-KS3s=Colq$WmYwXziZ7(Ku#C9>FWZK)b$5*I>9v!6bC#t z1}dB&!S)pDpvECWH-KjLK=)ZeobNq7JB4!r$nE#iIPItVq;l3XwRUemo65=02o>E2 z5}23H$p;o#m%#}Z$jjv901JR)aBntp3}W!y;qe)m1Bp+;Voq>~4I#Q=`uYk^c92iV zaC8H!0uv~sA!&7*E>g>xgOnTD4zOf_a-3i>r_*%KI?gbrj_&P=b)1jE;q2A`$;XAg zoc7bdHo)`o#)+u;*me4oM$UPlxC5&^-VDu=*mybg*Tm(V4%4mMpt`X0 z5V}sZK~fLcbe#@pDuD4|`Pg;(_71o@aJ(1xLgJqaG&n^gGNkKt*M5jyg3}>(3;`PK z2Sl!PonA7Va~UW$?xk^BPY<8N*$hf|XHz*drn}7LTn?Afm}`cF?pFt3Yq}_EQHr z?+7yWbWdM#nNvw<0;pzΞ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 delta 233612 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 DiymPt -- GitLab From 6c800b6e26266893ed70d9678ea024d296106176 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Fri, 12 Jan 2024 13:27:48 +0100 Subject: [PATCH 3/5] Etherlink: snapshot node for version 9978f3a5f --- etherlink/CHANGES_NODE.md | 12 +- etherlink/bin_evm_node/evm_node.ml | 27 +- etherlink/bin_evm_node/lib_prod/dune | 11 +- .../bin_evm_node/lib_prod/durable_storage.ml | 222 +++++++ .../lib_prod/durable_storage_path.ml | 87 +++ .../lib_prod/durable_storage_path.mli | 53 ++ .../lib_prod/encodings/ethereum_types.ml | 26 +- .../bin_evm_node/lib_prod/filter_helpers.ml | 18 +- etherlink/bin_evm_node/lib_prod/helpers.ml | 17 + etherlink/bin_evm_node/lib_prod/helpers.mli | 13 + etherlink/bin_evm_node/lib_prod/publisher.ml | 47 ++ .../bin_evm_node/lib_prod/rollup_node.ml | 615 +---------------- .../bin_evm_node/lib_prod/rollup_node.mli | 121 +--- .../lib_prod/rollup_node_services.ml | 85 ++- .../bin_evm_node/lib_prod/rpc_encodings.ml | 410 +++++------- .../bin_evm_node/lib_prod/rpc_encodings.mli | 223 +++---- etherlink/bin_evm_node/lib_prod/sequencer.ml | 78 +++ .../lib_prod/sequencer_blueprint.ml | 90 +++ .../lib_prod/sequencer_blueprint.mli | 18 + .../lib_prod/sequencer_context.ml | 124 ++++ .../lib_prod/sequencer_context.mli | 47 ++ .../bin_evm_node/lib_prod/sequencer_state.ml | 80 +++ .../bin_evm_node/lib_prod/sequencer_state.mli | 34 + etherlink/bin_evm_node/lib_prod/services.ml | 624 ++++++++++++------ .../lib_prod/services_backend_sig.ml | 120 ++++ etherlink/bin_evm_node/lib_prod/simulation.ml | 82 ++- etherlink/bin_evm_node/lib_prod/simulator.ml | 81 +++ .../lib_prod/transaction_format.ml | 87 +++ etherlink/bin_evm_node/lib_prod/tx_pool.ml | 217 +++--- etherlink/bin_evm_node/lib_prod/tx_pool.mli | 26 +- manifest/main.ml | 5 + 31 files changed, 2272 insertions(+), 1428 deletions(-) create mode 100644 etherlink/bin_evm_node/lib_prod/durable_storage.ml create mode 100644 etherlink/bin_evm_node/lib_prod/durable_storage_path.ml create mode 100644 etherlink/bin_evm_node/lib_prod/durable_storage_path.mli create mode 100644 etherlink/bin_evm_node/lib_prod/helpers.ml create mode 100644 etherlink/bin_evm_node/lib_prod/helpers.mli create mode 100644 etherlink/bin_evm_node/lib_prod/publisher.ml create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer.ml create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_blueprint.ml create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_blueprint.mli create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_context.ml create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_context.mli create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_state.ml create mode 100644 etherlink/bin_evm_node/lib_prod/sequencer_state.mli create mode 100644 etherlink/bin_evm_node/lib_prod/services_backend_sig.ml create mode 100644 etherlink/bin_evm_node/lib_prod/simulator.ml create mode 100644 etherlink/bin_evm_node/lib_prod/transaction_format.ml diff --git a/etherlink/CHANGES_NODE.md b/etherlink/CHANGES_NODE.md index ba6543781b25..7af77956780a 100644 --- a/etherlink/CHANGES_NODE.md +++ b/etherlink/CHANGES_NODE.md @@ -2,12 +2,22 @@ ## Notes -Currently supported kernel version: 32f957d52ace920916d54b9f02a2d32ee30e16b3 +Currently supported kernel version: 9978f3a5f8bee0be78686c5c568109d2e6148f13 ## Version Next ### Features +### Bug fixes + +### Breaking changes + +### Internal + +## Version for kernel 9978f3a5f8bee0be78686c5c568109d2e6148f13 + +### Features + - Stream the L2 blocks to give a faster and more consistent inclusion of transactions on the L1. (!11102) - Add a keep alive argument that waits until the connection is made with the diff --git a/etherlink/bin_evm_node/evm_node.ml b/etherlink/bin_evm_node/evm_node.ml index 8f295a5d78de..ee912902a5f4 100644 --- a/etherlink/bin_evm_node/evm_node.ml +++ b/etherlink/bin_evm_node/evm_node.ml @@ -116,7 +116,9 @@ let install_finalizer_prod server = Lwt_exit.register_clean_up_callback ~loc:__LOC__ @@ fun exit_status -> let* () = emit Event.event_shutdown_node exit_status in let* () = Tezos_rpc_http_server.RPC_server.shutdown server in - emit (Event.event_shutdown_rpc_server ~private_:false) () + let* () = emit (Event.event_shutdown_rpc_server ~private_:false) () in + let* () = Evm_node_lib_prod.Tx_pool.shutdown () in + emit Event.event_shutdown_tx_pool () let install_finalizer_dev server = let open Lwt_syntax in @@ -160,10 +162,11 @@ let rollup_node_config_prod ~rollup_node_endpoint ~keep_alive = let* smart_rollup_address = fetch_smart_rollup_address ~keep_alive - (fun _endpoint -> Rollup_node_rpc.smart_rollup_address) + Rollup_node_services.smart_rollup_address rollup_node_endpoint in - return ((module Rollup_node_rpc : Rollup_node.S), smart_rollup_address) + return + ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) let rollup_node_config_dev ~rollup_node_endpoint ~keep_alive = let open Lwt_result_syntax in @@ -479,10 +482,17 @@ let proxy_command = let* () = Configuration.save_proxy ~force:true ~data_dir config in let* () = if not config.devmode then - let* rollup_config = + let* ((backend_rpc, smart_rollup_address) as rollup_config) = rollup_node_config_prod ~rollup_node_endpoint ~keep_alive in - let* () = Evm_node_lib_prod.Tx_pool.start rollup_config in + let* () = + Evm_node_lib_prod.Tx_pool.start + { + rollup_node = backend_rpc; + smart_rollup_address; + mode = Proxy {rollup_node_endpoint}; + } + in let* directory = prod_directory config rollup_config in let* server = start config ~directory in let (_ : Lwt_exit.clean_up_callback_id) = @@ -631,12 +641,13 @@ let sequencer_command = let make_prod_messages ~smart_rollup_address s = let open Lwt_result_syntax in let open Evm_node_lib_prod in + let s = Ethereum_types.hex_of_string s in let*? _, messages = - Rollup_node.make_encoded_messages + Transaction_format.make_encoded_messages ~smart_rollup_address - (Evm_node_lib_prod_encoding.Ethereum_types.hex_of_string s) + (Evm_node_lib_dev_encoding.Ethereum_types.hex_to_bytes s) in - return messages + return (List.map (fun m -> m |> Hex.of_string |> Hex.show) messages) let make_dev_messages ~smart_rollup_address s = let open Lwt_result_syntax in diff --git a/etherlink/bin_evm_node/lib_prod/dune b/etherlink/bin_evm_node/lib_prod/dune index 7566e1284752..c3d714a5683a 100644 --- a/etherlink/bin_evm_node/lib_prod/dune +++ b/etherlink/bin_evm_node/lib_prod/dune @@ -14,7 +14,12 @@ octez-libs.stdlib-unix octez-evm-node-libs.evm_node_lib_prod_encoding lwt-exit - octez-evm-node-libs.evm_node_config) + octez-evm-node-libs.evm_node_config + octez-libs.tezos-context.disk + octez-libs.tezos-context.encoding + octez-l2-libs.scoru-wasm + octez-l2-libs.scoru-wasm-helpers + octez-smart-rollup-wasm-debugger-lib) (flags (:standard) -open Tezos_base.TzPervasives @@ -22,4 +27,6 @@ -open Tezos_workers -open Tezos_stdlib_unix -open Evm_node_lib_prod_encoding - -open Evm_node_config)) + -open Evm_node_config + -open Tezos_scoru_wasm_helpers + -open Octez_smart_rollup_wasm_debugger_lib)) diff --git a/etherlink/bin_evm_node/lib_prod/durable_storage.ml b/etherlink/bin_evm_node/lib_prod/durable_storage.ml new file mode 100644 index 000000000000..31e7dbdc45a1 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/durable_storage.ml @@ -0,0 +1,222 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +open Ethereum_types + +module type READER = sig + val read : Durable_storage_path.path -> bytes option tzresult Lwt.t +end + +module Make (Reader : READER) = struct + let inspect_durable_and_decode_opt path decode = + let open Lwt_result_syntax in + let* bytes = Reader.read path in + match bytes with + | Some bytes -> return_some (decode bytes) + | None -> return_none + + let inspect_durable_and_decode path decode = + let open Lwt_result_syntax in + let* res_opt = inspect_durable_and_decode_opt path decode in + match res_opt with Some res -> return res | None -> failwith "null" + + let balance address = + let open Lwt_result_syntax in + let+ answer = Reader.read (Durable_storage_path.Accounts.balance address) in + match answer with + | Some bytes -> + Bytes.to_string bytes |> Z.of_bits |> Ethereum_types.quantity_of_z + | None -> Ethereum_types.Qty Z.zero + + let nonce address = + let open Lwt_result_syntax in + let+ answer = Reader.read (Durable_storage_path.Accounts.nonce address) in + answer + |> Option.map (fun bytes -> + bytes |> Bytes.to_string |> Z.of_bits |> Ethereum_types.quantity_of_z) + + let code address = + let open Lwt_result_syntax in + let+ answer = Reader.read (Durable_storage_path.Accounts.code address) in + match answer with + | Some bytes -> + bytes |> Hex.of_bytes |> Hex.show |> Ethereum_types.hex_of_string + | None -> Ethereum_types.Hex "" + + exception Invalid_block_structure of string + + exception Invalid_block_index of Z.t + + let block_number n = + let open Lwt_result_syntax in + match n with + (* This avoids an unecessary service call in case we ask a block's number + with an already expected/known block number [n]. *) + | Durable_storage_path.Block.Nth i -> + return @@ Ethereum_types.Block_height i + | Durable_storage_path.Block.Current -> ( + let+ answer = Reader.read Durable_storage_path.Block.current_number in + match answer with + | Some bytes -> + Ethereum_types.Block_height (Bytes.to_string bytes |> Z.of_bits) + | None -> + raise + @@ Invalid_block_structure + "Unexpected [None] value for [current_number]'s [answer]") + + let current_block_number () = block_number Durable_storage_path.Block.Current + + let un_qty (Qty z) = z + + let transaction_receipt tx_hash = + let open Lwt_result_syntax in + (* We use a mock block hash to decode the rest of the receipt, + so that we can get the number to query for the actual block + hash. *) + let mock_block_hash = Block_hash (Hex (String.make 64 'a')) in + let* opt_receipt = + inspect_durable_and_decode_opt + (Durable_storage_path.Transaction_receipt.receipt tx_hash) + (Ethereum_types.transaction_receipt_from_rlp mock_block_hash) + in + match opt_receipt with + | Some temp_receipt -> + let+ blockHash = + inspect_durable_and_decode + (Durable_storage_path.Indexes.block_by_number + (Nth (un_qty temp_receipt.blockNumber))) + decode_block_hash + in + let logs = + List.map + (fun (log : transaction_log) -> + {log with blockHash = Some blockHash}) + temp_receipt.logs + in + Some {temp_receipt with blockHash; logs} + | None -> return_none + + let transaction_object tx_hash = + let open Lwt_result_syntax in + (* We use a mock block hash to decode the rest of the receipt, + so that we can get the number to query for the actual block + hash. *) + let mock_block_hash = Block_hash (Hex (String.make 64 'a')) in + let* opt_object = + inspect_durable_and_decode_opt + (Durable_storage_path.Transaction_object.object_ tx_hash) + (Ethereum_types.transaction_object_from_rlp mock_block_hash) + in + match opt_object with + | Some temp_object -> + let+ blockHash = + inspect_durable_and_decode + (Durable_storage_path.Indexes.block_by_number + (Nth (un_qty temp_object.blockNumber))) + decode_block_hash + in + Some {temp_object with blockHash} + | None -> return_none + + let transaction_object_with_block_hash block_hash tx_hash = + inspect_durable_and_decode_opt + (Durable_storage_path.Transaction_object.object_ tx_hash) + (Ethereum_types.transaction_object_from_rlp block_hash) + + let full_transactions block_hash transactions = + let open Lwt_result_syntax in + match transactions with + | TxHash hashes -> + let+ objects = + List.filter_map_es + (transaction_object_with_block_hash block_hash) + hashes + in + TxFull objects + | TxFull _ -> return transactions + + let populate_tx_objects ~full_transaction_object block = + let open Lwt_result_syntax in + if full_transaction_object then + let* transactions = full_transactions block.hash block.transactions in + return {block with transactions} + else return block + + let blocks_by_number ~full_transaction_object ~number = + let open Lwt_result_syntax in + let* (Ethereum_types.Block_height level) = block_number number in + let* block_hash_opt = + inspect_durable_and_decode_opt + (Durable_storage_path.Indexes.block_by_number (Nth level)) + decode_block_hash + in + match block_hash_opt with + | None -> raise @@ Invalid_block_index level + | Some block_hash -> ( + let* block_opt = + inspect_durable_and_decode_opt + (Durable_storage_path.Block.by_hash block_hash) + Ethereum_types.block_from_rlp + in + match block_opt with + | None -> raise @@ Invalid_block_structure "Couldn't decode bytes" + | Some block -> populate_tx_objects ~full_transaction_object block) + + let current_block ~full_transaction_object = + blocks_by_number + ~full_transaction_object + ~number:Durable_storage_path.Block.Current + + let nth_block ~full_transaction_object n = + blocks_by_number + ~full_transaction_object + ~number:Durable_storage_path.Block.(Nth n) + + let block_by_hash ~full_transaction_object block_hash = + let open Lwt_result_syntax in + let* block_opt = + inspect_durable_and_decode_opt + (Durable_storage_path.Block.by_hash block_hash) + Ethereum_types.block_from_rlp + in + match block_opt with + | None -> raise @@ Invalid_block_structure "Couldn't decode bytes" + | Some block -> populate_tx_objects ~full_transaction_object block + + let chain_id () = + inspect_durable_and_decode Durable_storage_path.chain_id decode_number + + let base_fee_per_gas () = + inspect_durable_and_decode + Durable_storage_path.base_fee_per_gas + decode_number + + let kernel_version () = + inspect_durable_and_decode + Durable_storage_path.kernel_version + Bytes.to_string + + let storage_at address (Qty pos) = + let open Lwt_result_syntax in + let pad32left0 s = + let open Ethereum_types in + (* Strip 0x *) + let (Hex s) = hex_of_string s in + let len = String.length s in + (* This is a Hex string of 32 bytes, therefore the length is 64 *) + String.make (64 - len) '0' ^ s + in + let index = Z.format "#x" pos |> pad32left0 in + let+ answer = + Reader.read (Durable_storage_path.Accounts.storage address index) + in + match answer with + | Some bytes -> + Bytes.to_string bytes |> Hex.of_string |> Hex.show + |> Ethereum_types.hex_of_string + | None -> Ethereum_types.Hex (pad32left0 "0") +end diff --git a/etherlink/bin_evm_node/lib_prod/durable_storage_path.ml b/etherlink/bin_evm_node/lib_prod/durable_storage_path.ml new file mode 100644 index 000000000000..57ce39dcfe3f --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/durable_storage_path.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2023 Functori *) +(* Copyright (c) 2023 Trilitech *) +(* *) +(*****************************************************************************) + +open Ethereum_types + +type path = string + +module EVM = struct + let root = "/evm" + + let make s = root ^ s +end + +let chain_id = EVM.make "/chain_id" + +let base_fee_per_gas = EVM.make "/base_fee_per_gas" + +let kernel_version = EVM.make "/kernel_version" + +let upgrade_nonce = EVM.make "/upgrade_nonce" + +module Accounts = struct + let accounts = EVM.make "/eth_accounts" + + let balance = "/balance" + + let nonce = "/nonce" + + let code = "/code" + + let storage = "/storage" + + let account (Address (Hex s)) = accounts ^ "/" ^ s + + let balance address = account address ^ balance + + let nonce address = account address ^ nonce + + let code address = account address ^ code + + let storage address index = account address ^ storage ^ "/" ^ index +end + +module Block = struct + type number = Current | Nth of Z.t + + let blocks = EVM.make "/blocks" + + let number = "/number" + + let by_hash (Block_hash (Hex hash)) = blocks ^ "/" ^ hash + + let current_number = blocks ^ "/current" ^ number +end + +module Indexes = struct + let indexes = EVM.make "/indexes" + + let blocks = "/blocks" + + let blocks = indexes ^ blocks + + let number_to_string = function + | Block.Current -> "current" + | Nth i -> Z.to_string i + + let block_by_number number = blocks ^ "/" ^ number_to_string number +end + +module Transaction_receipt = struct + let receipts = EVM.make "/transactions_receipts" + + let receipt (Hash (Hex tx_hash)) = receipts ^ "/" ^ tx_hash +end + +module Transaction_object = struct + let objects = EVM.make "/transactions_objects" + + let object_ (Hash (Hex tx_hash)) = objects ^ "/" ^ tx_hash +end diff --git a/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli b/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli new file mode 100644 index 000000000000..f900c0d9e921 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli @@ -0,0 +1,53 @@ +open Ethereum_types + +type path = string + +val chain_id : path + +val base_fee_per_gas : path + +val kernel_version : path + +val upgrade_nonce : path + +(** Paths related to accounts. *) +module Accounts : sig + (** Path to the account's balance. *) + val balance : address -> path + + (** Path to the account's nonce. *) + val nonce : address -> path + + (** Path to the account's code. *) + val code : address -> path + + (** Path to the account's storage at a given index. *) + val storage : address -> path -> path +end + +(** Paths related to blocks. *) +module Block : sig + (** Block number is either the current head or a specific height. *) + type number = Current | Nth of Z.t + + (** Path to the given block. *) + val by_hash : block_hash -> path + + (** Path to the current block number. *) + val current_number : path +end + +module Indexes : sig + (** Make the path to the indexed block hash. *) + val block_by_number : Block.number -> path +end + +module Transaction_receipt : sig + (** Path to the given transaction receipt. *) + val receipt : hash -> path +end + +module Transaction_object : sig + (** Path to the given transaction object. *) + val object_ : hash -> path +end diff --git a/etherlink/bin_evm_node/lib_prod/encodings/ethereum_types.ml b/etherlink/bin_evm_node/lib_prod/encodings/ethereum_types.ml index 36455a4cf36a..ab4b4bfe12c7 100644 --- a/etherlink/bin_evm_node/lib_prod/encodings/ethereum_types.ml +++ b/etherlink/bin_evm_node/lib_prod/encodings/ethereum_types.ml @@ -161,6 +161,22 @@ let decode_number bytes = Bytes.to_string bytes |> Z.of_bits |> quantity_of_z let decode_hash bytes = Hash (decode_hex bytes) +let pad_to_n_bytes_le bytes length = + let current_length = Bytes.length bytes in + if current_length >= length then bytes + else + let padding_length = length - current_length in + let padding = Bytes.make padding_length '\x00' in + Bytes.cat bytes padding + +let encode_u256_le (Qty n) = + let bits = Z.to_bits n |> Bytes.of_string in + pad_to_n_bytes_le bits 32 + +let encode_u16_le (Qty n) = + let bits = Z.to_bits n |> Bytes.of_string in + pad_to_n_bytes_le bits 2 + type transaction_log = { address : address; topics : hash list; @@ -971,10 +987,9 @@ let hash_raw_tx str = str |> Bytes.of_string |> Tezos_crypto.Hacl.Hash.Keccak_256.digest |> Bytes.to_string -(** [transaction_nonce raw_tx] returns the nonce of a given raw transaction. *) -let transaction_nonce raw_tx = +(** [transaction_nonce bytes] returns the nonce of a given raw transaction. *) +let transaction_nonce bytes = let open Result_syntax in - let bytes = hex_to_bytes raw_tx in if String.starts_with ~prefix:"01" bytes then (* eip 2930*) match bytes |> String.to_bytes |> Rlp.decode with @@ -999,11 +1014,10 @@ let transaction_nonce raw_tx = Qty nonce | _ -> tzfail (Rlp.Rlp_decoding_error "Expected a list of 9 elements") -(** [transaction_gas_price base_fee raw_tx] returns the maximum gas price the +(** [transaction_gas_price base_fee bytes] returns the maximum gas price the user can pay for the tx. *) -let transaction_gas_price base_fee raw_tx = +let transaction_gas_price base_fee bytes = let open Result_syntax in - let bytes = hex_to_bytes raw_tx in if String.starts_with ~prefix:"01" bytes then (* eip 2930*) match bytes |> String.to_bytes |> Rlp.decode with diff --git a/etherlink/bin_evm_node/lib_prod/filter_helpers.ml b/etherlink/bin_evm_node/lib_prod/filter_helpers.ml index 3255c4b58a56..3feab686e9be 100644 --- a/etherlink/bin_evm_node/lib_prod/filter_helpers.ml +++ b/etherlink/bin_evm_node/lib_prod/filter_helpers.ml @@ -48,7 +48,7 @@ type valid_filter = { } module Event = struct - let section = ["evm_node"; "prod"; "logs_filter"] + let section = ["evm_node"; "dev"; "logs_filter"] let incompatible_block_params = Internal_event.Simple.declare_0 @@ -94,7 +94,8 @@ end (** [height_from_param (module Rollup_node_rpc) from to_] returns the block height for params [from] and [to_] as a tuple. *) -let height_from_param (module Rollup_node_rpc : Rollup_node.S) from to_ = +let height_from_param (module Rollup_node_rpc : Services_backend_sig.S) from to_ + = let open Lwt_result_syntax in match (from, to_) with | Hash_param h1, Hash_param h2 -> return (h1, h2) @@ -116,8 +117,8 @@ let emit_and_return_none event arg = return_none (* Parses the [from_block] and [to_block] fields, as described before. *) -let validate_range log_filter_config (module Rollup_node_rpc : Rollup_node.S) - (filter : filter) = +let validate_range log_filter_config + (module Rollup_node_rpc : Services_backend_sig.S) (filter : filter) = let open Lwt_result_syntax in match filter with | {from_block = Some _; to_block = Some _; block_hash = Some _; _} -> @@ -165,7 +166,8 @@ let ( let*?? ) m f = (* Parsing a filter into a simpler representation, this is the input validation step *) -let validate_filter log_filter_config (module Rollup_node_rpc : Rollup_node.S) : +let validate_filter log_filter_config + (module Rollup_node_rpc : Services_backend_sig.S) : filter -> valid_filter option tzresult Lwt.t = fun filter -> let open Lwt_result_syntax in @@ -221,7 +223,7 @@ let filter_one_log : valid_filter -> transaction_log -> filter_changes option = else None (* Apply a filter on one transaction *) -let filter_one_tx (module Rollup_node_rpc : Rollup_node.S) : +let filter_one_tx (module Rollup_node_rpc : Services_backend_sig.S) : valid_filter -> hash -> filter_changes list option tzresult Lwt.t = fun filter tx_hash -> let open Lwt_result_syntax in @@ -234,7 +236,7 @@ let filter_one_tx (module Rollup_node_rpc : Rollup_node.S) : | None -> emit_and_return_none Event.receipt_not_found tx_hash (* Apply a filter on one block *) -let filter_one_block (module Rollup_node_rpc : Rollup_node.S) : +let filter_one_block (module Rollup_node_rpc : Services_backend_sig.S) : valid_filter -> Z.t -> filter_changes list option tzresult Lwt.t = fun filter block_number -> let open Lwt_result_syntax in @@ -292,7 +294,7 @@ let split_in_chunks ~chunk_size ~base ~length = performace and not exceeding the bound in number of logs. *) let get_logs (log_filter_config : Configuration.log_filter_config) - (module Rollup_node_rpc : Rollup_node.S) filter = + (module Rollup_node_rpc : Services_backend_sig.S) filter = let open Lwt_result_syntax in let+ logs = let*?? filter = diff --git a/etherlink/bin_evm_node/lib_prod/helpers.ml b/etherlink/bin_evm_node/lib_prod/helpers.ml new file mode 100644 index 000000000000..e8cd7c674efd --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/helpers.ml @@ -0,0 +1,17 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +let now () = + let now = Ptime_clock.now () in + let now = Ptime.to_rfc3339 now in + Time.Protocol.of_notation_exn now + +let timestamp_to_bytes timestamp = + let seconds = Time.Protocol.to_seconds timestamp in + let buffer = Bytes.make 8 '\000' in + Bytes.set_int64_le buffer 0 seconds ; + buffer diff --git a/etherlink/bin_evm_node/lib_prod/helpers.mli b/etherlink/bin_evm_node/lib_prod/helpers.mli new file mode 100644 index 000000000000..468b2281a100 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/helpers.mli @@ -0,0 +1,13 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(** [now ()] returns the current time. *) +val now : unit -> Time.Protocol.t + +(** [timestamp_to_bytes timestamp] transforms the timestamp to bytes + compatible with the kernel. *) +val timestamp_to_bytes : Time.Protocol.t -> bytes diff --git a/etherlink/bin_evm_node/lib_prod/publisher.ml b/etherlink/bin_evm_node/lib_prod/publisher.ml new file mode 100644 index 000000000000..d56b3d894ffd --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/publisher.ml @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +open Ethereum_types + +module type TxEncoder = sig + val encode_transaction : + smart_rollup_address:string -> + transaction:string -> + (hash * string list) tzresult +end + +module type Publisher = sig + val publish_messages : + timestamp:Time.Protocol.t -> + smart_rollup_address:string -> + messages:string list -> + unit tzresult Lwt.t +end + +module Make (TxEncoder : TxEncoder) (Publisher : Publisher) = struct + let inject_raw_transactions ~timestamp ~smart_rollup_address ~transactions = + let open Lwt_result_syntax in + let* rev_tx_hashes, to_publish = + List.fold_left_es + (fun (tx_hashes, to_publish) tx_raw -> + let*? tx_hash, messages = + TxEncoder.encode_transaction + ~smart_rollup_address + ~transaction:tx_raw + in + return (tx_hash :: tx_hashes, to_publish @ messages)) + ([], []) + transactions + in + let* () = + Publisher.publish_messages + ~timestamp + ~smart_rollup_address + ~messages:to_publish + in + return (List.rev rev_tx_hashes) +end diff --git a/etherlink/bin_evm_node/lib_prod/rollup_node.ml b/etherlink/bin_evm_node/lib_prod/rollup_node.ml index e8e29771a71e..214b90a7de71 100644 --- a/etherlink/bin_evm_node/lib_prod/rollup_node.ml +++ b/etherlink/bin_evm_node/lib_prod/rollup_node.ml @@ -26,600 +26,47 @@ (* *) (*****************************************************************************) -open Ethereum_types open Rollup_node_services +open Transaction_format -(* The hard limit is 4096 but it needs to add the external message tag. *) -let max_input_size = 4095 - -let smart_rollup_address_size = 20 - -let transaction_tag_size = 1 - -let framing_protocol_tag_size = 1 - -type transaction = - | Simple of string - | NewChunked of (string * int * string) - | Chunk of string - -let encode_transaction ~smart_rollup_address kind = - let data = - match kind with - | Simple data -> "\000" ^ data - | NewChunked (tx_hash, len, all_chunk_hashes) -> - let number_of_chunks_bytes = Ethereum_types.u16_to_bytes len in - "\001" ^ tx_hash ^ number_of_chunks_bytes ^ all_chunk_hashes - | Chunk data -> "\002" ^ data - in - "\000" ^ smart_rollup_address ^ data - -let chunk_transaction ~tx_hash ~tx_raw = - let open Result_syntax in - let size_per_chunk = - max_input_size - framing_protocol_tag_size - smart_rollup_address_size - - transaction_tag_size - 2 (* Index as u16 *) - - (Ethereum_types.transaction_hash_size * 2) - in - let* chunks = String.chunk_bytes size_per_chunk (Bytes.of_string tx_raw) in - let all_chunk_hashes, chunks = - List.fold_left_i - (fun i (all_chunk_hashes, chunks) chunk -> - let chunk_hash = Ethereum_types.hash_raw_tx chunk in - let all_chunk_hashes = all_chunk_hashes ^ chunk_hash in - let chunk = - Chunk (tx_hash ^ Ethereum_types.u16_to_bytes i ^ chunk_hash ^ chunk) - in - (all_chunk_hashes, chunk :: chunks)) - ("", []) - chunks - in - let new_chunk_transaction = - NewChunked (tx_hash, List.length chunks, all_chunk_hashes) - in - return (tx_hash, new_chunk_transaction :: chunks) - -let make_evm_inbox_transactions tx_raw = - let open Result_syntax in - let tx_raw = Ethereum_types.hex_to_bytes tx_raw in - (* Maximum size describes the maximum size of [tx_raw] to fit - in a simple transaction. *) - let maximum_size = - max_input_size - framing_protocol_tag_size - smart_rollup_address_size - - transaction_tag_size - Ethereum_types.transaction_hash_size - in - let tx_hash = Ethereum_types.hash_raw_tx tx_raw in - if String.length tx_raw <= maximum_size then - (* Simple transaction, fits in a single input. *) - let tx = Simple (tx_hash ^ tx_raw) in - return (tx_hash, [tx]) - else chunk_transaction ~tx_hash ~tx_raw - -let make_encoded_messages ~smart_rollup_address tx_raw = - let open Result_syntax in - let* tx_hash, messages = make_evm_inbox_transactions tx_raw in - let messages = - List.map - (fun x -> - x - |> encode_transaction ~smart_rollup_address - |> Hex.of_string |> Hex.show) - messages - in - return (tx_hash, messages) - -module Durable_storage_path = struct - module EVM = struct - let root = "/evm" - - let make s = root ^ s - end - - let chain_id = EVM.make "/chain_id" - - let base_fee_per_gas = EVM.make "/base_fee_per_gas" - - let kernel_version = EVM.make "/kernel_version" - - module Accounts = struct - let accounts = EVM.make "/eth_accounts" - - let balance = "/balance" - - let nonce = "/nonce" - - let code = "/code" - - let storage = "/storage" - - let account (Address (Hex s)) = accounts ^ "/" ^ s - - let balance address = account address ^ balance - - let nonce address = account address ^ nonce - - let code address = account address ^ code - - let storage address index = account address ^ storage ^ "/" ^ index - end - - module Block = struct - type number = Current | Nth of Z.t - - let blocks = EVM.make "/blocks" - - let hash = "/hash" - - let number = "/number" - - let by_hash (Block_hash (Hex hash)) = blocks ^ "/" ^ hash - - let current_number = blocks ^ "/current" ^ number - - let _current_hash = blocks ^ "/current" ^ hash - end - - module Indexes = struct - let indexes = EVM.make "/indexes" - - let blocks = "/blocks" - - let blocks = indexes ^ blocks - - let number_to_string = function - | Block.Current -> "current" - | Nth i -> Z.to_string i - - let blocks_by_number number = blocks ^ "/" ^ number_to_string number - end - - module Transaction_receipt = struct - let receipts = EVM.make "/transactions_receipts" - - let receipt tx_hash = receipts ^ "/" ^ tx_hash +module MakeBackend (Base : sig + val base : Uri.t +end) : Services_backend_sig.Backend = struct + module READER = struct + let read path = + call_service ~base:Base.base durable_state_value () {key = path} () end - module Transaction_object = struct - let objects = EVM.make "/transactions_objects" - - let object_ tx_hash = objects ^ "/" ^ tx_hash + module TxEncoder = struct + let encode_transaction ~smart_rollup_address ~transaction = + make_encoded_messages ~smart_rollup_address transaction end -end -let inspect_durable_and_decode_opt base key decode = - let open Lwt_result_syntax in - let* bytes = call_service ~base durable_state_value () {key} () in - match bytes with - | Some bytes -> return_some (decode bytes) - | None -> return_none - -let inspect_durable_and_decode base key decode = - let open Lwt_result_syntax in - let* res_opt = inspect_durable_and_decode_opt base key decode in - match res_opt with Some res -> return res | None -> failwith "null" - -let smart_rollup_address base = - let open Lwt_result_syntax in - let*! answer = - call_service - ~base - ~media_types:[Media_type.octet_stream] - smart_rollup_address - () - () - () - in - match answer with - | Ok address -> return (Bytes.to_string address) - | Error tztrace -> - failwith - "Failed to communicate with %a, because %a" - Uri.pp - base - pp_print_trace - tztrace - -let balance base address = - let open Lwt_result_syntax in - let key = Durable_storage_path.Accounts.balance address in - let+ answer = call_service ~base durable_state_value () {key} () in - match answer with - | Some bytes -> - Bytes.to_string bytes |> Z.of_bits |> Ethereum_types.quantity_of_z - | None -> Ethereum_types.Qty Z.zero - -let nonce base address = - let open Lwt_result_syntax in - let key = Durable_storage_path.Accounts.nonce address in - let+ answer = call_service ~base durable_state_value () {key} () in - answer - |> Option.map (fun bytes -> - bytes |> Bytes.to_string |> Z.of_bits |> Ethereum_types.quantity_of_z) - -let code base address = - let open Lwt_result_syntax in - let key = Durable_storage_path.Accounts.code address in - let+ answer = call_service ~base durable_state_value () {key} () in - match answer with - | Some bytes -> - bytes |> Hex.of_bytes |> Hex.show |> Ethereum_types.hex_of_string - | None -> Ethereum_types.Hex "" - -let inject_raw_transaction base tx = - let open Lwt_result_syntax in - (* The injection's service returns a notion of L2 message hash (defined - by the rollup node) used to track the message's injection in the batcher. - We do not wish to follow the message's inclusion, and thus, ignore - the resulted hash. *) - let* _answer = call_service ~base batcher_injection () () [tx] in - return_unit - -let inject_raw_transaction base ~smart_rollup_address tx_raw = - let open Lwt_result_syntax in - let*? tx_hash, messages = - make_encoded_messages ~smart_rollup_address tx_raw - in - let* () = List.iter_es (inject_raw_transaction base) messages in - return (Ethereum_types.Hash Hex.(of_string tx_hash |> show |> hex_of_string)) - -exception Invalid_block_structure of string - -exception Invalid_block_index of Z.t - -let block_number base n = - let open Lwt_result_syntax in - match n with - (* This avoids an unecessary service call in case we ask a block's number - with an already expected/known block number [n]. *) - | Durable_storage_path.Block.Nth i -> return @@ Ethereum_types.Block_height i - | Durable_storage_path.Block.Current -> ( - let key = Durable_storage_path.Block.current_number in - let+ answer = call_service ~base durable_state_value () {key} () in - match answer with - | Some bytes -> - Ethereum_types.Block_height (Bytes.to_string bytes |> Z.of_bits) - | None -> - raise - @@ Invalid_block_structure - "Unexpected [None] value for [current_number]'s [answer]") - -let current_block_number base () = - block_number base Durable_storage_path.Block.Current - -let un_qty (Qty z) = z - -let transaction_receipt base (Hash (Hex tx_hash)) = - let open Lwt_result_syntax in - (* We use a mock block hash to decode the rest of the receipt, - so that we can get the number to query for the actual block - hash. *) - let mock_block_hash = Block_hash (Hex (String.make 64 'a')) in - let* opt_receipt = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Transaction_receipt.receipt tx_hash) - (Ethereum_types.transaction_receipt_from_rlp mock_block_hash) - in - match opt_receipt with - | Some temp_receipt -> - let+ blockHash = - inspect_durable_and_decode - base - (Durable_storage_path.Indexes.blocks_by_number - (Nth (un_qty temp_receipt.blockNumber))) - decode_block_hash - in - let logs = - List.map - (fun (log : transaction_log) -> {log with blockHash = Some blockHash}) - temp_receipt.logs + module Publisher = struct + let publish_messages ~timestamp:_ ~smart_rollup_address:_ ~messages = + let open Lwt_result_syntax in + (* The injection's service returns a notion of L2 message hash (defined + by the rollup node) used to track the message's injection in the batcher. + We do not wish to follow the message's inclusion, and thus, ignore + the resulted hash. *) + let* _answer = + call_service ~base:Base.base batcher_injection () () messages in - Some {temp_receipt with blockHash; logs} - | None -> return_none - -let transaction_object base (Hash (Hex tx_hash)) = - let open Lwt_result_syntax in - (* We use a mock block hash to decode the rest of the receipt, - so that we can get the number to query for the actual block - hash. *) - let mock_block_hash = Block_hash (Hex (String.make 64 'a')) in - let* opt_object = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Transaction_object.object_ tx_hash) - (Ethereum_types.transaction_object_from_rlp mock_block_hash) - in - match opt_object with - | Some temp_object -> - let+ blockHash = - inspect_durable_and_decode - base - (Durable_storage_path.Indexes.blocks_by_number - (Nth (un_qty temp_object.blockNumber))) - decode_block_hash - in - Some {temp_object with blockHash} - | None -> return_none - -let transaction_object_with_block_hash base block_hash (Hash (Hex tx_hash)) = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Transaction_object.object_ tx_hash) - (Ethereum_types.transaction_object_from_rlp block_hash) - -let full_transactions block_hash transactions base = - let open Lwt_result_syntax in - match transactions with - | TxHash hashes -> - let+ objects = - List.filter_map_es - (transaction_object_with_block_hash base block_hash) - hashes - in - TxFull objects - | TxFull _ -> return transactions - -let populate_tx_objects ~full_transaction_object base block = - let open Lwt_result_syntax in - if full_transaction_object then - let* transactions = full_transactions block.hash block.transactions base in - return {block with transactions} - else return block + return_unit + end -let blocks_by_number ~full_transaction_object ~number base = - let open Lwt_result_syntax in - let* (Ethereum_types.Block_height level) = block_number base number in - let* block_hash_opt = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Indexes.blocks_by_number (Nth level)) - decode_block_hash - in - match block_hash_opt with - | None -> raise @@ Invalid_block_index level - | Some block_hash -> ( - let* block_opt = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Block.by_hash block_hash) - Ethereum_types.block_from_rlp + module SimulatorBackend = struct + let simulate_and_read ~input = + let open Lwt_result_syntax in + let* json = call_service ~base:Base.base simulation () () input in + let eval_result = + Data_encoding.Json.destruct Simulation.Encodings.eval_result json in - match block_opt with - | None -> raise @@ Invalid_block_structure "Couldn't decode bytes" - | Some block -> populate_tx_objects ~full_transaction_object base block) - -let current_block base ~full_transaction_object = - blocks_by_number - ~full_transaction_object - ~number:Durable_storage_path.Block.Current - base - -let nth_block base ~full_transaction_object n = - blocks_by_number - ~full_transaction_object - ~number:Durable_storage_path.Block.(Nth n) - base - -let block_by_hash base ~full_transaction_object block_hash = - let open Lwt_result_syntax in - let* block_opt = - inspect_durable_and_decode_opt - base - (Durable_storage_path.Block.by_hash block_hash) - Ethereum_types.block_from_rlp - in - match block_opt with - | None -> raise @@ Invalid_block_structure "Couldn't decode bytes" - | Some block -> populate_tx_objects ~full_transaction_object base block - -let txpool _ () = - Lwt.return_ok {pending = AddressMap.empty; queued = AddressMap.empty} - -let chain_id base () = - inspect_durable_and_decode base Durable_storage_path.chain_id decode_number - -let base_fee_per_gas base () = - inspect_durable_and_decode - base - Durable_storage_path.base_fee_per_gas - decode_number - -let kernel_version base () = - inspect_durable_and_decode - base - Durable_storage_path.kernel_version - Bytes.to_string - -let simulate_call base call = - let open Lwt_result_syntax in - let*? messages = Simulation.encode call in - let insight_requests = - [ - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_result"]; - (* TODO: https://gitlab.com/tezos/tezos/-/issues/5900 - for now the status is not used but it should be for error handling *) - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; - ] - in - let* r = - call_service - ~base - simulation - () - () - { - messages; - reveal_pages = None; - insight_requests; - log_kernel_debug_file = Some "simulate_call"; - } - in - Simulation.call_result r - -let estimate_gas base call = - let open Lwt_result_syntax in - let*? messages = Simulation.encode call in - let insight_requests = - [ - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_gas"]; - (* TODO: https://gitlab.com/tezos/tezos/-/issues/5900 - for now the status is not used but it should be for error handling *) - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; - ] - in - let* r = - call_service - ~base - simulation - () - () - { - messages; - reveal_pages = None; - insight_requests; - log_kernel_debug_file = Some "estimate_gas"; - } - in - Simulation.gas_estimation r - -let is_tx_valid base (Hex tx_raw) = - let open Lwt_result_syntax in - let*? messages = Simulation.encode_tx tx_raw in - let insight_requests = - [ - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_result"]; - Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; - ] - in - let* r = - call_service - ~base - simulation - () - () - { - messages; - reveal_pages = None; - insight_requests; - log_kernel_debug_file = Some "tx_validity"; - } - in - Simulation.is_tx_valid r - -let storage_at base address (Qty pos) = - let open Lwt_result_syntax in - let pad32left0 s = - let open Ethereum_types in - (* Strip 0x *) - let (Hex s) = hex_of_string s in - let len = String.length s in - (* This is a Hex string of 32 bytes, therefore the length is 64 *) - String.make (64 - len) '0' ^ s - in - let index = Z.format "#x" pos |> pad32left0 in - let key = Durable_storage_path.Accounts.storage address index in - let+ answer = call_service ~base durable_state_value () {key} () in - match answer with - | Some bytes -> - Bytes.to_string bytes |> Hex.of_string |> Hex.show - |> Ethereum_types.hex_of_string - | None -> Ethereum_types.Hex (pad32left0 "0") - -module type S = sig - val smart_rollup_address : string tzresult Lwt.t - - val balance : Ethereum_types.address -> Ethereum_types.quantity tzresult Lwt.t - - val nonce : - Ethereum_types.address -> Ethereum_types.quantity option tzresult Lwt.t - - val code : Ethereum_types.address -> Ethereum_types.hex tzresult Lwt.t - - val inject_raw_transaction : - smart_rollup_address:string -> hex -> hash tzresult Lwt.t - - val current_block : - full_transaction_object:bool -> Ethereum_types.block tzresult Lwt.t - - val current_block_number : unit -> Ethereum_types.block_height tzresult Lwt.t - - val nth_block : - full_transaction_object:bool -> Z.t -> Ethereum_types.block tzresult Lwt.t - - val block_by_hash : - full_transaction_object:bool -> - Ethereum_types.block_hash -> - Ethereum_types.block tzresult Lwt.t - - val transaction_receipt : - Ethereum_types.hash -> - Ethereum_types.transaction_receipt option tzresult Lwt.t - - val transaction_object : - Ethereum_types.hash -> - Ethereum_types.transaction_object option tzresult Lwt.t - - val txpool : unit -> Ethereum_types.txpool tzresult Lwt.t - - val chain_id : unit -> Ethereum_types.quantity tzresult Lwt.t - - val base_fee_per_gas : unit -> Ethereum_types.quantity tzresult Lwt.t - - val kernel_version : unit -> string tzresult Lwt.t - - val simulate_call : - Ethereum_types.call -> (Ethereum_types.hash, unit) result tzresult Lwt.t - - val estimate_gas : - Ethereum_types.call -> Ethereum_types.quantity tzresult Lwt.t - - val is_tx_valid : - Ethereum_types.hex -> (Ethereum_types.address, string) result tzresult Lwt.t - - val storage_at : - Ethereum_types.address -> - Ethereum_types.quantity -> - Ethereum_types.hex tzresult Lwt.t + return eval_result.insights + end end module Make (Base : sig val base : Uri.t -end) : S = struct - let smart_rollup_address = smart_rollup_address Base.base - - let balance = balance Base.base - - let nonce = nonce Base.base - - let code = code Base.base - - let inject_raw_transaction = inject_raw_transaction Base.base - - let current_block = current_block Base.base - - let current_block_number = current_block_number Base.base - - let nth_block = nth_block Base.base - - let block_by_hash = block_by_hash Base.base - - let transaction_receipt = transaction_receipt Base.base - - let transaction_object = transaction_object Base.base - - let txpool = txpool Base.base - - let chain_id = chain_id Base.base - - let base_fee_per_gas = base_fee_per_gas Base.base - - let kernel_version = kernel_version Base.base - - let simulate_call = simulate_call Base.base - - let estimate_gas = estimate_gas Base.base - - let is_tx_valid = is_tx_valid Base.base - - let storage_at = storage_at Base.base -end +end) = + Services_backend_sig.Make (MakeBackend (Base)) diff --git a/etherlink/bin_evm_node/lib_prod/rollup_node.mli b/etherlink/bin_evm_node/lib_prod/rollup_node.mli index d34102fef523..f3a43667aeff 100644 --- a/etherlink/bin_evm_node/lib_prod/rollup_node.mli +++ b/etherlink/bin_evm_node/lib_prod/rollup_node.mli @@ -25,127 +25,10 @@ (* *) (*****************************************************************************) -(** [make_encoded_messages ~smart_rollup_address raw_tx] returns the - hash of the transaction, and a list of transactions to include in the inbox. - - [smart_rollup_address] is encoded on 20 bytes - - [raw_tx] is an ethereum transaction in hex format (without the 0x prefix). - - All messages go through the same encoding, but will only be chunked if - necessary. *) -val make_encoded_messages : - smart_rollup_address:string -> - Ethereum_types.hex -> - (string * string list, 'a) result - -(** List of services supported to communicate with a rollup node. *) -module type S = sig - (** [smart_rollup_address] asks for the smart rollup node's address. *) - val smart_rollup_address : string tzresult Lwt.t - - (** [balance address] returns the [address]'s balance. *) - val balance : Ethereum_types.address -> Ethereum_types.quantity tzresult Lwt.t - - (** [nonce address] returns the [address]'s nonce. *) - val nonce : - Ethereum_types.address -> Ethereum_types.quantity option tzresult Lwt.t - - (** [code address] returns the [address]'s code. *) - val code : Ethereum_types.address -> Ethereum_types.hex tzresult Lwt.t - - (** [inject_raw_transaction ~smart_rollup_address tx_raw] crafts the hash of [tx_raw] and sends to - the injector a message consisting of: - - First 20 bytes: [smart_rollup_address]. - - Following 32 bytes: crafted transaction hash. - - Remaining bytes: [tx_raw] in binary format. - *) - val inject_raw_transaction : - smart_rollup_address:string -> - Ethereum_types.hex -> - Ethereum_types.hash tzresult Lwt.t - - (** [current_block ~full_transaction_object] returns the most recent - processed and stored block. - - If [full_transaction_object] is [true], returns the transaction objects, - the transactions hashes otherwise. - *) - val current_block : - full_transaction_object:bool -> Ethereum_types.block tzresult Lwt.t - - (** [current_block_number ()] returns the most recent processed and stored block - number. *) - val current_block_number : unit -> Ethereum_types.block_height tzresult Lwt.t - - (** [nth_block ~full_transaction_object n] returns the [n]th processed and - stored block. - - If [full_transaction_object] is [true], returns the transaction objects, - the transactions hashes otherwise. - *) - val nth_block : - full_transaction_object:bool -> Z.t -> Ethereum_types.block tzresult Lwt.t - - (** [block_by_hash ~full_transaction_object hash] returns the block with the - given [hash]. - - If [full_transaction_object] is [true], returns the transaction objects, - the transactions hashes otherwise. - *) - val block_by_hash : - full_transaction_object:bool -> - Ethereum_types.block_hash -> - Ethereum_types.block tzresult Lwt.t - - (** [transaction_receipt tx_hash] returns the receipt of [tx_hash]. *) - val transaction_receipt : - Ethereum_types.hash -> - Ethereum_types.transaction_receipt option tzresult Lwt.t - - (** [transaction_object tx_hash] returns the informations of [tx_hash]. *) - val transaction_object : - Ethereum_types.hash -> - Ethereum_types.transaction_object option tzresult Lwt.t - - (** [txpool ()] returns the pending and queued transactions. *) - val txpool : unit -> Ethereum_types.txpool tzresult Lwt.t - - (** [chain_id ()] returns chain id defined by the rollup. *) - val chain_id : unit -> Ethereum_types.quantity tzresult Lwt.t - - (** [base_fee_per_gas ()] returns base fee defined by the rollup. *) - val base_fee_per_gas : unit -> Ethereum_types.quantity tzresult Lwt.t - - (** [kernel_version ()] returns the internal kernel version (i.e the commit hash where - the kernel was compiled). *) - val kernel_version : unit -> string tzresult Lwt.t - - (** [simulate_call call_info] asks the rollup to simulate a call, and returns the - result. *) - val simulate_call : - Ethereum_types.call -> (Ethereum_types.hash, unit) result tzresult Lwt.t - - (** [estimate_gas call_info] asks the rollup to simulate a call, and returns the - gas used to execute the call. *) - val estimate_gas : - Ethereum_types.call -> Ethereum_types.quantity tzresult Lwt.t - - (** [is_tx_valid tx_raw] checks if the transaction is valid. Checks if the nonce is correct - and returns the associated public key of transaction. *) - val is_tx_valid : - Ethereum_types.hex -> (Ethereum_types.address, string) result tzresult Lwt.t - - (** [storage_at address pos] returns the value at index [pos] of the - account [address]'s storage. *) - val storage_at : - Ethereum_types.address -> - Ethereum_types.quantity -> - Ethereum_types.hex tzresult Lwt.t -end - -(** Instantiate a module of type {!S} that communicates with a rollup +(** Instantiate a module of type {!Services_backend_sig.S} that communicates with a rollup node endpoint given by [Base.base]. *) module Make : functor (Base : sig val base : Uri.t end) - -> S + -> Services_backend_sig.S diff --git a/etherlink/bin_evm_node/lib_prod/rollup_node_services.ml b/etherlink/bin_evm_node/lib_prod/rollup_node_services.ml index b3892e5e00f8..bc671e4381d0 100644 --- a/etherlink/bin_evm_node/lib_prod/rollup_node_services.ml +++ b/etherlink/bin_evm_node/lib_prod/rollup_node_services.ml @@ -11,6 +11,35 @@ open Tezos_rpc open Path +type error += Lost_connection + +let () = + let description = + "The EVM node is no longer able to communicate with the rollup node, the \ + communication was lost" + in + register_error_kind + `Temporary + ~id:"evm_node_lost_connection" + ~title:"Lost connection with rollup node" + ~description + ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) + Data_encoding.unit + (function Lost_connection -> Some () | _ -> None) + (fun () -> Lost_connection) + +let is_connection_error trace = + TzTrace.fold + (fun yes error -> + yes + || + match error with + | RPC_client_errors.(Request_failed {error = Connection_failed _; _}) -> + true + | _ -> false) + false + trace + let smart_rollup_address : ([`GET], unit, unit, unit, unit, bytes) Service.service = Service.get_service @@ -46,7 +75,7 @@ let batcher_injection : ~query:Tezos_rpc.Query.empty ~input: Data_encoding.( - def "messages" ~description:"Messages to inject" (list string)) + def "messages" ~description:"Messages to inject" (list (string' Hex))) ~output: Data_encoding.( def @@ -72,5 +101,55 @@ let simulation : ~output:Data_encoding.Json.encoding (open_root / "global" / "block" / "head" / "simulate") -let call_service ~base ?(media_types = Media_type.all_media_types) = - Tezos_rpc_http_client_unix.RPC_client_unix.call_service media_types ~base +let global_block_watcher : + ([`GET], unit, unit, unit, unit, Data_encoding.json) Service.service = + Tezos_rpc.Service.get_service + ~description:"Monitor and streaming the L2 blocks" + ~query:Tezos_rpc.Query.empty + ~output:Data_encoding.json + (open_root / "global" / "monitor_blocks") + +let call_service ~base ?(media_types = Media_type.all_media_types) a b c d = + let open Lwt_result_syntax in + let*! res = + Tezos_rpc_http_client_unix.RPC_client_unix.call_service + media_types + ~base + a + b + c + d + in + match res with + | Ok res -> return res + | Error trace when is_connection_error trace -> fail (Lost_connection :: trace) + | Error trace -> fail trace + +let publish : + rollup_node_endpoint:Uri.t -> + [< `External of string] list -> + unit tzresult Lwt.t = + fun ~rollup_node_endpoint inputs -> + let open Lwt_result_syntax in + let inputs = List.map (function `External s -> s) inputs in + let* _answer = + call_service ~base:rollup_node_endpoint batcher_injection () () inputs + in + return_unit + +(** [smart_rollup_address base] asks for the smart rollup node's + address, using the endpoint [base]. *) +let smart_rollup_address base = + let open Lwt_result_syntax in + let*! answer = + call_service + ~base + ~media_types:[Media_type.octet_stream] + smart_rollup_address + () + () + () + in + match answer with + | Ok address -> return (Bytes.to_string address) + | Error trace -> fail trace diff --git a/etherlink/bin_evm_node/lib_prod/rpc_encodings.ml b/etherlink/bin_evm_node/lib_prod/rpc_encodings.ml index f09c90e1fe90..eb473293e717 100644 --- a/etherlink/bin_evm_node/lib_prod/rpc_encodings.ml +++ b/etherlink/bin_evm_node/lib_prod/rpc_encodings.ml @@ -54,21 +54,21 @@ module JSONRPC = struct type id = id_repr option - type 'params request = { + type request = { method_ : string; - parameters : 'params option; + parameters : Data_encoding.json option; id : id; } - let request_encoding method_ parameters_encoding = + let request_encoding = Data_encoding.( conv - (fun {parameters; id; _} -> ((), (), parameters, id)) - (fun ((), (), parameters, id) -> {method_; parameters; id}) + (fun {parameters; id; method_; _} -> ((), method_, parameters, id)) + (fun ((), method_, parameters, id) -> {method_; parameters; id}) (obj4 (req "jsonrpc" (constant version)) - (req "method" (constant method_)) - (opt "params" parameters_encoding) + (req "method" string) + (opt "params" Data_encoding.json) (opt "id" id_repr_encoding))) type 'data error = {code : int; message : string; data : 'data option} @@ -83,12 +83,11 @@ module JSONRPC = struct (req "message" string) (opt "data" data_encoding))) - type ('result, 'data_error) response = { - value : ('result, 'data_error error) result; - id : id; - } + type value = (Data_encoding.json, Data_encoding.json error) result + + type response = {value : value; id : id} - let response_encoding result_encoding error_data_encoding = + let response_encoding = Data_encoding.( conv (fun {value; id} -> @@ -108,15 +107,11 @@ module JSONRPC = struct {value; id}) (obj4 (req "jsonrpc" (constant version)) - (opt "result" result_encoding) - (opt "error" (error_encoding error_data_encoding)) + (opt "result" Data_encoding.json) + (opt "error" (error_encoding Data_encoding.json)) (req "id" (option id_repr_encoding)))) end -type 'method_ input = .. - -type 'method_ output = .. - module Error = struct type t = unit @@ -125,9 +120,9 @@ end type 'result rpc_result = ('result, Error.t JSONRPC.error) result -module type METHOD_DEF = sig - type method_ +type ('input, 'output) method_ = .. +module type METHOD = sig val method_ : string type input @@ -137,66 +132,11 @@ module type METHOD_DEF = sig val input_encoding : input Data_encoding.t val output_encoding : output Data_encoding.t -end - -module type METHOD = sig - type method_ - - type m_input - - type m_output - - (* The parameters MAY be omitted. See JSONRPC Specification. *) - type 'method_ input += Input : m_input option -> method_ input - - type 'method_ output += Output : m_output rpc_result -> method_ output - - val method_ : string - - val request_encoding : m_input JSONRPC.request Data_encoding.t - - val request : m_input option -> JSONRPC.id -> m_input JSONRPC.request - val response_encoding : (m_output, Error.t) JSONRPC.response Data_encoding.t - - val response : - (m_output, Error.t JSONRPC.error) result -> - JSONRPC.id -> - (m_output, Error.t) JSONRPC.response - - val response_ok : - m_output -> JSONRPC.id -> (m_output, Error.t) JSONRPC.response + type ('input, 'output) method_ += Method : (input, output) method_ end -module MethodMaker (M : METHOD_DEF) : - METHOD with type m_input = M.input and type m_output = M.output = struct - type m_input = M.input - - type m_output = M.output - - type method_ = M.method_ - - type 'a input += Input : m_input option -> method_ input - - type 'a output += Output : m_output rpc_result -> method_ output - - let method_ = M.method_ - - let request_encoding = JSONRPC.request_encoding M.method_ M.input_encoding - - let request parameters id = JSONRPC.{method_; parameters; id} - - let response_encoding = - JSONRPC.response_encoding M.output_encoding Error.encoding - - let response value id = JSONRPC.{value; id} - - let response_ok result id = response (Ok result) id -end - -module Kernel_version = MethodMaker (struct - type method_ - +module Kernel_version = struct type input = unit type output = string @@ -206,11 +146,11 @@ module Kernel_version = MethodMaker (struct let output_encoding = Data_encoding.string let method_ = "tez_kernelVersion" -end) -module Network_id = MethodMaker (struct - type method_ + type ('input, 'output) method_ += Method : (input, output) method_ +end +module Network_id = struct type input = unit type output = string @@ -220,11 +160,11 @@ module Network_id = MethodMaker (struct let output_encoding = Data_encoding.string let method_ = "net_version" -end) -module Chain_id = MethodMaker (struct - type method_ + type ('input, 'output) method_ += Method : (input, output) method_ +end +module Chain_id = struct type input = unit type output = Ethereum_types.quantity @@ -234,11 +174,11 @@ module Chain_id = MethodMaker (struct let output_encoding = Ethereum_types.quantity_encoding let method_ = "eth_chainId" -end) -module Accounts = MethodMaker (struct - type method_ + type ('input, 'output) method_ += Method : (input, output) method_ +end +module Accounts = struct type input = unit type output = Ethereum_types.address list @@ -248,12 +188,12 @@ module Accounts = MethodMaker (struct let output_encoding = Data_encoding.list Ethereum_types.address_encoding let method_ = "eth_accounts" -end) -module Get_balance = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_balance = struct + open Ethereum_types type input = address * block_param @@ -264,12 +204,12 @@ module Get_balance = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getBalance" -end) -module Get_storage_at = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_storage_at = struct + open Ethereum_types type input = address * quantity * block_param @@ -281,12 +221,12 @@ module Get_storage_at = MethodMaker (struct let output_encoding = hex_encoding let method_ = "eth_getStorageAt" -end) -module Block_number = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Block_number = struct + open Ethereum_types type input = unit @@ -297,12 +237,12 @@ module Block_number = MethodMaker (struct let output_encoding = block_height_encoding let method_ = "eth_blockNumber" -end) -module Get_block_by_number = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_block_by_number = struct + open Ethereum_types type input = block_param * bool @@ -314,12 +254,12 @@ module Get_block_by_number = MethodMaker (struct let output_encoding = block_encoding let method_ = "eth_getBlockByNumber" -end) -module Get_block_by_hash = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_block_by_hash = struct + open Ethereum_types type input = block_hash * bool @@ -330,12 +270,12 @@ module Get_block_by_hash = MethodMaker (struct let output_encoding = block_encoding let method_ = "eth_getBlockByHash" -end) -module Get_code = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_code = struct + open Ethereum_types type input = address * block_param @@ -346,12 +286,12 @@ module Get_code = MethodMaker (struct let output_encoding = hex_encoding let method_ = "eth_getCode" -end) -module Gas_price = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Gas_price = struct + open Ethereum_types type input = unit @@ -362,12 +302,12 @@ module Gas_price = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_gasPrice" -end) -module Get_transaction_count = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_transaction_count = struct + open Ethereum_types type input = address * block_param @@ -378,12 +318,12 @@ module Get_transaction_count = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getTransactionCount" -end) -module Get_block_transaction_count_by_hash = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_block_transaction_count_by_hash = struct + open Ethereum_types type input = block_hash @@ -394,12 +334,12 @@ module Get_block_transaction_count_by_hash = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getBlockTransactionCountByHash" -end) -module Get_block_transaction_count_by_number = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_block_transaction_count_by_number = struct + open Ethereum_types type input = block_param @@ -410,12 +350,12 @@ module Get_block_transaction_count_by_number = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getBlockTransactionCountByNumber" -end) -module Get_uncle_count_by_block_hash = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_uncle_count_by_block_hash = struct + open Ethereum_types type input = block_hash @@ -426,12 +366,12 @@ module Get_uncle_count_by_block_hash = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getUncleCountByBlockHash" -end) -module Get_uncle_count_by_block_number = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_uncle_count_by_block_number = struct + open Ethereum_types type input = block_param @@ -442,12 +382,12 @@ module Get_uncle_count_by_block_number = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_getUncleCountByBlockNumber" -end) -module Get_transaction_receipt = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_transaction_receipt = struct + open Ethereum_types type input = hash @@ -458,12 +398,12 @@ module Get_transaction_receipt = MethodMaker (struct let output_encoding = Data_encoding.option transaction_receipt_encoding let method_ = "eth_getTransactionReceipt" -end) -module Get_transaction_by_hash = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_transaction_by_hash = struct + open Ethereum_types type input = hash @@ -474,12 +414,12 @@ module Get_transaction_by_hash = MethodMaker (struct let output_encoding = Data_encoding.option transaction_object_encoding let method_ = "eth_getTransactionByHash" -end) -module Get_transaction_by_block_hash_and_index = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_transaction_by_block_hash_and_index = struct + open Ethereum_types type input = block_hash * quantity @@ -490,12 +430,12 @@ module Get_transaction_by_block_hash_and_index = MethodMaker (struct let output_encoding = Data_encoding.option transaction_object_encoding let method_ = "eth_getTransactionByBlockHashAndIndex" -end) -module Get_transaction_by_block_number_and_index = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_transaction_by_block_number_and_index = struct + open Ethereum_types type input = block_param * quantity @@ -506,12 +446,12 @@ module Get_transaction_by_block_number_and_index = MethodMaker (struct let output_encoding = Data_encoding.option transaction_object_encoding let method_ = "eth_getTransactionByBlockNumberAndIndex" -end) -module Get_uncle_by_block_hash_and_index = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_uncle_by_block_hash_and_index = struct + open Ethereum_types type input = block_hash * quantity @@ -522,12 +462,12 @@ module Get_uncle_by_block_hash_and_index = MethodMaker (struct let output_encoding = Data_encoding.option block_encoding let method_ = "eth_getUncleByBlockHashAndIndex" -end) -module Get_uncle_by_block_number_and_index = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_uncle_by_block_number_and_index = struct + open Ethereum_types type input = block_param * quantity @@ -538,12 +478,12 @@ module Get_uncle_by_block_number_and_index = MethodMaker (struct let output_encoding = Data_encoding.option block_encoding let method_ = "eth_getUncleByBlockNumberAndIndex" -end) -module Send_raw_transaction = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Send_raw_transaction = struct + open Ethereum_types type input = hex @@ -554,12 +494,12 @@ module Send_raw_transaction = MethodMaker (struct let output_encoding = hash_encoding let method_ = "eth_sendRawTransaction" -end) -module Send_transaction = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Send_transaction = struct + open Ethereum_types type input = transaction @@ -570,12 +510,12 @@ module Send_transaction = MethodMaker (struct let output_encoding = hash_encoding let method_ = "eth_sendTransaction" -end) -module Eth_call = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Eth_call = struct + open Ethereum_types type input = call * block_param @@ -586,12 +526,12 @@ module Eth_call = MethodMaker (struct let output_encoding = hash_encoding let method_ = "eth_call" -end) -module Get_estimate_gas = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_estimate_gas = struct + open Ethereum_types type input = call * block_param @@ -619,12 +559,12 @@ module Get_estimate_gas = MethodMaker (struct let output_encoding = quantity_encoding let method_ = "eth_estimateGas" -end) -module Txpool_content = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Txpool_content = struct + open Ethereum_types type input = unit @@ -635,12 +575,12 @@ module Txpool_content = MethodMaker (struct let output_encoding = txpool_encoding let method_ = "txpool_content" -end) -module Web3_clientVersion = MethodMaker (struct - type input = unit + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Web3_clientVersion = struct + type input = unit type output = string @@ -649,12 +589,12 @@ module Web3_clientVersion = MethodMaker (struct let output_encoding = Data_encoding.string let method_ = "web3_clientVersion" -end) -module Web3_sha3 = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Web3_sha3 = struct + open Ethereum_types type input = hex @@ -665,12 +605,12 @@ module Web3_sha3 = MethodMaker (struct let output_encoding = hash_encoding let method_ = "web3_sha3" -end) -module Get_logs = MethodMaker (struct - open Ethereum_types + type ('input, 'output) method_ += Method : (input, output) method_ +end - type method_ +module Get_logs = struct + open Ethereum_types type input = filter @@ -681,9 +621,33 @@ module Get_logs = MethodMaker (struct let output_encoding = Data_encoding.list filter_changes_encoding let method_ = "eth_getLogs" -end) -let methods : (module METHOD) list = + type ('input, 'output) method_ += Method : (input, output) method_ +end + +module Produce_block = struct + type input = unit + + type output = Ethereum_types.quantity + + let input_encoding = Data_encoding.unit + + let output_encoding = Ethereum_types.quantity_encoding + + let method_ = "produceBlock" + + type ('input, 'output) method_ += Method : (input, output) method_ +end + +type map_result = + | Method : + ('input, 'output) method_ + * (module METHOD with type input = 'input and type output = 'output) + -> map_result + | Unsupported + | Unknown + +let supported_methods : (module METHOD) list = [ (module Kernel_version); (module Network_id); @@ -715,43 +679,31 @@ let methods : (module METHOD) list = (module Txpool_content); (module Web3_clientVersion); (module Web3_sha3); + (module Produce_block); ] -module Input = struct - type t = Box : 'a input -> t [@@ocaml.unboxed] - - let case_maker tag_id (module M : METHOD) = - let open Data_encoding in - case - ~title:M.method_ - (Tag tag_id) - M.request_encoding - (function - | Box (M.Input input), id -> Some (M.request input id) | _ -> None) - (fun {parameters; id; _} -> (Box (M.Input parameters), id)) - - let encoding = - let open Data_encoding in - union @@ List.mapi case_maker methods -end - -module Output = struct - type nonrec 'a result = ('a, error JSONRPC.error) result - - type t = Box : 'a output -> t [@@ocaml.unboxed] +let unsupported_methods : string list = + [ + "net_listening"; + "net_peerCount"; + "eth_protocolVersion"; + "eth_syncing"; + "eth_coinbase"; + "eth_mining"; + "eth_hashrate"; + "eth_accounts"; + "eth_sign"; + "eth_signTransaction"; + "eth_sendTransaction"; + ] - let case_maker tag_id (module M : METHOD) = - let open Data_encoding in - case - ~title:M.method_ - (Tag tag_id) - M.response_encoding - (function - | Box (M.Output accounts), id -> Some JSONRPC.{value = accounts; id} - | _ -> None) - (fun {value = req; id} -> (Box (M.Output req), id)) - - let encoding = - let open Data_encoding in - union @@ List.mapi case_maker methods -end +let map_method_name method_name = + match + List.find + (fun (module M : METHOD) -> M.method_ = method_name) + supported_methods + with + | Some (module M) -> Method (M.Method, (module M)) + | None -> + if List.mem ~equal:( = ) method_name unsupported_methods then Unsupported + else Unknown diff --git a/etherlink/bin_evm_node/lib_prod/rpc_encodings.mli b/etherlink/bin_evm_node/lib_prod/rpc_encodings.mli index 6d5b39543fa3..46512f3ddd25 100644 --- a/etherlink/bin_evm_node/lib_prod/rpc_encodings.mli +++ b/etherlink/bin_evm_node/lib_prod/rpc_encodings.mli @@ -49,14 +49,13 @@ module JSONRPC : sig } ]} *) - type 'params request = { + type request = { method_ : string; - parameters : 'params option; (** `params` is optional. *) + parameters : Data_encoding.json option; (** `params` is optional. *) id : id; (** `id` is optional. *) } - val request_encoding : - string -> 'a Data_encoding.t -> 'a request Data_encoding.t + val request_encoding : request Data_encoding.t (** JSON-RPC Error representation. {@js[ @@ -70,6 +69,8 @@ module JSONRPC : sig val error_encoding : 'a Data_encoding.t -> 'a error Data_encoding.t + type value = (Data_encoding.json, Data_encoding.json error) result + (** JSON-RPC Response object: {@js[ { "jsonrpc": "2.0", @@ -81,15 +82,9 @@ module JSONRPC : sig Note that `result` and `error` cannot appear at the same time, hence the choice of using the result type as representation. *) - type ('result, 'data_error) response = { - value : ('result, 'data_error error) result; - id : id; - } + type response = {value : value; id : id} - val response_encoding : - 'a Data_encoding.t -> - 'b Data_encoding.t -> - ('a, 'b) response Data_encoding.t + val response_encoding : response Data_encoding.t end (* Errors returned by the RPC server, to be embedded as data to the JSON-RPC @@ -100,26 +95,12 @@ module Error : sig val encoding : unit Data_encoding.t end -(** Extensible variant representing the possible input requests extended by the - application of the method generator. - Parameterized by a type indicating which method this input is for. -*) -type 'method_ input = .. - -(** Extensible variant representing the possible outputs extended by the - application of the method generator. - Parameterized by a type indicating which method produced this output. -*) -type 'method_ output = .. - type 'result rpc_result = ('result, Error.t JSONRPC.error) result -(** API of an Ethereum method. *) -module type METHOD_DEF = sig - (** Type-level identifier of the method. - Used as parameter for [input] and [output] types. *) - type method_ +type ('input, 'output) method_ = .. +(** API of an Ethereum method. *) +module type METHOD = sig (** Method name in the specification. *) val method_ : string @@ -132,206 +113,154 @@ module type METHOD_DEF = sig val input_encoding : input Data_encoding.t val output_encoding : output Data_encoding.t -end - -(** Interface of a generated method. *) -module type METHOD = sig - type method_ - - (** Input type of the method, if any. *) - type m_input - - (** Output type of the method. *) - type m_output - - (** Variant representing the method's request. *) - type 'a input += Input : m_input option -> method_ input - - (** Variant representing the method's response. *) - type 'a output += Output : m_output rpc_result -> method_ output - - (** See METHOD_DEF.method_ *) - val method_ : string - val request_encoding : m_input JSONRPC.request Data_encoding.t - - (** [request input] builds a request object of the current method. *) - val request : m_input option -> JSONRPC.id -> m_input JSONRPC.request - - val response_encoding : (m_output, Error.t) JSONRPC.response Data_encoding.t - - (** [response output] returns a response object for the method. *) - val response : - (m_output, Error.t JSONRPC.error) result -> - JSONRPC.id -> - (m_output, Error.t) JSONRPC.response - - (** [response_ok output] is a shortcut for [reponse (Ok output)]. *) - val response_ok : - m_output -> JSONRPC.id -> (m_output, Error.t) JSONRPC.response -end - -(** Builds a full Method module out of a method description. *) -module MethodMaker : functor (M : METHOD_DEF) -> - METHOD with type m_input = M.input and type m_output = M.output - -(** [methods] is the list of currently defined methods. *) -val methods : (module METHOD) list - -(** [Input] defines the input encoding matching the defined methods in - [methods]. *) -module Input : sig - type t = Box : 'a input -> t [@@ocaml.unboxed] - - val encoding : (t * JSONRPC.id) Data_encoding.t + type ('input, 'output) method_ += Method : (input, output) method_ end -(** [Output] defines the output encoding matching the defined methods in - [methods]. *) -module Output : sig - type nonrec 'a result = ('a, error JSONRPC.error) result +module Kernel_version : METHOD with type input = unit and type output = string - type t = Box : 'a output -> t [@@ocaml.unboxed] - - val encoding : (t * JSONRPC.id) Data_encoding.t -end - -module Kernel_version : - METHOD with type m_input = unit and type m_output = string - -module Network_id : METHOD with type m_input = unit and type m_output = string +module Network_id : METHOD with type input = unit and type output = string module Chain_id : - METHOD with type m_input = unit and type m_output = Ethereum_types.quantity + METHOD with type input = unit and type output = Ethereum_types.quantity module Accounts : - METHOD - with type m_input = unit - and type m_output = Ethereum_types.address list + METHOD with type input = unit and type output = Ethereum_types.address list module Get_balance : METHOD - with type m_input = Ethereum_types.address * Ethereum_types.block_param - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.address * Ethereum_types.block_param + and type output = Ethereum_types.quantity module Get_storage_at : METHOD - with type m_input = + with type input = Ethereum_types.address * Ethereum_types.quantity * Ethereum_types.block_param - and type m_output = Ethereum_types.hex + and type output = Ethereum_types.hex module Block_number : - METHOD - with type m_input = unit - and type m_output = Ethereum_types.block_height + METHOD with type input = unit and type output = Ethereum_types.block_height module Get_block_by_number : METHOD - with type m_input = Ethereum_types.block_param * bool - and type m_output = Ethereum_types.block + with type input = Ethereum_types.block_param * bool + and type output = Ethereum_types.block module Get_block_by_hash : METHOD - with type m_input = Ethereum_types.block_hash * bool - and type m_output = Ethereum_types.block + with type input = Ethereum_types.block_hash * bool + and type output = Ethereum_types.block module Get_code : METHOD - with type m_input = Ethereum_types.address * Ethereum_types.block_param - and type m_output = Ethereum_types.hex + with type input = Ethereum_types.address * Ethereum_types.block_param + and type output = Ethereum_types.hex module Gas_price : - METHOD with type m_input = unit and type m_output = Ethereum_types.quantity + METHOD with type input = unit and type output = Ethereum_types.quantity module Get_transaction_count : METHOD - with type m_input = Ethereum_types.address * Ethereum_types.block_param - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.address * Ethereum_types.block_param + and type output = Ethereum_types.quantity module Get_block_transaction_count_by_hash : METHOD - with type m_input = Ethereum_types.block_hash - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.block_hash + and type output = Ethereum_types.quantity module Get_block_transaction_count_by_number : METHOD - with type m_input = Ethereum_types.block_param - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.block_param + and type output = Ethereum_types.quantity module Get_uncle_count_by_block_hash : METHOD - with type m_input = Ethereum_types.block_hash - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.block_hash + and type output = Ethereum_types.quantity module Get_uncle_count_by_block_number : METHOD - with type m_input = Ethereum_types.block_param - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.block_param + and type output = Ethereum_types.quantity module Get_transaction_receipt : METHOD - with type m_input = Ethereum_types.hash - and type m_output = Ethereum_types.transaction_receipt option + with type input = Ethereum_types.hash + and type output = Ethereum_types.transaction_receipt option module Get_transaction_by_hash : METHOD - with type m_input = Ethereum_types.hash - and type m_output = Ethereum_types.transaction_object option + with type input = Ethereum_types.hash + and type output = Ethereum_types.transaction_object option module Get_transaction_by_block_hash_and_index : METHOD - with type m_input = Ethereum_types.block_hash * Ethereum_types.quantity - and type m_output = Ethereum_types.transaction_object option + with type input = Ethereum_types.block_hash * Ethereum_types.quantity + and type output = Ethereum_types.transaction_object option module Get_transaction_by_block_number_and_index : METHOD - with type m_input = Ethereum_types.block_param * Ethereum_types.quantity - and type m_output = Ethereum_types.transaction_object option + with type input = Ethereum_types.block_param * Ethereum_types.quantity + and type output = Ethereum_types.transaction_object option module Get_uncle_by_block_hash_and_index : METHOD - with type m_input = Ethereum_types.block_hash * Ethereum_types.quantity - and type m_output = Ethereum_types.block option + with type input = Ethereum_types.block_hash * Ethereum_types.quantity + and type output = Ethereum_types.block option module Get_uncle_by_block_number_and_index : METHOD - with type m_input = Ethereum_types.block_param * Ethereum_types.quantity - and type m_output = Ethereum_types.block option + with type input = Ethereum_types.block_param * Ethereum_types.quantity + and type output = Ethereum_types.block option module Send_raw_transaction : METHOD - with type m_input = Ethereum_types.hex - and type m_output = Ethereum_types.hash + with type input = Ethereum_types.hex + and type output = Ethereum_types.hash module Send_transaction : METHOD - with type m_input = Ethereum_types.transaction - and type m_output = Ethereum_types.hash + with type input = Ethereum_types.transaction + and type output = Ethereum_types.hash module Eth_call : METHOD - with type m_input = Ethereum_types.call * Ethereum_types.block_param - and type m_output = Ethereum_types.hash + with type input = Ethereum_types.call * Ethereum_types.block_param + and type output = Ethereum_types.hash module Get_estimate_gas : METHOD - with type m_input = Ethereum_types.call * Ethereum_types.block_param - and type m_output = Ethereum_types.quantity + with type input = Ethereum_types.call * Ethereum_types.block_param + and type output = Ethereum_types.quantity module Txpool_content : - METHOD with type m_input = unit and type m_output = Ethereum_types.txpool + METHOD with type input = unit and type output = Ethereum_types.txpool module Web3_clientVersion : - METHOD with type m_input = unit and type m_output = string + METHOD with type input = unit and type output = string module Web3_sha3 : METHOD - with type m_input = Ethereum_types.hex - and type m_output = Ethereum_types.hash + with type input = Ethereum_types.hex + and type output = Ethereum_types.hash module Get_logs : METHOD - with type m_input = Ethereum_types.filter - and type m_output = Ethereum_types.filter_changes list + with type input = Ethereum_types.filter + and type output = Ethereum_types.filter_changes list + +module Produce_block : + METHOD with type input = unit and type output = Ethereum_types.quantity + +type map_result = + | Method : + ('input, 'output) method_ + * (module METHOD with type input = 'input and type output = 'output) + -> map_result + | Unsupported + | Unknown + +val map_method_name : string -> map_result diff --git a/etherlink/bin_evm_node/lib_prod/sequencer.ml b/etherlink/bin_evm_node/lib_prod/sequencer.ml new file mode 100644 index 000000000000..41bde1bdbda1 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer.ml @@ -0,0 +1,78 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module MakeBackend (Ctxt : sig + val ctxt : Sequencer_context.t + + val rollup_node_endpoint : Uri.t +end) : Services_backend_sig.Backend = struct + module READER = struct + let read path = + let open Lwt_result_syntax in + let* Sequencer_context.{evm_state; _} = + Sequencer_context.sync Ctxt.ctxt + in + let*! res = Sequencer_state.inspect evm_state path in + return res + end + + module TxEncoder = struct + let encode_transaction ~smart_rollup_address:_ ~transaction = + let tx_hash_str = Ethereum_types.hash_raw_tx transaction in + let tx_hash = + Ethereum_types.( + Hash Hex.(of_string tx_hash_str |> show |> hex_of_string)) + in + Result_syntax.return (tx_hash, [transaction]) + end + + module Publisher = struct + let publish_messages ~timestamp ~smart_rollup_address ~messages = + let open Lwt_result_syntax in + let* ctxt = Sequencer_context.sync Ctxt.ctxt in + (* Create the blueprint with the messages. *) + let (Ethereum_types.(Qty next) as number) = ctxt.next_blueprint_number in + let inputs = + Sequencer_blueprint.create + ~timestamp + ~smart_rollup_address + ~transactions:messages + ~number + in + let* () = + Rollup_node_services.publish + ~rollup_node_endpoint:Ctxt.rollup_node_endpoint + inputs + in + ctxt.next_blueprint_number <- Qty (Z.succ next) ; + (* Execute the blueprint. *) + let inputs = + List.map + (function `External payload -> `Input ("\001" ^ payload)) + inputs + in + let* _ctxt = Sequencer_state.execute ~commit:true ctxt inputs in + return_unit + end + + module SimulatorBackend = struct + let simulate_and_read ~input = + let open Lwt_result_syntax in + let* ctxt = Sequencer_context.sync Ctxt.ctxt in + let* raw_insights = Sequencer_state.execute_and_inspect ctxt ~input in + match Simulation.Encodings.insights_from_list raw_insights with + | Some i -> return i + | None -> Error_monad.failwith "Invalid insights format" + end +end + +module Make (Ctxt : sig + val ctxt : Sequencer_context.t + + val rollup_node_endpoint : Uri.t +end) = + Services_backend_sig.Make (MakeBackend (Ctxt)) diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.ml b/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.ml new file mode 100644 index 000000000000..7088b7fd82d2 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.ml @@ -0,0 +1,90 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +open Ethereum_types + +(* U256 *) +let blueprint_number_size = 32 + +(* U16 *) +let nb_chunks_size = 2 + +(* U16 *) +let chunk_index_size = 2 + +let blueprint_tag_size = 1 + +(* Tags added by RLP encoding for the sequencer blueprint. + The sequencer blueprint follows the format: + [ chunk, <- max size around 4kb, requires tag of 3 bytes + number, <- 32 bytes, requires a tag of 1 byte + nb_chunks, <- 2 bytes, requires a tag of 1 byte + chunk_index <- 2 bytes, requires a tag of 1 byte + ] <- outer list requires tag of 3 bytes. + + In total, the tags take 9 bytes. We use 16 to be safe. +*) +let rlp_tags_size = 16 + +let max_chunk_size = + let open Transaction_format in + (* max_input_size already considers the external tag *) + max_input_size - framing_protocol_tag_size - smart_rollup_address_size + - blueprint_tag_size - blueprint_number_size - nb_chunks_size + - chunk_index_size - rlp_tags_size + +let make_blueprint_chunks ~timestamp ~transactions = + let open Rlp in + let messages = + List + (List.map + (fun transaction -> + let tx_hash_str = Ethereum_types.hash_raw_tx transaction in + List + [ + Value (Bytes.of_string tx_hash_str); + List + [ + Value (Bytes.of_string "\001"); + Value (Bytes.of_string transaction); + ]; + ]) + transactions) + in + let timestamp = Value (Helpers.timestamp_to_bytes timestamp) in + let blob = List [messages; timestamp] |> encode in + match String.chunk_bytes max_chunk_size blob with + | Ok chunks -> chunks + | Error _ -> + (* [chunk_bytes] can only return an [Error] if the optional + argument [error_on_partial_chunk] is passed. As this is not + the case in this call, this branch is impossible. *) + assert false + +let encode_u16_le i = + let bytes = Bytes.make 2 '\000' in + Bytes.set_uint16_le bytes 0 i ; + bytes + +let create ~timestamp ~smart_rollup_address ~number ~transactions = + let open Rlp in + let number = Value (encode_u256_le number) in + let chunks = make_blueprint_chunks ~timestamp ~transactions in + let nb_chunks = Rlp.Value (encode_u16_le @@ List.length chunks) in + let message_from_chunk chunk_index chunk = + let chunk_index = Rlp.Value (encode_u16_le chunk_index) in + let rlp_sequencer_blueprint = + List [Value (Bytes.of_string chunk); number; nb_chunks; chunk_index] + |> encode |> Bytes.to_string + in + `External + ("\000" (* Framed protocol *) ^ smart_rollup_address + ^ "\003" + ^ (* Sequencer blueprint *) + rlp_sequencer_blueprint) + in + List.mapi message_from_chunk chunks diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.mli b/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.mli new file mode 100644 index 000000000000..e3f0cf49cc37 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_blueprint.mli @@ -0,0 +1,18 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(** [create ~timestamp ~smart_rollup_address ~number ~transactions] + creates a sequencer blueprint at [timestamp] with a given [number] + containing [transactions]. Returns valid payload of external + messages inputs to put in the inbox. +*) +val create : + timestamp:Time.Protocol.t -> + smart_rollup_address:string -> + number:Ethereum_types.quantity -> + transactions:string list -> + [> `External of string] list diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_context.ml b/etherlink/bin_evm_node/lib_prod/sequencer_context.ml new file mode 100644 index 000000000000..c957efc54a9a --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_context.ml @@ -0,0 +1,124 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module Context = Tezos_context_disk.Context_binary + +type index = Context.index + +type store = Context.t + +type evm_state = Context.tree + +type t = { + data_dir : string; + index : index; + store : store; + evm_state : evm_state; + kernel : string; + preimages : string; + smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; + mutable next_blueprint_number : Ethereum_types.quantity; +} + +(** The EVM/PVM local state used by the sequencer. *) +module EVMState = struct + let key = ["evm_state"] + + let get store = + let open Lwt_result_syntax in + let*! tree_opt = Context.find_tree store key in + match tree_opt with + | Some tree -> return tree + | None -> failwith "The EVM state was not found" + + let set ctxt tree = + let open Lwt_syntax in + let* store = Context.add_tree ctxt.store key tree in + return {ctxt with store} +end + +type metadata = { + checkpoint : Context_hash.t; + next_blueprint_number : Ethereum_types.quantity; +} + +let store_path ~data_dir = Filename.Infix.(data_dir // "store") + +let metadata_path ~data_dir = Filename.Infix.(data_dir // "metadata") + +let metadata_encoding = + let open Data_encoding in + conv + (fun {checkpoint; next_blueprint_number} -> + (checkpoint, next_blueprint_number)) + (fun (checkpoint, next_blueprint_number) -> + {checkpoint; next_blueprint_number}) + (obj2 + (req "checkpoint" Context_hash.encoding) + (req "next_blueprint_number" Ethereum_types.quantity_encoding)) + +let store_metadata ~data_dir metadata = + let json = Data_encoding.Json.construct metadata_encoding metadata in + Lwt_utils_unix.Json.write_file (metadata_path ~data_dir) json + +let load_metadata ~data_dir index = + let open Lwt_result_syntax in + let path = metadata_path ~data_dir in + let*! exists = Lwt_unix.file_exists path in + if exists then + let* content = Lwt_utils_unix.Json.read_file path in + let {checkpoint; next_blueprint_number} = + Data_encoding.Json.destruct metadata_encoding content + in + let*! store = Context.checkout_exn index checkpoint in + let* evm_state = EVMState.get store in + return (store, evm_state, next_blueprint_number, true) + else + let store = Context.empty index in + let evm_state = Context.Tree.empty store in + return (store, evm_state, Ethereum_types.Qty Z.zero, false) + +let init ~data_dir ~kernel ~preimages ~smart_rollup_address = + let open Lwt_result_syntax in + let*! index = Context.init (store_path ~data_dir) in + let* store, evm_state, next_blueprint_number, loaded = + load_metadata ~data_dir index + in + let smart_rollup_address = + Tezos_crypto.Hashed.Smart_rollup_address.of_string_exn smart_rollup_address + in + return + ( { + index; + store; + data_dir; + evm_state; + kernel; + preimages; + smart_rollup_address; + next_blueprint_number; + }, + loaded ) + +let commit ctxt evm_state = + let open Lwt_result_syntax in + let*! ctxt = EVMState.set ctxt evm_state in + let*! checkpoint = Context.commit ~time:Time.Protocol.epoch ctxt.store in + let* () = + store_metadata + ~data_dir:ctxt.data_dir + {checkpoint; next_blueprint_number = ctxt.next_blueprint_number} + in + return {ctxt with evm_state} + +let sync ctxt = + let open Lwt_result_syntax in + let*! () = Context.sync ctxt.index in + let* store, evm_state, next_blueprint_number, _loaded = + load_metadata ~data_dir:ctxt.data_dir ctxt.index + in + return {ctxt with store; evm_state; next_blueprint_number} diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_context.mli b/etherlink/bin_evm_node/lib_prod/sequencer_context.mli new file mode 100644 index 000000000000..883bc3cd1ee8 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_context.mli @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module Context : Tezos_tree_encoding.Encodings_util.Bare_tezos_context_sig + +type index + +type store + +type evm_state = Context.tree + +type t = { + data_dir : string; (** Data dir of the EVM node. *) + index : index; (** Irmin index. *) + store : store; (** Irmin store. *) + evm_state : evm_state; (** EVM local state of the sequencer. *) + kernel : string; (** Path to the kernel to execute. *) + preimages : string; (** Path to the preimages directory. *) + smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; + mutable next_blueprint_number : Ethereum_types.quantity; + (** Number for the next bluerpint to be produced. *) +} + +(** [init ~data_dir ~kernel ~preimages ~smart_rollup_address] creates + a context where it initializes the {!type-index}, and use a + checkpoint mechanism to load the latest {!type-store} if any. + + Also returns a boolean denoting whether the context was initialized or not. +*) +val init : + data_dir:string -> + kernel:string -> + preimages:string -> + smart_rollup_address:string -> + (t * bool) tzresult Lwt.t + +(** [commit ctxt evm_state] updates the [evm_state] in [ctxt], commits + to disk the changes, and update the checkpoint. *) +val commit : t -> evm_state -> t tzresult Lwt.t + +(** [sync ctxt] synchronizes the [ctxt] based on on-disk information, loads the + latest checkpoint. *) +val sync : t -> t tzresult Lwt.t diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_state.ml b/etherlink/bin_evm_node/lib_prod/sequencer_state.ml new file mode 100644 index 000000000000..8131af386d7c --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_state.ml @@ -0,0 +1,80 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module TreeEncoding = + Wasm_utils.Make + (Tezos_tree_encoding.Encodings_util.Make (Sequencer_context.Context)) +module Wasm = Wasm_debugger.Make (TreeEncoding) + +let execute ?(commit = false) ctxt inbox = + let open Lwt_result_syntax in + let inbox = List.map (function `Input s -> s) inbox in + let inbox = List.to_seq [inbox] in + let config = + Config.config + ~preimage_directory:ctxt.Sequencer_context.preimages + ~kernel_debug:true + ~destination:ctxt.Sequencer_context.smart_rollup_address + () + in + let* evm_state, _, _, _ = + Wasm.Commands.eval 0l inbox config Inbox ctxt.Sequencer_context.evm_state + in + let* ctxt = + if commit then Sequencer_context.commit ctxt evm_state else return ctxt + in + return (ctxt, evm_state) + +let init ~smart_rollup_address ~rollup_node_endpoint ctxt = + let open Lwt_result_syntax in + let* evm_state = + Wasm.start + ~tree:ctxt.Sequencer_context.evm_state + Tezos_scoru_wasm.Wasm_pvm_state.V3 + ctxt.kernel + in + let ctxt = + {ctxt with evm_state; next_blueprint_number = Ethereum_types.(Qty Z.one)} + in + (* Create the first empty block. *) + let inputs = + Sequencer_blueprint.create + ~timestamp:(Helpers.now ()) + ~smart_rollup_address + ~transactions:[] + ~number:Ethereum_types.(Qty Z.zero) + in + let* () = Rollup_node_services.publish ~rollup_node_endpoint inputs in + let inputs = + List.map (function `External payload -> `Input ("\001" ^ payload)) inputs + in + let* ctxt, _evm_state = execute ~commit:true ctxt inputs in + return ctxt + +let inspect evm_state key = + let open Lwt_syntax in + let key = Tezos_scoru_wasm.Durable.key_of_string_exn key in + let* value = Wasm.Commands.find_key_in_durable evm_state key in + Option.map_s Tezos_lazy_containers.Chunked_byte_vector.to_bytes value + +let execute_and_inspect ctxt + ~input:Simulation.Encodings.{messages; insight_requests; _} = + let open Lwt_result_syntax in + let keys = + List.map + (function + | Simulation.Encodings.Durable_storage_key l -> + "/" ^ String.concat "/" l + (* We use only `Durable_storage_key` in simulation. *) + | _ -> assert false) + insight_requests + in + (* Messages from simulation requests are already valid inputs. *) + let messages = List.map (fun s -> `Input s) messages in + let* _ctxt, evm_state = execute ctxt messages in + let*! values = List.map_p (fun key -> inspect evm_state key) keys in + return values diff --git a/etherlink/bin_evm_node/lib_prod/sequencer_state.mli b/etherlink/bin_evm_node/lib_prod/sequencer_state.mli new file mode 100644 index 000000000000..ff90ce82425f --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/sequencer_state.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(** [execute ?commit ctxt messages] executes [messages] on the local + EVM state of [ctxt], commits to disk if [commit] is true. Returns + the modified EVM state even if it's not commited. *) +val execute : + ?commit:bool -> + Sequencer_context.t -> + [< `Input of string] list -> + (Sequencer_context.t * Sequencer_context.evm_state) tzresult Lwt.t + +(** [init ~smart_rollup_address ~rollup_node_endpoint ctxt] + initializes the local state in [ctxt], produces and publishes the + genesis block. *) +val init : + smart_rollup_address:string -> + rollup_node_endpoint:Uri.t -> + Sequencer_context.t -> + Sequencer_context.t tzresult Lwt.t + +(** [inspect evm_state key] inspects [key] in [evm_state]. *) +val inspect : Sequencer_context.evm_state -> string -> bytes option Lwt.t + +(** [execute_and_inspect ctxt ~input] executes [input] in [ctxt] and + returns the [input.insights_requests]. *) +val execute_and_inspect : + Sequencer_context.t -> + input:Simulation.Encodings.simulate_input -> + bytes option list tzresult Lwt.t diff --git a/etherlink/bin_evm_node/lib_prod/services.ml b/etherlink/bin_evm_node/lib_prod/services.ml index 3330c1aef4ca..72257b4de63b 100644 --- a/etherlink/bin_evm_node/lib_prod/services.ml +++ b/etherlink/bin_evm_node/lib_prod/services.ml @@ -51,7 +51,7 @@ let version dir = (* The node can either take a single request or multiple requests at once. *) -type 'a request = Singleton of 'a | Batch of 'a list +type 'a batched_request = Singleton of 'a | Batch of 'a list let request_encoding kind = Data_encoding.( @@ -71,15 +71,15 @@ let request_encoding kind = (fun i -> Batch i); ]) -let dispatch_service = +let dispatch_service ~path = Service.post_service ~query:Query.empty - ~input:(request_encoding Input.encoding) - ~output:(request_encoding Output.encoding) - Path.(root) + ~input:(request_encoding JSONRPC.request_encoding) + ~output:(request_encoding JSONRPC.response_encoding) + path let get_block_by_number ~full_transaction_object block_param - (module Rollup_node_rpc : Rollup_node.S) = + (module Rollup_node_rpc : Services_backend_sig.S) = match block_param with | Ethereum_types.(Hash_param (Block_height n)) -> Rollup_node_rpc.nth_block ~full_transaction_object n @@ -87,7 +87,7 @@ let get_block_by_number ~full_transaction_object block_param Rollup_node_rpc.current_block ~full_transaction_object let get_transaction_from_index block index - (module Rollup_node_rpc : Rollup_node.S) = + (module Rollup_node_rpc : Services_backend_sig.S) = let open Lwt_result_syntax in match block.Ethereum_types.transactions with | TxHash l -> ( @@ -103,199 +103,453 @@ let block_transaction_count block = | TxHash l -> List.length l | TxFull l -> List.length l -let dispatch_input (config : 'a Configuration.t) - ((module Rollup_node_rpc : Rollup_node.S), _) (input, id) = - let open Lwt_result_syntax in - let dispatch_input_aux : type w. w input -> w output tzresult Lwt.t = function - (* INTERNAL RPCs *) - | Kernel_version.Input _ -> - let* kernel_version = Rollup_node_rpc.kernel_version () in - return (Kernel_version.Output (Ok kernel_version)) - (* ETHEREUM JSON-RPC API *) - | Accounts.Input _ -> return (Accounts.Output (Ok [])) - | Network_id.Input _ -> - let* (Qty chain_id) = Rollup_node_rpc.chain_id () in - let net_version = Z.to_string chain_id in - return (Network_id.Output (Ok net_version)) - | Chain_id.Input _ -> - let* chain_id = Rollup_node_rpc.chain_id () in - return (Chain_id.Output (Ok chain_id)) - | Get_balance.Input (Some (address, _block_param)) -> - let* balance = Rollup_node_rpc.balance address in - return (Get_balance.Output (Ok balance)) - | Get_storage_at.Input (Some (address, position, _block_param)) -> - let* value = Rollup_node_rpc.storage_at address position in - return (Get_storage_at.Output (Ok value)) - | Block_number.Input _ -> - let* block_number = Rollup_node_rpc.current_block_number () in - return (Block_number.Output (Ok block_number)) - | Get_block_by_number.Input (Some (block_param, full_transaction_object)) -> - let* block = - get_block_by_number - ~full_transaction_object - block_param - (module Rollup_node_rpc) +let decode : + type a. (module METHOD with type input = a) -> Data_encoding.json -> a = + fun (module M) v -> Data_encoding.Json.destruct M.input_encoding v + +let encode : + type a. (module METHOD with type output = a) -> a -> Data_encoding.json = + fun (module M) v -> Data_encoding.Json.construct M.output_encoding v + +let build : + type input output. + (module METHOD with type input = input and type output = output) -> + f:(input option -> (output, string) Either.t tzresult Lwt.t) -> + Data_encoding.json option -> + JSONRPC.value Lwt.t = + fun (module Method) ~f parameters -> + let open Lwt_syntax in + let decoded = Option.map (decode (module Method)) parameters in + let+ v = f decoded in + match v with + | Error err -> + let message = Format.asprintf "%a" pp_print_trace err in + Error JSONRPC.{code = -32000; message; data = None} + | Ok value -> ( + match value with + | Left output -> Ok (encode (module Method) output) + | Right message -> Error JSONRPC.{code = -32000; message; data = None}) + +let missing_parameter = Either.Right "Missing parameters" + +let dispatch_request (config : 'a Configuration.t) + ((module Backend_rpc : Services_backend_sig.S), _) + ({method_; parameters; id} : JSONRPC.request) : JSONRPC.response Lwt.t = + let open Lwt_syntax in + let open Ethereum_types in + let* value = + match map_method_name method_ with + | Unknown -> + return + (Error + JSONRPC. + { + code = -3200; + message = "Method not found"; + data = Some (`String method_); + }) + | Unsupported -> + return + (Error + JSONRPC. + { + code = -3200; + message = "Method not supported"; + data = Some (`String method_); + }) + (* Ethereum JSON-RPC API methods we support *) + | Method (Accounts.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + return (Either.Left []) in - return (Get_block_by_number.Output (Ok block)) - | Get_block_by_hash.Input (Some (block_hash, full_transaction_object)) -> - let* block = - Rollup_node_rpc.block_by_hash ~full_transaction_object block_hash + build ~f module_ parameters + | Method (Network_id.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* (Qty chain_id) = Backend_rpc.chain_id () in + return (Either.Left (Z.to_string chain_id)) in - return (Get_block_by_hash.Output (Ok block)) - | Get_code.Input (Some (address, _)) -> - let* code = Rollup_node_rpc.code address in - return (Get_code.Output (Ok code)) - | Gas_price.Input _ -> - let* base_fee = Rollup_node_rpc.base_fee_per_gas () in - return (Gas_price.Output (Ok base_fee)) - | Get_transaction_count.Input (Some (address, _)) -> - let* nonce = Tx_pool.nonce address in - return (Get_transaction_count.Output (Ok nonce)) - | Get_block_transaction_count_by_hash.Input (Some block_hash) -> - let* block = - Rollup_node_rpc.block_by_hash - ~full_transaction_object:false - block_hash + build ~f module_ parameters + | Method (Chain_id.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* chain_id = Backend_rpc.chain_id () in + return (Either.Left chain_id) in - return - (Get_block_transaction_count_by_hash.Output - (Ok (block_transaction_count block))) - | Get_block_transaction_count_by_number.Input (Some block_param) -> - let* block = - get_block_by_number - ~full_transaction_object:false - block_param - (module Rollup_node_rpc) + build ~f module_ parameters + | Method (Get_balance.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (address, _block_param) -> + let* balance = Backend_rpc.balance address in + return (Either.Left balance) in - return - (Get_block_transaction_count_by_number.Output - (Ok (block_transaction_count block))) - | Get_uncle_count_by_block_hash.Input (Some _block_hash) -> - (* A block cannot have uncles. *) - return (Get_uncle_count_by_block_hash.Output (Ok (Qty Z.zero))) - | Get_uncle_count_by_block_number.Input (Some _block_param) -> - (* A block cannot have uncles. *) - return (Get_uncle_count_by_block_number.Output (Ok (Qty Z.zero))) - | Get_transaction_receipt.Input (Some tx_hash) -> - let* receipt = Rollup_node_rpc.transaction_receipt tx_hash in - return (Get_transaction_receipt.Output (Ok receipt)) - | Get_transaction_by_hash.Input (Some tx_hash) -> - let* transaction_object = Rollup_node_rpc.transaction_object tx_hash in - return (Get_transaction_by_hash.Output (Ok transaction_object)) - | Get_transaction_by_block_hash_and_index.Input - (Some (block_hash, Qty index)) -> - let* block = - Rollup_node_rpc.block_by_hash - ~full_transaction_object:false - block_hash + build ~f module_ parameters + | Method (Get_storage_at.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (address, position, _block_param) -> + let* value = Backend_rpc.storage_at address position in + return (Either.Left value) in - let* transaction_object = - get_transaction_from_index - block - (Z.to_int index) - (module Rollup_node_rpc) + build ~f module_ parameters + | Method (Block_number.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* block_number = Backend_rpc.current_block_number () in + return (Either.Left block_number) in - return - (Get_transaction_by_block_hash_and_index.Output - (Ok transaction_object)) - | Get_transaction_by_block_number_and_index.Input - (Some (block_number, Qty index)) -> - let* block = - get_block_by_number - ~full_transaction_object:false - block_number - (module Rollup_node_rpc) + build ~f module_ parameters + | Method (Get_block_by_number.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (block_param, full_transaction_object) -> + let* block = + get_block_by_number + ~full_transaction_object + block_param + (module Backend_rpc) + in + return (Either.Left block) + in + build ~f module_ parameters + | Method (Get_block_by_hash.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (block_hash, full_transaction_object) -> + let* block = + Backend_rpc.block_by_hash ~full_transaction_object block_hash + in + return (Either.Left block) + in + build ~f module_ parameters + | Method (Get_code.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (address, _) -> + let* code = Backend_rpc.code address in + return (Either.Left code) + in + build ~f module_ parameters + | Method (Gas_price.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* base_fee = Backend_rpc.base_fee_per_gas () in + return (Either.Left base_fee) + in + build ~f module_ parameters + | Method (Get_transaction_count.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (address, _) -> + let* nonce = Tx_pool.nonce address in + return (Either.Left nonce) + in + build ~f module_ parameters + | Method (Get_block_transaction_count_by_hash.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some block_hash -> + let* block = + Backend_rpc.block_by_hash + ~full_transaction_object:false + block_hash + in + return (Either.Left (block_transaction_count block)) + in + build ~f module_ parameters + | Method (Get_block_transaction_count_by_number.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some block_param -> + let* block = + get_block_by_number + ~full_transaction_object:false + block_param + (module Backend_rpc) + in + return (Either.Left (block_transaction_count block)) + in + build ~f module_ parameters + | Method (Get_uncle_count_by_block_hash.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some _block_param -> return (Either.Left (Qty Z.zero)) + in + build ~f module_ parameters + | Method (Get_uncle_count_by_block_number.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some _block_param -> return (Either.Left (Qty Z.zero)) + in + build ~f module_ parameters + | Method (Get_transaction_receipt.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some tx_hash -> + let* receipt = Backend_rpc.transaction_receipt tx_hash in + return (Either.Left receipt) + in + build ~f module_ parameters + | Method (Get_transaction_by_hash.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some tx_hash -> + let* transaction_object = + Backend_rpc.transaction_object tx_hash + in + return (Either.Left transaction_object) + in + build ~f module_ parameters + | Method (Get_transaction_by_block_hash_and_index.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (block_hash, Qty index) -> + let* block = + Backend_rpc.block_by_hash + ~full_transaction_object:false + block_hash + in + let* transaction_object = + get_transaction_from_index + block + (Z.to_int index) + (module Backend_rpc) + in + return (Either.Left transaction_object) in - let* transaction_object = - get_transaction_from_index - block - (Z.to_int index) - (module Rollup_node_rpc) + build ~f module_ parameters + | Method (Get_transaction_by_block_number_and_index.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (block_number, Qty index) -> + let* block = + get_block_by_number + ~full_transaction_object:false + block_number + (module Backend_rpc) + in + let* transaction_object = + get_transaction_from_index + block + (Z.to_int index) + (module Backend_rpc) + in + return (Either.Left transaction_object) in + build ~f module_ parameters + | Method (Get_uncle_by_block_hash_and_index.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (_block_hash, _index) -> + (* A block cannot have uncles. *) + return (Either.Left None) + in + build ~f module_ parameters + | Method (Get_uncle_by_block_number_and_index.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (_block_number, _index) -> + (* A block cannot have uncles. *) + return (Either.Left None) + in + build ~f module_ parameters + | Method (Send_raw_transaction.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some tx_raw -> ( + let* tx_hash = Tx_pool.add (Ethereum_types.hex_to_bytes tx_raw) in + match tx_hash with + | Ok tx_hash -> return (Either.Left tx_hash) + | Error reason -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/6229 *) + return (Either.Right reason)) + in + build ~f module_ parameters + | Method (Eth_call.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (call, _) -> ( + let* call_result = Backend_rpc.simulate_call call in + match call_result with + | Ok result -> return (Either.Left result) + | Error () -> return (Either.Right "Call simulation failed")) + in + build ~f module_ parameters + | Method (Get_estimate_gas.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some (call, _) -> + let* gas = Backend_rpc.estimate_gas call in + return (Either.Left gas) + in + build ~f module_ parameters + | Method (Txpool_content.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + return + (Either.Left + Ethereum_types. + {pending = AddressMap.empty; queued = AddressMap.empty}) + in + build ~f module_ parameters + | Method (Web3_clientVersion.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + return (Either.Left client_version) + in + build ~f module_ parameters + | Method (Web3_sha3.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some data -> + let open Ethereum_types in + let (Hex h) = data in + let bytes = Hex.to_bytes_exn (`Hex h) in + let hash_bytes = Tezos_crypto.Hacl.Hash.Keccak_256.digest bytes in + let hash = Hex.of_bytes hash_bytes |> Hex.show in + return (Either.Left (Hash (Hex hash))) + in + build ~f module_ parameters + | Method (Get_logs.Method, module_) -> + let f input = + let open Lwt_result_syntax in + match input with + | None -> return missing_parameter + | Some filter -> + let* logs = + Filter_helpers.get_logs + config.log_filter + (module Backend_rpc) + filter + in + return (Either.Left logs) + in + build ~f module_ parameters + (* Internal RPC methods *) + | Method (Kernel_version.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* kernel_version = Backend_rpc.kernel_version () in + return (Either.Left kernel_version) + in + build ~f module_ parameters + | _ -> Stdlib.failwith "The pattern matching of methods is not exhaustive" + in + return JSONRPC.{value; id} + +let dispatch_private_request (_config : 'a Configuration.t) + ((module Backend_rpc : Services_backend_sig.S), _) + ({method_; parameters; id} : JSONRPC.request) : JSONRPC.response Lwt.t = + let open Lwt_syntax in + let* value = + match map_method_name method_ with + | Unknown -> + return + (Error + JSONRPC. + { + code = -3200; + message = "Method not found"; + data = Some (`String method_); + }) + | Unsupported -> return - (Get_transaction_by_block_number_and_index.Output - (Ok transaction_object)) - | Get_uncle_by_block_hash_and_index.Input (Some (_hash, _index)) -> - (* A block cannot have uncles. *) - return (Get_uncle_by_block_hash_and_index.Output (Ok None)) - | Get_uncle_by_block_number_and_index.Input (Some (_number, _index)) -> - (* A block cannot have uncles. *) - return (Get_uncle_by_block_number_and_index.Output (Ok None)) - | Send_raw_transaction.Input (Some tx_raw) -> ( - let* tx_hash = Tx_pool.add tx_raw in - match tx_hash with - | Ok tx_hash -> return (Send_raw_transaction.Output (Ok tx_hash)) - | Error reason -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/6229 *) - return - (Send_raw_transaction.Output - (Error {code = -32000; message = reason; data = None})) - (* By default, the current dispatch handles the inputs *)) - | Eth_call.Input (Some (call, _)) -> ( - let* call_result = Rollup_node_rpc.simulate_call call in - match call_result with - | Ok result -> return (Eth_call.Output (Ok result)) - | Error () -> - return - (Eth_call.Output - (Error - JSONRPC. - { - code = -32000; - message = "Call simulation failed"; - data = None; - }))) - | Get_estimate_gas.Input (Some (call, _)) -> - let* gas = Rollup_node_rpc.estimate_gas call in - return (Get_estimate_gas.Output (Ok gas)) - | Txpool_content.Input _ -> - let* txpool = Rollup_node_rpc.txpool () in - return (Txpool_content.Output (Ok txpool)) - | Web3_clientVersion.Input _ -> - return (Web3_clientVersion.Output (Ok client_version)) - | Web3_sha3.Input (Some data) -> - let open Ethereum_types in - let (Hex h) = data in - let bytes = Hex.to_bytes_exn (`Hex h) in - let hash_bytes = Tezos_crypto.Hacl.Hash.Keccak_256.digest bytes in - let hash = Hex.of_bytes hash_bytes |> Hex.show in - return (Web3_sha3.Output (Ok (Hash (Hex hash)))) - | Get_logs.Input (Some filter) -> - let+ logs = - Filter_helpers.get_logs - config.log_filter - (module Rollup_node_rpc) - filter + (Error + JSONRPC. + { + code = -3200; + message = "Method not supported"; + data = Some (`String method_); + }) + | Method (Produce_block.Method, module_) -> + let f (_ : unit option) = + let open Lwt_result_syntax in + let* nb_transactions = + Tx_pool.produce_block ~force:true ~timestamp:(Helpers.now ()) + in + return + (Either.Left + (Ethereum_types.quantity_of_z @@ Z.of_int nb_transactions)) in - Get_logs.Output (Ok logs) - | _ -> Error_monad.failwith "Unsupported method\n%!" + build ~f module_ parameters + | _ -> Stdlib.failwith "The pattern matching of methods is not exhaustive" in - let* output = dispatch_input_aux input in - if config.verbose then - Data_encoding.Json.construct Output.encoding (Output.Box output, id) - |> Data_encoding.Json.to_string |> Printf.printf "%s\n%!" ; - return (output, id) + return JSONRPC.{value; id} -let dispatch config ctx dir = - Directory.register0 dir dispatch_service (fun () input -> +let generic_dispatch config ctx dir path dispatch_request = + Directory.register0 dir (dispatch_service ~path) (fun () input -> let open Lwt_result_syntax in match input with - | Singleton (Box input, rpc) -> - let+ output, rpc = dispatch_input config ctx (input, rpc) in - Singleton (Output.Box output, rpc) - | Batch inputs -> - let+ outputs = - List.map_es - (fun (Input.Box input, rpc) -> - let+ output, rpc = dispatch_input config ctx (input, rpc) in - (Output.Box output, rpc)) - inputs - in - Batch outputs) + | Singleton request -> + let*! response = dispatch_request config ctx request in + return (Singleton response) + | Batch requests -> + let*! outputs = List.map_s (dispatch_request config ctx) requests in + return (Batch outputs)) + +let dispatch_public config ctx dir = + generic_dispatch config ctx dir Path.root dispatch_request + +let dispatch_private config ctx dir = + generic_dispatch + config + ctx + dir + Path.(add_suffix root "private") + dispatch_private_request let directory config - ((module Rollup_node_rpc : Rollup_node.S), smart_rollup_address) = + ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) = + Directory.empty |> version + |> dispatch_public + config + ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) + +let private_directory config + ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) = Directory.empty |> version - |> dispatch + |> dispatch_private config - ((module Rollup_node_rpc : Rollup_node.S), smart_rollup_address) + ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) diff --git a/etherlink/bin_evm_node/lib_prod/services_backend_sig.ml b/etherlink/bin_evm_node/lib_prod/services_backend_sig.ml new file mode 100644 index 000000000000..8772d6288c02 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/services_backend_sig.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module type S = sig + (** [balance address] returns the [address]'s balance. *) + val balance : Ethereum_types.address -> Ethereum_types.quantity tzresult Lwt.t + + (** [nonce address] returns the [address]'s nonce. *) + val nonce : + Ethereum_types.address -> Ethereum_types.quantity option tzresult Lwt.t + + (** [code address] returns the [address]'s code. *) + val code : Ethereum_types.address -> Ethereum_types.hex tzresult Lwt.t + + (** [inject_raw_transactions ~timestamp ~smart_rollup_address + ~transactions] crafts the hashes and chunks of each transaction + of [transactions]. Injects the chunks and returns the hashes of + injected transactions. *) + val inject_raw_transactions : + timestamp:Time.Protocol.t -> + smart_rollup_address:string -> + transactions:string list -> + Ethereum_types.hash list tzresult Lwt.t + + (** [current_block ~full_transaction_object] returns the most recent + processed and stored block. + + If [full_transaction_object] is [true], returns the transaction objects, + the transactions hashes otherwise. + *) + val current_block : + full_transaction_object:bool -> Ethereum_types.block tzresult Lwt.t + + (** [current_block_number ()] returns the most recent processed and + stored block number. *) + val current_block_number : unit -> Ethereum_types.block_height tzresult Lwt.t + + (** [nth_block ~full_transaction_object n] returns the [n]th + processed and stored block. + + If [full_transaction_object] is [true], returns the transaction objects, + the transactions hashes otherwise. + *) + val nth_block : + full_transaction_object:bool -> Z.t -> Ethereum_types.block tzresult Lwt.t + + (** [block_by_hash ~full_transaction_object hash] returns the block with the + given [hash]. + + If [full_transaction_object] is [true], returns the transaction objects, + the transactions hashes otherwise. + *) + val block_by_hash : + full_transaction_object:bool -> + Ethereum_types.block_hash -> + Ethereum_types.block tzresult Lwt.t + + (** [transaction_receipt tx_hash] returns the receipt of [tx_hash]. *) + val transaction_receipt : + Ethereum_types.hash -> + Ethereum_types.transaction_receipt option tzresult Lwt.t + + (** [transaction_object tx_hash] returns the informations of [tx_hash]. *) + val transaction_object : + Ethereum_types.hash -> + Ethereum_types.transaction_object option tzresult Lwt.t + + (** [chain_id ()] returns chain id defined by the rollup. *) + val chain_id : unit -> Ethereum_types.quantity tzresult Lwt.t + + (** [base_fee_per_gas ()] returns base fee defined by the rollup. *) + val base_fee_per_gas : unit -> Ethereum_types.quantity tzresult Lwt.t + + (** [kernel_version ()] returns the internal kernel version (i.e the + commit hash where the kernel was compiled). *) + val kernel_version : unit -> string tzresult Lwt.t + + (** [simulate_call call_info] asks the rollup to simulate a call, + and returns the result. *) + val simulate_call : + Ethereum_types.call -> (Ethereum_types.hash, unit) result tzresult Lwt.t + + (** [estimate_gas call_info] asks the rollup to simulate a call, and + returns the gas used to execute the call. *) + val estimate_gas : + Ethereum_types.call -> Ethereum_types.quantity tzresult Lwt.t + + (** [is_tx_valid tx_raw] checks if the transaction is valid. Checks + if the nonce is correct and returns the associated public key of + transaction. *) + val is_tx_valid : + string -> (Ethereum_types.address, string) result tzresult Lwt.t + + (** [storage_at address pos] returns the value at index [pos] of the + account [address]'s storage. *) + val storage_at : + Ethereum_types.address -> + Ethereum_types.quantity -> + Ethereum_types.hex tzresult Lwt.t +end + +module type Backend = sig + module READER : Durable_storage.READER + + module TxEncoder : Publisher.TxEncoder + + module Publisher : Publisher.Publisher + + module SimulatorBackend : Simulator.SimulationBackend +end + +module Make (Backend : Backend) : S = struct + include Durable_storage.Make (Backend.READER) + include Publisher.Make (Backend.TxEncoder) (Backend.Publisher) + include Simulator.Make (Backend.SimulatorBackend) +end diff --git a/etherlink/bin_evm_node/lib_prod/simulation.ml b/etherlink/bin_evm_node/lib_prod/simulation.ml index f6463369de45..31fe037c1544 100644 --- a/etherlink/bin_evm_node/lib_prod/simulation.ml +++ b/etherlink/bin_evm_node/lib_prod/simulation.ml @@ -52,8 +52,6 @@ let rlp_encode call = (* we aim to use [String.chunk_bytes] *) Rlp.encode rlp_form -let tx_rlp_encode tx_raw = `Hex tx_raw |> Hex.to_bytes_exn - type simulation_message = | Start | Simple of string @@ -94,21 +92,18 @@ let evaluation_tag = "\000" (** Tag indicating simulation is a validation *) let validation_tag = "\001" -(** [hex_str_of_binary_string s] translate a binary string into an hax string *) -let hex_str_of_binary_string s = s |> Hex.of_string |> Hex.show - (** [add_tag tag bytes] prefixes bytes by the given tag *) let add_tag tag bytes = tag ^ Bytes.to_string bytes |> String.to_bytes let encode_message = function - | Start -> hex_str_of_binary_string @@ simulation_tag - | Simple s -> hex_str_of_binary_string @@ simulation_tag ^ simple_tag ^ s + | Start -> simulation_tag + | Simple s -> simulation_tag ^ simple_tag ^ s | NewChunked n -> let n_le_str = Ethereum_types.u16_to_bytes n in - hex_str_of_binary_string @@ simulation_tag ^ new_chunked_tag ^ n_le_str + simulation_tag ^ new_chunked_tag ^ n_le_str | Chunk (i, c) -> let i_le_str = Ethereum_types.u16_to_bytes i in - hex_str_of_binary_string @@ simulation_tag ^ chunk_tag ^ i_le_str ^ c + simulation_tag ^ chunk_tag ^ i_le_str ^ c let encode call = let open Result_syntax in @@ -120,7 +115,7 @@ let encode call = let encode_tx tx = let open Result_syntax in let* messages = - tx |> tx_rlp_encode |> add_tag validation_tag |> split_in_messages + Bytes.of_string tx |> add_tag validation_tag |> split_in_messages in return @@ List.map encode_message messages @@ -151,8 +146,6 @@ module Encodings = struct log_kernel_debug_file : string option; } - let hex_string = conv Bytes.of_string Bytes.to_string bytes - let insight_request = union [ @@ -183,11 +176,11 @@ module Encodings = struct @@ obj4 (req "messages" - (list string) + (list (string' Hex)) ~description:"Serialized messages for simulation.") (opt "reveal_pages" - (list hex_string) + (list (string' Hex)) ~description:"Pages (at most 4kB) to be used for revelation ticks") (dft "insight_requests" @@ -221,6 +214,20 @@ module Encodings = struct (fun (result, success) -> {result; success}) (tup2 (option bytes) bool_as_bytes) + let insights_from_list l = + match l with + | [result; success] -> + Some + { + result; + success = + Option.bind success (fun s -> + s + |> Data_encoding.Binary.of_bytes Data_encoding.bool + |> Result.to_option); + } + | _ -> None + let eval_result = conv (fun {state_hash; status; output; inbox_level; num_ticks; insights} -> @@ -253,36 +260,25 @@ module Encodings = struct ~description:"PVM state values requested after the simulation") end -let parse_insights decode (r : Data_encoding.json) = - let s = Data_encoding.Json.destruct Encodings.eval_result r in - match decode s.insights with - | Some insight -> Lwt.return_ok insight - | None -> - Error_monad.failwith - "Couldn't parse insights: %s" - (Data_encoding.Json.to_string r) - -let decode_call_result {Encodings.result; success} = +let call_result {Encodings.result; success} = + let open Lwt_result_syntax in match (result, success) with | Some b, _ -> let v = b |> Hex.of_bytes |> Hex.show in - Some (Ok (Hash (Hex v))) + return (Ok (Hash (Hex v))) (* TODO: https://gitlab.com/tezos/tezos/-/issues/6752 better propagate errors and reverts messages from kernel to help the user debug their call *) - | None, Some false -> Some (Error ()) - | _ -> None + | None, Some false -> return (Error ()) + | _ -> failwith "Insights of 'call_result' cannot be parsed" -let call_result json = parse_insights decode_call_result json - -let decode_gas_estimation {Encodings.result; _} = - match result with - | Some b -> b |> Bytes.to_string |> Z.of_bits |> Option.some - | None -> None - -let gas_estimation json = +let gas_estimation {Encodings.result; _} = let open Lwt_result_syntax in - let* simulated_amount = parse_insights decode_gas_estimation json in + let* simulated_amount = + match result with + | Some b -> b |> Bytes.to_string |> Z.of_bits |> return + | _ -> failwith "Insights of 'gas_estimation' cannot be parsed" + in (* See EIP2200 for reference. But the tl;dr is: we cannot do the opcode SSTORE if we have less than 2300 gas available, even if we don't consume it. The simulated amount then gives an amount of gas insufficient @@ -293,18 +289,14 @@ let gas_estimation json = let simulated_amount = Z.(add simulated_amount (of_int 2300)) in return (quantity_of_z simulated_amount) -let decode_is_valid {Encodings.result; success} = +let is_tx_valid {Encodings.result; success} = + let open Lwt_result_syntax in match (result, success) with | Some payload, Some success -> if success then let address = Ethereum_types.decode_address payload in - Some (Ok address) + return (Ok address) else let error_msg = Bytes.to_string payload in - Some (Error error_msg) - | _ -> None - -let is_tx_valid json = - let open Lwt_result_syntax in - let* result = parse_insights decode_is_valid json in - return result + return (Error error_msg) + | _ -> failwith "Insights of 'is_tx_valid' is not [Some _, Some _]" diff --git a/etherlink/bin_evm_node/lib_prod/simulator.ml b/etherlink/bin_evm_node/lib_prod/simulator.ml new file mode 100644 index 000000000000..1762db6f6cef --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/simulator.ml @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +module type SimulationBackend = sig + val simulate_and_read : + input:Simulation.Encodings.simulate_input -> + Simulation.Encodings.insights tzresult Lwt.t +end + +module Make (SimulationBackend : SimulationBackend) = struct + let simulate_call call = + let open Lwt_result_syntax in + let*? messages = Simulation.encode call in + let insight_requests = + [ + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_result"]; + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5900 + for now the status is not used but it should be for error handling *) + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; + ] + in + let* results = + SimulationBackend.simulate_and_read + ~input: + { + messages; + reveal_pages = None; + insight_requests; + log_kernel_debug_file = Some "simulate_call"; + } + in + Simulation.call_result results + + let estimate_gas call = + let open Lwt_result_syntax in + let*? messages = Simulation.encode call in + let insight_requests = + [ + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_gas"]; + (* TODO: https://gitlab.com/tezos/tezos/-/issues/5900 + for now the status is not used but it should be for error handling *) + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; + ] + in + let* results = + SimulationBackend.simulate_and_read + ~input: + { + messages; + reveal_pages = None; + insight_requests; + log_kernel_debug_file = Some "estimate_gas"; + } + in + Simulation.gas_estimation results + + let is_tx_valid tx_raw = + let open Lwt_result_syntax in + let*? messages = Simulation.encode_tx tx_raw in + let insight_requests = + [ + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_result"]; + Simulation.Encodings.Durable_storage_key ["evm"; "simulation_status"]; + ] + in + let* results = + SimulationBackend.simulate_and_read + ~input: + { + messages; + reveal_pages = None; + insight_requests; + log_kernel_debug_file = Some "tx_validity"; + } + in + Simulation.is_tx_valid results +end diff --git a/etherlink/bin_evm_node/lib_prod/transaction_format.ml b/etherlink/bin_evm_node/lib_prod/transaction_format.ml new file mode 100644 index 000000000000..3e51c177b760 --- /dev/null +++ b/etherlink/bin_evm_node/lib_prod/transaction_format.ml @@ -0,0 +1,87 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(* The hard limit is 4096 but it needs to add the external message tag. *) +let max_input_size = 4095 + +let smart_rollup_address_size = 20 + +let transaction_tag_size = 1 + +let framing_protocol_tag_size = 1 + +type transaction = + | Simple of string + | NewChunked of (string * int * string) + | Chunk of string + +let encode_transaction ~smart_rollup_address kind = + let data = + match kind with + | Simple data -> "\000" ^ data + | NewChunked (tx_hash, len, all_chunk_hashes) -> + let number_of_chunks_bytes = Ethereum_types.u16_to_bytes len in + "\001" ^ tx_hash ^ number_of_chunks_bytes ^ all_chunk_hashes + | Chunk data -> "\002" ^ data + in + "\000" ^ smart_rollup_address ^ data + +let chunk_transaction ~tx_hash ~tx_raw = + let open Result_syntax in + let size_per_chunk = + max_input_size - framing_protocol_tag_size - smart_rollup_address_size + - transaction_tag_size - 2 (* Index as u16 *) + - (Ethereum_types.transaction_hash_size * 2) + in + let* chunks = String.chunk_bytes size_per_chunk (Bytes.of_string tx_raw) in + let all_chunk_hashes, chunks = + List.fold_left_i + (fun i (all_chunk_hashes, chunks) chunk -> + let chunk_hash = Ethereum_types.hash_raw_tx chunk in + let all_chunk_hashes = all_chunk_hashes ^ chunk_hash in + let chunk = + Chunk (tx_hash ^ Ethereum_types.u16_to_bytes i ^ chunk_hash ^ chunk) + in + (all_chunk_hashes, chunk :: chunks)) + ("", []) + chunks + in + let new_chunk_transaction = + NewChunked (tx_hash, List.length chunks, all_chunk_hashes) + in + return (tx_hash, new_chunk_transaction :: chunks) + +let make_evm_inbox_transactions tx_raw = + let open Result_syntax in + (* Maximum size describes the maximum size of [tx_raw] to fit + in a simple transaction. *) + let maximum_size = + max_input_size - framing_protocol_tag_size - smart_rollup_address_size + - transaction_tag_size - Ethereum_types.transaction_hash_size + in + let tx_hash = Ethereum_types.hash_raw_tx tx_raw in + if String.length tx_raw <= maximum_size then + (* Simple transaction, fits in a single input. *) + let tx = Simple (tx_hash ^ tx_raw) in + return (tx_hash, [tx]) + else chunk_transaction ~tx_hash ~tx_raw + +(** [make_encoded_messages ~smart_rollup_address raw_tx] returns the + hash of the transaction, and a list of transactions to include in the inbox. + - [smart_rollup_address] is encoded on 20 bytes + - [raw_tx] is an ethereum transaction in hex format (without the 0x prefix). + + All messages go through the same encoding, but will only be chunked if + necessary. *) +let make_encoded_messages ~smart_rollup_address tx_raw = + let open Result_syntax in + let* tx_hash, messages = make_evm_inbox_transactions tx_raw in + let tx_hash = + Ethereum_types.(Hash Hex.(of_string tx_hash |> show |> hex_of_string)) + in + let messages = List.map (encode_transaction ~smart_rollup_address) messages in + return (tx_hash, messages) diff --git a/etherlink/bin_evm_node/lib_prod/tx_pool.ml b/etherlink/bin_evm_node/lib_prod/tx_pool.ml index 0d274b742c3a..42058cfdac62 100644 --- a/etherlink/bin_evm_node/lib_prod/tx_pool.ml +++ b/etherlink/bin_evm_node/lib_prod/tx_pool.ml @@ -12,7 +12,7 @@ module Pool = struct (** Transaction stored in the pool. *) type transaction = { index : int64; (* Global index of the transaction. *) - raw_tx : Ethereum_types.hex; (* Current transaction. *) + raw_tx : string; (* Current transaction. *) gas_price : Z.t; (* The maximum price the user can pay for fees. *) } @@ -24,7 +24,7 @@ module Pool = struct let empty : t = {transactions = Pkey_map.empty; global_index = Int64.zero} (** Add a transacion to the pool.*) - let add t pkey base_fee (raw_tx : Ethereum_types.hex) = + let add t pkey base_fee raw_tx = let open Result_syntax in let {transactions; global_index} = t in let* (Qty nonce) = Ethereum_types.transaction_nonce raw_tx in @@ -75,7 +75,7 @@ module Pool = struct let selected = selected |> Nonce_map.bindings |> List.map snd in (selected, {transactions; global_index}) - (** Removes from the pool the transactions matching the predicate + (** Removes from the pool the transactions matching the predicate for the given pkey. *) let remove pkey predicate t = let _txs, t = partition pkey predicate t in @@ -104,15 +104,23 @@ module Pool = struct aux current_nonce user_transactions |> Ethereum_types.quantity_of_z end +type mode = Proxy of {rollup_node_endpoint : Uri.t} | Sequencer + +type parameters = { + rollup_node : (module Services_backend_sig.S); + smart_rollup_address : string; + mode : mode; +} + module Types = struct type state = { - rollup_node : (module Rollup_node.S); + rollup_node : (module Services_backend_sig.S); smart_rollup_address : string; - mutable level : Ethereum_types.block_height; mutable pool : Pool.t; + mode : mode; } - type parameters = (module Rollup_node.S) * string + type nonrec parameters = parameters end module Name = struct @@ -131,9 +139,9 @@ end module Request = struct type ('a, 'b) t = | Add_transaction : - Ethereum_types.hex + string -> ((Ethereum_types.hash, string) result, tztrace) t - | New_l2_head : Ethereum_types.block_height -> (unit, tztrace) t + | Inject_transactions : (bool * Time.Protocol.t) -> (int, tztrace) t type view = View : _ t -> view @@ -148,28 +156,39 @@ module Request = struct ~title:"Add_transaction" (obj2 (req "request" (constant "add_transaction")) - (req "transaction" Ethereum_types.hex_encoding)) + (req "transaction" string)) (function | View (Add_transaction messages) -> Some ((), messages) | _ -> None) (fun ((), messages) -> View (Add_transaction messages)); case (Tag 1) - ~title:"New_l2_head" - (obj2 + ~title:"Inject_transactions" + (obj3 (req "request" (constant "new_l2_head")) - (req "block_height" Ethereum_types.block_height_encoding)) - (function View (New_l2_head b) -> Some ((), b) | _ -> None) - (fun ((), b) -> View (New_l2_head b)); + (req "force" bool) + (req "timestamp" Time.Protocol.encoding)) + (function + | View (Inject_transactions (force, timestamp)) -> + Some ((), force, timestamp) + | _ -> None) + (fun ((), force, timestamp) -> + View (Inject_transactions (force, timestamp))); ] let pp ppf (View r) = match r with | Add_transaction transaction -> - let (Ethereum_types.Hex transaction) = transaction in - Format.fprintf ppf "Add [%s] tx to tx-pool" transaction - | New_l2_head block_height -> - let (Ethereum_types.Block_height block_height) = block_height in - Format.fprintf ppf "New L2 head: %s" (Z.to_string block_height) + Format.fprintf + ppf + "Add [%s] tx to tx-pool" + (Hex.of_string transaction |> Hex.show) + | Inject_transactions (force, timestamp) -> + Format.fprintf + ppf + "Inject transactions at %a (force is %b)" + Time.Protocol.pp + timestamp + force end module Worker = Worker.MakeSingle (Name) (Request) (Types) @@ -192,7 +211,6 @@ let on_transaction state tx_raw = (* Add the tx to the pool*) let*? pool = Pool.add pool pkey base_fee tx_raw in (* compute the hash *) - let tx_raw = Ethereum_types.hex_to_bytes tx_raw in let tx_hash = Ethereum_types.hash_raw_tx tx_raw in let hash = Ethereum_types.hash_of_string Hex.(of_string tx_hash |> show) @@ -204,12 +222,10 @@ let on_transaction state tx_raw = state.pool <- pool ; return (Ok hash) -let on_head state block_height = +let inject_transactions ~force ~timestamp ~smart_rollup_address rollup_node pool + = let open Lwt_result_syntax in - let open Types in - let {rollup_node = (module Rollup_node); smart_rollup_address; pool; _} = - state - in + let (module Rollup_node : Services_backend_sig.S) = rollup_node in (* Get all the addresses in the tx-pool. *) let addresses = Pool.addresses pool in (* Get the nonce related to each address. *) @@ -261,29 +277,46 @@ let on_head state block_height = Int64.compare index_a index_b) |> List.map (fun Pool.{raw_tx; _} -> raw_tx) in - (* Send the txs to the rollup *) - let*! () = - Lwt_list.iter_s - (fun raw_tx -> - let open Lwt_syntax in - let+ hash_result = - Rollup_node.inject_raw_transaction ~smart_rollup_address raw_tx - in - match hash_result with - | Error _ -> - (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) - Format.printf "[tx-pool] Error when sending transaction.\n%!" - | Ok _ -> - Format.printf - (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) - "[tx-pool] Transaction %s sent to the rollup.\n%!" - (Ethereum_types.hex_to_string raw_tx)) - txs + + let n = List.length txs in + + if n > 0 || force then + (* Send the txs to the rollup *) + let*! hashes = + Rollup_node.inject_raw_transactions + ~timestamp + ~smart_rollup_address + ~transactions:txs + in + let nb_transactions = + match hashes with + | Error _ -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) + Format.printf "[tx-pool] Error when sending transaction.\n%!" ; + 0 + | Ok hashes -> + List.iter + (fun hash -> + Format.printf + (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) + "[tx-pool] Transaction %s sent to the rollup.\n%!" + (Ethereum_types.hash_to_string hash)) + hashes ; + n + in + return (pool, nb_transactions) + else return (pool, 0) + +let on_head ~force ~timestamp state = + let open Lwt_result_syntax in + let open Types in + let {rollup_node; smart_rollup_address; pool; _} = state in + let* pool, nb_transactions = + inject_transactions ~force ~timestamp ~smart_rollup_address rollup_node pool in (* update the pool *) - state.level <- block_height ; state.pool <- pool ; - return_unit + return nb_transactions module Handlers = struct type self = worker @@ -297,20 +330,15 @@ module Handlers = struct match request with | Request.Add_transaction raw_tx -> protect @@ fun () -> on_transaction state raw_tx - | Request.New_l2_head block_height -> - protect @@ fun () -> on_head state block_height + | Request.Inject_transactions (force, timestamp) -> + protect @@ fun () -> on_head ~force ~timestamp state type launch_error = error trace - let on_launch _w () (rollup_node, smart_rollup_address) = + let on_launch _w () + ({rollup_node; smart_rollup_address; mode} : Types.parameters) = let state = - Types. - { - rollup_node; - smart_rollup_address; - level = Block_height Z.zero; - pool = Pool.empty; - } + Types.{rollup_node; smart_rollup_address; pool = Pool.empty; mode} in Lwt_result_syntax.return state @@ -349,43 +377,52 @@ let handle_request_error rq = | Error (Closed (Some errs)) -> Lwt.return_error errs | Error (Any exn) -> Lwt.return_error [Exn exn] -(** Sends New_l2_level each time there is a new l2 level -TODO: https://gitlab.com/tezos/tezos/-/issues/6079 -listen to the node instead of pulling the level each 5s -*) -let rec subscribe_l2_block worker = - let open Lwt_result_syntax in - let*! () = Lwt_unix.sleep 5.0 in - let state = Worker.state worker in - let Types.{rollup_node = (module Rollup_node_rpc); _} = state in - (* Get the current eth level.*) - let*! res = Rollup_node_rpc.current_block_number () in - match res with - | Error _ -> +let make_streamed_call ~rollup_node_endpoint = + let open Lwt_syntax in + let stream, push = Lwt_stream.create () in + let on_chunk _v = push (Some ()) and on_close () = push None in + let* _spill_all = + Tezos_rpc_http_client_unix.RPC_client_unix.call_streamed_service + [Media_type.json] + ~base:rollup_node_endpoint + Rollup_node_services.global_block_watcher + ~on_chunk + ~on_close + () + () + () + in + return stream + +let rec subscribe_l2_block ~stream_l2 worker = + let open Lwt_syntax in + let* new_head = Lwt_stream.get stream_l2 in + match new_head with + | Some () -> + let* _pushed = + Worker.Queue.push_request + worker + (Request.Inject_transactions (true, Helpers.now ())) + in + subscribe_l2_block ~stream_l2 worker + | None -> (* Kind of retry strategy *) Format.printf "Connection with the rollup node has been lost, retrying...\n" ; - subscribe_l2_block worker - | Ok block_number -> - if state.level != block_number then - let*! _pushed = - Worker.Queue.push_request worker (Request.New_l2_head block_number) - in - subscribe_l2_block worker - else subscribe_l2_block worker - -let start ((module Rollup_node_rpc : Rollup_node.S), smart_rollup_address) = + let* () = Lwt_unix.sleep 1. in + subscribe_l2_block ~stream_l2 worker + +let start ({mode; _} as parameters) = let open Lwt_result_syntax in - let+ worker = - Worker.launch - table - () - ((module Rollup_node_rpc), smart_rollup_address) - (module Handlers) - in + let+ worker = Worker.launch table () parameters (module Handlers) in let () = Lwt.dont_wait - (fun () -> subscribe_l2_block worker) + (fun () -> + match mode with + | Proxy {rollup_node_endpoint} -> + let*! stream_l2 = make_streamed_call ~rollup_node_endpoint in + subscribe_l2_block ~stream_l2 worker + | Sequencer -> Lwt.return_unit) (fun _ -> (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) Format.printf "[tx-pool] Pool has been stopped.\n%!") @@ -417,3 +454,11 @@ let nonce pkey = | Some current_nonce -> Pool.next_nonce pkey current_nonce pool in return next_nonce + +let produce_block ~force ~timestamp = + let open Lwt_result_syntax in + let*? worker = Lazy.force worker in + Worker.Queue.push_request_and_wait + worker + (Request.Inject_transactions (force, timestamp)) + |> handle_request_error diff --git a/etherlink/bin_evm_node/lib_prod/tx_pool.mli b/etherlink/bin_evm_node/lib_prod/tx_pool.mli index 13aef691141a..cb351cc44243 100644 --- a/etherlink/bin_evm_node/lib_prod/tx_pool.mli +++ b/etherlink/bin_evm_node/lib_prod/tx_pool.mli @@ -5,19 +5,35 @@ (* *) (*****************************************************************************) -(** [start config] starts the tx-pool. The [config] represents the - Rollup_node rpc module and the address of the smart rollup. *) -val start : (module Rollup_node.S) * string -> unit tzresult Lwt.t +(* TODO: https://gitlab.com/tezos/tezos/-/issues/6672 + It should be created by the configuration, or at least using values of + the configuration. *) +type mode = Proxy of {rollup_node_endpoint : Uri.t} | Sequencer + +type parameters = { + rollup_node : (module Services_backend_sig.S); (** The backend RPC module. *) + smart_rollup_address : string; (** The address of the smart rollup. *) + mode : mode; +} + +(** [start parameters] starts the tx-pool *) +val start : parameters -> unit tzresult Lwt.t (** [shutdown ()] stops the tx-pool, waiting for the ongoing request to be processed. *) val shutdown : unit -> unit Lwt.t (** [add raw_tx] adds a raw eth transaction to the tx-pool. *) -val add : - Ethereum_types.hex -> (Ethereum_types.hash, string) result tzresult Lwt.t +val add : string -> (Ethereum_types.hash, string) result tzresult Lwt.t (** [nonce address] returns the nonce of the user Returns the first gap in the tx-pool, or the nonce stored on the rollup if no transactions are in the pool. *) val nonce : Ethereum_types.Address.t -> Ethereum_types.quantity tzresult Lwt.t + +(** [produce_block ~force ~timestamp] takes the transactions in the tx pool + and produces a block from it, returns the number of transaction in + the block. The block is not produced if the list of + transactions is empty and [force] is set to [false]. *) +val produce_block : + force:bool -> timestamp:Time.Protocol.t -> int tzresult Lwt.t diff --git a/manifest/main.ml b/manifest/main.ml index cc0aa492faf5..9232c5b64930 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -8386,6 +8386,11 @@ let evm_node_lib_prod = evm_node_lib_prod_encoding |> open_; lwt_exit; evm_node_config |> open_; + octez_context_disk; + octez_context_encoding; + octez_scoru_wasm; + octez_scoru_wasm_helpers |> open_; + octez_scoru_wasm_debugger_lib |> open_; ] let evm_node_lib_dev_encoding = -- GitLab From 4da0399afe16f7122fa39df1ed58f6d0c619bd7b Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Fri, 12 Jan 2024 13:36:09 +0100 Subject: [PATCH 4/5] EVM/Node: fix event and errors duplicated names --- etherlink/bin_evm_node/lib_dev/filter_helpers.ml | 10 +++++----- etherlink/bin_evm_node/lib_dev/rollup_node_services.ml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/etherlink/bin_evm_node/lib_dev/filter_helpers.ml b/etherlink/bin_evm_node/lib_dev/filter_helpers.ml index 3feab686e9be..6da40250cf55 100644 --- a/etherlink/bin_evm_node/lib_dev/filter_helpers.ml +++ b/etherlink/bin_evm_node/lib_dev/filter_helpers.ml @@ -53,7 +53,7 @@ module Event = struct let incompatible_block_params = Internal_event.Simple.declare_0 ~section - ~name:"incompatible_block_params" + ~name:"incompatible_block_params_dev" ~msg:"block_hash field cannot be set when from_block and to_block are set" ~level:Error () @@ -61,7 +61,7 @@ module Event = struct let block_range_too_large = Internal_event.Simple.declare_0 ~section - ~name:"block_range_too_large" + ~name:"block_range_too_large_dev" ~msg:"Requested block range is above the maximum" ~level:Error () @@ -69,7 +69,7 @@ module Event = struct let topic_list_too_large = Internal_event.Simple.declare_0 ~section - ~name:"topic_list_too_large" + ~name:"topic_list_too_large_dev" ~msg:"Topic list length should be at most 4" ~level:Error () @@ -77,7 +77,7 @@ module Event = struct let receipt_not_found = Internal_event.Simple.declare_1 ~section - ~name:"receipt_not_found" + ~name:"receipt_not_found_dev" ~msg:"Receipt not found for {tx_hash}" ~level:Error ("tx_hash", hash_encoding) @@ -85,7 +85,7 @@ module Event = struct let too_many_logs = Internal_event.Simple.declare_0 ~section - ~name:"too_many_logs" + ~name:"too_many_logs_dev" ~msg:"Too many logs requested" ~level:Error () diff --git a/etherlink/bin_evm_node/lib_dev/rollup_node_services.ml b/etherlink/bin_evm_node/lib_dev/rollup_node_services.ml index bc671e4381d0..bce4cd59a3e6 100644 --- a/etherlink/bin_evm_node/lib_dev/rollup_node_services.ml +++ b/etherlink/bin_evm_node/lib_dev/rollup_node_services.ml @@ -20,7 +20,7 @@ let () = in register_error_kind `Temporary - ~id:"evm_node_lost_connection" + ~id:"evm_node_dev_lost_connection" ~title:"Lost connection with rollup node" ~description ~pp:(fun ppf () -> Format.fprintf ppf "%s" description) -- GitLab From e81b5a835ebbe4c3fd97aed186af1efbf3871508 Mon Sep 17 00:00:00 2001 From: Pierrick Couderc Date: Fri, 12 Jan 2024 14:31:53 +0100 Subject: [PATCH 5/5] EVM/Node: fix missing header --- .../bin_evm_node/lib_dev/durable_storage_path.mli | 10 ++++++++++ .../bin_evm_node/lib_prod/durable_storage_path.mli | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/etherlink/bin_evm_node/lib_dev/durable_storage_path.mli b/etherlink/bin_evm_node/lib_dev/durable_storage_path.mli index f900c0d9e921..4fa978e08a0b 100644 --- a/etherlink/bin_evm_node/lib_dev/durable_storage_path.mli +++ b/etherlink/bin_evm_node/lib_dev/durable_storage_path.mli @@ -1,3 +1,13 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2023 Functori *) +(* Copyright (c) 2023 Trilitech *) +(* *) +(*****************************************************************************) + open Ethereum_types type path = string diff --git a/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli b/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli index f900c0d9e921..4fa978e08a0b 100644 --- a/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli +++ b/etherlink/bin_evm_node/lib_prod/durable_storage_path.mli @@ -1,3 +1,13 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2023 Functori *) +(* Copyright (c) 2023 Trilitech *) +(* *) +(*****************************************************************************) + open Ethereum_types type path = string -- GitLab