!twZhZb?!G;hbvy!mE}w| z&&?_yP%Z9O*{G)Ce|I$-|L3cD_}^c(cvxjbH~jxg&GxXG{7sV7T+Im#kkeI*r&Zpi zrg~ZpZ%yhp&tTb2%>${QYVoqls+#I$Rn8TXq(G=^Qgc1ca%nXWB~hxy+bYjfQ}MsJ zn(b{>l5Mdng3G9ec$noKs>R1@a)ui;m6ZZBs x2bAs zpw;lIjJho_SP8|9Cbey;6DYC-S(Ou@2@?dF6+6TNGJ#RewV0JAz`Qm75R|0@s}HQO zW`cddNS2M7;cZsz5!|TD1{Iu!UJmLAOE3o7VztUu)l{ohnNePnJhjSX%^kpeHFmP* zQ(z<*mWEpBRRgQC5mTWPXfg>@Y%0L_G!8UoiU1a@j)E1JQ4aLNYR1?8wm_N!(T2#> z070rD8BH039Pbku *;eDI>ynSb0{wxJ*`YbGZv|FJ z!!84BfHIS&LS0whjzmKuC#b1St;%}PsNaRiHx2Jx)i+Ip 9HhQDfQZdJxsktBD}U}qn*vI!Vz1+2bVexT-oqf1pu>JJ(;9p-Nf zga)p#HYpwh 2?j&)tsVQO)kYol>^KOG wVE2&mZbJtB$|_-`wO{N8qKSYh)$;A`MI6QX)(lPQ&-QmK(3Ki zV;XWHTJ8wXAsD)eP(T^0RyHF)cO*Yo3`1;HM|BFc(J~Y~ryv)kRoI`Ov+>YrA;|F{ z`gMLTOUu1C2ND}Ebi S#8eDG99bO|=q!=lz$v-=3jX(I%` zHys1kQj5fnh%;hTG3~kns|PL{GPj8V<5BYza{0oQGH@2MJcc3Eth50p$^y*F1YqQ- zh$%b#ZGq6hB60=z+k#9QaR2EEjAUp*O`fCXb+;l!SbA8M3Vysq^Jh~hVEz VQRmS7CK9r^$14}(-c@EltG)eX0(#sizMXXzfrY> zS>^U>D*k_?X5;@oH80Gn{DO%}a}_I$)hvIlruMeV=hf`qR#Od3=!UdBD$&SMw=i1~ zLw*9rdyJVZKUK5)SWVA@B&m&>( oS8M$yRcMrKfTCPP4 zJ-0ePSGc7lg=wXc`MKQuT%}gD^`O>L^K++>>#ot G zGq6Fxuw?J^S5srGN=iFEdl0NJm(~I!FOjrJd>fdjHWNMC>+^-;=m22kJ$yl2sOH65 z mPfrma>mBY-Y4#3>i97}*H9l18@s1bp-$k1fPgn}E|bmW30a&^TY7%e~? zO9Do!Kyh#$7o1wKR_r_RGAtNP%}Q%vm~rI(z0JxrU_3Zby+gogqCrYCvtsDX)x$m$ zn+I<-dx%x(2O4Rl?JAX2Se6V_M3oUHZUCc+1%B*slDlG&0ai$*)e;Csm>Na=FW!wS zWT)o#G%J09VFc65Y1MuNhS7$Q3@Bvi&eh{_r~xoflwpM%Y*rG0`Dz&L621e5X+;|_ zlsyNAS%F ?^8U(DZw&%Kt zTzypGD|k7yO_o5UzTj^Qgxce>e+CA>ri}x1DcP5IR@*Mg9n|bpt1=HX8p+}s$5UVk z1L!5fxhW}}7Ejvb?L|(=sSi03d=G{NA5!T~JJsQK+60XJgnQH@U}Rn_%mHRoLO)6B zMvkl8Mh-!XE(S0pY9#jn>|+tAZvaDBfV_;8{x(q*(1H+Yae%08{LsrFvniV}js7v8 zPMhE+{dx1Ke9+$(2o_fOApF_1i7@qj>i|=+0c6OWApuHH 6RgUrA)lzO z+y_S9s*Ri+tY%NN$|KdhiB@HEA|F$j!fI9uCF!-O!Ir?tF|p^yJRJkf8yJrZKLg{P z$^hp*U;!vAs<~seWFA~#Yee1@V2Cy(1rg*hFscXd=wepn6ke|w)x$MU_7tm}qUKGp znv#do3jBUbfN2ME*sUVgzC#YN7FVnthw=U(n!|ag10$JQ)Hdw_) {(X%u9}CE z4(WV4U}Q1*7XYKkjl~L*4gm|)F!+F}P=?lX97;4)Ewio4*TAVAj02XD&A_n#fJWpm zuYuJErr8%ul4TCAv&QJsC`|7JCVUv4@evrDk@^$sZ#$Nog$v#QjFu1W6h*lq$`D^M z_?5?T6||L4i3LXH 2J1dRYj^|bAQvJ4o-2knGFc?yh7 zpiLgdeS%((CSIg!nQv8=f=0FZoW2B%%z$k!=6ltNoFBst<8~LAHmu5gU?dq4Zlk{~ z5L)buXxDJ1C&AZ&p(C(tI54s$H^3HPWH)U=Q$C0?%qT=(|H*nFr%p}+Mm~-mm5;wI zkj6l;$%n{dQ@AxWOUaGZyhT=JIcUAW0Y`vM-UDj~j5|W;R6Yg}1-HlmMz+)zdjwj` z607nNw2*xM2Gg*=1IFVzE-98+<%_CisZ}XAUFRcL?Fx*vg5%aV8x~Gix6KMxj)O=& z @;|roLYoXp2lkT@U3FFz%GpLx*o9 z$&9k%+ODaMn) tZX!qV9DN*Ymfcm$3ac_K6Zc?2<5su{tPLG};tjx^#EdLuCEEwoKD Meu$GjQmgwr>2ml#82mDDaa9>U(jX)BO9P^h&_du=_5unJp`C1$}oFK zPhg}4j~d&6QI9ZAaMgFfXw*t*^Q_NuU0+OD(?VdL+9G!txptZa%vY1sx3C^*gqV}J z(Q29l9DAwy0m>facz VW}C{TWx> zpy6y1yk4t#liJ)>#sec&wUt`VRa3WEm3phWiW*HB2FwZ$@MDkp3t?)|-~i #12*rN<9^Z;uNYEToIoJkTD1Mje11 z{NP_}xiF4}0pmd>V}!pA5SXZGfKuv5K2@>yjxj48fKi`qwc(r%jKpcng?v=a%eE?p zbv#gDL4m%Jz=E^}L$EJhu4Zoo$9inVInCXyj0Z+;1}kC^F94&s4VxhJ*s0mut%j%# zYJHDjd4+2E6?@GMoE-xM@s&1m<#3Gwuk0-_&69B~W67~9r8aR6KBGDSBTvN&iq4Dy zMm 0tufp>PELZ>SH%srCpZpG8D1r z03%at*FEwvH8t0&l;5hyrQBeDTOiaKzT|hz))zFIpx1zPLm2{)FUD}2t{AP9%Yl(# z&7h_Wz_9zoHBYbYdeEX!v;Y{FK!YRlnLGUu_4hojMBp)Md!wbOB-bIC6oSRG3!w zRP*-YaxX`3mpXJASTJuFSj8ROAedPQ6TN_S;kAKn2F5icLw*F-hS!6?gzl829>Cz8 z=w~jlUc8>wY;fMC*54nD+d`@Pt?~^ud%sl)+LNyWx-k|QnGCLqE%|m}!CK{9e=MrN zXk4{estnkx3nr880oGJ2qmI wN8s9nf{f@R|~Vwboj3JgCd1K}!KfL!zCVm^Kln z1*!+g`D%2U1(gqdf|)u4!+IGIpiD)M4=DPKz-T#&Bhth9!-T#j0Bfx2L{|A3SW8VR zS?ohTr##iH4E&wPceotRY__V|$E>FJpmot!=8i|uYt4zKBPZMdn%w{<`V5!yQ1g!C z*4R *KLd0WH?Sc5(;izkfV91MGR#w zu%^JY8&S$dU?c%$=uhnv`JBL(0&ACF?-4LDesEXwN#1j9O*Ul!!zB~i%0Z5M6v-=j zD&I2@$GQTezG0O_Pgelzph>66@FE|hQEYZvZwr`dCa~U`^asf0Pf$~nGnf`?(Eb2r zDRSJ?(5mS+Fn)Mk>#ROn7!gw}uz}hI-+kn`me}hkVdo?%QqzP+F&7w(Fzka-H2uM6 zPYD&FT?rBxU(8Z~ktMbGCT~|Q=e7I7=W#K1p4$=oNQ5HKKRJf@jmew<%onw=)L|d- z9kBMAjEps~0x+8PJiIl!z%fKa?C3Lr)khiHUgmEL#0v;wT~BN{1S6KXF=nOHMcz3y zfFW27%nzLQYVKGw-MP8wT*NHx$u9Zpgr9#|r(PZAXnRTThTI0%BEWpWj}YF|Y&ToS z5VXswn-H`;BNa&5b}?A#c3H274VGcaWwrjLV8g}B>Ii_USJZ8nf|b=*^6iXUc&4jr z{ma3I=2z7b0Q0Y^+b#zyXRq=z0?izzlGn(!b9x0RvykfwJ+OT{YBt>khI9JC0S2$@ z>YFRUhE3Pi`d5RMx7Rrrv_)S#+~9|32z6u3hNCysH&=rVMQ;*Ny58gi3G-pwIulqk z_5IZV!&wwx3pP03`l PLRqw3!EU8cM~{4YN!Wb z5x_`6{}dAc0KpdxNG!27X%fCFEJ;bgh+(LJse)k?pa b=Sz_4?Ls-VzDMwV0ruAf?*jwz9Kt_p=yy?pAmK*^PLR|;Cg5=aPXH3% zDM0#s3W@*pPjX(J{|!joN&Yt={ck|}-+-jWiT`&2DQkWS`Ro0y{k&>bxI1$BUmtI* znf=x2DWj*_Utid`%C$e+gtR^Q;|i|?bIqDH_oqGnc|w4TYf7VEpWb;8`=D_5`=@>i zI-TiqCY!#uFH0Xvd;o01lyh=dw)LEB$70XPt>k7bn+OB{0KxeW5L&S4KR_sd9)u%A zXvG}QgKz+Zw3}^~PJGG6nd0->j*Y$HJFeD`nR3wfEwdKn?QUB0VBu%V_Dv58=lngx zb-{r1FMReEUg&+_rbl2e`!YkKZWfPseEx|h^jl8-V-vVrd0Kzpn$C55EqXny*HXDi z)WCtEmemQnTVL2VyvJkz=t;q^ep~s{@p_tb>8@>8wlL=$y41aA;iO(W=T_eT?Wt9c zEcQ>iJahXK`nF}Me?s4y7tn!AL}<@yT>#+^B22#kLPvI<2$L>?5OfiQ&TR5U5d1HJ z@PG(indK7x-66u_OCWS-cZo3XG6 Wz|th)k2AC^ai z)mK3Xy9z=$TXPkJZr4Dty9Po(*8Lg?w%0+(Awm>Wu7j|Z2(i~e7{IcLFz^Nl&No1a zX3;l5D1Q@#BSaX?9B+bffC!^*f)L9N5@Gl)5ZrEo5YJL?fl%`=5H1m62&?rM2!9Y^ z`d=U 2SOUlBf{$YAcWlqA%m^C4??%UL9qK9gt4sq-yqmN03nA6 z F` zJ49Ig421dYE)nKE2O;!12n*T#=O8qH0m6GCEM_fUfbg0K>t2Acl;sg&^-B=KUV^Zk zt$7JTw^tz8y#iqc>;4J^+t(oE5Md=#UW2fe2(hn0SjDo5Ffb1U=R6SBu;@Gx%D(~O z2ocsY$2TAxAi}6OAgp5ti7@;vrgP7Az2}^ZA7;)dbtHMwg~$7pC-1ttebqj V>$SO#;S!GMzVkI-Rpd_Fl|t zj4EQA>hw+8>)ejNJPN(}sZl`?gz3w#@r>Tk@PrM@lUi>^Qnd+~fyOo?D*xJb$$I zTC0o=0 zO^yybr&>q%u9CXG@r&4n&l~i4bvS5#=^|c7hPadt@*dp!&mGeu4=w#U*_w2xaO Yz9TnBJN9nc4KMYC!!)-_1Hzm4laBFb3=EjA?-8-~vIP7=F+HMYW z)`VYP)T^~`*YSf~vt!?dJ5=0stZwexEAD-JCM18NUhbS026(N(U^i!-p_RO6P99KO zBTO461K-Ei$RKPbf}H_`{j9qIgn>37 MHgmjO*QZYr+KMp%Bs=6 z@ieS9b^kWMt0ee$nTnimtmEc;30O>+Dk>?FEG3O(vA%}2%6ITxt%z0jGYnRDxs~BU z{m{_YKVyUntn|*nb*BG+XbsqXfS_^^+!CjJTJHyFwJ!#v_I{k**^@;yH68U|@NjS9 z*Phz1d01vO!&<6l(tfQ&s1Koz`j2xyt)bC~#f4Z5&2O@}28Ie{KlP8Oq==O0m`Le% z*5U?+K~retUleI@oLmPtPR_EDhYbx`r^ALaY3R51S%or~LAx9-DQK$&jjqK@3ECP# zqw91BLHj|_=qkF3psfXs>e2B+Z9!WP8ve910=fjpCr#Q23N=heNZZAA_$EQ4lex8m zwpq~VFzq!-!RIGID~kL(LHk+IsAC@mZHu5`sz{TCyk9gL4qNEBahf1zfk;}HK%$2q z(Px{eY>)hTLEA29WU1MpQT1Oz!=Gj;Cir#;zS5wt5PTH8sl#QEzDpB~y9BW;h^quG zSJ2>G68-R#KDz~tOg~%D_6Qmx5S`|0pS_^rkACRI&td?66MPkr-z(Zk+b@U+P|^>A zctFr9f;K?V4hotxXzxVBhXkz>X#GGV1rCFTKYGH5G*Ivz5qz$oMGC&7oR%h425~qN zedw`QRHq8kP$J+%PD`|^NI6KP=m|ml3i&uFNQ#~mv}(wwB2S-Ff>s@QS bg
+AqX}&pFVjSo3Jo3ZL_WuMYCRYZOWP6ErehU8D@EfX^kt z=Z5?^LAy-nXe7rSX^bFV5i~mG9V=*81 Tw8CPcV>)UI@m9$h#m<7J4aYjgWUlo<6Sx z4a=xRWM;QD7o@O(+SzJV9#;T65&dYHtLs8Tp?D2$}7zAT~$diaeQ(q8bTofm9e7 z>iK)n@JDw&rHaUqQXd6hE94s?PYRG(sBT~KWPBpYIq)eGnBwCd?CR^96g`3!J7IXN z(7ER%upVcolZHkibbR_7(tad5Vm*LFM;?2TC`8ja?k`ALNL!Jzk+vbx`R^*EwQTZ9 z!^oC1ke!4y6^Wwm6eK!%reI6=Wdf0ckV+wyMJk8nfK(pI38^BIGm?u T-QL zu6+hIA0s_QdWiH0=`Io-0Ut*C3Hcnr9Y{NorUBnzV(U*E;=JhedJa+p2yKWIg4779 zF;Y{cCP>YYnj_JTB5PLY8ADrxiO!?_+46G+vm2ePk3brU^fl5bq|r!p5}$xH1StwB z1=U+I(;tRcX>@025K;^h-A(F%)DdYE(r6^Q-!cYiEYdin2}qNWCL>KjnuatT=^La> zBo%2k(j26@NDOHn(gLJ~NQ;mbBP~T*W`i%ee2dHqr0 *x_BzrHq&qC*g25$nMfy5wh3@OU}w;qA%!3<13nvRF4C;5CumA8@{Mr(t9k6raYL0fnh)DC5opQS z4fq_1mK0iQjv~<-Mr#|bdAUe*El9frTH$HYrPY5U(t4zINNtcpky<0s3~!3m42dE@ zV nt?=SrVdO;nuat5DHSOmDH`chrPBt3 zK$;9fA| wewt=J zT?y(TH9i7KH#v IqdKJ`#|Lq7lzME@sEuSX5jxPMws)}o;ye<2xURoy30FHQ4uy#jgsr+J!YdapnAfw_W@ z;HTx(Yu%EXc?C{%osaTA sP9nX>F!(4;*RHX@MDzbD-K+2zQH+0EAgW``s0ZFrnUXP!If39 zwm5Kwso0U124~y^xld{gW2RRI4@*7wdfLS<&KuIZZSH4tZLIeuAqdwr`bkagzRp!! zoXdTR5?`+NMi%?Z;OLYCxwx=SpSP;i_x(SHdw{{)-5aV)C)jc@$XD2QfQqz*gsIb8 zzCIXZdbFYw_ l4tO7qA7?A`1G@_ z#&pZ9Sp8>>-3J|)Cb2zvhCa$PY-Hd_=|@?eH>iCB=i7!dg*8)tFtWaH4Bk#fu`jX* zOaJe`&N}| Fpnhp-^`dc{AWj3Uvv78MqcwR8CFr$OBucSX2x^IhqMXOBi z{HG>g^A}zbEc(NuuYEYOzNW9;JWXR787|vV=EB(KcW9y%J7I5hl%3{W!T%a;NGSk6 z=KLNCHe%-YF#jSp7?{&aj1i8B(g&C7n{%n|$*~3*M(}gTh1`0!6byd)gKh70cy4O6 zr-x?&!!A^%5w5qtSMjBVL#`H-9AXbhw*IW#-#7pHV#m()Fq$s=GOPRns@!D(02TFz z?M||uO}&4k_^1NDk40F*2Sa&3{qelF%6}DJ`C5Gc0uKEFzDL;UW8b|gS-7C2GRuK* zC;f@P#qv^0gmzoa3K%Tx2`Ry? ?UjE=0YY^)%cW+P>zqm%wX=A^6{ z8Nr6i!SEal4@SHyJ0Kf JFWW}PWn@{-^a)s6RI?(`Q!_+aO)W? z$ON0{Pb1$Dz4pxSrFWFmH1c%EoLs|(fC0Bm> q {1~ZbOb9|*f_vRe@gkT3e^g2@6#7^8S%}_9ZSYgHa!%oq_K5{ zp^E;DbjMPqVmehVaa!;}l?Ch?806OMErG7AtgSKBNq=;DgR)oV)!%80nXNCAK5Ue& zv57JaM~^s9P0wV9Z6RKNwrKaA4^4|MKd34AVa!GBBN+Vjr>8IZVb=X}WlxR=0}TiC z)Ss`uI`u=m&oZYF8*L4t5ITm1Dv +w2Y7 UD zV$h$DdA7JEu2k7pEx_Of#{tJscB+Wc=f4;{l~pck93bZVmqG~H9U9eQIYlwxB1)Lq z6T)~bVP6$9wm~FFDh5a6afO!%vE`W64uNAc3$x2_Nsm9T?Tk&U>ap(&-4M21#lnlD z8~Q`!zj?WG**0h681&QI9VWx@u?@xHH?Gxr6rH+sgpbdrGx1;$>-QIeBaH^C)?x39 z8$+RSs}ksvrhggswuDikxLC4~*84L|#yabyKjePm!EW!WRt E?@RsqDKEVF`<#u+n4 z%M;&PlsM^+@(+5pYttcnzk$%jOc5HFAM6Sk{Pbu0*Y;@s?sd;HPc;V3LG`EnCp&uI zdegM{c9i(Idn0a3C7GKOWbearM$uo15B%+3`vqVaUC-T{>b7IyV8FG*NGG`55O&bX z*aY7=DpAo`8Q%c%stC BsC!*B{xfUfujn zk1KDZ4KjM+MMfRT+B&0lCd>52&SH!+R_jM>v9oc2;hlvQs$}%$q8wR=O4x^#U=u5$ zc~`c*lCh3cE!^m+4C(q4TlJ?X+RH7O?4otS$;J4@k1l#?o0RF%V|w*1L6$P|I@Bx; z$}T`M!sx9jNeBGTc$cBM=}im6?<~X>E!ndn6R{nK#VfFxuCTcNW`N6=cP?J*onx_) z5mmitZ=k 0z_#cMS~+7>crMq=O54OME`K8A2;nM7eiL370Z23;3Ebk1EhXe?`NAm+3BFf7e+p zV9;OUu*Au8+o`+#dK8q5W1~>jNq_5uokQchOV$tFU%;@DZ32V*8#@e8QGaX1iRJdr zdu!fpTfq0hIJc_N+i7iM{ wd3|O >rug|0xFib=VHV5g2l21m)9DQaeC|Svzzk=*Ng5j@_YPK&LHQrmmaE-MGgDkPZ z#HYVaqWyx04;w5y@u7e(m@Nf^U+<>c{oM4aGv6=Ds#@}10Yf@UszQg?z2}eiU3BPU zLCFgC09C#8H(JcfsMvk<&=)le81$D%w8-3Y;qr;G4{$-!hSti;p~ea}*n7vb&ebq8 z__ZxtR?X-x4`;`Sw3ivHW3e9223I#aDiz!D4bosXy}Hq-wEotKuQPLd6yD{!*dRNw zQ`L=~o%Ht&9RH!^%|T^j=2L8-3xC|{V2x@Rx4<3J>cJ?*S?QW+B!iVeq`+4I!)pSp zWFrY|W^!#~>B9V&Wf#lvg!S|{KGdq?vvs!l4EA*T&iFQ)TG!}kc;A_QsA(+kq`xv^ z>HK;xzB^O%S1?k<$13m3ylO#uC)SEUej^n2R H8)wO;AFy8&a*Tq&vjjW-fJfsg5wGQ*B^<*>WPbWNm9>>!QCMqgndnAICHg zih&GqlC+tf06Y7oHsU4E<8a~rCld0d6Q3?tYq^{abkO>ePjAV#qg5yU ;B zMMIi)|7=KRhdt2H=k0yT^^dbqa{X(4`D2N9&Y%7;{X&230E-;QSK@O+^!vYh{xLF) z7@S7o{9>p}mmQTac^s=~kj>aZ(-iH&oW0Os*9gAC+D>j%_{xfJg9;oqg0%;OpZ-Ry z$9qR5EIRl5DTD0UPx~%H{u^LE^Ksgz!09yK6$TY%5`L|XWtl?Sd=e(>#sa*divF6D zi}jkX|6%ROYEVVY<_j#|8<(>+BDt>dZqFv)&wX*Cz(Ks(6G)IlSWzDcY6m`iS1G;L z{Ef9d{N(__2gUj@D>1}_!5$22?WT^Ic&)34V8E4i8nc^(**VPzvs1*YD=Zgv40-+8 zMIU2%oyrTH{<%Rh$hB$K;j@%A@ fqe=)g2?KmznEo=Tip+XQaWBT$l^R2-!|Ale0y12Gx+ou zx76I1bkyy}*>)7E!HEw4#oiO&bGF JW=TTvudCcKYI{G5gOUjB zLc0EVf0xCEtG=avz73_Z?Z!UQ%+(ZH(82>{IB+m}N}rYfm%e AJ<0|N)MXyDt z1k3+utIy?sCXv}%j1`<(;47ZA>0GpV>NKxnrjpof(m4t&5yXNl@XSqMpxtQAa?g85 z6zO`mz~ge*P7C^MX6G#!Uj2 ~UgH|7`w z1sk$ZwBy%mC_gMN)N23IAOCzbvP?evKPN`P&b>2Rh^kJJs7iBiNamiz>U9UCmdT$v zS|5C{k{W~2Qhrz5SbM^GkJyr6%uvx=tt8(P`4t>lWvemNfO`W8R%2`3P@)bOBR610 z8)){b*1&koNq_ZDgJm%X9bd=1z%b$hfll1gS&0xRt-ofa|9R`?&Tjs<3^JB5e>$kz z#2SSd>r_24ipTGN-Y2n_ucL&{q2gF3B+1j*S`w(g=jC!`$5KUtiW{`4 gJ?Or5e|e>*byR)W49ZD?;JbP-dKV8H3n%mYugx+P`pVfy-S7WCtRNV z1by|>l)Y>*@eO4kTL2tqCkVU3?xPlFf=d%r_DJV9G wxKv>a| z*t+JBFp=$V4s|QCw}c&IWm{nTZO;z308!YrB6DmB%)&xj!twMs5&iu-;!>Z|w!V-k zHe07z1{kn!!nl*DEmTX$h+xK6#ya>Vf=4SHDNJJRTY)8$y>AO3#*NPuKmCP8*Ct&^ z-qhw0-^|e|rKG<*C^Ku%p6DuGlM3e0Huiwzoo6|%;Z?4!jioIA^L+Z}l(d)gX3^b9 zT=Y20-B~UjbAKin=OSM1a0c;TL^J15T;AyKO7gOPSMBSuB`at~$K=aDJr^DStdak? zLs~HNxeExLzQ7k8L^m@$@zwY+%ql0>IXpn_th?~ffX?MxqIp`haq@DGWwybXc(Q#2 z_#qUtYYS()%iJ&&PWGbe)X3SJe*N>{6^i28T@WdRh0|C~XCvF9>Svm>>unKIMW6U6 z3RC?bL^UBv3vOi!X)}!vqYx4FU#u+x<3Ddc+shy3@nyFi^J|aE)t8NJk5KUM!=eS9 zP Q|>ueiD&yLVx?+wBhv567a%&*<=TzF6>ygCe%L1N>z)+fG&W_dz+WNxQQC z_7+K0#dMp?9ub3hqf~nLwN>xgjUP%Eo;ZS|K#;}ybT*b_mX1a bu2u{hnv(jVCtadqHKuD={Y_Y7 zH%1++ZD~vQj<6k}@KuOi>V(D`u#%l&t6NL>qVuiK*)~g8=9vW_Tv*eSY_+a4lv>B$ zf*t#3k1o)rGi%WWrvWF}Cc+-G!(C7o%02?~>;4^AvHOCP4{H@4@fs58_7@~Zp`;XI z)T_Yr*08cWpW;>x&I!pT!&qon810|iMD1RV4-O2xRF(k-c|BX$6;{{=L3HT1j~(j@ z-A*&-ZYaFP%-s-r9 +Ft #+|&%F zIsOh-xjXDJ3FnD)Up%)|z>7YuXOU09qO{x=XYt)3NIS7E MT!#<1>ElK^yZtnY+{gQa>iLryA;~!5}x)*K&_E^u?;7AtU3;g08 zd+7)6`u>=*@$%m`av~ULFb=Xgy|BjVFaH|%am$jo<;%v27Gdr{_P!VV;@U=jXsmrB zA{6s>`2@_gIblW*r6o>->7HM4b|efIDavk#!DY3>W=Hw|!S_X+PHg6h$+XKG7_4eqhiv@f$nM)t&upSJqU^sfA<*>z$ zM-CM*92F&x+IAh-ZtNqepyVNoMOCMgKl4+{Lsim7JaZd1wt&HxEe8WOPTTw7dk*Ed z@UwypR<$qY@>w>dFGlhfsN_5K*-D`D1$Lq@s?=lm`x^0v2Ua5-7d@t}tXDX$Nc1;V zl`X%xZaKpd`kDjX ciO_Uf4W zu%P5NyM(Is^tWd ejC!Npu{zs)s28&`a9nu10!~N zj=n^v6|~5r?gsXxKkhsrx0PLsFd~}JqOHFhE}_BKYj>pu6faN){7LA(g@wccXm#lO zJQ GWNPiYvz;l}!SWvP1<6q~TwW+>sG7t2evLzwzuAK*-p#Lv0{y&>U}ACo zp@xNxjE1^jwz2-YyYkg WL-(Fg3$@j2<=1p@io9@p^yDZ4Q^^ zyE)B`>#(qa5cHJ&=KwhA?}IDeVD3GqksaxKG~{G(rw;52)e2`BLyYB2*wpZm#Sy+6 z*=Gi87L5oftTm67pfTn{=%l}-u1<&SrR}PZXrU>ooo1|O@2PSQEBQ6R0p>LbYo`9L zyYk}?%-_*%%?;5fTom79xf!_qsa=OWV^>n}oi{&8-p#}Qc?afRD!o6g!E|K>7oE(G z48kB6-OYB5z#wyvH8}2O6$it$tD{~y7^rGm(^}8|cBOAt(6u+Z8pzthwf#cDKtW^V zincAo*Z)4SKyWXVkZo5#9X_$!{K{Ec3D$K_=^$H-s!spn7qHq8c7mqOSazTI7C;a! zBN^ZADfOq#^gvAz9lql7-UZ|9v`6UhxR}GBfhXUD7U*!2EltE12K}+Q{13kfmEBp% zcvK&q!*@1?7iIolb?jf?3i;@xW^ytm@}Vp!7CKoNxs;Rs#ze{TeCW5$rj8VK;E39A zIy#lv$9rFP#_-A?&L6ofbi&jg$#z1J-#9RoM6Zfo54hJ#&9u`PU> = 94AEpI5ooy^t#I z!g!bt&zUh1>zurs`6n8^4Q2MRm_*D2{SBC>zF*#{oe#c*mmfkj7YoIde~<{l`WrGo zgw5=F|76p1;1i*N+fj4@b}X=*wkQcRe@YkK(Tat61edT9zATxHa3TVOrpPA|FgF=X zyNEIQaX^2wr*ypC-uKOJ=wSn2D-bKr2KFEIbf?!B08Lo_h;fZ+Ez}kXp_&*uKS`{Z z1q(#MqN>}1J1UDDhEe@I_={n8J;sg>!}_SVAr>O7`=p${_7sHte=I4y1rghH9~O#> z2%YbipIKU0aUNTqilD2%K-8|>>mHA%U8R#I5k-ZjB8occZxkJR?3?AS+n&bl8EwUZ ze~n~8Bj6|cD@gC!^{bkAzVEvNe-a+>smGT!`5{7y0L=yH4)m{VpDQHn!B&sdCb>4F zKdo9`ccNpg4i=e;Ukol<$kq1-+MM^Kt;%N#V|ltptCVn5-UeT@zD)eLB^`o44+;4m z^_kvI>#>5<`V+h0*UFjUJ9fj6v=PPPAXE^m=jV Pm>Ehe3|TzpxE*iga0`Bsm!me=3+s=p)^l5wH# z?#VWW;pEhFg3%U^Qeq62h^uc56~u*ut$yLaf a f0%ui+YSyfMNVKi=@ne`oGzHpFQRw_%&U#wt$wYjpK@&uX34zAMHr#WYK^ tKhy}m%;F|sNz-55JIdSLWp`;~6-^24YslI)Jl(h5KEdeI?ms0(Ug4640G5Ho z`vKwM2ff=UkU*P5vyU`haAcL=ck%e~5BiahmqnU&g#}N AV2*zO?0~)e4pnJi z^FjQsB)GTX*VB(|aayY1!}Vl4Ct_;w`x8$3D}?9o34ioW*BQTQCeV&L`CVgQ{awR* z*AHu0N^Xp;8qVry8>;;_n`XNH!y0>e@HISI6% 7P)>*{zOIO&$*(7E`>GQO8@0k;Rf&(f!(b!h!_!&Tm+Q^T`LO~nr;it}~V zEiP(!vb)*L{H7Uev%%AhRps7UGo~5sHnF}ljD^^{8O9Pg$yh$y=*k{gZAxUV4YH|c zL%&jTPaZIWxdqxdu#X`&frfgPte}QAA(dI-t~M@Iw=mn;z{VNB=P6m*rYf@zurXz= t?Pp`LVRBm=*H0MC?Am-|W%kPqqrL3S+TSx)(egGF60&X$u<^A0{{Z0nTRs2) delta 35663 zcmeHwd3;UB`~Nxj=0*-eLPFw7Beo)v$mS+OuGoVhweKPcLKd 3MNN%K&k03Q!n6)-g;IX(_-X`|y4)8i#69#YDI-W#wy z;9a96nE@k#I{`KmbO*cK^Y29Z0jmIN9l)}Hu7WEjHYGI~QqQ8cE9kGvNRm6?PzT=X zP2kjeC8$E>qtpnwYD5%7P#XuK0CD>RC+Qhbq%vT2;G}zVM@gbSEd(T8ZvhhDB{kZv zYSs;83G)!8i79b0X~QJRDx?L1jz3#0nj&d^1ndF`7F%+PPi#zDyfo06 d-V)+y>nt%eESj)LsNg<#PnQ?ZS<536Q#T29Ojf zgk=cEr^Uu3#>B z4^E9AElJbdxPYOFDT9f=8peh!+k8ND#uihJ3+^G{O+Zq-nW`8)v$DZO%`U0Vr6eUJ zCyb0qOS6Ga_Kf!6+@Au{IE)c=>pNU}03fNWcjNEf)y-0`h8R_07SY`-+gPYi_DhRT z8XcdCjA%d~pf+B-fkeRv{iv7H)SBF$vBToyQxj68h+2~5iRvR`Qq$stB`FX%DIA-Y z<}+qkOnP{2&c7RwIyN{ZC2??!cUrvecf&IhV#ztS)R818X$!8)1?c6PKSt{QcnO`R z;cNgdvY)4bu7E^eSC7N{fN&*SdTLN(QadRjN%O$A>K1r+9;#AXO9Y$+NX|7Lkj5xc zzyW~NnJxmh1SG3l0LggX0(uJQ0*F7GBH&A?MEFAiZ*mx5D?$c;wjTsMCg6TRveFI# z^91}<%{0B6^|TRJ=T`xb`g665fm1UHX+D}avH&hUH9jUTE+KWKYao{zlbo3plO8*4 zaB56!e3~R30v!$5$_8<{{Q#-;_#s2$W78$+2jEn0#<+rB(-s$#9`7?GIc*5y9yNFp z1!RYwz{zgo)d+jf`l^Lf)6)_YXljhW2+)j(4B=za2RK=~shVx?snibRHm#;^v9FqS zy&0dzrvPa-?G$jefFB5$35c0(iwAT8j25t&fb|7*6;KxNZd1;GPQY&f5kYL*ILxxG z6oecB#{-fhB?#D4z}5l=3YeObn3yqAk_y{M5?tN3QNUS%m=d;OfS5YAc7Qbi>jTof zDJ$Te)`WMJY{!wo 7Ut& z4{coh;EbU(A29s%=?Z#Xa5ZSc%gKLI xNuDq5Tyn@^(ZCH%&aI`mDz2)$3)_@+8R0q_&?!4CU zo_s`l1Cm$l2A!mI>%~3b0dVpJxi|N@lw>VjNMllCMvlysq)5~w@4Aa}svj!wx`3qZ z-{fW4!l6J76nFuWLCXM=p?dV=>i&!dU4b71q>*3RpYvw{68}&@1V!7$0o-IwfRlm; zfs>prz^ek58^jf>51bVH1oFyDS(5Dz3WyLF!&m4iK&lW9s6`)48j3P8fHcd_3;w~e zyy0trH0!eCxaBed$pQ%i_5mb09RzGDpg&-_EEEhMgVDfe_!zW^j}ab0rn)tR_uw=d zAlzXXZy;f4a!M)&IyN=dClImaU{|i-SAaCY(?huh)+O-zRfluM8;syXSp|?L=?T!Y zDAOAmvcO9~GUa?gGWBnOH1?kYQV*^Od^?~!@Tq`QFD)f8A ?{ z++fKMIH_YuQ_q)sCre) @6>Vxv0Sv65grq(BM zJc2oy^cEbbEa)9=T*<`v(aBV+1#qJK2^b1U(&OUeNBShBN#{|ITG#g(`UYp}6khKH z%4z7<0U|uSXIqX8dB5&_#f>;VBq2G@2az^$8pmS<9O;vo5{vZ-Fd-=+U5c5`%Rhh| zvgYq XpDd0w;fp9Tt-a zpOy|~^8pwZljbudF=lAYa10ebxwH60m 3Be0B)mz o0dHwy1`NY2uyaM qb@Q;PSNpSv3E@&pNU>mrK(?^oF_;dhHqcTw~Mt6pbS{P(1l==WC zC%A>q(^S0xNNOAbq*`UxaHq+neF;ALRcm_6$dt5{)byh$C#`k?k~y%dCk#$Wm+r6T zW-9_Dxzj(>w92v#Pf5@O`K{#zo`9r4MFF32Mw cymv z(8Bkx>v@A$0Ts}9pdLBT;SJn;+X0N-R 5=t)AmUIK3;wD1Qcxz2zj=Nb5@`;Sg& zc$V!R2;>o$g}`-!VHqF|#8g1C&uBp6dw7b|2NiNfx&TtQtbo)&EcmEHQGnFYyQ01; zAelu1B!%u^99-$@;{q}yU_BtY_B=rHpu=LIcLS2$^8iVKRe;p<$$&Kg*Z;^Ha`}m` z8)<5>Yt^jEGFR{CvmA~)C)CEWN8Qrb-=m^@J0Lm!+v4ZPqWp!#TZ>Cck53*gNrMy8 z(|mBe^9$%CH}Ilnu2@?=WXK(=15$xezzIcMKnfsrr!OE)5NNOA#{}F4NCT@!{MMJb znO1>LcI;EEKCSXj%}rOhxre01kH!WxE#N92E)1F0{9jkMHK|&+(zapsyBO7d4M%>` z&PSG)sFA)_`LvpiZ%4HN-?6IVXO%xuBk?^_&Bpg8wE*A0sY)ZO(!wN3?a-!CjUH{0 zXQ|nZtnx9nppn&JvRBLchszc<(%&j4soD5mrWW{Hm128IYKkf*)!E-7d#I5CRyjq@ z#`ni+0lwW-CD5u&a=@CU3C>*_qGktLP48l;+o)0gVUVT-S>=2+65n^!>>#VDKm00E z%?S!K{S3?Yr5v>!Y?WuK*}+!RPq1^CniJO44u)+@#mXw=!qI@D7W!LEe*tTy9uEjp z!r(z%z1&6?Wel(oaM`KO!14r!-uhdVN5ER4%s_otLSa{uXCQg<7*z?enl^&gTFvR+ z)B%|mniw+EShXO;DsNMjP^;-K9K5NT;~%Ef#~f*_2_U;9s0E=`d5x+xvC4&NB)-e5 z+4%0F7BsOcb1=@NBscqMH8RXLh#J|{s&s=lMS$X} z=AwlKY5{06W?T
;Eex&bC@*AGN@0RTjBPQX^g$mOTnA zh;zfT&w-I#bhfEQZle}7w< _MdG%|%fIjq6nOKsmaTppxmx3wzsy>yjH z$rHfBz*ttZr&3drLV-z|DO#x6?W{@;XuhDq;(-=r7cf!_7#jOajf}J^gKA0A5YV`) z-vFaAgf~F(r@;7Jp>DLR&5g&qVFO08OxjF546KPZAzleCS@S1L9o;p_jFW%`q7K*h zFt9GbAg@!1LtWk!ER2rL07e#ojes2nMok$tr zpq%P*|M08FF*`Ln%z_vc*~zMG1C6UrAwaG#NgXwQYAXsDxipN}$RbZvBRgA_ji5CF zO&bsShFZ|sDw|cMi`CSrfh0w%Q9YX4X&DM-zaiIwCbTKcTSP6>l#*Nla)>SOHMMJ~ zWrDO!OO1aaNLnZ`{Zx{3^U-O&k+W)ii%N1omE@{mka=nMlH7dcnrSr(c@C}m5$SkW zErZYsE#C);=k}N6o|oh-utliGH&V|j>yYD9F1oYD;NY(w>k+Or_t(ddY&uO~T39um z1J+&()3q=y#kgYr#Q |>RS)a*W1rFO7BvT$(I0AL~NajaDf z)yTe9`GT5_@9Js+zSpWsKdbT!)TP$#wLn_kq6a+auXF*{5@qna&K9(y^d||C_;ysY z@!eM~!1qV0GQcYTp+*j{D*G^7X~M!vR*U?;T7Z(Psxr`O^2e-hL93>ch8*<^Qx^T& z1B|98W=Wt$ey%Emtfm*uB&n0?IJl`DEZb3a9290^CAq65IX|mjIv%<98sA~$+G#mQ zL?oW;UXoi@lDk%t^TA5Q`7%m!drESq7PQ!tDm(*Ka!YbQmE=5NrdC?BF(tV*CAnKA zIUfw6#wXiUWr)@EsEs5gsE$LzOat2Lxg*F8)o8xh(Zp*x6}cEK_XlzVwOrRoJ-4+a z=ZuB6zgC)DlKZwKSFZ!@NvO4{TJHGprgq5m)<_ma44(V2BzFtBo?2=1C`szB ;I!ujrxvi4YTbAl){Qn6r3Wy~I+_9lEXqP)JUmdnAAr$hgOs)wrF?g;o=Mx} zG*y*UtC9p7DTL_&8%%|H$x3C_XatJ8z-V$|!`j4Rn$#0(jhfR8fdV; nzd z#!+?dXHkX&!ywwKXw&;kU>I;nKyXmX_vX6sFw`CxSy)z`6D`U(U_ly2tK24Fm{{13 zQQ1pim>}4((k8>&hnMlyb`r4GD1%QRXdVPcRx7UskXLHtXsgnpFWi=Mv P4Qa zJU|YSiY^Ybt4Pdx5QNM2G_r!~!w !t3C{rd@=oQBh&0DnrSNj;UcvJaVu-1#QgN{c3iWwv1$1mEps Z~c@wELc7RTd`lMG ;Q()3!?MmJ#Olh|rwUd{m)0F1|huYvJiQB?Q?7)7&knk)LH z^GJd@fhdy&455XjAYz;WM)lxiJuFJO3|_CiX5lufGTSO=sgbj-rb(k|&5fEJW;%*o zxE5IL$7q2SSFin%qy8Xz!*LlflBtDg({W(UwVIA&p|P6d7iO{|2j76S@yIoyoU)xt zQA>-3rW++3jWRJp KUp}?RW4=B%pk DwA_@zf@C#tZ@$*jTRJaX)!gOhk&Q%%nLJ_Rc+ZsZUu4!G@AW< z9O-DeKFDG5oEN67M2@-(*KcW2E(7Db!NrtT3rgJ2YBAY>VTr&Z_XToRtxjQoi( uq_hRNP)!Dm*}00vXirrI #R!OkFZfe3C6M=PH})W1_sZ>)#?>s z4b`YlVT%6}K3%lXri=$hT(BK1xuv9xM({o`8Z*9)@L$Tu0qtT=j0Z+KX=U<0HS%+- z; UtG^ZRoQ4YRas8 *b?hg~0L$qQiQk36h) zSi!xXpN(VzqcVOqdk`4e0ggB}#9^gAXf*3P0BeLIOe9hj7%2inwAC1?PdxnFuj1oY zQJZlIz_`Yw{~BOI$VVX#K)Ue8AhFKJdc*-EqEO@(t7!#j*jI&xDaVoHVrZA7e8P8M z+B&3IfJH!#w#!$>0wdSPl*Q%z0bs4vsLo*q`_*dMZQ-WoYp~x`9kE#EAm arR8ub8%2(~Ex8@M!%4F$$y45FgxEHD_U zZJ1L1b3SXK=M+R6VAN{|ZTVUbjO6hX=Cf+#PODOWBaaza(x7oNux46|x!9y`P?cTa z*o2)qr} qv#~O|s>(jA9Ir<1vnmDK^&muh%$i^FX`=;vWh5{PecGbo zcmx=AS;FU=dA{Cib6*FgPQLCVg_A=ZfRJIez>Py{<$zVW3tA`8;C@&H!gg@2_?lnu zD}70$dHE$UGB5%}kVScSr>+-Gx6!~zvSvTiW? rqFpjG|ZHNTq7+2uR)F+P@5XENzFcttMEN~yKpFF8?bQRF0co{$R6NN3~~6H zM<(8}8Nj%LWX2zW@lKO>)ZB~TCZHO85#3w}tREL*wHSWis~$TNE_YRxqgHu`8hO;J zR61Cq0eaC37!5ZZvxi0b5E$3T8GE`Dz-UyVLY75odPo;c7Fz_YjaEkecnOS_MA&vx zh{NF$T~V|LSP7%a_zjxVOdE!r=n=RwfVJaIVV>;)#s{Fx5uJ;gi2%mcBP N@5rI}tWe{?F zK+(RuR4q7RRqlh 0LmmQRivdCF=! z4O$OvO|Eww{nnglFmggZ;_D7zqR)u0c4~H^)ztHZX05O=d6lZ1wwmlu5>BzX3vv{f zuu2`kju2RDP1C~d7Ud^k++NNTLmW=&o<~L+0jv!evGC#gZVNCH0!7iKS0$Wu6 V)@g&@7j87>H!RwO^BTHkmK!=xa+{EDQ)5@4Zr8T bP z7^ztO2fZy|rZ`{&H0cMBE19CEYG*Jr)Z<6Olyu~Tw?&570pSP6FOh4dHGv^9wfIqz zhH2M)`;g;GlII8fBuR0c3&Xe&7}bGwFpTGc(fp~XB9tqY&hiBdQ!&}4oImbPk8f4s z@s0P&s*QZz _#sbWV@J6pg+S7$P<%wEcPRj9A{V-ZudjjTSIN*J1Mw zjHW)1aOVVuh=}?6?gidSEEAa_4nUv)P079(dtg)zp>~QzxebiEr>M^DLmYnQ7avZl z^E8W`rbb@$zz@{z?@!D0JbT=W6gTYuS#4hwuC%zw2Mf{L&tjN)Q9V`^ZusV+TJ}=7 z!Ldkfe<@s N_mq#i?Az$LZp<#5B)OKSVe;mW>C{JLN3o#`1coUh}oWWr^f z2x~nnJYg|?4-9ALiD3qFu{x_b+_0orJysm9Tr1{W&;jn#^a?)|gKef*3_Gr {xXMQc)<8(f1cq(Fl`zA;tLm();RfR`+m2oBQz^?C%S|mid mN65dciA3)-3B+3a={Q!XzRDg#85??qV6}7O#k9$Z^OTq*shBg8xNabw> zPLRsm3!ES|)Df^OU=Klm9TGqNV-)fA1tgY%__7C#x69%Jhk-zhBLqVVpdaw%f^jt< zDY8buPXXyekm#QYoFHX4;L8NK8Ia^|6Yxtw{7F0UMGEcC5}B_B+y_Vk_XE<0AZdC8 z&;jrypd;YVfcTRx _Y6l6w_=1b-1Q>zWX7LlABPQiJyZ=|hkz+y^WJ_@}`C z0;C>32c#ap66N+F61^P0K$0p7SQ(Jyx>KQmkeek{1Azp12v|eFT7dYI>IvurNCN!< zsmFl=1_M(45COvk3>Pp$z*Yjb1*DF20yLm~sS7eBxSK|R6A8QzAPMddNEPA)905ol zg4Cl?0w+lP>3}pulSTOqK(gRWKvH}bAo1k@(t@F7h~WbeNRfF|@Ha>m=Yvjs3q(0V zQfw(fb UU2Z$f2aqK%pkq3(kLoB=K{U6U!ES5x!0E6C`}QzzI^zUkaEn;0{3I z+X+Y?z>0cCtFX(o?djD9{~KlaaQttS`QIq>zftD@MwF@WW|Ya#be1O^VNvJg4svU@ z_?+C6EjlMVvKK^X%OcN%(C$148_$Cf$(|75F%kM-kUK }Fdd*H7zV@B; zrUkz?8}dF|c0qRQ*vYj0*VM4U14XXOj;~pH>xbPH-JIw2Xqt88c-JrTYzh0Fz8>6f z-JRiM)d8kv6N2_D)=S%FKic?&HT~#=5bp&IPa@jN(#wi30i#&&pP_EApP}xapP_$e zrd$NU;UWl07eR<-UlCyk5j=`O=*kj`Kp0j8!f_&WXYQ9kaJvM;#7iLbWCcVxN(7(F zAoOOLmq8eN8H9^O=*#LCgHW#+gq&g!`m=LHI7@_PS3nrZvaf(J^9l%ei4em=uYwSA z6@+D1L5O9yh;Wk#QNMr?&ldjz!lGY5ctM1rEb >z^2EfCUJ!YvSn-2&k_ z5i*$jZ4lgUgD~+n2xC|Q5snhU=MD&&Eb|TsWAA`)kqF~i{a-<-_bUiFzk)E4og>0o zA~d@TLKe%u3&PC1AlxOwWEOf4gphk6EV~E7RCbF9H;E8+AB5>_@qG{$-3Q?X5oWN+ z-#}>h8weYJ10kC|A;M!K^nU=tY_{$J2x}jJ;P^WTIjr~ZAoThjggr!<%an&8I6MR) z=^+TY>? qeSre6NJSq^G^`Q z{t3cGA}nF`{{o@jUm)cC1;R3RjtFOo(Cje?D_Hhp5N19G;VuzYvCt JKnw ~-3y^!6Q>q|70$6{WhA%~Y}=r9qsFy~hw z>>xtMD-gD^{X`h{N_JdO$IwCEzF?H0=K?o_ hn9hR^-^NY%w;ky)y7bRo`~cJ<<+cX~Pz*t2yCh$ClSd )|COFojnMS4j>e; z-VPu ^`75ek`mIS_V$kUz1U zAzwBP!3I}hqs)f!I1jaBUCagtd42wVM=;BQ%(0@uY)W*(kL-!1tHv^|qQNFtVA1sq zDjQVE@CEDWY^Z@rlH_a%Gc|U{59x__F7Y}ZGV>qMp8#~q2f3$AbVYw!!JlkPWkY3C zS1;`7sn|~|X3t#=4yKGc(2R&?jhJ7riea-|z)v^~sVqsh+km(twb78S3+4H3fVeQw zX!K8-wBn3!!jjE~7A2i?%?soI;XoDR(*|cGB*sY(@{`PlOR_vFKgz=p=pZl8pIpa~ zCp+SwH?@B+&>ACE%5e3Er==tZqrPT^6$o|@>KOt}+W&vDh?a&8WS66w0rY>$oIf6_ zF-VxpntH=rjr03^8wT3RGxGQN8KxTL?JOeDutJVt#es(Va%_HKkfEy4>+VM0S!om3 zgX^41{gS4GR+c1wqBXP$3t4&ez5Et207JDdHw}d)qrV{Q$9Nk$+vN`mg%!0LFCe4} zYFxgc334|0IsO6?3E6@p8*LP=#92lE?+QF?L;J^XQe#393vX%IYU)#r|4gAy2NJ8h z{vQ*svuZSA@gx>Qz*RQ9m7$vJ>myh)5DWuh$v@S~5IC!B7xBE7-%c^ZDMJg^@|3|< zJ5E9K(q~WtUDmFSY7zmTwV=^e8Knk9z-NQtqpLQ$s-n;5f=1}af<{4& sCRT2^_igU7PLyB&7(qm z_6Qngm^5F|z7{kW(B8x4y!P1(BL3)~jrcV+z<$99r;-kdMh*yCRnXQ8+Cf2c18u0F z9TGHz59zsR_^_Z=11%ObQXuOa5b;O<%p?sHj7J4yb ehJvK%aZbyUynti^q0b4ySQB|!&`t_kEzs-)?UbO^ z295s3l|F@nRtNbnHHsvi291jA5-vLTgW!7?r0?iBg+6CMB+J!9noKqDIV%|JBR@^h z&IuaLhADz}UeLTjn<{7*1g#-x(*^BkLGuCaeL=gJC5XNt&Je^RL8J4$PJ(s`kg|=C z90jcykUE7^W2u6mT@kbZ(43I333ye|0+DZoJbiu 3`IvTY`pVL^45B8iw1Tk)@j;ouK118i%`r5le}L z`xP4Po}l6WjdWVj?h9Ho;C+!N3;iZ&xX&bcB2N~2AZS+P-I1ry?}FAGc{k+AY7Y$< ze==bNQftBZhhS_0T07*)Y>x!3CGw%jlhytdv{uMlkteJDC1|aYF9X5UbBccWquVA@ zb!14Xr-H97O{bPXNP%a9Sc6;{AE%2f`HG>-VGKvO*_TGa)gbwf@P_GJ+1gHX?08 zqC>GfBsw(PfJ7mfj@XtVEk{~`v=V6*5*@)UMEZyo{A3v4ej>7Ckj5cVpv^?0<3I|q zbV%-t ${>!1fSo{)Y5B(mka6Nc2D0bZEB~ zX&dsZ0oNdXiZlm!Jv(;qoFUntjufXM(FuGIQXo<=Qe&hLBnwg~QWGRPwfE1@IdAA} zFwp^G16KUA!Qw;5oQX(DNXbYkNF$NxSadK_EK*OTp{U-BwZ3Tht2Z69_d^ A;VuX`Pk>mt32bOK~L(*GQ3Bg?sLc-QeXvOgf5K|0U&Up9C~)0zB5q#~qCNXhWK zkw~MECO`@;m9z@3L7Iy}`U _G0aDyQ0Qd(ItqZhX(Aq-l&|xH6xM(G%6_!?JT77Bd{0eXr(nciOZ$u$=MCyRl z7KvtW8>Ci9P(_ B0ieo1gWh^k#8>`(W8;? zjMNFK0`%wtNPD2QNVI4A6lo38YNR1ZaY*kW4MysL)K%pB3A`KaIl2SsgVYPDCsJ>b zh)!`W2C2V*g8-?V%1~LN6Bgnbi1Y&a0f5A>*Cj|iM5B5nCl-m?<7F5RB9ahNK-V<> zwLCSX(}yBY_$NpoBPAkH8TDut(n_QiNUtlo9QZP%_mQZrrASMVv^KMlnT4eHU?K7g zkVYWQM@mIfk XDC-99>pP!=RDuED}b&Vt|w<$NC6q zG14L=U1MUVGNS*Trq`o}Y205gCu`BrkiU=&va0SAsF$UAxn6-h{`EXfGriZZ`@jOh zNAUG>>a}i3&Ab99y3R-WbtO11!gaHg<}{6TMxw7rqTW#@^7_}yh( 5j z0BL171h@nEcBC(mwjt%Q{f`Y*9k(JajS3vulqH@0#+F{gOF9F}$nY1k?rY19>mf z*GPMizCo>WfK;342aygS?MG@38kJKWx(Yl1B~~IG1s(=?1d#S1GN6QXOyESLbOQJ( z15Q9rB6AvP&>#51XFxW){lrigE1bkCJ~cEl2KzS7Z}HSnUB= 0{8A|9(W#fC}8r(k` zzZxZte1n36d>iRcJ!$vJ(VyGpc_i`@U+hx{qYf^GZNYOof7<-gXGson4{D7~d~Wc- zar2VrP-8ON{@maf8sr-!>5pIOwKdkRcxu2FO;E5eE(tbKH3(`j$fH)|Py2sI2^uD~ zb~29_26wamXq-i#Rr++us~A5p1o#FJ#|0J*2Kg2n0Z?6ko>2S81&OBnpL7FXpl^^b zwuvSKTlvD^W_E)a$pS0t*cy6Ij~@( lHd$TPyja7~Q{_)I5Mzw#4b+v;E8nr5$CmXBFH#& zV--7G7`$S|gN;=^f+YRfw1XmJ%hk;8eqIx=IR>u?7X5Lx#V?O ?QmX=joGK)1cK?nVTseg>Q*P(0i)c&Om zd2AFIa85njgfS7rCdMm+Jv12yDwW`~h+#Gl)|Upe9!q)$Kn!glTSeHLBix)tmo>UG zr!vNBvIp}n0}b@Y!lvbaFge`d6%OwS<&lS1Wn;@2gXBwWR3%8e#fni!2RGQWQjA?L zW3*%Gm5fzHaS5R^%XBb$=$ZtvEe;S7&b}qkmR)l&1_tX-Io|y3=jR(-!fL|9A6!^} z4s!oKZ3ZUY?AHq=jo{okNr+`p3M?~_O;#YN4O>FkQFf9r(Q9rIR=q5`D=es4V6s_% zobQW7dGpAct!P>WK`fkm5xWZ$nf1pa=Ot`7^Iheyt7sZE^2OBL#=Od*i8E{ufLVV$ z@~?4yx?gO%uNC-0`1HTcQos {upB%O6X4`9`*jai;qZ`_n<13_y +c9v^oKROSE`iQtyaY!1Rqph&2qsY_h1_c#IVDT#wfG?4Cm&q zmlieI>wx)< Tu)C20}TiC)F1S`HuGgl;7W6ZowjCBB%Q-vknAfsm2^T=kDrbocA(e% zH3s=xP-xva!~826-LuMgYFB->xZVd3EU&oIWRQOcgDV*RWh6uR9IB5xw6ge@eQ>8i z8y7o+> *!|c+7iij;*ZG%WCy%j1FS#b>fAJ|A@Dc`0SF;nkRIdit zxc4`W-@D!Z$**XGCJ#oV4eLw{`h)s@tPq-9$+bfy82n*=aM;*XCu87$F!)qf=!8X( z2Zn!(B4l@H6o~s$7;q6QBG@XzcrEsWv#}E*L9I$~G#*+?f<_$Yslx78LhRVh94nVJ zrn9cCY;03YkAeTv6Jbu=#B@PV^aomh_~)9HJ3Wk3(A5B6SPh4OY@iEVM}GqL>=okz z1Gk(>0fSh`|0P7yfS_tH+vsA9f~wCTf$QaBuXS7Nj>unPTU=pm{gK-<3VJ=SRjcVk zGB&r7VAe+F9~FgZT tb?lWZTD;Gqs=#QkFAM)4F}{HEDEt4hSuLvnzi-c-o$@da zGuzyGc=j}084!K%9tG}D3>TINVfFv{dh6h693~gDQJ!#;U)gK|PuUtzZM`~2fHB7! zAiA=M8b%su%o{CFe0@=3)}Jii?BTvG$DD$PK^Y6hX}WVb7YxDrqsANfwR`@!ugmWm zgXW|9L&wwI1Fk)7Q(+fM0(}Dzy(KfdNV4^Zjw>lmzquX#5f~;l=6m=)%-IWSjbPqh z@VW6U)63Wzzv$TOW%R-?EQ-CLxyIsRuT7*#=2sK!0<>kZHBn331$)=(fUSOAggyNU z!s_L%ANINQEWse77ye|`>FgENUcw@pV2ct^3v2ch7FEkQ)L`F)eOU{ea7~muGt|b0 z#GP4cqxlAGL~WzDDG+xDyx4=GMpwBT+frN8`P JxQk@LY? z8I)sybZIkbM@HJwkTU@;+OC<_gCE(0ItUomaC3n!NYb*~z5HTL?Fq1(wlw1Q1+&(L z$@M3d7ZvSYwjp3osGW@9>Q7q){aNM-Uo~ADWS?}sw4^7?K~=N<@bmrGa@SU_+V-zf zhVg7a7;rcL0`aZH89FKZ@w!RF?>W>tUCOtOReTpZ=#N`>a1Qt0A rPie^q%%>h?uZ9lT1>t28t!^#fH2O#> z!%h|h2Kf{l4^UlyihbcKCyzt*Zgno@bFgEZ>lp*g+gtGmXIjfd4@sR_5NC%giU4e6 zamCJFKt%9OFwiyQE|)5m`p;cFrIf+gnm^QZ`>S7nFI(+cozfCd)}cPM3=<3$uN3+> zeE#k8Qih%^3k<>OV8D$To5#4$^0f(PY^4mjD8VMdW}kjKF7d=eLupAKJ5I8X3x?|v zbsQeGY;~xV;SQ4 UQB9r3}`rp)s(s{uulT zx%>N+*;iwkLH1%(8ydTt^#`DzTHpSc;jW2`DLUZF5N9d}*~5m$?eGV`rZ9>dJLrQ( zX0yGaz&>Hlz5sd5o4{_i#m`u|4Btl{WB!d{J^c~%^}Pdk%(tAu-cH{kKVV@2Mt4J* z9&D4Z(ao$s!+yo$#*bE?ska-96!fvwhqGdmK7c)YqY(;xdCbobBcMMZf7RBA 5_g{eh7BfSqiltL_eSehYc>a2D+k(2c$FLpahO z*WcFm+vii-HA{pH-bHCQn~chANFzi{p2tzc5|Sq*lt?E&ov5{3#SS`X1}mX=V i>=m^$;zI?3V95ZUl4v2SVD&HAJM|7`xjpf9eSanO|04huNL9EcO&1BK;Cb&{vv@pD>@|39CVYk5(CnO zJ;12rx0!_&qYLv4G@9_+#t!flc`38<0U@_|)0Ymi94czUHUt5PkrS$4WVu8X1{Xs9 zb#Mjeze*9+MMIi)e{ZN98y}2@-fZvRJpVj<0Y>wkLHxnBdl%>2vt1bS5p3X3eiJ0| zsUiCPA00o73?l|7Du!PZ_2}`n*G0dR)eW)*yJ(uBaqKuvwV1(t#dXMTS?1CwA2-un zL7PE|OtxT}=x^xx?a;)LOMm+AdxP90R{J4^?O$D-HY&o!b(_EG*4kLQ*lW{Cm~1e+ zgO<$tYZrcQ+-}qQ4dd%T6)~BwG0zZO)%wSAT~mA>X5ZQWsIb&QnzB_P=yV6R3&5o0FOUagVeM>W5t z-UaihGn!p&0;Q%h=P An~1GuZT~7heW-@ zX(xQH{@8_LG&s@M-`GatdÒjjWK!nkT?{nZsumyfJ4q2^7aw(p||D2b3Rr0Y)_ z_grSU98~Fx8&Dd1Zfv|PTuq?`EjhFhXrQXGk@QCCf9T7b%89mxFs_0wTJ&0UO0fJ_ zTfHg&4T)?=xUrhKEAFPymTu|R*>n8Mo1C%lq>~g_qAj}{4yW7&2HKd`tMbQy!DV~i zDs{FaEX9gGN3d)whF5>N#@xkihy89|ulpPXwPz2AuNN!V9HZ>Vtj&Riv);fAhBWp; zbL^#uvHi`BC-H;c+z1o~vJC`wvt_LSj<8FFon~1r0nl^p7(3u1Th$ule>;O8DqR1q z! (=f*A=eBtR<95`s@laK zwlR9wx-gN4?!Vs|agu*U34VWI8_OcvqQ!-*FMwHp !^fzrZ@$b;B+T=^0YyH%YK 4p)Rd*v59+uot6P z9>kszNMw7v8r_+1Bu<2~*u+SXK42^oe8p^XPh&N9jY!McE0E0MohG&()!G$$KG+6z z^^=qnEUG>DY%H%cz <%CXkI$B1{rxG$GcTlX z>2!?m<>;(Z(qCngn}6_NLQVgfrSs?zTSoG(vZVLW(y3@;rO^LAr~W=Ion)hm9{|!N zj|cwUXB4~?rhH8>&P9s58@o&9{u2%Y|gFT5Gu(r6@AV~*W0Oxhb_(AM6DOU{RNcWaO4Y2gl(q+%A)4Fl7J zWf0(pP;5^(c-%vFk*Zc(z~k%excOUlpD(yXkzBhMB6VQSG**mxcSqGXG-va=Bdm%( z@lh0}`X59#AxR5xF811V 2)LeTjAzd`1lze{$0wW7i>|DS$e@1Gua4WX8p}Hh*_65 z-PkUPT9|Gt*$QG1@3yh^-cakd {c(Mh2I&b+ht+BA-ge4 z>5UGwWqW#~!3xaU2f&>@AgnGc*T?9sq%7gP2woVhzj5c2;iEG$U-qSIQ!K`G1*gB0 zXX@tolMO;U)6FC7Mkstav7A0=tUcRL;6BUy5aKnZ$R_>!LW6v^p)blhuuFYWHjq8( zi);Q1ET$i@r)+#bl=WnJz=C5}bA5V$boyTX3gaH58M@g8=TAXNCHUoEP0v~TyYBrR zH)e1iNCue9UZAS^?^{Cc&P^bW1^kyWf4U#PgLUYSE+2v*I_o>hvid`}B6ge#@3R{y zgf^827{d%@*03%Ej16F{@dHrUm@OD!^fK!&?D_HQ$?Z2ro%uzxj^^M;S>XWq2>qys zeo(Q$QrM$`9p};5!+f-~x-rjz5TqSVyVSt?9VkuzjIS7pL+iJm*Y(p8LK-^sj3t5D ztiR6Z_fECh7pywnTNE4fifk20^JKe-Pk$}Y{$B!3A8o&md)xXY|1)-<_ypL>B4Uhg zhL8iS*&tNY-wu?z)a#uVH>YV6J !gJ#&nKQ2k9ocv`~eNAC69BpBewTI=rk2b#XbcX$JzW8>P{U3yUAL~rnsJ7Js$ zu(`x=5~D=x&ycBG2VHkso`U@^b_;aK(}W$2!7abIP27CR%y}^Q#jCw+M{fmvp0T;; zS37wE7-%rQXRQZgLDSzkH0{;)< f#GPyeK=qSb`RP^cjm+a^S1w5|-Cq8(m931& zuMqSX72S?M-(|$ZsyIy6FWsJ?E^Z{){O|jJ*Kq&VDWxTq*j)%W`)uRql0OF8igWh0 zomR@wj(H7%5^*dHz&sUvH6ZB3h4y2XxgS4P%J&IN0YmUXFw_FWhnE}YTMjoWTgq@< zlpL#>HSVF$n5m^D3fn_XG-N*w!S4y~e!;K9dob%zOrQ-cXDH0KbGvxw3fm7<-puX} zMU`@_%rIjZHZ?7WVSeZ@Ryw(OM6+SDp3V?s0Pjd+xx>IdnQZ_tuiC*ku79l^+;Q4D zPyCcZ^Nv9J(bpv~G}d2-GvIO8&w4+fn_enNe_>8b{NHU}`AyAHB5uzW?O?tMxZcp; zowVb6=qTmEZaNR5WeSc^fyE?1iD}F^1wXF=A%{hb$Bh>4zQb~sS5ip9bksPoY7BJF z7?BJtiTMx5PWI_e)^Rv4+wos#SzJzCmW6^~{dG`oE5 mO`<0tkW{AWDcM*8t?)@UR;_;!xAtn&z%_bshq7 CmP+Vzom6p0Uh`a9Krfqu71m(`Qc)R zYayDQ@Ov>Vp*#7_h%?pq{oM77L#wqC?H39{bFQ*MNMf^+pt?2={~XpD+OX j1Sk7|iAfvZhptKR>|5Wh)m$K iVm-26VdI^;UGf2u+@Ly{@~J z{w}MEcFV5}45-d0rFJ3_%VI~uH-w#&*p`uyD;#Dtdqvn()_FSr$=W JRoaQqSPC)x4}FFGn1=hDMwSP^G3zgoE3-8ByINDP ze_Y!5JZ4STx|KBsfV-KY=n(rL9p=);%H4eH5MRJtKN#!v^4#$vp%Of&3%h{YX8mn% z<*tO??x5y6Y7E%n;K$jlBAM&8ag@ign5kOuM6n2$ydB-Pf+!+JQHC~EDXg+eqmk!b zVw -~>2m r)_bY&;hGyzEqW+ z&NMa-Zd|~3Oe>EKb-KILZXg<>g%4c%+xTAgpWE}!={7%!68Nle6wzClz0}a!3MoeA zb-L)LR{Ta((^t#-tnYYCeGv$_h8~Tj|K{)P^9gWt9$nr#p23nfkaP(|OC4X!-CwVY z-~K(DfD)lOyl 1TrM<@6p-sW=Wlg3W}5_dcFv3a{1V#(9YNiAZxp?6sC-JAOpG5vUO)LHn@>6*UP zuz_!`P&&U@ ler_xWwkWxgh9p3GG>=;7JQtdp@H(%+g`_i^gXNc-OQ zn&)e4nEqbHTaK}{QqK)~E=sg8pn0GW2>W8k;A+CDoRDpPyHMezZ>_5D-*hdx@z|j$ zT417eS?AD)mAkNc^-;cJRc|wS^v$ydPoXW8(qf>yz8!fjq|vVAwT@spd@=P6r^J4d zuaU2NYANw;TMfi1G3VZN($Y?A{-`a-C6Y@Q=Qn+`9V>jz!8L)ncBQ4P9rh=54L$ql zq;fwUFM4K>H=W@&_}3XPrpTMp1#vyQPur|F%l@{pVk2i@44m2Q8E@hA2$1wQUp_v0 z}Mfau8kuFq3#iTW??l?<3*)~ uW2w6Lp0O%hmu<9| zKR(MZX(t73QclNC;b-5tV5cLTXJD bA3Na!?BXnASnwbm=hEGxC5vl+9i@Ku2P9i?e1r+5zY}!duI#x*XDxM6LdUY$ z>S#x=-iF`KvT?JGHSq5NubmvT6SFZQB`3|sIk*r^XVG(vOG uXw5E4pk3KL4HvVU0or-v4 z`in{LgvG=Z1awj$lJ<#~Kq;k&4Va7L6g*&K>|ER_tHw6W#UTH^M^5r}h@x`{+!VTu z3ja8%D7}Bn?@Ab2UuM1^f-yUeU+kN%j|;> zF;@H(F1SxIUsX=8x*bsSs(&+0d+jXupH)YI7w% i-nI#l?sVkE ztsSs>(6e>gk8iY}P~nLo9dnHVhQF>dTdvWq?AmOjL?4IQ?BiTx^XSt!NFgU&v~b>> z&gr?^i-2oaL!rwPKW&({;1A&RE9hp?b%ylG{&}nH#<$Xs?%ZDAK6r{-J@JnWpS<(_ zp&DsF)O2H^^NdzR(o7D%nrHO%s!*A$$6f}uNZj0^(%(B$fjt3Rle0MFr3iMR`}oy8 zH`H*y3Y>JCT(x_JS1v(C_klYBKO8!+t95jfpF(EyzD!KXe^13;!I3ugjeL^h$EN#Q zf) 7;Gq1q?d>AGOj=EryV~f*=BC({$?u+MhaU_E<%f;3Yvk~M07Jjnl>h($ diff --git a/webapp/package.json b/webapp/package.json index cc0d5fe..528821c 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@inlang/cli": "^2.18.1", - "@internationalized/date": "^3.5.6", + "@internationalized/date": "^3.6.0", "@playwright/test": "^1.45.3", "@sveltejs/kit": "^2.12.2", "@sveltejs/vite-plugin-svelte": "^4.0.0", @@ -53,26 +53,26 @@ "@types/eslint": "^9.6.0", "@types/lodash": "^4.17.13", "autoprefixer": "^10.4.20", - "bits-ui": "1.0.0-next.74", + "bits-ui": "^1.0.0-next.77", "clsx": "^2.1.1", "dotenv": "^16.4.5", "eslint": "^9.7.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.36.0", - "formsnap": "2.0.0-next.1", + "formsnap": "^2.0.0", "globals": "^15.0.0", "json-to-ts": "^2.1.0", - "lucide-svelte": "^0.454.0", - "mode-watcher": "^0.4.1", - "paneforge": "1.0.0-next.2", + "lucide-svelte": "^0.469.0", + "mode-watcher": "^0.5.0", + "paneforge": "^1.0.0-next.2", "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.5", - "svelte": "^5.14.4", + "svelte": "^5.16.6", "svelte-adapter-bun": "^0.5.2", "svelte-check": "^4.0.0", "svelte-sonner": "^0.3.28", - "sveltekit-superforms": "^2.20.0", + "sveltekit-superforms": "^2.22.1", "tailwind-merge": "^2.5.4", "tailwind-variants": "^0.2.1", "tailwindcss": "^3.4.9", @@ -82,7 +82,7 @@ "vite": "^5.0.3", "vite-node": "^2.1.4", "vitest": "^2.0.4", - "zod": "^3.23.8" + "zod": "^3.24.1" }, "dependencies": { "@inlang/paraglide-sveltekit": "^0.15.0", diff --git a/webapp/src/modules/collections-components/form/collectionFormSetup.ts b/webapp/src/modules/collections-components/form/collectionFormSetup.ts index 7997a5c..a3d4f3c 100644 --- a/webapp/src/modules/collections-components/form/collectionFormSetup.ts +++ b/webapp/src/modules/collections-components/form/collectionFormSetup.ts @@ -1,6 +1,6 @@ import type { CollectionName, - FileSchemaField, + FileCollectionField, SchemaFields } from '@/pocketbase/collections-models'; import { pipe, Record, String } from 'effect'; @@ -98,7 +98,9 @@ export function setupCollectionForm ({ let record: CollectionResponses[C]; if (recordId) { - record = await pb.collection(collection).update (recordId, data); + record = await pb + .collection(collection) + .update (recordId, data); } else { record = await pb.collection(collection).create (data); } @@ -136,7 +138,7 @@ export function setupCollectionForm ({ // - return form as SuperForm ; + return form as unknown as SuperForm ; } // @@ -146,7 +148,7 @@ function removeExcessProperties ( collectionModel: CollectionModel, exclude: string[] = [] ): Partial { - const collectionFields = collectionModel.schema.map((f) => f.name); + const collectionFields = collectionModel.fields.map((f) => f.name); return Record.filter(recordData, (v, k) => { const isRecordField = collectionFields.includes(k); const isNotExcluded = !exclude.includes(k); @@ -177,9 +179,9 @@ function mockInitialDataFiles ( ) as Partial ; } -function mockFile(filename: string, fileFieldConfig: FileSchemaField) { +function mockFile(filename: string, fileFieldConfig: FileCollectionField) { let fileOptions: FilePropertyBag | undefined = undefined; - const mimeTypes = fileFieldConfig.options.mimeTypes; + const mimeTypes = fileFieldConfig.mimeTypes; if (Array.isArray(mimeTypes) && mimeTypes.length > 0) { fileOptions = { type: mimeTypes[0] }; } @@ -212,7 +214,7 @@ export function cleanFormDataFiles( initialData, Record.filter((_, fieldName) => { return Boolean( - model.schema.find( + model.fields.find( (fieldConfig) => fieldConfig.name == fieldName && fieldConfig.type == 'file' ) ); @@ -236,7 +238,9 @@ export function cleanFormDataFiles( else if (Array.isArray(newFieldValue) && newFieldValue.every((v) => v instanceof File)) { const allFilenames = newFieldValue.map((file) => file.name); const newFiles = newFieldValue.filter((file) => !initialFilenames.includes(file.name)); - const filesToRemove = initialFilenames.filter((filename) => !allFilenames.includes(filename)); + const filesToRemove = initialFilenames.filter( + (filename) => !allFilenames.includes(filename) + ); if (newFiles.length === 0) delete data[field]; else data[field] = newFiles; @@ -261,7 +265,7 @@ function mapRecordDataByFieldType ( return pipe( recordData, Record.map((fieldValue, fieldName) => { - const fieldConfig = model.schema.find((field) => field.name == fieldName); + const fieldConfig = model.fields.find((field) => field.name == fieldName); if (!fieldConfig) throw new FieldConfigNotFound(); if (fieldConfig.type != fieldType) return fieldValue; return handler(fieldValue, fieldConfig as SchemaFields[T]); diff --git a/webapp/src/modules/components/ui/badge/badge.svelte b/webapp/src/modules/components/ui/badge/badge.svelte index 0c3a927..f467641 100644 --- a/webapp/src/modules/components/ui/badge/badge.svelte +++ b/webapp/src/modules/components/ui/badge/badge.svelte @@ -43,7 +43,7 @@ this={href ? "a" : "span"} bind:this={ref} {href} - class={cn(badgeVariants({ variant, className }))} + class={cn(badgeVariants({ variant }), className)} {...restProps} > {@render children?.()} diff --git a/webapp/src/modules/components/ui/button/button.svelte b/webapp/src/modules/components/ui/button/button.svelte index 2ff6a02..80c29d0 100644 --- a/webapp/src/modules/components/ui/button/button.svelte +++ b/webapp/src/modules/components/ui/button/button.svelte @@ -56,7 +56,7 @@ {#if href} @@ -65,7 +65,7 @@ {:else} diff --git a/webapp/src/modules/components/ui/sidebar/sidebar-provider.svelte b/webapp/src/modules/components/ui/sidebar/sidebar-provider.svelte index 31abc2c..a6ee95e 100644 --- a/webapp/src/modules/components/ui/sidebar/sidebar-provider.svelte +++ b/webapp/src/modules/components/ui/sidebar/sidebar-provider.svelte @@ -15,7 +15,6 @@ ref = $bindable(null), open = $bindable(true), onOpenChange = () => {}, - controlledOpen = false, class: className, style, children, @@ -23,18 +22,13 @@ }: WithElementRef > & { open?: boolean; onOpenChange?: (open: boolean) => void; - controlledOpen?: boolean; } = $props(); const sidebar = setSidebar({ open: () => open, setOpen: (value: boolean) => { - if (controlledOpen) { - onOpenChange(value); - } else { - open = value; - onOpenChange(value); - } + open = value; + onOpenChange(value); // This sets the cookie to keep the sidebar state. document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`; diff --git a/webapp/src/modules/components/ui/sidebar/sidebar.svelte b/webapp/src/modules/components/ui/sidebar/sidebar.svelte index cf9f0e1..336d119 100644 --- a/webapp/src/modules/components/ui/sidebar/sidebar.svelte +++ b/webapp/src/modules/components/ui/sidebar/sidebar.svelte @@ -36,9 +36,7 @@ {:else if sidebar.isMobile} sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps} > Date: Wed, 8 Jan 2025 10:17:45 +0100 Subject: [PATCH 06/29] fix: types --- webapp/src/modules/auth/oauth/oauth.svelte | 6 ++-- webapp/src/modules/pocketbase/types/index.ts | 13 +++++++- .../pocketbase/zod-schema/index.test.ts | 30 ++++++++++--------- webapp/src/modules/webauthn/index.ts | 7 +++-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/webapp/src/modules/auth/oauth/oauth.svelte b/webapp/src/modules/auth/oauth/oauth.svelte index 43fa9d2..132c98f 100644 --- a/webapp/src/modules/auth/oauth/oauth.svelte +++ b/webapp/src/modules/auth/oauth/oauth.svelte @@ -5,7 +5,7 @@ import type { ClientResponseError } from 'pocketbase'; import Alert from '@/components/ui-custom/alert.svelte'; import { goto, m } from '@/i18n'; - import type { UsersRecord } from '@/pocketbase/types'; + import type { Data, UsersRecord } from '@/pocketbase/types'; import { nanoid } from 'nanoid'; import LoadingDialog from '@/components/ui-custom/loadingDialog.svelte'; import { Separator } from '@/components/ui/separator'; @@ -27,14 +27,14 @@ .collection('users') .listAuthMethods() .then((list) => - list.authProviders.map((provider) => { + list.oauth2.providers.map((provider) => { return { displayName: provider.displayName, image: `${PUBLIC_POCKETBASE_URL}_/images/oauth2/${provider.name}.svg`, // TODO - This won't work with `oidc2` for example initializer: async () => { loading = true; try { - const createData: UsersRecord = { name: nanoid(5) }; + const createData: Data = { name: nanoid(5) }; const authData = await pb.collection('users').authWithOAuth2({ provider: provider.name, createData diff --git a/webapp/src/modules/pocketbase/types/index.ts b/webapp/src/modules/pocketbase/types/index.ts index b0e26a5..0294014 100644 --- a/webapp/src/modules/pocketbase/types/index.ts +++ b/webapp/src/modules/pocketbase/types/index.ts @@ -4,6 +4,17 @@ export * from './extra.generated'; // import type { SimplifyDeep } from 'type-fest'; + export type Data > = SimplifyDeep< - Omit + Omit< + R, + // base system fields + | 'id' + | 'created' + | 'updated' + // user/auth fields + | 'password' + | 'tokenKey' + | 'username' + > >; diff --git a/webapp/src/modules/pocketbase/zod-schema/index.test.ts b/webapp/src/modules/pocketbase/zod-schema/index.test.ts index b17c852..3fabf67 100644 --- a/webapp/src/modules/pocketbase/zod-schema/index.test.ts +++ b/webapp/src/modules/pocketbase/zod-schema/index.test.ts @@ -1,11 +1,13 @@ import { describe, it, expect } from 'vitest'; import { createCollectionZodSchema } from '.'; -import type { CollectionFormData } from '@/pocketbase/types'; +import type { CollectionFormData, Data } from '@/pocketbase/types'; import { getCollectionModel } from '@/pocketbase/collections-models'; import { subYears, addYears, differenceInMilliseconds, addMilliseconds } from 'date-fns'; // +type ZTestFormData = Data ; + describe('generated collection zod schema', () => { const schema = createCollectionZodSchema('z_test_collection'); @@ -14,7 +16,7 @@ describe('generated collection zod schema', () => { expect(parseResult.success).toBe(false); }); - const baseData: CollectionFormData['z_test_collection'] = { + const baseData: ZTestFormData = { number_field: 3, relation_field: 'generic-id', text_field: 'sampletext', @@ -29,7 +31,7 @@ describe('generated collection zod schema', () => { }); it('fails the validation for file with bad mimeType', () => { - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, file_field: dummyFile('text/json') }; @@ -41,7 +43,7 @@ describe('generated collection zod schema', () => { }); it('accepts empty string for optional url', () => { - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, url_field: '' }; @@ -50,7 +52,7 @@ describe('generated collection zod schema', () => { }); it('doesn`t accept url with bad domain', () => { - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, url_field: 'https://miao.com' }; @@ -61,7 +63,7 @@ describe('generated collection zod schema', () => { }); it('fails the regex test', () => { - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, text_with_regex: 'abc 123-24' }; @@ -71,7 +73,7 @@ describe('generated collection zod schema', () => { // JSON Field Checks - const jsonField = getCollectionModel('z_test_collection').schema.find( + const jsonField = getCollectionModel('z_test_collection').fields.find( (schemaField) => schemaField.type == 'json' ); if (!jsonField) throw new Error('field not found'); @@ -79,7 +81,7 @@ describe('generated collection zod schema', () => { if (!jsonMaxSize) throw new Error('missing json max size'); it('fails the json size check with a large JSON object', () => { - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, json_field: generateLargeJSONObject(jsonMaxSize * 1.5) }; @@ -90,9 +92,9 @@ describe('generated collection zod schema', () => { }); it('passes the json size check with a small JSON object', () => { - const jsonMaxSize = getCollectionModel('z_test_collection').schema[12].options.maxSize; + const jsonMaxSize = getCollectionModel('z_test_collection').fields[12].options.maxSize; const jsonObject = generateLargeJSONObject(jsonMaxSize * 0.5); - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, json_field: jsonObject }; @@ -102,7 +104,7 @@ describe('generated collection zod schema', () => { // Date checks - const dateField = getCollectionModel('z_test_collection').schema.find( + const dateField = getCollectionModel('z_test_collection').fields.find( (schemaField) => schemaField.type == 'date' ); if (!dateField) throw new Error('field not found'); @@ -112,7 +114,7 @@ describe('generated collection zod schema', () => { it('fails the date check with a date earlier than minimum', () => { const earlierDate = subYears(minDate, 10); - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, date_field: earlierDate.toISOString() }; @@ -123,7 +125,7 @@ describe('generated collection zod schema', () => { it('fails the date check with a date later than maximum', () => { const laterDate = addYears(maxDate, 10); - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, date_field: laterDate.toISOString() }; @@ -137,7 +139,7 @@ describe('generated collection zod schema', () => { console.log(minDate, betweenDate.toISOString(), maxDate); - const data: CollectionFormData['z_test_collection'] = { + const data: ZTestFormData = { ...baseData, date_field: betweenDate.toISOString() }; diff --git a/webapp/src/modules/webauthn/index.ts b/webapp/src/modules/webauthn/index.ts index 5e209c4..4b457a4 100644 --- a/webapp/src/modules/webauthn/index.ts +++ b/webapp/src/modules/webauthn/index.ts @@ -62,7 +62,8 @@ export async function loginUser(username: string) { const clientDataJSON = resp.clientDataJSON; const rawId = assertion.rawId; const sig = resp.signature; - const userHandle = resp.userHandle || new Uint8Array(); + const userHandle = resp.userHandle; + if (!userHandle) throw new Error('WEBAUTHN: Missing user handle'); const token = await pb.send('/api/webauthn/login/finish/' + username, { body: { @@ -97,7 +98,9 @@ export async function isPlatformAuthenticatorAvailable() { // Base64 to ArrayBuffer function bufferDecode(value: string) { - return Uint8Array.from(atob(value.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0)); + return Uint8Array.from(atob(value.replace(/-/g, '+').replace(/_/g, '/')), (c) => + c.charCodeAt(0) + ); } function bufferEncode(buffer: ArrayBuffer) { From 8b48ae70252bb11e40c3104ed1aa965264500e0d Mon Sep 17 00:00:00 2001 From: Giovanni Abbatepaolo <30571828+bbtgnn@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:38:11 +0100 Subject: [PATCH 07/29] fix: types --- webapp/bun.lockb | Bin 293227 -> 293227 bytes webapp/package.json | 2 +- .../form/collectionForm.svelte | 10 +++-- .../form/collectionFormField.svelte | 37 ++++++++++-------- .../modules/pocketbase/zod-schema/index.ts | 8 ++-- .../src/routes/ui-tests/schema/+page.svelte | 4 +- webapp/tsconfig.json | 2 +- 7 files changed, 34 insertions(+), 29 deletions(-) diff --git a/webapp/bun.lockb b/webapp/bun.lockb index 9195bb122889b0a90eeb06c1fcafecf7de12a527..d41a9aeba8f7e7ae40baa2cb6f205c3881b38d5d 100755 GIT binary patch delta 27 jcmaF;N$~Y2!G;#bEllEnnGN*}+ok?8ZI}AX99RPYu|x}f delta 27 jcmaF;N$~Y2!G;#bEllEnnGN&|+NJ(7ZI}AX99RPYu`COF diff --git a/webapp/package.json b/webapp/package.json index 528821c..a509c6f 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -70,7 +70,7 @@ "prettier-plugin-tailwindcss": "^0.6.5", "svelte": "^5.16.6", "svelte-adapter-bun": "^0.5.2", - "svelte-check": "^4.0.0", + "svelte-check": "^4.1.1", "svelte-sonner": "^0.3.28", "sveltekit-superforms": "^2.22.1", "tailwind-merge": "^2.5.4", diff --git a/webapp/src/modules/collections-components/form/collectionForm.svelte b/webapp/src/modules/collections-components/form/collectionForm.svelte index a069f3d..0061594 100644 --- a/webapp/src/modules/collections-components/form/collectionForm.svelte +++ b/webapp/src/modules/collections-components/form/collectionForm.svelte @@ -1,5 +1,5 @@ @@ -45,31 +48,31 @@ {:else if snippet} {@render snippet({ - form: form as SuperForm , + form: form as unknown as SuperForm , field: name as FormPath })} -{:else if fieldConfig.type == 'text' || fieldConfig.type == 'url' || fieldConfig.type == 'date' || fieldConfig.type == 'email'} - -{:else if fieldConfig.type == 'number'} +{:else if config.type == 'text' || config.type == 'url' || config.type == 'date' || config.type == 'email'} + +{:else if config.type == 'number'} -{:else if fieldConfig.type == 'json'} +{:else if config.type == 'json'} -{:else if fieldConfig.type == 'bool'} +{:else if config.type == 'bool'} -{:else if fieldConfig.type == 'file'} - {@const accept = fieldConfig.options.mimeTypes?.join(',')} +{:else if config.type == 'file'} + {@const accept = config.mimeTypes?.join(',')} -{:else if fieldConfig.type == 'select'} - {@const items = fieldConfig.options.values?.map((v) => ({ label: v, value: v }))} +{:else if config.type == 'select'} + {@const items = config.values?.map((v) => ({ label: v, value: v }))} -{:else if fieldConfig.type == 'editor'} +{:else if config.type == 'editor'} -{:else if fieldConfig.type == 'relation'} - {@const collectionName = getCollectionNameFromId(fieldConfig.options.collectionId!) as C} +{:else if config.type == 'relation'} + {@const collectionName = getCollectionNameFromId(config.collectionId) as C} ( collection: C ): CollectionZodSchema { const { schema } = getCollectionModel(collection); - const schemaFields = schema as AnySchemaField[]; + const schemaFields = schema as AnyCollectionField[]; const entries = schemaFields.map((fieldConfig) => { const zodTypeConstructor = schemaFieldToZodTypeMap[fieldConfig.type] as ( - c: AnySchemaField + c: AnyCollectionField ) => z.ZodTypeAny; const zodType = pipe( @@ -36,7 +36,7 @@ export function createCollectionZodSchema ( minSelect: z.number().nullish(), maxSelect: z.number().nullish() }) - .parse(fieldConfig.options); + .parse(fieldConfig); if (minSelect) s = s.min(minSelect); if (maxSelect) s = s.max(maxSelect); return s; diff --git a/webapp/src/routes/ui-tests/schema/+page.svelte b/webapp/src/routes/ui-tests/schema/+page.svelte index d035e6b..aa67791 100644 --- a/webapp/src/routes/ui-tests/schema/+page.svelte +++ b/webapp/src/routes/ui-tests/schema/+page.svelte @@ -1,7 +1,7 @@ -