->( zJ$D)ZJH(#$zuz*;r?sCj88UGmY!T%Im9h{PCk(y*zb|)+jDILe$kva`yuF3SETAVf zeUl})q_9j?{$JyWg9#TRc{p|AiM;c%LbnNkW1oh&(&E4OhX)t@79ynvYAa?rva{Zn zPfor5=ZH)k+4J1i^%zScXk5yKwxtF6FpdBf;B7tJGLyRm)2uY9k98l)KSD} z%2Di?EBKE8(ZRB^+W6m){7HeyoNT4#M^_Y~2d2k-S%d}E^eRt9x-+54CWLuzn(76U zx@R6!jvNRk?SNTrjqAwFPL6*gr@S3$6OWC5R)6IYy1lkt+Yy>O^EKB`d+<9p8=PLc zN8_yF+8$$P3y5enyl?#H94mI?wauG)Wqq&l#U-MGL*VGs@|xZKyqry{DtP84cV`Vz z@cD05Oa=AQn>L`P)Oc Vc(yLOOCgt1Q!gaKg# ziD{ 44UeMi3_#UzW z1jfg|+sWD~w}qw%Xx!zov}vTZKN^Q_bC&`Lp&xeD|D7~W7P|2=bW?us>IBYtEkrb} zf&G%lOIc!krPLN3(&(G7ym(C_>niqxA9IC*UR?8EFpg>vrow=OB9ljJK0e2e#`UaP zZmEr5IOyI=V->{OWW}GgBZHp}W7`rqB2e0+0dL?c{5KUqP2dj%Am59)fgyk(S1RU~ z>G8nPFm-SgQf}dCJQeS6{x0~A%LxzP51%f#eC+-7`?Ten4F}Gi)px#PR=fhUzUySe zn@nfLn9y}i-f+{AHSu8DEwoT;Zf%__cAWp#qjTgp*oNh}ap|3ACy4XnjcJO(Zo|$M zcyQC0alr`xdi8Ih xxHW5@#QqYp@Od$JKn&U|W%Q z1I aibfl>jX-y9=2 z93E+woE;b6`@rK50X9wB&eH;=TW(jn+hMyz$%CyuNrT?C0wb*l5kZz&-OFd%7|pvq zdG27T&(;j;8-ja3&i@wEP=Jlm2%(& (PN5g zxMgpR+on>omEm`NRb1Ii2N?;I>h9%93Ylq|V}a%fLgBXWZt9s;%-l)Ec5uV6LVS#? z< ;Q_us+wp zs TZ z!Tk&l{s)h%yK|pD;XS!e+3@e7IJ7$088(KK(*LAY#4d$ap~49>7t%|1t8gs>m?9I2 zS&jYXg7lJf376-H@2PgXN@RFE`K@~v^@8ikB(JPb&a?52f85tsp)<(V6FVAff1fzVb#?M?afUOB7NLxUwf$1dh7<2Yoi{^ZY|2iqgt&h31ck_Cm#0&@VHn{?k}2 zu}W5b*ktyPq2Dh+(c`|dW!d!dS)RLJr~bHGJ4y|*OP3|)vFv_%{>VYs9dEO6jRuWP zN|j(7YQ1h0QtelgKKL0Nxjp*J)KJJ`v6Q>JRwBe|;Vr|+cL%NMM7vPB;#b{qBzVW0 z&;*{s08^`_X}ZiQg23<#^nCvw!ei@~);-}egd%3sE{3LcgbX%OO (^yWPIUgYj~a78ljcWFgeZ#tZsF! z)#awI`JbKUrG _M#ZEFlejRVuRc6B$r=)qf@ zkRmS>$QI+di|4|g#>6OHR<;bbc^0gF)=Nh37JI%!=hE!H);Q3!e*Cf&F ~l$K%fK;UU;i3_H*gV*n?j%YYNw&T<5^8-4Ba#GUeJ%0udKpJM1#pWYj;;286WJb zE-rA1R#jxEE?&%*A2D0X2iDJG%bsgitUu}NwW92VFj M^3X|BG!vnQ!??0oZ-x5m2Pz$MuY%P zXxyjR5Ur$wm6zV}C9f#c6NS7anSv|BOsL3v%{-|j)Qe&8boL+{T&U8tiOP`&-uv6; z$qRb 6klr >nn@JMV(GFW&q@H6#W zLfm+zHI)@2PvkWvZMV1v{s`48;AKj_ zl?g69VK%FKoH*yQ+XnB`{oz)_f7fMOY%Prtck4x;odcsn1~EVoBlfvS#lUe9ULO8U zbbN?tWmsc<{W**vg7 |eM Pa+p(s{B>-tRX-~ zN#ygMAVThAmizI+_{U~m2cG#C(VwZuB2?$TyJ=u*{ADVVf93>42mu RSf5^+>?!rkBV&KD#M#C5}Tb XAd@J0b+3K R1r;B zHt&ymPVX0A)aaO{%hhpUTHxE7Oc_5!TzN!}W E;6X_2G9(*J^6@9-1H9f?~ZQ4x-9zX=OOxcm t(=O!=RX~+Jg-^ zK<(S@F}mFM0F+b?}vt0e6wooqEchYBcC-)#K~-vs@N@!#uYKB&MT18K=6nvIiiio7B;G zT}%IqM}vbrDr5`SJI|q%ZtB#QASdWRy~5k!D774=Mf!Fw%(yea6QhdG=efhvokg?H zxkdBEA;;&n2chNF2++zN)6tJ>=o`ZE5xShyDuO+%i=ZPGmhT5|lG%?V*hYD}FVt&F zw9MUS`^mrL*K|KQUAqRFoT?C|inCNVEK*Qm>8<&6rLl$Nj<&`kJyo8ER~F`NVk?GR zPzm(%biWhE2@HkuP+(`jCYrL9D?ib6_JFKrIPWi9(j4rYzo5Y72;mXlcix9|rtMGt z6Ia;Kh-I!__?1a;+YubC>G6U6oy4W!JKv|Jg!4(Y zd*3`vtsK^-Ef2K;C{$Lqqf4)^xx7lNyEn{1%Y}YnBcgc%^_5z5mlRl;lPUq(g!s87 zctLuFKHXEul)v>Aj5R~$>@9<(?JZeMFi*XJ>+p3KyJ`ETRHIq2Y>R5B0$pipvr64A z_`!n5=GE?}@id9xB&lPdn)o3RwZ}Y%@TMnx@{QwL=qEqQtlHZ@HJZ_S1WMnQ8WJSW z87z_DbmF<|TjGYs05m8ij(5R|q0l!Jm?&hdb4*yNarsF**P|M(qOCHN^$Lt#+*DQF zcAD$)2%_DtEc}$NBrWl?*vFC95ARXf{e{U=E6waRe`rnb#me@%wlLotG_JTkj_Met zF?jO8$|pnNd0G-I4@l3- V9~C;zu{-jXBOsXRX;BSm3tj9#z$j29QMf%OHY8K ze!^Dm8tq3fgVQ7_1QP6TY|gbAp+j@{F3y)d^ZVpxCX*)VS#<=(5=Ngr29i^rXcBmB z-Sy8yJH=YR$(9w<%TwjkzzZ54Na!cPBUa7kzaG^0!b#}eI>s;U*H%~ORw%s-JN^7m zS9^_=JQv}X*kfW%E-U-$3TaCLNvd1lVaAwXRUU~;tb6}`8hu{(*P-K;1bjW-Jzrq8 zuj@t|_$?$CJCKETLs*yMUfuw@>JDBf$Ss^>RAR-%S@@oe-21L%bftmD32rt281*35 zr$zq6zPqqW(VCpFO$^>Satk)6f4@tHT>u=unYlBQ88S&vf>W6ub#Ey=tJ2C{a1wIA zFB1a19J1e!JjH=!20!c*?JNJTZ}daX)W1DfPTxABObtgG6%iGgWtwGB&qc}iX*V`Y zmk PewD75>2py2 8?x1T)ml$97igKvbDBg%7B~o2WE`X zD{tV|pixuu2tOK)g^rl;qU?@ivR>=m@eFVvgjfD5-R;8UvYE%0ZVXc-?Adp|w4-KA z>Z|?y$e$Fe)Dt$W)5D)^?5{A8Nr_*O35LJ`mq(1BI(i@ms~0x-I+tcYZ&eXPJ)Dmg z+RU*bnTv2g4)Q9KdC!ePrp_ci8?@4j&7DQ^mD7lb_r2F_BZv|PI~qi^!rtk8ySNm$ zS6;wRw;-d! Mp@k8%xc+g6{&(vb=I~P!I^6WJU&Au+0`V=);9?5s zy_-`!B@uKqzSfHTOt^(b>G)e3vsWQ8c(9K_d2u(?E6eeja;C_1g8eI~Gwx+Z>U7EB zanN)~0UERjnOL>8s1=RNDZh|mfH~N!I_wQcOhyA^9~S8y&lio$8#IfR;`^!{m;Qt; z4M_#;JTM8dc5P1@0akkFN+Sr;#kHgMi`bTX!T{3=wpwBhLEI(GJ=G*wnTec);G r$1uV%#V*QpiyVCyi zE{xFF*eduX67HRMMA7ce>$K4`_>E3pU~*$R&UbX)6$k$~j=ACfxxPW(Yscov@TtGi z?_BuB(oxJTWrL A^=u;XM{|9?c)N!*Z b!<^FuLiMH$d` zf{E0n=(ne3iOAg%B2k~#Zn2D=&+f7qS(9+dVt`M31_IDMLsdoT(^F)1s?yf8@d8JD z*X>lr5Nc~sjV+ o*oW^VH9=$YYERK9ACc9|E;- z_;ErwzQB)=39jX?lMTJEUNZ9S0Io#Pni6{Noy)Irpxb$^*`GghK-wB0`)Zyx7R3yN zMB5^MsDBn4x6UKqG84V!CgQbOD>9NO7`#VrZ;a112prg_sbb>-oOC;hAn$6Pp3m$C z7|uzeLQ*hdM&9mx9R*acV1kdhfry>;1TKRnz9#v&aayoU)Uky$JZ5ocW2tfe{x*pl zSX%$EF>puMT~i{~! LL5&HSy(La*#NYgMWI5XU9I)eXDG}}L&X=AkF^2FiQTRTKwj=Y)691b* zb}QSHw5sJf4a2AI4r0gZCu{pVTGsf@4f02HH{M<4(&0k)se0+}*V~Lee>A3TT-A*k zwJNF91IN9B>1p25(~wH}`@p2VhZmO)|Dq};D;+mtj2lf&nu_}EHfSw9-5YRp=83^G zg*xwUlaV+i-wuydVpNKY!lylCn0(b|L&+qN&_1T-PR_>iZ@dU1@C3FH^tas1T{ppc zPB|l4eJ68~kHv+@r*%OwiHL@eYC-b;KHK Z1 z^8f5`{zdUn{T)_J|4Z#&Z~Ur;X)CYs$5wu6ZeA>+LL=bA+dp_z_rdURa(cgGWJwvL zr@GWQQmS)xRUM+^Z)|XsiU#$-&Y3()N{fmEnD|(_JiO(k?R?(AkW{Ql3)Zh^2WI+cp{cWaFc }fVQko|e=>60ebrJkYv;G^tOo9Y*o`ADGWHu8Xq{fb=y zKuF)f#HDIP=W${0ad$>HWZ$k;u;nGyr8M_ZpD^)W($943kqN(9z#iR1RTfLMY+yRT z$ZHobpmfyZ4~P9+KxPW4wfdZ%(?S|?Ez(lsaK};e{*J*K?wSR~2fqD2iE9 {WL7}G3N6z8&saG$Q}|5+pKK5bA+ zk$Uu8BJ`HV{i9<;e+bh}uRhxp?K&HfibgtcJa*g$aeIUz>f3%Z>yzu)sx>h7x((q$ zm~7-mcP$!B`R>86NTi^`s@=x?=|OYi08_^4_4|ir%sJJ+yEF$0iIC&b_7pL*-o(N9 zwu9$b;|KtKieB_#9$sczTD5&Bx9D@H(xndu{&U(jS0v+-hN&elPbNY4=yxkZhI0aV z`&OVqb{a7|iSeXT`}L`~JT7TY?Y7ref!p%IS9IqszW DBIGAa0?p7#xDKSkyO pET0CC@>blyr C-W zn%xI4lm#ZcZhrSo&%F@Gl`Qzy4z*C9*7%N~)nzOFTQB7%GRr!FmT=s}rQaE0k!Lo* zJ;5$#jd_P|!7W-M*i~_EJKmX(54mgNzymiR3m@~t?(ipPIjFdr(y#D5{6B&bYv#p$ z$a$_Oh4fTQbk}!HG)W-&^ux{NP;4Ln>!pjBbqiu`M~>jH$z#oWnoXUa!quAPRljX- z8UXjPOPaav@)?95RObb#QM@r&`tB4#(xvb7ZRm@3)+m&5&3@g&pXCjq@1Wwwe?Q>g z#$#O876CmE*fM_|p)kUn`W~2S(L~v4O4j|TVda%txeG&Ki?OwBdHtUKsS$-u_lNh+ zzJk59(wA>Un<1ndFlYL~es0%aRK8rhpW07Um8y?Q`i2+PNBQ!8+l_Zcr8X3-?oRD6 zlP}>*@1P?&`*#i#e#^FeX&)U$yzlqg>pD&6Tn_{*o;FL)vYHM>l7(Jd|4=(MLn4QI zB&UK-+hO0A%rcep=k9zcYYtMLLCUn(qne`@C^EyHi5B|}ZKNW5KS3=z|2Ny&l-$s! z>|YmcZ0PAy?3!&v{n`VD%q)7qo{zS-YtIs06unf;5kUB^sh`oR^8<`KeYjSK4mu4; zJ3d`@L4^ola )Qu(eK(bFF*u}b{PK#K7X4`YS`J2q7(3g6*2t;giVUVY2 zztP_b_BP7L9 z+6TJdLE7{-_5%LZ@+adIw&s}cGzt@s&=I)PC}h9ix9GizXOssph&Sm~2q>`tb 7{S;D{0ilA8jlpHGqi5RHmJz`+p*wK!FY4BUKMIIri(A-_S1;2HeMBG zW7fWZ>2$7S g8!MLkezXomX5k)%?OZt0i_H6!*8P*+GX3yk)1a$DH`;C{!{m`w|6&r3&=aWUfgl zg}EzlLsEl7N??XpGNIczd(K4Q39g7bnJ7Oy*2{)MBxX^l76Kb72o-R-Y$7fE{4%A~ z4bY`# )(gj zU^!=YnF(p7TT_15iQRTBJ4bli WW=kbF%XUu=&xA$z8)UKe{ w3dUl{?u;Sdehp7n%FFf<}etbD3M9O%t+!{Rtd4GWWsj5D={Y zo$+Op9@8lJ_?~>%ivrqYbJu9|xpP=dS^Qzu!yA)1lirX*hTW_0EpS`Z(2!%0&AE)l z1`pzIGw}0fFWs^%6y_o^7NT-;bEt|LMqoWEHBMSzC}PNBB5ld~+y91EJRU*HwX3q> zGd< I3?A( cBXmTjILYy;-*R-0tVNU_h@R0thfbBH zC~fIodg7F_sK*3;dWUPBFKhEzi96>KcV@8you)EjfdtG?;Lt}3@fhG^Q4v9}BlcqW zhMu$R%flXr@4(x@@O-uItz;9SKN+1yD#ss;R`7-etIIb|W_UcwYkx>6v6dj^nf0H^ zrI#4PtCUKu*KZ9=f3dx$RW%fl_gqXYa20!pED1|)QAZ>>iP6O~f6o8>t%RmtWEh-$ z<-z+wb(W=jAVq a(ahp~1eQ0q=P`plBT`vrt@gHluZf~1? zkjF!oGvhxSCCV*wldcv#T1`dh
-$w6t>DvERoTnQ^CJu>vVP^(X={(k!h0$Q zG4+Tvy?vumq7aM*O?gU};`Myr`|Gu0Pw)i7n@# z8-MKhggY*8GOP*QQq2`$XDF%U(Q6! x@&UC1bP3V5x&(r>Aa%zn}Hz6=elNHCfZ zZ*xUqiG2xw(Qp?p0Iq$;LX^l%YX#xn?w$vg!RY1h^xJMIUlc?OC$j4(y+QKqK-v18 zjq{qV3JC~yv7f3moVStg+i+xH!M0?lhxIgYSI7qS@KN2O%y ;wHqq-O{ws0Rz*Dbx|@)E6P_shvTVWe8-tb9UJHj> z5yFN(Vq;r3^AsmuRG-kKN dTz#4Sj?ObN`KB(I7) zP(=lQwt?`sCnuo2u{Scd+tGT$7U(x>vJM?8&p&AeJy;!E5u>}gelctDsAmt azb@xU|d=7q^uBjZ^5%J1qgQ#s?d+;~r^0RWd zz2!rN0C08viEJ_K3#m=JN4;Pro)};nj_og4gfDLRt1h&w8W8nI0vNl$oX}U^y(Rtj z?PK#*&&RcjqmmaoB9i?aX4_1X9pQB1R6ltg$Hk-#sdR+;=7T6naUX}j24|F;gkstz zYqk#!`$Dy6U-3!0;H^6(O)6)%RF6ZVFH1)qzcEjTCpE+pSJT*uZxqG7zMz;ugW{8_ zXTQlQc4eNZV0tH;?vqwDkJPB1hnj~wON^6&v2*&|#;CUQ7tKs;OgHL}+JqoJQ*Q2F z3n8nYyl#7gK}_hLw^TunUa&IyqPrmuVX|9_G$k0i&LvnxKI79-Fm|0TIj$r`CfCWm z(<$6@kI~Ia%Fz}ZVn{0;dC8^Rf+Rm)>fhj oK!kGOdzvoTEqT78!*;A&(1j` zm;hz<55Fj(sahR=DM!Zl=5|XAL+l)AB|h2lp*}f}Sf3rK@p6Kk_K)p2pQSS;)7=lE z#TovVyKUc6^- 3CAXp38OyX&wEc_ZpMu`=?aOAD3XInAkv`0CbS6MeHn+QUCTW z qamY)&W{*b4$jnPQ+wxI!n3C>^y|K+g2rXq8M2wVeYDA)cxuG)2XG$|?HvCSQg z0e|uSW&y^FO4p!Smg;zIhS){JJAw%-^>R*;>bV+MNyK3LlDCxtY3E%XABl3OgI1zh zC+A0dVp3ca3@yKj%eT?xq`#=%e8L;}TZ=EA7%Qj6QI>`l|EYQ&-$jp1zia%P*-9P> zijn+Qnl5%V=^QMJ(r@)K?^6ISr}_;hn1dBqovI&HM)Sr3ZZPdD>U;m^)FcE2X1;zq zo%1BUZ0tq`-e{QMRbQARrZZj# 6wSdf_eToZJ$pQB!q%%;p^Pjy|TO`=g9kwM<|=S}@^* z6t$vXx%>AI5HkFsuHVwPuLM7|2z@}_{aZrl;5Ted3h47imPo=0pPgqyFTf$h`dNhX zbQtlOct!QbzhkNhBn~GZUj3-}Cig6-SUT_Zg@hIYhAY_Jcfs8i?rW4|9R}CH1XGlD z_VriKD;|vcA3!<-NPV8D7s& TjBaQ>km={UrIO5;2V1_wt z>d@RbV&uAxlBIuq*IDD)FX*oz{iH!<#byE2`ChpR&O6~c>!Sa9fAnwQQQ6Y@vI?0~ z@~WK@jRjNxMizO)?A*#o;kPp-k< 8*R-;C
RB}M&BTi(R?KUCf zA8 RgSV|+wQZ^S$xZIbiD~JE zgCn=!dW|RpLX;t>&OKWHd>|1jV+JO+C8 iZi$}-QYOMADZOLUIV#iox biHvF}T1pmw(ej*nu+6kxWqlr%|pM8Xuaw4oBR>7dxw9_6Kg+UN5I z?08)jLg?Kv{`NDBF_(~>Amvf`3l+yAr5qUV^W{NTHqk2+!+>k1DynxeN0=U<2)^NS zGIYli*b1`G 9qr*_pzEFFNd`=q^79f zz05v6^>HOf_JMnUcamTxnCKPV`}=n^x?fAM!j{RD{NkA+>R67F?>c?TW#Z|u_%%JV zV=_`iT;0y#_Yy^Y#k~MHbBWS6U}^wByw^qj)wnAB593#VriaANT6z<77N!;+1tEa5 zm6TQ>)tP91jGbz$fO%>^r2NYaB)g>3->z;DL@5=j c?wp< zE;!GWz~9EudzLS4Tk tw}Au3UrJ8^Q_X#rp6!OR`SH08npV;2!JD1B zNia{**t^p!Ig{>a6`JJ~(Sw)y#J6ks7EcI#=-UXj9cLnXPMLN$O_AB9bCnX&JxXK) zDT^h*HDEjK_)tne5UEG!9K}&CQVbDjt6an$0z7&%hbU8mX4BwL5&10NXil{y{f;Ki zYiPG#y|t4Gbda4$X?T~+MSOvmDy2PS_LFWWo!?>PW%cVEOgfzs0f^!TY4CdO-dkx; z1cd6#K?5oqvwhxgr@ARaYWQZ}0H~ZgfMwpa-L;o>@39CI>@;#-P* bt{RJ=rFoA!RYrnESMA-U!$|nT K+i`Rb*2 rdPlZw;+luA&l0G`$Z`QO};e zuyZWM(876L7J`xw%A8EO)G5G9Z|czweyoaejz3Lu1Qyqui2BV)Mw12`svbBav(*^6 zy)Klvf(Ptq&pv%e4q8CJBB|JtGSBs%n>15Z^^pq!w{w5^=2eLXb;np~(96ndpYB~( zu{1@RH?twdg!O 9 z2 mw^@M^HwME^`hA{6C7$!}V7YE`# z=Cdp|O6P%BVPnOvEx`C$!q*=w+=c2Xpq}Q)o}=V3P#kg-OB-goyAYMiqnbVg56&9v zo^7!r`{(mw?Tp7sBSUXNHrGd%uii@PF7mz?D?X0YHklGvpe1;H`b;HIlygMcp4KvI z{sJcoaMb0wnW1YMpGY~w_69vMwP(MAF?7ddP)12f6F!!<-h*feJAFhvJd3*5yyUmw zd=6%!_Tru<4%NfmR~9;$Xz-?w=?uN>otv5BkhWn4R^RIX>7QL1KWQQ=2(o!s_s`D} z-3vI=lvd50R C)az(+N&a zF6M_{u&EgP7QRsVOLftGWqa4F?Glf0vUOUfAx8f))})U`x3Qn7-E*Pk9=j9nX9w5b ziAhyJ%AlXu;bzF*&rYx1ueoe{6W?B&_#b?XR~j~uJomIT;UGtaglWu5yj~VFTpIXZ zmKuiaqP07HI6n{Y=Vv@UCGTNeF3(3_?v%Uj{u}hL?CMD;Otn}ipN?o{%S9`eetD{4 z-FMZq{m9X$MZ4cb@E+bF>t>s+p4Pc(TY!O}^dGeo`>IFSF*T3kcA;q3H?^>&e;}jO z;%Ob#q j)l-WRJ+ijb}%aS|0};KPpOr*7Oh8zW1>sBO&Qt!4}IQyJq`#rDZ0! zUBams }sQ+pxg z(!gkd4zMN~g9M)ofR;$!5t?KhbaF5d&l_BZqf>R>C8kLtcC=dGVSp`8Miq8zRs@Dk zLcIZE<~5m9T+)Vu2H$Ol8}}_ex{DPsYy4!m+J(*8eA~ I$BA=z|ysyDcwbb=p>CTVxC2dGI@TyQV>A~(s}H4NkZ55L}_0qE5W z9#u5Ir=URDhMM2{FiPLDV2yS%wRa$HH&fhlW~aEN4ZRK8ZRQH2bq{XLclso1?0#|S z*V<84m^3~Ylx(ADd_4=i!JXL5B<){k`cbz0*eMb)O&$Wp0uxKtQ>hwLY~0 z4Ykc;MR%Id2c0@S6P<2&NaRY p>jUkK=?+61jc+$KF2!$4=X!zWn+_o@ z< ;{kPPsn5%Cnm_nJ%8Vd{yo((Vq(}K;zGHR*D<9y z=!}J{)9<6^BKeU@)>XG{c(Z9NL5xiL+aJT|w_Tu7IVC(u` SHjwP#u-u{h zxl+@a8>EN~z;+ Te?iXyY?IyAb3pTKRuIEJSiFq ziR!gAZn?DunsTUOO_4bvY|kM#El@OQD!qkK`1-y^<(+EyfX?0f$6Z;NY6A)^X6ajS zNd1OaSk2*$ob!6sgGAA$*2gI7?@}~?r+{8>@1D1e6cf+03z%#ab_|u>0M@X{G;Ix0 z<4woei4br4N*X&1N52USHreqe#@?i%wwLLWZN4lO?=(?ta~5#Clyl@91qd3s3< EUsR#&nGySrQe4m(}|jHYqhhG&mjJ zLLUeE!zu<5jW5mwU)*hFFskH!{wWdU#v3~ka~b Np^iInQI;(c@p$L>_p)~Nt zo1h^k)h&o#qT&@8ex9I147F-TaM)ZY14KylXAJk)*@#^ HqbF?H zWcrGo*|HKODdr8258gOw^l _9y}Wdqlrm_gq@RoNz$wx+xh>%v>qRfGCKaiKwTTLz)BY(C zI@ha+Q{UK^F$_89D%+LGRO-ItH9FYqT^bnO53WT)qW90Wvep0yLP!I5LereV#4_I~ z?}U%P0B{U9hfsXYD~^b@XpXuiqTEkAzL06hCMXEv{yF8CpXy0-?PU-XcHtT#o4w#j z=p0v2+q$X0W=Zky?-jLvlm&~dgOU blC)s6xWU1*C zlU~EM1t>4=J*NgWZpnqt*j`_kwPCn4RNusAab2RvEjR0FL_>eef6uSZr)7 M{ zbwjC$SIk`cnpx%xC8JcA{2X8Giew+WZl`_G5skPG%aty_$n^U2uv){tTN!*fY+fiO zG8@dzB_))V=4Tnbo^_$qvd;9l%elK+xSmpKQy TlQ$Za{15pM79a8MIXfsRn(JVBzZ&~#cr+{ zWM%vv6(=Dd1W;iX5%I;86c``nhUyM$0$=!6Uq8)YSie_zCTIOob23&16rz1Ai5ou) z$9FUy|Gej3Z?}X98uvw4GBSlWI2Hbq4)@DVUu>9j{OdVN%H3UmHe$^qwud6tlU(g* z3#&^#`lv|7n`R$zV=&A&Jno%MDr1;G@K&E70yeA-icj<_upm^jTK#()Sj?AEye9x4 zO7)r9k~a{OVYaf{g1IqgvJ3GHx%L5QGIY3E6C_IB=4Ht)gt$j@n6|lGP%&66VDqvV zZEY~hIhKEuWDj(Ge_1v4%^rgYdT0M2D0{BhZZItN0i{$NFMPK)RWcUF=9VY!NkqsQ zb80@NTL8K(xS1AE8mRSd8oSI=%7|$Ov=2kirjL$7oazL-#+m2Le%!0pcwTTtYX@T> z+V6i%aX51?H_%OW98Tzc*K%`3WOO9!Ce3M70*HO1$!0YA(v0UkFvPwFtMQ)3H;`_K zX-=x;d4&kK)kdq|{i?$$#@INF!CPMB!4jubSUa=QV$r~bHlipoiI2&Q4L;K-!KC!q z2hLA(^jlCtiPSLJC@Uf~t4mQ3P5b9F)S!d0y6IJ7#tCkCF^mBp;jD(I!zVBm;{ksC z;#HMUWg6sG5@H#s?KR!Jj(QaG Jt54VX=+0mKxlEr(v0?-27=zgs)T-_py}Iero+@{=04vRG3i0_zXzD3XGQ zr0S)Zg~c4KP~o~!{t8lm@GPC9$It!!T}!H-T9YlN(WCz(?6u6Pp>_YuPx~3WM_UP^ zG*D52;tji?aV^J@HGxGpZJr1OQ-lBckJ}~(5??=9LFWxUtdfEbN3v|G7p2hBK5S+N zvP=Y^Rh{8zSbg|NH=y6Tu yu8sgeXS@>oaJ2cl6HqRMfx_!!c^dq z;v&7Ukg<~BPS-oPFVgr1ZbSP`@7@H`7^1E2WEa)+cg%^$ddDFhZbOGo88rAmeSK9_ zTul>g2u^_D?h@P~!CePua0~7PclQ9n2X`CX-CctY1P>bA-Qmvn-}`*mn#VaURlB=S zSMAz|kYX||32_eJ!PKyn^D5Inu5&j1w|n11o1W1^lpnh-p?6sYit*a7ruYuUE5J8g z9Q2ye*G uBZuuw!OHR}kxR3org(fKhvXUa6GS8R9)6L6NVDL$*f-)8ttKnz?P! zWa3g~PHN3O8z2dzc-sco&RRDrp-Tl_rOWG?s0ZEL8I$<#9=hg(_F{_NWb$W|^a|4e z$ZE8b$?Ut?qSW#J j zR!wq_L?YqIFOy8p5Fzz4PiLkoS=|p_P`=a03EggDX+<4aAf8
`&O>$a-+p(D=+>qbb-3Dc*bR43rL7QvPAGkjzbnlzbVUT`umWUEOn zM^n4OdXGgoi6x@Q&V21Z2m2G*X`lZ(g%@o7S(Du$D QR!4p29kQe}9DG!yVzNA6x#Dt7KC`l9`n%! pkP_G zHt?3y=F2uQDPC%MZaFQZ_`6GQ)~COVC`8?6#}ltjuc8j8Q>UbjTRwlP8gZ3^XE`FJ zPLm=Ty>t`vY1}>x_ez#$s(Z_|37*zAt-k6D_u@Iz^fS|&R@K$=$Fi<>4*Q^4grchX zK>EY1tXGeNZ Q7Hbbn2QR_0z!oi&KdbV@VyKxxk$i~Z0^u=`#;mjgq upjfKxF=JrSlez7L0idP z6xhMqJ$o`M@6ckBUDRx3 ;3ugn6%!&P7C+2M4eozTGIJea z@xMIRCYO2qVk@)QQ!kR9s|QE&SK?>5_9ARIe)(&csvGF;0#m`1bD<9!@xZ%iV7L8# z$ph@($H|@6*8KqSS2;9-T@g2(+UfYzH9_jk-|vT!-HwCx ~#CQd69 z-P0Tljz!}A`l7W_u#HiU!&voZO`fty`3mOaLJR_RjS%aHAH1$03PJE0ZAea#gI&`z zDA0~Lz7D0&&H>oe+mt4s;e=b#k%*7ef@A$>-rh?20dt*hdPGL^6TV-Y06EkVWh`;? zoU{F8bFS (&tyV5a*D_E9FyY>B8=??r~PMMd7FnW%Ji<#{D^3BwKhj kHc0VUF8 zEO-^mUDAaG^;)hH_f#|cfH96$JOH9vkJ4C=c1v{Oaqg)fD5zYaH!wgX;)%`2EhvDv z iGSsg&WSZg3yG`)&k)^HVA67ml)a&Y-J6eqFs8g#XXCHS8^Md(QBV;!?PuHXp- z{HSSSzQfMppN9QIKBjOxvLHyQg+myc3{eFxa((s`yMrO%bAk ;V9@5*W7fcFlNi&Foc^zP{AnNUggg1qW)$nw>V`P6g*zz&I6p< z +6NRb@p7 z%Md|-idHPEp8-+Ky(RgTnf)2MrJEk-N^GZ!4|f{Olx@J>WxU}DS-{^AeI@Lg@lEUY z{X8-FPRilEATG0p{~s=VjegYm7JU;S92d5q?ZG|dK5UA1!1--3)dx7YPN-Nj5cUl% zfxQ8hI6k^K%PO=@+@|Omk6x xC%v^hR#
Mtv{!^ruBj_@@-e6P<{1oQEy~kk5b=dN#+7M(?$GdS!YYXTw2Gg#J$C?GT!0 zeS)BeSO#*5+1PG|Vq|Nicw0lPvzAbR<8SuW4r5HW5E-$OzBz3gwxEQ&P%H)H4Cp&o z@D)yKS@hLxp)dLu7GEX6S#5j#Z36Q3WkWjrOx?Sg)f^M4Zhnb8AfZhTdy!gOYoPaG z2qQZK7Iqs??5a_aT}j(-T=gE_aFK3h(PaoEwHr= =+4~rnml9BU z;!C4L(wu+m<~W@s0B9y*9M4yrLP}00Vc<88e(j;ko9mi@zPq8?jmHa;Ir|j%tAl6V z K8icG-f~A#C5*Bdv21oNBb=^KPNz5@WH(JP$CW98}ACTg6 zWle~L5C#Fr54dutm_-pJ<}{#S$7l`WqU?xCgk-U&?>7hUnkn988;oG5Yz&Snz4EuJ z4-6dvw+FXyGGaAW48{YE#U0uoFvXHYiFlkTe`R&*-f3RXROq9*)T3OwtS*Bt;zJ*2 z@&kxm$#^lv_%X3Kzlx2|R~gCv4x3M3HGVlEo$+|EJ0KSN%pa;4Sey39PH)U1Ni#uq zTKfF4=9ugBxXsrl>QllFGcWJ*Y>bs2NKEoZ|D*CR5L$J5V?<+0z%MV4px0*r?k+P$ z<{6%q(e6$i?F$homijeYTlC%5jb3&cLHC57BcM>~fO9%$`mdMaR%fj*kp^LrahGu_ zu{XN;E*Tk_w_Wzpq~RCxW6AA>04=h>N%Rcb3+`{)y$KGq30KF%@|JNBO!F%cT$kkv zcJUI{&Q17!^iAL1={LBkC$YjJ8q7CjD0488`)N+jsMz_kX--$Ma2df0xjIoMmV$Sa zo;n}&$kzcb<7<-Fqk+<{K8nyU)xVyWfSEG!o^yWemSukR8zC=o&aiN$KM*g`+&(L> zuzO;mN!i^!#cv@PR+tWfKS);#ry5t1tR>-LNu|vx*>C(47He79mEWigs) KzwCc5n*8ahT4ZTe@L=^&2de@*wg0zUk&`v&eeL0-V*U;2c%- z%1H9c&^XFn5aTctc|4Q^`$()$Q3i>QZ<^X$KG-%?CHFxX6M`c4$?1x_Zq1S&CUQW< z<5v9S>8olEk46r(Me|1@3vD@NofA`tL*fR0i6Aq?Wb;ai2bbbB0`H>xLw?(_PIej6 zksMYa-37WVdyqO|)A)Wy)uKW&=^!KTfOwUd4ay$-=>~_cXVgu$-9SwYx|c|NeSJ7h zdf$jp<6a$JAh%dDSWGXk&o-76rX~~p_RB$Hy+or10>gBvgxe$$Ht|v+;a5kXZw=)_ zKoT#59#XgR;;?i`lwTa28i0TWO}*%fO4gq2r-7 %6TB@+IENx)t5Zsed0m&M3R|y~hyR!lwEY+%I1~ojDqE08;7q&Il;`@O` z95YZ_9bR~xK1%p36NOj5E}p9-d+{xV^1w;SP# (8Jv>%T0i|u5q zefiFCZfPrEKJCsRMDy0udA hAmlq%DA^t53iO{ZZ3c?j+Lf%LF<*l z3{<`51$H99I{ a}jX>PyTl$HF15wa$~X%TPixBXLkR2`&FrjM6=ofNn=* zkXTX{dVM}OkK)(l5YT7z16{KbupJr0v-69%CIj9F4omd<^`tU8L0jcNKj;z-EKmgY z3>oh8?1CU C5vI7-;A2(LwwI4%Cd)ZUl!n9*6v864$C4A)8w=B-Zq;6tefFpCI@Y zjD9R!wUEQRsSjmx@6cF(yH=6^%ICC8(&7OiLVwwxfbwd<>8Pdo5nNoLaajc=snEzl z9Z1cQTtQzw@WUFC@vO_zJe$-y*!)M(8;1*KQAOT!pxlH2Z9If*c4~_dX`M8l-;`@Y z$1PCIb#RoH-C-AoK#2O>(Cq4@hyN&tqVM=&`Ki4%yYXU5ocVfMcf@?HrbpYeC`kI# zb4B9_Aif=ucFEPX@^_v-r0^;cjW!MxIFL;qwY<4c?XoHhZ1+6^39t(?HWwW`fih~8 zKQbm~dgXT4onT;1Bh;aS*J0%B>{Aht)!DcMHyeD-?vcB1^fBkX@)fd0gG>4T09oen zqIrSAAIY-K$KNm#&1T~lFqIcJp_$Jb9bHR;`b8%|)=ILF{*^ZGPb*!J(Z3x!(iqJV z@^>-}2OHPsQD(NZYaXCGhW)2P3kq6u()v2zobRwV; kjZlEz~MbT@znHQb?|O$fI; >ti iXFfdK?8Ha2G%0+*K|V&}mUmabwL9RWSIQT!m3AoNJz|Pu zTE?&UP0W*f 9A8<&G^2oPR$XKZ^ zTPt-MiWb04OKUUSnwn2f^)e=Tl_BZI;aygmjAa%kfRrn6uzCL&((KQ%*>TGrqfHR= zd{Arynl^a(WawIBGD!%l-YGbNaI< EYF8_m2)Ex=yT2#eykb_3h(hCnhWt zvh8%oyiPADgU`1TZS%|yh3)nhabm`=1uOo D_l zeWNbvyBw5r {oZlAQV_OJAMn}5HJGL( zFU9Uf@s5#xsvlE@wJV*3YRKQEOaX!#Wo-!?LjR^Yr`>EfNC7yGMbgw2HvtwM{PlX0 zJC21@J^SStf7KV#4pWh6Z)TfowK_(5X-5=s=U p2;;*<6=yB~ zORzz!*^G3&40o3s1`*^IrtS0dPEfjG(MD;qWG%b^Rnz49^o;`*VIeb6k#rIzZ?9e! zvt@!shTYj=s)SP0#P9H*yD%puFUKO8gC>-&M|&k@5nc8vnLn^zxRe?0MHj8GxCtfO z3qw5D{E<1NXiDA|mpi5u^~0ul4Y}Y;ZD9;Na_|jZlNi78m~ba}3miyIcVGbby|(a( z-fv-V;a2zh)pli|jFI8iI786{=!Awkvm}DYX>k_b_8VPvui<$qf6Xt#vcI*A*qB+| zNw!6DR6!SRdU6#(4 zVza;O2lGp6^>rL;aN_!P3=jM{MiD(meKqS)y@DoT|2&XO*7j?xi6MhPn6#4lXu6nw z;WCRdN$DjmN4H=6TlLbEOSeLHAnpgI-~1jG9=|1lff3H$i@K+Zef28V2wz;Vj1koM zDl U<9w zU7=7cxx_gcV4jDg4{4OUB y D_Wzyjl+Ic>A+7rGj)-^9fSp1UyHb}>NKPoF_*XG5v6w@F8lo&)ZpaOsFd zdxPkabie13^*{bXExMrv^ZAzl!%MtWvp`o<8gkxEh)nVMwxe)(=jqva<3VjppAmd( zaluuiteY!7An>z_!4w^cuA|jPJ?l*gGq<`p+NqYYQY_ j*c?y4 zKceyNOO%j17$GjHe-@WGDw$NYT=~!sFAp=3Lea%kfOA@td~2puk`)P(2|Y8ojw!gU zn7lS#j0|OhptbT1AhyNXTW<4N)?BbM-3BfNOBkiP8H6$(0-_?cLcuDFJ37XOx6d5x z#eoJbGP;TCOKKu2|0z6}9r^MKxnt=Q^TGe1RSdM1V{qiBBJoE*hq3JM=w;h7*wPR1 zK0y~jC;31(x8Hem;Jz2U`!3EGR-v9MY8{okIfi&~vKgs4cC|jK%?EFVa-GwfO`WM; zC`Z!}H_o7Mp$t2zr{0QR+St-8I&R;}^j$Am**Sk>fA-ysx-DDNyQh(4SPak%5(P{} z`3w*=>r3Bd1+}z^xy3au>C9D<{^JI*OfJVL&{;BcItas#A@ZLH1aJTA6TSK`Qo%fk zFi&0Tz<}FxV?W<=a=`I;9)T%)^Fm$ukGxiGI*;y|67P<>MRaGCx8M<7Xpk#Mac3$o z^A#TN#gzNSff^~+hdb^SX5$%!_!wCE0&M~D!N6e*FfAfJH2Zz+Iq^$($OZ2aW|r@u zP-xeCorhz;@rl*DSX$2Duy71@2^Vh^zea`A#Pq=_>2TB=0n-h;f6m)JcICzAx*gwW zZ#dkVNzXn_8!<}{xcN+^JC9n0h~48?q~jwlyQTZux-wSbVd5hJ-#5Y|j`@J3?b0Ke z$^qrlZpY0_TL1kHsJKN)mN9#lpIrt^{M48*983Ez3mwNIekNkss*n{>4Q2u6R4H9z zKDCzM2$g4u=Sk4+=)D;5SazoVO@v(V`amv&6V)mQ)!s&?-|=47lg^#=g_q;AA(uk9 z@`z%P%TD5!nhlLUIWBUGoQzEG?gRUSS1*^NyQmh}^69>J 1eB^6LM#+4F>5|U8#aqeUd3f4Ds%sI_8+k`OopMs{c_5#W&h9_w5BJ-}?!4dV z_x6lCu{r$`KG&2% =?Ur*D4P(*Zf~q#qKXpFGoR_P zH5QX8nkX-R0=%?$vmOH3L_oQK4P4`?v2u0#+o{5iz^Apzx+698$pP_=GyCWAX z-GjFL;fqgS4Vat{d$fn+E?)03)5wj5x? #f*GH?;31)s-qbSUt(Je5TL|6-Jz%B4?{ipN zx=$*t98mo(rPEI>7YR3KY3vW?NI{Jam9Lm!xeNb)p{|zAP4U~oUr$4cC^V)%ZuYum zFD$Z1Qd(V9S6GH(F|;sQ`AyP}6`TZ*G=5+>g*_4U %B=d0Obi=BL?kZ-fyJphC3>e=fpmhLr+0hQAE_;gD|S;3ujs zMw9u89!`9? W3xe5Ikv! z@;rZ&Tzk)UzS2zXrSA6@j4)ZUGXC&Ts!3m0OlTdkveidOB^6RkP9c=7Dr)9bAGXd8 ztnxl)=e;KN7Y(KrY(&sDS7X?&m*b*#trGcog{?WTUW)o)qQLl)gBKZp^83cyhP*Wa zZ~W$IX =|o0<%TQ;YKm<3cUY_!K& 61hX5hONSeY! zdN1dGTPvgfEsZvol!+9w0qQLdDDj&7m=sMcNG NqhimspxLYuZVChmP=+Jc;OvuDb$XUh{&<+G z8|dmk1vBHJ%=S(8@?H1>BJ-+q{6rlI(0S3Wn2E%v52KL3JP_%3UBMEW&*uyR#qK1k z=TzGpEA5Oeh{Nve0>5qV?zC(xE<07mCGFUjDPCqs5Tl2iCTR^kI$fertbC$j#Fs6x z{=4u83WcHA6kuO0)G=TF=NL#~d64?TVRTE~=-<27l2i}B%jy BN9ZW&|&OmOxKzGMHDt z=iZ39)c(iI@Mp1py`&qo^ zAj~ Wv9! zeHNV6&l%(j)!F;Bdw$symz}`Wr{*tY{f3uT=h|_2J7Jk?X{jO|yQ^pP%N+TmKy>bV z$-=FLayxp4MvZD_sO|a*d$849q%cX*OXbS5wH)Hcbs)L JLR#i(mOghu{#V zgSCx#v%`zfUdfc1EYi9m<&}74we5XEY*#OFH-7>l(zu20Go+>D){jbY@*F`IPXzLg zSHGlo;TR}n3mbpz95GtWoshB6iRvm!2F^oe(JVFRsWtjtw`>jtz-<0GeIN=UHrpCG z=zxm_j8_tc;@REg)5W65PK>IKD`^N*>c@*U&c}K%6b=Vz{Snwhj2J|p-cPfA9M$*T zdUs|TFUb|>;NoHAC`2h}3?YDzu;3*EVl%N&Gr5DVl|MF3Sc#hF_dc{YA8!V~9vF)< z#naMwRXKsJM^1~XEcq2rMG_T=N3w_0R2Flb)>?;AEO>?XJMPb_4UM9TJItmX_9o8O z{r+|_-Hkk+Jx<-bNggxLhn?Y%*lJ?K?}z0lCw$n|FV&v@rlNb{b&D?Z<%nK7F*xO1 zP1B qa z5M{z!kQ6^Yj`h_yj>hAx1c)uSyJB!zE8=)&)!iwL8o$WO{3}0*CoVAmMME1q>xP2r z)wU^aagp|G#lCW`@azTaB-gDgR$0B|)<7h;VoHPmx?{J)-A?I)oL6^!C0>=DTsnQ# zlsG4@M2FJx3!~WbZIu1kwwgEDkJTR-)0fLXaO9n!s+Uxqsld-I4Zj=(_J?!`4>)E) zZ^n{OUjBpUKT>FzfzQuwG8f-YQ<>GiS>oaoPkxGWB}cB#t5!zs0Z7!|<1q?bO7liH z-c8_gG|JZ(%~-UEISu5!v?6x~;4rEb?6MT9c-<-1_1-V?$wZ|eG ?@x zKFFl4GpHXhov%#`+qp4QRe$uWkkJz?yTAH{O#UP4RIOz(C@hgX_hK ;1;g$<*!1cU-d5rKjPAJg! z-^Ir1FjG9l4|%BM^3P|(@t0g?K)d&jAUf5k ztm3L3BM&dd9V)*snvAMOw7_Gm8KndMGS`jN(&*Vnqs%`oFRlT;o4GD6Pi6FA;A+Ar z-ST@|ZLIZh<5eIc+S>Vuy*8G;n)k-_DmE)}AIoPVeQp5yS5tD`FKp1Nk=J!~PukR@ z>;WhBBn a7%AF!kbxOHk&DBD=|C;x+LLkFT@u20{ z^nKh?>xRDkouRZXLj-Sf`Tb*+<*zVcA|_cs8+^P&BE@oz)17NYYzKbQCo}CgXc3;3 zarPHjP5b%&qe*_sZ$vq6IUQai36Kj$A(@+DDTYLDDXA(!NqL<@^~mTriFC$vaN1Sy zd6%zC!E4vS-AXnBrG9(0`d*?S?xC8>SNZg+k{(0mwW?7aqJpnKf4M=+yI+#FXx7H% zf~@Q8G9-%9!j$r5N3s@4lEZ%t(A!)*bzDcPdskyHuvHa*q=y8UCbaW0L&7-l8a-4m zl}$7|kjAC0wNs-)WmD8ei?ZH}uCp5r7y$LIhS*mV)t>M*%A%Ufe3U!=?UbVx?Qrc` zhCgSUddKShFWc1v)m22`+JjRmyS6ziQ2>Uu9SJhEZ`jI;{U}Xw( Kj BIvs5$5h=74A+wkTWh{G7^VDx>sM zBi?p$c!YISvM6kHkt@UtzXzHd9STN&PDPq{o)<+KWD9C7aL`7Ok=N5A3@4RuQoDp5 zv vMq;}0aY)vWfR4S@s|$tsZ~r>8T51?{(eI6?wvftO2lfwF7|{#T zMTIfyhMy?n&?EpL%mO?#mN|uYsL4}R5N>>a@{I4RY@E|qK =x#Xzm{bB*9^agz`biYUK`SE`b;!{*uf{VCdmf#zK&fH+e`RLD^~{#h z>IuYuWwzBcd9bRU-49N#1 _8oGg!mjhA`@e z>#SOw4RoXx#{w7O#&HMpop&Nc%i a1zd|p-gUf9F4 z&YuNEJ_<7`U8p}lJ6l5cJM;f}+{cBcdT;0CNUYSVgHdZIb~#M0z9?Uh=!iwYO>Ptv z3 P{3cx3Clvvk?VEjxfA2K`I4 z|9~Hz_KP(x#7QyW7(2sBi;qsOpui=yA;NqA*pr4+tnKlm8!47Vo%0?bI45Ct`xwFp zBswduR6{8&?ZiE2(!ynOQ7M~|oe(NM+Q6WdaPRECdYfmQkq@bfjPrX7JZm?9-@+GW z9{0Y!f8=P8l2iRz=Odh;v>%pi>bZIQ8T71L5MmP`bA}#uBcfgO13mg?eb6#ze6+0l zLlbFDQ1Rldc2KBXL6Kcjy%LtWp&Pkb%1zWsQZSi>4l~+mq9od*kP##QXY0LG3gK7o zbz!=wSSza*jD|n5e%OO%Zc*2TQ };wtr`k6 zQAwzS2YI8_8Q7f-n`7$58T5FfhOZ%}b0^oLhhH`Js{a~e!7JtH%? A-auy^Iz-nG4&zDv0l<{{{p=MxvMCKh)~_bryZIdJ&blL4Ia{$*wBveD zBTTC`qGAJiX~2~kA!PGOt$!|=4nM^y%TKD#GcXeLybMtn8G)8+*ZdUB)gN=-RAB_M zRX_Tm@Aq$|0Y({*BS2ZKs$~_E$1wJnUPxZ~+CQ{wM*C +j3vp)*VKH aQqqKq9E=3Ry?p0 638&T}BjSxAn zvIIM}Y`N9iOx7@+npb<4nAR??V{QJ7#C^LmsIPjYCW%$-RZ^^21B3E`QFkQ2bc<)S zyc2Hr&@!*o2`ACTn}W6lA0?w&Ou?P)O E zHxA2wuvJ2%?fXA+pK}YjwY?#c@`;dsD)a89ak(OSZko%{NKoyK;iqAR8%@wu@UnSw zJT)??+)XZR{_ rT}Jj@yy8$FeReG0+Z zkC${lTZ3b%#sh{g=)t?YbK*thHZOfWQ6r~LO(H!NE>s;pQrfzD139JT-|c+IUG)xk z<_2^AToG#4==Tu)<`<+kmvxxb=gm>Z9s-WpQydb8awKP*!20HMfbV#-9wF-urfJ z-^PE#eZ0Rf^3%d!Ki5ywOS56^u9?sG`+`O`PtWsZ{e&4KT_T58(%YE-%v8@8sG;DM zMQ>poZp+`O;xWw5b6qN&E???#<9?wnf&G=1ohWNfpoR0PDNfArHW0&FZ9!+WhBSEX zNZzQr6Lq$1a%P4Ho{+ZY=axS3k%C0gCRC!%?SlH1aLI|D97H*qOhk(8wgOD*eb;`= zElTSUiaRFyeILI6#%z>(H`i;a`2EM4d8@pXh#`>;UmA)bC4_GxSx+?zhQZ{mBsCYk z^Q*OS729w)&c*uARlg*oKYP4LOPT&Y8>-inJ^VTM4W=vY3s$BsqXTFAlZl~E)7R8l z6^@AAk<-)6r1ErXu+j4xeQXEzziLt#FFtRYHi=vh%*+UN3pAXpotN_d)O}Iir=Gn! zpP--5Ny%W%v&%1VLrqk6mp}(J=2>XFaum1}AW}!G7QDtA_+c^%fb%xzY3zion%Vxb z> lTArTHE`8U?DLMN|nNR4p#B5|y4z*kM#JJqX`hv~{ zbt25`CXw^av{EIx%XMkbp`2)0Q=gP`zmf~orkxKkqtip~ieJ!%9 zbLs(hXovs5-wrD(y5bw*u;H%~gvy-_4W9sL>jZlV#*U-SmPS@bu$@^%wMr{bmCeVV zkBuwOL;tnL`g#1?r(W{(_hi1T$Bj;juw*)`mdnO}PY&;jMM@j%XLONDt;C4`DX*1> z{=XX8g2XUHB8f1~JZn(?d((Y{6Pij&B>iM;+iD5XWw!#)UF3g{ibf8bEL?5{{#gi~ z4ZMUh&y%1XmVSO487F=x6YhPGFR>4ZZ3&1;^|v`A9$^0^A1D&eq*BmR{7Zc~d{HZ2 zf#Yj=o5L^L!1uE8grW54gqZXLw#$0)(^nIMa3|yo84mC?znlNr9m6N-6r$(BRx #cSjQ{{R!JDYq`8C@f1L0OD*gA zKG8)8rBVn>(?oH5_wsi`M+fz&ll(=*0|(B&GJ7Fkfbr5Eo118zfkZ-g`Ca#anECZP zgbIzgcI9o@i`atqw+dKf ;K%;l^ZyDk*WFQ59bWqUHh@d;Bi1{&`$@!~gKfoXRcl3iuBvJ6Cz!T^x1< rxu}MC#zV& 8>~gX!-}+54E#g)Er)&@^@E(0l4P~GQSko(hU9}` literal 0 HcmV?d00001 diff --git a/src/components/dashboard/ConfirmDisableModal.tsx b/src/components/dashboard/ConfirmDisableModal.tsx new file mode 100644 index 0000000..43a131d --- /dev/null +++ b/src/components/dashboard/ConfirmDisableModal.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +interface ConfirmDisableModalProps { + sellerName: string; + onClose: () => void; + onConfirm: () => void; +} + +const ConfirmDisableModal: React.FC = ({ sellerName, onClose, onConfirm }) => { + const handleBackgroundClick = (e: React.MouseEvent ) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + + return ( + ++ ); +}; + +export default ConfirmDisableModal; \ No newline at end of file diff --git a/src/components/dashboard/RoleChangeModal.tsx b/src/components/dashboard/RoleChangeModal.tsx new file mode 100644 index 0000000..6c98b65 --- /dev/null +++ b/src/components/dashboard/RoleChangeModal.tsx @@ -0,0 +1,69 @@ +import React, { useState } from 'react'; + +interface Role { + id: string; + name: string; +} + +interface RoleChangeModalProps { + isOpen: boolean; + onClose: () => void; + onConfirm: (roleId: string) => void; + user: any; + roles: Role[]; +} + +const RoleChangeModal: React.FC++Confirm Disable
++ Are you sure you want to disable the seller account for {sellerName}?
+
+
+ This action will change their role to buyer. ++ + ++= ({ isOpen, onClose, onConfirm, user, roles }) => { + const [selectedRoleId, setSelectedRoleId] = useState (''); + + if (!isOpen || !user) return null; + + const handleConfirm = () => { + if (selectedRoleId) { + onConfirm(selectedRoleId); + } + onClose(); + }; + + return ( + ++ ); +}; + +export default RoleChangeModal; diff --git a/src/components/dashboard/Sidebar.tsx b/src/components/dashboard/Sidebar.tsx index 786aba3..3f36707 100644 --- a/src/components/dashboard/Sidebar.tsx +++ b/src/components/dashboard/Sidebar.tsx @@ -1,4 +1,4 @@ -import { FaRegListAlt, FaUserFriends, FaUserTie, FaRegEnvelope, FaCog } from 'react-icons/fa'; +import { FaRegListAlt, FaUserFriends, FaUserTie, FaRegEnvelope, FaCog, FaUsers } from 'react-icons/fa'; import { FiLogOut } from 'react-icons/fi'; import { RxDashboard } from 'react-icons/rx'; import logo from '../../assets/Rectangle 2487.png'; @@ -97,6 +97,19 @@ export default function Sidebar({ isOpen, toggleSidebar }: { isOpen: boolean; to Messages ++++ Change Role for{' '} + + {user.firstName} {user.lastName} + +
+Current Role: {user.Role.name}
++ + +++ + +++ + `flex items-center py-2.5 px-4 rounded transition duration-200 hover:bg-[#E5E7EB] ${ + isActive ? 'bg-skyBlue text-skyBlueText hover:bg-skyBlue' : 'text-[#8F8183]' + }` + } + > + ++ Users + React.ReactNode; +} + +interface TableProps { + data: any[]; + columns: Column[]; + itemsPerPage: number; +} + +const getInitials = (firstName: string, lastName: string) => + `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase(); + +const getRandomColor = () => { + const letters = '0123456789ABCDEF'; + let color = '#'; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +}; + +const Table: React.FC = ({ data, columns, itemsPerPage }) => { + const [currentPage, setCurrentPage] = useState(1); + const [sortColumn, setSortColumn] = useState (null); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc'); + const [searchTerm, setSearchTerm] = useState(''); + + const filteredData = useMemo( + () => + data.filter(item => + columns.some(column => String(item[column.key]).toLowerCase().includes(searchTerm.toLowerCase())) + ), + [data, columns, searchTerm] + ); + + const sortedData = useMemo(() => { + if (!sortColumn) return filteredData; + return [...filteredData].sort((a, b) => { + if (a[sortColumn] < b[sortColumn]) return sortDirection === 'asc' ? -1 : 1; + if (a[sortColumn] > b[sortColumn]) return sortDirection === 'asc' ? 1 : -1; + return 0; + }); + }, [filteredData, sortColumn, sortDirection]); + + const paginatedData = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + return sortedData.slice(startIndex, startIndex + itemsPerPage); + }, [sortedData, currentPage, itemsPerPage]); + + const totalPages = Math.ceil(sortedData.length / itemsPerPage); + + const handleSort = (column: string) => { + if (column === sortColumn) { + setSortDirection(prev => (prev === 'asc' ? 'desc' : 'asc')); + } else { + setSortColumn(column); + setSortDirection('asc'); + } + }; + + const handleSearch = (e: React.ChangeEvent ) => { + setSearchTerm(e.target.value); + setCurrentPage(1); + }; + + const renderCell = (item: any, column: Column) => { + if (column.isImage) { + return item[column.key] ? ( + + ) : ( + + {getInitials(item.firstName, item.lastName)} ++ ); + } + if (column.render) return column.render(item); + return column.key.includes('.') + ? column.key.split('.').reduce((obj, key) => obj && obj[key], item) + : item[column.key]; + }; + + return ( +++ ); +}; + +export default Table; diff --git a/src/components/dashboard/VendorsTable.tsx b/src/components/dashboard/VendorsTable.tsx new file mode 100644 index 0000000..39b6398 --- /dev/null +++ b/src/components/dashboard/VendorsTable.tsx @@ -0,0 +1,159 @@ +import React, { useState, useMemo } from 'react'; + +interface Column { + key: string; + label: string; + isImage?: boolean; + render?: (item: any) => React.ReactNode; +} + +interface TableProps { + data: any[]; + columns: Column[]; + itemsPerPage: number; +} + +const getInitials = (firstName: string, lastName: string) => + `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase(); + +const getRandomColor = () => { + const letters = '0123456789ABCDEF'; + let color = '#'; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +}; + +const Table: React.FC+ +++ +
++ {columns.map(column => ( + + + + {paginatedData.map((item, index) => ( +!column.isImage && handleSort(column.key)} + className={`pl-4 py-4 text-left text-sm font-bold text-[#6B7280] uppercase tracking-wider ${!column.isImage ? 'cursor-pointer' : ''}`} + > + {column.label} + {!column.isImage && sortColumn === column.key && {sortDirection === 'asc' ? ' ▲' : ' ▼'}} + + ))} ++ {columns.map(column => ( + + ))} + ++ {renderCell(item, column)} + + ))} ++++ Showing {(currentPage - 1) * itemsPerPage + 1} to {Math.min(currentPage * itemsPerPage, sortedData.length)} of{' '} + {sortedData.length} entries +++ + ++= ({ data, columns, itemsPerPage }) => { + const [currentPage, setCurrentPage] = useState(1); + const [sortColumn, setSortColumn] = useState (null); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc'); + const [searchTerm, setSearchTerm] = useState(''); + + const filteredData = useMemo( + () => + data.filter(item => + columns.some(column => String(item[column.key]).toLowerCase().includes(searchTerm.toLowerCase())) + ), + [data, columns, searchTerm] + ); + + const sortedData = useMemo(() => { + if (!sortColumn) return filteredData; + return [...filteredData].sort((a, b) => { + if (a[sortColumn] < b[sortColumn]) return sortDirection === 'asc' ? -1 : 1; + if (a[sortColumn] > b[sortColumn]) return sortDirection === 'asc' ? 1 : -1; + return 0; + }); + }, [filteredData, sortColumn, sortDirection]); + + const paginatedData = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + return sortedData.slice(startIndex, startIndex + itemsPerPage); + }, [sortedData, currentPage, itemsPerPage]); + + const totalPages = Math.ceil(sortedData.length / itemsPerPage); + + const handleSort = (column: string) => { + if (column === sortColumn) { + setSortDirection(prev => (prev === 'asc' ? 'desc' : 'asc')); + } else { + setSortColumn(column); + setSortDirection('asc'); + } + }; + + const handleSearch = (e: React.ChangeEvent ) => { + setSearchTerm(e.target.value); + setCurrentPage(1); + }; + + const renderCell = (item: any, column: Column) => { + if (column.isImage) { + return item[column.key] ? ( + + ) : ( + + {getInitials(item.firstName, item.lastName)} ++ ); + } + if (column.render) return column.render(item); + return column.key.includes('.') + ? column.key.split('.').reduce((obj, key) => obj && obj[key], item) + : item[column.key]; + }; + + return ( +++ ); +}; + +export default Table; diff --git a/src/pages/NotFoundPage.tsx b/src/pages/NotFoundPage.tsx new file mode 100644 index 0000000..47ea344 --- /dev/null +++ b/src/pages/NotFoundPage.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Link, useNavigate } from 'react-router-dom'; +import photo404 from '../assets/404_page.png'; +import { FaHome, FaArrowLeft } from 'react-icons/fa'; + +const NotFoundPage: React.FC = () => { + const navigate = useNavigate(); + + return ( ++ +++ +
++ {columns.map(column => ( + + + + {paginatedData.map((item, index) => ( +!column.isImage && handleSort(column.key)} + className={`pl-4 py-4 text-left text-sm font-bold text-[#6B7280] uppercase tracking-wider ${!column.isImage ? 'cursor-pointer' : ''}`} + > + {column.label} + {!column.isImage && sortColumn === column.key && {sortDirection === 'asc' ? ' ▲' : ' ▼'}} + + ))} ++ {columns.map(column => ( + + ))} + ++ {renderCell(item, column)} + + ))} ++++ Showing {(currentPage - 1) * itemsPerPage + 1} to {Math.min(currentPage * itemsPerPage, sortedData.length)} of{' '} + {sortedData.length} entries +++ + ++++ ); +}; + +export default NotFoundPage; diff --git a/src/pages/admin/Sellers.tsx b/src/pages/admin/Sellers.tsx index 3651d71..f8bee62 100644 --- a/src/pages/admin/Sellers.tsx +++ b/src/pages/admin/Sellers.tsx @@ -1,3 +1,112 @@ -export default function Sellers() { - return+ + +Not Found
++ Oops! ... Looks like this page does not exist in MAVERICKS +
++ ++{/* Add Home icon */} + Go Home + + + Sellers; -} +// src/pages/admin/Sellers.tsx +import React, { useState, useEffect } from 'react'; +import Table from '../../components/dashboard/VendorsTable'; +import { BiLoader } from 'react-icons/bi'; +import { useGetRolesQuery } from '../../services/roleApi'; +import { useGetSellersQuery, useUpdateUserRoleMutation } from '../../services/userApi'; +import ConfirmDisableModal from '../../components/dashboard/ConfirmDisableModal'; +import { User as Seller } from '../../types/Types'; + +const Sellers: React.FC = () => { + const { + data: sellersData, + isLoading: sellersLoading, + isError: sellersError, + refetch: refetchSellers, + } = useGetSellersQuery(undefined, { + pollingInterval: 30000, + }); + const { data: rolesData, isLoading: rolesLoading, isError: rolesError } = useGetRolesQuery(); + const [updateUserRole] = useUpdateUserRoleMutation(); + + const [selectedSeller, setSelectedSeller] = useState(null); + + const loading = sellersLoading || rolesLoading; + const error = sellersError || rolesError; + + const sellers = sellersData?.message || []; + const roles = rolesData?.data || []; + + useEffect(() => { + refetchSellers(); + }, [refetchSellers]); + + const handleOpenModal = (seller: Seller) => { + setSelectedSeller(seller); + }; + + const handleCloseModal = () => { + setSelectedSeller(null); + }; + + const handleDisableSeller = async () => { + if (selectedSeller) { + try { + const buyerRole = roles.find(role => role.name.toLowerCase() === 'buyer'); + if (!buyerRole) { + console.error('Buyer role not found'); + return; + } + await updateUserRole({ userId: selectedSeller.id, roleId: buyerRole.id }).unwrap(); + refetchSellers(); + handleCloseModal(); + } catch (error) { + console.error('Failed to disable seller:', error); + } + } + }; + + const columns = [ + { key: 'photoUrl', label: 'Photo', isImage: true, sortable: false }, + { key: 'firstName', label: 'First Name', sortable: true }, + { key: 'lastName', label: 'Last Name', sortable: true }, + { key: 'email', label: 'Email', sortable: true }, + { key: 'phoneNumber', label: 'Phone', sortable: true }, + { key: 'gender', label: 'Gender', sortable: true }, + { + key: 'Role.name', + label: 'Role', + render: (seller: Seller) => seller.Role.name, + sortable: false, + }, + { + key: 'action', + label: 'Action', + render: (seller: Seller) => ( + + ), + sortable: false, + }, + ]; + + if (loading) + return ( + ++ ); + if (error) { + return+ Error fetching data. Please try again.; + } + + return ( +++ ); +}; + +export default Sellers; diff --git a/src/pages/admin/UserManagement.tsx b/src/pages/admin/UserManagement.tsx new file mode 100644 index 0000000..d3d022d --- /dev/null +++ b/src/pages/admin/UserManagement.tsx @@ -0,0 +1,112 @@ +// src/pages/admin/UserManagement.tsx +import React, { useState, useEffect } from 'react'; +import Table from '../../components/dashboard/UsersTable'; +import { BiLoader } from 'react-icons/bi'; +import { useGetRolesQuery } from '../../services/roleApi'; +import { useGetUsersQuery, useUpdateUserRoleMutation } from '../../services/userApi'; +import RoleChangeModal from '../../components/dashboard/RoleChangeModal'; +import { User } from '../../types/Types'; + +const UserManagement: React.FC = () => { + const { data: usersData, isLoading: usersLoading, isError: usersError } = useGetUsersQuery(); + const { data: rolesData, isLoading: rolesLoading, isError: rolesError } = useGetRolesQuery(); + const [updateUserRole] = useUpdateUserRoleMutation(); + + const [users, setUsers] = useStateSeller Management
++ {selectedSeller && ( +
+ )} + ([]); + const [selectedUser, setSelectedUser] = useState (null); + const [isModalOpen, setIsModalOpen] = useState(false); + + useEffect(() => { + if (usersData?.message) { + setUsers(usersData.message); + } + }, [usersData]); + + const loading = usersLoading || rolesLoading; + const error = usersError || rolesError; + + const roles = rolesData?.data || []; + + const handleOpenModal = (user: User) => { + setSelectedUser(user); + setIsModalOpen(true); + }; + + const handleCloseModal = () => { + setSelectedUser(null); + setIsModalOpen(false); + }; + + const handleRoleChange = async (newRoleId: string) => { + if (selectedUser) { + try { + await updateUserRole({ userId: selectedUser.id, roleId: newRoleId }).unwrap(); + setUsers(prevUsers => + prevUsers.map(user => + user.id === selectedUser.id + ? { + ...user, + Role: { ...user.Role, id: newRoleId, name: roles.find(r => r.id === newRoleId)?.name || '' }, + } + : user + ) + ); + handleCloseModal(); + } catch (error) { + console.error('Failed to update user role:', error); + } + } + }; + + const columns = [ + { key: 'photoUrl', label: 'Photo', isImage: true }, + { key: 'firstName', label: 'First Name' }, + { key: 'lastName', label: 'Last Name' }, + { key: 'email', label: 'Email' }, + { key: 'phoneNumber', label: 'Phone' }, + { key: 'gender', label: 'Gender' }, + { + key: 'role', + label: 'Role', + render: (user: User) => user.Role.name + }, + { + key: 'action', + label: 'Action', + render: (user: User) => ( + + ), + }, + ]; + + if (loading) + return ( + ++ ); + if (error) { + return+ Error fetching data. Please try again.; + } + + return ( +++ ); +}; + +export default UserManagement; diff --git a/src/services/roleApi.ts b/src/services/roleApi.ts new file mode 100644 index 0000000..21c4f52 --- /dev/null +++ b/src/services/roleApi.ts @@ -0,0 +1,18 @@ +import { mavericksApi } from '.'; +import { Role } from '../types/Types'; + +export const roleApi = mavericksApi.injectEndpoints({ + endpoints: builder => ({ + getRoles: builder.query<{ data: Role[] }, void>({ + query: () => ({ + url: 'roles', + headers: { + Authorization: `Bearer ${localStorage.getItem('token')}`, + }, + }), + }), + }), + overrideExisting: false, +}); + +export const { useGetRolesQuery } = roleApi; diff --git a/src/services/userApi.ts b/src/services/userApi.ts index 7072975..b6b8c74 100644 --- a/src/services/userApi.ts +++ b/src/services/userApi.ts @@ -1,4 +1,5 @@ import { mavericksApi } from '.'; +import { User } from '../types/Types'; export const userApi = mavericksApi.injectEndpoints({ endpoints: builder => ({ @@ -7,8 +8,35 @@ export const userApi = mavericksApi.injectEndpoints({ url: `users/user/${id}`, }), }), + getUsers: builder.query<{ message: User[] }, void>({ + query: () => ({ + url: 'users', + headers: { + Authorization: `Bearer ${localStorage.getItem('token')}`, + }, + }), + }), + getSellers: builder.query({ + query: () => ({ + url: 'users/role/seller', + headers: { + Authorization: localStorage.getItem('token') || '', + }, + }), + }), + updateUserRole: builder.mutationUser Management
++
+ ({ + query: ({ userId, roleId }) => ({ + url: `users/role/${userId}`, + method: 'PUT', + headers: { + 'Authorization': `Bearer ${localStorage.getItem('token')}`, + 'Content-Type': 'application/json', + }, + body: { roleId }, + }), + }), }), overrideExisting: false, }); -export const { useGetUserByIdQuery } = userApi; +export const { useGetUserByIdQuery, useGetUsersQuery,useGetSellersQuery, useUpdateUserRoleMutation } = userApi; diff --git a/src/types/Types.ts b/src/types/Types.ts index 25aeaa0..ec6df7f 100644 --- a/src/types/Types.ts +++ b/src/types/Types.ts @@ -54,3 +54,21 @@ export interface NotificationProps { updatedAt: string; isRead: boolean; } + +export interface User { + id: string; + firstName: string; + lastName: string; + email: string; + phoneNumber: string; + photoUrl: string | null; + gender: string; + Role: { + name: string; + }; +}; + +export interface Role { + id: string; + name: string; +} \ No newline at end of file