From 94a6607a519967022eedaa57995442ceda6648aa Mon Sep 17 00:00:00 2001 From: electroluxcode <3451613934@qq.com> Date: Sun, 5 Jul 2026 00:39:15 +0800 Subject: [PATCH 1/2] fix: x2t CDN loading and support plain-text Office fallbacks --- playwright.config.ts | 5 +- public/packages/onlyoffice/9.3.0/x2t/x2t.js | Bin 35039 -> 168972 bytes ...57\346\214\201\346\240\274\345\274\217.md" | 2 +- .../internal/editor/plain-text-office.ts | 236 ++++++++++++++++++ .../internal/editor/server.ts | 44 +++- tests/e2e/files/manifest.json | 14 ++ tests/e2e/files/plain-text-as-docx.docx | 2 + tests/e2e/files/plain-text-as-xlsx.xlsx | 1 + tests/e2e/scripts/generate-office-files.mjs | 14 ++ .../e2e/specs/onlyoffice-factory.contract.ts | 1 + tests/e2e/specs/onlyoffice-factory.page.tsx | 48 ++++ 11 files changed, 358 insertions(+), 9 deletions(-) create mode 100644 src/components/onlyoffice-web-comp/internal/editor/plain-text-office.ts create mode 100644 tests/e2e/files/plain-text-as-docx.docx create mode 100644 tests/e2e/files/plain-text-as-xlsx.xlsx diff --git a/playwright.config.ts b/playwright.config.ts index 7e934d7b..a8873384 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,10 +4,7 @@ const appPort = Number(process.env.PLAYWRIGHT_APP_PORT ?? 3001); const cdnPort = Number(process.env.PLAYWRIGHT_CDN_PORT ?? 3010); const host = process.env.PLAYWRIGHT_HOST ?? "127.0.0.1"; const isCI = !!process.env.CI; -const headless = - process.env.PLAYWRIGHT_HEADLESS !== undefined - ? process.env.PLAYWRIGHT_HEADLESS !== "false" - : isCI; +const headless = true; const appCommand = isCI ? `pnpm exec next start --port ${appPort} --hostname ${host}` : `pnpm exec next dev --turbopack --port ${appPort} --hostname ${host}`; diff --git a/public/packages/onlyoffice/9.3.0/x2t/x2t.js b/public/packages/onlyoffice/9.3.0/x2t/x2t.js index 9fc1a74973fb39751d85ae2ea124e3056f594089..672a1bde80f64633a83658b8247c5cf7099b6fed 100644 GIT binary patch literal 168972 zcmdqKd3#hxlJEcb_*EQw`qwHMC?T;J%L`WqF=oar50cwGm-dK~RDx=xDorg2TFrg! zzt1-!*HcwOc1OkEHm2>gKR)Um^qc9ZnbKx7n@$FY{pM^mK0fR=KlPiz$?0f3 z6^!2Su<5_kZ_V4@@vJ{-M#E+>?F#s~-}LzZZErjn%_hxR@BJk9chDO)`~7A%=^t(i z%zC$ZGMYAr{iDIK?|mGM`@Jb$O&dW{qm6E})f~-+2h#zaoc6}OlRl_kOV2tdHkz&R ztJUV4Z<}Z1(aB)a|Juj+tw7xDHmBqM_3>=j^iEIv!^8d|JzNux5w&lc^ABG&-R`UY zus;Ta!{%Ug*zb1r`K@lV{f;h&z2jzbFdm#vn`!S=KzmX^vDOf3*ynr5c<{P^@TM6Y z#ZG$1jPCF~q#I18lcv+}zUnpyy-B~h+4S~DZ~LnTVQ02KnGU8i8}QlS_*g_6_fL=E z&S7&ln7(d$2h$nY2uG3r7>viw1g!Y=$k?|(8yp{A6Z+HF17kyT|9CW+!J7M{lheU5 z9~kT*960F>Um*`ry}*fK7f8VhI*b}o^}r!tGr{N`PmrLI*c=8f zEP6*mQG!*I_?iRLC?nZi9-5}0Y-9Wpoc;dMh%pF|aY!OJbi`boeN;ir5bM;`u>*C1 zktiOFhSR}tW)h!~bxhBCn$Ooh%i{BuKth+! z6_>izmkl&O7|#v{a0!IxY43_M5zUPaBSthnLvSOfoBrGW_r zN+Ukgz#d57PEb)JCH$TaPWnxM_;xTJ4Nv-r!I|s)VAyT`6VWi@&L&e7@$dQwTI|0U zq)C4Y#a|hm?I(YJ^!(|Q$JESVDW;MY<+f)XBZ>P*$XPBl)l~ zA#I0P;qhX+?0mod!w+G>7z025|bYupL2W zHCesFOlwAv6}Z;OU}aUU9TOT3`)AFM&wuFf!T4acJL&hv2d`=Iq3IuEo6gI&E6ByaeE96M ze+e`>9vv_bJ!EPDP#W!NZ~FS0=3j>DqZs$6voTY-J!-Bpr!%8n&D6l`d|2&(7c4*m z7qa0qlmFiMl@V*QM~^RlcJ-CL!3jVd7+nChDjbLMn5xrUVN zz8;Ux%!4@ptU)yREj|Swm(NGT=JC@9KmM@w{L%m3Zcd~(d+rfD!7H%|Y$AbU_BrUC zGD-<=nDkvZ8#C(D(P^BgPc>%`PEPuV1BizyIP>|e4_WkPB9{k;$wZvVf(Lm5)tq5Y zQZXyqXUC%+{uJmAN5ktalrwTk3-cj??8T?={#+Z-B?`>+A)1)cry@_F~g`^HSiyF{mz352P z9Yqnv_2$J&Zm{yRzilvHrX-7+7!>5ej6lK*eQBBx{2#t-y$*U7NB;e2^afFt$&{tV zwLk95>>#j*gCp!FKO>B|Pw7{AdhMBi;-VwBc5Cu}cyNv0dxzf*hQ0Co!1)%NG!1Bs zAPT>CUqf;!63Y>MEqQ^n37#!oM-L7YFR8%xcAFm%Ygz4+rjK%rX(bon?Pzf5;CN*Y z#4#TB^u1K*QE`(9bFp9XFFm}1W#bcLUQ?7*rFMa_cH@Q)iiwKR_MVNaaR z!@)B#{_;lCUOBoQ+_k_1o5OePPgZ_LGTd&tNutq5=i4UvrBdDdnpwZmf|kiyK;|Z7OdaYNW&^2ZUZ2`} zBe-spXgd_fz-!0GXnGy@kNa=6e(jtx(Ie`t!{nm(_K*9Az6cLCCw(U?>FW&5>G-EI zG*Sd}La{V0JLhh#7R17?^-@N#yKoX?ee#cgw3|CD7py63!gHg@yuFIf+e&xkS~-WV z`lKg=o9Hqf_XfvWi%pJulh*+JfXgyHcpZRCxLCo-3iq0q`z&@gS%Qw6mxsM+j~}s5 zAy(ioUr(o}*s#f9+V4V`wf^)#|G!){DZ?RW#x$%A2l?f_;d?j*0!IXF%&5yEFfTWt zkTKoV%4csh-g5@F46bI;7HvynNx9>6ggkX-dl|kWS z9Cn7Y9%5|lh7#b^{VL#o~mU^)^cSw{W+EB)r9kZk2S zR}_q7*fWneb~+Glbo`dJ=(w-2Y9(lw6}2V8X7g+mM{g6^f048WXhYFP;@?8a zExcsO4Xq*t8#ivq0GWj4r#BQHsD-XMmpPHAA&L>~BA^!J_(sqh7x_SzT4wWD)X2Xp zpUIDnf1I2JMoDjM5{S)AO9|eN5fr(1;z0&!qnuN`4^ellJ9m{_i2>0&>#^Q4QI+Ai z#)yedA0nhI`zN>%6FkG~qw(O?V7SsmP?DO+o9^h%oXDhiW*%Ipqp9&x`_faQwXMNq zXn`O2qH3SkLIkk$!In{=&!M;ovigv z2YB?h2I5hHVRt;SkldD*iVCn#ZEbg~MZIEaaZMkW#*U&)%UdQ}ITx%gt8Ohyzc%f^ zn|`e8={xH>hF2|OWnXI{K5;x)4`I;1-+laptffVi6?{JFvDtttZUYsSx4?ABB>j9I(NzWEvxHP?D@fRD((>Zb1qd&AL86;$gvs0~`gB$RMO_DeLVK-R*!Dy|Y zzPWB_e1y=irzgiQk7vEfNm@^W`%nDdyt3fyMDl=GTP`~jptqBE*6-K(FK;yDT+xjN}z~^iz#w~V_2lX9_9lyM_#|mmL|L0~ zk`_~*5GfA!+jf=gFA0sd4$H{1=_%nuiBO1E4M*xSQkNbK>ky*;%cI?$-L2gpcYG9& zhRx3I^GEl0EqrF)p#cifSB*nNa6f%(XJ`BQ?xUwqc7!(sV5oy`zYG0ELSMXuFR|4M zW`HbM%fZ*a8taxmaRVPZdccN=4|%`;y7!h1O4Q^?pdLSZ^62r_4|~sle6suKG0r*9 zcAq|Y+L`PhtZp`sdw4&#un@iIu}Ab?J2W^FcsDYdVN_ue0f4w=)SSmiQ0H@^Hnzt9 zX4Q6(;tLpI!^XqvWR@)=R1nWeL`1N883~*M zUxj0?9VfYV@~F&2`jF}SXz*$l;_YHR6t-4Iy5eZul;Ftn)@>_jLQrH2iicpHev zt_N|ZDCjxr_Kyb) zhC#d?1iy|Y@N{%AI&M19YIJ(a4uC0)OxBvYs;h$gzlNiM*+zcxExzOfqK-LeqOIoG zqx`4wbn+9DKs?E#ITloc3~3J`M9=o*=-QT$L~QOYkPhDL*}h$v606xf0-0|%2dV$= zpnoc#UK?lXYayVyR&#I;ndx3#1fp#4xPL;3RQt)q=j6|4Bkr#-0yq$*a$I>7S3IT? zP4oTs*0a0pTxb2c@?%;R6>WZOH3H819a||Cjn?nXLz-{(W4jr!Zf>+;-Q1XmHQ(yT zcC&}L-wU8UT-ff;t#+>u@7!|B`Q6|ZXoUv0i7QE0B>G^)#_)mSwL#I5tGFkh$W6oR zwuRlCU#UP9)Vgy^BW!prihpufVp*%30#4D-k2WUrw>_pDHq+QH)V0#S^=|!6ei?+Kli&V$H@wZ# zSH4Xj>-GHCH#aiuASC72>9xL|e~)m4&r9hk03a1*gTShyL3&^Dx@Z6o0)(2~*2K3* zk}WtfwZ?+VxQ!PXgO9g}rYqaOH2dLA<2(e8YP$32;foc2kvB#3E<_~TO>CPxLR?u5 z0mux3vA$@3^RtAcVFJ-AcCOP9(~T1@aoNMer^9ECYa3K|@_KND-%>0nwVK21e%EJx z*lg`Sd%lfxvD2{k{AR){&6tc@J1Y12aUZ)s>5KyWiNWFPZT!Oaw=gFT6h%*tSD;^@ zbFERnKV2h)$FrN!F)t&IYB+khBLIYQwPXKqr>lNg_DVrloAA4qt-HJbY47y&vq#Ui zc{LtklD<)+lM&aSOld0<%W?prU{#DMfvl}hOTywG$fFHJ6(gUqLu{eqabMX& z@^1pIQwWoZ4_#J`kOJIuCNL;vDyH#%EPXNV1+C`--5zNPC84+c1Tat$R53K~QC&MG_HM_P&v zJ>O1F&LR7O+OA^zerV~3g#B@8`P8^IUBhL}^QggQmgFfsL* z>CM4j^VNpd8n0fP>&R-`Fq$-kpk6B`8%Nn(x2!zd62hIA;1QVyDVdvNeeA24g0|Y; zAg?lP=gx)?O2U8B-0-+h$&QD!V+N&l0uwBe+^?h~iWiRuhXlzq@Tpc!dHrn9t) z#x1M{_1K3Lxi=baDIj9(vbRQO`yAV7@A`)w#X;>EVbN8#=sm35o259W}MK?_YBFNn0%!qCQLV}>Nyn9t3J^(Ngo7&WG#?&VPOW0 zCQ+h8jlb8tcDr>n=m(zJR35YByUh+$izk_$uw};5)`pE>c^Ha#l5@}UPArITQs(@$ zJ`L-C-yuyN`Sh5QF_fq^7P%K7GUCyhqEw(AP%x30oc0gQsesr!A;UMW@|ZJYPIqst zNzT&eyD9BBzFzTw5%N#qkvTTViY*&$1JEYfpZfb-1f+<|zwef`r?=kV1gszfk|5UR zWCfd_oF+a=sTsB-h=&E!7VQX*Mx>svg$(lR5mDb9y!qw&O`>nl%^I^+w`RNdvr{CO zZG$v;k{T7|f5#aDAt2)uQ=pqN2U=#w&80SIwJKaT(n7zXHjbZ?0h3n5h*OZEA`1hS zS(rAes|=XLPcDJe2FhD#RheMOGDea;ChdR^NbMvgfh<7nB+vz7jz^HxSYXJoV4WX9 zd7`07ntgx}$Npr(of`JKAvqPZti`fK$>Zq{aY?W|$qthMeklF)x6$#%Y+52(&Qa^E zyxW*|1xGQia@K?o{&C7La*M7x%p4#lwz_{UFY=Q(rG+lVpknP^w3C_FWFx@x$-URs z=lO+o4zB)@Q)FeI+01=Kn+Yt($u|3>J-D7?x4LBA0HF>s(hSv8p%Td$@K2dy`<50Z zvN|S6j{B#Dfe=)0*Szm@1jV*yQIyhY#T3pa!a^h15@Hf-jrB@FgPf@0d-(0x)w9-~9&A zgknz_hn<7C)@q;gG;Jfz;mO7n?*8$6fCOBt-s&;UGcqe*-{Nm!Up7;MMT4DwnmB7S zH7x)Y^WmJ5OQpg`t1rAij&elmmxic7Cg7cWcMxHS5sDs0;!7VUqhZtq`6@46f^8{M z5lc%843NwDX7k5$|MtU6_iTuG*p5_yXuT{@f&yI=)`as?>X|49Ex-VTh|Urc?3k^W zI#f$y6Ka!~2bRJn@5rYGHI;)Ui=(uZycgi7JZx6A0~JaDA(O{aVGz5MT9l-8`lAR) z+5;#BDWkBZ6x70k_Y=~XQLK4PCM(W&7>aCka4JcD3%F)*vH9EeyWREfjl55ysTWzm z;fbzN@H$vDan48sVgJz4X5=ZW*XI-rP8`#kCPMw8)$_R3y_ugii;{PWJzOHr{bEno zXY2JlU#@=d7pi5<6IGikzOr_8J6YbS~MA0(CqETz> zTrw;Rpu1KsQ9&azuC-6zHm{tpBA3g?0@bD$oyv0u-{cHf2*y-yc@zn=6gJ^yH45HXm;zfC!Uag5tz5ce&vFfd zr>}f+V7kpzEiJIm5;oqD-?o4aG3=lz2|JD0vm zZQKaxD6LG6n7;|Bw%xWv;(NdvULMyEA!**dnG-+ytHrN3mXjG#kl*9ZgYsHg&&Z87 z7uJtaYVkQFoDHrf)t+O(+9@ANah%PUJ+NFjjYlSVfR7%~mc!)$NJ_?3bG8tdOA|j% zxz4Ov)(^uyRjVSFP)-pZCLo~TBQn=MIc98!iHwf|9-TPAYoT?tK*Dz0!_8QT*s2@w zv~_vYXm#$9Y2RU@W%1pM72o?<3BgxuykNU30MnPd=E1a}?Cs%y+aZ&^IE=li8YaL7 znYA%X{GT%3odTEOh%Jgu1%+whp*(Cvuxl)p`NC||$U}#t*xn);=90opels;Dc$%P_COqkJsc7s$l~DetA}Z6el$|lL3*f9d`@8GKgGjn1y)ei*4o#!x`#Hz zfSA5=pU-x`f4;r-VCQ;Bg|YK}4l&4Do1V_E7b}tQY>~JOLMZo^k47k6@T-&IF2ZIU zez!a&9e(p%)Uz>ZeZp$Muo-7yN*1@ibO@+X#5&2)PG$!(Ligd7X3|yTntlQuXaa}H zZ}3A(1vsOC!3?5A-zOYB!np zD{LXaa^an%k!@yFH2%E771*tH{IkntNiPM71wR^HYdX-Dc^$Jpm&=S0Dg7FAP*@6- zHGdJTql|gX*7bk!4&1(fmsar2y?cm8DtI2Ca-b z{mGj)zFYGFyP?gH>J|KFn)qM~lkiT9$!JDprT?s&FdVI7Y!^cEbj)aLFb+N|HH8?E1Y z(GljW-+sHk+6H)Yqi%e2BQ@TbYkcQc-T2O})c9t*@sU!*>gHqsrS@~c4@acC_gf!a z)WPRC3iQY7(65j=@_oemu9A0Q(pE}tfC zQ4p=nP!PA)*5YzeBotqWqJj8*B{GX5I%)lV)$C)C-$WZ0q*s!8*|sL3o~@R6hG<^g zfk~=9su_LpM<%iQsFox?@*J{`jfhR*1w)Dwtj}Abdts+ZlI_E}j+fI=60L7qqP(QD zk4knFm5U{t3F+X?^WgDfT|v*x^xj^MjqO<@4v?5%Y)z8MwpTmaDCA@Ra_&QPY%lDI z#$+e0fK3N;CV98p{d{%vUdX9T#&>V;e?M9O^8OQBz2B$4(Rg&c&BpuT`VHV(WN)dRc42fxqYHaze| z$Q4Io`}u!7*_qzl+uK;*U^9Mjfd1(Dqk|_q>wD|#2d{hMJsnn_P97a>Z|mWgT1c_g zG#cy4_V(qZdGT<6Yg{fv;@`T@--k;#5y9 z@$VvE_t)X}{;zOi9Ka>0=?#CEK|EOhRXVTFFEIc$`|Z%bW$U5-13%3>`SbzI0a!MK zxrTFtP~7Cl-G_G{PzZ&Zn_3|eUtv3Tm*qfwSeIX-2A?A9MFWf= z{?FR;b-#D|bZq$ngrpDOu`k+t_uYGr)9#L*lXb>JJ3;egHeWD@mX8kK0fp~KzOFxv zfer=v3J@Vw=by$l1X~N_?Gy*G)=~3@v>1!I?t>61+E!VMeYV~qHJh}l91>tuh(-y> z#8f>pr0}hdB5-(Gd&*iN=o|)12UP&fZML*8NDeHOLLqiDvGd8)ym`Zx7J0PFh|<`4 zuQ<&^&^HX&H^zJ5`O5NXiZqN^eYB>4G6I z=-ba-am?Xe^DWgojpBqzuU_RzBwwIudh$UpY>-8W?cdl1S90?yr<$P(k<-I>E4Hg- zl)4@%MG~~ck3Bn)GwG?aHo?%O~*_` zraW#)ho*IaNkF|9Vf{P1yMiVy%rZx_C7^MzRf=Ys%&( zlNw+?QJeBm-oP+bI!1yQPbH+|2+$)UGxx4$XS>-x+u*R241^@;9K3l%<|tM1h%;)_ zAeJq+{bD7;2YChCCqMo`fpGTuNa&?XgQBPkzz42|V-vo4kn@(sBh%X5QJ~iXWkxk` zTt=b2PurCs6#r~0t5aEuPcjop`fL})HjZ6m5Rz0}s?c{zA-ox|e@^-{+#`2}L}-@~ zOhvvsO5rO6DVz}2)57HD zErztuR=n+U!~n%8Dbk(H_D#a1rX0^Q62=3d9ugN%Wq%nLv{g}1Juw0yCsw*aTBeE( zr75(k7@pY|ipR<$AzzJ-`u&(OXbqLEK)xkqU(N<_Rt0Ulqw%XX{k8^# z>v#Y4LEn{~E$)DK`cj3$&d$!dgZ}i$J{un$tnvTG#us09Rs2TS>JK(P=0!}=z)Ai> zMPu~I%{v=krsg95>;}{?1V9${>eaNn6LPCNH2YI?S!e4DI|KBco00$CW9)F7El3^tdUs!Ykr#E`@lS42Wb*5; zn>(w`KbqP4MY!k``TW2yz~y1YMM#||DmG5T(Es{v>wkSi2y|xa8JUed!c;NZNu$4w z4*|v(4&rVBBEs89@Je+HOf%fm=Ble%LQ~pLCtpL$^&9-DhafGyfTIb@0?fr&_9DO0 z5Uxk)d8`zXS`Pchy9akwRgKM93WQ>hZcr4FhxgM%N!`td53}va)+0;+aj%nZyw}T3 z_AD+xd9rshe9q}r*HzpH?Xz5FR<{}WqUk)su4meX+stW#t|wurzeV*bD{Mls!r&a5 zGotfR15R(*+!1@CI%)46wf0YNcXR+zQ;7_jIhyRuQ4=SY)Z(@R9q(ddQTB~pG9pK5 zqAVvS^9&It$ZFeRTA$`EH{gZ=wlm2soDHN3H2D=2@(dhChKYNmEo=&}7U>x?}W#_{N-kkqWc{Zg}W5lQl zv20NiTqeF?Nu;T&@{l^VOL*5Pd!biEO}#Kdn{r9z_xAS42B9F;o{mtU{;Go)D>UhR zfl_5u8*|9ta`v>R=S+=z=v(%^a=QE!hBg?5V;pOSxJrEl%EL7;Sya7-bzN zJ+AH0QVGZb6Ka!YROY@k^vbV-b86XkAYJUlm3g+7tQz(iMH3}7*)tg;`zD^XTYS`x zy*Xut*(U^VIfeuoMXP6IS(GU{Oze+_&Go0ae|Rm|pZ?t)B-Rrg>X)xaf}R&Cm#@D= zIXl*F!iK|$Dy?@iuye8IO`hN)20j4RS9#<;a*$SekCtW2DXX64`Q;JCld{Uy&N8)ZM%4Q@u#f2L9okepr>KvV} zcJwxF9j9}E_j_dI={!S7`eB&rB)$Kkhx2DA_S5oT$m^rDopWCm7Gk4_;=3N3)_yn+ z4pppC6D6+kN$SV(=$?*FwM{LW1V73$+zQ_zY%!CCn!c4?wVpg+qEF*Qr>>;Q%Esnw zG@l?RbMQs(h%JR6%6T4sKUHNq5L1?-jIGs2Qe96~fu~gDlH&bhE~%t}=#wdwkO`cI zTCs_9uWI10uxLPu8GoTL*duZDJV1wRd)(MYUkD}`CVjH0asrw04Vt~fF-g)>2uo2BA5$+2|JFbM=InW zOW=#4-p!ci&lYqcd~*Y|_dHN0nW~H7F90d5gQ)sHB~X6?{lX9TnssI*%7i#;LhY>= zC4q47MR5NhHk8_jZ!`pdxeWcg^Y93XrcMi3l^zEDPG=&8VtfWd>Bq~Afz-X?lO>~w z5HC3n!CW#9n-gQ@B@%P}P)=NfGx1Zafb{a6bccy18gy`^Yr_1>H6GZ#Ja#r-Ls$6G z^n{5u31!J!Pr`*8y~DpzHMf7LO{xxS-o)J0BJ13Oml--0OrrEBC@pSPeZ^nU_!6qzloM5yRT5*Az7m`dOmD6T6{v6ViHYLC{*)w!%zH z`PjVmkx5B3c(%3sJ!*9hAqSJK{mEvyC2B@6I)7ce_m9=ii@#3(y7Tkr_f|Wddz*jlp08iq`0$Sx|Ml0k zpRelmU%M~L1r4HIh*+pyR6ai%V6)T^&Sc0y-arGgZlOP4Pr+ ziK1arHx##DCquS$V&^%<(<;}?0$#z75iN)=+Y*=K^c3H)Lq2kGRCMiH^Ky3jQc*lB z$NX)R3$cq592qH$B^lcU_DD~}v*WoT5|iSuH|vyD(aysS{=I&^R1+8VV|Oy`s~3YJ zk_H2b!T4*js+-cjBU8L55st$dgKJ!v5-Fq>A@URmgTBt3rOLDiE1h+U@FujsMZ;+ahtE-UiNn1zP&Q z&7L@%+0YLptaPE?$FL8^&j=CQ)&g6oWJblLM+!SSCOVB6Ns+sz!mhz_kIcsv?;P1d zJ`_wd-S#_et`pJ>x*hvB$$t_R#vFNlkmz9A5W1}O%KA2bPCL3;r^^DFO%@XSO|`CE zIVA$enf{3QYWHt!k6F{)xtMUp`tSk(sd3?2iPos3$$9=#Gfrk?1W^sXmOyJlWYX@K zir;1^fjOOwFl&3-Dg=Of`2~8hd*fQTwrVNQ(g7ypS2ALYcowQT`WG*5{9JRCju?G- zxn9@-qn>>$>d~woG1~HEq=mShHB!Z_NvymT#~((G1&Ko|)lKjhL4BmEcv`*(*sQTJ zm=yPFUw0F`p&cXO?_jXmIYSl~br}${L0#1sv5}Eng`_l?g65I)`nP+c#GcMt$LE-T z{B>>huWO(Gacz~$phQv$;AV%cZZ-C!OU9cd*v1=5IY&WVjbCkScDS3uLn*CKj*$(? z2{%PpbBk-ynW-&a;Bx{kqmzd^%i3P?!=PP-Lb>@zR~Y+do9Zl@bJ@II|B?$EsiVl^ zdi?%$I?{sN!Ts4Ugx0sZAt4k5_jzGKMTk-^gqN<{x^Ey&u)-y6-brc4qEcvg*R(o+ z*d3>F?dYO2Ym%77_=A4Vfml40@_VD8(9B(kbP0*`02=cB(EIypHs?Pth1 zRU?O-kYMz`Iu$g1;iMF22yVDG79J-I}o@ zFd@ed=s)BrM^f8#66wI&hMi}Yks~v5=ZRz%WpnQb?T=zoa=HLgOKx$0lJ`R zN?JirPC8^b)Y2=P!#O6hHLBG_@=E>P*Gj$#mfAoQFM_K78kfT(|ewOaP%@rk(N>@%%M7^AU34+`-toD(&lj;h8?#pchMH`{6& zc1yXP5wYu%A!p)Zp9fY+(8}Li0CeM(z5cx83k0VoG1V_fr-^hc*;nD;>d;4%5KhuPH?9J_pSNzU!7?&M zOSoP9#%+0Q+7PD;> zbQ|UxADrC!^*h(KF-PGl<=7#-qH~MexlY|=&$z!5Ff$u8&>8SVLYuq)v zw~r1hLFr%l1u!=gWYJ7lw2LT0;l2&IGw|Ze91xidsKW~8iWE?giA_%OPxJVsL z!c-EAbYKQhD<#L~bOUP`mpw7tq}x2P)L*rPIcNDBf!6)L4+(v@6ijDZzZfSlx#3L!`Q1GEjSS#R{lbE`<5Q8`&PcM2n5lCCmhi-e)J_<@ z;FDRqZ5Y^j;}g$nUH#o zuG@^QsoYFZxbuqC@4jD5SAxYO%Q6zDlK3xua;)VzAARukt2CQIu~1TO>l2&+Y&l?;t0wTF2BJN5xRhfm)t zCyMunhZ+f4U*?Wi6Pql*CgSL#b2a@97NOpf$cq1vytxQ?^=ev43Bv3y%NS03c(ruH zr^A;?a@7Xh4UFc@sr5KFF-Pd!o$UZ^<_tdvS1`epIV(oD8ovqcgiGCHWOd+10P9av zz^?7&ikKC_)Gaq1Ep&w=iiMk_kt6S3T2?+l#NtwsPLq7D4zS!zrJ**KP{U!RgV$vB zp)a3PeFg<_MP0Pd-6yvFT8kl*Y`W;I4v)!C;9H?)p5iI|M&K>Dy8$0{d$DO4F*n|}> zkYfu;0jDry{zfzuioG&7%`Jr(Sa8BflS38Wc5%%|~#-F6lN@>Pdib{!3r zL96dQ2qj&p!3O=NghhjGi3F4oKsk2dLKMvi*gZOwP!;1Yi!}SUrRW?@2tD-4Pkg%5Z-Iyl%Nt!S4AnJz^KEe9u2?%usAA;oX^7AL zMo6T-G;;(CbfaX8+k<|08cu9+ZB@8eZ_-%-f=Zv26it(h)2Dw-y|a))QL4LUvjS0B zuM9t*AT-@|}2G3wjz#1*fy}Xh=|pJyBN9Qmx2a8E455 zdHe_c;{qGu9$+c(q;^ZF#u|0yufr6f6(yoK5m(3w?s|W~RZW*bPJ~x6h3^J$=OFrAFO!brF_bwq9rTC^#&i^Z*RzVArT%BNVOh zNR^opyHp5^Zs&}-UCFF)GIMquc}f5%8>L7NJ2W`ubhxGeD?^>T-4bPVXvMZ+jtFVN zh?MPJf&!{%@z2>6lT5FaMRxk0VGPeVid!|&; zS0PmcMW=p}TV*vZaj?7uBSZ97N(XHy>AFuvId?~TcE_jO9Oe~G*};=V2_dd~dCSRW zt`91Oqr{JPFFh-rSCp#Ou;Or)(;AOv=x41paXGXH1u?Mfnu~q^aDL!{K^!5e_)4Ay zH-_-JB0>YMMAP0Xi4IeKq~Sg%O7O*xDbHijbyK3`K;74UEQFe;&bIP!ZXHuaE)wR1 z2<2(GPsXK6m#NC+zTlYmfL0wNgV)OGEGL1@Ho+grPU<%A4+vg>D2aWNhA(!nAylyu}W( z?66ZPR7Z9?x5{8rIknokO3)Ei=$*gIZUPRRLw*wq>bFuAY>>vpg~Nh3N5?u0A{!Dp zY!%bB7)xv}k?2CJ?vcuH2Z+Kf5f#+s-k0xd5(JF-=2C!6NBtY~tkExce{_Voj%$97 zwT&hm!wNMB4k;B-cWJ!H{c5lIO8(W*P+GKh9_kNu`a;*9DI=n0*PSvIyk^(Jm8HvP zD|6&ydxI`@?mU%D2d&~Js|Y%{akh&Rd%vl=X;PLwkGfJqEHa#kn#lpuo>o1o^dP2FruB{29xHL0<= zgkoTOe=Eh97g`*~oPParZJ4t{5xGLN+F%Yh4&#wlfLG#cw zIci+|okRXrm&~rSX(#Pert`cu6<9VxxtT9T%5PATGDSf)%c273b5=*a>m(7y)HTHz zT+cud@|JAo2oei6H<;U3iJ@r`;f>AFG@nrCX?3u?3}s}F7xNrF)k76oa`*RQ*mglo z;-O`yf7J`m=b)}{*c*rUg??VYlVRL&s2}@#4(cVp6UH~{ z(f?e)Dtz0Dr?AX;DmPfklD*@-a1{!>A~~J4{kxpSvG%E!tWb(cmW-xlKBVIhz zwb9k4Q;;Cb$KwK+W6u2lz2B^rttq$`KUE)CfBhqDPfmKLTRPpz1YsXmpbZjPk{KCm zbFH~^`}WQ3O$v~P@l8|Kun(#Gdt7a106O-O3Kl>ON5fq`K3y%yR?sZA3PYq}3;oC2 zk5k$@%PPO@Y*Q1dY=XrVxV(q3R;kdDVEVS}b;O^r2JP5qb~2C@vAbW&G$uTa-9_6| z3j7UOL3!~Gu6cnyEMd!TG>6f_VDjDZ8(!%WA*2A0+8#c9^zf-aD!;MF8dVO$oq6G! zFLCSwufAOQX5BH;XaVCyp<|E7I+g&&uin0 zv$mvpc;0SKiLp1c(>dV&xZU`KS|x{bZS85hDeTcnnl{q@xZQX*WXb+!uCYIEHy)oD z=~~pVr*ln-F)eKD&)dx>?@t!u5uTgoM)sLN#$Td~JkLBLU4%B`$lPf*?)i%vWbs=C zUUBa>=zoT+6!>7WYHImV+E|eec=3R1AoA3DNuUbq=yAKLtq~Vc(w?^)%dReHtH*Oq z6$)C^R?lk^6u(vEaH%;jUhA0fKVO+ewuKTLUsM=YLnuTz+preb4_+%w*yi~^W1yG8 zTa$?)sM{w9AW6-N@A9Y$r&Kei@Mr3*=b~lvOPmpX=CqmQ!C>4GjIK>E^=x9#^_P&L zlh&lr#W-2~HG_4*DZ;%=zVb27eMgoR`8#&*;Jg@Tk=^IB9~R{oBQ10E3$V7&mY_`> z|L{92>84B;?fmYtAHb4;D;h&$mF-Vh6E)UOi?$538y$+o;-9g}!d2#ki%~Zt76MJm4PzM0nge2L6+C*L~hizNsi&z?vC!^DO zKNh*I5F}hg^*1{Xt?E~nm(^`{^BCANVIPuhCBnq)!xZ8RPKq{#t0BFHvi3cU7~~v< zMM}5%o&)P-_JLI!tdi%6CJz2?k@n*OJC!Y5toyKi#XgYlx>Dnw&3ATZ-d`$ZxGWi`Kg;Ol7iC0wFWM>d!}E6A3j6bmm<&a8zZlm7`(E zhC(~?kKQ-fA1*!Z54F3VDS`+;75`kM`lxN`AO6H zdj0Wtl*0&ljBkA}=G(?o_0LcTJT(E}_pulU&^2dbV}{(e8il zJ$U-#cRxIO@^5>OxBh~Ftl!wUMO}6Mlhw80H%#~*3#=jNlja}oNIUnGz>bDyGL1B3wmmWdYjC73`mR!(c3u zOj~n*sl>+CE>J~iQPjK*hVYOd(B?Dlr3s%9?j~ru}4aF!kRfEf)X&SP*J-V=9 zqe!|^5Lif*Y|h*dkmD@0kpD)5OYq+1zUa23uu!dVP!-LkLXeIw2NujtU+klOvQP+x zJcTcyY3M9dC$=_m682i8Sr$zQt=UXg4^yO9)D2RW>#HIKF)UY<-~>l8ngEW^N}dY} zHxj%Bk}b*RyuUaTVqCFB8STapAOTtB0F3AZ%l8%m^v3{eEgE0z=ef@<;zo;kz%x3m zBrt${wdA>C0bz^&4 zHO7oRdAhs3sVdH+83(>%xn__U4OtmZ_pF+b#WGZYz&AXm)J6V#f6d;$(T`TDNT})$ zK>d$$1Z}O%a@qY+D-Cog=fHh3{Hxx$$a4*(-#<2}3#7y7wg4r2ZbZjHk){O@)o6pS ztM{3UW(`8HJh-xIP@4fu{E(kCZQk_lcAOV~kedDBTJs0vmwqr_=m(?oALeQyNI3-h z1t6??sHT#-AJI)x>`mASip?{=Y7#A3`{&q0*C?R``IN}i?#Clj%O+LzYd|Xcf8 z+z({j7TjV*H1$!UDZ17mF4t}0Xr-}A`4v#JJ0i{i`A!r{i|01N`ea!q*zMabv8~NW z`!|S7QNGvD`<#*MCjyI^6_}EgP=J-C47=sW6DUND&jva-TTGCL{bLF@$e%TClhm!9 z-87^Z>4gP;N*)Fd=cdND5FU!3l^?`sU4e34-qVj|n*=mQid>Akak@<~BA%gL`+01? zC^gcQ&o?(K?W@@r2ow9M;$J1ku|Ys2{QA-UZNv0}?o9<@@0?vx&DC+?=jMb_%inI`T__^xs$ zb^lC4N9xn@p(>=+v?<8G+}K74H%4E4@df1^=0X91LA$%#uY{tNhpy zj+=!GXkl}xIrJa#n3q|djk;n&$>2cegmw!nr)ApNvvrym?jm^FI31a z2vbzkmF?@Pl9)yi>WEc|=|H#C^oYreqT9MU^#Y+WplNI-Dz@u%Y2o13(BAOrSxZPD z<|Ds;#8K6TSg6FW`S*l-Gr1C!peg6hlv_p&R`ebmB~;802u*aJPg`DgH6Xume2tQj zD)g_IknQfDK8(15zhBC5V%aW8qhop5;S_hDr>D zGcnt}p4_XN<*4XUvgUoon-*2sS!28#9@J)w6k4Mns?<8ba@hjLWJ|(eM*}%nn73NR z%IZNrIVW#SbX_EAdRKMK;9KZ+;;AA37kvptEGd)VB%=hN`9Ou51=25iS%gOnsREb+ zq9R<;BGls55+XD0mlY#BhUPP6TcR!!l|sj4n2TQ#h^>?f5LmAjw^l*6yCGW% zvm=|C&BN{kGmJ`?%*IFqHcgel522mX2XNf2GEt#&r7XD5v}{i@^5p6Q&5>qSQj}ER z&U{&rAw6mvKZg3Fj+qvAz$M<3PNWZSxqVKF7bUj81G_Fg4+p)UujtvfMD;|R>{2+O zWYe}q>z`7K1O_(yie12Ns+%Z#C)mm(@vk0xIggh=*GfW%d2>%LZ8An#U>DoMB~okN zfu|`Z_aIsbZQ2~PqE_dicG3xt=Bq(V23j(WgaxN`}S9 zdEn-w+0}Oz4bnyRXYQ!kcH-l$XM4|{Kl=05?zZOGcw1@}Fc+V$bc`-kn?rnxl|uRR zW&Ju#+fU>Kn7i6Pv6Qz)c33gsEnFlwGc>Crxacw!ad%;%>erQ|UOi*@NcW7RPr(qQ)OPV@`2WXqfhm_Vgw(Vw2jQB7krI2M0Q(`Yg%S+Nr$ z)#_4!AkU&Rlm04#rWeb}QemR$Nb|85O6n@FCZU|W%RgP%af_j)T~zbg`bkl%M;FDLuz zN=XPQ1B!E^=~*=tl$cZ>DzM0Vv+WHDgq`h{FRKEAa_wAvETh$S_Xv8G-f9?jvGg;u z?|+GM{3qkt)3ARSS(Q8cnNqD|_Q_gzuvs$gcfJ?IM%h`991O*Wwv1}}B61^iEYn(~ z;uYVAmPY@K2L+gX}!v}rk$>MRS zFh*xUG5TUm0n50zACa-ChnoeU$Ft)ZDOB2u^`pgl1(IGxg>>p?Wi$044w-i7qT}OZ zk3y=P--NpyMr<_MPFR5hjNTqv2H|PwODi!^^?h{ZWC^5ZEJ;F{uU7T2)%e_Rr!(3@ zRQ(ac0b9_k>^X^B#SpuMmbWRu%QF8_NJZ)i}pQ z`54%9xMDv@1r=Q$ihzl)T51oc_u<{tlBQz73qv*Lfn=bfDy-jq`rxTFJm|U%(-}F2 zBW`fkv||TxPpPt{P#C2oDFkObIdTMSgC(Rk24({g8FAdrJXjkq&19+J^kg7a@?LJh z39a6%l2;)uk!g^@KED^Q&PkVN*c~APu~E?pE^mg;BdcnyzI`vW%5eXlm&iy0{U( zNo3!>Zdv@m1^-IT^b))jaL%MvG-Hm*24jJQ@kkNVNKXNbGOnLp0NYrNZ3D3~eiS)6 zEudr=vMoyuTBgS$YerS5!j3sQX5W4RJ}nF3hB=Qq<2%Qw*eEt(i)s1D3rmVlEAw#C zHAiVSv`Mgwm<`EtO`??aJrQ)yX)0P9j2g*uo`LpSQ|_>tFnqN;GOt1g2rr@{uQW*u zj>k0CbaWnMy=hj)Dg1bUHLM7XoHh5M2v-P!kjy7#y>}D6x>h)8p4m1JyX@V%nL}eLMVmx^2Z_PWVw9X zmPD$^Wmy%Q7!!Js9SQV_ViBf#>&M@KW>DGqO$mWjRYW-G9#S1tJ_#zYo*LAU8ef&Gto+L3)YZBYGGZzn1a7Zt{9#X&L zk-`$2CIK?;yNZ@2V4(nnE?e6C!`dGtK`Lj-9vAybhnwa+*uz(xY3e`gQw5e=H^|W1 z)GVww;>P4X+4gj5N6mRA-|*oMb@!CJKiM=%m3t%iuD}((hHRfrzkmHaaF75Vm@@d4 z+@wg&Va{XitjM;egO_UiQih*Iea=iVhf?0r4rB2n1rRwJb@aY@i65Dvy-Ym;?0N~u zgX~kh4N~Ts?fZ|nu5aAg$l#f6`<7_scffPS^nXy@Rg>_m(a6q2yzVh;sc4_gv(clo zrR8;B*w2W_ziOU6fBKjIe7K{{tpE~v(uB{dU$qhWMVc`_ey`RKcS@8A*2Y4>Q(lD& z=_hze^bJ+0Dlb*3#%z~uWE;W2MLv$HOq-Vs3C5EkMVyYIRNuX%AddD84oN6E(6A!5 zBXaGDIXkXiM>tD^JRu+F{_It;Xr^1TcL-<_a5MyPNe9lYh)GB!`KI|pX4oHI8h!{- zA_I#;qYQZo zzfbW)o&S+IV z>+<`HX&z%nA4ev(T*N(D#rR$&xE8QKpcGpz!z$>;6U`oT=9!1#>~)#1?~~7h7c%}~ zs%=k^jc;Xyx5d;L3Z0k&*4j}je!XhbJW3^WX2p8knuo7=)A|LDKAOr!jVvp%7oj{h z)2;0(YL4MZvbWG=GM)5~%PfQ}<-y)0X#PXyPwmy;yeIpLR+82>BSQ4cEfP{lN;wK z75G}Xf!0xcl=03amS`LJIkDye$2uHsjU7*{g2o~>zx>lT&Ht(1F6v80@JuWI%Z|kw zKc@3yFzMN%9yA*7;nKrN@D`6Jy}ZA4&mpoNm-1)v~QFI0lWPY zO^|mS?xh#T2}fVRVY!S0dR1JQx!|UF4Yl}KJ=pE1q)Dk0ty+rLS{#Pu21r9Yz0cJ0 z&O?K}K;dxhdjTa4f8Zlm?wes8PBbsLOVc3_CdbN$VXeoPn49vW>RNNzG|52tfPFrb z8#m~+9H^;{dUT3q(v7(|#09c?KX>z{TgT^Y%gzAa^| zn4xB_PuH)P;_079CZNr(k?kgPfuY!Kmi_Qk$jP4r(84D6Shv%(ST(Gu>=zn$Jz!hD zAucWT))lffy!j&_>@m8CxV9E&K*IB-u&Pra6_Q4Jqifkh&h=@FsU+u3@cq`v3Q|k5^XsHwuvB7^g=6nmGA79MtA!6;`$SnW=>L`K+CFR zLd@%X$|YnA6I;x+ucgYSpj(u$>?rvYpBz7CEui1uW+$gwwrYSjEmB`Ww%J`^Mxsev zG^3hQQw z-_9()lZUui_GjA~Zl;@F$JcN$P6;%I14@+;TYRi6q&((b=Ri z!6zqPyeFv!lgMUS|9Pl#B9~Kb0lft1O8j1OZd=jvm1U(CN!BvY>2`gEq$H^=SDMEK zmfbE5mOQf}w}y(^8sA)Uw@88)suC8M{LJm&`!X1~0MtWq0Mz z!744%UmZGBCA&bv^16x)VHuZhW-gf%jdL#npF3G1R%z&&JS0xC&DfEg)>KcjXtTO- zo0Bs^bGJEU+}ba$nr0JnH9QH!Vuy z1k$tlZ}AO+4p$9ItjyBUI5;@%t7DpF&t-t}Jk7IeYHD`V>HHy8=0xF}Xw5?g@( zkzq(Ggm9rTVqmZ!YFEO}bjUy9F+pK+QI5#h$M447#LePNm(Ez3*L6T55=%KH6!Ivz zqkk@Ty+Uv3r?WoruytbAWWzIjo`6@?C?3Oa$A=@qL@cjE@Nnnik2Tz6!h^-A3}Mw^ z0i6s@w)Lmu(R=GkL@enWfVOQ`q_cg`E{&Gp?N5vDjH!CxT5E>SA7^)c36LvZaL=aN zeoDX&pKCie)c-zD)Cj%XbKT3me(M%V?Fwq#-1y?o-PQmUZ&XOQ9Qtwy>vwM6O|{Ab z5TDNU!*jENYGS0z0kDftI(C;W?cQ$IFShHxg4MR|mZ* z^(yOosB@2DoIqbp<+Fm!kp>T}5J|@28etX)Qt~?@p0R5WP2IU$RJeVatog&mBS?ho zdqA#epNK6aE+I(e5L=RTo?zwv-1}VApZGsV35S?vU*nF#UxH5^l#-DhWU*K9VN~TK z_$?iEv_La6?QA2fWJ)0->xGDvoh(?Oq+TC{q8}Gxf3rv!sQ@QRF4L^1r2m=OTyR#+ zG)t7LhZ8{EDvU>#?1Z(r2TS<85X zySs@l;!dNJM(IdeC#H0+$}a0`C7KgpQk^V=@N{oyd+YiA@9#Aox|sBPV^m$BQ6!}m zzhAAu$H88fM+>Zi=xA3`Up(Ywn$2by!cR}FirAzxI=v>fELmy%9i5hsmLCSww~N#- zjBa!qUs~U6y6!!Fw*6%9;e(w`xmQY;QxM{)PHIT&wIeU;*zhms&>=wy;VT}uw_y!= z+IgzX+s#Zs41HskIC{98<0_A(}(^tw{Z?CM6YdJ zXui4yf#t^Pi?Yg>eQtl9^!_#)Z|c5qmdoF=fVH2fTz=PTv62A2 z;Ps!lzVYbD8&G|aPc}OzTr_zy2tZD_iIKqlT|)C69$L$I{rQ99hH{8pVh`VdrF{Q< z4Z71=g4VkB+|W;K&O>Mckx`|UMS>>84O*AVNdxSmt@4Z2yk59#!Rp^y*vrJN7=6}^ z6SfY@p}0hzAQT3q%e60l%qjs0>7Nt7r1iw4zjzrwz7^ao$VB;ykjeSa~;xh(c z9nNgw45R9E6rKf|#uU8Cx($WnTZJ-kfI2TxD>;%nD>Dc7gH5wW25H^cY7$$z zE*si<*TF}3uo!h3c%(W zU%-<7{O4zEu{-%J3E&!w&oalBjMW~O7dB47f~9$sKyy&+Qjn}*Zbv*Fv@BCqw8-Dh zQN|?(90!xfi7~!YQjh79G-{c&Adm+Cq80yg=(o!hG$lSCsRbbwT3WU%5sVLajm6U&g^IIyp2I;}f$5{!3svB3zj+g67Ro%9llVL*GM0G|$&{!vc zWIh|Fj#pCbPrJ(O%NQs8MJ>%H>B$c1w@l_F?TA|DS>6r}&a8$gHyOFiE{@?~#x^lO zL=>#XF>O=k$ZD>~p&XaFIZ$Xs$+BM3mpLaUb@H+N4*?6=H4C#Z3P5h`Y#@`odlkR( z0oII^s4=o~e>*fUrX7<RM8z zFO)P63LdgI1i9Fvs=unh#=8l0(ncGOb9WM4p#GYiHM@JK9H~;WYxav=3;ZQ?Dbze- z;4LJzytmBGeJ*U%?_f-xU~XrILodoPe}aLKY`NHaZ(6K%SF8-J^=`knPem*Xr*2fv zQW95DDmeQL2XSXVGi>-d5n7okj?cp7!LpuX<4li+%1;F3D{6vhT2YIm#k3XxLnjUi(clTvrwuBXlV`NHPY^Ko9$mgZtlCy%Lbd2& z#{-%k04aMyohc9SrcV(XGQ9iHNFI&%>K{=(X2_97Dn#%1bxK_~wsJ16cXmXT=n(J9 z(*y7Z)2{CBNv&ek*N{`*_(azXa;%$!1y~m~w)+RICUq#pngj=U8no8cj=Z_OIaOdG zr9w+#u!tB&O?z38oQ|H@wL?!72G_xJi`5 z(mSF}aWxDe{m-NaNKP(N;i22y_k#&U2804cv?Cct&T;>g3uNr1KV%Nq=@!0f0+{Ou zuvD~i5*+9W)eNYGph$iuk#ui79in&ViL7KCs$Th~mF+Lx-lOs2=YGEtHBI`q%@YRJ z>>rK$K)Kz&T>{y+O0#p1t=_?=v|sa;mD(u3I&xU$YjSmqYAoytOa@%lek&DI5gN8# zRuy!?CB$%%8qL$&1!A@To}5at!Gq7HYo&HHO}(Q58Bu83=R^lrmBKwG&dSNjF>X0m z$R&bjTNES~Q1Pwlsjnr1T3dPx+0UapckYzt>E$)Tpg;uwY*>(z!7aQa#+IwRbp zX8_AcF%Qq(7led6!O49W?+P)&b@Q~6I;%u-E>uEFhRWM9(PE->dv)P_SDs&xy~yDH z+k&=pu8g3Es4Zc03)n8MG{hk7u00`M4%37%h-`kI#XbsYnGSfdh|o`>j8A3Z7L#z3 z2%6YGYtNh-hn<<(gUWt3t*<+u0@KcuLN0fZmK=zdc=`N`i~+ouivu3N(%&=G-ASoM zbeYF<0is~!&RolNj10@W|c9)3+97ZlVNFk{&ldSxOTaq;DV`Y1a{OM-~rf*uyO zUjQHH!YM*5V8-F^zUt&Bb;;6C4A)2MqzKk7H3W>#7R!4=tVWn@t9itQFb)x)SQgT5 zA5)J$b|b3mdJxTmorq_!zcW1@(zz(QY3$cSOS&rY!;7IJ*`}~Txb4czm^hJanvH0 z)F6#nVn_`vw%sV*4amPU5zCGO%}9pjy&`|*KA z5~P7eq!tZIEEN@!=KT(Xs;=UzWuQ-1kPBgC2P+JnmwoRVofm)6s7WZY#tI&bx0W2 zCzZm*#NmvhMi#!V$Fj`3h>bIdYLqs?J z{-I2wF$j&`LHVUQfEeaXA((@p}XqDpb39QK&fKN*+xjobQEJE#o^&jV*|@Oit?U(ewdqHc_ys z$tz2LNa|+ZL3F=7F~%}>?IcPNh6G5X2|O`79Vk{)D9Z!`mvMQP#VSun9G5AWd4U_d ze6F0=ibZQK+m%gWa*vqhAbD^>v~Q6{3EKL-IKq}VmK6}1hTBYwT9-tSTxJriw!vK@ zW698^$+YMI_8%$YRL$PDeR$ zkKNedM1(_k7{b8pJnUt*e{T8v!OKx#?#~l3tn0M-h-9S8fn<_JbB-1$doBbvEfUls zsKM}=LZ>i^TWWGDx(M8hryAp!3So=3)7KOy7;9UNmr^YIzQjBA+5exin_zRe$W$zH zpYVHLF4YtB1+!Ara8c`;MNSKXNUftXRqR@3XJX?*E)oX>ER-xPEUBnm5_q{*e}W;E z__q#oEyH+;WpuK%@LWb-B&*yRwB92H!uk~9{$2~(vwZ9aizP7>z$F`S4j#vx}4x#6oNtOq0WU{cfXsmSsKx0 zw2dic>)>EC4wkuj_H^gbUu-8PT)DtiF3t9%od=Je%U#}nw*CCEE`G_80W*$F2jQv( zO$%qb{FB2$vv=mpH63kn&_wGO@oYVcMoTKuZjP>5KZf95t6{OM+4xjmyKG z%Xv|}JO!5pXC89Lz*i|^t$Ea*vBLQzh)iZI&Gts{W2kw zUN1SMbDkU?-}Kw$LU_)_d^r9g|@yPs@iihnbeQx_p$OFrP)^UK}K*c;GaGA+ka1J-PIzlXC z936H~&I(*qz5GKXIC2r zK&|A@r$Sxg%ZOyb({+s(+%m}JE(`8u(k!Q8Mb4|M$C0PD$8HJr~{L;7q}f5@Ds6EwX-^ zN=mQ-6D*$Wdg&K`;EkkvPE;?0?X~m7>gA%hgiR)OX?zRye{P`EiVs<`It$>U?UT z>2b?{vlGv*RhBj9Ge5(aOEeRM)zD5~{oxNK<(9K>$@0#+qLZLo;a75};HDfvN|r9V z<;{zA=*~p@BGX2=rAi)mZndnnoGChMJI1ZtxCLHd_^>G7l3l>a@r;C?*tGGi@*0I( z+lF|N?UtV#MHwXc>dh3oEa&ZUwyt6J5B zW57%i7O&TwN;Sugc7aY(W3b{ToTY(Om7#s*GvO{VNWE#-ZduXrm)+*2;BW=jfDi0Ir&EFzw_`#kgIVqGmzCn409$ie0yuxQjVYQZU5!|53%@~6^>Ej zh3}I`lm(NWkaJR z+^?d1a=YQp)_eZUl$DF=*~=0ya*rh4lO&^u3jxxXx-HcwNicJ1Jem-Xw5Zr@} zu!A4W^w0R&r>JXYR}tE?9!a4ZRds+p4z-#Z!+DPq_@v)|WB0V0r7GXVTl=c}e`9GJ z1){w$QBfqP{2I<6$cMThL%5l}KI)wePzh~LVX7#aLrpo^TdF)+1`GcpaU)V6`_qGN zR)PkGy&6rYI+OC^=du@T9?tzILYEGRbXA^_a9|n<4B()&`b~$k(x(zp=TR{%tNl|e z-{Lmm(?aXAB@*OiqVADOW4j+mp{$SQm8F0lj}B+Y{TD08qgT(dGzyhWR(|#hugPs| zc@#q6iZ4sZ*g(N#hV08$LyLH(moFrJTou(^wm6@YCRz+zJ6lz-NStClCX{?S;+j*6 z#rdZ#be38C#d)L!1JM@U$V*+Lz^(Xz!Dy-fm3$eUno7Iz+Kb3@R67x<0PO&6GsebN z3rEzEQiLiJMB>O($P)4^6LlbDS$!>xxvHy|`$}&kErJFZy9Sf{6+a4&g?*dib7gsk zQ_eOVX=f;h<*mrOJvw5Y&bBx%!9nF)|4ssMCEyoro1!e~nb})oougUvZke>zMY}3{ z;lt9Yq8rk{{OfxCEAw4x<(KueB$N||6pb=`i-T+rD5%jK-Luq%FQZWf){COvR?Xws zVf@-8MAjj7vp+k+Z0GKXD7})09KS4wEr$Dhg&@V3*y>k@B!4Ga3d39+oof}qTE^1l zrpm0J{N2EkWe)i=$kmE1tG8&eK;Xr;k{in%za>IwE({KX5)o5KDsd1ESjorUqQLl4 z_lk6p&+6{er%9UQll*nDpiM&xK1&U38I6{xuEw(eo;%5(LzRW<^l4I_F?Q<5@wOG0 zGmfd-{7q20xi_Y6<{VvG-&9y``1EXUtLFb9y}M*o{QnlcGyYvpSeGcCL@L_*ApDwK z!lUH!>H6_%lEK4~;>E=P;ZFi2EHzm*_{jp@i9(=6FBHN}6Pr1Kt$F;$wI<&NR(dY~ zPnw0FAP_5#g_hwLDr8po%bAFPLjJ6@60MhJC{D;XOm?C@4_j45+%S&}6k>vq{K)kZ zxWWHTjRg|4H9VPkR?D_->rjqy%FfiY=TCR{etQ0BciX(3BEb+4mg=Oh7#pk7*D9z` zL|p{T$QEVMAd{p=kRVANU>(Vw^IM3`F13$C|VkZ8#*!~KI0Q(@ki4EB$+ z00XM*(R$OGk0mK0FVpVv8QZw9^0Muo^Ewk)D&WO3lGcNx0bAn)IaHOFM?|*X4ypmI@xH{=%SZHym{r3Xj1H#9 zX;=p*?3F7eu&_2uu(uD(cFUd9+g~me(4_-ff>VXJ41$6oA=gP&NU;3p)z$ERpRBmS ztKt_{F$IO~1q)p)g?Y*K@3dXn=hoNp`=a!PNK!YmBek>X(cKkk{epJ^#xjC!D~#58 z`DjSp9J0I;I@(=r{_w~13gU-9v4?m4?KmY89S&oW#*PhOd; z6(es=K=1p<-T%M6H}7uiIQ~BW_p5+3zYIZ3+_gKgA4;NZ#@a@t;v_mg2uMN_A`;*b zpk!I`y!QEgt9re-;Nmz|o;kxKk-)v()z#J2)zwwi)sMW{-SLiJNX7G_?Yz&5HkZKg zMVY{iRE)jLntZ`$oC_mcw?>0LUzpo&-o727UT~DWjpmtH5hnQCg~&s@5?3L0VH6k}Pr146!~eYoqiy7#h-^ zGxRcSe=><$A_MX=;!|beCEmy5y*kl73>*-q2uYzKXE%8Rg7K$PeioaZtfm`)&bTnT@^Af4k#6wvI6E5Nt83Ns<; zFSHzuouG3Za_a1$yeLy>KQE4(7R{Y`nbxO5^O=W3XsDQ$^&sZaVfKZFW$uog;{%GE znGPNfESDLknwWcoLC!ePcTY;RurfV5F4?Ad^OnqQXS`bZFxcziGvThbGZ65s{8i&9 zmhM^Ttl;lWbSYZqaRzFBBMh?KB&YH#;+L{g^lLrz>j4DDuNLU8UGHpg4N2~{j!X2( zDdr5nnl)x}g32w*8(%EH2AlAUQG^@W=On>Z(eHv2xE zezb57tIU_R)ILO=;6FG~qM4BG;Fy3bLTyf`$Ao#DPPDx9p1zayk01uLd*T*&-OZjW zL1Et`7sDG8!dTkS$$(s0M6l4b`J3hWCF@^md3X13tZiOg?vY6Sn+h|y-qGuj+^z=< zDWOI8=2gDcT6wKeyFpFB*Tggwiq>Y!uhkW-*`k8zkvZ?x>5nJ4(8ouq@4ROQ;7WIP z(H71RMk^V@TN&zzbRz5N@cr=Mw0{WSe>|p)I}_P$nrSUTld$mye7Tv`E7oK&xgH8V z9=w+BQs{C80M;AcIir^oK*G}7@ao#Nm6Abcp1!O^KDFw)+*zdzNePTn4c$dxQns9Z#6*iITrYboh8@uti$(i`d^r7Qx3=p8Bi zBC&#VDyy%{30f!x;_Ta6j28>R4mO8j|8U+y0Gd%2YlFWs863V|;SM7%DdA*4CWP^a zNoS>ewQ@_>y-1GgOdSU--V=HVF%s&4)ERJbzGxIQa!C!~-a^9S!NiO`?VXMgF$WR~ z^$Gi;cWSuoxENf|dcqU_ZWJ~2%kpjS>0Yyl@>6%qSz@`Dszpour`BCO# zk0`;5KqqDKtvh!SKHLOa&H#_iD(nUHplnrbxDE4O=gHO++Hm3(-oMOXDqPGBeHCu$ z>|-13@`i6tHtB5t3k=57|8Bgcf`;Pra5wO>OCEgplxsl)FRS+~U_>2*EUGBHm#eCK!!(Hl<@R zZ`4x(w2fc@V>_2+Wn|O3?7f~4Q_LoDFzGJlWk17R#_-6p-|fD7cfIqT3;3Ap?^_GX zbX%5sw>*v8&vGy2pi9|5!?poi5v1&OuJa2z9RC+8Ih5ycDeb1L&s>z{{5T=k2f7d2 zEYpEP)N4sFWYsQrK_b16QIye}O=OYLBZb;vk3jKJyfULVdQ)3$4Lm2)f{vwS-EKEh zoSg}I4ksL9F_>g|;Y(K>&H0JlTT{v;O! z`eRsBQa>EJ!Y<3|pmP-ao)t=|C`Q?Gq|R9VSww~-gs#`gEYz}%)-(utMSWp)l`$-` z2B(nNnFEEA5AwxvqC7~MKnn~~g7&cIPl+1VzcX5c7@Ki}r$HyAYI= zyj-WH(Wo;NUCtB0Agyv}sEElj{ybp<`)o=L?RXF&%a}Mo0hiisp?R^jD$=K0D6f*b z4}Q`W62qxtnz^DB;1oag1Xc;S3-E79F5u8#aZE|VQOM>{vy6Dg z%B1Gf5ba!Kor*XZHCY#CxU8mJm@jz55c}b)G_1{lQIW>2icTH>To5N-U&d*x7AjYU-gAyhVF8)4zpV3~XIkY! z`joJR`V(E)6r!h5=9ID+{oeRK=yr3^JGwJ-@@cxV0N(&Kge8Nicc>p z;^8ty_{Q(m$=mR-I-KFp3gt~4%R_VVso~=K1?;@+43N)7@o=53)o8sJGr|KmFT_of zC4eAS^{)L|1_6jsD1jyaNs7_+f;?1>G!(BlC!wt@?(hhJs^aqo(lNWtH4M>^L0>~d z8Lced!oW956oVf;t~nE!#X?~(p0aU2hY_6IHd$=;I;nmoR|F$b?u4LQ2$JS}4-Epn zY0$-k+2G7vBXl;YK4F;_kTeKI*B|1`Z0WvxQ)k*SS~Oxu3j);kEA5luGVCAa#3_dC zR}v}rHLZFkKEHACS@Wvi=$N}BlB;I!xIBqfL$VC6JCn@L&mv__01@Uwes#Cv^=*rk zw>1J7XMXOG=3!C_hoI)s4tyxebHtE9dVFbLb*^0-E)sil@@lBlJ647ytS1lX7irsv ziB|-dYf0qt{*%g=EoLH`G>h;pcqWGK#x2nY^Dk!2BXgJcKoKx-@b(Zrf9jqnMG*_iW|BNR6fGrEQ zKTgETXd7%*X28=mX{Jg0hD8=Q?IVK|D6tPPWXh1?aBqN7Y&bs2_AIc7{!#BjmlkTb zw6Rh9p2(jrr?WvbDFWCU^??UlN}%ZXEi|d`i7h(QNVh zX4##a-^4lI07_P8+ahoKr6MBjVkFqpuyj!a@dOu&S(A#-IAnRqc zpbFM>)OU?dY#je>iYHR+T|tmG*RHD1Yq^$mDp?MozBd}ywn}HB+HhIy>@mvknv_iF zUAs2($|5da`RTiBwhB1lx?qiyFiJ3IhcrwcQ}ivD4x{yusqXm@&jK9OmIS*jTg|sx z#`{!3tcEj$QOXnV-Nf$F{5h-DYD~i9^M*6^3IVE8|1oZy9S-kuv$yGxsf~ptE@CXo z@v(H3mmQyBH7-ell_57-0c8i!axYqhV57>Q><=D~LvSry%Ca9O6Zih9405)jiuWnP zcQR=bdlSE#V?4YwV~m~Z4S3X>TY(I!*I%DJ{%$%we&MGYbYh`6omQez&fqNzoW1(E z|1;;*L0bYnj*xzR!eyPv=qxP_j`juzOR^kySfiJg@Tv(beYKev zYr%4v+$g$jv|2qNE&?yslGdoaptcEQjYI0(pAbp?gZmb@+|`@Ylf%Y@u%}ps@9Rh% zTvyf)3teQ4vuDpdY1)wEd7i{ig@P8zpLVp`C6G<=g#4p3d!CXNAdwBw{@c@$a+~B3 zWL#+SH6Q6jc}JFBxfy+G`rQ<{Xnihb(_>nwVrOc|IYOR>=?S4O!0&(Pf3$@aJHW_d zUrq)DK;@y?Kg8BizThZ)PqGrZaT+#jg`Cn6jRz-u#Q>U$wCj&`c`O%5>xhlC zEqjP<51z|jMN@Kg9$ad_GGD=qepCp*>O>9z)VG5Hc*@Pn`h^D}Y^*!|7_p_aYPnAx z(ND2(#Zp`HMlX=Hp@H-aza9J%l#^S32gTjGQ`BXmjzN-93G5M4-b@RNus!Om9Q3Y2Fs{zVMb1 zT9a>o9v)w$jo6{Ba7d=5nKyv4R%ZAo%@SHt^yZiPWuonYL>)mT$OjfeLzLPT0Aq)m zD40l9FNl>qEb3xaS9~4s@A+#tl!+XPUqQ@KViutTK+;`o$4%GO(D0N{pb}E3D9qb$& zTq*Se%}8&MI$swYxx`7nnTAbOQFEC@YACc|S60hEe?{{D%}M|02>EVa+|XvDpHNeQ zLibG1IU4^Qncf`x9v(~dX_yH+77gcFfh5&aYc-WGCtx}@1w82C+pXQRB#cw3=(vt& zCAL{~v7w1;WRCOJ=8#6kSn*HgP%Y^T<2%D-CO&sKC(yz9h@!#Bh_CjzsaPj;&4hyO z%~C%35ilE%CLJ`nBk^{1A{MSiyN2{c`9ompm z)}?XCZRN`^JO4|Ymrphe{^*+6*S}z@v9%$Ns8*_1KQ`Badc_xoLn|5lGaeK2I(yWS!x|wWl;=dQ|<{a;Xhp28fKRC zqc8I$tJ`oql(YbOY7>#-*AQDpjm{D&tE7z#NBf7TwviLECa@Y@=YXEbH+M7~b@}S2 z%zVW~96B5>Ku@bSY9z3Tn#Kb@ptyk!dNeBgw6k|O-hbCfxG9*x;Krg0DP@+d!uPSxy4taI9NNvt>rk%~I*!bvKnph~|}?D6Vi%LZJdl9n)#$;7M&!VF?vGlW z!k`xHY1$FULr!=|(4{VAVyhIU<`Sq?{4o+a8))jitjZTg5kfy%I^5uyf~}&Z?OvAc zKo$ZjQGzw1&X)$n-O11vu)XBJm=}S^KLLW z_O-W!MV7&1HTZfkIF#|#4Y(yxlD6n3QW?#dccaeZ&Ad(K`( zINR>Z&hlvA<*RX8|1*ER9@6E6t)`H}(&;G3|EZX4diiefQI7*r^vwtnLU|hpaP@kb zmbWmlb-R3tS;@|{t^*$CRD4Q8=|x(7mIP# zxlTCN9lWYde5J2;OPniOHgGNghru)K(&H=!AUARbX}8Y>su=3z%1W{&mCw@!%ZVj~ zyabyz=F|DJDWGh=?#oV!gmN+EntfE>s5AR$1rQ0|?Z~`2X=@`{+@(9H$#ZPCaH=I8 zIN6^~;u9=7l&crJ(jf~iF}ugCA~(vEjx|TL(Gu6e^E-59%IQ1TtaA@5<_hD%9pNg9 z8*8k?i=0~3Mxl~zc^WkYFakF7P%af9t8jd1j!GLmhEjyu`P-0P%@O54Rp| zzI?pfd;aY4<0qRt-`~5bSRYi9eLE>n^d4zsbPJV-F$>!dTSv!J77JDPABmplo4eoP zOyAs_SdeHV!%o0VKq6)(MPVtN%>;QUj~`_cWMK>fxsIALj4Y&kX>GOPSK}Q$lY;r- zpj3@pQA}%0wwinbsGu%O$de3L~K&T;mMj0>8^qF@7=jmV2p-%-89@eid~qPTyF6 z)z#a@ufJYjRM4jip@zNBZKh&Y?phcBR#jMgq`LG=gBpr+OHEaLq{xiAd|8|;9_sR3 zXLv^GTaD7(H95aDm*CW}Pi8uL>jv})n3Lv%;u}Vm`@=WeudXwfLxs7arVq6a!{ zI3FKwFsbn|17Kkr6>G^;1h?C(0i0CG> z$eLZRbxB0H;;P9Z1x1|77eM4r!IxdHbxB0-7)>jR*w_w7?l5xs9%M$+SZg8iXd=FM zF;NA|H5t4hn;Mxc@6~G5O!=aF7phP&NGLDEcrh=UEi{D&DCv@hnu97S)0lZwFbCoM z8co^3mP@A1Gb+rG>Gjz-kwrAIqj&o?7OD9Skcq8XUU??Ja)01%@9DFhm)j5165OO& zQ}|5m6c!p!Y|*&mVEn{Vdy?k@CC8UZ(~Ck*;234uR3khWoNWuk+G?tgoj57Wp0PBR zd0Xk4X1OTt^hs-PnknVV zEK%!wD3(i6_2r#q+oyG%Nczoc3?&OG$g+QAgp4F~2$6gxNmDHwfTj}j?_44u=D(v* z4KsbxF8^NgKuUY`rn?PQTipi`eOJ!Ql_P*EaakgE{ zQjkxOGNGZR;;^BZ_LndC)z;&K)8h@ht{GFX^m5~A=jTS}MQ|NzI7727ZfsG9D7~!Y zL3GEUlWoqAIWDc=iG*RYSgIf|A@gfEz3fpU*i=0Ytb!ffqIWQu?4Jxtokpl>7#B5W zEySBS{0o*7M&rrmUwhAD~c6`{QjHr-U-C-tnQY*3KqU{Onctv^? zyA(PJB#66Xn!iZFVH=Tn5t4Yx&%_1hs+adrp1;l~aKyNyBQJ8+Lr@VU%!h9W)4$k^ z+-B42y#S9R7qs&>ywY?DBJ3 zY(CpoVgJ`QmtOCWriZs~*mSb=(Gfk9B{OLKN$sllg4#0KTs~fKzD<}mIz>;rN=i7eGFFOMYAe2ZRUcVu}#Ca(ZR5~)vgHvjOf zKK)UG5TeW(pF$#1{7Db#Lp9C3DbL$oRtV^(dT9;{Vs6r?wRSJHWZ&2G_q3p_x_0yE zVei4?XIp>WdeG4^Glj_$S3&%v#YM*~QF5Zx>GBQkMhjfW-?LL^{H^$nUpa^+$j-lX zO!7^JTy!XPx=D`pi#Ghc<{pinAAMnz3Ju2e!XGS|V*ijBassglRoEwFJx+NIiYEKo zEp389c=1}-AxYC*vyJfj=CHo-xT`mEEyaVP>05<93|)x&9vYe^Mm% zWOw|7XNoA6@zBw-zJ-YrrQXZ$XHUA(LpcZAN zL|ZFtUTlq)V@i9g@LD@5Q>;U+(8}rlwCBvwS-+EnieBPdqy6d;OM>&n>|IZuoUMXQ zOyM?1T*&Sv1G?J^1%a&2I7&jhN!M4CEC)pmMOQZZ7R>Nws&eSpO6W$@l@fYPo|!$R zh7qE~s^ci-`yWHY_N_jfEUZdXjJ}JF@>-}TmT)3^bkab)0``x&pg7PAYO}e#P%CEK zyO98x!K7>zW!2-d{p`ZS-QL6P7lGELHZ?e8rEIj*Y)JUd$sAO03J2svl8orpN&_Wb z!LTj!`21>YKc#L2v4av@n7*=_u4esbUqu2RS_-76_#q;vh;}o1Q=rj|K#0&-o3}j} zkz+HYkJ4reqfvD|xikP|vbHQoQW9u@W-7apX$npeq2sqbo%Dwc$kz7Lzid9{xX(M{ zN!h|ln?X;J<9#?ftrP{{0Svxb<}d`Bt@iO42OAnZ-n~#YGnaZ3H39FLJDv(gtqa%) z8YP!o$BqS;n_b_^PeRNz1o!J4I^T5G$)6&BK3w?VyB7#D0{C@4(K0{~v{34lfyf5z zA+o53bVHE%abU1CfziK&B?OSt~cFBTd7=4!bD3Ga^z@en#UOx1JHs4V|7MCrwW^9q{c?sCxf|#R3SN2 zLgUN(y`ikKG6NT6Q5%|c?oP6bl}|j^9$&O};rPk5_b*zzbbjUPhjXfD6$k=hPEqcs zjrBR9V(KTt!pKRW80LVr+b$}6d?3;OzLG`Fk|<7jk*kfnO8#nlpX*2NTU*VhgY<01 zXtZ{7tzkI1>;%w4G#W2yQkx23XYo1l(Lc~-60!^!l}THw1P*$TGqBELy?SdF>($#W z&+h!za|`5J=hj6hhvs3N0)-JcPnA-91huW_JYN(y=7Djdv$Cy{vwBOVI5FBPIfJ)U zO7o$u7O5|k*Pu{0+rt*;P6=`R@-f+byX}*sA&oLa6w_diOw)iBg3{NOPjL)Tv7Ea4 zU=-5_qk=uzZ{&V0TTa6Lx8?1%U$@kVu`b4hNzP`bGpSV!U+P+VmOCD$#CpRJe>sUD zTf5VZQvvb5w=-JXXqnv`YxV5DI0-`kq&rvFWJ)|4RWg^ibbO<37Rlx(s4eTuK$p#O zGC1U_F#P>*)Nj+*LsD<0j@NMwtt})K@r2g#yqrbG_D3Ie zX5x)bf(>&Zdu^I@KLGGB#&DsP1B&!sM;xh4|FUZg#BL;pyXi)q)Gz!x8>!ge0m z)z$BS#H-c93Lpf<+{w~@jEJ;gqPosnRVNSd#a7JqhVLQ`|8%hbc7*fs@bF_ihAQT= zBP@{}*wBs0QxKSeZS=hE}VNG!GrVcI+$bWZ^(=U<6>yv-G27q+aI={?)<%g zbGi9l=ysXFQFN^RI+gb(BDL?*DV^20^V6#svq;&jf@h`&joJu20B+Bma6a0kCcHzBTZ_fh3rg2tXQOKv&?x@M_i!!!ua!%)p~+OvuQ2ZCh&&43}PEu5wrX+ zYBI$@+PqJ(4WDVQsZ-ClpKmFS&1BI1mk++*+U?zc`RLKsi{8%m-?#4FS-ZO~XSrW^ zW4}wiNhZ&+?Rt-yL#N>?E;P79zb_48XII&B8JF%KonZBq5ng6+k00wC503{~Nd(?w zZ1bGj)!l0>-k8;&eQ&`@09CeMcG$WG^>{KkJs2;YaJPg(GaO{Lb&tA~5ZK>dza0)3 zvHiDF2>?eRLt6Rs5PAN7ncywMmu^WSRms||jXO6wSaZg=Z{IFur3EL3od0y7Iwdc% zs#k%i(%kg3cS_`huD*EnVr>2mC3$i>LG)PI0Q;8FG1+6^mv_7h%cpba6-l z@gzM>4;vXiG&Cnq!z~%c`O70R)5yJ6hQz4Yhl>?EF|UmuJTeY777CpZ`{4@^r0X56 z7bOdY4afQQ4U@Wl>Yp{g9Joz?qVOTCOOTtdQbnT#o?fvE($Ss9%oyise^OnpDe;8{ zYJEvi{7ASS(^feYCd3=V6O&=bd;|p)-_QBYkAZgiQ7Ts+`Sp%_Atsu5J9kAyNVRM* z38%=fDSv)Xo$3in?5R<;rKfAiR8OAR=?)XOw zExH%sTFLk&l}rU~hD#cl1az!y+|(*7ZGXyA>yOKI!kK*pmq2`fZHKCbfBexvCHX=z zl{WrePEX6?Exjc@&EWk#(*Kto!(=cTBW46`San&e+5y*xua4JNZ>?6MgyGg=0<0Po zXUiH~O|M&?$^SW1Q1+3Thjt1IXL%H?b$fQmXzp7(`7`(J-r+lM(IihnXk@Pi!8LG6 zLmLKHEBf4_3?io(N*gK-P|=e1)zMNC_2%`}ySLYF-XumDFExHjF;4yoquNCSXWiwn zWAQd`whI%iuP;jJQ7$)4utLO3F8dxzbj zoRUR>lb^_0o}BJkiiHsQ8cE|Pdbqg2c({NdUi84X&L8PmJqC&83f5uZ8rAFWFpp-S zpatI7ofc@!1nhgDipEj8qZGan&^sEBmP{C6YAxD8(KG9rbUc>Ie2S%8y6{vYG1-PLijz-XN)Cgus z&7t&Fj~nE7l$FCcM#^xwnjx%Pq9h_YKoMtpV>I0n469tbE~V$4=ak# zv=BEd?4La8G!tfaOoU6z>3Th;Wgu&?N)hI7N?z6zO(tb=>_!Y{&}q4oVotlpCb`dn zj?H;`IdY$mUl0dgFbad%n`I?tbul*6vA{!1P&Xi5lrGs{bec!elAeuKC~}I;8geX0 z5G=jbY8kWDG}hw0xqmYlv4>{+J@`rIBb2S-P5)%CkGUVmkhZKce_Q-LmzL)3yzmB! zS!(fplOhqrfC$2UXfBO-*EwLdH;!p?u@ z6p!rRDBqxRS=p}L+aGkp+!En!)C;7;Dr=d`H2X5*w!|A1evj3*KuOakFmZFP#AQAT zf)KLZ>{NsRqa)^QCS<J6RjTTQMG<6lD|yl?5p!9{RDya{eu+s+$YuLu zIaUom*L}<^dj`OWH0$6lVjG|NR7W2P7dSK)D8jTVJ=K?`l&pipPmWXP! z+ktYhG;mvUZ7u*to@WhGVS*zPcZJ3(N)t!he6J|R&`yb0Qs!FTh4DHA^;xB^Xt#lL zwW_z0V)0jYs})$?N%bzy`lJlE*7J=6|z%1ujx#IjZRUS69IEsW>Hq# z5=}uPbN*JmU1df}ai_*yXaZC)aoT(o`O`9{t)X$&nZbu7vpyBzG|zuCIWxBpwPE4c z%OCax-ivDNFqp*WNxcp8sp8GK=tT#Wh@qcWrkY#(QjDcJSF%FO&i{8CE_JhD>CZMu z)nGOzV$fJ-gqZ0o^KUK`4YkZLbDQ>!a$?#_s4geh>A~DyG zDGjh=EK;?(P6dxsjhq{F^cv1@TUYc}x_(8qc{}^{Y~Cuy-^He+Z$P_rdKF?Z1>QMI zF-sDe3zntm%VLdXIgWcO9eR+XJ!wdFq5(S83DgX<40QfXUQ=+HGbHM$tj0}`HnQF9 zX0pb%4p!3}{abjf#Q-#{HiM!as8?hH@WEBa2Kh<@_BlyPpt?$-K2ypL;&UWsUirSJb=)u%u@q88AKhd02!p?y{0v+_n%|hHYfTQ1&aO z()BdXT#v)i={QAn$rxFNeJ`n8&;8B=i60sfXl3-)>3?lSJN;v2!=Qv+i5cP;{bt6n z9(S+AgMc(&p~|htek9(3$W?1lwCf?jO}Ka!!wE6{$!D4lk?@@&InT)ve*b?vIZpwl(dW-A0NQ%|I|jM^w}kYxk%9aW zE%MJiKfkNsyHYgi%P<1Yk;~#uFUnn*#ePZ2;6O;ZO zkM)OG5Z|(j0kU{F!!v4lG9cLbKpK|Tw>&&uZzcmYEQx>06|x%TWy66`^0MYy!gy5H z(v5bvH*VipyR*JgcA}FKhZY!DGh`l^YPJ+$xM(`#G1K>4up4^BEqlu9i;7&dw89PL ztE>JhDFdZqZ(WxGW-Y~Ra&7TNiCVP82>iwbZDE05L(l}~Jc7o8{|-T;&_dxc6~!`z z9S!=U3F-T`pKSG>J=xy1n}+=?ho!^WBPfsfdej{pIk*|hq9`__ph?OVAXmYtGYMzf z{Q!Y(H##J%&*8_Y{D^BqhShJramHM<8_$GO$+eQ};s6ut^_)%I61((YBZqsv{@(ax z+WV(jwIqN8f$VX2K^I%`#6-4k#5fv!&lM#7L;NmW3(7^E(x+`XQITFRpQPxWc=?|0 zEU^l`{lkIj-*r|va-IJ)oWAhVK&$Tb4M65K3J)jzs>TV3oeu2ASw>V>Kv!#v#1)R6|9lFIAe!2rWw@Z^Q~G z$5&zvxvMNpl$JhdC-LTRxVH~mLt`;ECrG-Eir=V>D{K0VHVHK0*I9=+=ff6@Uz)6M zZI2_rbLfMH;ob0%JJ@jMahm51hjS7Xk(Y)n^qeb`q);^{tvLlJY?eP-SXMgzGx&*< z`^b<}^5aGIGQssh_QrO{Tw=#YXSwnRzN|+DA3)K4V<@1GfLMJ6Ka^xmI#a-L0zN%_f4)vq)8Tw{lso zKZp5Mu%}$4^6S}6fuAd5??k210|Jc zjXZ0|r+X8-7W&P}`1E*reDY?6xxh6;da;5wvU>OC#@)Lskwqsf4u1LV^eD~)pmBv5 zN7{5|4!1cnTPN6J0=ROWyAm-$VoXoDJd8v3R9A*VlX<1U(|CnaOE&}U=Llo7^YsqL zqc{INvKx~tVeD4G?Gd*p4W}P{lrtcvz|D;w`B<4?cUM<$uid@7e)Gm{0txS0ql|}S zS17jqlwwP5I&mXe^$UZruwj;n%0bZe}w5Xt}I$WX>%44D{N{4&;pMMWh~vMxyJ~11K_FV zlTwjXMQ3vvN&Z-#Cxznwp#qY+a zCudemC*A9M4=s#8PW4$dJvWSB_fRzVgmgl0&%&}yfnL;mgbw#Nl#=e^(i&Vdzg@pi zVW!=O{g1g-jTa^nyVF(uScdX)6h>m^#t;vj=&;{>(7!a80`l>o|52QoD(_0IT*UWm z;1}^W+E#?@Gq-f(fc+AN|2nG&#XzY6@2h@Wo@cc?oID=%k3|o){*k{nG4$aN?9pYu z*Zt`B<`3+JObxb+Bf!0A z1AFuC^}DNp<^N4U-&q4Jpl<;B_6A@9y>Y|9Mw-hSp@CEHHExxdQX%wL$*)YOG(vf7 ztC3`NpT31jCJ#=JbeWC9l>lyVzB!9F_sW;Eova!O?9$TKtH^y}e*DOeHa=2Eji+3x z<$_;73yn6%EvHJc>fis2+O_86S&011L5OM_>_P+*(%nClr20=vLEncv7Z+J=+GXIc z6M(-?`u!@==c6&xntP6e2!$sM)++xXJZawvPr~bnony zsJvtde7sBgZ3_{9)wy2p=v@#YARL8DU<>n>hl1#!>QS&MoTWR>Y7<#2P)@k!xf|#4 z_ zTNFUd7C39Q+to;R-pJpn-R)QY?5H=Kh#y}M2OPv5##mjZuI@=S6UT7k5Va@|r_0zlet} zkuc1xtOKB1OKaua_X#vRs)?z~85$Z*Q*_?6D(n33EnHGpFCryub9shr4zgTk9Fe_o zr9ds>FD}8`=42W@L`m4%mGVqic$d;nS}+*J&i*NKmp@2Szi{bU2Q0b^Q2H{jZrmwK zc1R9#EaqV@9fWWHr*4T(L-hQ1GNB~&~Q#`LHS zMJA5l=j`EErf2MlNDM|szn^JjgzIoaj8MeFF6ibgKe9%q_RYU25tGb(O00+E*bMJQ#U3<5)8-?snbrwF=o@#V-d>*+{EvT)q`dS z3b_maMf(2#I%}kacBC_Ur;}F##?FbNoWiw7;DV3@?=t71{&>F$v9fr=w7(x z%T_E_hoj;CN%V7uaSOEr0)9tcm^QyGI-a3OxOtIphL>BloP*QvsM<*5;p$jznFyre zveOft*th5b{wPyxIOd2l>bJF`x^i7t6d3**dbAjq{GH+8?KVR6T&cy_eqO%zC>>OR zup(N+>m{_)F%iQ(qFVGJ4UDSdw5O_~>-ZF5rum#Yn6jFxWO`bb_s9SvLo|C85W^^Z zwrB@o8g<%om`_JxpoMt2KCK{CIozLRbTxN`PlxnF5dn$Ml<(@oH|xc*^7-}q$AzU4 z5ZCp3)1O&`g0EB4S6fKMYkxc(zIn@R!>iR(1`eK0ruL~a0ZH0Fd-&{L=Ovz&E*F|( z$HDuzNIcy8A$ldTBvUQgLp{}Y6H7m5PzeqU?nqjc)`^)>u zNJ!Q2rN1m(z?i%7oLk=ZnzQhq`FYEz_?)+~tkfmKtZg?quM+b@KhX2BOhwvIj}H1L z==@<&g0Nd|d#|0mCAYPlwyd|Dfye;kV0I>~!KAlk&#Iab}Aq7fUc3ag8l^vAuRO`X2+4O zllGE573>?)U({X*b}c$w;VX_~UZ^A4;sP^0Aq&eg*TkHsiRPh6gUfJC(3OU4{D^tw zO9+wqfCpQ%1-p5tdv%w7ByUxmRT;^M^Nfy0!R9|fe6vH*oVxbS+nW#Rn9S~C6P0OqdUIrND)MD zZc?sbgLt9R1^j$>Z#DgVCdx`TpO#Nw4kKaG@;QTqnaecg1Kw%rjk70J4V$5Ix1r5Y zIoqRJp&2b^Va#-!!rv7a&0Z&Bi8oJ? z&17&$7PAv>bNCs@f8U&85{a?ASx6PL4(>(@J1SFa|m%3DU3$X%B~WmNv4`mNOy zDnVWP2VDO@pEMM|{Ld#tjlTi%FaL-OMX?bRshmMVqN;)eD(R50HR9R|(NbfEx5QXd zNy--(14^DOwG;&GQ$m{H8sbF;N5jdn7%26!ik;7Bmy17%;$t_7-?Kpp#{wJ$%RH4- z1WdKL{7h_NRlRI3Y8X}ZGn&h~N!grr%l8!`Y8ih8Z}&Wu)NP~88CFVSp}63L=V?RL ztf&1{RZ%l#rUnqUCwL&n(=pk2;W*n%fsVlKza8wq`vDu>0|e(gUUoT~wg0ZiMIs9E zjbD5!VM|F5IKOLwD8R`Iv%l3W?9nGc2@q2K&4^PC2ShWmluWSPvu9GF$O|*?!J}nw zG*c|fv%oRpyeoBw0t#(g%ADgSZYf2NB8(O8)ME7k;&`_)iEOSe~nlGCuxeG{I#hwj1u<{X?Ns(iMeB=1{(NS)Ed;eaz zuN43OG8Yo#Jf=(Z4CP$qXf@Lm&bpo$Lfh^! zQ6W+p65OgDMH!r=)4!gh8s*m1*#r0}q_cc0XSEJp(E=B%63F&pe2Sqx1OvJXmZIf= zMu?X5TCr!UOKIHJ=rX21(<>!xo3a3!0!PslC%e8zRL-4^TQ@93Or$NDQoJOfJv7Eh z=z{j*F^!1-vvDD1_7hRaA|d>|T5$)Vif})&hHgicW1GSld4+iDcQ);VYH1j?LXr(k z6_+Y7*E+Xu-rOJ~7|SgmZdGTuqtPU>xUr~_m>mL)8nR%?`v9ecP+%H0)WtOc9dF(E z{(c8hYy^x)x=4|ju@@*}h{1Bv4CKr9V6ii`+hV!ZYjDUR_n`Khn?(GB6vXDpzCyhU zEY}GJNGHo*hJz19NKTr)Yvjoax0Qam64$-3RqrNgTFq_6GYod_;0!&dplQW-LU3*D9PRxeU(bWhr@hUG4_|EU?DW=|mdvInTTh<7_}i@; ztR-V}uezk_AHwzrAGvi_dQrZ0wnC%x_1Dr3o2?M|F{L#D(4OFwth3BWRAkt&h-vM{ ze6n5?!y_gM=%iDwsK!x7WNCs(2%8x;B6iHrMxxK=c6fMt!oJ6LF4_{oA7L~Yt`nQG z8BUmGPToN-;h#^l?rXHT|vUu-{cWMoZ%ce)`WwR3HK z^$(26=G3BmYe1yo;UqWdOPDO|59h&su=zYl{si^zttaxX?Osfo3^4r=8M^)C<&&PH5Q=m*cQ&7rxcO*^QSZQRn%AHbYV8Z53=n3% zo5cG(fOZ4aw(UM;J3ewcYA)n5RU9cG{K(cNG*AW@4Pj3vAuaheQ8dy^1LU}_6?6?% zeBWSMV+60>>2eB+a~JQ+nV>#?Co_h&K=QD=^&fTD<~fpN-;NT0P#C#Uvu~-frK5OL zHC9?o6!n7i5Hwz_IsX4??txA?fQk|8ARs0kU>hFEbZ_Shhx}HTfX##jT<++##di* z>1RnnTa%d%-@*%{VqnnVjPzd;&x#*-b$K1dD*$ojhtruXWoU{)e4C;*eH(gb8x3ur zY^ry%Y}IT}f)kFGWHH@#+PNk;vw^Gr53dDj}S+cPnk9`ON379qI~sH#mP!x-1yDTm28~g#1%~Q36Q4Y z@mGAo8t>{J;RtxsmwtfGvM@I54e6X-c1`Hdv?!pqO{}+1P zv`ju0;>jN^-APGVoP4;R0#PFp3om!JUU0%@;lp6BhsWb&p$z6)c>L_!r<+f7q-Rcn z=bO9V=`FVoq>gnu3(tRe*z)u{6d`;3mI=Btr^U^u-%>`stRVJyI5Ya)JP(aayjP6R z=J7E~p4JHUX$dZP&tCW-j28=_RyT%Gk{5B zP$vO{h-ICJiGl;s0@9*V>3k{JB#i2VFnbZswiSqo)dThl!%yfhYRibLNp4EImM3qg zW7lo_W4OpG=l5|^JEw(dL%CN4jI=BmnE_RkIaKmH7yj`-pMLt~Pyh4D8~o)Th49Hu zwa!%<4Ui&su|g0yt+l*tDQtQ)El;fsiNNe~X4D_Bl?ZQ0`cerH&1s$mshxIrdQ24^ z2T0EnEgV;=U=?27%3>%89tcr1%{&i{#g2NontOIKzMR-m>x;=zQ-nQO3O8SiBH5z( z+9aRsq=X&B6IYTgDG&yhP^UP^6I?A$Hfr*1?l_9pDQCy}_Mv~gnFrS`NM zztcl2IYZ~nVhy@QVq_;*0%pJy86v+ChC;sUSZ&T2wv1P(UovqVd}!iObB-Y|T@f%+ zs|C~4?HH=k80o;uZ3NaC>Tp7OQ)jQmyGFhG@HETEyaUrj{fQbjTFB1*-he~b0waq} zH4r+ryR*Bw`*MfZdK;-|OKB66nx~(P53nD+S{RRXrhDPXZuWjjCK%XYr>7H#66A$V=#?+O?EEiXX^F-=>3kxcJrWp8CC2VASLmp{ z$1#rX@M&*6#zZmt7pM6+sr#p2I>~-zMMV=)E)Nm4!Ir~L>V}LFIFxcTWS@)?Uz8*mmw3f7#EJ#DS(#0L57y_*_3ppeE0^-dNa|V_P4Goqtd5p#)lt$Vj zqN;Ac#uwI~nsdkQqhnsorND{IVw3wai4~GpwDC9Fej;7Ue&fC0`cORl6bPG^w~Le3 zmg`Ln(9TJ0*iGLt{4%jjngRk})$+3(E!8qVrON*e^QRPVNvwI;rOQ9fh=cJ9jLzC0 zgaJaTjo;fZuJnizrImoQiDbIbtX4C$8D+Pw0|p2)>19>hRhqo~QPfxGIAYF~ETw?U z#kwk&k0Iy6JeN9BBpy&Jig=?w3@f{O>Ym`;3HnVDiJFGacez&CP7{QoTq^V*9;rQ* zDUd)UhFXAK?D#zZem36bHgi%L_N1Km57Lw_Bxx8MY_f$kE!B*epL@3PxID(c0crj? zf>FV(WU7%x(iHmT5kH1k=8D!!EiM`afH4Mv%hDJW4JNwhaW)L10tA3aJWO@2rydf4frR9P`_Xph`@&9qDYxzObl>fcN zu1_{sR#2Coa`Z-GmwZLoO%T3S)>0K~+}9E%s4oLS#|;eoyGdpz-R~rtofp$U{qHK9 znSog{pWx^iAK7*R-H`B3oI@4`AogeoS1oih>aK7+Z!)1EfRP9CSO@+xtl~JUWL{5Z$KBp%f5(DN2X&1P73owkcdcMO z3dXE}Wuvn*QXp--5)%rhbCCYz+7aQnWl*^&4Z>(mUsy!fU*rbE^H^OuAW}P6v4z`z z!kE=t885^^jz@QP$2&G_4Av|r(eJ3(r3^G!?C^U9NcY`@*8mb;@+SgT2g6{Bra>}B z5gO!YEUXgyo4P^0^l9j+jRH>-qp9b*YrX7dG9M4Eq-~5Pl)(L9cFZBR3p*ln7HAQ8ce*$33LK&+xX3UcBSa%3!Lq! zeauGsoIoXp58ZpwVB?5z!6A-W(R3`s3uV9Kk3V6$C_0r*Rk(A4sMxW>`A{rmTYI$A zYk8r%Q~}NDaDSWRc0`|i^#zi0i$D#G&7|`r#Dc_@*x0|&bD~5JPjwA2d#!1ByZq0I zUhV1(+iSJP-%yT7sg$q3e>xo>sU2ka$EA2l-fS~~QoO|80OoaLqD9#h_8;sN4_>KQ0nYF5`Vp>N=<3S6`G+ zu;q)a&ks*&aUwAF6DS?w)Grob#~Ki^o2t(_xT=ypZYhfqTg97j!y`>fcA5G|qV#n+;K@l+7LU|X9; zICzeNny3+u#5T=f!9<7nOC5@@9_`rkM>|C?X91-)3a)o;RL$_VF(cwTA;(=4k>O`1 zhGD;bB(*lASCD!92L)bx4B7G*l0XEV4@Y)=b{UecNL)_i_K4=Qs2i=-Jxmb0Z%+mv z>`PhNgiQ|{g+$Msx2B`oyCMy;S7Zh1$$-e{N|q$KhsB?OA7Q*@+WDj_)(M|o>PJ$0 zFO1y&k#Q{wzgn$ZW2*nnB2!)vfNmzdv2O``{^pSoyI>)06Sx7Cy&=wNB4Q?rU}JQoe4h|ng{#N)15!>$iKF>`rywy>I8w>YpdUazw>W| ze}RIRYh&Hl9#v({T%ljE&Nh~jWM+1}sU(!;wp z{35ZQY;8H2+tK{3+qzs&H=yPgF|Zt6BH`TG1Z|eRTuV2GlbuojnAqFtOOo=O-PBCs zOSN@FEB=`cgc6s6dUH!j?#=`oi(Crs?S~u;#oK-+WDo*YTg1mqfp(ZZzecyG=yG+l z{643K)IUPE-n_*G%i%7o)p$0q=1+aJCkqepTKW4KHR|&AZBA)IDh!eRw|I}Nh3d&U zwFn>Ds4D5fIdxv+0YAKTqpB93omUejW7@3g&(5jI62Jf9plZ?|onOx!bd5%-8y=ri ze>mQsI*&xE+LLo?9k%o{JUgf6(K|-5Kdm|%o}E(@H|A?K+o+r$pHrXI666A@8umx$ z)YB!HRV_U@r;dE|9J=C`#;Rt1d|rLs1y)zplXGgd49bOgFW#tDH5ebB(`LG8tFEl0 z;JSXRy>`5rMs?!n_L7DE9yXuNTW190{8Hya_rR?NFn@S%U6Wq%7K8?f>RmgebgzJ_ zrZ4SfEnSU>ORg&wFTc0fNXd3pJbjr{*0YycN&h&fT+DN3CF7U&vN1E4ipI~aCF^7m z6t5q&)+q))CP$!R%hU5}BQMh__8LO@<|0tYYcLCdhv(JB0D-f~kf`eyFWO;*SZokg z#r*Be(rV1&xr;jKS$j=30V>R&*7q^Wl``?;ymC1#)C=eD^J++PdRcv%S4v?qUP_QEdz;FFIIYq9IVWNn>E(O@u>bL2R9Mr0!% zm@{;64M&l!G@TG^Vyw5%P4f^nVV{bDx_rS;EdjH1tKABf8HX^}8ckaLhsK5L0RK2@s zr_S!p?>$PIFEcada-(#1hnP2?XL#mx?4rYT3Eum?$E;<F zyW`z57O?w8hhuI(Oabtz^I5tyM;2o;`**JQ z@Ba3k&7l9oy`Bj*;f@uuFL|Je&h%{(Oj5*q6z=x{rMefY4Ion=bwtwO*GbrItW z$5JhDL~18rA6oJqPEC;LPB%|D*|-p*cutmUB3pEYD>>m$N9ujlgN+i3Lm}Sdg@EHc zw}63uc%l^eR8&?p40jka_dgN|cS@okrPAXRzKp^YP!c<3Sow|7N{TXvU_#%8JYfsM zLCJyagx)_-35(ntaO5eVBQ0FHViMLO&)z_%7D*BqsA07Ty;0DH@=Jf@1_}JT+PGK~ z#9NZiNXZ5XdgxEMuU7-KgXxnraF$GRk9e973K9qx=K|j<$B+WY2Fxw0z>nlw0g-7_ zCv{^0p3xoh5yeDt0S{x5LqW!)@J69dLqaNk9vs*SU>`Kb5I&-aDk@TpUuq`el2BLl z%BKp=;#GG62qXGIC|SI}nAf`?M66G|1h;EpmbP@owJzIou7fdsApPqv@r?(? z0oD;K3f221*wh2PtYF!_@FsUoFQ-IN5+)nbN@bWEMXt?WM>u+ zy~ZxQIcVYifLqxrz@1;5;D$|3DS7ysOWkkOE9Y>Ji#u_(0OSx7cud__y=tnrh!u5P zaZ!>(9%Z5rR=jklzrCtozmn6I7vu3Bpiy1Pm>bW-8RCQ#HK#cC`m_A{&0e+E@|C6p zF(z$ON?RUn8RftTn{^6j<(vBb>*uTGx4Q%^5De{{Wc*aIj;xZ~$6kyIhKV5sn-Ww2 zXq(T`UN*JYSGjI?Oj;8{!lH@Ou3Xxtk#v|b$yNB8#=hUCdWc}=vaaawG9*^T@gY@l z`o7KbzL%47Vx09rN`;itZu@vFAi@?~IMS!gM8moKjC)Mej>t*C8-ed!M7tYsG!`x%=zA2f%|sdO%QIi&R*qhCfl7 z5bwDc{C)uCzd&*V#YvK!Ladz2(r!z)rTzc+E$vO491bXN!k?saBziz2>msEtN1waT z+hWzL?mykt4gE$pAQ9kj4LBTY?>Xn*S5>bH%{CaS0dTkm;QTR=qm!{N@=>a#)Q4F$ zbVC#9wqj3EAag0*J#Ul+JO#8f1IR4O-$}F(gleV0o#dS%}0yqy0217q|*um&S zMmEDvm?Nag%zR}z_<52Rj%tA3G=~;FA_hM&xFtrb0dv+!BQ)6{C7yn%El0mdTN_DFex@?AhuL0TJhlfAlO*!pFx5R1jJd? zQhPH>i5C`;k;v_+;7!g4Q?w4s$DDt3AzJj7PJTEBn;!Ck+H2z$OKEysWZO^%kVt1( z6+UQunr-VZw1E_Z06y+a+K%!$UY9PGi+CGhLRR(!IbznwqebEXew*FN%mx^l$1IS! z^#F;DlaA@{^|#yzuyVg-cMRW$=bWWQwG<$`a$*P<0Sd`6`T7FFSw79D$N4u&Y93?d zWA5p{m;D6?+G&KMVTY2d8$b7y+pxwOcgpmqXYtna3Kx=VTMnbkp>CXGW=2yPbDs`o zw;-Dh(AYjRp$RD-9*&Hfo=EiPo?B#Xi*{-GSesBCw^(G3b&m2S&u(X!@fTmYD~Z&SIbp>Xso&G%aqvPaD+fmz{TuI%Kz*D5Db`Ui=|f2a zO=Um?FTvRc+2`7%(g)(IH>CZG&X!Zsn8S*b3uJ67FY`jbxo6PM7v(sxJcB|rZP4c3 z?P28iIQUwzJ&gN+^#z~(BDQy~%3(V(% zkj{X3QHY?9l}Su)8+SWp_5b*8kU^TL-WHKK{BZuvBUXF!0Uh(vTmaEJI&+-^RT{`R zb5v;{o#}@DcF9E?+VxSxmxuPV1^xORT%@#k&W@vlcz5Afbc;iNy*vpRJpYBQjH!%4 zN>h{=%k&L5MjKh6nWa??EEnV21x z5+J$yF-sP{7Qb$HAIu89n=1X8&}0Z~$m0ZOpVX8CiI!4W`Sj+)F6GSw?X9czs!&M&-8h(ITbs z3Z@h2H7b_ViRW_U{7wAeGxntnuel=Pp_Y*RMqd2meEv-`u!f z|4`CcmXr}OVAI()xvNG693_(o00=|iTm>wJ9KznHd2El7n|)BG>_$Ll94LpI#?SIH zM_`=CzKqN`_>}>kTy+8zu}jaw8(5RE zTd<*5ocjEE@K7(O&FCg__`mQ+7>}|FfInt}^=RJSw|Q3!GI3<}LCT$bl|zc_Y6w=<>=bmKV4JFZ)Lml$Dyz3HAR^ZaAlD^t=T8gDedxrnHGEEfUA9{tIiL ztko%}$}tMQ@my(vD&3`Kn2P*UdK>YsNLD|kmgzQ{|T;B8*e+Rpg7g#YR{jh>r`v9aL1M{5^%C51CH3sqX0)SRTtVVj1L& z4Kiw0B~z-Dk0bepYPo1M0R1kRENY9!fBpQqp6xkD}Q&Pl=tVof!MNGIn}5&i)VVr(!u(&b?~^2yR}H=!M>>+OqJv)E0L7K?RMM zFdU94C7B1-WO?`&ph|*{l_zH&P9vk$Kj>ayEV5xklcpc6nA5@>quv&vLnq>C^xw)V ze1Q|0(Q!?%7IBr=)_X8T$4Bc6_<#TX9cRmnmsC!lIscY{wNtMDsJoTI~AS4@VN zVQ3U6b}1;UCRDXMwY^V+IY4j#VNLz`>B3&ly9J3AP`q&5v&wHOHga^1v6_h6dm~44 z7W1xsRiH3p6XE@>w?~ug+^VWWw_vNylB*4ey;yl-1w*NtPxVg+mbdF91mBz>?BDAE z$qEV9|I?j-fP#PM9|9^d`1dhwvUvd6w% zH(QH4lcxDDKRC(`?A$>}bck9gsWA_S(O&0euxY0|j z-&k(hP8!0v4HVkDn?ce^S98ct2x9bNNG8Fw>^BuWs-V;eEaelXardl)5yC zuMX-2kx&P*EDbbeCw0B9jezsFlv@Bv5Re(qVEcec>Yn;WZHKibdHaxNTsE`Q@*0jxb-s7-sWD#2;NaP zvv)fMZdEWDHn8O(jWqoWyp9JZ%*aJ-CzDACk+|69x|8`$~;y_^+m_-S&@OVO25%`guXpeDy>m8ON`L_$cBQ#PWerk_j9!~ znB9CoT6=ui5J@zs*u}|+jOv;YDW+WAN&i>RzfDxdbto>K{K z2`CJz;R^%+dMhH}rtns3m_wh+9&hPcCd(yK+c!zSd)p9};BBnNturP5E*%`-fS^%U zc%;J43h~WI_oV9-N;qtxkQE24ine{w?+(=T?!&clYFN-olYMJRlS|!m*PlLcUXx_= z-w9In=%C@xo7z}GK2n;yDcmLI`_G`yqi9#6qoU>7q5|1^>{jGpM1x>X{YJgymchA{ zZ_0ip(b<7^T>$c7*R3n*l0u`0(F$e@N08YZqwak!yM4@##AK_<3DYieuctZUqJGoK zBPy>k>`QN1s}*Fsl0jjYuiCSM@QKq_r!lY5eJYDSrc<@7bd4ChYV#_%LWn{4aq zRbnvvvz%?^$B92yXy!8tZNP&h21_c%;ugI5co&4%*)moW$jW+|^Y%iWEe~tsWlv}o zT9`}+!BNd{J??3$S(kc(rE{uvmDOZ*w0N((4%ddlW?7MLyKco<_~2itwJx= z=L>on0?bNwWVy;tX$f{Yhm=CB(k)7n5Iq#(sf|`-5$o=(oV(EW$VEMp)x=Ebgo)^j zXUTL$2+>|O$ILxopX4oaodZ9pS(L z9H3Lp*N7_9E2E;_U6Iwifj^Sg{lc$*{gcBE{Zt0eBf2k3zraJEmT)IKQw0hE=7X0a z14q$EqK?_(jL+H)ABG}#-kBb4A`E!i1e=JYyCY+@jflviGVd-#*_Q?r;ZV3#*iqR>1N3MFd zx}zmTO8!nCRTHRc8E@#azaD{?+WdQOQZ~fCiQRonVT_kLlO9Bp4(_`II=1Wg7RCy6 z^Wdz2xd*70G$&hlXu-s$yppHLJQ^&761moQ2ZndajTXQsKR+F(P?#|V&r!zx9SgP@ z>K7w!|1FhOeC+{Z(kav2DgS_dl82;JYwyIdo#@|an{d=AY#h|St?s&9xpK!{n#!}% z7-`}&FyIrJ=-Y=w85l&z*Iic(k690lAj)nOoEJz=8-^Mll7PO~nSfwdGCrSpK$$*+ zUz|FE=RWPISxUiL8aVPE6Htc_2qbIyO_3G#regEkx`gtC;DK3GFnfBi6{`25g&RGj zJ!KbCu7d=MMa~<5YdEeR6Y{65mgx$hsG57m>jkj*rCMdxGbrn^t#rPxl$GZ0LuHk* ziiQQ;E@=+1y?^T-GDr%p>LpkWjP_HHvnESVYfk=9!luW zXC8reCk^uy%#^~WJ!%7M>yBCue<$qxF;5eB?Ab06?4(LI-St#}x_VM;|J-kg6&z@p zqdFF^KJX`I za47Iwk*0LB-3m)U8r2OVJWhXg;|PIwUUb%}tdjM(48K`#&gy~79VTZ?zzdBP71(+| z3aJib#0y20_2w_8N(PctFu2Z6*{*D}aEExRbZuHBk)vP8dy`hjV+`<3;AF2)Me1Qm zt;JB)!)c(KR8xnka8=s|RqoYdr9O?wIkg7S-7{8hmFTKUu6J5edO5I7n_3(A9$JB; zG#6!!OAMCl@<1;N|BBg)g%h`D=M3XQb0tMl zqgvFqE>t^;+Pb}G@C^##5NPYN2)*|>Wf)P^TV?gwVM&#%vzh~^OdvbIBB}WAAnQGN zX#&MA1SFtFF~;fl8OSRR+U14EVjCbyNGo8d*EYTmfclBZC0;Em1zDr5uR;&@(48{I z3Vrt%lxA)vU4oiwOxR)9G}+y3_fp zPG?;91yWhWH%n}>#^x6vaN!TDPNzL&PW-qhzm&wb{lPlj!wVZeeXD(Rzv>&@ZcuLS z(Q(41ygTMNj&RGH+=-c;@u96_(??L!=XgJbr$espyZh*h+j-f<^Iq=neE&ec)|)gu z%U%1)zCHQpSsvgg@8e1TFpW~@V_{_g`UUdt#fJ18zpcXQD+jD)KbH$DT_-UgO81q$ zLHXp@Ohnmn9|+xZ91o+bp-$QH2_9gUmn-wPG1|;wH4uc)o%QO;r4f6^8ZEc_Y+Cw8 zu8r7r8!bmRWcug13%Qu=TWzrAW}l4McbN2`CljyCEWVQ*Bl7iSn&zI$4 zDxa%qE3Yr>qjK5elu3s=x&gnrow>{mdcX}NqLO#g1_(Rbm(gwOBfmzE{Yg$SRwpRFr{tSQ5;#Wfa)c4b4 zI#KH>uT>%YKkBOgw)2iXJ>O_mvFl5ORlj(<;PTOFsFB=s`hBt0(&%j9W5|3a%w0m4 z`X+x-Vi4HLaiR~;KI-)?<>Lk1+GX*r%(gl)tNH-lTfN3*ybWGf%O+z(LaDPBRWGAm zhOb8KozR6~DsNQ2jJN0CJbki}NE5pgQ1zV}mhpc5-HQ@k<4x>tLGfO1@-p7{zVy<; z)uh8~aRw8#`)7Oib*nY1efZTkAWxsffZJhas5gtZrv2X0vHtBn;tRat-n~A?dl=e= z4*YPW|MKzJA1AY?XEwQUS^}w}C>1ZCMONmM@b?5!VF@Z-lCKuEvD(G=frdXmkoX=e zws+64$E2O`32R4sAb8yNp;gf_jJ@xT0X-FFYm##)y@7nnMs518TVnXP zvhzuJx9xmJvMU5ph*mVmf6GpD#Pp37KLK`+gT9Ev>_CNJwERi6XJP=>hU`I6=F9s? zF(c8c*L3YJ+cqP&2@?NH4yZ|(orTUHaf)L8x=iLGJG%{J78JD8Pr`XZA(VDpF5%PB z%YeC#N7pRc=D0?7v=&^C;94}9kdKyvyefC7+T|2?@2%rCY=-INFTXgaGz3$gT%8VADd1nt>Yz zQ^!DTX0mSgpG>fxbl|nxTo-uRXl3BhM&i0rl+$Jm&VOno1F@x9T@CWbvoX*l1GTI` zq$OWawzzqAh{B@do|C#tKk=3+P%B1e--PM)nZ~$e;G?~5lV?8%GG4iK+vaHi=*RL+ z7Hww1L?TEtu3zM#Wz0^sr_TTWDb$!B;epViyH9c;E05LJ@MY@~pZj@G8|5+v*1x?v zK^%*PT9A(e;({pv$_+EXjji2L8c&1r-z7{k*aR zweQ(&Dxy(`Ca>dlKdJ1m^BseVNJuMb6|a#zJ|coTkS$IOpyQW2$^%D1Weq%gL!Qgx z>{2&sj2kFWLyn9=5JE9SdMVY3O}A>+V~DJohrQ%Al#0Fompzi@JlaSOc%&;?tAM&)AxW-_UdG^{)SNM zbBy|TKY+j93W)|jJai74g!e+-Y8uh6%!|)0au4!%sLTyK|Lp<%5xc3)d1aBBeSIUp zW{-xewtt7E693)@G4ZXs;d4Rn=a!EysH}yKs&tD2hfT8E?*_{d+PFjJh*dG1HaVZG z9OmP976JU>(fDC(BiBb#nRUjoMvbe+*c*cWn6k?Ax-sDZ*7u8wA2WZE5dFpK3cDbo zlz9A;ME<>}&sEE6_GfnN`>KVH@PEVZ!#4m~Ie}`!>X^MQO0Tc{E02gj3S+ezTMk>I z$vJ1um`$3&=d&^32L(v0(1;iu_~jNVY|U}nARjP10WRZ`UA)Ki zCU74ygyR|9Ybp3%Q+Xd3egfi>uhLrTn8`48GVDtC+CIh=>5m^%X4*qmi88=Rv(A1f zq;5>YMk1t(jEMqYQ=Nb;l{8}g#oQFA8(AbxfsMWOrRpsa%@R zl@a9?M-3%rRS_Lz4eLetS#YVVCKD=^UAyPL%Tw;g`V0rGgwG1TP5?#s4B|QGAuebNYyh z3<2O9yfZ}-Be1kg1oT`EvW7K}5)3aHQ6l?iCAPmrnrRJjw#IaX`KnX0D}FS9@wNl} z<4rR(63JqSI2q$wvI;cC)}WcO6=Ilg6lVBs{bKVE3t6AP1pKq!9*;V;mE0R8UEI&> z^qK6;iDe+nhvT;nl{3QC?i(*V>bZn#MMxHXr7oLGLEOFKfOVtWyq_%&=S% zRngzM3JTdivZ-%g^TgNtBfQBW%1f>}zFD)X?=&a65xx_V>boXm17gQ@`wr46BYQiXdnEtKXjoO zEN855bRc^amp_1&Pkc#OmWVLn7onbOPBGdFNt~(t*K;9){snu;roVZ+e+a)W*Tp}tT^Dm$2W)ktYm z677rk*OtGyfI7WggIY`&!hV(e1n`+@YKv-Oml|^l7Ic$_F_hud)b4$Ksyk3$QM<{^TdBo>5AGFRjzd?~zhWaM5>NqI^$&Y= zbY0I^{-FvumR;8drRuP66x^ZG*3oqns@7}PF!a7vu=&!|twPTCcxWi_+3EHLX~>&s z3;gEH__8?}y1DDy&pu}O)MN3?Yrmh@_<82|Zy7&{tdIpGx-P&% z8$cA8+d%gMvks;6w|lZJ-fk72-8^>LF}OmD7aV)iV`{Ow1yJDfa- zjE}cZ{b&viCuJY@ai`ota!P9>_BQ2@CC7t{?D@Ed={49eP#X<$FB&}tj_|_wx#qpR z*bVq!sH~7Atb3T@PPYCY)yXDZi8x9{_d@RmtWcre;Q zqGL`hLq^TwQ^{;Wzde~kCZ{h5Rkw*;dW#O9ps&=2ZdPd&deQJDi4_Zf`u<$Q21c2WIUHj?${6gFbACw|t=L$w5^ZB)e1Q+( zMG~0W8gZS$kmzbHogo`yHQIcWIyeI!%vqG0rR8$q{nNa8C&hf~*N@DFndj6*Vhhie z{s8Zi-G^VGQE4TH$R_6E-oEZsRRmgY${oHR_En4TUH+Uqbxg?Wei9 zae)8vhOg*hH1l$%Y4|PNK^?yJF6*;>vmb2UlyQO>VQ+7Y^O`C_5{EA0gPU{r$NP5p zaCzgXhihnibCO`vU#_u#S&v5D5=XZBlm5}8$#diLZNTCr=3 z7vBDiN7}8IwBOD%-#nMq!IBWZJDP%v?2IlV9xE0SEmFr*I4kpl%TPJ63oTTAQ&RRt z-gzQZBKdXcifVsl%b^f^dK*H1u##I$b9{9Z>+2^HAFg7}`ZPNk+sxOM(ylEIYmkcr zbDF^^{VZhrp(9XqO(VX$4q=c+nUNKoy$laQQqd=$&I(=|CqpnB7VjzLJI&!^q3w#) z`({7gcN%ExN>d-G^wjlIgcFh+lsN86dXV}$mLOCQD%mIx~hyK9vnq(Oz3*G(hSAb6Mr@1%Fy*AtWa$KF~wyco}wW%1>LipLkP17w%R zT10p%#|=?>x%QtJgb|zxo7ws?{9PtFmi2bD zJF+L%CMmiE{6*gL^*Wt?+EEl18nL79b9L~)f%3`gUVzA1s3)L@0{%N@H{6%yHeAQm zUJ005auL@ecUU5!8%sSE1uv5vPH5JP(n}*~oWHcwhYz3xrFE*%;m*O@%F+KPoFG=2C>ykxb=sE zfj`bV5NE0>K;4~`sRs5akipY)4LKI~>?FHOgA(-u&O~yA>YOrw`@#t@qNyqpMI0*r z;H!{r6!wS{UvZ+I6On(%SLTUsL1-1v2n%L=6c4_Ww8Q;SEycY~Vv{3Z`>m-MgB*u1 zN!Ujuoi3*iOVhE=h!SL?M9KuQJokZ*U(Be-_VOh*Hy{MWm2it3N`ergX8k87A1A$m zNdL!0ghI>T)ucBJ`dtN7abdK84^xu1a)JLI$YFuPSz=$TjB2%gF+lh(PJhD5Y8{8- zEw7;jqn*py$)YKQTkVlRCQ)474ga87f59d8Yb3}WlpC9dq==y*)dKX}!NRETQijx( zl@RYnQEc8QRZRrRG24YNl~?ek>~NQ?^|&9=Jc>bjlZ&NlQ7rEwNj=4Zs+)fnKtxjguQ^CL=U<`_b8dXSP6 z{l%TTcOFmt&4>WA{Pt3J{)kT=pM+4T@N<%c!8R6aIeiDM3t$;KrSvehAsN)kxO^Lv z*dhwuU_Yn97(Mtot(B=boGHRDd1o5f8%})K<(zMGh9#Qyaw;P#xd@yC2e*R-&*-7{ z*hx5tcSrHla+xKNQo(=E1ztMHpK?Dg}j_=SB*&a&C1VwF8zIeFm2HAzabMIY1H&K1MNVuqZq-u z6GJY|K#lzV|0InTA+M0Wr9xGScAu*VpT0(GU^i=9_v;qT?C;$Q#Sb|R6teU;4uI=O zI3s*P68{a9i?%u-J2oghlBS-4=Ywj$?+P&hSVC!SqTI2$DH!GP`xLEXRNpaEeeNpt;USWwY9fRIHInMUehHR$B2B2T&5t0 zj-ImvecV*4;b{WE;7>L1P(Rj+*NCa9wEGN);kY^V-$Tn}EZrkBMvgc4g{UOq``4vv zb+Ttqr95}pdHtZxWfPFil*B3A66=M8wi%OkT&juijIj9;r7a%;6U1vU1TrIi))KxW zW09PdwH;!@!pb;X=Sa?u;JmgvU!B-m;;*=#oDf|rnvi3ZdI%Qf=DyK_l`)o0$nxR% z6jZBJ-@5f2ztUIfGj8`j;$%S3vUk65vXF6N=I{93cX?Q#`1>)l&mU;Z3bSMZ{nkEy zrJaRQ8vVbCjf!(djqwBzG6PELLptE1wS@I`&2#^^4ID1>I4IQ2Jx`nZU0)~kH0-4Dw2;s=6a)JkJWdi){n=!2g~r9 zI`6kH-249zU;KLE?ESd>eCy5CzaNdQ7dX97ru6i_yv=ovPLKJJw{p7!=A-i`=UM-g z|7UU#X5O520bkx9Hbmw8NbSLkRNj2|X5j(yFi0&0uD-yDnQQL5);?MZe}yG~R=%Hr zrE(ZJwfSYK!j}J|`}Y4^#$bXrT(*-Hh~lSEpo)RJ*oJS<`%!8HT}g<_+OGJl!;Ueu zvRpPLO{g^kB}Q6*Kn^fO-B&;+?^>(Npy3D|U#8kmcx81rx~9{I13isN7JPy>1BCSR zdK}>?O55h%c1N$```6S~5y+5f1VwCRoeWgWNtb{2yN3?X3RhpsOmzL)vVz*j_C}-z z^M^=31uZq9-&+i(Xf-)$O|1iOpsX$)o&0XD9=mpfHX@jc&i+V?QM8^kr~N)VU+>FK z517JqtZpJ)U;a?0^5-{KKcM#zp*Gcc&TWM#a=_e6b9Ls~{W{lTVvz)ui%;pGmo=g< zq>4fbiAIv<&b}9MC+Bxr=EU)RDnN4WgY9kSxJVS&>N^$UXCS%o+g<6b+{5_N@6wEo zVxsu$cU8+ZXnuQlpWCo#Mnk1^lgYsd{MfVx8l-|VwIIf+d*2HwAU<>YvTTtK$CBfK z*89SGV#J?lE=brK<#Nck632zP9P3~tL37TS35Tew#caEQvZ!vhwW#o+q>XD*1aeA^ z$b#fUzt331^RCn`W9GQHHg{#K!qE~%jxj>V0t<#~dFRT~Te)L2idr!FZS#oVc;H?y zWvJoC-LNME5+rp9bXo-0su6pki3Fi61vAUkSrWTFznO^vn~q}bvT7P~XzCOd5S%4G z+GI5wdqA}8z?sR|0kPyHSCJ(+mxe3H5g`hc7V*uFZiytnboS-rXK>_{Z4O9+Q!!HTeID)Ma<9Htdu>3F6&=B zQjm6eqE>SXksHoJu*uvJ0Csz)X8+EA+45dn5?EXWNSW=GsWXgEdKwWa1hY0w#nX<} zaibd#Dyh1t@%@!rqN-0l(THwltHPGzG==fbZWanpVbE>srTJV)M~Y!L_c1%>%tiPN z9Qyo7#cE^+#e@(j0i-?-NeBED6BH3v>Jb3w@S~~Qyv+$aP8)_rz}2ykB@8AvE^oS* z0!hQbLunRG=gM8m9P7>T;{ZS0m)VpOuRTaE3+Na-&D0qwqMriFCj;G)_?-{P*Vm9{ zXOE4drGcEH0zk~cg3pzg)1314H##iMMI9CBgM^zaoozot(`I_>`Kp6&Y&1oJzO6&( z=toZ!>;x<+I@2utKSRBzcR_21kYvfBn8k6lPB9fcLR{xwL?E zngUp1{!NLDeLNpt4-4#lpxWfpYkdL-f-#E;f*8w3?MMJOrO&C#{C_tI<n5T$qyb|O>T=tC`!b0Wk%V;(gN>mN;<)G zo_)38JT@TUF7pN9Ng_~FCjsbE0JEsWqbAd@&1>+KB~|A*SB^ET!p`45dCR$GzKz`q z?&y9bT=t=Q6uK<{l^&a+-iC#W!Tp~{T>{oq{wq$D2H2Nk~qj^ujOX)$GPqM>iKmC7C(q+KXuX} zl3-_G24$BtEv0fHju*_SF|!aOqFJ`eq9|e|pyJ9x)En61Gn!4?0u`x)-{FLX90`c2AtN+(B&l2G!-Eo2HtbVZ&Xmi8T0}&cMw111h2RCO#=VWV*lsRjKA0dBfOqS#1RDGpNs;T{GtQMUaHm#Z2}G zQbK7~=9^6Zw$j6dWJGzgj&&V5BGxQtwA<3^=_T2)bGeZ8ae!-~d@6o?IOmvCM$#Y4 z5|D}2ZNNA_;(|^~j)XODPCQzaYOa?-T}=@wqHZyZT0C?mV2|-xd|Efo=8ClHAvZJA z06Pq;$L3vKQ8b#SDOhHHV-S~M@MV_(E*=Tkt|je@9+efhjSS0|OB%afY#Zu{^4g$C zI6P(7eR#BSM#M%`sv&dKWn!(2w1CksEA4z4ns_>WH;tBs6^sMG-HVmeruPg@zK=1$ zasKlDBG z`t(NVaB`ES#4~idh#n}e(WYe-uv1LnC6C{fMb!FxsKF2PN!QndhHS)B(bTyeyFu(} z7z|pkX`psf4;5RAY%cl8tE-VNVkPx3lEE|+1O95JrRY@j-T{Fp`=`msh}+`wIuGS_ z#=rD4Q8*EoetCrz*83O*VG)T7P-hcQ&%<^w^e{R}ZJjK%cAA@Z=4C9TZc`aIsvm^2 zHwhMcB=(oJaJe+yF`K4D@aA*+p`rX4{BDRuBacN|Dy5Xu)jxwmS|OE>0KuyM%Raj$ zM>paKmc`f7Od{>1YNcJi9imXp_j%HK{y>-mFOd&ubkvAoDs<@d`XNK|+PnEme z1I-Ze_s%({jMSQ^1J`pQKAG?e!}VU67>`kKXxUMDBEkJ{k^)ox4P<+T7^m7XOtal^ z-9d1395xIrrP5?uHB;!`O}H@FKKL@TVTZrdB>{@pq_T!8#TQ=kf_}C1FVQd1yGw#0 zqs{l=fS}xh`FCyFjskH_l69-zVs8l-{QB#Q-xwij;eHAR_~k-`Q79eL#n+Al8;2lX z8nN?iok`^|t=ZBLBDdwe)qEXXSUbqX8{h0|2pl%w+a6G;=06zC@fH) z+Ag5yG$!WWCsiMlrjPQmLl%k=rBqzuNn?D7UQxt|H^cv3WHe(6$Jf{-4DQZ-*GdEt z1x+^_;L@exi^p^DLpCp++7=bJ-i=x;qD>OH(QQBnVfDIPt)$fcWyn|}I`2c=Kwt#U zaV~Ae3#VnwMbaUz6rBhj2nN^@q)C4XKgH+G_V`0+j)kCu2*#zB!{SQwSx1)V#0p#I znG9g%I??tK1G3Rkd}d@=}_(ShZN+=NnJdr7HxWo{j9H<)J*YTGHcUOEu-uD(jQ zp*yB|rpK<2iE%MZFIn?Q4(N%K(J5RaqQt{t)g^jd=Lag(CjVK=%<4vkVwxZ+A8bC) zPq^qqs9TXqMdYN&jMOBzF0!0E<&2o`O7(90Rd)qgHXb(quouCS%Z3q}>~WOy7y+kcH7L<*#^8$qwYX^ z&*{9*g+a)6;uyKYlmKFVHYNrhYy0CW6)GzZM20|UIr%M>(lY+?X;#!5_Wq5v8HFJr z*{V!^>6X55;k4b7Db%YX+OsF4bFkk`DKE%pj7F_$FkFGcDV*^BQ^^*4@o^m9jivoy z&Eqc`8*mw!s4SrjCiF0i=eGGRHA;Mtu(Cj{{4-iBkNSnKahj_-p%7=^u~Z@7@0O-9 z%@0i_U*7^S)DdIE6s?Kk%X4-Lf+auUlU{zM0DtS5U-qu<>Dr<6s}uo1G;Au_iR zLz#JRzV9ze$j?1@W51+$?(z6Hiqys|#+cFJ*_(^ix}qT(9Niw#RKOc8NUYUL#9okM z&0D*ODvsCA6)yPaaB)4Zzp(TxQ7M!I?E3I!N!-gL%$i%e#O{OOONoEqF9!3wf$Ax= z4Ry9$!Hqc+9koXiS4gP5-HDL#l`IX>RF}U`VL}sdvef^i|C$D_`LE7PN**t?#Z_xU zb4_IE)j#dY*$D*4i=EG8M-S&~TJV>)=4z}Qp)IznkS%F_nWln_47I!5?UP4aaH}sv zE#RBw+qz;5b}TJTwo=N{N%?1A4tSHB-#y2UaAmWhPOE8N%`=KCHvs!xSYFWXVsn2m zRwCoQQQ9J>Ei~}oE=Avf3&^d@BC;71*RGMK_39bG{7rAHnave+8Nea|YF*G9!t$l> zkOQ!h*(ZlPX-BBAs`O}YoFj+%9U208g#2D-Uyb}(pw|R--GQ$sQyAxqz11xEGmh}B zP<^?`F;HT^R<@$OA-zx`88$9Vaw9E7HjmB|KeZwBVc4(n1IzG^-|KS9*kp5>%VkF7 zQe-8UtoP#d;nNDIPbVX=g#R0|x)n;>es#PYJW_Lla$o5OS#Z`1Sxos!2K#w(1{vxZ z0KXFzYQ~HZBM_+jOg)Mfm_Jk(mWF+*^wbCvglEP9# zgAV{Ng!8z^^tLd{>CRG51mqt?1c2z)k0w>D z04hxMsIi@0hlB6=V`<4jaSIBtqo$Dj*aGOIU1VQo!kchgj;)Nxl&PY`Iq6G?%osUp zlC^lnQ@+BnvV<68@Z(P>>hdgGU=Zjjzxv0uX@NYsZxogXAoD~l3lMYiqGQ-W{MrM^ z4QF7CYx{I)#5wm_do6evnf?1_h^Hxm!0p-3M~QX7o1NT}2Jgn_;~Pz>zwuspqmsga zbGTg3^Dh9!a0z}v2Mm4b#wXMEru1PY+&Rp4>b(phh=Fg1jIFH&h{OB@9xoGmt32a4 zD~puY;F#wQ_!Ho*|sQsm1Rtchfltcp)Ti{`kQ3fWL{Gv z#zZTIS;cePYn2UU^Y5!E)Wz081BtW|6n4;Aw-!!^U921}J{TV*z4FSbHLV1akS7=$+8c4_QdBZwW2 zzR3^Y$Y#;=bs*ccd956FREEnN9l1#WsavBlSY&U>asA|soW6<#Y`bz>cu zVT*o^gy7udJm*igW^ZF9t)7BWy5yrF5s+ggSx{bES+y=6rIhn%#$=1a2zn^%t_jns zjS;H0fhaPT7BT?i1XjW^yvV}xsEM(Om@dbgu@N4f$3lL{->Dda?}yPqpU=}v6H2j5 zJsz?AxJmQMPt92P&$N3l;#U~0} zhRUOs8-MX#jB;4P;xw%QD7-4DO<;crO?WF&+da~1?RLEEKWOm{=TAb+x1b?4y|Zlc zJLNUi21LrWyv#>=7nt~uwiZw%lWEW=02@H$zmY}i=l+h*51LkxqW~_0GjLhsmFT#- zn~SY&XgT=@Sv|z#bTO&?kF|1LHzkZ9%Sl7;u3Gru2M=fF2blBfs}GQ`&-|3f^f9~z z!s7+aC*#vr-QEEdyT|PCrA58xl&ZeIoPoF8&8k?+aFb=EJY!FMUDr*A@sm&fg7%K$ zu2CL~<`b{v{(MI2AcP}J4SmD*j`i~ZT90dH(ap1Yi2-??sYKv&+*OA4Pc>h*gemG3 zp}StK`-)3We0A%Ky#jy<#>I{s7*bJj=XbjEa$cxJz+t#$VVDS;XKSQ-YPz)tf=Tu= zK!+C7vHelvKPn8qz@mAi3P@jw6_}vZ_ez^tU{L1R(e<~b^a9e)9sNPOUVCDBWk>gW zQ*Ar5NA!+P-zyL^|F8%3&g|oze-~ZS-xGd7wT9uJ<_$Gkhpwpa*U<%JnV-O1BPMCd zPfq-W#~y#V;ZI3@S`d;vy}1vy?3i>x@sgN;wy86q!W0XXdQ)+lVc7&UOM=>{>v~s~ zf$BT~+Bg`al6I`}MI=&`wwZ6s^&X$>6%L`!%U*crDIt~*bGzp++=O=3pUL`>V`Q;( zR51I9818u=f1?rdyid2D_&Ih#$Ma<|@|_#k691-3LJZ)_yu@p~#2U}LJdrvqkzmB} zJ>lwejzXc($?d>@id(kMiVzc&3*wP_i~4k>rFmnqU48cw#KC^kD#Sc0yo;T(kkV6+ z7t-N3n=86@(WegtF>CWEr|WG^;H<8Q)XK1@e-Sf<3*B~9yQ1swf(!<2S184 z^&F|gDKWUDtIR4g=vhytd>#-T+2EPy+Ew5oB0WnFue}=I%Q_vIf8n3%yR9SYLC{%m zcU4#%$&Ldr`B?G${e%}~Hr4Pt*(_P7Y?ihTVx0qWIa^0j+F13`>)$82@48@c))vuR zu3S6SeZ{yth293=b=J1w29O?qPya~?zJo0ZdO4*U-^u*MRd!9WRtAGL^CFH*#*1M)ANzXMnSs(VE-X}IIiD$CtLDO*}4hZuDm37a(A%fr

(ZIuz~!SA{gv)~sUOuz^R9 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�A8iV30OXM?x|k&y+jVM3CIkDccdhXhkq1YwfiZ7G%Q3q>N?qdqwOTA^0>h zQ-^p>1CZ&VL1590_yoalqb-%u?C7NvyJ_hrst7? `${result}${value}${values[index] ?? ""}`, "") + .trim(); +} + +function escapeXml(value: string) { + return value + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function decodeText(buffer: ArrayBuffer) { + return new TextDecoder("utf-8").decode(buffer); +} + +function zip(entries: Array<[string, string | Uint8Array]>) { + const localParts: Uint8Array[] = []; + const centralParts: Uint8Array[] = []; + let localOffset = 0; + + for (const [name, content] of entries) { + const nameBytes = utf8(name); + const data = typeof content === "string" ? utf8(content) : content; + const crc = crc32(data); + + const localHeader = new Uint8Array(30 + nameBytes.length); + writeU32(localHeader, 0, 0x04034b50); + writeU16(localHeader, 4, 20); + writeU16(localHeader, 6, 0); + writeU16(localHeader, 8, 0); + writeU16(localHeader, 10, 0); + writeU16(localHeader, 12, 0); + writeU32(localHeader, 14, crc); + writeU32(localHeader, 18, data.length); + writeU32(localHeader, 22, data.length); + writeU16(localHeader, 26, nameBytes.length); + writeU16(localHeader, 28, 0); + localHeader.set(nameBytes, 30); + localParts.push(localHeader, data); + + const centralHeader = new Uint8Array(46 + nameBytes.length); + writeU32(centralHeader, 0, 0x02014b50); + writeU16(centralHeader, 4, 20); + writeU16(centralHeader, 6, 20); + writeU16(centralHeader, 8, 0); + writeU16(centralHeader, 10, 0); + writeU16(centralHeader, 12, 0); + writeU16(centralHeader, 14, 0); + writeU32(centralHeader, 16, crc); + writeU32(centralHeader, 20, data.length); + writeU32(centralHeader, 24, data.length); + writeU16(centralHeader, 28, nameBytes.length); + writeU16(centralHeader, 30, 0); + writeU16(centralHeader, 32, 0); + writeU16(centralHeader, 34, 0); + writeU16(centralHeader, 36, 0); + writeU32(centralHeader, 38, 0); + writeU32(centralHeader, 42, localOffset); + centralHeader.set(nameBytes, 46); + centralParts.push(centralHeader); + + localOffset += localHeader.length + data.length; + } + + const centralDirectory = concatBytes(centralParts); + const end = new Uint8Array(22); + writeU32(end, 0, 0x06054b50); + writeU16(end, 8, entries.length); + writeU16(end, 10, entries.length); + writeU32(end, 12, centralDirectory.length); + writeU32(end, 16, localOffset); + + return concatBytes([...localParts, centralDirectory, end]).buffer; +} + +const coreProps = xml` + + + Plain text fallback + +`; + +const appProps = xml` + + + OnlyOffice Web Comp + +`; + +export function createDocxFromText(buffer: ArrayBuffer) { + const paragraphs = decodeText(buffer) + .split(/\r\n|\r|\n/) + .map((line) => `${escapeXml(line)}`) + .join(""); + + return zip([ + [ + "[Content_Types].xml", + xml` + + + + + + + + + `, + ], + [ + "_rels/.rels", + xml` + + + + + + + `, + ], + ["docProps/core.xml", coreProps], + ["docProps/app.xml", appProps], + [ + "word/document.xml", + xml` + + + + ${paragraphs || ''} + + + + + + + `, + ], + [ + "word/_rels/document.xml.rels", + xml` + + + `, + ], + ]); +} + +export function createXlsxFromText(buffer: ArrayBuffer) { + const text = escapeXml(decodeText(buffer)); + + return zip([ + [ + "[Content_Types].xml", + xml` + + + + + + + + + + + `, + ], + [ + "_rels/.rels", + xml` + + + + + + + `, + ], + ["docProps/core.xml", coreProps], + ["docProps/app.xml", appProps], + [ + "xl/workbook.xml", + xml` + + + + + `, + ], + [ + "xl/_rels/workbook.xml.rels", + xml` + + + + + + `, + ], + [ + "xl/styles.xml", + xml` + + + + + + + + + `, + ], + [ + "xl/worksheets/sheet1.xml", + xml` + + + + ${text} + + + `, + ], + ]); +} diff --git a/src/components/onlyoffice-web-comp/internal/editor/server.ts b/src/components/onlyoffice-web-comp/internal/editor/server.ts index 8a2a57c0..963b2afe 100644 --- a/src/components/onlyoffice-web-comp/internal/editor/server.ts +++ b/src/components/onlyoffice-web-comp/internal/editor/server.ts @@ -10,6 +10,7 @@ import { } from "./types"; import { emptyDocx, emptyPdf, emptyPptx, emptyXlsx } from "./empty"; import { convertCsvBufferToXlsxBuffer } from "./csv-to-xlsx"; +import { createDocxFromText, createXlsxFromText } from "./plain-text-office"; import { getDocumentType, getFileExt, @@ -91,6 +92,31 @@ function isOfficeZipFileType(fileType: string) { ); } +function isZipBytes(data: Uint8Array) { + return ( + data.length >= 4 && + data[0] === 0x50 && + data[1] === 0x4b && + ((data[2] === 0x03 && data[3] === 0x04) || + (data[2] === 0x05 && data[3] === 0x06) || + (data[2] === 0x07 && data[3] === 0x08)) + ); +} + +function createPlainTextOfficeFallback( + buffer: ArrayBuffer, + fileType: string, +) { + switch (getDocumentType(fileType)) { + case "word": + return { buffer: createDocxFromText(buffer), fileType: "docx" }; + case "cell": + return { buffer: createXlsxFromText(buffer), fileType: "xlsx" }; + default: + return null; + } +} + const PDF_MAX_OUTPUT_BYTES = 50 * 1024 * 1024; const PDF_EOF_MARKER = new TextEncoder().encode("%%EOF"); @@ -914,23 +940,33 @@ export class EditorServer { buffer = await buffer(); } + const bytes = new Uint8Array(buffer); + const fallback = + isOfficeZipFileType(fileType) && !isZipBytes(bytes) + ? createPlainTextOfficeFallback(buffer, fileType) + : null; + if (fallback) { + buffer = fallback.buffer; + } + const sourceFileType = fallback?.fileType ?? fileType; + let output: Uint8Array | null = null; let media: { [key: string]: Uint8Array } = {}; let themes: { [key: string]: Uint8Array } = {}; - if (fileType == "pdf") { + if (sourceFileType == "pdf") { output = new Uint8Array(buffer); - } else if (fileType === "csv") { + } else if (sourceFileType === "csv") { ({ output, media } = await this.loadCsvDocument(buffer)); } else { ({ output, media, themes } = await this.convertBufferToEditorBin( buffer, - fileType, + sourceFileType, )); } if (!output) { - throw new Error(`Failed to convert ${fileType} file`); + throw new Error(`Failed to convert ${sourceFileType} file`); } if (this.urlsMap.size > 0) { diff --git a/tests/e2e/files/manifest.json b/tests/e2e/files/manifest.json index 8f464745..dd119208 100644 --- a/tests/e2e/files/manifest.json +++ b/tests/e2e/files/manifest.json @@ -19,5 +19,19 @@ "fileType": "DOCX", "source": "extension/content mismatch rejection", "size": 6524 + }, + { + "name": "plain-text-as-docx.docx", + "kind": "positive", + "fileType": "DOCX", + "source": "plain text content with DOCX extension fallback", + "size": 14 + }, + { + "name": "plain-text-as-xlsx.xlsx", + "kind": "positive", + "fileType": "XLSX", + "source": "plain text content with XLSX extension fallback", + "size": 15 } ] \ No newline at end of file diff --git a/tests/e2e/files/plain-text-as-docx.docx b/tests/e2e/files/plain-text-as-docx.docx new file mode 100644 index 00000000..70224372 --- /dev/null +++ b/tests/e2e/files/plain-text-as-docx.docx @@ -0,0 +1,2 @@ +dsadads +dasdas \ No newline at end of file diff --git a/tests/e2e/files/plain-text-as-xlsx.xlsx b/tests/e2e/files/plain-text-as-xlsx.xlsx new file mode 100644 index 00000000..6beb67e7 --- /dev/null +++ b/tests/e2e/files/plain-text-as-xlsx.xlsx @@ -0,0 +1 @@ +dsadads.dasdas diff --git a/tests/e2e/scripts/generate-office-files.mjs b/tests/e2e/scripts/generate-office-files.mjs index b3222931..07695450 100644 --- a/tests/e2e/scripts/generate-office-files.mjs +++ b/tests/e2e/scripts/generate-office-files.mjs @@ -312,6 +312,20 @@ const fixtures = [ fileType: "DOCX", source: "extension/content mismatch rejection", }, + { + name: "plain-text-as-docx.docx", + data: utf8("dsadads\ndasdas"), + kind: "positive", + fileType: "DOCX", + source: "plain text content with DOCX extension fallback", + }, + { + name: "plain-text-as-xlsx.xlsx", + data: utf8("dsadads.dasdas\n"), + kind: "positive", + fileType: "XLSX", + source: "plain text content with XLSX extension fallback", + }, ]; fs.rmSync(outputDir, { recursive: true, force: true }); diff --git a/tests/e2e/specs/onlyoffice-factory.contract.ts b/tests/e2e/specs/onlyoffice-factory.contract.ts index 27d9d273..422e4db4 100644 --- a/tests/e2e/specs/onlyoffice-factory.contract.ts +++ b/tests/e2e/specs/onlyoffice-factory.contract.ts @@ -23,6 +23,7 @@ export const ONLYOFFICE_FACTORY_EXPECTED_STEPS = [ "generated negative fixtures", "manager create", "manager createWithFile", + "text fallback files", "manager fromEditor", "manager factory destroyAll", ] as const; diff --git a/tests/e2e/specs/onlyoffice-factory.page.tsx b/tests/e2e/specs/onlyoffice-factory.page.tsx index 906c345c..b0834813 100644 --- a/tests/e2e/specs/onlyoffice-factory.page.tsx +++ b/tests/e2e/specs/onlyoffice-factory.page.tsx @@ -29,6 +29,7 @@ export const CONTAINER_IDS = { factory: "e2e-factory-editor", create: "e2e-create-editor", file: "e2e-file-editor", + textFallback: "e2e-text-fallback-editor", fromEditor: "e2e-from-editor", fixture: "e2e-fixture-editor", } as const; @@ -349,6 +350,52 @@ export async function runScenario(mode: ResourceMode, cdnOrigin: string) { editorManagerFactory.destroy(CONTAINER_IDS.file); }); + await runStep("text fallback files", async () => { + const textDocx = await fetchPublicFile( + "/e2e/fixtures/plain-text-as-docx.docx", + "plain-text-as-docx.docx", + ); + const docxManager = await withDocumentReady(() => + OnlyOfficeManager.createWithFile( + { + containerId: CONTAINER_IDS.textFallback, + fileType: FILE_TYPE.DOCX, + defaultFileName: textDocx.name, + readOnly: false, + theme: DEFAULT_OFFICE_THEME, + }, + textDocx, + ), + ); + + assert(docxManager.isReady(), "Text DOCX fallback was not ready"); + await assertExport(docxManager, FILE_TYPE.DOCX); + docxManager.destroy(); + editorManagerFactory.destroy(CONTAINER_IDS.textFallback); + + const textXlsx = await fetchPublicFile( + "/e2e/fixtures/plain-text-as-xlsx.xlsx", + "plain-text-as-xlsx.xlsx", + ); + const xlsxManager = await withDocumentReady(() => + OnlyOfficeManager.createWithFile( + { + containerId: CONTAINER_IDS.textFallback, + fileType: FILE_TYPE.XLSX, + defaultFileName: textXlsx.name, + readOnly: false, + theme: DEFAULT_OFFICE_THEME, + }, + textXlsx, + ), + ); + + assert(xlsxManager.isReady(), "Text XLSX fallback was not ready"); + await assertExport(xlsxManager, FILE_TYPE.XLSX); + xlsxManager.destroy(); + editorManagerFactory.destroy(CONTAINER_IDS.textFallback); + }); + await runStep("manager fromEditor", async () => { const editor = editorManagerFactory.get(CONTAINER_IDS.fromEditor); const manager = OnlyOfficeManager.fromEditor(editor, { @@ -477,6 +524,7 @@ export function OnlyOfficeFactoryE2EPage() { + From 7cc49456309512779e9a72544879c8b0ee777726 Mon Sep 17 00:00:00 2001 From: electroluxcode <3451613934@qq.com> Date: Sun, 5 Jul 2026 01:06:20 +0800 Subject: [PATCH 2/2] perf: e2e display --- .../e2e/specs/onlyoffice-factory.contract.ts | 2 +- tests/e2e/specs/onlyoffice-factory.page.tsx | 31 ++- tests/e2e/specs/onlyoffice-factory.spec.ts | 220 ++++++++++++++---- 3 files changed, 201 insertions(+), 52 deletions(-) diff --git a/tests/e2e/specs/onlyoffice-factory.contract.ts b/tests/e2e/specs/onlyoffice-factory.contract.ts index 422e4db4..c9758c3b 100644 --- a/tests/e2e/specs/onlyoffice-factory.contract.ts +++ b/tests/e2e/specs/onlyoffice-factory.contract.ts @@ -2,7 +2,7 @@ export type ResourceMode = "local" | "cdn"; export type StepResult = { name: string; - status: "passed" | "failed"; + status: "running" | "passed" | "failed"; detail?: string; }; diff --git a/tests/e2e/specs/onlyoffice-factory.page.tsx b/tests/e2e/specs/onlyoffice-factory.page.tsx index b0834813..a3da2d46 100644 --- a/tests/e2e/specs/onlyoffice-factory.page.tsx +++ b/tests/e2e/specs/onlyoffice-factory.page.tsx @@ -154,16 +154,30 @@ export function resetAll() { converter.terminate(); } -export async function runScenario(mode: ResourceMode, cdnOrigin: string) { +export async function runScenario( + mode: ResourceMode, + cdnOrigin: string, + onStepsChange?: (steps: StepResult[]) => void, +) { const steps: StepResult[] = []; const runStep = async (name: string, action: () => Promise) => { + const stepIndex = + steps.push({ name, status: "running", detail: "running" }) - 1; + onStepsChange?.([...steps]); + try { const detail = await action(); - steps.push({ name, status: "passed", detail: detail || undefined }); + steps[stepIndex] = { + name, + status: "passed", + detail: detail || undefined, + }; + onStepsChange?.([...steps]); } catch (error) { const detail = error instanceof Error ? error.message : String(error); - steps.push({ name, status: "failed", detail }); + steps[stepIndex] = { name, status: "failed", detail }; + onStepsChange?.([...steps]); throw new Error(`${name}: ${detail}`); } }; @@ -474,7 +488,15 @@ export function OnlyOfficeFactoryE2EPage() { setResult({ mode: params.mode, status: "running", steps: [] }); // 用例入口 - runScenario(params.mode, params.cdnOrigin) + let latestSteps: StepResult[] = []; + const updateSteps = (steps: StepResult[]) => { + latestSteps = steps; + if (!disposed) { + setResult((current) => ({ ...current, steps })); + } + }; + + runScenario(params.mode, params.cdnOrigin, updateSteps) .then((steps) => { if (!disposed) { setResult({ mode: params.mode, status: "passed", steps }); @@ -485,6 +507,7 @@ export function OnlyOfficeFactoryE2EPage() { setResult((current) => ({ ...current, status: "failed", + steps: latestSteps, error: error instanceof Error ? error.message : String(error), })); } diff --git a/tests/e2e/specs/onlyoffice-factory.spec.ts b/tests/e2e/specs/onlyoffice-factory.spec.ts index 492148e0..534404cb 100644 --- a/tests/e2e/specs/onlyoffice-factory.spec.ts +++ b/tests/e2e/specs/onlyoffice-factory.spec.ts @@ -1,7 +1,15 @@ -import { expect, test } from "playwright/test"; +import { + expect, + test, + type Browser, + type Page, + type TestInfo, +} from "playwright/test"; import { ONLYOFFICE_FACTORY_EXPECTED_STEPS, + type ResourceMode, type ScenarioResult, + type StepResult, } from "./onlyoffice-factory.contract"; const cdnOrigin = @@ -10,30 +18,85 @@ const cdnOrigin = process.env.PLAYWRIGHT_CDN_PORT ?? 3010 }`; -// factory API 在本地资源和独立 CDN 资源下都必须表现一致。 -for (const mode of ["local", "cdn"] as const) { - test(`OnlyOffice factory APIs work with ${mode} resources`, async ({ - page, - }, testInfo) => { - const consoleLines: string[] = []; - - // 按行附加浏览器日志,方便 CI 中定位 x2t/iframe 错误; - // 用例通过时又不会把 reporter 输出刷得太吵。 - page.on("console", (message) => { - const text = `[${message.type()}] ${message.text()}`; - consoleLines.push(text); - testInfo.attach(`console-${consoleLines.length}`, { - body: text, - contentType: "text/plain", - }); - }); +const scenarioTimeoutMs = 110_000; +const testTimeoutMs = scenarioTimeoutMs + 30_000; + +type ScenarioRun = { + result: ScenarioResult; + consoleLines: string[]; + waitError?: string; +}; + +function stepFailureMessage(mode: ResourceMode, name: string, step?: StepResult) { + if (!step) { + return `[${mode}] missing scenario step: ${name}`; + } + + return `[${mode}] ${name} ${step.status}${ + step.detail ? `\n${step.detail}` : "" + }`; +} + +function assertStepPassed( + mode: ResourceMode, + name: string, + step?: StepResult, +): asserts step is StepResult { + if (!step || step.status !== "passed") { + throw new Error(stepFailureMessage(mode, name, step)); + } +} - page.on("pageerror", (error) => { - consoleLines.push(`[pageerror] ${error.message}`); +function firstBlockingStep(result: ScenarioResult) { + return result.steps.find((step) => step.status !== "passed"); +} + +async function readScenarioResult(page: Page) { + const text = await page + .getByTestId("scenario-result") + .innerText({ timeout: 5_000 }) + .catch(() => null); + if (!text) { + return null; + } + + try { + return JSON.parse(text) as ScenarioResult; + } catch { + return null; + } +} + +async function attachScenarioRun(testInfo: TestInfo, run: ScenarioRun) { + await testInfo.attach("scenario-result", { + body: JSON.stringify(run.result, null, 2), + contentType: "application/json", + }); + + if (run.consoleLines.length > 0) { + await testInfo.attach("browser-console", { + body: run.consoleLines.join("\n"), + contentType: "text/plain", }); + } +} + +async function runScenarioPage( + browser: Browser, + mode: ResourceMode, +): Promise { + const page = await browser.newPage(); + const consoleLines: string[] = []; + let waitError: string | undefined; + + page.on("console", (message) => { + consoleLines.push(`[${message.type()}] ${message.text()}`); + }); + page.on("pageerror", (error) => { + consoleLines.push(`[pageerror] ${error.message}`); + }); - // Next 路由只保留薄 wrapper;OnlyOffice SDK、worker、iframe 都必须在真实 - // 浏览器上下文中运行,所以生命周期和 API 断言放在页面侧 scenario 中。 + try { const url = new URL("/e2e/onlyoffice-factory", "http://e2e.local"); url.searchParams.set("mode", mode); if (mode === "cdn") { @@ -43,33 +106,96 @@ for (const mode of ["local", "cdn"] as const) { await page.goto(`${url.pathname}${url.search}`, { waitUntil: "domcontentloaded", }); - await expect(page.getByTestId("scenario-status")).toBeVisible(); - // 等页面内 scenario 结束,而不是在 Playwright 里重复编排每个异步步骤; - // 下方 JSON 结果是 browser scenario 和 spec 之间的稳定契约。 - await page.waitForFunction( - () => { - const status = document.querySelector( - '[data-testid="scenario-status"]', - )?.textContent; - return status === "passed" || status === "failed"; + await page + .waitForFunction( + () => { + const status = document.querySelector( + '[data-testid="scenario-status"]', + )?.textContent; + return status === "passed" || status === "failed"; + }, + undefined, + { timeout: scenarioTimeoutMs }, + ) + .catch((error) => { + waitError = error instanceof Error ? error.message : String(error); + }); + + const result = await readScenarioResult(page); + return { + result: result ?? { + mode, + status: "failed", + steps: [], + error: waitError ?? "Scenario result was not rendered", }, - undefined, - { timeout: 60_000 }, - ); - - const result = JSON.parse( - await page.getByTestId("scenario-result").innerText(), - ) as ScenarioResult; - - expect(result.mode).toBe(mode); - expect(result.status, JSON.stringify(result, null, 2)).toBe("passed"); - // 显式校验步骤列表,避免已知边界场景被静默跳过; - // 例如钉钉非法 bookmark 的 x2t 导入回归。 - expect(result.steps.map((step) => step.name)).toEqual( - ONLYOFFICE_FACTORY_EXPECTED_STEPS, - ); - expect(result.steps.every((step) => step.status === "passed")).toBe(true); + consoleLines, + waitError, + }; + } finally { + await page.close().catch(() => {}); + } +} + +for (const mode of ["local", "cdn"] as const) { + test.describe(`OnlyOffice factory APIs / ${mode}`, () => { + test.describe.configure({ mode: "serial" }); + + let run: ScenarioRun; + + test.beforeAll(async ({ browser }, testInfo) => { + testInfo.setTimeout(testTimeoutMs); + run = await runScenarioPage(browser, mode); + }); + + test(`${mode} / scenario boot`, async ({}, testInfo) => { + await attachScenarioRun(testInfo, run); + expect(run.result.mode).toBe(mode); + expect(run.result.status).not.toBe("idle"); + expect(run.waitError, run.waitError).toBeUndefined(); + }); + + for (const name of ONLYOFFICE_FACTORY_EXPECTED_STEPS) { + test(`${mode} / ${name}`, async ({}, testInfo) => { + const step = run.result.steps.find((item) => item.name === name); + const blockingStep = firstBlockingStep(run.result); + if (!step && blockingStep) { + test.skip( + true, + `[${mode}] blocked after ${blockingStep.name}: ${ + blockingStep.detail ?? blockingStep.status + }`, + ); + } + + if (!step || step.status !== "passed") { + await attachScenarioRun(testInfo, run); + } + + assertStepPassed(mode, name, step); + }); + } + + test(`${mode} / scenario contract`, async ({}, testInfo) => { + const blockingStep = firstBlockingStep(run.result); + if (blockingStep) { + test.skip( + true, + `[${mode}] blocked after ${blockingStep.name}: ${ + blockingStep.detail ?? blockingStep.status + }`, + ); + } + + await attachScenarioRun(testInfo, run); + expect(run.result.steps.map((step) => step.name)).toEqual( + ONLYOFFICE_FACTORY_EXPECTED_STEPS, + ); + expect(run.result.status, JSON.stringify(run.result, null, 2)).toBe( + "passed", + ); + }); }); }