From 727c265811d24d074ffd96b7da373386b1cea88d Mon Sep 17 00:00:00 2001 From: Kara Alexandra Date: Thu, 15 Jan 2026 03:37:02 -0600 Subject: [PATCH] Fix/update (de)compress utils --- bin/linux/compress | Bin 16544 -> 20728 bytes bin/linux/decompress | Bin 16312 -> 16392 bytes bin/src/compress.c | 38 +++++++++++++++++++++++-------------- bin/src/decompress.c | 34 ++++++++++++++++++++------------- bin/windows/compress.exe | Bin 6656 -> 6656 bytes bin/windows/decompress.exe | Bin 5120 -> 5120 bytes 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/bin/linux/compress b/bin/linux/compress index fb8342d01c021c3f9200272ded319efbddfaefdf..cef95d0702de688e8e512218e79849516a735f29 100644 GIT binary patch delta 4097 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 delta 3797 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 diff --git a/bin/src/compress.c b/bin/src/compress.c index 2bb46e9..4b9bcdb 100644 --- a/bin/src/compress.c +++ b/bin/src/compress.c @@ -1,5 +1,6 @@ #include #include +#include #include const int MAXLENGTH = 0x300; @@ -7,11 +8,11 @@ const int MAXLENGTH = 0x300; struct section { int mode; int length; - char data[2]; + unsigned char data[2]; int datalength; }; -int find_duplicate(off_t loc, off_t size, char buf[], struct section *out) { +int find_duplicate(off_t loc, off_t size, unsigned char buf[], struct section *out) { int i, j; struct section result; result.mode = 4; @@ -39,7 +40,7 @@ int find_duplicate(off_t loc, off_t size, char buf[], struct section *out) { return 0; } -int find_repeat_byte(off_t loc, off_t size, char buf[], struct section *out) { +int find_repeat_byte(off_t loc, off_t size, unsigned char buf[], struct section *out) { int i; for (i = 0; i < MAXLENGTH && loc + i < size; i++) { if (buf[loc + i] != buf[loc]) { @@ -58,7 +59,7 @@ int find_repeat_byte(off_t loc, off_t size, char buf[], struct section *out) { return -1; } -int find_repeat_word(off_t loc, off_t size, char buf[], struct section *out) { +int find_repeat_word(off_t loc, off_t size, unsigned char buf[], struct section *out) { int i; for (i = 0; i < MAXLENGTH && loc + i + 1 < size; i += 1) { if (buf[loc + i] != buf[loc + (i & 1)]) { @@ -78,7 +79,7 @@ int find_repeat_word(off_t loc, off_t size, char buf[], struct section *out) { return -1; } -int find_incrementing_byte(off_t loc, off_t size, char buf[], struct section *out) { +int find_incrementing_byte(off_t loc, off_t size, unsigned char buf[], struct section *out) { int i; for (i = 0; i < MAXLENGTH && loc + i < size; i++) { if (buf[loc] + i < i) { @@ -100,7 +101,7 @@ int find_incrementing_byte(off_t loc, off_t size, char buf[], struct section *ou return -1; } -int get_section(off_t loc, off_t size, char buf[], struct section *out) { +int get_section(off_t loc, off_t size, unsigned char buf[], struct section *out) { struct section best, current; best.length = 0; if (!find_repeat_byte(loc, size, buf, ¤t)) { @@ -132,7 +133,7 @@ int get_section(off_t loc, off_t size, char buf[], struct section *out) { } } -int write_section(struct section section, char data[], char buf[], int loc) { +int write_section(struct section section, unsigned char data[], unsigned char buf[], int loc) { int nloc = loc; int len = section.length - 1; if (len > 0x1F) { @@ -149,10 +150,15 @@ int write_section(struct section section, char data[], char buf[], int loc) { int main(int argc, char *argv[]) { if (argc < 3) { - printf("Usage: %s infile outfile\n", argv[0]); + printf("Usage: %s infile outfile [start [length]]\n", argv[0]); return 1; } + off_t seek = 0; + if (argc > 3) { + seek = strtol(argv[3], NULL, 0); + } + FILE *inptr; if ((inptr = fopen(argv[1], "rb")) == NULL) { printf("%s does not exist.\n", argv[1]); @@ -170,9 +176,14 @@ int main(int argc, char *argv[]) { printf("Error stating file: %s\n", argv[1]); return 1; } - off_t size = buf.st_size; + off_t size = buf.st_size - seek; - char inbuf[size]; + if (argc > 4) { + size = strtol(argv[4], NULL, 0); + } + unsigned char inbuf[size]; + + fseek(inptr, seek, SEEK_SET); if (fread(inbuf, 1, size, inptr) < size) { printf("Error reading file: %s\n", argv[1]); @@ -181,9 +192,8 @@ int main(int argc, char *argv[]) { fclose(inptr); - - char outbuf[size * 2]; - char m0data[MAXLENGTH]; + unsigned char outbuf[size * 2]; + unsigned char m0data[MAXLENGTH]; int oloc = 0; struct section m0; @@ -233,7 +243,7 @@ int main(int argc, char *argv[]) { } fclose(outptr); - printf("Input file: %X bytes. Compressed: %X bytes.\n", size, oloc); + printf("Input file: %lX bytes. Compressed: %X bytes.\n", size, oloc); return 0; } diff --git a/bin/src/decompress.c b/bin/src/decompress.c index 15dcbdd..1be2274 100644 --- a/bin/src/decompress.c +++ b/bin/src/decompress.c @@ -1,21 +1,20 @@ #include #include +#include #include struct section { int mode; int length; - char data[2]; + unsigned char data[2]; int datalength; }; -int read_section(char buf[], int loc, struct section *out) { +int read_section(unsigned char buf[], int loc, struct section *out) { int nloc = loc; - char header = buf[nloc++]; + unsigned char header = buf[nloc++]; - printf("%x: ", header & 0xff); - - if (header == -1) { + if (header == 0xFF) { return -1; } @@ -31,8 +30,6 @@ int read_section(char buf[], int loc, struct section *out) { result.length = (header & 0x1F) + 1; } - printf("%d: %x\n", result.mode, result.length); - switch (result.mode) { case 0: result.datalength = 0; @@ -61,10 +58,15 @@ int read_section(char buf[], int loc, struct section *out) { int main(int argc, char *argv[]) { if (argc < 3) { - printf("Usage: %s infile outfile\n", argv[0]); + printf("Usage: %s infile outfile [start [length]]\n", argv[0]); return 1; } + off_t seek = 0; + if (argc > 3) { + seek = strtol(argv[3], NULL, 0); + } + FILE *inptr; if ((inptr = fopen(argv[1], "rb")) == NULL) { printf("%s does not exist.\n", argv[1]); @@ -82,9 +84,15 @@ int main(int argc, char *argv[]) { printf("Error stating file: %s\n", argv[1]); return 1; } - off_t size = buf.st_size; - char inbuf[size]; + off_t size = buf.st_size - seek; + + if (argc > 4) { + size = strtol(argv[4], NULL, 0); + } + + fseek(inptr, seek, SEEK_SET); + unsigned char inbuf[size]; if (fread(inbuf, 1, size, inptr) < size) { printf("Error reading file: %s\n", argv[1]); @@ -93,7 +101,7 @@ int main(int argc, char *argv[]) { fclose(inptr); - char outbuf[size * 256]; + unsigned char outbuf[size * 256]; int oloc = 0; struct section section; @@ -141,7 +149,7 @@ int main(int argc, char *argv[]) { } fclose(outptr); - printf("Input file: %X bytes. Decompressed: %X bytes.\n", size, oloc); + printf("Input file: %lX bytes. Decompressed: %X bytes.\n", size, oloc); return 0; } diff --git a/bin/windows/compress.exe b/bin/windows/compress.exe index bd9d2fbf015cdc43ec5b48a86f974377cc5296ba..3366dc6e2d65e353ae4b94c362fa1ef0455adfb3 100644 GIT binary patch literal 6656 zcmeHLe{36f6+b8OaMQYW#|r)f=oO`qYFf4qgh_y_j& z7XsSI^_0`;LW}lCg|t!FCJKMBNkk!?1a+DsIa!OciAfXMPzJ4JlSl*+z#RtjdEf8% zeCH%hLnFi_IO*=a_r3RhzrOGL-uEti@SM~rNm3K;YE_aZ0O{&r&$Sk76h!AO2rHZ+Y13}5e%S)%aY`g0@k}AOI!JvYD{MH9z&_j&w@kk%d2KsRy~uZ z5@bXK#MQvKCotX&NoTz@^_SIZRVXQ&O4;=HV9`lWmm|1r3og&U%?v4f3U$)WNZB)c zM->#&`O73cya36gyP36Rct?KBVFO4b$|CT|vd<>}G(ocrWvSEx15ITiTW$(i%@~^i zT`heAm})AmmucBLje=^0i=D=6oyOHJJ&2FAAq#(nKGBH`?8fb)%k(XW!Be5vp3Jj{VkC$=mke-YEx z4#|1{213&P5groS&vr;eJidmZ)$^dvOp!VjN*%V{+Fha?PJ6+{25m4S6&APltL~sZ zTbD6Zi})7WK*prE+*5d#R7;ubG$v_PZCn&Bnd z|2siV@O_)-f~Ei#oyl(_(eA3D^U{F2D3zQ-3QDRK30jop9SKDibrHgYYBt|w`m!aD5vEp=E$;}7Mlb_u zX*UQoooT-93+O#TbKB(a8ir@)h$&p2yzSdGGZI{#9q)(VWv#%+iu>wZwootFNtWnb zOTxS@$S^b5{(8WA94f{BT(XT@nty9`shGv=j)YXt44UJJZ@vJ|T3FC%YhghgsBl@- z#Go~#nmzD8N6WxVP9>uwYPtN8;mw~em#t=@t#-z@O zR`!mMwI-%5oA;@f{|_IgDfL`ez@?%TsFV;noWyJmzM6^SY?^K2w=jX5ID^sz>0$>K zzsdBW9HZ&tgt4lq({-XgRTFiZL|MuNs|V;#wz3$;Sv^=)T4$ZKTOY6u+k;uAavfE4 zcfnA`SooR(?(oTX58v|;$0m;%$}6g&T{M+fxM9Ty@k;fw&0{E+@a_UzDOS=daKQ-* z9Vz1AHkC16wh^pp@Tn|9hi9HPVX%$s3yQAkoe-sZkRhbHzEtY2`k=2Cd88ZR9M;F+20chGJJ zJ>Z~SKvk1XF>^$~Giqu#X=_-y&tZi30|X$CAkq3WJ|`Y8)fKxEVrJ$@11n%dHPXl( zAzjwK7TG!6S!7jRL7Sk|V0Lr8BeWPMa}Bz?tnL<^r`btR{(H4*xIHAL%jI(iTm|#M zYVxhzK4wRq{QP^id=VL|15BQR!Tc}%yyltdZ^TCfqL%x&y`4cmtk2s=Yu1RRC2x74 zMIB^87ok#du(kNwMlRXKkGnyqJnli$KWz#3wp9Lg8-ENbvSO*Y-?s6Tsn{7Ku>3M_ z7ob9DO+nPfJs(_I7k`L@l4|50p?PG#yEF!CrSUy{`Z=lEhdF#BzRXsSDW%UTi^QzH z^O1mdv3m;BO^Z)jvH2aH&)4bvBTm6w=VQ=`_2H^WX0ee3iewkN3mxZF-TaqnK4v=I zTqZf<`;vmhYI4vqlaAfB9(TmeY$=81%;&&uDA!1i87>%TDlFo@h zeSs_CS%+)}`G!Mo0r_i(#CO(PH9-%U;kg=tCL1oQHBtt-=#Z@-@rCL$m23Fcqf319 z><7v>fl^_S<*pZRpk`sb5eq&A=y5Ilt5nWR@9*(LKsEh08Q6Y{0CiT24mzkyrgtw( zw8>6mmbGEKbyAl&%|%?~BEHW>{D6xns%8VLQy!>B1dFCi_qYE>sm0d&3CLLa-OBqE z|6c$jKM$EWV^LVVdzqSW2w}K`XLAS!7&kFSe=`HyHxn=vd_vWkRd$X>fRLkHyEQ@WOElb=Y&Q)w-e(fVPGJxX62?rUO?L#dDA-=B+i-bm7u zct_V^0S5$33V1@mVF3*R&kOin0bdaCCjwp(@VbC+3iw+AO9I{&kX!NovnQT8-j~+f z`iJN|5!d4J%pw%X% zXMj@cGoL23C!^^-(NwBOKb2zd`jQDfog5lSvA5CmV4sZ~CqzpekEN4LW6z+b$D^?X zcrti}sJ+pa7h*!nu9QzvM~213iwAQFArvlNS}izQSIrB3pa2E~77 zyKM%V)XMRc$JMI}LI|NE_=40;2%>F>bZo&%if}TDvS~;IfkK^vW z&g+M!w4UpSdQXp}^<*kBoQlTufoMFQ$mso+o;nlPN8~QhnTD zZ18#Vz645dk=^pYo3ZiQ_W#KHA7SkLCUZM8)>sDPljIEjD0akA`{<0F>Ku$_qUfBW zG59J1zX!DD>1Hh7nUsRUcXS9{?KMJR(cK*}?Z28A*1$5;4hKy;(%xemdXF7GGDVo$ z#}&6Pc}&$MT!vot zji6{m(3lNOYk}!jXd3s?)L&LA6=kHvjS_F`JIEN>>G2eoT*al;KL|%kTA@xmkCe2< z4>duktzISN;WcQ!_>l0ngy<-aC2RmTVXT9nDf!*z-vrjSQC#VOgWOolmRbT%D@3Qz zuBbH@T7ie#sq0B}-3<4-Qxn5%N zuwD~JQ3;eb#JpA)bFoduyh2MWfSRA%YS6>?$)Ni&)eQ&Pq~aFYuuBY;RgN_bx}06o zcqFLJngegaS0vnGV0v$0+TXRH63)#A1m7IE_!V-Lx@0yq4j%5nriZP7=b@OTDYjq{++O_e%jN*%G?x@uH;lJ0`54cf#bWr17QY%OTts>>KE z-^wKxL-rhk@V4JK%9TpC#FYCFi>Tk_;Uew- zLugIOeVdnx=0MiH$)A8%x3tjlpKVxJKqa}Qh2L(+!s)G8`1||Yh+zjTaHB{lU!+56 zLumk>HRbSkJKcp2Ky(FDRUrk#szrhpW#fs2B8$2RZ{hyzie`uDsK}NM1};W0 z18M0V5IA(^<+d;2>kw1%6T78%w!LeGn&I z>f|aa_jV)0c(Ciufb#@Qs{L7Xohz=s(^xBJ3BM!lrnZ2?al*e^fMgXG9JEzffCCjS zhYm4VZ8y0eK%0*5^ zVkJZQ;l`Bmvk7vhPh_oaOk(T@kdpNfq0FPE zm;yaO0Z`|F-=yczQB3Axh|ilSC)tK>eels*y#9g5pd>&FVf;yJP)YQku>Y3ELpE$3K=?%kIh z@~W;z{1gk#h2PTdC0Yh9LWAudr?&%FRB^ew{_je~u8ok4ZqzRWsHs7bM*5vxkMN^T zf2^usA>)`3(h9bSf93URWV~$>_i&(=yX|OyMG3m4X#WJ1Z;Dm|txAgkT|s5yuIR|M zjZC`rM20~ZCmBJ@2UzZHELH24oqwRQ^OT*g^MdEbC3t>SR$%Oqc2xTy>ecoAw2|uT z)n(j0Ogr}&>DXAZg4L4sZ86g=h^H_|Zo!|3)e}bP4aFffjrTkf(48K_bneJWH*I^* z=HqoX*Ko0vHa`oSSRZMMbS|%B%w2x9yHLar)Xo19&BsjdfYeEkdSxS!M6C>ZZqiM* zdTgAk6?TlmM&aimZ5!7}4-Xe?6nlYsOWGN~r8eX56dWATScw})i$^uqZ2wz9R zLVq(=YETW-UA7mgmT}(zUaU>tHYmseiwJJ|IBalnKvCkp?+V;!LiVD_wc5*ILaNZE zibGPx15(AZ$(uxx(qJ0!E%O@NpD$5fiN*dDblm(ND32fc{tYLm_aY<0LBhoMDtKVf z4h%jdvPD{4?z4qp+t&p-z=_a7Uhh_^)~zf5tW*e8JSR=OxccZqW*%P0E(nZ^Tg4Of zEh6wd4pwI7#yc2>@U?(C&7<_c`bYDjYo@()LTbS`q{AnUOyyFoJ)-e6PZMfl~6o+CgZlhr1w9YvC^IT7ZR~#%1WoL zLHOeKwz7#wJgoeWGDhFw8a?|lM$dhUKB#D?qK_%st!PNm6N-LW(YT^tQ*>NWN73&n zdPPxbm9hV~{aE_!Kq}KYI7*k7m=%j9&RXD-sgZbQ2+R;I5ojN+c055nw4OuI3U|m9{Sndw3)J76 znY&#%N>m&Q31s2sy*KmTo8P>7^Jb*vgHN#*##k$UD=UnRfzsC{+D~szV0iP*XEw9Z z4HvhMMfP3X{(~c#qF!+90VkEy)2V#kcJ*FMcaG-uOkUr6?|pjC?z1}E+uL?3*ZU2| z`W_<$!MDV2i*Afw$Ji$HfzUVeRWu3Wx~P$SRN^L)@QbetE&BiZYbMsEjGCm$2w&19 z#IhxwvE8y;wzo58hUIJIJGL|S)Th{Xy4IsE#^2kBh5*spv5xSkGj_PMFXg7tS*I~{ zh=p$k4SijVjdvELqQH(d2wyjZl)yr->!9iV%N)84mYH5MVR{EU_IZZRjSkOP=Ekz= zO_atX;LY@`$&G{=nb9io;p7#qVq6)jBV(9WZbLh^g0FTg!WeAL^tj34Ei$21BE!bg z7`mBfd?<|O=OGN$snyDNQwvw6`L9jXqn=TfLd(Q_oF_5+xza?$1CxGRI=rM+wrrRa zkS^E0u8fC-%ZYldX@9fQ_&zj5N@Ma`ngoTUc0UOeL>lQ1kK7d=xeY??7Bt+bmg-UM z)Q#Z5{CKKVXYRA5dc=LPM(Z!tTin-6^;UOU&9}gf1)luy&Kb?8Mb>DO(A5a&!r})c zAy9sD34s!^o@~S#tEE`aX_dtAmc}K{l=cc8vttl9_phF;&J#e{n&ClIc>Ol7_LNwYA@j2sf8d7gz=Mi zG>l8*9j}2GXapmL^TO*n1#268QQpvOrSZ7wx1SYrt=3wO6G&spL^!qbt-%cOCd8ku zf_N4N5@H+>;eAQMub#nxXI$pSWpd@O>1zKfSB0jlH)3$*8)Mzx6zqd|{0aT!?c|!? zwypBEqv_3t6*n#*fA`FI#;6Eis}>HQzJB=remyN`RO~^wH;xSkxL~=o@pDk&#;9k! zYBQF!j{Q_D#n^XsC9TY1}CkNFL z6^e`Jxxm%vBaB$$FzO)p1xi_>B+rv0W`s)AaANUv?LY`jL@Q_32lKsa2BTGc7tn^| zi_^9DsR*keM78qB`tzRn?DNXdQT@6qz&qgk6JrS2M+%1=VnDrEwRJXTTOFyZ-!(X&o!9k^zAT)1zbGxzCqL>TgLB#;DtaP-34=iSa9G(lX0BE~1#QomCOeyawo$OUeVNP-b(G_ zKg>PTrZ;~;Y!0+mc0G?*!T*y^D*uwwT>r~=u$UUKzN7Cd;t#a`OxDuvqpqNbif+nr z^+Q=JKj0pD=%F^|^fIXR*;Y}fzw4|=Gex(vjTw$(J36%8OnyKoTXMHvzhkBPR_h<@ zRj%xUm0vw1r#R+h#1yU_nx#8mIO;a!>;ro5an~w#>U*uUohvw2v1s)HPNTn#jcgC1 z^6edr(cfijefMCDzNDh}E83&zfTBNC^thr!iaxIB(~AC9(bI~)uIOJBeM`~5DOyuh zqG0Uvh9_4XOgnC8Up5PbIV+d52Q6>~CzE&k!4zG`wP~!MwiC36G9zzOPtmd-Axb$w zG@Z4JWZX|XOiWKdrPH^*No-Hia(hyRLXUgAAjZ;m-gWG3e?g3yhxM~aW&e=pPck={F?r?%mL V8TkDHzngB7eAwrg{1+zz{{>3}!BhYM literal 5120 zcmeHLZ){w}5#O_Y)N$gx0};jisq)gs5($lo03ixZWuYuuBOe%Osy1Jo^ZD5v^8MlN z#TcnXSm&env^^12D)^TAF4IVhD762hP$`Q!+lL=Yz>==ja< z-o10;5;Y)Ityt;p%2=Al@|PNkEh=}6p;MiPmnYY#bg`ar^tCG0)-J!r?1!%k0UXU8_9dVn)F z{3Kc6w+g$dWqr#PjBUUe0JUA$pbHV!OP$7BwB1CK{i^k%$9VN4ru;HO4bVW8E-li8 zvWm^v4SHDjyBHJA^kw2*TN!)eJ7jxYXTrt&uJ!21Ao3l4G&h^E{XN4GH-f==n!|u{ zd?R2}>t(FilhTaJcKD!lUDd<{6nwpVh4;CbJOh*oFB}ry-mZR++md&A{JiAng;&ZJ z1HeUeK}a4Ffq84TJs&=2&GK`TOUM}3=go;i@C}Qwqy65=e($5@109SJN48qCa=_Vi z4XylKfH9~R(V~!8EKss$19@JV#xV2vS*>#k#AKCvE4Q0^(zA4ZsoLW4Wlgk}mfB?) z#vRX=0v?d)2U_7tYxc@@i^}3N<)0ei$t6-&ssPW!4a+C;TYWcTB&?eAKU-QhbnrChTQQmBsl2lDt_w#wX>vekh5 zw=xANTWxh`veh>Cm|5?%@Vl70!5)rn~b6QhMZpcgeXL^5UwDSYOjvg_X^>l zy;`(pL-{LL=0Vx-P*(MM^WcZSCwxawwv*!X3v+?CmS9_JV8G-=5&ZR>fHoLt6}HnD z?VxOj4s82EXLHOBLY0b8`Bcy_W{d5j&^e>nPAIYCCPyM*79Ot(M8eALtZOELy7v4k z?RG=^xYl0PPAqT11hzr)v!tr9rmFi_sruJX>W1D(stUY_6o9-Rl}#8YZBuJ%yKa@X zKQ^>|j5;LwDUZ)cKI8Fe;W@8JK5gvW3_cOGRb2TI%)JOMeHh@%0&-EP=z#${HHSbS z@eR5Q!ZHl@1%aH%u4&d`R1IIEg4(Hf<8GJ*ZS{E7FoBhEh&+B+^25fw2@E&PI|TFc zCKabN%#Gm;3+d!VA?E_6v!li?vi0S2wVJ1aH#_<*_cNpp};W*s^|Ec4R6?LGf23!!% z>!Edxh(YjiZR*qI%}u7ZTDeCqZ7LPL%QRK~g|<6za`IEUKoF{#^0Q>3300ew%Y(FL zb7UUU)OfhA=`^^gqPb7>n^Hip+-I1tR(A~+L8HU6~ z)xck^gtF*Me1`1TtKE*(gjBYglm7*s3_hhU!x?=UzOYL8uOtjHwlHUI2b+|b7X!sc z)z6T>90Yvk{msk;K7S$eL2!Hg80nGWc@GzW3U-_IcKF?q26+X@_kFV6`e%62Cp$oX z;FB9bp7P0%41d^AbhQjGH3-~g;bqYvZIBh8ya8ktq~ymI=HP|#p6Zj%LVjKa)dcb% zI7Jw5rSc6JXo~-*yRSB@+HBUJzpm9(R2kbR@G=SF4ar1z1qZ;I z+D`axdJ9`mZYDf8wT)p4uT>fpJE>p!SZqHgyrlZI}@4_wiL&AMVpN6FS|EYCP z++nls;XCZ^i4L|m6B%`YX7FomBsS*Q$pbFI4wfEb7#&VJ8Jm97ITNvr+ta~#I-N}0 z88_m_5~DV;lJup<(@tb~HUFbSMpZK9Bvw!9B_2)3)Dmv8X_dZ2>VR9Pe`gOp<~o@k zdyf-M##3o0lX1wc`Z&F@(Vp9?A@yB9!`DRnGmQNlbJTue;B5x}+CX98fPud^aLB;8 zfd>tg20mlp^9H_R;Ix5y)&Ktb@yvKM?e+|hjlrT+I+k!pfW)16JUQ+F8=;*79HdQ8 zBx!`Um0)x%nNcjXX@m@pP=?%gE1`oK#~qBMQiJYeDK!^OCfsy#Y$T;-Bk9p-9T_LY zNsPzRNww18sN=>Xu>^QBm_iQHW9i5Cy&|w4MRWuH7ocwozMH!=z8i4R;12`t#Q!hE Yb0^@}_^SBUUyGke_z3^8{clF#Th+%>hyVZp