From c8cd08e79332d0654df783c4c68e45681201a15e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 2 Nov 2023 21:38:33 +0100 Subject: [PATCH] Add "Coccinelle for Rust" page Signed-off-by: Julia Lawall Signed-off-by: Miguel Ojeda --- SUMMARY.md | 2 ++ src/Coccinelle-for-Rust.md | 37 ++++++++++++++++++++++++++++++ src/Coccinelle-for-Rust/tcx.png | Bin 0 -> 14354 bytes src/Coccinelle-for-Rust/tokio.png | Bin 0 -> 11468 bytes 4 files changed, 39 insertions(+) create mode 100644 src/Coccinelle-for-Rust.md create mode 100644 src/Coccinelle-for-Rust/tcx.png create mode 100644 src/Coccinelle-for-Rust/tokio.png diff --git a/SUMMARY.md b/SUMMARY.md index fe418fe..91f2b61 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -22,6 +22,8 @@ ## Tools + - [Coccinelle for Rust](Coccinelle-for-Rust.md) + ## Users - [NVMe Driver](NVMe-driver.md) diff --git a/src/Coccinelle-for-Rust.md b/src/Coccinelle-for-Rust.md new file mode 100644 index 0000000..492c4ca --- /dev/null +++ b/src/Coccinelle-for-Rust.md @@ -0,0 +1,37 @@ +# Coccinelle for Rust + +Coccinelle is a tool for automatic program matching and transformation that +was originally developed for making large scale changes to the Linux kernel +source code (ie, C code). Matches and transformations are driven by +user-specific transformation rules having the form of abstracted patches, +referred to as semantic patches. As the Linux kernel, and systems software +more generally, is starting to adopt Rust, we are developing Coccinelle for +Rust, to make the power of Coccinelle available to Rust codebases. + +## Examples + +Changing a method call sequence in the Rust implementation: + +![Changing a method call sequence in the Rust implementation](Coccinelle-for-Rust/tcx.png) + +Merging some lifetimes in tokio: + +![Merging some lifetimes in tokio](Coccinelle-for-Rust/tokio.png) + +## Current status + +Coccinelle for Rust is currently a prototype. It relies on Rust Analyzer +for parsing and rustfmt for pretty printing. It mainly supports matching +and transformation of expressions and types, but reasoning about control +flow is not yet supported. + +## Availability + +[Coccinelle for Rust](https://gitlab.inria.fr/coccinelle/coccinelleforrust.git) + +[A recent talk about Coccinelle for Rust](https://gitlab.inria.fr/coccinelle/coccinelleforrust/-/blob/main/talks/rfl.pdf) + +## Contact + +- Julia Lawall: [Julia.Lawall@inria.fr](mailto:Julia.Lawall@inria.fr) +- Tathagata Roy: [tathagata.roy1278@gmail.com](mailto:tathagata.roy1278@gmail.com) diff --git a/src/Coccinelle-for-Rust/tcx.png b/src/Coccinelle-for-Rust/tcx.png new file mode 100644 index 0000000000000000000000000000000000000000..1d76f806ec1845a9d7c559cbe21b8707e1bd0625 GIT binary patch literal 14354 zcmeHuWmH_xx8=np5F`Zm1Oh>WJA^=RcbDKEJh)4M0Kq-DyEd-D-5mln?(TE*|GoF- zy;(DBX1>jbxr+tem%3GTPVKYLsom9~^0H#+sD!8h0H8~VizosBEIatR4jC5wT{g5I z1^$6^5SCCzMn+y-msZfQU+j&IZ5+&O9sA->BmsaN zkP!K(?3#MG{LKUH`kCuwb_MbV2?a}-@~1qu7((t;G-YhocU)1GI4_z#f$yL9Tcx5= zvnZVOs7ByFVv7ZYEMY;a`=JZ&t8IeR%T^pI%k#svUaPa`>+8{Jo`>!$tmj^%mZngC zUbIjVSY(QTsAvPaXG3OuY3gc}Vn0k_WLg6+VPp!UaApdM08Ez8i5cKMf;U5QVB2sk z=(_++;or#TufQf>y2}nD0^mFPW6V)ds7y>sA_eRd*$PR5v$>PTBSpaWW)rF6vT2ej z9EV=&>hZPgVl=VGDv!RVTg`4xvnMA@TZ0)PBKCWwbZRWi%PnXje+RtC z_3~ok;tK50A4=KQ(5BaboSE0#)QLrUv3)h<1zaCB_0`{k1LrVZZsgy%ejH7|;^0{N z();r@YL!<@WG(ybV6ld@w87`k5QFHy&S{;B%=r0Ja(Rg!hMX#QXmD_0Az4c1`qH|L z&okfl-@1Bui`_3HqcKIM%_zm4HfWrjREZw;&veo=mX_$1lm>zJ`T2+86zrsM`ANN& z_s-57oc|b>;O1rTR2v>j8{6NPpHcUoF`k(3CJ3{^;oUnH7VjIocU_c!J>^-cTB<4f zD9ZobKR$l3Gj1d$<^25gLy;B*O&aZ`EX0GmTCE&djHo#kD)}480uQn zYWCE+?0-#ST-nkqD>h+Jojxcu^zI^gM~o5#5YKMkUpUFfv?HU7>Q(0~tlYic&2!zqz>? zY%1vWpiYi?b8|D4&fnyIeKg>btGHXg>ZPTwjtuaT+V=h+sjRF-dPyu#g99+@xBCRX zz*CIw=;)xJpqT2W_!M-oSbscStY%|llPwlW%5D)`)$Zr#$L#<`4ipB=X3Lhr3F@}E zIjyz(&dsU63}*fEI~?T|^^VG?@9Oj`O)ke&y1HP}x&F`rmnZd1Yp1 zULUV+pSmjL%aU-~Xj>awBqSy_IPNNjieTg6Apw*5a-6KJZ~&tJ=`iPNI00)OR7^IF z$LUXZXim=CO7(+-1HNx(n*^*T^0wov-RRq6nV(EY(>PrYN*Hw-Z|?7d0|G=uL>d|!j}~f+zx4jFaKJ+qMe>)cP%qKYllf!E zh2BzuOyTtNxzC8@ECaNZ-F78)*aU-=@1}ZGpt`zx!yW>5u7;?rtQ?O2p>uNb6|l6t z{OZ-KPr||nhlen0T^NGebyi6%_QxwNt*xzmq>;TFACjcS#CkJ71@rLmz_z=rdgh}I z4h<1A>-&_K+nz&*Ve~KermZ*@ySoGK=u?JqQ3FK+M+mWnyA3Pr>p4NImYc4-Ltphq z5N&U6!UJ%KXw2l{EXD&kdVjA~a2Ws~Zq%aD^S&-EEiEZ&zQUj@2#ug~<5aWO;`Qs- zDh{>k>gsk}sV2k8=!9&20|Tf)nKmS=QaUYNz;mHoPY~<|2?+@}IX%rRS^!tP?deX6 zp&={l&whCuBH-@s?(O|t-uARGHH8DD3woEK{epxN^;MgW0_~lhh6^?38@-XXvt=Ye zI0>&R`{!~KR_`Ydz|O(p{QNwdg|l`6M!zcvot+NTo9&&6 z__h_Bl|@M!$!XMwIXz((RG7r?&H)&in9O)ckz;akb3+;$n!lX~C7(UqI)FaGz`%$W zS9YjHBVfrXC=HIt%Qu{0)H5X_Kn_o+_Zb zw^vJ3)6LbD2Io82M|^zz4E^~>gqByQL4ca&ux<1s06;({J(ydK>EF3-Cfi>39h zV3;)!^A;JS!^76gjh78yH$dV*d`Vp3hM6}oJUl!#rR;R9t*ZL@uxgsJkR$@cR4v(f zhzU9f+d|tVm*W)%I=XCX-ByoVu(Kkv9D=;hQeF#n)+w5uZvx;E5nigzVQyn10P-9d*k@<<4h{~rYsQ1|mGiZ_MA;gj zI63S2-LFd2EB}BrOpiM_ISIlvJ?5R<(R6Wwg*jW-PS}qhCd~L#p>J}*kc1VImPT_@ zmFb_K*Kmp@3G4YexD_;<(3&roff^`mfmHhH?+UW8u*{TboFBJ6LpL{R-o+;*%;J{k z&da~MP#)|b8G)X<&dkhcz8`C~CTgLJz$|)4cr==O=dGZi;0yM0dfH2Ny)&L|!WY() z#i;SBG?Fu?thktkl~sub2aHd4e@_pO8XVEKAi;-|PX-1Cj*b`5;gsd2B}Uz5F4vPa zTBW>#*W#?nX+y@~?N=gc{{+rL?Ty7U; zMn;>%DV(+5B2v}2f5MpP>FIHqbcsnx(^FFJ!MI+5IGBQ@%5?%mv7vJQuu^3_2$0iD zKPEG0jH=P#u)k|;XaL=4I9Fltcz0QRcugO`)>CdY7GdcjWi)z{q6q@H8 zG`X^}GCNyemoy=gwkjnfldJn#ObmQp=W^4+#Dp5~xZO&yAS)T9E_2aobo{{1E+Z?e zDk~u)gWv;k*q%X~nYRM*#7+ETuOp+atxbsBEUM^Dz@C55Mt%~jsiwL*m@!ip!W6Qy zvWQ7Y3S(|01ER`X?*?XOoQIRy#eNWfJBLQZf9N%=bOl*>AOTF`-#}BR3Y9L0^4+FD zgRY()?**S9s?Ww`zAZ3ta;mK|-%-mXcW<1=(`zUyDhkWc($J_w>~rJd;(mWzx%@%s zotU03+oIj%Y^|^VYp)6<6ou^K=i6FblBGKL2P#E$p>kufQh-by=`h>@D)ty-@kt!8XEHP@lnYB>~yrGv3)gZ))z%V zr&ji`9!!=em+|y)doGp02qwD%nG}lz#ixgJIWSY6ZuELT-EM;}9UL44IfabEs5=B} zfWfexx|QH7(+8^8z>MwUR{@%_iaRB6ob$u_RX2C{NFvUWo}R4^e3bk|Or`^Y7kXm%XX}#l@yN)PQAlIaxU*A0n)4 zYVQ?%J$g*xX|v|%P|UNlEh%qr?>#R(I=W&oW4E}T3g6mzcgy zFE>@!(%ObXi{hc+wYS&ke5gr8L`Y-I@F38u7&(^_S3zp)@kZ-%uF+QNl{=wE3zo(0yQtVz;aI1w(JV|X|?B9B);!TJKk7F+raHZnX|UuB-f zLm=OtpB`0?$0l4}DNU@jK3eTvyllC@eMzQ~aHj+d2dAT>Q^;LsHE$2D3lWEvot@n; z7R>Sdc|O;Z_K68><+5A_w~HMtGP3foM-t}daDvaBwQ8%Y&c~(qRpj6f?f%*zEG&%u zDE4w9^Ai$B3JDn*20%qcwJ=(|BPE3{N*Ns*it_qROuv485s8WdyN8x$D>eUc$^#sD{kxEXe&xeq%-BGa)-gX4@~;D zw#V)5?RD0R?{U6^4xa6W!e+5tg(M>)E^Kct=YogCQOM7Oi2J7V?eW z-sMOA5;Bj}@5VGgz27&B%p@}bjQeH$cr>RAN$dM!@R(+7R&?99N0Us}c6yURKHgLB z1WWQ8kEb6bykNe40Z3C%f}{#w%gbp!h7qLv$vm_9SA{3Rk+{!Q9kterA0GvZz93)< zBerh~X5Q88)iVT&ir#ZtA1w427w#(t@&rrhv?}Jx)BK&Yc3E|`!?2w7Qf=?b%vF2* zs*D*%w;1wtHlp{_D|Sr%#X4(gYKIO#1Tb>hy?b6idVhM0>%dK%W{N|!`u#N>EG#St zHXbmQ;Njs3i%Uul>`vzEwRyFGB|gFn+^L5UaeC-i$PF4pK(eI&c0PDdUQh}SKtuep z-WgbwJ%nY!mcXP3ZXs+%MBts^YUARje|_`^QyZt9N6xgg#=gE1qv@xG9WU{i zT3hVaOSNSm9*WW${*e-P11X}#3)&K;sl!y*(T+F!Yrx@4N>D-WoH)11ax&_^$ z?0#YlwrvX>&t5-T&MW)=y@DB^2gmCPQn>GnStOU3@iZD19>CNVz^L;}j*QDiR_tUb z$!-Vp;pPpo;0jG#_VypqMDAA{wn3s{$&K&9J|{zNcZZ3%Jn)gto4NM}Z!Fc1%XIv` z9@l=Oo6TcWzA;!Aw(bbV=!$;B?8$Smgkt6VMI{=M5$`2w0Iib#zUne9F2zNVZGhPMS>+RQOGI3TgG{QBlF*Z5kqJ_zL%n^=6j zaFetC7r4=MU&yzOnV;!ZEIUgC_-L-@h+L_8W$3~MWrU|U67NgzR=Ehg(f4(PVQXwL zhEw1GdTn(}dsv^Y;LHllnKJeXaC47~%WO-UlM5=OGCHpVP%%Gl~_5$HNBz2!`9A{gf}8JV?w8WM%t~A~Dv_+>-LZ zn~ruixwIPz2ft)?rVl5>K>MsB^buw#2~L;-5NdL+u*7S2LqK{dWJPbs#r!46&5zFk zQTP)D-HS#?7;kT66yFeJJEuUMre9yg&|mkBAex%uvw{tr%BcdPzFLCbJG1W_4fgXJ zXi-$a!og8~dWAgYA1Iv2fk3RL;78_txR&N(&hSiHyw7!M}he zks0Q9WI65|T(z=2u}J-E8}(|$M(04mXZUF3&aU<1a-p|HsJa!v?;n9XX3Xq??Ls#f zN?a~4wYAsooNl(shMmCR(AHV+fLpdip)h)Q`yAbG6mWLE+C3VHMq2V@JI8E)%kp7v z2?FnvlWQKP(HILvA-o9D*5x+7w3vXf_K%d|Qpf##dJJvirKP3#`n7u~oL=B%Aipx{3$1e2!>oKA3HM&Q&@zOG2scFfMh(S%Ss&fAkxuu?MD?e8XB}@f!FaOwU5+jp>mJv77 z;{6fk13MKcb-ZWbOsKJu`5o~_SJ!AwD67OnXRKfDcm<0ij(!Jyfm#5z_^Hn-SyxH$If4Tegs1;U%p?HS&k z*Q;R;cU9 z#*EKwCSMy0N+&>fcl)d!ks>uPw+NSl&dtr!$-<&POn7s>Y7xD)Rr{MsOLd>iX%G9C z1^4`X`-X3A?GGL!Q~$KIy7MUH%q{jZ`V z*O$1hzpNA}5ETs#31t>E4t+XoQYm*;m<)%Z)I=Qfui`bQUE#K|ujB7)XIHGNthF z1xbyneiu+|P0E3+>*u!ym7!sriO*nRDT?4Cho^kgF%Pll;{+}aP=J#`CQK}a!`1of zWU;&5saiTr*z04p6nxT`zt{=J){ij)1NW$kHLDSUwJj+wN95KgLJ!YOPj?dIg@u_r zTz?qD4@M@Py=4B`Z%VXLo}MZk@_)cSKjL*8;&UsC;S2A0j)mOz_oD#h{4Hl&3$>W| z$PmahY{7@_qU`F)?_qjXs9SuL1AqN zIfcW#*ut7x29^{fp5FK8&jDHlgbI5qbq#aU0lC!@jrR5Sv#nah3Uz%G)i^hpwOfZS z(}Y-fMOy8)m!>1_>s^?y;P9CI;^OKe`;01VND@=jw7NiG;95=>sZ8miA^P`Q^*I__ zpn{ouqn8}JCqxsvkA>zw`F?rBmy3IZZRt__Jh=rCl9MOw#$&aF?0zLQnvRL1>{L7S8xiEs9fi3zvXvGvBXcPVW(5!)}j$5`kZ8M4-eHe~XC) z6BxL*t6|wcocz&%A|S}Gx*F=#X9%W!yR)}O#vc{24;B#G9$@XckprU=kgPar%;5|_ zfcNTcIt~}3V&Ld;`8<#@$ozuEwh-P?NlDFBBk8unySoEEF302_uyDQ)@D8ypR3Z5J z8*EA93uw2+1!1zt68=7BPyIzcQAGtqZen6I5If-8V*wA#V*1j2G6=wQaF}Ql4Eh#EN8Kah+u_M)B3B7lY8S@JR}|-LtFS^$W>L1=9tg^1paWdaM?oLor$pH3K*nn zZJqwyfhCNCI#HP&behEPwnL*z^LAw=pocQ}rTI%_w6|qtak;ft6423iL>!n%NS*6Z z1gyw~t+%nyT*USpL2e2dq?l4tutMteo%+hfMjp*U8plf#_-GU5dZlo%Si;9CpC2Ci zbF(Nb>JZaELyL?h2KG{>N?JLPC3;!Q(RcUG5VZMPmue zbSI|&)PDfsUB$v>4_{{mV`-VlUK|a*f8btf$fOXgoM*Pv|DtD8S>e;-PUMVhy#N3K zK}Dz?+Ii19BkGjK39}@d4F@X`la3y+!|rTOPG;N$&)Z~jvwAWDw9!(02aOy~PAjZmZxx!p%pm@@fh1!u z40Y#~Iw3K1vu^lVG$;C+_wL06X3YhTe~RVCWqtV1%`k}$`0yiKIz(o5w5!2~#PiTzaN3R^ z2&8fSANh{Qw>B~TUwl|#nD|9%y!>>u8m%zDewFv*@0_yKEKyn$aXh%WyH~9z{L*3Q zgRuC+gSs{u_gg#@_XA#)UxDtLn3^ukTjx>!R5Mpn72ZC_fRv7igY4jhI4jjQ`QlMD zubLcvcB}Rprz@p6e!GdO^>R8nWd8CpXN5$8&eQ+ke9(#Cpd~b%chaE~vLd7N;?aZf zkHGmrKBD(hU%fb7lJ`c~Q*YY$0EB=ja7nrpM`v&~7-=tGd?j{tMR7u$2 zV83%4aZ@qE2$cZn3#n;E6>+-ob_g><{+UXzot!iW)Bd)c+h6DNEbg}twCd#0(Sy5c z+QkxZL?orUTi4N~d1G7KoHWb5Mz$bCi^|C+`iI8z$V)8~&vDCWCq{9&QlVu29v|q! zT0Z?se9nP;m2Oc~4o)vzd-?Tq@0S!<01p4j=9QogYZg?@CNHfm-HoT3O@$JVH<9677bu3bpFZLXT^)FCEf;;m&kb>M`Z})=w~YL;0Z<4P82I4>^b85$B$=2M~6l zbJtz*a62XKlnNjFiXY2S(_Uk-p_Gy!i5{E|=XHLSv0PDTT) zs7>RqC$5J1*l^uBH@?#@9=u9W&@}O+IK5d8AH01%kA^roU-a0{@ka0~L61+-ssSzT zIj5jDeS8@3D^4^eLtrWKy*Sr3HBI5p>y!?Hd4noVzvh^)yQ&L;9tJ;BWbz|5G0>&> z&*_g1EC-zhJ@LnW50si91l18Wahm9KFBWIik;z#aPs_efc!;sP`Dmiv${dV2QKlhA z?LR(Vw?BmeRf1t7s(a5vBDw8>J{LSz$?GQLCV_qF@}gQ*@P6hlisSB4*1aolb?Z{o zDD8#fv5s!32M>Q>maT*J$-~>9DmY=NMk3Vlp};Q@#i6(tFo2H&HG|3v+(FScF~;U( z`yztTI;C?`)g_bq38wDNrSqEeuhplp0C)6@?!aTo$w_$I1$Btz<{vN&!kT+~3|kXC zIei-n7*&Sf%VfBj|B4800S)bQ;bfwE<9sbo&43khi}Em6GT~T6ln@dIZ|LRG!Rnh>e(-ys;vM((wSb0cC&zik z{vAE%nHTiZ+F#g>7hN&sI4?MCw3XX%xcbm+aZAHy^D=f47}I?20f8d1Z%~tvl17`fPVLk-I)->}MTYh{at<{`Ryfivy>g|<*lcZe3kDR@& z3`3gB!wvTAw^QE*cpn!cC%w%bZC|45#mae>D)_+SuvovM-SCV1XRRj)A? zMnX?LxP0Z0_fU|S>JA3eR}H@Ru3}RIF{enHT6GRpj*wWKhtd5{xZ0K&O=Xc)Hmj0t zT!(Pza_DuOPG;7-*ePVW+ZIaiRK!iRFQpjWwv54p4Oegw;X6t}o;FG?az;fcN;0}u zsBCZ+t6s|$#l`E;7lkG#Wo(D7J9iglVFxlK7D403E<8jWkBsI2qAj=MGmF<_^GdN7 zHf2S#89Da-ckT|`I%HCh`!3DXKKiCxgTol!WrN%U43Y77i1Vfi#%7`Oc-1SMeO_Wy zk`Q58ncMSS+nAASx`I9x^cdQl>SvPMo_XD^pA(x|H!vL|?q6o6b8SF1#ncUazPyQ3 zjs6vu@LQHskgQujUOiI>7X`&hNPZ6TVusep1(7Eu|LpVTe#qGlaA=`osnqnf*j{B% zuginpZ(M%O{bMLBp2=M9B7dHo@Hj#Ze+zc`@>!OqlsrIu^N$`S^agQ$c8iZIjX@as zmd<(6M}J$f(#MT9PAVwKaqf9jE#gI%0|KhZ16F=>P{xJypSG;LlfYZO)Jqb=iA)jg zoMXzdRbt66viH(Ft8%9ORDUQ}$?t2iRxLyO%lncXpR#|=9ZpF>gs-$Vg~9(c5vW-p zmbY=va`ydo$?l3RH7e|LJvRV&^?ST}MdU+L^+ zC^KU92Mi=A%)7i6k>xzzl_Q5{gbR*AzKuR#s+SX|-;`eeTvJ%LAV}%aNAe)1`HAA~ zd9pFk#L7GGl5tqweDr#)Qab+5CbxCSUVVwGRm)l?`T5c?#bT(Zd+p)-0Rlfv7$Coha8g%O{pV@!e6~nkJl2sf5FeGACz^AkFsm?G#N-uJWDg$pC9qfSCF^ z9|Mliw4u6fU!+jmjsKGEl7)viOGKM(&RBX_oQLkju~QEW?Vi>YZELb zmc8}&p-m_0u^b&RUWxhWDv0A_Z`=YFts{RA%Hyc~%T>WK~L#UYG@eMk#B+k2U zcvyB2Pz0vS*}zd?O>rW$xIc5C4_g8YFnVx#nbsOKM~q{c&JfnYhyyjp7-SgbyE(WH z)~Hv0Q}|f&S&4VF+&Y!VNy4XGQ8tq~q3e&P9ewR=rhKC1aCNSOvuM~%{2}hu-C_Hr z&*E-EB3gV{ZBs%^y&3oCVus7^>(`T7I=R7wcSqVh+aq6C_Nsc*hpI0>*eX#VY0 z^g}Oc_kPGzl2VY-myAwH{J6D6b1{+AjjjR~knHY({hE13MuAEeEI>M4jz2z*nd0AR z#H^F-6fzh&Q?-HY?QRU#hz91S_gv^2kK-%;U1dk4ZlB#NkLt*#u4dNivSsF>P1&;` z3^v2gBAe%)-fln1CydTZ|A>bTtUAm2qjs3=GzAgiiP-1bSP0^;;5yC zgURZk(OnQpfW>GUXv0DF}O@;S5_|7|deUnyte;C8Pl|-2o#S?`Dz;23q)%ZhR zvEwF9bmS>@FM5ADCoNn-cw}S326$##_cJA9Xx;{?ltjeQ1^0NWoQOCXI?pe%NQ4?7 zs1~aqYKipMPrrK!l~w!s$*rDHn;L6sMt!$LNX|W@;Gk*MjcIrO?9241qL#+$08umd z&d%b(@lF^?(E&9)IxC6m^lYkLRWO=diL|9 zns4R{0kkn){mmvVMaX9MjMqY!qa@?^)eG>{0EYK<#r~eb?4?xsJbd42!}5K42^sVb z-2W=(<{C_zV;~MC$cB~Txm`BhS%W(c|B|L zdA0{6u6`PcnI}3RDYr0&>EizGPw#>)R>A;P2h%l;Ub-uUQzwe6`K}-*^YAywh%It6 zanGDbx#~lLCv5GhUkW*PVtP4f)d+~rDVd5o$80a?5#0+0w?A-ScdqK@=3$b1^J&jV565*HSF!(KvPaB#r>gmZ8t(bM%sPPD-?)>bT48>X8n=gluW9HfPLgn=gZPdu+>er->hqB2 zVTKI&*@v?-Nm(P`$`qM-lQ-IJQ>rWxR~gC|EF8zDU~wF~>KFG;_O{bwTKo<@Mb`b7 zpx#)1&&-RKJDo=ktK2)CO|VkHN#hR`u7(s%T;01rrV5fQ*jRZkr}lkG(v?Q_0%1gn zm*M%!k?v7AGXAmG-J_Ura`-eGw2JX9sTAXPCLHKzBi+TN-46Afs3$*+sR-|NfQ%i=LA7?w~AOLDV<(^Wo2k^F<)LnMW zW<|eT3hR;4N8ylm7Tx(3bU`TEKQDuF_`>Jk!dNZb;l`&pI zGGlXT@xtz_%{S=ZDpk<^wcgEvhE0x;cC1>u6WwEH*$z841Q~d1U-^1;;djnAkB-T~ zehP5O-m+w-_Q}lUy{@V{xBc;XTci(%#TZ{j6Ax*X$lR3aEg~LrHLH{&1|NDu!nZUx zDTXSq`jDS7xr5^kY5hH?8~i4YPGctwp-|MCKkSy~>mFdGnH2B_++t{K5pYh99EageLeOD(FHy|M!d=O@dH%(y3YhL4ouYB zx|z(8{YGu{A)$03HkQjDzv+Mcu%Z5NerG57)vq>`0eDkRxo<6jO7T6p>sy>`^MX6W z)&-}I*WMwU`k-dkXhc*--e;oQj%iu*gexVDP@P%icr4PeV^Z z&7LRS8O6J>s$9S#&(|aKO7;9}PU4a~!fS46#C?_Z$pi#Bo;hdegNtmOS6lXE#pT`^ z8(tFB55EG|$@v@Azd_AV{B2w>RGK=brzltfQBzw+0CL=a2WwDv^t=h&!VhV@x2^A8JAvQy8ODO#v0!U(KB9||W^p(YG2qUCw5;_tg+5m37y4i)G~jaF!4kW)*wO}{bmU*3(*HTSZ= z+0CvNjm2F_y;)n1@cu2rtn*q!pHY8RN%;9BaAvsJ zG{FW`a5~{{vNR@z>XtCH8py8}Ic53$?#! zi10U+>B$lIVX=D)FJJ!G-gaVB-^&=>cKIMO`Hy1TBJ_>i=6>5QVA!=XNWcK3gE_YQ z6oOak+xohPHe~<6BXegoAxkZ6I!k?s%=@Z~B~-|oC%A{7>!4^)R<+zKzr|pGach^J zlRHUAPTWWHI$1LK}yZ;!xuFBZ4s@KKU!X1t}W4pS^kE)%kmzQ0*ao z<{FHhDB7H@3B|6)sL${r;;Na(HI*=CHqlh|`I~A+vvr@qAwS{9$V6P_Kwx2hNmCZw z&woQr8#Vx1X}ni1N0q+oc^_9B4tTqS7hw$yycYTB5Y7Jc)%=N)?h!|t+Qss&*-;7k zcMu&Qdngh=_r~aLiMUx@e3?eS*shN7?y=bi4{GhWC{= z%xDJn>`hnH)+4n*r84IY_oG`M%Seeha=q{%x{b|*4E#N7&;@wGerX3~M;$kJlJQjb zG>T^{>U`3eR{*n5W^PPCZdyy~h0Cxnn-#TtYVVLhEwSq4JS7+ff2*|P*>S(8y5dp{ zq6+ehN&}$BC6=i=x#{ z_!^g#OZ8-39nzXBP#`SE;%5P-b+Dg}!TrbZVu1#lvrBIz+D@t#8AEAQT=`zpefMAs zE-_tgW*mC{3SJJQ^gJ}o?Q!K-wH>nytdG|2_Vf{p0;Z_)jLyp#DFhm8k_#9Ane9ho zWrl4}lbBlj|ML{m5$hlRoT* zRQWMjGn)lO+OT@vXFL&J7>XgK$UZKj*_w|BVg6K!cjkRmY$QMJCEahmNM4?LE%N+s zZ1*ezF(V_aX1!9H)N~b8J5ugC{FwMm&6|nwAM9bTjx^|kc01-V$hwdM4(_O!Ki^?Kv>b|CFU z83dvQDapRn^~*V2_BAEip#+^UW1-WU$f-O-LK6Wo&lvTE7p&hHX;n$;eE zTP??X>#>u-)7s+oP>G*-g!9SDM2E@DeF6>M-fq14fnQHYCAEqd%9zf4+_Kbbw$i>d z%)-qb30|9L^#pCe6ViPD|?#V=-^{VS>xiN5UAywXTEmYuuK0Cpz*%JaI7wZ~pZ6 zBZtQZ?7^oSeGYSAv9jo8Y8Ux6c^32$-!r6Fd8NC95O8L*cH zX{NI5A?N#Ro=jCIr=!7?nrs2f%VRe)t(PC42X5`8`)w&3*O;r3a(Y_vtn{Wi}&@=9t8oBHOz#@K&0R$iVs+sO-^nVK?zI;QpvEVuhwboeEG ze;xF2z0+VnKGWiFTwnG#AU}Dlva$D_s5q~h>(7(L=rFZT8XxYTFR{uv| z-*Zt8R_qz2Avo#j>b%tqaX|G~%pMb>0#c{A;bX&Ittq=$c9v&W7y3?CCyGQ>V zaCmu54IZe$ZnV5TK$6gx04>lA4;Dot=F_!8*R)mw-eoDQTAZ+E$D& z=*k@hCBpZ3g#a8B6m)lgFUX-8qYF>a7ZDM8yZh_qserI>`ob4#>5z`<3fCq0CN7>@ zwve~GJ31EDR4tY5NS<`)YFF^!;9!+W^Ne!1kB^Tj*JWP!7~ zsoB{)soCYRtWQgJI>oPNyi9`Z83_Wb?y~oxT0e=HDYSCg%3$#?HoO06SaU_vmD; zcl?XE{hK#rgoKlwftO25rkP32ZmUPIvXsO`yp+Mly1G{PwVu+v5ctjxGX@I_%fR3u z1}5gsUTL1Gsj1K5!V8jwS70!cdXC@W0u(Nn`uVfwXkpW7M@L7_ z2w9z>sgaSAOn}=VEWsK^>i)D$2^}bl`mVg+>RE=9##ot7|nB z>V3973WS?F=itzg<7!uDRMeBa@fzyA-#|Hg6^%VOJj@VjV`s-l_MTOzWI)0vPuPtb z#K_Fd?)85gWgaTBek!P;2FON=uj;d3liWH_(sy>a~Me}E%%OJ0* z^Hwr0zIs2}A*v*9p+FAH#KgpLTJ!YuG(**HRCc-65(Sha?puA+Q>c)L{Ea5`PAixW z`m-VtFEcy)a&Jn(4voUO05I&-qM)s%MORms#R$sxHW}h9wD|L%V{VQNBtkVdQ)RMW z>d2MOj*rf$5}%NeE$n6<>|W6}JLsl8MY-!9tVS{VJ|j0bHz|qN_sA3l1!WM-&(H7W zb(Zx#ky;Wt37*{VD{UpqRGO0ywkM6?}VB)}~jX55u5~PfD5qf_ywjR7YFe%7#(0`K#H!K4OZk z>eriwuU$A<8HyS_Iz~oD{4GUAs36F_3t|i9DfaG4XS=TZ=(Msp8zLS2{Ke!KC={AA z0Tlznv^b57f+D_eeR5K}%}tBqg=4$V;W+})+uK{gt*WkGEt-P@k_;J_;QfCq~F zR9nkKojBX*ptCHb>P2C;KWx{)tdSdZdvOSatCk8n9lJsGXY#vg0}FCW%JEEoW=>AE zdLDZEo`r>g#U>ZW=Cu?JDWouAw-rr|*=n=EgSooON)9L%EKLmVW~QjFc6O3GV-K5C z7|)$*bIjLl3BL6i)S;oto12^4n<^cy^qnhWjrgfCG&DBTu@a!U@9Y}+>HhW-?a7m< z=;*&L1`ra!e~G`x()_%UhDKui@nUmLclYB&p~BSE6p(28RmO&`?)@*stmCdVB~3o&5Qe|F9z`D|`2Fd)(~0%*M`MQCTSoA9A?1D0n;0K5Yc3c%CY$cRmyAs)4a-^uTnF}Tke+n)%s ztdb73vKw%lJ(d;itkAObAu5=jb>;HVslarIvVp`qf>rm`C1fb4! zP>8#`ySDZu5a~j0D;+@51Z>O^@hI39l(0vB#Kmqi($s}z*-sU7X*_pOb1CeapP%PT z`~~=dfq|hSQDJLyQ#F&XZ)pkOIgM_sQna*RHS(lD-(K?wxh}B?`XSc)umFd#v$KPE zczOSvoW#b*CwH{HnV?sa!+vVLH(3n8@aLfZ6eC)?%^z_@oW_j+;=JnR?z(y>)=8JI zs_?_AZUiauXt{m1QvF)6u(q3*mshaa4mZXNz^n!N$7kAQ+@CjLFy1Nqro-iNmme(9 zeH={8WK+>^YwqtNB2xX+^~+0unmf0+SYy_nMlrnk#}A0YXP8lZ5k$!;(v+9dx8}i3 z2g@~XTG0q9*Oo-WiKuYngt*x*t$A|*NgX6>o1fsMW zl-;`%D!!5MQ_FjlpFkT-EpcbLEPp#wg?71L(HF3fdpN#8H(E8no?>CR+wRifrBIq! z1Ro8&FfuYcSUpV$uO7!`!Prrdqs7NWh){i@N_HfUpG~CBj13Ch=B+HY8Ngaq7?!L_w+MG>sp0najfKB^_l|_a(EaftIP+3++7c@Yyao&-w^`dW8k*HgBYvRX0o<;&r3L2A zkTk|RSNOBPpGGp^b62_yPytOl15(F#8s?pavY(TXTtL3+pYb5cEUI=^A1DlD!DfL+e^qavmgMv)BzK z;B|y?vH%+{VRGf+;hAgqtpQNHykUJXuUwNzf_i*t2o97_J_}ARE_DqJAZhOb;^}+1 zKuk$#;^xK6GSvex+ApGBOtiG$0JN{Kt*jjR^~-%EgO|@M)h7k3U}0dTkWI9VE^mB% zWCR;vZn(H1mq%X|8QEA_2L}ewF)%Q2a7IT)inc9u9rPulbcko315Es8Ty-n>Y*ZLP z=gQn-kc=9hlamws8RvPnDgLzlgRidbw(??&M`3=xWk`q=qOqf6si((kx?E4&a%d#J zbW%6U5%Peei3`8zL7Y9;i%;hK{FR9n7Y{G}n(dH@R2Dh`E+{E2ZJ0kmLBrM5C?k(~ zk;#-lQt8L0rU!|ZPlI5QaDc+1utw(78J6(0hb|XwrGsUyH>Jm;l~+3)GE78tG~X zq{Z*gdXZ9!P4r+Uabf^lW;stOMV%pseR)r!rjpWNi^m2)__huYgKy6FqJtJaia3=I zwc-ktaANRi#y0+_=ZLJWttI8hD)XW+-Y4+T^GR$cP zM0fA-aE0ASnNF$WO3>26LY7#bZVE{$wr)ujFn>zE#?U^~8RAI!Ck|NxOYZ;_0^50H$dWq!|f6Npw?x;s2nkdvJVJ9BfnF1Y>GV)Jer zXML1}pNQAQWxH@S<(`z`tjkNdj?XvEwIaZMQNpfE5En9~cs?UcoWOGMuRZ4|<$~qE z=4X987zaw;&-dh@-y0j&j*eo17tWjl@k}$$e+EZ~rw0GFWFnQ=Y)JL-qNiicGCy&@ zyYhesZUeo-rIF(BGEf?g@83DgRNXF7%l-_63(45?TQ!3QVz#}WKMem2lJeT?b)MtLTKiV^3LM$3#X>-dM-P!7&QH z6}r4|?OhufbJ+sqn)2jymC*ZC3G1JoU%xh&l;qU&O{{eC244JlLk3LwUsVO_hCVXV zOk7)9&LbfW7Rvuwfbwf`1G)qCeB96uR&el!eB$=~d5V{!;!L8n z6wnx^Vo*~8b=oPC|3_ZI3%`baW({nHvTMmOg(b{8uwIMHWx@H^`v4xIT6Dl9G}D zn5S@aNiu_p-d`aKkZb@sY1mc^@BDmawe6)wqQjd3{lDe{G70?mFGkifvcJ;D)m6{X zP`L%9D=2e(gS?FNe`+qxZiM8SCPqrpcy5__79m&e5_I@fIpid1l2$*M|B4EBAlgviEuw`_x@X7^v%b!T*PL|5o(>+qeCHYPBcZ zCrV1-7*<3?ykja0LF##B@$bCD;b`)Oh@a-{2hD^;Jk%$9Z3K#s9|&StcdD$tNLJZ|C>g*gYL6GC$y$qyaJ3zM?aRow6qZh z2P4b;)t;J&zylM7s9|sSwDoGbqRB=o5m}K!~!pNc2V;8?`+gSKsobH7klB;s9}{Bj}M*m^F>YuJyuCEc*HY0 z$8ifKI3AwbLL&Srs=2D5*l?uzmLy%>pp$Z#&`b2Sv$%XZauH2&wbZ?}SL+9NQd{Mr zJlfnzk4p{7;`4Gg7X?w8fb-mjsp?G1*8yTkH1Sk1vyeRzB3r@?r zfk=!j{VKw(*(T*pXS}X1o0HecDQDk%Cbf}ee!kZ-bPs+3C$+#A7GB?$KSyAsn;=@; zEC{K&7(}?L;j4+QqM|_=v3>Q!m91(;Mfj4Ed~YEKR}p9xxGy#GW-9ro2Q+jsYzb5G z=?Rm9Z)4*ykZ2hcl7-!DV#vt`7GEB&T0nCV2#ge^$|@jye=KByKDl)z-IH)ulj})8 zQ*QSuvQ<&5&`(WvGI^owibn{e_Fe-=g+rO)d7;Ucz2#jb29IYavum?bZ_@E?ZOgJeRao{^%&pa61gK(yU2+Sm_IBqiTW$q&2Ca5*_$o$FlPy0LIYr*jt@ z2zo#Cev|PKHRYlbL%q2Hfo^Wxck!1xFert4KC@0HEtv7M1+yfV#LH?LVFUy?>X%<^ zvxU0MmPKLF@!*qiMN&&XLz}&Po!leIMz?vn8dv-Ri8e1-etp9U$IG48&dz3xiq9VR z`bfOqEw8?vgLCqR8u7<^63UK5%W3?{YsUsPRyJ~!DK{5$$itoXa8ZRjM<9+T(_37> zawTT6Q@pORvR8jver*95ro{+DQ>fDW=M|eCvJtAf;DL7EAB*jd9hd1AHi^r_RLu~3 zV^tV1k#HurY`}A?8>#&Uix+9^Jl#33_8@Fp0NIi5;f?Qol9%T^GGn6 zVEKciu7it{fimX#9!ffQ?@ZP2ol=+qnKH_9q4G1*l)eNY05VhoR*S}6b~AoE%|2Pj zus0di5nR#JzBx5S?S1QmEF(fy??_C5{wzK1v#bc!WOGdinIn(G;lia#lM4gL2H{Bl z-Pn}BJcNaqxX8=i%0{>O_8P8hw#b&$ExFXKktNK`#I$+by~-`&_v!8|vFDx9-xZ+T zX6&aCgOw4>mEF>&ZK(PA?)xO@sG8=u`T3u+u|9spT!ECL^+tb>B{sMU%*GbbdwxMHN+dC{BOC13W;pRNU$R8TW7amL zd{k14ia=W%d)^XEIXM~D_ijK@Q4wS?i`P?7nBPG)_9bF4CA{j#^sJp7@Wb|FphN>F zg^QynQZ(-(=vXmUI>JY@Emx&>Cs5RLKqM++hU`xAop^oyXm@w75%3$zJ}qw-cBQoo zd@^(f1@KFx_cVC)1d-AD_f@7CnVCG^%%jYQsaZ30S~oA|E3a zRcxoEQF{}-fPgx&($r`lfo*KW?-<0=?o0GE;(VVuc$EA(>k>6Er$|BuMSiDMNoV88 z)dFS_l5Ux*OcmRqrZAAL?f2i`Pu8C}FQBp;D0eS3an{b`6QO`K4bhpH5UVmzW-7x! zQ05zO1Jl-rF8WFRSI*V@V3QD%nOPiu<%E(3;QeQtAZ}_>x9JB)d2R{8N9c{U7ukocK z*2ynYKsWh!CR2o#0vV=#`(Idoq$|3hfZuMye_e8uBot&sEL^v2w7EXf9y#uNIC=lt zths=|aW{^QsbJJHA$|2>U1=uRtoaEmNs@=X<*y&XN&9b?KmC+POUIYDS3v!7m!^x~ zZ%e7MFHj?`v7&J+ypkQd1$}&^>NfusESWIzyINK1?k#&vv2fwpdH`g9byJ0OJ(O9~ z`}CkeKbJ@>s8}i7K~71$H}qNTkWH844~P1Z(f)Y$;QpDD_rEQALnRJ8pmDiIqrQ5v z!@<;C-FNWM%~Q>1?NfqgddB?31*c(iujp83wXrO+DFwW1cSWi;?wUxxG%gn1tQ1NG z1>R=w7t-^AD_dqJ<_Q9+?-`jzc)lMGIfZJV9rsBJ34Y@UHp%fkXdTaI&h{Lthv$m{ zd1X~w)(ts`{T4YzL2@O)eh_jq3bxEG8p+5hg;|Ff`MiN6GIE%;-B>F)mM?zC2tTPg zMHS^6-sC~(U##p|O7EQyqtKNZ2s-DV7Bn#2nIEu|VnDUCPMzd6jV`94Yqt!u=?Rgq z7T$aD__k#SSpQ7@j>H?&I7x`nXYyFTIE5|x)9KdH-q`7p%t9#TPtbUWkMPu~rUv@;j@mXf|;=eUkB zH_5YEStYK!nbL@^&7{IvEPKyhgTnPQuZ1ks)BpJSa@DPaA<(65oAYYF5ZEjiyPeN< zu5mK=CO2kQ%g)63m+TAo`pK&q(?_iig%7~sW#6irAc~(c23a{f*}cX9t*EcIEzXD~ zc)WgR5&r2h^^A{eQPTwKv^>JKs_OmmC5Z#{-g9;tc0O6K~}YE!Lx(qS0Hzn z6%)eOC2n;~qYA3BzS=bolTTR@ZzWo}J|XdSzt0w?}%L zi9G{TKNC^)E>#DC!a5T}LUb}@Bwg+1JTn)4%0S3AixD(ew#V{fK@Thp=Xxs%mM%;| zGYe-YQ&n!5MDla@4S30+HDs-_tBQmPbzhx@Li~#7unIBT>-;>jG+VSKi5u~(A^&tIX zq1;hW8ZoaRN#@(dp6(Jf_v*XWOD+G9Rz<@_;kiGD_8;A(z1E|00a#)!Pe)Q< zHs8(E%DKtzC(ez#m+98;BaSMSk23Vk#(8KMovP$v)0*DL;uH|Bj~nS=XR=~?bi&nBqiD+aoL?a`pcVAI7W_gn1CF;WF{thrb1VZHQji2B$>owZfVs#+u9x% zw3uQv5LMcWXY+Fcw_~cr8@=tH%gb#RVFqN`WwY8FvU=tIX8N01@L%fz-n#^j5|^Saylz|Nj1uZ??-ma%}v;in?n1OmHnNK zp+jsc$)_7|el1`5J3ryWpN#$UAN8x_3sadGv~Wa!rZaWWNK$ysWDfJ5(&*I8Qf9zS zYRL|k>U~dpvnb~^O@yL`g$^8-cV@DOZBvW+V!rB%`AuO`rj*BFXJV(RrCcUD$(Jvr zM{_rG4C}6fd)LBR%?!p5+l-5wf1DKp*!HYH)V0s$A-IMU#l+un60}7?+s-g^N9^S% zQ;~$#=Jv~V4d-Z+F>3JjLKgJHSP0|ex45u#f+VDDU{ow^jZo%WD%?s=h3BJJNmD=T zr7>=HAH314xzr(VhSp)*gwA^7!N@s_JNoKvMid9tfjXx()Iaol#_Se;kXQ{(KYnFA@g z*#`cMYYgdXnk)dwUhSvc`k@;;bZ>r;A|ZKi^_cz6fZ;*>jP6Ahi^I@X$P_XfY&=S~ z99ZhY$%)ma4($2@V4cIG|2=H?((3W<>mQ>Rd;DVDQi5zhiWlNW+ep4V=RF(x)!fIr zC?zfk-3W4Ai@I8c-fp1w#dLM!UfA;rN`i5fyJXBJv~|r{ARM=nj?AD&UKio7(*p}D zlRX*2UH9ooyxmWju0D7|c(d+$rU*ez+4u&|8P_Xt%H)lQGY?$1;u<|=m;wGxkVV;j2% z=pcC|xrsC1HC|DTNGr=$#S;Pck*Y1)GIsFR<(9Yk$Z{hkOpx~lu^hd&Qk6Ut&(ryj zNkK^Zy}*48f9@ByKK1aKPPx#sjLPJ5N+tU~**p3jUQkY=xU1c3+dh}0z29aH-=r<5 zgT9cSL5EKR#Ho1J1@@*-8?KjU=Cj$eXf%m2XaD|+^h%}?9UIMp-Cae;u7Upq?9_TZ zs13Ti*w82A0xgo_8e*1_>b`Oq3N=7i6fth2q9kYB`LIR5W-uGwJ(gfJ5vVX~`o%Aw z8EM_}vK#1f{Loo8Wia1}>$<_1H0(l;r-9LX{*W8UMw6$xwVOgZ?c&$qhaXsy3By=L zXUzA#PP=Wo9q3y|)07CueM6lB=y&Kxi*)^Gk6%uhQOKsmI6q;h zuuP>}kNZ;jw?Vg4BUGPySzdm4^tv-Xq#o^*g739op2=SBe3-kL$0*C7jI*Cz&1M$7 zaU68<30bl(W9aO*!aa^R+*+!f?Xo1L_)WaPrqyEiHw80(8=QT>e(mRb=VRUsU2s%- z)r}-<@k#PA&m-=-&dbaoc*0)`k%MWJR964-Wqb!H)M z?7g`4V9*&XcSk0$^qnz2>g5yzLv^B?G(VliN|3_&a=lZ5x5c_=p2ptQa=2wWj|w#5 zsREN}Qxe52nC{CQ@0Es`aK49Cl~F^0i`%g(A}DeN`(4E)Dw25E7z17V|3 zzQ!5vLKrOL<{cat=K>71?%f4%o=&Ja-`3QKTr!b#;7oK zm>(bYo=|@GVIh2xKuQm^#K3=2a@|C(V&w(pz$Uo1oj z+q()A-{Ze~tDfHiqHjZ?cr$R!dKZ3@m#TIOW*)yjx*pEx%of7FYxM1XO!^cpOFxmC z-JDjv$Ws*BeQy#n;qCQFp5po^Ab>CwsumEDZip!vwZw3R!kko9Ncq1%!4vFaHd; zX7=&$yeo=AJj(lDxO-0kT^XWyq!zr;17D?-VkiyLCk^zBjHDUFOf3k>TvV9|^9qrm zN3Ch(u3&|p->Ah`n?%C?)a58})<9a^5esn6MaieZO*`p`HdpogOd&VR&4!)DQ1j&) z1MU>2pKY$V+BzGnh1%yLIZD>@!q7&)l(drlCRl~AgF{o5AHy=5b=u@Ye=_75Q_72n zfoPdNt4S8TBq<>pg969d>_!2+V~1Rw((d8GX$jS0#q+xBD?+`%K$uDXrTGh{KBf-b zu273Jo>cnO%cNW}*SAvDvVy|=qkie5+w9~q=1r!HF! Ie*Nx$0Qgg4#sB~S literal 0 HcmV?d00001