From db7e4393bc99602fbccea2eaeda69a0c612499b5 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Mon, 22 Sep 2025 15:40:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 271872 -> 277504 bytes ...ingDef_Building_CatastropheMissileSilo.xml | 65 ++ ...ThingDef_Projectile_CatastropheMissile.xml | 96 +++ .../WorldObjectDef_CatastropheMissile.xml | 13 + CatastropheMissileSilo_Implementation_Plan.md | 468 +++++++++++ Railgun_System_Documentation.md | 743 ++++++++++++++++++ Source/ArachnaeSwarm/ArachnaeSwarm.csproj | 5 + .../Building_CatastropheMissileSilo.cs | 119 +++ .../Comps/CompForceTargetable.cs | 18 + .../HarmonyPatches/Patch_ForceTargetable.cs | 23 + .../Verbs/Verb_LaunchCatastropheMissile.cs | 78 ++ .../World/WorldObject_CatastropheMissile.cs | 73 ++ 12 files changed, 1701 insertions(+) create mode 100644 1.6/1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml create mode 100644 1.6/1.6/Defs/ThingDefs_Misc/ThingDef_Projectile_CatastropheMissile.xml create mode 100644 1.6/1.6/Defs/WorldObjectDefs/WorldObjectDef_CatastropheMissile.xml create mode 100644 CatastropheMissileSilo_Implementation_Plan.md create mode 100644 Railgun_System_Documentation.md create mode 100644 Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs create mode 100644 Source/ArachnaeSwarm/Comps/CompForceTargetable.cs create mode 100644 Source/ArachnaeSwarm/HarmonyPatches/Patch_ForceTargetable.cs create mode 100644 Source/ArachnaeSwarm/Verbs/Verb_LaunchCatastropheMissile.cs create mode 100644 Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index f433ccf126f6515b39788c48b1b5f7e222bceeca..fa152df1cc938d5990f12cd8bef71f3e68e00680 100644 GIT binary patch delta 88576 zcmb5X2YggT_dY)NZn6nUC~3QaKtc;#vH_$B0i-tp=_&zKPz0s9umJ^cE*q*MO$fLm zf>e`nQL^~!&% zcjNVgZ@HxTEz14(foj?~)i_J3jtNS6HS+1v$TvoQBA!aslf0>vKtQ-`N^M>HYMVN9 zz&)IN;J(jX+axosJVB)aE&-uoMH92AVyw|J<;4!J(2f;17|m)?H05=wxYx+9g%S!C zsIC>KjHdPPVEy=aF8-S;QQcbCR1ftvl@aNkpU}B-ggG_Q*k18K(!K5PG*v=DYk!Lc z`;n>gZu2N_=|rVc3d%_dUW#n+G9=1t1}EX^9H`iy+{xHc`A+hEiH4_gU7gDfBd_Au zx>wcBGnA2@wo)FoSLRjDsW;IC#~T^V&Eh?fo8t92l@O{-ugz!hCCWoP6I_J-GHZK< z*xD|(qFr{jQCTrCJHMM0*+^o&xFV~8u-712a1bJ;C3hiH<-MIPc^!m;@`DxIva=Fc zzG7s4QF3ZhQ6X!r_%_=L6KkIYTUM1PExD+hX`Q05yK4&DO=0hgFjBl#-o3DbwTg11?IOzl7)j|TNSv$~bH#dJy4K-S@_a^ec3krW`#G_`)3IL= z>jzf36@Li?T9KKUo>=6IR!wB^E3)RqYW>>f^rm~k+1f2nZ15YhqDj%#eCx6%r6*~j z6(jw*=#iOzeqX>>>e0H}{5gff@dG)2M6%#eO{?BP8~y}BLHVJI zkNr)%>;r;cau|GQ6(6Qe2MPWRE*B$SV%qeO;4dz^qDPL;I9zc-PLuF{3jGcE;P0_A zLHdnp({ZW{UzGtD$c)M-GAsC>7_(jNQ^7xoHSKh;pwI85=s$r9{uRgl7V-tH6Ix^i z8rg5Fii!D+lHo`_sVzLLVa1kwZ^b$FYqdDQ(toqGG9WeD8rS#WE|aCm^!lyPk`48{ zgxUP4H)XP`a<$5WGi`d2_9uFlOQOHf2iRTxqE!%S+H@<24i?91+H@<24psw8x2hQ0 zAh}3%h&onsdUBE9T$Sc67r z>!}8LNdIcksIAmScR>>ZhA%TMJ*{X=v=!BE6ika&I4HMa^Sfx)y1)eM#Z@KD=|r%2 zuD8o@krF&6STuT-=>@2A|Sq7t5zDxRc-7A9Nq zRK@WNM_1f9)XIIjCeKqbo~J8c8#>67{HhlGc4hOCcNlfQ)X;ajnr|ykjJiDcy{L#2 zQq4(<=q1&>S2=F<_eSo?nhdAN&`%gnR$P8TVeYA#^!H=*QQk^Cbt==@(Q?;5v~6WTc!XC@~9p^<-9jJd45mIu)a z9H4!0*`1!0RDda7)A4vJB2xzCCU_9WtQm0Y)FgWiBnNLqf_RdaQ2ED{XH%PV#@t?z zlb#rSmaW(;jwiVKz?~1~m3bAPhn^hig(Pv^L}aSGbx}|0YoaPC7H0c^S>??zfPNil zYY^L)RI^Y$7J5SpC3!0UEZv@zoTt^VUwON|z^I$8p>!7WIQ1$!I9D5k(}7G&Hl13) zCMN|eP~J&KUYW@@pTRF!-Md8^dGjw$wE> z)ipJ#_&a>OZg-9AtZ|(x-Y=h(+kybsCpjNYo^q)aPjta6E8e?lVw0F4@TDik zNdjYfGDKY*$xbjHtSsGB$7?)QxoF#JPx5?ik1Hy3cHNwiJ0seh>0*y1Y|bsxoEeob z>}is2cq+bq;AW)D9-NnZRg`(AFkeUJSA_Yhiuw=b=LT!iuP1#iyuF}2STXvcHR!L8 zA8O2QOL*kVgvQH3W<;2UQg9+Ze7>x#;1O5`f#8P9+D|m_!=bEq2O^#IZYVbtl|LJq zD(@=F_a#t%sN%18bNbvU5sHiA-@5YSvF76tN&M>_8HI>i2*VHgJRD5;vsBu%}{!{zS+&MMtS`({l zPDSa5*QPNl*RrP>5|DrY@LzQ!;DC=iEa!2`Du4TEZQZ6@r7F`Y2NvtTg{;wQ^AVhm zc!_Mqz8@PH+bW;_u~|Zw?ZWMG7Lhx_S**DUx!lBfZ9%Mst(vNH8V*2HcT_h0wO(S% zzo1gMoE=Uj@Nhg)uBEs_bgA zy&_^J7`IJ4NEvA=J;lNvB!HD=X6^LaMP^`ndRltQf~Alsfolme*pg7=E+y+$D(lfA~d z!}q$Z%d5qLb6>P#Ydxwg#HKLwtOUg;c3kPD``t1(RF`S0RC!MnyfgBr*BFw!41~CL z?54QSq#es5A14{jB1@BuzPZ=c5*Zy zY;Y5bW0QFvhD4B)rL%zukJr8_63#FhBt-}U*qUK9G#)(^00uFfHasWSuavd z?%lXNNkZPgU^b-tf$B{ZXVKaxpaOn+EGZjkj9=Us=Q9qnkjLjvfDXdhME>#95_WCN+t-G4FU=g~TY1`aOk6Velkrj@=6O)|YI-K#5b?gJ~w-HC+J zZhJD5tlB8zmacR(BA~Y4yTR=&T&j zL`-3xY1Ic%c$scVumOO^w=FYNmX#|4(9a%)#b#K+W6;q-KP1h431>4YURX!`M0x_& z!PYd9TBn+x1nV03Q5tp5Jj+zYu=D>^J{2b{RzG+}TA-F`HG~STjBtV)0Y}KE5+3Uy zVgc$;^#&)SC*cIB9Xr=nDl`zywZiCRs~m~PT8Px`^u@?3U+v-)$O%msvot~lRvwZ$ zub@S#Ngf%#VufHn+n?moEo^)_Ih!DHLa<^K-IRz@B0{%`z-C0u0m5pITvD(Asq%7L zOV6pJyb_**SJ3}d=meE*0Tz$U0-i{_nT9XyiS>_Z-wZRF_8m~&-hgaXf}D}mQl`%# z2_dzb=BqMgubrt(7kd*poR(Ap>~PW)f9-&(Meq2OW%US4P$BeAV?B&5uL^Vcvyq`+ zpq|fXVNeEuVlzY8J=H9X)a)i0Ctja*wVMu0~VEI5a%?T=}A1j?f|~hJ#lOuJAyNERPB_F@uNDM@4l_IfAlQVBpI@lVR@hk5YwGOzU3pWb@do z(9G%$H+A|Tp^M!^3IdE>hN=o50QqdzW|k2S*>n!8QoD;oOhmiOVGLe4#wCb!305a5 z0a?H~3n+*4zp1doQaHdtJhE9fM^46|woiFNyC5eP0Y>^#1AVj(MYZ)axEUG-3_p6d z5%{00$#0t0xX6}ki~^%9a?CLr7VD8At&mZg5>Q@_oZPdL6!ulBnfR5*>MXhnUr{~O z6v>%qCejY z2cICbTF^Dpc)l^PjR!M&fiLtmnzOyYZ(7|@7+dpDlU_vB*M;?IU!v75lIs{vQsT6I zY`&4*P}IcU$_v9X?+eaE9q3w*bx!1m`9^-naU>SwOj6~p`foL^&^3Bmd$IyvkFKkk zMR{h9BYk}o9N26j2wBTefg5(aL*rnN$eL@74goepw;}X3n5~syvvyM%Gs_WCJ}v5o z-jQ#wHQM+-)r%9HCduN&qj0#Xnn&8%M*XvTLNKBu95=}utU#?TyrD;WyKWNduaH~J zu~bIos(i0SuC;X_G-{=#W%LmEKCum)eF^gBv`$X z;fM$WU3gV&L=X<0f>@t*uXsP4JW(x00}wjWW0w98SZeg`S$*8TrG)CfMJ)xby)8oD zMw&ZDMr3Q5kyMKeY(qG5u*}H5kYG^yQuHQGJ=NzGg>< zMFiK2-{~%S-t7`oO@KUi*or@Jb;Lq5sF=6|KZd@q@Rzv|D?P!7D^!{(12JQ`s{HZ&w_2aVc6r zclD?0YIJX{2^-m6T>nMDiuvz9dSSIPQ7=3hHtPG_;+T+P#Sis~q?H@ZTGjN;_NF}y zO_}>ThI}Ca7&T=M29jBLRmIkFU$~s!!LChAl>HE9Wp^v^6x45lNLY$jcCt!;4J7RQ zUdIE$gi`;nJpyKIvc#5Odad;)g_t(04c=v7X<}M9)WF^vi1AaMH$b+yyTB^iK)vqn zq7N{BpiH8;yIAlt7-bju5;9fZ-?`%M%VAPZN>+wZC0maqU;Ng?tC}Ocw`6#CcN?jg z*3k*rZXD~w?M80?ztC)}A0&aJF&@GGNMx-Crlx(#)VPyg#?)+|%kOXe_uqeqeZc`J zmf}ss3XZS9uSmm2Ps3`cYzW)C6X-dwN4{Qc~soM6ms^ipODXCJxN_@JPEY*_fGdL<&iSn_%9kW7^9i4=%-WO|S2@;n2iD zLF?oeSfy|69Z0mVM}ZWq<*9Ge$*-*F>>XF)5CAGtcNvZk1h8-nNBfJrCa9nB3`i&0 z)plMm3>M3>h9kwYfr?m1Vb9jJynbs0kO4$3VpBuDepp@nfHg;!HHMz@27D85{W+v9c>2M9ETEQ>5bislT^dv7DRo*lBB-Sku!k*)V z!KbWm^`2PvgBbpTPY#Y{yOLcl9Fe1uHMR;^nn0UyLSa{rY2ifDYhhM`>kcz%!CnsS zXIcluon;+99;V?x)9>6sn&{-LcC)INgLg)PRXrUXF(+W-v5t@Yy3Qs(L%m=f=T>H| z9thNsbnLyz!`B)9+C|#pb7`{^kq@sk8icoiFSM{>{I2pgqDDbTY@@l0sB)m7O!Y?7 zEZa%+!86de6a7IA0o#f4_K(SwE#x5;x%PS^r9O@dz4m6XICmhaUK=&+AK8389H<4# z$!dEZ6t}0KP4+hAwih%AwIRvc4hY+Gl(n|72TTixw|uP8kCpm?^HL&L%fn_f(W7wm z1}ZcTa%xIgPcHgvW*D2@S(vq2i}g%fw0ICzIy)f3w3%9)!LFrYDc>L5ro9_@%qxJ; z7MM1`iW!q#7B{~H{bLF(0=N3*z;iwa*4IDQ$ z6NgszRthR{_%PEGw7@6nKw992GXz?jv^<#?t{){T&q$%_DEROsXxHmqrPv8b!mjSymCE1Z&9E1d_4HCvTprl&}y=zz?#a7=|Y zm|o=O*N*Ox3I@3Ac3Q2B!^0YhG0ffB7$McyRh4nLxTFRlTS&PsNwmf+83KV`4k7S87y8x@*3i(C;LL zvC-D{V0^Ql!1(9T|7Xj_H6w6tye%W~az_d&D)#0W>7QEBRtFfj8QjPr9(a^$qoZkc zIB?^~Es={>VZxEd(k&eZPn>`Vg3jnLY`QSDg8l1Y{71Wl+O+m~1EzO!TC^DD$UKl- zGVTm{)db4Tud918>=v>zRrK^$Y|R+2|AooT$9mdYuD=XVVue6hOHC4 zlLLk~Ga*!gdNO+Jimh&#SZf4!R|=)h5X+?}l*|}sjm99G8eh#Vk@jnhmVNH0u>U5@ z?=Z&e8Nsb&BchQi<|fCjXk%p48l$mx2m0@H>_>Rx2`9?hB?Ou2^=BqwR?sL>F5O#G zEt@v*Ux7A}ty3^i=5>5pTD*~LBPG-d9zt9S(5a;S=cwFdVFieVb`ZGDc7ZEW7p6;~KRr4#D z2G0@;YCqxpfEB6+Rz@1EGx9t6&%@f70{m{+J;N5RDT=21f)hbn5sOiM3@aVUs)kNRyvZ8W?cUD4yW&X4roU}T2d11!yU&pAHl zfd)2g)w84X1u(8bxL@(L>+ZFQlk+Kk5$*y6VH|V#c+7zXSc-+SvVipflDL9ZT(#>r zqse^V3?Gs%n1MY6I}>xmjp*KJw{V@5g^L(8y6{hox$Y{^c%YsrFJdwie3^;GCs0(G zFn9%Qf|_K3Dg|4{3a*Uwyvb;5d=UxWWaNdbTd`ma8z8N+N|4RmMpT(O;687{Jq%c>vP@ZkBY-z)6?4 zy{-`VBT`!9-8!|g2;g;0W}Wmpc=6@d&pn~0SCqHRP9SH+>~)!uX%Qo>QM9?~>FL@| zuf=S*JW>%cnuZymoN=5`W9`YzOwYt@lwQy8w>qIxs9G<*uG=U%!o@X&tg7s5aafU_ zReBLx=C|5GMvFL2GqcmPiw2yjX6XA=jOZ(|9Z#(y^JG7S7JlaBQxpr;}WUukA&17E@UnoJ{3UBSG1#{&L z55cUItg>nsF99X=5l3Sghpe7$aRXkzx=Hb-HgISDBCnUPSKLXryQB zmrBA^9A(-b*|O2djVFzYlD3{f3PnlVgcObwxGqYHTkO>jQAs^7pRVQ8QGPL>-hBOE z{QrsaS5J@I3nI_nV${93`A8au6TK`~td$r|@-Ch|fyg2Mczl906PeSIE$^w9&wBA> zHVtMh?&@&zH}kU`MrgC~cNpf*zDUPSM*oZ+tRi;e5V~+=WW^@D#ymT6_a>u(IcH?# zrA>xEd@;P*3_7Uaz69CvDf(){mDT$?{a%ipbPN(Du=jxD1X(aM5jW1Fb~q*E23lAd zg}J2MP{JsdY#3d$OTgD}?;?|KHPZc^#Dy>n;61s@gOy8d74nUWthm)^UvB~=&252S z{1j#2DrIm&TABk!MXb$6cXQ&X$Q7H77RIHK z)til6bKR)OzRkuM?^X<%^8JzIEk=He%OHrSvKCB$Q&~@NDl(>h00ylx3fq+KBJW+1 zp<9e=^v^_2g6;`oEfZI4ifJE?e7MCZNI#5nv7cQK?Z3@92fqsVHrpSWew&e=hnK{d zdTjJ)g3p?S+EaKT1OcEChW_EmEw>pB!*{dNdmt)aGrJ$^w0ZLcgATjOdkUDcY>kE-Twi}&?im=kB(FEr><=Q$uhPx?tn?Wg@HOIXoziL!JKIH+v5<8& zi_-osy z+l^LX@itBLkr+&qu#b_?n&JY1fO@~c`M8^QS@7gbB%t5NB7sPiNbnqLXCx5!Wr94m zz6lQ9*IU>TVc{59;z!dPptz&yEo2e9Ih>lvaN=lsBQjyP;WOXxMBYDXX?e~iSmKPB_^XkKUu z8Xk?c)eL9GS|NQx0sjzdt0xMK5c>-Vwo=^5AHQOhecQ^-c@^@?TDVCNAj&7?)d_x2q02N8p zzgxp?JqfrqFf%ZzP#t4Ms$g`8{VuX)pV83# zVpK)@OetR9Ev{pxl;xNuqp5Y5n0bxF%x}UOcr*D zr^QUx6gS)ijK$0z+O5E&2ONDfHsD0647e{*J7Xrh#$kf|x6ISUbj1P~X5LX9Gk=UAX68n!4jA>q6eC{o3o_PI)q(Th6c2|WJ#Y@Zh6o)v ze?^Xd#HaHU5;z>$;BdI_BpoGEVQaFuMJ03|F|A+3&{>XDV24?)3~dYVWCLl*UEXG2 zm*N1*>-;9AbxJ;maR6=>!|0NDB_D7Y7|w{iu?2@NCE>%yX-0y*fxf>ql6KIja|KuK z1)+Ou#%r$G3qlWMFqU=4E-M9$TOpvrrydaiT8plN<*0rMKrGIOeBh9xK46xJ4J8v*r5<3^>ISce*D>#$8R z>xgDz9sbmp)}cNQ6S0ngDJ_0*Re>PJ$w_f=T`p=J-bmEesiJjq!@Y{v03~}!7J;D* zaQiL1EPxF)R@skF)W1F;D^z!(P|}(gw?7i>hC;OIXbd+JCA95 zD5y3DO;I!bLk<^(U-Ek`EF97G31F%6=q(3U6?M3%Nc2R0sWh4x3nTu+Mw{`qz+&oO zBrk$w6{~BQX{QJ=6=_ft<4yz8NRx&*b&x$HHl}$Z6L%ZgMo#3^Nuy!yRP`k0-acZC zw8;C1jb34qP?`y)oD8W*r~DnYqifcPxH$HYql77EVaKL41?}UkM=v;goVE zoDvbtCMg>^hEqPB+DPCWQa|G9FK#?#G0t7&!N($y2BYyb2Rf1@HN@)1cP_wXac|q8 zz7KbSZor9^K2ey3JxB8S+|&rmVwl##;wmK;EJImmfi7#;+8G{e2|1P+k)!)?k|i$uelt;~zA!%At-nWR*7y4V06T z23c86Rix;4BP|?fNjc`-|#n5BVRpDf#@&vfMXMS4GFWJdNMF|xF0Nf$EwOIKEhe+r2ktO7=l zL;Gs?1cx50bnMtzWo4#}RsQ0iW0jrYFhRZ^^K?~j;n~=JH3Un1wDW=D4woEc&loN~ zcepgs!zEEgFkJMC*%zt2&*&be1nK(v$XIwy>~6mrP%_+}ba8tk^eQ43IXVlUjvoo! zo@{U`4_Cr&DY`aUOk0XZy}pU-^-_TymTKQaT)|p;e)R@yR@8~bpY#SSbaPGQf1Bkg zvC4}pck#2lsF@R0Q(j?a6T%&*Vw_AuYn$cllh6bQnm9?BQ?1OiHS5(&j&Eur|8He* zgY67u>WeaA811-rap{TZIwoW0`H`5FF%ZRP2tp;UZvkwS?}#wvS@5%!$j5t z1x2xPv~SXcQU#5Kbs4K`hXeqU^>NUt9VmtFKuMAs z?4~z8Y&0B375JU3gy0JFi=Klqa@r#PT?L;o?P>-KKYUHmwdT0BN^p}Jbw^o|X%FMX zkr-V!J4$q@?kH*<*HHpS;~H*TqN7+^cNEPV>nM>bajm7>QB=)gf=+9~JT2)hY>2pq zd4&fQ?eHkad2Z~qIWpoA!yg&&h%q$W7I?b|iD|b%>U;t#gziP7qX!n%3}+r#2&pv% z{J#z?+K~y%Hq?Tb5DCGRFmnrr+`iG}cYB~+hw6x|>rk-+3)27bz@k?|WW!z~KUv4$ z_MXT?dyP(E5m#D_mOI6iZ0oc$@{Vq;Mx0Fqn}Bgjq9xx!`2d>ojJPI73$dlaH^UQS zXT&v+EKmwZ7I@1dM;0Q3K=qMD45N=MI!7*fEbhpn1Jr;^vjuQz_sD`!+>u30vG?h< zt6)y23(H~1kkvi1=)(4QCEnI48||>$TtpcQS*ux`y$>VgkWpO0{*hL|39!aQ+8s6W z)83Wg;9{zd!i#Dg{(?evkw>7w$IS-Q&GH6haYcBB3fDPP|$ zug@%`FlRt=np*iaP`;}^v*?B9;>?0=s>;Up**)j&kq~+IPJ~XDcBwv6V+XygDsDUq z7(28WAS05c^@yZ@#zv$_l@ZCW`!IB}a~vkfcVeDSrdJyMz!JaG=mv`G_1%#@BaC)) z!{{IhqjeHh?9c+Ft-Fl|`qYAQB$)O<#=_FbU2pWHeE0y2K>F^ux*oPz{D zM>hCe^wdJ6!rEjpZ7CWJql3iMS&md-8$BY!o-}-8y8-L;7H*wV9fyM-o)yDLB(NUi zDFvfJbat*jAC4`&bt(I-$iq(>jsE`~OR%~s?>W#Y_F7T5GskVGOtjH9l3mB|fn1!n z43nT6&G;>iua4g|SDe2H7@cSbinp+|_7?VQ%v(gNcnd#^L~jujF_DROD6q1vi+ui+ zkstm!E)e$zkKKpKFa#gj$wc4MRg+A+9~hi3CDIDEFAMxbc#hj04gibmgy$j~_wFuV zPCiJl4!!=kcXt;=c0OJG?ruQjg{O@+XN$1X;dF%aDA(5M5ab;yA4Lozg37@&hD6#t zW7Ho^9t-Oful=qYe`{iNQCnJcTKvVz5|^4%PBxY^;~|l?&lq_VW2N6=ki3ymZYWj2 zfS{Vid$~O;9YI}(5pV018ap(eizs6uYb}e@x=@&WcE3p7XN{a3ohJe(brLUKYR_k@ z6P7P7XX<_v-43*coyNXOAw z6?w_bS9wReaa6?QxMEKAjP5N20_{b6qrmQb+a0nO+rsvA=U}-%(=y9>(AyQ>{jDijv9^yDmkRObPL&wp< zbSzlngXsuRTt6O#>>0sygd0pRi3U@=%y-wMAW1Mi^*oM%DMy0oXk@J6)xq?9%7^ce zF2R%t9ZWAkj=_{qXCxBz8`;orN8ElBsW3TNOk0XZgXtw=?<_|uu)|UZFA zj~99(BkneQkvcEqFoet)q+{{$TSxU_V~%@7JBEV%4q4=|Q3RJ(aBPnw$<`^$R(VHP z8%&?hl2&~>OTZCvIW@(F<(!d}IO7NyJDnXY=3(X9JZx0VJff7ChabVCd8m)WM9ecS zY97o3+>DI}!L`oC9+h>bdB(?^hukpFC3yI)$7`DBB1-a$KrxR<*5;W&lC4vgt@4gJ z%{-)4n}>iS;&N(=)8-*1&O8Ff%rivH!^*XJ(5g7|h*Dx6eiD%8p*{{1F;9r*X;V5E zkMfB?#*RtzJi)n@3Da4*|t?KW1iDZw-zE8|v{=u-xLs`szwR|k)*3-KdLIbzX#_(EQF=kdOk zGmZ7)H_Lcv4Rc%#Wswxs4&-Eam2@qSBeEi29K&2dvR0ZwLX@u#5^Qc5Zp6_-uTj(&6ZZ6l|yg1=3^z(FJWBrV4Q5(=I`9WEz5N)>_VA~F# z!1ryulQSaBnS(G#+q&1W=^mcB8XtF!Z!v&=g`qa zY)(`xuWX3AdJ%CmrM!pxh(hLFprYo#ZN*43UwsZmb~<93d~(NmM5 z;!3PWyArJ$b0y;S@fJVS$cRDZ<#Ub5moZNZid$^~N6eE(;fn(-ET3)k_=1aZ#tmxZ z^Vf~s(ThN_?gplHYtvpVY(%+iMYtU(pe)sMs$V*2@7aZF%9nsUR#%?K-Wa*y4a2(p z7Py*eFQ@oT$i`Skc@pefg?Iyrn~@zCqxONnt^hu`1$ab(7$pSCN>JLQyP4pY$cJwj z{>xSoS{a_0($6TqnH|S@#ZUih2ow5o-yYQjz1dJEZ$Sl=pw6VVYSR8TY2q zp!Pb-vYCcXUKm;UCZYxb{iz*XoU8y)9HAS)H`fA?FIAd0@xj~B9A`apT7qdaA6$wd zy9mw9T5gw#5362K#QU&Cr)tit%T0Fx<6KaG6heI=|TtBRk28Ivlf1ftP8s$ zB17K7i%wCI`!E~#T~mVFQB~`t1v~HvBre#AM<{Vt&nSiw*cFdB8S zpmn=W4;A)pY^YF#9xD8xC5H-|>M)Vv@qi4E$mMSv^%{?WBn5}sKnXk19q>6^T28<( zYbF4FQ)Ku5@`YLl;@n7&H><9599=_)i(WQ?-b!RJUv30r`d55~dPl>Ua=Tv$d zffT$3#w||_3dA;ENW$-1=$#~5;l~kd;}~rN+&*gujG$#zc^_rJLdg_s6MEFyhGHnq zN0#*jF!80U7)GBY+jh`d3!lN}=yPWW3nG}a5rG~c5ivH1qtO&+C$i+`)7gXs-atM? z^K+tQu#+QMf00j@)-Ox%F|8+{BR!rXb$C9i_jt$NHL{AtY*HPgF?nLUJXRL5MrBWuV=@hz6qzQvA=`Ig9&8T~QTOW&d`9VW2{JPRg=~V$+`n$q@oshpVAsv|l7yLv7d^0tRii|E zGDL$~B;`G$b{As!eZ+%!2Jnv7wC_Z2!Q0Z=MDA$9s^10d+zrsQb$VB1#Cv!{Ou*Sg zyx*ZH8LA=^T|;8DYbYwsOh&|E&a|0IEvu(i;fG*dufp%6WO!3pobd^+qzc&b%3X%x zcw+N{VUB9TZeOsqvA$sadYtn+vh0hyfN_{0zn}SiI)8w9Hdy-Q7`U@U%FmA+S zn!$KF0zf`qq`xI(or60oahD&Y$wg=~zHs4wHZiyll5vwC1@(vjdV7n~-47}fsXw(E z?-ut1>$=5*$etd3?sucl`#Sn0s!W_TT_7fA$<(C&T*?3kPZ32_DxQHlfy}^^VxBV; zKZgWCV&PI5Pz5sp56NXv6U7>W`al*q= zC7WaKhw+1LF@Iq`KPr;m2x75!p=8nx%ZWBjPQA3bOq;^xW2<5L zo-ALmc3A>5S8sEAMk}x=*lo}3nn-C+XdjR@udz{hmA7ZjMm+{3OwNZ^tiCAL0P&S~ z+N2j@Q_^+#JSp3va4mQO|I5M_3UX~rX5A-@rqVanYg_habU5!f zO&Fj}%f>rQ#IoOncJmm=<0HUb1M-D?;7kDh3vZl0dghl8pk)|ISEe4K-LaG$E{ZepZW*>vhAhbwH z4V+h6gd#dStsM1yfuCRBH9^d&n-Eo-+~>a@2z_|zj+kXJZKHGh6p zJz-A4&vC$m*1nDhejdUAZOumI{CcweCXn)7G*YNmE{qkY))w%*B?aG>^c_jxMe5GL z`a6K}LF5EkbPzd-Y;+Oz6sDo^?E0`xj_4}N{dpl4$9iihrAz+sgVaLFXe{2wx(>RORiB3wfINt+UsIgeorE~M3nu=dkfJn|XLPya)Nw zb3#+Ex}p>ssrC5KMZW==-Hm^Zu#)FL zukv?IzzO@slHMfgk}hQnGSvwDipi@!>vGe%`1*XWE@X1Lmf@oQhKeW0c-0NX%-;-F zulifky;_d_0k0iZweuk>gB&|SdpLXlAm@1^W#@A4fmeR$F+ibtDO0SX-rF+GM!nM>42%MV1`sMx)(9(Ak#1JVtQ$A zUcOh=uhT9&MK$Wf{Li(iO4dcpznj`FyHdShh9$JRvGwb+sFKudzro_=^s?yt8aQ=k`Ha5q|jzogMq3QJ`N(6SWO zd_J! z|D#64_{F+?I+FkXvxu23%Kbc_4J)|9m>5n`Ed=Ee)|F!R3DYS$DTAVazLY}yi1%Jn zm!hYMG5ggc{=AvAhtHT1kBI%`vN!Tv^J-!RIPM&iDn3HXY-_n_wKzF8pjbpk&y5LSpYX$T2>!{a8 zQt6lGvjIcvFyE{-%U*st`CDZ(4R<1D@J`9UdoCYebYhyH$+S^c5n6CjlOp`uzuskR z@r&>h_;Ueu|8op^eueHn_2S?kGgH)qGHQOu7=cT|kyF$);(DDemRfurG2dRrvfHJW zWO3n)O{7}k4J7|w!Sv)jrgKJC-XMcyLx4heoJCCUeoWWR zCFbosrula>?FpyzsiR`#eUpfJ?Fz=V8!Li%7nnMMe&gFr%)C*ge$#^n--3$0Dr*qq zLDEd{gw_0MBp(xf3nA32?r+1wBbKt_qA=4fvzg|JCALbyUf-OUF;eR9YneAzGyT0g zrGrDD88qH(Ox=G8G5ucBmlrdCiBx>E==-f;=1JkFB>hwHIg?YLLI#Aj<;()^i)2@$<>|*iu-|i;)#BLVYjsTLP+TF}_i>MVwi(v!dyyPl!z9fRK z7R=c3#0-=Cm6HDZ3fiMy8f|c+$oyANN*Hj6oGlQ%Q`A!<_lNPgp%H;*Qo&h5u5!pU zQK~<19;t~kf4_Z@`FTT`W=>?fOUA{!=yk6;xX758q81Efe&|?MoL5RY<7RQt9-YYa ziLOlBUcsok;hGcq;S}|p2+gb{>m7*UnAv1vT_Tm+_V?za<^c_@INBwIC^Gh#esq+^zJx98-rF2SGZWVvA@f&xNr%l$pphS)$uw{`=fL|yEVflx*ND%X=aaLuVE!E-b(nGelMl`+Mn zKD>z1j$$lel^}L{6H0j1)kA2Z*(=2VpOV#1LMcu6?S7iek#O{}OhtF@W8oW`v0}f3 z;X-lA46)GO3{n?okoxLQsj@xuABqxh2xp~O^dT|$a#8oodF1H>Y8cT<3_D6%@XA&a zR*8tZ;$qvS-OVSl9eYK@=LeZ@a)6WUq0a1@-^y5OpUfH`!I8acjI5Llk?@XK@rZO; zdOxbzSMsGpkPoX3;;UDQrVq$aY=)SH(cFoaXp3sli?=WxDpRmeT9znEe>a=>DKcnt zR#A!eDBCyrkLFxS|L$=5`Q&Qiw`?V6qxMX{6iirV&hTeqkU_J^dc{npGa4~HJd><` ztaH%Td}7K)>sO@W!`G2|a3-m(#I0^y#Qay{dIhpC7;=D?*n2B`dKTu0I_i#295plZ ziBFJ~l`kwpI}D&nn=fa&>Pn_P#RDFb<;E}4HFrw7d@ZYaOh)#zGMsjagr6mTbixSw zI{D=hY<)^oR?|x6g3M8rxo=hb3~tQk;o~LTykVPWgzKrda8O*}g7s9JF2N;dW8a+w zVm(!ebuXc0(CevA{R1Vvae`1wps_AgTcCFa2TCpmEnT4GA%T*~*c)aD^gU?3F{d^V z=<|LWYOEIGRhGJVe4wNNM5<6vWuo8)K$bw=W&}z$0%|2t*HyY;Yk|%ObR4t}0yV!V zP%;&*?kLdnnUtBP&Jk#!K#f!{fyM~bMD=0yD*VeqvNluwg!u3PRADqz{RL`K6e#I$ zG*?3f8eYQcTjB3^P|;DKIe;z}XgX-e@s}1R3)BU)`S=rGQv_NujI^`V6`B)JZzz4G zK;6T)lh{Gc5U?qr-l~(DDbSwjq;*oW1-c$kZ~SGykU;-APeXGBYBV%Zvd1__Ef8qq zG}3zDZwOM+2LT-iv{azvc7c+6jDc#IKp&hHChNKCIswZkX=tTD69F9uZLL7wLed7~ zY=A<)Xhqs!wH}aCuK;@37>%P4(pr+!xKeEr=*7vj)0JwoKzjhq2eeI~t7Zhk0H>+# z0=_+itaH>3f&M*{9doTZEYMoe=A(W03iN<*UZ;)-^xecj$zR3_^|V0gmj+4peOTcJ{2?p0;`cm48`V1k{m?Z~l4x#H z?+UaD6(*Xus`mxzx-L+XZf;he2y}VFKuLXbtNL7^rGOd%`a+;nV*({j0DUFUcW`_s z3{(6l;41*R`b!`iP=7#G0%gu;x#yH=Q0>-$9QC5| z2-F!i>~FrTQU&q@>TSNFG6lMIZJ=bV89s(nLKeImV0ZI%e7Kd6c^6y%rfM(HMY~wV zJF0^~AIu^2zUm~9F_#s7j6coBat=5hw7s7|?}^pE!e5dk%~wpTeT}Oogt{yalq@yB z4XY9X|2)77|D`Sx=mY8dpKR_3!a9Bvf)H5e z3Dh0XW;4y0FHkc;Q&pN_3sia|p=_fv=Fq-W}$K12-CnV;7}X!`QbN(mdavxo5w?2qdE zo=vc)@q-Y@0on-YXMqM+lGfMwMWAVbHUj!hpdEmoGY1;K3)G>4stq#!6dT?%m^M7$ z_)BPCA_mS^7aFF?=I+GMcHn6qK$!my1DpzX$}krqn618(1uw-<2+8`wb{4$UXe7|r zfE+c+$O9+NQ+JSalF?Xb$Af{AljbC&i9m+{eQHiI+6wfAIQLYegFx@VzK)t{bR-m3 zj{uwxuvmz_b&V!@k zZ#5%8?J^b^!-TdJwE3zW5Y;|{kYAuy8^eVbJ^*5(XSFd>!23|)W^=W1zCiB*+GwsZ z#t2k$F2zKQ5`o^9Hr-;373evEHXGvvng>otZ8gS=MZJIu09_)qS*3xJR-SFf1c6S5 zM+8b*d$t>w33&F{KuJ45mkYEIv80c&wgWtK)t%L;C|yq zfzDn;_u6l)7ie5ITuSC^ zhM|SKJRcf|1Zn|j6-G#d(GX!co{|MqxN%p(GxhtTqcS=W3*pxvlqk0;%H zUZD1%ZSZ87uL$(UIEu+N-w~(~v)Tqv6Z2hx9u!(L^Fx6e4kOJnKN2Wi6m4&QC6Emp zt_^#7m|qLH8sJei(ELWAMG$&aooiMJ^vEPcHqS+--$Rq0JD$~FWabK#gic%Qxx~y9 zsNc{)$vfudX1+jU0j>31ZZ;F>O2}O0nQS%}Xb_C6u|)TLOj62|`=cjs?rj83IiNG+!+= z=L+;7phR<#d9^@$0R7@wWR?lE5m0yYdUL5jtLKz0+Gs8}!^;G;0d6+8nAeHk2d*ny z1kX1&dOS_)DFYvpA#|I^16y2-^ae z^B(h{&^loYQlO5Qm0^HN-BqmAF5@Bd!8q1OYd}ZMN8)HtnvaW^33zE$pq??G7U&*a z5Gqj5na>C`2obtKyK+VrvciLiDP)=$k(1=4N$-27ai zpRp|}P+yu~3e-?q@uT^pKz^z4ck_=ps0x2omo*F!TX;OF2{DT%dTJ+l!XO@z>XSX` z!ukm8QGhQXX9~nSD%i<*vIQy>)qI{jfoe(hjXW*mgcf+t5}IyOk*8Q7-J~|2E&^ef z2AOAhx&gxcr`y!t(_M(Oq!ryf0|eS8tbIJg1zJ{%1^anM2y{v~2Y5yabb%;3!ZTi= zhhzzGt2~DUxqgHb0$nbaxyAEX!eV&I2E6DkP`foO;pFcmsAUt zcG2^OS3NT2a?`8c?4RcGszXhi<8P;>xBMmnuaS4P=;2kbuIvP!%F@ApuR4+07MR)X zJ0LZh6eDdZ>4DWjuUGA!@O3S(+IC%c;LY;z06aceJOb%QtxJ-;YG&tINH6U;7wNqG zYmv6wHy+fV_fAB5YVTyE>WXPdCoT*k9o#PuN|c{Z6)!uV3N^f_8B$$MNqZad?T+H4b|qU=LEzX>N8YUb2ylMLm#ycb058qF%Z^k!R!1SziDXd5lQ zHJj-@Lzr&ZQCi!px}Qhthb@WuqsKCcyXf{9X6N7)z>sRF2a0b*l>>J?kBR2@2-EUq z8$i8(+w(@)t2(Wr?oY2_;m`B`#QT}S9d85qot}>Yv#}}h9l(lrBBIuW?aX(-g!qvQ znZINRm3I1UO+_gm@wc^L`bJx(uZV<7k@kEaHZ18z;{VOM!m8PwEc|~LYjo3FDK(0@ zr4BA-YknL^`_;OM>CQ{*Hb_^quGrZlT@9BsQPOfrGbCLl=_EnP87Y4 zEIfexd%NyK>TC-&^QyIzsp6)ysr3O#R}W`?*Mi5vvpa|R<2$}VSAMzjMVPw%aH^HO zoN4~8#OF>c>(Nfl8Fvl-*5rS{;}stKamX;3yu##F@fBack$4LI?-f%yLmgak9OAx` zidl`JMoc>a%#WQFnO<_KE)MxwNlY#WJqz_6@kA-=?Dl9#!9cu4g zA3$_U{x=CD%lqel+C!&?Iz06&o$~Y&TH=Y)pMhCB;&({s zC6=!0@EHE!tvWl-p|k^LOro0%Xvg$|^$XGW+V$d{@$8OfPnfZJD$*4qq0veLTi`eN*<+QKl-!&A~P$nu9J3S#C@y@C-z`tv8OwAliX;+6Q@bNhu&`=8}(@mD& za4DE}?qOWhX{-K>?f3U%+O!oTe>X|blk}2S6!+jLrbidBvz|(4I#s&hwINjEIs_|2 zU0BL=prn%}{dHKFRXz?EGt^kbWJA3vUOHhNyW_1cvS5Qxeo+1leIn`~S-3q2Ifq3(an;CZ0`d{qCa_(4ZZD!3(O(Gp(^wN!#@+s&LomhES$ z4_Yw2Xb`Qd1NnD?Ikbd|PT0=0_oDlHgc;+=`al5(#x+($RIFQkREEt7Nnb8ufl8TR z{)AO9Ba9=av81yWEkN0w;{RKuQ+nUY&T1_a^tWQOLb2B8>!?tF8B^bN!2A++Cz1m) zr@d1^@&uT-otlux82+_jvSB)0w&~6)XG!{(OfX4e_KC|`YUnxFCgD%8iIHcEMekf! zw*iLPFqZwJ7Zu9D_)1sHMRH$B!*lWQs&Nx3VxRQui(RirYqW1`zg@6&9Waw`XBt_w z5$P~-uA>WC>ggLksaLEuWO?UzPFl;qBx+hAxA(1oLTFdUTbb z&X($@663uh<9Xx4@-4Y{pt4gFnJ$$PF)P5n|9-1f*`8^M*yEBQRp}!U(Aim#=T(oN z$Mh{pFAOl>Ski7t4b`g4osjulE5v`iuU&Zvz?(A6T6Lj6uR+{~2T0N;=DmQpQdXbN{?pE5 zu+2@kzY)gc$~)fe=~IsndZ=rb%DCS4WT|hjW8mDj`h8S$sidJ+Um`!JA6ws5)SA?o zt?$y74YHtS6pbS91+> z=45l`q@t%EJ>|qtFnYfDcq_xvQ-usTt8e)cjZBpYyAaEh=ARnMh*{*0fR^|Z?gH#*0Y`=rmtSF(2CAQ@(@IxWfmwZfzUBXna zr(4PB_%e^xYstS#S<1&{EJ%R=_ZJa=iHM&>#Cj2NYA7qvlgH=VC?bC4pDUs_wP7m{ zmQdWk_cK4T9n*I!IDv8a8ETTGUk@>QVGSthys5+=Vw1v%M5!PQmB}|_4ws1EFRKU4 zN0M6CG2d0vDM&|_*FBGgZxBJpgy#aGdPPnb$Z4l?7d7aG_KElWON_6Zq31olb=lC0 zO$zss$ut?u?P$2rb64R;l55GVwP7S3r$83hg)8zQx?gAZ>-n9@)2Z{H+3D)g+~&YH z+R&<3C)Iop*ZEJirB(J^kb;5T4NF-=-4BeRM$6iwic3B36=8|JA=O6EE6O->l{?c&1dG;-`vLlc}zr z=r6}^2^aLHa9#QN$S{F!yUBE^q|Ie!dq{@d(M@cDUa57!^y*d3C0%ov`H_v8u8{PI zV0K9Qh-_V6&tjT$X&Y1v_tCroDH zE)dZ~S->|@cR+L#H52{XNli@e)60if?gL?iOMCr)q`i4umDTpZz4kumaAqb!1pz@( zK{3IZ#2lCvQ*y`wOAAe$aYoU{qlluWk|Rpy9601$+2EBza;z-7#Z60!9Lif-mQq&l zT5CVZ;r{OL{ruj~%O9KPyVu%l?djQjKl_}sp8;6yqkINq%;KF&={K|g8^gPf)tr_4n2B`p5W`4^xmQD2?nz;H zNtrugpzFI9l4=DGpI(&HAPnp0Gz?>`lUwT2I>(sn|C;HbUXwj*E|5~OQ=wO;H2g5Yy0t^RuEynPQ7u7*+hTMA(>FXuqf?f1n z=cY-`r<(g9KQ-))&(!d~jLCbElf8stuydY)O0XI8o-SU&Fw(J?O5;gkcS+$23&kfo zj&W)Jp_c}iW&GIny}cY`tdq~`(z=ZPw}!*Lneq zmrw6;p*o`t!^!+7`nQ?0y@b#Pgz!TStezhb)BoBRJ4nCsA&uVVPexI#BK z?sxVV82=p33)EF+U)oX#B5JqC9?s`8w*jfmw;k zyNBVktEXZctMTi5d(ETx;X7$W3*JqW)`%E2b&z%-!)lEX*`p4TjoP zhkFU!Z=}CaoX9tlaCYLm+z_w2+kjB~C3j}T z1w`gI!jD!y&?zgtjWohTB8|SamFkJxBjdvmAs-Xs2msR`kqK$BBFo9;mUttqVXA zj7M5hI_e1l@CB0#I%o8XZvx?MNp@XKZ;~1x46i>%q--{YQ;!JOe@(%=ox3nnk>#J6 zW>xQPFG@zMhTa0CbNb zs(=I7*v()L({+J__dncjuT-ZsC=t!zK_^9Hk($GySSGIgaJa+72_YQP9(R`wW~!CV zuP0l^v;oA^&%}qr(B71;0-6k)Y13N5VTINcz1ztscvF#ON5p+&6r9mjZ){3$8-+g| zQ3>(0NJCp#$y5$LJ0qYSv`whXOgrez86Yh znh}i)gIE4N#=s4Yl+tAAY-wphjDqw!&c}UmO@$=u>(#OG1 zEOgv9+-wVogq7ktde9WX8rWcGFL=M%!ihXi0kqg>)DvXbZ zp+l7H+gH=EhfdXr2DU`#`ZUcysJb-&<@h9+F^p7IizY)}JvyWaGqX2789rum@lcu! zcNDReWZV%~4yi6uz(7Bt#;lS1J`lpBJoJSKB29PL7v|Ix7AZo9hvNG}36m;sU#Mns z!AH^QZTrE{4CR8#^d!t+QZD+#d_`#G_4xj?UZ0QKi|ScpgOQBKLs zKv>J9%nX9!di1U$H2O~bAUIb~cDWvPeU@w%Hm;gq5;O=xM-k=2mz&b4Nv><{+I;F258%3^JKq7SHjYBW-3< z4u`?(I?)6_98T#(v;S}i8c#MWpo>;;I&e62WXy-%qXhowe!osn=3k8;0gj2J>Vhnk zWx!3HRxov(q|DF)BLf;wQAA@&21GEan#q8!OsXj|pbwJ^mI2Ox88A@Ct7b}=!K5aV z40xBR*38HCsMAz(n2*){eS8KaFsZu8fT=olAAbjBTbL?fRrj?r1J3BwrQoy{I1;Wg z=EHUTkl+~z&sL?Nih2g3@%`FV`X}>$i+=`EW-7`W<&iK7t}#^rm3}l#oTJiFb&rOf zI#FGWhNDcX5ToG?lM6B}&ID~VICGRyD*bcd&!kkJgYJqf9!>5WpMyl5PA>OLcn$_J zsbS|iC{{AKF)$Eiq4UUQJ`@d1vp)|}Oe&+9kdaHW>*6acV5SCZ8I{9Kc$KM2yfH8W zGT~4?nV8Q;vASC(WP&%7a-Rv`Eg+eiRx%-ohxJ;A)0k>K%&SLQ9;0gQO!%sv@J2nl z!<2`s{wQ?cc%gFm#>Gode2Ib`LxPZ$Fun3TgYkjdnN2NECbU=EYAG6uG3j1@p; z#=xgc%FI~!mPwfz3%8k+8N8KUfPWP{dW?m}I%ys8(m}Dy5I2c-wW-zIm83%h8 zyOnSp9Alx&^3(9{3FF{4Q@N$<*ftVx-aIl|ZiyIcZ#WLpn3Vf*uu#c((J~&^EMZN! z?^hzm!>FZ1Dl-!xi^&C7%@^ea$X?3xAB|V>2@_xe3soCVfI~X%eaZwApz$&?qgs0+ zjAL@aE?gx|ge$u2pN&%!aCj&nO&26|wRfEiKP)Fw?x(=LdNgAN&wn@rXzdzJfnA8T zs#D=yJ*sAMSzLuf@HW54RAC8Q)xXhH=(v*7sVbccqnMP#sgPBVikPUl8EB=1NCTH; zaN*V1sqixk)!;c5j4vvqGzw%xM&B`HzN=88D!b5~>QG0f$~vX08sLk}v~q>f{(SD`6(|SW7bH za2BL6x!}BIe!?sm?IxQI`ApZX>Av@kv!Ph0S?!44P^4LBcV3Y&8{T1bS$zC|X*3&p z(klg_!ZLs3TH9<$Vam6>m-Tu4Z2ZyyySGG+j)2*)PNy{+$>_&A-NA+SZ0NC`t?)fE z8}Mg!WD}kqQz>&`7gITCw9uXl9XBdr@R%6^bK!wbZN`*{d62n@WGYA zGm%Z4{}#h*kC5nOJ-W?Q0h3mK61W%)TWgJe5|{@LCY7}%&{Yw3w!(xZkfJnsWv~Qh z=tQ&O5_pA)XG2XcfeSj~bQqWq)l6zOTnZguA&074E`^fqim1yjh2ouxXvSL#mvy2U zZz)tWsjMx92TU~MZA@4S{<|risu^t=ZXyxVEWR~i8MM}^JUIfF2c4L3oq}0g25CwL z{WI`uI~tP^E)xgGX0QcgE|wv&OG z)LzTsvaUq)!g8?eB?D?+SOJZhRM}QQIFkzkaIb3xjAByr$qHEKmTo2NdX#SCO7x`d zInW_!C4}!&wmbRlOL!5c?k7^VS3wSwS~abLl}u`?Tm{$bX&Mhux?0&9rdli8>d~QE z(s1Ru3Mv(1?H^581vi=05VZV?bfWrR4RHramJh$+a&|SGIz;4xMPrGs zFsa&K4QCFsCT}6EhD(nKyZ&nUK_R+7k+2#bFx5ItI7$iCLS;3~V^U>W4S7szow6EM z)|2f~gf{-2gu^;Ugcq-v~82RW~LIEh9~} z)3gzue^1fvCIWx2x<;p=I0hGi<9%Hd$KWCe(uv04BGB&WNSjhckY7%!s!EGsHmaNcN_EkbL1SsO3 zPz=rLQSw<{`q5&f8dV3eumUm%RH4Im=hzGOhjZGcm2zfX7>7V5Nk%g+g~z>DYW zG#s%-K$M0IhAf^gffIVmz z;Lob@Pc_UgXvw6;&Rx)j$psCKq=`RMCI4ze1Mw3|sCFXuz<|q&S`Ul&DS`1!%IIF0 zUXRu&P0QPzJ;h$g{Y<5!j<^?=DYCp87XkaAM3>QBu@C(INt(FzPu*)DOkz|n_Q4#c z3X5|U$u{Yv%oOXS(v^R%9Mb)>4;)_*|%0h zuH7VYHnMv1S%LPpgSUV{>y$jobC{kqP~LGZ0dT@_hI_893n2)paazF?~0 z2cm;ec8#p44c~)sjj0eG*O~_>9)zY{w>$zt-zwRS6i;yk;+e=F&VNTB?GX~?)uY{tFf%cU zN8lJ!1%zVvIs%qzWt2X#I10PJQ$!ArLK%}P(os042(5HUJPKdvnwV`(V8ZK^P^lh+ zL-k19U>PRto_Gwrnbd7~4Bl5V?j^_JLOn9xRGEou@=CMgkiq1FPmbCX-+*IG%AfWo zTz11ZA^H|2+yG}v;}hS6k{^f)p>uFr;@eQI)9)`0PJ9>k|69pK%V!f$!Q~&Bc$=>r z9xy2v<&g0c$?`30_un^`!#16^?oYFqYj9J?QWTzs4tJF58z?*topn07d_rOcBKTyvd{%Efrw7OIFl^xdImIw4>E*OgHpr_5i~gj*UM9+B-U~>?iR2 zgpR+E&;{K$5`Dmw5C6hh{4D%S5m)zFFyCV{mbF?Nc^15N+O3&TGpLrb7ABs9HB4$O zIR_VXqS50Vbkcq$GwQZD2R(J7(d!&c)rrQ0^KeWjdR99RZGU6;oSE~`l}Qb==V4?$ z*&;>QgYpy4!|HmnO}}YmhFW_i3OC&+a#>~+tbY6=RO{3%rH#A@(GQfYdx{AzLat7Q z)1zZQgfmR}mY@~u5sW!X}QGb)H0_b_+G9>6kk3g4kR1hdro$WH7OX^PFF{vlF%Y2Xq zS)sj-&+r%h_|Z4D_EqyIf&YZ@h_z-uhq;Qd+KwlF4$GL-lKgX^lNKo5OPM9&3pj*Z zTD9pa;Y2<9j;Y-8`I47rBn4(3745vT~xx=dSt?79NmT|mzSYUUnb3Ed1ji~fG(5} zq7ptpVNWKPW%i+qNXwYi%~c88bfQO)N{I4M?pOLXY*`62n3Vf3VOc%;NfEmLH1SJ# zs7T`;{3V$1OMbPL_$72@+5qEAD^YbQKG;(yO)vd6@hUuIs(=n9eOq3GD64WGICn(L zZym2^|2sIWBW?YE2UqKnpHrzSS(|#)TM@eW zHSs$bz@&P~chK0YF5PtqV^X*1b?C@M9T6v>>yXA+4)pkW9Rj@T65fDtrgBJYY)`xa zliXxCVHQ(`WoGyvi8mov$zWZYNV*AElnkaOL&PnZ=tDLuV0!Y=XT%BGSJf+nyu$4(w>2FZNq%!&&T=AoHc>5;%B;ALu`0X2_rv_V- zYG7zXMLqq3l75E)_{dV*yboa*6W4_n^bjU8suDhgH{4YJgi}nagnz>OOdFs}gOZ>> z;f|i}U#nUr{Rz1NzHDMme_E=l;)@3$H0w&1NcL_M36%mu4gxsWb10eA9EtPD}izAY3q9K!N zCYxwoj}mlE`jE{g=IKNWR)^3wF{;np9O9i;WHcWSlpdSp5aviGzC}HSH`4}KmN+%Z zQzYng@zq&LULsegLFu_k-r|s3Iv;VO9$jFnfcJJTO7aoo=&K*pYEK;~Olly4+SEDp z7ZLR+R}nT-agx6%s3%*;b_QWJ4Gy3T!&xW=Tu+7KiL#VE~_BhDrTiPt+QGgOJe;!`G7`N5*P9__Isk0%Q|_o_$CQuOy!XG zQp#g!rhA>42+^}1U1m}ribRNqOfG0UUqEY-iC?QmoA67)O?>2}pIe}R7j)_VQ&Jl- zrY8wqus&ZVM~hr0VjSL%Pl#xy zJUBAK-t`IbVN#vL9^wl{+)O>h&}8L-nyH7#W5V?>t>=0%O71!pZ?tWm_7Nf-MEkxje} zTXw=%hpZf|`_nKtBgASQ$>9j`5|eT`QXHs9pEHre9?2s`HIr(zkzy#m*N2*rDtM$g z#-#ei7%^&SU6IC!LrgB{(Mn59enBi7UYoZPktGI=AX4tfi|Tr`DZ^cMnTayfKY6^k zr_+cXZRB{7HWOu7zOPR^pV(M5$iv#~K&J^WL zg>Z8AwB%VLY8=VR#g5qp$y%=1#^{2mmc_~Q#eggl=0o2drOAs#)ObbCXAURliPjUC zcs|G%J(d z;?86eszGT0lwy&9dtXGqZi)@qCg$iA zIwT@xy9m{1j`CI=Qg(@Qm$E{4)2m|tA|lm;UKMeRm6eO|UaMC{ADvPR@3krs(={DO znBHquD)M!jiNd|&5R_1m6E*1Bqyu8ci#-3ipftTiye86CDHjI(j@&`9WHphxw-1ROOv>RQ zaikvI(lu#)b4d8DQRzxTw;GR#O^PhGp6%ojabA}Vm^m=zi1-i*=Re$;p1IX{R9x1D zl`A6Ps0b}oX6S>L`dn#RTC?m9lRp2wFXn7k zIjwF&W`1N+)r}6fkc_HyL(2Oig-OXyi|6Xm1VxrUPrZ_IT1;nB89gm_=tRBbw0K7+ zt#jLX@gIne#pI#_oLQgBGh(Pt&t_ainxj)Wex3V__~K=yNuQvf6?3){<->@lcBh;Z z9bZxOS`cp0h>c9DdC!Xyo#KL0x}wlJy>W6z77N{FS{pK@O8V^XC! zFV5&h?$3*1+m*vD=<1M^Y|`_nDOYi{i3QRNRZA=MG9o#nnEQABs#Jsk|SG zJe{b#AByUoN|o~ck=VaW&o^fKBXOKbW&0!Xu98`{`0P*lNSxCNKT|~doJoE4>m%`t zPPmz)`F<>nyHzRrjw}%$i!Yd5aBbZ`QZ5P0t0cn@tw)|sxh$sYw7AdZlrKcPO~H4?6)}{_#hJMxrZTAygs+I5OzMMV?W#EHmhh^0My)b^g-I<;aR2vBMi)@e zuM%(WBh~9-5q_JzN}SS(zG+@1K4MZXz7f^+C~ZHxz@^CdDc^{ROzKmCZ^S*F=wqI5 z#IXaMZT^t!8=*xXBy_?3sOp_O3$u%=$YqRi}wX_l@6)bvo@|Lv)6z z!tzgi`bEuuP&!o?--%O98(>f3-zndTh*Kon0RH1VQg4XcIt4ayrrr`~%9QNp0cYwD zqUU>>!Y-LF1pHfMzNaYmdB4;j#X=@Eu-*|XnUupjVm;GhJZU;G^^Vx@Cc7(+>#|+8 z(A2x)G?TLOv$*7@`Lp=fdp!RwhEv8?sXq&!_sRWY*llf>`it<>>5ymF)O(^UlXCy7 z=%ve6Ilr|2Dh9d9eiI{gS)@nL)ZfG$onEpfr`{JI>y+#4m-;~5L&EuQG1$EZrPhd! z<>X%F^moydNjdyoq%tjr6d0cRyBPLJW`aM&45lifb-@=(i8(q=c{Kv*z-h8sWxeyt z=+uYexFYdBPErrWJ46}^=WTl&v0N8Emiq##nkzV=csDm4WnN4wYY#;eCY7~^BAjV4 ztdP?%U0XNJKSivY=AWXsuK5^#v;9voj7eLJ_jOpazr<9xgnx@%w}gL-C3?cgty=2e z;zgb28?{uB>)kYk+**%Hbj>(39yu(%KcFH}woOP;OnCoOwMjWqp`dD$GU7a`y5M&^ z$>N!+tb1O`PnEK-BCbR!pVDPihf-$fvTx?CM9qCVQ5{Nolu5al@?%}5k$Z#mzM!g` z+#BSei*@b|GMh=Yp+V*-V)q8QP?wQ=gIuP|s0j`7yiVlaAU|bNO=yr`Ght?E{xis% zjEiBma3&b!FFJK_I1`NWFP+wTIulIN`XOa)F}xtPR1fK+)B6Tzf>{RX^ap;W*CJc# zwAQgP)hgRDsXk+qT^|wN|2CPRt5Q4J2Z(`fVoF^X)R~qq;h@ z%ZZ=V)uCN3Wl~LOm#Y;~9co~g8+0L6qFrv&h17<2`IAmmiFSFPNwuL}`hBV#QWHAl zAf2cQ9Wwm0I`%3j4`ngWz&?&!WQVyN+cU?vf zJ>^54$f2h!|Gdtjr@Wwu9eT=7bs0JIlvi{a`SX-o(=Svdl0#3~ib-`7PZ`a$7+&OsWTa$vJMCUecv&t~DG?^^#k3n&bFKs<%Ahrs*T!(`CV4^a{d%YW0L)>%yn8 zBl^f+9?48d-jyn&RC-@IKqo4_uZ+7wGBsZK%3(~Zv-!%=inuO(SFF>mH*IHsV;ow2TZE+ePy*SBlitt_*In|a^FB!e_iLkffUzR#$$d1X;sAT8%S?m zM(!KP#@BfM!?(L)XKNrw=&Iztfqb4xxo;pB>N0ZgCr{}_?){|qH+Am)WLu^xYqM88 zg`e!Ch~4|iI9*2W{bT|X&VN;6_`Hj$esZm@O78vS7ADo&e)3f&)i345^ z8Na0xE(RK)0_8-eTFsfdj0UJcx%!dJgtVVY4Ny(wZJnsrn#iadWK&a}rin~uRGp@Y z?5~Kct%)3>%c$C#$WgkC`b-mfP$#OjCh`p?)o4xRWnD&%79{;{lEW&V;(}!LEh3l3 zb6k)V-?NZAO^~!IV)sGPTbGghAlX=#QJ)EtBXlD7LGpPfRWm_yVm+F}r0Ot8Uejgx z`JV|BK4erC6)fX^sLN@vO#6{@${7uoFEFWk3YJq8aYlpXEL}z!4VDXa8P!v;{75It zXt4a82{Wpp`(Sxb7g9xq$c{hNxet+>?$o&tk;j?TNFE~JRmAQ?WVtRQ_aX9vE~9!1 zkzRL|O>!S18!=Hm;rA6nWP4pm?wiVvI#D-iDsL#_k-Vw=Nte+IuBrS@myyG!5`I=L zXkcwB<8>m3O=Vvu)i0XLvAPWXX%H&M=|~PkWs_gn3_A>!%@uJ8LuG4SMh-(|M_on^ zL*;Cp$YH3|nAGhXDpxS6ei16yF)fBJ#;d7Xs4Uj8#B?<^OzzU@eQR}UGx_?XgeGV% zFEgoL5-$Djsq#{`!{wY`iPYT`F4r@uW(t=tE8;?g%U!yR3K6c!{ko9aDO~=f6O|%d z-e*#!2$zQ6$b~9JxO6Zr1~1bOn65dK(rh8yxoNhLU3JY5O!mYU@=2Y(vDy<`N^OFh zYAZQI7k2XqYt~AhVp2vUF?=Ss;E+jgVJ$+9B|jr9Eo^E?p0~O0Ch`8usZf3lwovbeC&%8Qn77FXI<%^kaL;v`L6*ApODKQ2~E&L?qX6o?J28uqAt`^j{2L-s5`x< zoX=Ecy|(qD>?xNh;%xVnD|H!VyQeJHWew-G>eEyHph)8`)KlJLR6U`me2U+sOrX=(7pf@|WiKW*=qAckMO+t&a)2(Q zx=57xegv+I$8xn7QWNDC9jPu7=|t|6Wu~RB^vTl2 zq)MMG3lwqbljRy+M(&g4CS67|j+QLH)REjL%Ws)fPe_(OF{w68mJgT~!#j@HKFQK( zCHG2}BArZ&!5g2IQe=uwIW|1gO-9&Ab1^*cB=+xRBdT8StqKsG})g?HCmb+ugl0`KRHn+a@bF<^i=-n$+(|f zrzvEI{p1#1NDlkSUAm0cH~r)doycK7`4f|>#D4Mt(_;7$E59Gw$FHI%;r$8=$J6z= zZWOlJKrv_V8~X0o8lAjHQ7ZgTC3jVIjlFp&89K?S+^@-kWT`=yw%OqAE%A8g`Yy5Y z=8&fE7>w7z$CtosJt_S;j6$z*l+3W1uH7^DYID;3nKhgBq3bq%yuA(3`AKhYBb+Pn z_Qpk8CvR^&rT0-ODbr*vi!*V^pKSKeqO^bUwdOUBz@MGbwScKDD6C%-b>)~cR-&~1 z^Q1FpLfv(({{M_2&G}1fZPwNz>EpGg{{2VW{HOc+iR)UiE?df+YJw6jy?ZHDSydRH ziT5J^2^hSBtHnL4!DMpg9&W;+U%-wX6qYrv3*8;KU(cC9I=358*gK1|NDZp0UBJP3 zidR|rF$d>=0e}0|MJ?eTtHKXUDZbV;nNUsR-X|#Qcmh{vYQ!o2)Eib}>tesbYpGu= z9pzYsgIACa#bf_hWmQW1o06cml;m=K9Gm0bu5#T1yCHQ_3U4!S}BFwW_E8G+J9vs^-dGrRJN%1^e$YtgoSi zL)>rORsSb9yzRq-a{yny|GY!Mm7V|Xxp@};`4 z_Qs=_s0C!YBUUmV2bb`lq0AuZyPTH#hlKM_lMeNO+R>h_v0m3uKiJ&vkyHcx-8(Ab zyE-2wsKy~kLgsKv@WwhyFc?DX z)4(!*er@WC>q;@onF{CZq*SUOJncTTYiO?SuB}@4=kUKmO`N*aR0Gad3tp|YSBVJiG$0>!IP>8Nl6HUy6U^shElO71c0+C7>3wQ{Bw zaO&D!TIZ(L{{OJ7>F)n$vi}+5-k(*;luk?%6+o?XRQ$W#8@6?)copLws(2M@>Yp;C zD)avm?%PJ)=YP{w*64P{x9#v_hI?UDJx%3WPwu{+l-$McSy8!GZj%3pW)I(u>!!#! zfBc;nRO9iX)i6_3;}lhmFOsd^=$tCsXm`OE?qc*^@WlU<@PD@W8C8GAxSvt=XN>z9 z<9@-{vj2i{zd%F$KMDV5i+dP%5997(+&zrDhjBG%uLk34&|VG3)nMH3XzzE7`yK85 zj&Z+Z+#k>k{(zYpUWDMqB>bO^-+{nKJ$$<|2%Lt+B>bN(1RiE8FizkRwgTe>#u-u1 zh;c^LGh&<(<4mY$!Z;J^nJ~_TaULQNJTT5fG{pat@PD>2W1Jb|%ot}D+9bTl7FJAb z#YihAwxXgH<9tLj@WD7A5rY3G;s0zAC|W}x#s!L&_aZwl-g>g|B7lm%NeVQ7OG4DoH+9Mg-h zhhgXs+Gvi-!LSLG$p-Vopi;hsyAoBBb|W0Hd0QvEreC{O$<4Uw;0IT7lkwG-S8$VI zyMdgY!0>4ZV$E=tM)7q=zD_qbnD2r(j!EE{NK=FP>);lK_OoOytU8EQ zGx$1_uP>QNI+0)bH<4fYm&#e60qr+e|zt8oT|X|de2ACF#*V!vhgse)zK=0f?qQbZ zbMIr!>&5pqeDye$CdNe76>A#2;!hcCqVFNbn&=SESW~-~9flY|KcGJhbi6_g>lXq^ ztKio1R)!qQl-AfNmdCrcHB=gNi#i$#EV)J94270o_9Pg#TfS?RYB(&?0tOpOE!}o` zio+<)Fq}aB=M7ppbY3>oP-@P=_b0mekjpYm@R@-c;$MafdR1><`itSLW&6?xhRfI) z?ZzwIF|!4|)-hYWy!jm7dh|laYSeFUynxl)9(CvrssgVbj~l}bzIc4eB}}PRo?&x_DO3n06NXo=~W0~cXxt|#dfsPBQ zg24-R8LKSCex(?HDCIMQOMJcjh%wA;+3^O3{~AeQKEC*7J7(oHI&R;x8o!O$~`h_;&uxS`Zo#OC&(`dYQdSqFL#C5}P9)?xWto<+y_rCV5 zN4E95&`b>NVHCc$YP?5|buzxL^C4z&k%tkpjxY1JzPc87gRLLzej8J*UU1Q)NXCSH z;!$87u#MWPh)rD_4#9^nz_n4F6lLMM|O$H+W%``HbigyUo9KfT+1cvnZ1iGmDUGims@7A(JJe^ zt2W~gU&uioJ6OpMs;mtc(m-U%Icd3TEtpwusj(W4<2N_C-=v`?{eYCh3=UUv7+~3S zaESFG-$&~-%vUGKv1SyFv99B+WTVm~Yqp@bq+W&&4QE-a;Ld_vYcV&_E-XzlzHOaS zWyy?=#W-^h>9!riZDUKU4wTxB$5>iqed)Cm)?;k*9Zprw@l~**@n!3FYwEEttuus1 z2`;c8UDC@~(`BE8JJu@e*D=3ZFL2^qHhP(LvgPF>yDeMN-HbX#KDNuOQw0Z>HL(TQ zmM#+zU@KY{YP*8Ppw76eV<%fRTe!^@a?t(@wj6md6Yn5fnU*opcAHJOBptLJX}gz` zDZ|WX@wG#RK(~-fe1Ip6yF{NkE?XhA8+=j5*k-NI$Ln=oYi+T%Lpen@m!NaFD?O^Z z?zG)w$Fa6yNk?riNoR1o1iekL5ORyY#BkHWZ!z4F904>QXg^@$Bh7zC)u#`26EU{s z;~(HPwOOjI#U`h{K+;`XAn8XDxA>=sMei}7LaZ) zv>e@*U?`FocMY@q7*Yn^H~JW+V|duQuJ{@IXxr7~Obn-GQMma)re?3PSchlXBdxw%nq97$yWCvlq&r`@e-@_yhrA20HZnA$Pjbwl3+J_DbXNQFl4~!(M9MGtTVL zs1lrxhk`oVS<9#)4IJ6x$AN7mE~Sbo?|a61ic;IPEkTZ3K)-M(wS9Ih%n@LjGQ6du zK+?(K+u`hXET8RwE8dY~YqolU{e&%fcRxp%A!KzMxgD-PF%ot5Y`$;Y4nBCO<94_+ zcPoYqpKB+#YjF3#^C<4UZYz$}zXwDB%}d#6nx@VIZivIS`0hI$WwsAX&xy0P;LuXX zCEJY!Cos&7I^n3aMK^oj5o?(-)&!*%`qc+bxF0!c3>^;QYYYuNv1bV54QwEq39mV7 zcqJi>c?0hot8Chkv394A;pvDpY=WEfeVn&!Lz*tkXR=9S`kE=t8o1cPvYH~8s2_>xUlSmtwlfkpZB~1=`G}{Feah0eJ-b{{3j@96}UwvQT9 z<)53|#4FZtZ&(DxT7JZ%w_M`V*tT8{-96n$acFIpHOziwM4lJjmfw11@wz#S>O+$* zLGOTzv=4dylrhKhRA1}?a!ZJxx63f3TU+l~d+_Y`c>Qd*Zr)X}xCt#NexB9KJJtU9 z5V{`emxS>>7o>To+h_Sbjp4D!Gre;Rbi3wojm8+}wzzLBvNf2$$vexQTeQVfae7GB}p>z`N8!KTysw&?($GT(Ve8p9D{zLi?M`8~C`az8!-x9I!dY$0d%= z-fAqh&^=WM3BgbJ#A=qaUE_Uf`0#BXu{C&vPmz7VaD0On8XAxB)Nvy1t5Z+m-O;`C zePg6`-sC)=?RLNRZDgtavttK+CSvto@R`9)=CXdCbj>H1Go8no4zRlp`1!i5H%qT! zCKl|8L48_f9kx#%|Ag;KiQn$S``+WlgM)p`?5&a~_!b%d9f4=Ba5*Xsx7wHbp0&>m zJ>+}Io;2_+--(hJXE+{|;q^?f4}42)zji9~rG?sg3|lq*%(qzny0+T4h7Y3I#r!g&78HKPSQrLlQzwS2$lahA3PO-?fO;S$;Ge&GRd?l;NmeWAMTOwbb@- zP!J9;ALCoYX+T})S7Qjr7kJhfzQPyX34Gq8CVOM#DPs*Enrk&K^E=^JWhh#I($8w- zrz`u%aTR!tni_-|sjo&F9e4|c8NVK4@{cu6%$aMpitA}M|1iVIXT1D#>|d4o`&-2& zjJagn)s}9&#+}1ZvlaG<8cW=QKa8D+Mzt9J7i**gGy*K2;@BR`F{S3<5ig4xd*9iQ8w2b^ zier3ki5odH{Dp(ED;#g)P;GTI?Z3(2N0b$8^Y?N12k!Q-=4QIh4RnvIx(c3{5dp&S zX-bI*aGXnd=wD#LayRT{q$8peG)yqdT87WR0S)Q#;Qfa9=-Ksr!*s`=>s_{9Mmklx z7iWl^ebI23WBcB!hQo{_hT~JdcqZp|!_kiGQFj{}u?Nhu1~?iFe(0ZNH)oj|W!tN# z`!reyExScP4bXc@?((Tdk#-NiQ$`2(m>eUYZsTGHhmE_Y_i0on<{yZF0wW#T?8iz4 zTsH-*ljGQQaB3r$qxH*k8x=ZyhiZ+2c+m9`nTt0!DsnjYywWHLQ{~_wJvm~LhmT0g zInk)paboewMu#1_MejG-?)dH4xkfcWr!wONt>Hn&WyU2NYZ}EE4i10a`-H=Du527* z@IQXrSmp?O%G$UT9h*#6yLidk_^jir_TG)DKjTni-!nF5 zm?rcW@S6I6IA|sH#Dn1NtkEYo#;X~&$0aftV?g)Id z-W!u&2%wlrs7VJU({*k@nBldxiv!9;z~qU>!^YtQ=#D!v_@agnM^)nsQQT=rKU1Z_ z)wI;N#!+?bpJ?uSpxIGrd@+tX=AC2n42O+$&~uIT{+jPmpAJF3#fKlCaO}WW7?&Bp zdetxRFgH^beD_4NK;hhz6cLziALrLLFab-Cul>V4lpJ{&uZLg^&5#`gb&@#U zNyqLEbJjdPJgA%>74q1Gk60KyIVj6%E1VuwWxp7=ASle#D&nOe;T$nMA~46<)^Af# z9%snPdrD_*)vL4pT+XR2b_TheZCivnT+S{nN`h{|w&nYSRvNJX(|YE?ps#`ooq$8o zIxbl;J1b^GyEtY)$Iu+nJGjXC>aZ!n`&oL7OId1bvAZxh6*rsk8QGH1>|n4k(uU1; z=hl$p!7-ebSPn~_lgC#EU*fZ5!wjP|-1!mKbq#L>+-SM$%wPXp$X#dIit!;h9Q8jZYMc#Xaj9Z+?!woUdXC>aJtV;K-A)>Ca*O6+ zTJMNF3_mV48xG?~6P?8^=ZNQBXy?V%c4rm5(nx^SlX`&FGbs!Qc+at`=W6(``>MHS zAJ2edNU(W$m&&aYd)*tEyjl%sql8y(hICo;=^$@AbdY4!kz zZ_9`NR{MZE@s=;kZfJ{BPVPUxfSVcs^hr_87w^%wm*=^A!!iZx5Xtp5s|K_Jsi2 z2R{nQRVsXR$sQb<+((QnrqIoX7N5}>9h#AWRiG1&Lz&>C6m{S zxAB?|gS=#-Ga$?0Wqh8c)y}UiE^$^WP2C>D^$+mjil(-BeaTS08MESXdOt2ZJ#OI% z=ECD%DsI!^ms{|;z~dR5I|4k^ha9(3H5^bq>7Ycb2OW@T<&R*5`LzL<%yY=zO)bMb zc&X_~ezv4#tjECh$6FSde1C5TRa$Of*D)~ zSnd=@tBEYlW$9s$4+BEAR);+ThquDe5Es)bmsN$=7jt7<`Iw%-kDf<+(0PPDqVwd; zR#vZ86SGtCr@-Ve<__0-$;p27pTaEUh0}-nX&Th7dmE5jY zkrHh45AZsb-z8$S2c3bKV?Pp@77^?9T%REkKH_w6Rz$kj?zG7f!g;JDB5*WkWt}lK zpxSqsSJJd?m}*}7LDYP5^0yILUejDRBZ|2uc4=G{E{|FHrpR4f`T~y+OWMgQ+*YAU z#ju4!*K`WM8cg91bWr5+L7H9L4yqR?YN{K&{`ukxW`{yAQjl8+)QZMF_y zMizRE!*>WDwpsB;Ed$4v8HD{V6xopAUFZR_OQkwsqV;SsRiD|Ernkv`&R z@Po)wubzc}qH1Uoss6s%qjiyU%P`;81s;3%%r(=)bCcGk9viW96?(12OyqcVnAWCs zmA!wT*w&Rc@mRmsMO+Nh9M(F=>tE0I2q}ZlqHtC1^;b@2>q4(VL(Yi;+o#&95d2JI zS|6N*EFA~o$_GE2nbLZ+SD%Dgt;=9`>O2hRzP1oe_!cf{U1eBMk|_(hdds{byT07I z%xi1NE)0isds&?Dpe5IS?uM7_*#|GR-fyIRq5WLd$GE27;Xbk7NNe9?Sl`(H%XxSy z=OJZ3xAz4jeHL(;RRio(Hg#-M=8>`@qs=9cf8ZMCiXQJeFt^QJk815jl*YaGa+_)+ zO+sZJz8&V8X+V3w%{|t1S);q&Z1a$>OKmgu1V)|kpaU9DP%&`-k4sbIL64PX5WS#j z)Ge>d1>sRO9!u~cp~i!@Uu!&OKXcnyg#PCJQ_Mo z^w1e#pbe=2!%OJ0%$epN`dF;F3hOV{d39RF!uF9XA(X=#6KW2N={Ccxwe12Cw_vRv;Rpxd5Ky zZ}FRSV(@whrp+Ag6&Pdqu=KVu#?S~KY6A>KBPr%yvr61^4Av&J#)r;nFVY5Nrvtf< zrJI$@gU^x!dbN#JEWqu!N?Yuh4<8$5{&8p}hA-l$0O@)b_hLHCOgHrC}-QWWv$r zUaqyaAl@zuFwl-@3@#A}%V^V76U6%&SIm5NZT*aDF> ztx5YxYk1ZeQ=w>B6xrToy;wM)J#AlSwGZdo3g;SfVZ#|a6bYX`jXG3nxWyRR!Ns>$ zn0YU4#FhUxtBp}jvuv~Yx3us z!%bAx3FsyVfAh4gBkd=;4!nk%%jUk-;WiI(w|R&QGf%~sa1#}*(5wl32ukRtz; z@Ts9cPB1u@9K@LMz173$yB!PVfsI~)h4LB}Bg}lCHGhx0*fHC9s_Q2mT_R7zqXDhB zyZ5?xoayZ@l!^8`@sk_#uBRXR$8jFR%pXKhCVuaG+Zcxxh+FCAr5QLHTAaiG!1zI( z>DHQ+al|tYTi0$(ZH4N)WqKQgJ&FcBB|Deatd(P*5-p}Vn_jmvIfBn{d?X@p6 zd(R!7W_4fKx0CY*M;o{HYF1;Yk@tnYddHpJqK$`9(nXfrw>^gbUU`Qs#E#xEx9tnt zb%#FKCx4cgB~!nCZmHe4)4JX$-w^2IKj-6EO0(X{ux~nNbz4t6s*lUpHEt*U6w?RE z|G?E|-D_`nh7{U1&f7U;H~%2n8M&L){0XPkMtLmQZj`T?+isNarQ2?l7nJu?J+@PF zyV>~23qy9Z&HXM9nQP11_Un+%^b@ycK4}WB6^-})**0{Ib<6TCUGvc@qgfHPioAL6 z8oJ1IEDOh5+nw|6eLUNZt=J=X8`EoN4n0CshrDK6F!ZEx@tS2reYTdBe*$Y~K07qd z+`8n&p|!RPxtJx*4GUf!T1Ew0W1BJduh7d6D^D8b_dXE!so#fQF-8`mC2XO$8xpRN zf3s~+VQ4~}`O5|N1ScJwoSu-frH>dF2Wy6e90|2J*bGhBY0JGQEB*-8^`sFW6(k&? zHqiLX{qIU}T1JiJk8o?TmIA|2~Ear{rw3ijZz~o)*go~KQUcSnmF^` z6>Abcw+-s}e8LnlKJujmANNFU_=q=Ay_<~k4RuWvInF#I>c10?*bEDICScyiF4ts~ z2NlisE#~dbwgWQ`C!DmUO*)w%KdSl>iGGm$JhGQ}H@HcT3~r+P#3uQUG;X4ob=j`Y z8seEjxHK(R6*{pT^RU^Kd&t^Gv;% zRA_j5$mOK%>dIxfh*K)#ZSp<;lhx$$bPM7j73dfh=ol5~6nUCGc#i+1Olnv^SAzgJeJEYkYjy&9WTxyiA~}-xCK<$ zR?&W#fo&5PVef>kuzkcsM1$IXn2BYptw`-*^(r(g;IXq>RTg~}sIYbLAQrKS*s8Yo zz@-_aG{PXIks#_sp26gCl4m$P3Y$Xy2gvUx|6KAfBmWBW*OGq?`OktTb`2gYGlX#{{17R}Pw z&)K)K5$xjRek_!!!}_uI>~G`yu`X;c*pvMo?90xNA5O|NHVB$D{Mfl+l8fC9JC8hh zED^SsJbv={$>V1e+4xCyP2LmQ$mUIY zk8FoEhb5+atunM{m{hvLq`jwIBRe-K%|_|i8rcK)rr9sTpN3!TP=_@V(>gS=PwsVh z_}IgK&(6cfl>2-gK8Edx$YEva4d7qXQ#;D!Ty2yEb={J~*gdJ8a#;F3-cB;Ku8lI( zAK8ewXoIc)Vk8@kBq)pwyH5*tAeq+O-U(KUx1y{9MHX+#$> zkLV}vAvO|4l#JDrm`2Pa`iUEedx(uh(T#FxqbzPuX?upHkt>hrCvG6_AvO|4cgl>I zM$9Ani5rM}h>b+yAU!dSm`C&zHxTy_J&m*y(G-E0N=zf>5&gss#684DqUb@fh^fRh zVjj^?+(6tzY$S@F6pNVVp;aEyPuxIkB#Ic464QuzL_cu@u|6h;bGev4L1m+(T?=qwFo#ODb6}X?uI+u%|QX$Wuoi*R471 zc!vC~`W~67y`|FCMyaodzaY~am%}z^*2l@vhBn@fr<;a3`sA?YOjjQ&3hZ068p!tb zlQoDQa0Z&;#JYhw%$4Q1T`E)CC^K*kl^!-Khdq~-I*LL^Nq@uGUx$<%3(vZUB%MlDyG5}V^{ZNvyvPZ$WASxfFS3E z$_PZ)0*XwmCpHk-Lg{x9Q-k&*=}9Hl5$lN!MD_^jiK#>v(Nj;W1|oZuM8wpfy@V1a z))DK84Mg@B>4~XC7qOn$Kn%{X4w`3Ei7uj-Snr`#1CeNBPB7F zSXVAR^+bnX+Nner(Mzl&))O0usTGv5t3pQb66=Wd#0Da(l%X!7msm%vCpH8<)s#Ka zv6QkWx`xrq4Q^v%4Vgr%YNWX)aN^}vu#0DZ;P8wn= z(M9wU>xc~?=6|+=q{LLBi|8fR5gUl?2~rYMiLRjMzob8vSVycUHW1m96pPsKCuy^% zBwdo8VP4v(Bi0ieh~B5AsE*h`WV-Y?h^a&uk*y{_(Mzl&))O0uY>m{U5?#bPqNko# z4Mg?~B}DW-EA2WWTT6aoD$zys66=WdM8`VHhUg-CiFL$!VgoVtIjMAcXyql=5$l6? zoeZugvh|cbF_q{ddWm(!dLny)l*Ck`i|8eOj%TG}cs^gi>-l^98*WzGDS@RMl^zP- z@!C9eQo;iXTNB<*_&6clndNjjXF8WU1I|6pkDX1<&WVo1eu*Oz$0lYc<|Xb<{5bK8 z#BUNWCK{9MNtsDSNu@~-CwY^qlHN>uH)(Iu*`(i+LX&$Y$0ZL>9-TZfIXAf=`LX0@ zl6NKVN&Y1{G{v6MDJ3RlP>M6<&XkcUQ&aMcDKk?7DZ5evj+d2e?)j9x#17)3;1GL- zeTCo5Jd7W_Ji=aM$M8dLr||oWXV@F8nZ3zc*kAB`+FN)Y?QJ}N_6|Mnl91br?@)9c3~67>ng6@URtr zE{uQY!P8Wy@cxTeM~%San%TVCT=X82yB5PncYyDVUPLwy18iFdOyz9G${M-RF;mv>v00e4*ggtaOMPFm zK_(X(C0R`M8+(tm|29M>U7sxNU^dzl|LV!8!8FF)on*=xHJC4$`%dhbus4BkQ{0T2 z*KkaL>kSHc3w&pbY>&SZGivJLDM7Y)8#$@UA}x3vmwiH&06Y@OsH1cVaMl*tJ)K4Rr~@Rc+Xa#;qe3mo_5Qj@#TY4 zNR$f(JsC9xij?g7J7<&M|s zahc1tWs?2Ke$X?a62T8nr~$WXk{LC%H|#I7M`r)b>qbF~QI?xCD1Gj~ZtzNz*% z5`ywS+5fC@V8Cn2W#Jhk(m8HPhzxL?$O5y(L@-xO0*l0bV6m72E)Y53V(|dDMC5|i z!VT&o4}4P;fPWFw!2_ZY{8Y>WzY@jZVNn8}6?4I##60k4F(16_5eu>UO)LVL`Y0Hp zE&)xd2aLq$O$zIx`oSJ*B^aYtgMIO_kHX^B8gRI}0!&l?3mm7`g5%YvzMUZ04`Bq1U>4@;IsI2N!~en6%43b!JX=#!S~ed z;0O3k8q`wV0e-3mzy@_E_?`M!uu0too>Bh>Uch%(6?RG81DXu)gBHVwpv|xkv>QJ5 z@WJdk{-ZLLolt(n+geV8r`QZ*Bo4SUja|SZV-z^s*d3f>j0Q`MJ;5?#EDp#kp*+K$ zhVl%1#@H8J3*{O19F%8RoiQGK0m^3f5|qts6O_$t3({<6uR-Z)X4@cbX0IdBX7&c8 zE$kqqE$k~uTi8(~+QN=O+QLpi*}@u-Xbbxe$_wlVC@-+nP+nloNb~|b2jvBJ9?A>s z0@A#|E~>RM@D3=iupv-hVF{*qFcHeDY#5YRSt^uQ*ehY zO2*5PJswbmlJP1i8DEO*8Gjr~&Yysi^CzL?d?m8y{AnmTU+saE^JkDf=W8KV`Ad+h zd=sQ9--1L{{u-nz-v*`1Uq_-Ue*;Pb{|l4`{uY!5{tgl~@Omf>{9Pyw{5_;;;2%I4 z!assCgztwEr(7X7q}}-okjC)0AdTT~ zLmI>D%~9aHkjC)$AdTT4piVJ-FO;!-Ka{cj6DVW(7f{CXgHXouub_|luoJ6d{z zoh-39Pwon3Jnsf&Ja<_7gFT>(=P^*m^In#LU~fy{^?-6e_iP{9DPe9xZNg&b)WoZa zwEg-pD^? zR&aeYPvd1Se~9a02UCU)mQMM?9w80-tK2GACs-)^7E1%(o^TS&cUT(nx`R`!6MpbF z8o$9C&Hm1AWvAHyJW)S@{fOlZmS!wx*&ucf%THL&V`;&10n0_)mA-_RAGESm_A~Zz z_766WUB+?+3-)&G!RdHfHiP|&cqS8AR4fK8Av_CXegZS`$r#aY zX5rIVC@;nnw)0pRuVUd?+F`L_(Rekp^L4B}e~xwF8(9RFjvn9^ES<1KV(E;f3*W-J z@&LwYfOX?4T*&mfNtz<5H?0 zE~Dh1%8ugcOSx{IwTx}x>sc$`%v2?C?JZ@SlK+4@D`6GSYPXqPOIXho=PGV;Zf3J! zPsRERr)Fq$#;fj5TdhsjN$RBb7p;@pw_5e2R_ohIzhk**b#!U9rYE;rrzEF`Wwpz| zGD&T+=7!Bl$-`0@wml_ac}Iy|H~9jme^l;MoK*OX zX)_D*%5u}(W$t-pNMS}ndf~izg@|--LFu&I@$UJv^Je@@XdvmV@&Xs5-Nk{g&nf9$ z4H>2R1*L(gQ1NYud4hX(eo67j{OS77ns~sHUofw%aJIXwuq2Rf7f*(Sj4CWe7J;uj ziD|}mBjy(trv#+T%|%L1$K5({`Nx-EC) z?EK7iMUL6S>BA?8-)#4Vf6gj zXw2CY3(Ba$X>jN~Q=CwWN&;VH3KtLiLyW+n31TH)F%x)avRG{h%Pw7%h9ZnEDw&4L zWIZVE3ok3on>8=HrL*~@9sy-KrO68L zZIheQDuefW!5w#FBah8Rq(V3gP{Mx5d=zaJqF~dpg-#?z0k-pCI}kb>3ts4g*kx_8 zSgdaQP;~MPheu|Shr+U+_aNhR=w#azq8J5ew-Q{fx{;$y4X;!hBwIwr2v)KL%`gMH zKgP;MnTpsVq#?`1k}^@+5;haMJj4yAoQsbi-HHF#q*&wxM3u#pU3XJa^slyy9{sxK z!!L^>vyufXgnBlTEoEr*82JFA|bGFt8lA<-miw3NV(kH z12+#2Hu(QVeHWE1kFj>LSu?RLga_~P9Qe;vrpZjxsHJ5$|Hq7-|BUj#i*Y0KU_XZj z$FUp_MS+M9#NF~uQMOlhU%FHO?4A|hXYU(izCTW%^PyDYLYGdK{9+6>D`nJ8e{*2buePSk$*Gu+^ z2)wDR;9z!dlPt_mGS5nLm;UVmF+KEs zY44Lbpl5v|I)!|0LYjy4l263s`;M4HBJAGnC;^8zXh`XCHAM3nB+N>PB0VQ%!oDzR zeov+*%_cG{kFvaA({Q0T!hd^R?OR29WOSFtkD*6A{p zb6<)++^t6*6hq8T6Hf9lQquLw2Sq>hfAvAp%eY9ZTw<^E1>QI)jwpPM{>0bf*4P)R zHCtr4Hyh-*Rjdwy{I=2{R%B@9cKztrVp#YNSr~?z`nGD7JM>I* zQ*UNcPMrqGcwr!Rgw0pD0@|O+g6lStBQp%R)JgZdIAF~PES1{ z9PtA~9oVe~%ED9)4i>L`U?@7RQZ|KF<%Df7k8f*_6(_`$xDjdp?`ZyTo}=6#2o3X zwa+!lK|2>Fb~tIcF|DEx;h>ab+ZjXbzQuC%1}ARlQ3iXpL2v(q7#edUZCOZ@oU58- zWw1iwtL02pt?9FW5UJS7|NMiP*CWp2z>z}E7v5GgwIK`zGp}4JidG%3-}QHqZE?zd z9urixQ-9&_A~ke4_AaZv{C#`%aQ*DxMZdoOD`7@6B6url*TTrrs>hlg21Uc~ETXi` zV6Tp_mv7gq)AdoO#btg-zq3i)#s>t7ngr*3iaz^C+>mtZ-~A~1SmZ>uM3%Nd?|4Rx z=7su$XT%s&G4)J!vHsc_kz-0Qbu^mo70J5REQaz_eQdM1Po>FcW3zb4I9E;x)${eN zv*M_lZm(XV_dh2#M^}=2S*SzEE}AO~Y%(hLiZN(0nPaVf<(x>soOAn6Vvtf{(5L?- zitsuYw8e`ue6xPyClRlqgwN;hVu zkja(^dv%Mjq9E2tnIXz5j0_1t&1YxYKQw`wgv1ogKd5zV{Hf@309Cd{QqqpS*YH)wrZ!_jLPX%te7 zom)=c$kC|E30+aFM$7=qmqJnyd@vVVpB+{xx#8p@B7qm==Ijd$wH_RP3-@bs!OF@ zgz}?6yQ~g_tQ-C-CPfy_|0`@7gj=N0AB8rv3T5OGZ~Bm`>D)-GbQol^>dC&ADorGw!MxF8LPq&-07C? z40i}5*FtTybf<1s)E-^7P#W8eMg!`v1Pk>Z`S$9g6gAGXk2dzpN_x+e{h7rW0x?<@ zhf_KYM~B(4Gx?6l|2T$);}AyDQz%jS4%tk;L*zIuo89hvfHs=jit5WW1*aWfru0`Z zqC9i(ZqG#147eUVfC6m94zfhPyU6ZD_879e5@Rq0RxZJL7Bce%5BXCl;4XcbP@NiRjTi;+9kz|IxM5xi|gXe|X#Z!jUP`iIexK_C)1ZOj-IEfZZ`j5-1 zRZhVuY-X4JzA}W(rwFp8;vFx=9i_dTnV#T zI3`6oJ1%Y2ovJ#>_J$dIfSZnu$gCnoU#zOb)LQ~sPJO4UR`HdARD-&j$K%WvdkrN1 zY}pB1TA30Lo8%SA3T|J7Ew4OE`MpmY(bLN<2#{xkz7#pUe1#HH$IhD2z-RdV=R zt=m5DX3+lT|VvO8$=-W(ccdhr0nzYKARotdGnABT3-f`Vs?vMxDa=Px#)Wghb z3ZJ9jZB}~>_ey!ib)Bz}8s-i-{lChPwbo!m;t+t{N4n)iQc))@m&BaFMzeYk*RNRA z@<4g0x>*dPiOSz1=UYUh{l|X?o!R-%+UPpPpDhE?(Q-8UGlLtMv~j7NMFQ|Nbsx-{c!NWY659b|$I* z!zYR@P}W(EQ61hY&Sp+1ET(&c{r+%Iub>Qf0rlNo)r?y@%G-wjdOxtBOnUn|MQ%=o85qZfA62qhjZtYIdkUBnKN_e-n}XRwRZW- zwKuNrH}>a+rTsf^H>OPy^i2bt4jj5QUH#6EP%UQ;;>N<59r z_MlMZTJ2D-((y{U3(CpyUW=l40)TRv-if#d?yA@o*T%T9^6j{XV+^BmbMhp^$gTKq ztvR)F4P~Sxu9HjBy4=cnwa1%~cs;d|*={5Bx?PUIy-=!5m!DVfN$NvCoi@S$3R^ox zYLZQ@Xqk~=+*@&3Mt(=BvYpJ@QB^j8;J*o=Y#&rgPwqyc%C(+7c@2z$@_iL|W~4h= zzhZEHaa=-daUol*_%_1|lInjSV(C?m#JJ*)rgfIe?y0G41C@Os%E)n5xi*pVAt+WI zrHTS+FiH2y|FKq<6knVZ?iWe^PXJ0k1qh@^ge$gWrf3^Jqs+g^&WP%sP(LR%^Frzu zq`y zX~keq4n}0Q$5U5)_Z@3}&ssUCWxb42acz3{PES^$Nc=#F9|6kt*YxU5^x;on6qN6; z_{7to{bmptB?lmfUh!i386e*OK+2{_l$d@-i1%lkT+t;f(>PFZRaX6A1(p5^y7#w8 z9WUd?^fPd(jLa$nA&?fv|{6xR?ZVOWe!ASo~V5F%D#@cV_Na)%0`3t8MRJp>|eT>&nn&>GAZY^u!>iu znP;h@n>6!U<>;Z`89A@l6nKsTy+q*kib+=$=DbmpeIP2f7>)w{A#9?~(P4Ar(_b&hGkl&AR_!U2Q%& zR%@j0vUh6Ayhxe;(t~#@Q%7wz;@$=Yga2*i;nC~3pmiFX78CceCjO^l#DwzruQc+T zS^43FgAVtPK;14g@P}Cun$kDt92zjKSqSTdSpQAX?A-`}eDaf{@{cJmBsAiRxvL;6 zCC2*#d$C^vPiS>O8wTNZxfP%Lo*i5jHuXFTRjyyqPALWkgHDcx)xOBAa-|v|W8mCY zU-s|Mnw9>`N*Fa%`qQjDSGp@UE(XaK9Zadb%U@>HI;T4m?~rJVt85jx-stx$h>3A# zzyLKa)?0!40fn+Mo>LuF*nE+Kb7q@_Eu~Uj;NKa z+s)Q3)v5S1c&1h(O>3@c%_=@9pPQ3MgnN{_C{(%XK%_JQ+6v0^DrYPiXyoMA6v(DP zEfL7Ccx|bbQ?DjJC&I5+;aPTXPW_tv+z7vZ#rw;`A=Vat^?#&8ENMAItl9F}T^rP_ zi#=M{IC3oP>x#-6)|A0U(N&r%_BE_{XL(gz2?!W~HkBW)7-iIIud$x2Z6DGsU%TN@csPD-03B0_Su^>4{B=vC%0N@7+AUenb)E zQevYtK`X&goW>)SrMD)#jAtvC-nqdMH(vYWn#!!b+nhO*!rhrD{+P+`Ah9Ei zCRM(4PyH0bsQC7gZGbBuy&-2xSa`As&!O-s5uQ>}=dt{psWtgt@;4#c3(BWf41Me- zjMpcR)#I=^pZL;QZ!Xx(2-8ptLBvaDW_r5!C_IBia9w56Gua*ll=aSKfOFsR<;)1{ zpN>M6YaaDyI;np~#rb!#dMpr)j=*ecG_Crka+S@jS!X`$Xq(CLBEP#EYf-d$L&b=9 z8^kZP)y%0_`tB}cQANRf8&mx@%}dp(hRg4*eEz)#hOxNftM{KW0+k2O9x!ue)oknf zNL#ZiNbS2;jj_%^IIbS71tbxmX5p2Zx|=`8R}usYZ6}O+!FcGy|f(cm~@}^qfq5~6r%Pf?%tyv zXBxl7<{S)5VB-XdCn)h<45#41qXSEg<3=)*k~zrx9}wf#`~K*p=4M*=VE{mxPl~5AD4Es~k_yKu)8VvmGJp!Ebw5MndaA)tnF^CZ zVXvKn!Dr1ZxruS(=1n<#1<+yz;V=u^ANSx^nF&QbvQMv>vcZAo2J=v%Xb zX>||fl^F%bywITKMs7QFitW&5nO5#12RDjfO$0FfBKlSA}_|m4E`S{skZx&WX$i z;=XZEn`u=_@S_7UY6UuggRzu|rx!t_#@OB`1dJ^;RF5rMDJXF@_I(@Lv&={h)mvu7 z##4ZOSP*Kl%*Yr{)GK2tV=D$WrfbQd|6?zA21nE7Jc$-!BChn>?Jisky zJ(PGR#DlPWWyX5zgW$B~#Ct9acRWZSMY+n1raN6_E4hsuEnH7hk%})&!(uiHeQCfU zeBU0zXB{f&bj1X4h{63O&MKU)WM=?J5>DmtK8+!DWR^BSv*GbC*sK_gr*1&;y`wwCSILdz-~YG-VGc^Ii$fywS)vi(C~ytj+20 zIr@%`-5EHFs^>sf6?QSLu`nXMVS&p{RRB*Q$gsZiT7Ge^kCZ~_*i1#byJ z;X9TNqs6eyI*Xw8He>6W=&wOE{Q=_5S#5(UgB=J;hY-{3kmp{}7t>Vhv5lUp?GaUi8X5!w47l-uQxMKS(zRB)TxJq;$GTHDq&dSrmcgA}@Holz$! zh=qGhv=3`wj#J^RT@}b6`K$e0)*8*ETbBZ2+dxCCr{K?$c$dd&17Z=f7O4rof1#7s z57=|0TO$}Lr{Mp@xL8+sx$x6VJgzI6pQ}Pm)*D$t?h4al;&CHiLnz++CATiv@PQxe zl0fx7ix6#W`Z;o3FnE>iEizR&J7D??JZ>GT_+&KnF*Qe*A$`SjWAp=&o7*}b=o7JwkPFLIC}Odf59SmBDa7PEFkYJ5kzIknO7?%i0CZ^s}yo+gEI~EuX$zuP>$g zGEZM{Jixs;yNMA+pl2&zVNYz0YiPiIzK++lAS|7WRjY}3&$i-GG#R)RDoj72g}Z8( z)`qQoZ%CW|J3z;}0{l|J=>zPTvDl>}UHFN5Mg@3jmremo+^`OKahleuEecvVHE<#F zu-U*ow{TyNKpj8hveDDioKUolibe)_F;kpc;j;`Nt#JKC3N74(Q=hDh)&&|}(70V| zn_CBC@M z1va?N6t^^rgpt-F=v0{YdXt-<6uv|H8Li2_onBka>0!0QgyY>=lU_Prr2mUKU2Imi zufMQzv=xiR3SBGLH&a-3Z5C&iT`QR9TP3{wc$>*Fvf4{)`EK7q%}lVF^mmw<=zEpS zzX(tn>tzr{{P|SfaIfALUAWVfUXgFL58B=OS$K6c&%YeJ>S>VHn>`M9YemF@+`lm( z92^@Unh@Lm1gCXw*oezSTiA#Vl8JS1vwYVH&o*K)P9wv8&DJf!h{ZAyrGj)kGdwA! z&zn&NQ(#2o4(yH^&5>`rFU$82vVxfU+8@ks7WS_)_5a$lQQi2XhF&}riRi80Cptp# zs3gq#t6ntM<7an+N!qFAIwq zX=s?9{I?NmyNHWmfJ=&vGh~zE+kX`0GKOJ^(>1xsaHTnY6VXm;cin*15esXL#2%$} zmUu43Idax$s{C0~2&wGBQQoOux)W|D9}{nJAfyF)^7~Shr<*+I%dz5k47uKW(bX%$WS= zyBa1$h5AJi=UWefiBUm+vBYsv5pm#!K^xvRpTaU&C?3>t!u0_=RE;bT-LlQdZ}T~H zNedo3?Ox;y+ZF9*LYrN8W$3$YM#DC9`~9zVQzLa(g)ZN2H0=Jb|GDn5$mC!$sW#!j zb|a_FnEwB(31cH_mWIx6H|qC%c&ae^Lmiu>sRAq*5AZAsEeAI?gPH%S=Te!$dNe^9&)ikO9U!H18y}k$8w*K-6k)lpAb7yy@F z@O~w;WoMV4G&!Hr?<{me62>vd_dMo6PIp^4D=V^aQ(Y8Qv5LEPxRFOTDl@Si7B(4z zS#UcC6Klgp3~zW?xKB#QGc%s)i2V3S=yIdP1N9hdEm})+Vn^KWT~t*j9F9kP+|kPh zRVp@#R9qf9ew)$Ucs=ypZAMOjKsR(?xv)qXg}d3C|q$#DD8Hm zL68Y5Fq#W$q(5nCDQQ@ZQfhl}la5AVYVDL-cBkYBH$6Qyy((i74l7d9OM9Yc9;+pE zG>)<~Eh8nPxKFsXh?&0c5-<^`;dVTww(l6IH930>MoQ;b)W%X){mlgG+8@DSV+g|x&aVO+^Lo!2_xtK=V`66WPG*UA3LnRT4 z8=w=*;#)#_JB^%ZR)a8W+eNG%Vb*qG1)~&B2(zL#dv$y?Qm@MwT6uF=K57&Af62cX zmakqOcNK&#ztgBS_CMg5i@DItcEwtU*<>HQnhKdi{+Z%^z2!!+ysO?m>&=tdz?-_P zLx79FnV%kDhBoW{8`C_nJM_SvM(@<*fy{)}Cl0>G149YB@EEgssO2sr+w3(kbmcC? z6YPbkHoXC+y51;W?RLm<^|b2yI{jRZgR~PGC9!uw;CNXvEe0LjmF01q2xVA zjyYjasA!Kd!nF!hrhHFm^&TU?abGCnsjLMT;8fP(osNR(zY7knG76iOuA}VTp_6-z z1^SKN_rZ5~VRBTpDW?BG=-RzTL5jSixq)s` z@MA=snN~lv?sn;?S#>e>4}`MsGIE34*yur+5N(;i7uxjqM-9xg!Wp*7I21k1!MCme zBXERu_&k~ir`WNoOVFC>rvx^uad=kkY33}7EsAZ2S8Y{hAx_}PL(BK$BF|;;GH@cs zj>}3b93kExdg?CR6JAN}m5?$08dBaG#~1QS(38Lb@GoXHBWvIVtSZ+eRFfw$fkDEH z=xUA%)&}%br;-8~Cd~!KKHVN=JXUAe7Z{A{swmZ#DjNb+)37gQy}*66*du-PL^_); zJ;~$&Cj|<#ONXN7qA<#I*cR?-Rqea{U=^SI(!1j4RtaXNcDuVMEt9WF@gbMk7+_~y ze7w68R0Pm&j^$A{Qypau@cd;MS_Jnla*x&Ej&}GTKkqbPYZYRsQ1urvE9xz&tq1w`dTbl#GNb(_by1AHt19OI86^zcA}bD)<9b zS7zxb)X4OX25cN1Z_iM@j<@GfEX2DHrfLX>`BfgHjeNH&|9ms9E?J{IZOo!Xbrw%% zDnrBWG3v#(7Qa3d!n;ImuM}mac$vf%_y_g+HRRj80o@NxI6(r9!(fwX?M4ul6l!@t z8K8&$yvHaE3LDR1Tz)*`b>i0yxw_a zh(}ggO_p~uTvgo2Zi2$z*yjOh%;Eh;PUge#y}W-Cd9lFv>7dYu`;A7yXKA%3Ko@x2 z@BfJDiup(k?R*N1w|9}w%s^+nV_<6FMb^tdFQV<%v0CXNI`AdZ{TkA10S>lJSjP=p>CB% zmdlnOS83Fb54?=ZF!<$A%L7JcE9qNSxNnEq8QWsMS3udKDa!OkHxPQF(#VUY&MMd8 z&>aVi?0%x9j;-Zvw`vvCA^p_d8i#Imm{j%WpNKIy0#B6K+o}xgzjHF(XX8xkNXT)} zXd0Ag)67gVy@?oqdD6j_q7s3iOrv@|#xb}Z*!hwP826D(AX+68+=teg2_$?8P<|el z0K?Z+*cxd8??1SrXVXb=?Ade*MdWTyr}{FT*yzd72M3Kz^D#&0)Tc(>1iXKwe!^Cj zjQm4JQIPc|Qck157e-v(6m%+ZhI-+0@{2lPU`X&Lll4!sOg}GyS6KFl6k_mJdz{3m zbS|9`? z9tRnx=uzu{HYLk8R{xJcw&Uj$6z%xY z>6l?c{$FO}S3~JXkd5)u8l^%Vj~H!(qO26}akv7XQ?Fmcf1w=Eebt0dNni(HBANOJ z26)X*(rrzOR^pfL)=am2<&HUZyyR5WDsl3b*;U-$)=H#0!-`g+=mh((P~QDUuKDnw ziq65jVBlkzfk0*t5Xc`eD`p6W2F?IuGL0Bk22*u1{etx{Pgt?tLRKq%nf?Egbian| zbby0q6Be_QPNp1tI3bII5(w4FR8yEt^X)up%UqmCZBgXW*2U6~tZ+Z}*%Ol1si=%; z*N}|Ka+T|(&X`iYj$K`6OsUI^NkLQFE*W!yWXxC5TVzajDLP}G30?L8GA1kA%nLFm zTZ)=)f<`iCI~`V#(G!lb8JTdRRVLhNw9bslp$QP6{29v(F`Y5rgh+J8{0ba9;=e)h zqKx^K&Y17n8FOEC#{7yIGbdE`piw(WB@z?gqF_B&oi=d~CE-ARQ76O<2|8_lhZ3WR z*TB~R2ser$-0*l>);G}#PgBIMDv9%`X}u?IP7g=}{vex`iESOjAyHyn`?omKrLRCL z@V(U5ka7WL0R&luqH8{angOPTi}G${v!QEA^6=v%!|C73$X^j!_mGi1RT8srWzB5O z{d$4#kyK`~>RmQ+He0W9;f?v|oGot1vfXet2U9NW0*dR@{Z7a@iquVp_6bwBxV1WU zQ%zJX2^vn_?In^}TSpSdJQ7KwRU+waSjI>aj}b`f{t#3No^ZbW0USGeenJsNi|G zd_e?`vXRGYdhNf|?U5$LYtmMf*M2A8uOYQnxjwnTYvhU7@aCVE42aUKno7lMWJGyQ zP}$DWX&uFBG(bCzU5z+R3=^k)Wjl@L1PH`w-#Z2)rmC0ee><$H7|4>A4%7b!6(!-; zw78)|&hBi|59o{Ja^O|AVl=zj;CZwD;n;L& zR*|*_n0`~34jw;iX4FZ5lRW82z=h&PnbGM8eR$BwF#nX)n3I&Cu+LSU#2e1gHIEwI zf}*1IcUTp0OG_HYqa4spYXaU;bp~jKBvG7opN>`ntS1j7acM+NN31#Xa^{RI+e`eH(>8BCEo$;GfF87*CCiR_oPBdc70po4NulAWI3 zK!pw*FcO1NPLArRuMoP@tywTvJF-sLO#GrHY$kqbXPYsb-Lg+vp1393ZcldYGG;pUpXaVUEmZu3k**_4hLHJRhO#>UQ%Tfp6*PSB)meup zB=lruWJe~e#H&o!b8r{)zl16Q%5k^^7^<$qOL6bT{d@FIA{iWezSKtXqWO}n=Zg^+ zdgW6iFCm14Bh2K+&378`3fHqr~L@4mW)Ls+6o-+lR})g=Di zB2SG~E<6v5UgX8htgxB#^fH4OUTS-KLP=k0No2vX-fEG?uT;3cm z0XZZhRlS-B{2qVO8X1i(b07{+`D$K0;P*+3D~FIB@6CB>d7vC@J+J5>IR zkvo7k@N*_kuMY#G*I-PY=16~C5EQ1rTEJR~pwZ1{+09CBlkVt|sulX`8Jsqfq8sN( zi4oN!MYE$uO3-jx>nbC~+Ipnu-^fUbRv9V&44flH(*gu2*I}8ibQR_ztz~f7nw4hZ zQeGF->it6K^s|O1bmCd#%3u@F{fz)je`CPFr|^PrB|05GuBaBc__#t?1yu0=I<9C+ zA#B^wiiM)L6mFK|ik{)^cOl4jL=~fGM^xmvg8aWcu4v*6WgIc`<8%Tpbc8w`G1>%0 zU1>gg9%w<$ehr(W9MHYhgc1_i1x!>jEvRw%KZK<`AFfH!O8nB{Z3xB4`Ebnx3)I4a z1#WcZz(RBosXnlXQ1pRC^U&E7Q3n=9Fat5o9w4Ue0}EnN2Nn^-K48?&gF6E)Sr5@q zQTxE69{Ya@>3$8_=>Uh#CM;$pYd))U^x=do3Q8#W@$nfs{neDvk>`#4#QicIY)aV+ zh@u(?zcwT91sqsNKeEF82p?F`I(=Yqp{l$%)~<5Z$1fER75eRR(T??K9p2XXx?=kULr1=4O%`Ipk$iQS(vI$dN@inUSom zXC&h@G9yK+%t(HOfiseW6Cgmj8OsbZz0oLwNc2Xd6*zX(Uy9;Id9;3f-(I)iDi$>$-Pth22_l_VXS`m&K9d^Rc#cZQ6= z1Hk~K9=VMPKcA~+nf^`?2z)7dR;V3W;V+VN)V(2oP!SHnZYV}Qwab@t5Av%MuP5rM zU8hi^lhse{x`g_lG@4y1%1YZX5PDIsU&Ed#2WWhl(47Pthsfv|I&{*g(~mM1c8xCo zJ9hT1NzqmP(xVHqFE*BVoyq-vJvlG#8A^G@$QvK2{WeqN0_M2hGyxNWX12ozW3U@- zOI!Pp?$?kO2k1PTu$Yys8(5v*g~62bcM9F~ijkG2%Ov2OPO_!VJ^o5{wzMgCoVqYu z+Kl2;MuUXQpab)fm(UOUjkH!>N$`lNn3VVdylib~ITIk|E+q1Oekh%*=EWHR!q!v$w>DM`TmI=EJ@m0=0LH!ItNlg)G!Mg&Vg8fkONs; z4>E@%GRUG;2AN;w;ULq(0D0DB4Glcf+;%=y8A}bo!`~8QSm~ z&Os=QDLNPzk9AxhG-lbyvjeHf6QGD3G>YQVMV#3~$ntB*x>c^B)eh4qv*cBu%n}KR zx~!V&f^x=4PLy*5jhxIP$H6^pT)T&zinvFN68G>sMRX7C2@r^T28Z2)Re&e6L&31U zbCpA-U+kWt(e9x%+%p^(kM(3t_Y9*Zk0=!Ph-U4c5oGx_WZf#)hzs09UbTCO1Vmj{ zO?BEmahEl**d z!#h8;?RBGR!!e-SE*nP?L{iO1>tpOxF;S-qoC@2i0t`tNUEV;dpc+XP*Pvi+hC}qO zYdqB>Rgf>Kf&`r^u0@Hdg4e)U0Qj3?NELY6BMDx#B2`et^h?!ns+fpQF>RA*`S}|v zyqxW4>+(9XH<9PdwKc_B4120?WQSE}l25Uv&?i4y4xi+#9!b7*6_~(wO+PQ%!YtcD z*)N5y13S*%FkQ=oiS*F4H?b^`t&L{J5aX*e2D=+I>Vk$dMjsh-*4AUrVTnu$(JEs; z-X3%IIY1y|ju(tM<};ivFz6FOjSM>8jarOe$*;>cn&{axZ(?c)3W%M*= zhZ5g5vWz)$>FGrsypz|(;h&DrBbk01kJ^3Bg@hf8K3aZ3B+j)XaY^_bX)QrU!NP?P4fqm=A<#r^R#+|H+z@m1egdb2 zF7+N>N;GO?>x6!N_L+*~F!*da-6|tVtgenEY7IvczZ)cY`1s^92_-h8Ly2CEgc9lc zpo<^YV)~%*@_8+k=dnx=N?5IcL?n`i;KhGdmd|WCGQG=i)(viG>bpkH&_&=_M?fhl zG5vlKBgqyk#w&t?%C0@D`r(6)o^@!Zd@-aWZRI)q<)PQ#HLOWX5Nf7>3Dqw}F(NX= z;q)&P=29}3qc}Rk?SXh*2D*0z=*R*Qjt`vW;519I3wY#v?R$o2!U_`O9S*62(2m|( ztpv{w($y&1FOs^|NhHS0#ov^;;6>7V!ITGqhcr%4h{<$?;~pv z(cjy_+mma7vIXW6>~Q@U&wSk`l#o~@Av8%GQH zSA!QOQ%{s)@0-rHcz=JC{B8=77O{l^uA5?&Br_gANY<5Y6`_~j#}iL6k+)=iy!7h! zu0c~Jv1K>nQWR6R78l=lm0(7;k-7LsfgpBZ9!Bi16oOSzF51pPW9NWlLp$a`! z_yICb6?Qd1Ak*VcnI54}&lY(Z8n7~M2FjE5bbc=g5rfaakHHh_e)Mh78zE(KC>o&L{p?<_4~|; z?am{TaBGP7o%y^=RG03B>49x*#joL3lmoN{aY~AxWiF*5B5pjH#jBo}6v%CSF9|<# zVRVvd@y%NJrdrT%KswXf4JT+_Rj#`@t}xPV-HH(nY)3WJ<|W;F3Y6&DRZOE#Q|uP- z*$S`TMi}$Jt*nS-&Q26{0gHrDUYwD-1Gk|_Xr0Eh<4A)9v!*TGF4*;N_!^-oMt z)(=e|G_C!xkr7XoIz8{xw|j#=GSZ91ZPFaGF=Zk*d~7TnVfYkDMQ9^x^zSdR#dL-VNNP`t zLXz5tYZ0E+n*O~gmAxf{P2z64)_Mnc;2xm(LZQIBL#IDBvV%kdcaq`>P?bzo(TSlU zGdwg@m1xEx!}4xjzKdmcSjOcjq_O#V1efytAV$`hsMpvZC-;EO4Sn&6 zQF{>XL{l8|{|h7G+f3ReOt2Z77>uvh|RE^n0zHE(1(A)G%lsLG&1`Y#YyeNjr)HYm& zlZAY|-4Cee5w=E8qr+s8DD%j)o(vuQ0tchHZq05m{Q$aF)gy1n!4e zThAo=Au@WRRc6w0w9J{rZUzWslum#uK_9-GegGWXqYt5Y(J{#bwnJaK*r5+-hf;$$ z^e76}kZOlMOwDj8`QlI#v_p@fM2GSkcn|;%rC8XZq7q&s-}Fnp@LuyJ+o2@d4*iFA zC@X1UI#eoEJCtoiIaJWFLkEdNSz9}lZiqNkw2DLdT{=3H-3$A6&G3cOLPYi> zphn`pneSGl8*4LSIYK<^@K%IUzQ#SlW1+&YjmDP^M)RulPi#_f|L%Vr8obYAg-1rCcc>vqUID;2SwL-i8^ z;Uj*w4B5l}Bw2JShoizl{UVCtRQ{Zy6wYx{5P2_zioV4p6v5Kh;OD^0qE^F~P!6!S zXqsjDRv15&m{}AT{t{P7?%(h{vNgcA!@>QoylN0QDar|be@2Z?5aY==9q^JqS-pox z51jpjDB)Cq6ZMv*Zn^pccc?E`4uebOBX_cU<+}z_`S)(oYQygu_|a9~t+A#IYSgck zHzKO=3k`6pT(849Q9o7oaxcOt)qDw9>lqNS#lyLKb)!$!=u35@G$^e34QDX=5E7$8 zZr~pj@dP+DvLLb`iyIkHlUUI3B*u0MS&^c85_8xilURmXCh-U84dYox_@(xcl3Dy2 z$k74x3K(`)JdL89F~+EL#E(8>d?n=n&S)N_7`%K27mxKUoX}V!8dkZk#ekIFi~;70 z!(e*CM~|nd-xFYc>7%rle?z9V4Z@yGo<1D6wxb;QCnf!ao-7L=v4Iwi22ODr;nS!! zmFNSySEZJQw64lEfu<-X5Pg10UiAST5$J=uIyKda-^qybyP&e02)2ctSBd9og!VlB z74f`uOgxV}7V$jIk#F3IQWo{#)TYw@W@H>+;_g8u)|JF!yz+vtPE1RJswBW?DN!8-6fab$$b17{nX@ zH{d!KKRRhRbe?beoT;U-NPV%|P@fJ5?W&>bWjut(8HH+i*;Rde;rbr%VIx9SKj3}f zj(Fx&fH*;8>U$*WUclEwW(PjCH5ykxc<7$O5AM{5`2Q*Xqbb>Df{ed1q!ex+6{;!u zW|4XkDU1JH>U6vMIGf6BPdHFu=XTo{r>WTia_?w2@G@6W{nnQ3Hto0LpliXVA^2fn z&$cWNhNw$DEO26b(m!5HSkP|BaJRZ@(}X;?3ic!%I%RSjm)h?py>jy8Hg0uX=&O6N z9Cwg1GrO_eRLWykvwY!1K`h=&F31?4b1OJi+61$Qz{2*ah zfqSzjj z%$Ym6%}dI`$AYSz^sLe%eZMreU?$5!AK^>Igy}5_AMZhRf80!1e;nc4_Y!uHTD^pO zsv#*8g}!hf%UuOF6*yyZa6;a0vCgHIqX#ZERcybx1w}vY!X6Z%2X6IIXHu4j2wPlD zxImmasW(med>&yRFX@N6v+UW$a)(CroU0WFZk9yDgKlbjK!)si@sJ=GO%{HGgOR?) z->h`2MPpgn*Msm#J;DRha8@SOoo`Ocff4~yi0AFylh<1tv-;@cuYi}5VtR$PSqn)sQUWxRQiY5{$w&$ zKPk@KQj7HIGvD9iRwI$$|mHcs%P9^Plrqq8~ajV&H{38y^C<=P{NX{$lXb9 zQ1uXGtiYp3$T%+Jo!*XC7x?n?-Riv((nqu*<hr%Y2Q%~UJ;_DFN9w`A7TlUY+AfsFW&(3{?bwRWx`#XXyKua;IiNC+R? zCT0aUll|@{!r!katUrW|ytZuMi~Vfi#hs*^b4c&8i{%HVW!&Ekdilw z&wj^%W~%tRNm(i(S@#~+8iZhUt6#*R_uF##`X>Y#jWY+5@%b7meF!n{R*NO*UbvoC z?;k|i-bebq4Ot%9pXC`6;U{D&uDqO-LkkGM7Kh&{{hKKCm&EjW*OL3M?u2h1AdD-T z5X6{0aRbLGB#f!T$QRMRiz)Qs92&QBG~u&XkkU|wV6wP9Z3`)1m6IEnM)(|h?^gE- zcX|hw*KTAqTr%otOPAV*m`_#hF{K}MFexGauLT?7;~~64Cdu=KR61EE+wU?J50{dX zn@2cb!fh);FH?EM$pwQ+?=gjW?Z_>Jdu2BHHf3XPoQ1|*>f~k20gYxdo^GB-`EO}r zP?bXw@_Y#yvzO6`z5&8Vy@Va5_q8Ume4-)YJn32PLY9A8OL%`LswBMF?*hZ!l^Y z4-y4_y@chr+^q1R1de+tDO;uT#{%mJyi{PTx%A(UvN)X)pKUK?-I2mwcM0qMEU`69 zC|_ZTa;qQ2X9Er+|GQPUy{vE?NyDvP-b(m!KIyNc$8Ob6=7N6~DJx}WHy6t1qezLB za(#i5C9B_*7hxBhaC_&XwdfBHdNeQh8`!u0wVOuJ#Bfgm} ziREz_tk5O-`N`NRF-SKfp(d-OnJlMW#ah=bAsi(``Jps+QZz4?c`;%#xoae4{TDLH zD!4R(m6t-1TRkHcevu~clXYP-C@!^rEJt)5CRMV!X(Qzymf^4@ZW8Wd-Mttxmul>% zWX>F}9jQ||G>`9Rmx}JC%qOxCKO#PEA*(}bP-fxJ^~m9x| zy86ADgi8)_^?O~`v0tQt0}}a%Wm#G;6sw3zV`Wl(CF)XT?9=Zfy>?r|cgm@)1!e@+ zPniop!3dXX-j5!dD4Wl+9uoicuam^GpYFOv?7B@BA&0D5k2RpxttA0pCV|;}1}VR% zQ1z=REVq?a@%olh79)NX$p*@i=t;b*P)Wxco+GsvZm$sQ?BH2fl7oGU~2qO2q5WPpnM z(V&J5*q~Y~w$zp}?uN{TP1U9J#0m+S-$N9gA&c)U8R@Gt4uSrg*v$JfoAbmI+03%6rP6cr>B5dKr>i zf#KMX=*StzhHnSjRIuW;T1|;yeSn<-ua#i;k3KehI(pq&uE4{5&tA@UlkUc$S+H(D?ns@^In%@-XT-rH!Tt`z3`!`XaO{GkBymV*}nHde6T zz&nFaxK9>rCU^@~v6>=SyDQ0Sp{5F!1*|)ao+j9?-Q=}WvjkfOth;KXW-B9zCQeKz zvyHk=n0tYBSM8Kfu*&`#n=jZK!0s_RsWQPHnnqq1rG5Aourt6`2=B$_$A&*>T&7kE zwhLHy{8`{tf|(OEwhmaZw)*&5R=iwo5@x%mWcE{=1N zA;I1h(N*fGU~{iIHvGJ?7RL;1z5(pt%wgC&ELuUkYHed@C>J7ox zbtkqJe>jI)f}Qh-ZdY#$y1)Ig;W6f|>K(!AqKO#uHuZsE#T$H_;huvv(b`oO*tY%xMM08jiV*jQi-)n4_xV2=hdEjpVg)Hy+KxE?Mw z|DnzcwhdTsU{!*(Sip+^Q21MvXucn?fO=Uu1RFM!lCP))!CC|BZk|$Uf^E3z*zi&2 zX&eT!-fm!>&DT^*!A2ekviEP`b6R9RwTn%>jSoZ-JMSa*fodaIUMU;=1iup`?_)>? z(Dz<~Z56M5r3MLhstvvNH6CkIa`=*C!&jK!s*!>XIl%V5S7QV_Kl4}+=zr8WL0{NJ z<}Yfz#-#aQ)wP0s0W1K&Ob~4JJ;#QhR)4A)f~^4d8lrQiV0(d`N79=s*a=_;Ty~vt zCyY6XNPwU*-(X659~mNud}J&T(O=9pJ z*bXz#xLdIIT5?i0H69Zz<`PcIrpA+k6##q6Y-&6uSQ=txI(W|u)&aa7W}$ILu%6&; z$LCJp5UeS%9VR{z`lg^mA-dfxG2Rty(jJCMGvhtM>Y(}Qh>^2`EpN<Zm*KM0oAnvz|E#(xCec^{cQjh_X364-WN zzY6vnuz#4B8NUfufGFu~_BGCl6X*10%nUQm3(qy3A&UVw8G2vTWz38*9D@A{Y&xPT z)m(yH_UV4syVeNi3bWr%R=n1zE7%NR0X5OcgD6r2umWK9g!k{+$A-UePBiKZb_&>M z<`kp3U|l4-ryH#V`vndTsM$tq!QKV75Li3GKCE|a_?PBfqkT}&CxI@+Uo_|;*o+cZ zoM-eDtRJw2>UyKUU>$BIugtgtfvVIXB&fYcnSnnYjQ-XGZ=os&MzdcF(CiJyK;iWT zFUGOK7%bR1w70|DU<@;5{i|1>?!L(wAk8wVa6UgFqgOc3mu5yytN1UAW(_3w7%vZjvR z#w<~DM<=Se%eYQNACZc88$Q8~?mafVuj6iGp7gK*0;)jWV=NS`(_oD)63MYx)W$mQ zG5msc1h&wz-?&k*9*beNuhm4ESFo3xQp*d*UBrUw zbD#nBqH(t{4+C4{c+t2=FyByYlYku%?5XZF?WA!;u+!r)_KuH?`vuzvY&~X3rC{62 zDEXW5kYKHvW7pttn@0uvZ^g0UUzoMbX9NolLlgHnQp^_xeILxNj&$>sU=w9=$}!&- z>|yj`tE0a8j$nO-*U_sv367ws;UV;xdIl7o%3w9RRQ|dDF8^LM^ zhZDWrtP-?j0y3LpjOlUErEf?RW6T`E8e!BnImVfJf}O`s=xuY7nJ-u>n&0G@WHuD+ z7Z|$UG1+V+*qgu}Hm8_Hf}JZxJ;w~QSTIKr>tAPcmf70DDbuqrBf)E4>fq#Bge*(^6_33{(@d--;Ai8))aZNPSzH=A?Bw3k+FFE3Dg%yNgLKKAnI+{^DV zS2`Rpdn~qQm@(#>DBj)XTH)=&Bb@?uuenjMo_Jb=P&YSMOJe;yXoiHj61NKl>ackW zFr}v9S=nCW0drTiXn{If13PB!jp99K-XmJ@6d78Mn+FA(i5FrE)Klgm!M4{T_KbO- zU?*_vf%WgCc`QoJtLD?f^huxIHD40!2a2lq&6fq!efq$BMX>$C`^Y>k*evP9SLWM- zO_c_JFh7pMelfoiEKPh7{KNb)s`>Nge}s8dnpcir1$zSiz$ZH$zYF%I+(LPsOPo|Im+ za+C-*M@F=Rqm5uq;#segqpe`gr1>t6_JW-fLoavq5Uj0W104MYy919-3e-?XaA=gJ zBOO<3rl=X?7$3!(=$IabO?J!@Nqk}jYNk2nM)9UQe8M}-CyQ#fV}W2gF6KBE3Z}d3 zb@=i147hEP^l+}DOt4I;c!Oh=VDAXF$gw7>iN%h!!sElp0=2}kNihDpv_LI&R0yX1 zw9K(pFzu)1j*wt4$k?xNYNj=qATr!5$FLYH8P9dJA*k|omKA;)p2BM3EprQ!pQ7otQTahwrR{NNT% zJmz>!u*YONJ>hsuFx|r^9q$OH`}C~ieZhW~CSGuSAebKQR~(-UroHx><2z@46`Wl6 zAF95(q3%i5Slu%EMZ={^CQmY5>ZV?a4ww3+ek1&~q@InxapGag?rS@{)U!9Xfz0Xa z`r%Iq7NyMqrLg53z~1#r0cQ%_xz6jt&HT8p<6Y{B6*qvMU$zAB{F1eR9~F_x*?!$ zCZ(kxS!>+pH{FKXTvUl~tNdDY6!6Hr$56Nau5X-%+A?)ftf71px2mQ!RYeLEcou7ibr*=muWBZ-}ggYx8EH!+FDQe@OsuQ%0HKZF130m2=?YKPlEJ*eKMZCokF9!(X8*K+VL@@ z&k2(5=|`*Ebl;hPerJ+?rhxFZW`t=C2xp15W!t0w3zXge|_Cm#* z?!T&bav6JbZy!4FfeOOL<7;K7s1GK8&^bjtA#k3+?*uLpcuwFy1=gMN0lK<+(x-q! zHi*%|FFWJ;fA`%#fs}lQuOZ$zm_!?gwI+M2z>Wi0etPkF$b9W#xy_v%%Xe>##V0{N zxRPe2t|EM7JLx^99qrswnWNg^^WEP-#w9X1jE0O$WZ*3}Y_}V17$Sp8|Gr@wXQ*9k z5~1!rX_(CzYWB2DQ0{GWVciB|^iXX&xR4a%KF?zJy30HoC2(F)M*4cV*QHKnP>~KO zbub622jqR@99+I8uU;1o(eJ4RDBppA9bCQ?<87#)M-{>oxj7t^PnOaXA70lSlr95X zL&GKF>Z6x1!cIiRlMcWw*Gl}ywP3I$Y+iz~*P$03jQ_r*GZal~*at8dv5o0>Bm2=+ zOn*+ocAtdpi>=s!gT2UodK~39Ex8gfyV(f9^=nC=FJZf10<&!Gq991w^Vs|rKP$i7 z@nmb4dQzrMo-|O^mE4CXvEkPiGgf*?pPDaWI%+5}KM2#+Q2A)gP(yDT5BLsdze|0$ zj~+TVm4h`meKI_EE}x#;Af9fGT8RHmH*SII@AEpK`JCl!Mi0SFt7gDz9iBQcb&$?a zqx{s=_&UgvtL9b9L?Vf?!aqEba$q$~iNuPbev*JagSPO-(1G<`1_#Tx%IKB~3;-Hx zbXz)VX8E;<-y1i@nh-m z((4E(30x|0kM#QnM3|wjM@oh#BuEDbH*!3d52i&QjOBvSp~qdYYv2*8?kA>PC*}7f zqn+JCdeW7PVh5Ku!>nnkaz}OU=u#agEO9&4KqOtKnj)|qsmxGs4r7m7%DV8@0JhQ_ zCgK@`M9D+J;Jt8orH8iXN{%b-^#GcGPbTEIE$Exan$Qz*!Y!8M`s6KKLf*TFwNe`s zW?WA9>O@{oD5sXPneXo)99OPW93{VL#CdT~lM!ea9S)+$izL%+5jbW9D`f2AA4BDvCH_y#poI2w$gYtEx~KT5T;SUqY0w0jQ+Lbk*Xu~yom|oq3dqfZ zcY`g}?z+t3b%k`_7B(5viA^>Y*j!Za61UG-#cHmOi(;MXIY>HH-axwaj*YeOv&5ws zW2}%}Y0v~ruoQJtG_MkP3=lpWM-7u?SXZ=vrVH}Fj%^*cw=O%0{=K-H@PYEz05?l; zoei?u!yDK@tfZh!kT-Wxn*;L&<#vb(y}P=R}_Mktr`WbZfLN2~A7XYboJ zWBG+9g!3e<_8^%cfnY{ppEI8_Nux=rkg(MY54rd~fy{{cV^~)&JWtQ#76xlg5Kf3* zY%X3@^zx&ZoahBcuNU)fXFB?CQzo3I+e*;Ohb7fGussQ{etKH&xSJ+!ZN!b&Z+#D9 zN^_}0{*P|n(TZ!GUXU&}MK`HUX`IWxp1O&BIxOqn&9d%oP9a_QUeo_>wUm`MSfhE} zSKW*@B6Ibu$T1 zk0I0>YD;EE3ASrU*rIxj)csM`kz&!%OEfeW4LwCe=GaC-s0dxb26U9(APYwH&OcjJ z-%`R}b{Ro~u8>5bPn9Vq#}z|W4byfvTjl)$9m{X~8f#wfWJX(TtGzhgrY-l@Gk zk(T}w3$CGV7WkIz^UqG|2Ff8cj}R94&m)w1Wg_eT2o3esdeG~up3q!hRbi61QTNrp z0joff3cv^1U4tvTlC&12WzLO&o#Jl;te1Qb*la*U$~-959)UCGv}H4GZ+{Nux*6>2 zfTg_U-W&g7_0XK(_fqHKp1=0xHHfcGaK z1ME_Z@?nD{dV+TN><1&dXI+zDj0!Z4pC0dNJvbpJ3LLQX8L9OGU?|b=UN(L9FEob)!`LUBg+BakwejFR20G^~uG6 ze;?o$aLBZT(9?e#GHt-E1eZ?k*gaGI;phf9D~9mu`2OJjRlkQ?Ae z!%7WTqt?UD@!i`5fy@*|b4AfY_@ma4=>~KxbKS6l4bhGzbZ+aXQv1N_b;TcJq;>B`TAx; zBUBmH`-f2ud-QRXe~y0|ur!g$YDO~Uub=unVEk&XGWQ3^ai23_>B}}F(i?Y1IOcVQ z>!jL%rDved;eG?~k;Hcahb0rPuk{(=gSFflnJUfqLFY_$>uSQQM}7x-cxWOzFK@`^ z3mOJV8Ys5(6F6Y$e^BAoc-p%z(VfA8_zgaI&CuDq3guZbjvf)E(W?NL+P@04XqoBJ zGCKb!_sCQwiD^CPiF$y8*WZh|pp(y}go0}NvpYFmm+s<{Q@4d)cqp&Sn%leqO%L}t zy5V{-+Tkt$9FZ8#E{OlOw@0VOLa_fOv%sG?Q!+twG{7hsR1Z%Z)XKOay)Q*5j85 zv>J;6woGGj_pNT-!>Kk3c0%pj-wYMM&{*7EQ!It!%LWlGIGEEI>a~aIR|ux-xzquT zNxe9Az5#xA8*V;Mxf(`e^)v=GU3$c+5*u5#rYEpYf}K#W)!Apnsd5|p6j;1^*v2}i zCL4IEy%BYuP$qx*sutSVZ>hw#Hp07W;pXv%wlG)5^_mdtz)vk~?D^q;Le1kgR&R21 z6F<1I)zBAi^{b7o+579Ii8$McbRtQmYfN+|sroiXok^-SFto2-lcY8Z^Ms8qny`tR)tTOdd!(u{HrB7ts2=I+PQmnmdeoyDgAXV6@Zj#5 z^-ic8@D~g{_-pk*fIL&bH1olr}2%N!nc1iyv<|0sL&xGJmd z@qg`o&f&}q3gS^fP*M;aaAt61PD)8LP@D==3~y3u4(RD9qBta|shFvxCMXt|4Kzv- zscARvC5x+dqs-z;rDZ9F^<8W2hk*O}{(i5|mp?Yod#|*9-1px@zA2NT_cw zxL=XjUa)3DFIb?_0awMyKzNd=7M}FI#}Ei}2D3qET`HhA;0*%))xsUD?cT7Q>8eoF zJcKo!@NSn<(Hm|LR{>u^>H`&#OkDWEaGgm742G1bjP=wK(m@pc`nN&2Rp+X}XgvLOxDed9LK}aXMM-j$ya>6*sU{bM+bHecs zs^j4llM7W}oiHA%HKGx5JbbJLB!lB&&Qvm}23Bm7_Y=9`+R(Qq#6lWAUMH$hgo(L0ArU@ia`8}_2-g(>MUx1D(Y=g^3W-iIzJ%VX-1KczMD^C}mQSPJ}B=E+`t5I^Z5i%TOjLPxrzS zCS_t0tX71vd^KSbY|%8S)bM+~^so#jl$vuYJUNT!KQ-o0fgN}RR$Ez2g?*jqEkzjV zcN3<dA| zgf;L1_JcGy$E5O<23Is04LfPzdYClZWSf|%&D@%h278!lVNsR~HBT!UOvx1ZKzqgf z_HgM?g@pE1H0khVCt>meRyDQG3c-L=HLBQnXF@t;GPz8{7wBTsVK0+1m=3RKL_K{v zoYshD|LNejkm9U`@f+UnF&%~xIk9N^%@!~N%2}8XkK~zSXMio6RIxqJ5|9DkX=F#u z3>dbEWVJvGj11`hs3IIpx@15Ilgd&CjABw%kpXuzxnLtM-!fndlhXw|j1(|~QB5Qn z@D@{BG#_`O;fu*&J{EVk*bIncQe}|=i#3|Qzz=25Fx5h0%nq3WXEdVR&x9|T@||!1 zPx74w!8s}yR8X^EFuiS$xql?DckC=kTB_*UtRb;;;7cZz`?-+4oMdWXoePIFqOzC^ zFEOc1%!M;dF6d#3jGYVi6)H|A<^DnNVN|LQ!e~XNyL;TyKM3&}Rcss=`yfnZQp3)J zuusWg=Y0t%3tUB!=0n1LDb|M|oJl1#6Ebp1c2#V~3}(U(CbZ|ob#EpdWo#6g_k|!; zvf6frNFmEmNThX=D|TG zoB{GzIs4Cpe=@3Q9)_=(R5TAmGn0x2yRr-LPYoXrLwAiv4HfvR#iVs4Q{fgsS|?h< zq^e>89P1!+E`U>vF4OAttk?z6%v57Kni(ds^X5^cHKyH})@}$@rBNUUhB3Kdyo=~NO?LL-X5SoWeTp=d!N#BTDuXm|VoITNUsUsMxNe*>vA?u}k1PjjHY|i(Lw1caTgO zTn0%@F2G#HE`zxpWKTdo(^Yec*Dd`Muur3<1BqVMXz=j2W1oOGckuk@GR^h=+4l(; zx06iNnz}!|!}0_qG3A?@=Ic;(l}5*BhrkoCQ=_n_DbkNMN;pb1_GylVr`RVTO{3a} z8srK%%%tYql`w2K&wsVB<)I~xm2ex88phs-O2sP3+(YDoyY9vxQ{aq77UZ+8+lGu6WEP55`1}_ZMm}6&%;(u~0}MMr2351%0Hr00sLgJGeTNj$0%HTz zYeX~N2DrkclC}YEGtrE9E_MU>9HDTkWHy37Q@+Vrv9T_8BlOpBbwUU(4~8?Tb;?Fa zQ8K8TE^w6Dqsgd?7QhuI7rgc0r?Ca_U1@tlH$iq;dqOwCUX3WBo8TA|CRD829S|jZ zWYRRe3FS;fHaJtsntYSD4eI_Pobb27HHB!tId&V|W@^Z8{{#mb;>r_ z(nAVjPn#zTP)YwHJxbwCSzMPWDfIdUxSMu9-WB{v`*Rvt*p5VJdfVSNEg3M znkq4c(CZZ@H27z1A%rX9{1(D+CY;k37~%?HoTm9hVhA`3p^y=8dT<-65Slew?(>6x zA%wk3k=DZ94uS7aPSt1z&c;P>^L3KBpl)~wz8;$L22nozo@hX-cvHz569v9$nempQ z`b6w+aOG`9lXLK~SSJjAhp-mD#chh6F!(f4KFlhy#_fV1nQCDdn%@mA8ijNx3alng zwbQg49(q^NU>tRep-`iJOt$xwjK<(%@Y9IK;9_uI*O0cMiXp#-R8^4{!x1JIq#H=~ zqDIs=i{Vv8SfpLzis3X9ZslRA6@&Nt${=lm?FBkKjS}jE>y&+v&E$d+#YA(QACS-m z2WO7eczlxP9PI#4TYT z^zKB7XL-V>#Yh0EPGw;&cui_VgM-d-G#v0*7{#;;o+}EDdlsJ5D4;kz?f`84uwC;I zR4`pNzZAb;e+bSnk%h>(L-3s@Ywg<41Bc`DJmFt8_t>5?^bmAEPtja8zjJSxJOqQ8 z@=d$5#$v$98u@rrz{N~1(^n6N;CsVcH2MT@h7Uo~1x}1Vp1h@2x2~_Xk4&phrl^_DpM_dge~YW z;7i8%rz++!^kq_G=V2Jh!HV90%`o_c8R3?t|5ptLq z)1RB&#c|lfvRW;geHu}-JPtLVDudL2j)UzpqI|d=5g&IP&NnF9hofvcEWV^@*^p9E z4u_dsPWVrSfD`a0V=YkHPQa6wS(TgK3D~I!o6y9#6Hua2iEo%Z0cA|8@K3-Qji>>i zfbn0n$MOQCcB03bTr}aQ#=QVfGOCvF0+eb*(YyfWf44{TB6R6QqZFCCjhShC5sq|{ zea2MFH$*Q&^_LWj+VFi5zGNzbY-jHW;$DPajU-fsUjZSCFu(KSDjVL=9y8NHV;4DZ8bwfrA>|EK9N0IN>`D|3u;YF!Z`owI55dz7Hcbs@QlW zt`_1n>M`;-(jKNf)27Fax>|URNiAAx!E}RSQ440AAvLP+TZ!S)eqswy=Cggm8F0R- zVLToZeinxPOhOlYwv*@srhM3uMD#C3T-;~Dc$1?sRjdw^XTejWcUK!w(@&%G^IwlU z2Zc;(EI9|~HKNhu91M5_4`INsY@QSIA&g>D z!|aDJvy*JCB5XmY<35CKon(7{by74`+qEd%bBoAjTC<@c@&a7Z=u$$Mya0o5E7`9J z2DkvZ8oiKHG4dlg!<27wFZd|#BltvQR=h(dr|Y;{Fb$zw!L% zg4gkW;bWM3N2z|5eI>3A_A#kCtcUPFNmdJVzfccx8qqCKJ&pYYO@s^e~kMSHZrLt`KLhV4p2CO zx5l4A1#W4zg=>JSPV@~^jp^)DVX^^!(rDfRqCbh8xSMos^dLkVPKva*bZ?ovXn?Lv zWd4`91_;z-zek1Oc@(cPsg->Lez=Fisd8$7dL~sC4e)sh^ zs6!J<2;WQ)@eMGJ$z{55!icnyNp-FUIH(cbf;2$5n=*g7Yq!1)u!KpOzXTgQ(T|ES zOZNCn(5lGEE%*``@DaVXLc9c{n0CSG=ewe68s6AbBR%@OfBfgr%7p#@$i%*1LbzF( zAGv%+->)EnNtwR_lN6!B(D*Bmp=r`waRo|k%AS*+H24N8HB|I@C-Sx{RV54SL=zOD zi9zw-z+@)XO1^>a9_`_-LJ*VcqE}%U6E;NWYJ9!|QW$H1Za=Sr!?Qi$w-C&Pzp(no z$9)TnI>^3*WlXiEqkV?Qe+Rir2KP*iM!KwI5SjoXO_1$Han?e3LR!COSdLQ^mNxWx z-WePJBZPNV!lI zDY5Y_kk(C6Vb^K#zrkd@WofJ4R!C>!vT*vfLN=qyVJp1aLG=!tW>Pu41Me~If(>0t z{qDeZE!_DnbK~zoF5V+i4k_7x!XLfb4N74OB%=Gqh4E6%`HOPm@rBnn7^$nRj5mlg z8b!uGiS#j(YWW5c9;8gH4;5e#3z%H6a0}76J|x2}z%4GMdZv8%_pZ;Q-Nd?J74BT> zGH;{UsL|Bro8wJRaZtnGc0S+LB3ECi z#-ysrBKmitI8Bp&WwVG?8qtE)CY*a1)gGWtyxET;&4+Qh2jgwRi1}=*HFx33vG`!K$%@C$1< z=p#ZpQLZAari<}DqM(y(CzH$c-u%lbdyT0EOgp|pdUGJf=>q@h|B3G=>IW%%^ejUU z5i%IpezBGc+|-4X)C zYfQBell-kcKwM!`71~$iMYbojuNWEC9!p;_4hiim^L@pcPQp{stcof1OF$V@4J<26 z8i>*0!_95sLd3XERL`V-6bTWnOfI+^N7?=&6Q8ojaBycs?}YxMbu5w-3;%j_XhN8n zH;#lZIGGodFj(X=DT5IrZM>3=n|^n~P|?7owuU2x_XLuu{6>pCOfGn8M@B-lSRP9< zmBAR{VxsB(f{YPcn4I~hSz{kch!K`JQdJAF7(rjIZHqKUEZ2x~A0tfhEE9W!@ey7z zm?;m&ORdxiQ-|6QfF=-oG6wkViSoXZ6ayr!S>zwOrywSsukbkv^_~A z-J|R|$>1b03_aWOJ4qN)6;XaC2`?s(xxMfp^U z6Q5kU>(PXCvE_cvo)dFFLu}KK49*bSnUukq;zTFnJ`~$#I0Dv;r#ez&C+%dtiY_ag0N3;vxD%_utBNjib=mW>^ z`lX_VsR%ADEl*e`!WWRNM!d81y#!~jILPRNS$ADbSS==JkuV=FANV?9tq5PJXj{g$ zggnvz5hh-;<%@AlHKwLRVKQILQ8H7{&A0UVVxvZ9XYa7&i&l-kVp^O{vDBI-_4zp= z-zi>G$hpWD*Z)RBHRx^-&5seeAZ7aR2^&PxQldO4ooYxd5N9+xKDBG&7I9Uh@b$eC zpA!0IY=R$dD-`3HTyRg`;KW_x_HrfLjXhwWaPC{7kZNY1FyU?&8Ju(X-HH1|+!{rN zyCNM2#d3{anEGI1i3rqYj$ivON<1uTTq+joO-DufS|Zhgj*6IdDwYfIZoi}AZjF3& z@AfMdk2^ICF}&NaOyp}c0fomz1(Pb^^zE8mD6$Y2a_^*T$t9AY!`f5 zv^?>+2xU^TauLa-mZ9Y$em&=+O}JjEn!*ZPiFo7_lQK~*nm4Fi&;w58!n%n_g*zd< zJ5exGp6T_C8xl{5VN5EP6XG%xRj4lEgjlkb=RX%rn_Mbh5GhY76YJ-eiWkNDZA7YX zSBU4Bl)(ydvJ*9FnzX*D5Z;9?C6U3T%)cb&b)sA*T3kMz_>u_TPT}Z|x+L*ck+FlQ z2(CO{k@$va-bs{ix;6QY#J9ywBHI6?M)S7l^E3(7#QC;}(P%;V(Fv!;DUD+1|5H|r z&opYBegWyWMy4L6qFSWkSWmIg54`V++f4ajO07llgdPmNYaSR*N6tC3I9fe?~5xM znNmMWd|$*q!wGfrFT=HBszRXr){4^_QGP!VS2UvhejxPwI3Q4dKM6+)6#53Yj8bt{q#Ym= zF4(pGQsOzW@t~rsGrmc@Ag*f^lYBj~P8=&~Ps}IcrB3u2lgo6?iK+QSTxV22Sbie< zJVyc551kjqP$t#%E{Yf?d=N~8z(tXwQ8?ZcUlgmEYE8M5eIqZ5O&a-a++n#Ws+rni z`A*5O zB_=T`6PHA0CpxbPXG*uEOQM;HH?5s;Ni2DuB2}Bum&CB6is(N5lBg(E=9@MOxGZ9h zD++m%=(QIVbz#bTQBf;q>9V-3k*~2ePUKS~g^do8rd@km^ zqJ%T1c1`+RoY#ncQvE_)*T}g0mi`Oj{i@R3{}fRYQ?02l-khQ4Ya~-;@r4*yMYIcM z$MsD5LX>Kh_i*o|FP$R$btRnDBQ)tNk@SY5F~>ubu87kbJ^$c*$5nAfqc`RbPWo2h zE)+(pM)D?MV^Rj2gb&j?JQjFFQj-YpAp4IPuE~a5Vv_zNobik*nrkApgX%RgT~pnv zk4?HJiZn_vPfThSJ2mR>J~iok@mhy)KZt5gX0l&0{~+o+$bJ-`YqDPr8A(5i+fEJp zSRP8cE+)T4d0Gd*+Om>vh$R}Wc3+(IlQ_ks68f_^&7|`CvpB11Cc(0#pGCu8G6UQc zH<=p6s1f+~k+`i<{oxR#0q^kq*JyS$2h2c(g(EL?Yz0=|T?^p4zraBOxy#7@* zX!JSKEpfd=z}upgNtw7U45wA8T{1nBbX(Xpx?BHDQj73mQkuVsfKC*Gg!A7zFdGH@ zCJO%&8j#AFRI&Xonl++g`(2dQkUOlgs=`*$qKM76 z3iyCD8@UQwg-Ma1Dr^-KnViaetC+&5>abPJW>Ur0Di$!UgC|5}Y^!)&qZ8K1*gIm4 zM(*yBv44mHjqaDvB>gFhG%D0Z#)90Z(LQ|QRLG->oM5-TlqBVgjLM)+zSfCqw18Ai zIvIYZt(=I4Gp&Qq4Mdavk{OV)nN%6-Ww}OFhI-ljp(;Zs)uCP*&#Qu>I@C)KMO=t_ z*-evC9qMJECZjsk%SSb$D%8s-m?#tYzLwmn$*AKQWW7dY-XITuq|7gIqIrX?W>j@( zkY^RKd4v2|laYCY{7jQk9U5fMzjLy=1sP-?CS~3r$7nJ#?~p@J z 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 Y3 + + + + CatastropheMissileSilo + + 一个多功能导弹发射平台。它装备的武器系统既可以作为自动炮塔进行本地防御,也可以在操作员的指引下,将“天灾”级巡航导弹发射到全球任何一个角落。 + ArachnaeSwarm.Building_CatastropheMissileSilo + + Things/Building/Security/TurretMortar_Base + Graphic_Single + (6,6) + + (2,2) + Building + PassThroughOnly + 50 + 0.5 + false + + 500 + 12000 + 800 + -20 + + Normal + +
  • + CompPowerTrader + 500 +
  • +
  • + 导弹 + 导弹 + 缺少导弹 + + +
  • ComponentSpacer
  • + + + 1 + 0 + 1 + true + true + +
  • +
  • +
  • + + + CatastropheMissile_Weapon + 5.0 + +
  • Artillery
  • + + + Security + 8 + +
  • ShipbuildingBasics
  • +
    +
    + +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDefs_Misc/ThingDef_Projectile_CatastropheMissile.xml b/1.6/1.6/Defs/ThingDefs_Misc/ThingDef_Projectile_CatastropheMissile.xml new file mode 100644 index 0000000..5a7b84a --- /dev/null +++ b/1.6/1.6/Defs/ThingDefs_Misc/ThingDef_Projectile_CatastropheMissile.xml @@ -0,0 +1,96 @@ + + + + + Projectile_CatastropheMissile + + ArachnaeSwarm.Projectile_CruiseMissile + + Wula/Projectile/WULA_Loitering_Munition + Graphic_Single + + + Bomb + 200 + 30 + 5.9 + MortarBomb_Explode + + +
  • + Bomb + 150 + 5.9 + MortarBomb_Explode + true + 8 + 2.9 + 50 + 15 + Bomb + Mortar_Explode + 0.05 + 5 + 20 + 0.1 + 0.2 + 0.5 +
  • +
    +
    + + + CatastropheMissile_Weapon + + 天灾导弹的发射系统。 + Spacer + + Things/Building/Security/TurretMortar_Top + Graphic_Single + + + 5.0 + 50 + + +
  • + Verb_Shoot + false + 4.0 + 9 + 13 + true + false + 29.9 + 500 + 1 + Mortar_LaunchA + 16 + 1 + + true + +
  • +
    + +
  • + ArachnaeSwarm.Verb_LaunchCatastropheMissile + true + Projectile_CatastropheMissile + 3.0 + 1 + true + false + 29.9 + 1 + 500 + Shot_Autocannon + 16 + + true + +
  • +
    +
    + +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/WorldObjectDefs/WorldObjectDef_CatastropheMissile.xml b/1.6/1.6/Defs/WorldObjectDefs/WorldObjectDef_CatastropheMissile.xml new file mode 100644 index 0000000..a9f4e11 --- /dev/null +++ b/1.6/1.6/Defs/WorldObjectDefs/WorldObjectDef_CatastropheMissile.xml @@ -0,0 +1,13 @@ + + + + + CatastropheMissile_Flying + + ArachnaeSwarm.WorldObject_CatastropheMissile + World/WorldObjects/Caravan + true + true + + + \ No newline at end of file diff --git a/CatastropheMissileSilo_Implementation_Plan.md b/CatastropheMissileSilo_Implementation_Plan.md new file mode 100644 index 0000000..2cf1df7 --- /dev/null +++ b/CatastropheMissileSilo_Implementation_Plan.md @@ -0,0 +1,468 @@ +# 天灾导弹防御塔 - C# 实现计划 + +本文档包含构建“天灾导弹防御塔”所需的全部C#类的源代码。这些代码基于 `Rimatomics` 的跨地图打击框架,并与我们自己的 `Projectile_CruiseMissile` 弹头相结合。 + +--- + +## 1. 建筑类: `Building_CatastropheMissileSilo.cs` + +**路径**: `Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs` + +**功能**: 这是导弹发射井的建筑本体,负责处理玩家的瞄准指令。它几乎是 `Building_Railgun` 的翻版,但进行了一些重命名和命名空间调整。 + +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace ArachnaeSwarm +{ + [StaticConstructorOnStartup] + public class Building_CatastropheMissileSilo : Building + { + public CompPowerTrader powerComp; + public CompRefuelable refuelableComp; + public Verb_LaunchCatastropheMissile verb; + + private GlobalTargetInfo longTargetInt; + private List selectedSilos; + + public static readonly Texture2D FireMissionTex = ContentFinder.Get("UI/Commands/Attack", true); + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + this.powerComp = base.GetComp(); + this.refuelableComp = base.GetComp(); + // This is a placeholder, verb will be initialized from the weapon ThingDef + this.verb = (Verb_LaunchCatastropheMissile)Activator.CreateInstance(typeof(Verb_LaunchCatastropheMissile)); + this.verb.caster = this; + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_TargetInfo.Look(ref this.longTargetInt, "longTargetInt"); + } + + public override IEnumerable GetGizmos() + { + foreach (Gizmo c in base.GetGizmos()) + { + yield return c; + } + + Command_Action launch = new Command_Action + { + defaultLabel = "CommandFireMission".Translate(), + defaultDesc = "CommandFireMissionDesc".Translate(), + icon = FireMissionTex, + action = new Action(this.StartChoosingDestination) + }; + + if (!CanFire()) + { + launch.Disable("CannotFire".Translate() + ": " + GetDisabledReason()); + } + yield return launch; + } + + private bool CanFire() + { + return powerComp.PowerOn && refuelableComp.HasFuel; + } + + private string GetDisabledReason() + { + if (!powerComp.PowerOn) return "NoPower".Translate().CapitalizeFirst(); + if (!refuelableComp.HasFuel) return "NoFuel".Translate().CapitalizeFirst(); + return "Unknown"; + } + + private void StartChoosingDestination() + { + this.selectedSilos = Find.Selector.SelectedObjects.OfType().ToList(); + CameraJumper.TryJump(CameraJumper.GetWorldTarget(this), CameraJumper.MovementMode.Pan); + Find.WorldSelector.ClearSelection(); + + Find.WorldTargeter.BeginTargeting( + new Func(this.ChoseWorldTarget), + true, // Can target self + FireMissionTex, + true, + () => GenDraw.DrawWorldRadiusRing(this.Map.Tile, this.MaxWorldRange), + (GlobalTargetInfo t) => "Select target", + null, null, true); + } + + private bool ChoseWorldTarget(GlobalTargetInfo target) + { + if (!target.IsValid) + { + Messages.Message("MessageTargetInvalid".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + + int distance = Find.WorldGrid.TraversalDistanceBetween(this.Map.Tile, target.Tile, true, int.MaxValue); + if (distance > this.MaxWorldRange) + { + Messages.Message("MessageTargetBeyondMaximumRange".Translate(), this, MessageTypeDefOf.RejectInput, true); + return false; + } + + MapParent mapParent = target.WorldObject as MapParent; + if (mapParent != null && mapParent.HasMap) + { + Map targetMap = mapParent.Map; + var originalMap = base.Map; + + Action onFinished = () => { + if (Current.Game.CurrentMap != originalMap) Current.Game.CurrentMap = originalMap; + }; + + Current.Game.CurrentMap = targetMap; + + Find.Targeter.BeginTargeting( + new TargetingParameters { canTargetLocations = true }, + (LocalTargetInfo localTarget) => + { + foreach (var silo in this.selectedSilos) + { + silo.FireMission(targetMap.Tile, localTarget, targetMap.uniqueID); + } + }, + null, onFinished, FireMissionTex, true); + + return true; + } + else // For non-map targets (caravans, sites) + { + foreach (var silo in this.selectedSilos) + { + silo.FireMission(target.Tile, new LocalTargetInfo(target.Cell), -1); + } + return true; + } + } + + public void FireMission(int tile, LocalTargetInfo targ, int mapId) + { + if (!targ.IsValid) + { + this.longTargetInt = GlobalTargetInfo.Invalid; + return; + } + + Map targetMap = (mapId != -1) ? Find.Maps.FirstOrDefault(m => m.uniqueID == mapId) : null; + this.longTargetInt = new GlobalTargetInfo(targ.Cell, targetMap); + + this.verb.verbProps.defaultProjectile.GetModExtension(); // Ensure verb has properties. + this.verb.TryStartCastOn(this.longTargetInt); + } + + public int MaxWorldRange => 99999; // Effectively global range + + public GlobalTargetInfo LongTarget => longTargetInt; + } +} +``` + +--- + +## 2. 动作类: `Verb_LaunchCatastropheMissile.cs` + +**路径**: `Source/ArachnaeSwarm/Verbs/Verb_LaunchCatastropheMissile.cs` + +**功能**: 定义发射动作。它会创建 `WorldObject_CatastropheMissile` 并将其发射到世界地图。 + +```csharp +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class Verb_LaunchCatastropheMissile : Verb_Shoot + { + public override bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ) + { + return true; // Always true for world-map targeting + } + + protected override bool TryCastShot() + { + Building_CatastropheMissileSilo silo = this.caster as Building_CatastropheMissileSilo; + if (silo == null || !silo.LongTarget.IsValid) return false; + + WorldObject_CatastropheMissile missile = (WorldObject_CatastropheMissile)WorldObjectMaker.MakeWorldObject( + DefDatabase.GetNamed("CatastropheMissile_Flying") + ); + + missile.Tile = silo.Map.Tile; + missile.destinationTile = silo.LongTarget.Tile; + missile.destinationCell = silo.LongTarget.Cell; + missile.Projectile = this.verbProps.defaultProjectile; + + Find.WorldObjects.Add(missile); + + // Consume fuel + silo.refuelableComp.ConsumeFuel(silo.refuelableComp.Props.fuelConsumptionRate); + + // Visual/Sound effects at launch site + MoteMaker.MakeStaticMote(silo.TrueCenter(), silo.Map, ThingDefOf.Mote_ExplosionFlash, 10f); + SoundDefOf.RocketLaunch.PlayOneShot(new TargetInfo(silo.Position, silo.Map)); + + return true; + } + } +} +``` + +--- + +## 3. 飞行物类: `WorldObject_CatastropheMissile.cs` + +**路径**: `Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs` + +**功能**: 模拟导弹在世界地图上的飞行,并在抵达时生成 `Projectile_CruiseMissile`。 + +```csharp +using RimWorld.Planet; +using UnityEngine; +using Verse; +using RimWorld; + +namespace ArachnaeSwarm +{ + public class WorldObject_CatastropheMissile : WorldObject + { + public int destinationTile = -1; + public IntVec3 destinationCell = IntVec3.Invalid; + public ThingDef Projectile; + + private int initialTile = -1; + private float traveledPct; + private const float TravelSpeed = 0.0002f; // Faster than sabot + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref destinationTile, "destinationTile", 0); + Scribe_Values.Look(ref destinationCell, "destinationCell"); + Scribe_Defs.Look(ref Projectile, "Projectile"); + Scribe_Values.Look(ref initialTile, "initialTile", 0); + Scribe_Values.Look(ref traveledPct, "traveledPct", 0f); + } + + public override void PostAdd() + { + base.PostAdd(); + this.initialTile = this.Tile; + } + + private Vector3 StartPos => Find.WorldGrid.GetTileCenter(this.initialTile); + private Vector3 EndPos => Find.WorldGrid.GetTileCenter(this.destinationTile); + + public override Vector3 DrawPos => Vector3.Slerp(StartPos, EndPos, traveledPct); + + public override void Tick() + { + base.Tick(); + traveledPct += TravelSpeed / GenMath.SphericalDistance(StartPos.normalized, EndPos.normalized); + + if (traveledPct >= 1f) + { + Arrived(); + } + } + + private void Arrived() + { + Map targetMap = Current.Game.FindMap(this.destinationTile); + if (targetMap != null) + { + // Target is a loaded map, spawn the projectile to hit it + IntVec3 entryCell = Find.WorldGrid.GetRotatedPos(new IntVec2(0, 1), targetMap.info.parent.Rotation).ToIntVec3() * (targetMap.Size.x / 2); + entryCell.y = 0; + entryCell.z += targetMap.Size.z / 2; + + Projectile_CruiseMissile missile = (Projectile_CruiseMissile)GenSpawn.Spawn(this.Projectile, entryCell, targetMap, WipeMode.Vanish); + missile.Launch(this, this.destinationCell, this.destinationCell, ProjectileHitFlags.IntendedTarget); + } + else + { + // Target is not a loaded map (e.g., caravan, site), do direct damage + GenExplosion.DoExplosion( + this.destinationCell, + null, // No map + this.Projectile.GetModExtension()?.customExplosionRadius ?? 5f, + this.Projectile.GetModExtension()?.customDamageDef ?? DamageDefOf.Bomb, + null, // Launcher + this.Projectile.GetModExtension()?.customDamageAmount ?? 50 + ); + } + + Find.WorldObjects.Remove(this); + } + } +} +--- + +## 4. XML 定义 + +以下是实现天灾导弹防御塔所需的所有XML定义。 + +### 4.1 建筑定义: `ThingDef_Building_CatastropheMissileSilo.xml` + +**路径**: `1.6/Defs/ThingDefs_Buildings/ThingDef_Building_CatastropheMissileSilo.xml` + +**功能**: 定义导弹发射井这个建筑,链接到 `Building_CatastropheMissileSilo` 类,并配置其电力、燃料和内置武器。 + +```xml + + + + + CatastropheMissileSilo + + 一个重型加固的导弹发射设施,能够将“天灾”级巡航导弹发射到全球任何一个角落。需要大量的电力和化学燃料来运作。 + ArachnaeSwarm.Building_CatastropheMissileSilo + + Things/Building/Security/ShipMissileTurret + Graphic_Single + (3,3) + + (3,3) + + 500 + 8000 + 1000 + 0.5 + + + 400 + 150 + 10 + 4 + + +
  • + CompPowerTrader + 500 +
  • +
  • + 10 + 10.0 + + +
  • Chemfuel
  • + + + true + +
    + + +
  • + ArachnaeSwarm.Verb_LaunchCatastropheMissile + false + Projectile_CatastropheMissile +
  • +
    + + true + + +
  • ShipbuildingBasics
  • +
    +
    + +
    +``` + +### 4.2 武器/投射物定义: `ThingDef_Projectile_CatastropheMissile.xml` + +**路径**: `1.6/Defs/ThingDefs_Misc/ThingDef_Projectile_CatastropheMissile.xml` + +**功能**: 定义导弹本身 (`Projectile_CatastropheMissile`) 和它作为投射物的行为 (`ThingDef` of `Projectile_CruiseMissile`)。这里是配置集束弹头和弹道参数的地方。 + +```xml + + + + + Projectile_CatastropheMissile + + ArachnaeSwarm.Projectile_CruiseMissile + + Things/Projectile/Missile + Graphic_Single + + + Bomb + 200 + 10 + 5.9 + MortarBomb_Explode + + + +
  • + + Bomb + 150 + 5.9 + MortarBomb_Explode + + + true + 8 + 2.9 + 50 + 15 + Bomb + Fragment_Explode + + + 0.05 + 5 + 20 + 0.1 + 0.2 + 0.5 +
  • +
    +
    + +
    +``` + +### 4.3 飞行物定义: `WorldObjectDef_CatastropheMissile.xml` + +**路径**: `1.6/Defs/WorldObjectDefs/WorldObjectDef_CatastropheMissile.xml` + +**功能**: 定义在世界地图上飞行的那个导弹实体。 + +```xml + + + + + CatastropheMissile_Flying + + ArachnaeSwarm.WorldObject_CatastropheMissile + World/WorldObjects/Missile + true + false + false + true + + + +``` \ No newline at end of file diff --git a/Railgun_System_Documentation.md b/Railgun_System_Documentation.md new file mode 100644 index 0000000..986fb33 --- /dev/null +++ b/Railgun_System_Documentation.md @@ -0,0 +1,743 @@ +# Rimatomics 电磁炮战略打击系统技术文档 + +## 1. 引言 + +本文档旨在详细解析 Rimatomics Mod 中的电磁炮(Railgun)远程战略打击系统的实现机制。该系统允许玩家对世界地图上的任意(已加载的)地图进行精确的火力投送,是游戏中一种强大的后期战略武器。 + +我们将通过分析其三个核心 C# 类:`Building_Railgun`、`Verb_Railgun` 和 `WorldObject_Sabot`,来深入理解其功能、设计模式以及类之间的交互。 + +## 2. 核心组件概览 + +整个系统由三个主要部分协同工作,各司其职: + +* **`Building_Railgun`**: 炮塔建筑本身,是整个系统的用户交互入口和武器平台。它负责处理玩家的瞄准指令,管理武器的属性(如射程、精度),并发起射击流程。 +* **`Verb_Railgun`**: 定义了电磁炮的“射击”这一具体动作。它能够智能区分常规的本地射击和需要跨地图飞行的远程打击,并根据不同模式执行相应的逻辑。 +* **`WorldObject_Sabot`**: 一个在世界地图上存在的临时对象,用于模拟炮弹在飞向目标过程中的状态。它负责处理跨地图飞行、轨迹计算,并在抵达目标后触发最终的命中效果。 + +## 3. 类详解 + +### 3.1 `Building_Railgun` + +`Building_Railgun` 是电磁炮塔的建筑类,继承自 `Building_EnergyWeapon`。它是玩家能直接看到并与之交互的实体。 + +#### 功能概述 + +此类作为系统的交互枢纽,主要负责以下功能: +* **提供玩家操作界面**:通过 Gizmo(操作按钮)让玩家启动“火控任务”。 +* **处理目标选择流程**:引导玩家从世界地图选择目标区域,再到目标地图内选择精确弹着点。 +* **管理武器状态与属性**:存储远程目标信息,并根据已安装的升级动态计算射程、散布等属性。 +* **发起射击指令**:在获取有效目标后,命令自身的武器组件(Verb)开火。 + +#### 源代码 + +```csharp +using System; +using System.Collections.Generic; +using System.Linq; +using Multiplayer.API; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace Rimatomics +{ + [StaticConstructorOnStartup] + public class Building_Railgun : Building_EnergyWeapon + { + public override bool TurretBased + { + get + { + return true; + } + } + + public override Vector3 TipOffset + { + get + { + Vector3 pos = this.DrawPos; + Vector3 vecOffset = new Vector3(0f, 1f, 5f); + vecOffset = vecOffset.RotatedBy(this.TurretRotation); + return pos + vecOffset; + } + } + + public override bool CanFireWhileRoofed() + { + // For remote fire missions, cannot be roofed. For local targets, it's allowed. + if (this.longTargetInt == GlobalTargetInfo.Invalid) + { + return true; + } + return !base.Position.Roofed(base.Map); + } + + public float RangeToWorldTarget + { + get + { + return (float)Find.WorldGrid.TraversalDistanceBetween(base.Map.Tile, this.longTarget.Tile, true, int.MaxValue, false); + } + } + + public void TryChamberRound() + { + if (this.magazine.NullOrEmpty()) + { + return; + } + + CompChangeableProjectile comp = this.gun.TryGetComp(); + if (!comp.Loaded) + { + comp.LoadShell(this.magazine.FirstOrDefault(), 1); + this.magazine.RemoveAt(0); + } + } + + public override void MuzzleFlash() + { + Mote flash = (Mote)ThingMaker.MakeThing(Building_Railgun.Mote_RailgunMuzzleFlash, null); + flash.Scale = 5f; + flash.exactRotation = this.TurretRotation; + flash.exactPosition = this.TipOffset; + GenSpawn.Spawn(flash, base.Position, base.Map, WipeMode.Vanish); + + Vector3 vecOffset = new Vector3(1f, 1f, -1f).RotatedBy(this.TurretRotation); + FleckMaker.ThrowSmoke(this.DrawPos + vecOffset, base.Map, 1.5f); + + Vector3 vecOffset2 = new Vector3(-1f, 1f, -1f).RotatedBy(this.TurretRotation); + FleckMaker.ThrowSmoke(this.DrawPos + vecOffset2, base.Map, 1.5f); + } + + public override IEnumerable GetGizmos() + { + foreach (Gizmo c in base.GetGizmos()) + { + yield return c; + } + + Command_Action launch = new Command_Action + { + defaultLabel = "critCommandFireMission".Translate(), + defaultDesc = "critCommandFireMissionDesc".Translate(), + icon = Building_Railgun.FireMissionTex, + action = new Action(this.StartChoosingDestination) + }; + + if (base.Spawned && base.Position.Roofed(base.Map)) + { + launch.Disable("CannotFire".Translate() + ": " + "Roofed".Translate().CapitalizeFirst()); + } + yield return launch; + } + + private void StartChoosingDestination() + { + // Record all selected railguns to fire them simultaneously + this.selectedRailguns = Find.Selector.SelectedObjects.OfType().ToList(); + + CameraJumper.TryJump(CameraJumper.GetWorldTarget(this), CameraJumper.MovementMode.Pan); + Find.WorldSelector.ClearSelection(); + + int tile = base.Map.Tile; + Find.WorldTargeter.BeginTargeting( + new Func(this.ChoseWorldTarget), // Callback when target is chosen + false, + Building_Railgun.FireMissionTex, + true, + () => GenDraw.DrawWorldRadiusRing(tile, this.WorldRange, null), // Draws the range ring + null, null, null, false); + } + + public static TargetingParameters ForFireMission() + { + // In multiplayer, disallow targeting mobile pawns to prevent desync issues. + if (MP.IsInMultiplayer) + { + return new TargetingParameters + { + canTargetPawns = false, + canTargetBuildings = false, + canTargetLocations = true + }; + } + + return new TargetingParameters + { + canTargetPawns = true, + canTargetBuildings = true, + canTargetLocations = true + }; + } + + private bool ChoseWorldTarget(GlobalTargetInfo target) + { + if (!target.IsValid) + { + Messages.Message("MessageRailgunTargetInvalid".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + + int distance = Find.WorldGrid.TraversalDistanceBetween(base.Map.Tile, target.Tile, true, int.MaxValue, false); + if (distance > this.WorldRange) + { + Messages.Message("MessageTargetBeyondMaximumRange".Translate(), this, MessageTypeDefOf.RejectInput, true); + return false; + } + + MapParent mapParent = target.WorldObject as MapParent; + if (mapParent != null && mapParent.HasMap) + { + if (mapParent.Map == base.Map) + { + Messages.Message("MessageRailgunCantTargetMyMap".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + + // --- Refactored Code Block --- + // This block handles the logic for fine-grained targeting within the destination map. + Map targetMap = mapParent.Map; + var originalMap = base.Map; + + // Action to execute when targeting is finished or cancelled. + Action onFinished = () => { + if (Current.Game.CurrentMap != originalMap) + { + Current.Game.CurrentMap = originalMap; + } + }; + + // Switch to the target map to allow the player to pick a precise location. + Current.Game.CurrentMap = targetMap; + + Find.Targeter.BeginTargeting( + Building_Railgun.ForFireMission(), + (LocalTargetInfo localTarget) => // Lambda for when a local target is selected + { + // Assign the fire mission to all selected railguns. + foreach (Building_Railgun railgun in this.selectedRailguns) + { + railgun.FireMission(targetMap.Tile, localTarget, targetMap.uniqueID); + } + }, + null, // Action on highlight + onFinished, // Action on finish/cancel + Building_Railgun.FireMissionTex, + true); + + return true; + } + else + { + Messages.Message("MessageRailgunNeedsMap".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + } + + [SyncMethod(SyncContext.None)] + public void FireMission(int tile, LocalTargetInfo targ, int map) + { + if (!targ.IsValid) + { + this.longTargetInt = GlobalTargetInfo.Invalid; + return; + } + + GlobalTargetInfo newtarget = targ.ToGlobalTargetInfo(Find.Maps.FirstOrDefault((Map x) => x.uniqueID == map)); + int distance = Find.WorldGrid.TraversalDistanceBetween(base.Map.Tile, tile, true, int.MaxValue, false); + + if (distance > this.WorldRange) + { + Messages.Message("MessageTargetBeyondMaximumRange".Translate(), this, MessageTypeDefOf.RejectInput, true); + return; + } + + if (this.holdFire) + { + Messages.Message("MessageTurretWontFireBecauseHoldFire".Translate(this.def.label), this, MessageTypeDefOf.RejectInput, true); + return; + } + + if (this.longTargetInt != newtarget) + { + this.longTargetInt = newtarget; + if (this.burstCooldownTicksLeft <= 0) + { + this.TryStartShootSomething(); + } + SoundDefOf.TurretAcquireTarget.PlayOneShot(new TargetInfo(base.Position, base.Map, false)); + } + } + + public override float PulseSize + { + get + { + float f = base.GunProps.EnergyWep.PulseSizeScaled; + if (this.UG.HasUpgrade(DubDef.MEPS)) + { + f *= 1.15f; + } + if (this.UG.HasUpgrade(DubDef.ERS)) + { + f *= 0.85f; // Equivalent to f -= 0.15f * f + } + return f; + } + } + + public override int WorldRange + { + get + { + // In space (SoS2 compatibility), range is unlimited. + if (base.Map != null && this.space != null && base.Map.Biome == this.space) + { + return 99999; + } + + int range = base.GunProps.EnergyWep.WorldRange; + if (this.UG.HasUpgrade(DubDef.TargetingChip)) + { + range += 10; + } + if (this.UG.HasUpgrade(DubDef.MEPS)) + { + range += 10; + } + return range; + } + } + + public int spread + { + get + { + int v = 6; + if (this.UG.HasUpgrade(DubDef.TargetingChip)) + { + v -= 3; + } + return v; + } + } + + public static readonly Texture2D FireMissionTex = ContentFinder.Get("Rimatomics/UI/FireMission", true); + public static ThingDef Mote_RailgunMuzzleFlash = ThingDef.Named("Mote_RailgunMuzzleFlash"); + private List selectedRailguns; + public BiomeDef space = DefDatabase.GetNamed("OuterSpaceBiome", false); + } +} +``` + +#### 关键方法和属性详解 + +* **`GetGizmos()`**: 为炮塔添加“火控任务” (Fire Mission) 按钮,这是远程打击流程的起点。如果炮塔被屋顶遮挡,该按钮会被禁用。 +* **`StartChoosingDestination()`**: 响应按钮点击,将视角切换到世界地图,并启动一个带射程圈的目标选择器,让玩家选择目标地块。它支持多炮塔同时选择。 +* **`ChoseWorldTarget(GlobalTargetInfo target)`**: 当玩家在世界地图上选择目标后的回调函数。它会进行一系列合法性验证(如射程、是否为当前地图等),如果通过,则将视角切换到目标地图,让玩家选择精确落点。 +* **`FireMission(int tile, LocalTargetInfo targ, int map)`**: 这是目标选择的最后一步。它将最终的、精确的目标信息(包含地块ID和地图内坐标)存入 `longTargetInt` 变量,并立即尝试触发射击 (`TryStartShootSomething()`)。该方法支持多人游戏同步。 +* **`WorldRange` (get)**: 一个计算属性,返回炮塔在世界地图上的最大射程。基础射程定义在XML中,并会受到 `TargetingChip` 和 `MEPS` 等升级的加成。 +* **`spread` (get)**: 计算属性,返回炮弹的散布半径。`TargetingChip` 升级可以减小此值,提高精度。 +* **`CanFireWhileRoofed()`**: 重写方法,规定在执行远程打击 (`longTargetInt` 有效) 时,炮塔不能处于屋顶之下。 + +### 3.2 `Verb_Railgun` + +`Verb_Railgun` 继承自 `Verb_RimatomicsVerb`,它定义了电磁炮武器的“射击”这个核心动作。它不处理玩家交互,只负责执行射击逻辑。 + +#### 功能概述 + +这个类的主要职责是根据炮塔当前的目标状态(本地目标 vs 远程目标),决定执行哪种射击模式。 + +* **动态炮弹选择**: 根据 `CompChangeableProjectile` 组件的状态,决定是发射已装填的特殊炮弹还是默认炮弹。 +* **射击模式分发**: 检查是否存在远程目标 (`longTarget`),如果存在,则执行“火控任务”流程;否则,执行标准的本地射击。 +* **远程打击发起**: 在“火控任务”模式下,负责创建并初始化 `WorldObject_Sabot`,将其发射到世界地图。 +* **本地打击后效**: 为本地射击附加额外的效果,如能量消耗、数据收集和屏幕震动。 + +#### 源代码 + +```csharp +using System; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; + +namespace Rimatomics +{ + [StaticConstructorOnStartup] + public class Verb_Railgun : Verb_RimatomicsVerb + { + public override ThingDef Projectile + { + get + { + ThingWithComps equipmentSource = base.EquipmentSource; + CompChangeableProjectile comp = (equipmentSource != null) ? equipmentSource.GetComp() : null; + if (comp != null && comp.Loaded) + { + return comp.Projectile; + } + return this.verbProps.defaultProjectile; + } + } + + public override bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ) + { + // If a long-range target is set, we can "hit" it regardless of local range. + if (base.GetWep.longTarget.IsValid) + { + return true; + } + return base.CanHitTargetFrom(root, targ); + } + + protected bool TryCastFireMission() + { + Building_Railgun railgun = this.caster as Building_Railgun; + + // Create the flying sabot object on the world map + WorldObject_Sabot sabot = (WorldObject_Sabot)WorldObjectMaker.MakeWorldObject(DefDatabase.GetNamed("Sabot", true)); + sabot.railgun = railgun; + sabot.Tile = railgun.Map.Tile; + sabot.destinationTile = railgun.longTarget.Tile; + sabot.destinationCell = railgun.longTarget.Cell; + sabot.spread = railgun.spread; + sabot.Projectile = this.Projectile; + Find.WorldObjects.Add(sabot); + + // Post-launch effects and data gathering + railgun.GatherData("PPCWeapon", 5f); + railgun.GatherData("PPCFireMission", 10f); + railgun.GatherData("PPCRailgun", 10f); + railgun.PrototypeBang(railgun.GunProps.EnergyWep.PrototypeFailureChance); + railgun.MuzzleFlash(); + Find.CameraDriver.shaker.SetMinShake(0.1f); + + // Spawn a dummy projectile that flies off-map. This is for visual effect only. + Vector3 shellDirection = Vector3.forward.RotatedBy(railgun.TurretRotation); + IntVec3 outcell = (railgun.DrawPos + shellDirection * 500f).ToIntVec3(); + Projectile projectile2 = (Projectile)GenSpawn.Spawn(this.Projectile, railgun.Position, this.caster.Map, WipeMode.Vanish); + projectile2.Launch(railgun, railgun.DrawPos, outcell, null, ProjectileHitFlags.None, false, base.EquipmentSource, null); + + // Handle shell consumption + CompChangeableProjectile comp = base.EquipmentSource?.GetComp(); + if (comp != null) + { + comp.Notify_ProjectileLaunched(); + } + + railgun.DissipateCharge(railgun.PulseSize); + return true; + } + + public override bool TryCastShot() + { + Building_Railgun railgun = this.caster as Building_Railgun; + if (!railgun.top.TargetInSights) + { + return false; + } + if (this.Projectile == null) + { + return false; + } + + bool shotResult; + // --- Shooting Mode Dispatch --- + if (railgun.longTarget.IsValid) + { + // Execute long-range fire mission + shotResult = this.TryCastFireMission(); + } + else + { + // Execute standard local shot + shotResult = base.TryCastShot(); + if (shotResult) + { + railgun.DissipateCharge(railgun.PulseSize); + railgun.GatherData("PPCWeapon", 5f); + railgun.GatherData("PPCRailgun", 10f); + railgun.PrototypeBang(railgun.GunProps.EnergyWep.PrototypeFailureChance); + railgun.MuzzleFlash(); + Find.CameraDriver.shaker.SetMinShake(0.1f); + } + } + + // Chamber the next round after firing + railgun.TryChamberRound(); + return shotResult; + } + } +} +``` + +#### 关键方法和属性详解 + +* **`Projectile` (get)**: 这是一个动态属性,用于获取当前应该发射的炮弹类型。它会优先返回 `CompChangeableProjectile` 中已装填的炮弹,如果未装填,则返回在 XML 中定义的默认炮弹。 +* **`CanHitTargetFrom(...)`**: 重写了基类方法。当炮塔被赋予了一个远程目标 (`longTarget.IsValid`) 时,该方法直接返回 `true`,绕过了所有常规的射程和视线检查,确保远程打击流程可以启动。 +* **`TryCastShot()`**: 这是射击动作的入口点。它的核心逻辑是检查 `railgun.longTarget` 是否有效。 + * 如果**有效**,说明是远程打击任务,它便调用 `TryCastFireMission()`。 + * 如果**无效**,说明是常规的本地瞄准,它就调用基类的 `base.TryCastShot()` 来发射普通炮弹,并附加一系列开火后效。 +* **`TryCastFireMission()`**: 这是发起远程打击的核心。它不直接生成命中目标的炮弹,而是: + 1. 创建一个 `WorldObject_Sabot` 实例。 + 2. 将目标地块、精确坐标、炮弹类型、散布等关键信息从 `Building_Railgun` 传递给 `sabot` 对象。 + 3. 将 `sabot` 添加到世界对象管理器 (`Find.WorldObjects.Add(sabot)`),让其开始在世界地图上“飞行”。 + 4. 触发炮口闪光、能量消耗、屏幕震动等本地开火效果。 + 5. 生成一个飞向地图外的“虚拟”炮弹,仅用于视觉表现,它不会造成任何伤害。 + +### 3.3 `WorldObject_Sabot` + +`WorldObject_Sabot` 继承自 `WorldObject`,是远程打击流程中的“飞行”阶段的执行者。它是一个临时的、在世界地图上存在的实体,模拟了炮弹从发射点到目标点的飞行过程。 + +#### 功能概述 + +此类完全独立于发射它的炮塔,其核心职责是在世界地图上完成一段旅程,并在抵达终点时触发命中效果。 + +* **飞行轨迹模拟**: 通过 `DrawPos` 属性和 `Tick` 方法,平滑地计算并更新自身在世界地图上的位置,实现飞行-动画效果。 +* **状态持久化**: 通过 `ExposeData` 方法保存所有关键信息(如起点、终点、飞行进度、炮弹类型),确保在游戏存读档后飞行可以继续。 +* **命中触发**: 在飞行到达终点后,`Arrived` 方法负责在目标地图上生成真正的 `Projectile`(炮弹),并让其从地图边缘发射,命中最终的精确弹着点。 +* **自我销毁**: 完成命中逻辑后,将自身从世界对象管理器中移除。 +* **Mod兼容性**: 能够识别并处理 "Save Our Ship 2" Mod 中的轨道飞船,实现地对空、空对地和空对空打击。 + +#### 源代码 + +```csharp +using System; +using System.Linq; +using RimWorld.Planet; +using UnityEngine; +using Verse; + +namespace Rimatomics +{ + public class WorldObject_Sabot : WorldObject + { + private Vector3 Start + { + get + { + Vector3 startPos = Find.WorldGrid.GetTileCenter(this.initialTile); + // SoS2 compatibility: if a ship is at the tile, use its position. + if (HarmonyPatches.SoS) + { + WorldObject ship = Find.World.worldObjects.AllWorldObjects.FirstOrDefault(o => + (o.def.defName.Equals("ShipOrbiting") || o.def.defName.Equals("SiteSpace")) && o.Tile == this.initialTile); + if (ship != null) + { + startPos = ship.DrawPos; + } + } + return startPos; + } + } + + private Vector3 End + { + get + { + Vector3 endPos = Find.WorldGrid.GetTileCenter(this.destinationTile); + // SoS2 compatibility + if (HarmonyPatches.SoS) + { + WorldObject ship = Find.World.worldObjects.AllWorldObjects.FirstOrDefault(o => + (o.def.defName.Equals("ShipOrbiting") || o.def.defName.Equals("SiteSpace")) && o.Tile == this.destinationTile); + if (ship != null) + { + endPos = ship.DrawPos; + } + } + return endPos; + } + } + + public override Vector3 DrawPos + { + get + { + // Slerp for a smooth curve over the planet's surface + return Vector3.Slerp(this.Start, this.End, this.traveledPct); + } + } + + private float TraveledPctStepPerTick + { + get + { + Vector3 start = this.Start; + Vector3 end = this.End; + if (start == end) return 1f; + + float distance = GenMath.SphericalDistance(start.normalized, end.normalized); + if (distance == 0f) return 1f; + + // Travel speed is constant + return TravelSpeed / distance; + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref this.destinationTile, "destinationTile", 0, false); + Scribe_Values.Look(ref this.destinationCell, "destinationCell", default(IntVec3), false); + Scribe_Values.Look(ref this.arrived, "arrived", false, false); + Scribe_Values.Look(ref this.initialTile, "initialTile", 0, false); + Scribe_Values.Look(ref this.traveledPct, "traveledPct", 0f, false); + Scribe_Defs.Look(ref this.Projectile, "Projectile"); + Scribe_References.Look(ref this.railgun, "railgun"); + Scribe_Values.Look(ref this.spread, "spread", 1, false); + } + + public override void PostAdd() + { + base.PostAdd(); + this.initialTile = base.Tile; + } + + public override void Tick() + { + base.Tick(); + this.traveledPct += this.TraveledPctStepPerTick; + if (this.traveledPct >= 1f) + { + this.traveledPct = 1f; + this.Arrived(); + } + } + + private void Arrived() + { + if (this.arrived) return; + this.arrived = true; + + Map map = Current.Game.FindMap(this.destinationTile); + if (map != null) + { + // Spawn the projectile at the edge of the map + IntVec3 entryCell = new IntVec3(CellRect.WholeMap(map).Width / 2, 0, CellRect.WholeMap(map).maxZ); + Projectile projectile = (Projectile)GenSpawn.Spawn(this.Projectile, entryCell, map, WipeMode.Vanish); + + // Find a random cell near the target destination within the spread radius + IntVec3 finalDestination; + CellFinder.TryFindRandomCellNear(this.destinationCell, map, this.spread, null, out finalDestination, -1); + + // Launch the projectile to the final destination + projectile.Launch(this.railgun, finalDestination, finalDestination, ProjectileHitFlags.IntendedTarget, false, null); + } + + // Remove self from the world + Find.WorldObjects.Remove(this); + } + + private const float TravelSpeed = 0.0001f; + private bool arrived; + public IntVec3 destinationCell = IntVec3.Invalid; + public int destinationTile = -1; + private int initialTile = -1; + public ThingDef Projectile; + public Thing railgun; + public int spread = 1; + private float traveledPct; + } +} +``` + +#### 关键方法和属性详解 + +* **`Start` / `End` (get)**: 这两个属性负责计算飞行的起点和终点坐标。它们通过检查 `HarmonyPatches.SoS` 来判断是否加载了 "Save Our Ship 2" Mod,如果加载了,则会尝试获取轨道上飞船的位置作为起点/终点,从而实现与该Mod的无缝兼容。 +* **`DrawPos` (get)**: 重写属性,用于在世界地图上渲染该对象。它使用 `Vector3.Slerp`(球面线性插值)在起点和终点之间进行插值,根据 `traveledPct`(已飞行百分比)计算出当前帧应该在的位置,从而形成一条平滑的弧形飞行轨迹。 +* **`Tick()`**: 游戏引擎为每个世界对象调用的更新方法。它在每一帧增加 `traveledPct` 来推进飞行进度。当 `traveledPct` 达到1时,调用 `Arrived()`。 +* **`Arrived()`**: 这是飞行结束、触发命中的核心方法。它首先检查目标地块是否存在一个已加载的地图。如果存在,它会在该地图的边缘生成 `Projectile` 实体,并根据 `spread`(散布)在目标点附近随机一个最终落点,然后调用炮弹的 `Launch()` 方法完成最后的攻击。无论地图是否存在,它最终都会将自己从世界上移除。 +* **`ExposeData()`**: 保证了该飞行物体的所有状态(起点、终点、进度、炮弹类型等)都能被正确地保存和加载。 + +## 4. 系统工作流程 + +现在我们将三个核心组件联系起来,详细描述从玩家点击按钮到炮弹命中的完整工作流程。 + +### 4.1 交互时序图 + +下面的 Mermaid 时序图直观地展示了不同对象之间的交互顺序。 + +```mermaid +sequenceDiagram + participant Player as 玩家 + participant Railgun as Building_Railgun + participant Verb as Verb_Railgun + participant Sabot as WorldObject_Sabot + participant Projectile as 最终炮弹 + + Player->>Railgun: 点击 "Fire Mission" 按钮 + activate Railgun + Railgun->>Player: 显示世界地图和射程圈 + Player->>Railgun: 1. 选择世界目标 (地块) + Player->>Railgun: 2. 选择地图内目标 (坐标) + Railgun->>Railgun: 调用 FireMission() 设置 longTarget + Railgun->>Verb: 调用 TryStartShootSomething() + deactivate Railgun + + activate Verb + Verb->>Verb: TryCastShot() 检测到 longTarget + Verb->>Verb: 调用 TryCastFireMission() + Verb->>Sabot: new WorldObject_Sabot() + activate Sabot + Verb->>Sabot: 传递目标信息、炮弹类型等 + Verb-->>Player: 触发炮口闪光和声音 + deactivate Verb + + loop 飞行过程 (每Tick) + Sabot->>Sabot: 更新 traveledPct (飞行进度) + end + + Sabot->>Sabot: Arrived() - 到达目标 + Sabot->>Projectile: GenSpawn.Spawn(炮弹) + activate Projectile + Sabot->>Projectile: Launch() - 飞向最终落点 + Projectile-->>Player: 爆炸和伤害效果 + deactivate Projectile + + Sabot->>Sabot: Find.WorldObjects.Remove(this) + deactivate Sabot +``` + +### 4.2 步骤分解 + +1. **启动与目标选择 (玩家 -> `Building_Railgun`)** + * 玩家选中一门或多门 `Building_Railgun` 并点击其 "Fire Mission" Gizmo。 + * `GetGizmos` 触发 `StartChoosingDestination` 方法,视角切换至世界地图,并显示最大射程圈。 + * 玩家在世界地图上选择一个目标地块。 + * `ChoseWorldTarget` 方法被回调。在通过一系列验证后,视角切换到目标地图。 + * 玩家在目标地图上选择一个精确的弹着点。 + +2. **下达指令 (`Building_Railgun` -> `Verb_Railgun`)** + * 当精确弹着点被选定后,`ChoseWorldTarget` 方法会为所有被选中的炮塔调用 `FireMission` 方法。 + * `FireMission` 将包含地块和坐标的 `GlobalTargetInfo` 存入炮塔的 `longTarget` 变量中。 + * `FireMission` 随即调用 `TryStartShootSomething()`,这会启动炮塔的射击冷却计时器,并最终触发其Verb组件。 + +3. **发射与创建飞行物 (`Verb_Railgun` -> `WorldObject_Sabot`)** + * 炮塔的 `Verb_Railgun` 组件的 `TryCastShot` 方法被调用。 + * `TryCastShot` 检测到 `longTarget` 是有效的,因此它不会执行常规射击,而是调用 `TryCastFireMission`。 + * `TryCastFireMission` 创建一个 `WorldObject_Sabot` 的实例,并将目标信息、炮弹定义、散布等关键数据从 `Building_Railgun` 复制到这个新实例中。 + * `WorldObject_Sabot` 被添加到 `Find.WorldObjects` 管理器中,正式开始其生命周期。 + * 同时,`Verb_Railgun` 在本地触发开火的视觉和听觉效果。 + +4. **跨地图飞行 (`WorldObject_Sabot`)** + * `WorldObject_Sabot` 作为一个独立的世界对象,其 `Tick` 方法被游戏引擎在每一帧调用。 + * `Tick` 方法不断更新 `traveledPct` 属性,模拟飞行进度。 + * 其 `DrawPos` 属性根据 `traveledPct` 在世界地图上平滑地渲染出飞行轨迹。 + +5. **抵达与命中 (`WorldObject_Sabot` -> `Projectile`)** + * 当 `traveledPct` 达到100%时,`Arrived` 方法被调用。 + * `Arrived` 检查目标地块的地图是否已加载。 + * 如果地图已加载,它会在地图边缘 `GenSpawn.Spawn` 一个真正的 `Projectile`(最终炮弹)。 + * 根据从 `Building_Railgun` 继承来的 `spread` 值,在玩家指定的精确落点附近随机一个最终弹着点。 + * 调用 `Projectile.Launch()`,使其从地图边缘飞向并命中最终弹着点,产生爆炸和伤害。 + * 最后,`WorldObject_Sabot` 调用 `Find.WorldObjects.Remove(this)` 将自己从世界上移除,完成其使命。 + +## 5. 总结 + +Rimatomics的电磁炮系统是一个设计精良的远程打击模块。它通过将**交互(Building)**、**动作(Verb)**和**飞行(WorldObject)**三个阶段清晰地分离到不同的类中,实现了高度的内聚和低耦合。这种设计不仅使得代码逻辑清晰、易于维护,还通过 `WorldObject` 机制优雅地解决了跨地图状态同步和持久化的问题,并为兼容其他Mod(如Save Our Ship 2)留出了接口。 diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index b5ad875..4e1f258 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -208,6 +208,11 @@ + + + + + diff --git a/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs b/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs new file mode 100644 index 0000000..1ce483e --- /dev/null +++ b/Source/ArachnaeSwarm/Buildings/Building_CatastropheMissileSilo.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace ArachnaeSwarm +{ + [StaticConstructorOnStartup] + public class Building_CatastropheMissileSilo : Building_TurretGun + { + public GlobalTargetInfo longTarget; + + public static readonly Texture2D FireMissionTex = ContentFinder.Get("UI/Commands/Attack", true); + + public override void ExposeData() + { + base.ExposeData(); + Scribe_TargetInfo.Look(ref this.longTarget, "longTarget"); + } + + public override IEnumerable GetGizmos() + { + foreach (Gizmo c in base.GetGizmos()) + { + yield return c; + } + + // Gizmo to set the long range target + Command_Action setTarget = new Command_Action + { + defaultLabel = "CommandSetGlobalTarget".Translate(), + defaultDesc = "CommandSetGlobalTargetDesc".Translate(), + icon = FireMissionTex, + action = new Action(this.StartChoosingDestination) + }; + if (!this.powerComp.PowerOn) + { + setTarget.Disable("NoPower".Translate().CapitalizeFirst()); + } + yield return setTarget; + + // Gizmo to clear the long range target + if (this.longTarget.IsValid) + { + Command_Action clearTarget = new Command_Action + { + defaultLabel = "CommandClearGlobalTarget".Translate(), + defaultDesc = "CommandClearGlobalTargetDesc".Translate(), + icon = ContentFinder.Get("UI/Commands/Cancel"), + action = () => { this.longTarget = GlobalTargetInfo.Invalid; } + }; + yield return clearTarget; + } + } + + private void StartChoosingDestination() + { + CameraJumper.TryJump(CameraJumper.GetWorldTarget(this), CameraJumper.MovementMode.Pan); + Find.WorldSelector.ClearSelection(); + + Find.WorldTargeter.BeginTargeting( + new Func(this.ChoseWorldTarget), + true, + FireMissionTex, + true, + () => GenDraw.DrawWorldRadiusRing(this.Map.Tile, 99999), + null, null, null, true); + } + + private bool ChoseWorldTarget(GlobalTargetInfo target) + { + if (!target.IsValid) + { + Messages.Message("MessageTargetInvalid".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + if (target.Map == this.Map) + { + Messages.Message("Cannot target own map for global strike.", MessageTypeDefOf.RejectInput, true); + return false; + } + + // The target must be a map parent that has a loaded map. + if (target.WorldObject is MapParent mapParent && mapParent.HasMap) + { + var originalMap = this.Map; + Action onFinished = () => { + if (Current.Game.CurrentMap != originalMap) Current.Game.CurrentMap = originalMap; + }; + + Current.Game.CurrentMap = mapParent.Map; + Find.Targeter.BeginTargeting(new TargetingParameters { canTargetLocations = true }, + (LocalTargetInfo localTarget) => // This is called when the user clicks a cell in the target map + { + this.FireMission(new GlobalTargetInfo(localTarget.Cell, mapParent.Map)); + }, + null, onFinished, FireMissionTex, true); + + return true; + } + else + { + Messages.Message("MessageTargetMustBeMap".Translate(), MessageTypeDefOf.RejectInput, true); + return false; + } + } + + public void FireMission(GlobalTargetInfo target) + { + this.longTarget = target; + this.OrderAttack(new LocalTargetInfo(this)); + Messages.Message("Global target acquired. Firing sequence initiated.", MessageTypeDefOf.PositiveEvent); + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Comps/CompForceTargetable.cs b/Source/ArachnaeSwarm/Comps/CompForceTargetable.cs new file mode 100644 index 0000000..da82707 --- /dev/null +++ b/Source/ArachnaeSwarm/Comps/CompForceTargetable.cs @@ -0,0 +1,18 @@ +using Verse; + +namespace ArachnaeSwarm +{ + public class CompProperties_ForceTargetable : CompProperties + { + public CompProperties_ForceTargetable() + { + this.compClass = typeof(CompForceTargetable); + } + } + + public class CompForceTargetable : ThingComp + { + // This component doesn't need any specific logic. + // Its mere presence on a turret is checked by the Harmony patch. + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/HarmonyPatches/Patch_ForceTargetable.cs b/Source/ArachnaeSwarm/HarmonyPatches/Patch_ForceTargetable.cs new file mode 100644 index 0000000..716e922 --- /dev/null +++ b/Source/ArachnaeSwarm/HarmonyPatches/Patch_ForceTargetable.cs @@ -0,0 +1,23 @@ +using HarmonyLib; +using Verse; +using RimWorld; + +namespace ArachnaeSwarm +{ + [HarmonyPatch(typeof(Building_TurretGun), "get_CanSetForcedTarget")] + public static class Patch_Building_TurretGun_CanSetForcedTarget + { + public static void Postfix(Building_TurretGun __instance, ref bool __result) + { + if (__result) + { + return; + } + + if (__instance.GetComp() != null && __instance.Faction == Faction.OfPlayer) + { + __result = true; + } + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Verbs/Verb_LaunchCatastropheMissile.cs b/Source/ArachnaeSwarm/Verbs/Verb_LaunchCatastropheMissile.cs new file mode 100644 index 0000000..e963a9a --- /dev/null +++ b/Source/ArachnaeSwarm/Verbs/Verb_LaunchCatastropheMissile.cs @@ -0,0 +1,78 @@ +using RimWorld; +using RimWorld.Planet; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace ArachnaeSwarm +{ + public class Verb_LaunchCatastropheMissile : Verb_Shoot + { + public override bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ) + { + var silo = this.Caster as Building_CatastropheMissileSilo; + if (silo != null && silo.longTarget.IsValid) + { + return true; + } + return base.CanHitTargetFrom(root, targ); + } + + protected override bool TryCastShot() + { + var silo = this.Caster as Building_CatastropheMissileSilo; + + if (silo != null && silo.longTarget.IsValid) + { + return this.TryCastGlobalShot(silo); + } + + // If no long target, perform a normal local shot + return base.TryCastShot(); + } + + private bool TryCastGlobalShot(Building_CatastropheMissileSilo silo) + { + var refuelableComp = silo.TryGetComp(); + if (refuelableComp != null && !refuelableComp.HasFuel) + { + Messages.Message("NoMissileToLaunch".Translate(), silo, MessageTypeDefOf.RejectInput); + return false; + } + + WorldObject_CatastropheMissile missile = (WorldObject_CatastropheMissile)WorldObjectMaker.MakeWorldObject( + DefDatabase.GetNamed("CatastropheMissile_Flying") + ); + + missile.Tile = silo.Map.Tile; + missile.destinationTile = silo.longTarget.Tile; + missile.destinationCell = silo.longTarget.Cell; + missile.Projectile = DefDatabase.GetNamed("Projectile_CatastropheMissile"); + + Find.WorldObjects.Add(missile); + + if(refuelableComp != null) + { + refuelableComp.ConsumeFuel(1); + } + + SoundDef.Named("RocketLaunch").PlayOneShot(new TargetInfo(silo.Position, silo.Map)); + + // Reset target after launch + silo.longTarget = GlobalTargetInfo.Invalid; + + // Manually reset cooldown + if (this.burstShotsLeft < this.verbProps.burstShotCount) + { + this.burstShotsLeft = 0; + } + if (this.verbProps.burstShotCount > 0) + { + this.ticksToNextBurstShot = this.verbProps.ticksBetweenBurstShots; + } + this.state = VerbState.Idle; + + return true; + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs b/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs new file mode 100644 index 0000000..7c99942 --- /dev/null +++ b/Source/ArachnaeSwarm/World/WorldObject_CatastropheMissile.cs @@ -0,0 +1,73 @@ +using RimWorld.Planet; +using UnityEngine; +using Verse; +using RimWorld; + +namespace ArachnaeSwarm +{ + public class WorldObject_CatastropheMissile : WorldObject + { + public int destinationTile = -1; + public IntVec3 destinationCell = IntVec3.Invalid; + public ThingDef Projectile; + + private int initialTile = -1; + private float traveledPct; + private const float TravelSpeed = 0.0002f; // Faster than sabot + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Values.Look(ref destinationTile, "destinationTile", 0); + Scribe_Values.Look(ref destinationCell, "destinationCell"); + Scribe_Defs.Look(ref Projectile, "Projectile"); + Scribe_Values.Look(ref initialTile, "initialTile", 0); + Scribe_Values.Look(ref traveledPct, "traveledPct", 0f); + } + + public override void PostAdd() + { + base.PostAdd(); + this.initialTile = this.Tile; + } + + private Vector3 StartPos => Find.WorldGrid.GetTileCenter(this.initialTile); + private Vector3 EndPos => Find.WorldGrid.GetTileCenter(this.destinationTile); + + public override Vector3 DrawPos => Vector3.Slerp(StartPos, EndPos, traveledPct); + + protected override void Tick() + { + base.Tick(); + float distance = GenMath.SphericalDistance(StartPos.normalized, EndPos.normalized); + if(distance > 0) + { + traveledPct += TravelSpeed / distance; + } + else + { + traveledPct = 1; + } + + if (traveledPct >= 1f) + { + Arrived(); + } + } + + private void Arrived() + { + Map targetMap = Current.Game.FindMap(this.destinationTile); + if (targetMap != null) + { + // Target is a loaded map, spawn the projectile to hit it + IntVec3 entryCell = CellFinder.RandomEdgeCell(targetMap); + + Projectile_CruiseMissile missile = (Projectile_CruiseMissile)GenSpawn.Spawn(this.Projectile, entryCell, targetMap, WipeMode.Vanish); + missile.Launch(null, this.destinationCell, this.destinationCell, ProjectileHitFlags.IntendedTarget); + } + + Find.WorldObjects.Remove(this); + } + } +} \ No newline at end of file