From e05a88c6a6ea46fb751778cbaf947505095aac6d Mon Sep 17 00:00:00 2001 From: gijoe0295 <153004152+gijoe0295@users.noreply.github.com> Date: Fri, 19 Jun 2026 11:41:56 +0700 Subject: [PATCH 01/35] Reapply "Merge pull request #92007 from gijoe0295/feat/ai-feature-promo-modal" This reverts commit 9586f9688b0a0d5f3723c6caa8e605b0a333ec04. --- assets/animations/CustomAgents.lottie | Bin 0 -> 39784 bytes assets/animations/ExpenseAssistant.lottie | Bin 0 -> 26689 bytes assets/animations/SpendAnalysis.lottie | Bin 0 -> 21421 bytes config/eslint/eslint.seatbelt.tsv | 5 +- jest/setupAfterEnv.ts | 10 + src/CONST/index.ts | 9 + src/NAVIGATORS.ts | 1 + src/ROUTES.ts | 1 + src/SCREENS.ts | 4 + src/components/AIFeaturesPromoModal/index.tsx | 92 +++++ .../FeatureTrainingModalBody.tsx | 110 ++++++ .../FeatureTrainingModalCarouselBody.tsx | 302 ++++++++++++++ .../FeatureTrainingModalContent.tsx | 138 +++++++ .../FeatureTrainingModalIllustration.tsx | 179 +++++++++ .../FeatureTrainingModalTextContent.tsx | 76 ++++ .../index.tsx} | 370 +++++++----------- src/components/Lottie/index.tsx | 12 +- src/components/LottieAnimations/index.tsx | 16 + src/components/Section/index.tsx | 1 + src/languages/de.ts | 16 + src/languages/en.ts | 16 + src/languages/es.ts | 16 + src/languages/fr.ts | 16 + src/languages/it.ts | 16 + src/languages/ja.ts | 16 + src/languages/nl.ts | 16 + src/languages/pl.ts | 16 + src/languages/pt-BR.ts | 16 + src/languages/zh-hans.ts | 16 + .../Navigation/AppNavigator/AuthScreens.tsx | 6 + .../AIFeaturesPromoModalNavigator.tsx | 26 ++ .../Navigation/guards/AIFeaturesPromoGuard.ts | 226 +++++++++++ src/libs/Navigation/guards/index.ts | 10 +- src/libs/Navigation/linkingConfig/config.ts | 9 + src/libs/Navigation/types.ts | 6 + src/styles/index.ts | 6 + src/styles/utils/index.ts | 9 + src/styles/variables.ts | 1 + src/types/onyx/DismissedProductTraining.ts | 5 + 39 files changed, 1552 insertions(+), 238 deletions(-) create mode 100644 assets/animations/CustomAgents.lottie create mode 100644 assets/animations/ExpenseAssistant.lottie create mode 100644 assets/animations/SpendAnalysis.lottie create mode 100644 src/components/AIFeaturesPromoModal/index.tsx create mode 100644 src/components/FeatureTrainingModal/FeatureTrainingModalBody.tsx create mode 100644 src/components/FeatureTrainingModal/FeatureTrainingModalCarouselBody.tsx create mode 100644 src/components/FeatureTrainingModal/FeatureTrainingModalContent.tsx create mode 100644 src/components/FeatureTrainingModal/FeatureTrainingModalIllustration.tsx create mode 100644 src/components/FeatureTrainingModal/FeatureTrainingModalTextContent.tsx rename src/components/{FeatureTrainingModal.tsx => FeatureTrainingModal/index.tsx} (51%) create mode 100644 src/libs/Navigation/AppNavigator/Navigators/AIFeaturesPromoModalNavigator.tsx create mode 100644 src/libs/Navigation/guards/AIFeaturesPromoGuard.ts diff --git a/assets/animations/CustomAgents.lottie b/assets/animations/CustomAgents.lottie new file mode 100644 index 0000000000000000000000000000000000000000..6f6b40b8c4634fe0c16f6057ae1ffa5356a92988 GIT binary patch literal 39784 zcma&tV~i+Kw=U|oZQHhO+qP}nwr$(CZF{wi)$YFQ+vnUIWZ&dg=1i*ojmk`=W<51t z1!-Uq6aWAK2!L(YNu7b2#hZYCSFQgh?7wMiXlH3=>g+;i#m9tmrVl zj}*@}U1rbH{8seoZvaJ&Bu*uB1{-85p56B%<$1VRbbhiFIe0Eev(>tmg(&W7`hxl3 zJhj%C=%mRwc!vO$LoDB%T@~_l?mD(D*SlZh;(=)TOF_AtDGMJdKavE|n8UNQE-S}Q5owOysbU)waIVHNTWBbhChx${v zi8u8$)h3wP7cO+)ae4wGk!XmhChjg5Hwp6^Ac8<15F}1q-O=y={@p&K@9*__{q^^M z-=22=KK%N4T<-7pd2RCb^nDNgwex#Fi>LS{pYngdz~BFUdvEVQc-TB@ zK32`+y}ntT!@D8F=XH6P^eo{&7@Ob!y*tx?QTF>F_q$mg z(bN9{R`vS@z8m6htEc}R;_n{zboTLmhh@E=w)g-1NuS?>!}ouG*?$gR(Cqxh?^u0F zpS^JL;I)PG7uD`ZbAQmK_mQmF$EV94K5P}X^=oPQ9GR{zSU{i%NI-M0IE z1LpUhUw~x`^jDf^$XIGVO!vEV%f{1>QY+`q)fQu3b82n1<6lnjE18)rWg{oI#g8we zA2+$|zR$YshDbv;LnOF>QzyG!pXdML7Z$!n0N?}>^eTjB@?UsY18^Yvsk%$v9O^%t zHj6Javop+_%I+SP$O<`}26^?Ja_wg~C_iM*--Sbnzf1h6jKE7_(%{duO}+(dkLU9V(iFh|vw33%XeQ0Bz^M>VwGwdo?FMJJXJg(0J8-!% z=QVN3R?^Sp27oXgH$1Ixg3v9S57@xD*{}PyOMVv+CI?i#dnIV~kVSi|;ZNPJanW?4 zuvP3x`|wwk>QQ^{5&Nn!C2?|oss1VR24xtq@a+iiiTouZjkF;;EC7<$Wn{fH;7YO} z5>Fa@gYqXSFj9O2-`>O#2MM=UV8kbnvsG50#g+$XvHgKna)&%$9=8nPnwDl5pqeZBCfR&J?b zvS%gdh5`58;4j+{7|#L%8$~@7b}_J6s|g2Zu-G^bEGQxu=oE`!wGUqT)~vmsi9Se< z^ujbN{jt0GWd^^JpbXGSe?ywTYwhS)-=9O1@k}s|z^dRxdy!JS5&YE7qqbyeP*H(tK1$v=GiWCDwF)2iJ^1hF&-L6yK6>2Y@YjJ@ z2AxNH$zCVxKu8T7?u>TGYZieK1SGsXa0xGuFSCStDyz-nr$&3B+Qfl{D&>I{s~d%J z;0~GVJNjSYrq3wbW6&FkN$^B>6TFkSoRF`Ic7A&|KPa5mKk_PDL@496qs*l|zOUh- z#${?5yk=#IGb*M=N&)X}!aH^KI7e<{Hp!tx2-lC&9{@LDB zV&HH4rLzY2d3MpT7a&ZVZTJnjhRc0B;!UNx@?ehL_S!Ap+4&8tC1v<%5fu)$6cC&G z1YeiqO9{JwUC*Y?lZNctc$Dqj(D6LvKBs9iP3`Mw$zagcoR^KZ)=9EHX%=ImFRXF8 z$sm{Z-~^bV*Zy z0n3S?)2JqH&@l~NPdnV@>CCcAMs3arE%h(gF)^0+IF``M=M1Or9*69Ad@5!$gu@dM zF>|_UMGHvWbqgxU25*>ZN-*4TaBO^M4paV@dj_KlzA*Bp=A)zEH zgc1w(Nii)v(wibb6cmVKr(%1;3N93t!^w>%yvnoqNl+91Y6^?h^uHsIcaD^88NluI|l&sFMzO-DiedWrc~aRonE=Tp(9bI zHmwx=(VJT7Fi>I0F|i7gL4`H1)LM&Q)z*y{Q$0aWj@YvOdmxI9$f~Bl#9<^W5=le? zi64y`RYX4_Bw7*V{55PhiCiG7I+#h!I%|(~iRYT!V>4Lz(OnwO#OcMb$ADD|no>3FmV${7pvWfz!V+_OED&EFymUYBd zkF*izM~1on`y~=qnns4&WtlB2%_6T zhhUViT5v1bBohb$rsmku9^r`C-I*w!FG^&tWf>=u(HVV*<_97w$#Q#^DFJaI7@8cs zrq<>inj%38vgS1ho6ycK@nvD(puhXdF=I;%7359DhDZ)4E&yJJ>KugVGa)!) z#9g0|&%9<)XGN6x104IL|2!EWj*S_dy6PW=zf95U*D8y89@@!Z!poYC*F9$g3ah69 zv0(TMb+ennx(`dUKS!)9qsfA-cmD&VSC2zPr(h@3;?i)z|c^My4+ z7O|uwpRl(nU+RKswR6iO+xKMZfhhsntO^jQvcOQ>(${w_86lhi%pIIovj`7Pl$IUz zVMqr9j+kEPHuim!lD8E2Ws{?{VW&N508ljC#250ejp|hWX;pK zH&GY-+lO(*@2O6+2-j_`$pCiQnqAt?$|j}F3m8L}(u0I>Q*VwA%L0W!`=G0S25&ij z_rA0ys7_jGcktG<{H|s+-@^`fa;=6h)EFGm<<6?bEBE0(g0pR?pz3Y*qdu2Sop0m4w_sU! z{F-Sy!N&~FJ%ZWy@Q(IPdml^$(uL;g$j~pX;=rlB@f2))i}!fD5gZmxE1NL1E3$I; z?5OzZQ?3dtl05e2NnihV!|Y%xEw^7RmRg_cA+IXgAKo$ib;J1JqPe+f*u)oYra=1p z4LUx}$)o;-%jG4rN=sb`KFqgs383-dsj+!+cmedb+6k}+IN8`ZfGRNr4}w&uCJ{Fa z%H`y7cXG$`JdS8W=~%MOELbTfQ8ncLYPf~iQLoo$4d3o9P|qG{Ec)^cGKBL8kyq{r zw2R&6aH^xJ`Ry{TJx+V)X3%*hiQUj(;1Fg3sx~YACc6`o+eY1szumJIgICuD-d##$ z8`9zeMM{d^Q=Jy&0=U-Q&IN2u5x=fE%yewVV}#u-f-G6DqPc$T8~pHXX^#@XSCGciF~U1R z`?pH69&M#$Js+YCd$P`SxRJ$@w(&^1mgf4LwCwm+BVVmFquttigrT#R3Sk-2sr!1w zBm$ku-Nucz8HKLPtZj=2%2TwOHxCtg&~=v`xzp^qWBnMhZQf^s`8XZEHC(ywXl8>q zu)PpM4QvZo;3X%pKyWgdq@KXjyu(U zASaj!L?z5rX$k&|F=jc(pL7NCv`N}5MNh?^i25Bc>1iut89C8St?@3J>5bxN>Rxg| z3XE4EIM&iMZRg1WaW;7Cym%(D>5ieoOpJY$zS1MfP1$bBK`K1>7O>>1971)svYBoV zBiG>xSVGuju;Dg`%Wf-`{E#!=Mz1wm^gp~d4$(YWkswl^x+i zf>r|hQMtm1@T+XMl)TE+JSc#jm?j%&iTORbi(0;Z_#Q`GlB z`QQsJL)A`4+MCTtHVw*xPAN@$j5V5Rq-0r%M;{8o2M;K0DxC&XqGY7k*};MqwNO=F z2&hYVuzyKh<-_Q@YBe-3U8YQg%gTTF)p#qIh(K^YIQSMhvRj-6z?;=IFpwiUwNZg> zKA}SfMX!^4MjGH6Ic#X?ywnn2kR<5)qCM7;?FT-GI%;vg$Q+^7uoL;U4YfJnYH#`` z^~e=V(U()QtTEad;;ed1*^{1%_ZyCjyvr$TWKvgsUDP-QH9Ro4iGbW)|ZV ze2N_WrGblBvWhkE(03{2=5t0bxH;{o5Vm_rZU=RFJe!)v9|6jX3nSfzW_Y|%Wbt!? z@3*X{E&6eET9r7q4lYe7rN?p?{Ed5if~sf7(D_|r+Sq^>rg<073LH4+5XC6N6s`w; zcSEoyC7B}0UFO%!FTt(WRmMV7)OWZHaj55-mPMddP|*xyMXHbJwrg+bx8K&w5xyP$ z9ix6Lt%z_=LlOVUD%5>NtoOJxzr&xRK>)<2N|El2CR>Z#U~N7xncJzEjnfuymZ2{|hXr{o zb^pK|3}MBmm(dKV^t7Nz5^FYVF48K1t;q`_TAx)|ml22R(Y@Ht0!XX$dQl}6`rVDa$^d6+$vL?Z_w2j+@Q-mHB%APAdpIBQ&0st zn&E40IxjDXPwg-3DLW7x4K;(ETSmAGAT4UyZkbd!f&z`@Y56FN{_9o*EgXZ)Vk(_* z$|KJ0BT!Jti-WZ3<5mKbFYd-Fq!tY_@yUyk@IB4diC@{;6+0h%HmFEbj4?`)Em}bn zgkMeC+Woq(QSaqYGs2|hfvO7fYl+I5TTNBY3I^nf{mnRWm>_9_P#KwI^*B=W}avG__KB7F&G4x+y`jF~82`?W? ziI7T|2N;m_uTpP-B2E6G9+sAM(O3~Cf~0CH&gYXp$C2{M$96WdMyI5M(_&e0oN)j{ zpI0CgSl$zGJ6|SZ9Cu#83^=>U5&bC+!H0Hj8rCO=a#EORc&h=;kpo;jn>|s3M=R8{BhHqWW8~`oO57i@*Wi zwh&3HYQ@4PmCJ6&!Tbawz*abNsD;a-=1-lm2%2a_$%3kmpxiY#e*ForQA!AP=LS0Z z-xR%wzEygWR;noOD@=V*uRv-zLN}#O*A=;GW~1o{<}#n41qzt59mMmJ#MTo_z8UxJ z27;;LnWn=4fDpKCwI_3yCnYb51?w`$W7MR@=w;CIP+&Md38mSI zbK?(#GqDm>b@OcV8dRxMlcG_sh;EQO&Nq`z!5N^IOIQ5;?zr1TBNC507EE)9oHLjWyNH*@B1Z2ics9#5UznG>w!+-e9+x}W3W&euz_dpLe+F_t@yOV^&)uoU<@+ag7ji4HOt~AmQ9i=!)!O+am?%eLdQ)_H zRDT&P5-wQyl0p~x$WsJi()0hx<&_zk?WneZ;h|N!oD`{3~(`VX{S*))l7mGH)zMEU+ib(AW zoa6>1g@j=LaLcVcGV2p70z;V$hTgI5n}Q8eaZ#zzuKzM5Xr$LTy149<>vmHt6G&^^ zVHgq%WYm-Gyjzsm(x7w<{V~75HhDa~27{yI?32U{CruqLj7#ZPlli{?p6`zpH|7CC zL}{QfOivxsv>-b5er2W-Fn@m9|C8_kHG{YEK@wG5!3Kz$j~n4wqY%PczVY{`+<+h9(%gNV zJDF*Gqrx#IbTNMyZ$@L<)_S>=T4yW|#~&7Ml?ex_FCZY%dQx;gL9KamQLTGuOD`Vb z_ED4Gpx#B@Q11a};Tx{G|8ZtM=>u&vV}F~W_xiWr>Uirxv7FsawTP{rX)`5L`J7wTl9UaT1! zExh=!p+Rm|Df{M7>t@^+?lyD2N+C^Baf3ym)N~q_klY<>^vJw?Cy`W4AsrNHhC>sP zDO^fFT9`+nV8rr)v&*ZL+2E}eRRz`K_zLgw?07PkmBIr{>yTO$m?XCnRKJ;m-0X%= z38o}yRiS_8)mgEKJX{J(BUmdF@^FY);U?1{ek=%K0#r4*o~<)wFo}xCh(tiD$O3|L za9Y>L?hsskYY;>2^JDTwcAbUo*Nvi8)UT5sJwgpo^>CW16Dt(d0?^Ar7F4e85?S)a;$#*o4nQC!N0`eQe_O%KE}>^&=f=6r?%BZfEF zDB(4|4qu?y8VnGK&oDTpjL%AQ_8(5M&s<_NfExDIlv_O5*m%-wE(`r=lg>12TFHnl zHAKy$ZP-{?HqEzcyCfgd91{pCY+dpmzI2t>u5k9Dg?L+8*1WsAM`zkRad5J2^8ccL z!D~CN>Uy7yro7Z}d?ygH0&u`$`8Ww(tZh3;|D7cfU`OFW2gI{R+Q@WHgqYH`;H?=f)&Qiep6(BDKbfVG zoUEo`+JP#2_r32mCxiJvuUrr39De>0l-IV?+kr15zUkIFFWNIU^~c6s{Tw*ZbFP4m zH1a;p1TDF!-UYC9i1(Cn_l=$2^VE3@n8fYuFcoVHU&puIz}~fncfb%yxiFohUWy&0 z+ABpNjRy@%azlfJ3nM_hhoebkVoU+b6jVw8tU zM)p8)6th@R0YlGxoHQ=b#4y#G(1Zn=h9Ja(4GlD7J)yZNWPyYq4)byn3M*U~PeZWn6Kc>oF0KdjOruSHqP9 z=gQ~6MB3(TH`u^ZAPKY$s1kcItFVf{o6*>_Qm3GDkA8+lrWXuJKdI|sU4Mm;&T@#X zbyTESEXVDlha#QtNVhbA8Ar1)AlqS5Vf5R{ha2Ty5>i$wo7C^&6h_!sDEgDM zL46)em{SIvCkTm5ry>V~CCS@;-MxjnFo4to)y?XVkCY*v3vBX95QGGrHxi_DCIvc3 zC<_O^hg2?@y3m9s_0Euoi*fRNp~irPwRc|4tn=a>qeH&$Qhr7~b~e6ju_HKGi5YFY zDh1EvfD+Y9Ds)ebN~D367`v;Hn8re@F*jD5x$Vq3l74{GEY3`*?f8OUl!kFy;&PFY zyx7=|X_X)m0kTA;te6R#qRDwt0$nOL#;h=bl2kphPgcS<2*u`wrim%@W&?14GiS5T zoq7$3dywF#Q=I?xoDgf=4sO}vI)ktzH%T=PbTa4F6U;9!(0=Tawj5jRH0^6fR^vq^ z7F2DWcbDgby$oBjT??6kEgc| zU{Vo%oh&J*jF1W;-RTHnXu@h1N<)4}x4=lZ?M{-EpCh$~!7bUsB*z`%27B?Ga{!v9 zZgzt;pKGeWn59lV4%d#KxztCt#a1C^JkttlJxo~wLJDmp#s9V$l5rKrFoToOP>?!^ zT8I2eu|Db_;Z(|brj43;mjgz05}su)-;bs3fzUyyDHQ~*Ly-1Pi#LS^{;+{Qeu)I0 z1(8zxkbQ7Z5TpK_=FvkV$Ze7cWc^)@0>kj^AdfgfGz=plF~A<9I)$1je%xu!_x?+g zN9`ce@J3lo8QHZRHX1eQ?qvMaOeK)j_6c7EQ0b8@PYf;`@FiWlP^qC(&eC0-xvfZu z6YH}4cR8W6-=w_EoizSV-y#r{F{&nn_)oA3hJ){SHkBK3P?+K;xL6Cy#djF;qh z?_+<2gUO031)j-d-0+2d`&OGh4C2(7%d&AwYrG0uRc2>@+@^s9ACH&=vH~^Nz(p_4 znuhj7A2xbmxlerbK}(-wh?5OrdI%25bGlWV|0xn>^LPB;8y|tn_HKo?-!Nc_6BMB~ z|H8v}hqBhaD~KUUyr9dIq9G{V&tt#YWc1%njmTuM#2ur3RJ^a7F|;y zhe@H$HV7&oN+Y=M&i5tzNrv!bP9c4$1qL|Yb;cw^VmGQ7O64E^*AshR`8tQF)Iw1C|TnB(T@z6f18$WcBVwI}-;*1e%AwP{$(MuSsU zuML^OH4@>R5x0p2*TT)IKRS-$#w`ux_^&6&XrT_HwRT8D+!}?%9v;*o)Jaw#$X-~e ze6dh>BUYkuys@e@6Mqj#@tW%gE-%T$&d_>)(0r#Q3(co?%&suuH+2lmZjy(V%d8Mp zc80Eo8;>{a@?v0yiB)vgO#hl%s<$?f9-?=k3=9ab%jYOkdbcIec~diH-XAEWhafZH zG?cfnEWN_XR|E?HpOij(haF(Pmr*=~sWg}8O|$wrF$)jcIdyYX|i*I6Ol{Up>B)fP>y-qh*yK z=vy+A#V{wzpn0WadFilnW>+orQ(Qs@zB)s;dE+hB0ytZ7%{xY`R=Ui(fqibUCsWEZ z;a^1j)S0UWSs@L|dPQVy{-*d{gCGlyFj~QE;WjD!5p8HHd|}Qy{5RAQW*43oMpa!i z`J2PRsL01BO+7(+MVrFbOgZ_0uM14PZe{0tEf+-z3a|_^#!!=c_>A6Kggj<0?=pby zArHwz(nIgx0vKQoZQg1fHQn;gs|4<+q5{b6pHE`<^4XCxo5>p1|f*!;sDqAHNzJ(jX00|nts6JUc3*F8fMzLe zV}$HTW@3)At^H%ybgK3A&7lRHX6o)TceCPa2P*gRO1Q@&{L2 z!uN>u1I)4j)wB;a4Q&yLZY@!NV>L#nP2dK@4H%T^P_vD8%!g%NCQP2c3_pzv_au+mLS%3vNsvYd-lWic*Xcz)3 zFMAU0mZZ8+rdmh$4Ghg*9QGQ`TSvO{&XdA$tWFpw6qEX`3ijY<>M;RN`phn}5-o2a z?Jd{S!WBt7w8IpUA^XY@Y@(!;95=g>^x%Sbuyp6#!;AhPO6$&!#F320n;3xuK7e!= zmwg3FDU+}jj~TV;d3wb9Tt69SPR@>u_;m46GZsHKW+`q4hzNu|ANq`&(3xV%6d}Xp zvgAu+M&&CL2H?tQMTeq8UBC9W`mj1pb+V!mTr zE*V&cm5^E3u+=jaf#e`2Dk|I3C#!89TZ%j;9a-{ZoN$jQcyO3LT`1(@5zBgT`1gVn z^?=EQSsfh>^~@22E==TBaZH7)x1GJ^N!)**ZuT}(x)t1WNb9$aw_Wc^xB&oa!XavcmyaNb%=JRI0MZeff)$_9f#)pOq=vO^(dkn~S%rj!_3RY`$?4DnHSx`QM8 zdQ*bN$uSnyo|}Cv2LjRNDkiIEN%Z#GyH7)bkGJ}0(S66JEYBMY4mBc)PItbbUxjpj4R?xkzS{!QwRbCo zbPlGX*mms*5e%}WAo{M5CfJW(#j|3GT$M3d=v!ZhfyhYnXDZGH)VJn~H4-=!$x6~@ zZIuVYs$i0NXI*E)iB!r8p;!RL7zo6kJWHL#A4E$|1|lGcqw-YOdm4eHa3o=3Y?<*# zn#qM9i5gNxT>9sK`l*Tw;4AMdIM#%XQ~*6A>=svC;8iQ!u&r`_8*Y1Wd0qZ7XZf+P))9P40L!}ykEOf zDvM1)VNg!`cHnMAJV{xQ@MYpo#KGv?lzhYm1oE!rb{Gqs2IM1%^7IXx#3LVS?7|w$ z2SQ9mN0=3p4at|F%>T}AOA1@bv}Wo@rY1v*NydJ@(Bs}v8h`$tf0}*C& z{!ds9-XLWn#&PEX^n|yII7N~TiWY<*{NH4CWjN#z2gYBMct&N>49AMWlPM|}lnmT! zaE$tEkn-S&B1*>r+ezBP|0H>-FrB(Tw2glbfY`h-KsDFGP;)%`+L3E;60)Ghgs$hq z#C(e@hq!{UF*qfH(ajAIF^6}a`xa@&Jj9$G5eTM-7Pz@Bm!FCj=Qm;k(um7RKZLzK zW*#P@<>F;xby`Vfw7ZAg-EYMrAhp$;ccj7d*m)`Le)RIW`XUcC*{44y*{n9qG&6-! z$})pC*~R{%jgINx%Z0J4Fsp6Ez2H?eaVZMF}GmL{fe<`kSwrp6o%%mF8| zgn_E_NGT{vmJR+NuoC?jupUwT2Uzz~h(xbnG|=oVIQbB!y95|vj&O7AAre>A3?C=e zu6|iDf$tvCHfI1 zNt?tPbDz``$UDxE4aq-gC!pp)AbSgh%0l!kP{EY$AY7Ivt}sgs`!_k!2t!QMVZcE5 z1>gfQd>Y;e4roGRYfaB#n6tvHV+8luLR)TB!-x&i{YzP{_b12X|It+pRQ;+4z$j=? z@GpZpGfm1bCPGxPuzSgOOp)e4;~&CU+ysA&@#|fL=~obP(BL@U2xKtW6cn$9w1iHN zRCID}^BUDC(vu^{yiKtA9`l0b)38Hm1hRJnS%k9MHPLM(ggpB>E=9`eKR7<6WF=tB zIf%&;Tl5;;*J>$w3feRiUM7Jyw|O?^YOnHRs7FA#N+xoyr;(Zom@T0hTN&6(LRk4g z{4D_9;nJ|D|fSd?N*<2!fo&pt2KmR1~7p9FI`#V?z z>!+RAcmnTJHey3w#0*VN&3yT8@MtR5+*NB zlpisSd<+3vBI`ion{RZwBwLbBcX2KM%SFS;Rpa8|rimnjGSP#Cl8g zA7cHto&F!hnqBQqHTu63D-tJ@f9qDdaGWHf*>&mlQRPRtV6aU2Ln28GB-&Kcl)T}p ztSTgIsx(aQ$p-^D3LQ@Ibq8Q)LlRws>BE2Ts|5ecSE>FxUrp=&FJA?EJ^8?be57i46@(Cwefm#6Ds2n4@0Y z5W?E%|HD@qq|==1Q~rPWYGN5!ioOkGJ@=KuX0d5+s3k#wYftL}r%bQ*FcC!Jt8Am{iQL=7G@>m@iX2AP5p(rD+Wo!dMcK z;{b7NeM{g{ehw>D1`7z`4n7N&X*V}>R+qql-* z4k=9X6)<>FJVmZjWB8dWm8b_tif%VMOLQ|VQuNQG)XlmXAy`0+_i9Bcs7*3zv>1$n zQq!W1^c_x%#KU_QMZpl#MVVqSI1!cp$Hc=t3I`{Y4W3+Fr%nZFtEkQ|AHY?9j$^^y z7_ouU`s5abCJ7RomEY%KwmKoR!)cCZ6=-Sv`>GZZ292Tm=uT1And~bZCE7&p#i0!W zYNnP7^`}jy4)(C45fCe~0HB7ajgiEF3_T zQBOFJ{sl$1{yQO z-GnM^&id4${74S#Cf$3PHFxm#aO)3h_9``M#ot&zRfphWi)$ml`Wba+wgid_jzUtw0kGSb3%)hYtCI1+9?v`qxVgcs4tx1z{M) zetd8)p-6dOSW9S_# z@Tnh&8lRf|>U#mk9kAXZziTv+PC6bC^2~bZK8{>Yl|S?&#FALNc=$K;1M^~$=?$4&8`t;7u688g@HLW#!am&eZ2$F7vYD{lkhu+U`W99nfD=;3TfFn5FtSKN!Tx zYhN8!&r3-fQoO2;aBGj%96eQIeI#5ElC{WDrQmE(sV}xPmLM#`;{FHC*d{4>0$(*_ zJumy`TrB9tH;`z@icX;yTNbJ%4!@XLHI6M(rv#NZ$;>;QfbKJEi{T+sdQ)5#ax7Z% z+d*gKD3B%9q~hy8Xuw1>GsTGT%i!dWf&FY@i7SJv%zS?;`7H7{R!QUa=rzPvvSR7| zD71<{olrCAOY!*5OwCz_sAi2&xf@?{hOKz`RM*JHpnt^Ynpq$sc& z4v-HQD0OYLuu>UVDpx^Ggi;~Q32Iag5jG|`2{%M@4(AX6j_7HE%mD}MV8Cc4tnM{# zoWXko94gTiDcAnkZF|qXV+XT%vp+uCac+TSgHakb!A} zwoHN2PuA=p^qks45kS{D+;?ewp&fP0>~@e)7(h@hqYa$kh}iso9UO<3z8@0mm!_Vf zFr;BzQRmvPCWD|~1fzPGn4#lvcf^n}c0w>!jEaXfINc!xuNDKgj9+`CPx7=!R}mh< zLlq^jm^oKrY!njAQvJj=*nfab&JYy=!wpp zhjjfCRMZc}Z$u)9h<#lY>9BUxAe+cis4$Ve<=j7|F6M}CN5=w3Ei``6 zyOXHwg|XbEfiRVW^{C9T@(kCZ-6HxGr2`@Y!2FriTWjkHxRj#jui7t zek{|7!o~=`Cy872FofU%jEOn95?Zzq4A3yqh3FW{0iPj+Dn>)5QPi+PBQYZJl7Re#ESP+l2d+=d z7AAsLtOrTcM-|v<63*fPpvHlTGgy1T#Vtmbc(0U*|4dkN@x%ZpK>C&xt z#{u?;ap=<^A!>Y8`$R}$SO^>L3`6O<0KEdpVTuF3r~R+-pkrvcXG9asz6Kj@>I+O+ zlwR?S)&sP~=^`JJL?B%GD#ex7;0EHOxf^4WQ7GR5MDYS`bO9ohf8FUhN2ul?H3UH1 zIK;wfXbE}&_(A5F;FF>wHfB)}k;!Y%e*knz25c8YVcvDhL0h{Q%yx@v9UH{Kp=EcB$caXV#VcV^QG4SibHUxXInAnXDG4y6b*=6KON z`Zb(_iZ-&P0d>Pl@kXr%E!5ol^cD+5>Z0yK)0e1EI1$zayrjPq;AI-Z-jROX2N@5Z zjt+xQdA6e`D?%crWfH3nB-u*cN-Ta)7@-C|0XL3`(G9{F3`UQJnbJRnTkQi(KJZC*vX$OP6y0`zZwp zp3*XDvIJbMrONczd;o*eZWgD2KU#1CRHw^^f;>{e7RO~?1s&<&dQUf4o2+wmARaiO z#MX{s;P0ST>7LaAx7L}N6fl%*-3pNFM&AY7!6KYc(JE=zaH2z#uwp!gN4rkL)Y(NU z$nKYv4?ywext})ldC#lQRo(Q0GcWuQ(c?*fGq`u&$$Q;;I=;h*na%fL@o>A64g(6) z9^rYZ&R?@d;*360(|B?k&$>bIqXchuE7@JF5T2K~Sj1X*3i<{{88+7|_ZODiwlRzM zwuqF~ZK}{06ze5|Hd4|>OvHiajs~KSzTvm^@EbCfvIk9=RDIQ>MY@vI#kMLB z!?3QfT)GklWE+@PZ`eudfbHqv;bROTWdwElww#h$x73@w2eng*GG-FCopvWQ#cZyB zDF$taYu+256*u2mDli;u60|+k`~r{>rCC?m;!qCG{Qd~OGx44ed;Pwz$8C52_vwBA zkHlhq7ZMQa>X(v~H3NV2E&T`UQ6OCQ_d z;gqsvHm+^eU9X+NZ2`=QxS2-*@Yc>{lZMoz(?}+yxS&5?;`Wq8c*xanW|lpmNu|F7 zwqp0hZE5LgiCO7^`Y%4#_Y9@mW`_+q+h=9PV-{!*d`A#;7ftfK5_9Utb|@ssGRz)pim1? z4&Tv`qHILpAssFSu`-D`j^SlVWkHnWc(S*Bws?&M@&xrkfyzsKml3sFM$M1-mDa4Jzo!zI8TQ7?wynzvR6pSgqKp^j96p z#UO#uJZtJmNo2dFtqvA>2L3sL*)8{!WHcv&Q%;3yF&Z^hNbV3-D4i&XyBQlAoRh7&iZ#W9?+4 zq)y^`<=bk8vHRF=-S6}|qI1ZKw3K4#)6$ygM$MKDx{}-AWF)7os6xskNqV+)T68oz968#m!8ALLOXkJ%-6 zVIien0Adn1tPLAGbvy40^IA>I#f)yBp70$7TW)F=ybMC7aw^waXW9*pHr9&FofK0G zPhV7IkfXW#J(8xsc2fwh0br&kn<(7zo(vy`t}N5!VYKNv14vW8g%0!VSU_6nqC18> zp1L+W%Mvw6SAi&kTtNAPYQ+i-@cY=DGLeWcTUSKiSm08a<72A zK7Bn34>;y+z3PD8>xL8&D52AN(ot_(jkTv{#Tz*P5<DghP29>fIHsOR zlFN+a4s#wxDCABq(mXM4^G?&d>~ccZo51Kk4~>@H&;}_S;X)$Ii?Ei2B7N`#VB6r% zK{_V~xSp1kkjg{8(QTsryX8B4jO39`idB)Zr=0`JQu}DaOpaq@i-Ts;>rsfpGgskC zWrIONJ%AWms(LBG!#+^mcbJ4UAGrA4Y+^(9gKtGg{Zt7EYy$PoBh0XXP964EZ?*0u zu?S0b2J{9lY3mR)_a29=uU1jD#;=L-fyYKNS&`%2Moj{=g75Jlnu zChz&7Md=C*Vaf{jMUvT_tHB@>m!NIG4TI<0dp|Wy!EIsjtfDB*cnZImUzAY%9?JiZeQfgRHgXk=2LSfc_S7( zRnMcG&f%NVyZLuR#3%U{DI6D=o%ct0#J}PwRSlGovW8+wAdo_ZDMn9{NEx`FRq(qN zP8{NCS*Xb>J{J=&cbt;(LSU*Z^bH#Nhx2P;-tIlz65jd-AY?~!j3i$cAnOmufzZW4 zGaFa!aK_`#+N~Mg;)%i+m6l_9hET0VIye_#e(SKO`_=M|oR)j%?GM7Zo!QU*Xt!_( zDkdu*aQ)(iiqs|$4&Ma@{yahBiIMGa#hi?(Q)V@ElN$>GSiRj#FGGVRBN?nuH@*QsA88ur{hzNR>p1OwnG9Wbpx83x0pR znzMIi+PmfEcf-|*IYa^C$AXi_<4^wR{Q^nnE9Ujz9pfkioh$kpFXPLTBsKk_Tv(oy z5b)7YNMV|&x&kynnjp66`=JVp!VmFL+FE!cR*}4z>P~WtV~=Z$;avNSSyO}QOjNk` z@>Co%_=|y&C+y(Wat(K8iD1v!6olYa^3#2t?>lTcF- zAF!5$phzB_jAfZOL4^8Ej@2+M;;6^uw^GN$dp6J>6Swm`_XSFme@c!o! zh~D6l08fM*+vb~@e%aVr~g@(SsXrj?)=g zPHG?hsFFa3oCM}|zSfZb@4%-^v;N0LkX0~Q&j-(JvWUQ;h9w@51`Ah6#n&TTclPnp zZ^S;f33Ff_`EL~Y-%p)>gwr1_at=zpyCWZOjxdeWfnv!58cbj*MT zVik4bc8Wcr_Pgfk+qdwCAEb7Do??8#m8S0cLiD}`AQ=^z;9E`ai{Vf`bWU=9I`3&+ z;(9A6dL#R2QT}L;-J?LMU(Hs;cnYMofzCNtNt_5VbqeCq$D!JmaRLd*o-p z>WeKJs|ebpRn|^!qcv5VM+7?D2V8W{cExz$&ow!#q*unL{LMf=nT8M}KZvN=CD+V( z6F^&6`8D#MQGwe60QdvurlVrU`O)VLdFtsttnDk@vCHTV=#V1Z>#kuOj>?!460xg! zaD5PTdBp@NSCGb1VV>!?1^jvygPsl8pFiA&1?+?_!<4WKOTDOmg~K_b_Pak{Dm341 z6K>ws2PHGjyzB8KDe!aVkiIS5yoq)o^HIcELxJY2AH}PQDBTnGy zeGQBh`DHd#t(dO4y;F1k>apFix)uD;22+vb) zGx^u4_M2sz3TJo*V(@6LZua|_Gw8;oa+DBbbMYfxI*<*80hCeCzlXk zVA6*Y7uJhXx~%SAew-HtKtVm!G-UljTu?P)x`tYdmlHST`IQ53B`0ctg}GCQ&LN8B zX7}=Ahf=ghvRu1j@e(p7we5J65y8Y$5xVW^c^T3or)`L&ZscM~TE5T4jP5(-Gur6Y zVuUon;->uTmYGL{i#K*Sx43@^KnZMARF;KrrtsEPv5leIlgmVxU}akD-&dtK@JYo{ z{)`U^8s$!y77-!{k-DZp5dfq)u~e9unYlJ?qsi}ya-k>W-40=uLDx-#XUEP6UP@|e zQl{gE&uD1tU)JwOa_iX22p&Yq<7>$Ec&U!tg^G5bT-UJ$biUfDlD#BBe-y80_F3ocYR4U0at=Y}!7F|w1)Z`S?8+2W{l4%Lvi1~_LLZAgkr5u7 zi+2~~boD)j1;oP&VsvJ)MHALn8_PxAGBSv!5z?VFu;@aTRJ+sGa` z1tbD(_aaa!`s{x7G)Fj$0D&Q%TP4cu3LNAz1<;LsOPiTtC^pcD#g5O{2CnZ0?GsEQeTxtx*AV?gL9^J%Q2%zi zzXr3TUaK#5(SD`2x{dg_le%SkqFG;Hx)JNr-cWTWQO9mf{N7$7w55&M7nHuXX5X!t zZ*I$@awfMMK);Xz;E z1HXq3Xi0^3TMXQyVrqDUghTA574B<|FyNt7cbcO}De(FZ6+7Qh@rHOWzF@na7e|en zEEx7XibME}DG)q`P#6IT%(y77MOzDG&Dj-L&>4F}6^rl5Rk}5#h`9O!_{&xKT8GSj zS3kO*JDQhH=`45)r+SbOF?bw|Qunlc>77gGmmyEj!3o?q{R|y@36q>LWN@AD81qXa z%S=)trYY1E|L~&$!OA#h0DHJ1P_2ekE(7)dJ>RbN{e{;>@8@wncX$Q;*?5>p<$3S0 z={+0`@s`Lfl==Q$`sc&;&2E2Y;r2Z~-OzsR5dxR`Mt5FTRwNL)_+-7VcX^1xx1e{R z313Cn5r!c3FIyA!5TEvbNHxnQ>F5doLrohS%WDAHe4sYauKn0&kJOgbTCZ{neYWGe zAxMMACi{KkZ#nE=dOM%e{^a@Y|U93Y( zBub7{&H}~m2MM~<3sGKe5cg}^y)kEq;f%fo&P88bm{`%l1xWJi0Tp`eTXoLQpvSVY zyID@l%CT9am9pbfEuDR;r0e)Oynxdq(D~8ae4|fLi<5@qeE{0hHKGW2VHZ1QD z$brS_F?9#6FLIeyj2>}Gj}2WChirNY~VB*?M>!)*9{eTQSCRp*K^b! zBXxD`2`S=ZTd6P7KMGL-A&Ybc{RScOw+{eY7BRNt>lw7>JXfO0bhwO33j>O99s`Kx zbpcgKnj5l=oKlWEW_OC|jz2RaPJ&n-H`P+$9fj1n4)}FYm;qaHWND+1_Q?Z#>EAdA z4)B$%YRQ;SvmtEe#wADj$l^u9Ul-e%zqzbSNRs|$DqPbgaNF=e{0?9`%%k3r7lBAH zV4kBTVUdOHT*wgWl!tbwbEYPMp73R`)Xj;!ht@5A@eaY%u_ZLA*;w{E`%O<8tGP^*6wu zX_+-g@1l2r3h0o?F=+E`46~hR`&Q&Kr90^64f&7~x1xPHf(;z&LH?j$gU&CJRFD6- zJ%oUM=`OD?8g~Qjl(v`16S8FUou04JnxVu1SmVePM}s#2GT$3Bd6NS5jrI>*k(RO_ z!q3;xdlx+%A7UR!AR_pG?Y8qh=f2}|Hw{4^dBiSbkdN-`AI@%4L;VgHFMXatpT>oC zJMBM6HQj!y4l731+@UqFSLC5?mmUAR&}l^Y=DS>T>=0+{?9`y}3jaPNS$GAtD5Jku zf<+-Ji(uenLo5ktWj{w^f=VX>xa@zQ%<{kA7LTX%iu6gQVPP&p!Fxs9wg6V@k+}|r zHnS1z*Smfv7SRsuyDjIDHsfcS$!c35Q|QsWaaVfyo9Q`e#?n3)?wFMwqOQH))a*R! zbg?)cAxa6QtT2CTj)O)U_V9x%MMeZNfct&vLyS@ufdPvp2)LA zGx>Wga^ZqLCC|1NfMtt|b~Qj`2wOlA`22Du;EC7*DvhVM6uFh~`PW4@0ndUoY3ntR zGx74Q@zvk_QaGPVIloa@?b0wip}OcLBa>=zifHCVwBp6VcA=^D)i7n$5Ghxb7xiB{ zCsS_%Z;<1wT0_gfF)>kE`W$C#+95T(ngGm`iLMZ+-9vYH%(ToG`f!mCr@|DXK&#rf ziRY-X!^J_$f`DSpjr<0}EAU7;B_-o}56475u5SY18b!ES2^h3+K!cy2mG;6CpsUs> z+3P2>css1pMm$3#p|tx-vYen5eHhxF6IM@%{^jxy(3vNErXY5=9bby(!y%8R~M$^6xv( zlp@l`=_`NL51Z8Fab42D8z1*Ys67|e;(iRcmOL+4CVGH~|1^cEnD?2P%HB|i-v`FN zRXl`6B_?C`tocGC7ksp+@TP|yr?^NO^c1WU9~Zd?p1JNT$i`35qt%0Qb*Ebr)02x! zN%$j9LEzd=TV*qqb78GNLw>rTQnw{+4%5$wvy&{*lbeDRGb{7S1<{MdTA7ADm8}|a zuM4UgWk`e9@%w859~V!ytRi7M4s8&j3!qx2peb*7YzYa5-SJtNFXQi_)GJBD;gJjG zJfLLzQihsVU-KfqvoX*~XG9R_oOgd!;@lj&PVM)=jG6FZC$NuhMg*^W#fZsr{K-GN zt>*2m@(1M~GxWpzFo%yDxZI+{1WOU;%lpGK;Cl1`lr$38b528-h2r4t(=UkXrB&4<)ovuDQB zy=w99lRO7D+#;>-#{>wN|E3^KN)QwM%UK)XqzdmjFzATB2|SXTUWhFt8J6s96RhTc>w2yo>cZE?*%JJA{P4a|&BU;K9-bX1Ycn48 z5Q1+_@6`*xtNnAHeW9`Y0KcaTxySvU2lM4%hw0{VM~B_Wfe$0cRfS(3CRBp=OXjE% zM(0DWjGc}kU6*=+0~LFK#NCyUnfY1X&$7j5=Q{>qvno_OHshLeHb)MKLHC0(Kfk`O zvGcWWMnKkyUXTz|<&3A_8TJIii4o#0=a63a6UVfBD+@gf!=m>za|dHAfor`Ub;F2Xh&QR`J_|>`Ih$OOdeb^# z)F(sbZEL=Q76Fp2z~@x1^YsJv)`$QD?n)DJD8#+Et#-w}0^)ta1p`QW6YTn{Z%ZJe zrCMTmZ&oCLg__MFo+@(^JG!$st*!u>wOtwl&p7a5%Wq57SBybY*lR5)J>+UZ6zo7xRvsRO&&uQH^pHd1t+zvju66lFf%=z`*!L6 z40gcas`-cc=?gYWv0_&NF@xC(IU((KhTh7JqObcs=SO+t12ewDv)<$MYii41yu*U8 zSxRMq;I5GJ@TDg#*ph4E=X(GI26QOIiYbPr2S&=_t_*sN;?%Fr$Rfs@Zey#Y*6r24 zfOrbR0}L;q6Oc`LUtD0b)m-*gg*42Hxr#cIdQM0>%0U8+fI*Ut&yAhyt%W zm!pRfUPz3Z~?^`$<)MtclKQ+>ogO)&8Ld97Izh3&i zS5pY2Nl+SkOE5jfauDIwLb6840@!S(5cP13HYMb2L&v?b`S6V_dV|9Q&_EuwTF8>n zo&&oJk9^FGs;T4HK0inn=u>+vXt)oc-e|)NQTX675}KjiHjw*Z)M`4Nvr&ZJkZNYF zbVf_-9F$k8E;v*%Q0FW~$?(Y>{4QR$K~bFB^lnnYNRK(4C0MTdPoV1O8m=hoiNiV0+!LGymlB_mUMO`$ab-siSzb`+1haL2|`&If|Vq&q9wtC3>l7>52RrLrr zq^>Q#Ck_Qd9_0!v8M>xW5KjZce?DFUif18oe&MG?b@26KxM1>_seOl1lO+NFIhKD} z;aN|wA83Z8Ruf)z%SKtD!m{cg>d9uy;a#jH{A_~COR|Y51rcbn3?64`KG>hb$#!zITA(5lQExRERq|mk-evP{^g6-DRAG>waKdteO%9E)3TF z%3mKabr?BrlsI;%+~AD`j<5}HbI*9gg1RGrfa{(kupRs2d`crrPOSxolie4U%#MKD zGn1zfSfBRyKZ< z_>E%)0ijAQR#_UW-3IE;@e~*pstuz+upEHy7QX`ea z%(W1Mm!B4hc?k$$nLITv+*XryO7t8Hd|R4E$+b10p?f^%-4$&V{t?T>PyPiA3WR=b zz?YRP;pi#m2vmkE$B`{`be#!C4?X>DS$S{m*Q3GP>6myc!FLJv-sCz{!G0ah9CwLk zalHL7XLslvluK=@!%b8Wm4!u2B`5v*?Ee{JRpD-!UZO|Uk?okknPawfy!JmX;H2yK zLjSAJKFfuFadP!@%qSX`1nIc5{e6HNhv#qf%P+|^0Hm42RS~DakzaiQzd)3MQj}GF zg-3~ymiUd2ia`gq5;Y!;{89xzClDd#PW^XVP%Ff)O>d7o{c3>bAWL~+7c`DO*lgDl zxOIhB3UWIgS%iri#8T;3aU-Y@IEx+Td|CSk4W zZ*z+PuP)&6jyNDOr}s~XK`?dI(xo(+DTmdqiym-}k($7R8r|rB#qQ&GLd@rWFBWMY z{u}c3(rQ~n!g6w|msbPd+@TWHp-W&U5AxgOs8;<7_x#siQUQBXYVVXgIRSp4-v%d- zH>P_QYuYjE1_xC_Njj>DiiilK5=|vqEVLwtYUyuRFkSNt>TZk59o2S@00WkP^S($o zw@0267hWP?cV1@lT?ePz#}!yE(}VK*lmahB0+gSib8k{Czds+Bnh`%oF6{1^0NV_I zcCUrJ48=7>zEhH-D>&_R%Ny#~(Sq6P4|o;CCCj7zS|aRkIplq8*h}`o{zcO*Q3AQj zUtiEtNPbU=pOLtZG)`Q8tcqmzzCMf-1>HY_nELN!ZvNE@(+GI>e*F}DrRqG4v`KBP z!{gqcXPMx@)_f0pF<~~hCBjRJM$ZOuAS}}vW_3E934#HC!nnt_1IszxO@>SIY8~$K z_Y2|Y?>myH@SOKGEDXEWb3wF+4hb)$ZAFgU^PzLn6UNsS zEsqz7?mo@>JHFa;ru~?bjg}M4!R)`_Im{-Q1V^)A^!90+Y0dz0lkLlw;ZnBiD)o7E zx7%OCy{_6-BIO>3wH$LzP5A-t!A2QvLqUm_NIW%0Y^Lmy5y*>lF2+3eQ@Z7I$RqE1YnaI}t zljUuK8Sn~OMrE|^@h8a(uK>9gwcoB_-riwuK>W$@N})?SPi^7326E8BWREHIsvx6c zBWuJFT-c|fF)PDnpPEPEEex+a!i-ol+Yop(t4zmKVz-c0&<5z%w&MhLxM?hZMiBhC zEjFNB6%38e!qb&7I@{5Ypde3W%obo`rZ3&~)$&y${6OEQGGz?Y6!;<4)s&|hcU^liP=-Bo z}E%n!uNqu#-R7_x zIbmGG(kae@{ys&W)~~>>y+0vTXpTliN} z2E-Eup^Zf^xPL_ex8K(NECtDc;9=?gf^Zk%?`QP!EHR_fwTNZr*fIhw2}aNv*R0s_ zFEaiq!&(6s3@~n(Ng)*)0sP)$#Wi_`u>Z9{mK^#k_zDZMveOC^yo+f?`;K^RFXLnc zKNkKhh)7u{SX%usFv*YFm_%$`&qsu>sv(_(Y`k9E^W#2g(b%D?w*HrOyIK_6 zNxCgxw644NMM#CV$EI57rDaCI{?hUJ_l(9&e>Dx^z>Fmeo&ODGYSlK}WNF{bPZEdU z!zd17{zXzpzTONWiK|#i+L$V_@}e$@cY`O#8yEDA+8=i((o?!FuezeycuowxwsE34iY*Cx8 zGr__QWaVy3wx0=7`oZ>&adz*y+yp1elxt0Ex4Fg@(3SdDwJs@gj2;DU7oIP(g3(3Y zc%wkEH3|$$88z&3C_G7qyyO@@?(+I0rmbzmfHcf=LXjKf+w(f|o zM-;01it76t1(gU4jqlL=k09j2t0X}RSLEy$O2XFax^_{*Wga}ox?dsErj#UQ71&O- zmv-5GSK8{TDv9QTv+^cT9i zlf%ll%_r$V0iEYBJb}Ma>re7u{H10e-8XJ4RU zB3b2e-0pL}yM?F1#X2an({jL+Y{K>z9c0`MDGH@%(+PWDsk-hoXw-Tb91#)RjJFVH zPbs;5A#tzQT5=oVTN;O_UqGOn5#tvl#T;~i6ELA5Y3WE4Gw?-Yuw8(gl>b%oU?e%! zsn)(d`XJ#ectnVuv=SjnFN#6(YdZGo8~3hK>L%tf@d0!+0uuZE&v*2Klz~6}93qvG ziZbc$0KTz@#BEW#-V(fqeI)kYmtzT#pV3Q9PUr^pWQepmWvJy%R(7O0q8LInf!#vd z-K2D1JkLz&;cM~+MSsOX7_I4~Jd!Mct=-0}8cUuvr|}k!~e*8+95>Q%~hox#AgbRhPJplaI~KS|mD> z`cA|;FDFbWc#oLnJHPr5c!MsSM_oFmG&CgS8@Yiizp z5gmfM;`%5!Hdcp0R4DYHdnKPV5CjVp^w~t&d5W4qnA~q;mXI)@P~!|H?0~sIU&wD! zxyCv1p>a=u*8JLV?IH|SSUmGXz326JT@2=x&`BSyaY}*%XS=woabkxK+2OPV& zq$tR*6Fm6{GOrUxC!R*kFs4z)w94PD1p>zO#ihlB@bobzm4GDW^LV|^51UhE4SC-2 z;v7wf>I4n{PC4HsLC8*&JZa}@rp@bh=IjzUE{RHKZE-ZI36bi6naKJ$V%iFtiUg}D ztbRM!_3JAAKBX}ULv#J9)0gBY>N*s{XOLGOEuKM94j&+P&Hn@!GTmJ_No%I)!rth` z#L_kw&NM+r0FEqq#jb4-&(HuGQy|87`KPI5$3Tis3~q87bOLv2#X()lFWP;0?sx@! zC^7zMxjf`mkam}iHM z5*tW@gY_-s>!~Znx9zPE$ivan{8=%j(WV75W5>-vh~k#F zcLXGQ4Lb?OXIHMyK zwmLw=<&42AiCpAnyv5X#e)CS>)lFkar92D(k@{j4>Gp=23u|%Fch_Svs}siXYyZwv z%{%cx45yO0b8=Owm=|-=&L!~JM6T7V_EkmCR}!51!9j;H9^TW5NAb4OH-J@1+P-k1GyPPOT9ZkkNdV^RiA0=8Ksej`{i~ zVAP{{-xM)3-Q5%&XyEPA$|mIDw%5wuvx{a$TQAdWKw&fwaIh(fk)&PYzF+=i9iQh{ zv|n*$hD-^J4n|>Kj}Ziw#{&r|Da&ZG4OAyw&zeHhz z&a=K1Pmz^g39tYrU|n#Bs1!aJwb2}8x?T6!km`+pvoy~PZce03r_Act)2Zv3pnXYK zT=@IdmR~kYNwJ|Nr|HLPA^8s@1C|6df${7fIX*=>&J>F5ZA00LRQS;EaOScV*aaT4 z5*?Udp~Z_)>4|jqoU5TriY*|)eI`tbuX=$^nwwt7I>Eh*nkR+y|MXmB^SEhU28 z87i;2hB4va{05A=tp;Xmsx4vXDXkfaMrcT|rl=7_32)Luc3?pgfh+VIN-8e~d=t=P zf7(Q4iDU#}+{B1Qsb;MOtXd8IT#Eb4JdoK=?gSssa6>m9^1T091NW>b8t70{e}1`9 zg-xxh%Rv@pM;<7H1m!?tqp)`lnY5&!KROg{Q!9EJx1#CByMxR5LUur@AhH718Ko5@ z-<&dcJaUXPWZ(j%N6|Dn`F&Zs3@P%>f->lQnC2|&4|`6hKId{vmM+@DeA|B!q&wK3 z@=!%sm&T}DW8J^b=iHGxb!lYZ(fh&id2&{Ssk>m^#`9Y}UuK%b3KT)~@3MB6jv+DP zx9MQw1Bf>{pS`c>H!dc!72PK0R_bRaYMIOY&WrrlZUr6MIqUDo}2F1G_+>{X0hpMJlZ8Jz+Fsks|T{$m6zY@;LIk zG=DB@EL4XJ8`6gPYZ5ZVjidj93PFG8$Hw?^;y{M`>B}K%Zle4dqnmQi%m~X=ZxM(g zeAW$2V|nWBtR^JN^l`A1C*_;25B4^Kgt)O-(Y=Iv7ki*2@wK5?=Mj0JZ>$+>9VqZB z=v}Niatqz3^cEcQJSfQUqAUe|0@DR8xF%f$Adl|&iueD=1q@sB3#rI=snJ<@P&q00 zIL1?27`New-$Vo*&leW=ijGHSgsEeoF^%@Jdm!5T`Vj zli^&)9T00E;6j`?#farJelMf4y4m)~_$w}N&Pp}9?c31Fl_D*^FiDb=jlnEP2CFl} zl~0}cF_kD;PDK>%j~p0+J+&t!xVuGS%9T2G`RluIPNLjqyt8LdWrLBE;&)C9MYy9* zIfl$bas1k4M%DQgOChgAeO+8^c#7oQ1Vxpz8`&%$qK_Mygw3?=Tz9!K*a*~g*SPhW zMD%qg;?GcLVfD!`8Fo}sYKi}5V$+Z`&2jz%s}VG)W0HSQk+X<(MqzbCg(sSV1$#6C zPrA_>o|{X6E%RS7((}Iq=i_awvt;Rc<`*Y|B|)wI;*mQk-;@e?&4Ud%x|n^~Vj$mD zeT)zh!rN^B^uWvQK<)$J7S21gwGRAytq4C%p^m}^UJ_rv91hiraOamhHzr~CVc7oa zq(kaiv?Ap(b9Lq#Q5wjXY(ODYrc0gI7L<&a>ja}2Sg7LOKYxC4<;W>@neTguV;^u7 z2ko{S(tGYhsR8Ct081+oJL#1u3zizSYu@W2WUjm1P%YMuRD-^qo>O}+3W<2T*7p7* zytG6I&S;9oVUOw9jbukKP*Akcsowx8IOef2rcJ$n8LCm-u?RA~IbtYva!!P^rl<>5 z>mzU}QE!vvglkjDOhqMWIc=;3Jl4h;ve~(sY_|3fE6JB~Pb8jmS0bF4@~}I(_xW^j zZQ6v1R7lU9KnvSB?jy+IX1KNuu)Wc+SPv#*@5^5aez*pYA3m_r6$lW%-*E6{spBf7 z)|S~NW0X5mlL9*{x)x~Aku}$@O087yY0q{oA(S+M1;54lWsaFW`YDY zM@z<=O;)@q$#Y_#_$LdO;z8x|q$?)&+*2lfmOA-jRPtGiSTpm@VewtVJ>OlSSdo8O z5vdEyDm%womqSH78s(gZ}YTdCh#j1NY@@FCdp z*dsK;)G6+{+_Q|~a_w?6d^_|KhC8u$Q~kb>eou-!>vHppGcY>6NkO>{LyTe9(UJNyg#}Q`cX|r-kAnfX_ns1Q@${%q>aHuw<1}&q?9;0>4@Fn#=-mH-&9#?6~QvU zVju)&beMZq?9;~Yx(vi-=dHJ)HU6)Kz7TjQ`dXTQhU;VTr+W1MGntbSu%}F+Gxrl^~!7U&%)wsxEwmh zum_K3v>hzQbc!7u6YjhBg1zJrK|+}EQb=T^|F0J-D!z}(;&k6A9Zz7)=+Mgj1`p3a zjH~N?uc&^nm`FJhyFTS@d0RE|lk4gMCCWH?^YtQ&jAeIoXjn=)WccSl7vb(5p`G?D zqy&>DdlCqWinKu^_8O*j$o1T%j9x#(p9pA3h9a#s2=ar|IaEXJx&K86C6Hdn@>est zn-aCeWQlb2fL#wLkX%_G3bVUPmSCavV~DeZb*C>Xn1F&hVa+^4Qm>()nQAPA;8V9bg*}>`dx(+vW+Pgwn*c9I5B(G8ua#DY`>!x48;f|;&0~zD z7!sR~BOW0;u8jpgtRboErN=(fk@?~_`$YyA${TRI1AeY? z4mi|@asi}yhn>m}Kj_bVnakOoG`X;;TWqX_h}tB@Q;S;}$>DD>u<+D$bOvyHh^*f` z#vmt(;|c0>y(j3l_rNhD*gC1P4qvl#m)39|SxK6be=&` zNjSRUUK5k^aU*bGSNP6TlG;Hj#iVc-?0>2rKyDCsM)xx&OsD$dG|gF_Q*1EcdL|UX zLFYIvlS^zP9>!cyyTR8SBWzII#)4m`ARtv?cveOgfFt_y5PB;xV*3t*kqPb zYx`S9qq`_%jvs=3SC?J1g@9(?UQ&{W!^RO`#1(_!^Q=#w`?J?7Mm7(YeaT{QMJjHl zY{_C#W|~BKkFC?gRH7P-&k7z{v{K#qkIjl}-l0XlX+ zx0A_Q>>J>fh%zrwpxpqF0Awj*;^t#f#EuI%ttTRzuY@UDFp+WIQu%)Y%HkJr*K^LE z(-rf(QA{V_XTppZjXHHjv+x5;@B927_it*Qgmpen4_^mmX%cMvY{twso8noSF1o8O zVi2raiNen$2gP`&7%9G%>Vr9cK3jjLO8!EQIAb(+aQ;T6hpNtNw``m@x8_V>h*4IXlHXf) z;+AA(pdbbVxk)2h9ViMj=Z$c5 z84ZdF=Kt*qy!}%TbDHVBD2Yf{Hwcv-8V*1g2TyTAx^m_m*eT9=oY#8JFMhLAs-%ro5qA_dUnbjH@IZJNkIp@>I)`k?@&IbE}B|C-MjRyc! zLYgM&wcO%-dagzaBoCShwPfm^jGnmu50(7SLkY(;)~BJkDWMftKrD#@!iZdO@M)yo z&(N&tWMAEx!cHxzT9MS%O>&IdI_g?w9i(JSM7Z&~e(V<2u9UjV@KQrnhm?mfAZ`5& z9(8sM5Q}nNMJ{W{L5xZ~M~4P~9a-nCBiz81LLqRERfJ6c&J;OhTkx)yO>1cV;^~dTqdHLg82xhC%kQiyS#eN+!{U0TuiM~1Hho{M; z#bQ|@A@lrpS1REEgzWxdGj#|#xbtpnkT5$=-XHRa40Tsp)|&6Kr;;RC|w zzy53+T!j1@#~$*+w1(7cIJoTK3T!s@;-ny!lpsZgAx~65@??~Q7X%~-^j+f<6KFxb zSpRC&OhvD^f?0pk6>4}i*%;%o*MTeao{tt6R-Cc4q%mjcc`!B8)m`XZPuzRE+_GEo zd}3l{N+;&7I=K*9ks`ow$eteWAd^Ek|D6U?CdOSGLcST_a1gB$>On#+aGl9LBv(6% zjyaH(S2l|1;A@@QiviRbnlmTz-)lCb-}~7Y<`1Y!)C z<$&-xd3dQ@NgrXV;VcVOQNj3$xr3mRGUh-?L>tZ{Gi$o10$p*k`M^4ylKB1L{V0}( z?0Sf6VDlk#Et^>VLUY+u(LLb_%;_ArXMIj9q@X28ln|kxJfY&r^7OHBvL(ChrX(3v zZ{Oc3r=k>p#Wr5q)5V8;7l&gS?E(<}bJ^;8tr@3!CGbzE#D+tSJPc(W=Lm@$1j5*7 zk>}DL9qw0uk%cyybLUn$nIM9_p-}J_x=F^HhPyiJ725XK?rSANoq;HoQ+G`L_pRo~ zt=PUOL~igiFSt2s$)uI!u8Dh-|CYEo6^Z;QdpCWeK^wzPfd{ECnm6z4m2W{RSE>wT zVJGh@5B4(u?{F}X*|h*Uf+Gj*!+9ZGR~Dnk#MLH3va*UDNpDix4iX&_R~QgLFp=+ibrv=&H&bXpmGLZ4J0@;wlqBi>~m z_84Ws&%-c#2qk=*jsjr=Q^L7=mR7>A6CZ?J*rcgRyusB`akOvyp8+k;VG5oc6eKzE zKuy*L+7oZdKKMS*B*g$OVwHB3F}UYoqNKv8Mwe7{_uLN5XF~r3u-lrzuD1RPniHQH z^jis<9W$B9k_u@tS5lgx8;`SB4s z1Q&$_y1nDxR;FjgY!*tmwMy_$!0pQmE6%#mkc$j)mbVknm6hq>-_Qg;WgtT}v6r5r z318zsi&x#JBn1mzH|33Ra*{Obr5?aK0>pY~%AxpFMKu%@#UXgg!Od>Xb1eB*vo ziNv0QLjq^JNmUubuh>wDwGU>{o(ZEwc) z4L?_iMBDn`&$bRnoy<@l6^PQjNAG$B_G{jiSMq1C6Lt@gVL+Y{^;r+jE=?x$39Wxb zObd1?3_DhC4KC6I@iHVa5PvRURY^M@8ixGB_`;K|oW=gfdiMb;+-zD#a9xE?687_# znX3PM7@hJQCxi$#@$IZFFK0^Z{RPKA41iy_{V#hk?{gc3@pHcGr&EGXMQmi0H_G=r z)34za+UQwn5UFhR&@N2cuVSp`$!?RaE}Cb}yHF?O6fF{v%$mr;k9ZQtx}8KsbX%w0 z3ZmS`bHPsUceJXqqXFDO#T1N8^3DslE`?>1 zY9gHrUa4a|jzl*9Y3{lRa9P~EF|B{>d*V~>#}g3-t*l`O0p~+KPvo8rzH%;%6c89? zd768iuws_9fnv-F_A{os-=dAB+Fv#9h zbxr+xMp*2RHQULccMv_G;op$(O}@|Cm);2Dk+NK)|K=hRndzOE#jiV?f;m6|$I2w8 zOL)Qz_%GFbRyYN$=6>9C$5$|bJ#J0&p%q*efZSqa!BCa zZ`ss*COl8496frKBJmK0cmU341cuN#38_dk81D?8^8M zO-143YGYzTps(K=A3TI(&fI4}KVEC8B;>gxC#c6sEK81lx|7B^nR% z64|pyc|0$Zn;dhqlz&JxZabj}mA(qS4ef8joH(%n!rOkXCp94h^BNAO_RTaWzbJpA zSeE1ebk%On+mPepD0T4V;eKSfMKGt?X6N}Scdr*f76S^K&q@mhQqMVyuDXKVak|O} z{yJC4Sn1WfyYG^gmOQOnS7;-~t^Szt*1UghJD+eN!--&-to*j&9ae8!3oa%Rx=JN_0G!pi zjDY5=^|**>>=jooU9eS9omYd!l*SU*}1gHQ>gQuZ!vuw~+j)m0X75{?ru40w%2 zP4en=@>TFcJ3UsGYc0QPIbUDTps)l+k3!&@$E7HFiw_HK53eUA;03ZV0t!A)sFbul zogqthkh=tG19tB3W~!+XDN07#Hg z$`0Y7+L$3y$3m#EV#XPxwfHJXNg5*h&8j|50t#``iWw<5973E{744IS)xX1dyO0wd zA4V-D6rTfk0AlP1dYPW9)234t1cH;UgpRS;wAlnta_MV2wv+p;gTw59N(E7F58W3@ z5d)+8n5J*yDNh(2aw|aAAy3t1+zGpCjX{PyY$xwogEOY2f|tge^ZLw`95Y8hTX#|& zD;U?kWr8f#1Zj@eb)FB3aS&o_?)9NjeuC(KjI>jSE48QpdL3pMv>w8L$7vUOGTK@us4~Y{7H<5L&m0#0tN?(Ptr0Rn>t1{o}a z26r9Y-8HyFaCaxc-ARxnxH|-bLs;JZvAgeA+g<1BI$d>F_rK?^>h9}&?RE$iglx5> zolC_4_J+5#>_t}t4w_tC?w$feb4*MIlUUevgH${&rk!$c=+BZ=O%`#&=V20}KyNl> zk$zaEid$@ZLW|HBh=-eMXz{vNDN(aa;-}z=DVNZ$LI%;e1nK@}Et2lS6^7wiBM}II&b)|24~I zo|L~vh*}o%9JwWz&CzEc|ggIQbj7C=GLixV*^b}zDlG9B}j4mk)jdeApZilP=ezxFiL~l@V=TYAhY1u^h zgsFIIzaaCR2KJ-G_c=g*PI$}V(rmoWBT9RqyLcvA4O|X5ya1j$wj-L0Xs$3~sI!7j4m#a6o$U5GZM|4ROn{W4w_*GwJ zr=3(!Hch`ESFp5HxpwcM1nPOvJSv>7V@}FSPwIGlUfTaj}ebUxJ%VY zO)RAVhkc(ngDic6VVt&rdt9Yz-cu=`iJx`L?CPNAmJm+YI45FoRA(nQg%t~%NnPhs zFbdj)%FhZ6^+CM6{7^icnFG|hAK(4&rwo;tolM^t2;=6Caj&Eh$vo zI({-Ux8JBeb&Z~i0J-&Xzi<_wE_1&fzh;dWlkFm17#S)PFutY0uKwid)&0s@l|1=X zaWq;_pyaH-OcEmN!{Hll#-wE1NP6;RbEmqb4+C|4I|Z~j;c+f&I_Jo&xC*!&KS2DV z($W$PLant~)Oh>>g7SSasjRe*Ap8dzKbtiJzcaU*XN%H(eA`}abix5>d#!F?{gGoS zae8i5IZ^Rk`+hm?Ou|`Yn$3?R65o;!N>IIXr8v!Lslh|z6N7HqDhG!`cI zr)U{LU;BQj_F40`%<M!FP=QVoekQ>F=B}IU(r~ES!-yq=B*nrKT2iJ7{_%02Pw|~tLi}par+8A{E=ng~jz`!zv$&}*g)v?kU z{f%~p+M;xk;$i>3C>g_=y1&Yl|KKXmo{zpXH(?_^2}0x*`^wCk^-AT}fb9QK3X@Bm^}wvXvB^*co4 z^l$zEyD&MsKyAR}c$}iP9Sz~#FpUjrOoSf)^Lom}P$4@+hj3)P6LldaW=)VCYq7ge z%fBtzSp}amXgZ;Gy#G@NcrWi0;g04F=dP~0?R+M^EHV5Wlp>knTvI{!zLFH=vQJs1 z>a+NGE4G`-`t6&c#iqbXO7BL1NH;-}0vguF^qg*+Hy2wL#9sM&j-5Su&Xf5JQCi`J z3EWDGH2eKSZfhX*cs%u@Hh&iT+vSdCw(~Z1(_IHwmJ5arNpqy;#NQ9V>b>NP)s z;fiYRw;Tm3YNW%T85CFEfAvsvu5RKIKy2~1!3_=w(lI1xrYaF8hT;m}$}5tnH;9=c z1WQfm>!o+oJ;vh#iRC5*igzXQlLfa+!h{+HSM{uPVF^f;r4V@4^M zME>fmV7IqyU}V;W$PznY>)vFZE)Bhwg>t{7%O&hcBw|-Sd54eh;T}UAy&cnek{@C) zrt&@Nq(Q4m@1*Rps=PVmCp&S&P8bVXic&WepaPq9@t={y39qt=DXX1@31#zmuD@ogq2SmlY0p~VjK0sh=dy(m9d8n889xp_GISo+{(#1 zEG8&*d+aa15EwElA6@1j>4kVW4UukyUMl=$ohwJ zLd06Xn0Ng7(+dF4U#xCqff|h{vuIAA> z&lcpYv1ihfcy!W))*qyjjdiiiIwRV?I`LM!I)@e2r>mRpWS%7@6}335ByDe62!nGl z9o;$BViQKOTg|)=`FE86TpV#_8}TPeXpfvh0;egWs$>b;SE=CjqkkBv_k%yU57jV~ z$c#m&N$J+OQjOzTa8=4XH4ddw#DVhcwq$A)-Gawc>9V7c(GM9aVS$oKiBoldP+)N} z+{_bV2oF_X3Xf+Ce0FSd_ROXVip`xuBSint7{Oa!N9bT0R_Ps_B#o;5WCW)*}p zr7GAF%@joczAH%#gfyAk7PysGbaBnTqdAN_T8rY8HR{s%gYcc@64f1F7Xh2^YZ8mr zly==}pZH@F`KpWe$sUYr^4&nyuSra_@sUaNwTyKx2Arpt8`2XiUf!I+N+<<|D2(rs z5JVC3OC^fNw>_0-DDZC|o^Qh>4<$^_u!gHe0aE}CZ5}rwE>2p#KS{MIgKML8yJD^> z$YZZh>Y=@t;KYJgSP*AcuMi8^IEME{qng@2yeXnQkQb>gT&yy_F&Np7%3l}pG6&`) zdb{+DG!zxA_}TC>`vFrnO+DNZ8y{qOA@gDUeU?#WZG;{2!fcPo*}!XUIFuV72<}Rt z9d4-|Jk{9Am7x1`luy(#q$pmqJvZ zF~e^{^0_YsVEJE{tyL+SlIMa#sTR0z(!-}J2xkRtBq{IP^1qSO#^`#eH|}E+A})%> zH=b{9@cDbXHE2}vT`71WM#?M-=eL<^Q*dw?Z32JXp?>dqZKU1N!u#PyZJkHU3ReDB zK0ZA^;cC0B!LrbVqepts@v|7q&>8XT)fKnV)jUnEot$M@<5P=JAb_-?5zwL(0Uw&b z>za9d!^Eq*qpkPM&yCjPz^l&O$n9SskyDO1%B_k}NA_(G&B)bK{s@D{tdJtQYUZq5@9s{YNP+y zVXPPXieT9_qq#NK5BNZ+%<60%&QLnkEb|rldZ@bxdZ`s6yN8f!x|V$U zS5VYIvVzbj%YNN0>5q6XPDrhvWJ%F#I2#RKp|Ex&Hc~LIz%q%KFtu~nlv*`BqbUInEerVdd0?CUyW<8SL|`Ul^5erR zlC|btE@PWj&zGM|3u_1SPe<1n5lwLbkm@Pjdp$q!h*BHd#A*!HAIYG{KB95f8h1Ub z?=oE_ZRgX}VG2ur*A#tHevnNk%fZ*;<^&}bgGPYh+eu*Sy50IFjrY$6)4PFduzE?& zUZ-<>#R#6Q8*@9qzIU}R{ohU7peKh?g~&Fo0H{KxRev)lg6bN9B%=p^#>H+2V<<3m zA-P7-l$EMbtXVOvuY5ztD=qN>leEY^ba~zukv_OUt4u$h=rLvP>s9JP7odj2vV`Vy z&`M;!OFg%RaY`T%#76Sx&49k9=PJGdfj)dltv7&&UCVU9YcLGM55a}okLGYKr@f~G z>ZFwUw`K;Aji+l|)9HcKVp)E`c2m^ZnzP~`h)%KT;4Go~Q!&FEFa2gT6$G3d$JNG)Cj`&D@PN5-wmZ%M1HHkLY(+Bnm+Gli*U(hysj8EU}`oy zI$FkH=qlaK@eVl(zXJ%*i1$Cnqf~Xl3>c;?z^`f}BEqb9WT$7;eFeXH74?XLdWd%M zv(*WkQqc{xB<~OPy&=B)7_q-%2and!Bcui1*mugK(~x5RN}s+3L*`{axj)v>4hFbK4Z_jU&j9 z1Y2ez^XIcRu@h-X7enb}o@Of|k}FVM@faeCSu3Oy5wRp#zei~W48%u7063WQ38O60 z))PJsCwWkLgQE8)yL{Wl7VCA{1eljhqG{t#1>HSwa^PRRr@rh>Mcm^1YK{7+<+LAW zXiiu4pjU_%CNN|MExt1S2V)q&CBt+itF8e$9faVx5@9(>F3(!dq9T z*NQ}(7Tw6EfNy-Z#K84Lf8t1&F`7Y}pZdCRHjr*9{%xnn7Y zzB8pxz@=JGr6ImvVGpquwfrda9&H4Wc=(fY(e>LvK#VyuE&T}YlX$lTc~@pVm|+$i zB+-~G9obbXzDpCjFb&E3P$uU z0l70w=lnJ{c1f67&1*B|{SZ-~B~0mIKbevTj{;%50BM8hoZc`#lBfAytshjL%i1e#1k6lZ7Ir%!5i!KF)COdD(s!^( zBJ91mnohANJ<~#`s+LJ1gB3L)t!AEQ=p=BbcJ}axV44nBRLtE%Dko!DF3v*hS!h?P z?Ygm0B#Ba=VeplxVI-fe1m(d`HzohA z3OP=lqqlaB9h`(f{!&B3N|w&nMNO!02g?a712lDrpd-In0~gjq80BZD?&iul`<2goSgCRezPYhW9Y~KD)=y2zAPkGB$x)>O(HSk@vud@ z#i_Oe3rE6;x+ZyARqUJ@i8(3?d*QaIxN2%_Mwh3!I-QFJ1(hUMSpuI=E5yn=FUTyH zoRM_g)&i!o+_oxywE(kP1RjfOzFbjzdy2V>y?)40k;S~V0&Dc;9FZsom}tE`BA&P& zWt%{zqjfnz>2|ya^M2;%kr!`p&?0>P&G-PwkkUdvA%u*(suH8%dbq{<m-`L88MD+684UZu{J7Qf(8(188NEq&w2^xX{ZHCuqYF8xukmQIMj714Mu& zj2o|q(FhzbNum&LY$2L5i3Wx)FFT5fCS*e3&I)msGNq=gEamyNXM(I81VS8R%Z~*H zQeh$@D+Dp$aXV}Eo*y{HFhSGz$$F(7sOG=OU)|8;2!&6C`V~#z=$asv-^>R+J&gGZ zk2MszCCX&qM!16Q3Pk%4)4R~YT`#|mz#S`8pFD(@&-_AgIMW@R6 zZL%Fxd`vJV)X3VeOr6$6CZHhFk%AEpfAK^@!+ZC~g)qv1=Ou#zk_jOO>EH`= zOI5iJ8o+~HqW(eE+~TLu6^q09ve6v8Qyv~!MU9KM#@9x-=q5YU;EF{mVl(?ErP*@D zmH+3pUhuB|ui4vq8@08S*r95&3bw3D93{$X185(z?{3n;tqw5viHm#FlxS4alN%gp zq13AepP5tG|G^_fdUZhTh9$02I;rA41ZTNsnUIcLKtjgLHT$Mw5&fwY>4S87zW^X> zR~LElwchwLyQnh5kH#Y2_!w$(J|h;U3`yWzw_J->Kru^GVChF@7@;JdN?d=5 z)9{>87AZ+pVz0~Rc2ny1LHMhpaQFzrx0ws{7%7C;6o_s#5Wx_><38jGJ^Y1j;%}Fs ze{WB2=+g#5407edh618a-K##k;(Gyg1Y~}A6K3?%&%NOt!CWE+(G}jD(6YspmZG&w zhk1|C;D~gHK$Je|Z>!VZufn;%7aDE5po6Kd)O>;cViw%zXN~e*X~d+$Y2K_YjQ5Sj zrq5Pc2R4$tefMj{`x8F&qUG6R*bt**0s^Gc0!FXxg3GerL{pQGjE8Ak#uFH>ikkrM-3;Rej{47sK{)~7oujn4ZATL z8_~9}&~^1u$BjfXE}x~RGUw@4iCw>@2gl##sd=OhsK54+agpDH-kp4veohUKr7~^2 zSlzBWA1@F;tIqZJ8k2keDCGbCGl*7_Wc*tJ51N=Df*3!hoiSi+#M5+|DFGx{Ec2Ae zx2TEk!E7NH$*94{xqN6VDU%y-eJ$^!FCJOM`Sn z_3fbOUW&{*esX*IbW8!!2C``440P~vj&NiT>6u?$I9d9su}{VM7A&-1?R~wvX|@%m5T*l%;E=J_e~OA|Mh12w!GU0l)Z1^?D{|PXb=D z=9j>FiGMdcBYP`zGq?+gAb|h?0JQ)B01W^D0BvDzX=Y_}bS`RhZ*Gl^ zK@P$o5Jm4YYpDfETe|86Jb`gRVX7Dk21XOp^zP2ewY&e5_wqJ)W2qr07(v1TZkVuG z%7y>rGsR34@c3KeQ774S&52q2qWgbf3acfKR2VNC1kX;7+6=}R(V|;~R-G2JY8NqB zr`)W3ucTr18SUqsJ+hHIALQlV`4I7H!?9fE^2dc zZtQ)_k{vga<*&4Hol3j!hqhgtS@oipW3`~Es4jN1M48B$nl_pKea`U*;0PdYAZ|t^ zGsU#B5|I&c5dpyAa6kU~{oVU7Up{>O^6tm~{rkI*e}DJmyZ!dv!@E!K|L4PRcJUWn z-ESV=ef^(zKOP?5{rdj555IhU_v7yR@b16y$nSqVy!-g;yC3nyXZ*9@>>hUy@4ny( zT>0{k_rHG7e)#iuzx{;H@f2Pw_x~HW_S?tvasP0Byq=DKLubDgw>P-Lw}c;@_K(NS z>0x_(yzc+@#~%;Y_s^fu_fO@cn+N=loqjH^Z#SDi{=j7$9f!g$_F;4v8{P10f7tFH zcjqH}9Upk^8QoaV&EB?$iH`ImWnGS~bwS7MA3sfBe)f0aHO+VZ>)nrMeAhoP52qVz z_uGe`|CbR&8qXdCFrQz7NZyG{ANEo4!vLi|^e&UeU+IEi6-cbHCZj2bTA4 zO<*4hZZD79?T!?6*qpj(aDRL}U(XM_>*MxvS%wHPj|-8??$98WEtX}lbX#^kcME^{ z2Rcs#rXTk^hy3-o|MLO;;7N}7Zx1*Bi?#c|d=iWOaCto8D&Kj0yjW`|t?lDBwDj)w zaWB6>517xccm0vqXV%w09{BGgC!T-*pcnX0F#@on&Er`tl2cyH-Q$_7L^?a*#`W=PEnDGZ**re(?0#-31z+)7rPd3mm8;2?K85~6 z>+*P%U)YN?d04Mu*dKDqXT|_7K&gi5z{d?&%!$(<~)!#*au`CYbihEdgoTj zSkgFzG;UD_9^oh5q@Jaz#w3Uys=<_R&b?$~$7duPNH^>9ATR^n$3_|aSlw}4Kcgr- zw#Et>k#NicnsH;v~V$Qbg-6lrLE8jTbZs-@;85_E$}7zuKZ-dWAb;T z@6^u>d%;dIA6XhW?r`Mx_yp7VmfSIO>nu`d9}muAk$jwBrQIdTY7TwZf@;`jpTn1 zO6=rccFs|@^OpAIz4LvfvGk4k1dL-e>a@eoX>P`Um5^`T=LT7xdb0vJNxk6iz1(hB z3-i0Rg?ZiIdB2bFE|5dwUT5b!q?VEs`D2+Ewfi0CEc3oSFyzG6;uhftRg9HeKv?T3 zT;Wsx)vX@$`xd7ru5l+dL0Q^U^zEXiT7KWHE5G}GEO)i5KX#}Jx3s4SxJ2g1OGZ#> z0pvU~@l5rntXUn|)}z{fN-`^C=z%5>sNpI=mbhZshPx{WCslWV0WyZW_9GZgxThL>lz>{T1<5gnYi4P1yp4YdLau;Dj!q-(upNT zARAJ6kY3?44fQH^7+?7$u}Ko zfhu|M*O@P65i^4cwV;~ym}U9YxN6wJj%qZv0%KbcqXELQ6u-awe>_pC^uI$_((;ey z9hnEY!A;?^=o{ZplfpFie9YMM&J+Q@iqkvtsx%_JieHCU5rv<86+qK4*yFA-*kdhq9q*C4 znh-Q(=EEE-2%zV~Wl1XthceiAhcW45o)v`MECg*IPpx$^Od(i74vA&lpu_`y*J}j< zLFAdLA*%eoc~%gz3&XuXtpVhp*XR8q@#nSAY)Dz@Y+U5fPJ8m3 z9on3{g--3`wZ$-PpUpV6`4b+cI8mp0pinU4_T?G zS$}@tj5GTP+s%mQLb&y8XZ8*#0|aVN)P8^MBEcg*1fL1|)6JKJ_|+`FlWQ4#u^%ZEwu(eU z3K?+56Hb&SfgXTV_nM7Pwb=+l^V(RcL7R7DrH(K*u~NnJ92T9#N;96A%}YeZl~~>J zMak9-mO{KRd-GqzNl%7|o`8`$jZ_$ELP*^a$KJx7qeBAjrF$UZqfm+U8};cnI;w_o zx5o9LqjBz^ijZdO@6*vypQ{1zSeld7(xwaG3KIhDMm zvda+I)J2k&RfJSDB=;3dmd)V116!inVC?q+7)>S{Tc`3H^6qJl_vw78HVBULC5V@o zW3LhCT!T~R=kV`Khl(z2m`R)0z=6h;;cW3>GkMD>vW>;gt)tnY$wrcuI@zOjTc1N~ z#51NezDH6V^3OH3Zmv%^E#Qpm7T(XbK@SJqo5b`cG2NoZ8pIi;MraQwprD=9Si_~~ z)jj%5WJn@UJdDHCAI(Hd*IjTGGx)+A(`Gtf<8ygA+Wn6E?k<2BmQ1pn*{#XHYG1x_ zia9-=PrW{%=UU@CukOr;>5Z1sw9N|tT6gBl$5{{_m6aIh8*zwHYd`n5w$!7<*;ep7 zNuC30zE)=%J^X6USUJ-qu{29u15Zyo1mj_+gVR|kME+GA`?#Xr)C0;scS}OGipF@C z=aYmA&xi8AX=POPYI*&QZ1}VJ>`^Ytq`?l@O3uT^1)N~GloX8B$J}Em=1EI7mT>M= z4h?py)~Drqyk~|S4cqDgE(x8$XDvrxp3Ai^k5B%#k}Vr{uY%u1NSN z`oviv4Ex23SzH5F(OMcY!{4dzuwOd}e}P~NPQ&-}x7y-em$m4#&Q^L!CSU)m>~$YU zk-``TGCUZpkvnHqZ^6lU71FsOI`?3TCLqV3yMVm5`4n!55{v(}1w&XT7sISc z5?ZWl$H5&a{`snI{SR61?9-gDq|cK_)sAzpC~+rlH2i((Q_|U=7E}DQZ3?9q-8(0o zQOF38r+K4TBake+e$)?;=h5cMp`R|HLf(mvj0b|dG-M0!~l5 z03Ti_1#q{B)r3=94%?VGsKPb{DiE!YGVy#?{;&wL`~wfIG|D$YkuR|R<>~Y=I?t9k z=~})cFq!RrD`^Qtdb~wc|kR@A>pKtJQ4UozJB7%~Yz#)(vG^>Dw;KJH=M!Srs^D`9S;Xu%CRs(m>1U$}>ZU9RtWu zj$x%|q+!9%Ocb0wD6)zwM<)JZ9PLI`VhC`2L{)2j(i-=rL20hl_g%N4gt2U7Zm+bvMf2kCXL7^FP1;^riOiNF?Zx zZ}WI6gto68B=QLlV2M8cm;Ce3PnxB%9*LNC;@ENC9DBwe6ZX{>?r~B>iWA6QTO1BJ znfpksl?HO{JTlAj5UfdJBFa1b+RJ7ljf5LFmdvFBsy>%jr_$cC(X$;AcrrXBeKAS1aJ)w zwq8+`LEl4?+)wLKPX%{WlPt(G*$K@kHFP9b8|k- z$cZs2(!p6RGd#MtzZ%BP=NuxLkpT2+wFWvl0247VgOZWjX}Ru5C~VoJ)g?)3!}=*0 zR1PDuQ@4%GR+6pJ4nq^UrYuAbzMqd#x<0W1zI^E!F#D-V*OiY zyc-b220`!$$vhxSRM+}9B(;{$Qff zpZ~_#Gz>@6N7lrXLfEV5^c2I!U#AFn>&~7P5uzOX6OC2UqX|zbb8GblIWjlL;O8)V z%{pqq0lwZ@KEd4%3Ny(iEE zMnCBxE|Df0UoOUGO=O{MVd#>hRr93tZ1<+##XtH33bNLZ^?e(Mq#hPZf)seWb3 z7J^}jt0{9PSUWwjK$z)l+MT0H;G5}M+DW$!E#k1Q7IAwafVvik75z?yK}pF8Z58x% ztIvtGAnOvf@_Oiy6*w(3^tltj3<$y-sJMMA(UAX{LT*i2!B1=bQ$n7K?bbTqHAxM^ zz>-f)jV=ne!>1c*YE?JLyNkn2;%*p=2wj`_iyRrVRn z3mHGmJ2&b0<>I=%3-DFmLfU$Z;y?pva+;(q7woCi*G) z`nYCZ* zJ>pd}`!DFMk;L-UDt@?m*n6bjjg^r#L6Sjn4}!UR(wj7&@9iW2j2r6;+uI(Sfou?F zeg0zL-b5#abe-Kv%uX!ZRY!TFZfAj#n-pzO@1@ zFWkEV*=1{)^9hbQ>hD?}P}^OjssvQw<7C*icy1A-CKhl@6Nx8CvvNb7kAE%Kw6R%e zmDV@_-NrOP(f%f$X^Ssn(-RG49z=8&0rzqg3Fdxpw7I@$p7SEhVo#xf=OOz(!OYW7 zWWlU4GE5)eNp8i=`qSJB0$9$eKf!7kTihonpEoTz*>jY#zm`mC89b_Ttq%yuH%`1G zki)_C>7e5fA% z>*t@p{_^3=m%87R%&wA}E*7ax7OaQhK=+B@rnF9IP`!HRZqqvCb{>yWRO?)dyrDLn zVb$rcL4gV<2iTRDD?%Y-83<3iQP5*v84BrVq2dC&ZHwFOJO@J9g1ap64q0DF>ca$v zy`?Bf8DUU$v_*L33>g~`nv2ReZarTGDdemLNJS@@&Jt34*f9|2i+r+6)sT{jT!><} z*H-nMttVwFN=L8mboN#|8m;fEc67tmb{T`JftBr12(Q!P>E(S25?C>ZHbosT1`mpQCPhK3}r;TFjJ6D$um2^bOTe4(6{=e?!{* z{2HICPpz`o@(g-PqTZG?;Ld3^r3N25oUb09BIU<5+Zyw@>dEXy&)Kq))WYuJJuccC29Q9ekgY*8ktVA3JSv~WH0!JJ__l+17RnBTVoO*K5&#%YSFVmOC= zG}X{a;Lh_bS?@zKoVYWK`afBkYq%YH#apl4qQ|b+tz!QA+)_TnyXGAYj$_(D!G!`p zYS#d2RDX(9fNrS?3sc1$F&}~|jE}uU(U9_)z4+Ojfh;k1kS<2cAo~vW0zfp)0!OfG zvx+3=_nB0-jJJAGJ}TD{i=)A(+6QZka$+8YDj8H_hoK<3w|VY>GYRdMX3(WIHoTjd z-u^i|i(E9Lqo}yxNt=oIqWe)hPt9A2QyzY8USsfycYM0*{+HR1mz65%dH4 zM{pS!9Tx=j8$r7}`X(&_=zHA$5`g}`1<&q0oG}9WDKo%LKwoLS56}l?ghAB@ZFuDz zKp$trNO|dS>-hkE$j$`xae5&|UZ3d{&Yl4D5vhQ5am!HSlxxilifL9j*fp|W?N-iy zRq3(muV#FmX+MM7P>Q;zl22?p6i@WZm2`NKTPq_Fx#cBWtjDa155UeO8OJIG&jN(Y zS`7ISQ_+o8n(Kv-c8%;$vArmS{^Ra@SY$++RzK<*YZeE1C&tfFd%SGqN>|{B%`sl_VZO5@t9cBq7U5 z7+q5yCyOXmz0mZEuF(GyG~sc|b3lqAIzK}6fr+dRSjb{_lMZBuD_qliX{X^Tvv#7f zH-`MikY55rZg^3R?kZ@9u=DnAsyb^gW%QNBTTggVAzTeJt~0v2mbjH6jMgZla803c zGPsx?+uG8tQ0^^W19)uDX@U*@R$IKAOFnxU!ht-TziME74weoxQAcdh6FeB3j-?1& zb)pv_qdMzeCZir|@f^=Z2UTRyN+2IM=5iQcP^P~b#wT;PP&vZgp%sR=^Q0a#3K9~@ z?Tr~D%o4Qm93RwMkr2Vr^0FS+Tx#fX#HXghj=WA4M}w_wA&**Q;hX1Cix@*7b_)V< z9LsPIjuxYx3BZMFqfdrY&P{qGjy43~azWEuR0(S82H-#$c~IwuBA;J52Y^EYgsD5v z2fx9^5~M&8y4Rl;G7lV00D&y!PCHdibq=|lwoUfc08dxW`SH~MW;Ib<1g#(=1Q7L& zO}ZmY)Y)T}61W%zlMUMyK>k)$&D!hLEu-Q#GiLF8!blbsJ{k!}B+RMpu?iWhyNdR% zk!@tRa<-Az?CsSBYjgt%}1#bvfW-1zV=aL?cTRLuI=9U<}&)tT}EY*`)LY7 zCgk;Anrg`1Op)|mpN@{fk6FuK)#*4#8b52ou1*Z0A&eiNC8hV9W9iFtES04nCA1!T z@&v3!2NmA666Op8k>`h60(8y*l05KDFz1k^^~sp?x#)B9eBz(s(SdR(2 zse=@m(iKuCK0P_c0!DVz z5D`J#HViZjIpMWFftNvG^3~jf>FU`}LYzhwjn1mSI+zF=Exl18gScd_r79Q`-F6eX zx8$z8H9t?#K%G?Rej!45a>$_5sViQJZR1|{WsN#wa=FRAr8ZTukiPrW3>;RopH2o= zqd$+-cQ5@+%Dn3kBQv1V3UNR6 zp6b~UmX zFJgCkk^McAG1k<$zM=6=F_tTDim?z|H*G`gIClpZ?LE_LLEGyZJl{C&E9bPe33Z$r z5p~kdXPH;OqQ&R1puQR3pT+nti`h*%n1XXR8}pPdg}lFVJ>|Fb!{1%{VWFu}3hp{@ zYdj9R;xoZ%nCWDPUjR-Es_{32(`51%GVAYm=O%m+5U$=(GBu!f!D$3d0)d&RHz$-# z%eQrz^{H>i5g%HH<9(xM_5QA!)lE1JCm8^VemLy_cOJl53&LrQs>yp+5`JUF%?;ozk>l=SqVD@tU!$>16& zZVe45AE@~Bpsul$;6E5(1q(*HKm*hq_X<8BI3k%$84jZQqz8tug{s$P9o4XTS463% z={t935>x}L>IKPwD*CQ!m6B0RyOnIx4uTX$!~k&Q8Pr5p;g)`a6b#5xQm!N*lWS4> z$q4Dn0E_e6kMh)J;KMbM3TL_36zgelvlgO$@1+GcYrDQ6dqa%4$bN;-WO1|EVSMEh z24tWAfo`SuwKhVi$e{TRIO|woLB2=`3T6pl;a<7cB-L5waQk(zv8VbEjqGR{nQGd~ zpDqW7jD?w{RAQ`iFnnx3+PbgP-RzlM^37S}%~|8m?W`eW-o2}E;2>3B@20AgL+qJM z_65X~=h&l^w2@8q=|}Op&~nr(w)8I7Ft?r%6Ta|*);|1sLA%zifj2PQ$aBC2Cx}H$ zW|t14|F?q+JXOmQaKW*a>0|Hlw=>`ZR=n&kzz(G_C=c^9&(N2oH-|J8ia6qP)4v0S zk1OWFAuR(Jz?=n)XNLC;PAB|eLAbyRlEzKQFb+ndaxb=MAHxSc740F71@F-$fmh`^yOhQXg%&7@@HX<4K zD@QV_Zrfuvi4oE~@9_^eTNeLBd-8gBTRvMD+d>{1H>gpo%q{R65hI}Hn~JSA<X)lsuoT!yo znrScM0+poKNPE%lcOlC97Id`^RWR?! z8K=mJRM`h&eN(!G0Z2UTH$w+)Sf|u*0wWW&4ICHx0On#qm$W34U~?BQnlKy6>L_6X zMc4SNh<+3sO4-J4#H+Jui+6$!8nq7w}yaEz<$T}Y3SH@l_Q_EeU29hw%ywY?v1;bF9>6Gb-$?V zSlB#DjlO$yo7wi^t+angqJs?tPGeZ?BNi4%gJqb9I{~~zy^W|t#fd=KfP)M(f=4KV z?qrieNrRy~LPQ831zzf3mo`zcaR%+YhhEthYTy~8TZmJMiNg-Uu={pULy^3zc6-+j z0>gy*4DNZtfzq*qSUsE0h=&Wx!oKhw1d!fR8reR@`PQ)}!5ehj8{9)Xk>bF_koQRQ_#E2N!FfVUo zAZ;e&S4hQkG*rOp@aF{;AL-T5Ma8v>N}rq6L>Z=F0A^3B>=I>Ye}liPLP0N@iYZ&z zVIMqLa|U&gPHm`o$)qQAFhd5|LMWp!z3*k9wGw)`D>Y276b&YU{lDpx0bm7z8UfSW z>E$y}h^bm-Qb^2esE1q!uaETRXmB7s^jXBU4$78QGUSjV6H%5$K`gizubGR`yB2{ z)Y2(9ZXnoFA?-6)F!Q!V!<}C~DvTo+A#mJZ(YJs=*TKwUCOEz-);C9O0b7AufT-6) zAM$%>WM(@tJzVSf+>?dE$pcL6cJbkd`$O9B%eH?utqIfdxGF2ZXi zV;Lnp*1aZtd%AS$xNyL!32!w;1FHaEE`+Xh6CPkm=Fg*I^1=xZd4>pX2do{0Cq8X9$oK2c%>z z6AL(*OjV&}x@aEh1cHAgqo3tN(4Si)AjyryP-?`%E{Wd~Li%U8X-4w7>8B~vKV!i! z@X-dQLGh()!5gA|%I>_{f{U5#Fiagly)2|Lv&8$pceJc3QIzyM|EBMCR)* zyQWrYEqh+ilY-t*Q0uMErSPq;OAWg=5LzVx7Ft*HD5Fsh=2#ZS# zr#vvdS44R%N?TGMEIF^3^5#g_S2!rDn`bB8HH2#h(yT>yJLFrKLw77(@LK4O2dbH8 z+~<_hB(Ik4X1e-7WyMk3=f!{UL^B25t?B3k85A;GpScjOYCvsK83t1M%Obl*wE%bA zaZ01fI_C1rP&yKyi7uiD17-wppW*`XqQ=nslYwT(x-UQCh12vL-32raNElG!x$_YB zw11JPJMvlG&rBt!UZ>j+)|6qvmsjBRLx13b+QKUW8NEtY+R9TlB|K7PhT~`-;WhLY zrnOy%@DO%~6h_Rq*_9I*Y6}i=q!pCGyllctMS%>~)sWGmXvCn3P)gC;1b&mZkg``e z2z%aAP0zZ)jwJE}6r6h#Ets9H#j+TfJIh$9A^Y^IFTCed9*B_TRx+qYP+GwNCQ(g% zTfxHc%`bZU%+bBX=p!j&fxGtYo`&wlG^=av9_9>q}SGW6tddil;H$snSM zQ!Q6A_fs8VXf;@r29bKzu5c^p^Ei1KI5K4RgKVRr?-xzObF?^=0)ym18U{w(N5c(0 zj#*9DlBbV=wJCt~(J=CcBk@1j*h`bA8x#z`PjJsN5|+t21 z%L~sY=Y?>daW-aHQcf&(eod?fj0~mXR3ZkASD7>@E?Z3zI+wo+lAWWN!8C!0L}Ws{ zkS4lFwxO6o6xA5gh_L*(=H-FftIQ zp^;Y|;>jXjTZZ-!jr3YZSzcn!gcK30XPIO-@Tt-Xm8sGur^;qjb&R4gGr=c|6IcI3 zT@6aXsf3d!01cD-qB+JKHJA<(lw~)){Gy=*vmD&2E@O1UGWMMkSA^n2g&mp(LZlNi z5W_qGi)*QtHZDcm%ShMd2Q2OB<)!p`VQXgo!oJ(|3eU%e0(n^5#g7D){rf~Q3c#)x zmDV)7gGxGs|N6Q@c445rU{~DkY$4BuJjZfXUX4sF-?mvbnFIh{uji6*Vcv;7YO9nL zyi8dhhp>e~-5{#xRVu89AdCYd?f7NA;q=`+`{DkvQk(@?iqQDoJ6 z>>h8flp$W5JQE}1=OiJaW;oX*p`WTBwm-qlJewL8i-`V7t6tl)gC$PyweID;^4h$b z%dVZ5X6c2C#5T(GV_hrPP(O|<=jG0253SH*CH%+{YX_$}@VmuFvRA7>lZyjNQl!vH ztK5088Re@Y>6joOU!~1ltBWv?pXGz{fvy;f0jEOJDKD8wB*mS)hCf)bm1|^E^LMju zI%F#{8>y>)Q86n@VHh(LG_mQ$^wAB(B;iJa{{jXX7LgmzTW4f1Hd;(5wll(i+5 zY;?t%R_k8$5U+E3tvf^QtVt2T)50Y=Zcw0mP`q&RfJdYx=^PnIrfa3h{u|x!U7Nb0 zpuy*9%}wn>{p|$~Wz=I4)Z$k3sOJtZrGRp$>*Mv>=0jE)Oj&k43kWU*a5v=A^bSyI z$Ogp$YzZqQpw&)E_FA}2leKG$*;_R98D3(>b zllynPdJ zWxIMPT79*;io}{G1B9Ld;vR12ksC0Q3>!dUXN^OtSgK;Q_GtV*ElE23z7>{#p6zXa z!EubeiP(&;^=}lRI;>oTs+d$kc5du3%0L;*$j4eo&7To1YXgZw(Iu$`?FtkoP3ypd zj+CR(l>kjX0EvK2lGmBCk=Ce2ooV)%_MW>la8I-(un z8j&vT$dz}>=PDcM_v*jnatUX0ltZdWQBS0ov0k<~2Q(Bpp2UIvKr`?pmCsD1CZSUo z=s;ZwE!k7myNegKGRZV;(4{-UBCkPIB)Gpvc4_A5AkbZd$OoLZ=UpSR2NnS@&@sL` zgxeXpAtEF*Xicn+49DiLed-_@@zz|$(iJCs(Xey{@qC}dSghkE&R!dRAJVf|kD4e5 z;u8lvls>;KPTErjk_ABGq@Fj8N!@ugHGb%XxxI|mK`BQyT{Q9xUCYbTjNa)k8Cfsg z9^4g^k&3g>2c@@o>u$Tx#aVW4ux!u6j1jXQ((M~h81DuLOQ=Od2lL)qG`j=HAr057 zf7gyd`G4IG(?R$cA`(05D)l+179 z*0T6QHvJ%&_nkaKAoGicW8CixG1n6UL^RNyo<;-DL;QVe6so`v)Trjzcoxvd3rvT2 z<}}lR!jw--_H>i!uo`Bcc8j8r4eb`8>OP7Q-AnfVP<+B6tuL10shGiot7CYFJiLSJ z1B)@j1MwHsd4)>>0hk^(aDklwmOSE;PhbQECu~;zJcO#BnNq4kt@f@TSi{EV_`}a> z)D$b?pAYYT`6u4^*MGeK`{#fC+rNMQ^qJcdSmGcPhGbDn|IOpX6Vkzd{QCZux;yCJpd*x@_ zhZYy?LkkqS9Que${G2&W9t@@TzFvvhd)=^4Ms2DDEI zyTgBx(VA^fIs&S?eSS3x1s+%sb;L{Yp!t|PE1gMC!`@SA)mn?`^zZk|JjKqMHs(Lc zB3PQ%!e0aP>a^WA6Xb|NDHf#9W$0ZfhAyV)Fd}Of=5gXvO|uV=AAa^ z$sJN_;!Hd=c5X=BkG^922QSW35b`||@hn1?Ol+x=Lg9d*m+2Fd9rDEa55X$=ako!1 zb-sF!N-^nJJY-K=P)|>29`M{yM-W`Mwml<-faym|JEM{`t}~j%p9cubHX{$bEzfAa z0D2D>Kb6;J8f2pDf(U7|l%$t=km`S?j;nC$ET0!wQ&djOqvTx-+%1)BP+VQhf1KhN zH;}9lQxwOP>qCk=5}jVvt29ls`xr9GaB}X&+((BN4-Z9oA5455Mu7wya0xOJB9m&6 z0p0nW`WP=E-lw1@Qlhl&8S_vD&JDjH^-z`W(GEd&R!JTIGSOeL{wQ2Hpcf(~QaytH zl0!~+p9De+xCL2AEi(3;tMbWY!lNY32rHQ7&4cTCH)yI~oiOWi9TFCr>L+3D_kI%2 zXhJ4oJhrY}ZD~aO@XpS*mZ)0SLY&+6WEIjf*D<TaShLj~) z!dhQKfyZY+A|yd~IvPb+Pv!IFjQ8B{IGHJAHr(jKIVWjmQBv0`o8y?)RpgOpG9`Vk zRN!qhahzU4`MBz#?Tk5I^2V-k7$_ybPcFm7s=5zBF zf7|j`%x@%Dn^?yAgR`i+=<6LvqzTaUn`Inf6biZNXsawexxX^RVil^prKEHzzqQvm zUOYy&@XJSD=1#h8l!`juRVr$pUfq^hMz9OZXcvmkJJ91WPl9#`s(OfogFGm&5JXFF zsavr36$JkgDCPzhwIZY5=P62$_kscy!jZO|!aOjGHnh!@|AQYE#Hs>^k&O8~ zC@n=mRFg@RqNSpomFnCX3`Z^?A@gwnk+NqqIlw$sPt<)81bkVvG;>S`A!SMeOndMt z;wNw#(+a>{JIy+bRk3Zrsr@zXU0EJxa^t;$FfQmHMxWC7HzAwZ0z#*wx?&PBHdHjbiF0A+MXo1}^gLU&54 z!dlwJbi!WoaKUGmSQ}NeZcrD~Blkk;{D_*m)=rG^b^yE`0DravpbqLA-=a{r=pxv+ zLmSo3jw@F?6G^vFN< zn%Y~lg38}&OYYiU%+E)0zEp?JhGNKD%9-OC7>dwu8Jy08jlv52uSiFA*j%QgE{5K+ zB#fzvduAQ!24}s{QKUqcWP3JvWBz|b)kQ%sRPF#CjnGf^Evd5f98hrf_7Y)3Ghq6IXE~+EO4(Nqn8VDNQ}Pu~=WH;y1X`NkED}nTzuwfR?4>*2gBh6mx@8x);~#H#6k@fGtyrz2$HXrcfvCyZ z`$7+)K|Lwr&}S*bsyau5*FZ<5T%!NnnyrqQ>nBukrA`pNKPmHyEdZI%8>zqc5pfq# zCOlL~ztz+3TvnW%tuDf+gini!{6rr~zHB0fYeR~6qU64aN#p>c(rSSsX`W~s0@Klq zm}r|+#YbSIQ5X&VdRy;La~&zS%&f`OUdQ6{`@_<2g>lEtb8T*(It#>+sY*iZv!)8_ z$%4TRnpvHvRf)VZrBbeI0O8!DvVq{Y9zGg!!j8qGLEgQcr7}+r;_n)hb8_S{NCKx0 zZr>T`j4XYS+PS0qvK{PkZsYAxlYswG_F#pY50q$&OlEzQPEY0qzEUh2*EN~7AI6Db_A&<`?VmH|@`|uSRE1h=E^B{- z@wr4&s0}86ySaL?n~u4xy$()9djE`bSsR8Y=kkIP0GR8V%0{{T(_Q8AU%^z?w$aI{ zJVCTXHI%-oY@9uJ6={F@Q`smxJ~@>K4Efv_a(-%*9Y5Vwc6^Ro5qwUHB>R$ZH;T9- zIF}cm`an)%E<&t&B5)a^^TeOM+ra~|saP}cCm2nPavnvF zi|?-U`HvK(vK=3SZwLc{G}SfB7isYiWC#*;NFYwwa>Y%8ZTOuFvLkKUeYC~UB7cIT zwe|*1UjEER>Uv81ij>;+$d%c;t?36nX&mN#vPMegk?E#)0-sIxw14kwa*H;`7%jr$c?;;OqX*VgFB8B&*c|ZyZ zdjRQ{d95$6Pg;{X$qk;CdQuw2#mq9+Aa+i8-1_Tz1IzT0W}33+AugP-CL$tR{i z`04(b49WkHq55Mo1v?f)@Tm!ZprEEd#;NoUWQx-toO*vumc;*%rSivQ3DX~3+VmKg z++QlB;C~2-_+vsk-hq&m{~@H7CQV8j`X40C^cYFj{}594$ArZFr9%4Y4{iy6Oty-5 zfDM$I+*au!Znv~*vJcZ*$qr3_$=*#*%C63TvF*>13#7kihSFC!Q?t}}GbJ=q-$?R2@I5K8Gl|O* z-pr#3UcJ3mrxWn;MQtoND&V95zgM`jRSM{}QNtKxmhlP@aZ~*iAL5q5rAl{uI_z6Z z5NhQQGM=6opz^}U-ZkEHjWxQ~z44dVE zK;x{U7nldD?6COQtU44smRX*=wgx8cWDeWkN`PJbd6>j2^8kN*#Pq#{8VzILC*8;gEX{2@;&aNH-2x?Be9t;i)# zYdSAr&Zn(gNEI5)+KmwU%UCK{)F9m=aYdJ9%Zt@V_Y<^GRCUW%VTF9$y_f0Z&{vS&=n#;d+~6ddBH561T|?+G zZ0e+vI7EunS`k1kKB#U^cstZRi>r`u9E+cjP#%lDaQ`TL0W;T$Pb*{gY3|hsFs5b{ zA5$a;l#+$ohA*9cQ*<`bsQd_Q90Vx4k|YZ%VA2siesb`l zI@SKv$SIIm>&YccnW@XRu@=YHPok;B7Mh7?a=iQeY2T{F4nh9u+F`&n%;);lfk()B|+!y(ZT`X zb%IUmPo&xfOkDL9fjLw^iI4Aa@w6wo044d%nk(PJhQvcY0G!=m=mJU}N2!J#OKNtf z4v&lHb2unPwYey4xHyZZBXQ9pr*UHgSYMYntjJ(LJ6nBz?4>M(*cJ1cqOWQ21!@wc z@lSZCopACxG+wy^dhkf%&Q(coZSRbiMK*+vJw&9c8#=L0Ni|Kl&hFkx zu^L(sPX1Cn`j$*_{nP)+>Vuxnt}phH)gw!Mxw?+aR)e(=Oi6W*E4GoN$05V|!>HENbd$ezJjrWwPF#*#f@u8<*~d0utGAs ziRgfPr{diUcYw@QEYL@+kc^i8@^qzWbmfN^!$w9N##N)|g00RAZpevGprMdXv?xI% zPcK6(KIVV(tqqWzooI;Ho=}Y{8X`FJ21WylGr!$Mr*=c6!GD1`p++&k+69%Fv`PhM zxwd#`vCB&nS6!1qyGr5WUR{z4Xr76IAcNWP@6je;oxLlRiEdI|IPztQ5a^t>q~%i3 z!!ekqia?f(1%$LBvdieKG-Xm&;l&X&kFjEbpRv6dHHZ3A?2hn_i(nRA=QjJsRh+qy zF7iw?y3*LuGx;gd3)cRQd@N=qC=zNlR9&ZnvTFAmV;kZN8Ex^!qS=*Tj?P?6zV+tE zEvi_a2>d>sS4h&GE~yqc*2o|bpcKV9SmTF5AGqa?lWEHzRlUI#PnoAz}rj?$j~{1criY#p!&=iQ-k0(f@2 zp@DrJ%!eW6EAUtP6rRv)vTj)PQeU`n$15QqmFC=Y!vGE}flo8q(k#+Ly%4s$Vxprx zKfAStKtGP$CAGW(jPkv9h)?)cWGcw-+yJvQL;MBG9t$^R4Z+&a|Did{a>Xw=Cl!jQ zw!R@HbVrwJ{^}Jt66T;bOwE|io-dzW!yhP(9&y8W6Z;#Tnx|XScm|59uO6Yn?gV-d z^~>+nO(if3Ay$hboEp4_+Y9qe*0wxU7XcDdJ3Xp7s~iHn8sIkaJMv~J>(B4A3M+)s zVFprqwdV>kN}0BagT*>a_j~AV37C$gf$;VScxh)Ukh)_=*u&3X8^6~9GA@5!nBRQ7 zf0bM@S9}N><~`TJ5*`Pc^xpgyAZP!npjl6OR^-;j(QoQQ8#Po({&Va-HamyYnxEQa z16!`LLhO_Jeaz4vlK+f%bmbJT0QMloy6DEUv`E#{_a1L)7_Ay}Fof6$z?UlGYkr8T z!jIH|qX!p*)=d@T#Azpq*-LG`!_Y4V*2pe*KW-kzy(!#^b7>U>!hWY$2g{7Bc)jaRaOa#PtBA=cz^}0aO3TR-T$m|jnLuf&=WxN+ z7WGu)neD_SjXLvd-Ss94W~+iHbCXPAHh~`6m2^7RiR$ki8AmB|Xb096-$7}A(&&?4 zH5wnM=FFOv%hv`s+N`7iDR%_1EaRh(P3#?REpe(lbeb>qx?vCnCuz!NBSi_AM|oCY z<2D41f7a;_)_qa&qR^H#hU|5_2bc}?EGhSYHCwa+?|ZVOX_5EcuE_+ zqDZHp(fwZ5)+#bx4j*;wdVh4EK?mA0n^K@mbdC#93VW50+ zIT){4SMP<12)r=qsJXAM1n0{p)wUukeB`C-gZ^2dAw#s*Nljp2uYB=+n@T>3n{=YQ-!lkv_24Dw9H$Ws6c3qi;fVSQxn`rnI_9rzRp)tnlIMS`E*RRT6SYcnCK! z!cddgc4=+=y&NA+M~Y0hvxUYjy~HV8pxb`6qtv}69MgqcQ+{|tpS>kg{(kpiH|h4s zDwbV3i2{}$Ai@Wa(uv~%$M)df-Bo!qbM^G z1c5dXp~!2L;qxp@|Ip%GQSZCSnG*Qe+x}40Ntl7b@{@XC^h)A`yaY$8RWtGD*Dy)f zeW49=&llxkVIzTwUyw3Qa#-{{;`8#O$zV%nY==#V)-Ba!8`x(J)*qc<44u+7>_)Dc zjf<_H-~ST{&wSd5tEH=48Q{FPPN>wsJRG$QB0L zX~w(Yh$s}v~BjT~|T#gk@;(?$+D1t76OPGtw?Jlqm^9q6p^-3IVVY=hdWiwp*&h9y) zKY9DGmD=_;{@InDBdJ`Oy*T7_aNWRJn47GEM4}a7x0~=BYTEHn^+^mQBOANmT$2kLAwE{1YCL`stQ;s$ru?x6q zyZ5=Q0*Va82eqrlZ0mZD1f%apGg1%2VjogU+WUDwDUKW;9jy1}?+U>wE$uUFQgHHKNJ2o3Xt_Mvj$^^ z`l%;OnA}PbcA`Dr(5USgVl*D#`Xf>)dDsF*RdjunaqpC!Q>6UTuXCRho-dtmM(TA$1vuW}Y!K*NH~Rp-i7>*yfWG1Zc>FwC9AVh_=LWoE6;riiSJGh5eG(YT;MV#OksI`R=u z2$d2zE1)cDWaDmvmjc--pwpGqygld}l-`G)*AA&JSKV?EU+kZe@>OG^NS(}G)K-N2 zVYQF_!^-0zQneB=b@o^oqEShxDwP@qjtLI_W{$YR#nc(%w!zkg0tNi1cqK7cJsm6t zR;_3!m7{ja8ww@@*BIczUZMKN?a$&feH(|6=4C(Uynj8u>qVX}?)H zcWXp!MeL`xhBldNu1$V9%CL6?$MeI(gvE!uwdc~90D+QT1}Sz#MT5OU*0j#9O8vlq zsvu&UJgKWdq4lB;Y&1h17n3Dc-KzIC*u8Q7BWh?dC4vc9l3D$jTfitMJ6*CTm&}y%==`^sl zKz)cL%UJ#1yghP!s+e+VqA$PTn^vB^1=vopL49#~GVaF2JlJpceJ z8Iv-0QA_ZG7T$wAnOjE8%X{)GmiQj!Zj2wB9Lxgm<fnhw7%bl`=_bUErDcCA?9&^!iPo)?s^U?e57)}J5Q>GLMu5qXC5mxrhaNd+E z_v!tgF3nF}`ZbV}BdfnWWZliEImAS9Y#cl*yiy4{%U##(cOG_5pBSk8B@ryE#8s3hGVu>oZdz| zRhcismM6TgAP9ww+FLd*$8|6_#o!B6*Tr$ZrMCTQ{DG=du+FTZlar>!QDm}dy>Wfq zj?yLX#E^JTt5QGVW*T{|U&~eMRto!7m1TA2kZWOjZj$$+LN^ZYd}$}nz+-)wLS#9t zg!0y3afF3ZVJ~9=Ip#~!=F7NG6jMHKWnmt=gcJWM=$N#IHGu8}Wu3AS!0 zG)o%^Y_Kl9Gqjq)%^H`FC(ax9=)5ywJbcF!wU|5M|N7>i@vA>Lh zeXJv1Ek$0Oiia$K0#Pf1!Kwe!| zk4nZJ8YSA`UgUs-oW^e1zoqmcPp$akf=%7WjmRpnf2-(EV$0S{>wRP2^$|__>*QW8 zo5nW4KNVag=ootn?_~kOq9KYSsg&;1H#BCPZ5%vpK%3ohUVj1w)|m3m0v6)f8*`GE zf0n@tIKHwSWF^Dd&bzz^nd;m#1na_AWb?v&Mw*Ue@MHq54!w>9hj4x4aH|L!A1Fg{ zEN3DBDn`1CayZ;d3!egm^*g)>jII3fA=wJYqV6iFV}I}<^Gg3DeufbB5cFX88UbO( z4bwt0S3vM}?Le+C{90|)??}M3N9vZbfKQB%4jqIQmUEk@NJaI1I4RYNM)h7gDWzLI zkn_@ovNjR{<6`V^rZ)ovI{zh2XS*(?ibB<`JSnAO{KwTVAxsl=pjVAVB~Lt|o{s{T zRJ|1|)})T3)E551DbJH+=Zi)s!;|Q_sa|X(>?AMAW1oTtMp(|-UL!~2(Aof6kFcm| zl9-^m+?rSW-QjO4@S2F2thA4sLO;rPMstf*MtQ(3W|s2I>3@8r;Du!6W(dfLZsx1H zzPU&4K4DMmp3iV0S*yy8f1ItBIaOl6I0WeK*$&DUHEab(NSq9NY3ySR#7y2v-~@xl z^e0>ddQFj~-Tp|#XApV(0{lE+Q_g4<;>K0SoFyfW5DnS&F%u2pbS!Pn$WV+>F9%Vy zqh^!F;D{mmo%g}}Kg~h~$@D!7p;EWWpw)nVrXZ4jd>`U9Oxy2j#R^K4OX{~$@YYGJ zf`}s#K=mtI@a=(`<(7p|>UxULIAdivhDRARfM>*3`4gVv(l;*u?z{p7ioV~MZryShmly3k|%ePd_a5PwPJE6&4^z|8Sl3omsf6O991+6g zdx&;RMBtizzj8~2+}(U8zsoZaEfTtwZNHv3Aca4zDAwH|D)3H$(N`v8K)vk@z`dXp z`WHhwUW2;|Yen-j%%w> zhM+sE((lM7>&b%Q(3$4UBo3`2#T=^bxp_X=LkVMiNnXWTzqoS!> z)BY?QI?xB0hhJQ8lN-dO+Yc_ePIlz2f2ez+{rTPQG%W)!Vrqg%kRvQFqhCa`wC-v0 z1qWJ0++p|x$Dp*4h`Sc*R>A7;-+3KLwE;@szzfdoZ-G|Ysy8ByrPn7r{`tIxruG z43`M(_`Zb*OcA&OD|f2->nK+W{gtrGjR6X2aEL-Y}Dt6jeDBnoihcPEk6#g$*ABPR=(P{4?O~DVk_Z zjfmI+Cx?BERU*256Wa9yH5J?Q*4#=Ug6W*A)XcuYOCUka0{NUCSs73v^}9pQL!H>1 z*YlyV)Be=>i3?8fS8ITkyh}55jQ^mefxXplBymS$h142CJ!gWuR%!;WH;OoNN9ct+ zF+bDF=0wAO);_5AdN_Gubv3tl-m4vp>cixD4$5h_Y+*;-;T1 zd)&HkHlS`E?I#apB{eGdk#Bf=qVgF2a3ICUwQ3^7ZWo-6bpZjFJ|K-umG$Y^hv{|T z)UED?9d_dUgS?~k()S;k3FwFSI?#f%@}MdPF6lqFr_qn9(Tb1l0+((OY??N(bGH#D zjLVSynK(@$RV3g=Ygd1MOcQQ`1*>IF|-SI*nl;2=hbf_aGo=0Jw5~Gl*Ag9%wJ+PGfK6e+Sh9IsV#e$q%{c}@hO+?X%G z1QZv>%#gOq_wA70-*Qlw)$g}wls9(_Avn!IA!~psaqSX}b?V&fF4pD{<3`5_K}q~F zf`tclzFOt_524C~8ebN86;}c9;QjDDB2>6q-5S}PFSVcJ=h+X*8p->kDlX|K+RJ-KboESXDY!#urNoe` zbFZiqJdxs#a5FC`p3V(`fcT+@ov2!6A__TeM3T$GP<$PsTP^4h(+;tARUG@(q7GIq z&_22hPU5TVWLu;%c2;cebh-omodS|8m`V=)q200c{3=}M>fqV11!3_jQZ$v8>)e$` zbl{)uRH8{EtXvS0(&=wzgR4m^aOT?W%Y~3Ad1Ux;86TA29*eiO z{2e@V0b$O8E`#6{gIg4{EEFk&$Vc$R!h% zqRSKSv9LgT<9Phq=^*)2>vQ{)s6c68-Ec$ zy?0~6C~K^bsPw;`xZY_&)AIi#+FCD@AN4u#hvP^ZV-|P3!$oCCQLlCTbSD-v{#u=aWp0#};iwo!aSB zVCuAYOq2?xE3DsOcU0WvG>Qn#5%5jNtPVuztC(cWw{%`esC&282AOoGih7$18v zAwY;@K`t52q6)8ysHetWc0OV3yphbV*wwT|tf|WxtVN9!GR4xSy*Y-QdacEl9E=3I zq)w4_6TAaSN!kE?c&o&;tBsFGC>gz7SyLB?gOxb6+eDXEhD{(da)B-?UA(zQjK6tV zI7^O;K~5CB#?!8gi|KE6zp}q~SbzG1NH&VsMY@4bzrU-HdsqY&hwZ$o6`7)~;R`o) z1cAy;IW4QB#pJ~Wf(sc-qc4PQ7!8$O$-GR<;#$pE;7~vBWFvn!-)~l z(2=aPw6#4~A>K^wl_qaV=l`L%Y(iAGeR1DEqSBvv>A`9I#I zzes%Y>wo*9a^Y<6!Q+I1zicXX3VgAzU12uNt%+BoE4GJURbqIUoz!l<#*g@{ctD8@ zx%mVge|@VsQ}{P_KENk2Ot>#gRvY`FRE1>F$z;)TDw|FJ!6r(B~Qk zn~%kqrrNT4^``#7DTD&faGjtowDCy)N$)EKMHkz)=5*LTyA;a<#gJzr=V8S!A8@5i zU?`dM7sWMjjkb-uhdp?&tK1?6V4|Yh+SJP#*9RG5v=tqG0h5g0c^S5nMyej*C<-dV+eM+B{3pTFLGWDrUd~2k zZwvckOuPEqgSUr|z#k@{6`ohTEq2UWy4^t<4(s{y5Nve~3Ngl%xJ_so5-m1NwcdAh z32F^~WX^jZa`Z6pX8CXbm5S});3)t-EAhd60=8F!vEe6ElE3!m(d!W9CPnEu5;yPH zW6GM(55|6RTG_h+SK}j55qO^3c7(58KKnM@)N@f35u8>Gk?1pP4QZ0jzwH`sI$O zCP?S8(QN#e+E$TPrkVMIu(WRXWDpUgGT}iJhEnO;&`1YAg8?yKH>fg1DU<8L3E$*I zr2F~@q}{iw0~1a1*zBp_7mEAbxW$>&rU*BD*4I3j1*u~7N(Ht|N}NGSZx-&TJ_~mm zq@JemH>uZMYsP+nF~n>Xh~h?+MB!k>)HTsW^-XeNV+g9*Xnbolb-;d0$6fLey>jra zf`yPLy336>FI`Fi%_|xdvr^&mz0#uL8@?6RSMmh3z^7>{ku2m%BX7_H#_lQqzYZh~ zk=nlGbv(hQ6n}=kk1$NR!ht*y_pOnuYB&`MFBcOqd}7`qTjv-G*&_$ERXQCLkyDH!=bebj;PX06npY)gYm+*Fwm)@s3g#)G+osxNITtwx{7 z(lAGtlgv3g*aBuI%LpulMupAB`TScJkG9|Sv3~{i=M|DObILzzV_&Icvv zcWi3{9REDM)%PD?@2vr`V4L^-Ib|w)(zlIS$(Hw5$Xf4kT7T+#xBil_xgIen;jH;D}r17^J?WE@ni-i3H0*iY!iUs zSztlc_nLaoL8UM8uzJf%j%haEuanEwMM6I_|8nf9d2Aer3@Mn?dYX#I9$%QbU7^coN#*1=fF69{vSHj)n0h&Pcl`V3mk3yZP`~H%!NMoH z;yL!G?#`XVdy2c}LW>?uM(nLtWI^SJ7nhp(?CZLA+C6BM$&c6j@p`DntlHVZ?_yDr z4wJtO!l*~S2DL(P+~sll7_8LFfI8dor}#_0C=wPbsc*Kd+r~d`J C(RY3T literal 0 HcmV?d00001 diff --git a/assets/animations/SpendAnalysis.lottie b/assets/animations/SpendAnalysis.lottie new file mode 100644 index 0000000000000000000000000000000000000000..f1cc7ab61cb541c7e831cdbe0ed09b21294961b6 GIT binary patch literal 21421 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

a8pPBBarxF_=j{(GXRZ_X}ry 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 ({ + __esModule: true, + default: {name: 'AIFeaturesPromoGuard', evaluate: () => ({type: 'ALLOW'})}, + onSessionOrLoadingAppChanged: jest.fn(), +})); + // Patch Keyboard.addListener to return a subscription object with .remove() so that // @react-navigation/bottom-tabs useIsKeyboardShown hook doesn't crash on cleanup. if (Keyboard && typeof Keyboard.addListener === 'function') { diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 6af591bed322..811031a296e8 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -7258,6 +7258,7 @@ const CONST = { SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN, SCREENS.MIGRATED_USER_WELCOME_MODAL.ROOT, + SCREENS.AI_FEATURES_PROMO_MODAL.ROOT, SCREENS.MONEY_REQUEST.STEP_SCAN, SCREENS.DOMAIN.MEMBERS_MOVE_TO_GROUP, ...Object.values(SCREENS.MULTIFACTOR_AUTHENTICATION), @@ -7777,6 +7778,14 @@ const CONST = { MIGRATED_USER_WELCOME_MODAL: 'migratedUserWelcomeModal', + AI_FEATURES_PROMO_MODAL: 'aiFeaturesPromoModal', + + AI_FEATURES_PROMO_LEARN_MORE_URLS: { + SPEND_ANALYSIS: 'https://help.expensify.com/articles/new-expensify/concierge-ai/How-Concierge-Analyzes-Spend', + EXPENSE_ASSISTANT: 'https://help.expensify.com/articles/new-expensify/concierge-ai/Expense-Assistant', + BUILD_AGENTS: 'https://help.expensify.com/articles/new-expensify/ai-agents/Create-Agent-Rules', + }, + BASE_LIST_ITEM_TEST_ID: 'base-list-item-', SELECTION_BUTTON_TEST_ID: 'selection-button-', PRODUCT_TRAINING_TOOLTIP_NAMES: { diff --git a/src/NAVIGATORS.ts b/src/NAVIGATORS.ts index 7f24aedd382e..3a99812352d3 100644 --- a/src/NAVIGATORS.ts +++ b/src/NAVIGATORS.ts @@ -8,6 +8,7 @@ export default { ONBOARDING_MODAL_NAVIGATOR: 'OnboardingModalNavigator', FEATURE_TRAINING_MODAL_NAVIGATOR: 'FeatureTrainingModalNavigator', MIGRATED_USER_MODAL_NAVIGATOR: 'MigratedUserModalNavigator', + AI_FEATURES_PROMO_MODAL_NAVIGATOR: 'AIFeaturesPromoModalNavigator', TEST_DRIVE_MODAL_NAVIGATOR: 'TestDriveModalNavigator', TEST_DRIVE_DEMO_NAVIGATOR: 'TestDriveDemoNavigator', REPORTS_SPLIT_NAVIGATOR: 'ReportsSplitNavigator', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index d9790039e6ab..8cc6bdcf979d 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -3375,6 +3375,7 @@ const ROUTES = { getRoute: (backTo?: string) => getUrlWithBackToParam('onboarding/migrated-user-welcome', backTo, false), }, + AI_FEATURES_PROMO_MODAL: 'ai-features-promo', TRANSACTION_RECEIPT: { route: 'r/:reportID/transaction/:transactionID/receipt/:action?/:iouType?', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 5ff83221799a..e448e95c7b71 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -970,6 +970,10 @@ const SCREENS = { ROOT: 'MigratedUserWelcomeModal_Root', }, + AI_FEATURES_PROMO_MODAL: { + ROOT: 'AIFeaturesPromoModal_Root', + }, + TEST_DRIVE_MODAL: { ROOT: 'TestDrive_Modal_Root', }, diff --git a/src/components/AIFeaturesPromoModal/index.tsx b/src/components/AIFeaturesPromoModal/index.tsx new file mode 100644 index 000000000000..a161b7688029 --- /dev/null +++ b/src/components/AIFeaturesPromoModal/index.tsx @@ -0,0 +1,92 @@ +import React, {useRef} from 'react'; +import {View} from 'react-native'; +import Badge from '@components/Badge'; +import FeatureTrainingModal from '@components/FeatureTrainingModal'; +import type {FeatureTrainingModalPageProps} from '@components/FeatureTrainingModal'; +import LottieAnimations from '@components/LottieAnimations'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import usePermissions from '@hooks/usePermissions'; +import useThemeStyles from '@hooks/useThemeStyles'; +import {dismissProductTraining} from '@libs/actions/Welcome'; +import Log from '@libs/Log'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; + +function AIFeaturesPromoModal() { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const {isBetaEnabled} = usePermissions(); + const canUseCustomAgent = isBetaEnabled(CONST.BETAS.CUSTOM_AGENT); + + const customAgentPromoTitle = ( + + {translate('aiFeaturesPromoModal.customAgents.title')} + + + ); + + const pages: FeatureTrainingModalPageProps[] = [ + { + animation: LottieAnimations.SpendAnalysis, + title: translate('aiFeaturesPromoModal.spendAnalysis.title'), + subtitle: translate('aiFeaturesPromoModal.subtitle'), + description: translate('aiFeaturesPromoModal.spendAnalysis.description'), + confirmText: translate('common.next'), + }, + { + animation: LottieAnimations.ExpenseAssistant, + title: translate('aiFeaturesPromoModal.expenseAssistant.title'), + subtitle: translate('aiFeaturesPromoModal.subtitle'), + description: translate('aiFeaturesPromoModal.expenseAssistant.description'), + confirmText: canUseCustomAgent ? translate('common.next') : translate('aiFeaturesPromoModal.confirmText'), + }, + ...(canUseCustomAgent + ? [ + { + animation: LottieAnimations.CustomAgents, + title: customAgentPromoTitle, + subtitle: translate('aiFeaturesPromoModal.subtitle'), + description: translate('aiFeaturesPromoModal.customAgents.description'), + confirmText: translate('aiFeaturesPromoModal.confirmText'), + }, + ] + : []), + ]; + + const wasDismissedViaConfirmRef = useRef(false); + + const onConfirm = () => { + Log.hmmm('[AIFeaturesPromoModal] onConfirm called, recording click dismissal'); + wasDismissedViaConfirmRef.current = true; + }; + + const onClose = () => { + const isCloseButtonDismissal = !wasDismissedViaConfirmRef.current; + Log.hmmm(`[AIFeaturesPromoModal] onClose called, dismissing product training via ${isCloseButtonDismissal ? 'x' : 'click'}`); + dismissProductTraining(CONST.AI_FEATURES_PROMO_MODAL, isCloseButtonDismissal); + }; + + return ( + + ); +} + +export default AIFeaturesPromoModal; diff --git a/src/components/FeatureTrainingModal/FeatureTrainingModalBody.tsx b/src/components/FeatureTrainingModal/FeatureTrainingModalBody.tsx new file mode 100644 index 000000000000..8bbcc63c56d1 --- /dev/null +++ b/src/components/FeatureTrainingModal/FeatureTrainingModalBody.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import {View} from 'react-native'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useStyleUtils from '@hooks/useStyleUtils'; +import FeatureTrainingModalContent from './FeatureTrainingModalContent'; +import FeatureTrainingModalIllustration from './FeatureTrainingModalIllustration'; +import type {BaseFeatureTrainingModalProps, FeatureTrainingModalPageProps} from './index'; + +type FeatureTrainingModalBodyProps = BaseFeatureTrainingModalProps & + FeatureTrainingModalPageProps & { + /** Padding for the modal */ + modalPadding: number; + + /** Whether the modal should be shown again */ + willShowAgain: boolean; + + /** A callback to call when the modal should be shown again */ + toggleWillShowAgain: () => void; + + /** A callback to call when we want to close the modal */ + closeModal: (didPressHelpButton?: boolean) => void; + + /** A callback to call when we want to close the modal and confirm */ + confirmModal: () => void; + + /** Whether to show the back button to navigate back to the previous page in carousel mode */ + shouldShowBackButton?: boolean; + + /** A callback to call when we want to navigate back to the previous page in carousel mode */ + onBack?: () => void; + }; + +function FeatureTrainingModalBody({ + illustrationInnerContainerStyle, + illustrationOuterContainerStyle, + illustrationAspectRatio: illustrationAspectRatioProp, + width, + title = '', + subtitle = '', + description = '', + secondaryDescription = '', + titleStyles, + shouldShowDismissModalOption = false, + confirmText = '', + helpText = '', + onHelp = () => {}, + children, + contentInnerContainerStyles, + contentOuterContainerStyles, + shouldRenderSVG = true, + shouldRenderHTMLDescription = false, + shouldShowConfirmationLoader = false, + canConfirmWhileOffline = true, + shouldCallOnHelpWhenModalHidden = false, + helpSentryLabel, + confirmSentryLabel, + modalPadding, + willShowAgain = true, + toggleWillShowAgain, + closeModal, + confirmModal, + shouldShowBackButton = false, + onBack, + ...props +}: FeatureTrainingModalBodyProps) { + const StyleUtils = useStyleUtils(); + const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); + + return ( + + + + {children} + + + ); +} + +export default FeatureTrainingModalBody; diff --git a/src/components/FeatureTrainingModal/FeatureTrainingModalCarouselBody.tsx b/src/components/FeatureTrainingModal/FeatureTrainingModalCarouselBody.tsx new file mode 100644 index 000000000000..5f2d0c0b0e1e --- /dev/null +++ b/src/components/FeatureTrainingModal/FeatureTrainingModalCarouselBody.tsx @@ -0,0 +1,302 @@ +import React, {useEffect, useRef, useState} from 'react'; +import {FlatList, View} from 'react-native'; +import type {LayoutChangeEvent, FlatList as RNFlatList, StyleProp, ViewabilityConfig, ViewStyle, ViewToken} from 'react-native'; +import Icon from '@components/Icon'; +import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; +import Tooltip from '@components/Tooltip'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; +import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import isInLandscapeModeUtil from '@libs/isInLandscapeMode'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; +import FeatureTrainingModalContent from './FeatureTrainingModalContent'; +import FeatureTrainingModalIllustration from './FeatureTrainingModalIllustration'; +import FeatureTrainingModalTextContent from './FeatureTrainingModalTextContent'; +import type {BaseFeatureTrainingModalProps, FeatureTrainingModalCarouselProps, FeatureTrainingModalPageProps} from './index'; + +// A page is considered "viewable" — and `currentPage` updates — only once it occupies at least +// 95% of the viewport. The viewability event fires for both user swipes and programmatic +// scrollToIndex once the scroll has practically settled on a new page. +const CAROUSEL_VIEWABILITY_CONFIG: ViewabilityConfig = {itemVisiblePercentThreshold: 95}; +const CAROUSEL_DOT_SIZE = 6; +const PAGINATION_DOTS_BOTTOM_OFFSET = 5; + +type FeatureTrainingModalCarouselBodyProps = Pick< + BaseFeatureTrainingModalProps, + | 'illustrationAspectRatio' + | 'illustrationInnerContainerStyle' + | 'illustrationOuterContainerStyle' + | 'titleStyles' + | 'shouldRenderSVG' + | 'shouldRenderHTMLDescription' + | 'shouldShowDismissModalOption' + | 'helpText' + | 'onHelp' + | 'shouldCallOnHelpWhenModalHidden' + | 'helpSentryLabel' + | 'confirmSentryLabel' + | 'shouldShowConfirmationLoader' + | 'canConfirmWhileOffline' + | 'contentInnerContainerStyles' + | 'contentOuterContainerStyles' + | 'width' +> & + FeatureTrainingModalCarouselProps & { + /** Padding for the modal */ + modalPadding: number; + + /** Styles for the wrapper */ + wrapperStyles?: StyleProp; + + /** Whether the modal should be shown again */ + willShowAgain: boolean; + + /** Callback when the "Don't show me this again" option is toggled */ + toggleWillShowAgain: () => void; + + /** Callback to close the modal */ + closeModal: (didPressHelpButton?: boolean) => void; + + /** Callback fired when the user presses the confirm button on the LAST page */ + onConfirm: () => void; + + /** Called when the user swipes to a different page */ + onPageChange?: (index: number) => void; + }; + +function FeatureTrainingModalCarouselBody({ + pages, + modalPadding, + width = variables.featureTrainingModalWidth, + titleStyles, + wrapperStyles, + illustrationAspectRatio, + illustrationInnerContainerStyle, + illustrationOuterContainerStyle, + shouldRenderSVG = true, + shouldRenderHTMLDescription = false, + shouldShowDismissModalOption = false, + helpText = '', + onHelp = () => {}, + shouldCallOnHelpWhenModalHidden = false, + helpSentryLabel, + confirmSentryLabel, + shouldShowConfirmationLoader = false, + canConfirmWhileOffline = true, + contentInnerContainerStyles, + contentOuterContainerStyles, + willShowAgain, + toggleWillShowAgain, + closeModal, + onConfirm, + onPageChange, +}: FeatureTrainingModalCarouselBodyProps) { + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const theme = useTheme(); + const {translate} = useLocalize(); + const expensifyIcons = useMemoizedLazyExpensifyIcons(['Close']); + const {onboardingIsMediumOrLargerScreenWidth} = useResponsiveLayout(); + const {windowHeight, windowWidth} = useWindowDimensions(); + const isInLandscapeMode = isInLandscapeModeUtil(windowWidth, windowHeight); + + const [currentPage, setCurrentPage] = useState(0); + const [carouselViewportWidth, setCarouselViewportWidth] = useState(0); + const horizontalListRef = useRef>(null); + const lastReportedPage = useRef(0); + + const [contentMinHeight, setContentMinHeight] = useState(undefined); + const measuredHeightsRef = useRef>({}); + const handleProbeLayout = (index: number) => (event: LayoutChangeEvent) => { + const measured = event.nativeEvent.layout.height; + if (measuredHeightsRef.current[index] === measured) { + return; + } + measuredHeightsRef.current[index] = measured; + if (Object.keys(measuredHeightsRef.current).length < pages.length) { + return; + } + setContentMinHeight(Math.max(...Object.values(measuredHeightsRef.current))); + }; + + // FlatList's `onViewableItemsChanged` must keep a stable identity (it errors otherwise). + // The handler reads the latest `onPageChange` via a ref so the callback identity never changes. + const onPageChangeRef = useRef(onPageChange); + useEffect(() => { + onPageChangeRef.current = onPageChange; + }, [onPageChange]); + + const onViewableItemsChanged = ({viewableItems}: {viewableItems: ViewToken[]}) => { + const entry = viewableItems.at(0); + if (entry?.index == null || entry.index === lastReportedPage.current) { + return; + } + lastReportedPage.current = entry.index; + setCurrentPage(entry.index); + onPageChangeRef.current?.(entry.index); + }; + + const advanceCarousel = () => { + horizontalListRef.current?.scrollToIndex({index: Math.min(currentPage + 1, pages.length - 1), animated: true}); + }; + + const goBack = () => { + if (currentPage <= 0) { + return; + } + horizontalListRef.current?.scrollToIndex({index: Math.max(currentPage - 1, 0), animated: true}); + }; + + const handleConfirmPress = () => { + if (currentPage < pages.length - 1) { + advanceCarousel(); + return; + } + onConfirm(); + }; + + const carouselPaginationDots = pages.map((_page, index) => ( + + )); + + const currentPageData = pages.at(currentPage); + + return ( + { + const newWidth = e.nativeEvent.layout.width; + if (newWidth === carouselViewportWidth || newWidth <= 0) { + return; + } + setCarouselViewportWidth(newWidth); + }} + > + {carouselViewportWidth > 0 && contentMinHeight === undefined && ( + // Probe layer is used to measure the tallest page to lock the modal height + // when moving between pages with different content lengths. + + {pages.map((page, index) => ( + + + + ))} + + )} + {carouselViewportWidth > 0 && ( + <> + + `FeatureTrainingModalIllustration-${index}`} + horizontal + pagingEnabled + showsHorizontalScrollIndicator={false} + keyboardShouldPersistTaps="handled" + viewabilityConfig={CAROUSEL_VIEWABILITY_CONFIG} + onViewableItemsChanged={onViewableItemsChanged} + getItemLayout={(_data, index) => ({length: carouselViewportWidth, offset: index * carouselViewportWidth, index})} + renderItem={({item: page, index}) => ( + + + + )} + /> + + {carouselPaginationDots} + + + 0} + onBack={goBack} + shouldShowConfirmationLoader={shouldShowConfirmationLoader} + canConfirmWhileOffline={canConfirmWhileOffline} + titleStyles={titleStyles} + contentInnerContainerStyles={[contentInnerContainerStyles, contentMinHeight !== undefined && {minHeight: contentMinHeight}]} + contentOuterContainerStyles={contentOuterContainerStyles} + shouldRenderHTMLDescription={shouldRenderHTMLDescription} + /> + + + closeModal()} + role={CONST.ROLE.BUTTON} + accessibilityLabel={translate('common.close')} + sentryLabel="FeatureTrainingModal-Carousel-Close" + style={[styles.p2, styles.opacitySemiTransparent]} + > + + + + + + )} + + ); +} + +export default FeatureTrainingModalCarouselBody; diff --git a/src/components/FeatureTrainingModal/FeatureTrainingModalContent.tsx b/src/components/FeatureTrainingModal/FeatureTrainingModalContent.tsx new file mode 100644 index 000000000000..57d4f258a4b4 --- /dev/null +++ b/src/components/FeatureTrainingModal/FeatureTrainingModalContent.tsx @@ -0,0 +1,138 @@ +import React from 'react'; +import {View} from 'react-native'; +import Button from '@components/Button'; +import CheckboxWithLabel from '@components/CheckboxWithLabel'; +import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton'; +import OfflineIndicator from '@components/OfflineIndicator'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import FeatureTrainingModalTextContent from './FeatureTrainingModalTextContent'; +import type {FeatureTrainingModalContentProps as BaseFeatureTrainingModalContentProps, BaseFeatureTrainingModalProps} from './index'; + +type FeatureTrainingModalContentProps = Pick< + BaseFeatureTrainingModalProps, + | 'helpText' + | 'onHelp' + | 'shouldCallOnHelpWhenModalHidden' + | 'helpSentryLabel' + | 'confirmSentryLabel' + | 'shouldShowDismissModalOption' + | 'shouldShowConfirmationLoader' + | 'canConfirmWhileOffline' + | 'titleStyles' + | 'contentInnerContainerStyles' + | 'contentOuterContainerStyles' + | 'shouldRenderHTMLDescription' + | 'children' +> & + BaseFeatureTrainingModalContentProps & { + /** Whether the modal should be shown again (drives the dismiss checkbox state) */ + willShowAgain: boolean; + + /** Callback when the "Don't show me this again" option is toggled */ + toggleWillShowAgain: () => void; + + /** Callback to close the modal */ + closeModal: (didPressHelpButton?: boolean) => void; + + /** Callback when the user presses the confirm button */ + confirmModal: () => void; + + /** Whether to render a Back button (carousel mode, non-first pages) */ + shouldShowBackButton?: boolean; + + /** Callback when the Back button is pressed */ + onBack?: () => void; + }; + +function FeatureTrainingModalContent({ + title = '', + subtitle = '', + description = '', + secondaryDescription = '', + confirmText, + helpText = '', + onHelp = () => {}, + shouldCallOnHelpWhenModalHidden = false, + helpSentryLabel, + confirmSentryLabel, + shouldShowDismissModalOption = false, + willShowAgain, + toggleWillShowAgain, + closeModal, + confirmModal, + shouldShowBackButton = false, + onBack, + shouldShowConfirmationLoader = false, + canConfirmWhileOffline = true, + titleStyles, + contentInnerContainerStyles, + contentOuterContainerStyles, + shouldRenderHTMLDescription = false, + children, +}: FeatureTrainingModalContentProps) { + const styles = useThemeStyles(); + const {translate} = useLocalize(); + + return ( + + + {children} + + {shouldShowDismissModalOption && ( + + )} + {!!helpText && ( + )} {shouldShowBackButton && ( )} onConfirm?.(willShowAgain)}