From adacdf533cee4981b1f1ad3ac794968240e9ffeb Mon Sep 17 00:00:00 2001 From: funman300 Date: Sat, 25 Apr 2026 22:48:58 -0700 Subject: [PATCH] feat(engine,assetgen): synthesized SFX + kira AudioPlugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New solitaire_assetgen crate with gen_sfx binary: synthesizes five 44.1kHz mono 16-bit PCM WAVs (flip/place/deal/invalid/fanfare) from an LCG noise source + sine/square synths. Output committed under assets/audio/. - AudioPlugin (engine): embeds the WAVs via include_bytes!, decodes once with kira::StaticSoundData, plays on Draw / Move / NewGame / GameWon events. card_invalid is loaded but unused — wiring it needs a MoveRejectedEvent. - AudioManager kept on the main thread (NonSend) since cpal is !Send on some platforms; degrades gracefully if no audio device present. Co-Authored-By: Claude Opus 4.7 --- Cargo.lock | 4 + Cargo.toml | 1 + assets/audio/card_deal.wav | Bin 0 -> 15920 bytes assets/audio/card_flip.wav | Bin 0 -> 7100 bytes assets/audio/card_invalid.wav | Bin 0 -> 15920 bytes assets/audio/card_place.wav | Bin 0 -> 12392 bytes assets/audio/win_fanfare.wav | Bin 0 -> 85598 bytes docs/SESSION_HANDOFF.md | 19 ++- solitaire_app/src/main.rs | 7 +- solitaire_assetgen/Cargo.toml | 12 ++ solitaire_assetgen/src/bin/gen_sfx.rs | 207 ++++++++++++++++++++++++++ solitaire_engine/src/audio_plugin.rs | 177 ++++++++++++++++++++++ solitaire_engine/src/lib.rs | 2 + 13 files changed, 421 insertions(+), 8 deletions(-) create mode 100644 assets/audio/card_deal.wav create mode 100644 assets/audio/card_flip.wav create mode 100644 assets/audio/card_invalid.wav create mode 100644 assets/audio/card_place.wav create mode 100644 assets/audio/win_fanfare.wav create mode 100644 solitaire_assetgen/Cargo.toml create mode 100644 solitaire_assetgen/src/bin/gen_sfx.rs create mode 100644 solitaire_engine/src/audio_plugin.rs diff --git a/Cargo.lock b/Cargo.lock index 97aaa97..b3468da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5672,6 +5672,10 @@ dependencies = [ "solitaire_engine", ] +[[package]] +name = "solitaire_assetgen" +version = "0.1.0" + [[package]] name = "solitaire_core" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 768a383..f14bc35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "solitaire_server", "solitaire_gpgs", "solitaire_app", + "solitaire_assetgen", ] resolver = "2" diff --git a/assets/audio/card_deal.wav b/assets/audio/card_deal.wav new file mode 100644 index 0000000000000000000000000000000000000000..a429eb0d501cad128fec75c78e0dbc1042f2fdd0 GIT binary patch literal 15920 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 z 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 OC+GuJMgM(`U-5qjQKG{D literal 0 HcmV?d00001 diff --git a/assets/audio/card_invalid.wav b/assets/audio/card_invalid.wav new file mode 100644 index 0000000000000000000000000000000000000000..af0f4d337a4f053f6d1932a12d3234adfcf7edb5 GIT binary patch literal 15920 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%0DAqSI#$N^-3vLD%p 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 UfZbsqs6J4=AGS-i3-)sV54=<_c>n+a literal 0 HcmV?d00001 diff --git a/assets/audio/card_place.wav b/assets/audio/card_place.wav new file mode 100644 index 0000000000000000000000000000000000000000..2074b3b486e25c78dc2fbfc44dc05ddac70d54a8 GIT binary patch literal 12392 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 Q-7y>Ey~C?!W7NCwf94ee;Q#;t literal 0 HcmV?d00001 diff --git a/assets/audio/win_fanfare.wav b/assets/audio/win_fanfare.wav new file mode 100644 index 0000000000000000000000000000000000000000..1edaf610c683d75ea0d40f500d3c4f3b3375edc6 GIT binary patch literal 85598 zcmW(-WsuZp*G)Ptv34KD8Qk67^~IgV-CY-VSy&CK6Luf>hO0E z_!EIxk`jzDmn;l zgH}OpsEFhs&yn-UHe>-Z0_ljX@>k@*36(`>L3t&?_#Z15g6J1^?D!$R~N3TuuHi&6BLsu|%cBX)#S)A>_v!#Mi_= zMD5YOkv-vDz8b%p^RvTQAG3jJ%M@d5Ol4*?^OR}F2H0ENasFyJCsIDPHjav`63Oxv zq?^KvEmmnXi|}ls0@a5eq3x=(>#ysp8I~C?7_J+38u}UH`i1%;T_fEh?Irp@F51p6=e}_PghKnt1E`#`@m|Muf_-Hok16Pwb!| zCWas{6jfDgHJ=D2ZPTHK$Ht!KE0$l@x3*PwwWFh>pQDE3yS=;pfbF^Uo#n21tEs=y zZg{O*qHRD6N@(Px(D6SZZUO*CZJ9(q@Iw6at#5zLVc55!w_``saAV?!~UOqW=mm&UEN1viwLzC1#qAiYVeyRRdKE*yNe5e7fiwu)jOD7X|#eX0JcgIFY z(<2Y~j@(nGN@#81x38*qnLDefQ{nskX?YEDtK{^`zMj=Pt3lSNtY29NvoGZs@^0pz zD$H{A^kRYBke9PZ`v@nbINCmF5(AM!Vcl*}TvC-u}QjI{9hJ*VMgf zw)EENmD4|_)lVCpIxMAH@(<@o$9G#}>rQjf*uijCm!jQ8RUqHv>ofz^EmRGat+7Fh zCFoh?r%cKItMbO=&dIr( z-7s6oN@TUo&dk1>g%%(-q>VgX+LgE}J{0c8kH+Ri>qc_;S)9O34t<0A+2u{R$GVCN7Zg;@ z$MdwgEpsks56$kHy&_wg^C~ARw^4p>!P_FiJ=}){-!o76uTfO2C686?R9(k!QM+_q zjPK1!wvrAPe9^rrt5P%47Nu=S>z7uLS|{~?DNU1ANhciD?8mHn%M{Z`Lw)@zZ3cav z>_-^zpX$4+i^?0=8$}3BMY|wN=-J4SFv72ANoH;^$KTp_)|2es zUR18|zx)$}okVIlppC=3gjSTC~IM_D%~_WOTeCT3+~{vvxJ`|$-R)(ZSCfR~Xv*nSYg*kjd)n1hM{28-X33VMe;j@6U#zVy=S^1Q zLVZv>iB6DviSBrcCa&@-Lzo)NQ1n1oBKKrQDlWB2428&#jCYKsMSp~s@k!i%#vWP` z2>AMX|8=)=eJ)&B&^EtbUZ334IdyZe9AnP#962X9*O0%wph;0f_bji=zacb`>k{b~ zpPAT++``_gKM>dG>3XGUh~-b)9}d~sD|tjp`PAd7nW=A67pHP5)l(WLrzib%%(G** zc^0>+hw-7lmhKAOoXRG);{7#s)MZuWl#L)m*P!>1uv}RlDy>hP6(0x>;}>FUqunA{ z_%K(Ey%;JJ{M(QDW_TFaqN37;MfvaZ@^dTZp3E7RGcadQPVroSt}=f}0ajGxqP(O1 z(cl$!Yj{&^zj#yrpvYC_;LoU4x-{bw^EvAtdt2wZq&LY&Q);CyOkI-NI`vgba!Q@# zvPmJwZhIx$IZH|N79(buql?ljs8Zx-e3xdrdZ_9T_ z-W2Y3o$&a5V}eFDi+>e;BV@0L%t4Gv{e&E(XS`zcAO)l)U8 z2U6tZipk}ZQ0EPM4_l_CulcR9h2gfYq4oteinJ5oH5b);RJ)X?uzwXCS`HnK9F%`b zMyXL^pg2L85bqnS9*u-g@@=`V%z)5;fzJM?-d3LXuE|B^3$X%aevQ1Xxs`L3xhc7` zavgbcUZsKqg}q!IJoA0oftgHoULVB-wWLGMN?H>juF^gA&x~pdW&2?7?cAQUIk{EJ z<&?~nCn=LsvXWDh%O&ZY@9nc~q;-RtF#Tx|VUlX;Q)C~)iTl-GR3DUCn4~DD7>Mpf zzREVatMq5$xOiW98owRe8yy!Z6Mn;uWJ958!GM1(bf;NvtLsJK-hyrUH}iCPJ8}o* z4$D22TRTsapH?uZ(BTTZ4Zfj)oX|S1Po#0YR-y({4J)I@i8s_#o!d~&+{|jVpKwH- zSn~7awkb!NAiI>ILhA#xf0H-GbHgbyI-=W}y%`{r5ltp)uGvx`o;&w7jeJwjggcz9uKj5tW{p=hBhiMz>7TAg8_X{M!@ zEo|@UoRZWg`D=0+s39a}OL8y?lE4|WU$gbM`pq*3|DY(^99bbhlN3_TL|<`|Fe5%X)+TC+yn!xiWDkVO22cB|`R;rAxe3>Y!rKKe z^YQ#yd8v7FZhGF5yo`KPL9@b(MSr-vdT09I1pmh-_$SfB!g^^QI$YUIqaiQQ)%B~4 zr_Fy`Ti7o;emWl~jZA)$oSXb8d1UgZBz;nvQ{#ANTVzePoHA82Ue`C(y{9KoPN<|K zniYUYmMV8+j};NL209bDBO`JXX=dUOME+I$S?oe|d8BPP#_eXSG53RQ0`Gl8yn_3< zYkX0c!d?Zd^4;*l|K$zMyO7r`-&Rn$aCK2hx8R}tU4jppe!MA~6MvXEhOEZ^P?sg% zQ+;$-48KjEEE{a3qouP!QXpwa@}}fJlWQkmPLiA{PLre1cEH-o^20RR$mkd94BE3) zAJR-@X&$IAt8OaaVPVM75$H)IB-fSaN!JoZA}tmdO2w@)HgYdKn=irLXZ{z;4ovjR z-d&!SZj~#iFsFbl7?SVGJC%1lFE?*UezAfQg(HhRt}~wFzW)NXnY-MGNZEK?{7=55 zSgC4{bL2v8mfmbKS-x6_*iSkxI%gzBlIkTlNJf)4Cb^w9r_&L)-LsCj5azwc3Wi&{ zE?OV8o$N-W;)2?%3MiGz46L7GJNg4DiA;p4#3w2wdWlno1@W1&fzfIamOsk1XY)d{ zf_PxJuZ}m{z27ynXj0+&g0J~K^40lFUUL5O{Hg^hg&m4+x<+_9_(lex=W_SLQ)Bf+ zO3p&hD<^A`$YZot-^SR*T+DjargfBbMxASuGLu3{&yz+by?4^iR0nDQX5D0|4V`J2 zf!D3mR-nI-8;QPnElnwPX;ociKWwey8A_wQkVCRpswPcH?1gUsG5#s`IJ!SFHe8B- z&rV^;(EdPe|3~k9PaQYu5(`a*-3uP(kH~MD-zWcEeyf7i!dgWeT%|m`SMb*eZDZ5I zkE08OR+16@j_pu4C*D%^b@L2sO`|M?ZGwG^W41FnX;ISQq_s))ldd==N29Vymi(RhnJ|w^7M3X*>vFq~d3X5l z1hwok-Wh!sUzTWtkl16@cw8XIXwU1P8_$~iSzp-@2j@89OiAjN)INzw+T!#&oQ`z6 z%J$B(!d%(($}mcg>5kIfC<4&kNzGREX4QV>eaxpQs~C^oKr~2i`LI-!D3$0T&Jb3_ zm&c|?J4YPhkK7WrEb}xt46yxK?+8zIx5JfQ)S>WjL4^WW{;zyP!Qz4{g=s|{UDw?M zy$$>wgKL-|H#1_3KNFY8jTDS>rzV5kLFeg|M#gl?QqDHcKG9L#dCe(0RY{+n6P;fi zMn@^T&E~P3GWRt}hQ0bmx@>wq)rzEvT+J)>Gu20B5KF~+D|VxWNF8L2{7ot;4NvS6 z9|_;%*|Gnkw<7DIi>kN_Opj1Fu+!htCwTsGA9EcmdQoUE+)~iIAfupd!O?=Ig~>%V zU2EJa-h5w9K+F8WeG89`8N`RubhNbcxw<#;f^zDb80wf}=4IB8wtV{yM@Q#j=N;!B zXKUwOhuTrbUdpDlzA`U0RWg3i&(I}n|E2yU+dw5LH3^kQRYKVbTcLOXd-EvhO*(mi zbSRMtHD5ufAFmTD8I{7%`Q=<4HY>CuSTXR`x6#|nQ`249)xKzbVWMDP!Hj}s1#b&_ z7p4}Ka1D27dH(h-3hW5|V4H=XLj0;xM~$Hl3lg)_4ABv%$b(@wtn`8jx0xO z=Va#)r_;IL5wVxHSGGB=9`h;K=~RZ(x*l4LzC$h{df^Q<)zuADJ(LTutB|2B(QSxN zZZ2<;G81Wu|A}*ijq$%@t6+XM4lDRu>=?!px*HhhFX1cnJaS)iy)04{je(awDfp*A zDwqcOX>+x3pYe3`l?Y^n`mz`J($S0YPKl7b6?V@%nrh@q`iAbFVXLW@Wgq0|9s6WQ zfuoqSnA7E0=*Y9D+iTe>ST&Y6rWM9ohAgP~Ms%3GLu|ySX-2Cjsa7b@V!4XaiYe$n zNHQ`_elFRifr%aB6Co!ah~O`1)Lc*%#^%6#SQAJMQ9X;_m2LSoF1UaG|r1 zD6CevwXkN9!Bx(^z(e|8`R@mRF{Su55hA_|ko|jfw31PeA|6m-t-_FPTxUkD4Q%!8 z3HuVqE5}dARYzaP8@tV3&sN`B%n~%6Hx4&g^pCYO>8cb@JjYLK_Nfo4ZYVP`6ZSvF zK9oV)BS&OW>MZR{e1|z-O=ul&7i$*Hyc{(quR6d7^*Uf5;>YrfSO!Nt+FY$ zSn(1~LuVl$0WmL=J|&zG`GvwR*p~K3S4W10tMUwcni(3h1>gC%`bNPQ?dG25x>ZyG z>S<5mk;1&f!9`Y=#$Cg+!&}{t1cgvBZdCY1w1w~@(HqHCj8c8q)FP+SYjm>>wM`Gr z7Hbuo&VI?B>}c<3?oc|m+2gj_w$9demI~&$@s44JzM?LdJ_snZ9-uoyL#mTijg%9y zvoPh`qep<*8YJJ4XsLH%oA_LC#}hF*8jO4hALA!-mDs`%a0!88e#ZNs=aW0&s^r>I zRJO=dm|JKrnqQRel3X^=C~v@bDzGJVjQz#eh#rWiBo4}D6vvcy%{1Z?^;Y|jevL8R zywGygy2aMYe%CJAF~=wSbbEoVimivWuceha#gu0_q93GlYQIwZ$tgrvys@T{x|3>x zau4=RQBpAzeTP&=Hpm{Sx%5}!KT$8%6}rd!$9hB?N1Wk8?kqcw$p{q$PW$Kk26=mX z#=8%>q@oo?jf%#e>7bKa`e z>wg*Mn+nWHR;%rcZGioh{ek_Uy^H;=t+cI|b)==gxq*o?zSD2ib<*l!cAg+s;L|lz z)C*O6lrLbT>#R743cxqrk(1?F(#wPuBEM8P62BU|7CjbO6&}Qw<9y87&_vkjRsMYM zcaO{MaF25p7Huw?P_&@vpQ08n(G_qzz4LsAz~|r-CX=&9M#tU=&7|u{C2XgP)zl{Y z)BSYS3}20%%uyHDGj?qy*{GLC=jbp1aT<}g{oqwEf zfOnKDi z_U3uip0@4_t`;t(D_oT7n(H#SGu=6!G~arE<)9d1S#7vgbW5BO`^t}CDlJey0Bq0F zUvwJ`Hq&_cqO+_SwnMf&Tgdj(Hp9kP+gj&ZHkenNCL7xtZ2BziNqPp=jx0-iMH?di`891N{w|Ke{)60vUL1;9;{u_r1VuR%7Y zGjv7zImYiMwIyM>V{KvEYP(?DVe4x9VQplcXW3=mXIgI@Z)mF5>Auq^sfFYKqBT@f zD?m+u0*4z@v{M{HF?0;_L9Qq7kz$EX5czjPBAyh_h?R{xA|n5VJHgIkT8EN?VShG! z(XgkyXR%vy9dj*kt#Cbd)plpOA9}ueOZpE4I)sX`DSVyC_}Eo}l!hbs6b4my%|c=W zHBZ}2|I^Ugw9vfR(#e`*ZDt#18)_?Sdtj|%ontvllC}(+U_EF}wNA4fH{UniH=Z@D*N@QE)zWkx`ItD1 zAJ!aK-%@2N^~%oJZUu|>KyL&8|CcOCgQYtOJz)Dy!tMBfvAk$bKtXb#dDdQ*nHNeU&}LAU=bXoT|dMzI#r`moUxd_H@R*%6u< z931EcIl9#Q$WzL52EJ)ycW3usZo+fTv)y~f$N9$v^~?|U1^*vpXiagJbQe)zjZ|YG z^0TPUT3NTu@WY6h8S{Bd9qStFY3nX)e{0Y(2;TYGRA|gMe9&LjZPt#X+fW&#iO|4I za;od9Mkx;iUTy&yO2Y10Aoq~(OQnE!_$WHWuEN~-*4P2qLN%97o#`&f><`$N(mU`CF*5TIb*3XtMmZRn$rid|N2dPaCq&vW-(=$;KcPdzKVvweI0Okg@xQi#h92ckxySz?ZS2`#|%>e6^g z5~J^Hd+6^PB1YNt**wcqU@2~`Xw_J+SsGgQnSYy9CbLm*Na%94|IkONHRKFpEIw8< zTfJ3v4|;uL>@P(S?G5;@7IH#%%F88pqIF`s_(L!X_2U1F4T=tobPG3xT2it_p%1|) zf#?2TKHAsY`;VuW$K;8-jh=p<&z@!8k-oY9dx0vUm&|%@a(HrdMf{BTQ_`bNuo0?x z(Cr6N>Dt@6iiXL?rKS;Pi)ABx(;)oXYAI{kYR)q0O=XPb4QYBp7oa~L^`I(4Z>qgFQJOGXZ~_7BK_5_p+avN1y&JtaiOV|`MbFhym6|fjfFMOGJi9rm|7Y882anG>6&QE(^g7J#_^a& zsYy{cSIq<-T!Z}qyL>J5IFg2J19f4Zl$U6k*ePZUDMCBooaROsN9KXHG>~h@)?q4! z$^$pr*T2Q*@(%Heo(G-_o;RKp?{05LUuA#Oz~Z1Mw1}<4>mz6k7t#_9<^Jd_Y_)2Q zW;)TF3eYokpY&=YVfta3Z}ynWTk2a zcp7pv;p^nP;h4pn8pafidJqs!x)#pBWg3DhALRv(chU@U5L>%4ZgHjl$NbI*yArDFbPsXsc|au7Rt` zJ5*QgUC2*4 z;+55v^FgDl4LH<-u19cWnVgWONWT)z6T8JCp{&q1zA&~edMI)1w+9`n`sY#{ZcLO&!gDnpc}gnv={YOjgry<1WK3{lB``+UN9r>Kb{GxP;%< zyi8gIv>tl+3iYI7Yz;~69({dSkucVV^0m3T_O32ap+n5i!C?3JX7%#G6h7U)q+S;N`ueeUv}bpBW%SLzql<0pBQMjbVZ;DrE{aV3aDNev7Xq z%h5-)5nXXZs?lp)XA(_~&E3rn%!27}6Kxt{JYsmI&(V3b9=d?aA~T6!c#%d_r>NTj z8~OrE!xk!vK+FGxbVc6DoncFE2-+u|7%rX{eDSn+^H{&==*Wcdcz!fDoE^bT2rUVo z2;}(d_)qv6_*m~pZ>HDko9om0-}xT~GJ~a=Eo^E2zwnXh%J^KEp0knJiYdwg>Y6x5 zY@_Vjsk+1ZQ--C+%BEAMsL5&8LA5V3q3}IV8-D6zI$Q@-Jxx$JNfK5(L(@h*O?4U+ zrIy$s1qB%zMy4aYJY5b+W2EniW{G`bK&T;%h530Y`Xur;{DJ?#y=Ol%KSF_^DcCNs z-LLSkhnE_BI$vGiMxVw1+yG z5A{2c%{5G;XHdh#x7$A2;TVNGcO3ib83Mo>< zwa0Y#^k)p?jk0lsX)k=$^``cwY-3;JWdo-#4t!WgZ4bH+)t?+fjK>#&;`tQzk0#2E zm|M|J@d&LC{9S#}>6*&-q}t$f&?ZKUH-vb+YP?@;c6422C-99&xl`;F=2@s9Xbbia z-1OJSK&GxPKJ%RrDkAG!gW^hyJ15=NC%#VvyjG;ol_(6JvTu^LNPK28OO-!OP z=`y-D`o;#_c+6-w4KPhN4Kr0Ry)kxycP8}J^gVQAU`tv+Eg{!{s&Gp4OdV8}QjG-v zfDW6k$b}634%0J79s!P#Kcp`Z`9oq@Xd=vupNhSS7Di%WWtis8TspA#UEqt}4cG!} z{AvDAzKgzVzI;Lwp`N2xYaOo1uCs}5*76FJaDk80oO z-sle-IvAhBOBA=t;Br|bYeBD3O4AbG#2VtC!lQUJRy@`;+AA_5JcXaftzvgE*F!nM^x!l=&g1<_ zelNTd_xFN2ni*&lY#AEETwzP_7sLIcNpY|6Z{nQ%7djPdtI}%j;XTRMR7q_Q-9UW< zL%=Z8_}++`G^TvxK4VR&BaNYhe!gy>_6q%&dQ1Kw+_7lDhMCka9F3ff%@EorGGq;!tGEu^XBGTkqBV7h{;u`tKIk_Y zN*Gre9~(a#?-`dEOBfFua6?bP^jEd-={$-hQ9#QXcq`2~sHE@8Qp&m5PeohBJz&D` zBdwt~^#(<;zw{9ze@v8w4#K+lgP1!?MoUC$gDV6JZN6#bH|+Ag#WGS{euM78hNvu>OL!e}FO@@MI#KspKMi8v%s3i; znj0gAb&#J!^(S<{v?^^0x-QibDt+lynzE{i%12mnP(WmK9x5X%5hJosE-Rmr zDgeuDNK6x72sWW7IGe5jFB%MM!YO#NDS_8`hX~FE^ z>rfWs;HL7P@WNuC(i^lJbz}5S!vTY6sA8;VOf&v6 zEP#3+uD`4cXj8O}>Auutas{y;zo*GlThyIZTb21(3+xPV4!eP8Jcd+9?gNkW5q6Mw zFy~K+8nL&qH~uB2j#Z3yfLdAr8|Y>BD?>2tL;Heca8saGK=2p%!~QCP&4JY5$Kb`# zH71*_%6{;m-(3{pM+AAg1eoZ-IC+VUb+TuE;{+_GK@3u z@Xp&hSzBG(m!3`iMV=;};`tg{(?C5P6gomV0(-4!0?v^}=o9eAWdUN2N(&@0F)i_1 zYzEs>cDz`;XKZowaO7e5Cm-Q#TmyD2e9>5NaPW6vexP0;DNroXDR3xIJor4gGqj00 z%lf%a;eR88Vrt=zxIk)#s1%Q|87jNxFm5NuQwQlw+P%6V`nZ0);fmpt;f>+2p_jp} z|3m*!N9$T^rvhfWOui+&I1MQD4?uUnl$DgLFu!83;v4kPTx2r1`Zmfb@)4=5bP$-F zIpQawlrTDe2s~}^NJ^xBxHmtO+rz$O)Sxb2g=%^dm=ow4=n$9?xE9C=J_;@mO=1?Y zmpD~;MnsP8jdu{0(qnlE+6eP2H>uO`zli`@o^GzKr9<^c^~DU+4Eqd+3`-16V7?F3 zKhfEBy|ruTOVme_Aq+%yysu`J`hf~lbp!W+9$N&;!W>kAZUkh1L2d#Lr>@c)!1m{X z6&)^|i~C|FVx6PYBY%gl0-GbU<=NrPxeygv6x0Q82UZ8>1~vs=2dW1j1ZRZ0Gdsotfr5L3xZ)O-4s_Mon_{-eICVWeTYVUVFT;H6&r zr@CUgQQH0VD~cg4WKE(s%+7P_0#$};25iVxv3&|VsGjNIZfXR*X{a2KW&z_gEs-m> z6%Prac&+#(*yvwG0%2pgCf}c1%|3)2{Uh`~*e@st9tTdt*DMM&4L%Hx3DsjNvu(IP z`ETJ)(J!%SLQ3MTv=phU$j4SdStM}e)U)E!kjlmV<8c27}DaTPN31=1f0$V+6CyblzxgTUS{5`PKR zVSe6<1*2)v){*hy&Cs0+*)(<-b2C&jbPVbq3H}QF4yc0NgHMA)LnRrCwR5fbzrwM| zoER;f75hp!aswTPDOG=~&G>BM5$U7C^iS<>T@C#ay3Y z23*eM=pL9$Uf#;L83Qvj#0J*{8wbr$`=x^;gKvTZq0{>qFRSG{hfhU{#ZJbX ziv@|zazivvu~cbMZ_$W&dvYGNmYxM)G)vcCe_sDnpRa$R-=MFlzpJaFTdVy-o9R~I z5!*#P#{HT!O;7dTs^7|*$}Q0Ar-BD-7ODh%R~~sN_XIpLRf;60Ckn-`;yD2o+Q(PN z9)QM>5@{8l%0?IPxOeF8*DZ z1s>6d$Vk8=TUA!gV*CSvQ)#qGo2^}^Gw3J4m%O1ruAiYVslNvA+@j5+%hH3W4dg8% zA2;F6HFMQBRSH!vKuxLGW`$0%6)lEdLfRm|qDyEdY>0n|X=BZ! zQzCoAFZeiDm75F+-T7~x`{w6O{r|G5I+PcTO^7`@mRr){mef38D8C@ma4sDRG2Rzd$@*ANh zYT+Y6_sUe2QO#C<#u{N46crU0AVc3E!@(oERW2{zmfA?K5^WQ=#NwbWy^lM=KeQQ` zW-eSJ+=E}k{mWX}$;_|Nu#h5jFSs+fEqE;`1V@DU&?#mqyNKJ(e-4+AZi`ujLt;JY zi#!!2v0ch!^%_ksUYu+}wWLdGe`#mv@^w}9z2TMh^`h>8uAFXZvp2tIDRrg!S8hX-~pdmCd!~g~z#rEb#@!P^#k!G>$@rL57#4uSv zHY?JU2UG^lc>EmknfysTrdMc7>GtVZT}gcveUd&;w^>&bkew1H(g7-yG?T4i#-GvT zt4pcJK_%HioAoM2DqQGvRE_QdUhJJb7JM#$NvRO|l*D?G6}kuqk9U(d#fheex=~xO^3OhnI==iTh#&Ku$TZh0KUuj(Q^{B7LAcz2)qH z^4>5lnfIaDq57eeP+F*YXiX>*TFEqI%^by-4EKg!ua3_XL~*5LMUJ4Au(Qf^^&;4o zq69@r)H`~ymeNhtUDbWkebAlPP1G56yR~}l6u`W~SU4|}CyHab^uB5$Gb80>L9hEyr-Zjg-bRbXmk1$oj8q{1f&Nf*P@YpEn#TArVglKhDnoyu`)eO* z)$qphfa>0B=WBJ^wKPw4qYjZSq9QR4D&DWItzM@3p{x&FlMQ%qhvFFQ@}H4upeJ61 zsT7h{OG(mU@Z{_k3GiS(k0-}R#?D0jkt&fX;Tyb~AH@B`)@PqEBbnk%G~^3mOg&~Z zL$fE@Q8441h5JR;MnA+V2!8>-n=f<7Sj9K2p=y)*ohF9kWE?io#k5iTr}m9Drp0uA z?H%nTEv{WhOVnWM3W-2xS_Ly+r|GResuGlal@GBRz%teVA8QZPkE{d5`@K9>Hp-`^ zCeZD>C0>b*#p7`GF))56#z*Ue4)!Qa02)2Z8M$RF$sS|+G3DXDq6E{0*$eO7$9CgN z@z!vONW19D*jLEV!wIXr8WGVk*ehi*^&grI_#r^|)2K@HQ@XKsi}soJhxV=ZsCKXx zg?B3Hanw`NMh+&903%ijxX>r6WT>PptSk0H(OK~wod6kn45p_?-XK?zUrNIu^79jd zI2DjnbJ#+Hu|~1w(U%cpq%ZghL~aoGhV9B0Fk6{{Of%?GqnOi-f!)S7=G45G4}|Gx zli135me4YBK`Mr9LKF>X8oW8#R}X(Y>`>wHLH!wQIGVwNZKvjl<;p zOqM5S5%+Nw-chqnov*47=uW~WVui4Ia_CB!^7oJ-h!Qy|cLW!~a>*$jO_WO<7A@j@ z;YYkid}-`0T&xU=oCx!L2mTc2;I^?D>^q3}M7UO2!rWnO>|bnU&ci+9?}y(<#3)?3 z2t{IN>6Tm?-Jl3yEmf=4w>4kz|A@QfGO8kdnNEW5xKz7ZJ6YQRHscjEMK7Xq$wuS` z;u~HZRGO=5rMjQ$x-vz%7Q>*|>wp!jhyDlnE)Drd9xW5{F{u$CydJ=Zw-v7n4(OuK zVz$`O=;;U_ZW-PI8`B@$Pj)Ozv(F&n8=3vgTPB^|%$DFjaYq1!?uy)whGO-Ejbb3t zQ@)FoR4l>%Q>LoBX(r<{iJ@d=Dw7&df2T9FJ+;HM|I?Py{-zhxG%l<#mV@9 z*r{kZ(i{}K0=@-*hAYXPVcWA3^P0KN++*^g&;P|bxd+?|eoS~&WMTAl%pI>M{*_>* zUdT<H2@Qc~l|7ep~)GJYQ_eu(;-$^<%1 z4%Qp{tQes1pi5v=dI;=@9=QQi36l>2%lroJy}pb86CVrZg*Cv7)&cGNzeq-8A?P7Z z_={W(?io9ot;T9uCF@{2K)oBdLtJ;hSeT4xqZzSY@xO%}v5xeY>_b{Bc3@dbhq{TT zE8dRCAl>8!%1qCp@6!deA2Q%HJ&eZaO%zSd0Y0o2u^O(xDrgp{KdGvM;wfX(u%Kdw zLaEq=)<(Y~i;%M5A($%{gB@fL%=sk=O=6iC6^4QSSu#Ek_{L(H4NETWRn+-MpUG3L+@wdcw zvN`pJYCx~1Z_xkJcj;|(PuP$)Q6_3R=_T61mc(gVYj%OE&>8MOl7Y3Qu#JjT#U->e z8ic#LCU8x+RcN~F5O zOApce=!JAEnxi&Sc4{LTCk7DLa4o1w*VH;dp>F`)ox;jsCqb!sfsTL-J&W`LAJ$o5 z@DkE~sR1xK0~6WeK=HlMP&g2mV!dN$qgb?mcxON(^U+lFF){&={Zo00oCIw6 zK*09PffZdZs>JES&v>Kw&KMJI5BicE9vXfHRsWnD%#qwn_6WNJqW+mJ&aL50{B?eI zxChLn9)Ly;3ctjX(nR?tqExiSmcX2Up?wM6p<50=(QFGISR(x4e8c+&tqg6*y1r_B>s=4I8=P5s;TOv z(y82x8L^$ zmG$9uyaRCFNUjn`b4r+{ZMkh6!ms2jgx%rCk;~B=v3K!^P(Cq2Ix6QQr4$3O)yk8q z8|o{Xo%l$?L7pcwsO8iXs)!0uKdAH6ILb_&fF0==VF9Pm4^2JI4s}%3U-bkShtpVj z?2@7xuy?b7v44V0MT&#>atXLE|AWg^r*uBiIPpYm0sCh;;V-!S>xjo!Kt`=7o`e{FIAG~uR?+CvR?};ppE{<)ApBH|LCaDwPrl+U~Y_ly)?oqF)htzJsbz0CpYJk>Rl30faHQnIq$E2R6%2IZLN@|I{RP+Tu z#(Hp$d`DKn^mNI)k^Bu*23!VtK&s2SfLi$?oK??y@klcx{=%~t^3 zZUZ-j>%ev4CUU1Z1wWJ5gfEBZM0!Wt$GXSI37f`eFnT3%aw6#7A7iIL$ALH%7PNTi2MP_ z{<%CyE+>DI<^s0A46NvDv5WXGbkS3BQ+#$TGui^MQxaejbNCS7oaeY(+;({DUhX-k z<0tceer32pL>+ZSvtll|NG_e|E-jU>A_b@stFCOL>Im~Q70<;t6Q#)AWCZGd0KByy z)d1$^8*&L*f&7;kM0oINcvv%2!>T8#J*v^FLgi?s7bd8rSf@yX$zT3;XLjbJD#Z?;sO`_qkVSoBlmb$a?z)P18@ht zJ@-paw;WSW$(;2$y>gf3r4*zUt#tSFEe;~w^T8JYCO-okndUK7yXqD~QyG?Hq7^0Q(XDuXYh zX5y|;Ilef0E_{{S%(M!A_Obu zxut59Y+by3dNAd1Qa6Xv_K$hHahZO#_9R@RR>D`Qeaar#bySb^mR5@gMtQ|9Z;1-}mduAN;s_dx!zq8XkS{w_?IKNlO8 zP@+qf?=`>3gIc|zr0JWvvbD7Bk&Un`>^E(-Y|E_YE&qU<@}2R!A)vSEy8x3Y(USln zjin07zOZRTaT{F2|Eub$Jgs}m^SrrFa+C8y zd2I?DMFZWm&k>x$sw0o%TczQOG`PxEXmP^@lizaFMmc^vYCFx&1&#&wblW7$0#iSO zRd=5nO%&5GN{_;fPLpXVTMP+xg^Tf?z*0nGxv_V#Yq7PlHsCTH5Iq<99?k}=wTe_f`m(=>j&Xm|&iYVhR)46P=vRlinEuCI!aEac<9BG%5 zYdX)^GAx&kz4T5kLg|TCnggm7%a{-fCUqOYl6U;G#Q@BG)`w>v+KzlyTzAR;+W06(yUOT3M=psTU=Gl{j2Hqu89Z!zq`Ot~xH+E?e%Kei(3lJMC^N zL5#sO)!kGNuu_WI$PFn=^vAQKcf-rL28=tf)7QgO%4ILCo4+NuR!&CttgMWz7Fqvh z-OEnPEzC0(ZgCCsP7hpV9N~2_Bryy*irrHGMUS#4}Y)epxF-`%}wa!3A6(;O8TGZj6Z_! z5@a?9JNavQd%GVOttdQO&=fAVo)R|ol#af5C2U0bXSbY z7N_k9+-P-kPIaa^`#WmduUK8?EaPc?Z*7>|hPPB}l_Kgy#!4aaf^a2gQ`PmtKFCU#&Xg}MT~Yk1 zaLAv`f-}Eo|GxWsX~DBU>xyzqmX&9l)9jQ>;_pq}2qnapp-%)~#b@QU)kAb?h86Ks z6DyM3$(vIirEE(Pr8G&doK%!BE&h+8aolFzFQ9%lDBbeWK>1A-M}YN85nSL`=I!K~ zkxH=+Y-YF#Bd7C-9sX`!vAf9e*=D!2Fn_AJTwYc-zie9B`?5XdxfLVK{jF#0ZCr`o znt>72DaH{=N7|ruFtc!wcnJ_v_Z6R&n^ktmr#(P7Ir}`` zWRsPRHP3aCxDw;ogf)rHleQ!+PQsF!B_<}^2V%XmzPGluIz`FK3MKFGH{hla@VldD zIeO$^G=sed^Ut5bLG(MaDlyxC+MDD4;{0m=Wc_3=tl*Vrm3}YYTXd>WT=?UUtnfi$ zQPJ{}{bf~5Rjk__eLSNAm*`57Ye+kOjwnUeQI)DYZFrV2HTiIAW~IgH=^1@91R34a zYgM|P>Q5#T-^8ylr0a9Rl~G&4m$70!K2Z1&Yt1i)9M&*SHH3`bWhY0_@M@-*j;9(D zb^Juy{fpOuiCP?~Ttp=QFY_*KRUhT3t(aJE*`v{%BDRPV=DGl z)HT&NAF_H{i6DpoHSxCy{WvcDC~K_fpbRKGt2(I&_HK7KaaD0ncJSfPbZ`PKbESAPd}{-LQAVb5WM1qUSA?|^^#IGxePu{p zq#drG9j7<+G#Cx5;x_0T>5jm^{k~$0tcxTpx*=G^?~nH7EQsZ>%_AkDE6geALU~}` zv1}9-l2;s_3J(XzRvRHa?4|6W%2@Not?uNo=3kDS;Ee((qpI(?-;^(kVAd zZQ`h?ns6HShSvhk<%~w~*gY`ND8pBn=D{13g6tPq>DvkRnKh0Xwvm<*rbXosOY4`o zi-Lv23#%56E|eEFEY2(Olr1+cw&pwFe;Ig3SC1S)coZao+t&_}`E2@;2mD)-=m2gWcm0SX^5K{iS!fT#u z>*O5nx#&-&t}>n2JfsKjxZoLnO4>rPLA6w)*A3RUkNXvuV9*=B#Px|gq5q)E*M8MJ zRsRd*)I!B1`6$^4>1fFW@g#f~SLwv10?On4R z-)sx56D$|ZUCo*1>*f`ftJb#mTF$9%ulGveAa#Pd6?q9y#zB4?;W_-ZWRFY$3FJKG zU#h=U1xRi+BFrd%BEJw5LLe+cAwQs(SsOVD z9Gnws#f{;F(4Jt38caR}PA|v1+Or7g+!n5Q*8rE_<#qS;3jGFRA*Bbp)e>bmDt@X^ zD=v}FRy$=$_=WPzlGysGM#rj@?0K@vY9VR)h^F)7KFI5u&8!ie~wVR+m@ z-961q)mz0EIK5DD3(;0VkiUW#kACEALx#kvMgx&sP#Yo48rn+MA%^*9c&ECDINRIn zT5Fj*RctClN*@)!DXLu*Dy&~rT*NIoT6(#>mRWBb?TmVg0t8(%G8ehWvkJYEXNpdm z1^N!gvkCi?R4KaD)2S~~=cneTJWHODRG46huWR^ApQcr-B}$FFzI3Yisi+RTJBRbt zyr0k)nT0fokYncO+aKD#S=(5}*2dO1)<-s#;|2HEotf9;8A)^Zn0;*XOMTTj~Dns1gJiYDSR@z zgfoiQUZBBqC0*q^lsnb!w1;&E^o@YJ?jQF@FVmCS0~)Tnm2#kbkTesXi28yi{66S9 z&bL^b==;draHEi%3DXqCkQ`D($OCe}$j5q|?tIr<;Md;SZMG`5Z9oABEfVV_s~ULF z(GGzN@pSR!2QE-I7;~f{vJVYnJ@9qX9g1;kzqVeS!FVeEZNfi^)q5(P^I20(6Kbk! zx@$UM{?9VX*2*!?^~N*CUx`G5_D~*s16hdbu=T=6_zlTe*$25@@l@GEbwKs6YK5wb z>Y`Gi91RpoxhzdK0aDa5$vm+MABC5S#)-;=1L5{37PNw@s5MUj_nu^AZuH;C8cUREQM5lK+2J1;fIB0tQG$X3N8$oNEJiBcO@{GIg!1Qm63&! z`7ntdAL$I#@H6PAKMDy$jhL>GXzz@^mhGmJ*H39g*AuO64gM(2H9!JLok1M zu|)m|^cJTQaxt38B9S+tY)H3GrnCOX*v0%me5buLJPq6t=Lg3Hu##M}+AaMoL35#5 zY}srXVqFcC`VVK!J>OT4s7VhDonvL36+Ek;g?Jj=Ijd?8>mJ0dFqXs@B`i$5oVYeI zmQXDLkH2h4h#RNdp}DAfuJ|oOq)o;Dh-kqYtQy~ezT#fzTtF_w&PTJ^O_AYYL+Bnj z+YXV%0oLcYY-S%|-DdVyY%CvDwxN_;T2zu;`o6ThY+^+}^BHSjM<4e-pN4!G zTpDSIpu9_hTH-~rmC7cXL%L&et&B_J`@mhVDB)OwETL(9Rig=fVx)Gs=8?*%TrPJ= zCrSu>m#D3fg}QV%ZyZ{m8-fYv_$b0|3P-?ybA<{JbpkVdH#`FO0w?BpX}e>!ScY4Y z!7Q=Q(#tx`_P{>Y*~h)io9`b^vh>B!P!>V9aT#7yL3@!xd<2-Ta@jGtR?%J2RiRPb zkk^)PlNCxUNykeri=+5({G+HR(6Fn8wS{GZ{emu#3t5e^{2~0kyz}4;8^H0##zt>P zTp=Y>lkP&!2A`SEdkH)OyPTxss^f*Dz7qw8VdLeZTy5|*8nGA%CX*)>8!7b3Y+1D1b`I`tWxH9cb zIwZF+&H<>$o(h|ZcT1nk?<%LO3p5dMfOOH%)pytD>ymWoTAzBGimx0c{}*h2@%Uij z2`tDPjTUoeBL=uz9fZsabdDJ;SVG+-mqU&2^&RoH^_W~+oUI)^d%4vLhL1Jo>Sm*P zu-Re$VKIV*=CYG?|Kl4+ETr#-4AH+i9R5@=_Z7)LC>Ln{)8)l2H9n0$mS6xUnmeIi z!qoVd#_w^h^y{=Y)ZdjP7$y5kj^bR=Izc6@n0Fh9rQ`5)-iQ3ad-i$c6!6^!<~*H1 z%_VO5OT4J3lB=6zovpw!)T}gN6&=femAx!emcJfabe2+Zu{Ss;>yvIi& zU(m{e{&+8`NU=n9NHbRVO>d1m2_77svA{4C%q`dS`*kD09e7QZsWi#g$!bW8#7FS) zK=x_`1h7fh(DmFN9077Q+JSu)t{>VNETd|Wa|6$O@!l=&MAuKSw3uz(ZH(1#ZEpK+ zdu$It_oT6>p>KTPF*-_Cj`EHbQ2Byvkw8 zPqA3s8ebxMA&eLPEszT?V#BdiEWrN=74lksAHD<__#j#7W@#J#>OM>xijEi(HCDL86}H= z6RMdiPo-1GRC`o^l!b~D@_Mo(5*wZ&8YVcvFGJgNUm)XRHKPe^12|9fLIdG>JjIM+ zGQa?HF*qhDhID>aFuBIae&lh&1{3_Pe%iOpm+lLCW8PN22fl^=1%bOnQ{Y=%j4CoB znv1kWU+`POotKcr$%V=%s=AtC+Ge`9I$Y1{&g!JP`cMm&tCoYKVyx_`L@%B#`Yz~z zz2prt}3sDQZ(&XishMqUkM`u}(*faPI@)8Ke(J7C>zxo1u^zcM{A zA>j7eXK`2$!u^VIAN8#zj?>mq_vjN&ZT@!Qe`1sDnX;eefNpJ^!q_67pD;CHPC|0R z;`mL*fd;RBxbC8+LZwl5kgt&DiZk$|!g_*o_zd=-+qeffmylOrxHYpCkx!5c9m3G` z63Rrh2(0zxfU~Km^Rm6V?LW&U_&F+@@+y8;G%*ECxMjJuvwgHP*FDA8j%ZJh3~ges zA#c#v*ilg%$ywQ3#R*k)%@}Q0U74=7zJZ?6t=AQ6<=SM8RvlLUP+W#*a}-p_wZzF_ z4%7%$0vX1Gp3*1o5zas)7Tv*0Ba1_M!K(BE@^zq+f0sAW^U-zD`NSc2oCXU1l0C!W za73L$+>Ga&uOy(OCIvr*ny^P=PEHc98pai#5OKvRkfhoo{UdcqpGikaze!Rh{lxR} zt&sJ~fh0{ma4{fYr)>_|k6-8u^e%c0J%jE*r=T^_FTllJ=9D1L*q7)|cxs-8nle}D z4C*403HL9q?=SBWPnKtp=c;FjcaZO2e=8!Msvle$vPPx>-@KL=#JcD8gNfRF2sp0aX;10KfW-X~ldDP6`Tx z=jqOn*_jM=$#624s0??_LVqj&C0{My8}9~4X0P{t^$zwW`BMX9iE{EN@T=#-cCdTh z92P9i*>su;(L3!<$2snPyOhog+IEU;TZ3A3W{d&zzYKx9z$$+w#I($^6dr z)Fd=tG@r9@ZFlU?oC%)izJG})bTl+5`jBJfPZI7C@04XJKdBk*2Yq|PP@_72YW(DQ zMf@b=QbX^!fNqBNqZ*iB#aS6G87O`a-oqHMAcr6^wvC$&Wa4))wT0La(7n&WjZr=L z2-3=D;cTA*?z2{|T*pj%TU!_FKNhvcWENPKTRK_C*}mI%I`_DLczXuC!Q3zD1`aW>nL%@b0*PKvG)B{z2D=#T>#HN`!_HE>k; zN??N&o0hNTq39pZF{Ep(kR1y5o+`{r`a4;dIO0$8J@;&diA0XGxijcMoc*1Yv)pCy z?Dlr^Hzs;g8-w3NHQ1HlV{xKh{wu*)Q4U@TZ_Z5V0qF_pbVwqOlVpn@;?G47gx4V@ zdk2hVBHmCSi$-vz++UoBoa>yM@SiU@PrXz%Wb&GX!-9+t1%|b9?+F^>zm93U=#G6D$_*v%goAIP-@kMChRVl?+&4-xc49p?t&znJSu~UW?twJlNq#ul`$MxqXbXms3a=rZ19OoM;@!AK)JAkr=ofSp?7%)jszJlk zqcPwo*2Pkw5-~!@vy5&}T_&o**}l{}#0ol$t=_1Jm@jd*4=pW%YsCd%&I$j#ujk^mN z*Y%J<3dR1!zQ%sUN@K2=KW2-4goJeG*bm6??_{5VdFMmu4zoYFkRA!0oEgMfNb;Ta zFZb^TI%jKOE^(9;&=-SiLTiDA4RH1#J>g$0VdatP;ep_uD~2xkCh#dVf?VDYn9Ga_oc3FM zfB9B<%REDXUp(vH>^|%+bC2;PdyT$+{`WxCkEfS2kHd-4T`<$$$Cn9bK}Gmhc3IJ1 z^$_ly*R?HlOLcR=khNd?S(B%}u9~WpD2~c1ORtDqfK_ybpc#hq-QYNPLq?+#(j_)6 z`Zt>$ITJnr*{0S(AGMX#6TAHa-y%5M7dmy0U$$KEi}kS3X1BSq<)`JdHQAoyxbF&i zmiwEKslgiIF3~BR^}H>DnRq%>hQE}#>ap6(y5stmaT~yUS2J$E{uP*pc52$G|0pK{ z);kNbh^ ziPPig=OFCg?38_^L+0eVnz^reM)+C>x{>o?(vL>^ME4L%GcfBX%zTv*^4!O6&U2m(;=idp>=IG#x(3OZeY6J&M zH-2p(cShma;=__YaGqPGAEdLT1rm)URV>9zh5rgBVm0_-V8{wMBs`bffW5vFod(Zg zU9cuzUtkw_lV7uxgYl$1ATYa$#z@P?{{c31sji zL2K+SZzRg+K7p>u3~)_OhphpZLxqfn=>;>I94bgwC9{BD%Lc!b-&++b=6CM)!2X|g z9do^N)ph@HKkyWJ+xsg5PstCoAT&Nw7#+_Epv$m;u%~#9bc4K)vQU+-Nz>-R(>WL{ zb2(arwwb0D`0y?$I?I0nb3@}hMa^LvkjuZsJB!}o=D~`GhRAfVbbe(?U}yzlFY^Kt z_LZo+M9aVfUnB25=yp<$9Qz}i!#cn!uyUoott4FnD`VZK-ya?uPCnSg?LWZ?7JBtZC&P#T0p*?2TlFxE0tqtw1Gy zf(e-kWr3Wm!|90hjb%kUvDG87&?{znuqK?RONpvrx4Z}p?|yf#E5mi)xzV}XS>l}T zYT@qc*$G~zM_>-yNbh1UhF`JyaGtzExAFfHoD`Oey!dPJBw$e#(qy2cUPCT9DqbNb z@kx;P?I-#!94RCPdj+ip9@q^r0M7LD{MP&&-e0`c@Z0$S2BG7zQBfhA9j*o`oW}Hf zaz6ZCY64T7?XBbGd6T@Wyw!b1NC7<|##7CMjevTc5#58_EzH}Iv)LwxHXq%`f-1KhpC-Z8dJT3wIH0s6HK%#g9+mK}=zay_A4e=)9~VGeNH)iQwU)j@gQkK z`DeHR*H<&@MVjlH3z~@mJ8|5lN5CFS@B;3^&qa@ZG%i_a;{>?`l6FU4Y+O8f`1|B z8|2^NuY~%z3ZLbD;_cyO@?0>vvv3=8Cv%oU$1^i3WuHK*o5x(Bhk>hDOvDBHgOg){ zZ@h26Pws#3e-{vt%c+bY&Dg>o=prc~FNa_s1k*&naIqvNxh74JbpWF13or(A!L%_J zuLX|W?O0R34L!?U#2JH3j%|haLnHQHq<;j5boSZshVZ0tSK!0R&^_3@A`hKl(wW0S z5ip|#R3`P790DBCH{vy6CK`~p$thG{dV26KQ!D&7vOYQxY06FI@gb#lT+~7QLZX({ zmB%SwDjFy!Do26|;H&~s)Rs4vRg%(h|D7+YAuPvEz&E88n!;6alt^-{5m-By!&&+< zb|lSTs|$XJ8i5S$hwRQ!!P!^1Ncu|E5)qVN$nCI0#I) zY5c0ZcIZqV2zs$qi4*k9Z8 z;mQ2&fb$h5>;|6zd^l6-&rGLCZnQn;CMv}`3bXJ!l00cE`D8_wl2uLwQ_tV3?r@s) zR327*lDlPyOf1z%5@DN0Ytazla(F_%^ZAe#918}A3&8rkiaiEb%j!taumYwL>*&_t zt4<5vOZ ztdi)vs1JSwzk{E_r{PNcFmP}SAT?PZI3q5$jF0h8@%q9I(~Raqjhu~cN0&ery%yMG zwsQ^K^>7PD5OoZX+9MCct3&OJU5=N?|X@T5;d;ItosS{)kP| zJMyl|1FGZdk(xXWs&#^0j;m>*?y9P%L=^XBlcXxiQ+xsR^JD@VI3NM9CRotUz|+|g zIT*9S4QDDO)~|=}0YA4jIFe4MO2OkW#GmftcxkuNo#o1P&T{s1E^-z*H@arKk9v4e z2h1g=Q5%ByLcvJ$*dorq=p+7h!E$hSte4!E-jdCiN9Da0GZe!WsfwraR*P$+mJg3%K8KHPh{h6Ip-*$nspW<-NPPhiVK z-u>Q5-Z|de-ugbf?-%?ox&U!DC@2iQ4ew+J#uS{p+%`bMnlTFAoU23>ka3y#U%)-C zgmmH%ARh^=Iko`|F)eu4(PrS!-NqdRj)OEV46)#^9xPE_sFqiNJ>(REBmLn$ei%&e zJHT`>j>!U^bR4yhbU}W*GNA&(;0Vzi7{aRbj9?kF0=OqER)Rd{?&9^sLV{(Y|L}mg zNU~K54iKO*%cK*e_auC8*WYkYq=Ks-{*k5BAJs+ zPlgH}2sQ}5p$E`K)L7`|%pv*UQyK#Q?@FjpvWV+MOOhr_D4K4{oC?*66tG8QGdP{m zWWEbKFU-V0h%;bAR2R8eu~%VHAj)#ZZkPj1l^>N|mtK(^0K&Gfs3zE2{d^PLtpc#a zsxfB@Fv=$IdrX8G?$V1`LBk-G^ML>!@?4bGh@QbEK=G zyN~AzbS+Ye8q_GL46Cu{V%52)VdKU?(NghDX-%+9*_Gw0J!(W#StHimRHv)Qsg^2d zDZ0ybvLBM&;(mCdC;)TY|M-6(zg`s`&%MHlB3Z~epg&qim$K)8mHry~#5@Fx!(2Gq z4d6KaX3!eeic?83;1;EKR;cbSV za|}qyzmQt7xF`YJo&JI3nl@NYJteOJukG@8^uPD5^Ud)c^fA6&{;|Np9wr%TNl+ik z4Xz$4_hV5LRAr=2Ym@FIxTg7tV7EyyY3w;fw>s?M? zpr8Ijt|KRqY~&1b8Mz7n{S?qUJ)x6v7$~C^(RVDurbk+adxb_bOQD}pPPL(4kTb}x zejfo9$YZ_Ym8?_CH) zYXe~vh@1_)K4=xLgu_FWv3k)->P+R3ZOE7K zJo*Bs0y6>w17m?(4Fr}G4ao$m4m~TF&x{Yt*{{(v$ZGJ*HozFczoPn3kL5{=Ww+#g z6n7Nmir4{VuQbXAMuY6bG1bgEaxM#VRck@`;frxTN@?a))J z!ybrnxMO(Nuo9sSe<_(P`zDVnEa1QMsFZ3-brM{H6Tv08SH2$Hj4ffuf&*xPJA!Lq zxBbpz(T3EhK~GZ_70eEDne%F4_I4nPzS-azYKP(obdheHuvUu7I{X2 zvF9_Ks79Z{-#G9Ofl;UEAxv7Bh`fpJMf!82=oWquYbhKg>WquTN5y4cObid z12LrmvMUA87A1n~C>@xo=7NvdC}85(@#XxT@GhSYza2ie0jDR@5AsdXONpR?%Eb^}ey0lTi6nIM%k;(Lipd@rY+>hnQt|7g-zu`>Xfn5HK9k|OPOcQ2h@CQurK2gi5e$+tfAIeK@pnC;7F;haf!pT6qG(`$H zD^MfQF7d+IqT~2!@nVTVx=wl@{;Zd#NViGy#0<{G3E>a;6gI#fyOwBWZXzcgX#o?{ zY~aG$Moxo8V;z`A=P#|@$0~Lklnyo)r74ZHejePMKQR09)=zk2~%}36NSp?IeCbf3mNowzD_Wy zxd0ZlyRI#+Bk;~zVBis+h==ZWx`8`D+ zMM0}d^dF^B$%)C2#? zG>(ruoOhA`11k{R6;2lUMSbyq@Z3UPIM4La#o`RuM;*`Fjv?f-kY89Mfd`|Jzg#v0_2kk2tp%P8PX>0 z{^Fc(f|KRf{ju^_A|Q&EWakmK6t=r@e-J#^^7w(GFU;c zhUX=Yj)(sANxEvVAozfJ5%PqavnQkR$Z@F0uJLMs{ij4I!Bt|H_@G219WI?O9V%6W z=ZP=rBA$t_0Dsa9!4SCV)rY+{Rk-yz-H~~aE^x3-*&PvgxKH?QC?T|pDGj!QZF>%? z6}5vj16z4MkOKbJUVbIa4tf3-{*(SDfmnbh5~YOuhr!+C60Jr5B-# zk&oL&QK4Sg1bkxqp@S0-DZWQwi=6=T89tI3+WB~Kd=JBljpIEk_jqtuuB5Ee; z1l2JndMTU@R-=o8ws5DIhw0!%o6oP$XLz~11H7rcmOLCxTCu_sF3k$J3Dsxn2HSzv>Nc59J|;F0tAKJ>LnW{fK9l`W3v~;>j|_==V{17QAae`( zIzbhoSoB2H3jZ5FiEn~;=UY)NAleUt_vZ-K8j zd={U<*{BA(Qo!5^t%;0@_C#89Yw@JmFTqBUQand;N_t#2QBKLbE2b#26ma{LQ?iD# zL6AEcBOZu%6}5!tp*5BT+Y>JWJKq875GCwfV8JtGiw=n11CMA{WE1o~UodZ=uXGot zh)0P1fsxc~nk{(|STLqHH9{L(;H;5FR!>XK<-K$sl7#VEr| zA{MqcoT(gc3v?K7IKMd-z}5@Af`-BYaIb7Ej0vs_vIKT)3A`x}fBH9-W4awk-dCgr1HrN-OHsBGVVs&BzVC&Rka9XViZG}|y2Ud8s7hDCuniAfdm+@=(TD&Sa##vz#;Sj+T z*mX05Hxpe5n+z`_6<{ja31{~KwmIvM+>QJV39*im$`K6Q*tf#Vffe%k_CVAf>&3YPJopO!7fdSrOH>b6ir<}T z(NHI5H4ugtN(U9daneqDV-^+DnBpx%Q1yXzE^ILF9MHfz64e<;#SD$mB8~r!LHm6P?P=# zpTK^w?yrM8_e!WlCWC*V2D>nF6a0(_>;y>+ra&LO8rhT>1lf-wUoW54d&zqoPShmd zWpEvi4QwFt$gXrD^pmR1z@4~;uONH%TLGEzqc&a(0z;gEs_LHQsP2fE~AT*Yl7u*it zlmOWYw*7Pg3ce6dQzH=Z0`f7~D-Y6lgP#A{P8@8<*nYTe;b<~X$G5}NktSF#cqaHM z_#ikb7%o5s`>|v!o1X*@@~XUt=n(Lwzl46xWNt5bQ#R(-<<{V)a3x?Sf5=$`714F1 zCbBbD8cmM&1QX~k@SFUC4Z^*FysH7V!5*MW&Ql?337n~11`SmSPmVlitHll=BJLdY zJ-jpO!}mfVdMav-ZwI#hI6e-Kisk_08WAK4YGV!gO`)gPl{*UF507G4Y#i8ohp~ak z;Yc4yF6M{Ngy)1?!JF%CXkDmj$ii%A8o(~wrNNBgFZv)omCmC3(R1nRv@*Ci*n+`A z{!k>G#*U0$fp5oD?nksLe<5}g%rpgHrdcAEfjQ-lx~uTAK4xM}wVZ;B8$*8PN?I~Q3cI~zD^LwE$taX$uwbTZ6Or;z)>)oOrwF5%nZ z%L0GjaCkba!3`@XP(Y+nyXk67ap-bnOLPu0nA?;m#GVNHi(cbW@J#V#H)Pf1Q{)Tf zedP$`T};xd;D?_I)%r@&df^ViNto2xd6jrm(HGpx+`X`sZZmA!-VF2P1+dq(1vn=@ z1ASgQ)B`MSOX%&?Me;vFNc0CkUl+JxeD;0wVgAYfi2rfm5;&I;dU)_VGcp{E?2Fa~ zjz1Fxry|x_FjUw@B*o7Ii#$cVQ@mHaMBE-+Y`dTiISsCs{X&^=ogfPDFowSj`Zw#K z3fX`n=xjLU8pA#K1N=0#;fWX@SqL@Sc`!A|p{w+U>OuL)J7hL_kt`$|QrD^8v?AyU z+L#dRBFJP{NAJa~h?JX*8h8ZnGQSme1}nxK*gI?mRN}Mw523FuN2_r=z?QQkF>AD6 z)WjZxb96V{>*_}zMn}iufeN_AS;1|J7NTQ#&v_6_1k-)Nl1-HUHVi3_43>l=V`2c^h;z|xD;&c&nOw$J}}%j%G1kL-w|iSEk@Iz@}H#_N=l2j7C$atTJpK{ zVR7Z$#e_EoLaH8xI6mzORn9#ZtQ z@J?ZuqNT+>O7EB7G}p8%-Cg_-sBYmuvA(>0!mW}@icV^$RuXr{aL3pweiY!=vFD2v&s$8{Kldb)&y`-(I9jNK0 z)~P-#Hp~0U>O=mjJ6Og)iqfFsx-Te#&1QRea?7Rw{FCU+NK1|Zdx&%7pHw193a>Ptjn^f7k9Qjv88+#g zY0s-jc@yb2TrT{;&qM2REr=g#Y;*J$kOfDg+oO}Bn&?LMF6`B489ESrK;0nr_~(0P zxsN(E4iD^iO1AB^9k*vXx4TFBE)v6n10yStTf98sOUYQpUUf&^=(qyIRbv6{z8qr6 z)j!n^Ro_$;OKDss?8raCt%smdZDd-A!+e7Gx1CHS#}Fq2`Tm$sB`ZKyaHHS|3rr++)lZcZmQC) z`p+6WYA&mJzDCXJiBR;?9s`bwbKV z$nT2w<``n9BNStxjRfwCx+IRC)&kRq@+M{VOFxvzOSxsI%e|(2YcFS0?{Xp>+{31G zw_(@tnX((o@tUPNxBda_Ph1|i4K_{B*34J+Riw*e;xI6B`@t5R$=e0**L?0%?tShZ z?n&-c=#}>642E~@Vs>wM7GtE(!goK%v%$5~5eAC2BW#|tT5H+W&Ta0UK0f(hFh9Z~ z34E>Sog_&SRCUmjI&Rz~$g2#1#C(#*qy*=;#3iaOSjFRVp8*@Fj9i4d$-Q7)@C@CH z76F4bkCIV;LuVtAXc}ncZwf?pH_uu(2?qbyuFmeJp3~mVehYDnt_Y2frg1Th5Pg$w zP?8#9+gyBg;lAi(N|21i6;-C1JhN1eq8oN>`Pm^>Kt-!va-8dD|?8yAk=-@DF z7%{}(+uO{obynCeSr(YOm$xn*S^TVU(Vv3_jSI#V)c$j<@L}<~vVbXS+vPqQ;4mkm z!*~k(kUU>=$q-7ska{uQQ+amPy44z1`@3rEDpNAjDy>dAnV4&(v|Ki~XX`J4Ik zSBbh}yY+9E*}pp2I9i5|744G^RUgzhi~lQWdP*SmMVcvXa@xq$qGUEP4;WaP{;;Nz z$|-*>{QyLCmhe3`i0?x;auu8vu{W$aoX6~?tC5HOG`vHv+Ur|gCK6bPc5q(&Tha>N zYnc^y%olA&m(wdE2Q!aZ1GgWRg(I@gN`q#)u4UY2LzeNhaf4A{Y;4GgE7dL0#$bl- zSImID?+ak>`zoL@24mU09QY<~j#h~rVyr-Ewf0SPpL7Up7tNx*5m zwFH9<8i8HJmSKai+TgTb1Ky!9WSzQj7RH9M(a_A`a}p1X^_pE*fLxqv-E3(M+dH>f ztJsG*<30WSPVx=&j{U-U#GfI0Be^Lzs@&>y?S1Vvty1ey_k@#AB0DHnind}IJUho7 zYZ}diEwPc%3aFN+?j<~Lz>|H)Tju*G zaEWXkY#3e^MY!kqLq!qE9K~t%5?x7Lt}!LSnvj_IEa7+j0^_N;xw@dbi*kW%xA>Z{ zke`ljLsFvo;fKsqx&&q;qx{!^5$Nwa?eN*!S`V3prv2pu%KDf7TQaC*c}YrX_cBq% zAaf(zG3Q$EH)07hGCB^ODI6iytCs8L8Lf%0QetUa(`RJ-o6#bpRr;f}4=JmYsQA`~ zxwVCuTuKDDCbYz zf@;4X=STC&-{<~liyM@MOnvN?JiUpBOxxIFo*dW8uc>qOZQ@l)byE(cW~TK?dyu*> zC6dHVd|~Vt_eI-X{To=Wv6AWdd7u%_@(1yZXesO$YX|QEU8HfSQt%HsC6MQ>?OyNj zSvQ$SRqQIOSK6;c2>;gZrKYlElh@MK5$EX`xJ`GDI1%tQimcKj%0HUJ`p<@W@qZ_1 z6H^jzCsf2gGWIrH)jPB*O>I@CV!G_0S2*<#&{G)z>w1 zw2!sNw3UDZ8mVpuQH9r#Ygr}TB)JJy-&{N*+6&&P=g=kCAUFXNbQNy|cNCHwJrSmZ zbtuRrdgbm1j>opYtZA0h=I7>RmhaY=_ExTX-c5nZv@i4~x{X@}nMd8kn)9%f;38zXP$RDdlXgBL?8#)=^ z86UvT_h8&`{ZK8co~k$}{e*i3N&Jc2{MZ7vL%0*Oi2eb4>LUJIzQx{79<95=dBd^R zKFrn;wmUB}7n(N0PVWlSb+g}c)n;`Zc0c#^AnP#w*>fBPHV3~Yd#IYJdtlg{@Fi(Y z%Hh=bG%Rg=YKN5DNpBK%8>_}0(Q?(36(!O+;xrKjSx*$L%b6Lw$@;@-p=QB`l#F=g z8}2D~X4&6bvP`^ke@TPlqC$S*!#~nOe$n}2y3|%N&$`|z^p%oE8%R(TI;Gx1>2CBa`)S|Uv zB=()V3@Z~6l2h_><#jc#^=KzSuDYe}mNuXfX)twA=}=hZI8>omz>2p44~Vivhr!l) z8+KXHXj5(rgdaT=7BVBL>jAazuzRF)ft>(;Z<1vpY`z`{IlzUkw%!>56SXar8I5tk z;w}6k9xa=t2r2`r(dy3XtE%(Lj*7#O(tVA85SC&_{(7`F*9fMT7qG8sP;5+Wb?i*+ zaqK>L3o~M?qleg85m9(L5K*5BkR!a- z!iQo~mZ$8bX`(v{_JM10BjVQSYwMgMVgBz3peo<=u6~E^lPL(aNQ@s)cA(N zsbS#i6GLz3066%aUd)>e8WU!70ct5aD|-iv6C!6GBxxm zSec$i9tqs_J@VXe9e3=q9k4tzB~`pCdtKVNv{LE8(od#@0Um;n2l z3&}*uImK;FkGK)>KN2q|7o|)|9hiDGWleHmbaibj4u1C>2 z+DyOr}_TY}|Y#g4K^C0WIjiljxoi<%XGDiN34O(Ses zuG_weRPS&Pq%B{H@0Q(DP0(#I#3x9Sh9-+s(o?P{KTn#Ncqcx`a8f@}TS;wF+=CPN zDx`5z1S=uwJOSQ2-D0QM@-QzX2s+3+fmyzEPl@xU{hHNko@VM*akPAF`GxX@74J;h z7PsxZGsjak@Pb+#Y7(vBOy%De-V_g%?NdxveOAAL^#3;P3@xS|uQ{l`qPn5HqBt+V zAiE)bA^9P;d9wPk?yI3!LhYo<$@~;7Wl8ePq+mj|_&9iP zuhvvjeU|T(&J!;aT@)bL0v;bd&FO+zql;KixN~TEa67e%7~nU0f4fdOHrtL`e5U;s zC(Dz|jpc{R&r~!v_q3MSi(HL;KZ$d}osq>zCeI`2EgmKlC_AbZ+KIYM{d4^{{Xcq2 zm!?b966)Kk$x5T*18f0nFTuob!ExSP@P|K^_Yq8Hjbim#S@=_M8I?|a^BsiW?NvvL z-C<3%zOa;7mRa}NsyS-9c6qw{JCW0Zr^5x&AjiVnEAWZj;`P$2Fb#Yoe-2Z?molf+ zBPkH);J0D7b(x?x+#{MpLi96aL{C6spckLw&43f?0(U&8D5j6bLsfX6o=3I_RQ2`n zJag@J7C4RrBlp~y;^umX`V+|7!R28We2TC6VWCC5K(<%WSk+H$R(sWppyO0mxmLbQ zI$zvIBoe@J3hB$`v1-vcwkvFc8xqb4OT#GeKjop@a07NT-GTYu2Fc{%U@9~Q4E~P3 zE8cP5xn7g^g-;AS1AbB67*T{9OXFtomka*}pAf02t!6cYb{rO-Yzs{AH}m1%eD@XLmA5-?+C}!`wso)p zd8B=kqu80_R{3%QAE@NedA2`C#(yI0{(l^uWq1?W+lS-HNHX!HsnAlO=;H3~*2Udz zf#Pn9Q*3c}cXuo9u5F>-#%(5($z&$U`@H|<+7J6>xtdPqob#OD@4oS)#Ch!i!!Fa% zxMP;F@h9Ua#ox0WkE?H9V%(x%rX8%VtJ32LYEg8R9fYaReql3#74A~&@Q=gw*|p3a z`UQ2(zsB3ct#>+X#bvtEO~vDiE*CB+{9O33s6)xvGPC_}m)w^WSP?QuvV@~#`KW~m zYbO}f8JxZ}PBsi;cO%Dxqy z8d32Z!(|~8lLF_KY~Mc5Fjrki4co}Ff|7^DXz|yg)Z$q2q|y=A9Q#{W1>Z;N4)cmD zih0Ce<%_Vds+XGX`awp!i8F7Dy9E@p&*mc2buhXA)V0%|RcnZ)$`ClR3FNfAtt?kE zNo*DN6dZ_t;ETfrp;y6EffeNB|4p1E&TIDDwiH{y+5~z^so=kU?oRc+BQF8nCRrpPCx3vLVd?hev3p#hu|9?|tZ-MXnBbfR(eAzZ|oPD$52VQ}9m2 zAB{y%8HSnqnX}DybEf&F>5Q?ZVYlw7<|FYAdb+QXKXO#oTXGHPpbuh$V0v%}jK)u) znXrxiNlD0LUtLcZ*EGjXXu4TT10`ciI+vU+*-|R9Mr@0n^E`$A6Z9q47O4-r!XxN< zRe5bMgT!3N@+m$yp-*D##B&LU{fAjYFQW#-I`42jbX>FLmUSyNm-H$Y6*nywl?*IxX}w_I?ecq1Q2UuI zj*cZuDl3B6EMk+kzG1jY8duTs*ivZOX!#PCWgc((X-Luc)h<(CRM~*-u>-*sJ7u+` zUm=fW7M_pQi0ow^KC=8ZKm^?&Lx(TP~CdH}5YdXRblgjNS?wL{TT zu>!i5H(>JHLHr6xb}ggL`Gl~Yxk9g|7WnsjWA1CNSI*AP7S0RKov_ls@P_k?pQzdr0|+@W1X5;o@NeMUE0xcZB}v_okWLV-gxfWTAV*Lp z5C{_>Ka&XmwFW#~7GPe!;M3u(uL=zYYDi7$xBr9B=zHwV@s9IN^yiaL0y5?RJA5S^o>Y@639Ru?6+2|JBpISDf?`PdrSf{NKD1?h zp}8Ry@POMf-ypH|gf2%<30$ElvN^dQ3{TH|r{UYs-mfBSQfC4Sf_plg8<9cK zDY^}}RS0vGt`Rs3z1WTLDK2$coPX>;Y)0D|>pm-MeQi@aJ~&05qrT%*IJhO;H~JUM z@tz?)mD|-zby0)NyfJRG1&>GKH(5@^4Tn<_uNUhmb)M=Y{vBn3r*=`=N>DOZCkGmmJ$`6qlTk}C*`%Vc{I2_CQdNz~WW)Be;}(534BXotbRw^$t|FhZ+}Q&xcQL??78 zGF35GJ`M5}7Rh6{|2ZDZhn8uS^)vbO530l;=UeHi?{4JU>m2Re1H86A?$4e}z5=oz z9c5mG_e4etF!3tsBl#Jm8J2;!QeIKMP_9*ql&$b|_`lbJR;^B65$qf{B#j|8d>wNA z`^AUF2gU2*u2>+R4HW0=g2m8noxxuY{|d3eO7t|!?LY5(=&j?`dB=NeL*pfhs!i`> zx`wMpDhN`BzH6@x{%}AJ7v?cBXO-P5D6mhaDlK!F#f(CGR=jM|j zC2io|g!hE!0A0Oim|;(|&A{M`hB`BIf_q`E7Nj~;FUW=DEb=bdm+B0;p(e~<>_jdv zvPe)*OiGU_>H!<%60tzz(9*hH`j7fU;5bj!IW!sSER_ovU)Io3H1+|Bq;BV~HdZTWcy8(QXEu1x-vz%sEk~`Bg$d^fKX)6;BH;wKP z(vpsfIl!o~Xr}6h7;=rJrUmA`=I-XbrcJfscjVb{OtB6_Wd+HNw%* z2CWvAz)pV-bhM`eS*?%?_(NXajky{*w%h7hQ_JR*HZ5IL+Nx}Wb-4YSbBX7gza_0^ z@rXs3B1Mqfc%0g#J8rmUY7y7U^1yQ2(#+B?&S1_ozSQSyi_``129;thklk{l?51R< zxD%`vW`Pho>c{!sTpn~(_60u$NTB9c^$v1haMpEjHiK=WHN*PEy59E2zR0=TZSvX4 z2;GW3#ES&|#cO4&kmmSN)me2 zt&qstCg}%V#{+`+*y6|wE(9Rv2Eo38<>Xsn``O$-T?R1NpL9xGuU&rkT<_ohdDJg@ zbVvsGpGDJ{GSBH!+N)?eRYCAPAaGU;{X~|CKa)DQ<7eA2p zRlGvQVCLSb{;9d5Ew8Hr>}8df2Sy31>VS_yXDXJ$diz9#2xr8ik&FB?Zbo=9^s8Pn z;b1K|qiqF-XEBMvO~`EDYi~<$f#(k7`RaMCUazkk8KZ>Yi~JSd8p#k06?c_YM6$7d zs*UOy+ORIskZq`Lv>4AA3iTg#i?y7(AF&^35Ao;(#VcTBeiF|YHG-*cA!OKg@FTf+ znEZBRZqfvtmA3gldlK9$ohC<_O=z2K?QK0^9c4ReALiWRt_{3WV2p-;M2-n3Np;9- z{0gy5Tde;G_XJhrcE+uVlgA~Si;cq!$8^s%--!Zc5G#-VqxcD3zXW)L{sA*UL97@u zS@-zmT;=e&5Dx47d}=2Ul5*V1u5FIC_BL=99bw&JZ3Df1sng)z=p9Zjg8QXT{QFoZ z@k!YiUurTv=o|q2Hk!sEw%qBP^;@cvCDF$%KZ6N|pyLk!7Ne zLV@6Pv~lD*X9-UY-3W#Pt*O0!!gtZL!oAlObKZ7-aJF+<+&w+Ny?6XMz+}A=>co{q zW(n+~deYAFc;p0H1g_8-%D3QRe5jnP4B(^iCs;f-2hBmc0ChcGVU;hF$H`C2(qtQ? zpCuk~f#|rfDg3QIxcRBic7v%9G~mgLzFok#nd4dH@p#@r6aO}OEkFmSvKW6WIz(s_ zcalw1Gy_}NSICFv!rwMhc?v&=Ekr9J59R4H64G{SM4N>#1+@k5W7}d&z)!R%b}jZi z_7p4|Lt~C;r|6u>JiZU710LBFpq7LJA*wEQi`+y$hWBWzPC?J%4qZ`1J>Y{p3k06~A^ndo3_#2R)$QzUudfe4Qb;2|L*I?$wTY$llf$deU zBvLdJwf%I(I<3A;H%7NZyIj*q{X|t0<}x`*O~ocz6mnaMqIb}`8y0N{1Z)@BY~VJG z`AyG&sq-?w!nfbk*`44@bxv}`>@ItA2LpS;%kB$aCHXw?k`ZxZqd$cmrH2%+u*<6U zngu}K+hv>sY_spCk*1Bt32=usT6;|WS;YZ|W(M+A-UsMW55$MTI(z~MUjN^WeE>*3ku!kqW)H(;HAX7yRO+Ai4JI6J%VdpD40Xc7A_uNLeP%jNCR zX37F0RmCd0(z3t=pe|1ImiK7gZGrZ;%lXpT&(+?&#Z%W;ksK6w7VN`v+{tKr;VW^f ztfQhT`T{d34XW4RUL8oZB{)^4idCjVwz&+e0j-c%&^?#~4#pJu1ld8z;oKMR7Yz`S zu?f+~ya=AqF>pR}P(y%lWA&Q62RzF>&plJX?4IM_LT#p>GZla$qKz$r+;D;PzPvlK z0dlHhyeW`%9%6}*rtgKcQB(sWSUl{NX2DJJIA~+}g(X6#kP{*zR745yf<5ykxX}q< zZyw_7aW^2Ldn?$FE*B_I{X;59A$Zdgz?Sxq-pX7A{=l-RN_a>dFPo-V4{VGac#~ct zVuYQTK^%o_avHu1EmNe*hf0qDM`x*^N-P$UMjG>bxFn#(EDW~>@Ag+nlQo6pQh#V* zRb^H{o4Og8rP>Ar0UwnBW{eJWm*8$N)(bc+(kiw^NQ!&O_A8#F5Ak^_JAr^#y`}bV ztr}QPht;cy20(MF4os4KpgtUt#EDM|y9gw}8oR>p=Qf8|vhzaYm~Oz-5(j>fm;GCS zY_QAo$=%#-cl~jtx*xmmdNjW0{tr}I@M&l}w;{SqctUbiz7S1PE+kfI>geX{`y1XG zej1h=zUi}d2ef}__7eeRJA60FDQ3!LvRjgs;>pklo&$FIec<-n&CdZsGR<{|L@ zdXO7@-#rc7S#T4x$?mmXvlZD^LAIl+E6uaf*OM9=Jjog&+XaMVihMu1R++5suT9l2 zF^n<(GX60x0gAv~IQ52se0WnOQx3tNAT1R?fC1SbPK5PfwP-157i$hY2?jX*z1eK0 zNAPAKo>~n(+!LM|Zn%qZPH>KN-gVA$ZE<5jFo=-DX$pvTvm(s}jOagUSY8Fy;uqkz z=pnYL9cotnN~^o*W_PCHi6b!*U&ofW0a2#5zZEmkZR;h!2dTNl>jrP z6>vp2f^WJRGFNd??vyo>?U%+u9&-{{-x8p25rHd~=i;^hbA39&2jmBDM#sowE-kz+ z6bR0xQv*_}26@sy&wtk63fey#0uABKHaL8fuNFHlR7(cSW-2o@C{7T40BX;5$ifbUto9jxIiCR@juBwys0G>iV_a?EZw1)~>;&i) zybBtFOK1%kI7$Nz=r7>s@-tJ|>RfW9Wo*9ikytFNt!N6LbCX0sYKZ zs$I$k_*K*hl-pO*s*?Sp3c{DMRncM4V;{gx5AS53hA42U_JE&gf8Yst=*y8~{LjHj z9DzNB8W;yn{q4vDR4ckV(~rHuHH-chtQJ?5-B83~os{*6&+0g>M7LGxQg_>tiEC}(j3h}>tlVe7FZbF zhH8O->jKK?J9&3`zHGUyF4*60NasuIOA94)z_im6NVOA$%>}OL+=vZm>!(6WCKJxw z5-Oft;&0&Z49vQ<YS z%a_TjO7mcvyhC_OV2!22F5*mdJrHoWMvq6Y!k>L`r>u@{1>0>^z9ZKI_P=dmg_;z+ zOjo4~19^ce^fUT0*kPu!wYe(bSYIf-Ep|vn3LkO;R-}et1fEN5A^L)=+yiFqb(kJq z2_&Vq(zD`J(KW&7SUq^FG~~y_jfgTlpY?>shJHgL=zcI2+-1%{Uofoo17G1g@)a2- zCsO7BPPYp_WM;FYxP_6MF_EaRGm2u2&c4Y!1>{{;Nrx_d^tFS|OrYC>aL z>o#~6dRzO4Q}2LmJcJt&ogw^JGGE>a&Bap*qvkXaPDe`1nq@$pRIS2>~Cj{AGy{rw?llFXNp!V;CQ^bB+0i66|-xROK!?_Y%na*Bt z3XM9wt`454S4~a}Xqi&>7ym2vS#(W0S>Zw}DwV{3^?S`h=s8x`QQGO+%bNRerkDgI zh40upv^}DPPxqblF&I~0i9QLxfoC-5(IzL#wil{IhJBtV}vm`dVTE2f`>gN2LfpMn^_|!xMTVR0Sq$g95dwHsmhotJMUz zbUD&YjR^SY`^+u&GZ%?e610L0wOF=Q{s)rWnP47c(Z^^fbPw_n%x!m|7k31#f*(YB z(GsCr_yYR0Tfr`OL68L*-e=IS9Rdleho4NZg1u!pJ)+~g8SD%YaV1tvp={tq~U z_XSC26FY{R7}*F}T(20Di50Jr9@skA*NaunREetdaPQ&+8pU8($$3uIVRl$kCD6bB8E@ppSV6!;jq`SfM4hSUee9Qc5$_>xT zOxQPFi_R3*krc=#Ay2Vf03%>2j(#C!gV9H1l7bU*(;b-u2fDT!s;|Fr5&pK2WDKGw6|e~KZmHOdJ37w5S;4= z%d5z6sYIfL7E@c8lq`#Fi|z!1?>Mej*cRHxGzew~R#P3xG=FVhhS%x2;JNRyc;9;8 z`7Go`Y8kx}_J<_bD!NXPCCZk(lr2{X!TZ=0yrdI=s&^FVP-f*pXoFA09-uhSXL!{6Zh&(T){o2i3944dWe;?M9G1KaUBrJ#2O z`-hr?yR~_=iJ-j5CSE2jkO>ueV8wie{6fwn-I1r@ZW{!=t2aP59Vz($*3$^wCGQt) z6s-q3!6wnaq7kALSfLt11L92VWb|L?J^RD^*&ZPS6Qko`E-MdssIx9_lD zUw^P*--mf~a;Pix`ghZh0#2#|HG|CcPx7bv<6uR)=bsG})hys4CWKPL>HNtkDx4$! zE=^K2N2}mJfXdiIt=25o?9`0Xl&I6xbqT%dJM0M4AW5=7-T(|EZs-(6V4B`buo?)J z_6QO&@dQw;ZiXf>ir_(bw|wv~_4W2b0>@3b3tgCdyL++cxp%UEJaq{SC+_gG$XP+A zxQ~ogjKMZ2M-q8zPIFtU*BNwK+H%@vnhNSt)mmi|WF0ypZuu!_lZ};35dRDOmjZ!B z@ONxQ^f)x=&jK}|KdT1T_egkiKOi%Ku(!_}@NDtS2ZmV-Z<4RK{}Z`0urv4~WZ{-Z zoUtyVZIT zz-W9?U;ljgRNIqAuz4<_CCrV`>hO5*HCKbK z?E!JTbi8bVJYC^ZbU~&eqmin}duXnGkhg#?W5xfmudI?|k_?!nRh8fp8}Lu3i`9^L zvI^sb72$mLE3%HS#=T~zhSC^O5TQH68oZ0TN|l4v-buG)K8N;%SMqD4TLfE03nWct zujNK00sW4)!1`kquybetoW+d%wQM6W+Y^9#8xoiV!(#8iqZ}9YMe-wgk&=ibQWp6f zISEG4DA3GHx%%8};M6%nbwgVjJ-EM*2cHC!na9kD&?~kQcZ1J}wh^R>loG4-w7fNP z8vTOZ1y}Z2AQesr|8!NDo9lp4zCdo4U4xmVO!QW83hZv@fvu|HM{p0r6~kMB5;Fx_ zMJ<@4L3wZ*T^tx65QC582>fIWH9Js?t{fc3ybDbWx8&e19#aQ>19zXT zR61fG@r(FCEG0-)O;t-}b(k_gM^-4>%5hmS7+0Q(J__yNIBo&lx4pob`vDy6uRvK? z!*qqu@Flg0oai3~wt#$iRt9@Ec}&2`tOJ~jgMp{P6!tvVKZ*+pevwR=C2Je2)RCr1e?@ur1n?}|O)DDghy#%+)lUQ@0d^luL#V>RU zP+x9A@AC~&0u$2yM3yQBJhdu#MVK7wz?7f|vUM}qL#+~D6nz8M9wsox)KLz8(&OPt zZ1oTc9Emev!v0RyAn*Iv`gi(m{$=DKpgq2%yD-7fLm=wSjCK$xMCYNmHAl8ZK1)#! z*@k>YN|3k6e@IhseT`Ju<+J1x`2krgnH%yB1Ep%%%Z!t-;#pvmHi#O)>B1DtgFbcx z?k7xznlq-Lh3*}APA#UEQ6H#DfnM~YU3>_KRB~&f@$(+Xjg9(Bny7V&d2u04#h6UvSJ^AXn8BPCe{GRWVNGxFkf#B)?|=S96L1p5q2>ZVx-_5{O+d7QWTdE71j_>1p*zkbX84M`O5Cf zOd!kd0J2s`g#nn)cO?hJ8$}z1`vrHw7p;mmhaKTIILkkW#@id_QScId6nH^r$WQ)w zn4@>_HSkULd3+E2Ib^#4MHc~yurHq#Z6LfLR?GS*CZX-|-^z+ag8Gpf*C3iZu$$>a z^nn?k7dwXj4YvdDWJiIpyi0YA>|{ z-Zhm2MS*`**ZTu_V$_xDiXr#qzOft7Jm zEQEVGDfkW+fDblZ*iSf0I9WJVI9%9BNC`FyB!U63n>iTS&u;)8)kJvDZGwbC-yj~8 z2HOSS1a~nf!Jj;XONbOkZwS_jdPz9xV)=VTK5_xA3ohD`7=bN9uL6bmAj}8TfSi6p zv_LpkkP+JxEs6AohW`qn`{R5OcaPi3jf8zgZg@pFF?<1L7LP*RLk?y?bTvmXOPLQ$ zdI)7hteG3j=R~H&48oV9`I1E0X}K2Zi4Mfl@Y}co_GeCf1#ZQXu$s_ukpa8(ymTp0 zINFFB!=$NyY%wI8ZG0L(0a!{UtOe-0bD6`ynurFP2ewioY8N?>>_ILeT`;fM9C$`I zWQszM!cX|Zs8ZMrrazP9JrNHyK}qvC*kHtYub z14(v0I8IRE5WzJ#oecn5)O#KXdf|NbE>LMY1f}#F=&kSYU-8Af>w&Dc(ChSG_Pz4g zrb+@iK^Z%Q`xxmicq6JST`1oM^KFIlZ&eS1hUWa=YK?j`nM1iuS?YVi<15gV+U_cs>4K(xDVQ;@iL@-c@#1 zih_SBORN(25-k@V6#eR3gjv6qTiyg zq8FkIq7~3NE`+Bw3+Mo5;Qfmt1<(WE$*zWV{y8`lU(mW1);7FzFjLc`c5;m+I|-U-jBM0gDL z+MlEy>?bsdW%y&PJy>-g!VdqEd>uS3HDJGOhe=a$jECgW_{a?)D$Rgz zLi_L~)&vyO0wCm^fn3mkbRzu}h@A_7+*uNsKvxKwnRcP0>|b0ye?GcFFiSK*QdL$Y zhnoj9g4yxyN=})qlBq5M@!=nQBQTyi7el*ZP>$4R?<(Qg~IlLIC4$tTls)z!Xao_}fCit7F&t3>O;@?Jw#Y%v~bV~e9 z@^L zCuk3e>f{K^eSpUEb~tlC3nm25!ijz<{T`^mwV9Toe_3yMDPJD^&$EPxc&X%r)DD!* z>53nUu%b}03BDBrz|TH_)-K2o!a1Yz6Eh$@N(M7?#We11GFl*>ZjsQ@e=$C z{vX`@%&Itl%23wrZFk(8+EVzR&fIc%stf%E2ABkQzUrs5e0EsUMeDv z2S%`Ers~Fd`jy&Q>QSn(_-3?JF;Py)-oS3Vis%^FR=@EJ!@n6RjgxwBYu7{jRcrgQ z9bgD~Sa#et*!jWpjqJd9xV_NAY>5=(WdxW}boccU{ROyXeWo3y$%SwF5nP0g0!p=5 zR#Q?_BoOS2K#M*!o4!P9eJ|ZU=XFO-$2`X#=T>)b-$Uvg z2bvVk7b2v5fb~V3vP+O&XbL%uRk8L!5nB^`1}yjoa1!YqCHd-{j(r`R7wAc@^tJWg z@*5)O*P*SKRkWsbs9oh5O{v(| z(dLpgqzm{8muoY0ZFDBBMZHwH7R`{)k-QP^i3NaeHJb0o@8{9TjL7N8ng|01j1l2! zp=LoZ_1N$7p7f-8GCh=c9QhUc{fV(mNfq=A@j?&w^@RTAvXX@}cO&1!l|uXIIBKmg*DZCbY{JrLVYU40zdz?(&)%H9Cgf_=O;-^wpPBU15;gYMF@ytefWDLOkj@mh6#j`; z;f?Hm`mz78dx*VSX`8~*KizV#WVg)L=QR3#I=^*Ep1q+DWw2@Doi>;s))_b$IYn85ufNS3X`7O9`Dv*mLorS-kQM@6%Dl{wDHc;&E;j$R1g z3?3zSdR{puS+AG;C<+$VF4|H|l+DSHe8YFw;9-n9$;_6#FF2gsIW)-1$(I;AN_+f2}9W z`OEgZw6rL(;QXIgxkqv)=CsZ2_Gd#uv}Bco^CgDP$9l@|sg4`&#J@^DT%mf}*vf+| z*GN-TEMNXkk~F@xX_u~=TCMDezL&3)juzL4{&!D)44V*KK<@Hvc5E-pDcYT{{4*&x zH)l!ikUz5u&Xjzy-}fd4ukaPcO_B4e&N{DgZJaUwczmz;mX<^2{l>BSByAb-UYUzw zXivp9*?s8qOc8vKIKuas!2y?VpL@3>&eo%BOzFbXlVw(0ZPy52XZm!wh2ViS4;@Vq zx<`h7rf;SWrZdoxsEESU{0 zz}?OsjxWGGzvryuIpoi!?}o*KsnYxCal)e;YqG_Si_eKqk9WqsGFc2t?KjmfY^GwR z^pj|?z#I*7`RqMdndH<2-y!!?hu7M(R9!r_a7n@1f}@2+#ht7#ovr;#na{BXe)PJ)B)*1?AJ%kgA-0A*~-;PK3;Bo z(iv!brkiEPXSxH>R@$cAiLF99!4t*^KSuj-JD97~d#}ay)}|>-DJfT6rMP>^siz8`fNLUouNLJ$i;Su!n;60uTMQyvtk{?eEIm#Z3yc^CG{0=5EdH`@30Q zufk2GxemRbWxB>5%Ot9g`mdI}a`#jFS2~;aAnjtMQx$%vtW7GlR5UHtA?i|Ghi;K~ zk*0|e__>GkN7=2x8dRqDi8ErIUedGhb6({?OMZKQXXbS&Oe)Q__wlx)r*g}MZRB(C zVs(aIXxeLT8)uGdYW`(38`5-@HI0aI%6nKH^e#*$uSmUOoAAF_F>htB2ggy>eAV4Y z9CyIr1j#;ILr0>!)HjYE9X=5IEV+TGREIR}^~HwSMyc_FeutI>(nbkV2784(p;T}o z`a04+B8+77C-_z{XP6UaLOP}pnk30SkGq`93j3Ttj+U;yo&rBZpAUbGnWWv(O2lNH z&zKokCH`f6MtoySC-WOU7%4qRCVbvJRe+?fA{Twi9ZtuCN@miYq?g~iO56t%?K#;QU(C9}gt;CVK$d#@ zxQ{zZtZAiNiaHl8%o_ma^*eu-k=P`s%iFVCDe zFz;%9xuR{Qc6-pXD9}92$1YsRJenb%E3WO% z8qWRBpsS^KA~`JR4ZC7GX=T)}s;0XH4K8u~z4+zvQ!IzgEsXPYv(&?s>F7W58xm;R z#tubha7|fPaBkqIU+-<=nrMGgHofF{(b~d}Kn-|be5q`|V~Mu{J%IZo9IZI58mjLW z*EA7NzL=6!J|pFExt573mc2$R{GP60^A&rg31SNRM13R2xB}M4JfV9~dwkd3w;f-s zRZ6L%A%)utZWjD0RF$-|j&Qd1U85Ir>B5+-BkoiG(C3=yxQg+M;`Q-b%RY0C(XSWi z;x)aABjB?bkKTgJ!E;~^9Ez>s)7Wh^>7V4O<(y#~RhCv-P;#L3w0*0qpYKs%7cfn> zit8wv;j5uV+Cz6sS6lZ>^Nr}M+=@PwW70#ST>@#$8fgIE_Z$34ehuH0KLwWA*=!zz z1``5J$sN7{-pigW&r$CPe~22$4CC@*`z2!$N~zOsFf=iXEI%xFEcfHWroDz2+Ec_7 zyaAF5`Z{dXB{ zbhiY<;xw7Ya`9J^Qd1_E-%|cO&`$;?cDDqKOLP{s9T%We<<+Fs#RG-AA*cG8+Xs}K zu7M_gf#;rMkM(uQf}*^F_=4UATMDy_ldSEW3BEZr!Ce%nWn!#1k)vI27-Z^gUT#Ls zO4C(Cy#62UJ#`|nLs=fbg|v2De1HR1)g)x47<;oZar_6+lM;$ zdbX407?!gNj!HeqF6C79Ky4T3#E;TG0(-6tOGQS?-itR2@5P1y0kVKU0Qs+}Fi*|q z(zvAXW4Np73U1b0U_%<{Re0xmZ~H!zx9GpwMG=wcs;mpPgXpiDXgqFa;)Ym$$89ig zG>Y{J8j&g+eId`0R1sZ`O^fv9da_-ZIy6rn^p%5mC<7dg(Iq#F&J|8Bv=qHAUQyP{ zVeiQzE!>R>QrCTVfOF8zUdzT? zvuyu5YPv7_vI8^O4pBtBTD}0gqbjG_0hZ4TkY4zY_)ED0eJs~Y&xrO2!r)ewgY9)Z zBC-qLZq}}>CA9$jFDVGz9^e( z@^ohnXN@l7M&kv;3_Y*S&=i7Ql*dnF!%-D-L@tz-lQ@N=W9#{8Y@MJF_KartA4j@< zpY5Y9Y&W@#-cMvabB~)TK%|Y4FZfAfFC>U=XuX=r>U7mtEE)L+-l6+}G}kNo|Fq5_ zd;@6dP~09a5>|(Qga$Ad=@2y(OlB#*kKS6oe*R8Wj2_MQi5wD|WlPZ`s*c+Bh9#zK zb9$WD{LJJrY}Nf#+mu!`B(EXeEov+vq9|_)r-f33qQD)0cX-FQcKoznEDaQYEc&OY ztY~1#yRsIJ9iE%iBzAG^g!ClVN>kI=*)k?Equj{kPRUKm4Nokz(5Bb=|1?un%dvcD znJ<)_gd9h=*ng2T+)7|n{S#Q@U+!7qylksq)}|y@w5do@Jg+3TEXh&c^N4)F*m;5I zo2)uktSZ!K^m7dsqsBPjFk4?)cU@CQeOJ{_iNIWE3ry2~0EMoh*auvkX7rK;F<#cbun8rbT%jl<_+u5^R@Q1@o~QSbRa`%vrX z($Zp8v9LI|_)_UoTT54tuYAzKxrLPciqfN;YoONiel}Ah+2nxSl%YyW#%fXkZfnm1kjbMsc^2__7bSbk|Z}6*?)L z9E*q-DrVu2iC$WhKHf0dP~I>^-yGVr^VA4&S~(1_j75@^`BQo#W5>5L@-y9snFp?sz2(0rUGQIE$U>|Ltw!yfZgI% z;Rl#5wSo>_H9o{;bC8k$+*imz!{d0$E7o5%3inJ51m1ZG# zmF+ck^ka=L;Z2X21*TqxMBN7U3#AK9R?LxdqML#v(aS*H4~7&BA9zd7@Wr47lVT5+ z)dFJH)Z%-^0pJsKbM*66rZ$HLL_101(Eo@j`jzH$@gEY)lEO*JNedEcTjrYP>&IwD zsWxDo;tEX2N=2=OXJW!=eZF?s&5WlnkYBwFJo`CTPwDZJq>@=BS4)3bzdF`=evm7f zQG7k&D=CSrR89mZJE=RMKcP?6H_<7ySHQF32d~&XY#`bk(J5Za+DYe&hYP7_6TS=E zEZB$|vaE2Y2YE9GwUu1s_xs$wo&FH1r}LQBoGw;fJU~7M zvk*PCdHS=)6Q+-*+NL7tR9w(#h@SX*tmx;dFn&j6FQOpjn1MoXmizTh`K5_+{_(EcOk14!@vZvKypwtRX|2+ za;-z{=@H~3Z>HPh#GMhxN9Rg64o=x}u!fw9*&KWjD=s4W@YoEVMINMc9Yx zB%g&=aLKiZEQ0U*EA9w42b^w~!8%O>^|)s+H!zp#MlJ@A?>r!Sln<;9u4R=GpFkj0 zA%%D^b#>i9LzZ!%sfwwk@tXdWwz>MC(t$QtT$T0~R}fZ=b&f3K?ttIZNq?l)`>S~$ zy2dz~+9s97m(D8LS+ch@(>l>n#dD5)%k+o{#fKG?@}BmMk&kPTFfH*?qBL<^{L;99 zvAn*nrWbI>bjUARAtYkgLPv5^^cMdKX4t)h4=B{%+jGY`*1p18zwAKi*V59m&$bOt zxSAt}GCpp(;5V=++u{UKNwZqpNY`DLuf?^L`X(5Ysw#P`6fHyw6+giw&{KL*{17;F ze!g0`4Kp-w*k9k<*&TDvgDwm0;ythYjp>TOh1wxJDIJK+!wXf5)Xg=OH9gdCRWI;~ zXn}l?G%P9-REWKaeBo>JU%7+aY@h`fhPy*jczh^@c|;EhBv2{j7JsI{0y%{mPb)%A zfUNOUlm*TACaV6L9Nh_6Im?Wrjr9z3be)0C*AU-<{spcxP7h5}(H7_kK8CH6)Ok%I?s_QEX7{YsE)up@9{SbpWXPRiKoe)j@ zjs)}aQ5?U2$pr|2_O1A=& z^$)OI0$g=AJ-C(%`QCV{xa+$R*ELro;23S8Dl;ium)K}=3;9uWqB4Uxp_Xd)s^=09 zl{>Ji$Vpj!Nl2&=%!_u4%z;~{6YzO<)DPg%#F0&QV5kBfCsRuhHLi)*-fyco; ztd~D3SRomwFyIr3dfI_tl%8blWn6AB>1%1-#583-nyx4YCea$5` z>>XV*yj7`=%nr^LLnYtjN!UkaHc<~uvZ(gF#;tY&S!D~@F?(UX(6Puexa(Xe>mmIn zR*Klz&IlWB6w07qlmGaZd8)fNyY9QP+}pfW$dR;>)kZ1`_0sc-$5<8B2jZCel-fmP zs*d5KfQvR?3hifMhge}G2W(*XxrJOe=r%tLHw35RA}|NyaQ@s)T_7uv7V~pRC%JNF9mG!m`wzqYKydwhL*v(OgxGGF>#sQV~tNE(sX#AP@ ze9MTqKBh8#bL~nZ2Ok0xGGIeX&Wmaa?}AZnGk-gLCNw5UQ`7vUXCE{$;i|!U)|y}& zU?1!>c&7N9z&T_?$<4WL&|MoUCTWfXD+f1nb;U0<5I0#J{a zVKtE~*&s=(sJ38FbSS(-?c64=50?T-x>-Oa7elK1LvS-aG|&%{y6Mnr97E*?*dWlU z`2hl@&k|fMat&ezBxQ9z)xW((fdf5!lD3%H}oXj;vS+= zg6h$mTpT+sSVV30pY`_i9B`j^uklp#Z6G(&82f|2D_AE{C+pNSPGDlD(o*W3 zZ;hvqtC!=LEyJ1(pQq3Iz&-{TxFoeZv@h~N^iIAN|D~R-?`Uck*Tpj5k_#u=OF(jS zY5Ebb@sa3Xih8oyk`mDjAtKlnl|?#p1K4_SSF?gl^_93?z^m$K57@fchdJuFu6f@0 z2hw$cT5J-&kt8TQXiep3)pw%3x{mr5;Z~85z4?H>Me`68X%Ezo>tN_QENKiY-nv+a z$op`^&mP@Qf!hpc<3eKSsXhw420zaiQbB#9>d-Zq+w2`)BRC+g zDL;tbSB_IJ(zN1n0n&=L80w=8uL?h872F2Xg(}y-VHqof(d6_9ONVj#JLN?hM~) zstqs&ebIBGcv%W^2+LIdQvF9fA{G$2DiC`>bI1dP|1@MQq+)1UB{(UC#mhwx1ec?u zcn3RzaRC40rEjeFsAq?#i}$h5L*A#wKo}SxkVq!UN2Aa2`KoEeNumNw1P0>0Q8f^t z7K$ed4+C`yjWmNNbRe+!bHnSyMtDMx0BdJca3-A*I1H(B6SbMz8)zP!5lZ7aL{AH= zNe?P=U_M~bWW#QGh(2E5T34WnQ_EE!u+>O6`Crn;;tb*ISj*@mzA1Nuy_h$2Qjk?=FgE?(iptt7TQOfrJ-mXYWjmxog}{^9_^C=+*7i zq!QQRt=~$~M|N0Z7GDNJq(3@4@{!}9`}K-mMYV*tNiFvo=OJjfO?C`*irl@uHOb|4 zIkte`AuxmMF^r_)_mvM+HHnJEO%hC@)+fJ*h~?M#BGZ2+^8Ys7hA;jWs|>**PGD z?hugB5qy*y{VDZw$0SG-K0)!+qP2MW|}Is)A-SN=G(t- zWp%CoHEW)^=N{~H&fashO1SaI)i&653R9xwN>U+zPE0{A_cZlP^;GoE^!1c(_BQIpj%DTEHvkR{J2aA>SBGGq$1^Uzpa)~21;?h zQRw*P&$OkNPCbya^KaDO8Gl!%j7!a%F*|#v!SIUp6A$_b8F5Y zIhICT4qF{kBPhu=)6v@2T9^kvH=QX=KZV}aH@$+^PH8OV@_lok$vT~(r=3d8{P*Zz zhty?hV>7a{+@5w)s=Ct5&Gh9Oi%0D7&d07f0p~EA@z<3b^U7r$)iGJLR{V+0q#b+; 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

(#b?1G0rnE)_S=>EPzgu`qf#v} znbF=jZ*Sioe|0%T&7qeDZ(4EYGusNBR3(IE!VY1mpaN6A@c)byAMri&vwyH{y^op6 zG=%O}3>a#TASyM1g424nBkHhGlF$F$Uq^Dvjg>FzUH!8eNLOd;a{_aT|=`Ot+A3OMUx zU4hPY`x(r^R|2bVCb+^)a3xovTY+V)p_$uA)|P_t;17J$L2$tK^i~ItL_uFk|5B;C zl26NT{AcB*|1uNFIq=0)5Jm{yz?eIi|Hegu%gBrSo&!8dN5DHb7Fj)EHqjJa3CK$j z;$5s(Nwq6EU{yt=I?_YwrkqcG0fhadMKNJS<~9l+#S6A#cCZWBGR2R=8a|Rc%{E|C zfmr) zWcSHF2R769p6$LTQghWphk7&9kUJ*avW;@=2ixCS*LqhjAOvk4rR_fPs<4uu$c;wL zuo2aKGS13vegvvBQY(n9s(;q8WQwxJjC6r2|SF=7M@V8;3 z)dfM=!i#(#Fa(E^g=}u{IILqPFg=($Oc1n3ngb_zWZgD57@d&oeNx=P5rX@ocaM~!cDwQ%xk-2vrx^}vBii{;8UN9*l`rUx`oxroNpxSEukt9qy10^ zs2`MuxbuN>yc7ZC{<%LyIsj&=cgjeuiP71bL!SrU@Ishx`)mK_nCm?4jB}T*#r=vG`eUh22Cb;z9lpqef0`|0`M&I?wqhuN*&Z9MnA$HDVC zRV!ttP@AE-)Jd#lKj=8UV0t@?R3Q&YOhDrNlKuE5t)nH8_@W{WU!H7%0 zkTVRF^2_Cv)oOjc4A|sGGONi}u!|eE@($WL)H&Sga`tizw>PudfC(u6D&_y;y@dIm8g9Ye!0mSz@?Q7dkiyiRdJD@($CD3;c1!IK z9qXKK*#2ziOUGY(GT4>Y3sd=#+<3BtJ;i(k({wQ^3fYMZcYcc+gBibIsic37?>}D& zU}JUtou$iiZ?&u*Y-U^M>DKH%a)KMgKjc62$M}ZOFACxYk$Y?n_6ZY*yB-P7D~d^` zx6skB&~H|@`5BCbGqo5n7A`^l_*KdU-kU36e7vD=M`pW*nM5M_wZeX}vu&Gg1~{$C zL*?;1yhvF#ncfMe#nt9*BZmK+wqERlZ1EGh%${SO(mGX}T4cSzoiAmSgMP<* zWszJ#`s_R4-42!d;qC$MXYOMj%6HA51nrI+Mt3Tm>B7wsy4oJ2>pRl9%{kJUip;r+ zJrXFEkN?Z15{eXMJ0OENPCc=b;HmbbuC1an%2(+-YLNB50lp=^AY^&PpCu%U9c&|^h_(Rzl$l`6`^&BaBW_9H zmW>cG|LVPvISm5~+6b^rHA8M+P~IaomGT02S}awTD=YKWg1ThLRv=RpoSbO_W-sh< zj&z6SIO=dZBC&<~M>x!ngN0UO8zEafLP=I*YZ*@Kvz`ogr8w-DeDZJcP4lkwWT8fU zpAq_+8fu<3Aw2?)gFTN|0LML z=0Q_)IlgEWX^8YoIwL14b+s)0wfThPVaGr8Df>DS(DVH&z6UpQBKMuJq#`?v*+;*pXz&;201wtj?YKG@lLX_W zWBwBU44>UU%imfWDZhZuQDNh^xt*%QY-4YdEnHE)58nYAI4e1YbRfqO;Wsf=!O!%B zK2IN}H_=n+ns{zYYOQq!y_+5ATh3PxD3-iS-XN#QTa^7OrEf9%Sk=JlbB8qIX9)wr z4H|0uD7F#f&`+t0-p>Un>huQd(rojNQN-Aw=hAm-MZroR4lS`XxhK5GT&aW9OFAL7 zmTM}pc;ap2q?G`!?*rU$Aww)|*X%N?!In@z#=>K(9|4(6JWy119K!PuOO8V{y3 zn;B))*DIn!|4^PUwenZ=HSzB9wDI)ueDvJ$=I}q19xHZznE9G2!}jD_2r1%!VDOK1 ztZ{U9ys}5wqinUrT0%X(Eu#EZC)h8{$NF03(R{)Dsr-qU?7`_ zTr|`l=xgA;0k+ncU^I>Q`TaNK7izFE)VfM5EY05)D%$GXGwn4U}k|6DG;mIldojI_iUBH=Rz&a-Rzx!lwD{rPJ!_&^2*VoFQ z494;oT7cP&+Q6J9tN9Y*AX^jr1ANmv_73)=w$Gv}ID`W5`h&?1@KBaw#?mLDdSsZK zslxByg@-zYI;5QR5Lxpt|7fX&JW6@4cGGoZr&WR8!MtUkky!2{=i{Doqq%>i6}rZD zb_U~M&e1dJK45=rLD!-S&_Ahp&^%}ZY;ZYxH=DI{s-jF#qER`XR7R^awIscd>7?$^ z<5-=v<9iFa#Tnv4v8K3RxDSjq7%GM3NGmWLKcg$sho~~({;q;7--cf0O!U(atCy6w zU<#X#S|Lp8EM-YwCQ zAU+i*i9euLQ;!G!h!}DbReV?a3DufX=fNS)+n$^w<>r;Mpq6Pjap62cb~ ze8PBfyBI5miIc!8{ha%a94r#*wioH5^e(C-tf`iD7QBo@5RY!dKlzlrN+0=!6eo?6 zPJ#`ww9-p`h1$D1*cb0I{mE0#k5h^fSBg{6^@|s7Vd{+Ha+7*&EON%m^eNoW`>^)M zW)$kCTks$Ror?y_Tqsekl%`0>kvRn^Rn=WuZ9{`K&1H&__1t~_m{3=oEshrph%2E> zYeM%WigaUFgOjo;eT!-a#@~L{H?tMky?@~3OF{E#n6h7X02!N$iVj-Da;Q3128e5TZsJ{F_FJ4jIsJ~FW_nCvt8wNoSu!A-V z^Fxp2Ncjrh^aN^(}0a!#7t6C`L(oNIxR)Wk74yWv`u+oY5uJsOK!i3zODY5T-D;Yn7f})5-7XJ5 z5(4#yt@>Tv)uS_jj6DUT{z0LD*hDNU-VjQF ze|8mjiX^cd+Z+}eL2smr1AnM*-7rg;Gm-24)0|paOrai@3jxEuD{=CAd7`pSW%P|k zQ$&yxOii+hOTa0KVs){Qcu$DNjKe|h5lLtB!Pj4)OQ8Q14QuLzTA`u2)%XG)&x%?n zWMfa{n(|L@*s}5hxjQoZ*IFOLY2BvAG7Ra@E#UhJnL=qXALdZ%3(NRx$m@6#4QAda z;NiVMHG(w_LLJ%zIusTV{BBwtaHkBpn=DK3@yuAczS2S6uaz`jn(&Dj- zUJH4}oS6P^g=zKIoJ#T|zg>bnv^o8N>IhAi$(9MGnAb*rocv5}kNR8*QYK+y@)vT4 zF>)!TqB>RcBYS89_V>lC1a8qB!UZt228*vSv3(K~@WD{!8o=&?3Re&M9o3)mTMMmV zFa~EDwV)Tb2br^1sRYK$VzOHj^2P(qjlj$ zU&)>1VElELJ@OmHRQu@Z#wx2O{g!D*HgG%mp2Bm%E4&oO2%q?(d}sLjBkWJ6JS@}( ze^-RMXf?GSK{0wA@RuOHx;799X0|*^E-dFn4e~?2th`ez=;w?smPu`4a*~1EM7}1z z=pQ_H5+*pS@WW9l-eOf`jeEhFzY}_V53Fv`l<9!{TLTkCA9&_lN-*p`8dlm#PLg*i z2`a14G4feAsotnOD{;;EJi<=lgYa00#nfF>el|KF@7Z8B1}IKR`UF)M)-=rWn8Uzr zn;TeDJoboxD;1#y(o`-bca$H>i-Bdl)mj@r%=uIiFrQlBS(f+(c;a1QCMM6i@$0!e zB%3V(gya!jgT6+!p?+Jj7LP3dk5SE-jK1<4p!Xdx>C_WiCY|K#@&sf~$Fw}gQL_d0 zmmbMJB3WD_KT^0PTo+~|vl$95;Sb=tuFcMco?}b;8P${WSxZpMtw$}^1*&9EpcY>i zJTV{T@nA9SDxZ`4DDBm`T8ciw45W_IQ7pb4cN}r)kZ@j@BZL7Hxr%w%g6Ms0VzN+e zf1*Y}CvJ;X$~tQ1M)&8Uo{7#)2e1aK@*=sN+(SMgw^E|i?%E~ja=f+1(i+o;tik<^ z64ndH@yxu!0`%wvSp5ia)e~4~Iu%O=LxZa(@{x+>O0e35=ncSObrH9< zC8t_hTLOQ#&5A}QT8a$d`tT9>-Fxw`h_H_T!R3Y3&jH_Q4p^v8Edpo!MXMG3NOSWD zvivCM7;OQ1Ul|PUW91?6c4Z-x5v=vpUmF7~om#;7*eI?F@8?Gd8*xUFm~QcL6}SOp z6EyQm!9tzzcV%Hsy{x}xUu5?YxbsW2>#Cu2g5A%-ecvk=RDLTNYDImQQ3lr3in+$J zTmb)u?<6dNEtQ3~HP1KZrUA3g1ZKGx+SB`~ny{u(V4a;}el?_8@|cGA@9FBog;CK`E?Ul~>_=GRl5sg?dg4G!~l? z)Gj(VJCZEpM)5YG2Yg7h@R*OrO}aun;Ps7TKG3ZYkq4pX-ey&>&Le^>2G>Ej-V&N6 zNlI;K18&E;Yw}uUoVrr`s&_WOSVQUWOm)%+_cH@5!hM9w!YjT3x_&Q-4SL}#nRL1r z{f(LcrH7-4N{_+eyU*}}FJ-iL1X)gZB}G04`}E22N>_EbmH@8cgI0O^2qTb+ToL{y zUj;rn8dD=}`F+Tm3SgFRA8@SJnt}v8Rt+hM{Cp6 zS4sQN$B+yvy{GSiYd1MKP& z)q(O@tE>{%akB`r#w4H`U2s3Mm4ONe|CB8^S5lP6>Tj)*vBS(mZJ;T(G3myY=kM^L zLVh8Qk4I;^F}H|3U|nn<^rLGdBKJX0dIxHyTZkY#4G$QWr-BzNNSy`b=`RFV8z}FT z6Y5Rmj3dlHR$uxFdMjl)7k`*%ga|xyDNplVF~j+ZEzFJw{@t2>OO2vjm^W?;Khn;; zgn5c?sOLUI8GDOTPVvi%Tw8gdtW&pZAM~2$X{#i?p83Ht++S`vpNVry<=5~5==h!@ zZng?KsVT6~U+{OisVi1j_>sZL9m*P0^~=B?+F%Z|F@C)zS6416(^W8`>JD?d<)!*E zr`b2;4mXbfh&N5)H=>I?6sJ>><485L; zf;CM7C-y4T$b*dYn8>TAEmyNp%@$Vzl`6_^rL9^^>!TkxB4AAt-4d9?WG))G?LYoI zzl$%2oymWsJhq8$GX17;t}x8Elw4|xnhj;Wxn{c6jXuj{ zvnEO8hVobVXLx2){uWn&8v(1gn6Btf)kcjx1j;NY5S6|_ap$>F+K5F37N`wIhiN>X zSXYTxZ0d7ph*)|D^RiWpp3U3@Yx+s9HEi@Azn5>#KjX?nkKsQ0KEs(rSm+08A~bxi zLSqg4uE-slVutFcR#uybym29JXk%p-Zs&RRg!UHs-9o4Zv|(1UhvAtk!H%xrdv@eM zaCH$slG*=&W&A>v|BL*tD6DBXs^rDMbo%4uS=7mUahJ9$F-j|ChLWl5QdejvfQEOr zu2FfJzF=G*!bRX-p5k}%UHP9toc5AT^gvdj`Wgui^5w|I-dfYFP^iJ>fND#UURWQc z-NGrIRfZvk#wkCQWvJ*D>yM1$)?(y171$1>A*Z1F-pg-=2hHGma_4}CwSiw2ndvma zTtY2a(?Vpor_3^#&T;GY^kta4Z-Po0eE4`~vNBce2*ryXh@M@LF;i>_l8;M9cE16C zy?Kcn!QBTkHUKzlZm6(?q5^3K1bn>}h1uJN<|*`6`=D<{X#;?fEK`QywDyF4pbn?34)7zR%pMvih3Kbm@-TqUk68l4UsWo!OSn$t3299I5 zHkiTC4tS&ghdTMK+8jKPTa{JH4W*o#tlrSxpr6*?x=cBlhHNJijZz>Uwr zjU#v2oT%u&{(skJ0dTQ*$Z_(3tMfl7X1KwVvCGOa5W9XEVcKCyz%3 z(g@w|O;&YuL^>dAj0BVD8?C&y89Cllyy*=kRNbSF)JEuQjCW=vHI2T&ykQ@Zc#h+n z;Jz2&u{+4^BRbojJ&Md>2^~fsquNorwclz64V@wAB{qcagjZ{&okjNWMLCNza;j@! z_09DW#t~Dsn$e4(>$Haq;xf3Z@Jj{x2V6_^&;w!h*O57Fp$pR&Q7s7Qt#n0aKF;(R zy-?K!qpSK-ZL7MKo3JH8od;iEQg39;G@n?x=Bg&5*LXnoC5GnT~N~$gw?-f zDnp&EJbDX5sZi=VDsKkeX{R{_6SL*?h0s$PqH^G5c%rcCWVN{F)C(9Lk=dspDs{xk z7vrvSIZ?~yN6p=jOC%NH>wlt;dKng)i2N=;tZ4%L$R1Rms}Sc~V)EXm%~o?^d+C)z ztHae0EmKp0-;K5|Q9At}Tb2-R56AOm_`K)=j6lD;0lE}^CWd*8JoGCy3%S@ko#V+XwhX(10ZRe2HTI%ErCA4o z;Qccvnb|<_uj#pQKmV#@)V#=>S=`enu=)x5V&kewQT6DF%o27Aa^?h1<3!B2Eak#* zlYT$}cNa2;MRYiD^)5gi60Dx6YZjRzI`r?6hp)$u*#fnUN~t_{A+M=m@Y4qxYtf+$ zqnjdvbU+7a8~VO9p1B&ab2X-B+OemZ{LDtW2z>?UNH98!!{JA^B6nC}c)=)pM#~3g z$-3x(+tFh@g$$>vUJw3mzx9j4><(Loc*#6?5}EtTZNzNoPQsD?s1nOD2VkKO;qUUI zGd;!14Q1&{=0U{y(U|+Frkz(iz@CEC+UkC_iI!K-Z`3oVS?8$?+R2LKHBRXfm&twN zwsMt#4uq45>>E^c=Mm+TsA-XX_{1TxkX^B$4dtx5%3&U4I(mr!$Hwt1@>rO~>k z=Qdlznr_hFm~U(XY0q8YesUkUom@@mz!xL)F@M#TxrbW*J30y#p>DIPfAk&oh_UHKZ!Hk9*I(;dXP45a*)F2J95{ zgC{ybQTg5%$UUGZkMG}#T9b_HsIOaD!6qA=*six@89kx0GADL?s%%ptOYwP>K8?s;R ztX5F#z>Bcj1#PQ-(0E}Isyf}58IBB(;^N?&ALDI1a9?nfE@C?;9+|^rSm;4i3k0}z zKh!nrp;Wls@ar-94RB{%#TTuK`!q}S17Dt@#~TOC50;Cr%rsz2kst7Qr?@+K&u)mF zeX)gF2K|1XnGXw1pn9QByk(7sA2|r^fqh00w)2zWMHAJjYExtoamenLY5nxR@OLMy z@06X%%?ji$?$R#q3ZB`E^FXQb1FU{O69J9p!pIqi0<(W=#leqUG8>pz5$9KeBsPQ zMPW^gfZaYuALKPo{s<6~S>OiSjv3?*=v%&42WzEap%u*Tu%-n1A#jI? zs~6Q$P-)!{6z8J(6+N}0ObM2d1X6*U!Y#%#3n2@wNOr;MrvMd$+7RYEx}i?Iji{6x z+Z(mb%SI_B99 zp*-v&%wx=jg`R`I%RxP}X2Fl#HQSpn5$8{$T3Vy!fp*R^b-sF94FfOa7`?YK(p+wx zptI8}vc`;N&0aRrI4; zMcDl&-1k$eUE8R2frU0R2f>;S(5IQLY!8x7nsH-bOJ#w!bi=f5O>|ZAGdoZzJ*B2l zrD07Qt%lZbbE;_=6VS0~2X&*S+Hds${L)F4(H3fT^g>2av$oZTnocifrm(e161>wO z*nD~JJsE(iy9IlRDU00pe=`$vsmidXJ-}T2<`N)IOATEgrhn3UYYM*Q7QCmXPSO6; zS%WrnSe2&N>(AkK{&4FQEL{thz1gU{3{xaZD2*gBtA#_!b;axM;UdX{8>(`9O=5KUCLK!>z zg{4_qmZ4I*gMLLMtZB2=!pel!eIQPrg2GukPAMn4 zm5=bu%G!Bth+f~QX*P#7ji)Ct-Pj1SA30um*t|v#kjf+h)$CUIOs%p6SS# z(Kj$R0&&`H@*iq_x+J8M)1(RyC>x-I}S)D(rIN!LKg?uY8Qu zgKm2j_6YLjLqP05Pz!+EO4dnhfaS6dnN`qPDsSw={oIWjOjh5kf7M8Bi&jgw8;U_$ zAyiTNKPHs@0Br0V$qnsD6CR}nZc=0RGJ169q3QM;5xFritjnmC@*sk=FrT5Gzp6*; z7qxbn?fs#qszt%O7pZ6J?~RXUnq^Q7lf_)d{d`JX@O37+NIIdC?*yxF0933aEOZNc z3pQ*g#=(y~GJBdojNYidTOrFCi0#UBHA5|^&DC<~N%|$@f_cwMqCNr{+rri-mk^c1 z@!PMFUfAdE4;;KbFo(Xd(Eadtp|GX}@FO3PJIKZ)%#IAye``~r>L;llH6Q-R=~pq` zw9edV9Y^JTkcmU>y^pvFSf9u(G8oz2SoSZ|m-$YQMwCAZf0q~5v>JXS#hinBVX47^ zo50YPVQQ4cH_fY!(R}dB(~a?FEUak-9nW-Uon!?fJqL94F5i_&BnB8kUu0w5FzYfytBSKPpmjz}>Y#@hZX*?wtbWRkIjoIr zMcm3{l7eS0B>!Pgx&kWCl0d~8!9v$kEhv$?hp1E@nCJ*}s3)TW8v{&u75GXEXoa=* z+G(w>uAr~-5Ov}!)JkWVX>2aClsrSl^oT4Y705MYO_wk!cb#qr3*8QX7fiiCSKW`214La39AprRiH{JNCZTHC1=)E~n_=OY)JPsIZt zsm1}&O-debeKeC#9Sw|nr*@BIHJ>KAqp`->R>zdRXe(-mqAqGuX1 z=6+V7brOivQ=^sfL~nyyaRHuJ1^-rQtiB7CQWHeaTF96q8G|{&RwZl54gCI%KyXsn z@vMg#$4GQM=8x{90*Qt-C0HYYv)(|~_zf7|4}FmC18;ncRtLX*iRK56(Zcx8%xmSM zB502JgxtOmtmqtK=w{LpeVUojww;Y0-DJ5>yntSp&zOpAEKav! zgJm$zzO6PNF)3EBXgEyO^jq1~cls(bnYEL#nK>G<2w!qXJtEhWo4Fziq2^fM@!u4b^iS8OD3miBGBP^cE(Db+f%;qo>Fw zcqRfZIBz%2YOwF``h3 zH^p6A1K!RaxKU5FW_kuJbhEh()-;9g#uQ+0vegjX_u$+I;>I6kE2H~U6BS)|B9Uh6$^N_*hx`fAg)ds+?sy}s3mHHX8RI?+`bnmxc4g-_ZH z`y5R2U=y`IruLh|FAt^#R5im9J=2ge4~F{c6|*Bwez5TmGmauEDqOzjD8RO z?w*LAb&xSfFyEPFY#@}pSCN%uC@BQQp*7f0x?mD#0_Kpep#rIhPVzbQm5QPU8HAIM zLrh+%=S7aU5XufSw2N9H{fs`$sAEQ2d8t6!N8bi6sIr~O0^Ivyqy+ZeV%TrYKqiBp zg&E`f)O4x_WkSn)I=X)!%*ntAR-vQ14J-;t+B)2(S=w3P^*iH&e`a)Ib~qk3HN{ z>{(#ePw4)@L(ifDDFkWfdP>)*$y62K>o=|0z(;+||bz)yxRXvVLRwav9K}YiwT97Ei5BXmXgXhdydo;25#!%RfLwt^?HJ z5u#E3#>b z2j@G|>CWJujXbd4%O%W*X2TgHnZ~(_k24r1y2C|M=f^PXvVgr*z;55o*BBa_<))Rr z%dA|ApC#Uv;VKUvo{u}$Bj82umN|es@K8-xmFTB+B12cu?GMGh{1@JB2q&tdU6Gv$ zGN%!xKj9&nD1}h-si_Nwe&wc-O)sHqepEyCMKoAfs&Qp{R3C7DZoaAwF29PFUrm4Z zFJ#kp*liPBtdEHNGA7#7iBcf`d?WVIdPy7>k| z%Ae#C)mm@WI^cO!d{s~+R#(?+=p`QEtL)TYnCY z7?)Sd67FG>bKcAZPJz0N^ z+3nh7=uF&^isAyw`wb=#x1$tq+3`#^t}+pv47yR00|W1GPMD##4tRIie@#{DsD4%- zvX_Db8uHt7^b*|~U+7KP$V}!#&%qgci)tbpALkvI=zbT)o}bNGqiyC5`T+$cw@L!= z+xM7AtK2DE))``;d`6w5CLd%)Ly6H%c6=x5M-1-W0{nri^i}%9#csoKMxtm>qZi7# zWRUqFQL4urNk050!fZ92z|ie(4%yURO7(9%yzTl=U4vY@qrXBYU5D2zaJd6o{!1}L zJWDox>nHl>ak1j@1vlHyD4R*#rENy@cGSiF^Oa`wJF;veY|Gl41zveEEQ*)+0`k`s(nvPV^-+9mW?4%I8*T%Wt zzM&`)M`WC;L1eOZ8T#@0dZT_5CN`H|;&vG+AB)XYmXpmIbk*~?U$NpSl zdYPxp6V|gW-$Sp!_hg5lw*@3OBRN6SEW-=P94>zZdglcXeCEfOx;*Xyof}VWH)8 z3R!<#zAuBw&^X+Y@?_IWaHOiwL@7S9^KE_f=Lob-dH%LEpO||%SmCbNo$x7QB#QQ= z>dVa)d1&Q)y-SZ~N^S#Ke*w?oX)-hcysJt!t?}>qXW$NFi2N$l(it8k!+|Ex3g1ZI%ZVK_Hr91hkw`YL_lVz>QfyxV53i&_O#KNuX&>JfzbEISzOJHb z-eg|vo==C}w)J@~k;osk15q|B=rJ_nv~qKD^{Dx~EkuEg_uWM`&Yw+JmBEffXoj1t z>vVj!6R6o@aQOxN&{a&YH(|Wg5F9dU0*qG>mncUa3%9M@=eQhR&ZevbBR zEQ-V~xI?iT!Pn2T@rd?QCwzQ5->iXZe*PTGk-) ztu(XM`Yitz>7M#Gl}Og_$8)GihE47_X9PgD{N=Oi898f55f^lVMCX)7u@oIc2WB7c;= zw>KN{8(-q7ubV}t2wVN+hoEQ*nUtZE@GUE# zx_jV_%z)coLDdYRdj9VB!ESqSW@SB*FR-)hv-r0OVDrno=WKJ`473lZ$kD!u;G{3y zAzQu5O73KDCR5|9ah|Flb8?@_*37P_h-j+k6MxJvPS#c1*q)GOqkte2f1qgC!Z_^NUf4pRi3pH zOitFLn6*6%YYJAIIj7^rE?n!bF#BtMJvb5ucbEsmJC0ha2;$A)*AE8m_L%y1t&MPx zU51ZCc~d2o!);uo*Ak<#^pmboKWf89hTyU8qp#8fm-P-DX9`TT&?U3yuYk;<+*+Cl zXNUs#(oJ={lnl*vskoQ*muxlVZ30#PI8H`{(46mjU0qb|!MP;;1)QlJ?(#xAFDKOo46%s!yImsp)sNr*_4G=ipI;x!Xu~)8;i2# z=v6Kt_OWKQDKu}{n{dXz`9JWj--|8O8y@x&xN>RzmTCL=`92@ zi?jwl($rt0Lmh_p9*ZY@8vKX@^}aH9@J6!i7+25ZA)%FiW6u|Doaar%+<4lE#K5}b`{I4K$I~4s^5G28@LMOEW zmm}PLx0YI_jDO6)(_n6u6RmxIyrbD2k} z&jj8fJeSvTu?`UVU?!&qq7{$vyhQ$;V#Z?;N{M?heRCLdqHLnp(Fy6zuOCg9zYdIX zDmOJ9hA-E~v0sP+X-qbq@XPU8Ltu?lTs>;?FkFHQ$qW4>Ziv7l{F$dV4|AaY=hTk3WQ^a%f2O@tIpSc%r z8i`W4r&5`jDTIx5=0344aK^4M`#bnJGhm{^|C>FpK<0kzr7UoCo!O60>IW{r#TB-j ze3Ymxx5+MQhpNcF97x=oQ;*lF*KiqEq3BA;&{*)U7TJ{P=P^H0iEh3Dm4{o~`RnrG2;~|WB zF()^k_9uya19!}h<9t<~*-M=E;j?wN8&OJGRL>SL=6KZS0#yjR@5SGiI5_EQsHy-5 zAI#kTQF_z;sh*GhkMxz^MT7ju&2g=$$?^8DaJ*w+@_uvIw6!U=f!pI^{8Qqf7%r`h z#TBiuyR+Zv1FG-YN!6J`dJpDsnhYJp)R6b*d>S|s=I`JUbb*a6#2?~56n4`AI*BdF z`YQj!Y&@*>B2wnbVd|8sPXDw!bMOimW4x-1@*KmY^+hr?8nqBW7i2v+!mYe+HLC6r zyRk2I=?YIgWNza%C0KzjeF2@gQ2b415&2A2j>^%M_Y9r`o z({^yA8{Alxeb= zT0xW=;NFDMJwLDJ(F4fkEOH0b*A^yOUxtg_105HjXsgq$n!*XyQ#O_;Juw%-kQ?SH z8)MH?<%`@(u<2JZAOG@Gl|v0_1^*7htzWFVsbAz5;Bv7@N7eMi$#@83UdG9dddy$W z;gm_X{gfz`VM5_7&#Y_*+avZ>mqYao6F<>Wl-$X6Rt4#1?4!z@nNCtYRgp}AFAJH8 z6CO$REcU19D-B13+#>SbsL4ri(JJKVMSgn)_7&X$_oEx_YluuSgc~bj)Iq$QhV1uX zP$ZR|WVyp)0LH-RIanZ?@b-iC+o1dW~p?{mqe z05B!h)&ya?`8=N}!l)pf)oK_?b?`G7WZFng3MT7^%R0<9CDEm8gHF6bOlL3`ABf95 z%GKg-f=QfS(P-s7qu>!sZQ1|nXMe^|q$+KYoS;$HL6SPGX8~+)gsKJBk7KUu8W}nQ zybC6qI2#KSt?G|c=Nr58_Wx`*RPBBCrliv{k51||{JY)EH#xDC4%kehq^L(h%x$OR z4%Dan^9hRX4jDQYysJSr9pIe7U>{1iYL06QGB1IV)MA3D5Ty_f0^9{dCCu^_ILk6$)?lvl}4dKpgX01 fN>`wC1xi<-bOlORpmYUFSD||jwF3VI{L^C1 literal 0 HcmV?d00001 diff --git a/docs/SESSION_HANDOFF.md b/docs/SESSION_HANDOFF.md index 77a60e6..7575c6f 100644 --- a/docs/SESSION_HANDOFF.md +++ b/docs/SESSION_HANDOFF.md @@ -2,7 +2,7 @@ > Last updated: 2026-04-25 > Branch: `master` — pushed to https://git.aleshym.co/funman300/Rusty_Solitare.git -> Test count: **225 passing** (83 core + 54 data + 88 engine), `cargo clippy --workspace -- -D warnings` clean +> Test count: **226 passing** (83 core + 54 data + 89 engine), `cargo clippy --workspace -- -D warnings` clean --- @@ -153,13 +153,22 @@ All sub-phases (3A–3F) done. Plugins: `GamePlugin`, `TablePlugin`, `CardPlugin - `HelpPlugin`: **H** or `?` toggles a full-window cheat sheet listing all keybindings (gameplay, mode hotkeys, overlays). 3 unit tests. - `AnimationPlugin` now surfaces `ChallengeAdvancedEvent` as a 3-second toast ("Challenge N cleared!"). +### Phase 7 (part 2) — Synthesized SFX + AudioPlugin ✅ COMPLETE + +- New workspace crate `solitaire_assetgen` with bin `gen_sfx`. Synthesizes five 44.1kHz mono 16-bit PCM WAVs from a deterministic LCG noise source + sine/square synths into `assets/audio/`. Run with `cargo run -p solitaire_assetgen --bin gen_sfx`. Output is committed; end users never run the generator. +- `AudioPlugin` (`solitaire_engine`): embeds the WAVs via `include_bytes!()`, decodes once via `kira::StaticSoundData::from_cursor`, plays on `DrawRequestEvent` (flip), `MoveRequestEvent` (place), `NewGameRequestEvent` (deal), `GameWonEvent` (fanfare). `card_invalid.wav` is loaded but unused — wiring it needs a `MoveRejectedEvent` (no such event today). +- Backend handle stored as `NonSend` (cpal stream is `!Send` on some platforms). Plugin degrades gracefully if no audio device is available — logs a warning, gameplay continues silently. +- Single decode unit test (`embedded_wavs_decode_successfully`) keeps the loader and generator in sync. + ## What Is Next -### Phase 7 (part 2+) — Audio + Pause Menu +### Phase 7 (part 3+) — Pause Menu + Polish -- Audio (`kira`): card deal/flip/place/invalid SFX, win fanfare, ambient loop. Volume sliders in a Settings overlay. **Blocker:** asset files are not yet in the repo; sourcing/recording these is the first step. -- Pause menu: Esc currently logs a placeholder. Likely a small overlay similar to `HelpPlugin` with a `Paused` resource that gates `Time::delta_secs` propagation in `tick_elapsed_time` / `advance_time_attack`. -- Onboarding: first-run banner pointing at the **H**/`?` cheat sheet (single-shot via `Settings.first_run_complete`). +- **Pause menu**: Esc currently logs a placeholder. Likely a small overlay similar to `HelpPlugin` with a `Paused` resource that gates `Time::delta_secs` in `tick_elapsed_time` / `advance_time_attack`. +- **`MoveRejectedEvent`** (small): emit from `end_drag` when a drop is on a real pile but validation fails, so `card_invalid.wav` finally has something to fire on. +- **Volume controls**: Settings overlay with `sfx_volume` slider; persist via `solitaire_data::Settings` (already defined). Apply to kira's main-track gain. +- **Ambient loop**: optional sixth WAV — needs taste, deferred. +- **Onboarding**: first-run banner pointing at the **H**/`?` cheat sheet (single-shot via `Settings.first_run_complete`). ### Phase 8 — Sync diff --git a/solitaire_app/src/main.rs b/solitaire_app/src/main.rs index 808fb5c..fe7885d 100644 --- a/solitaire_app/src/main.rs +++ b/solitaire_app/src/main.rs @@ -1,8 +1,8 @@ use bevy::prelude::*; use solitaire_engine::{ - AchievementPlugin, AnimationPlugin, CardPlugin, ChallengePlugin, DailyChallengePlugin, - GamePlugin, HelpPlugin, InputPlugin, ProgressPlugin, StatsPlugin, TablePlugin, TimeAttackPlugin, - WeeklyGoalsPlugin, + AchievementPlugin, AnimationPlugin, AudioPlugin, CardPlugin, ChallengePlugin, + DailyChallengePlugin, GamePlugin, HelpPlugin, InputPlugin, ProgressPlugin, StatsPlugin, + TablePlugin, TimeAttackPlugin, WeeklyGoalsPlugin, }; fn main() { @@ -30,5 +30,6 @@ fn main() { .add_plugins(ChallengePlugin) .add_plugins(TimeAttackPlugin) .add_plugins(HelpPlugin) + .add_plugins(AudioPlugin) .run(); } diff --git a/solitaire_assetgen/Cargo.toml b/solitaire_assetgen/Cargo.toml new file mode 100644 index 0000000..69a06f9 --- /dev/null +++ b/solitaire_assetgen/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "solitaire_assetgen" +version.workspace = true +edition.workspace = true +publish = false + +# Dev-only utility: synthesizes placeholder SFX WAV files into `assets/audio/`. +# Not depended on by any other workspace crate. + +[[bin]] +name = "gen_sfx" +path = "src/bin/gen_sfx.rs" diff --git a/solitaire_assetgen/src/bin/gen_sfx.rs b/solitaire_assetgen/src/bin/gen_sfx.rs new file mode 100644 index 0000000..3b70d99 --- /dev/null +++ b/solitaire_assetgen/src/bin/gen_sfx.rs @@ -0,0 +1,207 @@ +//! Synthesize placeholder SFX into `assets/audio/`. +//! +//! Output: 44.1kHz mono 16-bit PCM WAV. Run with +//! `cargo run -p solitaire_assetgen --bin gen_sfx`. Files are committed to +//! the repo so end-users never need to run this generator. + +use std::fs::{self, File}; +use std::io::{self, Write}; +use std::path::{Path, PathBuf}; + +const SAMPLE_RATE: u32 = 44_100; + +type Generator = fn() -> Vec; + +fn main() -> io::Result<()> { + let out_dir = workspace_root().join("assets").join("audio"); + fs::create_dir_all(&out_dir)?; + + let effects: [(&str, Generator); 5] = [ + ("card_flip.wav", card_flip), + ("card_place.wav", card_place), + ("card_deal.wav", card_deal), + ("card_invalid.wav", card_invalid), + ("win_fanfare.wav", win_fanfare), + ]; + + for (name, gen) in &effects { + let samples = gen(); + let path = out_dir.join(name); + write_wav_mono_pcm16(&path, SAMPLE_RATE, &samples)?; + println!("wrote {} ({} samples)", path.display(), samples.len()); + } + + Ok(()) +} + +// --------------------------------------------------------------------------- +// Synth primitives +// --------------------------------------------------------------------------- + +/// Simple deterministic noise source — LCG, no `rand` dep needed. +struct Lcg(u64); + +impl Lcg { + fn new(seed: u64) -> Self { + Self(seed) + } + fn next_f32(&mut self) -> f32 { + self.0 = self + .0 + .wrapping_mul(6_364_136_223_846_793_005) + .wrapping_add(1_442_695_040_888_963_407); + ((self.0 >> 32) as i32 as f32) / (i32::MAX as f32) + } +} + +fn duration_samples(seconds: f32) -> usize { + (seconds * SAMPLE_RATE as f32) as usize +} + +/// Linear attack / exponential decay envelope. `attack` and length in seconds. +fn ar_envelope(t_secs: f32, attack: f32, total: f32, decay_rate: f32) -> f32 { + if t_secs < attack { + (t_secs / attack).clamp(0.0, 1.0) + } else { + (-decay_rate * (t_secs - attack)).exp() * (1.0 - (t_secs - total).max(0.0)) + } +} + +fn quantize(sample: f32) -> i16 { + let clipped = sample.clamp(-1.0, 1.0); + (clipped * 32_767.0) as i16 +} + +// --------------------------------------------------------------------------- +// Effect generators +// --------------------------------------------------------------------------- + +fn card_flip() -> Vec { + let n = duration_samples(0.08); + let mut rng = Lcg::new(0x1234_5678_DEAD_BEEF); + let mut out = Vec::with_capacity(n); + let mut prev = 0.0f32; + let alpha = 0.35; + for i in 0..n { + let t = i as f32 / SAMPLE_RATE as f32; + let raw = rng.next_f32(); + // High-pass-ish: subtract a low-pass-smoothed signal. + let lp = alpha * raw + (1.0 - alpha) * prev; + prev = lp; + let hp = raw - lp; + let env = ar_envelope(t, 0.005, 0.08, 60.0); + out.push(quantize(hp * env * 0.6)); + } + out +} + +fn card_place() -> Vec { + let n = duration_samples(0.14); + let mut rng = Lcg::new(0xCAFE_F00D_8BAD_F00D); + let mut out = Vec::with_capacity(n); + for i in 0..n { + let t = i as f32 / SAMPLE_RATE as f32; + // Low sine for body (~120 Hz) + filtered noise for click. + let body = (2.0 * std::f32::consts::PI * 120.0 * t).sin(); + let click = rng.next_f32() * 0.5; + let env = ar_envelope(t, 0.003, 0.14, 35.0); + let sample = (body * 0.7 + click) * env * 0.55; + out.push(quantize(sample)); + } + out +} + +fn card_deal() -> Vec { + let n = duration_samples(0.18); + let mut rng = Lcg::new(0xFEE1_DEAD_DEAD_BEEF); + let mut out = Vec::with_capacity(n); + let mut lp = 0.0f32; + for i in 0..n { + let t = i as f32 / SAMPLE_RATE as f32; + let raw = rng.next_f32(); + // Sweeping low-pass: cutoff falls over time → "whoosh". + let alpha = 0.6 - (t / 0.18) * 0.5; + lp = alpha * raw + (1.0 - alpha) * lp; + let env = ar_envelope(t, 0.01, 0.18, 18.0); + out.push(quantize(lp * env * 0.7)); + } + out +} + +fn card_invalid() -> Vec { + let n = duration_samples(0.18); + let mut out = Vec::with_capacity(n); + for i in 0..n { + let t = i as f32 / SAMPLE_RATE as f32; + // Two dissonant squarish tones — strong beat creates a buzz. + let a = (2.0 * std::f32::consts::PI * 196.0 * t).sin().signum(); + let b = (2.0 * std::f32::consts::PI * 207.65 * t).sin().signum(); + let env = ar_envelope(t, 0.005, 0.18, 12.0); + out.push(quantize((a + b) * env * 0.18)); + } + out +} + +fn win_fanfare() -> Vec { + // C major arpeggio: C5, E5, G5, C6. + let notes = [523.25_f32, 659.25, 783.99, 1046.50]; + let note_dur = 0.18_f32; + let total = note_dur * notes.len() as f32 + 0.25; + let n = duration_samples(total); + let mut out = Vec::with_capacity(n); + for i in 0..n { + let t = i as f32 / SAMPLE_RATE as f32; + let mut sample = 0.0f32; + for (idx, freq) in notes.iter().enumerate() { + let start = idx as f32 * note_dur; + let local = t - start; + if !(0.0..=0.4).contains(&local) { + continue; + } + // Layered sine + soft 2nd harmonic for warmth. + let s = (2.0 * std::f32::consts::PI * freq * local).sin() + + 0.3 * (2.0 * std::f32::consts::PI * freq * 2.0 * local).sin(); + let env = ar_envelope(local, 0.008, 0.4, 6.0); + sample += s * env; + } + out.push(quantize(sample * 0.22)); + } + out +} + +// --------------------------------------------------------------------------- +// Minimal WAV writer (mono 16-bit PCM) +// --------------------------------------------------------------------------- + +fn write_wav_mono_pcm16(path: &Path, sample_rate: u32, samples: &[i16]) -> io::Result<()> { + let mut f = File::create(path)?; + let byte_rate = sample_rate * 2; // mono 16-bit + let data_bytes = samples.len() as u32 * 2; + let chunk_size = 36 + data_bytes; + + f.write_all(b"RIFF")?; + f.write_all(&chunk_size.to_le_bytes())?; + f.write_all(b"WAVE")?; + + f.write_all(b"fmt ")?; + f.write_all(&16u32.to_le_bytes())?; // PCM fmt chunk size + f.write_all(&1u16.to_le_bytes())?; // PCM + f.write_all(&1u16.to_le_bytes())?; // mono + f.write_all(&sample_rate.to_le_bytes())?; + f.write_all(&byte_rate.to_le_bytes())?; + f.write_all(&2u16.to_le_bytes())?; // block align + f.write_all(&16u16.to_le_bytes())?; // bits per sample + + f.write_all(b"data")?; + f.write_all(&data_bytes.to_le_bytes())?; + for &s in samples { + f.write_all(&s.to_le_bytes())?; + } + Ok(()) +} + +fn workspace_root() -> PathBuf { + // CARGO_MANIFEST_DIR points at the assetgen crate; parent is workspace. + let crate_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + crate_dir.parent().expect("workspace root").to_path_buf() +} diff --git a/solitaire_engine/src/audio_plugin.rs b/solitaire_engine/src/audio_plugin.rs new file mode 100644 index 0000000..98b384f --- /dev/null +++ b/solitaire_engine/src/audio_plugin.rs @@ -0,0 +1,177 @@ +//! Sound-effect playback via `kira`. +//! +//! Loads five embedded WAVs (`include_bytes!`) at startup and plays them in +//! response to gameplay events: +//! +//! | Event | Sound | +//! |---|---| +//! | `DrawRequestEvent` | `card_flip.wav` | +//! | `MoveRequestEvent` | `card_place.wav` | +//! | `NewGameRequestEvent` | `card_deal.wav` | +//! | `GameWonEvent` | `win_fanfare.wav` | +//! +//! `card_invalid.wav` is loaded but not yet wired — there is no +//! "rejected move" event today; adding one is a follow-up. +//! +//! If the audio device cannot be opened (e.g. a headless CI machine or a +//! Linux box without a running PulseAudio/Pipewire session), the plugin +//! logs a warning and degrades gracefully — gameplay continues, just +//! silently. + +use std::io::Cursor; + +use bevy::prelude::*; +use kira::manager::backend::DefaultBackend; +use kira::manager::{AudioManager, AudioManagerSettings}; +use kira::sound::static_sound::StaticSoundData; + +use crate::events::{DrawRequestEvent, GameWonEvent, MoveRequestEvent, NewGameRequestEvent}; + +/// Pre-decoded sound effects. Cheap to clone (frames are an `Arc<[Frame]>`), +/// so we hand a fresh handle to `manager.play()` on every event. +#[derive(Resource, Clone)] +pub struct SoundLibrary { + pub deal: StaticSoundData, + pub flip: StaticSoundData, + pub place: StaticSoundData, + pub invalid: StaticSoundData, + pub fanfare: StaticSoundData, +} + +/// Wraps the audio backend. `NonSend` because cpal streams are `!Send` on +/// some platforms. +pub struct AudioState { + manager: Option>, +} + +pub struct AudioPlugin; + +impl Plugin for AudioPlugin { + fn build(&self, app: &mut App) { + let manager = AudioManager::::new(AudioManagerSettings::default()).ok(); + if manager.is_none() { + warn!("audio device unavailable; SFX disabled"); + } + app.insert_non_send_resource(AudioState { manager }); + + let library = build_library(); + if let Some(lib) = library { + app.insert_resource(lib); + } else { + warn!("failed to decode embedded SFX assets; SFX disabled"); + } + + app.add_event::() + .add_event::() + .add_event::() + .add_event::() + .add_systems( + Update, + ( + play_on_draw, + play_on_move, + play_on_new_game, + play_on_win, + ), + ); + } +} + +fn build_library() -> Option { + let deal = decode(include_bytes!("../../assets/audio/card_deal.wav"))?; + let flip = decode(include_bytes!("../../assets/audio/card_flip.wav"))?; + let place = decode(include_bytes!("../../assets/audio/card_place.wav"))?; + let invalid = decode(include_bytes!("../../assets/audio/card_invalid.wav"))?; + let fanfare = decode(include_bytes!("../../assets/audio/win_fanfare.wav"))?; + Some(SoundLibrary { + deal, + flip, + place, + invalid, + fanfare, + }) +} + +fn decode(bytes: &'static [u8]) -> Option { + match StaticSoundData::from_cursor(Cursor::new(bytes.to_vec())) { + Ok(data) => Some(data), + Err(e) => { + warn!("failed to decode SFX: {e}"); + None + } + } +} + +fn play(audio: &mut AudioState, sound: &StaticSoundData) { + let Some(manager) = audio.manager.as_mut() else { + return; + }; + if let Err(e) = manager.play(sound.clone()) { + warn!("failed to play SFX: {e}"); + } +} + +fn play_on_draw( + mut events: EventReader, + mut audio: NonSendMut, + lib: Option>, +) { + let Some(lib) = lib else { + return; + }; + for _ in events.read() { + play(&mut audio, &lib.flip); + } +} + +fn play_on_move( + mut events: EventReader, + mut audio: NonSendMut, + lib: Option>, +) { + let Some(lib) = lib else { + return; + }; + for _ in events.read() { + play(&mut audio, &lib.place); + } +} + +fn play_on_new_game( + mut events: EventReader, + mut audio: NonSendMut, + lib: Option>, +) { + let Some(lib) = lib else { + return; + }; + for _ in events.read() { + play(&mut audio, &lib.deal); + } +} + +fn play_on_win( + mut events: EventReader, + mut audio: NonSendMut, + lib: Option>, +) { + let Some(lib) = lib else { + return; + }; + for _ in events.read() { + play(&mut audio, &lib.fanfare); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn embedded_wavs_decode_successfully() { + // Verifies the include_bytes! paths resolve and the bytes are valid + // WAV (so the gen_sfx output stays in sync with the loader). + let lib = build_library(); + assert!(lib.is_some(), "embedded SFX failed to decode"); + } +} diff --git a/solitaire_engine/src/lib.rs b/solitaire_engine/src/lib.rs index 13383d7..273425b 100644 --- a/solitaire_engine/src/lib.rs +++ b/solitaire_engine/src/lib.rs @@ -2,6 +2,7 @@ pub mod achievement_plugin; pub mod animation_plugin; +pub mod audio_plugin; pub mod card_plugin; pub mod challenge_plugin; pub mod daily_challenge_plugin; @@ -27,6 +28,7 @@ pub use daily_challenge_plugin::{ pub use progress_plugin::{LevelUpEvent, ProgressPlugin, ProgressResource, ProgressUpdate}; pub use weekly_goals_plugin::{WeeklyGoalCompletedEvent, WeeklyGoalsPlugin}; pub use animation_plugin::{AnimationPlugin, CardAnim}; +pub use audio_plugin::{AudioPlugin, AudioState, SoundLibrary}; pub use card_plugin::{CardEntity, CardLabel, CardPlugin}; pub use events::{ AchievementUnlockedEvent, CardFlippedEvent, DrawRequestEvent, GameWonEvent, MoveRequestEvent,